ماشین حساب

اصلاح شده

2026-09-23

با استفاده از مطالبی که آموخته‌اید میتوانید برنامه‌های زیر را بسازید.

عبارات و دستورات

یک برنامه بنویسید که:

  • از کاربر دو عدد دریافت کند و تمام عملیات‌های ریاضی و مقایسه‌ای را برای آن‌ها بنویسد.
کد
n1 = input("n1: ")
n1 = float(n1)
n2 = input("n2: ")
n2 = float(n2)

print(n1, "+ ", n2, "=", n1 + n2)
print(n1, "- ", n2, "=", n1 - n2)
print(n1, "* ", n2, "=", n1 * n2)
print(n1, "**", n2, "=", n1 ** n2)
print(n1, "/ ", n2, "=", n1 / n2)
print(n1, "//", n2, "=", n1 // n2)
print(n1, "% ", n2, "=", n1 % n2)
print(n1, "==", n2, "=", n1 == n2)
print(n1, "! ", n2, "=", n1 != n2)
print(n1, "< ", n2, "=", n1 < n2)
print(n1, "<=", n2, "=", n1 <= n2)
print(n1, "> ", n2, "=", n1 > n2)
print(n1, ">=", n2, "=", n1 >= n2)

ساختار داده

یک برنامه بنویسید که:

  • از کاربر دو عدد و یک عملگر دریافت کند و آن عملگر را برای آن دو عدد اعمال کند و در نهایت حاصل را به همراه اعداد و عملگر چاپ کند.
کد
n1 = input("n1: ")
n1 = float(n1)
n2 = input("n2: ")
n2 = float(n2)
op = input("(+,-,*,**,/,//,%,==,!=,<,<=,>,>=)\nop: ")

n1_op_n2 = {
    "+": n1 + n2,
    "-": n1 - n2,
    "*": n1 * n2,
    "**": n1**n2,
    "/": n1 / n2,
    "//": n1 // n2,
    "%": n1 % n2,
    "==": n1 == n2,
    "!=": n1 != n2,
    "<": n1 < n2,
    "<=": n1 <= n2,
    ">": n1 > n2,
    ">=": n1 >= n2,
}

print(f"{n1} {op} {n2} = {n1_op_n2[op]}")

دستورات شرطی و مدیریت خطا

یک برنامه بنویسید که:

  • از کاربر دو عدد و یک عملگر دریافت کند و آن عملگر را برای آن دو عدد اعمال کند و در نهایت حاصل را به همراه اعداد و عملگر چاپ کند.
  • برای عملگرهایی که وجود ندارن یک پیام برای کاربر چاپ کند.
  • خطای تقسیم بر صفر را به طور خاص مدیریت کند.
  • برای باقی خطاها یک پیام متناسب با نوع خطا چاپ کند.
کد
valid_op = "+,-,*,**,/,//,%,==,!=,<,<=,>,>=".split(",")

try:
    n1 = input("n1: ")
    n1 = float(n1)
    n2 = input("n2: ")
    n2 = float(n2)
    op = input(f"op: ")

    if op not in valid_op:
        print(f"{op} is not valid operator!")
        print(f"({','.join(valid_op)})")
    else:
        n1_op_n2 = {
            "+": n1 + n2,
            "-": n1 - n2,
            "*": n1 * n2,
            "**": n1**n2,
            "/": n1 / n2,
            "//": n1 // n2,
            "%": n1 % n2,
            "==": n1 == n2,
            "!=": n1 != n2,
            "<": n1 < n2,
            "<=": n1 <= n2,
            ">": n1 > n2,
            ">=": n1 >= n2,
        }

        print(f"{n1} {op} {n2} = {n1_op_n2[op]}")
except ZeroDivisionError:
    print(f"ZeroDivisionError: {n1} {op} {n2} is not valid output")
except ValueError:
    print("ValueError: Please enter just number for n1 and n2!")
except Exception as e:
    print(f"Error: {str(e)}")

حلقه

یک برنامه بنویسید که:

  • از کاربر دو عدد و یک عملگر دریافت کند و آن عملگر را برای آن دو عدد اعمال کند و در نهایت حاصل را به همراه اعداد و عملگر چاپ کند.
  • برای عملگرهایی که وجود ندارن یک پیام برای کاربر چاپ کند.
  • خطای تقسیم بر صفر را به طور خاص مدیریت کند.
  • برای باقی خطاها یک پیام متناسب با نوع خطا چاپ کند.
  • بعد از چاپ خروجی دوباره بتواند حداکثر ۳ بار ورودی جدید از کاربر دریافت کند. دقت کنید که فقط در صورت انجام عملیات بدون خطا، تعداد دفعات محاسبه شود.
  • با نوشتن exit در ورودی اول از برنامه خارج شود.
  • برای اصلاح ورودی‌ها اگر به جای عملگر عبارت edit وارد شود تا ورودی دوباره دریافت شود.
کد
valid_op = "+,-,*,**,/,//,%,==,!=,<,<=,>,>="
counter = 1
while counter <= 3:
    try:
        n1 = input("n1: ")
        if n1 == "exit":
            break

        n1 = float(n1)
        n2 = input("n2: ")
        n2 = float(n2)
        op = input(f"op: ")

        if op == "edit":
            continue

        if op not in valid_op.split(","):
            print(f"{op} is not valid operator!")
            print(f"({valid_op})")
            continue

        n1_op_n2 = {
            "+": n1 + n2,
            "-": n1 - n2,
            "*": n1 * n2,
            "**": n1**n2,
            "/": n1 / n2,
            "//": n1 // n2,
            "%": n1 % n2,
            "==": n1 == n2,
            "!=": n1 != n2,
            "<": n1 < n2,
            "<=": n1 <= n2,
            ">": n1 > n2,
            ">=": n1 >= n2,
        }

        print(f"{n1} {op} {n2} = {n1_op_n2[op]}")
        counter += 1

    except ZeroDivisionError:
        print(f"ZeroDivisionError: {n1} {op} {n2} is not valid output")
    except ValueError:
        print("ValueError: Please enter just number for n1 and n2!")
    except Exception as e:
        print(f"Error: {str(e)}")

تابع

یک برنامه بنویسید که:

  • از کاربر دو عدد و یک عملگر دریافت کند و آن عملگر را برای آن دو عدد اعمال کند و در نهایت حاصل را به همراه اعداد و عملگر چاپ کند.
  • برای عملگرهایی که وجود ندارن یک پیام برای کاربر چاپ کند.
  • خطای تقسیم بر صفر را به طور خاص مدیریت کند.
  • برای باقی خطاها یک پیام متناسب با نوع خطا چاپ کند.
  • بعد از چاپ خروجی دوباره بتواند حداکثر ۳ بار ورودی جدید از کاربر دریافت کند. دقت کنید که در صورت انجام عملیات بدون تعداد دفعات محاسبه شود.
  • با نوشتن exit در ورودی اول از برنامه خارج شود.
  • برای اصلاح ورودی‌ها اگر در ورودی عملگر عبارت edit وارد شود تا ورودی دوباره دریافت شود.
  • یک تابع برای ثبت تاریخچه هر رویداد بنویسید
  • در هنگام بسته شدن برنامه، تاریخچه را از آخر به اول چاپ کنید.
  • برنامه را به گونه‌ای بنویسید که اگر فایل برنامه به صورت مستقیم اجرا شود برنامه اجرا شود.
کد
history = []


def save_event(event):
    history.append(event)
    print(event)


def print_events():
    for event in history[::-1]:
        print(event)


def pretty_text(text, symbol="="):
    return f"<< {text} >>".center(20, symbol)


def opration(n1, n2, op):
    n1_op_n2 = {
        "+": n1 + n2,
        "-": n1 - n2,
        "*": n1 * n2,
        "**": n1**n2,
        "/": n1 / n2,
        "//": n1 // n2,
        "%": n1 % n2,
        "==": n1 == n2,
        "!=": n1 != n2,
        "<": n1 < n2,
        "<=": n1 <= n2,
        ">": n1 > n2,
        ">=": n1 >= n2,
    }

    return f"{n1} {op} {n2} = {n1_op_n2[op]}"


def main():
    save_event(pretty_text("Start"))
    counter = 1
    while counter <= 3:
        print(pretty_text("Input", "-"))
        try:
            n1 = input("n1: ")
            if n1 == "exit":
                save_event(pretty_text("Exit"))
                break

            n1 = float(n1)
            n2 = input("n2: ")
            n2 = float(n2)
            op = input(f"op: ")

            if op == "edit":
                save_event(pretty_text("Edit"))
                continue

            valid_op = "+,-,*,**,/,//,%,==,!=,<,<=,>,>="
            if op not in valid_op.split(","):
                save_event(f"{op} is not valid operator! ({valid_op})")
                continue

            save_event(f"{counter}: {opration(n1, n2, op)}")
            counter += 1

        except ZeroDivisionError:
            save_event(f"ZeroDivisionError: {n1} {op} {n2} is not valid output")
        except ValueError:
            save_event("ValueError: Please enter number for n1 and n2!")
        except Exception as e:
            save_event(f"Error: {str(e)}")

    save_event(pretty_text("End"))


if __name__ == "__main__":
    main()
    print_events()

رابط گرافیکی

یک برنامه گرافیکی بنویسید که:

  • از کاربر دو عدد و یک عملگر دریافت کند و آن عملگر را برای آن دو عدد اعمال کند و در نهایت حاصل را به همراه اعداد و عملگر چاپ کند. برچسب و ورودی هر بخش در یک ردیف باشد و حاصل با یک دکمه در پنجره نمایش داده شود.
  • تمام خطاهای ممکن با پیام مناسب در یک جعبه پیام نمایش داده شود.
  • یک دکمه برای خروج درنظر گرفته شود.
  • تاریخچه را در یک لیست باکس از آخر به اول نمایش دهد.
  • یک دکمه برای پاک کردن تاریخچه انتخاب شده در لیست باکس در نظر گرفته شود..
کد
import tkinter as tk
from tkinter import messagebox

# =========== Variables ================
vars = {
    "counter": 1,
    "valid_op": "+,-,*,**,/,//,%,==,!=,<,<=,>,>=",
}


# =========== Functions ================
def save_event(event):
    lbl_rsl.config(text=event)
    lst_hst.insert(0, event)


def showerror(title, msg):
    save_event(f"{title}:\n{msg}")
    messagebox.showerror(title=title, message=msg)


def clear_entries():
    ntr_n1.delete(0, tk.END)
    ntr_n2.delete(0, tk.END)
    ntr_op.delete(0, tk.END)


def clear_events():
    lst_hst.delete(0, tk.END)


def selection(event):
    selection = lst_hst.curselection()
    index = selection[0]
    lbl_rsl.config(text=lst_hst.get(index))


def remove():
    selection = lst_hst.curselection()
    if not selection:
        return

    index = selection[0]
    lst_hst.delete(index)


def close():
    root.destroy()


def opration(n1, n2, op):
    n1_op_n2 = {
        "+": n1 + n2,
        "-": n1 - n2,
        "*": n1 * n2,
        "**": n1**n2,
        "/": n1 / n2,
        "//": n1 // n2,
        "%": n1 % n2,
        "==": n1 == n2,
        "!=": n1 != n2,
        "<": n1 < n2,
        "<=": n1 <= n2,
        ">": n1 > n2,
        ">=": n1 >= n2,
    }

    return f"{n1} {op} {n2} = {n1_op_n2[op]}"


def calculate():
    try:
        n1 = ntr_n1.get()
        n1 = float(n1)
        n2 = ntr_n2.get()
        n2 = float(n2)
        op = ntr_op.get()

        if op not in vars["valid_op"].split(","):
            title = f"{op} عملگر معتبر نیست!"
            msg = f"عملگرهای معتبر: " + vars["valid_op"]
            showerror(title, msg)
            return

        title = vars["counter"]
        msg = opration(n1, n2, op)
        save_event(f"{title}:\n{msg}")
        vars["counter"] += 1

    except ZeroDivisionError:
        title = f"خطا تقسیم بر صفر"
        msg = f"حاصل {n1} {op} {n2} تعریف نشده است!"
        showerror(title, msg)
    except ValueError:
        title = f"خطا مقدار"
        msg = f"لطفا مقدار معتبر وارد کنید!"
        showerror(title, msg)
    except Exception as e:
        title = f"خطا"
        msg = str(e)
        showerror(title, msg)


# ===========    GUI    ================
root = tk.Tk()
root.title("ماشین حساب")
root.geometry("400x400")

frm_n1 = tk.Frame(root)
frm_n1.pack(pady=2)
lbl_n1 = tk.Label(frm_n1, text="عدد اول:")
lbl_n1.pack(side="right", padx=2)
ntr_n1 = tk.Entry(frm_n1)
ntr_n1.pack(side="right", padx=2)

frm_n2 = tk.Frame(root)
frm_n2.pack(pady=2)
lbl_n2 = tk.Label(frm_n2, text="عدد دوم:")
lbl_n2.pack(side="right", padx=2)
ntr_n2 = tk.Entry(frm_n2)
ntr_n2.pack(side="right", padx=2)

frm_op = tk.Frame(root)
frm_op.pack(pady=2)
lbl_op = tk.Label(frm_op, text="عملگر:")
lbl_op.pack(side="right", padx=2)
ntr_op = tk.Entry(frm_op)
ntr_op.pack(side="right", padx=2)

tk.Button(
    root,
    text="محاسبه",
    command=calculate,
).pack(pady=5)

lbl_rsl = tk.Label(root, text="---")
lbl_rsl.pack(pady=5)


frm_lst = tk.Frame(root)
frm_lst.pack(padx=5)
scb = tk.Scrollbar(
    frm_lst,
    cursor="hand1",
)
scb.pack(side="right", fill="y", pady=5)
lst_hst = tk.Listbox(
    frm_lst,
    height=10,
    width=50,
    yscrollcommand=scb.set,
)
lst_hst.bind("<Double-1>", selection)
lst_hst.pack(side="right", pady=5, padx=5)
scb.config(command=lst_hst.yview)

frm_btn = tk.Frame(root)
frm_btn.pack(pady=5)

tk.Button(
    frm_btn,
    text="حذف رویداد",
    command=remove,
).pack(side="right", padx=5)
tk.Button(
    frm_btn,
    text="حذف کل رویدادها",
    command=clear_events,
).pack(side="right", padx=5)
tk.Button(
    frm_btn,
    text="بستن",
    command=close,
).pack(side="right", padx=5)

root.mainloop()

فایل

یک برنامه گرافیکی بنویسید که:

  • از کاربر دو عدد و یک عملگر دریافت کند و آن عملگر را برای آن دو عدد اعمال کند و در نهایت حاصل را به همراه اعداد و عملگر چاپ کند.
  • برای عملگرهایی که وجود ندارن یک پیام برای کاربر چاپ کند.
  • خطای تقسیم بر صفر را به طور خاص مدیریت کند.
  • برای باقی خطاها یک پیام متناسب با نوع خطا چاپ کند.
  • یک دکمه برای خروج درنظر بگیرید.
  • یک تابع برای ثبت تاریخچه هر رویداد بنویسید
  • تاریخچه را در یک لیست باکس از آخر به اول چاپ کنید.
  • یک دکمه برای پاک کردن تاریخچه وقتی آنرا انتخاب کرده است در نظر بگیرید.
  • تغییرات تاریخچه در هنگام اجرای برنامه بارگذاری شود و در هنگام بسته شدن در فایل ثبت شود.