├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── README.md ├── experiments ├── edit-mode-to-json │ ├── lifetimes-malformatted-0.md │ ├── lifetimes-well-formatted-0.md │ └── lifetimes-well-formatted-1.md ├── hand-scoring │ ├── 001 │ │ ├── prompts │ │ │ ├── ch03-02-data-types-text-only-0 │ │ │ ├── ch03-02-data-types-text-only-1 │ │ │ ├── ch03-02-data-types-text-with-mcqs-0 │ │ │ ├── ch03-02-data-types-text-with-mcqs-1 │ │ │ ├── ch05-03-method-syntax-text-only-0 │ │ │ ├── ch05-03-method-syntax-text-only-1 │ │ │ ├── ch05-03-method-syntax-text-with-mcqs-0 │ │ │ ├── ch05-03-method-syntax-text-with-mcqs-1 │ │ │ ├── ch10-03-lifetime-syntax-text-only-0 │ │ │ ├── ch10-03-lifetime-syntax-text-only-1 │ │ │ ├── ch10-03-lifetime-syntax-text-only-2 │ │ │ ├── ch10-03-lifetime-syntax-text-only-3 │ │ │ ├── ch10-03-lifetime-syntax-text-only-4 │ │ │ ├── ch10-03-lifetime-syntax-text-with-mcqs-0 │ │ │ ├── ch10-03-lifetime-syntax-text-with-mcqs-1 │ │ │ ├── ch10-03-lifetime-syntax-text-with-mcqs-2 │ │ │ ├── ch10-03-lifetime-syntax-text-with-mcqs-3 │ │ │ └── ch10-03-lifetime-syntax-text-with-mcqs-4 │ │ └── questions │ │ │ ├── 03-02-mcq-0 │ │ │ ├── 03-02-mcq-1 │ │ │ ├── 05-03-mcq-0 │ │ │ ├── 05-03-mcq-1 │ │ │ ├── 10-03-mcq-0 │ │ │ ├── 10-03-mcq-1 │ │ │ ├── ch03-02-data-types-text-only-0 │ │ │ ├── ch03-02-data-types-text-only-1 │ │ │ ├── ch05-03-method-syntax-text-only-0 │ │ │ ├── ch05-03-method-syntax-text-only-1 │ │ │ ├── ch10-03-lifetime-syntax-text-only-0 │ │ │ ├── ch10-03-lifetime-syntax-text-only-1 │ │ │ ├── ch10-03-lifetime-syntax-text-only-2 │ │ │ ├── ch10-03-lifetime-syntax-text-only-3 │ │ │ └── ch10-03-lifetime-syntax-text-only-4 │ ├── 002 │ │ ├── prompts │ │ │ ├── ch03-02-data-types-text-only-0 │ │ │ ├── ch03-02-data-types-text-only-1 │ │ │ ├── ch03-02-data-types-text-with-mcqs-0 │ │ │ ├── ch03-02-data-types-text-with-mcqs-1 │ │ │ ├── ch03-02-data-types-text-with-quiz-template-0 │ │ │ ├── ch03-02-data-types-text-with-quiz-template-1 │ │ │ ├── ch05-03-method-syntax-text-only-0 │ │ │ ├── ch05-03-method-syntax-text-only-1 │ │ │ ├── ch05-03-method-syntax-text-with-mcqs-0 │ │ │ ├── ch05-03-method-syntax-text-with-mcqs-1 │ │ │ ├── ch05-03-method-syntax-text-with-quiz-template-0 │ │ │ ├── ch05-03-method-syntax-text-with-quiz-template-1 │ │ │ ├── ch10-03-lifetime-syntax-text-only-0 │ │ │ ├── ch10-03-lifetime-syntax-text-only-1 │ │ │ ├── ch10-03-lifetime-syntax-text-only-2 │ │ │ ├── ch10-03-lifetime-syntax-text-only-3 │ │ │ ├── ch10-03-lifetime-syntax-text-only-4 │ │ │ ├── ch10-03-lifetime-syntax-text-with-mcqs-0 │ │ │ ├── ch10-03-lifetime-syntax-text-with-mcqs-1 │ │ │ ├── ch10-03-lifetime-syntax-text-with-mcqs-2 │ │ │ ├── ch10-03-lifetime-syntax-text-with-mcqs-3 │ │ │ ├── ch10-03-lifetime-syntax-text-with-mcqs-4 │ │ │ ├── ch10-03-lifetime-syntax-text-with-quiz-template-0 │ │ │ ├── ch10-03-lifetime-syntax-text-with-quiz-template-1 │ │ │ ├── ch10-03-lifetime-syntax-text-with-quiz-template-2 │ │ │ ├── ch10-03-lifetime-syntax-text-with-quiz-template-3 │ │ │ └── ch10-03-lifetime-syntax-text-with-quiz-template-4 │ │ └── questions │ │ │ ├── ch03-02-data-types-text-with-quiz-template-0 │ │ │ ├── ch03-02-data-types-text-with-quiz-template-1 │ │ │ ├── ch05-03-method-syntax-text-with-quiz-template-0 │ │ │ ├── ch05-03-method-syntax-text-with-quiz-template-1 │ │ │ ├── ch10-03-lifetime-syntax-text-with-quiz-template-0 │ │ │ └── ch10-03-lifetime-syntax-text-with-quiz-template-1 │ ├── 003 │ │ ├── prompts │ │ │ ├── ch03-02-data-typ-text-with-quiz-template-0.txt │ │ │ ├── ch05-03-method-synt-text-with-quiz-template-0.txt │ │ │ ├── ch10-03-lifetime-synt-text-with-quiz-template-0.txt │ │ │ ├── ch10-03-lifetime-synt-text-with-quiz-template-1.txt │ │ │ └── ch10-03-lifetime-synt-text-with-quiz-template-2.txt │ │ ├── questions │ │ │ ├── ch03-02-data-typ-text-with-quiz-template-0.txt │ │ │ ├── ch05-03-method-synt-text-with-quiz-template-0.txt │ │ │ ├── ch10-03-lifetime-synt-text-with-quiz-template-0.txt │ │ │ ├── ch10-03-lifetime-synt-text-with-quiz-template-1.txt │ │ │ └── ch10-03-lifetime-synt-text-with-quiz-template-2.txt │ │ └── tests │ │ │ ├── combined.txt │ │ │ ├── high-presence-high-frequency-0.txt │ │ │ ├── high-presence-high-frequency-1.txt │ │ │ ├── high-presence-high-frequency-2.txt │ │ │ ├── main-idea-test.txt │ │ │ ├── main-idea.md │ │ │ ├── misunderstanding-test.txt │ │ │ ├── pipeline-test.txt │ │ │ └── prompted.txt │ ├── 004 │ │ ├── prompts │ │ │ ├── ch03-02-data-typ-template-with-main-ideas-0.txt │ │ │ ├── ch05-03-method-synt-template-with-main-ideas-0.txt │ │ │ ├── ch10-03-lifetime-synt-template-with-main-ideas-0.txt │ │ │ ├── ch10-03-lifetime-synt-template-with-main-ideas-1.txt │ │ │ └── ch10-03-lifetime-synt-template-with-main-ideas-2.txt │ │ └── questions │ │ │ ├── ch03-02-data-typ-template-with-main-ideas-0.txt │ │ │ ├── ch05-03-method-synt-template-with-main-ideas-0.txt │ │ │ ├── ch10-03-lifetime-synt-template-with-main-ideas-0.txt │ │ │ ├── ch10-03-lifetime-synt-template-with-main-ideas-1.txt │ │ │ └── ch10-03-lifetime-synt-template-with-main-ideas-2.txt │ ├── 005 │ │ ├── prompts │ │ │ ├── mdn-functions-text-only-0.txt │ │ │ ├── mdn-functions-text-only-1.txt │ │ │ ├── mdn-functions-text-with-quiz-template-0.txt │ │ │ ├── mdn-functions-text-with-quiz-template-1.txt │ │ │ ├── mdn-objects-text-only-0.txt │ │ │ ├── mdn-objects-text-with-quiz-template-0.txt │ │ │ ├── mdn-promises-text-only-0.txt │ │ │ ├── mdn-promises-text-only-1.txt │ │ │ ├── mdn-promises-text-with-quiz-template-0.txt │ │ │ ├── mdn-promises-text-with-quiz-template-1.txt │ │ │ ├── rust-book-data-types-text-only-0.txt │ │ │ ├── rust-book-data-types-text-only-1.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-0.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-2.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-2.txt │ │ │ ├── rust-book-method-syntax-text-only-0.txt │ │ │ ├── rust-book-method-syntax-text-only-1.txt │ │ │ ├── rust-book-method-syntax-text-with-quiz-template-0.txt │ │ │ └── rust-book-method-syntax-text-with-quiz-template-1.txt │ │ └── questions │ │ │ ├── mdn-functions-text-only-0.txt │ │ │ ├── mdn-functions-text-only-1.txt │ │ │ ├── mdn-functions-text-with-quiz-template-0.txt │ │ │ ├── mdn-functions-text-with-quiz-template-1.txt │ │ │ ├── mdn-objects-text-only-0.txt │ │ │ ├── mdn-objects-text-with-quiz-template-0.txt │ │ │ ├── mdn-promises-text-only-0.txt │ │ │ ├── mdn-promises-text-only-1.txt │ │ │ ├── mdn-promises-text-with-quiz-template-0.txt │ │ │ ├── mdn-promises-text-with-quiz-template-1.txt │ │ │ ├── rust-book-data-types-text-only-0.txt │ │ │ ├── rust-book-data-types-text-only-1.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-0.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-2.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-2.txt │ │ │ ├── rust-book-method-syntax-text-only-0.txt │ │ │ ├── rust-book-method-syntax-text-only-1.txt │ │ │ ├── rust-book-method-syntax-text-with-quiz-template-0.txt │ │ │ └── rust-book-method-syntax-text-with-quiz-template-1.txt │ ├── 006 │ │ ├── prompts │ │ │ ├── rust-book-data-types-text-only-0.txt │ │ │ ├── rust-book-data-types-text-only-1.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-0.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-2.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-2.txt │ │ │ ├── rust-book-method-syntax-text-only-0.txt │ │ │ ├── rust-book-method-syntax-text-only-1.txt │ │ │ ├── rust-book-method-syntax-text-with-quiz-template-0.txt │ │ │ └── rust-book-method-syntax-text-with-quiz-template-1.txt │ │ └── questions │ │ │ ├── rust-book-data-types-text-with-quiz-template-0.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-2.txt │ │ │ └── rust-book-method-syntax-text-with-quiz-template-0.txt │ ├── 007 │ │ ├── prompts │ │ │ ├── rust-book-data-types-text-only-0.txt │ │ │ ├── rust-book-data-types-text-only-1.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-0.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-only-2.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-2.txt │ │ │ ├── rust-book-method-syntax-text-only-0.txt │ │ │ ├── rust-book-method-syntax-text-only-1.txt │ │ │ ├── rust-book-method-syntax-text-with-quiz-template-0.txt │ │ │ └── rust-book-method-syntax-text-with-quiz-template-1.txt │ │ └── questions │ │ │ ├── rust-book-data-types-text-with-quiz-template-0.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-2.txt │ │ │ └── rust-book-method-syntax-text-with-quiz-template-0.txt │ ├── 008 │ │ ├── prompts │ │ │ ├── rust-book-data-types-text-with-quiz-template-0.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-2.txt │ │ │ └── rust-book-method-syntax-text-with-quiz-template-0.txt │ │ └── questions │ │ │ ├── rust-book-data-types-text-with-quiz-template-0.txt │ │ │ ├── rust-book-data-types-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-0.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-1.txt │ │ │ ├── rust-book-lifetime-syntax-text-with-quiz-template-2.txt │ │ │ └── rust-book-method-syntax-text-with-quiz-template-0.txt │ ├── 009 │ │ ├── prompts │ │ │ ├── mdn-functions-text-with-quiz-template-0.txt │ │ │ ├── mdn-functions-text-with-quiz-template-1.txt │ │ │ ├── mdn-objects-text-with-quiz-template-0.txt │ │ │ ├── mdn-promises-text-with-quiz-template-0.txt │ │ │ └── mdn-promises-text-with-quiz-template-1.txt │ │ └── questions │ │ │ ├── mdn-functions-text-with-quiz-template-0.txt │ │ │ ├── mdn-functions-text-with-quiz-template-1.txt │ │ │ ├── mdn-objects-text-with-quiz-template-0.txt │ │ │ ├── mdn-promises-text-with-quiz-template-0.txt │ │ │ └── mdn-promises-text-with-quiz-template-1.txt │ ├── 010 │ │ ├── prompts │ │ │ ├── mdn-functions-text-with-quiz-template-0.txt │ │ │ ├── mdn-functions-text-with-quiz-template-1.txt │ │ │ ├── mdn-objects-text-with-quiz-template-0.txt │ │ │ ├── mdn-promises-text-with-quiz-template-0.txt │ │ │ └── mdn-promises-text-with-quiz-template-1.txt │ │ └── questions │ │ │ ├── mdn-functions-text-with-quiz-template-0.txt │ │ │ ├── mdn-functions-text-with-quiz-template-1.txt │ │ │ ├── mdn-objects-text-with-quiz-template-0.txt │ │ │ ├── mdn-promises-text-with-quiz-template-0.txt │ │ │ └── mdn-promises-text-with-quiz-template-1.txt │ ├── 011 │ │ ├── prompts │ │ │ ├── mdn-functions-text-with-quiz-template-0.txt │ │ │ ├── mdn-functions-text-with-quiz-template-1.txt │ │ │ ├── mdn-objects-text-with-quiz-template-0.txt │ │ │ ├── mdn-promises-text-with-quiz-template-0.txt │ │ │ └── mdn-promises-text-with-quiz-template-1.txt │ │ └── questions │ │ │ ├── mdn-functions-text-with-quiz-template-0.txt │ │ │ ├── mdn-functions-text-with-quiz-template-1.txt │ │ │ ├── mdn-objects-text-with-quiz-template-0.txt │ │ │ ├── mdn-promises-text-with-quiz-template-0.txt │ │ │ └── mdn-promises-text-with-quiz-template-1.txt │ └── README.md ├── logit-bias │ └── main.py ├── plai │ ├── algebraic-types.md │ ├── control-on-web.md │ ├── evaluation-on-paper.md │ ├── generators.md │ ├── intro-to-objects.md │ ├── nominal-structural-subtype.md │ ├── parsing.md │ ├── representing-arithmetic.md │ ├── smol-reactivity.md │ ├── smol.md │ └── union-and-retrofitted-types.md ├── prompt-bank │ ├── api-comparison │ │ ├── prompts │ │ │ └── prompt01.txt │ │ └── results │ │ │ ├── chatgpt-output-1.txt │ │ │ ├── chatgpt-output-2.txt │ │ │ ├── chatgpt-prompt.txt │ │ │ ├── prompt01-output-1.txt │ │ │ ├── prompt01-output-2.txt │ │ │ ├── prompt01-output-3.txt │ │ │ ├── prompt01-output-4.txt │ │ │ └── with-code-template-1.txt │ ├── hypothetical │ │ ├── prompts │ │ │ └── prompt01.txt │ │ └── results │ │ │ ├── prompt01-output-1.txt │ │ │ ├── prompt01-output-2.txt │ │ │ └── prompt01-output-3.txt │ ├── main.py │ ├── prompt.txt │ └── test-files │ │ ├── lifetimes.md │ │ └── traits.md └── server-tests │ └── load.py ├── lib ├── .gitignore ├── LICENSE ├── quizicist │ ├── __init__.py │ ├── completion.py │ ├── consts.py │ ├── errors.py │ ├── parsers │ │ ├── md.py │ │ └── text.py │ ├── postprocess.py │ └── prompt.py ├── setup.py └── tests │ └── test_prompt.py └── site ├── Caddyfile ├── README.md ├── backend ├── __init__.py ├── blueprints │ ├── __init__.py │ ├── admin.py │ ├── api.py │ └── auth.py ├── config.py ├── db.py ├── lib │ ├── __init__.py │ ├── consts.py │ ├── export.py │ ├── files.py │ └── mdbook.py ├── limiter.py ├── main.py ├── migrations │ ├── README │ ├── alembic.ini │ ├── env.py │ ├── script.py.mako │ └── versions │ │ ├── 1d7661406625_add_timestamps_and_export_model.py │ │ ├── 3cdfbfffba69_add_content_type_to_generation.py │ │ ├── 5845a6a202dc_add_admin_expiration_datetime_for_user_.py │ │ └── a0318327cfbb_add_llm_model_field_to_generation_class.py ├── models.py └── templates │ ├── score.html │ └── upload.html ├── create_db.py ├── data-notebook.ipynb ├── frontend ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── src │ ├── components │ │ ├── AdminAuth.tsx │ │ ├── AdminDashboard.tsx │ │ ├── AdminTable.tsx │ │ ├── CollapsibleAlert.tsx │ │ ├── Dashboard.module.css │ │ ├── Dashboard.tsx │ │ ├── ExportTextbox.tsx │ │ ├── GenerationDiff.tsx │ │ ├── GenerationView.module.css │ │ ├── GenerationView.tsx │ │ ├── MessageForm.tsx │ │ ├── QuestionView.module.css │ │ ├── QuestionView.tsx │ │ ├── QuizUtilsModal.tsx │ │ ├── Upload.tsx │ │ ├── buttons │ │ │ ├── LoadingButton.tsx │ │ │ └── LoadingIconButton.tsx │ │ ├── fields │ │ │ ├── CheckboxField.tsx │ │ │ ├── IconCheckbox.module.css │ │ │ ├── IconCheckbox.tsx │ │ │ ├── RadioField.tsx │ │ │ ├── SelectField.tsx │ │ │ ├── Shared.module.css │ │ │ ├── TextField.tsx │ │ │ └── TextareaField.tsx │ │ └── forms │ │ │ ├── CustomQuestionForm.tsx │ │ │ ├── ExportQuizForm.tsx │ │ │ ├── MoreQuestionsForm.tsx │ │ │ ├── shared.ts │ │ │ └── utils.ts │ ├── hooks │ │ ├── fetcher.ts │ │ ├── mutation │ │ │ ├── mutationHooks.ts │ │ │ ├── optimisticData.ts │ │ │ └── useMutationPost.ts │ │ └── useGenerations.ts │ ├── main.tsx │ ├── schemas │ │ ├── addQuestions.schema.ts │ │ ├── customQuestion.schema.ts │ │ ├── exportToForms.schema.ts │ │ ├── message.schema.ts │ │ ├── question.schema.ts │ │ └── upload.schema.ts │ ├── shared │ │ ├── answerchoice.type.ts │ │ ├── api.ts │ │ ├── consts.ts │ │ ├── feedback.type.ts │ │ ├── generation.type.ts │ │ ├── message.type.ts │ │ └── question.type.ts │ ├── vite-env.d.ts │ └── wrappers │ │ ├── AuthWrapper.tsx │ │ └── Navbar.tsx ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── gunicorn_config.py └── requirements.txt /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: Deploy App 2 | 3 | on: [push] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | - run: cd lib && pip3 install -e .[dev] && pytest 12 | 13 | deploy: 14 | if: github.ref == 'refs/heads/master' 15 | runs-on: ubuntu-latest 16 | needs: test 17 | 18 | strategy: 19 | matrix: 20 | node-version: [18.x] 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Set up Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v2 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | - name: Build React app 29 | working-directory: ./site/frontend 30 | run: | 31 | npm ci --legacy-peer-deps 32 | npm run build 33 | - name: Deploy to gh-pages 34 | uses: peaceiris/actions-gh-pages@v3 35 | with: 36 | github_token: ${{ secrets.GITHUB_TOKEN }} 37 | publish_dir: ./site/frontend/dist 38 | cname: quizici.st 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # virtual environment 2 | quiz-env 3 | .venv 4 | 5 | .env 6 | 7 | **.pyc 8 | 9 | *.egg-info 10 | 11 | # SQLite database and uploaded files 12 | site/backend/uploads 13 | site/instance 14 | 15 | # Google Cloud service account credentials 16 | site/backend/google-service-account.json 17 | 18 | # gunicorn logs 19 | site/gunicorn.log 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Quizicist: an AI-powered quiz generator 2 | 3 | ## Getting started 4 | Want to quickly generate a quiz? Visit our hosted Quizicist instance at [quizici.st](https://quizici.st). With a piece of text content (eg. a textbook or lecture notes), Quizicist can generate a quiz in minutes. Once you review the questions and mark answers as correct or incorrect, you can export the quiz to Google Forms, [mdbook-quiz](https://github.com/cognitive-engineering-lab/mdbook-quiz), or plain text. 5 | 6 | ## Running Quizicist locally 7 | Running into rate limits at [quizici.st](https://quizici.st)? Quizicist can be deployed locally with the following instructions: 8 | 9 | ### Environment variables 10 | You'll need to create a `.env` file in the root of the project with the following key-value pair: 11 | ``` 12 | OPENAI_SECRET_KEY= 13 | ``` 14 | 15 | ### Dependencies 16 | You'll also need to install dependencies: 17 | ```shell 18 | $ cd lib && pip3 install -e . && cd .. 19 | $ cd site && pip3 install -r requirements.txt 20 | $ cd frontend && npm install --legacy-peer-deps 21 | ``` 22 | 23 | ### Database 24 | When developing/running locally, we use SQLite to store generated items: 25 | ```shell 26 | $ cd site 27 | $ python3 create_db.py # set up local sqlite database 28 | ``` 29 | 30 | ### Running the server + frontend 31 | In one shell: 32 | ```shell 33 | $ cd site 34 | $ flask --app backend/main --debug run --port 5000 # run server in debug mode 35 | ``` 36 | 37 | In another shell: 38 | ```shell 39 | $ cd site/frontend && npm run dev -- --port 3000 40 | ``` 41 | -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/03-02-mcq-0: -------------------------------------------------------------------------------- 1 | The default type for floating-point numbers is: 2 | Correct: f64 3 | Incorrect: f32 4 | Incorrect: f128 5 | 6 | Which of the following is not a primitive type in Rust? 7 | Incorrect: Integer 8 | Incorrect: Floating-point number 9 | Incorrect: Boolean 10 | Correct: String 11 | 12 | Which of the following is not a scalar type? 13 | Incorrect: Integer 14 | Incorrect: Floating-point number 15 | Incorrect: Boolean 16 | Incorrect: Character 17 | Correct: Array 18 | 19 | Which of the following is not a compound type? 20 | Correct: Scalar type 21 | Incorrect: Tuple 22 | Incorrect: Array 23 | Incorrect: Slice 24 | 25 | If x : u8 = 0, what will happen when computing x - 1 in release mode? 26 | Incorrect: It will always panic. 27 | Correct: It will wrap around and become 255. 28 | Incorrect: It will return an error. 29 | -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/03-02-mcq-1: -------------------------------------------------------------------------------- 1 | What is the output of the following code? 2 | fn main() { 3 | let x = 5; 4 | let y = if x == 5 { 10 } else { 15 }; 5 | let z = if x < 10 { 10 } else { 15 }; 6 | println!("x is {} and y is {} and z is {}", x, y, z); 7 | } 8 | 9 | Correct: x is 5 and y is 10 and z is 10 10 | Incorrect: x is 5 and y is 10 and z is 15 11 | Incorrect: x is 5 and y is 15 and z is 10 12 | Incorrect: x is 5 and y is 15 and z is 15 13 | 14 | A char type in Rust: 15 | Correct: Can represent more than just ASCII. 16 | Incorrect: Is 4 bytes in size. 17 | Incorrect: Represents a Unicode Scalar Value. 18 | Incorrect: Is a string literal. 19 | 20 | Which of the following is not a compound type in Rust? 21 | Correct: i32 22 | Incorrect: Array 23 | Incorrect: Tuple 24 | Incorrect: Vector 25 | 26 | The ownership of the variable s will be moved to ____ after the following code executes. 27 | let s1 = String::from("hello"); 28 | let s2 = s1; 29 | 30 | Correct: s2 31 | Incorrect: s1 32 | Incorrect: s1 and s2 33 | Incorrect: None of the above. 34 | 35 | The ownership of the variable s will be moved to ____ after the following code executes. 36 | let s1 = gives_ownership(); 37 | let s2 = String::from("hello"); 38 | let s3 = takes_and_gives_back(s2); 39 | 40 | Correct: s3 41 | Incorrect: s2 42 | Incorrect: s1 43 | Incorrect: s1 and s3 -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/05-03-mcq-0: -------------------------------------------------------------------------------- 1 | What is the first parameter of a method always called? 2 | Correct: self 3 | Incorrect: first 4 | Incorrect: &self 5 | Incorrect: &mut self 6 | 7 | What does the '&' symbol represent in a method signature? 8 | Correct: Borrows the instance immutably 9 | Incorrect: Borrows the instance mutably 10 | Incorrect: Takes ownership of the instance 11 | Incorrect: Takes ownership of the instance and mutates it 12 | 13 | What does the method call rect1.width() return? 14 | Correct: True if the width field is greater than 0, false if it is 0 15 | Incorrect: The width of the Rectangle 16 | Incorrect: True 17 | Incorrect: False 18 | 19 | What is the output of the following code? 20 | 21 | #[derive(Debug)] 22 | struct Rectangle { 23 | width: u32, 24 | height: u32, 25 | } 26 | 27 | impl Rectangle { 28 | fn area(&self) -> u32 { 29 | self.width * self.height 30 | } 31 | } 32 | 33 | fn main() { 34 | let rect1 = Rectangle { 35 | width: 30, 36 | height: 50, 37 | }; 38 | 39 | println!( 40 | "The area of the rectangle is {} square pixels.", 41 | rect1.area() 42 | ); 43 | } 44 | 45 | Correct: The area of the rectangle is 1500 square pixels. 46 | Incorrect: The area of the rectangle is 30 square pixels. 47 | Incorrect: The area of the rectangle is 50 square pixels. 48 | Incorrect: The area of the rectangle is Rectangle { width: 30, height: 50 } -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/05-03-mcq-1: -------------------------------------------------------------------------------- 1 | What is the difference between an associated function and a method? 2 | 3 | Correct: Associated functions don't take an instance of the type as a parameter 4 | Incorrect: Associated functions don't have a self parameter 5 | Incorrect: Associated functions can't access the fields of an instance 6 | Incorrect: Associated functions can't be called on an instance 7 | 8 | Which of the following is not a valid way to create a new struct? 9 | 10 | Correct: Self {width: 10} 11 | Incorrect: Self(10) 12 | Incorrect: Self {width: 10, height: 10} 13 | Incorrect: Self::new(10, 10) 14 | 15 | What is the return type of the area method? 16 | 17 | Correct: u32 18 | Incorrect: f32 19 | Incorrect: i32 20 | Incorrect: &self 21 | 22 | What is the return type of the can_hold method? 23 | 24 | Correct: bool 25 | Incorrect: u32 26 | Incorrect: f32 27 | Incorrect: &self 28 | 29 | What does the :: syntax do? 30 | 31 | Correct: Call an associated function 32 | Incorrect: Access a namespace 33 | Incorrect: Call a method 34 | Incorrect: Access a field -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/10-03-mcq-0: -------------------------------------------------------------------------------- 1 | What does the Rust borrow checker do? 2 | Incorrect: It ensures that all pointers are valid 3 | Incorrect: It ensures that all references are valid 4 | Correct: It compares the scopes of variables to ensure that all borrows are valid 5 | Incorrect: It determines which type of reference to use 6 | 7 | 8 | 9 | If a reference has a lifetime of 'a, and it refers to an object with a lifetime of 'b, 10 | Incorrect: The lifetime of 'a must be greater than the lifetime of 'b 11 | Correct: The lifetime of 'b must be greater than the lifetime of 'a 12 | Incorrect: The lifetimes of 'a and 'b must be the same 13 | Incorrect: There is no relationship between the lifetimes of 'a and 'b 14 | 15 | 16 | 17 | What will the following code print? 18 | 19 | fn main() { 20 | let string1 = String::from("abcd"); 21 | let string2 = "xyz"; 22 | 23 | let result = longest(string1.as_str(), string2); 24 | println!("The longest string is {}", result); 25 | } 26 | 27 | Incorrect: The longest string is xyz 28 | Correct: The longest string is abcd 29 | Incorrect: The longest string is abcdxyz 30 | Incorrect: The longest string is 5 31 | 32 | 33 | 34 | Why does Rust need us to annotate lifetimes? 35 | Incorrect: So that the borrow checker can determine which references are valid 36 | Incorrect: So that the compiler can infer the type of each reference 37 | Correct: So that the compiler can infer the lifetime of each reference 38 | Incorrect: So that the compiler can figure out which functions to call 39 | 40 | 41 | 42 | What is the lifetime of the variable x in the following code? 43 | 44 | fn main() { 45 | let x = 5; // ----------+-- 'b 46 | // | 47 | let r = &x; // --+-- 'a | 48 | // | | 49 | println!("r: {}", r); // | | 50 | // --+ | 51 | } // ----------+ 52 | 53 | Incorrect: 'a 54 | Incorrect: 'b 55 | Incorrect: 'x 56 | Correct: 'static -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/10-03-mcq-1: -------------------------------------------------------------------------------- 1 | Which of the following is NOT a valid lifetime annotation? 2 | Incorrect: &'a i32 3 | Correct: &a i32 4 | Incorrect: &'i32 5 | Correct: &i32 6 | 7 | In order for a function to take two references with different lifetimes as arguments, 8 | Correct: both references must have the same lifetime annotation 9 | Incorrect: both references must have different lifetime annotations 10 | Correct: the function must have a generic lifetime parameter specifying how the lifetimes of the two references relate to each other 11 | Incorrect: the function signature must explicitly state the lifetime of the returned reference 12 | 13 | What does this function signature tell Rust? 14 | for some lifetime 'a, the function takes two parameters, both of which are string slices that live at least as long as lifetime 'a 15 | Incorrect: for some lifetime 'a, the function takes two parameters, both of which are string slices that live at most as long as lifetime 'a 16 | Correct: for some lifetime 'a, the function takes two parameters, both of which are string slices that live at least as long as lifetime 'a, and the function returns a string slice that lives at least as long as lifetime 'a 17 | Incorrect: for some lifetime 'a, the function takes two parameters, both of which are string slices that live at least as long as lifetime 'a, and the function returns a string slice that lives at most as long as lifetime 'a 18 | 19 | Lifetime annotations 20 | Incorrect: are meant to tell Rust how generic lifetime parameters of multiple references relate to each other and nothing else 21 | Incorrect: only have meaning in the context of the longest function 22 | Correct: are meant to tell Rust how generic lifetime parameters of multiple references relate to each other 23 | Incorrect: do not change how long any of the references live 24 | 25 | Listing 10-23 will not compile because 26 | Incorrect: the lifetime of result is not the same as the lifetime of string1 27 | Incorrect: the lifetime of result is not the same as the lifetime of string2 28 | Correct: the lifetime of result is not the same as the smaller lifetime of string1 and string2 29 | Incorrect: the lifetime of result is not the smaller lifetime of string1 and string2 -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/ch03-02-data-types-text-only-0: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. Which of the following is not a primary scalar type in Rust? 4 | 5 | A. Characters 6 | B. Booleans 7 | C. Integers 8 | D. Floating-point numbers 9 | 10 | 2. Which of the following best describes the purpose of type annotations in Rust? 11 | 12 | A. To tell the compiler what kind of data is being specified 13 | B. To provide more information to the compiler when it is inferring the type of a value 14 | C. To allow a variable to hold values of multiple data types 15 | D. To determine the size of a value 16 | 17 | 3. What does the term "panicking" mean in Rust? 18 | 19 | A. When a program exits with an error 20 | B. When a variable has a value that is not what was expected 21 | C. When a program compiles with the --release flag 22 | D. When a program does not include checks for integer overflow 23 | 24 | 4. What is the result of integer division in Rust? 25 | 26 | A. The division rounds up to the nearest integer 27 | B. The division rounds down to the nearest integer 28 | C. The division rounds to the nearest integer 29 | D. The division rounds to the nearest floating-point number 30 | 31 | 5. Which of the following is not a way to handle the possibility of integer overflow in Rust? 32 | 33 | A. Return the None value if there is overflow with the checked_* methods 34 | B. Saturate at the value’s minimum or maximum values with saturating_* methods 35 | C. Use the Wrap family of methods 36 | D. Use the Overflow family of methods -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/ch03-02-data-types-text-only-1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What is Rust's char type four bytes in size? 4 | a. So that it can represent a lot more than just ASCII 5 | b. So that it can represent a Unicode Scalar Value 6 | c. To match the size of other programming language's char types 7 | d. So that it can easily be stored on the stack 8 | 9 | 2. What is the lenght of a Rust tuple? 10 | a. 2 11 | b. 3 12 | c. 4 13 | d. Fixed 14 | 15 | 3. What is the difference between an array and a vector in Rust? 16 | a. An array is more flexible than a vector 17 | b. An array cannot grow or shrink in size, whereas a vector can 18 | c. An array is stored on the heap, whereas a vector is stored on the stack 19 | d. An array can store values of different types, whereas a vector cannot 20 | 21 | 4. What does the expression let a = [3; 5] do? 22 | a. It initializes an array named a with 5 elements that are all set to the value 3 23 | b. It set the value of a to 3 24 | c. It initializes an array named a with 3 elements 25 | d. It initializes an array named a with 5 elements 26 | 27 | 5. What happens if you try to access an element of an array that is past the end of the array? 28 | a. It will print out an error message 29 | b. It will print out the corresponding value at that index in the array 30 | c. It will initializes an array with that index 31 | d. Rust will panic -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/ch05-03-method-syntax-text-only-0: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What keyword is used to declare methods? 4 | a. fn 5 | b. method 6 | c. trait 7 | d. struct 8 | 9 | 2. What is the first parameter of a method always called? 10 | a. self 11 | b. &self 12 | c. &mut self 13 | d. trait 14 | 15 | 3. What does the & in &self represent? 16 | a. Borrows the Self instance 17 | b. Borrows the self instance 18 | c. Borrows the first parameter 19 | d. Borrows the method 20 | 21 | 4. When is it appropriate to use &mut self as the first parameter of a method? 22 | a. When the method transforms self into something else 23 | b. When the method borrows self mutably 24 | c. When the method borrows self immutably 25 | d. When the method takes ownership of self 26 | 27 | 5. What is the difference between the . operator and the -> operator when calling methods? 28 | a. . is used when calling a method on an object directly, and -> is used when calling a method on a pointer to the object 29 | b. . is used when calling a method on an object directly, and -> is used when calling a method on an object that doesn't have a pointer 30 | c. . is used when calling a method on an object indirectly, and -> is used when calling a method on a pointer to the object 31 | d. -> is used when calling a method on an object directly, and . is used when calling a method on a pointer to the object -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/ch05-03-method-syntax-text-only-1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1) What does the "impl Rectangle" block do? 4 | 5 | a) It holds all associated functions for the Rectangle struct 6 | b) It holds all methods for the Rectangle struct 7 | c) It allows for multiple impl blocks for the Rectangle struct 8 | d) It is a private function for the Rectangle struct 9 | 10 | 2) What does the "Self" keyword represent in the following code? 11 | 12 | impl Rectangle { 13 | fn square(size: u32) -> Self { 14 | Self { 15 | width: size, 16 | height: size, 17 | } 18 | } 19 | } 20 | 21 | a) The return type of the square function 22 | b) The size parameter of the square function 23 | c) The width and height parameters of the square function 24 | d) The type that follows the impl keyword, which in this case is Rectangle 25 | 26 | 3) What is the "::" syntax used for? 27 | 28 | a) Associated functions that aren't methods 29 | b) Namespaces created by modules 30 | c) Traits 31 | d) Generic types 32 | 33 | 4) What does the "Self" keyword represent in the following code? 34 | 35 | impl Rectangle { 36 | fn area(&self) -> u32 { 37 | self.width * self.height 38 | } 39 | } 40 | 41 | a) The width and height parameters of the area function 42 | b) The return type of the area function 43 | c) The type that follows the impl keyword, which in this case is Rectangle 44 | d) The &self parameter of the area function 45 | 46 | 5) What is the main purpose of structs? 47 | 48 | a) To let you create custom types that are meaningful for your domain 49 | b) To keep associated pieces of data connected to each other 50 | c) To name each piece of data to make your code clear 51 | d) All of the above -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/ch10-03-lifetime-syntax-text-only-0: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What is the main aim of lifetimes? 4 | A. To prevent dangling references 5 | B. To ensure references are valid 6 | C. To annotate lifetimes 7 | D. To compare scopes 8 | 9 | 2. What is the borrow checker? 10 | A. A Rust compiler tool that compares scopes to determine whether all borrows are valid 11 | B. A Rust compiler tool that checks for lifetimes 12 | C. A Rust compiler tool that checks for dangling references 13 | D. A Rust compiler tool that checks for valid references 14 | 15 | 3. What does it mean when a lifetime is "larger" than another? 16 | A. It will end first 17 | B. It will end later 18 | C. It will contain more data 19 | D. It will contain less data 20 | 21 | 4. Why is it preferable to use string slices rather than strings as parameters? 22 | A. So the function can take ownership of its parameters 23 | B. So the function can't take ownership of its parameters 24 | C. So the function can't borrow its parameters 25 | D. So the function can borrow its parameters 26 | 27 | 5. What does it mean when a reference has a lifetime of 'a? 28 | A. It will end first 29 | B. It will end later 30 | C. It will contain more data 31 | D. It will contain less data -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/ch10-03-lifetime-syntax-text-only-1: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What does the longest function return? 4 | A. The longest string 5 | B. A reference to the longest string 6 | C. A reference to the longest string, with a lifetime parameter 'a 7 | 8 | 2. What is the relationship between the lifetimes of the parameters and the return value? 9 | A. The returned reference will be valid as long as both the parameters are valid. 10 | B. The returned reference will be valid as long as the parameter x is valid. 11 | C. The returned reference will be valid as long as the parameter y is valid. 12 | 13 | 3. What does it mean when we specify the lifetime parameters in this function signature? 14 | A. We're changing the lifetimes of any values passed in or returned. 15 | B. We're specifying that the borrow checker should reject any values that don't adhere to these constraints. 16 | C. We're specifying that the borrow checker should accept any values that don't adhere to these constraints. 17 | 18 | 4. When annotating lifetimes in functions, where do the annotations go? 19 | A. In the function signature 20 | B. In the function body 21 | C. In the function signature and the function body 22 | 23 | 5. What is the lifetime of the reference in result if string1 and string2 have different concrete lifetimes? 24 | A. The lifetime of result will be the smaller lifetime of the two arguments. 25 | B. The lifetime of result will be the larger lifetime of the two arguments. 26 | C. The lifetime of result will be the same lifetime as string1. -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/ch10-03-lifetime-syntax-text-only-2: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What does the error in Listing 10-23 show? 4 | 5 | a) That the reference returned by the longest function is not valid for the println! statement. 6 | 7 | b) That the borrow checker disallows the code in Listing 10-23 as possibly having an invalid reference. 8 | 9 | c) That the longest function will always return the first parameter rather than the longest string slice. 10 | 11 | d) That the lifetime of the reference returned by the longest function is not related to the lifetime of the parameters at all. 12 | 13 | 14 | 2. Why is it a problem if the return value lifetime is not related to the lifetime of the parameters at all? 15 | 16 | a) It will cause a dangling reference. 17 | 18 | b) It will violate memory safety. 19 | 20 | c) Rust won't let us create a dangling reference. 21 | 22 | d) It will cause an error when compiling the code. 23 | 24 | 25 | 3. Which statement about lifetime parameters is true? 26 | 27 | a) Once they're connected, Rust has enough information to allow memory-safe operations and disallow operations that would create dangling pointers. 28 | 29 | b) They need to be specified for every reference in a struct's definition. 30 | 31 | c) They're only necessary when returning a reference from a function. 32 | 33 | d) Every reference has a lifetime. 34 | 35 | 36 | 4. What does it mean if an instance of a struct can't outlive the reference it holds in its part field? 37 | 38 | a) The instance can't be created before the reference. 39 | 40 | b) The instance can't outlive the data it's referencing. 41 | 42 | c) The reference can't outlive the instance. 43 | 44 | d) The instance can't outlive the struct it's a part of. 45 | 46 | 47 | 5. What's the purpose of lifetime annotations? 48 | 49 | a) To specify the lifetime of the references in a struct's definition 50 | 51 | b) To connect the lifetimes of various parameters and return values of functions 52 | 53 | c) To ensure that every reference has a lifetime 54 | 55 | d) To allow memory-safe operations and disallow operations that would create dangling pointers -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/ch10-03-lifetime-syntax-text-only-3: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. According to the text, why was it historically necessary to add explicit lifetime annotations to every reference in Rust? 4 | 5 | A. To prevent errors 6 | 7 | B. To ensure code compatibility 8 | 9 | C. To provide full inference 10 | 11 | D. To deter future programmers from guesswork 12 | 13 | 2. What is the significance of the lifetime elision rules? 14 | 15 | A. They form a set of cases where the compiler can safely figure out lifetimes without programmer input 16 | 17 | B. They help to predict patterns of code usage 18 | 19 | C. They provide a way to resolve ambiguity in code 20 | 21 | D. They are a set of guidelines for Rust programmers to follow 22 | 23 | 3. What is the relationship between input and output lifetimes? 24 | 25 | A. Input lifetimes must always be longer than output lifetimes 26 | 27 | B. Output lifetimes are a subset of input lifetimes 28 | 29 | C. Output lifetimes can be independent of input lifetimes 30 | 31 | D. All of the above 32 | 33 | 4. Which rule applies when there are multiple input lifetimes, one of which is &self or &mut self? 34 | 35 | A. The first rule 36 | 37 | B. The second rule 38 | 39 | C. The third rule 40 | 41 | D. None of the above 42 | 43 | 5. What does the text say about the future of Rust programming? 44 | 45 | A. It will become increasingly necessary to add explicit lifetime annotations 46 | 47 | B. It will become increasingly difficult to add explicit lifetime annotations 48 | 49 | C. The number of explicit lifetime annotations required will stay the same 50 | 51 | D. The number of explicit lifetime annotations required will decrease -------------------------------------------------------------------------------- /experiments/hand-scoring/001/questions/ch10-03-lifetime-syntax-text-only-4: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What does the third lifetime elision rule state? 4 | 5 | A. That references in method signatures can be tied to the lifetime of references in the struct's fields. 6 | B. That lifetime annotations are not necessary in method signatures. 7 | C. That the return type gets the lifetime of &self. 8 | 9 | 2. What is the lifetime of all string literals? 10 | 11 | A. 'static 12 | B. 'a 13 | C. 'b 14 | 15 | 3. What is the syntax of specifying generic type parameters, trait bounds, and lifetimes all in one function? 16 | 17 | A. use std::fmt::Display; 18 | 19 | fn longest_with_an_announcement<'a, T>( 20 | x: &'a str, 21 | y: &'a str, 22 | ann: T, 23 | ) -> &'a str 24 | where 25 | T: Display, 26 | { 27 | println!("Announcement! {}", ann); 28 | if x.len() > y.len() { 29 | x 30 | } else { 31 | y 32 | } 33 | } 34 | 35 | B. use std::fmt::Display; 36 | 37 | fn longest_with_an_announcement<'a, T>( 38 | x: &'a str, 39 | y: &'a str, 40 | ann: T, 41 | ) -> &'a str 42 | where 43 | T: Display, 44 | { 45 | println!("Announcement! {}", ann); 46 | if x.len() > y.len() { 47 | x 48 | } else { 49 | y 50 | } 51 | } 52 | 53 | C. use std::fmt::Display; 54 | 55 | fn longest_with_an_announcement<'a, T>( 56 | x: &'a str, 57 | y: &'a str, 58 | ann: T, 59 | ) -> &'a str 60 | where 61 | T: Display, 62 | { 63 | println!("Announcement! {}", ann); 64 | if x.len() > y.len() { 65 | x 66 | } else { 67 | y 68 | } 69 | } 70 | 71 | 4. What is the difference between a method and a function? 72 | 73 | A. A method is a function that is associated with a struct, and a function is not. 74 | B. A function can only be called from within a method, and a method can be called from anywhere. 75 | C. There is no difference. 76 | 77 | 5. What is the significance of the 'a in <'a, T>? 78 | 79 | A. The 'a is a generic lifetime parameter. 80 | B. The 'a is a generic type parameter. 81 | C. There is no significance. -------------------------------------------------------------------------------- /experiments/hand-scoring/002/questions/ch03-02-data-types-text-with-quiz-template-0: -------------------------------------------------------------------------------- 1 | Question: What does the u in u32 stand for? 2 | Correct answer: Unsigned 3 | Incorrect answer: Upper 4 | Incorrect answer: Unit 5 | Incorrect answer: 32-bit 6 | 7 | Question: What is the size of a Boolean in Rust? 8 | Correct answer: 1 byte 9 | Incorrect answer: 2 bytes 10 | Incorrect answer: 4 bytes 11 | Incorrect answer: 8 bytes 12 | 13 | Question: When integer overflow occurs in Rust, what is the default behavior? 14 | Correct answer: The program panics 15 | Incorrect answer: The variable is set to the minimum or maximum value that the type can hold 16 | Incorrect answer: The program does nothing 17 | Incorrect answer: The variable is set to 0 18 | 19 | Question: What type of number is a floating point number? 20 | Correct answer: A number with a decimal component 21 | Incorrect answer: A number without a decimal component 22 | Incorrect answer: A number that is 32 bits in size 23 | Incorrect answer: A number that is 64 bits in size 24 | 25 | Question: What is the default type for a floating point number in Rust? 26 | Correct answer: f64 27 | Incorrect answer: f32 28 | Incorrect answer: f128 29 | Incorrect answer: There is no default type -------------------------------------------------------------------------------- /experiments/hand-scoring/002/questions/ch05-03-method-syntax-text-with-quiz-template-0: -------------------------------------------------------------------------------- 1 | Question: What does the first parameter in a method signature always represent? 2 | Correct answer: The instance of the struct the method is being called on 3 | Incorrect answer: The type of the struct the method is being called on 4 | Incorrect answer: The name of the method 5 | Incorrect answer: The code within the method 6 | 7 | Question: What is the difference between a method and a function? 8 | Correct answer: Methods are defined within the context of a struct, and their first parameter is always self 9 | Incorrect answer: Methods can only be called from within the same struct 10 | Incorrect answer: Functions can only be declared with the 'fn' keyword 11 | Incorrect answer: Methods can take ownership of self, borrow self immutably, or borrow self mutably 12 | 13 | Question: Which symbol is used to call methods in Rust? 14 | Correct answer: The '.' operator 15 | Incorrect answer: The '&' operator 16 | Incorrect answer: The '->' operator 17 | Incorrect answer: The '*' operator 18 | 19 | Question: What does Rust do when you call a method with object.something()? 20 | Correct answer: Rust automatically adds in &, &mut, or * so object matches the signature of the method 21 | Incorrect answer: Rust automatically dereferences the object 22 | Incorrect answer: Rust automatically references the object 23 | Incorrect answer: Rust automatically adds in the object's type 24 | 25 | Question: What is a getter? 26 | Correct answer: A method that returns the value in a field 27 | Incorrect answer: A method that takes ownership of a field 28 | Incorrect answer: A method that borrows a field mutably 29 | Incorrect answer: A method that borrows a field immutably -------------------------------------------------------------------------------- /experiments/hand-scoring/002/questions/ch05-03-method-syntax-text-with-quiz-template-1: -------------------------------------------------------------------------------- 1 | Question: What is the return type of the can_hold method? 2 | Correct answer: bool 3 | Incorrect answer: u32 4 | Incorrect answer: &Rectangle 5 | Incorrect answer: Self 6 | 7 | 8 | 9 | Question: What is the type of the parameter for the can_hold method? 10 | Correct answer: &Rectangle 11 | Incorrect answer: u32 12 | Incorrect answer: Rectangle 13 | Incorrect answer: Self 14 | 15 | 16 | 17 | Question: What is the type of the Self keyword in the return type of the square method? 18 | Correct answer: Rectangle 19 | Incorrect answer: u32 20 | Incorrect answer: &Rectangle 21 | Incorrect answer: Self 22 | 23 | 24 | 25 | Question: What does the :: syntax with the struct name do? 26 | Correct answer: calls an associated function 27 | Incorrect answer: calls a method 28 | Incorrect answer: creates a namespace 29 | Incorrect answer: creates a new instance of the struct 30 | 31 | 32 | 33 | Question: What are the benefits of using structs over just using tuples? 34 | Correct answer: Structs let you name each piece of data, which can make your code more clear. 35 | Incorrect answer: Structs can only hold data, tuples can also hold functions. 36 | Incorrect answer: There is no benefit, tuples are just as good as structs. 37 | Incorrect answer: Structs can hold multiple types of data, tuples can only hold one type. -------------------------------------------------------------------------------- /experiments/hand-scoring/002/questions/ch10-03-lifetime-syntax-text-with-quiz-template-0: -------------------------------------------------------------------------------- 1 | Question: What is the main aim of lifetimes? 2 | Correct answer: To prevent dangling references 3 | Incorrect answer: To ensure references are valid 4 | Incorrect answer: To annotate relationships 5 | Incorrect answer: To compare scopes 6 | 7 | Question: What does the Rust compiler do with lifetimes? 8 | Correct answer: Uses a borrow checker 9 | Incorrect answer: Determines if the lifetimes are valid 10 | Incorrect answer: Checks if the program will compile 11 | Incorrect answer: Compares the size of the lifetimes 12 | 13 | Question: What is the difference between 'a and 'b in Listing 10-18? 14 | Correct answer: 'a is the lifetime of x and 'b is the lifetime of r 15 | Incorrect answer: 'a is the lifetime of r and 'b is the lifetime of x 16 | Incorrect answer: There is no difference 17 | Incorrect answer: 'a is the outer scope and 'b is the inner scope 18 | 19 | Question: How do you annotate lifetimes? 20 | Correct answer: By using generic lifetime parameters 21 | Incorrect answer: By using references 22 | Incorrect answer: By using scopes 23 | Incorrect answer: By using variables 24 | 25 | Question: What is the outcome of the code in Listing 10-20? 26 | Correct answer: It doesn't compile 27 | Incorrect answer: It compiles without any errors 28 | Incorrect answer: It prints "The longest string is abcd" 29 | Incorrect answer: It prints "The longest string is xyz" -------------------------------------------------------------------------------- /experiments/hand-scoring/003/questions/ch03-02-data-typ-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | Question: What is the type of an integer value that can store numbers from -(2n - 1) to 2n - 1 - 1 inclusive, where n is the number of bits that variant uses? 4 | Correct answer: i8 5 | Incorrect answer: i32 6 | Incorrect answer: u8 7 | Incorrect answer: f32 8 | 9 | Question: What is the size of a Boolean value in Rust? 10 | Correct answer: 1 byte 11 | Incorrect answer: 2 bytes 12 | Incorrect answer: 4 bytes 13 | Incorrect answer: 8 bytes 14 | 15 | Question: What is the size of a char value in Rust? 16 | Correct answer: 4 bytes 17 | Incorrect answer: 1 byte 18 | Incorrect answer: 2 bytes 19 | Incorrect answer: 8 bytes 20 | 21 | Question: What is the default type for an integer value in Rust? 22 | Correct answer: i32 23 | Incorrect answer: u32 24 | Incorrect answer: f32 25 | Incorrect answer: char 26 | 27 | Question: What does the type annotation in the following example tell Rust? 28 | 29 | let guess: u32 = "42".parse().expect("Not a number!"); 30 | 31 | Correct answer: that the value associated with "guess" should be an unsigned integer that takes up 32 bits of space 32 | Incorrect answer: that the value associated with "guess" should be an integer that takes up 32 bits of space 33 | Incorrect answer: that the value associated with "guess" should be an unsigned integer that takes up 64 bits of space 34 | Incorrect answer: that the value associated with "guess" should be an integer that takes up 64 bits of space -------------------------------------------------------------------------------- /experiments/hand-scoring/003/questions/ch05-03-method-synt-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | Question: What keyword is used to declare methods? 4 | Correct answer: fn 5 | Incorrect answer: method 6 | Incorrect answer: struct 7 | Incorrect answer: impl 8 | 9 | 10 | Question: What is the first parameter of every method? 11 | Correct answer: self 12 | Incorrect answer: &self 13 | Incorrect answer: &mut self 14 | Incorrect answer: other 15 | 16 | 17 | Question: What does the Self keyword mean in a method's return type? 18 | Correct answer: Self is an alias for the type that appears after the impl keyword. 19 | Incorrect answer: The method will return the struct that it was called on. 20 | Incorrect answer: The method will return the first parameter. 21 | Incorrect answer: The method will return the result of the code within the method. 22 | 23 | 24 | Question: When is it useful to create an associated function? 25 | Correct answer: When you want to namespaces the function by the struct. 26 | Incorrect answer: When you want the function to take ownership of the struct. 27 | Incorrect answer: When you want the function to be a method. 28 | Incorrect answer: When you want the function to have the same name as a field. 29 | 30 | 31 | Question: How do you call an associated function? 32 | Correct answer: By using the :: syntax with the struct name. 33 | Incorrect answer: By using the . syntax with the struct name. 34 | Incorrect answer: By using the : syntax with the struct name. 35 | In -------------------------------------------------------------------------------- /experiments/hand-scoring/003/questions/ch10-03-lifetime-synt-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | Question: Which of the following is a lifetime annotation? 2 | Correct answer: 'a 3 | Incorrect answer: a 4 | Incorrect answer: ' 5 | Incorrect answer: "a" 6 | 7 | Question: Which of the following is not a lifetime annotation? 8 | Correct answer: a 9 | Incorrect answer: 'a 10 | Incorrect answer: ' 11 | Incorrect answer: "a" 12 | 13 | Question: What do lifetime annotations do? 14 | Correct answer: Describe the relationships of the lifetimes of multiple references to each other 15 | Incorrect answer: Declare the generic lifetime parameters inside angle brackets between the function name and the parameter list 16 | Incorrect answer: Change how long any of the references live 17 | Incorrect answer: Affect the lifetimes 18 | 19 | Question: What is the main aim of lifetimes? 20 | Correct answer: To prevent dangling references 21 | Incorrect answer: To prevent the use of references 22 | Incorrect answer: To stop references from being valid 23 | Incorrect answer: To change the scope of references 24 | 25 | Question: What is the difference between a reference's lifetime and a generic lifetime parameter? 26 | Correct answer: A reference's lifetime is how long the reference is valid, while a generic lifetime parameter is a placeholder for the reference's lifetime 27 | Incorrect answer: There is no difference 28 | Incorrect answer: A reference's lifetime is a placeholder for the lifetime of other references, while a generic lifetime parameter is how long the reference is valid 29 | Incorrect answer: A generic lifetime parameter is how long the reference is valid, while a reference's lifetime is a placeholder for the lifetime of other references -------------------------------------------------------------------------------- /experiments/hand-scoring/003/questions/ch10-03-lifetime-synt-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | Question: What is the first rule that the compiler uses to figure out the lifetimes of the references? 2 | Answer: The compiler assigns a lifetime parameter to each parameter that’s a reference. 3 | Incorrect answer: The compiler uses three rules to figure out the lifetimes of the references. 4 | Incorrect answer: The compiler assigns a lifetime parameter to each parameter. 5 | Incorrect answer: If there is exactly one input lifetime parameter, that lifetime is assigned to all output lifetime parameters. -------------------------------------------------------------------------------- /experiments/hand-scoring/003/questions/ch10-03-lifetime-synt-text-with-quiz-template-2.txt: -------------------------------------------------------------------------------- 1 | 2 | Question: What is the signature of the longest function after the first rule of lifetime elision is applied? 3 | Correct answer: fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &str 4 | Incorrect answer: fn longest<'a, 'b>(x: &str, y: &'a str) -> &'a str 5 | Incorrect answer: fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &'b str 6 | Incorrect answer: fn longest<'a, 'b>(x: &'a str, y: &'a str) -> &'b str 7 | 8 | 9 | Question: What is the signature of the longest function after the second rule of lifetime elision is applied? 10 | Correct answer: fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &str 11 | Incorrect answer: fn longest<'a, 'b>(x: &str, y: &'a str) -> &'a str 12 | Incorrect answer: fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &'b str 13 | Incorrect answer: fn longest<'a, 'b>(x: &'a str, y: &'a str) -> &'b str 14 | 15 | 16 | Question: Which rule of lifetime elision does not apply to the longest function? 17 | Correct answer: The second rule 18 | Incorrect answer: The first rule 19 | Incorrect answer: The third rule 20 | Incorrect answer: The lifetime elision rules do not apply to the longest function 21 | 22 | 23 | Question: Which statement best describes the lifetime of a string literal? 24 | Correct answer: The lifetime of a string literal is 'static. 25 | Incorrect answer: The lifetime of a string literal is the same as the lifetime of the variable it is assigned to. 26 | Incorrect answer: The lifetime of a string literal is shorter than the lifetime of the variable it is assigned to. 27 | Incorrect answer: The lifetime of a string literal is the same as -------------------------------------------------------------------------------- /experiments/hand-scoring/004/questions/ch03-02-data-typ-template-with-main-ideas-0.txt: -------------------------------------------------------------------------------- 1 | Rust has four primary scalar types: integers, floating-point numbers, Booleans, and characters. 2 | Question: Which of the following is a scalar type? 3 | Correct answer: Integer 4 | Incorrect answer: Tuple 5 | Incorrect answer: Array 6 | Incorrect answer: String 7 | 8 | Idea: A tuple is a general way of grouping together a number of values with a variety of types into one compound type. 9 | Question: What is a tuple? 10 | Correct answer: A general way of grouping together a number of values with a variety of types into one compound type. 11 | Incorrect answer: A general way of grouping together a number of values with the same type into one compound type. 12 | Incorrect answer: A way of grouping together a number of values with a variety of types into one compound type that can grow or shrink in size. 13 | Incorrect answer: A way of grouping together a number of values with the same type into one compound type that can grow or shrink in size. 14 | 15 | Idea: Every value in Rust is of a certain data type, which tells Rust what kind of data is being specified so it knows how to work with that data. 16 | Question: What does a data type do? 17 | Correct answer: Tell Rust what kind of data is being specified so it knows how to work with that data. 18 | Incorrect answer: Tell Rust what kind of data is returned so it knows how to work with that data. 19 | Incorrect answer: Tell Rust what kind of data is being specified so it knows how to work with that data and if it's valid data. 20 | Incorrect answer: Store data that can be used by Rust. 21 | 22 | Idea: If you're unsure which integer type to use, Rust's defaults are generally good places to start: integer types default to i32. 23 | Question: What's a good default integer type to use if you're unsure? 24 | Correct answer: i32 25 | Incorrect answer: u32 26 | Incorrect answer: isize 27 | Incorrect answer: usize 28 | 29 | Idea: An array is a single chunk of memory of a known, fixed size that can be allocated on the stack. 30 | Question: What is an array? -------------------------------------------------------------------------------- /experiments/hand-scoring/004/questions/ch05-03-method-synt-template-with-main-ideas-0.txt: -------------------------------------------------------------------------------- 1 | Defining methods within the context of a struct 2 | Question: Methods are analogous to which of the following? 3 | Correct answer: Functions 4 | Incorrect answer: Structs 5 | Incorrect answer: Variables 6 | Incorrect answer: Traits 7 | 8 | Idea: The first parameter in a method is always self 9 | Question: Which of the following is true about the first parameter in a method? 10 | Correct answer: It is always self 11 | Incorrect answer: It can be any name 12 | Incorrect answer: It is always a reference 13 | Incorrect answer: It has to be the same type as the struct 14 | 15 | Idea: Associated functions are not methods 16 | Question: Which of the following is true about associated functions? 17 | Correct answer: They don't have a self parameter 18 | Incorrect answer: They can be called with the struct's name 19 | Incorrect answer: They can only be called on an instance of a struct 20 | Incorrect answer: They can take multiple parameters 21 | 22 | Idea: Multiple impl blocks are valid syntax 23 | Question: Can a struct have multiple impl blocks? 24 | Correct answer: Yes 25 | Incorrect answer: No 26 | Incorrect answer: Only for generic types 27 | Incorrect answer: Only for trait objects -------------------------------------------------------------------------------- /experiments/hand-scoring/004/questions/ch10-03-lifetime-synt-template-with-main-ideas-0.txt: -------------------------------------------------------------------------------- 1 | Rust provides a borrow checker to ensure data referenced by a variable will not go out of scope before the variable does. 2 | Question: Why does Rust provide a borrow checker? 3 | Correct answer: To ensure data referenced by a variable will not go out of scope before the variable does. 4 | Incorrect answer: To ensure variables are declared before they are used. 5 | Incorrect answer: To ensure variables are initialized before they are used. 6 | Incorrect answer: To ensure all variables are used before the program ends. 7 | 8 | Idea: Every reference in Rust has a lifetime, which is the scope for which that reference is valid. 9 | Question: What is a lifetime? 10 | Correct answer: The scope for which a reference is valid. 11 | Incorrect answer: The amount of time a program will take to execute. 12 | Incorrect answer: The amount of data a program will process. 13 | Incorrect answer: The amount of memory a program will use. 14 | 15 | Idea: Most of the time, lifetimes are implicit and inferred, just like most of the time, types are inferred. 16 | Question: How are lifetimes handled most of the time? 17 | Correct answer: Implicitly and inferred, like most types. 18 | Incorrect answer: Always explicitly specified. 19 | Incorrect answer: Explicitly specified when multiple types are possible. 20 | Incorrect answer: Explicitly specified when multiple lifetimes are possible. 21 | 22 | Idea: One detail we didn’t discuss in the “References and Borrowing” section in Chapter 4 is that every reference in Rust has a lifetime. 23 | Question: What detail about references was not discussed in the “References and Borrowing” section of Chapter 4? 24 | Correct answer: Every reference has a lifetime. 25 | Incorrect answer: References can only point to data. 26 | Incorrect answer: Data can only have one reference to it. 27 | Incorrect answer: Mutable references cannot point to immutable data. 28 | 29 | Idea: Annotating lifetimes is not even a concept most other programming languages have. 30 | Question: What is true about annotations in Rust? 31 | Correct answer: Annotating lifetimes is not a concept in most other programming languages -------------------------------------------------------------------------------- /experiments/hand-scoring/004/questions/ch10-03-lifetime-synt-template-with-main-ideas-1.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | In Rust, every reference has a lifetime and you need to specify lifetime parameters for functions with references. 4 | 5 | Question: 6 | 7 | What is true about references in Rust? 8 | 9 | Correct answer: 10 | 11 | Every reference has a lifetime. 12 | 13 | Incorrect answer: 14 | 15 | Lifetime parameters are only required for functions with references. 16 | 17 | Incorrect answer: 18 | 19 | Lifetime parameters can only be specified for function parameters. 20 | 21 | Incorrect answer: 22 | 23 | Lifetime parameters are not required for return values. -------------------------------------------------------------------------------- /experiments/hand-scoring/004/questions/ch10-03-lifetime-synt-template-with-main-ideas-2.txt: -------------------------------------------------------------------------------- 1 | The lifetimes of references in a function signature are determined by applying elision rules. 2 | Question: Which of the following is an elision rule? 3 | Correct answer: Each parameter gets its own lifetime. 4 | Incorrect answer: The lifetime of the one input parameter gets assigned to the output lifetime. 5 | Incorrect answer: Lifetimes in a method signature are always assigned to self. 6 | Incorrect answer: If there is exactly one input lifetime, the lifetime of the one input parameter gets assigned to the output lifetime. 7 | 8 | Idea: Each parameter gets its own lifetime. 9 | Question: What is the signature of a function with one parameter after applying the first elision rule? 10 | Correct answer: fn first_word<'a>(s: &'a str) -> &'a str 11 | Incorrect answer: fn first_word<'a>(s: &'ns str) -> &'a str 12 | Incorrect answer: fn first_word<'a>(s: &'a str) -> &'s str 13 | Incorrect answer: fn first_word<'a>(s: &'ns str) -> &'s str 14 | 15 | Idea: The lifetime of the one input parameter gets assigned to the output lifetime. 16 | Question: What is the signature of a function with one parameter after applying the second elision rule? 17 | Correct answer: fn first_word<'a>(s: &'a str) -> &'a str 18 | Incorrect answer: fn first_word<'a>(s: &'a str) -> &'ns str 19 | Incorrect answer: fn first_word<'a>(s: &'ns str) -> &'a str 20 | Incorrect answer: fn first_word<'a>(s: &'ns str) -> &'ns str 21 | 22 | Idea: The lifetime of &self gets assigned to the output lifetime. 23 | Question: What is the signature of a function with one parameter after applying the third elision rule? 24 | Correct answer: fn first_word<'a>(s: &'a str) -> &'a str 25 | Incorrect answer: fn first_word<'a>( -------------------------------------------------------------------------------- /experiments/hand-scoring/005/prompts/rust-book-method-syntax-text-only-1.txt: -------------------------------------------------------------------------------- 1 | Based on the text between the =====, generate 5 multiple-choice questions to test a reader's comprehension of the text's concepts 2 | 3 | ===== 4 | 5 | 6 | 7 | ===== 8 | 5 multiple-choice questions: -------------------------------------------------------------------------------- /experiments/hand-scoring/005/prompts/rust-book-method-syntax-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | Based on the text between the =====, generate 5 multiple-choice questions to test a reader's comprehension of the text's concepts 2 | 3 | ===== 4 | 5 | 6 | ===== 7 | 8 | Use the following format for each question: 9 | Question: 10 | Correct answer: 11 | Incorrect answer: 12 | Incorrect answer: 13 | Incorrect answer: 14 | 15 | 5 multiple-choice questions: 16 | 17 | Question: -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/mdn-functions-text-only-0.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What is the main purpose of a function? 4 | 5 | A. To allow you to store a piece of code that does a single task inside a defined block 6 | 7 | B. To provide built-in code for common tasks 8 | 9 | C. To allow you to call a block of code multiple times without having to type it out each time 10 | 11 | D. To support optional parameters 12 | 13 | 2. What is the difference between a function and a method? 14 | 15 | A. A function is a custom block of code while a method is a built-in function 16 | 17 | B. A method is a custom block of code while a function is a built-in function 18 | 19 | C. A function is a block of code associated with an object while a method is a block of code not associated with an object 20 | 21 | D. There is no difference between a function and a method 22 | 23 | 3. What is an anonymous function? 24 | 25 | A. A function that has no name 26 | 27 | B. A function that is not part of the core JavaScript language 28 | 29 | C. A function that is defined by the browser 30 | 31 | D. A function that is defined by the user 32 | 33 | 4. What does the addEventListener() function do? 34 | 35 | A. It generates a random number 36 | 37 | B. It calls a function when an event happens 38 | 39 | C. It replaces a specified string with a new string 40 | 41 | D. It joins all the items in an array together into a single string 42 | 43 | 5. What is the default value of the parameter for the array join() function? 44 | 45 | A. A comma 46 | 47 | B. An empty string 48 | 49 | C. 0 50 | 51 | D. 1 -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/mdn-functions-text-only-1.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What is the difference between an arrow function and a regular function? 4 | 5 | A. Arrow functions do not have a return statement. 6 | B. Arrow functions have a shorter syntax. 7 | C. Arrow functions do not have their own scope. 8 | D. Arrow functions cannot be used as event listeners. 9 | 10 | 2. What does the map() method do? 11 | 12 | A. It takes each item in an array and passes it into a given function. 13 | B. It creates a new array from the values returned by a given function. 14 | C. It assigns a new value to a given variable. 15 | D. It prints out the value of a given variable. 16 | 17 | 3. What is the global scope? 18 | 19 | A. The top level outside all functions. 20 | B. The lion enclosure at the zoo. 21 | C. The part of the code that is locked away in functions. 22 | D. The console in the browser developer tools. 23 | 24 | 4. What will happen if you try to print a variable that is not in the same scope as the function? 25 | 26 | A. It will print out the value of the variable. 27 | B. It will throw an error. 28 | C. It will print out the value of a different variable. 29 | D. It will print out undefined. 30 | 31 | 5. What is the purpose of keeping parts of your code locked away in functions? 32 | 33 | A. To avoid conflicts with other parts of the code. 34 | B. To make the code more readable. 35 | C. To make the code shorter. 36 | D. To make the code more secure. -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/mdn-functions-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is a function? 2 | A: A store for a piece of code that does a single task that is defined in a block 3 | B: A built in browser code that can't be written in JavaScript 4 | C: A code that is defined in your custom browser 5 | D: A code that is part of an object 6 | 7 | Correct answer: A 8 | Incorrect answer: B 9 | Incorrect answer: C 10 | Incorrect answer: D 11 | 12 | Question: What is the purpose of a function? 13 | A: To allow you to store a piece of code that does a single task inside a defined block 14 | B: To call that code whenever you need it using a single short command 15 | C: To clear up any possible confusion of method versus function 16 | D: All of the above 17 | 18 | Correct answer: D 19 | Incorrect answer: A 20 | Incorrect answer: B 21 | Incorrect answer: C 22 | 23 | Question: What is the difference between a function and a method? 24 | A: A function is part of an object while a method is not 25 | B: A method is part of an object while a function is not 26 | C: A function is a code that is defined in your custom browser while a method is not 27 | D: There is no difference between a function and a method 28 | 29 | Correct answer: A 30 | Incorrect answer: B 31 | Incorrect answer: C 32 | Incorrect answer: D 33 | 34 | Question: What is an anonymous function? 35 | A: A function that doesn't have a name 36 | B: A function that has a name 37 | C: A function that is part of an object 38 | D: A function that is part of the browser 39 | 40 | Correct answer: A 41 | Incorrect answer: B 42 | Incorrect answer: C 43 | Incorrect answer: D 44 | 45 | Question: What is the difference between a built in function and a custom function? 46 | A: A built in function is a code that is part of an object while a custom function is not 47 | B: A built in function is part of the browser while a custom function is not 48 | C: A custom function is part of an object while a built in function is not 49 | D: There is no difference between a built in function and a custom -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/mdn-functions-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is a function in JavaScript? 2 | A: A set of code that runs when it is called 3 | B: A block of code that cannot be accessed by code outside it 4 | C: A value that is returned by a function 5 | D: A block of code that is run only once 6 | 7 | Correct answer: A: A set of code that runs when it is called 8 | Incorrect answer: B: A block of code that cannot be accessed by code outside it 9 | Incorrect answer: C: A value that is returned by a function 10 | Incorrect answer: D: A block of code that is run only once 11 | 12 | Question: What is the global scope? 13 | A: The top level outside all your functions 14 | B: values defined in the global scope are accessible from everywhere in the code 15 | C: the lions, zebras, tigers, and penguins are kept in their own enclosures 16 | 17 | Correct answer: B: values defined in the global scope are accessible from everywhere in the code 18 | Incorrect answer: A: The top level outside all your functions 19 | Incorrect answer: C: the lions, zebras, tigers, and penguins are kept in their own enclosures 20 | 21 | Question: What is the purpose of keeping parts of your code locked away in functions? 22 | A: To avoid having to write the same code multiple times 23 | B: To keep variables and other things defined inside the function from being accessed by code outside the function 24 | C: To make your code shorter and more readable 25 | 26 | Correct answer: B: To keep variables and other things defined inside the function from being accessed by code outside the function 27 | Incorrect answer: A: To avoid having to write the same code multiple times 28 | Incorrect answer: C: To make your code shorter and more readable 29 | 30 | Question: What is an arrow function? 31 | A: A function that can be called from anywhere in the code 32 | B: A function that can take any number of parameters 33 | C: A function that only has one line in the curly brackets 34 | 35 | Correct answer: C: A function that only has one line in the curly brackets 36 | Incorrect answer: A: A function that can be called from anywhere in the code -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/mdn-objects-text-only-0.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What is an object in JavaScript? 4 | a) A data type 5 | b) A collection of related data and/or functionality 6 | c) A function 7 | d) An HTML element 8 | 9 | 2. How do you create an object in JavaScript? 10 | a) By initializing a variable 11 | b) By using a constructor 12 | c) By using an object literal 13 | d) By chaining dot notation 14 | 15 | 3. What is the difference between a property and a method in an object? 16 | a) A property is a function while a method is data 17 | b) A property is data while a method is a function 18 | c) A property is an array while a method is an object 19 | d) There is no difference 20 | 21 | 4. What does the keyword "this" refer to in an object? 22 | a) The object's methods 23 | b) The object's properties 24 | c) The current object the code is being written inside 25 | d) The object's values 26 | 27 | 5. What is the purpose of prototypes in JavaScript? 28 | a) To create an object instance 29 | b) To allow an object to inherit properties from other objects 30 | c) To provide structure for an object 31 | d) To instantiate a new object -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/mdn-objects-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is an object? 2 | Correct answer: A collection of related data and/or functionality 3 | Incorrect answer: A programming language 4 | Incorrect answer: A file type 5 | Incorrect answer: A software development method 6 | 7 | Question: What is an object property? 8 | Correct answer: A value that is associated with a name 9 | Incorrect answer: A function that is associated with a name 10 | Incorrect answer: A name that is associated with a value 11 | Incorrect answer: A value that is associated with a function 12 | 13 | Question: What is an object method? 14 | Correct answer: A function that is associated with a name 15 | Incorrect answer: A name that is associated with a function 16 | Incorrect answer: A value that is associated with a function 17 | Incorrect answer: A function that is associated with an object 18 | 19 | Question: What is an object literal? 20 | Correct answer: An object that is defined using curly braces {} 21 | Incorrect answer: An object that is defined using quotation marks "" 22 | Incorrect answer: An object that is defined using parentheses () 23 | Incorrect answer: An object that is defined using square brackets [] 24 | 25 | Question: What is a constructor? 26 | Correct answer: A function that is used to create an object 27 | Incorrect answer: A function that is used to modify an object 28 | Incorrect answer: A function that is used to destroy an object 29 | Incorrect answer: A function that is used to access an object -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/mdn-promises-text-only-0.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1) What is a Promise in JavaScript? 4 | A) an object that represents an asynchronous function 5 | B) an object that represents a synchronous function 6 | C) an object returned by an asynchronous function 7 | 8 | 2) What is the modern, promise-based replacement for XMLHttpRequest? 9 | A) the fetch() API 10 | B) the XMLHttpRequest API 11 | C) the then() API 12 | 13 | 3) How do you handle errors when using promises? 14 | A) By adding a catch() handler to the end of the promise chain 15 | B) By adding a then() handler to the end of the promise chain 16 | C) By adding a success() handler to the end of the promise chain 17 | 18 | 4) What is the purpose of Promise.all()? 19 | A) To start all promises at the same time 20 | B) To handle errors for all promises 21 | C) To be notified when all promises have been fulfilled 22 | 23 | 5) What is the status code for a successful HTTP request? 24 | A) 200 25 | B) 404 26 | C) 500 -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/mdn-promises-text-only-1.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What does adding the "async" keyword to a function do? 4 | a. Makes the function an asynchronous function 5 | b. Allows the function to use the "await" keyword 6 | c. Returns a promise from the function 7 | d. Makes the function return its value immediately 8 | 9 | 2. What is the difference between "Promise.all" and "Promise.any"? 10 | a. "Promise.all" is fulfilled as soon as any of the array of promises is fulfilled, while "Promise.any" is fulfilled when all of the array of promises is fulfilled 11 | b. "Promise.all" is fulfilled when all of the array of promises is fulfilled, while "Promise.any" is fulfilled as soon as any of the array of promises is fulfilled 12 | c. "Promise.all" is fulfilled when all of the array of promises is rejected, while "Promise.any" is fulfilled when any of the array of promises is fulfilled 13 | d. "Promise.all" is fulfilled when any of the array of promises is rejected, while "Promise.any" is fulfilled when all of the array of promises is fulfilled 14 | 15 | 3. What is the output of the following code? 16 | ``` 17 | const fetchPromise1 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json'); 18 | const fetchPromise2 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found'); 19 | const fetchPromise3 = fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json'); 20 | 21 | Promise.all([fetchPromise1, fetchPromise2, fetchPromise3]) 22 | .then((responses) => { 23 | for (const response of responses) { 24 | console.log(`${response.url}: ${response.status}`); 25 | } 26 | }) 27 | .catch((error) -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/mdn-promises-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is a promise? 2 | Answer: 3 | A) An object that is returned by an asynchronous function, which represents the current state of the operation. 4 | B) A function that is called when an asynchronous operation is successful. 5 | C) A function that is called when an asynchronous operation is unsuccessful. 6 | D) A way to avoid having nested levels of code when using callbacks. 7 | 8 | Question: What state does a promise enter when the asynchronous function it is associated with is successful? 9 | Answer: 10 | A) fulfills 11 | B) promises 12 | C) rejected 13 | D) settled 14 | 15 | Question: How do you add a handler to a promise? 16 | Answer: 17 | A) By calling the .then() method and passing in a callback function. 18 | B) By calling the .error() method and passing in a callback function. 19 | C) By calling the .catch() method and passing in a callback function. 20 | D) By calling the .finally() method and passing in a callback function. 21 | 22 | Question: What is the difference between the .then() and .catch() methods? 23 | Answer: 24 | A) The .then() method is called when an asynchronous operation succeeds, while the .catch() method is called when an asynchronous operation fails. 25 | B) The .then() method is called when an asynchronous operation fails, while the .catch() method is called when an asynchronous operation succeeds. 26 | C) The .then() method is called when an asynchronous operation is finished, while the .catch() method is called when an asynchronous operation errors. 27 | D) There is no difference between the .then() and .catch() methods. 28 | 29 | Question: What is a benefit of using promises? 30 | Answer: 31 | A) You can avoid ever-increasing levels of indentation. 32 | B) You can chain together multiple asynchronous function calls. 33 | C) You can use the .all() method to start multiple asynchronous function calls at the same time. 34 | D) All of the above. -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/mdn-promises-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is a promise? 2 | Answer: A promise is an object that may produce a single value some time in the future: either a resolved value, or a reason that it's not resolved (e.g., a network error occurred). A promise may be in one of 3 possible states: fulfilled, rejected, or pending. 3 | Incorrect answer: A promise is a Boolean. 4 | Incorrect answer: A promise is a function. 5 | Incorrect answer: A promise is an array. 6 | 7 | Question: What is the function of the keyword "async"? 8 | Answer: The async keyword enables you to write asynchronous code as if it were synchronous code. 9 | Incorrect answer: The async keyword is used to declare a function. 10 | Incorrect answer: The async keyword is used to create an asynchronous function. 11 | Incorrect answer: There is no such thing as the async keyword. 12 | 13 | Question: What is the output of the following code? 14 | const fetchPromise1 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json'); 15 | const fetchPromise2 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found'); 16 | const fetchPromise3 = fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json'); 17 | 18 | Promise.all([fetchPromise1, fetchPromise2, fetchPromise3]) 19 | .then((responses) => { 20 | for (const response of responses) { 21 | console.log(`${response.url}: ${response.status}`); 22 | } 23 | }) 24 | .catch((error) => { 25 | console.error(`Failed to fetch: ${error}`) 26 | }); 27 | Answer: https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json: -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-data-types-text-only-0.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What does the Rust compiler need in order to know the type of all variables? 4 | 5 | A. The type annotation of the variable 6 | B. The value of the variable 7 | C. The context in which the variable is used 8 | D. All of the above 9 | 10 | 2. Which of the following is NOT a primary scalar type in Rust? 11 | 12 | A. Integers 13 | B. Floating-point numbers 14 | C. Characters 15 | D. Booleans 16 | 17 | 3. Which of the following is NOT a property of the f32 type? 18 | 19 | A. 32 bits in size 20 | B. IEEE-754 standard 21 | C. Double precision 22 | D. Single precision 23 | 24 | 4. What is the range of Unicode Scalar Values that a char type in Rust can represent? 25 | 26 | A. U+0000 to U+D7FF 27 | B. U+E000 to U+10FFFF 28 | C. U+0000 to U+FFFF 29 | D. U+D800 to U+DFFF 30 | 31 | 5. What are the two primitive compound types in Rust? 32 | 33 | A. Tuples and arrays 34 | B. Strings and arrays 35 | C. Functions and arrays 36 | D. Tuples and structs -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-data-types-text-only-1.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What does a tuple allow you to do that an array does not? 4 | A. Bind to a single value 5 | B. Change in size 6 | C. Access elements by index 7 | D. Have values of different types 8 | 9 | 2. What is the output of the following program? 10 | let months = ["January", "February", "March", "April", "May", "June", "July", 11 | "August", "September", "October", "November", "December"]; 12 | 13 | let a = [3; 5]; 14 | 15 | println!("{}", a[months.len()]); 16 | 17 | A. 3 18 | B. 5 19 | C. An error 20 | D. December 21 | 22 | 3. What is the type of the following array? 23 | let a = [1, 2, 3, 4, 5]; 24 | 25 | A. [i32; 5] 26 | B. [f64; 5] 27 | C. [u8; 5] 28 | D. [i32] 29 | 30 | 4. What is the value of the following array element? 31 | let a = [3; 5]; 32 | 33 | println!("{}", a[2]); 34 | 35 | A. 2 36 | B. 3 37 | C. An error 38 | D. 5 39 | 40 | 5. What happens when you attempt to access an element of an array that is past the end of the array? 41 | 42 | A. An error 43 | B. The element is returned 44 | C. The program panics 45 | D. The program exits -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-data-types-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What does the text say Rust's floating-point types are based off of? 2 | Correct answer: The IEEE-754 standard 3 | Incorrect answer: The APA standard 4 | Incorrect answer: The AMA standard 5 | Incorrect answer: The MLA standard 6 | 7 | Question: What does the text say is the size of a Boolean value in Rust? 8 | Correct answer: One byte 9 | Incorrect answer: Two bytes 10 | Incorrect answer: Four bytes 11 | Incorrect answer: Eight bytes 12 | 13 | Question: What does the text say Rust's char type represents? 14 | Correct answer: A Unicode Scalar Value 15 | Incorrect answer: An ASCII code 16 | Incorrect answer: A number 17 | Incorrect answer: A character 18 | 19 | Question: What are the two possible values for a Boolean type? 20 | Correct answer: True and false 21 | Incorrect answer: On and off 22 | Incorrect answer: 0 and 1 23 | Incorrect answer: Right and wrong 24 | 25 | Question: What are the two primitive compound types in Rust? 26 | Correct answer: Tuples and arrays 27 | Incorrect answer: Strings and characters 28 | Incorrect answer: Floats and integers 29 | Incorrect answer: Signs and unsigned numbers -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-data-types-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is a tuple in Rust? 2 | A) A general way of grouping together a number of values with a variety of types into one compound type 3 | B) A flexible collection type that is allowed to grow or shrink in size 4 | C) A single chunk of memory of a known, fixed size that is allocated on the stack 5 | D) An expression that implicitly returns the unit value 6 | 7 | Correct answer: A) A general way of grouping together a number of values with a variety of types into one compound type 8 | Incorrect answer: B) A flexible collection type that is allowed to grow or shrink in size 9 | Incorrect answer: C) A single chunk of memory of a known, fixed size that is allocated on the stack 10 | Incorrect answer: D) An expression that implicitly returns the unit value 11 | 12 | Question: What is an array in Rust? 13 | A) A general way of grouping together a number of values with a variety of types into one compound type 14 | B) A flexible collection type that is allowed to grow or shrink in size 15 | C) A single chunk of memory of a known, fixed size that is allocated on the stack 16 | D) An expression that implicitly returns the unit value 17 | 18 | Correct answer: C) A single chunk of memory of a known, fixed size that is allocated on the stack 19 | Incorrect answer: A) A general way of grouping together a number of values with a variety of types into one compound type 20 | Incorrect answer: B) A flexible collection type that is allowed to grow or shrink in size 21 | Incorrect answer: D) An expression that implicitly returns the unit value 22 | 23 | Question: What is the unit type in Rust? 24 | A) A general way of grouping together a number of values with a variety of types into one compound type 25 | B) A flexible collection type that is allowed to grow or shrink in size 26 | C) A single chunk of memory of a known, fixed size that is allocated on the stack 27 | D) An empty value that represents an empty return type 28 | 29 | Correct answer: D) An empty value that represents an empty return type 30 | Incorrect answer: A) A general way of grouping together a number of values with a variety of types into one compound type -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-lifetime-syntax-text-only-0.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What is the main aim of lifetimes? 4 | a. To prevent dangling references 5 | b. To ensure references are valid 6 | c. To compare scopes 7 | d. To annotate relationships 8 | 9 | 2. How does Rust determine whether references are valid? 10 | a. By using a borrow checker 11 | b. By annotating lifetimes 12 | c. By comparing scopes 13 | d. By analyzing lifetimes 14 | 15 | 3. What is the significance of generic lifetime parameters? 16 | a. They help Rust determine whether the reference being returned refers to x or y. 17 | b. They describe the relationships of the lifetimes of multiple references to each other without affecting the lifetimes. 18 | c. They ensure that the actual references used at runtime are definitely valid. 19 | d. They prevent dangling references. 20 | 21 | 4. What is the syntax for lifetime annotations? 22 | a. The names of lifetime parameters must start with an apostrophe ('). 23 | b. Lifetime annotations are placed after the parameter list, using a space to separate the annotation from the reference's type. 24 | c. Most people use the name 'a for the first lifetime annotation. 25 | d. All of the above. 26 | 27 | 5. What is the relationship between the lifetimes of the parameters and the return value in the longest function? 28 | a. The return value will be valid as long as the parameters are valid. 29 | b. The return value will be valid as long as one of the parameters is valid. 30 | c. There is no relationship between the lifetimes of the parameters and the return value. 31 | d. The return value will be valid as long as the lifetime of the longest string slice is valid. -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-lifetime-syntax-text-only-1.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What is the main difference between a string slice and a string literal? 4 | 5 | a) A string slice is a reference to a string, while a string literal is a string value. 6 | b) A string slice is a piece of a string, while a string literal is a string value. 7 | c) A string slice can be mutable, while a string literal cannot. 8 | d) There is no difference between string slices and string literals. 9 | 10 | 2. What does the lifetime annotation 'a in fn longest<'a>(x: &'a str, y: &'a str) -> &'a str mean? 11 | 12 | a) That the function takes two string slice parameters and returns the longest string slice. 13 | b) That the function takes two string parameters and returns the longest string. 14 | c) That the lifetime of the returned string slice is the same as the lifetime of the shorter of the two string slice parameters. 15 | d) That the lifetime of the returned string slice is the same as the lifetime of the longer of the two string slice parameters. 16 | 17 | 3. What does the lifetime annotation 'a in struct ImportantExcerpt<'a> mean? 18 | 19 | a) That the struct holds a string slice reference which must have the same lifetime as the struct. 20 | b) That the struct holds a string reference which must have the same lifetime as the struct. 21 | c) That the struct holds a string slice reference which must have a shorter lifetime than the struct. 22 | d) That the struct holds a string reference which must have a shorter lifetime than the struct. 23 | 24 | 4. Which of the following code snippets would not compile? 25 | 26 | a) 27 | 28 | fn main() { 29 | let string1 = String::from("abcd"); 30 | let string2 = "efghijklmnopqrstuvwxyz"; 31 | 32 | let result = longest(string1.as_str(), string2); 33 | println!("The longest string is {}", result); -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-lifetime-syntax-text-only-2.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. Why did the Rust team find thatRust programmers were entering the same lifetime annotations over and over in particular situations? 4 | A. To make the code more consistent 5 | B. Because the code wouldn't compile without them 6 | C. To avoid having to write explicit lifetimes 7 | D. To make theborrow checker's job easier 8 | 9 | 2. What does the first rule of lifetime elision dictate? 10 | A. That each parameter gets its own lifetime 11 | B. That the lifetime of the one input parameter gets assigned to the output lifetime 12 | C. That the lifetime of self is assigned to all output lifetime parameters 13 | D. That more deterministic patterns will be programmed into the compiler 14 | 15 | 3. Which rule applies when there is more than one input lifetime parameter and one of them is &self or &mut self? 16 | A. The second rule 17 | B. The third rule 18 | C. The first rule 19 | D. There is no rule that applies 20 | 21 | 4. What does the lifetime 'static denote? 22 | A. That the affected reference can live for the entire duration of the program 23 | B. That the code can be applied to different types 24 | C. That the code won't have any dangling references 25 | D. That the code is generic 26 | 27 | 5. What is the primary benefit of using generic type parameters? 28 | A. That the code can be applied to different types 29 | B. That the code is more consistent 30 | C. That the code is generic 31 | D. That the code is easier to read -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-lifetime-syntax-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is the main aim of lifetimes? 2 | A) To prevent dangling references 3 | B) To ensure references are valid 4 | C) To annotate the relationships between references 5 | D) To calculate the longest string 6 | 7 | Correct answer: To prevent dangling references 8 | Incorrect answer: To ensure references are valid 9 | Incorrect answer: To annotate the relationships between references 10 | Incorrect answer: To calculate the longest string 11 | 12 | Question: What does Rust use to determine whether all borrows are valid? 13 | A) A compiler 14 | B) An interpreter 15 | C) A borrow checker 16 | D) A runtime 17 | 18 | Correct answer: A borrow checker 19 | Incorrect answer: A compiler 20 | Incorrect answer: An interpreter 21 | Incorrect answer: A runtime 22 | 23 | Question: How do you declare lifetime parameters in a function signature? 24 | A) Between the function name and the parameter list 25 | B) After the parameter list 26 | C) Before the parameter list 27 | D) In the body of the function 28 | 29 | Correct answer: Between the function name and the parameter list 30 | Incorrect answer: After the parameter list 31 | Incorrect answer: Before the parameter list 32 | Incorrect answer: In the body of the function 33 | 34 | Question: What is the relationship between the lifetimes of the parameters and the return value in the longest function? 35 | A) The lifetime of the return value is the same as the lifetime of the parameters. 36 | B) The lifetime of the return value is shorter than the lifetime of the parameters. 37 | C) The lifetime of the return value is longer than the lifetime of the parameters. 38 | 39 | Correct answer: The lifetime of the return value is the same as the lifetime of the parameters. 40 | Incorrect answer: The lifetime of the return value is shorter than the lifetime of the parameters. 41 | Incorrect answer: The lifetime of the return value is longer than the lifetime of the parameters. 42 | 43 | Question: When does Rust require you to annotate types? 44 | A) When multiple types are possible 45 | B) When the type is unknown 46 | C) When the type is a reference 47 | D) When the type is a struct 48 | 49 | Correct answer: When multiple types are possible 50 | Incorrect answer: When the type is -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-lifetime-syntax-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | 2 | What does the longest function signature telling Rust? 3 | A. That the lifetime of the reference returned from the longest function is the same as the lifetime of the smaller of the values of the function arguments 4 | B. That the function takes two parameters, both of which are string slices that live at least as long as the lifetime of the function 5 | C. That the function signature tells Rust to use the relationships when analyzing the code 6 | D. That the lifetime of the reference returned by the longest function is the same as the lifetime of the values of the function arguments 7 | 8 | Correct answer: B. That the function takes two parameters, both of which are string slices that live at least as long as the lifetime of the function. 9 | Incorrect answer: A. That the lifetime of the reference returned from the longest function is the same as the lifetime of the smaller of the values of the function arguments 10 | Incorrect answer: C. That the function signature tells Rust to use the relationships when analyzing the code 11 | Incorrect answer: D. That the lifetime of the reference returned by the longest function is the same as the lifetime of the values of the function arguments 12 | 13 | Question: 14 | What is the lifetime of the reference in result must be the smaller lifetime of the two arguments? 15 | A. The lifetime of the first argument 16 | B. The lifetime of the second argument 17 | C. The lifetime of the reference in result 18 | D. The lifetime of the smaller of the two arguments 19 | 20 | Correct answer: D. The lifetime of the smaller of the two arguments 21 | Incorrect answer: A. The lifetime of the first argument 22 | Incorrect answer: B. The lifetime of the second argument 23 | Incorrect answer: C. The lifetime of the reference in result 24 | 25 | Question: 26 | Why is the return value lifetime is not related to the lifetime of the parameters? 27 | A. The return value lifetime is not connected to the lifetime of the parameters at all 28 | B. The return value lifetime must match the lifetime of one of the parameters 29 | C. The data inside the return value must be related to the lifetime of the parameters 30 | D. The return value lifetime is connected to the lifetime of the shorter of the two parameters 31 | 32 | Correct answer: A. -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-lifetime-syntax-text-with-quiz-template-2.txt: -------------------------------------------------------------------------------- 1 | What is the reason the function in Listing 10-25 compiles without lifetime annotations? 2 | A) Early versions of Rust didn't require explicit lifetimes for references. 3 | B) The Rust team found that Rust programmers were entering the same lifetime annotations over and over. 4 | C) The developers programmed patterns into the compiler's code so the borrow checker could infer the lifetimes in these situations. 5 | D) TheRust team discovered deterministic patterns that could be applied to eliminate the need for explicit lifetime annotations. 6 | 7 | Correct answer: C) The developers programmed patterns into the compiler's code so the borrow checker could infer the lifetimes in these situations. 8 | 9 | Incorrect answer: A) Early versions of Rust didn't require explicit lifetimes for references. 10 | Incorrect answer: B) The Rust team found that Rust programmers were entering the same lifetime annotations over and over. 11 | Incorrect answer: D) TheRust team discovered deterministic patterns that could be applied to eliminate the need for explicit lifetime annotations. 12 | 13 | Question: What does the first rule of the lifetime elision rules specify? 14 | A) That the lifetime of &self is assigned to all output lifetime parameters 15 | B) That the lifetime of one input parameter gets assigned to the output lifetime 16 | C) That each parameter gets its own lifetime 17 | 18 | Answer: C) That each parameter gets its own lifetime 19 | 20 | Incorrect answer: A) That the lifetime of &self is assigned to all output lifetime parameters 21 | Incorrect answer: B) That the lifetime of one input parameter gets assigned to the output lifetime 22 | 23 | Question: After applying the first lifetime elision rule, what would the signature of the first_word function in Listing 10-25 be? 24 | 25 | A) fn first_word<'a>(s: &'a str) -> &'a str 26 | B) fn first_word<'a>(s: &'a str) -> &str 27 | C) fn first_word(s: &str) -> &str 28 | 29 | Answer: B) fn first_word<'a>(s: &'a str) -> &str 30 | 31 | Incorrect answer: A) fn first_word<'a -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-method-syntax-text-only-0.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1. What keyword do you use to declare a method? 4 | 5 | a. fn 6 | b. method 7 | c. struct 8 | d. impl 9 | 10 | 2. What is the first parameter of a method always named? 11 | 12 | a. self 13 | b. method 14 | c. struct 15 | d. impl 16 | 17 | 3. Which of the following is not a reason to use a method instead of a function? 18 | 19 | a. to provide method syntax 20 | b. to prevent the caller from using the original instance after the transformation 21 | c. to provide an associated function that doesn't need an instance of the type 22 | d. to organize related capabilities together 23 | 24 | 4. What is the difference between an associated function and a method? 25 | 26 | a. Associated functions don't take self as a first parameter, while methods do. 27 | b. Methods are associated with a struct, while associated functions can be associated with any type. 28 | c. Associated functions are defined within an impl block, while methods are not. 29 | d. There is no difference between an associated function and a method. 30 | 31 | 5. Which of the following is not a way to create a custom type in Rust? 32 | 33 | a. Structs 34 | b. Traits 35 | c. Enums 36 | d. Functions -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-method-syntax-text-only-1.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 1) What is the main idea of the text? 4 | 5 | A) The importance of following your dreams 6 | 7 | B) The dangers of not perusing your passions 8 | 9 | C) The difficulty of making a life-changing decision 10 | 11 | 2) What does the author say about making a life-changing decision? 12 | 13 | A) It is always a good idea 14 | 15 | B) It is a difficult decision to make 16 | 17 | C) You should always consult with others before making a decision 18 | 19 | 3) What is the author's purpose for writing this text? 20 | 21 | A) To persuade the reader to follow their dreams 22 | 23 | B) To warn the reader of the dangers of not following their dreams 24 | 25 | C) To provide the reader with information about making life-changing decisions 26 | 27 | 4) What does the author say about following your dreams? 28 | 29 | A) It is always easy 30 | 31 | B) It is worth it, even if it is difficult 32 | 33 | C) It is the only way to achieve happiness 34 | 35 | 5) What is the author's tone in the text? 36 | 37 | A) Inspiring 38 | 39 | B) Cautious 40 | 41 | C) Informative -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-method-syntax-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What does the 'impl' keyword do? 2 | 3 | A) Implementation for a struct 4 | B) Implementation for a function 5 | C) Implementation for a trait 6 | 7 | Correct answer: A) Implementation for a struct 8 | 9 | Incorrect answer: B) Implementation for a function 10 | Incorrect answer: C) Implementation for a trait 11 | Incorrect answer: D) Implementation for an enum 12 | 13 | Question: Where are methods defined? 14 | 15 | A) In an impl block 16 | B) In a struct 17 | C) In a function 18 | 19 | Correct answer: A) In an impl block 20 | 21 | Incorrect answer: B) In a struct 22 | Incorrect answer: C) In a function 23 | Incorrect answer: D) In an enum 24 | 25 | Question: What is the first parameter in a method signature always called? 26 | 27 | A) Self 28 | B) rect 29 | C) method 30 | 31 | Correct answer: A) Self 32 | 33 | Incorrect answer: B) rect 34 | Incorrect answer: C) method 35 | Incorrect answer: D) parameter 36 | 37 | Question: What is the difference between a method and a function? 38 | 39 | A) A method is defined within the context of a struct 40 | B) A method's first parameter is always self 41 | C) A function is defined within the context of a struct 42 | 43 | Correct answer: B) A method's first parameter is always self 44 | 45 | Incorrect answer: A) A method is defined within the context of a struct 46 | Incorrect answer: C) A function is defined within the context of a struct 47 | Incorrect answer: D) A method can take multiple parameters 48 | 49 | Question: What is an associated function? 50 | 51 | A) A function that doesn't have a self parameter 52 | B) A function that is associated with a type 53 | C) A method that is associated with a type 54 | 55 | Correct answer: B) A function that is associated with a type 56 | 57 | Incorrect answer: A) A function that doesn't have a self parameter 58 | Incorrect answer: C) A method that is associated with a type 59 | Incorrect answer: D) A function that is defined within the context of a struct -------------------------------------------------------------------------------- /experiments/hand-scoring/005/questions/rust-book-method-syntax-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is the name of the author of the text? 2 | Correct answer: Julia Cook 3 | Incorrect answer: John Cook 4 | Incorrect answer: Julie Cook 5 | Incorrect answer: Jacob Cook 6 | 7 | Question: What is the main idea of the text? 8 | Correct answer: The importance of being able to understand and manage anger 9 | Incorrect answer: The importance of being able to understand and manage sadness 10 | Incorrect answer: The importance of being able to understand and manage fear 11 | Incorrect answer: The importance of being able to understand and manage anxiety 12 | 13 | Question: How can anger be managed? 14 | Correct answer: Breathing slowly and deeply 15 | Incorrect answer: Sleeping 16 | Incorrect answer: Eating 17 | Incorrect answer: Exercising 18 | 19 | Question: What should you do if you can't calm down? 20 | Correct answer: Get some help 21 | Incorrect answer: Ignore it 22 | Incorrect answer: cry 23 | Incorrect answer: shout 24 | 25 | Question: What is the tone of the text? 26 | Correct answer: Informative 27 | Incorrect answer: Sarcastic 28 | Incorrect answer: Angry 29 | Incorrect answer: Happy -------------------------------------------------------------------------------- /experiments/hand-scoring/006/prompts/rust-book-method-syntax-text-only-1.txt: -------------------------------------------------------------------------------- 1 | Based on the text between the =====, generate 5 multiple-choice questions to test a reader's comprehension of the text's concepts 2 | 3 | ===== 4 | 5 | 6 | 7 | ===== 8 | 5 multiple-choice questions: -------------------------------------------------------------------------------- /experiments/hand-scoring/006/prompts/rust-book-method-syntax-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | Based on the text between the =====, generate 5 multiple-choice questions to test a reader's comprehension of the text's concepts 2 | 3 | ===== 4 | 5 | 6 | ===== 7 | 8 | Use the following format for each question: 9 | Question: 10 | Correct answer: 11 | Incorrect answer: 12 | Incorrect answer: 13 | Incorrect answer: 14 | 15 | 5 multiple-choice questions: 16 | 17 | Question: -------------------------------------------------------------------------------- /experiments/hand-scoring/006/questions/rust-book-data-types-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | 2 | What does the text say about the Rust programming language? 3 | 4 | Correct answer: 5 | Rust is statically typed language. 6 | Incorrect answer: 7 | Rust is interpreted. 8 | Incorrect answer: 9 | Rust is object-oriented. 10 | Incorrect answer: 11 | Rust is functional. 12 | 13 | Question: 14 | What is the size of a Boolean type in Rust? 15 | 16 | Correct answer: 17 | 1 byte 18 | Incorrect answer: 19 | 8 bytes 20 | Incorrect answer: 21 | 4 bytes 22 | Incorrect answer: 23 | 0 bytes 24 | 25 | Question: 26 | If a value is of the type u32, what can we infer about it? 27 | 28 | Correct answer: 29 | The value is an unsigned integer that takes up 32 bits of space. 30 | Incorrect answer: 31 | The value is an unsigned integer that takes up 8 bits of space. 32 | Incorrect answer: 33 | The value is a signed integer that takes up 32 bits of space. 34 | Incorrect answer: 35 | The value is a signed integer that takes up 8 bits of space. 36 | 37 | Question: 38 | Is 1_000 the same value as 1000? 39 | 40 | Correct answer: 41 | Yes 42 | Incorrect answer: 43 | No 44 | 45 | Question: 46 | Which type represents a single value? 47 | 48 | Correct answer: 49 | Scalar 50 | Incorrect answer: 51 | Compound 52 | Incorrect answer: 53 | Tuple 54 | Incorrect answer: 55 | Array -------------------------------------------------------------------------------- /experiments/hand-scoring/006/questions/rust-book-data-types-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What type of data structure is a tuple? 2 | A. A linear data structure 3 | B. A nonlinear data structure 4 | C. A mutable data structure 5 | D. An immutable data structure 6 | 7 | Correct answer: B. A nonlinear data structure 8 | Incorrect answer: A. A linear data structure 9 | Incorrect answer: C. A mutable data structure 10 | Incorrect answer: D. An immutable data structure 11 | 12 | Question: How do you access individual values in a tuple? 13 | A. Use indexing 14 | B. Use pattern matching to destructure the tuple 15 | C. Use the . operator followed by the index of the value 16 | 17 | Correct answer: C. Use the . operator followed by the index of the value 18 | Incorrect answer: A. Use indexing 19 | Incorrect answer: B. Use pattern matching to destructure the tuple 20 | 21 | Question: What is the difference between an array and a vector? 22 | A. An array is more flexible than a vector 23 | B. An array is less flexible than a vector 24 | C. An array can grow or shrink in size 25 | D. An array's size is fixed 26 | 27 | Correct answer: D. An array's size is fixed 28 | Incorrect answer: A. An array is more flexible than a vector 29 | Incorrect answer: B. An array is less flexible than a vector 30 | Incorrect answer: C. An array can grow or shrink in size 31 | 32 | Question: What does the expression let a = [3; 5] do? 33 | A. It declares a variable named a that is set to the value 3 34 | B. It declares a variable named a that is set to an array of five elements, all with the value 3 35 | C. It declares a variable named a that is set to an array of five elements, all with the value 0 36 | 37 | Correct answer: B. It declares a variable named a that is set to an array of five elements, all with the value 3 38 | Incorrect answer: A. It declares a variable named a that is set to the value 3 39 | Incorrect answer: C. It declares a variable named a that is set to an array of five elements, all with the value 0 40 | 41 | Question: -------------------------------------------------------------------------------- /experiments/hand-scoring/006/questions/rust-book-lifetime-syntax-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is the main aim of lifetimes? 2 | Correct answer: To prevent dangling references 3 | Incorrect answer: To ensure references are valid as long as we need them to be 4 | Incorrect answer: To annotate relationships between lifetimes 5 | Incorrect answer: To compare scopes to determine whether borrows are valid 6 | 7 | Question: What does it mean when we say that "r has a lifetime of 'a but it refers to memory with a lifetime of 'b"? 8 | Correct answer: The subject of the reference doesn't live as long as the reference 9 | Incorrect answer: The reference in r will always be valid while x is valid 10 | Incorrect answer: R is referencing memory that was deallocated when x went out of scope 11 | Incorrect answer: Rust knows that the reference in r refers to x 12 | 13 | Question: How do lifetime annotations relate to each other? 14 | Correct answer: They describe the relationships of the lifetimes of multiple references to each other without affecting the lifetimes 15 | Incorrect answer: They are meant to tell Rust how generic lifetime parameters of multiple references relate to each other 16 | Incorrect answer: They don't have much meaning by themselves 17 | Incorrect answer: They are meant to tell Rust how long any of the references live 18 | 19 | Question: What is the difference between a reference and a String slice? 20 | Correct answer: A String slice is a reference 21 | Incorrect answer: A String slice is a type of generic 22 | Incorrect answer: A reference is a type of generic 23 | Incorrect answer: There is no difference 24 | 25 | Question: Why is it necessary to add generic lifetime parameters when implementing the longest function? 26 | Correct answer: So Rust can determine whether the reference being returned refers to x or y 27 | Incorrect answer: So the function can take ownership of its parameters 28 | Incorrect answer: So the borrow checker can perform its analysis 29 | Incorrect answer: So the function can take string slices as parameters -------------------------------------------------------------------------------- /experiments/hand-scoring/006/questions/rust-book-lifetime-syntax-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is the lifetime of the reference returned by the longest function if the lifetimes of the references passed in are different? 2 | A) The lifetime of the reference is the same as the lifetime of the first reference passed in 3 | B) The lifetime of the reference is the same as the lifetime of the second reference passed in 4 | C) The lifetime of the reference is the same as the smaller of the lifetimes of the references passed in 5 | D) The lifetime of the reference is the same as the larger of the lifetimes of the references passed in 6 | 7 | Question: What is the lifetime of the reference returned by the longest function if the lifetimes of the references passed in are the same? 8 | A) The lifetime of the reference is the same as the lifetime of the first reference passed in 9 | B) The lifetime of the reference is the same as the lifetime of the second reference passed in 10 | C) The lifetime of the reference is the same as the smaller of the lifetimes of the references passed in 11 | D) The lifetime of the reference is the same as the larger of the lifetimes of the references passed in 12 | 13 | Question: Why is it a problem if the lifetime of the reference returned by the longest function is not related to the lifetimes of the references passed in? 14 | A) Rust can't see that the reference is valid in this case 15 | B) The borrow checker disallows the code 16 | C) It would be a dangling reference because the value will go out of scope at the end of the function 17 | D) All of the above 18 | 19 | Question: What is the lifetime of the reference in the part field of the ImportantExcerpt struct? 20 | A) The lifetime of the reference is the same as the lifetime of the first reference passed in 21 | B) The lifetime of the reference is the same as the lifetime of the second reference passed in 22 | C) The lifetime of the reference is the same as the smaller of the lifetimes of the references passed in 23 | D) The lifetime of the reference is the same as the larger of the lifetimes of the references passed in 24 | 25 | Question: What is the lifetime of the reference in the part field of the ImportantExcerpt struct? 26 | A) The lifetime of -------------------------------------------------------------------------------- /experiments/hand-scoring/006/questions/rust-book-lifetime-syntax-text-with-quiz-template-2.txt: -------------------------------------------------------------------------------- 1 | What is the first rule of lifetime elision? 2 | Correct answer: The compiler assigns a lifetime parameter to each parameter that’s a reference. 3 | Incorrect answer: The compiler assigns a lifetime parameter to each parameter that’s a primitive type. 4 | Incorrect answer: The compiler assigns a lifetime parameter to each return value that’s a reference. 5 | Incorrect answer: The compiler assigns a lifetime parameter to each return value that’s a primitive type. 6 | 7 | Question: What is the second rule of lifetime elision? 8 | Correct answer: If there is exactly one input lifetime parameter, that lifetime is assigned to all output lifetime parameters. 9 | Incorrect answer: If there is more than one input lifetime parameter, that lifetime is assigned to all output lifetime parameters. 10 | Incorrect answer: If there is exactly one output lifetime parameter, that lifetime is assigned to all input lifetime parameters. 11 | Incorrect answer: If there is more than one output lifetime parameter, that lifetime is assigned to all input lifetime parameters. 12 | 13 | Question: What is the third rule of lifetime elision? 14 | Correct answer: If there are multiple input lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self is assigned to all output lifetime parameters. 15 | Incorrect answer: If there are multiple input lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self is assigned to all input lifetime parameters. 16 | Incorrect answer: If there are multiple output lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self is assigned to all input lifetime parameters. 17 | Incorrect answer: If there are multiple output lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self is assigned to all output lifetime parameters. 18 | 19 | Question: What does the lifetime elision rule mean for programmers? 20 | Correct answer: It’s a set of particular cases that the compiler will consider, and if your code fits these cases, you don’t need to write the lifetimes explicitly. 21 | Incorrect answer: It -------------------------------------------------------------------------------- /experiments/hand-scoring/006/questions/rust-book-method-syntax-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What does the 'impl' keyword do? 2 | A. Implementation blocks associated with a type 3 | B. Implements a trait for a type 4 | C. Implicitly returns the last expression 5 | D. Imports a module 6 | 7 | Correct answer: A. Implementation blocks associated with a type 8 | 9 | Incorrect answer: B. Implements a trait for a type 10 | Incorrect answer: C. Implicitly returns the last expression 11 | Incorrect answer: D. Imports a module 12 | 13 | Question: Which of the following is true about methods? 14 | A. Must have a parameter named self of type Self 15 | B. Their first parameter is always self 16 | C. Can only be defined within the context of a struct 17 | D. Parameter self represents the instance of the struct the method is being called on 18 | 19 | Correct answer: D. Parameter self represents the instance of the struct the method is being called on 20 | 21 | Incorrect answer: A. Must have a parameter named self of type Self 22 | Incorrect answer: B. Their first parameter is always self 23 | Incorrect answer: C. Can only be defined within the context of a struct 24 | 25 | Question: Which of the following is not a reason to use methods instead of functions? 26 | A. To provide method syntax 27 | B. To avoid repeating the type of self in every method’s signature 28 | C. For organization 29 | D. To take ownership of self 30 | 31 | Correct answer: D. To take ownership of self 32 | 33 | Incorrect answer: A. To provide method syntax 34 | Incorrect answer: B. To avoid repeating the type of self in every method’s signature 35 | Incorrect answer: C. For organization 36 | 37 | Question: Which of the following best describes an associated function? 38 | A. A function that is associated with an instance of a type 39 | B. A function that is associated with a type 40 | C. A function defined within an impl block 41 | D. A function that takes ownership of an instance of a type 42 | 43 | Correct answer: B. A function that is associated with a type 44 | 45 | Incorrect answer: A. A function that is associated with an instance of a type 46 | Incorrect answer -------------------------------------------------------------------------------- /experiments/hand-scoring/007/prompts/rust-book-method-syntax-text-only-1.txt: -------------------------------------------------------------------------------- 1 | Based on the text between the =====, generate 5 multiple-choice questions to test a reader's comprehension of the text's concepts 2 | 3 | ===== 4 | 5 | 6 | 7 | ===== 8 | 5 multiple-choice questions: -------------------------------------------------------------------------------- /experiments/hand-scoring/007/prompts/rust-book-method-syntax-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | Based on the text between the =====, generate 5 multiple-choice questions to test a reader's comprehension of the text's concepts 2 | 3 | ===== 4 | 5 | 6 | ===== 7 | 8 | Use the following format for each question: 9 | Question: 10 | Correct answer: 11 | Incorrect answer: 12 | Incorrect answer: 13 | Incorrect answer: 14 | 15 | 5 multiple-choice questions: 16 | 17 | Question: -------------------------------------------------------------------------------- /experiments/hand-scoring/007/questions/rust-book-data-types-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | 2 | What data type represents a single value in Rust? 3 | a. Scalar 4 | b. Compound 5 | c. Boolean 6 | Correct answer: Scalar 7 | Incorrect answer: Compound 8 | Incorrect answer: Boolean 9 | Incorrect answer: 10 | 11 | Question: 12 | Which type annotation below declares an unsigned integer that takes up 32 bits of space? 13 | a. f32 14 | b. i32 15 | c. u32 16 | Correct answer: u32 17 | Incorrect answer: f32 18 | Incorrect answer: i32 19 | Incorrect answer: 20 | 21 | Question: 22 | Which type of integer would you use when indexing some sort of collection? 23 | a. isize 24 | b. usize 25 | c. i32 26 | Correct answer: usize 27 | Incorrect answer: isize 28 | Incorrect answer: i32 29 | Incorrect answer: 30 | 31 | Question: 32 | In Rust, what does the 't' in 'let t = true;' stand for? 33 | a. true 34 | b. type 35 | c. False 36 | Correct answer: true 37 | Incorrect answer: type 38 | Incorrect answer: False 39 | Incorrect answer: 40 | 41 | Question: 42 | What is the size of a char type in Rust? 43 | a. 1 byte 44 | b. 2 bytes 45 | c. 4 bytes 46 | Correct answer: 4 bytes 47 | Incorrect answer: 1 byte 48 | Incorrect answer: 2 bytes -------------------------------------------------------------------------------- /experiments/hand-scoring/007/questions/rust-book-data-types-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is the type of the variable 'five_hundred'? 2 | Correct answer: i32 3 | Incorrect answer: f64 4 | Incorrect answer: u8 5 | Incorrect answer: tuple 6 | 7 | Question: What is the value of the variable 'six_point_four'? 8 | Correct answer: 6.4 9 | Incorrect answer: 500 10 | Incorrect answer: 1 11 | Incorrect answer: tuple 12 | 13 | Question: What is the first index of a tuple? 14 | Correct answer: 0 15 | Incorrect answer: 1 16 | Incorrect answer: 2 17 | Incorrect answer: 3 18 | 19 | Question: What is the type of variable 'a'? 20 | Correct answer: [i32; 5] 21 | Incorrect answer: [f64; 3] 22 | Incorrect answer: i32 23 | Incorrect answer: tuple 24 | 25 | Question: What will happen if you try to access an element of an array that is past the end of the array? 26 | Correct answer: Rust will check that the index you've specified is less than the array length. 27 | Incorrect answer: The program will result in a runtime error. 28 | Incorrect answer: The program will exit with an error message. 29 | Incorrect answer: The program will print out the corresponding value at that index in the array. -------------------------------------------------------------------------------- /experiments/hand-scoring/007/questions/rust-book-lifetime-syntax-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | Which of the following is not a reason to use generic lifetime parameters? 2 | Correct answer: So references are valid as long as we need them to be 3 | Incorrect answer: To prevent dangling references 4 | Incorrect answer: To express the relationship between the lifetimes of the parameters and the return value 5 | Incorrect answer: To ensure that a type has the behavior we want 6 | 7 | Question: Which of the following will not compile? 8 | Correct answer: fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { 9 | Incorrect answer: fn longest(x: &str, y: &str) -> &str { 10 | Incorrect answer: fn longest<'a>(x: &'a str, y: &str) -> &str 11 | Incorrect answer: fn longest<'a>(x: &str, y: &'a str) -> &'a str 12 | 13 | Question: What is the main aim of lifetimes? 14 | Correct answer: To prevent dangling references 15 | Incorrect answer: To ensure that a type has the behavior we want 16 | Incorrect answer: To express the relationship between the lifetimes of the parameters and the return value 17 | Incorrect answer: So references are valid as long as we need them to be 18 | 19 | Question: In Listing 10-18, why is x valid for the outer scope? 20 | Correct answer: Because its scope is larger 21 | Incorrect answer: Because its lifetime is longer 22 | Incorrect answer: Because it is a reference 23 | Incorrect answer: Because we annotated it with a generic lifetime parameter 24 | 25 | Question: What does Rust use to compare scopes to determine whether all borrows are valid? 26 | Correct answer: The Rust compiler has a borrow checker 27 | Incorrect answer: We annotate the relationships using generic lifetime parameters 28 | Incorrect answer: Lifetime annotations 29 | Incorrect answer: Most of the time, lifetimes are implicit and inferred -------------------------------------------------------------------------------- /experiments/hand-scoring/007/questions/rust-book-lifetime-syntax-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | Is it necessary to annotate every reference in a struct's definition with a lifetime annotation? 2 | A) No, only references that will be used after the struct goes out of scope need to be annotated 3 | B) Yes, all references in a struct's definition need to be annotated 4 | C) No, only references that are borrowed from another reference need to be annotated 5 | D) Yes, all references in a struct's definition need to be annotated with the same lifetime parameter 6 | 7 | Correct answer: B 8 | Incorrect answer: A 9 | Incorrect answer: C 10 | Incorrect answer: D 11 | 12 | Question: Where do lifetime annotations go for a function? 13 | A) In the function body 14 | B) In the function signature 15 | C) In the function parameters 16 | D) In the return type 17 | 18 | Correct answer: B 19 | Incorrect answer: A 20 | Incorrect answer: C 21 | Incorrect answer: D 22 | 23 | Question: What is the difference between a lifetime parameter and a concrete lifetime? 24 | A) A lifetime parameter is a generic lifetime that can be substituted for any other lifetime, while a concrete lifetime is a specific lifetime 25 | B) A lifetime parameter is a specific lifetime that cannot be substituted for any other lifetime, while a concrete lifetime is a generic lifetime that can be substituted for any other lifetime 26 | C) A lifetime parameter is a generic lifetime that can be substituted for any other lifetime, while a concrete lifetime is a generic lifetime that can only be substituted for other generic lifetimes 27 | D) A lifetime parameter is a specific lifetime that cannot be substituted for any other lifetime, while a concrete lifetime is a specific lifetime that can only be substituted for other specific lifetimes 28 | 29 | Correct answer: A 30 | Incorrect answer: B 31 | Incorrect answer: C 32 | Incorrect answer: D 33 | 34 | Question: Which of the following will cause a compilation error? 35 | A) Declaring a struct with a reference field that is not annotated with a lifetime parameter 36 | B) Declaring a struct with a reference field that is annotated with a lifetime parameter 37 | C) Calling a function with references that have different concrete lifetimes 38 | D) Returning a reference from a function with a lifetime parameter that does not match the lifetime -------------------------------------------------------------------------------- /experiments/hand-scoring/007/questions/rust-book-lifetime-syntax-text-with-quiz-template-2.txt: -------------------------------------------------------------------------------- 1 | What does the first rule of lifetime elision state? 2 | A) Each parameter gets its own lifetime. 3 | B) The lifetime of the one input parameter gets assigned to the output lifetime. 4 | C) The lifetime of self is assigned to all output lifetime parameters. 5 | D) If the compiler gets to the end of the three rules and there are still references for which it can't figure out lifetimes, the compiler will stop with an error. 6 | 7 | Correct answer: Each parameter gets its own lifetime. 8 | 9 | Incorrect answer: The lifetime of the one input parameter gets assigned to the output lifetime. 10 | Incorrect answer: The lifetime of self is assigned to all output lifetime parameters. 11 | Incorrect answer: If the compiler gets to the end of the three rules and there are still references for which it can't figure out lifetimes, the compiler will stop with an error. 12 | 13 | Question: What is the lifetime of a string literal? 14 | A) 'a 15 | B) 'static 16 | C) The lifetime of the one input parameter 17 | D) The lifetime of self 18 | 19 | Correct answer: 'static 20 | 21 | Incorrect answer: 'a 22 | Incorrect answer: The lifetime of the one input parameter 23 | Incorrect answer: The lifetime of self 24 | 25 | Question: Which of the following is true about the lifetime of a reference? 26 | A) It must live for the entire duration of the program 27 | B) It must live for at least as long as the thing it references 28 | C) It must live for at least as long as the function it's in 29 | D) It must live for at least as long as the function it's called in 30 | 31 | Correct answer: It must live for at least as long as the thing it references 32 | 33 | Incorrect answer: It must live for the entire duration of the program 34 | Incorrect answer: It must live for at least as long as the function it's in 35 | Incorrect answer: It must live for at least as long as the function it's called in 36 | 37 | Question: What is the purpose of the third rule of lifetime elision? 38 | A) To specify that the lifetime of self is assigned to all output lifetime parameters 39 | B) Togt her use of -------------------------------------------------------------------------------- /experiments/hand-scoring/007/questions/rust-book-method-syntax-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is the first parameter in a method signature always called? 2 | Correct answer: self 3 | Incorrect answer: method 4 | Incorrect answer: type 5 | Incorrect answer: struct 6 | 7 | Question: Which keyword is used to create a method? 8 | Correct answer: fn 9 | Incorrect answer: struct 10 | Incorrect answer: method 11 | Incorrect answer: trait 12 | 13 | Question: What does the & in &self represent? 14 | Correct answer: Borrows the Self instance 15 | Incorrect answer: Takes ownership of the Self instance 16 | Incorrect answer: Mutably borrows the Self instance 17 | Incorrect answer: Read-only borrows the Self instance 18 | 19 | Question: When is it useful to create an associated function? 20 | Correct answer: When you want to create a new instance of the struct 21 | Incorrect answer: When you want to reference a field in the struct 22 | Incorrect answer: When you want to call a method on the struct 23 | Incorrect answer: When you want to borrow the struct 24 | 25 | Question: How many impl blocks can a struct have? 26 | Correct answer: Multiple 27 | Incorrect answer: One 28 | Incorrect answer: Three 29 | Incorrect answer: None -------------------------------------------------------------------------------- /experiments/hand-scoring/008/questions/rust-book-data-types-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What does the keyword "let" do in Rust? 2 | A. It denotes a variable binding 3 | B. It compiles the program 4 | C. It runs the program 5 | Correct answer: A. It denotes a variable binding 6 | Incorrect answer: B. It compiles the program 7 | Incorrect answer: C. It runs the program 8 | 9 | Question: What is the result of two divided by three in Rust? 10 | A. 1 11 | B. 0 12 | C. 3 13 | Correct answer: B. 0 14 | Incorrect answer: A. 1 15 | Incorrect answer: C. 3 16 | 17 | Question: Which of the following is not a scalar type? 18 | A. Boolean 19 | B. Character 20 | C. Array 21 | Correct answer: C. Array 22 | Incorrect answer: A. Boolean 23 | Incorrect answer: B. Character 24 | 25 | Question: What is the size of a char in Rust? 26 | A. 1 byte 27 | B. 2 bytes 28 | C. 4 bytes 29 | Correct answer: C. 4 bytes 30 | Incorrect answer: A. 1 byte 31 | Incorrect answer: B. 2 bytes 32 | 33 | Question: What does Rust's char type represent? 34 | A. A Unicode Scalar Value 35 | B. An ASCII character 36 | C. A number 37 | Correct answer: A. A Unicode Scalar Value 38 | Incorrect answer: B. An ASCII character 39 | Incorrect answer: C. A number -------------------------------------------------------------------------------- /experiments/hand-scoring/008/questions/rust-book-data-types-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is the data type of the value 6.4 in the following tuple? 2 | A) i32 3 | B) f64 4 | C) u8 5 | Correct answer: B 6 | Incorrect answer: A 7 | Incorrect answer: C 8 | 9 | Question: What is the output of the following code? 10 | let a = [1, 2, 3, 4, 5]; 11 | let first = a[0]; 12 | let second = a[1]; 13 | 14 | A) 1 2 15 | B) 2 3 16 | C) 1 3 17 | Correct answer: A 18 | Incorrect answer: B 19 | Incorrect answer: C 20 | 21 | Question: What is the value of the element at index 10 in the following array? 22 | let a = [1, 2, 3, 4, 5]; 23 | A) 6 24 | B) 10 25 | C) Panics 26 | Correct answer: C 27 | Incorrect answer: A 28 | Incorrect answer: B 29 | 30 | Question: What is the output of the following code? 31 | println!("Please enter an array index."); 32 | 33 | let mut index = String::new(); 34 | 35 | io::stdin() 36 | .read_line(&mut index) 37 | .expect("Failed to read line"); 38 | 39 | let index: usize = index 40 | .trim() 41 | .parse() 42 | .expect("Index entered was not a number"); 43 | 44 | let element = a[index]; 45 | 46 | println!("The value of the element at index {index} is: {element}"); 47 | A) the element at the specified index 48 | B) the index 49 | C) the value of the element 50 | Correct answer: A 51 | Incorrect answer: B 52 | Incorrect answer: C 53 | 54 | Question: Which of the following data types can be elements of an array? 55 | A) i32 56 | B) f64 57 | C) u8 58 | D) All of the above 59 | Correct answer: D 60 | Incorrect answer: A 61 | Incorrect answer: B 62 | Incorrect answer: C -------------------------------------------------------------------------------- /experiments/hand-scoring/008/questions/rust-book-lifetime-syntax-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What does the longest function signature telling Rust? 2 | A. That for some lifetime 'a, the function takes in two parameters, both of which are string slices that live at long as lifetime 'a 3 | B. That the string slice returned from the function will live at least as long as lifetime 'a 4 | C. That the lifetime of the reference returned by the longest function is the same as the smaller of the lifetimes of the values referred to by the function arguments 5 | D. That the generic lifetime 'a will get the concrete lifetime that is equal to the smaller of the lifetimes of x and y 6 | 7 | Correct answer: C. That the lifetime of the reference returned by the longest function is the same as the smaller of the lifetimes of the values referred to by the function arguments 8 | 9 | Incorrect answer: A. That for some lifetime 'a, the function takes in two parameters, both of which are string slices that live at long as lifetime 'a 10 | Incorrect answer: B. That the string slice returned from the function will live at least as long as lifetime 'a 11 | Incorrect answer: D. That the generic lifetime 'a will get the concrete lifetime that is equal to the smaller of the lifetimes of x and y 12 | 13 | Question: What is the main reason for having function signatures contain the lifetime contract? 14 | A. So the analysis the Rust compiler does can be simpler 15 | B. So that the compiler can point to the part of our code and the constraints more precisely 16 | C. So that the compiler can only point to a use of our code many steps away from the cause of the problem 17 | D. So that the lifetime of the reference returned by the longest function is the same as the smaller of the lifetimes of the values referred to by the function arguments 18 | 19 | Correct answer: A. So the analysis the Rust compiler does can be simpler 20 | 21 | Incorrect answer: B. So that the compiler can point to the part of our code and the constraints more precisely 22 | Incorrect answer: C. So that the compiler can only point to a use of our code many steps away from the cause of the problem 23 | Incorrect answer: D. So that the lifetime of the reference returned by the -------------------------------------------------------------------------------- /experiments/hand-scoring/008/questions/rust-book-lifetime-syntax-text-with-quiz-template-2.txt: -------------------------------------------------------------------------------- 1 | With respect to the elision rules, if the Rust compiler gets to the end of the three rules and there are still references for which it can't figure out lifetimes, what will the compiler do? 2 | 3 | Correct answer: The compiler will stop with an error. 4 | Incorrect answer: The compiler will assign a lifetime of 'static to all remaining references. 5 | Incorrect answer: The compiler will make an educated guess as to what the lifetime of the remaining references should be. 6 | Incorrect answer: The compiler will print a warning message but continue compiling the code. 7 | 8 | Question: Which of the following best describes the lifetime elision rules? 9 | 10 | Correct answer: The lifetime elision rules are particular cases that the compiler will consider when inferring lifetimes, and if the code fits these cases, the programmer doesn't need to write the lifetimes explicitly. 11 | Incorrect answer: The lifetime elision rules are particular cases that the programmer needs to follow when writing code with references. 12 | Incorrect answer: The lifetime elision rules are guidelines for the programmer to follow when writing code with references. 13 | Incorrect answer: The lifetime elision rules are suggestions for the programmer to follow when writing code with references. 14 | 15 | Question: With respect to the lifetime elision rules, what is true about the third rule? 16 | 17 | Correct answer: The third rule is that, if there are multiple input lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self is assigned to all output lifetime parameters. 18 | Incorrect answer: The third rule is that, if there are multiple input lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self MUST be assigned to all output lifetime parameters. 19 | Incorrect answer: The third rule is that, if there are multiple input lifetime parameters, but one of them is &self or &mut self because this is a method, the lifetime of self MAY be assigned to all output lifetime parameters. 20 | Incorrect answer: There is no third rule. 21 | 22 | Question: Which of the following is NOT a rule for lifetime elision? 23 | 24 | Correct answer: If there are multiple -------------------------------------------------------------------------------- /experiments/hand-scoring/008/questions/rust-book-method-syntax-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is the first parameter in the signature of a method always called? 2 | A. self 3 | B. first 4 | C. the instance of the struct 5 | D. the type of the struct 6 | 7 | Correct answer: A. self 8 | Incorrect answer: B. first 9 | Incorrect answer: C. the instance of the struct 10 | Incorrect answer: D. the type of the struct 11 | 12 | Question: Where are methods defined? 13 | A. within the context of a struct 14 | B. within an impl block 15 | C. within the context of an enum 16 | D. within the context of a trait object 17 | 18 | Correct answer: B. within an impl block 19 | Incorrect answer: A. within the context of a struct 20 | Incorrect answer: C. within the context of an enum 21 | Incorrect answer: D. within the context of a trait object 22 | 23 | Question: What does the & in &self represent? 24 | A. that the method borrows the Self instance 25 | B. that the method takes ownership of the Self instance 26 | C. that the method borrows the self instance immutably 27 | D. that the method borrows the self instance mutably 28 | 29 | Correct answer: C. that the method borrows the self instance immutably 30 | Incorrect answer: A. that the method borrows the Self instance 31 | Incorrect answer: B. that the method takes ownership of the Self instance 32 | Incorrect answer: D. that the method borrows the self instance mutably 33 | 34 | Question: What is the type of the parameter in an associated function? 35 | A. the type of the struct 36 | B. the instance of the struct 37 | C. the type of the Self 38 | D. the instance of the Self 39 | 40 | Correct answer: A. the type of the struct 41 | Incorrect answer: B. the instance of the struct 42 | Incorrect answer: C. the type of the Self 43 | Incorrect answer: D. the instance of the Self 44 | 45 | Question: What is the main reason for using methods instead of functions? 46 | A. to provide method syntax 47 | B. to not have to repeat the type of self in every method's signature 48 | C. to keep all the things that can be done -------------------------------------------------------------------------------- /experiments/hand-scoring/009/questions/mdn-functions-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is the output of the following code? 2 | 3 | const myText = 'I am a string'; 4 | const newString = myText.replace('string', 'sausage'); 5 | console.log(newString); 6 | 7 | A) "I am a sausage" 8 | B) "I am a string" 9 | C) "I sausage a string" 10 | D) SyntaxError 11 | 12 | Correct answer: A) "I am a sausage" 13 | 14 | Incorrect answer: B) "I am a string" 15 | Incorrect answer: C) "I sausage a string" 16 | Incorrect answer: D) SyntaxError 17 | 18 | Question: What is the output of the following code? 19 | 20 | const myArray = ['I', 'love', 'chocolate', 'frogs']; 21 | const madeAString = myArray.join(' '); 22 | console.log(madeAString); 23 | 24 | A) "love chocolate frogs" 25 | B) "I love chocolate frogs" 26 | C) "I,love,chocolate,frogs" 27 | D) SyntaxError 28 | 29 | Correct answer: B) "I love chocolate frogs" 30 | 31 | Incorrect answer: A) "love chocolate frogs" 32 | Incorrect answer: C) "I,love,chocolate,frogs" 33 | Incorrect answer: D) SyntaxError 34 | 35 | Question: What is the output of the following code? 36 | 37 | const myNumber = Math.random(); 38 | 39 | A) A random decimal number between 0 and 1 40 | B) A random whole number between 0 and 10 41 | C) A random whole number between 0 and 1 42 | D) SyntaxError 43 | 44 | Correct answer: A) A random decimal number between 0 and 1 45 | 46 | Incorrect answer: B) A random whole number between 0 and 10 47 | Incorrect answer: C) A random whole number between 0 and 1 48 | Incorrect answer: D) SyntaxError 49 | 50 | Question: What is the output of the following code? 51 | 52 | textBox.addEventListener('keydown', logKey); 53 | 54 | A) When the user presses a key, the browser will call the logKey() function 55 | B -------------------------------------------------------------------------------- /experiments/hand-scoring/009/questions/mdn-functions-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is the name of the top level outside all your functions? 2 | Correct answer: The global scope. 3 | Incorrect answer: The function scope. 4 | Incorrect answer: The local scope. 5 | Incorrect answer: The arrow function. 6 | 7 | Question: What is the purpose of function scope? 8 | Correct answer: To avoid problems with external scripts calling in and using the same variable names. 9 | Incorrect answer: To allow functions to access variables defined in other functions. 10 | Incorrect answer: To keep variables and other things defined inside the function locked away. 11 | Incorrect answer: To provide a better organization for your code. 12 | 13 | Question: What does the map() method do? 14 | Correct answer: Takes each item in the array in turn, passing it into the given function, and then takes the value returned by that function and adds it to a new array. 15 | Incorrect answer: Takes the value returned by a given function and adds it to a new array. 16 | Incorrect answer: Takes each item in the array in turn and passes it into a given function. 17 | Incorrect answer: Takes the value returned by a given function and adds it to the original array. 18 | 19 | Question: Which of the following is NOT true about arrow functions? 20 | Correct answer: They can only be used when the function only has one line in the curly brackets. 21 | Incorrect answer: They can make your code shorter and more readable. 22 | Incorrect answer: If the function only takes one parameter, you can omit the brackets around the parameter. 23 | Incorrect answer: If your function needs to return a value, and contains only one line, you can omit the return statement. 24 | 25 | Question: What is the difference between the following two code snippets? 26 | Const name = 'Chris'; 27 | function greeting() { 28 | alert(`Hello ${name}: welcome to our company.`); 29 | } 30 | 31 | and 32 | 33 | Const name = 'Zaptec'; 34 | function greeting() { 35 | alert(`Our company is called ${name}.`); 36 | } 37 | 38 | Correct answer: The first code snippet will print "Hello Chris: welcome to our company." while the second code snippet will print "Our company is called -------------------------------------------------------------------------------- /experiments/hand-scoring/009/questions/mdn-objects-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is an object in JavaScript? 2 | A: A collection of related data and/or functionality 3 | B: A JavaScript feature 4 | C: A HTML element 5 | D: A CSS property 6 | 7 | Correct answer: A: A collection of related data and/or functionality 8 | Incorrect answer: B: A JavaScript feature 9 | Incorrect answer: C: A HTML element 10 | Incorrect answer: D: A CSS property 11 | 12 | Question: How do you create an object in JavaScript? 13 | A: By writing out the object contents as you've come to create it 14 | B: By using a constructor 15 | C: By initializing a variable 16 | D: By calling a function 17 | 18 | Correct answer: C: By initializing a variable 19 | Incorrect answer: A: By writing out the object contents as you've come to create it 20 | Incorrect answer: B: By using a constructor 21 | Incorrect answer: D: By calling a function 22 | 23 | Question: What is dot notation? 24 | A: A way to access object properties 25 | B: A way to set object properties 26 | C: A way to create object methods 27 | D: A way to create an object constructor 28 | 29 | Correct answer: A: A way to access object properties 30 | Incorrect answer: B: A way to set object properties 31 | Incorrect answer: C: A way to create object methods 32 | Incorrect answer: D: A way to create an object constructor 33 | 34 | Question: What is a constructor? 35 | A: A function called using the new keyword 36 | B: A function that creates a new object 37 | C: A function that initializes an object 38 | D: A function that binds an object to this 39 | 40 | Correct answer: A: A function called using the new keyword 41 | Incorrect answer: B: A function that creates a new object 42 | Incorrect answer: C: A function that initializes an object 43 | Incorrect answer: D: A function that binds an object to this 44 | 45 | Question: What is this? 46 | A: The current object the code is being written inside 47 | B: The name of the object 48 | C: A property of the object 49 | D: The value of the object 50 | 51 | Correct answer: A: The current object the code -------------------------------------------------------------------------------- /experiments/hand-scoring/009/questions/mdn-promises-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is the difference between a promise and a callback? 2 | Correct answer: A promise is an object returned by an asynchronous function, which represents the current state of the operation. A callback is a function that is passed into an asynchronous function. 3 | Incorrect answer: Callbacks are the foundation of asynchronous programming in modern JavaScript. 4 | Incorrect answer: Promises are used to handle the eventual success or failure of the operation. 5 | Incorrect answer: A promise is returned by a synchronous function. -------------------------------------------------------------------------------- /experiments/hand-scoring/009/questions/mdn-promises-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is the correct output of the following code? 2 | const fetchPromise1 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json'); 3 | const fetchPromise2 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found'); 4 | const fetchPromise3 = fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json'); 5 | 6 | Promise.all([fetchPromise1, fetchPromise2, fetchPromise3]) 7 | .then((responses) => { 8 | for (const response of responses) { 9 | console.log(`${response.url}: ${response.status}`); 10 | } 11 | }) 12 | .catch((error) => { 13 | console.error(`Failed to fetch: ${error}`) 14 | }); 15 | 16 | Correct answer: https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json: 200 17 | https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found: 404 18 | https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json: 200 19 | Incorrect answer: https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json: 404 20 | https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found: 200 21 | https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json: 404 22 | Incorrect answer: https://mdn.github.io/learning-area/javascript/apis/fetching -------------------------------------------------------------------------------- /experiments/hand-scoring/010/questions/mdn-functions-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is a function? 2 | A: A chunk of code that performs a specific task 3 | B: A programming structure that allows you to repeatedly execute a block of code 4 | C: A built-in code that is part of the JavaScript language 5 | D: A custom code that is written by the programmer 6 | 7 | Correct answer: A: A chunk of code that performs a specific task 8 | 9 | Incorrect answer: B: A programming structure that allows you to repeatedly execute a block of code 10 | Incorrect answer: C: A built-in code that is part of the JavaScript language 11 | Incorrect answer: D: A custom code that is written by the programmer 12 | 13 | Question: What is the purpose of a function? 14 | A: To allow you to store a piece of code that does a single task inside a defined block 15 | B: To generate a random number 16 | C: To Call another function 17 | D: To join all the items in an array together into a single string 18 | 19 | Correct answer: A: To allow you to store a piece of code that does a single task inside a defined block 20 | 21 | Incorrect answer: B: To generate a random number 22 | Incorrect answer: C: To Call another function 23 | Incorrect answer: D: To join all the items in an array together into a single string 24 | 25 | Question: How do you invoke a function? 26 | A: By including the name of the function in the code somewhere, followed by parentheses 27 | B: By writing the function's name followed by its parameters 28 | C: By writing the function's name 29 | D: By adding an event listener 30 | 31 | Correct answer: A: By including the name of the function in the code somewhere, followed by parentheses 32 | 33 | Incorrect answer: B: By writing the function's name followed by its parameters 34 | Incorrect answer: C: By writing the function's name 35 | Incorrect answer: D: By adding an event listener 36 | 37 | Question: What is a method? 38 | A: A function that is part of an object 39 | B: A function that is written in JavaScript 40 | C: A function that is built into the browser 41 | D: A function that is invoked by an event 42 | 43 | Correct answer: A: A function -------------------------------------------------------------------------------- /experiments/hand-scoring/010/questions/mdn-functions-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is the default value of a function parameter in JavaScript? 2 | Correct answer: undefined 3 | Incorrect answer: null 4 | Incorrect answer: 0 5 | Incorrect answer: false 6 | 7 | Question: What is the preferred way to create a function in JavaScript? 8 | Correct answer: function declaration 9 | Incorrect answer: function expression 10 | Incorrect answer: arrow function 11 | Incorrect answer: IIFE 12 | 13 | Question: How do you create an IIFE in JavaScript? 14 | Correct answer: (function(){ /* code */ })(); 15 | Incorrect answer: function(){ /* code */ }; 16 | Incorrect answer: function()(); 17 | Incorrect answer: function /* code */ ; 18 | 19 | Question: How do you call a function in JavaScript? 20 | Correct answer: functionName(); 21 | Incorrect answer: FunctionName(); 22 | Incorrect answer: function_name(); 23 | Incorrect answer: Function.prototype(); 24 | 25 | Question: What does "use strict" do in JavaScript? 26 | Correct answer: Enforces strict mode 27 | Incorrect answer: Makes variables global 28 | Incorrect answer: Nothing 29 | Incorrect answer: Duplicates code -------------------------------------------------------------------------------- /experiments/hand-scoring/010/questions/mdn-objects-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is an object in JavaScript? 2 | Correct answer: A collection of related data and/or functionality 3 | Incorrect answer: A programming language 4 | Incorrect answer: A software structure 5 | Incorrect answer: A file type 6 | 7 | Question: What is the this keyword? 8 | Correct answer: Refers to the current object the code is being written inside 9 | Incorrect answer: Refers to the global object 10 | Incorrect answer: Refers to the previous object 11 | Incorrect answer: Refers to the next object 12 | 13 | Question: What is a constructor? 14 | Correct answer: A function called using the new keyword 15 | Incorrect answer: A function that creates a new object 16 | Incorrect answer: A function that creates a new array 17 | Incorrect answer: A function that creates a new string 18 | 19 | Question: Why is dot notation generally preferred over bracket notation? 20 | Correct answer: It is more succinct and easier to read 21 | Incorrect answer: It is less common 22 | Incorrect answer: It is more common 23 | Incorrect answer: It is faster 24 | 25 | Question: What is the purpose of an object prototype? 26 | Correct answer: Inherit properties from other objects 27 | Incorrect answer: Initialize objects 28 | Incorrect answer: Define the set of methods and properties an object can have 29 | Incorrect answer: Create as many objects as needed from a single object definition -------------------------------------------------------------------------------- /experiments/hand-scoring/010/questions/mdn-promises-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is the foundation of asynchronous programming in modern JavaScript? 2 | Correct answer: Promises 3 | Incorrect answer: XMLHttpRequest 4 | Incorrect answer: Event handlers 5 | Incorrect answer: setTimeout() 6 | 7 | Question: What does the fetch() API return? 8 | Correct answer: A Promise object 9 | Incorrect answer: A Response object 10 | Incorrect answer: The JSON data 11 | Incorrect answer: undefined 12 | 13 | Question: When is the handler passed into the then() method of a promise executed? 14 | Correct answer: When the asynchronous operation has succeeded 15 | Incorrect answer: When the promise is returned 16 | Incorrect answer: When the asynchronous operation has failed 17 | Incorrect answer: Immediately 18 | 19 | Question: How do you get the data contained in a Response object? 20 | Correct answer: By calling the json() method 21 | Incorrect answer: By calling the fetch() method 22 | Incorrect answer: By calling the then() method 23 | Incorrect answer: It is undefined 24 | 25 | Question: What is the catch() method used for? 26 | Correct answer: It is used for error handling 27 | Incorrect answer: It is used for request handling 28 | Incorrect answer: It is used for promise chaining 29 | Incorrect answer: It is used for logging -------------------------------------------------------------------------------- /experiments/hand-scoring/010/questions/mdn-promises-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is the output of the following code? 2 | const fetchPromise1 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json'); 3 | const fetchPromise2 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found'); 4 | const fetchPromise3 = fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json'); 5 | 6 | Promise.all([fetchPromise1, fetchPromise2, fetchPromise3]) 7 | .then((responses) => { 8 | for (const response of responses) { 9 | console.log(`${response.url}: ${response.status}`); 10 | } 11 | }) 12 | .catch((error) => { 13 | console.error(`Failed to fetch: ${error}`) 14 | }); 15 | 16 | Correct answer: https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json: 200 17 | https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found: 404 18 | https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json: 200 19 | Incorrect answer: https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json: 404 20 | https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found: 200 21 | https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json: 404 22 | Incorrect answer: https://mdn.github.io/learning-area/javascript/apis/fetching- -------------------------------------------------------------------------------- /experiments/hand-scoring/011/questions/mdn-functions-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is the result of the following code? 2 | const myText = 'I am a string'; 3 | const newString = myText.replace('string', 'sausage'); 4 | 5 | A) "I am a sausage" 6 | B) "I am a string" 7 | C) "I sausage a string" 8 | D) Syntax error 9 | 10 | Correct answer: A) "I am a sausage" 11 | 12 | Incorrect answer: B) "I am a string" 13 | Incorrect answer: C) "I sausage a string" 14 | Incorrect answer: D) Syntax error 15 | 16 | Question: What is the result of the following code? 17 | const myArray = ['I', 'love', 'chocolate', 'frogs']; 18 | const madeAString = myArray.join(' '); 19 | 20 | A) "I,love,chocolate,frogs" 21 | B) "I love chocolate frogs" 22 | C) "I+love+chocolate+frogs" 23 | D) Syntax error 24 | 25 | Correct answer: B) "I love chocolate frogs" 26 | 27 | Incorrect answer: A) "I,love,chocolate,frogs" 28 | Incorrect answer: C) "I+love+chocolate+frogs" 29 | Incorrect answer: D) Syntax error 30 | 31 | Question: What is the result of the following code? 32 | const myNumber = Math.random(); 33 | 34 | A) A random number between 0 and 1 35 | B) A random number between 0 and 100 36 | C) A random number between 1 and 100 37 | D) Syntax error 38 | 39 | Correct answer: A) A random number between 0 and 1 40 | 41 | Incorrect answer: B) A random number between 0 and 100 42 | Incorrect answer: C) A random number between 1 and 100 43 | Incorrect answer: D) Syntax error 44 | 45 | Question: What is the result of the following code? 46 | function logKey(event) { 47 | console.log(`You pressed "${event.key}".`); 48 | } 49 | 50 | textBox.addEventListener('keydown', logKey); 51 | 52 | A) You pressed the key that was pressed -------------------------------------------------------------------------------- /experiments/hand-scoring/011/questions/mdn-functions-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is the value of the x variable when output(x) is called from inside function a? 2 | Correct answer: 2 3 | Incorrect answer: 3 4 | Incorrect answer: 1 5 | Incorrect answer: 0 6 | 7 | Question: What is the value of the y variable when output(y) is called from inside function b? 8 | Correct answer: 3 9 | Incorrect answer: 2 10 | Incorrect answer: 1 11 | Incorrect answer: 0 12 | 13 | Question: What is the value of the z variable when output(z) is called from inside function a? 14 | Correct answer: undefined 15 | Incorrect answer: 3 16 | Incorrect answer: 2 17 | Incorrect answer: 1 18 | 19 | Question: What happens when you try to call output(y) from inside function a? 20 | Correct answer: ReferenceError: y is not defined 21 | Incorrect answer: 3 22 | Incorrect answer: 2 23 | Incorrect answer: 1 24 | 25 | Question: What is the value of the x variable when output(x) is called from inside function b? 26 | Correct answer: 1 27 | Incorrect answer: 3 28 | Incorrect answer: 2 29 | Incorrect answer: 0 -------------------------------------------------------------------------------- /experiments/hand-scoring/011/questions/mdn-objects-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is the this keyword in JavaScript? 2 | A) A keyword that refers to the current object the code is being written inside 3 | B) A keyword that refers to the current array the code is being written inside 4 | C) A keyword that refers to the current function the code is being written inside 5 | D) A keyword that refers to the global window object 6 | 7 | Correct answer: A) A keyword that refers to the current object the code is being written inside 8 | Incorrect answer: B) A keyword that refers to the current array the code is being written inside 9 | Incorrect answer: C) A keyword that refers to the current function the code is being written inside 10 | Incorrect answer: D) A keyword that refers to the global window object 11 | 12 | Question: Which of the following is NOT a value that can be stored in an object? 13 | A) A number 14 | B) A function 15 | C) An array 16 | D) A string 17 | 18 | Correct answer: D) A string 19 | Incorrect answer: A) A number 20 | Incorrect answer: B) A function 21 | Incorrect answer: C) An array 22 | 23 | Question: What is the difference between a method and a property in an object? 24 | 25 | A) A property is a value that can be stored in an object, while a method is a function that can be performed on an object 26 | B) A property is a function that can be performed on an object, while a method is a value that can be stored in an object 27 | C) There is no difference between a method and a property in an object 28 | D) A method is a value that can be stored in an object, while a property is a function that can be performed on an 29 | 30 | Correct answer: A) A property is a value that can be stored in an object, while a method is a function that can be performed on an object 31 | Incorrect answer: B) A property is a function that can be performed on an object, while a method is a value that can be stored in an object 32 | Incorrect -------------------------------------------------------------------------------- /experiments/hand-scoring/011/questions/mdn-promises-text-with-quiz-template-0.txt: -------------------------------------------------------------------------------- 1 | What is the value of fetchPromise when the fetch() operation is still going on? 2 | Correct answer: Promise { : "pending" } 3 | Incorrect answer: Promise { : "fulfilled" } 4 | Incorrect answer: Promise { : "rejected" } 5 | Incorrect answer: Promise { : "resolved" } 6 | 7 | Question: What is the value of fetchPromise when the fetch() operation finished successfully? 8 | Answer: Promise { : "fulfilled" } 9 | Incorrect answer: Promise { : "pending" } 10 | Incorrect answer: Promise { : "rejected" } 11 | Incorrect answer: Promise { : "resolved" } 12 | 13 | Question: What is the value of fetchPromise when the fetch() operation failed? 14 | Answer: Promise { : "rejected" } 15 | Incorrect answer: Promise { : "pending" } 16 | Incorrect answer: Promise { : "fulfilled" } 17 | Incorrect answer: Promise { : "resolved" } 18 | 19 | Question: What is the value of fetchPromise when the fetch() operation is successful and the promise is "locked in" to follow the state of another promise? 20 | Answer: Promise { : "resolved" } 21 | Incorrect answer: Promise { : "pending" } 22 | Incorrect answer: Promise { : "fulfilled" } 23 | Incorrect answer: Promise { : "rejected" } 24 | 25 | Question: Which of the following is not a possible state for a promise? 26 | Answer: Promise { : "invalid" } 27 | Incorrect answer: Promise { : "pending" } 28 | Incorrect answer: Promise { : "fulfilled" } 29 | Incorrect answer: Promise { : "rejected" } -------------------------------------------------------------------------------- /experiments/hand-scoring/011/questions/mdn-promises-text-with-quiz-template-1.txt: -------------------------------------------------------------------------------- 1 | What is a multiple-choice question? 2 | 3 | Correct answer: A question with more than one answer 4 | Incorrect answer: A question with only one answer 5 | Incorrect answer: A question with no answer 6 | Incorrect answer: A question that can't be answered -------------------------------------------------------------------------------- /experiments/hand-scoring/README.md: -------------------------------------------------------------------------------- 1 | # Scoring generated items 2 | 3 | ## Accuracy 4 | 5 | | Score | Description | 6 | | ----- | -------------------------------------------------------------------------------------------------------------------------------------- | 7 | | 1 | A correct answer to the question is not present in any of the answer choices | 8 | | 2 | Either the "correct answer" is wrong but a distractor is correct, or the "correct answer" is correct but there are correct distractors | 9 | | 3 | "Correct answer" is correct, no correct distractors | 10 | 11 | ## Depth 12 | 13 | | Score | Description | 14 | | ----- | ------------------------------------------------------------------------------------- | 15 | | 1 | Question and answer choices cover a single concept | 16 | | 2 | Question covers a single concept, but answer choices include other concepts from text | 17 | | 3 | Question combines multiple concepts | 18 | 19 | ## Utility 20 | 21 | | Score | Description | 22 | | ----- | ----------------------------------------------------------------------------------- | 23 | | 1 | Item is not useful (either completely unrelated to content or no pedagogical value) | 24 | | 2 | Used in an "inspired by" way | 25 | | 3 | Used with superficial modifications | 26 | | 4 | Used verbatim | 27 | -------------------------------------------------------------------------------- /experiments/logit-bias/main.py: -------------------------------------------------------------------------------- 1 | LOGIT_BIASES = [] 2 | -------------------------------------------------------------------------------- /experiments/prompt-bank/api-comparison/prompts/prompt01.txt: -------------------------------------------------------------------------------- 1 | You are creating a multiple choice quiz. Each question should begin with two short code snippets (1-3 lines of code each) that contain patterns or APIs from the content above. The question should compare differences between the code snippets. -------------------------------------------------------------------------------- /experiments/prompt-bank/api-comparison/results/chatgpt-output-1.txt: -------------------------------------------------------------------------------- 1 | In summary, a trait in Rust defines a set of behaviors that a type can have. The trait is defined using the keyword "trait" and the name of the trait. Inside the trait, the method signatures that describe the behavior are listed. Types can then implement this trait by providing their own custom behavior for the methods defined in the trait. This allows for shared behavior among different types and allows for generic types to be constrained to only those types that have the desired behavior. In the example provided, the Summary trait is defined and implemented on the NewsArticle and Tweet structs, providing a summary method for each type. -------------------------------------------------------------------------------- /experiments/prompt-bank/api-comparison/results/chatgpt-output-2.txt: -------------------------------------------------------------------------------- 1 | In Rust, a trait is a way to define shared behavior between different types. Traits are defined using the "trait" keyword and consist of method signatures that describe the behavior of types that implement the trait. In the example provided, a Summary trait is defined that consists of a single method, "summarize", which takes a reference to self and returns a string. The NewsArticle and Tweet structs are then implemented to have the Summary trait, with custom behavior for the summarize method provided for each struct. This allows the media aggregator library to display summaries of data stored in a NewsArticle or Tweet instance by calling the summarize method on an instance. 2 | -------------------------------------------------------------------------------- /experiments/prompt-bank/hypothetical/prompts/prompt01.txt: -------------------------------------------------------------------------------- 1 | You are writing a multiple choice quiz. Each question should present a hypothetical code snippet (1-10 lines of code). The code snippet should be related to the content above. The code snippet should NOT reuse code from above. The question should then ask a question about the code snippet's design. Do NOT simply ask what the code snippet does. -------------------------------------------------------------------------------- /experiments/prompt-bank/main.py: -------------------------------------------------------------------------------- 1 | import functools 2 | import operator 3 | import os 4 | from pathlib import Path 5 | 6 | PROMPTS = ["api-comparison", "hypothetical"] 7 | BANK_DIR = os.path.dirname(os.path.realpath(__file__)) 8 | TEST_FILES_DIR = os.path.join(BANK_DIR, "test-files") 9 | 10 | # add parent dir to path to allow importing from server dir 11 | parent_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 12 | os.sys.path.insert(0, os.path.join(parent_dir, "server")) 13 | from lib.completion import complete 14 | from lib.parsers.md import md_parser 15 | 16 | for test_dir in PROMPTS: 17 | test_dir = os.path.join(BANK_DIR, test_dir) 18 | prompt_dir = os.path.join(test_dir, "prompts") 19 | 20 | for prompt_file in os.listdir(prompt_dir): 21 | prompt_file = os.path.abspath(os.path.join(prompt_dir, prompt_file)) 22 | 23 | with open(prompt_file) as pf: 24 | prompt = pf.read() 25 | 26 | with open(os.path.join(TEST_FILES_DIR, "traits.md")) as cf: 27 | content = cf.read() 28 | 29 | # retrieve and flatten results 30 | completion = complete(content, md_parser, 5, prompt) 31 | completion = functools.reduce(operator.iconcat, completion, []) 32 | 33 | prompt_no_ext = Path(prompt_file).stem 34 | results_file = os.path.join(test_dir, "results", f"{prompt_no_ext}-output.txt") 35 | with open(results_file, "w+") as rf: 36 | for question in completion: 37 | # a python string abomination 38 | formatted = \ 39 | f"""Question: {question['question']} 40 | Code: {question['code']} 41 | Correct: {question['correct']} 42 | Incorrect: {''' 43 | Incorrect: '''.join(question['incorrect'])}\n\n""" 44 | 45 | rf.write(formatted) 46 | -------------------------------------------------------------------------------- /experiments/server-tests/load.py: -------------------------------------------------------------------------------- 1 | import aiohttp 2 | import asyncio 3 | import pathlib 4 | 5 | BACKEND_URL = "http://localhost:8000" 6 | API_URL = f"{BACKEND_URL}/api" 7 | AUTH_URL = f"{BACKEND_URL}/auth" 8 | 9 | NUM_REQUESTS = 20 10 | NUM_QUESTIONS = 5 11 | CONTENT_FILE = pathlib.Path(__file__).parent.resolve().parent.joinpath("plai/smol-reactivity.md") 12 | 13 | # POST data for new quiz 14 | with open(CONTENT_FILE) as f: 15 | content = f.read() 16 | 17 | data = { 18 | "title": "Test quiz", 19 | "content": content, 20 | "count": NUM_QUESTIONS, 21 | "is_markdown": True, 22 | } 23 | 24 | # call /upload route 25 | async def make_gpt_request(session: aiohttp.ClientSession): 26 | response = await session.post(f"{API_URL}/upload", json=data) 27 | result = await response.json() 28 | return result 29 | 30 | async def main(): 31 | async with aiohttp.ClientSession() as session: 32 | # authenticate 33 | await session.post(f"{AUTH_URL}/authenticate") 34 | 35 | tasks = [] 36 | 37 | for _ in range(NUM_REQUESTS): 38 | tasks.append(make_gpt_request(session)) 39 | 40 | results = await asyncio.gather(*tasks, return_exceptions=True) 41 | 42 | return results 43 | 44 | if __name__ == "__main__": 45 | data = asyncio.run(main()) 46 | 47 | for result in data: 48 | print(result) -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | -------------------------------------------------------------------------------- /lib/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2023 Connor Fogarty 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /lib/quizicist/__init__.py: -------------------------------------------------------------------------------- 1 | from .completion import complete as generate_quiz 2 | from .prompt import PromptType -------------------------------------------------------------------------------- /lib/quizicist/consts.py: -------------------------------------------------------------------------------- 1 | import enum 2 | 3 | 4 | # gpt model to use for generating questions 5 | GPT_MODEL = "gpt-4" 6 | 7 | # gpt model to use for converting questions to JSON 8 | JSON_MODEL = "gpt-3.5-turbo" 9 | 10 | # markdown element types valid at the top level 11 | TOP_LEVEL_COMPONENTS = [ 12 | "Paragraph", 13 | "CodeFence", 14 | "List" 15 | ] 16 | 17 | # number of questions to generate per shard 18 | NUM_QUESTIONS = 5 19 | 20 | # maximum tokens allowed in DaVinci-2 model prompt 21 | MAX_MODEL_PROMPT_SIZE = 4000 22 | 23 | # estimated number of tokens generated from a single MCQ 24 | ESTIMATED_QUESTION_SIZE = 175 25 | 26 | # assuming generating 5 questions per shard, largest context possible 27 | MAX_CONTEXT_SIZE = MAX_MODEL_PROMPT_SIZE - NUM_QUESTIONS * ESTIMATED_QUESTION_SIZE 28 | 29 | # feedback options for answer choices 30 | class FeedbackTypes(enum.IntEnum): 31 | unselected = 0 32 | correct = 1 33 | incorrect = 2 -------------------------------------------------------------------------------- /lib/quizicist/errors.py: -------------------------------------------------------------------------------- 1 | # custom exception class for API errors 2 | class QuizicistError(Exception): 3 | pass 4 | -------------------------------------------------------------------------------- /lib/quizicist/parsers/text.py: -------------------------------------------------------------------------------- 1 | from transformers import GPT2Tokenizer 2 | 3 | tokenizer = GPT2Tokenizer.from_pretrained("gpt2") 4 | 5 | def extract_chunk_info(chunk): 6 | tokens = tokenizer(chunk)["input_ids"] 7 | 8 | return { 9 | "text": chunk, 10 | "tokens": len(tokens), 11 | } 12 | 13 | 14 | def parse_text(content): 15 | content = content.read() 16 | 17 | # chunk text by newlines 18 | delimiter = "\n" 19 | chunks = [chunk + delimiter for chunk in content.split(delimiter)] 20 | 21 | return list(map(extract_chunk_info, chunks)) 22 | -------------------------------------------------------------------------------- /lib/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | name="quizicist", 5 | version="0.1.0", 6 | packages=["quizicist"], 7 | install_requires=[ 8 | "openai==0.27.2", 9 | "python-dotenv==0.21.0", 10 | "mistletoe==0.9.0", 11 | "transformers==4.22.1", 12 | "beautifulsoup4==4.11.1", 13 | "lxml==4.9.1", 14 | ], 15 | extras_require={ 16 | "dev": [ 17 | "pytest==7.2.2" 18 | ] 19 | } 20 | ) -------------------------------------------------------------------------------- /lib/tests/test_prompt.py: -------------------------------------------------------------------------------- 1 | from quizicist.prompt import Prompt, PromptType 2 | 3 | def test_prompt(): 4 | for prompt_type in [PromptType.MCQ, PromptType.OPEN_ENDED]: 5 | prompt = Prompt(prompt_type=prompt_type) 6 | prompt.add_system_prompt() 7 | prompt.add_message(role="user", content="hello world") 8 | assert len(prompt.messages) == 2 -------------------------------------------------------------------------------- /site/Caddyfile: -------------------------------------------------------------------------------- 1 | api.quizici.st 2 | 3 | reverse_proxy :8000 4 | -------------------------------------------------------------------------------- /site/README.md: -------------------------------------------------------------------------------- 1 | ## Deployment 2 | 3 | Instructions for deploying to a Google Compute Engine VM. 4 | 5 | ### Installation 6 | 7 | 1. Install [Caddy](https://caddyserver.com/docs/install#debian-ubuntu-raspbian) 8 | 2. Allow Caddy to bind to privileged ports: 9 | ```shell 10 | $ sudo setcap CAP_NET_BIND_SERVICE=+eip $(which caddy) 11 | ``` 12 | 3. Install server dependencies: 13 | ```shell 14 | $ sudo apt-get install libmysqlclient-dev 15 | $ sudo apt-get install memcached 16 | $ python -m venv quiz-env # create quiz-env virtual environment 17 | $ source quiz-env/bin/activate 18 | $ pip install wheel 19 | $ cd lib && pip install -e . && cd .. 20 | $ cd site && pip install --no-cache-dir -r requirements.txt # install dependencies without cache (helps low-RAM VMs) 21 | ``` 22 | 23 | ### Environment 24 | 25 | The production server `.env` file contains different variables from the dev file: 26 | ``` 27 | ENV=prod 28 | FLASK_SECRET= 29 | 30 | RUST_BOOK_PATH= 31 | OPENAI_SECRET_KEY= 32 | 33 | MYSQL_USERNAME= 34 | MYSQL_PASSWORD= 35 | MYSQL_HOST= 36 | MYSQL_DB= 37 | ``` 38 | 39 | ### Running the server 40 | 41 | ```shell 42 | $ cd site 43 | $ sudo systemctl start memcached # start memcached to store rate-limiting data 44 | $ gunicorn -c gunicorn_config.py "backend.main:app" --log-file=gunicorn.log # start app with production WSGI container 45 | $ caddy start # bind caddy to local app 46 | ``` 47 | 48 | ### Stopping the server 49 | 50 | ```shell 51 | $ sudo systemctl stop memcached 52 | $ pkill gunicorn 53 | $ caddy stop 54 | ``` 55 | -------------------------------------------------------------------------------- /site/backend/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cognitive-engineering-lab/quizicist/d6f6c8dd9142f837722569e4119e2419452a4042/site/backend/__init__.py -------------------------------------------------------------------------------- /site/backend/blueprints/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cognitive-engineering-lab/quizicist/d6f6c8dd9142f837722569e4119e2419452a4042/site/backend/blueprints/__init__.py -------------------------------------------------------------------------------- /site/backend/blueprints/auth.py: -------------------------------------------------------------------------------- 1 | from flask import Blueprint 2 | from flask_login import LoginManager, login_user, current_user 3 | from ..models import User 4 | from ..db import db 5 | 6 | login_manager = LoginManager() 7 | 8 | # routes for authentication in JSON API 9 | auth = Blueprint("auth", __name__, template_folder="templates") 10 | 11 | 12 | @login_manager.user_loader 13 | def load_user(user_id): 14 | return User.query.get(int(user_id)) 15 | 16 | 17 | @auth.route("/authenticated", methods=["GET"]) 18 | def authenticated(): 19 | return { "authenticated": current_user.is_authenticated } 20 | 21 | 22 | # create user 23 | @auth.route("/authenticate", methods=["POST"]) 24 | def authenticate(): 25 | if current_user.is_authenticated: 26 | return { 27 | "message": "Already authenticated" 28 | } 29 | 30 | user = User() 31 | 32 | db.session.add(user) 33 | db.session.commit() 34 | 35 | login_user(user, remember=True) 36 | 37 | return { 38 | "message": f"Successfully authenticated with ID: {user.id}" 39 | } 40 | -------------------------------------------------------------------------------- /site/backend/config.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | APP_FOLDER = os.path.dirname(os.path.realpath(__file__)) 4 | UPLOAD_FOLDER = os.path.join(APP_FOLDER, "uploads") 5 | 6 | MYSQL_USERNAME = os.getenv("MYSQL_USERNAME") 7 | MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD") 8 | MYSQL_HOST = os.getenv("MYSQL_HOST") 9 | MYSQL_DB = os.getenv("MYSQL_DB") 10 | 11 | 12 | # base config for debug and production 13 | class Config(object): 14 | # folder for markdown file uploads 15 | UPLOAD_FOLDER = UPLOAD_FOLDER 16 | 17 | # secure secret key loaded from .env 18 | SECRET_KEY = os.environ.get("FLASK_SECRET", "UNSAFE_DEBUG_SECRET") 19 | FLASK_SECRET = SECRET_KEY 20 | 21 | # allow Content-Type header cross-origin 22 | CORS_HEADERS = "Content-Type" 23 | 24 | 25 | # for use in local development 26 | class DebugConfig(Config): 27 | DEVELOPMENT = True 28 | DEBUG = True 29 | 30 | # path to local sqlite database 31 | SQLALCHEMY_DATABASE_URI = "sqlite:///questions.db" 32 | 33 | # store flask limiter data in memory 34 | RATELIMIT_STORAGE_URI = "memory://" 35 | 36 | 37 | # for use in production environment (Google VM) 38 | class ProductionConfig(Config): 39 | DEVELOPMENT = False 40 | DEBUG = False 41 | 42 | SQLALCHEMY_DATABASE_URI = f"mysql://{MYSQL_USERNAME}:{MYSQL_PASSWORD}@{MYSQL_HOST}/{MYSQL_DB}" 43 | 44 | # store flask limiter data in memcached 45 | RATELIMIT_STORAGE_URI = "memcached://localhost:11211" 46 | 47 | # allow requests only from quizici.st 48 | CORS_ORIGINS = ["https://quizici.st"] 49 | -------------------------------------------------------------------------------- /site/backend/db.py: -------------------------------------------------------------------------------- 1 | from flask_sqlalchemy import SQLAlchemy 2 | from flask_migrate import Migrate 3 | 4 | db = SQLAlchemy() 5 | migrate = Migrate() 6 | -------------------------------------------------------------------------------- /site/backend/lib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cognitive-engineering-lab/quizicist/d6f6c8dd9142f837722569e4119e2419452a4042/site/backend/lib/__init__.py -------------------------------------------------------------------------------- /site/backend/lib/consts.py: -------------------------------------------------------------------------------- 1 | import enum 2 | 3 | # message options for user-provided messages 4 | class MessageTypes(enum.IntEnum): 5 | error = 0 6 | suggestion = 1 7 | other = 2 8 | 9 | # methods for exporting forms 10 | class ExportTypes(enum.IntEnum): 11 | google_forms = 0 12 | mdbook = 1 13 | plain_text = 2 14 | 15 | # LLMs used to generate questions 16 | class ModelTypes(str, enum.Enum): 17 | gpt3 = 0 18 | gpt4 = 1 19 | -------------------------------------------------------------------------------- /site/backend/lib/files.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple 2 | from flask import request, current_app 3 | import os 4 | import re 5 | import uuid 6 | from werkzeug.utils import secure_filename 7 | 8 | def handle_file_upload() -> Tuple[str, str]: 9 | """ 10 | Saves an uploaded file to disk with a unique filename. 11 | 12 | Returns a tuple with the original filename and unique filename. 13 | """ 14 | 15 | if "file" not in request.files: 16 | raise ValueError("No file selected") 17 | 18 | file = request.files['file'] 19 | 20 | # If the user does not select a file, the browser submits an 21 | # empty file without a filename. 22 | if file.filename == '': 23 | raise ValueError("No file selected") 24 | 25 | # save file to disk 26 | filename = file.filename 27 | unique_filename = secure_filename(f"{uuid.uuid4().hex}-{filename}") 28 | 29 | upload_path = os.path.join(current_app.config['UPLOAD_FOLDER'], unique_filename) 30 | file.save(upload_path) 31 | 32 | return (filename, unique_filename) 33 | 34 | 35 | def create_file_from_json() -> Tuple[str, str]: 36 | """ 37 | Saves plain-text content uploaded as JSON to disk as markdown. 38 | """ 39 | 40 | title = request.json["title"] 41 | content = request.json["content"] 42 | is_markdown = request.json["content_type"] == "Markdown" 43 | 44 | if not title: 45 | raise ValueError("Title is a required field") 46 | 47 | if not content: 48 | raise ValueError("Content is a required field") 49 | 50 | # if user submitted plain text, escape before saving as markdown 51 | if not is_markdown: 52 | # TODO: more robust escaping for plain text 53 | escape_chars = r'_*[]()~`>#+-=|{}.!' 54 | content = re.sub(f'([{re.escape(escape_chars)}])', r'\\\1', content) 55 | 56 | unique_filename = secure_filename(f"{uuid.uuid4().hex}-{title}.md") 57 | upload_path = os.path.join(current_app.config['UPLOAD_FOLDER'], unique_filename) 58 | with open(upload_path, "w+") as f: 59 | f.write(content) 60 | 61 | return (title, unique_filename) 62 | -------------------------------------------------------------------------------- /site/backend/lib/mdbook.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | import toml 3 | from ..models import Question 4 | from quizicist.consts import FeedbackTypes 5 | 6 | def get_answer_by_feedback(question: Question, feedback: FeedbackTypes): 7 | return [choice.text for choice in question.answers if choice.user_feedback == feedback] 8 | 9 | def serialize_question(question: Question): 10 | incorrect = get_answer_by_feedback(question, FeedbackTypes.incorrect) 11 | correct = get_answer_by_feedback(question, FeedbackTypes.correct) 12 | 13 | return { 14 | "type": "MultipleChoice", 15 | "prompt": { 16 | "prompt": question.question, 17 | "distractors": incorrect, 18 | }, 19 | "answer": { "answer": correct }, 20 | } 21 | 22 | 23 | def questions_to_toml(questions: List[Question]): 24 | # remove deleted questions 25 | questions = filter(lambda question: not question.deleted, questions) 26 | 27 | # remove questions without one correct answer 28 | questions = filter(lambda question: len(get_answer_by_feedback(question, FeedbackTypes.correct)) == 1, questions) 29 | 30 | return toml.dumps({ "questions": list(map(serialize_question, questions)) }) 31 | -------------------------------------------------------------------------------- /site/backend/limiter.py: -------------------------------------------------------------------------------- 1 | from flask_limiter import Limiter 2 | from flask_limiter.util import get_remote_address 3 | 4 | # use IP as default rate limiting key 5 | limiter = Limiter(key_func=get_remote_address) 6 | -------------------------------------------------------------------------------- /site/backend/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | from flask import Flask 4 | from flask_cors import CORS 5 | from dotenv import load_dotenv 6 | from .blueprints.api import api 7 | from .blueprints.auth import auth, login_manager 8 | from .blueprints.admin import admin, bcrypt 9 | from .db import db, migrate 10 | from .config import APP_FOLDER, ProductionConfig, DebugConfig 11 | from .limiter import limiter 12 | 13 | app = Flask(__name__) 14 | 15 | # set config based on ENV variable 16 | load_dotenv() 17 | CONFIG = ProductionConfig if os.getenv("ENV") == "prod" else DebugConfig 18 | app.config.from_object(CONFIG) 19 | 20 | # initialize sqlite db with migrations 21 | db.init_app(app) 22 | migrate.init_app(app, db) 23 | 24 | # limit requests by IP 25 | limiter.init_app(app) 26 | 27 | # initialize flask-login authentication 28 | login_manager.init_app(app) 29 | 30 | # initialize password hashing utils 31 | bcrypt.init_app(app) 32 | 33 | # enable CORS 34 | CORS(app, supports_credentials=True) 35 | 36 | # add blueprints for JSON API, authentication, and admin routes 37 | app.register_blueprint(api, url_prefix="/api") 38 | app.register_blueprint(auth, url_prefix="/auth") 39 | app.register_blueprint(admin, url_prefix="/admin") 40 | 41 | @app.before_first_request 42 | def setup(): 43 | # create directory for file uploads 44 | Path(os.path.join(APP_FOLDER, "uploads")).mkdir(exist_ok=True) 45 | -------------------------------------------------------------------------------- /site/backend/migrations/README: -------------------------------------------------------------------------------- 1 | Single-database configuration for Flask. 2 | -------------------------------------------------------------------------------- /site/backend/migrations/alembic.ini: -------------------------------------------------------------------------------- 1 | # A generic, single database configuration. 2 | 3 | [alembic] 4 | # template used to generate migration files 5 | # file_template = %%(rev)s_%%(slug)s 6 | 7 | # set to 'true' to run the environment during 8 | # the 'revision' command, regardless of autogenerate 9 | # revision_environment = false 10 | 11 | 12 | # Logging configuration 13 | [loggers] 14 | keys = root,sqlalchemy,alembic,flask_migrate 15 | 16 | [handlers] 17 | keys = console 18 | 19 | [formatters] 20 | keys = generic 21 | 22 | [logger_root] 23 | level = WARN 24 | handlers = console 25 | qualname = 26 | 27 | [logger_sqlalchemy] 28 | level = WARN 29 | handlers = 30 | qualname = sqlalchemy.engine 31 | 32 | [logger_alembic] 33 | level = INFO 34 | handlers = 35 | qualname = alembic 36 | 37 | [logger_flask_migrate] 38 | level = INFO 39 | handlers = 40 | qualname = flask_migrate 41 | 42 | [handler_console] 43 | class = StreamHandler 44 | args = (sys.stderr,) 45 | level = NOTSET 46 | formatter = generic 47 | 48 | [formatter_generic] 49 | format = %(levelname)-5.5s [%(name)s] %(message)s 50 | datefmt = %H:%M:%S 51 | -------------------------------------------------------------------------------- /site/backend/migrations/script.py.mako: -------------------------------------------------------------------------------- 1 | """${message} 2 | 3 | Revision ID: ${up_revision} 4 | Revises: ${down_revision | comma,n} 5 | Create Date: ${create_date} 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | ${imports if imports else ""} 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = ${repr(up_revision)} 14 | down_revision = ${repr(down_revision)} 15 | branch_labels = ${repr(branch_labels)} 16 | depends_on = ${repr(depends_on)} 17 | 18 | 19 | def upgrade(): 20 | ${upgrades if upgrades else "pass"} 21 | 22 | 23 | def downgrade(): 24 | ${downgrades if downgrades else "pass"} 25 | -------------------------------------------------------------------------------- /site/backend/migrations/versions/1d7661406625_add_timestamps_and_export_model.py: -------------------------------------------------------------------------------- 1 | """Add timestamps and export model. 2 | 3 | Revision ID: 1d7661406625 4 | Revises: 3cdfbfffba69 5 | Create Date: 2023-01-28 10:41:57.557274 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = '1d7661406625' 14 | down_revision = '3cdfbfffba69' 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | op.create_table('export', 22 | sa.Column('id', sa.Integer(), nullable=False), 23 | sa.Column('generation_id', sa.Integer(), nullable=True), 24 | sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=True), 25 | sa.Column('export_type', sa.Enum('google_forms', 'mdbook', 'plain_text', name='exporttypes'), nullable=True), 26 | sa.Column('google_form_id', sa.String(length=200), nullable=True), 27 | sa.ForeignKeyConstraint(['generation_id'], ['generation.id'], ), 28 | sa.PrimaryKeyConstraint('id') 29 | ) 30 | with op.batch_alter_table('generation', schema=None) as batch_op: 31 | batch_op.add_column(sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=True)) 32 | 33 | with op.batch_alter_table('user', schema=None) as batch_op: 34 | batch_op.add_column(sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=True)) 35 | 36 | # ### end Alembic commands ### 37 | 38 | 39 | def downgrade(): 40 | # ### commands auto generated by Alembic - please adjust! ### 41 | with op.batch_alter_table('user', schema=None) as batch_op: 42 | batch_op.drop_column('created_at') 43 | 44 | with op.batch_alter_table('generation', schema=None) as batch_op: 45 | batch_op.drop_column('created_at') 46 | 47 | op.drop_table('export') 48 | # ### end Alembic commands ### 49 | -------------------------------------------------------------------------------- /site/backend/migrations/versions/3cdfbfffba69_add_content_type_to_generation.py: -------------------------------------------------------------------------------- 1 | """Add content type to generation 2 | 3 | Revision ID: 3cdfbfffba69 4 | Revises: 5 | Create Date: 2023-01-17 17:04:19.179944 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = '3cdfbfffba69' 14 | down_revision = None 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | with op.batch_alter_table('generation', schema=None) as batch_op: 22 | batch_op.add_column(sa.Column('content_type', sa.String(length=10), nullable=False, server_default="Markdown")) 23 | 24 | # ### end Alembic commands ### 25 | 26 | 27 | def downgrade(): 28 | # ### commands auto generated by Alembic - please adjust! ### 29 | with op.batch_alter_table('generation', schema=None) as batch_op: 30 | batch_op.drop_column('content_type') 31 | 32 | # ### end Alembic commands ### 33 | -------------------------------------------------------------------------------- /site/backend/migrations/versions/5845a6a202dc_add_admin_expiration_datetime_for_user_.py: -------------------------------------------------------------------------------- 1 | """Add admin expiration datetime for user model. 2 | 3 | Revision ID: 5845a6a202dc 4 | Revises: 1d7661406625 5 | Create Date: 2023-02-06 11:28:24.038441 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = '5845a6a202dc' 14 | down_revision = '1d7661406625' 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | with op.batch_alter_table('user', schema=None) as batch_op: 22 | batch_op.add_column(sa.Column('admin_expires', sa.DateTime(), nullable=True)) 23 | 24 | # ### end Alembic commands ### 25 | 26 | 27 | def downgrade(): 28 | # ### commands auto generated by Alembic - please adjust! ### 29 | with op.batch_alter_table('user', schema=None) as batch_op: 30 | batch_op.drop_column('admin_expires') 31 | 32 | # ### end Alembic commands ### 33 | -------------------------------------------------------------------------------- /site/backend/migrations/versions/a0318327cfbb_add_llm_model_field_to_generation_class.py: -------------------------------------------------------------------------------- 1 | """Add LLM model field to Generation class 2 | 3 | Revision ID: a0318327cfbb 4 | Revises: 5845a6a202dc 5 | Create Date: 2023-03-19 09:54:45.844733 6 | 7 | """ 8 | from alembic import op 9 | import sqlalchemy as sa 10 | 11 | 12 | # revision identifiers, used by Alembic. 13 | revision = 'a0318327cfbb' 14 | down_revision = '5845a6a202dc' 15 | branch_labels = None 16 | depends_on = None 17 | 18 | 19 | def upgrade(): 20 | # ### commands auto generated by Alembic - please adjust! ### 21 | with op.batch_alter_table('generation', schema=None) as batch_op: 22 | batch_op.add_column(sa.Column('model', sa.Enum('gpt3', 'gpt4', name='modeltypes'), server_default='gpt3', nullable=True)) 23 | 24 | # ### end Alembic commands ### 25 | 26 | 27 | def downgrade(): 28 | # ### commands auto generated by Alembic - please adjust! ### 29 | with op.batch_alter_table('generation', schema=None) as batch_op: 30 | batch_op.drop_column('model') 31 | 32 | # ### end Alembic commands ### 33 | -------------------------------------------------------------------------------- /site/backend/templates/upload.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generate Questions 5 | 6 | 7 |
8 | 9 | 10 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /site/create_db.py: -------------------------------------------------------------------------------- 1 | from backend.main import app 2 | from backend.db import db 3 | 4 | # if running as a script, create db 5 | if __name__ == "__main__": 6 | with app.app_context(): 7 | db.create_all() 8 | -------------------------------------------------------------------------------- /site/frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /site/frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Quizicist: AI-powered quiz generator 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /site/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "homepage": "https://connorff.github.io/quizicist", 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "tsc && vite build", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@chakra-ui/icons": "^2.0.13", 14 | "@chakra-ui/react": "^2.4.1", 15 | "@emotion/react": "^11.10.5", 16 | "@emotion/styled": "^11.10.5", 17 | "axios": "^1.1.3", 18 | "formik": "^2.2.9", 19 | "framer-motion": "^6.5.1", 20 | "react": "^18.2.0", 21 | "react-data-grid": "^7.0.0-beta.22", 22 | "react-diff-viewer": "^3.1.1", 23 | "react-dom": "^18.2.0", 24 | "react-helmet": "^6.1.0", 25 | "react-router-dom": "^6.6.1", 26 | "react-textarea-autosize": "^8.4.1", 27 | "swr": "^2.0.0", 28 | "yup": "^0.32.11" 29 | }, 30 | "devDependencies": { 31 | "@types/node": "^18.11.9", 32 | "@types/react": "^18.0.24", 33 | "@types/react-dom": "^18.0.8", 34 | "@types/react-helmet": "^6.1.6", 35 | "@vitejs/plugin-react": "^2.2.0", 36 | "typescript": "^4.6.4", 37 | "vite": "^3.2.3" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /site/frontend/src/components/AdminAuth.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Container, FormControl, FormErrorMessage, FormLabel, Input } from "@chakra-ui/react"; 2 | import api from "@shared/api"; 3 | import { useState } from "react"; 4 | import { useNavigate } from "react-router-dom"; 5 | 6 | const AdminAuth: React.FC = () => { 7 | const navigate = useNavigate(); 8 | 9 | const [password, setPassword] = useState(""); 10 | const [error, setError] = useState(""); 11 | 12 | const handleChange = (e: React.ChangeEvent) => { 13 | setPassword(e.target.value); 14 | setError(""); 15 | } 16 | 17 | const handleSubmit = async (e: any) => { 18 | e.preventDefault(); 19 | 20 | try { 21 | await api.post("/admin/authenticate", { password }); 22 | } catch (e: any) { 23 | return setError(e.response.data.message); 24 | } 25 | 26 | return navigate("/admin"); 27 | } 28 | 29 | return ( 30 | 31 |
32 | 33 | Admin password 34 | 35 | {error && {error}} 36 | 37 | 38 |
39 |
40 | ); 41 | } 42 | 43 | export default AdminAuth; 44 | -------------------------------------------------------------------------------- /site/frontend/src/components/AdminDashboard.tsx: -------------------------------------------------------------------------------- 1 | import { Container, Spacer } from "@chakra-ui/react"; 2 | import { fetcher } from "@hooks/fetcher"; 3 | import { SERVER_URL } from "@shared/consts"; 4 | import Generation from "@shared/generation.type"; 5 | import { useState } from "react"; 6 | import useSWR from "swr"; 7 | import AdminTable from "./AdminTable"; 8 | import GenerationDiff from "./GenerationDiff"; 9 | 10 | const AdminDashboard = () => { 11 | const { data: generations, isLoading, error } = useSWR(`${SERVER_URL}/admin/generated`, fetcher); 12 | const [generation, setGeneration] = useState(null); 13 | 14 | if (isLoading || error) { 15 | return
Loading data...
; 16 | } 17 | 18 | return ( 19 | 20 | 21 | 22 | 23 | 24 | {generation && } 25 | 26 | ); 27 | } 28 | 29 | export default AdminDashboard; 30 | -------------------------------------------------------------------------------- /site/frontend/src/components/CollapsibleAlert.tsx: -------------------------------------------------------------------------------- 1 | import { Alert, AlertDescription, AlertTitle, Box, Link, Text, useDisclosure } from "@chakra-ui/react"; 2 | import { PropsWithChildren } from "react"; 3 | 4 | type CollapsibleAlertProps = { 5 | storageKey: string; 6 | title: React.ReactNode; 7 | content: React.ReactNode; 8 | } 9 | 10 | // retrieve whether message should display from local storage 11 | const shouldBeOpen = (key: string) => { 12 | const stored = localStorage.getItem(key); 13 | if (!stored) return true; 14 | 15 | return stored !== "1"; 16 | } 17 | 18 | const CollapsibleAlert: React.FC = ({ storageKey, title, content }) => { 19 | const ALERT_KEY = `quizicist:${storageKey}`; 20 | const { isOpen: isVisible, onOpen, onClose } = useDisclosure({ defaultIsOpen: shouldBeOpen(ALERT_KEY) }); 21 | 22 | const toggle = () => { 23 | if (isVisible) { 24 | localStorage.setItem(ALERT_KEY, "1"); 25 | onClose(); 26 | } else { 27 | localStorage.setItem(ALERT_KEY, "0"); 28 | onOpen(); 29 | } 30 | } 31 | 32 | const ToggleLink: React.FC = ({ children }) => ( 33 | 34 | {children} 35 | 36 | ); 37 | 38 | if (isVisible) { 39 | content = ( 40 | <> 41 |
{content}
42 | Dismiss 43 | 44 | ) 45 | } else { 46 | content = ( 47 | Show more 48 | ) 49 | } 50 | 51 | return ( 52 | 53 | 54 | {title} 55 | 56 | {content} 57 | 58 | 59 | 60 | ) 61 | } 62 | 63 | export default CollapsibleAlert; 64 | -------------------------------------------------------------------------------- /site/frontend/src/components/Dashboard.module.css: -------------------------------------------------------------------------------- 1 | .divider { 2 | margin: 2em 0; 3 | } 4 | -------------------------------------------------------------------------------- /site/frontend/src/components/ExportTextbox.tsx: -------------------------------------------------------------------------------- 1 | import { Button, Textarea, useClipboard } from "@chakra-ui/react" 2 | import api from "@shared/api"; 3 | import { API_URL } from "@shared/consts"; 4 | import Generation from "@shared/generation.type"; 5 | 6 | type ExportTextboxProps = { 7 | value: string; 8 | generation: Generation; 9 | export_type: number; 10 | }; 11 | 12 | const ExportTextbox: React.FC = ({ value, generation, export_type }) => { 13 | const { onCopy, hasCopied } = useClipboard(value); 14 | 15 | const handleCopy = async () => { 16 | // copy value to clipboard 17 | onCopy(); 18 | 19 | // log export on server 20 | await api.post(`${API_URL}/generated/${generation.id}/log_export`, { export_type }); 21 | } 22 | 23 | return ( 24 | <> 25 |