پایتون - ام‌تایی‌ها


سجاد یک لیست nn تایی از اعداد دارد و در گروه‌های مختلف آن را تقسیم‌بندی می‌کند؛ به این صورت که mm عضو اول را در یگ گروه قرار می‌دهد، mm عضو بعدی را در یک گروه و به همین ترتیب اعضا را گروه بندی می‌کند (دقت کنید که گروه آخر ممکن است کمتر از mm عضو داشته باشد).

سجاد از روی این اعداد، یک لیست جدید می‌سازد که عضو iiام آن، جمع اعضای گروه iiام باشد.

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

مثال محاسبه ارزش لیست

به طور مثال اگر سجاد لیست زیر را داشته باشد و مقدار mm برابر با ۳ باشد:

[1,2,3,4,5,6,7,8][1, 2, 3, 4, 5, 6, 7, 8]

آنگاه لیست جدید به صورت زیر می‌شود:

[6,15,15][6, 15, 15]

بعد از آن سجاد اعداد لیست را به صورت شطرنجی جمع می‌کند و ارزش لیست برابر با عبارت زیر می‌شود:

615+15=66 - 15 + 15 = 6

بنابراین عدد نهایی سجاد برابر با ۶ می‌شود. هم‌چنین اگر مقدار mm در این سوال برابر با یک بود ارزش نهایی برابر با عبارت زیر می‌شود:

12+34+56+78=41 - 2 + 3 - 4 + 5 - 6 + 7 - 8 = -4

در این سوال شما باید تابع ‍‍calculator(n, m, li) را پیاده‌سازی کنید که به ترتیب nn (تعداد اعضای لیست)، و mm (تعداد اعضای هر گروه) و خود لیست را ورودی بگیرد و ارزش نهایی لیست را بر‌گرداند.

پروژه اولیه🔗

پروژه اولیه را از این لینک دانلود کنید. شما باید تابع ‍‍calculator را در این فایل کامل کنید.

مثال🔗

>>> calculator(8, 3, [1, 2, 3, 4, 5, 6, 7, 8])
6
>>> calculator(8, 1, [1, 2, 3, 4, 5, 6, 7, 8])
-4
Python

آن‌چه باید آپلود کنید🔗

یک فایل پایتون که تابع calculator در آن پیاده‌سازی شده است را آپلود کنید.

پایتون - فاکتوریسم


در این سوال شما باید یک کلاس مدیریت فاکتورهای فروش برای شرکت سجادینه طراحی کنید. در شرکت سجادینه افراد زیادی می‌توانند فاکتورهای مالی را ثبت کنند و هر کدام از این افراد تاریخ فاکتور را به یکی از ۶ فرمتی که در جدول پایین آمده ثبت می‌کنند.

برای مثال یک فاکتور که روز دوم ماه ششم سال ۲۰۲۰ ثبت شود، می‌تواند طبق یکی از فرمت‌های زیر ثبت شود:

زمانی که در سیستم ثبت می‌شود فرمت زمان
‍‍02/06/2020 dd/mm/yyyy‍
‍‍02/2020/06 dd/yyyy‍/mm
‍‍2020/06/02 yyyy‍/mm/dd
‍‍2020/02/06 yyyy‍/dd/mm
‍‍ 06/2020/02 mm/yyyy‍/dd
‍‍ 06/02/2020 mm/dd/yyyy‍

پروژه اولیه🔗

پروژه اولیه را از این لینک دانلود کنید. شما باید کلاس ‍‍FactorHandler را در این فایل کامل کنید به طوری که سه تابع زیر عملکردهای خواسته شده را داشته باشند.

تابع add_factor

این تابع به ترتیب سه ورودی time_format و time و value را ورودی می‌گیرد. مقدار time_format یکی از ۶ رشته جدول بالا است و time تاریخ ثبت فاکتور بر حسب فرمت داده شده است. مقدار value هم، هزینه فروش فاکتور داده شده برای آن تاریخ را مشخص می‌کند.

تابع remove_all_factors

این تابع به ترتیب سه ورودی time_format و time را ورودی می‌گیرد که هر دویشان مانند تابع add_factor هستند؛ این تابع تمام فاکتورهایی که در تاریخ داده شده ثبت شده‌اند را از لیست فاکتورها حذف می‌کند.

تابع get_sum

این تابع به ترتیب سه ورودی time_format و start_time و finish_time را ورودی می‌گیرد و جمع هزینه فاکتورهایی که از تاریخ ‍‍start_time تا finish_time ثبت‌شده‌اند (شامل خود این دو تاریخ) را برمی‌گرداند.

در همه توابع تضمین می‌شود که time حتما بر حسب فرمت time_format است. توجه کنید که هیچ یک از توابع بالا را نباید استاتیک تعریف کنید.

مثال🔗

>>> fh = FactorHandler()
>>> fh.add_factor("dd/mm/yyyy", "02/10/2019", 10)
>>> fh.add_factor("dd/mm/yyyy", "03/10/2019", 20)
>>> fh.add_factor("dd/mm/yyyy", "03/10/2019", 30)
>>> fh.add_factor("dd/mm/yyyy", "05/10/2019", 5)
>>> fh.get_sum("yyyy/dd/mm", "2019/02/10", "2019/03/10")
60
>>> fh.remove_all_factors("mm/dd/yyyy", "10/03/2019")
>>> fh.get_sum("yyyy/dd/mm", "2019/02/10", "2019/05/10")
15
Python

آن‌چه باید آپلود کنید🔗

یک فایل پایتون که کلاس FactorHandler در آن پیاده‌سازی شده است را آپلود کنید.

پایتون - قانون‌شکن


در شهر انگوتستان داده‌ها تنها به وسیله‌ی JSON منتقل می‌شود. برای نمایش داده‌‌ی یک جدول در این شهر، به ازای هر سطر، یک فایل JSON ذخیره‌ می‌شود؛ در فایل JSON مربوط به هر سطر، به ازای هر ستون، شماره ستون به عنوان key و مقدار موجود در آن سطر و ستون، به عنوان value ذخیره می‌شود.

مثال ذخیره جدول به صورت JSON

برای مثال جدول زیر را در نظر بگیرید:

ستون اول ستون دوم‌ ستون سوم
۳ ۱ ۴
۱ ۳ ۱۳
‌ ۱ ۲ ۳

این جدول در شهر انگوتستان به شکل سه فایل JSON ذخیره می‌شود، فایل مربوط به هر سطر، به ترتیب به شکل زیر می‌شود:

{"1": "3", "2": "1", "3": "4"}
JSON
{"1": "1", "2": "3", "3": "13"}
JSON
{"1": "1", "2": "2", "3": "3"}
JSON

سجاد که از اهالی قانون‌شکن شهر انگوتستان می‌باشد می‌خواهد برعکس کارهای بالا را انجام دهد و با گرفتن تمامی فایل‌های‌ ‍‍JSON مربوط به یک جدول، آن را به صورت یک فایل CSV نمایش دهد. او برای این کار، دقیقا برعکس کارهای بالا را انجام می‌دهد؛ البته چون فقط می‌خواهد جدول را ذخیره کند از index و header در CSV استفاده نمی‌کند.

اما او هر جدولی را دوست ندارد و برای این که جدول بهتر شود؛ ابتدا مقادیر مربوط به هر سطر را از کوچک به بزرگ مرتب ‌می‌کند؛ سپس سطر iiام را i1i - 1 بار شیفت دوری می‌دهد (یعنی سطر اول هیچ تغییری نمی‌کند)؛ در واقع خانه موجود در سطر iiام و ستون jj ام مقدار خانه سطر ii و ستون (i+j1)modn(i+j - 1) \mod n را به خود می‌گیرد (اگر مقدار عبارت گفته شده برابر با صفر بود، nn در نظر گرفته می‌شود).

مثال عملیات روی جدول

برای مثال جدول زیر را در نظر بگیرید:

ستون اول ستون دوم‌ ستون سوم‌
۳ ۱ ۴
۱ ۳ ۱۳
‌ ۱ ۲ ۳

اگر سطرهای این جدول را مرتب کنیم به صورت زیر درمی‌آید:

ستون اول ستون دوم‌ ستون سوم
۱ ۳ ۴
۱ ۳ ۱۳
‌ ۱ ۲ ۳

حال اگر هر سطر را با توجه به روش داده شده تغییر دهیم سطر اول تغییری نمی‌کند؛ ولی سطر دوم، یک شیفت به سمت راست می‌خود و سطر سوم دو شیفت به سمت راست می‌خورد و جدول نهایی به شکل زیر درمی‌آید:

ستون اول ستون دوم‌ ستون سوم
۱ ۳ ۴
۳ ‍۱۳ ۱
۳ ۱ ۲

بررسی دقیق‌تر:

inputs:
3 1 4
1 3 13
1 2 3
-----------------
sort:
1 3 4
1 3 13
1 2 3
---------------
rotate:
1 3 4  (no rotation)
3 13 1 (one left rotation)
3 1 2 (two left rotation)
Plain text

حال سجاد از شما می‌خواهد برایش یک تابع به نام process بنویسید که به عنوان ورودی یک لیست از نام فایل‌های JSON بگیرد (دقت کنید که فایل‌های JSON در این لیست به ترتیب هستند؛ یعنی فایل مربوط به سطر ii در جایگاه i1i-1 در لیست وجود دارد)، و جدول نهایی را در فایلی به نام ans.csv ذخیره کند.

تضمین می‌شود که جدول ورودی داده شده مربعی است و در آن اعداد صحیح قرار دارد.

پروژه اولیه🔗

پروژه اولیه را از این لینک دانلود کنید. شما باید تابع ‍‍process در فایل ‍‍solution.py را کامل کنید.

مثال🔗

اگر در کنار فایل solution.py فایل‌های JSON پروژه اولیه وجود داشته باشد، باید خروجی زیر از تابع گرفته شود:

>>> from solution import process
>>> process(['sample1.json', 'sample2.json'])
>>> with open('ans.csv', 'r') as f:
...     print(f.readlines())
... 
['1,3\n', '3,1\n']
Python

نکات🔗

  • دقت کنید که در جداول مثال، ستون اول، به علت فارسی بودن، سمت راست جدول است و اگر CSV را به طور عادی باز کنید باید ترتیب ستون‌های جدول برعکس شود و ستون اون در سمت چپ قرار گیرد.
  • توجه کنید که مقادیر را باید به صورت عددی مرتب کنید؛ یعنی عدد ۲ از عدد ۱۷ کوچک‌تر است (یعنی باید اعداد را هنگام خواندن از فایل به int تبدیل کنید).

آن‌چه باید آپلود کنید🔗

فایل کامل شده solution.py را ارسال کنید؛ همچنین برای استفاده از کتابخانه‌های مختلف می‌توانید همراه فایل ارسالی، فایلی به نام python_requirements.txt در ZIP خود بگذارید که در آن نام کتاب‌خانه‌های مورد نیاز و شماره نسخه‌ی آن‌ها به فرمت زیر در آن موجود باشد: (اگر شماره نسخه را ننویسید آخرین نسخه‌ی آن کتابخانه نصب می‌شود)

firstlib==1.2.3
secondlib==4.5.6
...
Plain text

در نهایت یک فایل ZIP حاوی دو فایل خواسته شده را آپلود کنید.

جنگو - جیتسی


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

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

از شما می‌خواهیم ویوهای این وبسایت را با توجه به ساختار پروژه برای ما طراحی کنید.

پروژه اولیه🔗

پروژه اولیه را از این لینک دانلود کنید. ساختار فایل‌های این پروژه به صورت زیر است.

مدل‌ها - پیاده‌سازی شده است

مدل Team🔗

این مدل نشان‌دهنده‌ی تیم‌ها می‌باشد.

هر تیم شامل دو فیلد زیر می‌باشد:

  • فیلد name: که از نوع CharField می‌باشد و نشان‌دهنده‌ی نام تیم است.
  • فیلد jitsi_url_path: که از نوع CharField می‌باشد و نشان‌دهنده‌ لینک اختصاصی جیتسی برای آن تیم می‌باشد.

مدل Account🔗

این مدل از مدل User ارث‌بری می‌کند و دارای یک فیلد اضافه بر User می‌باشد:

  • فیلد team: که از نوع foreignkey می‌باشد و نشان‌دهنده‌ی شیء تیم مربوط به این فرد می‌باشد.

فرم‌ها - پیاده‌سازی شده است

فرم SignUpForm🔗

از این فرم باید در قسمت ثبت‌نام افراد در سایت استفاده شود.

فرم TeamForm🔗

از این فرم باید برای اضافه کردن یک تیم و یا اضافه شدن به یک تیم استفاده شود.

فرم LoginForm🔗

از این فرم باید برای وارد شدن کاربر به سایت استفاده شود.

ویو‌ها - توسط شما پیاده‌سازی شود

ویو home🔗

به این ویو فقط می‌توان ریکوئست Get زد و این ویو برای این نوع ریکوئست باید نام تیم کاربر را نشان دهد.

اگر کاربری که به این ویو ریکوئست می‌زند دارای تیم بود، صفحه‌ی home.html را طوری نمایش دهید که در این صفحه، نام تیم این کاربر به نمایش دربیاید.

اگر کاربری که به این ویو ریکوئست می‌زند تیمی نداشت، صفحه‌ی home.html را طوری نمایش دهید که در این صفحه‌، کلمه‌ی None به نمایش دربیاید.

ویو signup🔗

به این ویو می‌توان دو نوع ریکوئست Get و Post زد و کار این ویو ثبت‌نام کردن کاربر در سایت می‌باشد.

اگر نوع ریکوئست کاربر Get باشد؛ صفحه‌ی signup.html را طوری به کاربر نمایش دهید که در این صفحه فرم SignUpForm برای کاربر به نمایش دربیاید.

اگر نوع ریکوئست کاربر Post باشد؛ بعد از انجام اعتبارسنجی داده‌های وارد شده در فرم،‌ اگر فرم به درستی پر شده بود کاربر را در دیتابیس ذخیره کرده و در سایت login‍ کنید و کاربر را به آدرس team بفرستید؛ اگر هم فرم اشتباه پر شده بود کاربر را دوباره به صفحه signup بازگردانید.

ویو login_account🔗

به این ویو می‌توان دو نوع ریکوئست Get و Post زد و کار این ویو وارد کردن کاربر به سایت می‌باشد.

اگر نوع ریکوئست کاربر Get باشد؛ صفحه‌ی login.html را طوری به او نمایش دهید که فرم LoginForm به نمایش دربیاید.

اگر نوع ریکوئست کاربر Post باشد؛ بعد از اعتبارسنجی فرم، اگر کاربر فرم را درست پر کرده بود، بررسی کنید که کاربری با اطلاعات پر شده وجود داشته باشد و اگر وجود داشت کاربر را login کنید و او را به صفحه‌ی home بفرستید؛ در غیر این صورت او را دوباره به صفحه‌ی login بازگردانید.

ویو logout_account🔗

به این ویو فقط می‌توان ریکوئست Get زد و کار این ویو خارج کردن کاربر از حساب کاربری خود می‌باشد.

اگر کاربر به این ویو ریکوئست Get زد او را از حساب کاربری خود بیرون کنید و به صفحه‌ی login منتقل کنید.

ویو joinoradd_team🔗

به این ویو می‌توان دو نوع ریکوئست Get و Post زد.

اگر نوع ریکوئست کاربر Get باشد؛ بررسی کنید کاربر در حال حاضر دارای تیم می‌باشد یا خیر.

اگر کاربر تیمی داشت او را به صفحه‌ی home منتقل کنید وگرنه او را طوری به صفحه‌ی team.html منتقل کنید که فرم TeamForm به او نمایش داده شود.

اگر نوع ریکوئست کاربر Post باشد؛ بعد از اعتبارسنجی فرم اگر کاربر فرم را درست پر کرده بود بررسی کنید اگر تیمی با این نام وجود داشت فیلد team کاربر را برابر با این تیم قرار دهید؛ و اگر وجود نداشت یک تیم با این نام بسازید. فیلد jitsi_url_path این تیم به صورت ‍‍http://meet.jit.si/team_name قرار گیرد که جای team_name نام تیم قرار می‌گیرد. بعد از ساخت تیم فیلد team کاربر را برابر با این تیم قرار دهید و کاربر را به صفحه‌ی home انتقال دهید.

اگر هم فرم درست پر نشده بود کاربر را به صفحه home انتقال دهید.

ویو exit_team🔗

به این ویو فقط می‌توان ریکوئست Get زد و کار این ویو خارج کردن کاربر از تیم حال حاضر آن می‌باشد.

اگر کاربر به این ویو ریکوئست Get زد فیلد team کاربر را برابر با None قرار دهید و او را به صفحه‌ی home منتقل کنید. اگر هم کاربر از قبل تیمی نداشت صرفا او را به صفحه‌ی home منتقل کنید.

نکات🔗

  • دقت کنید که تمامی ریدایرکت‌ها را با استفاده از تابع redirect انجام دهید.

آن‌چه باید آپلود کنید🔗

یک فایل ZIP شامل پروژه جنگو خود آپلود کنید؛ توجه کنید که فقط می‌توانید فایل‌ ‍‍account/views.py را تغییر دهید.

جنگو - بورس و کرونا


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

شما باید به مدیر شرکت ع.ش کمک کنید تا با کمترین هزینه و با کمک دانش ملی و بومی! جلوی حملات این خرابکاران را بگیرد.

پروژه اولیه🔗

پروژه اولیه را از این لینک دانلود کنید. ساختار فایل‌های این پروژه به صورت زیر است:

ساختار فایل‌ها
boors-va-corona
├── apps
│   ├── guard
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── __init__.py
│   │   ├── management
│   │   │   ├── commands
│   │   │   │   ├── init_guard.py
│   │   │   │   └── __init__.py
│   │   │   └── __init__.py
│   │   ├── middlewares.py
│   │   ├── migrations
│   │   ├── models.py
│   │   ├── urls.py
│   │   ├── utils.py
│   │   └── views.py
│   ├── __init__.py
│   └── market
│       ├── admin.py
│       ├── apps.py
│       ├── __init__.py
│       ├── migrations
│       │   └── __init__.py
│       ├── models.py
│       ├── tests.py
│       ├── urls.py
│       └── views.py
├── codecup
│   ├── asgi.py
│   ├── __init__.py
│   ├── settings
│   │   ├── base.py
│   │   ├── development.py
│   │   ├── __init__.py
│   │   └── production.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── codecupdb.sqlite3
├── deploy
│   └── nginx
│       └── default.conf
├── docker-compose.yml
├── Dockerfile
├── manage.py
├── README.md
└── requirements.txt
Plain text
راه‌اندازی پروژه

برای اجرای پروژه ابتدا باید تمام کتابخانه‌های مورد نیاز را با استفاده از دستور زیر اجرا کنید:

> pip install -r requirements.txt
Plain text

برای اجرای خود پروژه هم می‌توانید از دستور زیر استفاده کنید:

> python manage.py runserver
Plain text

فایل‌هایی که شما باید در این پروژه تکمیل کنید همگی در اپ guard قرار دارند. نام این فایل‌ها به صورت زیر است:

middlewares.py admin.py models.py init_guard.py

فایل models.py

در این فایل تمام مدل‌های مورد نیاز برای پروژه از قبل تعریف شده‌اند. در زیر به توضیح هر کدام از این مدل‌ها می‌پردازیم:

مدل BlockedIp🔗

این مدل برای ذخیره کد آی‌پی‌ها مسدود شده می باشد. این مدل یک فیلد ban_time دارد که اگر از زمان ساخت یک نمونه از این مدل، به مقدار ban_time بگذرد، آی‌پی موردنظر از حالت مسدود خارج می‌شود. توجه کنید که واحد ban_time به ثانیه است.

شما تنها کافی‌ست دو متد is_blocked و is_ip_blocked را کامل کنید. متد is_blocked یک مقدار بولین برمی‌گرداند که آیا هنوز یک شئ BlockedIp معتبر هست یا نه. اگر معتبر بود مقدار True و اگر زمان ban_time به طور کامل گذشته‌ باشد مقدار False برمی‌گرداند. متد is_ip_blocked نیز یک آی‌پی به عنوان ورودی گرفته و یک مقدار بولین برمی‌گرداند که نشان می‌دهد آی‌پی داده شده مسدود شده است یا نه.

همچنین دو مدل دیگر در این فایل قرار دارد که نباید در آن‌ها تغییری ایجاد کنید.

مدل ViewDetail🔗

این مدل برای ذخیره کردن تمام ویوهای موجود در پروژه استفاده می‌شود. یعنی تمام ویوها به همراه URL شان را در ابتدای اجرا کردن پروژه، تعریف می‌کنیم و به دیتابیس اضافه می‌کنیم. با این کار به راحتی می‌توانیم بفهمیم که هر آی‌پی با ریکوئست زدن به کدام ویو و URL مسدود شده است.

مدل SecurityConfig🔗

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

فایل init_guard.py

در این فایل باید یک دستور برای جنگو بنویسید که بتواند مقادیر اولیه‌ی موردنیاز برای مدل‌های ViewDetail و SecurityConfig را در صورتی که از قبل ساخته نشده باشند را بسازد و در دیتابیس قرار دهد.

فایل admin.py

در این فایل نیز باید تنظیمات ادمین مربوط به مدل‌های گفته‌ شده در بالا را انجام دهید. نیاز‌مندی‌های ما به شکل زیر است:

  • لیست اشیاء BlockedIp را بتوان بر حسب فیلد view فیلتر کرد.

  • در لیست اشیاء BlockedIp، بتوان بر حسب آی‌پی، نام ویو و URL ویو جست‌ و جو کرد.

  • برای قسمت ادمین SecurityConfig، اجازه ساختن و حذف کردن شئ جدید را به ادمین‌های سایت ندهیم.

  • برای قسمت ادمین ViewDetail، اجازه ساختن، حذف کردن و تغییر دادن شئ را به ادمین‌های سایت ندهیم.

فایل middlewares.py

در این قسمت باید مهمترین عنصر این ماژول امنیتی جدید را پیاده کنید. یک middleware که مقدار ریکوئست بر ثانیه را برای هر ریکوئست محاسبه می‌کند و اگر این مقدار از حداکثر مقدار ممکن، یعنی ۴ ریکوئست بر ثانیه، بیشتر باشد، آی‌پی کاربر را مسدود می‌کند. در این میدلور باید بررسی شود که اگر آی‌پی کسی که ریکوئست زده است، قبلا مسدود شده بود (banned_before)، یک ریسپانس با کد ۴۰۳ برگرداند؛ همچنین در این میدلور برای ذخیره کردن ریکوئست‌های هر کاربر، از کش جنگو با زمان ماندگاری (timeout) ۶۰ثانیه استفاده می‌شود نه دیتابیس، تا سرعت پاسخگویی به ریکوئست‌ها خیلی تحت تاثیر قرار نگیرد. هم چنین در متد validate_request_per_second باید داده‌های مربوط به آی‌پی ریکوئست زننده که در کش ذخیره شده، بررسی و تعداد ریکوئست‌ها بر ثانیه‌ی آن محاسبه شود. اگر این مقدار بیشتر از ۴ ریکوئست بر ثانیه بود، آن وقت آی‌پی موردنظر را در لیست سیاه قرار داده و ریسپانسی با کد ۴۲۹ برگردانده شود.

حالا با اطلاعاتی که آقای رئیس به شما داده، کمک‌هایتان را برای ما آپلود کنید!

آن‌چه باید آپلود کنید🔗

یک فایل ZIP شامل پروژه جنگو خود آپلود کنید؛ توجه کنید که فقط می‌توانید ۴ فایل گفته شده در بالا را تغییر دهید.

جنگو - دوبستان


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

در این کشور عجیب فقط بیمارستان‌ها و شرکت‌ها وجود دارند. ساکنانش هم مثل کشورشان عجیب‌اند؛ با این‌که پروتکل‌ها را رعایت نمی‌کنند ولی از مریضی به شدت می‌ترسند، برای همین برای هر مسئله‌ای به بیمارستان مراجعه می‌کنند.

برای اجرای این سامانه مدیران‌ بیمارستان‌ها و شرکت‌ها همکاری خود را اعلام کرده‌اند. این سامانه چند کار را انجام می‌دهد:

  1. با گرفتن اسم بیمارستان، افرادی را که در این بیمارستان بستری هستند، کرونا دارند و در شرکتی کار می‌کنند را برمی‌گرداند.

  2. با گرفتن اسم شرکت، کارمندانی که به‌خاطر کرونا به بیمارستان مراجعه‌ کرده بوده‌اندرا بر می‌گرداند.

  3. این سامانه برای اطلاع‌رسانی از سرویس sms استفاده می‌کند. لیستی از کد ملی اشخاص دریافت می‌کند و با استفاده از کد ملی شماره‌ تلفنشان را پیدا کرده و برای آن‌هاsms می‌فرستد. (در این شهر هر کد ملی به یک شماره تلفن اختصاص و هر شماره تلفن به یک کد ملی اختصاص داده شده است.)

پروژه اولیه🔗

پروژه اولیه را از این لینک دانلود کنید. ساختار فایل‌های این پروژه به صورت زیر است.

دیتابیس‌ها - پیاده‌سازی شده است

دیتابیس‌ها🔗

دیتابیس default🔗

در این دیتابیس قرار است گزارش‌های مربوط به smsهای داده شده ذخیره شود.

دیتابیس hospitals🔗

در این دیتابیس اطلاعات راجع‌به بیمارستان‌ها و مریض‌های مربوط به هر بیمارستان را داریم.

دیتابیس companies🔗

در این دیتابیس اطلاعات راجع به شرکت‌ها و کارمند‌های مربوط به هر شرکت را داریم.

مدل‌ها - پیاده‌سازی شده است

مدل‌ها🔗

مدل DeliveryReport🔗

این مدل فقط شامل یک فیلد می‌باشد:

فیلد phone_number : شماره‌ی شهروندی که به او از طریق این سرویس sms داده شده در آن ذخیره می‌شود. این فیلد از نوع CharField می‌باشد.

این مدل مربوط به دیتابیس default می‌باشد.

مدل Hospital🔗

این مدل شامل سه فیلد می‌باشد:

فیلد name: نشان‌دهنده‌ی نام بیمارستان می‌باشد و unique است. این فیلد از نوع ‍CharField می‌باشد.

فیلد manager_name: نشان‌دهنده‌ی نام مدیر بیمارستان است. این فیلد از نوع CharField می‌باشد.

فیلد manager_id: نشان‌دهنده‌ی کد ملی مدیر بیمارستان است. این فیلد از نوع CharField می‌باشد.

این مدل مربوط به دیتابیس hospitals می‌باشد.

مدل Company🔗

این مدل شامل سه فیلد می‌باشد:

فیلد name: نشان‌دهنده‌ی نام شرکت می‌باشد و unique است. این فیلد از نوع ‍CharField می‌باشد.

فیلد manager_name: نشان‌دهنده‌ی نام مدیر شرکت است. این فیلد از نوع CharField می‌باشد.

فیلد manager_id: نشان‌دهنده‌ی کد ملی مدیر شرکت است. این فیلد از نوع CharField می‌باشد.

این مدل مربوط به دیتابیس companies می‌باشد.

مدل Sick🔗

این مدل شامل چهار فیلد می‌باشد:

فیلد name: نشان‌دهنده‌ی نام بیمار است. این فیلد از نوع CharField می‌باشد.

فیلد nationalID: نشان‌دهنده‌ی کدملی بیمار است. این فیلد از نوع CharField می‌باشد

فیلد illName: نشان‌دهنده‌ی نام بیماری‌ بیمار مورد نظر است. این فیلد از نوع CharField می‌باشد.

فیلد hospital: نشان‌دهنده‌ی بیمارستانیست که این بیمار در آن بستری شده است. این فیلد از نوع ‌‍ForeignKey به مدل hospital می‌باشد.

این مدل مربوط به دیتابیس hospital می‌باشد.

مدل employee🔗

این مدل شامل سه فیلد می‌باشد:

فیلد name: نشان‌دهنده‌ی نام کارمند است. این فیلد از نوع CharField می‌باشد.

فیلد nationalID: نشان‌دهنده‌ی کد ملی کارمند است. این فیلد از نوع CharField می‌باشد.

فیلد company: نشان‌دهنده‌ی شرکتیست که این کارمند در آن کار می‌کند. این فیلد از نوع ‌ForeignKey به مدل company می‌باشد.

این مدل مربوط به دیتابیس companies می‌باشد.

ویو‌ها - توسط شما پیاده‌سازی می‌شود

ویو‌‌ها🔗

ویو get_sick_employee_by_hospital🔗

این ویو یک request می‌پذیرد که از نوع POST می‌باشد.

در request اسم بیمارستان به صورت json داده می‌شود. (NameSerializer سریالایزر مربوط به این ریکوئست می‌باشد.) به عنوان response یک دیکشنری داده می‌شود؛ به این صورت که در قسمت key اعداد ‍۱ تا n قرار دارند و در قسمت value یک رشته به صورت زیر ذخیره می‌شود: "(name, nationalID)" در واقع نام و کد ملی شخصیست که به آن بیمارستان برای کرونا مراجعه کرده و کارمند است. دقت کنید که اهمیتی ندارد کدام value به کدام key‍‍ نسبت داده شده است.

کسانی که کرونا دارند فیلد illName آن‌ها به صورت Covid19 ذخیره شده است.

ویو get_sick_employee_by_company🔗

این ویو یک request می‌پذیرد که از نوع POST می‌باشد.

در request اسم شرکت به صورت json داده می‌شود. (NameSerializer سریالایزر مربوط به این ریکوئست می‌باشد.) به عنوان response یک دیکشنری داده می‌شود؛ به این صورت که در قسمت key اعداد ‍۱ تا n قرار دارد و در قسمت value یک رشته به این صورت ذخیره می‌شود: (name, nationalID)(دقت کنید که این رشته است و نه تاپل.) در واقع نام و کدملی شخصیست که در آن شرکت کار می‌کند و برای کرونا به بیمارستان مراجعه کرده است. دقت کنید که اهمیتی ندارد کدام value به کدام key‍‍ نسبت داده شده است.

کسانی که کرونا دارند فیلد illName آن‌ها به صورت Covid19 ذخیره شده است.

این ویو یک request می‌پذیرد که از نوع POST می‌باشد.

در request کد ملی کسانی که قرار است برای آن‌ها sms فرستاده شود به صورت json داده می‌شود.(NationalIDSerializer سریالایزر مربوط به این ریکوئست می‌باشد.)

در فایل SMS.py دو تابع داریم:

تابع sms: به عنوان ورودی یک شماره تلفن می‌گیرد(phone_number) و برای آن sms می‌فرستد.

تابع ‍get_phone_number: به عنوان ورودی کد ملی می‌گیرد(number) و به عنوان خروجی شماره تلفن اختصاص داده شده به آن را می‌دهد.

ویو sms_link با استفاده از توابع فایل SMS.py‍‍ برای شماره‌های اختصاص داده شده به کد‌های ملی دریافتی sms می‌فرستد و در دیتابیس به ازای هر sms فرستاده شده، یک شیءDeliveryReport با شماره‌ی شخص را ذخیره‌ می‌کند.

دقت کنید که تابع sms از نوع async می‌باشد.

در نهایت به عنوان response کد استاتوس ۲۰۰ برگردانده می‌شود..

فایل روتر - توسط شما پیاده می‌شود

فایل db_Router.py🔗

در این فایل دو کلاس مربوط به لیست DATABASE_ROUTERS (تعریف شده در settings.py) باید توسط شما پیاده‌سازی شود.

نکات🔗

  • توجه کنید که اگر هر request مشکلی داشته باشد، ویوی مربوط به آن باید کداستاتوس ۴۰۰ را برگرداند.
  • هر کد ملی برای یک نفر است.
  • شما فقط مجاز به تغییر دادن فایل‌های views.py و db_Router.py هستید. باقی تغییرات در سیستم داوری نادیده گرفته می‌شود.

آن‌چه باید آپلود کنید🔗

یک فایل ZIP شامل پروژه جنگو خود آپلود کنید.