если / элиф растолочь - PullRequest
       12

если / элиф растолочь

3 голосов
/ 05 февраля 2012

Это мой второй вопрос на этом сайте, и оба они имеют дело с утверждениями «если», которые работают не так, как ожидалось.Я изучал Python около 3-4 месяцев, и я помню в начале, когда я учил «для», «если» и «в то время как я помню, я думал, что утверждение« если »является самым простым из трех;Я начинаю осознавать, что операторы «если» не так ясны, как я когда-то думал.

Я пишу конвертер, который преобразует двоичный, десятичный и шестнадцатеричный формат без использования каких-либо встроенных Pythonв математических функциях.Я использую tkinter.

Проблема, о которой я буду спрашивать о сделках, когда выбран переключатель «Преобразовать из двоичного».под 3 переключателями «конвертировать из» стоят 3 переключателя «конвертировать в».Следующий код предназначен для преобразования из двоичного в десятичное, если установлен флажок dec_bttn, и в шестнадцатеричный, если установлен флажок hex_bttn:

def from_binary(self, dec_bttn, hex_bttn):
    """ Performs conversion from base2 to base10 and base16. """
    bits = '1010'               #actual code used -> self.input_str.get()
    exp =  len(bits) -1         #actual code used -> len(self.input_str.get()) - 1

    # operate on valid string
    # converts to decimal
    if self.dec_bttn:           
        dtot = 0
        while exp >= 1:
            for i in bits[:-1]:
                if i == "1":
                    dtot += 2**exp
                elif i == "0":
                    dtot = dtot                        
                exp -= 1

            if bits[-1] == "1":
                dtot += 1

            self.output_disp.delete(0.0, END)
            self.output_disp.insert(0.0, dtot)


    # convert to hex

    elif self.hex_bttn:
        hex_digits = {
                      10: 'a', 11: 'b',
                      12: 'c', 13: 'd',
                      14: 'e', 15: 'f'
                      }
        string_length = len(bits)
        exp = len(bits) - 1
        if string_length <= 4:
            htot = 0
            while exp >= 1:
                for i in bits[:-1]:
                    if i == "1":
                        htot += 2**exp
                    elif i == "0":
                        htot = htot                        
                    exp -= 1

                if bits[-1] == "1":
                    htot += 1

            for i in hex_digits.keys():
                if i == htot:
                    htot = hex_digits[i]
                else:
                    htot = htot

            self.output_disp.delete(0.0, END)
            self.output_disp.insert(0.0, htot)

Я разместил весь метод from_binary.Это, вероятно, немного больше, чем нужно, но слишком много лучше, чем пренебрегать какой-либо суммой.

Поскольку мне нужно в конечном итоге разбить строку на полубайтовые строки для шестнадцатеричного преобразования, оно теперь установлено как <= 4Поэтому я тестирую его только с использованием 4-битных строк. </p>

В нынешнем виде, используя 'elif self.hex_bttn', он преобразует двоичный код в десятичный независимо от того, какой флажок установлен.Если я изменю это на 'if self.hex_bttn', то он преобразуется в шестнадцатеричный независимо от того, какой флажок установлен.

Математика и все работает правильно и выводит правильно.Это просто смешение с этими «если» заявлениями, которые задерживают мой прогресс.На мой взгляд, для начинающих это кажется довольно простым тестом, но я, очевидно, что-то упускаю.

Я был бы очень признателен, если бы кто-то мог поставить меня на правильный путь.

Благословение F.

Ответы [ 2 ]

6 голосов
/ 05 февраля 2012

Оператор if и его дополнение elif работают с логическими значениями . Если переменная, или что-то еще, что проверяется, уже не является булевой, то она принудительно и понимается истинно / ложно.

Любой объект, который не равен нулю и не пуст, интерпретируется как "True". Итак, если предположить, что dec_bttn и hex_bttn являются флажками Tkinter, тогда Python проверяет логическое значение значение флажков сами и, видя, что они истинны, каждый раз выполняет первый блок if.

Где-то в вашем коде вы, вероятно, инициализируете чекбоксы Tkinter следующим образом:

self.dec_bttn = Checkbutton(root, Text='To decimal', ... )
self.hex_bttn = Checkbutton(root, Text='To hex', ... )

Вместо того, чтобы инициализировать их таким образом, у вас должны быть переменные, которые могут хранить «проверенные» состояния флажков, например:

self.dec_checked = IntVar()
self.hex_checked = IntVar()

self.dec_bttn = Checkbutton(root, Text='To decimal',
                    variable=self.dec_checked, ... )
self.hex_bttn = Checkbutton(root, Text='To hex',
                    variable=self.hex_checked, ... )

Обратите внимание на IntVar. Вот где хранится значение. Но вам не нужно использовать IntVar, вы также можете использовать BooleanVar или любой другой тип переменной Tkinter.

Но, я отвлекся, я вижу, что вы уже используете BooleanVar. Итак, большинство из этого вы уже знали. Но причина, по которой проверка self.dec_bttn не работает, заключается в том, что dec_bttn - это объект , а не просто логическое значение.

Используйте self.dec_bttn.get() в своем выражении if, чтобы проверить состояния флажков.

Ознакомьтесь с ссылкой на Tkinter для некоторых других методов, связанных с типами переменных Tkinter.

1 голос
/ 05 февраля 2012

Звучит так, как будто вы self.dec_bttn и self.hex_bttn оценили как true, вероятно потому, что, как говорит @voithos, вы должны .get() значения из объектов.

Вот совершенно исправный преобразователь двоичных строк в числа:

def binary_to_number(binary_string):
    total = 0
    for c in binary_string:
        total = total * 2 + (c == "1")
    return total

Тогда ваш код может быть таким:

def binary_to_number(binary_string):
    total = 0
    for c in binary_string:
        total = total * 2 + (c == "1")
    return total

def binary_to_decimal(binary_string):
    return str(binary_to_number(binary_string))

def binary_to_hex(binary_string):
    hex_digits = {
        10: 'a', 11: 'b',
        12: 'c', 13: 'd',
        14: 'e', 15: 'f'
    }
    tot = binary_to_number(bits)
    return str(hex_digits.get(tot, tot))

if self.dec_bttn.get():           
    self.output_disp.delete(0.0, END)
    self.output_disp.insert(0.0, binary_to_decimal(bits))

elif self.hex_bttn.get():
    self.output_disp.delete(0.0, END)
    self.output_disp.insert(0.0, binary_to_hex(bits))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...