ویرگول
ورودثبت نام
Omid.log
Omid.logدانش‌آموز یازدهم ریاضی‌ام و مسیر یادگیری پایتون و برنامه نویسی رو قدم‌ به‌ قدم مستند می‌کنم D: از باگ‌ها و سؤال‌های پرتکرار تا پروژه‌های کوچیک و پیشرفت‌های روزا‌نه
Omid.log
Omid.log
خواندن ۴ دقیقه·۱ ماه پیش

برنامه‌م خطا نمیداد ولی کار هم نمی‌کرد (دردسر های حلقه پایتون) | Omid_Log_2#

-chat gpt-
-chat gpt-

بدترین باگ‌ها همیشه اون‌هایی نیستن که با یه ارور قرمز جلوی چشمت ظاهر می‌شن. بعضی وقت‌ها برنامه بدون هیچ خطایی اجرا می‌شه، ولی کاری که ازش انتظار داری رو انجام نمی‌ده. نه اروری، نه پیامی؛ فقط نتیجه‌ای که هیچ‌وقت ظاهر نمی‌شه.

این هفته، وسط یه پروژه‌ی کوچیک با پایتون، با یکی از همین باگ‌ها روبه‌رو شدم.


پروژه از کجا شروع شد؟

ایده ساده بود: یه سیستم ثبت فاکتور خرید. کاربر قیمت محصولات رو یکی‌یکی وارد می‌کنه و مجموع خرید نمایش داده می‌شه.

با خودم گفتم: «یه حلقه، چند تا شرط و یه متغیر برای جمع قیمت‌ها... چقدر می‌تونه سخت باشه؟» 😂

نسخه‌ی اولم تقریباً این منطق رو داشت:

if user_input.isdigit(): price = int(user_input) if price > 0: total_price += price elif user_input == "checkout": print(f"OK! total price: {total_price}")

قیمت‌ها رو وارد می‌کردم و همه‌چیز خوب بود. اما وقتی checkout می‌نوشتم، هیچ اتفاقی نمی‌افتاد.

چرا ساکت بود؟

متد isdigit() مثل یه بازرسه که بررسی میکنه ورودی عدد هست یا نه:

"25".isdigit() # True (عدد هست) "checkout".isdigit() # False (عدد نیست)

من بررسی checkout رو داخل بلوکی گذاشته بودم که فقط برای ورودی عددی اجرا می‌شد. ولی checkout عدد نیست، پس برنامه اصلاً وارد اون بلوک نمی‌شد.

مثل این بود که پیام مهمم رو بذارم توی اتاقی که فقط با کارت عددی باز می‌شه، و بعد انتظار داشته باشم کسی با یه کلمه واردش بشه. کامپیوتر حدس نمی‌زنه منظورم چی بوده؛ دقیقاً همون چیزی رو اجرا می‌کنه که نوشتم.

ترتیب شرط‌ها فقط ظاهر کد نیست؛ تعیین می‌کنه کدوم بخش برنامه اصلاً شانس اجرا شدن داره.

راه‌حل: اول حالت ویژه، بعد قانون عمومی

لازم نبود همه‌چیز رو از صفر بنویسم، فقط ترتیب تصمیم‌گیری رو عوض کردم:

total_price = 0 while True: user_input = input("Enter price or 'checkout': ") (اولویت ۱: دستورات خاص) if user_input == "checkout": if total_price > 0: print(f"Total: {total_price}") else: print("Cart is empty!") break (اولویت ۲: اعتبارسنجی و محاسبات) elif user_input.isdigit(): price = int(user_input) if price > 0: total_price += price print(f"Added: {price}. Total: {total_price}") else: print("Please enter a positive number!") (اولویت ۳: مدیریت خطاهای کاربر) else: print("Invalid input. Try again.")

حالا برنامه سه مسیر مشخص داره

1.checkout وضعیت سبد رو نشون می‌ده و حلقه رو می‌بنده،
مثلا : قیمت نهایی= 1,230,000


2. ورودی عدد رو اعتبارسنجی میکنه و مجموع قیمت ها رو حساب میکنه،

قیمت یک کالای فرضی رو نشون میده و همون رو با عدد ها جمع میکنه تا مجموع رو بدست بیاره


3. هر چیز دیگه‌ای به جز چیزهای تنظیم شده وارد بشه، پیفام خطا می‌گیره.

هر شرط یه مسئولیت داره و هیچ ورودی‌ای بدون جواب نمی‌مونه.

(ترتیب شرط ها بسیار مهمه و این نیاز به یک تفکر الگوریتمی قوی داره)


+ بقیه‌ی ریز باگ‌های این پروژه

مشکل checkout تنها اشتباهم نبود. چون قبلا گفتم قراره با شفافیت همه چیزو ثبت کنم، پس بقیه رو هم ثبت می‌کنم:

  • NameError

    : به‌جای user_input نوشته بودم user_inout

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

اینجا هم مثل مدرسه باید حواست باشه غلط املایی نداشته باشی

‌

  • SyntaxError


    یه : بعد از if و while جا انداخته بودم.
    پایتون برای شروع بدنه‌ی دستورهایی مثل if و while به : نیاز داره؛ جا انداختنش باعث SyntaxError میشه.

دو نقطه ( :‌ ) بعد از شروط دستور شروع شدن اون شرطه؛
اگر : بعد از شرط ها نباشه، شرط اجرا نمیشه.

  • input بیرون از حلقه:

    دستور input() رو بیرون از حلقه گذاشته بودم؛ بنابراین در هر دور حلقه ورودی جدیدی دریافت نمی‌شد

به عبارت دیگه ورودی فقط یه بار گرفته می‌شد و وارد حلقه نمیشد، چون هنوز درست نفهمیده بودم حلقه دقیقاً چی رو تکرار می‌کنه.

  • مقایسه‌ی متن با عدد: "5" > 0 توی پایتون ۳ با TypeError روبه‌رو می‌شه. چون اینجا "5" داخل کوتیشن یه رشته حروف حساب میشه. نمیشه حروف رو با عدد مقایسه کرد

    (همونطور که نمیشه احسان علیخانی رو با دوچرخه مقایسه کرد!)

برای این نوع ورودی، یکی از الگوی های مفید اینه :

اعتبارسنجی ← تبدیل نوع ← پردازش.
ترتیبش مهمه.


چیزی که از این پروژه یاد گرفتم

قبلاً وقتی برنامه کار نمی‌کرد، سریع چند خط رو عوض می‌کردم و امیدوار بودم درست بشه. این بار یه روش دیگه امتحان کردم:

1. انتظارم چیه؟ با وارد کردن checkout، خرید تموم بشه.

2. در عمل چی می‌شه؟ هیچ اتفاقی نمی‌افته.

3. فاصله از کجاست؟ شرط checkout توی مسیری بود که ورودی متنی بهش راه نداشت.

4. کوچک‌ترین تغییر ممکن چیه؟ جابه‌جا کردن همون شرط، نه بازنویسی کل برنامه.

و یه سؤال جدید هم به عادت‌های قبل از کدنویسی‌م اضافه شد: «کاربر چی می‌تونه تایپ کنه که من فکرش رو نکردم؟ که باعث بشه برنامه سوپرایز شه و ارور بده؟ » متن به‌جای عدد، صفر، یا نوشتنcheckout وقتی هنوز چیزی نخریده.

یه سؤال هنوز باقیه: اگه کاربر -5 یا 12.5 وارد کنه چی؟ isdigit() برای هر دو False برمی‌گردونه، چون علامت منفی و نقطه رقم نیستن. برنامه‌ی فعلی من این ورودی‌ها رو رد می‌کنه و می‌خوام بعداً درستش کنم.


این پروژه قرار نبود یه سیستم فروشگاهی کامل باشه؛

فقط یه تمرین کوچیک بود. اما چند بار مجبورم کرد مکث کنم، کدم رو دوباره بخونم و درباره‌ی منطقش فکر کنم.

شما چطور؟ تا حالا شده برنامه‌تون بدون هیچ ارور قرمزی اجرا بشه، اما دقیقاً کاری رو که انتظار داشتید انجام نده؟ چطور پیداش کردید؟


#Omid_Log #برنامه‌نویسی #پایتون #Python #دیباگ #حل_مسئله #پروژه_کوچک #یادگیری

برنامه‌نویسی پایتونحل مسئلهپایتونpythonبرنامه نویسی
۱۰
۲
Omid.log
Omid.log
دانش‌آموز یازدهم ریاضی‌ام و مسیر یادگیری پایتون و برنامه نویسی رو قدم‌ به‌ قدم مستند می‌کنم D: از باگ‌ها و سؤال‌های پرتکرار تا پروژه‌های کوچیک و پیشرفت‌های روزا‌نه
شاید از این پست‌ها خوشتان بیاید