این پکیج توی پایتون بتون کمک میکنه که خیلی سریع دیتاستتون رو بررسی کنید و به اصطلاح فنی یک تجربه ی Exploratory Data Analysis هستش..
من خوشم اومد، جالبه.. براتون یه گزارش مفصل و خیلی یوزرفرندی میسازه از داده هاتون، داده های Nan رو مشخص میکنه و خیلی چیزای دیگه!
اگر میخواین شروع کنید، توی Vscode یا Jupyter notebook دستورای توی تصویر رو اجرا کنید..
من خوشم اومد، جالبه.. براتون یه گزارش مفصل و خیلی یوزرفرندی میسازه از داده هاتون، داده های Nan رو مشخص میکنه و خیلی چیزای دیگه!
اگر میخواین شروع کنید، توی Vscode یا Jupyter notebook دستورای توی تصویر رو اجرا کنید..
استفاده از پایتون در پلتفرم های یونیکس
پایتون روی اکثر توزیع ها لینوکس از پیش نصب شده است و به صورت بسته در همه توزیع های دیگر در دسترس است ولی یه سری ویژگی های خاصی هستن که ممکن بخواهیم ازشون استفاده کنیم که تو بسته های توزیع ما موجود نیستن به راحتی هم میتونیم از اخرین نسخه پایتون رو از منبع کامپایل کنیم
در صورتی که پایتون از پیش نصب نشده باشه و تو مخزن ها هم وجود نداشته باشه می تونیم به راحتی بسته های رو برای توزیع خودمون بسازیم به لینک های زیر یه نگاه بندازین
همچنین ببینید
https://www.debian.org/doc/manuals/maint-guide/first.en.html
برای کاربران دبیان
https://en.opensuse.org/Portal:Packaging
برای کاربران OpenSuse
https://docs.fedoraproject.org/en-US/package-maintainers/Packaging_Tutorial_GNU_Hello/
برای کاربران فدورا
https://slackbook.org/html/package-management-making-packages.html
برای کاربران Slackware
پایتون روی اکثر توزیع ها لینوکس از پیش نصب شده است و به صورت بسته در همه توزیع های دیگر در دسترس است ولی یه سری ویژگی های خاصی هستن که ممکن بخواهیم ازشون استفاده کنیم که تو بسته های توزیع ما موجود نیستن به راحتی هم میتونیم از اخرین نسخه پایتون رو از منبع کامپایل کنیم
در صورتی که پایتون از پیش نصب نشده باشه و تو مخزن ها هم وجود نداشته باشه می تونیم به راحتی بسته های رو برای توزیع خودمون بسازیم به لینک های زیر یه نگاه بندازین
همچنین ببینید
https://www.debian.org/doc/manuals/maint-guide/first.en.html
برای کاربران دبیان
https://en.opensuse.org/Portal:Packaging
برای کاربران OpenSuse
https://docs.fedoraproject.org/en-US/package-maintainers/Packaging_Tutorial_GNU_Hello/
برای کاربران فدورا
https://slackbook.org/html/package-management-making-packages.html
برای کاربران Slackware
🧑💻PythonDev🧑💻
چطوری در تلگرام یک قطعه کد برنامه نویسی رو بنویسیم؟ فقط کافیه کدتون رو به روش معمول تایپ کنید ولی اول و آخرش رو سه تا علامتی که در عکس میبینید بزارید خودش به صورت کد نمایش داده میشه. اول کدتون هم اسم زبانش رو بنویسید که مردم بدونند زبانش چیه. برای مثال:…
import os
from pdfminer.high_level import extract_text
def search_keywords_in_pdfs(folder_path, keywords):
try:
# Iterate over each file in the specified folder
for filename in os.listdir(folder_path):
if filename.endswith(".pdf"):
file_path = os.path.join(folder_path, filename)
print(f"\nSearching in file: {file_path}")
# Extract text from the PDF file
text = extract_text(file_path)
# Check if any of the keywords are present in the extracted text
if any(keyword.lower() in text.lower() for keyword in keywords):
print(f"Keyword(s) found in {filename}")
except Exception as e:
print(f"Error: {e}")
# Example usage:
pdf_folder_path = "path/to/your/pdf/folder"
search_keywords = ["python", "programming", "example"]
search_keywords_in_pdfs(pdf_folder_path, search_keywords)
✔️ سوال: best practiceها و ابزارات مورد نیاز برای توسعه یه بسته، لایبرری یا نرمافزار پایتونی چیه؟
ابزارهای زیادی واسه اینکارا وجود داره که بر اساس تجربه و چیزی که از 80 درصد پروژه های معروف و بزرگ دیدم، سعی میکنم بهتریناش رو معرفی کنم:
Dependency Management System
برای مدیریت وابستگی های یک پروژه بزرگ (یا نسبتا بزرگ)، پیشنهاد میکنم از
همچنین
1. آشنایی و شروع به کار با Poetry
https://realpython.com/dependency-management-python-poetry/
2. جزیات عمیق درباره هر قابلیت و نحوه استفاده
https://python-poetry.org/docs
3. نحوه انتشار یک package پایتونی در PyPI به کمک Poetry
https://johnfraney.ca/blog/create-publish-python-package-poetry/
Linting & Type Checking
برای
اگر عادت دارید کدهای خودتون رو
1. داکیومنت Flake8
https://flake8.pycqa.org/en/latest/user/invocation.html
2. داکیومنت MyPy
https://mypy.readthedocs.io/en/stable/getting_started.html
Code Formatting
برای مرتب و
1. داکیومنت isort
https://pycqa.github.io/isort/
2. داکیومنت Black
https://black.readthedocs.io/en/stable/getting_started.html
3. یک ویدیو از PyCon 2019 درباره Black
https://youtu.be/esZLCuWs_2Y
* این ابزارها همگی داکیومنت ساده و خوانایی دارن و به نظرم بهترین منبع همین داکیومنتهاشون هست.
Testing
دو کتابخونه
1. یک مقاله جامع درباره تست نویسی، انواع آن و روشهای مورد استفاده در پایتون
https://realpython.com/python-testing/
2. ویدیو درباره unittest در پایتون
https://m.youtube.com/watch?v=FxSsnHeWQBY
https://www.youtube.com/watch?v=6tNS--WetLI
* همچنین اگر از
وبسایت pre commit:
https://pre-commit.com/
ابزارهای زیادی واسه اینکارا وجود داره که بر اساس تجربه و چیزی که از 80 درصد پروژه های معروف و بزرگ دیدم، سعی میکنم بهتریناش رو معرفی کنم:
Dependency Management System
برای مدیریت وابستگی های یک پروژه بزرگ (یا نسبتا بزرگ)، پیشنهاد میکنم از
Poetry
استفاده کنید، چون ابزار بسیار قدرتمندی هست، کار باهاش بسیار راحته (خیلی شبیه به Cargo
در زبان Rust
هست)، کامیونیتی بزرگی داره، به راحتی محیط dev
و prod
رو میتونید مدیریت کنید، مستندات بسیار خوب و روانی داره، در سریع ترین زمان ممکن میتونید پروژه رو در PyPI
منتشر کنید و همچنین پروژههای معروفی از جمله Rich (کتابخونهای که خود pip
هم ازش برای رنگی کردن progress bar
ها استفاده میکنه) از اون استفاده میکنن، که همین نشون میده چقدر کاربردی هست.همچنین
build
و run
هم توسط Poetry
انجام میشه-
منابع آموزشی:1. آشنایی و شروع به کار با Poetry
https://realpython.com/dependency-management-python-poetry/
2. جزیات عمیق درباره هر قابلیت و نحوه استفاده
https://python-poetry.org/docs
3. نحوه انتشار یک package پایتونی در PyPI به کمک Poetry
https://johnfraney.ca/blog/create-publish-python-package-poetry/
Linting & Type Checking
برای
Linting
ابزارهای flake8
و pylint
از معروف ترینها هستن، هر یک رو میتونید شدت سخت گیریشون رو تنظیم کنید، به راحتی همراه با Poetry
تنظیماتشون در یک فایل قرار میگیره و نیاز به نگه داشتن فایلهای متفاوت برای هر کدوم ندارید. به نظرم خود flake8
به تنهایی نیازتون رو برطرف میکنه. اگر از PyCharm
استفاده کنید یک Linter
به صورت Built-in
در اختیارتون میذاره که خوبه و کارتون رو راه میندازه.اگر عادت دارید کدهای خودتون رو
Annotate
کنید و زیاد از Type Hint
ها استفاده میکنید، استفاده از MyPy
به عنوان یک static type checker
به شما کمک میکنه ایرادات موجود در کلاس ها، توابع و ... رو پیدا کنید و بتونید type
های دقیق تری استفاده کنید. همچنین ابزار Pyright
که توسط مایکروسافت توسعه داده میشه، در VSCode
به صورت integrated
با افزونه Pylance
کار میکنه و اگر از VSCode
استفاده میکنید پیشنهاد میکنم حتما افزونه Pylance
رو نصب کنید. PyCharm
هم یک Type Checker
داره ولی هنوز توانمندی Pylance
و MyPy
رو نداره.-
منابع آموزشی:1. داکیومنت Flake8
https://flake8.pycqa.org/en/latest/user/invocation.html
2. داکیومنت MyPy
https://mypy.readthedocs.io/en/stable/getting_started.html
Code Formatting
برای مرتب و
organize
کردن import
ها از isort
استفاده کنید، هم به صورت CLI
در دسترس هست و هم یک API
داره که میتونید در کد پایتون استفاده کنید. یک code formatter
بسیار معروف که در اکثر پروژهها استفاده میشه Black
هست، زیر نظر PSF
(یا Python Software Foundation
) و برنامه نویسای با تجربه و کار کشته ای همچون آقای Łukasz Langa
(ریلیس منیجر پایتون 3.9) توسعه داده میشه، با دیگر ابزار ها مثل isort
سازگار هست، با PEP8
سازگاره و کلی قابلیت مزیت دیگه داره که حقیقتا اینجا جا نمیشن :)-
منابع آموزشی:1. داکیومنت isort
https://pycqa.github.io/isort/
2. داکیومنت Black
https://black.readthedocs.io/en/stable/getting_started.html
3. یک ویدیو از PyCon 2019 درباره Black
https://youtu.be/esZLCuWs_2Y
* این ابزارها همگی داکیومنت ساده و خوانایی دارن و به نظرم بهترین منبع همین داکیومنتهاشون هست.
Testing
دو کتابخونه
Pytest
و unittest
(در stdlib
موجود هست) در تست نویسی پروژه ها استفاده میشن، برای تست کردن پروژه در environment
های متفاوت از ابزار tox
استفاده میشه و باهاش میتونید در نسخه های متفاوتی از پایتون کدتون رو تست کنید.-
منابع آموزشی:1. یک مقاله جامع درباره تست نویسی، انواع آن و روشهای مورد استفاده در پایتون
https://realpython.com/python-testing/
2. ویدیو درباره unittest در پایتون
-
آقای ned batchelder:https://m.youtube.com/watch?v=FxSsnHeWQBY
-
آقای Corey Schafer:https://www.youtube.com/watch?v=6tNS--WetLI
* همچنین اگر از
Git
در پروژه خودتون استفاده میکنید، پیشنهاد میکنم از pre-commit
حتما استفاده کنید و تمام این ابزارهای گفته شده رو automate
کنید تا در هربار commit
کردن، قبل از اینکه commit
انجام بشه، این ابزارها روی کدتون اجرا بشن و اگر اشکالی در کدتون وجود داره پیدا بشه و اون رو برطرف کنید و دوباره commit کنید.وبسایت pre commit:
https://pre-commit.com/
GitHub
GitHub - Textualize/rich: Rich is a Python library for rich text and beautiful formatting in the terminal.
Rich is a Python library for rich text and beautiful formatting in the terminal. - Textualize/rich
📚 آموزش پیشرفته Set در پایتون
ستها در پایتون، مجموعههایی بدون ترتیب و با عناصر منحصربهفرد هستن که به دلیل سرعت بالا در عملیاتهای مجموعهای و حذف دادههای تکراری، یک ابزار کارآمد برای تحلیل دادهها محسوب میشن.
🔵 یکی از ویژگیهای پیچیده در setها، توانایی انجام عملیاتهای ریاضی مجموعهای، مثل اجتماع، تقاطع، تفاضل و تفاضل متقارن هست.
ستها در پایتون، مجموعههایی بدون ترتیب و با عناصر منحصربهفرد هستن که به دلیل سرعت بالا در عملیاتهای مجموعهای و حذف دادههای تکراری، یک ابزار کارآمد برای تحلیل دادهها محسوب میشن.
🔵 یکی از ویژگیهای پیچیده در setها، توانایی انجام عملیاتهای ریاضی مجموعهای، مثل اجتماع، تقاطع، تفاضل و تفاضل متقارن هست.
a = {1, 2, 3, 4}🔵 ستها در پایتون از Comprehensions پشتیبانی میکنن، که با استفاده از شرطها و حلقهها، امکان ساخت setهای پیچیدهتر فراهم میشه.
b = {3, 4, 5, 6}
print(a | b) # اجتماع
print(a & b) # تقاطع
print(a - b) # تفاضل
print(a ^ b) # تفاضل متقارن
🔜 {1, 2, 3, 4, 5, 6}
{3, 4}
{1, 2}
{1, 2, 5, 6}
squared_primes = {x**2 for x in range(10) if is_prime(x)}🔵 متدهای پیشرفته setها مثل isdisjoint, issubset, و issuperset اجازه میدن روابط بین دو set رو بررسی کنیم.
print(squared_primes)
🔜 {4, 9, 25, 49}
c = {1, 2}🔵 برای افزودن یا حذف عناصر از ستها، متدهای add, update, و discard کاربرد دارن که امکان مدیریت انعطافپذیر عناصر رو میدن.
d = {1, 2, 3, 4}
print(c.isdisjoint(b)) # بررسی عدم اشتراک
print(c.issubset(d)) # بررسی زیرمجموعه بودن
print(d.issuperset(c)) # بررسی سوپرمجموعه بودن
🔜 False
True
True
e = {1, 2, 3}🔵 پایتون همچنین اجازه میده ستهای frozen ایجاد کنیم، که setهایی غیرقابل تغییر هستن و میتوانن به عنوان کلید در دیکشنریها استفاده شن.
e.add(4) # افزودن عنصر
e.update([5, 6, 7]) # افزودن چندین عنصر
e.discard(3) # حذف عنصر
print(e)
🔜 {1, 2, 4, 5, 6, 7}
f = frozenset([1, 2, 3])
print(f)
🔜 frozenset({1, 2, 3})
🧑💻PythonDev🧑💻
✔️ سوال خروجی چیست؟ 1) NameError: name 'e' does not exists 2) 10 3) ZeroDivisionError() چرا؟ 😁
جواب:
تو حالت های دیگه مثلا زمانی که از context manager استفاده میکنیم دستور as درواقع همون کار assignment رو انجام میده. مثلا:
ولی اگه این اتفاق توی exception ها هم بیفته مشکل ساز میشه. آبجکت exception داخل خودش یه traceback آبجکتی داره که حاوی اطلاعاتی از exception ما هست. مثلا خود این traceback آبجکت یه رفرنس داره به frame ای که توش exception رخ داده و اون frame هم رفرنس داره به تمام متغیر های لوکال اون scope از جمله؟ e !
e -> traceback -> frame -> e
پس یک circular reference ایجاد میشه:
تو این مثال پایین ما میخوایم از قصد یک رفرنس ایجاد کنیم به e تا زنده بمونه، انگار که همچین مکانیزمی نداشته پایتون. ببینید چه اتفاقی میفته: (فرض کنید obj یک آبجکت خیلی بزرگ هست)
تو حالت های دیگه مثلا زمانی که از context manager استفاده میکنیم دستور as درواقع همون کار assignment رو انجام میده. مثلا:
e = 10
with open("text.txt") as e:
pass
print(e)
اینجا دیگه e اشاره میکنه به فایل باز شده.ولی اگه این اتفاق توی exception ها هم بیفته مشکل ساز میشه. آبجکت exception داخل خودش یه traceback آبجکتی داره که حاوی اطلاعاتی از exception ما هست. مثلا خود این traceback آبجکت یه رفرنس داره به frame ای که توش exception رخ داده و اون frame هم رفرنس داره به تمام متغیر های لوکال اون scope از جمله؟ e !
e -> traceback -> frame -> e
پس یک circular reference ایجاد میشه:
e = 10
try:
raise ZeroDivisionError("hiiiii")
except ZeroDivisionError as e:
print(e is e.__traceback__.tb_frame.f_locals["e"])
در نتیجه پایتون میاد بعد از اینکه بلاک except تموم شد اون اسمی که اشاره میکرد به آبجکت exception یعنی e رو پاک میکنه از namespace.تو این مثال پایین ما میخوایم از قصد یک رفرنس ایجاد کنیم به e تا زنده بمونه، انگار که همچین مکانیزمی نداشته پایتون. ببینید چه اتفاقی میفته: (فرض کنید obj یک آبجکت خیلی بزرگ هست)
class A:فانکشن تموم شده، obj فقط داخل فانکشن ساخته شده بوده باید رفرنسش صفر میشد و از بین میرفت ولی نرفت...
def __del__(self) -> None:
print("object is deleted")
def fn():
obj = A()
exc = None
try:
raise ZeroDivisionError()
except ZeroDivisionError as e:
exc = e
fn()
print("Object is still alive!")
input()
گروه هکری که قبلا به اطلاعات تپسی دسترسی پیدا کرده بود، مدعی هک اسنپفود شد و برخی اطلاعات (شامل اطلاعات ۱۰۰۰ کاربر و...) را به عنوان دیتای نمونه منتشر کرد.
✔️ کلاس zip
ببینید zip یک کلاس هست که میاد به عنوان پارامتر های ورودی خودش،
شاید بگید
خوب حالا این zip چطوری کار میکنه 🤔
این کلاس میاد و از
نکته مهم ❗️
کلاس zip هم مثل filter و map و ... یک
مثال 🧪
پس
ببینید zip یک کلاس هست که میاد به عنوان پارامتر های ورودی خودش،
iterable
(یا iterable
هایی) رو به صورت postional argument
میگیره و یک zip object
به ما برمیگردونه!شاید بگید
iterable
چیه؟ iterable
میشه چیزی که شما توی پایتون بتونی مثلا روش for
بزنی و به اصطلاح iterate
کنی! مثل چی؟ مثل list - str - tuple و ...خوب حالا این zip چطوری کار میکنه 🤔
این کلاس میاد و از
iterable
هایی که بهش داده شده، به تعداد اون Iterable
ها (فرض کنیم n
تا) tuple (هایی) به سایز n
برامون yield
میکنه! حالا اعضای اون tuple که سایزش n
هست (یعنی n
تا عضو داره) چی هستن؟ zip میاد و اولین عضو رو از اولین iterable
و دومین عضو رو از دومین iterable
و همینطوری تا آخر میگیره! این تا کی ادامه داره؟ تا زمانی که اعضای کوتاه ترین iterable
تمام بشه!نکته مهم ❗️
کلاس zip هم مثل filter و map و ... یک
lazy iterator
هست، یعنی چی؟ یعنی جواب رو درجا برای ما محاسبه نمیکنه و هر بار که روش next زده بشه، به ما یک چیزی yield میکنه.مثال 🧪
names = [الان هر بار که روی z ما
"Ali",
"Mohsen",
"Hassan",
]
last_names = [
"Hassanzadeh",
"Mohammadi",
]
z = zip(names, last_names)
next
بزنیم به ما یک tuple به سایز 2 میده (چرا 2 ؟ چون 2 تا iterable
بهش دادیم)>>> next(z)به همین صورت میتونید به لیست، ست و ... این
('Ali', 'Hassanzadeh')
zip object
رو تبدیل کنید:>>> list(z)چرا هر tuple دوتا عضو بیشتر نداره؟ چون همونطور که بالا گفتم تعداد به اندازه کوتاه ترین
[('Ali', 'Hassanzadeh'), ('Mohsen', 'Mohammadi')]
iterable
هست که در اینجا last_names
کوتاه تر هست و فقط 2 عضو داره!پس
signature
کلی کلاس zip به شکل زیر هست (از پایتون 3.10 پارامتر strict
بهش اضافه شده که توضیحش میدم)zip(*iterables, strict=False) —> zip objectخوب ی نکته میمونه، اینکه از پایتون 3.10 به این کلاس یک پارامتری اضافه شده به اسم
strict
! کارش چیه؟ مقدارش به صورت پیشفرض False
هست، ولی زمانی که شما اون رو True کنید، چک میکنه که همه iterable
هایی که بهش دادید آیا طول یکسان دارند یا نه و اگر این شرایط برقرار نبود یک خطای ValueError
به شما میده! مثال:names = [خروجی:
"Ali",
"Mohsen",
"Hassan",
]
last_names = [
"Hassanzadeh",
"Mohammadi",
]
print(list(zip(names, last_names, strict=True)))
ValueError: zip() argument 2 is shorter than argument 1
#builtins✔️ کلاس map
کلاس
این تایپ برای اولین پارامتر یک
اول از همه تایپ مپ درست مانند
کاری که
چند مثال کاربردی 🧪
تبدیل همه اعداد یک لیست به مربع خودشان:
اگر به
کلاس
map
یکی دیگه از تایپهای built-in پایتون است.این تایپ برای اولین پارامتر یک
Callable
دریافت میکنه (مثلا یک تابع یا یک کلاس که داندر ____call____ رو پیادهسازی میکنه) و پارامتر بعدیش تعداد متغیری iterable
هست که بعد از callable
بهش پاس میدیم. signature
عه تابع مپ به این شکل هست:map(callable, *iterables) —> map objectاما
map
چه کاری انجام میده؟ 🤔اول از همه تایپ مپ درست مانند
range
و فیلتر lazy iterator
هست، یعنی فوری نتایج رو محاسبه نمیکنه،کاری که
map
میکنه اینه که میاد دونه دونه از اون iterable
(یا iterable
هایی) که بهش داده شده، به اون callable
پاس میده و نتیجه ای که اون callable
بهش داده (در واقع مقداری که از callable
ما return
شده) رو هر بار که ما next
میزنیم به ما برمیگردونه!چند مثال کاربردی 🧪
تبدیل همه اعداد یک لیست به مربع خودشان:
lst = [2, 4, 6, 8]Output:
print(list(map(lambda x: x ** 2, lst)))
[4, 16, 36, 64]
تبدیل تمام استرینگهای یک لیست به شکل Uppercase خودشان:lst = ["John", "David", "Mike"]Output:
print(list(map(str.upper, lst)))
['JOHN', 'DAVID', 'MIKE']
نکته مهم ❗️اگر به
map
چند تا iterable
میدید، باید حواستون باشه که اون callable
باید به تعداد iterable
ها پارامتر داشته باشه! مثال:x = list(map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6]))Output:
print(x)
[5, 7, 9]
در مثال بالا دو تا iterable
به مپ پاس دادیم پس باید تابعی که به map
میدیم دوتا آرگومان بگیره. حالا map
میاد پارامتر اول (یعنی x) رو از اولین iterable
و دومی رو (یعنی y) از دومین iterable
میگیره! نکته قابل توجه دیگه اینکه، این فرایند توی تابع (یعنی جمع x و y) به تعداد اعضای کوتاه ترین iterable
انجام میشه! یعنی اگر یکی از iterable
ها 2 عضو داشت و بقیه 5 عضو، فقط روی 2 عضو اول هر iterable
مپ کار انجام میده! مثال:x = list(map(lambda x, y: x + y, [2, 3], [4, 5, 6, 4]))Output:
print(x)
[6, 8]
#builtinsهیچوقت نباید اسم ماژولی که داریم داخلش کد میزنیم رو اسم یکی از ماژول/پکیج های خود پایتون یا ماژول/پکیج هایی که نصب کردیمشون تا استفاده کنیم قرار بدیم...
مثال: من قرار هست با تاریخ کمی کار کنم و خب ماژول datetime رو که پایتون توی استاندارد لایبرری گذاشته رو import میکنم. ولی اسم فایل یا ماژولی که دارم کد میزنم داخلش رو میذارم datetime.py !
# datetime.py
import datetime
t = datetime.date(2020, 10, 10)
print(t)
اروری دریافت میکنم :
AttributeError: partially initialized module 'datetime' has no attribute 'date' (most likely due to a circular import)
این ارور تا حدی خوبه یه چیزایی داره بهمون راجع partially initialized شدن و همچنین circular import میگه...
سناریوی بد موقعی هست که اسم فایلی که دارم توش کد میزنم datetime نیست ولی کنار فایلم توی "همون پوشه" یه فایل به اسم datetime.py به اشتباه درست کردم و خالی هست... حالا چی :
# main.py
import datetime
t = datetime.date(2020, 10, 10)
print(t)
متن ارور :
AttributeError: module 'datetime' has no attribute 'date'
این جا دیگه نه تنها کمک نمیکنه بلکه باعث میشه اول فکر کنیم که خب آها حتما این ماژول قبلا attribute عه date رو داشته الان حذف کردن برم ببینم معادلش چیه! یا اگه مثلا datetime ماژولی بوده باشه که نصب کرده بودیم، حتما ما ورژن دیگه ای ازشو نصب کردیم... ما که عین کدی که مثلا توی ویدیو آموزشی هست رو داریم میزنیم چرا میگه date رو نداره ؟؟
ماجرا از این قرار هست که وقتی دارید یه ماژولی رو import میکنید ، پایتون یه مسیر های مشخصی رو برای پیدا کردن اون ماژول طی میکنه که میتونید با پرینت کردن sys.path ببینید :
import sys
for path in sys.path:
print(path)
توی ویندوز حدودا(ممکنه بسته به نسخه پایتون و platform ترتیبش فرق کنه یا کم و زیاد باشه ما کاری به این قضیه نداریم) به این شکل هست: (اون فولدر test فولدری هست که ماژولی که داره ران میشه داخلش هست)
C:\Users\usr\Desktop\test
C:\Users\usr\...\Python39\python39.zip
C:\Users\usr\...\Python39\DLLs
C:\Users\usr\...\Python39\lib
C:\Users\usr\...\Python39
C:\Users\usr\...\Python39\lib\site-packages
پایتون این مسیر هارو "به ترتیب" از بالا تا پایین چک میکنه تا ماژولی که اسمشو جلوی import statement زدیم رو پیدا کنه و "به محض" اینکه بهش برسه همون رو برای ما import میکنه.
به مسیر ها نگاه کنید: اولین مسیر همیشه مسیری هست که script شما داخلش هست. (اگه PYTHONPATH رو set کرده باشید به عنوان مسیر دوم بعد از current directory اضافه میشه به sys.path. ) یه مسیر دیگه اون folder عه site-packages هست که میبینید. این دقیقا همونجایی هست که پکیج هایی که نصب میکنید داخلش میرن. باقی مسیر ها هم برای ماژول های دیگه ی پایتون هستند.
حالا میتونیم دلیلشو متوجه بشیم چرا پایتون توی هر دو مثالی که اول پست زدیم اول پکیج مارو پیدا کرد... site-package و فولدر های دیگه ای که ماژول های خود پایتون داخلش هستن "بعد" از اولین مسیری که داخل لیست دیدیم سرچ میشن پس در نتیجه اینجا datetime داره اشاره میکنه به همین ماژولی که داریم توش کد میزنیم(مثال اول) یا اون ماژول datetime ای که کنار فایمون ساختیم (مثال دوم)... اونو پایتون پیدا میکنه و میاره و خب طبیعتا ما چیزی به عنوان "date" تعریف نکرده بودیم !!
اگه کمی کلی تر بخوایم بگیم در واقع "هرجا" از این مسیرها یه فایل datetime.py قرار بدیم که نسبت به اونی که پایتون توی استاندارد لایبرری قرار داده جلوتر باشه این مشکل رو داریم...
سوال: همه ی ماژول ها به همین صورت هستن ؟ نه ! اون هایی که داخل مفسر compile شدن شامل موارد بالا نمیشن یعنی اگه اسم فایلتون رو این اسامی بذارین باعث نمیشه پایتون اونارو پیدا کنه اول. اینجوری ببینینشون :
import sys
for i in sys.builtin_module_names:
print(i)
هیچوقت مثلا gc.py شما زود تر پیدا نمیشه.
مثال: من قرار هست با تاریخ کمی کار کنم و خب ماژول datetime رو که پایتون توی استاندارد لایبرری گذاشته رو import میکنم. ولی اسم فایل یا ماژولی که دارم کد میزنم داخلش رو میذارم datetime.py !
# datetime.py
import datetime
t = datetime.date(2020, 10, 10)
print(t)
اروری دریافت میکنم :
AttributeError: partially initialized module 'datetime' has no attribute 'date' (most likely due to a circular import)
این ارور تا حدی خوبه یه چیزایی داره بهمون راجع partially initialized شدن و همچنین circular import میگه...
سناریوی بد موقعی هست که اسم فایلی که دارم توش کد میزنم datetime نیست ولی کنار فایلم توی "همون پوشه" یه فایل به اسم datetime.py به اشتباه درست کردم و خالی هست... حالا چی :
# main.py
import datetime
t = datetime.date(2020, 10, 10)
print(t)
متن ارور :
AttributeError: module 'datetime' has no attribute 'date'
این جا دیگه نه تنها کمک نمیکنه بلکه باعث میشه اول فکر کنیم که خب آها حتما این ماژول قبلا attribute عه date رو داشته الان حذف کردن برم ببینم معادلش چیه! یا اگه مثلا datetime ماژولی بوده باشه که نصب کرده بودیم، حتما ما ورژن دیگه ای ازشو نصب کردیم... ما که عین کدی که مثلا توی ویدیو آموزشی هست رو داریم میزنیم چرا میگه date رو نداره ؟؟
ماجرا از این قرار هست که وقتی دارید یه ماژولی رو import میکنید ، پایتون یه مسیر های مشخصی رو برای پیدا کردن اون ماژول طی میکنه که میتونید با پرینت کردن sys.path ببینید :
import sys
for path in sys.path:
print(path)
توی ویندوز حدودا(ممکنه بسته به نسخه پایتون و platform ترتیبش فرق کنه یا کم و زیاد باشه ما کاری به این قضیه نداریم) به این شکل هست: (اون فولدر test فولدری هست که ماژولی که داره ران میشه داخلش هست)
C:\Users\usr\Desktop\test
C:\Users\usr\...\Python39\python39.zip
C:\Users\usr\...\Python39\DLLs
C:\Users\usr\...\Python39\lib
C:\Users\usr\...\Python39
C:\Users\usr\...\Python39\lib\site-packages
پایتون این مسیر هارو "به ترتیب" از بالا تا پایین چک میکنه تا ماژولی که اسمشو جلوی import statement زدیم رو پیدا کنه و "به محض" اینکه بهش برسه همون رو برای ما import میکنه.
به مسیر ها نگاه کنید: اولین مسیر همیشه مسیری هست که script شما داخلش هست. (اگه PYTHONPATH رو set کرده باشید به عنوان مسیر دوم بعد از current directory اضافه میشه به sys.path. ) یه مسیر دیگه اون folder عه site-packages هست که میبینید. این دقیقا همونجایی هست که پکیج هایی که نصب میکنید داخلش میرن. باقی مسیر ها هم برای ماژول های دیگه ی پایتون هستند.
حالا میتونیم دلیلشو متوجه بشیم چرا پایتون توی هر دو مثالی که اول پست زدیم اول پکیج مارو پیدا کرد... site-package و فولدر های دیگه ای که ماژول های خود پایتون داخلش هستن "بعد" از اولین مسیری که داخل لیست دیدیم سرچ میشن پس در نتیجه اینجا datetime داره اشاره میکنه به همین ماژولی که داریم توش کد میزنیم(مثال اول) یا اون ماژول datetime ای که کنار فایمون ساختیم (مثال دوم)... اونو پایتون پیدا میکنه و میاره و خب طبیعتا ما چیزی به عنوان "date" تعریف نکرده بودیم !!
اگه کمی کلی تر بخوایم بگیم در واقع "هرجا" از این مسیرها یه فایل datetime.py قرار بدیم که نسبت به اونی که پایتون توی استاندارد لایبرری قرار داده جلوتر باشه این مشکل رو داریم...
سوال: همه ی ماژول ها به همین صورت هستن ؟ نه ! اون هایی که داخل مفسر compile شدن شامل موارد بالا نمیشن یعنی اگه اسم فایلتون رو این اسامی بذارین باعث نمیشه پایتون اونارو پیدا کنه اول. اینجوری ببینینشون :
import sys
for i in sys.builtin_module_names:
print(i)
هیچوقت مثلا gc.py شما زود تر پیدا نمیشه.
درود.
میخواستم درباره ی آبجکت معروف و شناخته شده ی generator حرف بزنیم ولی با نگاه کمی متفاوتتر تا به این برسیم که دقیقا چطور کار میکنه و چطور پیداش شد. نیاز هست که کمی حرف های پیش نیاز بزنیم صبور باشید.
قبل از هر چیزی درباره ی خود فانکشن حرف بزنیم؛ ولی نه تو پایتون بلکه تو C:
وقتی یه فانکشنی کال میشه، توی call stack یک frame جدید میاد که برای اون فانکشن هست. این frame شامل تمام متغیر های لوکال و پارامتر های اون فانکشنه. وقتی فانکشن تموم میشه چه اتفاقی میفته؟ اون frame از stack پاپ میشه (یا دقیق ترش stack pointer کم میشه)
و نکته اینجاس که هرچی که توی اون frame هست دیگه قابل دسترس نیست و اگر استفادشون کنیم، undefined behavior هست. چرا؟ چون توی "مموری استک" این frame قرار داده شده بود و اون فضا الان آزاد شده و قابل استفاده هست برای بقیه (توی پرانتز، در C که مدیریت حافظه نداره، باید آبجکت هایی که توی heap میسازیم رو خودمون مدیریت کنیم نه استک):
با اینکه آدرسش رو return کردیم ولی باز هم نمیتونیم به آیتم های لیست دسترسی داشته باشیم.
حالا اینارو گفتم که موضوع مهمی رو بگم. اونم اینه که تو پایتون هم همین call stack و اینا هست ولی اون frame object توی heap ساخته میشه. این یعنی اگر بخوایم میتونیم اون رو ذخیره داشته باشیم و همیشه بمونه! مثلا مانع از نابود شدن خودش و آبجکت های درونش بشیم. تو مثال زیر
خب حالا که اینو گفتیم بریم سراغ خود آبجکت فانکشن تو پایتون. وقتی فانکشن کال میشه یه frame object ساخته میشه. این frame object داخلش آبجکت های زیادی هست (مستقیم یا غیرمستقیم) از جمله رفرنس داره به متغیر های داخل اون namespace و رفرنسی داره به code object که یک unit ئه executable هست. داخل این code object ما bytecode ها رو داریم که همون instruction ها هستن.
درواقع instruction ها هستن که اجرا میشن و این state ذخیره میشه. تو کد زیر
خب حالا بخش جالب ماجرا اینجاست. ما به عنوان طراحان فرضی زبان پایتون، میدونیم که frame ما میتونه خارج از موقع کال شدن هم زنده بمونه + از طرفی به state هم که دسترسی داریم. ( اینکه الان متغیر های local چیا هستن، اینکه الان تا instruction چندم اجرا شده و غیره)
فقط یه مشکلی هست، فانکشن های ما وقتی کال میشن از اولین instruction تا آخرینش رو اجرا میکنن و تموم میشن و همه ی آبجکت های داخل اون frame از بین میرن (اگر رفرنس دیگه ای نداشته باشن جای دیگه).
الان همه چیز محیا هست برای اینکه یه ساختار یا keyword جدیدی بیاریم تو زبان که هرجایی از execution فانکشن خواستیم بتونیم pause کنیم و اون رو با هر state ای که داره به حال خودش رها کنیم.
بیایم yield رو معرفی کنیم! هروقت yield اومد، کافیه اجرا رو متوقف کنیم و مثل فانکشن ها (که بعد از تموم شدنشون، frame شون از stack frame جدا میشن) frame این generator ها رو هم جدا کنیم.
بعدا اگه خواستیم generator رو ادامه بدیم و روش next بزنیم (مستقیم خودمون یا غیر مستقیم توسط پایتون) تنها کاری که باید بکنیم اینه که frameش رو برداریم و بچسبونیم به stack frame ممون و از اون state ای که بودیم ادامه بدیم.
این call stack با linked list پیاده سازی شده و frame ها نود های اون هستن. با
جنریتور ها با وجود سرعت خوبی که دارن، برای سرعت بیشتر ساخته نشدن بلکه برای استفاده بهینهتر از مموری ساخته شدن. داشتن همچین آبجکتی (به اضافه ساختار هایی مثل
میخواستم درباره ی آبجکت معروف و شناخته شده ی generator حرف بزنیم ولی با نگاه کمی متفاوتتر تا به این برسیم که دقیقا چطور کار میکنه و چطور پیداش شد. نیاز هست که کمی حرف های پیش نیاز بزنیم صبور باشید.
قبل از هر چیزی درباره ی خود فانکشن حرف بزنیم؛ ولی نه تو پایتون بلکه تو C:
وقتی یه فانکشنی کال میشه، توی call stack یک frame جدید میاد که برای اون فانکشن هست. این frame شامل تمام متغیر های لوکال و پارامتر های اون فانکشنه. وقتی فانکشن تموم میشه چه اتفاقی میفته؟ اون frame از stack پاپ میشه (یا دقیق ترش stack pointer کم میشه)
و نکته اینجاس که هرچی که توی اون frame هست دیگه قابل دسترس نیست و اگر استفادشون کنیم، undefined behavior هست. چرا؟ چون توی "مموری استک" این frame قرار داده شده بود و اون فضا الان آزاد شده و قابل استفاده هست برای بقیه (توی پرانتز، در C که مدیریت حافظه نداره، باید آبجکت هایی که توی heap میسازیم رو خودمون مدیریت کنیم نه استک):
int *returnArray() {
int arr[3] = {11, 22, 33};
printf("%p\n", arr);
printf("%d\n", arr[1]);
return &arr;
}
int main(void) {
int *arr;
arr = returnArray();
printf("%p\n", arr);
printf("%d\n", arr[1]); // ???
}
با اینکه آدرسش رو return کردیم ولی باز هم نمیتونیم به آیتم های لیست دسترسی داشته باشیم.
حالا اینارو گفتم که موضوع مهمی رو بگم. اونم اینه که تو پایتون هم همین call stack و اینا هست ولی اون frame object توی heap ساخته میشه. این یعنی اگر بخوایم میتونیم اون رو ذخیره داشته باشیم و همیشه بمونه! مثلا مانع از نابود شدن خودش و آبجکت های درونش بشیم. تو مثال زیر
global f
رو اگه از کامنت در بیارید obj از بین نمیره چون frame رو ذخیره کردیم:from gc import collect
from sys import _getframe
class A:
def __del__(self):
print("del called")
def fn():
# global f
f = _getframe(0)
obj = A()
fn()
collect()
input()
خب حالا که اینو گفتیم بریم سراغ خود آبجکت فانکشن تو پایتون. وقتی فانکشن کال میشه یه frame object ساخته میشه. این frame object داخلش آبجکت های زیادی هست (مستقیم یا غیرمستقیم) از جمله رفرنس داره به متغیر های داخل اون namespace و رفرنسی داره به code object که یک unit ئه executable هست. داخل این code object ما bytecode ها رو داریم که همون instruction ها هستن.
درواقع instruction ها هستن که اجرا میشن و این state ذخیره میشه. تو کد زیر
lasti
یعنی last instruction. (توی cpu هم اتفاق مشابهی میفته. اینجا pvm میخواد بدونه چی رو اجرا کرده و حالا نوبت چیه):from sys import _getframe
def fn():
print(_getframe(0).f_lasti)
a = 10
print(_getframe(0).f_lasti)
fn()
خب حالا بخش جالب ماجرا اینجاست. ما به عنوان طراحان فرضی زبان پایتون، میدونیم که frame ما میتونه خارج از موقع کال شدن هم زنده بمونه + از طرفی به state هم که دسترسی داریم. ( اینکه الان متغیر های local چیا هستن، اینکه الان تا instruction چندم اجرا شده و غیره)
فقط یه مشکلی هست، فانکشن های ما وقتی کال میشن از اولین instruction تا آخرینش رو اجرا میکنن و تموم میشن و همه ی آبجکت های داخل اون frame از بین میرن (اگر رفرنس دیگه ای نداشته باشن جای دیگه).
الان همه چیز محیا هست برای اینکه یه ساختار یا keyword جدیدی بیاریم تو زبان که هرجایی از execution فانکشن خواستیم بتونیم pause کنیم و اون رو با هر state ای که داره به حال خودش رها کنیم.
بیایم yield رو معرفی کنیم! هروقت yield اومد، کافیه اجرا رو متوقف کنیم و مثل فانکشن ها (که بعد از تموم شدنشون، frame شون از stack frame جدا میشن) frame این generator ها رو هم جدا کنیم.
بعدا اگه خواستیم generator رو ادامه بدیم و روش next بزنیم (مستقیم خودمون یا غیر مستقیم توسط پایتون) تنها کاری که باید بکنیم اینه که frameش رو برداریم و بچسبونیم به stack frame ممون و از اون state ای که بودیم ادامه بدیم.
def gen():
a = 1
yield
b = 1
yield
g = gen()
next(g)
print(g.gi_frame.f_lasti, g.gi_frame.f_locals)
next(g)
print(g.gi_frame.f_lasti, g.gi_frame.f_locals)
این call stack با linked list پیاده سازی شده و frame ها نود های اون هستن. با
f_back
به frame قبلی اشاره میکنن به راحتی وصل میشن و جدا میشن.جنریتور ها با وجود سرعت خوبی که دارن، برای سرعت بیشتر ساخته نشدن بلکه برای استفاده بهینهتر از مموری ساخته شدن. داشتن همچین آبجکتی (به اضافه ساختار هایی مثل
yield from
) میتونه زمینه خیلی چیز ها رو فراهم کنه. از جمله فریموورک هایی مثل asyncio :)پارو، aur helper ای که ما پیشفرض توی پارچ داریمش و یک aur helper نوشته شده در راست، یک ابزار شخص ثالثی براش هست به نام paruz که میاد و با fzf همچین چیزی میسازه.
اینطوری خیلی راحت تر میتونید دنبال بسته هاتون با paru بگردید.
نصبش:
به زودی paruz رو توی پارچ به همراه چندتا بسته دیگه به صورت پیشفرض قرار خواهم داد.
اینطوری خیلی راحت تر میتونید دنبال بسته هاتون با paru بگردید.
نصبش:
paru -S paruz
به زودی paruz رو توی پارچ به همراه چندتا بسته دیگه به صورت پیشفرض قرار خواهم داد.
This media is not supported in your browser
VIEW IN TELEGRAM
مثل که vscode ساپورت از چند مانیتور رو روی نسخه بتاش اضافه کرده.
https://github.com/microsoft/vscode/issues/10121
https://github.com/microsoft/vscode/issues/10121
@python4all_pro - Data Cleaning Cheat Sheet in py.pdf
168.9 KB
🔘 پاکسازی داده ها با پایتون
🔻چرا دادههای تمیز بسیار مهم هستند، چه چیزی می تواند باعث خطا شود و چگونه خطا ها را شناسایی، پیشگیری و رفع کنیم تا داده های خود را تمیز نگه داریم. مبارزه با دیتاهای آلوده و دسترسی به دیتاهای تمیز یکی از بزرگترین دغدغه های دیتاساینتیست هاست برای آموزش این موضوع از چیت شیت های پاک سازی داده با پایتون که در کانال منتشر میشه استفاده کنید .
✔️دوتا دوره خوب هم با همین موضوع معرفی میکنم استفاده کنید
1️⃣ آموزش پاک سازی داده با پایتون از یودمی : لینک
2️⃣ آموزش ضروری پاکسازی داده ها در پایتون با زیرنویس فارسی : لینک
Cheat Sheet 1 : #Data_Cleaning
#علم_داده #cheat_sheet #pdf
🔻چرا دادههای تمیز بسیار مهم هستند، چه چیزی می تواند باعث خطا شود و چگونه خطا ها را شناسایی، پیشگیری و رفع کنیم تا داده های خود را تمیز نگه داریم. مبارزه با دیتاهای آلوده و دسترسی به دیتاهای تمیز یکی از بزرگترین دغدغه های دیتاساینتیست هاست برای آموزش این موضوع از چیت شیت های پاک سازی داده با پایتون که در کانال منتشر میشه استفاده کنید .
✔️دوتا دوره خوب هم با همین موضوع معرفی میکنم استفاده کنید
1️⃣ آموزش پاک سازی داده با پایتون از یودمی : لینک
2️⃣ آموزش ضروری پاکسازی داده ها در پایتون با زیرنویس فارسی : لینک
Cheat Sheet 1 : #Data_Cleaning
#علم_داده #cheat_sheet #pdf