Confessions of
Joe Developer
   Daniel Greenfeld
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 Roy

http://www.flickr.com/photos/pydanny/4442245488
Why am I talking?
I’m stupid and lazy
I’m stupid
Daniel Greenfeld
                   @pydanny




I’m stupid
Daniel Greenfeld
                                 @pydanny




            I’m stupid

• Can’t figure things out
Daniel Greenfeld
                                 @pydanny




           I’m stupid

• Can’t figure things out
• Can’t remember things
Daniel Greenfeld
                                                 @pydanny




            I’m stupid

• Can’t figure things out
• Can’t remember things
• Too stupid not to ask stupid questions
Daniel Greenfeld
                               @pydanny




   I’m stupid
Can’t figure things out
Daniel Greenfeld
                                                     @pydanny




             I’m stupid
        Can’t figure things out
• If I get stuck for more than 30 minutes...
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
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
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.
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.
Daniel Greenfeld
                               @pydanny




   I’m stupid
Can’t figure things out
Daniel Greenfeld
                                                                          @pydanny




                                                  I’m stupid
                                     Can’t figure things out

      “Smart” people way
# This sample gleefully taken from https://gist.github.com/973705

import urllib2

gh_url = 'https://api.github.com'
gh_user= 'user'
gh_pass = 'pass'

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'
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 from
import urllib2
                                                                    # https://gist.github.com/973705
gh_url = 'https://api.github.com'
gh_user= 'user'
gh_pass = 'pass'                                                    import requests
req = 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_code
opener = urllib2.build_opener(auth_manager)
                                                                    print r.headers['content-type']
urllib2.install_opener(opener)

handler = urllib2.urlopen(req)                                      # ------
                                                                    # 200
print handler.getcode()
print handler.headers.getheader('content-type')                     # 'application/json'
# ------
# 200
# 'application/json'
Daniel Greenfeld
                            @pydanny




I’m stupid
        ‘Smart way’
             aka
          hard way
Daniel Greenfeld
                                                                      @pydanny




                 I’m stupid
# This sample gleefully taken from
# https://gist.github.com/973705
                                          ‘Smart way’
import urllib2
                                               aka
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'
Daniel Greenfeld
                                                                                 @pydanny




                            I’m stupid
           # This sample gleefully taken from
           # https://gist.github.com/973705
                                                     ‘Smart way’
 What      import urllib2
                                                          aka
is 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'
Daniel Greenfeld
                                                                                 @pydanny




                            I’m stupid
           # This sample gleefully taken from
           # https://gist.github.com/973705
                                                     ‘Smart way’
 What      import urllib2
                                                          aka
is 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'
Daniel Greenfeld
                                                                                  @pydanny




                            I’m stupid
           # This sample gleefully taken from
           # https://gist.github.com/973705
                                                     ‘Smart way’
 What      import urllib2
                                                          aka
is 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'
Daniel Greenfeld
                                                                                  @pydanny




                            I’m stupid
           # This sample gleefully taken from
           # https://gist.github.com/973705
                                                     ‘Smart way’
 What      import urllib2
                                                          aka
is 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'
Daniel Greenfeld
                                     @pydanny




   I’m stupid            ‘Stupid way’
                              aka
Can’t figure things out
                           easy way
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/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'
Daniel Greenfeld
                                                            @pydanny




                I’m stupid                      ‘Stupid way’
                                                     aka
HTTP       Can’t figure things out
GET                                               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'
Daniel Greenfeld
                                                                @pydanny




                    I’m stupid                      ‘Stupid way’
                                                         aka
HTTP           Can’t figure things out
GET                                                   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_code
Password   print r.headers['content-type']

           # ------
           # 200
           # 'application/json'
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 from
import urllib2
                                                                    # https://gist.github.com/973705
gh_url = 'https://api.github.com'
gh_user= 'user'
gh_pass = 'pass'                                                    import requests
req = 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_code
opener = urllib2.build_opener(auth_manager)
                                                                    print r.headers['content-type']
urllib2.install_opener(opener)

handler = urllib2.urlopen(req)                                      # ------
                                                                    # 200
print handler.getcode()
print handler.headers.getheader('content-type')                     # 'application/json'
# ------
# 200
# 'application/json'
Daniel Greenfeld
                                           @pydanny




           I’m stupid
Too stupid not to ask stupid questions
Daniel Greenfeld
                                           @pydanny




             I’m stupid
Too stupid not to ask stupid questions




 • There are no stupid questions
Daniel Greenfeld
                                                   @pydanny




             I’m stupid
Too stupid not to ask stupid questions




 • There are no stupid questions
 • Don’t try and impress the people around
   you by not asking questions.
Daniel Greenfeld
                                              @pydanny




           I’m stupid
Too stupid not to ask stupid questions


         You are at DjangoCon.

       If you don’t ask the question,
       you are wasting opportunity.
Daniel Greenfeld
                                                     @pydanny




             I’m stupid
Too 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.
Daniel Greenfeld
                              @pydanny




   I’m stupid
Can’t remember things
Daniel Greenfeld
                                           @pydanny




          I’m stupid
      Can’t remember things


• Documentation makes me look good
Daniel Greenfeld
                                           @pydanny




          I’m stupid
      Can’t remember things


• Documentation makes me look good
• Docstrings are awesome
Daniel Greenfeld
                                           @pydanny




          I’m stupid
      Can’t remember things


• Documentation makes me look good
• Docstrings are awesome
• Learn you some Restructured Text
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!
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
Daniel Greenfeld



        Joe Developer
                                                     @pydanny




          Resources
      Where the code examples live!


https://github.com/pydanny/django-party-pack

      http://django-party-pack.rtfd.org/
Daniel Greenfeld
                                                      @pydanny




            I’m stupid




http://readthedocs.org/docs/django-party-pack
Daniel Greenfeld
                                                          @pydanny




                I’m stupid

Sphinx
makes
  me
 look
good!



    http://readthedocs.org/docs/django-party-pack
Daniel Greenfeld
                                                   @pydanny




   Docs/Sphinx Basics

• pip install sphinx
• make a docs directory
• sphinx-quickstart
• Follow instructions
• Starting over is just removing your docs
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 test




http://readthedocs.org/docs/django-party-pack/en/latest/_sources/install.txt
Daniel Greenfeld
                                                                                                         @pydanny




 page
header
                                 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
Daniel Greenfeld
                                                                                                         @pydanny




 page
header
                                 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
Daniel Greenfeld
                                                                                                          @pydanny




 page
header
                                  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
Daniel Greenfeld
                                                      @pydanny




            I’m stupid




http://readthedocs.org/docs/django-party-pack
Daniel Greenfeld
                                                          @pydanny




                I’m stupid

Sphinx
makes
  me
 look
good!



    http://readthedocs.org/docs/django-party-pack
Daniel Greenfeld
                                                                                     @pydanny




                    I’m stupid
     Sphinx makes me look good!




http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
Daniel Greenfeld
                                                                                     @pydanny




                    I’m stupid
      Sphinx makes me look good!




http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
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
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
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
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
Daniel Greenfeld
                                                                                     @pydanny




                    I’m stupid
     Sphinx makes me look good!




http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
Daniel Greenfeld
                                                                                     @pydanny




                    I’m stupid
      Sphinx makes me look good!




http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
Daniel Greenfeld
                                                                          @pydanny




         Sphinx walk-through

http://audreyr.posterous.com/how-to-create-sphinx-docs-the-python-github-r


                                   or

          http://bit.ly/audreyr-sphinx
I’m lazy
Daniel Greenfeld
                 @pydanny




I’m lazy
Daniel Greenfeld
                                        @pydanny




             I’m lazy

• Don’t wanna do anything twice
Daniel Greenfeld
                                               @pydanny




             I’m lazy

• Don’t wanna do anything twice
• Don’t wanna debug code when I had it
  working before
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
Daniel Greenfeld
                                      @pydanny




        I’m lazy
Don’t wanna do anything twice
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
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.
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.
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?
Daniel Greenfeld
                                                    @pydanny




                  I’m Lazy
Don’t wanna debug code when I had it working before
Daniel Greenfeld
                                                           @pydanny




                   I’m Lazy
Don’t wanna debug code when I had it working before

     • Manually testing code by watching it run is
        hard...
Daniel Greenfeld
                                                           @pydanny




                    I’m Lazy
Don’t wanna debug code when I had it working before

     • Manually testing code by watching it run is
        hard...
     • ...and boring...
Daniel Greenfeld
                                                           @pydanny




                   I’m Lazy
Don’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.
Daniel Greenfeld
                                                           @pydanny




                   I’m Lazy
Don’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.
Daniel Greenfeld
                                @pydanny




    I’m Lazy
Are you testing enough?
Daniel Greenfeld
                                                @pydanny




                    I’m Lazy
                Are you testing enough?




 Stick even
 the ‘basic
stuff’ in the
    docs!
Daniel Greenfeld
                                @pydanny




    I’m Lazy
Are you testing enough?
Daniel Greenfeld
                                                          @pydanny




                    I’m Lazy
               Are you testing enough?




Yeah, some of the configuration is off. Will be fixed soon.
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
Daniel Greenfeld



settings.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'

Confessions of Joe Developer

  • 1.
  • 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 Roy http://www.flickr.com/photos/pydanny/4442245488
  • 3.
    Why am Italking?
  • 4.
  • 6.
  • 7.
    Daniel Greenfeld @pydanny I’m stupid
  • 8.
    Daniel Greenfeld @pydanny I’m stupid • Can’t figure things out
  • 9.
    Daniel Greenfeld @pydanny I’m stupid • Can’t figure things out • Can’t remember things
  • 10.
    Daniel Greenfeld @pydanny I’m stupid • Can’t figure things out • Can’t remember things • Too stupid not to ask stupid questions
  • 11.
    Daniel Greenfeld @pydanny I’m stupid Can’t figure things out
  • 12.
    Daniel Greenfeld @pydanny I’m stupid Can’t figure things out • If I get stuck for more than 30 minutes...
  • 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
  • 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
  • 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.
  • 16.
    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.
  • 17.
    Daniel Greenfeld @pydanny I’m stupid Can’t figure things out
  • 18.
    Daniel Greenfeld @pydanny I’m stupid Can’t figure things out “Smart” people way # This sample gleefully taken from https://gist.github.com/973705 import urllib2 gh_url = 'https://api.github.com' gh_user= 'user' gh_pass = 'pass' 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'
  • 19.
    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 from import urllib2 # https://gist.github.com/973705 gh_url = 'https://api.github.com' gh_user= 'user' gh_pass = 'pass' import requests req = 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_code opener = urllib2.build_opener(auth_manager) print r.headers['content-type'] urllib2.install_opener(opener) handler = urllib2.urlopen(req) # ------ # 200 print handler.getcode() print handler.headers.getheader('content-type') # 'application/json' # ------ # 200 # 'application/json'
  • 20.
    Daniel Greenfeld @pydanny I’m stupid ‘Smart way’ aka hard way
  • 21.
    Daniel Greenfeld @pydanny I’m stupid # This sample gleefully taken from # https://gist.github.com/973705 ‘Smart way’ import urllib2 aka 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 aka is 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'
  • 23.
    Daniel Greenfeld @pydanny I’m stupid # This sample gleefully taken from # https://gist.github.com/973705 ‘Smart way’ What import urllib2 aka is 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'
  • 24.
    Daniel Greenfeld @pydanny I’m stupid # This sample gleefully taken from # https://gist.github.com/973705 ‘Smart way’ What import urllib2 aka is 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'
  • 25.
    Daniel Greenfeld @pydanny I’m stupid # This sample gleefully taken from # https://gist.github.com/973705 ‘Smart way’ What import urllib2 aka is 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'
  • 26.
    Daniel Greenfeld @pydanny I’m stupid ‘Stupid way’ aka Can’t figure things out easy way
  • 27.
    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/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’ aka HTTP Can’t figure things out GET 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'
  • 29.
    Daniel Greenfeld @pydanny I’m stupid ‘Stupid way’ aka HTTP Can’t figure things out GET 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_code Password print r.headers['content-type'] # ------ # 200 # 'application/json'
  • 30.
    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 from import urllib2 # https://gist.github.com/973705 gh_url = 'https://api.github.com' gh_user= 'user' gh_pass = 'pass' import requests req = 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_code opener = urllib2.build_opener(auth_manager) print r.headers['content-type'] urllib2.install_opener(opener) handler = urllib2.urlopen(req) # ------ # 200 print handler.getcode() print handler.headers.getheader('content-type') # 'application/json' # ------ # 200 # 'application/json'
  • 31.
    Daniel Greenfeld @pydanny I’m stupid Too stupid not to ask stupid questions
  • 32.
    Daniel Greenfeld @pydanny I’m stupid Too stupid not to ask stupid questions • There are no stupid questions
  • 33.
    Daniel Greenfeld @pydanny I’m stupid Too stupid not to ask stupid questions • There are no stupid questions • Don’t try and impress the people around you by not asking questions.
  • 34.
    Daniel Greenfeld @pydanny I’m stupid Too stupid not to ask stupid questions You are at DjangoCon. If you don’t ask the question, you are wasting opportunity.
  • 35.
    Daniel Greenfeld @pydanny I’m stupid Too 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.
  • 36.
    Daniel Greenfeld @pydanny I’m stupid Can’t remember things
  • 37.
    Daniel Greenfeld @pydanny I’m stupid Can’t remember things • Documentation makes me look good
  • 38.
    Daniel Greenfeld @pydanny I’m stupid Can’t remember things • Documentation makes me look good • Docstrings are awesome
  • 39.
    Daniel Greenfeld @pydanny I’m stupid Can’t remember things • Documentation makes me look good • Docstrings are awesome • Learn you some Restructured Text
  • 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!
  • 41.
    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
  • 42.
    Daniel Greenfeld Joe Developer @pydanny Resources Where the code examples live! https://github.com/pydanny/django-party-pack http://django-party-pack.rtfd.org/
  • 43.
    Daniel Greenfeld @pydanny I’m stupid http://readthedocs.org/docs/django-party-pack
  • 44.
    Daniel Greenfeld @pydanny I’m stupid Sphinx makes me look good! http://readthedocs.org/docs/django-party-pack
  • 45.
    Daniel Greenfeld @pydanny Docs/Sphinx Basics • pip install sphinx • make a docs directory • sphinx-quickstart • Follow instructions • Starting over is just removing your docs
  • 46.
    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 test http://readthedocs.org/docs/django-party-pack/en/latest/_sources/install.txt
  • 47.
    Daniel Greenfeld @pydanny page header 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
  • 48.
    Daniel Greenfeld @pydanny page header 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
  • 49.
    Daniel Greenfeld @pydanny page header 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
  • 50.
    Daniel Greenfeld @pydanny I’m stupid 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
  • 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! http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
  • 54.
    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
  • 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`` ================= .. 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
  • 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: ``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
  • 57.
    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
  • 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 I’m stupid Sphinx makes me look good! http://readthedocs.org/docs/django-party-pack/en/latest/reference_polls.html
  • 60.
    Daniel Greenfeld @pydanny Sphinx walk-through http://audreyr.posterous.com/how-to-create-sphinx-docs-the-python-github-r or http://bit.ly/audreyr-sphinx
  • 61.
  • 62.
    Daniel Greenfeld @pydanny I’m lazy
  • 63.
    Daniel Greenfeld @pydanny I’m lazy • Don’t wanna do anything twice
  • 64.
    Daniel Greenfeld @pydanny I’m lazy • Don’t wanna do anything twice • Don’t wanna debug code when I had it working before
  • 65.
    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
  • 66.
    Daniel Greenfeld @pydanny I’m lazy Don’t wanna do anything twice
  • 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
  • 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.
  • 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.
  • 70.
    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?
  • 71.
    Daniel Greenfeld @pydanny I’m Lazy Don’t wanna debug code when I had it working before
  • 72.
    Daniel Greenfeld @pydanny I’m Lazy Don’t wanna debug code when I had it working before • Manually testing code by watching it run is hard...
  • 73.
    Daniel Greenfeld @pydanny I’m Lazy Don’t wanna debug code when I had it working before • Manually testing code by watching it run is hard... • ...and boring...
  • 74.
    Daniel Greenfeld @pydanny I’m Lazy Don’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.
  • 75.
    Daniel Greenfeld @pydanny I’m Lazy Don’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.
  • 76.
    Daniel Greenfeld @pydanny I’m Lazy Are you testing enough?
  • 77.
    Daniel Greenfeld @pydanny I’m Lazy Are you testing enough? Stick even the ‘basic stuff’ in the docs!
  • 78.
    Daniel Greenfeld @pydanny I’m Lazy Are you testing enough?
  • 79.
    Daniel Greenfeld @pydanny I’m Lazy Are you testing enough? Yeah, some of the configuration is off. Will be fixed soon.
  • 80.
    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
  • 81.
    Daniel Greenfeld settings.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'
  • 82.
    Daniel Greenfeld settings.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'
  • 83.
    Daniel Greenfeld settings.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'
  • 84.
    Daniel Greenfeld settings.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'
  • 85.
    Daniel Greenfeld settings.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'
  • 86.
    Daniel Greenfeld settings.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 exclude 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'
  • 87.
    Daniel Greenfeld settings.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 exclude 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'
  • 88.
    Daniel Greenfeld settings.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 exclude 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'
  • 89.
    testrunner.py Daniel Greenfeld @pydanny # Make our own testrunner that by default only tests our own apps from django.conf import settings from django.test.simple import DjangoTestSuiteRunner from django_coverage.coverage_runner import CoverageRunner class 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!
  • 90.
    Daniel Greenfeld @pydanny I’m Lazy Are you testing enough?
  • 91.
    Daniel Greenfeld @pydanny I’m Lazy Are you testing enough? Yeah, some of the configuration is off. Will be fixed soon.
  • 92.
    Daniel Greenfeld @pydanny I’m Lazy Don’t wanna upload zip files per document change
  • 93.
    Daniel Greenfeld @pydanny I’m Lazy Don’t wanna upload zip files per document change READ
  • 94.
    Daniel Greenfeld @pydanny I’m Lazy Don’t wanna upload zip files per document change READ THE
  • 95.
    Daniel Greenfeld @pydanny I’m Lazy Don’t wanna upload zip files per document change READ THE DOCS
  • 96.
    Daniel Greenfeld @pydanny I’m Lazy Don’t wanna upload zip files per document change READ THE DOCS .ORG
  • 97.
    Daniel Greenfeld @pydanny I’m Lazy Don’t wanna upload zip files per document change READ THE DOCS .ORG http://readthedocs.org / http://rtfd.org
  • 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
  • 99.
    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
  • 100.
    Daniel Greenfeld @pydanny Import your project I’m Lazy Host your docs on http://rtfd.org
  • 101.
    Daniel Greenfeld @pydanny I’m Lazy Host your docs on http://rtfd.org
  • 102.
    Daniel Greenfeld @pydanny I’m Lazy Host your docs on http://rtfd.org
  • 103.
    Daniel Greenfeld @pydanny I’m Lazy Host your docs on http://rtfd.org
  • 104.
    Daniel Greenfeld @pydanny I’m Lazy Host your docs on http://rtfd.org
  • 105.
    Daniel Greenfeld @pydanny I’m Lazy Host your docs on http://rtfd.org Admin
  • 106.
    Daniel Greenfeld @pydanny I’m Lazy Host your docs on http://rtfd.org Admin Service Hook
  • 107.
    Daniel Greenfeld @pydanny I’m Lazy Host your docs on http://rtfd.org Admin Service Hook ReadTheDocs
  • 108.
    Daniel Greenfeld @pydanny I’m Lazy Host your docs on http://rtfd.org Admin Service Hook ReadTheDocs Active
  • 109.
    Daniel Greenfeld @pydanny I’m Lazy django-party-pack-rtfd.org
  • 110.
    Daniel Greenfeld @pydanny I’m Lazy pydanny-event-notes.rtfd.org
  • 111.
    Daniel Greenfeld @pydanny Sphinx Trick! /django-party-pack /docs /conf.py Makes Sphinx play nicely with Django
  • 112.
  • 113.
    Daniel Greenfeld @pydanny Django Worst Practice 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 IS Magical 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 IS Magical 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
  • 115.
    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 IS Magical 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
  • 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", ... ... ] ] Explicit is better This isn’t that much typing, is it? then Implicit
  • 117.
    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
  • 118.
  • 119.
    Daniel Greenfeld @pydanny Technical Debt http://bit.ly/technical-debt
  • 120.
    Daniel Greenfeld @pydanny Technical Debt Postponed Activities http://bit.ly/technical-debt
  • 121.
    Daniel Greenfeld @pydanny Technical Debt Postponed Activities • Documentation http://bit.ly/technical-debt
  • 122.
    Daniel Greenfeld @pydanny Technical Debt Postponed Activities • Documentation • unshared knowledge http://bit.ly/technical-debt
  • 123.
    Daniel Greenfeld @pydanny Technical Debt Postponed Activities • Documentation • unshared knowledge • Tests http://bit.ly/technical-debt
  • 124.
    Daniel Greenfeld @pydanny Technical Debt Postponed Activities • Documentation • unshared knowledge • Tests • attending to TODO statements http://bit.ly/technical-debt
  • 125.
    Daniel Greenfeld @pydanny Technical Debt Postponed Activities • Documentation • unshared knowledge • Tests • attending to TODO statements • Code too confusing to be modified easily http://bit.ly/technical-debt
  • 126.
  • 127.
    Daniel Greenfeld @pydanny Why?
  • 128.
    Daniel Greenfeld @pydanny More fun community http://www.flickr.com/photos/pydanny/5851931370/
  • 129.
  • 130.
    Daniel Greenfeld Jane Developer @pydanny Advocacy • Now is the time
  • 131.
    Daniel Greenfeld Jane Developer @pydanny Advocacy • Now is the time • Empowerment through Education
  • 132.
    Daniel Greenfeld Jane Developer @pydanny Advocacy • Now is the time • Empowerment through Education • Contribute to open source
  • 133.
    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
  • 134.
    Daniel Greenfeld Joe Developer @pydanny Advocacy How to get involved with PyLadies as a man
  • 135.
    Daniel Greenfeld Joe Developer @pydanny Advocacy How to get involved with PyLadies as a man • Give your own time
  • 136.
    Daniel Greenfeld Joe Developer @pydanny Advocacy How to get involved with PyLadies as a man • Give your own time • Honor your promised commitments
  • 137.
    Daniel Greenfeld Joe Developer @pydanny Advocacy How to get involved with PyLadies as a man • Give your own time • Honor your promised commitments • Give kudos to the men who bring ladies!
  • 138.
    Daniel Greenfeld Joe Developer @pydanny Advocacy How 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.
  • 139.
    Daniel Greenfeld Acme Corporation @pydanny Advocacy http://en.wikipedia.org/wiki/File:Acme_anvil.gif
  • 140.
    Daniel Greenfeld Acme Corporation @pydanny Advocacy How to get involved as a company http://en.wikipedia.org/wiki/Acme_Corporation
  • 141.
    Daniel Greenfeld Acme Corporation @pydanny Advocacy How to get involved as a company http://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 http://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 http://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 http://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 http://en.wikipedia.org/wiki/Acme_Corporation
  • 146.
    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.com http://en.wikipedia.org/wiki/Acme_Corporation
  • 147.
    Daniel Greenfeld Joe/Jane Developer @pydanny Resources party-pack https://github.com/pydanny/django-party-pack/ http://django-party-pack.rtfd.org/ http://bit.ly/audreyr-sphinx
  • 148.