Sequential Search: Input Length Isn't Detected Python - list

I'm writing a program where the user inputs a list of numbers, and then is asked which number he or she wants the program to return that numbers position. (Ex. 3,5,1,9,12,6 --> find position in list where 9 occurs)
I can get this to work if I hard code the list and the search number, but I'm having trouble with input. Mostly my problem is that Python isn't detecting the length of the list of numbers but I'm not sure how to fix this.
Here is the code I have:
def List(line):
list = []
for e in line.split(','):
list.append(int(e))
def Search(num, list):
for i in range(len(list)):
if list[i] == num:
return i
return -1
def main():
line = input("Enter list of numbers separated by commas: ")
p = input("Number searching for")
print(List(line))
a = Search(p, list)
print(a)
main()
And here's the error:
Traceback (most recent call last):
File "G:\Final Exam Practice\linearsearch.py", line 24, in <module>
main()
File "G:\Final Exam Practice\linearsearch.py", line 19, in main
a = Search(p, list)
File "G:\Final Exam Practice\linearsearch.py", line 7, in Search
for i in range(len(list)):
TypeError: object of type 'type' has no len()

First, this answer has something you could use. list.index is a class method that returns the index of a list item:
>>> mylist = [3,5,1,9,12,6]
>>> mylist.index(9)
3
Next, a TypeError is raised because list is one of Python's reserved keywords. If you want to pass a list to your Search function, don't name it 'list'.
Just changing the name of the 'list' variable in the function will solve your problem. Additionally, here's another way to define search (Python function names are usually lowercase):
def search(num, mylist):
try:
return mylist.index(num)
except:
return -1

Related

Pass all the elements of a list through a functions

I created a python program that arranges and finds the median of a series of numbers a user inputs. I keep getting this error.
Traceback (most recent call last):
File "C:/Users/NL-LP3/Desktop/Corses/Python/Tests Programs/median user input.py", line 24, in
median(^series)
TypeError: median() takes 1 positional argument but 4 were given
series=[]
finished = False
while not finished:
number = input("Please enter a number, when you are done hit ENTER")
if len(number)>0:
series.append([number])
print ("Number Entered")
else:
finished = True
print (series)
def median(data):
data.sort(key=int)
elements = len(data)
middle = int(elements/2)
if elements%2 ==1:
print (data[middle])
else:
half = ((data[middle])+(data[middle-1]))/2
print (half)
median(*series)
Three issues here:
You are passing in a string into your array, you need to convert it to an int
You are passing in an array to an array which gives you an output like this:
[[5], [6], [7]]
You are attempting to unpack your array by using the * in your *series.
It needs to be this:
[5, 6, 7]
Change this line:
series.append(int(number))
You are also just need to pass in the array to median like such:
median(series)
you unpack your series as you are passing it to your function:
median(*series)
this way median is called with all the items in the list as arguments. what you want is:
median(series)
missed the second issue! read Jason Heine's answer...

Return instead of print key in a Python list

I'm trying to create a function where each key in a list becomes an updatable parameter for another function.
I know that I can print all the keys in a list like this:
x = [a , b, c, d]
for key in x:
print(key)
But when I use the return statement like:
for key in x:
return key
It only returns a.
How can I iterate over a list and return each value every time the loop is performed.
Thank you very much.
A slight modification is ok:
def PrintKey(x):
for key in x:
yield key
When you use the return statement you leave the function, thus after the first loop the interpreter exits the function and returns the first index of your list.
Could you post more code?
I see no reason to put this in a function but if you need to, one option could be :
for i in range(len(list)):
storeSomeWhere = myFunction(list, i)
def myFunction(list, i):
return list[i]
For what? The for loop already hands you one value from the list at a time.
If you insist you can use a generator function that accepts the list and returns the next element each time it is used (until it runs out of elements, then a StopIteration exception is raised):
def gen(li):
for element in li:
yield element
li = [1, 2, 3, 4]
a = gen(li)
print(next(a))
# 1
print(next(a))
# 2
print(next(a))
# 3
print(next(a))
# 4
print(next(a))
Traceback (most recent call last):
File "main.py", line 63, in <module>
print(next(a))
StopIteration
But again, I don't see any reason to use this in your case. Simply use the value that the for loop hands you.

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 Dictionary Type

I'm trying to figure out why I get this type error. Is it possible to put integers inside of dictionaries?
math_questions = [
{'question1':'1*1',
'answer1':1,
'quote1' :'What you are,you are by accident of birth; what I am,I am by myself.\n There are and will be a thousand princes; there is only one Beethoven.'},
{'question2':'2*1',
'answer2':2,
'quote2': 'Two is company, three is a crowd'},
{'question3': '3*1',
'answer3': 3,
'quote3': 'There are three types of people, those who can count and those who cannot'}
]
# read from a txt file later???
print math_questions[0]['question1']
math_answer = int(raw_input("What is the answer to " + math_questions["question1"] +"? : "))
if math_answer == math_questions['answer1']:
print math_questions['quote']
else:
print "Try again"
print math_questions['answer1']
This is the error message I get.
PS C:\python27\math_game> python math_game.py
1*1
Traceback (most recent call last):
File "math_game.py", line 17, in <module>
math_answer = int(raw_input("What is the answer to " + math_questions["question1"] +"? : "))
TypeError: list indices must be integers, not str
PS C:\python27\math_game>
Thanks for the help in advance.
When you access a list, you need the index. It looks like you are trying to access a dict. Instead, put:
math_answer = int(raw_input("What is the answer to " + math_questions[0]["question1"] +"? : "))
You had a few errors:
You had math_questions["question1"] on line 17, 19, 20, 23
You had math_questions["quote"] which didn't exist (I changed to math_questions["quote1"])
Over here, we try to access a list of dicts by the way you used. However, we need to strip it to just the dict before we access it that way.
>>> obj = [{'data1': 68,
... 'data2': 34,
... 'data3': 79}]
>>> obj['data2']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not str
>>> obj[0]['data2']
34
>>>
Here is your updated code:
math_questions = [
{'question1':'1*1',
'answer1':1,
'quote1' :'What you are,you are by accident of birth; what I am,I am by myself.\n There are and will be a thousand princes; there is only one Beethoven.'},
{'question2':'2*1',
'answer2':2,
'quote2': 'Two is company, three is a crowd'},
{'question3': '3*1',
'answer3': 3,
'quote3': 'There are three types of people, those who can count and those who cannot'}
]
# read from a txt file later???
print math_questions[0]['question1']
math_answer = int(raw_input("What is the answer to " + math_questions[0]["question1"] +"? : "))
if math_answer == math_questions[0]['answer1']:
print math_questions[0]['quote1']
else:
print "Try again"
print math_questions[0]['answer1']
You should rework your data structure similar to this:
class MathQuestion:
def __init__(self, question, answer, quote):
self.question = question
self.answer = answer
self.quote = quote
math_questions = [
MathQuestion(question='1*1', answer='1', quote='What you are …'),
MathQuestion(question='2*1', answer='2', quote='Two is company …'),
#…
]
This allows you to address your strings like this:
math_questions[0].answer

Python: TypeError: 'NoneType' object is not iterable Confusion

I'm new to python and am trying to write a code that would deal poker hands and check for pat flushes. Below is my code and the shell when I try to run it. According to my professor this should return True if there is only one suit in the hand, i.e., only one entry in the set "suits" and False otherwise, but I keep getting this error message. Can someone help explain this to me?
from random import *
suits = {'H','C','D','S'} #hearts, clubs, diamonds, spades
ranks = {'a','2','3','4','5','6','7','8','9','10','j','q','k'} #card values
deck = [r +s for r in ranks for s in suits]
hand = []
def deal (n):
'''deals n hands'''
for n in range (0,n):
hand = sample (deck,5)
for x in hand:
deck.remove (x)
print (hand)
def is_flush (hand):
'''checks for pat flush hands'''
suits = {c[-1] for c in hand}
return len(suits) == 1
RUN
>>> is_flush (5)
['10S', 'qD', '8H', '8D', '3S']
['5C', 'jC', 'kS', '4C', '2H']
['2S', '7C', '7H', '7S', '9S']
['8C', '8S', 'aH', '5S', '2D']
['9D', '6S', '4D', 'qS', '9H']
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
is_flush (5)
File "K:/stalter_3.py", line 19, in is_flush
suits = {c[-1] for c in hand}
TypeError: 'NoneType' object is not iterable
>>>
You're calling is_flush(5). If I understand you correctly, then that value 5 is the variable hand which you are trying to iterate through (as if it were a hand) in c[-1] for c in hand, but you can't iterate an integer. The reason I'm confused is I would expect it to say that it's an IntType, not a NoneType.