calcul_se.py

Created by fedyna-kevin

Created on April 18, 2020

6.01 KB


# Calcul Mental - V. 2.0.0.0

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

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 calculé !",45,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()