4
\$\begingroup\$

I'm making a CLI application for myself for tracking my budget. How can I improve this code?

#!/usr/bin/python3

def t_lines():
    import os
    terminal_size = os.get_terminal_size()
    print("-" * terminal_size.columns)


def main():
    import sqlite3 as sql

    conn = sql.connect("expenses.db")
    cur = conn.cursor()

    cur.execute("CREATE TABLE IF NOT EXISTS expenses \
            (Date TEXT DEFAULT \"x\", \
            item TEXT DEFAULT \"x\", \
            category TEXT DEFAULT \"x\", \
            Price REAL DEFAULT 0, \
            Type TEXT DEFAULT \"e\")" )

    t_lines()
    
    print("Enter in the following format")

    print("Enter 0 to quit")

    print("Date (dd/mmm/yy), Item, Category, Price, Type ([e]xpense/[i]ncome)")
    
    print("Example:")
    print("12/nov/18, carrot, vegetable, 15.64, e")
    print("13/aug/18, salary, work, 10000, income")

    t_lines()

    user_input = input()
    # the vals below seems unnecessary
    # vals = user_input.split(',')

    while user_input != "0":
        vals = user_input.split(',')

        if len(vals) != 5:
            print("Enter correctly")
        else:
            cur.execute("INSERT INTO expenses \
                VALUES (?, ?, ?, ?, ?)", vals)
            conn.commit()
            user_input = input()
        

    conn.close()

if __name__ == '__main__':
    main()
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Bug

When I run the code, and I enter input that has less than 4 commas, the code enters an infinite loop, printing this endlessly:

Enter correctly
Enter correctly
Enter correctly

You need to add a check for this in your code, and test it more thoroughly. Consider using pyinputplus to validate the input.

Imports

The imports should be placed at the top of the code, before the functions (not in the functions).

Layout

There are too many blank lines, especially between print statements.

Efficiency

There is no need to call os.get_terminal_size() multiple times (once per) t_lines function call. Call it once in main.

Naming

The function name t_lines is cryptic. A better name is something like print_dashes.

Comments

These comments should be deleted:

# the vals below seems unnecessary
# vals = user_input.split(',')

Comments are intended to explain code, not raise questions about it.

Simpler

This if/else:

if len(vals) != 5:

else:

is simpler using ==. I will demonstrate below.

Documentation

The PEP 8 style guide recommends adding docstrings for functions. The docstrings should describe the purpose of the code.


Here is the code with many of the suggestions:

#!/usr/bin/python3

import os
import sqlite3 as sql

def print_dashes(width):
    """
    Print a line of dashes.
    The input is an integer specifying the width of the line
    """
    print("-" * width)

def main():
    """
    Create an SQL database to track a budget.
    """
    terminal_size = os.get_terminal_size()
    line_width = terminal_size.columns

    conn = sql.connect("expenses.db")
    cur = conn.cursor()

    cur.execute("CREATE TABLE IF NOT EXISTS expenses \
            (Date TEXT DEFAULT \"x\", \
            item TEXT DEFAULT \"x\", \
            category TEXT DEFAULT \"x\", \
            Price REAL DEFAULT 0, \
            Type TEXT DEFAULT \"e\")" )

    print_dashes(line_width)
    print("Enter in the following format")
    print("Enter 0 to quit")
    print("Date (dd/mmm/yy), Item, Category, Price, Type ([e]xpense/[i]ncome)")
    print("Example:")
    print("12/nov/18, carrot, vegetable, 15.64, e")
    print("13/aug/18, salary, work, 10000, income")
    print_dashes(line_width)

    user_input = input()

    while user_input != "0":
        vals = user_input.split(',')

        if len(vals) == 5:
            cur.execute("INSERT INTO expenses \
                VALUES (?, ?, ?, ?, ?)", vals)
            conn.commit()
            user_input = input()
        else:
            print("Enter correctly")

    conn.close()

if __name__ == '__main__':
    main()
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.