Tobias-Kohn / TigerPython-Parser

Enhanced error recognition in Python
Mozilla Public License 2.0
39 stars 6 forks source link

Improve common mistake : use the comma `,` instead of `.` for decimal point notation #8

Open donnerc opened 8 months ago

donnerc commented 8 months ago

One common mistake for the novices, at least in french speaking part of switzerland, is to use the comma instead of the . for floating point literals. This is because we say "nombre à virgule" to denote numbers with decimal positions. This generates errors really difficult to decrypt for the novices

from gturtle import *
makeTurtle()

size = 10
for _ in range(10):
    fd(size)
    rt(360 / 6)

    size *= 1,2

image

donnerc commented 8 months ago

Some hints

Code examples where the error is likely to be found

examples = {
  "data": {
    "code": {
      "nodes": [
        {
          "code": "# on voulait écrire 1.2 au lieu de 1,2 ... erreur fréquente\nx = 1,2\ny = x ** 2\n",
          "emessage": "TypeError: unsupported operand type(s) for ** or pow(): 'tuple' and 'int' on line 3"
        },
        {
          "code": "def etat_eau(temp):\n    if temp =-10\n        print(\" état solide\")\n    elif temp=0\n        print (\" etat liquide\")\n    elif temp= 80,100\n        print (\" etatliquide\")\n    \n",
          "emessage": "SyntaxError: bad input on line 2"
        },
        {
          "code": "prix_unitaire = 5,8\nnb_articles = input(f\"Nombre d'articles à commander (Prix unitaire {prix_unitaire} CHF): \")\nprix_total = nb_articles * prix_unitaire\nprint(f\"Prix total: {prix_total} CHF.\")\n",
          "emessage": "TypeError: can't multiply sequence by non-int of type 'tuple' on line 3"
        },
        {
          "code": "def binary_search(sorted_list, value):\n    left = 0\n    right = len(sorted_list) - 1\n\n    nb_iterations = 0\n\n    while left <= right:\n        nb_iterations += 1\n\n        mid = (left + right) // 2\n        element = sorted_list[mid]\n\n        if element == value:\n            return mid, nb_iterations\n        elif element < value:\n            left = mid + 1\n        else:\n            right = mid - 1\n\n\n    return -1, nb_iterations\n\n######################################\n## Test de l'algorithme\n\n# Nombre d'éléments dans la liste\nN = 3,5*10^9\n\n\n# Liste de nombres triée de 0 à (N-1)\nnumbers = list(range(N))\n\n# Pour stocker le nombre d'itérations nécessaires pour trouver\n# Chaque élément dans la liste `numbers`\nnb_iterations = []\n\nfor value in range(N+1):\n    index, nb_iters = binary_search(numbers, value)\n    nb_iterations.append(nb_iters)\n\n",
          "emessage": "TypeError: 'tuple' object cannot be interpreted as an integer on line 31"
        },
        {
          "code": "from gturtle import *\r\n\r\nmakeTurtle()\r\nspeed(10)\r\nSCREEN_WIDTH =830\r\nSCREEN_HEIGHT=800\r\n\r\ndef rectangle(height,width):\r\n    for i in range (2):\r\n        forward(height)\r\n        right(90)\r\n        forward(width)\r\n        right(90)\r\ndef sol():\r\n    setPos(-SCREEN_WIDTH/2,-330)\r\n    setPenColor(49, 150, 45)\r\n    setFillColor(49, 150, 45)\r\n    startPath()\r\n    rectangle(250,SCREEN_WIDTH)\r\n    fillPath()\r\n\r\ndef sky():\r\n    setPos(-SCREEN_WIDTH/2,-330)\r\n    setPenColor(82, 188, 209)\r\n    setFillColor(82, 188, 209)\r\n    forward(250)\r\n    startPath()\r\n    rectangle(250,SCREEN_WIDTH)\r\n    fillPath()\r\n\r\ndef filled_triangle(size,color):\r\n    setPenColor(color)\r\n    setFillColor(color)\r\n    \r\n    startPath()\r\n    left(90)\r\n    forward(size/2)\r\n    for i in range(3):\r\n        right(120)\r\n        forward(size)\r\n    rt(120)\r\n    fd(size/2)\r\n    rt(90)\r\n    fillPath()\r\ndef sapin(n,size,color):\r\n    for i in range(n):\r\n        filled_triangle(size,color)\r\n        fd(size/2)\r\n        size*=0,7\r\nsapin_color= 41, 105, 28\r\nsol()\r\nsky()\r\nsetPos(0,0)\r\nsapin(3,100,sapin_color)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n",
          "emessage": "[line: 37] unsupported operand type(s) for Div: 'tuple' and 'int' "
        },
        {
          "code": "from math import*\nx=1,25+0,6\n\nsqrt(0,7\"2+x\"2)\n\n\n      ",
          "emessage": "SyntaxError: bad input on line 4"
        },
        {
          "code": "def appreciation_note(note):\n    if note > 6:\n        return Impossible\n    if note < 1:\n        return Impossible\n    if note >= 5,5 or <= 6:\n        return Excellent\n    if note >= 5 or < 5.5:\n        return Tres bien\n    if note >= 4.5 or < 5:\n        return Bien\n    if note >= 4 or < 4.5:\n        return Suffisant\n    if note < 4:\n        return Insuffisant\n",
          "emessage": "SyntaxError: bad input on line 6"
        },
        {
          "code": "def prix_trajet(distance):\n    prix_trajet = (5*distance)\n    \n    if distance >= 10 and distance < 20 :\n        prix_trajet *= 0,95\n        \n    if distance >= 20 and distance < 30 :\n        prix_trajet *= 0,95\n        \n    if distance >= 30 :\n        prix_trajet *= 0,90\n        \n    if prix_trajet < 50:\n        prix_trajet += 10\n        \n    print('montant du trajet:',prix_trajet)\n    \nprix_trajet(9)\nprix_trajet(11)\nprix_trajet(20)",
          "emessage": "TypeError: '<' not supported between instances of 'tuple' and 'int' on line 13"
        },
        {
          "code": "from gturtle import*\r\nmakeTurtle()\r\nhideTurtle()\r\nfrom math import*\r\n\r\na = 50\r\nb = 2*a\r\nc = 1,5 a\r\nr = c/pi\r\nhypotenus = sqrt(a**2+a**2)\r\ndef trianglegauche():\r\n    forward(hypotenus)\r\n    right(135)\r\n    forward(a)\r\n    right(90)\r\n    forward(a)\r\n\r\ndef triangledroite():\r\n    forward(a)\r\n    right(135)\r\n    forward(hypotenus)\r\n    left(45)\r\n    forward(a)\r\ndef roue():\r\n    for loop in range(360):\r\n        forward(r)\r\n        right(1)\r\ndef voiture():\r\n    right(90)\r\n    forward(a*4+b)\r\n    back(b)\r\n    left(45)\r\n    triangledroite()\r\n    left(90)\r\n    back(a+b+a)\r\n    left(45)\r\n    trianglegauche()\r\n    right(45)\r\n    forward(hypotenus)\r\n    right(45)\r\n    forward(b)\r\n    right(90)\r\n    forward(a)\r\n    left(90)\r\n    forward(b)\r\n    right(90)\r\n    forward(a)\r\n    right(90)\r\n    forward(a)\r\n    roue()\r\n    forward(b)\r\n    roue()\r\n    forward(a)\r\n    right(90)\r\n    forward(90)\r\n    \r\nshowTurtle()",
          "emessage": "[line: 8] Il manque une virgule ou un opérateur."
        },
        {
          "code": "from gturtle import *\r\nmakeTurtle()\r\nfrom math import *\r\nspeed(50)\r\n\r\na = 50\r\nb = 2 * a\r\nc = 1,5 * a\r\nr = c/pi\r\nlongueur = 4 * a + b\r\n\r\n\r\ndef triangle():\r\n    hyp = sqrt((a ** 2) * 2 )\r\n    \r\n    fd(a)\r\n    rt(90)\r\n    fd(a)\r\n    rt(90 + 45)\r\n    fd(hyp)\r\n    rt(90 + 45)\r\n    \r\ndef rectangle():\r\n    for _ in range(2):\r\n        fd(b)\r\n        rt(90)\r\n        fd(a)\r\n        rt(90)\r\n        \r\ndef grand_rectangle():\r\n    for _ in range(2):\r\n        fd(longueur)\r\n        rt(90)\r\n        fd(a)\r\n        rt(90)\r\n        \r\ndef roue():\r\n    dot(2 * r)\r\n    \r\n#triangle()\r\n\r\ndef voiture():\r\n    lt(90)\r\n    triangle()\r\n    fd(a)\r\n    rectangle()\r\n    fd(b)\r\n    lt(90)\r\n    bk(a)\r\n    \r\n    triangle()\r\n\r\n    fd(a)\r\n    rt(90)\r\n    fd(2 * a)\r\n    rt(180)\r\n    \r\n    grand_rectangle()\r\n    \r\n    rt(90)\r\n    fd(a)\r\n    lt(90)\r\n    fd (a + r)\r\n\r\nvoiture()\r\n#rt(90)\r\nroue()\r\n",
          "emessage": "[line: 9] unsupported operand type(s) for Div: 'tuple' and 'float' "
        },
        {
          "code": "\n################# NE PAS TOUCHER : lecture des cases ####################\nfrom document import *\n\ndef get_values(checkbox_class):\n    ''' Cette fonction récupère les valeurs des boîtes à cocher '''\n    boxes = getElementsByClassName(checkbox_class)\n    return [b.checked for b in boxes]\n\n# Création des variables pour recevoir les valeurs des cases cochées\n# case cochée => variable = True\n# case pas cochée => variable = False\nthe_froid, eau_plate, eau_gazeuse, biere, limonade = get_values('choice-checkbox')\n##########################################################################\n\n# Les variables ci-dessous sont des valeurs booléennes indiquant si la\n# case correspondante a été cochée. Utilisez ces variables pour calculer\n# le prix total à payer.\n\nprint(\"Articles commandés\")\nprint(\"------------------\")\n\nx = 0\nif the_froid:\n    x += 3,2\n    print(\"Thé froid\")\nif eau_plate:\n    x += 1\n    print(\"Eau plate\")\nif eau_gazeuse:\n    x += 1,2\n    print(\"Eau gazeuse\")\nif biere: \n    x += 4,5\n    print(\"Bière\")\nif limonade:\n    x += 3\n    print(\"Limonade\")\nprint(x)\n\nprint(\"------------------\")\nprint(f\"Le prix total est de {x:.2f} francs\")",
          "emessage": "TypeError: unsupported operand type(s) for +=: 'int' and 'tuple' on line 31"
        },
        {
          "code": "def imc(masse, taille, unit):\n    if unit == 'cm':\n        size /= 100\n    elif unit == 'm':\n        size = size\n        \n    IMC = 0\n    if unit == \"m\":\n        IMC = masse / taille**2\n            if IMC <= 18,5:\n                print(IMC \"insuffisance pondérale\"\n            elif IMC <= 25:\n                print(IMC \"poids normal\"\n            elif IMC <= 30:\n                print(IMC \"Excès pondéral\"\n            elif IMC <= 40:\n                print(IMC \"obesité\"\n            elif IMC > 40:\n                print(IMC \"hors catégorie\" \n                      \n        ",
          "emessage": "SyntaxError: bad input on line 10"
        },
        {
          "code": "from gturtle import *\r\n\r\nn=20\r\n\r\ndef spirale(cote, angle, k, cote_min):\r\n        if n > cote_min:\r\n            fd(cote)\r\n            right(angle)\r\n            n *= 0,98\r\n            \r\nmakeTurtle()\r\nsetPos(-300, -200)\r\nhideTurtle()\r\nspirale(20, 5, 0.98, 1)",
          "emessage": "[line: 6] UnboundLocalError: local variable 'n' referenced before assignment "
        },
        {
          "code": "from gturtle import *\r\nfrom math import cos, sin, radians\r\nfrom random import *\r\n#################### Constantes propres au jeu #################\r\nGAME_WIDTH  = 1000\r\nGAME_HEIGHT = 700\r\n\r\nball_radius = 30\r\nball_color = \"red\"\r\nball_velocity = 4\r\n\r\n\r\n\r\n\r\ndef draw_ball(x, y):\r\n    \"draws the ball at position (x;y)\"\r\n    setPenColor(ball_color)\r\n    setPos(x, y)\r\n    dot(ball_radius)\r\n\r\ndef move_ball(x, y, vx, vy):\r\n    \"Computes the next position of the ball\"\r\n    return x + vx,y + vy\r\n\r\ndef get_init_velocity(beta):\r\n    alpha_min=-beta\r\n    alpha_max= beta\r\n    delta=randint(0,1)*180\r\n    alpha = randint(alpha_min, alpha_max)+delta\r\n    vx = ball_velocity * cos(radians(alpha))\r\n    vy = ball_velocity * sin(radians(alpha))\r\n    \r\n    return(vx, vy)\r\n\r\ndef rectangle (GAME_WIDTH, GAME_HEIGHT):\r\n    for loop in range (2):\r\n         forward(-GAME_WIDTH)\r\n         right(90)\r\n         forward(GAME_HEIGHT)\r\n         right(90)\r\n\r\n\r\ndef draw_border():\r\n    xstart = -GAME_WIDTH / 2\r\n    ystart = GAME_HEIGHT/ 2\r\n    setPos(xstart, ystart)\r\n    setHeading(90)\r\n    rectangle(-GAME_WIDTH, GAME_HEIGHT)\r\n\r\ndef draw_paddle(x,y):\r\n    setPos(..., ...)\r\n    setheading(...)\r\n    setFillColor(\"black\")\r\n    startPath()\r\n    # dessin du rectangle\r\n    fillPath()\r\n    \r\n\r\ndef game(fps=60):\r\n    hideTurtle()\r\n\r\n    # temps d'attente entre deux parcours de la boucle\r\n    ms = 1000 // fps - 1\r\n\r\n    ball_x, ball_y = 0, 0\r\n    #  ball_vx, ball_vy=  get_init_velocity(30) \r\n    ball_vx, ball_vy = 1, 5\r\n    \r\n    #raquette 1\r\n    p1_x, p1_y = -450,0\r\n    p1_vx, p1_vy= 0,0\r\n    #raquette 2\r\n    p2_x, p2_y= 450,0\r\n    p2_vx, p2_vy= 0,0\r\n    \r\n    while True:\r\n        clear()\r\n        draw_border()\r\n        #lire le clavier\r\n        code=getKeyCode()\r\n\r\n        draw_ball(ball_x, ball_y)\r\n\r\n        ball_x, ball_y = move_ball(ball_x, ball_y, ball_vx, ball_vy)\r\n        # gestion des collisions\r\n        if ball_y + ball_radius > GAME_HEIGHT // 2:\r\n            ball_vy *= -1\r\n        if ball_y - ball_radius < -GAME_HEIGHT // 2:\r\n            ball_vy *= -1\r\n\r\n        delay(ms)\r\n\r\nmakeTurtle()\r\ngame()\r\n\r\n",
          "emessage": "[line: 51] SyntaxError: bad input "
        },
        {
          "code": "# -*- coding: cp1252 -*-\r\n#\r\n\r\n###############=============================##############\r\n###############============Créée============##############\r\n###############=============Par=============##############\r\n###############============Elnabo===========##############\r\n###############=============12/09===========##############\r\n###############=============================##############\r\n\r\n#On importe les fonctions necessaires\r\n\r\nfrom Tkinter import *\r\nfrom random import randrange\r\n\r\n#Fonction la plus compliquée permettant le déplacement du serpent\r\ndef deplacement():\r\n        global a,b,z,y,lu,lv,score,serpent,j,m\r\n        c=len(serpent)\r\n        c=c-1\r\n        #Chaque carré reprend la coordonnée du précédent dans la liste (serpent)\r\n        while c!=0 :\r\n                lu[c]=lu[c-1]\r\n                lv[c]=lv[c-1]\r\n                c+=-1\r\n        #On change les coordonées du premier carré\r\n        lu[0] += a\r\n        lv[0] += b\r\n        c=0\r\n        #On applique les nouvelles coordonnées aux carrés correspondant\r\n        while c!=len(serpent):\r\n                can.coords(serpent[c],lu[c],lv[c],lu[c]+10,lv[c]+10)\r\n                c+=1\r\n        c=1\r\n        #Si les coordonnées du premier carré sont égales à celle d'un autre le jeu s'arrêtera\r\n        while c!=len(serpent):\r\n                if lu[c]==lu[0] and lv[c]==lv[0]:\r\n                        j=1\r\n                        score = 'Perdu  avec  ' + str(score*10)\r\n                        scores.set(score)\r\n                        break\r\n                c+=1\r\n        #Si le serpent est mord un coté il ressort de l'autre\r\n        #La valeur 'd' sert à empecher un bug empechant la transfert du serpent de l'autre coté du canvevas\r\n        d=1\r\n        if lu[0]==200:\r\n                lu[0],d=10,0\r\n        if lu[0]==0 and d==1:\r\n                lu[0]=200\r\n        if lv[0]==200:\r\n                lv[0],d=10,0\r\n        if lv[0]==0 and d==1:\r\n                lv[0]=200\r\n        d=0\r\n        #Si le carré de tête recoupe le cercle, le score augmente et un nouveau cercle apparait aléatoirement\r\n        if z-7<=lu[0]<=z+7 and y-7<=lv[0]<=y+7:\r\n                score+=1\r\n                scores.set(str(score*10))\r\n                bestiole()\r\n        if j!=1 and m!=1:\r\n                fen.after(100,deplacement)\r\n\r\n#Cette fonction crée un cercle de coordonée multiple de 10 pour éviter que le cercle soit partiellement coupé par le serpent\r\n\r\ndef bestiole():\r\n        global z,y,n,lu,lv,serpent,a,b\r\n        z=randrange(2,18)\r\n        y=randrange(2,18)\r\n        z = z*10\r\n        y = y*10\r\n        can.coords(cercle,z,y,z+5,y+5)\r\n        #On ajoute un carré hors du canevas (pour allèger le code) qui se rajoutera à la suite\r\n        serpents = can.create_rectangle(300,300,310,310,fill='green')\r\n        serpent.append(serpents)\r\n        lu.append(lu[n]+12+a)\r\n        lv.append(lv[n]+12+b)\r\n        n+=1\r\n\r\n#Ces quatres fonctions permettent le déplacement dans quatres directions du serpent\r\n#Grace aux modifications successives des coordonées du premier carrée grave au valeur a et b\r\n#La valeur s permet de ne pas accelerer la vitesse du serpent ou à modifier ca direction\r\n#en appuyant successivement sur Haut/Bas/Gauche/Droite\r\n\r\ndef gauche(event):\r\n        global a,b,s\r\n        a=-10\r\n        b=0\r\n        if s==0:\r\n                s=1\r\n                deplacement()\r\n\r\ndef droite(event):\r\n        global a,b,s\r\n        a=10\r\n        b=0\r\n        if s==0:\r\n                s=1\r\n                deplacement()\r\n        \r\ndef haut(event):\r\n        global a,b,s\r\n        a=0\r\n        b=-10\r\n        if s==0:\r\n                s=1\r\n                deplacement()\r\n\r\n        \r\ndef bas(event):\r\n        global a,b,s\r\n        a=0\r\n        b=10\r\n        if s==0:\r\n                s=1\r\n                deplacement()\r\n\r\n#Cette fonction permet d'arrêter le serpent\r\n                \r\ndef pause(event):\r\n        global j,a,b,m,enpause\r\n        t=0\r\n        if a==b:\r\n                t=1\r\n        if j!=1:\r\n                #Affichage ou Effacage du texte 'PAUSE'\r\n                #Et arrêt du serpent\r\n                if m!=1:\r\n                        m=1\r\n                        can.coords(enpause,100,100)\r\n                else:\r\n                        m=0\r\n                        can.coords(enpause,300,300)\r\n                        if t!=1:\r\n                                deplacement()\r\n\r\n#Cette fonction réinitialise toutes les valeurs et recréée le serpent de base ainsi que le premier repas\r\n\r\ndef recommencer(event):\r\n        global z,y,lu,lv,score,serpent,j,m,s,n,a,b,cercle\r\n        if j!=1:\r\n                print 'Le suicide est puni'\r\n        can.delete(ALL)\r\n        s=score=j=m=a=b=0\r\n        z=y=50\r\n        lu,lv,serpent = [100,112],[100,112],[]\r\n        n=1\r\n        tete = can.create_rectangle(100,100,110,110,fill='dark green')\r\n        carre = can.create_rectangle(112,100,122,110,fill='green')\r\n        cercle = can.create_oval(z,y,z+5,y+5,fill='red')\r\n        serpent.append(tete)\r\n        serpent.append(carre)\r\n        scores.set('0')\r\n\r\n#On définit les valeurs initiales\r\n\r\ns=score=j=m=t=a=b=0\r\nz=y=50\r\nlu,lv,serpent = [100,112],[100,112],[]\r\nn=1\r\n\r\nprint ' '*35 + 'Les fleches pour bouger'\r\nprint ' '*35 + 'P pour mettre/enlever la pause'\r\nprint ' '*35 + 'Entree pour recommencer, attention au suicide'\r\n\r\n#On crée un canevas tout gris\r\n\r\nfen = Tk()\r\ncan = Canvas(fen,width = 200, height = 200 , bg = 'gray')\r\ncan.grid(row=1,column=0,columnspan=3)\r\n\r\nenpause=can.create_text(300,300,text=\"PAUSE\")\r\n\r\n#On crée la base du serpent ainsi que le premier repas\r\n\r\ntete = can.create_rectangle(100,100,110,110,fill='dark green')\r\ncarre = can.create_rectangle(112,100,122,110,fill='green')\r\ncercle = can.create_oval(z,y,z+5,y+5,fill='red')\r\n\r\nserpent.append(tete)\r\nserpent.append(carre)\r\n\r\n#On crée les commandes au clavier\r\n\r\ncan.bind_all('<Up>', haut)\r\ncan.bind_all('<Down>', bas)\r\ncan.bind_all('<Left>', gauche)\r\ncan.bind_all('<Right>', droite)\r\ncan.bind_all('<Return>',recommencer)\r\ncan.bind_all('p',pause)\r\n\r\n#L'affichage du score\r\n\r\nLabel(fen, text='Score:  ').grid(row=0,column=0)\r\n\r\nscores = StringVar()\r\nScore = Entry(fen, textvariable=scores)\r\nScore.grid(row=0,column=1)\r\nscores.set('0')\r\n\r\nfen.mainloop()\r\n\r\n",
          "emessage": "[line: 13] ImportError: No module named Tkinter "
        },
        {
          "code": "def double_compensation(*notes):\n    return sum(2 ** (1 - int(note > 4)) * (note - 4) for note in notes)\ndef est_promu(fr, al, ma, an, bio, chi, phy, hi, art):\n    return True\ni = 0\nwhile i < 6: \n    if notes > 4:\n        return True\n    else :\n        return False\n    i += 0,5\ndouble_compensation()\nest_promu()",
          "emessage": "SyntaxError: 'return' outside function on line 8"
        },
        {
          "code": "from gturtle import *\r\nfrom math import *\r\n\r\nmakeTurtle()\r\nc = 17112,5**1/2\r\nx = 185\r\n\r\n\r\nfor loop in range(5):\r\n    left(90)\r\n    forward(x/2)\r\n    right(45)\r\n    forward(c)\r\n    right(90)\r\n    forward(c)\r\n    right(45)\r\n    forward(c)\r\n    \r\n",
          "emessage": "[line: 13] nombre_de_pas doit être de type nombre  "
        },
        {
          "code": "from gturtle import *\r\nmakeTurtle()\r\nc = 144\r\nh = 124,71\r\nright(90)\r\nforward(c / 2)\r\nleft(120)\r\nforward(144)\r\nleft(150)\r\nforward(h)",
          "emessage": "[line: 10] nombre_de_pas doit être de type nombre  "
        },
        {
          "code": "def serie(n, nb_termes):\r\n    total = 0\r\n    repeat nb_termes:\r\n        #print(n)\r\n        total +=n\r\n        n /=1,5\r\n    print(\"somme:\", total)    \r\n\r\nserie(32, 100)\r\n",
          "emessage": "[line: 6] unsupported operand type(s) for Div: 'int' and 'tuple' "
        },
        {
          "code": "from gturtle import*\r\n\r\ndef spirale(cote):\r\n    repeat 18:\r\n        forward(cote)\r\n        left(360/60)\r\nprint cote\r\n        cote *= 1,2\r\n\r\nmakeTurtle()\r\nspirale(10)\r\n",
          "emessage": "[line: 8] Cette ligne est trop indentée par rapport à la précédente."
        },
        {
          "code": "from gturtle import*\r\n\r\ndef cercle(nombre,perimetre):\r\n    repeat nombre:\r\n        repeat 36:\r\n            forward(perimetre/36)\r\n            right(25)\r\n        perimetre *= 1,2\r\n        \r\nmakeTurtle()\r\nhideTurtle()\r\ncercle(5, 500)\r\n",
          "emessage": "[line: 6] unsupported operand type(s) for Div: 'tuple' and 'int' "
        },
        {
          "code": "from gturtle import*\r\n\r\ndef spirale(cote):\r\n    repeat 18:\r\n        forward(cote)\r\n        left(360/60)\r\n    print cote\r\n        cote *= 1,2\r\n\r\nmakeTurtle()\r\nspirale(10)\r\n\r\n\r\n",
          "emessage": "[line: 8] Cette ligne est trop indentée par rapport à la précédente."
        },
        {
          "code": "from gturtle import *\r\n#clair=green\r\n#fonce=blue\r\ndef ligne_bicolore(green,blue):\r\n    setPenColor(\"green\")\r\n    forward(green)\r\n    setPenColor(\"blue\")\r\n    forward(blue)\r\n    penUp()\r\n    setPenColor(\"white\")\r\n    back(50)\r\n    \r\n    green += 1,4\r\n    blue -= 1,4\r\n    \r\ndef etoile_coloree():\r\n    repeat 36:\r\n        ligne_bicolore(0,50)\r\n        right(10)\r\n    \r\n\r\nmakeTurtle()\r\nhideTurtle()\r\netoile_coloree()\r\n\r\n",
          "emessage": "[line: 13] unsupported operand type(s) for Add: 'int' and 'tuple' "
        },
        {
          "code": "from gturtle import*\r\n\r\ndef spirale(cote):\r\n    repeat 18:\r\n        repeat 6:\r\n        forward(cote)\r\n        left(60)\r\n    cote *= 1,2\r\n\r\nmakeTurtle()\r\nspirale(10)\r\n\r\n",
          "emessage": "[line: 5] Cette structure nécessite un corps. Vérifier l'indentation !"
        },
        {
          "code": "from gturtle import *\r\n\r\ndef spirale(cote):\r\n    repeat 18:\r\n        forward(cote)\r\n        left(60)\r\n        cote *= 1,2\r\n\r\nmakeTurtle()\r\nspirale(10)",
          "emessage": "[line: 5] nombre_de_pas doit être de type nombre  "
        },
        {
          "code": "from gturtle import *\r\n\r\n# Définir les commandes ici\r\n\r\ndef spirale(cote):\r\n    repeat 18:\r\n        forward(cote)\r\n        left(120)\r\n        cote *= 1,2\r\n\r\n\r\n# Programme principal\r\nmakeTurtle()\r\nspirale(10)\r\nforward(cote)\r\nleft(60)\r\n",
          "emessage": "[line: 15] NameError: name 'cote' is not defined "
        },
        {
          "code": "from gturtle import *\r\n\r\ndef ligne_bi(longueur1, longueur2):\r\n    setPenColor(\"dark blue\")\r\n    forward(longueur1)\r\n    setPenColor(\"light blue\")\r\n    forward(longueur2)\r\n    penUp()\r\n    back(50)\r\n    penDown()\r\n\r\ndef spiral(longueur1,longueur2):\r\n    repeat 36:\r\n        ligne_bi(longueur1,longueur2)\r\n        right(10)\r\n        longueur1 -= 0,5\r\n        longueur2 += 0,5\r\nmakeTurtle()\r\n\r\nspiral(30,20)",
          "emessage": "[line: 16] TypeError: unsupported operand type(s) for Sub: 'int' and 'tuple' "
        },
        {
          "code": "from gturtle import *\r\n\r\ndef cercle(nombre, perimetre):\r\n    repeat nombre:\r\n        repeat 36:\r\n            forward(perimetre / 36)\r\n            right(10)\r\n            \r\nprint 'nombre cercles:', nombre\r\nprint 'perimetre cercle:', perimetre\r\nperimetre *= 1,2\r\n\r\nmakeTurtle()\r\ncercle(3, 400)",
          "emessage": "[line: 9] NameError: name 'nombre' is not defined "
        },
        {
          "code": "from gturtle import *\r\nmakeTurtle()\r\n\r\ndef polygone(cote, couleur):\r\n    \r\n    setPenColor(couleur)\r\n    \r\n    setFillColor(couleur)\r\n    startPath()\r\n    \r\n    for loop in range(360//6):\r\n        forward(cote)\r\n        right(360/6)\r\n        \r\n    fillPath()\r\n\r\ndef decalage(nb_pixels):\r\n    penUp()\r\n    right(180)\r\n    forward(nb_pixels)\r\n    left(180)\r\n    penDown()\r\ndef animation(n):\r\n    #dessine n frames\r\n    \r\n    #temps d'affichage de chaque frame en ms\r\n    delai = 0,0000001\r\n    \r\n    #boucle d'animation\r\n    \r\n    for _ in range(n):\r\n        polygone(50, \"blue\")\r\n        delay(delai)\r\n        clear()\r\n        decalage(1)\r\n        right(1)\r\n        forward(1)\r\n        \r\nhideTurtle()      \r\nanimation(360)",
          "emessage": "[line: 33] temps doit être de type nombre  "
        },
        {
          "code": "from gturtle import *\r\n\r\ndef carre(taille,color,nbr_cote):\r\n    setPenWidth(60)\r\n    for _ in range(nbr_cote):\r\n        fd(taille)\r\n        rt(90)\r\ndef blink_light(diameter, color):\r\n    ms = 0,1\r\n\r\n\r\n    setPenColor(color)\r\n    for _ in range(1000):\r\n        # allumer le feu\r\n        carre(60,\"orange\",4)\r\n\r\n        # laisser le feu allumé quelques ms\r\n        delay(ms)\r\n\r\n        # effacer l'écran\r\n        clear()\r\n\r\n        # laisser le feu éteint quelques ms\r\n        delay(ms)\r\n\r\n\r\nmakeTurtle()\r\nhideTurtle()\r\nblink_light(50, \"orange\")\r\n",
          "emessage": "[line: 18] temps doit être de type nombre  "
        },
        {
          "code": "from gturtle import *\r\n\r\ndef draw_triangle(size, contour, fill_color):\r\n    # \"dessine un triangle équilatéral\"\r\n    setPenColor(contour)\r\n    setFillColor(fill_color)\r\n\r\n    startPath()\r\n    for loop in range(3):\r\n        forward(size)\r\n        right(120)\r\n    fillPath()\r\n\r\n\r\ndef move_left(nb_pixels):\r\n    # \"déplace la tortue vers la droite de nb_pixels pixels\"\r\n    penUp()\r\n    lt(90)\r\n    forward(nb_pixels)\r\n    rt(90)\r\n    penDown()\r\n\r\ndef animation(n):\r\n    # \"dessine l'animation (n frames)\"\r\n    # temps d'affichage de chaque image\r\n    ms = 16,666666667\r\n\r\n    # boucle d'animation\r\n    for loop in range(n):\r\n        # effacer tout l'écran\r\n        clear()\r\n\r\n        # dessiner une 'frame'\r\n        draw_triangle(50, \"red\", \"green\")\r\n\r\n        # attendre quelques millisecondes\r\n        # (temps affichage image)\r\n        delay(ms)\r\n\r\n        # déplacer la tortue\r\n        move_left(3)\r\n\r\n\r\nmakeTurtle()\r\nhideTurtle()\r\nanimation(60)\r\n",
          "emessage": "[line: 38] temps doit être de type nombre  "
        },
        {
          "code": "from gturtle import *\n\n\ndef fahrenheit_to_celsius(fahrenheit):\n    T (F) = 1,8 x T (C) + 32\n    return T(F)\n\nValeur de retour: Transforme la température ``fahrenheit``, donnée en\ndegrés Fahrenheit, en degrés Celsius.\n\n'''\n\n",
          "emessage": "SyntaxError: bad input on line 5"
        },
        {
          "code": "\ndef fahrenheit_to_celsius(temperature):\n    return(temperature-32)*(5/9)\ntemperature_1 = 30\nwhile temperature_1 < 101:\n    print(temperature_1, \"vaut\", fahrenheit_to_celsius(temperature_1))\n    temperature_1 +=0,1\n",
          "emessage": "TypeError: unsupported operand type(s) for +=: 'int' and 'tuple' on line 7"
        },
        {
          "code": "def f(x):\n    if x! = -0,5 and x != 0,5:\n        return 1 / (4 * x**2 -1)\n    else:\n        print(\"erreur\")\n        return None\n",
          "emessage": "SyntaxError: bad token on line 2"
        },
        {
          "code": "def f(x):\n    y = 1/(4*x**2-1)\n    \n\n    if x = 0,5\n    print(\"Vous avez fait une erreur\")\n\n    elif x = -0,5\n    print(\"Vous avez fait une erreur\")\n    \n    else :\n        \n    return y \n\n\nprint(f(10)) \n\n",
          "emessage": "SyntaxError: bad input on line 5"
        },
        {
          "code": "def letter_count(text, letter_to_find):\n    count = 0\n    for current_letter in text:\n        if current_letter == letter_to_find:\n            count += 1\n    return count\n\ndef letter_freq(text, letter_to_find):\n    if letter_count % 2 = 0:\n        letter_to_find == 1\n    elif letter_count % 2 = 1:\n        letter_to_find == 0,5\n    else:\n        letter_to_find == 0\n        \ntext = input(\"Entrez un texte:\")\nletter = input(\"Entrez une lettre à compter:\")\ncount = letter_count(text, letter)\nprint(\"Le texte '\" + text + \"' contient\", count, \"occurrences de la lettre\", letter)\n",
          "emessage": "SyntaxError: bad input on line 9"
        },
        {
          "code": "def mastermind_ill_positioned(choice, solution):\n    \n    for i in range(len(choice)):\n        if choice[i]==solution[i]:\n            choice[i]=None\n            solution[i]=None\n\n\n    while None in choice:\n        choice.remove(None)\n    choice.sort()\n    while None in solution:\n        solution.remove(None)\n    solution.sort()\n\n    i,j=0,0\n    common=0\n    while i<len(choice) and j<len(solution):\n        if choice[i]==solution[j]:\n            common+=1\n            i+=1\n            j+=1\n        elif choice[i]<solution[j]:\n            i+=1\n        else:\n            j+=1\n\n\n    return common\n\n\nprint(mastermind_ill_positioned([1,2,3,4], [1,2,3,4]))\nprint(mastermind_ill_positioned([1,2,3,4], [1,2,5,3]))\nprint(mastermind_ill_positioned([1,2,3,4], [5,1,2,3]))\nprint(mastermind_ill_positioned([1,2,3,4], [5,6,7,8]))\n\n",
          "emessage": "SyntaxError: bad input on line 124"
        },
        {
          "code": "numbers = [4, 6, 2, 8, 10]\n\ni = 0\nwhile i < len(numbers):\n    print(\"Le nombre à la position\", i, \"est\", numbers[i])\n    i += 0,5\n",
          "emessage": "TypeError: unsupported operand type(s) for Add: 'int' and 'tuple' on line 6"
        },
        {
          "code": "from gturtle import *\r\nfrom math import sqrt\r\n\r\ndef carre40():\r\n    forward(40)\r\n    right(90)\r\n    forward(40)\r\n    right(90)\r\n    forward(40)\r\n    right(90)\r\n    forward(40)\r\n    right(90)\r\n\r\ndef triangle40():\r\n    forward(40)\r\n    right(135)\r\n    forward(40 * sqrt(2))\r\n    right(135)\r\n    forward(40)\r\n    right(90)\r\n\r\ndef poisson():\r\n    left(135)\r\n    triangle40()\r\n    right(180)\r\n    carre40()\r\n    left(45)\r\n\r\ndef montre_poisson():\r\n    setPenColor(\"red\")\r\n    poisson()\r\n    delay(200)\r\n    setPenColor(\"white\")\r\n    poisson()\r\n\r\ndef un_pas():\r\n    montre_poisson()\r\n    setPenColor(\"white\")\r\n    setPenWidtch(2)\r\n    right(90)\r\n    forward(5)\r\n    left(90)\r\n\r\nmakeTurtle()\r\nhideTurtle()\r\n\r\nun_pas()\r\nun_pas()\r\nun_pas()\r\nun_pas()\r\nun_pas()\r\n\r\n#200ms = 0,2sec",
          "emessage": "[line: 39] NameError: name 'setPenWidtch' is not defined "
        },
        {
          "code": "from gturtle import *\r\nmakeTurtle()\r\n\r\ndef spirale(cote_initial, increment, angle, cote_max):\r\n\r\n    forward (cote_initial)\r\n    right (angle)\r\n    increment += 10 \r\n    \r\n    \r\nspirale (50,cote_initial+=10,120)\r\n    ",
          "emessage": "[line: 11] L'assignation '+=' ne peut pas faire partie d'une expression."
        },
        {
          "code": "from gturtle import *\r\nmakeTurtle()\r\n\r\ndef spirale(cote_initial, increment, angle, cote_max):\r\n    \r\n    cote = cote_initial\r\n    compteur = 0,1,2\r\n    \r\n    while not cote_initial > cote_max:\r\n        print (compteur, compteur % 3)\r\n        \r\n        if compteur % 3 == 0:\r\n            setPenColor (\"red\")\r\n        if compteur % 3 == 1:\r\n            setPenColor (\"green\")\r\n        if compteur % 3 == 2:\r\n            setPenColor (\"blue\")\r\n            forward (cote)\r\n            right (angle)\r\n            \r\n            cote += increment\r\n            increment += addition\r\n            compteur += 1\r\n        \r\n        print(cote_initial, increment, compteur)        \r\n        forward (cote_initial)\r\n        right (angle)\r\n        cote_initial = cote_initial + increment\r\nspirale (50, 10, 90, 400)",
          "emessage": "[line: 10] unsupported operand type(s) for Mod: 'tuple' and 'int' "
        },
        {
          "code": "from math import *\nDF = 1,85\nAD = 0,7\nAF = sqrt(DF ** 2 + AD ** 2)\nprint(\"la longueur AF vaut\", AF)\n\n",
          "emessage": "TypeError: unsupported operand type(s) for ** or pow(): 'tuple' and 'int' on line 4"
        },
        {
          "code": "from mbrobot import *\nRobotContext()\n\nrayon = 0,1\nwhile 1 == 1:\n    leftArc(rayon)\n    rayon += 0.1\n \n",
          "emessage": "ImportError: No module named mbrobot on line 1"
        },
        {
          "code": "from mbrobot import *\n\nRobotContext.enableTrace(True)\n\nrayon = 0,1\nwhile rayon < 2:\n    # tourner sur un arc de cercle à gauche\n    leftArc(rayon)\n    print(rayon)\n    delay(300)\n    # à chaque répétition, on rajoute 10 pixel\n    rayon += 0,01",
          "emessage": "ImportError: No module named mbrobot on line 1"
        },
        {
          "code": "from mbrobot import*\nsetSpeed (50)\nforward()\ndelay(1000)\narc_e = 0,5\ndef arc (arc_e):\n    leftArc (arc_e)\n    delay(1000)\n    arc_e += 0,5\ndef go ():\n    forward ()\n    delay(1000)\ndef retrun ():\n    motL.rotate(20)\n    motR.rotate(0)\n    delay(1500)\nwhile True :\n    arc(arc_e)\n    go()\n    retrun()\n    go()\n    \n    \n    \n    \n    \n    ",
          "emessage": "ImportError: No module named mbrobot on line 1"
        },
        {
          "code": "#Meilleur code\ndef sieve(n):\n    liste = [0] * (n + 1)\n    palier = 2\n    nombre_cible = 2\n    liste[0], liste[1] = 1,1\n    liste_nombre_premier = []\n    while nombre_cible <= n:\n        for element in range(nombre_cible, n+1, palier):\n            liste[element] = 1\n        liste[nombre_cible] = \"p\"\n        liste_nombre_premier.append(nombre_cible)\n        try:\n            palier = liste.index(0)\n            nombre_cible = liste.index(0)\n        except:\n            break\n    print (liste_nombre_premier)\n    return liste_nombre_premier\n\nsieve(0)",
          "emessage": "IndexError: list assignment index out of range on line 6"
        },
        {
          "code": "from gturtle import*\r\nfrom math import*\r\nmakeTurtle()\r\n\r\nspeed(5)\r\npenUp()\r\nleft(90)\r\nforward(10)\r\nright(90)\r\npenDown()\r\ndef cercle(rayon, nb_cotes, couleur, epaisseur):\r\n    nb_cotes=3,6*rayon\r\n    longueur=2*pi*rayon/nb_cotes\r\n   \r\n    repeat nb_cotes:\r\n        setPenColor(couleur)\r\n        setPenWidth(epaisseur)\r\n        forward(longueur)\r\n        right(360/nb_cotes)\r\n    penUp()\r\n    left(90)\r\n    forward(10)\r\n    right(90)\r\n    penDown()    \r\n\r\n\r\ndef test_cercle():\r\n    rayon = 10\r\n    couleur = \"red\"\r\n    epaisseur = 10\r\n    cercle(rayon, couleur, epaisseur)\r\n    \r\n\r\n    rayon = 20\r\n    couleur = \"yellow\"\r\n    epaisseur = 10\r\n    cercle(rayon, couleur, epaisseur)\r\n    \r\n\r\n    rayon = 30\r\n    couleur = \"blue\"\r\n    epaisseur = 10\r\n    cercle(rayon, couleur, epaisseur)\r\n    \r\n\r\ntest_cercle()\r\n",
          "emessage": "[line: 31] La fonction cercle() attendre exactement 4 argumentes (3 donnés). "
        },
        {
          "code": "from gturtle import*\r\nfrom math import*\r\n\r\ndef polygone(nb_cotes, longueur_cotes, couleur, epaisseur):\r\n    setPenColor(couleur)\r\n    setPenWidth(epaisseur)\r\n    repeat nb_cotes:\r\n        forward(longueur_cotes)\r\n        right(360/ nb_cotes)\r\n\r\ndef cercle(rayon, nb_cotes, couleur, epaisseur):\r\n    perimetre = 2 * pi * rayon\r\n    longueur_cotes = perimetre/ rayon\r\n    polygone(nb_cotes, longueur_cotes, couleur, epaisseur)\r\n\r\ndef cercles_concentriques(couleur1, couleur2, nb_cercles, epaisseur):\r\n    rayon = 0,1\r\n    compteur = 0\r\n    nb_cotes = 75\r\n    while True:\r\n        if compteur % 2 == 1:\r\n            couleur = couleur1\r\n        else:\r\n            couleur = couleur2\r\n        cercle(rayon, nb_cotes, couleur, epaisseur)\r\n        if compteur == nb_cercles:\r\n            break\r\n        rayon = rayon + epaisseur\r\n        compteur = compteur + 1\r\n        \r\ndef test_cercles_concentriques():\r\n    couleur1 = \"blue\"\r\n    couleur2 = \"yellow\"\r\n    nb_cercles = 15\r\n    epaisseur = 12\r\n    cercles_concentriques(couleur1, couleur2, nb_cercles, epaisseur)\r\n\r\ntest_cercles_concentriques()\r\n",
          "emessage": "[line: 13] unsupported operand type(s) for Div: 'tuple' and 'tuple' "
        },
        {
          "code": "def polygone(longueur_cotes, nb_cotes):\r\n    repeat nb_cotes:\r\n        forward(longueur_cotes)\r\n        right(360/nb_cotes)\r\n       \r\n #définition de la commande cerclebasique() \r\n #à partir de la commande polygone()       \r\n       \r\n        \r\n       \r\ndef cerclebasique(rayon, nb_cotes):\r\n    polygone(2*pi*rayon / nb_cotes, nb_cotes)\r\n    pi=3,14159 \r\ncerclebasique(10, 20)   ",
          "emessage": "[line: 12] UnboundLocalError: local variable 'pi' referenced before assignment "
        },
        {
          "code": "from math import sqrt\n\ndef norm_2d(v):\n    return sqrt(v[0] ** 2 + v[1] ** 2)\ncoor = 3,4\nprint(norm_2d(coor)",
          "emessage": "SyntaxError: bad input on line 8"
        }
      ]
    }
  }
}

for entry in examples['data']['code']['nodes']:
    print(30 * "#")
    code, msg = entry.values()
    print(code)
Tobias-Kohn commented 7 months ago

Thank you very much for the suggestion. I am afraid, it is not quite that simple, though.

One of the key words in your description is the almost in almost certainly. I had experimented a while back with these kinds of errors and found that they start to generate way too many false positives. All of a sudden, completely legal Python programs will not run anymore, because the parser is too zealous and seeing problems everywhere...

If you look at the list, almost all the examples are runtime-errors. This is another way of saying that (a) there is nothing wrong from a strict syntactical perspective with these programs and (b) you need information about the actual types and values to see the problem. In other words: there is only so much a parser can do here. But in order to point out a mistake, the parser essentially has to be certain and not almots certain, that is prove that something is wrong. Otherwise it is better not to interfere.

I will investigate and try to come up with something that can discover these kinds of mistakes in 'obvious' cases. However, please do not expect too much out of this; it really is a tough problem.