Primer on Dependency Injection

In a system constructed in a object oriented fashion, we usually have two types of objects: Data objects, where stores the data and Service objects, which manipulates the data. For example, if it is a database backed application it usually has some object that talks to the database, which is the Service object.

Say, we have 3 service objects

class ServiceA(object):
    def do_work():
        pass

class ServiceB(object):
    def do_work():
        pass

class ServiceC(object):
    def do_work():
        pass

Now say, that ServiceB need to use ServiceA, it need to get to ServiceA somehow. One of the antipatterns people used to use is to make ServiceA a singleton, then you have something like this:

class ServiceA(object):
    def do_work():
        pass

    @classmethod
    def get_instance(cls):
        # blah blah

class ServiceB(object):
    def do_work():
        ServiceA.get_instance().do_work()

class ServiceC(object):
    def do_work():
        pass

Dependency Injection basically says, don’t do that shit!! Using singleton making testing of ServiceB a pain, and makes it impossible to let ServiceB work with another service similar to A. If ServiceB needs ServiceA, it should ask it in the constructor, like this:

class ServiceA(object):
    def do_work(self):
        pass

    @classmethod
    def get_instance(cls):
        # blah blah

class ServiceB(object):
    def __init__(self, service_a):
        self.service_a = service_a

    def do_work(self):
        self.service_a.do_work()

class ServiceC(object):
    def do_work(self):
        pass

This (pretty long) Google talk explains this idea very well.

Sometimes the term Dependency Injection is sometimes refers a dependency injection framework, like Spring and Guice for Java, all that those framework does it to save you from typing out the constructors of the services. Here we will only talk it as the idea of asking dependencies explicitly, usually in constructors.

Dependency injection in web frameworks

Usually we instantiate service objects in the program’s entry point, like the main function. However, most web frameworks there is no such entry point.

Here is a extremely simple wsgi app written with bottle.

import bottle
app = Bottle()
@app.get('/')
def index():
    return 'hello world'

if __name__ == '__main__':
    bottle.run(app)

Now, index needs to use ServiceA, ServiceB, and ServiceC. Where do you put them? Usual approaches are using globals, annotations or closures.

As globals

import bottle
app = Bottle()

a = ServiceA()
b = ServiceB(service_a=a)
c = ServiceC(b, a)

@app.get('/')
def index():
    # do stuff with a,b,c
    return 'hello world'

if __name__ == '__main__':
    bottle.run(app)

Note that here a, b, c are effectively singletons, but that does not violate principles of dependency injection because inside of ServiceB does not read ServiceA from the global, but from its member variable. That makes us free to pass in a different object for ServiceA when needed.

The advantage of thise approach is the simplicity. We can also move all the instantiation to a config.py file and every other files just import the services it needs. However, now index is really hard to test. We cannot test it independently of ServiceA, ServiceB and ServiceC, and cannot mock those services out without monkey patching. We can sort of mitigate that by move most of the functionality inside some service and let the url handler just forward the call, and leave those handlers untested.

Decorators

import bottle
app = Bottle()

a = ServiceA()
b = ServiceB(service_a=a)
c = ServiceC(b, a)

@app.get('/')
@uses_service(a,b,c)
def index(a, b, c):
    # do stuff with a,b,c
    return 'hello world'

if __name__ == '__main__':
    bottle.run(app)

We can write a custom decorator to pass the dependent service as parameters to the needed function. This makes it look little nicer, and gives the impression that index function is not reading globals anymore. However, we cannot directly call index with custom a, b and c as the decorator call replaces the old function with a wrapped one. So it’s really the same.

Of course we can test the unwrapped version by not using decorator syntax, like this

def index(a, b, c):
    # do stuff with a,b,c
    return 'hello world'
app.get('/')(uses_service(a,b,c)(index))

but this is plain ugly. Also, doing this for every url handler could be a pain!

Using closures

import bottle

def make_wgsi_app(a, b ,c)
  app = Bottle()

  @app.get('/')
  @uses_service(a,b,c)
  def index(a, b, c):
      # do stuff with a,b,c
      return 'hello world'
  return app

if __name__ == '__main__':
    a = ServiceA()
    b = ServiceB(service_a=a)
    c = ServiceC(b, a)
    bottle.run(make_wgsi_app(a, b, c))

This is my favorite. It effectively put the service instantiation in the point of entry, and allows testing the wgsi app passing mocked out versions of service a b or c. Though, because make_wsgi_app returns a wsgi app instead of a function object, we need to test index through it, webtest package is a great tool to accomplish that.

Using this method, you can pass dependencies to a group of url handlers with similar dependencies as well.

ML;NL(TL;DR) El truco es usar LaTex in HTML. (Sigue leyendo si no sabes de que hablo).

Aqui les traigo un truco para escribir matemáticas con formulas cheveres como esto: $$ \sum_{n=0}^{\infty} \int_1^{10} \frac{x^2+1}{\sin x}dx $$ o esto: $$ \frac{x_1 + x_2 + … + x_n}{n} \geq \sqrt[n]{x_1x_2…x_n}$$

Los unicos que necesitas para poder hacer esto son

  • Un navegador de web decente, i.e. Chrome o Firefox.
  • Estar en internet.
  • Un editor de texto.

Primer paso, abre tu editor de texto favorito. Ojo, no es Word, no es Word, Word no es un editor de texto!! Si usas Word no funca! Si no tienes un editor de texto usas Notepad por momento y consíguete uno mas decente después. (Recomiendo Atom o Sublime Text).

y copias los siguientes:

<html>
<body>
Habla loco!!
</body>
</html>

Guardas en un archivo llamado hola.html, ahi el icono debe aparecer el icono de tu browser, y cuando lo abres, abrirá en tu browser verias “Habla loco!!” ahi.. De hecho, cualquier cosa que escribes dentro del <body></body>que no tenga <> para salir iguales, y ahi es donde escribiremos las fórmulas. Ojo si estas en Windows puede ser que Notepad asume que estas guardando con extensión .txt y te guarda hola.html.txt en vez de hola.html, si te hace eso no va a funcionar, tienes que guardar como .html.

Bueno, luego para poner fórmulas, primero copias y pegas lo siguiente justamente arriba de <body>

<head>
<script type="text/javascript"
  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
</head>

Esto permita que insertara comandos para tipear formulas llamado LaTex (no menciones condones please, ya no es chistoso después de 10 mil veces). Los comandos de LaTex es super intuitivo, los principales son: \frac{arriba}{abajo} hace una fracción, _ para poner subscripts, ^ para poner exponente, \sum para el simbolo de sumas. Con esos ya pueden hacer fórmulas más o menos complicados. Si necesitas más símbolos, mire en la pagina de Art of Problem Solving. Al final, tienes que poner tu formula entre simbolos \( \) para fórmulas dentro de una linea, o \[ \] para formulas en una linea aparte cada lado. Por ejemplo, esto:

<html>
<head>
<script type="text/javascript"
  src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
</head>
<body>
Aqui viene la formula tuca:
\(  \frac{x_1 + x_2 + ... + x_n}{n} \geq \sqrt[n]{x_1x_2...x_n} \)

Y aqui una mas tuca:
\[ \sum_{n=0}^{\infty} \int_1^{10} \frac{x^2+1}{\sin x}dx \]

</body>
</html>

produce esto cuando lo abres en el browser:

Aqui viene la formula tuca: \( \frac{x_1 + x_2 + … + x_n}{n} \geq \sqrt[n]{x_1x_2…x_n} \)

Y aqui una mas tuca: \[ \sum_{n=0}^{\infty} \int_1^{10} \frac{x^2+1}{\sin x}dx \]

Esto es, de hecho, la forma típica para meter fórmulas en las páginas de web, pero nada nos para para usarlo en el escritorio. Y después si es que quieres instalar LaTex ya en serio, pueden seguir las instruciones aqui: https://www.artofproblemsolving.com/wiki/index.php?title=LaTeX:Downloads.

Hace mucho mucho tiempo, en un lugar muy muy lejano, habia un pueblo aislado de los otros pueblos. El pueblo hay \( n \) hombres y \( n \) mujeres solteros en edad de casarse. Y el matrimonio es algo muy importante para la estabilidad de la sociedad del pueblo, la gente pregunta, ¿ hay como casarse a los chicos, para que sea un matrimonio estable, es decir, que no haya el caso de que un marido de una, y una mujer de otro, prefieren escapar y estar juntos?

Formalmente, asumimos que cada hombre tiene una lista secreta que ordenó a las mujeres en orden de su perferencia, y asi mismos, cada mujer orden&oacute a los hombres en su perferencia. El orden de cada persona puede ser distinta, ya que cada persona tiene su individualidad, como en la vida real. Y asumimos que todos terminan casados al final (no tanto como la vida real, ouch). Lo que la gente no quiere que pase, es que haya 2 parejas, digamos (Goku, Chi-Chi) y (Vegeta, Bulma) donde Goku prefiere a Bulma mas que su esposa Chi-Chi y Bulma prefiere a Goku mas que su esposo Vegeta .

La buena noticia es que, en 1962, dos matemáticos demostraron que, dado que el número de hombres y mujeres son iguales, siempre hay como hacer que todos los matrimonios estable. Y de hecho, ellos formularon un algoritmo de aparear a la gente, para llegar a una formulación estable.

Y el algorithmo es va más o menos así:

  1. todos los hombres va y declara a la mas preferida de su lista, en orden.
  2. Si su preferida es soltera, lo acepta y ellos se amarra.
  3. Si su preferida no es soltera, y ella prefiere a su pelado actual, (o, su pelado actual esta mas arriba en la lista), no lo para bola.
  4. O sino, si ella prefiere mas el nuevo, entonces corta con su pelado actual y amarra con el nuevo.
  5. y el rechazado regrese y mira la siguiente de su lista y sigue.

El chiste es que ese proceso eventualmente termina, y todos estan amarrados con alguien. De ahi despues de un año o dos de noviazgo terminan casando, y ahí tienen tus matrimonios estables.

Y porque carajo eso funca? Bueno la intuicion es lo siguiente: primero se nota que, aunque los hombres amarra y despues puede ser abandonados, las mujeres nunca vuelve soltera una vez amarrada. Es decir el numero de solteras disnumiye estrictamente. Entonces el proceso tiene que terminar. Cuando el proceso termina, si hubiera 2 parejas, digamos (Goku, Chi-Chi) y (Vegeta, Bulma) , entonces, como Goku prefiere a Bulma , entonces significa que Goku declaró antes que su esposa actual. Y como Bulma esta con otra persona Vegeta, significa que Bulma rechazó a Goku. Entonces no puede preferir a Goku más que Vegeta.

Bueno, una vez sabiendo como obtener estabilidad social del pueblo, otra pregunta que podemos hacer es, el proceso descrito conviene más a los hombres o a las mujeres?

Aparentemente a las mujeres mas, ya que ellas no tienen que tomar iniciativas, una vez amarrada nunca es rechazada, y si cambia de pelado es por uno mejor. Y los hombres hace todo, puede salir con corazones rotos varias veces hasta encontrar la final. Pero el resultado no es asi.

Puede que el proceso conviene a las mujeres, pero el resultado conviene a los hombres. De hecho, el apareamiento obtenido de la forma descrito arriba es llamado uun apareamiento “optimo para hombres” (male-optimal), y su definición es: “los hombres termina con la mejor mujer que quiere estar con el, y las mujeres termina con el peor hombre que ella puede aceptar” (Donde las definiciones de “mejor” y “peor” es basado en el escala de cada persona). Una forma de observar eso es ver el caso especial donde todos los hombres tienen gustos super distintos y sus mas preferidas son todas distintas. Este caso, el algoritmo termina en el primer paso, cada hombre declara su perferida y es aceptado, y ahi termina. Obteniendo el óptimo para los hombres.

Aparte de existir el apareamiento optimo para masculino, tambien hay uno que es optimo para mujeres. Y la formas de o btenerlo es sincillamente, cambiando el papel de hombre y mujeres. Entre esos 2 apareamientos estables que es optimo para algunos hombres y mujeres pero no todos de un género. No conozco algoritmos para obtenerlos aun.

En conclusion, la matématica demuestra que:

  1. Si las mujeres quieren conseguir el mejor hombre que puede conseguir, tienen que ser activas en vez de pasivas.
  2. Si estas casada, no tiene razón de estar celosa, ya que ya sabes que eres la m&aacutes preferida que le pare bola. En cambio, los hombres si deben estar cuidados.

Bueno, conclusiones anteriores estan asumiendo que la preferencia de uno nunca cambia, y que la poblacion inicial nunca cambia, que no es siempre verdad.

Este teorema es el que siempre uso cuando para mostrar que la mate es chévere. Invito a todos que sepa ingles que vea este video en youtube Ella explica mejor que yo XD.

ML;NL(TL;DR): Si has hecho páginas con plantillas de HTML, puedes usar lo mismo para XML.

Si quieres ingresar facturas emitidas al sistema de SRI, tiene 2 formas: o tipeas esos datos manualmente usando el aplicacion Java que se baja en las pajinas de SRI, o generas archivos de algun formato que ellos puede entender e importar al aplicacion antemencionado.

Entre ellos, tuve un request de generar archivos XML compartible para declarar el “Anexo Transaccional Simplificado” (ATS).

La ficha tecnica de ATS se encuentra aqui

Basicamente, se requiere un archivo en XML que se ve asi:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<iva>
  <TipoIDInformante>R</TipoIDInformante>
  <IdInformante></IdInformante> <!-- RUC -->
  <razonSocial></razonSocial> <!-- nombre de la compania -->
  <totalVentas></totalVentas>
  <!-- mas campos emitidos -->
  <compras>
    <!-- una lista de compras -->
  </compras>
  <ventas>
    <!-- Aqui viene uno de estos por cada cliente -->
    <detalleVentas>
      <idCliente>123</idCliente>
      <valorRetIva>0.00</valorRetIva>
      <valorRetRenta>0.00</valorRetRenta>
      <!-- mas campos emitidos -->
    </detalleVentas>
  </ventas>
  <ventasEstablecimiento>
    <ventaEst>
      <codEstab>001</codEstab>
      <ventasEstab></ventasEstab>
    </ventaEst>
  </ventasEstablecimiento>

  <anulados>
    <!-- Aqui viene uno de estos por cada uno de facturas anulados -->
    <detalleAnulados>
      <tipoComprobante>01</tipoComprobante>
      <autorizacion>1111897538</autorizacion>
      <!-- mas campos emitidos -->
    </detalleAnulados>
  </anulados>
</iva>

Como ya he hecho un servicio REST que retorna JSON, asumí que retornar XML en vez de JSON no es muy diferente. Que consistirán pasos como:

  1. generar objetos con datos de bases de dato
  2. convertir objetos en un dictionario (dict).
  3. Convertir dict en XML (previamente en JSON, que es sincillamente llamando a json.dumps).

Googlee “python generate xml”, y llegué a la biblioteca de lxml. Me di cuenta que tener diccionario no sirve para un carajo, y hay que generar XML desde principio.

Planee de escribir un base class que generara XML como lo hice para dict con SerializableMixin aqui, luego crear 4 clases, para ventasEstablecimiento, detalleVentas, detalleAnulados, e iva (que contiene a los demas). Pero me puse vago por unos días…

Cuando volví a ver el problema, y viendo las páginas web que estoy haciendo con HTML. Se me pegó que HTML es XML, HTML es XML!! HTML es XML!!! (repite 3 veces para las cosas importantes). Y teniendo ya años escribiendo platillas que genera HTML, porque no uso lo mismo para XML!!.

Al final, escribí un plantilla de jinja2 aqui. Que es basicamente copia y pega del formato de arriba.

Lo de abajo son las preguntas de entrevistas que me preguntaron en la ronda de entrevista por teléfono con Google. Lo escribí hace par de meses para apoyar a mi mejor amiga que estaba aplicando para ser ing. de software también. Bueno dejo de hablar huevadas y aquí son la primera pregunta técnica, espero que a alguien le sirve.

###Primera pregunta Dado un arreglo de numeros de un digito, digamos [1,2,5,9], que representa el número 1259. Retorna un arreglo de numeros de un dígito de la misma forma, representando el número + 1. Es decir, si me da [1,2,5,9] debo retornar [1,2,6,0].

Lo cagado del problema presenta cuando el último dígito es 9, ya que hay que sumar 1 al dígito anterior también; y si ese tambien es 9, hay que hacer lo mismo para el dígito anterior. Y en el peor caso, si te da [9,9,9,9] debes retornar [1,0,0,0,0] necesitas aumentar el tamano del arreglo también. Eso es lo jodido.

Le pregunte si podia usar python, y me acepto. Luego escribi algo asi:

def increment_one(num_array):
    if not num_array:
        return [1]
    last_digit = num_array[-1]
    if last_digit < 9:
        num_array[-1] += 1
        return num_array
    return increment_one(num_array[:-1]) + [0]

(Nota: después que ya me dio la entrevista onsite, me di cuenta que hice una CAGADA aqui. Quizas uds ya se dieron cuenta, pero de todos modos los verán al final)

###Segunda pregunta: Dado el interface Iterator de Java:

interface Iterator {
  bool hasNext();
  Object next();
}

bool hasNext() que te diga si hay siguiente elemento, y Object next() que retorna el siguiente elemento y avanza el iterator por uno; implemente una clase de Iterator que aparte de esos 2 metodos, tenga un tercer metodo Object peek(), que retorna el elemento sin avanzar el iterator. La clase nueva acepta un Iterator en el constructor.

Es decir algo asi:

class PeekIterator implements Iterator {
    PeekIterator(Iterator i) {} 
    bool hasNext() {}
    Object next() {}
    Object peek() {} 
} 

Pensado un rato, para poder saber cual es el siguiente elemento cuando llama peek(), tenemos que llamar next() del iterator pasado. Y para no avanzar el iterator, hay que recordar ese valor de alguna forma para usarlo de nuevo cuando peek o next sea llamado. Entonces primero hay que declarar un Object para guardar esa referencia:

class PeekIterator implements Iterator {
    Iterator source;
    Object temp;
    PeekIterator(Iterator i) {
        source = i;
    } 
    bool hasNext() {
        if (temp != null) {
            return true; 
        } 
        return source.hasNext();
    }
    Object next() {
        if (temp != null) {
            Object return = temp;
            temp = null;
            return temp;
        }
        return source.next();
    }
    Object peek() {
        if (temp == null) {
            temp = source.next();
        }
        return temp;
    } 
} 

Entonces, si llama peek, veremos el siguiente elemento usando next, pero acordamos ese valor. Para la siguiente llamada de peek o next, retornamos ese valor. Si llama a next, hay que descartar el valor de peek ya que el iterator avanzo.

Todo esta bonito.

Luego el entrevistador me recordo que source.next() puede retornar null, en el caso si metes un null a una List por ejemplo. Entonces cambie al codigo para use un boolean para acordar si temp tiene un valor valido o no. (De ley me quitó puntos aquí).

###La tercera pregunta:

Dado una cadena con caracteres ‘1’, ‘0’ y ‘?’. Digamos ‘1001?1?00?’ imprima todas las combinaciones reemplazando ? por 1 o 0.

Es decir, si hay 3 ?’s, tendre que hacer 8 combinaciones replazando ? por 1 o 0. Esto se puede hacer con recursiones facilmente. Pero la forma que pense es: es como si genero numeros binarios de 0 hasta 11111 (numeros de 1 es iguales a numeros de ?), y luego replazo cada ? por el numero de digitos correspondiente.

Podia generar esos numeros usando un entero luego convirtiendo en una cadena en representacion binario, pero ese entonces me dio pereza ya que si los numeros esta representados como un arreglo de digitos es mas facil. Y puedo reusar la respuesta del pregunta 1; cambiando numero decimal a numeros binarios.

def increment_one(num_array):
    if not num_array:
        return [1]
    last_digit = num_array[-1]
    if last_digit < 1:
        num_array[-1] += 1
        return num_array
    return increment_one(num_array[:-1]) + [0]

teniendo esta funcion, el resto es sencillo:

def printallcombination(format):
    num_interrogation = count(filter(lambda s: s=='?'), format)
    start = [0] * num_interrogation
    print_format = format.replace('?', '%d')
    while True:
        print print_format % start
        start = increment_one(start)
        if len(start) > num_interrogation:
            break

(Y parece que le gustó que he reusado el código anterior. :))

(la cagada de la primera pregunta es que num_array[:-1] crea una arreglo nuevo con elementos del viejo, y es tiempo lineal con respecto al tamaño del arreglo. Entonces el tiempo de ejecución termina siendo cuadrática en el peor caso, que es bien barbacha…)