mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
quizzes and assignments support negative and floating point values
This commit is contained in:
@@ -220,4 +220,52 @@ Which events are triggered when the user clicks on an input field?
|
|||||||
short_answer";
|
short_answer";
|
||||||
questionMarkdown.Should().Contain(expectedMarkdown);
|
questionMarkdown.Should().Contain(expectedMarkdown);
|
||||||
}
|
}
|
||||||
|
[Test]
|
||||||
|
public void NegativePoints_IsAllowed()
|
||||||
|
{
|
||||||
|
var rawMarkdownQuiz = @"
|
||||||
|
Name: Test Quiz
|
||||||
|
ShuffleAnswers: true
|
||||||
|
OneQuestionAtATime: false
|
||||||
|
DueAt: 2023-08-21T23:59:00
|
||||||
|
LockAt: 2023-08-21T23:59:00
|
||||||
|
AssignmentGroup: Assignments
|
||||||
|
AllowedAttempts: -1
|
||||||
|
Description: this is the
|
||||||
|
multi line
|
||||||
|
description
|
||||||
|
---
|
||||||
|
Points: -4
|
||||||
|
Which events are triggered when the user clicks on an input field?
|
||||||
|
short answer
|
||||||
|
";
|
||||||
|
|
||||||
|
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
||||||
|
var firstQuestion = quiz.Questions.First();
|
||||||
|
firstQuestion.Points.Should().Be(-4);
|
||||||
|
}
|
||||||
|
[Test]
|
||||||
|
public void FloatingPointPoints_IsAllowed()
|
||||||
|
{
|
||||||
|
var rawMarkdownQuiz = @"
|
||||||
|
Name: Test Quiz
|
||||||
|
ShuffleAnswers: true
|
||||||
|
OneQuestionAtATime: false
|
||||||
|
DueAt: 2023-08-21T23:59:00
|
||||||
|
LockAt: 2023-08-21T23:59:00
|
||||||
|
AssignmentGroup: Assignments
|
||||||
|
AllowedAttempts: -1
|
||||||
|
Description: this is the
|
||||||
|
multi line
|
||||||
|
description
|
||||||
|
---
|
||||||
|
Points: 4.56
|
||||||
|
Which events are triggered when the user clicks on an input field?
|
||||||
|
short answer
|
||||||
|
";
|
||||||
|
|
||||||
|
var quiz = LocalQuiz.ParseMarkdown(rawMarkdownQuiz);
|
||||||
|
var firstQuestion = quiz.Questions.First();
|
||||||
|
firstQuestion.Points.Should().Be(4.56);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,4 +68,35 @@ public class RubricMarkdownTests
|
|||||||
rubric.First().IsExtraCredit.Should().BeTrue();
|
rubric.First().IsExtraCredit.Should().BeTrue();
|
||||||
rubric.First().Label.Should().Be("(Extra Credit) this is the task");
|
rubric.First().Label.Should().Be("(Extra Credit) this is the task");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCanParseFloatingPointNubmers()
|
||||||
|
{
|
||||||
|
var rawRubric = @"
|
||||||
|
- 1.5pt: this is the task
|
||||||
|
";
|
||||||
|
|
||||||
|
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
|
||||||
|
rubric.First().Points.Should().Be(1.5);
|
||||||
|
}
|
||||||
|
[Test]
|
||||||
|
public void TestCanParseNegativeNubmers()
|
||||||
|
{
|
||||||
|
var rawRubric = @"
|
||||||
|
- -2pt: this is the task
|
||||||
|
";
|
||||||
|
|
||||||
|
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
|
||||||
|
rubric.First().Points.Should().Be(-2.0);
|
||||||
|
}
|
||||||
|
[Test]
|
||||||
|
public void TestCanParseNegativeFloatingPointNubmers()
|
||||||
|
{
|
||||||
|
var rawRubric = @"
|
||||||
|
- -2895.00053pt: this is the task
|
||||||
|
";
|
||||||
|
|
||||||
|
var rubric = LocalAssignment.ParseRubricMarkdown(rawRubric);
|
||||||
|
rubric.First().Points.Should().Be(-2895.00053);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,9 +61,7 @@
|
|||||||
|
|
||||||
private MarkupString preview { get
|
private MarkupString preview { get
|
||||||
{
|
{
|
||||||
var pipeline = new MarkdownPipelineBuilder()
|
return (MarkupString)MarkdownService.Render(assignmentContext?.Assignment?.Description ?? "");
|
||||||
.UsePipeTables().Build();
|
|
||||||
return (MarkupString)Markdown.ToHtml(assignmentContext?.Assignment?.Description ?? "", pipeline);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private string HelpText()
|
private string HelpText()
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
assignmentContext.StateHasChanged -= reload;
|
assignmentContext.StateHasChanged -= reload;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int requiredPoints => assignmentContext?.Assignment?.Rubric.Where(r => !r.IsExtraCredit).Select(r => r.Points).Sum() ?? 0;
|
private double requiredPoints => assignmentContext?.Assignment?.Rubric.Where(r => !r.IsExtraCredit).Select(r => r.Points).Sum() ?? 0;
|
||||||
private int extraCreditPoints => assignmentContext?.Assignment?.Rubric.Where(r => r.IsExtraCredit).Select(r => r.Points).Sum() ?? 0;
|
private double extraCreditPoints => assignmentContext?.Assignment?.Rubric.Where(r => r.IsExtraCredit).Select(r => r.Points).Sum() ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@if(assignmentContext != null)
|
@if(assignmentContext != null)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
private string rawText { get; set; } = string.Empty;
|
private string rawText { get; set; } = string.Empty;
|
||||||
private string? error = null;
|
private string? error = null;
|
||||||
|
|
||||||
private MarkupString preview { get => (MarkupString)Markdown.ToHtml(pageContext?.Page?.Text ?? ""); }
|
private MarkupString preview { get => (MarkupString)MarkdownService.Render(pageContext?.Page?.Text ?? ""); }
|
||||||
|
|
||||||
private void handleChange(string newRawPage)
|
private void handleChange(string newRawPage)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -96,7 +96,7 @@
|
|||||||
private string canvasQuizUrl =>
|
private string canvasQuizUrl =>
|
||||||
$"https://snow.instructure.com/courses/{planner.LocalCourse?.Settings.CanvasId}/quizzes/{quizInCanvas?.Id}";
|
$"https://snow.instructure.com/courses/{planner.LocalCourse?.Settings.CanvasId}/quizzes/{quizInCanvas?.Id}";
|
||||||
|
|
||||||
private int? quizPoints => quizContext.Quiz?.Questions.Sum(q => q.Points);
|
private double? quizPoints => quizContext.Quiz?.Questions.Sum(q => q.Points);
|
||||||
private bool showHelp = false;
|
private bool showHelp = false;
|
||||||
|
|
||||||
private readonly static string exampleMarkdownQuestion = @"QUESTION REFERENCE
|
private readonly static string exampleMarkdownQuestion = @"QUESTION REFERENCE
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public record LocalAssignment : IModuleItem
|
|||||||
public string? LocalAssignmentGroupName { get; init; }
|
public string? LocalAssignmentGroupName { get; init; }
|
||||||
public IEnumerable<string> SubmissionTypes { get; init; } = Array.Empty<string>();
|
public IEnumerable<string> SubmissionTypes { get; init; } = Array.Empty<string>();
|
||||||
public IEnumerable<RubricItem> Rubric { get; init; } = Array.Empty<RubricItem>();
|
public IEnumerable<RubricItem> Rubric { get; init; } = Array.Empty<RubricItem>();
|
||||||
public int PointsPossible => Rubric.Sum(r => r.IsExtraCredit ? 0 : r.Points);
|
public double PointsPossible => Rubric.Sum(r => r.IsExtraCredit ? 0 : r.Points);
|
||||||
|
|
||||||
|
|
||||||
public string GetDescriptionHtml()
|
public string GetDescriptionHtml()
|
||||||
|
|||||||
@@ -89,12 +89,12 @@ public static class LocalAssignmentMarkdownParser
|
|||||||
|
|
||||||
private static RubricItem parseIndividualRubricItemMarkdown(string rawMarkdown)
|
private static RubricItem parseIndividualRubricItemMarkdown(string rawMarkdown)
|
||||||
{
|
{
|
||||||
var pointsPattern = @"\s*-\s*(\d+)\s*pt(s)?:";
|
var pointsPattern = @"\s*-\s*(-?\d+(?:\.\d+)?)\s*pt(s)?:";
|
||||||
var match = Regex.Match(rawMarkdown, pointsPattern);
|
var match = Regex.Match(rawMarkdown, pointsPattern);
|
||||||
if (!match.Success)
|
if (!match.Success)
|
||||||
throw new RubricMarkdownParseException($"points not found: {rawMarkdown}");
|
throw new RubricMarkdownParseException($"points not found: {rawMarkdown}");
|
||||||
|
|
||||||
var points = int.Parse(match.Groups[1].Value);
|
var points = double.Parse(match.Groups[1].Value);
|
||||||
|
|
||||||
var label = string.Join(": ", rawMarkdown.Split(": ").Skip(1));
|
var label = string.Join(": ", rawMarkdown.Split(": ").Skip(1));
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ public record RubricItem
|
|||||||
{
|
{
|
||||||
public static readonly string extraCredit = "(Extra Credit) ";
|
public static readonly string extraCredit = "(Extra Credit) ";
|
||||||
public required string Label { get; set; }
|
public required string Label { get; set; }
|
||||||
public required int Points { get; set; }
|
public required double Points { get; set; }
|
||||||
public bool IsExtraCredit => Label.Contains(extraCredit.ToLower(), StringComparison.CurrentCultureIgnoreCase);
|
public bool IsExtraCredit => Label.Contains(extraCredit.ToLower(), StringComparison.CurrentCultureIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public record LocalQuizQuestion
|
|||||||
public string Text { get; init; } = string.Empty;
|
public string Text { get; init; } = string.Empty;
|
||||||
public string HtmlText => MarkdownService.Render(Text);
|
public string HtmlText => MarkdownService.Render(Text);
|
||||||
public string QuestionType { get; init; } = string.Empty;
|
public string QuestionType { get; init; } = string.Empty;
|
||||||
public int Points { get; init; }
|
public double Points { get; init; }
|
||||||
public IEnumerable<LocalQuizQuestionAnswer> Answers { get; init; } =
|
public IEnumerable<LocalQuizQuestionAnswer> Answers { get; init; } =
|
||||||
Enumerable.Empty<LocalQuizQuestionAnswer>();
|
Enumerable.Empty<LocalQuizQuestionAnswer>();
|
||||||
public string ToMarkdown()
|
public string ToMarkdown()
|
||||||
@@ -59,9 +59,9 @@ public record LocalQuizQuestion
|
|||||||
var textHasPoints = lines.Length > 0
|
var textHasPoints = lines.Length > 0
|
||||||
&& lines.First().Contains(": ")
|
&& lines.First().Contains(": ")
|
||||||
&& lines.First().Split(": ").Length > 1
|
&& lines.First().Split(": ").Length > 1
|
||||||
&& int.TryParse(lines.First().Split(": ")[1], out _);
|
&& double.TryParse(lines.First().Split(": ")[1], out _);
|
||||||
|
|
||||||
int points = firstLineIsPoints && textHasPoints ? int.Parse(lines.First().Split(": ")[1]) : 1;
|
double points = firstLineIsPoints && textHasPoints ? double.Parse(lines.First().Split(": ")[1]) : 1;
|
||||||
|
|
||||||
var linesWithoutPoints = firstLineIsPoints ? lines[1..] : lines;
|
var linesWithoutPoints = firstLineIsPoints ? lines[1..] : lines;
|
||||||
|
|
||||||
|
|||||||
@@ -19,24 +19,24 @@ services:
|
|||||||
- ~/projects/faculty/4620_Distributed/2024Spring/modules:/app/storage/distributed
|
- ~/projects/faculty/4620_Distributed/2024Spring/modules:/app/storage/distributed
|
||||||
- ~/projects/faculty/3840_Telemetry/2024Spring_alex/modules:/app/storage/telemetry_and_operations
|
- ~/projects/faculty/3840_Telemetry/2024Spring_alex/modules:/app/storage/telemetry_and_operations
|
||||||
|
|
||||||
collector:
|
# collector:
|
||||||
image: otel/opentelemetry-collector-contrib
|
# image: otel/opentelemetry-collector-contrib
|
||||||
volumes:
|
# volumes:
|
||||||
- ./canvas-development/otel-collector-config.yml:/etc/otelcol-contrib/config.yaml
|
# - ./canvas-development/otel-collector-config.yml:/etc/otelcol-contrib/config.yaml
|
||||||
ports:
|
# ports:
|
||||||
- 1888:1888 # pprof extension
|
# - 1888:1888 # pprof extension
|
||||||
- 8888:8888 # Prometheus metrics exposed by the Collector
|
# - 8888:8888 # Prometheus metrics exposed by the Collector
|
||||||
- 8889:8889 # Prometheus exporter metrics
|
# - 8889:8889 # Prometheus exporter metrics
|
||||||
- 13133:13133 # health_check extension
|
# - 13133:13133 # health_check extension
|
||||||
- 4317:4317 # OTLP gRPC receiver
|
# - 4317:4317 # OTLP gRPC receiver
|
||||||
- 4318:4318 # OTLP http receiver
|
# - 4318:4318 # OTLP http receiver
|
||||||
- 55679:55679 # zpages extension
|
# - 55679:55679 # zpages extension
|
||||||
|
|
||||||
zipkin:
|
# zipkin:
|
||||||
image: ghcr.io/openzipkin/zipkin-slim
|
# image: ghcr.io/openzipkin/zipkin-slim
|
||||||
# Environment settings are defined here https://github.com/openzipkin/zipkin/blob/master/zipkin-server/README.md#environment-variables
|
# # Environment settings are defined here https://github.com/openzipkin/zipkin/blob/master/zipkin-server/README.md#environment-variables
|
||||||
environment:
|
# environment:
|
||||||
- STORAGE_TYPE=mem
|
# - STORAGE_TYPE=mem
|
||||||
ports:
|
# ports:
|
||||||
- 9411:9411
|
# - 9411:9411
|
||||||
# command: --logging.level.zipkin2=DEBUG
|
# # command: --logging.level.zipkin2=DEBUG
|
||||||
|
|||||||
Reference in New Issue
Block a user