class Integrator(pyre.interface, family="gauss.integrators"): """ Interface declarator for integrators """ # access to the required interfaces from ..shapes import shape from ..functors import functor # required public state region = pyre.facility(interface=shape) region.doc = "the region of integration" integrand = pyre.facility(interface=functor) integrand.doc = "the functor to integrate" # my preferred implementation @classmethod def default(cls): # use {MonteCarlo} by default from .MonteCarlo import MonteCarlo return MonteCarlo # required interface @pyre.provides def integrate(self): """
class Homework(pyre.application): """ Grant repository access to the student's homework repositories """ # types from .interfaces import Course, Repository # public state course = pyre.facility(interface=Course) course.doc = 'the course whose materials are being served' student = pyre.properties.str() student.doc = 'the name of the student whose homework is being served' repository = pyre.facility(interface=Repository) repository.doc = 'the repository server' # interface @pyre.export def main(self, *args, **kwds): """ Serve the contents of some student's homework repository """ # get the path to the homework path = self.course.homework(student=self.student) # use it as the root for the repository self.repository.root = path # and the repository to serve its contents return self.repository.serve() # meta methods def __init__(self, name='homework', **kwds): super().__init__(name=name, **kwds) return
class RepositoryInitializer(pyre.application): """ Initialize the bzr repositories with the students' homework """ # types from .interfaces import Course, Repository # public state course = pyre.facility(interface=Course) course.doc = 'the course whose students are granted access' repository = pyre.facility(interface=Repository) repository.doc = 'the repository server' # interface @pyre.export def main(self, *args, **kwds): """ Initialize the student homework repositories """ # get the path to the student roll roll = self.course.roll() # get the path to the student homework repositories homework = self.course.homework() # each file corresponds to a student for filename in os.listdir(roll): # separate the name from the extension student, ext = os.path.splitext(filename) # skip files that are not public keys if ext != '.pub': continue # build the absolute path to repository repo = os.path.abspath(os.path.join(homework, student)) # if the directory exists and it is a directory, skip it if os.path.isdir(repo): continue # get the server to initialize this repository self.repository.initialize(repo) # all done return 0 # meta methods def __init__(self, name='init-repo', **kwds): super().__init__(name=name, **kwds) return
class Access(pyre.application): """ Build the authorized_keys file that grants limited access to the course directories """ # types from .interfaces import Course # public state course = pyre.facility(interface=Course) course.doc = 'the course whose students are granted access' # interface @pyre.export def main(self, *args, **kwds): """ Serve the contents of some student's homework repository """ # open the output file keys = open("roll.keys", "w") # build the command template command = ( 'command="/opt/pyre-1.0/bin/homework.py --student={}"' + ',no-port-forwarding,no-X11-forwarding,no-agent-forwarding {}') # write the keys to the file keys.writelines( command.format(student, key) for student, key in self.buildKey()) # close the file keys.close() # all done return 0 # meta methods def __init__(self, name='access', **kwds): super().__init__(name=name, **kwds) return # implementation details def buildKey(self): """ Return a student name and a key from the student's public key file """ # get the path to the student roll roll = self.course.roll() # for each file for filename in os.listdir(roll): # separate the name from the extension student, ext = os.path.splitext(filename) # skip files that are not public keys if ext != '.pub': continue # assemble the path to the key file keyfile = os.path.abspath(os.path.join(roll, filename)) # read the student's public key file for key in open(keyfile, "r"): # build the associated authorization yield student, key # all done return
class MonteCarlo(pyre.component, family="gauss.integrators.montecarlo", implements=Integrator): """ A Monte Carlo integrator """ # public state samples = pyre.properties.int(default=10**5) samples.doc = "the number of integrand evaluations" box = pyre.facility(interface=shape, default=box) box.doc = "the bounding box for my mesh" mesh = pyre.facility(interface=cloud) mesh.doc = "the generator of points at which to evaluate the integrand" region = pyre.facility(interface=shape, default=ball) region.doc = "the shape that defines the region of integration" integrand = pyre.facility(interface=functor) integrand.doc = "the functor to integrate" # interface @pyre.export def integrate(self): """ Compute the integral as specified by my public state """ # compute the overall normalization normalization = self.box.measure() / self.samples # get the set of points points = self.mesh.points(n=self.samples, box=self.box) # select the points interior to the region of integration interior = self.region.interior(points) # sum up and scale the integrand contributions integral = normalization * sum(self.integrand.eval(interior)) # and return the value return integral
class Quad(pyre.application): """ A harness for {gauss} integrators """ # public state samples = pyre.properties.int(default=10**5) integrator = pyre.facility(interface=gauss.integrator) # required interface @pyre.export def main(self, *args, **kwds): # pass the requested number of samples to the integrator self.integrator.samples = self.samples # get it to integrate integral = self.integrator.integrate() # print the answer print("integral = {}".format(integral)) # return success return 0 @pyre.export def main_mpi(self, *args, **kwds): # access the mpi package import mpi # find out how many tasks were launched size = mpi.world.size # find out my rank rank = mpi.world.rank # figure out how many samples to do and pass that on to my integrator self.integrator.samples = self.samples / size # integrate: average the estimates produced by each task integral = mpi.sum(self.integrator.integrate()) / size # node 0: print the answer if rank == 0: print("integral = {}".format(integral)) # all done return 0
class PostAssignment(pyre.application): """ Grant repository access to the student's homework repositories """ # types from .interfaces import Course, Repository # public state course = pyre.facility(interface=Course) course.doc = 'the course whose materials are being served' repository = pyre.facility(interface=Repository) repository.doc = 'the repository server' students = pyre.properties.tuple() students.doc = 'the names of the students whose repository is being modified' assignment = pyre.properties.str() assignment.doc = 'the name of the assignment' due = pyre.properties.str() due.doc = 'the due date of the assignment' # interface @pyre.export def main(self, *args, **kwds): """ Post the assignment """ # locate the assignment pdf file pdf = os.path.join(self.course.webContent(), '{}-hw-{}.pdf'.format(self.course.name, self.due)) print("pdf: {!r}".format(pdf)) # locate the source of the assignment assignmentSource = self.course.assignmentSource( assignment=self.assignment) print("assignment source: {!r}".format(assignmentSource)) # iterate over the selected students for student in self.selectedStudents(): # get the root of the student homework repository root = self.course.homework(student) print(" -- posting at {!r}".format(root)) # if the repository doesn't exist if not os.path.isdir(root): # initialize it self.repository.initialize(root) # bring the tree up to date self.repository.update(root) # construct the name of the assignment directory directory = os.path.join(root, 'assignment-{}'.format(self.assignment)) # if it doesn't exist if not os.path.isdir(directory): # create it os.mkdir(directory) # copy the assignment pdf here shutil.copy2(pdf, directory) # copy the sources for name in os.listdir(assignmentSource): # form the absolute path to the source file srcName = os.path.join(assignmentSource, name) # and the absolute path to the destination dstName = os.path.join(directory, name) # if the source is a directory if os.path.isdir(srcName): # copy its entire contents shutil.copytree(srcName, dstName) # otherwise else: # copy the file over shutil.copy2(srcName, dstName) # ask the server to add this directory to the repository self.repository.add(directory) # and to commit it self.repository.commit(path=directory, message='posted assignment {}'.format( self.assignment)) print(" -- done posting at {!r}".format(root)) return 0 # meta methods def __init__(self, name='hw-post', **kwds): super().__init__(name=name, **kwds) return # implementation details def selectedStudents(self): """ Generate the list of affected students """ # if we were asked to process all students if self.students == ('all', ): # otherwise, get the path to the student roll roll = self.course.roll() # each file corresponds to a student for filename in os.listdir(roll): # separate the name from the extension student, ext = os.path.splitext(filename) # skip files that are not public keys if ext != '.pub': continue # yield the student name yield student # all done return # if we were given an explicit list if self.students: # iterate over it for student in self.students: yield student # and no more return # otherwise, do nothing return
class user(pyre.component, family="deferred.user"): """a component user""" comp = pyre.facility(protocol=ifac)
class MissingRepositories(pyre.application): """ Identify the students with no homework repository """ # types from .interfaces import Course # public state course = pyre.facility(interface=Course) course.doc = 'the course whose materials are being served' # interface @pyre.export def main(self, *args, **kwds): """ Post the assignment """ # locate the enrolled students enrolled = set(self.roll()) # locate the ones that have homework repositories repos = set(self.repositories()) # compute the difference missing = enrolled - repos # if any were missing if missing: # print the names as a comma separated list print(','.join(missing)) # all done return 0 # meta methods def __init__(self, name='hw-missing', **kwds): super().__init__(name=name, **kwds) return # implementation details def repositories(self): """ Generate the list of enrolled students """ # otherwise, get the path to the student roll homework = self.course.homework() # each directory corresponds to a student for student in os.listdir(homework): # form the repository path repo = os.path.abspath(os.path.join(homework, student)) # if it's not a directory, skip it if not os.path.isdir(repo): continue # yield the student name yield student # all done return def roll(self): """ Generate the list of enrolled students """ # otherwise, get the path to the student roll roll = self.course.roll() # each file corresponds to a student for filename in os.listdir(roll): # separate the name from the extension student, ext = os.path.splitext(filename) # skip files that are not public keys if ext != '.pub': continue # yield the student name yield student # all done return
class CreateProjectDirectory(pyre.application): """ Grant repository access to the student's homework repositories """ # types from .interfaces import Course, Repository # public state course = pyre.facility(interface=Course) course.doc = 'the course whose materials are being served' repository = pyre.facility(interface=Repository) repository.doc = 'the repository server' students = pyre.properties.tuple() students.doc = 'the names of the students whose repository is being modified' dry = pyre.properties.bool(default=False) dry.doc = 'dry run' # interface @pyre.export def main(self, *args, **kwds): """ Create the project directory """ # print out the state print(' * {.pyre_name}:'.format(self)) print(' students: {}'.format(self.students)) print(' repository: {}'.format(self.repository.pyre_name)) print(' family: {}'.format( self.repository.pyre_getFamilyName())) print(' executable: {}'.format(self.repository.executable)) print(' root: {}'.format(self.repository.root)) print(' course: {}'.format(self.course.pyre_name)) print(' family: {}'.format(self.course.pyre_getFamilyName())) print(' term: {}'.format(self.course.term)) print(' home: {}'.format(self.course.home)) print(' source: {}'.format(self.course.source)) if self.dry: return # iterate over the selected students for student in self.selectedStudents(): # get the root of the student homework repository root = self.course.homework(student) print(" -- creating project directory at {!r}".format(root)) # if the repository doesn't exist if not os.path.isdir(root): # initialize it self.repository.initialize(root) # bring the tree up to date self.repository.update(root) # construct the name of the project directory directory = os.path.join(root, 'project') # if it doesn't exist if not os.path.isdir(directory): # create it os.mkdir(directory) # ask the server to add this directory to the repository self.repository.add(directory) # and to commit it self.repository.commit(path=directory, message='created project directory') print(" -- done creating project directory at {!r}".format(root)) return 0 # meta methods def __init__(self, name='project-init', **kwds): super().__init__(name=name, **kwds) return # implementation details def selectedStudents(self): """ Generate the list of affected students """ # if we were asked to process all students if self.students == ('all', ): # otherwise, get the path to the student roll roll = self.course.roll() # each file corresponds to a student for filename in os.listdir(roll): # separate the name from the extension student, ext = os.path.splitext(filename) # skip files that are not public keys if ext != '.pub': continue # yield the student name yield student # all done return # if we were given an explicit list if self.students: # iterate over it for student in self.students: yield student # and no more return # otherwise, do nothing return