# Estructura de control: Nos permite definir el flujo del programa # if : comprobar una condición y si se cumple se ejecuta un código # y, opcionalmente, si no se cumple, se ejecuta otro edad=int(input("Dime tu edad")) if edad>=18: print("Bienvenido a la web") print("Eres bienvenido/a") print("Disfruta del contenido") else: print("Eres menor de edad") print("Introduce un codigo de autorización si quieres acceder") codigo=input("Dime el codigo") if codigo=="1234": print("Bienvenido") else: print("Código incorrecto") print("Esto está fuera del if y se ejecuta tanto si se cumple la condición como si no") # Comparaciones # >, >=, <, <= , ==, != # La igualdad se utilizan dos signos = if edad==18: print("Bienvenido a la mayoría de edad") # Para diferente exclamación e igual != if edad!=18: print("No tienes 18 años") # Recordad que vimos los operadores booleanos # and, or, not if edad>=18 and edad<=25: print("Tienes descuento de carnet joven (entre 18 y 25)") if edad<18 or edad>65: print("Tienes descuento de niño o jubilado (menor de 18 o mayor de 65") # recordad la precedencia de los operadores, el and va primero if edad<18 or edad>20 and edad<30: print("Esto se cumple si la edad es menor de 18") print("O la edad está entre 20 y 30") # Recordad que si dudamos podemos usar paréntesis, que son gratis: if edad<18 or (edad>20 and edad<30): print("Esto se cumple si la edad es menor de 18") print("O la edad está entre 20 y 30") if not edad>=18: print("Eres menor") if edad<18: print("Es lo mismo") # Mini ejercicio planteado # Vamos a hacer un if que nos de un descuento si la edad es 40 o 50
Soluciones variables
import datetime ahora = datetime.datetime.now() anio_actual=ahora.year anio_actual=2025 anio_nacimiento=int(input("Dime tu año de nacimiento")) print(f"Este año tendrás {anio_actual-anio_nacimiento} años") # Calcular el área de un triángulo base=float(input("Dime la base")) altura=float(input("Dime la altura")) area=base*altura/2 print("El área es ",area) # saber hacer esto es importante porque puede ser que queramos # almacenar el valor, no imprimirlo print("El área es "+str(area)) print(f"El área es {area}") # Pido el número numero=int(input("Dime un numero del 10 al 99")) decenas=numero//10 unidades=numero%10 suma=decenas+unidades print("La suma es ",suma) # Pido los minutos total_minutos=int(input("Dime cuantos minutos")) # calculo horas y minutos horas=total_minutos//60 minutos=total_minutos%60 # muestro print(f"{horas} horas y {minutos} minutos")
Ejemplos operadores
precio=80 personas=7 print(precio/personas) print(precio//personas) print(2**4) # Modulo % Resto de la división print(17%5) # ¿Cómo saber si un número es par o impar? # Si el módulo 2 es 0, es par # si el módulo 2 es 1, es impar print(8%2) # 0, es par print(81%2) # 1, es impar numero=9 print(numero%2) print(numero%3) giro=850 print(giro%360)
Conversiones
texto = "123" numero = int(texto) print(numero + 10) # 133 texto = "12.3" numero = float(texto) print(numero + 10) # 22.3 edad = 30 print("Tienes " + str(edad) + " años") # Tienes 30 años # Esto da un error porque son tipos diferentes # print("Tienes " + (edad) + " años") # Tienes 30 años print(bool(0)) # False print(bool(1)) # True print(bool(125)) # True print(bool("")) # False print(bool("hola")) # True
Imprimir en python
print("hola") edad=20 print(edad) print("hola",edad) print("tu edad es ",edad) # La f lo que quiere decie es 'cadena formateada' # Nos permite poner valores entre llaves print(f"Tu edad es {edad} enhorabuena") print("Tu edad es",edad,"enhorabuena") print(f"Dentro de 10 años tendrás {float(edad)+10}") # La barra (slash) se llama carácter de escape # El caracter siguiente es especial # \" es una comilla print("Se llama \"wifi\" y es un medio de conexión") # \n es un salto de línea print("Se llama \n y es un medio de conexión") # \t es un tabulador print("Se llama \ty es un medio de conexión") # \\ es un barra print("para imprimir barra \\ ") # opciones del print print("hola",edad,"pepe",14) # especifico cual quiero que sea el separador print("hola",edad,"pepe",14, sep=" -- ") # especificar el final de línea print("hola") print("juan") print("hola", end=", ") print("juan") with open("salida.txt", "w") as f: print("Esto va al archivo", file=f) print("Esto también", file=f)
Variables
# tipos enteros (int) (sin decimales) edad=40 # tipos con decimales (float). Se usa el punto para indicar decimales temperatura=20.7 # Cadenas de letras (string) nombre='Ana' apellido=("Pi i Margall") direccion="""Calle del pino 08001 Barcelona""" precio=100 preciomal="100" cp="08001" precioConIva=precio*1.21 precioConIva2=float(preciomal)*1.21 # Booleano valores de cierto/falso (bool) mayorDeEdad=True estaLogueado=False
Juegos retro pantallas LCD
Codificar Hash con SHA256 en C#
https://hdeleon.net/funcion-para-encriptar-en-sha256-en-c-net/
public class Encrypt{ public static string GetSHA256(string str) { SHA256 sha256 = SHA256Managed.Create(); ASCIIEncoding encoding = new ASCIIEncoding(); byte[] stream = null; StringBuilder sb = new StringBuilder(); stream = sha256.ComputeHash(encoding.GetBytes(str)); for (int i = 0; i < stream.Length; i++) sb.AppendFormat("{0:x2}", stream[i]); return sb.ToString(); } }
Todos los elementos HTML
Arquitectura hexagonal
Arquitectura Hexagonal (Puertos y Adaptadores)
La arquitectura hexagonal, también conocida como arquitectura de puertos y adaptadores, es un estilo de diseño de software propuesto por Alistair Cockburn. Su objetivo es aislar el núcleo de la aplicación (la lógica de negocio) del mundo exterior (interfaces de usuario, bases de datos, APIs externas, etc.), creando un diseño más modular, escalable y fácil de probar.
Conceptos clave
- Core de la aplicación (Dominios):
- Es el núcleo que contiene la lógica de negocio, los casos de uso y las reglas de la aplicación.
- Es completamente independiente de cualquier tecnología o infraestructura externa.
- Puertos:
- Interfaces que definen cómo interactuar con el núcleo de la aplicación.
- Hay dos tipos:
- Puertos de entrada: Permiten interactuar con la aplicación desde el exterior (e.g., controladores de una API o eventos).
- Puertos de salida: Permiten que la aplicación interactúe con servicios externos (e.g., base de datos, APIs de terceros).
- Adaptadores:
- Implementaciones concretas de los puertos. Son responsables de conectar el núcleo con el mundo exterior.
- Adaptadores de entrada: Transforman las solicitudes externas (API, CLI, UI) en comandos comprensibles para el núcleo.
- Adaptadores de salida: Implementan las interacciones con servicios externos (e.g., repositorios de datos, APIs externas).
- Implementaciones concretas de los puertos. Son responsables de conectar el núcleo con el mundo exterior.
- Separación de preocupaciones:
- Los adaptadores y la infraestructura están separados del núcleo. Esto permite cambiar tecnologías o interfaces externas sin afectar la lógica de negocio.
Beneficios de la arquitectura hexagonal
- Independencia tecnológica:
- Puedes cambiar tecnologías (base de datos, frameworks) sin modificar el núcleo.
- Facilidad de pruebas:
- El núcleo puede ser probado de forma aislada con simulaciones o stubs.
- Escalabilidad:
- Es fácil añadir nuevos adaptadores o integrar nuevos sistemas externos.
- Mantenimiento:
- Reduce la complejidad al desacoplar la lógica de negocio de las dependencias externas.
Ejemplo práctico
Imaginemos un sistema para gestionar órdenes de compra. Implementaremos:
- Backend (C#): Con un núcleo que maneja órdenes y un adaptador para la base de datos.
- Frontend (React): Como adaptador de entrada para interactuar con el usuario.
Backend con C# (Puertos y Adaptadores)
Estructura del proyecto
/Core
- IOrderService.cs (Puerto de entrada)
- IOrderRepository.cs (Puerto de salida)
- OrderService.cs (Implementación del servicio)
- Models/
- Order.cs
/Infrastructure
- DatabaseOrderRepository.cs (Adaptador de salida)
/API
- OrderController.cs (Adaptador de entrada)
Código
- Core: Definición de puertos
- Puerto de entrada (IOrderService):
public interface IOrderService { void CreateOrder(Order order); Order GetOrderById(Guid orderId); }
- Puerto de salida (IOrderRepository):
public interface IOrderRepository { void Add(Order order); Order FindById(Guid orderId); }
- Core: Lógica de negocio
- Modelo de Orden:
public class Order { public Guid Id { get; set; } public string ProductName { get; set; } public int Quantity { get; set; } public decimal Price { get; set; } }
- Implementación del servicio:
public class OrderService : IOrderService { private readonly IOrderRepository _orderRepository; public OrderService(IOrderRepository orderRepository) { _orderRepository = orderRepository; } public void CreateOrder(Order order) { // Validaciones de negocio if (order.Quantity <= 0) throw new ArgumentException("La cantidad debe ser mayor a cero."); _orderRepository.Add(order); } public Order GetOrderById(Guid orderId) { return _orderRepository.FindById(orderId); } }
- Infraestructura: Adaptador de salida
- Adaptador para la base de datos:
public class DatabaseOrderRepository : IOrderRepository { private readonly List<Order> _orders = new List<Order>(); public void Add(Order order) { _orders.Add(order); } public Order FindById(Guid orderId) { return _orders.FirstOrDefault(o => o.Id == orderId); } }
- API: Adaptador de entrada
- Controlador:
[ApiController] [Route("api/orders")] public class OrderController : ControllerBase { private readonly IOrderService _orderService; public OrderController(IOrderService orderService) { _orderService = orderService; } [HttpPost] public IActionResult CreateOrder([FromBody] Order order) { _orderService.CreateOrder(order); return Ok("Orden creada con éxito."); } [HttpGet("{id}")] public IActionResult GetOrderById(Guid id) { var order = _orderService.GetOrderById(id); return order != null ? Ok(order) : NotFound(); } }
Frontend con React (Adaptador de entrada)
Estructura del proyecto
/components
- OrderForm.jsx
- OrderList.jsx
/services
- api.js
Código
- Servicio para interactuar con el backend (
api.js
):const BASE_URL = "http://localhost:5000/api/orders"; export const createOrder = async (order) => { const response = await fetch(`${BASE_URL}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(order), }); return response.json(); }; export const getOrderById = async (id) => { const response = await fetch(`${BASE_URL}/${id}`); return response.json(); };
- Formulario para crear órdenes (
OrderForm.jsx
):import React, { useState } from "react"; import { createOrder } from "../services/api"; const OrderForm = () => { const [productName, setProductName] = useState(""); const [quantity, setQuantity] = useState(1); const [price, setPrice] = useState(0); const handleSubmit = async (e) => { e.preventDefault(); const order = { productName, quantity, price }; await createOrder(order); alert("Orden creada con éxito."); }; return ( <form onSubmit={handleSubmit}> <input type="text" placeholder="Nombre del producto" value={productName} onChange={(e) => setProductName(e.target.value)} /> <input type="number" placeholder="Cantidad" value={quantity} onChange={(e) => setQuantity(e.target.value)} /> <input type="number" placeholder="Precio" value={price} onChange={(e) => setPrice(e.target.value)} /> <button type="submit">Crear Orden</button> </form> ); }; export default OrderForm;
Ventajas en este ejemplo
- Backend:
- La lógica de negocio está aislada (
OrderService
) y puede probarse fácilmente con mocks. - Cambiar la base de datos o usar un servicio externo solo requiere modificar
DatabaseOrderRepository
.
- La lógica de negocio está aislada (
- Frontend:
- El adaptador para interactuar con el backend (
api.js
) desacopla los detalles de implementación del resto del código.
- El adaptador para interactuar con el backend (
Para saber más:
https://salesystems.es/arquitectura-hexagonal/
https://www.hackio.com/blog/que-es-arquitectura-hexagonal-en-programacion
https://medium.com/@edusalguero/arquitectura-hexagonal-59834bb44b7f