Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Learn Python, the Right Way (Workshop)

Learn Python, the Right Way (Workshop)

Python Workshop for tutorial track at PyCon APAC 2015. Should be used in conjunction with the Learn Python, the Right Way presentation.

(Contact me if you’re interested in using this for your presentation. The source of the presentation contains some extra useful notes.)

Tzu-ping Chung

May 31, 2015
Tweet

More Decks by Tzu-ping Chung

Other Decks in Programming

Transcript

  1. $  python3  -­‐m  venv  accountant_venv   $  .  accountant_venv/bin/activate  

    (accountant_venv)  $ >  python3  -­‐m  venv  accountant_venv   >  accountant_venv\Scripts\activate   (accountant_venv)  >
  2. project   !""  accountant_venv   #      !""  bin

      #      !""  include   #      !""  lib   #      $""  pyvenv.cfg   $""  accountant.py
  3. def  _show_items(items):          template  =  '{name:20}{price:>5}'  

           if  not  items:                  print("No  items.  Use  'add'  to  add  some!")                  return          print()          print(template.format(name='Item',  price='Price'))          print('-­‐'  *  25)          for  item  in  items:                  print(template.format(                          name=item['name'],  price=item['price'],                  ))          print()
  4. def  add():          items  =  []  

           name  =  input('Item  name:  ')          price  =  input('Price:  ')          if  name  and  price:                  items.append({                          'name':  name,  'price':  price,                  })                  _show_items(items)   if  __name__  ==  '__main__':          add()
  5. $  python  accountant.py   What  to  buy:  Apples   Price:

     10   Item                                Price             -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   Apples                                  10
  6. File Objects • For reading files and file-like interfaces •

    Built-in type file • close(), read(), readline(), seek(), etc.
  7. Path Objects • import  pathlib • pathlib.Path • Path.cwd() •

    desktop  =  home  /  'Desktop' • home  =  desktop.parent
  8. import  pathlib   path  =  pathlib.Path('input.txt')   f  =  path.open()

      line  =  f.readline()   while  line:          print(line)          line  =  f.readline()   f.close()   print('ALL  DONE')
  9. import  pathlib   path  =  pathlib.Path('input.txt')   f  =  path.open()

      for  line  in  f:          print(line)   f.close()   print('ALL  DONE')
  10. import  pathlib   pathlib.Path('input.txt')   with  path.open()  as  f:  

           for  line  in  f:                  print(line)   print('ALL  DONE') File closed automatically on exiting.
  11. import  pathlib   path  =  pathlib.Path('output.txt')   with  path.open('w')  as

     f:          f.write('Hello  world!\n')   print('ALL  DONE')
  12. Python types JSON types int, float Number str String list,

    tuple, etc. Array dict, etc. Object None null
  13. import  pathlib   def  _get_save_path():          my_path

     =  pathlib.Path(__file__)          save_path  =  my_path.parent  /  'items.json'          return  save_path
  14. import  json   def  _load_items():          path

     =  _get_save_path()          try:                  with  path.open()  as  f:                          items  =  json.load(f)          except  (FileNotFoundError,  ValueError):                  items  =  []          return  items
  15. def  _save_items(items):        #  Your  turn!!  Implement  this.

      def  add():          items  =  _load_items()          #  Original  implementation.          _save_items(items)
  16. project   !""  accountant_venv   #      !""  ...

      !""  accountant.py   $""  items.json
  17. $  python  accountant.py   What  to  buy:  Apples   Price:

     10   Item                                Price             -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   Apples                                  10   $  python  accountant.py   What  to  buy:  Oranges   Price:  15   Item                                Price             -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   Apples                                  10   Oranges                                15
  18. $  python  accountant.py  add   What  to  buy:  Bananas  

    Price:  7   Item                                Price             -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   Apples                                  10   Oranges                                15   Bananas                                  7   $  python  accountant.py  show   Item                                Price             -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   Apples                                  10   Oranges                                15   Bananas                                  7
  19. $  pip  install  click   Collecting  click      Downloading

     click-­‐4.0-­‐py2.py3-­‐none-­‐any.whl  (62kB)          100%  |████████████████████████|  65kB  1.1MB/s     Installing  collected  packages:  click   Successfully  installed  click-­‐4.0   $
  20. pip • Python’s package manager • Manages packages on PyPI

    (Python Package Index) • pip  install, uninstall, freeze
  21. project   !""  accountant_venv   #      !""  ...

      !""  accountant.py   !""  items.json   $""  requirements.txt
  22. def  hi(name):          print('Hi'  +  name  +'!')

      greet  =  hi   greet('Mosky') First-class Functions
  23. def  get_name():          return  'TP'   def

     hi(name_getter,  words):          def  make_message(words):                  return  '  '.join(words)          print('{msg},  {name}!'.format(                  msg=make_message(words),                  name=name_getter(),          ))   hi(get_name,  ['Hello',  'there'])
  24. def  hi(name,  words):          def  make_message():  

                   return  '  '.join(words)          print('{msg},  {name}!'.format(                  msg=make_message(words),                  name=name,          ))   #  Prints  "Hello  there,  people!"   hi('people',  ['Hello',  'there'])
  25. def  outer_wrapper(func)          def  inner_wrapper(name):    

                 print('Before')                  func(name)                  print('After')          return  inner_wrapper   def  hi(name):          print('Hi,  {}!'.format(name))   #  What  happens  here?   outer_wrapper(hi)('Marty')
  26. def  outer_wrapper(func)          def  inner_wrapper(name):    

                 print('Before')                  func(name)                  print('After')          return  inner_wrapper   def  hi(name):          print('Hi,  {}!'.format(name))   #  What  happens  here?   outer_wrapper(hi)('Marty')
  27. def  outer_wrapper(func)          def  inner_wrapper(name):    

                 print('Before')                  func(name)                  print('After')          return  inner_wrapper   def  hi(name):          print('Hi,  {}!'.format(name))   #  What  happens  here?   outer_wrapper(hi)('Marty')
  28. def  outer_wrapper(func)          def  inner_wrapper(name):    

                 print('Before')                  func(name)                  print('After')          return  inner_wrapper   def  hi(name):          print('Hi,  {}!'.format(name))   #  What  happens  here?   outer_wrapper(hi)('Marty')
  29. def  outer_wrapper(func)          def  inner_wrapper(name):    

                 print('Before')                  func(name)                  print('After')          return  inner_wrapper   def  hi(name):          print('Hi,  {}!'.format(name))   hi  =  outer_wrapper(hi)   hi('Marty')
  30. def  outer_wrapper(func)          def  inner_wrapper(name):    

                 print('Before')                  func(name)                  print('After')          return  inner_wrapper   @outer_wrapper   def  hi(name):          print('Hi,  {}!'.format(name))   hi('Marty')
  31. import  click   @click.group()   def  cli():      

       pass   @cli.add_command   @click.command()   def  add():          #  Implementation  does  not  change.   if  __name__  ==  '__main__':          cli()
  32. $  python  accountant.py  add   What  to  buy:  Bananas  

    Price:  7   Item                                Price             -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   Apples                                  10   Oranges                                15   Bananas                                  7
  33. $  python  accountant.py   #  What  happens  here?   $

     python  accountant.py  -­‐-­‐help   #  What  happens  here?
  34. $  python  accountant.py  show   Item        

                           Price             -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   Apples                                  10   Oranges                                15   Bananas                                  7
  35. $  python  accountant.py  show   Item        

                           Price             -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   Apples                                  10   Oranges                                15   Bananas                                  7   $  python  accountant.py  remove  1   Item                                Price             -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐   Apples                                  10   Bananas                                  7
  36. #  remove_test.py   def  remove(index):          items

     =  [                  {'name':  'Apples',  'price':  10},                  {'name':  'Oranges',  'price':  15},          ]          #  㻛⡲...          #  㹀纏湫䱸䖰  accountant.py  䭠頺麓⢵կ          _show_items(items)   if  __name__  =  '__main__':          index  =  input('Index:  ')          remove(index)
  37. Keyword Arguments • print('Hello',  'World',  sep=',  ') • Named and

    unnamed arguments • Most arguments can be either
  38. def  hi(name,  message):          print('{},  {}!'.format(message,  name))

      #  Calling  with  positional  arguments.   hi('Doc',  'Hello')   #  Calling  with  keyword  arguments.   hi(message='Hello',  name='Doc')
  39. import  sys   print('Hello',  'World',          

       sep=',  ',  file=sys.stderr) Variable-length positional arguments keyword-only arguments
  40. @cli.add_command   @click.command()   @click.argument('index')   def  remove(index):    

         items  =  _load_items()          #  ...          #  Before  _show_items(items)          _save_items(items)
  41. $  python  accountant.py   #  What  happens  now?   $

     python  accountant.py  remove  0   #  What  happens?   $  python  accountant.py  remove   #  What  happens?
  42. $  python  accountant.py  show      #    Item  

                                 Price             -­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐-­‐      0    Apples                                  10      1    Oranges                                15      2    Bananas                                  7
  43. def  _show_items(items):          template  =  '{i:>3}  

     {name:20}{price:>5}'          #  ...          for  i  in  range(len(items)):                  item  =  items[i]                  print(template.format(                          i=i,  name=item['name'],                            price=item['price'],                  ))          print()
  44. def  _show_items(items):          template  =  '{i:>3}  

     {name:20}{price:>5}'          #  ...          i  =  0          for  item  in  items:                  print(template.format(                          i=i,  name=item['name'],                            price=item['price'],                  ))                  i  +=  1          print()
  45. def  _show_items(items):          template  =  '{i:>3}  

     {name:20}{price:>5}'          #  ...        for  i,  item  in  zip(range(len(items)),  items):                  print(template.format(                          i=i,  name=item['name'],                            price=item['price'],                  ))        print()
  46. def  _show_items(items):          template  =  '{i:>3}  

     {name:20}{price:>5}'          #  ...        for  i,  item  in  enumerate(items):                  print(template.format(                          i=i,  name=item['name'],                            price=item['price'],                  ))        print()
  47. Next Steps • Configurable _get_save_path • configparser module • Save

    as SQLite and other formats • sqlite3 module • Even more CLI improvements • colorama and palpatine • Any other ideas? Ask!