dodona-edu / universal-judge

Universal judge for educational software testing
https://docs.dodona.be/en/tested
MIT License
9 stars 4 forks source link

Testing stdin/stdout and expressions at the same time? #502

Closed DieterPi closed 3 months ago

DieterPi commented 3 months ago

I would like my to students to program something like this, to demonstrate the 'decomposition' of functions.

def harmonic_mean( a, b ):
    value = round( 2 / ( 1 / a + 1 / b ), 2)
    return value 

# Input
a = int(input())
b = int(input())

# Using the function
c = harmonic_mean(a,b)

# Printing on screen
print(c)

I was thinking of using TESTed to test both stdin/stdout and the harmonic_mean expression. But the testing fails on the expression, I guess because when Dodona is executing the code and expecting an stdin.

I there a way to check stdin/stdout and expressions at the same time? Specifying to ignore stdin when testing expressions? Or should I just pass random stdin? https://dodona.be/nl/courses/2741/series/32738/activities/185326272/

niknetniko commented 3 months ago

If you want to test it in the same tab, you could do something like this:

- tab: "test function and main"
  contexts:
    - testcases:
        - stdin: |
            100
            120
          stdout: "109.09"
        - expression: "harmonisch_gemiddelde(100, 120)"
          return: 109.99

Separate tabs are currently a limitation of TESTed: either you need to add if __name__ == '__main__': (but then the main code won't be executed) or you don't (in which case the code always runs).

This is something we want to enable at some point (as it has been requested before here), but the specifics of Python make this difficult, so we don't have a solution yet.

DieterPi commented 3 months ago

Thanks for the reply! Your suggestion would work. A separate tab would be a 'cleaner' solution for students, but this will also do the trick. 👍️

Could you elaborate on the if __name__ == '__main__': suggestion? How does that work? (I need to insert it as a user into my code?)

niknetniko commented 3 months ago

When creating a Python module that has both functions and is usable as a script, it is common to write it with a guard:

def harmonic_mean( a, b ):
    value = round( 2 / ( 1 / a + 1 / b ), 2)
    return value 

if __name__ == '__main__':
    # Input
    a = int(input())
    b = int(input())

    # Using the function
    c = harmonic_mean(a,b)

    # Printing on screen
    print(c)

This is basically the "main" function from other languages. In the future if/when we support separate tabs, you will probably need to write the submission like this. But, to be clear, this currently will not work in TESTed.