0

I am trying to complete a homework exercise for the following and I am stumped:

Create a variable called mark and assign it the value 65. Then write a series of if ... elif ... else statements to assign a new variable a grade such that marks below 50 produce "Fail", from 50 to 59 produce "Pass", from 60 to 69 produce "Merit" and from 70 and up produce "Distiction".

Print the grade.

Then implement the same logic again, but this time without using if statements.

I am able to complete the first part but I am unsure on how to do the same avoiding IF functions - can anyone help?

Using IF functions I have the following which works as expected:

mark = 50
if mark > 69:
    print(mark, "marks is a Distinction")
elif mark <= 69 and mark >= 60:
    print(mark, "marks is a Merit")
elif mark <= 59 and mark >= 50:
    print(mark, "markss is a Pass")
else:
    print(mark, "marks is a Fail")

I have no idea where to begin for avoiding if functions

11
  • You can use a while with an unconditional break at the end as a replacement for an if. It's silly, but so's the assignment. Commented Nov 3, 2022 at 13:47
  • (in terms of how I came to that suggestion -- "where to start" is by looking at the list of flow control operators and thinking about how they could be abused towards your end) Commented Nov 3, 2022 at 13:48
  • ...that said, Stack Overflow's scope is limited to practical, answerable questions; avoiding something that's manifestly the right tool for the job is anything but practical. Commented Nov 3, 2022 at 13:48
  • 1
    I hope the teacher isn't expecting them to use a match statement... Commented Nov 3, 2022 at 13:52
  • 1
    I'm pretty sure you can "abuse" booleans to write an algebraic expression for the result: for example, try to print a = "small"*(mark < 50) + "big" * (mark >= 50) for different values of mark. Commented Nov 3, 2022 at 13:55

4 Answers 4

5

Your current structure is likely the most readable and explicit if using pure Python. Note that you can simplify by only checking one bound as your intervals are successive and non-overlapping.

mark = 50
if mark > 69:
    print(mark, "marks is a Distinction")
elif mark >= 60:
    print(mark, "marks is a Merit")
elif mark >= 50:
    print(mark, "marks is a Pass")
else:
    print(mark, "marks is a Fail")

That said, if you really want a non-if solution and want to annoy a bit your instructor, what about:

mark = 65
grades = ['Fail', 'Pass', 'Merit', 'Distinction']
print(f"{mark} is a {grades[sum((mark >= 50, mark >= 60, mark > 69))]}")

Another approach using itertools.compress:

from itertools import compress
grades = ['Distinction', 'Merit', 'Pass', 'Fail']
tests = (mark > 69, mark >= 60, mark >= 50, True)
print(f"{mark} is a {next(compress(grades, tests))}")
Sign up to request clarification or add additional context in comments.

4 Comments

Wow, similar idea to mine, but even more elegant and explicit! Upvoting
@Yevhen not sure I would call this elegant, rather "hacky". I would certainly not use this in production code ;)
The moment the task states "without using if statement" nobody is talking about production code anymore :)
I like the 2nd solution; and as I said in an earlier comment, I doubt that will annoy the instructor (unless I'm totally wrong on their purpose).
3

Assuming list ["Fail", "Pass", "Merit", "Distinction"].

If you divide the mark by 10 (without remainder) (mark // 10) you'd get 5 for 50-59, 6 for 60-69, etc. If you subtract 4 from it you'll get an index of the correct result (1 for "Pass", 2 for "Merit", 3 for "Distinction"). Except for cases when mark is less than 40 or more than 80. We can cap the index with min and max accordingly:

mark = 50
["Fail", "Pass", "Merit", "Distiction"][min(max(mark//10 - 4, 0), 3)]

It is a very weird solution for a very weird task

1 Comment

I like it as well (although dependent on the regular pattern) ;)
2

A bit different approach than the rest of the answers, I limit the index with min/max and get a value from a big list.

grades = ["Fail"]*50 + ["Pass"]*10 + ["Merit"]*10 + ["Distiction"]

for mark in [-100,0,49,50,51,59,60,61,69,70,71,120]:
    print(mark,grades[min(len(grades)-1,max(0,mark))])

Comments

1

I'll join the fun :) with my solution:

mark = 65

print("Fail"*(mark < 50) + "Pass"*(50 <= mark < 60) + "Merit"*(60 <= mark < 70) + "Distinction"*(70 <= mark))

# Merit

To illustrate my point that about anything, however irrelevant it seems, can be used, I imagined this other (quite absurd but fun and working) solution (it assumes mark to be an integer between 0 and 100):

a="ffffffffffffffffffffffffffffffffffffffffffffffffffppppppppppmmmmmmmmmmddddddddddddddddddddddddddddddd"
print(a[mark].replace("f", "Fail").replace("p","Pass").replace("m","Merit").replace("d","Distinction"))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.