0% encontró este documento útil (0 votos)
5 vistas124 páginas

Curso de Programación en C y Python

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)
5 vistas124 páginas

Curso de Programación en C y Python

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

Notas del Curso de Computación

Raúl A. Espejel Morales


Facultad de Ciencias,
U.N.A.M.

30 de enero de 2023
Computación

R. Espejel 2
Índice general

1. Programación en C 5
1.1. Hola Mundo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2. Modificadores de flujo. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.1. Ciclo for. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.2. Ciclo while y do - while. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.2.3. Estructura condicional if. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.2.4. Ciclos anidados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.3. Sumatorias. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.4. Método de Newton-Raphson. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
1.5. Funciones en C. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.6. Simulación de Experimentos con Variables Aleatorias. . . . . . . . . . . . . . . . . . 38
1.7. Arreglos en C. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
1.8. Matrices en C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

2. Programación en Python 57
2.1. Inicio en Python. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
2.2. Listas y for. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
2.3. if y while en Python Simulaciones con variables aleatorias . . . . . . . . . . . . . . 65
2.4. Juego adivina mi número. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
2.5. Reforzamiento. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
2.6. Más listas y Juego del Ahorcado. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
2.7. Matrices en Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
2.8. Gráficas con Python. MatPlotLib . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
2.9. Funciones y recursividad. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
2.10. Solución de Ecuaciones Diferenciales. . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
2.11. Solución de Ecuaciones Diferenciales. Dinámica . . . . . . . . . . . . . . . . . . . . . 108
2.12. Simulación, animación y visualización en 3D . . . . . . . . . . . . . . . . . . . . . . . 115

3
Computación

R. Espejel 4
Capı́tulo 1

Programación en C

1.1. Hola Mundo.

Empezaremos, como es costumbre, por un primer programa que imprime el mensaje Hola Mundo
en una pantalla de comandos.

Utilizamos CodeBlocs o DevC para escribir el siguiente programa. Para comenzar a editar un
nuevo programa en DevC seleccionamos File, New y Source file (Archivo, Nuevo, Archivo Fuente).

Figura 1.1: CodeBlocks.

5
Computación

Figura 1.2: DevC.

#include<stdio.h>
int main(){
printf("Hola Mundo\n");
}

Grábalo en una carpeta creada exclusivamente para tus programas, con el nombre hola.c
usando Save as.
Este programa está escrito en lenguaje C, que es un lenguaje entendible por humanos, pero
para poder haacer que la computadora lo interprete y ejecute, necesitamos compilarlo. Compilar
significa traducir el código en C, a un código en lenguaje de máquina, que ejecuta el procesador de
la computadora.
Para hacer el proceso de compilación, selecciona Execute y Compile&Run si usas DevC o Build
y Build and run, si usas CodeBlocks. Ası́ se creará y ejecutará el archivo [Link].

Figura 1.3: Compilación y ejecución del programa (CodeBlocks).

R. Espejel 6
Computación

Figura 1.4: Compilación y ejecución del programa (DevC).

Explicaremos las partes del programa anterior. La primer lı́nea, #include <stdio.h> le indica al
compilador que usaremos ciertas instrucciones o funciones que están definidas en archivos externos
a nuestro programa. En este caso ese archivo es stdio.h. La palabra include es una directiva del
preprocesador y el o los archivos .h que se incluyen se denominan librerı́as.

La lı́nea siguiente, int main (), indica que se defiirá la función principal, cuyas instrucciones es-
tarán dentro de las llaves “{” y “}”, y forman el conjunto de instrucciones de la función principal.
Un programa en C tiene al menos una función, la función principal, pero puede tener más funciones
como veremos en secciones posteriores.

La función printf indica al compilador que muestre el mensaje Hola Mundo seguido por un salto
de lı́nea, representado por el identificador \n.

Ası́ mismo, podemos mostrar mensajes que contengan valores de variables, como se verá más
adelante.

Las variables que usamos en un programa en C tienen un nombre y un tipo, que indica el tipo
de datos que se almacenarán en la variable.

Para crear una variable escribiremos primero la palabra que hace referencia al tipo de variable
y luego el nombre de la variable. A esto se le llama declarar una variable. La forma general de las
declaraciones es:

int a;
float x;

Con lo que habremos creado una variable a que almacenará valores enteros y una variable x que
almacenará valores de punto flotante, que es como se modelan internamente, en el procesador, los
números reales. Cabe mencionar que existen más tipos de variables, sin embargo escapan al alcance
del curso para el cual se presenta este texto.

Consideremos el siguiente programa, en el cual se numeran las lı́neas de la función principal main()
en color rojo. Estos números no forman parte del programa:

7 R. Espejel
Computación

#include<stdio.h>
01 int main(){
02 int a;
03 float x;
04 a = 5;
05 x = 3.25;
06 printf("El valor de a es %d y el de x es %f\n", a, x);
}

El cual, al compilarse y ejecutarse, mostrará el mensaje:

El valor de a es 5 y el de x es 3.750000

En las lı́neas 02 y 03, se crean, o declaran, las variables a y x que almacenarán números enteros y
de punto flotante, respectivamente. En las lı́neas 04 y 05, se les asignan valores compatibles con ti-
po de variable, y finalmente, en la lı́nea 06 se muestra el mensaje que contiene el valor de las mismas.

Nótese que en la función printf, se han incluido los identificadores %d y %f para indicar el lugar
dónde aparecerán los valores de las variables enteras y flotantes respectivamente, respetando su
orden, es decir, el primer identificador se sustituirá por el valor de la primer variable que apare-
ce después del mensaje, el segundo identificador se sustituirá por el valor de la segunda variable, etc:

printf("El valor de a es %d y el de x es %f\n", a, x);

Capturemos ahora el siguiente programa, en el cual se declaran tres variables flotantes:

#include<stdio.h>
int main(){
float b,h,a;
b = 5.0;
h = 3.0;
a = b*h/2;
printf("El area de un triangulo con base %f y altura %f es %f\n" b,h,a);
}

El cual, al compilarse y ejecutarse, mostrará el mensaje:

El area de un triangulo con base 5.000000 y altura 3.000000 es 7.500000

En la lı́nea marcada en rojo se le está asignando a la variable a el valor resultante al evaluar el


producto de b por h dividido entre dos, para calcular el área del triángulo respectivo.

Ahora bien, si deseamos que se le soliciten al usuario los datos del triángulo, empleamos la función
scanf que recibe como argumento el identificador del tipo de variable cuyo valor se consulta y un
apuntador a la variable. Por ejemplo, para solicitar el valor de la variable b, que es de tipo flotante,
la sintaxis correcta serı́a:

scanf(" %f",&b);

R. Espejel 8
Computación

Al ejecutar esta función, se detendrá la ejecución del programa para que el usuario introduzca un
valor, seguido de la tecla Enter. De este modo, la variable b tomará ese valor. Ası́, el programa
quedarı́a como sigue:

#include<stdio.h>
int main(){
float b,h,a;
printf("Dame el valor de la base ");
scanf(" %f",&b);
printf("Dame el valor de la altura ");
scanf(" %f",&h);
a = b*h/2
print("El area de un triangulo con base %f y altura %f es %f", b,h,a);
}

9 R. Espejel
Computación

Ejercicios.
Ejercicio 1. Elabora un programa para resolver el siguiente problema, los datos vA , vB y d serán
consultados al usuario:
Dos vehı́culos A y B salen uno al encuentro del otro, viajando en lı́nea recta, desde dos
ciudades separadas una distancia d (en km), con velocidades de vA y vB respectivamente
(ambas en km/h). El programa debe mostrar la distancia xA (en metros) donde se dará
el choque respecto al punto de partida de A, considerando que salen al mismo tiempo.
Ejercicio 2. Elabora un programa que calcule el peso de una esfera de radio r y densidad p, estos
datos son consultados al usuario. (Usa el sistema de unidades MKS).
Ejercicio 3. En una bicicleta, al girar con los pedales el engrane 1 (con radio r1 ) un ángulo θ1 , la
cadena recorrerá una longitud l1 = θ1 r1 a partir del punto P . Ya que la cadena es
inextensible, esta misma longitud de cadena pasará por el punto Q, haciendo girar el
engrane 2 (con radio r2 ) un ángulo θ2 . Entonces

θ1 r1 = θ2 r2
r1
θ2 = θ1
r2
Este mismo ángulo es el que girará la rueda de radio r3 , haciendo avanzar la bicicleta
una distancia igual a la longitud de arco l2 = θ2 r3 . Elabora un programa para calcular la
distancia que recorrerá una bicicleta al dar n vueltas a los pedales (nota que θ1 = 2π n).
Tanto n, como los radios de los engranes y la rueda son solicitados al usuario (solicita
los radios en metros).

r3

r1
r2

Q
P

Ejercicio 4. Elabora un programa que calcule la altura máxima de un tiro vertical que inicia desde
el suelo. La velocidad inicial es solicitada al usuario (Usa el sistema de unidades MKS).
Hint: Despeja t de v = v0 − gt para calcular el tiempo en segundos que tarda el
móvil en llegar a su altura máxima (cuando v = 0), luego sustituye ese tiempo en
y = y0 + v0 t − 12 gt2 .
Ejercicio 5. Elabora un programa que calcule los ángulos (en grados) de las manecillas del reloj
(respecto a la vertical, es decir, a las 12:00 serı́an cero grados) para una hora introducida
por el usuario en horas y minutos, en formato de 12 hrs. (Nota que el ángulo de la
manecilla horaria, por ejemplo, a las 03:00 no es el mismo que para las 03:30).
Hint: Para el ángulo de la manecilla de los minutos, considera que, por cada minuto,
ésta avanza 360◦ /60 = 6◦ , y para la de las horas, la manecilla avanza 360◦ /12 = 30◦ ,
por cada hora, pero además avanza (360◦ /12)/60 = 0.5◦ por minuto.

R. Espejel 10
Computación

1.2. Modificadores de flujo.

Como hemos visto, un programa en C como el siguiente, muestra en la pantalla la palabra


“Hola”, seguida de un salto de lı́nea, luego se muestra en la pantalla la palabra “Mundo”:

int main(){
printf("Hola\n");
printf("Mundo\n");
}

Es necesario resaltar que hasta ahora hemos implementado programas donde las lı́neas se ejecu-
tan en orden. En el programa que sigue aparecen las lı́neas de la función principal main() numeradas
en color rojo, estos números no forman parte del programa.

00 int main(){
01 printf("Hola\n");
02 printf("Mundo\n");
00 }

Ası́, al iniciar el programa, se ejecuta la lı́nea 01, seguida de la 02, y termina el programa al no
haber más lı́neas de código.
Si quisiéramos mostrar este mensaje un cierto número de veces en la pantalla, por ejemplo 3,
podrı́amos incluir de forma repetida estas lı́neas:

00 int main(){
01 printf("Hola\n");
02 printf("Mundo\n");
03 printf("Hola\n");
04 printf("Mundo\n");
05 printf("Hola\n");
06 printf("Mundo\n");
00 }

Sin embargo, esto es muy poco práctico, ya que aumenta de forma innecesaria la longitud del
programa, además de que podrı́a darse el caso de fuera necesario repetir las lı́neas 100, 1000, 10000
o más veces, o repetirlas mientras se cumpla una cierta condición, por lo que introduciremos las
estructuras llamadas modificadores de flujo, las cuales permiten controlar el flujo del programa, es
decir, el orden en que se ejecutan las lı́neas. Esto permitirá hacer repeticiones de ciertas lı́neas, ası́
como condicionar su ejecución.

11 R. Espejel
Computación

1.2.1. Ciclo for.


El primer modificador de flujo que abordaremos es la estructura formada por la instrucción for,
la cual nos permite repetir un conjunto de instrucciones un número determinado de veces:

00 main(){
01 int i;
02 for (i=1;i<=5;i++){
01 printf("Hola\n");
02 printf("Mundo\n");
00 }
00 }

Ası́, en este caso, las lı́neas marcadas en azul y que están delimitadas por las llaves “{” y “}”
marcadas en verde, se repiten 5 veces, y el orden en que se ejecutan es 01, 02, 01, 02, etc. Mostrando
un mensaje como el siguiente:
Hola
Mundo
Hola
Mundo
Hola
Mundo
Hola
Mundo
Hola
Mundo

Noten que declaramos una variable entera i que forma parte de la estructura de la instrucción
for y hace la función de contador, es decir, esta variable “lleva la cuenta” de cuántas veces se ha
repetido el ciclo, el cual tiene tres partes:

for(i=1;i<=5;i++)

La primera, i=1, es una instrucción de asignación que indica en qué número comenzamos a
contar, en este caso, comenzamos en 1. La segunda, i<=5, es una condición que indica cuándo
parar, en este caso el ciclo se ejecuta mientras se cumpla que la variable i sea menor o igual
que 5. La tercera parte, i++, indica que la variable que funciona como contador, se incrementa en
uno después de cada repetición. La notación es la siguiente:

++ incrementa en 1

-- decrementa en 1

+=n incrementa en n

-=n decrementa en n

Por ejemplo, i-=3 decrementa a i en 3 después de cada repetición.

R. Espejel 12
Computación

De esta forma, la estructura for(i=1;i<=5;i++), se puede leer como sigue: “Las lı́neas dentro de
esta estructura se repetirán mientras i sea menor o igual a 5, comenzando a contar desde desde uno,
y contando de uno en uno”. Cabe mencionar que la variable (ı́ndice) que se incluye en la estructura
puede ser entera o flotante, ası́ como los incrementos (es decir, podemos contar de 0.1 en 0.1 si el
programa lo requiere).

13 R. Espejel
Computación

El contador del ciclo for, en este caso, la variable i, que se incrementa en cada repetición, puede
usarse para realizar algún cálculo, o simplemente visualizarla como parte de un mensaje de texto,
como en el siguiente ejemplo:

main(){
int i;
for (i=1;i<=5;i++){
printf("Estoy en la repeticion %d\n",i);
}
}

Estoy en la repeticion 1
Estoy en la repeticion 2
Estoy en la repeticion 3
Estoy en la repeticion 4
Estoy en la repeticion 5

Podemos emplear la función scanf para configurar la instrucción for:

main(){
int i,n;
printf("Cuantas repeticiones quieres? ");
scanf(" %d",&n);
for (i=1;i<=n;i++){
printf("Estoy en la repeticion %d\n",i);
}
}

Cuantos ciclos quieres? 4


Estoy en la repeticion 1
Estoy en la repeticion 2
Estoy en la repeticion 3
Estoy en la repeticion 4

O bien, si queremos contar en orden inverso:

main(){
int i,n;
printf("Cuantas repeticiones quieres? ");
scanf(" %d",&n);
for (i=n;i>=1;i--){
printf("Estoy en la repeticion %d\n",i);
}
}

R. Espejel 14
Computación

Un ejemplo podrı́a ser un programa que muestre una tabla de multiplicar, por ejemplo, la tabla
del 7:

main(){
int i,n;
for (i=1;i<=10;i++){
n = 7*i;
printf("7 x %d = %d \n",i,n);
}
}

Veamos algunos ejemplos más de la estructura:

for(i=1;i<=5;i++)

Las lı́neas dentro de esta estructura se repetirán


mientras i sea menor o igual a 5, comenzando a contar
desde desde uno, y contando de uno en uno.
Los valores de i en cada repetición serán: i = 1, 2, 3, 4, 5

for(i=4;i<=10;i++)

Las lı́neas dentro de esta estructura se repetirán


mientras i sea menor o igual a 10, comenzando a contar
desde desde 4, y contando de uno en uno.
Los valores de i en cada repetición serán:
i = 4, 5, 6, 7, 8, 9, 10

for(i=7;i<10;i++)

Las lı́neas dentro de esta estructura se repetirán


mientras i sea menor a 10, comenzando a contar desde
desde 7, y contando de uno en uno.
Los valores de i en cada repetición serán: i = 7, 8, 9

for(i=3;i<15;i+=2)

Las lı́neas dentro de esta estructura se repetirán


mientras i sea menor a 15, comenzando a contar desde
desde 3, y contando de dos en dos.
Los valores de i en cada repetición serán:
i = 3, 5, 7, 9, 11, 13

15 R. Espejel
Computación

Resolvamos ahora el siguiente ejercicio:

Elabora un programa que muestre las coordenadas de las posiciones de los números de la
caratula de un reloj. Considera que el centro de la caratula está en el origen del sistema de
coordenadas y que el radio de la caratula es de 7 cm.

Bien, ya que la caratula de un reloj tiene 12 números, es lógico pensar que necesitamos implementar
un ciclo for que realice 12 repeticiones; una opción para la estructura serı́a:

for(i=1;i<=12;i++)

en este caso, los valores de i en cada repetición serı́an i = 1, 2, 3, 4, 5, . . . , 12.


O bien:

for(i=0;i<12;i++)

que generarı́a los valores para i en cada repetición i = 0, 1, 2, 3, 4, . . . , 11.

Si recordamos que el ángulo que existe entre un número y otro de la caratula es de 2π/12 =
π/6 radianes, nos podemos plantear entonces, que la primera meta para resolver el problema sea
desarrollar un ciclo que genere los valores de los ángulos para cada número, es decir, si empezamos
por la posición del número 3, los ángulos serı́an:

π π π π
0, 1 , 2 , 3 , . . . , 11
6 6 6 6
de modo que serı́a más conveniente usar la segunda estructura. El programa preliminar serı́a:

#include<stdio.h>
int main(){
int i;
float t;
for (i=0;i<12;i++){
t = i*3.1416/6;
printf("angulo = %f \n",t);
}
}

Ahora, recordando que el radio de la caratula es 7cm, podemos convertir esas coordenadas
polares a rectangulares usando:

x = r cos(θ)
y = r sin(θ)

R. Espejel 16
Computación

Para usar las funciones seno y coseno, es necesaria la librerı́a math.h, el programa final serı́a:

#include<stdio.h>
#include<math.h>
int main(){
int i;
float t,x,y;
printf("Las coordenadas son: \n")
for (i=0;i<12;i++){
t = i*3.1416/6.0;
x = 7*cos(t);
y = 7*sin(t);
printf("( %f, %f) \n",x,y);
}
printf("Fin del programa \n") }

Nota que la lı́nea donde se usa la funcion printf para mostrar el mensaje Las coordenadas son:
está fuera del ciclo for, ya que no requerimos que se repita, lo mismo para el mensaje Fin del
programa.

1.2.2. Ciclo while y do - while.


Otro ciclo es el while. En este caso, se repite el conjunto de instrucciones mientras se cumpla
una condición:

main(){
int respuesta;
respuesta=1;
while (respuesta==1){
printf("Quieres que continue el ciclo (1=si, 0=no) ");
scanf(" %d",&respuesta);
}
}

Quieres que continue el ciclo (1=si, 0=no) 1


Quieres que continue el ciclo (1=si, 0=no) 1
Quieres que continue el ciclo (1=si, 0=no) 1
Quieres que continue el ciclo (1=si, 0=no) 0

o bien:

main(){
int respuesta;
do{
printf("Quieres que continue el ciclo (1=si, 0=no) ");

17 R. Espejel
Computación

scanf(" %d",&respuesta);
}
while (respuesta==1);
}

Quieres que continue el ciclo (1=si, 0=no) 1


Quieres que continue el ciclo (1=si, 0=no) 1
Quieres que continue el ciclo (1=si, 0=no) 1
Quieres que continue el ciclo (1=si, 0=no) 0

Nota que es este caso no es necesario dar un valor previo a la variable respuesta para forzar la
entrada al ciclo, ya que aquı́ se evalúa la condición al final. Cabe mencionar que la conveniencia
de usar una u otra estructura (while o do-while) dependerá de la aplicación especı́fica que se
implemente.

1.2.3. Estructura condicional if.


Es posible condicionar la ejecución de ciertas lı́neas mediante la instrucción if, como en el
ejemplo:

main(){
int a,b;
a = 5;
b = 8;
if(b>a){
printf("La condición se cumple\n");
}
printf("FIN\n");
}

La condición se cumple
FIN

También puedes incluir operadores lógicos OR y AND como ∥ y && respectivamente:

main(){
int a,b;
a = 5;
b = 8;
c = 2;
if(b>a && c<a){
printf("La condición se cumple\n");
}
}

R. Espejel 18
Computación

La condición se cumple

main(){
int a,b;
a = 5;
b = 8;
c = 2;
if(b==8 ∥ a==0){
printf("La condición se cumple\n");
}
}

La condición se cumple

Puedes agregar un bloque de instrucciones que se ejecutarán si no se cumple la condición del


if:

main(){
int a,b;
a = 15;
b = 8;
if(b>a){
printf("La condición se cumple\n");
}
else{
printf("La condición no se cumple\n");
}
}

La condición no se cumple

19 R. Espejel
Computación

Ejercicios. Ciclos en C
Ejercicio 1. Implementa el ejemplo de la tabla de multiplicar. El programa debe consultar al usuario
un número y mostrar la tabla de multiplicar correspondiente (del 1 al 10 como en el
ejemplo).

Ejercicio 2. Elabora un programa que genere y muestre los primeros n elementos de la sucesión:

{1, 2, 4, 7, 11, 16, 22, . . .},


donde n es un número solicitado al usuario.

Ejercicio 3. En matemáticas, la sucesión o serie de Fibonacci es la siguiente sucesión de números


naturales:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610 . . .

La sucesión comienza con los números 0 y 1, y a partir de estos, cada término es la


suma de los dos anteriores. Elabora un programa que muestre los primeros n términos
de la serie, considera que el usuario siempre dará n > 2.

Ejercicio 4. Elabora un programa que muestre las coordenadas x, y de los vértices de un polı́gono
regular, centrado en el origen, de N lados de longitud d. Tanto N como d son datos
solicitados al usuario.

Hint: Considera que los vértices del polı́gono estarán dis- Q


tribuidos cada 2π/N radianes sobre una circunferencia de
radio r, y que el primer vértice está en la coordenada (r, 0). d
2 P
Entonces, del triángulo OP Q se obtiene que: r
d
2π θ
 
θ d 2
r sin = , con θ = , (r, 0)
2 2 N r
O
de donde puedes obtener r.

Ejercicio 5. Elabora un programa que muestre las tablas de multiplicar desde la del 2 hasta la del 5.

R. Espejel 20
Computación

1.2.4. Ciclos anidados.

Extendamos un poco las aplicaciones de los ciclos. Notemos que éstos puede hacer repeticiones
de las instrucciones que contienen, y estas pueden ser, a su vez otros ciclos, por ejemplo:

#include<stdio.h>
int main(){
int i,j;
for (i=1;i<=5;i++){
for (j=1;j<=3;j++){
printf("El valor de j es %d, y el de i es %d \n",j,i);
}
}
}

Noten que ahora hay un ciclo for interior, marcado en verde, el cual repite la función printf
tres veces. Sin embargo, este conjunto de instrucciones se encuentra dentro de otro ciclo for exterior,
marcado en rojo. De modo que este programa mostrarı́a lo siguiente en pantalla:

El valor de j es 1, y el de i es 1
El valor de j es 2, y el de i es 1
El valor de j es 3, y el de i es 1
El valor de j es 1, y el de i es 2
El valor de j es 2, y el de i es 2
El valor de j es 3, y el de i es 2
El valor de j es 1, y el de i es 3
El valor de j es 2, y el de i es 3
El valor de j es 3, y el de i es 3
El valor de j es 1, y el de i es 4
El valor de j es 2, y el de i es 4
El valor de j es 3, y el de i es 4
El valor de j es 1, y el de i es 5
El valor de j es 2, y el de i es 5
El valor de j es 3, y el de i es 5

Es decir, el programa cuenta del 1 al 3 (con la variable j) cinco veces (con la variable i).

21 R. Espejel
Computación

Planteémonos el siguiente problema:


Elabora un programa que muestre cada una de las fichas de dominó, sin que se repitan, en el
formato [m, n]. Por ejemplo, la “mula” de 4 serı́a [4,4].
Hagamos un programa previo, que muestre todas las fichas que tienen un cero en un renglón:
#include<stdio.h>
int main(){
int i,j;
i = 0;
for (j=0;j<=6;j++){
printf("( %d, %d) \t",i,j);
}
printf("\n);
}
Incluimos la lı́nea printf("\n) para incluir un salto de lı́nea después de terminar de imprimir
el renglón. El programa mostrarı́a lo siguiente (el identificador \t es un tabulador):
(0,0) (0,1) (0,2) (0,3) (0,4) (0,5) (0,6)
El siguiente renglón deberı́a contener todas las fichas que tengan un uno, sin embargo, la ficha
(0,1) ya la hemos mostrado y no debemos repetirla. Entonces, para mostrar el segundo renglón
podrı́amos modificar el programa como sigue:
#include<stdio.h>
int main(){
int i,j;
i = 1;
for (j=1;j<=6;j++){
printf("( %d, %d) \t",i,j);
}
printf("\n);
}
El programa mostrarı́a, ahora, lo siguiente:
(1,1) (1,2) (1,3) (1,4) (1,5) (1,6)
Noten los números en rojo de los dos últimos programas. Es claro que para el siguiente renglón
debemos hacer i=2 y comenzar el for en j=2, es decir, para este problema j comienza siempre en
el valor de i. Entonces podemos hacer lo siguiente:
#include<stdio.h>
int main(){
int i,j;
i = 2;
for (j=i;j<=6;j++) {
printf("( %d, %d) \t",i,j);
}
printf("\n);
}

R. Espejel 22
Computación

Con el siguiente resultado:

(2,2) (2,3) (2,4) (2,5) (2,6)

Es claro ahora que para obtener todos los renglones, podemos incluir las lı́neas marcadas en
verde dentro de un ciclo for exterior con ı́ndice i que vaya desde 0 hasta 6:

#include<stdio.h>
int main(){
int i,j;
for (i = 0; i <= 6; i++){
for (j=i;j<=6;j++) {
printf("( %d, %d) \t",i,j);
}
printf("\n");
}
}

obteniendo, finalmente, el siguiente resultado:

(0,0) (0,1) (0,2) (0,3) (0,4) (0,5) (0,6)


(1,1) (1,2) (1,3) (1,4) (1,5) (1,6)
(2,2) (2,3) (2,4) (2,5) (2,6)
(3,3) (3,4) (3,5) (3,6)
(4,4) (4,5) (4,6)
(5,5) (5,6)
(6,6)

23 R. Espejel
Computación

1.3. Sumatorias.
Una de las aplicaciones básicas del ciclo for, es el cálculo de sumatorias. Gracias a que pode-
mos asignar a una variable un valor que resulte de evaluar una expresión que la contenga, mediante
instrucciones como x = x + 3, el cálculo de sumatorias es muy sencillo, por ejemplo:

5
X
S= 3 i2
i=1

podrı́a calcularse con el siguiente programa:

#include<stdio.h>
int main(){
int i,s;
s = 0;
for (i=1;i<=5;i++){
s=s+3*i*i;
}
printf("El valor de la sumatoria es %d \n",s);
}

Noten que la instrucción s=0 antes del for es necesaria, ya que si la omitimos, la primera vez
que se entra al ciclo, la expresión s+3*i*i no podrı́a evaluarse al no haber asignado un valor a s.
Noten también que la función printf está fuera del ciclo for, de modo que sólo se ejecutará una
vez para dar el valor del cálculo final de la sumatoria.
Inclusive podemos evaluar sumatorias dobles, como:

5 X
X 3
S= 3 i + j2
i=1 j=0

#include<stdio.h>
int main(){
int i,j,s;
s = 0;
for (i = 1; i<= 5; i++){
for (j = 0; j<= 3; j++){
s=s+3*i+j*j;
}
}
printf("El valor de la sumatoria es %d \n",s);
}

R. Espejel 24
Computación

A continuación veremos como aplicar estas ideas para calcular numericamente la integral de
una función contı́nua en el intervalo [a, b].

Para calcular el área bajo la curva en ese intervlalo, lo dividiremos en M subintervalos de ancho
h, de la siguiente manera:

De este modo, tendremos M trapecios, para los cuales es fácil calcular el área. La suma de todos
ellos se aproximará a la integral deseada si consideramos un valor de h pequeño.

Ahora bien, el área del trapecio, es h2 (l1 + l2 ), donde l1 y l2 , son los lados y h es la base (lo
puedes comprobar sumando el área del rectángulo de lados h y lmenor y la del trı́angulo de base h
y altura lmayor − lmenor ).

25 R. Espejel
Computación

Entonces, la suma de todos los trapecios es:

     
h h h
S= f (a) + f (a + h) + f (a + h) + f (a + 2h) + f (a + 2h) + f (a + 3h) + . . .
2 2 2
   
h h
... + f (a + (M − 2)h) + f (a + (M − 1)h) + f (a + (M − 1)h) + f (b) .
2 2

Factorizando h2 :

h
S= f (a) + f (a + h) + f (a + h) + f (a + 2h) + f (a + 2h) + f (a + 3h) + . . .
2 
. . . + f (a + (M − 2)h) + f (a + (M − 1)h) + f (a + (M − 1)h) + f (b)

y simplificando los sumandos repetidos

h
S= f (a) + 2f (a + h) + 2f (a + 2h) + 2f (a + 3h) + . . .
2 
. . . + 2f (a + (M − 2)h) + 2f (a + (M − 1)h) + f (b) .

Podemos escribir finalmente:

M −1
" #
1 X
I≃h (f (a) + f (b)) + f (a + ih)
2
i=1

La implementación del programa en C es sencilla; basta con calcular la sumatoria mediante un


ciclo for corriendo el ı́ndice de 1 a M − 1, el cual servirá tambien para calcular el argumento de la
función. Es claro que el valor de h estará dado por:

b−a
h=
M

R. Espejel 26
Computación

A continuación se muestra un ejemplo del código para calcular la integral de x3 + 2x:

main(){
float h,m,a,b,sum,integral;
int i;
printf("a = ");
scanf(" %f",&a);
printf("b = ");
scanf(" %f",&b);
printf("m = ");
scanf(" %f",&m);
h=(b-a)/m;
sum=0;
for (i=1;i<=m-1;i++) {
sum=sum+(a+i*h)*(a+i*h)*(a+i*h)+2*(a+i*h);
}
integral=(a*a*a+2*a+b*b*b+2*b+2*sum)*h/2;
printf("El resultado de la integral es %f",integral);
}

Cabe mencionar que el código se simplifica en gran medida al definir funciones, lo cual veremos
más adelante.

27 R. Espejel
Computación

Ejercicios.
Ejercicio 1. Elabora un programa que te permita estimar el lı́mite de la serie:


X 1
2n
n=1

Nota: Puedes usar la función pow(a,b) para calcular ab . Está definida en math.h.

Ejercicio 2. El Algoritmo de Euclides es un método para calcular el máximo común divisor (mcd).
Se basa en el hecho de que el máximo común divisor de a y b es el mismo que el de b
y r, donde r es el residuo de la división de a entre b, es decir, mcd(a, b) = mcd(b, r1 ),
y que mcd(k, 0) = k. Ası́, se puede seguir el proceso siguiente:

Dividendo Divisor Residuo Significado


a b r1 mcd(a, b) = mcd(b, r1 )
b r1 r2 mcd(b, r1 ) = mcd(r1 , r2 )
r1 r2 r3 mcd(r1 , r2 ) = mcd(r2 , r3 )
.. ..
. .
rn−1 rn rn+1 mcd(rn−1 , rn ) = mcd(rn , rn+1 )
rn rn+1 0 mcd(rn , rn+1 ) = mcd(rn+1 , 0) = rn+1

Nota que, de una fila a la siguiente, el valor de la segunda columna (divisor ) pasa a la
primera (dividendo) y el de la tercera (residuo) a la segunda (divisor ), hasta llegar a
un residuo igual a cero. Con base a lo anterior, y empleando la función módulo para
calcular los residuos, elabora un programa que calcule el mcd de los números a y b
proporcionados por el usuario.
Empleando la función módulo para calcular el residuo, elabora un programa que calcule
el MCD de los números a y b proporcionados por el usuario.

Ejercicio 3. Elabora un programa que muestre los primeros N números primos. N es solicitado al
usuario.

Sugerencia: Usa la función módulo (recuerda que a mod b, se denota como a %b) para
determinar si un número i (que puede ser el ı́ndice de un for ) divide a otro número z.
Cambia el valor de una variable dentro del ciclo cuando encuentres un divisor. De esta
forma, al terminar el ciclo sabrás (por el valor de esa variable) si el número z es primo
o no, si es ası́, muéstralo e incrementa un contador que te servirá para la condición de
un ciclo while.

Ejercicio 4. Elabora un programa que muestre en pantalla las posiciones (x, y) de un tiro parabólico
con rapidez inicial v0 y ángulo de lanzamiento a (con respecto a la horizontal) en
intervalos de tiempo dt; estos datos son solicitados al usuario. El programa debe mostrar
las posiciones del objeto mientras esté en el aire y detenerse cuando cae al suelo. Para
usar las funciones sin y cos necesitas la librerı́a math.h (recuerda que su argumento
está en radianes).

R. Espejel 28
Computación

Ejercicio 5. Elabora un programa que genere y muestre los elementos menores que n de la sucesión:

{1, 2, 4, 7, 11, 16, 22, . . .},


donde n es un número solicitado al usuario.

29 R. Espejel
Computación

1.4. Método de Newton-Raphson.

Cuando se desea resolver una ecuación f (x) = 0, en general no lineal, de manera numérica, pue-
de emplearse el método de Newton-Raphson. La idea fundamental del método consiste en calcular el
punto xn+1 a partir del punto xn , teniendo ası́ una expresión iterativa que genere una sucesión que
converja al valor para el cual la ecuación f (x) = 0 se satisfaga, a partir de una estimación inicial x0 .

Para realizar este cálculo, como se muestra en la figura 1, se traza una linea vertical sobre el
punto x0 hasta el punto en que ésta toca a la función f (x), esto es, en [x0 , f (x0 )]. A partir de este
punto, se traza una recta tangente a la función, obteniendo ası́ x1 en el cruce con el eje X.

Figura 1. Método de Newton-Raphson.

Ahora bien, sabemos que el valor la derivada de una función evaluada en un cierto punto,
coincide con el de la pendiente de la recta tangente que toca a la función en dicho punto. Entonces,
debemos obtener la ecuación de la recta con pendiente f ′ (x) que pasa por [x0 , f (x0 )] a partir de la
ecuación general de la recta y = mx + b:

f (x0 ) = f ′ (x0 )x0 + b,

despejando b:

b = f (x0 ) − f ′ (x0 )x0 ,

entonces:

y = f ′ (x0 )x + f (x0 ) − f ′ (x0 )x0 .

R. Espejel 30
Computación

El punto que buscamos, x1 , corresponderá entonces al valor de x cuando el valor de y, en la ecuación


anterior es cero:

0 =f ′ (x0 )x + f (x0 ) − f ′ (x0 )x0

f ′ (x0 )x0 − f (x0 )


⇒ x = x1 =
f ′ (x0 )
f (x0 )
x1 =x0 − ′ .
f (x0 )

Entonces, en general:

f (xn )
xn+1 =xn − . (1.1)
f ′ (xn )

Apliquemos ahora el método para un cálculo muy sencillo; obtener la raı́z cuadrada de un
número a. La ecuación
x2 − a = 0

se satisface cuando x = a, entonces, empleando la ecuación 1.1 obtenemos:

x2n − a x2 + a
xn+1 = xn − = n .
2xn 2xn

Aplicando este resultado calcularemos 5, es decir, resolveremos la ecuación x2 − 5 = 0. En este
caso, f (x) = x2 − 5 y f ′ (x) = 2x, y partiremos de la estimación x0 = 2:

x0 = 2
x0 2 + a 22 + 5
x1 = = = 2.25
2x0 2·2
(2.25)2 + 5
x2 = = 2.361
4.5
(2.361)2 + 5
x3 = = 2.3606797791580 . . .
2 · 2.361

Lo cual coincide hasta la octava cifra decimal con el valor “exacto” que es 2.2360679774 . . .
Es claro que podemos seguir calculando términos de la sucesión xn indefinidamente para acercarnos
cada vez más al valor analı́tico, sin embargo en un caso práctico es necesario plantear un criterio
que nos indique cuándo debemos parar, por ejemplo, cuando se programe este método el criterio
podrı́a ser: “Calcular mientras se cumpla |f (xn )| ≥ ϵ”, es decir pararemos cuando f (x) se acerque
a cero tanto como ϵ y reportamos el último valor de x. Es claro que, en general, ϵ ≪ 1.

31 R. Espejel
Computación

Ejercicios. Método de Newton-Raphson.


Ejercicio 1. Implementa un programa para obtener la raı́z n-ésima de un número a con el méto-
do de Newton-Raphson, lo cual es equivalente a resolvier numéricamente la ecuación
xn − a = 0, es decir,
f (x) = xn − a
y
f ′ (x) = nxn−1

Los datos n, a y la tolerancia para el criterio de paro ϵ, son solicitados al usuario.

R. Espejel 32
Computación

1.5. Funciones en C.

Como comentamos la clase anterior, podemos construir nuestras propias funciones en un pro-
grama en C, lo cual nos permite tener un código más ordenado y claro. Para construir una función
son necesarias dos estructuras: el prototipo de la función y su definición.

Un ejemplo de prototipo de función serı́a el siguiente:

float MiFuncion(float,float);

En esta estructura sólo estamos declarando una función llamada MiFuncion que recibe como
argumento dos números o variables de tipo flotante, y el valor que devuelve es también flotante. La
definición correspondiente a este prototipo podrı́a ser la siguiente:

float MiFuncion(float b, float h){


float a;
a = b*h/2;
return(a);
}

Esta función recibe como argumentos la base y la altura de un triángulo de base b y altura h,
y regresa su área. La estructura del programa serı́a entonces:

#include<stdio.h>
float MiFuncion(float,float);
int main(){
}
float MiFuncion(float b, float h){
float a;
a = b*h/2;
return(a);
}

Este programa se puede compilar sin problemas, pero no producirá salida alguna, hasta que com-
pletemos el cuerpo de la función principal (main), por ejemplo:

33 R. Espejel
Computación

float MiFuncion(float,float);
int main(){
float k,m,z;
printf("Dame la altura del triangulo ");
scanf(" %f",&k);
printf("Dame la base del triangulo ");
scanf(" %f",&m);
z = MiFuncion(m,k);
printf("El area del triangulo con base %f y altura %f es %f.\n",m,k,z);
}
float MiFuncion(float b, float h){
float a;
a = b*h/2;
return(a);
}

A este programa, es posible agregar más funciones, por ejemplo, el siguiente programa calcula el
volumen del prisma triangular, ası́ como el área del triángulo que lo forma:

float Area(float,float);
float Volumen(float,float,float);
int main(){
float k,m,a,v,L;
printf("Dame la altura del triangulo ");
scanf(" %f",&k);
printf("Dame la base del triangulo ");
scanf(" %f",&m);
printf("Dame la longitud del prisma ");
scanf(" %f",&L);
a = Area(m,k);
v = Volumen(m,k,L);
printf("El area del triangulo con base %f y altura %f es %f.\n",m,k,a);
printf("El volumen del prisma es %f.\n",v);
}
float Area(float b, float h){
float a;
a = b*h/2;
return(a);
}
float Volumen(float b, float h, float z){
float v;
v = Area(b,h)*z;
return(v);
}

R. Espejel 34
Computación

Hemos renombrado la función MiFuncion por Area.


A continuación transcribo el programa donde se implemeta el método del trapecio para calcular
integrales definidas:

#include<stdio.h>

float MiFuncion(float);

int main(){

float h,m,a,b,integral;
int i;
printf("a = ");
scanf(" %f",&a);
printf("b = ");
scanf(" %f",&b);
printf("m = ");
scanf(" %f",&m);

h=(b-a)/m;
integral=(MiFuncion(a)+MiFuncion(b))*h/2;

for (i=1;i<=m-1;i++) {
integral=integral+h*MiFuncion(a+i*h);
}
printf("El resultado de la integral es %f\n",integral);
}

float MiFuncion(float x){


return(x*x*x+2*x);
}

Y el programa donde se implementa el método de Newton-Raphson para resolver ecuaciones no


lineales, aplicado al cálculo de raı́ces n-ésimas f (x) = xn − a.

#include<stdio.h>
float MiFuncion(float,float,float);
float Derivada(float,float);
int main(){
float n,a,x,e;
printf("Dame el valor de a ");
scanf(" %f",&a);
printf("Dame el valor de n ");
scanf(" %f",&n);
printf("Dame el valor de x0 ");
scanf(" %f",&x);
printf("Dame el valor de e ");
scanf(" %f",&e);
while(fabs(MiFuncion(x,n,a))>e){

35 R. Espejel
Computación

x = x - MiFuncion(x,n,a) / Derivada(x,n);
}
printf("La solucion es x = %f\n",x);
}
float MiFuncion(float x, float n, float a){
return(pow(x,n)-a);
}
float Derivada(float x, float n){
return(n*pow(x,n-1));
}

R. Espejel 36
Computación

Ejercicios.
Ejercicio 1. Elabora un programa para obtener el volumen de un cilindro de radio r y altura h
implementando las funciones AreaCirculo y VolumenCilindro.

Ejercicio 2. Elabora un programa para convertir grados Fahrenheit a Centı́grados implementando


la función FtoC.

Ejercicio 3. Elabora un programa para convertir pies por segundo a kilómetros por hora implemen-
tando la función PtoK.

37 R. Espejel
Computación

1.6. Simulación de Experimentos con Variables Aleatorias.


Comenzaremos a exponer cómo se generan números aleatorios en C mediante la función rand()
que pertenece a la librerı́a time.h. Implementemos el siguiente programa:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
int z;
z = rand();
printf("El numero es %d\n",z);
}

El resultado será un número aleatorio entero entre 0 y RAND MAX. RAND MAX es una constante
definida en la librerı́a stdlib.h, generalmente es un número grande, del orden de 216 . Sin embargo,
este número aleatorio será siempre el mismo cada vez que ejecutemos el programa.
El problema es que rand() calcula los números aleatorios a partir de un número inicial (llamado
semilla), el cual es el argumento de una función que devuelve el número aleatorio. Para generar más
números, el número anterior es la semilla del siguiente y ası́ sucesivamente, de modo que siempre
tendremos la misma secuencia de números.
Podemos entonces elegir la semilla del generador de números aleatorios, de modo que ésta sea
distinta cada vez que ejecutamos el programa. La semilla se elige con la función srand(s) donde el
argumento s es propiamente la semilla. Por lo general ésta se elige empleando la función time(0)
que devuelve el número de segundos que lleva activo nuestro procesador. Prueba ahora el siguiente
programa:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
int z;
srand(time(0));
z = rand();
printf("El numero es %d\n",z);
}

Ejecútalo varias veces y verás que da un número diferente cada vez.


Ahora, rand() devuelve un numero aleatorio en un intervalo muy grande (de cero a RAND MAX).
Podemos limitar ese intervalo usando la función módulo. Es claro que al estar definido a mod b
como el residuo de a/b, entonces
a mod b < b
De hecho a mod b estará en el intervalo [0, b − 1], de modo que podemos modificar el programa
anterior para obtener un número aleatorio entero, por ejemplo, entre 1 y 6:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

R. Espejel 38
Computación

int main(){
int z;
srand(time(0));
z = rand() %6+1;
printf("El numero es %d\n",z);
}

Con las estructuras que ya conocemos, podemos implementar un programa para simular un
experimento que se comporta de manera similar al decaimiento radiactivo, consistente en:

Lanzar una cierta cantidad n de dados.

Retirar aquellos que hayan caı́do en un número c, previamente elegido.

Tomar nota del número de dados restante y lanzarlos.

Repetir el proceso hasta que no queden más dados.

Para simular este experimento, dividimos el problema en ”metas”ó ”secciones”. Los cambios en el
programa para avanzar de una meta a otra, se resaltan en color.

Meta 1

Comenzemos por simular el comportamiento de un sólo dado, generando un número aleatorio


entero en el intervalo [1,6].

#include <time.h>
#include <stdio.h>
main(){
int z;
srand(time(0));
z=rand() % 6 + 1;;
printf("El dado cayó en %d.",z);
}

39 R. Espejel
Computación

Meta 2

El siguiente paso serı́a solicitar al usuario el número de dados n, y repetir el proceso n veces
empleando un ciclo for:

main(){
int z,i,n;
printf("Dame el número de dados ");
scanf(" %d",&n);
srand(time(0));
for (i=1;i<=n;i++) {
z=rand() % 6 + 1;;
printf("El dado cayó en %d.\n",z);
}
}

Meta 3

Ahora contemos cuántas veces cae el dado en un número especı́fico, por ejemplo el 5, empleando
la instrucción if.

main(){
int z,i,n,m;
printf("Dame el número de dados ");
scanf(" %d",&n);
srand(time(0));
m=0;
for (i=1;i<=n;i++) {
z=rand() % 6 + 1;;
printf("El dado cayó en %d.\n",z);
if (z==5) {
m=m+1;
}
}
printf("\nEl dado cayó en %d, %d veces.",c,m);
}

R. Espejel 40
Computación

Meta 4
Calculemos el número de dados que quedan restando m a n y asignándole este nuevo valor:

main(){
int z,i,n,m;
printf("Dame el número de dados ");
scanf(" %d",&n);
srand(time(0));
m=0;
for (i=1;i<=n;i++) {
z=rand() % 6 + 1;;
printf("El dado cayó en %d\n",z);
if (z==5) {
m=m+1;
} }
n=n-m;
printf("\nEl dado cayó en %d, %d veces.",c,m);
printf("\nQuedan %d dados.",n);
}

Meta 5
Por último, incluyamos el ciclo for dentro de un ciclo while con la condición n > 0, es decir
”mientras haya dados”.

main(){
int z,i,n,m;
printf("Dame el número de dados ");
scanf(" %d",&n);
srand(time(0));
while(n>0) {
m=0;
for (i=1;i<=n;i++) {
z=rand() % 6 + 1;;
printf("El dado cayó en %d\n",z);
if (z==5) {
m=m+1;
} }
n=n-m;
printf("\nEl dado cayó en %d, %d veces.",c,m);
printf("\nQuedan %d dados.\n",n);
}
}

41 R. Espejel
Computación

Eliminemos algunas de las funciones printf para tener una salida más limpia:

main(){
int z,i,n,m;
printf("Dame el número de dados ");
scanf(" %d",&n);
srand(time(0));
while(n>0) {
m=0;
for (i=1;i<=n;i++) {
z=rand() % 6 + 1;
if (z==5) {
m=m+1;
}
}
n=n-m;
printf("\nQuedan %d dados.\n",n);
}
}

R. Espejel 42
Computación

Ejercicios. Simulación de Experimentos con Variables Aleatorias


Ejercicio 1. Implementa un programa para obtener una aproximación al valor de π mediante el
método Monte–Carlo. Para ello imagina que vas a lanzar piedras a un cuadrado de 1m
× 1m, el cual tiene un cuarto de cı́rculo dibujado, como el de la figura:

La probabilidad de que aciertes al cuarto de cı́rculo es:

área del cuarto de cı́rculo π


P = = ,
área del cuadrado 4
Pero esa probabilidad también la puedes calcular como:

Aciertos
P = .
Total de intentos
Usa esta última expresión para elaborar el programa.

a) Implementa el siguiente programa que genera y muestra una coordenada aleatoria


en el intervalo [0,1).

main(){
float x,y;
srand(time(0));
x = float(rand())/float(RAND MAX);
y = float(rand())/float(RAND MAX);
printf("x= %f\n",x);
printf("y= %f\n",y);
}

Se espera una salida como la siguiente:

x=0.33568
y=0.05456

b) Con base en el programa anterior elabora otro que solicite al usuario el número de
coordenadas n, y repita el proceso n veces. Se espera una salida como la siguiente
(se muestra entre corchetes lo que introduce el usuario):

43 R. Espejel
Computación

Dame el número de coordenadas [5][enter]

x=0.57389
y=0.52653
x=0.88082
y=0.07643
x=0.84538
y=0.52014
x=0.07631
y=0.97632
x=0.33568
y=0.05456

c) Con base en el programa anterior elabora otro que cuente cuántas veces “se acier-
ta” en el cı́rculo y lo divida entre el número de intentos, lo cual, con un valor de
n suficientemente grande, te dará una aproximación a π4 .
d ) Elabora un programa que simule n lanzamientos de 2 dados y cuente el número
de veces m que la suma de ambos dados resulte 7 u 11, mostrando como resultado
la probabilidad dada por el cociente m/n.
e) Elabora un programa que simule 1000 lanzamientos de 2 dados, mostrando como
resultado la probabilidad de que la suma de ambos dados sea k. El proceso debe
repetirse para cada valor de k en el intervalo [1,12]. Recuerda que esta probabilidad
estará dada por m/1000, donde m es el número de veces que la suma de los dados
es k.

R. Espejel 44
Computación

1.7. Arreglos en C.
Como ya sabes, al declarar una variable en un programa en C, se le asigna una localidad de
memoria donde se almacena su valor, como en el siguiente programa:

int main(){
int a;
a = 5; printf("El valor de a es %d\n",a);
}

Lo que verı́amos al ejecutar el programa es:

El valor de a es 5

Podemos hacer la analogı́a de lo anterior con un cajón llamado a donde se guarda un valor que
se puede modificar.
int a; → 5
Ahora bien, es posible asignar más de una localidad de memoria a una sola variable, por medio
de lo que llamaremos arreglo. La analogı́a serı́a entonces a una cajonera con varios cajones. La
forma de declarar un arreglo como este (por ejemplo, de cinco entradas) es int a[5];

5
3
int a[5]; → 1
4
9
Este arreglo lo podemos implementar en un programa como el siguiente, en el que llenamos el
arreglo con los números anteriores y mostramos el contenido del tercer cajón:

int main(){
int a[5];
a[0]=5;
a[1]=3;
a[2]=1;
a[3]=4;
a[4]=9;
printf("El valor de a[2] es %d\n",a[2]);
}

Lo que verı́amos al ejecutar el programa es:

El valor de a[2] es 1

Como te habrás dado cuenta, el número entre corchetes (el 2) es el número del cajón empezando
la numeración en cero. A este número, que siempre será un entero, le llamaremos ı́ndice.

45 R. Espejel
Computación

5 a[0]
3 a[1]
int a[5]; → 1 a[2]
4 a[3]
9 a[4]

Podemos entonces, por ejemplo, usar el contador de un ciclo for para mostrar todos los valores
del arreglo. En el siguiente programa usamos un ciclo for con un contador entero n, el cual toma
los valores 0,1,2,3,4, para mostrar cada uno de los valores a[0],a[1],a[2],a[3],a[4]:

int main(){
int a[5],n;
a[0]=5;
a[1]=3;
a[2]=1;
a[3]=4;
a[4]=9;
for (n=0;n<5;n++){
printf("El valor en el cajón %d es %d\n",n,a[n]);
}
}

El valor en el cajón 0 es 5
El valor en el cajón 1 es 3
El valor en el cajón 2 es 1
El valor en el cajón 3 es 4
El valor en el cajón 4 es 9

También podemos emplear el ciclo for para asignar valores a las entradas del arreglo. El siguien-
te programa llena un arreglo de 10 entradas con ceros y lo muestra usando dos ciclos independientes.

int main(){
int a[10],n;
for (n=0;n<10;n++){
a[n]=0;
}
for (n=0;n<10;n++){
printf("El valor en el cajón %d es %d\n",n,a[n]);
}
}

Es posible también usar el contador del for (la variable n, en este caso), para calcular la entrada.
Por ejemplo, el siguiente programa asigna a cada entrada del arreglo un valor que es el triple de su
ı́ndice:

int main(){
int a[10],n;

R. Espejel 46
Computación

for (n=0;n<10;n++){
a[n]=n*3;
}
for (n=0;n<10;n++){
printf("El valor en el cajón %d es %d\n",n,a[n]);
}
}

¿Recuerdas el programa que calcula el promedio de números introducidos por el usuario? Usando
arreglos se puede hacer un programa con una salida más completa:

int main(){
int k,n;
float s,p,x;
printf("Cuantos datos tienes? ");
scanf(" %d",&k);
float a[k];
for(n = 0; n<k; n++){
printf("Dame el dato %d ",n+1);
scanf(" %f",&x);
a[n] = x;
}
printf("Los datos son:\n");
s = 0.0;
for(n = 0; n<k; n++){
printf("Dato %d = %f\n",n+1,a[n]);
s = s + a[n];
}
p = s/n;
printf("El promedio es %f\n",p);
}

Nota que en el programa, se declara el arreglo a (ahora como flotante) una vez que se sabe su
tamaño, es decir, el número de datos que se van a manejar. De este modo, en el primer ciclo, se
consulta el dato y se le asigna este valor a la entrada correspondiente del arreglo. Posteriormente
se puede mostrar y hacer la suma para calcular el promedio.
Una aplicación directa de los arreglos, es la implementación de los llamados algoritmos de
ordenamiento, es decir, procedimientos para ordenar las entradas de un arreglo, ya sea de forma
ascendente o descendente. Uno de estos algoritmos consiste en comparar el valor de cada una de
las entradas del arreglo con el valor de la primera entrada, y si encontramos que una de ellas en
menor (en este ejemplo) que la primera, intercambiaremos los valores:

a[0] 3 a[0] 2
a[1] 6 a[1] 6
a[2] 2 → a[2] 3
a[3] 7 a[3] 7
a[4] 5 a[4] 5

47 R. Espejel
Computación

Al final de este proceso, podemos asegurar que el menor valor del arreglo está justo en la primer
entrada del arreglo. Ahora podemos repetir este proceso, pero ahora comparando el valor de cada
una de las entradas del arreglo con el valor de la segunda entrada,

a[0] 2 a[0] 2
a[1] 6 a[1] 3
a[2] 3 → a[2] 6
a[3] 7 a[3] 7
a[4] 5 a[4] 5

ahora el valor de esta segunda entrada, será el menor del resto del arreglo. Repitiendo este proceso
con cada valor del arreglo, lograremos ordenarlo.

Podemos hacer un programa para realizar la primera comparación (el valor de la primer entrada
del arreglo con el cada una del resto de las entradas) empleando un ciclo for y un if:

int main(){
int a[5],n,t;
a[0]=3;
a[1]=6;
a[2]=2;
a[3]=7;
a[4]=5;
for (n=0;n<5;n++){
if a[n] < a[0]{
t = a[0];
a[0] = a[n];
a[n] = t;
}
}
for (n=0;n<5;n++){
printf("El valor en el cajón %d es %d\n",n,a[n]);
}
}
R. Espejel 48
Computación

Nota:
Para intercambiar el valor de 2 variables a y b, no podemos simplemente hacer:
a = b;
b = a;
ya que con esto tendrı́amos, por ejemplo, si a = 5 y b = 3:
a=b=3
b=a=3
Y se pierde el valor de 5, ya que sobreescribimos el valor de a. Por esto es que
incluimos la variable t para almacenar este valor. Entonces podemos hacer:
t = a;
a = b;
b = t;
Ası́ se tendrá que:
t=a=5
a=b=3
b=t=5

Ahora, podemos incluir otro ciclo for con indice k, para hacer todas comparaciones, la primera
con el resto (k = 0), la segunda entrada con el resto (k = 1), la tercera con el resto (k = 2). . . etc,
y terminar de ordenar el arreglo.

int main(){
int a[5],n,t,k;
a[0]=3;
a[1]=6;
a[2]=2;
a[3]=7;
a[4]=5;
for (k=0;k<5;k++){
for (n=k;n<5;n++){
if (a[n] < a[k]){
t = a[k];
a[k] = a[n];
a[n] = t;
}
}}
for (n=0;n<5;n++){
printf("El valor en el cajon %d es %d\n",n,a[n]);
}
}

49 R. Espejel
Computación

En el siguiente programa estamos llenando un arreglo de 20 entradas con números aleatorios y


ordenándolos en orden ascendente (el programa muestra el contenido del arreglo antes y después
de ordenarlo):

int main(){
int a[20],n,t,k;
srand(time(0));
for (n=0;n<20;n++){
a[n]=rand() %100+1;
printf("El valor en el cajon %d es %d\n",n,a[n]);
}
for (k=0;k<20;k++){
for (n=k;n<20;n++){
if (a[n] < a[k]){
t = a[k];
a[k] = a[n];
a[n] = t;
}
}}
for (n=0;n<20;n++){
printf("El valor en el cajon %d es %d\n",n,a[n]);
}
}

R. Espejel 50
Computación

Ejercicios. Arreglos en C
Ejercicio 1. Elabora un programa que genere y muestre un arreglo que contenga los 10 primeros
números impares.

Ejercicio 2. Elabora un programa que genere y muestre un arreglo que contenga 100 números
aleatorios en el intervalo [1,20] y reporte el mayor, el menor y el promedio.

51 R. Espejel
Computación

1.8. Matrices en C

Como ya vimos, es posible asignar más de una localidad de memoria a una sola variable, por
medio de un arreglo. Veremos hora que cada entrada de un arreglo, puede a su vez, ser otro arreglo:



 5 4 1 a[0]
3 7 6 a[1]



int a[5][3] 1 2 9 a[2]
4 3 4 a[3]




9 8 1 a[4]

Ası́, por ejemplo, el arreglo a[2] será [1,2,9], y la segunda entrada de éste a[2][1] será 2. De
este modo, tendremos una matriz.
Necesitamos ahora dos números para identificar una entrada del arreglo bidimensional, podemos
entonces, usar dos ciclos for para mostrar todos los valores del arreglo. En el siguiente programa
usamos un ciclo for con un contador entero r, el cual toma los valores 0,1,2,3,4, para identificar
cada uno de los renglones a[0],a[1],a[2],a[3],a[4], y otro ciclo for con un contador entero c,
que toma los valores 0,1,2 para identificar a cada entrada de éstos.

int main(){
int a[5][3],r,c;
a[0][0]=5; a[0][1]=4; a[0][2]=1;
a[1][0]=3; a[1][1]=7; a[1][2]=6;
a[2][0]=1; a[2][1]=2; a[2][2]=9;
a[3][0]=4; a[3][1]=3; a[3][2]=4;
a[4][0]=9; a[4][1]=8; a[4][2]=1;
for (r=0;r<5;r++){
for (c=0;c<3;c++){
printf(" %d ",a[r][c]);
}}
}

ya que no incluimos \n en el printf, tendremos la salida en una sola lı́nea:

541376129434981

R. Espejel 52
Computación

Si incluimos un salto de lı́nea al terminar el for interno,

int main(){
int a[5][3],r,c;
a[0][0]=5; a[0][1]=4; a[0][2]=1;
a[1][0]=3; a[1][1]=7; a[1][2]=6;
a[2][0]=1; a[2][1]=2; a[2][2]=9;
a[3][0]=4; a[3][1]=3; a[3][2]=4;
a[4][0]=9; a[4][1]=8; a[4][2]=1;
for (r=0;r<5;r++){
for (c=0;c<3;c++){
printf(" %d ",a[r][c]);
}
printf("\n")
}
}

Veremos la salida como sigue, ya que al terminar de imprimir un renglón, se ejecuta el salto de lı́nea.

5 4 1
3 7 6
1 2 9
4 3 4
9 8 1

También podemos emplear ciclos for anidados para asignar valores a las entradas del arreglo.
El siguiente programa llena un arreglo de 10×10 entradas con ceros y lo muestra usando ciclos
independientes.

int main(){
int a[10][10],r,c;
for (r=0;r<10;r++){
for (c=0;c<10;c++){
a[r][c]=0;
}}
for (r=0;r<10;r++){
for (c=0;c<10;c++){
printf(" %d\t",a[r][c]);
}
printf("\n")
}
}

53 R. Espejel
Computación

Modifiquemos el programa anterior para obtener la matriz identidad de 10×10. Recuerda que la
matriz identidad tiene 1’s en la diagonal principal y ceros en el resto de las entradas, y los ı́ndices de
la diagonal principal son aquellos en que el número de renglón coincide con el número de columna.
Usemos un if para asignar estos valores:

int main(){
int a[10][10],r,c;
for (r=0;r<10;r++){
for (c=0;c<10;c++){
if (r == c){
a[r][c]=1;
}
else{
a[r][c]=0;
}
}}
for (r=0;r<10;r++){
for (c=0;c<10;c++){
printf(" %d\t",a[r][c]);
}
printf("\n")
}
}

O bien:

int main(){
int a[10][10],r,c;
for (r=0;r<10;r++){
for (c=0;c<10;c++){
a[r][c] = (r==c) ? 1:0;
}}
for (r=0;r<10;r++){
for (c=0;c<10;c++){
printf(" %d\t",a[r][c]);
}
printf("\n")
}
}

En la lı́nea en azul le hemos asignado el valor a la entrada del arreglo usando un operador
ternario, que tiene la siguiente sintaxis:

variable = condición ? valor para verdadero : valor para falso

Ası́, si se cumple la condición, a la variable se le asigna el valor para verdadero, y de lo contrario


se le asigna el valor para falso. Esta estructura abreviada puede ahorrar mucho código.

R. Espejel 54
Computación

Ejercicios. Matrices en C
Ejercicio 1. Elabora un programa que almacene en un arreglo una matriz triangular superior de
n × n. Las entradas de la matriz serán números aleatorios enteros en el intervalo [0,20].
Ejemplo de Matriz triangular superior:
 
3 4 2
 0 9 5 
0 0 1

Ejercicio 2. Elabora un programa que almacene en un arreglo una matriz triangular inferior de
n × n. Las entradas de la matriz serán números aleatorios enteros en el intervalo [0,20].
Ejemplo de Matriz triangular inferior:
 
3 0 0
 2 9 0 
9 7 1

55 R. Espejel
Computación

R. Espejel 56
Capı́tulo 2

Programación en Python

2.1. Inicio en Python.


La estructura de un programa en Python es muy sencilla. Comenzaremos por mostrar el uso de
la función print, la cual muestra un mensaje en la ventana shell :

print(’Mi primer programa en Python’)

De forma similar a cuando programamos en C, podemos mostrar el valor de una variable de la


siguiente manera:

a = 5
print(’El valor de a es %d’ % a)

Con lo que el programa mostrará el mensaje:


El valor de a es 5
Notamos que en Python, la declaración de la variable es intrı́nseca a la asignación, en el pro-
grama anterior la variable a es de tipo entero. Sin embargo, al hacer la asignación de la siguiente
manera:

a = 5.0
print(’El valor de a es %f’ % a)

la variable a es de tipo flotante, y habrá que manejarla como tal al mostrarla con la función print

Las operaciones entre variables, al igual que en C, en Python son muy intuitivas. Veamos el siguiente
programa:

b = 5.0
h = 3.0
a = b*h/2
print(’El area de un triangulo con base %f y altura %f es %f’ % (b,h,a))

57
Computación

Notamos que al mostrar varias variables con print, es necesario agruparlas en una tupla, en el
orden en la que se muestran en el mensaje. El programa mostrará:

El area de un triangulo con base 5.0 y altura 3.0 es 7.5


Ahora bien, si deseamos que se le soliciten al usuario los datos del triángulo, empleamos la función
input que recibe como argumento el mensaje con el que se solicitará el dato al usuario y devolverá
el valor que se introduzca en el teclado. Por ejemplo:

b = input(’Dame el valor de la base ’)

de este modo, la variable b tomará el valor que el usuario introduzca. Sin embargo este valor será
siempre una cadena de texto, de modo que para poder hacer operaciones, debemos convertir esta
cadena de texto al tipo de valor que requiramos:

b = float(input(’Dame el valor de la base ’))

Ası́, el programa quedarı́a de la siguiente forma:

b = float(input(’Dame el valor de la base ’))


h = float(input(’Dame el valor de la altura ’))
a = b*h/2
print(’El area de un triangulo con base %f y altura %f es %f’ % (b,h,a))

Otro ejemplo podrı́a ser el cálculo del volumen de una esfera:

r = float(input(’Dame el radio de la esfera ’))


v = (4/3)*3.1416*r**3
print(’El volumen de una esfera de radio %f es %f’ % (r,v))

Notamos que la forma de elevar un número a alguna potencia (xy ), en Python se denota como x**y.

Actividad: Modifica el programa para calcular el volumen de un cilindro de radio r y altura h


solicitados al usuario.

R. Espejel 58
Computación

Ejercicios. Introducción a Python


Ejercicio 1. Elabora un programa para resolver el siguiente problema, los datos vA , vB y d serán
consultados al usuario:
Dos vehı́culos A y B salen uno al encuentro del otro (viajando en lı́nea recta) desde
dos ciudades separadas una distancia d (en km), con velocidades de vA y vB (ambas en
km/h) respectivamente. El programa debe mostrar la distancia xA (en metros) donde
se dará el choque respecto al punto de partida de A, considerando que salen al mismo
tiempo.

Ejercicio 2. Elabora un programa que calcule el peso de una esfera de radio r y densidad p (estos
datos son consultados al usuario).

Ejercicio 3. En una bicicleta, al girar con los pedales el engrane 1 un ángulo θ1 , la cadena recorrerá
una longitud l1 = θ1 r1 a partir del punto P . Ya que la cadena es inextensible, esta
misma longitud de cadena pasará por el punto Q, haciendo girar el engrane 2 un ángulo
θ2 . Entonces

θ1 r1 = θ2 r2
r1
θ2 = θ1
r2
Este mismo ángulo es el que girará la rueda de radio r3 , haciendo avanzar la bicicleta
una distancia igual a la longitud de arco l2 = θ2 r3 . Elabora un programa para calcular
la distancia que recorrerá una bicicleta al dar n vueltas a los pedales. Tanto n, como
los radios de los engranes y la rueda son solicitados al usuario.

r3

r1
r2

Q
P

Ejercicio 4. Elabora un programa que calcule la altura máxima de un tiro vertical que inicia desde
el suelo. La velocidad inicial es solicitada al usuario.
Hint: Usa v = v0 − gt para calcular el tiempo que tarda el móvil en llegar a su altura
máxima (cuando v = 0), luego sustituye ese tiempo en y = y0 + v0 t − 12 gt2

Ejercicio 5. Elabora un programa que calcule los ángulos de las manecillas del reloj (respecto a
las 12:00) para una hora introducida por el usuario en horas y minutos, en formato de
12 hrs. (Nota que el ángulo de la manecilla horaria, por ejemplo, a las 03:00 no es el
mismo que para las 03:30)

59 R. Espejel
Computación

2.2. Listas y for.

Las listas es una estructura fundamental en la programación con Python. Podemos crear una
lista de valores asignando directamente una colección de estos, separados por comas y delimitados
por corchetes. Por ejemplo:

A = [3,0,’k’,0.5,1,’python’]

Podemos identificar al primer elemento como A[0], al segundo como A[1], etc. e incluso podemos
referirnos al último término como A[-1], al penúltimo como A[-2], etc. de modo que:

print(A[0])]

mostrará el número 3, y

print(A[-1])]

mostrará python. También podemos aumentar elementos a la lista con el método append, como
sigue:

A = [3,0,’k’,0.5,1,’python’]
[Link](7)

Con lo cual la lista quedará como A = [3,0,’k’,0.5,1,’python’,7]

La función range, devuelve una lista con el número de elementos que recibe como argumento.
Por ejemplo:

A = range(5)
asigna a A la lista [0,1,2,3,4]

A = range(2,7)
asigna a A la lista [2,3,4,5,6]

A = range(3,10,2)
asigna a A la lista [3,5,7,9].

En ocasiones, es necesario crear listas más especiales, como por ejemplo, una lista que contenga
100 ceros. Serı́a muy tedioso crear la lista dando directamente los valores, como en el último ejem-
plo, ası́ que podemos recurrir a la siguiente estructura:

B = [0 for i in range(100)]

R. Espejel 60
Computación

De este modo, tendremos que el cero se “replica” dentro de la lista, teniendo una lista con 100
ceros. En general, esta estructura, replica una expresión que puede (o no) depender de la variable
involucrada en el for:

B = [expresión for k in Lista]

Actividad: Captura y ejecuta el siguiente programa para comprobar que se le asigna a B la


lista [6,0,14,1.0,2,0.5].

A = [3,0,7,0.5,1,0.25]
B = [2*n for n in A]
print (B)

Como puedes ver, esta estructura es muy útil para hacer operaciones elemento a elemento sobre
listas.
Otra aplicación es el cálculo de sumatorias, ya que Python tiene incorporada la función sum,
que toma como argumento una lista y devuelve la suma de sus elementos. Por ejemplo, si queremos
calcular la sumatoria

5
X
(2k − 1)
k=1

podrı́amos implementar el siguiente programa

B = [2*k-1 for k in range(1,6)]


print B
s = sum(B)
print ’La suma es’,s

Al ejecutarlo obtenemos lo siguiente:

[1, 3, 5, 7, 9]
La suma es 25

Actividad: Completa las metas para elaborar un programa que simule 1000 lanzamientos de
2 dados, y que en un arreglo A, que comienza con ceros en cada una de sus 12 entradas, se vaya
contando el número de veces que la suma de los dados corresponde a cada entrada. Es decir, la pri-
mera entrada (A[0]) se incrementa cuando la suma de los dados es 1, la segunda (A[1]) cuando
la suma de los dados es 2, la tercera (A[2]) cuando la suma de los dados es 3, etc. El programa
debe mostrar el arreglo final.

Meta 1: Comencemos por simular el lanzamiento de 2 dados. Usaremos la función randint, incluida
en la librerı́a random, la cual genera un número aleatorio entero en el intervalo definido por los
argumentos que recibe:

from random import randint


d1 = randint(1,6)
d2 = randint(1,6)
print (’El dado 1 cayo en %d, el dado 2 cayo en %d.’ % (d1,d2))

61 R. Espejel
Computación

Meta 2: Calculemos la suma y la mostramos para comprobar el resultado:

from random import randint


d1 = randint(1,6)
d2 = randint(1,6)
s = d1+d2
print (’El dado 1 cayo en %d, el dado 2 cayo en %d. La suma es %d’ % (d1,d2,s) )

Meta 3: Construyamos la lista A con ceros en sus 12 entradas. Incrementemos aquella que coincide
con la suma de los dados. Recuerda que la primer entrada es A[0]:

from random import randint


A = [0 for i in range(12)]
d1 = randint(1,6)
d2 = randint(1,6)
s = d1+d2
A[s-1] = A[s-1] +1
print (’El dado 1 cayo en %d, el dado 2 cayo en %d. La suma es %d’ % (d1,d2,s))
print (A)

El programa mostrará algo como lo siguiente:

El dado 1 cayo en 2, el dado 2 cayo en 2. La suma es 4


[0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]

El lugar de la entrada con el uno, debe coincidir con la suma de los dados, en este caso, la suma es
4, y la entrada con el uno es la cuarta.

Meta 4: Incluyamos las lı́neas adecuadas en un ciclo for y eliminemos el primer print para
simplificar la salida:

from random import randint


A = [0 for i in range(12)]
for n in range(1000):
d1 = randint(1,6)
d2 = randint(1,6)
s = d1+d2
A[s-1] = A[s-1] +1
print (A)

Ahora la salida será algo como lo siguiente:


[0, 25, 53, 86, 111, 155, 173, 122, 116, 76, 57, 26]

La primer entrada siempre será cero, ya que es imposible que la suma de dos dados sea uno. Ahora
comprobemos que la suma de todas las entradas de A es 1000:

R. Espejel 62
Computación

from random import randint


A = [0 for i in range(12)]
for n in range(1000):
d1 = randint(1,6)
d2 = randint(1,6)
s = d1+d2
A[s-1] = A[s-1] +1
print (A)
print (’la suma es’,sum(A))

Meta 5: Por último, podemos calcular la probabilidad a la que corresponde cada entrada, creando
la lista B como cada una de las entradas de A, divididas entre 1000; ahora la suma debe ser uno.

from random import randint


A = [0 for i in range(12)]
for n in range(1000):
d1 = randint(1,6)
d2 = randint(1,6)
s = d1+d2
A[s-1] = A[s-1]+1
s1 = sum(A)
print A
print (’la suma es’,s1)
B = [k/1000.0 for k in A]
s2 = sum(B)
print B
print (’la suma es’,s2)

63 R. Espejel
Computación

Ejercicios. Introducción a Python


Ejercicio 1. Elabora un programa en Python que genere y muestre una lista con los cuadrados de
los primeros n enteros y su suma. Consulta el valor de n al usuario con input.

Ejercicio 2. Elabora un programa que genere los primeros n términos de la sucesión de Fibonacci,
considera que el usuario siempre dará una n mayor a 2. Puedes usar el método append.

Ejercicio 3. Elabora un programa que calcule la sumatoria siguiente:

n
X
k 2 + 2k 3 + k 4
k=1

solicita el valor de n al usuario. La operación xy en Python se denota como x**y.

Ejercicio 4. Elabora un programa que te consulte un número del 1 al 7 y te muestre el dı́a de


la semana correspondiente. Es decir, si le das el número 4, te debe mostrar “jueves”.
Nota: No uses if, usa una lista con los nombres de los dı́as.

R. Espejel 64
Computación

2.3. if y while en Python Simulaciones con variables aleatorias

Problema: Simular un experimento que se comporta de manera similar al decaimiento radiactivo,


y que consiste en:

Lanzar una cierta cantidad n de dados.

Retirar aquellos que hayan caı́do en un número previamente elegido.

Tomar nota del número de dados restante y lanzarlos.

Repetir el proceso hasta que no queden más dados.

Para simular este experimento, dividimos el problema en ”metas”:

Meta 1. Comencemos por simular el comportamiento de un solo dado, generando un número alea-
torio entero en el intervalo [1,6], esto lo haremos con la función randint(a,b), que recibe como
argumentos los números enteros que definen el intervalo cerrado, esta función es parte del paquete
random.

from random import randint


z = randint(1,6)
print (’El dado cayo en %d’ % z)

Meta 2. El siguiente paso será repetir el proceso anterior un cierto número de veces empleando un
ciclo for. La instrucción for repite la ejecución de las lı́neas que le siguen y que están alineadas en
una sangrı́a (indentación) mayor. En el programa se muestra esta sangrı́a en color azul:

from random import randint


for i in range(10):
z = randint(1,6)
print(’El dado cayo en %d’ % z)

65 R. Espejel
Computación

Recuerden que el ciclo for actúa sobre los elementos de la lista que devuelve la función range,
la cual podemos incluir directamente en la lı́nea del for. Incluyamos ahora una variable n que será
el número de dados que se lanzará, de este modo podremos modificar este valor.

from random import randint


n = 10
for i in range(n):
z = randint(1,6)
print(’El dado cayo en %d’ % z)

Meta 3. Ahora contemos cuántas veces cae el dado en el número 5, empleando la instrucción if
para condicionar el incremento de na variable c. La instrucción if condiciona la ejecución de las
lı́neas que le siguen y que están alineadas en una sangrı́a (indentación) mayor, indicada en rojo.

from random import randint


n = 10
c = 0
for i in range(n):
z = randint(1,6)
if z == 5:
c = c + 1
print (’El dado cayo en %d’ % z)
print (’el dado cayo en 5, %d veces’ % c)

Noten que la última lı́nea no tiene sangrı́a, por lo tanto está fuera del ciclo for, por lo tanto se
ejecutará una sola vez.

Ahora calculemos el número de dados que quedan restando c a n y reasignándole este nuevo valor:

from random import randint


n = 10
c = 0
for i in range(n):
z = randint(1,6)
if z == 5:
c = c + 1
print (’el dado cayo en 5, %d veces’ % c)
n = n - c
print (’Quedan %d dados’ % n)

Hemos eliminado la lı́nea print (’El dado cayo en %d’ % z) para mostrar sólo el número de
dados que cayó en 5 y el número de dados que quedan.

R. Espejel 66
Computación

Meta 4. Por último, incluyamos el ciclo for dentro de un ciclo while con la condición n > 0, es
decir ”mientras haya dados”. Noten que las lı́neas de código que son controladas por instrucciones
while, for, if, etc. se agrupan conservando un nivel de sangrı́a.

from random import randint


n = 10
while n>0:
c = 0
for i in range(n):
z = randint(1,6)
if z == 5:
c = c + 1
n = n - c
print (’Quedan %d dados’ % n)

Hemos eliminado la lı́nea print (’el dado cayo en 5, %d veces’ % c) para mostrar sólo el
número de dados que quedan.

Noten que en Python, los ciclos o condicionales anidados (uno dentro de otro), se organizan por
niveles, como se puede ver en el programa anterior, el nivel del while está indicado en verde, el del
for en azul, y el del if en rojo.

67 R. Espejel
Computación

Ejercicios. Practicando el ciclo for en Python


Para resolver algunos de estos ejercicios en Python necesitarás importar el paquete math (el
equivalente a las librerı́as de C) para poder usar las funciones seno y coseno. La sintaxis para
incluir paquetes es la siguiente:

from math import *

Esta lı́nea hará que se incluyan todas las funciones del paquete math. En caso de que deseemos sólo
incluir ciertas funciones, sustituirı́amos el asterisco por el nombre de las funciones separadas por
comas. Es decir, si sólo usaremos las funciones seno y coseno podremos sustituir esta lı́nea por:

from math import sin,cos

Ejercicio 1. Elabora un programa que genere y muestre los primeros n elementos de la sucesión:

{1, 2, 4, 7, 11, 16, 22, . . .},

donde n es un número solicitado al usuario.

Ejercicio 2. Elabora un programa que genere y muestre los elementos menores que n de la suce-
sión:

{1, 2, 4, 7, 11, 16, 22, . . .},

donde n es un número solicitado al usuario.

Ejercicio 3. Elabora un programa que genere 100 números aleatorios en el intervalo [1,20] y reporte
el mayor, el menor y el promedio.

Ejercicio 4. Elabora un programa que calcule el promedio de n valores solicitados al usuario (n es


solicitada también).

Ejercicio 5. Elabora un programa que te permita estimar el lı́mite de la serie:


X 1
2n
n=1

Ejercicio 6. Implementa el ejemplo de la tabla de multiplicar. El programa debe consultar al usuario


un número y mostrar la tabla de multiplicar correspondiente en el intervalo [1,10].

R. Espejel 68
Computación

Ejercicio 7. Elabora un programa que muestre las coordenadas x, y de los vértices de un polı́gono
regular, centrado en el origen, de N lados de longitud d. Tanto N como d son datos
solicitados al usuario.

Hint: Considera que los vértices del polı́gono estarán dis- Q


tribuidos cada 2π/N radianes sobre una circunferencia de
radio r, y que el primer vértice está en la coordenada (r, 0). d
2 P
Entonces, del triángulo OP Q se obtiene que: r
d
2π θ
 
θ d 2
r sin = , con θ = , (r, 0)
2 2 N r
O
de donde puedes obtener r.

69 R. Espejel
Computación

2.4. Juego adivina mi número.


Recordemos el juego de Adivina mi Número. Se trata de adivinar, en la menor cantidad de
intentos, un número al azar que genera el programa. Hagámoslo en Python.

Meta 1. Comencemos por generar un número aleatorio usando la función randint que forma parte
del paquete random:

from random import randint


z = randint(1,20)
print (’El numero es’,z)

Hemos incluido la instrucción print para mostrar el número y comprobar que se genera correc-
tamente.
Meta 2. Consultemos ahora al usuario su número usando la función input:

from random import randint


z = randint(1,20)
n = input(’Que numero crees que es? ’)
print (’El numero es’,z)

Meta 3. Comparemos ambos números con if mostrando los mensajes correspondientes al usuario:

from random import randint


z = randint(1,20)
n = input(’Que numero crees que es? ’)
if n>z: print (’El numero que diste es mayor’)
if n<z: print (’El numero que diste es menor’)
print (’El numero es’,z)

notemos que, cuando if, for, etc. actúan sobre una sola lı́nea, no es necesario “agrupar” esta lı́nea
con sangrı́a. El programa hasta ahora harı́a algo como lo siguiente:

Que numero crees que es? 10


El numero que diste es menor
El numero es 13

Meta 4. Ahora, lo único que falta es incluir las lı́neas adecuadas dentro de un ciclo para que el
programa nos de más oportunidades de adivinar el número. En C podrı́amos usar un ciclo tipo do
while, el cual no está implementado en Python, por lo que tendremos que usar un while True
como si fuera un ciclo “infinito”, e incluir in if al final para condicionar la instrucción break que
obliga al programa a salir del ciclo donde se encuentre:

R. Espejel 70
Computación

from random import randint


z = randint(1,20)
while True:
n = input(’Que numero crees que es? ’)
if n>z: print (’El numero que diste es mayor’)
if n<z: print (’El numero que diste es menor’)
if n==z: break
print (’Adivinaste!’)
print (’El numero es’,z)

Esto es, si se cumple la condición del último if, significa que el usuario adivinó el número y sale
del ciclo. Incluyamos ahora un contador que indique cuántos intentos lleva el jugador:

from random import randint


z = randint(1,20)
c = 0
while True:
c = c + 1
n = input(’ Intento %d. Que numero crees que es? ’ % c)
if n>z: print (’El numero que diste es mayor’)
if n<z: print (’El numero que diste es menor’)
if n==z: break
print (’Adivinaste!’)
print (’El numero es’,z)

El programa ahora funcionarı́a ası́:

Intento 1. Que numero crees que es? 10


El numero que diste es menor
Intento 2. Que numero crees que es? 15
El numero que diste es menor
Intento 3. Que numero crees que es? 20
El numero que diste es mayor
Intento 4. Que numero crees que es? 17
El numero que diste es mayor
Intento 5. Que numero crees que es? 16
Adivinaste!
El numero es 16

71 R. Espejel
Computación

Meta 5. Ahora limitaremos a 5 el número de intentos, aumentando la conjunción lógica or (también


existe and), de modo que el programa salga del ciclo si el jugador acertó o en el caso de que haya
excedido el número de intentos. Para dar al jugador el mensaje correcto ( Adivinaste! o Perdiste),
debemos incluir un if con else:

from random import randint


z = randint(1,20)
c = 0
while True:
c = c + 1
n = input(’ Intento %d. Que numero crees que es? ’ % c)
if n>z: print (’El numero que diste es mayor’)
if n<z: print (’El numero que diste es menor’)
if n==z or c>4: break
if n==z: print (’Adivinaste!’)
else: print (’Perdiste. El numero es’,z)

R. Espejel 72
Computación

Ejercicios de evaluación. Perfeccionando el Juego Adivina mi Núme-


ro en Python
Ejercicio 1. Modifica el programa de la clase:

from random import randint


z = randint(1,20)
c = 0
while True:
c = c + 1
n = input(’ Intento %d. Que numero crees que es? ’ % c)
if n>z: print (’El numero que diste es mayor’)
if n<z: print (’El numero que diste es menor’)
if n==z or c>4: break
if n==z: print (’Adivinaste!’)
else: print (’Perdiste. El numero es’,z)

para que muestre los mensajes El numero que diste es mucho mayor (o mucho menor)
si la diferencia es mayor o igual a 10, o El numero que diste es un poco mayor (o
un poco menor) si la diferencia es menor o igual a 3. Recuerda que puedes usar if
anidados, ası́ como las conjunciones lógicas or y and.

Ejercicio 2. Modifica el programa del ejercicio anterior para que muestre al final del juego, la
lista completa de los números que dio el jugador. Puedes empezar con una lista vacı́a
A = [] y usar el método append que se mencionó la clase anterior.

73 R. Espejel
Computación

2.5. Reforzamiento.
Resolvamos el siguiente problema: Para automatizar una caja registradora, nos han pedido que
elaboremos un programa en Python que, dada una cantidad n de dinero, muestre esta cantidad
representada en el menor número de monedas/billetes posible. Por ejemplo, si damos la cantidad
n = $3497, el programa mostrarı́a lo siguiente:
6 billetes de 500
2 billetes de 200
1 billete de 50
2 billetes de 20
1 moneda de 5
1 moneda de 2
Para plantear el programa, pensemos en la manera en la que pagamos una cantidad de dine-
ro con billetes o monedas de diferente denominación, haciendo consciente el proceso mental que
seguimos. Una forma de hacerlo es: vamos entregando los billetes de mayor denominación y por
cada uno que entregamos restamos mentalmente su denominación a la cantidad que debemos, de
modo que con cada billete que entregamos esta cantidad va disminuyendo. Entonces si queremos
pagar, por ejemplo, $1800 pesos, empezamos entregando un billete de $500, y quedan por pagar
$1300, entregamos otro de $500, quedan $800, entregamos otro más de $500, y quedan $300. En este
punto, no podemos entregar un billete más de $500 (porque esta cantidad excede lo que debemos),
entonces, pasamos a los billetes de la siguiente denominación, que serı́an los de $200, etc.
n Denominación
$1800 $500
$1300 $500
$800 $500
$300 $200
$100 $100
$0
Notemos que dejamos de entregar billetes de cierta denominación cuando la cantidad n que
debemos es menor a esta denominación. Es decir entregamos billetes (o monedas) de denominación
k mientras n es mayor o igual a k, y este proceso lo repetimos para cada denominación, es decir,
comenzamos con los billetes de $500, seguimos con los de $200, luego con los de $100, los de $50, etc.
Las palabras clave que debemos tomar en cuenta para plantear la estructura de nuestro programa
son mientras (while) y para cada (for).

Recordemos que en Python, el ciclo for actúa sobre los elementos de una lista y, ya que tenemos
que cierto proceso, lo realizamos para cada denominación, hagamos primero una lista con las
denominaciones de billetes o monedas posibles:
D = [500,200,100,50,20,10,5,2,1]
Ası́, si incluimos algo como for k in D:, k tomará el valor de cada elemento de la lista D en cada
repetición, por ejemplo, si ejecutamos el siguiente programa:
D = [500,200,100,50,20,10,5,2,1]
for k in D:
print (k)

R. Espejel 74
Computación

obtendremos:

500
200
100
50
20
10
5
2
1

Ahora, lo que queremos repetir para cada calor de k es un proceso de ir restando k a n mientras
n es mayor o igual a k, entonces podemos implementar algo como lo siguiente:

D = [500,200,100,50,20,10,5,2,1]
n = int(input(’Dame una cantidad ’))
for k in D:
while n>=k:
n = n - k
print (’un billete de’,m)

En este programa, no estamos haciendo diferencia entre monedas o billetes, de modo que al ejecu-
tarlo, y darle la cantidad de $3497, la salida serı́a:

Dame la cantidad 3497


un billete de 500
un billete de 500
un billete de 500
un billete de 500
un billete de 500
un billete de 500
un billete de 200
un billete de 200
un billete de 50
un billete de 20
un billete de 20
un billete de 5
un billete de 2

D = [500,200,100,50,20,10,5,2,1]
n = int(input(’Dame una cantidad ’))
for k in D:
while n>=k:
n = n - k
if k>=20:
print (’un billete de’,k)
else:
print (’una moneda de’,k)

75 R. Espejel
Computación

O bien:

D = [500,200,100,50,20,10,5,2,1]
n = int(input(’Dame una cantidad ’))
for k in D:
while n>=k:
n = n - k
if k>=20:
mensaje = ’un billete de’
else:
mensaje = ’una moneda de’
print (mensaje,k)

Aparentemente este último código no tiene ninguna ventaja sobre el anterior, sin embargo, nos
permite ver el programa de una forma tal que podemos identificar una forma de optimizarlo por
medio de lo que llamamos operador ternario, es decir, empleando un operador que permite decidir
el asignar un valor u otro a una variable, a través de una condición (Ver la clase de matrices del 30
de marzo):

variable = valor para verdadero if condición else valor para falso

Ası́, si se cumple la condición, a la variable se le asigna el valor para verdadero, y de lo contrario


se le asigna el valor para falso. Usando esta estructura, el programa quedarı́a ası́:

D = [500,200,100,50,20,10,5,2,1]
n = int(input(’Dame una cantidad ’))
for k in D:
while n>=k:
n = n - k
mensaje = ’un billete de’ if k>=20 else ’una moneda de’
print (mensaje,k)

R. Espejel 76
Computación

Pero aún no tenemos el tipo de mensajes que planteamos al principio de estas notas, ya que
queremos que nos muestre la cantidad total de billetes de cada denominación, para ello podemos
incluir una variable que actúe como contador:

D = [500,200,100,50,20,10,5,2,1]
n = int(input(’Dame una cantidad ’))
for k in D:
c = 0
while n>=k:
n = n - k
c = c + 1
mensaje = ’billetes de’ if k>=20 else ’monedas de’
print (c,mensaje,k)

Ası́, el programa darı́a el siguiente resultado:

Dame la cantidad 3497


6 billetes de 500
2 billetes de 200
0 billetes de 100
1 billetes de 50
2 billetes de 20
0 monedas de 10
1 monedas de 5
1 monedas de 2
0 monedas de 1

Podemos inhibir los ceros incluyendo un if:

D = [500,200,100,50,20,10,5,2,1]
n = int(input(’Dame una cantidad ’))
for k in D:
c = 0
while n>=k:
n = n - k
c = c + 1
if c>0:
mensaje = ’billetes de’ if k>=20 else ’monedas de’
print (c,mensaje,k)

77 R. Espejel
Computación

Por último, podemos anidar los operadores ternarios para distinguir el singular o plural, es decir,
a partir de la cantidad, escribir moneda o monedas y billete o billetes.

D = [500,200,100,50,20,10,5,2,1]
n = int(input(’Dame una cantidad ’))
for k in D:
c = 0
while n>=k:
n = n - k
c = c + 1
if c>0:
mensaje = (’billete de’ if c==1 else ’billetes de’) if k>=20 else (’moneda de’ if c==1
else ’monedas de’)
print (c,mensaje,k)

De esta forma, el operador externo (en verde) decidirá si son billetes o monedas, y los internos
(azul y rojo), decidirán si es singular o plural:

Dame la cantidad 3497


6 billetes de 500
2 billetes de 200
1 billete de 50
2 billetes de 20
1 moneda de 5
1 moneda de 2

R. Espejel 78
Computación

Ejercicios.
Ejercicio 1. Modifica el ultimo programa de la clase de hoy, de modo que no sea necesario usar el
ciclo while. Es decir, calcula el número de monedas o billetes con una división (si es
necesario, puedes obtener la parte entera de una cantidad x con int(x)).

Ejercicio 2. La numeración romana original está basada en la numeración etrusca, la cual, a su vez
se basa en un sistema aditivo. Por ejemplo, el 4 en la numeración etrusca se representaba
como IIII (1+1+1+1), mientras que en la numeración romana moderna se representa
como IV (1 restado a 5). Usando la numeración romana original, es decir sin resta, y
basándote en los programas de la clase, elabora un programa para convertir números
arábigos a romanos.

Ejercicio 3. En electrónica, se usa un código de colores para identificar el valor en Ohms de una
resistencia. Elabora un programa que consulte al usuario el valor de una resistencia
en Ohms y le muestre los colores que la representan (Si es necesario puedes obtener el
logartimo de x con log(x,base) y el paquete math). Vean:
[Link]
Ejemplo de ejecución:

Dame el valor de la resistencia en Ohms: 2300


El codigo de colores es:
Rojo
Naranja
Rojo

79 R. Espejel
Computación

2.6. Más listas y Juego del Ahorcado.

En esta ocasión haremos una versión del Juego del Ahorcado. Para ello necesitamos conocer
algunas funciones nuevas.
Veamos el siguiente programa:

L = [’A’, ’B’, ’C’, ’D’]


for contador, elemento in enumerate(L):
print (contador, elemento)

Noten que en el ciclo for hay ahora dos variables (contador y elemento), y después de in está la
lista L como argumento de la función enumerate. Esta función, al evaluarla sobre la lista L genera
la siguiente estructura:

[(0, ’A’), (1, ’B’), (2, ’C’), (3, ’D’)]

Esto es, genera una lista de duplas que contiene, cada una, como primer entrada un contador
que enumera a cada elemento de la lista, que aparece como segunda entrada.

Ası́, cuando implementamos un ciclo for como el del programa anterior, la variable elemento
tomará el valor de cada uno de los elementos de la lista L y la variable contador tomará el valor
de las posiciones de cada elemento. Entonces, al ejecutar el programa mostrarı́a lo siguiente:

0 A
1 B
2 C
3 D

Por otro lado, para el Juego del Ahorcado, necesitaremos convertir cadenas de texto en listas y
viceversa:

T = ’Hola Mundo’
L = list(Texto)
print (L)

En el programa, usamos la función list para convertir la cadena de texto T a una lista cuyos
elementos son cada uno de sus caracteres, de modo que se mostrará lo siguiente:

[’H’, ’o’, ’l’, ’a’, ’ ’, ’M’, ’u’, ’n’, ’d’, ’o’]

R. Espejel 80
Computación

Ahora, en el siguiente programa, comenzamos con la lista de caracteres L, y con el método join
unimos cada uno de los elementos de la lista en la cadena de texto T y, en este caso, incluimos un
asterisco entre cada uno:

L = [’H’, ’o’, ’l’, ’a’, ’ ’, ’M’, ’u’, ’n’, ’d’, ’o’]


T = ’*’.join(L)
print (T)

por lo que el programa mostrará lo siguiente:

H*o*l*a* *M*u*n*d*o

Podemos ejecutar el método join sobre un caracter vacı́o para recuperar la cadena original:

L = [’H’, ’o’, ’l’, ’a’, ’ ’, ’M’, ’u’, ’n’, ’d’, ’o’]


T = ’’.join(L)
print (T)

Ahora el programa mostrará lo siguiente:

Hola Mundo

El ahorcado es un juego para dos jugadores (en nuestro caso el jugador y la computadora). Un
jugador piensa en una palabra y el otro trata de adivinarla letra por letra.
Se representa la palabra a adivinar usando una fila de tantos guiones como letras tenga la pa-
labra. Si el jugador dice una letra que aparece en la palabra, el otro jugador la escribe en todas
sus posiciones correctas. Si la letra o el número sugerido no aparece en la palabra, se acumula un
error a un contador que puede representarse como cada uno de los elementos de un dibujo de un
hombre ahorcado. El juego termina cuando el jugador completa la palabra, o cuando se acumula
una cierta cantidad de errores (completando el dibujo del ahorcado).

La idea general del programa es la siguiente; asignamos la palabra a adivinar a una variable
(posteriormente la podremos elegir al azar de una lista de palabras o de un archivo de texto),
la convertimos en una lista y creamos otra lista con tantos guiones como letras tenga la palabra
(¿recuerdan la estructura que replica expresiones para formar una lista con un for?). Algo como
lo siguiente:

P = ’python’
L = list(P)
A = [’ ’ for i in L]
print (’ ’.join(A))

En la penúltima lı́nea estamos replicando la expresión (el caracter) ’ ’ para cada uno de los
elementos de la lista L, teniendo ası́ una lista con tantos ’ ’ como caracteres tenga la cadena de
caracteres (palabra) P. De modo que el programa simplemente mostrará 6 guiones bajos separados
por espacios:

81 R. Espejel
Computación

Elaboraremos un procedimiento para ir sustituyendo los guiones de la lista A por las letras
que proponga el jugador en los lugares que coincidan con los elementos de la lista L. Primero
consultamos al jugador la propuesta de la letra, usando la función input. Luego usaremos un ciclo
for para ir checando si la letra que propuso el jugador coincide con alguna de la lista L y, en ese
caso, sustituir el guión de la posición equivalente de la lista A con esa letra.

P = ’python’
L = list(P)
A = [’ ’ for i in L]
print (’ ’.join(A))
letra = input(’Dame una letra ’)
for k,p in enumerate(L):
if p == letra:
A[k]=letra
print (’ ’.join(A))

Nota que en el ciclo for, la variable p toma el valor de cada una de las letras de la lista L,
mientras que la variable k toma el valor de la posición de cada una de ellas. Entonces gracias a la
función enumerate podemos tener la información del lugar de la lista A que debemos sustituir por
la letra correspondiente.
Al ejecutar el programa e introducir una letra que esté contenida en la palabra python, por
ejemplo, la letra t, tenemos lo siguiente:

Dame una letra t


t

Es claro que el objetivo del juego es hacer coincidir las listas A y L. Entonces si, por lo pronto,
no tomamos en cuenta los errores, es decir, tenemos un numero infinito de oportunidades, podemos
plantear un ciclo while con la condición A!=L,

P = ’python’
L = list(P)
A = [’ ’ for i in L]
print (’ ’.join(A))
while A!=L:
letra = input(’Dame una letra ’)
for k,p in enumerate(L):
if p == letra:
A[k]=letra
print (’ ’.join(A))
print (’Ganaste!’)

R. Espejel 82
Computación

Ahora, si hacemos una lista de palabras, por ejemplo

Palabras = [’perro’, ’gato’, ’loro’, ’caballo’, ’cebra’, ’jirafa’, ’gallo’]

podemos generar un número aleatorio entre cero y el número de elementos de la lista menos uno
con la función randint y ası́ elegir un elemento al azar de la lista de palabras:

from random import randint


Palabras = [’perro’, ’gato’, ’loro’, ’caballo’, ’cebra’, ’jirafa’, ’gallo’]
z = randint(0,len(Palabras)-1)
P = Palabras[z]

donde hemos usado la función len para obtener el número de elementos de la lista, o bien, emplea-
mos directamente la función choice para elegir un elemento al azar:

from random import choice


Palabras = [’perro’, ’gato’, ’loro’, ’caballo’, ’cebra’, ’jirafa’, ’gallo’]
P = choice(Palabras)

83 R. Espejel
Computación

Ejercicios.
Ejercicio 1. Implementa la selección de un elemento al azar de una lista al ultimo programa del
juego del ahorcado.

Ejercicio 2. Aumenta a este programa el contador de errores. Recuerda que el contador debe in-
crementarse en uno cuando la letra que propone el usuario no está en la palabra a
adivinar.
Hint: Puedes hacer una variable e=1 antes del ciclo for y asignarle el valor de cero
dentro del if, ası́ si no se encuentra la letra, esta variable e quedará con el valor de
uno; y de cero si se encontró. Ası́ puedes hacer algo como E = E + e fuera del ciclo
for.

Ejercicio 3. Otra regla del juego menciona que, si el jugador que adivina repite una letra que ya
ha sido “descubierta” se cuenta como error. Incorpora esta regla al programa.
Hint: Puedes sustituir la letra “adivinada” en la palabra original por un caracter es-
pecial.

R. Espejel 84
Computación

2.7. Matrices en Python

Como se ha manejado en secuencias anteriores, en Python, una lista puede contener como
elementos a diversos tipos de variable (más adelante veremos que puede contener objetos, funciones,
etc), incluso puede contener otras listas. Ası́, podemos asignar a una variable A una lista como la
siguiente:



 5 4 1 A[0]
3 7 6 A[1]



A = [[5,4,1],[3,7,6],[1,2,9],[4,3,4],[9,8,1]] 1 2 9 A[2]
4 3 4



 A[3]
9 8 1

A[4]

Ası́, por ejemplo, el tercer elemento de la lista A, es decir, A[2], será [1,2,9], y el segundo elemento
de éste, A[2][1] será 2. De este modo, tendremos una matriz.
De modo que si tenemos una matriz definida como una lista de listas, podemos usar un cilclo
for para mostrar cada una de ellas:

A = [[5,4,1],[3,7,6],[1,2,9],[4,3,4],[9,8,1]]
for a in A:
print (a)

y tendremos la salida siguente:

[5, 4, 1]
[3, 7, 6]
[1, 2, 9]
[4, 3, 4]
[9, 8, 1]

Esto es, la variable a del for toma el valor de cada elemento de la lista A (renglones de la
matriz), los cuales son, a su vez, una lista. Podemos obtener una impresión más agradable de la
matriz, imprimiendo cada elemento de ésta, seguido de un tabulador, con el siguiente código:

A = [[5,4,1],[3,7,6],[1,2,9],[4,3,4],[9,8,1]]
for a in A:
for i in a:
print (’ %d’ % i,end = ’\t’)
print()

85 R. Espejel
Computación

Lo que muestra en pantalla lo siguiente:

5 4 1
3 7 6
1 2 9
4 3 4
9 8 1

En el programa anterior incluimos un segundo ciclo for con variable i, la cual toma el valor de
cada lista (renglón) y lo imprimimos seguido de un tabulador. Noten que hemos inhibido el salto
de lı́nea intrı́nseco a print, sustituyéndolo por un tabulador (\t) y ası́ mostrar todos los elementos
de cada renglón en la misma lı́nea, lo cual nos obliga a incluir un print al final del for interior
sólo para saltar al renglón siguiente.

Recordemos la estructura:

T = [0 for i in range(5)]

Esta estructura replica la expresión en color azul (cero) dentro de una lista, obteniendo ası́ una
lista con 5 ceros. Del mismo modo, podemos hacer que la expresión que se replique sea una lista:

T = [[0 for c in range(3)] for r in range(5)]

La parte azul de este código replica la expresión cero formando una lista de 3 ceros, y esta lista
a su vez se replica, gracias a la parte roja, formando ası́ una lista de 5 listas de 3 ceros cada una,
es decir una matriz de 5 × 3. De modo que si incluimos esta lı́nea en el programa anterior:

A = [[0 for c in range(3)] for r in range(5)]


for a in A:
for i in a:
print (’ %d’ % i,end = ’\t’)
print()

Tendremos lo siguiente:

0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

También podemos sustituir la expresión que se replica (cero) por la función que genera números
aleatorios enteros, randint para obtener una matriz de números aleatorios:

from random import randint


A = [[randint(0,20) for c in range(3)] for r in range(5)]
for a in A:
for i in a:
print (’ %d’ % i,end = ’\t’)
print ()

R. Espejel 86
Computación

Tendremos lo siguiente:

5 0 20
3 16 7
15 1 0
17 17 8
15 16 5

Modifiquemos el programa anterior para obtener la matriz identidad de 10×10 usando el opera-
dor ternario sobre las variables r y c como expresión a replicar, recuerda que estas variables toman
los valores de cada uno de los elementos de las listas de sus respectivos for, en este caso, ambas
listas son las que devuelve la función range evaluada en 10, es decir, la lista [0,1,2,3,4. . .,9].
Recuerda también que la matriz identidad tiene 1’s en la diagonal principal y ceros en el resto de
las entradas, y los ı́ndices de la diagonal principal son aquellos en que el número de renglón coincide
con el número de columna.

A = [[1 if r==c else 0 for c in range(10)] for r in range(10)]


for a in A:
for i in a:
print (’ %d’ % i,end = ’\t’)
print ()

También podemos sumar dos matrices con entradas aleatorias con el siguiente código:

from random import randint


A = [[randint(0,20) for c in range(5)] for r in range(5)]
B = [[randint(0,20) for c in range(5)] for r in range(5)]
C = [[0 for c in range(5)] for r in range(5)]
for r in range(5):
for c in range(5):
C[r][c]=A[r][c]+B[r][c]
print ’La suma es:’
for k in C:
for i in k:
print (’ %d’ % i,end = ’\t’)
print ()

87 R. Espejel
Computación

Ejercicios. Matrices con Python


Ejercicio 1. Captura el siguiente programa y, a partir de lo que imprime, explica que hace la fun-
ción zip:

A = [1,2,3]
B = [4,5,6]
C = zip(A,B)
print (list(C))
for c in C:
print (c)

Ejercicio 2. Analiza el siguiente programa y explica su funcionamiento, ¿Qué es la matriz D? ¿Qué


realción tiene con A y B?

from random import randint


A = [[randint(0,10) for c in range(5)] for r in range(5)]
B = [[randint(0,10) for c in range(5)] for r in range(5)]
D = []
for r,a in enumerate(zip(A,B)):
C = []
for c,b in zip(a[0],a[1]):
[Link](c+b)
[Link](C)

R. Espejel 88
Computación

2.8. Gráficas con Python. MatPlotLib

En esta secuencia te guiaremos para crear una gráfica, ya sea de funciones o de datos fijos usando
el paquete MatPlotLib. Comencemos por graficar los valores de una lista Y contra los de otra lista
X. Para ello tenemos que importar el paquete MatPlotLib y definir nuestras listas a graficar:

import [Link] as plt


X = [0,1,2,3,4,5]
Y = [0,1,4,9,16,25]
Fig, ax = [Link]()
[Link](X, Y)
[Link]()

Con la lı́nea marcada en rojo, creamos una figura Fig, y dentro de ella una gráfica ax. En este
caso, la gráfica es de tipo scatter, como lo especificamos en la lı́nea azul, esto es, una gráfica
de puntos definidos por pares ordenados (el equivalente de dispersión, en Excel). En esta mis-
ma lı́nea azul especificamos las listas que vamos a graficar, esto es, los pares ordenados serı́an
(0, 0), (1, 1), (2, 4), (3, 9), . . . , (5, 25). Con la última lı́nea [Link]() mostramos la gráfica que he-
mos construido:

89 R. Espejel
Computación

Podemos cambiar el tipo de gráfico sustituyendo scater por plot, obteniendo lo siguiente:

Podemos especificar también un tipo de marcador y el color, por ejemplo. También especificar
el nombre de los ejes y el tı́tulo de la gráfica:

import [Link] as plt


X = [0,1,2,3,4,5]
Y = [0,1,4,9,16,25]
Fig, ax = [Link]()
[Link](X, Y,color=’red’,marker=’o’)
[Link] xlabel(’Nombre del eje X’)
[Link] ylabel(’Nombre del eje Y’)
[Link] title(’Titulo de la Grafica’)
[Link]()

R. Espejel 90
Computación

Y podemos incluir también una leyenda y especificar su localización:

import [Link] as plt


X = [0,1,2,3,4,5]
Y = [0,1,4,9,16,25]
Fig, ax = [Link]()
[Link](X, Y,color=’red’,marker=’o’,label=’Ejemplo 1’)
[Link] xlabel(’Nombre del eje X’)
[Link] ylabel(’Nombre del eje Y’)
[Link] title(’Titulo de la Grafica’)
[Link](loc=’upper left’)
[Link]()

El hacer la gráfica de una función se reduce a evaluar ésta en una serie de datos (lista de
abscisas) obteniendo otra lista (de ordenadas) y, a partir de lo que se mostró anteriormente, generar
la gráfica. Aunque ésto podemos hacerlo con las funciones y estructuras que conocemos, los paquetes
MatPlotLib y NumPy nos ofrecen otras herramientas útiles que veremos más adelante.

import [Link] as plt


from math import *
X = [t/101.0 * 2*pi for t in range(101)]
Y1 = [sin(x) for x in X]
fig, ax = [Link]()
[Link](X,Y1)
[Link]()

91 R. Espejel
Computación

Como ya hemos visto, con la lı́nea marcada en rojo creamos una lista replicando la expresión
2π t/100 para los valores de t tomados de la lista generada por range(101), es decir, la lista
[0,1,2,3,. . .,100]; de modo que la lista X tiene 101 elementos, los cuales toman los valores desde
0 hasta 2π en intervalos regulares. Es claro entonces, que la lı́nea marcada en verde genera la lista
Y evaluando la función seno en los valores de los elementos de la lista X, y podemos especificar el
nombre de los ejes, la leyenda y el tı́tulo de la gráfica:

import [Link] as plt


from math import *
X = [t/100.0 * 2*pi for t in range(100)]
Y1 = [sin(x) for x in X]
fig, ax = [Link]()
[Link](X,Y1, label=’sen(x)’)
[Link] xlabel(’x’)
[Link] ylabel(’sen(x)’)
[Link] title("Grafica")
[Link](loc=’upper center’)
[Link]()

R. Espejel 92
Computación

También podemos superponer la gráfica de otra función:

import [Link] as plt


from math import *
X = [t/100.0 * 2*pi for t in range(100)]
Y1 = [sin(x) for x in X]
Y2 = [cos(x) for x in X]
fig, ax = [Link]()
[Link](X,Y1, label=’sen(x)’)
[Link](X,Y2, label=’cos(x)’)
[Link] xlabel(’x’)
[Link] title("Grafica")
[Link](loc=’upper center’)
[Link]()

Ahora bien, en el paquete NumPy está implementada la función linspace que nos permite crear
y evaluar más fácilmente las listas que se graficarán:

import [Link] as plt


import numpy as np
X = [Link](0, 2*[Link], 100)
Y1 = [Link](X)
Y2 = [Link](X)
fig, ax = [Link]()
[Link](X,Y1, label=’sen(x)’)
[Link](X,Y2, label=’cos(x)’)
[Link] xlabel(’x’)
[Link] title("Grafica")
[Link](loc=’upper center’)
[Link]()

Con la lı́nea marcada en azul, creamos una lista con las mismas caracterı́sticas que en el caso ante-
rior, es decir, comienza en cero, termina en 2π y el valor de sus 100 elementos está uniformemente
espaciado.
Podemos especificar directamente la evaluación de la función en el método plot. Es decir, sin
asignar las variables Y1 y Y2, con lo que tenemos un código más compacto:

import [Link] as plt


import numpy as np
X = [Link](0, 2*[Link], 100)
fig, ax = [Link]()
[Link](X,[Link](X), label=’sen(x)’)
[Link](X,[Link](X), label=’cos(x)’)
[Link] xlabel(’x’)
[Link] title("Grafica")
[Link](loc=’upper center’)
[Link]()

93 R. Espejel
Computación

Del mismo modo, es fácil hacer una gráfica paramétrica en 3D:

import [Link] as plt


import numpy as np
from mpl toolkits.mplot3d import Axes3D
fig = [Link]()
ax = [Link](projection=’3d’)
t = [Link](-5 * [Link], 5 * [Link], 500)
X = 5 * [Link](t)
Y = 5 * [Link](t)
Z = t
[Link](X, Y, Z, label=’Curva Parametrica’)
[Link]()
[Link]()

O bien, generar una gráfica tipo z = f (x, y). En este caso f (x, y) = sen(x) cos(y), en el
plano [−π, π] × [−π, π].

import [Link] as plt


from matplotlib import cm
import numpy as np
from mpl toolkits.mplot3d.axes3d import get test data
fig = [Link]()
ax = [Link](projection=’3d’)
X = [Link](-[Link], [Link], 0.25)
Y = [Link](-[Link], [Link], 0.25)
X,Y = [Link](X, Y)
Z = [Link](X)*[Link](Y)
surf=[Link] surface(X,Y,Z, cmap=[Link])
[Link]()

En el código anterior, en las lı́neas marcadas en azul, hemos usado la función arange que es
equivalente a la función range con la diferencia de que la primera, permite generar una lista con
valores de punto flotante. De modo estas lı́neas asignan a las variables X y Y la lista que devuelve
arange(-[Link], [Link], 0.25), que es [−π, −π + 0.25, −π + 0.50, −π + 0.75, . . . , π]. De este modo,
con estas listas, se crea la malla donde se evaluará la función (lı́nea naranja).

R. Espejel 94
Computación

Ejercicios.
Ejercicio 1. Genera la gráfica y = x2 + 3x en el intervalo [−5, 5].

Ejercicio 2. Elabora un programa que consulte al usuario los coeficientes de un polinomio de ter-
cer grado, ası́ como xmin y xmax y genere la gráfica correspondiente en el intervalo
[xmin , xmax ].

Ejercicio 3. Modifica el programa anterior para que se consulte al usuario, además, el grado del
polinomio.

95 R. Espejel
Computación

2.9. Funciones y recursividad.


A lo largo de esta secuencia aprenderemos cómo definir nuestras propias funciones.
Para nuestros propósitos, podemos ver a una función como una caja negra, que transforma los
valores de entrada en los valores de salida.

Por ejemplo, la función coseno (cos(θ)), toma un valor de entrada (argumento), que es un ángulo
y nos da como valor de salida (devuelve) la longitud del cateto adyacente del triángulo rectángulo
con hipotenusa unitaria correspondiente a ese ángulo (valor de entrada). Sabemos que esta función
está definida en Python en varios paquetes (math, numpy, etc).

Veamos el siguiente programa:

from math import *


x = cos(pi)

En el programa, la variable x queda con el valor de −1, mismo que devuelve la función cos al
ser evaluada en π. Decimos que la función cos, recibe como argumento el valor de π y devuelve el
valor de −1.
Otro ejemplo serı́a la función f (x) = 2x2 , esta función toma como argumento un número y
nos devuelve el doble de su cuadrado. En Python, podemos definir esta función con el siguiente
programa:

def MiFuncion(x):
y = 2*(x**2)
return y

Si ejecutamos este programa, no veremos ninguna salida, ya que sólo hemos definido una función,
pero no la hemos usado (llamado). Completemos el programa de modo que quede como sigue:

def MiFuncion(x):
y = 2*(x**2)
return y
z = MiFuncion(3)
print (z)

R. Espejel 96
Computación

Veremos entonces que la variable z queda con el valor de 18, que es el valor que muestra el
programa al ejecutarse. De este modo podemos, por ejemplo, tabular la función para diferentes
valores:

from numpy import arange


def MiFuncion(x):
y = 2*(x**2)
return y
for z in arange(0,5,0.5):
print (’f( %f) = %f’ % (z,MiFuncion(z)))

Al ejecutarse veremos lo siguiente:

f(0.000000) = 0.000000
f(0.500000) = 0.500000
f(1.000000) = 2.000000
f(1.500000) = 4.500000
f(2.000000) = 8.000000
f(2.500000) = 12.500000
f(3.000000) = 18.000000
f(3.500000) = 24.500000
f(4.000000) = 32.000000
f(4.500000) = 40.500000

(Recuerda que la función arange(a,b,c) devuelve una lista con valores en el intervalo [a, b) con
incrementos de c.)

De este modo, estamos evaluando la función que definimos (MiFuncion) en cada uno de los
valores de los elementos de la lista A.

Podemos definir una función con varios argumentos. Por ejemplo, una función que reciba la
base y la altura de un triángulo y devuelva su área:

def AreaT(b,h):
a = b*h/2
return a

Y también podemos definir una función que devuelva varios valores, haciendo que devuelva una
lista; hagámos una función que reciba el radio r de una esfera y devuelva una lista con los valores
de su volumen, su área y el perı́metro de su ecuador:

def Esfera(r):
v = pi*4.0/3.0*r**3
a = 4*pi*r**2
e = 2*pi*r2
return [v,a,e]

Un programa que use esta función podrı́a ser el siguiente

97 R. Espejel
Computación

from math include pi


def Esfera(r):
v = pi*4.0/3.0*r**3
a = 4*pi*r**2
e = 2*pi*r2
return [v,a,e]
k = Esfera(2)
print (’El volumen de la esfera es: ’, k[0])
print (’El área de la esfera es: ’, k[1])
print (’El perı́metro del ecuador es: ’, k[2])

O bien:

from math include pi


def Esfera(r):
v = pi*4.0/3.0*r**3
a = 4*pi*r**2
e = 2*pi*r2
return [v,a,e]
[x,y,z] = Esfera(2)
print (’El volumen de la esfera es: ’, x)
print (’El área de la esfera es: ’, y)
print (’El perı́metro del ecuador es: ’, z)

De hecho, una función puede ser un programa en sı́ mismo, con ciclos, condicionales etc, e
incluso puede llamar a otras funciones. Veamos el siguiente programa donde se ha definido la función
Muestra que recibe como argumento una matriz y la imprime, nota que no devuelve ningún valor:

from random import randint

def Muestra(M):
for r in M:
for c in r:
print (’ %d’ % c, end = \t)
print()

A = [[randint(0,20) for i in range(4)] for j in range(3)]


Muestra(A)

En el primer for de la función, la variable r toma en valor de cada uno de los elementos de la
lista M, es decir, los renglones de la matriz; en el segundo for la variable c toma el valor de cada
uno de los elementos de r, es decir cada uno de las entradas del renglón. Al terminar la ejecución
de ese ciclo, se ejecuta la lı́nea marcada en naranja, que es un print para dar un salto de lı́nea e
imprimir el siguiente renglón, mostrando lo siguiente:

18 10 9 0
8 5 2 9
13 14 4 18

R. Espejel 98
Computación

El uso de funciones en un programa en Python, es particularmente útil cuando necesitamos hacer


el mismo proceso para diferentes valores u objetos. Por ejemplo, si en un programa necesitamos
mostrar, con el formato anterior, varias matrices, podemos implementar el siguiente programa:

from random import randint

def Muestra(M):
for r in M:
for c in r:
print (’ %d’ % c, end = \t)
print()

A = [[randint(0,20) for i in range(4)] for j in range(3)]


B = [[randint(0,20) for i in range(4)] for j in range(3)]
C = [[randint(0,20) for i in range(4)] for j in range(3)]
print (’A = ’)
Muestra(A)
print (’B = ’)
Muestra(B)
print (’C = ’)
Muestra(C)

y tiene la siguiente salida:

A=
7 18 14 10
10 1 8 9
8 3 11 14
B=
14 7 11 20
7 16 2 8
9 12 19 6
C=
3 10 9 0
1 15 17 3
18 14 6 20

99 R. Espejel
Computación

Un aspecto interesante en este tipo de lenguajes, es que las funciones pueden llamarse a sı́
mismas. Por ejemplo, sabemos que la función factorial puede definirse como sigue:

n! = n (n − 1)!

con esta definición y sabiendo que 1! = 1, podemos evaluar cualquier factorial:

5! = 5 · (4)!
= 5 · 4 · (3!)
= 5 · 4 · 3 · (2!)
= 5 · 4 · 3 · 2 · (1!)
=5·4·3·2·1
= 120

Entonces, podemos definir la función Factorial en un programa de la siguiente manera:

def Factorial(n):
if n==1:
return 1
else:
return n*Factorial(n-1)
print (Factorial(5))

Otro ejemplo donde es útil la recursividad es el cálculo de los términos de la sucesión de Fibonacci;
la sucesión comienza con los números 0 y 1, a partir de éstos, cada término es la suma de los dos
anteriores.

def fibonacci(n):
if n == 0 or n == 1:
return 1;
else:
return fibonacci(n-1) + fibonacci(n-2)
for i in range(10):
print (fibonacci(i),end = ",")

Al ejecutarlo, el programa mostrará lo siguiente:

1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , 55 ,

R. Espejel 100
Computación

Ejercicios.
Ejercicio 1. Elabora un programa en Python implementando la función desglosa que reciba una
lista como argumento y muestre sus elementos de la siguiente forma:

El elemento 1 es: 5
El elemento 2 es: 3
El elemento 3 es: 7
El elemento 4 es: 1
El elemento 5 es: 4
El elemento 6 es: 0

Suponiendo que la lista es [5,3,7,1,4,0]

Ejercicio 2. Elabora un programa implementando la función ceros que reciba un número entero n
como argumento y devuelva una lista con n ceros.

Ejercicio 3. Elabora un programa implementando la función diaSemana que reciba como argumento
un número del 1 al 7 y devuelva una cadena de texto con el nombre del dı́a de la semana
correspondiente. Es decir, si recibe el número 4, devuelve “jueves”.
Este ejercicio está basado en uno anterior, en este caso sólo impleméntalo como función.

101 R. Espejel
Computación

2.10. Solución de Ecuaciones Diferenciales.

En esta secuencia, expondremos una introducción a la solución numérica de ecuaciones dife-


renciales. El método más sencillo es el método de Euler, el cual se basa en la aproximación por
diferencias de la derivada. Para deducir este método consideremos una ecuación diferencial de
primer orden:

dx
= f (x, t),
dt

y de acuerdo con la definición de derivada:

dx x(t + h) − x(t)
= lı́m ,
dt h→0 h

entonces, su tomamos una h lo suficientemente pequeña, podemos aproximar:

x(t + h) − x(t)
f (x, t) ≃ ,
h

y despejando x(t + h) se tiene el esquema del método de Euler:

x(t + h) = x(t) + f (x, t)h, (2.1)

Ası́, teniendo el valor inicial x(t = 0) es posible calcular los valores siguientes iterativamente,
esto es, obtener x(t = h) a partir de x(t = 0); x(t = 2h) a partir de x(t = h); x(t = 3h) a partir de
x(t = 2h), etc.
Con esta expresión, es posible hacer algunas simulaciones interesantes, aplicándola otros mo-
delos, como el de crecimiento de poblaciones. Tomemos, por ejemplo, el modelo depredador-presa
de Lotka-Volterra, que es un sistema formado por dos ecuaciones diferenciales de primer orden no
lineales que modela el cambio de dos poblaciones que interactúan, una es de depredadores y otra
de presas:

dC
= a C(t) − c C(t) Z(t) (2.2)
dt
dZ
= −b Z(t) + d C(t) Z(t) (2.3)
dt

R. Espejel 102
Computación

donde C representa el número de presas (conejos) y Z el número de depredadores (zorros). Entonces,


podemos interpretar la ecuación (3), como sigue: el cambio (velocidad) de la población de conejos
crece cuando éstos se reproducen con una taza a de crecimiento, pero decrece a una taza c debido a
que son cazados por zorros, y los encuentros entre zorros y conejos es más probable si cualquiera de
las dos poblaciones es alta, de aquı́ el término C(t) Z(t). Por otro lado, la ecuación (4) nos dice que
la población de zorros aumenta con los encuentros entre zorros y conejos (entre más conejos haya,
es favorable para la población de zorros) y decrece si hay sobre población de zorros en ausencia de
presas (−b Z(t)).
Aplicando el método de Euler de la ecuación (1) al modelo de las poblaciones de la ecuación
(3) y (4):

 
C(t + h) = C(t) + h a C(t) − c C(t) Z(t) (2.4)
 
Z(t + h) = Z(t) + h − b Z(t) + d C(t) Z(t) (2.5)

El programa en Python es muy sencillo; notemos que las ecuaciones anteriores relacionan un
nuevo valor de C, es decir C(t + h), con el anterior, es decir C; y lo mismo para Z:

a = 0.5
b = 0.4
c = 0.35
d = 0.06
C = 3
Z = 2
h = 0.01
for i in range(5000):
C = C + h*(a*C-c*C*Z)
Z = Z + h*(-b*Z+d*C*Z)
print (C,Z)

Los valores de los parámetros a, b, c y d, marcados en color azul, son elegidos por ensayo y error
(como una actividad, pueden variarlos y observar como cambia el resultado), el número inicial de
conejos y zorros está en miles, es decir, comenzamos con 3000 conejos y 2000 zorros. Las lı́neas en
rojo equivalen a las ecuaciones (5) y (6).
Si ejecutamos el programa, obtenemos la serie de valores que van tomando las poblaciones, pero
es conveniente visualizarlos en una gráfica. Aprovecharemos para aprender a graficar con el paquete
vpython que es más sencillo que matplotlib, pero mucho más limitado:

103 R. Espejel
Computación

from vpython import *


ventana = graph()
conejos = gcurve(color=[Link], graph=ventana)
zorros = gcurve(color=[Link], graph=ventana)
a = 0.5
b = 0.4
c = 0.35
d = 0.06
C = 3
Z = 2
h = 0.01
for i in range(5000):
C = C + h*(a*C-c*C*Z)
Z = Z + h*(-b*Z+d*C*Z)
[Link](pos=(t*h,C))
[Link](pos=(t*h,Z))

Con las lı́neas marcadas en azul, importamos el paquete vpython, el cual nos permite hacer
gráficas x, y, ası́ como la visualización de cuerpos en 3D. Cabe mencionar que la funcionalidad de
este paquete en la tarjeta Raspberry pi cero es limitada. Sin embargo en tarjetas más recientes y
con mayor memoria RAM, como la Raspberry pi 4, funciona sin problemas.
La lı́nea marcada en color naranja, crea un objeto tipo graph y se le asigna a la variable
ventana. Este objeto es una ventana para la visualización de la gráfica. Las lı́neas en rojo, crean
dos objetos tipo gcurve, asignados a las variables conejos y zorros; estamos especificando valores
a sus atributos color y gdisplay; el primero es el color de la lı́nea a graficar, y el segundo es
el objeto tipo graph (ventana) dónde aparecerá la gráfica (aunque en este caso tenemos sólo una
ventana, es posible mostrar varias gráficas en varias ventanas diferentes).
Las lı́neas en magenta agregan un punto al objeto gcurve correspondiente, a conejos se le
agrega el punto (t*h),C y a zorros se le agrega el punto (t*h),C. Noten que estas lı́neas están
dentro del ciclo for. Es claro que la expresión t*h toma los valores correspondientes al tiempo, es
decir 0, h, 2h, 3h, ... Obteniendo la siguiente gráfica:

R. Espejel 104
Computación

Lo que podemos ver en la gráfica, es que al haber una baja población de conejos, la de los
zorros va disminuyendo, con lo cual, crece la de conejos, propiciando que los zorros tengan alimento
y crezca su población, ocasionando que necesiten más alimento y disminuya el número de conejos,
cerrando el ciclo.
Una forma útil de visualizar este tipo de sistemas es graficando cada cantidad en un eje; gra-
fiquemos la población de zorros en el eje x y la conejos en el y, con lo que requeriremos un solo
objeto gcurve:

from vpython import *


ventana = graph()
ciclo = gcurve(color=[Link], graph=ventana)
a = 0.5
b = 0.4
c = 0.35
d = 0.06
C = 3
Z = 2
h = 0.01
for i in range(5000):
C = C + h*(a*C-c*C*Z)
Z = Z + h*(-b*Z+d*C*Z)
[Link](pos=(Z,C))

Obteniendo la siguiente gráfica:

Donde podemos ver directamente, entre otras cosas, el número de conejos cuando la cantidad
de zorros es mı́nima (o máxima) y el numero de zorros cuando la cantidad de conejos es mı́nima (o
máxima).

105 R. Espejel
Computación

Ejercicios.
Ejercicio 1. Investiga en la documentación de VPython la manera de incluir tı́tulos de los los ejes y
de la gráfica, y ponlo en práctica en los programas (visita [Link])

Ejercicio 2. Modifica los programas expuestos para hacer las gráficas usando el paquete MatPlotLib.
Es necesario crear las listas de abscisas y ordenadas como listas vacı́as y emplear append
para agregar a ellas los datos calculados.

Ejercicio 3. Investiga la ecuación diferencial que describe la variación de la corriente en un circuito


RCL e implementa el programa para graficar la solución.

R. Espejel 106
Computación

2.11. Solución de Ecuaciones Diferenciales. Dinámica


Para resolver ecuaciones de movimiento que involucran a la segunda derivada, esto es, la ace-
leración, es necesario escribir las ecuaciones diferenciales de segundo orden como un sistema de
ecuaciones diferenciales de primer orden, de forma similar al caso de la secuencia anterior.
Pensemos en el movimiento de un objeto a una cierta velocidad. Si conocemos la posición inicial
xi y la velocidad v, entonces la posición xf después de un tiempo h, estará dada por:

xf = xi + v h, (2.6)

Nota que, si recordamos que la velocidad es la derivada de la posición, esta última ecuación
es equivalente a la ecuación (1) si consideramos que la posición inicial se da en el tiempo t y la
posición final se da después de un intervalo de tiempo h, es decir, en t + h.

dv
= a(x, v, t)
dt (2.7)
dx
= v(x, t)
dt

y el esquema del método de Euler para ecuaciones de segundo orden quedarı́a como sigue:

v(t + h) = v(t) + h a(xn , vn )


, (2.8)
x(t + h) = x(t) + h v(t)

noten que la aceleración es la derivada de la velocidad, entonces, análogamente a lo anterior tenemos


vf = vi + h v. Entonces, si conocemos la expresión de la aceleración, podemos calcular la velocidad
y, a partir de ésta, la posición.
Seguramente observaron que, la expresión xf = xi + v h, es válida para movimiento rectilı́neo
uniforme y la expresión vf = vi + h v es válida para movimiento uniformemente acelerado. Es aquı́
donde está nuestra aproximación, la cual es muy aceptable si se usan valores pequeños de h.
Pongamos un ejemplo concreto; un objeto de masa m que se desliza sobre una superficie ho-
rizontal sin fricción y que está unido a un extremo de un resorte de constante k, mientras el otro
extremo está fijo. Tomemos x = 0 en el punto de equilibrio del resorte, es decir, cuando no está
estirado ni comprimido:

107 R. Espejel
Computación

Ahora desplacemos el objeto hacia la derecha, estirando el resorte una distancia x:

Recordando la Ley de Hook, la fuerza de restitución del resorte que se ejerce sobre el cuerpo
será:

F = −kx

y, de acuerdo a la Ley de Newton F = m a, tenemos:

ma = −kx

o bien,

d2 x k
2
= − x(t) (2.9)
dt m

Esto es, tenemos una ecuación diferencial que nos indica que x es una función del tiempo t, y que
k
al derivarla dos veces, obtenemos como resultado una constante negativa (− m ) multiplicando a la
función original x(t).
Las funciones que conocemos, que tienen esta propiedad (que al derivarlas dos veces, regresamos
a la función original), son la función seno y la función coseno. Sin embargo, sabemos algo más sobre
la función que soluciona la ecuación diferencial: que evaluada en cero, es decir, en t = 0, es diferente
de cero, por lo tanto la función solución es el coseno; más precisamente:

r !
k
x(t) = x0 cos t (2.10)
m

Gracias a lo que sabemos sobre funciones trigonométricas y derivadas, pudimos “adivinar” esta
solución, pero habrá ecuaciones diferenciales con las que no tendremos esa suerte y nos verı́amos
obligados a implementar algún método numérico, como el método de Euler en un programa.

R. Espejel 108
Computación

Tomemos las ecuaciones (3) y la ecuación (4):

v(t + h) = v(t) + h a(xn , vn )


,
x(t + h) = x(t) + h v(t)

d2 x k
2
= a = − x(t) (2.11)
dt m
Podemos escribir entonces:

 
k
v(t + h) = v(t) + h − m x(t)
,
x(t + h) = x(t) + h v(t)
Al igual que el sistema de la secuencia anterior, la implementación de estas expresiones en un
programa en Python es muy sencilla; ya que las ecuaciones anteriores relacionan un nuevo valor de
v, es decir v(t + h), con el anterior, es decir v(t); y lo mismo para x:

from vpython import *


ventana = graph()
posicion = gcurve(color=[Link], graph=ventana)
k = 0.4
m = 1.0
x = 5.0
v = 0.0
h = 0.01
for t in range(5000):
v = v + h*(-k/m * x)
x = x + h*v
[Link](pos=(t*h,x))

En las lı́neas marcadas en color naranja se le dan valores a las constantes del sistema, es decir
la constante del resorte k y la masa m, en las lı́neas en color azul, se le dan valores a las condiciones
iniciales, es decir, la posición inicial y la velocidad inicial, a partir de las cuales evolucionará el
sistema. Nota que toda la información de nuestro sistema dinámico está en la parte marcada en
rojo. La gráfica generada por este programa es la siguiente:

109 R. Espejel
Computación

Nota que estamos graficando la posición x en el eje vertical y el tiempo t en el eje horizontal, y que
esta gráfica de tiempo contra posición coincide con la solución de la ecuación (5) que “adivinamos”.
Vemos que el objeto comienza su movimiento en x = 5 para t = 0, toma el valor mı́nimo en x = −5
y continúa oscilando. Superpongamos ahora la gráfica de la velocidad en color verde:

from vpython import *


ventana = graph()
posicion = gcurve(color=[Link], graph=ventana)
velocidad = gcurve(color=[Link], gdisplay=ventana)
k = 0.4
m = 1.0
x = 5.0
v = 0.0
h = 0.01
for t in range(5000):
v = v + h*(-k/m * x)
x = x + h*v
[Link](pos=(t*h,x))
[Link](pos=(t*h,v))

Noten que la gráfica de la velocidad comienza en v = 0, y que los máximos (mı́nimos) de la


posición coinciden con los ceros de la velocidad, es decir, cuando el objeto llega a los extremos de
su movimiento la velocidad es cero, y ésta es máxima (mı́nima) cuando el objeto pasa por el punto
de equilibrio del resorte (en x = 0).

R. Espejel 110
Computación

Visualizaremos ahora el diagrama de fases, que consiste en graficar la posición en el eje horizontal
y el momento en el vertical. Ya que, como podemos observar en la gráfica anterior, la posición se
comporta como el coseno y la velocidad como el seno, es claro que lo que obtenemos es una elipse.

from vpython import *


ventana = graph(ytitle=’velocidad, momento’, xtitle = ’posicion’)
fase = gcurve(color=[Link], graph=ventana)
k = 0.4
m = 1.0
x = 5.0
v = 0.0
h = 0.01
for t in range(5000):
v = v + h*(-k/m * x)
x = x + h*v
[Link](pos=(t*h,x))
[Link](pos=(x,m*v))

Es ahora más claro que los máximos de la posición ocurren en los extremos horizontales de
la elipse, es decir, cuando se cruza el eje horizontal en v = 0, y que los máximos de la velocidad
ocurren en la posición de equilibrio del resorte (x = 0).

111 R. Espejel
Computación

Como ya mencionamos, la ventaja de la forma en la que implementamos el Método de Euler,


es que para cambiar el modelo del sistema fı́sico, basta con cambiar la expresión de la acelera-
ción (marcada en rojo). Por ejemplo, podemos aumentar un término de fricción; como ustedes
saben, la fricción es una fuerza proporcional a la velocidad y que se opone al movimiento, de la
β
forma Ff = −β v, entonces af = − m v, sumamos ese término a la expresión de la aceleración, de
modo que el programa quedarı́a:

from vpython import *


ventana = graph(ytitle=’velocidad, momento’, xtitle = ’posicion’)
fase = gcurve(color=[Link], graph=ventana)
k = 0.4
m = 1.0
B = 0.3
x = 5.0
v = 0.0
h = 0.01
for t in range(5000):
v = v + h*(-k/m * x-B/m * v)
x = x + h*v
[Link](pos=(t*h,x))
[Link](pos=(x,m*v))

Como pueden ver, ahora tanto la posición como la velocidad (en valor absoluto) disminuyen
formando un espiral al ir perdiendo energı́a. En el diagrama de fases, cada punto de la gráfica
representa un estado del sistema, en este caso, el sistema converge a un estado particular: el reposo
que está representado por el punto que coincide con el origen de la gráfica.

R. Espejel 112
Computación

Ejercicios.
Ejercicio 1. Agrega un término de forzamiento periódico a la ecuación diferencial e implementa los
cambios en el último programa.

Ejercicio 2. Implementa un programa para mostrar el concepto de velocidad terminal en un sistema


de caı́da libre. Implementa en él la solución para la ecuación diferencial considerando
fricción con el aire.

113 R. Espejel
Computación

2.12. Simulación, animación y visualización en 3D


En esta secuencia haremos una breve introducción a VPython que nos permitirá visualizar el
movimiento que resulta de la solución numérica de las ecuaciones diferenciales que modelan un
sistema.
La visualización de objetos 3D en VPython es muy sencilla. Veamos el siguiente programa:

from vpython import *


ventana1 = canvas()
masa = sphere(radius = 1.0)

La lı́nea en rojo es la llamada al paquete vpython que nos permite trabajar con objetos 3D. De
manera similar a como lo hicimos en las clases anteriores con graph para crear una ventana para
gráficas, ahora creamos una ventana de visualización de objetos ventana1 con display (lı́nea en
azul). En la lı́nea marcada en naranja, creamos un objeto tipo sphere, es decir, una esfera, y lo
llamamos masa; dentro de los paréntesis especificaremos los valores de los atributos del objeto. En
este caso sólo estamos dándole el valor de 1.0 al atributo radius (radio). Veremos algo como esto:

Una esfera de radio 1.0, centrada en el origen de color blanco. Tanto la posición del centro
como el color, son atributos que no especificamos, de modo que se toman los valores por defecto.
Vemos que la esfera llena la ventana, esto también es una acción por defecto; la escala se ajustará
automáticamente para que los objetos que visualicemos llenen la ventana. Cambiemos el atributo
range del objeto ventana1:

from vpython import *


ventana1 = canvas(range = 6.0)
masa = sphere(radius = 1.0)
sleep(0)

R. Espejel 114
Computación

El atributo range especifica la escala de visualización (o el zoom), el valor 6.0 significa que una
esfera de radio 6 llenarı́a la ventana, de modo que nuestro programa mostrarı́a ahora lo siguiente:

Cambiemos otros atributos de la esfera; el color y la posición:

from vpython import *


ventana1 = canvas(range = 6.0)
masa = sphere(radius = 1.0, color = [Link], x = 3.0)

De esta forma notamos también que la visualización dentro del objeto ventana1 está, por
defecto, está centrada en el origen.

115 R. Espejel
Computación

Ahora bien, podemos cambiar los atributos de los objetos después de haberlos creado. Como
recordarán, en la secuencia anterior, se obtuvo la posición del objeto de un oscilador armónico, esto
es, una variable x dentro de un ciclo iba cambiando su valor en función del tiempo. A continuación
muestro un segmento del programa:

for t in range(5000):
v = v + h*(-k/m * x)
x = x + h*v

Combinemos ambos programas:

from vpython import *


k = 0.4
m = 1.0
x = 5.0
v = 0.0
h = 0.02
ventana1 = canvas(range = 6.0)
masa = sphere(radius = 1.0, color = [Link], x = 5.0)
for t in range(5000):
rate(50)
v = v + h*(-k/m * x)
x = x + h*v
masa.x = x

De esta forma, estamos cambiando el atributo de posición de la esfera de acuerdo a la posición


que se calcula mediante el método de Euler, con lo que vemos ahora la esfera en movimiento. La
instrucción rate(50) controla la velocidad de la animación fijándola a 50 cuadros por segundo.
Podemos también, por ejemplo, mostrar la gráfica del diagrama de fases simultáneamente con
la animación:

from vpython import *


k = 0.4
m = 1.0
x = 5.0
v = 0.0
h = 0.02
ventana1 = canvas(range = 6.0)
ventana2 = graph(x = 500)
masa = sphere(radius = 1.0, color = [Link], x = 5.0)
fase = gcurve(color=[Link])

R. Espejel 116
Computación

for t in range(5000):
rate(50)
v = v + h*(-k/m * x)
x = x + h*v
masa.x = x
[Link](pos=(x,v))

Los cambios en el programa se señalan en color azul. La lı́nea señalada en color naranja, especi-
fica la posición en pixeles de la ventana, respecto a la pantalla del monitor (x=500), esto para que
no se superpongan ambas ventanas.

El paquete vpython tiene una gran variedad de objetos disponibles1 . Podemos completar nuestra
visualización agregando el resorte por medio de un objeto tipo helix, que tiene los atributos de
posición, vector del eje (axis) (1,0,0), longitud, radio, número de espirales coils y diámetro del
alambre thickness:

from vpython import *


k = 0.4
m = 1.0
x = 5.0
v = 0.0
h = 0.02
ventana1 = canvas(range = 6.0)
ventana2 = graph(x = 500)
masa = sphere(radius = 1.0, color = [Link], x = 5.0)
resorte = helix(pos = (-8,0,0),radius = 0.5, coils = 10, axis=(x+8,0,0),
thickness = 0.1)
fase = gcurve(color=[Link])
for t in range(5000):
rate(50)
v = v + h*(-k/m * x)
x = x + h*v
masa.x = x
[Link](pos=(x,v))
[Link]=(x+8,0,0)
1
visite [Link]

117 R. Espejel
Computación

En la lı́nea marcada en naranja se crea el objeto resorte de tipo helix; el atributo de posición
se está dando como el vector (-8,0,0), esto es, la posición de un extremo, el otro extremo se especifica
con el vector axis (que parte del vector pos, no del origen), y es este atributo el que se cambia
dentro del ciclo for.

Cambiemos de sistema. Pensemos ahora en un péndulo, como el que se muestra a continuación:

R. Espejel 118
Computación

Como puede verse en la figura, la fuerza de restitución es ahora:

F = −m g sen(θ),
m aT = −m g sen(θ),
d2 θ
mL = −m g sen(θ),
dt2
donde hemos llamado aT a la acleración tangencial. De modo que la ecuación diferencial a resolver
será:

d2 θ g
2
= − sen(θ),
dt L
Ası́, las expresiones del método de Euler para resolverla serán muy similares a las del oscilador
armónico, con la diferencia de que ahora tendremos un ángulo y una velocidad angular:
 g 
v(t + h) = v(t) + h − sen(θ) ,
L
θ(t + h) = θ(t) + h v(t)

El ciclo for del programa serı́a entonces el siguiente:

for t in range(4000):
v = v+h*(-g/L*sin(x))
x = x+h*v

Las condiciones iniciales serán, en consecuencia, un ángulo inicial en radianes y una velocidad
angular en radianes por segundo. El siguiente programa muestra el diagrama de fases para el
péndulo con fricción (en la lı́nea marcada en azul, se han especificado valores de otros atributos de
graph, como el color blanco del del fondo y negro para las lı́neas y el texto, ası́ como el tı́tulo de
los ejes):

from vpythonimport *
ventana = graph(xtitle=’Angulo (rad)’, ytitle=’Velocidad (rad/s)’,
background=[Link],foreground=[Link])
fase = gcurve(color=[Link])
h = 0.01
g = 9.81
L = 0.5
x = pi/5
v = 0.0
B = 0.3
for t in range(4000):
v = v+h*(-g/L*sin(x)-B*v);
x = x+h*v;
[Link](pos=(x,v))

119 R. Espejel
Computación

Vamos a construir el péndulo; consistirá de un cilindro y una esfera. El cilindro irá desde el origen
(0,0,0), hasta el punto (0,-20,0), donde colocaremos el centro de la esfera:

cuerda = cylinder(pos=(0,0,0),axis=(0,-20,0), radius=0.2)


masa = sphere(pos=(0,-20,0), radius=1, color=[Link])

Ahora bien, vamos a necesitar que este sistema rote, entonces debemos hacer rotar tanto el
cilindro como la esfera. Para ello podemos incluir ambos objetos en lo que llamamos compound. Es
decir formar un solo objeto a partir de estos últimos, de la siguiente forma:

cuerda = cylinder(pos=(0,0,0),axis=(0,-20,0), radius=0.2)


masa = sphere(pos=(0,-20,0), radius=1, color=[Link])
pendulo = compound([cuerda,masa])

R. Espejel 120
Computación

y aplicamos la rotación con el método rotate, como en el siguiente ejemplo:

from vpython import *


ventana1 = canvas()
cuerda = cylinder(pos=(0,0,0),axis=(0,-20,0), radius=0.2)
masa = sphere(pos=(0,-20,0), radius=1, color=[Link])
pendulo = compound([cuerda,masa])
sleep(1.0)
[Link](angle = pi/4, axis = (0,0,1) )
sleep(1.0)
[Link](angle = - pi/4, axis = (0,0,1) )
sleep(0)

Veremos que al péndulo en su posición vertical, después de un segundo, habrá rotado 45 grados,
y después de un segundo más habrá rotado -45 grados para quedar en su posición original. Noten
que en las lı́neas marcadas en rojo se especifican la rotación de π/4 sobre un vector (0, 0, 1), es
decir, el eje de rotación es un vector paralelo al eje z el cual “sale” de la pantalla.

121 R. Espejel
Computación

Apliquemos lo anterior para completar nuestro programa:

from vpython import *


ventana1 = canvas()
ventana2 = graph(xtitle=’Angulo (rad)’, ytitle=’Velocidad (rad/s)’,
background=[Link],foreground=[Link],x=500)
curva = gcurve(color=[Link])
h = 0.01
g = 9.81
L = 0.5
x = pi/5
v = 0.0
B = 0.3
cuerda = cylinder(pos=(0,0,0),axis=(0,-20,0), radius=0.2)
masa = sphere(pos=(0,-20,0), radius=1, color=[Link])
pendulo = compound([cuerda,masa])
[Link](axis=(0,0,1),angle=x)
for t in range(4000):
rate(50)
v = v+h*(-g/L*sin(x)-B*v);
x = x+h*v;
[Link](axis=(0,0,1),angle=h*v)
[Link](pos=(x,v))

R. Espejel 122
Computación

Con esto completamos la simulación del péndulo y podemos hacer “experimentos” cambiando
las condiciones iniciales y las propiedades del sistema; como el valor de g, la longitud del péndulo, la
fricción, etcétera. Por ejemplo, podemos ver el comportamiento del sistema si el péndulo comienza
en su posición de equilibrio y le damos un cierto valor a la velocidad inicial, es decir cambiamos las
lı́neas en rojo por x = 0.0 y v = 15.0.

En este ejemplo, el péndulo tiene suficiente impulso al inicio como para girar sobre su eje,
pero al tener fricción, este impulso va disminuyendo hasta que no le es posible completar el giro y
comienza a oscilar como en los casos anteriores. De aquı́ que en la gráfica anterior, el ángulo crezca
con oscilaciones en la velocidad, para después formar la espiral que ya hemos visto.

123 R. Espejel
Computación

Ejercicios.
Ejercicio 1. Aumenta un resorte al sistema del oscilador armónico, de modo que la masa quede
sujeta por dos resortes opuestos.

Ejercicio 2. Modifica programa del péndulo de modo que la longitud aumente durante la simulación.
Comenta el cambio en el comportamiento del sistema.

R. Espejel 124

También podría gustarte