An important thing to know about Python is that modules, as written, are pretty much only useful as imported objects for other programs.However, a module can be written to be imported or function as a standalone program.
When a module is imported into another program, only certain objects are imported over. Not everything is imported, which is what allows a module to perform dual duty. To make a module operate by itself, a special line has to be inserted near the end of the program.
The following program is a simple dice rolling simulator, broken up into separate parts:
random_dice_roller.py (part 1)
1 import random #randint
2
3 def randomNumGen(choice):
4 """Get a random number to simulate a d6, d10, or d100 roll."""
5
6 if choice == 1: #d6 roll
7 die = random.randint(1, 6)
8 elif choice == 2: #d10 roll
9 die = random.randint(1, 10)
10 elif choice == 3: #d100 roll
11 die = random.randint(1, 100)
12 elif choice == 4: #d4 roll
13 die = random.randint(1, 4)
14 elif choice == 5: #d8 roll
15 die = random.randint(1, 8)
The preceding code imports the random library from the built-in Python modules. Next, we define the function that will actually perform the dice simulation in line 3:
# random_dice_roller.py (part 2)
1 elif choice == 6: #d12 roll
2 die = random.randint(1, 12)
3 elif choice == 7: #d20 roll
4 die = random.randint(1, 20)
5 else: #simple error message
6 return "Shouldn't be here. Invalid choice"
7 return die
8
9 def multiDie(dice_number, die_type):
10 """Add die rolls together, e.g. 2d6, 4d10, etc."""
11
12 #---Initialize variables
13 final_roll = 0
14 val = 0
In the preceding code, we continue the different dice rolls and then define another function (line 9) that combines multiple dice together, as frequently used in games:
# random_dice_roller.py (part 3)
1 while val < dice_number:
2 final_roll += randomNumGen(die_type)
3 val += 1
4 return final_roll
5
6 if __name__ == "__main__": #run test() if calling as a separate
program
7 """Test criteria to show script works."""
8
9 _1d6 = multiDie(1,1) #1d6
10 print("1d6 = ", _1d6, end=' ')
11 _2d6 = multiDie(2,1) #2d6
12 print("\n2d6 = ", _2d6, end=' ')
13 _3d6 = multiDie(3,1) #3d6
14 print("\n3d6 = ", _3d6, end=' ')
In the preceding code, we finish with the summation of dice. The key part of the entire program is line 6. This line determines whether the module can run by itself or can only be imported into other programs.
Line 6 states that, if the namespace seen by the interpreter is the main one (that is, if random_dice_roller.py is the main program being run and not something else), then the interpreter will process any operations that are specified below line 6. In this case, these operations are simply tests to confirm that the main logic (preceding line 6) works as expected.
If this program were to be imported into another program, then everything before line 6 would be imported while everything following it would be ignored. Thus, you can make a program that functions as a standalone program or can be imported; the only difference is what code is written below if __name__ == "__main__":
# random_dice_roller.py (part 4)
1 _4d6 = multiDie(4,1) #4d6
2 print("\n4d6 = ", _4d6, end=' ')
3 _1d10 = multiDie(1,2) #1d10
4 print("\n1d10 = ", _1d10, end=' ')
5 _2d10 = multiDie(2,2) #2d10
6 print("\n2d10 = ", _2d10, end=' ')
7 _3d10 = multiDie(2,2) #3d10
8 print("\n3d10 = ", _3d10, end=' ')
9 _d100 = multiDie(1,3) #d100
10 print("\n1d100 = ", _d100)
This finishes the self-tests for the dice rolling program.