ثبت نام


حتماً دیده‌اید که در بخش عضویت بسیاری از وب‌سایت‌ها برای امنیت بیشتر محدودیت‌هایی بر روی نام کاربری و گذرواژه وجود دارد.

می‌خواهیم با پایتون ۳ تابعی بنویسیم که تعدادی نام کاربری و گذرواژه دریافت کند و بر اساس قواعدی معتبر بودن آن‌ها را بررسی کند و در نهایت لیست نام‌های کاربری مجاز به عضویت را برگرداند.

جزئیات🔗

قواعد زیر را برای نام کاربری و گذرواژه در نظر گرفته‌ایم:

  • نام‌های کاربری quera و codecup را می‌خواهیم برای خودمان نگه داریم. کسی مجاز به عضویت با این نام‌های کاربری نیست.
  • نام کاربری کمتر از ۴ حرف بسیار کوتاه است و مجاز نیست.
  • همچنین برای امنیت کاربران، کاربری که رمز عبور او کمتر از ۶ حرف باشد یا فقط از اعداد تشکیل شده‌باشد نیز مجاز به عضویت نیست.

تابعی با نام check_registration_rules بنویسید که نام کاربری و گذرواژه‌ی تعدادی کاربر را مانند نمونه‌ی زیر دریافت کند و در خروجی لیستی از نام‌های کاربری مجاز به عضویت را برگرداند. ترتیب اعضای لیست خروجی اهمیت ندارد.

>>> check_registration_rules(username='password', sadegh='He3@lsa', quera='kLS45@l$')
['username', 'sadegh']

>>> check_registration_rules(saeed='1234567', ab='afj$L12')
[]
Python

نکات🔗

  • یک فایل 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')
Plain text

خروجی:‌ باید پوشه ها و فایل های زیر ایجاد شوند.🔗

test
├── test1
│   ├── test2
│   │   └── test.txt
│   └── test.txt
└── test.txt
Plain text

ادامه دستورات🔗

print(fm.find('test.txt', 'test'))
Plain text

خروجی🔗

['test/test.txt', 'test/test1/test.txt', 'test/test1/test2/test.txt']
Plain text

ادامه دستورات🔗

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')
Plain text

خروجی🔗

test
├── test1
   ├── test2
   │   └── test.txt
   └── test.txt
Plain text

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

یک فایل Zip شامل یک فایل به نام source.py که کلاس‌ FileManager در آن قرار دارد آپلود کنید.

کارت پستال


در این سوال قصد داریم برای یک سایت تولید کارت پستال امکان فارسی کردن ارقام را بگذاریم.

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

اما یکی از مشکلاتی که دارد ارقام انگلیسی است. به همین دلیل تصمیم گرفته‌است که تمام ارقام انگلیسی از 0 تا 9 داخل متن را، هنگام نمایش به فارسی تبدیل کند و نمایش دهد.

پروژه اولیه را می‌توانید از اینجا دانلود کنید.

ساختار پروژه به شکل زیر است:

├── 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
Plain text

جزئیات🔗

اپ اصلی پروژه 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 اهمیت ندارد.

بلاگ API


در این سوال قصد داریم به کمک کتابخانه DjangoRestFramework یک RESTful API برای وبلاگ خود طراحی کنیم.

می خواهیم یک API برای وبلاگ خود طراحی کنیم به طوری که کاربران بتوانند از طریق این API پست ها و کامنت های خود را مدیریت کنند و همچنین ادمین وبلاگ بتواند به تمام فعالیت ها نظارت داشته باشد و در صورت لزوم دست به کار شده و خودی نشان دهد.

پروژه اولیه🔗

پروژه اولیه را از اینجا دانلود کنید. ساختار این پروژه به شرح زیر است:

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
Plain text

جزئیات🔗

در فایل models.py دو مدل به شرح زیر وجود دارد:

۱. مدل Post شامل فیلدهای زیر:

  • نویسنده :‌ owner
  • عنوان :‌‌ title
  • متن پست :‌ body
  • زمان انتشار پست :‌ created
  • زمان ویرایش پست :‌ updated

۲. مدل Comment شامل فیلدهای زیر:

  • نویسنده :‌ owner
  • متن کامنت : body
  • پست مربوطه : post
  • زمان انتشار کامنت :‌ created
  • زمان ویرایش کامنت : updated

در فایل views.py چهار view به شرح زیر وجود دارد:

۱. کلاس PostList

GET: لیست تمام پست ها را به صورت یک خروجی 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"
    },
    ...
]
JSON

POST: عنوان و متن پست را به عنوان ورودی به صورت JSON می پذیرد و در صورتی که کاربر از قبل لاگین کرده باشد یک پست جدید به نام این کاربر می سازد.

۲. کلاس PostDetail

GET: جزئیات یک پست را به صورت یک خروجی 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/"
    ]
}
JSON

PUT: عنوان و متن پست را به عنوان ورودی به صورت JSON می پذیرد و در صورتی که کاربر مالک پست و یا ادمین باشد پست را ویرایش می کند.

DELETE: در صورتی که کاربر مالک پست و یا ادمین باشد پست را حذف می کند.

۳. کلاس CommentDetail

GET: جزئیات یک کامنت را به صورت یک خروجی 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"
}
JSON

PUT: متن کامنت را به عنوان ورودی به صورت JSON می پذیرد و در صورتی که کاربر مالک کامنت و یا ادمین باشد کامنت را ویرایش می کند.

DELETE: در صورتی که کاربر مالک کامنت و یا ادمین باشد کامنت را حذف می کند.

۴. کلاس AddComment

POST: متن کامنت را به عنوان ورودی به صورت JSON می پذیرد و در صورتی که کاربر از قبل لاگین کرده باشد یک کامنت جدید به نام این کاربر و برای پست انتخاب شده می سازد.

اما کارهایی که شما باید تو این پروژه انجام بدید:

شما باید در دو فایل serializers.py و permissions.py کلاس هایی که در این view ها استفاده شده و پیاده سازی نشده اند را طوری پیاده سازی کنید که view ها طبق توضیحات داده شده عمل کنند.

نکات🔗

  • شما تنها مجاز به تغییر در app/serializers.py و app/permissions.py هستید. اگر تغییری در سایر فایل‌ها ایجاد کنید، این تغییرات نادیده گرفته خواهد شد.
  • در هر بخشی از پروژه که view ها یک ورودی به فرمت json می‌پذیرند،‌ منظور فرمتی به صورت زیر است:
{
  "title": "test",
  "body": "test_body"
}
JSON

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

  • پس از اعمال تغییرات، کل پروژه را Zip کرده و ارسال کنید.
  • نام فایل Zip اهمیت ندارد.