یکی از امکانات جالب در پایتون ۳.۷ به بعد اضافه شدن dataclass هست. امروز و در این پست نگاهی به این کتابخوانه می‌کنیم و از ماژول مورد علاقه خودم برای مدل‌سازی pydantic هم خواهم گفت.

کلاس داده (Dataclass)

در بسیاری از پروژه ها قالب های داده داریم مثلا شخصی که در سیستم ثبت می‌شود دارای فیلد های داده مانند نام، نشانی، سن، آدرس ایمیل و … است (جداً برای فیلد هیچ معادل فارسی درستی پیدا نکردم!). یکی از روش های نگهداری و استفاده از این داده ها که ساختار و فیلد های مشخصی دارند استفاده از dataclass است.

در واقع dataclass یک decorator از کتاب‌خانه‌ی dataclasses است. کلاس داده تفاوت یا محدودیتی نسبت به یک کلاس معمولی پایتون ندارد اما می‌تواند کار را ساده‌تر کند چون که این دکوریتور خودش توابع __init__() و __repr__() را ایجاد می‌کند.

from dataclasses import dataclass, field

@dataclass
class Person:
    name:str
    lastname:str
    age:int = 0
    address:str = ""
    children: list["person"] = field(default_factory=list)

کد بالا یک مدل داده برای یک فرد را می‌سازد. دکوریتور dataclass همراه با توابع دیگر یک تابع init مانند زیر ایجاد می‌کند:

def __init__(self, name:str, lastname:str, age:int = 0, address="", children=[]):
    self.name = name
    self.lastname = lastname
    self.age = age
    ...

دقت کنید که هنگام ایجاد کلاس داده استفاده از typehint ضروری است. typehint (راهنمای نوع؟!) یک شیوه نوشتار در پایتون برای اشاره به نوع داده یک متغیر است. مثلا:

age:int

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

استفاده از تابع field در کلاس های داده

همونطور که در مثال بالا آمده برخی فیلدها می‌توانند داده پیشفرض داشته باشند (در مثال age, address و children) اما باید دقت کنید که برای داده هایی که اسطلاحاً mutable هستند مانند list, dict ,… برای این که مشکلی پیش نیاد باید از تابع field استفاده کنید تا یک تابع مثلا list() را هنگام ایجاد یک نمونه صدا بزند و خروجی را در فیلد ذخیره کند (در غیر این صورت یک لیست مشترک بین همه نمونه ها خواهید داشت که می‌تواند برای‌تان ایجاد مشکل کند).

from datetime import datetime

@dataclass
class book:
    name:str
    author:str
    was_added_at:datetime = field(default_factory=datetime.now)
    owners:list[Person] = field(default_factory=list)

در کد بالا برای فیلد «تاریخ اضافه شدن» هنگام ایجاد یک نمونه تابع now() صدا زده می‌شود که تاریخ فعلی را باز می‌گرداند (البته اگه در ورودی ها تاریخ دیگری داده شد جایگزین می‌شود)

ماژول pydantic

اگر امکانات بیشتری نیاز داشتید حتما نگاهی به ماژول pydantic بیاندازید. این ماژول کامل با هدف مدل‌سازی داده و اعتبارسنجی داده هاست. این ماژول امکانات زیادی داره مثل خواندن و خروجی به فرمت های مختلف مثل json، تولید schema و …

جدا از این که با linter ها و ویرایشگر های کد به خوبی کار می‌کند در بسیاری از ماژول های دیگر مانند FastAPI, Beanie و … استفاده شده.

from datetime import datetime
from pydantic import BaseModel, PositiveInt

class User(BaseModel):
    id: int  
    name: str = 'John Doe'  
    signup_ts: datetime | None  
    tastes: dict[str, PositiveInt]

این ماژول علاوه بر این که همانند یک dataclass به شما امکان دسترسی به فیلد ها مختلف با نوشتار نقطه‌ای می‌دهد (dot notation) و ویرایشگر کد شما نیز به خوبی شما را راهنمایی می‌کند، صحت داده ها را می‌سنجد، مثلا نمی‌توانید برای فیلد id که از جنس عدد است یه متن وارد کنید. (البته pydantic دوست داشتنی، رشته "12" را به عدد تبدیل می‌کنه و گیر نمیده ولی اجازه نمیده که مثلا "foobar" ذخیره بشه)

خطای اعتبارسنجی برای فیلد های signup_ts و tastes

مقایسه pydantic با dataclass

ماژول pydantic تمام نیاز هایی که هنگام استفاده از dataclass دارید را به خوبی پاسخگو هست و به شما بسیاری امکانات بهتر و مفید‌تر می دهد، برای مثال تبدیل یک نمونه به JSON و بلعکس به همراه اعتبارسنجی داده ها به سادگی انجام می‌شود و نوع داده های مختلفی مثل آدرس ایمیل، عدد مثبت و حتی نوع داده سفارشی شما را پشتیبانی می‌کند. کلی امکانات دیگر نیز هستند که همه‌ی آن ها را در مستندات کامل این ماژول در سایت‌شون می‌تونید بخونید.

docs.pydantic.dev

بهنام سیم‌جو08-02-1403 تخصصی

الگوریتم کوله‌پشتی، یک الگوریتم از نوع حریصانه هست. در این مطلب در مورد الگوریتم کوله‌پشتی یک و صفر (0/1 knapsack algorithm) می‌نویسم. برای مثال فرض کنید یک کوله پشتی با حجم ۹۰ لیتر دارید؛ و وسایلی که دارید علاوه بر حجم برای شما یک ارزش یا اهمیت دارند و احتمالا همه آن‌ها جا نمی‌شوند. حال به چه صورت وسایل را انتخاب می‌کنید تا بیشترین ارزش را در کوله پشتی خود داشته باشید؟ در الگوریتم کوله‌پشتی یک و صفر یا یک شی انتخاب می‌شود و یا خیر! امکان برش و تکه کردن نیست.

بهنام سیم‌جو28-10-1402 تخصصی

امروز می‌خوام براتون از رمزنگاری دوسویه یا دو کلیده بگم، این رمزنگاری دنیای اطلاعات رو زیر و رو کرده! تو جهان امروز هر جا رو که نگاه می‌کنی ردپای این رمزنگاری هست! HTTPS ،SSH، ارز های دیجیتال، شبکه‌های مجازی و … همه و همه دارن از این روش برای حفظ امنیت استفاده می‌کنن.

آنچه خواهید خواند!

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

بهنام سیم‌جو10-12-1401 عمومی

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

پایپ (pipe) چیست؟

به طور پیش‌فرض سیستم‌عامل ورودی‌ها رو از موس و کیبورد می‌گیره و خروجی‌ها رو روی صفحه‌نمایش می‌نویسه. اما در بعضی مواقع نیاز هست که یک برنامه از خروجی‌های یک برنامه (یا دستور) دیگه استفاده کنه یا به ورودی استاندارد یک برنامه داده ارسال کنه. در چنین شرایطی pipe استفاده میشه. pipe یک فضای موقتی در حافظه برای جابه‌جایی اطلاعات بین دو برنامه هست که البته یک طرفه هم هست؛ یعنی مثلا برای گرفتن خروجی باید از یک pipe و برای نوشتن ورودی هم از یک pipe دیگر باید استفاده کرد.

بهنام سیم‌جو21-11-1401 تخصصی

زبان‌ها معمولاً یا تعیین نوع پویا دارند؛ مانند کامن لیسپ، پایتون، جاوا اسکریپت یا دارای تعیین نوع ایستا هستند؛ مانند سی و سی‌پلاس‌پلاس، راست و دوباره کامن لیسپ (معمولاً پیاده‌سازی‌های مدرن کامن لیسپ، مانند SBCL، اجازه می‌دهند بنا به خواست برنامه‌نویس، قسمتی از کد، دارای تعیین نوع ایستا و قسمتی دارای تعیین نوع پویا باشد).

در پایتون، تعیین نوع متغیر‌ها، مقدار یا مقادیر بازگشتی توابع و متد‌ها و آرگومان‌های توابع اجباری نیست. اما می‌توانیم با تعیین نوع و استفاده از یک نرم‌افزار Linter به کاهش خطا‌های خود پیش از اجرا کمک کنیم.

def f(x: int) - > int:
    return x * 2 + 1

با این که تعیین نوع آرگومان یا ورودی تابع f که x باشد و مقدار بازگشت آن یعنی x*2 + 1 در اجرا تأثیری ندارد، اما زمانی که بخواهم مقدار بازگشت تابع f را با یک رشته نویسه (کاراکتر) جمع کنم به من اخطار داده می‌شود:

بدیهی است که اجرای این برنامه به وسیلهٔ پایتون نیز باعث خطا می‌شود. در مقابل زمانی که نوع ورودی و خروجی تابع را مشخص نمی‌کنم اخطاری داده نمی‌شود:

در ادامه با تعیین نوع ورودی‌ها و خروجی توابع و متد‌ها و ویژگی‌های یک کلاس آشنا می‌شویم.

فاروق کریمی‌زاده30-08-1401 تخصصی

مسئلهٔ ۸ وزیر می‌پرسد که در یک صفحهٔ شطرنج چه‌طور می‌توانیم ۸ مهرهٔ وزیر را چنان قرار دهیم که هیچ‌کدام در معرض تهدید دیگری نباشد. در ریاضیات و علوم کامپیوتر، مسئلهٔ n وزیر یک نسخهٔ تعمیم‌یافته از ۸ وزیر می‌باشد که برای اکثر nهای صحیح مثبت (یا طبیعی) بیش‌تر از یک چینش وجود دارد.

قبلاً یک روش برای پیدا کردن راه حل برای مسئلهٔ ۸ وزیر با استفاده از الگوریتم ژنتیک ارائه دادم. حال می‌خواهم یک روش دیگر برای همین هدف اما به صورت یک الگوریتم قطعی و تصادفی به همراه کد پایتون ارائه دهم.

زمانی که از یک برنامه‌نویس پایتونی بخواهید یک تابع ساده بنویسد تا ارقام یک عدد را جمع کند و برگرداند، احتمالاً ابتدا عدد را به یک رشته تبدیل می‌کند و سپس رشته را به لیست (فهرست) و نهایتاً تک‌تک اعضای لیست را که ارقام عدد به صورت رشته‌های تک‌نویسه‌ای هستند به عدد تبدیل می‌کند و سپس آن‌ها را با هم جمع می‌کند. ولی الزاماً اولین روشی که برای حل مسئله به ذهن‌مان می‌رسد، بهترین روش نیست. در این مطلب دو الگوریتم برای جمع ارقام یک عدد صحیح به صورت بازگشتی و تکرارشونده به همراه کد های پایتون آن ها ارائه می‌دهم.

فاروق کریمی‌زاده16-08-1401 تخصصی

صدای بوق ممتد از لحاظ فنی همان موج سینوسی با فرکانسی (بسامد) ثابت است. در این مطلب یک کد ساده و کوتاه پایتون ارائه می‌دهم که بدون استفاده از کتاب‌خانه‌های اضافی، می‌تواند یک بوق را با هر فرکانسی تولید کند و در یک فایل صوتی wave ذخیره کند.

فاروق کریمی‌زاده07-08-1401 تخصصی

مسئلهٔ ۸ وزیر یک تمرین معروف در علوم کامپیوتر و ریاضیات می‌باشد. این مسئله در مورد یک صفحهٔ شطرنج رایج و مهرهٔ وزیر در این بازی فکری می‌باشد. در ریاضیات ثابت می‌شود که می‌توان ۸ وزیر را در یک صفحهٔ شطرنج چنان قرار داد که هیچ‌کدام از وزیر‌ها، دیگری را تهدید نکنند. با تعمیم این مسئله در ریاضیات، ثابت می‌شود که در یک صفحهٔ شطرنج به ضلع n، می‌توان تعداد n وزیر قرار داد؛ چنانچه هیچ‌کدام دیگری را تهدید نکنند. در علوم کامپیوتر می‌توان با روش‌های مختلفی این مسئله را حل کرد و به یک چینش از مهره‌های وزیر رسید که هیچ‌کدام دیگری را تهدید نکنند. یکی از این روش‌ها «الگوریتم ژنتیک» است.

تصویر از Encik Tekateki

خیلی ها میگن پایتون زبان ساده‌ای هست، میشه اون رو زود یاد گرفت، بخاطر تعیین نوع پویا(dynamic typing) دیگه نیازی نیست که برنامه‌نویس با type ها درگیر باشه و …

ولی آیا واقعا همین‌طوره؟! توی این مطلب قصد دارم کمی زبان پایتون رو به عنوان یه برنامه‌نویس پایتون بررسی کنم.

۱. پایتون زبان ساده‌ای هست

منظور از سادگی زبان می‌تونه خوانا بودن اون و نزدیکی اون به زبان انگلیسی (زبان انسان) باشه. برای مثال دو تکه کد زیر رو ببینید:

زبان پایتون:

if not 2 in lst:
  for x in lst:
    print(x);

زبان سی‌شارپ:

if ( ! lst.contains(2) )
  foreach ( int x in lst )
    Console.WriteLine(x);

بهنام سیم‌جو27-07-1401 تخصصی

حتماً تا به حال با برنامه هایی سروکار داشتید که امکان نصب افزونه داشتند. در این پست قرار هست بهتون بگم چطور میشه توی پایتون برنامه‌ای بنویسیم که بشه بهش افزونه اضافه کرد.

معماری افزونه‌ای (plugin architecture) یک شیوه توسعه نرم‌افزار است که به برنامه‌نویس این امکان رو میده که بدون نیاز به ویرایش کد های اصلی برنامه‌ش (هسته/main) قابلیت ها رو با ارائه بسته‌هایی به نام پلاگین در اختیار کاربران قرار بده و کاربران هم می‌تونن به سادگی با توجه به نیازشون از بین این افزونه ها، اون هایی که می‌خوان رو به برنامه‌شون اضافه کنن.

از طرفی میشه از این معماری به عنوان یک پلن تجاری نیز استفاده کرد. مثلا شما می‌تونید برنامه خودتون رو به صورت رایگان و حتی متن‌باز عرضه کنید اما با فروش پلاگین ها (و یا ارائه خدمات) کسب درآمدکنید. اگر شما هم یک کاربر وردپرس باشید حتما با این پلن آشنا هستید! 😄

پ.ن: پروژه telegram-post-bot من در گیت‌هاب از همین ساختار پیروی می‌کنه و توش امکان اضافه کردن پلاگین هست و درواقع همین پروژه بهانه‌ای شد که من پیاده‌سازی این معماری رو توی پایتون یاد بگیرم و امتحان کنم.

خب وقتشه که دیگه مقدمه رو بذاریم کنار و بریم سراغ اصل مطلب!

بهنام سیم‌جو29-05-1401 تخصصی

هیچ می‌دونستین که تو پایتون می‌تونین برای لیست ها و توپل ها عبارت هایی مثل [1,2,3]>[0,2,3] نوشت؟ یعنی می‌تونی خیلی راحت لیست ها رو باهم مقایسه کنی.

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

بهنام سیم‌جو29-04-1401 تخصصی

امروز، دوشنبه ۲ اسفند ۱۴۰۰،‌ جلسه دوم گروه نرم‌افزار آزاد هرمزگان را با حضور نویسنده این مطلب داشتیم و به پیشنهاد یکی از اعضا، یک بازی جالب کردیم: «به صورت چرخشی در یک دایره هرکس میبایست نام یک ماژول پایتونی، توکار یا غیر تو‌کار،‌ بگوید. نام ماژول‌ها روی تابلو نوشته می‌شود و کسی حق تکرار اسم یک ماژول را ندارد. کسی که ظرف مدت زمان ۳۰ ثانیه نتوانست اسمی پیدا کند، از بازی خارج می‌شود و آخرین نفر باقی مانده در بازی برنده است». روشن است که در بازی حق جستجو کردن، نوشتن یا امثالهم را نداشتیم!

بنده در دانشگاه هرمزگان دستیار تدریس یا حل التمرین(TA) برنامه‌سازی پیشرفته هستم بودم. ضمن تصحیح پروژه دانشجویان به اشتباهاتی درست(!) در کد هایشان برخوردم. قسمت درست کد‌ها این می‌باشد که «کار» می‌کنند اما به روش درست پایتون نوشته نشده‌اند.

فاروق کریمی‌زاده26-11-1400 تخصصی

به صورت کلی، جنگو و django-admin تلاش می‌کنند با پیاده‌سازی پیش‌فرض‌هایی که مناسب هستند زندگی توسعه‌دهنده را آسان‌تر کنند. در نتیجه یک توسعه دهنده قادر خواهد بود تا یک اپلیکیشن را در زمان بسیار کمی بالا بیاورد. اما او مجبور است به اکثر پیش‌فرض‌ها بچسبد. البته سفارشی‌سازی ممکن است اما اغلب تغییر پیش‌فرض‌ها نیازمند فهمی درست از اتفاقاتی است که پشت صحنه می‌افتد که می‌تواند وقت‌گیر و نیازمند مهارت باشد.

فاروق کریمی‌زاده18-11-1400 تخصصی