برنامه‌نویسی و توسعه نرم‌افزار

شرط (If-Else) - تصمیم‌گیری در کد

23 تیر 1404
202 بازدید
17 دقیقه مطالعه
محمد رستمی
محمد رستمی
نویسنده
شرط (If-Else) - تصمیم‌گیری در کد

برنامه‌ها چگونه فکر می‌کنند؟ مقدمه‌ای بر منطق دیجیتال

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

در دنیای واقعی، ما مدام تصمیم می‌گیریم: "اگر باران می‌بارد، چتر برمی‌دارم"، "اگر پول کافی دارم، آن کتاب را می‌خرم"، "اگر ترافیک سنگین است، مسیر دیگری می‌روم". برنامه‌های کامپیوتری نیز دقیقاً همین کار را با استفاده از ساختارهای شرطی انجام می‌دهند.

If-Else یا ساختار شرطی، یکی از بنیادی‌ترین مفاهیم در برنامه‌نویسی است که به کامپیوتر می‌گوید چه زمانی چه کاری انجام دهد. این ساختار مبنای هوش مصنوعی، بازی‌های کامپیوتری، سیستم‌های بانکی و حتی ماشین‌های خودران است. بدون درک صحیح ساختارهای شرطی، نمی‌توان برنامه‌نویس ماهری شد.

ساختار If-Else: قواعد منطق کامپیوتری

If ساده: اولین قدم در تصمیم‌گیری

ساده‌ترین شکل تصمیم‌گیری در برنامه‌نویسی، دستور If است. این دستور می‌گوید: "اگر شرط درست است، این کار را انجام بده". در زبان انگلیسی به آن Conditional Statement می‌گویند.

if temperature > 30:
    print("هوا گرم است، آب بیشتری بنوش")

در این مثال، برنامه ابتدا مقدار متغیر temperature را بررسی می‌کند. اگر این مقدار بزرگ‌تر از 30 باشد، دستور print اجرا می‌شود و پیام نمایش داده می‌شود. اگر دما 30 درجه یا کمتر باشد، هیچ اتفاقی نمی‌افتد و برنامه به دستور بعدی می‌رود. این مثل چراغ راهنمایی است که فقط وقتی قرمز است کار می‌کند - اگر قرمز نباشد، هیچ تغییری در رفتار ماشین‌ها ایجاد نمی‌شود.

Boolean Logic یا منطق بولی، پایه کار تمام ساختارهای شرطی است. در این منطق تنها دو حالت وجود دارد: True (درست) یا False (غلط). کامپیوتر هر شرطی را ارزیابی می‌کند و به یکی از این دو جواب می‌رسد. در مثال بالا، عبارت temperature > 30 یا True برمی‌گرداند (اگر دما بالای 30 باشد) یا False (اگر 30 یا کمتر باشد).

If-Else: انتخاب بین دو راه

وقتی می‌خواهیم برای هر دو حالت (درست و غلط بودن شرط) کاری تعریف کنیم، از If-Else استفاده می‌کنیم:

if account_balance >= withdraw_amount:
    print("تراکنش موفق")
    account_balance = account_balance - withdraw_amount
else:
    print("موجودی کافی نیست")

در این مثال سیستم بانکی، برنامه ابتدا موجودی حساب (account_balance) را با مبلغ درخواستی برداشت (withdraw_amount) مقایسه می‌کند. اگر موجودی کافی باشد، دو کار انجام می‌دهد: پیام موفقیت نمایش می‌دهد و مبلغ را از موجودی کم می‌کند. اگر موجودی کافی نباشد، فقط پیام خطا نمایش می‌دهد و هیچ تغییری در موجودی ایجاد نمی‌کند. این مثل دوراهی است که حتماً باید یکی از دو مسیر را انتخاب کنید - مسیر سومی وجود ندارد.

Elif: زنجیره تصمیمات

در دنیای واقعی اغلب بیش از دو حالت داریم. برای این موارد از Elif (مخفف Else If) استفاده می‌کنیم:

if score >= 90:
    grade = "عالی"
elif score >= 75:
    grade = "خوب"
elif score >= 60:
    grade = "قبولی"
else:
    grade = "مردودی"

در این سیستم نمره‌دهی، برنامه از بالا به پایین حرکت می‌کند و اولین شرط درستی که پیدا کند، اجرا می‌کند و بقیه را نادیده می‌گیرد. مثلاً اگر نمره 85 باشد، ابتدا بررسی می‌کند آیا 85 >= 90؟ که جواب False است. سپس بررسی می‌کند آیا 85 >= 75؟ که جواب True است، پس grade را "خوب" قرار می‌دهد و دیگر شرط‌های بعدی را بررسی نمی‌کند. این مثل یک آبشار است که آب از اولین شکاف مناسبی که پیدا کند، عبور می‌کند.

عملگرهای مقایسه: زبان ریاضی کامپیوتر

عملگرهای پایه

کامپیوترها برای مقایسه از نمادهای خاصی استفاده می‌کنند که به آن‌ها Comparison Operators می‌گویند:

  • == (مساوی): بررسی می‌کند آیا دو مقدار کاملاً یکسان هستند یا نه
  • != (نامساوی): بررسی می‌کند آیا دو مقدار متفاوت هستند یا نه
  • > (بزرگ‌تر): بررسی می‌کند آیا مقدار سمت چپ از مقدار سمت راست بزرگ‌تر است
  • < (کوچک‌تر): بررسی می‌کند آیا مقدار سمت چپ از مقدار سمت راست کوچک‌تر است
  • >= (بزرگ‌تر مساوی): بررسی می‌کند آیا مقدار سمت چپ از مقدار سمت راست بزرگ‌تر یا مساوی است
  • <= (کوچک‌تر مساوی): بررسی می‌کند آیا مقدار سمت چپ از مقدار سمت راست کوچک‌تر یا مساوی است

توجه مهم: = برای تخصیص مقدار به متغیر (Assignment) استفاده می‌شود، مثل x = 5 که یعنی مقدار 5 را به متغیر x بده. اما == برای مقایسه (Comparison) استفاده می‌شود، مثل x == 5 که یعنی بررسی کن آیا x برابر 5 است یا نه. اشتباه گرفتن این دو، یکی از رایج‌ترین خطاهای مبتدیان است.

عملگرهای منطقی: ترکیب شرط‌ها

گاهی نیاز داریم چندین شرط را با هم ترکیب کنیم. برای این کار از Logical Operators استفاده می‌کنیم:

AND (و): هر دو شرط باید درست باشد تا نتیجه کل True شود

if age >= 18 and has_license == True:
    print("می‌تواند رانندگی کند")

در این مثال، فرد باید هم بالای 18 سال باشد و هم گواهینامه داشته باشد تا بتواند رانندگی کند. اگر یکی از این دو شرط برقرار نباشد، اجازه رانندگی نمی‌گیرد.

OR (یا): حداقل یکی از شرط‌ها باید درست باشد تا نتیجه کل True شود

if payment_method == "card" or payment_method == "cash":
    print("پرداخت قابل قبول است")

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

NOT (نه): شرط را برعکس می‌کند - اگر True بود، False می‌شود و برعکس

if not is_weekend:
    print("امروز روز کاری است")

در این مثال، اگر is_weekend متغیری False باشد (یعنی تعطیل نباشد)، NOT آن را True می‌کند و پیام "امروز روز کاری است" نمایش داده می‌شود.

اولویت عملگرها: ترتیب ارزیابی

مثل ریاضیات که ابتدا ضرب و تقسیم، سپس جمع و تفریق انجام می‌شود، در برنامه‌نویسی نیز ترتیب عملیات اهمیت دارد. Operator Precedence تعیین می‌کند کدام عملگر ابتدا اجرا شود:

  1. پرانتز () - بالاترین اولویت
  2. عملگرهای مقایسه ==, !=, <, >, <=, >=
  3. NOT
  4. AND
  5. OR - کمترین اولویت

مثلاً در عبارت A or B and C، ابتدا B and C محاسبه می‌شود و سپس نتیجه آن با A ترکیب می‌شود. اگر A=True، B=False، C=True باشد، ابتدا False and True = False محاسبه می‌شود، سپس True or False = True. برای وضوح بیشتر و جلوگیری از سردرگمی، همیشه از پرانتز استفاده کنید: A or (B and C).

ساختارهای پیچیده: Nested Conditions

شرط‌های تو در تو

گاهی نیاز داریم داخل یک شرط، شرط دیگری قرار دهیم. به این کار Nested If می‌گویند:

if weather == "sunny":
    if temperature > 25:
        print("روز عالی برای پیک‌نیک")
    else:
        print("آفتابی اما سرد")
else:
    if weather == "rainy":
        print("چتر فراموش نکن")
    else:
        print("هوا نامعلوم است")

در این مثال، برنامه ابتدا آب‌وهوا را بررسی می‌کند. اگر آفتابی باشد، وارد شرط دوم می‌شود و دما را بررسی می‌کند. اگر دما بالای 25 باشد، پیام پیک‌نیک نمایش می‌دهد، وگرنه می‌گوید آفتابی اما سرد است. اگر آب‌وهوا آفتابی نباشد، بررسی می‌کند آیا بارانی است یا خیر. این مثل درخت تصمیم است که در هر شاخه، شاخه‌های کوچک‌تری دارید. اما مواظب باشید که Nesting زیاد برنامه را پیچیده و غیرقابل خواندن نمی‌کند.

بهینه‌سازی شرط‌های پیچیده

به‌جای Nesting زیاد، می‌توان از تکنیک‌های دیگری استفاده کرد:

Early Return: زودتر از تابع خارج شدن

def check_access(user):
    if not user.is_logged_in:
        return "ابتدا وارد شوید"
    
    if not user.has_permission:
        return "دسترسی ندارید"
    
    return "خوش آمدید"

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

Guard Clauses: شرط‌های محافظ در ابتدای تابع

def process_payment(amount, card):
    if amount <= 0:
        return "مبلغ نامعتبر"
    
    if not card.is_valid:
        return "کارت نامعتبر"
    
    # پردازش اصلی
    return "پرداخت موفق"

Guard Clauses مثل نگهبان در ورودی هستند که شرایط اشتباه را زودتر شناسایی و رد می‌کنند. ابتدا تمام حالات خطا بررسی می‌شوند و اگر همه‌چیز درست باشد، کد اصلی اجرا می‌شود. این روش باعث می‌شود منطق اصلی برنامه در انتها قرار گیرد و واضح‌تر باشد.

انواع داده و شرط‌بندی: نکات ظریف

Truthiness و Falsiness

در برنامه‌نویسی، نه تنها True و False، بلکه مقادیر دیگری نیز می‌توانند در شرط‌ها استفاده شوند. به این مفهوم Truthiness می‌گویند:

مقادیر Falsy (معادل False در شرط‌ها):

  • None (هیچ - مقدار خالی)
  • 0 (عدد صفر)
  • "" (رشته خالی)
  • [] (لیست خالی)
  • {} (دیکشنری خالی)

مقادیر Truthy (معادل True در شرط‌ها):

  • هر عدد غیر صفر (مثبت یا منفی)
  • هر رشته غیر خالی
  • هر لیست غیر خالی
users = ["احمد", "فاطمه"]

if users:  # اگر لیست خالی نباشد
    print(f"تعداد کاربران: {len(users)}")
else:
    print("کاربری یافت نشد")

در این مثال، متغیر users یک لیست است که شامل دو نام است. چون لیست خالی نیست، در شرط if True محسوب می‌شود و تعداد کاربران نمایش داده می‌شود. اگر لیست خالی بود users = []، شرط else اجرا می‌شد.

Type Checking: بررسی نوع داده

گاهی نیاز داریم نوع داده را بررسی کنیم تا متناسب با آن عمل کنیم:

def process_input(data):
    if isinstance(data, str):
        return data.upper()
    elif isinstance(data, int):
        return data * 2
    elif isinstance(data, list):
        return len(data)
    else:
        return "نوع داده پشتیبانی نمی‌شود"

تابع isinstance بررسی می‌کند که آیا متغیر data از نوع مشخص شده است یا نه. اگر data یک رشته (str) باشد، آن را بزرگ می‌کند. اگر عدد صحیح (int) باشد، آن را دو برابر می‌کند. اگر لیست باشد، تعداد عناصر آن را برمی‌گرداند. اگر هیچ‌کدام نباشد، پیام خطا برمی‌گرداند.

الگوهای رایج: Common Patterns

Switch-Case Alternative

برخی زبان‌ها Switch-Case دارند که برای مقایسه یک متغیر با مقادیر مختلف استفاده می‌شود، اما Python ندارد. می‌توان با Dictionary آن را شبیه‌سازی کرد:

def get_day_name(day_number):
    days = {
        1: "شنبه",
        2: "یکشنبه", 
        3: "دوشنبه",
        4: "سه‌شنبه",
        5: "چهارشنبه",
        6: "پنج‌شنبه",
        7: "جمعه"
    }
    return days.get(day_number, "روز نامعتبر")

در این روش، به‌جای نوشتن 7 شرط if-elif، از Dictionary استفاده می‌کنیم. متد get دو پارامتر می‌گیرد: کلید مورد نظر (day_number) و مقدار پیش‌فرض ("روز نامعتبر") که اگر کلید پیدا نشود، برگردانده می‌شود. این روش سریع‌تر و خواناتر است.

Ternary Operator: شرط در یک خط

برای شرط‌های ساده می‌توان از عملگر سه‌گانه استفاده کرد:

# به‌جای این:
if age >= 18:
    status = "بزرگسال"
else:
    status = "نوجوان"

# می‌توان نوشت:
status = "بزرگسال" if age >= 18 else "نوجوان"

Ternary Operator ساختار مقدار_اگر_درست if شرط else مقدار_اگر_غلط دارد. در مثال بالا، اگر age >= 18 درست باشد، مقدار "بزرگسال" به status تخصیص داده می‌شود، وگرنه "نوجوان". این روش برای شرط‌های ساده مفید است اما برای شرط‌های پیچیده خوانایی را کم می‌کند.

Validation Chains: زنجیره اعتبارسنجی

در فرم‌ها و ورودی‌های کاربر، اغلب نیاز به چندین بررسی داریم:

def validate_email(email):
    if not email:
        return False, "ایمیل نمی‌تواند خالی باشد"
    
    if "@" not in email:
        return False, "ایمیل باید شامل @ باشد"
    
    if len(email) < 5:
        return False, "ایمیل خیلی کوتاه است"
    
    if "." not in email.split("@")[1]:
        return False, "دامنه ایمیل نامعتبر است"
    
    return True, "ایمیل معتبر است"

این تابع ایمیل را مرحله به مرحله بررسی می‌کند. ابتدا چک می‌کند خالی نباشد، سپس وجود @ را بررسی می‌کند، بعد طول آن را چک می‌کند و در نهایت بررسی می‌کند که بعد از @ حداقل یک نقطه وجود داشته باشد (برای دامنه). هر مرحله که مشکل داشته باشد، فوراً False و پیام خطا برمی‌گرداند.

کاربردهای عملی: از ساده تا پیشرفته

سیستم احراز هویت ساده

def login_system(username, password, users_db):
    if not username:
        return "نام کاربری را وارد کنید"
    
    if not password:
        return "رمز عبور را وارد کنید"
    
    if username not in users_db:
        return "کاربر یافت نشد"
    
    if users_db[username]['password'] != password:
        return "رمز عبور اشتباه است"
    
    if not users_db[username]['is_active']:
        return "حساب کاربری غیرفعال است"
    
    return f"خوش آمدید {username}"

این سیستم ورود مرحله به مرحله ورودی‌های کاربر را بررسی می‌کند. ابتدا چک می‌کند که نام کاربری و رمز عبور وارد شده باشد (Guard Clauses). سپس بررسی می‌کند آیا کاربر در پایگاه داده وجود دارد. بعد رمز عبور را مقایسه می‌کند و در نهایت چک می‌کند که حساب فعال باشد. اگر همه مراحل موفق باشد، پیام خوشامدگویی برمی‌گرداند.

محاسبه‌گر مالیات پیشرفته

def calculate_tax(income, marital_status, children_count):
    base_tax = 0
    
    # محاسبه مالیات پایه بر اساس درآمد
    if income <= 5000000:
        base_tax = 0  # درآمد کم، بدون مالیات
    elif income <= 10000000:
        base_tax = (income - 5000000) * 0.1  # 10% مالیات برای مازاد بر 5 میلیون
    elif income <= 20000000:
        base_tax = 500000 + (income - 10000000) * 0.15  # مالیات تجمعی
    else:
        base_tax = 2000000 + (income - 20000000) * 0.2  # بالاترین نرخ مالیات
    
    # اعمال تخفیف‌های خانوادگی
    if marital_status == "married":
        base_tax *= 0.95  # 5% تخفیف برای متأهل‌ها
    
    if children_count > 0:
        discount = min(children_count * 0.02, 0.1)  # 2% تخفیف به ازای هر فرزند، حداکثر 10%
        base_tax *= (1 - discount)
    
    return max(base_tax, 0)  # مالیات نمی‌تواند منفی باشد

این محاسبه‌گر سیستم مالیات پلکانی را پیاده‌سازی می‌کند. ابتدا بر اساس سطح درآمد، مالیات پایه محاسبه می‌شود. سپس تخفیف‌های خانوادگی اعمال می‌شود. تابع min مطمئن می‌شود که تخفیف فرزندان از 10% تجاوز نکند، و تابع max تضمین می‌کند که مالیات نهایی منفی نشود.

سیستم امتیازدهی بازی

def calculate_game_score(level, time_taken, lives_remaining, bonus_collected):
    base_score = level * 1000  # امتیاز پایه بر اساس سطح بازی
    
    # جایزه سرعت: تکمیل سریع مرحله
    if time_taken < 60:
        speed_bonus = 500  # تکمیل در کمتر از یک دقیقه
    elif time_taken < 120:
        speed_bonus = 250  # تکمیل در کمتر از دو دقیقه
    else:
        speed_bonus = 0  # بدون جایزه سرعت
    
    # جایزه بقا: جان‌های باقی‌مانده
    life_bonus = lives_remaining * 100  # 100 امتیاز به ازای هر جان
    
    # جایزه جمع‌آوری: آیتم‌های جمع‌آوری‌شده
    collection_bonus = bonus_collected * 50  # 50 امتیاز به ازای هر آیتم
    
    # اعمال ضریب عملکرد
    if lives_remaining == 3 and time_taken < 60:
        multiplier = 2.0  # عملکرد کامل: تمام جان‌ها + سرعت بالا
    elif lives_remaining >= 2:
        multiplier = 1.5  # عملکرد خوب: بیشتر جان‌ها محفوظ
    else:
        multiplier = 1.0  # عملکرد معمولی
    
    total_score = (base_score + speed_bonus + life_bonus + collection_bonus) * multiplier
    return int(total_score)  # برگرداندن عدد صحیح

این سیستم امتیازدهی چندین عامل را در نظر می‌گیرد: سطح بازی (که امتیاز پایه را تعیین می‌کند)، سرعت تکمیل، تعداد جان‌های باقی‌مانده و آیتم‌های جمع‌آوری‌شده. سپس بر اساس عملکرد کلی، ضریبی اعمال می‌شود. عملکرد کامل (تمام جان‌ها + سرعت بالا) امتیاز را دو برابر می‌کند.

بهینه‌سازی و کارایی: Performance Considerations

Short-Circuit Evaluation

در عملگرهای منطقی، کامپیوتر از تکنیک Short-Circuit استفاده می‌کند که باعث صرفه‌جویی در زمان و جلوگیری از خطاهای احتمالی می‌شود:

# اگر user None باشد، دومی اجرا نمی‌شود
if user and user.is_premium():
    show_premium_content()

# اگر اولی True باشد، دومی اجرا نمی‌شود  
if is_admin() or check_special_permission():
    grant_access()

در مثال اول، اگر متغیر user مقدار None داشته باشد (که Falsy است)، کامپیوتر دیگر user.is_premium() را اجرا نمی‌کند چون می‌داند که نتیجه کل حتماً False خواهد بود. این مانع از خطای "NoneType has no attribute" می‌شود. در مثال دوم، اگر is_admin() True برگرداند، دیگر check_special_permission() اجرا نمی‌شود چون یک True کافی است تا کل عبارت OR برابر True شود.

Function Call Optimization

محاسبات سنگین را در شرط‌ها به تأخیر بیندازید تا فقط در صورت نیاز اجرا شوند:

# بد: همیشه محاسبه می‌شود حتی اگر کاربر premium نباشد
expensive_result = calculate_complex_data()
if user.is_premium and expensive_result > threshold:
    process_data()

# خوب: فقط در صورت نیاز محاسبه می‌شود
if user.is_premium and calculate_complex_data() > threshold:
    process_data()

در روش اول، تابع calculate_complex_data() همیشه اجرا می‌شود حتی اگر کاربر premium نباشد و شرط اول False شود. در روش دوم، ابتدا بررسی می‌شود که کاربر premium است یا نه، و فقط در صورت True بودن، محاسبه سنگین انجام می‌شود. این باعث صرفه‌جویی قابل توجه در منابع سیستم می‌شود.

Lookup Tables: جایگزین If-Elif طولانی

برای مقایسه‌های زیاد، Dictionary سریع‌تر از زنجیره if-elif است:

# کند برای مقادیر زیاد
def get_month_days(month):
    if month == 1:
        return 31
    elif month == 2:
        return 28
    elif month == 3:
        return 31
    elif month == 4:
        return 30
    # ... ادامه تا 12 شرط

# سریع: جستجو در Dictionary O(1) است
MONTH_DAYS = {1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30,
              7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31}

def get_month_days(month):
    return MONTH_DAYS.get(month, 0)

در روش اول، کامپیوتر باید تا 12 مقایسه انجام دهد تا جواب را پیدا کند. در روش دوم، Dictionary با استفاده از Hash Table، مستقیماً به جواب دسترسی دارد. وقتی تعداد حالات زیاد می‌شود، تفاوت سرعت قابل توجه است.

خطاهای رایج و راه‌حل‌ها: Common Pitfalls

اشتباه در Assignment vs Equality

# اشتباه: استفاده از = به‌جای == در شرط
if password = "123456":  # خطای نحوی!
    print("رمز ساده")

# درست: استفاده از == برای مقایسه
if password == "123456":
    print("رمز ساده")

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

مقایسه اشتباه Float ها

# اشتباه: مقایسه مستقیم اعداد اعشاری
if 0.1 + 0.2 == 0.3:  # این False برمی‌گرداند!
    print("برابر است")

# درست: استفاده از tolerance برای مقایسه تقریبی
if abs((0.1 + 0.2) - 0.3) < 0.0001:
    print("تقریباً برابر است")

به دلیل نحوه ذخیره‌سازی اعداد اعشاری در کامپیوتر (فرمت IEEE 754)، برخی محاسبات دقیق نیستند. 0.1 + 0.2 در واقع 0.30000000000000004 می‌شود. برای مقایسه اعداد اعشاری، از tolerance استفاده می‌کنیم - یعنی اگر تفاوت کمتر از مقدار کوچکی (مثل 0.0001) باشد، آن‌ها را برابر در نظر می‌گیریم.

عدم درنظرگیری None

# خطرناک: اگر user مقدار None داشته باشد، خطا می‌دهد
if user.name == "admin":  # AttributeError: 'NoneType' has no attribute 'name'
    grant_admin_access()

# امن: ابتدا وجود user را بررسی می‌کند
if user and user.name == "admin":
    grant_admin_access()

وقتی متغیری ممکن است None باشد، باید ابتدا وجود آن را بررسی کنید. در مثال خطرناک، اگر user برابر None باشد، تلاش برای دسترسی به attribute آن خطا می‌دهد. در مثال امن، ابتدا user بررسی می‌شود (که اگر None باشد، False برمی‌گرداند) و بعد name آن چک می‌شود.

ابزارها و تکنیک‌های پیشرفته

Assert Statements: بررسی فرضیات

def divide(a, b):
    assert b != 0, "تقسیم بر صفر غیرممکن است"
    assert isinstance(a, (int, float)), "عدد معتبر وارد کنید"
    return a / b

Assert statements برای بررسی فرضیات در برنامه استفاده می‌شوند. اگر شرط assert برقرار نباشد، برنامه متوقف می‌شود و پیام خطا نمایش می‌دهد. این ابزار برای Debug کردن و اطمینان از صحت ورودی‌ها مفید است. در مثال بالا، assert اطمینان می‌دهد که مخرج صفر نباشد و ورودی‌ها عدد باشند.

Exception Handling با If

def safe_file_read(filename):
    if not os.path.exists(filename):
        return None, "فایل وجود ندارد"
    
    if not os.access(filename, os.R_OK):
        return None, "دسترسی خواندن ندارید"
    
    try:
        with open(filename, 'r') as file:
            return file.read(), "موفق"
    except Exception as e:
        return None, f"خطا در خواندن: {str(e)}"

در این تابع، ابتدا با استفاده از if شرایط اولیه بررسی می‌شوند: آیا فایل وجود دارد و آیا دسترسی خواندن داریم. اگر این بررسی‌های اولیه موفق باشند، سعی می‌کنیم فایل را باز کنیم. اگر در مرحله باز کردن خطایی رخ دهد، آن را catch کرده و پیام مناسب برمی‌گردانیم. این ترکیب if و exception handling باعث robust بودن کد می‌شود.

Finite State Machine با If-Else

class TrafficLight:
    def __init__(self):
        self.state = "red"
        self.timer = 0
    
    def update(self):
        if self.state == "red":
            self.timer += 1
            if self.timer >= 30:  # 30 ثانیه قرمز
                self.state = "green"
                self.timer = 0
        elif self.state == "green":
            self.timer += 1
            if self.timer >= 25:  # 25 ثانیه سبز
                self.state = "yellow"
                self.timer = 0
        elif self.state == "yellow":
            self.timer += 1
            if self.timer >= 5:  # 5 ثانیه زرد
                self.state = "red"
                self.timer = 0

این کلاس یک چراغ راهنمایی را شبیه‌سازی می‌کند که سه حالت دارد: قرمز، سبز و زرد. در هر حالت، تایمر افزایش می‌یابد و وقتی به حد مشخصی رسید، به حالت بعدی تغییر می‌کند. این الگو برای پیاده‌سازی سیستم‌هایی که حالات مختلف دارند (مثل بازی‌ها، ربات‌ها، پروتکل‌های شبکه) بسیار مفید است.

نتیجه‌گیری: هنر تصمیم‌گیری در کد

ساختارهای شرطی قلب هر برنامه کامپیوتری هستند. از ساده‌ترین اپلیکیشن موبایل تا پیچیده‌ترین سیستم‌های هوش مصنوعی، همه از If-Else استفاده می‌کنند. درک عمیق این مفهوم، اولین قدم برای تبدیل شدن به برنامه‌نویس ماهر است.

نکات کلیدی که باید به خاطر بسپارید:

  • همیشه از پرانتز برای وضوح در شرط‌های پیچیده استفاده کنید
  • شرط‌های پیچیده را به قطعات کوچک‌تر و قابل فهم تقسیم کنید
  • از Early Return و Guard Clauses برای کاهش Nesting استفاده کنید
  • مراقب تفاوت بین = (تخصیص) و == (مقایسه) باشید
  • هنگام مقایسه اعداد اعشاری از tolerance استفاده کنید
  • همیشه احتمال None بودن متغیرها را در نظر بگیرید
  • برای شرط‌های زیاد از Dictionary به‌جای if-elif طولانی استفاده کنید

آینده برنامه‌نویسی در حال تغییر است، اما ساختارهای شرطی همچنان جایگاه خود را حفظ خواهند کرد. حتی در عصر هوش مصنوعی، الگوریتم‌ها نیاز به تصمیم‌گیری دارند. Pattern Matching در زبان‌های جدید، Functional Programming و حتی Neural Networks، همگی بر پایه مفاهیم تصمیم‌گیری شرطی بنا شده‌اند.

تمرین مداوم کلید تسلط است. هر روز سعی کنید مسائل کوچک را با If-Else حل کنید. از محاسبه‌گر ساده شروع کنید، سپس به سمت پروژه‌های پیچیده‌تر پیش بروید. به یاد داشته باشید که برنامه‌نویسی هنر حل مسئله است، و ساختارهای شرطی قلم شماست که با آن منطق و تصمیمات را روی کاغذ دیجیتال می‌آورید.

محمد رستمی

محمد رستمی

اگر نتوانید چیزی را به زبان ساده توضیح دهید، آنرا به اندازه کافی نفهمیده اید...

نظرات کاربران (0)

هنوز نظری ثبت نشده است. اولین نفری باشید که نظر می‌دهید!

اشتراک‌گذاری: