Dieser Artikel ist der 9. Tagesartikel von DSL Adventskalender 2019. In Fortsetzung des Artikels am 8. Tag werden wir über die Vorlesung "Einführung in die Programmierung" an unserer Universität sprechen.
Ich mache TA in dieser Vorlesung, aber kurz gesagt, es gibt Hausaufgaben, wie zum Beispiel, dass Studenten wöchentliche Aufgaben erhalten und bis zur Vorlesung der nächsten Woche fertig sind. Der TA hat die Aufgabe, die Aufgabe jede Woche zu bewerten. Am Anfang ist der Inhalt der Aufgabe mit nur einem einfachen Programm einfach, aber mit zunehmender Häufigkeit werden Inhalt und Vergleich mit der Ausgabe komplizierter. Deshalb habe ich ein Bewertungssystem erstellt, das auf Python ausgeführt wird.
"** Lass Python die langweiligen Dinge machen **".
Aufgaben können mit einem Jupyter-Notizbuch beantwortet werden. Es wird im IPynb-Format verteilt und enthält Zellen für Fragen und Antworten, sodass Sie den Code dort schreiben und prüfen können, ob die Ausgabe korrekt ist. Grundsätzlich werden Sie aufgefordert, nur den Inhalt der Codezelle zu bearbeiten und das Ergebnis zu überprüfen, sodass Sie immer Punkte erhalten können, indem Sie nur die Ausgabe einer bestimmten Zelle überprüfen.
Unten sehen Sie ein Bild, das die Aufgabe einfach reproduziert, sodass Sie ein Bild haben können.
Ich habe das Problem sehr einfach gemacht, aber es sieht so aus.
Zunächst zu den Bewertungskriterien. Es wird sich je nach Aufgabe und Problem ändern, aber die folgenden drei sind die groben Kriterien.
Das erste und das zweite Kriterium bleiben gleich, aber die dritte "angegebene Grammatik und Syntax" ist das "Für" und "Wenn", das Sie in dieser Woche gelernt haben. (Die Struktur des Programms wird nicht jedes Mal angegeben.)
Die Antworten auf die Aufgaben und Bewertungskriterien werden vorab an TA verteilt. Ungefähr 20 Personen haben ipynb für jeden TA beantwortet, es auf dem Jupyter-Notizbuch geöffnet, jeden Quellcode überprüft, das Ergebnis ausgegeben und erneut ausgeführt und das Bewertungsergebnis in die Bewertungsspalte geschrieben. Derzeit beträgt die maximale Punktzahl 4, und Sie können jeweils 4 Punkte überprüfen, aber ich konnte diese Arbeit nicht ausführen, also habe ich ein Skript erstellt. (Da das System eines bestimmten II kein Labor, sondern ein Notizbuch ist, war es schwierig, viele Registerkarten zu öffnen, auf die Kommunikation zu warten und die Zelle neu zu bewerten.)
Hier ist was zu tun ist
Ich werde jeden von ihnen mit dem Quellcode erklären.
Verwenden Sie pathlib, ein Standard-Python-Modul.
import pathlib
# path to notebook(.ipynb)
p_nb = pathlib.Path("../path/to/notebook/")
Da der Inhalt von ipynb json ist, können Sie ihn mit json.load () analysieren. Es wird auch die glob-Methode verwendet, die pathlib gut handhabt, wenn alle ipynb durchlaufen werden.
import json
# notebooks(.ipynb)
for _nb in p_nb.glob("*.ipynb"):
# load json (*.ipynb)
with open(_nb, "r")as f:
nb = json.load(f)
cells = nb["cells"]
Ich werde die detaillierte Erklärung der Struktur von ipynb weglassen, aber da die Zellinformation wie folgt lautet: {"Zelle": [Zelle1, Zelle2, Zelle3], ...} "," nb ["Zellen"] Sie können die Liste mit `erhalten.
Bitte beachten Sie, dass sich der Quellcode danach in einem Zustand befindet, in dem der Einzug um einen Schritt verringert wird, aber weggelassen wird.
Der Inhalt der Zelle ist ungefähr wie folgt.
--cell_type: 'markdown', 'code' usw. --source: Markdown-Text, Quellcode usw. (zeilenweise Liste) --outputs: Ergebnisse der Quellcode-Ausgabe (einschließlich Fehler)
Andere Informationen sind enthalten, aber die obigen drei werden in diesem System verwendet.
Geben Sie nun die Zelle für die Antwort an. ** Diesmal ist der Quellcode so geschrieben, dass er mit dem oben als Beispiel angegebenen ipynb vergleichbar ist. ** ** ** Da es in einer Wertung bis zu viermal verwendet wird, ist es funktionalisiert.
def identify_cell(sentence, cells, cell_type='markdown'):
"""Gibt die Anzahl der Zellen zurück, die den Bedingungen aller Zellen entsprechen"""
for i,_cell in enumerate(cells):
if _cell['cell_type'] == cell_type \
and _cell['source'][0] == sentence:
_cell_num = i
break
return _cell_num
# identify cell
_cn = identify_cell(sentence="##Frage 1\n",
cells=cells)
ans_cell = cells[_cn + 1]
Was von identity_cell ()
überprüft wird, ist
Der Zelltyp ist Markdown und die erste Zeile der Quelle lautet "## Q1 \ n".
Die Zellennummer, die den obigen Bedingungen entspricht, wird zurückgegeben.
Von hier aus ist es gut, den Inhalt der Zelle zu überprüfen, während Sie "pprint ()" usw. verwenden.
Es ist zu beachten, dass die Antwort der Quellcode und das Ausgabeergebnis ist, sodass die nächste Zelle, die "_cn + 1" -te Zelle, in der Variablen als Antwortzelle gespeichert wird.
Geben Sie die erste Frage "Hallo Welt!" Aus. Lassen Sie uns die Richtigkeit des Problems überprüfen. Dieses Mal müssen Sie nur überprüfen, ob das Ausgabeergebnis korrekt ist.
try:
result = ans_cell['outputs'][0]["text"][0]
if result == "Hello World!":
score += 1
except:
pass
Try-Except wird übrigens verwendet, weil es dem Fall entspricht, in dem die Aufgabe unbeantwortet bleibt. (Es gibt keinen Inhalt in den Ausgaben) Es war in Ordnung, damit umzugehen, wenn, aber als ich viele Antworten sah, wurden Fehler an verschiedenen Stellen geworfen, also habe ich dies kompromittiert.
Im aktuellen Quellcode, der tatsächlich in Betrieb ist, wird lediglich der Pfad und dieser Teil jede Woche geändert. Antwortmuster und Notizen werden am Ende des Artikels separat aufgeführt.
Ursprünglich ist es in Ordnung, etwas anderes als die perfekte Punktzahl zu schreiben, aber nur für den Fall, dass die Antwort ipynb überprüft wird und ein falsches Problem vorliegt, wird ein separater Kommentar abgegeben, sodass die Spezifikationen so sind, wie sie jetzt sind.
if score == 2: #Perfektes Ergebnis=Bei 2 Punkten
# identify cell
_cn = identify_cell(sentence="##Auswertung\n",
cells=cells)
#Score-Zelle überschreiben
cells[_cn + 1] = {'cell_type': 'code',
'execution_count': None,
'metadata': {},
'outputs': [],
'source': [str(2)]}
#Zur Antwort an ipynb senden(Überschreiben)
json.dump(nb, _nb.open("w"))
Dies wurde von einer Person bereitgestellt, die auch TA in unserem Labor durchführt (@y_k).
Was den Inhalt des Programms betrifft, so wird nur dann, wenn die Punktzahl perfekt ist, die Zelle, in die das Bewertungsergebnis eingegeben wird, mit der Anzahl der perfekten Punkte überschrieben und ipynb gespeichert. Wenn Sie jedoch das falsche überschreiben, ist dies problematisch. In der Produktionsumgebung verfügen wir daher auch über ein Skript zum Sichern des ursprünglichen ipynb.
Hier sind einige Teile, die Sie bei der Überprüfung der Antwort beachten sollten. Zusätzlich zu den aufgelisteten werfen Sie als Anfänger in der Programmierung verschiedene wechselnde Bälle, so dass es ziemlich schwierig ist.
Selbst wenn dies alleine so ist, ist der Inhalt der "Ausgaben" unterschiedlich, so dass sich das Programm erheblich ändert, was ziemlich schwierig ist.
Dies ist auch ziemlich schwierig, und wenn es etwas gibt, das in den Bewertungskriterien neu bewertet werden muss Ich benutze "exec (script)" (script ist der Quellcode von str), um das Ergebnis zu überprüfen, aber "print ()" im Skript wird nicht auf dem Jupyter-Notizbuch angezeigt, und es ist ziemlich schwierig, die Ausgabe zu erhalten. Ich habe ein Programm geschrieben, das die Standardausgabe überschreibt, aber ich kann es nicht sehr empfehlen (da print () zur normalen Zeit ebenfalls nicht angezeigt wird). Ich werde den Quellcode vorerst veröffentlichen.
import sys
import io
import contextlib
@contextlib.contextmanager
def stdoutIO(stdout=None):
old = sys.stdout
if stdout is None:
stdout = io.StringIO()
sys.stdout = stdout
yield stdout
sys.stdout = old
#Lauf
try:
with stdoutIO() as s:
exec(script)
#Drucken Sie unten()Holen Sie sich die Ausgabe von
output = s.getvalue().split()
except:
#Im Falle eines Skriptfehlers außer
pass
Wenn die Antwort ein Symbol oder eine Zahl in voller Breite enthält, stimmt diese nicht mit der richtigen Antwort überein und wird falsch behandelt. Daher ist es etwas einfacher, wenn Sie das Ausgabeergebnis im Voraus in die halbe Breite konvertieren.
def trans_hankaku(sentence: str) -> str:
"""Funktion zum Konvertieren von Zeichen voller Breite in Zeichen halber Breite"""
return sentence.translate(
str.maketrans(
{chr(0xFF01 + i): chr(0x21 + i) for i in range(94)}
))
Es kann einfacher sein, eine Funktion zu definieren, die wie oben beschrieben in halbe Breite konvertiert wird.
Dieses Mal konnte ich üben "Lass Python die langweiligen Dinge machen"! (Ich habe noch nie gelesen) Ich hoffe, dass der heutige Artikel sowohl jemandem als auch dem gestrigen Artikel [DSL Adventskalender Tag 8] hilft (https://qiita.com/liseos_x140/items/d25362a115573a5c2022).
Der diesmal verwendete Quellcode und ipynb sind hier. https://github.com/liseos-x140/scoring_ipynb
Die Struktur des generierten ipynb kann je nach Version und Typ des Jupyters unterschiedlich sein. Ich wäre Ihnen dankbar, wenn Sie es nur als Referenz verwenden könnten. Außerdem befindet sich der Quellcode noch in der Entwicklungsphase, daher hoffe ich, ihn erneut zu aktualisieren, sobald er zu einem gewissen Grad organisiert ist.
https://www.oreilly.co.jp/books/9784873117782/
Recommended Posts