-
Notifications
You must be signed in to change notification settings - Fork 317
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Late penalty plugin #512
Late penalty plugin #512
Conversation
add late submission penalty to SubmittedAssignment dict repr
@jhamrick this is what I've come up with so far (still a bit to add), let me know what you think. |
This is really awesome! I'm super excited about this 🎉 I do wonder though if we want to necessarily define a custom plugin loader class, rather than relying on traitlets' built-in functionality. With traitlets, you can define class variables so that instances of the class are loaded, and the type of that instance is configurable. A good example is in nbconvert, where things like the writer and postprocessor are configurable instances: https://github.com/jupyter/nbconvert/blob/master/nbconvert/nbconvertapp.py#L181 e.g. for the writer: # Writer specific variables
writer = Instance('nbconvert.writers.base.WriterBase',
help="""Instance of the writer class used to write the
results of the conversion.""", allow_none=True)
writer_class = DottedObjectName('FilesWriter', config=True,
help="""Writer class used to write the
results of the conversion""")
writer_aliases = {'fileswriter': 'nbconvert.writers.files.FilesWriter',
'debugwriter': 'nbconvert.writers.debug.DebugWriter',
'stdoutwriter': 'nbconvert.writers.stdout.StdoutWriter'}
writer_factory = Type(allow_none=True)
def _writer_class_changed(self, name, old, new):
if new.lower() in self.writer_aliases:
new = self.writer_aliases[new.lower()]
self.writer_factory = import_item(new) this will by default use the I have a few smaller comments that I'll leave inline, too. |
@@ -126,6 +126,9 @@ span.nbgrader-label { | |||
<li><a href="#comment-{{ cell.metadata.nbgrader.grade_id }}">Comment</a></li> | |||
{% endif %} | |||
{% endfor %} | |||
{% if resources.nbgrader.late_penalty %} | |||
<li style="color: #d2413a;">Late submission penalty (Score: -{{ resources.nbgrader.late_penalty | float | round(2) }})</li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This li
tag should probably be given a class and then define the color using that class in the CSS at the top of the page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Did this just to quickly test it.
This makes sense. I'll definitely look into it. |
No problem, and yeah, the traitlets stuff can be pretty confusing. I remember being incredibly confused when I was first learning about it maybe a year ago. There's at least a bit more documentation now than there was then! These links might also be helpful, and definitely let me know if you have any questions...
Note that nbgrader still has some of the traitlets 4.0 syntax, while there was new syntax introduced in 4.1: http://traitlets.readthedocs.io/en/stable/migration.html which reminds me, I should open an issue to remind myself to migrate the traitlets stuff! |
Aha, I also tracked down an example of using the https://github.com/jupyter/nbgrader/blob/master/nbgrader/apps/formgradeapp.py#L78 This one is a little different (and simpler) from the writer example. I'm actually not totally sure why the writer example is so complicated, as it is possible to also pass just the string of a class name for |
still keep late_penalty in feedback
@jhamrick I still need to add tests to check this, but it seemed rather easy to utilize traitlets as you suggested. |
|
||
class LateSubmissionPlugin(BasePlugin): | ||
|
||
penalty_method = Unicode( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an enum trait type which might be good to use here to ensure user typos throw an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks :) I was looking for the best way to do this validation.
👍 This looks great! Let me know when you are ready for me to review the tests and docs. |
@jhamrick ready for review. |
Just wanted to say really quickly that I think this looks great -- I've skimmed over it and will have a longer look at it on Monday (I am about to leave for a conference in Singapore, so I'll be offline for the rest of the weekend). |
Another quick update -- so sorry that I haven't had time to finish the review for this. I am definitely going to try to get to it this week (hopefully tomorrow)! |
No worries. I have been swamped with work lately, so probably would not have been able to get round to any updates had you done it earlier :P |
@@ -9,6 +9,17 @@ | |||
from .. import run_nbgrader | |||
from .base import BaseTestApp | |||
|
|||
PLUGIN = """ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is only used in one place, I would define it in the function where you use it rather than having it be a global variable.
This looks really great. I only have the one comment about that plugin variable -- if you address that then I'll merge! Looks like this will make it in to the 0.3.0 release, too 😄 |
Awesome :D |
Done |
Framework for loading plugin functions.
Adds enhancement for #233
TODO list from the discussions below: