SlideShare uma empresa Scribd logo
1 de 44
Ulteriori
approfondimenti
Python
Enrico Franchi
enrico.franchi@gmail.com
franchi@cs.unipr.it
Aumentare il dinamismo
Python offre come builtin getattr, setattr e
hasattr
  f.foo     getattr(f, ‘foo’)

  f.foo = 4     setattr(f, ‘foo’, 4)

  hasattr   controlla solo se c’è l’attributo
Questo vuole dire che possiamo chiedere
un attributo a runtime conoscendone il
nome
Forte capacità di introspezione (assieme al
Esempio
class Capsule(object):
   def __init__(self, obj):
      self.obj = obj

  def get(self, attribute_path):
    parts = attribute_path.split('.')
    current_obj = self.obj
    for attribute in parts:
       current_obj = getattr(current_obj, attribute)
    return current_obj




if __name__ == "__main__":
    d = datetime.date(1983, 7, 1)

  e = Capsule(Employee('Enrico Franchi', d))

  print e.get('birth_date.month')
Ripasso MRO
Sia a oggetto di tipo A, sottoclasse di B e
C
a.foo cerca nell’ordine:
1.fra gli attributi dell’oggetto a
2.fra gli attributi dell’oggetto classe A
3.fra gli attributi dell’oggetto classe B
4.fra gli attributi dell’oggetto classe C
Se non viene trovato, viene lanciato
AttributeError
Eppure...
Di fatto prima di lanciare AttributeError, si
vede se è disponibile un metodo
__getattr__(self, name)

In questo caso viene passato il nome
dell’attributo come stringa (in name)
Il corpo di __getattr__ può specificare cosa
ritornare (o se lanciare eccezione)
NB: siccome i metodi sono anche attributi,
funziona anche con loro
Per i “PRO” ci sono anche i descrittori...
Esempio
class Capsule(object):
   def __init__(self, obj):
      self.obj = obj

  def get(self, attribute_path):
    parts = attribute_path.split('.')
    current_obj = self.obj
    for attribute in parts:
       current_obj = getattr(current_obj, attribute)
    return current_obj

  def __getattr__(self, attribute):
    return getattr(self.obj, attribute)
Esempio
class Capsule(object):
   def __init__(self, obj):
      self.obj = obj

  def get(self, attribute_path):
    parts = attribute_path.split('.')
    current_obj = self.obj
    for attribute in parts:
       current_obj = getattr(current_obj, attribute)
    return current_obj

  def __getattr__(self, attribute):
    return getattr(self.obj, attribute)




                                                Facile delegare...
                                      (pensate un po’ al decorator pattern...)
Esempio
class Enum(object):
   def __init__(self, *args, **kargs):
      self._enums = dict(((name, i) for i, name in enumerate(args)))
     min_val, max_val = 0, len(args)
      for k, v in kargs.iteritems():
         if min_val < v < max_val:
            raise ValueError, ('Value %s already specified' % v)
         else:
            self._enums[k] = v

  def __getattr__(self, name):
    try:
       return self._enums[name]
    except KeyError:
       raise AttributeError
Esempio
class Enum(object):
   def __init__(self, *args, **kargs):
      self._enums = dict(((name, i) for i, name in enumerate(args)))
     min_val, max_val = 0, len(args)
      for k, v in kargs.iteritems():
         if min_val < v < max_val:
            raise ValueError, ('Value %s already specified' % v)
         else:
            self._enums[k] = v

  def __getattr__(self, name):
    try:
       return self._enums[name]
    except KeyError:
       raise AttributeError




                       Per Enum fatte a modo, qui.
                      Meglio ancora le named tuples.
Funzioni create a runtime
class Collection(object):
   def __init__(self, l=None):
      self.buf = l or []

  def find(self, **kargs):
    temp_buf = self.buf
    for k, v in kargs.iteritems():
       temp_buf = [item for item in temp_buf
                if getattr(item, k) == v]
    return temp_buf
Funzioni create a runtime
class Collection(object):
   def __init__(self, l=None):
      self.buf = l or []

  def find(self, **kargs):
    temp_buf = self.buf
    for k, v b1 kargs.iteritems():
             in = book.Book('Python in a Nutshell', 'Alex Martelli')
       temp_buf = [item for item in temp_buf 'Alex Martelli')
             b2 = book.Book('Python Cookbook',
             b3 if getattr(item, k) == v]
                = book.Book('Python', 'Marco Beri')
    return temp_buf
             b4 = book.Book('Sviluppare applicazioni web con Django',
                        'Marco Beri')
             b5 = book.Book('Espressioni Regolari', 'Marco Beri')

             c = Collection([b1, b2, b3, b4, b5])
             for b in c.find(title='Python', author='Marco Beri'):
                print b
Funzioni create a runtime
class Collection(object):
   def __init__(self, l=None):
      self.buf = l or []

  def find(self, **kargs):
    temp_buf = self.buf
    for k, v in kargs.iteritems():
       temp_buf = [item for item in temp_buf
                if getattr(item, k) == v]
    return temp_buf



  @classmethod
  def add_method(cls, func, name):
    func.im_class = cls
    func.im_func = func
    func.im_self = None
    func.func_name = name
    setattr(cls, name, func)
__getattr__ avanzato
def __getattr__(self, name):
  if name.startswith('find_by_'):
     key = name[8:]
     def _aux(self, value):
        return Collection.find(self, **{key : value})
     Collection.add_method(_aux, name)
     return getattr(self, name)
  else: raise TypeError
__getattr__ avanzato
def __getattr__(self, name):
  if name.startswith('find_by_'):
     key = name[8:]
     def _aux(self, value):
        return Collection.find(self, **{key : value})
     Collection.add_method(_aux, name)
     return getattr(self, name)
  else: raise TypeError



  Creiamo una funzione a runtime
__getattr__ avanzato
def __getattr__(self, name):
  if name.startswith('find_by_'):
     key = name[8:]
     def _aux(self, value):
        return Collection.find(self, **{key : value})
     Collection.add_method(_aux, name)
     return getattr(self, name)
  else: raise TypeError



  Creiamo una funzione a runtime
  La facciamo diventare metodo della classe
__getattr__ avanzato
def __getattr__(self, name):
  if name.startswith('find_by_'):
     key = name[8:]
     def _aux(self, value):
        return Collection.find(self, **{key : value})
     Collection.add_method(_aux, name)
     return getattr(self, name)
  else: raise TypeError



  Creiamo una funzione a runtime
  La facciamo diventare metodo della classe
  Ora getattr la può trovare (nella fase 2.) e
  restituisce il metodo
__getattr__ avanzato
def __getattr__(self, name):
  if name.startswith('find_by_'):
     key = name[8:]
     def _aux(self, value):
        return Collection.find(self, **{key : value})
     Collection.add_method(_aux, name)
     return getattr(self, name)
  else: raise TypeError



  Creiamo una funzione a runtime
for b in c.find_by_author('Marco Beri'):
  La facciamo diventare metodo della classe
   print b

for b in c.find_by_author('Alex Martelli'):
  Ora getattr la può trovare (nella fase 2.) e
   print b

  restituisce il metodo
Server side modules
Scriviamo un gestore (“handler”) che
contiene il codice per implementare il
protocollo
Creiamo un server cui passiamo l’handler
  Il server gestisce i dettagli, noi il protocollo
  Server prefabbricati:
    TCPServer                       ForkingUDPServer
    UDPServer                       ThreadingTCPServe
                                    r
    ForkingTCPServer
Handler
Per ogni richiesta viene creato un nuovo
handler
Alcuni server (Threading, Forking)
gestiscono concorrenza, gli altri in serie
  con un server Forking di base le modifiche
  allo stato dei figli non si riflette sul padre
  con un Threading bisogna gestire lock,
  etc...
Handler (2)
 Si sottoclassa un handler
 (SocketServer.BaseRequestHandler)
 Si “overridda” handle(self) [e altro se
 opport.]
 Si hanno come variabili d’istanza
   self.request: la richiesta (socket)
   self.client_address: guess...
   self.server: un’istanza del server
 Entro certi limiti, si è indipendenti dal
Handler (2)
 Si sottoclassa un handler
 (SocketServer.BaseRequestHandler)
 Si “overridda” handle(self) [e altro se
 opport.]
                                             Chi scrive trova
 Si hanno come variabili d’istanza           particolarmente
   self.request: la richiesta (socket)           orrendo
   self.client_address: guess...                il termine
   self.server: un’istanza del server
 Entro certi limiti, si è indipendenti dal
import SocketServer

class EchoHandler(SocketServer.BaseRequestHandler):
   def handle(self):
      print 'Connected from', self.client_address
      try:
         for message in self.messages():
            if message.upper().startswith('QUIT'):
               break
            self.request.sendall(message)
      finally:
         self.request.close()
         print 'Disconnected from', self.client_address

  def messages(self):
    while True:
       rec_data = self.request.recv(8192)
       if not rec_data: break
       yield rec_data

try:
   srv = SocketServer.ForkingTCPServer(('', 8881), EchoHandler)
   srv.serve_forever()
except KeyboardInterrupt:
   print 'Stopping server...'
Scriviamo Gumball!
Scriviamo un simulatore di macchine che
distribuiscono palline di gomma
  Inserisci un quarto di dollaro
  Gira la manovella
  Fatti restituire il quarto di dollaro
  [consegna la pallina]

L’esempio viene da Head First Design
Patterns, Freeman&Freeman, O’Reilly
Il metodo tradizionale
class GumballMachine(object):
   SOLD_OUT = 0
   NO_QUARTER = 1
   HAS_QUARTER = 2
   SOLD = 3

  def __init__(self, count):
    self.count = count
    self.state = GumballMachine.SOLD_OUT
    if self.count > 0:
        self.state = GumballMachine.NO_QUARTER

  def insert_quarter(self):
    if self.state == GumballMachine.HAS_QUARTER:
        print "You can't insert another quarter"
    elif self.state == GumballMachine.NO_QUARTER:
        self.state = GumballMachine.HAS_QUARTER
        print "You inserted a quarter"
    elif self.state == GumballMachine.SOLD_OUT:
        print "You can't insert a quarter, the machine is sold out"
    elif self.state == GumballMachine.SOLD:
        print "Please wait, we are already giving you a gumball"
Il metodo tradizionale
def eject_quarter(self):
  if self.state == GumballMachine.HAS_QUARTER:
      print "Quarter returned"
      self.state = GumballMachine.NO_QUARTER
  elif self.state == GumballMachine.NO_QUARTER:
      print "You haven't inserted a quarter"
  elif self.state == GumballMachine.SOLD_OUT:
      print "You can't eject, you haven't inserted a quarter yet"
  elif self.state == GumballMachine.SOLD:
      print "Sorry, you already turned the crank"

def turn_crank(self):
  if self.state == GumballMachine.SOLD:
      print "Turning twice doesn't get you another gumball"
  elif self.state == GumballMachine.NO_QUARTER:
      print "You turned, but there is no quarter"
  elif self.state == GumballMachine.SOLD_OUT:
      print "You turned, but there is no quarter"
  elif self.state == GumballMachine.HAS_QUARTER:
      print "You turned..."
      self.state = GumballMachine.SOLD
      self.dispense()
Il metodo tradizionale
def dispense(self):
  if self.state == GumballMachine.SOLD:
      print "A gumball comes rolling out of the slot"
      self.count -= 1
      if self.count == 0:
          print "Oops, out of gumballs"
          self.state = GumballMachine.SOLD_OUT
      else:
          self.state = GumballMachine.NO_QUARTER
  elif self.state == GumballMachine.NO_QUARTER:
      print "You need to pay first"
  elif self.state == GumballMachine.SOLD_OUT:
      print "No gumball dispensed"
  elif self.state == GumballMachine.HAS_QUARTER:
      print "No gumball dispensed"
Il metodo tradizionale
def dispense(self):
  if self.state == GumballMachine.SOLD:
      print "A gumball comes rolling out of the slot"
      self.count -= 1
      if self.count == 0:
          print "Oops, out of gumballs"
          self.state = GumballMachine.SOLD_OUT
      else:
          self.state = GumballMachine.NO_QUARTER
  elif self.state == GumballMachine.NO_QUARTER:
      print "You need to pay first"
  elif self.state == GumballMachine.SOLD_OUT:
      print "No gumball dispensed"
  elif self.state == GumballMachine.HAS_QUARTER:
      print "No gumball dispensed"




             Ora supponiamo di volere aggiungere uno stato...
ENCAPSULATE WHAT VARIES
State pattern e protocolli
 Design pattern nei linguaggi dinamici
 State pattern
 Vediamo il punto di vista per implementare
 un protocollo?
Pattern state
 Gli stati sono rappresentati da oggetti
 L’oggetto principale “delega” le azioni ai
 metodi degli stati
   Eventualmente questi cambiano lo stato




 Aggiungere stati diventa facile
class GumballMachine(object):
   'The true and only gumball machine'
   actions = set(['insert_quarter', 'eject_quarter',
             'turn_crank', 'dispense'])

  def __init__(self, count):
    self.no_quarter = NoQuarterState(self)
    self.has_quarter = HasQuarterState(self)
    self.sold = SoldState(self)
    self.sold_out = SoldOutState(self)

     self.count = count
     self.state = self.sold_out
     if self.count > 0:
         self.state = self.no_quarter

  def __getattr__(self, action):
    if action in GumballMachine.actions:
        return getattr(self.state, action)

  def __str__(self):
    return ("nMighty Gumball, Incn"
     "Python-enabled Standing Gumball Model #2009n"
     "Built from orginal specifications by Freeman&Freeman,"
     " Head First Design Patternsn"
     "Inventory: %d gumballsn") % (self.count)
class HasQuarterState(object):
   'Represent a state where the machine has a quarter inside.'
   def __init__(self, gumball):
      self.gumball = gumball

  def insert_quarter(self):
    'Perform quarter insertion'
    print "You can't insert another quarter"

  def eject_quarter(self):
    'Ask the quarter back'
    print "Quarter returned"
    self.gumball.state = self.gumball.no_quarter

  def turn_crank(self):
    'Turn the crank'
    print "You turned..."
    self.gumball.state = self.gumball.sold
    self.gumball.dispense()

  def dispense(self):
    'Actually gives the gumball'
    print "No gumball dispensed"
class NoQuarterState(object):
   'Represent a state where the machine has no quarter inside.'
   def __init__(self, gumball):
      self.gumball = gumball

  def insert_quarter(self):
    'Perform quarter insertion'
    self.gumball.state = self.gumball.has_quarter
    print "You inserted a quarter"

  def eject_quarter(self):
    'Ask the quarter back'
    print "You haven't inserted a quarter"

  def turn_crank(self):
    'Turn the crank'
    print "You turned, but there is no quarter"

  def dispense(self):
    'Actually gives the gumball'
    print "You need to pay first"
class SoldState(object):
   'The machine is to dispense the ball'
   def __init__(self, gumball):
      self.gumball = gumball

  def insert_quarter(self):
    'Perform quarter insertion'
    print "Please wait, we are already giving you a gumball"

  def eject_quarter(self):
    'Ask the quarter back'
    print "Sorry, you already turned the crank"

  def turn_crank(self):
    'Turn the crank'
    print "Turning twice doesn't get you another gumball"

  def dispense(self):
    'Actually gives the gumball'
    print "A gumball comes rolling out of the slot"
    self.gumball.count -= 1
    if self.gumball.count == 0:
        print "Oops, out of gumballs"
        self.gumball.state = self.gumball.sold_out
    else:
        self.gumball.state = self.gumball.no_quarter
class SoldOutState(object):
   'No more balls. Sorry guys.'
   def __init__(self, gumball):
      self.gumball = gumball

  def insert_quarter(self):
    'Perform quarter insertion'
    print "You can't insert a quarter, the machine is sold out"

  def eject_quarter(self):
    'Ask the quarter back'
    print "You can't eject, you haven't inserted a quarter yet"

  def turn_crank(self):
    'Turn the crank'
    print "You turned, but there is no quarter"

  def dispense(self):
    'Actually gives the gumball'
    print "No gumball dispensed"
Setattr
 def __setattr__(self, name, value): ...

 __getattr__viene chiamato solo quando non
 si trova l’attributo, __setattr__ è chiamato
 sempre
 Attenzione ai loop se lo ridefinite!

                              def   __setattr__(self, name, value):
                              
     if name in self.names:
                              
     
    self.k = value * self.conversion[name]
                              
     elif name == ‘k’:
                              
     
    object.__setattr__(self, name, value)
                              
     else:
                              
     
    raise AttributeError, name
Q&A
Web
cgi (sconsigliato)/fastcgi
WSGI: modulo di medio livello per interfacciarsi con i
server
Django: framework completo, molto usato
Nevow: framework completo basato su Twisted
Zope2/3: “mega framework”
Google App Engine (+web.py ev. Django)
web.py: modulo minimalista, facile comprensione
Web.py
   import web

   urls = (
      '/(.*)', 'hello'
   )
   app = web.application(urls, globals())

   class hello:
      def GET(self, name):
        if not name:
           name = 'world'
        return 'Hello, ' + name + '!'

   if __name__ == "__main__":
       app.run()
XML-RPC Server
from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler

class RequestHandler(SimpleXMLRPCRequestHandler):
   rpc_paths = ('/RPC2',)

server = SimpleXMLRPCServer(("localhost", 8000),
                   requestHandler=RequestHandler)
server.register_introspection_functions()
server.register_function(pow)

def adder_function(x,y):
  return x + y
server.register_function(adder_function, 'add')

class MyFuncs:
   def div(self, x, y):
      return x // y
server.register_instance(MyFuncs())

server.serve_forever()
XML-RPC Client

 import xmlrpclib

 s = xmlrpclib.ServerProxy('http://localhost:8000')
 print s.pow(2,3) # Returns 2**3 = 8
 print s.add(2,3) # Returns 5
 print s.div(5,2) # Returns 5//2 = 2

 # Print list of available methods
 print s.system.listMethods()

Mais conteúdo relacionado

Mais procurados

Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to PigChris Wilkes
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
 
Javascript essential-pattern
Javascript essential-patternJavascript essential-pattern
Javascript essential-pattern偉格 高
 
JSConf: All You Can Leet
JSConf: All You Can LeetJSConf: All You Can Leet
JSConf: All You Can Leetjohndaviddalton
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserHoward Lewis Ship
 
Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1Zaar Hai
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language TriviaNikita Popov
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!Brendan Eich
 
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new APIMTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new APISix Apart KK
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation JavascriptRamesh Nair
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsŁukasz Chruściel
 
Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Juriy Zaytsev
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptLoïc Knuchel
 
Ian 20150116 java script oop
Ian 20150116 java script oopIan 20150116 java script oop
Ian 20150116 java script oopLearningTech
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix itRafael Dohms
 

Mais procurados (20)

Pig Introduction to Pig
Pig Introduction to PigPig Introduction to Pig
Pig Introduction to Pig
 
this
thisthis
this
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
Javascript essential-pattern
Javascript essential-patternJavascript essential-pattern
Javascript essential-pattern
 
JSConf: All You Can Leet
JSConf: All You Can LeetJSConf: All You Can Leet
JSConf: All You Can Leet
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1
 
ddd+scala
ddd+scaladdd+scala
ddd+scala
 
PHP Language Trivia
PHP Language TriviaPHP Language Trivia
PHP Language Trivia
 
Oojs 1.1
Oojs 1.1Oojs 1.1
Oojs 1.1
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
 
MTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new APIMTDDC 2010.2.5 Tokyo - Brand new API
MTDDC 2010.2.5 Tokyo - Brand new API
 
ES6 - Next Generation Javascript
ES6 - Next Generation JavascriptES6 - Next Generation Javascript
ES6 - Next Generation Javascript
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patterns
 
Say Hello To Ecmascript 5
Say Hello To Ecmascript 5Say Hello To Ecmascript 5
Say Hello To Ecmascript 5
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 
Codeware
CodewareCodeware
Codeware
 
Programmation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScriptProgrammation fonctionnelle en JavaScript
Programmation fonctionnelle en JavaScript
 
Ian 20150116 java script oop
Ian 20150116 java script oopIan 20150116 java script oop
Ian 20150116 java script oop
 
Your code sucks, let's fix it
Your code sucks, let's fix itYour code sucks, let's fix it
Your code sucks, let's fix it
 

Destaque

马尔基尔:漫步华尔街
马尔基尔:漫步华尔街马尔基尔:漫步华尔街
马尔基尔:漫步华尔街大璋 王
 
MoneyTrac CPG: Adding a new debit credit card
MoneyTrac CPG: Adding a new debit credit cardMoneyTrac CPG: Adding a new debit credit card
MoneyTrac CPG: Adding a new debit credit cardGlobal Payout
 
MoneyTrac CPG: Prepaid discover card application and activation
MoneyTrac CPG: Prepaid discover card application and activationMoneyTrac CPG: Prepaid discover card application and activation
MoneyTrac CPG: Prepaid discover card application and activationGlobal Payout
 
MoneyTrac CPG: Adding a community member
MoneyTrac CPG: Adding a community memberMoneyTrac CPG: Adding a community member
MoneyTrac CPG: Adding a community memberGlobal Payout
 
Willkommen in der Echtzeit! #AFBMC
Willkommen in der Echtzeit! #AFBMCWillkommen in der Echtzeit! #AFBMC
Willkommen in der Echtzeit! #AFBMCAllFacebook.de
 
价值投资的运用困难
价值投资的运用困难价值投资的运用困难
价值投资的运用困难大璋 王
 
MONOGRAFIA DATACION ARQUEOLOGICA 2009
MONOGRAFIA DATACION ARQUEOLOGICA 2009MONOGRAFIA DATACION ARQUEOLOGICA 2009
MONOGRAFIA DATACION ARQUEOLOGICA 2009burmandaniel
 
Equipos TP Lípidos 2007
Equipos TP Lípidos 2007Equipos TP Lípidos 2007
Equipos TP Lípidos 2007burmandaniel
 
Cayco thuoc+nam05
Cayco thuoc+nam05Cayco thuoc+nam05
Cayco thuoc+nam05Duy Vọng
 
S3 D 01 Pr..[1]
S3 D 01 Pr..[1]S3 D 01 Pr..[1]
S3 D 01 Pr..[1]Fiama Oré
 
Universidad tecnologica antonio jose de sucre
Universidad tecnologica antonio jose de sucreUniversidad tecnologica antonio jose de sucre
Universidad tecnologica antonio jose de sucrepablo-24jose
 
Cayco thuoc+nam21
Cayco thuoc+nam21Cayco thuoc+nam21
Cayco thuoc+nam21Duy Vọng
 
SIEMBRA DE FRESA ORGANICA
SIEMBRA DE FRESA ORGANICASIEMBRA DE FRESA ORGANICA
SIEMBRA DE FRESA ORGANICAdanielg232000
 
Understanding how and why students use lecture captures
Understanding how and why students use lecture capturesUnderstanding how and why students use lecture captures
Understanding how and why students use lecture capturesMatt Cornock
 
Internet session: Stavíme e-shop, internet vs. kamenná prodejna
Internet session: Stavíme e-shop, internet vs. kamenná prodejnaInternet session: Stavíme e-shop, internet vs. kamenná prodejna
Internet session: Stavíme e-shop, internet vs. kamenná prodejnaoptimio
 
How students use lecture captures as part of their studying
How students use lecture captures as part of their studyingHow students use lecture captures as part of their studying
How students use lecture captures as part of their studyingMatt Cornock
 
UPDATED Spring 2010 Public Presentation
UPDATED Spring 2010 Public PresentationUPDATED Spring 2010 Public Presentation
UPDATED Spring 2010 Public PresentationRegional Plan
 

Destaque (20)

马尔基尔:漫步华尔街
马尔基尔:漫步华尔街马尔基尔:漫步华尔街
马尔基尔:漫步华尔街
 
MoneyTrac CPG: Adding a new debit credit card
MoneyTrac CPG: Adding a new debit credit cardMoneyTrac CPG: Adding a new debit credit card
MoneyTrac CPG: Adding a new debit credit card
 
MoneyTrac CPG: Prepaid discover card application and activation
MoneyTrac CPG: Prepaid discover card application and activationMoneyTrac CPG: Prepaid discover card application and activation
MoneyTrac CPG: Prepaid discover card application and activation
 
Método de caso
Método de casoMétodo de caso
Método de caso
 
MoneyTrac CPG: Adding a community member
MoneyTrac CPG: Adding a community memberMoneyTrac CPG: Adding a community member
MoneyTrac CPG: Adding a community member
 
Calatogue apps
Calatogue appsCalatogue apps
Calatogue apps
 
Willkommen in der Echtzeit! #AFBMC
Willkommen in der Echtzeit! #AFBMCWillkommen in der Echtzeit! #AFBMC
Willkommen in der Echtzeit! #AFBMC
 
价值投资的运用困难
价值投资的运用困难价值投资的运用困难
价值投资的运用困难
 
Doc1
Doc1Doc1
Doc1
 
MONOGRAFIA DATACION ARQUEOLOGICA 2009
MONOGRAFIA DATACION ARQUEOLOGICA 2009MONOGRAFIA DATACION ARQUEOLOGICA 2009
MONOGRAFIA DATACION ARQUEOLOGICA 2009
 
Equipos TP Lípidos 2007
Equipos TP Lípidos 2007Equipos TP Lípidos 2007
Equipos TP Lípidos 2007
 
Cayco thuoc+nam05
Cayco thuoc+nam05Cayco thuoc+nam05
Cayco thuoc+nam05
 
S3 D 01 Pr..[1]
S3 D 01 Pr..[1]S3 D 01 Pr..[1]
S3 D 01 Pr..[1]
 
Universidad tecnologica antonio jose de sucre
Universidad tecnologica antonio jose de sucreUniversidad tecnologica antonio jose de sucre
Universidad tecnologica antonio jose de sucre
 
Cayco thuoc+nam21
Cayco thuoc+nam21Cayco thuoc+nam21
Cayco thuoc+nam21
 
SIEMBRA DE FRESA ORGANICA
SIEMBRA DE FRESA ORGANICASIEMBRA DE FRESA ORGANICA
SIEMBRA DE FRESA ORGANICA
 
Understanding how and why students use lecture captures
Understanding how and why students use lecture capturesUnderstanding how and why students use lecture captures
Understanding how and why students use lecture captures
 
Internet session: Stavíme e-shop, internet vs. kamenná prodejna
Internet session: Stavíme e-shop, internet vs. kamenná prodejnaInternet session: Stavíme e-shop, internet vs. kamenná prodejna
Internet session: Stavíme e-shop, internet vs. kamenná prodejna
 
How students use lecture captures as part of their studying
How students use lecture captures as part of their studyingHow students use lecture captures as part of their studying
How students use lecture captures as part of their studying
 
UPDATED Spring 2010 Public Presentation
UPDATED Spring 2010 Public PresentationUPDATED Spring 2010 Public Presentation
UPDATED Spring 2010 Public Presentation
 

Semelhante a Pyimproved again

Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethodsdreampuf
 
Declarative Data Modeling in Python
Declarative Data Modeling in PythonDeclarative Data Modeling in Python
Declarative Data Modeling in PythonJoshua Forman
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicGraham Dumpleton
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicNew Relic
 
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...Databricks
 
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...Matthew Tovbin
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
#! usrbinpythonimport naoqiimport timeipaddress = 192..docx
#! usrbinpythonimport naoqiimport timeipaddress = 192..docx#! usrbinpythonimport naoqiimport timeipaddress = 192..docx
#! usrbinpythonimport naoqiimport timeipaddress = 192..docxkatherncarlyle
 
Gevent what's the point
Gevent what's the pointGevent what's the point
Gevent what's the pointseanmcq
 
The Ring programming language version 1.7 book - Part 16 of 196
The Ring programming language version 1.7 book - Part 16 of 196The Ring programming language version 1.7 book - Part 16 of 196
The Ring programming language version 1.7 book - Part 16 of 196Mahmoud Samir Fayed
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript IntroductionDmitry Sheiko
 
用Tornado开发RESTful API运用
用Tornado开发RESTful API运用用Tornado开发RESTful API运用
用Tornado开发RESTful API运用Felinx Lee
 
Testing My Patience
Testing My PatienceTesting My Patience
Testing My PatienceAdam Lowry
 
Practical Google App Engine Applications In Py
Practical Google App Engine Applications In PyPractical Google App Engine Applications In Py
Practical Google App Engine Applications In PyEric ShangKuan
 
The Ring programming language version 1.6 book - Part 15 of 189
The Ring programming language version 1.6 book - Part 15 of 189The Ring programming language version 1.6 book - Part 15 of 189
The Ring programming language version 1.6 book - Part 15 of 189Mahmoud Samir Fayed
 
Say Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick SuttererSay Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick SuttererRuby Meditation
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridGiorgio Cefaro
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrideugenio pombi
 

Semelhante a Pyimproved again (20)

Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Declarative Data Modeling in Python
Declarative Data Modeling in PythonDeclarative Data Modeling in Python
Declarative Data Modeling in Python
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New Relic
 
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
The Rule of 10,000 Spark Jobs: Learning From Exceptions and Serializing Your ...
 
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
The Rule of 10,000 Spark Jobs - Learning from Exceptions and Serializing Your...
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
25-functions.ppt
25-functions.ppt25-functions.ppt
25-functions.ppt
 
#! usrbinpythonimport naoqiimport timeipaddress = 192..docx
#! usrbinpythonimport naoqiimport timeipaddress = 192..docx#! usrbinpythonimport naoqiimport timeipaddress = 192..docx
#! usrbinpythonimport naoqiimport timeipaddress = 192..docx
 
Gevent what's the point
Gevent what's the pointGevent what's the point
Gevent what's the point
 
The Ring programming language version 1.7 book - Part 16 of 196
The Ring programming language version 1.7 book - Part 16 of 196The Ring programming language version 1.7 book - Part 16 of 196
The Ring programming language version 1.7 book - Part 16 of 196
 
TypeScript Introduction
TypeScript IntroductionTypeScript Introduction
TypeScript Introduction
 
用Tornado开发RESTful API运用
用Tornado开发RESTful API运用用Tornado开发RESTful API运用
用Tornado开发RESTful API运用
 
Testing My Patience
Testing My PatienceTesting My Patience
Testing My Patience
 
Practical Google App Engine Applications In Py
Practical Google App Engine Applications In PyPractical Google App Engine Applications In Py
Practical Google App Engine Applications In Py
 
The Ring programming language version 1.6 book - Part 15 of 189
The Ring programming language version 1.6 book - Part 15 of 189The Ring programming language version 1.6 book - Part 15 of 189
The Ring programming language version 1.6 book - Part 15 of 189
 
Say Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick SuttererSay Goodbye to Procedural Programming - Nick Sutterer
Say Goodbye to Procedural Programming - Nick Sutterer
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrid
 
Datagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and BackgridDatagrids with Symfony 2, Backbone and Backgrid
Datagrids with Symfony 2, Backbone and Backgrid
 

Mais de rik0

Python intro
Python introPython intro
Python introrik0
 
Complex and Social Network Analysis in Python
Complex and Social Network Analysis in PythonComplex and Social Network Analysis in Python
Complex and Social Network Analysis in Pythonrik0
 
Game theory
Game theoryGame theory
Game theoryrik0
 
Social choice
Social choiceSocial choice
Social choicerik0
 
Social Network Analysis
Social Network AnalysisSocial Network Analysis
Social Network Analysisrik0
 
Clojure Interoperability
Clojure InteroperabilityClojure Interoperability
Clojure Interoperabilityrik0
 
Pydiomatic
PydiomaticPydiomatic
Pydiomaticrik0
 
Pycrashcourse4.0 pdfjam
Pycrashcourse4.0 pdfjamPycrashcourse4.0 pdfjam
Pycrashcourse4.0 pdfjamrik0
 
Twcrashcourse
TwcrashcourseTwcrashcourse
Twcrashcourserik0
 
Pycrashcourse3.1
Pycrashcourse3.1Pycrashcourse3.1
Pycrashcourse3.1rik0
 
Pycrashcourse3.0
Pycrashcourse3.0Pycrashcourse3.0
Pycrashcourse3.0rik0
 
Pycrashcourse2.0
Pycrashcourse2.0Pycrashcourse2.0
Pycrashcourse2.0rik0
 
Pycrashcourse
PycrashcoursePycrashcourse
Pycrashcourserik0
 
Pyimproved
PyimprovedPyimproved
Pyimprovedrik0
 

Mais de rik0 (14)

Python intro
Python introPython intro
Python intro
 
Complex and Social Network Analysis in Python
Complex and Social Network Analysis in PythonComplex and Social Network Analysis in Python
Complex and Social Network Analysis in Python
 
Game theory
Game theoryGame theory
Game theory
 
Social choice
Social choiceSocial choice
Social choice
 
Social Network Analysis
Social Network AnalysisSocial Network Analysis
Social Network Analysis
 
Clojure Interoperability
Clojure InteroperabilityClojure Interoperability
Clojure Interoperability
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
 
Pycrashcourse4.0 pdfjam
Pycrashcourse4.0 pdfjamPycrashcourse4.0 pdfjam
Pycrashcourse4.0 pdfjam
 
Twcrashcourse
TwcrashcourseTwcrashcourse
Twcrashcourse
 
Pycrashcourse3.1
Pycrashcourse3.1Pycrashcourse3.1
Pycrashcourse3.1
 
Pycrashcourse3.0
Pycrashcourse3.0Pycrashcourse3.0
Pycrashcourse3.0
 
Pycrashcourse2.0
Pycrashcourse2.0Pycrashcourse2.0
Pycrashcourse2.0
 
Pycrashcourse
PycrashcoursePycrashcourse
Pycrashcourse
 
Pyimproved
PyimprovedPyimproved
Pyimproved
 

Último

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 

Último (20)

Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 

Pyimproved again

  • 2. Aumentare il dinamismo Python offre come builtin getattr, setattr e hasattr f.foo getattr(f, ‘foo’) f.foo = 4 setattr(f, ‘foo’, 4) hasattr controlla solo se c’è l’attributo Questo vuole dire che possiamo chiedere un attributo a runtime conoscendone il nome Forte capacità di introspezione (assieme al
  • 3. Esempio class Capsule(object): def __init__(self, obj): self.obj = obj def get(self, attribute_path): parts = attribute_path.split('.') current_obj = self.obj for attribute in parts: current_obj = getattr(current_obj, attribute) return current_obj if __name__ == "__main__": d = datetime.date(1983, 7, 1) e = Capsule(Employee('Enrico Franchi', d)) print e.get('birth_date.month')
  • 4. Ripasso MRO Sia a oggetto di tipo A, sottoclasse di B e C a.foo cerca nell’ordine: 1.fra gli attributi dell’oggetto a 2.fra gli attributi dell’oggetto classe A 3.fra gli attributi dell’oggetto classe B 4.fra gli attributi dell’oggetto classe C Se non viene trovato, viene lanciato AttributeError
  • 5. Eppure... Di fatto prima di lanciare AttributeError, si vede se è disponibile un metodo __getattr__(self, name) In questo caso viene passato il nome dell’attributo come stringa (in name) Il corpo di __getattr__ può specificare cosa ritornare (o se lanciare eccezione) NB: siccome i metodi sono anche attributi, funziona anche con loro Per i “PRO” ci sono anche i descrittori...
  • 6. Esempio class Capsule(object): def __init__(self, obj): self.obj = obj def get(self, attribute_path): parts = attribute_path.split('.') current_obj = self.obj for attribute in parts: current_obj = getattr(current_obj, attribute) return current_obj def __getattr__(self, attribute): return getattr(self.obj, attribute)
  • 7. Esempio class Capsule(object): def __init__(self, obj): self.obj = obj def get(self, attribute_path): parts = attribute_path.split('.') current_obj = self.obj for attribute in parts: current_obj = getattr(current_obj, attribute) return current_obj def __getattr__(self, attribute): return getattr(self.obj, attribute) Facile delegare... (pensate un po’ al decorator pattern...)
  • 8. Esempio class Enum(object): def __init__(self, *args, **kargs): self._enums = dict(((name, i) for i, name in enumerate(args))) min_val, max_val = 0, len(args) for k, v in kargs.iteritems(): if min_val < v < max_val: raise ValueError, ('Value %s already specified' % v) else: self._enums[k] = v def __getattr__(self, name): try: return self._enums[name] except KeyError: raise AttributeError
  • 9. Esempio class Enum(object): def __init__(self, *args, **kargs): self._enums = dict(((name, i) for i, name in enumerate(args))) min_val, max_val = 0, len(args) for k, v in kargs.iteritems(): if min_val < v < max_val: raise ValueError, ('Value %s already specified' % v) else: self._enums[k] = v def __getattr__(self, name): try: return self._enums[name] except KeyError: raise AttributeError Per Enum fatte a modo, qui. Meglio ancora le named tuples.
  • 10. Funzioni create a runtime class Collection(object): def __init__(self, l=None): self.buf = l or [] def find(self, **kargs): temp_buf = self.buf for k, v in kargs.iteritems(): temp_buf = [item for item in temp_buf if getattr(item, k) == v] return temp_buf
  • 11. Funzioni create a runtime class Collection(object): def __init__(self, l=None): self.buf = l or [] def find(self, **kargs): temp_buf = self.buf for k, v b1 kargs.iteritems(): in = book.Book('Python in a Nutshell', 'Alex Martelli') temp_buf = [item for item in temp_buf 'Alex Martelli') b2 = book.Book('Python Cookbook', b3 if getattr(item, k) == v] = book.Book('Python', 'Marco Beri') return temp_buf b4 = book.Book('Sviluppare applicazioni web con Django', 'Marco Beri') b5 = book.Book('Espressioni Regolari', 'Marco Beri') c = Collection([b1, b2, b3, b4, b5]) for b in c.find(title='Python', author='Marco Beri'): print b
  • 12. Funzioni create a runtime class Collection(object): def __init__(self, l=None): self.buf = l or [] def find(self, **kargs): temp_buf = self.buf for k, v in kargs.iteritems(): temp_buf = [item for item in temp_buf if getattr(item, k) == v] return temp_buf @classmethod def add_method(cls, func, name): func.im_class = cls func.im_func = func func.im_self = None func.func_name = name setattr(cls, name, func)
  • 13. __getattr__ avanzato def __getattr__(self, name): if name.startswith('find_by_'): key = name[8:] def _aux(self, value): return Collection.find(self, **{key : value}) Collection.add_method(_aux, name) return getattr(self, name) else: raise TypeError
  • 14. __getattr__ avanzato def __getattr__(self, name): if name.startswith('find_by_'): key = name[8:] def _aux(self, value): return Collection.find(self, **{key : value}) Collection.add_method(_aux, name) return getattr(self, name) else: raise TypeError Creiamo una funzione a runtime
  • 15. __getattr__ avanzato def __getattr__(self, name): if name.startswith('find_by_'): key = name[8:] def _aux(self, value): return Collection.find(self, **{key : value}) Collection.add_method(_aux, name) return getattr(self, name) else: raise TypeError Creiamo una funzione a runtime La facciamo diventare metodo della classe
  • 16. __getattr__ avanzato def __getattr__(self, name): if name.startswith('find_by_'): key = name[8:] def _aux(self, value): return Collection.find(self, **{key : value}) Collection.add_method(_aux, name) return getattr(self, name) else: raise TypeError Creiamo una funzione a runtime La facciamo diventare metodo della classe Ora getattr la può trovare (nella fase 2.) e restituisce il metodo
  • 17. __getattr__ avanzato def __getattr__(self, name): if name.startswith('find_by_'): key = name[8:] def _aux(self, value): return Collection.find(self, **{key : value}) Collection.add_method(_aux, name) return getattr(self, name) else: raise TypeError Creiamo una funzione a runtime for b in c.find_by_author('Marco Beri'): La facciamo diventare metodo della classe print b for b in c.find_by_author('Alex Martelli'): Ora getattr la può trovare (nella fase 2.) e print b restituisce il metodo
  • 18. Server side modules Scriviamo un gestore (“handler”) che contiene il codice per implementare il protocollo Creiamo un server cui passiamo l’handler Il server gestisce i dettagli, noi il protocollo Server prefabbricati: TCPServer ForkingUDPServer UDPServer ThreadingTCPServe r ForkingTCPServer
  • 19. Handler Per ogni richiesta viene creato un nuovo handler Alcuni server (Threading, Forking) gestiscono concorrenza, gli altri in serie con un server Forking di base le modifiche allo stato dei figli non si riflette sul padre con un Threading bisogna gestire lock, etc...
  • 20. Handler (2) Si sottoclassa un handler (SocketServer.BaseRequestHandler) Si “overridda” handle(self) [e altro se opport.] Si hanno come variabili d’istanza self.request: la richiesta (socket) self.client_address: guess... self.server: un’istanza del server Entro certi limiti, si è indipendenti dal
  • 21. Handler (2) Si sottoclassa un handler (SocketServer.BaseRequestHandler) Si “overridda” handle(self) [e altro se opport.] Chi scrive trova Si hanno come variabili d’istanza particolarmente self.request: la richiesta (socket) orrendo self.client_address: guess... il termine self.server: un’istanza del server Entro certi limiti, si è indipendenti dal
  • 22. import SocketServer class EchoHandler(SocketServer.BaseRequestHandler): def handle(self): print 'Connected from', self.client_address try: for message in self.messages(): if message.upper().startswith('QUIT'): break self.request.sendall(message) finally: self.request.close() print 'Disconnected from', self.client_address def messages(self): while True: rec_data = self.request.recv(8192) if not rec_data: break yield rec_data try: srv = SocketServer.ForkingTCPServer(('', 8881), EchoHandler) srv.serve_forever() except KeyboardInterrupt: print 'Stopping server...'
  • 23. Scriviamo Gumball! Scriviamo un simulatore di macchine che distribuiscono palline di gomma Inserisci un quarto di dollaro Gira la manovella Fatti restituire il quarto di dollaro [consegna la pallina] L’esempio viene da Head First Design Patterns, Freeman&Freeman, O’Reilly
  • 24.
  • 25. Il metodo tradizionale class GumballMachine(object): SOLD_OUT = 0 NO_QUARTER = 1 HAS_QUARTER = 2 SOLD = 3 def __init__(self, count): self.count = count self.state = GumballMachine.SOLD_OUT if self.count > 0: self.state = GumballMachine.NO_QUARTER def insert_quarter(self): if self.state == GumballMachine.HAS_QUARTER: print "You can't insert another quarter" elif self.state == GumballMachine.NO_QUARTER: self.state = GumballMachine.HAS_QUARTER print "You inserted a quarter" elif self.state == GumballMachine.SOLD_OUT: print "You can't insert a quarter, the machine is sold out" elif self.state == GumballMachine.SOLD: print "Please wait, we are already giving you a gumball"
  • 26. Il metodo tradizionale def eject_quarter(self): if self.state == GumballMachine.HAS_QUARTER: print "Quarter returned" self.state = GumballMachine.NO_QUARTER elif self.state == GumballMachine.NO_QUARTER: print "You haven't inserted a quarter" elif self.state == GumballMachine.SOLD_OUT: print "You can't eject, you haven't inserted a quarter yet" elif self.state == GumballMachine.SOLD: print "Sorry, you already turned the crank" def turn_crank(self): if self.state == GumballMachine.SOLD: print "Turning twice doesn't get you another gumball" elif self.state == GumballMachine.NO_QUARTER: print "You turned, but there is no quarter" elif self.state == GumballMachine.SOLD_OUT: print "You turned, but there is no quarter" elif self.state == GumballMachine.HAS_QUARTER: print "You turned..." self.state = GumballMachine.SOLD self.dispense()
  • 27. Il metodo tradizionale def dispense(self): if self.state == GumballMachine.SOLD: print "A gumball comes rolling out of the slot" self.count -= 1 if self.count == 0: print "Oops, out of gumballs" self.state = GumballMachine.SOLD_OUT else: self.state = GumballMachine.NO_QUARTER elif self.state == GumballMachine.NO_QUARTER: print "You need to pay first" elif self.state == GumballMachine.SOLD_OUT: print "No gumball dispensed" elif self.state == GumballMachine.HAS_QUARTER: print "No gumball dispensed"
  • 28. Il metodo tradizionale def dispense(self): if self.state == GumballMachine.SOLD: print "A gumball comes rolling out of the slot" self.count -= 1 if self.count == 0: print "Oops, out of gumballs" self.state = GumballMachine.SOLD_OUT else: self.state = GumballMachine.NO_QUARTER elif self.state == GumballMachine.NO_QUARTER: print "You need to pay first" elif self.state == GumballMachine.SOLD_OUT: print "No gumball dispensed" elif self.state == GumballMachine.HAS_QUARTER: print "No gumball dispensed" Ora supponiamo di volere aggiungere uno stato...
  • 29.
  • 31. State pattern e protocolli Design pattern nei linguaggi dinamici State pattern Vediamo il punto di vista per implementare un protocollo?
  • 32. Pattern state Gli stati sono rappresentati da oggetti L’oggetto principale “delega” le azioni ai metodi degli stati Eventualmente questi cambiano lo stato Aggiungere stati diventa facile
  • 33. class GumballMachine(object): 'The true and only gumball machine' actions = set(['insert_quarter', 'eject_quarter', 'turn_crank', 'dispense']) def __init__(self, count): self.no_quarter = NoQuarterState(self) self.has_quarter = HasQuarterState(self) self.sold = SoldState(self) self.sold_out = SoldOutState(self) self.count = count self.state = self.sold_out if self.count > 0: self.state = self.no_quarter def __getattr__(self, action): if action in GumballMachine.actions: return getattr(self.state, action) def __str__(self): return ("nMighty Gumball, Incn" "Python-enabled Standing Gumball Model #2009n" "Built from orginal specifications by Freeman&Freeman," " Head First Design Patternsn" "Inventory: %d gumballsn") % (self.count)
  • 34. class HasQuarterState(object): 'Represent a state where the machine has a quarter inside.' def __init__(self, gumball): self.gumball = gumball def insert_quarter(self): 'Perform quarter insertion' print "You can't insert another quarter" def eject_quarter(self): 'Ask the quarter back' print "Quarter returned" self.gumball.state = self.gumball.no_quarter def turn_crank(self): 'Turn the crank' print "You turned..." self.gumball.state = self.gumball.sold self.gumball.dispense() def dispense(self): 'Actually gives the gumball' print "No gumball dispensed"
  • 35. class NoQuarterState(object): 'Represent a state where the machine has no quarter inside.' def __init__(self, gumball): self.gumball = gumball def insert_quarter(self): 'Perform quarter insertion' self.gumball.state = self.gumball.has_quarter print "You inserted a quarter" def eject_quarter(self): 'Ask the quarter back' print "You haven't inserted a quarter" def turn_crank(self): 'Turn the crank' print "You turned, but there is no quarter" def dispense(self): 'Actually gives the gumball' print "You need to pay first"
  • 36. class SoldState(object): 'The machine is to dispense the ball' def __init__(self, gumball): self.gumball = gumball def insert_quarter(self): 'Perform quarter insertion' print "Please wait, we are already giving you a gumball" def eject_quarter(self): 'Ask the quarter back' print "Sorry, you already turned the crank" def turn_crank(self): 'Turn the crank' print "Turning twice doesn't get you another gumball" def dispense(self): 'Actually gives the gumball' print "A gumball comes rolling out of the slot" self.gumball.count -= 1 if self.gumball.count == 0: print "Oops, out of gumballs" self.gumball.state = self.gumball.sold_out else: self.gumball.state = self.gumball.no_quarter
  • 37. class SoldOutState(object): 'No more balls. Sorry guys.' def __init__(self, gumball): self.gumball = gumball def insert_quarter(self): 'Perform quarter insertion' print "You can't insert a quarter, the machine is sold out" def eject_quarter(self): 'Ask the quarter back' print "You can't eject, you haven't inserted a quarter yet" def turn_crank(self): 'Turn the crank' print "You turned, but there is no quarter" def dispense(self): 'Actually gives the gumball' print "No gumball dispensed"
  • 38. Setattr def __setattr__(self, name, value): ... __getattr__viene chiamato solo quando non si trova l’attributo, __setattr__ è chiamato sempre Attenzione ai loop se lo ridefinite! def __setattr__(self, name, value): if name in self.names: self.k = value * self.conversion[name] elif name == ‘k’: object.__setattr__(self, name, value) else: raise AttributeError, name
  • 39.
  • 40. Q&A
  • 41. Web cgi (sconsigliato)/fastcgi WSGI: modulo di medio livello per interfacciarsi con i server Django: framework completo, molto usato Nevow: framework completo basato su Twisted Zope2/3: “mega framework” Google App Engine (+web.py ev. Django) web.py: modulo minimalista, facile comprensione
  • 42. Web.py import web urls = ( '/(.*)', 'hello' ) app = web.application(urls, globals()) class hello: def GET(self, name): if not name: name = 'world' return 'Hello, ' + name + '!' if __name__ == "__main__": app.run()
  • 43. XML-RPC Server from SimpleXMLRPCServer import SimpleXMLRPCServer from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler class RequestHandler(SimpleXMLRPCRequestHandler): rpc_paths = ('/RPC2',) server = SimpleXMLRPCServer(("localhost", 8000), requestHandler=RequestHandler) server.register_introspection_functions() server.register_function(pow) def adder_function(x,y): return x + y server.register_function(adder_function, 'add') class MyFuncs: def div(self, x, y): return x // y server.register_instance(MyFuncs()) server.serve_forever()
  • 44. XML-RPC Client import xmlrpclib s = xmlrpclib.ServerProxy('http://localhost:8000') print s.pow(2,3) # Returns 2**3 = 8 print s.add(2,3) # Returns 5 print s.div(5,2) # Returns 5//2 = 2 # Print list of available methods print s.system.listMethods()

Notas do Editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n