comment
IRC Chat
play_arrow
Este sitio utiliza cookies propias y de terceros. Si continúa navegando consideramos que acepta el uso de cookies. OK Más Información.

NumSys Calculator by Azav

  • 2 Respuestas
  • 1236 Vistas

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Azav

  • *
  • Underc0der
  • Mensajes: 23
  • Actividad:
    0%
  • Reputación 0
    • Ver Perfil
« en: Enero 23, 2015, 04:16:23 am »
Numbering System Calculator by Azav

La semana pasada estuve investigando las representaciones ASCII de los caracteres, para las cuales se usan distintos sistemas numéricos (varían en su base). Los cuatro sistemas numéricos más usados son el binario, el octal, el decimal y el hexadecimal. Por ejemplo: la letra 'a' tiene por valor ASCII el numero 97 en el sistema decimal, o bien 1100001 en binario, o bien 141 en octal o bien 61 en hexadecimal (este último es que se usa en los editores de archivos ejecutables). Resulta que para entender mejor cómo se llevan a cabo las transformaciones de un sistema a otro creé esta herramienta , que también permite realizar operaciones (suma y resta) en los diversos sistemas numéricos. No es nada del otro mundo pero a mi me sirvió para entender mejor cómo funcionan estos sistemas.

La herramienta la programé en Python 3.4 y usé tkinter para la interfaz gráfica. Convertí el archivo .py a ejecutable usando py2exe. Captura (se ve un poco mal):


Source code:
Código: Python
  1. from tkinter import *
  2. from tkinter import messagebox, ttk
  3.  
  4. def cambio_de_base(base, valorbase10):
  5.         caracteres = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  6.         lista = [valorbase10]
  7.         while True:
  8.                 division = valorbase10 // base
  9.                 if division == 0:
  10.                         break
  11.                 else:
  12.                         lista.append(division)
  13.                         valorbase10 = division
  14.         lista.reverse()
  15.         valorbase2 = ''
  16.         for i in lista:
  17.                 resto = i % base
  18.                 valorbase2 += caracteres[resto:resto + 1]
  19.         return valorbase2
  20.  
  21. def cambio_a_decimal(base, valorbase):
  22.         caracteres = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  23.         for char in valorbase:
  24.                 if caracteres[:base].find(char) == -1:
  25.                         return "ERROR"
  26.         j = len(valorbase)
  27.         k = -1
  28.         sumatoria = 0
  29.         for i in range(j):
  30.                 valor_parcial = caracteres.find(valorbase[k:j]) * (base ** i)
  31.                 sumatoria = sumatoria + valor_parcial
  32.                 j = k
  33.                 k = k - 1
  34.         return sumatoria
  35.  
  36.  
  37. class Interfaz():
  38.         def __init__(self):
  39.                 #Main Window
  40.                 self.mainWindow = Tk()
  41.                 self.mainWindow.geometry("450x250")
  42.                 self.mainWindow.title("Azav's Numeric Calculator")
  43.                 self.mainWindow.protocol("WM_DELETE_WINDOW", self.quit)
  44.                
  45.                 #ComboBoxs
  46.                 ComboVar = StringVar()
  47.                 self.Combo = ttk.Combobox(self.mainWindow, textvariable=ComboVar, width = "2", values=('+', '-'))
  48.                 self.Combo.place(x=105, y=85)
  49.                
  50.                 #Textboxs
  51.                 self.Sumando1 = Text(self.mainWindow, height = "0.7", width = "30", relief = "flat")
  52.                 self.Sumando1.place(x=150, y=55)
  53.                 self.Sumando2 = Text(self.mainWindow, height = "0.7", width = "30", relief = "flat")
  54.                 self.Sumando2.place(x=150, y=85)
  55.                 self.Suma = Text(self.mainWindow, height = "0.7", width = "30", relief = "flat")
  56.                 self.Suma.place(x=150, y=140)
  57.  
  58.         def start(self):       
  59.                 def Operate():
  60.                         nro1 = self.Sumando1.get('1.0', 'end').strip().upper()
  61.                         nro2 = self.Sumando2.get('1.0', 'end').strip().upper()
  62.                         base = OptVar.get()
  63.                         nro1_dec = cambio_a_decimal(base, nro1)
  64.                         nro2_dec = cambio_a_decimal(base, nro2)
  65.                         if nro1_dec == "ERROR":
  66.                                 messagebox.showwarning("Azav's Numeric Calculator", nro1 + " is not a valid value for base " + str(base) + ".")
  67.                                 return
  68.                         if nro2_dec == "ERROR":
  69.                                 messagebox.showwarning("Azav's Numeric Calculator", nro2 + " is not a valid value for base " + str(base) + ".")
  70.                                 return
  71.                         if self.Combo.get().strip() == '+':
  72.                                 resultado = nro1_dec + nro2_dec
  73.                         else:
  74.                                 resultado = nro1_dec - nro2_dec
  75.                         if resultado < 0:
  76.                                 messagebox.showwarning("Azav's Numeric Calculator", "Negative numbers are not supported.")
  77.                                 return
  78.                         resultado_base = cambio_de_base(base, resultado)
  79.                         self.Suma.delete('1.0', 'end')
  80.                         self.Suma.insert('1.0', str(resultado_base))
  81.                         info_list = []
  82.                         if base != 2:
  83.                                 info_list.append("Binary result: " + str(cambio_de_base(2, resultado)))
  84.                         if base != 8:
  85.                                 info_list.append("Octal result: " + str(cambio_de_base(8, resultado)))
  86.                         if base != 10:
  87.                                 info_list.append("Decimal result: " + str(resultado))
  88.                         if base != 16:
  89.                                 info_list.append("Hexdecimal result: " + str(cambio_de_base(16, resultado)))
  90.                         info = ""
  91.                         for i in info_list:
  92.                                 info = info + i + "\n"
  93.                         lbInfo['text'] = info
  94.                
  95.                 def BaseConverter():
  96.                         base = OptVar.get()
  97.                         suma = self.Suma.get('1.0', 'end').strip().upper()
  98.                         NewGUI = BaseConverterGUI()
  99.                         NewGUI.txtBase.delete('1.0', 'end')
  100.                         NewGUI.txtBase.insert('1.0', str(base))
  101.                         exec("NewGUI.txt" + str(base) + ".delete('1.0', 'end')")
  102.                         exec("NewGUI.txt" + str(base) + ".insert('1.0', suma)")
  103.                         NewGUI.ConvertBases()
  104.                         NewGUI.start()
  105.                
  106.                 #Combo Config
  107.                 self.Combo.set('+')
  108.                
  109.                 #OptionButton
  110.                 OptVar = IntVar()
  111.                 opt1 = Radiobutton(self.mainWindow, text="Binary", width = "10", variable=OptVar, indicatoron=0, value=2).place(x=15, y=15)
  112.                 opt2 = Radiobutton(self.mainWindow, text="Octal", width = "10", variable=OptVar, indicatoron=0, value=8).place(x=115, y=15)
  113.                 opt3 = Radiobutton(self.mainWindow, text="Decimal", width = "10", variable=OptVar, indicatoron=0, value=10).place(x=215, y=15)
  114.                 opt4 = Radiobutton(self.mainWindow, text="Hexdecimal", width = "10", variable=OptVar, indicatoron=0, value=16)
  115.                 opt4.place(x=315, y=15)
  116.                 opt4.select()
  117.                
  118.                 #Buttons
  119.                 cmdCalcular = Button(self.mainWindow,  text = "Calculate", width = "10", height = "4", command = lambda:Operate()).place(x=15, y=55)
  120.                 cmdBaseConverter = Button(self.mainWindow,  text = "Base Convert", width = "10", height = "1", command = lambda:BaseConverter()).place(x=15, y=140)
  121.                
  122.                 #Labels
  123.                 lbLine = Label(self.mainWindow, text="__________________________________", font=("Courier New", 8)).place(x=150, y=110)
  124.                 lbInfo = Label(self.mainWindow, text="", font=("Courier New", 10), justify="left")
  125.                 lbInfo.place(x=15, y=180)
  126.                
  127.                 #Start
  128.                 self.mainWindow.mainloop()
  129.  
  130.         def quit(self):
  131.                 if messagebox.askyesno("Azav's Numeric Calculator", "Are you sure you want to quit?"):
  132.                         self.mainWindow.destroy()
  133.                         self.mainWindow.quit()
  134.                         quit()
  135.                        
  136.                        
  137. class BaseConverterGUI():
  138.         def __init__(self):
  139.                 #Main Window
  140.                 self.mainWindow = Tk()
  141.                 self.mainWindow.geometry("1100x500")
  142.                 self.mainWindow.title("Azav's Numeric Calculator")
  143.  
  144.                 #TextBoxs
  145.                 for i in range(2, 14):
  146.                         exec('self.txt' + str(i) + ' = Text(self.mainWindow, height = "0.6", width = "30", relief = "flat")')
  147.                         exec('self.txt' + str(i) + '.place(x=90, y=' + str(30 * i) + ')')
  148.                 for i in range(14, 26):
  149.                         exec('self.txt' + str(i) + ' = Text(self.mainWindow, height = "0.6", width = "30", relief = "flat")')
  150.                         exec('self.txt' + str(i) + '.place(x=460, y=' + str(30 * (i - 12)) + ')')
  151.                 for i in range(26, 37):
  152.                         exec('self.txt' + str(i) + ' = Text(self.mainWindow, height = "0.6", width = "30", relief = "flat")')
  153.                         exec('self.txt' + str(i) + '.place(x=830, y=' + str(30 * (i - 24)) + ')')
  154.                
  155.                 self.txtBase = Text(self.mainWindow, height = "0.6", width = "10", relief = "flat")
  156.                 self.txtBase.place(x=575, y=470)
  157.                 self.txtBase.insert('1.0', '10')               
  158.                
  159.         def start(self):               
  160.                 def DoConversion():
  161.                         self.ConvertBases()
  162.  
  163.                 #Labels
  164.                 for i in range(2, 14):
  165.                         if i == 2 or i == 8 or i == 10:
  166.                                 color = ', fg = "red"'
  167.                         else:
  168.                                 color = ''
  169.                         exec('lb' + str(i) + ' = Label(self.mainWindow' + color + ', text="Base ' + str(i) + ':", font=("Courier New", 10)).place(x=20, y=' + str(30 * i) + ')')
  170.                 for i in range(14, 26):
  171.                         if i == 16:
  172.                                 color = ', fg = "red"'
  173.                         else:
  174.                                 color = ''
  175.                         exec('lb' + str(i) + ' = Label(self.mainWindow' + color + ', text="Base ' + str(i) + ':", font=("Courier New", 10)).place(x=390, y=' + str(30 * (i - 12)) + ')')                       
  176.                 for i in range(26, 37):
  177.                         exec('lb' + str(i) + ' = Label(self.mainWindow, text="Base ' + str(i) + ':", font=("Courier New", 10)).place(x=760, y=' + str(30 * (i - 24)) + ')')
  178.                 lbBase = Label(self.mainWindow, text="Base:", font=("Courier New", 10)).place(x=520, y=470)
  179.                
  180.                 #Buttons
  181.                 cmdCalcular = Button(self.mainWindow,  text = "Calculate", width = "25", command = lambda:DoConversion()).place(x=500, y=440)
  182.                
  183.                 #Start
  184.                 self.mainWindow.mainloop()
  185.  
  186.         def ConvertBases(self):
  187.                 local_var = locals()
  188.                 BaseGuia = self.txtBase.get('1.0', 'end').strip()
  189.                 try:
  190.                         int(BaseGuia)
  191.                 except:
  192.                         messagebox.showwarning("Azav's Numeric Calculator", "Base must be a number.")
  193.                         return
  194.                 if int(BaseGuia) < 2 or int(BaseGuia) > 36:
  195.                         messagebox.showwarning("Azav's Numeric Calculator", "Base must be a value beetween 2 and 36.")
  196.                         return
  197.                 exec("valor = self.txt" + BaseGuia + ".get('1.0', 'end').strip().upper()", globals(), local_var)
  198.                 base_decimal = cambio_a_decimal(int(BaseGuia), local_var['valor'])
  199.                 if base_decimal == "ERROR":
  200.                         messagebox.showwarning("Azav's Numeric Calculator", local_var['valor'] + " is not valid value for base " + BaseGuia + ".")
  201.                         return
  202.                 else:
  203.                         for i in range(2, 37):
  204.                                 exec("self.txt" + str(i) + ".delete('1.0', 'end')")
  205.                                 exec("self.txt" + str(i) + ".insert('1.0', cambio_de_base(i, base_decimal))")
  206.  
  207.                
  208. GUI = Interfaz()
  209. GUI.start()
Lo importante son las dos funciones del inicio, el resto es pura interfaz.

¡Espero le sirva a alguien!

Desconectado blackdrake

  • *
  • Co Admin
  • Mensajes: 1910
  • Actividad:
    15%
  • Reputación 15
    • Ver Perfil
« Respuesta #1 en: Enero 23, 2015, 08:10:30 am »
Muy bueno, ahora mismo leo el código pues se ve interesante y no sé apenas python ^^

Gracias :D



Desconectado Barlan

  • *
  • Underc0der
  • Mensajes: 89
  • Actividad:
    0%
  • Reputación 0
  • "The demons of my own design"
    • Ver Perfil
  • Twitter: @BarlanV
« Respuesta #2 en: Enero 23, 2015, 12:07:14 pm »
Bastante curioso el programa.  :o
Buen aporte. xD

Saludos!


 

¿Te gustó el post? COMPARTILO!



Azav Cipher Algorithm

Iniciado por Azav

Respuestas: 1
Vistas: 2067
Último mensaje Octubre 11, 2014, 06:45:15 pm
por Once