2023-24 Premier League Player Data
2023-24 Premier League Player Data
A CSV & Matplotlib based Python Project for Class 12 Commerce - Information Practices
Date: 2025-10-10
Acknowledgement
Acknowledgement I would like to express my deepest gratitude to all those who supported and guided me in
completing this project. First, I sincerely thank my Information Practices teacher for their continuous guidance,
insightful feedback, and encouragement throughout the development of this project. Their detailed explanations of
programming concepts, patient assistance during troubleshooting, and practical suggestions for improvement
were invaluable at every stage. Their mentorship not only helped me to solve technical problems but also to
structure the project in a clear and presentable manner suitable for academic evaluation. I would also like to thank
my school management for providing access to the computer laboratory and the necessary software tools.
Availability of computers and internet resources made it possible to research, test, and refine the application. I
appreciate the support of my classmates and friends who assisted in testing the application across different
machines and offered constructive suggestions based on their usage. The testing feedback helped me to make
the system more robust and user-friendly, and to handle edge cases which I might have missed while coding
alone. Special thanks to online educational platforms, documentation resources, and community forums which
provided references and examples for file handling, CSV operations, and data visualization using Matplotlib.
These resources were particularly useful in learning how to create informative charts to accompany the textual
outputs of the system. I am also grateful for open-source examples and snippets that guided various parts of the
program's modular design. I am thankful to my family for their continuous encouragement during this academic
exercise. Their support allowed me to focus on completing the work and polishing the final report. Completing this
project has been a significant learning experience: I improved my programming skills, learned to handle data files
responsibly, and gained experience in documenting and presenting technical work professionally. This project
would not have been possible without the collective support of my teacher, school, peers, online communities, and
family. Thank you to everyone who contributed to this project.
Introduction
Introduction In contemporary education and amateur sports administration, organizing and managing information
accurately is crucial. This Sports Management System is designed as a practical, educational application that
uses Python programming, CSV file handling, and Matplotlib visualization to demonstrate how a small-scale
information system can be implemented using accessible tools. The project aligns well with Class 12 Commerce
Information Practices curriculum objectives, which emphasize file handling, data organization, program logic, and
basic data visualization. The system focuses on core entities such as teams, players, tournaments, and matches.
To keep the implementation straightforward for classroom instruction, CSV (Comma Separated Values) files are
used to store records. CSV provides a simple, portable, and human-readable format that students can open and
inspect in text editors or spreadsheet software. Through this project, students learn how to append new records,
read existing records, update entries by reading and rewriting files, and delete records by filtering data. These
operations illustrate real-world programming tasks without the overhead of a database server. An important
addition to this project is the use of Matplotlib for basic reporting and visualization. Visual charts—such as a bar
chart for wins per team or a line chart comparing match scores—help in interpreting data quickly and provide an
impressive output for project presentation. Creating plots also teaches students how to prepare data for graphical
representation, label axes, and save images for inclusion in reports or presentations. Modularity is central to the
program’s design. Each major concern is separated into manager modules: TeamManager, PlayerManager,
TournamentManager, MatchManager, and StatsModule. This separation improves readability and makes the code
easier to maintain and extend. The console-based user interface keeps the interaction simple—students can
focus on program logic, validation, and file operations. Additionally, the program includes utilities for
importing/exporting CSV, generating sample data, and producing charts for reports. Overall, this project serves as
a practical demonstration of how programming skills taught in Class 12 Information Practices can be applied to
develop a small but functional information system. It is suitable for classroom demonstrations, practical
examinations, and project submissions, and can easily be extended to a GUI or a database-backed system in
higher studies.
Features & Technologies
def ensure_files():
"""Ensure CSV files exist with headers."""
files = {
TEAM_FILE: ['id','name','coach','city','created_at'],
PLAYER_FILE: ['id','name','team_id','age','position','nationality','created_at'],
MATCH_FILE: ['id','tournament_id','team_a_id','team_b_id','team_a_score','team_b_score','winner_id'
TOURNAMENT_FILE: ['id','name','start_date','end_date','venue','created_at']
}
for fname, hdr in [Link]():
if not [Link](fname):
with open(fname, 'w', newline='') as f:
w = [Link](f)
[Link](hdr)
def read_csv_dict(fname):
if not [Link](fname): return []
with open(fname, 'r', newline='') as f:
return list([Link](f))
class TeamManager:
def __init__(self, file=TEAM_FILE):
[Link] = file; [Link] = ['id','name','coach','city','created_at']
ensure_files()
def _next_id(self):
rows = read_csv_dict([Link])
if not rows: return '1'
ids = [int(r['id']) for r in rows if [Link]('id')]
return str(max(ids)+1) if ids else '1'
def add(self, name, coach='', city=''):
name=[Link]()
if not name: raise ValueError('Name required')
rows = read_csv_dict([Link])
for r in rows:
if r['name'].lower()==[Link](): raise ValueError('Team exists')
row = {'id':self._next_id(),'name':name,'coach':coach,'city':city,'created_at':[Link]().isofo
append_csv_dict([Link], row, [Link]); return row
def list(self): return read_csv_dict([Link])
def find(self, tid):
for r in [Link]():
if r['id']==str(tid): return r
return None
def update(self, tid, **kwargs):
rows = [Link](); changed=False
for r in rows:
if r['id']==str(tid):
for k,v in [Link]():
if k in r and v is not None: r[k]=str(v)
changed=True
if changed: write_csv_dict([Link], rows, [Link])
return changed
def delete(self, tid):
rows = [Link](); new=[r for r in rows if r['id']!=str(tid)]
if len(new)==len(rows): return False
write_csv_dict([Link],new,[Link]); return True
def search_by_city(self, city):
return [r for r in [Link]() if [Link]('city','').lower()==[Link]()]
class PlayerManager:
def __init__(self,file=PLAYER_FILE):
[Link]=file; [Link]=['id','name','team_id','age','position','nationality','created_at']; en
def _next_id(self):
rows=read_csv_dict([Link]); return str(max([int(r['id']) for r in rows])+1) if rows else '1'
def add(self,name,team_id='',age='',position='',nationality=''):
name=[Link]();
if not name: raise ValueError('Player name required')
row={'id':self._next_id(),'name':name,'team_id':str(team_id),'age':str(age),'position':position,'na
append_csv_dict([Link],row,[Link]); return row
def list(self): return read_csv_dict([Link])
def find(self,pid):
for r in [Link]():
if r['id']==str(pid): return r
return None
def update(self,pid,**kwargs):
rows=[Link](); changed=False
for r in rows:
if r['id']==str(pid):
for k,v in [Link]():
if k in r and v is not None: r[k]=str(v)
changed=True
if changed: write_csv_dict([Link],rows,[Link])
return changed
def delete(self,pid):
rows=[Link](); new=[r for r in rows if r['id']!=str(pid)]
if len(new)==len(rows): return False
write_csv_dict([Link],new,[Link]); return True
def list_by_team(self, team_id):
return [r for r in [Link]() if [Link]('team_id')==str(team_id)]
class TournamentManager:
def __init__(self,file=TOURNAMENT_FILE): [Link]=file; [Link]=['id','name','start_date','end_dat
def _next_id(self): rows=read_csv_dict([Link]); return str(max([int(r['id']) for r in rows])+1) if r
def add(self,name,start_date='',end_date='',venue=''):
if not [Link](): raise ValueError('Name required')
row={'id':self._next_id(),'name':name,'start_date':start_date,'end_date':end_date,'venue':venue,'cr
append_csv_dict([Link],row,[Link]); return row
def list(self): return read_csv_dict([Link])
def find(self,tid):
for r in [Link]():
if r['id']==str(tid): return r
return None
def delete(self,tid): rows=[Link](); new=[r for r in rows if r['id']!=str(tid)];
if len(new)==len(rows): return False
write_csv_dict([Link],new,[Link]); return True
class MatchManager:
def __init__(self,file=MATCH_FILE): [Link]=file; [Link]=['id','tournament_id','team_a_id','team
def _next_id(self): rows=read_csv_dict([Link]); return str(max([int(r['id']) for r in rows])+1) if r
def add(self,tournament_id,team_a_id,team_b_id,team_a_score,team_b_score,match_date='',venue=''):
# compute winner
try:
a=int(team_a_score); b=int(team_b_score)
if a>b: winner=str(team_a_id)
elif b>a: winner=str(team_b_id)
else: winner='0'
except Exception:
winner=''
row={'id':self._next_id(),'tournament_id':str(tournament_id),'team_a_id':str(team_a_id),'team_b_id'
append_csv_dict([Link],row,[Link]); return row
def list(self): return read_csv_dict([Link])
def stats(self):
rows=[Link](); stats={}
for r in rows:
ta=[Link]('team_a_id'); tb=[Link]('team_b_id'); winner=[Link]('winner_id')
for t in (ta,tb):
if t not in stats: stats[t]={'played':0,'wins':0,'losses':0,'draws':0,'goals_for':0,'goals_
try:
a=int([Link]('team_a_score') or 0); b=int([Link]('team_b_score') or 0)
stats[ta]['played']+=1; stats[tb]['played']+=1
stats[ta]['goals_for']+=a; stats[ta]['goals_against']+=b
stats[tb]['goals_for']+=b; stats[tb]['goals_against']+=a
except Exception:
pass
if winner and winner!='0':
stats[winner]['wins']+=1
loser=tb if winner==ta else ta
if loser in stats: stats[loser]['losses']+=1
elif winner=='0':
stats[ta]['draws']+=1; stats[tb]['draws']+=1
return stats
def plot_wins(self, teams_map, out_path='team_wins.png'):
stats=[Link](); names=[]; wins=[]
for tid,s in [Link]():
[Link](teams_map.get(tid,f'Team {tid}'))
[Link]([Link]('wins',0))
if not names:
print('No matches to plot')
return None
[Link](figsize=(6,4))
[Link](names,wins)
[Link]('Wins per Team')
[Link]('Team'); [Link]('Wins')
plt.tight_layout(); [Link](out_path); [Link](); return out_path
def plot_scores(self, out_path='match_scores.png'):
rows=[Link](); labels=[]; a_scores=[]; b_scores=[]
for r in rows:
[Link](f"{[Link]('team_a_id')} vs {[Link]('team_b_id')}")
try:
a_scores.append(int([Link]('team_a_score') or 0)); b_scores.append(int([Link]('team_b_score')
except Exception:
a_scores.append(0); b_scores.append(0)
if not labels:
print('No matches for score plot'); return None
x=range(len(labels))
[Link](figsize=(7,4))
[Link](x,a_scores,marker='o',label='Team A'); [Link](x,b_scores,marker='o',label='Team B')
[Link](x,labels,rotation=30,ha='right'); [Link](); plt.tight_layout(); [Link](out_path
class StatsModule:
@staticmethod
def top_teams_by_wins(match_mgr, teams_map, top_n=3):
stats=match_mgr.stats(); arr=[(tid,s['wins']) for tid,s in [Link]()]; [Link](key=lambda x:x[
@staticmethod
def team_summary(match_mgr, team_id):
stats=match_mgr.stats(); return [Link](str(team_id),{})
def main_menu():
ensure_files()
team_mgr = TeamManager()
player_mgr = PlayerManager()
tour_mgr = TournamentManager()
match_mgr = MatchManager()
sample_data(team_mgr,player_mgr,tour_mgr,match_mgr)
teams_map = {t['id']:t['name'] for t in team_mgr.list()}
while True:
print('\n--- Sports Management System (CSV + Matplotlib) ---')
print('1. List Teams')
print('2. Add Team')
print('3. Update Team')
print('4. Delete Team')
print('5. List Players'); code_lines.append(" print('6. Add Player')")
code_lines_tail = []
print('7. Update Player'); print('8. Delete Player')
print('9. List Tournaments'); print('10. Add Tournament')
print('11. List Matches'); print('12. Add Match')
print('13. Show Team Stats'); print('14. Plot Wins Chart')
print('15. Plot Match Scores Chart'); print('16. Export CSVs (copy to sample folder)')
print('17. Top teams by wins (summary)'); print('18. Exit')
choice = input('Enter choice: ').strip()
if choice == '1':
for t in team_mgr.list(): print_row(t)
elif choice=='2':
try:
name=input('Name: '); coach=input('Coach: '); city=input('City: ')
print('Added:', team_mgr.add(name,coach,city))
except Exception as e:
print('Error:',e)
elif choice=='3':
tid=input('Team id to update: '); name=input('New name (leave blank to keep): ')
coach=input('New coach: '); city=input('New city: ')
ok=team_mgr.update(tid, name or None, coach or None, city or None)
print('Updated' if ok else 'Not found')
elif choice=='4':
tid=input('Team id to delete: '); print('Deleted' if team_mgr.delete(tid) else 'Not found')
elif choice=='5':
for p in player_mgr.list(): print_row(p)
elif choice=='6':
try:
name=input('Player name: '); team_id=input('Team id: '); age=input('Age: ')
position=input('Position: '); nat=input('Nationality: ')
print('Added:', player_mgr.add(name,team_id or '', age or '', position or '', nat or ''))
except Exception as e:
print('Error:', e)
elif choice=='7':
pid=input('Player id to update: '); field=input('Field: '); val=input('New value: ')
print('Updated' if player_mgr.update(pid, **{field:val}) else 'Not found')
elif choice=='8':
pid=input('Player id to delete: '); print('Deleted' if player_mgr.delete(pid) else 'Not found')
elif choice=='9':
for tr in tour_mgr.list(): print_row(tr)
elif choice=='10':
try: name=input('Tournament name: '); sd=input('Start date: '); ed=input('End date: '); venue=i
except Exception as e: print('Error:', e)
else: print('Added:', tour_mgr.add(name,sd,ed,venue))
elif choice=='11':
for m in match_mgr.list(): print_row(m)
elif choice=='12':
try:
tid=input('Tournament id: '); a=input('Team A id: '); b=input('Team B id: ')
sa=input('Score A: '); sb=input('Score B: '); md=input('Match date: '); venue=input('Venue:
print('Added:', match_mgr.add(tid,a,b,sa,sb,md,venue))
except Exception as e:
print('Error:', e)
elif choice=='13':
tid=input('Team id for summary: '); print('Summary:', StatsModule.team_summary(match_mgr, tid))
elif choice=='14':
out=match_mgr.plot_wins(teams_map, out_path='team_wins.png'); print('Chart saved to', out)
elif choice=='15':
out=match_mgr.plot_scores(out_path='match_scores.png'); print('Chart saved to', out)
elif choice=='16':
# export by copying current CSVs to sample folder
for fname in [TEAM_FILE, PLAYER_FILE, MATCH_FILE, TOURNAMENT_FILE]:
if [Link](fname):
import shutil
[Link](fname, [Link]('sample_csvs', fname))
print('Exported CSVs to sample_csvs/ folder')
elif choice=='17':
print('Top teams:', StatsModule.top_teams_by_wins(match_mgr, teams_map))
elif choice=='18':
print('Exiting...'); break
else:
print('Invalid choice')
if __name__ == '__main__':
main_menu()
# Padding comment to expand the source code for project requirements
How to run
1. Install Python 3.x and Matplotlib: pip install matplotlib
2. Save the source code to a file (e.g., sports_ms.py) in the same folder.
3. Run the script: python sports_ms.py
4. Use the menu to add teams, players, and matches. Use options 14/15 to generate charts.
5. Check sample_csvs/ for exported CSVs and charts saved as PNG files.