jueves, 3 de agosto de 2017

¿Qué tipo de triángulo es?

Existen conceptos que captamos mejor cuando los ejemplificamos. Hay un ejercicio que considero es lo suficientemente sencillo para que un principiante lo razone pero no tan simple como para que sienta su intelecto mancillado: determinar el tipo de triángulo. Partimos de la suposición de que contamos con la información de la longitud de los tres lados del mismo y queremos determinar qué tipo de triángulo es: isósceles, escaleno o equilátero. Dejaremos de lado la comprobación de que realmente se trata de un triángulo y utilizaremos datos enteros. Después de todo es un ejercicio para principiantes.

Supongamos que en tres direcciones de memoria contamos con las longitudes de los lados y que se trata de números enteros positivos de 8 bits. Las longitudes negativas en complemento a la base las dejamos para alguna tarde de lluvia y alcohol. Ubiquemos las longitudes desde la dirección de memoria 0000 y reservemos también un byte para indicar el tipo de triángulo. 

      ORG 0000    // el cero es cero en hexa y en decimal
lado1 RMB 1
lado2 RMB 1
lado3 RMB 1
tipoT RMB 1

El tipo de triángulo lo indicaremos con un ASCII. Si es equilátero guardaremos una E en tipoT, si es isósceles una I y si es escaleno una K. 

¡IMPORTANTE! Como en tantos órdenes de la vida hay más de una manera válida de resolver el problema. Podríamos hacerlo bien, mal o a la "Max Power". Sería ideal que antes de seguir leyendo intente hacerlo por sí mismo. No importa si le toma un buen rato, haga su mejor intento. Luego puede ver la solución que aparece a continuación, que puede ser distinta a la suya sin que por eso alguna sea incorrecta. Si no logra completar la solución -recordando que hay muchos escenarios posibles- trate de lidiar con algunas de las combinaciones.

El HC11 de alguna manera nos fuerza a utilizar los acumuladores, ya que las operaciones que podemos hacer directamente contra memoria son muy pocas. Por tanto para evaluar los lados vamos a necesitar que siquiera uno de ellos esté en un registro de la CPU. Dado que estamos limitados a realizar comparaciones de dos valores (no podemos hacer lado1==lado2==lado3 o lado1==lado2 AND lado1==lado3) tendremos que realizar varias comparaciones. Tenemos dos caminos para las comparaciones: 
  • podemos cargar los dos registros acumuladores A y B y comparar entre ellos con CBA; 
  • o podemos comparar un registro contra memoria con CMPA / CMPB.
Avancemos gradualmente a la solución. Empecemos por comparar dos lados y saltar si no son iguales, quedaría así:

        ORG     $C000
        LDAA    lado1
        CMPA    lado2
        BNE     salto1  // salta si no son iguales


La instrucción que siga será la que se ejecute si el salto NO se ejecuta. Si la condición se cumple y el salto se ejecuta, el flujo de programa continuará donde esté la etiqueta salto1. Esta forma de razonar los saltos trae algunas dificultades al programador de alto nivel porque básicamente es al revés de lo que solemos pensar. Aquí el "else" es lo que sigue al "if" y el lado verdadero (true o "then") es lo que irá donde ubiquemos la etiqueta. Es por ello que el salto suele ser el opuesto al que razonaríamos en alto nivel.
Luego de cada comparación tenemos un salto. Esto ocurre en el 95% de las situaciones en que usamos comparaciones, básicamente porque después de preguntar algo, tenemos que hacer algo con la respuesta.

¿Qué hacemos si los lados 1 y 2 son iguales? Sabemos que no es escaleno. Vamos a compararlo con el tercero para determinar si es isósceles o equilátero.

        ORG     $C000
        LDAA    lado1
        CMPA    lado2
        BNE     salto1

        LDAB    lado3
        CBA
        BNE     esIso

Hemos comparado el lado 1 (en el acumulador A) con el lado 3 (en el acumulador B). Si son iguales se ejecutará la instrucción que siga... ya sabemos que es equilátero.
Aunque podríamos cargar directamente el valor numérico del ASCII de la "E", vamos a dejar que el ensamblador trabaje por nosotros. Con una comilla simple como prefijo le estamos indicando que lo que sigue debe interpretarse como ASCII:
LDAB #'E
Además dado que queremos guardar el ASCII de la "E" en la posición "tipoT", primero necesitamos cargar el ascii en un acumulador y luego guardarlo con STAA. ¿Por qué no lo guardamos directamente en memoria? 
Respuesta corta: porque con el HC11 no se puede. 
Respuesta larga: el HC11 no admite instrucciones con dos referencias a memoria. Necesitamos que uno de los operandos esté en registro. Así que cargamos el ASCII de la E en el acumulador B (podríamos tranquilamente usar A, pero bueno, para que no se ponga celoso....) y luego lo guardamos en memoria.
Pasemos esto a código:

        ORG     $C000
        LDAA    lado1
        CMPA    lado2
        BNE     salto1

        LDAB    lado3
        CBA
        BNE     esIso
        LDAA    #'E
        STAA    tipoT

Si son distintos se ejecutará el salto "esIso" porque podemos afirmar que es isósceles. Tenemos entonces dos saltos para desarrollar: salto1 y esIso. El segundo es el más fácil, así que lo podemos agregar:


        ORG     $C000

        LDAA    lado1
        CMPA    lado2
        BNE     salto1

        LDAB    lado3
        CBA
        BNE     esIso
        LDAA    #'E
        STAA    tipoT    <- punto 1


esIso   LDAA    #'I
        STAA    tipoT    <- punto 2

¿Qué ocurre si dejamos eso como está? Además de que falta resolver un salto, obviamente.
Recordemos que la ejecución se da en forma secuencial. Luego de que la CPU ejecute la instrucción "STAA tipoT" del punto 1, continuará con la instrucción "LDAA #'I" y el siguiente "STAA tipoT" del punto 2. ¿Por qué? Respuesta corta: porque la CPU continuamente repite el ciclo de instrucción. Respuesta larga: porque si queremos que se altere el flujo de ejecución, debemos hacerlo con instrucciones que impacten en el contador de programa. Una etiqueta no tiene ese efecto. ¡Es solo una etiqueta! Si queremos que luego del punto 1 el programa continúe su ejecución en otra instrucción, debemos agregar un salto. Dado que deseamos que ese salto se ejecute siempre, será un salto incondicional. Veamos cómo queda:


        ORG     $C000

        LDAA    lado1
        CMPA    lado2
        BNE     salto1

        LDAB    lado3
        CBA
        BNE     esIso
        LDAA    #'E
        STAA    tipoT    <- punto 1

        BRA     fin     

esIso   LDAA    #'I
        STAA    tipoT    <- punto 2

Note que luego de ejecutar la instucción del punto 1 el flujo del programa se ve alterado por el branch always.
Aun tenemos que resolver el "salto1". Dicho salto se ejecuta cuando el lado 1 (en A) y el lado 2 son distintos. En ese punto solo podemos decir que el triángulo no es equilátero. Vamos a cargar el lado 3 en el acumulador B y comparar entonces lado 1 con lado 3 y lado 2 con lado 3. Si hallamos que hay alguna igualdad, entonces es isósceles (observar que la carga de lado3 en el acumulador B se produce justo después del salto).

        ORG     $C000

        LDAA    lado1
        CMPA    lado2
        BNE     salto1

        LDAB    lado3
        CBA
        BNE     esIso
        LDAA    #'E
        STAA    tipoT

        BRA     fin     

esIso   LDAA    #'I
        STAA    tipoT
        BRA     fin   <- agrego un salto por lo expuesto antes
salto1  LDAB    lado3
        CMPB    lado2
        BEQ     esIso // salta si lado 3 y lado 2 son iguales
        CBA
        BEQ     esIso // salta si lado 1 y lado 3 son iguales
        LDAA    #'K   // si no salto hasta aca...escaleno
        STAA    tipoT
fin     BRA     fin

Con esto agregamos las comparaciones que faltaban. El BRA del final lo usamos para darle un cierre elegante al programa, pero no cumple ninguna función más que gastar ciclos. Se puede hacer más prolijo: notar que se repite el STAA tipoT en más de un lugar. Eso es justo lo último que hace el programa, así que cambiaremos los saltos a fin por saltos a una nueva etiqueta para que guarde con una misma instrucción:

        ORG     $C000

        LDAA    lado1
        CMPA    lado2
        BNE     salto1  // salta si lado 1 y lado 2 son distintos

        LDAB    lado3   // si son iguales compara con lado 3
        CBA
        BNE     esIso   // salta si lado 2 y lado 3 son distintos
        LDAA    #'E     // si no saltó es porque es equilátero
        BRA     guarda     

esIso   LDAA    #'I
        BRA     guarda
salto1  LDAB    lado3
        CMPB    lado2
        BEQ     esIso // salta si lado 3 y lado 2 son iguales
        CBA
        BEQ     esIso // salta si lado 1 y lado 3 son iguales
        LDAA    #'K   // si no salto hasta aca...escaleno
guarda  STAA    tipoT
fin     BRA     fin


La programación en bajo nivel no tiene por qué ser "estructurada", pero si nos esforzamos un poco podemos dejar un solo punto de finalización para que se vea más claro. 

¿Se puede optimizar más? Seguramente. Estamos ejecutando dos veces la instrucción "LDAB lado3". Podríamos tratar de ubicarla de forma que aparezca solo una vez. ¿Dónde le parece que quedaría bien? Tal vez justo antes del salto "BNE salto1"... ¿qué habría que verificar? Recordemos que la instrucción CMPA actualiza los flags de la palabra de estao. Luego BNE utiliza el flag Z (zero) para determinar si hay que saltar o no. Por lo tanto debiéramos constatar que LDAB no modifique el flag Z para ubicarla entre CMPA lado2 y BNE salto1. Si aun le quedan dudas, revise el set de instrucciones:

Dado que LDAB actualiza el flag Z no podemos ubicarla antes del BNE. Pero sí podríamos acomodarla antes del CMPA. Así nos queda la versión definitiva del programa:

        ORG     0000   
lado1   RMB     1
lado2   RMB     1
lado3   RMB     1
tipoT   RMB     1


ORG     $C000

        LDAA    lado1        LDAB    lado3   
        CMPA    lado2
        BNE     salto1  // salta si lado 1 y lado 2 son distintos


        CBA             // si son iguales compara con lado 3
        BNE     esIso   // salta si lado 2 y lado 3 son distintos
        LDAA    #'E     // si no saltó es porque es equilátero
        BRA     guarda     

esIso   LDAA    #'I
        BRA     guarda
salto1  CMPB    lado2
        BEQ     esIso // salta si lado 3 y lado 2 son iguales
        CBA
        BEQ     esIso // salta si lado 1 y lado 3 son iguales
        LDAA    #'K   // si no salto hasta aca...escaleno
guarda  STAA    tipoT
fin     BRA     fin



Llegó el momento de probar el programa en el simulador, pero es tema de otro post. ¿Se puede optimizar más? Tal vez, pero ya queda a criterio del lector. Acepto ideas en los comentarios!


Sugerencias: partiendo del fuente provisto realice los cambios siguientes:
  • manejar valores de lado de triángulo de 16 bits
  • acceder a los lados del triángulo como elementos de un vector

jueves, 15 de junio de 2017

[Off-topic] Consejos para armar un curriculum y para entrevistas laborales

Por cuestiones que no vienen al caso me encontré recopilando consejos y pautas para armar un curriculum vitae. En varias oportunidades me ha tocado participar en la búsqueda y selección de personal para el área de sistemas, por lo que he vivido "de los dos lados" de la entrevista. Así que agregué al material que tenía algunos consejos sobre cómo enfrentarse a una entrevista. Aunque no es el objetivo primario del blog, me pareció interesante compartirlo. Como siempre, se valoran los comentarios y opiniones.

Buena parte de lo que sigue lo preparé examinando el blog de Cisco (sitio netacad.com) y completé con lo que he visto en mi corta experiencia. Como en otros órdenes de la vida no-tecnológicos, hay mucha subjetividad en lo que sigue. Recomiendo las pautas a continuación para la búsqueda laboral en el área de tecnología. Muchas de ellas podrían replantearse si estamos postulándonos para un trabajo en otros rubros.

Consejos para preparar un CV
  • Comencemos preparando la información necesaria
    • Datos personales de contacto: teléfono, email, dirección postal, etc.
      • No es necesario incluir DNI, CUIT, CUIL. Puede darse el caso de que soliciten alguien que pueda emitir factura, en ese caso incluir el CUIT sería correcto.
      • Nota: CUIL es un identificador de seguridad social en Argentina; CUIT es un identificador tributario.
      • ¿Se trata de un puesto donde tener registro de conductor es valioso? Mencionemos la categoría para la que estamos habilitados.
    • Experiencia: lugares donde hemos trabajado, período, rol desempeñado, logros alcanzados, referencias.
      • Los trabajos por cuenta propia también pueden mencionarse
      • Mencionemos el motivo de la desvinculación de los trabajos previos, es preferible ser sincero a que parezca que lo estamos ocultando. Como en otros órdenes de la vida, hay que saber expresar "la verdad" (recordar a Lionel Hutz en el mercado inmobiliario)
    • Educación: institución educativa, título obtenido o nombre del curso, año de finalización.
      • Cuando incluimos cursos realizados indiquemos la duración (horas), ya que la educación formal demora años, pero los cursos que hagamos luego pueden durar desde unas pocas horas hasta muchos meses.
    • Habilidades
      • Puede que existan tecnologías o habilidades relevantes que hemos adquirido y no sea evidente para quien lee sobre nuestra educación.
    • Idiomas
      • Indiquemos si tenemos buen manejo a nivel oral, escrito o ambos.
      • Seamos honestos en este punto
    • Foto
      • Solo si la impresión será de calidad o si lo enviaremos en formato electrónico. 
      • Si hemos cambiado significativamente el look, actualicemos la foto.
      • Escojamos una buena foto. Asegurémonos que nos deje bien parados.
  • No escribir sobre uno mismo en tercera persona.
    • En lugar de ello usar viñetas (ítems) con verbos fuertes variados para iniciar cada línea. Algunas expresiones para incluir: colaboración, administración, creación.
  • No escribir demasiado. No es una novela.  
    • Ser claros sobre los logros alcanzados y cómo se relacionan con el trabajo para el que nos estamos postulando. Cada línea debe tener un propósito específico y resaltar una fortaleza
  • El CV se debe preparar apuntando al trabajo que queremos.
    • Un CV genérico puede volverse nuestro enemigo.  (Esto es particularmente importante con las empresas grandes, en las pequeñas tal vez no tanto)
    • Está bien tener un modelo base, pero para cada trabajo al que nos querramos postular debemos incluir/resaltar los talentos y habilidades específicos.
    • Redacte un objetivo para cada tipo de trabajo al que se postulará.
  • No brindar información de contacto de terceros.
    • No es profesional dar como contacto el teléfono de un vecino.
  • Las primeras líneas del CV deben ser la información de contacto. 
    • Asegurarnos de que estén actualizados, tanto teléfono como email.
  • No usar direcciones de correo poco profesionales
    • No nos tomarán en serio si la dirección de mail que damos es algo como elCapoDeAvellaneda@hotmail.com.
    • Si no la tenemos, crear una cuenta de formato nombreApellido@algo.com o similar
  • Incluyamos LinkedIn
    • Si creamos un perfil en LinkedIn (gratuito), pongamos un enlace al mismo
    • Dependiendo de dónde vayamos a dejar el CV, un QR puede quedar muy bien.
  • La presentación
    • Verificar la ortografía
      • Un CV con faltas de ortografía grita "no me contrate"
    • El diseño debe ser uniforme, sobrio y atractivo. Si no se ve bien a primera vista, puede que vaya al final de la pila.
    • Si vamos a enviar el CV por correo electrónico, usemos formato PDF
      • Nos permite asegurar la visualización correcta sin importar el software con que se abra.
    • No usemos tipografías extrañas.
    • Si lo entregaremos en papel, verifiquemos la calidad de la impresión. Si es posible usemos una carpeta para entregarlo.
    • A menos que se requiera explícitamente, no adjuntemos constancias, certificados, etc. 
    • Dos páginas debieran ser suficientes para un CV. 
      • Si es más largo puede que debamos resumir o quitar información antigua
    • El orden es fundamental
      • Información personal, objetivo, experiencia laboral, educación. 
      • Puede que debamos alterar el orden si tenemos más educación que experiencia para el puesto en cuestión.
    • La experiencia laboral y educación se ordenan de más reciente a más antiguo
  • Objetivo
    • En un máximo de dos o tres frases escribamos lo que le diríamos al empleador para convencerlo de que somos su mejor opción. 
    • El mensaje es: quiero trabajar para ustedes, soy su mejor opción.
    • Cuanto más grande la empresa y/o menos experiencia tengamos, más importante este punto.
  • Habilidades
    • Especialmente si no tenemos mucha experiencia o educación para incluir debemos redactar bien esta sección. 
    • Una lista larga puede dar el mensaje incorrecto, es preferible indicar pocas habilidades y explicar por qué somos excelentes en ellas.
    • Decir que somos expertos (por ejemplo) en facebook o youtube puede ser pésima idea si el puesto para el que nos estamos postulando no requiere usar esos servicios como herramienta.
    • Si el puesto al que nos postulamos requiere habilidades básicas implícitas no las incluyamos (por ejemplo, si es "Soporte técnico" se sobreentiende que sabemos usar correo electrónico)
  • Educación
    • Incluyamos los títulos obtenidos y el establecimiento y año en que completamos esa educación. Si está incompleto, debe aclararse.
    • Los cursos o capacitación adicionales deben incluirse si tendrán relevancia para el puesto para el que estamos postulándonos.
    • Mencionar la cantidad de horas de los cursos o jornadas permite justipreciar su importancia.
  • Intereses personales y trabajo voluntario
    • A menos que nuestros intereses personales o hobbies tengan relación con el puesto que deseamos puede que sea mejor idea dejarlos en LinkedIn.
  • Incluir una mención breve puede ayudar a que nos conozcan mejor.
    • No incluir atributos personales
    • Nuestra raza, religión, peso, altura normalmente no tienen lugar en el CV.
    • Recordemos que el empleador estaría discriminando si nos elige en base a alguno de ellos, por lo tanto directamente no le permitamos esa tentación.
      • Hay excepciones, como aquellos trabajos en que se requiere un atributo particular.
  • ¡No mentir!
    • Nadie quiere contratar mentirosos
  • ¿Video curriculum?
    • Dependiendo del puesto que estemos buscando puede que un breve video donde nos presentamos y contemos algo de nosotros logra un buen impacto. 
    • Personalmente considero que el video CV es más un "video carta de presentación".
    • En algunos ámbitos puede ser una excelente idea, ¡en otros no tanto!
    • Siempre cuidemos la calidad del video, del sonido, cómo nos vemos y qué se muestra de fondo. 
    • Acá tienen un modelo (?) (les debo los subtítulos). Gracias Francisco!
  • Las redes sociales son un arma de doble filo
    • Los empleadores acostumbran cada vez más buscar a los candidatos en Facebook u otras redes. Seamos cautos en cuanto a qué compartimos en las redes, preguntémonos ¿realmente quiero que un potencial empleador vea esto?

Consejos para una entrevista exitosa

  • Prepárese bien
    • Investigue a la empresa: conozca a qué se dedica, cuánto tiempo lleva en el rubro, etc. LinkeIn puede ser una fuente interesante de información.
    • Póngase en los zapatos del empleador. 
    • ¿Qué querrá saber el potencial empleador de mí? ¿Qué habilidades se necesitan para el puesto? ¿Cómo pueden asegurarse de que soy la persona indicada?
    • ¿Qué movimientos hay en el mercado? ¿Tengo las habilidades que se requieren para mi puesto? ¿Cuáles son mis fortalezas para el mismo?
    • ¿Qué responderé cuando me pregunten por qué dejé algún trabajo previo?
    • Investigue la remuneración para su puesto y experiencia. 
      • Una cifra demasiado baja habla peor de usted que una demasiado alta.
  • Comuníquese bien
    • Asegúrese de hablar claro y a buen volumen. No balbucee. 
      • Es preferible tomarse unos instantes para ordenar las ideas y luego expresarse con propiedad.
    • Ensaye con un amigo o familiar: prepárese para contestar conciso y al grano las preguntas que podrían hacerle
    • Acostumbre mirar a los ojos y sonreír. 
    • Cuide los movimientos de las manos.
    • Haga las preguntas que considere pertinentes
      • Usualmente la remuneración y las vacaciones no son tema que deba sacar el entrevistado. Muchas veces la primera entrevista es un filtro, y recién se aborda el asunto salarial posteriormente.
      • ¿Trabajan en horarios fijos? ¿Los feriados? ¿Hay cambios periódicos en los lugares de trabajo? ¿Qué responsabilidad tendrá? ¿Cómo se hizo disponible el puesto (quien estaba renunció o lo despidieron, fue ascendido)? ¿Cuándo tomarán una decisión sobre la vacante a cubrir? En caso de ser seleccionado, ¿en qué fecha comenzaría a trabajar?
  • Sea positivo.
    • Hablar negativamente de otros no le hará un candidato atractivo.
  • Sea cortés
    • Luego de la entrevista puede enviar un email agradeciendo a su entrevistador el tiempo dispensado y expresando interés en la compañía.
      • No es necesario explayarse mucho.
    • Sonría. Sea amable con cualquier persona que se cruce al ingresar al lugar. Nunca se sabe con quién se va a cruzar.
  • Lleve alguna copia de su CV
    • Si la entrevista la realizan varias personas en simultáneo es apropiado entregar copias a quienes puedan no tenerlo.
  • Si aplica, tenga a mano copias de trabajos que pueda presentar.
  • Tenga algo para tomar notas a mano en caso de que vea apropiado hacerlo.
  • Cuide su apariencia
    • Vístase para impresionar. Su ropa y peinado deben ser nítidos. La primera impresión es MUY importante. Si consigue el puesto luego podrá vestirse como el resto.
    • No se perfume demasiado (o para nada). No es una cita.
  • Relájese
    • Llegue temprano, asegúrese de ser puntual (si lo citaron 9:00 trate de llegar con tiempo de antelación pero preséntese a las 8:58).
    • Descanse bien la noche anterior. 
    • Cuide lo que come (el aliento a ajo es mala idea).
  • Evite estos terribles errores:
    • Mostrarse desinteresado
    • Dar una apariencia arrogante
    • Vestir inapropiadamente
    • Hablar negativamente de empleos anteriores.
    • Masticar chicle
    • No dar ejemplos específicos
    • Contestar llamados o mensajes durante la entrevista
    • Dar demasiada información personal
    • No hacer contacto visual
    • Mala postura
    • Acomodarse demasiado en el asiento
    • Jugar con algo en la mesa
    • Cruzar los brazos sobre el pecho
    • Dar un apretón de manos demasiado flojo
    • Jugar con su pelo o tocarse la cara
    • Usar demasiados ademanes (o ninguno)
    • No se incomode si las preguntas que le hacen suenan repetitivas, en ocasiones el entrevistador tiene un bosquejo estructurado a seguir. Otras veces querrá corroborar que somos honestos.
    • No se moleste por las notas que toma el entrevistador
      • Particularmente si hay un panel de entrevistadores esto es habitual
Espero les sirvan las pautas. ¡Se aceptan más ideas y experiencias en los comentarios!