라벨이 개발인 게시물 표시

파이썬 폴더 순회 os.scandir. python

다이얼로그에서 폴더 선택 후 작업하는 일반적인 패턴 구현 소스. import os import tkinter import tkinter . filedialog import tkinter . messagebox def select_folder ():     path = tkinter . filedialog . askdirectory ()     return path def work_file ( src_path ):     try :         path , name = os . path . split ( src_path )     except Exception as e :         tkinter . messagebox . showinfo ( "Exception!" , e ) def work_folder ( folder_path , is_sub ):     try :         with os . scandir ( folder_path ) as it :             for entry in it :                 if entry . is_file ():                     work_file ( entry . path )                 elif is_sub and entry . is_dir ():                     work_folder ( entry . path , is_sub )     except Exception as e :         tkinter . messagebox . showinfo ( "Exception!" , e ) if __name__ == "__main__" :     try :         work_path = select_folder ()         work_folder ( work_path , True )         os . system ( &q

파이썬 vscode에서 자동 코드 정렬. Formatter.

세가지 autopep8, black, yapf 규칙이 있습니다. 저는 black이 가장 취향 이었습니다. * 설치. pip install black * vscode 설정.     - 아래 둘 중에 하나로 선택해 설정한다.     -  settings.json          +  "python.formatting.provider": "black"     - vscode-파일-기본설정-설정-확장-Python-Formatting:provider-black * 코드 정렬 방법.     - 단축키 Shift+Alt+F      - 코드에서 우클릭 - 문서 서식.     - 터미널에서  black --check file_name.py * 이외의 자동 정렬 설정.     - 파일저장, 복사, 타이핑 시 자동 정렬 옵션.      - settings.json          +  "editor.formatOnSave": true,         + "editor.formatOnPaste": true,         + "editor.formatOnType": true, * 주의.     - 확장자 .py 파일이어야 자동 정렬 합니다. * 참조. https://code.visualstudio.com/docs/python/editing https://jiku90.tistory.com/12

flutter- 아이콘 적용하기.

플러터 프로젝트는 이미지나 아이콘 툴이 기본 탑재되어 있지 않아 상당히 불편하다. 그래서 이를 자동화해주는 flutter_launcher_icons을 사용한다. * 툴의 사이트. https://pub.dev/packages/flutter_launcher_icons * 툴 설치. flutter pub add flutter_launcher_icons * 아이콘 이미지 추가. 프로젝트 폴더에 assets폴더를 만들고 app_icon.png 을 추가했다. 아이콘 이미지는 1024*1024 (ios때문인거 같다.), 알파채널 제거. * 설정 파일 생성. pubspec.yaml 을 그대로 사용하거나 flutter_launcher_icons.yaml 파일을 만들어 사용할 수 있다. flutter_icons : image_path : "assets/app_icon.png" android : true ios : true * 실행.  pubspec.yaml 일때는 flutter pub run flutter_launcher_icons:main flutter_launcher_icons.yaml 일때는 flutter pub run flutter_launcher_icons:main -f flutter_launcher_icons.yaml 적용된다. ////////////////////////////////////// 안드로이드 기기(픽셀4)에 따라 라운드 아이콘 일 때 제대로 보이지 않는 문제가 있다.  구조상 자동으로 해결되기는 어려울 것으로 보여 수동으로 추가해 줘야 한다. * 라운드 아이콘을 만든 후 다운로드 받는다. https://romannurik.github.io/AndroidAssetStudio/ Launcher icon generator 항목으로 이동 후 아이콘을 만들어 다운 받는다. * 이미지 복사. 압축을 풀고 이미지 파일 이름을 적절하게 변경한다. _back, _fore 같은 배경 파일이 필요 없다면 삭제한다. 프로젝트폴더\android

flutter- keystore 만들기.

안드로이드 어플을 스토어에 올리기 위해서 key 파일이 필요하다. 키파일을 만들기 위한 순서를 올린다. jre 폴더 위치는 아래 명령어로 알 수 있다. flutter doctor -v C:\Program Files\Android\Android Studio\jre\bin>keytool -genkey -v -keystore d:/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key 키 저장소 비밀번호 입력: 새 비밀번호 다시 입력: 이름과 성을 입력하십시오.   [Unknown]:  name 조직 단위 이름을 입력하십시오.   [Unknown]: 조직 이름을 입력하십시오.   [Unknown]:  name 구/군/시 이름을 입력하십시오?   [Unknown]: 시/도 이름을 입력하십시오.   [Unknown]:  Seoul 이 조직의 두 자리 국가 코드를 입력하십시오.   [Unknown]:  kr CN=Dev Cats, OU=Unknown, O=Minihand, L=Unknown, ST=Seoul, C=kr이(가) 맞습니까?   [아니오]:  y 다음에 대해 유효 기간이 10,000일인 2,048비트 RSA 키 쌍 및 자체 서명된 인증서(SHA256withRSA)를 생성하는 중         : CN=Dev Cats, OU=Unknown, O=Minihand, L=Unknown, ST=Seoul, C=kr [d:/key.jks을(를) 저장하는 중] * 참고. https://flutter-ko.dev/docs/deployment/android#keystore-%EB%A7%8C%EB%93%A4%EA%B8%B0 - 얼마전까지 Android Studio에 gui툴이 있었는데 안보이네요.

flutter- wakelock 꺼짐 방지. 화면 유지.

화면 꺼짐 방지 방법. * 라이브러리 페이지. https://pub.dev/packages/wakelock * 라이브러리 설치. flutter pub add wakelock * 코드. 기본 사용법은 아래와 같이 매우 심플하다. Wakelock.enable(); Wakelock.disable(); 아래와 같은 사용법도 있다. bool enable = true; Wakelock.toggle(enable: enable); Wakelock.isEnabled

flutter- Admob 배너 적용.

flutter에 Admob 배너 적용하는 방법. * 라이브러리 페이지. https://pub.dev/packages/google_mobile_ads * Admob 라이브러리 설치. flutter pub add google_mobile_ads * AndroidManifest에 추가. 인터넷 권한은 admob 라이브러리에서 자동병합 되어 따로 할 필요가 없다. android\app\src\main\AndroidManifest.xml <application>        <meta-data            android:name="com.google.android.gms.ads.APPLICATION_ID"            android:value="ca-app-pub-##############"/> </application> * build.gradle에 추가.  2022년08월 현재 flutter과 Admob이 minSdkVersion 불일치로 컴파일 에러가 난다. minSdkVersion 19, 20 가능하지만 추가 코드 작업이 필요하다. 특별한 사유가 없으면 21로 하는 걸 추천한다. android\app\build.gradle minSdkVersion 21 * Admob 라이브러리 초기화. main.dart 이나 초기화 코드에 아래 코드를 넣는다.   MobileAds.instance.initialize(); * 구현 코드.  본인에 맞게 변경해 구현한다. // 광고 ID 를 리턴하는 함수 . String getAdId () { if (!kReleaseMode) { return 'ca-app-pub-3940256099942544/6300978111' ; } if (Platform.isAndroid) { return 'ca-app-pub-#############' ; } else if (Platform.isIOS) { //

flutter - flutter_native_splash 스플래시 이미지 추가.

flutter 실행시 네이티브에서 플러터를 로딩하는 시간에 지연이 있다. 하얀 화면보다 스플래시 이미지를 보는게 유저가 느끼는 경험이 더 좋다.   flutter_native_splash를 이용하면 코드 작업 없이 스플래시 적용할 수 있다. 물론 따로 처리해야 하는 것도 가능하다. * 라이브러리 페이지. https://pub.dev/packages/flutter_native_splash * 라이브러리 설치. flutter pub add flutter_native_splash * pubspec.yaml 에 추가. 각자 환경에 맞게 세팅하면 된다. # flutter pub run flutter_native_splash:remove # flutter pub run flutter_native_splash:create flutter_native_splash : color : "#3B303E" image : assets/image/splash_logo.png fullscreen : true android_12 : color : "#3B303E" image : assets/image/splash_logo12.png # branding: assets/image/splash_logo.png * 터미널에서 실행한다.(Android Studio 터미널도 가능하다.) flutter pub run flutter_native_splash:create - 여기까지 하면 적용 완료다. 에뮬레이터에서는 확인할 수 없다. 진짜 핸드폰에 설치해 확인할 수 있다. * 만약 설정이 바뀌거나 스플래시 이미지가 바뀐 경우는 remove 후 create 해주면 된다. flutter pub run flutter_native_splash:remove flutter pub run flutter_native_splash:create - 주의. 에뮬레이터에서는 스플래시 이미지 적용이 원할하지 않았다.  핸드폰을 꼽았을 때는 제대로 확인이 됐습

flutter 방향 고정. 가로, 세로.

아래 한 줄이면 어플의 방향을 고정할 수 있습니다. SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); 방향 옵션 입니다.. enum DeviceOrientation { portraitUp , landscapeLeft , portraitDown , landscapeRight , }

flutter license 표시 페이지.

손쉽게 어플에서 표시할 라이센스를 표시합니다.. pubspec.yaml 파일 dependencies 에 추가한 라이브러리도 자동으로 표시합니다. 아래 한 줄만 넣으면 됩니다. Navigator.of(context).push(MaterialPageRoute(builder: (_) => const LicensePage())); 만약 수동으로 추가한 추가 라이센스가 있다면 아래와 같이 추가할 수 있습니다. void licenseAdd () { LicenseRegistry. addLicense (() => Stream <LicenseEntry>. value ( const LicenseEntryWithLineBreaks ( <String>[ '라이브러리 이름' ] , ''' 라이센스 본문을 복사한다. ''' , ) , )) ; }

dart (flutter) 문법 - 생성자.

플러터는 생성자의 구문이 매우 다양 합니다. https://dartpad.dev 에 아래 코드를 복사해서 실행해 보세요. factory 는 다음 페이지에 정리되어 있습니다. https://abel9999.blogspot.com/2022/07/dart-flutter-factory.html class Animal { String name = '' ; int id = 0 ; // 이름 없는 생성자 . Animal() {} // 이름 없는 생성자는 하나이상 만들수 없다 . // Animal(int i) { } // 에러 . // 이름 있는 생성자 . Animal. name () {} // 생성자를 여러개 만들수 있고 // 멤버변수의 기본값을 설정할 수 있다 . Animal. nameNew () : name = 'test' {} // 생성자에서 파라메터를 받을수 있다 . // 아래 생성자는 동일한 동작을 한다 . Animal. arg (String n) { name = n ; } Animal. arg2 (String n) : name = n {} Animal. arg3 ( this . name ) ; // {} 로 둘러산 부분은 호출시에 이름을 지명해야 한다 . // 예 ) Animal a = Animal.argName(name:'go', id:2); Animal. argName ({ required this . name , required this . id }) ; // [] 로 둘러싼 부분은 호출시에 값이 없으면 기본값을 지정한다 . // 예 ) // Animal a = Animal.argName2(); // Animal a2 = Animal.argName2('go'); // Animal a3 = Animal.argName2('go'. 33); // Animal a4 = Animal.argName

dart (flutter) 문법 - null 관련 문법 정리.

dart문법에서 아래 키워드를 코드와 주석으로 설명 합니다. ?  !  ??  ??=  ?.  ?.. https://dartpad.dev 에 아래 코드를 복사해서 실행해 보세요. void main () { String? strTest ; // '?' 는 null 이 가능하다는 표시 . // '!' 는 strTest 가 null 이 아니라는 표시 . // Uncaught TypeError 예외가 난다 . //print("'!' $strTest!"); print(strTest) ; // null 을 print 하면 null 출력한다 . strTest = "test" ; print(strTest) ; // getString() {} 은 null 을 리턴할 수 있다는 암시적 표현이다 . print( "'getString()' ${getString()} " ) ; // String? getString2() {} 은 null 을 리턴할 수 있다는 명시적 표현이다 . print( "'String? getString2()' ${getString2()} " ) ; // String getString3() {} 은 반드시 String 을 리턴하는 명시적 표현으로 // return "test" 가 없으므로 예외가 난다 . int? nInt ; int res = nInt ?? 5 ; // '??' 는 nInt 가 null 이면 5 를 반환한다 . print( "'??' $res " ) ; nInt ??= 5 ; // '??=' 는 nInt 가 null 이면 nInt 에 5 를 할당한다 . print( "'??=' = $res " ) ;

android studio emulator만 독립 실행하는 방법.

안드로이드 개발할 때 사용하는 에뮬레이터를 독립 실행하는 방법입니다. 안드로이드 스튜디오 실행 없이 에뮬레이터를 사용하고 싶거나, 빠르게 에뮬레이터를 실행하고 싶을 때 사용 합니다. https://developer.android.com/studio 안드로이드 스튜디오를 설치하고 안드로이드 스튜디오에 있는 디바이스 매니저로 가상 디바이스를 만듭니다. https://www.nirsoft.net/utils/nircmd.html 다운 받아 압축을 풀고 nircmd 파일을 아래 배치 파일과 같은 경로에 복사 합니다. 배치파일을 실행하면 검은 콘솔이 같이 뜨는데 콘솔을 보이지 않게 해 줍니다. 아래 스크립트를 콘솔(cmd.exe)에서 실행하거나 배치파일(bat)을 만들어 실행하면 됩니다. bat로 만드는게 더 편합니다. * 에뮬레이터에 생성된 가상 디바이스 목록을 보여줍니다. %localappdata%\Android\Sdk\emulator\emulator -list-avds @pause * 에뮬레이터를 실행합니다. nircmd exec hide %localappdata%\Android\Sdk\emulator\emulator -avd <디바이스이름> 위 경로는 sdk가 설치되어 있는 기본 경로 입니다. 다른 폴더에 설치했다면 경로를 변경해 줘야 합니다. 

flutter - ChangeNotifierProvider 사용법 설명.

* provider 가 필요한 이유.  - 예를 들면 flutter에서 버튼을 클릭한 경우 다른 위젯이나 상위 위젯의 리빌드를 구현하기 위해 필요하다. * 설명.  - ChangeNotifierProvider에 ChangeNotifier 상속 받은 클래스를 등록하면 하위 위젯에서 등록한 것을 찾아 사용할 수 있습니다. 즉 상위 위젯에서 하위 위젯으로 흐르는 데이터의 이동 통로를 만든다 생각하면 됩니다.  - 리빌드가 필요한 위젯을 지정합니다.   + Consumer, context.watch, Provider.of<Counter>(context, listen: true) 사용.  - 갱신이 필요한 경우 ChangeNotifierProvider에 등록한 ChangeNotifier 상속 받은 클래스를 찾아 notifyListeners() 호출하면, 위에서 지정한 리빌드가 필요한 위젯을 리빌드 합니다.   + 데이터 사용은 context.read<Counter>(), Provider.of<Counter>(context, listen: false)으로 합니다.  * 중요 - 아래 함수의 차이를 알아야 합니다.  - context.read<Counter>(), Provider.of<Counter>(context, listen: false)   + 데이터에 접근만 합니다.  - context.watch, Provider.of<Counter>(context, listen: true), Consumer   + 데이터에 접근도 하고, notifyListeners() 호출시 리빌하는 위젯을 지정하는 기능도 있습니다.   + 이 함수나 클래스를 사용하지 않으면 notifyListeners() 호출해도 리빌드 하지 않습니다.  * 공식 사이트.  -  https://pub.dev/packages/provider * 코드 구현.  - https://pub.dev/packages/provider/example 의 샘플 코

dart (flutter) 문법 - factory 키워드.

dart (flutter)에서 지원하는 factory 기능에 대해 정리 합니다.  * 설명.  - 생성자는 원래 리턴할 수 없지만, factory 키워드를 사용하면 현재 클래스와 자식 클래스의 인스턴스를 생성자에서 리턴할 수 있게 됩니다.  - 아래 코드의 주석으로 설명 합니다. 동작과 제한 사항을 알 수 있습니다.

dart (flutter) 문법 - ! (느낌표, exclamation mark)

// 리턴값이 항상 null이 아니지만 예를 위한 함수. // int? 는 getInt()가 null을 리턴할 수 있다고 명시해 준다. int? getInt () { return 3 ; } void main () { // int? 는 변수에 null 을 허용하는 표현 . int? a = getInt() ; // ERROE int b 는 null 을 허용하지 않는데 // getInt() 는 null 을 리턴할 수도 있으므로 에러가 난다 . //int b = getInt(); // getInt()! 에서 null 을 리턴하지 않는다고 // getInt() 의 끝에 ! 를 명시해 에러가 나지 않는다 . int c = getInt()! ; } null 에러가 많이 나서 이런 기능을 추가 했다고 하는데 그다지 좋은 해결법이 아닌거 같다. !를 붙여도 에러가 날 수 있는 구멍이 많다.

dart (flutter) 문법 - 클래스. class, abstract, implements, factory

클래스 기본 예제. dart에서는 단일 상속만 가능하다. class Point { double? x ; double? y ; // 이름 없는 생성자 . 하나만 가능하다 . Point(double x , double y) { this . x = x ; this . y = y ; } // 이름있는 생성자 . Point. init () : x = 0 , y = 0 { } // 이름 없는 생성자 호출 . Point. init2 () : this ( 0 , 0 ) { } int GetV () { return 1 ; } } class Point3D extends Point { final bool i3D = true; double z = 0 ; // 생성시 부모 클래스 생성자 호출 . Point3D(double x , double y , double z) : super (x , y) { this . z = z ; } // 부모의 함수를 재정의 할 수 있다 . @override int GetV () { return 2 ; } } void main () { var p1 = Point ( 2 , 2 ) ; var p2 = new Point3D ( 2 , 2 , 2 ) ; print( 'The type of a is ${p1. runtimeType } ' ) ; } 추상 클래스. 인스턴스화 되지 않는 클래스로 주로 인터페이스 정의에 사용된다. abstract class AbstractContainer { void updateChildren () ; // 추상 함수 . } class ClassA extends AbstractContainer { // 추상 함수 정의 . void updateChildren () {} } implements (인터페이스) 상속받지 않고 다른 클래스의 인터페이스를 지원할 수 있다. 여러 클래스의 인터페이스를 지원합니다.

dart (flutter) - 함수.

알림 - dart는 함수 표현법이 다양합니다.  이 문서에서는 제가 선호하는 유형만 다룹니다. 아래 3가지 함수는 동일한 동작의 함수 입니다. bool isOne (int one) { return one == 1 ; } isOne2 (one) { return one == 1 ; } bool isOne3 (int one) => one == 1 ; 보통 함수. // 호출 . int n = test( true, 1 ) ; // 정의 . int test (bool isB , int numN) { return numN ; } 이름 있는 함수. test2 (isB: true, numN: 1 ) ; test2(numN: 1 ) ; // test2(true, 1); // error // {} 로 둘러싸면 호출시 변수명을 명시해야 한다 . void test2({bool? isB , int? numN}) {} test2_1 (isB: true, numN: 1 ) ; test2_1(isB: true ) ; // error test2_1(numN: 1 ) ; // required 를 붙여주면 실행하는데 꼭 필요한 함수 . void test2_1({bool? isB , required int numN}) {} 옵션 인수 함수.   test3(true, 1);   test3();   test3(false); // [] 로 둘러싸면 호출시 인수를 입력하지 않으면 기본값을 지정해 줍니다. void test3 ([bool isB = true, int numN = 1 ]) {} forEach 에서 익명함수. var intList = [ 1 , 2 , 3 ] ; intList.forEach((item) { print(item) ; }) ; int List.forEach((item) => print(item)) ;

dart (flutter) 문법 - typedef.

// 기존 타입의 별칭을 만들수 있다 . typedef IntList = List<int> ; // 함수의 형태를 타입으로 사용 가능 . typedef Compare(int n , int m) ; bool maxLeft (int a , int b) { return a > b ; } bool compareAB (int a , int b , Compare cp) { return cp(a , b) ; } void main () { IntList il = [ 1 , 2 , 3 ] ; int a = 2 ; int b = 1 ; bool isLeftMax = compareAB(a , b , maxLeft ) ; }

dart (flutter) 문법 - 제어문. if, for, forEach, switch

- if 문. if (isRaining()) { you.bringRainCoat() ; } else if (isSnowing()) { you.wearJacket() ; } else { car.putTopDown() ; } - for, forEach 문. var message = StringBuffer ( 'Dart is fun' ) ; for ( var i = 0 ; i < 5 ; i++) { message.write( '!' ) ; } for ( final candidate in candidates) { candidate.interview() ; } var collection = [ 1 , 2 , 3 ] ; collection. forEach (print) ; // 1 2 3 - while, do while 문. while (!isDone()) { doSomething() ; } do { printLine() ; } while (!atEndOfPage()) ; - switch 문.  test () { var command = 'OPEN' ; switch (command) { case 'OPEN' : executeOpen() ; break; default : executeUnknown() ; } } 참고. https://dart.dev/guides/language/language-tour#control-flow-statements

dart (flutter) - 예외.

test () { try { throw OutOfLlamasException( 'Expected at least 1 section' ) ; throw 'Out of llamas!' ; } on OutOfLlamasException { // A specific exception buyMoreLlamas() ; } on Exception catch (e) { // Anything else that is an exception print( 'Unknown exception: $e ' ) ; } catch (e) { print( 'Error: $e ' ) ; // Handle the exception first. } finally { cleanLlamaStalls() ; // Then clean up. } }