I know that Python variables could be used when it first declared like Example 1, but when I try Example 2 without the line total = 0, it will appear NameError: 'name' total is not defined. Why?
Example 1
dmil = float(input("Enter the distance (miles): "))
dis = dmil * 1.61
print("The distance in miles {} is equal to {} in
kilometer.".format(dmil,dis))
Example 2
total = 0 #why I necessarily need this?
for i in range (1,4):
h = float(input("Enter the {} height: ".format(i)))
total = h + total
avg = total/3
print("The average height of the 3 cousins is ",avg)
It really confused me when I type programmes, is there a definition about when should I declare var at first and when should not?
total = h + total is intending to add the value of h to what total currently is.
Without having previously stated what total currently is, there is no value to add h.
In simpler terms, if you remove the total = 0 statement, walk through the code line-by-line and when you reach total = h + total, what should h + total be, it's undefined.
total = 0 is not a declaration per se: it's an initialization. It is needed because when you get to the line
total = h + total
the value of total on the RHS would be unknown. Python tries to look up the value and finds nothing by that name at that point in your program, so it complains.
Related
Little new here and any help would be appreciated.
I have been tooling around with this code for a while now and I cant seem to wrap my head around it. Im fairly new to python so I dont quite know or remember all the tricks yet/skills.
So the question at hand:
Equation: {x_(n+1) = x_n * r * (1- x_n)}
With x_n between (0,1) and r between (0,4).
The goal here is to make a loop function that will gather a value for 'x_n' and 'r' and spit out the iteration 'n' and the current 'x_n+1'; i.e. print(n , x_n+1), at each 'n' step while checking to see if the new value is within 0.0000001 of the old value.
If it settles on a fixed point within 20,000 (0.0000001), print the final 'n' + message. If not then and goes to 20,000 then print another message.
All i have so far is:
import math
x_o=float(input("Enter a 'seed' value: "))
r=float(input("Enter an 'r' value: "))
x_a=((x_o + 0) * r * (1-(x_o + 0)))
while x_a != (0.0000001, x_o , 0.0000001):
for n in range(0,99):
x_a=((x_o + n) * r * (1-(x_o + n)))
print(n , x_a)
I'm pretty sure this is no where close so any help would be awesome; if you need any more info let me know.
Much appreciated,
Genosphere
You could write a generator function and use it directly in your for loop. If you need to keep track of the rank of intermediate values you can use enumerate on the generator.
def fnIter(fn,x,delta=0.000001):
while True:
yield x
prev,x = x,fn(x)
if abs(x-prev)<delta:break
output:
r = 2
seed = 0.1
for i,Xn in enumerate(fnIter(lambda x:x*r*(1-x),seed)):
print(i,Xn)
0 0.1
1 0.18000000000000002
2 0.2952
3 0.41611392
4 0.4859262511644672
5 0.49960385918742867
6 0.49999968614491325
7 0.49999999999980305
To implement the maximum iteration check you can either add a conditional break in the loop or use zip with a range:
maxCount = 20000
n,Xn = max(zip(range(maxCount+1),fnIter(lambda x:x*r*(1-x),seed)))
if n < maxCount:
print(n,Xn)
else:
print(Xn,"not converging")
This is an exponentially-weighted moving average. Pandas has a function for this: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.ewm.html
You have a good start so far. You might be overthinking it, though.
The following approach just tries to generate this sequence for 20,000 terms. Each time, it checks whether the new value is within 0.0000001 from the previous value. If so, it breaks out of the loop and prints that. If not, it uses python's for/else construct to print a different value. Note the different levels of indentation.
x_0 = float(input("enter a 'seed' value: "))
r = float(input("enter an 'r' value: "))
x_m = x_0 # placeholder for 'previous value'
delta = 0.0000001
# Try to calculate 20 thousand terms of this sequence
# We will break out of the loop early if our x_n converges
for _ in range(20000):
x_n = x_m * r * (1 - x_m)
if abs(x_n - x_m) < delta:
print("Settled on value for x_n: ", x_n)
break
else:
x_m = x_n # move forward to the next value
else:
print("x_n did not converge in 20000 terms")
I haven't found anything even relevant to my question, so i may be asking it wrong.
I am working on an exercise where I am given sequential values starting at 1 and going to n, but not in order. I must find a missing value from the list.
My method is to add the full 1 => n value in a for loop but I can't figure out how to add n - 1 non-sequential values each as its own line of input in order to subtract it from the full value to get the missing one.
I have been searching modifications to for loops or just how to add n inputs of non-sequential numbers. If I am simply asking the wrong question, I am happy to do my own research if someone could point me in the right direction.
total = 0
for i in range (1 , (int(input())) + 1):
total += i
print(total)
for s in **?????(int(input()))**:
total -= s
print(total)
sample input:
5
3
2
5
1
expected output: 4
To fill in the approach you're using in your example code:
total = 0
n = int(input("How long is the sequence? "))
for i in range(1, n+1):
total += i
for i in range(1, n):
total -= int(input("Enter value {}: ".format(i)))
print("Missing value is: " + str(total))
That first for loop is unnecessary though. First of all, your loop is equivalent to the sum function:
total = sum(range(1,n+1))
But you can do away with any iteration altogether by using the formula:
total = int(n*(n+1)/2) # division causes float output so you have to convert back to an int
I don't know if you are supposed to create the initial data (with the missing item), so I added some lines to generate this sequence:
import random
n = 12 # or n = int(input('Enter n: ')) to get user input
# create a shuffled numeric sequence with one missing value
data = list(range(1,n+1))
data.remove(random.randrange(1,n+1))
random.shuffle(data)
print(data)
# create the corresponding reference sequence (without missing value)
data2 = list(range(1,n+1))
# find missing data with your algorithm
print("Missing value =", sum(data2)-sum(data))
Here is the output:
[12, 4, 11, 5, 2, 7, 1, 6, 8, 9, 10]
Missing value = 3
I have to create a program that shows the arithmetic mean of a list of variables. There are supposed to be 50 grades.
I'm pretty much stuck. Right now I´ve only got:
for c in range (0,50):
grade = ("What is the grade?")
Also, how could I print the count of grades that are below 50?
Any help is appreciated.
If you don't mind using numpy this is ridiculously easy:
import numpy as np
print np.mean(grades)
Or if you'd rather not import anything,
print float(sum(grades))/len(grades)
To get the number of grades below 50, assuming you have them all in a list, you could do:
grades2 = [x for x in grades if x < 50]
print len(grades2)
Assuming you have a list with all the grades.
avg = sum(gradeList)/len(gradeList)
This is actually faster than numpy.mean().
To find the number of grades less than 50 you can put it in a loop with a conditional statement.
numPoorGrades = 0
for g in grades:
if g < 50:
numPoorGrades += 1
You could also write this a little more compactly using a list comprehension.
numPoorGrades = len([g for g in grades if g < 50])
First of all, assuming grades is a list containing the grades, you would want to iterate over the grades list, and not iterate over range(0,50).
Second, in every iteration you can use a variable to count how many grades you have seen so far, and another variable that sums all the grades so far. Something like that:
num_grades = 0
sum_grades = 0
for grade in grades:
num_grades += 1 # this is the same as writing num_grades = num_grades + 1
sum_grades += sum # same as writing sum_grades = sum_grades + sum
Now all you need to do is to divide sum_grades by num_grades to get the result.
average = float(sum_grade)s / max(num_grades,1)
I used the max function that returns the maximum number between num_grades and 1 - in case the list of grades is empty, num_grades will be 0 and division by 0 is undefined.
I used float to get a fraction.
To count the number of grades lower than 50, you can add another variable num_failed and initialize him to 0 just like num_counts, add an if that check if grade is lower than 50 and if so increase num_failed by 1.
Try the following. Function isNumber tries to convert the input, which is read as a string, to a float, which I believe convers the integer range too and is the floating-point type in Python 3, which is the version I'm using. The try...except block is similar in a way to the try...catch statement found in other programming languages.
#Checks whether the value is a valid number:
def isNumber( value ):
try:
float( value )
return True
except:
return False
#Variables initialization:
numberOfGradesBelow50 = 0
sumOfAllGrades = 0
#Input:
for c in range( 0, 5 ):
currentGradeAsString = input( "What is the grade? " )
while not isNumber( currentGradeAsString ):
currentGradeAsString = input( "Invalid value. What is the grade? " )
currentGradeAsFloat = float( currentGradeAsString )
sumOfAllGrades += currentGradeAsFloat
if currentGradeAsFloat < 50.0:
numberOfGradesBelow50 += 1
#Displays results:
print( "The average is " + str( sumOfAllGrades / 5 ) + "." )
print( "You entered " + str( numberOfGradesBelow50 ) + " grades below 50." )
I wrote a simple program to calculate average outcome of a dice throw (pretty pointless, but you have to start somewhere ;P):
import random, time
from random import randrange
count = 0
total = 0
one_count = 0
for x in range(10000000):
random = randrange(1,7)
count = count + 1
total = total + random
average = total / count
percentage = one_count / count * 100
if random == 1:
one_count = one_count + 1
print("the percentage of ones occurring is", percentage, "and the average outcome is", average)
# time.sleep(1)
To clean it up I want the output to overwrite the previous line. I tried everything I could find, but the only thing I managed to to is to print to the same line without erasing the previous content by changing the last line to:
print("the percentage of ones occuring is", percentage, "and the average outcome is", average, "/// ", end="")
which outputs:
the percentage of ones occuring is 0.0 and the average outcome is 4.0 /// the percentage of ones occuring is 0.0 and the average outcome is 4.5 /// the percentage of ones occuring is 0.0 and the average outcome is 3.6666666666666665 ///
Any ideas?
Add a \r at the end. That way, the next line you write will start at the beginning of the previous line. And then flush output so it shows immediately.
Note: If the next line is shorter, the remaining characters will still be there.
use end='\r:
for x in range(100000):
rnd = randrange(1,7) # don't use random
count += 1
total = total + rnd
average = total / count
percentage = one_count / count * 100
if rnd == 1:
one_count += 1
print("the percentage of ones occurring is {} and the average outcome is {}".format(percentage,average),end='\r')
time.sleep(.1)
On another note using total = total + random is not a good idea, you are importing the random module and using random as a variable name.
In python: how do I divide an int received by a user from a list while every time it runs in the for loop I need to divide the value I received from the round before in the next round?
This is my code:
a = input('price: ')
b = input('cash paid: ')
coin_bills = [100, 50, 20, 10, 5, 1, 0.5]
if b >= a:
for i in coin_bills:
hef = b - a
print (hef / i), '*', i
else:
print 'pay up!'
Example: a=370 b=500 ---> b-a=130
Now in the loop I will receive (when i=100) 1, and (when i=50) I will receive 2 but I want in the second round (when i=50) to divide 30 (130[=b-a]- 100[=answer of round 1*i]) by 50.
What do I need to change in the code?
Thanks!
You just need to subtract the amount of change you give back at each step from the total amount of change you're returning. It's much easier to see if you change your variable names to something meaningful:
price= int(raw_input('price: ')) # Use int(raw_input()) for safety.
paid= int(raw_input('cash paid: '))
coin_bills=[100,50,20,10,5,1,0.5]
if paid >= price:
change = paid - price
for i in coin_bills:
# Use // to force integer division - not needed in Py2, but good practice
# This means you can't give change in a size less than the smallest coin!
print (change // i),'*',i
change -= (change // i) * i # Subtract what you returned from the total change.
else:
print 'pay up!'
You could also clear up the output a bit by only printing the coins/bills that you actually return. Then the inner loop might look something like this:
for i in coin_bills:
coins_or_bills_returned = change // i
if coins_or_bills_returned: # Only print if there's something worth saying.
print coins_or_bills_returned,'*',i
change -= coins_or_bills_returned * i
OK, I'm assuming that you're trying to calculate change for a transaction using a number of types of bills.
The problem is that you need to keep a running tally of how much change you have left to pay out. I used num_curr_bill to calculate how many of the current bill type you're paying out, and your hef I changed to remaining_change (so it would mean something to me) for the remaining change to pay.
a= input('price: ')
b= input('cash paid: ')
coin_bills=[100,50,20,10,5,1,0.5]
if b>=a:
# Calculate total change to pay out, ONCE (so not in the loop)
remaining_change = b-a
for i in coin_bills:
# Find the number of the current bill to pay out
num_curr_bill = remaining_change/i
# Subtract how much you paid out with the current bill from the remaining change
remaining_change -= num_curr_bill * i
# Print the result for the current bill.
print num_curr_bill,'*',i
else:
print 'pay up!'
So, for a price of 120 and cash paid 175, the output is:
price: 120
cash paid: 175
0 * 100
1 * 50
0 * 20
0 * 10
1 * 5
0 * 1
0.0 * 0.5
One bill for 50 and one for 5 add up to 55, the correct change.
Edit: I'd go more sparingly on the comments in my own code, but I added them here for explanation so that you could more clearly see what my thought process was.
Edit 2: I would consider removing the 0.5 in coin_bills and replacing 1 with 1.0, since any fractional amounts will wind up being fractions of 0.5 anyway.