Skip to content

Instantly share code, notes, and snippets.

@juvuorin
Last active April 24, 2020 11:06
Show Gist options
  • Save juvuorin/db99349ee678e6f6465dcab0dbbfd57c to your computer and use it in GitHub Desktop.
Save juvuorin/db99349ee678e6f6465dcab0dbbfd57c to your computer and use it in GitHub Desktop.
koiramainenOhjelmointikisa2020
#!/usr/bin/env python3
from functools import reduce
from sys import exit
# @author Samu Kumpulainen
# This is a really simple command-line program for managing the dog school
# diplomas. Grades can be inputted as well as printed.
grades = list(range(4, 11))
student_data = {}
# For simplicity's sake I decided to just make a dictionary with the subjects
subject_groups = {"Metsästys": [
"Pupun jäljestys",
"Hirven jäljestys",
"Linnun noutaminen"],
"Pihatyöt": [
"Lumen pöllyytys",
"Kukkapenkkien kaivaminen"],
"Muut": [
"Parvekkeen vahtiminen",
"Piilotetun luun löytäminen",
"Oman hännän jahtaaminen",
"Kuun ulvonta"]}
def input_student_info():
"""Asks the user to input the student's grades one by one."""
student_grades = dict()
name = str(input("Minkä oppilaan tiedot haluat syöttää? \n"))
while not name:
name = str(input("Minkä oppilaan tiedot haluat syöttää? \n"))
for subject_group in subject_groups:
student_grades[subject_group] = []
for subject in subject_groups.get(subject_group):
grade = 0
while (grade < 4 or 10 < grade):
try:
grade = int(input(f"Anna arvosana aineessa {subject} (4-10): "))
except ValueError:
print("Anna numero väliltä 4-10!")
student_grades[subject_group].append((subject, grade))
student_data[name.lower()] = student_grades
def get_student_diploma(name):
"""
Returns single student's diploma, grouped by subject groups
name: str, name of the student
Returns
Dictionary of grades: <group_name> -> <group grade sum>"""
if not name:
return
diploma = {}
for subject_group in student_data[name.lower()]:
# Here's a functional reduce, but a for-loop would have maybe been a
# more understandable solution
total = reduce(lambda ini, x: ini + x[1],
student_data[name][subject_group], 0)
diploma[subject_group] = total
return diploma
def print_student_diplomas(*student_names, all=False):
"""Prints given students' diplomas"""
names = student_data.keys() if all else student_names
for name in names:
diploma = get_student_diploma(name)
print(f"---- {name.capitalize()} ----")
for group in diploma:
print(f"{group:} ---------- {diploma[group]}")
print(f"---------------------")
if __name__ == "__main__":
# Here I just added some example data
student_data = {'roope': {'Metsästys': [('Pupun jäljestys', 10),
('Hirven jäljestys', 9), ('Linnun noutaminen', 5)],
'Pihatyöt': [('Lumen pöllyytys', 6), ('Kukkapenkkien kaivaminen', 10)],
'Muut': [('Parvekkeen vahtiminen', 10),
('Piilotetun luun löytäminen', 6), ('Oman hännän jahtaaminen', 4),
('Kuun ulvonta', 8)]},
'pluto': {'Metsästys': [('Pupun jäljestys', 10),
('Hirven jäljestys', 9), ('Linnun noutaminen', 5)],
'Pihatyöt': [('Lumen pöllyytys', 6), ('Kukkapenkkien kaivaminen', 10)],
'Muut': [('Parvekkeen vahtiminen', 10),
('Piilotetun luun löytäminen', 6), ('Oman hännän jahtaaminen', 4),
('Kuun ulvonta', 8)]}}
# User can input multiple students' grades
print("========== Koirakoulun Oppilastietojärjestelmä ==========")
while(input("Haluatko syöttää oppilaan tiedot? Jos et, paina Enter.\n")):
input_student_info()
# User can select either one or several diplomas to print
while True:
name = str(input("""Kenen todistuksen haluat? Nimi/kaikki/Enter\n"""))
if not name:
exit()
if name.lower() == "kaikki":
print_student_diplomas(all=True)
else:
print_student_diplomas(name)
@juvuorin
Copy link
Author

juvuorin commented Apr 24, 2020

Hyvä ratkaisu tämäkin! Käytetty näppärästi Pythonin ehkä käytetyintä tietotyyppiä dictionarya tiedon kuvaamiseen.

Tekijältä erinomainen oma pohdinta, että olisiko for-loop ollut luettavampi vaihtoehto? Riippunee paljon koodin lukijasta! Hyvä, että oli laitettu myös testidata, jolla koodia voi ajaa ilman erillistä syötteen lukemista ja tulostusta.

Erinomainen valinta koostaa lopulliset ryhmäkohtaiset arvosanat vaivattomasti reduce-funktiolla. Reduce on juuri tätä varten - muodostetaan tiedosta yhteevento ja sitähän ryhmäkohtaiset arvosanat juuri edustavat.

Hyvä, että virhetilanteita on otettu syötettä lukiessa kiinni. Ohjelmassa on hauska lisäominaisuus, jossa todistuksen saa tulostettua koiran nimen perusteella!

Kehitysehdotukset

Koska esimerkkidata on jo olemassa, voisiko koodin vielä lisätä testin, jolla voidaan testata tuottaako esimerkkidata oikeat ryhmärvosanat lopulliseen todistukseen. Käytetäänkö grades muuttujaa?

Tsemppiä ohjelmointihommiin!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment