Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,5 @@ soccer.json
*.csv

.vscode/
showoff/
showoff/
*.json
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
# Showoff - A simple sports stats tracker

![Version](https://img.shields.io/badge/version-2.1.0-blue)
![Python](https://img.shields.io/badge/python-3.9+-green)
![Version](https://img.shields.io/badge/version-2.1.1-blue)
![Python](https://img.shields.io/badge/python-3.11+-green)
![License](https://img.shields.io/badge/license-GPLv3-orange)
![made with love](https://img.shields.io/badge/made%20with-%3C3-red)

> **Versions below v2.0.0 are temporarily not-supported. Stay tuned for updates!**

Showoff is a simple sports self-statistics tracker for players or their coaches, written to be easy to use and to be informational.
Currently supports basketball, soccer.
You can also offer your sport, or help with existing ones

## Requirements

Expand All @@ -19,7 +16,7 @@ You can also offer your sport, or help with existing ones

## Running

You can run showoff using [binaries for your system](https://github.com/worthyworm/showoff/releases/latest) or using the source code.
You can run showoff using [binaries for your system](https://github.com/80degree/showoff/releases/latest) or using the source code.

### Using ready-to-use binaries(recommended)

Expand All @@ -30,11 +27,11 @@ You can run showoff using [binaries for your system](https://github.com/worthywo
| Platform | Latest Status | Latest Uploaded |
|----------|-----------------------------|--------------------|
| Windows | Awaits building | v2.0.0 |
| Linux | Ready ✅ | v2.1.0 |
| macOS | Ready ✅ | v2.1.0 |
| Linux | Ready ✅ | v2.1.1 |
| macOS | Ready ✅ | v2.1.1 |

1. Download the latest binary files for your system:
- [Latest Release](https://github.com/worthyworm/showoff/releases/latest)
- [Latest Release](https://github.com/80degree/showoff/releases/latest)

2. Unpack the binary in a convenient folder.

Expand Down
50 changes: 30 additions & 20 deletions locales/lang_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,35 @@
"game_date": "Enter date(dd.mm.yyyy)",
"game_basketball_position": "Select position:\n[1] - PG\n[2] - SG\n[3] - SF\n[4] - PF\n[5] - C",
"game_soccer_position": "Select position:\n[1] - GK\n[2] - SW\n[3] - LB\n[4] - CB\n[5] - RB\n[6] - RWB\n[7] - DM\n[7] - LM\n[8] - CM\n[9] - RM\n[10] - AM\n[11] - LW\n[12] - SS\n[13] - RW\n[14] - LF\n[15] - CF\n[16] - RF",
"game_saves": "Enter saves",
"game_minutes": "Enter playtime(minutes)",
"game_points": "Enter points",
"game_assists": "Enter assists",
"game_2pta": "Enter 2 Pointers attempted",
"game_3pta": "Enter 3 Pointers attempted",
"game_2ptm": "Enter 2 Pointers made",
"game_3ptm": "Enter 3 Pointers made",
"game_rebounds": "Enter rebounds",
"game_blocks": "Enter blocks",
"game_steals": "Enter steals",
"game_personal_fouls": "Enter fouls",
"game_missed_free_throws": "Enter missed free throws",
"game_turnovers": "Enter turnovers",
"game_result": "Enter result(W/L)",
"game_goals": "Enter goals",
"game_shots": "Enter shots",
"game_yellow_cards": "Enter yellow cards",
"game_red_cards": "Enter red cards",
"game_saves": "Saves",
"game_minutes": "Playtime(minutes)",
"game_points": "Points",
"game_assists": "Assists",
"game_2pta": "2 Pointers attempted",
"game_3pta": "3 Pointers attempted",
"game_2ptm": "2 Pointers made",
"game_3ptm": "3 Pointers made",
"game_2pt": "2 Pointers",
"game_3pt": "3 Pointers",
"game_rebounds": "Rebounds",
"game_blocks": "Blocks",
"game_steals": "Steals",
"game_personal_fouls": "Fouls",
"game_missed_free_throws": "Missed free throws",
"game_turnovers": "Turnovers",
"game_result": "Result(W/L)",
"game_goals": "Goals",
"game_shots": "Shots",
"game_yellow_cards": "Yellow cards",
"game_red_cards": "Red cards",
"game_position": "Position",
"game_missed": "Missed",
"currently_in": "Currently in",
"added": "Added!",
"enter_to_continue": "Enter to continue",
"game_to_show": "What game to show?(Leave blank to exit)",
"game_index_out": "Game index out of range",
"games_menu": "Games menu",
"add_game": "Add a game",
"view_games": "View your games",
"stats_review": "Statistics review",
Expand All @@ -56,5 +61,10 @@
"changed_sport": "Sport changed to",
"back": "Back",
"name": "Name",
"date": "Date"
"date": "Date",
"player": "Player",
"welcome_back": "Welcome back!",
"games_played": "Games played",
"last_game": "The last game was on",
"keep_up": "Keep up"
}
52 changes: 31 additions & 21 deletions locales/lang_ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,35 @@
"game_date": "Введите дату(дд.мм.гггг)",
"game_basketball_position": "Выберите позицию\n[1] - PG\n[2] - SG\n[3] - SF\n[4] - PF\n[5] - C",
"game_soccer_position": "Выберите позицию:\n[1] - GK\n[2] - SW\n[3] - LB\n[4] - CB\n[5] - RB\n[6] - RWB\n[7] - DM\n[7] - LM\n[8] - CM\n[9] - RM\n[10] - AM\n[11] - LW\n[12] - SS\n[13] - RW\n[14] - LF\n[15] - CF\n[16] - RF",
"game_saves": "Введите сейвы",
"game_minutes": "Введите игровое время(минуты)",
"game_points": "Введите очки",
"game_assists": "Введите помощи",
"game_2pta": "Введите все 2-очковые броски",
"game_3pta": "Введите все 3-очковые броски",
"game_2ptm": "Введите реализованные 2-очковые",
"game_3ptm": "Введите реализованные 3-очковые",
"game_rebounds": "Введите подборы",
"game_blocks": "Введите блоки",
"game_steals": "Введите перехваты",
"game_personal_fouls": "Введите фолы",
"game_missed_free_throws": "Введите промазанные штрафные",
"game_turnovers": "Введите потери",
"game_result": "Введите результат(W - победа/L - проигрыш)",
"game_goals": "Введите голы",
"game_shots": "Введите удары",
"game_yellow_cards": "Введите желтые карточки",
"game_red_cards": "Введите красные карточки",
"game_saves": "Сэйвов",
"game_minutes": "Игровое время(минуты)",
"game_points": "Очков",
"game_assists": "Помощи",
"game_2pta": "2х очковых попыток",
"game_3pta": "3х очковых попыток",
"game_2ptm": "2х очковых реализовано",
"game_3ptm": "3х очковых реализовано",
"game_2pt": "2х очковых",
"game_3pt": "3х очковых",
"game_rebounds": "Подборов",
"game_blocks": "Блоков",
"game_steals": "Перехватов",
"game_personal_fouls": "Фолов",
"game_missed_free_throws": "Промазано штрафных",
"game_turnovers": "Потерь",
"game_result": "Результат(W/L)",
"game_goals": "Голов",
"game_shots": "Ударов",
"game_yellow_cards": "Желтые карточки",
"game_red_cards": "Красные карточки",
"game_position": "Позиция",
"game_missed": "Промазано",
"currently_in": "Сейчас в",
"added": "Добавлено!",
"enter_to_continue": "Enter чтобы продолжить",
"game_to_show": "Какую игру показать?(Enter для выхода)",
"game_index_out": "Игра не существует",
"games_menu": "Меню Игр",
"add_game": "Добавить игру",
"view_games": "Посмотреть сохраненные игры",
"stats_review": "Статистика",
Expand All @@ -40,7 +45,7 @@
"settings": "Настройки",
"about": "О приложении",
"exit": "Выход",
"description": "Showoff это простой трекер статистики для спорта, написанный чтобы быть легким и информациональным.",
"description": "Showoff - легкое и удобное приложение для просмотра и экспорта статистики для спорта.",
"file_not_found": "Файл не найден",
"no_games": "Нет игр для экспорта",
"export_finished": "Экспортировано в файл",
Expand All @@ -56,5 +61,10 @@
"changed_sport": "Спорт изменен на",
"back": "Назад",
"name": "Имя",
"date": "Дата"
"date": "Дата",
"player": "Игрок",
"welcome_back": "С возвращением",
"games_played": "Сыграно игр",
"last_game": "Последняя игра была",
"keep_up": "Продолжайте в том же духе"
}
15 changes: 7 additions & 8 deletions source/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
VERSION = '2.1.0'
VERSION = '2.1.1'
LOGO = """
███████╗██╗ ██╗ ██████╗ ██╗ ██╗ ██████╗ ███████╗███████╗
██╔════╝██║ ██║██╔═══██╗██║ ██║██╔═══██╗██╔════╝██╔════╝
███████╗███████║██║ ██║██║ █╗ ██║██║ ██║█████╗ █████╗
╚════██║██╔══██║██║ ██║██║███╗██║██║ ██║██╔══╝ ██╔══╝
███████║██║ ██║╚██████╔╝╚███╔███╔╝╚██████╔╝██║ ██║
╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝
▗▄▄▖▐▌ ▄▄▄ ▄ ▄ ▄▄▄ ▗▞▀▀▘▗▞▀▀▘
▐▌ ▐▌ █ █ █ ▄ █ █ █ ▐▌ ▐▌
▝▀▚▖▐▛▀▚▖▀▄▄▄▀ █▄█▄█ ▀▄▄▄▀ ▐▛▀▘ ▐▛▀▘
▗▄▄▞▘▐▌ ▐▌ ▐▌ ▐▌

"""

INFO = f"""
{LOGO}
v{VERSION} - meeko 2026
v{VERSION} - worthyworm 2026
"""
85 changes: 45 additions & 40 deletions source/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,59 +27,64 @@
sport = 'basketball'
elif db.sport == 2:
sport = 'soccer'
#elif db.sport == 3:
# sport = 'volleyball'
#elid db.sport == 4:
# sport = 'football'

def main():
while True:
Menu.show_info(False)
print(f"{texts["currently_in"]} {sport}")
try:
print(f"{texts['welcome_back']}, {data_handler.db['player']}\n{texts['games_played']}: {len(games)}.\n{texts['last_game']}: {games[-1]['date']}, {texts['game_points']}: {games[-1]['points']}. {texts['keep_up']}!")
except IndexError:
pass
user_choice = Menu.create_menu()
if user_choice == ValueError:
Menu.clear_screen()
pass
elif user_choice == 1:
db.add_match()
print(f"{texts["added"]}")
db.save()
input(f"{texts["enter_to_continue"]}... ")
Menu.clear_screen()

elif user_choice == 2:
games_count = len(games)
for i in range(games_count):
print(f"{i + 1} - {str(games[i]['name'])}")
while True:
try:
choice = input(f"{texts["game_to_show"]}\n")
if choice != '' and int(choice) - 1 in range(games_count):
stats.show_stats(int(choice) - 1)
break
else:
print(f"{texts["game_index_out"]}.")
break
if user_choice == 1:
print(f'{texts["games_menu"]}:')
choice = Menu.games_menu()
if choice == ValueError:
Menu.clear_screen()
pass
if choice == 1:
db.add_match()
print(f"{texts["added"]}")
db.save()
input(f"{texts["enter_to_continue"]}... ")
Menu.clear_screen()
elif choice == 2:
games_count = len(games)
for i in range(games_count):
print(f"{i + 1} - {str(games[i]['name'])}")
while True:
try:
choice = input(f"{texts["game_to_show"]}\n")
if choice != '' and int(choice) - 1 in range(games_count):
stats.show_stats(int(choice) - 1)
break
else:
print(f"{texts["game_index_out"]}.")
break

except ValueError:
print("Invalid input.")
except ValueError:
print("Invalid input.")

except Exception as e:
print(f'ERROR: {e}')
except Exception as e:
print(f'ERROR: {e}')

input(f"{texts["enter_to_continue"]}... ")
Menu.clear_screen()
input(f"{texts["enter_to_continue"]}... ")
Menu.clear_screen()

elif user_choice == 3:
stats.stats_review()
input(f"{texts["enter_to_continue"]}... ")
Menu.clear_screen()
elif choice == 3:
stats.stats_review()
input(f"{texts["enter_to_continue"]}... ")
Menu.clear_screen()

elif user_choice == 4:
export.export_to_csv(db.sport)
Menu.clear_screen()
elif choice == 4:
export.export_to_csv(db.sport)
Menu.clear_screen()

elif user_choice == 5:
elif user_choice == 2:
print(f'{texts["settings"]}:')
choice = Menu.settings_menu()
if choice == 1:
Expand All @@ -95,13 +100,13 @@ def main():
elif choice == ValueError:
pass

elif user_choice == 6:
elif user_choice == 3:
Menu.clear_screen()
Menu.show_info(True)
input(f"{texts["enter_to_continue"]}... ")
Menu.clear_screen()

elif user_choice == 7:
elif user_choice == 4:
break


Expand Down
33 changes: 17 additions & 16 deletions source/statistics_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ def stats_review():
print(f"{texts["no_saved_games"]}.")
return

table = [["Points", all_points, round(all_points / all_games, 2)], ["Minutes", all_minutes, round(all_minutes / all_games, 2)],
["2 Pointers", all_2pt, round(all_2pt / all_games, 2)], ["3 Pointers", all_3pt, round(all_3pt / all_games, 2)],
["Assists", all_assists, round(all_assists / all_games, 2)], ["Rebounds", all_rebounds, round(all_rebounds / all_games, 2)],
["Blocks", all_blocks, round(all_blocks / all_games, 2)], ["Steals", all_steals, round(all_steals / all_games, 2)],
["Missed", all_missed, round(all_missed / all_games, 2)], ["Missed Free Throws", all_missed_free_throws, round(all_missed_free_throws / all_games, 2)]
table = [[texts["game_points"], all_points, round(all_points / all_games, 2)], [texts["game_minutes"], all_minutes, round(all_minutes / all_games, 2)],
[texts["game_2pt"], all_2pt, round(all_2pt / all_games, 2)], [texts["game_3pt"], all_3pt, round(all_3pt / all_games, 2)],
[texts["game_assists"], all_assists, round(all_assists / all_games, 2)], [texts["game_rebounds"], all_rebounds, round(all_rebounds / all_games, 2)],
[texts["game_blocks"], all_blocks, round(all_blocks / all_games, 2)], [texts["game_steals"], all_steals, round(all_steals / all_games, 2)],
[texts["game_missed"], all_missed, round(all_missed / all_games, 2)], [texts["game_missed_free_throws"], all_missed_free_throws, round(all_missed_free_throws / all_games, 2)]
]

print(f"{f'{texts["stat"]}':<20} {f'{texts["all_time"]}':<10} {f'{texts["per_game"]}'}")
Expand Down Expand Up @@ -78,16 +78,17 @@ def calculate_efficiency(points, rebounds, assists, steals, blocks, missed, miss


def show_stats(match_index):
print(f'{texts["player"]}: {data_handler.db["player"]}')
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"])}'],
["Assists", str(games[match_index]["assists"])], ["Rebounds", str(games[match_index]["rebounds"])],
["Blocks", str(games[match_index]["blocks"])], ["Steals", str(games[match_index]["steals"])],
["Personal fouls", str(games[match_index]["personal_fouls"])], ["Missed Free Throws", str(games[match_index]["missed_free_throws"])],
["Turnovers", str(games[match_index]["turnovers"])], ["Result", str(games[match_index]["result"])]
table = [[texts["game_points"], str(games[match_index]["points"])], [texts["game_minutes"], str(games[match_index]["minutes"])],
[texts["game_2pt"], f'{str(games[match_index]["2pt_shots_made"])}/{str(games[match_index]["2pt_attempts"])}'], [texts["game_3pt"], f'{str(games[match_index]["3pt_shots_made"])}/{str(games[match_index]["3pt_attempts"])}'],
[texts["game_assists"], str(games[match_index]["assists"])], [texts["game_rebounds"], str(games[match_index]["rebounds"])],
[texts["game_blocks"], str(games[match_index]["blocks"])], [texts["game_steals"], str(games[match_index]["steals"])],
[texts["game_personal_fouls"], str(games[match_index]["personal_fouls"])], [texts["game_missed_free_throws"], str(games[match_index]["missed_free_throws"])],
[texts["game_turnovers"], str(games[match_index]["turnovers"])], [texts["game_result"], str(games[match_index]["result"])]
]
print(f"{f'{texts["stat"]}':<20} {f'{texts["value"]}'}")
print("─" * 35)
Expand All @@ -96,11 +97,11 @@ def show_stats(match_index):
print("─" * 35)

if sport == 2:
table = [["Minutes", str(games[match_index]["minutes"])], ["Goals", str(games[match_index]["goals"])],
["Assists", str(games[match_index]["assists"])], ["Shots", str(games[match_index]["shots"])],
["Saves", str(games[match_index]["saves"])], ["Steals", str(games[match_index]["steals"])],
["Yellow Cards", str(games[match_index]["yellow_cards"])], ["Red Cards", str(games[match_index]["red_cards"])],
["Result", str(games[match_index]["result"])]
table = [[texts["game_minutes"], str(games[match_index]["minutes"])], [texts["game_goals"], str(games[match_index]["goals"])],
[texts["game_assists"], str(games[match_index]["assists"])], [texts["game_shots"], str(games[match_index]["shots"])],
[texts["game_saves"], str(games[match_index]["saves"])], [texts["game_steals"], str(games[match_index]["steals"])],
[texts["game_yellow_cards"], str(games[match_index]["yellow_cards"])], [texts["game_red_cards"], str(games[match_index]["red_cards"])],
[texts["game_result"], str(games[match_index]["result"])]
]
print(f"{f'{texts["stat"]}':<20} {f'{texts["value"]}'}")
print("─" * 35)
Expand Down
Loading
Loading