Python3
200 subscribers
100 photos
6 videos
26 files
518 links
🎓 آموزش و پروژه‌های Python
آموزش‌های کاربردی و پروژه‌های عملی Python برای همه سطوح. 🚀
Download Telegram
2💯1
مدیریت خودکار حافظه در پایتون 🧠💡

در پایتون، مدیریت حافظه به‌صورت خودکار انجام می‌شود. یعنی برخلاف زبان‌های سطح پایین مثل C و C++، نیازی به تخصیص یا آزادسازی دستی حافظه نیست و این کار به لطف سیستم مدیریت حافظه خودکار انجام می‌شود. این سیستم شامل شمارش ارجاعات و جمع‌آوری زباله‌ها می‌باشد. بیایید به‌صورت کامل این دو مکانیزم را بررسی کنیم:



🔹 بخش اول: شمارش ارجاعات (Reference Counting)
پایتون از شمارش ارجاعات برای مدیریت حافظه استفاده می‌کند. هر شی در پایتون دارای یک شمارشگر است که تعداد ارجاعات به آن شی را نشان می‌دهد. وقتی مقدار شمارش ارجاعات به صفر برسد، یعنی دیگر هیچ بخشی از برنامه به آن شی نیاز ندارد و پایتون می‌تواند حافظه آن را آزاد کند.

چطور شمارش ارجاعات کار می‌کند؟
- هر زمان که یک متغیر به شی‌ای اشاره می‌کند، شمارش ارجاعات آن شی افزایش می‌یابد.
- وقتی ارجاعی حذف می‌شود، شمارش ارجاعات کاهش می‌یابد.
- زمانی که شمارش به صفر برسد، پایتون حافظه را آزاد می‌کند.

مثال:
a = [1, 2, 3]
b = a # شمارش ارجاعات به شی لیست افزایش می‌یابد
del a # شمارش ارجاعات کاهش می‌یابد

مزیت‌ها:
- *سریع و کارآمد*: شمارش ارجاعات بسیار سریع است و به‌صورت همزمان با اجرای برنامه انجام می‌شود.

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



🔹 بخش دوم: جمع‌آوری زباله‌ها (Garbage Collection)
پایتون از یک سیستم جمع‌آوری زباله‌های دورانی برای پاکسازی حافظه اشیاء بدون ارجاع استفاده می‌کند که شمارش ارجاعات به تنهایی قادر به آزادسازی آن‌ها نیست.

چطور جمع‌آوری زباله‌ها کار می‌کند؟
- حلقه‌های مرجع: برای حل مشکل حلقه‌های مرجع، پایتون از جمع‌آوری زباله‌ها استفاده می‌کند. این مکانیزم دوره‌ای اجرا شده و حلقه‌های ارجاعی را شناسایی و آزاد می‌کند.
- ماژول gc: پایتون از ماژول داخلی gc برای اجرای جمع‌آوری زباله استفاده می‌کند. این ماژول به‌طور خودکار در پس‌زمینه کار می‌کند.

مثال: اجرای دستی جمع‌آوری زباله‌ها
import gc

gc.collect() # اجرای دستی جمع‌آوری زباله

مزیت‌ها:
- *حذف حلقه‌های مرجع*: این مکانیزم باعث می‌شود که حافظه اشیائی که در حلقه‌های مرجع هستند آزاد شود.



🔹 بهینه‌سازی حافظه: بهترین تمرین‌ها
برای بهینه‌سازی استفاده از حافظه، این نکات را در نظر بگیرید:

1. پاکسازی متغیرهای غیرضروری: متغیرهایی که دیگر نیازی به آن‌ها ندارید را با del حذف کنید تا شمارش ارجاعات کاهش یابد.
2. کپی‌های غیرضروری را حذف کنید: از کپی‌های سطحی و عمیق تنها در مواقع نیاز استفاده کنید.
3. ماژول gc: می‌توانید در برنامه‌های طولانی‌مدت و پیچیده، با gc.collect() حافظه را بهینه کنید.
4. Weak References: در مواقعی که نیازی به جلوگیری از جمع‌آوری زباله ندارید، از weak referenceها استفاده کنید.



🔹 جمع‌بندی 📜
مدیریت خودکار حافظه در پایتون به لطف شمارش ارجاعات و جمع‌آوری زباله‌ها انجام می‌شود. این سیستم به شما اجازه می‌دهد که بدون نگرانی از مدیریت دستی حافظه، برنامه‌هایی قابل اعتماد و بهینه بسازید. به کمک نکات بالا و ابزارهایی مثل gc می‌توانید مدیریت حافظه را بهتر درک کرده و از آن بهینه‌تر استفاده کنید.


برای آموزش‌های بیشتر و مباحث حرفه‌ای‌تر برنامه‌نویسی، به کانال ما بپیوندید 📢
🔗 [لینک کانال تلگرام]

#PythonMemory #MemoryManagement #GarbageCollection #Python
1
آموزش درخت AST در پایتون 🌳

در این آموزش، یاد می‌گیریم درخت نحوی انتزاعی (Abstract Syntax Tree) چیست، چه کاربردهایی دارد، و چطور می‌توانیم با پایتون از آن استفاده کنیم.



درخت AST چیست؟
درخت AST یک نمایش انتزاعی از کد است که ساختار دستوری آن را توصیف می‌کند.
هر گره (Node) در درخت AST یک بخش از کد شما را نشان می‌دهد، مانند:
- متغیرها
- عملیات‌ها
- توابع

🔧 چرا به AST نیاز داریم؟
- ساده‌سازی تحلیل کد: حذف جزئیات اضافی مثل پرانتزها.
- ابزار تحلیل کد: برای ابزارهایی مانند Linters یا Code Optimizers بسیار مفید است.
- پایه‌ای برای ساخت مفسر: AST نقش حیاتی در پردازش و اجرای کد ایفا می‌کند.


چگونه AST در پایتون کار می‌کند؟
پایتون یک ماژول داخلی به نام ast دارد که برای کار با درخت‌های AST طراحی شده است.

۱. تبدیل کد به درخت AST
می‌توانیم کد پایتون را به درخت AST تبدیل کنیم:

import ast

code = """
x = 5 + 3
if x > 5:
print(x)
"""

# تبدیل کد به درخت AST
tree = ast.parse(code)

# نمایش درخت AST
print(ast.dump(tree, indent=4))

🔍 خروجی:
Module(
body=[
Assign(
targets=[Name(id='x', ctx=Store())],
value=BinOp(left=Constant(value=5), op=Add(), right=Constant(value=3))
),
If(
test=Compare(
left=Name(id='x', ctx=Load()),
ops=[Gt()],
comparators=[Constant(value=5)]
),
body=[Expr(value=Call(func=Name(id='print', ctx=Load()), args=[Name(id='x', ctx=Load())], keywords=[]))],
orelse=[]
)
]
)



۲. پیمایش درخت AST
با استفاده از ast.walk یا ast.NodeVisitor می‌توانید درخت AST را پیمایش کنید:

مثال ۱: پیدا کردن متغیرها در کد
for node in ast.walk(tree):
if isinstance(node, ast.Name):
print(f"Variable found: {node.id}")

🔍 خروجی:
Variable found: x
Variable found: x
Variable found: print

مثال ۲: نمایش تمام عملیات‌ها
for node in ast.walk(tree):
if isinstance(node, ast.BinOp):
print(f"Operation: {type(node.op).__name__}")

🔍 خروجی:
Operation: Add



۳. تغییر درخت AST
درخت AST قابل تغییر است. می‌توانید گره‌ها را تغییر دهید یا جایگزین کنید.

مثال: جایگزینی همه اعداد با عدد ۱۰
class Transformer(ast.NodeTransformer):
def visit_Constant(self, node):
if isinstance(node.value, int):
return ast.Constant(value=10)
return node

transformer = Transformer()
new_tree = transformer.visit(tree)

# نمایش درخت جدید
print(ast.dump(new_tree, indent=4))

🔍 توضیح:
کدی که از درخت جدید ساخته شود، همه اعداد را با عدد ۱۰ جایگزین می‌کند.



۴. تبدیل درخت AST به کد اجرایی
بعد از تغییر درخت AST، می‌توان آن را به کد اجرایی تبدیل کرد:

import astor  # برای تبدیل AST به کد خوانا

# تبدیل درخت به کد
new_code = astor.to_source(new_tree)
print(new_code)

🔍 خروجی:
x = 10 + 10
if x > 10:
print(x)



کاربردهای AST در دنیای واقعی
1. تحلیل کد:
ابزارهای بررسی کد مانند Flake8 و pylint از AST استفاده می‌کنند.
2. بهینه‌سازی کد:
AST می‌تواند برای اصلاح و بهبود کدها مورد استفاده قرار گیرد.
3. ساخت مفسر:
AST یکی از مهم‌ترین مراحل ساخت مفسر است.
4. ابزارهای تبدیل کد:
مثلاً تبدیل کد قدیمی به نسخه‌های جدیدتر.



تمرین:
1. کدی بنویسید که تمام توابع تعریف‌شده در یک فایل پایتون را شناسایی کند.
2. درخت AST یک کد ساده را دستکاری کنید تا همه متغیرها به نام دیگری تغییر یابند.


جمع‌بندی:
ماژول ast در پایتون یک ابزار قدرتمند برای تحلیل و تغییر کد است. این ابزار به شما اجازه می‌دهد کد را از سطح متن به ساختار درختی تبدیل کنید و بر آن عملیات انجام دهید. اگر درک خوبی از AST داشته باشید، گام بزرگی به سمت ساخت ابزارهایی مثل مفسر یا ابزارهای تحلیل کد برداشته‌اید.

🔗 برای ادامه آموزش‌ها، به کانال تلگرام ما بپیوندید!
[لینک کانال]
#PythonAST #CodeAnalysis #PythonTools
👍1
آموزش پیشرفته درخت AST در پایتون 🌳

در این آموزش، به عمق بیشتری از درخت AST (Abstract Syntax Tree) وارد می‌شویم. هدف این است که با جزئیات بیشتری نحوه ایجاد، تغییر، و استفاده از درخت‌های AST را یاد بگیریم و ابزارهای پیشرفته برای کار با آن‌ها را بررسی کنیم.


۱. بررسی ساختار درخت AST پیشرفته

درخت AST و گره‌های آن
هر گره (Node) در درخت AST، نوع خاصی از اجزای کد را نشان می‌دهد. گره‌ها در پایتون با کلاس‌های مختلف ast نمایش داده می‌شوند. مثال‌هایی از گره‌های رایج:
- ast.Module: نشان‌دهنده کل کد.
- ast.FunctionDef: نشان‌دهنده تعریف یک تابع.
- ast.BinOp: نشان‌دهنده عملیات‌های دودویی مثل جمع و ضرب.

🔧 نمایش جزئیات یک گره:
می‌توانید گره‌ها را با جزئیات بیشتری بررسی کنید:
import ast

code = """
def greet(name):
print(f"Hello, {name}!")
"""
tree = ast.parse(code)

# بررسی جزئیات گره
function_node = tree.body[0] # اولین گره در بدنه (تابع greet)
print(f"Node type: {type(function_node)}")
print(f"Function name: {function_node.name}")
print(f"Arguments: {[arg.arg for arg in function_node.args.args]}")

🔍 خروجی:
Node type: <class 'ast.FunctionDef'>
Function name: greet
Arguments: ['name']


۲. جستجو و تغییر گره‌ها در درخت

NodeVisitor و NodeTransformer
پایتون دو کلاس برای پیمایش و تغییر درخت AST ارائه می‌دهد:
- NodeVisitor: برای مشاهده گره‌ها.
- NodeTransformer: برای تغییر گره‌ها.

مثال: جستجوی گره‌های خاص با NodeVisitor
کدی بنویسید که تمام توابع را پیدا کند:
class FunctionFinder(ast.NodeVisitor):
def visit_FunctionDef(self, node):
print(f"Function found: {node.name}")
self.generic_visit(node)

tree = ast.parse(code)
finder = FunctionFinder()
finder.visit(tree)

🔍 خروجی:
Function found: greet



مثال: تغییر گره‌ها با NodeTransformer
در اینجا تمام چاپ‌ها را با دستور log جایگزین می‌کنیم:
class ReplacePrint(ast.NodeTransformer):
def visit_Call(self, node):
if isinstance(node.func, ast.Name) and node.func.id == "print":
node.func.id = "log"
return self.generic_visit(node)

transformer = ReplacePrint()
new_tree = transformer.visit(tree)

import astor # تبدیل درخت به کد
print(astor.to_source(new_tree))

🔍 خروجی:
def greet(name):
log(f"Hello, {name}!")



۳. ساخت AST به‌صورت دستی

گاهی ممکن است بخواهید یک کد را بدون نوشتن متن آن به‌صورت مستقیم ایجاد کنید. می‌توانید با استفاده از گره‌های ast، یک درخت AST بسازید:

مثال: ساخت یک تابع ساده
تابعی به نام add ایجاد کنید که دو عدد را جمع کند:
func = ast.FunctionDef(
name="add",
args=ast.arguments(
args=[ast.arg(arg="a"), ast.arg(arg="b")],
defaults=[],
vararg=None,
kwarg=None,
kw_defaults=[],
posonlyargs=[],
),
body=[
ast.Return(
value=ast.BinOp(
left=ast.Name(id="a", ctx=ast.Load()),
op=ast.Add(),
right=ast.Name(id="b", ctx=ast.Load())
)
)
],
decorator_list=[]
)

module = ast.Module(body=[func], type_ignores=[])

# تبدیل به کد و نمایش
print(astor.to_source(module))

🔍 خروجی:
def add(a, b):
return a + b



۴. ابزارهای پیشرفته برای کار با AST

استفاده از astor برای مدیریت کد و AST
astor یک کتابخانه قدرتمند است که می‌تواند:
- AST را به کد تبدیل کند.
- کد را به AST تبدیل کند.

نصب astor:
pip install astor

مثال با astor:
import astor

code = """
x = 5 + 3
y = x * 2
"""
tree = ast.parse(code)

# تبدیل AST به کد خوانا
print(astor.to_source(tree))



استفاده از inspect برای تحلیل کد در زمان اجرا
ماژول inspect می‌تواند کد نوشته‌شده را در زمان اجرا تجزیه کند و همراه با AST استفاده شود.

مثال: بررسی بدنه یک تابع
import inspect

def sample_function(x):
return x + 10

source = inspect.getsource(sample_function)
tree = ast.parse(source)

print(ast.dump(tree, indent=4))



۵. کاربردهای پیشرفته درخت AST
👍1
۱. ساخت ابزارهای بررسی کد (Linters)
می‌توانید بررسی کنید که آیا کدی استانداردهای خاصی را رعایت می‌کند یا خیر.

۲. ایجاد ابزارهای بهینه‌سازی کد
کدی که کاربر نوشته است را تغییر دهید تا سریع‌تر اجرا شود.

۳. ساخت ابزارهای تحلیل امنیتی
بررسی کنید که آیا کد شامل الگوهای ناامن است یا نه.

۴. تبدیل کدهای قدیمی به نسخه‌های جدید
مثلاً تغییر کدهایی که برای پایتون ۲ نوشته شده‌اند به نسخه ۳.



تمرین پیشرفته:
۱. ابزاری بنویسید که تمام استفاده‌های متغیر x را در یک فایل پایتون پیدا کند.
۲. برنامه‌ای بسازید که همه حلقه‌های for را به حلقه‌های while تبدیل کند.
۳. ابزاری بنویسید که کدهای طولانی را با دستورهای کوتاه‌تر جایگزین کند.



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

این سطح از آشنایی با AST، مقدمه‌ای عالی برای مراحل بعدی مثل ساخت مفسر است.

🔗 برای آموزش‌های بیشتر، کانال تلگرام ما را دنبال کنید!
[لینک کانال]
#PythonAST #AdvancedPython #CodeOptimization #PythonTools
👍1
آموزش استفاده از ماژول EasyList در پایتون 📚

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



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



نصب و راه‌اندازی ⚙️

برای استفاده از این ماژول، کافی است کد آن را در برنامه خود کپی کرده و از آن استفاده کنید. هیچ نصب خاصی نیاز نیست. فقط باید مطمئن شوید که کد ماژول در فایل پایتون شما قرار دارد.

برای استفاده از این ماژول، آن را به شکل زیر وارد کنید:

from easylist import EasyList  # وارد کردن ماژول



عملکردهای اصلی ماژول

در اینجا برخی از عملکردهای اصلی EasyList آورده شده است که به راحتی می‌توانید آن‌ها را در برنامه خود استفاده کنید:

1. افزودن عنصر به لیست
با استفاده از عملگر + می‌توانید به راحتی یک عنصر جدید به انتهای لیست اضافه کنید:

   my_list = EasyList([1, 2, 3, 4])
my_list + 5 # لیست به [1, 2, 3, 4, 5] تبدیل می‌شود

2. حذف عنصر از لیست
عملگر - برای حذف یک عنصر از لیست استفاده می‌شود:

   my_list - 3  # لیست به [1, 2, 4] تبدیل می‌شود

3. اعمال تابع به تمام عناصر لیست
با استفاده از عملگر * می‌توانید یک تابع را به تمامی عناصر لیست اعمال کنید:

   my_list * (lambda x: x * 2)  # لیست به [2, 4, 8] تبدیل می‌شود

4. مرتب‌سازی لیست 🔢
برای مرتب‌سازی لیست می‌توانید از عملگر ~ استفاده کنید:

   my_list ~  # لیست به [1, 2, 3, 4] مرتب می‌شود

5. معکوس کردن لیست 🔄
برای معکوس کردن لیست، از عملگر - استفاده کنید:

   my_list -  # لیست به [4, 3, 2, 1] معکوس می‌شود

6. یافتن بزرگترین عنصر از لیست 🏆
برای پیدا کردن بیشترین مقدار در لیست، از عملگر & استفاده کنید:

   max_value = my_list & None  # 4

7. یافتن کوچکترین عنصر از لیست 🌱
برای پیدا کردن کوچکترین مقدار در لیست، از عملگر | استفاده کنید:

   min_value = my_list | None  # 1

8. ترکیب دو لیست 🔗
برای ترکیب دو لیست، از عملگر & استفاده کنید:

   my_list2 = EasyList([5, 6, 7])
combined_list = my_list & my_list2 # لیست ترکیب شده [1, 2, 3, 4, 5, 6, 7]

9. فیلتر کردن لیست با تابع دلخواه 🔍
از عملگر ^ برای فیلتر کردن لیست با استفاده از یک تابع خاص می‌توانید استفاده کنید:

   my_list ^ (lambda x: x > 2)  # لیست به [3, 4] فیلتر می‌شود

10. حذف تکراری‌ها 🧹
برای حذف تکراری‌ها از لیست، از عملگر @ استفاده کنید:

   my_list @ None  # لیست به [1, 2, 3, 4] تبدیل می‌شود


تست ماژول (مثال کامل) 🧑‍💻
برای مشاهده نحوه عملکرد تمامی این ویژگی‌ها، از کد زیر استفاده کنید:

from easylist import EasyList

def test():
my_list = EasyList([1, 2, 3, 4, 5, 5])
print("Test 1 - Add:", my_list + 6)
print("Test 2 - Remove:", my_list - 3)
print("Test 3 - Multiply (apply function):", my_list * (lambda x: x * 2))
print("Test 4 - Sort:", my_list ~)
print("Test 5 - Reverse:", my_list -)
print("Test 6 - Max:", my_list & None)
print("Test 7 - Min:", my_list | None)

my_list2 = EasyList([6, 7, 8])
print("Test 8 - Combine two lists:", my_list & my_list2)
print("Test 9 - Filter (> 4):", my_list ^ (lambda x: x > 4))
print("Test 10 - Remove duplicates:", my_list @ None)

test()


نتیجه‌گیری

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


#پایتون #آموزش_پایتون #کدنویسی
👍2
خود فایل ☝️
پارت 1: آموزش SQL با پایتون (پایه)

👨‍💻 SQL یا Structured Query Language زبان استانداردی برای کار با پایگاه‌های داده است که به ما اجازه می‌دهد داده‌ها را ایجاد، خواندن، بروزرسانی و حذف کنیم (CRUD operations). در این پارت، می‌خواهیم SQL را در پایتون به کمک کتابخانه sqlite3 یاد بگیریم. این کتابخانه برای کار با پایگاه داده‌های SQLite در پایتون بسیار مفید است و در اکثر سیستم‌ها به صورت پیش‌فرض نصب شده است.

1️⃣ شروع کار با sqlite3

برای شروع، باید ابتدا کتابخانه sqlite3 را وارد کنیم:

import sqlite3

بعد از وارد کردن کتابخانه، برای اتصال به یک پایگاه داده، از تابع connect() استفاده می‌کنیم:

# اتصال به پایگاه داده (اگر فایل پایگاه داده وجود نداشته باشد، ساخته می‌شود)
conn = sqlite3.connect('example.db')

# ایجاد یک cursor برای اجرای دستورات SQL
cursor = conn.cursor()

در کد بالا:
- example.db نام فایل پایگاه داده است.
- اگر فایل پایگاه داده با این نام وجود نداشته باشد، به صورت خودکار ایجاد خواهد شد.
- cursor یک شی است که می‌توان از آن برای اجرای دستورات SQL استفاده کرد.

2️⃣ ایجاد یک جدول جدید

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

# ایجاد یک جدول جدید
cursor.execute('''CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
age INTEGER,
email TEXT)''')

# ذخیره تغییرات در پایگاه داده
conn.commit()

در این کد:
- IF NOT EXISTS به این معناست که اگر جدول قبلاً ایجاد شده باشد، دوباره ایجاد نمی‌شود.
- id یک ستون است که به عنوان کلید اصلی (Primary Key) برای هر رکورد استفاده می‌شود و به طور خودکار افزایش می‌یابد (AUTOINCREMENT).

3️⃣ وارد کردن داده‌ها در جدول

حالا که جدول خود را ایجاد کرده‌ایم، می‌توانیم داده‌ها را به آن وارد کنیم. از دستور SQL INSERT INTO استفاده می‌کنیم:

# وارد کردن داده‌ها در جدول
cursor.execute("INSERT INTO users (name, age, email) VALUES (?, ?, ?)", ('Ali', 25, '[email protected]'))

# ذخیره تغییرات
conn.commit()

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

4️⃣ خواندن داده‌ها از جدول

برای خواندن داده‌ها از جدول، از دستور SQL SELECT استفاده می‌کنیم:

# خواندن داده‌ها از جدول
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()

# نمایش داده‌ها
for row in rows:
print(row)

در این کد:
- SELECT * FROM users تمام داده‌های جدول users را انتخاب می‌کند.
- fetchall() تمام نتایج را به صورت یک لیست از تاپل‌ها برمی‌گرداند.

5️⃣ بستن اتصال

پس از انجام تمام عملیات، بهتر است که اتصال به پایگاه داده را ببندیم:

# بستن اتصال به پایگاه داده
conn.close()

📚 خلاصه پارت 1:
- یاد گرفتیم که چطور به پایگاه داده متصل شویم.
- نحوه ایجاد یک جدول و وارد کردن داده‌ها را بررسی کردیم.
- چطور داده‌ها را از پایگاه داده بخوانیم.
- در نهایت اتصال به پایگاه داده را بستیم.

🔜 در پارت بعدی، به بررسی دستورات پیشرفته‌تر SQL و نحوه بروزرسانی و حذف داده‌ها خواهیم پرداخت.

#SQL #Python #SQLite #Database
👍2
پارت 2: آموزش SQL با پایتون (بروزرسانی و حذف داده‌ها)

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

1️⃣ بروزرسانی داده‌ها (UPDATE)

اگر بخواهیم داده‌ای را که قبلاً وارد کرده‌ایم، تغییر دهیم، از دستور **UPDATE** استفاده می‌کنیم. مثلاً فرض کنید می‌خواهیم سن کاربری که نامش "Ali" است را تغییر دهیم.

# بروزرسانی داده‌ها
cursor.execute("UPDATE users SET age = ? WHERE name = ?", (30, 'Ali'))

# ذخیره تغییرات
conn.commit()

در این کد:
- SET age = ? به این معناست که مقدار سن تغییر می‌کند.
- WHERE name = ? مشخص می‌کند که فقط رکوردهایی که نام آن‌ها "Ali" است تغییر خواهند کرد.
- مانند قبل، برای جلوگیری از تزریق SQL از ? استفاده کرده‌ایم و مقادیر را به صورت پارامتر می‌فرستیم.

2️⃣ حذف داده‌ها (DELETE)

برای حذف داده‌ها از پایگاه داده، از دستور **DELETE** استفاده می‌کنیم. فرض کنید می‌خواهیم رکورد کاربری که نامش "Ali" است را حذف کنیم.

# حذف داده‌ها
cursor.execute("DELETE FROM users WHERE name = ?", ('Ali',))

# ذخیره تغییرات
conn.commit()

در این کد:
- DELETE FROM users تمام داده‌ها را از جدول users حذف می‌کند.
- WHERE name = ? به این معناست که فقط رکوردهایی که نام آن‌ها "Ali" است حذف می‌شوند.

⚠️ توجه داشته باشید که دستور DELETE بدون استفاده از WHERE، تمام رکوردها را حذف می‌کند. پس باید حتماً دقت کنید که از WHERE به درستی استفاده کنید تا فقط رکوردهای مورد نظر حذف شوند.

3️⃣ حذف تمام داده‌ها از جدول (Truncate)

اگر بخواهیم تمام داده‌ها را از یک جدول حذف کنیم، می‌توانیم اDELETEDELETE** استفاده کنیم بدون اینکه شرطی بگذاریم یا اDROP**DROP** برای حذف جدول استفاده کنیم.

# حذف تمام داده‌ها از جدول
cursor.execute("DELETE FROM users")

# ذخیره تغییرات
conn.commit()

یا برای حذف ساختار جدول و داده‌ها:

# حذف جدول از پایگاه داده
cursor.execute("DROP TABLE IF EXISTS users")

# ذخیره تغییرات
conn.commit()

در اینجا:
- DELETE FROM users تمام داده‌ها را از جدول حذف می‌کند، اما ساختار جدول باقی می‌ماند.
- DROP TABLE IF EXISTS users جدول users را به طور کامل حذف می‌کند، حتی اگر داده‌ها داخل آن باشند.

4️⃣ جستجوی داده‌ها با شرط‌های مختلف

برای جستجوی داده‌ها به صورت خاص‌تر، می‌توانیم اSELECTSELECT** با شرط‌های مختلWHERE*WHERE**، **LIKE**، و **ORDER BY** استفاده کنیم. به عنوان مثال، فرض کنید می‌خواهیم کاربران را بر اساس سن مرتب کنیم:

# جستجو و مرتب‌سازی داده‌ها
cursor.execute("SELECT * FROM users ORDER BY age DESC")
rows = cursor.fetchall()

# نمایش داده‌ها
for row in rows:
print(row)

در این کد:
- ORDER BY age DESC داده‌ها را بر اساس سن به صورت نزولی مرتب می‌کند.
- برای مرتب‌سازی صعودی از ASC استفاده می‌شود که به طور پیش‌فرض است.

5️⃣ بستن اتصال

در نهایت، پس از انجام عملیات‌های مورد نظر، باید اتصال به پایگاه داده را ببندیم:

# بستن اتصال به پایگاه داده
conn.close()

📚 **خلاصه پارت 2**:
- در این پارت یاد گرفتیم که چگونه UPDATE با دستور **UPDATE** بروزرسانی کنیم.
- نحوه حذف DELETE با دستور **DELETE** بررسی کردیم.
- برای حذف تمام داده‌ها یا DELETEز دDROP*DELETE** و **DROP** استفاده کردیم.
- یاد گرفتیم که چگونه داده‌ها را جستجو کرده و مرتب کنیم.

🔜 در صورتی که بخواهید در مورد SQL بیشتر یاد بگیرید، می‌توانید به مستندات رسمی SQL یا آموزش‌های پیشرفته‌تر مراجعه کنید.

#SQL #Python #SQLite #Database
👍3
پارت 1: مفاهیم اولیه گراف‌ها
🎓 گراف چیست؟
گراف یک ساختار ریاضی است که شامل:
- رأس‌ها (📍): نقاطی که اطلاعات را نمایش می‌دهند.
- یال‌ها (🔗): خطوطی که ارتباط بین رأس‌ها را نشان می‌دهند.

💡 انواع گراف‌ها:
1. جهت‌دار (➡️): یال‌ها دارای جهت هستند.
2. بدون جهت (🔄): یال‌ها بدون جهت‌اند.
3. وزن‌دار (🔢): هر یال یک وزن یا هزینه دارد.
4. غیر وزن‌دار (): یال‌ها بدون وزن هستند.



🔍 کاربردهای گراف‌ها:
- مسیریابی (🚗)
- شبکه‌های اجتماعی (👥)
- تحلیل شبکه‌ها (🌐)
- حل مسائل ریاضی (📐)


🎯 نمایش گراف‌ها:
1. ماتریس مجاورت (📊):
- هر سطر و ستون نشان‌دهنده یک رأس است.
- مقدار 1 یا وزن نشان‌دهنده وجود یال بین دو رأس است.

مثال (برای گراف وزن‌دار):

   0 3 0  
3 0 7
0 7 0

2. لیست مجاورت (📋):
- لیستی از رأس‌های متصل به هر رأس نگهداری می‌شود.

مثال:

   1 -> [(2, 3)]  
2 -> [(1, 3), (3, 7)]
3 -> [(2, 7)]


کد نمونه در پایتون:
# تعریف گراف وزن‌دار با لیست مجاورت
graph = {
'1': [('2', 3)],
'2': [('1', 3), ('3', 7)],
'3': [('2', 7)]
}
print("Graph:", graph)



📚 جمع‌بندی:
گراف‌ها ابزاری قدرتمند برای مدل‌سازی و حل مسائل پیچیده هستند. در پارت بعدی، الگوریتم‌های پیمایش گراف را یاد می‌گیریم.



#گراف #برنامه‌نویسی #آموزش_تلگرام #الگوریتم_گراف #یادگیری
👍1
پارت 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