def _prompt_for_confirmation(user_name, course_name, quiz_title, has_question_bank): """Prints user inputs to screen and asks user to confirm. Shuts down if user inputs anything other than 'Y' or 'y'. Returns otherwise. Args: user_name (string): name of user (aka. holder of token) course_name (string): name of course returned from Canvas quiz_name (string): name of quiz returned from Canvas course object Returns: None -- returns only if user confirms """ cprint('\nConfirmation:', 'blue') print(f'USER: {user_name}') print(f'COURSE: {course_name}') print(f'QUIZ: {quiz_title}') print(f'HAS QUESTION BANK: {has_question_bank}') print('\n') confirm = input( 'Would you like to continue using the above information? [y/n]: ') print('\n') if confirm == 'y' or confirm == 'Y': return elif confirm == 'n' or confirm == 'N': shut_down('Exiting...') else: shut_down('ERROR: Only accepted values are y and n')
def _get_peer_reviews_json(base_url, course_id, assignment_id, token): """Makes request to Canvas API to get peer review object. Shuts down with error if server responds with error or if response is empty. Otherwise returns JSON. Args: base_url (str): Canvas instance being used course_id (str): Canvas course id assignment_id (str): Canvas assignment id token (str): Canvas access token Returns: assessments_json: peer reviews JSON obj for the given course + assignment """ # headers variable for REST API calls headers = {"Authorization": "Bearer " + token} try: peer_reviews_endpoint = f"{base_url}/api/v1/courses/{course_id}/assignments/{assignment_id}/peer_reviews" peer_reviews = requests.get(peer_reviews_endpoint, headers=headers) peer_reviews.raise_for_status peer_reviews = json.loads(peer_reviews.text) except Exception as e: shut_down( "ERROR: Could not get peer reviews specified course and assignment (API responded with error)." ) if not peer_reviews: shut_down( "ERROR: Assignment must have at least one peer review assigned.") return peer_reviews
def _get_rubric(course, assignment): """ Parses rubric id from assignment object. If found, retrieves rubric with that id from course object. Otherwise, shuts down with error message. Args: course (object): Course object - canvasapi assignment (object): Assignment object - canvasapi Returns: rubric: Rubric object as specified by canvasapi python wrapper """ # get rubric id from assignment attributes # throw error and shut down if assignment has no rubric try: rubric_id = assignment.rubric_settings["id"] # depreciated sytax - remove soon # rubric_id = assignment.attributes['rubric_settings']['id'] except KeyError as e: shut_down(f"Assignment: {assignment.name} has no rubric") # get rubric object from course rubric = course.get_rubric(rubric_id, include=["peer_assessments"], style="full") return rubric
def _prompt_for_confirmation(user_name, course_name, assignment_name, include_assignment_score): """Prints user inputs to screen and asks user to confirm. Shuts down if user inputs anything other than 'Y' or 'y'. Returns otherwise. Args: user_name (string): name of user (aka. holder of token) course_name (string): name of course returned from Canvas assignment_name (string): name of assignment returned from Canvas include_assignment_score (boolean): whether to include the assignment score (non-peer-review) Returns: None -- returns only if user confirms """ cprint("\nConfirmation:", "blue") print(f"USER: {user_name}") print(f"COURSE: {course_name}") print(f"ASSIGNMENT: {assignment_name}") print(f"INCLUDE ASSIGNMENT SCORE: {include_assignment_score}") print("\n") confirm = input( "Would you like to continue using the above information?[y/n]: ") print("\n") if confirm == "y" or confirm == "Y": return elif confirm == "n" or confirm == "N": shut_down("Exiting...") else: shut_down("ERROR: Only accepted values are y and n")
def _prompt_for_confirmation(user_name, account_name, term): """Prints user inputs to screen and asks user to confirm. Shuts down if user inputs anything other than 'Y' or 'y'. Returns otherwise. Args: user_name (string): name of user (aka. holder of token) account_name (string): name of account returned from Canvas Returns: None -- returns only if user confirms """ cprint('\nConfirmation:', 'blue') print(f'USER: {user_name}') print(f'RUNNING ON ACCOUNT: {account_name}') print(f'RUNNING FOR TERM: {term}') print('\n') confirm = input( 'Would you like to continue using the above information? [y/n]: ') print('\n') if confirm == 'y' or confirm == 'Y': return elif confirm == 'n' or confirm == 'N': shut_down('Exiting...') else: shut_down('ERROR: Only accepted values are y and n')
def _get_students(course): """ Gets a paginated list of students enrolled in the course using the course param and shuts down with error if that list is empty. Args: course (object): Course object - canvasapi Returns: students: Paginated list of students in this course """ students = course.get_users(enrollment_type=["student"]) if not students: shut_down("ERROR: Course must have students enrolled.") return students
def main(): pygame.init() pygame.display.set_caption('Pent') screen = pygame.display.set_mode((SCREEN_W, SCREEN_H)) clock = pygame.time.Clock() # Sprite groups all_sprites = pygame.sprite.RenderPlain() board = Board(screen.get_rect().center) all_sprites.add(board) # White goes first for now current_player = WHITE # Main event loop while True: for event in pygame.event.get(): if event.type == pygame.QUIT: shut_down(screen) if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: shut_down(screen) if event.type == pygame.MOUSEBUTTONDOWN: if board.make_move(current_player, pygame.mouse.get_pos()): winner = board.winner() if winner == TIE: print "Tie game..." elif winner == WHITE: print "White won..." elif winner == BLACK: print "Black won..." current_player = -current_player # Clear screen screen.fill(pygame.Color('black')) all_sprites.update() all_sprites.draw(screen) # Flip screen pygame.display.flip() # Pause clock.tick(FPS)
def download_quiz_report(report_info): # downloads the quiz reports and gathers info try: download_url = report_info['file']['url'] filename = report_info['file']['display_name'] res = requests.get(download_url, headers=settings.auth_header) with (open('raw_reports/' + filename, 'wb')) as output: output.write(res.content) print(f'Outputting Raw Report: {filename}\n') df = pd.read_csv(io.StringIO(res.content.decode('utf-8'))) return df except Exception: shut_down('ERROR: Unable to download quiz report.')
def get_user_inputs(): """Prompt user for required inputs. Queries Canvas API throughout to check for access and validity errors. Errors stop execution and print to screen. Returns: Dictionary containing inputs """ # prompt user for url and token url = "https://ubc.test.instructure.com/" # url = "https://canvas.ubc.ca/" token = input('Please enter your token: ') term = input( 'Please enter the Canvas term or year (or hit enter for all): ') auth_header = {'Authorization': f'Bearer {token}'} # Canvas object to provide access to Canvas API canvas = Canvas(url, token) # get user object try: user = canvas.get_user('self') cprint(f'\nHello, {user.name}!', 'green') except Exception: shut_down(""" ERROR: could not get user from server. Please ensure token is correct and valid and ensure using the correct instance url. """) # get account object try: account_id = input('Account ID: ') account = canvas.get_account(account_id) except Exception: shut_down( f'ERROR: Account not found [ID: {account_id}]. Please check account number.' ) # prompt user for confirmation _prompt_for_confirmation(user.name, account.name, term) # set course, quiz, students and auth_header as global variables # return inputs dictionary return canvas, account, auth_header, term
def process_keypress(self, key): """Process key presses.""" self.player.process_keypress(key) # Player gets first whack at keys if key == pygame.K_ESCAPE: if self.game_paused or self.player.is_dead(): shut_down(self.screen) else: self.game_paused = True pygame.event.set_grab(False) # ungrab when paused self.player.untarget_all() # untarget all when paused # When the game is paused, any non-ESC key will unpause else: if self.game_paused: if self.intro_screen: self.intro_screen = False self.game_paused = False pygame.event.set_grab(True) # grab for less annoyance
def _get_assessments_json(rubric): """Gets completed assessments data from rubric object. If there rubric object is missing assessments field, shuts down with error otherwise returns JSON. Args: rubric (object): Rubric object - canvasapi Returns: assessments_json: JSON data of all completed assessments """ try: assessments_json = rubric.assessments # depreciated sytax - remove soon # assessments_json = rubric.attributes['assessments'] except AttributeError: shut_down("ERROR: Rubric JSON object has no assessments field.") return assessments_json
def get_progress(progress_url, attempt_number): # maximum 9 attempts (90 seconds) to get progress before shutting down with error if attempt_number >= 9: shut_down( 'ERROR: Application timeout, Canvas quiz report is taking too long to generate. Try again in a few minutes.' ) r_progress = requests.get(progress_url, headers=settings.auth_header) progress_state = json.loads(r_progress.text) progress_completion = progress_state['workflow_state'] if progress_completion == 'completed': return progress_completion elif progress_completion == 'failed': raise Exception elif progress_completion == 'queued' or progress_completion == 'running': # set timeout for 10 seconds then try again print(f'Report state is: {progress_completion}, waiting...') time.sleep(10) return get_progress(progress_url, attempt_number + 1) else: shut_down( f'ERROR: Unrecognized value for workflow_state in Canvas: {progress_completion}.' )
def process_event(self, event): """Process pygame events.""" if event.type == pygame.QUIT: shut_down(self.screen) if event.type == pygame.KEYDOWN: self.process_keypress(event.key) if event.type == pygame.KEYUP: self.player.process_keyrelease(event.key) if event.type == pygame.MOUSEMOTION: # Update the cursor position self.cursor.rect.center = event.pos if event.type == pygame.MOUSEBUTTONUP: # When the mouse button 1 is released, kill any targeted enemies if event.button == 1 and not (self.game_paused or self.player.is_dead()): self.player.kill_targeted() if event.type == pygame.MOUSEBUTTONDOWN: # 3 is right button... nuke 'em all! if event.button == 3 and not (self.game_paused or self.player.is_dead()): self.player.nuke(self.enemies)
def main(): # initialize global variables - call only once settings.init() # get user inputs url, course_id, quiz_id = get_user_inputs() # get quiz questions and save ids of essay questions quiz_questions = settings.quiz.get_questions() # get list of ids of all essay question (in Quiz and in Quiz Banks if used) essay_question_ids = get_all_essay_question_ids(quiz_questions) # create a new quiz report on Canvas try: print(f'Creating Canvas quiz report for: {settings.quiz.title}...\n') post_report_res = create_quiz_report(url, course_id, quiz_id) progress = get_progress(post_report_res['progress_url'], 1) assert progress == 'completed' except Exception: shut_down( f'ERROR: Failed to create Canvas quiz report for: {settings.quiz.title}.' ) report_info = get_quiz_report(url, course_id, quiz_id, post_report_res['id']) # download raw report that was just generated df = download_quiz_report(report_info) # reduce dataframe columns name, id and any question columns cols = ['name', 'id'] for c in df.columns.values: if c[:7] in essay_question_ids: cols.append(c) df = df[cols] # remove name and id so we're only left with question column names - used later cols.remove('name') cols.remove('id') # make students dataframe students_df = pd.DataFrame( columns=['Name', 'UBC ID', 'Canvas ID', 'Anonymous ID']) # make output directory for quiz dir_path = f'output/COURSE({course_id})_QUIZ({quiz_id})' if not os.path.exists(dir_path): os.makedirs(dir_path) # make outpit subdirectory for pdfs - delete old data if any is there pdf_dir_path = dir_path + '/pdfs' if os.path.exists(pdf_dir_path): rmtree(pdf_dir_path) os.makedirs(pdf_dir_path) for index, row in df.iterrows(): # generate a random id for the student anonymous_id = generate_random_id() # get UBC id ubc_stu_id = get_ubc_id(row['id']) # add the random id, student name, and UBC sid to a dataset that will be made into csv students_df = students_df.append( { 'Name': row['name'], 'UBC ID': ubc_stu_id, 'Canvas ID': row['id'], 'Anonymous ID': anonymous_id }, ignore_index=True) # create a pdf doc_title = f'{anonymous_id}_{course_id}_{quiz_id}' # create and output pdf try: generate_pdf(row, cols, doc_title, pdf_dir_path, anonymous_id) except Exception: shut_down('There was a problem generating PDFs') # output to {course_id}_{quiz_id}_students.csv students_df.to_csv(f'{dir_path}/{course_id}_{quiz_id}_students.csv', index=False) # Call the function to retrieve all files and folders of the assigned directory filePaths = retrieve_file_paths(pdf_dir_path) # writing files to a zipfile zip_file = zipfile.ZipFile(pdf_dir_path + '.zip', 'w') with zip_file: # writing each file one by one for file in filePaths: arcname = file[len(dir_path) + 1:] zip_file.write(file, arcname) cprint('PDFs successfully created in: ' + pdf_dir_path + '.zip', 'green') rmtree(pdf_dir_path)
sendMmiButton(MmiButtonIds.NAV, True) nr_turns = 0 acc_12v_on_timestamp = time.time() # signal Pi has booted and is up and running GPIO.output(PI_ON_OUTPUT_PIN, GPIO.HIGH) shutdown = False while not shutdown: if (not GPIO.input(ACC_12V_INPUT_PIN)): # reset timestamp in acc is on (active low) acc_12v_on_timestamp = time.time() if (time.time() - acc_12v_on_timestamp > 5): # if acc has been off for 5 seconds initiate shutdown # this timeout prevents unintended shutdowns when power is turned off and on in short succession shutdown = True sendMmiWheel(MmiWheelIds.BIG_WHEEL, nr_turns < 7, 1) nr_turns += 1 if nr_turns >= 14: sendMmiButton(MmiButtonIds.RADIO, True) if nr_turns >= 20: nr_turns = 0 sendMmiButton(MmiButtonIds.NAV, True) time.sleep(0.5) # initiate shutdown shut_down()
def get_user_inputs(): """Prompt user for required inputs. Queries Canvas API throughout to check for access and validity errors. Errors stop execution and print to screen. Returns: Dictionary containing inputs """ # prompt user for url and token url = input("Canvas Instance URL: ") token = getpass.getpass("Please enter your token: ") # Canvas object to provide access to Canvas API canvas = Canvas(url, token) # get user object try: user = canvas.get_user("self") cprint(f"\nHello, {user.name}!", "green") # shut_down('TEMP KILL SWITCH') except Exception as e: shut_down(""" ERROR: could not get user from server. Please ensure token is correct and valid and ensure using the correct instance url. """) # get course object try: course_number = input("Course Number: ") course = canvas.get_course(course_number) except Exception as e: shut_down("ERROR: Course not found. Please check course number.") # get assignment object try: assignment_number = input("Assignment Number: ") assignment = course.get_assignment(assignment_number) except Exception as e: shut_down( "ERROR: Assignment not found. Please check assignment number.") # get whether to include assignment grades try: include_assignment_score = input( "Y or N, do you require non-peer-review scores?: ") if include_assignment_score.upper().strip() == "Y": include_assignment_score = True else: include_assignment_score = False except Exception as e: shut_down("ERROR: error in input for requiring non-peer-review-scores") # prompt user for confirmation _prompt_for_confirmation(user.name, course.name, assignment.name, include_assignment_score) # set course and assignment objects to global variables settings.COURSE = course settings.ASSIGNMENT = assignment settings.INCLUDE_ASSIGNMENT_SCORE = include_assignment_score # return inputs dictionary return { "token": token, "base_url": url, "course_number": course_number, "assignment_number": assignment_number, }
def get_user_inputs(): """Prompt user for required inputs. Queries Canvas API throughout to check for access and validity errors. Errors stop execution and print to screen. Returns: Dictionary containing inputs """ # prompt user for url and token url = input('Canvas Instance URL: ') token = getpass.getpass('Please enter your token: ') auth_header = {'Authorization': f'Bearer {token}'} # Canvas object to provide access to Canvas API canvas = Canvas(url, token) # get user object try: user = canvas.get_user('self') cprint(f'\nHello, {user.name}!', 'green') except Exception: shut_down(""" ERROR: could not get user from server. Please ensure token is correct and valid and ensure using the correct instance url. """) # get course object try: course_id = input('Course ID: ') course = canvas.get_course(course_id) except Exception: shut_down( f'ERROR: Course not found [ID: {course_id}]. Please check course number.' ) # get students from course try: students = course.get_users(enrollment_type='student') except Exception: shut_down( 'ERROR: Not able to get students from course. Ensure course has enrolled students.' ) # get the quiz from course try: quiz_id = input('Quiz ID: ') quiz = course.get_quiz(quiz_id) except Exception: shut_down( f'ERROR: Quiz not found [ID: {quiz_id}]. Please check quiz number.' ) question_bank_input = input('Does this quiz use Question Bank(s)? [y/n]: ') if question_bank_input == 'y' or question_bank_input == 'Y': has_question_bank = True else: has_question_bank = False # prompt user for confirmation _prompt_for_confirmation(user.name, course.name, quiz.title, has_question_bank) # set course, quiz, students and auth_header as global variables settings.course = course settings.quiz = quiz settings.students = students settings.auth_header = auth_header settings.has_question_bank = has_question_bank # return inputs dictionary return url, course_id, quiz_id