INFO-H-100 : Introduction à la programmation Projet 1 : Boggle
Transcription
INFO-H-100 : Introduction à la programmation Projet 1 : Boggle
UNIVERSITE LIBRE DE BRUXELLES École Polytechnique de Bruxelles février 2014 INFO-H-100 : Introduction à la programmation Projet 1 : Boggle – Quelques erreurs récurrentes Lors du premier projet nous avons relevé certaines erreurs récurrentes. Pour vous permettre de ne plus les commettre à l’avenir, nous avons reproduit ci-dessous quelques extraits de code qui contiennent un ou plusieurs défauts. Nous vous proposons, en regard, des commentaires et une version “corrigée”. Exemple 1 def word_on_board(word, board): k=0 for i in range(len(board)): for j in range(len(board[0])): if (word_in_place(word,board,i,j)): k+=1 return k>0 Commentaires – Il suffit que la sous-fonction word_in_place renvoie True une fois pour que la fonction word_on_board doive retourner True. Il est dès lors inutile de continuer à parcourir la grille après qu’un appel de word_in_place ait renvoyé True. Dans l’exemple ci-dessus, il aurait donc été plus judicieux d’utiliser deux boucles while imbriquées, au lieu de boucles for. – La variable k est un entier, mais est utilisé comme un booléen. Veillez à utiliser des booléens plutôt que des entiers pour vérifier une condition. Notre proposition def word_on_board(word, board): found = False i = 0 while i<len(board) and not found: j = 0 while j<len(board) and not found: found = word_in_place(word,board,i,j) return found Exemple 2 def play_boggle(): dico=Bg.load_dico("dico.txt") tour,score=5,0 while tour>0: score+=play_one_round(dico) tour-=1 print("Votre score final est de ",score,plural("point",score)) if (Boggle_mod.ask_yes_no("Voulez-vous jouer une partie de Boggle ? :):")): play_boggle() Commentaires – Une partie est composée d’exactement cinq tours. Ce nombre étant connu et constant, il est plus adéquat d’utiliser une boucle for. – En fin de partie, le programme demande au joueur s’il veut jouer une autre partie. En cas de réponse positive, il y a un appel, au sein de la fonction play_boggle, à elle-même. Cette utilisation de la récursivité, même si elle fonctionne dans ce cas, n’est pas conseillée. Il aurait mieux valu utiliser une boucle while qui avait le même effet. Notre proposition def play_boggle(): dico = Boggle_mod.load_dico("dico.txt") play = True while play: 1 score = 0 for tour in range(5): score += play_one_round(dico) print("Votre score final est de ",score,plural("point",score)) play = Boggle_mod.ask_yes_no("Voulez-vous jouer une partie de Boggle ?:") Exemple 3 def dictionary(word): """ description: regarde si le mot est bien dans le dictionnaire input: word (string) output: x (bool) """ file_name = "dico.txt" dico = Boggle_mod.load_dico(file_name) if word.upper() in dico: x = True else: x = False return x Commentaires – La lecture répétée du dictionnaire à partir du fichier n’est pas très efficace. Mieux vaut le charger initialement et le passer en paramètre aux fonctions qui en ont besoin. – Le nom de variable x n’est pas très parlant. On n’en comprend pas la signification. – La condition if est inutile. La variable x reçevant la valeur booléenne qui doit être renvoyée par la fonction, il aurraît suffit de retourner la valeur de l’expression booléenne du if. Notre proposition def in_dico(dico, word): """ description: regarde si le mot est bien dans le dictionnaire input: dico (dictionnaire), word (string) output: (bool) True si le mot est trouvé dans dico. """ return word.upper() in dico Exemples 4 & 5 Les extraits suivants sont des exemples de code compliqué et difficilement lisible (même s’il s’exécute correctement et fournit les résultats attendus). Nous ne proposons pas de correction pour ces exemples. def next_is_adjacent(letter, board_nia, line_nia, col_nia, memory_nia): verify_nia=False # Checks the space at the bottom. if line_nia!=3 and letter==board_nia[line_nia+1][col_nia] and not(line_nia+1,col_nia) in memory_nia: verify_nia, line_nia = True, line_nia+1 elif line_nia!=0 and letter==board_nia[line_nia-1][col_nia] and not (line_nia-1,col_nia) in memory_nia: verify_nia, line_nia = True, line_nia-1 elif col_nia!=3 and letter==board_nia[line_nia][col_nia+1] and not (line_nia,col_nia+1) in memory_nia: # Checks the space at the right. verify_nia, col_nia = True, col_nia+1 elif col_nia!=0 and letter==board_nia[line_nia][col_nia-1] and not (line_nia,col_nia-1) in memory_nia: # Checks the space at the left. verify_nia, col_nia = True, col_nia-1 return(verify_nia, line_nia, col_nia) et def play_one_round(dico): board=shake() Boggle_mod.show_grid(board) word=writting_word() x=word_on_board(word, board) y=False z=True i=0 if x==True: line_or_col=search_first_letter_on_word(word,board) print(line_or_col) while i<len(line_or_col) and z==True: z=word_in_place(word,board,line_or_col[0][i],line_or_col[1][i]) i+=1 if z==True: y=word_in_dico(word) 2 s=0 if y==True: s=score(word) elif x==False: s=0 print("Ce mot n'est pas dans le tableau") return s Commentaires – La lecture et la compréhension du premier exemple sont rendus très compliquées par le fait que, pour respecter la limite des 10 lignes : 1. l’expression booléenne teste trois conditions. 2. les assignations sont faites sous forme de tuples. – Pour le deuxième exemple, nous avons surtout voulu mettre en évidence la difficulté de lire un code dont les noms choisis pour les variables sont abscons. En particulier, il est difficile de comprendre la signification “logique” des variables x, y et z. 3