why main() and if __name__=='__main__': main() is causing trouble? - python-2.7

def removal(DataList, n):
if len(DataList) < 2*n:
print "Not enough elements!"
for i in range(n):
DataList.remove(min(DataList))
DataList.remove(max(DataList))
return sorted(DataList)
def main():
inputs = []
while True:
inp = raw_input("Please enter a new integer, press ENTER if you want to stop: ")
if inp == "":
break
else:
inputs.append(inp)
removal(inputs,2)
if __name__=='__main__':
main()
main()
I got a ValueError: min() arg is an empty sequence
At a meanwhile, if I do not write my code in the main() and if name=='main', I'd be fine with the following code.
def removal(DataList, n):
#return to a sorted list with n smallest and n largest numbers removed.
for i in range(n):
DataList.remove(min(DataList))
DataList.remove(max(DataList))
return sorted(DataList)
inputs = []
while True:
inp = raw_input("Please enter a new integer, press ENTER if you want to stop: ")
if inp == "":
break
else:
inputs.append(inp)
removal(inputs,2)
Could somebody explain why it doesn't work in former and how should I make it work?

With:
if __name__=='__main__':
main()
main()
You're calling the main function twice (when your program is run as the main program), so after you enter a series of numbers and press another Enter to end the input, main calls removal to do the intended operations, which do not produce any output, and returns to the main program to start another call to main, which prompts for another series of number input. If at this point you simply press another Enter, you would end up with an empty list for the inputs list, which your removal function does not handle properly and would call min with the empty list, causing the said exception of ValueError: min() arg is an empty sequence.

Related

For-loop error: list index out of range

So I am rather new to programming and just recently started with Classes and we are supposed to make a phonebook that can be loaded in seperate text files.
I however keep running into the problem in this section that when I get into the for-loop. It hits a brick wall on
if storage[2] == permaStorage[i].number:
And tells me "IndexError: list index out of range". I am almost certain it is due to permaStorage starts out empty, but even when I attempt to fill it with temporary instances of Phonebook it tells me it out of range. The main reason it is there is to check if a phone number already exists within the permaStorage.
Anyone got a good tip on how to solve this or work around it?
(Sorry if the text is badly written. Just joined this site and not sure on the style)
class Phonebook():
def __init__(self):
self.name = ''
self.number = ''
def Add(name1, number1):
y = Phonebook()
y.name = name1
y.number = number1
return y
def Main():
permaStorage = []
while True:
print " add name number\n lookup name\n alias name newname\n change name number\n save filename\n load filename\n quit\n"
choices = raw_input ("What would you like to do?: ")
storage = choices.split(" ")
if storage[0] == "add":
for i in range(0, len(permaStorage)+1):
if storage[2] == permaStorage[i].number:
print "This number already exists. No two people can have the same phonenumber!\n"
break
if i == len(permaStorage):
print "hej"
try:
tempbox = Add(storage[1], storage[2])
permaStorage.append(tempbox)
except:
raw_input ("Remember to write name and phonenumber! Press any key to continue \n")
I think problem is that permaStorage is empty list and then u try to:
for i in range(0, len(permaStorage)+1):
if storage[2] == permaStorage[i].number:
will cause an error because permaStorage has 0 items but u trying to get first (i=0, permaStorage[0]) item.
I think you should replace second if clause with first one:
for i in range(0, len(permaStorage)+1):
if i == len(permaStorage):
print "hej"
try:
tempbox = Add(storage[1], storage[2])
permaStorage.append(tempbox)
if storage[2] == permaStorage[i].number:
print "This number already exists. No two people can have the same phonenumber!\n"
break
So in this case if perStorage is blank you will append some value and next if clause will be ok.
Indexing starts at zero in python. Hence, a list of length 5 has the last element index as 4 starting from 0. Change range to range(0, len(permastorage))
You should iterate upto the last element of the list, not beyond.
Try -
for i in range(0, len(permaStorage)):
The list of numbers produced in range() is from the start, but not including the end, so range(3) == [0, 1, 2].
So if your list x has length 10, range(0, len(x)) will give you 0 through 9, which is the correct indices of the elements of your list.
Adding 1 to len(x) will produce the range 0 through 10, and when you try to access x[10], it will fail.

Determining if an int exist in a list, without using the "in" function

I need to get user input to generate a list of 8 numbers, but when they input a number that is already in the list print and error . Without using the in function to determine if its in the list. Here's what I have so far.
def main():
myList = range(9)
a= True
for i in myList:
while a == True:
usrNum = int(input("Please enter a number: "))
if usrNum != myList[i]:
myList.append(usrNum)
print(i)
main()
Error for above code,
Scripts/untitled4.py", line 18, in main
myList.append(usrNum)
AttributeError: 'range' object has no attribute 'append'
The issue seems to be your way of generating myList. If you generate it with myList = [range(9)] you'll get:
[[0, 1, 2, 3, 4, 5, 6, 7, 8]]
Try using simply:
myList = range(9)
Also, you need to change myList.append[usrNum] with myList.append(usrNum) or you'll get a:
TypeError: 'builtin_function_or_method' object has no attribute '__getitem__'
You could also use wim's suggestion instead of the != operator:
if myList.__contains__(usrNum):
myList.append(usrNum)
There are two ways you can go about this:
Loop through the list to check each element.
The in operator is effectively doing:
for each value in the list:
if the value is what you're looking for
return True
if you reach the end of the list:
return False
If you can add that check into your code, you'll have your problem solved.
Use an alternate way of tracking which elements have been added
Options include a dict, or bits of an int.
For example, create checks = {}. When you add an value to the list, set checks[usrNum] = True. Then checks.get(usrNum, False) will return a boolean indicating whether the number already exists. You can simplify that with a collections.DefaultDict, but I suspect that may be more advanced than you're ready for.
The first is probably the result your instructor is after, so I'll give you a simple version to work with and massage to fit your needs.
myList = []
while True:
usrNum = int(input())
found = False
for v in myList:
if usrNum == v:
found = True
if not found:
myList.append(usrNum)
else:
#number was already in the list, panic!
Most instructors will be more impressed, and hence award better grades, if you can figure out how to do something like method 2, however.
You could do something like this, modify as needed (not sure when/if you want to break when the user enters a number that is already in the list, etc.)
This prompts for user input until they enter an item that already exists in the list, then it prints a message to the user, and stops execution.
def main():
mylist = range(9)
while True:
usrNum = int(input("Please enter a number: "))
if existsinlist(mylist, usrNum):
print("{} is already in the list {}".format(usrNum, mylist))
break
else:
mylist.append(usrNum)
def existsinlist(lst, itm):
for i in lst:
if itm == i:
return True
return False
Perhaps the point of this homework assignment is to help you understand how an operator like in is more efficient to read (and write, and compile) than the explicit loop that I used in the existsinlist function.
Not sure if list-comperehension would be allowable in this case, but you also could've done something like this, without relying on the existsinlist helper function:
def main():
mylist = range(9)
while True:
usrNum = int(input("Please enter a number: "))
if [i for i in mylist if i == usrNum]:
print("{} is already in the list {}".format(usrNum, mylist))
break
else:
mylist.append(usrNum)
In this case, the result of the list-comprehension can be evaluated for truthiness:
An empty list like [] results if no matching value exists, and this will be considered False
A non-empty list will result if at least one matching value exists, and this will be considered True
Yet another option which short-circuits and may be preferable:
if any(usrNum == i for i in mylist)

Python 2.7 Coin Flip Program Crashes Every Time

I'm having this strange problem with a simple coin flip program where, instead of giving me some sort of error, whenever i run this code it just sort of crashes. I type in a yes or no answer and hit enter, but it does nothing. Then I hit enter again and it closes out completely.
import time
import random
constant = 1
FirstRun = True
def Intro():
raw_input("Hello and welcome to the coin flip game. Do you wish to flip a coin? (yes or no): ")
def CoinToss():
print "You flip the coin"
time.sleep(1)
print "and the result is..."
time.sleep(1)
result = random.randint(1,2)
if result == 1:
print "heads"
if result == 2:
print "tails"
while constant == 1:
if FirstRun == True:
Intro()
FirstRun = False
else:
answer = raw_input()
if answer == "yes":
CoinToss()
raw_input("Do you want to flip again? (yes or no): ")
else:
exit()
As you simply ignore the return value of the raw_input method, you don't know what the user is entered in order to break out of the loop.
Here is a simplified version of your program, note how I store the result of the raw_input method in result and use that to control the execution loop:
import random
import time
result = raw_input('Hello and welcome to the coin flip game. Do you wish to flip a coin? (yes or no): ')
while result != 'no':
print('You flip the coin....')
time.sleep(1)
print('...and the result is...')
toss_result = random.randint(1,2)
if toss_result == 1:
print('Heads')
else:
print('Tails')
result = raw_input('Do you want to flip again? (yes or no): ')
print('Goodbye!')

(Super beginner) Can someone explain what's going wrong with my lists?

Ok, so, this is the longest code I've ever written, so I apologize if it's a bit messy. First computer science assignment ever.
def main():
#generate random value
import random
rand = random.randint(1, 99)
#instructions
print("""The purpose of this exercise is to enter a number of coin values
that add up to a displayed target value. Enter coins as 1=penny, 5-nickel,
10-dime, 25-quarter. Hit return after the last entered coin value.""")
#defining function for 'first coin'
def firstCoin ():
coins = []
global coins
coin = int(input("Enter first coin: "))
if coin > rand:
print("Sorry, total value exceeds", rand, "cents.")
again = input("Try again (y/n): ")
if again == "y" or "Y":
main()
else:
sys.exit() #ends program
elif coin in possible:
coins.append(coin)
nextCoinplease()
#defining function for 'next coin'
def nextCoinplease ():
while True:
nextcoin = (input("Enter next coin: "))
if nextcoin in possible:
coins.append(nextcoin)
elif nextcoin == "":
break
else: print("Invalid entry.")
#making lists
possible = [1, 5, 10, 25]
print("Enter coins that add up to", rand, "cents, one per line.") #program start
firstCoin ()
sumcoin = sum(coins)
print(sumcoin)
if sumcoin == rand:
print("Correct!")
else:
print("Invalid entry.")
firstCoin()
main()
So, this is my issue. For some reason, user input in the function nextCoinplease does not get added to the list "coins", only the first input from the function firstCoin does. This means that sum(coins) is literally only the first input. I cannot for the life of me figure out why, so any input would be greatly appreciated, thanks!
You have two input statements, one to get coin and one to get nextcoin. They are different. What's the difference?
(I'm deliberately not giving the answer outright because from what you've written so far, I am sure you can figure this one out given this hint.)
The return type of input is a string, so nextcoin in possible always fails since possible only contains integers. Try using int() to parse the input as an integer.
Your code never gets to check if the rand is equal to sumCoin, so it never stopped. I've fixed the problem, this code works now.
Demo on repl.it
What did I do?
I moved your if statement that checked if rand == sumCoin at the beginning of the while loop in nextCoinPlease(), so that it will check the sumCoin value before entering each next coin value and will stop once it equals rand.
Code:
import random
import sys
def main():
rand = random.randint(1, 99)
print('''The purpose of this exercise is to enter a number of coin values \
that add up to a displayed target value. Enter coins as 1=penny, \
5=nickel, 10-dime, 25-quarter. Hit return after the last entered \
coin value.''')
coins = []
def firstCoin():
coin = int(input("Enter first coin: "))
if coin > rand:
print('Sorry, total value exceeds ', rand, ' cents.')
again = input('Try again? (y/n): ')
if again == 'y' or 'Y':
main()
else:
sys.exit()
elif coin in possible:
coins.append(coin)
nextCoinPlease()
def nextCoinPlease():
while True:
sumCoin = sum(coins)
print('Total Value: ' + str(sumCoin))
print ''
if sumCoin == rand:
print('Correct! You Win!')
sys.exit()
elif sumCoin > rand:
print('You exceeded the total value! You lose! Try again!')
sys.exit()
nextCoin = (input('Enter next coin: '))
if nextCoin in possible:
coins.append(nextCoin)
elif nextCoin == "":
break
else:
print('Invalid entry.')
possible = [1, 5, 10, 25]
print('Enter coins that add up to', rand, 'cents, one per line.')
firstCoin()
main()

How to run the code from start after calculation?

What if i want to ask the user whether he wants to perform another calculation or not everytime the user makes a calculation and gets the answer? I just want the code to run again from start everytime user performs calculation
var = int(raw_input("Enter 1,2,3 or 4 for add,subtract,multiplication,division respectively: "))
if var == 1:
print "You chose to add.Lets add!! :)"
def main ():
total = 0.0
while True:
number = float(raw_input('enter a number: '))
total+=number
if number == 0:
break
print "your answer is:",total
main()
elif var == 3:
print "You chose to multiply.Lets multiply!! :) "
def main ():
total = 1.0
while True:
number = float(raw_input('enter a number:'))
total*=number
if number == 1:
break
print "the answer is", total
main()
Just put
while True:
around the whole thing. This will continue looping indefinitely. If you want the user to be able to choose to end the program, try:
while True:
...
continue = raw_input("Continue? (Y/N) ")
if continue.lower in ("n", "no"):
break