Curso de Programación en C y Python
Curso de Programación en C y Python
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
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).
5
Computación
#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].
R. Espejel 6
Computación
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 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:
#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);
}
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
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
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
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
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);
}
}
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);
}
}
for(i=1;i<=5;i++)
for(i=4;i<=10;i++)
for(i=7;i<10;i++)
for(i=3;i<15;i+=2)
15 R. Espejel
Computación
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++)
for(i=0;i<12;i++)
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.
main(){
int respuesta;
respuesta=1;
while (respuesta==1){
printf("Quieres que continue el ciclo (1=si, 0=no) ");
scanf(" %d",&respuesta);
}
}
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);
}
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.
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
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
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:
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.
Ejercicio 5. Elabora un programa que muestre las tablas de multiplicar desde la del 2 hasta la del 5.
R. Espejel 20
Computación
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
R. Espejel 22
Computación
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");
}
}
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
#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
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)
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) .
M −1
" #
1 X
I≃h (f (a) + f (b)) + f (a + ih)
2
i=1
b−a
h=
M
R. Espejel 26
Computación
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:
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:
29 R. Espejel
Computación
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.
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:
despejando b:
entonces:
R. Espejel 30
Computación
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
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.
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:
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
#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);
}
#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 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
#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);
}
#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:
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
#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
Aciertos
P = .
Total de intentos
Usa esta última expresión para elaborar el programa.
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);
}
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
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);
}
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]);
}
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
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]);
}}
}
541376129434981
R. Espejel 52
Computación
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:
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
a = 5
print(’El valor de a es %d’ % a)
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á:
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:
Notamos que la forma de elevar un número a alguna potencia (xy ), en Python se denota como x**y.
R. Espejel 58
Computación
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
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)
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:
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
[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:
61 R. Espejel
Computación
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]:
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:
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
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.
63 R. Espejel
Computación
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.
n
X
k 2 + 2k 3 + k 4
k=1
R. Espejel 64
Computación
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.
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:
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.
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.
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:
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.
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
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:
Ejercicio 1. Elabora un programa que genere y muestre los primeros n elementos de la sucesión:
Ejercicio 2. Elabora un programa que genere y muestre los elementos menores que n de la suce-
sión:
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.
∞
X 1
2n
n=1
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.
69 R. Espejel
Computación
Meta 1. Comencemos por generar un número aleatorio usando la función randint que forma parte
del paquete random:
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:
Meta 3. Comparemos ambos números con if mostrando los mensajes correspondientes al usuario:
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:
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
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:
71 R. Espejel
Computación
R. Espejel 72
Computación
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:
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):
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)
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:
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:
79 R. Espejel
Computación
En esta ocasión haremos una versión del Juego del Ahorcado. Para ello necesitamos conocer
algunas funciones nuevas.
Veamos el siguiente programa:
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:
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:
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:
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:
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:
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
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:
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:
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
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)
[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
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:
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:
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:
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.
También podemos sumar dos matrices con entradas aleatorias con el siguiente código:
87 R. Espejel
Computación
A = [1,2,3]
B = [4,5,6]
C = zip(A,B)
print (list(C))
for c in C:
print (c)
R. Espejel 88
Computación
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:
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:
R. Espejel 90
Computación
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.
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:
R. Espejel 92
Computación
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:
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:
93 R. Espejel
Computación
O bien, generar una gráfica tipo z = f (x, y). En este caso f (x, y) = sen(x) cos(y), en el
plano [−π, π] × [−π, π].
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
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).
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:
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]
97 R. Espejel
Computación
O bien:
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:
def Muestra(M):
for r in M:
for c in r:
print (’ %d’ % c, end = \t)
print()
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
def Muestra(M):
for r in M:
for c in r:
print (’ %d’ % c, end = \t)
print()
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)!
5! = 5 · (4)!
= 5 · 4 · (3!)
= 5 · 4 · 3 · (2!)
= 5 · 4 · 3 · 2 · (1!)
=5·4·3·2·1
= 120
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 = ",")
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
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
dx
= f (x, t),
dt
dx x(t + h) − x(t)
= lı́m ,
dt h→0 h
x(t + h) − x(t)
f (x, t) ≃ ,
h
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
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
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:
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.
R. Espejel 106
Computación
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:
107 R. Espejel
Computación
Recordando la Ley de Hook, la fuerza de restitución del resorte que se ejerce sobre el cuerpo
será:
F = −kx
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
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:
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:
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.
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 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.
113 R. Espejel
Computación
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:
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:
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
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:
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.
R. Espejel 118
Computación
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)
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:
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:
R. Espejel 120
Computación
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
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