SlideShare uma empresa Scribd logo
1 de 61
Baixar para ler offline
Python Worst Practices
       Daniel Greenfeld
Daniel Greenfeld
                                        @pydanny




I do cartwheels
        Daniel Greenfeld (@pydanny)
        Pythonista at Cartwheel
        Djangonaut at Revsys
        Co-lead of Django Packages &
           Open Comparison
        Learned Python at NASA
        Fiancé of Audrey Roy
Daniel Greenfeld
                                                     @pydanny




          Talk Format
 Each section will have three components:


• At least one ‘Python Worst Practice’ slide
• At least one ‘Fixed Python Practice’ slide
• A side-by-side comparison slide
        These slides are already online!
Daniel Greenfeld
                                              @pydanny




       Warning!

       Don’t use the
‘Python Worst Practices’
   examples in your code*

You may be hunted down and killed

       *Sometimes these are caught by
         various code checking tools
Daniel Greenfeld
                                   @pydanny




      Advice!

    Do consider using the
‘Fixed Python Practices’
    examples in your code


  You may get complimented
Fundamentals
Daniel Greenfeld
                                                      @pydanny




    Python Worst Practice
object = MyObject()
map = Map()
zip = 90213 # common US developer mistake
id = 34 # I still fight this one

I’m guilty

    • I still use ‘id’ when I shouldn’t
    • I admit I have a problem
    • That gives me license to pick on others
Daniel Greenfeld
                                                                @pydanny




      Fixed Python Practice
obj = MyObject() # necessary abbreviation
object_ = MyObject() # Underscore so we don't overwrite

map_obj = Map() # combine name w/necessary abbreviation
map_ = Map()

zip_code = 90213 # Explicit name with US focus
postal_code = 90213 # i18n explicit name
zip_ = 90213

pk = 34 # pk is often synonymous with id
id_ = 34
Daniel Greenfeld
                                                                                                      @pydanny




   Side-by-side comparison
 Worst Practice                               Fixed Practice
object = MyObject()                         obj = MyObject() # Use a necessary abbreviation
map = Map()                                 object_ = MyObject() # Use underscore so we don't overwrite
zip = 90213 # common US developer mistake
id = 34 # I still fight this one            map_obj = Map() # combine name with necessary abbreviation
                                            map_ = Map()

                                            zip_code = 90213 # Explicit name with US focus
                                            postal_code = 90213 # International explicit name
                                            zip_ = 90213

                                            pk = 34 # pk is often synonymous with id
                                            id_ = 34
Daniel Greenfeld
                                          @pydanny




Python Worst Practice
       Flipping the booleans

          true = 0
          false = 1
          True = False

   Usually done to support an API
Daniel Greenfeld
                                       @pydanny




   This sort of API
def crazy_posting_api(value):
    """ If a value is supplied
     successfully return ‘0’.
        Otherwise return ‘1’
    """
    if value:
        return 0
    return 1
Daniel Greenfeld
                                                              @pydanny




Fixed Python Practice
class CrazyApiConsumer(object):

    def __init__(self, value):
        self.value = value

    def post(self):
        # fix booleans in/around the return statement
        response = crazy_posting_api(self.value)
        return not bool(response)

cac1 = CrazyApiConsumer("hello")
print(cac1.post())
cac2 = CrazyApiConsumer("")
print(cac2.post())
Daniel Greenfeld
                                                                      @pydanny




Side-by-side comparison
Worst Practice   Fixed Practice
true = 0         class CrazyApiConsumer(object):
false = 1
True = False         def __init__(self, value):
                         self.value = value

                     def post(self):
                         # fix booleans in/around the return statement
                         response = crazy_posting_api(self.value)
                         return not bool(response)

                 cac1 = CrazyApiConsumer("hello")
                 print(cac1.post())
                 cac2 = CrazyApiConsumer("")
                 print(cac2.post())
Daniel Greenfeld
                                                  @pydanny




Python Worst Practice
  Identifying variable types with prefixes


 strColor = "green"
 boolActive = False
 intPythonYears = 20
 dtPythonFirstUsed = "04/20/2011"


   Mixing case doesn’t help either
Daniel Greenfeld
                                                 @pydanny




Python Worst Practice
Conserving pixels by removing the vowels


clr = "green"
ctv = False
pythnYrs = 20
pthnFrstSd = "04/20/2011"
Daniel Greenfeld
                                 @pydanny




Python Worst Practice

    c   =   "green"
    a   =   False
    p   =   20
    t   =   "04/20/2011"
Daniel Greenfeld
                                                    @pydanny




Fixed Python Practice
 color = "green"
 active = False
 python_years = 20
 python_first_used = "04/20/2011"

Python assumes we are all consenting adults

 • Infer from naming schemes the type/purpose
 • Don’t be constrained by type
Daniel Greenfeld
                                             @pydanny




Fixed Python Practice
color = "green"
active = False
python_years = 20
python_first_used = "04/20/2011"


     The pixel shortage is over.
 Use reasonably long variable names.
Daniel Greenfeld
                                                                     @pydanny




     Side-by-side comparison
 Worst Practice                    Fixed Practice
 c   =   "green"
 a   =   False                     color = "green"
 p   =   20
 t   =   "04/20/2011"
                                   active = False
                                   python_years = 20
                                   python_first_used = "04/20/2011"
 clr = "green"
 ctv = False
 pythnYrs = 20
 pthnFrstSd = "04/20/2011"




strColor = "green"
boolActive = False
intPythonYears = 20
dtPythonFirstUsed = "04/20/2011"
Daniel Greenfeld
                                             @pydanny




   Python Worst Practice
           Don’t use enumerate


foo = [1, 2, 3]

for i, item in zip(range(len(foo)), foo):
    print i, item
Daniel Greenfeld
                                            @pydanny




Fixed Python Practice
         Use enumerate

foo = [1, 2, 3]

for i, item in enumerate(foo):
    print i, item

   • Memorize the Python built-ins
   • Makes your code easier to read
   • Proven code
Daniel Greenfeld
                                                                    @pydanny




Side-by-side comparison
Worst Practice               Fixed Practice
foo = [1, 2, 3]              foo = [1, 2, 3]

zip(range(len(foo)), foo):   for i, item in enumerate(foo):
    print i, item                print i, item
Python Worst Practice
       Present using


      Different Fonts


        Dark Text


     Dire Backgr#nds
Daniel Greenfeld
                                @pydanny




Python Worst Practice

       Present using

       High Contrast
     Easy-to-read fonts
       All devices off
      All programs off
Daniel Greenfeld
                                              @pydanny




Side-by-side comparison
Worst Practice     Fixed Practice

   Present using
                     Present using
  Different Fonts

                     High Contrast
    Dark Text
                   Easy-to-read fonts
 Dire Backgr#nds     All devices off
                    All programs off
Classes
Daniel Greenfeld
                                                               @pydanny




Python Worst Practice
Implementing Java-style getters and setters
    import logging
    log = logging.getLogger()

    class JavaStyle:
        """ Quiz: what else am I doing wrong here? """

        def __init__(self):
            self.name = ""

        def get_name(self):
            return self.name

        def set_name(self, name):
            log.debug("Setting the name to %s" % name)
            if isinstance(name, str):
                self.name = name
            else:
                raise TypeError()

    if __name__ == "__main__":
        j = JavaStyle()
        j.set_name("pydanny did this back in 2006!")
        print(j.get_name())
Daniel Greenfeld
                                                                                @pydanny




Fixed Python Practice
                Python properties!
 import logging
 log = logging.getLogger()

 class PythonStyle(object):

     def __init__(self):
         self._name = ""                 Accessor
     @property
     def name(self):
         return self._name
                                                 Mutator
     @name.setter
     def name(self, value):
         """ Because name is probably a string we'll assume that we can
                  infer the type from the variable name"""
         log.debug("Setting the name to %s" % value)
         self._name = value

 if __name__ == "__main__":
     p = PythonStyle()
     p.name = "pydanny doing it the right way"
     print(p.name)
Daniel Greenfeld
                                                                                                 @pydanny




      Side-by-side comparison
    Worst Practice                               Fixed Practice
import logging              import logging
log = logging.getLogger()   log = logging.getLogger()

class JavaStyle:            class PythonStyle(object):
    """ Quiz: what else am I doing wrong here? """
                                def __init__(self):
    def __init__(self):             self._name = ""
        self.name = ""
                                @property
    def get_name(self):         def name(self):
        return self.name            return self._name

    def set_name(self, name):   @name.setter
        log.debug("Setting the name to %s" % name)
                                def name(self, value):
        if isinstance(name, str):   """ Because name is probably a string we'll assume that we can
            self.name = name                 infer the type from the variable name"""
        else:                       log.debug("Setting the name to %s" % value)
            raise TypeError()       self._name = value

if __name__ == "__main__": if __name__ == "__main__":
    j = JavaStyle()             p = PythonStyle()
    j.set_name("pydanny did thisp.namein 2006!") doing it the right way"
                                 back = "pydanny
    print(j.get_name())         print(p.name)
Daniel Greenfeld
                                                                         @pydanny




  Python Worst Practice
    Using property setters as action methods!
class WebService(object):

    @property
    def connect(self):
        self.proxy = xmlrpc.Server("http://service.xml")

if __name__ == '__main__':

    ws = WebService()
    ws.connect


            A.K.A.Trying to make your Python code look like Ruby
Daniel Greenfeld
                                                                 @pydanny




  Fixed Python Practice
                  Methods please!
class WebService(object):

    def connect(self):
        self.proxy = xmlrpc.Server("http://service.xml")

if __name__ == '__main__':

    ws = WebService()
    ws.connect()
Daniel Greenfeld
                                                                                               @pydanny




    Side-by-side comparison
  Worst Practice                               Fixed Practice

class WebService(object):         class WebService(object):
    @property
    def connect(self):                      def connect(self):
        self.proxy = xmlrpc.Server("http://service.xml")
                                                  self.proxy = xmlrpc.Server("http://service.xml")
if __name__ == '__main__':
                                  if __name__ == '__main__':
    ws = WebService()
    ws.connect
                                       ws = WebService()
                                       ws.connect()
Exceptions
Daniel Greenfeld
                                                   @pydanny




Python Worst Practice
    Passing Generic Exceptions silently
         try:
             do_akshun(value)
         except:
             pass

• Ignorance is not bliss
• You have no idea what your system is doing
• Arguably better to not have this in your code
Daniel Greenfeld
                                                                  @pydanny




   Fixed Python Practice
       Use specific exceptions and/or logging

class AkshunDoesNotDo(Exception):
    """ Custom exceptions makes for maintainable code """
    pass

try:
    do_akshun(value)
except AttributeError as e:
    log.info("Can I get attribution for these slides?")
    do_bakup_akshun(vlue)
except Exception as e:
    log.debug(str(e))
    raise AkshunDoesNotDo(e)
Daniel Greenfeld
                                                                            @pydanny




Side-by-side comparison
Worst Practice                   Fixed Practice

try:                   class AkshunDoesNotDo(Exception):
    do_akshun(value)       """ Custom exceptions makes for maintainable code """
except:                    pass
    pass
                       try:
                           do_akshun(value)
                       except AttributeError as e:
                           log.info("Can I get attribution for these slides?")
                           do_bakup_akshun(vlue)
                       except Exception as e:
                           log.debug(str(e))
                           raise AkshunDoesNotDo(e)
Getting controversial
Daniel Greenfeld
                                                                @pydanny




    Python Worst Practice
           Using exec for dynamic imports

imports = "from {0} import {1}".format("random", "randrange")
exec(imports)
print(randrange(10))



    • Hard to debug
    • Security risk
    • Sets bad precedents
Daniel Greenfeld
                                                        @pydanny




Fixed Python Practice
    Using importlib for dynamic imports

   import importlib
   funstuff = importlib.import_module('random')
   print(funstuff.randrange(10))



• importlib is in the standard library
• Really explicit
• Direct tie into the Python machinery
Daniel Greenfeld
                                                                                                              @pydanny




       Side-by-side comparison
     Worst Practice                                     Fixed Practice
imports = "from {0} import {1}".format("random", "randrange")
                                                         import importlib
exec(imports)                                            funstuff = importlib.import_module('random')
print(randrange(10))                                     print(funstuff.randrange(10))
Daniel Greenfeld
                                                                                                           @pydanny




       Python Worst Practice
                            Generally using lambdas
swap = lambda a, x, y: lambda f = a.__setitem__: (f(x, (a[x], a[y])), f(y, a[x][0]),   f(x, a[x][1]))()




    • Too many characters on one line
    • Lambdas by design does not have docstrings
    • Does not necessarily mean less characters
    • I can’t get this sample to work!
Daniel Greenfeld
                                                             @pydanny




    Fixed Python Practice
      def swap(a, x, y):
          """ Swap two position values in a list """
          a[x],a[y] = a[y],a[x]



• Doc strings that show up nicely in help/Sphinx
• Easier to read
• In Python, functions are first class objects
• Whenever possible avoid using lambdas
Daniel Greenfeld
                                                                                                @pydanny




 Side-by-side comparison
Worst Practice                           Fixed Practice
swap = lambda a, x, y:                   def swap(a, x, y):
       lambda f = a.__setitem__:             """ Swap two position values in a list """
       (f(x, (a[x], a[y])),                  a[x],a[y] = a[y],a[x]
       f(y, a[x][0]), f(x, a[x][1]))()
Daniel Greenfeld
                                                              @pydanny




Python Worst Practice
      Configuring your project with XML

<pydanny-ml>
    <do action="call_view">com.pydanny.nextSlide</do>
    <global name="spam" value="eggs" />
</pydanny-ml>




•   You can’t convince me that XML is the better way

•   You are forcing me to learn a new language
Daniel Greenfeld
                                                    @pydanny




Fixed Python Practice ?
     Use Python for configuration!
 spam = "eggs"
 actions = [
     ('call_view', 'com.pydanny.nextSlide')
 ]


  • Is this the right way?
   • This allows conditional logic
   • Iterators
   • i.e. “Magic Configuration”
Daniel Greenfeld
                                                                             @pydanny




Python Worst Practice
         ‘Magical configuration code’
 INSTALLED_APPS += [p for p in os.listdir(BASE) if os.path.isdir(p)]
 MIDDLEWARE_CLASSES = [...]
 def callback(arg, dirname, fnames):
     if 'middleware.py' in fnames:
         m = '%s.middleware' % os.path.split(dirname)[-1]
         MIDDLEWARE_CLASSES.append(m)

 urlpatterns = patterns('', ...)
 for app in settings.INSTALLED_APPS:
     if not app.startswith('django'):
         p = url('^%s/' % app, include('%s.urls') % app)
         urlpatterns += patterns('', p)




                              Ugh.
  http://www.slideshare.net/jacobian/the-best-and-worst-of-django
Daniel Greenfeld
                                                                                                @pydanny




          Fixed Python 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
Daniel Greenfeld
                                                                                                @pydanny




          Fixed Python 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
Daniel Greenfeld
                                                        @pydanny




 Fixed Python Practice
               Use a config file

spam = "eggs"

[actions]
call_view = com.pydanny.nextSlide



           Read up on config parser
http://docs.python.org/library/configparser.html
Daniel Greenfeld
                                                @pydanny




Side-by-side comparison
Worst Practice       Fixed Practice

XML                  simple python files
logic heavy python   config (.cfg) files
Documentation
Daniel Greenfeld
                                                              @pydanny




 Python Worst Practice
                   Bad docstrings
class Pythonista(): # Old style class!
    """ This class represents a Python programmer """

     def code(self):
         """Write some code """
         code, inspiration = Code(), Inspiration()
         for hour in Effort():
             try:
                  code += hour + inspiraion
             except CurseWorthyBug:
                  ...


 •   Do really obvious objects require doc strings?

 •   Complex methods require more than docstrings!
Daniel Greenfeld
                                                              @pydanny




      Fixed Python Practice
        class Pythonista(object):

            def code(self):
                """ Writes code following these steps
                1. Create a space for coding
                2. Get some inspiration
                3. Loop through some hours of effort
   Spend a      4. Write some code
few minutes     5. Pull out hair cause of bugs
                """
documenting     code = Code()
 the critical   inspiration = Inspiration()
                for hour in Effort():
 stuff, okay?       try:
                         code += hour + inspiraion
                    except CurseWorthyBug:
                         ...
Daniel Greenfeld
                                                                                        @pydanny




      Side-by-side comparison
     Worst Practice                         Fixed Practice
class Pythonista(): # Old style class!       class Pythonista(object):
    """ This class represents a Python programmer """
                                                 def code(self):
    def code(self):                                  """ Writes code following these steps
        """Write some code """                       1. Create a space for coding
        code, inspiration = Code(), Inspiration()    2. Get some inspiration
        for hour in Effort():                        3. Loop through some hours of effort
            try:                                     4. Write some code
                 code += hour + inspiraion           5. Pull out hair cause of bugs
            except CurseWorthyBug:                   """
              ...                                    code = Code()
                                                     inspiration = Inspiration()
                                                     for hour in Effort():
                                                         try:
                                                              code += hour + inspiraion
                                                         except CurseWorthyBug:
                                                              ...
Daniel Greenfeld
                                                              @pydanny




   Python Worst Practice
      Using a wiki for project documentation

 “Wikis are where project documentation goes to die”
                                         Jacob Kaplan-Moss



• Generally not version controlled
• Backups? Mirrors?
• Editing via the web? Ugh.
• No pull requests - smaller group of contributors
Daniel Greenfeld
                                         @pydanny




Fixed Python Practice

• Use Restructured Text
• Use Sphinx
• Host on http://readthedocs.org
Daniel Greenfeld
                                        @pydanny




Side-by-side comparison
Worst Practice   Fixed Practice
Daniel Greenfeld
                                                                                      @pydanny




Python Worst Practice
   >>> import that
   The Anti-Zen of Python, by Daniel Greenfeld

   Ugly is better than beautiful.
   Implicit is better than explicit.
   Complicated is better than complex.
   Complex is better than simple.
   Nested is better than flat.
   Dense is better than sparse.
   Line code counts.
   Special cases are special enough to break the rules.
   Although purity beats practicality.
   Errors should always pass silently.
   Spelchek iz fur loosers.
   In the face of explicity, succumb to the temptation to guess.
   There should be many ways to do it.
   Because only a tiny minority of us are Dutch.
   Later is the best time to fix something.
   If the implementation is hard to explain, it's a good sell.
   If the implementation is easy to explain, it won't take enough time to do.
   Namespaces are too hard, just use import *!


  http://pypi.python.org/pypi/that
Daniel Greenfeld
                                                                                 @pydanny




Fixed Python Practice
   >>> import this
   The Zen of Python, by Tim Peters

   Beautiful is better than ugly.
   Explicit is better than implicit.
   Simple is better than complex.
   Complex is better than complicated.
   Flat is better than nested.
   Sparse is better than dense.
   Readability counts.
   Special cases aren't special enough to break the rules.
   Although practicality beats purity.
   Errors should never pass silently.
   Unless explicitly silenced.
   In the face of ambiguity, refuse the temptation to guess.
   There should be one-- and preferably only one --obvious way to do it.
   Although that way may not be obvious at first unless you're Dutch.
   Now is better than never.
   Although never is often better than *right* now.
   If the implementation is hard to explain, it's a bad idea.
   If the implementation is easy to explain, it may be a good idea.
   Namespaces are one honking great idea -- let's do more of those!

                Core Python
Daniel Greenfeld
                                                                                                                                  @pydanny




          Side-by-side comparison
        Worst Practice                                             Fixed Practice
                                                         >>> import this
>>> import that
                                                         The Zen of Python, by Tim Peters
The Anti-Zen of Python, by Daniel Greenfeld
                                                            Beautiful is better than ugly.
Ugly is better than beautiful.
                                                            Explicit is better than implicit.
Implicit is better than explicit.
                                                            Simple is better than complex.
Complicated is better than complex.
                                                            Complex is better than complicated.
Complex is better than simple.
                                                            Flat is better than nested.
Nested is better than flat.
                                                            Sparse is better than dense.
Dense is better than sparse.
                                                            Readability counts.
Line code counts.
                                                            Special cases aren't special enough to break the rules.
Special cases are special enough to break the rules.
                                                            Although practicality beats purity.
Although purity beats practicality.
                                                            Errors should never pass silently.
Errors should always pass silently.
                                                            Unless explicitly silenced.
Spelchek iz fur loosers.
                                                            In the face of ambiguity, refuse the temptation to guess.
In the face of explicity, succumb to the temptation to guess.
                                                            There should be one-- and preferably only one --obvious way to do it.
There should be many ways to do it.
                                                            Although that way may not be obvious at first unless you're Dutch.
Because only a tiny minority of us are Dutch.
                                                            Now is better than never.
Later is the best time to fix something.
                                                            Although never is often better than *right* now.
If the implementation is hard to explain, it's a good sell.
                                                            If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it won't take enough time to do.
                                                            If the implementation is easy to explain, it may be a good idea.
Namespaces are too hard, just use import *!
                                                            Namespaces are one honking great idea -- let's do more of those!
Questions?

Mais conteúdo relacionado

Mais procurados

VAPT PRESENTATION full.pptx
VAPT PRESENTATION full.pptxVAPT PRESENTATION full.pptx
VAPT PRESENTATION full.pptxDARSHANBHAVSAR14
 
Secure Coding principles by example: Build Security In from the start - Carlo...
Secure Coding principles by example: Build Security In from the start - Carlo...Secure Coding principles by example: Build Security In from the start - Carlo...
Secure Coding principles by example: Build Security In from the start - Carlo...Codemotion
 
Splunk Enterpise for Information Security Hands-On
Splunk Enterpise for Information Security Hands-OnSplunk Enterpise for Information Security Hands-On
Splunk Enterpise for Information Security Hands-OnSplunk
 
OWASP Top 10 2021 What's New
OWASP Top 10 2021 What's NewOWASP Top 10 2021 What's New
OWASP Top 10 2021 What's NewMichael Furman
 
DASK and Apache Spark
DASK and Apache SparkDASK and Apache Spark
DASK and Apache SparkDatabricks
 
Desenvolvimento Seguro de Software - 10o Workshop SegInfo - Apresentação
Desenvolvimento Seguro de Software - 10o Workshop SegInfo - ApresentaçãoDesenvolvimento Seguro de Software - 10o Workshop SegInfo - Apresentação
Desenvolvimento Seguro de Software - 10o Workshop SegInfo - ApresentaçãoClavis Segurança da Informação
 
Talks@Coursera - A/B Testing @ Internet Scale
Talks@Coursera - A/B Testing @ Internet ScaleTalks@Coursera - A/B Testing @ Internet Scale
Talks@Coursera - A/B Testing @ Internet Scalecourseratalks
 
Approximate nearest neighbor methods and vector models – NYC ML meetup
Approximate nearest neighbor methods and vector models – NYC ML meetupApproximate nearest neighbor methods and vector models – NYC ML meetup
Approximate nearest neighbor methods and vector models – NYC ML meetupErik Bernhardsson
 
Writing clean and maintainable code
Writing clean and maintainable codeWriting clean and maintainable code
Writing clean and maintainable codeMarko Heijnen
 
Top 10 Web Security Vulnerabilities (OWASP Top 10)
Top 10 Web Security Vulnerabilities (OWASP Top 10)Top 10 Web Security Vulnerabilities (OWASP Top 10)
Top 10 Web Security Vulnerabilities (OWASP Top 10)Brian Huff
 
Brute force attack
Brute force attackBrute force attack
Brute force attackjoycruiser
 
ProdSec: A Technical Approach
ProdSec: A Technical ApproachProdSec: A Technical Approach
ProdSec: A Technical ApproachJeremy Brown
 
Bug Bounty - Hackers Job
Bug Bounty - Hackers JobBug Bounty - Hackers Job
Bug Bounty - Hackers JobArbin Godar
 
10X SOC - SANS Blue Summit Keynote 2021 - Anton Chuvakin
10X SOC - SANS Blue Summit Keynote 2021 - Anton Chuvakin10X SOC - SANS Blue Summit Keynote 2021 - Anton Chuvakin
10X SOC - SANS Blue Summit Keynote 2021 - Anton ChuvakinAnton Chuvakin
 
It all starts with the ' (SQL injection from attacker's point of view)
It all starts with the ' (SQL injection from attacker's point of view)It all starts with the ' (SQL injection from attacker's point of view)
It all starts with the ' (SQL injection from attacker's point of view)Miroslav Stampar
 
sqlmap - security development in Python
sqlmap - security development in Pythonsqlmap - security development in Python
sqlmap - security development in PythonMiroslav Stampar
 

Mais procurados (20)

VAPT PRESENTATION full.pptx
VAPT PRESENTATION full.pptxVAPT PRESENTATION full.pptx
VAPT PRESENTATION full.pptx
 
OWASP Risk Rating Methodology.pptx
OWASP Risk Rating Methodology.pptxOWASP Risk Rating Methodology.pptx
OWASP Risk Rating Methodology.pptx
 
Secure Coding principles by example: Build Security In from the start - Carlo...
Secure Coding principles by example: Build Security In from the start - Carlo...Secure Coding principles by example: Build Security In from the start - Carlo...
Secure Coding principles by example: Build Security In from the start - Carlo...
 
Bug Bounty 101
Bug Bounty 101Bug Bounty 101
Bug Bounty 101
 
Splunk Enterpise for Information Security Hands-On
Splunk Enterpise for Information Security Hands-OnSplunk Enterpise for Information Security Hands-On
Splunk Enterpise for Information Security Hands-On
 
OWASP Top 10 2021 What's New
OWASP Top 10 2021 What's NewOWASP Top 10 2021 What's New
OWASP Top 10 2021 What's New
 
DASK and Apache Spark
DASK and Apache SparkDASK and Apache Spark
DASK and Apache Spark
 
Desenvolvimento Seguro de Software - 10o Workshop SegInfo - Apresentação
Desenvolvimento Seguro de Software - 10o Workshop SegInfo - ApresentaçãoDesenvolvimento Seguro de Software - 10o Workshop SegInfo - Apresentação
Desenvolvimento Seguro de Software - 10o Workshop SegInfo - Apresentação
 
Python Programming Essentials - M23 - datetime module
Python Programming Essentials - M23 - datetime modulePython Programming Essentials - M23 - datetime module
Python Programming Essentials - M23 - datetime module
 
Talks@Coursera - A/B Testing @ Internet Scale
Talks@Coursera - A/B Testing @ Internet ScaleTalks@Coursera - A/B Testing @ Internet Scale
Talks@Coursera - A/B Testing @ Internet Scale
 
Approximate nearest neighbor methods and vector models – NYC ML meetup
Approximate nearest neighbor methods and vector models – NYC ML meetupApproximate nearest neighbor methods and vector models – NYC ML meetup
Approximate nearest neighbor methods and vector models – NYC ML meetup
 
Writing clean and maintainable code
Writing clean and maintainable codeWriting clean and maintainable code
Writing clean and maintainable code
 
Top 10 Web Security Vulnerabilities (OWASP Top 10)
Top 10 Web Security Vulnerabilities (OWASP Top 10)Top 10 Web Security Vulnerabilities (OWASP Top 10)
Top 10 Web Security Vulnerabilities (OWASP Top 10)
 
Brute force attack
Brute force attackBrute force attack
Brute force attack
 
ProdSec: A Technical Approach
ProdSec: A Technical ApproachProdSec: A Technical Approach
ProdSec: A Technical Approach
 
Bug Bounty - Hackers Job
Bug Bounty - Hackers JobBug Bounty - Hackers Job
Bug Bounty - Hackers Job
 
10X SOC - SANS Blue Summit Keynote 2021 - Anton Chuvakin
10X SOC - SANS Blue Summit Keynote 2021 - Anton Chuvakin10X SOC - SANS Blue Summit Keynote 2021 - Anton Chuvakin
10X SOC - SANS Blue Summit Keynote 2021 - Anton Chuvakin
 
It all starts with the ' (SQL injection from attacker's point of view)
It all starts with the ' (SQL injection from attacker's point of view)It all starts with the ' (SQL injection from attacker's point of view)
It all starts with the ' (SQL injection from attacker's point of view)
 
Python OOPs
Python OOPsPython OOPs
Python OOPs
 
sqlmap - security development in Python
sqlmap - security development in Pythonsqlmap - security development in Python
sqlmap - security development in Python
 

Destaque

Thinking hard about_python
Thinking hard about_pythonThinking hard about_python
Thinking hard about_pythonDaniel Greenfeld
 
Learn 90% of Python in 90 Minutes
Learn 90% of Python in 90 MinutesLearn 90% of Python in 90 Minutes
Learn 90% of Python in 90 MinutesMatt Harrison
 
Python Tricks That You Can't Live Without
Python Tricks That You Can't Live WithoutPython Tricks That You Can't Live Without
Python Tricks That You Can't Live WithoutAudrey Roy
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to PythonNowell Strite
 
Python 101: Python for Absolute Beginners (PyTexas 2014)
Python 101: Python for Absolute Beginners (PyTexas 2014)Python 101: Python for Absolute Beginners (PyTexas 2014)
Python 101: Python for Absolute Beginners (PyTexas 2014)Paige Bailey
 
Introduction to Python
Introduction to Python Introduction to Python
Introduction to Python amiable_indian
 
Object-oriented Programming in Python
Object-oriented Programming in PythonObject-oriented Programming in Python
Object-oriented Programming in PythonJuan-Manuel Gimeno
 
Introduction to python for Beginners
Introduction to python for Beginners Introduction to python for Beginners
Introduction to python for Beginners Sujith Kumar
 
Advanced Django Forms Usage
Advanced Django Forms UsageAdvanced Django Forms Usage
Advanced Django Forms UsageDaniel Greenfeld
 
Advanced Python : Static and Class Methods
Advanced Python : Static and Class Methods Advanced Python : Static and Class Methods
Advanced Python : Static and Class Methods Bhanwar Singh Meena
 
Advance OOP concepts in Python
Advance OOP concepts in PythonAdvance OOP concepts in Python
Advance OOP concepts in PythonSujith Kumar
 
Python Programming Language
Python Programming LanguagePython Programming Language
Python Programming LanguageLaxman Puri
 
Python PPT
Python PPTPython PPT
Python PPTEdureka!
 
Django Package Thunderdome by Audrey Roy & Daniel Greenfeld
Django Package Thunderdome by Audrey Roy & Daniel GreenfeldDjango Package Thunderdome by Audrey Roy & Daniel Greenfeld
Django Package Thunderdome by Audrey Roy & Daniel GreenfeldAudrey Roy
 
Confessions of Joe Developer
Confessions of Joe DeveloperConfessions of Joe Developer
Confessions of Joe DeveloperDaniel Greenfeld
 
Basics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonBasics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonSujith Kumar
 
Python Advanced – Building on the foundation
Python Advanced – Building on the foundationPython Advanced – Building on the foundation
Python Advanced – Building on the foundationKevlin Henney
 

Destaque (20)

Thinking hard about_python
Thinking hard about_pythonThinking hard about_python
Thinking hard about_python
 
Learn 90% of Python in 90 Minutes
Learn 90% of Python in 90 MinutesLearn 90% of Python in 90 Minutes
Learn 90% of Python in 90 Minutes
 
Python Tricks That You Can't Live Without
Python Tricks That You Can't Live WithoutPython Tricks That You Can't Live Without
Python Tricks That You Can't Live Without
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
Python 101: Python for Absolute Beginners (PyTexas 2014)
Python 101: Python for Absolute Beginners (PyTexas 2014)Python 101: Python for Absolute Beginners (PyTexas 2014)
Python 101: Python for Absolute Beginners (PyTexas 2014)
 
Introduction to Python
Introduction to Python Introduction to Python
Introduction to Python
 
Object-oriented Programming in Python
Object-oriented Programming in PythonObject-oriented Programming in Python
Object-oriented Programming in Python
 
Wordnet Introduction
Wordnet IntroductionWordnet Introduction
Wordnet Introduction
 
Introduction to python for Beginners
Introduction to python for Beginners Introduction to python for Beginners
Introduction to python for Beginners
 
Advanced Django Forms Usage
Advanced Django Forms UsageAdvanced Django Forms Usage
Advanced Django Forms Usage
 
Advanced Python : Static and Class Methods
Advanced Python : Static and Class Methods Advanced Python : Static and Class Methods
Advanced Python : Static and Class Methods
 
Advance OOP concepts in Python
Advance OOP concepts in PythonAdvance OOP concepts in Python
Advance OOP concepts in Python
 
Python Programming Language
Python Programming LanguagePython Programming Language
Python Programming Language
 
Python PPT
Python PPTPython PPT
Python PPT
 
Django Package Thunderdome by Audrey Roy & Daniel Greenfeld
Django Package Thunderdome by Audrey Roy & Daniel GreenfeldDjango Package Thunderdome by Audrey Roy & Daniel Greenfeld
Django Package Thunderdome by Audrey Roy & Daniel Greenfeld
 
Confessions of Joe Developer
Confessions of Joe DeveloperConfessions of Joe Developer
Confessions of Joe Developer
 
Why learn python in 2017?
Why learn python in 2017?Why learn python in 2017?
Why learn python in 2017?
 
Basics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonBasics of Object Oriented Programming in Python
Basics of Object Oriented Programming in Python
 
Python Advanced – Building on the foundation
Python Advanced – Building on the foundationPython Advanced – Building on the foundation
Python Advanced – Building on the foundation
 
Python/Django Training
Python/Django TrainingPython/Django Training
Python/Django Training
 

Mais de Daniel Greenfeld

Mais de Daniel Greenfeld (20)

How to Write a Popular Python Library by Accident
How to Write a Popular Python Library by AccidentHow to Write a Popular Python Library by Accident
How to Write a Popular Python Library by Accident
 
10 more-things-you-can-do-with-python
10 more-things-you-can-do-with-python10 more-things-you-can-do-with-python
10 more-things-you-can-do-with-python
 
From NASA to Startups to Big Commerce
From NASA to Startups to Big CommerceFrom NASA to Startups to Big Commerce
From NASA to Startups to Big Commerce
 
Intro to Data Visualizations
Intro to Data VisualizationsIntro to Data Visualizations
Intro to Data Visualizations
 
An Extreme Talk about the Zen of Python
An Extreme Talk about the Zen of PythonAn Extreme Talk about the Zen of Python
An Extreme Talk about the Zen of Python
 
PyCon Philippines 2012 Keynote
PyCon Philippines 2012 KeynotePyCon Philippines 2012 Keynote
PyCon Philippines 2012 Keynote
 
Round pegs and square holes
Round pegs and square holesRound pegs and square holes
Round pegs and square holes
 
Intro
IntroIntro
Intro
 
Intro to Python
Intro to PythonIntro to Python
Intro to Python
 
Lighting talk on django-social-auth
Lighting talk on django-social-authLighting talk on django-social-auth
Lighting talk on django-social-auth
 
Future of Collaboration
Future of CollaborationFuture of Collaboration
Future of Collaboration
 
The One Way
The One WayThe One Way
The One Way
 
Django Worst Practices
Django Worst PracticesDjango Worst Practices
Django Worst Practices
 
How to sell django panel
How to sell django panelHow to sell django panel
How to sell django panel
 
Pinax Long Tutorial Slides
Pinax Long Tutorial SlidesPinax Long Tutorial Slides
Pinax Long Tutorial Slides
 
Testing In Django
Testing In DjangoTesting In Django
Testing In Django
 
Django Uni-Form
Django Uni-FormDjango Uni-Form
Django Uni-Form
 
Nova Django
Nova DjangoNova Django
Nova Django
 
Pinax Introduction
Pinax IntroductionPinax Introduction
Pinax Introduction
 
Why Django
Why DjangoWhy Django
Why Django
 

Último

unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 

Último (20)

unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 

Python Worst Practices

  • 1. Python Worst Practices Daniel Greenfeld
  • 2. Daniel Greenfeld @pydanny I do cartwheels Daniel Greenfeld (@pydanny) Pythonista at Cartwheel Djangonaut at Revsys Co-lead of Django Packages & Open Comparison Learned Python at NASA Fiancé of Audrey Roy
  • 3. Daniel Greenfeld @pydanny Talk Format Each section will have three components: • At least one ‘Python Worst Practice’ slide • At least one ‘Fixed Python Practice’ slide • A side-by-side comparison slide These slides are already online!
  • 4. Daniel Greenfeld @pydanny Warning! Don’t use the ‘Python Worst Practices’ examples in your code* You may be hunted down and killed *Sometimes these are caught by various code checking tools
  • 5. Daniel Greenfeld @pydanny Advice! Do consider using the ‘Fixed Python Practices’ examples in your code You may get complimented
  • 7. Daniel Greenfeld @pydanny Python Worst Practice object = MyObject() map = Map() zip = 90213 # common US developer mistake id = 34 # I still fight this one I’m guilty • I still use ‘id’ when I shouldn’t • I admit I have a problem • That gives me license to pick on others
  • 8. Daniel Greenfeld @pydanny Fixed Python Practice obj = MyObject() # necessary abbreviation object_ = MyObject() # Underscore so we don't overwrite map_obj = Map() # combine name w/necessary abbreviation map_ = Map() zip_code = 90213 # Explicit name with US focus postal_code = 90213 # i18n explicit name zip_ = 90213 pk = 34 # pk is often synonymous with id id_ = 34
  • 9. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice object = MyObject() obj = MyObject() # Use a necessary abbreviation map = Map() object_ = MyObject() # Use underscore so we don't overwrite zip = 90213 # common US developer mistake id = 34 # I still fight this one map_obj = Map() # combine name with necessary abbreviation map_ = Map() zip_code = 90213 # Explicit name with US focus postal_code = 90213 # International explicit name zip_ = 90213 pk = 34 # pk is often synonymous with id id_ = 34
  • 10. Daniel Greenfeld @pydanny Python Worst Practice Flipping the booleans true = 0 false = 1 True = False Usually done to support an API
  • 11. Daniel Greenfeld @pydanny This sort of API def crazy_posting_api(value): """ If a value is supplied successfully return ‘0’. Otherwise return ‘1’ """ if value: return 0 return 1
  • 12. Daniel Greenfeld @pydanny Fixed Python Practice class CrazyApiConsumer(object): def __init__(self, value): self.value = value def post(self): # fix booleans in/around the return statement response = crazy_posting_api(self.value) return not bool(response) cac1 = CrazyApiConsumer("hello") print(cac1.post()) cac2 = CrazyApiConsumer("") print(cac2.post())
  • 13. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice true = 0 class CrazyApiConsumer(object): false = 1 True = False def __init__(self, value): self.value = value def post(self): # fix booleans in/around the return statement response = crazy_posting_api(self.value) return not bool(response) cac1 = CrazyApiConsumer("hello") print(cac1.post()) cac2 = CrazyApiConsumer("") print(cac2.post())
  • 14. Daniel Greenfeld @pydanny Python Worst Practice Identifying variable types with prefixes strColor = "green" boolActive = False intPythonYears = 20 dtPythonFirstUsed = "04/20/2011" Mixing case doesn’t help either
  • 15. Daniel Greenfeld @pydanny Python Worst Practice Conserving pixels by removing the vowels clr = "green" ctv = False pythnYrs = 20 pthnFrstSd = "04/20/2011"
  • 16. Daniel Greenfeld @pydanny Python Worst Practice c = "green" a = False p = 20 t = "04/20/2011"
  • 17. Daniel Greenfeld @pydanny Fixed Python Practice color = "green" active = False python_years = 20 python_first_used = "04/20/2011" Python assumes we are all consenting adults • Infer from naming schemes the type/purpose • Don’t be constrained by type
  • 18. Daniel Greenfeld @pydanny Fixed Python Practice color = "green" active = False python_years = 20 python_first_used = "04/20/2011" The pixel shortage is over. Use reasonably long variable names.
  • 19. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice c = "green" a = False color = "green" p = 20 t = "04/20/2011" active = False python_years = 20 python_first_used = "04/20/2011" clr = "green" ctv = False pythnYrs = 20 pthnFrstSd = "04/20/2011" strColor = "green" boolActive = False intPythonYears = 20 dtPythonFirstUsed = "04/20/2011"
  • 20. Daniel Greenfeld @pydanny Python Worst Practice Don’t use enumerate foo = [1, 2, 3] for i, item in zip(range(len(foo)), foo): print i, item
  • 21. Daniel Greenfeld @pydanny Fixed Python Practice Use enumerate foo = [1, 2, 3] for i, item in enumerate(foo): print i, item • Memorize the Python built-ins • Makes your code easier to read • Proven code
  • 22. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice foo = [1, 2, 3] foo = [1, 2, 3] zip(range(len(foo)), foo): for i, item in enumerate(foo): print i, item print i, item
  • 23. Python Worst Practice Present using Different Fonts Dark Text Dire Backgr#nds
  • 24. Daniel Greenfeld @pydanny Python Worst Practice Present using High Contrast Easy-to-read fonts All devices off All programs off
  • 25. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice Present using Present using Different Fonts High Contrast Dark Text Easy-to-read fonts Dire Backgr#nds All devices off All programs off
  • 27. Daniel Greenfeld @pydanny Python Worst Practice Implementing Java-style getters and setters import logging log = logging.getLogger() class JavaStyle: """ Quiz: what else am I doing wrong here? """ def __init__(self): self.name = "" def get_name(self): return self.name def set_name(self, name): log.debug("Setting the name to %s" % name) if isinstance(name, str): self.name = name else: raise TypeError() if __name__ == "__main__": j = JavaStyle() j.set_name("pydanny did this back in 2006!") print(j.get_name())
  • 28. Daniel Greenfeld @pydanny Fixed Python Practice Python properties! import logging log = logging.getLogger() class PythonStyle(object): def __init__(self): self._name = "" Accessor @property def name(self): return self._name Mutator @name.setter def name(self, value): """ Because name is probably a string we'll assume that we can infer the type from the variable name""" log.debug("Setting the name to %s" % value) self._name = value if __name__ == "__main__": p = PythonStyle() p.name = "pydanny doing it the right way" print(p.name)
  • 29. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice import logging import logging log = logging.getLogger() log = logging.getLogger() class JavaStyle: class PythonStyle(object): """ Quiz: what else am I doing wrong here? """ def __init__(self): def __init__(self): self._name = "" self.name = "" @property def get_name(self): def name(self): return self.name return self._name def set_name(self, name): @name.setter log.debug("Setting the name to %s" % name) def name(self, value): if isinstance(name, str): """ Because name is probably a string we'll assume that we can self.name = name infer the type from the variable name""" else: log.debug("Setting the name to %s" % value) raise TypeError() self._name = value if __name__ == "__main__": if __name__ == "__main__": j = JavaStyle() p = PythonStyle() j.set_name("pydanny did thisp.namein 2006!") doing it the right way" back = "pydanny print(j.get_name()) print(p.name)
  • 30. Daniel Greenfeld @pydanny Python Worst Practice Using property setters as action methods! class WebService(object): @property def connect(self): self.proxy = xmlrpc.Server("http://service.xml") if __name__ == '__main__': ws = WebService() ws.connect A.K.A.Trying to make your Python code look like Ruby
  • 31. Daniel Greenfeld @pydanny Fixed Python Practice Methods please! class WebService(object): def connect(self): self.proxy = xmlrpc.Server("http://service.xml") if __name__ == '__main__': ws = WebService() ws.connect()
  • 32. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice class WebService(object): class WebService(object): @property def connect(self): def connect(self): self.proxy = xmlrpc.Server("http://service.xml") self.proxy = xmlrpc.Server("http://service.xml") if __name__ == '__main__': if __name__ == '__main__': ws = WebService() ws.connect ws = WebService() ws.connect()
  • 34. Daniel Greenfeld @pydanny Python Worst Practice Passing Generic Exceptions silently try: do_akshun(value) except: pass • Ignorance is not bliss • You have no idea what your system is doing • Arguably better to not have this in your code
  • 35. Daniel Greenfeld @pydanny Fixed Python Practice Use specific exceptions and/or logging class AkshunDoesNotDo(Exception): """ Custom exceptions makes for maintainable code """ pass try: do_akshun(value) except AttributeError as e: log.info("Can I get attribution for these slides?") do_bakup_akshun(vlue) except Exception as e: log.debug(str(e)) raise AkshunDoesNotDo(e)
  • 36. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice try: class AkshunDoesNotDo(Exception): do_akshun(value) """ Custom exceptions makes for maintainable code """ except: pass pass try: do_akshun(value) except AttributeError as e: log.info("Can I get attribution for these slides?") do_bakup_akshun(vlue) except Exception as e: log.debug(str(e)) raise AkshunDoesNotDo(e)
  • 38. Daniel Greenfeld @pydanny Python Worst Practice Using exec for dynamic imports imports = "from {0} import {1}".format("random", "randrange") exec(imports) print(randrange(10)) • Hard to debug • Security risk • Sets bad precedents
  • 39. Daniel Greenfeld @pydanny Fixed Python Practice Using importlib for dynamic imports import importlib funstuff = importlib.import_module('random') print(funstuff.randrange(10)) • importlib is in the standard library • Really explicit • Direct tie into the Python machinery
  • 40. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice imports = "from {0} import {1}".format("random", "randrange") import importlib exec(imports) funstuff = importlib.import_module('random') print(randrange(10)) print(funstuff.randrange(10))
  • 41. Daniel Greenfeld @pydanny Python Worst Practice Generally using lambdas swap = lambda a, x, y: lambda f = a.__setitem__: (f(x, (a[x], a[y])), f(y, a[x][0]), f(x, a[x][1]))() • Too many characters on one line • Lambdas by design does not have docstrings • Does not necessarily mean less characters • I can’t get this sample to work!
  • 42. Daniel Greenfeld @pydanny Fixed Python Practice def swap(a, x, y): """ Swap two position values in a list """ a[x],a[y] = a[y],a[x] • Doc strings that show up nicely in help/Sphinx • Easier to read • In Python, functions are first class objects • Whenever possible avoid using lambdas
  • 43. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice swap = lambda a, x, y: def swap(a, x, y): lambda f = a.__setitem__: """ Swap two position values in a list """ (f(x, (a[x], a[y])), a[x],a[y] = a[y],a[x] f(y, a[x][0]), f(x, a[x][1]))()
  • 44. Daniel Greenfeld @pydanny Python Worst Practice Configuring your project with XML <pydanny-ml> <do action="call_view">com.pydanny.nextSlide</do> <global name="spam" value="eggs" /> </pydanny-ml> • You can’t convince me that XML is the better way • You are forcing me to learn a new language
  • 45. Daniel Greenfeld @pydanny Fixed Python Practice ? Use Python for configuration! spam = "eggs" actions = [ ('call_view', 'com.pydanny.nextSlide') ] • Is this the right way? • This allows conditional logic • Iterators • i.e. “Magic Configuration”
  • 46. Daniel Greenfeld @pydanny Python Worst Practice ‘Magical configuration code’ INSTALLED_APPS += [p for p in os.listdir(BASE) if os.path.isdir(p)] MIDDLEWARE_CLASSES = [...] def callback(arg, dirname, fnames): if 'middleware.py' in fnames: m = '%s.middleware' % os.path.split(dirname)[-1] MIDDLEWARE_CLASSES.append(m) urlpatterns = patterns('', ...) for app in settings.INSTALLED_APPS: if not app.startswith('django'): p = url('^%s/' % app, include('%s.urls') % app) urlpatterns += patterns('', p) Ugh. http://www.slideshare.net/jacobian/the-best-and-worst-of-django
  • 47. Daniel Greenfeld @pydanny Fixed Python 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
  • 48. Daniel Greenfeld @pydanny Fixed Python 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
  • 49. Daniel Greenfeld @pydanny Fixed Python Practice Use a config file spam = "eggs" [actions] call_view = com.pydanny.nextSlide Read up on config parser http://docs.python.org/library/configparser.html
  • 50. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice XML simple python files logic heavy python config (.cfg) files
  • 52. Daniel Greenfeld @pydanny Python Worst Practice Bad docstrings class Pythonista(): # Old style class! """ This class represents a Python programmer """ def code(self): """Write some code """ code, inspiration = Code(), Inspiration() for hour in Effort(): try: code += hour + inspiraion except CurseWorthyBug: ... • Do really obvious objects require doc strings? • Complex methods require more than docstrings!
  • 53. Daniel Greenfeld @pydanny Fixed Python Practice class Pythonista(object): def code(self): """ Writes code following these steps 1. Create a space for coding 2. Get some inspiration 3. Loop through some hours of effort Spend a 4. Write some code few minutes 5. Pull out hair cause of bugs """ documenting code = Code() the critical inspiration = Inspiration() for hour in Effort(): stuff, okay? try: code += hour + inspiraion except CurseWorthyBug: ...
  • 54. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice class Pythonista(): # Old style class! class Pythonista(object): """ This class represents a Python programmer """ def code(self): def code(self): """ Writes code following these steps """Write some code """ 1. Create a space for coding code, inspiration = Code(), Inspiration() 2. Get some inspiration for hour in Effort(): 3. Loop through some hours of effort try: 4. Write some code code += hour + inspiraion 5. Pull out hair cause of bugs except CurseWorthyBug: """ ... code = Code() inspiration = Inspiration() for hour in Effort(): try: code += hour + inspiraion except CurseWorthyBug: ...
  • 55. Daniel Greenfeld @pydanny Python Worst Practice Using a wiki for project documentation “Wikis are where project documentation goes to die” Jacob Kaplan-Moss • Generally not version controlled • Backups? Mirrors? • Editing via the web? Ugh. • No pull requests - smaller group of contributors
  • 56. Daniel Greenfeld @pydanny Fixed Python Practice • Use Restructured Text • Use Sphinx • Host on http://readthedocs.org
  • 57. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice
  • 58. Daniel Greenfeld @pydanny Python Worst Practice >>> import that The Anti-Zen of Python, by Daniel Greenfeld Ugly is better than beautiful. Implicit is better than explicit. Complicated is better than complex. Complex is better than simple. Nested is better than flat. Dense is better than sparse. Line code counts. Special cases are special enough to break the rules. Although purity beats practicality. Errors should always pass silently. Spelchek iz fur loosers. In the face of explicity, succumb to the temptation to guess. There should be many ways to do it. Because only a tiny minority of us are Dutch. Later is the best time to fix something. If the implementation is hard to explain, it's a good sell. If the implementation is easy to explain, it won't take enough time to do. Namespaces are too hard, just use import *! http://pypi.python.org/pypi/that
  • 59. Daniel Greenfeld @pydanny Fixed Python Practice >>> import this The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those! Core Python
  • 60. Daniel Greenfeld @pydanny Side-by-side comparison Worst Practice Fixed Practice >>> import this >>> import that The Zen of Python, by Tim Peters The Anti-Zen of Python, by Daniel Greenfeld Beautiful is better than ugly. Ugly is better than beautiful. Explicit is better than implicit. Implicit is better than explicit. Simple is better than complex. Complicated is better than complex. Complex is better than complicated. Complex is better than simple. Flat is better than nested. Nested is better than flat. Sparse is better than dense. Dense is better than sparse. Readability counts. Line code counts. Special cases aren't special enough to break the rules. Special cases are special enough to break the rules. Although practicality beats purity. Although purity beats practicality. Errors should never pass silently. Errors should always pass silently. Unless explicitly silenced. Spelchek iz fur loosers. In the face of ambiguity, refuse the temptation to guess. In the face of explicity, succumb to the temptation to guess. There should be one-- and preferably only one --obvious way to do it. There should be many ways to do it. Although that way may not be obvious at first unless you're Dutch. Because only a tiny minority of us are Dutch. Now is better than never. Later is the best time to fix something. Although never is often better than *right* now. If the implementation is hard to explain, it's a good sell. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it won't take enough time to do. If the implementation is easy to explain, it may be a good idea. Namespaces are too hard, just use import *! Namespaces are one honking great idea -- let's do more of those!