Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Confessions of Joe Developer

16,081 views

Published on

Admitting my flaws and turning them into virtues! This is a full length talk given it at DjangoCon US 2011, PyCon Australia 2011, and LA Django. The earliest version was a lightning talk given at the 2011 Hollywood hackathon.

Confessions of Joe Developer

  1. Confessions ofJoe Developer Daniel Greenfeld
  2. Daniel Greenfeld @pydanny Who am I? Daniel Greenfeld (@pydanny) Pythonista at Cartwheel Djangonaut at Revsys Co-lead of djangopackages.com & Packaginator (Open Comparison) Fiancé of Audrey Royhttp://www.flickr.com/photos/pydanny/4442245488
  3. Why am I talking?
  4. I’m stupid and lazy
  5. I’m stupid
  6. Daniel Greenfeld @pydannyI’m stupid
  7. Daniel Greenfeld @pydanny I’m stupid• Can’t figure things out
  8. Daniel Greenfeld @pydanny I’m stupid• Can’t figure things out• Can’t remember things
  9. Daniel Greenfeld @pydanny I’m stupid• Can’t figure things out• Can’t remember things• Too stupid not to ask stupid questions
  10. Daniel Greenfeld @pydanny I’m stupidCan’t figure things out
  11. Daniel Greenfeld @pydanny I’m stupid Can’t figure things out• If I get stuck for more than 30 minutes...
  12. Daniel Greenfeld @pydanny I’m stupid Can’t figure things out• If I get stuck for more than 30 minutes... • Find libraries that do it for me
  13. Daniel Greenfeld @pydanny I’m stupid Can’t figure things out• If I get stuck for more than 30 minutes... • Find libraries that do it for me • Ask on Twitter for answers
  14. Daniel Greenfeld @pydanny I’m stupid Can’t figure things out• If I get stuck for more than 30 minutes... • Find libraries that do it for me • Ask on Twitter for answers • Stack Overflow is also good, but watch for trolls.
  15. Daniel Greenfeld @pydanny I’m stupid Can’t figure things out• If I get stuck for more than 30 minutes... • Find libraries that do it for me • Ask on Twitter for answers • Stack Overflow is also good, but watch for trolls. • IRC can be good, if you get a troll try a different channel.
  16. Daniel Greenfeld @pydanny I’m stupidCan’t figure things out
  17. Daniel Greenfeld @pydanny I’m stupid Can’t figure things out “Smart” people way# This sample gleefully taken from https://gist.github.com/973705import urllib2gh_url = https://api.github.comgh_user= usergh_pass = passreq = urllib2.Request(gh_url)password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()password_manager.add_password(None, gh_url, gh_user, gh_pass)auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)opener = urllib2.build_opener(auth_manager)urllib2.install_opener(opener)handler = urllib2.urlopen(req)print handler.getcode()print handler.headers.getheader(content-type)# ------# 200# application/json
  18. Daniel Greenfeld @pydanny I’m stupid Can’t figure things out “Smart” people way PyDanny way# This sample gleefully taken from https://gist.github.com/973705 # This sample joyfully taken fromimport urllib2 # https://gist.github.com/973705gh_url = https://api.github.comgh_user= usergh_pass = pass import requestsreq = urllib2.Request(gh_url) r = requests.get(https://api.github.com,password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() auth=(user, pass))password_manager.add_password(None, gh_url, gh_user, gh_pass)auth_manager = urllib2.HTTPBasicAuthHandler(password_manager) print r.status_codeopener = urllib2.build_opener(auth_manager) print r.headers[content-type]urllib2.install_opener(opener)handler = urllib2.urlopen(req) # ------ # 200print handler.getcode()print handler.headers.getheader(content-type) # application/json# ------# 200# application/json
  19. Daniel Greenfeld @pydannyI’m stupid ‘Smart way’ aka hard way
  20. Daniel Greenfeld @pydanny I’m stupid# This sample gleefully taken from# https://gist.github.com/973705 ‘Smart way’import urllib2 akagh_url = https://api.github.comgh_user= usergh_pass = pass hard wayreq = urllib2.Request(gh_url)password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()password_manager.add_password(None, gh_url, gh_user, gh_pass)auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)opener = urllib2.build_opener(auth_manager)urllib2.install_opener(opener)handler = urllib2.urlopen(req)print handler.getcode()print handler.headers.getheader(content-type)# ------# 200# application/json
  21. Daniel Greenfeld @pydanny I’m stupid # This sample gleefully taken from # https://gist.github.com/973705 ‘Smart way’ What import urllib2 akais this? gh_url = https://api.github.com gh_user= user gh_pass = pass hard way req = urllib2.Request(gh_url) password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() password_manager.add_password(None, gh_url, gh_user, gh_pass) auth_manager = urllib2.HTTPBasicAuthHandler(password_manager) opener = urllib2.build_opener(auth_manager) urllib2.install_opener(opener) handler = urllib2.urlopen(req) print handler.getcode() print handler.headers.getheader(content-type) # ------ # 200 # application/json
  22. Daniel Greenfeld @pydanny I’m stupid # This sample gleefully taken from # https://gist.github.com/973705 ‘Smart way’ What import urllib2 akais this? gh_url = https://api.github.com gh_user= user gh_pass = pass hard way req = urllib2.Request(gh_url) password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() password_manager.add_password(None, gh_url, gh_user, gh_pass) auth_manager = urllib2.HTTPBasicAuthHandler(password_manager) opener = urllib2.build_opener(auth_manager) And urllib2.install_opener(opener) this? handler = urllib2.urlopen(req) print handler.getcode() print handler.headers.getheader(content-type) # ------ # 200 # application/json
  23. Daniel Greenfeld @pydanny I’m stupid # This sample gleefully taken from # https://gist.github.com/973705 ‘Smart way’ What import urllib2 akais this? gh_url = https://api.github.com gh_user= user gh_pass = pass hard way req = urllib2.Request(gh_url) password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() password_manager.add_password(None, gh_url, gh_user, gh_pass) auth_manager = urllib2.HTTPBasicAuthHandler(password_manager) opener = urllib2.build_opener(auth_manager) And urllib2.install_opener(opener) What is an this? install opener? handler = urllib2.urlopen(req) print handler.getcode() print handler.headers.getheader(content-type) # ------ # 200 # application/json
  24. Daniel Greenfeld @pydanny I’m stupid # This sample gleefully taken from # https://gist.github.com/973705 ‘Smart way’ What import urllib2 akais this? gh_url = https://api.github.com gh_user= user gh_pass = pass hard way req = urllib2.Request(gh_url) password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() password_manager.add_password(None, gh_url, gh_user, gh_pass) auth_manager = urllib2.HTTPBasicAuthHandler(password_manager) opener = urllib2.build_opener(auth_manager) And urllib2.install_opener(opener) What is an this? install opener? handler = urllib2.urlopen(req) print handler.getcode() print handler.headers.getheader(content-type) Finally we make # ------ the request! # 200 # application/json
  25. Daniel Greenfeld @pydanny I’m stupid ‘Stupid way’ akaCan’t figure things out easy way
  26. Daniel Greenfeld @pydanny I’m stupid ‘Stupid way’ aka Can’t figure things out easy way# This sample joyfully taken from# https://gist.github.com/973705import requestsr = requests.get(https://api.github.com, auth=(user, pass))print r.status_codeprint r.headers[content-type]# ------# 200# application/json
  27. Daniel Greenfeld @pydanny I’m stupid ‘Stupid way’ akaHTTP Can’t figure things outGET easy way # This sample joyfully taken from # https://gist.github.com/973705 import requests r = requests.get(https://api.github.com, auth=(user, pass)) print r.status_code print r.headers[content-type] # ------ # 200 # application/json
  28. Daniel Greenfeld @pydanny I’m stupid ‘Stupid way’ akaHTTP Can’t figure things outGET easy way # This sample joyfully taken from # https://gist.github.com/973705 import requests r = requests.get(https://api.github.com,Username auth=(user, pass)) + print r.status_codePassword print r.headers[content-type] # ------ # 200 # application/json
  29. Daniel Greenfeld @pydanny I’m stupid Can’t figure things out “Smart” people way PyDanny way# This sample gleefully taken from https://gist.github.com/973705 # This sample joyfully taken fromimport urllib2 # https://gist.github.com/973705gh_url = https://api.github.comgh_user= usergh_pass = pass import requestsreq = urllib2.Request(gh_url) r = requests.get(https://api.github.com,password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm() auth=(user, pass))password_manager.add_password(None, gh_url, gh_user, gh_pass)auth_manager = urllib2.HTTPBasicAuthHandler(password_manager) print r.status_codeopener = urllib2.build_opener(auth_manager) print r.headers[content-type]urllib2.install_opener(opener)handler = urllib2.urlopen(req) # ------ # 200print handler.getcode()print handler.headers.getheader(content-type) # application/json# ------# 200# application/json
  30. Daniel Greenfeld @pydanny I’m stupidToo stupid not to ask stupid questions
  31. Daniel Greenfeld @pydanny I’m stupidToo stupid not to ask stupid questions • There are no stupid questions
  32. Daniel Greenfeld @pydanny I’m stupidToo stupid not to ask stupid questions • There are no stupid questions • Don’t try and impress the people around you by not asking questions.
  33. Daniel Greenfeld @pydanny I’m stupidToo stupid not to ask stupid questions You are at DjangoCon. If you don’t ask the question, you are wasting opportunity.
  34. Daniel Greenfeld @pydanny I’m stupidToo stupid not to ask stupid questions You are at DjangoCon. A positive trait good tech leads often look for is the ability to ask questions.
  35. Daniel Greenfeld @pydanny I’m stupidCan’t remember things
  36. Daniel Greenfeld @pydanny I’m stupid Can’t remember things• Documentation makes me look good
  37. Daniel Greenfeld @pydanny I’m stupid Can’t remember things• Documentation makes me look good• Docstrings are awesome
  38. Daniel Greenfeld @pydanny I’m stupid Can’t remember things• Documentation makes me look good• Docstrings are awesome• Learn you some Restructured Text
  39. Daniel Greenfeld @pydanny I’m stupid Can’t remember things• Documentation makes me look good• Docstrings are awesome• Learn you some Restructured Text• Write down even the slide bullets!
  40. Daniel Greenfeld @pydanny I’m stupid Can’t remember things• Documentation makes me look good• Docstrings are awesome• Learn you some Restructured Text• Write down even the slide bullets!• https://github.com/pydanny/pydanny-event-notes
  41. Daniel Greenfeld Joe Developer @pydanny Resources Where the code examples live!https://github.com/pydanny/django-party-pack http://django-party-pack.rtfd.org/
  42. Daniel Greenfeld @pydanny I’m stupidhttp://readthedocs.org/docs/django-party-pack
  43. Daniel Greenfeld @pydanny I’m stupidSphinxmakes me lookgood! http://readthedocs.org/docs/django-party-pack
  44. Daniel Greenfeld @pydanny Docs/Sphinx Basics• pip install sphinx• make a docs directory• sphinx-quickstart• Follow instructions• Starting over is just removing your docs
  45. Daniel Greenfeld @pydanny I’m stupid Sphinx makes me look good! ============= Installation ============= .. note:: For things with **font like this** it means type it at the command line and hit enter. The Basics =========== 0. **git clone https://pydanny@github.com/pydanny/django-party-pack.git** 1. Make sure you have virtualenv installed. 2. change directory to the directory that contains this README.rst file. 3. **virtualenv pollaxe** and then **source pollaxe/bin/activate** 4. **pip install -r requirements.txt** 5. **mkdir pollaxe/coverage** Building the sphinx docs ========================= 1. change directory to docs 2. **make html** Running django-coverage ======================== 1. python manage.py testhttp://readthedocs.org/docs/django-party-pack/en/latest/_sources/install.txt
  46. Daniel Greenfeld @pydanny pageheader I’m stupid Sphinx makes me look good! ============= Installation ============= .. note:: For things with **font like this** it means type it at the command line and hit enter. The Basics =========== 0. **git clone https://pydanny@github.com/pydanny/django-party-pack.git** 1. Make sure you have virtualenv installed. 2. change directory to the directory that contains this README.rst file. 3. **virtualenv pollaxe** and then **source pollaxe/bin/activate** 4. **pip install -r requirements.txt** 5. **mkdir pollaxe/coverage** Building the sphinx docs ========================= 1. change directory to docs 2. **make html** Running django-coverage ======================== 1. python manage.py test http://readthedocs.org/docs/django-party-pack/en/latest/_sources/install.txt
  47. Daniel Greenfeld @pydanny pageheader I’m stupid Sphinx makes me look good! =============note Installation =============block .. note:: For things with **font like this** it means type it at the command line and hit enter. The Basics =========== 0. **git clone https://pydanny@github.com/pydanny/django-party-pack.git** 1. Make sure you have virtualenv installed. 2. change directory to the directory that contains this README.rst file. 3. **virtualenv pollaxe** and then **source pollaxe/bin/activate** 4. **pip install -r requirements.txt** 5. **mkdir pollaxe/coverage** Building the sphinx docs ========================= 1. change directory to docs 2. **make html** Running django-coverage ======================== 1. python manage.py test http://readthedocs.org/docs/django-party-pack/en/latest/_sources/install.txt
  48. Daniel Greenfeld @pydanny pageheader I’m stupid Sphinx makes me look good! =============note Installation =============block .. note:: For things with **font like this** it means type it at the command line and hit enter. The Basics =========== 0. **git clone https://pydanny@github.com/pydanny/django-party-pack.git** 1. Make sure you have virtualenv installed.section 2. 3. change directory to the directory that contains this README.rst file. **virtualenv pollaxe** and then **source pollaxe/bin/activate**headers 4. **pip install -r requirements.txt** 5. **mkdir pollaxe/coverage** Building the sphinx docs ========================= 1. change directory to docs 2. **make html** Running django-coverage ======================== 1. python manage.py test http://readthedocs.org/docs/django-party-pack/en/latest/_sources/install.txt
  49. Daniel Greenfeld @pydanny I’m stupidhttp://readthedocs.org/docs/django-party-pack
  50. Daniel Greenfeld @pydanny I’m stupidSphinxmakes me lookgood! http://readthedocs.org/docs/django-party-pack
  51. Daniel Greenfeld @pydanny I’m stupid Sphinx makes me look good!http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
  52. Daniel Greenfeld @pydanny I’m stupid Sphinx makes me look good!http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
  53. Daniel Greenfeld @pydanny I’m stupid Sphinx makes me look good! ======================== Reference for Polls App ======================== The polls app is a copy of the Django tutorial with some mild PEP-8 cleanup. ``polls.models`` ================= .. automodule:: polls.models :members: ``polls.views`` ================= .. automodule:: polls.views :members: ``polls.tests`` ================= .. automodule:: polls.tests.test_models :members: :undoc-members: .. automodule:: polls.tests.test_views :members: :undoc-members:http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
  54. Daniel Greenfeld @pydanny I’m stupid Sphinx makes me look good! ======================== page Reference for Polls App ========================header The polls app is a copy of the Django tutorial with some mild PEP-8 cleanup. ``polls.models`` ================= .. automodule:: polls.models :members: ``polls.views`` ================= .. automodule:: polls.views :members: ``polls.tests`` ================= .. automodule:: polls.tests.test_models :members: :undoc-members: .. automodule:: polls.tests.test_views :members: :undoc-members: http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
  55. Daniel Greenfeld @pydanny I’m stupid Sphinx makes me look good! ======================== page Reference for Polls App ========================header The polls app is a copy of the Django tutorial with some mild PEP-8 cleanup. ``polls.models`` =================auto- .. automodule:: polls.models :members:model ``polls.views`` ================= .. automodule:: polls.views :members: ``polls.tests`` ================= .. automodule:: polls.tests.test_models :members: :undoc-members: .. automodule:: polls.tests.test_views :members: :undoc-members: http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
  56. Daniel Greenfeld @pydanny I’m stupid Sphinx makes me look good! ======================== page Reference for Polls App ========================header The polls app is a copy of the Django tutorial with some mild PEP-8 cleanup. ``polls.models`` =================auto- .. automodule:: polls.models :members:model ``polls.views`` ================= .. automodule:: polls.views :members: auto-model ``polls.tests`` ================= for undocumented .. automodule:: polls.tests.test_models :members: items :undoc-members: .. automodule:: polls.tests.test_views :members: :undoc-members: http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
  57. Daniel Greenfeld @pydanny I’m stupid Sphinx makes me look good!http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
  58. Daniel Greenfeld @pydanny I’m stupid Sphinx makes me look good!http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
  59. Daniel Greenfeld @pydanny Sphinx walk-throughhttp://audreyr.posterous.com/how-to-create-sphinx-docs-the-python-github-r or http://bit.ly/audreyr-sphinx
  60. I’m lazy
  61. Daniel Greenfeld @pydannyI’m lazy
  62. Daniel Greenfeld @pydanny I’m lazy• Don’t wanna do anything twice
  63. Daniel Greenfeld @pydanny I’m lazy• Don’t wanna do anything twice• Don’t wanna debug code when I had it working before
  64. Daniel Greenfeld @pydanny I’m lazy• Don’t wanna do anything twice• Don’t wanna debug code when I had it working before• Don’t wanna upload zip files per document change
  65. Daniel Greenfeld @pydanny I’m lazyDon’t wanna do anything twice
  66. Daniel Greenfeld @pydanny I’m lazy Don’t wanna do anything twice• If I write the same code twice I stick it in a function
  67. Daniel Greenfeld @pydanny I’m lazy Don’t wanna do anything twice• If I write the same code twice I stick it in a function• Then I stick the function into a util module.
  68. Daniel Greenfeld @pydanny I’m lazy Don’t wanna do anything twice• If I write the same code twice I stick it in a function• Then I stick the function into a util module.• Then I put it on Github so I don’t lose it.
  69. Daniel Greenfeld @pydanny I’m lazy Don’t wanna do anything twice• If I write the same code twice I stick it in a function• Then I stick the function into a util module.• Then I put it on Github so I don’t lose it.• Isn’t this kinda the whole thing behind Open Source?
  70. Daniel Greenfeld @pydanny I’m LazyDon’t wanna debug code when I had it working before
  71. Daniel Greenfeld @pydanny I’m LazyDon’t wanna debug code when I had it working before • Manually testing code by watching it run is hard...
  72. Daniel Greenfeld @pydanny I’m LazyDon’t wanna debug code when I had it working before • Manually testing code by watching it run is hard... • ...and boring...
  73. Daniel Greenfeld @pydanny I’m LazyDon’t wanna debug code when I had it working before • Manually testing code by watching it run is hard... • ...and boring... • ...and hence is error prone.
  74. Daniel Greenfeld @pydanny I’m LazyDon’t wanna debug code when I had it working before • Manually testing code by watching it run is hard... • ...and boring... • ...and hence is error prone. • Meaning you have to do more work.
  75. Daniel Greenfeld @pydanny I’m LazyAre you testing enough?
  76. Daniel Greenfeld @pydanny I’m Lazy Are you testing enough? Stick even the ‘basicstuff’ in the docs!
  77. Daniel Greenfeld @pydanny I’m LazyAre you testing enough?
  78. Daniel Greenfeld @pydanny I’m Lazy Are you testing enough?Yeah, some of the configuration is off. Will be fixed soon.
  79. Daniel Greenfeld @pydanny Coverage Tricks• coverage.py is great• django-coverage runs coverage.py for Django• But you only want to test your own apps
  80. Daniel Greenfeldsettings.py @pydanny import os.path PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) PREREQ_APPS = (     django.contrib.auth,     django.contrib.contenttypes,     django.contrib.sessions,     django.contrib.sites,     django.contrib.messages,     django.contrib.admin, django-debug-toolbar’, ) PROJECT_APPS = (     polls, ) INSTALLED_APPS = PREREQ_APPS + PROJECT_APPS COVERAGE_MODULE_EXCLUDES = [     tests$, settings$, urls$, locale$,     migrations, fixtures, admin$, ] COVERAGE_MODULE_EXCLUDES += PREREQ_APPS COVERAGE_REPORT_HTML_OUTPUT_DIR = "coverage" HTML_OUTPUT_DIR = os.path.join(PROJECT_ROOT, "coverage") TEST_RUNNER = testrunner.OurCoverageRunner
  81. Daniel Greenfeldsettings.py @pydanny import os.path PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) Super PREREQ_APPS = (     django.contrib.auth, userful     django.contrib.contenttypes,     django.contrib.sessions,     django.contrib.sites,     django.contrib.messages,     django.contrib.admin, django-debug-toolbar’, ) PROJECT_APPS = (     polls, ) INSTALLED_APPS = PREREQ_APPS + PROJECT_APPS COVERAGE_MODULE_EXCLUDES = [     tests$, settings$, urls$, locale$,     migrations, fixtures, admin$, ] COVERAGE_MODULE_EXCLUDES += PREREQ_APPS COVERAGE_REPORT_HTML_OUTPUT_DIR = "coverage" HTML_OUTPUT_DIR = os.path.join(PROJECT_ROOT, "coverage") TEST_RUNNER = testrunner.OurCoverageRunner
  82. Daniel Greenfeldsettings.py @pydanny import os.path PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) Super PREREQ_APPS = (     django.contrib.auth, userful     django.contrib.contenttypes,     django.contrib.sessions,django or third-     django.contrib.sites,     django.contrib.messages, party-apps     django.contrib.admin, django-debug-toolbar’, ) PROJECT_APPS = (     polls, ) INSTALLED_APPS = PREREQ_APPS + PROJECT_APPS COVERAGE_MODULE_EXCLUDES = [     tests$, settings$, urls$, locale$,     migrations, fixtures, admin$, ] COVERAGE_MODULE_EXCLUDES += PREREQ_APPS COVERAGE_REPORT_HTML_OUTPUT_DIR = "coverage" HTML_OUTPUT_DIR = os.path.join(PROJECT_ROOT, "coverage") TEST_RUNNER = testrunner.OurCoverageRunner
  83. Daniel Greenfeldsettings.py @pydanny import os.path PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) Super PREREQ_APPS = (     django.contrib.auth, userful     django.contrib.contenttypes,     django.contrib.sessions,django or third-     django.contrib.sites,     django.contrib.messages, party-apps     django.contrib.admin, django-debug-toolbar’, ) PROJECT_APPS = (INSTALLED_APPS     polls, ) INSTALLED_APPS = PREREQ_APPS + PROJECT_APPS COVERAGE_MODULE_EXCLUDES = [     tests$, settings$, urls$, locale$,     migrations, fixtures, admin$, ] COVERAGE_MODULE_EXCLUDES += PREREQ_APPS COVERAGE_REPORT_HTML_OUTPUT_DIR = "coverage" HTML_OUTPUT_DIR = os.path.join(PROJECT_ROOT, "coverage") TEST_RUNNER = testrunner.OurCoverageRunner
  84. Daniel Greenfeldsettings.py @pydanny import os.path PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) Super PREREQ_APPS = (     django.contrib.auth, userful     django.contrib.contenttypes,     django.contrib.sessions,django or third-     django.contrib.sites,     django.contrib.messages, My custom party-apps     django.contrib.admin, apps django-debug-toolbar’, ) PROJECT_APPS = (INSTALLED_APPS     polls, ) INSTALLED_APPS = PREREQ_APPS + PROJECT_APPS COVERAGE_MODULE_EXCLUDES = [     tests$, settings$, urls$, locale$,     migrations, fixtures, admin$, ] COVERAGE_MODULE_EXCLUDES += PREREQ_APPS COVERAGE_REPORT_HTML_OUTPUT_DIR = "coverage" HTML_OUTPUT_DIR = os.path.join(PROJECT_ROOT, "coverage") TEST_RUNNER = testrunner.OurCoverageRunner
  85. Daniel Greenfeldsettings.py @pydanny import os.path PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) Super PREREQ_APPS = (     django.contrib.auth, userful     django.contrib.contenttypes,     django.contrib.sessions,django or third-     django.contrib.sites,     django.contrib.messages, My custom party-apps     django.contrib.admin, apps django-debug-toolbar’, ) PROJECT_APPS = (INSTALLED_APPS     polls, ) INSTALLED_APPS = PREREQ_APPS + PROJECT_APPSexclude this stuff COVERAGE_MODULE_EXCLUDES = [     tests$, settings$, urls$, locale$,     migrations, fixtures, admin$, ] COVERAGE_MODULE_EXCLUDES += PREREQ_APPS COVERAGE_REPORT_HTML_OUTPUT_DIR = "coverage" HTML_OUTPUT_DIR = os.path.join(PROJECT_ROOT, "coverage") TEST_RUNNER = testrunner.OurCoverageRunner
  86. Daniel Greenfeldsettings.py @pydanny import os.path PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) Super PREREQ_APPS = (     django.contrib.auth, userful     django.contrib.contenttypes,     django.contrib.sessions,django or third-     django.contrib.sites,     django.contrib.messages, My custom party-apps     django.contrib.admin, apps django-debug-toolbar’, ) PROJECT_APPS = (INSTALLED_APPS     polls, ) INSTALLED_APPS = PREREQ_APPS + PROJECT_APPSexclude this stuff COVERAGE_MODULE_EXCLUDES = [     tests$, settings$, urls$, locale$,     migrations, fixtures, admin$, ] Output results COVERAGE_MODULE_EXCLUDES += PREREQ_APPS here COVERAGE_REPORT_HTML_OUTPUT_DIR = "coverage" HTML_OUTPUT_DIR = os.path.join(PROJECT_ROOT, "coverage") TEST_RUNNER = testrunner.OurCoverageRunner
  87. Daniel Greenfeldsettings.py @pydanny import os.path PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) Super PREREQ_APPS = (     django.contrib.auth, userful     django.contrib.contenttypes,     django.contrib.sessions,django or third-     django.contrib.sites,     django.contrib.messages, My custom party-apps     django.contrib.admin, apps django-debug-toolbar’, ) PROJECT_APPS = (INSTALLED_APPS     polls, ) INSTALLED_APPS = PREREQ_APPS + PROJECT_APPSexclude this stuff COVERAGE_MODULE_EXCLUDES = [     tests$, settings$, urls$, locale$,     migrations, fixtures, admin$, ] Output results See next page! COVERAGE_MODULE_EXCLUDES += PREREQ_APPS here COVERAGE_REPORT_HTML_OUTPUT_DIR = "coverage" HTML_OUTPUT_DIR = os.path.join(PROJECT_ROOT, "coverage") TEST_RUNNER = testrunner.OurCoverageRunner
  88. testrunner.py Daniel Greenfeld @pydanny# Make our own testrunner that by default only tests our ownappsfrom django.conf import settingsfrom django.test.simple import DjangoTestSuiteRunnerfrom django_coverage.coverage_runner import CoverageRunnerclass OurTestRunner(DjangoTestSuiteRunner):    def build_suite(self, test_labels, *args, **kwargs):        return super(OurTestRunner,self).build_suite(test_labels or settings.PROJECT_APPS, *args, **kwargs)class OurCoverageRunner(OurTestRunner, CoverageRunner):    pass This only runs the tests on apps we want tested and skips the rest!
  89. Daniel Greenfeld @pydanny I’m LazyAre you testing enough?
  90. Daniel Greenfeld @pydanny I’m Lazy Are you testing enough?Yeah, some of the configuration is off. Will be fixed soon.
  91. Daniel Greenfeld @pydanny I’m LazyDon’t wanna upload zip files per document change
  92. Daniel Greenfeld @pydanny I’m LazyDon’t wanna upload zip files per document change READ
  93. Daniel Greenfeld @pydanny I’m LazyDon’t wanna upload zip files per document change READ THE
  94. Daniel Greenfeld @pydanny I’m LazyDon’t wanna upload zip files per document change READ THE DOCS
  95. Daniel Greenfeld @pydanny I’m LazyDon’t wanna upload zip files per document change READ THE DOCS .ORG
  96. Daniel Greenfeld @pydanny I’m LazyDon’t wanna upload zip files per document change READ THE DOCS .ORG http://readthedocs.org / http://rtfd.org
  97. Daniel Greenfeld @pydanny I’m stupid Can’t remember things• Documentation makes me look good• Docstrings are awesome• Learn you some Restructured Text• Write down even the slide bullets!• https://github.com/pydanny/pydanny-event-notes
  98. Daniel Greenfeld @pydanny I’m stupid Can’t remember things• Documentation makes me look good• Docstrings are awesome• Learn you some Restructured Text• Write down even the slide bullets!• https://github.com/pydanny/pydanny-event-notes• http://pydanny-event-notes.rtfd.org
  99. Daniel Greenfeld @pydannyImport your project I’m Lazy Host your docs on http://rtfd.org
  100. Daniel Greenfeld @pydanny I’m LazyHost your docs on http://rtfd.org
  101. Daniel Greenfeld @pydanny I’m LazyHost your docs on http://rtfd.org
  102. Daniel Greenfeld @pydanny I’m LazyHost your docs on http://rtfd.org
  103. Daniel Greenfeld @pydanny I’m LazyHost your docs on http://rtfd.org
  104. Daniel Greenfeld @pydanny I’m LazyHost your docs on http://rtfd.org Admin
  105. Daniel Greenfeld @pydanny I’m LazyHost your docs on http://rtfd.org Admin Service Hook
  106. Daniel Greenfeld @pydanny I’m LazyHost your docs on http://rtfd.org Admin Service Hook ReadTheDocs
  107. Daniel Greenfeld @pydanny I’m LazyHost your docs on http://rtfd.org Admin Service Hook ReadTheDocs Active
  108. Daniel Greenfeld @pydannyI’m Lazy django-party-pack-rtfd.org
  109. Daniel Greenfeld @pydannyI’m Lazy pydanny-event-notes.rtfd.org
  110. Daniel Greenfeld @pydannySphinx Trick! /django-party-pack /docs /conf.py Makes Sphinx play nicely with Django
  111. Don’t be smart and lazy
  112. Daniel Greenfeld @pydanny Django Worst PracticeMagical INSTALLED_APPS += [p for p in os.listdir(BASE) if os.path.isdirr(p)]settings MIDDLEWARE_CLASSES = [...] def callback(arg, dirname, fnames): code if middleware.py in fnames: m = %s.middleware % os.path.split(dirnaame)[-1] THIS MIDDLEWARE_CLASSES.append(m) urlpatterns = patterns(, ...) CODE ISMagical for app in settings.INSTALLED_APPS: if not app.startswith(django): BROKEN p = url(^%s/ % app, include(%s.urls) % app) urls urlpatterns += patterns(, p) code http://www.slideshare.net/jacobian/the-best-and-worst-of-django
  113. Daniel Greenfeld @pydanny Django Worst Practice ‘Magical configuration code’Magical INSTALLED_APPS += [p for p in os.listdir(BASE) if os.path.isdirr(p)]settings MIDDLEWARE_CLASSES = [...] def callback(arg, dirname, fnames): code if middleware.py in fnames: m = %s.middleware % os.path.split(dirnaame)[-1] THIS MIDDLEWARE_CLASSES.append(m) urlpatterns = patterns(, ...) CODE ISMagical for app in settings.INSTALLED_APPS: if not app.startswith(django): BROKEN p = url(^%s/ % app, include(%s.urls) % app) urls urlpatterns += patterns(, p) code http://www.slideshare.net/jacobian/the-best-and-worst-of-django
  114. Daniel Greenfeld @pydanny Django Worst Practice ‘Magical configuration code’Magical INSTALLED_APPS += [p for p in os.listdir(BASE) if os.path.isdirr(p)]settings MIDDLEWARE_CLASSES = [...] def callback(arg, dirname, fnames): code if middleware.py in fnames: m = %s.middleware % os.path.split(dirnaame)[-1] THIS MIDDLEWARE_CLASSES.append(m) urlpatterns = patterns(, ...) CODE ISMagical for app in settings.INSTALLED_APPS: if not app.startswith(django): BROKEN p = url(^%s/ % app, include(%s.urls) % app) urls urlpatterns += patterns(, p) code Ugh. http://www.slideshare.net/jacobian/the-best-and-worst-of-django
  115. Daniel Greenfeld @pydanny Fixed Django Practice urlpatterns = patterns("",PREREQ_APPS = [ # Django url(r"^$", homepage, name="home"), "django.contrib.admin", url(r"^accounts/", include("accounts.urls")), "django.contrib.auth", url(r"^admin/", include(admin.site.urls)), "django.contrib.contenttypes", url(r"^about/", include("about.urls")), "django.contrib.sessions", url(r"^profiles/", include("profiles.urls")), "django.contrib.sites", url(r"^notices/", include("notification.urls")), "django.contrib.messages", ... "django.contrib.humanize", MIDDLEWARE_CLASSES = [ ) "django.contrib.flatpages", "django.middleware.common.CommonMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", # external "django.middleware.csrf.CsrfViewMiddleware", "notification", # must be first "django.contrib.auth.middleware.AuthenticationMiddleware", "staticfiles", "reversion.middleware.RevisionMiddleware", "uni_form", "django.contrib.messages.middleware.MessageMiddleware", ... ... ] ]Explicit is better This isn’t that much typing, is it? then Implicit
  116. Daniel Greenfeld @pydanny Fixed Django Practice urlpatterns = patterns("",PREREQ_APPS = [ # Django url(r"^$", homepage, name="home"), "django.contrib.admin", url(r"^accounts/", include("accounts.urls")), "django.contrib.auth", url(r"^admin/", include(admin.site.urls)), "django.contrib.contenttypes", url(r"^about/", include("about.urls")), "django.contrib.sessions", url(r"^profiles/", include("profiles.urls")), "django.contrib.sites", url(r"^notices/", include("notification.urls")), "django.contrib.messages", ... "django.contrib.humanize", MIDDLEWARE_CLASSES = [ ) "django.contrib.flatpages", "django.middleware.common.CommonMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", # external "django.middleware.csrf.CsrfViewMiddleware", "notification", # must be first "django.contrib.auth.middleware.AuthenticationMiddleware", "staticfiles", "reversion.middleware.RevisionMiddleware", "uni_form", "django.contrib.messages.middleware.MessageMiddleware", ... ... ] ] Python’s design is predicated on the proposition that code is more often read than written. http://www.slideshare.net/jacobian/the-best-and-worst-of-django/44
  117. I’m stupid and lazy
  118. Daniel Greenfeld @pydannyTechnical Debthttp://bit.ly/technical-debt
  119. Daniel Greenfeld @pydanny Technical DebtPostponed Activities http://bit.ly/technical-debt
  120. Daniel Greenfeld @pydanny Technical DebtPostponed Activities • Documentation http://bit.ly/technical-debt
  121. Daniel Greenfeld @pydanny Technical DebtPostponed Activities • Documentation • unshared knowledge http://bit.ly/technical-debt
  122. Daniel Greenfeld @pydanny Technical DebtPostponed Activities • Documentation • unshared knowledge • Tests http://bit.ly/technical-debt
  123. Daniel Greenfeld @pydanny Technical DebtPostponed Activities • Documentation • unshared knowledge • Tests • attending to TODO statements http://bit.ly/technical-debt
  124. Daniel Greenfeld @pydanny Technical DebtPostponed Activities • Documentation • unshared knowledge • Tests • attending to TODO statements • Code too confusing to be modified easily http://bit.ly/technical-debt
  125. Advocacy
  126. Daniel Greenfeld @pydannyWhy?
  127. Daniel Greenfeld @pydanny More funcommunityhttp://www.flickr.com/photos/pydanny/5851931370/
  128. Daniel GreenfeldJane Developer @pydanny Advocacy
  129. Daniel Greenfeld Jane Developer @pydanny Advocacy• Now is the time
  130. Daniel Greenfeld Jane Developer @pydanny Advocacy• Now is the time• Empowerment through Education
  131. Daniel Greenfeld Jane Developer @pydanny Advocacy• Now is the time• Empowerment through Education• Contribute to open source
  132. Daniel Greenfeld Jane Developer @pydanny Advocacy• Now is the time• Empowerment through Education• Contribute to open source• If you don’t step up then no one will
  133. Daniel Greenfeld Joe Developer @pydanny AdvocacyHow to get involved with PyLadies as a man
  134. Daniel Greenfeld Joe Developer @pydanny AdvocacyHow to get involved with PyLadies as a man • Give your own time
  135. Daniel Greenfeld Joe Developer @pydanny AdvocacyHow to get involved with PyLadies as a man • Give your own time • Honor your promised commitments
  136. Daniel Greenfeld Joe Developer @pydanny AdvocacyHow to get involved with PyLadies as a man • Give your own time • Honor your promised commitments • Give kudos to the men who bring ladies!
  137. Daniel Greenfeld Joe Developer @pydanny AdvocacyHow to get involved with PyLadies as a man • Give your own time • Honor your promised commitments • Give kudos to the men who bring ladies! • Step back: Don’t try to run things.
  138. Daniel GreenfeldAcme Corporation @pydanny Advocacy http://en.wikipedia.org/wiki/File:Acme_anvil.gif
  139. Daniel Greenfeld Acme Corporation @pydanny Advocacy How to get involved as a companyhttp://en.wikipedia.org/wiki/Acme_Corporation
  140. Daniel Greenfeld Acme Corporation @pydanny Advocacy How to get involved as a companyhttp://en.wikipedia.org/wiki/Acme_Corporation
  141. Daniel Greenfeld Acme Corporation @pydanny Advocacy How to get involved as a company • Sponsor because it’s the right thing to dohttp://en.wikipedia.org/wiki/Acme_Corporation
  142. Daniel Greenfeld Acme Corporation @pydanny Advocacy How to get involved as a company • Sponsor because it’s the right thing to do • Sponsor because you get a tax breakhttp://en.wikipedia.org/wiki/Acme_Corporation
  143. Daniel Greenfeld Acme Corporation @pydanny Advocacy How to get involved as a company • Sponsor because it’s the right thing to do • Sponsor because you get a tax break • Sponsor because good developers noticehttp://en.wikipedia.org/wiki/Acme_Corporation
  144. Daniel Greenfeld Acme Corporation @pydanny Advocacy How to get involved as a company • Sponsor because it’s the right thing to do • Sponsor because you get a tax break • Sponsor because good developers notice • Mozillahttp://en.wikipedia.org/wiki/Acme_Corporation
  145. Daniel Greenfeld Acme Corporation @pydanny Advocacy How to get involved as a company • Sponsor because it’s the right thing to do • Sponsor because you get a tax break • Sponsor because good developers notice • Mozilla • cars.comhttp://en.wikipedia.org/wiki/Acme_Corporation
  146. Daniel Greenfeld Joe/Jane Developer @pydanny Resources party-packhttps://github.com/pydanny/django-party-pack/ http://django-party-pack.rtfd.org/ http://bit.ly/audreyr-sphinx
  147. Questions?

×