همه چی از uber شروع شد. ایدهی خوبی که رانندگان را به مسافران وصل میکرد و هر کسی هر جایی بود به سرعت میتوانست برای خودش تاکسی درخواست دهد. مدتی نگذشت که برنامهنویسهای داخل کشور عزیزمان هم از این سرویس ایده گرفتند و شروع به پیادهسازی مشابه آن در ایران کردند. در حال حاضر چندین سرویس درخواست آنلاین تاکسی وجود دارد که در تهران و چند شهر دیگر مشغول سرویسدهی به مسافرین هستند و روز به روز هم گسترش بیشتری مییابند و اشتغالزایی زیادی را نیز به وجود آوردهاند. حالا با توجه به بازار داغ این سرویس ما نیز میخواهیم یک سرویس مشابه ایجاد کنیم. اسمش را هم cabin
گذاشتهایم.
پروژه اولیه
پروژه اولیه را از این لینک دانلود کنید. ساختار این پروژه به شرح زیر است:
cabin 2
├─── manage.py
├─── requirements.txt
│
├─── cabin
│ ├─── admin.py
│ ├─── apps.py
│ ├─── models.py
│ ├─── > queries.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) های زیر را روی مدلهای بالا بنویسید.
حتما قبل شروع نوشتن کد، تذکرات انتهای سوال را بخوانید!
۱. کل مبلغ دریافتی توسط رانندهای با شناسهای برابر با x
- در این سوال status اهمیتی ندارد و نتیجه را میتوانید به شکل یک dict برگردانید.
{'payment_sum': value }
۲. لیست همه سفرهای یک مسافر با شناسه x
- ترتیب این لیست اهمیت ندارد.
۳. تعداد سفرهایی که طول آنها (از نظر زمانی) بیشتر از t بوده است.
- نتیجه این پرسوجو یک عدد است.
۴. لیست همه رانندههایی که در فاصله کمتر یا مساوی از r حول نقطه (x,y) قرار دارند و فعال (آماده به کار) نیز هستند.
- ترتیب این لیست اهمیت ندارد.
۵. لیست رانندگانی که یک ماشین کلاس A یا یک ماشین با رنگ c دارند و حداقل n سفر انجام دادهاند.
- ترتیب این لیست اهمیت ندارد.
۶. لیست مسافرانی که x سفر یا بیشتر داشتهاند و در مجموع بیشتر از t تومان پرداخت کردهاند.
- ترتیب این لیست اهمیت ندارد.
۷. لیست رانندگانی که حداقل یک سفر داشتهاند که در آن سفر اسم راننده با اسم مسافر یکسان بوده است.
- ترتیب این لیست اهمیت ندارد.
- در این لیست نباید رانندهی تکراری وجود داشته باشد.
۸. لیست همه رانندهها و یک ستون دیگر با نام n
که نشاندهندهی تعداد سفرهایی است که در آنها نام خانوادگی راننده با نام خانوادگی مسافر یکسان بوده است.
n
که نشاندهندهی تعداد سفرهایی است که در آنها نام خانوادگی راننده با نام خانوادگی مسافر یکسان بوده است.- ترتیب این لیست اهمیت ندارد.
۹. لیست همه رانندهها به همراه یک ستون دیگر به نام n
که تعداد سفرهاییست که در آن سفرها ماشین، مدل x یا به بالا (توجه کنید که مدل با نوع متفاوت است!) بوده است و طول سفر بیشتر از t ثانیه بوده است.
n
که تعداد سفرهاییست که در آن سفرها ماشین، مدل x یا به بالا (توجه کنید که مدل با نوع متفاوت است!) بوده است و طول سفر بیشتر از t ثانیه بوده است.خروجی نمونه:
<QuerySet [{'id': 1, 'n': 8}, {'id': 2, 'n': 1},....]>
- ترتیب این لیست اهمیت ندارد.
- طول این لیست به تعداد همه رانندهها است که در هر عنصر آن id راننده و n (با تعریف بالا) قرار دارد.
۱۰. لیست همه ماشینها و یک ستون اضافه شده به آن به نام extra
extra
مقدار extra
از نوع عدد صحیح است و با توجه به نوع ماشین (car_type
) به شرح زیر تعریف میشود:
- اگر نوع ماشین
A
بود تعداد سفرهای انجامشده با آن ماشین در ستونextra
قرار میگیرد. - اگر نوع ماشین
B
بود مجموع طول سفرهای انجامشده با آن ماشین در ستونextra
قرار میگیرد. - اگر نوع ماشین
C
بود مجموع مبلغ سفرهای انجامشده با آن ماشین در ستونextra
قرار میگیرد.
زیرمسئلهها
امتیاز | بخش |
---|---|
۱۰ | query_1 |
۱۰ | query_2 |
۱۰ | query_3 |
۱۰ | query_4 |
۱۰ | query_5 |
۱۰ | query_6 |
۱۰ | query_7 |
۱۰ | query_8 |
۱۰ | query_9 |
۱۰ | query_10 |
امکانات اضافه
در صورتی که علاقمندید که خودتان به صورت دستی کوئریهای خود را امتحان کنید و از درستی آنها اطمینان حاصل کنید، یا اینکه به بررسی بیشتر از این تمرین بپردازید، برای راحتی بیشتر شما، فایلهای مایگریشنها ساخته شدهاند و شما کافیست جهت ایجاد پایگاهداده، یک بار دستور migrate
را اجرا کنید.
علاوهبر این، یک سری دادهی از پیش آماده شده، فراهم شده که بعد از اجرای دستور migrate
، میتوانید آنها را وارد پایگاهدادهی پروژهی خود کنید. به این منظور، دستور زیر را اجرا کنید. میتوانید از این دادهها به جهت تست کردن کوئریهای خود استفاده کنید.
۱. ایجاد پایگاهداده
python manage.py migrate
۲. وارد کردن دادههای از پیش آماده شده (fixture)
python manage.py loaddata cabin/fixtures/sample_test_fixture.json
python manage.py loaddata cabin/fixtures/test_fixtures.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 اهمیتی ندارد.
ارسال پاسخ برای این سؤال