یک مربع در صفحه وجود دارد. میخواهیم با فشرده شدن کلیدهای جهت صفحه کلید
(بالا، پایین، راست، چپ) مربع بر روی صفحه در همین جهتها حرکت کند.
![Simple Movement](http://bayanbox.ir/view/5015922703850435480/movement.png)
کد HTML و CSS نوشته شده است و به شما داده میشود.
از شما میخواهیم عملکرد موردنظر را با JavaScript پیادهسازی کنید.
# فایلهای اولیه
فایلهای اولیه را از [اینجا](http://bayanbox.ir/download/8820622022963978567/movement-initial.zip) دانلود کنید. ساختار این فایلها به شرح زیر است:
```
initial
├── index.html
└── style.css
```
# جزئیات
باید با فشرده شدن هریک از کلیدهای بالا، پایین، راست و چپ، مربع
(بلوک div با شناسه `square`) یک پیکسل در جهت موردنظر حرکت کند.
در صورتی که هنگام فشرده شدن کلید جهت، کلید shift نیز نگه داشته شده باشد، حرکت مربع بجای یک پیکسل، باید ۱۰ پیکسل باشد.
مثلاً با فشردن `shift + up`، مربع باید ۱۰ پیکسل به بالا حرکت کند.
میتوانید در کنار `index.html`، تعدادی فایل `.js`
(کتابخوانههای آماده و یا کد خودتان) قرار دهید و استفاده کنید.
# نکات
- کافیست با هر بار زدن کلید، یک بار حرکت موردنظر انجام شود.
نیازی نیست تا زمانی که کلید پایین است، مربع به حرکت ادامه دهد.
- حرکت مربع باید بلافاصله پس از فشردن کلید به صورت کامل و **لحظهای** انجام شود.
بنابراین در صورتی که حرکت مربع کمی طول بکشد، پاسخ شما نمره نخواهد گرفت.
- همانطور که در فایل CSS داده شده مشاهده میکنید مکان اولیهی مربع `(200, 200)` است.
اما کد شما نباید به این اعداد وابسته باشد، زیرا هنگام داوری خودکار یک
فایل CSS دیگر جایگزین میشود و مکان اولیه مربع متفاوت خواهد بود.
- توجه کنید که داوری خودکار بر مبنای شناسه (id) عناصر انجام میشود،
پس دقت کنید که شناسههای موجود را تغییر ندهید.
- فرض کنید سیستم به اینترنت متصل نیست، بنابراین از ارجاع به فایلهای موجود
در وب (CDN ها) خودداری کنید.
- پروژه را با ساختار زیر ارسال کنید.
تغییر تنها در مواردی که با `*` مشخص شده مجاز است
و ارسال سایر فایلها الزامی نیست.
```
[your-zip-file-name].zip
├── index.html *
├── style.css
└── your .js files (Optional) *
```
Front-End - جابجایی ساده
شکل زیر یک **ماشینحساب ساده** را نشان میدهد که قرار است برای انجام عملیات سادهی
چهارگانه روی اعداد صحیح پیادهسازی شود.
![Calculator](http://bayanbox.ir/view/2308771569613452826/calculator.png)
میخواهیم رابط کاربری این ماشینحساب را با HTML و CSS پیادهسازی کنیم.
بخشی از کدها نوشته شده است که در اختیار شما قرار میگیرد.
از شما میخواهیم با تکمیل کدهای CSS و HTML این کار را به پایان برسانید.
# فایلهای اولیه
فایلهای اولیه را از [اینجا](http://bayanbox.ir/download/3126682149992659314/calculator-initial.zip) دانلود کنید. ساختار این فایلها به شرح زیر است:
```
initial
├── calculator.html
├── DigitalNumbers.woff
├── RobotoCondensed.woff
└── style.css
```
# جزئیات
همانطور که در فایل `calculator.html` مشاهده میکنید، ساختار عناصر ماشینحساب به صورت زیر است:
```html
<div id="app">
<div id="result">1428.57</div>
<div id="keypad">
<div id="nums">
<div class="key">7</div>
<div class="key">8</div>
<div class="key">9</div>
<div class="key">4</div>
<div class="key">5</div>
<div class="key">6</div>
<div class="key">1</div>
<div class="key">2</div>
<div class="key">3</div>
<div class="key">0</div>
<div class="key">.</div>
<div class="key">=</div>
</div>
<div id="ops">
<div class="key">×</div>
<div class="key">-</div>
<div class="key">+</div>
<div class="key">÷</div>
<div class="key">CM</div>
<div class="key">M-</div>
<div class="key">M+</div>
</div>
</div>
</div>
```
از شما میخواهیم بر اساس توضیحات زیر، پیادهسازی ظاهر این ماشینحساب را تکمیل کنید.
## عنصر `#app`
- ارتفاع این عنصر ۷۰٪ ارتفاع صفحه (و حداقل ۲۸۰ پیکسل) است.
- عرض این عنصر ۸۰٪ عرض صفحه (و حداکثر ۵۸۰ پیکسل) است.
- این عنصر همواره دقیقاً در مرکز صفحه قرار دارد.
![Calculator](http://bayanbox.ir/view/3610984830017936046/calculator.gif)
## عنصر `#result`
- ارتفاع این عنصر ۲۸٪ ارتفاع ماشینحساب و عرض آن به اندازهی عرض ماشینحساب است.
- رنگ پسزمینه `#EEE` و رنگ متن `#444` است.
- فونت این عنصر `DigitalNumbers` است.
## عنصر `#keypad`
- ارتفاع این عنصر ۷۲٪ ارتفاع ماشینحساب و عرض آن به اندازهی عرض ماشینحساب است.
- رنگ متن همهی کلیدها `#DDD` است.
- فونت همهی کلیدها `RobotoCondensed` است.
## عنصر `#nums`
- ارتفاع این عنصر به اندازهی ارتفاع بخش کلیدها و عرض آن ۵۴٪ عرض بخش کلیدها است.
- عرض و ارتفاع این عنصر مطابق شکل به طور مساوی بین ۱۲ کلید آن تقسیم میشود.
- کلیدهای این بخش مطابق شکل رنگهای `#19676E` و `#095057` را به صورت شطرنجی دارند.
## عنصر `#ops`
- ارتفاع این عنصر به اندازهی ارتفاع بخش کلیدها و عرض آن ۴۶٪ عرض بخش کلیدها است.
- کلیدهای این بخش (به جز کلید`+`) نیمی از عرض و یکچهارم ارتفاع این عنصر را دارند.
- کلیدهای این بخش (به جز کلید`+`) مطابق شکل رنگهای `#D34E47` و `#B52D26`
را به صورت شطرنجی دارند.
- ارتفاع کلید `+` دو برابر بقیه و رنگ آن `#C43E37` است.
## سایر توضیحات
- بین کلیدها هیچ فاصلهای وجود ندارد.
- هیچ عنصری حاشیه (border) ندارد.
- فایل فونتهای `RobotoCondensed` و `DigitalNumbers` به شما داده شده است.
باید قبل از استفاده، آنها را با `font-face` در فایل `style.css` تعریف کنید.
# نکات
- میتوانید در صورت لزوم این تغییرات را در فایل HTML بدهید:
کلاسهای جدیدی به عناصر اضافه کنید
و یا کلاسهای موجود را تغییر دهید، برای عناصری که
شناسه ندارند شناسه تعریف کنید، و یا ترتیب کلیدها
را در HTML تغییر دهید. تغییرات دیگر مجاز نیستند.
- توجه کنید که داوری خودکار بر مبنای شناسه (id) عناصر انجام میشود،
پس دقت کنید که شناسههای موجود را تغییر ندهید.
- محتوای عناصر (مثلاً حروف `+`، `×`، `2`) را تغییر ندهید.
- پروژه را با ساختار زیر ارسال کنید.
تغییر تنها در مواردی که با `*` مشخص شده مجاز است
و ارسال سایر فایلها الزامی نیست.
```
[your-zip-file-name].zip
├── calculator.html *
├── DigitalNumbers.woff
├── RobotoCondensed.woff
└── style.css *
```
Front-End - ماشینحساب ساده
در این سؤال قصد داریم از شما برای طراحی یک **سودوکوی ساده**
کمک بگیریم. این سودوکو در ابتدا به این شکل است:
![Sudoku 1](http://bayanbox.ir/view/5187773712446737362/sudoku1.png)
قوانین این سودوکو به این ترتیب هستند:
- همه خانههای این جدول باید با اعداد ۱ تا ۸ پر شود.
- در هر ردیف افقی یا مورب (در جهاتی که در شکل زیر مشخص شده است) و همچنین
در هر شش خانه مجاور هریک از خانههای رنگی شکل زیر
(مثلاً خانههای ۶، ۷، ۱۱، ۱۳، ۱۷ و ۱۸)، نباید عدد تکراری وجود
داشته باشد.
![Sudoku 2](http://bayanbox.ir/view/1525830049428463858/sudoku2.png)
- با زدن کلید `Check` ،درصورتی که تمام خانهها به درستی
پر شده باشند، جدول به شکلی مشابه تصویر زیر در میآید:
![Sudoku 3](http://bayanbox.ir/view/7356467150706897890/sudoku3.png)
- درصورتی که جدول ناقص باشد یا نادرست پر شده باشد،
با زدن کلید `Check` با نتیجهای مانند تصویر زیر مواجه میشویم:
![Sudoku 4](http://bayanbox.ir/view/8124794420146582403/sudoku4.png)
- با زدن کلید `New`، جدول خالی میشود و بازی تازهای آغاز میشود.
![Sudoku 5](http://bayanbox.ir/view/5187773712446737362/sudoku1.png)
کد HTML و CSS نوشته شده است و به شما داده میشود.
از شما میخواهیم عملکردهای خواستهشده را با JavaScript پیادهسازی کنید.
**مثالی از نحوهی عملکرد:**
![Sudoku](http://bayanbox.ir/view/184184379578497418/sudoku.gif)
# فایلهای اولیه
فایلهای اولیه را از [اینجا](http://bayanbox.ir/download/7048064799383683439/sudoku-initial.zip) دانلود کنید. ساختار این فایلها به شرح زیر است:
```
initial
├── sudoku.html
└── style.css
```
# جزئیات
همانطور که در فایل HTML دادهشده میبینید، هرکدام از خانههای جدول، یک
عنصر `input` با کلاس `cell` و شناسه `cell_i` است.
همچنین کلیدهای`Check` و `New` هر کدام یک عنصر `button` هستند
که به ترتیب شناسهی `check` و `new` دارند.
از شما میخواهیم بر اساس توضیحات زیر، پیادهسازی عملکرد را انجام دهید.
- با فشردن کلید `Check`:
+ خانههای جدول محتوای ثابتی خواهند داشت
و دیگر ورودی نخواهند پذیرفت؛ به عبارت دیگر `disable` میشوند.
+ رنگ متن همهی خانهها سفید میشود.
+ در صورتی که جدول به صورت کامل و به درستی (مطابق قوانین) پر شده باشد،
رنگ تمام خانههای جدول `#37B75E` میشود.
+ در صورتی که جدول به درستی و مطابق قوانین پر نشده باشد،
رنگ خانههای خالی `#F5BB88` میشود.
خانههایی که دارای *مقادیر تکراری* هستند رنگ `#DE480D` خواهند داشت.
رنگ بقیهی خانههای پر نیز `#F37540` میشود.
- منظور از خانههای با *مقادیر تکراری*، خانههایی هستند که با تکرار شدن مقادیر،
قوانین جدول را نقض کردهاند.
برای مثال، اگر در یک ردیف، سه خانه مقدار `1` داشته باشند،
هر سه دچار تغییر گفته شده خواهند شد.
- حتی اگر تمام خانههای جدول خالی باشند،
تمام خانههای خالی باید ویژگیهای گفته شده را اتخاذ کنند.
- با فشردن کلید `New`:
+ محتوای تمام خانهها خالی میشود،
رنگ پس زمینه و رنگ متن به حالت اولیه برمیگردد و میتوانند ورودی جدید بپذیرند.
- در هر خانه، تنها یکی از ارقام `1` تا `8` میتواند قرار بگیرد.
در صورت وارد شدن چند رقم متوالی، تنها اولین رقم در خانه قرار میگیرد
و کاراکترهای دیگر نیز به کلی پذیرفته نمیشوند. مثلاً در صورتی که در خانهای
رقم `9` یا حرف `a` تایپ شود، این حرف نباید وارد input شود، یا در صورتی که
در یک خانه که با رقم `1` پر شده است، رقم `2` تایپ شود، این حرف نیز نباید
وارد input شود.
(میتوانید پس از ورود حروف غیرمجاز، آنها را از input حذف کنید.)
- یک مثال دیگر: در صورتی که در یک خانه، عبارت `a925` تایپ شود،
انتظار داریم داخل خانه رقم `2` قرار بگیرد.
- اطلاعات دقیقتر در مورد ویژگی های هر کلاس و هر عنصر در
فایلهای اولیهی دادهشده موجود است. لذا این فایلها را به دقت بررسی کنید.
# نکات
- توجه کنید که داوری خودکار بر مبنای شناسه (id) عناصر انجام میشود.
پس دقت کنید که عناصر شناسهی صحیح داشته باشند.
- فرض کنید سیستم به اینترنت متصل نیست، بنابراین از ارجاع به فایلهای موجود
در وب (CDN ها) خودداری کنید.
- پروژه را با ساختار زیر ارسال کنید.
```
[your-zip-file-name].zip
├── sudoku.html
├── style.css
└── your .js files (Optional)
```
Front-End - سودوکوی ساده
در شکل زیر یک صفحه ساده را میبینیم که به زبان انگلیسی است.
![Farsization 1](http://bayanbox.ir/view/3611119775780345120/farsization1.png)
از شما میخواهیم این صفحه را مطابق شکل زیر با استفاده
از امکانات ترجمهی **Django** به فارسی ترجمه کنید.
![Farsization 2](http://bayanbox.ir/view/5017669853433447153/farsization2.png)
# فایلهای اولیه
فایلهای اولیه را از [اینجا](http://bayanbox.ir/download/433632270299847071/farsization.zip) دانلود کنید. ساختار این فایلها به شرح زیر است:
```
farsization
├── app
│ ├── templates
│ │ └── app
│ │ └── home_page.html
│ ├── __init__.py
│ ├── apps.py
│ ├── models.py
│ └── views.py
├── Home
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── requirements.txt
```
# جزئیات
شما باید فایل ترجمه را به همراه کامپایلشدهی آن،
در پوشهی صحیح در مسیر `app/locale` ایجاد کنید.
پروژه باید بدون نیاز به هیچ تغییر دیگری متون را فارسی نمایش دهد.
متنهای فارسی را از جدول زیر کپی کنید:
| متن انگلیسی | ترجمه فارسی |
|:--------------------------------------:|:----------------------------------:|
| Website Statistics | آمار سایت |
| Number of visits | تعداد بازدیدها |
| Your website had ### visits yesterday. | سایت شما دیروز ### بازدید داشت. |
# نکات
- پس از اعمال تغییرات موردنظر، کل پروژه را Zip کرده و ارسال کنید.
- نام فایل Zip اهمیت ندارد.
Django - فارسیزیشن
میخواهیم یک سایت برای خودکار کردن فرایند فروش بلیتهای سینما بنویسیم.
در این سایت امکان مشاهده فیلمهای در حال اکران وجود دارد.
کاربران میتوانند عضو سایت شوند و پس از ورود به سایت
برای هر فیلم صندلی موردنظر را رزرو کند.
بخشی از این پروژه نوشته شده است. از شما میخواهیم این پروژه را تکمیل کنید.
# پروژه اولیه
پروژه اولیه را از [اینجا](http://bayanbox.ir/download/5545408568741586764/cinema.zip) دانلود کنید. ساختار این پروژه به شرح زیر است:
```
cinema
├── app
│ ├── migrations
│ │ ├── __init__.py
│ │ └── 0001_initial.py
│ ├── templates
│ │ └── app
│ │ ├── movies.html
│ │ └── seats.html
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── urls.py
│ └── views.py
├── Cinema
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── templates
│ └── registration
│ ├── login.html
│ └── signup.html
├── manage.py
└── requirements.txt
```
# جزئیات
در این سؤال تنها لازم است تغییراتی در `app/views.py` و `app/fixtures` ایجاد کنید.
در فایل `models.py` سه مدل به شرح زیر وجود دارد:
۱. مدل `Movie` شامل فیلدهای زیر:
* `title`: نام فیلم
* `release_year`: سال انتشار فیلم
* `play_time`: زمان اکران فیلم در سالن
۲. مدل `Seat` شامل فیلد زیر:
* `number`: شماره صندلی
۳. مدل `Ticket`شامل فیلدهای زیر:
* `movie`: فیلمی که این بلیت برای آن فروخته شده است
* `user`: کاربری که این بلیت را خریده است
* `seat`: صندلی مربوط به این بلیت
* `date_bought`: تاریخی که بلیت خریده شده است
قرار است همه صندلیهای سالن و لیست فیلمها در ابتدا با استفاده از fixture
به پایگاه داده اضافه شود. سپس به ازای هر بلیتی که فروخته میشود
یک شیٔ از مدل `Ticket` ساخته میشود.
مواردی که باید انجام دهید:
### ۱. نوشتن fixture
از شما میخواهیم دو فایل *fixture* با نامهای
`movies` و `seats`
در مسیر `app/fixtures`
بنویسید. این *fixture* ها را میتوانید به فرمت
`JSON` یا `YAML`
بنویسید.
+ فایل `movies` باید شامل دادههای زیر باشد.
زمان اکران را به صورت naive (بدون TimeZone) تعریف کنید.
| id | نام فیلم | سال انتشار | تاریخ اکران | ساعت اکران |
|:---:|:----------:|:-------------:|:-------------:|:-------------------:|
| 1 | Children of heaven | 1997 | 2018/4/20 | 22:00 |
| 2 | About Elly | 2009 | 2018/4/20 | 20:00 |
| 3 | A separation | 2011 | 2018/4/22 | 18:00 |
| 4 | The salesman | 2016 | 2018/4/21 | 18:00 |
| 5 | The Elephant king | 2017 | 2018/4/21 | 20:00 |
+ فایل `seats` نیز باید شامل ۱۰ صندلی با `id` های ۱ تا ۱۰
و با شماره صندلیهای ۳۱ تا ۴۰ (به ترتیب `id` ها) باشد.
### ۲. نمایش صندلیها
در این قسمت باید view نمایش صندلیها (`list_seats`) را به گونهای تغییر دهید
که فقط صندلیهایی که برای فیلم موردنظر رزرو نشدهاند نمایش داده شوند.
### ۳. رزرو صندلی
با توجه به توضیحات زیر، view ها را تکمیل کنید.
برای رزرو صندلی، کاربر مراحل زیر را انجام میدهد:
+ ابتدا از آدرس `/movie` بازدید میکند که لیست فیلمهایی که در حال اکران هستند
را نمایش میدهد. سپس روی فیلم مورد نظر خود کلیک کرده و صفحهی بعدی صندلیهای رزرو
نشده برای آن فیلم را نمایش میدهد. تا این مرحله کاربر نیازی به login بودن ندارد.
+ وقتی کاربر روی یکی از صندلیها کلیک کرد:
+ اگر کاربر login است، صندلی برای کاربر
رزرو شده و دوباره به صفحهی صندلیهای همان فیلم *redirect* میشود تا
بتواند صندلیهای دیگری را نیز رزرو کند.
+ اگر کاربر login نیست،
به صفحهی *login* هدایت میشود و پس از وارد شدن به سایت،
بلافاصله به صفحهی قبلی (صفحه لیست صندلیها) *redirect* میشود،
بدون این که صندلی رزرو شود.
+ در صفحهی *login* اگر کاربر روی لینک *signup* کلیک کرد و در سایت
عضو شد، باید بلافاصله پس از عضویت به طور خودکار در سایت login شود
و به صفحه لیست فیلمها *redirect* شود.
### ۴. گزارش گیری سایت
در این قسمت شما باید view مربوط به آدرس `stats` را به نحوی کامل کنید
که در پاسخ برای همه صندلیهای که حداقل
برای یک فیلم رزرو شدهاند (به ترتیب `id` صندلی)،
یک خروجی JSON به شکل زیر بازگردد:
```json
[{"seat__number": 31, "total": 3}, {"seat__number": 32, "total": 1}, ... ]
```
+ مقدار *total*، تعداد رزروهای صندلی مشخص شده است.
+ این *view* تنها باید برای مدیران (superuser ها) فعال باشد و برای سایر افراد
خطای ۴۰۳ (Forbidden) برگرداند.
# نکات
+ شما تنها مجاز به تغییر در `app/views.py` و `app/fixtures` هستید.
اگر تغییری در سایر فایلها ایجاد کنید، این تغییرات نادیده گرفته خواهد شد.
+ پس از اعمال تغییرات، کل پروژه را Zip کرده و ارسال کنید.
+ نام فایل Zip اهمیت ندارد.
Django - فروش بلیت
همه چی از uber شروع شد. ایده ی خوبی که رانندگان را به مسافران وصل میکرد و هر کسی هر جایی بود به سرعت میتوانست برای خودش تاکسی درخواست دهد. مدتی نگذشت که برنامهنویس های داخل کشور عزیزمان هم از این سرویس ایده گرفتند و شروع به پیاده سازی مشابه آن در ایران کردند. در حال حاضر چندین سرویس درخواست آنلاین تاکسی وجود دارد که در تهران و چند شهر دیگر مشغول سرویس دهی به مسافرین هستند و روز به روز هم گسترش بیشتری میابند و اشتغالزایی زیادی را نیز به وجود آوردهاند. حالا با توجه به بازار داغ این سرویس ما نیز میخواهیم یک سرویس مشابه ایجاد کنیم. اسمش هم `cabin` گذاشتهایم. شما میتوانید پروژه کابین رو از [اینجا](http://bayanbox.ir/download/6519668623165691239/cabin.zip) دانلود کنید.
همانطور که در فایل ها میبینید یک app به نام cabin وجو دارد. در فایل models.py هشت مدل به شرح زیر وجود دارد:
+ Account: اکانت که به یک مدل دیگر اعم از راننده یا مسافر یا مدیر سیستم وصل است و شامل فیلد های زیر است
+ first_name: نام شخص
+ last_name: نام خانوادگی شخص
+ email: ایمیل شخص
+ phone: شماره تلفن شخص
+ password: پسورد شخص
+ Admin: مدیر سیستم که دسترسی هایی خاصی به سیستم دارد
+ account: اکانت ادمین که اطلاعات او را نگه میدارد
+ Rider: مسافر
+ account: اکانت مسافر که اطلاعات او را نگه میدارد
+ x: طول جغرافیایی موقعیت مسافر
+ y: عرض جغرافیایی موقعیت مسافر
+ rating: امتیاز مسافر
+ Driver: راننده
+ account: اکانت راننده که اطلاعات او را نگه میدارد
+ x: طول جغرافیایی موقعیت راننده
+ y: عرض جغرافیایی موقعیت راننده
+ rating: امتیاز راننده
+ active: آماده به کار بودن با نبود راننده را نشان میدهد
+ Car: خودرو
+ owner: صاحب خودرو که یک راننده است
+ car_type: نوع کلاس خودرو
+ model: سال تولید خودرو
+ color: رنگ خودرو
+ RideRequest: درخواست سفر
+ rider: مسافر درخواست دهنده
+ x: طول جغرافیایی نقطه درخواست
+ y: عرض جغرافیایی نقطه درخواست
+ car_type: کلاس خودرو درخواست شده
+ Ride: سفر
+ pickup_time: (زمان شروع سفر(سوار کردن مسافر
+ dropoff_time: زمان پایان سفر
+ *دو زمان بالا از نوع عدد صحیح و نشاندهنده تعداد ثانیه های گذشته از زمان تاسیس شرکت می باشند.*
+ request: درخواست سفری که این سفر به آن مربوط میشود
+ car: خودرویی که این سفر با آن انجام شده است
+ rider_rating: امتیازی که راننده به مسافر داده است
+ driver_rating: امتیازی که مسافر به راننده داده است
+ Payment: پرداخت
+ ride: سفری که پرداخت برای آن انجام شده است
+ amount: مبلغ پرداخت شده برحسب تومان
+ status: وضعیت پرداخت
حال از شما میخواهیم پرس و جو (query) های زیر را روی مدل های بالا بنویسید.
**حتما قبل شروع نوشتن کد، تذکرات انتهای سوال را بخوانید!**
#### ۱. ورودی کل شرکت کابین (پولی که از طریق پرداخت وارد شرکت میشود)
در اینجا status تاثیری ندارد و نتیجه را میتوانید به صورت dict برگردانید.
```json
{'income': value }
```
#### ۲. کل مبلغ پرداخت شده توسط مشتری با id برابر با x
```json
{'payment_sum': value }
```
#### ۳. تعداد راننده هایی که حداقل یک ماشین کلاس A دارند.
+ در این سوال باید `.count()` از QuerySet مربوطه را بازگرانید که نتیجه یک عدد خواهد بود.
#### ۴. لیست درخواست های سفرِ در انتظار (یعنی درخواست هایی که به هیچ سفری وصل نباشد)
#### ۵. لیست مسافرانی که مجموع مبلغ سفر هایشان بیشتر یا مساوی با t تومان است.
#### ۶. اکانتِ راننده ای که بیشترین تعداد ماشین را دارد. اگر تعداد ماشین ها یکسان بود راننده ای را بدهید که نام خانوادگیاش از نظر الفبایی کوچکتر است.
+ در این سوال باید یک شیء از نوع Account بازگرانید که نتیجه مانند زیر خواهد بود:
```json
<Account: Account object>
```
#### ۷. لیست همه مسافرانی که حداقل یک سفر با ماشین کلاس A داشته اند به همراه یک ستون اضافه با نام `n` که تعداد سفر هایی که هر مسافر با ماشین کلاس A داشته است را نشان میدهد.
#### ۸. لیست ایمیل رانندگانی که حداقل یک ماشین با مدل x (توجه کنید که مدل با نوع متفاوت است!) یا به بالا دارند.
خروجی نمونه:
```
<QuerySet [{'account__email': 'linda180@gmail.com'}, {'account__email': 'jacqueline859@gmail.com'}, {'account__email': 'benjamin780@gmail.com'},.....]>
```
#### ۹. لیست **همه** راننده ها و یک ستون اضافه شده به آن به نام `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 و یک ماشین مدل n یا به بالا(توجه کنید که مدل با نوع متفاوت است!) دارند.
+ *در این لیست نباید رانندهی تکراری وجود داشته باشد.*
+ *لزوما این دو ماشین یکسان نیست. ولی برای رنگ و مدل باید حداقل یک ماشین با شرایط گفته شده برای هر کدام وجود داشته باشد*
#### ۱۳. مجموع طول سفر هایی که در آن اسم راننده n (مثلا jack) و اسم مسافر m بوده است.
```json
{'sum_duration': value }
```
## **تذکرات:**
+ یک فایل به نام `queries.py` وجود دارد که برای هر سوال یک تابع در نظر گرفته شده است. شما کد های خود را باید در این فایل بنویسید و QuerySet مربوطه را بازگردانید.
+ برای نمونه تابع `query_0` در پاسخ به پرس و جویِ «لیست همه ی رانندگانی که رتبهی آنها بیشتر از x است.» کامل شده است که شما نیز باید مشابه همین تابع بقیه توابع را کامل کنید.
```python
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 است ولی شامل همه فیلد های مدل مورد نظر نمیشود و فقط فیلد های خواسته شده با نام خواسته شده باید در آن قرار داشته باشد.
+ در هیچ کدام از پرس و جوی های خواسته شده ترتیب مهم نیست.
+ منظور از نام برای رانندگان و مسافران `first_name` است.
### فایل آپلودی
یک فایل zip. که درون آن یک پوشه `cabin` وجود دارد که شامل یک فایل `queries.py` است. توجه کنید در صورتی که فایلهای اضافی ارسال کنید، حذف خواهند شد.
```
<Your-zip-name>.zip
└── cabin
└── queries.py
```
Django - کابین
با تعریف یک middle به نام minifier ترتیبی بدهید که html ارسال شده از سمت سرور برای کاربران minify شده باشد.
برای مثال بتوان از آن به شکل زیر استفاده کرد
```php
Route::middleware('minifier')->view('welcome.blade.php');
```
# نکات
شما فقط مجاز به ایجاد تغییرات در دو فایل زیرهستید و توجه داشته باشید که از تغییرات موجود در سایر فایل ها به هنگام داوری صرف نظر خواهد شد.
```
app/Http/Kernel.php
app/Http/middlewares/Minifier.php
```
از قطعه کد زیر میتوانید جهت فشرده سازی html استفاده کنید.
ورودی و خروجی این تابع از جنس string هستند.
```php
function minifyHTML($htmlString)
{
$replace = [
'<!--(.*?)-->' => '', //remove comments
"/<\?php/" => '<?php ',
"/\n([\S])/" => '$1',
"/\r/" => '', // remove carriage return
"/\n/" => '', // remove new lines
"/\t/" => '', // remove tab
"/\s+/" => ' ', // remove spaces
];
return preg_replace(array_keys($this->replace), array_values($this->replace), $htmlString);
}
```
محتوای اولیه ی فایل
`app/Http/middlewares/Minifier.php`
```php
<?php
namespace App\Http\Middleware;
use Closure;
class Minifier
{
public function handle($request, Closure $next)
{
}
}
```
#### آنچه باید برای ما بفرستید
برای حل سوال ابتدا فریم ورک لاراول را باید روی سیستم خود دانلود کنید.
در نهایت پس از اعمال تغییرات، تمامی فایل ها و فولدرهای لاراول (به جز پوشه ی vendor) را به صورت zip در آورده و آپلود کنید.
Laravel - فشردهساز HTML
همان طوری که می دانید فریم ورک لاراول برای لاگین کردن کاربر، تابع زیر را در اختیار ما قرار می دهد
```php
auth()->attempt(['email' => 'hello@gmail.com', 'password' => 123456]);
```
که تنها در صورت صحیح بودن رمز عبور ، کاربر لاگین می شود.
ما میخواهیم با تعریف یک provider جدید برای session guard و ست کردن آن در فایل config/auth.php، رفتار تابع attempt را طوری تغییر دهیم که هر پسوردی را به عنوان پسورد صحیح کاربر از ما قبول کند و یوزر لاگین شود.
با این کار برنامه نویس در مراحل کدنویسی پروژه مجبور نخواهد بود برای تست کردن پروژه اش، پسورد کاربران را به خاطر بسپارد و لاگین کردن در پنل برای او ساده تر می شود.
و در نهایت قبل از لانچ کردن پروژه از طریق فایل config/auth.phpرفتار تابع attempt را به حالت عادی باز گرداند تا با پسورد های واقعی کار کند.
# نکات
حتی الامکان از آخرین نسخه ی فریم ورک لاراول استفاده کنید.
در شروع کار جهت داشتن یک نمونه ی اولیه از UserProvider می توانید از کپی فایلی که در مسیر زیر در هسته ی لاراول وجود دارد استفاده کنید
و آن را طبق نیازتان تغییر دهید.
`/vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php`
شما مجاز به تغییر دادن و یا ایجاد هر فایل به دلخواه خودتان هستید.
#### آنچه باید آپلود کنید:
تمامی فایل ها و پوشه های فریم ورک لاراول به جز پوشه vendor را به صورت zip در آورده و آپلود کنید.
شامل پوشه های:
app, bootstrap, config, database, resources, public, routes, storage, composer.json, ...
Laravel - رمز عبور جعلی
میخواهیم یک سایت برای خودکار کردن فرایند فروش بلیتهای سینما بنویسیم.
در این سایت امکان مشاهده فیلمهای در حال اکران وجود دارد.
کاربران میتوانند عضو سایت شوند و پس از ورود به سایت
برای هر فیلم صندلی موردنظر را رزرو کند.
بخشی از این پروژه نوشته شده است. از شما میخواهیم این پروژه را تکمیل کنید.
# پروژه اولیه
پروژه اولیه را از [اینجا](http://bayanbox.ir/download/2962970233113283136/Blit-initial.zip) دانلود کنید. ساختار این پروژه به شرح زیر است:
```
cinema
├── app
│ ├── ...
│ ├── Http
│ │ └── Controllers
│ │ ├── MovieController.php
│ │ ├── StatsController.php
│ │ └── ...
│ ├── User.php
│ ├── Movie.php
│ ├── Seat.php
│ ├── Ticket.php
├── ...
├── datbase
│ ├── ...
│ ├── seeds
│ ├── migrations
│ └── ...
├── routes
│ ├── ...
│ └── web.php
...
```
# جزئیات
در این سوال لازم است علاوه بر ایجاد seed ها، تغییراتی در Controller ها و route ها ایجاد کنید.
سه مدل به شرح زیر وجود دارد:
۱. مدل `Movie` شامل فیلدهای زیر:
* `title`: نام فیلم
* `release_year`: سال میلادی انتشار فیلم
* `play_time`: زمان اکران فیلم در سالن
۲. مدل `Seat` شامل فیلد زیر:
* `number`: شماره صندلی
۳. مدل `Ticket`شامل فیلدهای زیر:
* `movie`: فیلمی که این بلیت برای آن فروخته شده است
* `user`: کاربری که این بلیت را خریده است
* `seat`: صندلی مربوط به این بلیت
* `date_bought`: تاریخی که بلیت خریده شده است
قرار است همه صندلیهای سالن و لیست فیلمها در ابتدا با استفاده از seed
به پایگاه داده اضافه شود. سپس به ازای هر بلیتی که فروخته میشود
یک شیٔ از مدل `Ticket` ساخته میشود.
مواردی که باید انجام دهید:
### ۱. نوشتن seed
از شما میخواهیم در پوشه `database/seeds` دو seed با نام کلاس
`Movies` و `Seats`
ایجاد کنید.
+ بعد از اجرای `seed` ها میخواهیم مقادیر زیر برای مدل `Movie` در دیتابیس ایجاد شده باشد:
زمان اکران را به صورت native (بدون TimeZone) تعریف کنید.
| id | نام فیلم | سال انتشار | تاریخ اکران | ساعت اکران |
|:---:|:----------:|:-------------:|:-------------:|:-------------------:|
| 1 | Children of heaven | 1997 | 2018/4/20 | 22:00 |
| 2 | About Elly | 2009 | 2018/4/20 | 20:00 |
| 3 | A separation | 2011 | 2018/4/22 | 18:00 |
| 4 | The salesman | 2016 | 2018/4/21 | 18:00 |
| 5 | The Elephant king | 2017 | 2018/4/21 | 20:00 |
+ برای `Seat` نیز میخواهیم بعد از اجرای `seed` مربوطهاش ۱۰ صندلی با آیدی ۱ تا ۱۰ و شمارهصندلی ۳۱ تا ۴۰ ایجاد شود.
توجه کنید به هنگام داوری `seed` ها با دستور
`artisan db:seed --class=CLASS_NAME`
اجرا میشوند پس حتما اسم کلاسها را مطابق اسمی که در صورت سوال گفته شده است قرار دهید.
### ۲. نمایش صندلیها
در این قسمت باید `Controller` مربوط به قسمت نمایش صندلیها را به نحوی تغییر دهید که فقط صندلیهایی که برای آن فیلم هنوز رزرو نشدهاند را نمایش دهد نه همه صندلیها را.
### ۳. رزرو صندلی
با توجه به توضیحات زیر، Controller ها را تکمیل کنید.
برای رزرو صندلی، کاربر مراحل زیر را انجام میدهد:
+ ابتدا از آدرس `/movies` بازدید میکند که لیست فیلمهایی که در حال اکران هستند
را نمایش میدهد. سپس روی فیلم مورد نظر خود کلیک کرده و صفحهی بعدی صندلیهای رزرو
نشده برای آن فیلم را نمایش میدهد. تا این مرحله کاربر نیازی به login بودن ندارد.
+ وقتی کاربر روی یکی از صندلیها کلیک کرد:
+ اگر کاربر login است، صندلی برای کاربر
رزرو شده و دوباره به صفحهی صندلیهای همان فیلم *redirect* میشود تا
بتواند صندلیهای دیگری را نیز رزرو کند.
+ اگر کاربر login نیست،
به صفحهی *login* هدایت میشود و پس از وارد شدن به سایت،
بلافاصله به صفحهی قبلی (صفحه لیست صندلیها) *redirect* میشود،
و صندلی رزرو میشود.
+ در صفحهی *login* اگر کاربر روی لینک *register* کلیک کرد و در سایت
عضو شد، باید بلافاصله پس از عضویت به طور خودکار در سایت login شود
و به صفحه لیست فیلمها *redirect* شود.
### ۴. گزارش گیری سایت
در این قسمت شما باید view مربوط به آدرس `stats` را به نحوی کامل کنید
که در پاسخ برای همه صندلیهای که حداقل
برای یک فیلم رزرو شدهاند (به ترتیب `id` صندلی)،
یک خروجی JSON به شکل زیر بازگردد:
```json
[{"seat__number": 31, "total": 3}, {"seat__number": 32, "total": 1}, ... ]
```
+ مقدار *total*، تعداد رزروهای صندلی مشخص شده است.
+ این *view* تنها باید برای افرادی که لاگین کردهاند فعال باشد و برای سایر افراد
خطای ۴۰۳ (Forbidden) برگرداند.
# نکات
+ برای حل سوال تنها فایلهایی که باید تغییر کنند فایلهای مربوط به `Controller` ها و در صورت نیاز فایل مربوط به `route` ها هستند.
+ فایلهای مربوط به `seed` ها را با اسم گفته شده در پوشه `database/seeds` قرار دهید.
+ اگر فایل `route` را تغییر دادید، نام یا آدرس `route` های موجود در فایل را تغییر ندهید. تغییراتی که شما روی پروژه انجام میدهید نباید باعث شود کاربری اصلی پروژه مختل شود.
+ همانطور که در سوال مشخص شده است، کاربر باید امکان ورود و خروج و ثبتنام در سایت را داشته باشد. برای اینکار از سیستم `Auth` از پیش آماده شده لاراول استفاده کنید و `route` های مربوطهاش را در فایل روتها اضافه کنید.
+ در قسمتهایی از سوال که گفته شده `redirect` انجام شود، حتما عملیات را به صورت `redirect` انجام دهید.
+ بدون پوشهی vendor به صورت پس از اعمال تغییرات، کل پروژه را Zip ارسال کنید.
+ نام فایل Zip اهمیت ندارد.
Laravel - فروش بلیط
[لینک دانلود پروژه اولیه](https://www.dropbox.com/s/g9musw14zoc4c5b/Form-contestant.zip?dl=0)
گروه کوه دانشگاه شریف تصمیم به گرفتن اعضای جدید کرده است. آنها میخواهند فرمی را درست کنند تا متقاضیان بتوانند اطلاعات خود را در آن وارد نمایند. برای اینکار از شما کمک میخواهند.
فرم شامل فیلد های نام، شماره دانشجویی و سال ورود به دانشگاه میباشد.
هر کدام از فیلد ها دارای شرایطی هستند:
+ در فیلد نام باید **حرف اول اسم** را **بزرگ** نوشت. در غیر اینصورت عبارت ```name is invalid``` در فیلد ```TextView``` که بالای صفحه قراردارد، نمایش داده میشود.
+ در فیلد شماره دانشجویی باید تعداد ارقام برابر با 8 باشند در غیر اینصورت عبارت ```student number is invalid``` در فیلد ```TextView``` که بالای صفحه قراردارد، نمایش داده میشود.
+ در فیلد سال ورود باید دو رقم ابتدای شماره دانشجویی با سال ورود برابر باشد (به طور مثال اگر شماره دانشجویی برابر با ```94000000``` باشد، در فیلد سال ورود نیز باید عدد ```94``` وارد شود) در غیر اینصورت عبارت ```entrance year is invalid``` در فیلد ```TextView``` که بالای صفحه قراردارد، نمایش داده میشود.
+ اگر همه فیلد ها درست پر شده بود باید عبارت ```you submit successfully``` در فیلد ```TextView``` که بالای صفحه قراردارد، نمایش داده میشود.
### نکات مهم:
+ پیغامها **پس از فشردن کلید** نمایش داده شوند.
+ اگر بیشتر از یک فیلد اشتباه پر شده بود، ارورهای آن به ترتیب در ```TextView``` نمایش داده میشوند.
+ هنگام نمایش پیغامها دقت کنید که کاراکترهای نامرئی مانند ```\n``` که بکار بردهاید، به تعداد کافی باشند. (عدم استفاده از ```\n``` برای جداکردن خطوط، درج ```\n``` قبل از خط اول یا بعد از خط آخر از خطاهای متداول هستند.)
+ درصورت خالی ماندن هریک از فیلدها، پیغامی چاپ نمیشود، اما برنامه شما در اینصورت نباید با فشردن دکمه موجود از کار بیفتد.
+ ورودی ها بصورت ارقام و حروف انگلیسی وارد میشوند.
+ **به هیچ وجه** در بخشهای دیگر پروژه تغییری اعمال نکنید.
+ برای ارسال پاسخ، دقت کنید **پوشه ```app```** موجود در ریشه فایلهای پروژه، باید **در ریشه فایل زیپ ارسالی** قراربگیرد.
ساختار فایل ارسالی(فایلهایی که باید تغییر دهید با ----> نمایش داده شده اند):
```
<Your-zip-name>.zip
app
│ .gitignore
│ app.iml
│ build.gradle
│ proguard-rules.pro
│
└───src
└───main
│ AndroidManifest.xml
│
├───java
│ └───com
│ └───example
│ └───mahsa_pc
│ └───form
│ MainActivity.java <----
│
└───res
├───drawable
├───layout
│ activity_main.xml <----
│
├───mipmap-hdpi
│
├───mipmap-mdpi
│
├───mipmap-xhdpi
│
├───mipmap-xxhdpi
│
├───mipmap-xxxhdpi
│
└───values
colors.xml
strings.xml
styles.xml
```
Android - فرم
[لینک دانلود پروژه اولیه](https://www.dropbox.com/s/5pupbir5665srh7/NumberRecognitionTest-contest.zip?dl=0)
### مرور وظایف:
+ پیادهسازی الگوی ارقام ```[0,1,2,3,4,5,6,7,8,9]``` ۲۵٪ امتیاز سوال (پیادهسازی هر عدد ٪۲.۵)
+ پیادهسازی انیمیشن برای الگوی نادرست ۱۵٪ امتیاز سوال
+ پیادهسازی روش صحیح وارد کردن اعداد (مشابه با وارد کردن الگو برای بازکردن قفل صفحه) ۵۰٪ امتیاز سوال
+ غیرفعال کردن صفحه ورود اعداد هنگام نمایش انیمیشن ۱۰٪ امتیاز سوال
محمد از اینکه هر دفعه برای زنگ زدن به کسی باید روی آن شماره لمس کند خسته شده و دلش تنوع میخواهد. حسین که به تازگی با برنامهنویسی اندروید آشنا شده است، قصد دارد به محمد کمک کند اما به دلیل تازه کار بودن برنامه را نصفه رها کرده است. حال، شما باید به وی کمک کنید تا بتواند محمد را خوشحال کند.
برنامه بدین صورت است که:
+ صفحه ای که نمایش داده میشود دارای دکمه های سفید با کد رنگ ```#FFFFFF``` است که با لمس شدن، به رنگ مشکی با کد رنگ ```000000#``` تغییر رنگ میدهند.
+ برای نوشتن هر عدد باید باید دکمه هایی که در کنار هم آن عدد را شکل میدهند، با لمس کردن به رنگ مشکی درآیند. وارد کردن عدد به این صورت است که کاربر، دست خود را برروی صفحه نمایش قرار میدهد و با کشیدن الگوی عدد موردنظر روی صفحه نمایش (بدون جدا شدن دست از صفحه نمایش)، مسیر متناظر با حرکت دست روی صفحه، به رنگ مشکی با کد رنگ ```000000#``` تغییر رنگ میدهند (مشابه با وارد کردن الگو برای باز کردن قفل صفحه گوشی) و در صورت برداشتن دست از روی صفحه نمایش:
+ درصورتیکه الگوی رسم شده معتبر باشد، عدد متناظر به ```TextView``` سبز رنگ، در پایین صفحه اضافه میشود و همه دکمه ها به رنگ سفید اولیه باز میگردند.
+ درصورتیکه الگوی رسم شده، متناظر با هیچیک از ارقام ```[0,1,2,3,4,5,6,7,8,9]``` نباشد، رنگ زمینه تمام پانزده دکمه، همراه با انیمیشنی به مرور تغییر رنگ داده و مجددا به رنگ سفید بازمیگردند.
### شمای کلی پروژه پس از تکمیل:
![پروژه کامل](http://bayanbox.ir/download/3299649379009666104/recog.gif)
[لینک دانلود درصورت بروز مشکل در نمایش گیف](http://bayanbox.ir/download/3299649379009666104/recog.gif)
### نکات مهم:
+ الگو را برای **اعداد انگلیسی** طراحی کنید و نه اعداد فارسی
+ برای ارسال پاسخ، دقت کنید **پوشه `app`** موجود در ریشه فایلهای پروژه، باید **در ریشه فایل زیپ ارسالی** قراربگیرد.
+ انیمیشن را به اندازه کافی، طولانی درنظر بگیرید. برای اطمینان میتوانید از مقدار ۴ ثانیه برای تکمیل انیمیشن استفاده کنید.
ساختار فایل ارسالی(فایلهایی که باید تغییر دهید با ----> نمایش داده شده اند):
<your-zip-name>.zip
├── app
│ ├── java
│ │ └── MainActivity <----
│ ├── res
│ │ ├── drawable
│ │ ├── layout
│ │ ├── mipmap
│ │ └── values
Android - تماس عجیب
[لینک دانلود پروژه اولیه](https://www.dropbox.com/s/h29c6vve5v0yt6i/OnlineQuessWord-contestant.zip?dl=0)
### خلاصه وظایف
+ ارتباط با سرور و فرستادن رکوئست به آن ۸٪ امتیاز سوال
+ ```encode``` کردن صحیح دادههای ارسالی به سرور ۸٪ امتیاز سوال
+ گرفتن پاسخ صحیح از سرور و نمایش آن در جای مناسب ۸٪ امتیاز سوال
+ امکان پردازش چند درخواست بطور همزمان ۱۶٪ امتیاز سوال
+ پایداری ارتباط با سرور درصورت تغییر وضعیت دستگاه (مانند چرخش) ۴۴٪ امتیاز سوال
+ پایداری محتوای مورد نمایش در رابط کاربری درصورت تغییر وضعیت دستگاه (مانند چرخش) ۱۶٪ امتیاز سوال
در این سوال شما باید یک بازی شبیه به بازی بیست سوالی (بدون محدودیت سوال) را پیادهسازی کنید. به این صورت که شما سوالات خود را تایپ و ثبت میکنید، سپس سوال خود را به آدرس سرور ارسال میکنید و پس از پردازش سوال، پاسخی متناسب از طرف سرور به شما برمیگردد (پاسخ سرور صرفا شامل یک رشته بعنوان پاسخ سوال ارسالی است و هیچ ساختار خاصی ندارد). شما باید سوالات و پاسخ ها را در قسمت بالایی صفحه، بصورت گزارشی از تاریخچه عملکرد نمایش دهید؛ به این صورت که هر سوال بلافاصله پس از لمس دکمه ```submit``` به لیست افزوده میشود، آخرین پاسخ ارسالی در ```last_answer_tv``` نمایش داده میشود و با رسیدن پاسخ جدید از سمت سرور، متن موجود در ```last_answer_tv```، به ```history_tv``` منتقل میشود و پاسخ جدید در ```last_answer_tv``` نمایش داده میشود.
# موارد مورد انتظار جهت پیادهسازی
۱- سوال کاربر باید در **EditText** با آیدی **question_et** تایپ شود و با لمس دکمه **Submit** برای پردازش، به سرور ارسال شود تا پاسخ سرور را در قالب یک رشته دریافت کند. دقت کنید **متن سوال نمیتواند خالی باشد**.
نمونه درخواست ارسالی به سرور برای پرسیدن سوال **?what is length of the word**
```
<YOUR_URL>?q=what+is+length+of+the+word%3F
```
نمونه پاسخ ارسالی سرور:
```
it contains 10 characters
```
۲- آخرین پاسخ دریافت شده از سرور باید در **TextView** با آیدی **last_answer_tv** نمایش داده شود.
۳- لیست تاریخچه سوالات کاربر و پاسخ های سرور (بجز آخرین پاسخ سرور) باید در **TextView** با آیدی **history_tv** نمایش داده شود.
۴- برنامه شما باید با تغییر جهت دستگاه، وضعیت فعلی خود (شامل اطلاعات نمایش داده شده به کاربر و اطلاعات موردنیاز جهت ادامه فعالیت بصورت صحیح) را حفظ کند.
۵- درصورتی که در هنگام ارتباط با سرور و انتظار برای پاسخ سرور، جهت دستگاه تغییر کرد (دستگاه **rotate** شد)، نباید خللی در ارتباط با سرور و دریافت پاسخ بوجود آید.
۶- درصورتی که کاربر سوالی را با استفاده از کلید *Submit* ثبت کند و پیش از پاسخگویی سرور، سوال (یا سوالات) دیگری را ثبت کند، ارسال سوالات به سرور باید در لحظه ثبت انجام شود (نباید ارسال سوال جدید و انتظار برای گرفتن پاسخ، تا زمان پاسخگویی سرور به سوال قبلی، به تعویق بیافتد).
# موارد مورد توجه هنگام پیادهسازی:
+ درخواست ها به سرور توسط متد **GET** ارسال میشوند.
+ آدرس پایهای سرور را حتما در متغیر **url** که عضو ثابت کلاس **BaseURL** میباشد،قرار دهید و زمانی که به آن نیاز داشتید، از **BaseURL.url** استفاده کنید. (از بکار گیری آدرس پایه بطور مستقیم در کد، جدا خودداری کنید).
+ به هیچ وجه آیدی (**id**) های موجود در فایل *activity_main.xml* را تغییر ندهید.
# توجه کنید که
+برای بررسی کدهای خود میتوانید از سرور محلی یا کتابخانههای موجود برای اندروید جهت شبیهسازی سرور استفاده کنید.
+ محتویات فیلد ```url`` موجود در کلاس ```BaseURL``` فقط و فقط باید حاوی آدرس پایه باشد و هیچ کاراکتر اضافهای نباید بعد از آن قرارگیرد.
مثال صحیح:
```
public static String url = "http://quera.ir/";
```
مثال غلط:
```
public static String url = "http://quera.ir/?q=";
```
+ برای ارسال پاسخ، دقت کنید **پوشه `app`** موجود در ریشه فایلهای پروژه، باید **در ریشه فایل زیپ ارسالی** قراربگیرد.
+ نوع، نام و محتویات اولیه کلاسهای موجود در فایل پایه را به هیچ وجه تغییر ندهید/حذف نکنید. (اضافه کردن بلامانع است.)
+ پروژه ارسالی شما میتواند فایل های اضافه بر فایلهای موجود در پروژه پایه داشته باشد؛ این فایل ها باید بطور مستقیم یا غیرمستقیم در پوشه ```main``` قرارگرفته باشند.
+ امکان تغییر در فایل ```manifest``` وجود دارد.
+ درصورت استفاده از کتابخانههای ثالث جهت ارتباط با سرور، کد شما توسط سیستم داوری مردود اعلام میشود.
ساختار فایل ارسالی(فایلهایی که باید تغییر دهید با ----> نمایش داده شده اند، همچنین امکان افزودن فایل به ساختار ارسالی زیر وجود دارد اما از اعمال تغییر در محتویات پوشه ```layout``` جداً خودداری کنید):
```
<your-zip-name>.zip
└───app
├───libs
└───src
└───main
│ AndroidManifest.xml
│
├───java
│ └───quera
│ └───androidchallenge
│ └───com
│ └───onlineguessword
│ │ MainActivity.java <------
│ │
│ └───models
│ BaseURL.java
│
└───res
├───drawable
│
├───drawable-v24
│
├───layout
│ activity_main.xml
│
├───mipmap-anydpi-v26
│
├───mipmap-hdpi
│
├───mipmap-mdpi
│
├───mipmap-xhdpi
│
├───mipmap-xxhdpi
│
├───mipmap-xxxhdpi
│
└───values
colors.xml
strings.xml
styles.xml
```