Skip to content

Commit

Permalink
Merge pull request #110 from avantifellows/partial_marking
Browse files Browse the repository at this point in the history
Partial marking
  • Loading branch information
suryabulusu committed May 22, 2023
2 parents 054d292 + 1af8d80 commit 852bc50
Show file tree
Hide file tree
Showing 23 changed files with 578 additions and 93 deletions.
2 changes: 1 addition & 1 deletion src/components/Omr/OmrModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<div
v-for="(questionSetState, index) in questionSetStates" :key="index" class="space-y-2">
<p :class="titleTextClass" :data-test="`questionSetTitle-${index}`">{{ questionSetState.title }}</p>
<p :class="instructionTextClass" :data-test="`questionSetInstruction-${index}`">{{ questionSetState.instructionText }}</p>
<p :class="instructionTextClass" :data-test="`questionSetInstruction-${index}`" v-html="questionSetState.instructionText"></p>
<div class="mt-4 space-y-4">
<OmrItem
v-for="(questionState, qindex) in questionSetState.paletteItems"
Expand Down
7 changes: 7 additions & 0 deletions src/components/Questions/Palette/Item.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
:hasQuizEnded="hasQuizEnded"
data-test="error"
></Error>
<PartialSuccess
v-else-if="state == 'partial-success'"
:hasQuizEnded="hasQuizEnded"
data-test="partial-success"
></PartialSuccess>
<Neutral
v-else-if="state == 'neutral'"
:hasQuizEnded="hasQuizEnded"
Expand All @@ -31,6 +36,7 @@
<script lang="ts">
import { defineComponent, PropType } from "vue";
import Success from "./Success.vue";
import PartialSuccess from "./PartialSuccess.vue"
import Error from "./Error.vue";
import Neutral from "./Neutral.vue";
import { questionState } from "../../../types";
Expand All @@ -39,6 +45,7 @@ export default defineComponent({
name: "Item",
components: {
Success,
PartialSuccess,
Error,
Neutral,
},
Expand Down
29 changes: 29 additions & 0 deletions src/components/Questions/Palette/PartialSuccess.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<template>
<KeyTemplate
:title="title"
:hasQuizEnded="hasQuizEnded"
iconName="partially-correct-rounded"
iconClass="bg-blue-300 border-blue-500"
></KeyTemplate>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import KeyTemplate from "./KeyTemplate.vue";
export default defineComponent({
props: {
title: {
type: String,
default: "",
},
hasQuizEnded: {
type: Boolean,
default: false,
},
},
components: {
KeyTemplate,
},
});
</script>
14 changes: 12 additions & 2 deletions src/components/Questions/Palette/QuestionPalette.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@
<Error :title="legendErrorText" :hasQuizEnded="hasQuizEnded"></Error>
</div>

<Neutral
<div class="grid grid-cols-2">
<Neutral
:title="legendNeutralText"
:hasQuizEnded="hasQuizEnded"
></Neutral>
<div v-if="hasQuizEnded">
<PartialSuccess :title="legendPartialSuccessText" :hasQuizEnded="hasQuizEnded"></PartialSuccess>
</div>
</div>
</div>

<div
v-for="(questionSetState, index) in questionSetStates" :key="index" class="space-y-2">
<p :class="titleTextClass" :data-test="`paletteTitle-${index}`">{{ questionSetState.title }}</p>
<p :class="instructionTextClass" :data-test="`paletteInstruction-${index}`">{{ questionSetState.instructionText }}</p>
<div :class="instructionTextClass" :data-test="`paletteInstruction-${index}`" v-html="questionSetState.instructionText"></div>
<div class="grid grid-cols-5 bp-500:grid-cols-6 lg:grid-cols-7 xl:grid-cols-8 mt-4 space-y-4">
<PaletteItem
v-for="(questionState, qindex) in questionSetState.paletteItems"
Expand All @@ -42,6 +47,7 @@

<script lang="ts">
import Success from "./Success.vue";
import PartialSuccess from "./PartialSuccess.vue";
import Error from "./Error.vue";
import Neutral from "./Neutral.vue";
import PaletteItem from "./Item.vue";
Expand All @@ -51,6 +57,7 @@ import { defineComponent, computed, PropType } from "vue";
export default defineComponent({
components: {
Success,
PartialSuccess,
Error,
Neutral,
PaletteItem,
Expand Down Expand Up @@ -84,6 +91,8 @@ export default defineComponent({
props.hasQuizEnded ? "Skipped" : "Not Visited"
);
const legendPartialSuccessText = "Partially Correct"
const state = {
instructionTextClass:
"text-lg md:text-xl lg:text-2xl mx-4 m-2 leading-tight whitespace-pre-wrap text-slate-500",
Expand All @@ -95,6 +104,7 @@ export default defineComponent({
...state,
navigateToQuestion,
legendSuccessText,
legendPartialSuccessText,
legendErrorText,
legendNeutralText,
};
Expand Down
18 changes: 10 additions & 8 deletions src/components/Scorecard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,15 @@
<!-- metric boxes -->
<div
v-if="hasGradedQuestions"
class="flex flex-col bp-500:flex-row justify-center space-y-1 bp-500:space-x-1 bp-500:space-y-0 px-4 bp-500:px-10 max-w-4xl place-self-center"
class="flex flex-col bp-500:flex-row justify-center space-y-1 bp-500:space-x-1 bp-500:space-y-0 px-4 bp-500:px-10 place-self-center items-stretch"
>
<div
v-for="(metric, metricIndex) in metrics"
class="rounded-md bp-500:rounded-2xl bg-amber-400 grid grid-cols-2 bp-500:grid-rows-2 bp-500:grid-cols-none lg:grid-cols-2 lg:grid-rows-none border-2 px-4 lg:px-6 w-full h-14 bp-500:h-20 min-w-max"
class="rounded-md bp-500:rounded-2xl bg-amber-400 flex flex-row bp-500:flex-col lg:flex-row border-2 px-4 lg:px-6 lg:h-20 space-x-4 w-full md:w-2/3 lg:w-1/2 h-full"
:key="metric"
>
<div
class="w-full h-full flex flex-row justify-center space-x-2 bp-500:mt-2 lg:mt-0"
class="w-full h-full flex flex-row justify-center space-x-2 bp-500:mt-2 lg:mt-0 "
>
<!-- metric icon -->
<BaseIcon
Expand All @@ -62,17 +62,17 @@
></BaseIcon>
<!-- numeric value of the metric -->
<p
class="text-xl bp-360:text-2xl md:text-3xl lg:text-4xl font-bold my-auto"
class="text-xl bp-360:text-2xl md:text-3xl lg:text-4xl font-bold my-auto text-left"
:data-test="`metricValue-${metricIndex}`"
>
{{ metric.value }}
</p>
</div>
<!-- name of the metric -->
<div
class="text-center text-xs bp-500:text-sm md:text-base mt-1 lg:mt-2 bp-500:whitespace-nowrap px-1 h-full flex place-self-center items-center"
class="text-center text-xs bp-500:text-sm md:text-base px-1 h-full flex items-center w-full"
>
<p>
<p class="break-words text-left">
{{ metric.name }}
</p>
</div>
Expand All @@ -98,12 +98,14 @@
></icon-button>

<!-- back button -->
<icon-button
<!-- commenting this as it's not being used right now, so it should not take
up space in the DOM -->
<!-- <icon-button
:titleConfig="backButtonTitleConfig"
:buttonClass="backButtonClass"
@click="goBack"
data-test="backButton"
></icon-button>
></icon-button> -->
</div>
</div>
</div>
Expand Down
6 changes: 6 additions & 0 deletions src/components/UI/Icons/BaseIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
<CorrectRounded v-if="name == 'correct-rounded'"></CorrectRounded>
<WrongRounded v-if="name == 'wrong-rounded'"></WrongRounded>
<SkipRounded v-if="name == 'skip-rounded'"></SkipRounded>
<PartiallyCorrect v-if="name == 'partially-correct'"></PartiallyCorrect>
<PartiallyCorrectRounded v-if="name == 'partially-correct-rounded'"></PartiallyCorrectRounded>
</div>
</template>

Expand All @@ -26,6 +28,7 @@ import Math from "./Math.vue";
import Notepad from "./Notepad.vue";
import Splash from "./Splash.vue";
import Correct from "./Correct.vue";
import PartiallyCorrect from "./PartiallyCorrect.vue";
import Wrong from "./Wrong.vue";
import SpinnerSolid from "./SpinnerSolid.vue";
import RightArrow from "./RightArrow.vue";
Expand All @@ -36,6 +39,7 @@ import Hamburger from "./Hamburger.vue";
import CorrectRounded from "./CorrectRounded.vue";
import WrongRounded from "./WrongRounded.vue";
import SkipRounded from "./SkipRounded.vue";
import PartiallyCorrectRounded from "./PartiallyCorrectRounded.vue"
export default {
name: "BaseIcon",
Expand All @@ -46,6 +50,7 @@ export default {
Notepad,
Splash,
Correct,
PartiallyCorrect,
Wrong,
SpinnerSolid,
RightArrow,
Expand All @@ -56,6 +61,7 @@ export default {
CorrectRounded,
WrongRounded,
SkipRounded,
PartiallyCorrectRounded
},
props: {
name: {
Expand Down
21 changes: 21 additions & 0 deletions src/components/UI/Icons/PartiallyCorrect.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="blue"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="4"
d="M5 13l4 4L19 7"
/>
</svg>
</template>

<script>
export default {
name: "PartiallyCorrect",
};
</script>
21 changes: 21 additions & 0 deletions src/components/UI/Icons/PartiallyCorrectRounded.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<template>
<svg
width="44"
height="44"
viewBox="0 0 44 44"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="21.7122" cy="21.7122" r="21.7122" fill="#1083b9" />
<path
d="M29.9989 13.4241L17.3629 23.6765L13.7178 18.4983C13.2138 17.7844 12.2328 17.6127 11.5218 18.1188C10.8108 18.6248 10.6443 19.6099 11.1438 20.3238L15.7609 26.8801C16.0129 27.237 16.3999 27.472 16.8319 27.5352C16.9039 27.5443 16.9759 27.5488 17.0479 27.5488C17.4079 27.5488 17.7544 27.4268 18.0379 27.1964L31.9834 15.8866C32.6584 15.3399 32.7664 14.3413 32.2174 13.6636C31.6684 12.9813 30.6784 12.8774 29.9989 13.4241Z"
fill="white"
/>
</svg>
</template>

<script>
export default {
name: "PartiallyCorrectRounded",
};
</script>
5 changes: 3 additions & 2 deletions src/services/Functional/Utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ export function resetConfetti() {
*/
export function isQuestionAnswerCorrect(
questionDetail: Question,
userAnswer: submittedAnswer
userAnswer: submittedAnswer,
doesPartialMarkingExist: Boolean
): answerEvaluation {
const answerEvaluation = {
valid: false,
Expand All @@ -102,7 +103,7 @@ export function isQuestionAnswerCorrect(
const correctAnswer = questionDetail.correct_answer;
if (isEqual(userAnswer, correctAnswer)) {
answerEvaluation.isCorrect = true;
} else if (Array.isArray(userAnswer) && Array.isArray(correctAnswer) && userAnswer.length > 0) {
} else if (doesPartialMarkingExist && Array.isArray(userAnswer) && Array.isArray(correctAnswer) && userAnswer.length > 0) {
// check if user answer is a subset of correct answer
const isSubset = userAnswer.every((option) =>
correctAnswer.includes(option)
Expand Down
13 changes: 12 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,20 @@ interface Image {
alt_text: string;
}

interface PartialMarkCondition {
num_correct_selected: number;
}

interface PartialMarkRule {
conditions: PartialMarkCondition[];
marks: number;
}

interface MarkingScheme {
correct: number;
wrong: number;
skipped: number;
partial: PartialMarkRule[] | null;
}

interface Option {
Expand Down Expand Up @@ -143,6 +153,7 @@ export interface QuestionSet {
questions: Question[];
max_questions_allowed_to_attempt: number;
title: string | null;
description: string | null;
marking_scheme: MarkingScheme;
}

Expand Down Expand Up @@ -203,7 +214,7 @@ export interface answerEvaluation {
isPartiallyCorrect?: boolean; // whether question has been partially answered for multi answer
}

export type questionState = "success" | "error" | "neutral";
export type questionState = "success" | "error" | "neutral" | "partial-success";
export interface paletteItemState {
index: number; // index of the corresponding question in the list of questions
value: questionState;
Expand Down
Loading

0 comments on commit 852bc50

Please sign in to comment.