0

Ich bin sehr neu in Python.Problem zu vereinfachen sich wiederholende - mehrere wenn elif-Anweisungen und mehrere Schleifen in einer Funktion in Python

Ich bin ein überzeugter Anhänger des einfachen, prägnanten und effizienten algorithmischen Designs sowie des Kodierungsstils. Während ich Python lerne, merke ich, dass Python eine Menge Dinge hinter der Szene macht, so dass die Sprache selbst für Programmierer sehr freundlich ist. Das ist schön, aber ich wollte genau darüber lernen, welche Optimierungen ich beim Codieren machen oder beibehalten kann. Und heute geriet ich in Schwierigkeiten, meinen Code zu vereinfachen.

Die folgende Funktion wird verwendet, um leere Punkte auf einem Sudoku-Board basierend auf dem gewählten Schwierigkeitsgrad zu erstellen.

Hier ist mein 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 

Wie Sie es ist sehr repetitiv sehen. Jede Idee zur Vereinfachung oder ein effizienterer Codierungsstil wird geschätzt.

Gibt es auch eine bessere Möglichkeit, eine Klasse in Python zu initialisieren, anstatt __init__() in Bezug auf Leistung und Speichernutzung aufzurufen? Genau wie in C++ gibt es eine Initialisierungsliste, wo es sauberer und schneller ist.

Bitte zögern Sie nicht, auf die Fehler, die ich gemacht habe, hinzuweisen. Jeder Rat wird sehr geschätzt. Danke

Antwort

1

Da die einzige Sache, die sich ändert, ist die Auswahl der Zahlen, von denen ich empfehle, ein Diktat zu schaffen, wo Schwierigkeit zu dieser Nummer dann das Verwenden in einer einzelnen Funktion bildet, die die Zahlen festlegt.

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

Das ist ein gültiger Punkt, ich werde meine Antwort aktualisieren, um genau das zu tun! – MattWBP

+0

Gibt es eine andere Leistung mit 'dict.get' oder es ist einfach sauberer? –

+0

Nicht sicher über schneller, obwohl in diesem Fall weniger Code ist. Obwohl ich verstehe, dass es sicherer ist - da es garantiert, einen Wert für diesen Diktatschlüssel zurückzugeben, auch wenn er nicht existiert (Sie erhalten None als Standard). Auf diese Weise treffen Sie keine Ausnahme. – MattWBP

1

Sie könnten eine Prüfmethode Ihnen Klasse hinzufügen:

# 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 

Dann können Sie einfach Sie Parameter an Ihre Methode übergeben werden:

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

Slots sind ein effektiver Weg zur Reduzierung Speichernutzung Usage of __slots__?

+0

Ich lese gerade die Dokumentation über '__slots__'. Ich habe viel gelernt, Danke! –

0

Eine Option ist das Verschieben die Parameter von Code zu Daten und arbeiten dann mit den Daten:

# 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

Mit Quelle von woanders meinst du, ich könnte ein anderes Modul erstellen und die Wörterbücher dort hinstellen/oder eine .txt-Datei erstellen und sie dort hinein schreiben? Welches Keyword sollte ich beim Sourcing verwenden, ** Import ** oder ** mit **? Und welchen Vorteil hat Sourcing? –

+0

Beide sind gültige Optionen; Es hängt davon ab, wie Sie diese Daten generieren/verwalten möchten und ob Sie in der Lage sein möchten, Schwierigkeiten neu zu laden, ohne Ihr Programm neu starten zu müssen. Wenn Sie nicht vorhaben, es viel komplexer als die oben genannten zu machen, können Sie genauso gut die Objekte in diesem Modul behalten, was effektiv @ MattWBPs Antwort ist. Der Vorteil der Trennung von Daten vom Code besteht darin, dass sich beide unabhängig voneinander entwickeln können.Sie können die Bereichsgröße (oder andere zukünftige Parameter) einstellen, ohne den Code ändern zu müssen. Es ermöglicht auch das Nachladen von Schwierigkeiten bei Bedarf. – tavnab

Verwandte Themen