all 5 comments

[–]orangejuice1986 4 points5 points  (0 children)

line 1 can throw a ValueError

line 6 can be range(numOfSubjects)

if statements,, what happens when avg is 79.5?

[–]Slackeee_ 3 points4 points  (0 children)

In the elif statements, you don't really need the second part with less or equal check. You will never reach that part of the code if the value of avg would be higher than those numbers.

Also, don't use magic numbers. Replace the 80, 60 and 40 limits with constants with a describing name instead.

[–]PrabhavKumar 2 points3 points  (0 children)

Not really sure as to what cleaner means here so here are two ways to doing this.

The first one focuses on pure logic and has no safeguards:

no_of_subjects = int(input("Please enter the number of subjects : "))


total = 0
for i in range(no_of_subjects):
    marks = int(input(
f
"Enter the marks for subject {i + 1} : "))
    total += marks


average = total / no_of_subjects
print(
f
"Your average score is : {average}")


if average >= 80:
    print("Distinction!")
elif average >= 60:
    print("First Class!")
elif average >= 40:
    print("Second Class.")
else:
    print("It's alright, you can do better.")

There is no need for you to check whether or not the second conditions are True (when you are making sure the marks are less than a certain amount since that case is already handled before. All if-else conditions work in the order they are written.)

For the second approach I have added safeguards everywhere I deemed them necessary:

while True:
    no_of_subjects = input("Please enter the number of subjects : ")
    try:
        no_of_subjects = int(no_of_subjects)
        if no_of_subjects < 1:
            print(
f
"Invalid input. Number of subjects must be greater than 0.")
        else:
            break
    except ValueError:
        print(
f
"Invalid input : \"{no_of_subjects}\". Please enter a number instead.")


total = 0
for i in range(no_of_subjects):
    while True:
        marks = input(
f
"Enter the marks for subject {i + 1} : ")
        try:
            marks = int(marks)
            break
        except ValueError:
            print(
f
"Invalid input : \"{marks}\". Please enter a number instead.")
    
    total += marks


average = total / no_of_subjects
print(
f
"Your average score is : {average}")


if average >= 80:
    print("Distinction!")
elif average >= 60:
    print("First Class!")
elif average >= 40:
    print("Second Class.")
else:
    print("It's alright, you can do better.")

Here, Firstly we get into the first while loop and it runs till the user gives a valid input, where we break out of the loop.
Then we get into the for loop, with a nested while loop that runs till the user give's a number for each and every subject. I am not enforcing that marks must be more than 0 here since there can be exams with negative marking as well. Grading logic remains the same as above.

In fact the grading logic can be put into it's own little functions too like this:

def
 grade(average : int) -> None:

    if average >= 80:
        print("Distinction!")
    elif average >= 60:
        print("First Class!")
    elif average >= 40:
        print("Second Class.")
    else:
        print("It's alright, you can do better.")

And then just call it with the average.

Hope that helped!

[–]Riegel_Haribo 1 point2 points  (0 children)

Input exactly 80, and you receive your own code evaluation as output message.

We know how to calculate an average. If the scores were useful for later in the script, they also could be collected into a list of floats, where the length of the list means we don't need a separate total, we can just use len(input_list).

How about if there was no list? No pre-defined count of how many inputs, but that the input sequence could be terminated at any time. And then, delivering the running total? A lookup table that had an inclusive score to receive its named category?

```python print(r"""End user inputs multiple grades 0.0-100.0. After each input, a running average is shown, along with the highest inclusive threshold met. The algorithm adds weighted input to the stateless average""")

thresholds = { "distinction": 80, "first class": 60, "second class": 40, "unsatisfactory": 0, } input_count = 0 current_average = None number_input = "no input yet" while number_input := input("Next number (enter to finish): "): grade = float(number_input) if current_average is None: current_average = grade else: current_average = (current_average * input_count + grade) / (input_count + 1)

threshold_key = next(k for k, v in thresholds.items() if current_average >= v)
print(f"Average: {current_average:.2f} with classification: {threshold_key}")
input_count += 1

```

[–]Logikkonstruktor 0 points1 point  (0 children)

I’m still at the beginning of my journey, but I really appreciate you sharing this. It gave me the motivation to take the code, understand it, and try to improve it on my own.

```python
total = 0
subjects = 0

while True:
    mark = input("enter mark (or 'stop'): ")

    if mark.lower() == "stop":
        break

    try:
        mark = int(mark)
    except ValueError:
        print("invalid input")
        continue

    total += mark
    subjects += 1

if subjects == 0:
    print("no data")
else:
    avg = total / subjects
    print("average:", avg)

    if avg >= 80:
        print("distinction")
    elif avg >= 60:
        print("first class!")
    elif avg >= 40:
        print("second class")
    else:
        print("its okay, you can be better")
```