Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
441: Building a Random Team Generator Tool
Imagine you're organizing a corporate retreat or a local gaming tournament. You have a group of twenty people, and you need to split them into four balanced teams. To keep things fair and avoid any accusations of favoritism, you write everyone's name on a small slip of paper, toss them all into a bowl, and give it a good shake. Then, you draw names one by one: the first five go to Team A, the next five to Team B, and so on.
In Python, we can mirror this exact process. The "bowl" is our list of names. "Shaking the bowl" is handled by the random.shuffle() function. And "drawing names" to fill teams is simply a matter of slicing that list into smaller chunks.
Shaking the Bowl of Names
I've seen a lot of beginners try to use random.choice() to pick team members one by one. While that works, it's a headache because you have to manually track who has already been picked so you don't put the same person on three different teams. It's much cleaner to shuffle the entire list once and then just walk through it linearly.
import random
players = ["Alice", "Bob", "Charlie", "Diana", "Ethan", "Fiona", "George", "Hannah"]
random.shuffle(players)
# Now the list is in a completely random order, just like our bowl of papers.
Dealing the Cards into Teams
Once the list is shuffled, we don't need any more "randomness." We just need to carve that list into equal segments. The most efficient way to do this in Python is using a range with a "step" value. If we want teams of 2, we jump through the list in increments of 2 and take a slice from the current position to the current position plus the team size.
team_size = 2
teams = []
for i in range(0, len(players), team_size):
team = players[i : i + team_size]
teams.append(team)
# Result: [['Hannah', 'Bob'], ['Alice', 'George'], ...]
Putting the Logic into a Reusable Tool
If you're building this for a real project, you don't want to rewrite this logic every time. I usually wrap this in a function that handles the edge case where the number of people doesn't divide perfectly by the team size. Python's slicing is actually very forgiving here—if you ask for a slice that goes past the end of the list, it just gives you whatever is left, meaning your last team might be slightly smaller than the others.
import random
def generate_teams(people, size):
# We copy the list first so we don't accidentally
# shuffle the original list outside the function
pool = people[:]
random.shuffle(pool)
return [pool[i : i + size] for i in range(0, len(pool), size)]
# Usage
all_staff = ["Dave", "Sarah", "Jen", "Mike", "Leo", "Amy", "Chris", "Pat"]
my_teams = generate_teams(all_staff, 3)
for idx, team in enumerate(my_teams, 1):
print(f"Team {idx}: {', '.join(team)}")
One small detail I added there: people[:]. This creates a shallow copy of the list. In professional software engineering, you generally want to avoid "mutating" (changing) the input data unless specifically asked to. If the rest of your program expects the all_staff list to stay in alphabetical order, calling shuffle() directly on it would break things elsewhere.
📋 Practical Task
The 1v1 Tournament Bracket Generator
You've been asked to build a tool for a local fighting game tournament. You have a list of 10 players, and you need to split them into 5 pairs for the opening round of 1v1 matches.
Your Task:
- Create a list called
competitorscontaining 10 unique names. - Write a function called
create_matchesthat takes the list of names and returns a list of pairs (lists of 2). - The pairs must be randomly assigned.
- Print the results in a readable format, such as:
"Match 1: Player A vs Player B".
There are no comments for now.