2013-08-25 27 views
5

Obecnie używam zmiennej globalnej w moim kodzie o nazwie correct. Biorąc pod uwagę, że globals są mile widziani, czy istnieje lepszy sposób na ustawienie mojego kodu, aby "chronić" zmienną globalną?Python: Kod reduktora do usunięcia globalnej zmiennej

from random import randint 
from random import choice 

lower = int(raw_input("Enter a lower integer constraint: ")) 
higher = int(raw_input("Enter a higher integer constraint: ")) 

correct = 0 


def gen_randoms(lower, higher): 
    integers = list() 
    for x in xrange(4): 
     rand_int = randint(lower, higher) 
     integers.append(rand_int) 
    return integers 


def gen_equation(integers): 
    nums = map(str, integers) 
    operators = ['*', '+', '-'] 
    equation = 'num op num op num op num' 
    while 'op' in equation: 
     equation = equation.replace('op', choice(operators), 1) 
    while 'num' in equation: 
     equation = equation.replace('num', choice(nums), 1) 
    print equation 
    return equation 


def evaluate(equation): 
    answer = eval(equation) 
    print answer 
    return answer 


def compare_answers(gen_answer, game): 
    global correct 
    user_answer = int(raw_input("What is the answer? ")) 
    if user_answer == gen_answer: 
     correct += 1 
     print 'Correct!' 
     print 'Current streak: %s' % str(correct) 
     game() 
    else: 
     print 'Incorrect!' 
     correct = 0 
     game() 


def game(): 
    nums = gen_randoms(lower, higher) 
    this_equation = gen_equation(nums) 
    gen_answer = evaluate(this_equation) 
    compare_answers(gen_answer, game) 


game() 
+0

Czy to jest wejście i powrót z funkcji compare_answers()? – Jiminion

+0

Najprostszym sposobem jest wstawienie 'compare_answers()' do 'game()' i przeniesienie zmiennej 'correct' również do' game() '. – Nayuki

+0

Również fakt, że używasz rekursji tail w 'game()' i 'compare_answers()' oznacza, że ​​w końcu skończy ci się przestrzeń stosu. – Nayuki

Odpowiedz

3

pewnie bym zrobić coś takiego:

#!/usr/bin/python 

"""Equation solving game.""" 

from random import randint 
from random import choice 


def gen_randoms(lower, higher): 

    """Generates four random numbers between provided bounds.""" 

    integers = [randint(lower, higher) for x in range(4)] 
    return integers 


def gen_equation(integers): 

    """Generates a random equation from four provided integers.""" 

    nums = [str(i) for i in integers] 
    operators = ['*', '+', '-'] 
    equation = 'num op num op num op num' 
    while 'op' in equation: 
     equation = equation.replace('op', choice(operators), 1) 
    while 'num' in equation: 
     equation = equation.replace('num', choice(nums), 1) 
    return equation 


def evaluate(equation): 

    """Evaluates an equation.""" 

    return eval(equation) 


def main(): 

    """Main game function.""" 

    lower = int(raw_input("Enter a lower integer constraint: ")) 
    higher = int(raw_input("Enter a higher integer constraint: ")) 
    nums = gen_randoms(lower, higher) 
    streak = 0 

    while True: 
     this_equation = gen_equation(nums) 
     print this_equation 

     user_answer = raw_input("What is the answer? ('Q' to quit) ") 

     if user_answer.lower()[0] == 'q': 
      break 

     gen_answer = evaluate(this_equation) 
     print 'The answer was: %d' % gen_answer 

     if gen_answer == int(user_answer): 
      streak += 1 
      print 'Correct!' 
      print 'Current streak: %d' % streak 
     else: 
      streak = 0 
      print 'Incorrect!' 


if __name__ == "__main__": 
    main() 

Kilka uwag:

  • Każda funkcja powinna generalnie zrobić tylko jedno, więc jeśli funkcja ocenia równanie, to zazwyczaj lepiej nie mieć tego, żeby wydrukować równanie.
  • Ustalenie, gdzie zmienne powinny się udać, staje się o wiele łatwiejsze, gdy robisz to, ponieważ nie musisz przekazywać ich tak często, jak musisz, gdy każda funkcja wykonuje kilka różnych czynności.
  • Główna logika gry jest na tyle prosta, że ​​tak naprawdę nie trzeba jej wyrzucać z głównej funkcji game() (lub main(), w moim przykładzie), nie komplikuje to zbyt wielu rzeczy, aby ją zostawić . Jeśli chcesz zrobić jeszcze więcej sprawdzania błędów (np. Sprawdzając, czy użytkownik wprowadził nieprawidłowy numer, i chcesz wrócić i poprosić o więcej danych wejściowych, jeśli tak), to możesz chcieć go trochę rozłożyć.
1

coś takiego:

def game(correct=0):  
    nums = gen_randoms(lower, higher) 
    this_equation = gen_equation(nums) 
    gen_answer = evaluate(this_equation) 
    correct = compare_answers(gen_answer, game, correct) 
    game(correct) 
0

Dodaj to:

def game(): 
    correct = 0 
    while True: 
     nums = gen_randoms(lower, higher) 
     this_equation = gen_equation(nums) 
     gen_answer = evaluate(this_equation) 
     user_answer = int(raw_input("What is the answer? ")) 
     if user_answer == gen_answer: 
      correct += 1 
      print 'Correct!' 
      print 'Current streak: %s' % str(correct) 
     else: 
      print 'Incorrect!' 
      correct = 0 

Następnie usunąć te fragmenty starego kodu: game(), compare_answers(), a zmienna globalna correct.

0
  1. usunąć global correct z compare_answers
  2. ustawić game podjąć w argumencie kluczowego correct z domyślnej wartości 0. def game(correct =0)
  3. ustawić compare_answers wziąć trzeci argument correct
  4. Dzwoniąc game z compare_answers przejściu w correct

tj:

def compare_answers(gen_answer, game, correct): 
    user_answer = int(raw_input("What is the answer? ")) 
    if user_answer == gen_answer: 
     correct += 1 
     print 'Correct!' 
     print 'Current streak: %s' % str(correct) 
     game(correct) 
    else: 
     print 'Incorrect!' 
     correct = 0 
     game(correct) 


def game(correct = 0): 
    nums = gen_randoms(lower, higher) 
    this_equation = gen_equation(nums) 
    gen_answer = evaluate(this_equation) 
    compare_answers(gen_answer, game, correct) 


game() 
0

skończyło się na wyciągnięciu @ sugestią JoelCornett oraz stworzenie klasa:

from random import randint 
from random import choice 

class Math_Problem_Generator(object): 

    def __init__(self): 
     self.lower = int(raw_input("Enter a lower integer constraint: ")) 
     self.higher = int(raw_input("Enter a higher integer constraint: ")) 
     self.correct = 0 
     self.game(self.correct) 


    def gen_randoms(self, lower, higher): 
     integers = list() 
     for x in xrange(4): 
      rand_int = randint(lower, higher) 
      integers.append(rand_int) 
     return integers 


    def gen_equation(self, integers): 
     nums = map(str, integers) 
     operators = ['*', '+', '-'] 
     equation = 'num op num op num op num' 
     while 'op' in equation: 
      equation = equation.replace('op', choice(operators), 1) 
     while 'num' in equation: 
      equation = equation.replace('num', choice(nums), 1) 
     print equation 
     return equation 


    def evaluate(self, equation): 
     answer = eval(equation) 
     print answer 
     return answer 


    def compare_answers(self, gen_answer): 
     user_answer = int(raw_input("What is the answer? ")) 
     if user_answer == gen_answer: 
      self.correct += 1 
      print 'Correct!' 
      print 'Current streak: %s' % str(self.correct) 
      self.game(self.correct) 
     else: 
      print 'Incorrect!' 
      self.correct = 0 
      self.game(self.correct) 


    def game(self, correct): 
     nums = self.gen_randoms(self.lower, self.higher) 
     this_equation = self.gen_equation(nums) 
     gen_answer = self.evaluate(this_equation) 
     self.compare_answers(gen_answer) 
     self.game() 


Math_Problem_Generator() 
+2

FYI, podczas gdy to działa, to naprawdę nie jest dobre OOP, i jest to po prostu program proceduralny lekko zawinięty w składnię OOP. Na przykład trzy z pięciu metod (z wyjątkiem '__init __()') nie uzyskują dostępu do żadnych danych instancji ani nie wywołują żadnych metod instancji, co sugeruje, że nie należą one do klasy. Usuwa problem zmiennych globalnych, ale w końcu zastępuje jedną złą praktykę drugą. –

+0

Czy nie jest również złym zwyczajem, aby pakiet '__init __()' wywoływał 'self.game()'? Powinieneś oddzielić 'game()' lub 'run()' od '__init() __'. Zawsze możesz go zadeklarować i uruchomić (anonimowo) jako jednolinijkową funkcją 'Math_Problem_Generator(). Run()' – smci

0

Zbierz wyniki w dzwoniącym, a następnie wydrukuj licznik. Ta wersja pozbywa się innych globali, lower i higher.

def compare_answers(gen_answer): 
    user_answer = int(raw_input("What is the answer? ")) 
    return user_anser == gen_answer 

def game(): 

    correct = 0 
    play_again = 'Y' 

    while play_again.lower() == 'y': 
     lower = int(raw_input("Enter a lower integer constraint: ")) 
     higher = int(raw_input("Enter a higher integer constraint: ")) 
     nums = gen_randoms(lower, higher) 
     this_equation = gen_equation(nums) 
     gen_answer = evaluate(this_equation) 
     if compare_answers(gen_answer): 
      correct += 1 
      print('You were right! Your winning streak is {0}'.format(correct)) 
     else: 
      print('Sorry, your answer was wrong. :(') 
      correct = 0 

     play_again = raw_input('Would you like to play again? (Y/N): ') 
Powiązane problemy