SlideShare a Scribd company logo
Developing a nice template for new scripts
#!/usr/bin/python import sys import random def scramble(word): if len(word) < 4: return word innards = list(word[1:-1]) random.shuffle(innards) return word[0] + ''.join(innards) + word[-1] while 1: line = sys.stdin.readline() if not line: break sys.stdout.write(' '.join([scramble(w) for w in line.split()]) + '\n') In the beginning
Adding basic niceties #!/usr/bin/ env  python # -*- coding: utf-8 -*- import sys import random def scramble(word): if len(word) < 4: return word innards = list(word[1:-1]) random.shuffle(innards) return word[0] + ''.join(innards) + word[-1] def _main(): while 1: line = sys.stdin.readline() if not line: break sys.stdout.write(' '.join([scramble(w) for w in line.split()]) + '\n') return 0 if __name__ == &quot;__main__&quot;: sys.exit(_main())
stephenj@lords:~$ python Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49)  [GCC 4.3.2] on linux2 Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information. >>> import scramble >>> scramble.scramble('scramble') 'srlacmbe' >>>
from optparse import OptionParser ... def _main(filename=None): ... if __name__ == &quot;__main__&quot;: usage = &quot;usage: %prog [options] [filename]&quot; parser = OptionParser(usage=usage) parser.add_option('--profile', '-P', help  = &quot;Print out profiling stats&quot;, action  = 'store_true') parser.add_option('--test', '-t', help  ='Run doctests', action = 'store_true') parser.add_option('--verbose', '-v', help  ='print debugging output', action = 'store_true') (options, args) = parser.parse_args() # Assign non-flag arguments here. filename = None if len(args) > 0: filename = args[0]
stephenj@lords:~$ python scramble.py -h Usage: scramble.py [options] [filename] Options: -h, --help  show this help message and exit -P, --profile  Print out profiling stats -t, --test  Run doctests -v, --verbose  print debugging output
Tests are good def scramble(word): &quot;&quot;&quot; Returns a scrambled version if it is longer than 3 chars.  Scrambling preserves the first and last characters. >>> scramble('a') 'a' >>> scramble('an') 'an' >>> scramble('the') 'the' >>> scramble('cart') in ['cart', 'crat'] True &quot;&quot;&quot; if len(word) < 4: return word innards = list(word[1:-1]) random.shuffle(innards) return word[0] + ''.join(innards) + word[-1] def _test(verbose=False): import doctest doctest.testmod(verbose=verbose)
stephenj@lords:~$ python scramble.py --test --verbose Trying: scramble('a') Expecting: 'a' ok Trying: scramble('an') Expecting: 'an' ok Trying: scramble('the') Expecting: 'the' ok Trying: scramble('cart') in ['cart', 'crat'] Expecting: True ok 5 items had no tests: __main__ __main__._main __main__._profile_main __main__._test __main__.really_blurt 1 items passed all tests: 4 tests in __main__.scramble 4 tests in 6 items. 4 passed and 0 failed. Test passed. stephenj@lords:~$
Now I'm a real  boy  Unix filter def _blurt(s, f): pass def _main(filename=None): f = sys.stdin if filename: try: f = file(filename) except Exception, ex: print &quot;Couldn't open file %s: %s&quot; % (filename, ex) return 1 while 1: line =  f.readline() if not line: break _blurt(&quot;Original line was: %s&quot; % line) sys.stdout.write(' '.join([scramble(w) for w in line.split()]) + '\n') return 0 if __name__ == &quot;__main__&quot;: ... if options.verbose: def really_blurt(s, f=()): sys.stderr.write(s % f + '\n') _blurt = really_blurt ... if len(args) > 0: filename = args[0] _blurt(&quot;filename is %s&quot;, filename) sys.exit(_main(filename))
Dealing with performance anxiety def _profile_main(filename=None): import cProfile, pstats prof = cProfile.Profile() ctx = &quot;&quot;&quot;_main(filename)&quot;&quot;&quot; prof = prof.runctx(ctx, globals(), locals()) stats = pstats.Stats(prof) stats.sort_stats(&quot;cumulative&quot;) stats.print_stats(10) ... if __name__ == &quot;__main__&quot;: ... if options.profile: _profile_main(filename) exit()
Making use of our options stephenj@lords:~$ python scramble.py asdf Couldn't open file asdf: [Errno 2] No such file or directory: 'asdf' stephenj@lords:~$ echo $? 1 stephenj@lords:~$ echo &quot;You should probably be able to understand this&quot; | python scramble.py -v Original line was: You should probably be able to understand this You suhold pbrbolay be able to usedanrntd this stephenj@lords:~$ echo &quot;You should probably be able to understand this&quot; | python scramble.py -P You sluohd pbalbroy be albe to unrdentsad tihs 57 function calls in 0.000 CPU seconds Ordered by: internal time List reduced from 12 to 10 due to restriction <10> ncalls  tottime  percall  cumtime  percall filename:lineno(function) 5  0.000  0.000  0.000  0.000 /usr/lib/python2.5/random.py:250(shuffle) 8  0.000  0.000  0.000  0.000 scramble.py:16(scramble) 1  0.000  0.000  0.000  0.000 scramble.py:59(_main) 1  0.000  0.000  0.000  0.000 {method 'write' of 'file' objects} 17  0.000  0.000  0.000  0.000 {method 'random' of '_random.Random' objects} 2  0.000  0.000  0.000  0.000 {method 'readline' of 'file' objects} 13  0.000  0.000  0.000  0.000 {len} 6  0.000  0.000  0.000  0.000 {method 'join' of 'str' objects} 1  0.000  0.000  0.000  0.000 <string>:1(<module>) 1  0.000  0.000  0.000  0.000 {method 'split' of 'str' objects}
#!/usr/bin/env python # -*- coding: utf-8 -*- import sys from optparse import OptionParser def _test(verbose=None): import doctest doctest.testmod(verbose=verbose) def _profile_main( filename=None ): import cProfile, pstats prof = cProfile.Profile() ctx = &quot;&quot;&quot;_main(filename)&quot;&quot;&quot; prof = prof.runctx(ctx, globals(), locals()) stats = pstats.Stats(prof) stats.sort_stats(&quot;time&quot;) stats.print_stats(10) def _blurt(s, f): pass def _main(filename=None): # YOUR CODE HERE return 0 if __name__ == &quot;__main__&quot;: usage = &quot;usage: %prog [options]  [filename] &quot; parser = OptionParser(usage=usage) parser.add_option('--profile', '-P', help  = &quot;Print out profiling stats&quot;, action  = 'store_true') parser.add_option('--test', '-t', help  ='Run doctests', action = 'store_true') parser.add_option('--verbose', '-v', help  ='print debugging output', action = 'store_true') (options, args) = parser.parse_args() if options.verbose: def really_blurt(s, f=()): sys.stderr.write(s % f + '\n') _blurt = really_blurt # Assign non-flag arguments here. filename = args[0] if options.profile: _profile_main( filename ) exit() if options.test: _test(verbose=options.verbose) exit() sys.exit(_main( filename ))
Original inspiration Guido's post and subsequent commentary http://www.artima.com/forums/flat.jsp?forum=106&thread=4829 Google app engine help http://code.google.com/appengine/kb/commontasks.html#profiling The scrambled text meme http://www.snopes.com/language/apocryph/cambridge.asp

More Related Content

PDF
Python and sysadmin I
Guixing Bai
 
ODP
Programming Under Linux In Python
Marwan Osman
 
PDF
Python fundamentals - basic | WeiYuan
Wei-Yuan Chang
 
PPT
Software Exploits
KevinCSmallwood
 
PDF
Good Evils In Perl
Kang-min Liu
 
ODP
PHP 5.3 And PHP 6 A Look Ahead
thinkphp
 
PDF
Having Fun Programming!
Aaron Patterson
 
PDF
Top 10 php classic traps
Damien Seguy
 
Python and sysadmin I
Guixing Bai
 
Programming Under Linux In Python
Marwan Osman
 
Python fundamentals - basic | WeiYuan
Wei-Yuan Chang
 
Software Exploits
KevinCSmallwood
 
Good Evils In Perl
Kang-min Liu
 
PHP 5.3 And PHP 6 A Look Ahead
thinkphp
 
Having Fun Programming!
Aaron Patterson
 
Top 10 php classic traps
Damien Seguy
 

What's hot (20)

PPTX
python beginner talk slide
jonycse
 
PDF
AmI 2016 - Python basics
Luigi De Russis
 
PPTX
P3 2018 python_regexes
Prof. Wim Van Criekinge
 
PPTX
Five
Łukasz Langa
 
PDF
Don't do this
Richard Jones
 
PDF
PHP 7 – What changed internally?
Nikita Popov
 
PDF
PHP 7 – What changed internally? (Forum PHP 2015)
Nikita Popov
 
PDF
SWP - A Generic Language Parser
kamaelian
 
PDF
Introdução ao Perl 6
garux
 
PDF
Matlab and Python: Basic Operations
Wai Nwe Tun
 
PPS
Bdd: Tdd and beyond the infinite
Giordano Scalzo
 
PDF
Top 10 pieges php afup limoges
Damien Seguy
 
PDF
Perl 6 by example
Andrew Shitov
 
PPTX
Learn python - for beginners - part-2
RajKumar Rampelli
 
PPT
Profiling and optimization
g3_nittala
 
PDF
A tour of Python
Aleksandar Veselinovic
 
PDF
Perl 6 in Context
lichtkind
 
PDF
PHP 7 – What changed internally? (PHP Barcelona 2015)
Nikita Popov
 
PDF
The Perl6 Type System
abrummett
 
PPTX
Down the rabbit hole, profiling in Django
Remco Wendt
 
python beginner talk slide
jonycse
 
AmI 2016 - Python basics
Luigi De Russis
 
P3 2018 python_regexes
Prof. Wim Van Criekinge
 
Don't do this
Richard Jones
 
PHP 7 – What changed internally?
Nikita Popov
 
PHP 7 – What changed internally? (Forum PHP 2015)
Nikita Popov
 
SWP - A Generic Language Parser
kamaelian
 
Introdução ao Perl 6
garux
 
Matlab and Python: Basic Operations
Wai Nwe Tun
 
Bdd: Tdd and beyond the infinite
Giordano Scalzo
 
Top 10 pieges php afup limoges
Damien Seguy
 
Perl 6 by example
Andrew Shitov
 
Learn python - for beginners - part-2
RajKumar Rampelli
 
Profiling and optimization
g3_nittala
 
A tour of Python
Aleksandar Veselinovic
 
Perl 6 in Context
lichtkind
 
PHP 7 – What changed internally? (PHP Barcelona 2015)
Nikita Popov
 
The Perl6 Type System
abrummett
 
Down the rabbit hole, profiling in Django
Remco Wendt
 
Ad

Similar to The bones of a nice Python script (20)

PPT
Python - Getting to the Essence - Points.com - Dave Park
pointstechgeeks
 
ODP
Why Python by Marilyn Davis, Marakana
Marko Gargenta
 
PDF
A Taste of Python - Devdays Toronto 2009
Jordan Baker
 
PPTX
files.pptx
KeerthanaM738437
 
PPTX
Basics of Python programming (part 2)
Pedro Rodrigues
 
PDF
Python Performance 101
Ankur Gupta
 
PDF
intro_to_python_20150825
Shung-Hsi Yu
 
PPTX
Learn python in 20 minutes
Sidharth Nadhan
 
PDF
python codes
tusharpanda88
 
PDF
Functions and modules in python
Karin Lagesen
 
PPTX
File Programs with Solutions on python.pptx
yogeshprasanna313
 
PPTX
Python Course Module 2 Topics and content
anuragrai759829
 
PDF
Python tutorial
Andrei Tomoroga
 
PPTX
Pygrunn 2012 down the rabbit - profiling in python
Remco Wendt
 
PPT
Python scripting kick off
Andrea Gangemi
 
ODP
Python quickstart for programmers: Python Kung Fu
climatewarrior
 
PPTX
10 Python file.pptx
SUJALORAON
 
PDF
Snakes for Camels
miquelruizm
 
PDF
python cheat sheat, Data science, Machine learning
TURAGAVIJAYAAKASH
 
PDF
2. Python Cheat Sheet.pdf
MeghanaDBengalur
 
Python - Getting to the Essence - Points.com - Dave Park
pointstechgeeks
 
Why Python by Marilyn Davis, Marakana
Marko Gargenta
 
A Taste of Python - Devdays Toronto 2009
Jordan Baker
 
files.pptx
KeerthanaM738437
 
Basics of Python programming (part 2)
Pedro Rodrigues
 
Python Performance 101
Ankur Gupta
 
intro_to_python_20150825
Shung-Hsi Yu
 
Learn python in 20 minutes
Sidharth Nadhan
 
python codes
tusharpanda88
 
Functions and modules in python
Karin Lagesen
 
File Programs with Solutions on python.pptx
yogeshprasanna313
 
Python Course Module 2 Topics and content
anuragrai759829
 
Python tutorial
Andrei Tomoroga
 
Pygrunn 2012 down the rabbit - profiling in python
Remco Wendt
 
Python scripting kick off
Andrea Gangemi
 
Python quickstart for programmers: Python Kung Fu
climatewarrior
 
10 Python file.pptx
SUJALORAON
 
Snakes for Camels
miquelruizm
 
python cheat sheat, Data science, Machine learning
TURAGAVIJAYAAKASH
 
2. Python Cheat Sheet.pdf
MeghanaDBengalur
 
Ad

Recently uploaded (20)

PPTX
Stamford - Community User Group Leaders_ Agentblazer Status, AI Sustainabilit...
Amol Dixit
 
PDF
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
 
PPT
Coupa-Kickoff-Meeting-Template presentai
annapureddyn
 
PDF
DevOps & Developer Experience Summer BBQ
AUGNYC
 
PPTX
What-is-the-World-Wide-Web -- Introduction
tonifi9488
 
PPTX
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
PDF
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
PDF
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
PPTX
How to Build a Scalable Micro-Investing Platform in 2025 - A Founder’s Guide ...
Third Rock Techkno
 
PDF
REPORT: Heating appliances market in Poland 2024
SPIUG
 
PDF
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
PDF
Revolutionize Operations with Intelligent IoT Monitoring and Control
Rejig Digital
 
PDF
Best ERP System for Manufacturing in India | Elite Mindz
Elite Mindz
 
PDF
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
PPTX
ChatGPT's Deck on The Enduring Legacy of Fax Machines
Greg Swan
 
PDF
CIFDAQ'S Market Insight: BTC to ETH money in motion
CIFDAQ
 
PPTX
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
PDF
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
 
PDF
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
PDF
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
 
Stamford - Community User Group Leaders_ Agentblazer Status, AI Sustainabilit...
Amol Dixit
 
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
 
Coupa-Kickoff-Meeting-Template presentai
annapureddyn
 
DevOps & Developer Experience Summer BBQ
AUGNYC
 
What-is-the-World-Wide-Web -- Introduction
tonifi9488
 
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
 
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
How to Build a Scalable Micro-Investing Platform in 2025 - A Founder’s Guide ...
Third Rock Techkno
 
REPORT: Heating appliances market in Poland 2024
SPIUG
 
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
Revolutionize Operations with Intelligent IoT Monitoring and Control
Rejig Digital
 
Best ERP System for Manufacturing in India | Elite Mindz
Elite Mindz
 
Data_Analytics_vs_Data_Science_vs_BI_by_CA_Suvidha_Chaplot.pdf
CA Suvidha Chaplot
 
ChatGPT's Deck on The Enduring Legacy of Fax Machines
Greg Swan
 
CIFDAQ'S Market Insight: BTC to ETH money in motion
CIFDAQ
 
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
 
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
 

The bones of a nice Python script

  • 1. Developing a nice template for new scripts
  • 2. #!/usr/bin/python import sys import random def scramble(word): if len(word) < 4: return word innards = list(word[1:-1]) random.shuffle(innards) return word[0] + ''.join(innards) + word[-1] while 1: line = sys.stdin.readline() if not line: break sys.stdout.write(' '.join([scramble(w) for w in line.split()]) + '\n') In the beginning
  • 3. Adding basic niceties #!/usr/bin/ env python # -*- coding: utf-8 -*- import sys import random def scramble(word): if len(word) < 4: return word innards = list(word[1:-1]) random.shuffle(innards) return word[0] + ''.join(innards) + word[-1] def _main(): while 1: line = sys.stdin.readline() if not line: break sys.stdout.write(' '.join([scramble(w) for w in line.split()]) + '\n') return 0 if __name__ == &quot;__main__&quot;: sys.exit(_main())
  • 4. stephenj@lords:~$ python Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49) [GCC 4.3.2] on linux2 Type &quot;help&quot;, &quot;copyright&quot;, &quot;credits&quot; or &quot;license&quot; for more information. >>> import scramble >>> scramble.scramble('scramble') 'srlacmbe' >>>
  • 5. from optparse import OptionParser ... def _main(filename=None): ... if __name__ == &quot;__main__&quot;: usage = &quot;usage: %prog [options] [filename]&quot; parser = OptionParser(usage=usage) parser.add_option('--profile', '-P', help = &quot;Print out profiling stats&quot;, action = 'store_true') parser.add_option('--test', '-t', help ='Run doctests', action = 'store_true') parser.add_option('--verbose', '-v', help ='print debugging output', action = 'store_true') (options, args) = parser.parse_args() # Assign non-flag arguments here. filename = None if len(args) > 0: filename = args[0]
  • 6. stephenj@lords:~$ python scramble.py -h Usage: scramble.py [options] [filename] Options: -h, --help show this help message and exit -P, --profile Print out profiling stats -t, --test Run doctests -v, --verbose print debugging output
  • 7. Tests are good def scramble(word): &quot;&quot;&quot; Returns a scrambled version if it is longer than 3 chars. Scrambling preserves the first and last characters. >>> scramble('a') 'a' >>> scramble('an') 'an' >>> scramble('the') 'the' >>> scramble('cart') in ['cart', 'crat'] True &quot;&quot;&quot; if len(word) < 4: return word innards = list(word[1:-1]) random.shuffle(innards) return word[0] + ''.join(innards) + word[-1] def _test(verbose=False): import doctest doctest.testmod(verbose=verbose)
  • 8. stephenj@lords:~$ python scramble.py --test --verbose Trying: scramble('a') Expecting: 'a' ok Trying: scramble('an') Expecting: 'an' ok Trying: scramble('the') Expecting: 'the' ok Trying: scramble('cart') in ['cart', 'crat'] Expecting: True ok 5 items had no tests: __main__ __main__._main __main__._profile_main __main__._test __main__.really_blurt 1 items passed all tests: 4 tests in __main__.scramble 4 tests in 6 items. 4 passed and 0 failed. Test passed. stephenj@lords:~$
  • 9. Now I'm a real boy Unix filter def _blurt(s, f): pass def _main(filename=None): f = sys.stdin if filename: try: f = file(filename) except Exception, ex: print &quot;Couldn't open file %s: %s&quot; % (filename, ex) return 1 while 1: line = f.readline() if not line: break _blurt(&quot;Original line was: %s&quot; % line) sys.stdout.write(' '.join([scramble(w) for w in line.split()]) + '\n') return 0 if __name__ == &quot;__main__&quot;: ... if options.verbose: def really_blurt(s, f=()): sys.stderr.write(s % f + '\n') _blurt = really_blurt ... if len(args) > 0: filename = args[0] _blurt(&quot;filename is %s&quot;, filename) sys.exit(_main(filename))
  • 10. Dealing with performance anxiety def _profile_main(filename=None): import cProfile, pstats prof = cProfile.Profile() ctx = &quot;&quot;&quot;_main(filename)&quot;&quot;&quot; prof = prof.runctx(ctx, globals(), locals()) stats = pstats.Stats(prof) stats.sort_stats(&quot;cumulative&quot;) stats.print_stats(10) ... if __name__ == &quot;__main__&quot;: ... if options.profile: _profile_main(filename) exit()
  • 11. Making use of our options stephenj@lords:~$ python scramble.py asdf Couldn't open file asdf: [Errno 2] No such file or directory: 'asdf' stephenj@lords:~$ echo $? 1 stephenj@lords:~$ echo &quot;You should probably be able to understand this&quot; | python scramble.py -v Original line was: You should probably be able to understand this You suhold pbrbolay be able to usedanrntd this stephenj@lords:~$ echo &quot;You should probably be able to understand this&quot; | python scramble.py -P You sluohd pbalbroy be albe to unrdentsad tihs 57 function calls in 0.000 CPU seconds Ordered by: internal time List reduced from 12 to 10 due to restriction <10> ncalls tottime percall cumtime percall filename:lineno(function) 5 0.000 0.000 0.000 0.000 /usr/lib/python2.5/random.py:250(shuffle) 8 0.000 0.000 0.000 0.000 scramble.py:16(scramble) 1 0.000 0.000 0.000 0.000 scramble.py:59(_main) 1 0.000 0.000 0.000 0.000 {method 'write' of 'file' objects} 17 0.000 0.000 0.000 0.000 {method 'random' of '_random.Random' objects} 2 0.000 0.000 0.000 0.000 {method 'readline' of 'file' objects} 13 0.000 0.000 0.000 0.000 {len} 6 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects} 1 0.000 0.000 0.000 0.000 <string>:1(<module>) 1 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects}
  • 12. #!/usr/bin/env python # -*- coding: utf-8 -*- import sys from optparse import OptionParser def _test(verbose=None): import doctest doctest.testmod(verbose=verbose) def _profile_main( filename=None ): import cProfile, pstats prof = cProfile.Profile() ctx = &quot;&quot;&quot;_main(filename)&quot;&quot;&quot; prof = prof.runctx(ctx, globals(), locals()) stats = pstats.Stats(prof) stats.sort_stats(&quot;time&quot;) stats.print_stats(10) def _blurt(s, f): pass def _main(filename=None): # YOUR CODE HERE return 0 if __name__ == &quot;__main__&quot;: usage = &quot;usage: %prog [options] [filename] &quot; parser = OptionParser(usage=usage) parser.add_option('--profile', '-P', help = &quot;Print out profiling stats&quot;, action = 'store_true') parser.add_option('--test', '-t', help ='Run doctests', action = 'store_true') parser.add_option('--verbose', '-v', help ='print debugging output', action = 'store_true') (options, args) = parser.parse_args() if options.verbose: def really_blurt(s, f=()): sys.stderr.write(s % f + '\n') _blurt = really_blurt # Assign non-flag arguments here. filename = args[0] if options.profile: _profile_main( filename ) exit() if options.test: _test(verbose=options.verbose) exit() sys.exit(_main( filename ))
  • 13. Original inspiration Guido's post and subsequent commentary http://www.artima.com/forums/flat.jsp?forum=106&thread=4829 Google app engine help http://code.google.com/appengine/kb/commontasks.html#profiling The scrambled text meme http://www.snopes.com/language/apocryph/cambridge.asp