Slide 1

Slide 1 text

Script, Library, or Executable? You can have it ALL! http://bit.ly/pyconde_pywc_refs 1

Slide 2

Slide 2 text

Luke Lee @durden20 Python GUI and CLI applications for Oil and Gas http://bit.ly/pyconde_pywc_refs 2

Slide 3

Slide 3 text

CLI Library GUI Executable http://bit.ly/pyconde_pywc_refs 3

Slide 4

Slide 4 text

1. CLI import sys lines = 0 words = 0 with open(sys.argv[1], 'rb') as file_obj: for line in file_obj: lines += 1 words += len(line.split()) print(f'{lines} {words}') http://bit.ly/pyconde_pywc_refs 4

Slide 5

Slide 5 text

Separation of concerns http://bit.ly/pyconde_pywc_refs 5

Slide 6

Slide 6 text

Separation of concerns def cli(): """ Parse sys.argv and return dictionary of arguments/configuration """ pass def get_file_info(file_): """ Return lines/words in file """ pass if __name__ == '__main__': file_ = cli() print(get_file_info(file_)) http://bit.ly/pyconde_pywc_refs 6

Slide 7

Slide 7 text

file_info = collections.namedtuple('file_info', 'lines words') def get_file_info(file_): lines = 0 words = 0 with open(file_, 'rb') as file_obj: for line in file_obj: lines += 1 words += len(line.split()) return file_info(lines, words) http://bit.ly/pyconde_pywc_refs 7

Slide 8

Slide 8 text

def cli(): parser = argparse.ArgumentParser(prog='pywc') parser.add_argument('arg', action='store', help='File or directory to count lines/words for') parser.add_argument('-w', dest='count_words', action='store_true', default=False, help='Show number of words in file(s)') parser.add_argument('-l', dest='count_lines', action='store_true', default=False, help='Show number of lines in file(s)') # Using vars() to turn namespace object returned by parse_args() into a # dict. args = vars(parser.parse_args()) # Mimic wc command by printing both of these if there are no other # arguments if not args['count_words'] and not args['count_lines']: args['count_words'] = True args['count_lines'] = True return args http://bit.ly/pyconde_pywc_refs 8

Slide 9

Slide 9 text

2. Library - setup.py - pywc/ - api.py - __init__.py - __main__.py http://bit.ly/pyconde_pywc_refs 9

Slide 10

Slide 10 text

setup.py from setuptools import setup, find_packages setup( name='pywc', version='1.0.0', packages=find_packages(), ) http://bit.ly/pyconde_pywc_refs 10

Slide 11

Slide 11 text

__main__.py http://bit.ly/pyconde_pywc_refs 11

Slide 12

Slide 12 text

from .api import get_file_info def cli(): """ Parse sys.argv and return dictionary of arguments """ pass def main(): args = cli() file_info = get_file_info(args['file']) if args['count_lines']: print(f' {file_info.lines}', end='') if args['count_words']: print(f' {file_info.words}', end='') print(f' {args['file']}') if __name__ == '__main__': main() http://bit.ly/pyconde_pywc_refs 12

Slide 13

Slide 13 text

CLI ? http://bit.ly/pyconde_pywc_refs 13

Slide 14

Slide 14 text

entry_points http://bit.ly/pyconde_pywc_refs 14

Slide 15

Slide 15 text

from setuptools import setup setup( name='pywc', version='1.0.0', packages=find_packages(), entry_points={ 'console_scripts': [ 'pywc = pywc.__main__:cli' ] }, ) http://bit.ly/pyconde_pywc_refs 15

Slide 16

Slide 16 text

python -m http://bit.ly/pyconde_pywc_refs 16

Slide 17

Slide 17 text

python -m http.server json.tool pdb timeit cProfile unittest doctests tarfile zipapp zipfile webbrowser base64 calendar sysconfig http://bit.ly/pyconde_pywc_refs 17

Slide 18

Slide 18 text

python -m pywc -h pywc -h http://bit.ly/pyconde_pywc_refs 18

Slide 19

Slide 19 text

Gooey http://bit.ly/pyconde_pywc_refs 19

Slide 20

Slide 20 text

3. GUI from gooey import Gooey @Gooey def cli(): parser = argparse.ArgumentParser( prog='pywc', description='Count lines/words in files or directory') parser.add_argument( 'arg', action='store', help='File or directory to count lines/words for') ... http://bit.ly/pyconde_pywc_refs 20

Slide 21

Slide 21 text

21

Slide 22

Slide 22 text

GUI as option (--gui) def cli(allow_gui_option=True): """ Add --gui option to call gui() """ pass def gui(): # Gooey doesn't like functools.partial def cli_only(): return cli(allow_gui_option=False) return Gooey(cli_only, program_name='pywc', show_success_modal=False) http://bit.ly/pyconde_pywc_refs 22

Slide 23

Slide 23 text

from setuptools import setup setup( entry_points={ 'console_scripts': [ 'pywc = pywc.__main__:cli' ] 'gui_scripts': [ 'pywcg = pywc.__main__:gui' ] }, ) http://bit.ly/pyconde_pywc_refs 23

Slide 24

Slide 24 text

python -m pywc --gui pywcg http://bit.ly/pyconde_pywc_refs 24

Slide 25

Slide 25 text

PyInstaller http://bit.ly/pyconde_pywc_refs 25

Slide 26

Slide 26 text

? http://bit.ly/pyconde_pywc_refs 26

Slide 27

Slide 27 text

4. Executable - setup.py - cli.py - gui.py - pywc/ - api.py - __init__.py - __main__.py http://bit.ly/pyconde_pywc_refs 27

Slide 28

Slide 28 text

cli.py from pywc.__main__ import cli if __name__ == '__main__': cli() http://bit.ly/pyconde_pywc_refs 28

Slide 29

Slide 29 text

gui.py from pywc.__main__ import gui if __name__ == '__main__': gui() http://bit.ly/pyconde_pywc_refs 29

Slide 30

Slide 30 text

pip install pyinstaller http://bit.ly/pyconde_pywc_refs 30

Slide 31

Slide 31 text

pyinstaller cli.py --name pywc http://bit.ly/pyconde_pywc_refs 31

Slide 32

Slide 32 text

pyinstaller gui.py --name pywcg -w http://bit.ly/pyconde_pywc_refs 32

Slide 33

Slide 33 text

❗ Takeaways ❗ http://bit.ly/pyconde_pywc_refs 33

Slide 34

Slide 34 text

Separation of concerns http://bit.ly/pyconde_pywc_refs 34

Slide 35

Slide 35 text

entry_points http://bit.ly/pyconde_pywc_refs 35

Slide 36

Slide 36 text

__main__.py http://bit.ly/pyconde_pywc_refs 36

Slide 37

Slide 37 text

Gooey http://bit.ly/pyconde_pywc_refs 37

Slide 38

Slide 38 text

PyInstaller http://bit.ly/pyconde_pywc_refs 38

Slide 39

Slide 39 text

Ready. Set. Launch. ! " http://bit.ly/pyconde_pywc_refs 39

Slide 40

Slide 40 text

pywc pywc --gui pywcg python -m pywc python -m pywc --gui pywc.exe pywcg.exe python cli.py python cli.py --gui python gui.py http://bit.ly/pyconde_pywc_refs 40

Slide 41

Slide 41 text

and these ... ! pywcg --gui python gui.py --gui pywcg.exe --gui http://bit.ly/pyconde_pywc_refs 41

Slide 42

Slide 42 text

Luke Lee @durden20 http://bit.ly/pyconde_pywc_refs 42