Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/backups/email_hash_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def find_emails_by_hashes(input_file, output_file, target_hashes):
print(f"Error: The file '{input_file}' or '{output_file}' was not found.")


# TODO parameterize as CLI
if __name__ == "__main__":
target_list = [
"e3384165",
Expand Down
4 changes: 0 additions & 4 deletions src/backups/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ def store(

If any arguments are not specified, this command will use the values in the CONFIG .json file.
"""
# TODO add prompt when overwriting db or actual files
config_dict = read_config(config)

if course_endpoint is None:
Expand Down Expand Up @@ -298,7 +297,6 @@ def store(
print(f"Finished storing backups in {database} in {end - start} seconds")


# TODO need to rerun lint with new schema for 61a and c88c fa25
@app.command()
def lint(
database: Annotated[
Expand All @@ -325,7 +323,6 @@ def lint(

If any arguments are not specified, this command will use the values in the CONFIG .json file.
"""
# TODO add prompt when overwriting db or actual files
config_dict = read_config(config)

if database is None:
Expand Down Expand Up @@ -375,7 +372,6 @@ def backup_file_metadata(

If any arguments are not specified, this command will use the values in the CONFIG .json file.
"""
# TODO add prompt when overwriting db or actual files
config_dict = read_config(config)

if database is None:
Expand Down
2 changes: 0 additions & 2 deletions src/backups/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@

PREFIX = "../../data/private"

# TODO make this programmatically adjustable
FILENAME_PREFIX = "/Users/rebeccadang/Desktop/Code/ucb/berkeley-cdss/assignment-snapshots/data/private/"


Expand Down Expand Up @@ -79,7 +78,6 @@ def create_backup_and_write_messages(
continue

if kind not in MESSAGE_KIND_TO_CLASS:
# TODO use typer error output formatting
print(
f"OkPy message kind {kind} in backup_id {backup_id} unrecognized, skipping"
)
Expand Down
5 changes: 2 additions & 3 deletions src/notebooks/cs_61a_fa25_ants_study.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -236,21 +236,20 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": null,
"id": "3515e182",
"metadata": {},
"outputs": [],
"source": [
"print_debug_data = {\n",
" # TODO find out why there is a path that is None\n",
" \"backup_id\": [row[0] for row in file_paths if row[3]],\n",
" \"student_email\": [row[1] for row in file_paths if row[3]],\n",
" \"created\": [row[2] for row in file_paths if row[3]],\n",
" \"num_occurrences_print\": [],\n",
"}\n",
"\n",
"for path in [row[3] for row in file_paths]:\n",
" if path: # TODO find out why there is a path that is None\n",
" if path:\n",
" print_debug_data[\"num_occurrences_print\"].append(\n",
" count_search_string_in_file(path, \"print\")\n",
" )"
Expand Down
5 changes: 2 additions & 3 deletions src/notebooks/data_c88c_fa25_ants_study.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -835,21 +835,20 @@
},
{
"cell_type": "code",
"execution_count": 14,
"execution_count": null,
"id": "3515e182",
"metadata": {},
"outputs": [],
"source": [
"print_debug_data = {\n",
" # TODO find out why there is a path that is None\n",
" \"backup_id\": [row[0] for row in file_paths if row[3]],\n",
" \"student_email\": [row[1] for row in file_paths if row[3]],\n",
" \"created\": [row[2] for row in file_paths if row[3]],\n",
" \"num_occurrences_print\": [],\n",
"}\n",
"\n",
"for path in [row[3] for row in file_paths]:\n",
" if path: # TODO find out why there is a path that is None\n",
" if path:\n",
" print_debug_data[\"num_occurrences_print\"].append(\n",
" count_search_string_in_file(path, \"print\")\n",
" )"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ def show
return
end

# TODO error if student doesn't have any backups for this assignment and course

assignment_file_names = AssignmentFile.where(assignment_id: assignment_id).map { |af| af.file_name }
backup_metadata = BackupMetadatum.where(course: course.okpy_endpoint, assignment: assignment.okpy_endpoint, student_email: student.email).order(:created)
file_contents_locations = backup_metadata.filter_map do |backup|
Expand Down
4 changes: 0 additions & 4 deletions src/snapshots-app/app/controllers/api/backups_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# TODO update tests

class Api::BackupsController < ApplicationController
def show
course_id = params[:course_id].to_i
Expand All @@ -24,8 +22,6 @@ def show
return
end

# TODO error if student doesn't have any backups for this assignment and course

assignment_file_names = AssignmentFile.where(assignment_id: assignment_id).map { |af| af.file_name }
assignment_problem_names = AssignmentProblem.where(assignment_id: assignment_id).map { |ap| ap.display_name }
backup_metadata = BackupMetadatum.where(course: course.okpy_endpoint, assignment: assignment.okpy_endpoint, student_email: student.email).order(:created)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# TODO unit tests
class Api::Debugging::AutograderSpamController < ApplicationController
def show
# Validate params
Expand Down Expand Up @@ -29,8 +28,6 @@ def show
return
end

# TODO error if student doesn't have any backups for this assignment and course

backups = BackupMetadatum.where(
course: course.okpy_endpoint,
assignment: assignment.okpy_endpoint,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# TODO unit tests
class Api::Debugging::PrintStatementsController < ApplicationController
CACHE_TTL = 1.hour

# TODO: don't hardcode this
IGNORE_LINES = [
"print('All bees are vanquished. You win!')",
"print('The bees reached homebase or the queen ant queen has perished. Please try again :(')",
Expand All @@ -12,7 +10,6 @@ class Api::Debugging::PrintStatementsController < ApplicationController
# Regex for Python print statements: print(...)
PRINT_REGEX = /^\s*print\s*\(.*\)/

# TODO deduplicate from FilesController
def fetch_file_from_local(object_key)
file_path = Rails.root.join("../../data/private/#{object_key}")
if File.exist?(file_path)
Expand Down Expand Up @@ -65,8 +62,6 @@ def show
return
end

# TODO error if student doesn't have any backups for this assignment and course

backups = BackupMetadatum.where(
course: course.okpy_endpoint,
assignment: assignment.okpy_endpoint,
Expand Down Expand Up @@ -95,14 +90,12 @@ def show
problem: problem_names.join(", "),
timestamp: backup.created,
passing: is_passing,
# TODO don't hardcode this (other assignments may have multiple files)
files: [ { name: "ants.py", contents: contents, hasPrint: has_print } ],
has_print: has_print # internal flag for grouping
}
end

# Identify the indices of backups that contain prints
# TODO investigate why problem name can be empty. perhaps they just ran `python3 ok` without specifying a problem?
print_indices = all_data.each_index.select { |i| all_data[i][:has_print] and all_data[i][:problem] != "" }

return render json: [] if print_indices.empty?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ def show
return
end

# TODO error if student doesn't have any backups for this assignment and course

calendar_data = BackupMetadatum
.where(
course: course.okpy_endpoint,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
require "active_support/time"

# TODO unit tests
class Api::ProblemTimelineController < ApplicationController
def show
# Validate params
Expand All @@ -26,8 +25,6 @@ def show
return
end

# TODO error if student doesn't have any backups for this assignment and course

problem_name_to_index = AssignmentProblem.where(assignment_id: assignment.id)
.pluck(:display_name, :problem_index)
.to_h
Expand All @@ -50,15 +47,13 @@ def show

SESSION_TIME_GAP_THRESHOLD = 15.minutes

# TODO move this logic into frontend since it's about styling
# color blind color palette from https://davidmathlogic.com/colorblind/#%23D81B60-%231E88E5-%23FFC107-%23004D40
PINK = "#D81B60"
BLUE = "#1E88E5"
YELLOW = "#FFC107"
DARK_GREEN = "#004D40"

def get_grading_backup_status(grading_message_question)
# TODO separate label into backup type (unlock vs. correctness) and status (passed boolean), then format label in frontend
if grading_message_question.failed == 0
{ label: "Correctness Tests Passed", color: DARK_GREEN }
else
Expand Down Expand Up @@ -93,8 +88,6 @@ def process_backups(backups, problem_name_to_index)
backup_problem_names = backup.analytics_message.question_display_names
umc_grouped_by_problem_name = backup_problem_names.map { |name| [ name, [] ] }.to_h
backup.unlock_message_cases.each do |umc|
# TODO dangerously (?) assume that unlock message cases
# will always match exactly one of the backup problem names
backup_problem_names.each do |name|
if umc.case_id.start_with?(name)
umc_grouped_by_problem_name[name] << umc
Expand Down Expand Up @@ -124,7 +117,6 @@ def get_sessions(processed_backups)
# 3. Consecutive timestamps are <= SESSION_TIME_GAP_THRESHOLD

result = []
# TODO only convert to camel case at the end for consistency. generally fix naming conventions in all files...
curr_session =
{
startTime: processed_backups[0][:timestamp],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# TODO unit tests

# TODO don't hardcode this
# based on DATA C88C FA25 Ants
# SCORING = {
# "Problem 0" => 0,
Expand All @@ -11,7 +8,7 @@
# "Problem 5" => 6,
# "Problem 6" => 2,
# "Problem 7" => 6,
# "Problem 8" => 6, # TODO combined??
# "Problem 8" => 6, # combined point values of 8a, 8b, 8c
# "Problem 8a" => 2,
# "Problem 8b" => 2,
# "Problem 8c" => 2,
Expand All @@ -32,7 +29,7 @@
"Problem 5" => 3,
"Problem 6" => 1,
"Problem 7" => 3,
"Problem 8" => 3, # TODO combined??
"Problem 8" => 3, # combined point values of 8a, 8b, 8c
"Problem 8a" => 1,
"Problem 8b" => 1,
"Problem 8c" => 1,
Expand Down Expand Up @@ -86,7 +83,6 @@ def get_score_distribution(course_endpoint, assignment_endpoint, course, student
{ "studentValue": student_score, "data": data }
end

# TODO make this more DRY (a lot of repeated code from previous method)
def get_problems_solved_distribution(course_endpoint, assignment_endpoint, student_email)
latest_analytics = get_latest_analytics(course_endpoint, assignment_endpoint)

Expand Down Expand Up @@ -190,26 +186,18 @@ def get_active_time_spent_distribution(course_endpoint, assignment_endpoint, stu

# Total lint errors across all files for the student's latest backup
def get_lint_errors_distribution(course_endpoint, assignment_endpoint, student_email)
# lint_counts = BackupMetadatum
# .where(course: course_endpoint, assignment: assignment_endpoint)
# .group(:student_email)
# .having("created = MAX(created)")
# # TODO don't hardcode ants.py
# .joins("INNER JOIN lint_errors ON lint_errors.file_contents_location = CONCAT(backup_metadata.file_contents_location, '/ants.py')")
# .select("student_email, COUNT(lint_errors.id) as error_count")

# Subquery to rank backups for each student by date
subquery = BackupMetadatum
.where(course: course_endpoint, assignment: assignment_endpoint)
.select("*, ROW_NUMBER() OVER (PARTITION BY student_email ORDER BY created DESC) as rank")

# Wrap that subquery and join the lint errors
lint_counts = BackupMetadatum
.from("(#{subquery.to_sql}) AS backup_metadata")
.where("backup_metadata.rank = 1")
.joins("INNER JOIN lint_errors ON lint_errors.file_contents_location = backup_metadata.file_contents_location || '/ants.py'")
.group(:student_email)
.select("student_email, COUNT(lint_errors.id) as error_count")
# Subquery to rank backups for each student by date
subquery = BackupMetadatum
.where(course: course_endpoint, assignment: assignment_endpoint)
.select("*, ROW_NUMBER() OVER (PARTITION BY student_email ORDER BY created DESC) as rank")

# Wrap that subquery and join the lint errors
lint_counts = BackupMetadatum
.from("(#{subquery.to_sql}) AS backup_metadata")
.where("backup_metadata.rank = 1")
.joins("INNER JOIN lint_errors ON lint_errors.file_contents_location = backup_metadata.file_contents_location || '/ants.py'")
.group(:student_email)
.select("student_email, COUNT(lint_errors.id) as error_count")

student_lint_errors = 0
data = [ [ "Student Email", "Lint Errors" ] ]
Expand All @@ -223,8 +211,6 @@ def get_lint_errors_distribution(course_endpoint, assignment_endpoint, student_e
end
end

# TODO Handle case where students have 0 lint errors (they won't appear in the INNER JOIN)

{
"studentValue": student_lint_errors,
"data": data
Expand Down Expand Up @@ -255,8 +241,6 @@ def show
return
end

# TODO error if student doesn't have any backups for this assignment and course

render json: {
"course_id": course_id,
"assignment_id": assignment_id,
Expand Down
1 change: 0 additions & 1 deletion src/snapshots-app/app/views/assignments/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
<%# TODO: pass props to components like courseId, assignmentId, submissionId %>
<%= react_component("Assignment", prerender: false) %>
3 changes: 1 addition & 2 deletions src/snapshots-app/app/views/login/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
<%= react_component("App", prerender: false) %>
<%# TODO: changing component to Login works but manually editing URL breaks it %>
<%= react_component("App", prerender: false) %>
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ function Footer() {
Copyright &copy; {new Date().getFullYear()} Regents of the University of
California and respective authors.
</span>
{/* TODO why does this go off to page to the right? */}
<span style={{ flex: 1, textAlign: "right" }}>
This app is a{" "}
<Link href="https://github.com/berkeley-cdss">Seamless Learning</Link>{" "}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ const AutograderSpam = () => {
flex: 2,
valueGetter: (value, row) => new Date(row.startTimestamp),
sortComparator: (v1, v2) => v1 - v2,
// TODO fix popper being hidden by DataGrid on the far left side when hovering over the slider thumbs
renderCell: (params) => {
const getSliderValueText = (value) => {
if (value === params.row.startIndex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ function DebuggingTab({}) {
component: <PrintStatements />,
},
{ text: "Errors", icon: <Dangerous />, component: <Errors /> },
// TODO(stretch): implement these pages
// { text: 'Test Regressions', icon: <SyncProblem />, component: <TestRegressions /> },
// { text: 'Pseudocode Detection', icon: <Lightbulb />, component: <PseudocodeDetection /> },
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ const PrintStatements = () => {
justifyContent: "center",
}}
>
{/* TODO investigate bug where backend doesn't have has_print true correctly?? */}
{selectedFileName &&
item.files.find((f) => f.name === selectedFileName)
?.hasPrint && (
Expand Down Expand Up @@ -289,7 +288,6 @@ const PrintStatements = () => {
enabled: true,
contextLineCount: 5, // Lines of unchanged code to show around a diff
minimumLineCount: 3, // Minimum unchanged lines required to trigger a collapse
// TODO this isn't working properly
revealLineCount: 20, // How many lines to reveal when clicking the "expand" button
},
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import Editor, { useMonaco } from "@monaco-editor/react";

import "./FileViewer.css";

// TODO deduplicate with FileViewer in submission folder
function FileViewer({ editorRef, code, language, lightMode, lintErrors }) {
const monaco = useMonaco();
const [editorMounted, setEditorMounted] = React.useState(false);
Expand Down Expand Up @@ -96,7 +95,6 @@ function FileViewer({ editorRef, code, language, lightMode, lintErrors }) {

return (
<>
{/* TODO fix alignment and scroll */}
<div
style={{
display: "flex",
Expand Down
Loading
Loading