Script to determine the outcome(s) of any number of dice rolls I think this code has far to many if else clauses and not enough abstraction via functions. I would like to break the code down into a series of small functions, or methods if i decide to go OOP, but I'm not sure of the best way to do so. If you brilliant Pythonista's could guide me in the write direction I would appreciate it.

Here is the GitHub repo if you would like to fork it repo

'''
script to determine the outcome(s) of any number of dice rolls
By Andrew Smith (2015)
'''

from random import randint

def dice_roller(dice, rolls, sides):
    '''
    Add doc string here.
    '''
    show_di = '|   |'
    show_di_1 = '| * |'
    show_di_2 = '|* *|'
    show_di_3 = '|***|'
    show_di_t = ' ___ '
    show_di_b = ' --- '
    roll_counter = 0
    di_counter = 0

    while roll_counter &lt; rolls:
        roll_counter += 1
        di_counter = 0
        print " "

        while di_counter &lt; dice:
            di_counter += 1
            num_side = randint(1, sides)
            print "Roll %r, Di %r: %r" % (roll_counter, di_counter, num_side)
            if num_side &lt;= 6: # print di symbol if di is six-sided
                if num_side == 1:
                    print show_di_t
                    print show_di_1
                    print show_di
                    print show_di_b
                elif num_side == 2:
                    print show_di_t
                    print show_di_1
                    print show_di_1
                    print show_di_b
                elif num_side == 3:
                    print show_di_t
                    print show_di_1
                    print show_di_2
                    print show_di_b
                elif num_side == 4:
                    print show_di_t
                    print show_di_2
                    print show_di_2
                    print show_di_b
                elif num_side == 5:
                    print show_di_t
                    print show_di_2
                    print show_di_3
                    print show_di_b
                elif num_side == 6:
                    print show_di_t
                    print show_di_3
                    print show_di_3
                    print show_di_b
    print " "
#-------------------------------------------------------------------------------

TITLE = """
 __________________
| Dice Roller v1.1 |
| by Andrew Smith  |
|__________________|
"""

MENU = """
Enter the number of dice to roll, the number
of rolls, and the number of sides per di in the
following format: #dice #rolls #sides

--- or ---

Select from the following presets:

a. 3 man attack (Risk)
b. 2 man attack or defend (Risk)
c. 1 man attack or defend (Risk)

--- or ---

Type 'menu' to repeat this menu

--- or ---

Type 'quit' to quit
        """

def main():
    '''
    Explain this function.
    '''
    print TITLE
    print MENU
    again = 0

    while again != 1: # prompts the user until 'quit' is entered
        roll_choice = raw_input("&gt; ")
        if roll_choice.isalpha(): # if input starts with a letter
            if roll_choice == 'a':
                dice_roller(3, 1, 6)
            elif roll_choice == 'b':
                dice_roller(2, 1, 6)
            elif roll_choice == 'c':
                dice_roller(1, 1, 6)
            elif roll_choice == 'menu':
                print MENU
            elif roll_choice == 'quit':
                again = 1
            else:
                print "Invalid choice.\n"

        elif roll_choice[0].isdigit(): # if input starts with a number
            choices = roll_choice.split()
            size = len(choices)
            if size == 3:
                one = int(choices[0])
                two = int(choices[1])
                three = int(choices[2])
                dice_roller(one, two, three)
            else:
                print "Invalid Choice.\n"
        else:
            print "Invalid choice.\n"

if __name__ == '__main__':
    main()
Use unpacking

        choices = roll_choice.split()
        size = len(choices)
        if size == 3:
            one = int(choices[0])
            two = int(choices[1])
            three = int(choices[2])
            dice_roller(one, two, three)
        else:
            print "Invalid Choice.\n"


Becomes:

dice_roller( * map(int, roll_choice.split()) )


Adding error handling it is:

 try:
     dice_roller( * map(int, roll_choice.split()) )
 except Exception as e:
     print("Invalid choice:" + e)


The * operator just goes from a list to free floating arguments and is called the unpacking operator. You use it to pass a list as argument to a function that takes separate arguments.

Naming in full

You should write the names of your variables in full to make them more understandable at first glance. show may be omitted. For example:


show_di_1 ➡ dice_1
show_di_b ➡ dice_bottom


A dictionary

A dictionary will allow you to avoid the first if elif chain easily. How is left as an exercise for the reader.