Как вы можете вернуть несколько переменных, определенных и инициированных в функции в Python? - PullRequest
0 голосов
/ 22 января 2012

, поэтому мой код выглядит так:

def parse(info):
    """
    'info' is a list made out of data received (info = list(data)). Examples are as follows:
    ['NEWGAME', '1', 'testbot', 'testbot', '100', '200', '2', '1', '10000.00000']
    ['NEWHAND', '1', '0', '4c', '5d', '0', '0', '0', '10000.00000']
    ['GETACTION', '3', '0', '2', 'POST:testbot:1,POST:testbot:2', '3', 'FOLD,CALL,RAISE:4', '10000.0']
    ['HANDOVER', '0', '0', '0', '3', 'FOLD:bot3001,FOLD:testbot,WIN:testbot:3', '9999.9506']
    """
    phase = info[0]   # setting board cards to 0
    boardCard1 = 0    # 0 means no card
    boardCard2 = 0
    boardCard3 = 0
    boardCard4 = 0
    boardCard5 = 0
    if phase == "NEWGAME":
        gameID = int(info[1])  # Game ID
        leftOpp = info[2]  # Left Opponent
        rightOpp = info[3]  # Right Opponent
        maxHands = int(info[4]) #Initializing number of hands that will be played
        maxStackSize = int(info[5]) # Stack size, also the maximum bet size
        bigBlind = int(info[6])
        smBlind = int(info[7])
        maxTime = float(info[8])  # Initiallizing milliseconds of time allocated for the game
        return (phase, gameID, leftOpp, rightOpp, maxHands, maxStackSize, bigBlind, smBlind, maxTime)
    if phase == "NEWHAND":
        handID = int(info[1]) # The hand number which we're currently at
        position = int(info[2]) # Possition, either 0, 1, or 2. 0 = dealer, 1 = smalll blind, 2 = big blind
        card1 = info[3]              # Card 1
        card1Rank = (list(info[3]))[0] # Rank of Card 1
        card1Suit = (list(info[3]))[1] # Suit of Card 1
        card2 = info[4]              # Card 2
        card2Rank = (list(info[4]))[0] # Rank of Card 2
        card2Suit = (list(info[4]))[1] # Suit of Card 2
        hand = [card1, card2]        # A list containing the 2 cards in your hand
        bankRoll = int(info[5])    # Your bank roll, total amount made (can be negative)
        leftOppBank = info[6]   # Left Opponent's bankroll
        rightOppBank = info[7]  # Right Opponent's bankroll
        timeLeft = float(info[8])  # Milliseconds of time allocated for the game
        boardPhase = "PREFLOP"     # Initializing boardPhase
        return(boardPhase, phase, handID, position, card1, card1Rank, card1Suit, card2, card2Rank, card2Suit, hand, bankRoll, leftOppBank, rightOppBank, timeLeft)
    elif phase == "GETACTION":
        potSize = int(info[1])
        numBoardCards = int(info[2]) # can be 0,3,4 or 5
        boardCardsPacket = 0    # 0 for none, 1 for present
        boardCards =[]
        if numBoardCards != 0:       
            boardCardsPacket = 1
            boardCards = (info[4]).split(",")   # info[4] looks like 'Th,Ad,Js,5h' and split(",") turns it into [Th, Ad, Js, 5h]
            boardCard1 = boardCards[0]
            boardCard2 = boardCards[1]
            boardCard3 = boardCards[2]
            try:
                boardCard4 = boardCards[3]
                try:
                    boardCard5 = boardCards[4]
                except:
                    pass
            except:
                pass
        numLastActions = int(info[3+boardCardsPacket])
        lastActions = []
        if numLastActions != 0:
            actionsString = info[4+boardCardsPacket] # a string of actions ex: POST:testbot:1,POST:testbot:2
            lastActions = actionsString.split(",")         # A list of the actions ex: ['POST:testbot:1','FOLD:testbot','WIN:testbot:3']
        for i, item in enumerate(actions):
            if "DEAL" in item.split(":"):
                boardPhase = item.split(":")[1]
        numLegalActions = int(info[5+boardCardsPacket])
        legalActions = (info[6+boardCardsPacket]).split(",") # List of Legal Actions, ex: ['FOLD', 'CALL', 'RAISE:4']
        minBet = "NULL"   # it will be NULL if BET is not a legal action.
        for i, item in enumerate(legalActions):
            if "BET" in item.split(":"):
                minBet = item.split(":")[1]
        minRaise = "NULL"
        for i, item in enumerate(legalActions):
            if "RAISE" in item.split(":"):
                minRaise = item.split(":")[1]        
        realLegalActions = []
        for item1 in legalActions:
            for item2 in item1.split(":"):    # this creates realLegalActions which will not include numbers, will look like ['FOLD','CALL', 'RAISE'], makes it easier to check if an action is in legalActions
                try:
                    int(item2)
                except:
                    realLegalActions.append(item2)       
        timeLeft = float(info[7+boardCardsPacket])
        try:                                             # If the boardPhase is still PREFLOP then there is no variable boardPhase to return, so we have an exception for that.
            return (realLegalActions, minBet, timeLeft, boardPhase, legalActions, numLegalActions, lastActions, numLastActions, boardCardsPacket,
                    boardCards, boardCard1, boardCard2, boardCard3, boardCard4, boardCard5, potSize, numBoardCards, minRaise)
        except:
            return (realLegalActions, minBet, timeLeft, legalActions, numLegalActions, lastActions, numLastActions, boardCardsPacket,
                    boardCards, boardCard1, boardCard2, boardCard3, boardCard4, boardCard5, potSize, numBoardCards, minRaise)
    elif info[0] == "HANDOVER":
        bankRoll = int(info[1])
        leftOppBank = int(info[2])
        rightOppBank = int(info[3])
        numLastAction = int(info[4])
        LastActions =[]
        if numLastAction!=0:
            LastActions = (info[5]).split(",")
        timeLeft = float(info[6])
        return(numLastAction, timeLeft, bankRoll, leftOppBank, rightOppBank, LastActions)    

Как я могу использовать все переменные, которые я возвращаю? Какой будет самый простой способ? Должен ли я создать класс (я не слишком хорош в использовании классов, но я пересмотрю свой код, если это возможно с классами)?

редактировать ---- Я просто хочу проанализировать строки и затем вернуть все переменные, чтобы я мог использовать их в других классах и функциях. Это основная функция, которая его импортирует:

import socket
import sys
import pokerParser
from time import time
import betMaster
import historian


if __name__ == "__main__":
    port = int(sys.argv[1])
    s = socket.create_connection(('127.0.0.1', int(sys.argv[1])))
    f_in = s.makefile()
    while 1:
        start = time() # converting from seconds to miliseconds
        data = f_in.readline()
        if not data:
            print "Gameover, engine disconnected"
            break
        info = data.split()
        pokerParser.parse(info)
        if phase == "HANDOVER":
            historian.lastActionInitiator(lastActions)
        if phase == "GETACTION":
            if (timeLeft/handsRemaining) < (maxTime*.90)/maxHands:
                output = "NULL" #Null is not a legalAction so it will be changed to CHECK or FOLD later.
                while (maxTime-(time()-startTimeelapsedTime)*1000)*.90/(handsRemaining-1): #This will set the cutoff time for a response at a time that will set the bot back on track time-wise.
                    #output = jonsModule.attribute()
            else:
                while (time()-startTime)*1000 < (maxTime*.90)/maxHands:
                    #output = jonsModule.attribute()  
            #if output.split(":")[0] not in realLegalActions and "CHECK" in realLegalActions:
                #output = "CHECK"
            #if output.split(":")[0] == "BET":
                #if output.split(":")[1] < minBet:
                    #output = "CHECK"
            #if output.split(":")[0] == "RAISE":
                #if output.split(":")[1] < minRaise:
                    #output = "CHECK"        
            #elif output not in legalActions and "CHECK" not in legalActions:
                    #output = "FOLD"
            #s.send(output)
    s.close()

# commented = dummy code for now

Ответы [ 4 ]

2 голосов
/ 22 января 2012
def test():
  return 1, 2, 3

a, b, c = test()  # a=1, b=2, c=3

Кстати, вам не нужно возвращать кортежи.

1 голос
/ 17 февраля 2012

Проще всего вернуть местных жителей ()

>>> def myfunction():
...    a = 1
...    b = 2
...    c = 3
...    return locals()
...
>>> print myfunction()
{'a': 1, 'c': 3, 'b': 2}
0 голосов
/ 22 января 2012

Короткий ответ

Вы можете возвращать переменные из методов Python любым способом, который имеет смысл для вас или для вашей намеченной цели. Это может быть единственное значение, кортеж, словарь, новый класс или вообще ничего - в зависимости, конечно, от вашего намерения.

Длинный ответ (что может быть проблемой CodeReview)

В таком контексте вы столкнетесь с проблемой, в которой слишком много переменных, определенных для отслеживания различных вещей. Это может быть старой привычкой использовать локальные переменные для отслеживания вещей, но в Python, поскольку у вас есть список (и вы документируете, что каждая позиция в списке представляет где-то), вы можете просто использовать это явно вместо этого.

Пример:

if phase == "NEWGAME":
    return tuple([i for i in info[1:]]) # Returns everything in info except "NEWGAME"

Вопрос в том, каковы цели и объем вашего кода. Я бы решительно рекомендовал бы вам сесть и реорганизовать свой код, чтобы он был понятен по своему намерению (не только для нас, но и для вас), и каждая функция является определенной и четко определенной по назначению.

0 голосов
/ 22 января 2012

Если вы хотите вернуть несколько значений и кортеж не будет работать, вы можете вместо этого вернуть словарь:

{name1: value1, name2: value2, ...}

Затем становится легко проверить, была ли возвращена какая-то переменная, или нет, используя:

if name in returnvalues:

(Все это предполагает, что вы не просто полностью реорганизуете свой сценарий, что выглядит хорошей идеей)

...