Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Python (Use the sanity checker to check the solution) # This is a sanity checker for your Project #0 solution, which checks whether # your

Python (Use the sanity checker to check the solution)

image text in transcribed

# This is a sanity checker for your Project #0 solution, which checks whether # your solution meets the basic requirements: # # * The file is named correctly # * It's possible to run the program by executing the module # * Your program generates the correct output for one scenario (the example # shown in the project write-up) # # There are other tests you'll want to run besides the one scenario here, # because we'll be testing more than just one when we grade your work, but if # your program is unable to pass this sanity checker, it will certainly be # unable to pass our automated tests. # # YOU DO NOT NEED TO READ OR UNDERSTAND THIS CODE, though you can certainly # feel free to take a look at it.

import collections import pathlib import queue import sys import subprocess import threading import time import traceback import typing

class TextProcessReadTimeout(Exception): pass

class TextProcess: _READ_INTERVAL_IN_SECONDS = 0.025

def __init__(self, args: [str], working_directory: str): self._process = subprocess.Popen( args, cwd = working_directory, bufsize = 0, stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)

self._stdout_read_trigger = queue.Queue() self._stdout_buffer = queue.Queue()

self._stdout_thread = threading.Thread( target = self._stdout_read_loop, daemon = True)

self._stdout_thread.start()

def __enter__(self): return self

def __exit__(self, tr, exc, val): self.close()

def close(self): self._stdout_read_trigger.put('stop') self._process.terminate() self._process.wait() self._process.stdout.close() self._process.stdin.close()

def write_line(self, line: str) -> None: try: self._process.stdin.write((line + ' ').encode(encoding = 'utf-8')) self._process.stdin.flush()

except OSError: pass

def read_line(self, timeout: float = None) -> str or None: self._stdout_read_trigger.put('read') sleep_time = 0 while timeout == None or sleep_time

if next_result == None: return None elif isinstance(next_result, Exception): raise next_result else: return next_result.decode(encoding = 'utf-8')

except queue.Empty: time.sleep(TextProcess._READ_INTERVAL_IN_SECONDS) sleep_time += TextProcess._READ_INTERVAL_IN_SECONDS

raise TextProcessReadTimeout()

def _stdout_read_loop(self): try: while self._process.returncode == None: if self._stdout_read_trigger.get() == 'read': line = self._process.stdout.readline()

if line == b'': self._stdout_buffer.put(None) else: self._stdout_buffer.put(line) else: break

except Exception as e: self._stdout_buffer.put(e)

class TestFailure(Exception): pass

class TestInputLine: def __init__(self, text: str): self._text = text

def execute(self, process: TextProcess) -> None: try: process.write_line(self._text)

except Exception as e: print_labeled_output( 'EXCEPTION', [tb_line.rstrip() for tb_line in traceback.format_exc().split(' ')])

raise TestFailure()

print_labeled_output('INPUT', self._text)

class TestOutputLine: def __init__(self, text: str, timeout_in_seconds: float): self._text = text self._timeout_in_seconds = timeout_in_seconds

def execute(self, process: TextProcess) -> None: try: output_line = process.read_line(self._timeout_in_seconds)

except TextProcessReadTimeout: output_line = None

except Exception as e: print_labeled_output( 'EXCEPTION', [tb_line.rstrip() for tb_line in traceback.format_exc().split(' ')])

raise TestFailure()

if output_line != None: if output_line.endswith(' '): output_line = output_line[:-2] elif output_line.endswith(' '): output_line = output_line[:-1]

print_labeled_output('OUTPUT', output_line)

if output_line != self._text: print_labeled_output('EXPECTED', self._text)

index = min(len(output_line), len(self._text))

for i in range(min(len(output_line), len(self._text))): if output_line[i] != self._text[i]: index = i break

print_labeled_output('', (' ' * index) + '^')

print_labeled_output( 'ERROR', 'This line of output did not match what was expected. The first', 'incorrect character is marked with a ^ above.', '(If you don\'t see a difference, perhaps your program printed', 'extra whitespace on the end of this line.)')

raise TestFailure()

else: print_labeled_output('EXPECTED', self._text)

print_labeled_output( 'ERROR', 'This line of output was expected, but the program did not generate', 'any additional output after waiting for {} second(s).'.format(self._timeout_in_seconds))

raise TestFailure()

class TestEndOfOutput: def __init__(self, timeout_in_seconds: float): self._timeout_in_seconds = timeout_in_seconds

def execute(self, process: TextProcess) -> None: output_line = process.read_line(self._timeout_in_seconds)

if output_line != None: print_labeled_output('OUTPUT', output_line)

print_labeled_output( 'ERROR', 'Extra output was printed after the program should not have generated', 'any additional output')

raise TestFailure()

TEST_LINES = [ TestInputLine('4'), TestOutputLine('+-+', 1.0), TestOutputLine('| |', 0.1), TestOutputLine('+-+-+', 0.1), TestOutputLine(' | |', 0.1), TestOutputLine(' +-+-+', 0.1), TestOutputLine(' | |', 0.1), TestOutputLine(' +-+-+', 0.1), TestOutputLine(' | |', 0.1), TestOutputLine(' +-+', 0.1), TestEndOfOutput(1.0) ]

def run_test() -> None: process = None

try: process = start_process() run_test_lines(process) print_labeled_output( 'PASSED', 'Your "project0.py" passed the sanity checker. Note that there are', 'other tests you\'ll want to run on your own, because we\'ll be testing', 'scenarios other than just this one. But you\'re well on your way to', 'being done with Project #0.')

except TestFailure: print_labeled_output( 'FAILED', 'The sanity checker has failed, for the reasons described above.')

finally: if process != None: process.close()

def start_process() -> TextProcess: filenames_in_dir = [p.name for p in list(pathlib.Path.cwd().iterdir()) if p.is_file()]

if not 'project0.py' in filenames_in_dir: print_labeled_output( 'ERROR', 'Cannot find file "project0.py" in this directory.', 'Make sure that the sanity checker is in the same directory as the', '"project0.py" that comprises your Project #0 solution. Also, be', 'sure that you\'ve named your "project0.py" file correctly, noting', 'that capitalization and spacing matter.')

raise TestFailure()

else: return TextProcess( [sys.executable, str(pathlib.Path.cwd() / 'project0.py')], str(pathlib.Path.cwd()))

def print_labeled_output(label: str, *msg_lines: typing.Iterable[str]) -> None: showed_first = False

for msg_line in msg_lines: if not showed_first: print('{:10}|{}'.format(label, msg_line)) showed_first = True else: print('{:10}|{}'.format(' ', msg_line))

if not showed_first: print(label)

def run_test_lines(process: TextProcess) -> None: for line in TEST_LINES: line.execute(process)

if __name__ == '__main__': run_test()

Your program is required to read a single line of input from the user (without printing any input prompt), which is expected to be a positive integer n (i.e., n will be neither zero nor negative). You can freely assume that your program will be given a positive integer, and it's not important what you do in any other case; we'll only test your program with positive integer input. You can also freely assume that n will not be greater than 999. After reading the input, your program will print a downward block diagonal of size n. The precise format of a downward block diagonal is best demonstrated with an example. If the input to the program was 4, the output would look like this: A few additional requirements apply: Though I've indented the text above to set it apart from the rest of the project write-up, note that the left edge of the topmost block must begin in the leftmost column of the output (i.e., it should not be indented at all). There must be no whitespace (e.g., spaces or tabs) at the end of each line of output. There must be a newline on the end of each line, including the last one. This is a complete specification of the structure of a downward block diagonal; the description is enough to solve the problem, so we will not be answering any additional questions about its structure. However, we are providing a tool that will give you a basic understanding of whether your program is reading the correct input and generating output in the correct format

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access with AI-Powered Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Students also viewed these Databases questions