Système de notation IPynb réalisé avec TA d'introduction à la programmation (Python)

Cet article est l'article du 9ème jour du DSL Advent Calendar 2019. Dans la continuité de l'article du 8ème jour, nous parlerons de la conférence "Introduction à la programmation" dans notre université.

Je fais de l'AT dans cette conférence, mais en bref, il y a des devoirs, comme des devoirs hebdomadaires aux étudiants et la fin de la conférence de la semaine prochaine. Les assistants techniques sont chargés de noter le devoir chaque semaine. Au début, le contenu de la tâche est simple avec seulement un programme simple, mais à mesure que le nombre de fois augmente, le contenu et la comparaison avec la sortie deviennent plus compliqués, j'ai donc créé un système de notation qui fonctionne sur Python.

"** Laissez Python faire les choses ennuyeuses **".

Tâche

Il est possible de répondre aux affectations avec jupyter notebook. Il est distribué au format .ipynb et contient des cellules pour les questions et réponses, vous pouvez donc y écrire le code et vérifier si le résultat est correct. Fondamentalement, il vous dit de ne modifier que le contenu de la cellule de code et de vérifier le résultat, afin que vous puissiez toujours obtenir des points simplement en vérifiant la sortie d'une cellule spécifique.

Vous trouverez ci-dessous une image qui reproduit facilement la tâche afin que vous puissiez avoir une image.

スクリーンショット 2019-12-09 16.56.18.png

J'ai rendu le problème très simple, mais il ressemble à ceci.

À propos de la notation

Critères de notation

Tout d'abord, sur les critères de notation. Cela changera en fonction de chaque tâche et problème, mais il y a trois critères généraux ci-dessous.

  1. Le programme ne provoque pas d'erreur
  2. Le résultat de sortie est correct
  3. La grammaire ou la syntaxe spécifiée est utilisée

Les premier et deuxième critères restent les mêmes, mais le troisième "grammaire et syntaxe spécifiées" est le "pour" et le "si" que vous avez appris cette semaine. (La structure du programme n'est pas spécifiée à chaque fois)

Méthode de notation

Les réponses aux affectations et aux critères de notation seront distribuées à l'AT à l'avance. Environ 20 personnes ont répondu à ipynb pour chaque TA, l'ouvrent sur le notebook Jupyter, vérifient chaque code source, sortent le résultat et la réexécution, et écrivent le résultat de la notation dans la colonne d'évaluation. Actuellement, le score maximum est de 4, et vous pouvez en vérifier environ 4 pour chacun, mais je n'ai pas pu faire ce travail, j'ai donc créé un script. (Parce que le système d'un certain II n'est pas un laboratoire mais un cahier, il était difficile d'ouvrir beaucoup d'onglets, d'attendre la communication et de réévaluer la cellule)

Système de notation

Voici quoi faire

  1. Liste ipynb pour tout le monde
  2. analyser ipynb
  3. Identifiez la cellule de réponse
  4. Comparez le code source et la sortie avec une réponse correcte avec l'expression régulière re et l'évaluation ʻexec ()`
  5. Si le score est parfait, écrivez le score dans ipynb

Je vais expliquer chacun d'eux avec le code source.

Liste ipynb pour tout le monde

Utilisez pathlib, un module Python standard.

import pathlib

# path to notebook(.ipynb)
p_nb = pathlib.Path("../path/to/notebook/")

analyser ipynb

Puisque le contenu d'ipynb est json, vous pouvez l'analyser avec json.load (). Il utilise également la méthode glob, qui gère bien pathlib lors de la boucle sur tout ipynb.

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"]

Je vais omettre l'explication détaillée de la structure d'ipynb, mais puisque les informations de cellule sont comme {" cellule ": [cellule1, cellule2, cellule3], ...}, nb [" cellules "] Vous pouvez obtenir la liste avec .

Veuillez noter que le code source après cela est dans un état où le retrait est abaissé d'une étape, mais il est omis.

Identifiez la cellule de réponse

Le contenu de la cellule est à peu près comme suit.

--cell_type: 'markdown', 'code', etc. --source: texte de démarque, code source, etc. (liste ligne par ligne) --outputs: résultats de sortie du code source (y compris les erreurs)

D'autres informations sont incluses, mais les trois ci-dessus sont utilisées dans ce système.

Maintenant, spécifiez la cellule de la réponse. ** Cette fois, le code source est écrit pour être comparable à l'ipynb donné ci-dessus à titre d'exemple. ** ** Puisqu'il est utilisé jusqu'à 4 fois en un seul scoring, il est fonctionnalisé.

def identify_cell(sentence, cells, cell_type='markdown'):
    """Renvoie les numéros de cellule qui correspondent aux conditions de toutes les cellules"""
    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="##question 1\n",
                    cells=cells)
ans_cell = cells[_cn + 1]

ʻIdentify_cell () `vérifie Le cell_type est markdown et la première ligne de la source est "## Q1 \ n". Le numéro de cellule qui correspond aux conditions ci-dessus est renvoyé par retour.

De là, il est bon de vérifier le contenu de la cellule en utilisant pprint () etc.

Il convient de noter que la réponse est le code source et son résultat de sortie, de sorte que la cellule suivante, la cellule _cn + 1th, est stockée dans la variable en tant que cellule de réponse.

Comparez le code source et la sortie avec la bonne réponse

Envoyez la première question "Hello World!". Vérifions l'exactitude du problème. Cette fois, il vous suffit de vérifier si le résultat de la sortie est correct, c'est donc comme suit.

try:
    result = ans_cell['outputs'][0]["text"][0]
    if result == "Hello World!":
        score += 1
except:
    pass

Au fait, try-except est utilisé car il correspond au cas où la tâche est sans réponse. (Il n'y a pas de contenu dans les sorties) C'était correct de le gérer si, mais quand j'ai vu de nombreuses réponses, des erreurs ont été lancées à divers endroits, alors j'ai fait un compromis avec cela.

Dans le code source actuel qui est réellement en fonctionnement, cela fonctionne simplement en changeant le chemin et cette partie chaque semaine. Les modèles de réponse et les notes sont répertoriés séparément au bas de l'article.

Si le score est parfait, écrivez le score en ipynb

À l'origine, il est correct d'écrire autre chose que le score parfait, mais j'ai fait les spécifications telles qu'elles sont maintenant parce que j'ai fait un commentaire séparé pour ceux qui ont une mauvaise réponse vérifier la réponse ipynb juste au cas où.

if score == 2:  #Score parfait=En cas de 2 points
    # identify cell
    _cn = identify_cell(sentence="##Évaluation\n",
                        cells=cells)

    #Écraser la cellule de score
    cells[_cn + 1] = {'cell_type': 'code',
                      'execution_count': None,
                      'metadata': {},
                      'outputs': [],
                      'source': [str(2)]}

    #Dump sur ipynb pour réponse(Écraser)
    json.dump(nb, _nb.open("w"))

Cela a été fourni par une personne qui fait également de l'AT dans notre laboratoire (@y_k).

Quant au contenu du programme, seulement lorsque le score est parfait, la cellule où le résultat de l'évaluation est entré est écrasée par le numéro de score parfait, et ipynb est sauvegardé. Cependant, si vous écrasez le mauvais, ce sera gênant, donc dans l'environnement de production, nous avons également un script pour sauvegarder l'ipynb d'origine.

Remarques

Voici quelques éléments à garder à l'esprit lors de la vérification de la réponse. En plus de ceux listés, si vous êtes débutant en programmation, vous lancerez diverses balles à langer, donc c'est plutôt difficile.

Le modèle de sortie est différent entre la sortie avec print () et la sortie avec seulement des variables qui peuvent être utilisées avec ipython.

スクリーンショット 2019-12-09 17.50.24.png

Même avec cela seul, le contenu des "sorties" est différent, donc le programme changera considérablement, donc c'est assez difficile.

Lorsque vous devez évaluer un programme, vous ne pouvez pas facilement obtenir le résultat de sortie par ʻexec (script) `.

C'est également assez difficile, et quand il y a quelque chose qui doit être réévalué dans les critères d'évaluation J'utilise ʻexec (script) (script est le code source de str) pour vérifier le résultat, mais print () ʻin script n'est pas affiché sur le notebook jupyter, et il est assez difficile d'obtenir la sortie. J'ai écrit un programme qui écrase la sortie standard, mais je ne le recommande pas beaucoup (car print () à l'heure normale n'est pas non plus affiché). Je publierai le code source pour le moment.

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


#Courir
try:
    with stdoutIO() as s:
        exec(script)
    
    #Imprimer ci-dessous()Obtenez la sortie de
    output = s.getvalue().split()
except:
    #En cas d'erreur de script sauf
    pass

Problème de demi-largeur pleine largeur

S'il y a un symbole ou un nombre pleine largeur dans la réponse, il ne correspondra pas à la bonne réponse et sera traité de manière incorrecte. Par conséquent, ce sera un peu plus facile si vous convertissez le résultat de sortie en demi-largeur à l'avance.

def trans_hankaku(sentence: str) -> str:
    """Fonction pour convertir les caractères pleine largeur en caractères demi-largeur"""
    return sentence.translate(
        str.maketrans(
            {chr(0xFF01 + i): chr(0x21 + i) for i in range(94)}
        ))

Il peut être plus facile de définir une fonction qui se convertit en demi-largeur comme décrit ci-dessus.

Résumé

Cette fois, j'ai pu pratiquer "Laisser Python faire les choses ennuyeuses"! (Je n'ai jamais lu) J'espère que l'article d'aujourd'hui aidera quelqu'un ainsi que celui d'hier article DSL Advent Calendar Day 8.

Le code source et ipynb utilisés cette fois sont ici. https://github.com/liseos-x140/scoring_ipynb

Épilogue

La structure d'ipynb générée peut différer selon la version et le type de jupyter, je vous serais donc reconnaissant de bien vouloir l'utiliser comme référence uniquement. De plus, le code source est encore au stade de développement, j'espère donc le mettre à jour à nouveau dès qu'il sera organisé dans une certaine mesure.

référence

https://www.oreilly.co.jp/books/9784873117782/

Recommended Posts

Système de notation IPynb réalisé avec TA d'introduction à la programmation (Python)
Introduction à la programmation (Python) TA Tendency pour les débutants
[Chapitre 5] Introduction à Python avec 100 coups de traitement du langage
[Chapitre 3] Introduction à Python avec 100 coups de traitement du langage
[Chapitre 2] Introduction à Python avec 100 coups de traitement du langage
Une introduction à la programmation Python
[Chapitre 4] Introduction à Python avec 100 coups de traitement du langage
Introduction à elle faite avec Python ~ Projet d'automatisation Tinder ~ Épisode 6
Introduction à elle faite avec Python ~ Projet d'automatisation Tinder ~ Épisode 5
[Raspi4; Introduction au son] Enregistrement stable de l'entrée sonore avec python ♪
[Introduction à Python3 Jour 1] Programmation et Python
[Introduction à Python3 Day 21] Chapitre 10 Système (10.1 à 10.5)
Activé pour convertir PNG en JPG avec Pillow of Python
De l'introduction de JUMAN ++ à l'analyse morphologique du japonais avec Python
Introduction au remplissage d'image Python Remplissage d'image à l'aide d'ImageDataGenerator
Introduction facile de la reconnaissance vocale avec Python
[Introduction à Python] Utilisons foreach avec Python
[Introduction au Data Scientist] Bases de Python ♬
[Introduction à Python] Comment trier efficacement le contenu d'une liste avec le tri par liste
[Introduction à Python] Quelle est la méthode de répétition avec l'instruction continue?
Introduction de Python
[Introduction à Udemy Python3 + Application] 26. Copie du dictionnaire
Markov Chain Artificial Brainless avec Python + Janome (1) Introduction à Janome
Chaîne de Markov artificielle sans cervelle avec Python + Janome (2) Introduction à la chaîne de Markov
Comment profiter de la programmation avec Minecraft (Ruby, Python)
Introduction à l'intelligence artificielle avec Python 2 «Pratique de l'algorithme génétique»
[Introduction à Udemy Python3 + Application] 19. Copie de la liste
Introduction à Tornado (1): Framework Web Python démarré avec Tornado
Comment spécifier des attributs avec Mock of Python
Introduction au vol en formation avec Tello edu (Python)
Introduction à Python avec Atom (en route)
Introduction au modèle linéaire généralisé (GLM) par Python
[Introduction à l'application Udemy Python3 +] 9. Tout d'abord, imprimez avec print
[Introduction à Python] Utilisation de base des expressions lambda
[Introduction à Python] Comment obtenir l'index des données avec l'instruction for
Essayez de résoudre le livre des défis de programmation avec python3
Mémo connecté à HiveServer2 d'EMR avec python
[Introduction à Python] Comment itérer avec la fonction range?
3. 3. Programmation IA avec Python
Changer les paramètres IP en ACL de conoha avec python
Introduction au traitement parallèle distribué Python par Ray
Introduction aux mathématiques à partir du mémo d'étude Python Vol.1
Note de lecture: Introduction à l'analyse de données avec Python
Introduction au langage Python
[Chapitre 6] Introduction à scicit-learn avec 100 coups de traitement du langage
Introduction à OpenCV (python) - (2)
[Introduction à Udemy Python3 + Application] 53. Dictionnaire des arguments de mots-clés
Programmation Python avec Atom
[Introduction au trading système] J'ai dessiné un oscillateur stochastique avec python et joué avec ♬
Programmation compétitive avec python
[Python] Introduction au scraping WEB | Résumé des méthodes pouvant être utilisées avec webdriver
[Introduction à Python] Utilisation basique de la bibliothèque matplotlib
[Introduction à Udemy Python3 + Application] 52. Tapple d'arguments positionnels
Programmation avec Python Flask
Articles permettant le développement de systèmes avec Django (Python) _Introduction
Une introduction au logiciel d'interface graphique de la plate-forme de classe fait avec Python / Tkinter! (Et de nombreux Try and Error)! (Au milieu de l'écriture)