🥟 Entrada
🍽️ Plato principal
🥄 Postre
- PEP8
Homunculo, extraido de Smalltalk, Objects and Design. Chamond Liu.
'humunculo', 1, print
('humunculo', 1, <function print>)
'humunculo'.upper()
'HUMUNCULO'
'humunculo'.split('u')
['h', 'm', 'nc', 'lo']
👤 💌 🖃 👤 ✉️ 🧧 👤
Why objects matter
When all the rhetoric is set aside -the rhetoric about reusability and productivity and so on- the salient charateristic of objects is that they reduce translation. That is, objects promote a common vocabulary: everyone, whether a software professional or not, has some intuitive understanding of what an object is. Thus we can understand one another more easil when we use objects to describe our thinking. Objects, then, promote mutual understanding -between users, analysts, executives, designers, programmers, testers... They reduce the effort of translating one persons'thoughts to another's, and therefore reduce misunderstandings as an idea passes from one person to the next.
As for reuse and productivity, they are nothing more that side effects of better understanding...
Smaltalk, Objects and Design. Chamond Liu
Huevos a la carta
-----------------
Huevo duro $0.1
Huevo frito $0.2
Quiero que imprima la orden completa y el total
!cat ordenes.txt
orden, cantidad, estilo 1, 1, duro 2, 2, frito
from soluciones.chef_nivel_uno import solucion
solucion.ejecutar()
1 pidio 1 huevo duro 2 pidio 2 huevo frito Total: 3.4
from soluciones.chef_nivel_dos.solucion import CocinarHuevos
CocinarHuevos().ejecutar()
La orden 1 es de 1 huevo 🥚 La orden 2 es de 2 huevos 🍳 El total a pagar es 0.5 pesos.
from soluciones.chef_nivel_tres.solucion import CocinarHuevos
CocinarHuevos().ejecutar()
La orden 1 es de 1 huevo 🥚 La orden 2 es de 2 huevos 🍳 El total a pagar es 0.5 pesos.
!tree soluciones/
soluciones/ ├── chef_nivel_dos │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ ├── solucion.cpython-38.pyc │ │ └── test.cpython-38-pytest-6.0.1.pyc │ ├── solucion.py │ └── test.py ├── chef_nivel_tres │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-38.pyc │ │ ├── solucion.cpython-38.pyc │ │ └── test_cocinar_huevos.cpython-38-pytest-6.0.1.pyc │ ├── solucion.py │ └── test_cocinar_huevos.py ├── chef_nivel_uno │ ├── __pycache__ │ │ └── solucion.cpython-38.pyc │ └── solucion.py ├── __init__.py └── __pycache__ └── __init__.cpython-38.pyc 7 directories, 16 files
# %load soluciones/chef_nivel_uno/solucion.py
precios = (1.0, 1.2) # Precios : ( duro, frito )
def ejecutar():
'Cocinar Huevos'
#Cargar ordenes
O = []
try:
with open('ordenes.txt','r') as f:
i = 0
for l in f:
# print(l)
if i == 0:
i += 1
continue
else:
# print(l)
# print(l[6:])
if (l[6:] == 'duro') or (l[6:] == 'duro\n'):
print(f'{l[0]} pidio {l[3]} huevo {l[6:]}')
O.append( ('duro', int(l[3]) ) )
elif (l[6:] == 'frito') or (l[6:] == 'frito\n'):
print(f'{l[0]} pidio {l[3]} huevo {l[6:]}')
O.append( ('frito', int(l[3])) )
i += 1
except:
print('No se pudieron cargar las ordenes. Ahhh!!')
# print(O)
# Calcular total
t = 0
for i in O:
if i[0] == 'duro':
t += precios[0]*i[1]
else:
t += precios[1]*i[1]
print(f'Total: {t}')
if __name__ == '__main__':
ejecutar()
1 pidio 1 huevo duro 2 pidio 2 huevo frito Total: 3.4
# %load soluciones/chef_nivel_dos/solucion.py
import csv
from collections import Counter, namedtuple
Orden = namedtuple('Orden','orden cantidad estilo')
class CocinarHuevos:
PRECIOS = { 'duro' : 1.0,
'frito': 1.2,
}
REPR = { 'duro' : '\N{egg}',
'frito' : '\N{cooking}',
}
@staticmethod
def ejecutar(archivo='ordenes.txt'):
with open(archivo) as f:
csv_reader = csv.reader(f)
ordenes = list(csv_reader)[1:]
cuentas = Counter( row[2] for row in ordenes for _ in range(int(row[1].strip())) )
total = sum( CocinarHuevos.PRECIOS.get(k.strip(),0)*v for k,v in cuentas.items() )
CocinarHuevos.informar(ordenes)
print(f'El total a pagar es {total} pesos.')
@staticmethod
def informar(ordenes):
for orden in ordenes:
orden = Orden(*orden)
x = ( f'huevo {CocinarHuevos.REPR.get(orden.estilo.strip())}'
if int(orden.cantidad.strip()) == 1
else f'huevos {CocinarHuevos.REPR.get(orden.estilo.strip())}' )
print(f'La orden {orden.orden} es de {orden.cantidad.strip()} {x}')
Patrones de Diseño
# %load soluciones/chef_nivel_dos/test.py
from .solucion import CocinarHuevos
esperado = '''La orden 1 es de 1 huevo 🥚
La orden 2 es de 2 huevos 🍳
El total a pagar es 3.4 pesos.
'''
def test_CocinarHuevos(capsys):
CocinarHuevos().ejecutar()
captured = capsys.readouterr()
assert captured.out == esperado
--------------------------------------------------------------------------- ImportError Traceback (most recent call last) <ipython-input-12-618844e8a431> in <module> 1 # %load soluciones/chef_nivel_dos/test.py ----> 2 from .solucion import CocinarHuevos 3 4 esperado = '''La orden 1 es de 1 huevo 🥚 5 La orden 2 es de 2 huevos 🍳 ImportError: attempted relative import with no known parent package
# %load soluciones/chef_nivel_tres/solucion.py
import csv
from collections import Counter, namedtuple
Orden = namedtuple('Orden','orden cantidad estilo')
class CocinarHuevos:
PRECIOS = { 'duro' : 1.0,
'frito': 1.2,
}
REPR = { 'duro' : '\N{egg}',
'frito' : '\N{cooking}',
}
@staticmethod
def ejecutar(archivo='ordenes.txt'):
with open(archivo) as f:
csv_reader = csv.reader(f)
ordenes = list(csv_reader)[1:]
cuentas = Counter( row[2] for row in ordenes for _ in range(int(row[1].strip())) )
total = sum( CocinarHuevos.PRECIOS.get(k.strip(),0)*v for k,v in cuentas.items() )
CocinarHuevos.informar(ordenes)
print(f'El total a pagar es {total} pesos.')
@staticmethod
def informar(ordenes):
for orden in ordenes:
orden = Orden(*orden)
x = ( f'huevo {CocinarHuevos.REPR.get(orden.estilo.strip())}'
if int(orden.cantidad.strip()) == 1
else f'huevos {CocinarHuevos.REPR.get(orden.estilo.strip())}' )
print(f'La orden {orden.orden} es de {orden.cantidad.strip()} {x}')
Preparar omelet, que cuesta $0.5 y lleva dos huevos
!cat nuevas_ordenes.csv
Los objetos deben estar abiertos para ser extendidos pero cerrados para ser modificados.
Objects should be open for extension, but closed for modification.
Imagen adaptada de 99 Bottles of OOP
Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.
Martin Fowler, Refactoring
Alternative Classes with Different Interfaces
Comments
Data Class
Data Clumps
Divergent Change
Duplicated Code
Feature Envy
Global Data
Insider Trading
Large Class
Lazy Element
Long Function
Long Parameter List
Loops
Message Chains
Middle Man
Mutable Data
Mysterious Name
Primitive Obsession
Refused Bequest
Repeated Switches
Shotgun Surgery
Speculative Generality
Temporary Field
!pytest soluciones/chef_nivel_dos/test.py
# %load soluciones/chef_nivel_dos/solucion.py
import csv
from collections import Counter, namedtuple
Orden = namedtuple('Orden','orden cantidad estilo')
class CocinarHuevos:
PRECIOS = { 'duro' : 1.0,
'frito': 1.2,
}
REPR = { 'duro' : '\N{egg}',
'frito' : '\N{cooking}',
}
@staticmethod
def ejecutar(archivo='ordenes.txt'):
with open(archivo) as f:
csv_reader = csv.reader(f)
ordenes = list(csv_reader)[1:]
cuentas = Counter( row[2] for row in ordenes for _ in range(int(row[1].strip())) )
total = sum( CocinarHuevos.PRECIOS.get(k.strip(),0)*v for k,v in cuentas.items() )
CocinarHuevos.informar(ordenes)
print(f'El total a pagar es {total} pesos.')
@staticmethod
def informar(ordenes):
for orden in ordenes:
orden = Orden(*orden)
x = ( f'huevo {CocinarHuevos.REPR.get(orden.estilo.strip())}'
if int(orden.cantidad.strip()) == 1
else f'huevos {CocinarHuevos.REPR.get(orden.estilo.strip())}' )
print(f'La orden {orden.orden} es de {orden.cantidad.strip()} {x}')
sashaKile
https://www.bonappetit.com/recipe/relish-tray-with-diy-eggs
https://www.bonappetit.com/recipe/traditional-carbonara
https://www.bonappetit.com/recipe/flan-with-grapefruit
https://www.bonappetit.com/video/watch/12-types-12-types-of-eggs-examined-and-cooked
https://www.bonappetit.com/video/watch/every-way-to-cook-an-egg-59-methods