INFORME TECNICO FINAL DEL PROYECTO: “ Efecto de la motivación en el aprendizaje de la programación como una herramienta de uso científico”. Clave SIP: 20082388. Director del proyecto: Ramón Sebastián Salat Figols. 1. Actividades desarrolladas: Durante los tres primeros meses del curso de Programación I de la Escuela Superior de Física y Matemáticas, se trabajó exclusivamente en lenguaje C y se cubrieron todos los temas del programa; el enfoque estuvo orientado a la solución de problemas de Física y de Matemáticas usando programación en C; se vieron ejemplos tales como encontrar raíces de ecuaciones trascendentes, cálculo aproximado de áreas bajo gráfica de funciones, encontrar números primos y problemas de simulación (valor aproximado de pi por el método de Montecarlo y simulación de incendios forestales). Durante el último mes se dio una introducción a Python y a la librería Tkinter para que pudieran diseñar interfases gráficas, lo cual, les permitía construir programas más similares a los que están acostumbrados a usar. Se les propuso de tarea que entregaran programas que resolvieran problemas de su elección usando Tkinter; esto con la finalidad de aumentar su motivación hacia la programación. En el último mes también se introdujeron temas adicionales en C y en Python simultáneamente, por ejemplo, el tema de recursividad. Esto con la finalidad de que los estudiantes se formaran conceptos más generales (independientes del lenguaje de programación). Al mismo tiempo, el becario PIFFI del proyecto Wilbert De Jesús, elaboró los programas que se utilizaron para introducir Python y Tkinter, e inició su tesis de licenciatura elaborando y probando un programa para ayudar a los estudiantes del primer semestre a entender mejor el método de mínimos cuadrados ; este programa permite trabajar simultáneamente las representaciones numérica, gráfica y simbólica de los datos. A continuación se presentan los programas que se utilizaron para introducir Python y Tkinter, elaborado por Wilbert De Jesús: #METODO DE LA BISECCION def f(x): return x**2 - 2*x -2 def biseccion(a, b, epsilon): c = (a + b) / 2.0 while f(c) != 0 and b - a > epsilon: if f(a)*f(c) > 0: a=c elif f(b)*f(c) > 0: b=c c = (a + b) / 2.0 return c 1 a=float(raw_input('limite inferior del intervalo ')) b=float(raw_input('limite superior del intervalo ')) epsilon=float(raw_input('valor de epsilon ')) print biseccion(a, b, epsilon) #Programa para determinar el MCD de dos numeros def mcd(u,v): aux=0 while u>0: if u<v: aux=u u=v v=aux u=u-v return v print 'Este programa determina el MCD de dos numeros' u=int(raw_input('Proporciona el primer numero ')) v=int(raw_input('Proporciona el segundo numero ')) print '\nEl MCD(',u, ',',v,')=',mcd(u,v) raw_input() #Este programa es para saber si un numero es primo num = int(raw_input('Dame un número: ')) a=0 for divisor in range(2, num): if num % divisor == 0: a=1 break if a==0: print 'El número', num, 'es primo' else: print 'El número', num, 'no es primo' raw_input() #EL FACTORIAL DE UN NUMERO NARTURAL def factorial(n): if n==0: return 1 else: 2 return n*factorial(n-1) print 'Este programa calcula el factorial de un numero natural n \n' n=int(raw_input('Proporciona el numero ')) print n,'!=',factorial(n) raw_input() #Escribe la serie de Fibonacci© n = int(raw_input('Escribe hasta que numero escribir la serie de Fibonacci: ')) a, b = 0, 1 while b < n: print b, a, b = b, a+b raw_input() m = int(raw_input('Número de filas: ')) n = int(raw_input('Número de columnas: ')) # Creamos dos matrices nulas... A = [] for i in range(m): A.append( [0] * n ) B = [] for i in range(m): B.append( [0] * n ) print 'Entradas de la matriz A' for i in range(m): for j in range(n): A[i][j] = float(raw_input('Dame el componente (%d,%d): ' % (i, j))) print 'Entradas de la matriz B' for i in range(m): for j in range(n): B[i][j] = float(raw_input('Dame el componente (%d,%d): ' % (i, j))) # otra matriz nula para el resultado C = [] for i in range(m): C.append( [0] * n ) # realizando la suma for i in range(m): for j in range(n): 3 C[i][j] = A[i][j] + B[i][j] # imprimiendo resultado en la pantalla print "La Suma es:" for i in range(m): for j in range(n): print C[i][j], print from Tkinter import * def callback(): print "apretaste un boton" root = Tk() # crear menu menu = Menu(root) root.config(menu=menu) filemenu = Menu(menu) menu.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="New", command=callback) filemenu.add_command(label="Open...", command=callback) filemenu.add_separator() filemenu.add_command(label="Exit", command='exit') helpmenu = Menu(menu) menu.add_cascade(label="Help", menu=helpmenu) helpmenu.add_command(label="About...", command=callback) mainloop() from Tkinter import * root = Tk() root.title("Mi ventana") btn = Button(root, text="Salir") btn.grid() def stop(event): root.destroy() btn.bind('<Button-1>', stop) root.mainloop() #PEQUE;A CALCULADORA import Tkinter as tk 4 labelfont=('times',12,'bold') def click(key): global guardar if key == '=': # Para realizar la division como flotantes if '/' in entry.get() and '.' not in entry.get(): entry.insert(tk.END, ".0") result = eval(entry.get()) entry.delete(0, tk.END) entry.insert(tk.END, " " + str(result)) elif key == 'C': entry.delete(0, tk.END) # Se limpia la entrada elif key == 'MS': guardar = entry.get() if '=' in guardar: ix = guardar.find('=') guardar = guardar[ix+2:] root.title('M=' + guardar) elif key == 'MR': entry.insert(tk.END, guardar) elif key == '+/-': if '=' in entry.get(): entry.delete(0, tk.END) try: if entry.get()[0] == '-': entry.delete(0) else: entry.insert(0, '-') except IndexError: pass else: if '=' in entry.get(): entry.delete(0, tk.END) entry.insert(tk.END, key) def Acerca(): win1=tk.Tk() win1.title('Acerca de calculadora') texto=tk.Text(win1,font=labelfont,height=8,width=45) texto.insert(tk.END,'* * * * Calculadora v2.0 * * * *\n\n') texto.insert(tk.END,' Derechos Reservados £.\n') texto.insert(tk.END,'El autor no concede garnatía alguna sobre el uso\n') texto.insert(tk.END,'de este programa, ni acepta ninguna responsabilidad\n') texto.insert(tk.END,'por cualquier consecuencia que se pueda atribuir al \n') texto.insert(tk.END,'uso del mismo.') texto.pack() 5 def Ayuda(): win2=tk.Tk() win2.title('Ayuda©') texto=tk.Text(win2,font=labelfont,height=8,width=55) texto.insert(tk.END,'* * * * ڜBienvenido a Calculadora v2.0* * * *\n\n') texto.insert(tk.END,'Tiene las misma funciones que una calculadora de\n') texto.insert(tk.END,'bolsillo, la novedad es que al teclear la operacion\n') texto.insert(tk.END,'a realizar aparece en la pantalla el signo (+, -, /, *).\n\n') texto.insert(tk.END,'Para iniciar una nueva operación, dar click al botón\n') texto.insert(tk.END,'"C", y listo.\n\n') texto.insert(tk.END,'Para guardar un numero en la memoria presionar la tecla MS\n') texto.insert(tk.END,'Para recuperar el numero de la memoria presionar la tecla MR\n\n') texto.pack() #Dimensiones de la ventana root = tk.Tk() root.title('Calculadora v1.0') root.minsize(width=250,height=200) ###Definicion del menu menu=tk.Menu(root,font=labelfont) root.config(menu=menu) infomenu=tk.Menu(menu,font=labelfont) menu.add_cascade(label='Archivo',font=labelfont,menu=infomenu) infomenu.add_command(label='Ayuda',command=Ayuda) infomenu.add_command(label='Acerca de . . .',command=Acerca) infomenu.add_separator() infomenu.add_command(label='Salir',command='exit') lista = [ '7', '8', '9', '*', 'C', '4', '5', '6', '/', 'MS', '1', '2', '3', '-', 'MR', '0', '.', '+/-', '+', '=' ] # creacion de las teclas r=1 c=0 for b in lista: cmd = lambda x=b: click(x) tk.Button(root,text=b,width=4,relief='raised', bd=3, font=labelfont,command=cmd).grid(row=r,column=c,padx=3, pady=3) c += 1 if c > 4: c=0 r += 1 6 entry = tk.Entry(root, width=30, bg="white", font=labelfont) entry.grid(row=0,column=0,columnspan=20, ipady=5, pady=10) root.mainloop() Como puede observarse el becario PIFFI tardó muy poco tiempo en parender Python y a usar la librería Tkinter. Además de estos ejemplos, se usaron otro dos más complejos elaborados por el director del proyecto; uno para graficar funciones y otro para la técnica de demosaicing dentro del procesamiento de imágenes digitales. Se incluyen en anexo. El de demosaicing también fue presentado en una ponencia con publicación de artículo en extenso en la Reunión Nacional Académica de Física y Matemáticas, celebrada en 2008 en la ESFM. El programa que presenta en su tesis es excelente porque está pensado en el uso didáctico. 2. Resultados: Los programas con Tkinter que hicieron los alumnos versaron sobre los siguientes temas: Calculo del tiempo ascenso, altura máxima y alcance para tiro parabólico Altitud y altitud magnética Diagnóstico de masa corporal Conversión de temperaturas Calculadora Contador de palabras Calendario Selección de becarios Ley de Coulomb Crecimiento poblacional de aves Programa sobre mapa de ciudades de la República con mapa Esta tarea fue opcional y la realizaron aproximadamente 50% de los estudiantes (el total fue de 23). Todos estos programas muestran la motivación de los estudiantes hacia la programación. Sin embargo, no todos estaban de acuerdo. Se aplicó la siguiente encuesta y examen: 7 Los dos problemas que siguen los puede resolver en C o en Phyton. Tiene que entregar esta hoja y el código de los programas con los resultados. x2 1 1 1. Calcular la integral e 2 dx con cuatro cifras decimales. 0 2 2. Encontrar la abscisa del punto de intersección de las curvas y x 2 y y sen x diferente del origen de coordenadas. 1. ¿Le gustaría aprender más de Phyton? ( ) si ( )no 2. Qué prefiere, aprender: ( ) más de Python exclusivamente. ( ) más de C, exclusivamente. ( ) más de C y de Phyton. 3. ¿Cuántos programas ha escrito con Tkinter?______ 4. Escribir interfases gráficas con Tkinter es: ( ) sencillo ( ) difícil ( ) muy difícil. 5. ¿Ha usado alguna vez algún lenguaje diferente de Tkinter para elaborar interfases gráficas? ( ) si ( ) no 6. Es mejor: ( ) aprender C, Phyton y Tk inter. ( ) más de C, exclusivamente. Los resultados a la encuesta se muestran a continuación: Total de alumnos que contest enc. Opciones Pregunta 1 pregunta 2 Pregunta 3 Pregunta 4 Pregunta 5 Pregunta 6 23 1 2 3 4 5+ 21 2 2 4 17 0 4 1 2 15 11 14 5 17 21 1 1 21 de los 23 alumnos manifestaron que les interesaría parender más de Python; 2 indicaron que les gustaría aprender más solamente de Python, 4 solamente de C y 17 de ambos; 11 de los 23 alumnos piensa que es sencillo construir interfases gráficas con Tkinter, 14 que es difícil. El promedio general en el examen fue de 9 y solamente hubo dos reprobados con 5. 8 3. Conclusiones. La introducción de Python y Tkinter no impidió cumplir con el programa de la materia. La introducción de Tkinter motivó a los estudiantes a crear sus propios programas, de su propio interés. Cuatro de los 23 alumnos preferían aprender exclusivamente más de C; es decir, no todos los alumnos estuvieron de acuerdo en la introducción de Python. En general puede estimarse que la introducción de Python y Tkinter respetando el programa vigente, produjo un éxito razonable en el mejoramiento de la motivación del estudiante y en su desempeño. Propuesta de programa para la materia de Programación I para la Licenciatura en Física y Matemáticas. 1. Introducción al funcionamiento de la computadora. Partes de una computadora con una arquitectura de Von Newman. Uso de un simulador. 2. Tipos de datos en C. Estructura de un programa en C. Entradas y salidas sencillas. Elaboración por parte de los alumnos de programas sencillos utilizando variables numéricas y de caracteres. Uso de librerías tales como math.h, stdli.h. 3. Generación de números pseudoaleatorios y simulación. 4. Introducción a funciones y su uso. Creación de archivos cabecera (.h). 5. Condicionales: if, else. Estructuras repetitivas: for, while, case. 6. Introducción a arreglos numéricos de una y dos dimensiones y de caracteres. Cadenas. Librería string.h 7. Apuntadores y uso de malloc. 8. Estructuras. 9. Introducción a Python. Entradas y saldas sencillas. Primeros programas sencillos. 10. Introducción a la librería Tkinter. 11. Recursividad en C y en Python. 12. Clases en C y en Python. Apéndice. Programas avanzados de ejemplo en Tkinter. INSTITUTO POLITÉCNICO NACIONAL. ESCUELA SUPERIOR DE FÍSICA Y MATEMÁTICAS. Nombre del programa: Interpolador v1. 9 Autor: Ramón Sebastián Salat Figols. Proyecto de investigación: Efecto de la motivación en el aprendizaje de la programación como una herramienta de uso científico. Clave SEPI: 20082388. Este programa es de propósito didáctico. Interpolador v1. Derechos Reservados. Ramón Sebastian Salat Figols. 2008. Condiciones de uso: Se permite, sin costo alguno, copiar, distribuir y usar sin quitar la nota condiciones de uso ni su contenido. Tambien se permite modificar con la condicion de que se especifiquen los cambios y el autor de los mismos y la fecha en que se realizaron al distribuir la version modificada. El autor no concede ninguna garantia sobre el uso de este programa, ni acepta ninguna responsabilidad por cualquier consecuencia que se pueda atribuir al uso de este programa. CODIGO FUENTE. # -*- coding: cp1252 -*############################################################### ###Interpolador v1############################################# ###Derechos Reservados. Ramon Sebastian Salat Figols. 2008.#### ###Este programa permite explorar diferentes algoritmos######## ###para interpolar en imagenes digitales####################### ############################################################### # -*- coding: cp1252 -*10 ##########Librerias########## from Numeric import* from Tkinter import * import ImageTk import Image import os ##########Variables########## a11=0 a12=0 a13=0 a21=0 a22=0 a23=0 a31=0 a32=0 a33=0 a="c:/demosaicing/X.bmp" b="c:/demosaicing/Y.bmp" canx=400 cany=300 maxx=2840 maxy=2128 z=3*maxx f=zeros((maxy+1,maxx+1)) ###########Autor############# def about(): win1=Tk() 11 win1.title('Condiciones de uso') texto=Text(win1,font=labelfont,height=12,width=60) texto.insert(END,'Interpolador v1\n') texto.insert(END,'Derechos Reservados. Ramon Sebastian Salat Figols. 2008.\n') texto.insert(END,'Condiciones de uso. \n') texto.insert(END,'Se pemite, sin costo alguno, copiar, distribuir y usar sin quitar\n') texto.insert(END,'la nota \"condiciones de uso\" ni su contenido.\n') texto.insert(END,'Tambien se permite modificar con la condicion de que\n') texto.insert(END,'se especifiquen los cambios y el autor de los mismos y\n') texto.insert(END,'la fecha en que se realizaron al distribuir la version modificada.\n') texto.insert(END,'El autor no concede ninguna garantia sobre el uso\n') texto.insert(END,'de este programa, ni acepta ninguna responsabilidad\n') texto.insert(END,'por cualquier consecuencia que se pueda atribuir al \n') texto.insert(END,'uso de este programa.') texto.pack() ###########Funcion que presenta la ayuda######## def helpp(): win2=Tk() scrollbar=Scrollbar(win2) scrollbar.pack(side=RIGHT,fill=Y) win2.title('Ayuda') texto=Text(win2,font=labelfont,height=20,width=50,wrap=WORD,yscrollcommand=scrollbar.set) scrollbar.config(command=texto.yview) texto.insert(END,'Bienvenido a Interpolador v1.\n\n') 12 texto.insert(END,'Este program permite explorar visualmente diferentes\n') texto.insert(END,'algoritmos para interpolar los colores en una imagen\n') texto.insert(END,'tal como es obtenida por el sensor de una camara\n') texto.insert(END,'en escala de grises.\n') texto.insert(END,'La imagen hay que ponerla en el directorio\n') texto.insert(END,'demosaicing\n') texto.insert(END,'Y tiene que tener las siguientes caracteristicas:\n') texto.insert(END,'1. Debe ser un archivo en mapa de bits con \n') texto.insert(END,'24 bits por pixel\n') texto.insert(END,'2. Debe ser la imagen en escala de grises\n') texto.insert(END,'tal y como es producida por el sensor de la camara,\n') texto.insert(END,'con una resolución de 2840x2128.Modificando las\n') texto.insert(END,'variables maxx y maxy en el programa, puede.\n') texto.insert(END,'trabajarse con otras resoluciones.\n') texto.insert(END,'El boton original permite visualizar la imagen\n') texto.insert(END,'original.\n') texto.insert(END,'El boton borra permite borrar la imagen.\n') texto.insert(END,'El boton interpola efectua la interpolacion y muestra\n') texto.insert(END,'el resultado.\n') texto.insert(END,'Introduccion de los parametros del algoritmo: \n') texto.insert(END,'En los cuadros donde se introducen los parametos.\n') texto.insert(END,'la primera o dos primeras palabras indican\n') texto.insert(END,'el color del pixel segun el sensor y la ultima\n') texto.insert(END,'palabra la componente de color de dicho pixel,\n') texto.insert(END,'por ejemplo, rojo verde indica la componente verde\n') texto.insert(END,'del pixel que originalmente en el sensor es rojo.\n') texto.insert(END,'Verde sup indica verde superior y verde inf, verde.\n') 13 texto.insert(END,'inferior.\n') texto.insert(END,'Los espacios de datos se pueden llenar con expressiones\n') texto.insert(END,'arritmeticas escritas en terminos de a11, a12, a13,...a33\n') texto.insert(END,'Para un pixel determinado, el siguiente arreglo representa\n') texto.insert(END,'los datos de intensidad de gris de los pixeles vecinos:\n') texto.insert(END,' a11 a12 a13\n') texto.insert(END,' a21 a22 a23\n') texto.insert(END,' a31 a32 a33\n') texto.insert(END,'La intensidad del pixel actual esta dada por a22.\n') texto.insert(END,'Para dar los parametros hay que considerar el orden\n') texto.insert(END,'de recorrido de los pixels en una imagen de mapa de bits.\n') texto.insert(END,'Para su fucionamiento, el programa requiere de Python 2.5.\n') texto.insert(END,'y las bibliotecas NumPy e Image.\n') texto.insert(END,'Se recomienda verificar las licencias de uso.\n') texto.insert(END,'Para obtener mejores resultados puede aumentarse\n') texto.insert(END,'el contraste de la imagen original.\n') texto.pack() #########Funcion que borra la imagen########## def borra(): can.delete(ALL) #########Funcion que despliega la imagen original### def ver(): im= Image.open(a) photoim=ImageTk.PhotoImage(im) can.create_image(0,0,anchor=NW,image=photoim) can.pack(expand=1,fill=BOTH,anchor=NW) 14 win.mainloop() ############Funcion que realiza el demosaicing#### def demo(): fx=open('c:/demosaicing/X.bmp',"rb") fy=open('c:/demosaicing/Y.bmp',"wb") for i in range(1,55): c=fx.read(1) fy.write(c) for i in range(1,maxy+1): for j in range(1,maxx+1): cb=fx.read(1) cg=fx.read(1) cr=fx.read(1) f[i][j]=ord(cb) print "Archivo leido" fx.close() for i in range(1,maxy+1): for j in range(1,maxx+1): if i>1 and i<maxy and j>1 and j<maxx: a11=f[i-1][j-1] a12=f[i-1][j] a13=f[i-1][j+1] a21=f[i][j-1] a22=f[i][j] a23=f[i][j+1] a31=f[i+1][j-1] 15 a32=f[i+1][j] a33=f[i+1][j+1] if i%2==0 and j%2==1: cb=chr(a22) cg=chr(eval(azulv)) cr=chr(eval(azulr)) if i%2==0 and j%2==0: cb=chr(eval(verdeia)) cg=chr(a22) cr=chr(eval(verdeir)) if i%2==1 and j%2==1: cb=chr(eval(verdesa)) cg=chr(a22) cr=chr(eval(verdesr)) if i%2==1 and j%2==0: cb=chr(eval(rojoa)) cg=chr(eval(rojov)) cr=chr(a22) fy.write(cr) fy.write(cg) fy.write(cb) else: cb=chr(200) fy.write(cb) fy.write(cb) fy.write(cb) if i%100==0: 16 print 4*i/100,"%" fy.close() print "termino" im= Image.open(b) photoim=ImageTk.PhotoImage(im) can.create_image(0,0,anchor=NW,image=photoim) can.pack(expand=1,fill=BOTH,anchor=NW) win.mainloop() #########Funciones para capturar datos######## def azul_v(): global azulv azulv=e_azul_v.get() def azul_r(): global azulr azulr=e_azul_r.get() def verdes_a(): global verdesa verdesa=e_verdes_a.get() def verdei_a(): global verdeia verdeia=e_verdei_a.get() def verdes_r(): global verdesr verdesr=e_verdes_r.get() def verdei_r(): global verdeir verdeir=e_verdei_r.get() 17 def rojo_a(): global rojoa rojoa=e_rojo_a.get() def rojo_v(): global rojov rojov=e_rojo_v.get() def umbral(): global um um=e_umbral.get() def salida(): win.destroy() win.quit() ######################################################### ##############Programa principal############################ ######################################################### #########Ventana principal################################### win=Tk() win.title('Interpolador v1') win.config(bg="#eee") labelfont=('times',12,'bold') labelfont1=('times',16,'bold') win.minsize(width=canx+600,height=cany) ###############Menu############## menu=Menu(win,font=labelfont1) win.config(menu=menu) win.config(menu=menu) infomenu=Menu(menu,font=labelfont) 18 menu.add_cascade(label='Informacion',font=labelfont,menu=infomenu) infomenu.add_command(label='Condiciones de uso',command=about) infomenu.add_command(label='Ayuda',command=helpp) ##########Lienzo################### can=Canvas(win,width=canx,height=cany,bg='black',bd=5) can.config(scrollregion=(0,0,maxx,maxy)) yscrollbar=Scrollbar(can,orient=VERTICAL) xscrollbar=Scrollbar(can,orient=HORIZONTAL) yscrollbar.config(command=can.yview) xscrollbar.config(command=can.xview) can.config(xscrollcommand=xscrollbar.set) can.config(yscrollcommand=yscrollbar.set) yscrollbar.pack(side=RIGHT,fill=Y) xscrollbar.pack(side=BOTTOM,fill=X) #############Botones################## marco3=Frame(win,width=250,height=800,bg='white',bd=5) marco3.pack(side=RIGHT) marco1=Frame(marco3,width=250,height=700,bg='white',bd=5) marco1.pack(side=TOP) marco2=Frame(marco3,width=250,height=100,bg='white',bd=5) marco2.pack(side=TOP) borrar=Button(marco2,text='borrar',command=borra,font=labelfont,width=7) borrar.config(bg='blue',fg='white',bd=5) borrar.pack(side=LEFT) ve=Button(marco2,text='original',command=ver,font=labelfont,width=7) ve.config(bg='blue',fg='white',bd=5) ve.pack(side=LEFT) 19 demo=Button(marco2,text='interpola',command=demo,font=labelfont,width=7) demo.config(bg='blue',fg='white',bd=5) demo.pack(side=LEFT) salir=Button(marco2,text='salir',command=salida,font=labelfont,width=7) salir.config(bg='blue',fg='white',bd=5) salir.pack(side=LEFT) azulv=Button(marco1, text='azul verde= ', command=azul_v,bd=5) azulv.config(bg='#777',fg='white',width=15,bd=5) azulv.config(font=labelfont) azulv.pack(side=TOP) e_azul_v=Entry(marco1,font=labelfont1,width=30,bd=5,bg='grey') e_azul_v.pack(side=TOP) azulr=Button(marco1, text='azul rojo= ', command=azul_r,bd=5) azulr.config(bg='#777',fg='white',width=15,bd=5) azulr.config(font=labelfont) azulr.pack(side=TOP) e_azul_r=Entry(marco1,font=labelfont1,width=30,bd=5,bg='grey') e_azul_r.pack(side=TOP) verdesa=Button(marco1, text='verde sup azul= ', command=verdes_a,bd=5) verdesa.config(bg='#777',fg='white',width=15,bd=5) verdesa.config(font=labelfont) verdesa.pack(side=TOP) e_verdes_a=Entry(marco1,font=labelfont1,width=30,bd=5,bg='grey') e_verdes_a.pack(side=TOP) verdesr=Button(marco1, text='verde sup rojo= ', command=verdes_r,bd=5) verdesr.config(bg='#777',fg='white',width=15,bd=5) verdesr.config(font=labelfont) 20 verdesr.pack(side=TOP) e_verdes_r=Entry(marco1,font=labelfont1,width=30,bd=5,bg='grey') e_verdes_r.pack(side=TOP) verdeia=Button(marco1, text='verde inf azul= ', command=verdei_a,bd=5) verdeia.config(bg='#777',fg='white',width=15,bd=5) verdeia.config(font=labelfont) verdeia.pack(side=TOP) e_verdei_a=Entry(marco1,font=labelfont1,width=30,bd=5,bg='grey') e_verdei_a.pack(side=TOP) verdeir=Button(marco1, text='verde inf rojo= ', command=verdei_r,bd=5) verdeir.config(bg='#777',fg='white',width=15,bd=5) verdeir.config(font=labelfont) verdeir.pack(side=TOP) e_verdei_r=Entry(marco1,font=labelfont1,width=30,bd=5,bg='grey') e_verdei_r.pack(side=TOP) rojoa=Button(marco1, text='rojo azul= ', command=rojo_a,bd=5) rojoa.config(bg='#777',fg='white',width=15,bd=5) rojoa.config(font=labelfont) rojoa.pack(side=TOP) e_rojo_a=Entry(marco1,font=labelfont1,width=30,bd=5,bg='grey') e_rojo_a.pack(side=TOP) rojov=Button(marco1, text='rojo verde= ', command=rojo_v,bd=5) rojov.config(bg='#777',fg='white',width=15,bd=5) rojov.config(font=labelfont) rojov.pack(side=TOP) e_rojo_v=Entry(marco1,font=labelfont1,width=30,bd=5,bg='grey') e_rojo_v.pack(side=TOP) 21 can.pack(expand=1,fill=BOTH) win.mainloop() Programa de cómputo con fines didácticos: Graficando funciones v 1.01. Elaborado dentro del proyecto de investigación: Efecto de la motivación en el aprendizaje de la programación como una herramienta de uso científico. Clave SEPI: 20082388 Autor: Ramón Sebatián Salat Figols. Este programa es de propósito didáctico. Derechos Reservados. Ramon Sebastian Salat Figols. 2008. Condiciones de uso. Se permite, sin costo alguno, copiar, distribuir y usar sin quitar la nota "condiciones de uso" ni su contenido. También se permite modificar con la condición de que se especifiquen los cambios y el autor de los mismos y la fecha en que se realizaron al distribuir la versión modificada. El autor no concede ninguna garantía sobre el uso de este programa, ni acepta ninguna responsabilidad por cualquier consecuencia que se pueda atribuir al uso de este programa. CODIGO FUENTE. ###################################################### ###Graficando funciones v1.01############################## ###Derechos Reservados. Ramon Sebastian Salat Figols. 2008.#### ###Este programa permite graficar funciones de una variable####### ###################################################### from Tkinter import * from math import sin,cos,tan,asin,acos,atan,log,sqrt,fabs,exp import os import sys ###Define variables globales labelfont=('times',12,'bold') labelfont1=('times',20,'bold') nam='traza' posy=0. 22 s=0 q1=0 q2=0 ###Abre archivo de historia e inicia def inicia(): global fil fil=open('traza1.txt','w') global minx,miny,maxx,maxy,a a='0' minx=-10. miny=-10. maxx=10. maxy=10. ###Funcion de respuesta del raton def callback(event): fil.write('click\n') borra() grafica() posx=event.x posy=event.y posy=600-posy x11=((maxx-minx)/598.)*posx+(minx-((maxx-minx)/598.)) y11=((maxy-miny)/598.)*posy+(miny-((maxy-miny)/598.)) fil.write(str(x11)+'\n') fil.write(str(y11)+'\n') can.create_text(200,20,text='('+str(x11)+', '+str(y11)+')',fill='white',font=('times',16)) fo=a fo=fo.replace("q1","("+str(q1)+")") fo=fo.replace("q2","("+str(q2)+")") can.create_text(180,50,text=fo,fill='white',font=('times',16)) ###Funcion que borra la pantalla def borra(): can.delete(ALL) ###Funcion que calcula valores de la funcion def funcion(x): try: b=eval(a) except ZeroDivisionError: b=2.2222 except ValueError: b=2.2222 23 except OverflowError: b=2.2222 return (b) ###Funcion que cierra el programa def salida(): fil.write('fin\n') win.destroy() fil.close() plataforma=sys.platform if plataforma=='darwin': os.system('mv'+' traza1.txt'+' '+nam+'.txt') if plataforma=='win32': os.system('rename'+' traza1.txt'+' '+nam+'.txt') os.system('del traza1.txt') win.quit() ###Funcion que grafica la funcion def grafica(): if minx<0 and maxx>0: x0=-(600*minx)/(maxx-minx) can.create_line(x0,0,x0,600,fill='#aaa') if miny<0 and maxy>0: y0=-(600*miny)/(maxy-miny) y0=600-y0 can.create_line(0,y0,600,y0,fill='#aaa') for x in range(1,599): x1=((maxx-minx)/598.)*x+(minx-((maxx-minx)/598.)) y1=funcion(x1) y=(598./(maxy-miny))*y1+1-(598.*miny)/(maxy-miny) xs=x+1 x1s=((maxx-minx)/598.)*xs+(minx-((maxx-minx)/598.)) y1s=funcion(x1s) ys=(598./(maxy-miny))*y1s+1-(598.*miny)/(maxy-miny) y=600-y ys=600-ys if y<600 and ys<600 and y1!=2.2222 and y1s!=2.2222 and abs(ys-y)<200.: can.create_line(x,y,xs,ys,fill='white') global fo fo=a fo=fo.replace("q1","("+str(q1)+")") fo=fo.replace("q2","("+str(q2)+")") can.create_text(180,50,text=fo,fill='white',font=('times',16)) ###Funcion que interpreta a la funcion def formula(): 24 fil.write('formula\n') global a a=e_formula.get() fil.write(a+'\n') borra() grafica() ##Funcion para alejar la grafica def zomout(): fil.write('aleja\n') global minx,miny,maxx,maxy a=minx b=miny c=maxx d=maxy hx=(maxx-minx)/10 hy=(maxy-miny)/10 if hx>0 and hy>0: minx=a-hx miny=b-hy maxx=c+hx maxy=d+hy borra() grafica() ###Funcion que acerca la imagen def zomin(): fil.write('acerca\n') global minx,miny,maxx,maxy a=minx b=miny c=maxx d=maxy hx=(maxx-minx)/10 hy=(maxy-miny)/10 if hx>0 and hy>0: minx=a+hx miny=b+hy maxx=c-hy maxy=d-hy borra() grafica() ###Funcion que reinicia la graficacion def reset(): 25 fil.write('reinicia\n') borra() a=-10. b=-10. c=10. d=10. global minx,miny,maxx,maxy minx=a miny=b maxx=c maxy=d grafica() ###Funcion que mueve la grafica hacia la derecha def right(): fil.write('derecha\n') global minx,miny,maxx,maxy a=minx c=maxx minx=a-(c-a)/10 maxx=c-(c-a)/10 borra() grafica() ###Funcion que mueve la grafica a la izquierda def left(): fil.write('izquierda\n') global minx,miny,maxx,maxy a=minx c=maxx minx=a+(c-a)/10 maxx=c+(c-a)/10 borra() grafica() ###Funcion que mueve la grafica hacia arriba def up(): fil.write('arriba\n') global minx,miny,maxx,maxy a=miny c=maxy miny=a-(c-a)/10 maxy=c-(c-a)/10 borra() grafica() ###Funcion que mueve la grafica hacia abajo 26 def down(): fil.write('abajo\n') global minx,miny,maxx,maxy a=miny c=maxy miny=a+(c-a)/10 maxy=c+(c-a)/10 borra() grafica() ###Funcion que captura valor de la escala para q1 def report(event): fil.write('valor de q1\n') global q1 q1=escala.get() fil.write(str(q1)+'\n') borra() grafica() ###Funcion que captura valor de la escala para q2 def report1(event): fil.write('valor de q2\n') global q2 q2=escala1.get() fil.write(str(q2)+'\n') borra() grafica() ###Funcion que captura el nombre de usuario def name(): global nam nam1=nam nam=nam1 nam=e_name.get() def nada(): global aaa def nada1(): global bbbb inicia() ###Funcion que presenta nota acerca de uso del programa def about(): win1=Tk() win1.title('Condiciones de uso') texto=Text(win1,font=labelfont,height=12,width=60) texto.insert(END,'Graficando funciones v1.01\n') texto.insert(END,'Derechos Reservados. Ramon Sebastian Salat Figols. 2008.\n') 27 texto.insert(END,'Condiciones de uso. \n') texto.insert(END,'Se pemite, sin costo alguno, copiar, distribuir y usar sin quitar\n') texto.insert(END,'la nota \"condiciones de uso\" ni su contenido.\n') texto.insert(END,'Tambien se permite modificar con la condicion de que\n') texto.insert(END,'se especifiquen los cambios y el autor de los mismos y\n') texto.insert(END,'la fecha en que se realizaron al distribuir la version modificada.\n') texto.insert(END,'El autor no concede ninguna garantia sobre el uso\n') texto.insert(END,'de este programa, ni acepta ninguna responsabilidad\n') texto.insert(END,'por cualquier consecuencia que se pueda atribuir al \n') texto.insert(END,'uso de este programa.') texto.pack() ###Funcion que presenta la ayuda def helpp(): win2=Tk() scrollbar=Scrollbar(win2) scrollbar.pack(side=RIGHT,fill=Y) win2.title('Ayuda') texto=Text(win2,font=labelfont,height=20,width=50,wrap=WORD,yscrollcommand=scrollb ar.set) scrollbar.config(command=texto.yview) texto.insert(END,'Bienvenido a Graficando funciones v1.01.\n\n') texto.insert(END,'En el rectangulo a la derecha de y=,\n') texto.insert(END,'escribe la formula de la funcion y luego\n') texto.insert(END,'oprime el boton y=.\n') texto.insert(END,'Para acercar la grafica presione acerca.\n') texto.insert(END,'Para alejar la grafica presione aleja.\n') texto.insert(END,'Para mover la grafica a la derecha, presione derecha.\n') texto.insert(END,'Para mover la grafica a la izquierda, presione izquierda.\n') texto.insert(END,'Para mover la grafica hacia arriba, presione arriba.\n') texto.insert(END,'Para mover la grafica hacia abajo, presione abajo.\n') texto.insert(END,'Para limpiar la pantalla, presione limpia\n') texto.insert(END,'Para poner los ejes y la ventana como al principio\n') texto.insert(END,'presione reinicia\n\n') texto.insert(END,'Para escribir una funcion puede usar dos\n') texto.insert(END,'parametros, q1 and q2 y las funciones sin,cos,tan,asin,\n') texto.insert(END,'acos,atan,log,sqrt,fabs,exp y abs.\n') texto.insert(END,'Usted puede variar los parametros por medio \n') texto.insert(END,'de las dos escalas que estan a la derecha.\n') texto.insert(END,'de la pantalla negra.\n\n') texto.insert(END,'Ejemplos de escritura de funciones:\n') texto.insert(END,'x**4-2*x**3+x**2-5*x, x*sin(1/x), (q1-x)**2+q2, q1*sin(q2*x)\n') texto.insert(END,'Al hacer click con el boton izquierdo del raton\n') 28 texto.insert(END,'aparecen en la pantalla las coordenadas del punto.\n') texto.insert(END,'Si pone su nombre arriba de nombre, se creara.\n') texto.insert(END,'un archivo con su nombre con toda la historia, \n') texto.insert(END,'de otro modo el archivo tendra el nombre de traza.\n') texto.insert(END,'\n') texto.insert(END,'La pantalla de graficacion es de 600x600 puntos y\n') texto.insert(END,'el programa puede dibujar segementos con pendiente\n') texto.insert(END,'menor que 200, es decir, entre dos abcisas consecutivas,\n') texto.insert(END,'la maxima variacion vertical es de 199 puntos.\n') texto.insert(END,'Si la grafica tiene un salto en algun punto debido\n') texto.insert(END,'a una discontinuidad de la funcion, esta puede\n') texto.insert(END,'ocultarse uniendo puntos indebidamente. Esto se\n') texto.insert(END,'resuelve usualmente si se realizan acercamientos en\n') texto.insert(END,'forma sucesivamente.\n') texto.pack() #################################### ###Inicio del programa principal########### #################################### ###Definicion de l ventana principal win=Tk() win.title('Graficando funciones v1.01') win.minsize(width=720,height=620) ###Definicion del menu menu=Menu(win,font=labelfont1) win.config(menu=menu) infomenu=Menu(menu,font=labelfont) menu.add_cascade(label='Informacion',font=labelfont,menu=infomenu) infomenu.add_command(label='Condiciones de uso',command=about) infomenu.add_command(label='Ayuda',command=helpp) ###Definicion de la pantalla de graficacion can=Canvas(win,width=600,height=600,bg='black',bd=5) can.bind("<Button-1>",callback) can.bind("<B3-Motion>",callback) ###Definicion de marcos marco1=Frame(win,width=120,height=400,bg='white',bd=5) marco1.pack(side=RIGHT) marco3=Frame(win,width=50,height=600,bg='white',bd=5) marco3.pack(side=RIGHT) marco4=Frame(marco3,width=50,height=60,bg='white',bd=5) marco4.pack(side=TOP) ###Definicion de escalas para los parametros 29 escala=Scale(marco3,from_=10,to=10,command=report,tickinterval=1,resolution=1,width=15,sliderlength=20,length=2 90,font=labelfont) escala.config(bg='grey',fg='black') escala.pack(side=LEFT) escala1=Scale(marco3,from_=10,to=10,command=report1,tickinterval=1,resolution=1,width=15,sliderlength=20,length= 290,font=labelfont) escala1.config(bg='grey',fg='black') escala1.pack(side=RIGHT) ###Definicion del boton para borrar borrar=Button(marco1,text='limpia',command=borra,font=labelfont,width=7) borrar.config(bg='#009',fg='white',bd=5) borrar.pack(side=TOP) ###Definicion de marco marco2=Frame(win,width=700,height=20,bg='white',bd=5) marco2.pack(side=TOP) ###Definicion de boton para captar la formula formula=Button(marco2, text='y= ', command=formula,bd=5) formula.config(bg='#009',fg='white',width=3,bd=5) formula.config(font=labelfont) formula.pack(side=LEFT) e_formula=Entry(marco2,font=labelfont1,width=40,bd=5,bg='grey') e_formula.pack(side=LEFT) ###Definicion d boton para graficar grafica1=Button(marco1,text='grafica',command=grafica,font=labelfont,width=7) grafica1.config(bg='#009',fg='white',bd=5) grafica1.pack(side=TOP) ###Definicion de boton para alejar la grafica zoomo=Button(marco1,text='aleja',command=zomout,font=labelfont,width=7) zoomo.config(bg='#009',fg='white',bd=5) zoomo.pack(side=TOP) ###Definicion de boton para acercar la grafica zoomin=Button(marco1,text='acerca',command=zomin,font=labelfont,width=7) zoomin.config(bg='#009',fg='white',bd=5) zoomin.pack(side=TOP) ###Definicion del boton para mover a la derecha right1=Button(marco1,text='derecha',command=right,font=labelfont,width=7) right1.config(bg='#009',fg='white',bd=5) right1.pack(side=TOP) ###Definicion del boton para mover a la izquierda left1=Button(marco1,text='izquierda',command=left,font=labelfont,width=7) left1.config(bg='#009',fg='white',bd=5) 30 left1.pack(side=TOP) ###Definicion del boton para mover hacia arriba up1=Button(marco1,text='arriba',command=up,font=labelfont,width=7) up1.config(bg='#009',fg='white',bd=5) up1.pack(side=TOP) ###Definicion del boton para mover hacia abajo down1=Button(marco1,text='abajo',command=down,font=labelfont,width=7) down1.config(bg='#009',fg='white',bd=5) down1.pack(side=TOP) ###Definicion del boton para reiniciar res=Button(marco1,text='reinicia',command=reset,font=labelfont,width=7) res.config(bg='#009',fg='white',bd=5) res.pack(side=TOP) ###Definicion del boton para salir salida=Button(marco1,text='salir',command=salida,font=labelfont,width=7) salida.config(bg='#009',fg='white',bd=5) salida.pack(side=TOP) ###Definicion de botones para capturar el nombre de usuario e_name=Entry(marco4,font=labelfont1,width=10,bd=5,bg='grey') e_name.pack(side=TOP) name=Button(marco4,font=labelfont, text='nombre', command=name,bd=5) name.config(bg='#009',fg='white',width=15,bd=5) name.config(font=labelfont) name.pack(side=TOP) can.pack() win.mainloop() 31