From 9dde0312c8537ee41bb4a47f9b54ace5b6e4ffa4 Mon Sep 17 00:00:00 2001 From: worthyworm <99085361+worthyworm@users.noreply.github.com> Date: Sun, 1 Mar 2026 19:37:48 +0300 Subject: [PATCH 1/8] Add language saving --- source/ui_handler.py | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/source/ui_handler.py b/source/ui_handler.py index 51779bf..5b716ca 100644 --- a/source/ui_handler.py +++ b/source/ui_handler.py @@ -1,28 +1,29 @@ import os import json -import sys from __init__ import INFO while True: try: - lang = int(input("[1] - English\n[2] - Русский\n>>>")) - if lang == 1: - lang = 'en' - break - elif lang == 2: - lang = 'ru' - break - else: - print("Out of range.") - - except ValueError: - print('Invalid choice') - - except Exception as e: - print(f'ERROR: {e}') - input('Press Enter to exit...') - sys.exit(1) + with open('preferences.json', 'r', encoding='utf-8') as f: + preferences = json.load(f) + lang = preferences['lang'] + break + except FileNotFoundError: + with open('preferences.json', 'w', encoding='utf-8') as f: + lang = int(input("[1] - English\n[2] - Русский\n>>>")) + if lang == 1: + lang = 'en' + with open('preferences.json', 'w', encoding='utf-8') as f: + json.dump({"lang": lang}, f, ensure_ascii=False, indent=4) + break + elif lang == 2: + lang = 'ru' + with open('preferences.json', 'w', encoding='utf-8') as f: + json.dump({"lang": lang}, f, ensure_ascii=False, indent=4) + break + else: + print("Out of range.") with open(f'locales/lang_{lang}.json', 'r', encoding='utf-8') as f: From b4135b5af40eb790eea1ca5799220f645093cc0c Mon Sep 17 00:00:00 2001 From: worthyworm <99085361+worthyworm@users.noreply.github.com> Date: Sun, 1 Mar 2026 21:49:30 +0300 Subject: [PATCH 2/8] Add sports saving, error handling in menu, preferences --- README.md | 2 +- locales/lang_en.json | 3 ++- locales/lang_ru.json | 3 ++- source/__init__.py | 2 +- source/data_handler.py | 37 ++++++++++++++++++++++++++++++++++--- source/main.py | 9 ++++++++- source/ui_handler.py | 24 ++++++++++++++++++++++-- 7 files changed, 70 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 4da09ea..76e8e86 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Showoff - A simple sports stats tracker -![Version](https://img.shields.io/badge/version-2.0.0-blue) +![Version](https://img.shields.io/badge/version-2.0.1-blue) ![Python](https://img.shields.io/badge/python-3.9+-green) ![License](https://img.shields.io/badge/license-MIT-orange) ![made with love](https://img.shields.io/badge/made%20with-%3C3-red) diff --git a/locales/lang_en.json b/locales/lang_en.json index 819cba9..4d06e00 100644 --- a/locales/lang_en.json +++ b/locales/lang_en.json @@ -51,5 +51,6 @@ "per_game": "PER-GAME", "value": "VALUE", "change_lang": "Change language", - "unsupported_version": "Unsupported save version\nFor more information, see the readme" + "unsupported_version": "Unsupported save version\nFor more information, see the readme", + "changed_sport": "Sport changed to" } \ No newline at end of file diff --git a/locales/lang_ru.json b/locales/lang_ru.json index 5a27ea5..55cb0ea 100644 --- a/locales/lang_ru.json +++ b/locales/lang_ru.json @@ -51,5 +51,6 @@ "per_game": "ЗА-ИГРУ", "value": "ЗНАЧ", "change_lang": "Смена языка", - "unsupported_version": "Неподдерживаемая версия сохранения\nДля большей информации, смотрите README.md" + "unsupported_version": "Неподдерживаемая версия сохранения\nДля большей информации, смотрите README.md", + "changed_sport": "Спорт изменен на" } \ No newline at end of file diff --git a/source/__init__.py b/source/__init__.py index a8b4286..06455eb 100644 --- a/source/__init__.py +++ b/source/__init__.py @@ -1,4 +1,4 @@ -VERSION = '2.0.0' +VERSION = '2.0.1' LOGO = """ ███████╗██╗ ██╗ ██████╗ ██╗ ██╗ ██████╗ ███████╗███████╗ ██╔════╝██║ ██║██╔═══██╗██║ ██║██╔═══██╗██╔════╝██╔════╝ diff --git a/source/data_handler.py b/source/data_handler.py index c6b499b..a835072 100644 --- a/source/data_handler.py +++ b/source/data_handler.py @@ -4,15 +4,35 @@ from ui_handler import texts from __init__ import VERSION +sport = 0 + +try: + with open('preferences.json', 'r', encoding='utf-8') as f: + preferences = json.load(f) + if preferences['sport'] == 1: + sport = 1 + elif preferences['sport'] == 2: + sport = 2 + else: + pass +except KeyError: + pass + while True: try: - sport = int(input(f''' + if sport != 1 and sport != 2: + sport = int(input(f''' {texts["select_sport"]}: [1] - {texts["basketball"]} [2] - {texts["soccer"]} >>>''')) - if sport > 2 or sport < 1: - print("Invalid option") + if sport > 2 or sport < 1: + print("Invalid option") + else: + with open('preferences.json', 'w', encoding='utf-8') as f: + preferences['sport'] = sport + json.dump(preferences, f, ensure_ascii=False, indent=4) + break else: break except ValueError: @@ -65,6 +85,17 @@ sys.exit(1) +def change_sport(preferences): + with open('preferences.json', 'w', encoding='utf-8') as f: + if preferences['sport'] == 1: + preferences['sport'] = 2 + json.dump(preferences, f, ensure_ascii=False, indent=4) + print(f'{texts["changed_sport"]} {texts["soccer"]}') + else: + preferences['sport'] = 1 + json.dump(preferences, f, ensure_ascii=False, indent=4) + print(f'{texts["changed_sport"]} {texts["basketball"]}') + def add_match(): if sport == 1: while True: diff --git a/source/main.py b/source/main.py index 6ed3b51..4a1932c 100644 --- a/source/main.py +++ b/source/main.py @@ -21,6 +21,7 @@ games = data_handler.db["games"] export = export_handler texts = ui.texts +preferences = data_handler.preferences if db.sport == 1: sport = 'basketball' @@ -36,7 +37,9 @@ def main(): Menu.show_info(False) print(f"{texts["currently_in"]} {sport}") user_choice = Menu.create_menu() - + if user_choice == ValueError: + Menu.clear_screen() + pass if user_choice == 1: db.add_match() print(f"{texts["added"]}") @@ -77,6 +80,8 @@ def main(): Menu.clear_screen() elif user_choice == 5: + db.change_sport(preferences) + db.save() os.execl(sys.executable, sys.executable, *sys.argv) elif user_choice == 6: @@ -86,6 +91,8 @@ def main(): Menu.clear_screen() elif user_choice == 7: + ui_handler.change_lang(preferences) + db.save() os.execl(sys.executable, sys.executable, *sys.argv) elif user_choice == 8: diff --git a/source/ui_handler.py b/source/ui_handler.py index 5b716ca..b9743e0 100644 --- a/source/ui_handler.py +++ b/source/ui_handler.py @@ -43,13 +43,33 @@ DESCRIPTION = f"{texts["description"]}\nhttps://github.com/worthyworm/showoff" +def change_lang(preferences): + if lang == 'en': + with open('preferences.json', 'w', encoding='utf-8') as f: + preferences['lang'] = 'ru' + json.dump(preferences, f, ensure_ascii=False, indent=4) + print("Язык изменен на русский.") + input("Enter чтобы продолжить...") + elif lang == 'ru': + with open('preferences.json', 'w', encoding='utf-8') as f: + preferences['lang'] = 'en' + json.dump(preferences, f, ensure_ascii=False, indent=4) + print("Language set to English.") + input("Enter to continue...") + class Menu: @staticmethod def create_menu(): print(MENU) - choice = int(input(f"{texts["select"]} >> ")) - return choice + try: + choice = int(input(f"{texts["select"]} >> ")) + return choice + except ValueError: + choice = ValueError + return choice + except Exception as e: + print(f'ERROR: {e}') @staticmethod def show_info(full): From 46f19062fbff2e1da1dc092e4a921e22a3f8dc67 Mon Sep 17 00:00:00 2001 From: worthyworm <99085361+worthyworm@users.noreply.github.com> Date: Mon, 2 Mar 2026 00:15:25 +0300 Subject: [PATCH 3/8] Add settings --- locales/lang_en.json | 4 +++- locales/lang_ru.json | 4 +++- source/main.py | 24 +++++++++++++++--------- source/ui_handler.py | 22 +++++++++++++++++++--- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/locales/lang_en.json b/locales/lang_en.json index 4d06e00..652ce08 100644 --- a/locales/lang_en.json +++ b/locales/lang_en.json @@ -37,6 +37,7 @@ "stats_review": "Statistics review", "data_export": "Data export(.csv)", "change_sport": "Change sport", + "settings": "Settings", "about": "About", "exit": "Exit", "description": "Showoff is a simple sports self-statistics tracker for players or their coaches, written to be easy to use and to be informational.", @@ -52,5 +53,6 @@ "value": "VALUE", "change_lang": "Change language", "unsupported_version": "Unsupported save version\nFor more information, see the readme", - "changed_sport": "Sport changed to" + "changed_sport": "Sport changed to", + "back": "Back" } \ No newline at end of file diff --git a/locales/lang_ru.json b/locales/lang_ru.json index 55cb0ea..495a39d 100644 --- a/locales/lang_ru.json +++ b/locales/lang_ru.json @@ -37,6 +37,7 @@ "stats_review": "Статистика", "data_export": "Экспорт данных(.csv)", "change_sport": "Поменять спорт", + "settings": "Настройки", "about": "О приложении", "exit": "Выход", "description": "Showoff это простой трекер статистики для спорта, написанный чтобы быть легким и информациональным.", @@ -52,5 +53,6 @@ "value": "ЗНАЧ", "change_lang": "Смена языка", "unsupported_version": "Неподдерживаемая версия сохранения\nДля большей информации, смотрите README.md", - "changed_sport": "Спорт изменен на" + "changed_sport": "Спорт изменен на", + "back": "Назад" } \ No newline at end of file diff --git a/source/main.py b/source/main.py index 4a1932c..718da10 100644 --- a/source/main.py +++ b/source/main.py @@ -40,7 +40,7 @@ def main(): if user_choice == ValueError: Menu.clear_screen() pass - if user_choice == 1: + elif user_choice == 1: db.add_match() print(f"{texts["added"]}") db.save() @@ -80,9 +80,20 @@ def main(): Menu.clear_screen() elif user_choice == 5: - db.change_sport(preferences) - db.save() - os.execl(sys.executable, sys.executable, *sys.argv) + print(f'{texts["settings"]}:') + choice = Menu.settings_menu() + if choice == 1: + ui_handler.change_lang(preferences) + db.save() + os.execl(sys.executable, sys.executable, *sys.argv) + elif choice == 2: + db.change_sport(preferences) + db.save() + os.execl(sys.executable, sys.executable, *sys.argv) + elif choice == 3: + pass + elif choice == ValueError: + pass elif user_choice == 6: Menu.clear_screen() @@ -91,11 +102,6 @@ def main(): Menu.clear_screen() elif user_choice == 7: - ui_handler.change_lang(preferences) - db.save() - os.execl(sys.executable, sys.executable, *sys.argv) - - elif user_choice == 8: break diff --git a/source/ui_handler.py b/source/ui_handler.py index b9743e0..21b2761 100644 --- a/source/ui_handler.py +++ b/source/ui_handler.py @@ -34,11 +34,15 @@ [2] - {texts["view_games"]} [3] - {texts["stats_review"]} [4] - {texts["data_export"]} -[5] - {texts["change_sport"]} +[5] - {texts["settings"]} [6] - {texts["about"]} -[7] - {texts["change_lang"]} -[8] - {texts["exit"]} +[7] - {texts["exit"]} +""" +SETTINGS_MENU = f""" +[1] - {texts["change_lang"]} +[2] - {texts["change_sport"]} +[3] - {texts["back"]} """ DESCRIPTION = f"{texts["description"]}\nhttps://github.com/worthyworm/showoff" @@ -81,3 +85,15 @@ def show_info(full): @staticmethod def clear_screen(): os.system('cls' if os.name == 'nt' else 'clear') + + @staticmethod + def settings_menu(): + try: + print(SETTINGS_MENU) + choice = int(input(f"{texts["select"]} >> ")) + return choice + except ValueError: + choice = ValueError + return choice + except Exception as e: + print(f'ERROR: {e}') \ No newline at end of file From 2a6622203e36bd4b40737f4d3c4dbb2af909442d Mon Sep 17 00:00:00 2001 From: worthyworm <99085361+worthyworm@users.noreply.github.com> Date: Mon, 2 Mar 2026 00:17:06 +0300 Subject: [PATCH 4/8] Update README.md --- README.md | 2 +- source/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 76e8e86..0c3c539 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Showoff - A simple sports stats tracker -![Version](https://img.shields.io/badge/version-2.0.1-blue) +![Version](https://img.shields.io/badge/version-2.1.0-blue) ![Python](https://img.shields.io/badge/python-3.9+-green) ![License](https://img.shields.io/badge/license-MIT-orange) ![made with love](https://img.shields.io/badge/made%20with-%3C3-red) diff --git a/source/__init__.py b/source/__init__.py index 06455eb..1a83449 100644 --- a/source/__init__.py +++ b/source/__init__.py @@ -1,4 +1,4 @@ -VERSION = '2.0.1' +VERSION = '2.1.0' LOGO = """ ███████╗██╗ ██╗ ██████╗ ██╗ ██╗ ██████╗ ███████╗███████╗ ██╔════╝██║ ██║██╔═══██╗██║ ██║██╔═══██╗██╔════╝██╔════╝ From fbf3ec01a529b1d6a2dadb9fba19637eab82a25a Mon Sep 17 00:00:00 2001 From: worthyworm <99085361+worthyworm@users.noreply.github.com> Date: Mon, 2 Mar 2026 16:45:33 +0300 Subject: [PATCH 5/8] Optimize ui_handler --- source/main.py | 2 +- source/ui_handler.py | 23 ++++++++++------------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/source/main.py b/source/main.py index 718da10..ced7268 100644 --- a/source/main.py +++ b/source/main.py @@ -83,7 +83,7 @@ def main(): print(f'{texts["settings"]}:') choice = Menu.settings_menu() if choice == 1: - ui_handler.change_lang(preferences) + ui_handler.change_lang(preferences, ui_handler.lang) db.save() os.execl(sys.executable, sys.executable, *sys.argv) elif choice == 2: diff --git a/source/ui_handler.py b/source/ui_handler.py index 21b2761..0f0936f 100644 --- a/source/ui_handler.py +++ b/source/ui_handler.py @@ -14,13 +14,11 @@ lang = int(input("[1] - English\n[2] - Русский\n>>>")) if lang == 1: lang = 'en' - with open('preferences.json', 'w', encoding='utf-8') as f: - json.dump({"lang": lang}, f, ensure_ascii=False, indent=4) + json.dump({"lang": lang}, f, ensure_ascii=False, indent=4) break elif lang == 2: lang = 'ru' - with open('preferences.json', 'w', encoding='utf-8') as f: - json.dump({"lang": lang}, f, ensure_ascii=False, indent=4) + json.dump({"lang": lang}, f, ensure_ascii=False, indent=4) break else: print("Out of range.") @@ -47,19 +45,18 @@ DESCRIPTION = f"{texts["description"]}\nhttps://github.com/worthyworm/showoff" -def change_lang(preferences): - if lang == 'en': - with open('preferences.json', 'w', encoding='utf-8') as f: +def change_lang(preferences, lang): + with open('preferences.json', 'w', encoding='utf-8') as f: + if lang == 'en': preferences['lang'] = 'ru' json.dump(preferences, f, ensure_ascii=False, indent=4) - print("Язык изменен на русский.") - input("Enter чтобы продолжить...") - elif lang == 'ru': - with open('preferences.json', 'w', encoding='utf-8') as f: + print("Язык изменен на русский.") + input("Enter чтобы продолжить...") + elif lang == 'ru': preferences['lang'] = 'en' json.dump(preferences, f, ensure_ascii=False, indent=4) - print("Language set to English.") - input("Enter to continue...") + print("Language set to English.") + input("Enter to continue...") class Menu: From 147b785e0b1910647f3245c3d3afd8a21af9d9b9 Mon Sep 17 00:00:00 2001 From: worthyworm <99085361+worthyworm@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:29:22 +0300 Subject: [PATCH 6/8] Add auto version updating in savefiles --- source/data_handler.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/data_handler.py b/source/data_handler.py index a835072..fc94145 100644 --- a/source/data_handler.py +++ b/source/data_handler.py @@ -165,6 +165,9 @@ def add_match(): def save(): + if db['version'] != VERSION: + db['version'] = VERSION + if sport == 1: try: with open('basketball.json', 'w', encoding='utf-8') as f: From 2d4a65d4409c56b4f2815bb3d1cb0ebcb7dcceb8 Mon Sep 17 00:00:00 2001 From: worthyworm <99085361+worthyworm@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:45:06 +0300 Subject: [PATCH 7/8] Add name and date printing for the game --- source/statistics_handler.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/statistics_handler.py b/source/statistics_handler.py index c72d7c0..a933103 100644 --- a/source/statistics_handler.py +++ b/source/statistics_handler.py @@ -78,6 +78,9 @@ def calculate_efficiency(points, rebounds, assists, steals, blocks, missed, miss def show_stats(match_index): + print(f'{texts["name"]}: {games[match_index]["name"]}') + print(f'{texts["date"]}: {games[match_index]["date"]}') + print("─" * 35) if sport == 1: table = [["Points", str(games[match_index]["points"])], ["Minutes", str(games[match_index]["minutes"])], ["2 Pointers", f'{str(games[match_index]["2pt_shots_made"])}/{str(games[match_index]["2pt_attempts"])}'], ["3 Pointers", f'{str(games[match_index]["3pt_shots_made"])}/{str(games[match_index]["3pt_attempts"])}'], From 8c08fa63fbebc7129c1d3f9afb1873cb5bc5271d Mon Sep 17 00:00:00 2001 From: worthyworm <99085361+worthyworm@users.noreply.github.com> Date: Mon, 2 Mar 2026 17:45:06 +0300 Subject: [PATCH 8/8] Add name and date printing for the game, add locales --- locales/lang_en.json | 4 +++- locales/lang_ru.json | 4 +++- source/statistics_handler.py | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/locales/lang_en.json b/locales/lang_en.json index 652ce08..65aff0e 100644 --- a/locales/lang_en.json +++ b/locales/lang_en.json @@ -54,5 +54,7 @@ "change_lang": "Change language", "unsupported_version": "Unsupported save version\nFor more information, see the readme", "changed_sport": "Sport changed to", - "back": "Back" + "back": "Back", + "name": "Name", + "date": "Date" } \ No newline at end of file diff --git a/locales/lang_ru.json b/locales/lang_ru.json index 495a39d..f2babec 100644 --- a/locales/lang_ru.json +++ b/locales/lang_ru.json @@ -54,5 +54,7 @@ "change_lang": "Смена языка", "unsupported_version": "Неподдерживаемая версия сохранения\nДля большей информации, смотрите README.md", "changed_sport": "Спорт изменен на", - "back": "Назад" + "back": "Назад", + "name": "Имя", + "date": "Дата" } \ No newline at end of file diff --git a/source/statistics_handler.py b/source/statistics_handler.py index c72d7c0..a933103 100644 --- a/source/statistics_handler.py +++ b/source/statistics_handler.py @@ -78,6 +78,9 @@ def calculate_efficiency(points, rebounds, assists, steals, blocks, missed, miss def show_stats(match_index): + print(f'{texts["name"]}: {games[match_index]["name"]}') + print(f'{texts["date"]}: {games[match_index]["date"]}') + print("─" * 35) if sport == 1: table = [["Points", str(games[match_index]["points"])], ["Minutes", str(games[match_index]["minutes"])], ["2 Pointers", f'{str(games[match_index]["2pt_shots_made"])}/{str(games[match_index]["2pt_attempts"])}'], ["3 Pointers", f'{str(games[match_index]["3pt_shots_made"])}/{str(games[match_index]["3pt_attempts"])}'],