calcul.py

Created by cent20

Created on April 21, 2021

8.42 KB

𝗖𝗮𝗹𝗰𝘂𝗹 𝗠𝗲𝗻𝘁𝗮𝗹

Un générateur de calcul aléatoire : nsi.xyz/calcul
Version 2.0, intègre le menu graphique pour python pour un paramétrage facile. 🤯
Ne fonctionne que sur la calculatrice, pas sur le simulateur en ligne.


# Calcul Mental - V. 2.0.0.0 ^^

from kandinsky import *
from ion import keydown
from random import randint as rd,choice
from time import *

# menu récupéré sur nsi.xyz/menu ;-)

def wait(buttons=range(53)):  # Attends qu'une des touches précisées soit pressée
    while True:
        for i in buttons:
            if keydown(i):
                while keydown(i):
                    pass
                return i


def omega():  # Vérificateur d'OS
    try:
        get_keys()
        return True
    except:
        return False


def menu(titre, action, *para):
    n, g, f = (0, 0, 0), (96, 96, 96), (255, 183, 52)  # couleurs : réglages, optionsn focus
    if omega():
        f = (192, 53, 53)
    chx = [1 for i in para]  # Valeurs par défaut
    curs = 0  # Initialisation sur l'action
    draw_string(titre, int(160 - 5 * len(titre)), 8, (42, 120, 224))
    draw_string(action, int(160 - 5 * len(action)), 36, f)

    def menu_option(i, col, cursor):
        draw_string(" " * 13, 150, 64 + i * 25, col)
        txt = str(para[i][chx[i]])
        if txt.find("$") != -1:
            txt2 = txt[txt.find("$") + 1:]
            txt = txt[:txt.find("$")]
            draw_string(" " * 32, 0, 64 + (i + 1) * 25)
            draw_string(str(txt2), int(150 + (150 - 10 * len(str(txt2))) / 2), 64 + (i + 1) * 25, col)
        draw_string(" " * 17, 140, 64 + (i) * 25)
        draw_string(str(txt), int(150 + (150 - 10 * len(str(txt))) / 2), 64 + i * 25, col)
        draw_string("<" * cursor, 140, 64 + i * 25, g)
        draw_string(">" * cursor, 300, 64 + i * 25, g)

    for i in range(len(para)):
        draw_string(para[i][0], 10, 64 + i * 25, n)
        menu_option(i, g, False)

    while True:
        r = wait((0, 1, 2, 3, 4, 52))
        if r in (4, 52):  # Lance l'application
            return [para[i][chx[i]] for i in range(len(para)-1)]
        elif r in (1, 2):
            if curs == 0:
                draw_string(action, int(160 - 5 * len(action)), 36, n)
            else:
                menu_option(curs - 1, g, False)
            curs = (curs - 1 * (r == 1) + 1 * (r == 2)) % (len(para) + 1)
            if curs == 0:
                draw_string(action, int(160 - 5 * len(action)), 36, f)
            else:
                menu_option(curs - 1, f, True)
        elif r in (0, 3) and curs != 0:
            chx[curs - 1] = chx[curs - 1] + 1 * (r == 3) - 1 * (r == 0)
            if chx[curs - 1] == 0:
                chx[curs - 1] = len(para[curs - 1]) - 1
            if chx[curs - 1] == len(para[curs - 1]):
                chx[curs - 1] = 1
            menu_option(curs - 1, f, True)


def start():
    fill_rect(0, 0, 320, 222, (255, 255, 255))
    global mode, ope, dif, rep
    try:
        mode, ope, dif, rep = menu("Automatismes en calcul mental", "Calculer [OK]",
                                        ["Mode", "Classique", "Rapide"],
                                        ["Opération(s)", "+", "-", "x", "/", "+ -", " x / ", "+ - x", "+ - x /"],
                                        ["Difficulté", "  modéré", "difficile", "expert", "facile"],
                                        ["Répétition", 42, 50, 100, 120, 20],
                                        ["Crédits", "Site web$nsi.xyz/calcul", "Auteur$Kevin Fedyna",
                                         "Contributeur$Vincent ROBERT", ])
        dif = ["f", " ", "d", "e"].index(dif[0])
    except:
        mode, ope, dif, rep = "Classique", "+", 1, 42
    aff(1)
    return 1


# Difficulte
da = [1, 9]
db = [10, 19]
dc = [1, 10]
dd = [dc, [2, 10]]
diff = {"+": [[da] * 2, [db, da], [db, da], [db] * 2],
        "-": [[da] * 2, [db, da], [[10, 20], [10, 20]], [db] * 2],
        "*": [[dc] * 2, [dc] * 2, [[2, 10], [11, 20]], [[1, 25], [1, 25]]],
        "/": [dd, dd, dd, [[1, 20], [2, 20]]]}


def mel(a, b):
    l = [a, b]
    a = l[rd(0, 1)]
    l.remove(a)
    b = l[0]
    return a, b


def draw_line(x, y, clr, *ts):
    for t in ts:
        d = list(map(lambda n: n // abs(n) if n != 0 else 0, t[0]))
        for i in range(t[1]):
            set_pixel(x + i * d[0], y + i * d[1], clr)
        x += i * d[0]
        y += i * d[1]


def inputG(x, y):
    inp = ""
    dico = {46: "-", 49: ".", 48: "0", 42: "1", 43: "2", 44: "3", 36: "4", 37: "5", 38: "6", 30: "7", 31: "8", 32: "9"}
    while 1:
        try:
            key = wait()
        except:
            fill_rect(0, 0, 320, 222, (255,255,255))
            draw_string("Merci d'avoir joué !",60,100)
            return "e"
        if key == 6:
            return "h"
        if key in dico:
            inp += dico[key]
        if inp:
            if key in (4,52) and (inp.count("-") == 0 or (inp.count("-") == 1 and inp[0] == "-")):
                return eval(inp)
            if key == 17:
                draw_string(" " * len(inp), x, y)
                inp = inp[:-1]
        draw_string(inp, x, y)


def aff(mde, prog=0, a=0, b=0, op="", c=0):
    global rep
    w = (255, 255, 255)
    if mde == 1:
        fill_rect(0, 0, 320, 222, w)
        fill_rect(0, 204, 320, 18, (200, 200, 200))
        for i in [-1, 1]:
            draw_line(160, 215, w, ([i, 0], 3), ([0, 1], 5), ([i, 0], 5), ([0, -1], 7), ([-i, -1], 7))
        draw_line(295,219,w,([1,0],10),([1,-1],5),([-1,-1],5),([-1,0],10),([1,1],5),([-1,-1],5),([1,-1],5))
        draw_string("Automatismes en calcul mental", 15, 8, (42, 120, 224))
    if mde == 2:
        fill_rect(0, 204, int(320 * (prog / rep)), 18, (42, 204, 120))
    if mde == 3:
        fill_rect(0,92,320,50,w)
        draw_string(str(a) + " " + op + " " + str(b) + " = ",180-10*len(str(a)+" "+op+" "+str(b)+" = "),98)
    if mde == 4:
        fill_rect(0,92,320,50,w)
        todraw = str(a) + " " + op + " " + str(b)
        draw_string(todraw + " = " + str(c),180-10*len(todraw + " = "),98,(251,77,61))
        draw_string(todraw + " = " + str(eval(todraw)),180-10*len(todraw + " = "),126,(42, 204, 120))
        wait()


def calcul():
    global ope,dif,rep,mode
    # Le generateur de calcul

    exeMu = list(range(1, 6))
    exeMu.append(10)
    exeDiv = [[2, 10], [2, 3, 5, 10]]

    juste = 0
    chrono = 0

    for i in range(rep):

        if len(ope) > 1:
            op = choice(ope.split(" "))
        else:
            op = ope
        if op == "x":
            op = "*"

        while "exceptions gérées":
            a, b = [rd(*diff[op][dif][i]) for i in [0, 1]]
            if op in "+-*":
                a, b = mel(a, b)
            if op == "*" and dif == 0:
                if a in exeMu and b in exeMu:
                    break
            elif op == "-" and dif == 0:
                if a >= b:
                    break
            elif op == "/":
                a = a * b
                if dif in [0, 1, 2] and a <= 100:
                    if dif in [0, 1] and b in exeDiv[dif]:
                        break
                    if dif == 2:
                        break
                if dif == 3 and a <= 200:
                    break
            else:
                break

        aff(2,i)
        c = "c"
        while c == "c":
            aff(3, a=a, b=b, op=op * (op != "*") + "x" * (op == "*"))
            depart = monotonic()
            c = inputG(180,98)
            chrono += monotonic()-depart
            if c == "e":
                return "e",0
            if c == "h":
                return "s",0

        if int(c) == int(eval(str(a) + op + str(b))):
            juste += 1
        else:
            if mode == "Classique":
                aff(4, a=a, b=b, op=op * (op != "*") + "x" * (op == "*"), c=c)

    return juste,str(round(chrono/rep,1))

while start():
    justes,temps = calcul()
    if justes == "e":
        break
    elif justes == "s":
        pass
    else:
        fill_rect(0, 0, 320, 222, (255,255,255))
        espace = 0
        for i in [str(rep)+" calculs",str(rep-justes)+" erreur"+"s"*((rep-justes)>1),str(justes)+" juste"+"s"*(justes>1)]:
            draw_string(i,190-len(i.split(" ")[0]+" ")*10,30+espace*28,((0,0,0),(251,77,61),(42, 204, 120))[espace])
            draw_string([mode,ope,["facile","modéré", "difficile", "expert"][dif]][espace],53,30+espace*28,(200,200,200))
            espace += 1
        fill_rect(53,118,214,22,(200, 200, 200))
        fill_rect(55,120,int((justes/rep)*210),18,(42, 204, 120))
        fill_rect(55+int((justes/rep)*210),120,int((1-(justes/rep))*210),18,(251,77,61))
        fill_rect(55+int((justes/rep)*210),120,2,18,(200,200,200))
        draw_string(temps+" secondes / calcul",160-5*len(temps+" secondes / calcul"),152,(200,200,200))
        wait()