Python3
200 subscribers
100 photos
6 videos
26 files
518 links
🎓 آموزش و پروژه‌های Python
آموزش‌های کاربردی و پروژه‌های عملی Python برای همه سطوح. 🚀
Download Telegram
پارت 2: الگوریتم‌های پیمایش گراف
یکی از مهم‌ترین بخش‌های کار با گراف‌ها، پیمایش (Traversal) است. با پیمایش گراف می‌توان به اطلاعات مختلف دست یافت، مانند:
- بررسی اتصال رأس‌ها (🔗).
- یافتن مسیر بین رأس‌ها (🚶‍♂️).
- تحلیل داده‌های گراف (📊).



🎯 انواع پیمایش گراف:
1. پیمایش عرضی (BFS - Breadth First Search):
- گراف را به صورت لایه‌لایه (📏) پیمایش می‌کند.
- از یک رأس شروع کرده و ابتدا رأس‌های مجاور را بررسی می‌کند.
- مناسب برای پیدا کردن کوتاه‌ترین مسیر.

💡 مراحل BFS:
1. رأس شروع را در یک صف (Queue) قرار دهید.
2. رأس جاری را بازدید کرده و رأس‌های مجاور را به صف اضافه کنید.
3. تا خالی شدن صف، مراحل را تکرار کنید.

کد BFS در پایتون:

   from collections import deque

def bfs(graph, start):
visited = set()
queue = deque([start])
while queue:
node = queue.popleft()
if node not in visited:
print(node, end=" ")
visited.add(node)
queue.extend(graph[node])

# تعریف گراف
graph = {
'1': ['2', '3'],
'2': ['4', '5'],
'3': ['6'],
'4': [],
'5': [],
'6': []
}
print("BFS:", end=" ")
bfs(graph, '1')



2. پیمایش عمقی (DFS - Depth First Search):
- گراف را به صورت عمقی (🔍) پیمایش می‌کند.
- ابتدا رأس شروع و سپس رأس‌های فرزندان هر رأس بررسی می‌شوند.
- مناسب برای بررسی تمام مسیرهای ممکن.

💡 مراحل DFS:
1. رأس شروع را به یک پشته (Stack) اضافه کنید.
2. رأس جاری را بازدید کرده و رأس‌های فرزند را به پشته اضافه کنید.
3. تا خالی شدن پشته، مراحل را تکرار کنید.

کد DFS در پایتون:

   def dfs(graph, start, visited=None):
if visited is None:
visited = set()
visited.add(start)
print(start, end=" ")
for neighbor in graph[start]:
if neighbor not in visited:
dfs(graph, neighbor, visited)

# تعریف گراف
graph = {
'1': ['2', '3'],
'2': ['4', '5'],
'3': ['6'],
'4': [],
'5': [],
'6': []
}
print("DFS:", end=" ")
dfs(graph, '1')



📚 جمع‌بندی:
- BFS برای پیدا کردن کوتاه‌ترین مسیر مناسب است.
- DFS برای جستجوی عمیق و بررسی همه مسیرها به‌کار می‌رود.
در پارت بعدی با الگوریتم‌های پیشرفته مثل دایکسترا و درخت پوشای کمینه آشنا خواهیم شد.


#پیمایش_گراف #BFS #DFS #الگوریتم_گراف #آموزش_تلگرام
پارت 3: الگوریتم‌های پیشرفته گراف
در این بخش با الگوریتم‌های پیشرفته برای حل مسائل مختلف گراف آشنا می‌شویم. این الگوریتم‌ها در تحلیل شبکه‌ها، مسیریابی و بهینه‌سازی کاربرد دارند.



🎯 الگوریتم‌های یافتن کوتاه‌ترین مسیر
1. الگوریتم دایکسترا (Dijkstra):
- برای گراف‌های وزن‌دار با یال‌های مثبت مناسب است.
- کوتاه‌ترین مسیر از یک رأس به تمام رأس‌های دیگر را پیدا می‌کند.

💡 مراحل:
1. مقدار فاصله از رأس شروع به خود را 0 و بقیه رأس‌ها را بی‌نهایت قرار دهید.
2. رأس‌هایی که بازدید نشده‌اند را بررسی کرده و مسیر کوتاه‌تر را به‌روزرسانی کنید.
3. تا بازدید از تمام رأس‌ها، مراحل را تکرار کنید.

کد دایکسترا در پایتون:

   import heapq

def dijkstra(graph, start):
distances = {node: float('inf') for node in graph}
distances[start] = 0
priority_queue = [(0, start)]

while priority_queue:
current_distance, current_node = heapq.heappop(priority_queue)

if current_distance > distances[current_node]:
continue

for neighbor, weight in graph[current_node].items():
distance = current_distance + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(priority_queue, (distance, neighbor))

return distances

# تعریف گراف
graph = {
'1': {'2': 4, '3': 1},
'2': {'4': 1},
'3': {'2': 2, '4': 5},
'4': {}
}
print("Shortest distances:", dijkstra(graph, '1'))


2. الگوریتم بلمن-فورد (Bellman-Ford):
- برای گراف‌های وزن‌دار با یال‌های مثبت و منفی مناسب است.
- همچنین حلقه‌های منفی (Negative Cycles) را تشخیص می‌دهد.

💡 مراحل:
1. فاصله از رأس شروع را به 0 و بقیه رأس‌ها را بی‌نهایت قرار دهید.
2. برای تمام یال‌ها، مسیرها را بهینه کنید.
3. در صورت وجود بهینه‌سازی اضافی پس از n-1 بار، حلقه منفی وجود دارد.


🎯 درخت پوشای کمینه (Minimum Spanning Tree)
1. الگوریتم کروسکال (Kruskal):
- برای یافتن درختی که همه رأس‌ها را با کمترین هزینه متصل کند.
- ابتدا یال‌ها را بر اساس وزن مرتب کرده و یکی‌یکی اضافه می‌کند.
- از اتحاد و یافتن (Union-Find) برای جلوگیری از حلقه استفاده می‌کند.

2. الگوریتم پریم (Prim):
- مشابه کروسکال، اما از یک رأس شروع می‌کند و رأس‌های متصل‌شده را گسترش می‌دهد.



📚 جمع‌بندی:
- دایکسترا سریع و برای یال‌های مثبت عالی است.
- بلمن-فورد برای یال‌های منفی کاربرد دارد.
- کروسکال و پریم برای ساخت درخت پوشای کمینه بهینه هستند.

امیدوارم این آموزش مفید بوده باشد! 🙌



#دایکسترا #بلمن_فورد #درخت_پوشا #الگوریتم_گراف #آموزش_تلگرام
👍4
؟
👏4
آموزش ماژول جدید یا که آموزش الگوریتم ؟
👍1
🎓 آموزش الگوریتم مرتب‌سازی رادیکس (پارت 1)

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



🌟 الگوریتم رادیکس چیست؟
الگوریتم Radix Sort یک روش مرتب‌سازی غیرمقایسه‌ای است.
این روش به جای مقایسه عناصر، اعداد را بر اساس ارقامشان مرتب می‌کند، از رقم کم‌ارزش‌تر (Least Significant Digit) به رقم پرارزش‌تر (Most Significant Digit) یا برعکس.

این الگوریتم مناسب داده‌هایی است که به صورت عددی یا رشته‌ای (مانند اعداد کارت بانکی یا کد پستی) هستند.



🧠 ایده اصلی پشت Radix Sort
ایده ساده است:
1. ابتدا اعداد را بر اساس رقم یکان مرتب می‌کنیم.
2. سپس بر اساس رقم دهگان، صدگان، و الی آخر.
3. در نهایت، لیستی مرتب خواهیم داشت! 🎉



💡 چرا Radix Sort مهم است؟
1. سریع‌تر از بسیاری از الگوریتم‌ها: اگر داده‌ها توزیع مناسبی داشته باشند، رادیکس می‌تواند عملکرد بهتری نسبت به الگوریتم‌های مقایسه‌ای مانند Quick Sort یا Merge Sort داشته باشد.
2. پیاده‌سازی ساده برای داده‌های خاص: اگر طول داده‌ها محدود باشد، این روش بسیار کارآمد است.



🎯 کاربردهای Radix Sort
- مرتب‌سازی شماره حساب‌ها
- مرتب‌سازی کدهای پستی
- سیستم‌های بانکی و تجاری


🧩 در پارت بعدی...
در پارت 2، به مراحل و نحوه عملکرد الگوریتم رادیکس همراه با مثال واقعی می‌پردازیم!
حتماً دنبال کنید و یادگیری را ادامه دهید. 🌱

بزن رو این تا بیشتر یاد بگیری

#آموزش_پایتون #مرتب_سازی #RadixSort #الگوریتم #پایتون #برنامه_نویسی
🎓 آموزش الگوریتم مرتب‌سازی رادیکس (پارت ۲)

🔰 مراحل و نحوه عملکرد الگوریتم رادیکس

در پارت قبل با مفهوم کلی Radix Sort آشنا شدیم. حالا در این بخش می‌خواهیم مراحل اجرای این الگوریتم را با توضیحات و یک مثال کاربردی بررسی کنیم. 🛠️


🌟 مراحل اجرای Radix Sort
1️⃣ شناسایی بیشترین رقم عدد:
ابتدا طول بزرگ‌ترین عدد را پیدا می‌کنیم (تعداد ارقام). این به ما می‌گوید که چند مرحله نیاز به مرتب‌سازی داریم.

2️⃣ مرتب‌سازی بر اساس ارقام (از راست به چپ):
- ابتدا اعداد را بر اساس رقم یکان مرتب می‌کنیم.
- سپس به رقم دهگان، صدگان و ... می‌رویم.

3️⃣ استفاده از مرتب‌سازی پایدار (Stable Sort):
در هر مرحله، باید از یک روش مرتب‌سازی پایدار (مثل Counting Sort) استفاده کنیم، تا ترتیب قبلی حفظ شود.

4️⃣ تکرار تا رسیدن به رقم بیشینه:
این فرآیند تا مرتب شدن کامل ادامه پیدا می‌کند.



🧠 مثال: مرتب‌سازی لیست [170, 45, 75, 90, 802, 24, 2, 66]

#### 🔹 مرحله ۱: مرتب‌سازی بر اساس رقم یکان
اعداد را بر اساس رقم یکان مرتب می‌کنیم:
[170, 802, 2, 24, 45, 75, 66, 90]

🔹 مرحله ۲: مرتب‌سازی بر اساس رقم دهگان
اعداد را بر اساس رقم دهگان مرتب می‌کنیم:
[802, 2, 24, 45, 66, 170, 75, 90]

🔹 مرحله ۳: مرتب‌سازی بر اساس رقم صدگان
اعداد را بر اساس رقم صدگان مرتب می‌کنیم:
[2, 24, 45, 66, 75, 90, 170, 802]

اکنون لیست مرتب‌شده نهایی داریم:
[2, 24, 45, 66, 75, 90, 170, 802] 🎉



🔑 نکات مهم:
- این الگوریتم از مرتب‌سازی پایدار استفاده می‌کند.
- عملکرد آن برای مقادیر بزرگ و تعداد ارقام ثابت بسیار عالی است.
- پیاده‌سازی به روش عددی یا رشته‌ای قابل انجام است.



🧩 در پارت بعدی...
در پارت ۳، کدنویسی الگوریتم Radix Sort در پایتون را گام به گام بررسی می‌کنیم. آماده شوید تا کد بنویسیم! 👩‍💻👨‍💻



🔗 بزن رو این تا بیشتر یاد بگیری

#آموزش_پایتون #مرتب_سازی #RadixSort #الگوریتم #پایتون #برنامه_نویسی
🎓 آموزش الگوریتم مرتب‌سازی رادیکس (پارت ۳)

🔰 پیاده‌سازی Radix Sort در پایتون

در این بخش با هم کدنویسی الگوریتم Radix Sort را در پایتون انجام می‌دهیم. با یک رویکرد ساده و گام‌به‌گام پیش می‌رویم تا همه چیز کاملاً شفاف و قابل‌فهم باشد.

🌟 کد Radix Sort گام‌به‌گام

1️⃣ مرتب‌سازی کمکی با Counting Sort
ابتدا یک تابع برای مرتب‌سازی پایدار (Stable Sort) براساس رقم خاص (یکان، دهگان و ...) ایجاد می‌کنیم.

def counting_sort(arr, exp):
n = len(arr)
output = [0] * n # آرایه خروجی
count = [0] * 10 # آرایه شمارش (اعداد 0 تا 9)

# شمارش تعداد وقوع هر رقم
for i in range(n):
index = (arr[i] // exp) % 10
count[index] += 1

# تغییر آرایه شمارش برای یافتن موقعیت هر عنصر
for i in range(1, 10):
count[i] += count[i - 1]

# ساخت آرایه خروجی
i = n - 1
while i >= 0:
index = (arr[i] // exp) % 10
output[count[index] - 1] = arr[i]
count[index] -= 1
i -= 1

# کپی آرایه خروجی به آرایه اصلی
for i in range(n):
arr[i] = output[i]



2️⃣ تابع اصلی Radix Sort
حال، یک تابع اصلی ایجاد می‌کنیم که از تابع Counting Sort استفاده کرده و داده‌ها را مرحله به مرحله مرتب می‌کند.

def radix_sort(arr):
# یافتن بزرگ‌ترین عدد برای تعیین تعداد ارقام
max_num = max(arr)
exp = 1 # مقدار اولیه (یکان)

# مرتب‌سازی برای هر رقم (یکان، دهگان، ...)
while max_num // exp > 0:
counting_sort(arr, exp)
exp *= 10



3️⃣ آزمایش الگوریتم با مثال
حالا الگوریتم خود را روی یک مجموعه داده اجرا می‌کنیم.

if __name__ == "__main__":
arr = [170, 45, 75, 90, 802, 24, 2, 66]
print("قبل از مرتب‌سازی:", arr)
radix_sort(arr)
print("بعد از مرتب‌سازی:", arr)



🧪 خروجی کد:
قبل از مرتب‌سازی: [170, 45, 75, 90, 802, 24, 2, 66]  
بعد از مرتب‌سازی: [2, 24, 45, 66, 75, 90, 170, 802]

🎉 الگوریتم به‌درستی اجرا شد و لیست مرتب شد!



🔑 نکات کدنویسی:
- دقت کنید که Counting Sort مرتب‌سازی پایدار است، یعنی ترتیب اعداد با مقدار یکسان حفظ می‌شود.
- این الگوریتم زمانی کارآمد است که تعداد ارقام بزرگ‌تر از تعداد کل مقایسه‌ها در الگوریتم‌های دیگر نباشد.



🧩 در پارت بعدی...
در پارت ۴، به تحلیل زمان اجرا، پیچیدگی زمانی و فضایی، و مزایا و معایب الگوریتم Radix Sort می‌پردازیم. حتماً همراه ما باشید! 🌟



🔗 بزن رو این تا بیشتر یاد بگیری

#آموزش_پایتون #مرتب_سازی #RadixSort #الگوریتم #پایتون #برنامه_نویسی
🎓 آموزش الگوریتم مرتب‌سازی رادیکس (پارت ۴)

🔰 تحلیل و بررسی Radix Sort

در این پارت پایانی، به بررسی عملکرد الگوریتم Radix Sort از نظر زمان اجرا، فضای موردنیاز، مزایا، معایب و کاربردهای آن می‌پردازیم. این اطلاعات به شما کمک می‌کند تا بدانید چه زمانی از این الگوریتم استفاده کنید. 📊



🌟 پیچیدگی زمانی Radix Sort

حالت عادی (Average Case):
اگر تعداد عناصر لیست n و بیشترین طول ارقام d باشد:
O(n * d)


یعنی زمان اجرا خطی است، به شرطی که تعداد ارقام d کوچک باشد.

حالت بدترین (Worst Case):
مشابه حالت عادی:
O(n * d)



حالت بهترین (Best Case):
باز هم همان پیچیدگی:
O(n * d)





🌟 پیچیدگی فضایی (Space Complexity):
Radix Sort به دلیل استفاده از آرایه کمکی (مثل آرایه شمارش)، به فضای اضافی نیاز دارد:
O(n + k)


که k تعداد مقدارهای ممکن در هر رقم است (برای اعداد دهدهی، معمولاً 10).



🌟 مزایا و معایب Radix Sort

مزایا:
1. پیچیدگی زمانی خطی: در داده‌هایی با تعداد رقم کم، Radix Sort عملکرد سریعی دارد.
2. مرتب‌سازی پایدار: ترتیب عناصر مشابه حفظ می‌شود، که در مسائل خاص مفید است.
3. عدم نیاز به مقایسه: برخلاف Quick Sort یا Merge Sort، این الگوریتم بر اساس مقایسه عمل نمی‌کند.

معایب:
1. نیاز به فضای اضافی: استفاده از آرایه‌های کمکی باعث مصرف حافظه بیشتری می‌شود.
2. محدودیت داده‌ها: این الگوریتم برای داده‌های با طول زیاد (مثل رشته‌های بسیار بزرگ) کارآمد نیست.
3. وابستگی به تعداد ارقام: اگر تعداد ارقام زیاد باشد، Radix Sort ناکارآمد می‌شود.

🌟 چه زمانی از Radix Sort استفاده کنیم؟
- داده‌های عددی بزرگ با ارقام کم: مانند کدهای پستی، شماره حساب‌ها و ...
- وقتی نیاز به مرتب‌سازی پایدار داریم: چون ترتیب عناصر با مقدار برابر حفظ می‌شود.
- وقتی مقایسه‌ها در مرتب‌سازی گران است: مثل داده‌های خاص که مقایسه‌ی مستقیم دشوار است.



🧩 نتیجه‌گیری
Radix Sort یک الگوریتم قدرتمند و کارآمد برای مرتب‌سازی اعداد است، مخصوصاً در شرایطی که تعداد ارقام محدود باشد. با این حال، اگر به فضای زیادی نیاز نداشته باشید یا داده‌های خاصی دارید، ممکن است الگوریتم‌های دیگر مانند Quick Sort یا Merge Sort انتخاب بهتری باشند.



🔗 بزن رو این تا بیشتر یاد بگیری

#آموزش_پایتون #مرتب_سازی #RadixSort #الگوریتم #پایتون #برنامه_نویسی
شبکه‌های عصبی مصنوعی: مغز ماشینی دنیای مدرن 🧠🤖

مقدمه: چرا شبکه‌های عصبی؟
تصور کنید می‌خواهید ماشینی بسازید که بتواند تصاویر را شناسایی کند، زبان انسان را بفهمد، یا حتی بازی‌هایی مانند شطرنج را بهتر از شما انجام دهد. برای رسیدن به این هدف، الهام‌بخش‌ترین الگو، مغز انسان است. مغز ما از میلیاردها سلول کوچک به نام نورون ساخته شده است که به صورت موازی کار می‌کنند تا اطلاعات را پردازش کنند. شبکه‌های عصبی مصنوعی (ANN) تلاش می‌کنند این فرایند را شبیه‌سازی کنند و این کار را با مدل‌سازی ریاضی و استفاده از سخت‌افزار‌های محاسباتی قدرتمند انجام می‌دهند.



شبکه عصبی چیست؟
یک شبکه عصبی مصنوعی مجموعه‌ای از واحدهای محاسباتی (که به آن‌ها نورون‌های مصنوعی یا گره‌ها گفته می‌شود) است که به صورت لایه‌ای سازمان‌دهی شده‌اند. این واحدها داده‌ها را پردازش کرده و اطلاعات را از یک لایه به لایه دیگر منتقل می‌کنند.

ساختار کلی:
1. لایه ورودی (Input Layer): داده‌های خام (مثل تصویر، صدا، یا عدد) وارد این لایه می‌شوند.
2. لایه‌های پنهان (Hidden Layers): این لایه‌ها همان‌جایی هستند که جادو رخ می‌دهد. در هر گره (یا نورون)، داده‌ها با وزن‌ها ضرب شده، جمع شده و از یک تابع غیرخطی (فعال‌سازی) عبور می‌کنند.
3. لایه خروجی (Output Layer): نتیجه نهایی (مثل پیش‌بینی یک کلاس یا تولید یک مقدار عددی) از این لایه به دست می‌آید.



چگونه یک نورون مصنوعی کار می‌کند؟
بیایید یک نورون ساده را بررسی کنیم:
1. هر نورون ورودی‌هایی از نورون‌های قبلی می‌گیرد (مثل داده خام یا خروجی یک نورون دیگر).
2. این ورودی‌ها با مقادیری به نام وزن‌ها (Weights) ضرب می‌شوند. وزن‌ها نشان می‌دهند که هر ورودی چقدر مهم است.
3. خروجی حاصل از وزن‌ها جمع می‌شود و یک مقدار بایاس (Bias) به آن اضافه می‌شود.
4. نتیجه به یک تابع فعال‌سازی (Activation Function) داده می‌شود تا غیرخطی شود. این مرحله بسیار مهم است، زیرا به مدل امکان می‌دهد مسائل پیچیده را حل کند.

فرمول ریاضی یک نورون:
import numpy as np

# داده‌های ورودی (مثال: ویژگی‌های یک داده)
inputs = np.array([1.2, 2.3, 3.4]) # x1, x2, x3

# وزن‌های هر ورودی (چقدر هر ورودی مهم است)
weights = np.array([0.5, -0.7, 0.9]) # w1, w2, w3

# مقدار بایاس (bias)
bias = 1.0 # مقدار ثابت اضافه‌شده

# محاسبه خروجی نورون
# 1. ضرب هر ورودی در وزن مربوطه
weighted_sum = np.dot(inputs, weights) # مجموع وزن‌دار x1*w1 + x2*w2 + x3*w3

# 2. افزودن بایاس
weighted_sum += bias # مجموع وزن‌دار به‌علاوه بایاس

# 3. اعمال تابع فعال‌سازی (برای غیرخطی‌سازی)
def activation_function(x):
return 1 / (1 + np.exp(-x)) # تابع سیگموید (نمونه‌ای از توابع فعال‌سازی)

output = activation_function(weighted_sum) # نتیجه نهایی نورون

# چاپ خروجی
print(f"Weighted Sum: {weighted_sum}")
print(f"Neuron Output: {output}")

یک مثال ساده:
فرض کنید می‌خواهید دمای یک روز را پیش‌بینی کنید. ورودی‌ها می‌توانند شامل رطوبت، فشار، و سرعت باد باشند. نورون شما این ورودی‌ها را گرفته، با وزن‌های مناسب ترکیب کرده و خروجی را تولید می‌کند.



اتفاقات پشت پرده: محاسبات روی سخت‌افزار
1. سخت‌افزار محاسباتی:
شبکه‌های عصبی نیازمند حجم زیادی از محاسبات موازی هستند. اینجا جایی است که پردازنده‌ها (CPU) و واحدهای پردازش گرافیکی (GPU/TPU) وارد عمل می‌شوند:
- CPU (واحد پردازش مرکزی): وظایف سریالی و عملیات منطقی را اجرا می‌کند. مناسب برای کارهای سبک و کنترل کلی سیستم.
- GPU (واحد پردازش گرافیکی): طراحی‌شده برای پردازش موازی. ایده‌آل برای انجام محاسبات ماتریسی سنگین در شبکه‌های عصبی.
- TPU (واحد پردازش تنسوری): سخت‌افزار خاص گوگل برای شتاب‌دهی به محاسبات یادگیری ماشین. سرعت بسیار بالایی در عملیات ماتریسی دارد.

2. محاسبات ماتریسی:
- هر لایه از شبکه عصبی را می‌توان به شکل یک ضرب ماتریسی بزرگ در نظر گرفت. به همین دلیل GPU‌ها و TPU‌ها در این زمینه کارآمد هستند.
- مثال:
اگر لایه‌ای 1000 ورودی و 500 نورون داشته باشد ضرب ماتریسی میشود.

3. بهینه‌سازی حافظه:
برای اجرای مدل‌های بزرگ، حافظه بهینه استفاده می‌شود. بچ‌پردازش (Batch Processing) به مدل کمک می‌کند تا داده‌ها را به دسته‌های کوچک‌تر تقسیم کرده و پردازش کند.



آموزش شبکه عصبی:
شبکه‌های عصبی باید آموزش داده شوند تا بتوانند وظایف خاصی را به درستی انجام دهند. این فرایند شامل مراحل زیر است:
👍1
1. فاز پیش‌رو (Forward Pass):
- داده از لایه‌های شبکه عبور می‌کند و خروجی تولید می‌شود.
- هر نورون ورودی را پردازش کرده و خروجی را به نورون بعدی ارسال می‌کند.

2. محاسبه خطا (Loss Calculation):
- خطا (Loss) میزان اختلاف بین خروجی مدل و مقدار واقعی (برچسب) را نشان می‌دهد.
- توابعی مثل MSE یا Cross-Entropy برای محاسبه خطا استفاده می‌شوند.

3. فاز پس‌انتشار (Backward Pass):
- با استفاده از الگوریتم پس‌انتشار (Backpropagation)، خطا به عقب شبکه منتقل می‌شود.
- گرادیان نزولی (Gradient Descent) وزن‌ها را به‌گونه‌ای به‌روزرسانی می‌کند که خطا کاهش یابد.



سوال مهم: چرا شبکه‌های عصبی اینقدر قدرتمند هستند؟
1. توانایی یادگیری غیرخطی: به لطف توابع فعال‌سازی، شبکه‌های عصبی می‌توانند روابط پیچیده غیرخطی را یاد بگیرند.
2. مقیاس‌پذیری: شبکه‌های عصبی بزرگ‌تر و عمیق‌تر می‌توانند وظایف پیچیده‌تری را انجام دهند.
3. تنوع کاربرد: از تشخیص تصویر گرفته تا پردازش زبان طبیعی (NLP) و پیش‌بینی سری‌های زمانی.



چالش‌ها و محدودیت‌ها:
1. نیاز به داده‌های زیاد برای آموزش.
2. مصرف منابع محاسباتی بالا.
3. حساسیت به تنظیمات هایپرپارامترها.



مثالی واقعی: شناسایی دست‌نوشته با شبکه عصبی
فرض کنید می‌خواهید اعداد دست‌نوشته را شناسایی کنید:
1. ورودی: تصویر 28x28 پیکسلی از یک عدد.
2. لایه‌های پنهان: نورون‌ها ویژگی‌هایی مثل خطوط و منحنی‌ها را شناسایی می‌کنند.
3. خروجی: یکی از 10 عدد (0 تا 9).



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

import numpy as np

# ======= توابع فعال‌سازی برای هر نورون =======
def sigmoid(x):
return 1 / (1 + np.exp(-x))

def relu(x):
return np.maximum(0, x)

# ======= تعریف نورون‌ها به صورت توابع مستقل =======
def neuron_1(inputs, weights, bias):
return relu(np.dot(inputs, weights) + bias)

def neuron_2(inputs, weights, bias):
return sigmoid(np.dot(inputs, weights) + bias)

def neuron_3(inputs, weights, bias):
return np.tanh(np.dot(inputs, weights) + bias)

def neuron_4(inputs, weights, bias):
return np.exp(-np.abs(np.dot(inputs, weights) + bias))

# ======= تنظیمات شبکه =======
np.random.seed(42)

# تعداد نورون‌های هر لایه
input_neurons = 2
hidden_neurons = [3, 3, 3, 3] # چهار لایه پنهان با مجموع 12 نورون
output_neurons = 2

# ======= وزن‌ها و بایاس‌ها =======
weights = {
"layer_1": np.random.randn(input_neurons, hidden_neurons[0]),
"layer_2": np.random.randn(hidden_neurons[0], hidden_neurons[1]),
"layer_3": np.random.randn(hidden_neurons[1], hidden_neurons[2]),
"layer_4": np.random.randn(hidden_neurons[2], hidden_neurons[3]),
"output": np.random.randn(hidden_neurons[3], output_neurons)
}

biases = {
"layer_1": np.random.randn(hidden_neurons[0]),
"layer_2": np.random.randn(hidden_neurons[1]),
"layer_3": np.random.randn(hidden_neurons[2]),
"layer_4": np.random.randn(hidden_neurons[3]),
"output": np.random.randn(output_neurons)
}

# ======= ورودی اولیه =======
inputs = np.array([0.5, -1.5])

# ======= فاز پیش‌رو (Forward Pass) =======
# لایه 1
layer_1_output = np.array([
neuron_1(inputs, weights["layer_1"][:, 0], biases["layer_1"][0]),
neuron_2(inputs, weights["layer_1"][:, 1], biases["layer_1"][1]),
neuron_3(inputs, weights["layer_1"][:, 2], biases["layer_1"][2])
])

# لایه 2
layer_2_output = np.array([
neuron_2(layer_1_output, weights["layer_2"][:, 0], biases["layer_2"][0]),
neuron_3(layer_1_output, weights["layer_2"][:, 1], biases["layer_2"][1]),
neuron_4(layer_1_output, weights["layer_2"][:, 2], biases["layer_2"][2])
])

# لایه 3
layer_3_output = np.array([
neuron_1(layer_2_output, weights["layer_3"][:, 0], biases["layer_3"][0]),
neuron_3(layer_2_output, weights["layer_3"][:, 1], biases["layer_3"][1]),
neuron_4(layer_2_output, weights["layer_3"][:, 2], biases["layer_3"][2])
])

# لایه 4
layer_4_output = np.array([
neuron_2(layer_3_output, weights["layer_4"][:, 0], biases["layer_4"][0]),
neuron_3(layer_3_output, weights["layer_4"][:, 1], biases["layer_4"][1]),
neuron_4(layer_3_output, weights["layer_4"][:, 2], biases["layer_4"][2])
])

# لایه خروجی
output = np.array([
neuron_1(layer_4_output, weights["output"][:, 0], biases["output"][0]),
neuron_2(layer_4_output, weights["output"][:, 1], biases["output"][1])
])

# ======= نمایش خروجی =======
print("Input:", inputs)
print("Layer 1 Output:", layer_1_output)
print("Layer 2 Output:", layer_2_output)
print("Layer 3 Output:", layer_3_output)
print("Layer 4 Output:", layer_4_output)
print("Final Output:", output)
👍2
پارت ۱: مقدمات پیشرفته حلقه for (قسمت ۱/۴)

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

---

1. مفهوم for در پایتون
برخلاف زبان‌هایی مثل C++ یا Java که از شاخص‌ها استفاده می‌کنند، پایتون از Iterable Objects استفاده می‌کند. یعنی:
- حلقه for مستقیماً با مقادیر مجموعه کار می‌کند، نه صرفاً شاخص‌ها.
- هر چیزی که قابل تکرار (Iterable) باشد، می‌تواند در حلقه for پیمایش شود.

2. ساختار کلی حلقه for
for variable in iterable:
# دستورات

- variable: متغیری که در هر دور حلقه، مقدار جدیدی از iterable دریافت می‌کند.
- iterable: هر مجموعه‌ای مثل لیست، رشته، تاپل، دیکشنری یا حتی یک فایل.

مثال پایه‌ای:
names = ['Alice', 'Bob', 'Charlie']
for name in names:
print(name)

خروجی:
Alice  
Bob
Charlie

---

3. پیمایش روی اعداد با range()
تابع range() ابزاری قدرتمند برای تولید توالی عددی است.

مثال:
for i in range(5):  # تولید اعداد از 0 تا 4
print(i)

خروجی:
0  
1
2
3
4

تخصیص محدوده در range():
تابع range() سه پارامتر دارد:
- شروع (اختیاری): عدد شروع (پیش‌فرض ۰).
- پایان: عدد انتهایی (این عدد شامل نمی‌شود).
- گام (اختیاری): فاصله بین اعداد.

مثال پیشرفته‌تر:
for i in range(2, 10, 2):  # تولید اعداد ۲، ۴، ۶، ۸
print(i)

---

4. حلقه بدون بدنه (حلقه خالی)
در مواقعی که فقط نیاز دارید حلقه‌ای را اجرا کنید بدون اینکه کاری درون آن انجام دهید، از کلمه کلیدی pass استفاده کنید:
for _ in range(5):
pass # حلقه اجرا می‌شود ولی کاری انجام نمی‌دهد

---

ادامه دارد...
در قسمت دوم، با حلقه‌های تو در تو و ابزارهای حرفه‌ای مانند enumerate آشنا خواهیم شد.

برای دیدن پارت های بعدی و آموزش های بیشتر در این چنل عضو شوید
پارت ۱: مقدمات پیشرفته حلقه for (قسمت ۲/۴)

در این قسمت، به موضوعات پیشرفته‌تر مانند حلقه‌های تو در تو (Nested Loops) و استفاده از ابزارهای حرفه‌ای مثل enumerate و zip می‌پردازیم. این موارد به شما کمک می‌کند از حلقه for به شیوه‌ای بهینه‌تر استفاده کنید.

---

1. حلقه‌های تو در تو (Nested Loops)
گاهی اوقات برای پردازش داده‌های چندلایه (مثل لیست‌های تو در تو)، نیاز به حلقه‌های تو در تو دارید.

مثال: پیمایش یک لیست تو در تو
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]

for row in matrix:
for item in row:
print(item, end=" ") # نمایش همه اعداد در یک خط

خروجی:
1 2 3 4 5 6 7 8 9

مثال: محاسبه مجموع عناصر
total = 0
for row in matrix:
for item in row:
total += item
print(f"Total: {total}")

خروجی:
Total: 45

---

2. پیمایش همراه با اندیس (Index) با enumerate
تابع enumerate امکان پیمایش همزمان مقدار و اندیس هر عنصر را می‌دهد.

مثال:
names = ['Alice', 'Bob', 'Charlie']
for index, name in enumerate(names):
print(f"{index}: {name}")

خروجی:
0: Alice  
1: Bob
2: Charlie

کاربرد: پیدا کردن موقعیت یک عنصر خاص
numbers = [10, 20, 30, 40]
for index, num in enumerate(numbers):
if num == 30:
print(f"Found 30 at index {index}")
break

خروجی:
Found 30 at index 2

---

3. پیمایش همزمان چند مجموعه با zip
تابع zip این امکان را فراهم می‌کند که چند لیست یا مجموعه را همزمان پیمایش کنید.

مثال:
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]

for name, age in zip(names, ages):
print(f"{name} is {age} years old.")

خروجی:
Alice is 25 years old.  
Bob is 30 years old.
Charlie is 35 years old.

---

4. ترکیب enumerate و zip برای پیمایش پیشرفته
می‌توانید enumerate و zip را با هم ترکیب کنید تا اندیس‌ها و مقادیر چند مجموعه را همزمان مدیریت کنید.

مثال:
for index, (name, age) in enumerate(zip(names, ages)):
print(f"{index}: {name} - {age}")

خروجی:
0: Alice - 25  
1: Bob - 30
2: Charlie - 35

---

ادامهقسمت سوم
در قسمت سوم، به موضوعات پیشرفته‌تر مانند فیلتر کردن داده‌ها، استفاده از حلقه‌ها در شرط‌ها، و ساختارهای List Comprehension می‌پردازیم.

برای دیدن پارت های بعدی و آموزش های بیشتر در این چنل عضو شوید
پارت ۱: مقدمات پیشرفته حلقه for (قسمت ۳/۴)

در این قسمت، به مباحث پیشرفته‌تری مانند فیلتر کردن داده‌ها و استفاده از حلقه‌ها در ساختارهای شرطی و List Comprehension می‌پردازیم.

۱. فیلتر کردن داده‌ها در حلقه for
در پایتون می‌توانید با استفاده از شرط‌ها درون حلقه for، داده‌های مورد نظر خود را فیلتر کنید.

- مثال: فیلتر کردن اعداد زوج
numbers = [1, 2, 3, 4, 5, 6]  
for num in numbers:
if num % 2 == 0:
print(num)

خروجی:
۲
۴
۶

- مثال: فیلتر کردن رشته‌های طولانی‌تر از ۳ کاراکتر
words = ['cat', 'dog', 'elephant', 'fox']  
for word in words:
if len(word) > 3:
print(word)

خروجی:
elephant

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

- مثال: بررسی وجود یک عنصر
numbers = [10, 20, 30, 40]  
target = 30

found = False
for num in numbers:
if num == target:
found = True
break

if found:
print("Number found!")
else:
print("Number not found!")

خروجی:
Number found!

۳. معرفی List Comprehension
List Comprehension یکی از روش‌های کوتاه و قدرتمند برای تولید یا فیلتر کردن لیست‌ها است.

- مثال ۱: تولید یک لیست جدید با اعداد زوج
numbers = [1, 2, 3, 4, 5, 6]  
even_numbers = [num for num in numbers if num % 2 == 0]
print(even_numbers)

خروجی:
[2, 4, 6]

- مثال ۲: تولید مقادیر مربع یک لیست
numbers = [1, 2, 3, 4, 5]  
squares = [num**2 for num in numbers]
print(squares)

خروجی:
[1, 4, 9, 16, 25]

۴. Nested List Comprehension (پیشرفته)
می‌توانید لیست‌های تو در تو را با استفاده از List Comprehension پردازش کنید.

- مثال: صاف کردن یک لیست تو در تو
matrix = [  
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]

flattened = [item for row in matrix for item in row]
print(flattened)

خروجی:
[1, 2, 3, 4, 5, 6, 7, 8, 9]

ادامه دارد...
در قسمت چهارم (پایانی)، تکنیک‌های بسیار پیشرفته‌ای مانند استفاده از حلقه for برای ایجاد دیکشنری‌ها و مجموعه‌ها، و همچنین کاربردهای خاص با generatorها را یاد خواهیم گرفت.

برای دیدن پارت های بعدی و آموزش های بیشتر در این چنل عضو شوید
پارت ۱: مقدمات پیشرفته حلقه for (قسمت ۴/۴)

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

---

۱. ایجاد دیکشنری‌ها با for
حلقه for می‌تواند برای ساخت دیکشنری‌های پیچیده استفاده شود. با استفاده از Dictionary Comprehension می‌توانید دیکشنری‌ها را به صورت سریع و بهینه بسازید.

مثال: ساخت دیکشنری از اعداد و مربعات آنها
numbers = [1, 2, 3, 4, 5]  
squares_dict = {num: num**2 for num in numbers}
print(squares_dict)

خروجی:
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

مثال: تبدیل لیست به دیکشنری با استفاده از zip
keys = ['a', 'b', 'c']  
values = [1, 2, 3]
dictionary = {key: value for key, value in zip(keys, values)}
print(dictionary)

خروجی:
{'a': 1, 'b': 2, 'c': 3}

---

۲. ایجاد مجموعه‌ها (Sets) با for
برای ساخت مجموعه‌ها از Set Comprehension استفاده می‌کنیم که مشابه به List Comprehension است ولی به جای لیست، مجموعه‌ای ایجاد می‌شود.

مثال: ساخت مجموعه‌ای از اعداد زوج
numbers = [1, 2, 3, 4, 5, 6]  
even_set = {num for num in numbers if num % 2 == 0}
print(even_set)

خروجی:
{2, 4, 6}

---

۳. استفاده از for با generatorها
Generatorها ابزاری هستند که برای تولید مقادیر به صورت تدریجی و بهینه طراحی شده‌اند. در پایتون، می‌توانیم از یک حلقه for برای ایجاد یک generator استفاده کنیم.

مثال: ساخت generator برای اعداد زوج
def even_numbers(limit):  
for num in range(0, limit, 2):
yield num

evens = even_numbers(10)
for even in evens:
print(even)

خروجی:
0
2
4
6
8

توجه: به جای تولید همه مقادیر در یک لحظه، generator مقادیر را به تدریج تولید می‌کند و در نتیجه حافظه کمتری مصرف می‌شود.

---

۴. ترکیب for با توابع و شرایط پیچیده
حلقه for را می‌توان با توابع و شرایط پیچیده ترکیب کرد تا کدهایی بهینه و قدرتمند بسازیم.

مثال: ترکیب حلقه با تابع و شرط
def is_prime(num):  
if num < 2:
return False
for i in range(2, num):
if num % i == 0:
return False
return True

numbers = [10, 15, 17, 20, 23, 25]
primes = [num for num in numbers if is_prime(num)]
print(primes)

خروجی:
[17, 23]

---

خلاصه
در این مجموعه آموزش‌ها، شما با تکنیک‌های پیشرفته و کاربردی حلقه for در پایتون آشنا شدید. با استفاده از این روش‌ها می‌توانید کدهای بهینه، خوانا و قدرتمندتری بنویسید که در پردازش داده‌ها و حل مسائل پیچیده کمک زیادی به شما خواهد کرد.

---

پایان پارت ۱

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

برای دیدن پارت های بعدی و آموزش های بیشتر در این چنل عضو شوید
👏3
پارت ۲: کاربردهای پیشرفته حلقه for (قسمت ۱/۴)

۱. حلقه‌های تو در تو (Nested Loops):
حلقه‌های تو در تو برای پیمایش در ساختارهای داده‌ای چندبعدی مثل ماتریس یا لیست‌های تودرتو بسیار مفید هستند.
مثال:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]

for row in matrix:
for elem in row:
print(elem)

خروجی:
1
2
3
4
5
6
7
8
9

۲. استفاده از enumerate() برای دسترسی به ایندکس‌ها:
تابع enumerate() این امکان را می‌دهد که همزمان با پیمایش یک مجموعه، به ایندکس و مقدار آن دسترسی داشته باشید.
مثال:
names = ['Alice', 'Bob', 'Charlie']

for index, name in enumerate(names):
print("Index:", index, "Name:", name)

خروجی:
Index: 0 Name: Alice
Index: 1 Name: Bob
Index: 2 Name: Charlie

۳. استفاده از zip() برای پیمایش همزمان چند مجموعه:
اگر نیاز دارید که دو یا چند مجموعه را به صورت همزمان پیمایش کنید، از تابع zip() استفاده کنید.
مثال:
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 90, 88]

for name, score in zip(names, scores):
print(name, "scored", score)

خروجی:
Alice scored 85
Bob scored 90
Charlie scored 88

۴. فیلتر کردن داده‌ها در حلقه for:
با استفاده از شرط‌های منطقی در حلقه، می‌توانید داده‌های خاصی را فیلتر کنید.
مثال:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = [num for num in numbers if num % 2 != 0]
print(odd_numbers)

خروجی:
[1, 3, 5, 7, 9]

۵. حلقه خالی با pass:
گاهی نیاز دارید یک حلقه را تعریف کنید ولی هنوز کاری در آن انجام ندهید. در این موارد از pass استفاده کنید.
مثال:
for _ in range(5):
pass # حلقه بدون هیچ عملیات

---

در قسمت بعدی، به کاربردهای پیچیده‌تر و حرفه‌ای‌تر حلقه for خواهیم پرداخت. منتظر باشید!

برای دیدن قسمت های بعدی آموزش اینجا کلیک کن
👍1
پارت ۲: کاربردهای پیشرفته حلقه for (قسمت ۲/۴)

---

۱. استفاده از else در حلقه for:
برخلاف تصور رایج، حلقه for می‌تواند دارای بلوک else باشد. این بلوک تنها زمانی اجرا می‌شود که حلقه به طور کامل اجرا شده باشد (و نه با break متوقف شود).
مثال:
for num in [1, 2, 3, 4]:
if num == 5:
break
else:
print("Loop completed without break.")

خروجی:
Loop completed without break.

---

۲. استفاده از break و continue:
- break: حلقه را بلافاصله متوقف می‌کند.
- continue: اجرای آن دور حلقه را رد کرده و به دور بعدی می‌رود.
مثال:
for i in range(5):
if i == 2:
continue
if i == 4:
break
print(i)

خروجی:
0  
1
3

---

۳. پیمایش معکوس با reversed():
با استفاده از تابع reversed() می‌توانید یک مجموعه را به صورت معکوس پیمایش کنید.
مثال:
numbers = [1, 2, 3, 4, 5]
for num in reversed(numbers):
print(num)

خروجی:
5  
4
3
2
1

---

۴. حلقه‌های تو در تو با ترکیب enumerate():
می‌توانید از enumerate() در حلقه‌های تو در تو برای دسترسی به ایندکس‌ها و مقادیر استفاده کنید.
مثال:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]

for row_index, row in enumerate(matrix):
for col_index, value in enumerate(row):
print(f"Value at ({row_index}, {col_index}) is {value}")

خروجی:
Value at (0, 0) is 1  
Value at (0, 1) is 2
...
Value at (2, 2) is 9

---

۵. ترکیب zip() با enumerate():
با ترکیب zip() و enumerate() می‌توانید به طور همزمان به ایندکس و مقادیر دو یا چند مجموعه دسترسی داشته باشید.
مثال:
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 90, 88]

for index, (name, score) in enumerate(zip(names, scores)):
print(f"{index}: {name} scored {score}")

خروجی:
0: Alice scored 85  
1: Bob scored 90
2: Charlie scored 88

---

در قسمت سوم، به تکنیک‌های پیشرفته‌تر و بهینه‌سازی‌های خاص در حلقه for خواهیم پرداخت. منتظر باشید!

برای دیدن قسمت های بعدی آموزش اینجا کلیک کن
👍2
پارت ۲: کاربردهای پیشرفته حلقه for (قسمت ۳/۴)

---

۱. استفاده از List Comprehensions برای فیلتر داده‌ها:
List Comprehensions می‌تواند با شرط‌های اضافی ترکیب شود تا داده‌ها را فیلتر کند.
مثال:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
odd_numbers = [num for num in numbers if num % 2 != 0]
print(odd_numbers)


خروجی:
[1, 3, 5, 7, 9]



---

۲. ساخت مجموعه (Set Comprehensions) با حلقه for:
مشابه لیست‌ها، می‌توانید مجموعه‌هایی ایجاد کنید که مقادیر تکراری را حذف می‌کنند.
مثال:
numbers = [1, 2, 2, 3, 4, 4, 5]
unique_squares = {x ** 2 for x in numbers}
print(unique_squares)


خروجی:
{1, 4, 9, 16, 25}



---

۳. استفاده از Dictionary Comprehensions:
با حلقه for می‌توانید دیکشنری‌های جدید بسازید.
مثال:
keys = ['a', 'b', 'c']
values = [1, 2, 3]
dictionary = {key: value for key, value in zip(keys, values)}
print(dictionary)


خروجی:
{'a': 1, 'b': 2, 'c': 3}



---

۴. پیمایش با حلقه for و پردازش شرطی داده‌ها:
می‌توانید از حلقه for همراه با شرط برای انتخاب داده‌ها استفاده کنید.
مثال:
words = ["apple", "banana", "cherry", "date"]
short_words = [word for word in words if len(word) <= 5]
print(short_words)


خروجی:
['apple', 'date']



---

۵. ترکیب چندین حلقه در List Comprehensions:
می‌توانید از چند حلقه for در یک List Comprehension استفاده کنید.
مثال:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened)


خروجی:
[1, 2, 3, 4, 5, 6, 7, 8, 9]



---

۶. استفاده از تابع any() و all() در حلقه‌های for:
این توابع برای بررسی شرط‌هایی روی داده‌ها در حلقه for کاربرد دارند.
مثال:
numbers = [2, 4, 6, 8]
all_even = all(num % 2 == 0 for num in numbers)
print(all_even)


خروجی:
True



---

در قسمت بعدی، به تکنیک‌های بهینه‌سازی و مفاهیم پیشرفته‌تر خواهیم پرداخت. منتظر باشید!

برای دیدن قسمت های بعدی آموزش اینجا کلیک کن
👍1
پارت ۲: کاربردهای پیشرفته حلقه for (قسمت ۴/۴)


۱. حلقه for با itertools:
ماژول itertools مجموعه‌ای از ابزارهای قدرتمند برای کار با حلقه‌ها ارائه می‌دهد.
مثال: استفاده از itertools.cycle برای تکرار بی‌نهایت:
import itertools

colors = ['red', 'green', 'blue']
for color in itertools.cycle(colors):
print(color)
break # برای جلوگیری از حلقه بی‌پایان


خروجی:
red  
green
blue



---

۲. حلقه‌های موازی با itertools.product:
برای ایجاد ترکیب تمام مقادیر دو مجموعه، از itertools.product استفاده کنید.
مثال:
import itertools

letters = ['A', 'B']
numbers = [1, 2]
combinations = itertools.product(letters, numbers)

for combo in combinations:
print(combo)


خروجی:
('A', 1)  
('A', 2)
('B', 1)
('B', 2)



---

۳. کار با enumerate در شرایط خاص:
enumerate می‌تواند شروع ایندکس را سفارشی کند.
مثال:
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits, start=1):
print(f"{index}: {fruit}")


خروجی:
1: apple  
2: banana
3: cherry



---

۴. ایجاد حلقه‌های بی‌پایان با while و for ترکیبی:
می‌توانید از یک حلقه for به همراه حلقه while برای پردازش بی‌پایان استفاده کنید.
مثال:
counter = 0
for char in 'ABC':
while counter < 3:
print(f"{char}-{counter}")
counter += 1


خروجی:
A-0  
A-1
A-2



---

۵. فیلتر داده‌ها با حلقه و شرط‌های چندگانه:
می‌توانید از شرط‌های ترکیبی برای فیلتر دقیق‌تر داده‌ها استفاده کنید.
مثال:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
filtered_numbers = [num for num in numbers if num > 4 and num % 2 == 0]
print(filtered_numbers)


خروجی:
[6, 8]



---

۶. استفاده از توابع lambda در حلقه‌های for:
ترکیب توابع lambda با حلقه‌ها امکان پردازش‌های پیچیده را فراهم می‌کند.
مثال:
numbers = [1, 2, 3, 4]
squared = list(map(lambda x: x ** 2, numbers))
print(squared)


خروجی:
[1, 4, 9, 16]



---

پایان پارت ۲: کاربردهای پیشرفته حلقه for

در این پارت، تکنیک‌های متنوعی از جمله استفاده از ماژول itertools، کار با enumerate و ترکیب شرط‌های مختلف را بررسی کردیم. این مفاهیم، شما را برای نوشتن کدهای پیشرفته‌تر و حرفه‌ای‌تر آماده می‌کند.

در پارت ۳، به سراغ بهینه‌سازی حلقه‌ها و نکات پیشرفته‌تر می‌رویم. منتظر باشید!

برای دیدن قسمت های بعدی آموزش اینجا کلیک کن
👍4
پارت ۳: بهینه‌سازی حلقه‌های for در پایتون (قسمت ۱/۴)



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



۱. استفاده از List Comprehension به‌جای حلقه‌های معمولی

توضیح:
اگر هدف شما ساخت یک لیست جدید از عناصر یک مجموعه دیگر باشد، List Comprehension از نظر خوانایی و سرعت بسیار بهتر از روش سنتی حلقه‌ها عمل می‌کند.

مثال: ساخت لیستی از اعداد مربع‌شده
روش سنتی:
numbers = [1, 2, 3, 4]
squared_numbers = []
for num in numbers:
squared_numbers.append(num ** 2)
print(squared_numbers)

با استفاده از List Comprehension:
numbers = [1, 2, 3, 4]
squared_numbers = [num ** 2 for num in numbers]
print(squared_numbers)

مزایا:
- کاهش خطوط کد
- افزایش سرعت در اجرای کد
- افزایش خوانایی

مقایسه سرعت:
در پروژه‌های بزرگ، List Comprehension معمولاً سریع‌تر عمل می‌کند.



۲. استفاده از Generator Expression برای صرفه‌جویی در حافظه

توضیح:
زمانی که نیازی به ذخیره همه مقادیر در حافظه ندارید (مثل زمانی که مقادیر فقط یک‌بار استفاده می‌شوند)، Generator Expression گزینه مناسبی است.

مثال:
با لیست:
numbers = [1, 2, 3, 4]
squared_numbers = [num ** 2 for num in numbers]
for sq in squared_numbers:
print(sq)

با Generator Expression:
numbers = [1, 2, 3, 4]
squared_numbers = (num ** 2 for num in numbers)
for sq in squared_numbers:
print(sq)

تفاوت اصلی:
- لیست: تمام مقادیر در حافظه ذخیره می‌شوند.
- جنراتور: مقادیر به‌صورت لحظه‌ای تولید می‌شوند و در حافظه ذخیره نمی‌شوند.

نکته: جنراتورها در پردازش داده‌های بسیار بزرگ مؤثرتر هستند.



۳. استفاده از شرط در List Comprehension

توضیح:
شما می‌توانید به‌راحتی شرایط را داخل یک List Comprehension قرار دهید تا تنها مقادیر مورد نظر به لیست اضافه شوند.

مثال: فیلتر کردن اعداد فرد
روش سنتی:
numbers = [1, 2, 3, 4, 5, 6]
odd_numbers = []
for num in numbers:
if num % 2 != 0:
odd_numbers.append(num)
print(odd_numbers)

با استفاده از شرط داخل List Comprehension:
numbers = [1, 2, 3, 4, 5, 6]
odd_numbers = [num for num in numbers if num % 2 != 0]
print(odd_numbers)

مزایا:
- کد کوتاه‌تر و خواناتر می‌شود.
- پردازش داده‌ها بهینه‌تر می‌شود.

تمرین: لیستی از اعداد بین ۱ تا ۲۰ تولید کنید که مضرب ۳ هستند.



۴. استفاده از توابع آماده مثل sum() و max()

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


روش دستی:
numbers = [1, 2, 3, 4, 5]
total = 0
for num in numbers:
total += num
print(total)

استفاده از تابع آماده:
numbers = [1, 2, 3, 4, 5]
total = sum(numbers)
print(total)

مزایا:
- سرعت بیشتر (این توابع در سطح پایین پایتون بهینه شده‌اند).
- کد خواناتر.



۵. تمرین:
یک جنراتور بنویسید که مقادیر بین ۱ تا ۱۰۰ را تولید کند که هم زوج باشند و هم مضرب ۵. سپس این مقادیر را در کنسول چاپ کنید.



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

https://t.iss.one/hamidpython123
👍1