Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@drexel-uxid/hw-admin

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@drexel-uxid/hw-admin

This repo will serve as the admin side of the homework system. This repo should remain private so that the questions and answers remain private as well.

  • 0.1.0
  • unpublished
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
 
Created
Source

UXID Homework Admin API

This repo will serve as the admin side of the homework system. This repo should remain private so that the questions and answers remain private as well.

Contributions are welcome! Please read the How To Contribute section.

Function

In order to keep the questions and answers private from the students, this project will serve as an API to communicate with the students' frontend.

This API will do a few things when communicating with the frontend:

  • Send available classes and assignments
  • Check answers in a more robust way
  • Generate a submission receipt for students
  • Validate those submissions via URL check

Definitions

TERMDEFINITION
CourseThe class for which this assignment is for, e.g. idm222.
AssignmentA topic that contains numerous exercises within, e.g. Assignment 1: Media Queries.
ExerciseA single problem in an assignment that has instructions and a solution.

Routes Neeed

All routes should follow REST standard pattern of /collection/item/collection/item...

  • ✅ GET courses
    • /api/courses
  • ✅ GET assignments
    • /api/courses/COURSE_ID/assignments
  • ✅ GET assignment
    • /api/courses/COURSE_ID/assignments/ASSIGNMENT_ID
  • ✅ GET exercises
    • /api/courses/COURSE_ID/assignments/ASSIGNMENT_ID/exercises
  • ✅ POST answer check
    • /api/courses/COURSE_ID/assignments/ASSIGNMENT_ID/exercises/EXERCISE_ID
  • ✅ POST submission
    • /api/courses/COURSE_ID/assignments/ASSIGNMENT_ID/submissions
  • ✅ GET check valid student in course
    • /api/courses/COURSE_ID/students/STUDENT_ID
  • ✅ POST exercise feedback
    • /api/courses/COURSE_ID/assignments/ASSIGNMENT_ID/exercises/EXERCISE_ID/feedback

How To Contribute

Please follow these steps to contribute to this repository.

  • Follow steps in the Getting Started section to get this project running locally.
    • Feel free to set up the student frontend locally too if you'd like to see your changes in action.
  • Before making changes, start a new branch with a descriptive title git checkout -b my-new-feature.
  • Make your changes
  • When committing, this project will automatically check for errors. Your commit won't succeed without fixing those errors.
  • Once all errors are resolved, push changes to open a pull request: git push origin branch-name-I-just-created.
  • Optional but highly recommended, request a review from Mike Carbone or another admin to make sure everything looks good.
  • Squash and merge

How to write a homework exercise

Background

When creating this system, we wanted to add flexibility to the way we create exercises. Previously, all answers were checked by doing a 1:1 string comparison, and if any character was different between the submitted answer and the solution, the submitted answer was flagged as incorrect. For simple exercises that only have one correct answer, this works fine. However, sometimes exercises require more complex answers that can have more than one right answer.

Take, for example, this exercise:

I have three images: icon_large.png, icon_medium.png, and icon_small.png.

All three of the images are in a directory named "ui" that is at the same level as the current HTML document. If the browser is at least 800px wide, icon_large.png should load. If the browser is at least 500px wide, icon_medium.png should load. If neither of those conditions are met, icon_small.png should load. The image should include an alt tag equal to "IDM Logo"

Program a picture element that loads the desired image based on these rules.

Note: media query width values should be expressed in rem units. You can assume the root element font size is set to 100%, > and the user has not changed the default preferences.

That question would require this answer:

<picture>
  <source media="(min-width: 50rem)" srcset="ui/icon_large.png" />
  <source media="(min-width: 31.25rem)" srcset="ui/icon_medium.png" />
  <img src="ui/icon_small.png" alt="IDM Logo" />
</picture>

Very few students were able to get this exercise correct because of the various ways we can produce this same markup. For example, writing the alt attribute before the src attribute is valid HTML, but the submitted answer would be determined as incorrect because the strings didn't align. Additionally, students were given no hints, and it was often difficult to tell what might be incorrect in their submitted answer.

So, this required some rethinking of the way we check answers.

The New Way (Technical Details)

Now, instead of always doing a 1:1 string comparison, we have the ability to create more flexible exercises using tree representations of our solutions.

This starts by creating an exercise in the appropriate assignment folder.

{
  id: 4,
  instructions:
    '<p>Write the optimal <code>meta</code> tag that tells an HTML document your page is mobile friendly. Here\'s the template, type the entire template and include the missing values in your answer.</p><p><pre>&lt;meta name="_______" content="width=_______, _______=1.0"&gt;</pre></p>',
  solution: '<meta name="viewport" content="width=device-width, initial-scale=1.0"/>',
  type: AnswerTypes.Textarea,
  rows: 1
}

This exercise above will perform a 1:1 string comparision using the provided solution, because it has omitted the complexCheck key. However, if we want to use a tree check to allow flexibility, we can include a complexCheck key that includes instructions for how we want to check this exercise:

{
  id: 4,
  instructions:
    '<p>Write the optimal <code>meta</code> tag that tells an HTML document your page is mobile friendly. Here\'s the template, type the entire template and include the missing values in your answer.</p><p><pre>&lt;meta name="_______" content="width=_______, _______=1.0"&gt;</pre></p>',
  solution: '<meta name="viewport" content="width=device-width, initial-scale=1.0"/>',
  type: AnswerTypes.Textarea,
  rows: 1,
  complexCheck: {
      // What language is the solution in? Tells the system which parser to use
      solutionLanguage: LanguageTypes.HTML,

      // Function to run some checks on the submitted attempt
      // this function must be async
      checkFunction: async ({ check, successfulResponse, solutionTree }) => {

        // We can see our solution in tree-form with console.log
        console.log(solutionTree);

        await check({

          // Describe this test
          description: 'Ensure the tag is <meta />'

          // `objectPath` will be a path down the solutionTree to get to a value
          // Similar to dot notation, this uses lodash's `get` method under the hood https://www.geeksforgeeks.org lodash-_-get-method/
          // This will ensure the value from the attemptTree is equal to the value in the solutionTree
          objectPath: '0.tag', // can also be an array ['0', 'tag']

          // Add an optional hint for this check
          hint: "Make sure you use the right tag name."
        })

        // Write more checks here...

        // Always end with returning a successfulResponse
        return successfulResponse
    }
  }
}

Additionally, we can get even more flexible and pass our own condition. If the condition key is present, the normal value comparison outlined above won't trigger. The condition function must return a boolean.

complexCheck: {
  solutionLanguage: LanguageTypes.HTML,
  checkFunction: async ({ solutionTree, attemptTree, check, successfulResponse }) => {

    await check({
      description: "Ensure there is an <img /> or <svg /> tag",

      // Path to the value. This value will get passed into the condition function below
      objectPath: '0.tag',

      // The value from the attempt is passed in here for a special check.
      // We can specify a specific condition based on the value targeted by objectPath above
      // Here we're saying the tag can be an img tag or an svg tag
      condition: (attemptTreeValue) => attemptTreeValue === 'img' || attemptTreeValue === 'svg',

      // Add an optional hint
      hint: "Make sure you use the right tag name."
    })

    // Always return a successful response at the end
    return successfulResponse
  }
}

The complexCheck object takes two keys:

  • solutionLanguage = the language the solution is in. This tells the system which parser to use.
    • Options: LaguageTypes.HTML, LanguageTypes.CSS, LanguageTypes.JS
  • checkFunction = a function that checks details of the submitted attempt

checkFunction Parameters

ParameterRequired?DEFINITION
checkYesFunction to use to check a piece of the exercise.
successfulResponseYesWhat you should return at the end of your checkFunction.
solutionTreeNoA tree representation of the correct solution.
attemptTreeNoA tree representation of the submitted attempt.

Internal await check() Parameters

ParameterRequired?DEFINITION
descriptionYesHuman-readable description of what we're checking here
objectPathYesPath to the value you want to check in the solutionTree (more info).
hintNoA hint to help the student understand get past this check.
conditionNoFunction to help write your own condition if needed.

How to add a new class

TO DO

Getting Started

  • Clone this repository
  • Run npm install
  • Run the development server npm run dev

Open http://localhost:3001 with your browser to see the result.

You can start editing the page by modifying pages/index.js. The page auto-updates as you edit the file.

API routes can be accessed on http://localhost:3001/api/hello. This endpoint can be edited in pages/api/hello.js.

The pages/api directory is mapped to /api/*. Files in this directory are treated as API routes instead of React pages.

Why NextJS

We're going to run with NextJS because it gives us a built-in server and frontend. The backend portion will be all JavaScript, so others should be able to contribute easily. It'll also be beneficial to use the same framework as the frontend repository. And finally, hosting should be easy (and free) with Vercel.

Learn More

To learn more about Next.js, take a look at the following resources:

You can check out the Next.js GitHub repository - your feedback and contributions are welcome!

Deploy on Vercel

The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.

Check out our Next.js deployment documentation for more details.

FAQs

Package last updated on 11 Jul 2022

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc