Todo empezó con un sueño. Un sueño que no era pesadilla, pero que me dejó el cuerpo pesado, como si hubiese peleado toda la noche con algo que no terminaba de verse. Soñé con ella. O con una versión de ella que mi cabeza, obstinada, se encargó de diseñar. En ese lugar irreal, hablábamos como si siempre hubiéramos estado ahí. No había ruidos de fondo, ni distancia, ni esa incomodidad que a veces arrastra la ternura. Solo estábamos nosotros. Y todo parecía posible.
Al despertar, el silencio fue violento. Abrí los ojos y su ausencia pesaba más que nunca. Me quedó un temblor en el pecho. Una duda incómoda: ¿y si nunca estuvo? Pero no era una duda cualquiera. Era una certeza disfrazada, de esas que uno no quiere mirar de frente. A veces lo que más duele no es lo que se pierde, sino lo que se cree haber tenido. O peor: lo que se esperaba que ocurriera.
Durante un tiempo, me convencí de que había algo real en todo eso. Que ella existía más allá de los mensajes, que alguna vez me había visto de verdad. Y empecé a buscarla. No afuera, sino en las señales que el recuerdo deja sin permiso. Un perfume flotando entre los libros, una foto, frases anotadas que ahora parecían hablarme solo a mí.
Pero cuando intentaba encontrarla entera, desaparecía. Era como esa partícula cuántica que cambia si la observás. Apenas la enfocaba, se deshacía. Como si supiera que no podía sostenerse bajo la luz.
Entonces, decidí experimentar. No para entenderla a ella, sino para entender qué me pasaba. Me volví el científico de mi propia obsesión. Escribía, imaginaba, reconstruía escenas en la cabeza. Como si repitiendo los pasos exactos pudiera provocar un final distinto. Pero cuanto más lo intentaba, más me hundía. Ella era pura posibilidad cuando no la miraba. Pero cuando intentaba tocarla, se volvía nada. Un reflejo que no se deja agarrar.
Y sí. Aunque nadie lo diga: el observador también llora. Lloré mucho. No por lo que fue, sino por lo que quise que fuera. Lloré por todo lo que guardé y no supe cómo dar. Por la soledad de sentir tanto y no tener dónde dejarlo. Porque solo yo, en mi cabeza, puedo sentir este amor que no se detiene. Y no sé cómo compartirlo si no es con ella. Por eso escribo. Para que no se pierda. Para que algo quede de este amor que no encontró cuerpo donde habitar.
Con el tiempo, empecé a entender. Que hay vínculos que son espejismos. Que algunas personas llegan como errores de sistema. Interferencias. Te sacuden, te desordenan el alma, y después se van sin mirar atrás. No porque quieran hacer daño, sino porque simplemente no están hechas para quedarse.
Y entendí también que yo la había idealizado. Que la había convertido en algo más grande de lo que podía ser. En un símbolo. En un experimento emocional que solo yo estaba ejecutando.
Un día, sin ninguna epifanía dramática, simplemente me rendí. Dejé de buscar señales. Dejé de escribir para acercarme. Empecé a escribir para cerrar.
Y así, como se anotan las conclusiones al final de un trabajo, con trazo firme, casi en voz baja, escribí:
No existes.
No como un insulto, no con rabia. Sino como una verdad limpia. Como un acto de cuidado. Como el cierre de un experimento solitario que me enseñó más sobre mí que sobre vos. Porque no fuiste persona. Fuiste reflejo. Fuiste posibilidad.
En este blog post vamos a hablar sobre varias herramientas de diagramación que pueden ser útiles para diferentes propósitos. Cada una de estas herramientas tiene su propia sintaxis y características únicas que las hacen útiles para diferentes tipos de diagramas.
PlantUML:
Es una herramienta para crear diagramas UML utilizando un lenguaje de marcado de texto. Puede utilizarse para crear diagramas de clases, secuencia, actividad, caso de uso, entre otros.
@startuml class Car { + int wheels + int doors + String color + drive() + park() }
class SUV { + int wheels + int doors + String color + int groundClearance + drive() + park() }
Car <|-- SUV @enduml
GraphViz:
es una herramienta de visualización de gráficos que utiliza lenguaje de descripción de gráficos DOT. Puede utilizarse para crear diagramas de flujo, diagramas de red, diagramas de árbol, entre otros.
1 2 3 4 5 6 7 8 9 10 11
digraph example { start [shape=Mdiamond,label="Inicio"] end [shape=Msquare,label="Fin"] proceso1 [shape=rectangle,label="Proceso 1"] proceso2 [shape=rectangle,label="Proceso 2"] proceso3 [shape=rectangle,label="Proceso 3"] start -> proceso1 proceso1 -> proceso2 proceso2 -> proceso3 proceso3 -> end }
Mermaid:
Es una herramienta para crear diagramas de flujo, diagramas de secuencia, diagramas de clase, entre otros. Utiliza una sintaxis de marcado de texto similar a PlantUML.
1 2 3 4 5
graph TD; A-->B; A-->C; B-->D; C-->D;
BPMN:
Es un estándar para modelar procesos de negocio utilizando un lenguaje gráfico. Puede utilizarse para crear diagramas de flujo de trabajo, diagramas de proceso, entre otros.
Es una herramienta para crear diagramas de clases, diagramas de secuencia, diagramas de flujo, entre otros. Utiliza una sintaxis de marcado de texto similar a PlantUML.
Es una herramienta para crear diagramas ASCII que pueden ser renderizados como gráficos SVG. Puede utilizarse para crear diagramas de flujo, diagramas de red, entre otros.
Es una herramienta para crear diagramas de secuencia utilizando una sintaxis de marcado de texto. Puede utilizarse para modelar interacciones entre objetos en un sistema.
Es una herramienta para crear diagramas de actividad utilizando una sintaxis de marcado de texto. Puede utilizarse para modelar procesos de negocio y flujo de trabajo.
1 2 3 4 5
actdiag { A -> B -> C; D -> E -> F; G -> H; }
RackDiag:
Es una herramienta para crear diagramas de rack y servidores utilizando una sintaxis de marcado de texto.
Es una herramienta para crear diagramas de red utilizando una sintaxis de marcado de texto. Puede utilizarse para modelar redes de computadoras y topologías de red.
1 2 3 4 5 6 7 8 9 10 11 12
[Computer] { internet : "10.0.0.1" eth0 : "192.168.0.2" }
[Server Web] { eth0 : "192.168.0.1" }
Computer -- Server Web : HTTP
PacketDiag:
Es una herramienta para crear diagramas de paquetes de red utilizando una sintaxis de marcado de texto.
Internet -> Server [label="Request"]; Server -> Internet [label="Response"]; }
C4 with PlantUML:
Es una extensión de PlantUML que permite crear diagramas de arquitectura de software utilizando la notación C4.
Erd:
Es una herramienta para crear diagramas de modelo de entidad-relación utilizando una sintaxis de marcado de texto.
1 2 3 4 5 6
digraph G { rankdir=LR; node [shape=plaintext];
"order" -> "customer"; }
Ditaa:
Es una herramienta para crear diagramas de flujo utilizando una sintaxis de marcado de texto.
1 2 3
+---------+ | Hello | +---------+
Pikchr:
Es una herramienta para crear diagramas utilizando una sintaxis de marcado de texto similar a Diagrama de flujo.
1 2 3 4 5 6 7 8 9 10 11
left box wid 3 ht 20 box wid 3 ht 20 at 5 0 arrow from last box to 2nd box arrow from last box down 10 box wid 3 ht 20 at 10 20 arrow from 2nd box down 10 box wid 3 ht 20 at 15 30 arrow from last box to 3rd box arrow from last box down 10 box wid 3 ht 20 at 20 20
UMlet
UMlet es una herramienta de diagramación de UML gratuita y de código abierto que permite crear diagramas de clases, de secuencia, de actividad y más. Es fácil de usar y permite exportar los diagramas a varios formatos, como SVG y PDF.
@startuml
class Person {
- name : String
- age : int
}
Person -> Address
@enduml
En este tutorial, aprenderás cómo construir una API web utilizando F# y Giraffe, una biblioteca de enrutamiento HTTP para .NET. Crearemos una API simple que permita leer y crear publicaciones de blog.
F# es un lenguaje de programación funcional que se ejecuta en la plataforma .NET, y puede ser utilizado para crear aplicaciones web y servicios de backend. La sintaxis simple y expresiva de F# lo hace ideal para construir aplicaciones concisas y eficientes. Giraffe, por otro lado, es una biblioteca de enrutamiento HTTP que se integra perfectamente con F#, lo que permite a los desarrolladores crear aplicaciones web de manera fácil y rápida.
En este tutorial, utilizaremos .NET 6, la última versión del marco de trabajo de .NET. .NET 6 ofrece un gran rendimiento y mejoras de productividad para los desarrolladores.
Comencemos con la creación de nuestra API web con F# y Giraffe en .NET 6.
En el archivo Blog.fs, definimos un módulo Blog que contiene la lógica del blog. Primero, definimos un tipo de datos BlogPost que representa una publicación en el blog y contiene un título y un contenido.
Luego, definimos un tipo de datos BlogDb que representa una base de datos de blog y contiene una lista mutable de publicaciones. El BlogDb tiene dos miembros, uno que devuelve todas las publicaciones existentes en la base de datos y otro que agrega una nueva publicación a la lista.
A continuación, definimos dos manejadores HTTP: getPostsHttpHandler y createPostHttpHandler. El primero se encarga de manejar solicitudes GET a la ruta /posts y devuelve todas las publicaciones de blog almacenadas en la base de datos. El segundo maneja solicitudes POST a la ruta /posts/create y agrega una nueva publicación a la base de datos.
member this.AddPost (newPost : BlogPost) = allBlogPosts <- (newPost::allBlogPosts) allBlogPosts
typeBlogServiceTree= { getBlogDb : unit -> BlogDb }
let getPostsHttpHandler (serviceTree: BlogServiceTree) = fun (next : HttpFunc) (ctx : HttpContext) -> json (serviceTree.getBlogDb().GetAllPosts()) next ctx
let createPostHttpHandler (serviceTree: BlogServiceTree) = fun (next : HttpFunc) (ctx : HttpContext) -> task { let! newPostJson = ctx.BindJsonAsync<BlogPost>() serviceTree.getBlogDb().AddPost(newPostJson) |> ignore return! json (newPostJson) next ctx }
En el archivo Program.fs, definimos el webApp, que es un árbol de rutas de Giraffe. El árbol de rutas incluye una ruta raíz que devuelve una cadena de texto y una subruta /posts que contiene dos rutas adicionales: una para obtener todas las publicaciones del blog y otra para crear una nueva publicación.
Finalmente, configuramos la aplicación y los servicios que utilizamos. En el método configureServices, agregamos la dependencia de Giraffe y en el método configureApp, configuramos la aplicación para usar Giraffe y nuestro árbol de rutas webApp.
Para ejecutar la aplicación, simplemente escribimos dotnet run en la terminal desde el directorio del proyecto.
open System open Microsoft.AspNetCore.Builder open Microsoft.AspNetCore.Hosting open Microsoft.Extensions.Hosting open Microsoft.Extensions.Logging open Microsoft.Extensions.DependencyInjection
[<EntryPoint>] let main _ = Host.CreateDefaultBuilder() .ConfigureWebHostDefaults( fun webHostBuilder -> webHostBuilder .Configure(configureApp) .ConfigureServices(configureServices) |> ignore) .Build() .Run() 0
Ejecutar
1
dotnet run
Si todo funciona correctamente, deberíamos ver un mensaje que indica que la aplicación se está ejecutando. En este punto, podemos abrir un navegador web y acceder a la dirección http://localhost:5000/posts para ver la lista de publicaciones de nuestro blog. Podemos crear una nueva publicación enviando una solicitud POST a la dirección http://localhost:5000/posts/create con el título y el contenido de la publicación en formato JSON.
Las Discriminated Unions, también conocidas como Sum Types, son un concepto importante en programación funcional y son utilizadas para modelar tipos de datos que pueden tener varios valores posibles.
Una Discriminated Union es un tipo de dato que puede contener uno de varios valores diferentes, cada uno de los cuales está etiquetado con un identificador único o discriminador.
En términos más simples, las Discriminated Unions se utilizan para definir un tipo de dato que puede tener varios valores posibles y que se pueden distinguir entre sí mediante una etiqueta o identificador único.
Por ejemplo, supongamos que estamos escribiendo una aplicación de procesamiento de pedidos en línea. Podríamos definir un tipo de dato para representar un pedido, que podría tener varios estados posibles, como “pendiente”, “en camino” o “entregado”. Utilizando Discriminated Unions, podríamos definir este tipo de dato como:
Una de las ventajas de las Discriminated Unions es que nos permiten manejar tipos de datos complejos de manera clara y concisa. Por ejemplo, podríamos definir un tipo de dato para representar una figura geométrica, que podría ser un círculo, un cuadrado o un triángulo. Utilizando Discriminated Unions, podríamos definir este tipo de dato como:
typeShape=
| Circle of float
| Square of float
| Triangle of float * float
En resumen, las Discriminated Unions son una herramienta poderosa para modelar tipos de datos complejos en programación funcional. Al permitirnos definir tipos de datos que pueden tener varios valores posibles, etiquetados con identificadores únicos, nos permiten manejar estructuras de datos complejas de manera clara y concisa.
El lenguaje Gherkin utiliza palabras clave especiales como “Feature”, “Scenario”, “Given”, “When” y “Then” para definir el comportamiento esperado de la aplicación. Cada “Scenario” describe un caso de prueba específico, y las instrucciones “Given”, “When” y “Then” indican las condiciones iniciales, la acción que se realiza y el resultado esperado, respectivamente.
Feature: Sistema de nómina El sistema de nómina permite a los empleados ver su información de pago y a los administradores de recursos humanos gestionar los pagos de los empleados.
Scenario: Ver información de pago Given estoy conectado como un empleado When accedo a mi página de información de pago Then se muestran mis datos de pago, como mi salario, impuestos y deducciones
Scenario: Gestionar pagos de empleados Given estoy conectado como un administrador de recursos humanos When accedo a la página de gestión de pagos de empleados Then puedo ver una lista de todos los empleados y sus respectivos datos de pago And puedo modificar la información de pago de cualquier empleado And puedo generar y descargar un informe de pago para cada empleado
Scenario: Generar informe de pago Given estoy conectado como un administrador de recursos humanos And he seleccionado un empleado en la página de gestión de pagos de empleados When hago clic en el botón "Generar informe de pago" Then se descarga un archivo PDF con el informe de pago del empleado seleccionado
La palabra “Jamstack” es un acrónimo que se refiere a “JavaScript, APIs y Markup”. Se trata de un enfoque para la construcción de sitios web y aplicaciones que se basa en el uso de servicios externos para el alojamiento, el procesamiento y la entrega de contenido. En lugar de utilizar un servidor web tradicional para ejecutar el código y servir contenido dinámico, Jamstack se apoya en servicios externos (conocidos como “APIs”) para manejar estas tareas.
¿Por qué elegir Jamstack? Hay varias razones por las que el enfoque Jamstack está ganando tanto terreno en el mundo del desarrollo web. En primer lugar, es increíblemente escalable. Al utilizar servicios externos para manejar tareas como el procesamiento y el alojamiento, puedes ahorrar recursos y aumentar la velocidad de tu sitio o aplicación. Esto es especialmente importante si tienes un gran tráfico o si tu sitio o aplicación necesita soportar picos de tráfico imprevistos.
Otra ventaja de Jamstack es que es extremadamente seguro. Al no tener que preocuparte por el servidor web y la ejecución de código en el lado del servidor, hay menos oportunidades para que alguien pueda atacar tu sitio o aplicación. Además, al no tener que preocuparte por el servidor, puedes enfocarte en lo que realmente importa: el contenido y la experiencia de usuario.
Por último, Jamstack es increíblemente rápido. Al utilizar servicios externos para manejar tareas como el procesamiento y el alojamiento, puedes ahorrar recursos y aumentar la velocidad de tu sitio o aplicación. Esto es especialmente importante si tienes un gran tráfico o si tu sitio o aplicación necesita soportar picos de tráfico imprevistos.
En resumen, Jamstack es un enfoque innovador para la construcción de sitios web y aplicaciones
El error aparece porque hay un byte en los archivos .pyc que se les asignan de manera unica. Si se trata de usar otro interprete sale el error. La solucion es eliminar los archivos .pyc