Skip to content
This repository has been archived by the owner on Aug 6, 2021. It is now read-only.

Commit

Permalink
Class Manager: Use section selector from Grade Puller in selecting la…
Browse files Browse the repository at this point in the history
…b parts

Pulled ZybooksSectionSelector into common utils.py to be used in both
 the Grade Puller and the Class Manager
  • Loading branch information
cs142ta committed Jul 28, 2020
1 parent c852f61 commit c189f0a
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 76 deletions.
26 changes: 10 additions & 16 deletions zygrader/class_manager.py
Expand Up @@ -8,6 +8,7 @@
from zygrader.zybooks import Zybooks
from zygrader import data
from zygrader.config.shared import SharedData
from zygrader.utils import ZybookSectionSelector

def save_roster(roster):
"""Save the roster of students to a json file"""
Expand Down Expand Up @@ -71,30 +72,23 @@ def add_lab():

# Get lab part(s)
parts = []
number = window.create_text_input("Enter Part", "Enter Chapter.section, e.g. 2.26 (ESC to cancel)")

while number != Window.CANCEL:
part = {}
chapter, section = number.split(".")
section_selector = ZybookSectionSelector()
section_numbers = section_selector.select_zybook_sections(return_just_numbers=True)

for chapter, section in section_numbers:
part = {}
response = zy_api.get_zybook_section(chapter, section)
if not response.success:
window.create_popup("Error", ["Invalid URL"])
else:
# Name lab part and add to list of parts
name = window.create_text_input("Part Name", "Enter new part name")
if name == Window.CANCEL:
name = response.name

part["name"] = name
part["id"] = response.id
parts.append(part)

# Get next part
number = window.create_text_input("Enter Part", "Enter Chapter.section, e.g. 2.26 (ESC to finish)")
part["name"] = response.name
part["id"] = response.id
parts.append(part)

new_lab = data.model.Lab(lab_name, parts, {})

edit_lab_options(new_lab)

all_labs = data.get_labs()
all_labs.append(new_lab)

Expand Down
68 changes: 8 additions & 60 deletions zygrader/grade_puller.py
Expand Up @@ -5,6 +5,7 @@
from zygrader.ui import UI_GO_BACK
from zygrader.config.shared import SharedData
from zygrader.zybooks import Zybooks
from zygrader.utils import ZybookSectionSelector, fetch_zybooks_toc

def create_last_night():
now = datetime.datetime.now()
Expand All @@ -27,7 +28,6 @@ def __init__(self):
def pull(self):
try:
self.read_canvas_csv()
self.fetch_zybooks_toc()
self.selected_assignments = []

more_assignments = True
Expand Down Expand Up @@ -65,14 +65,6 @@ def read_canvas_csv(self):
self.window.create_popup("Error in Reading Master CSV", [f"Could not open {path} for reading", "Please have the owner of the file grant read permissions"])
raise GradePuller.StoppingException()

def fetch_zybooks_toc(self):
wait_controller = self.window.create_waiting_popup("TOC", ["Fetching TOC from zyBooks"])
toc = self.zy_api.get_table_of_contents()
wait_controller.close()
if not toc:
raise GradePuller.StoppingException()
self.zybooks_toc = toc

def select_canvas_assignment(self):
real_assignments = self.canvas_header[GradePuller.NUM_CANVAS_ID_COLUMNS:]
index = self.window.create_filtered_list("Assignment", input_data=real_assignments)
Expand All @@ -81,55 +73,11 @@ def select_canvas_assignment(self):
return real_assignments[index]

def select_zybook_sections(self):
class ZybookSectionSelector:
def __init__(self, grade_puller):
self.outer = grade_puller
self.zybooks_sections = {(chapter['number'], section['number']): section for chapter in self.outer.zybooks_toc for section in chapter['sections']}

def draw_zybook_sections(self, chapters_expanded, selected_sections):
res = []
items = []
for chapter in self.outer.zybooks_toc:
res.append(f"{chapter['number']} - {chapter['title']}")
items.append(chapter['number'])
if chapters_expanded[chapter['number']]:
for section in chapter['sections']:
section_string = f"{chapter['number']}.{section['number']} - {section['title']}"
is_selected = selected_sections[(chapter['number'], section['number'])]
if not section['hidden'] and not section['optional']:
res.append(f" [{'X' if is_selected else ' '}] {section_string}")
else:
res.append(f" -{'X' if is_selected else '-'}- {section_string} (hidden/optional)")
items.append((chapter['number'], section['number']))
self.drawn_zybook_items = items
return res

def select_zybook_sections_callback(self, chapters_expanded, selected_sections, selected_index):
item = self.drawn_zybook_items[selected_index]
if isinstance(item, tuple): #is a section
section = self.zybooks_sections[item]
if not section['hidden'] and not section['optional']:
selected_sections[item] = not selected_sections[item]
else: #is a chapter
chapters_expanded[item] = not chapters_expanded[item]

def select_zybook_sections(self):
chapters_expanded = {chapter['number']: False for chapter in self.outer.zybooks_toc}
selected_sections = {(chapter['number'], section['number']): False for chapter in self.outer.zybooks_toc for section in chapter['sections']}
draw_sections = lambda: self.draw_zybook_sections(chapters_expanded, selected_sections)
draw_sections()
section_callback = lambda context: self.select_zybook_sections_callback(chapters_expanded, selected_sections, context.data)
self.outer.window.create_list_popup("Select zyBook Sections (use Back to finish)", callback=section_callback, list_fill=draw_sections)
res = []
for section_numbers, selected in selected_sections.items():
if selected:
res.append(self.zybooks_sections[section_numbers])
if not res:
raise GradePuller.StoppingException()
return res

selector = ZybookSectionSelector(self)
return selector.select_zybook_sections()
selector = ZybookSectionSelector()
res = selector.select_zybook_sections()
if not res:
raise GradePuller.StoppingException()
return res

def select_class_sections(self):
num_sections = len(self.canvas_students[-1]['Section'].split('and')) #Test Student has id -1, and is in every section
Expand Down Expand Up @@ -252,9 +200,9 @@ def write_upload_file(self, selected_canvas_assignment):
def find_unmatched_students(self):
try:
self.read_canvas_csv()
self.fetch_zybooks_toc()
zybooks_toc = fetch_zybooks_toc()

zybook_section_1_1 = self.zybooks_toc[0]['sections'][0]
zybook_section_1_1 = zybooks_toc[0]['sections'][0]
wait_msg = ["Fetching a completion report from zyBooks"]
wait_controller = self.window.create_waiting_popup("Fetch Reports", wait_msg)
zybooks_students, zybooks_header = self.fetch_completion_report(create_last_night(), [zybook_section_1_1])
Expand Down
62 changes: 62 additions & 0 deletions zygrader/utils.py
Expand Up @@ -14,6 +14,8 @@
from zygrader import data
from zygrader import ui
from zygrader.ui import components
from zygrader.zybooks import Zybooks
from zygrader.ui.window import Window


def suspend_curses(callback_fn):
Expand Down Expand Up @@ -161,3 +163,63 @@ def view_students():

window.create_filtered_list("Student Name", input_data=students,
callback=view_students_callback)

def fetch_zybooks_toc():
wait_controller = Window.get_window().create_waiting_popup("TOC", ["Fetching TOC from zyBooks"])
zy_api = Zybooks()
toc = zy_api.get_table_of_contents()
wait_controller.close()
return toc

class ZybookSectionSelector:
def __init__(self):
self.window = Window.get_window()
self.zy_api = Zybooks()

def draw_zybook_sections(self, chapters_expanded, selected_sections):
res = []
items = []
for chapter in self.zybooks_toc:
res.append(f"{chapter['number']} - {chapter['title']}")
items.append(chapter['number'])
if chapters_expanded[chapter['number']]:
for section in chapter['sections']:
section_string = f"{chapter['number']}.{section['number']} - {section['title']}"
is_selected = selected_sections[(chapter['number'], section['number'])]
if not section['hidden'] and not section['optional']:
res.append(f" [{'X' if is_selected else ' '}] {section_string}")
else:
res.append(f" -{'X' if is_selected else '-'}- {section_string} (hidden/optional)")
items.append((chapter['number'], section['number']))
self.drawn_zybook_items = items
return res

def select_zybook_sections_callback(self, chapters_expanded, selected_sections, selected_index):
item = self.drawn_zybook_items[selected_index]
if isinstance(item, tuple): #is a section
section = self.zybooks_sections[item]
if not section['hidden'] and not section['optional']:
selected_sections[item] = not selected_sections[item]
else: #is a chapter
chapters_expanded[item] = not chapters_expanded[item]

def select_zybook_sections(self, return_just_numbers=False):
self.zybooks_toc = self.zy_api.get_table_of_contents()
if not self.zybooks_toc:
return None
self.zybooks_sections = {(chapter['number'], section['number']): section for chapter in self.zybooks_toc for section in chapter['sections']}

chapters_expanded = {chapter['number']: False for chapter in self.zybooks_toc}
selected_sections = {(chapter['number'], section['number']): False for chapter in self.zybooks_toc for section in chapter['sections']}
draw_sections = lambda: self.draw_zybook_sections(chapters_expanded, selected_sections)
draw_sections()
section_callback = lambda context: self.select_zybook_sections_callback(chapters_expanded, selected_sections, context.data)
self.window.create_list_popup("Select zyBook Sections (use Back to finish)", callback=section_callback, list_fill=draw_sections)
res = []
for section_numbers, selected in selected_sections.items():
if selected:
if return_just_numbers:
res.append(section_numbers)
else:
res.append(self.zybooks_sections[section_numbers])
return res

0 comments on commit c189f0a

Please sign in to comment.