Hello this is my first question and sorry I don't know how to phrase it,
I am trying to create a two list. The first list is for one set of codes (code1) and is validated in the VC function. The second function (VC) is to validate the second list. Both functions work well in validating the numbers. However in the third function (add_validations). In that function I want to repeat VC and VQ until the user either types in END or either of the functions return False. When true I want the inputs to be appended into the two separate lists. However, the third function not only does not append any of the list it does not identify/run either of the two functions and comes up with:
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
And I'm sorry I didn't know which code to add so I added everything (delete if not allowed sorry):
Code:
def add_validations():
code1 = []
code2 = []
VC()
VQ()
while True:
record = []
i = VC()
q = VQ()
if i != "END":
VQ()
VC()
code1.append(int(i))
code2.append(int(q))
elif VC == True and VQ() == True:
VQ()
VC()
code1.append(int(i))
code2.append(int(q))
elif VC == False and VQ() == True:
print("Invalid code")
else:
print("Invalid quantity")
return code1,code2
def VC():
i = input("What is the item code \n")
minimum = 0
maximum = 39
if i == "END":
i = "END"
return showRecord()
elif int(i) > minimum and int(i) <= maximum:
return int(i)
True
else:
False
def VQ():
q = input("What quanity \n")
minimum = 0
maximum = 49
if q == "END":
isValidCode = "END"
return showRecord()
elif int(q) > minimum and int(q) <= maximum:
True
else:
False
Related
Just learning python, and trying to make a game of Hangman.
I'm having an issue when running the program, where if I run through it without trying to throw it off (ex. input "enter" and input "2") then it gives me a random word of difficulty I'm asking for.
If I try to throw it off, (ex. input "enter", input "12", input "3") it returns "None"
I've been trying to figure it out, printing different variables in different locations to see what's off, but I can't find anything.
I'd appreciate any help I can get.
Any other input welcome as well.
wordbank file
import random
import math
# Random Word Generator
with open('wordbank.csv') as f:
file = f.read().split('\n')
word_list = list(file)
def max_letters(x):
max_length = 0
for words in x:
if len(str(words)) >= max_length:
max_length = len(str(words))
return max_length
def word_selector(x):
diff = input("What difficulty would you like? Type a difficulty of 1 - 3 and press 'Enter': ")
diff_list = []
diff_var = math.ceil((max_letters(word_list) / 3))
if diff == "1" or diff == "2" or diff == "3":
for words in x:
length = len(str(words))
if diff == "1":
if 0 < length <= diff_var:
diff_list.append(str(words))
elif diff == "2":
if diff_var < length <= (diff_var * 2):
diff_list.append(str(words))
elif diff == "3":
if (diff_var * 2) < length:
diff_list.append(str(words))
return random.choice(diff_list)
else:
print("That's not an option... Difficulties are 1 - 3. Try again.")
word_selector(word_list)
def start_hangman():
start = input("Press 'Enter' to start!\n")
if start == "":
print(word_selector(word_list)) # Will eventually be hangman
else:
print("What are you doing??? Just press enter!")
start_hangman()
start_hangman()
You are calling the function back, which is called recursion. It can be pretty confusing. Let's say a bad input, 12 is entered. The function word_selector() will execute the else statement, which calls the function back:
def word_selector(x):
(...)
else:
word_selector(word_list) # <-- we are here
The function then asks again for input, let's say this time a valid input is entered, 3. It will then correctly return a word, let's say apple. So now, the function returned apple, but we are back at where the function was called from.
def word_selector(x):
(...)
else:
"apple" # because the function call returned "apple".
As you can see now, the else condition simply says "apple", without returning anything or assigning it to a value. Since the function does not return anything, python makes it return None, which is like a null/undefined value. This is why you are getting your error.
As a fix, I believe you have to move your error-checking and input getting code out of word_selector() to the start_hangman() loop. For example, this works as intended:
import random
import math
# Random Word Generator
with open('wordbank.csv') as f:
file = f.read().split('\n')
word_list = list(file)
def max_letters(x):
max_length = 0
for words in x:
if len(str(words)) >= max_length:
max_length = len(str(words))
return max_length
def word_selector(x, diff):
diff_list = []
diff_var = math.ceil((max_letters(word_list) / 3))
for words in x:
length = len(str(words))
if diff == "1":
if 0 < length <= diff_var:
diff_list.append(str(words))
elif diff == "2":
if diff_var < length <= (diff_var * 2):
diff_list.append(str(words))
elif diff == "3":
if (diff_var * 2) < length:
diff_list.append(str(words))
return random.choice(diff_list)
def start_hangman():
start = input("Press 'Enter' to start!\n")
if start == "":
diff = input(
"What difficulty would you like? Type a difficulty of 1 - 3 and press 'Enter': ")
if diff == "1" or diff == "2" or diff == "3":
print(word_selector(word_list, diff))
else:
print("That's not an option... Difficulties are 1 - 3. Try again.")
start_hangman()
else:
print("What are you doing??? Just press enter!")
start_hangman()
start_hangman()
I am writing a file overlap function that takes two arguments: longestFile and shorterFile. I want to see if two files have the same numbers and if they do, it will append that number to an empty list.
These are the two lists I am using for the program:
The first file that I am using to compare and The second file that I use
def longestFile(firstFile, secondFile):
if len(firstFile)>len(secondFile):
return firstFile
else:
return secondFile
def shortestFile(firstFile, secondFile):
if len (firstFile) < len(secondFile):
return firstFile
else:
return secondFile
def middleNumber(theLongestFile):
return theLongestFile[len(theLongestFile)//2]
def fileOverlap(lstFirstFile,lstSecondFile):
lstMatchingNums = []
lstLongerFile = longestFile(lstFirstFile,lstSecondFile)
lstShortestFile = shortestFile(lstFirstFile,lstSecondFile)
for eachLines in range(len(lstShortestFile)):
lstLongerFile = longestfile(lstFirstFile,lstSecondFile)
for eachLine in range(len(lstLongerFile)):
if lstShortestFile[eachLines] == middleNumber(lstLongerFile):
lstMatchingNums.append(lstShortestFile[eachLines])
break
elif lstShortestFile[eachLines] < middleNumber(lstLongerFile):
lstLongerFile = lstLongerFile[0:len(lstLongerFile)//2+1]
if len(lstLongerFile) <= 2 and lstLongerFile[0] == lstShortestFile[eachLines]:
lstMatchingNums.append(lstShortestFile[eachLines])
break
elif middleNumber(lstLongerFile) != lstShortestFile[eachLines] and len(lstLongerFile) <=2:
break
elif lstShortestFile[eachLines] > middleNumber(lstLongerFile):
lstLongerFile = lstLongerFile[len(lstLongerFile)//2:]
if len(lstLongerFile) <= 2 and lstLongerFile[0] == lstShortestFile[eachLines]:
lstMatchingNums.append(lstShortestFile[eachLines])
break
elif middleNumber(lstLongerFile) != lstShortestFile[eachLines] and len(lstLongerFile) <= 2:
break
return lstMatchingNums
lstHappyNums = open('happynumbs.txt','r')
lstReadingHappyLines = lstHappyNums.readlines()
lstHappyNums.close()
lstPrimeNumsFile = open('primenumbers.txt','r')
lstReadingPrimeLines = lstPrimeNumsFile.readlines()
lstPrimeNumsFile.close()
print(fileOverlap(lstReadingHappyLines,lstReadingPrimeLines))
If I was to run this program, it would give me an empty list and I am not sure why.
I have a binary search that searches a list from a user given input of an email. I get no errors and I get no output from it. I can't see where its going wrong?
def BubbleSort(logindata):
NoSwaps = 1
N = len(logindata)
logindata = list(logindata)
while NoSwaps == 1:
Count = 1
NoSwaps = 0
for Count in range(N-1):
if logindata[Count] > logindata[Count+1]:
temp = logindata[Count]
logindata[Count] = logindata[Count+1]
logindata[Count+1]=temp
NoSwaps=1
return tuple(logindata)
def BinarySearch(logindata,ItemSought):
First=0
Last=len(logindata)-1
ItemFound = False
SearchFailed = False
while ItemFound == False or SearchFailed == False:
Midpoint = (First + Last) // 2
if logindata[Midpoint] == ItemSought:
print("Item Found")
ItemFound = True
print("Item Found")
break
elif logindata[Midpoint][0] > ItemSought:
Last = Midpoint - 1
else:
First = Midpoint + 1
if __name__ == "__main__":
logindata=["tom#gmail.com","Password1"],["harry#gmail.com","Password2"],["jake#gmail.com","Password3"]
logindata=BubbleSort(logindata)
print(logindata)
ItemSought=input("Enter username")
BinarySearch(logindata,ItemSought)
In
if logindata[Midpoint] == ItemSought:
you compare list with a string. So I think you need
if logindata[Midpoint][0] == ItemSought:
You never terminate the search. If the item isn't in the list, you get to a stable midpoint and loop infinitely. If you do find the item, you loop infinitely on that (see Yehven's answer).
I traced it with the additions you see here:
SearchFailed = False
iter = 0
while iter < 10 and (ItemFound == False or SearchFailed == False):
iter += 1
Midpoint = (First + Last) // 2
print (First, Midpoint, Last, ItemSought)
if logindata[Midpoint] == ItemSought:
Note that you don't ever change SearchFailed. For instance, when I search for "harry", the loop hits a stable infinite point at (0, -1, -2) for First, Middle, Last.
Is that enough of a hint to let you fix it yourself?
Like using this to validate that an input is only alpha-numeric:
while True:
str = input('')
if str.isalnum():
break
else:
print("Please include only alpha-numeric characters.\n")
This code has worked for all instances that I have tested it in, but is this bad practice?
That's fine. Here is a note, however: you can find out if the while loop exited with a break or without one by using else:
x = 0
while x < 4:
x += 1
else:
print("no break")
# prints no break
If you break, however:
x = 0
while x < 4:
x += 1
if x == 2:
break
else:
print("no break")
# Does not print
you can abstract it further
def verified_input(prompt='',test_condition=lambda x:1,err_message="Please Enter Valid Input"):
while True:
result = input(prompt)
if test_condition(result):
return result
print( err_message )
def verified_alnum(prompt,err_message="Please enter Only alpha numerics"):
return verified_input(prompt,lambda x:x.isalnum(),err_message)
result = verified_alnum("Enter Password:","A password must be only letters and numbers")
this allows you to create any number of test conditions quickly and relatively verbosely
So i wrote this code and it passes the first test case, and fails all the rest. However, I can't seem to find an input that breaks it. Maybe it's because I've been staring at the code too long, but i would appreciate any help.
The algorithm uses two priority queues for the smallest and largest halves of the current list. Here's the code:
#!/bin/python
import heapq
def fix(minset, maxset):
if len(maxset) > len(minset):
item = heapq.heappop(maxset)
heapq.heappush(minset, -item)
elif len(minset) > (len(maxset) + 1):
item = heapq.heappop(minset)
heapq.heappush(maxset, -item)
N = int(raw_input())
s = []
x = []
for i in range(0, N):
tmp = raw_input()
a, b = [xx for xx in tmp.split(' ')]
s.append(a)
x.append(int(b))
minset = []
maxset = []
for i in range(0, N):
wrong = False
if s[i] == "a":
if len(minset) == 0:
heapq.heappush(minset,-x[i])
else:
if x[i] > minset[0]:
heapq.heappush(maxset, x[i])
else:
heapq.heappush(minset, -x[i])
fix(minset, maxset)
elif s[i] == "r":
if -x[i] in minset:
minset.remove(-x[i])
heapq.heapify(minset)
elif x[i] in maxset:
maxset.remove(x[i])
heapq.heapify(maxset)
else:
wrong = True
fix(minset, maxset)
if len(minset) == 0 and len(maxset) == 0:
wrong = True
if wrong == False:
#Calculate median
if len(minset) > len(maxset):
item = - minset[0]
print int(item)
else:
item = ((-float(minset[0])) + float(maxset[0])) / 2
if item.is_integer():
print int(item)
continue
out = str(item)
out.rstrip('0')
print out
else:
print "Wrong!"
Your original was not so legible, so first I made it object-oriented:
MedianHeapq supports methods rebalance(), add(), remove(), size(), median(). We seriously want to hide the members minset,maxset from the client code, for all sorts of sensible reasons: prevent client from swapping them, modifying them etc. If client needs to see them you just write an accessor.
We also added a __str__() method which we will use to debug visually and make your life easier.
Also added legibility changes to avoid the indexing with [i] everywhere, rename s,x arrays to op,val, add prompts on the raw_input(), reject invalid ops at the input stage.
Your actual computation of the median confuses me (when do you want float and when integer? the rstrip('0') is a bit wack), so I rewrote it, change that if you want something else.
A discussion of the algorithm is here.
Now it is legible and self-contained. Also makes it testable.
You might be making sign errors in your code, I don't know, I'll look at that later.
Next we will want to automate it by writing some PyUnit testcases. doctest is also a possibility. TBC.
Ok I think I see a bug in the sloppiness about locating the median. Remember the minset and maxset can have a size mismatch of +/-1. So take more care about precisely where the median is located.
#!/bin/python
import heapq
class MedianHeapq(object):
def __init__(self):
self.minset = []
self.maxset = []
def rebalance(self):
size_imbalance = len(self.maxset) - len(self.minset)
if len(self.maxset) > len(self.minset):
#if size_imbalance > 0:
item = heapq.heappop(self.maxset)
heapq.heappush(self.minset, -item)
#elif size_imbalance < -1:
elif len(self.minset) > (len(self.maxset) + 1):
item = heapq.heappop(self.minset)
heapq.heappush(self.maxset, -item)
def add(self, value, verbose=False):
if len(self.minset) == 0:
heapq.heappush(self.minset,-value)
else:
if value > self.minset[0]:
heapq.heappush(self.maxset, value)
else:
heapq.heappush(self.minset, -value)
self.rebalance()
if verbose: print self.__str__()
return False
def remove(self,value,verbose=False):
wrong = False
if -value in self.minset:
minset.remove(-value)
heapq.heapify(self.minset)
elif value in maxset:
maxset.remove(value)
heapq.heapify(self.maxset)
else:
wrong = True
self.rebalance()
if verbose: print self.__str__()
return wrong
def size(self):
return len(self.minset)+len(self.maxset)
def median(self):
if len(self.minset) > len(self.maxset):
item = - self.minset[0]
return int(item)
else:
item = (-self.minset[0] + self.maxset[0]) / 2.0
# Can't understand the intent of your code here: int, string or float?
if item.is_integer():
return int(item)
# continue # intent???
else:
return item
# The intent of this vv seems to be round floats and return '%.1f' % item ??
#out = str(item)
#out.rstrip('0') # why can't you just int()? or // operator?
#return out
def __str__(self):
return 'Median: %s Minset:%s Maxset:%s' % (self.median(), self.minset,self.maxset)
# Read size and elements from stdin
N = int(raw_input('Size of heap? '))
op = []
val = []
while(len(val)<N):
tmp = raw_input('a/r value : ')
op_, val_ = tmp.split(' ')
if op_ not in ['a','r']: # reject invalid ops
print 'First argument (operation) must be a:Add or r:Remove! '
continue
op.append(op_)
val.append(int(val_))
mhq = MedianHeapq()
for op_,val_ in zip(op,val): # use zip to avoid indexing with [i] everywhere
wrong = False
if op_ == 'a':
wrong = mhq.add(val_)
elif op_ == 'r':
wrong = mhq.remove(val_)
assert (mhq.size()>0), 'Heap has zero size!'
assert (not wrong), 'Heap structure is wrong!'
if not wrong:
print mhq.__str__()