Related
this maybe simple but how can I automatize this:
for example, this is just for 2 steps but I want to do the same for 100
should I use looping or another kind of function
def earn(w,y):
return w+y
def spend(w,x):
new_wealth = w -x
if new_wealth < 0:
print("Insufficient funds")
else:
return new_wealth
w0=0
w1=earn(w0,2300)
w2=spend(w1,1500)
w3=earn(w2,2300)
w4=spend(w3,1500)
print("w0,w1,w2,w3,w4 = ", w0,w1,w2,w3,w4)
To repeat the same action, you should obviously use loops.
Here is an example using a "for" loop with 100 iterations, appending each operation result in a list:
results = []
w = 0
for _i in range(100):
w = earn(w, 2300)
results.append(w)
w = spend(w, 1500)
results.append(w)
print(results) # [2300, 800, 3100, 1600, 3900, 2400 ... ]
You should obviously modify it for your purpose.
if you had a list of transactions with weather it was a spend or earn and the value you could try something like this
transactions = ['earn 2300', 'spend 1500', 'earn 2300', 'spend 1500']
string = ''
results = [0]
for n in range(len(transactions)):
string += 'w'+str(n)
transactions_type = transactions[n].split(' ')[0]
transactions_value = int(transactions[n].split(' ')[1])
if transactions_type.lower() == 'earn':
results.append(earn(results[-1], transactions_value))
if transactions_type.lower() == 'spend':
results.append(spend(results[-1], transactions_value))
output = string + ' = '
for value in results:
output += str(value)
which outputs
w0,w1,w2,w3,w4 = 0 2300 800 3100 1600
but this would depend on how you are storing this transaction information the method here works but is not ideal
I am creating a program for counting coins and I want to create a mechanism which essentially scans a specifically written text file and is able to calculate whether it has been falsely counted but also will replace the ending segment of the line with either Y for Yes or N for No.
The txt file reads as such:
Abena,5p,325.00,Y
Malcolm,1p,3356.00,Y
Jane,£2,120.00,Y
Andy,£1,166.25,N
Sandip,50p,160.00,Y
Liz,20p,250.00,Y
Andy,20p,250.00,Y
Andy,50p,160.00,Y
Jane,£1,183.75,N
Liz,£,179.0,N
Liz,50p,170.0,N
Jane,50p,160.0,Y
Sandip,£1,183.0,N
Jane,£2,132.0,N
Abena,1p,3356.0,N
Andy,2p,250.0,N
Abena,£1,175.0,Y
Malcolm,50p,160.0,Y
Malcolm,£2,175.0,N
Malcolm,£1,175.0,Y
Malcolm,1p,356.0,Y
Liz,20p,250.0,Y
Jane,£2,120.0,Y
Jane,50p,160.0,Y
Andy,£1,175.0,Y
Abena,1p,359.56,N
Andy,5p,328.5,N
Andy,£2,108.0,N
Malcolm,£2,12.0,N
as you can see every line is split into 4 segments, I want the fileinput to be able to replace the fourth segment within the specified line.
My program (all the relevant things to see right now) is as follows:
class Volunteer:
def __init__(self, name, coin_type, weight_of_bag, true_count):
self.name = name
self.coin_type = coin_type # a function allowing me to class the data
self.weight_of_bag = weight_of_bag
self.true_count = true_count
just a simple object system to make things easier for later
with open("CoinCount.txt", "r", encoding="'utf-8'") as csvfile:
volunteers = []
for line in csvfile:
volunteers.append(Volunteer(*line.strip().split(',')))
just to create a list as well as an object for easier calculations
def runscan():
with open("CoinCount.txt", "r+", encoding='utf-8') as csvfile:
num_lines = 0
for line in csvfile:
num_lines = num_lines + 1
i = 0
while i < num_lines:
ct = (volunteers[i].coin_type)
wob = float(volunteers[i].weight_of_bag)
if ct == ("£2" or "2"):
accurate_weight = float(12.0)
limit = 10
bag_value = 10 * 12
elif ct == ("£1" or "1"):
accurate_weight = float(8.75)
limit = 20
bag_value = 20 * 8.75
elif ct == "50p":
accurate_weight = float(8)
limit = 20
bag_value = 20 * 8
elif ct == "20p":
accurate_weight = float(5)
limit = 50
bag_value = 5 * 50
elif ct == "10p":
accurate_weight = float(6.5)
limit = 50
bag_value = 6.5 * 50
elif ct == "5p":
accurate_weight = float(3.25)
limit = 100
bag_value = 3.25 * 100
elif ct == "2p":
accurate_weight = float(7.12)
limit = 50
bag_value = 50 * 7.12
elif ct == "1p":
accurate_weight = float(3.56)
limit = 100
bag_value = 3.56 * 100
number_of_bags = wob / bag_value
print("Number of bags on this is" + str(number_of_bags))
import fileinput
line = line[i]
if number_of_bags.is_integer():
with fileinput.FileInput('CoinCount.txt',inplace=True) as fileobj:
for line in fileobj:
x = line.split(',')
for w, word in enumerate(x):
if w == 3 and word == 'N':
print(line[i].replace('N', 'Y'), end='')
i = i + 1
else:
i = i + 1
else:
with fileinput.FileInput('CoinCount.txt',inplace=True) as fileobj:
for line in fileobj:
x = line.split(',')
for w, word in enumerate(x):
if w == 3 and word == 'Y':
print(line[i].replace('Y', 'N'), end='')
i = i + 1
else:
i = i + 1
and finally the thing Im having issues with, the scan function.
the issue is specifically within the last few lines of code here (the replacement part):
import fileinput
if number_of_bags.is_integer():
target, replacement = ('N', 'Y')
else:
target, replacement = ('Y', 'N')
with fileinput.FileInput('CoinCount.txt', inplace=True) as fileobj:
for i, line in enumerate(fileobj):
words = line.rstrip().split(',')
if line.words[3] == target:
line.words[3] = replacement
print(','.join(words))
i = i + 1
f = fileobj.lineno() # Number of lines processed.
print(f'Done, {f} lines processed')
I basically have created a function which goes down each line and calculates the next line down until there aren't anymore lines, the issue with the last part is that I am unable to replace the actual txt file, If I were to run this program right now the result would be a completely blank page. I know that the fix is most likely a simple but tricky discovery but It is really bothering me as this is all that is needed for my program to be complete.
I understand the majority of the coding used but I am very new to fileinput, I want to be able to go from each line and replace the final segment if the segments name (i.e "Y" or "N") given is inaccurate to the actual legitimate segment name as Y is for true and N is for false. Please help, I tried to make sure this question was as easily understandable as possible, please make your example relatable to my program
As far as I understood, the problem is whether the calculation of the weight is correct or not. So just create another file instead of using fileinput. Do you really need it ?
test.csv
Abena,5p,325.00,Y
Malcolm,1p,3356.00,Y
Read the csv and assign some header names
Remove the last column, we don't care if it's correct or not, we will calculate the result anyways
Gather your calculation function in one method, we will apply this to every row
Apply function to every row, if it's correct write "Y" else write "N"
Truncate the whole file and write it over
import pandas as pd
with open("test.csv", "r+") as f:
df = pd.read_csv(f, names=["name", "coin", "weight", "res"])
del df["res"]
def calculate(row):
if row["coin"] == "5p":
return "Y" if 3.25 * 100 == row["weight"] else "N"
elif row["coin"] == "1p":
return "Y" if 3.56 * 100 == row["weight"] else "N"
df["res"] = df.apply(lambda row: calculate(row), axis=1)
f.seek(0)
f.truncate()
df.to_csv(f, index=False, header=False)
test.csv
Abena,5p,325.0,Y
Malcolm,1p,3356.0,N
I have 2 separate pandas dataframes, one of which tracks whether the platform of a train station is free or not and another which tracks the movement of the trains (note I am only at proof-of-concept stage, I appreciate my code is not tidy).
Code is as below:
L = []
M = []
x = 0
for i in range(0,k*2):
L.append(0)
M.append(x)
if (i == k):
x = 1
list_of_tuples = list(zip(M, L))
blocks_df = pd.DataFrame(list_of_tuples, columns = ['Direction', 'BlockTaken'])
L = ["London Depot", "London Platform", "Birmingham Platform", "Crossover"]
M = [0,0,0,0]
list_of_tuples = list(zip(L, M))
stations_control = pd.DataFrame(list_of_tuples, columns = ['Location', 'BlockTaken'])
for i in range (0,3600):
if (i%300==0): #Every 5 minutes, a new train enters service
print("Train " + str(TrainNumber) + " leaving depot for " + str(train_df.loc[train_df['Train_Number'] == TrainNumber, 'Start_Station'].iloc[0]) + " at " + str(t.time()) )
train_df.loc[train_df['Train_Number'] == TrainNumber, 'Dep'] = 'N'
train_df.loc[train_df['Train_Number'] == TrainNumber, 'Dep_Time'] = t.time()
train_df.loc[train_df['Train_Number'] == TrainNumber, 'From'] = L[0]
train_df.loc[train_df['Train_Number'] == TrainNumber, 'To'] = L[1]
if(stations_control[train_df.loc[train_df['Train_Number'] == TrainNumber, 'To']]['BlockTaken'] ==0):
print("Platform is free!!!")
t = t + datetime.timedelta(0,300)
#TrainNumber+=1
I know I am doing the if statement 4 lines from the end wrong, but I can't figure out how to do it properly. What I want to check is where the train is going and if the platform is free, print. What is the correct syntax here?
I think it is
b = train_df.loc[train_df['Train_Number'] == TrainNumber, 'To'].iloc[0]
if(stations_control.loc[stations_control['Location']==b]['BlockTaken'] == 0):
Answering my own question here. Thanks for the help guys.
if(stations_control.loc[stations_control['Location']==b].BlockTaken.iloc[0]== 0):
print("Platform is free!!!")
Basically in the last for loop the k variable uses the number of items in the list and then I have a false and unique answer rather than multiple answers I want to do some sort of n roots of a complex number (if my question isn't clear sorry i'm not a native english speaker I'll do my best to make it clearer)
from math import *
deg = int(input("entrez le degré:"))
re = int(input("le réel:"))
im = int(input("l'imaginaire:"))
counter = 0
while counter < deg:
counter = counter + 1
kkk = []
kkk.append(counter)
r = sqrt(pow(re,2)+pow(im,2))
if im != 0:
teton = round(pi/radians(degrees(acos(re/r))),1)
else:
teton = round(pi/radians(degrees(acos(im/r))),1)
if round(r) != r:
r = "sqrt(",(pow(re,2)+pow(im,2)),")"
else:
r = r
teta = "pi/%s" %teton
print("z = ",r,"e^i",teta,)
for k in kkk:
if re != 0 or im != 0:
print(r,"e^i*2*",teta,"*",k,"pi")
else:
print(r,"^1/",deg,"e^i(",teta,"/",deg," +(2",k,"pi)/",deg)
print(k)
If I understood the problem correctly, you are saying that for loop is not iterating over all the items in the list kkk.
if you check your code the list kkk always have only one item as you are initializing and appending item in same loop.
please move below statement out of the first loop.
kkk = []
like below.
from math import *
deg = int(input("entrez le degré:"))
re = int(input("le réel:"))
im = int(input("l'imaginaire:"))
counter = 0
kkk = []
while counter < deg:
counter = counter + 1
kkk.append(counter)
r = sqrt(pow(re,2)+pow(im,2))
if im != 0:
teton = round(pi/radians(degrees(acos(re/r))),1)
else:
teton = round(pi/radians(degrees(acos(im/r))),1)
if round(r) != r:
r = "sqrt(",(pow(re,2)+pow(im,2)),")"
else:
r = r
teta = "pi/%s" %teton
print("z = ",r,"e^i",teta,)
for k in kkk:
if re != 0 or im != 0:
print(r,"e^i*2*",teta,"*",k,"pi")
else:
print(r,"^1/",deg,"e^i(",teta,"/",deg," +(2",k,"pi)/",deg)
print(k)
This program pulls data out of two .CSV files, which are linked here:
https://drive.google.com/folderview?id=0B1SjPejhqNU-bVkzYlVHM2oxdGs&usp=sharing
It's supposed to look for anything after a comma in each of the two files, but my range logic is somehow wrong. I'm running a traceback error to line 101:
"line 101, in calc_corr: sum_smokers_value = sum_smokers_value + float(s_percent_smokers_data[r][1])
IndexError: list index out of range"
I assume it would do the same for the other times [k][1] shows up.
many thanks in advance if there's a way to fix this.
the program so far is:
# this program opens two files containing data and runs a corralation calculation
import math
def main():
try:
print('does smoking directly lead to lung cancer?')
print('''let's find out, shall we?''''')
print('to do so, this program will find correlation between the instances of smokers, and the number of people with lung cancer.')
percent_smokers, percent_cancer = retrieve_csv()
s_percent_smokers_data, c_percent_cancer_data = read_csv(percent_smokers, percent_cancer)
correlation = calc_corr(s_percent_smokers_data, c_percent_cancer_data,)
print('r_value =', corretation)
except IOError as e:
print(str(e))
print('this program has been cancelled. run it again.')
def retrieve_csv():
num_times_failed = 0
percent_smokers_opened = False
percent_cancer_opened = False
while((not percent_smokers_opened) or (not percent_cancer_opened)) and (num_times_failed < 5):
try:
if not percent_smokers_opened:
percent_smokers_input = input('what is the name of the file containing the percentage of smokers per state?')
percent_smokers = open(percent_smokers_input, 'r')
percent_smokers_opened = True
if not percent_cancer_opened:
percent_cancer_input = input('what is the name of the file containing the number of cases of lung cancer contracted?')
percent_cancer = open(percent_cancer_input, 'r')
percent_cancer_opened = True
except IOError:
print('a file was not located. try again.')
num_times_failed = num_times_failed + 1
if not percent_smokers_opened or not percent_cancer_opened:
raise IOError('you have failed too many times.')
else:
return(percent_smokers, percent_cancer)
def read_csv(percent_smokers, percent_cancer):
s_percent_smokers_data = []
c_percent_cancer_data = []
empty_list = ''
percent_smokers.readline()
percent_cancer.readline()
eof = False
while not eof:
smoker_list = percent_smokers.readline()
cancer_list = percent_cancer.readline()
if smoker_list == empty_list and cancer_list == empty_list:
eof = True
elif smoker_list == empty_list:
raise IOError('smokers file error')
elif cancer_list == empty_list:
raise IOError('cancer file error')
else:
s_percent_smokers_data.append(smoker_list.strip().split(','))
c_percent_cancer_data.append(cancer_list.strip().split(','))
return (s_percent_smokers_data, c_percent_cancer_data)
def calc_corr(s_percent_smokers_data, c_percent_cancer_data):
sum_smokers_value = sum_cancer_cases_values = 0
sum_smokers_sq = sum_cancer_cases_sq = 0
sum_value_porducts = 0
numbers = len(s_percent_smokers_data)
for k in range(0, numbers):
sum_smokers_value = sum_smokers_value + float(s_percent_smokers_data[k][1])
sum_cancer_cases_values = sum_cancer_cases_values + float(c_percent_cancer_data[k][1])
sum_smokers_sq = sum_smokers_sq + float(s_percent_smokers_data[k][1]) ** 2
sum_cancer_cases_sq = sum_cancer_cases_sq + float(c_percent_cancer_data[k][1]) ** 2
sum_value_products = sum_value_products + float(percent_smokers[k][1]) ** float(percent_cancer[k][1])
numerator_value = (numbers * sum_value_products) - (sum_smokers_value * sum_cancer_cases_values)
denominator_value = math.sqrt(abs((numbers * sum_smokers_sq) - (sum_smokers_value ** 2)) * ((numbers * sum_cancer_cases_sq) - (sum_cancer_cases_values ** 2)))
return numerator_value / denominator_value
main()
The values in each row of your data files are not comma separated, but rather tab separated. You need to change the ',' delimiter character you're splitting on for '\t'. Or perhaps use the csv module and tell it that your delimiter is '\t'. You can read more about the csv module in the documentation.