حتماً دیدهاید که در بخش عضویت بسیاری از وبسایتها برای امنیت بیشتر محدودیتهایی
بر روی نام کاربری و گذرواژه وجود دارد.
میخواهیم با پایتون ۳ تابعی بنویسیم که تعدادی نام کاربری و گذرواژه دریافت کند و بر اساس قواعدی
معتبر بودن آنها را بررسی کند و در نهایت لیست نامهای کاربری مجاز به عضویت را برگرداند.
# جزئیات
قواعد زیر را برای نام کاربری و گذرواژه در نظر گرفتهایم:
- نامهای کاربری `quera` و `codecup` را میخواهیم برای خودمان نگه داریم.
کسی مجاز به عضویت با این نامهای کاربری نیست.
- نام کاربری کمتر از ۴ حرف بسیار کوتاه است و مجاز نیست.
- همچنین برای امنیت کاربران، کاربری که رمز عبور او کمتر از ۶ حرف باشد یا
فقط از اعداد تشکیل شدهباشد نیز مجاز به عضویت نیست.
تابعی با نام `check_registration_rules` بنویسید که نام کاربری و گذرواژهی تعدادی کاربر را مانند نمونهی
زیر دریافت کند و در خروجی لیستی از نامهای کاربری مجاز به عضویت را برگرداند.
ترتیب اعضای لیست خروجی اهمیت ندارد.
```python
>>> check_registration_rules(username='password', sadegh='He3@lsa', quera='kLS45@l$')
['username', 'sadegh']
>>> check_registration_rules(saeed='1234567', ab='afj$L12')
[]
```
# نکات
- یک فایل Zip شامل یک فایل به نام `source.py` که تابع `check_registration_rules` در آن قرار دارد آپلود کنید.
- نام فایل Zip اهمیت ندارد.
ثبت نام
می خواهیم برنامه ای بنویسیم که با کمک آن بتوانیم فایل های خود را مدیریت کنیم.
##### نیاز هایی که باید این فایل منیجر برطرف کند عبارتند از:
* ساخت یک پوشه جدید
* ساخت یک فایل جدید
* جستجو کردن بر اساس نام فایل
* حذف فایل
* بازیابی فایل
## جزئیات
با توجه به نیازمندیهایی که در بالا گفته شد، یک کلاس با نام `FileManager` تعریف کنید که همه متدهای جدول زیر را طبق رفتار توضیح داده شده پیادهسازی کند.
| رفتار |خروجی| متد |
|:------------------:|:-------:|:-----------:|
|یک پوشه جدید با نام `name` در آدرس `address` می سازد.|`-`| `create_dir(name, address)` |
|یک فایل جدید با نام `name` در آدرس `address` ایجاد می کند .|`-`| `create_file(name, address)`|
|یک فایل با نام `name` را از آدرس `address` حذف می کند .|`-`| `delete(name, address)`|
|آدرس تمام فایل های با نام `name` را از آدرس `address` **به بعد** برمیگرداند|`List`| `find(name, address)`|
|فایل با نام `name` را بازیابی می کند.|`-`| `restore(name)`|
## نکات
* در متد `create_dir` در صورت عدم وجود پوشه باید پوشه ای جدید ساخته شود در غیر این صورت نباید هیچ اتفاقی بیفتد!
* در متد `create_file` در صورت عدم وجود فایل باید فایلی جدید ساخته شود در غیر این صورت نباید هیچ اتفاق دیگری بیفتد!
* در متد `delete` در صورت عدم وجود فایل نباید هیچ اتفاقی بیفتد
* در متد `find` باید یک لیست از تمام آدرس ها برگردانده شود ودر صورت عدم وجود فایلی با این نام یک لیست خالی برگردانده شود ترتیب این ادرس ها اهمیتی ندارد
* آدرسهای برگردانده شده از متد `find` باید از آدرس موجود در آرگومانها به بعد باشد (آدرس شامل خود آرگومان نیز میباشد)
.دقت شود که ممکن است فایل در سطوح پایین تر از سطح اول نیز موجود باشد.
* متد `restore`
* فایل بازیابی شده باید در آدرس قبلی خود قرار گیرد.
* اگر چند فایل هم نام بصورت متوالی حذف شوند باید با هربار صدا زدن متد `restore` فایلها به صورت متوالی و با عکس ترتیب حذف، بازیابی شوند.
* باید در عمل حذف و بازیابی محتوای فایل حفظ شود.
* در صورت عدم وجود فایلی برای بازیابی نباید هیچ اتفاقی بیفتد.
* برای حل این سوال می توانید هر فایل و یا پوشه دیگری که خواستید بسازید.
## نمونه
```
fm = FileManager()
fm.create_dir('test', '.')
fm.create_dir('test1', 'test')
fm.create_dir('test2', 'test/test1/')
fm.create_file('test.txt', 'test')
fm.create_file('test.txt', 'test/test1')
fm.create_file('test.txt', 'test/test1/test2')
```
#### خروجی: باید پوشه ها و فایل های زیر ایجاد شوند.
```
test
├── test1
│ ├── test2
│ │ └── test.txt
│ └── test.txt
└── test.txt
```
#### ادامه دستورات
```
print(fm.find('test.txt', 'test'))
```
#### خروجی
```
['test/test.txt', 'test/test1/test.txt', 'test/test1/test2/test.txt']
```
#### ادامه دستورات
```
fm.delete('test.txt', 'test')
fm.delete('test.txt', 'test/test1/')
fm.delete('test.txt', 'test/test1/test2')
fm.restore('test.txt')
fm.restore('test.txt')
```
#### خروجی
```
test
├── test1
├── test2
│ └── test.txt
└── test.txt
```
#### آنچه باید آپلود کنید:
یک فایل Zip شامل یک فایل به نام `source.py` که کلاس `FileManager` در آن قرار دارد آپلود کنید.
مدیریت فایلها
_در این سوال قصد داریم برای یک سایت تولید کارت پستال امکان فارسی کردن ارقام را بگذاریم._
شرکتی خدمات کارت پستال ارائه میدهد. این شرکت به تازگی سایتی ساختهاست که با وارد کردن متنی که میخواهید، میتوانید کارت پستال آن را به صورت `html` مشاهده کنید.
اما یکی از مشکلاتی که دارد ارقام انگلیسی است. به همین دلیل تصمیم گرفتهاست که تمام ارقام انگلیسی از 0 تا 9 داخل متن را، هنگام نمایش به فارسی تبدیل کند و نمایش دهد.
پروژه اولیه را میتوانید از [اینجا](http://s8.picofile.com/file/8339634018/persian_digits_initial.zip.html) دانلود کنید.
ساختار پروژه به شکل زیر است:
```
├── Company
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── postal_card
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── static
│ │ └── CSS
│ │ └── intro.css
│ ├── templates
│ │ └── postal_card.html
│ ├── templatetags
│ │ ├── __init__.py
│ │ └── filters.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
└── requirements.txt
```
### جزئیات
اپ اصلی پروژه `postal_card` است که داخل آن کدهایی که کارت پستال را تولید میکنند وجود دارد.
همچنین پروژه دارای یه `url` اصلی است که کارت پستال را تولید میکند و آدرس آن `postal_card/` است که یک پارامتر به نام `text` میگیرد و مقدار آن متن داخل کارت پستال را مشخص میکند.
برای مثال آدرسهای `postal_card/?text=this-is-card-postal1/` و `postal_card/?text=this%20is%card-postal%20with%20spaces/` به ترتیب متنهای `this-is-card-postal1` و `this is card-postal with spaces` تولید میکنند.
حال وظیفهی شما تبدیل ارقام انگلیسی داخل متن به ارقام فارسی است. به عنوان مثال متن `22 شهریور روز برنامهنویس مبارک` باید به متن `۲۲ شهریور روز برنامهنویس مبارک` تبدیل شود.
اما با توجه به اینکه نمیخواهیم به کدهای `view` و `url` مان دست بزنیم و منطق پشت کد دستنخوره باقی بماند، شما باید تغییرات را در فایلهای `templates/postal_card.html` و `templatetags/filters.py` داخل اپ `postal_card` قرار دهید.
# نکات
+ شما تنها مجاز به تغییر دو فایل گفته شده هستید و اگر تغییری در سایر فایلها ایجاد کنید، این تغییرات نادیده گرفته خواهد شد.
+ پس از اعمال تغییرات، کل پروژه را *Zip* کرده و ارسال کنید.
+ نام فایل *Zip* اهمیت ندارد.
کارت پستال
_در این سوال قصد داریم به کمک کتابخانه DjangoRestFramework یک RESTful API برای وبلاگ خود طراحی کنیم._
می خواهیم یک API برای وبلاگ خود طراحی کنیم
به طوری که کاربران بتوانند از طریق این API پست ها و کامنت های
خود را مدیریت کنند و همچنین ادمین وبلاگ بتواند
به تمام فعالیت ها نظارت داشته باشد
و در صورت لزوم دست به کار شده و خودی نشان دهد.
### پروژه اولیه
پروژه اولیه را از [اینجا](http://s8.picofile.com/file/8339634242/rest_api_initial.zip.html) دانلود کنید. ساختار این پروژه به شرح زیر است:
```
blog
├── app
│ ├── migrations
│ │ ├── __init__.py
│ │ └── 0001_initial.py
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── urls.py
│ ├── serializers.py
│ ├── permissions.py
│ └── views.py
├── Blog
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── requirements.txt
```
### جزئیات
در فایل `models.py` دو مدل به شرح زیر وجود دارد:
۱. مدل `Post` شامل فیلدهای زیر:
* نویسنده : `owner`
* عنوان : `title`
* متن پست : `body`
* زمان انتشار پست : `created`
* زمان ویرایش پست : `updated`
۲. مدل `Comment` شامل فیلدهای زیر:
* نویسنده : `owner`
* متن کامنت : `body`
* پست مربوطه : `post`
* زمان انتشار کامنت : `created`
* زمان ویرایش کامنت : `updated`
در فایل
`views.py`
چهار
`view`
به شرح زیر وجود دارد:
۱. کلاس **`PostList`**
`GET`:
لیست تمام پست ها را به صورت یک خروجی
`JSON`
به فرمت زیر بر می گرداند.
```json
[
{
"title": "test",
"body": "test_body",
"created": "2018-07-18T11:27:40.074000Z",
"owner": "admin"
},
{
"title": "test",
"body": "test_body",
"created": "2018-07-18T11:28:00.152000Z",
"owner": "test_author"
},
...
]
```
`POST`:
عنوان و متن پست را به عنوان ورودی به صورت
`JSON`
می پذیرد و در صورتی که کاربر از قبل لاگین کرده باشد یک پست جدید به نام این کاربر می سازد.
۲. کلاس **`PostDetail`**
`GET`:
جزئیات یک پست را به صورت یک خروجی
`JSON`
به فرمت زیر بر می گرداند.
لیستی از لینک کامنتهای یک پست نیز در این خروجی قرار دارد.
```json
{
"title": "test",
"body": "test_body",
"created": "2018-07-18T11:26:53.044000Z",
"updated": "2018-07-18T11:26:53.044000Z",
"owner": "admin",
"comment_set": [
"http://localhost:8000/api/comments/1/",
"http://localhost:8000/api/comments/10/"
]
}
```
`PUT`:
عنوان و متن پست را به عنوان ورودی به صورت
`JSON`
می پذیرد و در صورتی که کاربر **مالک** پست و یا **ادمین** باشد پست را ویرایش می کند.
`DELETE`:
در صورتی که کاربر **مالک** پست و یا **ادمین** باشد پست را حذف می کند.
۳. کلاس **`CommentDetail`**
`GET`:
جزئیات یک کامنت را به صورت یک خروجی
`JSON`
به فرمت زیر بر می گرداند.
لینک پست مربوطه نیز در این خروجی قرار دارد.
```json
{
"post": "http://localhost:8000/api/posts/1/",
"owner": "hamid",
"body": "test_body",
"created": "2018-07-18T11:28:47.400000Z",
"updated": "2018-07-18T11:28:47.401000Z"
}
```
`PUT`:
متن کامنت را به عنوان ورودی به صورت
`JSON`
می پذیرد و در صورتی که کاربر **مالک** کامنت و یا **ادمین** باشد کامنت را ویرایش می کند.
`DELETE`:
در صورتی که کاربر **مالک** کامنت و یا **ادمین** باشد کامنت را حذف می کند.
۴. کلاس **`AddComment`**
`POST`:
متن کامنت را به عنوان ورودی به صورت
`JSON`
می پذیرد و در صورتی که کاربر از قبل لاگین کرده باشد یک کامنت جدید به نام این کاربر و برای پست انتخاب شده می سازد.
اما کارهایی که شما باید تو این پروژه انجام بدید:
شما باید در دو فایل
**`serializers.py`**
و
**`permissions.py`**
کلاس هایی که در این
`view`
ها استفاده شده و پیاده سازی نشده اند را طوری پیاده سازی کنید که
`view`
ها طبق توضیحات داده شده عمل کنند.
### نکات
+ شما تنها مجاز به تغییر در `app/serializers.py` و `app/permissions.py` هستید.
اگر تغییری در سایر فایلها ایجاد کنید، این تغییرات نادیده گرفته خواهد شد.
+ در هر بخشی از پروژه که
`view`
ها یک ورودی به فرمت
`json`
میپذیرند، منظور فرمتی به صورت زیر است:
```json
{
"title": "test",
"body": "test_body"
}
```
### آنچه باید آپلود کنید
+ پس از اعمال تغییرات، کل پروژه را Zip کرده و ارسال کنید.
+ نام فایل Zip اهمیت ندارد.