{ "cells": [ { "cell_type": "raw", "id": "front-matter", "metadata": { "vscode": { "languageId": "raw" } }, "source": [ "---\n", "title: \"مسائل في التغليف والتعميم وإعادة الهيكلة\"\n", "og:title: encapsulation_generalization_refactoring_problems\n", "toc: true\n", "format:\n", " html: default\n", "---" ] }, { "cell_type": "markdown", "id": "download-notebook", "metadata": {}, "source": [ "[تحميل الدفتر](https://raw.githubusercontent.com/HassanAlgoz/python/main/book/chapters/ch3-functions/exercise_3b.ipynb)" ] }, { "cell_type": "markdown", "id": "intro-setup", "metadata": {}, "source": [ "لتكون المسائل قريبة من الحسّ والبصر، سنستخدم مكتبة [`jupyturtle`](https://pypi.org/project/jupyturtle/) كما في دفتر التطبيقات.\n", "\n", "**التهيئة:** ثبّت الحزمة إن لزم (راجع [إعداد بيئة التطوير](../ch0-intro/lesson_setup.ipynb))، ثم نفّذ خلية الاستيراد التالية قبل الحلول.\n", "\n", "بعد كل تمرين (حيث يظهر عنوان **اختبار مرئي**) نفّذ الخلية البرمجية التالية لترى إن كان رسمك يطابق المتوقع." ] }, { "cell_type": "markdown", "id": "42d5eb8e", "metadata": {}, "source": [ "```sh\n", "uv add jupyturtle\n", "```" ] }, { "cell_type": "code", "execution_count": null, "id": "imports", "metadata": {}, "outputs": [], "source": [ "import math\n", "from jupyturtle import (\n", " Turtle,\n", " make_turtle,\n", ")" ] }, { "cell_type": "markdown", "id": "b95256c0", "metadata": {}, "source": [ "المتغير `delay` يتم تمريره للتحكم بسرعة الرسم:" ] }, { "cell_type": "code", "execution_count": null, "id": "0c35a15a", "metadata": {}, "outputs": [], "source": [ "# Control speed of drawing\n", "fps = 10\n", "delay = 1 / fps" ] }, { "cell_type": "markdown", "id": "ex-1", "metadata": {}, "source": [ "## رسم مستطيل\n", "\n", "الفكرة: استخدم حلقة وانعطافات السلحفاة لتتبّع محيط المستطيل.\n", "\n", "**المطلوب:** نفّذ الدالة `rectangle(t, width, height)` لترسم مستطيلًا بالأطوال المعطاة." ] }, { "cell_type": "code", "execution_count": null, "id": "ex-1-code", "metadata": {}, "outputs": [], "source": [ "def rectangle(t: Turtle, width: float, height: float) -> None:\n", " pass" ] }, { "cell_type": "markdown", "id": "ex-1-test-md", "metadata": {}, "source": [ "**اختبار مرئي:** نفّذ الخلية التالية بعد إكمال `rectangle`.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-1-test", "metadata": {}, "outputs": [], "source": [ "t = make_turtle(delay=delay)\n", "rectangle(t, 80, 40)\n" ] }, { "cell_type": "markdown", "id": "ex-2", "metadata": {}, "source": [ "## رسم معين\n", "\n", "الفكرة: المَعِين يُرسم بمدّ متعاقبة مع زاويتي انعطاف متكاملتين (تكملان 180°).\n", "\n", "**المطلوب:** نفّذ الدالة `rhombus(t, length, angle)` لترسم معينًا بطول ضلع `length` وزاوية داخلية `angle` (بالدرجات)." ] }, { "cell_type": "code", "execution_count": null, "id": "ex-2-code", "metadata": {}, "outputs": [], "source": [ "def rhombus(t: Turtle, length: float, angle: float) -> None:\n", " pass" ] }, { "cell_type": "markdown", "id": "ex-2-test-md", "metadata": {}, "source": [ "**اختبار مرئي:** نفّذ الخلية التالية بعد إكمال `rhombus`.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-2-test", "metadata": {}, "outputs": [], "source": [ "t = make_turtle(delay=delay)\n", "rhombus(t, 70, 60)\n" ] }, { "cell_type": "markdown", "id": "ex-3", "metadata": {}, "source": [ "## تعميم بمتوازي أضلاع\n", "\n", "الفكرة: أعد استخدام منطق الرسم المشترك بين أشكال متعددة.\n", "\n", "**المطلوب:** نفّذ `parallelogram(t, side1, side2, angle)`، ثم أعد كتابة `rectangle` و`rhombus` بحيث تستدعيان `parallelogram` (المستطيل معين بزاوية 90°، والمعين بضلعين متساويين)." ] }, { "cell_type": "code", "execution_count": null, "id": "ex-3-code", "metadata": {}, "outputs": [], "source": [ "def parallelogram(t: Turtle, side1: float, side2: float, angle: float) -> None:\n", " pass\n", "\n", "\n", "def rectangle(t: Turtle, width: float, height: float) -> None:\n", " pass\n", "\n", "\n", "def rhombus(t: Turtle, length: float, angle: float) -> None:\n", " pass" ] }, { "cell_type": "markdown", "id": "ex-3-test-md", "metadata": {}, "source": [ "**اختبار مرئي:** مستطيل، ثم معين، ثم متوازي أضلاع عام — بعد إكمال التعريفات الثلاثة.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-3-test", "metadata": {}, "outputs": [], "source": [ "t = make_turtle(delay=delay, width=400)\n", "\n", "t.pen_up()\n", "t.forward(-120)\n", "t.pen_down()\n", "rectangle(t, 80, 40)\n", "\n", "t.pen_up()\n", "t.forward(100)\n", "t.pen_down()\n", "rhombus(t, 50, 60)\n", "\n", "t.pen_up()\n", "t.forward(80)\n", "t.pen_down()\n", "parallelogram(t, 80, 50, 60)\n" ] }, { "cell_type": "markdown", "id": "ex-3-1", "metadata": {}, "source": [ "## دالة القفز `jump`\n", "\n", "الفكرة: اجمع تسلسلًا متكررًا من أوامر السلحفاة في دالة واحدة.\n", "\n", "**المطلوب:** اكتب الدالة `jump(t, length)` التي تنفّذ بالترتيب: `pen_up()` ثم `forward(length)` ثم `pen_down()` — بحيث تتحرك بمسافة `length` دون رسم، وتنتهي والقلم للأسفل.\n", "\n", "يمكنك بعدها استخدام `jump` لفصل أشكال متجاورة بدل تكرار الثلاثة أوامر." ] }, { "cell_type": "code", "execution_count": null, "id": "ex-3-1-code", "metadata": {}, "outputs": [], "source": [ "def jump(t: Turtle, length: float) -> None:\n", " pass" ] }, { "cell_type": "markdown", "id": "ex-3-1-test-md", "metadata": {}, "source": [ "**اختبار مرئي:** نفس الأشكال السابقة باستخدام `jump` بدل تكرار `pen_up` / `pen_down`.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-3-1-test", "metadata": {}, "outputs": [], "source": [ "t = make_turtle(\n", " delay=delay,\n", " width=400,\n", ")\n", "\n", "jump(t, -120)\n", "rectangle(t, 80, 40)\n", "\n", "jump(t, 100)\n", "rhombus(t, 50, 60)\n", "\n", "jump(t, 80)\n", "parallelogram(t, 80, 50, 60)\n" ] }, { "cell_type": "markdown", "id": "ex-4", "metadata": {}, "source": [ "## «فطيرة» من مثلثات متكررة\n", "\n", "الفكرة: ابنِ شكلًا أكبر بتكرار أداة رسم صغيرة (قطعة مثلثية).\n", "\n", "**المطلوب:**\n", "\n", "1. نفّذ `triangle(t, r, angle)` لترسم قطعة مثلثية واحدة (كما في النص الأصلي للفصل).\n", "2. نفّذ `draw_pie(t, n, r)` لتكرار هذه القطعة `n` مرّة وتكوين فطيرة كاملة." ] }, { "cell_type": "code", "execution_count": null, "id": "ex-4-code", "metadata": {}, "outputs": [], "source": [ "def triangle(t: Turtle, r: float, angle: float) -> None:\n", " pass\n", "\n", "\n", "def draw_pie(t: Turtle, n: int, r: float) -> None:\n", " pass" ] }, { "cell_type": "markdown", "id": "ex-4-tri-test-md", "metadata": {}, "source": [ "**اختبار مرئي (مثلث واحد):** نُسرّع الرسم بقيمة `delay` أصغر.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-4-tri-test", "metadata": {}, "outputs": [], "source": [ "tri_fps = 40\n", "tri_delay = 1 / tri_fps\n", "t_tri = make_turtle(delay=tri_delay)\n", "triangle(t_tri, 60, 20)\n" ] }, { "cell_type": "markdown", "id": "ex-4-pie-test-md", "metadata": {}, "source": [ "**اختبار مرئي (فطائر):** ثلاث فطائر بأعداد أضلاع مختلفة؛ يفترض أن تكون `jump` قد عرّفتَها في التمرين السابق.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-4-pie-test", "metadata": {}, "outputs": [], "source": [ "size = 40\n", "margin = 2 * size + 20\n", "\n", "t = make_turtle(\n", " delay=delay,\n", " width=50 + (size + margin) * 3,\n", ")\n", "\n", "t.pen_up()\n", "t.forward(-80)\n", "t.pen_down()\n", "\n", "draw_pie(t, 5, size)\n", "\n", "jump(t, margin)\n", "draw_pie(t, 6, size)\n", "\n", "jump(t, margin)\n", "draw_pie(t, 7, size)\n" ] }, { "cell_type": "markdown", "id": "ex-5", "metadata": {}, "source": [ "## زهرة بأوراق\n", "\n", "الفكرة: اجمع زهرة كاملة بتكرار رسم ورقة واحدة.\n", "\n", "**المطلوب:** باستخدام الدالة `arc` المعطاة في الخلية التالية، نفّذ `petal(t, r, angle)` لرسم ورقة واحدة، ثم `flower(t, n, r, angle)` لتجميع `n` ورقة في زهرة." ] }, { "cell_type": "code", "execution_count": null, "id": "ex-5-arc", "metadata": {}, "outputs": [], "source": [ "def arc(t: Turtle, r: float, angle: float) -> None:\n", " for i in range(r):\n", " t.forward(r, i * 2)" ] }, { "cell_type": "markdown", "id": "ex-5-arc-test-md", "metadata": {}, "source": [ "**اختبار مرئي:** الدالة `arc` المعطاة (مرجع قبل رسم الورقة).\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-5-arc-test", "metadata": {}, "outputs": [], "source": [ "t = make_turtle(delay=delay)\n", "arc(t, 10, 36)\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-5-code", "metadata": {}, "outputs": [], "source": [ "def petal(t: Turtle, r: float, angle: float) -> None:\n", " pass\n", "\n", "\n", "def flower(t: Turtle, n: int, r: float, angle: float) -> None:\n", " pass" ] }, { "cell_type": "markdown", "id": "ex-5-petal-test-md", "metadata": {}, "source": [ "**اختبار مرئي:** ورقة واحدة بـ `petal`.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-5-petal-test", "metadata": {}, "outputs": [], "source": [ "t = make_turtle(delay=delay)\n", "petal(t, 10, 36)\n" ] }, { "cell_type": "markdown", "id": "ex-5-flower-test-md", "metadata": {}, "source": [ "**اختبار مرئي:** زهرة كاملة؛ لوحة أكبر كما في دفتر الفصل.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-5-flower-test", "metadata": {}, "outputs": [], "source": [ "t = make_turtle(\n", " delay=delay,\n", " height=400,\n", " width=400,\n", ")\n", "flower(t, 8, 10, 36)\n" ] }, { "cell_type": "markdown", "id": "ex-6", "metadata": {}, "source": [ "## حلزون\n", "\n", "البرنامج التالي (من نفس الفصل) يوضّح رسم مضلّع ودائرة تقريبية باستخدام السلحفاة — اقرأه كسياق، ثم انتقل للمطلوب.\n", "\n", "**المطلوب:** اكتب الدالة `spiral(t, n, length, gap)` التي ترسم حلزونًا: في كل خطوة تمشي `length` ثم تنعطف بزاوية ثابتة، وتزيد `length` بمقدار `gap` للخطوة التالية (كرر `n` مرّة)." ] }, { "cell_type": "code", "execution_count": null, "id": "ex-6-context", "metadata": {}, "outputs": [], "source": [ "def polygon(t: Turtle, n: int, length: float) -> None:\n", " angle = 360 / n\n", " for i in range(n):\n", " t.forward(length)\n", " t.left(angle)\n", "\n", "\n", "def circle(t: Turtle, radius: float) -> None:\n", " circumference = 2 * math.pi * radius\n", " n = 10\n", " length = circumference / n\n", " polygon(t, n, length)\n", "\n", "\n", "# مثال: t = make_turtle(delay=delay); t.jump_to(120, 120); circle(t, 60)" ] }, { "cell_type": "markdown", "id": "ex-6-circle-test-md", "metadata": {}, "source": [ "**اختبار مرئي (اختياري):** دائرة تقريبية باستخدام `polygon` و`circle` من خلية السياق.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-6-circle-test", "metadata": {}, "outputs": [], "source": [ "t = make_turtle(delay=delay)\n", "t.jump_to(120, 120)\n", "circle(t, 60)\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-6-code", "metadata": {}, "outputs": [], "source": [ "def spiral(t: Turtle, n: int, length: float, gap: float) -> None:\n", " pass" ] }, { "cell_type": "markdown", "id": "ex-6-spiral-test-md", "metadata": {}, "source": [ "**اختبار مرئي:** الحلزون بعد إكمال `spiral`.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ex-6-spiral-test", "metadata": {}, "outputs": [], "source": [ "t = make_turtle(delay=delay)\n", "spiral(t, 50, 5, 0.2)\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "pygments_lexer": "ipython3" } }, "nbformat": 4, "nbformat_minor": 5 }