I debated long and hard before posting this question, and I did a lot of experimenting. I just can't seem to work out an 'elegant', concise way to get done what I want done in the manner I want it done. I found it very hard to research because of the difficulty in not knowing exactly what to search for.
Again, I am writing a converter for binary, decimal and hex using Tkinter and not using any of Python's built-in math functions.
In the code I have one class, within it many methods. I have the methods to convert from binary to decimal and hex working correctly (bin_to_dec
& bin_to_hex
, respectively). I am now working on the 'from decimal' conversions. I have the dec_to_bin
method working correctly, as well. My issue is with the dec_to_hex
method. I want it to use the dec_to_bin
method to convert the string to binary first and then use the bin_to_hex
method for the final conversion. In doing this it has to overlook the lines of code that tell the 2 methods to display their results; but rather to store the results and transport them to the dec_to_hex
method.
I'm going to post the entire code except for the method that creates the Tkinter widgets:
def base_check(self):
""" Disable Checkbox that's connected with chosen Radiobutton. """
sel_radio = self.base.get()
for radio, cb in self.cb_to_radio.items():
if radio == sel_radio:
cb.configure(state = DISABLED)
else:
cb.configure(state = NORMAL)
def conv_segue(self):
""" Decides and directs towards proper conversion method.
Reading the 'convert from' radiobuttons. """
base = self.base.get()
if base == 'bin':
bits = self.input_str.get()
# test string validity
bit_list = list(bits)
ill_bits = ['2', '3', '4', '5', '6', '7', '8', '9']
for bit in bit_list:
if bit in ill_bits:
self.output_disp.delete(0.0, END)
self.output_disp.insert(0.0, "That bit string is invalid.")
break
else:
self.from_binary(self.dec_bttn, self.hex_bttn)
##
# learned here that I had to break once the match was found (if found) and that a 'for'
# loop can use an else block too
##
elif base == 'dec':
self.from_dec(self.bin_bttn, self.hex_bttn)
elif base == 'hex':
self.from_hex(self.bin_bttn, self.dec_bttn)
def from_binary(self, dec_bttn, hex_bttn):
""" Finds what base to convert to (Decimal or Hex) from binary. """
if self.dec_bttn.get():
self.bin_to_dec()
if self.hex_bttn.get():
self.bin_to_hex()
#if self.dec_bttn.get() and self.hex_bttn.get():
#(self.bin_to_dec, self.bin_to_hex)
def from_dec(self, bin_bttn, hex_bttn):
""" Finds what base to convert to (Binary or Hex) from decimal. """
if self.bin_bttn.get():
self.dec_to_bin()
if self.hex_bttn.get():
self.dec_to_hex()
def dec_to_bin(self):
""" Convert from decimal to binary. """
# get input string and convert to an integer
digits = self.input_str.get()
digits = int(digits)
bit_string = ""
# do the conversion
while digits:
bit, ans = digits%2, digits//2
bit = str(bit)
bit_string += bit
digits = ans
total = bit_string[::-1]
self.total = total
# print output
self.print_result(total)
#return total
def dec_to_hex(self):
bit_str = self.dec_to_bin().self.total
self.bit_str = bit_str
print(self.bit_str)
def bin_to_dec(self):
""" Convert from binary to decimal. """
# get input string
bits = self.input_str.get()
# set exponent
exp = len(self.input_str.get()) - 1
tot = 0
# do conversion
while exp >= 1:
for i in bits[:-1]:
if i == '1':
tot += 2**exp
elif i == '0':
tot = tot
exp -= 1
if bits[-1] == '1':
tot += 1
total = tot
# print output
self.print_result(total)
#return total
def bin_to_hex(self):
""" Convert from binary to hex. """
# get input string
bits = self.input_str.get()
# define hex digits
hex_digits = {
10: 'a', 11: 'b',
12: 'c', 13: 'd',
14: 'e', 15: 'f'
}
# add number of necessary 0's so bit string is multiple of 4
string_length = len(bits)
number_stray_bits = string_length % 4
# test if there are any 'stray bits'
if number_stray_bits > 0:
number_zeros = 4 - number_stray_bits
bits = '0'*number_zeros + bits
string_length = len(bits)
# index slicing positions
low_end = 0
high_end = 4
total = ""
# slice bit string into half byte segments
while high_end <= string_length:
exp = 3
half_byte = bits[low_end:high_end]
# do conversion
tot = 0
while exp >= 1:
for i in half_byte[:-1]:
if i == '1':
tot += 2**exp
elif i == '0':
tot = tot
exp -= 1
if half_byte[-1] == '1':
tot += 1
# check if tot needs conversion to hex digits
for i in hex_digits.keys():
if i == tot:
tot = hex_digits[i]
else:
tot = tot
# store and concatenate tot for each while iteration
tot = str(tot)
total += tot
# move right to next half byte string
low_end += 4
high_end += 4
# print the output
self.print_result(total)
#return total
def print_result(self, total):
""" display the result of conversion. """
self.output_disp.delete(0.0, END)
self.output_disp.insert(0.0, total)
I've tried to make it as easy to read for anyone who attempts to help me as possible. The dec_to_hex
method is a bit of a mess right now, I have been messing with it.
With the code posted I think its a bit more clear what exactly I'm trying to do. Its very simple code as I haven't a lot of Python experience.
Its all in one class, and I'm trying to do it without the need to copy the code from the two methods I want to use for the dec_to_hex
method (dec_to_bin
& bin_to_hex
).
I thought about breaking it into different classes and using inheritance, but I can't see where that will help me at all
My final decision to post the question now while I continue to mess with it came because I'm sure once its figured out I'm going to have learned something very important, and probably a concept or two that I don't have a complete grasp on will become clearer.
I hope someone will be willing to give me a little direction in this matter. I get an adrenalin rush when I see progress getting made. Its also very well commented and docstringed so it shouldn't be a problem for anyone.
I also thought that this would be a great situation to use some equivalent to the XHTML anchors, but then I realized they are about the same as the old goto
command from my 6th grade BASIC days and figured Python was too 'clean' to use that.
from_binary
arguments dec_bttn and hex_bttn are useless and should be removed. \$\endgroup\$