0

Je suis très nouveau à Python. Je suis un fervent partisan de la conception algorithmique simple, concise et efficace ainsi que du style de codage. Au fur et à mesure que j'apprends Python, je réalise que Python fait beaucoup de choses derrière la scène pour que le langage lui-même soit super sympa pour les programmeurs. C'est sympa mais je voulais en savoir plus sur les optimisations que je peux faire ou garder une habitude lors du codage. Et aujourd'hui, j'ai eu des problèmes pour simplifier mon code.Problème simplifiant répétitif - multiple si les déclarations elif et plusieurs boucles dans une fonction en python

La fonction suivante est utilisée pour créer des points vides sur une carte de sudoku en fonction du niveau de difficulté choisi.

Voici mon code:

class normalSudoku(Board): 
    def __init__(self,difficulties): 
     super.__init__() 
     self.Create_Empty_Entries(difficulties) 


    def Create_Empty_Entries(self,difficulties): 
     numbers = list(range(0,9)) 
     if difficulties == "Easy": 
      for x in range(25): 
       a,b = choice(numbers),choice(numbers) 
       if self.sudoku[a][b] != None: 
        self.sudoku[a][b] = None 
        self.holes += 1 
       self.holes += 1 
      return None 

     elif difficulties == "Medium": 
      for x in range(35): 
       a,b = choice(numbers),choice(numbers) 
       if self.sudoku[a][b] != None: 
        self.sudoku[a][b] = None 
        self.holes += 1 
      return None 

     elif difficulties == "Hard": 
      for x in range(45): 
       a,b = choice(numbers),choice(numbers) 
       if self.sudoku[a][b] != None: 
        self.sudoku[a][b] = None 
        self.holes += 1 
      return None 

     else: 
      for x in range(65): 
       a,b = choice(numbers),choice(numbers) 
       if self.sudoku[a][b] != None: 
        self.sudoku[a][b] = None 
        self.holes += 1 
      return None 

Comme vous pouvez le voir, il est très répétitif. Toute idée de simplification ou un style de codage plus efficace sera apprécié.

De même, existe-t-il une meilleure façon d'initialiser une classe en python plutôt que d'appeler __init__() en termes de performances et d'utilisation de la mémoire? Tout comme en C++, il y a une liste d'initialisation où elle est plus propre et plus rapide.

N'hésitez pas à signaler les erreurs que j'ai commises. Tout conseil sera grandement apprécié. Merci

Répondre

1

Comme la seule chose qui change est la gamme de nombres choisis, je vous recommande de créer un dict où la difficulté correspond à ce nombre puis de l'utiliser dans une seule fonction qui définit les nombres.

class normalSudoku(Board): 
    def __init__(self,difficulties): 
     super.__init__() 
     self.Create_Empty_Entries(difficulties) 


    def Create_Empty_Entries(self,difficulties): 
     numbers = list(range(0,9)) 
     difficulty_values = {'Easy':25,'Medium':35, 'Hard':45, 'Default':65} 

     # check the difficulty level exists in the dict. 
     # If it does, use that value, if it doesn't then use the default value 
      difficulty = difficulty_values.get(difficulties, difficulty_values['Default']) 

      # now use that difficulty to set the numbers once. 
      for x in range(difficulty): 
      a,b = choice(numbers),choice(numbers) 
      if self.sudoku[a][b] != None: 
       self.sudoku[a][b] = None 
       self.holes += 1 
      self.holes += 1 
    return None 
+0

C'est un point valide, je vais mettre à jour ma réponse pour faire exactement cela! – MattWBP

+0

Existe-t-il une performance différente utilisant 'dict.get' ou est-ce juste plus propre? –

+0

Pas sûr de plus rapide, bien que dans ce cas c'est moins de code. Bien que je comprenne que ce soit plus sûr - car il garantit de retourner une valeur pour cette clé dict même si elle n'existe pas (vous obtiendrez None par défaut). De cette façon, vous ne frappez pas une exception. – MattWBP

1

Vous pouvez ajouter une méthode de contrôle pour vous classe:

# add this to the class body 
def auto_increment(self, a, b): 
    if self.sudoku[a][b] != None: 
     self.sudoku[a][b] = None 
     self.holes += 1 
    self.holes += 1 
    return 

Ensuite, vous pouvez simplement vous passer des paramètres à votre méthode en utilisant:

self.auto_increment(choices(number), choices(number)) 

fentes sont un moyen efficace de réduire utilisation de la mémoire Usage of __slots__?

+0

Je viens de lire les documents sur '__slots__'. J'ai beaucoup appris, merci! –

0

Une option est de déplacer les paramètres du code à données, puis opérer sur les données:

# You could source these two dicts from elsewhere, like a JSON/YAML/config file 
difficulties = { 
    Easy: { 
    size: 25 
    }, 
    Medium: { 
    size: 35 
    }, 
    Hard: { 
    size: 45 
    } 
} 

defaultDifficulty = { 
    size: 65 
} 

# ... 

def Create_Empty_Entries(self, difficultyName): 
    if difficultyName in difficulties: 
    difficulty = difficulties[difficultyName] 
    else: 
    difficulty = defaultDifficulty 

    numbers = list(range(0,9)) 
    for x in range(difficulty.size): 
    a,b = choice(numbers),choice(numbers) 
    if self.sudoku[a][b] != None: 
     self.sudoku[a][b] = None 
     self.holes += 1 
+0

Par source d'ailleurs voulez-vous dire que je pourrais créer un autre module et y mettre les dictionnaires/ou créer un fichier .txt et les écrire là? Quel mot-clé devrais-je utiliser pour les rechercher, ** importer ** ou ** avec **? Et quel est l'avantage de l'approvisionnement? –

+0

Les deux sont des options valides; cela dépend de la façon dont vous voulez générer/maintenir ces données, et si vous voulez pouvoir recharger des difficultés sans redémarrer votre programme. Si vous ne prévoyez pas de le rendre beaucoup plus complexe que ce qui précède, vous pouvez tout aussi bien garder les objets dans ce même module, ce qui est effectivement la réponse de MattWBP. L'avantage de séparer les données du code est que les deux peuvent évoluer indépendamment les uns des autres.Vous pouvez régler la taille de la plage (ou d'autres paramètres futurs) sans avoir à changer de code. Il rend également possible le rechargement en direct des difficultés, si nécessaire. – tavnab