2016-05-01 1 views
0

Я пишу простую программу для переключения числа между базовыми 10, 2, 8 и 16. Однако у меня возникают проблемы с несколькими преобразованиями или преобразования обратно в денар. Вот код, я используюPython3 - Проблемы с преобразованием между различными системами счисления

#! python3 

import tkinter as tk 
from tkinter import ttk 

CurrentSystem = 'd' 

def clearEnt(): 
    ent.delete(0, last = None) 

def baseConverter(value,base): 
    try: 
     if base == 2: 
      clearEnt() 
      ent.insert(0, bin(value)) 
      CurrentSystem = 'b' 
     if base == 8: 
      clearEnt() 
      ent.insert(0, oct(value)) 
      CurrentSystem == 'o' 
     if base == 16: 
      clearEnt() 
      ent.insert(0, hex(value)) 
      CurrentSystem == 'h' 
     if base == 10: 
      if CurrentSystem == 'b': 
       clearEnt() 
       ent.insert(0, int(value, 2)) 
      if CurrentSystem == 'o': 
       clearEnt() 
       ent.insert(0, int(value, 8)) 
      if CurrentSystem == 'h': 
       clearEnt() 
       ent.insert(0, int(value, 16)) 
    except ValueError: 
     clearEnt() 
     ent.insert(0, 'ERROR') 

root = tk.Tk() 
root.title('Number Converter') 

ent = ttk.Entry() 
ent.grid (row = 0, column = 1, columnspan = 2, padx = 5) 

button1 = ttk.Button(root, text = "Den") 
button2 = ttk.Button(root, text = "Bin", command = lambda:baseConverter(int(ent.get()), 2)) 
button3 = ttk.Button(root, text = "Oct", command = lambda:baseConverter(ent.get(), 8)) 
button4 = ttk.Button(root, text = "Hex", command = lambda:baseConverter(ent.get(), 16)) 

button1.grid(row = 1, column = 0) 
button2.grid(row = 1, column = 1) 
button3.grid(row = 1, column = 2) 
button4.grid(row = 1, column = 3) 

root.mainloop() 

Как вы можете видеть, идея заключается в том, что число в поле ввода изменений лор ТЗ на основе нажатия кнопки. Пока он изменится от логана к другой системе, а затем откажется снова или снова работать. Буду признателен за любую помощь или совет по этому поводу. Спасибо

+0

Сделайте свой код модульным. Забудьте о tkinter полностью на некоторое время и просто сосредоточьтесь на правильном использовании функции или функций преобразования. Затем - назовите их соответствующим образом в обработчиках событий. Какие проблемы у вас есть с конверсией? –

+0

При запуске его с python3.4 постоянно появляются сообщения об ошибках типа: ent.insert (0, oct (value)) ТипError: объект 'str' не может быть интерпретирован как целое. Скорее всего, проблема в том, что значения представлены в виде строк, а ваши команды oct/hex терпят неудачу. –

+3

Чтобы развернуть мой последний комментарий, хорошей стратегией было бы написать функцию Python 'changeBase (s, a, b)', которая будет принимать * string * 's', int' a', который представляет текущую базу 's' и int' b', который представляет целевую базу, и которая возвращает строку, представляющую число в целевой базе. Получите это, чтобы он работал безупречно в оболочке (возможно, написал тестовый скрипт для него, который проверяет все допустимые случаи 4x4 = 16), а затем беспокоиться о том, как подключить его к tkinter –

ответ

0

Обратите внимание на отсутствие симметрии в 4-х направлениях:

button1 = ttk.Button(root, text = "Den") 
button2 = ttk.Button(root, text = "Bin", command = lambda:baseConverter(int(ent.get()), 2)) 
button3 = ttk.Button(root, text = "Oct", command = lambda:baseConverter(ent.get(), 8)) 
button4 = ttk.Button(root, text = "Hex", command = lambda:baseConverter(ent.get(), 16)) 

В первом, нет команды, второй имеет смысл (но все еще есть проблемы), а третий и четвертый отсутствие звонка на int, который находится в четвертом. Почему бы не сделать все 4 строки больше похожими на вторую строку? Также - обратите внимание, что если int() принимает необязательный аргумент для базы. Возможно, вы хотите что-то сделать с этим аргументом, что связано с CurrentSystem. Обратите внимание, что для этой цели может быть лучше для CurrentSystem удерживать int, например 2,8,10 или 16, а не строку.

И, наконец, обратите внимание на то, что для отображения вы можете отобразить что-то похожее на 100101, а не на 0b100101. Для этого вы можете использовать оператор среза: если s = '0b100101', то s[2:] = '100101'

+0

Я полностью пропустил разницу между кнопками 2 и 3/4 , Я сделал это изменение. Я честно понятия не имею, что делать для первой кнопки, хотя –

+0

Вероятно, вас смущает отсутствие базовой версии «bin, oct, hex». Просто используйте 'str()' в этом случае. Base-10 - это строковое представление * default * для 'int'. Вам не нужно ничего особенного делать. Также обратите внимание, что 'int (" 123 ", 10) = 123)'. Предоставление базы (10) не обязательно, но это ничего не вредит. –

+0

Что делать, если я конвертирую в одну систему и хочу, чтобы она вернулась в ден? Я собираюсь добавить радиокнопки, чтобы показать текущую систему чисел, используемую значением в записи –

0

Это состоит из двух частей: от строки до целого и обратно. Поэтому неплохо создать функцию для каждой единицы функциональности.

Преобразование строки в целое число.

int('100', 8) == 8**2 # second argument is the base 

Преобразование целого числа в строку.

def int_to_str(number, base): 
    assert isinstance(number, int) 
    char = {2:'b', 8:'o', 10:'d', 16:'x'}[base] 
    return '{0:{1}}'.format(number, char) 

int_to_str(8**2, 8) == '100' 

Затем используйте эти функции в своем коде TK. Что-то вроде этого:

button1 = ttk.Button(root, text="Dec", command=lambda:int(ent.get(), 10)) 
button2 = ttk.Button(root, text="Bin", command=lambda:int(ent.get(), 2)) 
button3 = ttk.Button(root, text="Oct", command=lambda:int(ent.get(), 8)) 
button4 = ttk.Button(root, text="Hex", command=lambda:int(ent.get(), 16)) 
+0

Что вы говорите, так это то, что я использую первую строку в качестве лямбда, а затем ставим их перед печатью? –

+0

То, что вы получаете из окна ввода, является строкой. Чтобы преобразовать это в целое число, вам нужно знать базу. Ваш код указывает, что пользователи сообщают вам базу, нажав соответствующую кнопку. Таким образом, вы используете функцию 'int', передавая ей как входную строку, так и базу, чтобы получить фактическое целое число, которое хотят пользователи. Чтобы получить базу для вывода номера, вам понадобится третья часть информации, например. TK Radiobutton. Затем вы вызываете 'int_to_str' с целым числом для преобразования (результат из' int' before) и базы вывода и показываете полученную строку пользователю. – Alvra