آموزش پایتون (python) با فیبیست-سطح 3

word image 1231 7

در این سطح از برنامه نویسی پایتون ، به سراغ ساخت کدهای اتوماسیون می رویم.

 

درس ۲۲ پایتون

اتوماسیون انتقال فایل‌های PDF در ویندوز و تلفن همراه

تا اینجا با pathlib مسیر فایل‌ها را مدیریت کردیم.

حالا می‌خواهیم یک پروژهٔ واقعی بسازیم:

تمام فایل‌های PDF موجود در پوشهٔ Downloads را پیدا کنیم و به پوشهٔ PDF_Files منتقل کنیم.

در این پروژه از دو ابزار استفاده می‌کنیم:

pathlib
shutil

ایدهٔ پروژه

روند برنامه:

Downloads
    ↓
پیدا کردن PDFها
    ↓
ساخت پوشه PDF_Files
    ↓
انتقال PDFها

مثلاً:

Downloads
│
├── book.pdf
├── lesson.pdf
├── photo.jpg
├── music.mp3
└── test.pdf

بعد از اجرای برنامه:

Downloads
│
├── photo.jpg
├── music.mp3
│
└── PDF_Files
      ├── book.pdf
      ├── lesson.pdf
      └── test.pdf

کد پروژه برای ویندوز

در سیستم ویندوز، اگر پوشهٔ Downloads کاربر در مسیر زیر باشد:

C:UsersMORTEZADownloads

کد:

# ============================================================
#                    فیبیست | PHY20
#              آموزش برنامه‌نویسی پایتون
# ============================================================
#
# وب‌سایت:
# https://www.phy20.com
#
# طراح و برنامه‌نویس:
# مرتضی محمدی‌وند خوشخو
#
# تاریخ:
# ..............................
#
# مجوز و لایسنس کد:
# استفاده از این کد برای مقاصد آموزشی و
# بدون مقاصد تجاری رایگان است.
#
# مالکیت معنوی:
# تمامی حقوق معنوی این کد متعلق به فیبیست (PHY20)
# و طراح و برنامه‌نویس آن محفوظ است.
#
# ============================================================

from pathlib import Path
import shutil

folder = Path(r"C:UsersMORTEZADownloads")

destination = folder / "PDF_Files"

destination.mkdir(exist_ok=True)

for file in folder.glob("*.pdf"):
    shutil.move(str(file), str(destination))

print("PDF files moved successfully.")

۱. وارد کردن ابزارها

from pathlib import Path
import shutil

Path

برای کار با مسیرها:

Path

shutil

برای جابه‌جایی فایل‌ها:

shutil.move()

۲. مشخص کردن Downloads

folder = Path(r"C:UsersMORTEZADownloads")

اینجا به پایتون می‌گوییم:

پوشه‌ای که باید فایل‌ها را بررسی کنی اینجاست.


۳. ساخت پوشهٔ مقصد

destination = folder / "PDF_Files"

حالا مسیر مقصد ساخته می‌شود:

C:UsersMORTEZADownloadsPDF_Files

۴. اگر پوشه وجود نداشت، آن را بساز

destination.mkdir(exist_ok=True)

اگر PDF_Files وجود نداشته باشد، ساخته می‌شود.

اگر از قبل وجود داشته باشد، برنامه بدون خطا ادامه پیدا می‌کند.

این قسمت خیلی مهم است؛ چون لازم نیست قبل از اجرای برنامه خودمان پوشه را بسازیم.


۵. پیدا کردن فایل‌های PDF

for file in folder.glob("*.pdf"):

اینجا glob() تمام فایل‌هایی را پیدا می‌کند که پسوندشان:

.pdf

است.

مثلاً:

book.pdf
lesson.pdf
report.pdf

ولی فایل‌هایی مانند:

photo.jpg
music.mp3
data.txt

انتخاب نمی‌شوند.


۶. انتقال فایل

shutil.move(str(file), str(destination))

این دستور فایل را از محل فعلی به پوشهٔ مقصد منتقل می‌کند.

یعنی:

file
 ↓
shutil.move()
 ↓
PDF_Files

چرا str() استفاده کردیم؟

file و destination از نوع Path هستند.

در اینجا برای سازگاری بیشتر با shutil.move() آن‌ها را به رشته تبدیل می‌کنیم:

str(file)

و:

str(destination)

نسخهٔ مناسب برای تلفن همراه

در اندروید، اگر پوشهٔ Downloads در این مسیر باشد:

/storage/emulated/0/Download

می‌توانیم همین پروژه را برای گوشی بنویسیم:

# ============================================================
#                    فیبیست | PHY20
#              آموزش برنامه‌نویسی پایتون
# ============================================================
#
# وب‌سایت:
# https://www.phy20.com
#
# طراح و برنامه‌نویس:
# مرتضی محمدی‌وند خوشخو
#
# تاریخ:
# ..............................
#
# مجوز و لایسنس کد:
# استفاده از این کد برای مقاصد آموزشی و
# بدون مقاصد تجاری رایگان است.
#
# مالکیت معنوی:
# تمامی حقوق معنوی این کد متعلق به فیبیست (PHY20)
# و طراح و برنامه‌نویس آن محفوظ است.
#
# ============================================================

from pathlib import Path
import shutil

folder = Path("/storage/emulated/0/Download")

destination = folder / "PDF_Files"

destination.mkdir(exist_ok=True)

for file in folder.glob("*.pdf"):
    shutil.move(str(file), str(destination))

print("PDF files moved successfully.")

در این حالت:

Download
│
├── book.pdf
├── lesson.pdf
└── PDF_Files
      ├── book.pdf
      └── lesson.pdf

یک نکتهٔ مهم دربارهٔ حروف بزرگ و کوچک

کدی که نوشته‌ایم:

folder.glob("*.pdf")

فایل‌های .pdf را پیدا می‌کند.

اگر بعضی فایل‌ها با حروف بزرگ ذخیره شده باشند، مثلاً:

BOOK.PDF

برای اینکه هر دو حالت را پوشش دهیم، می‌توانیم از:

folder.glob("*.[Pp][Dd][Ff]")

استفاده کنیم.

در نتیجه فایل‌های:

book.pdf
BOOK.PDF
Book.Pdf

همگی پیدا می‌شوند.


پروژهٔ کوچک‌تر برای تمرین

ابتدا این برنامه را اجرا کنید:

from pathlib import Path
import shutil

folder = Path(r"C:UsersMORTEZADownloads")

destination = folder / "PDF_Files"

destination.mkdir(exist_ok=True)

for file in folder.glob("*.pdf"):
    print("Moving:", file.name)
    shutil.move(str(file), str(destination))

print("Done!")

قبل از انتقال، نام هر فایل را می‌بینید:

Moving: book.pdf
Moving: lesson.pdf
Moving: physics.pdf
Done!

این کار کمک می‌کند فرآیند اتوماسیون را ببینیم.


چیزی که در این پروژه یاد گرفتیم

چهار ابزار مهم را کنار هم گذاشتیم:

Path
 ↓
ساخت و مدیریت مسیر

glob()
 ↓
پیدا کردن فایل‌ها

mkdir()
 ↓
ساخت پوشه

shutil.move()
 ↓
انتقال فایل

بنابراین برنامهٔ ما دیگر فقط یک برنامهٔ محاسباتی نیست؛

پایتون دارد خودش کارهای تکراری سیستم را انجام می‌دهد.

مسیر یادگیری ما:

TXT
 ↓
JSON
 ↓
Pathlib
 ↓
SQLite
 ↓
Automation

و این دقیقاً همان جایی است که پایتون از یک زبان آموزشی ساده، به یک ابزار عملی برای کار با سیستم تبدیل می‌شود.

ZZZ
ZZZ

درس 23 پایتون

پروژهٔ اتوماسیون فروش با Python و Excel

هدف پروژه

فرض کنید یک فروشگاه اطلاعات فروش خود را در فایل:

sales.xlsx

ذخیره کرده است.

پایتون می‌تواند این فایل را بخواند و به‌صورت خودکار:

  • تعداد فروش هر محصول را محاسبه کند.
  • مبلغ فروش هر محصول را محاسبه کند.
  • مجموع فروش را به دست آورد.
  • یک گزارش جدید در فایل report.xlsx ایجاد کند.

۱. ساختار فایل Excel

فایل sales.xlsx می‌تواند چنین جدولی داشته باشد:

product quantity price
Sock 10 200000
Shirt 5 500000
Sock 8 200000
Shoes 3 1200000
Shirt 4 500000
Sock 12 200000

در اینجا:

product

نام محصول است.

quantity

تعداد فروش است.

price

قیمت هر واحد است.


۲. کد اتوماسیون

# ============================================================
#                    فیبیست | PHY20
#              آموزش برنامه‌نویسی پایتون
# ============================================================
#
# وب‌سایت:
# https://www.phy20.com
#
# طراح و برنامه‌نویس:
# مرتضی محمدی‌وند خوشخو
#
# تاریخ:
# ..............................
#
# مجوز و لایسنس کد:
# استفاده از این کد برای مقاصد آموزشی و
# بدون مقاصد تجاری رایگان است.
#
# مالکیت معنوی:
# تمامی حقوق معنوی این کد متعلق به فیبیست (PHY20)
# و طراح و برنامه‌نویس آن محفوظ است.
#
# ============================================================

import pandas as pd

# خواندن فایل Excel
df = pd.read_excel("sales.xlsx")

# محاسبه مبلغ فروش هر ردیف
df["total"] = df["quantity"] * df["price"]

# ساخت گزارش فروش هر محصول
report = df.groupby("product").agg(
    quantity=("quantity", "sum"),
    sales=("total", "sum")
)

# محاسبه مجموع کل فروش
grand_total = report["sales"].sum()

# نمایش گزارش
print("Sales Report")
print(report)

print("nTotal Sales:", grand_total)

# ذخیره گزارش در Excel
report.to_excel("report.xlsx")

print("nReport saved successfully.")

۳. بخش مهم برنامه

ابتدا فایل Excel را می‌خوانیم:

df = pd.read_excel("sales.xlsx")

حالا اطلاعات Excel وارد یک DataFrame به نام df شده است.

می‌توانیم آن را تقریباً مثل یک جدول تصور کنیم:

df
 ↓
جدول اطلاعات فروش

۴. محاسبه مبلغ فروش

این خط بسیار مهم است:

df["total"] = df["quantity"] * df["price"]

یعنی:

تعداد × قیمت
       ↓
مبلغ فروش

مثلاً:

10 × 200000 = 2000000

پایتون این محاسبه را برای تمام ردیف‌های Excel انجام می‌دهد.


۵. گروه‌بندی محصولات

report = df.groupby("product")

یعنی:

محصولات مشابه را کنار یکدیگر قرار بده.

مثلاً:

Sock
Sock
Sock

در یک گروه قرار می‌گیرند.


۶. محاسبه تعداد و مبلغ فروش

report = df.groupby("product").agg(
    quantity=("quantity", "sum"),
    sales=("total", "sum")
)

اینجا برای هر محصول دو محاسبه انجام می‌دهیم:

quantity
↓
مجموع تعداد فروش

sales
↓
مجموع مبلغ فروش

مثلاً خروجی می‌تواند چیزی شبیه این باشد:

product quantity sales
Shirt 9 4,500,000
Shoes 3 3,600,000
Sock 30 6,000,000

۷. محاسبه کل فروش

grand_total = report["sales"].sum()

یعنی تمام مبلغ‌های فروش را با هم جمع کن.

مثلاً:

4,500,000
+ 3,600,000
+ 6,000,000
----------------
14,100,000

۸. ذخیره گزارش جدید

report.to_excel("report.xlsx")

پایتون فایل جدیدی ایجاد می‌کند:

report.xlsx

بنابراین:

sales.xlsx
     ↓
Python
     ↓
تحلیل اطلاعات
     ↓
report.xlsx

۹. ایدهٔ جذاب‌تر برای اتوماسیون

حالا تصور کنید هر روز فایل فروش جدیدی دارید:

sales_01.xlsx
sales_02.xlsx
sales_03.xlsx
...
sales_30.xlsx

به‌جای اینکه هر روز Excel را دستی بررسی کنید، می‌توانیم برنامه‌ای بنویسیم که:

فایل‌های Excel
       ↓
خواندن خودکار
       ↓
ترکیب اطلاعات
       ↓
محاسبه فروش
       ↓
محاسبه پرفروش‌ترین محصول
       ↓
محاسبه کل درآمد
       ↓
ساخت گزارش نهایی

این دیگر یک اتوماسیون واقعی فروش است.


نکتهٔ آموزشی مهم

در این پروژه سه دنیای مختلف را به هم وصل کردیم:

Excel
  ↓
Pandas
  ↓
Python

و نتیجه:

اطلاعات خام
     ↓
تحلیل خودکار
     ↓
گزارش

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

ZZZ

درس 24 پایتون
یک کد اتوماسیون بنویسید که تعداد کلمات تکراری یک مقاله یک صفحه ای فارسی یا انگلیسی را بشمرد و گزارش دهد.

============================================================

فیبیست | PHY20

آموزش برنامه‌نویسی پایتون

============================================================

وب‌سایت:

https://www.phy20.com

طراح و برنامه‌نویس:

مرتضی محمدی‌وند خوشخو

تاریخ:

…………………………

مجوز و لایسنس کد:

استفاده از این کد برای مقاصد آموزشی و

بدون مقاصد تجاری رایگان است.

مالکیت معنوی:

تمامی حقوق معنوی این کد متعلق به فیبیست (PHY20)

و طراح و برنامه‌نویس آن محفوظ است.

============================================================

============================================================

درس ۲۴

عنوان: شمارش کلمات تکراری یک مقاله

============================================================

from pathlib import Path
from collections import Counter
import re

————————————————————

1. مشخص کردن فایل مقاله

————————————————————

file_path = Path(“article.txt”)

————————————————————

2. خواندن مقاله

————————————————————

text = file_path.read_text(encoding=”utf-8″)

————————————————————

3. تبدیل حروف انگلیسی به حروف کوچک

————————————————————

text = text.lower()

————————————————————

4. استخراج کلمات فارسی و انگلیسی

————————————————————

words = re.findall(r”[آ-یa-zA-Z]+”, text)

————————————————————

5. شمارش تعداد تکرار هر کلمه

————————————————————

word_count = Counter(words)

————————————————————

6. مرتب کردن کلمات بر اساس تعداد تکرار

————————————————————

report = word_count.most_common()

————————————————————

7. نمایش گزارش

————————————————————

print(“================================”)
print(” WORD FREQUENCY REPORT”)
print(“================================”)

print(“Total words:”, len(words))
print(“Unique words:”, len(word_count))

print(“nRepeated words:”)
print(“——————————–“)

for word, count in report:
if count > 1:
print(word, “:”, count)

————————————————————

8. ذخیره گزارش در یک فایل جدید

————————————————————

report_path = Path(“word_report.txt”)

with report_path.open(“w”, encoding=”utf-8″) as file:

file.write("WORD FREQUENCY REPORTn")
file.write("=====================nn")

file.write(f"Total words: {len(words)}n")
file.write(f"Unique words: {len(word_count)}nn")

file.write("Repeated words:n")
file.write("---------------------n")

for word, count in report:

    if count > 1:
        file.write(f"{word} : {count}n")

print(“nReport saved successfully.”)
print(“File:”, report_path)


## ایده‌ی پروژه

فرض کنید یک مقاله‌ی یک‌صفحه‌ای داریم و می‌خواهیم بدانیم:

- مقاله چند کلمه دارد؟
- چند کلمه‌ی متفاوت دارد؟
- کدام کلمات بیشتر تکرار شده‌اند؟
- هر کلمه چند بار استفاده شده است؟
- گزارش را به‌صورت خودکار در یک فایل ذخیره کنیم.

مثلاً اگر مقاله این باشد:

```text
Physics is a science.
Physics helps us understand nature.
Science helps us understand the world.

برنامه می‌تواند گزارشی شبیه این تولید کند:

WORD FREQUENCY REPORT
=====================

Total words: 16
Unique words: 11

Repeated words:
---------------------
physics : 2
is : 2
a : 2
science : 2
helps : 2
us : 2
understand : 2

بخش اول — خواندن فایل

from pathlib import Path

file_path = Path("article.txt")

text = file_path.read_text(encoding="utf-8")

در این قسمت فایل مقاله را مشخص می‌کنیم.

فایل ما:

article.txt

است.

دستور:

read_text()

تمام متن فایل را می‌خواند و در متغیر text قرار می‌دهد.

عبارت:

encoding="utf-8"

برای این مهم است که فایل بتواند حروف فارسی و انگلیسی را به‌درستی بخواند.


بخش دوم — یکسان‌سازی حروف انگلیسی

text = text.lower()

مثلاً:

Physics
PHYSICS
physics

همه تبدیل می‌شوند به:

physics

در غیر این صورت برنامه ممکن است آنها را سه کلمه‌ی متفاوت در نظر بگیرد.


بخش سوم — پیدا کردن کلمات

words = re.findall(r"[آ-یa-zA-Z]+", text)

اینجا یک ابزار قدرتمند به نام Regular Expression یا regex وارد پروژه می‌شود.

ما به پایتون می‌گوییم:

از داخل متن، رشته‌هایی را پیدا کن که شامل حروف فارسی یا انگلیسی هستند.

بنابراین مثلاً:

Physics is very important.

به چیزی شبیه این تبدیل می‌شود:

["physics", "is", "very", "important"]

برای متن فارسی هم مثلاً:

فیزیک علم طبیعت است.

به:

["فیزیک", "علم", "طبیعت", "است"]

تبدیل می‌شود.


بخش چهارم — شمارش کلمات

from collections import Counter

و سپس:

word_count = Counter(words)

Counter برای شمارش بسیار مناسب است.

مثلاً:

words = [
    "python",
    "physics",
    "python",
    "science",
    "python"
]

نتیجه:

python : 3
physics : 1
science : 1

یعنی برنامه خودش تعداد تکرار هر کلمه را پیدا می‌کند.


بخش پنجم — مرتب کردن گزارش

report = word_count.most_common()

این دستور کلمات را از پرتکرارترین به کم‌تکرارترین مرتب می‌کند.

مثلاً:

python : 12
physics : 8
science : 6
nature : 3

بنابراین بدون اینکه خودمان مرتب‌سازی پیچیده‌ای بنویسیم، گزارش آماده می‌شود.


بخش ششم — فقط کلمات تکراری

در گزارش نوشته‌ایم:

for word, count in report:

    if count > 1:
        print(word, ":", count)

شرط:

count > 1

یعنی فقط کلماتی نمایش داده شوند که حداقل دو بار در مقاله آمده‌اند.

پس کلمه‌ای که فقط یک بار استفاده شده، در بخش «کلمات تکراری» قرار نمی‌گیرد.


بخش هفتم — ذخیره گزارش

گزارش را در این فایل ذخیره می‌کنیم:

report_path = Path("word_report.txt")

و سپس:

with report_path.open("w", encoding="utf-8") as file:

گزارش در فایل:

word_report.txt

ذخیره می‌شود.

در نتیجه پروژه‌ی ما فقط یک برنامه‌ی شمارش نیست؛ بلکه یک اتوماسیون واقعی است:

article.txt
     ↓
خواندن مقاله
     ↓
پیدا کردن کلمات
     ↓
شمارش کلمات
     ↓
مرتب‌سازی
     ↓
تشخیص کلمات تکراری
     ↓
ساخت گزارش
     ↓
word_report.txt

یک نکته‌ی مهم درباره فارسی

در فارسی ممکن است یک کلمه با شکل‌های مختلف نوشته شود.

مثلاً:

می‌رود
میرود
می رود

از نظر معنایی به هم نزدیک‌اند، اما برنامه ممکن است آنها را سه شکل متفاوت ببیند.

همچنین:

کتاب
کتاب،
کتاب.

به کمک regex علائم نگارشی از کلمه جدا می‌شوند.

اما در یک پروژه‌ی حرفه‌ای‌تر می‌توانیم مرحله‌ی بعدی را اضافه کنیم و کارهایی مانند این انجام دهیم:

  • یکسان‌سازی «ی» و «ي»
  • یکسان‌سازی «ک» و «ك»
  • حذف کلمات بسیار رایج مانند «از»، «به»، «در»، «و»
  • حذف Stop Words
  • ریشه‌یابی کلمات
  • تحلیل جداگانه‌ی فارسی و انگلیسی

تمرین درس ۲۴

فایل:

article.txt

بسازید و یک مقاله‌ی یک‌صفحه‌ای فارسی یا انگلیسی داخل آن قرار دهید.

سپس برنامه را اجرا کنید.

برنامه باید دو فایل داشته باشد:

article.txt
word_report.txt

و در گزارش مشخص شود:

Total words
Unique words
Repeated words

پروژه‌ی عملی

در مرحله‌ی بعد می‌توانیم همین برنامه را حرفه‌ای‌تر کنیم تا مثلاً خروجی نهایی چنین باشد:

TOP 10 MOST REPEATED WORDS
===========================

1. physics       18
2. science       14
3. energy        11
4. education      9
5. nature         8
...

و حتی گزارش را به Excel منتقل کنیم:

Word        Count
-----------------
physics       18
science       14
energy        11
education      9
nature         8

در آن صورت، درس ۲۴ عملاً سه موضوعی را که تاکنون یاد گرفته‌ایم به هم وصل می‌کند:

Pathlib
   +
File Handling
   +
Automation
   +
Excel

و یک ابزار واقعی برای تحلیل خودکار متن خواهیم داشت.

ZZZ
ZZZ

درس 25 پایتون

یک ماتریس دلخواه از ورودی نقاط بسازید. حداکثر 10 در 10 نقطه باشد.

============================================================

فیبیست | PHY20

آموزش برنامه‌نویسی پایتون

============================================================

وب‌سایت:

https://www.phy20.com

طراح و برنامه‌نویس:

مرتضی محمدی‌وند خوشخو

تاریخ:

…………………………

مجوز و لایسنس کد:

استفاده از این کد برای مقاصد آموزشی و

بدون مقاصد تجاری رایگان است.

مالکیت معنوی:

تمامی حقوق معنوی این کد متعلق به فیبیست (PHY20)

و طراح و برنامه‌نویس آن محفوظ است.

============================================================

============================================================

درس ۲۵

عنوان: ساخت خودکار ماتریس نقاط

============================================================

subscript = “₀₁₂₃₄₅₆₇₈₉”

————————————————————

1. دریافت تعداد سطر و ستون

————————————————————

rows = int(input(“Enter number of rows (1-10): “))
columns = int(input(“Enter number of columns (1-10): “))

————————————————————

2. کنترل محدوده

————————————————————

if rows < 1 or rows > 10 or columns < 1 or columns > 10:

print("Error: Matrix size must be between 1 and 10.")

else:

print("nPoint Matrix:")
print("------------------------------")


# --------------------------------------------------------
# 3. ساخت سطرهای ماتریس
# --------------------------------------------------------

for row in range(1, rows + 1):

    row_text = ""

    # تبدیل شماره سطر به زیروند
    for digit in str(row):
        row_text += subscript[int(digit)]


    # ----------------------------------------------------
    # 4. ساخت ستون‌های همان سطر
    # ----------------------------------------------------

    for column in range(1, columns + 1):

        column_text = ""

        # تبدیل شماره ستون به زیروند
        for digit in str(column):
            column_text += subscript[int(digit)]


        # ------------------------------------------------
        # 5. ساخت نام نقطه
        # ------------------------------------------------

        print("x" + row_text + column_text, end="   ")


    # رفتن به سطر بعدی
    print()

## خروجی برای ماتریس ۵×۵

اگر کاربر وارد کند:

```text
Enter number of rows (1-10): 5
Enter number of columns (1-10): 5

خروجی:

Point Matrix:
------------------------------

x₁₁   x₁₂   x₁₃   x₁₄   x₁₅
x₂₁   x₂₂   x₂₃   x₂₄   x₂₅
x₃₁   x₃₂   x₃₃   x₃₄   x₃₅
x₄₁   x₄₂   x₄₃   x₄₄   x₄₅
x₅₁   x₅₂   x₅₃   x₅₄   x₅₅

ایده‌ی اصلی برنامه

ما در واقع یک دستگاه مختصات ساده ساخته‌ایم.

هر نقطه دو شماره دارد:

xᵢⱼ

که در برنامه:

row    → شماره سطر
column → شماره ستون

است.

مثلاً:

x₃₄

یعنی:

سطر ۳
ستون ۴

بنابراین برنامه می‌تواند به‌صورت خودکار نقاط زیر را ایجاد کند:

x₁₁  x₁₂  x₁₃  x₁₄  ...
x₂₁  x₂₂  x₂₃  x₂₄  ...
x₃₁  x₃₂  x₃₃  x₃₄  ...
...

بخش مهم اول — زیروندها

این خط:

subscript = "₀₁₂₃₄₅₆₇₈₉"

یک رشته شامل اعداد زیروندی یونیکد است.

یعنی:

subscript[0] → ₀
subscript[1] → ₁
subscript[2] → ₂
...
subscript[9] → ₉

بنابراین اگر داشته باشیم:

digit = 4

می‌توانیم بنویسیم:

subscript[digit]

و نتیجه می‌شود:

₄

بخش مهم دوم — تبدیل عدد به زیروند

فرض کنید:

row = 7

ابتدا:

str(row)

عدد ۷ را به متن تبدیل می‌کند:

"7"

سپس:

for digit in str(row):

روی رقم آن حرکت می‌کند.

و:

subscript[int(digit)]

رقم ۷ را به زیروند ₇ تبدیل می‌کند.

پس:

7 → "7" → 7 → ₇

چرا این قسمت را با حلقه نوشته‌ایم؟

چون می‌خواهیم برنامه در آینده فقط برای اعداد یک‌رقمی محدود نباشد.

مثلاً:

12

باید تبدیل شود به:

₁₂

پس:

for digit in str(row):

رقم‌های عدد را یکی‌یکی بررسی می‌کند.

برای عدد ۱۲:

1 → ₁
2 → ₂

و در نهایت:


# ==========================================
# PROJECT #25
# Name: Sarina
# Python – Point Matrix Automation
# ==========================================

subscript = “₀₁₂₃₄₅₆₇₈₉”

# تعداد سطرها و ستون‌ها
rows = 10
columns = 10

# ایجاد ماتریس نقاط
for row in range(1, rows + 1):

for column in range(1, columns + 1):

# تبدیل شماره ستون به اندیس زیرنویس
column_text = “”

for digit in str(column):
column_text += subscript[int(digit)]

# نمایش نقطه همراه با شماره
print(“●” + column_text, end=” “)

# رفتن به سطر بعد
print()

ZZZ
ZZZ

درس 26 پایتون
با کمک درس 25 حرکت موجی ذرات را در یک ماتریس نمایش دهید و کنترل کنید.

============================================================

فیبیست | PHY20

آموزش برنامه‌نویسی پایتون

============================================================

وب‌سایت:

https://www.phy20.com

طراح و برنامه‌نویس:

مرتضی محمدی‌وند خوشخو

تاریخ:

…………………………

مجوز و لایسنس کد:

استفاده از این کد برای مقاصد آموزشی و

بدون مقاصد تجاری رایگان است.

مالکیت معنوی:

تمامی حقوق معنوی این کد متعلق به فیبیست (PHY20)

و طراح و برنامه‌نویس آن محفوظ است.

============================================================

============================================================

درس ۲۶

عنوان: نمایش حرکت موجی ذرات

============================================================

import tkinter as tk
import math

————————————————————

1. ساخت پنجره

————————————————————

window = tk.Tk()

window.title(“Python Wave”)

window.geometry(“900×500″)

window.configure(bg=”black”)

————————————————————

2. ساخت صفحه‌ی رسم

————————————————————

canvas = tk.Canvas(
window,
width=900,
height=500,
bg=”black”,
highlightthickness=0
)

canvas.pack()

————————————————————

3. تنظیمات موج

————————————————————

width = 900
height = 500

تعداد ذرات

points = 30

دامنه‌ی موج

amplitude = 100

سرعت حرکت موج

speed = 0.12

فاصله‌ی زمانی بین فریم‌ها

delay = 30

————————————————————

4. ایجاد ذرات

————————————————————

dots = []

for i in range(points):

x = i * width / (points - 1)

y = height / 2

dot = canvas.create_oval(
    x - 5,
    y - 5,
    x + 5,
    y + 5,
    fill="white",
    outline=""
)

dots.append(dot)

————————————————————

5. متغیر فاز موج

————————————————————

phase = 0

————————————————————

6. تابع حرکت موج

————————————————————

def wave():

global phase

for i in range(points):

    # موقعیت افقی ذره
    x = i * width / (points - 1)

    # زاویه‌ی موج
    angle = i * 0.35 + phase

    # محاسبه‌ی موقعیت عمودی
    y = height / 2 + amplitude * math.sin(angle)

    # جابه‌جایی ذره
    canvas.coords(
        dots[i],
        x - 5,
        y - 5,
        x + 5,
        y + 5
    )

# حرکت موج
phase += speed

# اجرای دوباره‌ی تابع
window.after(delay, wave)

————————————————————

7. شروع حرکت

————————————————————

wave()

————————————————————

8. اجرای پنجره

————————————————————

window.mainloop()


## نتیجه‌ی اجرای برنامه

با اجرای برنامه یک پنجره‌ی سیاه باز می‌شود و **۳۰ ذره** در عرض صفحه قرار می‌گیرند.

ذرات به شکل یک موج سینوسی بالا و پایین حرکت می‌کنند:

```text
       ●
          ●
             ●
                ●
                   ●
                      ●
                         ●

و شکل موج دائماً در حال حرکت خواهد بود.


۱. tkinter چیست؟

در این پروژه:

import tkinter as tk

از کتابخانه‌ی tkinter استفاده کرده‌ایم.

tkinter یکی از ابزارهای استاندارد پایتون برای ساخت پنجره و عناصر گرافیکی است.

ما با آن:

  • پنجره می‌سازیم.
  • صفحه‌ی رسم ایجاد می‌کنیم.
  • نقطه ایجاد می‌کنیم.
  • موقعیت نقطه را تغییر می‌دهیم.

۲. ساخت پنجره

window = tk.Tk()

پنجره‌ی اصلی برنامه ساخته می‌شود.

سپس:

window.title("Python Wave")

عنوان پنجره را مشخص می‌کند.

و:

window.geometry("900x500")

اندازه‌ی پنجره را تعیین می‌کند:

عرض = 900
ارتفاع = 500

۳. Canvas چیست؟

این قسمت:

canvas = tk.Canvas(
    window,
    width=900,
    height=500,
    bg="black",
    highlightthickness=0
)

یک صفحه‌ی رسم ایجاد می‌کند.

می‌توانیم آن را مانند یک کاغذ در نظر بگیریم که روی آن شکل‌ها را رسم می‌کنیم.

در این پروژه Canvas محل حرکت ذرات است.


۴. تعداد ذرات

points = 30

یعنی:

۳۰ ذره داریم.

این همان ایده‌ای است که در درس ۲۵ داشتیم.

اگر بنویسیم:

points = 10

فقط ۱۰ ذره خواهیم داشت.

اگر بنویسیم:

points = 100

موج با ۱۰۰ ذره نمایش داده می‌شود.


۵. دامنه‌ی موج

amplitude = 100

دامنه تعیین می‌کند ذرات چقدر بالا و پایین حرکت کنند.

رابطه‌ی اصلی ما:

y = height / 2 + amplitude * math.sin(angle)

است.

اگر:

amplitude = 50

باشد، موج کم‌ارتفاع‌تر می‌شود.

اگر:

amplitude = 150

باشد، موج ارتفاع بیشتری خواهد داشت.

پس:

دامنه بیشتر
      ↓
حرکت عمودی بیشتر

۶. چرا math.sin؟

در این قسمت:

math.sin(angle)

از تابع سینوسی استفاده کرده‌ایم.

تابع سینوس مقدارهایی بین:

-1

تا:

+1

تولید می‌کند.

وقتی آن را در دامنه ضرب کنیم:

amplitude * math.sin(angle)

حرکت بالا و پایین ذره ایجاد می‌شود.

بنابراین:

سینوس
  ↓
موقعیت عمودی
  ↓
حرکت موجی

۷. ایجاد ذرات

این قسمت بسیار مهم است:

for i in range(points):

حلقه برای هر ذره یک بار اجرا می‌شود.

موقعیت افقی هر ذره:

x = i * width / (points - 1)

محاسبه می‌شود.

بنابراین ۳۰ ذره تقریباً به‌صورت یکنواخت در عرض ۹۰۰ پیکسل پخش می‌شوند.

مثلاً:

●        ●        ●        ●        ●
|        |        |        |        |
0       225      450      675      900

۸. ساخت هر ذره

در tkinter دایره را با:

canvas.create_oval()

می‌سازیم.

مثلاً:

dot = canvas.create_oval(
    x - 5,
    y - 5,
    x + 5,
    y + 5,
    fill="white",
    outline=""
)

در واقع یک دایره‌ی کوچک ایجاد می‌شود.

و شناسه‌ی آن در:

dot

قرار می‌گیرد.

سپس آن را داخل لیست:

dots

ذخیره می‌کنیم.


۹. مهم‌ترین قسمت: حرکت ذرات

تابع:

def wave():

وظیفه‌ی حرکت دادن تمام ذرات را دارد.

در هر بار اجرای تابع:

for i in range(points):

تمام ۳۰ ذره بررسی می‌شوند.

برای هر ذره ابتدا موقعیت افقی مشخص می‌شود:

x = i * width / (points - 1)

بعد زاویه‌ی آن محاسبه می‌شود:

angle = i * 0.35 + phase

و در نهایت موقعیت عمودی:

y = height / 2 + amplitude * math.sin(angle)

به دست می‌آید.


۱۰. phase چیست؟

این متغیر:

phase = 0

برای حرکت دادن خود موج استفاده می‌شود.

بعد از هر فریم:

phase += speed

اجرا می‌شود.

مثلاً:

فریم اول:
phase = 0

فریم دوم:
phase = 0.12

فریم سوم:
phase = 0.24

فریم چهارم:
phase = 0.36

پس موج در هر فریم کمی جلو می‌رود.

اگر phase ثابت می‌ماند، ذرات فقط یک شکل ثابت از موج را تشکیل می‌دادند و حرکت نمی‌کردند.


۱۱. جابه‌جایی واقعی ذره

این دستور:

canvas.coords(
    dots[i],
    x - 5,
    y - 5,
    x + 5,
    y + 5
)

مختصات دایره را تغییر می‌دهد.

بنابراین ما ذره‌ی جدید نمی‌سازیم.

همان ذره را جابه‌جا می‌کنیم.

این نکته برای انیمیشن بسیار مهم است:

ساخت ذرات
     ↓
تغییر مختصات
     ↓
نمایش فریم جدید
     ↓
تغییر مختصات
     ↓
نمایش فریم بعدی

۱۲. دستور after

این قسمت قلب انیمیشن است:

window.after(delay, wave)

در اینجا:

delay = 30

یعنی تقریباً بعد از ۳۰ میلی‌ثانیه، تابع wave دوباره اجرا شود.

پس برنامه مرتب این کار را تکرار می‌کند:

wave()
  ↓
30 ms
  ↓
wave()
  ↓
30 ms
  ↓
wave()
  ↓
30 ms
  ↓
...

و چشم ما این فریم‌های سریع را به صورت حرکت موج می‌بیند.


۱۳. اگر سرعت موج را تغییر دهیم؟

سرعت فعلی:

speed = 0.12

است.

اگر بنویسیم:

speed = 0.05

موج آهسته‌تر حرکت می‌کند.

اگر بنویسیم:

speed = 0.30

حرکت موج سریع‌تر می‌شود.

بنابراین:

speed ↑
حرکت موج سریع‌تر

speed ↓
حرکت موج آهسته‌تر

۱۴. اگر تعداد نقاط را بیشتر کنیم؟

در این پروژه:

points = 30

را انتخاب کرده‌ایم.

اگر بنویسیم:

points = 60

موج نرم‌تر دیده می‌شود.

اگر:

points = 100

باشد، نقاط بیشتری خواهیم داشت.

اما افزایش بیش از حد تعداد نقاط لزوماً همیشه بهتر نیست؛ چون هر فریم باید تعداد بیشتری ذره جابه‌جا شود.


۱۵. رابطه‌ی فیزیکی موج

فرمولی که در برنامه استفاده کردیم:

y = height / 2 + amplitude * math.sin(angle)

از نظر مفهومی شبیه رابطه‌ی یک موج سینوسی است:

y = y₀ + A sin(θ)

که در آن:

y₀       → خط تعادل
A        → دامنه
θ        → فاز

و ما با تغییر فاز در زمان، حرکت موج را ایجاد کرده‌ایم.


نکته‌ی مهم فیزیکی

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

این موضوع برای آموزش مفهوم موج بسیار جالب است:

حرکت ذرات
     ↕
     ↕
     ↕
     ↕

حرکت موج
→ → → → → → →

یعنی الزاماً حرکت موج و حرکت ذرات یکسان نیست.


آزمایش‌های پیشنهادی

فقط این چهار عدد را تغییر دهید و نتیجه را مشاهده کنید:

points = 30
amplitude = 100
speed = 0.12
delay = 30

آزمایش ۱

points = 60

آزمایش ۲

amplitude = 50

آزمایش ۳

speed = 0.05

آزمایش ۴

speed = 0.30

آزمایش ۵

delay = 60

و تفاوت حرکت را با حالت:

delay = 15

مقایسه کنید.


پروژه‌ی تکمیلی درس ۲۶

در نسخه‌ی بعدی می‌توانیم برنامه را یک مرحله جذاب‌تر کنیم و این قابلیت‌ها را اضافه کنیم:

تعداد نقاط       ← قابل تنظیم
دامنه             ← قابل تنظیم
طول موج           ← قابل تنظیم
سرعت              ← قابل تنظیم
زمان انیمیشن      ← قابل تنظیم

و مهم‌تر از همه، عرض گوشی یا مانیتور را به‌عنوان طول موج/دامنه‌ی فضایی در نظر بگیریم و تعداد نقاط را افزایش دهیم تا حرکت بسیار نرم‌تر شود.

در آن حالت، از یک مدل ساده‌ی:

y = A sin(kx + φ)

به یک شبیه‌سازی واقعی‌تر می‌رسیم؛ یعنی دقیقاً همان جایی که پایتون، ریاضیات و فیزیک به هم وصل می‌شوند.

ZZZ
ZZZ

دیدگاهتان را بنویسید