By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,446 Members | 3,090 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,446 IT Pros & Developers. It's quick & easy.

Passing Tuples to Methods?

Megadeus
P: 4
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.

Expand|Select|Wrap|Line Numbers
  1. #! /usr/bin/python
  2.  
  3. import random
  4. import re
  5.  
  6. def roll(dice = 1, sides = 6):
  7.     array = [0] * dice        # array stores the results
  8.     total = 0            # total stores the running count of the dice
  9.     output = "* On a roll of "    # Contains the beginning of the output string
  10.         for pos in range(dice):
  11.                 array[pos] = random.randint(1, sides)
  12.         total += array[pos]    # add the roll to the total
  13.  
  14.         output += str(dice) + "d" + str(sides) + " you rolled "
  15.     output += str(array) + " Total: " + str(total)
  16.     print output
  17.  
  18. print "* Input number of dice to roll (XdY), type quit to exit."
  19.  
  20. rollString = ""
  21.  
  22. while rollString.lower() not in ("quit", "exit"):
  23.     rollString = raw_input("* How many dice to roll? Type \"quit\" to exit. ")
  24.     rollString = rollString.lower()
  25.     if rollString in ("quit", "exit"):
  26.         break
  27.     rollString = rollString.split(',')
  28.  
  29.     for x in rollString:
  30.         splitString = x.split('d') #split the string at 'd'
  31.         if(splitString[1]) == "%":
  32.             splitString[1] = 100
  33.         try:
  34.             roll(int(splitString[0]), int(splitString[1]))
  35.         except ValueError:
  36.             roll(1, int(splitString[1]))
  37.         rollString = ""
  38.  
And here's a sample run:
Expand|Select|Wrap|Line Numbers
  1. * Input number of dice to roll (XdY), type quit to exit.
  2. * How many dice to roll? Type "quit" to exit. 3d6
  3. * On a roll of 3d6 you rolled [3, 4, 6] Total: 13
  4. * How many dice to roll? Type "quit" to exit. 2d4,2d6,1d8
  5. * On a roll of 2d4 you rolled [2, 4] Total: 6
  6. * On a roll of 2d6 you rolled [5, 5] Total: 10
  7. * On a roll of 1d8 you rolled [5] Total: 5
  8. * How many dice to roll? Type "quit" to exit. quit
  9.  
Jun 30 '07 #1
Share this Question
Share on Google+
6 Replies


bartonc
Expert 5K+
P: 6,596
You may find this to be a very cool feature of python:
Expand|Select|Wrap|Line Numbers
  1. >>> def TakeAnyArgs(*args):
  2. ...     for arg in args:
  3. ...         print arg
  4. ...         
  5. >>> TakeAnyArgs(1, 3, 5)
  6. 1
  7. 3
  8. 5
  9. >>> t = ('a', 'tuple', 'of', 'args')
  10. >>> TakeAnyArgs(*t)
  11. a
  12. tuple
  13. of
  14. args
  15. >>> 
I'll have a look around the forum for recent thread on this topic.

Welcome to the Python Forum on TheScripts.com!
Jun 30 '07 #2

bartonc
Expert 5K+
P: 6,596
You may find this to be a very cool feature of python:
Expand|Select|Wrap|Line Numbers
  1. >>> def TakeAnyArgs(*args):
  2. ...     for arg in args:
  3. ...         print arg
  4. ...         
  5. >>> TakeAnyArgs(1, 3, 5)
  6. 1
  7. 3
  8. 5
  9. >>> t = ('a', 'tuple', 'of', 'args')
  10. >>> TakeAnyArgs(*t)
  11. a
  12. tuple
  13. of
  14. args
  15. >>> 
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.
Jun 30 '07 #3

bvdet
Expert Mod 2.5K+
P: 2,851
Take a look at this:
Expand|Select|Wrap|Line Numbers
  1. import random
  2. import re
  3.  
  4. def rollMulti(rollStr):
  5.     patt = re.compile(r'\d+d\d+', re.IGNORECASE)
  6.     rolls = rollStr.split(',')
  7.     # validate each item in rolls with re expression
  8.     rolls = [roll.strip() for roll in rolls if patt.match(roll.strip())]
  9.     # split on 'd' or 'D'
  10.     rollList = [(int(i), int(j)) for i,j in [re.split('[dD]',item) for item in rolls]]
  11.     outList = []
  12.     for roll in rollList:
  13.         outList.append([random.randint(1, roll[1]) for i in range(roll[0])])
  14.     return '\n'.join(['* On a roll of %s, you rolled %s. Total: %d' % \
  15.                       (rolls[i], outList[i], sum(outList[i])) for i in range(len(rolls))])
  16.  
  17. rollStr = '4d6, 5D6,8H7,4d5,9d9'
  18. print rollMulti(rollStr)
  19.  
  20. '''
  21. >>> * On a roll of 4d6, you rolled [5, 5, 4, 2]. Total: 16
  22. * On a roll of 5D6, you rolled [5, 3, 4, 1, 1]. Total: 14
  23. * On a roll of 4d5, you rolled [2, 5, 1, 1]. Total: 9
  24. * On a roll of 9d9, you rolled [5, 9, 4, 4, 6, 8, 3, 5, 5]. Total: 49
  25. >>>
  26. '''
Jun 30 '07 #4

Megadeus
P: 4
Wow, that's pretty good!

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

Expand|Select|Wrap|Line Numbers
  1. You rolled 7,12,11 using 3d4,2d8,4d6 ((3,2,2,8,4,1,3,6,1)).
or ideally, like this:

Expand|Select|Wrap|Line Numbers
  1. You rolled 7,12,11 using 3d4,2d8,4d6 ((3,2,2),(8,4),(1,3,6,1)).
Jul 1 '07 #5

bartonc
Expert 5K+
P: 6,596
Wow, that's pretty good!

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

Expand|Select|Wrap|Line Numbers
  1. You rolled 7,12,11 using 3d4,2d8,4d6 ((3,2,2,8,4,1,3,6,1)).
or ideally, like this:

Expand|Select|Wrap|Line Numbers
  1. 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:
Expand|Select|Wrap|Line Numbers
  1. import random
  2. import re
  3.  
  4. def rollMulti(rollStr):
  5.     patt = re.compile(r'\d+d\d+', re.IGNORECASE)
  6.     rolls = rollStr.split()
  7.  
  8.     # validate each item in rolls with re expression
  9.     rolls = [roll for roll in rolls if patt.match(roll)]
  10.  
  11.     # split on 'd' or 'D'
  12.     rollList = [(int(i), int(j)) for i, j in [re.split('[dD]',item) for item in rolls]]
  13.     outList = []
  14.  
  15.     for roll in rollList:
  16.         outList.append([random.randint(1, roll[1]) for i in range(roll[0])])
  17.  
  18.     return 'You roled %s, using %s (%s)' % \
  19.             (
  20.              ', '.join(["%d" %(sum(outList[i])) for i in range(len(rolls))]),
  21.              ', '.join(rolls),
  22.              ', '.join([str(tuple(l)) for l in outList])
  23.              )
  24.  
  25. rollStr = '4d6   5D6  8H7 4d5 9d9'
  26. print rollMulti(rollStr)
  27.  
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))
Jul 1 '07 #6

bartonc
Expert 5K+
P: 6,596
Nice work on the regex, there BV. For the second output I used:
Expand|Select|Wrap|Line Numbers
  1. import random
  2. import re
  3.  
  4. def rollMulti(rollStr):
  5.     patt = re.compile(r'\d+d\d+', re.IGNORECASE)
  6.     rolls = rollStr.split()
  7.  
  8.     # validate each item in rolls with re expression
  9.     rolls = [roll for roll in rolls if patt.match(roll)]
  10.  
  11.     # split on 'd' or 'D'
  12.     rollList = [(int(i), int(j)) for i, j in [re.split('[dD]',item) for item in rolls]]
  13.     outList = []
  14.  
  15.     for roll in rollList:
  16.         outList.append([random.randint(1, roll[1]) for i in range(roll[0])])
  17.  
  18.     return 'You roled %s, using %s (%s)' % \
  19.             (
  20.              ', '.join(["%d" %(sum(outList[i])) for i in range(len(rolls))]),
  21.              ', '.join(rolls),
  22.              ', '.join([str(tuple(l)) for l in outList])
  23.              )
  24.  
  25. rollStr = '4d6   5D6  8H7 4d5 9d9'
  26. print rollMulti(rollStr)
  27.  
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:
Expand|Select|Wrap|Line Numbers
  1. from random import randint
  2. import re
  3.  
  4. def rollMulti(rolls):
  5.     patt = re.compile(r'\d+d\d+', re.IGNORECASE)
  6. ##    rolls = rollStr.split()
  7.  
  8.     # validate each item in rolls with re expression
  9.     rolls = [roll for roll in rolls if patt.match(roll)]
  10.  
  11.     # split on 'd' or 'D'
  12.     rollList = [(int(i), int(j)) for i, j in [re.split('[dD]',item) for item in rolls]]
  13.     outList = []
  14.  
  15.     for roll in rollList:
  16.         outList.append([randint(1, roll[1]) for i in range(roll[0])])
  17.  
  18.     return 'You roled %s, using %s (%s)' % \
  19.             (
  20.              ', '.join(["%d" %(sum(outList[i])) for i in range(len(rolls))]),
  21.              ', '.join(rolls),
  22.              ', '.join([str(tuple(l)) for l in outList])
  23.              )
  24.  
  25. if __name__ == "__main__":  # use this 'guard' so that you can import you function from another module
  26.     import sys
  27. ##    rollStr = '4d6   5D6  8H7 4d5 9d9'
  28.     print rollMulti(sys.argv[1:])
  29.  
Jul 1 '07 #7

Post your reply

Sign in to post your reply or Sign up for a free account.