Programar (casi) sin condicionales

10 de Noviembre de 2022, PyAr Meetup

@sashakile

qr

lapiz resortes

cadena

cramica

marqueteria

vidrio

Artesanía de Software

Programa de la charla

  • ¿Qué significa programar?
  • Ejemplo práctico

Programar

Modelo simplificado de programación

Entes

entes

Entes

homunculo

Mensajes

homunculo 🎁 homunculo

👾 ✉ 
🤖 ✉
👤 📦
🦆 🔊
ente mensaje

Necesitamos un sistema para clasificar a los Entes

Ente

    nuevo -> { } 

    interactuar: x -> {
        x otroMensaje: yo
      }

    combinarCon: x e: y -> {
        [yo, x, y]
      }
MiEnteCantor <: Ente

   contar -> { ... } 

   cantar: partitura -> { ... } 

Caracteres <: Ente

Cadenas de caracteres <: Ente

Números <: Ente

Fotos <: Ente

Archivos Matrices URLs Patos Conexiones Colecciones Bits

> "Hola Mundo!" 
> "Hola Mundo!" tamaño 
11
> "Hola Mundo!" tamaño sumar: 31

Condicionales

Dada una [premisa]

[consecuente]

Control de la ejecución

Ejercicio 🤔
Ejercicio 🤔
Booleano <: Ente

  negar {}

  y: otro {}

  o: otro {}
Ejercicio 🤔
Verdadero <: Booleano

  negar {}

  y: otro {}

  o: otro {}
Ejercicio 🤔
Verdadero <: Booleano    Falso <: Booleano
                         
  negar {}                 negar {}
                         
  y: otro {}               y: otro {}
                         
  o: otro {}               o: otro {}

booleano y: otroBooleano

y Verdadero Falso
Verdadero
Falso

booleano o: otroBooleano

o Verdadero Falso
Verdadero
Falso

reloj-arena

Ejemplo 🐍

Tabla: Empresa de Agua Potable 💧

"""
Edificacion, Id, Tipo
casa,         0, domestico
departamento, 1, domestico
departamento, 2, comercial
departamento, 3, oficina
casa,         4, oficina
"""
lineas = documento.splitlines()
headers = [ e.strip() for e in lineas[0].split(",") ]
total = 0
for linea in lineas[1:]:
    if len(linea.strip()) > 0:
        fila = linea.split(",")
        valores = [ e.strip() for e in fila ]
        ed, id_, tipo= valores
        escala = 1.0
        if ed == "casa":
            total += 1.0 
        elif ed == "departamento":
            total += 0.5 
        else:
            print(f"Desconocido:{valores}")

Tabla: Empresa de Agua Potable 💧

"""
Edificacion, Id, Tipo
casa,         0, domestico
departamento, 1, domestico
departamento, 2, comercial
departamento, 3, oficina
casa,         4, oficina
"""

"oficina": 0.8, 
"comercial": 5.0, 
"domestico": 1.0, 
precios = {"oficina": 0.8, "comercial": 5.0, "domestico": 1.0}

for linea in lineas[1:]:
    if len(linea.strip()) > 0:
        fila = linea.split(",")
        valores = [ e.strip() for e in fila ]
        ed, id_, tipo= valores
        escala = 1.0
        if ed == "casa":
            total += 1.0 * precios[tipo] 
        elif ed == "departamento":
            total += 0.5 * precios[tipo]
        else:
            print(f"Desconocido:{valores}")

Tabla: Empresa de Agua Potable 💧

"""
Edificacion, Id,      Tipo, Consumo
casa,         0, domestico, 3.1
departamento, 1, domestico, 11.4
departamento, 2, comercial, 0.1
departamento, 3,   oficina, 10.0
casa,         4,   oficina, 1.0
"""
for linea in lineas[1:]:
    if len(linea.strip()) > 0:
        fila = linea.split(",")
        valores = [ e.strip() for e in fila ]
        ed, id_, tipo, consumo = valores
        escala = 1.0
        if ed == "casa":
            if consumo > 1.0:
                escala = 5.0
            else:
                escala = 1.1

            total += 1.0 * escala * precios[tipo] * consumo
        elif ed == "departamento":
            if consumo > 1.0:
                escala = 3.0
            else:
                escala = 1.2

            total += 0.5 * escala * precios[tipo] * consumo
        else:
            print(f"Desconocido:{valores}")

Tabla: Empresa de Energía Eléctrica ⚡

"""
 Edificacion, Id,      Tipo, Consumo
        casa, A0, domestico, 6.1
departamento, A1, domestico, 22.4
departamento, A2, comercial, 0.2
departamento, A3,   oficina, 20.0
        casa, A4,   oficina, 2.0
    edificio, A5,   oficina, 123.0
"""

Empresa de Agua Potable 💧

Empresa de Energía Eléctrica ⚡

Empresa de Gas Natural 🔥

Empresa de Telefonía ☎

Empresa de Internet 💻

Empresa de …

Casa 🏠

Departamento 🏬

Edificio 🏢

PH 🏘

Terreno 🏜

¿Qué podemos hacer para controlar la complejidad?

bruce

ALGO (servicio, edificacion)

ALGO (servicio, edificacion)

(servicio, edificacion)

servicio cobrar: edificacion ???

...
for servicio in servicios:
  total = 0
  for edificacion in edificaciones:
    total += servicio.cobrar(edificacion)
  ....

cartas

servicio cobrar: edificacion

Electricidad Agua Gas
Casa
Departamento
Edificio
Servicio <: Ente

  cobrar: edificacion -> {

  }
Servicio <: Ente                       Edificacion <: Ente

  cobrar: edificacion -> {                                    
                                                                     
  }                                                          
Servicio <: Ente                       Edificacion <: Ente

  cobrar: edificacion -> {               consumo: servicio -> {

  }                                      }
Servicio <: Ente                       Edificacion <: Ente

  cobrar: edificacion -> {               consumo: servicio -> {
    edificacion consumo: yo                0.0
  }                                      }
Servicio <: Ente                       Edificacion <: Ente

  cobrar: edificacion -> {               consumo: servicio -> {
    edificacion consumo: yo                0.0
  }                                      }                
Agua <: Servicio                       Casa <: Edificacion 

  cobrar: edificacion -> {               consumoDeAgua: servicio -> {
    edificacion consumoDeAgua: yo
  }                                      }
Servicio <: Ente                       Edificacion <: Ente

  cobrar: edificacion -> {               consumo: servicio -> {
    edificacion consumo: yo                0.0
  }                                      }                
Agua <: Servicio                       Casa <: Edificacion 

  cobrar: edificacion -> {               consumoDeAgua: servicio -> {
    edificacion consumoDeAgua: yo
  }                                      }
                                         consumoDeGas: servicio -> {
Gas <: Servicio
                                         }
  cobrar: edificacion -> {
    edificacion consumoDeGas: yo
  }
Servicio <: Ente                       Edificacion <: Ente

  cobrar: edificacion -> {               consumo: servicio -> {
    edificacion consumo: yo                0.0
  }                                      }
  montoParaCasa: ... -> {...}
Agua <: Servicio                       Casa <: Edificacion 

  cobrar: edificacion -> {               consumoDeAgua: servicio -> {
    edificacion consumoDeAgua: yo          servicio montoParaCasa: ...
  }                                      }
                                         consumoDeGas: servicio -> {
Gas <: Servicio                            servicio montoParaCasa: ...
                                         }
  cobrar: edificacion -> {
    edificacion consumoDeGas: yo
  }

servicios.py

edificacion.py

test.py

debug

Para pensar:
  • ¿Qué código hay que modificar para agregar una nueva edificación?
  • ¿Qué código hay que modificar para agregar un nuevo servicio?
  • ¿Qué código hay que modificar para eliminar una edificación?
  • ¿Qué código hay que modificar para eliminar un servicio?
Ejercicio 💸
edificacion monto: servicio

Programar (casi) sin condicionales

Tabla: Empresa de Energía Eléctrica ⚡

"""
 Edificacion, Id,      Tipo, Consumo
        casa, A0, domestico, 6.1
departamento, A1, domestico, 22.4
departamento, A2, comercial, 0.2
departamento, A3,   oficina, 20.0
        casa, A4,   oficina, 2.0
    edificio, A5,   oficina, 123.0
"""
edificaciones = [
Casa(watts=6.1,tipo=Domestico()), 
Departamento(watts=6.1,tipo=Domestico()), 
Departamento(watts=6.1,tipo=Comercial()), 
Departamento(watts=6.1,tipo=Oficina()), 
Casa(watts=6.1,tipo=Oficina()), 
Edificio(watts=6.1,tipo=Oficina()), 
]
linea = "departamento, A1, domestico, 22.4"
fila = linea.split(",")
valores = [ e.strip() for e in fila ]
ed, id_, tipo, consumo = valores

pan

mapa_edificaciones = {
  "casa": Casa,
  "departamento": Departamento,
  "edificio": Edificio,
}

def obtener_edificacion(ed, id_, tipo, consumo, servicio):
  if tipo == 'oficina':
    t = Oficina()
  elif: tipo == 'domestico':
    t = Domestico()
  else:
    t = Comercial()
  
  c =  float(consumo)

  tipo_consumo = servicio.tipo_consumo()
  args = {"tipo":t, tipo_consumo:c}

  return mapa_edificaciones[ed](**args)

clips

Las Factories son el lugar a donde los "IF"s van a morir. Sandi Metz

Dogdge if statements

  1. Localidad (Locality)
  2. Borrabilidad (Deletability)
  3. Codigo muerto (Dead code analysis)
  4. Testing
  5. Eficiencia (Efficiency)

A computer is like a violin. You can imagine a novice trying first a phonograph and then a violin. The latter, he says, sounds terrible. That is the argument we have heard from our humanists and most of our computer scientists.

Computer programs are good, they say, for particular purposes, but they aren’t flexible. Neither is a violin, or a typewriter, until you learn how to use it.

Marvin Minsky, “Why Programming Is a Good Medium for Expressing Poorly-Understood and Sloppily-Formulated Ideas” in Design and Planning, (1967)

Gracias

trump

Repositorio con ejemplos de código sin condicionales

panela

  • Metricas

radon

metricas_de_codigo

Para aprender más cosas de este estilo

Smalltalk, Objects and Design