Looping over a text file list with python - python
EDIT: Have updated post for better clarity, no answers have yet to help!
Alright, so my assignment is to take a text file, that would have 4 entries per line, those being firstName, lastName, hours, payRate. I'm to do some calculations and throw all this information in a formatted table in python. Now, I've got the code to enter the data into the table, but it only works for the first entry in the text file, and I can't quite make it loop. I honestly feel like an idiot, and that this is just a simple fix.
My output is supposed to look like this:
http://i.imgur.com/bIOBqye.png
Could really use some pointers on making this loop through and print the data from each line of the text file. Here's how my current code looks:
heading1 = "{0:15s}{1:15s}{2:10s}{3:15s}{4:20s}{5:15s}".format("First Name", "Last Name", "Hours", "Payrate", "Overtime Hours", "Gross Pay")
heading2= "=============================================================================================================="
print(heading1)
print(heading2)
if os.path.isfile(fileQuestion) == True:
file = open('emps', 'r')
data = file.readlines()
for tmp in data:
data2= [word.rstrip("\n") for word in data]
first = data2[0].split()
lastName = first[0]
firstName = first[1]
first[2]=(int(first[2]))
first[3]=(int(first[3]))
initialHours = first[2]
payRate = first[3]
if initialHours > 40:
overHours = initialHours - 40
regHours = 40
regPay = payRate * regHours
otPay = overHours * (payRate * 1.5)
grossPay = regPay + otPay
else:
regHours = first[2]
grossPay = initialHours * payRate
overHours = 0
heading3= "{0:15s}{1:15s}{2:2d}{3:10d}{4:14d} {5:24.2f}".format(firstName, lastName, regHours, payRate, overHours, grossPay)
heading4= "{0:15s}{1:21.2f}".format("Total Gross Pay", grossPay)
heading5= "{0:15s}{1:19.2f}".format("Average Gross Pay", grossPay)
heading6= "{0:15s}{1:16d}".format("Total Overtime Hours", 33)
spaceHeading = " "
print(heading3)
print(spaceHeading)
print(heading4)
print(heading5)
print(heading6)
Please let me know if I haven't done this correctly or anything, first time here. Thanks.
I found the duplicate, and think some people treat rude ;/ Just not focus on pragmatic problems of programmers but on good rules of Stack in bad way :(
Here is my complete answer for your problem:
1)
First of all, you must remember that ident is used against code block's brackets known from another landuages.
I reformatted your code remember that all of lines should have extra spaces at the beginning when you pase it here ;)
2) like it was said:
first = word.split()
fix "not changing" of lines in loop.
3) Total overtime hours have hardcoded number:
heading6= "{0:15s}{1:16d}".format("Total Overtime Hours", overHours)
Also, overHours(All?) should be not "zeroed" in 'else' block in loop. You must initialize it before loop.
I change some other places i.e. some hardcoded ints, maybe it not ideal and in your style, but you have code with my fixes below...
Best, if you use GitHub or Bitbucket or another repo accesible by web, because you help to contribute if you want it, and also - yourself, to find all the changes which was done. And then, just ask here to help in extremely unknown problems. In the begging of learning it is always hard to find out, but later - you could achieve more!
Here is code after my changes:
from os.path import isfile as isFileExsist
import sys
filePath = input("What is the name of your file?: ")
while isFileExsist(filePath) == False:
pos = ['y', 'Y', 'yes', 'Yes']
neg = ['n', 'N', 'no', 'No']
answer = input("File not found! Do you want to start again? (y-yes/n-no)")
if answer in neg:
exit("Bye!")
elif answer in pos:
filePath = input("What is the name of your file?: ")
continue
else:
print("Not sure what is the answer. Try again!")
continue
file = open(filePath, 'r')
data = file.readlines()
print("{0:15s}{1:15s}{2:10s}{3:15s}{4:20s}{5:15s}".format("First Name", "Last Name", "Hours", "Payrate", "Overtime Hours", "Gross Pay"))
print("==============================================================================================================")
overHoursAll = 0
grossPayAll = 0
count = 0
for line in data:
words = line.split()
lastName = words[0]
firstName = words[1]
initialHours=(int(words[2]))
payRate =(int(words[3]))
if initialHours > 40:
regHours = 40
overHours = initialHours - 40
regPay = payRate * regHours
otPay = overHours * (payRate * 1.5)
grossPay = regPay + otPay
else:
regHours = initialHours
overHours = 0
grossPay = initialHours * payRate
grossPayAll += grossPay
overHoursAll += overHours
# heading3
print("{0:15s}{1:15s}{2:2d}{3:10d}{4:14d}{5:24.2f}".format(firstName, lastName, regHours, payRate, overHours, grossPay))
# space heading
print(" ")
# overall stats
print("{0:15s}{1:21.2f}".format("Total Gross Pay", grossPayAll))
print("{0:15s}{1:19.2f}".format("Average Gross Pay", grossPayAll / len(data)))
print("{0:15s}{1:16d}".format("Total Overtime Hours", overHoursAll))
Best regards, I am sorry for my English.
Well, I think, you probably want data2 = [word.rstrip("\n") for word in tmp], but without seeing sample input and desired output it's hard to tell.
Also,
first[2]=(int(first[2]))
first[3]=(int(first[3]))
initialHours = first[2]
payRate = first[3]
Could be:
initialHours = int(first[2])
payRate = int(first[3])
But you'd also need to change other references to first[2]
Finally, I'd change
if os.path.isfile(fileQuestion) == True:
file = open('emps', 'r')
data = file.readlines()
for tmp in data:
to:
if os.path.isfile(fileQuestion) == True:
with open('emps', 'r') as myfile:
for tmp in myfile:
This ensures that the file gets closed properly (your code doesn't close it), and iterates directly through the file, rather than using readlines() which needlessly reads the entire file to memory before doing enything else. Note that file is a python builtin, so a bad choice of variable name.
You are using these lines:
data = file.readlines()
for tmp in data:
which already splits your data into lines, and iterates through them. That means that this line [data2= [word.rstrip("\n") for word in data]] is setting data2 to be the first line EVERY TIME, which renders the original for loop useless.
Try instead:
tmp = tmp.split()
which will split each line as you iterate, you can now call tmp as a list, like you called first except it will reflect the values for each line.
You could also change your original for loop to:
for tmp in file:
since file objects in python are generators that yield each line (this saves you some memory space)
try these changes:
totothrs = 0
totgross = 0.0
employees = 0
for tmp in data:
employees += 1
fname, lname, rate, hrs = tm.split()
hrs = int(hrs)
rate = float(rate)
othrs = 0
if hrs > 40:
othrs = hrs - 40
hrs = hrs - othrs
totothrs += othrs
gross = rate * hrs + (1.5*rate)*othrs
totgross += gross
heading3= "{0:15s}{1:15s}{2:2d}{3:10d}{4:14d} {5:24.2f}".format(firstName, lastName, hrs, rate, othrs, gross)
print heading3
spaceHeading = " "
heading4= "{0:15s}{1:21.2f}".format("Total Gross Pay", totgross)
heading5= "{0:15s}{1:19.2f}".format("Average Gross Pay", (totgross/employees)
heading6= "{0:15s}{1:16d}".format("Total Overtime Hours", totothrs)
print heading4
print heading5
print heading6
Note: you dontneed to define the "headingN"'s you can just print them
import os.path
import sys
#fileQuestion = input("What is the name of your file?: ")
fileQuestion = "Testfile.txt"
heading1 = "{0:15s}{1:15s}{2:10s}{3:15s}{4:20s}{5:15s}".format("First Name", "Last Name", "Hours", "Payrate", "Overtime Hours", "Gross Pay")
heading2= "=============================================================================================================="
print(heading1)
print(heading2)
if os.path.isfile(fileQuestion) == True:
file_handle = open(fileQuestion, 'r')
#file = open('emps', 'r')
#data = file.readlines() I would't go for readline here
#file_handle2 = open('outupt.txt')
total_gross_pay = 0
number_of_employees = 0
average_gross_pay = 0
total_overtime = 0
standard_working_hours = 40
for i in file_handle:
data = i.rstrip().lstrip().split()
#print (data)
first_name, last_name, hours, payrate = data
hours = int(hours)
payrate = int(payrate)
basic_pay = hours * payrate
if(hours > standard_working_hours):
overtime = hours - standard_working_hours
overtime_premium = overtime * payrate
gross_pay = overtime_premium + basic_pay
else:
overtime = 0
gross_pay = basic_pay
total_overtime += overtime
total_gross_pay += gross_pay
number_of_employees += 1
print("{0:15s}{1:15s}{2:10s}{3:15s}{4:20s}{5:15s}".format(first_name, last_name, str(hours), str(payrate), str(overtime), str(gross_pay)))
print('\n')
print("Total Gross Pay: ",total_gross_pay)
print("Average Gross Pay: ",total_gross_pay/number_of_employees)
print("Total overtime: ",total_overtime)
Related
How to add numbers inside of a program that reads data?
I have another program which is meant to get information and then write it into a separate text doc. For this program, I want to take the data on the text doc and format it into an output. I have managed to get the formatting correct as well as the loop to read the information correctly but am struggling to get three more variables: 1) Find the total amount due between all employees added together. 2) Find the total amount of hours all the employees worked added. 3) Find the average hours worked per week. I cannot figure out how to get these variables as the information from the text doc must be in string format (to my knowledge), and i need them to be in float to do the calculations. Thanks for any help in advance! def main(): employeeCount = 0 infile = open("BillingTEST.txt","r") print("Employee Name\t\t" + "Rate\t" + "Week 1\t" + "Week 2\t" + "Week 3\t" + "Week 4\t" + "Hours\t" + "Total") name = readAsString(infile) while name != "": employeeCount += 1 rate = readAsFloat(infile) week1 = readAsFloat(infile) week2 = readAsFloat(infile) week3 = readAsFloat(infile) week4 = readAsFloat(infile) empHours = week1+week2+week3+week4 empMoney = empHours * rate print(name + "\t\t\t$" + str(rate)+ "\t" + str(week1)+"\t" + str(week2)+"\t" + str(week3)+"\t" + str(week4)+"\t" + str(empHours)+"\t" + str(empMoney)) name = readAsString(infile) print("\nTotal Billable Due:\t"+ "\nTotal Billable Hours:"+ "\nAverage Billable Hours:\t"+ "\nEmployee Count: ",employeeCount) def readAsString(file): return file.readline().rstrip("\n") def readAsFloat(file): return float(file.readline().rstrip("n")) main()
How do you replace segments in a line using fileinput
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
Extracting three kinds of info on the same line with Python
I have written a short script to extract certain data from a long text-file in Python. This the code. fname = raw_input("Enter file name: ") if ( len(fname) < 1 ) : fname = 'test.v2' rdf = open(fname) import re totalmoney = 0 totallent = 0 totaldebt = 0 for line in rdf: line = line.rstrip() money = re.findall('.*money=([0-9]*)', line) #lent = re.findall('.*money_lent=([0-9]*)', line) #debt = re.findall('.*debt=([0-9]*)', line) try: money = int(money[0]) totalmoney = totalmoney + money #lent = int(lent[0]) #totallent = totallent + lent #debt = int(debt[0]) #totaldebt = totaldebt + debt except: continue print 'money total:',totalmoney #print 'lent total:',totallent #print 'debt total:',totaldebt As you can see, the second and third meaningful data extractor lines are currently inactive (#), that is because when they are on it finds the value as zero, which I know is incorrect, because when I run them separately, they find a real value. I suspect that for some reason it cannot run all the three lines in the same loop, but I do not know why. Could you please tell me how to extract three kinds of info from the same line? Thanks.
Swallowing exceptions is not a good practice - you may never find out the reason why things go wrong. It is better not to swallow exceptions at all and do it right. This should work. fname = raw_input("Enter file name: ") if ( len(fname) < 1 ): fname = 'test.v2' rdf = open(fname) import re totalmoney = 0 totallent = 0 totaldebt = 0 for line in rdf: line = line.rstrip() money = re.search('money=([0-9]*)', line) lent = re.search('money_lent=([0-9]*)', line) debt = re.search('debt=([0-9]*)', line) if money: totalmoney = totalmoney + int(money.group(1)) if lent: totallent = totallent + int(lent.group(1)) if debt: totaldebt = totaldebt + int(debt.group(1)) print('money total:',totalmoney) print('lent total:',totallent) print('debt total:',totaldebt) Have fun playing Victoria 2 - I myself wasted a lot of time playing that game :)
What is wrong with this code during enumeration
import datetime with open("fine.txt","r") as f, open("fine1.txt","a") as fine1: lines = f.read().split("\n") for i in range(2): var = input("reg : ") # registration number(reg_num) enter = input('Time entered camera 1(24hrs)in the format HH:MM:SS: ') ext = input('Time enterd camera 2 (24hrs)in the format HH:MM:SS : ') total_time = '%H:%M:%S' enter_time = datetime.datetime.strptime(enter, total_time) ext_time = datetime.datetime.strptime(ext, total_time) if enter_time > ext_time: ext_time += datetime.timedelta(hours=24) t_diff = ext_time - enter_time time = t_diff.total_seconds() / 3600 speed = 1 / time reg = var[0:1].isalpha() and var[2:3].isdigit() and var[4].isspace() and var[5:7].isalpha() and var.isupper() if reg == True: for i, line in enumerate(lines): if var in line: num = int("{}".format(i)) var = f.read() name = (var[num]) #the problem print(name) address = (var[num + 0]) if speed > 70: print("ovrspeeding", (var[num + 0])) fine1.write(name+address+speed+"\n") The whole code had to inputted, otherwise you will not understand what i am trying to do. fine.txt is a file that has already been made and looks like: reg_num1 aaaaaaaaaaaaaaaaaaa reg_num2 bbbbbbbbbbbbbbbbbbb reg_num3 ccccccccccccccccccc this code takes in inputs of the registration number(e.g. AA01 SSS) and 2 time formats (which will later be used to calculate the speed). i want this code to find the line in fine.txt that have the registration number i inputted and if that vehicle is overspeeding(speed >70mph)the whole line needs to be appended into the file fine1.txt. the problem is that when i run the code the error massage states that: name = (var[num]) IndexError: string index out of range i dont what this means, so can you help me with this.
wrap all lines that are longer than line length
I am writing a program that limits each line to a certain length. this is what i got so far, i am almost done but i still need to cut each line, but i cant figure it out. def main(): filename = input("Please enter the name of the file to be used: ") openFile = open(filename, 'r+') file = openFile.read() lLength = int(input("enter a number between 10 & 20: ")) while (lLength < 10) or (lLength > 20) : print("Invalid input, please try again...") lLength = int(input("enter a number between 10 & 20: ")) wr = textwrap.TextWrapper() wraped = wr.wrap(file) print("Here is your output formated to a max of", lLength, "characters per line: ") wr.width = lLength wr.expand_tabs = True for lines in wraped: print(lines) Edit: def main(): filename = input("Please enter the name of the file to be used: ") openFile = open(filename, 'r') file = openFile.read() lLength = int(input("enter a number between 10 & 20: ")) while (lLength < 10) or (lLength > 20) : print("Invalid input, please try again...") lLength = int(input("enter a number between 10 & 20: ")) if (lLength > 10) or (lLength < 20): print("\nYour file contains the following text: \n" + file) #========================================================================= wr = textwrap.TextWrapper(width=lLength) wraped = wr.wrap(file) print("\n\nHere is your output formated to a max of", lLength, "characters per line: ") for lines in wraped: print(lines) main() an example of what the output SHOULD be is this. If the file specified contains this text: hgytuinghdt #here the length is 11 ughtnjuiknshfyth #here the length is 16 nmjhkaiolgytuhngjuin #here the length is 20 and the lLength is specified to 15 then this should print out: hgytuinghdt ughtnjuiknshfyt h nmjhkaiolgytuhng juin
wr = textwrap.TextWrapper() should be wr = textwrap.TextWrapper(width=length, expand_tabs=True) You should then remove wr.width = lLength and wr.expand_tabs = True. They should have been run before wr.wrap() was called, but since one can set it using keyword arguments in the TextWrapper constructor as shown at the very top, they can be removed. PS: for lines in wraped: print(lines) can be replaced with print(wraped) if you use TextWrapper.fill.
Try this: line = 'nmjhkaiolgytuhngjuin' n = 5 # set the width here a = [line[i:i+n] for i in range(0, len(line), n)] print ("\n".join(a))
This might help you: def wrap(f,n): fi=open(f,"w+") rl=fi.readlines() for i in range(0,len(rl)): if len(rl[i]) > n: fi.write(rl[i][:n] +"\n" + rl[i][n:]) fi.Close() else: fi.write(rl[i]) fi.close()