python function project, histo function that return o - python-3.3

histogram(xs): Given a list of integers named xs, return a string which, when printed, shows a histogram corresponding to the integers. Use small "o" as the display symbol.
Assume: xs is a list of non-negative integers; xs could be empty.
Restrictions: none currently stated.
histogram([3,10,0,5]) → 'ooo\noooooooooo\n\nooooo'
histogram([]) → ''
This is what I tried:
def histogram(xs):
last = len(xs)
histo = ''
for number in xs:
while number > 0:
histo += 'o'
number -= 1
last -= 1
if last == 0:
if histo == None:
return ''
return histo
histo += '\n'

I may have had your indentation wrong when I edited your question. I had to guess because I was pulling it out of the comment. Also, you might have had an indentation problem. Anyways, this seems to work (It's your original code with proper indentation):
def histogram(xs):
last = len(xs)
histo = ''
for number in xs:
while number > 0:
histo += 'o'
number -= 1
last -= 1
if last == 0:
if histo == None:
return ''
return histo
histo += '\n'
Here's a more compact solution:
def histogram(xs):
output = ""
for number in xs:
output += "o" * number + "\n"
return output

Related

Why does my number reverser function produce an infinite loop

Whenever i try print the number reverser function i always get an infinite loop,instead of my expected output 54321. Can someone help find the problem? Thanks.
def order(num):
x=str(num)
if x==False:
return None
else:
return order(x[1:])+(x[0])
print (order(12345))
Welcome to your community.
There are some problems with your code:
First:
A string never will be equal to False.
for instance:
'0' is not equal to False.
'' is not equal to False.
Second:
You cannot add a String to None.
This Error will be thrown: TypeError: can only concatenate str (not "NoneType") to str
Modify your code like this:
def order(num):
x=str(num)
if x=='':
return ''
else:
return order(x[1:])+(x[0])
print (order(12345))
Tip 1: A string can be equal to '' (empty string).
In your function, you compare the string x with the boolean False. This is not a correct way to test whether string x is an empty string or not.
In addition, if string x is empty, then you shouldn't return None, but an empty string: reversing an empty string should logically return an empty string.
Here I present two ways to fix your function, which I implemented under the names reverse0 and reverse1. I also present a few other alternatives to achieve the same result using python features, under the names reverse2 to reverse6. Finally I present three other ways to reverse nonnegative integers, under the names reverse7 to reverse9.
def reverse0(num):
x = str(num)
if len(x) == 0:
return ''
else:
return reverse0(x[1:]) + x[0]
def reverse1(num):
x = str(num)
if not x:
return ''
else:
return reverse1(x[1:]) + x[0]
def reverse2(num):
return str(num)[::-1]
def reverse3(num):
return ''.join(reversed(str(num)))
def reverse4(num):
x = str(num)
return ''.join(x[len(x)-1-i] for i in range(len(x)))
def reverse5(num):
x = str(num)
return ''.join(x[-i] for i in range(1, len(x)+1))
def reverse6(num):
y = ''
for c in str(num):
y = c + y
return y
# reverse7 only works for nonnegative integers
def reverse7(num):
if num < 10:
return str(num)
else:
return str(num % 10) + reverse7(num // 10)
# reverse8 only works for nonnegative integers
def reverse8(num):
l = []
while num > 9:
l.append(num % 10)
num = num // 10
l.append(num)
return ''.join(str(d) for d in l)
# reverse9 only works for nonnegative integers
# reverse9 returns an int, not an str
def reverse9(num):
y = 0
while num > 0:
y = 10 * y + (num % 10)
num = num // 10
return y
Relevant documentation:
builtin reversed;
str.join;
An informal introduction to string slices such as x[::-1].

Appending results from a list to a string

Heavy python beginner here. I want to create a simple function for a PIN guessing game that receives two 4-digit lists ( [guess], [answer] ) and returns a string with 4 letters stating how close I am to guessing the correct [answer] sequence (eg. Higher, True, Lower, Higher)
However, I get a new list for each string:
def checkNumbers(guess,right):
for n in range(4):
result = []
if guess[n] == right[n]:
result.append("T") #true
elif guess[n] < right[n]:
result.append("H") #higher
elif guess[n] > right[n]:
result.append("L") #lower
else:
result.append("F") #false
print (result)
return
checkNumbers([1,2,3,5],[2,2,1,6])
The result should look like this:
checkNumbers([1,2,3,4], [2, 2, 1 , 6]) #call function with ([guess], [answer])
'HTLH' #returns a string stating how accurate [guess] is to [answer] list
Result looks like this however:
checkNumbers([1,2,3,5],[2,2,1,6])
['H']
['T']
['L']
['H']
Thanks very much in advance for any help I could get.
you can use string instead of list or "".join()
def checkNumbers(guess, right):
result = ""
for n in range(4):
if guess[n] == right[n]:
result += "T" # true
elif guess[n] < right[n]:
result += "H" # higher
elif guess[n] > right[n]:
result += "L" # lower
else:
result += "F" # false
print(result)
but... maybe you want to use zip function
def checkNumbers(guess, right):
result = ""
for g, r in zip(guess, right):
if g == r:
result += "T" # true
elif g < r:
result += "H" # higher
elif g > r:
result += "L" # lower
else:
result += "F" # false
print(result)
Funny bonus here:
def checkNumbers(guess, right):
print("".join("THL"[(g > r) + (g != r)] for g, r in zip(guess, right)))
I don't get why you need else part...
Initiate the list and print the result outside of the loop:
def checkNumbers(guess, right):
result = []
for n in range(4):
# do loopy stuff
print (result)
return # not strictly necessary
If you do it inside, you are creating a new list on every iteration.

Finding the logical error in my code to get first 50 primes

I'm trying to write my own formula to find a prime number, but it does not completely work and I cannot find the flaw in my logic. Bare in mind I have taken a look around but cannot find an algorithm that I find similar to mine.
My code:
#Challenge 7
prime = []
num = 0
found = False
while found == False:
if num == 0 or num == 1:
num+=1
else:
for value in range(2, num+1):
if len(prime) == 50:
print('Found all')
found = True
break
if num % value == 0:
num+=1
else:
if num not in prime:
prime.append(num)
else:
pass
print(prime)
This code works for first few primes (3, 5, 7...)
but it also gives incorrect values like 10, and I don't understand why. If someone could explain it to me so that I can understand where the logical mistake is, I'd appreciate it.
The error comes from this part
if num % value == 0:
num+=1
else:
if num not in prime:
prime.append(num)
else:
pass
You assume that the integer is a prime as soon as we find the first occurence of a non-divisor. But the def for primes is that every integer in the interval [2..prime] is a non-divisor. How do we check if any number does not have any divisors?
def isPrime(x):
for v in range(2, x):
if (x % v == 0):
return False;
return True;
Something like this would work to check if any given number is a prime or not. And since we now have taken the isPrime part out of the main loop, we no longer need a for loop inside the while. Something like this would do
def isPrime(x):
for v in range(2, x):
if (x % v == 0):
return False;
return True;
prime = [}
num = 2
found = False
while found == False:
if len(prime) == 50:
print("found all")
found = True
break
if(isPrime(num)):
print(num)
prime.append(num)
num+=1
else:
num+=1
If you set a breakpoint for when num == 10 you will see the problem clearly.
When you start doing you division check inside of for value in range(2, num + 1): the second number is 3, so num (10) modulo value (3) is 1, which is your test for determining a prime. What your test should be is that it not divisible by any number less than it (less than half is actually sufficient since you check with 2 anyway).
So, consider instead:
else:
is_indivisible = True
# loop through all numbers less than it not including itself
# (because x % x == 0)
for value in range(2, num - 1):
# it is only indivisible if it was previously indivisible
# And the check is same as before, modulo != 0
is_indivisible = is_indivisible and (num % value != 0)
if not is_indivisible:
break
# if it is indivisible and it doesn't exist in prime list yet
if is_indivisible and num not in prime:
prime.append(num)
# move on to the next number
num += 1

Using Recursive Functions in Python to find Factors of a Given Number

Have tried searching for this, but can't find exactly what I'm looking for.
I want to make a function that will recursively find the factors of a number; for example, the factors of 12 are 1, 2, 3, 4, 6 & 12.
I can write this fairly simply using a for loop with an if statement:
#a function to find the factors of a given number
def print_factors(x):
print ("The factors of %s are:" % number)
for i in range(1, x + 1):
if number % i == 0: #if the number divided by i is zero, then i is a factor of that number
print (i)
number = int(input("Enter a number: "))
print (print_factors(number))
However, when I try to change it to a recursive function, I am getting just a loop of the "The factors of x are:" statement. This is what I currently have:
#uses recursive function to print all the letters of an integer
def print_factors(x): #function to print factors of the number with the argument n
print ("The factors of %s are:" % number)
while print_factors(x) != 0: #to break the recursion loop
for i in range(1,x + 1):
if x % i == 0:
print (i)
number = int(input("Enter a number: "))
print_factors(number)
The error must be coming in either when I am calling the function again, or to do with the while loop (as far as I understand, you need a while loop in a recursive function, in order to break it?)
There are quite many problems with your recursive approach. In fact its not recursive at all.
1) Your function doesn't return anything but your while loop has a comparision while print_factors(x) != 0:
2) Even if your function was returning a value, it would never get to the point of evaluating it and comparing due to the way you have coded.
You are constantly calling your function with the same parameter over and over which is why you are getting a loop of print statements.
In a recursive approach, you define a problem in terms of a simpler version of itself.
And you need a base case to break out of recursive function, not a while loop.
Here is a very naive recursive approach.
def factors(x,i):
if i==0:
return
if x%i == 0:
print(i)
return factors (x,i-1) #simpler version of the problem
factors(12,12)
I think we do using below method:
def findfactor(n):
factorizeDict
def factorize(acc, x):
if(n%x == 0 and n/x >= x):
if(n/x > x):
acc += [x, n//x]
return factorize(acc, x+1)
else:
acc += [x]
return acc
elif(n%x != 0):
return factorize(acc, x+1)
else:
return acc
return factorize(list(), 1)
def factors(x,i=None) :
if i is None :
print('the factors of %s are : ' %x)
print(x,end=' ')
i = int(x/2)
if i == 0 :
return
if x % i == 0 :
print(i,end=' ')
return factors(x,i-1)
num1 = int(input('enter number : '))
print(factors(num1))
Recursion is a functional heritage and so using it with functional style yields the best results. This means avoiding things like mutations, variable reassignments, and other side effects. That said, here's how I'd write factors -
def factors(n, m = 2):
if m >= n:
return
if n % m == 0:
yield m
yield from factors(n, m + 1)
print(list(factors(10))) # [2,5]
print(list(factors(24))) # [2,3,4,6,8,12]
print(list(factors(99))) # [3,9,11,33]
And here's prime_factors -
def prime_factors(n, m = 2):
if m > n:
return
elif n % m == 0:
yield m
yield from prime_factors(n // m, m)
else:
yield from prime_factors(n, m + 1)
print(list(prime_factors(10))) # [2,5]
print(list(prime_factors(24))) # [2,2,2,3]
print(list(prime_factors(99))) # [3,3,11]
def fact (n , a = 2):
if n <= a :
return n
elif n % a != 0 :
return fact(n , a + 1 )
elif n % a == 0:
return str(a) + f" * {str(fact(n / a , a ))}"
Here is another way. The 'x' is the number you want to find the factors of. The 'c = 1' is used as a counter, using it we'll divide your number by 1, then by 2, all the way up to and including your nubmer, and if the modular returns a 0, then we know that number is a factor, so we print it out.
def factors (x,c=1):
if c == x: return x
else:
if x%c == 0: print(c)
return factors(x,c+1)

How to fix "maximum recursion depth exceeded" error in python code?

While I was running the code, I got a "maximum recursion depth exceeded in comparison" error. I'm not exactly sure which part of the code to look at to fix this problem. This numToBinary function is basically supposed to convert a number n to a binary number with bit size k. I would greatly appreciate any input on how I can resolve this issue!
def numToBinary(k, n):
''' converts number to binary number bit size k'''
def binary(n):
if n == 0:
return ''
elif n%2 == 1:
return binary(n/2)+'1'
else:
return binary(n/2)+ '0'
temp = binary(n)
if len(temp) <= k:
answer = '0' * (k - len(temp)) + temp
elif len(temp) > k:
answer = temp[-k:]
return answer
print (numToBinary(6, 10))
You need floor division, double /, in python3 / does truediv so you are getting floats from n/2:
def binary(n):
if n == 0:
return ''
elif n%2 == 1:
return binary(n//2) + '1' # // floor
else:
return binary(n//2)+ '0' # // floor
Once you make the change, it will work fine:
In [50]: numToBinary(6, 10)
Out[50]: '001010'
You can also use else in place of the elif, if the len of temp is not <= then it has to be greater than:
def numToBinary(k, n):
''' converts number to binary number bit size k'''
def binary(n):
if n == 0:
return ''
elif n % 2 == 1:
return binary(n//2)+'1'
else:
return binary(n//2) + '0'
temp = binary(n)
if len(temp) <= k:
answer = '0' * (k - len(temp)) + temp
else:
answer = temp[-k:]
return answer
If you wanted to see exactly what was happening you should put a print in you own code, if you added a print(n) in binary you would see a lot of output like:
5.125332723668738e-143
2.562666361834369e-143
1.2813331809171846e-143
6.406665904585923e-144
3.2033329522929615e-144
Which meant you eventually hit the recursion limit.

Resources