Doctesting a function which prints a students name along with the maximum mark scored - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Doctesting a function which prints a students name along with the maximum mark scored (/thread-36191.html) |
Doctesting a function which prints a students name along with the maximum mark scored - sean1 - Jan-26-2022 How would I go about doctesting this? Output is following for e.g Maths Sam - 98 def Maximum(): while True: print("Maximum marks: Please select a subject, (1) Maths (2) Physics (3) Biology (4) Geo (5) Chemistry (6) Total Marks (7) Menu") choice = input(" >> ") if choice == '1': # dictionary created which maps the students name to their score # Math mathtodict = dict(zip(Student, Maths_marks)) maxmath = max(zip(mathtodict.values(), mathtodict.keys()))[1] print('Highest maths score: ' + maxmath + ' ' + '-' + ' ' + str(max(Maths_marks))) elif choice == '2': # Physics phystodict = dict(zip(Student, Physics_marks)) maxphys = max(zip(phystodict.values(), phystodict.keys()))[1] print('Highest Physics score: ' + maxphys + ' ' + '-' + ' ' + str(max(Physics_marks))) elif choice == '3': # Biology biotodict = dict(zip(Student, Biology_marks)) maxbio = max(zip(biotodict.values(), biotodict.keys()))[1] print('Highest Biology score: ' + maxbio + ' ' + '-' + ' ' + str(max(Biology_marks))) elif choice == '4': # Geography geogtodict = dict(zip(Student, Geog_marks)) maxgeog = max(zip(geogtodict.values(), geogtodict.keys()))[1] print('Highest Geography score: ' + maxgeog + ' ' + '-' + ' ' + str(max(Geog_marks))) elif choice == '5': # Chemistry chemtodict = dict(zip(Student, Chemistry_marks)) maxchem = max(zip(chemtodict.values(), chemtodict.keys()))[1] print('Highest Chemistry score: ' + maxchem + ' ' + '-' + ' ' + str(max(Chemistry_marks))) elif choice == '6': # calculates highest total marks scored across all subjects max_marks = 0 for y in Total_marks: if y > max_marks: max_marks = y totaltodict = dict(zip(Student, Total_marks)) totmax = max(zip(totaltodict.values(), totaltodict.keys()))[1] print('Highest total score: ' + totmax + ' ' + '-' + ' ' + str(max_marks)) elif choice == '7': # exits the program and asks user if they want to return to menu or quit the program break else: print("Choice not found. Please choose again.") continue RE: Doctesting a function which prints a students name along with the maximum mark scored - deanhystad - Jan-26-2022 Convert it to a more useful function that takes input as arguments instead of using the input function and have it return a value instead of printing. Most functions should not use stdio. RE: Doctesting a function which prints a students name along with the maximum mark scored - ndc85430 - Jan-29-2022 Yes, so called pure functions are easier to test. RE: Doctesting a function which prints a students name along with the maximum mark scored - sean1 - Jan-30-2022 Do you know how I could refactor this code to do that? (Jan-26-2022, 11:58 AM)sean1 Wrote: How would I go about doctesting this? Output is following for e.g Maths Sam - 98 RE: Doctesting a function which prints a students name along with the maximum mark scored - deanhystad - Jan-30-2022 I think I would write 3 functions: max_mark(marks, students), total_marks(marks) and get_input(). max_marks does what your current function does, except it does not loop, it does not ask for input, and it returns a tuple (student, score). Since choice 6 is completely different than choices 1-5 I would write that as a separate function instead of messing up max_mark() trying to make it do two different things. get_input() displays a prompt, gets user input, VERIFIES USER INPUT, and returns user input. I would write it to return something more friendly than 1, 2, 3... Perhaps "Math", "Physics"..."Total", "Exit". I would probably make an enum for this, but that is overkill for a homework assignment. The loop gets moved to the body of the script. while True: choice = user_input() if choice == "Exit": break elif choice == "Total": totmax, max_marks = total_marks(Total_marks) print(f'Highest total score: {totmax} - {max_marks}') else: high_mark, student = max_marks(total_marks[choice], Students) print(f'Highest {choice} score: {student} - {high_mark}')This makes the assumption that "total_marks" is a dictionary of all of the marks and that the keys are "Math", "Physics"... Now that max_marks does not take input and returns output you can write a doctest. You also have a function that can be used by other scripts/programs. RE: Doctesting a function which prints a students name along with the maximum mark scored - Pedroski55 - Feb-01-2022 Where are you getting your data from? Excel? MySQL? Assume Excel, then I would have an Excel file with a sheet for each subject and one sheet for totals. Each sheet would have the columns: student_number, name, score1, score2, .... , scoreX No two student numbers can be the same, so they are safer than names. Hope you don't have millions of data! import openpyxl path2file = '/home/pedro/temp/' scoresXL = 'getmax.xlsx' sourceFile = openpyxl.load_workbook(path2file + scoresXL) sourceSheetNames = sourceFile.sheetnames for sheet in sourceSheetNames: print('Which maximum do you want?', sheet) mymax = input('Copy and paste one of the above sheet names here ... ') # maybe you want to change this for equally high scores or add the name def getData(sheet): high_score = 0 maxRow = sourceFile[sheet].max_row + 1 # + 1 makes sure you get the last row maxCol = sourceFile[sheet].max_column + 1 # ditto for rowNum in range(2, maxRow): for col in range(3, maxCol): score = sourceFile[sheet].cell(row=rowNum, column=col).value if score > high_score: high_score = score studinr = sourceFile[sheet].cell(row=rowNum, column=1).value return (studinr, high_score) tup = getData(mymax) print('The student with student number', tup[0], 'achieved', tup[1], 'in', mymax) |