Member Avatar for John A.

Hey guys, this is my first project since I completed CodeAcademy's Python course yesterday. Besides that course, this is my first time programming and I would really appreciate input on my program. I decided to create a database to help me keep track of the anime I watch. For this project I only used what was taught in the CodeAcademy course except for the webbrowser module.

import webbrowser

all_commands = {
    "ls": "  Lists all DataBase entries.",
    "add": " Add entries to DataBase.",
    "del": " Delete specified entry.",
    "edit": "Edit specified entry.",
    "open": "Open specified entry.",
    "web": " Open specified entry in web browser.",
    "help": "Displays these commands."
    }

class Anime(object):
    title = ""
    total_episodes = 0
    genres = ""
    current_episode = 0
    description = ""
    def __repr__(self): ## Format for print
        return (" Title: %s\n Episodes: %s/%s\n Genres: %s\n Description: %s") % (self.title,self.current_episode,self.total_episodes,self.genres,self.description)
    def add_to_file(self): ## Format used to write entry to file
        return ("%s|%s|%s|%s|%s\n" % (self.title,self.current_episode,self.total_episodes,self.genres,self.description))
    def from_file_data_format(self, data_list):
        self.title = data_list[0]
        self.current_episode = int(data_list[1])
        self.total_episodes = int(data_list[2])
        self.genres = data_list[3]
        self.description = data_list[4]

## get title of anime to be used in other functions
def get_title(command_list):
    if len(command_list) > 1:
        title = "-".join(command_list[1::]).lower()
    else:
        title = raw_input("Title of Anime?\n>>").lower()

    return title

## open anime in default browser using waoanime.tv
def open_in_web_browser(command_list):
    if len(command_list) > 1:
        title = "-".join(command_list[1::]).lower()  ## convert given title to proper format e.g(this-is-a-title)
    else:
        title = "-".join(raw_input("Title of anime?\n>>").split(" ")).lower() ## ask user for title and convert to proper format
    webbrowser.open_new_tab("http://waoanime.tv/anime/%s/" % (title))

## delete entry from file
def delete_entry(command_list):
    title = get_title(command_list)

    data_file = open("AnimeDataBase.txt", "r")
    lines = data_file.readlines()
    data_file.close()

    data_file = open("AnimeDataBase.txt", "w")
    for line in lines:
        data_list = line.split("|")
        if data_list[0].lower() != title:
            data_file.write(line)
    data_file.close()

## edit an entry in the database
def edit_entry(command_list):
    title = get_title(command_list)
    data_list = []
    edited_entry = Anime()

    ## print current information for specified entry, save to class variable, and delete it from database.
    data_file = open("AnimeDataBase.txt", "r")
    lines = data_file.readlines()
    data_file.close()

    data_file = open("AnimeDataBase.txt", "w")
    for line in lines:
        data_list = line.split("|")
        if data_list[0].lower() != title and data_list[0] != "\n":
            data_file.write(line)
        elif data_list[0].lower() == title:
            edited_entry.from_file_data_format(data_list)        
    data_file.close()

    print edited_entry

    ## get data from user used to edit entry
    entry_variable = raw_input("What would you like to edit?(title, episodes, genres, description)\n>>").lower()
    if entry_variable == "title":
        edited_entry.title = raw_input("What is the new title\n>>")
    elif entry_variable == "episodes":
        entry_variable = raw_input("Current or total?\n>>").lower()
        if entry_variable == "total":
            edited_entry.total_episodes = int(raw_input("Number of total episodes.\n>>"))
        else:
            edited_entry.current_episode = int(raw_input("Current episode.\n>>"))
    elif entry_variable == "genres":
        endited_entry.genres = raw_input("What genres does this belong to?(seperated by a space)\n>>")
    elif entry_variable == "description":
        edited_entry.description = raw_input("Description of Anime.\n>>")

    ## append edited entry to database file
    data_file = open("AnimeDataBase.txt", "a")
    data_file.write(edited_entry.add_to_file())
    data_file.close()

## list entries in database
def list_entries(command_list):
    ## check if command has arguments. if so, run open with intended arguments e.g(c = list entries that are completed)
    if len(command_list) > 1:
        if command_list[1][0] == "-":
            data_list = []
            arguments = command_list[1][1::].lower()

            data_file = open("AnimeDataBase.txt", "r+")
            for line in data_file.readlines():
                data_list = line.split("|")
                for arg in arguments:
                    if arg == 'c':
                        if data_list[1] == data_list[2]:
                            print "%s %s episodes" % (data_list[0], data_list[2])
                    if arg == 'i':
                        if data_list[1] != data_list[2]:
                            print "%s %s/%s episodes" % (data_list[0], data_list[1], data_list[2])
                    if arg == 'a':
                        old_entry = Anime()
                        old_entry.from_file_data_format(data_list)
                        print old_entry
            data_file.close()
        else:
            print ("Improper syntax")
    ## list all titles in database and number of entries
    else:
        data_file = open("AnimeDataBase.txt", "r+")
        total_entries = 0
        for line in data_file.readlines():
            data_list = line.split("|")
            print data_list[0]
            total_entries += 1
        print ("There are %s entries in the DataBase") % (total_entries)
        data_file.close()

## open specific database entry and print all information to screen
def open_entry(command_list):
    title = get_title(command_list)
    data_list = []

    data_file = open("AnimeDataBase.txt", "r+")
    for line in data_file.readlines():
        data_list = line.split("|")
        if data_list[0].lower() == title:
            break
    data_file.close()

    old_entry = Anime()
    old_entry.from_file_data_format(data_list)
    print old_entry

## adds entry to database using Anime class to get information from user
def add_entry(command_list):
    new_entry = Anime()
    new_entry.title = raw_input("What is the title?\n>>")
    new_entry.total_episodes = int(raw_input("How many episodes are there?\n>>"))
    new_entry.current_episode = int(raw_input("How many episodes have you watched?\n>>"))
    new_entry.genres = raw_input("What genres does this belong to?(seperated by a space)\n>>")
    new_entry.description = raw_input("Description of Anime.\n>>")

    data_file = open("AnimeDataBase.txt", "a")
    data_file.write(new_entry.add_to_file())
    data_file.close()

## lists the all_command dictionary, will eventually display arguments for specified command
def help(command_list):
    if len(command_list) > 1:
        print ("This will later list arguments for specific commands")   
    else:
        for key in all_commands:
            print key, all_commands[key]

## parses the command string into a list
def command_parser(command):
    return command.split(" ")

## runs specified command's function
def command_interpreter(command):
    command_list = command_parser(command)
    if command_list[0] == "help":
        help(command_list)
    elif command_list[0] == "add":
        add_entry(command_list)
    elif command_list[0] == "open":
        open_entry(command_list)
    elif command_list[0] == "ls":
        list_entries(command_list)
    elif command_list[0] == "web":
        open_in_web_browser(command_list)
    elif command_list[0] == "del":
        delete_entry(command_list)
    elif command_list[0] == "edit":
        edit_entry(command_list)
    else:
        print ("Command is not recognized")


## Start of program, gets commands from user
command = raw_input("Welcome to your Anime DataBase. \n >>").lower()
while command != "exit":
    command_interpreter(command)
    command = raw_input(">>").lower()

What's your opinion on it? How do you think I could improve it?

Things I know I should fix:
1. When editing an entry, you can add an entry with the base Anime class values. If/else statements can fix it.
2. Because of the way I handled commands in a list, the program can crash if you don't supply a value to certain functions. command_list[n] out of range.

Where could I find a good resource on GUI's and encryption/decryption of file IO?
And last question, what should I do next? Should I continute coding in python for a while, or try to learn a new language?

Thanks for reading and for any input you may give.

You can improve the program by using the standard module cmd which purpose is to write interactive command line interpreters. I wrote an enhanced class of cmd.Cmd in this code snippet. It makes it very easy to write an interpreter: copy the class ExampleCmd at the end of the file and add methods do_ls() do_add() do_open() etc with arguments and docstring. The help command is automatically provided.

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.