اگر مفهوم شرط، حلقه، تابع، لیست و دیکشنری را دیدهاید اما هنگام نوشتن برنامه نمیدانید از کجا شروع کنید، این ده تمرین پایتون برای شماست. از جمع چند مقدار شروع میکنیم و به گزارش مطالعه میرسیم. هر مسئله ورودی مشخص، پاسخ قابل اجرا و چند حالت بررسی دارد.
روش کار: ابتدا صورت مسئله را بخوانید و خودتان راهحل بنویسید. بعد پاسخ را ببینید، تفاوتها را توضیح دهید و دستکم یک ورودی تازه امتحان کنید. حفظکردن پاسخ جای تمرین مستقل را نمیگیرد.
کدها با پایتون ۳ و کتابخانهٔ استاندارد اجرا میشوند و بستهٔ اضافی لازم ندارند. فایل پاسخها و بررسی خودکار را دانلود کنید. در پوشهٔ بازشده دستور زیر را اجرا کنید:
python solutions.pyاگر دستور python در سیستم شناخته نمیشود، نصب و مسیر پایتون را بررسی کنید؛ در ویندوز ممکن است دستور py solutions.py در دسترس باشد. اجرای موفق فایل پیام All exercise checks passed. میدهد.
قبل از شروع: چاپ با بازگرداندن نتیجه فرق دارد
تابعها در این تمرین نتیجه را با return برمیگردانند. دستور print فقط آن را نمایش میدهد. هر assert یک انتظار مشخص را بررسی میکند؛ اگر شرط نادرست باشد خطا میگیرید و باید ورودی و نتیجه را بررسی کنید.
تمرین 1: جمع هزینههای تمرینی
تابعی بنویسید که فهرستی از مبلغهای صحیح نامنفی را جمع کند. فهرست خالی باید صفر بدهد.
پاسخ و توضیح
def total_cost(amounts):
total = 0
for amount in amounts:
total += amount
return totalمقدار اولیهٔ جمع صفر است. هر عضو فقط یک بار به آن اضافه میشود؛ return باید بعد از پایان حلقه باشد.
ورودیهای بررسی:
assert total_cost([120, 80, 50]) == 250
assert total_cost([]) == 0تمرین 2: زوج یا فرد بودن عدد
برای یک عدد صحیح، تابعی بسازید که زوجبودن آن را با مقدار True یا False برگرداند. صفر و عدد منفی را هم امتحان کنید.
پاسخ و توضیح
def is_even(number):
return number % 2 == 0باقیماندهٔ تقسیم بر دو ملاک است؛ صفر هم زوج است. تابع نتیجه را برمیگرداند و چاپ را به استفادهکننده واگذار میکند.
ورودیهای بررسی:
assert is_even(0) is True
assert is_even(-4) is True
assert is_even(7) is Falseتمرین 3: فیلتر نمرههای قبول
از یک فهرست نمرهٔ معتبر بین صفر و بیست، نمرههای حداقل ده را با همان ترتیب برگردانید. مرز ده را فراموش نکنید.
پاسخ و توضیح
def passing_scores(scores):
result = []
for score in scores:
if score >= 10:
result.append(score)
return resultفهرست جدید میسازیم تا ورودی تغییر نکند. شرط بزرگتر یا مساوی باعث میشود نمرهٔ ده نیز قبول باشد.
ورودیهای بررسی:
assert passing_scores([9, 10, 18]) == [10, 18]
assert passing_scores([]) == []تمرین 4: بیشترین عدد بدون max
بیشترین عدد فهرست را پیدا کنید. برای فهرست خالی None برگردانید. ورودی میتواند فقط عدد منفی داشته باشد.
پاسخ و توضیح
def largest(numbers):
if not numbers:
return None
best = numbers[0]
for number in numbers[1:]:
if number > best:
best = number
return bestشروع از صفر برای فهرست اعداد منفی اشتباه است. عضو اول مبنا قرار میگیرد و ورودی خالی پیش از دسترسی به آن کنترل میشود.
ورودیهای بررسی:
assert largest([-8, -3, -12]) == -3
assert largest([5]) == 5
assert largest([]) is Noneتمرین 5: شمارش واژههای جداشده با فاصله
تعداد بخشهای غیرخالی متن را که با فاصله، تب یا خط جدید جدا شدهاند پیدا کنید. این تمرین تحلیل زبان طبیعی نیست.
پاسخ و توضیح
def word_count(text):
return len(text.split())متد split بدون آرگومان، فاصلههای متوالی را یک جداکننده در نظر میگیرد. نیمفاصلهٔ داخل واژه جداکننده نیست؛ نشانهگذاری نیز مستقلاً تحلیل نمیشود.
ورودیهای بررسی:
assert word_count("سلام پایتون") == 2
assert word_count(" ") == 0
assert word_count("میروم خانه") == 2تمرین 6: حذف تکراریها با حفظ ترتیب
از فهرست نامها فقط اولین رخداد هر نام را نگه دارید. ترتیب را تغییر ندهید و ورودی اصلی را دست نزنید.
پاسخ و توضیح
def unique_names(names):
result = []
for name in names:
if name not in result:
result.append(name)
return resultعضویت را پیش از افزودن بررسی میکنیم. این راه برای فهم مسئله ساده است؛ در فهرستهای بزرگ، جستوجوی تکراری در لیست هزینه دارد و میتوان یک set کمکی هم داشت.
ورودیهای بررسی:
assert unique_names(["Sara", "Ali", "Sara"]) == ["Sara", "Ali"]
assert unique_names([]) == []تمرین 7: فراوانی هر واژه
تعداد تکرار هر واژهٔ جداشده با فاصله را در دیکشنری نگه دارید. تفاوت حروف بزرگ و کوچک انگلیسی را نادیده بگیرید.
پاسخ و توضیح
def word_frequencies(text):
counts = {}
for word in text.lower().split():
counts[word] = counts.get(word, 0) + 1
return countsکلید دیکشنری واژه است و مقدار آن شمارنده. اگر کلید هنوز وجود نداشته باشد get مقدار صفر میدهد. «سلام» و «سلام،» در این نسخه دو کلید متفاوتاند.
ورودیهای بررسی:
assert word_frequencies("Code code learn") == {"code": 2, "learn": 1}
assert word_frequencies("") == {}تمرین 8: تبدیل متن به عدد صحیح
رشتهٔ ورودی را به عدد صحیح تبدیل کنید. اگر تبدیل ممکن نبود، None بدهید؛ صفر یک نتیجهٔ معتبر است.
پاسخ و توضیح
def parse_integer(text):
try:
return int(text.strip())
except ValueError:
return Noneفقط خطای مورد انتظار ValueError را میگیریم. عدد اعشاری متنی مثل 3.5 در این قرارداد معتبر نیست. ورودی این تابع باید رشته باشد.
ورودیهای بررسی:
assert parse_integer(" 0 ") == 0
assert parse_integer("-12") == -12
assert parse_integer("3.5") is None
assert parse_integer("abc") is Noneتمرین 9: میانگین با ورودی خالی
میانگین اعداد فهرست را حساب کنید. وقتی دادهای وجود ندارد None بدهید تا با میانگین واقعی صفر اشتباه نشود.
پاسخ و توضیح
def average(numbers):
if not numbers:
return None
return sum(numbers) / len(numbers)بررسی خالیبودن قبل از تقسیم، جلوی تقسیم بر صفر را میگیرد. نتیجه معمولاً اعشاری است؛ برای گزارشهای واقعی سیاست گردکردن را جداگانه تعیین کنید.
ورودیهای بررسی:
assert average([10, 15, 20]) == 15
assert average([-2, 2]) == 0
assert average([]) is Noneتمرین 10: گزارش دقیقههای مطالعه
فهرستی از زوجهای نام درس و دقیقهٔ مطالعه دارید. مجموع دقیقههای هر درس را بسازید. فرض کنید دقیقهها صحیح و نامنفیاند.
پاسخ و توضیح
def study_totals(sessions):
totals = {}
for subject, minutes in sessions:
totals[subject] = totals.get(subject, 0) + minutes
return totalsاین تمرین حلقه، بازکردن زوجها و دیکشنری را ترکیب میکند. خروجی قرارداد مشخصی دارد و میتوان بعداً آن را از فایل خواند؛ ذخیرهسازی قدم بعدی است.
ورودیهای بررسی:
assert study_totals([("Python", 20), ("HTML", 15), ("Python", 30)]) == {"Python": 50, "HTML": 15}
assert study_totals([]) == {}چطور متوجه شوم واقعاً یاد گرفتهام؟
یک روز بعد، بدون نگاهکردن به پاسخ، تمرین چهارم و دهم را دوباره بنویسید. برای هر کدام حالت خالی، حالت عادی و حالت مرزی داشته باشید. اگر کد جواب میدهد اما نمیتوانید مسیر اجرای آن را با یک مثال توضیح دهید، مقدار متغیرها را در هر دور حلقه روی کاغذ بنویسید.
تمرین تکمیلی: گزارش مطالعه را کامل کنید
به تمرین دهم کنترل ورودی اضافه کنید: دقیقهٔ منفی را نپذیرید و نام درس خالی را گزارش کنید. سپس مجموع کل را نیز محاسبه کنید. برای نگهداری نتیجه پس از بستن برنامه، آموزش خواندن و نوشتن فایل متنی و CSV در پایتون را ادامه دهید.
اگر این تمرینها سخت بودند از کجا شروع کنم؟
ابتدا راهنمای شروع پایتون از صفر را بخوانید و تمرینهای اول تا سوم را انجام دهید. برای یادگیری منظمتر، سرفصلها و جلسههای دورهٔ پایتون را بررسی کنید؛ هدف این تمرینها سنجش مهارت پایه است و بهتنهایی آمادگی شغلی را اثبات نمیکند.