همه چی از uber شروع شد. ایدهی خوبی که رانندگان را به مسافران وصل میکرد و هر کسی هر جایی بود به سرعت میتوانست برای خودش تاکسی درخواست دهد. مدتی نگذشت که برنامهنویسهای داخل کشور عزیزمان هم از این سرویس ایده گرفتند و شروع به پیادهسازی مشابه آن در ایران کردند. در حال حاضر چندین سرویس درخواست آنلاین تاکسی وجود دارد که در تهران و چند شهر دیگر مشغول سرویسدهی به مسافرین هستند و روز به روز هم گسترش بیشتری مییابند و اشتغالزایی زیادی را نیز به وجود آوردهاند. حالا با توجه به بازار داغ این سرویس ما نیز میخواهیم یک سرویس مشابه ایجاد کنیم. اسمش را هم cabin
گذاشتهایم.
پروژه اولیه
پروژه اولیه را از این لینک دانلود کنید. ساختار این پروژه به شرح زیر است:
cabin
├─── manage.py
├─── requirements.txt
│
├─── cabin
│ ├─── admin.py
│ ├─── apps.py
│ ├─── models.py
│ ├─── > queries.py <
│ ├─── tests.py
│ ├─── urls.py
│ ├─── views.py
│ ├─── __init__.py
│ │
│ ├─── fixtures
│ │ └─── sample_test_fixture.json
│ │
│ └─── migrations
│ ├── 0001_initial.py
│ └─── __init__.py
│
├───challenge
│ ├─── settings.py
│ ├─── urls.py
│ ├─── wsgi.py
│ └─── __init__.py
│
└───tests
├─── testsample.py
└─── __init__.py
همانطور که در فایلها میبینید یک app به نام cabin وجود دارد. در فایل models.py
هشت مدل به شرح زیر وجود دارند:
مدل Account
(حساب کاربری)
Account
(حساب کاربری)حساب کاربریای که به یک مدل دیگر اعم از راننده یا مسافر یا مدیر سیستم وصل است و شامل فیلد های زیر است:
first_name
: نام شخصlast_name
: نام خانوادگی شخصemail
: ایمیل شخصphone
: شماره تلفن شخصpassword
: پسورد شخص
مدل Admin
(مدیر)
Admin
(مدیر)مدیر سیستم که دسترسیهای خاصی به سیستم دارد و شامل فیلد زیر است:
account
: اکانت ادمین که اطلاعات او را نگه میدارد.
مدل Rider
(مسافر)
Rider
(مسافر)شامل فیلدهای زیر است:
account
: اکانت مسافر که اطلاعات او را نگه میدارد.x
: طول جغرافیایی موقعیت مسافرy
: عرض جغرافیایی موقعیت مسافرrating
: امتیاز مسافر
مدل Driver
(راننده)
Driver
(راننده)شامل فیلدهای زیر است:
account
: اکانت راننده که اطلاعات او را نگه میدارد.x
: طول جغرافیایی موقعیت رانندهy
: عرض جغرافیایی موقعیت رانندهrating
: امتیاز رانندهactive
: آماده به کار بودن یا نبودن راننده را نشان میدهد.
مدل Car
(خودرو)
Car
(خودرو)شامل فیلدهای زیر است:
owner
: صاحب خودرو که یک راننده (از جنس مدلDriver
) است.car_type
: نوع کلاس خودروmodel
: سال تولید خودروcolor
: رنگ خودرو
مدل RideRequest
(درخواست سفر)
RideRequest
(درخواست سفر)شامل فیلدهای زیر است:
rider
: مسافر درخواستدهندهx
: طول جغرافیایی نقطه درخواستy
: عرض جغرافیایی نقطه درخواستcar_type
: کلاس خودرو درخواستشده
مدل Ride
(سفر)
Ride
(سفر)شامل فیلدهای زیر است:
pickup_time:
(زمان شروع سفر(سوار کردن مسافرdropoff_time
: زمان پایان سفر- دو زمان بالا از نوع عدد صحیح و نشاندهنده تعداد ثانیه های گذشته از زمان تاسیس شرکت می باشند.
request
: درخواست سفری که این سفر به آن مربوط میشودcar
: خودرویی که این سفر با آن انجام شده استrider_rating
: امتیازی که راننده به مسافر داده استdriver_rating
: امتیازی که مسافر به راننده داده است
مدل Payment
(پرداخت)
Payment
(پرداخت)شامل فیلدهای زیر است:
ride
: سفری که پرداخت برای آن انجام شده است.amount
: مبلغ پرداختشده برحسب تومانstatus
: وضعیت پرداخت
حال از شما میخواهیم پرسوجو (query) های زیر را روی مدلهای بالا بنویسید.
حتما قبل شروع نوشتن کد، تذکرات انتهای سوال را بخوانید!
۱. ورودی کل شرکت کابین (پولی که از طریق پرداخت وارد شرکت میشود)
- در اینجا status تاثیری ندارد و نتیجه را میتوانید به صورت dict برگردانید.
{'income': value }
۲. کل مبلغ پرداختشده توسط مشتری با id
برابر با x
id
برابر با x
{'payment_sum': value }
۳. تعداد رانندههایی که حداقل یک ماشین کلاس A
دارند.
A
دارند.- در این سوال باید
.count()
از QuerySet مربوطه را بازگرانید که نتیجه یک عدد خواهد بود.
۴. لیست درخواستهای سفرِ در انتظار (یعنی درخواستهایی که به هیچ سفری وصل نباشد)
- ترتیب این لیست اهمیت ندارد.
۵. لیست مسافرانی که مجموع مبلغ سفرهایشان بیشتر یا مساوی با t
تومان است.
t
تومان است.- ترتیب این لیست اهمیت ندارد.
۶. اکانتِ رانندهای که بیشترین تعداد ماشین را دارد. اگر تعداد ماشینها یکسان بود، رانندهای را بدهید که نام خانوادگیاش از نظر الفبایی کوچکتر است.
- در این سوال باید یک شیء از نوع Account بازگرانید که نتیجه مانند زیر خواهد بود:
<Account: Account object>
۷. لیست همه مسافرانی که حداقل یک سفر با ماشین کلاس A
داشتهاند به همراه یک ستون اضافه با نام n
که تعداد سفرهایی که هر مسافر با ماشین کلاس A
داشته است را نشان میدهد.
A
داشتهاند به همراه یک ستون اضافه با نام n
که تعداد سفرهایی که هر مسافر با ماشین کلاس A
داشته است را نشان میدهد.- ترتیب این لیست اهمیت ندارد.
۸. لیست ایمیل رانندگانی که حداقل یک ماشین با مدل x
(توجه کنید که مدل با نوع متفاوت است!) یا به بالا دارند.
x
(توجه کنید که مدل با نوع متفاوت است!) یا به بالا دارند.- ترتیب این لیست اهمیت ندارد.
- خروجی نمونه:
<QuerySet [{'account__email': 'linda180@gmail.com'}, {'account__email': 'jacqueline859@gmail.com'}, {'account__email': 'benjamin780@gmail.com'},.....]>
۹. لیست همه رانندهها و یک ستون اضافه شده به آن به نام n
که نشاندهنده تعداد سفرهای هر راننده است.
n
که نشاندهنده تعداد سفرهای هر راننده است.- ترتیب این لیست اهمیت ندارد.
۱۰. لیست اسمهای کوچک همه رانندهها و تعداد سفرهایی (n
) که راننده با آن آسم انجام داده است.
n
) که راننده با آن آسم انجام داده است.- بعضی رانندهها اسمهای یکسانی دارند.
- برای مثال اگر دو راننده مختلف با اسم jack وجود داشته باشند که هر کدام ۵ سفر انجام دادهباشند، در لیست زیر فقط یک بار اسم jack با ۱۰ سفر میآید.
- ترتیب این لیست اهمیت ندارد.
- خروجی نمونه:
<QuerySet [{'n': 41, 'account__first_name': 'aaron'}, {'n': 44, 'account__first_name': 'adam'}, {'n': 19, 'account__first_name': 'alan'},.....]>
۱۱. لیست رانندگانی که حداقل یک ماشین با رنگ c
(مثلا White) که مدلِ همان ماشین، n
(مثلا ۹۰) یا به بالا باشد (توجه کنید که مدل با نوع متفاوت است!)، دارند.
c
(مثلا White) که مدلِ همان ماشین، n
(مثلا ۹۰) یا به بالا باشد (توجه کنید که مدل با نوع متفاوت است!)، دارند.- در این لیست نباید رانندهی تکراری وجود داشته باشد.
- ترتیب این لیست اهمیت ندارد.
۱۲. لیست رانندگانی که حداقل یک ماشین با رنگ c
و یک ماشین مدل n
یا به بالا (توجه کنید که مدل با نوع متفاوت است!) دارند.
c
و یک ماشین مدل n
یا به بالا (توجه کنید که مدل با نوع متفاوت است!) دارند.- در این لیست نباید رانندهی تکراری وجود داشته باشد.
- لزوما این دو ماشین یکسان نیست. ولی برای رنگ و مدل باید حداقل یک ماشین با شرایط گفتهشده برای هر کدام وجود داشته باشد.
- ترتیب این لیست اهمیت ندارد.
۱۳. مجموع طول سفرهایی که در آن اسم راننده n
(مثلا jack) و اسم مسافر m
بوده است.
n
(مثلا jack) و اسم مسافر m
بوده است.{'sum_duration': value }
زیرمسئلهها
امتیاز | بخش |
---|---|
۵ | query_1 |
۵ | query_2 |
۵ | query_3 |
۵ | query_4 |
۵ | query_5 |
۵ | query_6 |
۱۰ | query_7 |
۱۰ | query_8 |
۱۰ | query_9 |
۱۰ | query_10 |
۱۰ | query_11 |
۱۰ | query_12 |
۱۰ | query_13 |
امکانات اضافه
در صورتی که علاقمندید که خودتان به صورت دستی کوئریهای خود را امتحان کنید و از درستی آنها اطمینان حاصل کنید، یا اینکه به بررسی بیشتر از این تمرین بپردازید، برای راحتی بیشتر شما، فایلهای مایگریشنها ساخته شدهاند و شما کافیست جهت ایجاد پایگاهداده، یک بار دستور migrate
را اجرا کنید.
علاوهبر این، یک سری دادهی از پیش آماده شده، فراهم شده که بعد از اجرای دستور migrate
، میتوانید آنها را وارد پایگاهدادهی پروژهی خود کنید. به این منظور، دستور زیر را اجرا کنید. میتوانید از این دادهها به جهت تست کردن کوئریهای خود استفاده کنید.
۱. ایجاد پایگاهداده
python manage.py migrate
۲. وارد کردن دادههای از پیش آماده شده (fixture)
python manage.py loaddata cabin/fixtures/sample_test_fixture.json
در صورتی که علاقمند به تست نیستید، نیازی به ایجاد پایگاهداده و وارد کردن دادههای آزمایشی نیست، و تنها کافیست که در فایل queries.py
کوئریهای خود را بنویسید و از کوئرا جهت امتحان کردن درستی کوئریهایتان استفاده کنید.
تست نمونه
در فایلهای اولیهای که دانلود کردید یکسری داده اولیه به عنوان نمونه قرار داده شده است. همچنین ۳ تست نمونه برای ۳ پرسوجو اول بر اساس دادههای اولیه قرار داده شده است که میتوانید قبل از فرستادن سوال در سایت، این تستها را ببینید تا با نحوه داوری ما آشنا شوید و از پاسخ خود اطمینان حاصل نمایید.
تستها را میتوانید با دستور زیر اجرا کنید:
python manage.py test
نکات
- یک فایل به نام
queries.py
وجود دارد که برای هر سوال یک تابع در نظر گرفته شده است. شما باید کدهای خود را در این فایل بنویسید و QuerySet مربوطه را بازگردانید. - برای نمونه تابع
query_0
در پاسخ به پرس و جویِ «لیست همهی رانندگانی که رتبهی آنها بیشتر از x است.» کامل شده است که شما نیز باید مشابه همین تابع بقیه توابع را کامل کنید.
def query_0(x):
q = Driver.objects.filter(rating__gt=x)
return q
- در سوالاتی که در صورت سوال مقداری به صورت متغیر ذکر شده است (مانند x در مثال بالا)، متغیر مورد نظر در آرگومانهای ورودی تابع درنظر گرفته شده است. شما خود نباید آرگومانهای ورودی تابع را تغییر دهید.
- در تمام سوالات به جز سوالاتی که خروجی نمونه برای آنها مشخص شده است، همانطور که ذکر شد، خروجی شما یک شئ از نوع
QuerySet
با المانهایی از جنس گفتهشده در اول سوال باید باشد. یعنی در واقع خود query را return کنید. - برای مثال اگر سوال گفته باشد «لیست ماشین هایی که....» خروجی شما به شکل زیر باید باشد:
<QuerySet [<Car: Car object>, <Car: Car object>,.....]>
- در سوالات دیگر نیز که خروجی مشخص شده است، باز نتیجه یک
QuerySet
است ولی شامل همه فیلدهای مدل مورد نظر نمیشود و فقط فیلدهای خواستهشده با نام خواستهشده باید در آن قرار داشته باشد. - شما تنها مجوز ایجاد تغییرات در فایل
cabin/queries.py
را دارید و تمامی تغییرات دیگر شما در فایلهای پروژه نادیده گرفته خواهند شد. - فراموش نکنید که میتوانید با مطالعهی
testsample.py
با روش تست کردن کوئریها آشنا شوید.
نحوه ارسال
یک فایل ZIP حاوی همهی فایلهای پروژه، آپلود کنید. نام فایل ZIP اهمیتی ندارد.
ارسال پاسخ برای این سؤال