diff --git a/lectures/oop_intro.md b/lectures/oop_intro.md
new file mode 100644
index 0000000..dcd8d7f
--- /dev/null
+++ b/lectures/oop_intro.md
@@ -0,0 +1,402 @@
+---
+jupytext:
+ text_representation:
+ extension: .md
+ format_name: myst
+kernelspec:
+ display_name: Python 3
+ language: python
+ name: python3
+heading-map:
+ overview: مروری کلی
+ objects: اشیاء
+ type: نوع
+ identity: شناسه
+ object-content-data-and-attributes: 'محتوای شیء: دادهها و ویژگیها'
+ methods: متدها
+ inspection-using-rich: بازرسی با استفاده از Rich
+ a-little-mystery: یک معمای کوچک
+ summary: خلاصه
+ exercises: تمرینها
+---
+
+(oop_intro)=
+```{raw} jupyter
+
+```
+
+# OOP I: اشیاء و متدها
+
+## مروری کلی
+
+پارادایم سنتی برنامهنویسی (مانند Fortran، C، MATLAB و غیره) [رویهای](https://en.wikipedia.org/wiki/Procedural_programming) نامیده میشود.
+
+این پارادایم به شرح زیر عمل میکند
+
+* برنامه دارای یک وضعیت متناظر با مقادیر متغیرهای خود است.
+* توابع فراخوانی میشوند تا بر روی وضعیت عمل کرده و آن را تغییر دهند.
+* خروجیهای نهایی از طریق توالیای از فراخوانیهای تابع تولید میشوند.
+
+دو پارادایم مهم دیگر، [برنامهنویسی شیگرا](https://en.wikipedia.org/wiki/Object-oriented_programming) (OOP) و [برنامهنویسی تابعی](https://en.wikipedia.org/wiki/Functional_programming) هستند.
+
+در پارادایم OOP، دادهها و توابع با هم در "اشیاء" بستهبندی میشوند --- و توابع در این زمینه به عنوان **متدها** شناخته میشوند.
+
+متدها برای تغییر دادههای موجود در شیء فراخوانی میشوند.
+
+* به یک لیست Python فکر کنید که حاوی داده است و متدهایی مانند `append()` و `pop()` دارد که داده را تغییر میدهند.
+
+زبانهای برنامهنویسی تابعی بر اساس ایده ترکیب توابع ساخته شدهاند.
+
+* نمونههای تأثیرگذار شامل [Lisp](https://en.wikipedia.org/wiki/Common_Lisp)، [Haskell](https://en.wikipedia.org/wiki/Haskell) و [Elixir](https://en.wikipedia.org/wiki/Elixir_(programming_language)) هستند.
+
+پس Python در کدام یک از این دستهها قرار میگیرد؟
+
+در واقع Python یک زبان عملگرا است که سبکهای شیگرا، تابعی و رویهای را ترکیب میکند، به جای اینکه رویکردی خالص داشته باشد.
+
+از یک طرف، این امکان را به Python و کاربران آن میدهد تا جنبههای خوب پارادایمهای مختلف را انتخاب کنند.
+
+از طرف دیگر، فقدان خلوص ممکن است گاهی اوقات منجر به برخی سردرگمیها شود.
+
+خوشبختانه این سردرگمی به حداقل میرسد اگر درک کنید که، در سطح بنیادی، Python شیگرا *است*.
+
+منظور ما این است که، در Python، *همه چیز یک شیء است*.
+
+در این سخنرانی، توضیح میدهیم که این گزاره به چه معناست و چرا اهمیت دارد.
+
+ما از کتابخانه شخص ثالث زیر استفاده خواهیم کرد
+
+```{code-cell} python3
+:tags: [hide-output]
+!pip install rich
+```
+
+## اشیاء
+
+```{index} single: Python; Objects
+```
+
+در Python، یک *شیء* مجموعهای از دادهها و دستورالعملهای نگهداریشده در حافظه کامپیوتر است که شامل موارد زیر میشود
+
+1. یک نوع
+1. یک شناسه منحصر به فرد
+1. داده (یعنی محتوا)
+1. متدها
+
+این مفاهیم به ترتیب تعریف و بحث میشوند.
+
+(type)=
+### نوع
+
+```{index} single: Python; Type
+```
+
+Python برای انواع مختلف اشیاء فراهم میکند تا دستههای مختلف داده را در بر گیرد.
+
+به عنوان مثال
+
+```{code-cell} python3
+s = 'This is a string'
+type(s)
+```
+
+```{code-cell} python3
+x = 42 # حالا بیایید یک عدد صحیح ایجاد کنیم
+type(x)
+```
+
+نوع یک شیء برای بسیاری از عبارات مهم است.
+
+به عنوان مثال، عملگر جمع بین دو رشته به معنای الحاق است
+
+```{code-cell} python3
+'300' + 'cc'
+```
+
+از طرف دیگر، بین دو عدد به معنای جمع معمولی است
+
+```{code-cell} python3
+300 + 400
+```
+
+عبارت زیر را در نظر بگیرید
+
+```{code-cell} python3
+---
+tags: [raises-exception]
+---
+'300' + 400
+```
+
+در اینجا ما در حال ترکیب انواع هستیم، و برای Python مشخص نیست که آیا کاربر میخواهد
+
+* `'300'` را به عدد صحیح تبدیل کند و سپس آن را به `400` اضافه کند، یا
+* `400` را به رشته تبدیل کند و سپس آن را با `'300'` الحاق کند
+
+برخی زبانها ممکن است سعی کنند حدس بزنند اما Python *به شدت تایپشده* است
+
+* نوع مهم است، و تبدیل ضمنی نوع نادر است.
+* Python در عوض با بالا آوردن یک `TypeError` پاسخ میدهد.
+
+برای جلوگیری از خطا، باید با تغییر نوع مربوطه توضیح دهید.
+
+به عنوان مثال،
+
+```{code-cell} python3
+int('300') + 400 # برای جمع به عنوان اعداد، رشته را به عدد صحیح تبدیل کنید
+```
+
+(identity)=
+### شناسه
+
+```{index} single: Python; Identity
+```
+
+در Python، هر شیء یک شناسه منحصر به فرد دارد که به Python (و ما) کمک میکند تا شیء را پیگیری کند.
+
+شناسه یک شیء را میتوان از طریق تابع `id()` به دست آورد
+
+```{code-cell} python3
+y = 2.5
+z = 2.5
+id(y)
+```
+
+```{code-cell} python3
+id(z)
+```
+
+در این مثال، `y` و `z` اتفاقاً مقدار یکسانی (یعنی `2.5`) دارند، اما آنها یک شیء نیستند.
+
+شناسه یک شیء در واقع فقط آدرس شیء در حافظه است.
+
+### محتوای شیء: دادهها و ویژگیها
+
+```{index} single: Python; Content
+```
+
+اگر `x = 42` را تنظیم کنیم، یک شیء از نوع `int` ایجاد میکنیم که حاوی داده `42` است.
+
+در واقع، حاوی چیزهای بیشتری است، همانطور که مثال زیر نشان میدهد
+
+```{code-cell} python3
+x = 42
+x
+```
+
+```{code-cell} python3
+x.imag
+```
+
+```{code-cell} python3
+x.__class__
+```
+
+وقتی Python این شیء عدد صحیح را ایجاد میکند، اطلاعات کمکی مختلفی مانند قسمت موهومی و نوع را با آن ذخیره میکند.
+
+هر نامی که بعد از نقطه میآید یک *ویژگی* از شیء سمت چپ نقطه نامیده میشود.
+
+* به عنوان مثال، `imag` و `__class__` ویژگیهای `x` هستند.
+
+از این مثال میبینیم که اشیاء دارای ویژگیهایی هستند که حاوی اطلاعات کمکی هستند.
+
+آنها همچنین دارای ویژگیهایی هستند که مانند توابع عمل میکنند، به نام *متدها*.
+
+این ویژگیها مهم هستند، بنابراین بیایید آنها را به طور عمیق بحث کنیم.
+
+(methods)=
+### متدها
+
+```{index} single: Python; Methods
+```
+
+متدها *توابعی هستند که با اشیاء بستهبندی میشوند*.
+
+به طور رسمی، متدها ویژگیهای اشیاء هستند که **قابل فراخوانی** هستند -- یعنی ویژگیهایی که میتوانند به عنوان تابع فراخوانی شوند
+
+```{code-cell} python3
+x = ['foo', 'bar']
+callable(x.append)
+```
+
+```{code-cell} python3
+callable(x.__doc__)
+```
+
+متدها معمولاً بر روی دادههای موجود در شیئی که به آن تعلق دارند عمل میکنند، یا آن داده را با دادههای دیگر ترکیب میکنند
+
+```{code-cell} python3
+x = ['a', 'b']
+x.append('c')
+s = 'This is a string'
+s.upper()
+```
+
+```{code-cell} python3
+s.lower()
+```
+
+```{code-cell} python3
+s.replace('This', 'That')
+```
+
+بخش بزرگی از قابلیتهای Python حول فراخوانیهای متد سازماندهی شده است.
+
+به عنوان مثال، کد زیر را در نظر بگیرید
+
+```{code-cell} python3
+x = ['a', 'b']
+x[0] = 'aa' # انتساب آیتم با استفاده از نماد براکت مربعی
+x
+```
+
+به نظر نمیرسد که در اینجا از هیچ متدی استفاده شده باشد، اما در واقع نماد انتساب براکت مربعی فقط یک رابط راحت برای فراخوانی متد است.
+
+آنچه در واقع اتفاق میافتد این است که Python متد `__setitem__` را فراخوانی میکند، به شرح زیر
+
+```{code-cell} python3
+x = ['a', 'b']
+x.__setitem__(0, 'aa') # معادل x[0] = 'aa'
+x
+```
+
+(اگر بخواهید میتوانید متد `__setitem__` را تغییر دهید، به طوری که انتساب براکت مربعی کار کاملاً متفاوتی انجام دهد)
+
+## بازرسی با استفاده از Rich
+
+یک بسته خوب به نام [rich](https://github.com/Textualize/rich) وجود دارد که به ما کمک میکند محتویات یک شیء را مشاهده کنیم.
+
+به عنوان مثال،
+
+```{code-cell} python3
+from rich import inspect
+x = 10
+inspect(10)
+```
+اگر بخواهیم متدها را نیز ببینیم، میتوانیم استفاده کنیم
+
+```{code-cell} python3
+inspect(10, methods=True)
+```
+
+در واقع متدهای بیشتری وجود دارند، همانطور که میتوانید ببینید اگر `inspect(10, all=True)` را اجرا کنید.
+
+## یک معمای کوچک
+
+در این سخنرانی ادعا کردیم که Python، در قلب، یک زبان شیگرا است.
+
+اما در اینجا مثالی وجود دارد که بیشتر رویهای به نظر میرسد.
+
+```{code-cell} python3
+x = ['a', 'b']
+m = len(x)
+m
+```
+
+اگر Python شیگرا است، چرا از `x.len()` استفاده نمیکنیم؟
+
+پاسخ به این واقعیت مربوط است که Python برای خوانایی و سبک ثابت تلاش میکند.
+
+در Python، معمول است که کاربران اشیاء سفارشی بسازند --- ما نحوه انجام این کار را {doc}`بعداً ` بحث میکنیم.
+
+کاملاً رایج است که کاربران متدهایی به اشیاء خود اضافه کنند که طول شیء را، به طور مناسب تعریف شده، اندازهگیری کنند.
+
+هنگام نامگذاری چنین متدی، انتخابهای طبیعی `len()` و `length()` هستند.
+
+اگر برخی از کاربران `len()` و دیگران `length()` را انتخاب کنند، سبک ناسازگار و سختتر برای به خاطر سپردن خواهد بود.
+
+برای جلوگیری از این امر، سازنده Python تصمیم گرفت `len()` را به عنوان یک تابع داخلی اضافه کند، تا به تأکید بر اینکه `len()` قرارداد است کمک کند.
+
+حالا، با گفتن همه اینها، Python همچنان در زیر پوشش شیگرا *است*.
+
+در واقع، لیست `x` مورد بحث بالا دارای متدی به نام `__len__()` است.
+
+تنها کاری که تابع `len()` انجام میدهد فراخوانی این متد است.
+
+به عبارت دیگر، کد زیر معادل است:
+
+```{code-cell} python3
+x = ['a', 'b']
+len(x)
+```
+و
+
+```{code-cell} python3
+x = ['a', 'b']
+x.__len__()
+```
+
+## خلاصه
+
+پیام این سخنرانی واضح است:
+
+* در Python، *همه چیز در حافظه به عنوان یک شیء در نظر گرفته میشود*.
+
+این شامل نه فقط لیستها، رشتهها و غیره، بلکه چیزهای کمتر آشکار، مانند
+
+* توابع (پس از خواندن در حافظه)
+* ماژولها (همانطور)
+* فایلهای باز شده برای خواندن یا نوشتن
+* اعداد صحیح و غیره
+
+به یاد داشتن اینکه همه چیز یک شیء است به شما کمک میکند تا با برنامههای خود تعامل کنید و کد Pythonic واضحی بنویسید.
+
+## تمرینها
+
+```{exercise-start}
+:label: oop_intro_ex1
+```
+
+ما قبلاً با {any}`نوع داده بولین ` آشنا شدیم.
+
+با استفاده از آنچه در این سخنرانی آموختیم، لیستی از متدهای شیء بولین `True` را چاپ کنید.
+
+```{hint}
+:class: dropdown
+
+میتوانید از `callable()` برای آزمایش اینکه آیا یک ویژگی از یک شیء میتواند به عنوان تابع فراخوانی شود، استفاده کنید
+```
+
+```{exercise-end}
+```
+
+```{solution-start} oop_intro_ex1
+:class: dropdown
+```
+
+ابتدا، باید همه ویژگیهای `True` را پیدا کنیم، که میتواند از طریق این انجام شود
+
+```{code-cell} python3
+print(sorted(True.__dir__()))
+```
+
+یا
+
+```{code-cell} python3
+print(sorted(dir(True)))
+```
+
+از آنجایی که نوع داده بولین یک نوع اولیه است، میتوانید آن را در فضای نام داخلی نیز پیدا کنید
+
+```{code-cell} python3
+print(dir(__builtins__.bool))
+```
+
+در اینجا از یک حلقه `for` برای فیلتر کردن ویژگیهایی که قابل فراخوانی هستند استفاده میکنیم
+
+```{code-cell} python3
+attributes = dir(__builtins__.bool)
+callablels = []
+
+for attribute in attributes:
+ # از eval() برای ارزیابی یک رشته به عنوان یک عبارت استفاده کنید
+ if callable(eval(f'True.{attribute}')):
+ callablels.append(attribute)
+print(callablels)
+```
+
+```{solution-end}
+```
\ No newline at end of file