Passing Tuples to Methods?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Megadeus
    New Member
    • Jun 2007
    • 4

    #1

    Passing Tuples to Methods?

    Okay, I've been programming for awhile in many different languages, but my current obsession is Python. Whenever I get into a new language, I usually write a small program, usually in the form of a dice roller.

    My Python dice roller is probably the best I've done yet (rivaling my mIRC script one ^_~), and I'm thrilled that I've been able to use string-splitting functions rather than regular expressions to allow multiple dice combinations. The user specifies a number of dice and number of sides in the form XdY, with the lowercase 'd' separating the two. The user can also put multiple rolls in the same command, which is the part I'm really proud of. The format for this is XdY,MdN,PdQ, etc.

    The part I'm looking to improve is the current version returns each die roll as its own string to the terminal. I want to pass the "roll" function a tuple (or something similar) and have the roll function output all the rolls as a single line to the terminal.

    Here's the source code.

    [code=Python]
    #! /usr/bin/python

    import random
    import re

    def roll(dice = 1, sides = 6):
    array = [0] * dice # array stores the results
    total = 0 # total stores the running count of the dice
    output = "* On a roll of " # Contains the beginning of the output string
    for pos in range(dice):
    array[pos] = random.randint( 1, sides)
    total += array[pos] # add the roll to the total

    output += str(dice) + "d" + str(sides) + " you rolled "
    output += str(array) + " Total: " + str(total)
    print output

    print "* Input number of dice to roll (XdY), type quit to exit."

    rollString = ""

    while rollString.lowe r() not in ("quit", "exit"):
    rollString = raw_input("* How many dice to roll? Type \"quit\" to exit. ")
    rollString = rollString.lowe r()
    if rollString in ("quit", "exit"):
    break
    rollString = rollString.spli t(',')

    for x in rollString:
    splitString = x.split('d') #split the string at 'd'
    if(splitString[1]) == "%":
    splitString[1] = 100
    try:
    roll(int(splitS tring[0]), int(splitString[1]))
    except ValueError:
    roll(1, int(splitString[1]))
    rollString = ""
    [/code]

    And here's a sample run:
    Code:
    * Input number of dice to roll (XdY), type quit to exit.
    * How many dice to roll? Type "quit" to exit. 3d6
    * On a roll of 3d6 you rolled [3, 4, 6] Total: 13
    * How many dice to roll? Type "quit" to exit. 2d4,2d6,1d8
    * On a roll of 2d4 you rolled [2, 4] Total: 6
    * On a roll of 2d6 you rolled [5, 5] Total: 10
    * On a roll of 1d8 you rolled [5] Total: 5
    * How many dice to roll? Type "quit" to exit. quit
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    You may find this to be a very cool feature of python:[CODE=python]
    >>> def TakeAnyArgs(*ar gs):
    ... for arg in args:
    ... print arg
    ...
    >>> TakeAnyArgs(1, 3, 5)
    1
    3
    5
    >>> t = ('a', 'tuple', 'of', 'args')
    >>> TakeAnyArgs(*t)
    a
    tuple
    of
    args
    >>> [/CODE]
    I'll have a look around the forum for recent thread on this topic.

    Welcome to the Python Forum on TheScripts.com!

    Comment

    • bartonc
      Recognized Expert Expert
      • Sep 2006
      • 6478

      #3
      Originally posted by bartonc
      You may find this to be a very cool feature of python:[CODE=python]
      >>> def TakeAnyArgs(*ar gs):
      ... for arg in args:
      ... print arg
      ...
      >>> TakeAnyArgs(1, 3, 5)
      1
      3
      5
      >>> t = ('a', 'tuple', 'of', 'args')
      >>> TakeAnyArgs(*t)
      a
      tuple
      of
      args
      >>> [/CODE]
      I'll have a look around the forum for recent thread on this topic.

      Welcome to the Python Forum on TheScripts.com!
      Here is the thread that I was looking for.

      Comment

      • bvdet
        Recognized Expert Specialist
        • Oct 2006
        • 2851

        #4
        Take a look at this:[code=Python]import random
        import re

        def rollMulti(rollS tr):
        patt = re.compile(r'\d +d\d+', re.IGNORECASE)
        rolls = rollStr.split(' ,')
        # validate each item in rolls with re expression
        rolls = [roll.strip() for roll in rolls if patt.match(roll .strip())]
        # split on 'd' or 'D'
        rollList = [(int(i), int(j)) for i,j in [re.split('[dD]',item) for item in rolls]]
        outList = []
        for roll in rollList:
        outList.append([random.randint( 1, roll[1]) for i in range(roll[0])])
        return '\n'.join(['* On a roll of %s, you rolled %s. Total: %d' % \
        (rolls[i], outList[i], sum(outList[i])) for i in range(len(rolls ))])

        rollStr = '4d6, 5D6,8H7,4d5,9d9 '
        print rollMulti(rollS tr)

        '''
        >>> * On a roll of 4d6, you rolled [5, 5, 4, 2]. Total: 16
        * On a roll of 5D6, you rolled [5, 3, 4, 1, 1]. Total: 14
        * On a roll of 4d5, you rolled [2, 5, 1, 1]. Total: 9
        * On a roll of 9d9, you rolled [5, 9, 4, 4, 6, 8, 3, 5, 5]. Total: 49
        >>>
        '''[/code]

        Comment

        • Megadeus
          New Member
          • Jun 2007
          • 4

          #5
          Wow, that's pretty good!

          What I was hoping to accomplish, however, was output closer to the following:

          Code:
          You rolled 7,12,11 using 3d4,2d8,4d6 ((3,2,2,8,4,1,3,6,1)).
          or ideally, like this:

          Code:
          You rolled 7,12,11 using 3d4,2d8,4d6 ((3,2,2),(8,4),(1,3,6,1)).

          Comment

          • bartonc
            Recognized Expert Expert
            • Sep 2006
            • 6478

            #6
            Originally posted by Megadeus
            Wow, that's pretty good!

            What I was hoping to accomplish, however, was output closer to the following:

            Code:
            You rolled 7,12,11 using 3d4,2d8,4d6 ((3,2,2,8,4,1,3,6,1)).
            or ideally, like this:

            Code:
            You rolled 7,12,11 using 3d4,2d8,4d6 ((3,2,2),(8,4),(1,3,6,1)).
            Nice work on the regex, there BV. For the second output I used:[CODE=python]import random
            import re

            def rollMulti(rollS tr):
            patt = re.compile(r'\d +d\d+', re.IGNORECASE)
            rolls = rollStr.split()

            # validate each item in rolls with re expression
            rolls = [roll for roll in rolls if patt.match(roll )]

            # split on 'd' or 'D'
            rollList = [(int(i), int(j)) for i, j in [re.split('[dD]',item) for item in rolls]]
            outList = []

            for roll in rollList:
            outList.append([random.randint( 1, roll[1]) for i in range(roll[0])])

            return 'You roled %s, using %s (%s)' % \
            (
            ', '.join(["%d" %(sum(outList[i])) for i in range(len(rolls ))]),
            ', '.join(rolls),
            ', '.join([str(tuple(l)) for l in outList])
            )

            rollStr = '4d6 5D6 8H7 4d5 9d9'
            print rollMulti(rollS tr)
            [/CODE]to get
            You roled 15, 12, 17, 41, using 4d6, 5D6, 4d5, 9d9 ((6, 4, 2, 3), (2, 6, 1, 1, 2), (5, 3, 5, 4), (2, 1, 6, 3, 8, 6, 4, 6, 5))

            Comment

            • bartonc
              Recognized Expert Expert
              • Sep 2006
              • 6478

              #7
              Originally posted by bartonc
              Nice work on the regex, there BV. For the second output I used:[CODE=python]import random
              import re

              def rollMulti(rollS tr):
              patt = re.compile(r'\d +d\d+', re.IGNORECASE)
              rolls = rollStr.split()

              # validate each item in rolls with re expression
              rolls = [roll for roll in rolls if patt.match(roll )]

              # split on 'd' or 'D'
              rollList = [(int(i), int(j)) for i, j in [re.split('[dD]',item) for item in rolls]]
              outList = []

              for roll in rollList:
              outList.append([random.randint( 1, roll[1]) for i in range(roll[0])])

              return 'You roled %s, using %s (%s)' % \
              (
              ', '.join(["%d" %(sum(outList[i])) for i in range(len(rolls ))]),
              ', '.join(rolls),
              ', '.join([str(tuple(l)) for l in outList])
              )

              rollStr = '4d6 5D6 8H7 4d5 9d9'
              print rollMulti(rollS tr)
              [/CODE]to get
              You roled 15, 12, 17, 41, using 4d6, 5D6, 4d5, 9d9 ((6, 4, 2, 3), (2, 6, 1, 1, 2), (5, 3, 5, 4), (2, 1, 6, 3, 8, 6, 4, 6, 5))
              In order to be able to call this from the command line, I'd give the function a list rather that a string:[CODE=python]from random import randint
              import re

              def rollMulti(rolls ):
              patt = re.compile(r'\d +d\d+', re.IGNORECASE)
              ## rolls = rollStr.split()

              # validate each item in rolls with re expression
              rolls = [roll for roll in rolls if patt.match(roll )]

              # split on 'd' or 'D'
              rollList = [(int(i), int(j)) for i, j in [re.split('[dD]',item) for item in rolls]]
              outList = []

              for roll in rollList:
              outList.append([randint(1, roll[1]) for i in range(roll[0])])

              return 'You roled %s, using %s (%s)' % \
              (
              ', '.join(["%d" %(sum(outList[i])) for i in range(len(rolls ))]),
              ', '.join(rolls),
              ', '.join([str(tuple(l)) for l in outList])
              )

              if __name__ == "__main__": # use this 'guard' so that you can import you function from another module
              import sys
              ## rollStr = '4d6 5D6 8H7 4d5 9d9'
              print rollMulti(sys.a rgv[1:])
              [/CODE]

              Comment

              Working...