How do I make sure all of my values are computed in my loop? - python

I am working on a 'keep the change assignment' where I round the purchases to the whole dollar and add the change to the savings account. However, the loop is not going through all of the values in my external text file. It only computes the last value. I tried splitting the file but it gives me an error. What might be the issue? my external text file is as so:
10.90
13.59
12.99
(each on different lines)
def main():
account1 = BankAccount()
file1 = open("data.txt","r+") # reading the file, + indicated read and write
s = 0 # to keep track of the new savings
for n in file1:
n = float(n) #lets python know that the values are floats and not a string
z= math.ceil(n) #rounds up to the whole digit
amount = float(z-n) # subtract the rounded sum with actaul total to get change
print(" Saved $",round(amount,2), "on this purchase",file = file1)
s = amount + s
x = (account1.makeSavings(s))

I'm fairly sure the reason for this is because you are printing the amount of money you have saved to the file. In general, you don't want to alter the length of an object you are iterating over because it can cause problems.
account1 = BankAccount()
file1 = open("data.txt","r+") # reading the file, + indicated read and write
s = 0 # to keep track of the new savings
amount_saved = []
for n in file1:
n = float(n) #lets python know that the values are floats and not a string
z= math.ceil(n) #rounds up to the whole digit
amount = float(z-n) # subtract the rounded sum with actaul total to get change
amount_saved.append(round(amount,2))
s = amount + s
x = (account1.makeSavings(s))
for n in amount_saved:
print(" Saved $",round(amount,2), "on this purchase",file = file1)
This will print the amounts you have saved at the end of the file after you are finished iterating through it.

Related

Python File reading and writing

I'm currently coding a program that is supposed to:
1) Open a file which has names along with grades on each line
(I have successfully done this and put the contents of each line into an array).
2) Evaluate the data and find the max, min, and average.
I am stuck in the second part because if I try to use the max or min function pertaining to the array, I have an error code that pops up, since the values in the array are technically a string.
So my question is how do I only get the value of the numbers? Would a parallel list be more useful and if so how would I implement that?
Here's my code so far:
def getGrades(filename):
try:
gradeArray = []
with open("Grades.txt", "r") as f:
for line in f:
gradeArray.append(line.find())
except:
print("Could not open", filename)
return(gradeArray)
Optimize as needed:
minValue = 0
maxValue = 0
total = 0
first = int(gradeArray[0])
total = first
for i in range(1, len(gradeArray)):
minValue = min(first, int(gradeArray[i]))
maxValue = max(first, int(gradeArray[i]))
total = total + int(gradeArray[i])
average = total / len(gradeArray)

Python - For every value in text file?

With the code I am writing, I have split a text file up using commas, and now for each value in there, I want to make it an integer. I have tried splitting the text file and then turning it into an integer but that would not work. Is there any way of saying for all values in a file, do a certain thing? Also, the amount of values isn't concrete, it depends on the user of the programme (it is a 'shopping list' programme.
My current code:
TotalCOSTS=open("TotalCOSTS.txt","r")
Prices=TotalCOSTS.read()
print(Prices)
Prices.strip().split(",")
IntPrices=int(NewPrices)
print(len(IntPrices))
if len(IntPrices)==1:
print("Your total cost is: "+IntPrices +" Pounds")
elif len(IntPrices)>1:
FinalTotal = sum([int(num) for num in IntPrices.split(",")])
print("Your total cost is: "+ FinalTotal +" Pounds")
Prices is the file that the values are contained in, so I've stripped it of whitespace and then split it. That is where I need to continue on from.
Thank you xx
results = [int(i) for i in results]
python 3 you can do:
results = list(map(int, results))
NewPrices isn't defined in your code example
split() returns a list
The most straight-forward way to accomplish what you are trying to do is the following:
total = sum([int(x) for x in TotalCOSTS.read().split(',') if x.isdigit() == True])
But this makes some super-simplifying assumptions which won't be accurate all of the time. For example, if something costs $2.99, int() will cast this to 3. Overall, you want to consider the price in terms of cents (idk which currency you are using, but in USD, 100 cents = 1 dollar) so that $2.99 = 299 cents.
So really, you want something like this:
total = sum([float(x)*100 for x in TotalCOSTS.read().split(',') if x.isnumeric() == True])/100

How do I manipulate data in a list that has been read in from a file using Python 2.x?

I am trying to create a program that will tally the cost of ingredients within a recipe and return a total cost for said recipe. I am teaching myself Python and have set this as a personal, but practical, challenge. However, I have hit a wall. Hard.
My idea was to read a file into a list. Multiply the ingredient within the list by the comma separated numeral. Add it all together, and return a single float for the overall cost.
#Phase 1 - MASTER INGREDIENTS LIST
flour_5lb = 2.5
sugar_4lb = 2.0
butter_lb = 3.0
eggs_doz = 3.0
#PHASE 2 - COST PER UNIT CONVERSION
flour_cup = flour_5lb*(1.0/20)
sugar_cup = sugar_4lb*(1.0/8)
butter_Tbsp = butter_lb*(1.0/32)
eggs_each = eggs_doz*(1.0/12)
#PHASE THREE - RECIPE ASSESSMENT
def main():
fileObject = open("filname.txt", "r")
fileLines = fileObject.readlines()
fileObject.close()
for line in fileLines:
print line
print "\n"
if __name__ == "__main__":
main()
The for line in fileLines: statement prints the following:
flour_cup, .5
milk_cup, .4
eggs_each, 3
butter_Tbsp, 3
Press any key to continue . . .
If I understand you correctly, you have to parse your file.
For this you need to know the format in which the ingredients are being stored. Since this program is for your personal use you may just choose the most simple.
So let's assume you have your ingredients in CSV format:
sugar 10g
flour 20g
...
Then you can use pythons buildin function split and iteration to obtain a list of list [['sugar', '10g'], ['flour', '10g'], ...].
Getting the amounts into python floats is a little tricky, since we haave to concern ourselves with the units.
Again - choose a fixed set of units to make your life a little easier.
Then use the in statement or the builtin function which checks if a given string has a certain suffix. (I will leave it to you to find this function.)
Then the hard part is done. Hope I could help without giving too much away.
Part of your difficulty is knowing how to split your input on the comma -- use split(). Another problem is converting the string to a float -- use float().
Your last problem is mapping input strings to values. You could write a function that maps strings to costs:
if item == "milk_cup":
return milk_cup
if item == "flour_cup":
return flour_cup
...
...but the better way (DRY) to do it is to use a dictionary.
In my sample below I've used dict() to make the dictionary as then I don't have to quote every string.
Here's a sample:
#!/usr/bin/python
pricelist = dict(
flour_cup=1.0,
milk_cup=0.4,
)
input = ["flour_cup, 0.5", "milk_cup, 0.4"]
total = 0
for line in input:
item, qty = line.split(",")
item = item.strip()
qty = float(qty)
if item in pricelist:
cost = qty * pricelist[item]
print "%s: %.02f\n" % (item, cost)
total += cost
else:
print "I don't know what '%s' is" % item
print "Total: %.02f" % total

How to find the sum of values in a column from a text file if matching certain criteria

I'm having some trouble trying add certain values in a column from a text file together. My text file looks like:
e320,2/3/5,6661,c120,A,6661
e420,6/5/3,16916,c849,A,24323
e432,6/5/3,6962,c8429,A,4324
e430,6/5/3,4322,c8491,A,4322
e32042,2/3/5,13220,c1120,A,13220
e4202,6/5/3,4232,c8419,E,4232
I would like to find the sum of the last column's values, provided in the array the third column (final total) is equal to the last column. (amount paid.). The total of all the last column's values should only be found if the fifth column's (status) equals 'E' and finaltotal == amountpaid.
My code so far for this is:
data = open("paintingJobs.txt", "r")
info=data.readlines()
data.close
totalrev=0
for li in info:
status=li.split(",")[4]
finaltotal=int(li.split(",")[2])
amountpaid=int(li.split(",")[5])
if amountpaid == finaltotal:
revenue=True
if status == "A" and revenue == True:
totalamountpaid = li.split(",")[5]
total = (sum(totalamountpaid))
print("The total revenue is")
print(total)
My desired output would be:
The total revenue is
28435
The total should equal 28435 as 6661+4322+13220+4232=28435 (the sum of the total revenues where status equals 'A' and finaltotal=amountpaid.)
I keep receiving a "TypeError: unsupported operand type(s) for +: 'int' and 'str'". I'm using Python 3.4.3 and a complete newbie to Python. Any help would be much appreciated.
Try this.
total = (sum(totalamountpaid))
to
total = (sum(map(int,totalamountpaid.split(','))))
Split every number from the string map converting the string to int. Then sum them up.
...assuming that the third column should be equal to 'E':
data = open("test.txt", "r")
info=data.readlines()
s = sum([int(li.split(',')[5]) for li in info if li.split(",")[4]=="E" and int(li.split(",")[2])==int(li.split(",")[5])])
print("The total revenue is")
print(s)
Tested. Returns 24113, i.e. 6661+13220+4232.
You are fetching strings from your text file. That means you first need to cast the values to appropriate data type (from strings) before adding them up.
Try changing this line total = (sum(totalamountpaid)) to total = (sum(Decimal(totalamountpaid))) or total = (sum(float(totalamountpaid)))
Just need to make use of the 'totalrev' variable and add up 'amountpaid' every time the 'for loop' executed, and only adding the numbers determined by your criteria. At the end you just call it in your print statement. I removed two lines of codes you didn't need after the small change.
data = open("paintingJobs.txt", "r")
info=data.readlines()
data.close()
totalrev=0
for li in info:
status=(li.split(",")[4])
finaltotal=int(li.split(",")[2])
amountpaid=int(li.split(",")[5])
if amountpaid == finaltotal:
totalrev += amountpaid
revenue=True
if status == "E" and revenue == True:
print("The total revenue is: " + str(totalrev))
This works with the data you provided, I get 28435 which is what you were looking for
It is because at this line,
total = (sum(totalamountpaid))
the sum function is applied to a string
So using your example data, you are effective asking python to execute this
sum("4322")
which is equivalent to
0 + "4" + "3" + "2" + "2"
Of course you cannot add string to a numeric value 0. Hence the error message.
Actually there are a few many issues with your code. I think you need to make these changes to make it work. See comments (words after #) for explanation. Not tested.
data = open("paintingJobs.txt", "r")
info=data.readlines()
data.close() ## Need the '()' to call the function
totalrev=0
for li in info:
status=li.split(",")[4]
finaltotal=int(li.split(",")[2])
amountpaid=int(li.split(",")[5])
if amountpaid == finaltotal:
revenue=True
if status == "A" and revenue == True:
totalamountpaid = li.split(",")[5]
### Assuming you actually want to accumulate the sum in variable `totalrev`
totalrev += int(totalamountpaid) ### you need to convert totalamountpaid to a numeric value, and add to the running total `totalrev`
print("The total revenue is")
print(totalrev)

Combining functions in one file

infilehandle = open ("receipts-10-28-13.txt", "r")
# FUNCTIONS
def stripsigns( astring ):
"""Remove dollar signs"""
signs = "$"
nosigns = ""
for numbers in astring:
if numbers not in signs:
nosigns = nosigns + numbers
return nosigns
def totaltake():
"""Calculate total take"""
total = 0
for line in infilehandle:
values = line.split(':')
cardnumbers = values[1]
cardnumbers = stripsigns(cardnumbers)
total = (total + eval(cardnumbers))
total = round(total,2)
return total
# more code etc
def computetax(rate, total):
total = totaltake() - totaltip()
taxed = total * rate
taxed = round(taxed,2)
return taxed
# more code etc
# VARS
total = totaltake()
tips = totaltip()
tax = computetax(rate,total)
rate = eval(input("Input the tax rate as an integer:"))
# PRINT
print("Total take: $", totaltake())
print("Total tips: $", totaltips())
print("Tax owed: $", computetax(rate,total))
I'm trying to make a file that will look at elements from a txt file and then calculate things based on the numbers in the file. The functions are all either variations of the totaltake(), which is getting numbers from the file and finding the sum, or the computetax(), which takes the numbers the other functions calculate and multiplies/divides/etc. I've tested all the functions individually and they all work, but when I try to put them together in one file, it doesn't give me the output I want, and I don't know why. It prints the value of whatever is first in the vars list, and 0 for everything else -- so for the version of code I have above, it prints
Total take: $ 6533.47
Total tips: $ 0
Tax owed: $ 0
So basically, what am I doing wrong?
See Is file object in python an iterable
File objects are iterators, meaning that once a file has been iterated to completion, you cannot iterate over the file again unless it has been reset to the beginning of the file by calling file.seek(0).
When you only call totaltake(), because infilehandle has not yet been iterated, the for loop goes through all the lines in infilehandle, which is why you get the expected result.
However, when you put computetax() together with totaltake(), totaltake() gets called by itself, and then again incomputetax(). Because infilehandle has been iterated to completion the first time totaltake() is called, the for loop is not entered the second time and the initial value for total, 0, is returned.
As the value returned by totaltake() should not change, you should modify computetax() so that you can pass total as a parameter instead of calling totaltake(). You should do the same so that it also takes tips as a parameter instead of recalculating the value.
If you cannot modify computetake(), you could also seek to the beginning of infilehandle by adding infilehandle.seek(0) to the beginning of totaltake(), to allow it to be iterated again.

Categories