Python script "generating" "None" values - python

So I have been having this issue with a simple python script I'm working on for an assignment. I am to make a small script simulating a lottery, and have written this code:
import random
def drawNumbers(nlist, n):
drawnlist = []
i = 0
while i < n:
if i == 0:
drawnlist.append(nlist[random.randint(0,33)])
i+=1
else:
r = random.randint(0,33)
dup = False
for x in drawnlist:
if x == r:
dup = True
if dup == False:
drawnlist.append(nlist[r])
i+=1
return drawnlist
def compList(drawlist, guesslist):
count = 0
for j in drawlist:
for h in guesslist:
if j == h:
count +=1
return count
def winnings(right, altright):
altcorrect = False
if altright > 0:
altcorrect = True
if right == 7:
return 2749455
elif right == 6:
if altcorrect:
return 102110
else:
return 3385
elif right == 5:
return 95
elif right == 4:
if altcorrect:
return 45
else:
return 0
a=0
tot = 0
while a <100:
numbers = []
i = 1
while i <= 34:
numbers.append(i)
i+=1
myGuess = []
i = 0
while i <7:
if i == 0:
myGuess.append(random.randint(1,34))
i+=1
else:
r = random.randint(1,34)
dup = False
for x in myGuess:
if x == r:
dup = True
if dup == False:
myGuess.append(r)
i+=1
tot += winnings(compList(drawNumbers(numbers,7),myGuess),compList(drawNumbers(numbers,3),myGuess))
a+=1
print(tot)
And it seems to be working fine for one iteration, however, when I increase a like now with a value of 100, I get an error saying that I cannot sum an "int" object and a "None" objects. When I tinkered with the code and printed "winnings" instead of the summed total for each iteration, it looks like the function sometimes returns "None" instead of a number. I can however not seem to recreate that with a smaller amount of iterations, so my question: Is this code related, or might it be that by calling the functions "too fast" it does not create a number? I know this question might seem odd, but I am new to programming as a whole and python itself, and I have no clue how to debug this.

The winnings function can return None as there is no else to the inner if. In this case, it does not trigger the final else and returns None by default. To fix it, add an else to the if, or just remove the final else in winnings:
def winnings(right, altright):
altcorrect = False
# ...
elif right == 4:
if altcorrect:
return 45
# maybe add an else here?
# or if you get to this point, _always_ return 0
return 0

Your winnings function sometimes returns None. It's because it's not catching some cases. Python returns None if it reaches the end of a function without any other returns being hit.
Specifically, if right is 4 and altright is 0, none of the if cases will get caught and the function returns None.

Related

Code not entering if statement with valid statement and not exiting while loop

I'm trying to see if the Collatz Conjecture is really true, it says that every integer number which is divided per 2 if it's even and multiplied by 3 and added 1 if it's odd, will eventually come to a loop of 4, 2, 1. But it gets stuck in a while loop and doesn't break or gets inside the if statement that I want
integers = [5]
#Returns true if a number is even and false if it's odd
def even(num):
if (num % 2 == 0):
return True
else:
return False
#Returns true if a list of a number is in a loop
def loop(numbers):
for x in numbers:
if (numbers.count(x) > 1 or 4 in x == True):
return True
break
else:
return False
continue
#Print a list of numbers that agree with the Collatz conjecture
def collatz(list):
for x in list:
collatz_nums = []
l = loop(collatz_nums)
list.append(list[-1] + 1)
#Add the first number to the "collatz_nums" list
if (even(x) == True):
collatz_nums.append(x / 2)
elif (even(x) == False):
collatz_nums.append(x * 3 + 1)
#Adds numbers to the collatz_nums variable
while (l != True):
print("Start")
if (l == False):
if (even(collatz_nums[-1]) == True):
collatz_nums.append(collatz_nums[-1] / 2)
print("/2")
else:
collatz_nums.append(collatz_nums[-1] * 3 + 1)
print("*3+1")
else:
print("Exit")
break
print(F'{x} = {collatz_nums}')
collatz(integers)
Let's start here
collatz_nums = []
l = loop(collatz_nums)
You're passing an empty list to a function with only return statements in the event that you have data to loop over, so the function returns, setting l = None
Now while (None!=True) is an infinite loop since you're never modifiying value of l
Perhaps you should move the "add first number" if statements (which really only need to call even function once using if-else) above those two lines? Or above for x in list so that you only add the first number once?
I'd also recommend removing 4 in x == True since I doubt that does what you want

My function does not return anything no matter what I try

def iq_test(numbers):
i = 0
length = len(numbers)
numbers = numbers.split()
ints = []
even = []
odd = []
try:
for i in range(i, length, i + 1):
number = int(numbers[i])
ints.append(number)
if ints[i] % 2 == 0:
even.append(ints[i])
else:
odd.append(ints[i])
except:
pass
if len(even) > len(odd):
return i
else:
return i
iq_test("1 2 2")
No matter how many times or ways I try to fix this it doesn't seem to return i. Whenever I do print(i) it gives me the exact thing I wanted and the function works well, but when it's return i I get nothing, how can I fix this?
Edit: this function is supposed to take in some numbers (in string format), one of those numbers will be different in evenness (one is even and the rest are odd and vice versa), I want to return the index of that number.
I have modified your code and it's working :
def iq_test(numbers):
i = 0
numbers = list(map(int,numbers.split()))
even = []
odd = []
try:
for i in range(len(numbers)):
if numbers[i] % 2 == 0:
even.append(i)
else:
odd.append(i)
except:
pass
finally:
if len(even) > len(odd):
return odd[0]
else:
return even[0]
print(iq_test("1 1 2"))
Points I have modified :
instead of creating another list for converting list elements to an integer you could just use the map function
you should store the index of the even and odd value instead of the value itself
And if there is something in the code that is necessary to do even if the error occurs you could use the finally block
def iq_test(numbers):
numbers = numbers.split()
length = len(numbers)
ints = []
even = []
odd = []
try:
for i in range(0, length):
number = int(numbers[i])
ints.append(number)
if ints[i] % 2 == 0:
even.append(ints[i])
else:
odd.append(ints[i])
if len(even) > len(odd):
return even[0]
else:
return odd[0]
except:
pass
ReturnedNumber = iq_test("1 2 2")
print("Returned number from function:",ReturnedNumber)

I've written a code to check if a number is prime, but doesnt work [duplicate]

For context, I am trying to solve Project Euler problem 3 using Python:
What is the largest prime factor of the number 600851475143?
As a first step to this, I am trying to write a function that returns whether or not a number is prime as a Boolean. I made a first attempt, and checked out how this has been written previously. I have ended up with the following code:
def isprime(x):
limit = x**0.5
i = 2
if x < 2:
return False
elif x == 2:
return True
else:
while i <= limit:
if x%i == 0:
return False
i = i + 1
else:
return True
For some reason, the code above does not work perfectly. For example, isprime(99) would return True.
Please, can someone help me understand why this isn't working? I am trying to avoid just copying and pasting someone else's code, as I want to understand exactly what is going on here.
To me, it looks like the issue is with the final else statement. I say this because the logic reads "in the event that x%i == 0, this number is not prime" but it doesn't explicitly say what to do in the event that no x%i iterations == 0.
Any help on this would be appreciated! I'm not necessarily looking for the cleanest, neatest way of doing this, but more just trying to first make this code work.
Just to show an alternative, what you could do is checking from number 2 to your number if the operation (x % i) is equal to zero. If it never happend, it will be a prime.
def isprime(x):
# check for factors
for i in range(2,x):
if (x % i) == 0:
return False
else:
return True
print(isprime(99))
Try this :
def isprime(x):
limit = x**0.5
i = 2
if x <= 2:
return False
while i <= limit:
if x%i == 0:
return False
i = i + 1
return True
I've changed many things. have this point in your mind that there is no need to else clauses when you return at the end of if block.
you need to tell what happens when x%i==0 condition not met and the value of i remain constant and also need to see when all conditions not met, then it is a prime
# your code goes here
def isprime(x):
limit = x**0.5
i = 2
if x < 2:
return False
elif x == 2:
return True
else:
while i <= limit:
if x%i == 0:
return False
i+=1
return True
print(isprime(144)) # false
print(isprime(99)) # false
print(isprime(131)) # true

Reducing the amount of return statements (Python)

The function below returns the index within the list list_of_items of the first item that is equal to search_item. If no such items exist the function returns -1.
With a while loop rather than a for loop and not using any break statements nor index method of a list. How can I reduce my function below so that it only contains a single return statement?
With the restriction to a while loop, and not using any break statements (making this seem a lot like a homework question), your best bet is to create a second condition that controls the execution of the loop. For example:
def my_index(list_of_items, search_item):
i = 0
done = False
return_value = '-1' # I suspect you meant this to be an int, not str
while i < len(list_of_items) and not done:
if list_of_items[i] == search_item:
done = True
return_value = i
else:
i += 1
return return_value
Is this considered breaking?
def my_index(list_of_items, search_item):
res = -1
i = 0
while i < len(list_of_items):
if list_of_items[i] == search_item:
res = i
i = len(list_of_items)
else:
i += 1
return res
def my_index(list_of_items, search_item):
ret = -2
i = 0
while i < len(list_of_items):
if list_of_items[i] == search_item:
ret = i
elif i == (len(list_of_items) - 1):
ret = -1
if ret != -2:
return ret
i += 1
list_of_items = [3, 7, 2, 9, 11, 19]
print(my_index(list_of_items, 3))

Generate triangular numbers

This function is supposed to take an integer, generate the list of triangular numbers within range of that integer, check that list for the longest list of numbers whose sum == number and return them in a list, otherwise if there is no such list within that range of triangular numbers, return an empty list. I thought I had it somewhat, and it runs on python tutor.com, but when I run it in IDLE, nothing happens.
def checkio(number):
x = 4
lst = [1, 3, 6]
new = []
if number == 0:
return []
elif number == 1:
return [1]
elif number == 3:
return []
elif number == 6:
return []
elif number == 4:
return [1, 3]
elif number == 7:
return [1, 6]
elif number == 10:
return [1, 3, 6]
elif number > 10:
while number > lst[-1]: # Generates a list of all the triangular numbers up to number
for item in range(lst[-1]):
lst.append(x + lst[-1])
x += 1
go = []
start = 0
end = 0
count = 0
while count < len(lst) * 2:
if sum(lst[start:end+1]) < number:
end += 1
count += 1
elif sum(lst[start:end+1]) > number:
start += 1
count += 1
elif sum(lst[start:end+1]) == number:
go.append(lst[start:end+1])
break
return go
if count >= len(lst) * 2:
return []
In the code you post you are just declaring a function. In order to run it, you have to make a call to that function. In your case, it receives one argument, so you have to pass it inside the parentheses ():
number = 5 # for example
checkio(number) # this is the function call
As Bakuriu commented: If you want to get a result change the order of this lines:
elif sum(lst[start:end+1]) == number:
go.append(lst[start:end+1])
break
return go
To :
elif sum(lst[start:end+1]) == number:
go.append(lst[start:end+1])
return go
break
This will return a value before escaping the while loop. As noted in the comments (thanks Andrea Corbellini) you can also remove the break statement and it will work well. Because after the return statement by definition escapes the function.
Also to run in idle once defined (you copied the code and pressed return), call it as Christian says.
This way you will check if works.
Note that you don't check in the ifelse clauses for the numbers 2, 5, 8 and 9. If you call this function with checkio(5), like suggested by Crhistian, it will not return anything because it doesn't have anything to return!

Categories

Resources