From 90cbf8e91dc75dc81ac8de623431f9b43f2d90f1 Mon Sep 17 00:00:00 2001 From: ValeZh Date: Thu, 23 May 2024 18:49:25 +0300 Subject: [PATCH 1/3] I make all --- hw_4/api.py | 180 +++++++++++++++++++++-------------------------- hw_4/main.py | 2 +- hw_4/validate.py | 23 +++++- 3 files changed, 101 insertions(+), 104 deletions(-) diff --git a/hw_4/api.py b/hw_4/api.py index 645988e..0e25113 100644 --- a/hw_4/api.py +++ b/hw_4/api.py @@ -8,6 +8,7 @@ from consts import URL from datetime import datetime, timedelta import random +from collections import Counter, defaultdict formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(name)s:%(message)s') my_logger = logging.getLogger('CustomLogger') @@ -21,7 +22,6 @@ # gets dict from currencies and their values relative to the dollar def get_currency_data(): - response = requests.get(URL.format(os.getenv('API_KEY'))) if response.status_code == requests.codes.ok: data = response.json() @@ -40,34 +40,24 @@ def read_csv_to_dict(file_path): def unpack_data(data): - keys = list(data.keys()) - return [data[key] for key in keys] if len(keys) > 1 else data[keys[0]] + return data.values() -# { filler_date: [{}, {} ]} -# { "row1": {}, "row2": {} } -# fills the table bank -@db_connection -def add_bank(cur, **kwargs): - data = unpack_data(kwargs) - my_logger.info(data) - # unpack the mass of dicts - my_logger.info(data) - cur.executemany("INSERT INTO Bank(name) VALUES(:Name)", data) # :param_name, :param_name2 - my_logger.info("Bank added successfully.") +def format_data_string(data): + formatted_string = ', '.join(f'{item}' for item in data[0]) + formatted_string_colon = ', '.join(f':{item}' for item in data[0]) + return formatted_string, formatted_string_colon -# fills the table user @db_connection -def add_user(cur, **kwargs): - data = unpack_data(kwargs) - my_logger.info(data) - for i in data: - i["name"] = validate.validate_user_full_name(i["user_name"])[0] - i["surname"] = validate.validate_user_full_name(i["user_name"])[1] - cur.executemany("INSERT INTO User(name,surname,birth_day,accounts) VALUES(:name ,:surname,:birthday,:accounts)", - data) - my_logger.info("User added successfully.") +def add_generic_by_path(cur, path, table_name): + data = read_csv_to_dict(path) + data = validate.username_validate(data) + column, form_column = format_data_string(data) + cur.executemany(f"INSERT INTO {table_name}({column}) VALUES({form_column})", data) + if table_name == "Account": + set_accounts(cur, data) + my_logger.info(f"{table_name} added successfully.") def unpack_to_string(data): @@ -79,6 +69,7 @@ def unpack_to_string(data): # fills the table account + def set_accounts(cur, data): for i in data: cur.execute("SELECT id FROM Account WHERE user_id = ?", (i["user_id"],)) @@ -88,18 +79,6 @@ def set_accounts(cur, data): cur.execute("UPDATE User SET Accounts = ? WHERE id = ?", (account_str, i["user_id"],)) -@db_connection -def add_account(cur, **kwargs): - data = unpack_data(kwargs) - my_logger.info(data) - validate.valid_acc(data) - cur.executemany('''INSERT INTO Account(user_id, type, account_number, bank_id, currency, amount, status) - VALUES(:user_id,:type,:account_number,:bank_id,:currency,:amount,:status)''', - data) - set_accounts(cur, data) - my_logger.info("account added successfully.") - - # update row in bd @db_connection def update_row(c, table_name, row_id, column, value): @@ -108,18 +87,34 @@ def update_row(c, table_name, row_id, column, value): @db_connection -def delete_row(cur, row_id, fnc): - match fnc: +def delete_generic(cur, row_id, table_name, second_table=None): + if second_table: + cur.execute(f"DELETE FROM Account WHERE {table_name.lower()}_id = ?", (row_id,)) + cur.execute(f"DELETE FROM {table_name} WHERE id = ?", (row_id,)) + my_logger.info(f"{table_name} delete successfully.") + return "success" + + +def delete_row(row_id, table_name): + match table_name: case "User": - cur.execute("DELETE FROM Account WHERE user_id = ?", (row_id,)) - cur.execute("DELETE FROM User WHERE id = ?", (row_id,)) + delete_user(row_id) case "Bank": - cur.execute("DELETE FROM Account WHERE bank_id = ?", (row_id,)) - cur.execute("DELETE FROM Bank WHERE id = ?", (row_id,)) + delete_bank(row_id) case "Account": - cur.execute("DELETE FROM Account WHERE id = ?", (row_id,)) - my_logger.info(f"{fnc} delete successfully.") - return "success" + delete_account(row_id) + + +def delete_user(row_id): + delete_generic(row_id, 'User', True) + + +def delete_bank(row_id): + delete_generic(row_id, 'Bank', True) + + +def delete_account(row_id): + delete_generic(row_id, 'Account', False) # it just clears the tables in the database @@ -129,30 +124,19 @@ def clear_table(cur, table_name): return 'success' -def add_table_by_file(path, table_name): - data = read_csv_to_dict(path) - match table_name: - case "Bank": - add_bank(table_filler=data) - case "User": - add_user(table_filler=data) - case "Account": - add_account(table_filler=data) - - def convert_currency(currency_values, orig_currency, conv_currency, amount): return round((amount / currency_values[orig_currency]) * currency_values[conv_currency], 2) def get_bankname(id_user): - bank_id = get_data_from_table(table_name="Account", row_name="bank_id", row_id=id_user) + bank_id = get_data_from_table(table_name="Account", col_name="bank_id", row_id=id_user) my_logger.info("get_bankname successfully.") - return get_data_from_table(table_name="Bank", row_name="name", row_id=bank_id) + return get_data_from_table(table_name="Bank", col_name="name", row_id=bank_id) @db_connection -def get_data_from_table(cur, row_name, table_name, row_id): - cur.execute(f"SELECT {row_name} FROM {table_name} WHERE id = ? ", (row_id,)) +def get_data_from_table(cur, col_name, table_name, row_id): + cur.execute(f"SELECT {col_name} FROM {table_name} WHERE id = ? ", (row_id,)) return cur.fetchone()[0] @@ -170,9 +154,17 @@ def insert_transaction(cur, bank_sender_name, sender_id, bank_receiver_name, sender_currency, sent_amount, transfer_time,)) +def account_valid(sender_amount, sent_amount, sender_currency, receiver_currency, currency_dict, transfer_time): + if validate.valid_currency_amount(sender_amount, sent_amount, sender_currency, receiver_currency): + sent_amount = convert_currency(currency_dict, receiver_currency, sender_currency, sent_amount) + transfer_time = validate.add_transaction_time(transfer_time) + return sent_amount, transfer_time + + def transfer_money(sender_id, receiver_id, sent_amount, transfer_time=None): currency_dict = get_currency_data() my_logger.info('valid current success') + # pull the necessary data to fill the transaction table bank_sender_name = get_bankname(sender_id) bank_receiver_name = get_bankname(receiver_id) @@ -180,22 +172,16 @@ def transfer_money(sender_id, receiver_id, sent_amount, transfer_time=None): receiver_amount = get_data_from_table("Amount", "Account", receiver_id) sender_currency = get_data_from_table("Currency", "Account", sender_id) receiver_currency = get_data_from_table("Currency", "Account", receiver_id) - sent_am_in_sender_cur = sent_amount - if sender_amount <= sent_amount: - raise ValueError("not enough money in the account") - if receiver_currency != sender_currency: - sent_am_in_sender_cur = convert_currency(currency_dict, receiver_currency, sender_currency, sent_amount) + sent_amount, transfer_time = account_valid(sender_amount, sent_amount, sender_currency, receiver_currency, + currency_dict, transfer_time) - # check the time - transfer_time = validate.add_transaction_time(transfer_time) - - new_sender_amount = sender_amount - sent_am_in_sender_cur - new_receiver_amount = receiver_amount + sent_am_in_sender_cur + new_sender_amount = round(sender_amount - sent_amount, 2) + new_receiver_amount = round(receiver_amount + sent_amount, 2) # change the sum values of the users - update_row("Account", sender_id, "amount", round(new_sender_amount, 2)) - update_row("Account", receiver_id, "amount", round(new_receiver_amount, 2)) + update_row("Account", sender_id, "amount", new_sender_amount) + update_row("Account", receiver_id, "amount", new_receiver_amount) # fill the table insert_transaction(bank_sender_name, sender_id, bank_receiver_name, receiver_id, @@ -210,9 +196,11 @@ def select_random_users_with_discounts(cursor): all_users = cursor.fetchall() random_users = random.sample(all_users, min(10, len(all_users))) # Randomly select up to 10 users user_discounts = {} + # comprehension use for user_id in random_users: discount = random.choice([25, 30, 50]) # Randomly choose discount user_discounts[user_id[0]] = discount + ######################################### my_logger.info(user_discounts) my_logger.info("select_random_users_with_discounts success") return user_discounts @@ -246,6 +234,7 @@ def bank_with_biggest_capital(cursor): # Create a dictionary to store the total capital for each bank in dollars for bank_id, currency, amount in accounts: amount_in_usd = convert_currency(currency_dict, currency, 'USD', amount) + # dict.setdefault() .append() .sum() / default_dict / if bank_id in bank_capital: bank_capital[bank_id] += amount_in_usd else: @@ -266,20 +255,14 @@ def bank_serving_oldest_client(cursor): cursor.execute("SELECT User_id, Bank_id FROM Account") accounts = cursor.fetchall() - # Find the oldest user - oldest_user_id = None - oldest_birth_day = datetime.max - - for user_id, birth_day in users: - birth_date = datetime.strptime(birth_day, '%Y-%m-%d') - if birth_date < oldest_birth_day: - oldest_birth_day = birth_date - oldest_user_id = user_id + oldest_user = min(users, key=lambda user: datetime.strptime(user[1], '%Y-%m-%d')) + oldest_user_id = oldest_user[0] + # Create a list of user_ids from the accounts + user_ids = [user_id for user_id, _ in accounts] + # Find the index of the oldest_user_id + index = user_ids.index(oldest_user_id) - # Find the bank that owns the oldest user - for user_id, bank_id in accounts: - if user_id == oldest_user_id: - return bank_id + return accounts[index][1] @db_connection @@ -294,37 +277,32 @@ def print_table(cursor, table_name): print(", ".join(map(str, row))) +# bank_2 : set(acc1 acc2) @db_connection def bank_with_highest_unique_users(cursor): - # Create a dictionary to store the number of unique users for each bank - unique_users_by_bank = {} - - # Select all transactions from the BankTransaction table cursor.execute("SELECT Bank_sender_name, Account_sender_id FROM BankTransaction") transactions = cursor.fetchall() - # Count the number of unique users for each bank + unique_users_by_bank = defaultdict(set) + for bank_name, account_id in transactions: - if bank_name not in unique_users_by_bank: - unique_users_by_bank[bank_name] = set() unique_users_by_bank[bank_name].add(account_id) - # Find the bank with the unique users - bank_with_highest_users = max(unique_users_by_bank.items(), key=lambda x: len(x[1])) + unique_user_counts = Counter({bank: len(users) for bank, users in unique_users_by_bank.items()}) + + bank_with_highest_users = unique_user_counts.most_common(1)[0] return bank_with_highest_users[0] @db_connection def delete_users_with_incomplete_info(cursor): - while True: - cursor.execute("SELECT id FROM User WHERE Name IS NULL OR Surname IS NULL OR Birth_day IS NULL") - result = cursor.fetchone() - if result is None: - break + cursor.execute("SELECT id FROM User WHERE Name IS NULL OR Surname IS NULL OR Birth_day IS NULL") + result = cursor.fetchall() + for i in result: deleted_user_id = result[0] - cursor.execute("DELETE FROM Account WHERE User_id = ?", (deleted_user_id,)) - cursor.execute("DELETE FROM User WHERE id = ?", (deleted_user_id,)) + delete_user(deleted_user_id) + return "Deletion complete" diff --git a/hw_4/main.py b/hw_4/main.py index e93ffdc..36ba7e5 100644 --- a/hw_4/main.py +++ b/hw_4/main.py @@ -32,7 +32,7 @@ def init_args(): def do_func_with_args(args): # to be able to perform multiple functions if args.add_path and args.table_name: - api.add_table_by_file(args.add_path, args.table_name) + api.add_generic_by_path(args.add_path, args.table_name) if args.table_name and args.row_id and args.column and args.value: api.update_row(args.table_name, args.row_id, args.column, args.value) if args.clear_table: diff --git a/hw_4/validate.py b/hw_4/validate.py index 8a9e574..61cf166 100644 --- a/hw_4/validate.py +++ b/hw_4/validate.py @@ -12,9 +12,12 @@ def validate_user_full_name(user_full_name): # Validation of fields with a strict set of values -def validate_field_value(field, value, allowed_values): +def validate_field_value(field, value, allowed_values, strict = True): if value not in allowed_values: - raise ValueError("error: not allowed value {} for field {}!".format(value, field)) + if strict: + raise ValueError("error: not allowed value {} for field {}!".format(value, field)) + return False + return True def valid_acc(data): type_values = ["credit", "debit"] @@ -50,3 +53,19 @@ def add_transaction_time(transaction_time): if not transaction_time: transaction_time = datetime.now() return transaction_time + + +def valid_currency_amount(sender_amount,sent_amount,sender_currency,receiver_currency ): + if sender_amount <= sent_amount: + raise ValueError("not enough money in the account") + if receiver_currency != sender_currency: + return True + +def username_validate(data): + if not validate_field_value("user_name", "user_name", dict.keys(data[0]), False): + return data + for i in data: + i["name"] = validate_user_full_name(i["user_name"])[0] + i["surname"] = validate_user_full_name(i["user_name"])[1] + del i["user_name"] + return data \ No newline at end of file From c9935ef8bd81e46905b1489abf85a1bd8820481d Mon Sep 17 00:00:00 2001 From: ValeZh Date: Wed, 29 May 2024 20:15:36 +0300 Subject: [PATCH 2/3] I hate tests --- hw_4/api.py | 36 ++++++---- hw_4/tests/unit/test_api.py | 132 ++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 12 deletions(-) create mode 100644 hw_4/tests/unit/test_api.py diff --git a/hw_4/api.py b/hw_4/api.py index 0e25113..e1334b6 100644 --- a/hw_4/api.py +++ b/hw_4/api.py @@ -10,6 +10,7 @@ import random from collections import Counter, defaultdict + formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(name)s:%(message)s') my_logger = logging.getLogger('CustomLogger') my_handler = logging.FileHandler('file.log') @@ -44,14 +45,16 @@ def unpack_data(data): def format_data_string(data): - formatted_string = ', '.join(f'{item}' for item in data[0]) - formatted_string_colon = ', '.join(f':{item}' for item in data[0]) + print(data) + formatted_string = ', '.join(f'{item}' for item in dict.keys(data[0])) + formatted_string_colon = ', '.join(f':{item}' for item in dict.keys(data[0])) return formatted_string, formatted_string_colon @db_connection def add_generic_by_path(cur, path, table_name): data = read_csv_to_dict(path) + print(data) data = validate.username_validate(data) column, form_column = format_data_string(data) cur.executemany(f"INSERT INTO {table_name}({column}) VALUES({form_column})", data) @@ -69,9 +72,9 @@ def unpack_to_string(data): # fills the table account - def set_accounts(cur, data): for i in data: + # import pdb;pdb.set_trace() cur.execute("SELECT id FROM Account WHERE user_id = ?", (i["user_id"],)) numb_of_acc = cur.fetchall() account_str = unpack_to_string(numb_of_acc) @@ -160,18 +163,23 @@ def account_valid(sender_amount, sent_amount, sender_currency, receiver_currency transfer_time = validate.add_transaction_time(transfer_time) return sent_amount, transfer_time - -def transfer_money(sender_id, receiver_id, sent_amount, transfer_time=None): - currency_dict = get_currency_data() - my_logger.info('valid current success') - - # pull the necessary data to fill the transaction table +def get_data_by_id(sender_id, receiver_id): bank_sender_name = get_bankname(sender_id) bank_receiver_name = get_bankname(receiver_id) sender_amount = get_data_from_table("Amount", "Account", sender_id) receiver_amount = get_data_from_table("Amount", "Account", receiver_id) sender_currency = get_data_from_table("Currency", "Account", sender_id) receiver_currency = get_data_from_table("Currency", "Account", receiver_id) + return bank_sender_name, bank_receiver_name, sender_amount, receiver_amount, sender_currency, receiver_currency + +def transfer_money(sender_id, receiver_id, sent_amount, transfer_time=None): + currency_dict = get_currency_data() + my_logger.info('valid current success') + + # тестировать количество вызовов функции + # pull the necessary data to fill the transaction table + (bank_sender_name, bank_receiver_name, sender_amount, receiver_amount, + sender_currency, receiver_currency) = get_data_by_id(sender_id, receiver_id) sent_amount, transfer_time = account_valid(sender_amount, sent_amount, sender_currency, receiver_currency, currency_dict, transfer_time) @@ -189,12 +197,16 @@ def transfer_money(sender_id, receiver_id, sent_amount, transfer_time=None): my_logger.info("success") return "success" - @db_connection -def select_random_users_with_discounts(cursor): +def select_id_from_user(cursor): cursor.execute("SELECT Id FROM User") - all_users = cursor.fetchall() + return cursor.fetchall() + +def select_random_users_with_discounts(): + all_users = select_id_from_user() + print(all_users) random_users = random.sample(all_users, min(10, len(all_users))) # Randomly select up to 10 users + print(random_users ) user_discounts = {} # comprehension use for user_id in random_users: diff --git a/hw_4/tests/unit/test_api.py b/hw_4/tests/unit/test_api.py new file mode 100644 index 0000000..a24e29e --- /dev/null +++ b/hw_4/tests/unit/test_api.py @@ -0,0 +1,132 @@ +import sys +from unittest.mock import MagicMock, patch, mock_open, call +import pytest +import requests +from functools import wraps + + +from api import unpack_to_string, convert_currency, format_data_string, unpack_data +import pytest +import requests +from functools import wraps + +def test_unpack_to_string(): + input_data = [(1, 2, 3), (4, 5), (6,)] + actual = unpack_to_string(input_data) + expected = '1,2,3,4,5,6' + assert actual == expected + +def test_convert_currency(): + input_data_1 = {'AUD': 1.5087302415, 'BGN': 1.7944802113, 'BRL': 5.1709607454, 'CAD': 1.3662601591, 'CHF': 0.9142001532, + 'CNY': 7.2410307379, 'CZK': 22.7015437907, 'DKK': 6.880361225, 'EUR': 0.9215801687, 'GBP': 0.7851001494, + 'HKD': 7.8098112804, 'HRK': 6.6462708211, 'HUF': 353.9114355311, 'IDR': 15972.272064036, 'ILS': 3.657970377, + 'INR': 82.9986356329, 'ISK': 138.25410507, 'JPY': 156.989784703, 'KRW': 1363.8085527748, 'MXN': 16.7282428767, + 'MYR': 4.7111009312, 'NOK': 10.5840419142, 'NZD': 1.6331801746, 'PHP': 58.1784177311, 'PLN': 3.912080408, + 'RON': 4.5850908988, 'RUB': 89.5966276992, 'SEK': 10.6642017923, 'SGD': 1.3488202508, 'THB': 36.635135533, + 'TRY': 32.2610938602, 'USD': 1, 'ZAR': 18.4172320138} + input_data_2 = 'USD' + input_data_3 = 'EUR' + input_data_4 = 500 + actual = convert_currency(input_data_1, input_data_2, input_data_3, input_data_4 ) + expected = 460.79 + assert actual == expected + +def test_string_elements(): + data = [{'a': 23, 'b': 34, 'c': 90}, {'d': 90, 'f': 78, 'g': 54}] + expected = ('a, b, c', ':a, :b, :c') + actual = format_data_string(data) + assert actual == expected + +def test_unpack_data(): + input_data = {'name': 'Alice', 'age': 30, 'city': 'Wonderland'} + expected_result = ['Alice', 30, 'Wonderland'] + result = unpack_data(input_data) + assert list(result) == expected_result + + + +@patch('api.get_currency_data', return_value={'CNY': 7.2410307379,'USD': 1 }) +@patch('api.get_data_by_id', return_value=['Bank1', 'Bank2',400,300,'USD','CNY']) +@patch('api.account_valid', return_value=[540.70, '2024-05-29 17:58:41.245018']) +@patch('api.update_row') +@patch('api.insert_transaction') +def test_transfer_money(mock_f_1, mock_f_2, mock_f_3, mock_f_4, mock_f_5): + from api import transfer_money + sender_id = 1 + receiver_id = 3 + sent_amount = 900 + result = transfer_money(sender_id, receiver_id, sent_amount) + expected_call_func_dict = {'get_currency_data': 1, + 'get_data_by_id': 2, + 'account_valid': 1, + 'update_row': 1, + 'insert_transaction': 1} + result_call_func_dict = {'get_currency_data': mock_f_1.call_count, + 'get_data_by_id': mock_f_2.call_count, + 'account_valid': mock_f_3.call_count, + 'update_row': mock_f_4.call_count, + 'insert_transaction': mock_f_5.call_count} + assert result == "success" + assert expected_call_func_dict == result_call_func_dict + +def test_set_accounts(): + from api import set_accounts + cursor = MagicMock() + data = [{'user_id': '1', 'type': 'credit', 'account_number': 'ID--dcd-123568744-', + 'bank_id': '3', 'currency': 'USD', 'amount': '1000', 'status': 'gold'}, + {'user_id': '3', 'type': 'debit', 'account_number': 'ID--xyz-987654-uvw', + 'bank_id': '2', 'currency': 'USD', 'amount': '500', 'status': 'silver'}] + set_accounts(cursor, data) + result = cursor.mock_calls + expected = [call.execute('SELECT id FROM Account WHERE user_id = ?', ('1',)), + call.fetchall(), + call.fetchall().__iter__(), + call.execute('UPDATE User SET Accounts = ? WHERE id = ?', ('', '1')), + call.execute('SELECT id FROM Account WHERE user_id = ?', ('3',)), + call.fetchall(), + call.fetchall().__iter__(), + call.execute('UPDATE User SET Accounts = ? WHERE id = ?', ('', '3'))] + assert result == expected + +@patch('validate.valid_currency_amount', return_value= True) +@patch('api.convert_currency', return_value= 450) +@patch('validate.add_transaction_time', return_value = '2024-05-29 17:58:41.245018') +def test_account_valid(mock_f_1, mock_f_2, mock_f_3): + from api import account_valid + result = account_valid(400,300,'USD','CNY', + {'CNY': 7.2410307379,'USD': 1 },'2023-05-11 12:33:12.245018') + expected = (450, '2024-05-29 17:58:41.245018') + expected_call_func_dict = {'valid_currency_amount': 1, 'convert_currency': 1, 'add_transaction_time': 1} + result_call_func_dict = {'valid_currency_amount': mock_f_1.call_count, + 'convert_currency': mock_f_2.call_count, 'add_transaction_time': mock_f_3.call_count} + + print(mock_f_1.call_count) + assert expected == result + assert expected_call_func_dict == result_call_func_dict + +""" +@patch('api.select_id_from_user', return_value= [(4,), (1,), (3,), (5,), (2,)]) +@patch('api.select_id_from_user', return_value=[(4,), (1,), (3,), (5,), (2,)]) +def test_select_random_users_with_discounts(): +""" + +''' +#sys.modules['db_con_decor'] = MagicMock() + +def mock_db_connection(func): + @wraps(func) + def wrapper(*args, **kwargs): + c = MagicMock() + result = func(c, *args, **kwargs) + + return wrapper + +patch('db_con_deco.db_connection', mock_db_connection).start() + +def test_update_row(): + from api import update_row + cur = MagicMock() + res = update_row(cur, "User", 1, None, "BUIXGSCG") + assert res == "success" + #cur.mock_calls) +''' \ No newline at end of file From bced03d558dec60caf6091584fa6a45524039291 Mon Sep 17 00:00:00 2001 From: ValeZh Date: Sat, 1 Jun 2024 18:12:35 +0300 Subject: [PATCH 3/3] I make a lot of test for api I make tests for validate --- hw_4/api.py | 74 +++++++++++------- hw_4/bank.db | Bin 36864 -> 36864 bytes hw_4/db_con_decor.py | 1 - hw_4/main.py | 1 - hw_4/tests/unit/test_api.py | 125 ++++++++++++++++++++++++------- hw_4/tests/unit/test_validate.py | 102 +++++++++++++++++++++++++ hw_4/user.csv | 2 +- hw_4/validate.py | 6 +- 8 files changed, 251 insertions(+), 60 deletions(-) create mode 100644 hw_4/tests/unit/test_validate.py diff --git a/hw_4/api.py b/hw_4/api.py index e1334b6..9e674c6 100644 --- a/hw_4/api.py +++ b/hw_4/api.py @@ -59,6 +59,8 @@ def add_generic_by_path(cur, path, table_name): column, form_column = format_data_string(data) cur.executemany(f"INSERT INTO {table_name}({column}) VALUES({form_column})", data) if table_name == "Account": + data = validate.valid_acc(data) + data = validate.validate_account_number(data) set_accounts(cur, data) my_logger.info(f"{table_name} added successfully.") @@ -204,9 +206,9 @@ def select_id_from_user(cursor): def select_random_users_with_discounts(): all_users = select_id_from_user() - print(all_users) + random_users = random.sample(all_users, min(10, len(all_users))) # Randomly select up to 10 users - print(random_users ) + print(random_users) user_discounts = {} # comprehension use for user_id in random_users: @@ -217,36 +219,42 @@ def select_random_users_with_discounts(): my_logger.info("select_random_users_with_discounts success") return user_discounts - @db_connection -def user_with_highest_amount(cursor): +def select_for_user_with_highest_amount(cursor): cursor.execute(''' SELECT User_id FROM Account ORDER BY Amount DESC LIMIT 1 ''') - user_id = cursor.fetchone()[0] + return cursor.fetchone()[0] + + + +def user_with_highest_amount(): + user_id = select_for_user_with_highest_amount() + print(user_id) name = get_data_from_table("name", "User", user_id) my_logger.info(name) my_logger.info("user_with_highest_amount success") return name - @db_connection -def bank_with_biggest_capital(cursor): - currency_dict = get_currency_data() - # Extract all records from the Account table +def select_for_bank_with_biggest_capital(cursor): cursor.execute("SELECT Bank_id, Currency, Amount FROM Account") - accounts = cursor.fetchall() + return cursor.fetchall() + +def bank_with_biggest_capital(): + currency_dict = get_currency_data() + # Extract all records from the Account table + accounts = select_for_bank_with_biggest_capital() # Create a dictionary to store total capital for each bank in dollars bank_capital = {} # Create a dictionary to store the total capital for each bank in dollars for bank_id, currency, amount in accounts: amount_in_usd = convert_currency(currency_dict, currency, 'USD', amount) - # dict.setdefault() .append() .sum() / default_dict / if bank_id in bank_capital: bank_capital[bank_id] += amount_in_usd else: @@ -258,15 +266,17 @@ def bank_with_biggest_capital(cursor): my_logger.info("bank_with_biggest_capital success") return max_capital_bank_id - @db_connection -def bank_serving_oldest_client(cursor): +def select_for_bank_serving_oldest_client(cursor): cursor.execute("SELECT Id, Birth_day FROM User") users = cursor.fetchall() cursor.execute("SELECT User_id, Bank_id FROM Account") accounts = cursor.fetchall() + return users, accounts +def bank_serving_oldest_client(): + users, accounts = select_for_bank_serving_oldest_client() oldest_user = min(users, key=lambda user: datetime.strptime(user[1], '%Y-%m-%d')) oldest_user_id = oldest_user[0] # Create a list of user_ids from the accounts @@ -288,13 +298,15 @@ def print_table(cursor, table_name): for row in rows: print(", ".join(map(str, row))) - -# bank_2 : set(acc1 acc2) @db_connection -def bank_with_highest_unique_users(cursor): +def select_for_bank_with_highest_unique_users(cursor): cursor.execute("SELECT Bank_sender_name, Account_sender_id FROM BankTransaction") - transactions = cursor.fetchall() + return cursor.fetchall() +# bank_2 : set(acc1 acc2) +def bank_with_highest_unique_users(): + transactions = select_for_bank_with_highest_unique_users() + print(transactions) unique_users_by_bank = defaultdict(set) for bank_name, account_id in transactions: @@ -306,21 +318,31 @@ def bank_with_highest_unique_users(cursor): return bank_with_highest_users[0] - @db_connection -def delete_users_with_incomplete_info(cursor): +def select_for_delete_users_with_incomplete_info(cursor): cursor.execute("SELECT id FROM User WHERE Name IS NULL OR Surname IS NULL OR Birth_day IS NULL") - result = cursor.fetchall() + return cursor.fetchall() + + +def delete_users_with_incomplete_info(): + result = select_for_delete_users_with_incomplete_info() for i in result: deleted_user_id = result[0] delete_user(deleted_user_id) return "Deletion complete" - @db_connection -def get_user_transactions(c, user_id): +def select_for_get_user_transactions(c, user_id, start_date_str, end_date_str): + c.execute(''' + SELECT * FROM BankTransaction + WHERE (Account_sender_id = ? OR Account_receiver_id = ?) + AND Datetime BETWEEN ? AND ? + ''', (user_id, user_id, start_date_str, end_date_str)) + return c.fetchall() + +def get_user_transactions(user_id): # Calculate the date three months ago from today end_date = datetime.now() start_date = end_date - timedelta(days=90) @@ -328,12 +350,6 @@ def get_user_transactions(c, user_id): # Convert dates to string format for SQL query start_date_str = start_date.strftime('%Y-%m-%d %H:%M:%S') end_date_str = end_date.strftime('%Y-%m-%d %H:%M:%S') + return select_for_get_user_transactions(user_id, start_date_str, end_date_str) - query = ''' - SELECT * FROM BankTransaction - WHERE (Account_sender_id = ? OR Account_receiver_id = ?) - AND Datetime BETWEEN ? AND ? - ''' - c.execute(query, (user_id, user_id, start_date_str, end_date_str)) - return c.fetchall() \ No newline at end of file diff --git a/hw_4/bank.db b/hw_4/bank.db index c7d0bcd3bea30be3eeba65cf5b74b233350eb5d8..699000613eb1007ccfe480fc1db0a94727acfa7f 100644 GIT binary patch delta 1035 zcmb7@KWGzC9LMi2N#o@%_s)b4l{O|@5bnJ9?%ln22d~t$in{oxbSs!(qsFF5Orulj zWpNUWa)N8YfP)1oCp3bSi-QhA2Nws2;!r_E)WOM%U>&T1d&7g@@cI3I-{1H5>uw0$ z4dLDqfzRBZEQSA8xqrNvk+wPT3fu(?U`p9lo+x!iOMgy3O}Ele{wfD@N4BIN(soc# z??@iYh+IJ&=d;NZv)3xC)qJVaSUx>pnvE^Y&&_ndUHEi6H$Vo$nqg_k$wT5=)WuLo z*fJnxhed9jFNh)j8~U5$B}b}15I4f@(;Z47waD18`(SIj!V91u9zzcJ=-h`uJ^vge;;}S8 z=D)pE3e@tmKjG^pQQBNW+2oX6&{sCWsX%Q#R{W3ax#WYN#qTeBi@xL;(`yeGhr!im zeMw7*96tfYtS}M3+^#OwI%noI?fPO$SwZ_dAzwedh1n6;K5A?tbuoI}=FW?t&X%Bz^ delta 201 zcmZozz|^pSX@V3J!^w#