I am creating a Yahtzee program in Python. This function is meant to carry out the action that the user chooses (the user inputs a number, and it chooses the appropriate list item). I just got to the section about adding the total of one number set (the top part of a Yahtzee card with the ones, twos, etc.). I made a loop that adds one to the score for every 1 found in list dicevalues (a random list of "rolled dice" numbers; declared earlier in program).
I am getting the error on the for 1 in dicevalues: line. It says SyntaxError: cannot assign to literal. I looked up this error, but I'm not making sense of it. What I interpret here is that the program would run the code in the for block for every value 1 in dicevalues, but I'm not quite sure if you can use the for loop in that way.
def choiceAction():
if options[choice] == "Chance (score total of dice).":
global score
score += (a + b + c + d + e)
if options[choice] == "YAHTZEE!":
score += 50
if options[choice] == "Large straight":
score += 40
if options[choice] == "Small straight.":
score += 30
if options[choice] == "Four of a kind (total dice score).":
score += (a + b + c + d + e)
if options[choice] == "Three of a kind (total dice score).":
score += (a + b + c + d + e)
if options[choice] == "Full house.":
score += 25
if options[choice] == "Add all ones.":
for 1 in dicevalues: # <-- SyntaxError: can't assign to literal
score += 1
Is it possible that for some reason 1 cannot be in the for declaration?
If you don't want to use the items in dicevalues you can use a placeholder
for _ in dicevalues:
The error
When you write for x in dicevalues: you iterate over dicevalues and put each element in the variable x, so x can not be replaced with 1. This is why you get the error SyntaxError: can't assign to literal.
The solution(s)
Here are several solutions to perform what you want:
dicevalues = [2, 1, 3, 6, 4 ,1, 2, 1, 6]
# 1. Classic 'for' loop to iterate over dicevalues and check if element is equal to 1
score = 0
for i in dicevalues:
if i == 1:
score += 1
print(score) # 3
# 2. Comprehension to get only the elements equal to 1 in dicevalues, and sum them
score = 0
score += sum(i for i in dicevalues if i == 1)
print(score) # 3
# 3. The 'count()' method to count the number of elements equal to 1 in dicevalues
score = 0
score += dicevalues.count(1)
print(score) # 3
Related
Hi I need to do this task in two ways: one way with for loop which I did and other with while loop but I don't secceed....The code I wrote is:
A = [5,8,9,1,2,4]
AV = sum(A) / float(len(A))
count = 0
for i in A :
if i > AV :
count = count + 1
print ("The number of elements bigger than the average is: " + str(count))
count = 0
while float in A > AV:
count += 1
print ("The number of elements bigger than the average is: " + str(count))
The problem is that you are using while float in A > AV: in your code. The while works until the condition is true. So as soon as it encounters some some number in list which is smaller than average, the loop exits. So, your code should be:
A = [5,8,9,1,2,4]
AV = sum(A) / float(len(A))
count = 0
for i in A : if i > AV :
count = count + 1
print ("The number of elements bigger than the average is: " + str(count))
count = 0
i = 0
while i < len(A):
if A[i] > AV: count += 1
i += 1
print ("The number of elements bigger than the average is: " + str(count))
i hope it helped :) and i believe you know why i added another variable i.
Your code is indeed unformatted. Generally:
for x in some_list:
... # Do stuff
is equivalent to:
i = 0
while i < len(some_list):
... # Do stuff with some_list[i]
i += 1
A = [5,8,9,1,2,4]
AV = sum(A) / float(len(A))
count = 0
for i in A:
if i > AV:
count = count + 1
print ("The number of elements bigger than the average is: " + str(count))
count = 0
i = 0
while i < len(A):
if A[i] > AV:
count += 1
i += 1
print ("The number of elements bigger than the average is: " + str(count))
You can use something like the code below. I have commented on each part, explaining the important parts. Note that your while float in A > AV is not valid in python. In your case, you should access elements of a list by indexing or using a for loop with the in keyword.
# In python, it is common to use lowercase variable names
# unless you are using global variables
a = [5, 8, 4, 1, 2, 9]
avg = sum(a)/len(a)
print(avg)
gt_avg = sum([1 for i in a if i > avg])
print(gt_avg)
# Start at index 0 and set initial number of elements > average to 0
idx = 0
count = 0
# Go through each element in the list and if
# the value is greater than the average, add 1 to the count
while idx < len(a):
if a[idx] > avg:
count += 1
idx += 1
print(count)
The code above will output the following:
4.833333333333333
3
3
Note: There are alternatives to the list comprehension that I've provided. You could also use this piece of code.
gt_avg = 0
for val in a:
if val > avg:
gt_avg += 1
I'm a complete beginner to programming so forgive me for my naivete.
I wanted to make a program in Python that lets me print a given N number of prime numbers, where N is inputted by the user. I searched a little on "for/while" loops and did some tinkering. I ran a program I saw online and modified it to suit the problem. Here is the code:
i = 1
print("Hi! Let's print the first N prime numbers.")
nPrimes = int(input("Enter your N: "))
counter = 0
while True:
c = 0 #another initialization
for x in range (1, (i + 1)):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
if c == 2:
print(i, end = " ")
counter = counter + 1
if counter > = nPrimes: #if it reaches the number input, the loop will end.
break
i = i+1
print(": Are your", nPrimes, "prime number/s!")
print()
print("Thanks for trying!")
This should be able to print the amount of prime numbers the user so likes. It is a working code, though I am having difficulty trying to understand it. It seems that the variable c is important in deciding whether or not to print the variable i (which in our case is the supposed prime number during that interval).
We do c + 1 to c every time our variable a has a remainder of 0 in a = i % x. Then, if c reaches 2, the current variable i is printed, and variable c re-initializes itself to 0 once a prime number has been found and printed.
This I can comprehend, but I get confused once the numbers of i get to values 4 and onwards. *How is 4 skipped by the program and not printed when it has 2+ factors in the range that makes its remainder equal to zero? Wouldn't c == 2 for 4 and thus print 4? *And how would the program continue to the next number, 5? (Given that variable N is a large enough input).
Any clarifications would be greatly appreciated. Thank you so much!
From Wikipedia we know:
A prime number (or a prime) is a natural number greater than 1 that cannot be formed by multiplying two smaller natural numbers.
So to find a prime, is to find a natural number, aka an integer, which can only be exactly divided by 1 or itself. This is called Approach of Definition to find primes.
Hence, the following loop traverses through all integers from 1 to i,
and it counts how many times the integer i can be exactly divided by them.
for x in range (1, (i + 1)):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
And later you judge if the integer i can only be exactly divided by 1 and itself.
If true, you got a prime;
otherwise you just keep on.
if c == 2:
print(i, end = " ")
counter = counter + 1
if counter > = nPrimes: #if it reaches the number input, the loop will end.
break
Meanwhile, you can improve this prime searching algorithm a little bit by changing i = 1 to i = 2 in the beginning and adding an if statement:
# Start from 2 instead of 1
# and end at `i - 1` instead of `i`
for x in range (2, i):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
# Abandon the loop
# because an integer with factors other than 1 and itself
# is unevitably a composite number, not a prime
if c > 0:
break
if c == 0:
print(i, end = " ")
counter = counter + 1
if counter >= nPrimes: #if it reaches the number input, the loop will end.
break
This twist improves the efficiency of your program because you avoid unnecessary and meaningless amount of work.
To prevent potential infinite loop resulting from while expression,
you should replace while True: with while counter < nPrimes:. And the code turns out to be like this:
#if it reaches the number input, the loop will end.
while counter < nPrimes:
c = 0 #another initialization
# Start from 2 instead of 1
# and end at `i - 1` instead of `i`
for x in range (2, i):
a = i % x # "a" is a new variable that got introduced.
if a == 0:
c = c + 1
# Abandon the loop
# because an integer with factors other than 1 and itself
# is unevitably a composite number, not a prime
if c > 0:
break
if c == 0:
print(i, end = " ")
counter = counter + 1
i = i + 1
If you want to read more about how to improve your program's efficiency in finding primes, read this code in C language. :P
c in this case is used to count the number of numbers that divide evenly into i.
for example, if i = 8: 8 is divisible by 1, 2, 4, and 8. so c = 4 since there are 4 things that divide evenly into it
if i = 5: 5 is divisible by 1 and 5. so c = 2 since there are 2 numbers that divide evenly into it
if i = 4 (where you seem to be confused): 4 is divisible by 1, 2, and 4. so c = 3, not 2.
I wrote a recursive function to find (0,0) tuples inside of a list.
def find_tuple(l, score = 0):
for i, item in enumerate(l):
try:
if item == 0 and l[i+1] == 0:
score = score + 1
print("Number of tuples: {}".format(score))
l = l[i+2:]
find_tuple(l, score)
except:
break
return score
When I've used it i noticed strange behaviour:
>>> find_tuple([0,0])
Number of tuples: 1
1
>>> find_tuple([0,0,0])
Number of tuples: 1
1
>>> find_tuple([0,0,0,0])
Number of tuples: 1
Number of tuples: 2
1
>>> find_tuple([0,0,0,0,0,0])
Number of tuples: 1
Number of tuples: 2
Number of tuples: 3
Number of tuples: 2
2
The function returned 1 instead of 2 and 2 instead of 3 in the last two examples. Why is this happening ?
You need to return the variable for the previous function call to catch it.
replace find_tuple(l, score) with return find_tuple(l, score) inside the if statement
def find_tuple(l, score = 0):
for i, item in enumerate(l):
try:
if item == 0 and l[i+1] == 0:
score = score + 1
print("Number of tuples: {}".format(score))
l = l[i+2:]
return find_tuple(l, score)
except:
break
return score
Your recursion logic doesn't seem correct to me. You don't need to use for loop in a recursive function. You handle a part of job, reduce the problem and call the same function again to rest of the problem. At the end, use the returned value from the function. Also, you need to put a condition to stop.
Something like this could work for your problem:
def find_tuple(l, score = 0):
if len(l)<=1:
return score
if l[0] == 0 and l[1] == 0:
score += 1
return find_tuple(l[2:], score)
print(find_tuple([0,0]))
print(find_tuple([0,0,0]))
print(find_tuple([0,0,0,0]))
print(find_tuple([0,0,0,0,0,0]))
Output:
1
1
2
3
Is there any way to execute statements between the (false) evaluation of 1 elif block and the evaluation of the next in Python 3.x?
I wish to optimise my program by only running the function "word_in_special_list" should the first 2 statements of an if block evaluate as false.
Ideally the program would look something like this:
for word in lis:
#Finds word in list
if word_in_first_list(word):
score += 1
elif word_in_second_list(word):
score -= 1
#Since the first 2 evaluations return false, the following statement is now run
a, b = word_in_special_list(word)
#This returns a Boolean value, and an associated score if it's in the special list
#It is executed only if the word isn't in the other 2 lists,
#and executed before the next elif
elif a:
score += b #Add b to the running score
else:
...other things...
#end if
#end for
Of course, putting a tuple in a elif evaluation returns an error. I also can't restructure my if statement because it is more likely that the word will be in the first or second list, and so this structure saves time. So is there any way to run a code block in between 2 elif evaluations?
You would have to make an else case then nest within that
for word in lis:
if word_in_first_list(word):
score += 1
elif word_in_second_list(word):
score -= 1
else:
a, b = word_in_special_list(word)
if a:
score += b #Add b to the running score
else:
...other things...
You could put in continue statements.
for word in lis:
#Finds word in list
if word_in_first_list(word):
score += 1
continue
if word_in_second_list(word):
score -= 1
continue
a, b = word_in_special_list(word)
if a:
score += b #Add b to the running score
else:
...other things...
I think this has the effect you're trying to achieve. Incidentally, I don't see why you need the function word_in_first_list. What's wrong with if word in first_list?
I've written a small piece of code that should detect if there are any matching characters in the same place in the 2 strings. If there is , the score in incremented by 1, if there is 2 or more consecutive matching characters , the score is incremented by 3, if there is no matching character, the score is decremented by 1.
The problem is though , when i try to run the code, it gives me a error: string index out of range.
What might be wrong ? thank you very much.
def pairwiseScore(seqA, seqB):
count = 0
score = 0
while count < len(seqA):
if seqA[count] == seqB[count]:
score = score + 1
count = count + 1
while seqA[count] == seqB[count]: # This is the line the error occurs
score = score + 3
count = count + 1
elif seqA[count] != seqB[count]:
score = score - 1
count = count + 1
return score
Do both strings have the same lenght? otherwise you should consider using something like:
while count < min(len(seqA), len(seqB)):
Also, the zip function might come in handy here to pair off the letters in each word. It is a python builtin. e.g.
def letter_score(s1, s2):
score = 0
previous_match = False
z = zip(s1, s2)
for pair in z:
if pair[0] == pair[1]:
if previous_match:
score += 3
else:
score += 1
previous_match = True
else:
score -= 1
previous_match = False
return score
Indexes are numberd 0 to n.
len(someString)
will give you n + 1.
Let's say that your string is length 10, and the indexes are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
Your while loop checks the condition that count is < 10. So far so good.
Ok now let's say that count is equal to 9. Immediately within the first while loop, you increment count.
So now count = 10.
Now attempting to access someString[count] will give you an IndexError because the indices only go up to 9.
The error message says it: You're trying to access a character beyond the boundaries of your string. Consider this:
>>> s = "hello"
>>> len(s)
5
>>> s[4]
'o'
Now when (at the start of the first while loop) count is 1 below len(seqA), then you're incrementing count and then you're doing seqA[count] which will throw this exception.
Let's assume you're calling pairwisescore("a", "a"):
score = 0
count = 0
while count < len(seqA): # 0 < 1 --> OK
if seqA[count] == seqB[count]: # "a" == "a" --> OK
score = score + 1 # score = 1
count = count + 1 # count = 1
while seqA[count] == seqB[count]: # seqA[1] doesn't exist!
In the second while loop you must test that count is less than len(seqA):
while count < len(seqA) and seqA[count] == seqB[count]:
...
and, also there's possibly other bug: If the length of seqB is less than length of seqA, you'll again see runtime exception. so, you should change every occurence of count < len(seqA) with count < min(len(seqA), len(seqB)).
def pairwiseScore(seqA, seqB):
count = 0
score = 0
isOne = False
isTwoOrMore = False
while count < min(len(seqA), len(seqB)):
if seqA[count] == seqB[count]:
if isTwoOrMore:
score = score + 3
count = count + 1
else:
if isOne:
isTwoOrMore = True
score = score + 1
count = count + 1
isOne = True
elif seqA[count] != seqB[count]:
score = score - 1
count = count + 1
isOne = False
isTwoOrMore = False
return score
a = 'apple'
b = 'aplle'
print(pairwiseScore(a, b))
I think this one solve the problem, I added a "counting" bool variable. And to respond to the question, your program didn't compare the length of the second string.
while count < min(len(seqA), len(seqB)):
The problem is that you do this:
count = count + 1
Both before the inner while loop and at the end of it. But you then continue using seqA[count] before checking it against len(seqA) again - so, once it goes too high, Python will try to read past the end of seqA, and you'll get that error (when, if the condition had been checked again after incrementing, the loop would have ended).
Using a Python for loop will get around bugs like this, since Python will manage count for you:
for a,b in zip(seqA, seqB):
if a == b:
score += 1
You can implement the extra-points bit easily in this by keeping track of whether the previous character is a match, rather than trying to work out how many after this one are. A boolean variable last_matched that you keep updated would help with this.