حل مشکل Race Condition توی جنگو

داشتم یه اپلیکیشن ساده جَنگو رو می‌ساختم که با یه مشکل به اسم Race Condition برخوردم. خیلی چیز جالب و در عین حال ساده‌ایه که باید حتما حتما حل بشه. خب منبع این آموزش کوچولو موچولو وبسایت اصلی Django هستش و توی آخر همین پست لینکش رو گذاشتم.

قضیه از چه قراره؟! تصور کنید که یه وبسایت فروشگاهی دارید که توش میخواید یه مداد بفروشید. تعداد مدادهای موجودتون ۱۰ تا هستش. منطق برنامه شما به این صورته که به ازای هر فروش یک عدد از مقادیر موجودتون کم میشه. پس من اگه بیام یه مداد بخرم میشه ۹ تا.

ولی وقتی من میام یه مداد می‌خرم دقیقا چه چیزی اون پشت مشتا اتفاق می‌افته. خیلی ساده است: بانک اطلاعاتی میاد اول مقدار موجود رو می‌گیره و اون رو میبره تو رَم، براساس منطق برنامه میاد یه دونه کم میکنه پس مقدار ۱۰ توی رم میشه ۹ و در نهایت object.save() … مقدار توی بانک اطلاعاتی ذخیره میشه.

حالا یه مشکلی که پیش میاد توی این حالت چیه؟ اینکه اگه دو نفر همزمان داشتن یه مداد میخریدن چه اتفاقی می‌افته.

نفر ۱: بانک اطلاعاتی ۱۰ رو گذاشته توی رم و یکی ازش کم میکنه و مقدار میشه ۹ و ذخیره می‌کنه.

نفر ۲: بانک اطلاعاتی ۱۰ رو گذاشته توی رم و یکی ازش کم میکنه و مقدار میشه ۹ و ذخیره می‌کنه.

وقتی انبار رو نگاه می‌کنی می‌بینی ۸ تا مداد داری ولی بانک اطلاعاتی میگه ۹ تا داری! اینجوریه که برنامه شما خطا میره  ☺😉🙃

راه‌حلش چیه؟! خب این مطلب می‌خواد همین رو بگه. برای حل این مشکل کافیه از یه F() expression هستش:

اول بیایید اون رو import کنید:

from django.db.models import F

F() به ما این قابلیت رو میده که قبل از ذخیره داده یا همون object.save() توی بانک اطلاعاتی، اون فیلد یا آبجکتی که می‌خوایم ذخیره بشه رو بروزرسانی کنیم. اینطوری دیگه مشکل Race Condition رو نداریم.

برای استفاده از این حالت می‌تونید توی تعریف View به صورت زیر کار بکنید:

reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()

reporter.name = 'Tintin Jr.'
reporter.save()

خیلی ساده و خوشمزه 😉

موسیقی این مطلب هم یک کار از نوازنده جَز Django Reinhardt:

چرا پایتون رو یاد بگیریم؟ 🐍

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

نمی‌خوام از علایق شخصی‌ بگم، بیشتر می‌خوام تکنیکی باشه.

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

بیایید یه مقایسه ساده بین نوشتن یه برنامه Hello World توی سی‌پلاس‌پلاس و پایتون رو ببینیم:

#include <iostream>
int main()
{
  std::cout << "Hello World!" << std::endl;
  return 0;
}

حالا همین برنامه رو می‌خوایم توی پایتون بنویسیم.

print ("Hello World!")

حالا این فقط یه ویژگی ساده از پایتونه، ولی باید بگم که پایتون یه جوری اعتیاد آوره🚬! یعنی اگه بتونی با پایتون کد بنویسی و باهاش حال بکنی، کم پیش می‌آد که وسوسه کدنویسی توی زبون‌های C-Style (شبیه سی) رو بکنید. من که به شخصه اینطوری شدم ولی خب یه راه حل‌م جبر بود. چون من سراغ جاوااسکریپت هم رفتم به یه سری دلایل!🧐🤪

 

جدای از ساده نویسی توی پایتون، شما این قابلیت رو هم دارید که با پایتون تقریبا هر کاری رو بکنید. می‌خواید وبسایت بسازید، می‌تونید! می‌خواید بازی بسازید، می‌تونید! می‌خواید دسکتاپ/موبایل بنویسید، می‌تونید. تقریبا میشه خیلی کارها باهاش کرد. وجود کتابخانه‌های بسیار زیاد پایتون این قابلیت رو بهتون می‌ده که هر کاری بکنید. حتی می‌تونید روی هوش مصنوعی و یادگیری ماشین هم کار کنید.

 

یه دلیل دیگه اینکه از پایتون خوشم میآد، اینه که من به ریاضی خیلی علاقه دارم. پایتون به شما خیلی توی حل کردن مسائل ریاضی کمک می‌کنه. یه کتابخونه به اسم Numpy داره که تقریبا میشه گفت خیلی خوبه :))😍 با این کتابخونه شما می‌تونید کارهای ریاضی مختلفی بکنید … همچنین از قابلیت‌هایی مثل آرایه و … هم استفاده بکنید.

 

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

 

پایتون یه آینده خوبی داره! من همیشه به این موضوع که هوش مصنوعی آینده تکنولوژي‌ها‌ست باور داشتم و دارم. وقتی که پایتون این قابلیت رو داره که با هوش مصنوعی ارتباط برقرار کنه و پیاده‌سازی‌ش بکنه، پس چرا یادش نگیریم! مثل اینه که میگن امروز دلار ۳ هزاره پس فردا میشه ۱۰ هزار … خب شما با ۲۰ میلیون تومن‌تون چیکار می‌کنید؟ میرید دلار می‌خرید دیگه 👀😉 –حالا مثال خیلی زیاد بود ولی خب انقدر همه جا بحث فقط شده دلار دلار دلار این مثال اومد تو ذهنم –

 

درک کردن برنامه‌نویسی با پایتون ساده است. همیشه توی دانشگاه‌ها و مراکز آموزشی با همه این درگیری رو داشتم که آقا شما به کسی که برنامه‌نویسی بلد نیست باید برنامه‌نویسی یاد بدی نه C# یا هر چیز دیگه‌ای. حتی در یک مرحله‌ای برنامه‌نویسی باید به صورت خیلی ساده تدریس بشه، مثلا با برنامه Scratch ولی با یه زبون اینترپرایس مثل سی‌شارپ به نظر نمی‌رسه که خیلی منطقی باشه. پایتون هم یه زبون ساده است. شما رو خیلی با سینتکس عجیب و غریبی همراه نمیکنه، پس شما شانس بیشتری در یادگیری دارید.

 

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

 

کار با بانک‌های اطلاعاتی SQL و NoSQL توی پایتون خیلی ساده است. پیکربندی عجیب و غریبی نمی‌خواد و تقریبا همه چی آماده‌س. پس یادگیری ادغام کردن دانش برنامه‌نویسی با SQL هم در پایتون ساده است.

 

پایتون رو میشه توی هر نرم افزار ویرایشگر کدی نوشت. این خوبه! بهتون آزادی میده. بعضیا ATOM دوست دارن، بعضیا میرن سراغ VIM بعضی دیگه Sublime Text و… . اینطوری خیلی بیشتر حال میده تا مجبور باشی حتما از یک IDE استفاده بکنی.

 

پایتون مزیت‌های بسیار زیاد دیگه‌ای داره که به نظر نمی‌رسه با فقط حرف زدن بهش رسید. باید امتحان‌ش کنید.

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

دم هممون گرم که انقدر باحالی‌م 😁🤓😎

شئ‌گرایی در پایتون به سادگیِ … (متدها و یه داستان جالب) ۲

خب گایز، ما تا اینجا یه کلاس ساختیم و یه سری خاصیت به کلاسمون دادیم. یه نمونه ساختیم و همین.
خب کلاس ها قرار نیستن که فقط یه سری ساختار داده‌ای باشن. منظورم اینه که قرار نیست فقط یه سری قالب داده‌ای رو نشون بدن، بگیم که فلانی تو کلاس اول منی باید اسم و … داشته باشی … نه قراره کلاسمون یه سری کارها هم بکنه. یعنی اینکه قراره کاربرد داشته باشه یا بهتره بگم تابع یا function … من هیچوقت تابع رو ترجمه خوبی نمی‌دونم ولی خب اینجوریاست دیگه … تابع خودش هم به این معناست که قراره یه کاری بکنه.

بزارید یه داستانی بگم براتون، اولین ترم سر کلاس برنامه‌نویسی بودیم که استاد قرار بود C درس بده مطابق با سرفصل ولی خب داشت C# و ASP MVC درس می‌داد … این در صورتی بود که هنوز نیمی از کلاس نمی‌فهمیدن اصلا کامپیوتر چیه … به هر حال یه سوالی برام پیش اومد و گفتم:
استاد ببخشید فرق متد و تابع چیه؟! در جواب گفتم هیچ فرقی ندارن 🙂

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

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

class Cat:
	def __init__(self, name, color):
		self.name = name
		self.color = color

	def callmebyname(self):
		a = input('Enter Cat Name: ')
		if self.name == a:
			print('Mue',a)
		else:
			print('We have no such cat')


cat1 = Cat('Arastoo', 'Brown')
cat1.callmebyname()

توی مثال بالا یه گربه داریم به اسم Arastoo که رنگش Brown هستش. وقتی یه تابع (درستش اینه بگیم متد) ما اجرا میشه، از ما یه ورودی می‌خواد.
به همین سادگی. البته باید بگم که این ورودی رو می‌تونستیم بجای اینکه مستقیم بگیریم بجاش به صورت یه آرگومان از تابع یا درستش اینه بگیم متد (مخاطبم استادمونه 🙂 ) دریافت کنیم. اینطوری می‌تونید به صورت پایین عمل کنید:

class Cat:
	def __init__(self, name, color):
		self.name = name
		self.color = color

	def callmebyname(self,a):
		#a = input('Enter Cat Name: ')
		if self.name == a:
			print('Mue',a)
		else:
			print('We have no such cat')


cat1 = Cat('Arastoo', 'Brown')
cat1.callmebyname('Arastoo')

یه چیز دیگه هم به صورت نکته بگم و تموم شه بره این قسمت هم. یه خطایی داریم به اسم AttributeError … در حقیقت این خطا زمانی اتفاق می‌افته که شما بخواید کاری رو بکنید یا مقداری رو بخواید که اون توی کلاس اصلی وجود نداره. مثلا اگه من بگم:
cat1.food
و برنامه رو اجرا کنم به من خطای AttributeError رو میده و میگه چنین خاصیت یا مقداری رو توی کلاس اصلی یعنی کلاس Cat نمی‌بینم. پس قضیه منتفیه!

موسیقی این مطلب هم تمومه چیزا از رادیو تهران

شئ‌گرایی در پایتون به سادگیِ … (کلاس) ۱

خب خوش اومدید به دوره آموزشی متنی شئ‌گرایی در پایتون به سادگیِ …؛ توی همین قسمت اول می‌خوایم یه ذره راجع به شئ‌گرایی به صورت بیسک و خیلی پایه بگم، چون واقعا وارد جزئیات شدن در رابطه با تئوریات شئ‌گرایی و اینکه دقیقا چه چیزهایی پشتش هست با توضیحات خیلی به دل نمی‌چسبه، حداقل برای من اینطوریه، به همین خاطر می‌خوام یه ذره اول کار ساده بهتون بگم که ماجرا چیه و بعدش بریم سراغ کدنویسی! پس امیدوارم کدنویسی خوبی داشته باشیم … خواستم بگم Good Coding نمی‌دونم چرا اینجوری شد!! به هر حال بریم سراغ مباحث!

 

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

 

خب نقطه کانونی شئ‌گرایی کلاس‌ها و آبجکت یا شئ‌ها هستند ولی خب اینا چی‌ان؟

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

برای ساخت کلاس ما از class استفاده می‌کنیم. بعدش یه اسم براش می‌زاریم که ترجیحا حرف اولش باید بزرگ باشه و بعدش بحث فاصله گذاری برای ایجاد بلاک کد! این یه مثال ساده است از این حالت:

class Cat:
	def __init__(self,name,color):
		self.name = name
		self.color = color

cat1 = Cat('kiti','brown')

توی کد بالا یه کلاس با نام Cat ایجاد کردیم و یه سری خاصیت به کلاسمون دادیم. مثلا اسم گربه و رنگ گربه.

حالا خب یه سری موارد عجیب و غریب دیگه هم وجود داره، مثل __init__ و self اینا چی‌ان! خب …

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

خب __init__ به چه دردی می‌خوره؟ توی زبون‌های دیگه بجای این می‌گن یه سازنده یا constractor می‌خوایم بسازیم. حالا این سازنده چیه؟

هر کلاسی برای خودش یه سری Attributes داره، در واقع یه سری داده است که یه کلاس باهاشون کار می‌کنه. برای مثال یه کلاس به اسم گربه داریم که ویژگی‌ها‌ش اسم و رنگشه، خب اینا به صورت __init__ قرار داده میشه.

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

نمونه چیه؟! خیلی پیچیده شد :))) می‌تونیم از کلاس‌ها‌مون نمونه بگیریم. یعنی چی؟ فکرش رو بکنید که می‌خوایم صد تا کتاب بنویسیم که همه این کتاب‌ها باید یه فونت مشخص برای عنوان‌شون داشته باشن، یه لایه‌بندی منحصر به فرد برای صفحه داشته باشن و… خب پس یه استایل کلی می‌نویسیم و می‌گیم تمام کتاب‌ها از این پیروی کنن، توی این حالت اون استایل کلی میشه class شما و اون کتاب‌های دیگه هر کدوم میشن یه نمونه از کلاس. حالا البته کتاب‌ها می‌تونن ویژگی‌های منحصر به فردی هم داشته باشن که راجع به اونا صحبت می‌کنیم.

برگردیم به مثال گربه … همه گربه‌ها یه اسم دارن و یه رنگ … خب پس به یه سری نمونه احتیاج داریم. در واقع self ارجاعی است به اون نمونه اصلی.

 

فعلا همین کافیه بحث متدها و… رو بزاریم برای بخش دومش!

موسیقی این مطلب هم خسرو خوبان از 127 بند