{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Мини-проект: магазин из трёх таблиц\n",
    "\n",
    "Собрать данные магазина из заказов, справочника товаров и справочника клиентов, проверить соединение, сверить с готовой таблицей и посчитать то, чего раньше не было, — прибыль и маржу по городам и товарам, доставку по каналам.\n",
    "\n",
    "Курс pandas · урок `pd-project-merge` · [урок на сайте](https://ds-edu-trainer.vercel.app/courses/pandas/project-merge).\n",
    "\n",
    "Выполняйте ячейки по порядку (Shift+Enter), начиная с первой — она готовит урок. После каждого упражнения идёт\n",
    "ячейка проверки: она печатает ✓ / ✗ и итог."
   ],
   "id": "intro"
  },
  {
   "cell_type": "code",
   "metadata": {
    "cellView": "form",
    "jupyter": {
     "source_hidden": true
    }
   },
   "source": [
    "# @title Подготовка урока — выполните эту ячейку первой\n",
    "# Проверяет версии пакетов, записывает файлы данных в папку data/ и определяет _check — проверку упражнений.\n",
    "import base64, os, zlib\n",
    "\n",
    "for _name, _min in {\"numpy\":\"2.0\",\"pandas\":\"3.0\"}.items():\n",
    "    try:\n",
    "        _have = __import__(_name).__version__\n",
    "    except ImportError:\n",
    "        print(f\"Нет пакета {_name}: выполните %pip install {_name} и перезапустите ядро\")\n",
    "        continue\n",
    "    if tuple(int(x) for x in _have.split(\".\")[:2]) < tuple(int(x) for x in _min.split(\".\")):\n",
    "        print(f\"Урок написан для {_name} {_min} и новее, у вас {_have}: выполните %pip install -U {_name} и перезапустите ядро\")\n",
    "\n",
    "_DATA = {\n",
    "    \"orders.csv\": \"\"\"\n",
    "eNqVfUuOdjFu3TxrKQMiqee4N9A7CAx3AzGQtBOne+CZ7RV50oEdJ/EW/t5R8En3QfKeS1XNCoVzJF191IuHov7u73/3+7//z3/7\n",
    "u6/f/fUff//1N3/6n3/8u/+2/vHf//7vfvenv/nj58//8ae//sMf//aP//D1N//lr//wh9//1/9EKSX64sTlrxL9VaKv36RRvn5L\n",
    "/Yu/fv2fX//yl3/89b9//fkv//zrP379+68///q3v/zTGyWNL4oobCllfP2W0ofyH3/5x1//+uvff/2/X//r159//d9f//rrz2+E\n",
    "VCOCGAIn+fptki/6+ss//fqXX//2l39+BX0+1oDyDeKv36T86RH59Mhb1cUSRPZdWA2FJM0urLYhzYJa/fpt4i95b0i/CfL1m88P\n",
    "9VsKCcMS2ueXbF/1lUDJEnr6+i3VTw2vn0pkKYNnd4YUthT+/Ewl+PEhgYKfDBJy0FOkLCd//YZozK6NfmPKhvL5zeOfj4qto6VJ\n",
    "COtQdlTO72jhUKRmKdLnp9uBQt2C+hpNbQ+qX9mClInVr98wtznkop+fk6GksX7+918TEmrQ05AwAgNjsoTazznh/SsAJclXjijs\n",
    "mvUZvxR9ByAkir5DLKHlg6B/Mgiqbpbk7H5XAmYEQX6+5WJAxPlcG947Spl9+5S7HyncDGX9HC3qKkQIjQoRcmS2avz0r9/QSAfB\n",
    "9A4CNTfIeBhQmrNT9T8GAM1hpUGSbHU1T5DsQb46IQBqvjq2bZL1q0SzA6Js1hNRBj0+lHTMxKYp2YFkO8NDSoqbgig5rqUYCpW1\n",
    "3XKtr7bcvHY2tAc9frdmq6ttTkLRcESUzYZQbrOm9Fk76mEdP6TUuJZhKCxts5HIyRE+c1FzPYRA83MNiGxrZzeyM38EevxqmQ2I\n",
    "qG/XeEgpYe9msZQ5z0Qb7pxfeuFHhBrMj7nYJs0zgPguRCC/DuXb8Omz7+e6XS8gJba23Axl9vrTeADo+VHdggpNUNmDyK0MCPQ0\n",
    "w2FBmcEaA0HdTUMlGVBq/TiFvfcaolANf5tC7rdp23kXUmILKGwpUua3vG8AitgvqQ0ssAj0OSJZkBoqfOzAPntWCyoW1AfYpiEQ\n",
    "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\n",
    "\"\"\",\n",
    "    \"products.csv\": \"\"\"\n",
    "eNp9k01qG0EQhfc6RR+gDNU9P5q5hW9gjCyCF4mM4iyym7EMCligeBUwgRDH4GwCI1tjj35mfIVXNwrV4/hPIsvu+V6/qlc1R8PB\n",
    "wafe8d7hAX3Yf9+n3v5x/91g+JmOhoe9PvUGH487u2wJfyTHg2QoJZcczY7kWPvDxFiDJW4JF2jkFCXZMGJKutzZZedvsZIR1pih\n",
    "kqlxEZuXdJwyBYnCgbqcokKDh61oN2UKA0VDwrlkKHCPCisPb1ThUqaufzh6ujWYocS9ov6MCjWKTSPHFFqVxoRrUatazrAwMkaB\n",
    "hbHc8td6oiBispHSXcI3lFjJ+X/5lMn6eBLCLx9O/QaJQiYXK5ISLn2nNzJFjUYfzTFDI5mJXkpczGSZO7uWCb/RaItYocDc4FZx\n",
    "mWCJCgvCz/YejeRygopswpSq0hJ+oJQxStQy0bga3Ej+6FxuUUZM2ol1hO8+zDkKrGRicGPky8sqtskD95iEDXxyOn3JNjln//UW\n",
    "Ei4kkxHusERhAo1gjZXWrfBI/SlKmZwOxEaEK11a1DLeed7f17hNUqbU87GmPZLMP64LjrkuiExfK1zITDbwFXUfB4AaFZYG9zor\n",
    "FJKhkXG7Bm/sdF/iULXJ08ph7XNSW21Pla3tVywlb6uWkT4rZxobk029fUq40n9AJnKiHw1m/mcrcOfNy+1PuLAduWPCJUrJfAHL\n",
    "52i3y6wOPIq58xfQUEqA\n",
    "\"\"\",\n",
    "    \"customers.csv\": \"\"\"\n",
    "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\n",
    "MbA4youwiqExZ9I32UIn978sij3j\n",
    "\"\"\",\n",
    "    \"shop_orders.csv\": \"\"\"\n",
    "eNrNvcuudclxHjjvp6gHOAQy8p5jPoghUIRbQLfkZlMDzapIAzJgArIGDQOCG4YvgHtioESpJKrIKr3CPm9krFzn3ztiX1bGbR31\n",
    "jKw6Fd/Oy4rMjIjviz/7xR///Bf/6k/++O2P/+iXP3/72Z//37/8s/9z/wc/+5Nf/sXbz/73P/rTP/35//H2sz/65c//9Z/94i/e\n",
    "/s0v/uyP//xnv3z7N7/4k5/9/O3/+vM/+tNf/skv/+J/gxACvMUQy08C/CTA20/DKG+X/3T58f2by/eX316+fbv84fLt+9eX7y/f\n",
    "vf/q8s+X31++u/zT+zdvl/9w+f79m8t379+8f/P+6+1P3v/92+VvLj++/9vLd5c/XH68/P7y/eXbr96/fv/1+19efrh8+/5XbymG\n",
    "8BYtqP/j8u3ln94u//X968u3l9++/9Xlh8uPl3/66v2by99efnz/+qsSvrr83Vus4Q0mTKQwZdzB/PP715ffXX5/+fHyD5fvLj9c\n",
    "fnf57u3yXy6/v3x7+fvt795/dfnd2+X/u/x4+X4O6dvL3391+bsN6v03l+8vv7v80xt0E9jHiP7H+1+/f3354f3fb6P5y+2ffQVh\n",
    "DiaVL/YTsR9D2ib828s/Xr69/PD+m7f3b7b/7P1X12V4u/zP9397+d3lx8s/X373/ldfxX122hAb/PiR/+3y+/dfX3748stK/rKa\n",
    "+WYovv005KKa5v94+W77ve9fv0X4YrlQy+nuJ560OytBhRS2X/vt5YfL9++/+snlP0+0796/vvzt+6/fv7783eNMMTZonUiNIrW6\n",
    "QHo+ldcF/5ttaO+/vvzh8rd4yesIb2ni9Rteevvp9h1e/p9tKj5gfnf5YQH1sGr/af5Hf3/59vL79998dfntV+//Dn8ul++2if1A\n",
    "HxS9FdVoP+b4P16+u/z+/a+ffzTjY4K3jYQhe+A5mv88B/jrbVzbav56/s23X13+cPnu8vcfGybm8DEwAIoyIm+bLj6B3XaktmN6\n",
    "u/y/lx8vv52j+N1c6K+38TD2xvY/vrr87eW7yz9+tS3R/By25fv26hzih3Nwg/2f79/Mv5gf4+XHn7x/s03i+zfvv/kKth/xd2+Q\n",
    "y8eH5wb61/P7+8f5F9t38AUpfvkQAPm+/PZTgPESibt2vA9hH2cm6JvDYThM9lcOhQ6uMTc9B2D//chBluN1Oj7IV9/wvhUbRUud\n",
    "7Y5ZG2IH6RSkJzpnktO1yQyyrgB52kQOtL79NMYmujY9Ob/nfomBmA3j/pR1cixRD8aao2S2z71YRqAgtfMWgnPn0dpe78u5h2K8\n",
    "mx9QXda2r+4vt3///ptt6X+8/Pb9m49p++4NrouhApOeHfuSJArVMuN6fIZ51lbdVzrffc4HtzGNT9PZX1z2YyFGIebVJY77LfCe\n",
    "WRGdPW0blPfhFhsBePz+LJdSMCNwXKDKPmtf7TOEjrb+9lMY4dXxL9y1auvM2d8d4CD2t0P1xcHMfgSAzK7y5EyBTkzNfgBJBsCP\n",
    "WiQQ2lyt4T4Vkc718kpovIcmV1DOsy+h82ZsYJJvbPVASPnOeFK+VwVvHjfM5TFhGiL55v9mCxBd/mF+9Wmbwz9cfv9WrpuwEAgo\n",
    "ZbG1GbfL/bdX+ttzsp3bYDbK+dAbnY3alFfi5c3SBCe86KfbYQRhe8VVEQzPmdkwOGszCEJM7ZwH3gTL4Q4ss5/r5OObw5u/5fuv\n",
    "5i/97ZyGH7eA7TbYN7iOzwAp3A8Z6Frdb7ubYYuv5KMsPvociSGA7rp9TRjKW1BOFO719dCacMlZuKtcQgu+qIxXaC50QssQ3DRe\n",
    "xhrsppfP23w70WDLX8Xq/BLUAgi2WCMID9+Og2tkI3DXtFODBfQGi9ogK3CTZeZNHntQlBwFtyvWs9WE8CryWwIxGlrn3ZKZGWat\n",
    "efbDe859gbvPVHvz5L0s3OAE26tEipmKMI76YpX2ASW6Sq9vG8ojmw8gfwzsAOjMjIfB2aeFAf91fkBbWcD3twffG9zMF2q+D+n1\n",
    "knEMG0DkG3l6lFIJIoz6atZMW5eNwjyASrszqLsAsp5mBR0eacMqziE3BcDC5Q5qMLQTrsdzbmqgSLUc1JL4vMYrEMjNsWjuxov4\n",
    "W3aEWiRTnFDYgb8a6ZrFLE+lv9x/1YggrJ0yIElPgX3zoVNsK9roTZBYZr2ka6YIJbDPyScR5FqotddFGsbjUQPE2bH7nFRiHO6D\n",
    "Y+LL9G610Z+srERjvnBqJ2iPN0arJ0Y+v2yeuLL3DS/nygd4uoH++za499+8/2r7v19tc7qdB5d/mKP6brvJ7zAtEJitrI6b+eOe\n",
    "IA053C17XYNv6rVFav/1c3vxMuMbYoczWiImH67h+rNln9pMzd9fwp3uAFoYbQClFYrXg3c5QKsE4cE96AMg+7I3upOiWz2RyTzn\n",
    "CGv97iMYyjpDxuaKPoCq4qKG/Gt7kp/RHXI9EKuQoqL2+WUKdC5QBwoBnxIid0K1vGp7JD+BeRlkvuF0xiVl8T3dbY3uW3mms79I\n",
    "ZvV8Ny2sYkJBQl8HwF3UQqdk4wicVzPdK0VbE0vcsnS++MrC045Opa5gEqy2YifmH5IK+jN1/zwHMR/BpWhqBDonRXZBe3VTHUDN\n",
    "Zq8yGL5hZqB7IL+61YxE+JTT3RF2dcUfiUBt/DmvIp99BjO1n+GcErjoCrbawIWuz5Lu50Ub3UdZ6ShLWz96WbOnsMvfZ+3OeHa8\n",
    "/uiMK5Mg4+bJYziMOagCvFbzyoybFZbzOBuDYEDOoroR/gPWBLS6qkIIxPohScJQOO+EpYhixIkMdEMUBYdOdAO0IAouuoBY9/uU\n",
    "ssoidHlmQIz5OGULuvuJtONkgiMj7jBf0YC49RsIpCwPVdZpqNJf+zp6obk+acyLnCUgEn6MrnX9zF11Gv7yCCwTv1N8azLk4PJQ\n",
    "HfG0qYZ9zgf5DQ95AG5QQmCIcWkDJFewWYsh6mqn//v2bV1+eP/Ln9w+szfo4wsM0B+dh4nok2Q2udlqQHIAczYOj0vfbxLpA8zR\n",
    "wGCnotYJO0D8/5iexcwdHxiA1AA2MGbxv2AwKvu8J7vVuOwgQLIGc1l4OTceQJ4AyNOrhBmWN0wtwuJCgsQMplnw5sQCkjaIMyM/\n",
    "zmf0+YEq78hIqyDmZ1xmxZNTaZRXygBInGAafx2Z1B7PSQbDDVloTK6oyoDkDeJWF9G6f2GoBUR5+NmHxcy3AlJVmEjR9+nANy9Y\n",
    "jkxsMrV7dIU3gMQWYn2WZ1DfxJvevHZXVQJ2SEB1PdYdgUWbr1FY3xQUIJmEuCUrodnFPQBpGGxG41Y9/EkH4vT7SIFgH9Rw5ysC\n",
    "UiSIjXm1V+48DZRBYA+QQkGcecMu3emLTecGwLqeIQ2EDW1z567EFA3A8XMFqQ7s81PP0DuabwmkPjB/e3eMonCUMsHxR7AjAkjE\n",
    "YOIp9TLZimtegCJCm/MoObUBgOQUYmflWo2pECR6EKd4Rj9LDsQEx9+Zt5MzbUmqWBxKNgAJG6Snwg1WAiVYUPiXZiMCN6WBdBMS\n",
    "sCucJUeSCeFFAQIgBYVp9BRJgx0pEaTHklBjLPAqXhCnpPT2VWiycbzApg6MV9YMV+mC3XhQlzUvH0fznLlKDXyMpZoCHvvH0O5G\n",
    "cJZIa/RBW+RHiuuYXl1wr2oBHwDrXJxW2xyuhP4PqAfRaPOhfqXfx11dPFqrQPgF0nBlyccPTfjqfOBqAdjiHHAl3X8gfGJe9mR8\n",
    "yTp6/Qj+1fAqFxCftxPgRDOmUy2Z7v82XKgpYLHNPH4KOn7Ss1J0tfnkZJ4fCCuVgMFRiY5R1x1Ko1g1sgR1DnkBAqOCTd7pCsSi\n",
    "IOfwaWxqPP7dr4y7Wco2pSGo4e4ne2rqND2CTrEQKtD5ycmPpTvdXUWuOnOCt/Yh6RFlXACo6EwoHHUU1xsNOP6ExQXUCUXlqGsm\n",
    "2I5EVKF5STi/FmJ1Kxpaxthl4ZGKzq+Nnxu6Q1LkMFftj3h8HaiN4i1XhnF7rp3aTCqpEcHuGgTPX7ZdicAopYcW7ta7nSRHER3R\n",
    "hKn+ho6/xlQJkayOwT5jN7dIrS9lzNnTwjbM9h4tUZPWKnXG3c8bkrfi+W7qklqAiodXKJ740STLhbdK4VL4vOiNFZv/Ecyba2sE\n",
    "bl1w5Po+dUNfFFc0dCL2J4V5TrVzfBj+a7UNYhO4/TrZPqsH+qODc9emOTMdCMiDroJVzQ96vBuFtnxGEJzoiS5NKvpX35Modc90\n",
    "zuR6bhxBCujlDiYpKmV4aaNeKdQAO/lBbPOVj+Ab4nxaM2fSkXtj0agVVw4DhiSh0TuFkSrNCUqz+83jWWTmX6V8ncyzZm0EgvXw\n",
    "blHkFhUmj1+g4+aap7r1JrV+Go1zRAoG6cQs9UgU7DVBTBaV4Nvlv3JGJja3RqLiGzX/UjEKQZNyCRZ6nTBurhQ02U/BtN28HyRz\n",
    "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\n",
    "\"\"\",\n",
    "    \"delivery_h1.csv\": \"\"\"\n",
    "eNpFWTkOZTcOzH0WBeJOncYw0Magkxmgx4lvbzyJVY4+IelRFMni9v/368efv37/+WP9+OPv/69ff/z187//+U323rJ8XUKXL7+U\n",
    "LV1xKV82VCxfdqlc9j4ofNlYOcseC9k4LgK2oitnzVbeD8TnS4lVSy+VK+ZU4VTPRXLW/dU9CyorHnPVFW/JsOdLHyMNiKAf83uN\n",
    "Qnhtbg532yOUySwoRDLDA83xGPtEv0RyCcytV875s/QuObg7ZXeFstygb3euBe70JFU8B907LoiNvZA1hI4mg5YNB68IyBg5OowC\n",
    "8XG/UsTBl7lXvbUUrul6ak0bcdKh1qTnZHKN8mdDjjy4q/Z6SyWrhtLRaNk6j6ABigqqHB1UcfOzwBWtDvTdG87Wgt1W3N6G97Xz\n",
    "C76hcw1RuLV7tNUHfM/GS48s2Xf30MrHIN3x+fTESH4ScpwiN/j/+YzwsZW933nZMmLIHhXJtnFy2XAi2fEuEqBXLnrfhz3uLRe/\n",
    "n1lEBmFC+IqME4nY3C3Qj0hgCS4qQK9Ic+mAl26sKeVXyK8GeS6ELxFrDiUO1bxDe5xQlOxtg4MNBMR0zpvx1ChfDMoxSm/UDiEs\n",
    "Ru07zCsuw9bB3w1KcfD34FKufqbx4tpYVxzRUwLaD2r/QvhRAzEJqj8CbCMhY0BB0eRxBk6Se0RLGSsltJ8IQZLQfn7Wvewz8R31\n",
    "kxOAJCcASUH6kjldXwC9PIvaL2ingptUfxVYUPgL32vTnggqLXDvVm5CO+3DouGbTfbErjSk7zPinA0NHkQfOTosDuK/HGRGOTEs\n",
    "DnV/yP/0Enm757mwblygW7A0zqMXunEpJxUTEXTnvFeRenX3k0w31KOyvyvlkjJCquhIpDIKUhkFqSA9quQLriqFm6QhrcA9VSf4\n",
    "qI6BVaF/VRhY1ed1GmChyJB60++VjPlXFSlGbTxITeYmQ3GixK8aVWSBY/lF2/t2q4mCaghAarzB9xoC8Uedb3CoyJHE1GMkYg5W\n",
    "LzwLCFZHBNJAktQL4XtVoP7RsFtYaMCJNAKSRZLHIFgDRo4zK4kcr/lqFE2FNBfA95r02UP80URxpQkPyubmebFAC/YtKqfIvsj+\n",
    "IvhRlP5C+FFUDzGshQiqjQiqLaQGZQoMa/vENW3e0BOClCDWRgLTPlDx2ZPZ9cvAg4dDEx+DJAeFkB4C7eCOgzCnp+FsB0a2jTrC\n",
    "tpDSEdT2vMK2cylGO7ZzxDPmYdvwU9vQkwn8yASliolyDVcIHMkElYpJcq3WcIOiTJDpTafYMpWpl+2i+a1NMW060do0RsN2a+l3\n",
    "CpWKaX/4eyRMYcY32PQahmxsRLMZahVDOjaDt5ohW5oh3ZsNGIzZ2Ahm80ln5ga2Th1dMD/qC3hvlzd4kzpTu1lMyrHgDYGIZIGM\n",
    "acSzxWfpq4fI9b6knQMh1QIlryUqFmNRbanglkg7lvSljCVzRSYUnDVVguXEDEtauibmWQmXUJNaTVFn5ZCuJuYZymorQM6Kvlpn\n",
    "TiEt2y2q715PU2aNvsPacSomPlvTkZo66oZgTbgdXHBohIMLDqKSnala7JbUbynJoiDHafjsxfN3zpmZ/cvMb2kc1bdxD0nB96Qd\n",
    "38mlmprBd4PFhFWXkd8JZRfo3wVAcHlR2yVwHDBwgfh+W+JHndG2K/irrHMDniuikQPJrojaroGlHAl1+j5XaMf1TNzzm5Tvmk3R\n",
    "6IZI5MSxm3MNBnAbB3JDXeEGELid1W/ttsb3BgcI3AEz9xkauE/h4g4NeUIHXliCgzqTsl8U35uCFgiAzNkbO2HsAQvH9B0etfoR\n",
    "iKUeU/h6oqvxRCx1gtjTIGSSf8IEmfy0oOYEBjwPdFq8oqY08lIu2ZtEeDkeWhNLvfCAqhcFvPgAdsbe0xd4o2rxVlKGTaRMb5SO\n",
    "3vChLrC9tfX7EsWp37R8CfgQIOwHHnp8naeBA+kPIpyfwqme/OIEcOzhHltmMzjViv2KrtjjPgH4xs6nt0BZHZhoxSZvQZYJtsRB\n",
    "+AYycQjgFRxphbwUEFI4NAVjsCMO3ZBYEZ1DYdlQ45rzi/GdUIivUH2wqA4d5wyD54Rh8BTGC8wGEGHwnTBcYAhvwbY4rL/0I5ec\n",
    "1imcVzj17/D/cFuz6SCQh8Mx9YgL4Ef1uEE4yvZAYxw3D99joViCCcJ5PN5YKiKxh8FQBAJExMFFSRtfAD9KYcacFBmJ0VMAv5GJ\n",
    "PbhQolCJRCUUNfCKmkIoCuiKMuwBXcHOOGo8qGoK4ihqh41xNLTTM5WIpoOipg70xdEod6MToja1301q8lcc1ChxkOHjoKeJYxPG\n",
    "4+CGExPK4iC8xcHkL86MzYJTrdwAQW5gLJGBc4/6cwNiuYOn8ITcKORyN7mNh6bs1+AmO+MU8Bdk+BRYICXe21PQeqfUQ1sKMJYC\n",
    "/0wdAyc641SwZ2OcCoQlB9OpUFBqcbfnJg620lChJErptOma0iY/JhGchhorjfLb5Pj8F8FpY+J0lOrpVJBPgE7H2DLZF6fzBU4L\n",
    "OIrQdFqAs60MeFHGpIAMPCFQrGdMmZgxCMtAO5NR+K7xHaJ05iYFBGfiATkZJtNHszkpIBM1aHI0nYnRcTL/5p1t3V3k3ywdx887\n",
    "3LofsIjOooIKZVxWcQ0pMlFGJ4fT2TMeylbsoQ/Inn4sO3g8cWrSTDZCUDYVdDakPYjReZAjk5Pp5HwrDzDA0XSyjM6DOjTPPKD2\n",
    "BoEiqDCarm0gxgK1p4arjdlQ7cLSRIgCfotJuGT8vwQJpmQSTInzFMYGxW64pPBlv4eVTCdZCniVjm8WptJF/JY6jkN2TX5XPNWk\n",
    "JgWXTXQow+Cy+NdSGVRjGOuWYXBWNvmrbKJPWeP4YLecwjuSY6ENLgd3dsHlwVP5atryGRSUozYsh26QeosDrQoMhSqonPABf8X4\n",
    "TXGiVUBuRfMUlJNAViVifwG5hdRbidhfidhWCeXc7vctAVeVSC7F0rlq0mOx/a1CgVUF69bEhiJwq4qn4DsF10TyrZ7AUE31NHJj\n",
    "NV2zA+cTHKCd7gk31e8vyTp7id5YXQetUR0lhbhQh/xv7XyZMPnWAbJYPBdg24Bt75G/t75OoYHaRuncGxPF3mDee5ynOcfqPcZt\n",
    "/J3UMnmxBTOmFnAnbFvg+D3/J/0DpZ50FA==\n",
    "\"\"\",\n",
    "    \"delivery_h2.csv\": \"\"\"\n",
    "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\n",
    "naaj+MU1CkvpmHz/Jt2b5XRKbZy+r1n/B5CuGbA=\n",
    "\"\"\",\n",
    "}\n",
    "os.makedirs(\"data\", exist_ok=True)\n",
    "for _name, _packed in _DATA.items():\n",
    "    with open(os.path.join(\"data\", _name), \"wb\") as _f:\n",
    "        _f.write(zlib.decompress(base64.b64decode(_packed)))\n",
    "print(\"Файлы данных:\", \", \".join(sorted(_DATA)))\n",
    "\n",
    "# ─── Проверка упражнений: тот же раннер, что у задач на сайте ───\n",
    "# ─── Запуск тестов ───────────────────────────────────────────────────────────\n",
    "\n",
    "_TIMEOUT = 2.0  # секунд на тест; отдельный тест может задать свой: test_x.timeout = 10\n",
    "\n",
    "\n",
    "def _call_with_timeout(target, seconds: float) -> bool:\n",
    "    \"\"\"Запускает target() в отдельном потоке. Возвращает False, если за seconds он не завершился.\"\"\"\n",
    "    import sys\n",
    "    import threading\n",
    "\n",
    "    if sys.platform == \"emscripten\":  # Python в браузере: потоков нет, таймаут обеспечивает страница\n",
    "        target()\n",
    "        return True\n",
    "    # Большой стек нужен, чтобы глубокая рекурсия давала RecursionError, а не аварийное завершение Python.\n",
    "    for megabytes in (256, 64, 0):\n",
    "        try:\n",
    "            threading.stack_size(megabytes * 1024 * 1024)\n",
    "            worker = threading.Thread(target=target, daemon=True)\n",
    "            worker.start()\n",
    "        except (ValueError, RuntimeError, MemoryError):\n",
    "            continue\n",
    "        worker.join(seconds)\n",
    "        return not worker.is_alive()\n",
    "    target()  # потоки недоступны — запускаем без таймаута\n",
    "    return True\n",
    "\n",
    "\n",
    "def _test_info(fn) -> dict:\n",
    "    \"\"\"Описание теста, его лимит времени и сообщение на случай зависания.\"\"\"\n",
    "    limit = getattr(fn, \"timeout\", _TIMEOUT)\n",
    "    hint = getattr(fn, \"timeout_hint\", \"\")\n",
    "    message = (\n",
    "        f\"тест не завершился за {limit:g} с — возможно, бесконечный цикл или рекурсия: \"\n",
    "        \"проверьте, что границы/аргументы изменяются на каждом шаге\" + (f\". {hint}\" if hint else \"\")\n",
    "    )\n",
    "    return {\"title\": (fn.__doc__ or fn.__name__).strip(), \"timeout\": limit, \"timeout_message\": message}\n",
    "\n",
    "\n",
    "def _error_result(title: str, error: BaseException, user_file: str | None) -> dict:\n",
    "    \"\"\"Результат упавшего теста: статус, сообщение, тип исключения и строка в коде решения.\"\"\"\n",
    "    line = None\n",
    "    if user_file:  # самый глубокий кадр в коде решения; ошибка внутри самих тестов — без номера строки\n",
    "        tb = error.__traceback__\n",
    "        while tb is not None:\n",
    "            if tb.tb_frame.f_code.co_filename == user_file:\n",
    "                line = tb.tb_lineno\n",
    "            tb = tb.tb_next\n",
    "    status, message = \"error\", f\"{type(error).__name__}: {error}\"\n",
    "    if isinstance(error, NotImplementedError):\n",
    "        status, message, line = \"not_written\", \"функция ещё не написана\", None\n",
    "    elif isinstance(error, AssertionError):\n",
    "        status, message = \"failed\", str(error) or \"проверка не прошла\"\n",
    "    elif isinstance(error, RecursionError):\n",
    "        message = \"RecursionError: слишком глубокая рекурсия — проверьте базовый случай и то, что задача уменьшается\"\n",
    "    elif isinstance(error, MemoryError) or (isinstance(error, OverflowError) and \"index-sized\" in str(error)):\n",
    "        message = f\"{type(error).__name__}: не хватило памяти — возможно, создаётся слишком большая структура данных\"\n",
    "    return {\"title\": title, \"status\": status, \"message\": message, \"error_type\": type(error).__name__, \"line\": line}\n",
    "\n",
    "\n",
    "def _run_tests(verbose: bool = True, on_start=None, on_result=None, user_file: str | None = None) -> list[dict]:\n",
    "    \"\"\"Запускает тесты задачи (_TESTS — функции из tests.py) по порядку, каждый — с таймаутом.\n",
    "\n",
    "    Возвращает список результатов: {\"title\", \"status\", \"message\", \"error_type\", \"line\"}, где status —\n",
    "    passed · failed · error · not_written · timeout · not_run. Если тест завис, при verbose=True печатает\n",
    "    итог и завершает процесс: зависший поток остановить нельзя. on_start(i) и on_result(i, результат)\n",
    "    вызываются по мере выполнения; user_file — имя файла с кодом решения для номеров строк в ошибках.\n",
    "    \"\"\"\n",
    "    import os\n",
    "    import sys\n",
    "\n",
    "    if verbose:\n",
    "        try:  # ✓ и кириллица в консоли Windows со старой кодировкой\n",
    "            sys.stdout.reconfigure(encoding=\"utf-8\")\n",
    "        except Exception:  # noqa: BLE001 — reconfigure может не быть (перенаправленный вывод, браузер)\n",
    "            pass\n",
    "\n",
    "    tests = list(_TESTS)\n",
    "    results: list[dict] = []\n",
    "    not_written = hung = False\n",
    "    for index, fn in enumerate(tests):\n",
    "        info = _test_info(fn)\n",
    "        outcome: dict = {}\n",
    "\n",
    "        def target(fn=fn, outcome=outcome):\n",
    "            try:\n",
    "                fn()\n",
    "            except BaseException as e:\n",
    "                outcome[\"error\"] = e\n",
    "\n",
    "        if on_start:\n",
    "            on_start(index)\n",
    "        if not _call_with_timeout(target, info[\"timeout\"]):\n",
    "            results.append({\"title\": info[\"title\"], \"status\": \"timeout\", \"message\": info[\"timeout_message\"], \"error_type\": None, \"line\": None})\n",
    "            for other in tests[index + 1:]:\n",
    "                results.append({\"title\": _test_info(other)[\"title\"], \"status\": \"not_run\", \"message\": \"не запускался: предыдущий тест завис\", \"error_type\": None, \"line\": None})\n",
    "            hung = True\n",
    "            break\n",
    "        error = outcome.get(\"error\")\n",
    "        if error is None:\n",
    "            result = {\"title\": info[\"title\"], \"status\": \"passed\", \"message\": \"\", \"error_type\": None, \"line\": None}\n",
    "        else:\n",
    "            result = _error_result(info[\"title\"], error, user_file)\n",
    "            not_written = not_written or result[\"status\"] == \"not_written\"\n",
    "        results.append(result)\n",
    "        if on_result:\n",
    "            on_result(index, result)\n",
    "\n",
    "    if not_written:  # пока функция не написана, «даром» пройденные тесты не засчитываются\n",
    "        for r in results:\n",
    "            if r[\"status\"] == \"passed\":\n",
    "                r.update(status=\"not_written\", message=\"не засчитан, пока функция не написана\")\n",
    "    for r in results:\n",
    "        if len(r[\"message\"]) > 300:\n",
    "            r[\"message\"] = r[\"message\"][:300] + \"…\"\n",
    "\n",
    "    if verbose:\n",
    "        if not_written:\n",
    "            print(\"Функция ещё не написана — замените raise NotImplementedError своим кодом.\\n\")\n",
    "        for r in results:\n",
    "            mark = {\"passed\": \"✓\", \"not_run\": \"–\"}.get(r[\"status\"], \"✗\")\n",
    "            print(f\"{mark} {r['title']}\")\n",
    "            if r[\"message\"]:\n",
    "                print(f\"    {r['message']}\")\n",
    "        passed = sum(r[\"status\"] == \"passed\" for r in results)\n",
    "        print(\"─\" * 40)\n",
    "        print(f\"Прошло {passed} из {len(results)}\" + (\" — всё верно!\" if passed == len(results) else \"\"))\n",
    "        if hung:\n",
    "            print(\"Выполнение остановлено: один из тестов завис.\")\n",
    "            sys.stdout.flush()\n",
    "            os._exit(1)\n",
    "    return results\n",
    "\n",
    "\n",
    "def _check(*tests, names=()):\n",
    "    \"\"\"Запускает проверки упражнения и печатает ✓ / ✗ и итог — как на сайте.\"\"\"\n",
    "    for name in names:\n",
    "        if \".\" in name:  # «Класс.метод» из заготовки: класс должен быть объявлен\n",
    "            if not isinstance(globals().get(name.split(\".\")[0]), type):\n",
    "                print(f\"✗ класс {name.split('.')[0]} не объявлен — выполните ячейку упражнения\")\n",
    "                return\n",
    "            continue\n",
    "        if name not in globals():\n",
    "            print(f\"✗ переменная {name} не создана — выполните ячейку упражнения\")\n",
    "            return\n",
    "        if globals()[name] is Ellipsis:\n",
    "            print(f\"✗ {name} пока равна ... — замените многоточие своим кодом\")\n",
    "            return\n",
    "    globals()[\"_TESTS\"] = list(tests)\n",
    "    _run_tests()"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "setup"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Весь курс мы пользовались готовой таблицей `shop_orders.csv`. Теперь соберём её сами — из трёх таблиц,\n",
    "как они лежат в базе магазина: заказы, справочник товаров, справочник клиентов. А заодно получим то, чего\n",
    "в готовой таблице не было: себестоимость, а значит, и прибыль. Новых методов в проекте нет."
   ],
   "id": "text-10"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "# Три таблицы\n",
    "import pandas as pd\n",
    "\n",
    "orders = pd.read_csv(\"data/orders.csv\")\n",
    "products = pd.read_csv(\"data/products.csv\")\n",
    "customers = pd.read_csv(\"data/customers.csv\")\n",
    "print(orders.shape, products.shape, customers.shape)\n",
    "orders.head(3)"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "load"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Шаг 1. Проверить ключи\n",
    "\n",
    "Прежде чем соединять, убедимся, что в справочниках ключ не повторяется: иначе строки размножатся."
   ],
   "id": "text-16"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Упражнение 1. Уникальны ли ключи\n",
    "\n",
    "Сохраните в `product_key_ok`, уникальны ли значения `product_id` в таблице `products`; в `customer_key_ok` —\n",
    "уникальны ли `customer_id` в `customers`; в `order_key_ok` — уникальны ли `order_id` в `orders`.\n",
    "\n",
    "<details><summary>Подсказка 1</summary>\n",
    "\n",
    "Атрибут столбца `is_unique` возвращает `True` или `False`: `products[\"product_id\"].is_unique`.\n",
    "\n",
    "</details>"
   ],
   "id": "keys-task"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "product_key_ok = ...\n",
    "customer_key_ok = ...\n",
    "order_key_ok = ..."
   ],
   "execution_count": null,
   "outputs": [],
   "id": "keys"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "# Проверка упражнения 1 — выполните после своего решения\n",
    "def test_keys():\n",
    "    \"уникальны ли ключи трёх таблиц\"\n",
    "    assert product_key_ok is True or product_key_ok == True, \"product_key_ok — это не ответ на вопрос, уникален ли product_id в products\"\n",
    "    assert customer_key_ok is True or customer_key_ok == True, \"customer_key_ok — это не ответ на вопрос, уникален ли customer_id в customers\"\n",
    "    assert not isinstance(order_key_ok, pd.Series), \"order_key_ok — Series, а нужно одно значение True или False\"\n",
    "    assert order_key_ok is False or order_key_ok == False, \"order_key_ok — это не ответ на вопрос, уникален ли order_id в orders\"\n",
    "\n",
    "_check(test_keys, names=[\"product_key_ok\",\"customer_key_ok\",\"order_key_ok\"])"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "keys-check"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<details><summary>Решение</summary>\n",
    "\n",
    "```python\n",
    "product_key_ok = products[\"product_id\"].is_unique\n",
    "customer_key_ok = customers[\"customer_id\"].is_unique\n",
    "order_key_ok = orders[\"order_id\"].is_unique\n",
    "```\n",
    "\n",
    "</details>"
   ],
   "id": "keys-solution"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "В справочниках ключи уникальны — так и должно быть. В заказах `order_id` повторяется, и это тоже нормально:\n",
    "заказ состоит из нескольких строк. Значит, оба соединения будут «многие к одному».\n",
    "\n",
    "## Шаг 2. Заказы и товары"
   ],
   "id": "text-27"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Упражнение 2. Выручка и прибыль строки\n",
    "\n",
    "Соедините `orders` с `products` по `product_id` и сохраните в `lines`; попросите pandas проверить, что\n",
    "соединение «многие к одному». Добавьте столбцы `revenue` (цена × количество) и `profit` — прибыль:\n",
    "(цена − себестоимость) × количество.\n",
    "\n",
    "<details><summary>Подсказка 1</summary>\n",
    "\n",
    "`orders.merge(products, on=\"product_id\", validate=\"many_to_one\")`.\n",
    "\n",
    "</details>\n",
    "<details><summary>Подсказка 2</summary>\n",
    "\n",
    "`(lines[\"price\"] - lines[\"cost\"]) * lines[\"quantity\"]`.\n",
    "\n",
    "</details>"
   ],
   "id": "lines-task"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "lines = ...\n",
    "# добавьте в lines столбцы revenue и profit"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "lines"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "# Проверка упражнения 2 — выполните после своего решения\n",
    "def test_lines():\n",
    "    \"lines — заказы с данными товара\"\n",
    "    assert isinstance(lines, pd.DataFrame), f\"lines — это {type(lines).__name__}, а нужна таблица\"\n",
    "    assert len(lines) == 2448, f\"в lines {len(lines)} строк, а должно остаться 2448\"\n",
    "    assert \"price\" in lines.columns and \"cost\" in lines.columns and \"order_id\" in lines.columns, \"в lines должны быть столбцы и заказов, и товаров\"\n",
    "\n",
    "\n",
    "def test_money():\n",
    "    \"revenue и profit — выручка и прибыль строки\"\n",
    "    assert \"revenue\" in lines.columns and \"profit\" in lines.columns, \"в lines нужны столбцы revenue и profit\"\n",
    "    assert lines[\"revenue\"].sum() == 3301420, \"revenue не тот: выручка строки — цена × количество\"\n",
    "    assert lines[\"profit\"].sum() != 3301420 - 9670, \"себестоимость нужно умножить на количество\"\n",
    "    assert lines[\"profit\"].sum() == 1542150, \"profit не тот: проверьте формулу из условия\"\n",
    "\n",
    "_check(test_lines, test_money, names=[\"lines\"])"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "lines-check"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<details><summary>Решение</summary>\n",
    "\n",
    "```python\n",
    "lines = orders.merge(products, on=\"product_id\", validate=\"many_to_one\")\n",
    "lines[\"revenue\"] = lines[\"price\"] * lines[\"quantity\"]\n",
    "lines[\"profit\"] = (lines[\"price\"] - lines[\"cost\"]) * lines[\"quantity\"]\n",
    "```\n",
    "\n",
    "</details>"
   ],
   "id": "lines-solution"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Шаг 3. Добавить покупателей"
   ],
   "id": "text-41"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Упражнение 3. Город и сегмент\n",
    "\n",
    "Добавьте к `lines` город и сегмент покупателя и сохраните в `full`. Из справочника `customers` возьмите только\n",
    "три столбца: `customer_id`, `city`, `segment`.\n",
    "\n",
    "<details><summary>Подсказка 1</summary>\n",
    "\n",
    "`lines.merge(customers[[\"customer_id\", \"city\", \"segment\"]], on=\"customer_id\", validate=\"many_to_one\")`.\n",
    "\n",
    "</details>"
   ],
   "id": "full-task"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "full = ..."
   ],
   "execution_count": null,
   "outputs": [],
   "id": "full"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "# Проверка упражнения 3 — выполните после своего решения\n",
    "def test_full():\n",
    "    \"full — к строкам заказов добавлены город и сегмент покупателя\"\n",
    "    assert isinstance(full, pd.DataFrame), f\"full — это {type(full).__name__}, а нужна таблица\"\n",
    "    assert len(full) == 2448, f\"в full {len(full)} строк, а должно остаться 2448\"\n",
    "    assert \"city\" in full.columns and \"segment\" in full.columns, \"в full нужны столбцы city и segment из справочника клиентов\"\n",
    "    assert \"name_x\" not in full.columns and \"name_y\" not in full.columns, \"задвоился столбец name: берите из customers только customer_id, city и segment\"\n",
    "    assert \"signup_date\" not in full.columns, \"лишние столбцы: берите из customers только customer_id, city и segment\"\n",
    "    assert \"name\" in full.columns and \"profit\" in full.columns, \"в full должны остаться столбцы таблицы lines\"\n",
    "\n",
    "_check(test_full, names=[\"full\"])"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "full-check"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<details><summary>Решение</summary>\n",
    "\n",
    "```python\n",
    "full = lines.merge(customers[[\"customer_id\", \"city\", \"segment\"]], on=\"customer_id\", validate=\"many_to_one\")\n",
    "```\n",
    "\n",
    "</details>"
   ],
   "id": "full-solution"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Шаг 4. Сверка\n",
    "\n",
    "Собранную таблицу стоит сверить с чем-нибудь известным. У нас есть готовая `shop_orders.csv` — сравним\n",
    "выручку по городам:"
   ],
   "id": "text-50"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "# Наша сборка против готовой таблицы\n",
    "shop = pd.read_csv(\"data/shop_orders.csv\")\n",
    "shop[\"revenue\"] = shop[\"price\"] * shop[\"quantity\"]\n",
    "ours = full.groupby(\"city\")[\"revenue\"].sum()\n",
    "theirs = shop.groupby(\"city\")[\"revenue\"].sum()\n",
    "print((ours == theirs).all())\n",
    "print(ours.sum(), theirs.sum())"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "check"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Выручка каждого города совпала, общий итог тоже. У обоих Series одинаковые метки в одинаковом порядке\n",
    "(группировка сортирует города по алфавиту), поэтому их можно сравнить через `==`; `all()` подтверждает, что\n",
    "совпало всё.\n",
    "\n",
    "## Шаг 5. Прибыль по городам\n",
    "\n",
    "**Маржа** — доля прибыли в выручке: сколько копеек с каждого рубля остаётся магазину."
   ],
   "id": "text-57"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Упражнение 4. Города\n",
    "\n",
    "Сохраните в `city_table` таблицу по городам (город в индексе): `revenue` — выручка, `profit` — прибыль,\n",
    "`margin` — маржа, округлённая до трёх знаков. Отсортируйте по убыванию прибыли.\n",
    "\n",
    "<details><summary>Подсказка 1</summary>\n",
    "\n",
    "`full.groupby(\"city\").agg(revenue=(\"revenue\", \"sum\"), profit=(\"profit\", \"sum\"))`.\n",
    "\n",
    "</details>\n",
    "<details><summary>Подсказка 2</summary>\n",
    "\n",
    "Маржа — `profit / revenue`; затем `sort_values(\"profit\", ascending=False)`.\n",
    "\n",
    "</details>"
   ],
   "id": "cities-task"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "city_table = ..."
   ],
   "execution_count": null,
   "outputs": [],
   "id": "cities"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "# Проверка упражнения 4 — выполните после своего решения\n",
    "def test_city_table():\n",
    "    \"city_table — выручка, прибыль и маржа по городам, по убыванию прибыли\"\n",
    "    assert isinstance(city_table, pd.DataFrame), f\"city_table — это {type(city_table).__name__}, а нужна таблица\"\n",
    "    assert list(city_table.columns) == [\"revenue\", \"profit\", \"margin\"], f\"столбцы сейчас {list(city_table.columns)}, а нужны revenue, profit, margin\"\n",
    "    assert len(city_table) == 5 and \"Казань\" in city_table.index, \"в индексе должны быть пять городов\"\n",
    "    assert city_table.loc[\"Москва\", \"profit\"] == 612070, \"profit не тот: нужна прибыль города\"\n",
    "    assert abs(city_table.loc[\"Москва\", \"margin\"] - 0.467) < 1e-9, \"margin не тот: нужна доля прибыли в выручке с округлением до трёх знаков\"\n",
    "    assert city_table[\"profit\"].tolist() == sorted(city_table[\"profit\"].tolist(), reverse=True), \"отсортируйте city_table по убыванию profit\"\n",
    "\n",
    "_check(test_city_table, names=[\"city_table\"])"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "cities-check"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<details><summary>Решение</summary>\n",
    "\n",
    "```python\n",
    "city_table = full.groupby(\"city\").agg(revenue=(\"revenue\", \"sum\"), profit=(\"profit\", \"sum\"))\n",
    "city_table[\"margin\"] = (city_table[\"profit\"] / city_table[\"revenue\"]).round(3)\n",
    "city_table = city_table.sort_values(\"profit\", ascending=False)\n",
    "```\n",
    "\n",
    "</details>"
   ],
   "id": "cities-solution"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Шаг 6. Прибыль по товарам"
   ],
   "id": "text-73"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Упражнение 5. Что приносит деньги\n",
    "\n",
    "Сохраните в `product_table` плоскую таблицу по товарам со столбцами `category`, `name`, `revenue`, `profit`,\n",
    "`margin` (три знака). В `top_profit` сохраните три товара с наибольшей прибылью, в `low_margin` — три товара\n",
    "с наименьшей маржой.\n",
    "\n",
    "<details><summary>Подсказка 1</summary>\n",
    "\n",
    "Группировка по `[\"category\", \"name\"]` с `as_index=False`.\n",
    "\n",
    "</details>\n",
    "<details><summary>Подсказка 2</summary>\n",
    "\n",
    "`product_table.nlargest(3, \"profit\")` и `product_table.nsmallest(3, \"margin\")`.\n",
    "\n",
    "</details>"
   ],
   "id": "products-task"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "product_table = ...\n",
    "top_profit = ...\n",
    "low_margin = ..."
   ],
   "execution_count": null,
   "outputs": [],
   "id": "products"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "# Проверка упражнения 5 — выполните после своего решения\n",
    "def test_product_table():\n",
    "    \"product_table — выручка, прибыль и маржа по товарам\"\n",
    "    assert isinstance(product_table, pd.DataFrame), f\"product_table — это {type(product_table).__name__}, а нужна таблица\"\n",
    "    assert list(product_table.columns) == [\"category\", \"name\", \"revenue\", \"profit\", \"margin\"], f\"столбцы сейчас {list(product_table.columns)}, а нужны category, name, revenue, profit, margin\"\n",
    "    assert len(product_table) == 20 and product_table[\"profit\"].sum() == 1542150, \"в product_table 20 товаров\"\n",
    "    assert abs(product_table[\"margin\"].max() - 0.625) < 1e-9, \"margin не тот: нужна доля прибыли в выручке с округлением до трёх знаков\"\n",
    "\n",
    "\n",
    "def test_tops():\n",
    "    \"top_profit — три самых прибыльных товара, low_margin — три товара с наименьшей маржой\"\n",
    "    assert isinstance(top_profit, pd.DataFrame) and len(top_profit) == 3, \"top_profit — три строки\"\n",
    "    assert top_profit[\"name\"].tolist() == [\"Эфиопия 250 г\", \"Колумбия 250 г\", \"Кофе без кофеина 250 г\"], f\"в top_profit сейчас {top_profit['name'].tolist()}: нужны три товара с наибольшей прибылью\"\n",
    "    assert isinstance(low_margin, pd.DataFrame) and len(low_margin) == 3, \"low_margin — три строки\"\n",
    "    assert low_margin[\"name\"].tolist() == [\"Бразилия 1 кг\", \"Эспрессо-смесь 1 кг\", \"Кофемолка ручная\"], f\"в low_margin сейчас {low_margin['name'].tolist()}: нужны три товара с наименьшей маржой\"\n",
    "\n",
    "_check(test_product_table, test_tops, names=[\"product_table\",\"top_profit\",\"low_margin\"])"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "products-check"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<details><summary>Решение</summary>\n",
    "\n",
    "```python\n",
    "product_table = full.groupby([\"category\", \"name\"], as_index=False).agg(revenue=(\"revenue\", \"sum\"), profit=(\"profit\", \"sum\"))\n",
    "product_table[\"margin\"] = (product_table[\"profit\"] / product_table[\"revenue\"]).round(3)\n",
    "top_profit = product_table.nlargest(3, \"profit\")\n",
    "low_margin = product_table.nsmallest(3, \"margin\")\n",
    "```\n",
    "\n",
    "</details>"
   ],
   "id": "products-solution"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Шаг 7. Доставка по каналам\n",
    "\n",
    "Данные о доставке — по строке на **заказ**, а наша таблица — по строке на **позицию**. Если соединить их\n",
    "напрямую, срок и оценка заказа повторятся в каждой его позиции, и заказы из трёх позиций будут весить втрое\n",
    "больше. Сначала свернём таблицу до заказов."
   ],
   "id": "text-84"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Упражнение 6. Срок и оценка\n",
    "\n",
    "Склейте файлы `data/delivery_h1.csv` и `data/delivery_h2.csv` в таблицу `delivery`. Соберите `order_table`:\n",
    "сверните `full` до заказов — плоская таблица `order_id`, `channel`, `total` (сумма `revenue`), — и присоедините\n",
    "к ней `delivery` по `order_id` с проверкой «один к одному». В `channel_delivery` сохраните средний срок (`days`)\n",
    "и среднюю оценку (`rating`) по каналам, округлённые до двух знаков.\n",
    "\n",
    "<details><summary>Подсказка 1</summary>\n",
    "\n",
    "`pd.concat([pd.read_csv(...), pd.read_csv(...)], ignore_index=True)`.\n",
    "\n",
    "</details>\n",
    "<details><summary>Подсказка 2</summary>\n",
    "\n",
    "`full.groupby([\"order_id\", \"channel\"], as_index=False).agg(total=(\"revenue\", \"sum\"))`, затем `.merge(delivery, on=\"order_id\", validate=\"one_to_one\")`.\n",
    "\n",
    "</details>\n",
    "<details><summary>Подсказка 3</summary>\n",
    "\n",
    "`order_table.groupby(\"channel\").agg(days=(\"days\", \"mean\"), rating=(\"rating\", \"mean\")).round(2)`.\n",
    "\n",
    "</details>"
   ],
   "id": "delivery-task"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "delivery = ...\n",
    "order_table = ...\n",
    "channel_delivery = ..."
   ],
   "execution_count": null,
   "outputs": [],
   "id": "delivery"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "# Проверка упражнения 6 — выполните после своего решения\n",
    "def test_delivery():\n",
    "    \"delivery — доставка за год\"\n",
    "    assert isinstance(delivery, pd.DataFrame) and len(delivery) == 1576, \"delivery — обе выгрузки одной таблицей\"\n",
    "    assert delivery.index.is_unique, \"метки delivery повторяются\"\n",
    "\n",
    "\n",
    "def test_order_table():\n",
    "    \"order_table — один заказ в строке: канал, сумма, срок, оценка\"\n",
    "    assert isinstance(order_table, pd.DataFrame), f\"order_table — это {type(order_table).__name__}, а нужна таблица\"\n",
    "    assert len(order_table) != 2448, \"в order_table 2448 строк — это позиции, а не заказы: сначала сгруппируйте full по order_id и channel\"\n",
    "    assert len(order_table) == 1576, f\"в order_table {len(order_table)} строк: нужна одна строка на заказ\"\n",
    "    assert list(order_table.columns) == [\"order_id\", \"channel\", \"total\", \"days\", \"rating\"], f\"столбцы сейчас {list(order_table.columns)}, а нужны order_id, channel, total, days, rating\"\n",
    "    assert order_table[\"total\"].sum() == 3301420, \"total не тот: нужна сумма revenue заказа\"\n",
    "\n",
    "\n",
    "def test_channels():\n",
    "    \"channel_delivery — средний срок и оценка по каналам\"\n",
    "    assert isinstance(channel_delivery, pd.DataFrame) and list(channel_delivery.columns) == [\"days\", \"rating\"], \"channel_delivery — таблица со столбцами days и rating\"\n",
    "    assert channel_delivery.loc[\"маркетплейс\", \"days\"] == 5.25 and channel_delivery.loc[\"сайт\", \"rating\"] == 3.76, \"средние должны быть округлены до двух знаков\"\n",
    "\n",
    "_check(test_delivery, test_order_table, test_channels, names=[\"delivery\",\"order_table\",\"channel_delivery\"])"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "delivery-check"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<details><summary>Решение</summary>\n",
    "\n",
    "```python\n",
    "delivery = pd.concat([pd.read_csv(\"data/delivery_h1.csv\"), pd.read_csv(\"data/delivery_h2.csv\")], ignore_index=True)\n",
    "order_table = full.groupby([\"order_id\", \"channel\"], as_index=False).agg(total=(\"revenue\", \"sum\"))\n",
    "order_table = order_table.merge(delivery, on=\"order_id\", validate=\"one_to_one\")\n",
    "channel_delivery = order_table.groupby(\"channel\").agg(days=(\"days\", \"mean\"), rating=(\"rating\", \"mean\")).round(2)\n",
    "```\n",
    "\n",
    "</details>"
   ],
   "id": "delivery-solution"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **Типичная ошибка: разная «единица» у двух таблиц.**\n",
    ">\n",
    "> Перед соединением спросите, что значит одна строка в каждой таблице. Если слева позиции, а справа заказы,\n",
    "> значения заказа размножатся по позициям — и средние, посчитанные после этого, сместятся в сторону больших\n",
    "> заказов. Сведите таблицы к одной единице, потом соединяйте."
   ],
   "id": "component-102"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Итог"
   ],
   "id": "text-107"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": [
    "# Сводка\n",
    "print(\"Выручка:\", full[\"revenue\"].sum(), \"· прибыль:\", full[\"profit\"].sum(), \"· маржа:\", round(full[\"profit\"].sum() / full[\"revenue\"].sum(), 3))\n",
    "print(city_table)\n",
    "print(channel_delivery)"
   ],
   "execution_count": null,
   "outputs": [],
   "id": "summary"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Выводы"
   ],
   "id": "text-111"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*После решения всех упражнений урока:*\n",
    "\n",
    "- За год магазин заработал 1.54 млн ₽ прибыли с 3.3 млн ₽ выручки — маржа 47 %.\n",
    "- Маржа по городам одинакова: 46.5–46.9 %. Города отличаются объёмом, а не выгодностью.\n",
    "- Больше всего прибыли приносят кофе в пачках по 250 г. Килограммовые пачки продаются на те же суммы,\n",
    "  но маржа у них самая низкая — около 40 %.\n",
    "- Маркетплейс везёт заказы на день с лишним дольше (5.3 дня против 4.0), и оценки у него ниже: 3.3\n",
    "  против 3.8. Возможно, поэтому на маркетплейс реже возвращаются."
   ],
   "id": "component-114"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Три таблицы, два соединения, одна склейка — и каждое действие проверено: ключи уникальны, число строк\n",
    "не изменилось, итог сошёлся с известным."
   ],
   "id": "text-122"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Подробнее в справочнике:** [pandas/merge](https://ds-edu-trainer.vercel.app/reference/pandas/merge) · [pandas/merge-keys](https://ds-edu-trainer.vercel.app/reference/pandas/merge-keys) · [pandas/concat](https://ds-edu-trainer.vercel.app/reference/pandas/concat) · [pandas/groupby-agg](https://ds-edu-trainer.vercel.app/reference/pandas/groupby-agg)"
   ],
   "id": "more"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  },
  "colab": {
   "provenance": []
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
