Issue with Nested If/While/If statement - python

As a D&D aficionado, I have written out a script to perform any attack and damage rolls for any specified die, including what happens in the event of a critical attack roll (20).
from random import randint
atk_roll = 20
hit_mod = 6
atk_hit = atk_roll + hit_mod
die = 'd10'
dmg_mod = 4
rolls = 1
def dice_roller(x, y, z):
y1 = int(y.strip('d'))
dict = {}
results = []
step = 1
while step <= z:
die = randint(1,y1)
results.append(die)
step += 1
if atk_roll == 20:
total = (sum(results)+dmg_mod) + (y1*z)
pct_dmg = total / (((y1*z)+dmg_mod) + (y1*z))
else:
total = sum(results) + dmg_mod
pct_dmg = total / ((y1*z)+dmg_mod)
dict.update({'Attack Roll: ' + f'{atk_roll} + {hit_mod} = {x}':
{'Damage Roll: ' + f'{z}' + y:
{'Rolls': results, 'Total Damage': total, 'Pct_Damage': f'{pct_dmg:.0%}'}}})
print(dict)
print(dice_roller(atk_hit, die, rolls))
{'Attack Roll: 20 + 6 = 26': {'Damage Roll: 1d10': {'Rolls': [4], 'Total Damage': 18, 'Pct_Damage': '75%'}}}
None
The issue becomes when I introduce a new "if/else" statement to account for a missed attack. The only roll that does not work is a critical roll:
from random import randint
atk_roll = 20
hit_mod = 6
atk_hit = atk_roll + hit_mod
die = 'd10'
dmg_mod = 4
rolls = 1
ac = 15
def dice_roller(x, y, z):
y1 = int(y.strip('d'))
dict = {}
results = []
step = 1
if x >= ac:
while step <= z:
die = randint(1,y1)
results.append(die)
step += 1
if atk_roll == 20:
total = (sum(results)+dmg_mod) + (y1*z)
pct_dmg = total / (((y1*z)+dmg_mod) + (y1*z))
else:
total = sum(results) + dmg_mod
pct_dmg = total / ((y1*z)+dmg_mod)
dict.update({'Attack Roll: ' + f'{atk_roll} + {hit_mod} = {x}':
{'Damage Roll: ' + f'{z}' + y:
{'Rolls': results, 'Total Damage': total, 'Pct_Damage': f'{pct_dmg:.0%}'}}})
print(dict)
else:
print('Your attack missed')
print(dice_roller((atk_hit), die, rolls))
{}
None
When I change the value of "atk_roll" in the second script back to "randint(1,20)", the code works exactly as intended, noting when an attack misses or returning the dictionary of values if the attack hits. I cannot for the life of me figure out why the code is returning a blank dict only when "atk_roll" = 20. Does it have something to do with the nesting syntax of if/while/if? Thanks!

In the second code snippet you provided: the if-else block if ask_roll == 20:
will always be taken and therefore your dictionary will not be populated with values as the atk_roll value is always 20. This is because your dict is being populated in the following else.
This differs from your first piece of code as dict is updated every time the function is called as its located outside of any conditional statements.
I would need more details about what your code does to provide a detailed solution but I will attempt to give a high-level solution. If you are trying to update the dictionary regardless if your atk_roll is equal to 20 then the update should be outside the nested else block in your conditional statement checking if atk_roll is equal to 20. This code snippet is included below.
if atk_roll == 20:
total = (sum(results)+dmg_mod) + (y1*z)
pct_dmg = total / (((y1*z)+dmg_mod) + (y1*z))
else:
total = sum(results) + dmg_mod
pct_dmg = total / ((y1*z)+dmg_mod)
dict.update({'Attack Roll: ' + f'{atk_roll} + {hit_mod} = {x}':
{'Damage Roll: ' + f'{z}' + y:
{'Rolls': results, 'Total Damage': total, 'Pct_Damage': f'{pct_dmg:.0%}'}}})

Related

how to put a $ in front of my value table numbers

I'm new to python and wondering how I can put a dollar sign in this spot? i think it might have something to do with line 31 in my code but I cannot figure it out
https://i.stack.imgur.com/Flv4W.png
here is the code:
#constants
CITY_CLOSE_RATE = 2
CITY_DIST_RATE = 1
BNDRY_DIST = 20
#inputs
propValue = float(input('What is the cost of the property right now?'))
numYears = int(input('Value after how many years?'))
propDist = float(input('How far is the property from your city?'))
# select the right rate depending on the distance to the city
if propDist <= BNDRY_DIST:
rate = CITY_CLOSE_RATE
else:
rate = CITY_DIST_RATE
#calculate percantage
rate = rate / 100
#print header of the table
print(f'{"Years":>5} {"value":>15}')
# calculating property for every year. body of the table
for count in range (1, numYears +1) :
increment = propValue * rate
endVal = propValue + increment
print (f'{count:>5} {endVal :>15.2f}')
propValue= endVal
#print final prop value after appreciation
print(f'Value of the property after {count} years: ${propValue : .2f}')
One way might be to use an earlier f-string to make endVal in to a string with a $ added before. As such the for loop becomes;
for count in range (1, numYears +1):
increment = propValue * rate
endVal = propValue + increment
strEndVal = '$ ' + f'{endVal:,.2f}'
print (f'{count:>5} {strEndVal :>15}')
propValue= endVal

How to repeat the steps

In my program I have total of 3 steps.
To find the mean
Split the given list using the mean value
If the threshold value > epsilon then update mean value and repeat the step 2 again with updated mean value, else finished.
I have achieved above two steps anyhow. Third step I have achieved only half and struggling in how to repeat the step 2 till the threshold value will be less than epsilon.
My code is below:
import numpy as np
store_list = [1,2,3,1,2,3,1]
# Step 1
mean_value = np.mean(store_list)
print("Mean Value : " + str(mean_value))
# Step 2
small_list = [i for i in store_list if i <= mean_value]
big_list = [i for i in store_list if i > mean_value]
print(small_list)
print(big_list)
toe_1 = np.mean(small_list)
toe_2 = np.mean(big_list)
print("toe value 1 : " + str(toe_1))
print("toe value 2 : " + str(toe_2))
toe_sum = np.sum([toe_1, toe_2])
toe_cap = np.divide(toe_sum, 2)
print("toe cap : " + str(toe_cap))
# Step 3
new_threshold = np.subtract(mean_value, toe_cap)
print(new_threshold)
epsilon_value = 0.1
if new_threshold > epsilon_value:
mean_value = toe_cap
print("new mean : " + str(mean_value))
My output of above is:
Mean Value : 1.8571428571428572
[1, 1, 1]
[2, 3, 2, 3]
toe value 1 : 1.0
toe value 2 : 2.5
toe cap : 1.75
new threshold : 0.1071428571428572
new mean : 1.75
In this case I have to repeat the step 2 again considering new mean. I am new to Python.
I'm not able to numpy but i can imagine that all you need is a recursive runner function, i don't want to break the structure of your code, therefore i did not try to optimize the code. You can try the following code, i tried, it works:
import numpy as np
def step2(store_list, mean_value):
small_list = [i for i in store_list if i <= mean_value]
big_list = [i for i in store_list if i > mean_value]
toe_1 = np.mean(small_list)
toe_2 = np.mean(big_list)
toe_sum = np.sum([toe_1, toe_2])
toe_cap = np.divide(toe_sum, 2)
return small_list, big_list, toe_1, toe_2, toe_cap
def step3(mean_value, toe_cap):
new_threshold = np.subtract(mean_value, toe_cap)
print(new_threshold)
epsilon_value = 0.1
if new_threshold > epsilon_value:
return True, toe_cap
else:
return False, mean_value
def my_run(store_list, mean_value):
small_list, big_list, toe_1, toe_2, toe_cap = step2(store_list, mean_value)
print(small_list)
print(big_list)
print("toe value 1 : " + str(toe_1))
print("toe value 2 : " + str(toe_2))
print("toe cap : " + str(toe_cap))
condition, mean_value = step3(mean_value, toe_cap)
if condition:
print("new mean : " + str(mean_value))
my_run(store_list, mean_value)
def main():
store_list = [1, 2, 3, 1, 2, 3, 1]
mean_value = np.mean(store_list)
print("Mean Value : " + str(mean_value))
my_run(store_list, mean_value)
if __name__ == '__main__':
main()
There are 2 types of loops in python. for loops and while loops. You can achieve a "loop" by doing recursion which is just calling a function inside the same function, having a correct exit statement, like this:
def print_10_times(num, count=0):
if count < 10:
print(num)
count += 1
print_10_times(num, count)
print_10_times(5) # will print '5' 10 times
Although there are easier ways to do loops in python. The easiest loop to do when you know how many loops you will need to do beforehand, is the for loop. The above example could be executed like this:
def print_10_times(num):
for i in range(10):
print(num)
print_10_times(5) # will print '5' 10 times
The other loop you can do is the while loop. To use it you will have to have a correct exit statement in the beggining of it. If you wanted to execute the above example with a while loop it would have to look something like this:
def print_10_times(num):
i = 0
while i < 10:
print(num)
print_10_times(5) # will print '5' 10 times
For you code to work you will need to have an exit statement for every loop you'd want to use. For example maybe you wanted those 3 steps to run 2 times. You could do this:
import numpy as np
store_list = [1,2,3,1,2,3,1]
for i in range(2):
# Step 1
mean_value = np.mean(store_list)
print("Mean Value : " + str(mean_value))
# Step 2
small_list = [i for i in store_list if i <= mean_value]
big_list = [i for i in store_list if i > mean_value]
print(small_list)
print(big_list)
toe_1 = np.mean(small_list)
toe_2 = np.mean(big_list)
print("toe value 1 : " + str(toe_1))
print("toe value 2 : " + str(toe_2))
toe_sum = np.sum([toe_1, toe_2])
toe_cap = np.divide(toe_sum, 2)
print("toe cap : " + str(toe_cap))
# Step 3
new_threshold = np.subtract(mean_value, toe_cap)
print(new_threshold)
epsilon_value = 0.1
if new_threshold > epsilon_value:
mean_value = toe_cap
print("new mean : " + str(mean_value))
But this will output the same thing 2 times.
I have achieved above two steps anyhow. Third step I have achieved only half and struggling in how to repeat the step 2 till the threshold value will be less than epsilon.
You can do this with a simple while loop:
import numpy as np
store_list = [1,2,3,1,2,3,1]
# Step 1
mean_value = np.mean(store_list)
print("Mean Value : " + str(mean_value))
# Step 2
toe_cap = 3
e = np.exp(1)
while toe_cap > e:
small_list = [i for i in store_list if i <= mean_value]
big_list = [i for i in store_list if i > mean_value]
print(small_list)
print(big_list)
toe_1 = np.mean(small_list)
toe_2 = np.mean(big_list)
print("toe value 1 : " + str(toe_1))
print("toe value 2 : " + str(toe_2))
toe_sum = np.sum([toe_1, toe_2])
toe_cap = np.divide(toe_sum, 2)
print("toe cap : " + str(toe_cap))
# Step 3
new_threshold = np.subtract(mean_value, toe_cap)
print(new_threshold)
epsilon_value = 0.1
if new_threshold > epsilon_value:
mean_value = toe_cap
print("new mean : " + str(mean_value))
This loop will end when toe_cap is smaller than e (Euler's number). I assigned toe_cap a value greater than e so that the loop is run at least 1 time.
There is no problem with this because the toe_cap value isn't used in any calculations and is only reassigned in the end of the loop. It's purpose here is to be used to have a correct exit statement.
If there is any possibility that the toe_cap value will never go below e, then you would have to add a different exit statement, probably according to the number of loops that you think will be enough.

How to structure python programs? Tried making it more structured, now runs 13 times slower

Im very new to programming, I wrote a simple program for a school project and wanted to make the code "prettier" by not just having the program be one giant function but instead be made up of multiple smaller functions with a singe purpose. I seemed to have messed up royally since the program now runs 13 times slower. How should I structured the program to make it run faster and just in general make programs easier to write, read and edit?
Here are the two programs:
First program (for reference values runs in ≈0:20):
import numpy as np
import matplotlib.pyplot as plt
def graf(a,b,H,p):
GM = 39.5216489684
x_0 = a + np.sqrt(a**2 - b**2)
v_0 = np.sqrt(GM*(2/x_0 - 1/a))
konstant_period = np.sqrt(a**3)*H
h = 1/H
'''starting position given by an elliptic orbit '''
stor_x_lista = [x_0]
stor_y_lista = [0]
hastighet_x = [0]
hastighet_y = [v_0]
liten_x_lista = []
liten_y_lista = []
''' a loop that approximates the points of the orbit'''
t = 0
tid_lista = []
n = 0
while n < konstant_period:
hastighet_x.append(hastighet_x[n] - h*GM* stor_x_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_x_lista.append(stor_x_lista[n] + h*hastighet_x[n])
hastighet_y.append(hastighet_y[n] - h*GM*stor_y_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_y_lista.append(stor_y_lista[n] + h*hastighet_y[n])
'''smaller list of points to run faster'''
if n % p == 0:
liten_x_lista.append(stor_x_lista[n])
liten_y_lista.append(stor_y_lista[n])
tid_lista.append(t)
n += 1
t += h
''' function that finds the angle'''
vinkel = []
siffra = 0
while siffra < len(liten_x_lista):
if liten_y_lista[siffra ] >= 0:
vinkel.append( np.arccos( liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2)))
siffra += 1
elif liten_y_lista[siffra] < 0 :
vinkel.append( np.pi + np.arccos( -liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2) ))
siffra += 1
'''get rid of line to find periodic function'''
mod_lista = []
modn = 0
while modn < len(vinkel):
mod_lista.append(vinkel[modn] - (2*np.pi*tid_lista[modn])/np.sqrt(a**3))
modn += 1
'''make all inputs have period 1'''
squeeze_tid = []
squeezen = 0
while squeezen < len(tid_lista):
squeeze_tid.append(tid_lista[squeezen]/np.sqrt(a**3))
squeezen += 1
del mod_lista[-1:]
del tid_lista[-1:]
del squeeze_tid[-1:]
plt.plot(squeeze_tid,mod_lista)
plt.title('p(t) där a = ' + str(a) + ' och b = ' + str(b))
plt.show
Second more split up program (for reference values runs in ≈4:20):
import numpy as np
import matplotlib.pyplot as plt
'''function that generates the points of the orbit'''
def punkt(a,b,H,p):
GM = 39.5216489684
x_0 = a + np.sqrt(a**2 - b**2)
v_0 = np.sqrt(GM*(2/x_0 - 1/a))
konstant_period = np.sqrt(a**3)*H
h = 1/H
'''starting position given by an elliptic orbit '''
stor_x_lista = [x_0]
stor_y_lista = [0]
hastighet_x = [0]
hastighet_y = [v_0]
liten_x_lista = []
liten_y_lista = []
''' a loop that approximates the points of the orbit'''
t = 0
tid_lista = []
n = 0
while n < konstant_period:
hastighet_x.append(hastighet_x[n] - h*GM* stor_x_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_x_lista.append(stor_x_lista[n] + h*hastighet_x[n])
hastighet_y.append(hastighet_y[n] - h*GM*stor_y_lista[n]/(np.sqrt(stor_x_lista[n]**2 + stor_y_lista[n]**2))**3)
stor_y_lista.append(stor_y_lista[n] + h*hastighet_y[n])
'''smaller list of points to run faster'''
if n % p == 0:
liten_x_lista.append(stor_x_lista[n])
liten_y_lista.append(stor_y_lista[n])
tid_lista.append(t)
n += 1
t += h
return (liten_x_lista,liten_y_lista,tid_lista)
''' function that finds the angle'''
def vinkel(a,b,H,p):
'''import lists'''
liten_x_lista = punkt(a,b,H,p)[0]
liten_y_lista = punkt(a,b,H,p)[1]
tid_lista = punkt(a,b,H,p)[2]
'''find the angle'''
vinkel_lista = []
siffra = 0
while siffra < len(liten_x_lista):
if liten_y_lista[siffra ] >= 0:
vinkel_lista.append( np.arccos( liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2)))
siffra += 1
elif liten_y_lista[siffra] < 0 :
vinkel_lista.append( np.pi + np.arccos( -liten_x_lista[siffra]/np.sqrt( liten_x_lista[siffra]**2 + liten_y_lista[siffra]**2) ))
siffra += 1
return (vinkel_lista, tid_lista)
def periodisk(a,b,H,p):
'''import lists'''
tid_lista = vinkel(a,b,H,p)[1]
vinkel_lista = vinkel(a,b,H,p)[0]
'''get rid of linear line to find p(t)'''
mod_lista = []
modn = 0
while modn < len(vinkel_lista):
mod_lista.append((vinkel_lista[modn] - (2*np.pi*tid_lista[modn])/np.sqrt(a**3)))
modn += 1
'''make all inputs have period 1'''
squeeze_tid = []
squeezen = 0
while squeezen < len(tid_lista):
squeeze_tid.append(tid_lista[squeezen]/np.sqrt(a**3))
squeezen += 1
del mod_lista[-1:]
del tid_lista[-1:]
del squeeze_tid[-1:]
return (squeeze_tid,mod_lista)
'''fixa 3d-punkt av p(a,b) a är konstant b varierar??? '''
def hitta_amp(a):
x_b = []
y_b = []
n_b = 0.1
while n_b <= a:
x_b.append(n_b)
y_b.append(punkt(a,n_b,10**5,10**3))
return 0
def graf(a,b,H,p):
plt.plot(periodisk(a,b,H,p)[0],periodisk(a,b,H,p)[1])
plt.show
I would assume the thing that is going wrong is that the program is running the same, slow code multiple times instead of just running it once and then accessing the data. Is the problem that everything is done locally and nothing is stored globally or is it something else?
Just as a heads up, the only thing I know about programming is basic syntax, I have no clue how to actually write and run programs. I ran all the code in spyder if that affects anything.
plt.plot(periodisk(a,b,H,p)[0],periodisk(a,b,H,p)[1])
This code runs periodisk twice with the same arguments, thus at this point we know we run things at least 2 times slower.
You should do some_var = periodisk(a,b,H,p) and then some_var[0], some_var[1]. Or just use unpacking:
plt.plot(*periodisk(a,b,H,p))
tid_lista = vinkel(a,b,H,p)[1]
vinkel_lista = vinkel(a,b,H,p)[0]
Again doing the same thing twice (total: 4*time of (current) vinkel function). Again, smart assignment to fix this:
vinkel_lista, tid_lista = vinkel(a,b,H,p)
liten_x_lista = punkt(a,b,H,p)[0]
liten_y_lista = punkt(a,b,H,p)[1]
tid_lista = punkt(a,b,H,p)[2]
And now you repeat yourself thrice. (total: 12 * time of current punkt function)
liten_x_lista, liten_y_lista, tid_lista = punkt(a,b,H,p)
punkt function is like in original, so we arrived as total being 12 times slower - which quite matches your time estimations. :)
You are calling the functions once per returned list, you should only call them once.
When a method returns multiple variables, (e.g. punkt):
def punkt(a,b,H,p):
# Here is all your code
return (liten_x_lista,liten_y_lista,tid_lista)
You must be careful to only call the function once:
result = punkt(a,b,H,p)
liten_x_lista = result[0]
liten_y_lista = result[1]
tid_lista = result[2]
# As opposed to:
liten_x_lista = punkt(a,b,H,p)[0] # 1st call, ignoring results 2 and 3
liten_y_lista = punkt(a,b,H,p)[1] # 2nd call, ignoring results 1 and 3
tid_lista = punkt(a,b,H,p)[2] # 3rd call, ignoring results 1 and 2
Note: I would personally not return a list, but use python's unpacking:
def punkt(a,b,H,p):
# Here is all your code
return liten_x_lista, liten_y_lista, tid_lista
And you'd access it:
liten_x_lista, liten_y_lista, tid_lista = punkt(a,b,H,p)

Column integration in a function

I have a code which return the number of trucks required to pack the given items based on the Weight and Volume of the items. This objective of this function is to minimize the cost of transportation
Code:
from pulp import *
import numpy as np
# Item masses, volumes
item_mass = data["Weight"].tolist()
item_vol = data["Volume"].tolist()
n_items = len(item_vol)
set_items = range(n_items)
# Mass & volume capacities of trucks
truck_mass = truck["Weight"].tolist()
truck_vol = truck["Volume"].tolist()
# Cost of using each truck
truck_cost = truck["Price"].tolist()
n_trucks = len(truck_cost)
set_trucks = range(n_trucks)
y = pulp.LpVariable.dicts('truckUsed', set_trucks,
lowBound=0, upBound=1, cat=LpInteger)
x = pulp.LpVariable.dicts('itemInTruck', (set_items, set_trucks),
lowBound=0, upBound=1, cat=LpInteger)
# Model formulation
prob = LpProblem("Truck allocatoin problem", LpMinimize)
# Objective
prob += lpSum([truck_cost[i] * y[i] for i in set_trucks])
# Constraints
for j in set_items:
# Every item must be taken in one truck
prob += lpSum([x[j][i] for i in set_trucks]) == 1
for i in set_trucks:
# Respect the mass constraint of trucks
prob += lpSum([item_mass[j] * x[j][i] for j in set_items]) <= truck_mass[i]*y[i]
# Respect the volume constraint of trucks
prob += lpSum([item_vol[j] * x[j][i] for j in set_items]) <= truck_vol[i]*y[i]
# Ensure y variables have to be set to make use of x variables:
for j in set_items:
for i in set_trucks:
x[j][i] <= y[i]
prob.solve()
x_soln = np.array([[x[i][j].varValue for i in set_items] for j in set_trucks])
y_soln = np.array([y[i].varValue for i in set_trucks])
print (("Status:"), LpStatus[prob.status])
print ("Total Cost is: ", value(prob.objective))
print("Trucks used: " + str(sum(([y_soln[i] for i in set_trucks]))))
a = []
b = []
for i in set_items:
for j in set_trucks:
if x[i][j].value() == 1:
print("Item " + str(i) + " is packed in vehicle "+ str(j))
a.append(str(j))
b.append(str(i))
totalitemvol = sum(item_vol)
totaltruckvol = sum([y[i].value() * truck_vol[i] for i in set_trucks])
print("Volume of used trucks is " + str(totaltruckvol))
if(totaltruckvol >= totalitemvol):
print("Trucks are sufficient")
else:
print("Items cannot fit")
This code return the output as follows:
Status: Optimal
Total Cost is: 400000.0
Trucks used: 3.0
Item 0 is packed in vehicle 7
Item 1 is packed in vehicle 7
Item 2 is packed in vehicle 6
Item 3 is packed in vehicle 7
Item 4 is packed in vehicle 16
Item 5 is packed in vehicle 7
Item 6 is packed in vehicle 16
Item 7 is packed in vehicle 7
Item 8 is packed in vehicle 16
Item 9 is packed in vehicle 6
Item 10 is packed in vehicle 16
Volume of used trucks is 3436.0
Trucks are sufficient
Instead of getting the index of items Can I replace "Item 0" with "Item (productId)" where ProductID is a series in the "data" Dataframe.
I am happy to give the data and trucks csv files or the colab link.
Instead of "Item " + str(i) + " is packed in vehicle " + str(j) and assuming that the order of the ProductID is the same as the order of set_trucks, you could do
s = pd.Series(['item0', 'item1', 'item2'])
for i in set_items:
for j in set_trucks:
print("Item " + str(s[i]) + " is packed in vehicle " + str(j))
Since you're using Python 3, you can do it faster by using string formatting such as
print(f"Item {s[i]} is packed in vehicle {j}")

How to group a list of numbers into certain categories

I am trying to figure out how to take in a list of numbers and sort them into certain categories such as 0-10, 10-20, 20-30 and up to 90-100 but I have the code started, but the code isn't reading in all the inputs, but only the last one and repeating it. I am stumped, anyone help please?
def eScores(Scores):
count0 = 0
count10 = 0
count20 = 0
count30 = 0
count40 = 0
count50 = 0
count60 = 0
count70 = 0
count80 = 0
count90 = 0
if Scores > 90:
count90 = count90 + 1
if Scores > 80:
count80 = count80 + 1
if Scores > 70:
count70 = count70 + 1
if Scores > 60:
count60 = count60 + 1
if Scores > 50:
count50 = count50 + 1
if Scores > 40:
count40 = count40 + 1
if Scores > 30:
count30 = count30 + 1
if Scores > 20:
count20 = count20 + 1
if Scores > 10:
count10 = count10 + 1
if Scores <= 10:
count0 = count0 + 1
print count90,'had a score of (90 - 100]'
print count80,'had a score of (80 - 90]'
print count70,'had a score of (70 - 80]'
print count60,'had a score of (60 - 70]'
print count50,'had a score of (50 - 60]'
print count40,'had a score of (40 - 50]'
print count30,'had a score of (30 - 40]'
print count20,'had a score of (20 - 30]'
print count10,'had a score of (10 - 20]'
print count0,'had a score of (0 - 10]'
return eScores(Scores)
Each time eScores is called is sets all the counters (count10, count20) back to zero. So only the final call has any effect.
You should either declare the counters as global variables, or put the function into a class and make the counters member variables of the class.
Another problem is that the function calls itself in the return statement:
return eScores(Scores)
Since this function is (as I understand it) supposed to update the counter variables only, it does not need to return anything, let alone call itself recursively. You'd better remove the return statement.
One thing you're making a mistake on is that you're not breaking out of the whole set of if's when you go through. For example, if you're number is 93 it is going to set count90 to 1, then go on to count80 and set that to one as well, and so on until it gets to count10.
Your code is repeating because the function is infintely recursive (it has no stop condition). Here are the relevant bits:
def eScores(Scores):
# ...
return eScores(Scores)
I think what you'd want is more like:
def eScores(Scores):
# same as before, but change the last line:
return
Since you're printing the results, I assume you don't want to return the values of score10, score20, etc.
Also, the function won't accumulate results since you're creating new local counts each time the function is called.
Why don't you just use each number as a key (after processing) and return a dictionary of values?
def eScores(Scores):
return_dict = {}
for score in Scores:
keyval = int(score/10)*10 # py3k automatically does float division
if keyval not in return_dict:
return_dict[keyval] = 1
else:
return_dict[keyval] += 1
return return_dict

Categories