Пример #1
0
def change_budget_amounts(budg_data, budg_path):
    """
    Changes budget amounts selected by the user
    """
    done = False
    while not done:
        print(env.OUTPUT_SEP_STR)
        prompt = "Which budget month would you like to edit eh? (q) to abort: "
        dates = util.select_indices_of_list(prompt,
                                            list(budg_data.keys()),
                                            return_matches=True,
                                            abortchar='q')
        if dates is None:  # none type returned if user aborts
            return None

        for date in dates:
            print(f"--- Editing {date} ---")
            expenses = util.select_dict_keys_using_integer(
                budg_data[date],
                "Select the expenses you wish to change: ",
                print_children=False,
                quit_str='q',
                print_vals=True)
            if expenses is not None:  # quit if user says so.
                for exp in expenses:
                    amnt = util.get_float_input(
                        f"Enter the new amount for '{exp}': ",
                        force_pos=True,
                        roundto=2)
                    budg_data[date][exp] = amnt
            else:
                continue

        data_help.write_to_jsonFile(budg_path, budg_data)
Пример #2
0
def add_expense(exp_data, exp_stor_data, exp_path, exp_stor_data_path):
    """
    Adds an expense to the expense database
    """
    flag = False
    while not flag:
        exps = util.format_input_to_list(
            "Enter the expenses you wish to add: ",
            mode='string',
            quit_str='q')
        if exps is None:
            return None

        for exp in exps:
            if exp not in exp_data[env.EXPENSE_DATA_KEY]:
                exp_data[env.EXPENSE_DATA_KEY].append(exp)
                data_help.write_to_jsonFile(exp_path, exp_data)

                user_in = util.get_user_input_for_chars(
                    f"Do you want to add expense [{exp}] expense to some stores [y/n]? ",
                    ['y', 'n'])
                if user_in == 'y':
                    add_expenses_to_store(exp_stor_data,
                                          exp_stor_data_path, [exp],
                                          force_add=True)

                else:
                    flag = True
            else:
                print(
                    f"That expense already exists! Try another one. Heres the list of existing expenses: {exp_data[env.EXPENSE_DATA_KEY]}"
                )
Пример #3
0
def change_storename(db_exp_data_fpaths, df, db_exprec_data_fpath, df_rec,
                     exp_stor_data, stor_data, stor_pair_path,
                     exp_stor_data_path):
    storenames = util.select_dict_keys_using_integer(
        exp_stor_data,
        'Please select storename(s) to change: ',
        print_children=False,
        quit_str='q')
    if storenames != None:  # select_dict_key_using_integer returns none if quitstr is given
        for storename in storenames:
            new_name = util.prompt_with_warning(
                f"Please enter your new storename for [{storename}]: ",
                ret_lowercase=True)
            if new_name != None:  # none is returned from prompt_with_warning when user wants to abort.
                print(f"--- Editing {env.OUT_EXP_DATA_TEMPL} --- ")
                edit_df_entries(df, db_exp_data_fpaths[0], env.FILT_STORENAME,
                                storename, new_name)
                print(f"--- Editing {env.OUT_EXPREC_DATA_TEMPL} --- ")
                edit_df_entries(df_rec, db_exprec_data_fpath,
                                env.FILT_STORENAME, storename, new_name)
                print(f"--- Editing {env.STORE_PAIR_FNAME} --- ")
                stor_data = data_help.match_mod_dict_vals(
                    stor_data, storename, new_name)
                data_help.write_to_jsonFile(stor_pair_path, stor_data)
                print(f"--- Editing {env.EXP_STOR_DB_FNAME} --- ")
                exp_stor_data = data_help.modify_dict_key(
                    exp_stor_data, storename, new_name)
                data_help.write_to_jsonFile(exp_stor_data_path, exp_stor_data)
Пример #4
0
def select_store_for_purchase(storename, stor_data_path, stor_db, exp_stor_db,
                              stor_exp_data_path):
    """
    Uses user input to match a storename to a storename in the database. If no store is found, takes user through adding a store.
    """
    if storename not in stor_db.keys():
        prompt = f"I cannot filter for the store '{storename}'. Please select the storename for this store and I will remember it for next time. If it is a new store, type 'n': "
        matched_storename = util.select_dict_key_using_integer(
            exp_stor_db,
            prompt,
            quit_str='n',
            print_children=False,
            print_aborting=False)

        if matched_storename == None:
            matched_storename = util.process_input(
                f"Could you enter a storename so I remember this store in the future? "
            )
            # if new store is added, add it to the exp_stor_db, with empty expenses to be added later by user
            exp_stor_db.update({matched_storename: []})
            data_help.write_to_jsonFile(stor_exp_data_path, exp_stor_db)
        stor_db.update({storename: matched_storename})

        data_help.write_to_jsonFile(stor_data_path, stor_db)

    else:
        matched_storename = stor_db[storename]

    return matched_storename, stor_db, exp_stor_db
Пример #5
0
def edit_settings(settings_path):
    """
    Main interface for editing settings for the app
    """
    done = False
    prompt = "Please select a setting to edit: "
    while not done:
        settings = data_help.read_jsonFile(settings_path)
        setting_sels = util.select_indices_of_list(prompt,
                                                   list(settings.keys()),
                                                   return_matches=True,
                                                   abortchar='q',
                                                   print_lst=True)
        if setting_sels is None:
            return None

        for setting in setting_sels:
            if setting == env.BANK_SELECTION_KEY:
                value = util.select_indices_of_list(
                    "Please select from the list: ",
                    settings[env.BANK_CHOICES_KEY],
                    return_matches=True,
                    abortchar='q')
            else:
                data_type = type(settings[setting])
                value = util.get_input_given_type(
                    f"Enter your '{data_type}' for {setting}={settings[setting]}. ",
                    data_type,
                    abortchar='q',
                    setting=settings[setting])
            if value is not None:  # none type returned upon quit
                settings[setting] = value
                done = True
                data_help.write_to_jsonFile(settings_path, settings)
Пример #6
0
def edit_notes(prompt, notes, months, notes_path):
    """
    Editing notes method
    params:
        prompt: Output prompt to user
        notes - the notes object
        notes_path - the path to the notes object
        months - the months given for editing or adding notes to
        notes_path - path to notes file
    """
    for month in months:
        if month in notes.keys():
            editable = notes[month]
        else:
            editable = ""
        note = util.get_editable_input(
            prompt + f"[{month}], or ctrl-c to quit process. " +
            "Tip: use (\\n) to denote new lines for plotting: ",
            editable=editable)
        if note is not None:  # note is None type upon quit
            notes[month] = note
            data_help.write_to_jsonFile(notes_path, notes)
        else:
            return None

    return notes
Пример #7
0
def set_dict_keys_to_lowercase(dct_path):
    """
    Function I wrote just to run on the stores exp database to keep all stores lowercase.
    """
    dct = data_help.read_jsonFile(dct_path)
    for key in dct.keys():
        dct = data_help.modify_dict_key(dct, key, key.lower())
    data_help.write_to_jsonFile(dct_path, dct)
Пример #8
0
def choose_bank(json_path: str):
    """
    Prompt user for banks
    """
    settings_json = data_help.read_jsonFile(json_path)
    if env.BANK_SELECTION_KEY not in settings_json.keys():
        prompt = f"Please choose your bank(s) from the list of banks: "
        choices = util.select_indices_of_list(prompt,
                                              env.BANK_OPTIONS,
                                              return_matches=True)
        settings_json[env.BANK_SELECTION_KEY] = choices
        data_help.write_to_jsonFile(json_path, settings_json)
Пример #9
0
def change_storepair(db_exp_data_fpaths, df, db_exprec_data_fpath, df_rec,
                     exp_stor_data, stor_data, stor_pair_path,
                     exp_stor_data_path, exp_data, budg_db):
    """
    Allows user to change the pairing setup within stor_data, opting for the creation of a new store, or the repairing to a different store name
    """
    bank_storenames = util.select_dict_keys_using_integer(
        stor_data,
        'Please select your bank storename(s) to change its pairing, ',
        print_children=False,
        quit_str='q',
        print_vals=True)

    if bank_storenames != None:
        for bank_storename in bank_storenames:
            user_in = util.get_user_input_for_chars(
                f"\nDo you want to:\n(a) - re-pair [{bank_storename}] to an existing store you setup\n(b) - re-pair [{bank_storename}] to a new store name?\n(q) quit\nType here: ",
                ['a', 'b', 'q'])
            if user_in == 'a':
                stor_exp_keys = list(exp_stor_data.keys())
                stor_exp_keys.sort()
                new_pairing = util.select_from_list(
                    stor_exp_keys,
                    f"\nPlease select a store to pair [{bank_storename}] to, or 'q' to quit: ",
                    abortchar='q',
                    ret_match=True)

            elif user_in == 'b':
                new_pairing = util.process_input(
                    f"\nPlease input your new storename to be used with [{bank_storename}]: "
                )
                exp_stor_data[new_pairing] = [
                ]  # add new storename to exp_stor_data

            elif user_in == 'q':
                new_pairing = None

            if new_pairing is not None:  # None type indicates user quit
                stor_data[
                    bank_storename] = new_pairing  # set the new pairing into the stor_db
                prompt = f"Searching {db_exp_data_fpaths[0]} for any old references to [{bank_storename}]."
                replace_store_in_df(prompt, df, db_exp_data_fpaths[0],
                                    new_pairing, exp_stor_data, budg_db,
                                    exp_stor_data_path, stor_data,
                                    stor_pair_path, bank_storename)
                prompt = f"Searching {db_exprec_data_fpath} for any old references to [{bank_storename}]."
                replace_store_in_df(prompt, df_rec, db_exprec_data_fpath,
                                    new_pairing, exp_stor_data, budg_db,
                                    exp_stor_data_path, stor_data,
                                    stor_pair_path, bank_storename)

                data_help.write_to_jsonFile(stor_pair_path, stor_data)
Пример #10
0
def sync_expenses(exp_data, exp_stor_data, exp_path, exp_stor_data_path):
    """
    Makes sure that the expenses in storesWithExpenses.json are matched to expenses.json
    """
    matched_expenses = []
    for stor, expenses in exp_stor_data.items():
        for expense in expenses:
            if expense in exp_data[env.EXPENSE_DATA_KEY]:
                matched_expenses.append(expense)
            else:
                print(f"REMOVED: {expense} from {stor}")
        exp_stor_data[stor] = matched_expenses
        matched_expenses = []
    data_help.write_to_jsonFile(exp_stor_data_path, exp_stor_data)
Пример #11
0
def initialize_settings(settings_path):
    settings = data_help.read_jsonFile(settings_path)
    for key in env.SETTINGS_TEMPL.keys():  # add keys in globvar
        if key not in settings.keys():
            settings[key] = env.SETTINGS_TEMPL[key]

    keys_to_rem = []
    for key in settings.keys():  # remove keys not in globvar
        if key not in env.SETTINGS_TEMPL.keys():
            keys_to_rem.append(key)

    for key in keys_to_rem:
        settings.pop(key)

    data_help.write_to_jsonFile(settings_path, settings)
Пример #12
0
def edit_list_in_dict(prompt, options, dct, key, dct_path, add=True):
    items = select_indices_of_list(prompt,
                                   list_to_compare_to=options,
                                   return_matches=True,
                                   abortchar='q')
    if items is not None:
        if add == True:
            for item in items:
                dct[key].append(item)
        else:
            for item in items:
                dct[key].remove(item)

        data_help.write_to_jsonFile(dct_path, dct)
    else:
        return None
Пример #13
0
def search_store_relationships(storename, exp_stor_db, budg_db,
                               stor_exp_data_path, stor_db, stor_data_path):
    """
    Searches the store expense relationship (exp_stor_db) for an expense and if multiple exist, prompts the user to select one.
    params:
        storename - a store's name from the dataframe
        exp_stor_db - a python dict containing stores as keys, and arrays of expenses as values
        budg_db - expense budget dict database
        stor_exp_data_path - filepath to storesWithExpenses.json
        stor_db - the storename to store strings database
        stor_data_path - the path to stor_db
    returns: the selected expense string, and the modified exp_stor_db
    """
    exp_stor_dbKeys = exp_stor_db.keys()

    if storename not in exp_stor_dbKeys:
        storename, stor_db, exp_stor_db = select_store_for_purchase(
            storename, stor_data_path, stor_db, exp_stor_db,
            stor_exp_data_path)

    exps_fr_store = exp_stor_db[storename]

    if len(exps_fr_store) == 0:
        selected_exps = util.select_indices_of_list(
            f"No expenses for '{storename}'. Please select one or multiple to go with this store from now on.",
            list(budg_db.keys()),
            return_matches=True)
        if len(selected_exps) == 1:
            selected_exp = selected_exps[0]
        else:
            selected_exp = util.select_from_list(
                selected_exps,
                f"Please select which expense you want for this transaction at '{storename}': ",
                ret_match=True)
        exp_stor_db[storename] = selected_exps
        data_help.write_to_jsonFile(stor_exp_data_path, exp_stor_db)

    elif len(exps_fr_store) == 1:
        selected_exp = exps_fr_store[0]
    else:
        selected_exp = exps_fr_store[util.select_from_list(
            exps_fr_store,
            f"Please select an expense for this transaction at '{storename}': "
        )]

    return selected_exp, dict(exp_stor_db), stor_db, storename
Пример #14
0
def get_budgets(budg_path, exp_path, dates=None):
    """
    Prompts user for budgeting options given a new month if no budget is present for that month
    """
    exp_budg = data_help.read_jsonFile(budg_path)
    exp_data = data_help.read_jsonFile(exp_path)
    if dates == None:
        dates = [util.get_current_month()]
    for date in dates:
        exp_budg_keys = exp_budg.keys()
        if date not in exp_budg_keys:  # check for current month to find exp categories
            print(
                f"I have detected some data with for the month {date} that has no budget set."
            )
            print(
                "Please set the budget for this month.. or delete the data and run the program again."
            )
            if len(exp_budg) != 0:
                user_in = util.get_user_input_for_chars(
                    "Would you like to the whole thing (w) or create new (n)? ",
                    ['w', 'n'])

                if user_in == 'w':
                    key = util.select_dict_key_using_integer(
                        exp_budg,
                        "Please select a budget to copy: ",
                        print_children=True,
                        print_vals=False,
                        print_child_vals=True)
                    exp_budg[date] = exp_budg[key]
                elif user_in == 'n':
                    exp_budg[date] = declare_new_budget(date, exp_data)
            else:
                exp_budg[date] = declare_new_budget(date, exp_data)

            print(f"Your budget is now saved for {date}.")

        else:
            print(f"Your monthly budget for {date} is: ")

        util.print_simple_dict(exp_budg[date], print_vals=True)

    data_help.write_to_jsonFile(budg_path, exp_budg)
    return
Пример #15
0
def add_expenses_to_store(exp_stor_data,
                          exp_stor_data_path,
                          exp_list: list,
                          force_add=False):
    """
    Adds an expense to a store within storesWithExpenses.json
    params:
        exp_stor_data : the dict object of storesWithExpenses.json
        exp_stor_data_keylist : the list of keys of exp_stor_data
        exp_list : the expense to add to the store selected by the user
        force_add : force the list of expenses into the store selection
    """
    stores = util.select_dict_keys_using_integer(
        exp_stor_data,
        "Select the store(s) you wish to add expense(s) to.",
        print_children=False,
        quit_str='q',
        print_aborting=False,
        print_vals=True)
    if stores != None:
        for store in stores:

            if not force_add:
                pair_prompt = f"Which expenses do you want to add to '{store}', separated by a space.. (q) to abort: "
                expenses = util.select_indices_of_list(pair_prompt,
                                                       exp_list,
                                                       return_matches=True,
                                                       abortchar='q')
            else:
                expenses = exp_list

            for expense in expenses:
                if expense not in exp_stor_data[store]:
                    exp_stor_data[store].append(expense)
                    print(f"Added '{expense}' to '{store}'")
                else:
                    print(
                        f"Ignoring addition! '{expense}' already is in '{store}'"
                    )

        data_help.write_to_jsonFile(exp_stor_data_path, exp_stor_data)
Пример #16
0
def setup_expense_names(exp_path: str):
    """
    Gets a list of expense names from the user and saves them.
    """
    exp_list = data_help.read_jsonFile(exp_path)
    if len(exp_list) == 0:
        exp_list[env.EXPENSE_DATA_KEY] = util.format_input_to_list(
            "Please input your expense categories, I will add a Misc category since it is reserved. "
        )
        idxs_matched = util.check_lst_for_values(
            exp_list[env.EXPENSE_DATA_KEY], env.MISC_POS_VALUES)
        for idx in sorted(idxs_matched, reverse=True):
            print(
                f"Found {exp_list[env.EXPENSE_DATA_KEY][idx]} in your expenses. Removing since '{env.EXPENSE_MISC_STR}' is reserved as miscellaneous category."
            )
            del exp_list[env.EXPENSE_DATA_KEY][idx]
        exp_list[env.EXPENSE_DATA_KEY].append(env.EXPENSE_MISC_STR)
        data_help.write_to_jsonFile(exp_path, exp_list)

    if env.EXPENSES_SUBTRACTED_KEY not in exp_list.keys():
        exp_list[env.EXPENSES_SUBTRACTED_KEY] = []
        data_help.write_to_jsonFile(exp_path, exp_list)
Пример #17
0
def edit_expense_name(exp_db_data_filepath, df, exp_recbin_path, df_rec,
                      exp_data, budg_data, exp_stor_data, exp_path, budg_path,
                      exp_stor_data_path):
    """
    Edits an expense name across storesWithExpenses.json, Budgjet.json, expenses.json, and exp_db.csv
    """
    exps_to_edit = util.select_indices_of_list(
        "Which expense(s) would you like to edit?: ",
        exp_data[env.EXPENSE_DATA_KEY],
        abortchar='q',
        return_matches=True)
    if exps_to_edit is None:  # none type quits
        return None

    for exp_to_edit in exps_to_edit:
        if exp_to_edit != env.EXPENSE_MISC_STR:

            expense_new_name = util.select_item_not_in_list(
                f"Enter your new expense name for '{exp_to_edit}' 'q' to abort: ",
                exp_data[env.EXPENSE_DATA_KEY],
                ignorecase=False,
                abortchar='q')
            if expense_new_name is None:
                return None
            # edit the exp_stor_db
            print(f"--- Editing {env.EXP_STOR_DB_FNAME} --- ")
            for store in exp_stor_data.keys():
                if exp_to_edit in exp_stor_data[store]:
                    print(f"In {store}: ", end=" ")
                exp_stor_data[store] = util.replace_string_in_list(
                    exp_stor_data[store], exp_to_edit, expense_new_name)

            # Edit the budg_db
            print(f"\n--- Editing {env.BUDGET_FNAME} --- ")
            for date in budg_data.keys():
                budg_data[date] = data_help.modify_dict_key(
                    budg_data[date], exp_to_edit, expense_new_name)
            # Edit expenses.json
            print(f"--- Editing {env.EXP_FNAME} --- ")
            exp_data[env.EXPENSE_DATA_KEY] = util.replace_string_in_list(
                exp_data[env.EXPENSE_DATA_KEY], exp_to_edit, expense_new_name)
            # Edit exp_db.csv and (writes itself)
            print(f"--- Editing {env.OUT_EXP_DATA_TEMPL} --- ")
            edit_df_entries(df, exp_db_data_filepath, env.EXPENSE, exp_to_edit,
                            expense_new_name)
            print(f"--- Editing {env.OUT_EXPREC_DATA_TEMPL} --- ")
            edit_df_entries(df_rec, exp_recbin_path, env.EXPENSE, exp_to_edit,
                            expense_new_name)
            # Write changes
            data_help.write_to_jsonFile(budg_path, budg_data)
            data_help.write_to_jsonFile(exp_path, exp_data)
            data_help.write_to_jsonFile(exp_stor_data_path, exp_stor_data)

        else:
            print(
                f"'{env.EXPENSE_MISC_STR}' is a reserved expense category, and its name cannot be changed."
            )
Пример #18
0
def remove_expense_from_dbs(exp_db_data_filepath, exp_recbin_path,
                            exp_stor_data, exp_data, budg_data, df, df_rec,
                            exp_stor_data_path, budg_path, exp_path):
    """
    Removes an expense from the storesWithExpenses.json, Budgjet.json, expenses.json
    """
    print(
        "Warning! Removing an expense is no small task. I will be pruning your store-expense database, your overall transactions, your expenses database and you budgets."
    )
    print(
        "This is irreversible, and will result in any reference to that expense being reverted to 'Misc'."
    )
    print(
        "Any budget amnt for that expense will be added to Misc to maintain balance in the force."
    )
    exps_to_rem = util.select_indices_of_list(
        "Which expense(s) would you like to go? ",
        exp_data[env.EXPENSE_DATA_KEY],
        abortchar='q',
        return_matches=True)
    if exps_to_rem is None:
        return None

    for exp_to_rem in exps_to_rem:
        if exp_to_rem != env.EXPENSE_MISC_STR:

            # delete from exp_stor db
            print(f"--- Editing {env.EXP_STOR_DB_FNAME} --- ")
            for store in exp_stor_data.keys():
                if exp_to_rem in exp_stor_data[store]:
                    exp_stor_data[store].remove(exp_to_rem)
                    print(f"Removed {exp_to_rem} from {store}.")

            # delete from expenses db
            print(f"--- Editing {env.EXP_FNAME} --- ")
            exp_data[env.EXPENSE_DATA_KEY].remove(exp_to_rem)
            print(f"Removed {exp_to_rem} from {env.EXP_FNAME}.")

            # remove from budget, adding amnt to Misc
            print(f"\n--- Editing {env.BUDGET_FNAME} --- ")
            for date in budg_data.keys():
                if exp_to_rem in budg_data[date].keys():
                    amnt_to_misc = budg_data[date][exp_to_rem]
                    budg_data[date][env.EXPENSE_MISC_STR] += amnt_to_misc
                    budg_data[date].pop(exp_to_rem)
                else:
                    print("No expense in this months budget.")

            print(f"--- Editing {env.OUT_EXP_DATA_TEMPL} --- ")
            edit_df_entries(df, exp_db_data_filepath, env.EXPENSE, exp_to_rem,
                            env.EXPENSE_MISC_STR)
            print(f"--- Editing {env.OUT_EXPREC_DATA_TEMPL} --- ")
            edit_df_entries(df_rec, exp_recbin_path, env.EXPENSE, exp_to_rem,
                            env.EXPENSE_MISC_STR)
            # write changes
            data_help.write_to_jsonFile(budg_path, budg_data)
            data_help.write_to_jsonFile(exp_path, exp_data)
            data_help.write_to_jsonFile(exp_stor_data_path, exp_stor_data)

        else:
            print(
                f"'{env.EXPENSE_MISC_STR}' is a reserved expense category, and it cannot be deleted."
            )
Пример #19
0
def remove_exp_from_store(df_path, df, exp_recbin_path, df_rec, exp_stor_data,
                          exp_stor_data_path):
    """
    Removes an expense from exp_stor_data dict, replacing the reference with user selection or misc in the dataframe
    """
    prompt = "Select which store you wish to remove expense(s) from. (q) to abort."
    storenames = util.select_dict_keys_using_integer(exp_stor_data,
                                                     prompt,
                                                     print_children=False,
                                                     quit_str='q',
                                                     print_aborting=False,
                                                     print_vals=True)
    if storenames is None:
        return None

    for storename in storenames:
        removed_expenses = util.select_indices_of_list(
            "Select which expense(s) to remove. (q) to abort.",
            exp_stor_data[storename],
            return_matches=True,
            abortchar='q')
        if removed_expenses is None:
            return None

        print(f"--- Editing {env.EXP_STOR_DB_FNAME} --- ")
        for expense in removed_expenses:
            exp_stor_data[storename].remove(expense)
            print(f"Removed {expense} from {storename}.")

        if len(exp_stor_data[storename]
               ) == 0:  # if all was deleted, append misc into this store.
            print(
                f"You deleted all expenses from {storename}, I am adding {env.EXPENSE_MISC_STR} to preserve your data."
            )
            exp_stor_data[storename].append(env.EXPENSE_MISC_STR)
            new_exp = env.EXPENSE_MISC_STR

        print(
            f"--- Editing {env.OUT_EXP_DATA_TEMPL} & {env.OUT_EXPREC_DATA_TEMPL} --- "
        )
        for rem_exp in removed_expenses:
            if len(exp_stor_data[storename]) == 1:
                print(
                    f"Only expense left for '{storename}' is '{exp_stor_data[storename][0]}'. Replacing '{rem_exp}' with '{exp_stor_data[storename][0]}'."
                )
                new_exp = exp_stor_data[storename][0]
            else:

                new_exp = util.select_from_list(
                    exp_stor_data[storename],
                    f"Which expense do you want to use to replace '{rem_exp}' in '{storename}'? (q) to quit. ",
                    abortchar='q',
                    ret_match=True)
                if new_exp is None:  # user quits
                    return None

            edit_df_entries_given_columns(df, df_path, env.EXPENSE,
                                          env.FILT_STORENAME, storename,
                                          rem_exp, new_exp)
            edit_df_entries_given_columns(df_rec, exp_recbin_path, env.EXPENSE,
                                          env.FILT_STORENAME, storename,
                                          rem_exp, new_exp)

        data_help.write_to_jsonFile(exp_stor_data_path, exp_stor_data)