درود.
تست نویسی یکی از مهم ترین ارکان توسعه نرم افزار هست. چهار تا اصطلاح معروف که موقع تست نویسی به کار میره:
1. False-Negative
کد شما مشکل "داره" + تست داره به غلط میگه که کد شما مشکلی نداره.
2. False-Positive
کد شما مشکلی "نداره" + تست داره به غلط میگه که کد شما مشکل داره.
3. True-Negative
کد مشکلی "نداره" + تست داره به درستی نشون میده که مشکلی نداره.
4. True-Positive
کد مشکل "داره" + تست به درستی نشون میده که مشکل داره .
خیلی از افراد تعاریف دیگری از این ها دارن که کاملا برعکس چیزیه که خوندین. ولی این تعاریف منبعش از کتاب xUnit Test Patterns از آقای Gerard Meszaros که آقای Martin Fowler هم تاییدش کردن.
راه درست فکر کردن بهش هم این هست که به جای "مشکل" یا "باگ" بیاید از "کرونا" استفاده کنید. وقتی تست کرونا میدید و کرونا دارید(باگ دارید) توی تست میزنه POSITIVE. ولی اگه کرونا داشتید و تو تست زد NEGATIVE یعنی یک NEGATIVE عه غلط هست یا همون false negative.
🖊 @AmirSoroushh
تست نویسی یکی از مهم ترین ارکان توسعه نرم افزار هست. چهار تا اصطلاح معروف که موقع تست نویسی به کار میره:
1. False-Negative
کد شما مشکل "داره" + تست داره به غلط میگه که کد شما مشکلی نداره.
2. False-Positive
کد شما مشکلی "نداره" + تست داره به غلط میگه که کد شما مشکل داره.
3. True-Negative
کد مشکلی "نداره" + تست داره به درستی نشون میده که مشکلی نداره.
4. True-Positive
کد مشکل "داره" + تست به درستی نشون میده که مشکل داره .
خیلی از افراد تعاریف دیگری از این ها دارن که کاملا برعکس چیزیه که خوندین. ولی این تعاریف منبعش از کتاب xUnit Test Patterns از آقای Gerard Meszaros که آقای Martin Fowler هم تاییدش کردن.
راه درست فکر کردن بهش هم این هست که به جای "مشکل" یا "باگ" بیاید از "کرونا" استفاده کنید. وقتی تست کرونا میدید و کرونا دارید(باگ دارید) توی تست میزنه POSITIVE. ولی اگه کرونا داشتید و تو تست زد NEGATIVE یعنی یک NEGATIVE عه غلط هست یا همون false negative.
🖊 @AmirSoroushh
Liskov Substitution Principle:
خانوم Barbara Liskov در سال ۱۹۸۷ یه اصلی رو به نام LSP معرفی کردن که یکی از اصول طراحی کلاس ها در object oriented programming هست.
به طور خلاصه این اصل میگه اگر تایپ B از تایپ A ارث بری میکنه، هرجایی که ما نمونه ای از تایپ A داشته باشیم باید بتونیم به جاش نمونه ای از تایپ B رو قرار بدیم بدون اینکه برنامه به مشکل بخوره. در غیر این صورت این رابطه ارث بری صحیح نیست.
مثال: فرض کنید یه کلاس base داریم به اسم Bird که یک متد داره به اسم Fly:
رابطه ی صحیح چطور میتونه باشه؟ اینکه تشخیص بدیم اصلا Fly متد درستی برای Bird نبوده و اون رو این شکلی بازنویسی کنیم:
خانوم Barbara Liskov در سال ۱۹۸۷ یه اصلی رو به نام LSP معرفی کردن که یکی از اصول طراحی کلاس ها در object oriented programming هست.
به طور خلاصه این اصل میگه اگر تایپ B از تایپ A ارث بری میکنه، هرجایی که ما نمونه ای از تایپ A داشته باشیم باید بتونیم به جاش نمونه ای از تایپ B رو قرار بدیم بدون اینکه برنامه به مشکل بخوره. در غیر این صورت این رابطه ارث بری صحیح نیست.
مثال: فرض کنید یه کلاس base داریم به اسم Bird که یک متد داره به اسم Fly:
class Bird:
def fly(self):
print("I can fly...")
و دو تا subclass داریم به اسم Duck (اردک) و Ostrich (شترمرغ) که از Bird ارث بری میکنن:class Duck(Bird):الان اردک میتونه پرواز کنه چون یه پرنده هست، ولی آیا شترمرغ میتونه پرواز کنه؟ نه نمیتونه. آیا پرنده نیست؟ چرا هست. پس این رابطه درست نیست و اصل LSP رو رعایت نمیکنه.
pass
class Ostrich(Bird):
pass
رابطه ی صحیح چطور میتونه باشه؟ اینکه تشخیص بدیم اصلا Fly متد درستی برای Bird نبوده و اون رو این شکلی بازنویسی کنیم:
class Bird:
pass
class FlyingBirds(Bird):
def fly(self):
print("I can fly...")
class Duck(FlyingBirds):
pass
class Ostrich(Bird):
pass
✒️ @Amirsoroushhدکتر فیروز نادری، دانشمند ایرانی ناسا در ۷۷ سالگی درگذشت.
او که معاون پیشین مدیرکل «آزمایشگاه پیشرانش جت» در ناسا بود، توانست پس از تصدی پست مدیریت برنامههای اکتشافات منظومه شمسی، ۳ ماموریت مهم از جمله پرتاب دو کاوشگر مریخنورد «روح» و «فرصت» را با موفقیت به انجام برساند.
یاد و نامش گرامی🌹
@raspberry_python
او که معاون پیشین مدیرکل «آزمایشگاه پیشرانش جت» در ناسا بود، توانست پس از تصدی پست مدیریت برنامههای اکتشافات منظومه شمسی، ۳ ماموریت مهم از جمله پرتاب دو کاوشگر مریخنورد «روح» و «فرصت» را با موفقیت به انجام برساند.
یاد و نامش گرامی🌹
@raspberry_python
✔️ بررسی موشکافانهی منطقهی کدهای C زبان پایتون، اینبار متد
این مقاله چگونگی انجام عمل سادهی append در لیستها رو با بررسی کدهای مفسر CPython بهتون نشون میده و همچنین بررسی میکنه که این عمل از چه الگوریتمی به چه الگوریتمی رفته و چه اتفاقاتی افتاده 😁
📄 https://virgool.io/@liewpl/how-append-works-gp4apwtpr0bt
#m4hdi
#cpython
✒️ @pyeafp
〰〰〰〰〰〰〰
©@raspberry_python
append
از تایپ list
این مقاله چگونگی انجام عمل سادهی append در لیستها رو با بررسی کدهای مفسر CPython بهتون نشون میده و همچنین بررسی میکنه که این عمل از چه الگوریتمی به چه الگوریتمی رفته و چه اتفاقاتی افتاده 😁
📄 https://virgool.io/@liewpl/how-append-works-gp4apwtpr0bt
#m4hdi
#cpython
✒️ @pyeafp
〰〰〰〰〰〰〰
©@raspberry_python
Forwarded from ~
Media is too big
VIEW IN TELEGRAM
part02:
آموزش ویدئویی کامندلاین گنو/لینوکس
CLI (command line interface)
توزیع اوبونتو Ubuntu
(کاربردی و گویا در حدود 4 ساعت)
+ فایل پیوست دستورات.
پارت ( 1 از 2 )
~
💌 @VimGnuLinuxPythonGit 💌
آموزش ویدئویی کامندلاین گنو/لینوکس
CLI (command line interface)
توزیع اوبونتو Ubuntu
(کاربردی و گویا در حدود 4 ساعت)
+ فایل پیوست دستورات.
پارت ( 1 از 2 )
~
💌 @VimGnuLinuxPythonGit 💌
HashMaps به بیان ساده:
قرار هست ببینیم associative array چیه، hashmap چیه، چه ارتباطی به dictionary داره، ویژگی هاشون چیه، hash collision چیه، چطور برطرف میشن، نمونه خیلی سادش رو پیاده سازی کنیم و در انتها یه نمونه کامل هم ببینیم ازش.
خب... زمانی که ما یک سری دیتا داریم که به هم مرتبط هستن میتونیم اون ها رو توی یه collection نگهداری کنیم مثلا array. اطلاعاتی مثل تمام نمرات دانش آموزان یک کلاس:
مشکل کجاست؟
مشکل اینه که برای ما سخته حفظ کنیم کدوم ایندکس برای کدوم شخص بوده و ترجیح میدیم که اگه نمره ی شخصی رو میخوایم به جای اینکه یه عدد بی معنی بدیم، اسمش رو بدیم و نمرش رو بگیریم:
اینکه اسمش رو(که بهش میگیم کلید) متصل یا مربوط یا "associate" بکنیم به نمرش.
چطوری؟ مثلا:
چیزی که ما بالا ساختیم یک پیاده سازی (بد) از associative array بود. چون associate کردیم یک کلید رو به مقدارش. associative array یک abstract هست و میتونه به شکل های مختلف پیاده سازی بشه.
خب... فقط یه مشکلی هست الان:
قبلا که با ایندکس میگرفتیم صاف میرفتیم سراغ خودش، الان مجبوریم که iterate کنیم روشون و دونه دونه بگردیم تا برسیم به اونی که میخوایم. کنده!! (شما مثال های این پست رو با ۱۰۰۰ تا داده مثلا تصور کنید)
راه حل چیه؟
اینکه بیایم "یه جوری" این اسم ها رو map کنیم به ایندکس های عددی تا دوباره بتونیم صاف بریم سراغ اونی که میخوایم و سرعت بهتر بگیریم.
چطور اینکارو بکنیم؟
مثلا بیایم یک فانکشن بنویسیم که از کلیدها عدد تولید کنیم به این صورت که اعداد اسکی متناظر با هر حرف از کلیدمون رو باهم جمع کنیم. یعنی برای sara داریم:
"sara" # -> 115 + 97 + 114 + 97 -> 423
این میشه فانکشنش:
باقی ماندش رو با طول لیستمون حساب کنیم!
اینطوری مطمئن هستیم که داخل اون رنجی که میخوایم هست. پس:
423 % 5 -> 3
کافیه sara و نمرش رو توی ایندکس شماره ۳ ذخیره کنیم:
الان خوب شد. هر کدوم از نمره هارو بخوایم بگیریم اول اون کلید رو hash میکنیم بعد باقی ماندش رو حساب میکنیم میشه ایندکس مورد نظر. دیگه iteration ای در کار نیست و به time complexity عه O(1) رسیدیم. الان get_grade عه ما اینطوری شد:
خب ما الان تونستیم associative array رو با کمک hashmap پیاده سازی کنیم :) بریم ادامش...
حالا اگه اسم یکی دیگه از دانشجو ها aras بود چی؟
(پست بعدی)
پست ۱ از ۳
قرار هست ببینیم associative array چیه، hashmap چیه، چه ارتباطی به dictionary داره، ویژگی هاشون چیه، hash collision چیه، چطور برطرف میشن، نمونه خیلی سادش رو پیاده سازی کنیم و در انتها یه نمونه کامل هم ببینیم ازش.
خب... زمانی که ما یک سری دیتا داریم که به هم مرتبط هستن میتونیم اون ها رو توی یه collection نگهداری کنیم مثلا array. اطلاعاتی مثل تمام نمرات دانش آموزان یک کلاس:
grades = [17, 19, 18, ...]و با ایندکس های عددی بهشون دسترسی پیدا کنیم:
grades[2]خیلی هم سریع هستن array ها تو دسترسی چون مستقیم میریم سراغ همون نمره ای که نیاز داریم.
مشکل کجاست؟
مشکل اینه که برای ما سخته حفظ کنیم کدوم ایندکس برای کدوم شخص بوده و ترجیح میدیم که اگه نمره ی شخصی رو میخوایم به جای اینکه یه عدد بی معنی بدیم، اسمش رو بدیم و نمرش رو بگیریم:
grades["ali"]راه حل چیه؟
اینکه اسمش رو(که بهش میگیم کلید) متصل یا مربوط یا "associate" بکنیم به نمرش.
چطوری؟ مثلا:
grades = [("reza", 17), ("sara", 19), ("ali", 18)]و بعد هم اینجوری میگیریم:
def get_grade(person_name):خیلی بهتر و راحت تر شد الان...
for name, grade in grades:
if name == person_name:
return grade
print(get_grade("ali"))
چیزی که ما بالا ساختیم یک پیاده سازی (بد) از associative array بود. چون associate کردیم یک کلید رو به مقدارش. associative array یک abstract هست و میتونه به شکل های مختلف پیاده سازی بشه.
خب... فقط یه مشکلی هست الان:
قبلا که با ایندکس میگرفتیم صاف میرفتیم سراغ خودش، الان مجبوریم که iterate کنیم روشون و دونه دونه بگردیم تا برسیم به اونی که میخوایم. کنده!! (شما مثال های این پست رو با ۱۰۰۰ تا داده مثلا تصور کنید)
راه حل چیه؟
اینکه بیایم "یه جوری" این اسم ها رو map کنیم به ایندکس های عددی تا دوباره بتونیم صاف بریم سراغ اونی که میخوایم و سرعت بهتر بگیریم.
چطور اینکارو بکنیم؟
مثلا بیایم یک فانکشن بنویسیم که از کلیدها عدد تولید کنیم به این صورت که اعداد اسکی متناظر با هر حرف از کلیدمون رو باهم جمع کنیم. یعنی برای sara داریم:
s: 115در نتیجه:
a: 97
r: 114
a: 97
"sara" # -> 115 + 97 + 114 + 97 -> 423
این میشه فانکشنش:
def hash_func(string):حالا یه لیست بسازیم که ۵ تا جای خالی داره:
return sum(map(ord, string))
grades = [None, None, None, None, None]خب حالا الان عددی که از هش کردن(پس یه هش فانکشن ساده بود اون) کلید sara به دست آوردیم و چطور map کنیم به یکی از ایندکس های لیستمون؟ ما که ۴۲۳ تا slot نداریم...
باقی ماندش رو با طول لیستمون حساب کنیم!
اینطوری مطمئن هستیم که داخل اون رنجی که میخوایم هست. پس:
423 % 5 -> 3
کافیه sara و نمرش رو توی ایندکس شماره ۳ ذخیره کنیم:
grades = [None, None, None, ("sara", 19), None]اگه همین کار رو برای باقی هم بکنیم همچین چیزی میشه:
grades = [(تو پرانتز حواسمون هست که ترتیبش عوض شد...)
("ali", 18),
None,
None,
("sara", 19),
("reza", 17),
]
الان خوب شد. هر کدوم از نمره هارو بخوایم بگیریم اول اون کلید رو hash میکنیم بعد باقی ماندش رو حساب میکنیم میشه ایندکس مورد نظر. دیگه iteration ای در کار نیست و به time complexity عه O(1) رسیدیم. الان get_grade عه ما اینطوری شد:
def hash_func(string):موقع insert کردن هم دقیقا برعکس همین شکل عمل میکنیم یعنی ابتدا هش میکنیم بعد باقیمانده میگیریم بعد که فهمیدیم کدوم slot برای اون کلید میشه میذاریمش اونجا. درواقع هر چیزی که برای get کردن میگیم برعکسش برای set کردن میشه.
return sum(map(ord, string))
def get_grade(person_name):
hash_value = hash_func(person_name)
idx = hash_value % 5
return grades[idx][1]
print(get_grade("reza"))
خب ما الان تونستیم associative array رو با کمک hashmap پیاده سازی کنیم :) بریم ادامش...
حالا اگه اسم یکی دیگه از دانشجو ها aras بود چی؟
(پست بعدی)
پست ۱ از ۳
چجوری aras رو اضافه کنیم به grades ؟ چون aras از همون حروفی که sara داره تشکیل شده با هش فانکشنی که ما نوشتیم دوباره بهمون ۴۲۳ میده و اگه باقی مانده بگیریم میشه ۳ یا درواقع همون ایندکسی که برای سارا اختصاص داده شده.
مشکل بوجود اومد... به این مشکل میگن hash collision یا تداخل هش ها!
هش فانکشنی که انتخاب کردیم شاید زیاد جالب نبود چون درواقع به ازای تمام جای گشت های یک کلمه همون هش رو بهمون میده.
هش فانکشن خوب توی hashmap ها دو تا ویژگی داره:
۱- باید محاسباتش سبک باشه. چون دائما داره برای همه ی کلید ها حساب میشه.
۲- "سعی کنه" مقدار های یونیک تولید کنه تا به hash collision بر نخوریم.
بیایم کمی تغییرش بدیم: علاوه بر اینکه از عدد اسکیشون استفاده میکنیم، بیایم اون عدد رو در جایگاهی که داره(حرف چندمه) ضرب هم بکنیم به این شکل:
چه کنیم؟ بیایم یه هش فانکشن معقول داشته باشیم که سعی کنه با سرعت بالا hash value رو محاسبه کنه (چیزی که الان داریم) ولی اگه collision پیش اومد رفعش کنیم! چطور؟
روش اول، separate chaining :
تو این روش میگه به جای اینکه ما بیایم slot ها رو خالی بذاریم (None) ، بیایم به جاش از لیست خالی استفاده کنیم! هر موقع hash collision داشتیم میایم اضافش میکنیم به لیست.
یعنی اگه ۴ تا دانش آموزش ما باشن: ali, sara, reza, nima
با هش فانکشن جدیدی که نوشتیم slot های ما به این صورت میشن:
اگه دقت کنیم میبینیم هرچی hash collision بیشتر داشته باشیم به رفتار خطی بیشتر نزدیک میشیم.
این روش اول بود که پیاده سازی خیلی ساده ای هم داره. یه مشکلی ریزی داریم اینجا. یه سری فضای خالی الان توی slot های ما بوجود اومده. آیا میتونیم بیایم از این فضاها استفاده کنیم؟
روش دوم، open addressing:
شرایطی و در نظر بگیرید که الان reza و ali و sara ذخیره شدن و ما میخوایم nima رو اضافه کنیم:
0 -> 1 -> 2 -> 3 -> 4
اگه برای ali میخواستیم probing sequence چی میشد؟
3 -> 4 -> 0 -> 1 -> 2
و به همین ترتیب میریم جلو تا به جای خالی برسیم. الان برای نیما ایندکس بعدی میشه ۱. خالی هست؟ بله. پس میذاریمش اونجا و تبدیل میشه به:
1- linear probing
2- quadratic probing
3- double hashing
کاری که بالا کردیم linear probing بود. چون نمیخوام بیشتر از این طولانی بشه دوتای دیگه رو اینجا نمیگم(پیاده سازیش رو در انتها گذاشتم) ولی حدس زدنش سادس. مثلا تو دومی به جای اینکه دونه دونه بره بالا ، با توان های ۲ میره بالا (کمک میکنه که توده ای از کلید ها رو یک جای hash table مون نداشته باشیم پخش بشن) و آخری میگه یه هش دیگه(هش دوم) انجام بدیم برای پیدا کردن ایندکس بعدی!
اینا هر کدوم مزایا و معایبی دارن که میشه کلی دربارشون بحث کرد که کدوم کجا چرا بهتره.
پست تموم شد ولی یه سری نکته های تکمیلی باقی موند:
(پست بعدی و آخر)
پست ۲ از ۳
مشکل بوجود اومد... به این مشکل میگن hash collision یا تداخل هش ها!
هش فانکشنی که انتخاب کردیم شاید زیاد جالب نبود چون درواقع به ازای تمام جای گشت های یک کلمه همون هش رو بهمون میده.
هش فانکشن خوب توی hashmap ها دو تا ویژگی داره:
۱- باید محاسباتش سبک باشه. چون دائما داره برای همه ی کلید ها حساب میشه.
۲- "سعی کنه" مقدار های یونیک تولید کنه تا به hash collision بر نخوریم.
بیایم کمی تغییرش بدیم: علاوه بر اینکه از عدد اسکیشون استفاده میکنیم، بیایم اون عدد رو در جایگاهی که داره(حرف چندمه) ضرب هم بکنیم به این شکل:
def hash_func(string):الان هش collision رو بر طرف کردیم:
hash_value = 0
for i, char in enumerate(string, start=1):
hash_value += ord(char) * i
return hash_value
for name in ("ali", "sara", "reza", "aras"):خروجیش میشه:
hash_value = hash_func(name)
print(f"{name}: {hash_value} : {hash_value % 5}")
ali: 628 : 3ولی همونطور که حدس میزنید باز هم با کلید های مختلف ما به hash collision بر میخوریم... مثلا جای aras بذارید nima ...
sara: 1039 : 4
reza: 1070 : 0
aras: 1076 : 1
چه کنیم؟ بیایم یه هش فانکشن معقول داشته باشیم که سعی کنه با سرعت بالا hash value رو محاسبه کنه (چیزی که الان داریم) ولی اگه collision پیش اومد رفعش کنیم! چطور؟
روش اول، separate chaining :
تو این روش میگه به جای اینکه ما بیایم slot ها رو خالی بذاریم (None) ، بیایم به جاش از لیست خالی استفاده کنیم! هر موقع hash collision داشتیم میایم اضافش میکنیم به لیست.
یعنی اگه ۴ تا دانش آموزش ما باشن: ali, sara, reza, nima
با هش فانکشن جدیدی که نوشتیم slot های ما به این صورت میشن:
grades = [مشکل حل شد. الان با اینکه وقتی نمره ی نیما رو بخوایم باید قبلش یه رضا رو هم چک کنیم ولی خیلی جلو افتادیم نسبت به اینکه بخوایم همه رو چک کنیم! یعنی کلی کلید رو محاسبه نمیکنیم فقط اون چندتایی که collision داشتن سرچ میشن. و خب باقی کلید ها که collision نداشتن مستقیم پیدا میشن.
[("reza", 17), ("nima", 20)],
[],
[],
[("ali", 18)],
[("sara", 19)],
]
اگه دقت کنیم میبینیم هرچی hash collision بیشتر داشته باشیم به رفتار خطی بیشتر نزدیک میشیم.
این روش اول بود که پیاده سازی خیلی ساده ای هم داره. یه مشکلی ریزی داریم اینجا. یه سری فضای خالی الان توی slot های ما بوجود اومده. آیا میتونیم بیایم از این فضاها استفاده کنیم؟
روش دوم، open addressing:
شرایطی و در نظر بگیرید که الان reza و ali و sara ذخیره شدن و ما میخوایم nima رو اضافه کنیم:
grades = [میایم nima رو هش میکنیم ایندکس و پیدا میکنیم میبینیم میشه صفر. و نگاه میکنیم میبینیم پر هست! میایم یه sequence ای تولید میکنیم به اسم probing sequence. به طوری که از همون اون ایندکسی که محاسبه کردیم شروع میشه(اینجا شد صفر برای نیما) و یه دور میزنه:
("reza", 17),
None,
None,
("ali", 18),
("sara", 19),
]
0 -> 1 -> 2 -> 3 -> 4
اگه برای ali میخواستیم probing sequence چی میشد؟
3 -> 4 -> 0 -> 1 -> 2
و به همین ترتیب میریم جلو تا به جای خالی برسیم. الان برای نیما ایندکس بعدی میشه ۱. خالی هست؟ بله. پس میذاریمش اونجا و تبدیل میشه به:
grades = [ما ۳ شکل probe sequence داریم:
("reza", 17),
("nima", 20),
None,
("ali", 18),
("sara", 19),
]
1- linear probing
2- quadratic probing
3- double hashing
کاری که بالا کردیم linear probing بود. چون نمیخوام بیشتر از این طولانی بشه دوتای دیگه رو اینجا نمیگم(پیاده سازیش رو در انتها گذاشتم) ولی حدس زدنش سادس. مثلا تو دومی به جای اینکه دونه دونه بره بالا ، با توان های ۲ میره بالا (کمک میکنه که توده ای از کلید ها رو یک جای hash table مون نداشته باشیم پخش بشن) و آخری میگه یه هش دیگه(هش دوم) انجام بدیم برای پیدا کردن ایندکس بعدی!
اینا هر کدوم مزایا و معایبی دارن که میشه کلی دربارشون بحث کرد که کدوم کجا چرا بهتره.
پست تموم شد ولی یه سری نکته های تکمیلی باقی موند:
(پست بعدی و آخر)
پست ۲ از ۳
نکته ۱:
دیکشنری توی پایتون نمونه از associative array هست که با hashtable یا hashmap پیاده سازی شده.
نکته ۲:
این پیاده سازی از hashmap چیزی هست که همین الان تو خیلی از زبان ها برای دیکشنری، set ها توی پایتون و برای دیکشنری ها تا قبل از ورژن ۳.۶ توی پایتون استفاده میشده.
به طور کلی hashmap ها ترتیب رو حفظ نمیکنن، همونطور که دیدید ولی از پایتون ۳.۶ به بعد آقای Raymond Hettinger یه پیاده سازی جدیدی برای دیکشنری ها انجام داد به اسم raymond dict. کلیت همینه ولی یه مقدار فرق داره با چیزی که دیدیم که هم کم حجم تره هم باعث میشه ترتیب رو حفظ کنن. اگه علاقه داشتید میتونم بعدا پیاده سازی دیکشنری های جدید پایتون رو هم بگم.
نکته ۳: توی separate chaining میشه به جای لیست از linked list یا binary search tree هم استفاده کرد که باز هم هر کدوم معایب و مزایای خودشون رو دارن.
نکته ۴:
خیلی از نکات گفته نشد به دلیل اینکه نمیخواستم بیشتر از این طولانی بشه. از جمله:
- پایتون علاوه بر key و value خود هشها رو هم نگه داره میکنه. چرا اینکارو میکنه؟
- این hash table عه ما به یه حدی که برسه نیاز داره تا resize بشه تا پرفورمنسش رو حفظ کنه. اگه از یه حدی بیشتر پر باشه تعداد دفعاتی که collision میگیریم بیشتر میشه و دیکشنری یا ست ما کند تر میشه.
- اگه یه کلیدی و delete کردیم تکلیف hashtable چی میشه؟ چطور باید هندل بشه؟
من همه ی انواع implementation هایی که اسمشون اومد رو به صورت کامل پیاده سازی کردم و نکاتی که وقت نشد رو توش گنجوندم. میتونید به عنوان رفرنس بهش یه نگاه بندازید:
* Open Addressing:
- Linear Probing
- Quadratic Probing
- Double Hashing Probing
* Separate Chaining
- With Dynamic Array
- With Linked List
- With Binary Search Tree
https://github.com/amirsoroush/Python_Hashmaps
پست ۳ از ۳
🖊 @AmirSoroushh
دیکشنری توی پایتون نمونه از associative array هست که با hashtable یا hashmap پیاده سازی شده.
نکته ۲:
این پیاده سازی از hashmap چیزی هست که همین الان تو خیلی از زبان ها برای دیکشنری، set ها توی پایتون و برای دیکشنری ها تا قبل از ورژن ۳.۶ توی پایتون استفاده میشده.
به طور کلی hashmap ها ترتیب رو حفظ نمیکنن، همونطور که دیدید ولی از پایتون ۳.۶ به بعد آقای Raymond Hettinger یه پیاده سازی جدیدی برای دیکشنری ها انجام داد به اسم raymond dict. کلیت همینه ولی یه مقدار فرق داره با چیزی که دیدیم که هم کم حجم تره هم باعث میشه ترتیب رو حفظ کنن. اگه علاقه داشتید میتونم بعدا پیاده سازی دیکشنری های جدید پایتون رو هم بگم.
نکته ۳: توی separate chaining میشه به جای لیست از linked list یا binary search tree هم استفاده کرد که باز هم هر کدوم معایب و مزایای خودشون رو دارن.
نکته ۴:
خیلی از نکات گفته نشد به دلیل اینکه نمیخواستم بیشتر از این طولانی بشه. از جمله:
- پایتون علاوه بر key و value خود هشها رو هم نگه داره میکنه. چرا اینکارو میکنه؟
- این hash table عه ما به یه حدی که برسه نیاز داره تا resize بشه تا پرفورمنسش رو حفظ کنه. اگه از یه حدی بیشتر پر باشه تعداد دفعاتی که collision میگیریم بیشتر میشه و دیکشنری یا ست ما کند تر میشه.
- اگه یه کلیدی و delete کردیم تکلیف hashtable چی میشه؟ چطور باید هندل بشه؟
من همه ی انواع implementation هایی که اسمشون اومد رو به صورت کامل پیاده سازی کردم و نکاتی که وقت نشد رو توش گنجوندم. میتونید به عنوان رفرنس بهش یه نگاه بندازید:
* Open Addressing:
- Linear Probing
- Quadratic Probing
- Double Hashing Probing
* Separate Chaining
- With Dynamic Array
- With Linked List
- With Binary Search Tree
https://github.com/amirsoroush/Python_Hashmaps
پست ۳ از ۳
🖊 @AmirSoroushh
GitHub
GitHub - amirsoroush/Python_Hashmaps: Python implementation of hash-tables using different techniques(Open addressing & Separate…
Python implementation of hash-tables using different techniques(Open addressing & Separate Chaining) for solving hash collisions. - amirsoroush/Python_Hashmaps
✔️ بررسی عمیق آبجکتها و تایپها در C layer مفسر CPython
بسیار شنیدیم که همهچیز در پایتون آبجکت است. با اینکه این جمله درسته ولی خب یه سوال پیش میاد! زبان C که پایتون نیست، پایتون هم که C نیست پس چجوری با C چیزی نوشتن که توی پایتون ما به همهچیز میگیم آبجکت!
برای اینکه متوجه بشید آبجکتهای پایتون دقیقا چجوری نوشته شدن، این مقاله رو بخونید 😁
https://virgool.io/@liewpl/cpython-objs-types-c-layer-deep-dive-m5fjelhzrzny
〰〰〰〰〰〰〰
©@raspberry_python
بسیار شنیدیم که همهچیز در پایتون آبجکت است. با اینکه این جمله درسته ولی خب یه سوال پیش میاد! زبان C که پایتون نیست، پایتون هم که C نیست پس چجوری با C چیزی نوشتن که توی پایتون ما به همهچیز میگیم آبجکت!
برای اینکه متوجه بشید آبجکتهای پایتون دقیقا چجوری نوشته شدن، این مقاله رو بخونید 😁
https://virgool.io/@liewpl/cpython-objs-types-c-layer-deep-dive-m5fjelhzrzny
〰〰〰〰〰〰〰
©@raspberry_python
درود. یه موضوع ساده ولی جالب:
همونطور که میدونید برای تولید اعداد (شبه) رندوم از ماژول random استفاده میکنیم توی پایتون. یکی از ویژگی های الگوریتم هایی که برای تولید اعداد شبه رندوم استفاده میشن این هست که باید سعی کنن به صورت یکنواخت اعداد رو توزیع کنن.
منظورم این هست که به طور مثال اگه خواستید ۱۰ هزار بار بین ۱ و ۲ و ۳ یه عددی رو انتخاب کنید باید بتونه تقریبا ۳۳۳۳ تا ۱ ، ۳۳۳۳ تا ۲ و ۳۳۳۳ تا ۳ انتخاب کنه. اول یه تست بگیریم ببینیم چقدر نزدیک هست:
خیلی استفاده ها. یکیش که میخواستم دربارش صحبت کنم، حل بعضی مسائل مربوط به احتمالات ریاضی هست.
یه نمونش رو ببینیم:
۱۴۳ نفر در صف برای ورود به هواپیما هستند و هر نفر یک شماره صندلی متفاوت بین ۱ و ۱۴۳ دارد. تعداد صندلی های هواپیما هم دقیقا ۱۴۳ تا است. نفر اول شماره خودش را گم میکند و روی یک صندلی تصادفی میشند. از آن موقع به بعد هر کسی روی صندلی خودش مینشیند مگر این که فرد دیگری آنجا نشسته باشد و در این صورت روی یک صندلی خالی تصادفی مینشیند.
احتمال اینکه نفر ۱۴۳ ام روی صندلی خودش بنشیند چقدر است؟
اگه تونستین این سوال رو از راه ریاضی حل کنید که چه عالی، ولی اگر مثل من با دیدن صورت سوال راه حل ریاضیش به ذهنتون نیومد یا شک داشتید، کافیه بیاید فقط ۱ بار اون داستانی که توی صورت سوال اومده رو به کد تبدیل کنید، هرجا گفت تصادفی یا رندوم شما از random استفاده میکنید. در آخر مثلا ۱۰ هزار بار توی لوپ تکرارش کنید. به همین راحتی جواب و به دست میارید.
کلیت کار: یک لیستی درست کنید از ۱۴۳ نفر که هر کدوم یه شماره صندلی ای بین ۱ تا ۱۴۳ دستشونه، برای نفر اول یه شماره به صورت رندم انتخاب کنید، بعد از نفر دوم تا آخر چک کنید که آیا صندلیش خالی یا None هست یا پره؟
اگه خالی بود بذاریدش اونجا و اگه پر بود یه شماره رندوم براش انتخاب کنید. در انتها، ما بدست آوردیم که "یک بار"ش چی میشه... آیا نفر آخر میشینه سر جاش یا نمیشینه. این جواب مهم نیست چی باشه، همین تابع رو ۱۰ هزار بار کال کنید و توی Counter بذارید.
احتمالش چقدر شد؟
🖊 @AmirSoroushh
همونطور که میدونید برای تولید اعداد (شبه) رندوم از ماژول random استفاده میکنیم توی پایتون. یکی از ویژگی های الگوریتم هایی که برای تولید اعداد شبه رندوم استفاده میشن این هست که باید سعی کنن به صورت یکنواخت اعداد رو توزیع کنن.
منظورم این هست که به طور مثال اگه خواستید ۱۰ هزار بار بین ۱ و ۲ و ۳ یه عددی رو انتخاب کنید باید بتونه تقریبا ۳۳۳۳ تا ۱ ، ۳۳۳۳ تا ۲ و ۳۳۳۳ تا ۳ انتخاب کنه. اول یه تست بگیریم ببینیم چقدر نزدیک هست:
> from random import randintخیلی خوب و نزدیک بود. ولی حالا از اینکه اینا یکنواخت توزیع میشن چه استفادهای میتونیم بکنیم؟
> from collections import Counter
>
> Counter((randint(1,3) for _ in range(10_000)))
Counter({2: 3379, 3: 3345, 1: 3276})
خیلی استفاده ها. یکیش که میخواستم دربارش صحبت کنم، حل بعضی مسائل مربوط به احتمالات ریاضی هست.
یه نمونش رو ببینیم:
۱۴۳ نفر در صف برای ورود به هواپیما هستند و هر نفر یک شماره صندلی متفاوت بین ۱ و ۱۴۳ دارد. تعداد صندلی های هواپیما هم دقیقا ۱۴۳ تا است. نفر اول شماره خودش را گم میکند و روی یک صندلی تصادفی میشند. از آن موقع به بعد هر کسی روی صندلی خودش مینشیند مگر این که فرد دیگری آنجا نشسته باشد و در این صورت روی یک صندلی خالی تصادفی مینشیند.
احتمال اینکه نفر ۱۴۳ ام روی صندلی خودش بنشیند چقدر است؟
اگه تونستین این سوال رو از راه ریاضی حل کنید که چه عالی، ولی اگر مثل من با دیدن صورت سوال راه حل ریاضیش به ذهنتون نیومد یا شک داشتید، کافیه بیاید فقط ۱ بار اون داستانی که توی صورت سوال اومده رو به کد تبدیل کنید، هرجا گفت تصادفی یا رندوم شما از random استفاده میکنید. در آخر مثلا ۱۰ هزار بار توی لوپ تکرارش کنید. به همین راحتی جواب و به دست میارید.
کلیت کار: یک لیستی درست کنید از ۱۴۳ نفر که هر کدوم یه شماره صندلی ای بین ۱ تا ۱۴۳ دستشونه، برای نفر اول یه شماره به صورت رندم انتخاب کنید، بعد از نفر دوم تا آخر چک کنید که آیا صندلیش خالی یا None هست یا پره؟
اگه خالی بود بذاریدش اونجا و اگه پر بود یه شماره رندوم براش انتخاب کنید. در انتها، ما بدست آوردیم که "یک بار"ش چی میشه... آیا نفر آخر میشینه سر جاش یا نمیشینه. این جواب مهم نیست چی باشه، همین تابع رو ۱۰ هزار بار کال کنید و توی Counter بذارید.
احتمالش چقدر شد؟
🖊 @AmirSoroushh
Forwarded from انرژی پرس
This media is not supported in your browser
VIEW IN TELEGRAM
📢 متهم کمبود برق کیست؟
🔹باز هم تابستان آمد و حرف از کمبود برق کشور داغ شده است.
🔹اما به راستی چه کسی در شرایط به وجود آماده مقصر است؟ چرا ایران که خود یکی از بزرگترین دارندگان منابع انرژی در جهان است، تابستانها با کمبود برق و زمستانها با کمبود گاز مواجه میشود؟
🔹خاموشی بخش صنعتی چه آسیبهایی به دنبال دارد و با این شرایط میتوان انتظار داشت از بحرانهای اقتصادی که با آن دست به گریبان است، خلاص شود؟ با توجه به برنامههای موجود آیا امیدی به رفع کمبود برق کشور وجود دارد؟
🗣 دکتر هاشم اورعی، استاد برق دانشگاه شریف و رئیس انجمن انرژی بادی ایران/ فردای اقتصاد
_
©️انــرژی پـــــرس
✅ @energypress
📌 Energypress.ir
🔹باز هم تابستان آمد و حرف از کمبود برق کشور داغ شده است.
🔹اما به راستی چه کسی در شرایط به وجود آماده مقصر است؟ چرا ایران که خود یکی از بزرگترین دارندگان منابع انرژی در جهان است، تابستانها با کمبود برق و زمستانها با کمبود گاز مواجه میشود؟
🔹خاموشی بخش صنعتی چه آسیبهایی به دنبال دارد و با این شرایط میتوان انتظار داشت از بحرانهای اقتصادی که با آن دست به گریبان است، خلاص شود؟ با توجه به برنامههای موجود آیا امیدی به رفع کمبود برق کشور وجود دارد؟
🗣 دکتر هاشم اورعی، استاد برق دانشگاه شریف و رئیس انجمن انرژی بادی ایران/ فردای اقتصاد
_
©️انــرژی پـــــرس
✅ @energypress
📌 Energypress.ir