cornellGrading 2.21.0__tar.gz → 2.22.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cornellgrading-2.21.0/cornellGrading.egg-info → cornellgrading-2.22.0}/PKG-INFO +1 -1
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading/__init__.py +1 -1
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading/cornellGrading.py +38 -12
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading/cornellQualtrics.py +74 -1
- {cornellgrading-2.21.0 → cornellgrading-2.22.0/cornellGrading.egg-info}/PKG-INFO +1 -1
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/LICENSE +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/MANIFEST.in +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/README.md +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading/cornellInterface.py +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading/dueDatesFromCSV.py +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading/pandocHTMLParser.py +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading/upload_MC_questions.py +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading/utils.py +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading.egg-info/SOURCES.txt +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading.egg-info/dependency_links.txt +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading.egg-info/entry_points.txt +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading.egg-info/requires.txt +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading.egg-info/top_level.txt +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/pyproject.toml +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/scripts/canvastex.py +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/scripts/matlabgrader.py +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/scripts/setupSelfGrading.py +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/setup.cfg +0 -0
- {cornellgrading-2.21.0 → cornellgrading-2.22.0}/setup.py +0 -0
|
@@ -2426,7 +2426,7 @@ class cornellGrading:
|
|
|
2426
2426
|
return q
|
|
2427
2427
|
|
|
2428
2428
|
def genNewQuizMultipleChoice(
|
|
2429
|
-
self, question, options, correct_ind, points=1, position=0
|
|
2429
|
+
self, question, options, correct_ind, points=1, position=0, fightml=None
|
|
2430
2430
|
):
|
|
2431
2431
|
"""Generate a new quiz-style multiple choice question dictionary
|
|
2432
2432
|
|
|
@@ -2441,6 +2441,8 @@ class cornellGrading:
|
|
|
2441
2441
|
Number of points for correct answer (defaults to 1).
|
|
2442
2442
|
position (int):
|
|
2443
2443
|
Position of question in quiz. Defaults to 0
|
|
2444
|
+
fightml (str, optional):
|
|
2445
|
+
HTML string from figure upload. Defaults to None.
|
|
2444
2446
|
|
|
2445
2447
|
Returns:
|
|
2446
2448
|
dict:
|
|
@@ -2462,6 +2464,10 @@ class cornellGrading:
|
|
|
2462
2464
|
}
|
|
2463
2465
|
)
|
|
2464
2466
|
|
|
2467
|
+
qtxt = f"<p>{convalllatex(question)}</p>"
|
|
2468
|
+
if fightml is not None:
|
|
2469
|
+
qtxt = f"{qtxt}\n<p>{fightml}</p>"
|
|
2470
|
+
|
|
2465
2471
|
q = {
|
|
2466
2472
|
"position": position,
|
|
2467
2473
|
"points_possible": float(points),
|
|
@@ -2472,7 +2478,7 @@ class cornellGrading:
|
|
|
2472
2478
|
"status": "mutable",
|
|
2473
2479
|
"entry": {
|
|
2474
2480
|
"title": question,
|
|
2475
|
-
"item_body":
|
|
2481
|
+
"item_body": qtxt,
|
|
2476
2482
|
"calculator_type": "none",
|
|
2477
2483
|
"interaction_data": {"choices": choices},
|
|
2478
2484
|
"properties": {
|
|
@@ -2604,27 +2610,34 @@ class cornellGrading:
|
|
|
2604
2610
|
# process figure (if any)
|
|
2605
2611
|
if not (pandas.isna(row.Figure)):
|
|
2606
2612
|
impath = os.path.join(imagePath, f"{row.Figure}.png")
|
|
2607
|
-
|
|
2608
|
-
status, fig = figFolder.upload(impath)
|
|
2609
|
-
assert status, f"Failed to upload {impath}."
|
|
2613
|
+
fightml = self.uploadFigure(impath, figFolder)
|
|
2610
2614
|
else:
|
|
2611
|
-
|
|
2615
|
+
fightml = None
|
|
2612
2616
|
|
|
2613
2617
|
# create and add the question depending on quiz type
|
|
2614
2618
|
if isinstance(quiz, canvasapi.new_quiz.NewQuiz):
|
|
2615
2619
|
q = self.genNewQuizMultipleChoice(
|
|
2616
|
-
question,
|
|
2620
|
+
question,
|
|
2621
|
+
opts.astype(str),
|
|
2622
|
+
correct_ind,
|
|
2623
|
+
position=k + 1,
|
|
2624
|
+
fightml=fightml,
|
|
2617
2625
|
)
|
|
2618
2626
|
|
|
2619
2627
|
self.addNewQuizItem(quiz.id, q)
|
|
2620
2628
|
else:
|
|
2621
2629
|
q = self.genQuizMultipleChoice(
|
|
2622
|
-
question,
|
|
2630
|
+
question,
|
|
2631
|
+
opts.astype(str),
|
|
2632
|
+
correct_ind,
|
|
2633
|
+
position=k + 1,
|
|
2634
|
+
fightml=fightml,
|
|
2623
2635
|
)
|
|
2624
2636
|
quiz.create_question(question=q)
|
|
2625
2637
|
|
|
2626
2638
|
def uploadFigure(self, impath, figFolder):
|
|
2627
|
-
"""Upload a figure and generate an HTML string for embedding it
|
|
2639
|
+
"""Upload a figure and generate an HTML string for embedding it. If filename
|
|
2640
|
+
already exists in the folder, use that rather than overwriting.
|
|
2628
2641
|
|
|
2629
2642
|
Args:
|
|
2630
2643
|
impath (str):
|
|
@@ -2637,9 +2650,22 @@ class cornellGrading:
|
|
|
2637
2650
|
HTML string representing the figure
|
|
2638
2651
|
"""
|
|
2639
2652
|
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2653
|
+
filename = os.path.split(impath)[-1]
|
|
2654
|
+
haveFile = False
|
|
2655
|
+
for file in figFolder.get_files():
|
|
2656
|
+
if file.filename == filename:
|
|
2657
|
+
haveFile = True
|
|
2658
|
+
fig = {
|
|
2659
|
+
"id": file.id,
|
|
2660
|
+
"uuid": file.uuid,
|
|
2661
|
+
"display_name": file.display_name,
|
|
2662
|
+
}
|
|
2663
|
+
break
|
|
2664
|
+
|
|
2665
|
+
if not haveFile:
|
|
2666
|
+
assert os.path.exists(impath), f"Can not locate {impath}."
|
|
2667
|
+
status, fig = figFolder.upload(impath)
|
|
2668
|
+
assert status, f"Failed to upload {impath}."
|
|
2643
2669
|
|
|
2644
2670
|
figsrc = (
|
|
2645
2671
|
f"{self.canvas._Canvas__requester.original_url}/courses/"
|
|
@@ -690,6 +690,79 @@ class cornellQualtrics:
|
|
|
690
690
|
|
|
691
691
|
return response.json()["result"]
|
|
692
692
|
|
|
693
|
+
def exportUploadedFiles(self, surveyId, DataExportTags, saveDir=None):
|
|
694
|
+
"""Download all user uploaded files associated with specific questions from one
|
|
695
|
+
survey
|
|
696
|
+
|
|
697
|
+
Args:
|
|
698
|
+
surveyId (str):
|
|
699
|
+
Unique id string of survey. Get either from web interface or via
|
|
700
|
+
getSurveyId
|
|
701
|
+
DataExportTags (list):
|
|
702
|
+
Data Export Tags for all questions with uploaded files
|
|
703
|
+
saveDir (str, optional):
|
|
704
|
+
Full path to save location. If None (default) uses system tmp dir
|
|
705
|
+
|
|
706
|
+
Returns:
|
|
707
|
+
str:
|
|
708
|
+
Full path to directory where the survey results and all files are saved.
|
|
709
|
+
The survey results will be a CSV file with a filename that is the same
|
|
710
|
+
as the survey name, except with any colons replaced with underscores.
|
|
711
|
+
The files will be named as: ResponseId-FileId-fileName where ResponseId
|
|
712
|
+
and FileId match the entries in the survey results and fileName is the
|
|
713
|
+
original fileName of the upload.
|
|
714
|
+
|
|
715
|
+
Notes:
|
|
716
|
+
https://api.qualtrics.com/1071635f5a615-retrieve-a-user-uploaded-file
|
|
717
|
+
|
|
718
|
+
"""
|
|
719
|
+
|
|
720
|
+
# get survey name from ID
|
|
721
|
+
if surveyId not in self.surveyIds:
|
|
722
|
+
self.listSurveys()
|
|
723
|
+
assert surveyId in self.surveyIds, f"Survey ID {surveyId} not found."
|
|
724
|
+
|
|
725
|
+
surveyname = self.surveyNames[self.surveyIds == surveyId][0]
|
|
726
|
+
|
|
727
|
+
# synthesize base URL
|
|
728
|
+
baseUrl = (
|
|
729
|
+
f"https://{self.dataCenter}{self.qualtricsapi}surveys/{surveyId}/responses/"
|
|
730
|
+
)
|
|
731
|
+
|
|
732
|
+
# export survey results and read output
|
|
733
|
+
tmpdir = self.exportSurvey(surveyId, saveDir=saveDir)
|
|
734
|
+
if ":" in surveyname:
|
|
735
|
+
surveyname = surveyname.replace(":", "_")
|
|
736
|
+
surveyfile = os.path.join(tmpdir, surveyname + ".csv")
|
|
737
|
+
assert os.path.isfile(surveyfile), "Survey results not where expected."
|
|
738
|
+
surveyres = pandas.read_csv(surveyfile, header=[0, 1, 2])
|
|
739
|
+
|
|
740
|
+
# get all response IDs
|
|
741
|
+
responseIds = surveyres["ResponseId"].values.flatten()
|
|
742
|
+
|
|
743
|
+
# loop through each data export tag and download the associated file for each
|
|
744
|
+
# response
|
|
745
|
+
for DataExportTag in DataExportTags:
|
|
746
|
+
# get all ids and filenames for current tag
|
|
747
|
+
fids = surveyres[f"{DataExportTag}_Id"].values.flatten()
|
|
748
|
+
fnames = surveyres[f"{DataExportTag}_Name"].values.flatten()
|
|
749
|
+
|
|
750
|
+
# loop through everything
|
|
751
|
+
for rid, fid, fname in zip(responseIds, fids, fnames):
|
|
752
|
+
durl = f"{baseUrl}{rid}/uploaded-files/{fid}"
|
|
753
|
+
requestDownload = requests.request(
|
|
754
|
+
"GET", durl, headers=self.headers_post, stream=True
|
|
755
|
+
)
|
|
756
|
+
assert (
|
|
757
|
+
requestDownload.status_code == 200
|
|
758
|
+
), f"Download failed for file {fid} on response {rid}."
|
|
759
|
+
|
|
760
|
+
outname = os.path.join(tmpdir, f"{rid}-{fid}-{fname}")
|
|
761
|
+
with open(outname, "wb") as ff:
|
|
762
|
+
ff.write(requestDownload.content)
|
|
763
|
+
|
|
764
|
+
return tmpdir
|
|
765
|
+
|
|
693
766
|
def exportSurvey(self, surveyId, fileFormat="csv", useLabels="true", saveDir=None):
|
|
694
767
|
"""Download and extract survey results
|
|
695
768
|
|
|
@@ -701,7 +774,7 @@ class cornellQualtrics:
|
|
|
701
774
|
Format to download (must be csv, tsv, or spss)
|
|
702
775
|
useLabels (str):
|
|
703
776
|
Use choice labels ("true" or "false", defaults "true")
|
|
704
|
-
saveDir (str):
|
|
777
|
+
saveDir (str, optional):
|
|
705
778
|
Full path to save location. If None (default) uses system tmp dir
|
|
706
779
|
|
|
707
780
|
Returns:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cornellgrading-2.21.0 → cornellgrading-2.22.0}/cornellGrading.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|