Hello everybody! Me again with an other question :)
I have a file with a list and 3 functions in it; view, sort, append.
I used pickle to save data changes in to an other file (films.db).
Imagine you want to use this programe for the first time on your system so there is no db file correct?
You should type python favemoviese.py view or favemovies.py append.... At this time the script must creat the db file immidiately beacuse there was no primary db file, right?

And then you should be able to append your word to the list because the db file has been created jaut a few seconds ago.
But when i do type python favemovies.py append or view, an error appears that say there is no db file to load data from, and after that an empty db file will be created immidiately.
Why? How can i create the db file first.

Really orry for long discribtion!! I just didnt know how to explaine the problem, just wanted to make it clear.

I've type this above all functions:

    #!/usr/bin/env python3
    # -*-coding: utf8-*-

    filename = 'films.db'
    target = open (filename, 'a')


    import pickle

    favorite_movies=[]

    favorite_movies = pickle.load( open("films.db", "rb"))

    def append():

I want filename and target work first to create the db file but the programe reads the pickle.load line first.

Recommended Answers

All 14 Replies

You can create a pickle file containing an empty list of favorite movies

#!/usr/bin/env python3
# -*-coding: utf8-*-

import os
import pickle

# use db file in the same folder as
# our program (this could be different)
filename = 'films.db'
folder = os.path.dirname(os.path.abspath(__file__))
filepath = os.path.join(folder, filename)


if not os.path.isfile(filepath): # <- file does not exist
    with open(filepath, 'wb') as fout:
        pickle.dump([], fout) # <- dump an empty fav movies list in file

# The 'with' construct ensures that the file is
# properly closed after the with block
with open(filepath, 'rb') as fin:
        favorite_movies = pickle.load(fin)

Well, here is a question for me....
Where should i put your codes?
All of them above the first functio?
I mean the first function must start from the line number 22?!

In fact it does not matter. However, a standard program pattern is

# shebang line (#! ...)
# coding

"""program docstring
"""

# imports ...
import os
import pickle

# some global constants
MYCONSTANT = 733

# functions and class definitions

def spam():
    ...

class Eggs():
    ...

# module level code
statement
statement

# script level code
if __name__ == "__main__":
    statement
    statement
    statement

With this design, my code could go in the module level code at the end, or in a function's body returning the fav movies list, which could be called from the module level code section.

Of course, python allows you to write the code anywhere.

Well, i added your code to the end of my code, but this is the error i got:

Traceback (most recent call last):
  File "test.py", line 12, in <module>
    favorite_movies = pickle.load( open("films.db", "rb"))
IOError: [Errno 2] No such file or directory: 'films.db'

Let mee add sth!!
Here you see tesst.py on the error message, it's the same as favemovies.py i'm working on it. I just use test.py with the same body for changing and testing codes.

Without the exact code, it is impossible to debug. For example in my code, there is no pickle.load( open("films.db", "rb")).

#!/usr/bin/env python3
# -*-coding: utf8-*-

filename = 'films.db'
target = open (filename, 'a')

import pickle

favorite_movies=[]

favorite_movies = pickle.load( open("films.db", "rb"))

def append():
    import sys
    movie_name = str(sys.stdin.readline())
    favorite_movies = pickle.load( open("films.db", "rb"))
    favorite_movies.append(movie_name)
    pickle.dump(favorite_movies, open("films.db", "wb"))
    print (favorite_movies)
def sort():
    favorite_movies.sort()
    print (favorite_movies)
def view():
    favorite_movies = pickle.load( open("films.db", "rb"))
    print (favorite_movies)

if __name__ == "__main__":

    import argparse
    parser = argparse.ArgumentParser(description='Execute a function')
    parser.add_argument('funcname',
    help='name of function to execute',
    metavar='FUNCNAME',
    choices=['view' , 'sort' , 'append'])
args = parser.parse_args()
function = globals()[args.funcname]
function()

That is the main code without adding your code.

Ok, here is a way. Try to understand every detail

#!/usr/bin/env python3
# -*-coding: utf8-*-
import os
import pickle

DBFILENAME = 'films.db'
loaded = False
favorite_movies = [] 

def pathtofile(filename=DBFILENAME):
    """Return absolute path to the db file"""
    # use db file in the same folder as
    # our program (this could be different)
    folder = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(folder, filename)

def load_favorite():
    global favorite_movies, loaded
    if loaded:
        return
    filepath = pathtofile()
    if not os.path.isfile(filepath): # <- file does not exist
        with open(filepath, 'wb') as fout:
            pickle.dump([], fout) # <- dump an empty fav movies list in file

    # The 'with' construct ensures that the file is
    # properly closed after the with block
    with open(filepath, 'rb') as fin:
        favorite_movies = pickle.load(fin)
    loaded = True

def dump_favorite():
    filepath = pathtofile()
    with open(filepath, 'wb') as fout:
        pickle.dump(favorite_movies, fout)

def append():
    import sys
    movie_name = str(sys.stdin.readline())
    load_favorite()
    favorite_movies.append(movie_name)
    dump_favorite()
    print (favorite_movies)

def sort():
    load_favorite()
    favorite_movies.sort()
    print (favorite_movies)

def view():
    load_favorite()
    print (favorite_movies)

if __name__ == "__main__":

    import argparse
    parser = argparse.ArgumentParser(description='Execute a function')
    parser.add_argument('funcname',
    help='name of function to execute',
    metavar='FUNCNAME',
    choices=['view' , 'sort' , 'append'])
    args = parser.parse_args()
    function = globals()[args.funcname]
    function()

Yesssssssssssss!!! It works :)
@Gribouillis, Thank you so much.

@Gribouillis, i didnt understand some details, whould you mind explaining each of them for me, please?

I will put the parts i didn't understand clearly:
Thank you :)

#!/usr/bin/env python3
# -*-coding: utf8-*-
import os
import pickle

DBFILENAME = 'films.db'
loaded = False          #What does this line do?
favorite_movies = []

#can you explain each line of this function please?
def pathtofile(filename=DBFILENAME):
    """Return absolute path to the db file"""
    # use db file in the same folder as
    # our program (this could be different)
    folder = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(folder, filename)

#And can you explain each line of this function too please? 
def load_favorite():
    global favorite_movies, loaded
    if loaded:
        return
    filepath = pathtofile()
    if not os.path.isfile(filepath): # <- file does not exist
        with open(filepath, 'wb') as fout:
            pickle.dump([], fout) # <- dump an empty fav movies list in file

    # The 'with' construct ensures that the file is
    # properly closed after the with block
    with open(filepath, 'rb') as fin:
        favorite_movies = pickle.load(fin)
    loaded = True

#And also each line of this function too please? 
#What does FOUNT word do here? Is it a keyword?
def dump_favorite():
    filepath = pathtofile()
    with open(filepath, 'wb') as fout:
        pickle.dump(favorite_movies, fout)

Sorry, was long part of codes but i just want to learn. I love programming specially in Python :)

Ok, here is the code section with comments. I hope it helps

#!/usr/bin/env python3
# -*-coding: utf8-*-
import os
import pickle

DBFILENAME = 'films.db'

# The next line initializes a variable named 'loaded' to the value False
# This variable tells us if the database of favorite movies has
# already been loaded.
loaded = False

favorite_movies = [] 

def pathtofile(filename=DBFILENAME):
    # The __file__ variable contains a string giving
    # the location of the current program in the file
    # system. The following line computes the absolute
    # path of the directory containing this program
    # (print it to see its value)
    folder = os.path.dirname(os.path.abspath(__file__))

    # the next line returns the absolute path
    # to the location of the dbfile that we want
    # to use. Computing this carefully allows
    # us to robustly call this program from
    # any folder.
    return os.path.join(folder, filename)

def load_favorite():
    # this global declaration (at the beginning of
    # the function's body) tells python that we are
    # going to give new values to these global variables
    # If we don't write this, python thinks that these
    # are local variables, and writing statements such as
    # loaded = True
    # would have no effect on the outer variable 'loaded'
    global favorite_movies, loaded

    # if the fav list has already been loaded, we don't
    # do anything and exit the function
    if loaded:
        return

    filepath = pathtofile()
    if not os.path.isfile(filepath): # <- file does not exist
        # the db file does not exist. We open it for writing
        # and dump an empty python list with pickle in order
        # to initialize it. We open files with a *with* block,
        # which is the best way to work with open files.
        # 'fout' is only a variable name for the opened file.
        # you can replace it with another name
        # such as 'strawberryfields'. fout is mnemotechnics,
        # it reminds us that this is a file opened for output.
        with open(filepath, 'wb') as fout:
            pickle.dump([], fout) # <- dump an empty fav movies list in file

    # Now we open the file for reading
    # Again we use a with block, and fin is
    # our file variable, opened for input
    with open(filepath, 'rb') as fin:
        favorite_movies = pickle.load(fin)

    # We set the variable 'loaded' to True
    # to remember that the list has been loaded.
    loaded = True

def dump_favorite():
    # see above for explanation
    filepath = pathtofile()
    with open(filepath, 'wb') as fout:
        pickle.dump(favorite_movies, fout)

Thank you so much, were clear comments :) Thank you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.