Nathan Wailes - Blog - GitHub - LinkedIn - Patreon - Reddit - Stack Overflow - Twitter - YouTube
Python
Table of contents
Child pages
- https://www.quora.com/Why-did-Quora-choose-Python-for-its-development
- Find or create an ab testing module for python that you can use with your emails
Criticisms of Python
- 2016.12.25 - ZenHack - Why Python Is Not My Favorite Language
- Posted by Yang on his Twitter
- Lack of Encapsulation - Python makes it more annoying than it should be to wall things off behind an interface.
- My summary: There's no protection / warning if you unknowingly try to use a private variable name (like "_bar") in a class you've created that subclasses another class that also uses that same private variable name.
- Weak Lambdas - Python's lambdas are seriously hamstrung: They can only be a single expression. No statements. Python has a bunch of built-in language features that would be totally obviated by adding a decent syntax for multi-statement lambdas.
- The 'with' statement's functionality could be done very simply with lambdas, and wouldn't need to have special code within the core Python codebase to handle just that feature.
- I couldn't make total sense of his decorator example. He seemed to be saying that, when using Flask, it's 'silly' to have to give your view-functions names when they're already uniquely defined by their string routes, and that in a language with strong support for lambdas you could just refer to the view-functions as unnamed/anonymous(?) functions, which would make the code easier to understand(?) / cleaner(?).
- Duck typing isn't very useful for production code - it is all too common in Python to either use nominal types anyway, or pass around mystery poultry.
- duck typing: If it looks like a duck and it quacks like a duck, it’s a duck. Or, as a more concrete example, if it’s got a next() method that returns the next element and raises StopIteration when you’re done, it’s an iterator.
- I didn't fully understand his example, but he seemed to be saying that, when using duck typing, you need to be sure to clearly document what your interfaces take as input and what they return, and once you're doing that much work, you might as well write the code in a slightly different way that'll do error checking for you, at which point there is no longer duck typing.
- duck typing: If it looks like a duck and it quacks like a duck, it’s a duck. Or, as a more concrete example, if it’s got a next() method that returns the next element and raises StopIteration when you’re done, it’s an iterator.
- Lack of a Type System - There are a few things that I really want a type system for: 1. Catching bugs earlier, 2. Refactoring, 3. Documentation
Learning resources
- PythonTutor (Visualize control flow): http://pythontutor.com/
- Dive Into Python (online book) - http://www.diveintopython.net/toc/index.html
- Google - 2 Day Intro-To-Python Class
- Khan Academy - Computer Science (uses Python)
- The New Boston - http://thenewboston.org/list.php?cat=36 - I'm on #27
- Books:
- Advanced:
- Advanced Python Performance Tips - http://blog.explainmydata.com/2012/07/expensive-lessons-in-python-performance.html
Information on miscellaneous tasks in Python
Creating a command-line program
Libraries
Articles / Videos
- 2017.08.30 - OpenSource.com - 3 open source Python GUI frameworks
- The command line offers many advantages—speed, remote access, reusability, scriptability, and control—which may be more important for your application's users than a graphical interface, and there are many libraries like Click, Cement, and Cliff that make it easier to design great command line programs.
Creating an executable (.exe)
- 2018.01.25 - I was having an issue using cx_freeze with Python 3.5.2, and then when I tried using pyinstaller it crashed during the installation. I read something in a GitHub issue that led me to try running the same commands in a command prompt (rather than from within PyCharm's terminal), and amazingly, both cx_freeze and pyinstaller commands completed without errors. The cx_freeze executable didn't print my "hello world" message, but the pyinstaller executable did.
Misc tricks
- Add logging to your code via a single decorator:
def run_with_logging(function): @wraps(function) def wrapped(*args, **kwargs): logging.basicConfig(filename='logs/' + function.__name__ + '.log', level=logging.DEBUG) logging.info('Starting at ' + str(datetime.now())) try: function(*args, **kwargs) except Exception as e: logging.exception(e) traceback_message = traceback.format_exc() send_an_email.send_email_with_error_message(traceback_message) logging.info('Finished at ' + str(datetime.now())) return wrapped
- For your main function (that kicks everything off), just add "@run_with_logging" above the function declaration.
- For anything you want logged in any submodules or subfunctions, just add a "logging.info(message)" to the code, and import "logging" into the module.
- Add info to an AssertionError:
try: assert(thing_you_want_to_check_for) except AssertionError as e: e.args += ("Invalid company domain", company_domain) raise
Optimizing Python programs
- Optimizing Python programs, PyPy to the rescue
- 7:35 - First focus on optimizing the complexity of your code.
- 12:30 - If switching to PyPy doesn't provide enough of a speed-up, you can use VMPROF to profile your program. He explains how to use it.
- 16:06 - I stopped here.
- 7:35 - First focus on optimizing the complexity of your code.
Packages
- How to install a package for a particular version of Python when you have multiple versions on your computer:
- python34 -m pip install packagename
PDFs
- It looks like I'll want to use ReportLab: http://stackoverflow.com/a/16632518/1513115
Testing
Misc learnings
- The nice thing about the assertIn() function is that when it fails, it tells you what the values were. This is really helpful if you've got a loop where the same assertion is being tried against several values, because otherwise you wouldn't know what value you need to debug (unless you added extra try/except code, which would get messy to have everywhere). The assertEqual function is useful for the same reason: if it fails, it not only tells you that the two things weren't equal (which is what a regular 'assert' statement would do), but it also tells you what the values of the two variables were.
Test-Driven Development
- Mutation testing in Python:
- 2008 - Python Module of the Week - unittest – Automated testing framework
- http://pymotw.com/2/unittest/
- - This was a very helpful introduction. He keeps it short and simple.
- - Check out "nose"
- How to organize python test in a way that I can run all tests in a single command?
- http://stackoverflow.com/questions/3667 ... gle-comman
- 2009 - infinitemonkeycorps.net - Python Project Howto (with a section on pylint and unittest)
- 2010.03.02 - Where do the Python unit tests go?
- http://stackoverflow.com/questions/6115 ... ts-go?rq=1
- 2013.01.03 - unittest introduction
- http://pythontesting.net/framework/unit ... roduction/
- 2013.02.21 - TutsPlus.com - Beginning Test-Driven Development in Python
- http://code.tutsplus.com/tutorials/begi ... -net-30137
- 2014(?) - Python-Guide.org - Testing Your Code
- 2014.06.29 - O'Reilly / Amazon - Test-Driven Development with Python
- http://www.amazon.com/Test-Driven-Devel ... 1449364829
- - The book seems to follow the same route as Hartl's RoR book: it goes through a single large web development project