Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial
Cheri Castro
226 PointsCan someone pin point why my data won't write to my file? My results are all 0's.
Also, either in my writeToFile or my readFromFile, it's repeating the statements. I've listed the results below. Please, help...
def main():
endProgram = 'no'
while endProgram == 'no':
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
option = 0
print ('Enter 1 to enter new data')
print ('Enter 2 to display to the screen')
print ('Enter 3 to write savings to the file')
print ('Enter 4 to read savings from the file')
option = int(input('Enter option now: '))
notGreenCost = [0] * 12
goneGreenCost = [0] * 12
savings = [0] * 12
if option == 1:
notGreencost = getNotGreen(notGreenCost, months)
goneGreenCost = getGoneGreen(goneGreenCost, months)
savings = energySaved(notGreenCost, goneGreenCost, savings)
elif option == 2:
displayInfo(notGreenCost, goneGreenCost, savings, months)
elif option == 3:
writeToFile(months, savings)
elif option == 4:
readFromFile(months, savings)
endProgram = input('Do you want to end program? (Enter no or yes): ')
while not (endProgram == 'yes' or endProgram == 'no'):
print ('Please enter a yes or no')
endProgram = input('Do you want to end program? (Enter no or yes): ')
def getNotGreen(notGreenCost, months):
counter = 0
while counter < 12:
print ('Enter NOT GREEN energy costs for', months[counter])
notGreenCost[counter] = input('Enter now -->')
counter = counter + 1
print ('-------------------------------------------------')
return notGreenCost
def getGoneGreen(goneGreenCost, months):
counter = 0
while counter < 12:
print ('Enter GONE GREEN energy costs for', months[counter])
goneGreenCost[counter] = input('Enter now -->')
counter = counter + 1
print ('-------------------------------------------------')
return goneGreenCost
def energySaved(notGreenCost, goneGreenCost, savings):
counter = 0
while counter < 12:
savings[counter] = int(notGreenCost[counter]) - int(goneGreenCost[counter])
counter = counter + 1
return savings
def displayInfo(notGreenCost, goneGreenCost, savings, months):
counter = 0
print (' SAVINGS ')
print ('_____________________________________________________')
print ('SAVINGS NOT GREEN GONE GREEN MONTH')
print ('_____________________________________________________')
while counter < 12:
print ('$', savings[counter], ' $', notGreenCost[counter], ' $', goneGreenCost[counter], ' ', months[counter] )
counter = counter + 1
return notGreenCost, goneGreenCost, savings, months
def writeToFile(months, savings):
outFile = open('savings1.txt', 'a')
outFile.write('Energy Savings: '+'\n')
counter = 0
while counter < 12:
outFile.write(str(months[counter]) + '\n')
outFile.write(str(savings[counter]) + '\n')
counter = counter + 1
outFile.write(str(savings) + '\n\n')
outFile.close()
def readFromFile(months, savings):
inFile = open('savings1.txt', 'r')
months = inFile.read()
print (months)
savings = inFile.read()
print (savings)
inFile.close()
main()
Enter 1 to enter new data
Enter 2 to display to the screen
Enter 3 to write savings to the file
Enter 4 to read savings from the file
Enter option now: 1
Enter NOT GREEN energy costs for January
Enter now -->789
Enter NOT GREEN energy costs for February
Enter now -->790
Enter NOT GREEN energy costs for March
Enter now -->890
Enter NOT GREEN energy costs for April
Enter now -->773
Enter NOT GREEN energy costs for May
Enter now -->723
Enter NOT GREEN energy costs for June
Enter now -->759
Enter NOT GREEN energy costs for July
Enter now -->690
Enter NOT GREEN energy costs for August
Enter now -->681
Enter NOT GREEN energy costs for September
Enter now -->782
Enter NOT GREEN energy costs for October
Enter now -->791
Enter NOT GREEN energy costs for November
Enter now -->898
Enter NOT GREEN energy costs for December
Enter now -->923
-------------------------------------------------
Enter GONE GREEN energy costs for January
Enter now -->546
Enter GONE GREEN energy costs for February
Enter now -->536
Enter GONE GREEN energy costs for March
Enter now -->519
Enter GONE GREEN energy costs for April
Enter now -->493
Enter GONE GREEN energy costs for May
Enter now -->472
Enter GONE GREEN energy costs for June
Enter now -->432
Enter GONE GREEN energy costs for July
Enter now -->347
Enter GONE GREEN energy costs for August
Enter now -->318
Enter GONE GREEN energy costs for September
Enter now -->453
Enter GONE GREEN energy costs for October
Enter now -->489
Enter GONE GREEN energy costs for November
Enter now -->439
Enter GONE GREEN energy costs for December
Enter now -->516
-------------------------------------------------
Do you want to end program? (Enter no or yes): no
Enter 1 to enter new data
Enter 2 to display to the screen
Enter 3 to write savings to the file
Enter 4 to read savings from the file
Enter option now: 2
SAVINGS
_____________________________________________________
SAVINGS NOT GREEN GONE GREEN MONTH
_____________________________________________________
$ 0 $ 0 $ 0 January
$ 0 $ 0 $ 0 February
$ 0 $ 0 $ 0 March
$ 0 $ 0 $ 0 April
$ 0 $ 0 $ 0 May
$ 0 $ 0 $ 0 June
$ 0 $ 0 $ 0 July
$ 0 $ 0 $ 0 August
$ 0 $ 0 $ 0 September
$ 0 $ 0 $ 0 October
$ 0 $ 0 $ 0 November
$ 0 $ 0 $ 0 December
Do you want to end program? (Enter no or yes): no
Enter 1 to enter new data
Enter 2 to display to the screen
Enter 3 to write savings to the file
Enter 4 to read savings from the file
Enter option now: 3
Do you want to end program? (Enter no or yes): no
Enter 1 to enter new data
Enter 2 to display to the screen
Enter 3 to write savings to the file
Enter 4 to read savings from the file
Enter option now: 4
SavingsJanuary
0
February
0
March
0
April
0
May
0
June
0
July
0
August
0
September
0
October
0
November
0
December
0
Savings:
January
0
February
0
March
0
April
0
May
0
June
0
July
0
August
0
September
0
October
0
November
0
December
0
Energy Savings:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Savings:
January
0
February
0
March
0
April
0
May
0
June
0
July
0
August
0
September
0
October
0
November
0
December
0
Energy Savings:
Energy Savings:
January
0
February
0
March
0
April
0
May
0
June
0
July
0
August
0
September
0
October
0
November
0
December
0
Energy Savings:
January
0
February
0
March
0
April
0
May
0
June
0
July
0
August
0
September
0
October
0
November
0
December
0
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Do you want to end program? (Enter no or yes): yes
>>>
3 Answers
andren
28,558 PointsYour results are all zeroes because you set them all to 0 at the begging of the program loop, before you are given the option to save or display them.
In other words after you enter have gone though and given a value to the notGreenCost and goneGreenCost their values are immediately reset as the program starts over from the top of the loop.
This can be fixed by simply moving the variable declarations outside the loop like this:
def main():
endProgram = 'no'
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October',
'November', 'December']
notGreenCost = [0] * 12
goneGreenCost = [0] * 12
savings = [0] * 12
while endProgram == 'no':
option = 0
print('Enter 1 to enter new data')
print('Enter 2 to display to the screen')
print('Enter 3 to write savings to the file')
print('Enter 4 to read savings from the file')
option = int(input('Enter option now: '))
if option == 1:
notGreencost = getNotGreen(notGreenCost, months)
goneGreenCost = getGoneGreen(goneGreenCost, months)
savings = energySaved(notGreenCost, goneGreenCost, savings)
elif option == 2:
displayInfo(notGreenCost, goneGreenCost, savings, months)
elif option == 3:
writeToFile(months, savings)
elif option == 4:
readFromFile(months, savings)
endProgram = input('Do you want to end program? (Enter no or yes): ')
while not (endProgram == 'yes' or endProgram == 'no'):
print('Please enter a yes or no')
endProgram = input('Do you want to end program? (Enter no or yes): ')
I moved the months variable outside the loop as well, that's technically not necessary but it's also not necessary to have it in the loop so putting it outside makes your code more efficient. In general you should also be careful about what you put inside a loop, only things that truly need to be performed multiple times should be placed inside. Anything that should only be set once or only needs to be set once should go outside.
When you complain about the saved file "repeating the statements" are you talking about the fact that it saves multiple energy reports? If so then that is because you open the file using the a mode which tells Python to append to the file rather than overwriting it. If you switch it to write mode like this:
def writeToFile(months, savings):
outFile = open('savings1.txt', 'w')
outFile.write('Energy Savings: ' + '\n')
counter = 0
while counter < 12:
outFile.write(str(months[counter]) + '\n')
outFile.write(str(savings[counter]) + '\n')
counter = counter + 1
outFile.write(str(savings) + '\n\n')
outFile.close()
Then you will only get one report written to the file which will be overwritten each time you write to it.
Jeff Muday
Treehouse Moderator 28,732 PointsFirst off-- nice job on the program, your code is clear and easy to follow. It makes your code easy to fix!
The reason why readFromFile() is producing zeros is that in Python the parameters of the function (month and savings) are passed by value rather than passed by reference -- which means when we change months and savings in the function, these are not changed in main().
To fix this situation, change one line in the main() function to assign values returned from readFromFile() (see the line commented)
def main():
endProgram = 'no'
while endProgram == 'no':
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
option = 0
print ('Enter 1 to enter new data')
print ('Enter 2 to display to the screen')
print ('Enter 3 to write savings to the file')
print ('Enter 4 to read savings from the file')
option = int(input('Enter option now: '))
notGreenCost = [0] * 12
goneGreenCost = [0] * 12
savings = [0] * 12
if option == 1:
notGreencost = getNotGreen(notGreenCost, months)
goneGreenCost = getGoneGreen(goneGreenCost, months)
savings = energySaved(notGreenCost, goneGreenCost, savings)
elif option == 2:
displayInfo(notGreenCost, goneGreenCost, savings, months)
elif option == 3:
writeToFile(months, savings)
elif option == 4:
months, savings = readFromFile() # change this to have month, savings as the assigned return values
endProgram = input('Do you want to end program? (Enter no or yes): ')
while not (endProgram == 'yes' or endProgram == 'no'):
print ('Please enter a yes or no')
endProgram = input('Do you want to end program? (Enter no or yes): ')
Now... change readFromFile() to take no parameters since these are not used as input. And at the bottom return months and savings as a tuple.
def readFromFile(): # change the definition to take no parameters
inFile = open('savings1.txt', 'r')
months = inFile.read()
print (months)
savings = inFile.read()
print (savings)
inFile.close()
return (months, savings) # add this return of your months and savings objects
Cheri Castro
226 PointsThank you, I'm really trying here. I have tried what the first gentleman suggested and it worked. I'm also going to go back and try what you stated so that if there's more than one way to solve this issue, then in the future I'll be aware of both methods. Thank you for your suggestions, and your encouragement. I don't know what a tuple is yet. We haven't covered that, in my college class and I haven't gotten far enough in the treehouse Python classes in order to figure that out yet. I'll have to look that one up.
Cheri Castro
226 PointsThat suggestion didn't work. It returned all 0's again. Maybe I didn't do something right.
def main():
endProgram = 'no'
while endProgram == 'no':
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
option = 1
print ('Enter 1 to enter new data')
print ('Enter 2 to display to the screen')
print ('Enter 3 to write savings to the file')
print ('Enter 4 to read savings from the file')
option = int(input('Enter option now: '))
notGreenCost = [0] * 12
goneGreenCost = [0] * 12
savings = [0] * 12
if option == 1:
notGreencost = getNotGreen(notGreenCost, months)
goneGreenCost = getGoneGreen(goneGreenCost, months)
savings = energySaved(notGreenCost, goneGreenCost, savings)
elif option == 2:
displayInfo(notGreenCost, goneGreenCost, savings, months)
elif option == 3:
writeToFile(months, savings)
elif option == 4:
months, savings = readFromFile()
endProgram = input('Do you want to end program? (Enter no or yes): ')
while not (endProgram == 'yes' or endProgram == 'no'):
print ('Please enter a yes or no')
endProgram = input('Do you want to end program? (Enter no or yes): ')
def getNotGreen(notGreenCost, months):
counter = 0
while counter < 12:
print ('Enter NOT GREEN energy costs for', months[counter])
notGreenCost[counter] = input('Enter now -->')
counter = counter + 1
print ('-------------------------------------------------')
return notGreenCost
def getGoneGreen(goneGreenCost, months):
counter = 0
while counter < 12:
print ('Enter GONE GREEN energy costs for', months[counter])
goneGreenCost[counter] = input('Enter now -->')
counter = counter + 1
print ('-------------------------------------------------')
return goneGreenCost
def energySaved(notGreenCost, goneGreenCost, savings):
counter = 0
while counter < 12:
savings[counter] = int(notGreenCost[counter]) - int(goneGreenCost[counter])
counter = counter + 1
return savings
def displayInfo(notGreenCost, goneGreenCost, savings, months):
counter = 0
print (' SAVINGS ')
print ('_____________________________________________________')
print ('SAVINGS NOT GREEN GONE GREEN MONTH')
print ('_____________________________________________________')
while counter < 12:
print ('$', savings[counter], ' $', notGreenCost[counter], ' $', goneGreenCost[counter], ' ', months[counter] )
counter = counter + 1
return notGreenCost, goneGreenCost, savings, months
def writeToFile(months, savings):
outFile = open('savings1.txt', 'a')
outFile.write('Energy Savings: '+'\n')
counter = 0
while counter < 12:
outFile.write(str(months[counter]) + '\n')
outFile.write(str(savings[counter]) + '\n')
counter = counter + 1
outFile.close()
def readFromFile():
inFile = open('savings1.txt', 'r')
months = inFile.read()
print (months)
savings = inFile.read()
print (savings)
inFile.close()
return months, savings
main()
Jeff Muday
Treehouse Moderator 28,732 PointsI also noticed-- readFromFile() needs a little additional tweaking, see below.
You will learn more "Pythonic" ways to write this as you progress on your Python learning, but for now you can read the file line-by-line and strip off the '\n' newline character.
def readFromFile():
months = []
savings = []
inFile = open('savings1.txt', 'r')
heading = inFile.readline().strip() # read the heading, strip removes '\n' character
while True:
# read month line in file, strip() removes '\n' character
this_month = inFile.readline().strip()
if not this_month:
# we read all the lines, close the file break out of loop
inFile.close()
break
months.append(this_month)
# read savings this month, strip() removes '\n' character
this_savings = inFile.readline().strip()
savings.append(this_savings)
print (months)
print (savings)
return months, savings
Another way to write it is by taking the entire file into a list called "data". The heading is in data[0] and the months and savings lines are interleaved, so you can use slicing operations to read those. This isn't such a good practice for parsing a file, but it achieves what your original code appeared to be going for.
def readFromFile(filename='savings1.txt'):
with open(filename,'r') as inFile:
data = inFile.read().split('\n')
# file is automatically closed once this code block completes
heading = data[0] # get the heading (for illustration purposes)
months = data[1:-1:2] # start at second element, skip by 2 (end at next to last element)
savings = data[2::2] # start at third element, skip by 2 (continue to end)
return months, savings # return lists
Cheri Castro
226 PointsJeff, ok, thank you for the elaboration on that. I think you are way ahead of me. I look forward to getting to that point though.
Cheri Castro
226 PointsCheri Castro
226 PointsI tried what you suggested. It worked, thank you. It makes sense what you said about changing the 'a' to a 'w'. It kinda makes sense about moving the variables outside the loop and that it was giving a result of all 0's because it kept resetting for each option 1-4 that I chose. However, I wrote another one similar to this but it only had two options and the variables were inside the loop and at first it did return all 0's as well but I changed something, I don't remember what but I didn't move the variables outside the loop and it returned the values. Would it have something to do with the fact that it only had two options to choose from?
Cheri Castro
226 PointsCheri Castro
226 PointsHere's the other one that worked, with the variables in the loop. I kept comparing these two when this new one wouldn't work. I also kept having to delete the writeToFile, in order to run a new set of input, so the 'w' would have helped with that.
If you can see why this one worked as opposed to the second one, please let me know so, hopefully I'll be able to recognize it next time. Thank you for your input. I'm also going to try what the other gentleman wrote, to see if there's more than one way to solve this issue, for future reference.
andren
28,558 Pointsandren
28,558 PointsIn that code the call to the
writeToFilemethod happens within the same iteration of the loop thatpints,totalPintsandaveragePintsgets populated. Meaning that the loop does not start from the top until after the data has been written.In other words the variables are still reset at the beginning of the loop but it doesn't really matter in this program since the file has already been written with the proper values, and the values are not needed when you enter new data.
If the call to
writeToFilehad been split into it's own option then you would have ended up with the same issue.Cheri Castro
226 PointsCheri Castro
226 PointsOh, ok, that makes sense, too. Thank you for helping me to understand this better.
Cheri Castro
226 PointsCheri Castro
226 PointsI think I just have one more question, if you don't mind, if I had not set the option to 0 (option = 0), then, as I had it wrote, would it have made any difference? I'm going to try it but I'm just curious on the explanation.
Cheri Castro
226 PointsCheri Castro
226 PointsNope still just 0's.
andren
28,558 Pointsandren
28,558 PointsYou answered your own question, but I'll still chime in. The core of your issue was that the loop restarted after you inserted your data, and at the top of your loop the variables are redeclared with the values you defined them with.
Nothing besides moving the variables out of the loop will fully fix that issue in your code. And moving the variables is technically better for performance reasons as well, since redeclaring those variables during each loop is unnecessary.