lunes, 12 de septiembre de 2011

Mi primera aplicación en Python: Calculadora de Ingeniería Económica

Desde hace tiempo había leído de este maravilloso lenguaje, sus ventajas sobre los demás como su facilidad, que es libre y sobre todas las cosas que es multiplataforma. Sin duda es el ideal para comenzar a programar, he aquí un ejemplo.

Investigando un poco y con ayuda de algunos tutoriales pude hacer mi primera aplicación gráfica en python. Por el momento no es la gran cosa, pero espero tener tiempo y sobre todo paciencia para terminar un proyecto personal, me gustaría hacer algo así como una suite para Ingenieros multiplataf, para los que conozcan WinQSB sería algo paracido, con herramientas para diferentes áreas como Investigación de Operaciones e Ingeniería Económica por mencionar sólo algunos.

Algunos botones aún no funcionan, pero ya resuelve operaciones como en el ejemplo.

El código fue escrito con ayuda de wxGlade y SPE Stani's Python Editor que puedes encontrar en el Centro de Software Ubuntu, el libro Python para todos, un tutorial de Ubuntu Life, y una calculadora básica en Python.
Para resolver un problema de este tipo por ejemplo en Excel o alguna calculadora científica se necesita teclear algo como esto :
VA= 1500*((.14*(1+.14)^5)/(((1+.14)^5)-1) 
Hay muchas más posibilidades de equivocarse, algo que no te puede pasar por ejemplo en un examen final...

Aquí el código:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# generated by wxGlade 0.6.3 on Tue Aug 16 18:36:57 2011


import wx


# begin wxGlade: extracode
# end wxGlade


class Ventana_calculadora(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: Ventana_calculadora.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        
        # Menu Bar
        self.Calculadora_menubar = wx.MenuBar()
        wxglade_tmp_menu = wx.Menu()
        wxglade_tmp_menu.Append(11, "Borrar", "", wx.ITEM_NORMAL)
        wxglade_tmp_menu.AppendSeparator()
        wxglade_tmp_menu.Append(22, "Salir", "", wx.ITEM_NORMAL)
        self.Calculadora_menubar.Append(wxglade_tmp_menu, "Archivo")
        wxglade_tmp_menu = wx.Menu()
        wxglade_tmp_menu.Append(55, "Acerca de", "", wx.ITEM_NORMAL)
        self.Calculadora_menubar.Append(wxglade_tmp_menu, "Ayuda")
        self.SetMenuBar(self.Calculadora_menubar)
        # Menu Bar end
        self.entrada_datos = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE and wx.ALIGN_RIGHT)
        self.entrada_datos.SetFocus()
        self.lblEjemplo = wx.StaticText(self, -1, "Ejemplo de Entrada: 1200(VP/VF,15%,6)", style=wx.ALIGN_CENTRE)
        self.btnVPVF = wx.Button(self, -1, "VP/VF")
        self.btnVFVP = wx.Button(self, -1, "VF/VP")
        self.btnVAVF = wx.Button(self, -1, "VA/VF")
        self.btnIRetroceso = wx.BitmapButton(self, -1, wx.Bitmap("/dos/Documentos/Programacion en Phyton/Proyecto Personal/btnretroceso2.png", wx.BITMAP_TYPE_ANY), style=wx.BU_AUTODRAW)
        self.btnVPVA = wx.Button(self, -1, "VP/VA")
        self.btnVFVA = wx.Button(self, -1, "VF/VA")
        self.btnVAVP = wx.Button(self, -1, "VA/VP")
        self.btnIgual = wx.Button(self, -1, "=")
        self.btn7 = wx.Button(self, -1, "7")
        self.btn8 = wx.Button(self, -1, "8")
        self.btn9 = wx.Button(self, -1, "9")
        self.btnMas = wx.Button(self, -1, "+")
        self.btn4 = wx.Button(self, -1, "4")
        self.btn5 = wx.Button(self, -1, "5")
        self.btn6 = wx.Button(self, -1, "6")
        self.btnMenos = wx.Button(self, -1, "-")
        self.btn1 = wx.Button(self, -1, "1")
        self.btn2 = wx.Button(self, -1, "2")
        self.btn3 = wx.Button(self, -1, "3")
        self.bx = wx.Button(self, -1, "x")
        self.btnPunto = wx.Button(self, -1, ".")
        self.btn0 = wx.Button(self, -1, "0")
        self.btnComa = wx.Button(self, -1, ",")
        self.btnDivision = wx.Button(self, -1, "/")
        self.btnRaiz = wx.Button(self, -1, "Raiz")
        self.btnPotencia = wx.Button(self, -1, "Potencia")
        self.btnParentesis1 = wx.Button(self, -1, "(")
        self.btnParentesis2 = wx.Button(self, -1, ")")
        self.panel_1 = wx.Panel(self, -1)
        self.btnBorrar = wx.Button(self, -1, "Borrar")
        self.btnSalir = wx.Button(self, -1, "Salir")
        self.static_line_1 = wx.StaticLine(self, -1)
        
        #Se ponen los metodos que activa el evento de cada boton
        self.btnIgual.Bind (wx.EVT_BUTTON,self.Resolver)
        self.btn1.Bind(wx.EVT_BUTTON,self.Uno)
        self.btn2.Bind(wx.EVT_BUTTON,self.Dos)
        self.btn3.Bind(wx.EVT_BUTTON,self.Tres)
        self.btn4.Bind(wx.EVT_BUTTON,self.Cuatro)
        self.btn5.Bind(wx.EVT_BUTTON,self.Cinco)
        self.btn6.Bind(wx.EVT_BUTTON,self.Seis)
        self.btn7.Bind(wx.EVT_BUTTON,self.Siete)
        self.btn8.Bind(wx.EVT_BUTTON,self.Ocho)
        self.btn9.Bind(wx.EVT_BUTTON,self.Nueve)
        self.btn0.Bind(wx.EVT_BUTTON,self.Cero)
        self.btnIRetroceso.Bind(wx.EVT_BUTTON,self.Retroceso)
        
        self.btnVPVF.Bind(wx.EVT_BUTTON,self.VPVF)
        self.btnVPVA.Bind(wx.EVT_BUTTON,self.VPVA)
        self.btnVFVP.Bind(wx.EVT_BUTTON,self.VFVP)
        self.btnVFVA.Bind(wx.EVT_BUTTON,self.VFVA)
        self.btnVAVP.Bind(wx.EVT_BUTTON,self.VAVP)
        self.btnVAVF.Bind(wx.EVT_BUTTON,self.VAVF)
        self.btnParentesis1.Bind(wx.EVT_BUTTON,self.Parentesis1)
        self.btnParentesis2.Bind(wx.EVT_BUTTON,self.Parentesis2)
        self.btnPunto.Bind(wx.EVT_BUTTON,self.Punto)
        self.btnComa.Bind(wx.EVT_BUTTON,self.Coma)


        
        self.__set_properties()
        self.__do_layout()
        # end wxGlade
        
    def Resolver(self, evento=None):
        strCadenaEntrada=self.entrada_datos.GetValue()
        print strCadenaEntrada
        lstValores = strCadenaEntrada.split(",")
        numValor = lstValores[0].split("(")
        lstValores[0]=float(numValor[0])
        numNPeriodos=lstValores[2].split(")")
        lstValores.append(int(numNPeriodos[0]))
        print lstValores[3]
        lstValores[2]= float(lstValores[1])
        lstValores[1]=numValor[1]
        # lstValores contiene los valores por separado de la cadena de entrada
        # van en orden, ejemplo lstValores[2] es la tasa i, y lstValores[3]Periodos
        if lstValores[1]== "VF/VP" or lstValores[1]=="F/P":
            resultado=float(lstValores[0]*((1+lstValores[2])**lstValores[3]))
            self.entrada_datos.SetValue(str(resultado))
        elif lstValores[1]== "VF/VA" or lstValores[1]=="F/A":
            resultado=float(lstValores[0]*((((1+lstValores[2])**lstValores[3])-1)/lstValores[2]))
            self.entrada_datos.SetValue(str(resultado))
        elif lstValores[1]== "VP/VF" or lstValores[1]=="P/F":
            resultado=float(lstValores[0]*(1/((1+lstValores[2])**lstValores[3])))
            self.entrada_datos.SetValue(str(resultado))
        elif lstValores[1]== "VA/VF" or lstValores[1]=="A/F":
            resultado=float(lstValores[0]*(lstValores[2]/(((1+lstValores[2])**lstValores[3])-1)))
            self.entrada_datos.SetValue(str(resultado))
        
            
    def Uno (self,evento=None):
        self.entrada_datos.AppendText('1')
    def Dos (self,evento=None):
        self.entrada_datos.AppendText('2')
    def Tres (self,evento=None):
        self.entrada_datos.AppendText('3')    
    def Cuatro (self,evento=None):
        self.entrada_datos.AppendText('4')
    def Cinco (self,evento=None):
        self.entrada_datos.AppendText('5')  
    def Seis (self,evento=None):
        self.entrada_datos.AppendText('6')
    def Siete (self,evento=None):
        self.entrada_datos.AppendText('7')
    def Ocho (self,evento=None):
        self.entrada_datos.AppendText('8')
    def Nueve (self,evento=None):
        self.entrada_datos.AppendText('9')
    def Cero (self,evento=None):
        self.entrada_datos.AppendText('0')
    def VFVP (self,evento=None):
        self.entrada_datos.AppendText("VF/VP")
    def VAVP (self,evento=None):
        self.entrada_datos.AppendText("VA/VP")
    def VPVF (self,evento=None):
        self.entrada_datos.AppendText("VP/VF")
    def VPVA (self,evento=None):
        self.entrada_datos.AppendText("VP/VA")
    def VAVF (self,evento=None):
        self.entrada_datos.AppendText("VA/VF")
    def VFVA (self,evento=None):
        self.entrada_datos.AppendText("VF/VA")
    def Parentesis1 (self,evento=None):
        self.entrada_datos.AppendText("(")
    def Parentesis2 (self,evento=None):
        self.entrada_datos.AppendText(")")   
    def Punto (self,evento=None):
        self.entrada_datos.AppendText(".")
    def Coma (self,evento=None):
        self.entrada_datos.AppendText(",")
    def Retroceso (self,evento=None):
        strCadenaEntrada=self.entrada_datos.GetValue()
        self.entrada_datos.SetValue(strCadenaEntrada[:-1])
        
    def __set_properties(self):
        # begin wxGlade: Ventana_calculadora.__set_properties
        self.SetTitle("Calculadora")
        self.entrada_datos.SetFont(wx.Font(20,wx.DEFAULT, wx.NORMAL, wx.LIGHT, 0, "Purisa"))
        self.btnVPVF.SetBackgroundColour(wx.Colour(252, 255, 223))
        self.btnVFVP.SetBackgroundColour(wx.Colour(252, 255, 223))
        self.btnVAVF.SetBackgroundColour(wx.Colour(254, 255, 244))
        self.btnIRetroceso.SetBackgroundColour(wx.Colour(255, 233, 237))
        self.btnIRetroceso.SetSize(self.btnIRetroceso.GetBestSize())
        self.btnVPVA.SetBackgroundColour(wx.Colour(252, 255, 223))
        self.btnVFVA.SetBackgroundColour(wx.Colour(252, 255, 223))
        self.btnVAVP.SetBackgroundColour(wx.Colour(252, 255, 223))
        self.btnIgual.SetBackgroundColour(wx.Colour(185, 255, 196))
        self.btnMas.SetBackgroundColour(wx.Colour(228, 235, 255))
        self.btnMenos.SetBackgroundColour(wx.Colour(228, 235, 255))
        self.bx.SetBackgroundColour(wx.Colour(228, 235, 255))
        self.btnPunto.SetBackgroundColour(wx.Colour(228, 235, 255))
        self.btnComa.SetBackgroundColour(wx.Colour(228, 235, 255))
        self.btnDivision.SetBackgroundColour(wx.Colour(228, 235, 255))
        self.btnRaiz.SetBackgroundColour(wx.Colour(228, 235, 255))
        self.btnPotencia.SetBackgroundColour(wx.Colour(228, 235, 255))
        self.btnParentesis1.SetBackgroundColour(wx.Colour(228, 235, 255))
        self.btnParentesis2.SetBackgroundColour(wx.Colour(228, 235, 255))
        # end wxGlade


    def __do_layout(self):
        # begin wxGlade: Ventana_calculadora.__do_layout
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_2 = wx.GridSizer(2, 4, 0, 0)
        grid_sizer_1 = wx.GridSizer(8, 4, 0, 0)
        sizer_1.Add(self.entrada_datos, 0, wx.ALL|wx.EXPAND, 10)
        sizer_1.Add(self.lblEjemplo, 0, wx.ALL|wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
        grid_sizer_1.Add(self.btnVPVF, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnVFVP, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnVAVF, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnIRetroceso, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnVPVA, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnVFVA, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnVAVP, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnIgual, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btn7, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btn8, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btn9, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnMas, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btn4, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btn5, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btn6, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnMenos, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btn1, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btn2, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btn3, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.bx, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnPunto, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btn0, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnComa, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnDivision, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnRaiz, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnPotencia, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnParentesis1, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.btnParentesis2, 0, wx.EXPAND, 0)
        sizer_1.Add(grid_sizer_1, 6, wx.ALL|wx.EXPAND, 0)
        grid_sizer_2.Add(self.panel_1, 1, wx.EXPAND, 0)
        grid_sizer_2.Add(self.btnBorrar, 0, wx.EXPAND, 0)
        grid_sizer_2.Add(self.btnSalir, 0, wx.EXPAND, 0)
        sizer_1.Add(grid_sizer_2, 0, wx.EXPAND, 2)
        sizer_1.Add(self.static_line_1, 0, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        sizer_1.Fit(self)
        self.Layout()
        # end wxGlade
        
# end of class Ventana_calculadora
    
if __name__ == "__main__":
    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    Calculadora = Ventana_calculadora(None, -1, "")
    app.SetTopWindow(Calculadora)
    Calculadora.Show()
    app.MainLoop()




Cabe mencionar que el código aún no es perfecto, pero si deseas hacer algún comentario, modificación, o tienes duda de alguna parte del código, puedes hacerlo en los comentarios, o por medio de un correo electrónico a ubuntu.latino@gmail.com

1 comentario:

  1. Pues yo estoy comenzando a leer el manual que mencionas. Quiero hacer algo grafico pero no tengo idea.

    ResponderEliminar

Eyyy!!! antes de que te vayas!!! deja tu comentario, critica, chisme, opinión o por que no? un chiste...
Un +1, un me gusta o un retweet serían suficientes para agradecer :)
"Saber que a los demás les gusta tu trabajo, te motiva a hacer más y mejores cosas"