def toBinary(decimal, binaryList):
if decimal <= 1:
return binaryList
else:
decimal = decimal //2
return toBinary(decimal, binaryList)
binaryList.append(decimal %2)
The functions returns empty brackets instead of printing the binary number as a list.
Your code is on the right track but has issues. First is what #KlausD comments, no line directly after a return gets executed. So the order of statements is at issue. Next, the variable binaryList doesn't get initialized in your provided code fragment. It could get initialized by the caller:
array = toBinary(13, []):
which works, but the caller might find it strange. We could intialize it using a default:
def toBinary(13, binaryList=[]):
But as a container type, that would constitute a dangerous default which we want to steer clear of. We could safely initialize it to None as a default and reinitialize it later in the code:
def toBinary(decimal, binaryList=None):
# ...
if binaryList is None:
binaryList = []
Which is safe and hides this argument from the caller. Next, by dividing, we're analyzing our decimal digits from right to left, so we need to build up our binary number in the same direction, thus append():
binaryList.append(decimal % 2)
is a problem as it builds up the binary result from left to right. We could end with a revese() but it's probably better to use binaryList.insert(0, ...) to build in the proper direction. Finally, this is a special case:
array = toBinary(0)
as we're going to use a zero argument to trigger end of recursion but how it affects our result (i.e. not at all) is different than if we're passed zero from the get-go (i.e. return a [0]). Here's my rework of your code that addresses all of these issues:
def toBinary(decimal, binaryList=None):
if decimal == 0:
return binaryList or [0]
if binaryList is None:
binaryList = []
binaryList.insert(0, decimal % 2)
return toBinary(decimal // 2, binaryList)
print(toBinary(13))
OUTPUT
> python3 test.py
[1, 1, 0, 1]
>
It is better not to return binary list.
def toBinary(decimal, binaryList):
if decimal <= 0:
return
else:
toBinary(decimal//2, binaryList)
binaryList.append(decimal %2)
This code also converts to Binary. It can also convert into other bases. Just change the parameter base, to the base you want.
import string
def to_base(value, base=2): # converts decimal to base n
string_slice = string.printable[0:base]
data_dict = {}
for each_character, each_number in zip(string_slice, range(base)):
data_dict.update({each_character: each_number})
data = []
temporary_var = value
data.append(temporary_var)
while True:
temporary_var = temporary_var // base
data.append(temporary_var)
if temporary_var < base:
break
else:
continue
result = ''
for each_data in data:
result += list(data_dict.keys())[each_data % base]
result = result[::-1]
return result by
My code may not be perfect. Feel free to suggest improvements.
print(to_base(5, base=2)) # Outputs : 101. Because 101 is 5 in binary
print(to_base(17, base=16)) # Outputs : 11. Because 11 is 17 in hexadecimal
Related
I've been at this for hours and hours. I think my problem is I need to use a return in my first function so that I can use this function as an argument in my second function. However, it seems that if I use a return, the data is somehow not being passed properly to the second function. I say that because I can't seem to format it properly if i comment out my print statement and only use a return (the return statement won't let me include the end = '' so it comes out vertically instead). Then the second function just spits out the first digit of my first function's return. I'm so lost and i need to get some sleep now I guess. Been up all night with this. Is there some way I can return the data int he first function and make it be a nice horizontal string like it would be if I used my print statement instead? (Or does that not matter and I'm way off track?) Please let me know if I can clarify something. Just a nudge in the right direction would help.
Instructions: Write a program that takes in a positive integer as
input, and outputs a string of 1's and 0's representing the integer in
binary. For an integer x, the algorithm is:
As long as x is greater than 0
Output x % 2 (remainder is either 0 or 1)
x = x // 2
Note: The above algorithm outputs the 0's and 1's
in reverse order. You will need to write a second function to reverse
the string.
Ex: If the input is:6
the output is:
110
The program must define and call the following two functions.
Define a function named int_to_reverse_binary() that takes an integer
as a parameter and returns a string of 1's and 0's representing the
integer in binary (in reverse).
Define a function named
string_reverse() that takes an input string as a parameter and returns
a string representing the input string in reverse. def
int_to_reverse_binary(integer_value) def string_reverse(input_string)
My code:
Define your functions here.
def int_to_reverse_binary(int_number):
while int_number > 0:
#print (int_number % 2, end='')
return int_number % 2
int_number = int_number // 2
def string_reverse(input_string):
for i in reversed(str(input_string)):
print(i,end='')
if __name__ == '__main__':
# Type your code here.
# Your code must call int_to_reverse_binary() to get
# the binary string of an integer in a reverse order.
# Then call string_reverse() to reverse the string
# returned from int_to_reverse_binary().
x = int(input())
int_to_reverse_binary(x)
string_reverse(int_to_reverse_binary(x))
1: Compare output
0 / 2
Output differs. See highlights below.
Input
6
Your output
0
Expected output
110
2: Unit test
0 / 2
Convert 19 to binary using int_to_reverse_binary() and string_reverse()
Your output
1
Test feedback
string_reverse(user_input) did not return a value.
Your function may be missing a return statement.
3: Unit test
0 / 3
Convert 255 to binary using int_to_reverse_binary() and string_reverse()
Your output
1
Test feedback
string_reverse(user_input) did not return a value.
Your function may be missing a return statement.
The return statement in Python also acts as the ending point of the function. i.e. no statement will be executed once a return statement is encountered in a function. So, when the while loop is being executed, the interpreter sees a return statement and stops executing any further. If you wish to return multiple values from the function you can do 2 things,
Instead of using a while loop in s function, use the function in the while loop:
Sample Code:
def foo(num):
return num % 2
i = 0
while i< 10:
print(foo(i))
i += 1
Use a list to return all values at once. Sample Code:
def foo(num):
a = []
i = 0
while i < num:
a.append(i)
i+=1
print(foo(10))
Code With corrections:
def int_to_reverse_binary(int_number):
# print('i', int_number)
a = []
while int_number > 0:
a.append(int_number % 2)
int_number = int_number // 2
# print('a', a)
return a
def string_reverse(input_string):
print(''.join([str(i) for i in input_string])[::-1])
if __name__ == '__main__':
x = int(input())
# a = int_to_reverse_binary(x)
string_reverse(int_to_reverse_binary(x))
You seem to have made this unnecessarily complex. f-string formatting will give you the binary representation of your integer then reverse the string with a slice as follows:
def int_to_reverse_binary(int_number):
return f'{int_number:b}'[::-1]
print(int_to_reverse_binary(100))
Output:
0010011
I've tried to write a simple function, which input is binary number in string format and converts binary to decimal. But in the output I always get the wrong thing: the 'res' value in line 3, no matter what the input is ('1010', '10010111010', etc.). Also, I've tried to debug the code and the function doesn't even start the loop, as if it wasn't there... So, I just don't see my mistake
def bin_to_dec(bin):
bin = bin[::-1]
res = 0
for i in range(len(bin)):
if bin[i] == 0:
res += 2**i
return res
You are comparing the string "0" to the number 0 and they are, trivially, unequal.
So, contrary to what you say, the loop is actually looping; but the if statement will never be true.
Of course, also, you should probably add when the number is 1, not when it's 0.
def bin_to_dec(bin):
bin = bin[::-1]
res = 0
for i in range(len(bin)):
if int(bin[i]) == 1:
res += 2**i
return res
Notice the addition of int().
if bin[i] == '1'
This will correct the problem. bin[i] is a character and you are comparing it to a number which always results in false.
You can just use the built in int function:
def binaryToDecimal(n):
return int(n,2)
I have a list of octal numbers that I want to be converted to decimal. Here's my class with what I've done so far:
class Octal:
#Reads in the file into numberList, converting each line into an int.
def __init__(self):
list = []
file = open("Number Lists/random_numbers3.txt")
for line in file:
list.append(int(line))
self.numberList = list
file.close()
#Convert numberList to decimal
def dec_convert(self):
decimal = 0
decimalList = []
for line in self.numberList:
temp = str(line)
i = 0
while i < len(temp):
digit = int(temp[i])
item = (digit * (8 ** (len(temp) - i)))
decimal = decimal + item
i += 1
decimalList.append(decimal)
return decimalList
def get_list(self):
return self.numberList
I read in the numbers from a file, that works fine. But I don't think that my dec_convert() function actually works. It just keeps running and doesn't finish.
It looks completely terrible and hard to read, so I was wondering if there was a simpler way of converting each octal number in the list to a decimal number?
Here is an easy solution that uses the built-in int() constructor rather your dec_convert() function.
class Octal:
def __init__(self):
with open("Number Lists/random_numbers3.txt") as fp:
self.numberList = map(lambda x:int(x,8), fp)
def get_list(self):
return self.numberList
if __name__=="__main__":
o = Octal()
print(o.get_list())
Yes, you could use list comprehension:
def dec_convert(self):
decimalList = [self._convert_to_dec(line) for line in self.numberList]
and with:
def _convert_to_dec(self,dec) :
n = len(temp)-1
return sum(int(x)*(8**(n-i)) for i,x in enumerate(dec))
The first code fragment is a simple list comprehension that calls self._convert_to_dec on all elements in `self.numberList. Not much magic there.
The _convert_to_dec is more complicated: we first calculate the amount of digits and store it in n. Next we define a generator that enumerates over the characters and binds i to the corresponding index. The generator multiplies each element with the corresponding power of 8 and the digit. This is a generator, so no real list is constructed.
By running this through sum we obtain the sum which is the requested result.
Or as #TomKarzes says, you can use int with a given base (in this case 8.
How would you recursively or iteratively change a decimal to hexadecimal?
I wrote a sample program that does not really work:
def ChangeHex(n):
if (n < 0):
print(0)
elif (n<=1):
print(n)
else:
ChangeHex(n / 16)
if (n == 15):
print("F")
if (n == 14):
print("E")
if (n == 13):
print("D")
if (n == 12):
print("C")
if (n == 11):
print("B")
if (n == 10):
print("A")
n % 16
How would I make it work properly? I know there is a built in function but I want to do it this way.
# Converts a decimal number to hexadecimal.
# Executes a zero-fill for up to six digits.
# This is used for correct conversion back
# to the instruction format. See zero_fill().
# #param dec Decimal representation of instruction
# #return Zero-filled hexadecimal instruction.
def convert(dec):
# BEGIN convert()
hex = "%X" % dec
return zero_fill(hex, 6)
# END convert()
# Prepends zeros until the specified
# length is reached. Works recursively.
# #param n Number to fill
# #param length Length to reach
# #return Zero-filled number
def zero_fill(n, length):
# BEGIN zero_fill()
# Check if length requirement is met
if len(n) != length:
# Requirement not met, run function again with
# n having one prepended zero.
return zero_fill('0'+n, length)
else:
# Requirement met, return n.
return n
# END zero_fill()
The main reason your program is not "working" is because you're misusing functions and immutable objects. Numbers objects are immutable, which means that you can't change the value of a number object in Python, you need to return a new number. And when you're doing ChangeHex(n), you passing the value of n (i.e. the number object) to the function - it doesn't know that there is a variable that was associated with this number. And thus, when you change a local variable like n, the the variable in the caller doesn't change.
You'd like the function to return a new value, not to try to change the one that's passed (which is not really possible). Look up the return statement, and use the value of ChangeHex(n). Hints:
result += ChangeHex(n)
return result
Probably you want to return what you're printing, but I can't really tell.
The same applies to operations. Since the numbers are immutable, an operations on numbers can't change the number, and you need to assign the number to a variable. n % 16 does nothing, you need assignment, like n = n % 16 or n %= 16.
I've just started exploring the wonders of programming. I'm trying to write a code to identify numeric palindromes. Just looking at numbers and not texts. I'm trying to learn to use recursion here. But I'm just not getting anywhere and I can't figure out what's wrong with it.
My idea was to check first string vs the last, then delete these two if they match, and repeat. Eventually there'll be nothing left (implying it is a palindrome) or there will be a couple that doesn't match (implying the reverse).
I know there are better codes to finding palindromes in but I just wanted to try my hand at recursion.
So what's wrong?
def f(n):
global li
li=list(str(n))
if (len(li)==(1 or 0)):
return True
elif li[len(li)-1]==li[0]:
del li[0]
del li[len(li)-1]
if len(li)==0:
return True
if len(li)>0:
global x
x=''.join(li)
str(x)
f(x)
else:
return False
Thanks in advance!
A few comments
Why are x and li globals? In recursion, all variables should be local.
Why are you converting back and forth between str and list? You can subscript both of them
You need to return the result of your recursive call: return f(x)
Try these suggestions, and see how it works out.
Before looking into it too much, if (len(li)==(1 or 0)): doesn't do what you're expecting it to do. (1 or 0) will always evaluate to 1.
You probably want:
if len(li) in (1, 0):
There are a couple of problems with your solution. Let me analyse them line by line.
You don't need global statements if you don't intend to change variables outside of function scope. Thus, I removed two lines with global from your code.
li=list(str(n)): casting a string to a list is unnecessary, as a string in Python has a similar interface to an immutable list. So a simple li = str(n) will suffice.
if (len(li)==(1 or 0)):: although it looks OK, it is in fact an incorrect way to compare a value to a few other values. The or operator returns the first "true" value from its left or right operand, so in this case it always returns 1. Instead, you can use the in operator, which checks whether the left operand is an element of a right operand. If we make the right operand a tuple (1, 0), all will be well. Furthermore, you don't need parentheses around the if statement. You should write: if len(li) in (1, 0):
elif li[len(li)-1]==li[0]: is fine, but we can write this shorter in Python, because it supports negative list indexing: elif li[-1] == li[0]:
Because we don't use lists (mutable sequences) because of point 2., we can't do del li[0] on them. And anyway, removing the first element of a list is very inefficient in Python (the whole list must be copied). From the very same reason, we can't do del li[len(li)-1]. Instead, we can use the "splicing" operator to extract a substring from the string: li = li[1:-1]
if len(li)==0: is unnecessary long. In Python, empty strings and lists resolve to False if tested by an if. So you can write if not li:
if len(li)>0:: You don't have to check again if li is not empty -- you checked it in point 6. So a simple else: would suffice. Or even better, remove this line completely and unindent the rest of the function, because the body of the if in 6. contains a return. So if we didn't enter the if, we are in the else without writing it at all.
x=''.join(li): We don't need to convert our string to a string, because of the decision made in 2. Remove this line.
str(x): This line didn't do anything useful in your code, because str() doesn't modify its argument in place, but returns a new value (so x = str(x) would have more sense). You can also remove it.
f(x): This is a valid way to call a recursive function in Python, but you have to do something with its value. Return it perhaps? We'll change it to: return f(li) (as we don't have an x variable any more).
We end up with the following code:
def f(n):
li = str(n)
if len(li) in (1, 0):
return True
elif li[-1] == li[0]:
li = li[1:-1]
if not li:
return True
return f(li)
else:
return False
It's almost what we need, but still a little refinement can be made. If you look at the lines if not li: return True, you'll see that they are not necessary. If we remove them, then f will be called with an empty string as the argument, len(li) will equal 0 and True will be returned anyway. So we'll go ahead and remove these lines:
def f(n):
li = str(n)
if len(li) in (1, 0):
return True
elif li[-1] == li[0]:
li = li[1:-1]
return f(li)
else:
return False
And that's it! Good luck on your way to becoming a successful programmer!
Split the whole show out into a list, then just:
def fun(yourList):
if yourList.pop(0) == yourList.pop(-1):
if len(yourList) < 2:
return True # We're a palindrome
else:
return fun(yourList)
else:
return False # We're not a palindrome
print "1234321"
print fun(list("1234321")) # True
print "6234321"
print fun(list("6234321")) # False
def palindrome(n):
return n == n[::-1]
It's hard to tell what you intend to do from your code, but I wrote a simpler (also recursive) example that might make it easier for you to understand:
def is_palindrome(num):
s = str(num)
if s[0] != s[-1]:
return False
elif not s[1:-1]:
return True
else:
return is_palindrome(int(s[1:-1]))
number = int(raw_input("Enter a number: "))
rev = 0
neg = number
original = number
if (number < 0):
number = number * -1
else:
number = number
while ( number > 0 ):
k = number % 10
number = number / 10
rev = k + ( rev * 10 )
if (number < 1):
break
if ( neg < 0 ):
rev = ( rev * -1)
else:
rev = (rev)
if ( rev == original):
print "The number you entered is a palindrome number"
else:
print "The number you entered is not a palindrome number"
This code even works for the negative numbers i am new to programming in case of any errors
dont mind.