0% encontró este documento útil (0 votos)
24 vistas51 páginas

Programas en Java y Python 001

Este documento describe cómo desarrollar un sistema de login en Java Spring Boot con MySQL y una interfaz web en HTML 5.2, donde un usuario solo puede iniciar sesión una vez y su cuenta se bloquea tras tres intentos fallidos. Incluye pasos para configurar el proyecto en Apache NetBeans, crear la base de datos y la tabla de usuarios, implementar la lógica de seguridad con Spring Security, y crear las páginas HTML necesarias. Al final, se proporciona información sobre cómo ejecutar y probar el sistema, incluyendo la creación de un usuario inicial con contraseña encriptada.

Cargado por

Jose Llanos Tech
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
24 vistas51 páginas

Programas en Java y Python 001

Este documento describe cómo desarrollar un sistema de login en Java Spring Boot con MySQL y una interfaz web en HTML 5.2, donde un usuario solo puede iniciar sesión una vez y su cuenta se bloquea tras tres intentos fallidos. Incluye pasos para configurar el proyecto en Apache NetBeans, crear la base de datos y la tabla de usuarios, implementar la lógica de seguridad con Spring Security, y crear las páginas HTML necesarias. Al final, se proporciona información sobre cómo ejecutar y probar el sistema, incluyendo la creación de un usuario inicial con contraseña encriptada.

Cargado por

Jose Llanos Tech
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

explicame como desarrollar un sistema de login; donde el usuario solo puede logearse una sola vez

y si este se equivoca en la contraseña por tres intentos, su cuenta será bloqueada en java sprint boot,
base de datos en mysql, con una interfaz web, osea en HTML 5.2, todo esto en el IDE apache
netbeans 26
Sistema de Login Sprint Boot – MySQL y HTML
Sistema de login con las características que mencionas: inicio de sesión único, bloqueo de cuenta
tras 3 intentos fallidos, y una interfaz web en HTML. Usaremos Java Spring Boot, MySQL y el
IDE Apache NetBeans 26.
Este es un proyecto completo que involucra varias capas: la interfaz de usuario (frontend), el
backend (Spring Boot) y la base de datos (MySQL). Al finalizar, tendrás un proyecto bien
estructurado y listo para ser editado.

Requisitos previos
• Apache NetBeans 26: Asegúrate de tenerlo instalado.
• JDK (Java Development Kit): Se recomienda una versión reciente (JDK 17 o superior).
• MySQL Server: Necesitas un servidor MySQL en funcionamiento y un cliente como
MySQL Workbench.
• Conocimientos básicos: Es útil tener nociones de Java, Spring Boot, SQL, HTML y Maven.

Paso 1: Configuración del proyecto en NetBeans


1. Abre NetBeans y ve a File > New Project.

2. Selecciona Maven > Spring Boot.

3. Elige Spring Initializr y haz clic en Next.

4. Configura el proyecto:
• Group: [Link]

• Artifact: login-app

• Name: login-app

• Java version: Selecciona la versión de JDK que tienes instalada.


• Packaging: Jar

• Language: Java

5. Añade las dependencias:


• En la ventana de dependencias, busca y selecciona:
• Spring Web: Para el desarrollo de controladores web.
• Spring Data JPA: Para la persistencia de datos con JPA y Hibernate.
• MySQL Driver: Para conectar con la base de datos MySQL.
• Spring Security: ¡Fundamental! Para manejar la autenticación y la gestión
de sesiones.
• Thymeleaf: Un motor de plantillas para renderizar las páginas HTML.
• Haz clic en Finish.

NetBeans creará el proyecto con una estructura de carpetas y el archivo [Link] con las
dependencias necesarias.

Paso 2: Configuración de la base de datos MySQL


1. Crea la base de datos: En tu cliente de MySQL, ejecuta el siguiente comando:
SQL
CREATE DATABASE login_db;

2. Crea la tabla de usuarios: Dentro de login_db, crea una tabla para almacenar los datos
de los usuarios. Esta tabla debe incluir campos para el contador de intentos fallidos y el
estado de la cuenta.
SQL
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
enabled BOOLEAN NOT NULL,
failed_attempts INT NOT NULL DEFAULT 0,
account_locked BOOLEAN NOT NULL DEFAULT FALSE
);

3. Configura [Link]: Abre el archivo


src/main/resources/[Link] en tu proyecto y añade la
configuración de la base de datos.
Properties
# Database configuration
[Link]=jdbc:mysql://localhost:3306/login_db?
createDatabaseIfNotExist=true
[Link]=root
[Link]=tu_contraseña_de_mysql
[Link]-class-name=[Link]

# JPA and Hibernate configuration


[Link]-auto=update
[Link]-sql=true
[Link]=[Link].MySQL8Dialec
t

¡Importante! Reemplaza tu_contraseña_de_mysql con la contraseña de tu usuario


root de MySQL.
Paso 3: Desarrollo del modelo y el repositorio
1. Crea la entidad User: En la carpeta
src/main/java/com/tuempresa/loginapp/model, crea la clase [Link].
Esta clase mapea la tabla users de la base de datos.

Java
package [Link];

import [Link].*;
import [Link]; // Si usas Lombok para getters/setters

@Entity
@Table(name = "users")
@Data
public class User {
@Id
@GeneratedValue(strategy = [Link])
private Long id;

@Column(unique = true, nullable = false)


private String username;

@Column(nullable = false)
private String password;

private boolean enabled;

@Column(name = "failed_attempts")
private int failedAttempts;

@Column(name = "account_locked")
private boolean accountLocked;
}

Si no tienes Lombok, puedes agregar los getters y setters manualmente.


2. Crea el repositorio UserRepository: En la carpeta
src/main/java/com/tuempresa/loginapp/repository, crea la interfaz
[Link].

Java
package [Link];

import [Link];
import [Link];
import [Link];

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
}

Paso 4: Implementación de Spring Security y la lógica del login


Aquí es donde implementaremos la lógica del login único y el bloqueo de cuenta.
1. Crea la configuración de seguridad: En la carpeta
src/main/java/com/tuempresa/loginapp/config, crea la clase
[Link].

Java
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import
[Link];
import
[Link]
Security;
import [Link];
import [Link];
import [Link];
import
[Link]
er;
import
[Link]
er;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Autowired
private UserDetailsServiceImpl userDetailsService;

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http)
throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/login", "/css/**",
"/error").permitAll() // Permite acceso a la página de login, CSS y la
página de error
.anyRequest().authenticated() // Requiere autenticación
para cualquier otra URL
)
.formLogin(formLogin -> formLogin
.loginPage("/login") // Ruta de la página de login
.usernameParameter("username")
.passwordParameter("password")
.successHandler(authenticationSuccessHandler()) //
Manejador de éxito del login
.failureHandler(authenticationFailureHandler()) //
Manejador de fracaso del login
.permitAll()
)
.logout(logout -> logout
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout") // Redirige al login
con un mensaje de logout
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll()
)
.sessionManagement(session -> session
.maximumSessions(1) // **Permite solo una sesión por
usuario**
.expiredUrl("/login?expired") // Redirige si la sesión
expira
);

return [Link]();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return (request, response, authentication) -> {
// Lógica que se ejecuta al iniciar sesión con éxito
String username = [Link]();
User user = [Link](username);
if (user != null) {
// Resetea el contador de intentos fallidos
[Link](0);
[Link](user);
}
[Link]("/"); // Redirige a la página principal
};
}

@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
return (request, response, exception) -> {
// Lógica que se ejecuta al fallar el login
String username = [Link]("username");
User user = [Link](username);

if (user != null) {
if ([Link]()) {
// Si la cuenta ya está bloqueada, no hacer nada más
} else {
// Incrementa el contador de intentos fallidos
[Link]([Link]() + 1);

// Bloquea la cuenta si llega a 3 intentos


if ([Link]() >= 3) {
[Link](true);
}
[Link](user);
}
}

// Redirige al login con un mensaje de error


[Link]("/login?error");
};
}
}

2. Implementa UserDetailsService: En la carpeta


src/main/java/com/tuempresa/loginapp/service, crea la clase
[Link].
Java
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import
[Link];
import [Link];
import [Link];
import [Link];

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

@Autowired
private UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String username) throws
UsernameNotFoundException {
User user = [Link](username);
if (user == null) {
throw new UsernameNotFoundException("Usuario no encontrado: "
+ username);
}

// Retorna un objeto UserDetails de Spring Security.


// La cuenta está habilitada solo si "enabled" es true y
"accountLocked" es false.
return new [Link](
[Link](),
[Link](),
[Link]() && ![Link](), // La cuenta está
habilitada y no bloqueada
true, // accountNonExpired
true, // credentialsNonExpired
true, // accountNonLocked - Spring Security maneja el bloqueo
de cuenta automáticamente si es false.
new ArrayList<>() // Puedes añadir roles aquí
);
}

public void saveUser(User user) {


[Link](user);
}

public User findByUsername(String username) {


return [Link](username);
}
}

3. Crea el controlador web: En la carpeta


src/main/java/com/tuempresa/loginapp/controller, crea la clase
[Link].

Java
package [Link];
import [Link];
import [Link];

@Controller
public class WebController {

@GetMapping("/login")
public String showLoginForm() {
return "login"; // Nombre de la plantilla HTML
}

@GetMapping("/")
public String showHomePage() {
return "home"; // Página principal después del login
}
}

Paso 5: Creación de la interfaz web (HTML 5.2 con Thymeleaf)


1. Crea la carpeta de plantillas: En src/main/resources, crea la carpeta templates.
2. Crea el formulario de login ([Link]): Dentro de templates, crea el archivo
[Link].

HTML
<!DOCTYPE html>
<html lang="es" xmlns:th="[Link]
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
<link rel="stylesheet" href="/css/[Link]">
</head>
<body>
<div class="login-container">
<h2>Iniciar Sesión</h2>

<div th:if="${[Link]}" class="error-message">


Usuario o contraseña incorrectos.
</div>

<div th:if="${[Link]}" class="success-message">


Has cerrado sesión exitosamente.
</div>

<div th:if="${[Link]}" class="error-message">


Tu sesión ha expirado. Por favor, inicia sesión de nuevo.
</div>

<form th:action="@{/login}" method="post">


<div class="form-group">
<label for="username">Usuario:</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="password">Contraseña:</label>
<input type="password" id="password" name="password"
required>
</div>
<button type="submit">Iniciar Sesión</button>
</form>
</div>
</body>
</html>

3. Crea la página principal ([Link]): Dentro de templates, crea el archivo


[Link].

HTML
<!DOCTYPE html>
<html lang="es" xmlns:th="[Link]
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Página Principal</title>
<link rel="stylesheet" href="/css/[Link]">
</head>
<body>
<div class="container">
<h1>¡Bienvenido!</h1>
<p>Has iniciado sesión correctamente.</p>
<form th:action="@{/logout}" method="post">
<button type="submit">Cerrar Sesión</button>
</form>
</div>
</body>
</html>

4. Añade estilos CSS: En src/main/resources, crea la carpeta static y dentro de


ella, la carpeta css. Crea el archivo [Link] para darle un buen diseño.

CSS
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}

.login-container, .container {
background-color: #fff;
padding: 40px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
text-align: center;
}

.form-group {
margin-bottom: 20px;
text-align: left;
}

.form-group label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}

.form-group input {
width: 100%;
padding: 10px;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 4px;
}

button {
width: 100%;
padding: 10px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}

button:hover {
background-color: #0056b3;
}

.error-message, .success-message {
padding: 10px;
border-radius: 4px;
margin-bottom: 15px;
}

.error-message {
color: #d9534f;
background-color: #f2dede;
border: 1px solid #ebccd1;
}

.success-message {
color: #5cb85c;
background-color: #dff0d8;
border: 1px solid #d6e9c6;
}

Paso 6: Ejecución y prueba


1. Crea un usuario inicial: La contraseña debe estar encriptada con BCrypt. Puedes usar un
generador en línea o un método en Java.
• Por ejemplo, el hash de la contraseña admin123 es
$2a$10$w09Jg6.2dE5Vf0.Xk7.n.Q2CgXb3Jj8d7E9F4H5I6J7K8L9M0N
1O2P3Q4R5S6T7.

• Inserta un usuario en la tabla users con la contraseña encriptada.

SQL
INSERT INTO users (username, password, enabled, failed_attempts,
account_locked)
VALUES ('admin',
'$2a$10$w09Jg6.2dE5Vf0.Xk7.n.Q2CgXb3Jj8d7E9F4H5I6J7K8L9M0N1O2P3Q4R5S6T7',
TRUE, 0, FALSE);

2. Ejecuta el proyecto: En NetBeans, haz clic derecho en el proyecto y selecciona Run.

3. Abre el navegador: Ve a [Link]

4. Prueba el login:
• Login exitoso: Usa el usuario admin y la contraseña admin123. Serás redirigido a
la página principal.
• Intentos fallidos: Intenta ingresar una contraseña incorrecta 3 veces. Después del
tercer intento, la cuenta se bloqueará y no podrás acceder.
• Login único: Si inicias sesión en otro navegador o dispositivo, la sesión anterior en
el primer navegador se invalidará.

¿Cómo puedes editar y mejorar este sistema?


Este proyecto está diseñado para ser fácilmente editable:
• Lógica de negocio: La lógica de bloqueo de cuenta está en el
AuthenticationFailureHandler en [Link]. Puedes cambiar
el número de intentos fallidos (>= 3) o agregar notificaciones.
• Interfaz de usuario: Los archivos HTML y CSS son totalmente personalizables. Puedes
cambiar el diseño, añadir más campos al formulario, o crear nuevas páginas web.
• Base de datos: Puedes añadir más columnas a la tabla users, como email, nombre,
apellido, etc. y mapearlas en la entidad [Link].

• Seguridad: Explora más opciones de Spring Security, como la autenticación con JWT o
OAuth2.
• Mensajes de error: Puedes personalizar los mensajes de error que se muestran en el HTML
modificando la plantilla [Link] y la lógica en
AuthenticationFailureHandler.

Añadiendo usuarios

Paso 1: Agregar el formulario de registro (Frontend)


Primero, necesitamos una página HTML para que los usuarios puedan registrarse.
1. Crea la página de registro: En la carpeta src/main/resources/templates, crea
un nuevo archivo llamado [Link].

HTML
<!DOCTYPE html>
<html lang="es" xmlns:th="[Link]
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registro de Usuario</title>
<link rel="stylesheet" href="/css/[Link]">
</head>
<body>
<div class="login-container">
<h2>Crear una Cuenta</h2>

<div th:if="${[Link]}" class="success-message">


¡Tu cuenta ha sido creada con éxito!
</div>
<div th:if="${[Link]}" class="error-message">
El nombre de usuario ya existe. Por favor, elige otro.
</div>

<form th:action="@{/register}" method="post">


<div class="form-group">
<label for="username">Nombre de Usuario:</label>
<input type="text" id="username" name="username" required>
</div>
<div class="form-group">
<label for="password">Contraseña:</label>
<input type="password" id="password" name="password"
required>
</div>
<button type="submit">Registrar</button>
</form>

<p class="mt-3">
¿Ya tienes una cuenta? <a th:href="@{/login}">Inicia sesión
aquí</a>
</p>
</div>
</body>
</html>

2. Agrega un enlace al formulario de login: Abre el archivo [Link] y añade un


enlace para que los usuarios puedan ir a la página de registro. Colócalo debajo del botón de
login.
HTML
<button type="submit">Iniciar Sesión</button>
</form>

<p class="mt-3">
¿No tienes una cuenta? <a th:href="@{/register}">Regístrate
aquí</a>
</p>
</div>
</body>
</html>

Paso 2: Crear el controlador y el servicio de registro (Backend)


Ahora, necesitas un controlador para manejar las solicitudes de registro y un servicio para procesar
la lógica de negocio.
1. Modifica [Link]: Agrega dos nuevos métodos para manejar las
solicitudes GET y POST para el registro.
Java
package [Link];

import [Link];
import [Link]; // Importa el nuevo
servicio
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

@Controller
public class WebController {

@Autowired
private UserService userService; // Inyecta el nuevo servicio

@GetMapping("/login")
public String showLoginForm() {
return "login"; // Muestra la plantilla de login
}

@GetMapping("/")
public String showHomePage() {
return "home"; // Muestra la página principal
}

@GetMapping("/register")
public String showRegisterForm() {
return "register"; // Muestra la plantilla de registro
}

@PostMapping("/register")
public String registerUser(@RequestParam String username,
@RequestParam String password, RedirectAttributes redirectAttributes) {
// Llama al servicio para registrar al usuario
if ([Link](username, password)) {
// Si el registro fue exitoso
[Link]("success", "true");
return "redirect:/login?success"; // Redirige al login con
mensaje de éxito
} else {
// Si el registro falló (ej: usuario ya existe)
[Link]("error", "true");
return "redirect:/register?error"; // Redirige al registro con
mensaje de error
}
}
}

2. Crea el servicio [Link]: Este servicio contendrá la lógica de negocio para


crear el usuario y encriptar la contraseña.
Java
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

@Service
public class UserService {

@Autowired
private UserRepository userRepository;

@Autowired
private PasswordEncoder passwordEncoder;

/**
* Registra un nuevo usuario en la base de datos.
* @param username El nombre de usuario.
* @param rawPassword La contraseña sin encriptar.
* @return true si el registro fue exitoso, false si el usuario ya
existe.
*/
public boolean registerNewUser(String username, String rawPassword) {
// Verifica si el usuario ya existe
if ([Link](username) != null) {
return false; // El usuario ya existe, no se puede registrar
}

// Crea una nueva instancia de User


User newUser = new User();
[Link](username);
[Link]([Link](rawPassword)); //
Encripta la contraseña
[Link](true); // Habilita la cuenta por defecto
[Link](0); // Resetea los intentos fallidos
[Link](false); // La cuenta no está bloqueada

// Guarda el usuario en la base de datos


[Link](newUser);
return true; // Registro exitoso
}
}

3. Inyecta el servicio en [Link]: Para que el servicio de


seguridad pueda acceder al repositorio de usuarios, asegúrate de que el UserRepository
esté inyectado. Ya lo está en el código anterior, pero vale la pena revisarlo.

Paso 3: Mejorar los mensajes de error


Los mensajes de error actuales en el formulario de login son genéricos. Vamos a personalizarlos
para que el usuario sepa por qué no puede iniciar sesión.
1. Modifica AuthenticationFailureHandler: Abre [Link] y
edita el authenticationFailureHandler() para que envíe un mensaje específico
según el tipo de error.
Java
// ... (código existente) ...
@Bean
public AuthenticationFailureHandler authenticationFailureHandler() {
return (request, response, exception) -> {
String username = [Link]("username");
String redirectUrl = "/login?error"; // URL por defecto

User user = [Link](username);

if (user != null) {
// Verifica si la cuenta está bloqueada
if ([Link]()) {
redirectUrl = "/login?error_locked"; // Mensaje para
cuenta bloqueada
} else {
// Incrementa el contador de intentos fallidos
[Link]([Link]() + 1);

// Bloquea la cuenta si llega a 3 intentos


if ([Link]() >= 3) {
[Link](true);
redirectUrl = "/login?error_locked";
} else {
// Mensaje de intentos restantes
int attemptsLeft = 3 - [Link]();
redirectUrl = "/login?error_attempts=" +
attemptsLeft;
}

[Link](user);
}
} else {
// Usuario no encontrado
redirectUrl = "/login?error_user_not_found";
}

[Link](redirectUrl);
};
}
// ... (código existente) ...

2. Modifica [Link] para mostrar los nuevos mensajes: Abre [Link] y añade
las nuevas etiquetas div para mostrar los mensajes condicionalmente.

HTML
<div th:if="${[Link]}" class="error-message">
Usuario o contraseña incorrectos.
</div>

<div th:if="${param.error_locked}" class="error-message">


Tu cuenta ha sido bloqueada debido a demasiados intentos
fallidos.
</div>

<div th:if="${param.error_attempts}" class="error-message">


Contraseña incorrecta. Tienes <span th:text="$
{param.error_attempts}"></span> intentos restantes antes de que tu cuenta
se bloquee.
</div>

<div th:if="${param.error_user_not_found}" class="error-message">


El usuario no existe.
</div>

<div th:if="${[Link]}" class="success-message">


Has cerrado sesión exitosamente.
</div>

<div th:if="${[Link]}" class="error-message">


Tu sesión ha expirado. Por favor, inicia sesión de nuevo.
</div>

Resumen de los cambios y cómo editarlos


Ahora, tu sistema tiene las siguientes nuevas funcionalidades:
• Registro de usuarios: Un formulario y un endpoint para crear nuevas cuentas de manera
segura, encriptando la contraseña.
• Mensajes de error detallados: El usuario recibe retroalimentación específica sobre si su
cuenta está bloqueada o cuántos intentos le quedan.
Todo este código es completamente editable.
• ¿Quieres cambiar el número de intentos? Edita el valor 3 en [Link].

• ¿Quieres añadir un campo de correo electrónico al registro? Agrega la columna email


a la tabla users en MySQL, añade el campo a la entidad [Link], el formulario
[Link] y el método registerNewUser en [Link].

• ¿Quieres un mensaje de error diferente? Modifica el texto en las etiquetas div de


[Link].
Enviando Correos, mensajes por sms y whatsapp con Java
Para estas funcionalidades, no basta con el código Java por sí solo; necesitas servicios de terceros
que actúen como intermediarios. Para el correo, usaremos la API de JavaMail (ahora Jakarta Mail),
y para los SMS y WhatsApp, utilizaremos un servicio popular y robusto como Twilio.

Resumen de los servicios a usar


• Correos electrónicos: Usaremos la librería Jakarta Mail (anteriormente JavaMail API).
Necesitarás una cuenta de correo electrónico (como Gmail, Outlook, etc.) y habilitar la
opción de "aplicaciones menos seguras" o generar una "contraseña de aplicación" para que
tu programa pueda iniciar sesión y enviar correos.
• SMS y WhatsApp: Usaremos la API de Twilio. Deberás registrarte en su plataforma,
obtener un número de teléfono de Twilio y tus credenciales de API (Account SID y Auth
Token). Twilio cobra por el envío de mensajes, pero ofrece un saldo de prueba para que
puedas experimentar.

Paso 1: Configuración del proyecto en Apache NetBeans 26


1. Crea un nuevo proyecto:
• Abre NetBeans y ve a File > New Project.

• Selecciona Java with Maven > Java Application. Haz clic en Next.

• Dale un nombre al proyecto, por ejemplo, MessengerApp.

• Define la ubicación y el grupo Maven. Haz clic en Finish.

2. Agrega las dependencias (Librerías):


• Abre el archivo [Link] en la carpeta de tu proyecto.

• Dentro de la etiqueta <dependencies>, agrega las siguientes dependencias. Si


estás usando una versión reciente de Java, utiliza [Link]. Para versiones
más antiguas, podría ser [Link].

XML
<dependencies>
<dependency>
<groupId>[Link]</groupId>
<artifactId>[Link]</artifactId>
<version>2.0.1</version> </dependency>

<dependency>
<groupId>[Link]</groupId>
<artifactId>twilio</artifactId>
<version>10.0.0</version> </dependency>
</dependencies>

• Guarda el [Link]. NetBeans descargará automáticamente las librerías necesarias.


Paso 2: Crear el programa para enviar correos electrónicos
1. Habilita el acceso a aplicaciones de terceros en tu cuenta de correo:
• Gmail: Ve a la configuración de tu cuenta de Google > Seguridad. Si tienes la
verificación en dos pasos activada, genera una "Contraseña de aplicación". Si no,
activa la opción de "Acceso de apps menos seguras". ¡Este paso es crucial para que
funcione!
• Outlook/Hotmail: Habilita el protocolo POP/IMAP en la configuración de correo.
2. Crea una clase Java para enviar correos:
• En tu proyecto, dentro de la carpeta Source Packages, crea un nuevo paquete
(por ejemplo, [Link]).

• Dentro del paquete, crea una nueva clase Java llamada [Link].

• Pega el siguiente código en la clase:


Java
package [Link];

import [Link].*;
import [Link];
import [Link];
import [Link];

public class EmailSender {

public static void sendEmail(String to, String subject, String body) {


// Reemplaza con tus credenciales de correo electrónico
final String fromEmail = "tu_correo@[Link]"; // Tu dirección de
correo
final String password = "tu_contraseña_de_aplicacion"; // Tu
contraseña de aplicación o clave de acceso

// Configuración del servidor SMTP de Gmail


Properties props = new Properties();
[Link]("[Link]", "[Link]"); // Servidor SMTP de
Gmail
[Link]("[Link]", "587"); // Puerto TLS
[Link]("[Link]", "true");
[Link]("[Link]", "true"); // Habilita
STARTTLS

// Crea la sesión de correo con autenticación


Session session = [Link](props, new
[Link]() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(fromEmail, password);
}
});

try {
// Crea un objeto MimeMessage
Message message = new MimeMessage(session);

// Establece el remitente
[Link](new InternetAddress(fromEmail));
// Establece el destinatario
[Link]([Link],
[Link](to));

// Establece el asunto
[Link](subject);

// Establece el cuerpo del mensaje


[Link](body);

// Envía el mensaje
[Link](message);
[Link]("Correo enviado exitosamente a " + to);

} catch (MessagingException e) {
[Link]("Error al enviar el correo: " +
[Link]());
[Link]();
}
}
}

3. Crea el método main para probarlo:

• En tu clase principal (por ejemplo, [Link] o la que se haya creado al inicio del
proyecto), llama al método sendEmail.

Java
package [Link];

import [Link];

public class Main {


public static void main(String[] args) {
String recipient = "destinatario@[Link]"; // Reemplaza con el
correo del destinatario
String subject = "Prueba de correo desde Java";
String body = "¡Hola! Este es un correo enviado automáticamente
desde un programa Java.";

[Link](recipient, subject, body);


}
}

• Ejecuta el proyecto. Si todo está bien, verás un mensaje de éxito en la consola y el


correo llegará al destinatario.

Paso 3: Crear el programa para enviar SMS y WhatsApp (con Twilio)


1. Regístrate en Twilio:
• Ve a la página web de Twilio y crea una cuenta.
• Sigue los pasos para verificar tu número de teléfono y obtener un número de prueba
de Twilio.
• En el panel de control de Twilio, encontrarás tu Account SID y Auth Token.
¡Guarda estos datos, los necesitarás en el código!
• Importante para WhatsApp: Debes configurar el "WhatsApp Sandbox". Sigue las
instrucciones de Twilio para vincular tu número de WhatsApp de prueba.
2. Crea una clase Java para enviar SMS y WhatsApp:
• En tu proyecto, crea un nuevo paquete (por ejemplo, [Link]).

• Crea una clase llamada [Link].

• Pega el siguiente código en la clase:


Java
package [Link];

import [Link];
import [Link];
import [Link];

public class TwilioMessenger {

// Reemplaza con tus credenciales de Twilio


public static final String ACCOUNT_SID =
"ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; // Tu Account SID
public static final String AUTH_TOKEN = "your_auth_token"; // Tu Auth
Token

/**
* Envía un mensaje SMS a un número de teléfono.
* @param toPhoneNumber El número de destino en formato E.164 (Ej:
+51987654321).
* @param messageBody El cuerpo del mensaje.
* @param fromTwilioNumber Tu número de Twilio en formato E.164.
*/
public static void sendSms(String toPhoneNumber, String messageBody,
String fromTwilioNumber) {
try {
[Link](ACCOUNT_SID, AUTH_TOKEN);
Message message = [Link](
new PhoneNumber(toPhoneNumber),
new PhoneNumber(fromTwilioNumber),
messageBody
).create();

[Link]("SMS enviado exitosamente. SID del mensaje:


" + [Link]());

} catch (Exception e) {
[Link]("Error al enviar el SMS: " +
[Link]());
[Link]();
}
}

/**
* Envía un mensaje de WhatsApp a un número.
* @param toWhatsAppNumber El número de destino de WhatsApp en formato
E.164 (Ej: +51987654321).
* @param messageBody El cuerpo del mensaje.
* @param fromWhatsAppSandboxNumber El número de sandbox de Twilio
para WhatsApp (Ej: whatsapp:+14155238886).
*/
public static void sendWhatsAppMessage(String toWhatsAppNumber, String
messageBody, String fromWhatsAppSandboxNumber) {
try {
[Link](ACCOUNT_SID, AUTH_TOKEN);
Message message = [Link](
new PhoneNumber("whatsapp:" + toWhatsAppNumber),
new PhoneNumber("whatsapp:" + fromWhatsAppSandboxNumber),
messageBody
).create();

[Link]("Mensaje de WhatsApp enviado exitosamente.


SID del mensaje: " + [Link]());
} catch (Exception e) {
[Link]("Error al enviar el mensaje de WhatsApp: "
+ [Link]());
[Link]();
}
}
}

3. Crea el método main para probarlo:

• En tu clase principal, llama a los métodos para enviar mensajes.


Java
package [Link];

import [Link];

public class Main {


public static void main(String[] args) {
// Configuración de Twilio (reemplaza con tus datos reales)
String myTwilioNumber = "+11234567890"; // Tu número de Twilio
String myWhatsAppSandbox = "+14155238886"; // Tu número de sandbox
de Twilio
String recipientPhoneNumber = "+51987654321"; // El número al que
quieres enviar el mensaje

// --- Enviar SMS ---


[Link]("Enviando SMS...");
[Link](recipientPhoneNumber, "Hola desde mi
programa Java! SMS de prueba.", myTwilioNumber);

// --- Enviar WhatsApp ---


[Link]("\nEnviando mensaje de WhatsApp...");
[Link](recipientPhoneNumber, "¡Hola!
Mensaje de WhatsApp de prueba desde Java.", myWhatsAppSandbox);
}
}

• Ejecuta el proyecto. Si tus credenciales y números están bien configurados, verás


mensajes de éxito en la consola y recibirás los mensajes en tu teléfono.

Consideraciones de seguridad y despliegue


• No guardes tus credenciales de API directamente en el código (ACCOUNT_SID,
AUTH_TOKEN, password). Esto no es seguro. Para un proyecto real, es mejor usar
variables de entorno o archivos de configuración externos.
• Costos: Twilio cobra por el uso de sus servicios. Un mensaje de prueba puede ser gratuito,
pero el uso continuo tiene un costo.
Envio de correos, mensajes sms y whatsapp con Python
A diferencia de Java, Python es conocido por su sencillez y por tener una gran cantidad de librerías
que facilitan este tipo de tareas. No necesitarás un IDE tan complejo como NetBeans, un editor de
código como Visual Studio Code o PyCharm es más que suficiente.
Para estas funcionalidades, al igual que en Java, se utilizan servicios de terceros que proveen APIs
para la mensajería.
• Correos electrónicos: Usaremos el módulo smtplib, que viene incluido en la instalación
estándar de Python.
• SMS y WhatsApp: Utilizaremos la librería Twilio, que es un servicio de comunicación en
la nube muy popular y robusto. Necesitarás registrarte en su plataforma y obtener tus
credenciales.

Paso 1: Configuración del entorno de Python


1. Instala Python: Si no lo tienes, descárgalo e instálalo desde la página oficial de Python. Se
recomienda usar Python 3.
2. Instala las librerías necesarias: Abre tu terminal o línea de comandos y ejecuta los
siguientes comandos para instalar las librerías.
Bash
# Para el envío de SMS y WhatsApp
pip install twilio

# Para el correo, 'smtplib' ya viene incluido, pero 'email' es útil para


construir mensajes.
# Si necesitas una librería más completa para correos, puedes usar
'yagmail'.
# pip install yagmail

Paso 2: Envío de Correos Electrónicos


Para enviar correos, usaremos la librería estándar smtplib para conectarnos al servidor de correo
y la librería email para construir el mensaje.

1. Habilita el acceso en tu cuenta de correo: Para que tu programa pueda iniciar sesión en tu
cuenta de correo (por ejemplo, Gmail), necesitas generar una "Contraseña de aplicación"
si tienes la verificación en dos pasos activada. Si no, deberás activar la opción de "acceso de
apps menos seguras". Este paso es crucial.
2. Crea el script de Python: Crea un archivo llamado send_email.py y pega el siguiente
código.
Python
import smtplib
from [Link] import MIMEText
from [Link] import MIMEMultipart
def send_email(sender_email, sender_password, receiver_email, subject,
body):
"""
Sends an email using the SMTP protocol.
"""
# Reemplaza con tus credenciales y el servidor de correo
smtp_server = "[Link]" # For Gmail
smtp_port = 587 # TLS port

# Create a multipart message and set headers


message = MIMEMultipart()
message["From"] = sender_email
message["To"] = receiver_email
message["Subject"] = subject

# Add body to email


[Link](MIMEText(body, "plain"))

try:
# Create a secure connection with the SMTP server
server = [Link](smtp_server, smtp_port)
[Link]() # Upgrade the connection to a secure one

# Login to the email account


[Link](sender_email, sender_password)

# Send the email


[Link](sender_email, receiver_email, message.as_string())
print(f"Correo enviado exitosamente a {receiver_email}")

except Exception as e:
print(f"Error al enviar el correo: {e}")
finally:
# Close the connection
if 'server' in locals():
[Link]()

if __name__ == "__main__":
# --- Configuración para pruebas ---
# Reemplaza con tu correo y la contraseña de aplicación generada
sender_email_address = "tu_correo@[Link]"
sender_app_password = "tu_contraseña_de_aplicacion"

# Reemplaza con el correo del destinatario


recipient_email_address = "destinatario@[Link]"

email_subject = "Prueba de correo desde Python"


email_body = "¡Hola! Este es un correo enviado automáticamente desde
un script de Python."

send_email(sender_email_address, sender_app_password,
recipient_email_address, email_subject, email_body)

3. Ejecuta el script: En tu terminal, navega hasta el directorio donde guardaste el archivo y


ejecútalo.
Bash
python send_email.py
Paso 3: Envío de SMS y WhatsApp con Twilio
Para enviar mensajes de texto y WhatsApp, usarás la API de Twilio.
1. Regístrate en Twilio:
• Ve a la página web de Twilio y crea una cuenta.
• Verifica tu número de teléfono y obtén un número de Twilio (puede ser de prueba al
inicio).
• En el panel de control, encontrarás tu Account SID y Auth Token. Estos son tus
credenciales de API.
• Para WhatsApp: Sigue las instrucciones de Twilio para configurar el WhatsApp
Sandbox y vincular tu número de teléfono de prueba. Recibirás un número de
sandbox que usarás como remitente.
2. Crea el script de Python: Crea un archivo llamado send_sms_whatsapp.py y pega el
siguiente código.
Python
from [Link] import Client

def send_sms(to_phone_number, message_body, from_twilio_number):


"""
Sends an SMS message using the Twilio API.
"""
# Reemplaza con tus credenciales de Twilio
account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # Tu Account SID
auth_token = "your_auth_token" # Tu Auth Token

try:
client = Client(account_sid, auth_token)

message = [Link](
to=to_phone_number,
from_=from_twilio_number,
body=message_body
)

print(f"SMS enviado exitosamente. SID del mensaje: {[Link]}")


except Exception as e:
print(f"Error al enviar el SMS: {e}")

def send_whatsapp_message(to_whatsapp_number, message_body,


from_whatsapp_sandbox):
"""
Sends a WhatsApp message using the Twilio API.
"""
# Reemplaza con tus credenciales de Twilio
account_sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # Tu Account SID
auth_token = "your_auth_token" # Tu Auth Token

try:
client = Client(account_sid, auth_token)

message = [Link](
to=f"whatsapp:{to_whatsapp_number}",
from_=f"whatsapp:{from_whatsapp_sandbox}",
body=message_body
)

print(f"Mensaje de WhatsApp enviado exitosamente. SID del mensaje:


{[Link]}")
except Exception as e:
print(f"Error al enviar el mensaje de WhatsApp: {e}")

if __name__ == "__main__":
# --- Configuración para pruebas ---
# Reemplaza con tus números y credenciales
twilio_number = "+11234567890" # Tu número de Twilio
whatsapp_sandbox_number = "+14155238886" # Tu número de Twilio
WhatsApp Sandbox
recipient_phone_number = "+51987654321" # Número del destinatario en
formato E.164 (+código_país_número)

# --- Enviar SMS ---


print("Enviando SMS...")
send_sms(recipient_phone_number, "Hola! Este es un SMS de prueba desde
Python.", twilio_number)

# --- Enviar WhatsApp ---


print("\nEnviando mensaje de WhatsApp...")
send_whatsapp_message(recipient_phone_number, "¡Hola! Mensaje de
WhatsApp de prueba desde Python.", whatsapp_sandbox_number)

3. Ejecuta el script: En tu terminal, navega hasta el directorio donde guardaste el archivo y


ejecútalo.
Bash
python send_sms_whatsapp.py

Consideraciones clave
• Credenciales de seguridad: Nunca expongas tus contraseñas o tokens directamente en el
código fuente. Para aplicaciones reales, usa variables de entorno ([Link]) para
almacenar estos valores de forma segura.
• Formato de números de teléfono: Twilio requiere que los números de teléfono estén en
formato E.164, que incluye el signo +, el código de país y el número, sin espacios. Por
ejemplo: +51987654321.

• Costos: El envío de SMS y WhatsApp a través de Twilio no es gratuito. Después de usar el


saldo de prueba inicial, se te cobrará por cada mensaje enviado.
Con estos scripts, tienes una base sólida para automatizar el envío de comunicaciones desde Python.
Revisar una Base de Datos en Java

Requisitos previos
1. Apache NetBeans 26: Asegúrate de tenerlo instalado.
2. JDK (Java Development Kit): Se recomienda una versión reciente (JDK 17 o superior).
3. MySQL Server: Necesitas tener un servidor MySQL en funcionamiento.
4. MySQL Connector/J: Este es el driver JDBC que permite a Java conectarse con MySQL.
Lo descargaremos y agregaremos al proyecto.

Paso 1: Crear un nuevo proyecto en NetBeans


1. Abre NetBeans y ve a File > New Project.

2. Selecciona Java with Maven > Java Application.

3. Haz clic en Next.


4. Asígnale un nombre a tu proyecto, por ejemplo, DatabaseExplorer.

5. Haz clic en Finish.

Paso 2: Agregar la dependencia del driver JDBC de MySQL


Para que Java pueda comunicarse con MySQL, necesitas el conector JDBC.
1. Abre el archivo [Link] en la carpeta de tu proyecto.

2. Dentro de la etiqueta <dependencies>, agrega la siguiente dependencia. Puedes


verificar la última versión del conector en Maven Central.
XML
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version> </dependency>
</dependencies>

3. Guarda el archivo [Link]. NetBeans descargará automáticamente la librería.

Paso 3: Escribir el código para listar bases de datos, tablas y campos


Ahora, crearemos una clase en Java que se conectará a la base de datos y utilizará los metadatos de
la conexión para obtener la información que necesitas.
1. Crea una clase Java: En tu proyecto, ve a Source Packages, haz clic derecho en tu
paquete principal ([Link]) y selecciona New >
Java Class. Nómbrala DatabaseLister.
2. Pega el siguiente código en la clase [Link]. El código está comentado
para que entiendas cada parte.
Java
package [Link];

import [Link];
import [Link];
import [Link];
import [Link];
import [Link];

public class DatabaseLister {

// --- Configuración de la conexión a la base de datos ---


// URL de conexión: reemplaza localhost y el puerto si es necesario.
// La URL debe ser solo al servidor, sin especificar una base de datos
inicial.
private static final String URL = "jdbc:mysql://localhost:3306/?
useSSL=false&serverTimezone=UTC";
private static final String USER = "root"; // Tu usuario de MySQL
private static final String PASSWORD = "tu_contraseña_de_mysql"; // Tu
contraseña

public static void main(String[] args) {

// Reemplaza con tu contraseña de MySQL


// String password = "tu_contraseña_de_mysql";

try (Connection conn = [Link](URL, USER,


PASSWORD)) {

[Link]("Conexión exitosa a MySQL!\n");

// Obtenemos los metadatos de la base de datos


DatabaseMetaData metaData = [Link]();

// --- 1. Listar bases de datos ---


[Link]("--- Bases de datos disponibles ---");
listDatabases(metaData);

// --- 2. Listar tablas y campos para cada base de datos ---


[Link]("\n--- Explorando tablas y campos ---");
listTablesAndColumns(conn, metaData);

} catch (SQLException e) {
[Link]("Error de conexión a la base de datos:");
[Link]();
}
}

/**
* Lista todas las bases de datos disponibles en el servidor.
* @param metaData Metadatos de la base de datos.
* @throws SQLException
*/
private static void listDatabases(DatabaseMetaData metaData) throws
SQLException {
try (ResultSet rs = [Link]()) {
while ([Link]()) {
String databaseName = [Link]("TABLE_CAT");
[Link]("- " + databaseName);
}
}
}

/**
* Recorre cada base de datos, lista sus tablas y los campos de cada
tabla.
* @param conn La conexión actual.
* @param metaData Metadatos de la base de datos.
* @throws SQLException
*/
private static void listTablesAndColumns(Connection conn,
DatabaseMetaData metaData) throws SQLException {
try (ResultSet dbRs = [Link]()) {
while ([Link]()) {
String databaseName = [Link]("TABLE_CAT");
// Omitimos bases de datos del sistema para mayor claridad
if ([Link]("information_schema") ||
[Link]("mysql") || [Link]("performance_schema")
|| [Link]("sys")) {
continue;
}

[Link]("\n== Base de datos: " + databaseName +


" ==");

// Lista las tablas en la base de datos actual


try (ResultSet tableRs = [Link](databaseName,
null, "%", new String[]{"TABLE"})) {
while ([Link]()) {
String tableName =
[Link]("TABLE_NAME");
[Link]("\n - Tabla: " + tableName);

// Lista los campos de la tabla actual


try (ResultSet columnRs =
[Link](databaseName, null, tableName, null)) {
while ([Link]()) {
String columnName =
[Link]("COLUMN_NAME");
String columnType =
[Link]("TYPE_NAME");
int columnSize =
[Link]("COLUMN_SIZE");
[Link](" - Campo: " +
columnName + " (Tipo: " + columnType + ", Tamaño: " + columnSize + ")");
}
}
}
}
}
}
}
}

3. Modifica las credenciales: Reemplaza USER y PASSWORD en el código con tu usuario y


contraseña de MySQL.
Java
private static final String USER = "root";
private static final String PASSWORD = "tu_contraseña_de_mysql";
Paso 4: Ejecutar el programa en NetBeans
1. Haz clic derecho en el archivo [Link] en el explorador de proyectos.

2. Selecciona Run File o presiona Shift + F6.

Salida esperada
Si todo está configurado correctamente, verás una salida en la consola de NetBeans similar a esta
(dependiendo de las bases de datos y tablas que tengas):
Conexión exitosa a MySQL!

--- Bases de datos disponibles ---


- information_schema
- mysql
- performance_schema
- sys
- mi_base_de_datos_ejemplo
- login_db

--- Explorando tablas y campos ---

== Base de datos: mi_base_de_datos_ejemplo ==

- Tabla: productos
- Campo: id (Tipo: INT, Tamaño: 10)
- Campo: nombre (Tipo: VARCHAR, Tamaño: 255)
- Campo: precio (Tipo: DECIMAL, Tamaño: 10)

- Tabla: clientes
- Campo: id (Tipo: INT, Tamaño: 10)
- Campo: nombre (Tipo: VARCHAR, Tamaño: 100)
- Campo: email (Tipo: VARCHAR, Tamaño: 255)

== Base de datos: login_db ==

- Tabla: users
- Campo: id (Tipo: BIGINT, Tamaño: 19)
- Campo: username (Tipo: VARCHAR, Tamaño: 50)
- Campo: password (Tipo: VARCHAR, Tamaño: 255)
- Campo: enabled (Tipo: TINYINT, Tamaño: 1)
- Campo: failed_attempts (Tipo: INT, Tamaño: 10)
- Campo: account_locked (Tipo: TINYINT, Tamaño: 1)

Explicación del código


• [Link](URL, USER, PASSWORD): Esta es la línea
clave para establecer la conexión. La URL de la conexión es crucial; en este caso, nos
conectamos al servidor de MySQL (localhost:3306) sin especificar una base de datos
inicial para poder listar todas.
• [Link](): Este método devuelve un objeto DatabaseMetaData, que es
una interfaz poderosa de JDBC para obtener información sobre la base de datos, sus tablas,
columnas, etc.
• [Link](): Este método devuelve un ResultSet que contiene la
lista de todas las bases de datos (llamadas "catálogos" en JDBC) en el servidor.
• [Link](databaseName, null, "%", new String[]
{"TABLE"}): Este método devuelve un ResultSet con todas las tablas de una base de
datos específica. El % en el tercer parámetro actúa como un comodín para buscar todas las
tablas.
• [Link](databaseName, null, tableName, null): Este
método devuelve un ResultSet con todos los campos (columnas) de una tabla
específica.
• try-with-resources: Se utiliza try (Connection conn = ...) para asegurar
que la conexión y los ResultSet se cierren automáticamente, incluso si ocurre un error.
Esto es una buena práctica para evitar fugas de recursos.
Revisión de una base de datos con Python

Paso 1: Configuración del Entorno


1. Instala Python: Asegúrate de tener Python 3 instalado en tu sistema.
2. Instala el conector de MySQL para Python: Abre tu terminal o línea de comandos y
ejecuta el siguiente comando.
Bash
pip install mysql-connector-python

Paso 2: Conexión al Servidor de Base de Datos y Obtención de Metadatos


En Python, la clave para obtener información sobre la estructura de la base de datos es ejecutar
consultas SQL específicas para metadatos o usar funciones de la biblioteca para este propósito.
Crea un archivo de Python llamado database_explorer.py y agrega el siguiente código. Este
script se conecta al servidor de MySQL y luego ejecuta consultas para listar lo que necesitas.
Python
import [Link]

def explore_database(host, user, password):


"""
Connects to a MySQL server and lists databases, tables, and columns.
"""
try:
# Step 1: Connect to the MySQL server (without specifying a database)
connection = [Link](
host=host,
user=user,
password=password
)

print("Conexión exitosa a MySQL!\n")

# Create a cursor object to execute SQL queries


cursor = [Link]()

# --- Step 2: List all databases ---


print("--- Bases de datos disponibles ---")
[Link]("SHOW DATABASES")
databases = [db[0] for db in [Link]()]

# Exclude system databases for clarity


databases_to_explore = [db for db in databases if db not in
('information_schema', 'mysql', 'performance_schema', 'sys')]

for db_name in databases:


print(f"- {db_name}")

# --- Step 3: List tables and columns for each database ---
print("\n--- Explorando tablas y campos en bases de datos de usuario
---")

for db_name in databases_to_explore:


print(f"\n== Base de datos: {db_name} ==")

# Switch to the current database to get its tables


[Link] = db_name

# Get a new cursor for the new database context


db_cursor = [Link]()

# List all tables in the current database


db_cursor.execute("SHOW TABLES")
tables = [table[0] for table in db_cursor.fetchall()]

if not tables:
print(" (Esta base de datos no tiene tablas)")
continue

for table_name in tables:


print(f"\n - Tabla: {table_name}")

# Get the columns (fields) for the current table


db_cursor.execute(f"DESCRIBE `{table_name}`") # DESCRIBE is an
alias for SHOW COLUMNS FROM
columns = db_cursor.fetchall()

for column in columns:


column_name = column[0]
column_type = column[1]
print(f" - Campo: {column_name} (Tipo: {column_type})")

# Close the cursor and connection


[Link]()
[Link]()

except [Link] as err:


print(f"Error de conexión a la base de datos: {err}")

# --- Main execution block ---


if __name__ == "__main__":
# --- Replace with your MySQL credentials ---
DB_HOST = "localhost"
DB_USER = "root"
DB_PASSWORD = "tu_contraseña_de_mysql" # <-- Change this to your password

explore_database(DB_HOST, DB_USER, DB_PASSWORD)

Paso 3: Ejecuta el script


1. Modifica las credenciales: Antes de ejecutar, cambia las variables DB_USER y
DB_PASSWORD en el script con tus credenciales de MySQL.

Python
DB_USER = "root"
DB_PASSWORD = "tu_contraseña_de_mysql" # <-- ¡No olvides cambiar esto!

2. Ejecuta el programa: Abre tu terminal, navega hasta la carpeta donde guardaste el archivo
database_explorer.py y ejecútalo.
Bash
python database_explorer.py

Salida esperada
Si la conexión es exitosa y tienes bases de datos, verás un resultado similar al siguiente en tu
terminal:
Conexión exitosa a MySQL!

--- Bases de datos disponibles ---


- information_schema
- mi_base_de_datos
- mysql
- performance_schema
- sys
- tu_base_de_proyecto

--- Explorando tablas y campos en bases de datos de usuario ---

== Base de datos: mi_base_de_datos ==

- Tabla: productos
- Campo: id (Tipo: int)
- Campo: nombre (Tipo: varchar(255))
- Campo: precio (Tipo: decimal(10,2))

- Tabla: clientes
- Campo: id (Tipo: int)
- Campo: nombre (Tipo: varchar(100))
- Campo: email (Tipo: varchar(255))

== Base de datos: tu_base_de_proyecto ==

- Tabla: users
- Campo: id (Tipo: bigint)
- Campo: username (Tipo: varchar(50))
- Campo: password (Tipo: varchar(255))
- Campo: enabled (Tipo: tinyint(1))
- Campo: failed_attempts (Tipo: int)
- Campo: account_locked (Tipo: tinyint(1))

Explicación del Código


• [Link](): Esta función establece la conexión con el servidor
MySQL. La conexión se realiza sin especificar una base de datos para poder listar todos los
catálogos.
• [Link](): Crea un objeto cursor, que es el que te permite ejecutar
comandos SQL en la base de datos.
• [Link]("SHOW DATABASES"): Esta es una consulta SQL estándar para
listar todas las bases de datos en el servidor. El resultado se obtiene con
[Link]().
• [Link] = db_name: Después de listar las bases de datos, el código
itera sobre ellas. Al asignar el nombre de una base de datos a [Link], la
conexión se cambia a ese esquema, permitiéndote consultar sus tablas.
• db_cursor.execute("SHOW TABLES"): Esta consulta lista todas las tablas dentro
de la base de datos seleccionada.
• db_cursor.execute(f"DESCRIBE {table_name}"): La consulta DESCRIBE es
perfecta para obtener la estructura de una tabla, incluyendo los nombres de los campos, sus
tipos de datos, si son NULL, etc.

• Manejo de errores: El bloque try...except es crucial para manejar errores de


conexión o de base de datos, lo que hace que el programa sea robusto.
Este script es una herramienta muy útil para inspeccionar la estructura de tus bases de datos desde
Python. Es el punto de partida para cualquier automatización o herramienta de desarrollo que
necesite interactuar con la estructura de un esquema de base de datos.
Revisión de una base de datos con C#

Requisitos previos
1. Visual Studio 2022: Asegúrate de tener la versión Community, Professional o Enterprise.
Durante la instalación, verifica que tienes seleccionada la carga de trabajo de "Desarrollo
de escritorio de .NET".
2. MySQL Server: Necesitas tener un servidor MySQL en funcionamiento.
3. Conector de MySQL para .NET: Este es el driver que permite a C# comunicarse con
MySQL. Lo instalaremos a través de NuGet.

Paso 1: Crear un nuevo proyecto en Visual Studio 2022


1. Abre Visual Studio 2022.
2. Haz clic en Crear un proyecto nuevo.
3. Selecciona la plantilla "Aplicación de consola" y asegúrate de que el lenguaje sea C# y la
plataforma sea Windows. Haz clic en Siguiente.

4. Asígnale un nombre a tu proyecto, por ejemplo, DatabaseExplorer.

5. Haz clic en Siguiente.

6. Selecciona el Framework de destino. Se recomienda usar una versión de .NET 6.0 o


superior (LTS). Haz clic en Crear.

Paso 2: Instalar el paquete NuGet del conector de MySQL


Para que C# pueda conectarse a MySQL, necesitas el conector. La forma más sencilla es usar el
Administrador de paquetes NuGet de Visual Studio.
1. En el Explorador de soluciones (Solution Explorer), haz clic derecho en tu proyecto
(DatabaseExplorer).

2. Selecciona Administrar paquetes NuGet....

3. Ve a la pestaña Examinar (Browse).

4. En la barra de búsqueda, escribe [Link].

5. Selecciona el paquete [Link] (asegúrate de que sea el oficial de Oracle).

6. Haz clic en Instalar. Acepta los términos de licencia si se te solicita.

Paso 3: Escribir el código en C#


Ahora, vamos a escribir el código en el archivo [Link] para conectarnos y obtener los
metadatos de la base de datos.
1. Abre el archivo [Link].

2. Reemplaza el código existente con el siguiente. El código está comentado para que
entiendas cada paso.
C#
using [Link];
using System;
using [Link];

class Program
{
static void Main(string[] args)
{
// --- 1. Configuración de la cadena de conexión ---
// Reemplaza los valores con tus credenciales de MySQL.
// La URL no especifica una base de datos inicial para poder
listar todas.
string connectionString =
"server=localhost;port=3306;user=root;password=tu_contraseña_de_mysql;";

// Reemplaza con tu contraseña real


// string password = "tu_contraseña_de_mysql";

try
{
// Create a connection object
using (MySqlConnection connection = new
MySqlConnection(connectionString))
{
// Open the connection
[Link]();
[Link]("Conexión exitosa a MySQL!\n");

// --- 2. Listar bases de datos ---


[Link]("--- Bases de datos disponibles ---");
ShowDatabases(connection);

[Link]("\n--- Explorando tablas y campos ---");

// --- 3. Listar tablas y campos para cada base de datos


---
ShowTablesAndColumns(connection);
}
}
catch (MySqlException ex)
{
[Link]($"Error al conectar o ejecutar la consulta:
{[Link]}");
}

[Link]("\nPresiona cualquier tecla para salir...");


[Link]();
}

/// <summary>
/// Lists all available databases on the MySQL server.
/// </summary>
/// <param name="connection">The MySQL connection object.</param>
static void ShowDatabases(MySqlConnection connection)
{
// The GetSchema method is a powerful [Link] feature for
metadata.
DataTable databases = [Link]("Databases");

foreach (DataRow row in [Link])


{
string dbName = row["database_name"].ToString();
[Link]($"- {dbName}");
}
}

/// <summary>
/// Iterates through each user database, lists its tables, and the
columns of each table.
/// </summary>
/// <param name="connection">The MySQL connection object.</param>
static void ShowTablesAndColumns(MySqlConnection connection)
{
DataTable databases = [Link]("Databases");

foreach (DataRow dbRow in [Link])


{
string databaseName = dbRow["database_name"].ToString();

// Skip system databases for clarity


if ([Link]("information_schema",
[Link]) ||
[Link]("mysql",
[Link]) ||
[Link]("performance_schema",
[Link]) ||
[Link]("sys",
[Link]))
{
continue;
}

[Link]($"\n== Base de datos: {databaseName} ==");

try
{
// Temporarily change the connection's database to list
tables within it.
[Link](databaseName);

// Get all tables for the current database


DataTable tables = [Link]("Tables");

if ([Link] == 0)
{
[Link](" (Esta base de datos no tiene
tablas)");
continue;
}

foreach (DataRow tableRow in [Link])


{
string tableName = tableRow["TABLE_NAME"].ToString();
[Link]($"\n - Tabla: {tableName}");

// Get all columns for the current table


DataTable columns = [Link]("Columns",
new string[] { null, null, tableName, null });
foreach (DataRow columnRow in [Link])
{
string columnName =
columnRow["COLUMN_NAME"].ToString();
string dataType =
columnRow["DATA_TYPE"].ToString();

// Get column size if available (can be null for


some types)
object columnSizeObj =
columnRow["CHARACTER_MAXIMUM_LENGTH"];
string columnSize = columnSizeObj !=
[Link] ? [Link]() : "N/A";

[Link]($" - Campo: {columnName}


(Tipo: {dataType}, Tamaño: {columnSize})");
}
}
}
catch (Exception ex)
{
// Handle cases where you can't access a specific database
[Link]($" Error al acceder a la base de datos
'{databaseName}': {[Link]}");
}
}
}
}

3. Modifica la cadena de conexión: Reemplaza tu_contraseña_de_mysql con tu


contraseña real de MySQL.

Paso 4: Ejecutar el programa


1. En Visual Studio, presiona F5 o haz clic en el botón Ejecutar (la flecha verde) en la parte
superior.
2. Se abrirá una ventana de consola que mostrará la salida del programa.

Salida esperada
Si la conexión es exitosa, verás una salida en la consola similar a esta, que te muestra la estructura
de tus bases de datos:
Conexión exitosa a MySQL!

--- Bases de datos disponibles ---


- information_schema
- mysql
- performance_schema
- sys
- mi_base_de_datos
- login_db

--- Explorando tablas y campos ---

== Base de datos: mi_base_de_datos ==

- Tabla: productos
- Campo: id (Tipo: int, Tamaño: N/A)
- Campo: nombre (Tipo: varchar, Tamaño: 255)
- Campo: precio (Tipo: decimal, Tamaño: N/A)

- Tabla: clientes
- Campo: id (Tipo: int, Tamaño: N/A)
- Campo: nombre (Tipo: varchar, Tamaño: 100)
- Campo: email (Tipo: varchar, Tamaño: 255)

== Base de datos: login_db ==

- Tabla: users
- Campo: id (Tipo: bigint, Tamaño: N/A)
- Campo: username (Tipo: varchar, Tamaño: 50)
- Campo: password (Tipo: varchar, Tamaño: 255)
- Campo: enabled (Tipo: tinyint, Tamaño: N/A)
- Campo: failed_attempts (Tipo: int, Tamaño: N/A)
- Campo: account_locked (Tipo: tinyint, Tamaño: N/A)

Presiona cualquier tecla para salir...

Explicación del código


• using [Link];: Esta línea importa la librería que instalaste,
dándote acceso a clases como MySqlConnection y MySqlCommand.
• MySqlConnection connection = new
MySqlConnection(connectionString): Aquí creas un objeto de conexión. La
cadena de conexión es vital y debe incluir el servidor, el puerto, el usuario y la contraseña.
• [Link](): Establece la conexión física con el servidor de la base de datos.

• [Link]("Databases"): Esta es una de las funcionalidades más


potentes de [Link]. El método GetSchema te permite obtener información sobre la
estructura de la base de datos sin necesidad de escribir consultas SQL.
• "Databases": Devuelve una DataTable con todas las bases de datos.

• "Tables": Devuelve las tablas del esquema actual.

• "Columns": Devuelve las columnas de una tabla específica.

• using (MySqlConnection connection = ...): El bloque using es una


excelente práctica en C#. Asegura que la conexión se cierre y se elimine correctamente de la
memoria, incluso si ocurre un error.
• [Link](databaseName): Esta línea cambia el "contexto"
de la conexión para que puedas consultar las tablas dentro de una base de datos específica.
Archivos JSON en Python
Usaremos una lista de diccionarios para representar los productos, donde cada diccionario
contendrá el código, el precio y el stock. Guardaremos estos datos en un archivo de texto utilizando
el formato JSON, que es ideal para guardar estructuras de datos de Python de manera legible y fácil
de manejar.

Paso 1: Estructura de la lista de productos


Imagina que tus productos se ven así:
Python
productos = [
{"codigo": "P001", "nombre": "Laptop", "precio": 1200.50, "stock": 50},
{"codigo": "P002", "nombre": "Mouse", "precio": 25.00, "stock": 200},
{"codigo": "P003", "nombre": "Teclado", "precio": 60.75, "stock": 150}
]

Cada elemento en la lista es un diccionario que representa un producto con sus atributos.

Paso 2: Crear el programa en Python


Vamos a crear un script con dos funciones principales: una para guardar la lista en un archivo y
otra para leer la lista desde el mismo archivo.
Crea un archivo llamado gestion_productos.py y pega el siguiente código:

Python
import json
import os

def guardar_productos(lista_productos, nombre_archivo="[Link]"):


"""
Guarda una lista de productos en un archivo JSON.

Args:
lista_productos (list): La lista de diccionarios de productos.
nombre_archivo (str): El nombre del archivo donde se guardará la lista.
"""
try:
# Abrimos el archivo en modo escritura ('w')
# La codificación 'utf-8' asegura que los caracteres especiales se
guarden correctamente.
with open(nombre_archivo, 'w', encoding='utf-8') as archivo:
# Usamos [Link]() para escribir la lista en el archivo.
# indent=4 hace que el archivo sea más legible.
[Link](lista_productos, archivo, indent=4)
print(f"La lista de productos ha sido guardada en '{nombre_archivo}'
exitosamente.")
except IOError as e:
print(f"Error: No se pudo escribir en el archivo {nombre_archivo}.
Detalles: {e}")

def leer_productos(nombre_archivo="[Link]"):
"""
Lee una lista de productos desde un archivo JSON.
Args:
nombre_archivo (str): El nombre del archivo desde el cual se leerá la
lista.

Returns:
list: La lista de productos leída desde el archivo, o una lista vacía si
el archivo no existe o está vacío.
"""
# Verificamos si el archivo existe
if not [Link](nombre_archivo) or [Link](nombre_archivo) ==
0:
print(f"El archivo '{nombre_archivo}' no existe o está vacío. Retornando
una lista vacía.")
return []

try:
# Abrimos el archivo en modo lectura ('r')
with open(nombre_archivo, 'r', encoding='utf-8') as archivo:
# Usamos [Link]() para cargar la lista desde el archivo.
lista_leida = [Link](archivo)
print(f"La lista de productos ha sido leída desde '{nombre_archivo}'
exitosamente.")
return lista_leida
except [Link] as e:
print(f"Error: El archivo '{nombre_archivo}' no tiene un formato JSON
válido. Detalles: {e}")
return []
except IOError as e:
print(f"Error: No se pudo leer el archivo {nombre_archivo}. Detalles:
{e}")
return []

# --- Bloque de ejecución principal ---


if __name__ == "__main__":

# 1. Creamos una lista inicial de productos para guardar.


productos_iniciales = [
{"codigo": "A001", "nombre": "Celular", "precio": 850.99, "stock": 120},
{"codigo": "B002", "nombre": "Smart TV", "precio": 1500.00, "stock":
45},
{"codigo": "C003", "nombre": "Refrigeradora", "precio": 2100.50,
"stock": 30}
]

# --- Guardamos la lista en un archivo ---


print("--- Guardando lista de productos ---")
guardar_productos(productos_iniciales)

# --- Leemos la lista desde el archivo ---


print("\n--- Leyendo lista de productos ---")
productos_leidos = leer_productos()

# --- Mostramos los productos leídos para verificar ---


if productos_leidos:
print("\nProductos cargados desde el archivo:")
for producto in productos_leidos:
print(f"Código: {producto['codigo']}, Nombre: {producto['nombre']},
Precio: S/.{producto['precio']:.2f}, Stock: {producto['stock']}")

# 2. Modificamos la lista leída y la volvemos a guardar


print("\n--- Modificando la lista y guardándola de nuevo ---")
productos_leidos.append({"codigo": "D004", "nombre": "Audífonos",
"precio": 150.00, "stock": 80})
productos_leidos[0]['stock'] = 100 # Actualizamos el stock del primer
producto

guardar_productos(productos_leidos)

# Leemos de nuevo para verificar los cambios


print("\n--- Leyendo la lista modificada para verificar ---")
productos_actualizados = leer_productos()
if productos_actualizados:
print("\nProductos con cambios:")
for producto in productos_actualizados:
print(f"Código: {producto['codigo']}, Nombre:
{producto['nombre']}, Precio: S/.{producto['precio']:.2f}, Stock:
{producto['stock']}")

Paso 3: Ejecutar el programa


1. Abre tu terminal o línea de comandos.
2. Navega hasta la carpeta donde guardaste el archivo gestion_productos.py.
3. Ejecuta el script:
Bash
python gestion_productos.py

¿Qué hace el programa?


1. Guarda la lista de productos:
• La función guardar_productos recibe una lista y un nombre de archivo.

• Usa with open(...) para manejar automáticamente la apertura y el cierre del


archivo.
• [Link]() convierte la lista de Python en una cadena de texto en formato
JSON y la escribe en el archivo. El formato JSON es muy legible, lo que te permite
abrir el archivo [Link] y ver los datos en un formato estructurado.

2. Lee la lista de productos:


• La función leer_productos verifica si el archivo existe. Si no, retorna una lista
vacía para evitar errores.
• Usa [Link]() para leer el contenido del archivo y lo convierte de nuevo en
una lista de Python (una lista de diccionarios, en este caso).
3. Ejecución de prueba (if __name__ == "__main__":):

• Este bloque de código solo se ejecuta cuando el script es el programa principal.


• Primero, crea una lista de productos y la guarda en el archivo [Link].

• Luego, lee el contenido del archivo y lo muestra.


• Finalmente, le agrega un producto nuevo, modifica el stock de uno existente y vuelve
a guardar la lista actualizada, demostrando cómo puedes editar y guardar los datos
nuevamente.

Ejemplo de contenido del archivo [Link]


Después de la primera ejecución, si abres el archivo [Link] en un editor de texto,
verás algo como esto:
JSON
[
{
"codigo": "A001",
"nombre": "Celular",
"precio": 850.99,
"stock": 120
},
{
"codigo": "B002",
"nombre": "Smart TV",
"precio": 1500.0,
"stock": 45
},
{
"codigo": "C003",
"nombre": "Refrigeradora",
"precio": 2100.5,
"stock": 30
}
]
Grabar y leer archivos de texto en Python

Paso 1: Grabar datos en un archivo de texto


Para grabar datos en un archivo, necesitas dos cosas: el nombre del archivo y el contenido que
quieres guardar. Python usa la función open() para abrir el archivo y la función write() para
escribir en él.
Crea un archivo de Python llamado grabar_leer_archivo.py y añade el siguiente código.

Python
def grabar_archivo(nombre_archivo, contenido):
"""
Graba el contenido dado en un archivo de texto.
Si el archivo no existe, lo crea. Si existe, lo sobrescribe.

Args:
nombre_archivo (str): El nombre del archivo a crear/sobrescribir.
contenido (str): El texto que se va a guardar en el archivo.
"""
try:
# 'w' significa modo de escritura ('write').
# Si el archivo existe, 'w' lo borra y empieza de cero.
# Si no existe, lo crea.
with open(nombre_archivo, 'w', encoding='utf-8') as archivo:
[Link](contenido)
print(f"Los datos han sido grabados exitosamente en
'{nombre_archivo}'.")
except IOError as e:
# Captura cualquier error al escribir en el archivo (ej. permisos).
print(f"Error al grabar el archivo: {e}")

# --- Uso de la función para grabar ---


# Define el nombre del archivo
nombre_del_archivo = "mi_primer_archivo.txt"

# Define el contenido a guardar


texto_a_guardar = """
¡Hola, Mundo!
Esta es la primera línea que guardo.
Esta es la segunda línea.
Podemos guardar varias líneas de texto.
¡Qué fácil es usar Python para esto!
"""

# Llama a la función para grabar


grabar_archivo(nombre_del_archivo, texto_a_guardar)

Explicación del código para grabar:


• open(nombre_archivo, 'w', ...): Esta función abre el archivo en modo de
escritura ('w'). Si el archivo ya existe, su contenido se borra y se reemplaza por lo nuevo
que escribas.
• with open(...) as archivo:: Esta estructura es una de las mejores prácticas en
Python. Garantiza que el archivo se cierre automáticamente una vez que terminas de
trabajar con él, incluso si ocurre un error. Esto evita problemas de corrupción de archivos.
• [Link](contenido): Este método escribe la cadena de texto (contenido)
en el archivo.
• encoding='utf-8': Es crucial para manejar caracteres especiales como tildes, la "ñ" y
otros símbolos sin problemas.

Paso 2: Leer datos desde el mismo archivo


Ahora que el archivo existe, podemos crear una función para leer su contenido.
Añade la siguiente función al mismo archivo grabar_leer_archivo.py:

Python
def leer_archivo(nombre_archivo):
"""
Lee y devuelve el contenido de un archivo de texto.

Args:
nombre_archivo (str): El nombre del archivo a leer.

Returns:
str: El contenido del archivo, o None si el archivo no existe.
"""
try:
# 'r' significa modo de lectura ('read').
with open(nombre_archivo, 'r', encoding='utf-8') as archivo:
# [Link]() lee todo el contenido del archivo como una sola
cadena.
contenido_leido = [Link]()
return contenido_leido
except FileNotFoundError:
# Captura el error si intentas leer un archivo que no existe.
print(f"Error: El archivo '{nombre_archivo}' no fue encontrado.")
return None
except IOError as e:
# Captura otros errores de lectura.
print(f"Error al leer el archivo: {e}")
return None

# --- Uso de la función para leer ---


# Llama a la función para leer
print("\n--- Leyendo el contenido del archivo ---")
contenido_recuperado = leer_archivo(nombre_del_archivo)

# Muestra el contenido si la lectura fue exitosa


if contenido_recuperado is not None:
print("Contenido del archivo:")
print(contenido_recuperado)

Explicación del código para leer:


• open(nombre_archivo, 'r', ...): Abre el archivo en modo de lectura ('r').

• [Link](): Lee todo el contenido del archivo de una vez y lo guarda en una
variable como una cadena de texto.
• try...except FileNotFoundError: Es fundamental para manejar errores. Si el
archivo que intentas leer no existe, el programa no fallará, sino que mostrará un mensaje de
error claro y continuará su ejecución.

Ejecución final del programa completo


Si pones todo el código junto en el archivo grabar_leer_archivo.py, así es como se vería el
programa completo y su ejecución:
Python
import os # Importamos el módulo 'os' para verificar si el archivo existe

# --- Función para grabar ---


def grabar_archivo(nombre_archivo, contenido):
"""
Graba el contenido dado en un archivo de texto.
Si el archivo no existe, lo crea. Si existe, lo sobrescribe.
"""
try:
with open(nombre_archivo, 'w', encoding='utf-8') as archivo:
[Link](contenido)
print(f"Los datos han sido grabados exitosamente en
'{nombre_archivo}'.")
except IOError as e:
print(f"Error al grabar el archivo: {e}")

# --- Función para leer ---


def leer_archivo(nombre_archivo):
"""
Lee y devuelve el contenido de un archivo de texto.
"""
try:
with open(nombre_archivo, 'r', encoding='utf-8') as archivo:
contenido_leido = [Link]()
return contenido_leido
except FileNotFoundError:
print(f"Error: El archivo '{nombre_archivo}' no fue encontrado.")
return None
except IOError as e:
print(f"Error al leer el archivo: {e}")
return None

# --- Bloque principal del programa ---


if __name__ == "__main__":

# 1. Grabar datos
nombre_del_archivo = "mi_primer_archivo.txt"
texto_a_guardar = "Esta es la primera línea.\nEsta es la segunda línea.\n"

grabar_archivo(nombre_del_archivo, texto_a_guardar)

# 2. Leer datos
print("\n--- Leyendo el contenido del archivo ---")
contenido_recuperado = leer_archivo(nombre_del_archivo)

# 3. Mostrar el contenido leído


if contenido_recuperado is not None:
print("\nContenido leído del archivo:")
print(contenido_recuperado)

# Opcional: Grabar con modo de adición ('a')


print("\n--- Añadiendo más contenido al archivo ---")

# 'a' significa modo de adición ('append').


# Si el archivo existe, añade el nuevo contenido al final.
with open(nombre_del_archivo, 'a', encoding='utf-8') as archivo_append:
archivo_append.write("Esta es una nueva línea que se añadió al final.
\n")
print("Se ha añadido más texto al archivo.")

# Leer el archivo de nuevo para ver los cambios


print("\n--- Leyendo el archivo actualizado ---")
contenido_actualizado = leer_archivo(nombre_del_archivo)
if contenido_actualizado is not None:
print("\nContenido actualizado del archivo:")
print(contenido_actualizado)

Al ejecutarlo, verás en la consola cómo se guarda el texto, luego se lee y se muestra, y finalmente se
añade más texto para que veas cómo funciona el modo de adición.
¡Así de simple es manejar archivos de texto en Python! ¿Te gustaría aprender a manejar archivos
con datos más complejos, como la lista de productos que vimos antes, usando JSON?
Crear un programa en Python que hable lo que escribas por teclado. Para lograr esto, usaremos una
librería que convierte texto a voz (Text-to-Speech o TTS).
La librería más recomendada y fácil de usar para esta tarea es pyttsx3. Funciona sin conexión a
internet, lo cual es una gran ventaja.

Paso 1: Instalar la librería pyttsx3


Primero, necesitas instalar la librería en tu entorno de Python. Abre tu terminal o línea de comandos
y ejecuta el siguiente comando:
Bash
pip install pyttsx3

También podrías necesitar instalar un motor de voz. En Windows, por lo general, viene integrado.
En Linux (Ubuntu/Debian), puedes instalarlo con:
Bash
sudo apt-get update && sudo apt-get install espeak

Paso 2: Crear el programa en Python


Ahora, crea un archivo de Python, por ejemplo, [Link], y pega el siguiente código. Este
programa te pedirá que escribas algo y luego lo dirá en voz alta.
Python
import pyttsx3

def configurar_voz():
"""
Configura el motor de voz de pyttsx3 para ajustar la velocidad y el volumen.

Returns:
object: El objeto del motor de voz configurado.
"""
engine = [Link]()

# Opcional: Configurar la velocidad de la voz (palabras por minuto)


velocidad = 150 # Valor por defecto: 200
[Link]('rate', velocidad)

# Opcional: Configurar el volumen (de 0.0 a 1.0)


volumen = 0.9 # Valor por defecto: 1.0
[Link]('volume', volumen)

# Opcional: Cambiar la voz (si hay varias disponibles)


# Puedes obtener la lista de voces disponibles con
[Link]('voices')
# Por ejemplo, para usar una voz masculina:
# voices = [Link]('voices')
# if len(voices) > 1:
# [Link]('voice', voices[0].id) # Cambia a voices[1].id para
otra voz

return engine

def hacer_hablar(motor, texto):


"""
Usa el motor de voz para decir el texto proporcionado.

Args:
motor (object): El objeto del motor de voz.
texto (str): El texto que se va a decir en voz alta.
"""
[Link](texto)
[Link]() # Bloquea hasta que la voz termine de hablar

def main():
"""
Función principal para la interacción con el usuario.
"""
# Configura el motor de voz una sola vez al inicio
motor_de_voz = configurar_voz()

print("¡Programa de texto a voz!")


print("Escribe algo y presiona Enter para que el programa lo diga.")
print("Escribe 'salir' para terminar el programa.")

# Bucle infinito para que el programa siga pidiendo texto


while True:
try:
# Lee la entrada del usuario desde el teclado
texto_ingresado = input("Escribe aquí: ")

# Convierte la entrada a minúsculas para verificar el comando de


salida
if texto_ingresado.lower() == 'salir':
print("¡Adiós!")
break # Sale del bucle y termina el programa

# Si el texto no está vacío, lo hace hablar


if texto_ingresado.strip(): # .strip() quita espacios en blanco al
inicio y final
hacer_hablar(motor_de_voz, texto_ingresado)

except Exception as e:
print(f"Ocurrió un error: {e}")
print("Saliendo del programa...")
break

# Asegura que el código se ejecute solo cuando el script se inicia directamente


if __name__ == "__main__":
main()

Paso 3: Ejecutar el programa


1. Abre tu terminal o línea de comandos.
2. Navega hasta la carpeta donde guardaste el archivo [Link].

3. Ejecuta el script con el siguiente comando:


Bash
python [Link]

El programa te pedirá que escribas algo. Escribe lo que quieras, presiona Enter, y ¡escucharás tu
texto en voz alta! Para salir del programa, simplemente escribe salir y presiona Enter.
¿Cómo funciona el código?
• import pyttsx3: Importa la librería que usaremos para la funcionalidad de texto a voz.

• [Link](): Inicializa el motor de voz TTS. Es como encender el sistema de voz.

• [Link]('rate', velocidad): Te permite controlar la velocidad


de la voz. Un valor más bajo la hace más lenta y viceversa.
• [Link]('volume', volumen): Te permite ajustar el volumen de la
voz.
• [Link](texto): Le indica al motor de voz qué texto debe preparar para decir.

• [Link](): Este es un comando crucial. Le dice al programa que espere a


que el texto se termine de reproducir antes de continuar con la siguiente línea de código. Sin
este comando, el programa podría terminar antes de que la voz hable.
• input("Escribe aquí: "): Es una función de Python que detiene el programa y
espera a que el usuario escriba algo por teclado y presione Enter.

• while True:: Crea un bucle infinito que permite que el programa siga pidiendo texto
hasta que el usuario decida salir.
• if texto_ingresado.lower() == 'salir':: Verifica si el usuario quiere
terminar el programa. Usamos .lower() para que funcione tanto si el usuario escribe
salir como SALIR o Salir.

También podría gustarte