Why is this simple subtraction code not working - python

This is a minimal representation of my original code
x = 0
count = 0
a=30-count
while x < 10:
if True:
count = count+1
x = x+1
print("count is ",count)
print("a is ",a)
This is the output:
count is 10
a is 30
The a in the output was supposed to be 20 but the line 'a=30-count' is not working
To make it work I have to move the line 'a=30-count' just above the 'print("a is ",a)'
but I want the line 'a=30-count' in the beginning of the code
I have tried setting a as a global variable but that didn't worked
Thank you in advance also sorry if the format of my question wasn't right its my first time posting a question on this site

Python is a procedural imperative programming language and the code is run from top to bottom. When you put a=30-count at the beginning of the code, python will interpret it as a = 30 - 0 by replacing count = 0 to that line of code. So, it prints 30.
Try moving print("a is ",a) to the line right below a=30-count and you will see that a is 30.
You already know the correct way to make it works, which is to move a=30-count just above print("a is ", a) because then python is replaying count = 10 there.

a=30-count
is only called once when you initially call it. To rectify this you should call it at the end of the while loop.
x = 0
count = 0
while x < 10:
if True:
count = count+1
x = x+1
a=30-count
this gives you
count is 10
a is 20
Also
if True:
is redundant as your while loop is essentially saying while x < 10 is true continue.

Python will interpret count as 0 and a = 30-0 hence the answer. And then it will proceed to the while loop.
You while have to move the line a=30-count after the while loop.
x = 0
count = 0
while x < 10:
count +=1
x = x+1
a=30-count
print("count is",count)
print("a is",a)

This is not working because you declared the value of a before you changed the value of count,
So a has the value : 30 - 0
which is nothing but 30.
After running through the WHILE loop, the value of count changes to 10, but the value of a is not updated because it has already been declared as (30-0) earlier.
The Variable a will not keep updating every time the value of count changes, that's why you have to update it's value again.
here's the code :
count = 0
a = 30
for x in range(10):
count += 1
a -= count
print("count is ",count)
print("a is ",a)
The Output should look like this :
count is 10
a is 20

x = 0
count = 0
a=30-count
while x < 10:
if True:
count = count+1
x = x+1
print("count is ",count)
print("a is ",a)
is equavalent to
x = 0
count = 0
a=30-count
while x < 10:
count = count + 1
x = x + 1
print("count is ",count)
print("a is ",a)
Discussing the problem , python evaluates the code form top to bottom. So as the time you set a = 30-count the value of count is 0 so 'a' gets the value 30. As you said the most significant way to solve this problem is by putting line before the print statement
or
create a function
def updateA():
global a
a = 30 - count
and call the function updateA() before the print statement.
I hope this will work

When you write a = 30 - count, it doesn't "bind" variable a to variable count. It simply calculates a value for a, using the current value for count.
If you want to "save" the expression 30 - count to be reevaluated later, you can put it in a function:
def a(count):
return 30 - count
x = 0
count = 0
while x < 10:
count = count+1
x = x+1
print("count is ",count)
print("a is ",a(count))
# count is 10
# a is 20

Related

how to use while loop to determine the amount of numbers in a list that are greater the average

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

Python 3 Count updating within function, but value doesn't update outside of it

I'm guessing that there is a scope issue here that I missed somewhere. This function squares all of the numbers and adds them together. It should stop if the number hits 1 or 89, otherwise keep going. Here's my code:
count = 0
def chain(x,count):
x = str(x)
temp = 0
for let in range(0,len(x)):
temp = temp + (int(x[let]) ** 2)
x = temp
print("\n")
print(temp)
if x == 89:
count = count + 1
print(count)
elif x == 1:
return False
else:
chain(x, count)
chain(145, 0)
print(count)
The problem is, when I print count when x == 89, I get 1. But when I print count at the end, it comes out as 0. I've looked over and I don't seem to be setting it to anything else, and I've also tried adding in return, return count, return True, and nothing seems to fix it. If someone could point out my error, I would greatly appreciate it!
Solution 1:
make count a global variable
count = 0
def chain(x):
global count
x = str(x)
temp = 0
for let in range(0,len(x)):
temp = temp + (int(x[let]) ** 2)
x = temp
print("\n")
print(temp)
if x == 89:
count = count + 1
print(count)
elif x == 1:
return False
else:
chain(x)
chain(145)
print(count)
Solution 2:
return count and receive it when recursively called.
def chain(x,count):
x = str(x)
temp = 0
for let in range(0,len(x)):
temp = temp + (int(x[let]) ** 2)
x = temp
print("\n")
print(temp)
if x == 89:
count = count + 1
print(count)
elif x == 1:
pass # you may want to use -1 or something as flag
else:
count = chain(x, count)
return count
print(chain(145,0))
These are two different variables with the same name. the count outside the function will not change when the count inside the function will so printing at the end will give 0
Well, the count is not exactly a reference since it's a primitive, so you don't get the same object every time (it is immutable).
Also, the count you are referencing outside of the function is not the same you pass initially (since your first call feeds it a 0, not the same variable).
Make count a global variable by removing it from the function parameters and using the modifier global
Example
count = 0
def chain(x):
global count
...
Make the count a mutable type and pass it from the very beginning (e.g. a Class, a Dict, a list).
Example
line 01: count = {'total': 0}
line 20: chain(145, count)

While Loops - Increment a List

I'm stuck trying to figure out this while loop. It seemed simple at first but I keep running into errors. I think I just haven't used python in a while so it's hard to get back into the gist of things.
Write a while loop that will add 100 numbers to a list, starting from the number 100 and incrementing by 2 each time. For example, start from 100, then the next number added will be 102, then 104 and so on.
I have this so far;
count = 0
while count < 99:
count += 1
numbers.append(len(numbers)+2)
for x in numbers:
print(x)
But that is simply giving me 0-100 printed out when I want it to be 2,4,6,8,10,...
numbers = []
index = 0
number = 100
while index < 100:
number += 2
index += 1
numbers.append(number)
for x in numbers:
print(x)
With a few modifications, and using a while loop as per your exercise:
numbers = []
count = 0
while count < 100:
numbers.append(100 + (2*count))
count += 1
for x in numbers:
print(x)
Or with a for loop:
numbers = []
for i in range(100):
numbers.append(100 + (2*i))
for x in numbers:
print(x)
Or as a list comprehension:
numbers.extend([(100 + (2*el)) for el in range(100)])
Or as a recursion:
numbers = []
def rec(num):
if num < 100:
numbers.append(100 + (2*num))
rec(num + 1)
rec(0)
Something like this:
numbers = []
while len(numbers) != 100:
if len(numbers) > 0:
numbers.append(numbers[-1] + 2)
else:
numbers.append(100)
Little explanation:
You loop until your list has 100 elements. If list is empty (which will be at the beginning), add first number (100, in our case). After that, just add last number in list increased by 2.
Try numbers.extend(range(100, 300, 2)). It's a much shorter way to do exactly what you're looking for.
Edit: For the people downvoting, can you at least leave a comment? My initial response was prior to the question being clarified (that a while loop was required). I'm giving the pythonic way of doing it, as I was unaware of the requirement.

How do I exit this while loop?

I’m having trouble with exiting the following while loop. This is a simple program that prints hello if random value is greater than 5. The program runs fine once but when I try to run it again it goes into an infinite loop.
from random import *
seed()
a = randint(0,10)
b = randint(0,10)
c = randint(0,10)
count = 0
while True:
if a > 5 :
print ("aHello")
count = count + 1
else :
a = randint(0,10)
if b > 5 :
print ("bHello")
count = count + 1
else :
b = randint(0,10)
if c > 5 :
print ("cHello")
count = count + 1
else :
c = randint(0,10)
if count == 20 :
count = 0
break
count = 0
Your while loop might increment the variable count by 0, 1, 2 or 3. This might result in count going from a value below 20 to a value over 20.
For example, if count's value is 18 and the following happens:
a > 5, count += 1
b > 5, count += 1
c > 5, count += 1
After these operations, count's value would be 18 + 3 = 21, which is not 20. Therefore, the condition value == 20 will never be met.
To fix the error, you can either replace the line
if count == 20
with
if count >= 20
or just change your program logic inside the while loop.
Does the following code help?
while True:
if a > 5 :
print ("aHello")
count = count + 1
if count == 20 :
break
else :
a = randint(0,10)
if b > 5 :
print ("bHello")
count = count + 1
if count == 20 :
break
else :
b = randint(0,10)
if c > 5 :
print ("cHello")
count = count + 1
if count == 20 :
break
else :
c = randint(0,10)
You have to check the value of count after incrementing it every time.
The "break" condition might fail if two or more values of the variables a, b, and c are greater than 5. In that case the count will be incremented more than once and count will end up > 20, and the loop can never terminate. You should change:
if count == 20 :
to
if count >= 20:
At the end of iteration, count might be greater than 20 due to multiple increments. So I would update the last if statement to:
if count >= 20:
to feel safe.
If your goal is to stop counting when count is >= 20, then you should use that condition for your while loop and you won't need to break at all, as you only break at the end of the loop anyways.
The new while statement would look like
while count < 20:
# increment count
and then outside of the while loop you can reset count to 0 if you want to use it again for something else.
since you increment count 2 or 3 times in one iteration, it may skip past your count == 20 check
Here's one way to get exactly 20 lines.
from random import seed, randint
seed()
a = randint(0,10)
b = randint(0,10)
c = randint(0,10)
count = iter(range(20))
while True:
try:
if a > 5:
next(count)
print ("aHello")
else:
a = randint(0,10)
if b > 5:
next(count)
print ("bHello")
else:
b = randint(0,10)
if c > 5:
next(count)
print ("cHello")
else:
c = randint(0,10)
except StopIteration:
break
Note there is still a lot of repetition in this code. Storing your a,b,c variables in a list instead of as separate variables would allow the code to be simplified further

string comparison in a while loop

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.

Categories