فرهاد و سلیب در حال بازی تفاضل هستند، بازی به این گونه اجرا میشود که فرهاد به سلیب یک عدد دو رقمی میدهد و سلیب باید رقم بزرگتر این عدد را از رقم کوچکتر کم کند و نتیجه را بگوید.
از آنجایی که سلیب از دبستان کلاسهایش را میپیچاند، تفریق را بهدرستی یاد نگرفته است. اما برنامهنویس متبحری میباشد و برنامهای مینویسد که این کار را برایش انجام دهد.
حال از شما میخواهیم که همانند سلیب این برنامه را پیادهسازی کنید تا شما هم به دانش "عمل تفریق" نیازی نداشته باشید.
شما در این سوال نیاز به پیادهسازی تابعی به نام game
دارید که یک عدد را به صورت عدد ورودی میگیرد.
خروجی تابع شما باید تفاضل رقم بزرگتر ورودی از رقم کوچکتر ورودی را برگرداند.
توجه کنید که باید جواب را در تابع return
کنید و نباید آن را print
کنید و نباید چیزی را از ورودی بخوانید.
۷ بزرگتر از ۱ است پس در خروجی باید ۱-۷ یعنی ۶ چاپ شود.
وقتی دو رقم برابر با هم میباشند تفاوتشان برابر با صفر است.
۸ بزرگتر از ۱ است پس در خروجی باید ۱-۸ یعنی ۷ چاپ شود.
game
به شکل گفته شده وجود داشته باشد.فرهاد و سلیب که از بازی تفاضل خسته شده بودند، بازی جدیدی را شروع کردند.
بازی کلمهها به این صورت است که فرهاد رشتهای را به سلیب میدهد و سلیب باید کلمات خوب آن به همراه تعداد تکرارهایش را به فرهاد بدهد.
در واقع فرهاد به سلیب یک رشته میدهد که کلمات آنها با کاراکترهای Whitespace از هم جدا شدهاند؛ برای مثال اگر متن ورودی Hello SAliB!
باشد، کلمات آن Hello
و SAliB!
هستند.
از نظر فرهاد هر کاراکتری که جز حروف انگلیسی نباشد، یک حرف بد است و باید حذف شود. برای مثال کاراکترهای A
و b
حرف خوب و کاراکتر !
حرف بد هستند.
همچنین به یک کلمه بد میگوییم اگر حداقل نیمی از کاراکترهای آن بد باشند. سلیب باید به ازای هر کلمه خوب، کاراکترهای بد آن را حذف کند و سپس کاراکتر اول هر کلمه را بزرگ و دیگر کاراکترها را کوچک کند. برای مثال کلمه A!
بد است اما A!A
خوب است.
برای مثال اگر متن ورودی به صورت زیر باشد:
بعد از این عملیات رشته به صورت زیر در میآید:
توجه کنید که در این نمونه کلمه #p#r#o#b#l#e#m
بد است و حذف شده و از دیگر کلمهها فقط کاراکترهای خوبشان باقی مانده است.
در نهایت سلیب باید در قالب یک لغتنامه (Dictionary) که کلیدهای آن کلمات متن و مقادیر هر کلید، تعداد تکرار آن کلمه در متن نهایی است برگرداند.
شما باید تابعی به نام words_check
بنویسید که با گرفتن متن ورودی، لغتنامه خواسته شده را برگرداند.
s
را بر حسب کاراکترهای Whitespace جدا کنید، میتوانید از تابع s.split()
استفاده کنید.words_check
به شکل گفته شده وجود داشته باشد.سلیب که از تنهایی و خانهنشینی حوصلهاش سر رفته تصمیم گرفته که دوستانش را دعوت کند تا با آنها اسمفامیل بازی کند.
بعد از رسیدن دوستان سلیب آنها بازی را شروع کردند، اما بعد از تمام شدن دست اول در امتیازدهی دچار مشکل شدهاند. هیچکس کلمات دیگری را قبول نداشت به همین خاطر نمرهی هر کلمه نامشخص بود.
سلیب و دوستانش برنامهنویس هستند و فقط به برنامهها اعتماد دارند. به همین خاطر از شما میخواهند برایشان برنامهای بنویسید تا با دریافت فایل تمامی کلمات قابل قبول طبق قوانین ذکر شده، بتواند به او و دوستانش نمرهای صحیح بدهد.
دوستان سلیب برای این که در امتیازدهی به مشکل نخورند یک فایل CSV آماده کردند که شامل همه کلمات درست است.
این فایل با نام esm_famil_data.csv
به فرمت CSV در اختیار شما قرار دارد که میتوانید از این لینک آن را دانلود کنید.
نمونه محتوای فایلCSV:
پیشنهاد میکنیم قبل از شروع به پیادهسازی یک بار این فایل را باز کنید و محتویات آن را ببینید (اگر با باز کردن این فایل مشکل داشتید میتوانید از ابزار گوگلشیت استفاده کنید).
شما باید سه تابع با نام های ready_up
و add_participant
و calculate_all
را برای سلیب پیادهسازی کنید.
شرح کار کلی شما به این صورت است که ابتدا محتویات فایل تمامی کلمات قابل قبول را میخوانید و ذخیره میکنید، سپس پاسخهای بازیکنان را به بازی اضافه میکنید. پس از آن شروع به امتیازدهی میکنید.
ready_up
این تابع باید محتویات درون فایل CSV را خوانده و به طور دلخواه شما ذخیره کند. فایل CSV با نام esm_famil_data.csv
در کنار فایل پایتون شما قرار دارد.
add_participant
این تابع باید یک بازیکن را به بازی اضافه کند. ورودی این تابع به این صورت است:
calculate_all
این تابع در زمانی فراخوانی میشود که تمامی بازیکنان پاسخهایشان را به برنامه شما دادهاند.
وظیفه این تابع محاسبهی نمرهی همهی افراد است و پس از محاسبه باید در قالب یک دیکشنری به فرمت خواسته شده در پایان سوال نتیجه بازی را بازگردانید.
نمرهدهی در انتهای سوال به طور کامل توضیح داده شده است.
در هر فیلد ( برای مثال ghaza
) دو حالت امتیازدهی زیر را داریم:
۱- اگر برای این فیلد همهی بازیکنان جوابی را ارائه کرده باشند:
پیتزا
نوشته باشند )، ۵ امتیاز میگیرد.۲- اگر بازیکنی وجود داشته باشد که برای این فیلد پاسخی ارائه نکرده باشد:
پیتزا
نوشته باشند )، ۱۰ امتیاز میگیرد.salib
برای فیلد ghaza
پاسخ باقالیپلو
معادل باقالی پلو
ایست که در فایل esm_famil_data.csv
وجود دارد و در شرکتکننده kianoush
برای فیلد ghaza
پاسخ به پلو
معادل به پلو
ایست که در فایل esm_famil_data.csv
وجود دارد.sajjad
برای فیلد ashia
پاسخ
معادل پاسخ خالیست.آ
نمیباشد و تمامی الفها به صورت ا
میباشند. یعنی اگر شرکت کنندهای برای آیدا
نوشته باشد، به تابع شما ایدا
ورودی داده میشود.س
شروع میشود پاسخهای تمامی شرکتکنندهها با س
شروع میشود.فایل کامل شده source.py
را ارسال کنید؛ همچنین برای استفاده از کتابخانههای مختلف میتوانید همراه فایل ارسالی، فایلی به نام python_requirements.txt
در ZIP
خود بگذارید که در آن نام کتابخانههای مورد نیاز و شماره نسخهی آنها
به فرمت زیر در آن موجود باشد: (اگر شماره نسخه را ننویسید آخرین نسخهی آن
کتابخانه نصب میشود)
در نهایت یک فایل ZIP حاوی دو فایل خواسته شده را آپلود کنید.
از بین تمامی دوستان سلیب تنها سجاد برای شب در خانه مانده و بقیه رفتهاند.
بازی قبلی برای دو نفر مناسب نبود به همین دلیل بازی جدیدی ابداء کردند که دو نفری بتوانند آن را اجرا کنند.
سلیب بازی را به سمت دنیای IT پیش میبرد و به سجاد ایدهی بازی جدیدش را میگوید.
بازی آنها به این صورت است که در ابتدا مسیری از کامپیوتر سلیب به طور تصادفی به نام path
انتخاب میشود. سپس سلیب و سجاد هر یک پسوندی را برای خود انتخاب میکنند (مثلا سلیب mp4
و سجاد jpg
انتخاب میکند).
سپس کسی برندهی بازی است که در مسیر انتخاب شده و تمامی زیر مسیرهای آن بیشترین پسوند را داشته باشد اما متاسفانه سجاد میخواهد تقلب کند.
تقلب او به این صورت است که یک نام انتخاب میکند و پسوند تمامی فایلهایی که نام برابر با نام انتخابی او دارند را به پسوند انتخابی خودش تغییر میدهد.
در مثال بالا sajjad
اسم فایل و txt
پسوند فایل میباشد.
اگر سلیب jpg
و سجاد mp4
انتخاب کرده باشد سجاد برنده بازی است.
اگر سلیب mp4
و سجاد jpg
را انتخاب کرده باشد، سلیب برنده بازی است؛ اما سجاد با تقلب روی اسم about
میتواند دو فایل را به پسوند انتخابی خودش (یعنی jpg
) تغییر داده و برنده بازی شود.
ما از شما میخواهیم تابعی با نام combet
برای سجاد بنویسید تا با دریافت path
و فرمت های انتخابی سلیب و سجاد بگویید که سجاد میتواند ببرد یا خیر.
combet
این تابع به عنوان ورودی سه متغیر از نوع رشته را میپذیرد، و به عنوان خروجی تابع شما باید نتیجه بازی را بازگرداند.
توجه کنید که نتیجهی بازی بنا به قوانین زیر متغیر هستند پس قوانین را با دقت بخوانید.
۱- اگر سجاد به طور عادی برندهی بازی میشد تابع شما باید مقدار زیر را برگرداند:
۲- اگر سجاد به طور عادی برندهی بازی نمیشد، ولی میتوانست با تقلب روی اسمی برنده شود، تابع شما باید مقدار زیر را برگرداند:
توجه کنید که '{cheat_name}'
نام کلمهایست که سجاد باید روی آن تقلب کند تا ببرد برای مثال در مثال بازیای که در آن سجاد تقلب میکند
که چند خط بالاتر توضیح داده شده است، باید مقدار زیر را برگردانید:
توجه کنید که اگر سجاد با تقلب روی چندین اسم میتوانست برنده شود، میتوانید هر یک از اسمها را به دلخواه برگردانید.
۳- اگر سجاد هیچ استراتژی بردی نداشت باید مقدار زیر را برگردانید:
.
نمیباشد.SAliB.txt
همراه SAliB.mp4
وجود داشت و شما بر روی نام SAliB
تقلب کنید تعداد فایلها با پسوند انتخابی سجاد دو واحد به ازای این دو فایل اضافه میشود).rename
کردن فایلی را ندارید و تنها باید بگویید که چه کسی بازی را میبرد.shutil
یا import sh
یا from sh
یا subprocess
یا os.popen
یا os.system
باشد. سلیب که تمام بازیها را با باخت پشت سر گذاشته بود، بیخیال بازی کردن شد. او از خانه بیرون رفت تا به دنبال سرگرمی جدیدی باشد که ناگاه ردپای سجاد را بر روی زمین دید. او به دنبال آن ردپا رفت و در نهایت توانست یک شرکت جدید تاسیس کند.
شرکت سلیب از همان ابتدا برای خود هدفی پیدا کرد. این شرکت میخواهد برای خود سایتی راهاندازی کند تا بتواند مشتریهای بیشتری را جذب کند. به همین دلیل از علی و کیانوش در این راستا تقاضای کمک کرده است.
آنها هم چون در برنامهنویسی تازهکارند از شما درخواست کردهاند که این پروژه را برایشان پیادهسازی کنید.
برای این پروژه ما نیاز به یک کلاس Account
و یک کلاس Site
داریم.
Account
هر شی این کلاس دارای پنج ویژگی () است که در تابع ــinitــ
مقداردهی میشود و به ازای هر شیء مقدار آن فرق دارد:
username
یوزرنیم کاربر باید به فرمت (نام + آندر لاین + نام خانوادگی) ذخیره شود. توجه کنید که نام و نام خانوادگی فقط باید از حروف انگلیسی باشند.
در صورتی که یوزرنیم دریافتی مانند فرمت بالا نبود باید یک با متن اررور invalid username
raise کنید.
مثال:
ali_babaei
بود مشکلی ندارد.kianoush_nasr_azadani
بود باید خواسته شده را raise کنید.password
پسورد کاربر باید دارای نکات زیر باشد:
hash
) با فرمت sha256
و encode
utf-8
ذخیره شود.
در صورتی که پسورد دریافتی مانند فرمت بالا نبود باید یک با متن اررور invalid password
raise کنید.مثال:
Aa123123
بود مشکلی ندارد و صحیح است.Aa12312
AA123123
aa123123
valid نیست.user_id
کدملّی کاربر باید اعتبار سنجی شود
الگوریتم اعتبارسنجی کد ملی:
کد ملی شمارهای است ۱۰ رقمی که از سمت چپ سه رقم کد شهرستان محل صدور شناسنامه، شش رقم بعدی کد منحصربهفرد برای فرد دارندهی شناسنامه در شهرستان محل صدور و رقم آخر آن هم یک رقم کنترل است که از روی ۹ رقم سمت چپ بهدست میآید. برای بررسی کنترل کد کافیست مجدد از روی ۹ رقم سمت چپ رقم کنترل را محاسبه کنیم
۱- برای محاسبهی رقم کنترل از روی سایر ارقام، هر رقم را در موقعیت آن ضرب کرده و حاصل را با هم جمع میکنیم.
۲- مجموع بهدست آمده از مرحله یک را بر ۱۱ تقسیم میکنیم.
۳- اگر باقیمانده کمتر از ۲ باشد، رقم کنترل باید برابر باقیمانده باشد در غیر اینصورت رقم کنترل باید برابر یازده منهای باقیمانده باشد.
مثال : آیا کد ۷۷۳۱۶۸۹۹۵۱ یک کد ملی معتبر است؟
حاصل جمع ضرب ارقام ۲ الی ۱۰ را در موقعیت آنها محاسبه میکنیم:
۱۰+۲۷+۳۶+۴۰+۳۶+۷+۲۴+۶۳+۷۰ = ۳۱۳
باقیمانده تقسیم ۳۱۳ بر ۱۱ = ۵
چون باقیمانده برابر با ۵ و بزرگتر یا مساوی ۲ است پس باید رقم کنترل این کد برابر ۶(یازده منهای پنج برابر است با شش)باشد.
در صورتی که کدملّی دریافتی مانند فرمت بالا نبود باید یک با متن اررور invalid code melli
raise کنید.
مثال:
0024848484
بود مشکلی نداشته و valid است.0024848483
valid نیست.phone
شماره تلفن کاربر ممکن است به دو فرمت به شما داده شود:
۱- +989xxxxxxxxx
۲- 09xxxxxxxxx
اگر شماره صحیح بود در هر حالتی شما باید آن را به صورت 09xxxxxxxxx
ذخیره کنید،
و در صورتی که شماره موبایل دریافتی مانند فرمت بالا نبود باید یک با متن اررور invalid phone number
raise کنید.
مثال:
09121212121
باشد مشکلی ندارد.08121212121
, 0912121212
, +988121212121
, +98912121212
باشد valid نیست.email
تضمین میشود ایمیل ورودی به فرمت First_Part@Second_Part.Third_Part
به شما داده میشود.
ایمیل کاربر باید صحیح باشد، ایمیلی را صحیح مینامیم اگر و فقط اگر:
First_Part
و Second_Part
تنها شامل حروف بزرگ و کوچک، اعداد، _
، -
، .
باشد و تضمین میشود نیازی به چک کردن محدودیت طولی بخش اول و دوم ندارید.Third_Part
باید تنها شامل حروف بزرگ و کوچک باشد و طولی میان ۲ تا ۵ کاراکتر داشته باشد.در صورتی که ایمیل دریافتی مانند فرمت بالا نبود باید یک با متن اررور invalid email
raise کنید.
show_welcome
این تابع بر اساس آنچه به عنوان کد اولیه پیادهسازی شده است شما باید آن را به نحوی پیادهسازی کنید که در ابتدا نام کاربری شخص (username
) را که شامل آندرلاین است را برداشته و به جای آن space
قرار داده و حروف اول آن را به صورت capital (بزرگ) بنویسد.؛
اگر طول این کلمه بیشتر از ۱۵ کاراکتر باشد (به همراه کاراکتر فاصله) هم ادامه آن را حذف کرده و به آخر آن ...
قرار دهد و در آخر تابع welcome
فراخوانی کند.
مثال:
verify_change_password
این تابع به عنوان کد اولیه پیادهسازی شده است و شما تنها نیاز است که اگر پسورد قبلی شما با old_password
یکسان بود پسورد جدید را برای user
قرار دهد و در آخر تابع change_password
را فراخوانی کند.
set_new_password
باشد که پسورد یوزر را عوض میکند(در این مرحله نیز باید چک کنید پسورد جدید دارای نکات گفته شده باشد و اگر بود باید آن را به صورت هش ذخیره کنید)Site
هر شی این کلاس دارای سه ویژگی () است که در تابع ــinitــ
مقداردهی میشود و به ازای هر شیء مقدار آن فرق دارد:
url
🔗تضمین میشود آدرس سایت صحیحی به شما داده میشود و نیازی به چک کردن آن ندارید.
register_users
🔗در هنگام ساخت شیء این مقدار را برابر با یک لیست خالی قرار دهید.
active_users
🔗در هنگام ساخت شیء این مقدار را برابر با یک لیست خالی قرار دهید.
register
کلاس سایت باید دارای تابعی به نام register
باشد. این تابع یک شیء از کلاس یوزر ورودی میگیرد و اگر آن یوزر در register_users
خود سایت بود یک با متن ارور user already registered
raise کنید وگرنه آن را به لیست register_users
خود سایت بیفزایید و عبارت register successful
را برگردانید.
توجه کنید که لیست register_users
باید به ترتیب ثبتنام کاربران، آنها را در خود ذخیره کند.
login
کلاس سایت باید دارای تابعی به نام login
باشد. این تابع ورودیهای متفاوتی میگیرد:
۱- ممکن است email
و username
و password
به آن داده شود. در این حالت شما باید چک کنید یوزری در register_users
سایت وجود دارد که هم یوزرنیم و هم ایمیلی برابر با ورودی داشته باشد و پسوردش برابر با هش شدهی پسورد ورودی باشد یا خیر.
۲- ممکن است username
و password
به آن داده شود. در این حالت شما باید چک کنید یوزری در register_users
سایت وجود دارد که یوزرنیمی برابر با ورودی داشته باشد و پسوردش برابر با هش شدهی پسورد ورودی باشد یا خیر.
۳- ممکن است email
و password
به آن داده شود. در این حالت شما باید چک کنید یوزری در register_users
سایت وجود دارد که ایمیلی برابر با ورودی داشته باشد و پسوردش برابر با هش شدهی پسورد ورودی باشد یا خیر.
active_users
اضافه کنید و عبارت login successful
را برگردانید. active_users
موجود بود باید عبارت user already logged in
را برگردانید.register_users
نبودند باید عبارت invalid login
را برگردانید.توجه کنید که لیست active_users
باید به ترتیب ورود کاربران، آنها را در خود ذخیره کند.
logout
کلاس سایت باید دارای تابعی به نام logout
باشد. این تابع یک شیء از کلاس یوزر ورودی میگیرد و اگر آن یوزر در active_users
خود سایت بود آن را از لیست حذف کرده و عبارت logout successful
را برگردانید و در صورت عدم وجود آن یوزر در active_users
سایت عبارت user is not logged in
را برگردانید.
Account
و Site
و دکوراتورها به شکل گفته شده وجود داشته باشد.