summaryrefslogtreecommitdiff
path: root/gere_grille.py
blob: 073a584b6b8cea8e1d82043176c9b17a7a705386 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jul 26 22:58:28 2021

@author: sekhmet
"""
import random, zlib, base64, json
import gere_erreurs as e
from config import DEFAUT, CONFIG


def genere_grille(config, textes, liste_err):
    """ génère une grille avec des éléments aléatoires du tableau textes. 
    textes est un tableau de tableau : la catégorie, la phrase, puis les réponses
    Dans la grille on mettra une liste avec la question et les réponses
    Si y'a pas assez, on met la liste vide []
    
    config contient tout ce qu'on veut pour la grille, 
    ici on utilisera les dimensions et les phrases_additionnelles
    on enlève aussi les réponses si config['reponses_presentes'] n'est pas là
    et on vire les éléments qui ne sont pas de la bonne catégorie"""
    e.debug("Début de genere_grille, config : "+str(config), liste_err)
    e.debug("textes "+str(textes), liste_err)
    nblignes, nbcol = config["nblignes"], config["nbcolonnes"]
    
    
    soustab = config.get("phrases_add",[]).copy() # On met les phrases custom en premier
    soustab = soustab + [ [] ]*config["nbcasesvides"] # On ajoute les blocs vides voulus
    
    # Les textes dans lesquels on pioche, sans les catégories ni les trucs qu'on veut pas
    textes_propre = [] 
    categ = config.get("categories",[])
    #print(str(categ))
    for ligne in textes:
        if (ligne[0] in categ) or (categ == []) :
            # On met cette ligne
            if config.get("reponses_presentes", True): # Si on veut les réponses
                textes_propre.append(ligne[1:])
            else:
                textes_propre.append(ligne[1:2]) # Snas les réponses
    e.debug("textes_propre : "+str(textes_propre), liste_err)
    
    nbdata = nbcol*nblignes - config["nbcasesvides"]-len(config.get("phrases_add", [])) # Nombre d'entrées à prendre
    if nbdata>0: # Sinon y'a pas besoin du tableau
        if nbdata <= len(textes_propre):
            soustab = soustab+random.sample(textes_propre, nbdata)
        else: # on n'a pas assez de textes, on met des 0
            soustab = soustab + textes_propre + [ []]*(nbdata - len(textes_propre))
    
    e.debug("Avant mélange : "+str(soustab), liste_err)    
    #print(soustab)
    # On mélange !            
    random.shuffle(soustab) 
    
#    # Si on ne veut pas des réponses, on ne garde que le premier élément
#    if not(config.get("reponses_presentes", True)):
#        #print("Je veux pas les réponses !")
#        soustab = [ [elt[0] ] for elt in soustab ]
#        #print(soustab)


    # Créer la grille
    grille = [ [ [] ]*nbcol for i in range(nblignes)]
  
    # On met tout ça dans la grille
    for i in range(nblignes):
        for j in range(nbcol):
            grille[i][j] = soustab[i*nbcol+j]
            
    return grille

#######################" Encoder/décoder la grille et la configuration via l'URL ############

def encode_grille(config, grille, liste_err):
    """ grille est un tableau double qu'on veut sauvegarder.
    config est la configuration (on va garder le titre avec)
    Renvoie une chaîne de caractères qui encode cette grille
    de manière condensée. Renvoie une chaîne cheloue"""
    # Chaîne de caractère
    data = {"titre": config["titre"], "grille": grille, "score": config["score"].copy()}
    chaine = json.dumps(data)
    code = zlib.compress(chaine.encode())
    chaineencodee = str(base64.urlsafe_b64encode(code))
    e.debug(chaineencodee, liste_err)
    return chaineencodee[2:-1] # Enlever le b' devant et le ' à la fin

def decode_grille(chaineencodee, liste_err):
    """ l'inverse de la fonction précédente : renvoie le dictionnaire
    avec les params et la grille reconstituée
    """
    e.debug(chaineencodee, liste_err)
    b2 = base64.urlsafe_b64decode(chaineencodee)
    try:
        decodee = zlib.decompress(b2)
    except:
        e.erreur("Impossible de décoder la chaîne : "+chaineencodee, liste_err)
        return {}
    # Remettre ça en python
    data = json.loads(decodee)
    return data

########################### gestion des données web ###############################

def gere_donnees_custom(data, liste_err):
    """ data est le dictionnaire de requête. Gère les données reçues
    et en fait un dictionnaire propre, en mettant les défauts là où
    c'est pas bon"""
    
    conf =DEFAUT.copy()
    
    ## Le titre
    t = data.get("titre", "")
    if len(t) > 0:
        conf["titre"] = t[0:CONFIG["lmax_titre"]]
        
    # Les dimensions
    conf["nblignes"] = minimaxi(data.get("nblignes",""), CONFIG["minlignes"], CONFIG["maxlignes"], DEFAUT["nblignes"], liste_err)
    conf["nbcolonnes"] = minimaxi(data.get("nbcolonnes",""), CONFIG["mincolonnes"], CONFIG["maxcolonnes"], DEFAUT["nbcolonnes"], liste_err)
    
    # Les cases vides
    conf["nbcasesvides"] = minimaxi(data.get("nbcasesvides",""), 0, CONFIG["maxlignes"]*CONFIG["maxcolonnes"], DEFAUT["nbcasesvides"], liste_err)
    
    # Les phrases additionnelles
    conf["phrases_add"] = []
    i=0
    while "phrase_add_"+str(i) in data:
        p = data.get("phrase_add_"+str(i), "")
        if len(p)>1:
            conf["phrases_add"].append([p])
        i=i+1
    
    # Veut-on les réponses ?
    conf["reponses_presentes"] = gere_checkbox(data.get("reponses_presentes",""))
    
    # Liste des catégories
    conf["categories"] = []
    for (key, val) in data.items():
        if key[0:10] == "categorie_" and val=="on":
            conf["categories"].append(key[10:])
            
    # Score
    conf["score"] = {}
    for cle in DEFAUT["score"]:
        if "score_"+cle in data:
            conf["score"][cle] = minimaxi(data.get("score_"+cle, ""), 0, 2**31, DEFAUT["score"][cle], liste_err)
    
    e.debug(str(conf), liste_err)
    return conf

### Fonctions pour gérer les données saisies
def minimaxi(donnee, mini, maxi, defaut, liste_err):
    """ donnee est une chaine qui est censée être un nombre entier.
    On vérifie que la donnée est valide, qu'elle est bien dans l'inter
    valle mini, maxi et si ça foire on met le défaut"""
    try:
        x = int(donnee)
    except:
        e.warning("La donnée "+donnee+ "est invalide !", liste_err)
        x = defaut
    x = max(mini, min(x, maxi))
    return x

def gere_checkbox(donnee):
    """ renvoie True si la donnee est à "on" et False sinon"""
    return donnee == "on"