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

Python

Can 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

Your 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.

I 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?

Here'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.

def main():
  endProgram = 'no'
  while endProgram == 'no':
    option = 0
    print ('Enter 1 to enter in new data and store to file')
    print ('Enter 2 to display data from the file')
    option = int(input('Enter now ->'))

    # declare variables
    pints = [0] * 7
    totalPints = 0
    averagePints = 0

    if option == 1:
      # function calls
      pints = getPints(pints)
      totalPints =getTotal(pints, totalPints)
      averagePints = getAverage(totalPints, averagePints)
      writeToFile(averagePints, pints)

    else:
      readFromFile(averagePints, pints) 

    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): ')

#the getPints function
def getPints(pints):
   counter = 0
   while counter < 7:
     pints[counter] = input('Enter pints collected: ')
     counter = counter + 1
   return pints

#the getTotal function
def getTotal(pints, totalPints):
   counter = 0
   while counter < 7:
     totalPints = int(totalPints) + int(pints[counter])
     counter = counter + 1
   return totalPints

#the getAverage function
def getAverage(totalPints, averagePints):
   averagePints = float(totalPints)/7
   return averagePints

#the writeToFile function
def writeToFile(averagePints, pints):
   outFile = open('blood.txt', 'a')
   outFile.write('Pints Each Hour: '+'\n') 
   counter = 0
   while counter < 7:
     outFile.write(str(pints[counter])+'\n')
     counter = counter + 1
   outFile.write('Average Pints: '+'\n') 
   outFile.write(str(averagePints) + '\n\n')
   outFile.close()

#the readFromFile function
def readFromFile(averagePints, pints):
   inFile = open('blood.txt', 'r')
   str1 = inFile.read()
   print (str1)
   pints = inFile.read()
   print (pints)
   print #adds a blank line
   averagePints = inFile.read()
   print (averagePints)
   inFile.close()

# calls main
main()

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.

In that code the call to the writeToFile method happens within the same iteration of the loop that pints, totalPints and averagePints gets 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 writeToFile had been split into it's own option then you would have ended up with the same issue.

Oh, ok, that makes sense, too. Thank you for helping me to understand this better.

I 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.

Nope still just 0's.

You 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.

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 28,732 Points

First 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

Thank 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.

That 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
MOD
Jeff Muday
Treehouse Moderator 28,732 Points

I 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

Jeff, 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.