Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2023
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.81 KB | None | 0 0
  1. # This code can be run as python2 or python3 in most systems.
  2. #
  3. # This is a small program that runs two processes, connecting the stdin of each
  4. # one to the stdout of the other.
  5. # It doesn't perform a lot of checking, so many errors may
  6. # be caught internally by Python (e.g., if your command line has incorrect
  7. # syntax) or not caught at all (e.g., if the judge or solution hangs).
  8. #
  9. # Run this as:
  10. # python interactive_runner.py <cmd_line_judge> -- <cmd_line_solution>
  11. #
  12. # For example, if you have a testing_tool.py in python3 (that takes a single
  13. # integer as a command line parameter) to use as judge -- like one
  14. # downloaded from a problem statement -- and you would run your solution
  15. # in a standalone using one of the following:
  16. # 1. python3 my_solution.py
  17. # 2. ./my_solution
  18. # 3. java Solution
  19. # 4. my_solution.exe
  20. # Then you could run the judge and solution together, using this, as:
  21. # 1. python interactive_runner.py python3 testing_tool.py 0 -- python3 my_solution.py
  22. # 2. python interactive_runner.py python3 testing_tool.py 0 -- ./my_solution
  23. # 3. python interactive_runner.py python3 testing_tool.py 0 -- java solution
  24. # 4. python interactive_runner.py python3 testing_tool.py 0 -- my_solution.exe
  25. # Notice that the solution in cases 2, 3 and 4 would usually have a
  26. # compilation step before running, which you should run in your usual way
  27. # before using this tool.
  28. #
  29. # This is only intended as a convenient tool to help contestants test solutions
  30. # locally. In particular, it is not identical to the implementation on our
  31. # server, which is more complex.
  32. #
  33. # The standard streams are handled the following way:
  34. # - judge's stdin is connected to the solution's stdout;
  35. # - judge's stdout is connected to the solution's stdin;
  36. # - stderrs of both judge and solution are piped to standard error stream, with
  37. # lines prepended by "judge: " or "sol: " respectively (note, no
  38. # synchronization is done so it's possible for the messages from both programs
  39. # to overlap with each other).
  40.  
  41. from __future__ import print_function
  42. import sys, subprocess, threading
  43.  
  44. class SubprocessThread(threading.Thread):
  45. def __init__(self,
  46. args,
  47. stdin_pipe=subprocess.PIPE,
  48. stdout_pipe=subprocess.PIPE,
  49. stderr_prefix=None):
  50. threading.Thread.__init__(self)
  51. self.stderr_prefix = stderr_prefix
  52. self.p = subprocess.Popen(
  53. args, stdin=stdin_pipe, stdout=stdout_pipe, stderr=subprocess.PIPE)
  54.  
  55. def run(self):
  56. try:
  57. self.pipeToStdErr(self.p.stderr)
  58. self.return_code = self.p.wait()
  59. self.error_message = None
  60. except (SystemError, OSError):
  61. self.return_code = -1
  62. self.error_message = "The process crashed or produced too much output."
  63.  
  64. # Reads bytes from the stream and writes them to sys.stderr prepending lines
  65. # with self.stderr_prefix.
  66. # We are not reading by lines to guard against the case when EOL is never
  67. # found in the stream.
  68. def pipeToStdErr(self, stream):
  69. new_line = True
  70. while True:
  71. chunk = stream.readline(1024)
  72. if not chunk:
  73. return
  74. chunk = chunk.decode("UTF-8")
  75. if new_line and self.stderr_prefix:
  76. chunk = self.stderr_prefix + chunk
  77. new_line = False
  78. sys.stderr.write(chunk)
  79. if chunk.endswith("\n"):
  80. new_line = True
  81. sys.stderr.flush()
  82.  
  83.  
  84. assert sys.argv.count("--") == 1, (
  85. "There should be exactly one instance of '--' in the command line.")
  86. sep_index = sys.argv.index("--")
  87. judge_args = sys.argv[1:sep_index]
  88. sol_args = sys.argv[sep_index + 1:]
  89.  
  90. t_sol = SubprocessThread(sol_args, stderr_prefix=" sol: ")
  91. t_judge = SubprocessThread(
  92. judge_args,
  93. stdin_pipe=t_sol.p.stdout,
  94. stdout_pipe=t_sol.p.stdin,
  95. stderr_prefix="judge: ")
  96. t_sol.start()
  97. t_judge.start()
  98. t_sol.join()
  99. t_judge.join()
  100.  
  101. # Print an empty line to handle the case when stderr doesn't print EOL.
  102. print()
  103. print("Judge return code:", t_judge.return_code)
  104. if t_judge.error_message:
  105. print("Judge error message:", t_judge.error_message)
  106.  
  107. print("Solution return code:", t_sol.return_code)
  108. if t_sol.error_message:
  109. print("Solution error message:", t_sol.error_message)
  110.  
  111. if t_sol.return_code:
  112. print("A solution finishing with exit code other than 0 (without exceeding "
  113. "time or memory limits) would be interpreted as a Runtime Error "
  114. "in the system.")
  115. elif t_judge.return_code:
  116. print("A solution finishing with exit code 0 (without exceeding time or "
  117. "memory limits) and a judge finishing with exit code other than 0 "
  118. "would be interpreted as a Wrong Answer in the system.")
  119. else:
  120. print("A solution and judge both finishing with exit code 0 (without "
  121. "exceeding time or memory limits) would be interpreted as Correct "
  122. "in the system.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement