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

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.

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.

assigning kth elemnt of a list to 'obj_k'

I am working with Python 2.7. Given a list of n objects i want to assign the variable 'obj_k' to the kth element of the list.
For example given the list
mylist = [1,'car', 10]
i am looking for a way to do the following for me
obj_0 = 1
obj_1 = 'car'
obj_2 = 10
This seems pretty basic, but i don't see how to do it. Morally i am thinking about something along the lines of
for i in range(len(mylist)): obj_i = mylist[i]
which is obviously syntactically invalid.
I am not sure if dynamically creating variable is a good idea but here is what you want. If I were you, I probably use a dictionary to store the variables to just avoid polluting the namespace.
In [1]: mylist = [1,'car', 10]
In [2]: print obj_1
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-2-2f857dd36a40> in <module>()
----> 1 print obj_1
NameError: name 'obj_1' is not defined
In [3]: for i,c in enumerate(mylist):
...: globals()['obj_'+str(i)] = c
...:
In [4]: obj_1
Out[4]: 'car'

Sequential Search: Input Length Isn't Detected Python

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

Sympy Can't differentiate wrt the variable

I am trying to evaluate a function (second derivative of another one) but Sympy seems to have a difficulty to do that... ?
from sympy import *
from sympy import Symbol
# Symbols
theta = Symbol('theta')
phi = Symbol('phi')
phi0 = Symbol('phi0')
H0 = Symbol('H0')
# Constants
a = 0.05
t = 100*1e-9
b = 0.05**2/(8*pi*1e-7)
c = 0.001/(4*pi*1e-7)
phi0 = 60*pi/180
H0 = -0.03/(4*pi*1e-7)
def m(theta,phi):
return Matrix([[sin(theta)*cos(phi), sin(theta)*cos(phi), cos(phi)]])
def h(phi0):
return Matrix([[cos(phi0), sin(phi0), 0]])
def k(theta,phi,phi0):
return m(theta,phi).dot(h(phi0))
def F(theta,phi,phi0,H0):
return -(t*a*H0)*k(theta,phi,phi0)+b*t*(cos(theta)**2)+c*t*(sin(2*theta)**2)+t*sin(theta)**4*sin(2*phi)**2
def F_theta(theta,phi,phi0,H0):
return simplify(diff(F(theta,phi,phi0,H0),theta))
def F_thetatheta(theta,phi,phi0,H0):
return simplify(diff(F_theta(theta,phi,phi0,H0),theta))
print F_thetatheta(theta,phi,phi0,H0), F_thetatheta(pi/2,phi,phi0,H0)
As seen below, the general function is evaluated but when I try to replace theta by pi/2 or another value, it does not work.
(4.0e-7*pi*sin(theta)**4*cos(2*phi)**2 - 4.0e-7*pi*sin(theta)**4 + 0.00125*sin(theta)**2 - 0.0001875*sqrt(3)*sin(theta)*cos(phi) - 0.0001875*sin(theta)*cos(phi) + 1.2e-6*pi*cos(2*phi)**2*cos(theta)**4 - 1.2e-6*pi*cos(2*phi)**2*cos(theta)**2 - 1.2e-6*pi*cos(theta)**4 + 1.2e-6*pi*cos(theta)**2 + 0.004*cos(2*theta)**2 - 0.002625)/pi
Traceback (most recent call last):
File "Test.py", line 46, in <module>
print F_thetatheta(theta,phi,phi0,H0), F_thetatheta(pi/2,phi,phi0,H0)
File "Test.py", line 29, in F_thetatheta
return simplify(diff(F_theta(theta,phi,phi0,H0),theta))
File "Test.py", line 27, in F_theta
return simplify(diff(F(theta,phi,phi0,H0),theta))
File "/usr/lib64/python2.7/site-packages/sympy/core/function.py", line 1418, in diff
return Derivative(f, *symbols, **kwargs)
File "/usr/lib64/python2.7/site-packages/sympy/core/function.py", line 852, in __new__
Can\'t differentiate wrt the variable: %s, %s''' % (v, count)))
ValueError:
Can't differentiate wrt the variable: pi/2, 1
The error means you can not differentiate with respect to a number, pi/2. Ie, you derive with respect to a variable (x, y...), not a number.
In an expression with several variables, you can substitute one of them (or more) by its value (or another expression) by using subs:
F_thetatheta(theta,phi,phi0,H0).subs(theta, pi/2)
Then, to evaluate it to the desired accuracy you can use evalf. Compare the two results:
F_thetatheta(theta,phi,phi0,H0).evalf(50, subs={theta:pi/2, phi:0})
F_thetatheta(theta,phi,phi0,H0).subs({theta: pi/2, phi:0})
You should probably have a look at the sympy documentation or follow the tutorial. The documentation is very good, and you can even try the examples in the browser and evaluate code.