Code Monkey home page Code Monkey logo

autograder's Introduction

AutoGrader

A Python based AutoGrader for Python Assignments.

Introduction

This system is developed for FAST-NUCES Peshawar Campus for the handling of student assignments. This system provide auto grading functionality for the students submission and generate submission reports for the instructor.

Functionality

  1. Admin, Instructor and Student accounts
  2. Course with unique enroll key
  3. Assignments with test and assignment file
  4. Assignment Submission Report (based on the latest submission)
  5. Student Account: Password Recovery, Submission Password, Submission Score and Submission Log

Prerequisites

Check requirements.txt for the prerequisites packages. You can install requirment package using following command:

cd AutoGrader/
pip install -r requirements.txt

Installing

For the installation first grab the latest source from the GitHub

git clone [email protected]:BilalZaib/AutoGrader.git
cd AutoGrader/

Edit settings.py of Django

cd AutoGr/
mv settings-sample.py settings.py
vi settings.py
cd ../

Note: You have to add secret key and SMTP detail in this file. You can generate Django secret key from any online website.

Setting up super user for Django

python manage.py migrate
python manage.py createsuperuser
python manage.py runserver

Now go to http://127.0.0.1:8000/admin to logon to the system.

Getting into system?

  1. After the installation admin user can logon to the system.
  2. Admin can create the Instructor, set him as "is_staff" and assign the permissions for example Assignment (All), Course (View only), Student (All) and Submission (All).
  3. After the creation of instructor, instructor will logon to his account.
  4. Instructor will create Assignment and share enroll key with students.
  5. Student will register to the system from http://127.0.0.1:8000/autograder
  6. Student will logon to the system and enter the enroll key to enroll into the course.
  7. Student will select the course, then assignment and then follow the instruction written on that page.

How system works?

Instructor uploads three files with Assignment which is assignment_file, instructor_test_file and student_test_file. Student will have to write code in assignment_file and it will be tested against student_test_file for student and after the submission to server the assignment_file will be tested againts instructor_test_file and submission will be stored with score in the database.

Deployment

Currently this system is used on a dedicated server located in the university with PostgresSQL database. Step for installation are same as the above.

Built With

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

Authors

  • Hafiz M. Bilal Zaib - Initial coding - BilalZaib
  • Mohammad Nauman - Design and requirement gathering - recluze
  • Syed Owais Ali Chishti - Funtionality integrations - soachishti

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE.md file for details

Acknowledgments

Note

There are no sandboxing mechanism in this system, however auto backups and system permission are used for now.

autograder's People

Contributors

bilalzaib avatar recluze avatar soachishti avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

autograder's Issues

Other files field in assignment

Need to have another field for "other_files" ... this can be multiple files ... for instance for adding a PDF or extra .py files which are needed for assignment.

Show late days details to students

We need to show a late days used to the students on their course dashboard. Following fields should be sufficient.

Date     Days Used    Assignment 

Assignment Reports

Been thinking that we can make the autograder demo look very good by adding some simple reports.

Some that come to mind are:

  1. Course report that has assignments on x-axis and number of submissions on the y-axis. So we know how many submissions were made for each assignment (since we already have some great students who fail to even submit ...)

  2. Same as above but the average score on the y-axis.

  3. Aggregate marks with averages and standard deviations. Similar to what we have on Neon but aggregates only ... not for each assignment.

This is all low priority. Let me know if you guys want to add another TA to this coding effort so that we can delegate some of this to them. I will relieve them of other grunt work duties if they want to do this instead.

Remove student form "get_student_latest_submissions" tuple

When get_student_latest_submissions called from Assignment instance. Then it returns [(submission, student1)...]. Technically it should return submissions only. Lately I was added for report section but now it is getting confusing.

Task:

  1. Remove student from get_student_latest_submissions returned tuple
  2. Update report section
  3. Update moss_submit, It uses get_student_latest_submissions.
  4. Check if get_student_latest_submissions is used anywhere else.

Assignments for different course can be submitted

Scenario: StudentA registers for CourseA which has AssignmentA. StudentB registers for CourseB which has AssignmentB.

StudentB downloads AssignmentB.

StudentA takes StudentB's downloaded file and tries to submit with it.

End result: AssignmentB submitted successfully by StudentA but does not show up in the Assignment Report (or submission history).

Resolution: Check during assignment submission that student is registered in the course to which the submitted assignment belongs.

Separate settings file for prod

Since it's a (really really) bad idea to publish our credentials on a public repo such as Github, we need to create a separate file for prod. In this file, we can put creds (and settings) that will be specific to prod. Then, this needs to be included in the settings.py.

Create this file in the same folder as settings.py and import. Commit the prod settings file once (while it's empty) and then never commit it (or do this: https://stackoverflow.com/questions/4114163/how-to-tell-git-to-ignore-all-further-edit-to-a-single-file-without-removing-it)

Please change the outlook password for the autograder sender email and send me through email. I will update the settings file in prod with it. I believe there is also a secret key or something in the settings that needs to be hidden. Also, send me that and any other things that should be hidden.

Exception in Add Assignment

Logged in as "nauman".

Clicked on "Add" under assignments.

Got this exception:

class AssignmentFormAdmin(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(AssignmentFormAdmin, self).__init__(*args, **kwargs)
        instance = kwargs['instance'] ...
        instructor = instance.course.instructor
        self.fields['course'].queryset = Course.objects.filter(instructor=instructor)

With exception:

KeyError
'instance'

For line 4.

Assignment folder name in uploads

The assignment folder name in uploads folder is problematic. Since it's called as "assignment title" with spaces replaced with -, we need the titles to be unique (and there is no check there for uniqueness).

So, we either need to change the folder path to course_id/assignment_id/ or put a check for uniqueness in the title (this one should be easier I think but only if we make a composite key on course and assignment title since we can have the same name in different courses). Not sure. You can think about it.

Module missing in requirements.txt

@bilalzaib You added a module's usage in the lastest commit. Please add that to requirements.txt so that we know it's needed when deploying. I brought down prod due to the missing dependency just now =]

MOSS report doesn't seem to be working

I've given your user on Prod staff access. Please see /autograde/assignment_report/14. Assignments for p176011 p176035 p176001 and p176031 are obviously copied but MOSS returns nothing. Is it a limitation of MOSS or something wrong on our end?

(Haven't seen any non-empty MOSS report till now.)

View Assignment for Instructor

The assignment view (as seen by students) should also be visible to the instructor so that any problems in the view can be identified.

Think we only need to put some ifs in the view assignment page to remove student email, submission password and submission history. Rest should be ok as is.

Let's make this high priority.

Conflict Issues

I am getting conflict every time I pull the code. Most of my commit are lost.

Kindly create a branch before making changes to the code.

We will then merge those branch back to the master branch. That is the solution which I can suggest now.

Let me know if there is any other better solution.

I am using GitKraken for conflict resolution.

NOTE: DO NOT PUSH YOUR CHANGES TO MASTER NOW

Resent Email Verification for Sign Up and Reset Password

SIGN UP - Email Verification
When user sign up for account then verification email is sent to their email account. But there are cases when; email are not received or they are delayed.

We can handle this like these:
Let the user "Login" after sign up without email verification. But user will get message on their screen to Verify their Email with these two options: "Resend email" or "Change Email". Without "Email Verification" student will not be able to submit their assignment. They will get "ERROR: Validate email first" when submitting assignments.

RESET PASSWORD - Email Verification
When user request for reset password, user is shown with "Email is sent" but there should be option of "Resent Email".

Autograder CL Utils

Create a set of utility functions which can be used in run.py and tests. This is aimed to clean up the code that is in these files and to ensure ease of updates.

This is also to be released in Pypy for easy deployment.

Detecting similarity.

If we can integrate MOSS (http://theory.stanford.edu/~aiken/moss/) with the autograder, it should be fantastic.

(Also, since I don't see a python submission script on their page, if you can provide one, you might get your name on the Stanford page which would be a good cred to have.)

The way I see this working is: after the due date has passed and the instructor is viewing the report, they can click on "Analyze for similarity" button at the bottom of report. The call would collect all assignment files (rename them as a01-p117878.py and a01-p119898.py i.e. append student ID to make files unique.

Then, it would package and submit to MOSS and set status as "running report". Once we have the report from MOSS (I believe it's HTML), we can show it to the instructor.

This would be one of those things that you can do whenever you have time. Low priority at the moment.

Bug in password reset page

Enter a valid email on password reset page to get this error: Invalid block tag on line 12: 'endautoescape'. Did you forget to register or load this tag?.

Course Student List View and Unenroll Student

We need a view for each course that shows all enrolled students. Next to each student's row, we need a link that says "Unenroll Student". This is to remove students incorrectly enrolled in wrong sections.

s = Student.objects.get(id=[STUDENT_ID])
c = c = Course.objects.get(id=[COURSE_ID]) 
s.courses.remove(c)
s.save() 

@soachishti I'll be assigning issues to you. You can pass them on to whoever is suitable.

Backup script for backing up code and db together

We're on PostgresSQL on prod.

We need a script that will take the whole db's dump and put it in a file (timestamped). Then, it will also get the current code and put that in a zip file along with the db dump (again, timestamped). Then, upload it somewhere off-site where we can only do writes and no deletes.

Missing requirements

Bootstrap3 is missing from requirements.txt. Python 3.8.1 is used, with virtualenv.

After installing requirements, bootstrap is missing when trying to run any command. Solution is easy, simply run the command pip install django-bootstrap3. Please, include this dependency in requirements.txt

Python version

Are we running on Python3?

We're following python2 in class so it would be better if we change to python2. Don't think it should be that big of a problem since django would support both, no?

Apologies for not mentioning this earlier.

run_test in grader.py not writing anything in log file

def run_test(out_file, target_folder, timeout):
    # chdir in main process create issue for django
    logger.debug("Changing directory ... ")
    cur_directory = os.getcwd()
    os.chdir(target_folder)
    with open(out_file, 'w') as f:
        old_stdout = sys.stdout 
        old_stderr = sys.stderr 
        sys.stdout = f
        sys.stderr = f
        import pytest
        pytest.main(['--timeout=' + str(timeout)])
        sys.stdout = old_stdout  
        sys.stderr = old_stderr 
    logger.debug("Restoring working directory ...")
    os.chdir(cur_directory)

this function is not writing anything it is giving error res_line = out.splitline()[-1] is out of index after debugging, I got that if we insert a print statement after an import pytest it is writing the same thing in file with an error message. please help.
@bilalzaib @recluze @soachishti
please help guys

Course student stats

This is another report that we need. This one is much more important so has the highest priority among reports at the moment. Whoever is doing reports needs to do this one first (or next if already working on one).

We need a report for each course. There should be a link in the course admin page (similar to "show report" in the assignments admin page) called "Student Stats". This opens up a new page similar to assign report view. In this, we need to do the following:

For all students registered in this course, we need the following fields:

No.
Student (comes from student.str)
Roll number
Assignments completed (total number -- a completed assignment is one with at least one submission)
Late days remaining
Average marks (in percentage since scores might be different for each assignment)
Average number of submissions (so, total number of submissions / assignments completed)
Average time taken (time taken for an assignment is last submission time - open date time .. then we average over the whole course)

If you can think of another field, please comment so we can discuss.

Has to be done with a separate views file and not in the main views.py file.

@soachishti Please assign forward to whoever is relevant.

Getting Started

【 highlighted #e2bb00 】Join an Onboarding Session【 end highlighted 】

We've found the quickest way to get familiar with Wrike is to attend this intro session, where you'll learn about essential features, best practices, and tips & tricks.

What you will learn:

  • How to organize your work by applying a framework of Projects, Folders, Tasks.
  • How to collaborate and share with your team in Wrike and why it's important.
  • How to generate Reports on Projects and Tasks.
  • Best practices for new Wrike users (that's you!).

Register Today!

【 highlighted #e2bb00 】Learn Now【 end highlighted 】

While you're waiting to attend the session, here are some basic lessons to help you get started on your own. Check the box next to each item when you finish and just like that, you've already learned how to use the checklist.

  • Navigate your work

  • Get familiar with your new Workspace.

  • Watch Tutorial Video [3:57]

  • Collaborate with your team

  • Communicate clearly with your team while keeping your work front and center.

  • Watch Tutorial Video [4:14]

  • Arrange your work

  • Manage your work with Projects, Folders, and Tasks.

  • Watch Tutorial Video [3:53]

【 highlighted #e2bb00 】Reference Guides【 end highlighted 】

Here are some documents and websites that will benefit you on your journey:

【 highlighted #e2bb00 】Discover More Anytime【 end highlighted 】

Wrike experts are here to make sure you're getting the most out of the tool, check out the links below.

Add course "course-id" field too small

Currently it's length is set to 6 characters. This needs to be a lot longer so that we can put, for instance ... cs101-f17-a (plus a few more characters just in case).

BTW, I've moved to postgres on GPU machine and it's working fine.

Remote test failure on prod

Pulled the SMTP code and email verification is working well. However, remote submission caused this error:

(2017-09-05 14:44:12; grader.py:72) DEBUG:AutoGrade.grader: Running student tests in: uploads/submission/student_2/assignment_1/2017-09-05-144412_submission/
(2017-09-05 14:44:12; grader.py:79) DEBUG:AutoGrade.grader: Capturing stdout
(2017-09-05 14:44:12; grader.py:85) DEBUG:AutoGrade.grader: Starting test process for submission
(2017-09-05 14:44:12; grader.py:48) DEBUG:AutoGrade.grader: Changing directory ...
(2017-09-05 14:44:12; exception.py:135) ERROR:django.request: Internal Server Error: /autograde/api/submit_assignment
Traceback (most recent call last):
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/views.py", line 291, in api
    score, outlog = run_student_tests(extract_directory, assignment.total_points, assignment.timeout)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/grader.py", line 86, in run_student_tests
    p.start()
  File "/usr/lib64/python2.7/multiprocessing/process.py", line 130, in start
    self._popen = Popen(self)
  File "/usr/lib64/python2.7/multiprocessing/forking.py", line 127, in __init__
    sys.stdout.flush()
ValueError: I/O operation on closed file
(2017-09-05 14:44:12; exception.py:135) ERROR:django.request: Internal Server Error: /autograde/api/submit_assignment
Traceback (most recent call last):
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/views.py", line 291, in api
    score, outlog = run_student_tests(extract_directory, assignment.total_points, assignment.timeout)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/grader.py", line 86, in run_student_tests
    p.start()
  File "/usr/lib64/python2.7/multiprocessing/process.py", line 130, in start
    self._popen = Popen(self)
  File "/usr/lib64/python2.7/multiprocessing/forking.py", line 127, in __init__
    sys.stdout.flush()
ValueError: I/O operation on closed file
(2017-09-05 14:44:12; exception.py:135) ERROR:django.request: Internal Server Error: /autograde/api/submit_assignment
Traceback (most recent call last):
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/views.py", line 291, in api
    score, outlog = run_student_tests(extract_directory, assignment.total_points, assignment.timeout)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/grader.py", line 86, in run_student_tests
    p.start()
  File "/usr/lib64/python2.7/multiprocessing/process.py", line 130, in start
    self._popen = Popen(self)
  File "/usr/lib64/python2.7/multiprocessing/forking.py", line 127, in __init__
    sys.stdout.flush()
ValueError: I/O operation on closed file
(2017-09-05 14:44:12; basehttp.py:124) ERROR:django.server: "POST /autograde/api/submit_assignment HTTP/1.1" 500 91233
(2017-09-05 14:44:12; basehttp.py:124) ERROR:django.server: "POST /autograde/api/submit_assignment HTTP/1.1" 500 91233
(2017-09-05 14:44:12; exception.py:135) ERROR:django.request: Internal Server Error: /autograde/api/submit_assignment
Traceback (most recent call last):
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/views.py", line 291, in api
    score, outlog = run_student_tests(extract_directory, assignment.total_points, assignment.timeout)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/grader.py", line 100, in run_student_tests
    res_line = out.splitlines()[-1]
IndexError: list index out of range
(2017-09-05 14:44:12; exception.py:135) ERROR:django.request: Internal Server Error: /autograde/api/submit_assignment
Traceback (most recent call last):
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/views.py", line 291, in api
    score, outlog = run_student_tests(extract_directory, assignment.total_points, assignment.timeout)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/grader.py", line 100, in run_student_tests
    res_line = out.splitlines()[-1]
IndexError: list index out of range
(2017-09-05 14:44:12; exception.py:135) ERROR:django.request: Internal Server Error: /autograde/api/submit_assignment
Traceback (most recent call last):
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/sys-autograder/autograder/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/views.py", line 291, in api
    score, outlog = run_student_tests(extract_directory, assignment.total_points, assignment.timeout)
  File "/home/sys-autograder/autograder/AutoGrader/AutoGrade/grader.py", line 100, in run_student_tests
    res_line = out.splitlines()[-1]
IndexError: list index out of range
(2017-09-05 14:44:12; basehttp.py:124) ERROR:django.server: "POST /autograde/api/submit_assignment HTTP/1.1" 500 83851
(2017-09-05 14:44:12; basehttp.py:124) ERROR:django.server: "POST /autograde/api/submit_assignment HTTP/1.1" 500 83851
(2017-09-05 14:44:12; basehttp.py:78) INFO:django.server: - Broken pipe from ('121.52.146.103', 53516)

(2017-09-05 14:44:12; basehttp.py:78) INFO:django.server: - Broken pipe from ('121.52.146.103', 53516)

And the test-results.log file in submission directory for this submission is completely empty.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.