-2

I have been working with some code that is meant to print a poem. The goal of the code is to make borders that will fit the poem's size. But that does not pertain to my issue. I have been trying to get the code to reprint a file, line for line, but ValueError: I/O operation on closed file. is all that is returned.

I've attempted to get around this by reopening the file after it's closed, and reopening it after the def poemprint(poem): function has completed. But both methods have failed. I don't know where to go from here.

import os
os.system("clear")

quitw=["no","n","ney","ne","nope","nuh-uh","nuh","noh","neigh","nye","negative","please no","no               please","quit","stop","q","s"]
harlem=open("harlem.txt","r")
hhop=open("hhop.txt","r")
poems={"1":harlem,"2":hhop}
poemname={"1":"harlem.txt","2":"hhop.txt"}

#10 lines of def quit() code

def poemprint(poem):
    print("╭"+"-"*60+"╮")
    print("|  Poem Printer [v0.5]"+" "*39+"|")
    print("⊢"+"-"*60+"⊣")
    print("|"+" "*60+"|")
    for a in poem: #line where error occurs
        b=57-len(a)
        print("|    "+a[0:len(a)-1]+(" "*b)+"|")
    print("|"+" "*60+"|")
    print("╰"+"-"*60+"╯")
    poem.close()
    if f=="harlem.txt": #doesn't work
        harlem=open("harlem.txt","r")
    elif f=="hhop.txt":
        hhop=open("hhop.txt","r")

c=(input("Enter a Poem: "))
if c not in quitw:
    while c not in quitw:
        while c.lower() in poems:
            os.system("clear")
            f=poemname[c]
            poemprint(poems[c])
            c=(input("Enter a Poem: "))
            if c in quitw:
                quit()
            else:
                continue
        os.system("clear")
        print("Invalid input.")
        c=(input("Enter a Poem: "))
else:
    quit()

Note: quit() is a defined function to stop the code entirely.

This is what I should be seeing after asking for the Harlem poem for the second time:

    ╭------------------------------------------------------------╮
    |  Poem Printer [v0.5]                                       |
    ⊢------------------------------------------------------------⊣
    |                                                            |
    |    Harlem by Langston Hughes                               |
    |                                                            |
    |      What happens to a dream deferred?                     |
    |                                                            |
    |        Does it dry up                                      |
    |        like a raisin in the sun?                           |
    |        Or fester like a sore—                              |
    |        And then run?                                       |
    |        Does it stink like rotten meat?                     |
    |        Or crust and sugar over—                            |
    |        like a syrupy sweet?                                |
    |                                                            |
    |        Maybe it just sags                                  |
    |        like a heavy load.                                  |
    |                                                            |
    |        Or does it explode?                                 |
    |                                                            |
    ╰------------------------------------------------------------╯

Instead, I'm getting:

    ╭------------------------------------------------------------╮
    |  Poem Printer [v0.5]                                       |
    ⊢------------------------------------------------------------⊣
    |                                                            |
    Traceback (most recent call last):
      File "main.py",line 44, in <module>
        poemsprint(poems[c])
      File "main.py",line 27, in poemprint
        for a in poem:
    ValueError: I/O operation of closed file.
OSA413
  • 387
  • 2
  • 4
  • 16
KiKUP
  • 13
  • 5
  • 1
    It seems that you didn't include the call of the `poemprint` function. Please provide a [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help%5Cmcve) so I will be able to help you. – OSA413 Feb 09 '19 at 18:21
  • @OSA413 I've attempted to make a code that replicated the error, but I can't figure it out. It's simple this code that is producing this error. – KiKUP Feb 09 '19 at 18:32
  • you're closing the file handle in poemprint, but you're opening it from outside it. It only works once. The next call, the file is closed. make your function symmetric – Jean-François Fabre Feb 09 '19 at 20:25
  • @Jean-FrançoisFabre I closed and opened the file after ```poemprint(poems[c])``` but it's still returning the same error. – KiKUP Feb 09 '19 at 20:29
  • You have a bug, but this is bad practice. So just don't do this. open & close the file in the subprogram. If you have to read it more than once, make a list of the lines instead – Jean-François Fabre Feb 09 '19 at 20:32
  • @Jean-FrançoisFabre I got some help from someone else, and it's fairly easy to fix the bug without having to move the file into a life (which would take ages). Thanks for the suggestions though. – KiKUP Feb 09 '19 at 21:47

1 Answers1

0

Your steps are:

  1. You open a file in harlem variable
  2. You call poemprint function with harlem argument. This harlem is referenced as poem inside of the function.
  3. You close the file that poem references to (it is harlem outside of the function)
  4. You create a new variable harlem that exists only inside of the function
  5. After the function is done, you have harlem as a closed file

This happens because harlem in the poemprint and the one outside are different objects.

Short example:

def a():
    var = 2

var = 1
a()

print(var) #prints 1

You can read more about this in mgilson's answer on a question that covers similar problem and in the Python documentation.

How to fix:

Instead of opening the files, keep their names.

poems={"1":"harlem.txt","2":"hhop.txt"}

Then modify the function to get the filename as the argument and to open the file inside of the function.

def poemprint(poem):
    print("╭"+"-"*60+"╮")
    print("|  Poem Printer [v0.5]"+" "*39+"|")
    print("⊢"+"-"*60+"⊣")
    print("|"+" "*60+"|")

    poem = open(poem, "r") #This
    for a in poem:
        b=57-len(a)
        print("|    "+a[0:len(a)-1]+(" "*b)+"|")
    print("|"+" "*60+"|")
    print("╰"+"-"*60+"╯")
    poem.close()
    #End of the function

Now it should work.

Enter a Poem: 1
╭------------------------------------------------------------╮
|  Poem Printer [v0.5]                                       |
⊢------------------------------------------------------------⊣
|                                                            |
|    Roses are red                                           |
|    Violets are blue                                        |
|                                                            |
╰------------------------------------------------------------╯
Enter a Poem: 1
╭------------------------------------------------------------╮
|  Poem Printer [v0.5]                                       |
⊢------------------------------------------------------------⊣
|                                                            |
|    Roses are red                                           |
|    Violets are blue                                        |
|                                                            |
╰------------------------------------------------------------╯
Enter a Poem: 

Here's the full code:

import os
os.system("clear")

quitw=["no","n","ney","ne","nope","nuh-uh","nuh","noh","neigh","nye","negative","please no","no               please","quit","stop","q","s"]
poems={"1":"harlem.txt","2":"hhop.txt"}

#10 lines of def quit() code

def poemprint(poem):
    print("╭"+"-"*60+"╮")
    print("|  Poem Printer [v0.5]"+" "*39+"|")
    print("⊢"+"-"*60+"⊣")
    print("|"+" "*60+"|")

    poem = open(poem, "r") #This
    for a in poem:
        b=57-len(a)
        print("|    "+a[0:len(a)-1]+(" "*b)+"|")
    print("|"+" "*60+"|")
    print("╰"+"-"*60+"╯")
    poem.close()

c=(input("Enter a Poem: "))
if c not in quitw:
    while c not in quitw:
        while c.lower() in poems:
            os.system("clear")
            f=poems[c]
            poemprint(poems[c])
            c=(input("Enter a Poem: "))
            if c in quitw:
                quit()
            else:
                continue
        os.system("clear")
        print("Invalid input.")
        c=(input("Enter a Poem: "))
else:
    quit()

OSA413
  • 387
  • 2
  • 4
  • 16