Why does my Collatz sequence code execute but show error? - python

This is my code on the Collatz sequence:
def collatz(a):
while (a != 1):
if a%2 == 0:
a = a//2
print (a, " -> ")
a = collatz(a)
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
a = collatz(a)
x = int(input("Enter a number: "))
collatz(x)
The output I get is perfect for every number I enter, but Jupyter Notebook also shows some kind of error. Am I making some kind of error in recursion? I've linked the output and error shown.
https://ibb.co/C1jCthq

You do a = collatz(a), but since your function has no return statements, this sets a to None. Then in the next iteration of the loop you try to do arithmetic on a. This fails, because you can't do arithmetic on None.
You don't really need recursion here at all. You already have a loop, so you can simply delete those collatz calls.
def collatz(a):
while (a != 1):
if a%2 == 0:
a = a//2
print (a, " -> ")
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
x = int(input("Enter a number: "))
collatz(x)
... But if you're dead-set on having recursion, you can do that too. Delete the while loop, and call collatz at the end of your function.
def collatz(a):
if a == 1:
return
if a%2 == 0:
a = a//2
elif a%2 != 0:
a = int(3*a + 1)
print (a, " -> ")
collatz(a)
The drawback of this approach is that it will crash with "maximum recursion depth exceeded" if the function recurses more than 999 times. Collatz sequences converge to 1 fairly quickly, so this probably isn't a practical problem for this specific algorithm, but it's something to keep in mind when writing any recursive function.
Both of these approaches have the potentially undesirable behavior of printing "->" after the final number in the sequence. This is a fairly common problem in this style of "print-while-iterating" code. One possible solution is to remove the print calls from the function, instead returning a list of the values of the sequence. Then you can style your output after the fact, using join to intersperse the numbers with arrows.
def collatz(a):
result = [a]
while (a != 1):
if a%2 == 0:
a = a//2
elif a%2 != 0:
a = int(3*a + 1)
result.append(a)
return result
x = int(input("Enter a number: "))
seq = collatz(x)
print(" -> ".join(str(num) for num in seq))

Related

checking next and previous indexes

I'm trying to go through each index and check if it's greater than the next index or not, but I could not come up with any idea about how to do it. I tried using range and enumerate functions, but did not work so help would be much appreciated. This is my current code:
user_input = input("Anything: ")
user_input = user_input.split(",")
arrayList = [int(i) for i in user_input]
test = []
for the_index, the_item in enumerate(arrayList):
Here is what I tried earlier than this
user_input = input("Anything: ")
user_input = user_input.split(",")
arrayList = [int(i) for i in user_input]
first_numbers = []
second_numbers = []
finalList = []
for i in arrayList:
the_index = arrayList.index(i)
if the_index % 2 != 0:
first_numbers.append(i)
if the_index % 2 == 0:
second_numbers.append(i)
first_numbers.append(second_numbers)
Not sure i got this clear but if you want to know if user's input was bigger / smaller than the previous choice, you can do this:
This may not be the shortest way to do it, but this is a dynamic snippet where you can decide ask as much as inputs you want the user to answer:
user_choice = input('Choose some numbers: ')
user_choice_listed = user_choice.split(',')
marked_choice = None # Uninitialized integer that would be assigned in the future
for t in user_choice_listed:
converted_t = int(t)
if marked_choice != None and marked_choice < converted_t:
print('{0} is Bigger than your previous choice, it was {1}'.format(t,marked_choice))
elif marked_choice != None and marked_choice > converted_t:
print('{0} is Smaller than your previous choice, it was {1}'.format(t,marked_choice))
elif marked_choice == None:
print('This is your first Choice, nothing to compare with!')
marked_choice = converted_t # this is marking the previous answer of the user
NOTE: You can add a line to handle where the previous is equal to the current choice.
OUTPUT:
Choose some numbers: 1,3,5 # My Input
This is your first Choice, nothing to compare with!
3 is Bigger than your previous choice, it was 1
5 is Bigger than your previous choice, it was 3
Loop it through the indexes?
for i in range(len(arrayList)):
if arrayList[i] > arrayList[i + 1]:
//enter code here

Asterisk Triangle in Python (using recursion)

I have seen multiple "python asterisk triangles" and their solutions, but I am stuck on creating an asterisk triangle using recursion (without a loop, which would make it much easier in my opinion.) Below is the current code I have:
def main():
num = int(input("Enter an integer: "))
triangle = draw_triangle(num)
print(triangle)
def draw_triangle(n):
if n == 0:
return
else:
return ("*" * n + '\n') + draw_triangle(n - 1)
main()
When I run the code, I receive "TypeError: must be str, not NoneType." I have done some research and still do not completely understand what this error is telling me. I apologize if this question was asked before, I was unable to find one dealing with any recursive functions. Thank you.
return to return ""
Input: 5
Output:
*****
****
***
**
*
This error occurs because you return a blank value. Try returning a blank string instead
Solution:
In line 9:
replace return with return ''
The code is working properly but there is just a slight problem.
When testing with base case i.e. if n == 0: the return must be set to something, if not it will return None. Thus after the input number reaches 0 it returns None anything that returns None is interpreted as a failed case in python so
Here is a work around:
def draw_triangle(n):
if n == 0:
return ''
else:
return ("*" * n + '\n') + draw_triangle(n - 1)
def main():
num = int(input("Enter an integer: "))
triangle = draw_triangle(num)
print(triangle)
main()
Thus after reaching n == 0 case the program will return a blank string and continue.

Function is not producing an integer, but instead producing a "none" output

The getvalidint function is explained below, as I am calling the function getvalidint and giving it a input so it may produce an integer output. It is not as I print the functions output(see below in the main program) it prints out "none", I am running on python33.
#getValidInt() takes in a minn and maxx, and gets a number from the
# user between those two numbers (inclusive)
#Input: minn and maxx, two integers
#Output: an integer, between minn and maxx inclusive
MIN_VAL = -1000000
MAX_VAL = 1000000
def getValidInt(minn, maxx):
message = "Please enter a number between " + str(minn) + " and " + \
str(maxx) + " (inclusive): "
newInt = int(input(message))
while newInt <= minn & newInt >= maxx:
# while loop exited, return the user's choice
return newInt
def main():
userNum = getValidInt(MIN_VAL, MAX_VAL)
print(userNum)
main()
If the while newInt <= minn & newInt >= maxx: condition is never met, then nothing will be returned. This means that the function will implicitly return None. Also, assuming you're using python 3 (which I induced from your int(input()) idiom).
The deeper issue is that the input code will only run once, regardless of whether or not the value meets the constraint. The typical way of doing this would be something along the lines of:
import sys
def get_int(minimum=-100000, maximum=100000):
user_input = float("inf")
while user_input > maximum or user_input < minimum:
try:
user_input = int(input("Enter a number between {} and {}: ".format(minimum, maximum)))
except ValueError:
sys.stdout.write("Invalid number. ")
return user_input

function that reverses digits, takes into consideration the sign

I've looked on the site to try and figure out how to do this but I'm still stuck.
My function is supposed to reverse digits, so reverse_digits(8765) returns 5678. This is easily done by :
def reverse_digits(num):
return int(str(num)[::-1])
However, my code needs to 1) test if it is a negative and keep it negative (so -8765 returns -5678) and 2) I think I should test to see if num is actually an int.
So far I have
def reverse_digits(num):
num = str(num)[::-1]
if num == '-':
minus = 1
num = num[:-1]
else:
minus = 0
int(num)
if minus == 1:
num = num*-1
else:
num = num
return num
It works for digits without a '-', but returns '' when it has a '-'.
I was originally trying to put the test to see if it is an int at the beginning od the loop like
if (num != int):
print("wrong type")
sys.exit()
else:
(the rest of my above code)
but that wouldn't work for me. Should I put all the code in a while loop so I can use continue/break?
Thanks!
Just don't put the - into the reversed string:
def reverse_digits(num):
return (-1 if num<0 else 1) * int(str(abs(num))[::-1])
Try to use the isdigit() string method.
def reverse_digit(num):
num_str = str(num)[::-1].strip('-')
if not num_str.isdigit():
<do what u want>
if num < 0:
return -int(num_str)
else:
return int(num_str)

Using Python, reverse an integer, and tell if palindrome

Using Python, reverse an integer and determine if it is a palindrome. Here is my definition of reverse and palindrome. Do I have a correct logic?
def reverse(num):
s=len(num)
newnum=[None]*length
for i in num:
s=s-1
newnum[s]=i
return newnum
def palindrome(num):
a=str(num)
l=len(z)/2
if a[:1]==a[-1:][::-1]:
b=True
else:
b=False
I am having some trouble to write def main.
def palindrome(num):
return str(num) == str(num)[::-1]
Integer numbers don't have len().
Testing if a number is a palindrome is as simple as testing if the number is equal to its reverse (though if you want maximum efficiency you can just compare characters from both ends of the string until you reach the middle).
To find the reverse of an integer you can either do it the hard way (using mod % and integer division // to find each digit and construct the reverse number):
def reverse(num):
rev = 0
while num > 0:
rev = (10*rev) + num%10
num //= 10
return rev
Or the easy way (turning the number into a string, using slice notation to reverse the string and turning it back to an integer):
def reverse(num):
return int(str(num)[::-1])
This is an unreadable one-line recursive implementation based in part on the answer by pedrosorio.
def reverse(i):
return int(i!=0) and ((i%10)*(10**int(math.log(i,10))) + reverse(i//10))
def is_palindrome(i):
return i == reverse(i)
It works for integer i ≥ 0.
Note that reverse(123) == reverse(1230) == 321. This is not a problem, considering any nonzero integer that ends with 0 cannot be a palindrome anyway.
Note also that complete reversal of the integer may of course not be necessary to determine if it's a palindrome. The reversal may be implemented so as to be aborted early if the number is determined to not be a palindrome.
Long but readable:
def palindrome(x):
a=""
x=str(x)
for i in range(len(x),0,-1):
a+=x[i-1]
print a
if a==x:
return True
else:
return False
Reverse an integer and determine if it is a palindrome:
Convert integer to string.
Use reverse function to reverse the string and join it.
Check if reversed number = original number with if else condition.
See code:
number = 1221
reverse = ''.join(reversed(str(number)))
print(reverse)
if (int(reverse) == number):
print("number is Palindrome")
else:
print("number is not Palindrome")
def revers(num):
rev = 0
while num > 0:
rem = num % 10
rev = (rev * 10) + rem
num = num // 10
return rev
I used a list for this program, works with strings too.
print('Enter Something')
a = list(input())
for i in range ((len(a)),0,-1):
print (a[i-1],end='')
import math
a = raw_input("Enter number:")
n = -1
reverse = 0
for i in a:
n += 1
digit = math.pow(10,n)
reverse = int(i)*digit + reverse
print int(reverse)
if int(reverse) == int(a):
print "Palindrome"
else:
print ":("
This code converts int to String and then checks if the string is pallindrome. The advantage is that it is fast, the disadvantage being that it converts int to String thereby compromising with the perfect solution to question.
It handles negative int as well.
class Solution:
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
s = str(x)
if x >=0 :
if s == s[::-1]:
return True
else:
return False
else:
return False
t=int(input("enter nos of test cases= "))
while t>0:
n=int(input("enter number="))
rev=0
while n>0:
digit=n%10
rev=rev*10+digit
n=n//10
print(rev)
t-=1
Here is my solution.
z=input('input number')
if int(z) == int(str(z)[::-1]):
print('The number is palindrome')
else:
print('The number is not palindrome')
def pal_num(num):
if num<0:
print(False)
elif num == int(str(num)[::-1]):
print(True)
else:
print(False)
This example quickly takes care of the negative number edge case
I try to come out with this myself.
def number():
n = int(input("Enter a number: "))
return n
def reverse(n):
total = ""
while n > 0:
a = n % 10
n//= 10
total+= str(a)
return total
def palindrome (n):
total = 0
while n > 0:
a = n % 10
n//= 10
total+= a
if total == n:
x = "This number has a palindrome"
else:
x = ""
return x
n = number()
print (reverse(n))
print (palindrome(n))
original = raw_input("Enter a no = ") #original = number entered by user
rev = original[::-1] #rev = reverse of original by useing scope resolution
print 'rev of original no =',rev
if original == rev:
print "no's are equal"
else:
print "no's are not equal"

Categories

Resources