on perhaps unloading modules?

Hope Rouselle hrouselle at jevedi.com
Sun Aug 15 11:09:58 EDT 2021


Hope Rouselle <hrouselle at jevedi.com> writes:

[...]

> Of course, you want to see the code.  I need to work on producing a
> small example.  Perhaps I will even answer my own question when I do.

[...]

Here's a small-enough case.  We have two students here.  One is called
student.py and the other is called other.py.  They both get question 1
wrong, but they --- by definition --- get question 2 right.  Each
question is worth 10 points, so they both should get losses = 10.

(*) Student student.py

--8<---------------cut here---------------start------------->8---
def question1(t): # right answer is t[2]
  return t[1] # lack of attention, wrong answer
--8<---------------cut here---------------end--------------->8---

(*) Student other.py

--8<---------------cut here---------------start------------->8---
def question1(t): # right answer is t[2]
  return t[0] # also lack of attention, wrong answer
--8<---------------cut here---------------end--------------->8---

(*) Grading

All is good on first run.

Python 3.5.2 [...] on win32
[...]
>>> reproducible_problem()
student.py, total losses 10
other.py, total losses 10

The the problem:

>>> reproducible_problem()
student.py, total losses 0
other.py, total losses 0

They lose nothing because both modules are now permanently modified.

(*) The code of grading.py

--8<---------------cut here---------------start------------->8---
# -*- mode: python; python-indent-offset: 2 -*-
def key_question1(t): 
  # Pretty simple.  Student must just return index 2 of a tuple.
  return t[2]

def reproducible_problem(): # grade all students
  okay, m = get_student_module("student.py")
  r = grade_student(m)
  print("student.py, total losses", r) # should be 10
  okay, m = get_student_module("other.py")
  r = grade_student(m)
  print("other.py, total losses", r) # should be 10

def grade_student(m): # grades a single student
  losses  = question1_verifier(m)
  losses += question2_verifier(m)
  return losses

def question1_verifier(m):
  losses = 0
  if m.question1( (0, 1, 2, 3) ) != 2: # wrong answer
    losses = 10
  return losses

def question2_verifier(m):
  m.question1 = key_question1
  # To grade question 2, we overwrite the student's module by giving
  # it the key_question1 procedure.  This way we are able to let the
  # student get question 2 even if s/he got question 1 incorrect.
  losses = 0
  return losses 

def get_student_module(fname): 
  from importlib import import_module
  mod_name = basename(fname)
  try:
    student = import_module(mod_name)
  except Exception as e:
    return False, str(e)
  return True, student

def basename(fname): # drop the the .py extension
  return "".join(fname.split(".")[ : -1])
--8<---------------cut here---------------end--------------->8---


More information about the Python-list mailing list