در این سطح از برنامه نویسی پایتون ، به سراغ ساخت کدهای اتوماسیون می رویم.
درس ۲۲ پایتون
اتوماسیون انتقال فایلهای 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
و این دقیقاً همان جایی است که پایتون از یک زبان آموزشی ساده، به یک ابزار عملی برای کار با سیستم تبدیل میشود.
درس 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 را نمیخواند؛ از اطلاعات داخل آن تصمیمهای محاسباتی و گزارش قابل استفاده تولید میکند.
درس 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
و یک ابزار واقعی برای تحلیل خودکار متن خواهیم داشت.
درس 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()
درس 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 + φ)
به یک شبیهسازی واقعیتر میرسیم؛ یعنی دقیقاً همان جایی که پایتون، ریاضیات و فیزیک به هم وصل میشوند.

