برنامه‌نویسی پایتون فهرست مطالب
فصل ۱۶

کتابخانه استاندارد

پایتون با «باتری‌های همراه» می‌آید. صدها ماژول آماده همراه نصب پایتون هستند و شما فقط باید بدانید که وجود دارند. این فصل معرفی پرکاربردترین‌هایشان است.

در این فصل می‌خوانید
  1. سه شکل import
  2. عدد تصادفی صحیح
  3. عدد تصادفی اعشاری
  4. انتخاب تصادفی از یک مجموعه
  5. دانه تصادفی
  6. بازی تاس
  7. ماژول math
  8. گرد کردن
  9. تاریخ و زمان
  10. اختلاف دو تاریخ
  11. ماژول time
  12. آرگومان‌های خط فرمان

۱. سه شکل import

ماژول یک فایل پایتون است پر از توابع آماده. برای استفاده از آن باید اول واردش کنید.

# Way 1: import the whole module, then use 'module.name'
import random
print(random.randint(1, 6))

# Way 2: import it under a shorter name
import random as rnd
print(rnd.randint(1, 6))

# Way 3: import only what we need, then use the name directly
from random import randint, choice
print(randint(1, 6))
print(choice(['red', 'green', 'blue']))

# 'from module import *' imports everything. Avoid it: you no longer know
# where a name comes from, and it can silently overwrite your own names.

سه شکل وارد کردن: نمونه 01_import_styles.py

شکلاستفادهکی
import randomrandom.randint(...)حالت پیش‌فرض و امن‌ترین
import random as rndrnd.randint(...)وقتی نام ماژول طولانی است
from random import randintrandint(...)وقتی فقط چند تابع لازم دارید
from random import *همه چیزهرگز
چرا ستاره ممنوع است

from module import * همه نام‌های ماژول را داخل فایل شما می‌ریزد. اگر ماژول تابعی به نام choice داشته باشد و شما هم متغیری به همان نام داشته باشید، یکی دیگری را از بین می‌برد و هیچ خطایی هم نمی‌بینید. به‌علاوه، وقتی کد را می‌خوانید نمی‌دانید randint از کجا آمده است.

دام نام فایل

هرگز فایل خودتان را random.py یا math.py نگذارید. پایتون اول در پوشه جاری جست‌وجو می‌کند، فایل شما را پیدا می‌کند و به جای ماژول واقعی واردش می‌کند. نتیجه، خطاهای بسیار گیج‌کننده است.

۲. عدد تصادفی صحیح

import random

# randint(a, b) -> a whole number between a and b, BOTH included.
x = random.randint(1, 6)
y = random.randint(1, 6)
print(f'{x}, {y}')

# randrange() works like range(): the last value is NOT included.
print(random.randrange(1, 10))        # 1..9
print(random.randrange(0, 100, 5))    # 0, 5, 10, ... 95

عدد تصادفی صحیح: نمونه 02_random_integers.py

تفاوت مهم: در randint هر دو سر بازه شامل هستند، ولی randrange مثل range عمل می‌کند و عدد آخر را شامل نمی‌شود. برای تاس، randint(1, 6) درست است.

۳. عدد تصادفی اعشاری

import random

# random() -> a decimal number between 0.0 and 1.0 (1.0 excluded)
print(random.random())

# uniform(a, b) -> a decimal number between a and b
print(random.uniform(5, 10))

# A percentage with two decimals:
print(round(random.random() * 100, 2))

عدد تصادفی اعشاری: نمونه 03_random_floats.py

۴. انتخاب تصادفی از یک مجموعه

import random

colors = ['red', 'green', 'blue']

# choice() -> ONE item
print(random.choice(colors))

# sample() -> k DIFFERENT items (no repetition)
print(random.sample(colors, 2))

# choices() -> k items WITH repetition allowed
print(random.choices(colors, k=5))

# choices() can also be given weights.
print(random.choices(colors, weights=[10, 1, 1], k=5))

# shuffle() mixes a list IN PLACE and returns None.
numbers = [1, 2, 3, 4, 5]
random.shuffle(numbers)
print(numbers)

انتخاب تصادفی: نمونه 04_random_choice.py

تابعوظیفه آن
choice(lst)یک عضو تصادفی
sample(lst, k)k عضو متفاوت، بدون تکرار. مثل قرعه‌کشی
choices(lst, k=n)n عضو با امکان تکرار
choices(..., weights=[...])با احتمال‌های متفاوت
shuffle(lst)بُر زدن خود لیست. چیزی برنمی‌گرداند

باز هم آن دام آشنا: shuffle مثل sort خود لیست را عوض می‌کند و None برمی‌گرداند. ننویسید numbers = random.shuffle(numbers).

۵. دانه تصادفی

import random

# The "random" numbers of a computer are computed from a starting value
# called the seed. With the same seed we always get the same sequence -
# which is exactly what we want while testing a program.
random.seed(42)
print([random.randint(1, 100) for _ in range(5)])

random.seed(42)
print([random.randint(1, 100) for _ in range(5)])   # the same five numbers

# Without a seed, Python uses the current time, so the numbers change.
random.seed()
print([random.randint(1, 100) for _ in range(5)])

دانه: نمونه 05_random_seed.py

اعداد تصادفی کامپیوتر در عمل شبه‌تصادفی هستند: از یک عدد شروع می‌شوند و با فرمولی محاسبه می‌شوند. اگر همان عدد شروع را بدهید، همان دنباله را می‌گیرید. این برای آزمایش برنامه بسیار مفید است، چون می‌توانید باگ را دوباره تولید کنید.

برای رمز و امنیت

ماژول random برای بازی و شبیه‌سازی عالی است ولی برای تولید رمز عبور یا توکن امنیتی مناسب نیست، چون قابل پیش‌بینی است. برای آن کارها ماژول secrets ساخته شده است.

۶. بازی تاس

'''A small dice game: the player and the computer roll two dice.'''

import random


def roll_two_dice() -> int:
    'Roll two dice and return their total.'
    return random.randint(1, 6) + random.randint(1, 6)


def main() -> None:
    player_score = 0
    computer_score = 0

    for round_number in range(1, 4):
        input(f'Round {round_number} - press Enter to roll...')

        player = roll_two_dice()
        computer = roll_two_dice()

        print(f'You: {player}   Computer: {computer}')

        if player > computer:
            player_score += 1
            print('You win this round!')
        elif computer > player:
            computer_score += 1
            print('The computer wins this round!')
        else:
            print('Draw.')

    print(f'\nFinal score - you: {player_score}, computer: {computer_score}')


if __name__ == '__main__':
    main()

بازی تاس: نمونه 06_dice_game.py

نکته ظریف: input() اینجا بدون ذخیره کردن نتیجه به کار رفته است. فقط می‌خواهیم برنامه منتظر بماند تا کاربر اینتر بزند. این ترفند ساده‌ای است برای مکث دادن به برنامه‌های متنی.

۷. ماژول math

import math

print(math.pi)              # 3.141592653589793
print(math.e)

print(math.sqrt(16))        # 4.0  -> square root
print(math.pow(2, 10))      # 1024.0 (a float; the operator ** gives an int)
print(2 ** 10)              # 1024

print(math.factorial(5))    # 120
print(math.gcd(12, 18))     # 6  -> greatest common divisor

print(math.floor(3.7))      # 3  -> down
print(math.ceil(3.2))       # 4  -> up
print(math.fabs(-5))        # 5.0

# Area of a circle.
radius = float(input('Radius of the circle: '))
print('Area:', math.pi * radius ** 2)

ماژول math: نمونه 07_math_module.py

در فصل‌های قبل فاکتوریل و بزرگ‌ترین مقسوم‌علیه مشترک را با دست نوشتیم. حالا می‌بینید که هر دو آماده‌اند. باز هم همان درس: اول بفهمید چطور کار می‌کند، بعد از نسخه آماده استفاده کنید.

۸. گرد کردن

import math

value = 3.567

print(round(value))         # 4     -> nearest whole number
print(round(value, 2))      # 3.57  -> two decimals
print(math.floor(value))    # 3     -> always down
print(math.ceil(value))     # 4     -> always up
print(int(value))           # 3     -> simply cuts the decimals

# Careful with negative numbers: int() and floor() are NOT the same.
print(int(-3.7), math.floor(-3.7))    # -3  and  -4

# Python uses "banker's rounding": .5 goes to the nearest EVEN number.
print(round(2.5), round(3.5))         # 2  and  4

گرد کردن: نمونه 08_rounding.py

روشروی ۳٫۷روی منفی ۳٫۷معنی
round()۴منفی ۴نزدیک‌ترین
math.floor()۳منفی ۴همیشه به سمت پایین
math.ceil()۴منفی ۳همیشه به سمت بالا
int()۳منفی ۳بریدن اعشار، به سمت صفر
گرد کردن بانکی

round(2.5) برابر ۲ است، نه ۳. این باگ نیست: پایتون نصف‌ها را به نزدیک‌ترین عدد زوج گرد می‌کند. دلیلش این است که اگر همیشه رو به بالا گرد کنید، در محاسبات مالی بزرگ یک خطای انباشته ایجاد می‌شود. اگر رفتار مدرسه‌ای می‌خواهید، باید خودتان بنویسید یا از ماژول decimal استفاده کنید.

۹. تاریخ و زمان

from datetime import datetime, date

# The current date and time.
now = datetime.now()
print(now)
print(now.year, now.month, now.day)
print(now.hour, now.minute, now.second)

# Only the date.
today = date.today()
print(today)

# Building a specific date.
birthday = date(2005, 3, 21)
print(birthday)

# strftime() turns a date into text the way we want it.
print(now.strftime('%Y/%m/%d'))
print(now.strftime('%d %B %Y'))
print(now.strftime('%H:%M:%S'))

# strptime() does the opposite: it reads a date out of a text.
parsed = datetime.strptime('2026-09-08', '%Y-%m-%d')
print(parsed)

تاریخ و زمان: نمونه 09_datetime_basics.py

کد قالبیعنی
%Yسال چهاررقمی
%mماه دورقمی
%dروز دورقمی
%Bنام ماه
%H:%M:%Sساعت و دقیقه و ثانیه

دو تابع را با هم اشتباه نگیرید: strftime تاریخ را به متن تبدیل می‌کند و strptime متن را به تاریخ. حرف f یعنی format و حرف p یعنی parse.

۱۰. اختلاف دو تاریخ

from datetime import date, timedelta

today = date.today()
birthday = date(2005, 3, 21)

# Subtracting two dates gives a timedelta.
age = today - birthday
print('Days lived:', age.days)
print('Approximate age:', age.days // 365)

# Adding a duration to a date.
print('In 100 days:', today + timedelta(days=100))
print('One week ago:', today - timedelta(weeks=1))

# A small program: how many days until the end of the year?
end_of_year = date(today.year, 12, 31)
print('Days left this year:', (end_of_year - today).days)

اختلاف تاریخ: نمونه 10_datetime_difference.py

تفریق دو تاریخ یک timedelta می‌دهد که یعنی «مدت زمان». صفت .days تعداد روزهایش را می‌دهد. برای جمع زدن هم همین نوع را می‌سازید و به تاریخ اضافه می‌کنید.

۱۱. ماژول time

import time

print('Start')
time.sleep(1)          # pause the program for one second
print('One second later')

# Measuring how long a piece of code takes.
start = time.time()

total = 0
for i in range(3_000_000):
    total += i

end = time.time()
print(f'The loop took {end - start:.3f} seconds.')

# perf_counter() is more precise for measuring short durations.
start = time.perf_counter()
sum(range(3_000_000))
print(f'sum() took {time.perf_counter() - start:.3f} seconds.')

ماژول time: نمونه 11_time_module.py

Start
One second later
The loop took 0.187 seconds.
sum() took 0.043 seconds.

شرح مثال

۱۲. آرگومان‌های خط فرمان

'''Reading the arguments typed on the command line.

Run it like this:
    python 12_sys_argv.py 12 30
'''

import sys


def main() -> None:
    # sys.argv[0] is the name of the file itself.
    print('All the arguments:', sys.argv)

    if len(sys.argv) < 3:
        print('Usage: python 12_sys_argv.py <number1> <number2>')
        sys.exit(1)          # stop the program with an error code

    num1 = float(sys.argv[1])
    num2 = float(sys.argv[2])

    print('Sum:', num1 + num2)


if __name__ == '__main__':
    main()

خط فرمان: نمونه 12_sys_argv.py

$ python 12_sys_argv.py 12 30
All the arguments: ['12_sys_argv.py', '12', '30']
Sum: 42.0

شرح مثال

فایل‌های تمرینی این فصل

پوشه S16-standard-library شامل نمونه‌های 01_import_styles.py تا 12_sys_argv.py.

خلاصه فصل

ابزاروظیفه آن
import m / from m import xوارد کردن ماژول. ستاره را به کار نبرید
random.randint(a, b)عدد صحیح تصادفی، هر دو سر شامل
random.choice sample shuffleانتخاب و بُر زدن
random.seed(n)تکرارپذیر کردن نتیجه‌های تصادفی
math.sqrt pi factorial gcdتوابع ریاضی آماده
round floor ceil intچهار نوع گرد کردن با رفتار متفاوت
datetime.now() date.today()زمان و تاریخ جاری
strftime strptimeتاریخ به متن و متن به تاریخ
timedeltaمدت زمان، برای جمع و تفریق تاریخ
time.sleep perf_counterمکث و اندازه‌گیری زمان
sys.argvآرگومان‌های خط فرمان، همیشه رشته

تمرین‌های فصل شانزده

  1. بازی حدس عدد را بنویسید که کامپیوتر عددی بین ۱ تا ۱۰۰ انتخاب کند و بگوید بزرگ‌تر یا کوچک‌تر.
  2. برنامه‌ای بنویسید که هزار بار تاس بیندازد و بشمارد هر وجه چند بار آمده است.
  3. یک رمز عبور تصادفی ده کاراکتری از حروف و ارقام و نمادها بسازید.
  4. برنامه‌ای بنویسید که شش عدد متفاوت بین ۱ تا ۴۹ انتخاب کند، مثل قرعه‌کشی.
  5. شعاع دایره را بگیرید و با math مساحت و محیطش را چاپ کنید.
  6. تاریخ تولد را بگیرید و سن دقیق را به سال و ماه و روز چاپ کنید.
  7. تاریخ امروز را در سه قالب مختلف چاپ کنید.
  8. زمان جمع اعداد یک تا ده میلیون را یک بار با حلقه و یک بار با sum(range(...)) اندازه بگیرید و مقایسه کنید.
فصل قبل: ساختارهای داده تودرتو فصل بعد: ماژول‌ها و بسته‌ها