*سلیب* پس از پیدا کردن سایت موردنظر در میان انبوهی از وبسایتهای خروجی مسئلهی قبل، به جزیره رسید و نقشهی گنج را پیدا کرد. پس از باز کردن نقشه، متوجه شد که نقشه به زبان عجیب و غریبی (احتمالاً عبری) نوشته شده و قادر به ترجمهی آن نیست. او که میدانست محال است بتواند نقشه را خودش ترجمه کند، به دنبال فردی با دانش عبری گشت. *سلیب* پس از پرسوجوهای فراوان با *علی* روبهرو شد که قبول کرد نقشه را برای او ترجمه کند؛ اما در ازای این کار، از او خواست تا تسک *iteration* فعلی او را برایش انجام دهد. *سلیب* هماکنون از شما درخواست انجام تسک پاکسازی و بهینه کردن ساختار ردیس شرکت *علی* را دارد.
# جزئیات پروژه
برای دانلود پروژهی اولیه روی [این لینک](/contest/assignments/68134/download_problem_initial_project/234211/) کلیک کنید.
برای انجام تسک شرکت *علی* نیاز به نوشتن **یک اسکریپت** به زبان `bash` دارید و اسکریپت شما باید ۴ سطح از پاکسازی که در ادامهی مسئله با جزئیات بیشتری توضیحشان میدهیم را روی دیتای ردیس فعلیشان انجام دهد.
برای حل این تمرین نیاز به دانش کار با دستور `redis-cli` را دارید که داکیومنتیشن آن را در [این لینک](https://redis.io/docs/latest/develop/get-started/) میتوانید مطالعه کنید، همچنین جهت آشنایی با تمامی داده ساختارهای موجود در ردیس هم از [این لینک](https://redis.io/docs/latest/develop/data-types/) کمک بگیرید.
<details class="blue">
<summary> **پاکسازی نوع اول** </summary>
در این سطح، نیاز است **تمامی کلیدهایی** از ردیس که شامل حداقل یک کاراکتر کوچک زبان انگلیسی است را به فرم بزرگ تغییر دهد. برای مثال اگر ردیس ما شامل کلیدهای زیر است:
```bash terminal bash
redis:6379> KEYS *
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
redis-key1
Redis-Key2
Redis-KEY3
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
```
پس از اجرای اسکریپت شما باید به شکل زیر تغییر کنند:
```bash terminal bash
redis:6379> KEYS *
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
REDIS-KEY1
REDIS-KEY2
REDIS-KEY3
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
```
اسکریپت شما پس از تغییر هر کلید باید عبارتی به فرم زیر به فایل `output.txt` **اضافه کند.**
```text output.txt text
Renamed key: <mark class="yellow" title="کلید قدیمی">OLD_KEY</mark> -> <mark class="yellow" title="کلید جدید">NEW_KEY</mark>
```
برای مثال، پس از اجرای اسکریپت روی مثال بالا، محتوای فایل `output.txt` شامل محتوای زیر باشد:
```text output.txt text
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
Renamed key: redis-key1 -> REDIS-KEY1
Renamed key: Redis-Key2 -> REDIS-KEY2
Renamed key: Redis-KEY3 -> REDIS-KEY3
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
```
**توجه داشته باشید تحت این عملیات پاکسازی مقدار هیچ کلیدی از ردیس نباید تغییر کند، یعنی پاکسازی شما نباید بههیچوجه باعث از دست رفتن دیتای موجود شود.**
**نکته پیرامون حفظ دیتا:** ممکن است هنگامیکه شما کلید را بهصورت *uppercase* مینویسید، کلید جدید در ردیس وجود داشته باشد. در این صورت، **تا زمانی که به کلیدی که در ردیسمان وجود نداشته باشد نرسیدهایم،** عبارت `DUPLICATE` را به انتهای کلید جدید اضافه میکنیم. برای مثال اگر ردیس ما شامل کلیدهای زیر باشد:
```bash terminal bash
redis:6379> KEYS *
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
redis-key1
REDIS-KEY1DUPLICATE
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
```
اسکریپت شما باید کلید `redis-key1` را به `REDIS-KEY1DUPLICATEDUPLICATE` تغییر دهد. یعنی پس از اجرای اسکریپت شما وضعیت کلیدهای ردیس مانند زیر خواهد بود:
```bash terminal bash
redis:6379> KEYS *
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
REDIS-KEY1DUPLICATE
REDIS-KEY1DUPLICATEDUPLICATE
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
```
و همچنین محتوای فایل `output.txt` شامل محتوای زیر باشد:
```text output.txt text
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
Renamed key: redis-key1 -> REDIS-KEY1DUPLICATEDUPLICATE
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
```
</details>
<details class="blue">
<summary> **پاکسازی نوع دوم** </summary>
در این سطح، نیاز است تا **تمامی مقادیری** از ردیس که بهصورت رشته هستند و با کاراکتر `[` شروع و با کاراکتر `]` تمام میشوند را بهصورت لیست در ردیس ذخیره کند. همچنین پس از تغییر هر مقدار باید عبارتی به فرم زیر به فایل `output.txt` **اضافه کند.**
```text output.txt text
Parsed list for key: <mark class="yellow" title="کلیدی که مقدار آن تغییر یافته">KEY</mark>
```
برای مثال، اگر ردیس ما شامل مقداری مانند زیر است:
```bash terminal bash
redis:6379> GET TEST_KEY
"[a, b, c]"
```
پس از اجرای اسکریپت شما باید مقدار کلید مذکور بهصورت دادهساختار لیست پیادهسازیشده در ردیس ذخیره شده باشد و بتوانیم مانند دستور زیر به محتوای آن دسترسی داشته باشیم:
```bash terminal bash
redis:6379> LRANGE TEST_KEY 0 -1
1) "a"
2) "b"
3) "c"
```
برای مثال پس از اجرای اسکریپت روی مثال بالا، محتوای فایل `output.txt` شامل محتوای زیر باشد:
```text output.txt text
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
Parsed list for key: TEST_KEY
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
```
**توجه داشته باشید که اسکریپت شما باید ترتیب لیست را حفظ کند و تغییر در ترتیب مقدار مجاز نیست.**
**توجه داشته باشید که اگر درون مقدار کاراکتر گیومه** (`"`) **وجود داشت، این کاراکتر باید از مقدار جدید حذف شود.**
</details>
<details class="blue">
<summary> **پاکسازی نوع سوم** </summary>
در این سطح، نیاز است تا **تمامی مقادیری** از ردیس که بهصورت رشته هستند و با کاراکتر `(` شروع و با کاراکتر `)` تمام میشوند را بهصورت ست در ردیس ذخیره کند. همچنین پس از تغییر هر مقدار باید عبارتی به فرم زیر به فایل `output.txt` **اضافه کند.**
```text output.txt text
Parsed set for key: <mark class="yellow" title="کلیدی که مقدار آن تغییر یافته">KEY</mark>
```
برای مثال اگر ردیس ما شامل مقداری مانند زیر است:
```bash terminal bash
redis:6379> GET TEST_KEY
"(a, b, c)"
```
پس از اجرای اسکریپت شما باید مقدار کلید مذکور بهصورت دادهساختار ست پیادهسازیشده در ردیس ذخیره شده باشد و بتوانیم مانند دستور زیر به محتوای آن دسترسی داشته باشیم:
```bash terminal bash
redis:6379> SMEMBERS TEST_KEY
1) "a"
2) "b"
3) "c"
```
برای مثال، پس از اجرای اسکریپت روی مثال بالا، محتوای فایل `output.txt` شامل محتوای زیر باشد:
```text output.txt text
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
Parsed set for key: TEST_KEY
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
```
**توجه داشته باشید که اگر درون مقدار کاراکتر گیومه** (`"`) **وجود داشت، این کاراکتر باید از مقدار جدید حذف شود.**
</details>
<details class="blue">
<summary> **پاکسازی نوع چهارم** </summary>
در این سطح، نیاز است **تمامی مقادیری** از ردیس که بهصورت رشته هستند و با کاراکتر `{` شروع و با کاراکتر `}` تمام میشوند را بهصورت هش در ردیس ذخیره کند. همچنین پس از تغییر هر مقدار باید عبارتی به فرم زیر به فایل `output.txt` **اضافه کند.**
```text output.txt text
Parsed map for key: <mark class="yellow" title="کلیدی که مقدار آن تغییر یافته">KEY</mark>
```
برای مثال اگر ردیس ما شامل مقداری مانند زیر است:
```bash terminal bash
redis:6379> GET TEST_KEY
"{a:b, c:d, e:f}"
```
پس از اجرای اسکریپت شما باید مقدار کلید مذکور بهصورت دادهساختار لیست پیادهسازیشده در ردیس ذخیره شده باشد و بتوانیم مانند دستور زیر به محتوای آن دسترسی داشته باشیم:
```bash terminal bash
redis:6379> HGETALL TEST_KEY
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
redis:6379> HGET TEST_KEY a
"b"
```
برای مثال پس از اجرای اسکریپت روی مثال بالا، محتوای فایل `output.txt` شامل محتوای زیر باشد:
```text output.txt text
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
Parsed map for key: TEST_KEY
<mark class="blue" title="ممکن است ادامه داشته باشد.">...</mark>
```
**توجه داشته باشید که اسکریپت شما باید ترتیب لیست را حفظ کند و تغییر در ترتیب مقدار مجاز نیست.**
**توجه داشته باشید که اگر درون مقدار کاراکتر گیومه** (`"`) **وجود داشت، این کاراکتر باید از مقدار جدید حذف شود.**
</details>
<details class="yellow">
<summary> **نمونه خروجی** </summary>
برای اجرای نمونه نیاز به نصب داکر در سیستم خود دارید. نیازی نیست تا شما درون محتوای فایلهای داکر پروژه هیچ تغییری ایجاد کنید.
درون پروژه اولیه فایلهایی جهت تست اسکریپت شما تهیه شده که در ادامه نحوه کار با هرکدام را بررسی میکنیم. ابتدا اسکریپت خود را در فایل `fixer.sh` پیادهسازی کنید. سپس با استفاده از دستور زیر کانتینرهای پروژه اولیه را بالا بیاورید:
```terminal Terminal terminal
$ docker-compose up --build -d
```
پس از اتمام اجرای دستور بالا، دستور زیر را اجرا کنید. این دستور محتوای موجود در فایل `redis-data.txt` را به درون ردیس در حال اجرا میریزد.
```terminal Terminal terminal
$ pip install redis
$ python redis-filler.py
```
<details class="blue">
<summary> **نام کلید و مقدار هر کلید در ردیس نمونه** </summary>
ساختار زیر به صورت `"key":"value"` است:
```
test1:1
test2:2
TEST1:TEST1
12345:12345
Test6:Test6
tEsT7:tEsT7
test8:[a,b,c]
test9:(a,b,c)
test10:{a:b,c:d}
```
یعنی مقدار کلید `test1` برابر با `1` است.
</details>
پس از اتمام اجرای دستور بالا، باید اسکریپت خود را اجرا کنید. برای این کار از دستور زیر استفاده کنید:
```terminal Terminal terminal
$ docker exec -it fixer ./fixer.sh
```
حال باید اسکریپت شما اجرا شده باشد و در فایل `output.txt` محتوای زیر قابل مشاهده باشد:
```text output.txt text
Renamed key: test10 -> TEST10
Parsed map for key: TEST10
Renamed key: test8 -> TEST8
Parsed list for key: TEST8
Renamed key: test2 -> TEST2
Renamed key: test9 -> TEST9
Parsed set for key: TEST9
Renamed key: Test6 -> TEST6
Renamed key: tEsT7 -> TEST7
Renamed key: test1 -> TEST1DUPLICATE
```
توجه داشته باشید که ترتیب خروجی برای سیستم داوری اهمیتی ندارد و تنها نیاز است تا تمامی موارد به هر ترتیب دلخواهی حتما در خروجی وجود داشته باشند.
پس از اتمام اجرای تست، **حتما** دستور زیر را اجرا کنید تا تمامی کانتینرها متوقف شوند:
```terminal Terminal terminal
$ docker-compose down
```
</details>
# نکات تکمیلی
* فراموش نکنید که در تمامی تمرینها نیاز است تا تمام کاراکترهای `"` از مقدارهایی که توسط اسکریپت شما تغییر میکنند، حذف شود.
* اولویت اجرا از پاکسازی نوع اول به چهارم است، یعنی ممکن است که ابتدا کلید را به صورت *uppercase* تغییر بدهیم (پاکسازی نوع اول) و سپس بفهمیم که مقدار **کلید جدیدی که به صورت** *uppercase* ذخیره کردهایم نیاز به ذخیرهسازی بهصورت لیست در ردیس را داشته باشد.
* باقی کلیدهای موجود در ردیس نباید توسط اسکریپت شما تغییری کنند.
* **برای اتصال به ردیس در اسکریپت خود باید به هاست** `redis` **وصل شوید.**
## نکات مهم
+ فراموش نکنید که اسکریپتی کامل را در پاسختان تحویل دهید.
+ فراموش نکنید که اسکریپت خود را درون فایلی با نام `fixer.sh` وارد نمایید.
+ برای ارسال پاسخ خود کافیست فایل `fixer.sh` را آپلود کنید.
ارسال پاسخ برای این سؤال
در حال حاضر شما دسترسی ندارید.