diff --git a/src/problem_bank_scripts/problem_bank_scripts.py b/src/problem_bank_scripts/problem_bank_scripts.py index 0366c9ce..ae73ed01 100644 --- a/src/problem_bank_scripts/problem_bank_scripts.py +++ b/src/problem_bank_scripts/problem_bank_scripts.py @@ -457,6 +457,7 @@ def write_info_json(output_path, parsed_question): "singleVariant", "showCorrectAnswer", "externalGradingOptions", + "workspaceOptions" } # Add tags based on part type @@ -489,6 +490,15 @@ def write_info_json(output_path, parsed_question): } ) + if "workspaceOptions" in info_json: # validate workspaceOptions contains the required keys if it exists + image = "image" in info_json["workspaceOptions"] + port = "port" in info_json["workspaceOptions"] + home = "home" in info_json["workspaceOptions"] + if not (image and port and home): + raise SyntaxError("workspaceOptions must contain image, port, and home keys") + if not isinstance(info_json["workspaceOptions"]["port"], int): + raise TypeError(f"workspaceOptions.port must be an integer, got {type(info_json['workspaceOptions']['port'])!r} instead") + # End add tags with pathlib.Path(output_path / "info.json").open("w") as output_file: json.dump(info_json, output_file, indent=4) @@ -874,6 +884,31 @@ def process_string_input(part_name, parsed_question, data_dict): return replace_tags(html) +def process_workspace(part_name, parsed_question, data_dict): + """Processes markdown format of workspace questions and returns PL HTML + Args: + part_name (string): Name of the question part being processed (e.g., part1, part2, etc...) + parsed_question (dict): Dictionary of the MD-parsed question (output of `read_md_problem`) + data_dict (dict): Dictionary of the `data` dict created after running server.py using `exec()` + + Returns: + html: A string of HTML that is part of the final PL question.html file. + """ + if "pl-customizations" in parsed_question["header"][part_name]: + if len(parsed_question["header"][part_name]["pl-customizations"]) > 0: + raise ValueError("pl-customizations are not supported for workspace questions") + + + html = f"""\n{parsed_question['body_parts_split'][part_name]['content']}\n\n\n""" + + html += f"""""" + + if parsed_question["header"][part_name].get("gradingMethod", None) == "External": + html += f"""\n\t\n\t""" + + return replace_tags(html) + + def process_matrix_component_input(part_name, parsed_question, data_dict): """Processes markdown format of matrix-component-input questions and returns PL HTML Args: @@ -1171,24 +1206,56 @@ def str_presenter(dumper, data2): encoding="utf8", ) - # Move image assets + # Create the file errors list + os_errors = [] + + # Move client assets (generally images) files_to_copy = header.get("assets") if files_to_copy: - [ - copy2(pathlib.Path(source_filepath).parent / fl, output_path.parent) - for fl in files_to_copy - ] + pl_path = output_path.parent + for file in files_to_copy: + try: + copy2(pathlib.Path(source_filepath).parent / file, pl_path / file) + except (FileExistsError, FileNotFoundError, IsADirectoryError, PermissionError) as e: + os_errors.append(str(e)) + + # Move server assets + files_to_copy = header.get("serverFiles") + if files_to_copy and instructor: + pl_path = output_path.parent + for file in files_to_copy: + try: + copy2(pathlib.Path(source_filepath).parent / file, pl_path / file) + except (FileExistsError, FileNotFoundError, IsADirectoryError, PermissionError) as e: + os_errors.append(str(e)) # Move autograde py test files files_to_copy = header.get("autogradeTestFiles") if files_to_copy: pl_path = output_path.parent / "tests" pl_path.mkdir(parents=True, exist_ok=True) - [ - copy2(pathlib.Path(source_filepath).parent / "tests" / fl, pl_path / fl) - for fl in files_to_copy - if (instructor or fl == "starter_code.py") - ] + for file in files_to_copy: + if file != "starter_code.py" and not instructor: + continue + try: + copy2(pathlib.Path(source_filepath).parent / "tests" / file, pl_path / file) + except (FileExistsError, FileNotFoundError, IsADirectoryError, PermissionError) as e: + os_errors.append(str(e)) + + # Move workspace files + files_to_copy = header.get("workspaceFiles") + if files_to_copy: + pl_path = output_path.parent / "workspace" + pl_path.mkdir(parents=True, exist_ok=True) + for file in files_to_copy: + try: + copy2(pathlib.Path(source_filepath).parent / "workspace" / file, pl_path / file) + except (FileExistsError, FileNotFoundError, IsADirectoryError, PermissionError) as e: + os_errors.append(str(e)) + + if os_errors: + error_msg = "\n ".join(os_errors) + raise FileNotFoundError(f"Error(s) copying specified files:\n {error_msg}") def process_question_pl(source_filepath, output_path=None, dev=False): @@ -1310,6 +1377,8 @@ def process_question_pl(source_filepath, output_path=None, dev=False): question_html += process_string_input(part, parsed_q, data2) elif "matching" in q_type: question_html += process_matching(part, parsed_q, data2) + elif "workspace" in q_type: + question_html += process_workspace(part, parsed_q, data2) elif "matrix-component-input" in q_type: question_html += process_matrix_component_input(part, parsed_q, data2) elif "matrix-input" in q_type: @@ -1364,25 +1433,56 @@ def process_question_pl(source_filepath, output_path=None, dev=False): # Write server.py file write_server_py(output_path, parsed_q) - # Move image assets + # Create the file errors list + os_errors = [] + + # Move client assets (generally images) files_to_copy = parsed_q["header"].get("assets") if files_to_copy: pl_path = output_path / "clientFilesQuestion" pl_path.mkdir(parents=True, exist_ok=True) - [ - copy2(pathlib.Path(source_filepath).parent / fl, pl_path / fl) - for fl in files_to_copy - ] + for file in files_to_copy: + try: + copy2(pathlib.Path(source_filepath).parent / file, pl_path / file) + except (FileExistsError, FileNotFoundError, IsADirectoryError, PermissionError) as e: + os_errors.append(str(e)) + + # Move server assets + files_to_copy = parsed_q["header"].get("serverFiles") + if files_to_copy: + pl_path = output_path / "serverFilesQuestion" + pl_path.mkdir(parents=True, exist_ok=True) + for file in files_to_copy: + try: + copy2(pathlib.Path(source_filepath).parent / file, pl_path / file) + except (FileExistsError, FileNotFoundError, IsADirectoryError, PermissionError) as e: + os_errors.append(str(e)) # Move autograde py test files files_to_copy = parsed_q["header"].get("autogradeTestFiles") if files_to_copy: pl_path = output_path / "tests" pl_path.mkdir(parents=True, exist_ok=True) - [ - copy2(pathlib.Path(source_filepath).parent / "tests" / fl, pl_path / fl) - for fl in files_to_copy - ] + for file in files_to_copy: + try: + copy2(pathlib.Path(source_filepath).parent / "tests" / file, pl_path / file) + except (FileExistsError, FileNotFoundError, IsADirectoryError, PermissionError) as e: + os_errors.append(str(e)) + + # Move workspace files + files_to_copy = parsed_q["header"].get("workspaceFiles") + if files_to_copy: + pl_path = output_path / "workspace" + pl_path.mkdir(parents=True, exist_ok=True) + for file in files_to_copy: + try: + copy2(pathlib.Path(source_filepath).parent / "workspace" / file, pl_path / file) + except (FileExistsError, FileNotFoundError, IsADirectoryError, PermissionError) as e: + os_errors.append(str(e)) + + if os_errors: + error_msg = "\n ".join(os_errors) + raise FileNotFoundError(f"Error(s) copying specified files:\n {error_msg}") def pl_image_path(html): @@ -1433,3 +1533,4 @@ def validate_header(header_dict): if topics.get(topic := header_dict["topic"], None) is None: raise ValueError(f"topic '{topic}' is not listed in the learning outcomes") + diff --git a/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/file1.txt b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/file1.txt new file mode 100644 index 00000000..b30565ee --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/file1.txt @@ -0,0 +1,18 @@ +Gk44G5S2cov8PgPpy9n7r0v4FYY7zU/7i8UNDrRYLU1GjpVdCPIzdbUUcln3CqNlBTEKjn75+3qs +DUvteohtwFF+4BYwAyfv7yjzX9CPsyfHjBYC+b+fMHPMFns1vdlGUvwDEePE4k1EnJECUZKTkebJ +ymKhR6BY4IUnO5cVsRARExtVkYddHUcNAhgLpN9E/SNln9gJ9fN4WRat6l2QSDaH2OJ96+lDM/yR +EVttiFtCynzgguVYQy06tlpLXk9a9MwPlVGJvH/qH28pHkIac2H6UpWnDcBptsVJTVfTVv9Gp9/s +IQmeZRDIUy6163Ga9Uke6o1W7dVeohjvwY/KQHApZcK15RDkb+UiBd/9VM26N7eMoW41Sg7SKtQZ ++i8vEu2H6whEnvZCnYg+sOh9fxaDlOQhh7qhu4g2z1TORCjWzgELzZEmPJVrsf45cG0tz0xKoF/d +Uw/YoHF8RJexASnLZWj4125sNCQ6XfoEl1DLzUULxH7SeWM9owpouV5RZC3LZmCgyDUvbI0oMk+l +9GTae6lcMLOKD1R2q4NksQAt/osyWXQZw1g6pcqNSz1TdirbiQsTY6g+JZ3pYN2tK2w4WqVnLPix +lI9ktBec6XknnEEvrI7NhPLEXdxS7mUXuapCV6EfMfDPMvW523EUQPE5MWYBvHTmlIW5pemWgsAd +vuCFOIjs73L0es+88D3gCrSGSyk7KydSY3f2XCD8PLf78ZamVWi9yRpQryc33bRB2CaGhHhmbKto +4nsb+ToaG0aZE2FtIjOHTyC8jjsqgLRbHfRXJVFnngKVT+DEQnrfLRuC8+PtMrDDpZ4VarpK0aLd +BMtHPOsg+cOhwhqU021s2nq6G6XKfSDHeRR/2T/R0loeMr8/6UCVQKXitWl2f//tfnBYYMQObys3 +tYsJC46pR+Gp9ytUxc+//NKKmhn1J4Sm8anhGeePEmxroVbm5O16jk62u+L2jNJ0HOGYXNKizuKP +aVSReke4ZqdxJCCLZjLS6q4B5v5s7XK2TRFUb7BUeOVvezG698khGjCdPDOZH1gYxRoKR5VrkM1z +Mr8VPMi6io9GhaGehNz+N5ygXp6IG9VOht+j7H1y76rgooUtmtNKLuySTkf4nxK/FocuyCsDxP0r +jIZIgLEn1CD6R+ewbVZbFqwJt5RfJRpGss3Lmn3SdF4VEYQNHos6ytL0JzejC0Q7Foy5YC0cC0QC +fjpFZcbNXCJSnq6fX+KKq8MdHdivisU2Nd+5TCeqDdpuz2Plxs0o6wMlrYxIJKH+caxzvtlKdmRh +u1Ko/xz1A4VkljPJAudnrWXuvgfxVCacQ0DNJ/I8fA== diff --git a/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/file2.txt b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/file2.txt new file mode 100644 index 00000000..492987ca --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/file2.txt @@ -0,0 +1,18 @@ +DBVUxxDUlMoztjq4PiJSvgtwoY56pePoFur5Pz64DnE3tf2d7ffUtDBqluysfK62jpBzD9Ws6sTp +HZj7GIV1UQZloqbT2jPwyi5HGs1/aDfwTJA+ISur9mSEKLGEHADFqMsC9B5OW1P6hpzWiIjTGzde +VBOE5LfCy03VEsHfu90Ouk+PjEkxCz7rdIjjmxIDTp0GVmy73UwjvPT9Qwu70i2qSA1MDpCfAFmu +daTha8axoUcTnhNFlT2jVf4e/4cITNEsi/T/mMbpAtbXQXXLfflv7btJDTnY7L05AJetLmIXhZXB +OCwkA0d4gPMjG6p5Lkq3Vs3aeO8CVgSLeKEWz8Pru1pbSe0xDtt6EGZXK4axQ/gpZQfymEdqF4x5 +V3qqlVMDYcwIHkZiLdmxZOBX6J62yHtU7VdMD8zaT2Ds+fnqc4O0kRuUl+wZb+aQ1+ScZ17mxZ4B +6//1Ped29UUHuZQcJlOfrbtoXH4ZNO01OzZbQQ9YHlHLpOKQNqPXyBBH0bTz53ta5QX0ItMZ42eo +61fMjWm4baU4UmB1s9jlQGMYoVoo8URROfuZn7kirS9J5YLOpAuny+dBZsS8ezjwFput3Hh5JyYo +qIiC7oIVjHsHoYgAELxxFzLR3RreRxbKcoNxvdBu/4RngKzahXypIVPx0ldMiWIVnoEZlJtq5WE5 +S49N+ojExqOOWPPgXxcUP8dHkhfXoDgTph4M0ZFb4H6FJuwX/R7CqNHnqHbgYiCj1tZG4LBwVO/v +kamJudzm/SBvLlUycL9JrMgedLnUmVZorUgj4IVDju8lyHcz8RRBFHCBTh4LII+W+PBQ21LBCsH8 +2BZPOh8MLXFb8G7stl/n0rMkqC+tmRw2CAjwmbz/54nwuzm8o7k7cGXhou6blkx6tBlC54muSBWd +X7vNSctuY+JwwgLXk5JfeHIF2JdaCNaGyyBFgPer2rTG9PuoHD3QRibXOJSHy+NlCLrdrZXB89HQ +WNCpeBjWjlclG/O7LL2yuvrkvM5eohPjRBIHa4lxzEecL5Y+SPUOy7vIg0DChpL5CzpbYzgM15mS +Zd/ai7rkBzfdJMlmxTXNewMVaf4drtx9Cg9HJAWCjIjaX1lqOfku2vqKetfLQytz1qnNYo8oPcKE +PmaHbGkubdHI3+dDbqva3LWgrKjUNdVaQq+ICo57Pdo1FycScSyWW58Peldh0mIZodxVt8IiDiR3 +hjVJqGkRuxT0T07Dc2fXHKtylz8L2VdAQeeqqdaLvJnNVRU/CRzjdLLnWKUzC4f3CiFVeHW1MiRn +hWLsmy+tcEvZnFh29K1Ei55NFBcQjUvBQvmZgg+SiQ== diff --git a/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/filebad.txt b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/filebad.txt new file mode 100644 index 00000000..90505446 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/filebad.txt @@ -0,0 +1,18 @@ +a5HQSUh3ZVyvZxZvF2t+Pi3BLjHQ8MTJJ/2I7rqOQQ+mPC3AWAD5WHR5OZ+XwE6qfVjThv0rH1Lk +3N9phhpM+4Ij7g2KwPK6sb076LbD6PRVNpIVjEfEuzdi8pcZ4hDvYbPOSZ3FSpqvDGbFCBRSobSp +npEnw2DkyABjlvh5JKsv732jrZBBXHqgtBE7RgVeT+wlXo6nu8h1330fOYQ3y0F8UCWELtqfHseU +A3T/yB56wOG33k8jBvpAzAYmM+zr3xfFKhp36Ak2NvKH2oikeUi5wB1q8kaVVbHKCEoCYYW/mYnf +FFaAh2zMYOhVEeNUaee8RrSQvIXar2vgOim9W4vJxgKRUpjp09YFDw9lOgu4ddru60pR7QLNmCP5 +ht1jImO1p0TZ+A/Vwp6jKskDFqKy7ZZBTHYT99scrUWd7OEyyIbWF7OSIeq8wubAqcbAJ6NMUBRv +JqPxsbNNhkm/Xw4zvhQyhsI5P9QIjBpzL8SwxdhD5DdGfP8JGQLaLlvW8GlgBhteNY2k5lpSL2YJ +UsT4BT6fkeZnaWNfxJR69eAI98PeDiVW8KedvtE/wU4WlhmXi/bY7lenZi6sBSzqiXxaJujszLIG +c/bahugWAMXEBHGBduaYBOI6JGdFY2219qqKlY1aM2WUBTh/IF+Ig9PZDSMGW/Qo4HEo8HYge1sl +JkbcIL2zNhLpUJR8eCaZ06QI8KOa2LvtVLRBFRCdLXhdelD3uZDYWRVh+0ykASdCNURqayIxC3ys +Uwq95Qt5uB0teliY/xQ+JRvu6YnU+kStJGrEgaeS8ZjF85ogFCbNUnqvub1mvek/y23Z5SSYSKm/ +KcUpAIVfAg+W2YriERzUEsyzMjTKS1MP4mEeWUGgBIR4yGU2hivyd4P0eeIAti/zCTaKQBTRwXJX +4nar06DgLUj4HHdcd7aaLTxt4bHA646IXO+2qYxQAZxvKkgWfZ6QWFakXVROR/6lfqJDLD3QVFD0 +0d25EOhPbxe/Q7L8TR7rMsmE7cpJvA/Mjv36g6f2l0PngzPlm/EiJ0i0wn/3Al4A5+AEfxDwRMFo +rNkaJEyEkRBDo5UeVdnTVXH1z70RLSju0n4oJe3NS47nv+gP5brMCkPxEh0pY1vtSFskaLHqJZwV +NWFSdij8THFL0dlfKG5wyPwtwCuQqCz029wRjfJNFEgfqWOGGXZLLC+7n4wdSr2QO+ppZdKqB/Bl +t6i2u5iwH+XrYf4j9THtXCQ6w/FEere2q8EBkCaTSOhKC+Gyp1rAnyuuYIy/dxprJKI4EzhgVHYo +171ZFv6aNT1ETGgB8ejaU9025ozLjRHvcbuHIZsm3g== diff --git a/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/q16_workspaces.md b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/q16_workspaces.md new file mode 100644 index 00000000..a1e11c53 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/q16_workspaces.md @@ -0,0 +1,153 @@ +--- +title: Moving and copying files +topic: Template +author: Jonatan Schroeder; Converted by Gavin Kendal-Freedman +source: original +template_version: 1.0 +attribution: standard +partialCredit: true +singleVariant: false +showCorrectAnswer: false +outcomes: +- 6.1.1.0 +- 6.1.1.1 +difficulty: +- undefined +randomization: +- undefined +taxonomy: +- undefined +span: +- undefined +length: +- undefined +tags: +- unknown +assets: null +workspaceFiles: +- file1.txt +- file2.txt +- filebad.txt +serverFiles: +- file1.txt +- file2.txt +- filebad.txt +workspaceOptions: + image: prairielearn/workspace-xtermjs + port: 8080 + home: /home/student + gradedFiles: + - file1.txt + - file2.txt + - filebad.txt + - newdir/file1_new.txt + - newdir/file2_new.txt +server: + imports: "import base64 \nimport problem_bank_helpers as pbh\n" + generate: | + data2 = pbh.create_data2() + + data2["params"]["vars"]["title"] = "Moving and copying files" + + # Update the data object with a new dict + data.update(data2) + grade: | + files = { f['name']: f['contents'] for f in data['submitted_answers'].get('_files', []) } + data['feedback']['results'] = [] + data['score'] = 0 + + with open('workspace/file1.txt', 'rb') as f: + file1_content = base64.b64encode(f.read()).decode() + with open('workspace/file2.txt', 'rb') as f: + file2_content = base64.b64encode(f.read()).decode() + + if 'newdir/file1_new.txt' not in files: + data['feedback']['results'].append('newdir/file1_new.txt was not created.') + elif files['newdir/file1_new.txt'] != file1_content: + data['feedback']['results'].append('newdir/file1_new.txt was created, but it is not based on file1.txt.') + elif 'file1.txt' in files: + data['feedback']['results'].append('newdir/file1_new.txt was created properly, but the old file still exists.') + data['score'] += 0.2 + else: + data['feedback']['results'].append('file1.txt moved successfully.') + data['score'] += 0.4 + + if 'newdir/file2_new.txt' not in files: + data['feedback']['results'].append('newdir/file2_new.txt was not created.') + elif files['newdir/file2_new.txt'] != file2_content: + data['feedback']['results'].append('newdir/file2_new.txt was created, but it is not based on file2.txt.') + elif 'file2.txt' not in files: + data['feedback']['results'].append('newdir/file2_new.txt was created properly, but the old file no longer exists.') + data['score'] += 0.2 + else: + data['feedback']['results'].append('file2.txt copied successfully.') + data['score'] += 0.4 + + if files and 'filebad.txt' in files: + data['feedback']['results'].append('filebad.txt still exists.') + else: + data['feedback']['results'].append('filebad.txt deleted successfully.') + data['score'] += 0.2 + prepare: 'pass + + ' + parse: | + if '_files' in data['format_errors']: + del data['format_errors']['_files'] +part1: + type: workspace +myst: + substitutions: + params: + vars: + title: Moving and copying files + +--- +# {{ params.vars.title }} + +## Question Text + +Open the Workspace below and perform the following tasks. + +- Create a new directory called `newdir`; +- Move the file `file1.txt` to the directory `newdir`, with the new name `file1_new.txt`; +- Copy the file `file2.txt` to the directory `newdir`, with the new name `file2_new.txt`; +- Delete the file `filebad.txt`. + +Once you complete these tasks, click on "Save & Grade" below. + +### Answer Section + +### pl-submission-panel + + + + + +### pl-answer-panel + +Everything here will get inserted directly into an pl-answer-panel element at the end of the `question.html`. +Please remove this section if it is not application for this question. + +## Rubric + +This should be hidden from students until after the deadline. + +## Solution + +This should never be revealed to students. + +## Comments + +These are random comments associated with this question: + +This example problem was originally created by [Jonatan Schroeder](https://www.cs.ubc.ca/people/jonatan-schroeder), and was later converted to the OER markdown layout. + +## Attribution + +Problem is licensed under the [CC-BY-NC-SA 4.0 license](https://creativecommons.org/licenses/by-nc-sa/4.0/).
![The Creative Commons 4.0 license requiring attribution-BY, non-commercial-NC, and share-alike-SA license.](https://raw.githubusercontent.com/firasm/bits/master/by-nc-sa.png) \ No newline at end of file diff --git a/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/workspace/file1.txt b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/workspace/file1.txt new file mode 100644 index 00000000..b30565ee --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/workspace/file1.txt @@ -0,0 +1,18 @@ +Gk44G5S2cov8PgPpy9n7r0v4FYY7zU/7i8UNDrRYLU1GjpVdCPIzdbUUcln3CqNlBTEKjn75+3qs +DUvteohtwFF+4BYwAyfv7yjzX9CPsyfHjBYC+b+fMHPMFns1vdlGUvwDEePE4k1EnJECUZKTkebJ +ymKhR6BY4IUnO5cVsRARExtVkYddHUcNAhgLpN9E/SNln9gJ9fN4WRat6l2QSDaH2OJ96+lDM/yR +EVttiFtCynzgguVYQy06tlpLXk9a9MwPlVGJvH/qH28pHkIac2H6UpWnDcBptsVJTVfTVv9Gp9/s +IQmeZRDIUy6163Ga9Uke6o1W7dVeohjvwY/KQHApZcK15RDkb+UiBd/9VM26N7eMoW41Sg7SKtQZ ++i8vEu2H6whEnvZCnYg+sOh9fxaDlOQhh7qhu4g2z1TORCjWzgELzZEmPJVrsf45cG0tz0xKoF/d +Uw/YoHF8RJexASnLZWj4125sNCQ6XfoEl1DLzUULxH7SeWM9owpouV5RZC3LZmCgyDUvbI0oMk+l +9GTae6lcMLOKD1R2q4NksQAt/osyWXQZw1g6pcqNSz1TdirbiQsTY6g+JZ3pYN2tK2w4WqVnLPix +lI9ktBec6XknnEEvrI7NhPLEXdxS7mUXuapCV6EfMfDPMvW523EUQPE5MWYBvHTmlIW5pemWgsAd +vuCFOIjs73L0es+88D3gCrSGSyk7KydSY3f2XCD8PLf78ZamVWi9yRpQryc33bRB2CaGhHhmbKto +4nsb+ToaG0aZE2FtIjOHTyC8jjsqgLRbHfRXJVFnngKVT+DEQnrfLRuC8+PtMrDDpZ4VarpK0aLd +BMtHPOsg+cOhwhqU021s2nq6G6XKfSDHeRR/2T/R0loeMr8/6UCVQKXitWl2f//tfnBYYMQObys3 +tYsJC46pR+Gp9ytUxc+//NKKmhn1J4Sm8anhGeePEmxroVbm5O16jk62u+L2jNJ0HOGYXNKizuKP +aVSReke4ZqdxJCCLZjLS6q4B5v5s7XK2TRFUb7BUeOVvezG698khGjCdPDOZH1gYxRoKR5VrkM1z +Mr8VPMi6io9GhaGehNz+N5ygXp6IG9VOht+j7H1y76rgooUtmtNKLuySTkf4nxK/FocuyCsDxP0r +jIZIgLEn1CD6R+ewbVZbFqwJt5RfJRpGss3Lmn3SdF4VEYQNHos6ytL0JzejC0Q7Foy5YC0cC0QC +fjpFZcbNXCJSnq6fX+KKq8MdHdivisU2Nd+5TCeqDdpuz2Plxs0o6wMlrYxIJKH+caxzvtlKdmRh +u1Ko/xz1A4VkljPJAudnrWXuvgfxVCacQ0DNJ/I8fA== diff --git a/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/workspace/file2.txt b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/workspace/file2.txt new file mode 100644 index 00000000..492987ca --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/workspace/file2.txt @@ -0,0 +1,18 @@ +DBVUxxDUlMoztjq4PiJSvgtwoY56pePoFur5Pz64DnE3tf2d7ffUtDBqluysfK62jpBzD9Ws6sTp +HZj7GIV1UQZloqbT2jPwyi5HGs1/aDfwTJA+ISur9mSEKLGEHADFqMsC9B5OW1P6hpzWiIjTGzde +VBOE5LfCy03VEsHfu90Ouk+PjEkxCz7rdIjjmxIDTp0GVmy73UwjvPT9Qwu70i2qSA1MDpCfAFmu +daTha8axoUcTnhNFlT2jVf4e/4cITNEsi/T/mMbpAtbXQXXLfflv7btJDTnY7L05AJetLmIXhZXB +OCwkA0d4gPMjG6p5Lkq3Vs3aeO8CVgSLeKEWz8Pru1pbSe0xDtt6EGZXK4axQ/gpZQfymEdqF4x5 +V3qqlVMDYcwIHkZiLdmxZOBX6J62yHtU7VdMD8zaT2Ds+fnqc4O0kRuUl+wZb+aQ1+ScZ17mxZ4B +6//1Ped29UUHuZQcJlOfrbtoXH4ZNO01OzZbQQ9YHlHLpOKQNqPXyBBH0bTz53ta5QX0ItMZ42eo +61fMjWm4baU4UmB1s9jlQGMYoVoo8URROfuZn7kirS9J5YLOpAuny+dBZsS8ezjwFput3Hh5JyYo +qIiC7oIVjHsHoYgAELxxFzLR3RreRxbKcoNxvdBu/4RngKzahXypIVPx0ldMiWIVnoEZlJtq5WE5 +S49N+ojExqOOWPPgXxcUP8dHkhfXoDgTph4M0ZFb4H6FJuwX/R7CqNHnqHbgYiCj1tZG4LBwVO/v +kamJudzm/SBvLlUycL9JrMgedLnUmVZorUgj4IVDju8lyHcz8RRBFHCBTh4LII+W+PBQ21LBCsH8 +2BZPOh8MLXFb8G7stl/n0rMkqC+tmRw2CAjwmbz/54nwuzm8o7k7cGXhou6blkx6tBlC54muSBWd +X7vNSctuY+JwwgLXk5JfeHIF2JdaCNaGyyBFgPer2rTG9PuoHD3QRibXOJSHy+NlCLrdrZXB89HQ +WNCpeBjWjlclG/O7LL2yuvrkvM5eohPjRBIHa4lxzEecL5Y+SPUOy7vIg0DChpL5CzpbYzgM15mS +Zd/ai7rkBzfdJMlmxTXNewMVaf4drtx9Cg9HJAWCjIjaX1lqOfku2vqKetfLQytz1qnNYo8oPcKE +PmaHbGkubdHI3+dDbqva3LWgrKjUNdVaQq+ICo57Pdo1FycScSyWW58Peldh0mIZodxVt8IiDiR3 +hjVJqGkRuxT0T07Dc2fXHKtylz8L2VdAQeeqqdaLvJnNVRU/CRzjdLLnWKUzC4f3CiFVeHW1MiRn +hWLsmy+tcEvZnFh29K1Ei55NFBcQjUvBQvmZgg+SiQ== diff --git a/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/workspace/filebad.txt b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/workspace/filebad.txt new file mode 100644 index 00000000..90505446 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/instructor/q16_workspaces/workspace/filebad.txt @@ -0,0 +1,18 @@ +a5HQSUh3ZVyvZxZvF2t+Pi3BLjHQ8MTJJ/2I7rqOQQ+mPC3AWAD5WHR5OZ+XwE6qfVjThv0rH1Lk +3N9phhpM+4Ij7g2KwPK6sb076LbD6PRVNpIVjEfEuzdi8pcZ4hDvYbPOSZ3FSpqvDGbFCBRSobSp +npEnw2DkyABjlvh5JKsv732jrZBBXHqgtBE7RgVeT+wlXo6nu8h1330fOYQ3y0F8UCWELtqfHseU +A3T/yB56wOG33k8jBvpAzAYmM+zr3xfFKhp36Ak2NvKH2oikeUi5wB1q8kaVVbHKCEoCYYW/mYnf +FFaAh2zMYOhVEeNUaee8RrSQvIXar2vgOim9W4vJxgKRUpjp09YFDw9lOgu4ddru60pR7QLNmCP5 +ht1jImO1p0TZ+A/Vwp6jKskDFqKy7ZZBTHYT99scrUWd7OEyyIbWF7OSIeq8wubAqcbAJ6NMUBRv +JqPxsbNNhkm/Xw4zvhQyhsI5P9QIjBpzL8SwxdhD5DdGfP8JGQLaLlvW8GlgBhteNY2k5lpSL2YJ +UsT4BT6fkeZnaWNfxJR69eAI98PeDiVW8KedvtE/wU4WlhmXi/bY7lenZi6sBSzqiXxaJujszLIG +c/bahugWAMXEBHGBduaYBOI6JGdFY2219qqKlY1aM2WUBTh/IF+Ig9PZDSMGW/Qo4HEo8HYge1sl +JkbcIL2zNhLpUJR8eCaZ06QI8KOa2LvtVLRBFRCdLXhdelD3uZDYWRVh+0ykASdCNURqayIxC3ys +Uwq95Qt5uB0teliY/xQ+JRvu6YnU+kStJGrEgaeS8ZjF85ogFCbNUnqvub1mvek/y23Z5SSYSKm/ +KcUpAIVfAg+W2YriERzUEsyzMjTKS1MP4mEeWUGgBIR4yGU2hivyd4P0eeIAti/zCTaKQBTRwXJX +4nar06DgLUj4HHdcd7aaLTxt4bHA646IXO+2qYxQAZxvKkgWfZ6QWFakXVROR/6lfqJDLD3QVFD0 +0d25EOhPbxe/Q7L8TR7rMsmE7cpJvA/Mjv36g6f2l0PngzPlm/EiJ0i0wn/3Al4A5+AEfxDwRMFo +rNkaJEyEkRBDo5UeVdnTVXH1z70RLSju0n4oJe3NS47nv+gP5brMCkPxEh0pY1vtSFskaLHqJZwV +NWFSdij8THFL0dlfKG5wyPwtwCuQqCz029wRjfJNFEgfqWOGGXZLLC+7n4wdSr2QO+ppZdKqB/Bl +t6i2u5iwH+XrYf4j9THtXCQ6w/FEere2q8EBkCaTSOhKC+Gyp1rAnyuuYIy/dxprJKI4EzhgVHYo +171ZFv6aNT1ETGgB8ejaU9025ozLjRHvcbuHIZsm3g== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/info.json b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/info.json new file mode 100644 index 00000000..221ffeb9 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/info.json @@ -0,0 +1,25 @@ +{ + "uuid": "fc0d8086-108a-3418-a5d7-498e9af0bd74", + "title": "Moving and copying files", + "topic": "000.Template", + "tags": [ + "workspace", + "DEV" + ], + "type": "v3", + "singleVariant": false, + "partialCredit": true, + "workspaceOptions": { + "image": "prairielearn/workspace-xtermjs", + "port": 8080, + "home": "/home/student", + "gradedFiles": [ + "file1.txt", + "file2.txt", + "filebad.txt", + "newdir/file1_new.txt", + "newdir/file2_new.txt" + ] + }, + "showCorrectAnswer": false +} \ No newline at end of file diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/question.html b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/question.html new file mode 100644 index 00000000..83e23818 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/question.html @@ -0,0 +1,38 @@ + + + + +Open the Workspace below and perform the following tasks. + +- Create a new directory called `newdir`; +- Move the file `file1.txt` to the directory `newdir`, with the new name `file1_new.txt`; +- Copy the file `file2.txt` to the directory `newdir`, with the new name `file2_new.txt`; +- Delete the file `filebad.txt`. + +Once you complete these tasks, click on "Save & Grade" below. + + + + + + + + + +Everything here will get inserted directly into an pl-answer-panel element at the end of the `question.html`. +Please remove this section if it is not application for this question. + + + + + + +--- +Problem is licensed under the [CC-BY-NC-SA 4.0 license](https://creativecommons.org/licenses/by-nc-sa/4.0/).
![The Creative Commons 4.0 license requiring attribution-BY, non-commercial-NC, and share-alike-SA license.](https://raw.githubusercontent.com/firasm/bits/master/by-nc-sa.png) +
+
diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/server.py b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/server.py new file mode 100644 index 00000000..1e664476 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/server.py @@ -0,0 +1,70 @@ +import base64 +import problem_bank_helpers as pbh + +def imports(data): + import base64 + import problem_bank_helpers as pbh + +def generate(data): + data2 = pbh.create_data2() + + data2["params"]["vars"]["title"] = "Moving and copying files" + + # Update the data object with a new dict + data.update(data2) + + # Start code added automatically by problem_bank_scripts + + # Convert backticks to code blocks/fences in answer choices. + pbh.backticks_to_code_tags(data2) + + # Update data with data2 + data.update(data2) + + # End code added in by problem bank scripts + +def grade(data): + files = { f['name']: f['contents'] for f in data['submitted_answers'].get('_files', []) } + data['feedback']['results'] = [] + data['score'] = 0 + + with open('workspace/file1.txt', 'rb') as f: + file1_content = base64.b64encode(f.read()).decode() + with open('workspace/file2.txt', 'rb') as f: + file2_content = base64.b64encode(f.read()).decode() + + if 'newdir/file1_new.txt' not in files: + data['feedback']['results'].append('newdir/file1_new.txt was not created.') + elif files['newdir/file1_new.txt'] != file1_content: + data['feedback']['results'].append('newdir/file1_new.txt was created, but it is not based on file1.txt.') + elif 'file1.txt' in files: + data['feedback']['results'].append('newdir/file1_new.txt was created properly, but the old file still exists.') + data['score'] += 0.2 + else: + data['feedback']['results'].append('file1.txt moved successfully.') + data['score'] += 0.4 + + if 'newdir/file2_new.txt' not in files: + data['feedback']['results'].append('newdir/file2_new.txt was not created.') + elif files['newdir/file2_new.txt'] != file2_content: + data['feedback']['results'].append('newdir/file2_new.txt was created, but it is not based on file2.txt.') + elif 'file2.txt' not in files: + data['feedback']['results'].append('newdir/file2_new.txt was created properly, but the old file no longer exists.') + data['score'] += 0.2 + else: + data['feedback']['results'].append('file2.txt copied successfully.') + data['score'] += 0.4 + + if files and 'filebad.txt' in files: + data['feedback']['results'].append('filebad.txt still exists.') + else: + data['feedback']['results'].append('filebad.txt deleted successfully.') + data['score'] += 0.2 + +def prepare(data): + pass + +def parse(data): + if '_files' in data['format_errors']: + del data['format_errors']['_files'] + diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/serverFilesQuestion/file1.txt b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/serverFilesQuestion/file1.txt new file mode 100644 index 00000000..b30565ee --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/serverFilesQuestion/file1.txt @@ -0,0 +1,18 @@ +Gk44G5S2cov8PgPpy9n7r0v4FYY7zU/7i8UNDrRYLU1GjpVdCPIzdbUUcln3CqNlBTEKjn75+3qs +DUvteohtwFF+4BYwAyfv7yjzX9CPsyfHjBYC+b+fMHPMFns1vdlGUvwDEePE4k1EnJECUZKTkebJ +ymKhR6BY4IUnO5cVsRARExtVkYddHUcNAhgLpN9E/SNln9gJ9fN4WRat6l2QSDaH2OJ96+lDM/yR +EVttiFtCynzgguVYQy06tlpLXk9a9MwPlVGJvH/qH28pHkIac2H6UpWnDcBptsVJTVfTVv9Gp9/s +IQmeZRDIUy6163Ga9Uke6o1W7dVeohjvwY/KQHApZcK15RDkb+UiBd/9VM26N7eMoW41Sg7SKtQZ ++i8vEu2H6whEnvZCnYg+sOh9fxaDlOQhh7qhu4g2z1TORCjWzgELzZEmPJVrsf45cG0tz0xKoF/d +Uw/YoHF8RJexASnLZWj4125sNCQ6XfoEl1DLzUULxH7SeWM9owpouV5RZC3LZmCgyDUvbI0oMk+l +9GTae6lcMLOKD1R2q4NksQAt/osyWXQZw1g6pcqNSz1TdirbiQsTY6g+JZ3pYN2tK2w4WqVnLPix +lI9ktBec6XknnEEvrI7NhPLEXdxS7mUXuapCV6EfMfDPMvW523EUQPE5MWYBvHTmlIW5pemWgsAd +vuCFOIjs73L0es+88D3gCrSGSyk7KydSY3f2XCD8PLf78ZamVWi9yRpQryc33bRB2CaGhHhmbKto +4nsb+ToaG0aZE2FtIjOHTyC8jjsqgLRbHfRXJVFnngKVT+DEQnrfLRuC8+PtMrDDpZ4VarpK0aLd +BMtHPOsg+cOhwhqU021s2nq6G6XKfSDHeRR/2T/R0loeMr8/6UCVQKXitWl2f//tfnBYYMQObys3 +tYsJC46pR+Gp9ytUxc+//NKKmhn1J4Sm8anhGeePEmxroVbm5O16jk62u+L2jNJ0HOGYXNKizuKP +aVSReke4ZqdxJCCLZjLS6q4B5v5s7XK2TRFUb7BUeOVvezG698khGjCdPDOZH1gYxRoKR5VrkM1z +Mr8VPMi6io9GhaGehNz+N5ygXp6IG9VOht+j7H1y76rgooUtmtNKLuySTkf4nxK/FocuyCsDxP0r +jIZIgLEn1CD6R+ewbVZbFqwJt5RfJRpGss3Lmn3SdF4VEYQNHos6ytL0JzejC0Q7Foy5YC0cC0QC +fjpFZcbNXCJSnq6fX+KKq8MdHdivisU2Nd+5TCeqDdpuz2Plxs0o6wMlrYxIJKH+caxzvtlKdmRh +u1Ko/xz1A4VkljPJAudnrWXuvgfxVCacQ0DNJ/I8fA== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/serverFilesQuestion/file2.txt b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/serverFilesQuestion/file2.txt new file mode 100644 index 00000000..492987ca --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/serverFilesQuestion/file2.txt @@ -0,0 +1,18 @@ +DBVUxxDUlMoztjq4PiJSvgtwoY56pePoFur5Pz64DnE3tf2d7ffUtDBqluysfK62jpBzD9Ws6sTp +HZj7GIV1UQZloqbT2jPwyi5HGs1/aDfwTJA+ISur9mSEKLGEHADFqMsC9B5OW1P6hpzWiIjTGzde +VBOE5LfCy03VEsHfu90Ouk+PjEkxCz7rdIjjmxIDTp0GVmy73UwjvPT9Qwu70i2qSA1MDpCfAFmu +daTha8axoUcTnhNFlT2jVf4e/4cITNEsi/T/mMbpAtbXQXXLfflv7btJDTnY7L05AJetLmIXhZXB +OCwkA0d4gPMjG6p5Lkq3Vs3aeO8CVgSLeKEWz8Pru1pbSe0xDtt6EGZXK4axQ/gpZQfymEdqF4x5 +V3qqlVMDYcwIHkZiLdmxZOBX6J62yHtU7VdMD8zaT2Ds+fnqc4O0kRuUl+wZb+aQ1+ScZ17mxZ4B +6//1Ped29UUHuZQcJlOfrbtoXH4ZNO01OzZbQQ9YHlHLpOKQNqPXyBBH0bTz53ta5QX0ItMZ42eo +61fMjWm4baU4UmB1s9jlQGMYoVoo8URROfuZn7kirS9J5YLOpAuny+dBZsS8ezjwFput3Hh5JyYo +qIiC7oIVjHsHoYgAELxxFzLR3RreRxbKcoNxvdBu/4RngKzahXypIVPx0ldMiWIVnoEZlJtq5WE5 +S49N+ojExqOOWPPgXxcUP8dHkhfXoDgTph4M0ZFb4H6FJuwX/R7CqNHnqHbgYiCj1tZG4LBwVO/v +kamJudzm/SBvLlUycL9JrMgedLnUmVZorUgj4IVDju8lyHcz8RRBFHCBTh4LII+W+PBQ21LBCsH8 +2BZPOh8MLXFb8G7stl/n0rMkqC+tmRw2CAjwmbz/54nwuzm8o7k7cGXhou6blkx6tBlC54muSBWd +X7vNSctuY+JwwgLXk5JfeHIF2JdaCNaGyyBFgPer2rTG9PuoHD3QRibXOJSHy+NlCLrdrZXB89HQ +WNCpeBjWjlclG/O7LL2yuvrkvM5eohPjRBIHa4lxzEecL5Y+SPUOy7vIg0DChpL5CzpbYzgM15mS +Zd/ai7rkBzfdJMlmxTXNewMVaf4drtx9Cg9HJAWCjIjaX1lqOfku2vqKetfLQytz1qnNYo8oPcKE +PmaHbGkubdHI3+dDbqva3LWgrKjUNdVaQq+ICo57Pdo1FycScSyWW58Peldh0mIZodxVt8IiDiR3 +hjVJqGkRuxT0T07Dc2fXHKtylz8L2VdAQeeqqdaLvJnNVRU/CRzjdLLnWKUzC4f3CiFVeHW1MiRn +hWLsmy+tcEvZnFh29K1Ei55NFBcQjUvBQvmZgg+SiQ== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/serverFilesQuestion/filebad.txt b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/serverFilesQuestion/filebad.txt new file mode 100644 index 00000000..90505446 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/serverFilesQuestion/filebad.txt @@ -0,0 +1,18 @@ +a5HQSUh3ZVyvZxZvF2t+Pi3BLjHQ8MTJJ/2I7rqOQQ+mPC3AWAD5WHR5OZ+XwE6qfVjThv0rH1Lk +3N9phhpM+4Ij7g2KwPK6sb076LbD6PRVNpIVjEfEuzdi8pcZ4hDvYbPOSZ3FSpqvDGbFCBRSobSp +npEnw2DkyABjlvh5JKsv732jrZBBXHqgtBE7RgVeT+wlXo6nu8h1330fOYQ3y0F8UCWELtqfHseU +A3T/yB56wOG33k8jBvpAzAYmM+zr3xfFKhp36Ak2NvKH2oikeUi5wB1q8kaVVbHKCEoCYYW/mYnf +FFaAh2zMYOhVEeNUaee8RrSQvIXar2vgOim9W4vJxgKRUpjp09YFDw9lOgu4ddru60pR7QLNmCP5 +ht1jImO1p0TZ+A/Vwp6jKskDFqKy7ZZBTHYT99scrUWd7OEyyIbWF7OSIeq8wubAqcbAJ6NMUBRv +JqPxsbNNhkm/Xw4zvhQyhsI5P9QIjBpzL8SwxdhD5DdGfP8JGQLaLlvW8GlgBhteNY2k5lpSL2YJ +UsT4BT6fkeZnaWNfxJR69eAI98PeDiVW8KedvtE/wU4WlhmXi/bY7lenZi6sBSzqiXxaJujszLIG +c/bahugWAMXEBHGBduaYBOI6JGdFY2219qqKlY1aM2WUBTh/IF+Ig9PZDSMGW/Qo4HEo8HYge1sl +JkbcIL2zNhLpUJR8eCaZ06QI8KOa2LvtVLRBFRCdLXhdelD3uZDYWRVh+0ykASdCNURqayIxC3ys +Uwq95Qt5uB0teliY/xQ+JRvu6YnU+kStJGrEgaeS8ZjF85ogFCbNUnqvub1mvek/y23Z5SSYSKm/ +KcUpAIVfAg+W2YriERzUEsyzMjTKS1MP4mEeWUGgBIR4yGU2hivyd4P0eeIAti/zCTaKQBTRwXJX +4nar06DgLUj4HHdcd7aaLTxt4bHA646IXO+2qYxQAZxvKkgWfZ6QWFakXVROR/6lfqJDLD3QVFD0 +0d25EOhPbxe/Q7L8TR7rMsmE7cpJvA/Mjv36g6f2l0PngzPlm/EiJ0i0wn/3Al4A5+AEfxDwRMFo +rNkaJEyEkRBDo5UeVdnTVXH1z70RLSju0n4oJe3NS47nv+gP5brMCkPxEh0pY1vtSFskaLHqJZwV +NWFSdij8THFL0dlfKG5wyPwtwCuQqCz029wRjfJNFEgfqWOGGXZLLC+7n4wdSr2QO+ppZdKqB/Bl +t6i2u5iwH+XrYf4j9THtXCQ6w/FEere2q8EBkCaTSOhKC+Gyp1rAnyuuYIy/dxprJKI4EzhgVHYo +171ZFv6aNT1ETGgB8ejaU9025ozLjRHvcbuHIZsm3g== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/workspace/file1.txt b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/workspace/file1.txt new file mode 100644 index 00000000..b30565ee --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/workspace/file1.txt @@ -0,0 +1,18 @@ +Gk44G5S2cov8PgPpy9n7r0v4FYY7zU/7i8UNDrRYLU1GjpVdCPIzdbUUcln3CqNlBTEKjn75+3qs +DUvteohtwFF+4BYwAyfv7yjzX9CPsyfHjBYC+b+fMHPMFns1vdlGUvwDEePE4k1EnJECUZKTkebJ +ymKhR6BY4IUnO5cVsRARExtVkYddHUcNAhgLpN9E/SNln9gJ9fN4WRat6l2QSDaH2OJ96+lDM/yR +EVttiFtCynzgguVYQy06tlpLXk9a9MwPlVGJvH/qH28pHkIac2H6UpWnDcBptsVJTVfTVv9Gp9/s +IQmeZRDIUy6163Ga9Uke6o1W7dVeohjvwY/KQHApZcK15RDkb+UiBd/9VM26N7eMoW41Sg7SKtQZ ++i8vEu2H6whEnvZCnYg+sOh9fxaDlOQhh7qhu4g2z1TORCjWzgELzZEmPJVrsf45cG0tz0xKoF/d +Uw/YoHF8RJexASnLZWj4125sNCQ6XfoEl1DLzUULxH7SeWM9owpouV5RZC3LZmCgyDUvbI0oMk+l +9GTae6lcMLOKD1R2q4NksQAt/osyWXQZw1g6pcqNSz1TdirbiQsTY6g+JZ3pYN2tK2w4WqVnLPix +lI9ktBec6XknnEEvrI7NhPLEXdxS7mUXuapCV6EfMfDPMvW523EUQPE5MWYBvHTmlIW5pemWgsAd +vuCFOIjs73L0es+88D3gCrSGSyk7KydSY3f2XCD8PLf78ZamVWi9yRpQryc33bRB2CaGhHhmbKto +4nsb+ToaG0aZE2FtIjOHTyC8jjsqgLRbHfRXJVFnngKVT+DEQnrfLRuC8+PtMrDDpZ4VarpK0aLd +BMtHPOsg+cOhwhqU021s2nq6G6XKfSDHeRR/2T/R0loeMr8/6UCVQKXitWl2f//tfnBYYMQObys3 +tYsJC46pR+Gp9ytUxc+//NKKmhn1J4Sm8anhGeePEmxroVbm5O16jk62u+L2jNJ0HOGYXNKizuKP +aVSReke4ZqdxJCCLZjLS6q4B5v5s7XK2TRFUb7BUeOVvezG698khGjCdPDOZH1gYxRoKR5VrkM1z +Mr8VPMi6io9GhaGehNz+N5ygXp6IG9VOht+j7H1y76rgooUtmtNKLuySTkf4nxK/FocuyCsDxP0r +jIZIgLEn1CD6R+ewbVZbFqwJt5RfJRpGss3Lmn3SdF4VEYQNHos6ytL0JzejC0Q7Foy5YC0cC0QC +fjpFZcbNXCJSnq6fX+KKq8MdHdivisU2Nd+5TCeqDdpuz2Plxs0o6wMlrYxIJKH+caxzvtlKdmRh +u1Ko/xz1A4VkljPJAudnrWXuvgfxVCacQ0DNJ/I8fA== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/workspace/file2.txt b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/workspace/file2.txt new file mode 100644 index 00000000..492987ca --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/workspace/file2.txt @@ -0,0 +1,18 @@ +DBVUxxDUlMoztjq4PiJSvgtwoY56pePoFur5Pz64DnE3tf2d7ffUtDBqluysfK62jpBzD9Ws6sTp +HZj7GIV1UQZloqbT2jPwyi5HGs1/aDfwTJA+ISur9mSEKLGEHADFqMsC9B5OW1P6hpzWiIjTGzde +VBOE5LfCy03VEsHfu90Ouk+PjEkxCz7rdIjjmxIDTp0GVmy73UwjvPT9Qwu70i2qSA1MDpCfAFmu +daTha8axoUcTnhNFlT2jVf4e/4cITNEsi/T/mMbpAtbXQXXLfflv7btJDTnY7L05AJetLmIXhZXB +OCwkA0d4gPMjG6p5Lkq3Vs3aeO8CVgSLeKEWz8Pru1pbSe0xDtt6EGZXK4axQ/gpZQfymEdqF4x5 +V3qqlVMDYcwIHkZiLdmxZOBX6J62yHtU7VdMD8zaT2Ds+fnqc4O0kRuUl+wZb+aQ1+ScZ17mxZ4B +6//1Ped29UUHuZQcJlOfrbtoXH4ZNO01OzZbQQ9YHlHLpOKQNqPXyBBH0bTz53ta5QX0ItMZ42eo +61fMjWm4baU4UmB1s9jlQGMYoVoo8URROfuZn7kirS9J5YLOpAuny+dBZsS8ezjwFput3Hh5JyYo +qIiC7oIVjHsHoYgAELxxFzLR3RreRxbKcoNxvdBu/4RngKzahXypIVPx0ldMiWIVnoEZlJtq5WE5 +S49N+ojExqOOWPPgXxcUP8dHkhfXoDgTph4M0ZFb4H6FJuwX/R7CqNHnqHbgYiCj1tZG4LBwVO/v +kamJudzm/SBvLlUycL9JrMgedLnUmVZorUgj4IVDju8lyHcz8RRBFHCBTh4LII+W+PBQ21LBCsH8 +2BZPOh8MLXFb8G7stl/n0rMkqC+tmRw2CAjwmbz/54nwuzm8o7k7cGXhou6blkx6tBlC54muSBWd +X7vNSctuY+JwwgLXk5JfeHIF2JdaCNaGyyBFgPer2rTG9PuoHD3QRibXOJSHy+NlCLrdrZXB89HQ +WNCpeBjWjlclG/O7LL2yuvrkvM5eohPjRBIHa4lxzEecL5Y+SPUOy7vIg0DChpL5CzpbYzgM15mS +Zd/ai7rkBzfdJMlmxTXNewMVaf4drtx9Cg9HJAWCjIjaX1lqOfku2vqKetfLQytz1qnNYo8oPcKE +PmaHbGkubdHI3+dDbqva3LWgrKjUNdVaQq+ICo57Pdo1FycScSyWW58Peldh0mIZodxVt8IiDiR3 +hjVJqGkRuxT0T07Dc2fXHKtylz8L2VdAQeeqqdaLvJnNVRU/CRzjdLLnWKUzC4f3CiFVeHW1MiRn +hWLsmy+tcEvZnFh29K1Ei55NFBcQjUvBQvmZgg+SiQ== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/workspace/filebad.txt b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/workspace/filebad.txt new file mode 100644 index 00000000..90505446 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn-dev/q16_workspaces/workspace/filebad.txt @@ -0,0 +1,18 @@ +a5HQSUh3ZVyvZxZvF2t+Pi3BLjHQ8MTJJ/2I7rqOQQ+mPC3AWAD5WHR5OZ+XwE6qfVjThv0rH1Lk +3N9phhpM+4Ij7g2KwPK6sb076LbD6PRVNpIVjEfEuzdi8pcZ4hDvYbPOSZ3FSpqvDGbFCBRSobSp +npEnw2DkyABjlvh5JKsv732jrZBBXHqgtBE7RgVeT+wlXo6nu8h1330fOYQ3y0F8UCWELtqfHseU +A3T/yB56wOG33k8jBvpAzAYmM+zr3xfFKhp36Ak2NvKH2oikeUi5wB1q8kaVVbHKCEoCYYW/mYnf +FFaAh2zMYOhVEeNUaee8RrSQvIXar2vgOim9W4vJxgKRUpjp09YFDw9lOgu4ddru60pR7QLNmCP5 +ht1jImO1p0TZ+A/Vwp6jKskDFqKy7ZZBTHYT99scrUWd7OEyyIbWF7OSIeq8wubAqcbAJ6NMUBRv +JqPxsbNNhkm/Xw4zvhQyhsI5P9QIjBpzL8SwxdhD5DdGfP8JGQLaLlvW8GlgBhteNY2k5lpSL2YJ +UsT4BT6fkeZnaWNfxJR69eAI98PeDiVW8KedvtE/wU4WlhmXi/bY7lenZi6sBSzqiXxaJujszLIG +c/bahugWAMXEBHGBduaYBOI6JGdFY2219qqKlY1aM2WUBTh/IF+Ig9PZDSMGW/Qo4HEo8HYge1sl +JkbcIL2zNhLpUJR8eCaZ06QI8KOa2LvtVLRBFRCdLXhdelD3uZDYWRVh+0ykASdCNURqayIxC3ys +Uwq95Qt5uB0teliY/xQ+JRvu6YnU+kStJGrEgaeS8ZjF85ogFCbNUnqvub1mvek/y23Z5SSYSKm/ +KcUpAIVfAg+W2YriERzUEsyzMjTKS1MP4mEeWUGgBIR4yGU2hivyd4P0eeIAti/zCTaKQBTRwXJX +4nar06DgLUj4HHdcd7aaLTxt4bHA646IXO+2qYxQAZxvKkgWfZ6QWFakXVROR/6lfqJDLD3QVFD0 +0d25EOhPbxe/Q7L8TR7rMsmE7cpJvA/Mjv36g6f2l0PngzPlm/EiJ0i0wn/3Al4A5+AEfxDwRMFo +rNkaJEyEkRBDo5UeVdnTVXH1z70RLSju0n4oJe3NS47nv+gP5brMCkPxEh0pY1vtSFskaLHqJZwV +NWFSdij8THFL0dlfKG5wyPwtwCuQqCz029wRjfJNFEgfqWOGGXZLLC+7n4wdSr2QO+ppZdKqB/Bl +t6i2u5iwH+XrYf4j9THtXCQ6w/FEere2q8EBkCaTSOhKC+Gyp1rAnyuuYIy/dxprJKI4EzhgVHYo +171ZFv6aNT1ETGgB8ejaU9025ozLjRHvcbuHIZsm3g== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/info.json b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/info.json new file mode 100644 index 00000000..b2bc7872 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/info.json @@ -0,0 +1,24 @@ +{ + "uuid": "fad3fc60-3738-3899-8c8d-04a0bf0a5c70", + "title": "Moving and copying files", + "topic": "000.Template", + "tags": [ + "workspace" + ], + "type": "v3", + "singleVariant": false, + "partialCredit": true, + "workspaceOptions": { + "image": "prairielearn/workspace-xtermjs", + "port": 8080, + "home": "/home/student", + "gradedFiles": [ + "file1.txt", + "file2.txt", + "filebad.txt", + "newdir/file1_new.txt", + "newdir/file2_new.txt" + ] + }, + "showCorrectAnswer": false +} \ No newline at end of file diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/question.html b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/question.html new file mode 100644 index 00000000..83e23818 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/question.html @@ -0,0 +1,38 @@ + + + + +Open the Workspace below and perform the following tasks. + +- Create a new directory called `newdir`; +- Move the file `file1.txt` to the directory `newdir`, with the new name `file1_new.txt`; +- Copy the file `file2.txt` to the directory `newdir`, with the new name `file2_new.txt`; +- Delete the file `filebad.txt`. + +Once you complete these tasks, click on "Save & Grade" below. + + + + + + + + + +Everything here will get inserted directly into an pl-answer-panel element at the end of the `question.html`. +Please remove this section if it is not application for this question. + + + + + + +--- +Problem is licensed under the [CC-BY-NC-SA 4.0 license](https://creativecommons.org/licenses/by-nc-sa/4.0/).
![The Creative Commons 4.0 license requiring attribution-BY, non-commercial-NC, and share-alike-SA license.](https://raw.githubusercontent.com/firasm/bits/master/by-nc-sa.png) +
+
diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/server.py b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/server.py new file mode 100644 index 00000000..1e664476 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/server.py @@ -0,0 +1,70 @@ +import base64 +import problem_bank_helpers as pbh + +def imports(data): + import base64 + import problem_bank_helpers as pbh + +def generate(data): + data2 = pbh.create_data2() + + data2["params"]["vars"]["title"] = "Moving and copying files" + + # Update the data object with a new dict + data.update(data2) + + # Start code added automatically by problem_bank_scripts + + # Convert backticks to code blocks/fences in answer choices. + pbh.backticks_to_code_tags(data2) + + # Update data with data2 + data.update(data2) + + # End code added in by problem bank scripts + +def grade(data): + files = { f['name']: f['contents'] for f in data['submitted_answers'].get('_files', []) } + data['feedback']['results'] = [] + data['score'] = 0 + + with open('workspace/file1.txt', 'rb') as f: + file1_content = base64.b64encode(f.read()).decode() + with open('workspace/file2.txt', 'rb') as f: + file2_content = base64.b64encode(f.read()).decode() + + if 'newdir/file1_new.txt' not in files: + data['feedback']['results'].append('newdir/file1_new.txt was not created.') + elif files['newdir/file1_new.txt'] != file1_content: + data['feedback']['results'].append('newdir/file1_new.txt was created, but it is not based on file1.txt.') + elif 'file1.txt' in files: + data['feedback']['results'].append('newdir/file1_new.txt was created properly, but the old file still exists.') + data['score'] += 0.2 + else: + data['feedback']['results'].append('file1.txt moved successfully.') + data['score'] += 0.4 + + if 'newdir/file2_new.txt' not in files: + data['feedback']['results'].append('newdir/file2_new.txt was not created.') + elif files['newdir/file2_new.txt'] != file2_content: + data['feedback']['results'].append('newdir/file2_new.txt was created, but it is not based on file2.txt.') + elif 'file2.txt' not in files: + data['feedback']['results'].append('newdir/file2_new.txt was created properly, but the old file no longer exists.') + data['score'] += 0.2 + else: + data['feedback']['results'].append('file2.txt copied successfully.') + data['score'] += 0.4 + + if files and 'filebad.txt' in files: + data['feedback']['results'].append('filebad.txt still exists.') + else: + data['feedback']['results'].append('filebad.txt deleted successfully.') + data['score'] += 0.2 + +def prepare(data): + pass + +def parse(data): + if '_files' in data['format_errors']: + del data['format_errors']['_files'] + diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/serverFilesQuestion/file1.txt b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/serverFilesQuestion/file1.txt new file mode 100644 index 00000000..b30565ee --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/serverFilesQuestion/file1.txt @@ -0,0 +1,18 @@ +Gk44G5S2cov8PgPpy9n7r0v4FYY7zU/7i8UNDrRYLU1GjpVdCPIzdbUUcln3CqNlBTEKjn75+3qs +DUvteohtwFF+4BYwAyfv7yjzX9CPsyfHjBYC+b+fMHPMFns1vdlGUvwDEePE4k1EnJECUZKTkebJ +ymKhR6BY4IUnO5cVsRARExtVkYddHUcNAhgLpN9E/SNln9gJ9fN4WRat6l2QSDaH2OJ96+lDM/yR +EVttiFtCynzgguVYQy06tlpLXk9a9MwPlVGJvH/qH28pHkIac2H6UpWnDcBptsVJTVfTVv9Gp9/s +IQmeZRDIUy6163Ga9Uke6o1W7dVeohjvwY/KQHApZcK15RDkb+UiBd/9VM26N7eMoW41Sg7SKtQZ ++i8vEu2H6whEnvZCnYg+sOh9fxaDlOQhh7qhu4g2z1TORCjWzgELzZEmPJVrsf45cG0tz0xKoF/d +Uw/YoHF8RJexASnLZWj4125sNCQ6XfoEl1DLzUULxH7SeWM9owpouV5RZC3LZmCgyDUvbI0oMk+l +9GTae6lcMLOKD1R2q4NksQAt/osyWXQZw1g6pcqNSz1TdirbiQsTY6g+JZ3pYN2tK2w4WqVnLPix +lI9ktBec6XknnEEvrI7NhPLEXdxS7mUXuapCV6EfMfDPMvW523EUQPE5MWYBvHTmlIW5pemWgsAd +vuCFOIjs73L0es+88D3gCrSGSyk7KydSY3f2XCD8PLf78ZamVWi9yRpQryc33bRB2CaGhHhmbKto +4nsb+ToaG0aZE2FtIjOHTyC8jjsqgLRbHfRXJVFnngKVT+DEQnrfLRuC8+PtMrDDpZ4VarpK0aLd +BMtHPOsg+cOhwhqU021s2nq6G6XKfSDHeRR/2T/R0loeMr8/6UCVQKXitWl2f//tfnBYYMQObys3 +tYsJC46pR+Gp9ytUxc+//NKKmhn1J4Sm8anhGeePEmxroVbm5O16jk62u+L2jNJ0HOGYXNKizuKP +aVSReke4ZqdxJCCLZjLS6q4B5v5s7XK2TRFUb7BUeOVvezG698khGjCdPDOZH1gYxRoKR5VrkM1z +Mr8VPMi6io9GhaGehNz+N5ygXp6IG9VOht+j7H1y76rgooUtmtNKLuySTkf4nxK/FocuyCsDxP0r +jIZIgLEn1CD6R+ewbVZbFqwJt5RfJRpGss3Lmn3SdF4VEYQNHos6ytL0JzejC0Q7Foy5YC0cC0QC +fjpFZcbNXCJSnq6fX+KKq8MdHdivisU2Nd+5TCeqDdpuz2Plxs0o6wMlrYxIJKH+caxzvtlKdmRh +u1Ko/xz1A4VkljPJAudnrWXuvgfxVCacQ0DNJ/I8fA== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/serverFilesQuestion/file2.txt b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/serverFilesQuestion/file2.txt new file mode 100644 index 00000000..492987ca --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/serverFilesQuestion/file2.txt @@ -0,0 +1,18 @@ +DBVUxxDUlMoztjq4PiJSvgtwoY56pePoFur5Pz64DnE3tf2d7ffUtDBqluysfK62jpBzD9Ws6sTp +HZj7GIV1UQZloqbT2jPwyi5HGs1/aDfwTJA+ISur9mSEKLGEHADFqMsC9B5OW1P6hpzWiIjTGzde +VBOE5LfCy03VEsHfu90Ouk+PjEkxCz7rdIjjmxIDTp0GVmy73UwjvPT9Qwu70i2qSA1MDpCfAFmu +daTha8axoUcTnhNFlT2jVf4e/4cITNEsi/T/mMbpAtbXQXXLfflv7btJDTnY7L05AJetLmIXhZXB +OCwkA0d4gPMjG6p5Lkq3Vs3aeO8CVgSLeKEWz8Pru1pbSe0xDtt6EGZXK4axQ/gpZQfymEdqF4x5 +V3qqlVMDYcwIHkZiLdmxZOBX6J62yHtU7VdMD8zaT2Ds+fnqc4O0kRuUl+wZb+aQ1+ScZ17mxZ4B +6//1Ped29UUHuZQcJlOfrbtoXH4ZNO01OzZbQQ9YHlHLpOKQNqPXyBBH0bTz53ta5QX0ItMZ42eo +61fMjWm4baU4UmB1s9jlQGMYoVoo8URROfuZn7kirS9J5YLOpAuny+dBZsS8ezjwFput3Hh5JyYo +qIiC7oIVjHsHoYgAELxxFzLR3RreRxbKcoNxvdBu/4RngKzahXypIVPx0ldMiWIVnoEZlJtq5WE5 +S49N+ojExqOOWPPgXxcUP8dHkhfXoDgTph4M0ZFb4H6FJuwX/R7CqNHnqHbgYiCj1tZG4LBwVO/v +kamJudzm/SBvLlUycL9JrMgedLnUmVZorUgj4IVDju8lyHcz8RRBFHCBTh4LII+W+PBQ21LBCsH8 +2BZPOh8MLXFb8G7stl/n0rMkqC+tmRw2CAjwmbz/54nwuzm8o7k7cGXhou6blkx6tBlC54muSBWd +X7vNSctuY+JwwgLXk5JfeHIF2JdaCNaGyyBFgPer2rTG9PuoHD3QRibXOJSHy+NlCLrdrZXB89HQ +WNCpeBjWjlclG/O7LL2yuvrkvM5eohPjRBIHa4lxzEecL5Y+SPUOy7vIg0DChpL5CzpbYzgM15mS +Zd/ai7rkBzfdJMlmxTXNewMVaf4drtx9Cg9HJAWCjIjaX1lqOfku2vqKetfLQytz1qnNYo8oPcKE +PmaHbGkubdHI3+dDbqva3LWgrKjUNdVaQq+ICo57Pdo1FycScSyWW58Peldh0mIZodxVt8IiDiR3 +hjVJqGkRuxT0T07Dc2fXHKtylz8L2VdAQeeqqdaLvJnNVRU/CRzjdLLnWKUzC4f3CiFVeHW1MiRn +hWLsmy+tcEvZnFh29K1Ei55NFBcQjUvBQvmZgg+SiQ== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/serverFilesQuestion/filebad.txt b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/serverFilesQuestion/filebad.txt new file mode 100644 index 00000000..90505446 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/serverFilesQuestion/filebad.txt @@ -0,0 +1,18 @@ +a5HQSUh3ZVyvZxZvF2t+Pi3BLjHQ8MTJJ/2I7rqOQQ+mPC3AWAD5WHR5OZ+XwE6qfVjThv0rH1Lk +3N9phhpM+4Ij7g2KwPK6sb076LbD6PRVNpIVjEfEuzdi8pcZ4hDvYbPOSZ3FSpqvDGbFCBRSobSp +npEnw2DkyABjlvh5JKsv732jrZBBXHqgtBE7RgVeT+wlXo6nu8h1330fOYQ3y0F8UCWELtqfHseU +A3T/yB56wOG33k8jBvpAzAYmM+zr3xfFKhp36Ak2NvKH2oikeUi5wB1q8kaVVbHKCEoCYYW/mYnf +FFaAh2zMYOhVEeNUaee8RrSQvIXar2vgOim9W4vJxgKRUpjp09YFDw9lOgu4ddru60pR7QLNmCP5 +ht1jImO1p0TZ+A/Vwp6jKskDFqKy7ZZBTHYT99scrUWd7OEyyIbWF7OSIeq8wubAqcbAJ6NMUBRv +JqPxsbNNhkm/Xw4zvhQyhsI5P9QIjBpzL8SwxdhD5DdGfP8JGQLaLlvW8GlgBhteNY2k5lpSL2YJ +UsT4BT6fkeZnaWNfxJR69eAI98PeDiVW8KedvtE/wU4WlhmXi/bY7lenZi6sBSzqiXxaJujszLIG +c/bahugWAMXEBHGBduaYBOI6JGdFY2219qqKlY1aM2WUBTh/IF+Ig9PZDSMGW/Qo4HEo8HYge1sl +JkbcIL2zNhLpUJR8eCaZ06QI8KOa2LvtVLRBFRCdLXhdelD3uZDYWRVh+0ykASdCNURqayIxC3ys +Uwq95Qt5uB0teliY/xQ+JRvu6YnU+kStJGrEgaeS8ZjF85ogFCbNUnqvub1mvek/y23Z5SSYSKm/ +KcUpAIVfAg+W2YriERzUEsyzMjTKS1MP4mEeWUGgBIR4yGU2hivyd4P0eeIAti/zCTaKQBTRwXJX +4nar06DgLUj4HHdcd7aaLTxt4bHA646IXO+2qYxQAZxvKkgWfZ6QWFakXVROR/6lfqJDLD3QVFD0 +0d25EOhPbxe/Q7L8TR7rMsmE7cpJvA/Mjv36g6f2l0PngzPlm/EiJ0i0wn/3Al4A5+AEfxDwRMFo +rNkaJEyEkRBDo5UeVdnTVXH1z70RLSju0n4oJe3NS47nv+gP5brMCkPxEh0pY1vtSFskaLHqJZwV +NWFSdij8THFL0dlfKG5wyPwtwCuQqCz029wRjfJNFEgfqWOGGXZLLC+7n4wdSr2QO+ppZdKqB/Bl +t6i2u5iwH+XrYf4j9THtXCQ6w/FEere2q8EBkCaTSOhKC+Gyp1rAnyuuYIy/dxprJKI4EzhgVHYo +171ZFv6aNT1ETGgB8ejaU9025ozLjRHvcbuHIZsm3g== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/workspace/file1.txt b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/workspace/file1.txt new file mode 100644 index 00000000..b30565ee --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/workspace/file1.txt @@ -0,0 +1,18 @@ +Gk44G5S2cov8PgPpy9n7r0v4FYY7zU/7i8UNDrRYLU1GjpVdCPIzdbUUcln3CqNlBTEKjn75+3qs +DUvteohtwFF+4BYwAyfv7yjzX9CPsyfHjBYC+b+fMHPMFns1vdlGUvwDEePE4k1EnJECUZKTkebJ +ymKhR6BY4IUnO5cVsRARExtVkYddHUcNAhgLpN9E/SNln9gJ9fN4WRat6l2QSDaH2OJ96+lDM/yR +EVttiFtCynzgguVYQy06tlpLXk9a9MwPlVGJvH/qH28pHkIac2H6UpWnDcBptsVJTVfTVv9Gp9/s +IQmeZRDIUy6163Ga9Uke6o1W7dVeohjvwY/KQHApZcK15RDkb+UiBd/9VM26N7eMoW41Sg7SKtQZ ++i8vEu2H6whEnvZCnYg+sOh9fxaDlOQhh7qhu4g2z1TORCjWzgELzZEmPJVrsf45cG0tz0xKoF/d +Uw/YoHF8RJexASnLZWj4125sNCQ6XfoEl1DLzUULxH7SeWM9owpouV5RZC3LZmCgyDUvbI0oMk+l +9GTae6lcMLOKD1R2q4NksQAt/osyWXQZw1g6pcqNSz1TdirbiQsTY6g+JZ3pYN2tK2w4WqVnLPix +lI9ktBec6XknnEEvrI7NhPLEXdxS7mUXuapCV6EfMfDPMvW523EUQPE5MWYBvHTmlIW5pemWgsAd +vuCFOIjs73L0es+88D3gCrSGSyk7KydSY3f2XCD8PLf78ZamVWi9yRpQryc33bRB2CaGhHhmbKto +4nsb+ToaG0aZE2FtIjOHTyC8jjsqgLRbHfRXJVFnngKVT+DEQnrfLRuC8+PtMrDDpZ4VarpK0aLd +BMtHPOsg+cOhwhqU021s2nq6G6XKfSDHeRR/2T/R0loeMr8/6UCVQKXitWl2f//tfnBYYMQObys3 +tYsJC46pR+Gp9ytUxc+//NKKmhn1J4Sm8anhGeePEmxroVbm5O16jk62u+L2jNJ0HOGYXNKizuKP +aVSReke4ZqdxJCCLZjLS6q4B5v5s7XK2TRFUb7BUeOVvezG698khGjCdPDOZH1gYxRoKR5VrkM1z +Mr8VPMi6io9GhaGehNz+N5ygXp6IG9VOht+j7H1y76rgooUtmtNKLuySTkf4nxK/FocuyCsDxP0r +jIZIgLEn1CD6R+ewbVZbFqwJt5RfJRpGss3Lmn3SdF4VEYQNHos6ytL0JzejC0Q7Foy5YC0cC0QC +fjpFZcbNXCJSnq6fX+KKq8MdHdivisU2Nd+5TCeqDdpuz2Plxs0o6wMlrYxIJKH+caxzvtlKdmRh +u1Ko/xz1A4VkljPJAudnrWXuvgfxVCacQ0DNJ/I8fA== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/workspace/file2.txt b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/workspace/file2.txt new file mode 100644 index 00000000..492987ca --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/workspace/file2.txt @@ -0,0 +1,18 @@ +DBVUxxDUlMoztjq4PiJSvgtwoY56pePoFur5Pz64DnE3tf2d7ffUtDBqluysfK62jpBzD9Ws6sTp +HZj7GIV1UQZloqbT2jPwyi5HGs1/aDfwTJA+ISur9mSEKLGEHADFqMsC9B5OW1P6hpzWiIjTGzde +VBOE5LfCy03VEsHfu90Ouk+PjEkxCz7rdIjjmxIDTp0GVmy73UwjvPT9Qwu70i2qSA1MDpCfAFmu +daTha8axoUcTnhNFlT2jVf4e/4cITNEsi/T/mMbpAtbXQXXLfflv7btJDTnY7L05AJetLmIXhZXB +OCwkA0d4gPMjG6p5Lkq3Vs3aeO8CVgSLeKEWz8Pru1pbSe0xDtt6EGZXK4axQ/gpZQfymEdqF4x5 +V3qqlVMDYcwIHkZiLdmxZOBX6J62yHtU7VdMD8zaT2Ds+fnqc4O0kRuUl+wZb+aQ1+ScZ17mxZ4B +6//1Ped29UUHuZQcJlOfrbtoXH4ZNO01OzZbQQ9YHlHLpOKQNqPXyBBH0bTz53ta5QX0ItMZ42eo +61fMjWm4baU4UmB1s9jlQGMYoVoo8URROfuZn7kirS9J5YLOpAuny+dBZsS8ezjwFput3Hh5JyYo +qIiC7oIVjHsHoYgAELxxFzLR3RreRxbKcoNxvdBu/4RngKzahXypIVPx0ldMiWIVnoEZlJtq5WE5 +S49N+ojExqOOWPPgXxcUP8dHkhfXoDgTph4M0ZFb4H6FJuwX/R7CqNHnqHbgYiCj1tZG4LBwVO/v +kamJudzm/SBvLlUycL9JrMgedLnUmVZorUgj4IVDju8lyHcz8RRBFHCBTh4LII+W+PBQ21LBCsH8 +2BZPOh8MLXFb8G7stl/n0rMkqC+tmRw2CAjwmbz/54nwuzm8o7k7cGXhou6blkx6tBlC54muSBWd +X7vNSctuY+JwwgLXk5JfeHIF2JdaCNaGyyBFgPer2rTG9PuoHD3QRibXOJSHy+NlCLrdrZXB89HQ +WNCpeBjWjlclG/O7LL2yuvrkvM5eohPjRBIHa4lxzEecL5Y+SPUOy7vIg0DChpL5CzpbYzgM15mS +Zd/ai7rkBzfdJMlmxTXNewMVaf4drtx9Cg9HJAWCjIjaX1lqOfku2vqKetfLQytz1qnNYo8oPcKE +PmaHbGkubdHI3+dDbqva3LWgrKjUNdVaQq+ICo57Pdo1FycScSyWW58Peldh0mIZodxVt8IiDiR3 +hjVJqGkRuxT0T07Dc2fXHKtylz8L2VdAQeeqqdaLvJnNVRU/CRzjdLLnWKUzC4f3CiFVeHW1MiRn +hWLsmy+tcEvZnFh29K1Ei55NFBcQjUvBQvmZgg+SiQ== diff --git a/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/workspace/filebad.txt b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/workspace/filebad.txt new file mode 100644 index 00000000..90505446 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/prairielearn/q16_workspaces/workspace/filebad.txt @@ -0,0 +1,18 @@ +a5HQSUh3ZVyvZxZvF2t+Pi3BLjHQ8MTJJ/2I7rqOQQ+mPC3AWAD5WHR5OZ+XwE6qfVjThv0rH1Lk +3N9phhpM+4Ij7g2KwPK6sb076LbD6PRVNpIVjEfEuzdi8pcZ4hDvYbPOSZ3FSpqvDGbFCBRSobSp +npEnw2DkyABjlvh5JKsv732jrZBBXHqgtBE7RgVeT+wlXo6nu8h1330fOYQ3y0F8UCWELtqfHseU +A3T/yB56wOG33k8jBvpAzAYmM+zr3xfFKhp36Ak2NvKH2oikeUi5wB1q8kaVVbHKCEoCYYW/mYnf +FFaAh2zMYOhVEeNUaee8RrSQvIXar2vgOim9W4vJxgKRUpjp09YFDw9lOgu4ddru60pR7QLNmCP5 +ht1jImO1p0TZ+A/Vwp6jKskDFqKy7ZZBTHYT99scrUWd7OEyyIbWF7OSIeq8wubAqcbAJ6NMUBRv +JqPxsbNNhkm/Xw4zvhQyhsI5P9QIjBpzL8SwxdhD5DdGfP8JGQLaLlvW8GlgBhteNY2k5lpSL2YJ +UsT4BT6fkeZnaWNfxJR69eAI98PeDiVW8KedvtE/wU4WlhmXi/bY7lenZi6sBSzqiXxaJujszLIG +c/bahugWAMXEBHGBduaYBOI6JGdFY2219qqKlY1aM2WUBTh/IF+Ig9PZDSMGW/Qo4HEo8HYge1sl +JkbcIL2zNhLpUJR8eCaZ06QI8KOa2LvtVLRBFRCdLXhdelD3uZDYWRVh+0ykASdCNURqayIxC3ys +Uwq95Qt5uB0teliY/xQ+JRvu6YnU+kStJGrEgaeS8ZjF85ogFCbNUnqvub1mvek/y23Z5SSYSKm/ +KcUpAIVfAg+W2YriERzUEsyzMjTKS1MP4mEeWUGgBIR4yGU2hivyd4P0eeIAti/zCTaKQBTRwXJX +4nar06DgLUj4HHdcd7aaLTxt4bHA646IXO+2qYxQAZxvKkgWfZ6QWFakXVROR/6lfqJDLD3QVFD0 +0d25EOhPbxe/Q7L8TR7rMsmE7cpJvA/Mjv36g6f2l0PngzPlm/EiJ0i0wn/3Al4A5+AEfxDwRMFo +rNkaJEyEkRBDo5UeVdnTVXH1z70RLSju0n4oJe3NS47nv+gP5brMCkPxEh0pY1vtSFskaLHqJZwV +NWFSdij8THFL0dlfKG5wyPwtwCuQqCz029wRjfJNFEgfqWOGGXZLLC+7n4wdSr2QO+ppZdKqB/Bl +t6i2u5iwH+XrYf4j9THtXCQ6w/FEere2q8EBkCaTSOhKC+Gyp1rAnyuuYIy/dxprJKI4EzhgVHYo +171ZFv6aNT1ETGgB8ejaU9025ozLjRHvcbuHIZsm3g== diff --git a/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/q16_workspaces.md b/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/q16_workspaces.md new file mode 100644 index 00000000..8d63d498 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/q16_workspaces.md @@ -0,0 +1,84 @@ +--- +title: Moving and copying files +topic: Template +author: Jonatan Schroeder; Converted by Gavin Kendal-Freedman +source: original +template_version: 1.0 +attribution: standard +partialCredit: true +singleVariant: false +showCorrectAnswer: false +outcomes: +- 6.1.1.0 +- 6.1.1.1 +difficulty: +- undefined +randomization: +- undefined +taxonomy: +- undefined +span: +- undefined +length: +- undefined +tags: +- unknown +assets: null +workspaceFiles: +- file1.txt +- file2.txt +- filebad.txt +serverFiles: +- file1.txt +- file2.txt +- filebad.txt +workspaceOptions: + image: prairielearn/workspace-xtermjs + port: 8080 + home: /home/student + gradedFiles: + - file1.txt + - file2.txt + - filebad.txt + - newdir/file1_new.txt + - newdir/file2_new.txt +part1: + type: workspace +myst: + substitutions: + params_vars_title: Moving and copying files +--- +# {{ params_vars_title }} + +## Question Text + +Open the Workspace below and perform the following tasks. + +- Create a new directory called `newdir`; +- Move the file `file1.txt` to the directory `newdir`, with the new name `file1_new.txt`; +- Copy the file `file2.txt` to the directory `newdir`, with the new name `file2_new.txt`; +- Delete the file `filebad.txt`. + +Once you complete these tasks, click on "Save & Grade" below. + +### Answer Section + +### pl-submission-panel + + + + + +### pl-answer-panel + +Everything here will get inserted directly into an pl-answer-panel element at the end of the `question.html`. +Please remove this section if it is not application for this question. + +## Attribution + +Problem is licensed under the [CC-BY-NC-SA 4.0 license](https://creativecommons.org/licenses/by-nc-sa/4.0/).
![The Creative Commons 4.0 license requiring attribution-BY, non-commercial-NC, and share-alike-SA license.](https://raw.githubusercontent.com/firasm/bits/master/by-nc-sa.png) \ No newline at end of file diff --git a/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/workspace/file1.txt b/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/workspace/file1.txt new file mode 100644 index 00000000..b30565ee --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/workspace/file1.txt @@ -0,0 +1,18 @@ +Gk44G5S2cov8PgPpy9n7r0v4FYY7zU/7i8UNDrRYLU1GjpVdCPIzdbUUcln3CqNlBTEKjn75+3qs +DUvteohtwFF+4BYwAyfv7yjzX9CPsyfHjBYC+b+fMHPMFns1vdlGUvwDEePE4k1EnJECUZKTkebJ +ymKhR6BY4IUnO5cVsRARExtVkYddHUcNAhgLpN9E/SNln9gJ9fN4WRat6l2QSDaH2OJ96+lDM/yR +EVttiFtCynzgguVYQy06tlpLXk9a9MwPlVGJvH/qH28pHkIac2H6UpWnDcBptsVJTVfTVv9Gp9/s +IQmeZRDIUy6163Ga9Uke6o1W7dVeohjvwY/KQHApZcK15RDkb+UiBd/9VM26N7eMoW41Sg7SKtQZ ++i8vEu2H6whEnvZCnYg+sOh9fxaDlOQhh7qhu4g2z1TORCjWzgELzZEmPJVrsf45cG0tz0xKoF/d +Uw/YoHF8RJexASnLZWj4125sNCQ6XfoEl1DLzUULxH7SeWM9owpouV5RZC3LZmCgyDUvbI0oMk+l +9GTae6lcMLOKD1R2q4NksQAt/osyWXQZw1g6pcqNSz1TdirbiQsTY6g+JZ3pYN2tK2w4WqVnLPix +lI9ktBec6XknnEEvrI7NhPLEXdxS7mUXuapCV6EfMfDPMvW523EUQPE5MWYBvHTmlIW5pemWgsAd +vuCFOIjs73L0es+88D3gCrSGSyk7KydSY3f2XCD8PLf78ZamVWi9yRpQryc33bRB2CaGhHhmbKto +4nsb+ToaG0aZE2FtIjOHTyC8jjsqgLRbHfRXJVFnngKVT+DEQnrfLRuC8+PtMrDDpZ4VarpK0aLd +BMtHPOsg+cOhwhqU021s2nq6G6XKfSDHeRR/2T/R0loeMr8/6UCVQKXitWl2f//tfnBYYMQObys3 +tYsJC46pR+Gp9ytUxc+//NKKmhn1J4Sm8anhGeePEmxroVbm5O16jk62u+L2jNJ0HOGYXNKizuKP +aVSReke4ZqdxJCCLZjLS6q4B5v5s7XK2TRFUb7BUeOVvezG698khGjCdPDOZH1gYxRoKR5VrkM1z +Mr8VPMi6io9GhaGehNz+N5ygXp6IG9VOht+j7H1y76rgooUtmtNKLuySTkf4nxK/FocuyCsDxP0r +jIZIgLEn1CD6R+ewbVZbFqwJt5RfJRpGss3Lmn3SdF4VEYQNHos6ytL0JzejC0Q7Foy5YC0cC0QC +fjpFZcbNXCJSnq6fX+KKq8MdHdivisU2Nd+5TCeqDdpuz2Plxs0o6wMlrYxIJKH+caxzvtlKdmRh +u1Ko/xz1A4VkljPJAudnrWXuvgfxVCacQ0DNJ/I8fA== diff --git a/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/workspace/file2.txt b/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/workspace/file2.txt new file mode 100644 index 00000000..492987ca --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/workspace/file2.txt @@ -0,0 +1,18 @@ +DBVUxxDUlMoztjq4PiJSvgtwoY56pePoFur5Pz64DnE3tf2d7ffUtDBqluysfK62jpBzD9Ws6sTp +HZj7GIV1UQZloqbT2jPwyi5HGs1/aDfwTJA+ISur9mSEKLGEHADFqMsC9B5OW1P6hpzWiIjTGzde +VBOE5LfCy03VEsHfu90Ouk+PjEkxCz7rdIjjmxIDTp0GVmy73UwjvPT9Qwu70i2qSA1MDpCfAFmu +daTha8axoUcTnhNFlT2jVf4e/4cITNEsi/T/mMbpAtbXQXXLfflv7btJDTnY7L05AJetLmIXhZXB +OCwkA0d4gPMjG6p5Lkq3Vs3aeO8CVgSLeKEWz8Pru1pbSe0xDtt6EGZXK4axQ/gpZQfymEdqF4x5 +V3qqlVMDYcwIHkZiLdmxZOBX6J62yHtU7VdMD8zaT2Ds+fnqc4O0kRuUl+wZb+aQ1+ScZ17mxZ4B +6//1Ped29UUHuZQcJlOfrbtoXH4ZNO01OzZbQQ9YHlHLpOKQNqPXyBBH0bTz53ta5QX0ItMZ42eo +61fMjWm4baU4UmB1s9jlQGMYoVoo8URROfuZn7kirS9J5YLOpAuny+dBZsS8ezjwFput3Hh5JyYo +qIiC7oIVjHsHoYgAELxxFzLR3RreRxbKcoNxvdBu/4RngKzahXypIVPx0ldMiWIVnoEZlJtq5WE5 +S49N+ojExqOOWPPgXxcUP8dHkhfXoDgTph4M0ZFb4H6FJuwX/R7CqNHnqHbgYiCj1tZG4LBwVO/v +kamJudzm/SBvLlUycL9JrMgedLnUmVZorUgj4IVDju8lyHcz8RRBFHCBTh4LII+W+PBQ21LBCsH8 +2BZPOh8MLXFb8G7stl/n0rMkqC+tmRw2CAjwmbz/54nwuzm8o7k7cGXhou6blkx6tBlC54muSBWd +X7vNSctuY+JwwgLXk5JfeHIF2JdaCNaGyyBFgPer2rTG9PuoHD3QRibXOJSHy+NlCLrdrZXB89HQ +WNCpeBjWjlclG/O7LL2yuvrkvM5eohPjRBIHa4lxzEecL5Y+SPUOy7vIg0DChpL5CzpbYzgM15mS +Zd/ai7rkBzfdJMlmxTXNewMVaf4drtx9Cg9HJAWCjIjaX1lqOfku2vqKetfLQytz1qnNYo8oPcKE +PmaHbGkubdHI3+dDbqva3LWgrKjUNdVaQq+ICo57Pdo1FycScSyWW58Peldh0mIZodxVt8IiDiR3 +hjVJqGkRuxT0T07Dc2fXHKtylz8L2VdAQeeqqdaLvJnNVRU/CRzjdLLnWKUzC4f3CiFVeHW1MiRn +hWLsmy+tcEvZnFh29K1Ei55NFBcQjUvBQvmZgg+SiQ== diff --git a/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/workspace/filebad.txt b/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/workspace/filebad.txt new file mode 100644 index 00000000..90505446 --- /dev/null +++ b/tests/test_question_templates/question_expected_outputs/public/q16_workspaces/workspace/filebad.txt @@ -0,0 +1,18 @@ +a5HQSUh3ZVyvZxZvF2t+Pi3BLjHQ8MTJJ/2I7rqOQQ+mPC3AWAD5WHR5OZ+XwE6qfVjThv0rH1Lk +3N9phhpM+4Ij7g2KwPK6sb076LbD6PRVNpIVjEfEuzdi8pcZ4hDvYbPOSZ3FSpqvDGbFCBRSobSp +npEnw2DkyABjlvh5JKsv732jrZBBXHqgtBE7RgVeT+wlXo6nu8h1330fOYQ3y0F8UCWELtqfHseU +A3T/yB56wOG33k8jBvpAzAYmM+zr3xfFKhp36Ak2NvKH2oikeUi5wB1q8kaVVbHKCEoCYYW/mYnf +FFaAh2zMYOhVEeNUaee8RrSQvIXar2vgOim9W4vJxgKRUpjp09YFDw9lOgu4ddru60pR7QLNmCP5 +ht1jImO1p0TZ+A/Vwp6jKskDFqKy7ZZBTHYT99scrUWd7OEyyIbWF7OSIeq8wubAqcbAJ6NMUBRv +JqPxsbNNhkm/Xw4zvhQyhsI5P9QIjBpzL8SwxdhD5DdGfP8JGQLaLlvW8GlgBhteNY2k5lpSL2YJ +UsT4BT6fkeZnaWNfxJR69eAI98PeDiVW8KedvtE/wU4WlhmXi/bY7lenZi6sBSzqiXxaJujszLIG +c/bahugWAMXEBHGBduaYBOI6JGdFY2219qqKlY1aM2WUBTh/IF+Ig9PZDSMGW/Qo4HEo8HYge1sl +JkbcIL2zNhLpUJR8eCaZ06QI8KOa2LvtVLRBFRCdLXhdelD3uZDYWRVh+0ykASdCNURqayIxC3ys +Uwq95Qt5uB0teliY/xQ+JRvu6YnU+kStJGrEgaeS8ZjF85ogFCbNUnqvub1mvek/y23Z5SSYSKm/ +KcUpAIVfAg+W2YriERzUEsyzMjTKS1MP4mEeWUGgBIR4yGU2hivyd4P0eeIAti/zCTaKQBTRwXJX +4nar06DgLUj4HHdcd7aaLTxt4bHA646IXO+2qYxQAZxvKkgWfZ6QWFakXVROR/6lfqJDLD3QVFD0 +0d25EOhPbxe/Q7L8TR7rMsmE7cpJvA/Mjv36g6f2l0PngzPlm/EiJ0i0wn/3Al4A5+AEfxDwRMFo +rNkaJEyEkRBDo5UeVdnTVXH1z70RLSju0n4oJe3NS47nv+gP5brMCkPxEh0pY1vtSFskaLHqJZwV +NWFSdij8THFL0dlfKG5wyPwtwCuQqCz029wRjfJNFEgfqWOGGXZLLC+7n4wdSr2QO+ppZdKqB/Bl +t6i2u5iwH+XrYf4j9THtXCQ6w/FEere2q8EBkCaTSOhKC+Gyp1rAnyuuYIy/dxprJKI4EzhgVHYo +171ZFv6aNT1ETGgB8ejaU9025ozLjRHvcbuHIZsm3g== diff --git a/tests/test_question_templates/question_inputs/q16_workspaces/file1.txt b/tests/test_question_templates/question_inputs/q16_workspaces/file1.txt new file mode 100644 index 00000000..b30565ee --- /dev/null +++ b/tests/test_question_templates/question_inputs/q16_workspaces/file1.txt @@ -0,0 +1,18 @@ +Gk44G5S2cov8PgPpy9n7r0v4FYY7zU/7i8UNDrRYLU1GjpVdCPIzdbUUcln3CqNlBTEKjn75+3qs +DUvteohtwFF+4BYwAyfv7yjzX9CPsyfHjBYC+b+fMHPMFns1vdlGUvwDEePE4k1EnJECUZKTkebJ +ymKhR6BY4IUnO5cVsRARExtVkYddHUcNAhgLpN9E/SNln9gJ9fN4WRat6l2QSDaH2OJ96+lDM/yR +EVttiFtCynzgguVYQy06tlpLXk9a9MwPlVGJvH/qH28pHkIac2H6UpWnDcBptsVJTVfTVv9Gp9/s +IQmeZRDIUy6163Ga9Uke6o1W7dVeohjvwY/KQHApZcK15RDkb+UiBd/9VM26N7eMoW41Sg7SKtQZ ++i8vEu2H6whEnvZCnYg+sOh9fxaDlOQhh7qhu4g2z1TORCjWzgELzZEmPJVrsf45cG0tz0xKoF/d +Uw/YoHF8RJexASnLZWj4125sNCQ6XfoEl1DLzUULxH7SeWM9owpouV5RZC3LZmCgyDUvbI0oMk+l +9GTae6lcMLOKD1R2q4NksQAt/osyWXQZw1g6pcqNSz1TdirbiQsTY6g+JZ3pYN2tK2w4WqVnLPix +lI9ktBec6XknnEEvrI7NhPLEXdxS7mUXuapCV6EfMfDPMvW523EUQPE5MWYBvHTmlIW5pemWgsAd +vuCFOIjs73L0es+88D3gCrSGSyk7KydSY3f2XCD8PLf78ZamVWi9yRpQryc33bRB2CaGhHhmbKto +4nsb+ToaG0aZE2FtIjOHTyC8jjsqgLRbHfRXJVFnngKVT+DEQnrfLRuC8+PtMrDDpZ4VarpK0aLd +BMtHPOsg+cOhwhqU021s2nq6G6XKfSDHeRR/2T/R0loeMr8/6UCVQKXitWl2f//tfnBYYMQObys3 +tYsJC46pR+Gp9ytUxc+//NKKmhn1J4Sm8anhGeePEmxroVbm5O16jk62u+L2jNJ0HOGYXNKizuKP +aVSReke4ZqdxJCCLZjLS6q4B5v5s7XK2TRFUb7BUeOVvezG698khGjCdPDOZH1gYxRoKR5VrkM1z +Mr8VPMi6io9GhaGehNz+N5ygXp6IG9VOht+j7H1y76rgooUtmtNKLuySTkf4nxK/FocuyCsDxP0r +jIZIgLEn1CD6R+ewbVZbFqwJt5RfJRpGss3Lmn3SdF4VEYQNHos6ytL0JzejC0Q7Foy5YC0cC0QC +fjpFZcbNXCJSnq6fX+KKq8MdHdivisU2Nd+5TCeqDdpuz2Plxs0o6wMlrYxIJKH+caxzvtlKdmRh +u1Ko/xz1A4VkljPJAudnrWXuvgfxVCacQ0DNJ/I8fA== diff --git a/tests/test_question_templates/question_inputs/q16_workspaces/file2.txt b/tests/test_question_templates/question_inputs/q16_workspaces/file2.txt new file mode 100644 index 00000000..492987ca --- /dev/null +++ b/tests/test_question_templates/question_inputs/q16_workspaces/file2.txt @@ -0,0 +1,18 @@ +DBVUxxDUlMoztjq4PiJSvgtwoY56pePoFur5Pz64DnE3tf2d7ffUtDBqluysfK62jpBzD9Ws6sTp +HZj7GIV1UQZloqbT2jPwyi5HGs1/aDfwTJA+ISur9mSEKLGEHADFqMsC9B5OW1P6hpzWiIjTGzde +VBOE5LfCy03VEsHfu90Ouk+PjEkxCz7rdIjjmxIDTp0GVmy73UwjvPT9Qwu70i2qSA1MDpCfAFmu +daTha8axoUcTnhNFlT2jVf4e/4cITNEsi/T/mMbpAtbXQXXLfflv7btJDTnY7L05AJetLmIXhZXB +OCwkA0d4gPMjG6p5Lkq3Vs3aeO8CVgSLeKEWz8Pru1pbSe0xDtt6EGZXK4axQ/gpZQfymEdqF4x5 +V3qqlVMDYcwIHkZiLdmxZOBX6J62yHtU7VdMD8zaT2Ds+fnqc4O0kRuUl+wZb+aQ1+ScZ17mxZ4B +6//1Ped29UUHuZQcJlOfrbtoXH4ZNO01OzZbQQ9YHlHLpOKQNqPXyBBH0bTz53ta5QX0ItMZ42eo +61fMjWm4baU4UmB1s9jlQGMYoVoo8URROfuZn7kirS9J5YLOpAuny+dBZsS8ezjwFput3Hh5JyYo +qIiC7oIVjHsHoYgAELxxFzLR3RreRxbKcoNxvdBu/4RngKzahXypIVPx0ldMiWIVnoEZlJtq5WE5 +S49N+ojExqOOWPPgXxcUP8dHkhfXoDgTph4M0ZFb4H6FJuwX/R7CqNHnqHbgYiCj1tZG4LBwVO/v +kamJudzm/SBvLlUycL9JrMgedLnUmVZorUgj4IVDju8lyHcz8RRBFHCBTh4LII+W+PBQ21LBCsH8 +2BZPOh8MLXFb8G7stl/n0rMkqC+tmRw2CAjwmbz/54nwuzm8o7k7cGXhou6blkx6tBlC54muSBWd +X7vNSctuY+JwwgLXk5JfeHIF2JdaCNaGyyBFgPer2rTG9PuoHD3QRibXOJSHy+NlCLrdrZXB89HQ +WNCpeBjWjlclG/O7LL2yuvrkvM5eohPjRBIHa4lxzEecL5Y+SPUOy7vIg0DChpL5CzpbYzgM15mS +Zd/ai7rkBzfdJMlmxTXNewMVaf4drtx9Cg9HJAWCjIjaX1lqOfku2vqKetfLQytz1qnNYo8oPcKE +PmaHbGkubdHI3+dDbqva3LWgrKjUNdVaQq+ICo57Pdo1FycScSyWW58Peldh0mIZodxVt8IiDiR3 +hjVJqGkRuxT0T07Dc2fXHKtylz8L2VdAQeeqqdaLvJnNVRU/CRzjdLLnWKUzC4f3CiFVeHW1MiRn +hWLsmy+tcEvZnFh29K1Ei55NFBcQjUvBQvmZgg+SiQ== diff --git a/tests/test_question_templates/question_inputs/q16_workspaces/filebad.txt b/tests/test_question_templates/question_inputs/q16_workspaces/filebad.txt new file mode 100644 index 00000000..90505446 --- /dev/null +++ b/tests/test_question_templates/question_inputs/q16_workspaces/filebad.txt @@ -0,0 +1,18 @@ +a5HQSUh3ZVyvZxZvF2t+Pi3BLjHQ8MTJJ/2I7rqOQQ+mPC3AWAD5WHR5OZ+XwE6qfVjThv0rH1Lk +3N9phhpM+4Ij7g2KwPK6sb076LbD6PRVNpIVjEfEuzdi8pcZ4hDvYbPOSZ3FSpqvDGbFCBRSobSp +npEnw2DkyABjlvh5JKsv732jrZBBXHqgtBE7RgVeT+wlXo6nu8h1330fOYQ3y0F8UCWELtqfHseU +A3T/yB56wOG33k8jBvpAzAYmM+zr3xfFKhp36Ak2NvKH2oikeUi5wB1q8kaVVbHKCEoCYYW/mYnf +FFaAh2zMYOhVEeNUaee8RrSQvIXar2vgOim9W4vJxgKRUpjp09YFDw9lOgu4ddru60pR7QLNmCP5 +ht1jImO1p0TZ+A/Vwp6jKskDFqKy7ZZBTHYT99scrUWd7OEyyIbWF7OSIeq8wubAqcbAJ6NMUBRv +JqPxsbNNhkm/Xw4zvhQyhsI5P9QIjBpzL8SwxdhD5DdGfP8JGQLaLlvW8GlgBhteNY2k5lpSL2YJ +UsT4BT6fkeZnaWNfxJR69eAI98PeDiVW8KedvtE/wU4WlhmXi/bY7lenZi6sBSzqiXxaJujszLIG +c/bahugWAMXEBHGBduaYBOI6JGdFY2219qqKlY1aM2WUBTh/IF+Ig9PZDSMGW/Qo4HEo8HYge1sl +JkbcIL2zNhLpUJR8eCaZ06QI8KOa2LvtVLRBFRCdLXhdelD3uZDYWRVh+0ykASdCNURqayIxC3ys +Uwq95Qt5uB0teliY/xQ+JRvu6YnU+kStJGrEgaeS8ZjF85ogFCbNUnqvub1mvek/y23Z5SSYSKm/ +KcUpAIVfAg+W2YriERzUEsyzMjTKS1MP4mEeWUGgBIR4yGU2hivyd4P0eeIAti/zCTaKQBTRwXJX +4nar06DgLUj4HHdcd7aaLTxt4bHA646IXO+2qYxQAZxvKkgWfZ6QWFakXVROR/6lfqJDLD3QVFD0 +0d25EOhPbxe/Q7L8TR7rMsmE7cpJvA/Mjv36g6f2l0PngzPlm/EiJ0i0wn/3Al4A5+AEfxDwRMFo +rNkaJEyEkRBDo5UeVdnTVXH1z70RLSju0n4oJe3NS47nv+gP5brMCkPxEh0pY1vtSFskaLHqJZwV +NWFSdij8THFL0dlfKG5wyPwtwCuQqCz029wRjfJNFEgfqWOGGXZLLC+7n4wdSr2QO+ppZdKqB/Bl +t6i2u5iwH+XrYf4j9THtXCQ6w/FEere2q8EBkCaTSOhKC+Gyp1rAnyuuYIy/dxprJKI4EzhgVHYo +171ZFv6aNT1ETGgB8ejaU9025ozLjRHvcbuHIZsm3g== diff --git a/tests/test_question_templates/question_inputs/q16_workspaces/q16_workspaces.md b/tests/test_question_templates/question_inputs/q16_workspaces/q16_workspaces.md new file mode 100644 index 00000000..24fa812f --- /dev/null +++ b/tests/test_question_templates/question_inputs/q16_workspaces/q16_workspaces.md @@ -0,0 +1,146 @@ +--- +title: Moving and copying files +topic: Template +author: Jonatan Schroeder; Converted by Gavin Kendal-Freedman +source: original +template_version: 1.0 +attribution: standard +partialCredit: true +singleVariant: false +showCorrectAnswer: false +outcomes: +- 6.1.1.0 +- 6.1.1.1 +difficulty: +- undefined +randomization: +- undefined +taxonomy: +- undefined +span: +- undefined +length: +- undefined +tags: +- unknown +assets: +workspaceFiles: + - file1.txt + - file2.txt + - filebad.txt +serverFiles: + - file1.txt + - file2.txt + - filebad.txt +workspaceOptions: + image: prairielearn/workspace-xtermjs + port: 8080 + home: /home/student + gradedFiles: + - file1.txt + - file2.txt + - filebad.txt + - newdir/file1_new.txt + - newdir/file2_new.txt +server: + imports: | + import base64 + import problem_bank_helpers as pbh + generate: | + data2 = pbh.create_data2() + + data2["params"]["vars"]["title"] = "Moving and copying files" + + # Update the data object with a new dict + data.update(data2) + grade: | + files = { f['name']: f['contents'] for f in data['submitted_answers'].get('_files', []) } + data['feedback']['results'] = [] + data['score'] = 0 + + with open('workspace/file1.txt', 'rb') as f: + file1_content = base64.b64encode(f.read()).decode() + with open('workspace/file2.txt', 'rb') as f: + file2_content = base64.b64encode(f.read()).decode() + + if 'newdir/file1_new.txt' not in files: + data['feedback']['results'].append('newdir/file1_new.txt was not created.') + elif files['newdir/file1_new.txt'] != file1_content: + data['feedback']['results'].append('newdir/file1_new.txt was created, but it is not based on file1.txt.') + elif 'file1.txt' in files: + data['feedback']['results'].append('newdir/file1_new.txt was created properly, but the old file still exists.') + data['score'] += 0.2 + else: + data['feedback']['results'].append('file1.txt moved successfully.') + data['score'] += 0.4 + + if 'newdir/file2_new.txt' not in files: + data['feedback']['results'].append('newdir/file2_new.txt was not created.') + elif files['newdir/file2_new.txt'] != file2_content: + data['feedback']['results'].append('newdir/file2_new.txt was created, but it is not based on file2.txt.') + elif 'file2.txt' not in files: + data['feedback']['results'].append('newdir/file2_new.txt was created properly, but the old file no longer exists.') + data['score'] += 0.2 + else: + data['feedback']['results'].append('file2.txt copied successfully.') + data['score'] += 0.4 + + if files and 'filebad.txt' in files: + data['feedback']['results'].append('filebad.txt still exists.') + else: + data['feedback']['results'].append('filebad.txt deleted successfully.') + data['score'] += 0.2 + prepare: | + pass + parse: | + if '_files' in data['format_errors']: + del data['format_errors']['_files'] +part1: + type: workspace +--- +# {{ params.vars.title }} + +## Question Text + +Open the Workspace below and perform the following tasks. + +- Create a new directory called `newdir`; +- Move the file `file1.txt` to the directory `newdir`, with the new name `file1_new.txt`; +- Copy the file `file2.txt` to the directory `newdir`, with the new name `file2_new.txt`; +- Delete the file `filebad.txt`. + +Once you complete these tasks, click on "Save & Grade" below. + +### Answer Section + + +### pl-submission-panel + + + + + +### pl-answer-panel + +Everything here will get inserted directly into an pl-answer-panel element at the end of the `question.html`. +Please remove this section if it is not application for this question. + +## Rubric + +This should be hidden from students until after the deadline. + +## Solution + +This should never be revealed to students. + +## Comments + +These are random comments associated with this question: + +This example problem was originally created by [Jonatan Schroeder](https://www.cs.ubc.ca/people/jonatan-schroeder), and was later converted to the OER markdown layout. + diff --git a/tests/test_question_templates/question_inputs/q16_workspaces/workspace/file1.txt b/tests/test_question_templates/question_inputs/q16_workspaces/workspace/file1.txt new file mode 100644 index 00000000..b30565ee --- /dev/null +++ b/tests/test_question_templates/question_inputs/q16_workspaces/workspace/file1.txt @@ -0,0 +1,18 @@ +Gk44G5S2cov8PgPpy9n7r0v4FYY7zU/7i8UNDrRYLU1GjpVdCPIzdbUUcln3CqNlBTEKjn75+3qs +DUvteohtwFF+4BYwAyfv7yjzX9CPsyfHjBYC+b+fMHPMFns1vdlGUvwDEePE4k1EnJECUZKTkebJ +ymKhR6BY4IUnO5cVsRARExtVkYddHUcNAhgLpN9E/SNln9gJ9fN4WRat6l2QSDaH2OJ96+lDM/yR +EVttiFtCynzgguVYQy06tlpLXk9a9MwPlVGJvH/qH28pHkIac2H6UpWnDcBptsVJTVfTVv9Gp9/s +IQmeZRDIUy6163Ga9Uke6o1W7dVeohjvwY/KQHApZcK15RDkb+UiBd/9VM26N7eMoW41Sg7SKtQZ ++i8vEu2H6whEnvZCnYg+sOh9fxaDlOQhh7qhu4g2z1TORCjWzgELzZEmPJVrsf45cG0tz0xKoF/d +Uw/YoHF8RJexASnLZWj4125sNCQ6XfoEl1DLzUULxH7SeWM9owpouV5RZC3LZmCgyDUvbI0oMk+l +9GTae6lcMLOKD1R2q4NksQAt/osyWXQZw1g6pcqNSz1TdirbiQsTY6g+JZ3pYN2tK2w4WqVnLPix +lI9ktBec6XknnEEvrI7NhPLEXdxS7mUXuapCV6EfMfDPMvW523EUQPE5MWYBvHTmlIW5pemWgsAd +vuCFOIjs73L0es+88D3gCrSGSyk7KydSY3f2XCD8PLf78ZamVWi9yRpQryc33bRB2CaGhHhmbKto +4nsb+ToaG0aZE2FtIjOHTyC8jjsqgLRbHfRXJVFnngKVT+DEQnrfLRuC8+PtMrDDpZ4VarpK0aLd +BMtHPOsg+cOhwhqU021s2nq6G6XKfSDHeRR/2T/R0loeMr8/6UCVQKXitWl2f//tfnBYYMQObys3 +tYsJC46pR+Gp9ytUxc+//NKKmhn1J4Sm8anhGeePEmxroVbm5O16jk62u+L2jNJ0HOGYXNKizuKP +aVSReke4ZqdxJCCLZjLS6q4B5v5s7XK2TRFUb7BUeOVvezG698khGjCdPDOZH1gYxRoKR5VrkM1z +Mr8VPMi6io9GhaGehNz+N5ygXp6IG9VOht+j7H1y76rgooUtmtNKLuySTkf4nxK/FocuyCsDxP0r +jIZIgLEn1CD6R+ewbVZbFqwJt5RfJRpGss3Lmn3SdF4VEYQNHos6ytL0JzejC0Q7Foy5YC0cC0QC +fjpFZcbNXCJSnq6fX+KKq8MdHdivisU2Nd+5TCeqDdpuz2Plxs0o6wMlrYxIJKH+caxzvtlKdmRh +u1Ko/xz1A4VkljPJAudnrWXuvgfxVCacQ0DNJ/I8fA== diff --git a/tests/test_question_templates/question_inputs/q16_workspaces/workspace/file2.txt b/tests/test_question_templates/question_inputs/q16_workspaces/workspace/file2.txt new file mode 100644 index 00000000..492987ca --- /dev/null +++ b/tests/test_question_templates/question_inputs/q16_workspaces/workspace/file2.txt @@ -0,0 +1,18 @@ +DBVUxxDUlMoztjq4PiJSvgtwoY56pePoFur5Pz64DnE3tf2d7ffUtDBqluysfK62jpBzD9Ws6sTp +HZj7GIV1UQZloqbT2jPwyi5HGs1/aDfwTJA+ISur9mSEKLGEHADFqMsC9B5OW1P6hpzWiIjTGzde +VBOE5LfCy03VEsHfu90Ouk+PjEkxCz7rdIjjmxIDTp0GVmy73UwjvPT9Qwu70i2qSA1MDpCfAFmu +daTha8axoUcTnhNFlT2jVf4e/4cITNEsi/T/mMbpAtbXQXXLfflv7btJDTnY7L05AJetLmIXhZXB +OCwkA0d4gPMjG6p5Lkq3Vs3aeO8CVgSLeKEWz8Pru1pbSe0xDtt6EGZXK4axQ/gpZQfymEdqF4x5 +V3qqlVMDYcwIHkZiLdmxZOBX6J62yHtU7VdMD8zaT2Ds+fnqc4O0kRuUl+wZb+aQ1+ScZ17mxZ4B +6//1Ped29UUHuZQcJlOfrbtoXH4ZNO01OzZbQQ9YHlHLpOKQNqPXyBBH0bTz53ta5QX0ItMZ42eo +61fMjWm4baU4UmB1s9jlQGMYoVoo8URROfuZn7kirS9J5YLOpAuny+dBZsS8ezjwFput3Hh5JyYo +qIiC7oIVjHsHoYgAELxxFzLR3RreRxbKcoNxvdBu/4RngKzahXypIVPx0ldMiWIVnoEZlJtq5WE5 +S49N+ojExqOOWPPgXxcUP8dHkhfXoDgTph4M0ZFb4H6FJuwX/R7CqNHnqHbgYiCj1tZG4LBwVO/v +kamJudzm/SBvLlUycL9JrMgedLnUmVZorUgj4IVDju8lyHcz8RRBFHCBTh4LII+W+PBQ21LBCsH8 +2BZPOh8MLXFb8G7stl/n0rMkqC+tmRw2CAjwmbz/54nwuzm8o7k7cGXhou6blkx6tBlC54muSBWd +X7vNSctuY+JwwgLXk5JfeHIF2JdaCNaGyyBFgPer2rTG9PuoHD3QRibXOJSHy+NlCLrdrZXB89HQ +WNCpeBjWjlclG/O7LL2yuvrkvM5eohPjRBIHa4lxzEecL5Y+SPUOy7vIg0DChpL5CzpbYzgM15mS +Zd/ai7rkBzfdJMlmxTXNewMVaf4drtx9Cg9HJAWCjIjaX1lqOfku2vqKetfLQytz1qnNYo8oPcKE +PmaHbGkubdHI3+dDbqva3LWgrKjUNdVaQq+ICo57Pdo1FycScSyWW58Peldh0mIZodxVt8IiDiR3 +hjVJqGkRuxT0T07Dc2fXHKtylz8L2VdAQeeqqdaLvJnNVRU/CRzjdLLnWKUzC4f3CiFVeHW1MiRn +hWLsmy+tcEvZnFh29K1Ei55NFBcQjUvBQvmZgg+SiQ== diff --git a/tests/test_question_templates/question_inputs/q16_workspaces/workspace/filebad.txt b/tests/test_question_templates/question_inputs/q16_workspaces/workspace/filebad.txt new file mode 100644 index 00000000..90505446 --- /dev/null +++ b/tests/test_question_templates/question_inputs/q16_workspaces/workspace/filebad.txt @@ -0,0 +1,18 @@ +a5HQSUh3ZVyvZxZvF2t+Pi3BLjHQ8MTJJ/2I7rqOQQ+mPC3AWAD5WHR5OZ+XwE6qfVjThv0rH1Lk +3N9phhpM+4Ij7g2KwPK6sb076LbD6PRVNpIVjEfEuzdi8pcZ4hDvYbPOSZ3FSpqvDGbFCBRSobSp +npEnw2DkyABjlvh5JKsv732jrZBBXHqgtBE7RgVeT+wlXo6nu8h1330fOYQ3y0F8UCWELtqfHseU +A3T/yB56wOG33k8jBvpAzAYmM+zr3xfFKhp36Ak2NvKH2oikeUi5wB1q8kaVVbHKCEoCYYW/mYnf +FFaAh2zMYOhVEeNUaee8RrSQvIXar2vgOim9W4vJxgKRUpjp09YFDw9lOgu4ddru60pR7QLNmCP5 +ht1jImO1p0TZ+A/Vwp6jKskDFqKy7ZZBTHYT99scrUWd7OEyyIbWF7OSIeq8wubAqcbAJ6NMUBRv +JqPxsbNNhkm/Xw4zvhQyhsI5P9QIjBpzL8SwxdhD5DdGfP8JGQLaLlvW8GlgBhteNY2k5lpSL2YJ +UsT4BT6fkeZnaWNfxJR69eAI98PeDiVW8KedvtE/wU4WlhmXi/bY7lenZi6sBSzqiXxaJujszLIG +c/bahugWAMXEBHGBduaYBOI6JGdFY2219qqKlY1aM2WUBTh/IF+Ig9PZDSMGW/Qo4HEo8HYge1sl +JkbcIL2zNhLpUJR8eCaZ06QI8KOa2LvtVLRBFRCdLXhdelD3uZDYWRVh+0ykASdCNURqayIxC3ys +Uwq95Qt5uB0teliY/xQ+JRvu6YnU+kStJGrEgaeS8ZjF85ogFCbNUnqvub1mvek/y23Z5SSYSKm/ +KcUpAIVfAg+W2YriERzUEsyzMjTKS1MP4mEeWUGgBIR4yGU2hivyd4P0eeIAti/zCTaKQBTRwXJX +4nar06DgLUj4HHdcd7aaLTxt4bHA646IXO+2qYxQAZxvKkgWfZ6QWFakXVROR/6lfqJDLD3QVFD0 +0d25EOhPbxe/Q7L8TR7rMsmE7cpJvA/Mjv36g6f2l0PngzPlm/EiJ0i0wn/3Al4A5+AEfxDwRMFo +rNkaJEyEkRBDo5UeVdnTVXH1z70RLSju0n4oJe3NS47nv+gP5brMCkPxEh0pY1vtSFskaLHqJZwV +NWFSdij8THFL0dlfKG5wyPwtwCuQqCz029wRjfJNFEgfqWOGGXZLLC+7n4wdSr2QO+ppZdKqB/Bl +t6i2u5iwH+XrYf4j9THtXCQ6w/FEere2q8EBkCaTSOhKC+Gyp1rAnyuuYIy/dxprJKI4EzhgVHYo +171ZFv6aNT1ETGgB8ejaU9025ozLjRHvcbuHIZsm3g==