Algunas ideas sobre código correcto

Un contrato... Otra lectura interesante, Foundations of Correct Code donde se habla de que el código no sólo ha de pasar los tests y las pruebas, sino que estas deben tener en cuenta que el código sea correcto.

En este sentido nos recuerda los conceptos de los contratos, pre y post-condiciones y nos recuerda su historia:

You may well have heard the terms before: contract, pre-condition, post-condition. But you might not be aware of their origins.

Posteriormente, entra en la discusión entre lo que llamamos programación defensiva (si no se cumple lo que esperamos lanzamos un error antes de hacer algo que, a priori, puede ser incorrecto) o bien el diseño por contrato, basado en el principio de que si el proveedor cumple su parte, nosotros devolveremos un resultado correcto.

We have two choices here: defensive programming, and Design by Contract.

Defensive programming guards the body of a function or method, checking that the pre-condition holds and throwing an error if it doesn’t.

all of the interactions between its components must be correct. A Hoare triple describes a contract between a client and a supplier of a service (e.g., a method of a class), such that the supplier ensures that the post-condition is satisfied, and the client ensures that they never a method or function unless the pre-condition is satisfied.

A la hora de elegir, puede depende de nuestra relación con el resto de proveedores: si nosotros producimos todo el código, hay cosas que podemos (o deberíamos poder) asegurar. En otros casos, tenemos que tener cuidado con lo que hayan podido hacer otras personas.

One final thought on defensive programming vs. Design by Contract, relating to the design of the system as a whole: when it’s us writing the client code, we have control over whether the inputs are correct. When someone else is providing the inputs – e.g., a web service client, or an end user – we don’t have that control. So it’s usually necessary to code defensively at system/service boundaries.

Tampoco tiene sentido conformarse con lanzar un error cuando algo no vaya bien: normalmente el usuario puede que ni siquiera tenga la culpa y nosotros tampoco queremos molestarle.

Offering users choices that aren’t actually available and then displaying an error message when they select them not only annoys the user, but also complicates the application’s internal logic as it now has to handle more edge cases.

De esta forma, es posible que tengamos que usar ambas aproximaciones:

I’ve found the best approach to delivering correct software that’s simple in its internal logic is to design the UX carefully to simplify the inputs, do some defensive programming just below the UI to validate the inputs, and then apply Design by Contract for all the internal logic, with test-time assertion checking in case we made a boo-boo in some client code.

Concurrencia en Python

Hilos Por ahora Python no es el lenguaje de programación con mejores características de concurrencia (fundamentalmente, el intérprete no es lo que se llama `thread safe’ así que hay que imponer restricciones para que las cosas funcionen Global Interpreter Lock). Esto no significa que no haya primitivas para gestionar la concurrencia y que, en algunos casos, podamos obtener ventajas de la concurrencia.

Por eso (y porque la concurrencia es un tema que me gusta mucho) traigo aquí An Intro to Threading in Python que me pareció una buena introducción al tema, didáctica y con ejemplos, sin olvidar el tema de las condiciones de carrera.

Allí también nos recuerdan que la concurrencia es limitada:

But for most Python 3 implementations the different threads do not actually execute at the same time: they merely appear to.

Y que si queremos ir más allá tendremos que utilizar un intérprete no estándar:

Getting multiple tasks running simultaneously requires a non-standard implementation of Python, writing some of your code in a different language, or using multiprocessing which comes with some extra overhead.

No obstante, es un tema interesante para explorar y siempre podremos obtener las ventajas típicas de la concurrencia, que consisten en poder hacer avanzar algunas tareas cuando otras se quedan atascadas (en operaciones de entrada/salida, o esperando algún evento, …). En otros casos no vamos a obtener una ventaja real, pero siempre está bien utilizar este lenguaje para aprender conceptos que luego pueden utilizarse en otros.

Sobre el tamaño y el desarrollo de Windows 10

Ventanas A través de Un ingeniero de Microsoft explica cómo es Windows 10 por dentro: el código ocupa 0,5 TB y se extiende por 4 millones de ficheros llegamos a unos cuantos datos e informaciones sobre las interioridades de Windows 10 que se agradecen, porque no siempre ha sido muy fácil conocer estas cosas.

Como lenguaje de programación se utiliza fundamentalmente el C, aunque también hay código en C#, JavaScript, TypeScript, VB.NET o C++.

Sobre el tamaño, como dice el titular, estamos hablando de que

Según explica Rietschin, el árbol completo con todo el código fuente, el código de prueba y todo lo que constituye el “código fuente de Windows” tiene más de medio terabyte de tamaño, en más de 4 millones de archivos

Muy interesante y para guardar como referencia.

Actualización (2019-09-18): En Which programming language is used for making Windows 10? podíamos leer algo más de información relacionada con el tema.

La liga de la entropía y la aleatoriedad

Dados En The League of Entropy Is Making Randomness Truly Random un texto interesante sobre aleatoriedad y ordenadores, así como algunos proyectos que ofrecen números aleatorios ‘de verdad’.

Entre otros, hablan de League of Entropy que se trata de un proyecto colaborativo.

Como nos cuentan en League of Entropy: Not All Heroes Wear Capes, proporcionan números aleatorios no predecibles en intevalos regulares.

A randomness beacon is a public service that provides unpredictable random numbers at regular intervals.

Al tratarse de números que son públicos, hay usos para los que se pueden contemplar (un sorteo, por ejemplo, donde es importante la auditabilidad y la transparencia) pero no para otros (una clave, donde el secreto es importante).

Modelado de amenazas y argumentos a su favor

Mirada amenazante Cuando nos preocupa la seguridad informática tenemos que tener claro cuáles son los riesgos que nos afectan. Para ello se puede utilizar el modelado de amenazas (threat modelling) y en Three Killer Arguments for Adopting Threat Modeling nos daban argumentos a favor de estas técnicas.

Los argumentos:

Se obtiene seguridad cuantificable.

Threat Modeling Produces Measurable Security

Bien hecha, promueve el cumplimiento.

Threat Modeling Done Right Encourages Compliance

Y, finalmente, ahorra dinero.

Threat Modeling Saves You Money

Este último argumento se basa en que arreglamos problemas de seguridad en el momento en que es más barato.

Un poco de numerología (no la traduzco):

Let’s say you found 10 major problems with the architecture in those three hours. You’ve only spent $168 USD per bug to fix them. The beauty of the design phase is that there is no code to change yet.

Without the threat modeling meeting, you could find these 10 bugs in either implementation, testing, or production. What’s the cost if you did?

For the implementation phase, you’ll pay $1,008 per bug for a total of $10,080 to fix these bugs.

If found in the testing phase, you’ll pay $2,520 per bug for a total of $25,200 to fix the bugs.

If you find the bugs in production, you’ll now have to pay $16,800 per bug, for a whopping total of $168,000.

Finalmente, el modelado de amenazas -afirman- nos proporciona una fotografía en cada momento de nuestro estado, lo que nos permite tomar mejores decisiones sobre dónde invertir el dinero.

Threat modeling gives you a constant snapshot of your current security posture. This snapshot allows you to send money where it’s needed most, not based on a slideshow or product demo, but based on real data.

Interesante.