Personal archive tool, looking for suggestions on improving the code

Discussion in 'Python' started by mo reina, Jul 27, 2010.

  1. mo reina

    mo reina Guest

    0 down vote favorite


    i've written a tool in python where you enter a title, content, then
    tags, and the entry is then saved in a pickle file. it was mainly
    designed for copy-paste functionality (you spot a piece of code you
    like on the net, copy it, and paste it into the program), not really
    for handwritten content, though it does that with no problem.

    i mainly did it because i'm always scanning through my pdf files,
    books, or the net for some coding example of solution that i'd already
    seen before, and it just seemed logical to have something where you
    could just put the content in, give it a title and tags, and just look
    it up whenever you needed to.

    i realize there are sites online that handle this ex. http://snippets.dzone.com,
    but i'm not always online when i code. i also admit that i didn't
    really look to see if anyone had written a desktop app, the project
    seemed like a fun thing to do so here i am.

    it wasn't designed with millions of entries in mind, so i just use a
    pickle file to serialize the data instead of one of the database APIs.
    the query is also very basic, only title and tags and no ranking based
    on the query.

    there is an issue that i can't figure out, when you are at the list of
    entries there's a try, except clause where it tries to catch a valid
    index (integer). if you enter an inavlid integer, it will ask you to
    enter a valid one, but it doesn't seem to be able to assign it to the
    variable. if you enter a valid integer straightaway, there are no
    problems and the entry will display.

    anyway let me know what you guys think. this is coded for python3.

    main file:

    #!usr/bin/python

    from archive_functions import Entry, choices, print_choice,
    entry_query
    import os

    def main():
    choice = ''
    while choice != "5":
    os.system('clear')
    print("Mo's Archive, please select an option")
    print('====================')
    print('1. Enter an entry')
    print('2. Lookup an entry')
    print('3. Display all entries')
    print('4. Delete an entry')
    print('5. Quit')
    print('====================')
    choice = input(':')

    if choice == "1":
    entry = Entry()
    entry.get_data()
    entry.save_data()

    elif choice == "2":
    queryset = input('Enter title or tag query: ')
    result = entry_query('entry.pickle', queryset)
    if result:
    print_choice(result, choices(result))
    else:
    os.system('clear')
    print('No Match! Please try another query')
    pause = input('\npress [Enter] to continue...')

    elif choice == "3":
    queryset = 'all'
    result = entry_query('entry.pickle', queryset)
    if result:
    print_choice(result, choices(result))

    elif choice == "4":
    queryset = input('Enter title or tag query: ')
    result = entry_query('entry.pickle', queryset)
    if result:
    entry = result[choices(result)]
    entry.del_data()
    else:
    os.system('clear')
    print('No Match! Please try another query')
    pause = input('\npress [Enter] to continue...')

    elif choice == "5":
    break

    else:
    input('please enter a valid choice...')
    main()

    if __name__ == "__main__":
    main()

    archive_functions.py:

    #!/bin/usr/python
    import sys
    import pickle
    import os
    import re

    class Entry():
    def get_data(self):
    self.title = input('enter a title: ')
    print('enter the code, press ctrl-d to end: ')
    self.code = sys.stdin.readlines()
    self.tags = input('enter tags: ')

    def save_data(self):
    with open('entry.pickle', 'ab') as f:
    pickle.dump(self, f)

    def del_data(self):
    with open('entry.pickle', 'rb') as f:
    data_list = []
    while True:
    try:
    entry = pickle.load(f)
    if self.title == entry.title:
    continue
    data_list.append(entry)
    except:
    break
    with open('entry.pickle', 'wb') as f:
    pass
    with open('entry.pickle', 'ab') as f:
    for data in data_list:
    data.save_data()

    def entry_query(file, queryset):
    '''returns a list of objects matching the query'''
    result = []
    try:
    with open(file, 'rb') as f:
    entry = pickle.load(f)
    os.system('clear')
    if queryset == "all":
    while True:
    try:
    result.append(entry)
    entry = pickle.load(f)
    except:
    return result
    break
    while True:
    try:
    if re.search(queryset, entry.title) or
    re.search(queryset, entry.tags):
    result.append(entry)
    entry = pickle.load(f)
    else:
    entry = pickle.load(f)
    except:
    return result
    break
    except:
    print('no entries in file, please enter an entry first')
    pause = input('\nPress [Enter] to continue...')

    def choices(list_result):
    '''takes a list of objects and returns the index of the selected
    object'''
    os.system('clear')
    index = 0
    for entry in list_result:
    print('{}. {}'.format(index, entry.title))
    index += 1
    try:
    choice = int(input('\nEnter choice: '))
    return choice
    except:
    pause = input('\nplease enter a valid choice')
    choices(list_result)


    def print_choice(list_result, choice):
    '''takes a list of objects and an index and displays the index of
    the list'''
    os.system('clear')
    print('===================')
    print(list_result[choice].title)
    print('===================')
    for line in list_result[choice].code:
    print(line, end="")
    print('\n\n')
    back_to_choices(list_result)

    def back_to_choices(list_result):
    print('1. Back to entry list')
    print('2. Back to Main Menu')
    choice = input(':')
    if choice == "1":
    print_choice(list_result, choices(list_result))
    elif choice == "2":
    pass
    else:
    print('\nplease enter a valid choice')
    back_to_choices(list_result)
    mo reina, Jul 27, 2010
    #1
    1. Advertising

  2. mo reina

    Peter Otten Guest

    mo reina wrote:

    > i've written a tool in python where you enter a title, content, then
    > tags, and the entry is then saved in a pickle file. it was mainly
    > designed for copy-paste functionality (you spot a piece of code you
    > like on the net, copy it, and paste it into the program), not really
    > for handwritten content, though it does that with no problem.
    >
    > i mainly did it because i'm always scanning through my pdf files,
    > books, or the net for some coding example of solution that i'd already
    > seen before, and it just seemed logical to have something where you
    > could just put the content in, give it a title and tags, and just look
    > it up whenever you needed to.
    >
    > i realize there are sites online that handle this ex.
    > http://snippets.dzone.com, but i'm not always online when i code. i also
    > admit that i didn't really look to see if anyone had written a desktop
    > app, the project seemed like a fun thing to do so here i am.
    >
    > it wasn't designed with millions of entries in mind, so i just use a
    > pickle file to serialize the data instead of one of the database APIs.
    > the query is also very basic, only title and tags and no ranking based
    > on the query.
    >
    > there is an issue that i can't figure out, when you are at the list of
    > entries there's a try, except clause where it tries to catch a valid
    > index (integer). if you enter an inavlid integer, it will ask you to
    > enter a valid one, but it doesn't seem to be able to assign it to the
    > variable. if you enter a valid integer straightaway, there are no
    > problems and the entry will display.
    >
    > anyway let me know what you guys think. this is coded for python3.


    > def choices(list_result):
    > '''takes a list of objects and returns the index of the selected
    > object'''
    > os.system('clear')
    > index = 0
    > for entry in list_result:
    > print('{}. {}'.format(index, entry.title))
    > index += 1
    > try:
    > choice = int(input('\nEnter choice: '))
    > return choice
    > except:
    > pause = input('\nplease enter a valid choice')
    > choices(list_result)


    When the exception is triggered you call choices() recursively but discard
    the result. Therefore you get Python's default, None, which is not a valid
    index. Change the last line to

    return choices(list_result)

    for a minimal fix. However, I suggest that you use a while loop instead of
    the recursion:

    def choices(list_result):
    while True:
    os.system('clear')
    for index, entry in enumerate(list_result):
    print('{}. {}'.format(index, entry.title))
    try:
    choice = int(input('\nEnter choice: '))
    if 0 <= choice < len(list_result):
    return choice
    except ValueError:
    pass
    input('\nplease enter a valid choice')

    I've also added a test for the integer range and replaced the bare except
    with a more specific one. I recommend that you never use bare excepts
    because they can hide unexpected exceptions and lead to nasty bugs.

    You should also remove the recursive call of main(). Its only effect is that
    when you enter an invalid choice twice you will have to enter "5" twice to
    really exit your script.

    Peter
    Peter Otten, Jul 27, 2010
    #2
    1. Advertising

  3. mo reina

    mo reina Guest

    Re: Personal archive tool, looking for suggestions on improving thecode

    On 27 Lug, 10:23, Peter Otten <> wrote:
    > mo reina wrote:
    > > i've written a tool in python where you enter a title, content, then
    > > tags, and the entry is then saved in a pickle file. it was mainly
    > > designed for copy-paste functionality (you spot a piece of code you
    > > like on the net, copy it, and paste it into the program), not really
    > > for handwritten content, though it does that with no problem.

    >
    > > i mainly did it because i'm always scanning through my pdf files,
    > > books, or the net for some coding example of solution that i'd already
    > > seen before, and it just seemed logical to have something where you
    > > could just put the content in, give it a title and tags, and just look
    > > it up whenever you needed to.

    >
    > > i realize there are sites online that handle this ex.
    > >http://snippets.dzone.com, but i'm not always online when i code. i also
    > > admit that i didn't really look to see if anyone had written a desktop
    > > app, the project seemed like a fun thing to do so here i am.

    >
    > > it wasn't designed with millions of entries in mind, so i just use a
    > > pickle file to serialize the data instead of one of the database APIs.
    > > the query is also very basic, only title and tags and no ranking based
    > > on the query.

    >
    > > there is an issue that i can't figure out, when you are at the list of
    > > entries there's a try, except clause where it tries to catch a valid
    > > index (integer). if you enter an inavlid integer, it will ask you to
    > > enter a valid one, but it doesn't seem to be able to assign it to the
    > > variable. if you enter a valid integer straightaway, there are no
    > > problems and the entry will display.

    >
    > > anyway let me know what you guys think. this is coded for python3.
    > > def choices(list_result):
    > >     '''takes a list of objects and returns the index of the selected
    > > object'''
    > >     os.system('clear')
    > >     index = 0
    > >     for entry in list_result:
    > >         print('{}. {}'.format(index, entry.title))
    > >         index += 1
    > >     try:
    > >         choice = int(input('\nEnter choice: '))
    > >         return choice
    > >     except:
    > >         pause = input('\nplease enter a valid choice')
    > >         choices(list_result)

    >
    > When the exception is triggered you call choices() recursively but discard
    > the result. Therefore you get Python's default, None, which is not a valid
    > index. Change the last line to
    >
    > return choices(list_result)
    >
    > for a minimal fix. However, I suggest that you use a while loop instead of
    > the recursion:
    >
    > def choices(list_result):
    >     while True:
    >         os.system('clear')
    >         for index, entry in enumerate(list_result):
    >             print('{}. {}'.format(index, entry.title))
    >         try:
    >             choice = int(input('\nEnter choice: '))
    >             if 0 <= choice < len(list_result):
    >                 return choice
    >         except ValueError:
    >             pass
    >         input('\nplease enter a valid choice')
    >
    > I've also added a test for the integer range and replaced the bare except
    > with a more specific one. I recommend that you never use bare excepts
    > because they can hide unexpected exceptions and lead to nasty bugs.
    >
    > You should also remove the recursive call of main(). Its only effect is that
    > when you enter an invalid choice twice you will have to enter "5" twice to
    > really exit your script.
    >
    > Peter


    hi peter, i noticed the issue you mentioned but don't understand why
    they happen.

    for example, when the function is called in the case of an exception,
    the variable choice is re-assigned to whatever the next input is, so
    why is the default None assigned instead? and what' s the difference
    between just calling the function again (the variable list_result
    remains unchanged) and using a return statement?

    i also don' t understand what happens when main is called recursively,
    the variable choice should be re-assigned to whatever the next input
    is, and yet it seems that in the first call, after an invalid choice,
    it doesn't assign the input to the variable.

    thanks for taking the time to post and review the code by the way, i
    really appreciate it
    mo reina, Jul 27, 2010
    #3
  4. mo reina

    Peter Otten Guest

    mo reina wrote:

    > On 27 Lug, 10:23, Peter Otten <> wrote:
    >> mo reina wrote:
    >> > i've written a tool in python where you enter a title, content, then
    >> > tags, and the entry is then saved in a pickle file. it was mainly
    >> > designed for copy-paste functionality (you spot a piece of code you
    >> > like on the net, copy it, and paste it into the program), not really
    >> > for handwritten content, though it does that with no problem.

    >>
    >> > i mainly did it because i'm always scanning through my pdf files,
    >> > books, or the net for some coding example of solution that i'd already
    >> > seen before, and it just seemed logical to have something where you
    >> > could just put the content in, give it a title and tags, and just look
    >> > it up whenever you needed to.

    >>
    >> > i realize there are sites online that handle this ex.
    >> >http://snippets.dzone.com, but i'm not always online when i code. i also
    >> > admit that i didn't really look to see if anyone had written a desktop
    >> > app, the project seemed like a fun thing to do so here i am.

    >>
    >> > it wasn't designed with millions of entries in mind, so i just use a
    >> > pickle file to serialize the data instead of one of the database APIs.
    >> > the query is also very basic, only title and tags and no ranking based
    >> > on the query.

    >>
    >> > there is an issue that i can't figure out, when you are at the list of
    >> > entries there's a try, except clause where it tries to catch a valid
    >> > index (integer). if you enter an inavlid integer, it will ask you to
    >> > enter a valid one, but it doesn't seem to be able to assign it to the
    >> > variable. if you enter a valid integer straightaway, there are no
    >> > problems and the entry will display.

    >>
    >> > anyway let me know what you guys think. this is coded for python3.
    >> > def choices(list_result):
    >> > '''takes a list of objects and returns the index of the selected
    >> > object'''
    >> > os.system('clear')
    >> > index = 0
    >> > for entry in list_result:
    >> > print('{}. {}'.format(index, entry.title))
    >> > index += 1
    >> > try:
    >> > choice = int(input('\nEnter choice: '))
    >> > return choice
    >> > except:
    >> > pause = input('\nplease enter a valid choice')
    >> > choices(list_result)

    >>
    >> When the exception is triggered you call choices() recursively but
    >> discard the result. Therefore you get Python's default, None, which is
    >> not a valid index. Change the last line to
    >>
    >> return choices(list_result)
    >>
    >> for a minimal fix. However, I suggest that you use a while loop instead
    >> of the recursion:
    >>
    >> def choices(list_result):
    >> while True:
    >> os.system('clear')
    >> for index, entry in enumerate(list_result):
    >> print('{}. {}'.format(index, entry.title))
    >> try:
    >> choice = int(input('\nEnter choice: '))
    >> if 0 <= choice < len(list_result):
    >> return choice
    >> except ValueError:
    >> pass
    >> input('\nplease enter a valid choice')
    >>
    >> I've also added a test for the integer range and replaced the bare except
    >> with a more specific one. I recommend that you never use bare excepts
    >> because they can hide unexpected exceptions and lead to nasty bugs.
    >>
    >> You should also remove the recursive call of main(). Its only effect is
    >> that when you enter an invalid choice twice you will have to enter "5"
    >> twice to really exit your script.
    >>
    >> Peter

    >
    > hi peter, i noticed the issue you mentioned but don't understand why
    > they happen.
    >
    > for example, when the function is called in the case of an exception,
    > the variable choice is re-assigned to whatever the next input is, so
    > why is the default None assigned instead? and what' s the difference
    > between just calling the function again (the variable list_result
    > remains unchanged) and using a return statement?


    If you have a function

    def f():
    return 42

    and just call it from another function

    def g():
    f()

    the result of f() is evaluated but immediately discarded. If you want to use
    it inside g() you have to assign it to a variable

    def g():
    x = f()
    y = x * x
    print y

    and if you want to use it outside g() you can return it.

    def g():
    return f()

    For recursion the same rules apply, only with the same function as f and g.
    Here's a simple example for you to work out the program flow:

    >>> def r1(n):

    .... print "entering level", n
    .... if n == 5:
    .... print "limit reached"
    .... print "exiting level", n
    .... print "returning 42"
    .... return 42
    .... else:
    .... print "recursing"
    .... r1(n+1)
    .... print "exiting level", n
    .... print "(implicitly) returning None"
    ....
    >>> r1(0)

    entering level 0
    recursing
    entering level 1
    recursing
    entering level 2
    recursing
    entering level 3
    recursing
    entering level 4
    recursing
    entering level 5
    limit reached
    exiting level 5
    returning 42
    exiting level 4
    (implicitly) returning None
    exiting level 3
    (implicitly) returning None
    exiting level 2
    (implicitly) returning None
    exiting level 1
    (implicitly) returning None
    exiting level 0
    (implicitly) returning None

    Try to change r1() to return the value from the innermost call (i. e. 42) to
    the outside world. Once you have understood what is going on you should be
    able to see what's wrong with your program.

    Peter
    Peter Otten, Jul 27, 2010
    #4
  5. mo reina

    mo reina Guest

    Re: Personal archive tool, looking for suggestions on improving thecode

    On Jul 27, 2:06 pm, Peter Otten <> wrote:
    > mo reina wrote:
    > > On 27 Lug, 10:23, Peter Otten <> wrote:
    > >> mo reina wrote:
    > >> > i've written a tool in python where you enter a title, content, then
    > >> > tags, and the entry is then saved in a pickle file. it was mainly
    > >> > designed for copy-paste functionality (you spot a piece of code you
    > >> > like on the net, copy it, and paste it into the program), not really
    > >> > for handwritten content, though it does that with no problem.

    >
    > >> > i mainly did it because i'm always scanning through my pdf files,
    > >> > books, or the net for some coding example of solution that i'd already
    > >> > seen before, and it just seemed logical to have something where you
    > >> > could just put the content in, give it a title and tags, and just look
    > >> > it up whenever you needed to.

    >
    > >> > i realize there are sites online that handle this ex.
    > >> >http://snippets.dzone.com, but i'm not always online when i code. i also
    > >> > admit that i didn't really look to see if anyone had written a desktop
    > >> > app, the project seemed like a fun thing to do so here i am.

    >
    > >> > it wasn't designed with millions of entries in mind, so i just use a
    > >> > pickle file to serialize the data instead of one of the database APIs.
    > >> > the query is also very basic, only title and tags and no ranking based
    > >> > on the query.

    >
    > >> > there is an issue that i can't figure out, when you are at the list of
    > >> > entries there's a try, except clause where it tries to catch a valid
    > >> > index (integer). if you enter an inavlid integer, it will ask you to
    > >> > enter a valid one, but it doesn't seem to be able to assign it to the
    > >> > variable. if you enter a valid integer straightaway, there are no
    > >> > problems and the entry will display.

    >
    > >> > anyway let me know what you guys think. this is coded for python3.
    > >> > def choices(list_result):
    > >> > '''takes a list of objects and returns the index of the selected
    > >> > object'''
    > >> > os.system('clear')
    > >> > index = 0
    > >> > for entry in list_result:
    > >> > print('{}. {}'.format(index, entry.title))
    > >> > index += 1
    > >> > try:
    > >> > choice = int(input('\nEnter choice: '))
    > >> > return choice
    > >> > except:
    > >> > pause = input('\nplease enter a valid choice')
    > >> > choices(list_result)

    >
    > >> When the exception is triggered you call choices() recursively but
    > >> discard the result. Therefore you get Python's default, None, which is
    > >> not a valid index. Change the last line to

    >
    > >> return choices(list_result)

    >
    > >> for a minimal fix. However, I suggest that you use a while loop instead
    > >> of the recursion:

    >
    > >> def choices(list_result):
    > >> while True:
    > >> os.system('clear')
    > >> for index, entry in enumerate(list_result):
    > >> print('{}. {}'.format(index, entry.title))
    > >> try:
    > >> choice = int(input('\nEnter choice: '))
    > >> if 0 <= choice < len(list_result):
    > >> return choice
    > >> except ValueError:
    > >> pass
    > >> input('\nplease enter a valid choice')

    >
    > >> I've also added a test for the integer range and replaced the bare except
    > >> with a more specific one. I recommend that you never use bare excepts
    > >> because they can hide unexpected exceptions and lead to nasty bugs.

    >
    > >> You should also remove the recursive call of main(). Its only effect is
    > >> that when you enter an invalid choice twice you will have to enter "5"
    > >> twice to really exit your script.

    >
    > >> Peter

    >
    > > hi peter, i noticed the issue you mentioned but don't understand why
    > > they happen.

    >
    > > for example, when the function is called in the case of an exception,
    > > the variable choice is re-assigned to whatever the next input is, so
    > > why is the default None assigned instead?  and what' s the difference
    > > between just calling the function again (the variable list_result
    > > remains unchanged) and using a return statement?

    >
    > If you have a function
    >
    > def f():
    >     return 42
    >
    > and just call it from another function
    >
    > def g():
    >     f()
    >
    > the result of f() is evaluated but immediately discarded. If you want to use
    > it inside g() you have to assign it to a variable
    >
    > def g():
    >     x = f()
    >     y = x * x
    >     print y
    >
    > and if you want to use it outside g() you can return it.
    >
    > def g():
    >    return f()
    >
    > For recursion the same rules apply, only with the same function as f and g.
    > Here's a simple example for you to work out the program flow:
    >
    > >>> def r1(n):

    >
    > ...     print "entering level", n
    > ...     if n == 5:
    > ...             print "limit reached"
    > ...             print "exiting level", n
    > ...             print "returning 42"
    > ...             return 42
    > ...     else:
    > ...             print "recursing"
    > ...             r1(n+1)
    > ...     print "exiting level", n
    > ...     print "(implicitly) returning None"
    > ...>>> r1(0)
    >
    > entering level 0
    > recursing
    > entering level 1
    > recursing
    > entering level 2
    > recursing
    > entering level 3
    > recursing
    > entering level 4
    > recursing
    > entering level 5
    > limit reached
    > exiting level 5
    > returning 42
    > exiting level 4
    > (implicitly) returning None
    > exiting level 3
    > (implicitly) returning None
    > exiting level 2
    > (implicitly) returning None
    > exiting level 1
    > (implicitly) returning None
    > exiting level 0
    > (implicitly) returning None
    >
    > Try to change r1() to return the value from the innermost call (i. e. 42) to
    > the outside world. Once you have understood what is going on you should be
    > able to see what's wrong with your program.
    >
    > Peter


    ok i think i understand, the variable from the second function call is
    returned but not assigned to any variable. since the function was
    called by another function and not the main function, it returns the
    variable to the first function instead of the main function.
    mo reina, Jul 27, 2010
    #5
  6. mo reina

    John Bokma Guest

    mo reina <> writes:

    > i mainly did it because i'm always scanning through my pdf files,
    > books, or the net for some coding example of solution that i'd already
    > seen before, and it just seemed logical to have something where you
    > could just put the content in, give it a title and tags, and just look
    > it up whenever you needed to.


    Ages ago I wrote something like this in Perl, but now I use a local
    install of MediaWiki to keep notes, interesting links, code snippets,
    etc. One of the advantages is that I can reach it from each computer
    connected to my LAN, even virtual ones.

    --
    John Bokma j3b

    Hacking & Hiking in Mexico - http://johnbokma.com/
    http://castleamber.com/ - Perl & Python Development
    John Bokma, Jul 27, 2010
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Lees
    Replies:
    2
    Views:
    385
    Robert Kern
    Feb 25, 2008
  2. Aditya Mahajan

    Suggestions for improving code

    Aditya Mahajan, Mar 11, 2006, in forum: Ruby
    Replies:
    2
    Views:
    109
    Aditya Mahajan
    Mar 14, 2006
  3. Rick Johnson
    Replies:
    0
    Views:
    88
    Rick Johnson
    Feb 28, 2013
  4. Joel Goldstick
    Replies:
    0
    Views:
    96
    Joel Goldstick
    Feb 28, 2013
  5. Ian Kelly
    Replies:
    0
    Views:
    87
    Ian Kelly
    Feb 28, 2013
Loading...

Share This Page