Design a function to generate a random verification code. The verification code is made up of digits and uppercase and lowercase English letters, and the length can be set through a parameter.
import random
import string
ALL_CHARS = string.digits + string.ascii_letters
def generate_code(*, code_len=4):
"""
Generate a verification code of the specified length.
:param code_len: The length of the verification code (default is 4 characters)
:return: A random verification code string made up of uppercase and lowercase English letters and digits
"""
return ''.join(random.choices(ALL_CHARS, k=code_len))Note 1:
string.digitsin thestringmodule means the string'0123456789', andstring.ascii_lettersin thestringmodule means the string'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.Note 2: The
sampleandchoicesfunctions in therandommodule can both do random sampling.sampledoes sampling without replacement, which means the sampled elements are not repeated.choicesdoes sampling with replacement, which means some elements may be chosen again. The first parameter of these two functions is the whole population to sample from, and the parameterkmeans the sample size. It should be noted that the parameterkof thechoicesfunction is a keyword-only parameter, so you must give the parameter name when passing it.
We can use the code below to generate 5 random verification codes to test the function above.
for _ in range(5):
print(generate_code())Or:
for _ in range(5):
print(generate_code(code_len=6))Note: The parameter of the
generate_codefunction we designed is a keyword-only parameter. Because it has a default value, we can choose not to pass a value to it and use the default value4. If we want to pass a value to the function, we must use the parameter namecode_len.
Design a function that checks whether a given positive integer greater than 1 is a prime number. A prime number is a positive integer greater than 1 that can only be divided exactly by 1 and itself. If a positive integer 2 and
def is_prime(num: int) -> bool:
"""
Determine whether a positive integer is prime.
:param num: A positive integer greater than 1
:return: True if num is prime, otherwise False
"""
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
return False
return TrueNote 1: The
: intafter the parameternumabove is used to mark the parameter type. Although it does not affect the execution result of the code, it improves the readability of the code well. In the same way,-> boolafter the parameter list is used to mark the return type of the function. It also does not affect the execution result of the code, but it clearly tells us that calling this function returns a Boolean value, eitherTrueorFalse.Note 2: The loop above does not need to go from
2all the way to$\small{N-1}$ , because if by the time the loop reaches$\small{\sqrt{N}}$ we still have not found a factor of$\small{N}$ , then no factor of$\small{N}$ will appear after$\small{\sqrt{N}}$ . You can think for yourself about why that is.
Design functions to calculate the greatest common divisor and the least common multiple of two positive integers. The greatest common divisor of
def lcm(x: int, y: int) -> int:
"""Compute the least common multiple."""
return x * y // gcd(x, y)
def gcd(x: int, y: int) -> int:
"""Compute the greatest common divisor."""
while y % x != 0:
x, y = y % x, x
return xNote: Functions can call each other. The
lcmfunction above calls thegcdfunction, and it uses$\frac{x \times y}{gcd(x, y)}$ to calculate the least common multiple.
Suppose sample data is saved in a list. Design functions to calculate the descriptive statistics of the sample data. Descriptive statistics usually include arithmetic mean, median, range, variance, standard deviation, coefficient of variation, and so on. The formulas are shown below.
def ptp(data):
"""Range."""
return max(data) - min(data)
def mean(data):
"""Arithmetic mean."""
return sum(data) / len(data)
def median(data):
"""Median."""
temp, size = sorted(data), len(data)
if size % 2 != 0:
return temp[size // 2]
else:
return mean(temp[size // 2 - 1:size // 2 + 1])
def var(data, ddof=1):
"""Variance."""
x_bar = mean(data)
temp = [(num - x_bar) ** 2 for num in data]
return sum(temp) / (len(temp) - ddof)
def std(data, ddof=1):
"""Standard deviation."""
return var(data, ddof) ** 0.5
def cv(data, ddof=1):
"""Coefficient of variation."""
return std(data, ddof) / mean(data)
def describe(data):
"""Print descriptive statistics."""
print(f'均值: {mean(data)}')
print(f'中位数: {median(data)}')
print(f'极差: {ptp(data)}')
print(f'方差: {var(data)}')
print(f'标准差: {std(data)}')
print(f'变异系数: {cv(data)}')Note 1: The median is the number in the middle after sorting the data in ascending or descending order, and it describes the middle level of the data. There are two cases when calculating the median: when the amount of data
$\small{n}$ is odd, the median is the element at position$\frac{n + 1}{2}$ ; when the amount of data$\small{n}$ is even, the median is the average of the elements at positions$\frac{n}{2}$ and $\frac{n}{2} + 1`.Note 2: In the functions that calculate variance and standard deviation, there is a parameter named
ddof. It means the adjustable degrees of freedom, and its default value is1. When calculating sample variance and sample standard deviation, we need to do degree-of-freedom correction. If we want to calculate population variance and population standard deviation, we can set theddofparameter to0, which means no degree-of-freedom correction is needed.Note 3: The
describefunction puts the statistics functions above together and is used to output the descriptive statistics of the data. In fact, Python's standard library has a module namedstatistics, and it has already packaged functions for getting descriptive statistics. Interested readers can learn about it by themselves.
Let us use functions to refactor the Double Color Ball example from an earlier lesson. We package the function that generates random numbers and the function that outputs one group of numbers into two functions, and then use function calls to generate N random tickets.
"""
Random number generator for Double Color Ball
Author: Luo Hao
Version: 1.3
"""
import random
RED_BALLS = [i for i in range(1, 34)]
BLUE_BALLS = [i for i in range(1, 17)]
def choose():
"""
Generate one group of random numbers.
:return: A list that saves the random numbers
"""
selected_balls = random.sample(RED_BALLS, 6)
selected_balls.sort()
selected_balls.append(random.choice(BLUE_BALLS))
return selected_balls
def display(balls):
"""
Print one group of numbers in a formatted way.
:param balls: A list that saves the random numbers
"""
for ball in balls[:-1]:
print(f'\033[031m{ball:0>2d}\033[0m', end=' ')
print(f'\033[034m{balls[-1]:0>2d}\033[0m')
n = int(input('生成几注号码: '))
for _ in range(n):
display(choose())Note: Look at the line
display(choose()). Here, we first use thechoosefunction to get one group of random numbers, then use the return value of thechoosefunction as the parameter of thedisplayfunction, and use thedisplayfunction to show the selected random numbers. After refactoring, the logic of the code becomes very clear, and the readability of the code becomes stronger. If someone already packaged these two functions for you, and you are only the caller of the functions, then you do not need to care about the internal implementation of thechoosefunction and thedisplayfunction at all. You only need to know that calling thechoosefunction can generate one group of random numbers, and calling thedisplayfunction with a list can output that group of numbers. In the future, when we use many third-party Python libraries, we also do not care about their bottom-layer implementation. What we need to know is only which function to call to solve the problem.
When writing code, especially when developing commercial projects, we should consciously package relatively independent functions that will be used repeatedly into functions. In this way, both you and other team members can use these functions by calling them, and this can reduce repeated and boring work in development.