Skip to content

Instantly share code, notes, and snippets.

@Searge
Last active October 2, 2018 13:45
Show Gist options
  • Save Searge/5555df50738e176ae982b9c21cc86691 to your computer and use it in GitHub Desktop.
Save Searge/5555df50738e176ae982b9c21cc86691 to your computer and use it in GitHub Desktop.
Калькулятор на Stepik'у
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"source": [
"#Калькулятор на Stepik'у\n",
"\n"
],
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Напишите простой калькулятор, который считывает с пользовательского ввода три строки: первое число, второе число и операцию, после чего применяет операцию к введённым числам (\"первое число\" \"операция\" \"второе число\") и выводит результат на экран.\n",
"\n",
"Поддерживаемые операции: `+, -, /, *, mod, pow, div`, где \n",
"\n",
"> mod — это взятие остатка от деления, \n",
"\n",
"> pow — возведение в степень, \n",
"\n",
"> div — целочисленное деление.\n",
"\n",
"Если выполняется деление и второе число равно 0, необходимо выводить строку `\"Деление на 0!\"`.\n",
"\nОбратите внимание, что на вход программе приходят **вещественные числа**."
],
"metadata": {}
},
{
"cell_type": "code",
"source": [
"first = float(input())\n",
"second = float(input())\n",
"action = input()\n",
"operations = {\"mod\": \"%\", \"div\": \"//\", \"pow\": \"**\"}\n",
"try:\n",
" print(eval(\"(\" + str(first) + \")\" + operations.get(action, action) + str(second)))\n",
"except ZeroDivisionError:\n",
" print('Деление на 0!')"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"5\n",
"0\n",
"mod\n",
"Деление на 0!\n"
]
}
],
"execution_count": 1,
"metadata": {}
},
{
"cell_type": "markdown",
"source": [
"Нашел интересный вопрос Льва Романова: _\"нельзя как-то заставить питон считать операцию инпута?_ например `s = a + c + b`, где «`с`» это операция?\" - да, можно (правда в предыдущих уроках почти ничего из этого не было)\n",
"\n",
"Всё довольно просто - на вход мы получаем три значения, два числа и знак, и, если их в правильном порядке соединить друг с другом, получится вполне осмысленное выражение.\n",
"\n",
"Для того, чтобы это выражение прочитать, есть функция `eval()`, принимающая на вход строку и преобразовывающая её в выражение, с которым интерпретатор может работать. Соответственно, нам необходимо все три значения привести к типу `string*` и объединить их в одну строку, что легко сделать при помощи конкатенации строк.\n",
"\n",
"Если со знаками `+, -, *, /` всё просто, их интерпретатор воспримет как надо и выдаст корректный результат, то как быть с `pow, div, mod`, ведь таких действий питон не знает. Нужно им как-то задать соответствия и в этом помогает словарь. В словаре задаются пары ключ, значение. В моём решении это переменная operations. Получить значение по ключу можно несколькими способами, но, так как я в словаре указал всего три пары, мне был нужен тот, который избавит меня от лишней условной инструкции, указывающей интерпретатору что делать, если ключа нет в словаре. Это метод `.get()`. Он позволяет получить из словаря значение по ключу, так же в нём можно указать значение, которое будет возвращаться в случае отсутствия указанного ключа в словаре. Выглядит это следующим образом `словарь.get(\"ключ\", \"значение, если ключа нет в словаре\")`.\n",
"\n",
"Осталось лишь обработать ситуацию, когда что-то делится на `0`. Тут можно было бы использовать условную инструкцию, перечислить условия, когда выдавалось бы сообщение `\"Деление на 0!\"`, но это было бы более громоздко и, на мой взгляд, менее читабельно. Потому я использовал `try...except`. Эта конструкция пробует выполнить действие указанное в блоке `try` и, если возникает ошибка, указанная в `except` (в нашем случае это `ZeroDivisionError`, тоесть деление на 0) действие программы не прерывается, а выполняется блок except, в нашем случае это печать сообщения \"Деление на 0!\".\n",
"\n* А вообще, чтобы не совершать лишних преобразований, можно было бы все три переменные считать как `input()`, тогда они будут строками, и не преобразовывать из типа `float` обратно в тип `string`, но я об этом поздно подумал"
],
"metadata": {}
},
{
"cell_type": "code",
"source": [
"a, b, op = input(), input(), input()\n",
"print (\"Деление на 0!\" if op in (\"/\", \"div\", \"mod\") and float(b) == 0 else eval(\"({0}){1}\".format(a, {'pow':'**', 'div':'//', 'mod':'%'}.get(op, op) + b)))\n",
"\n",
"# Калькулятор в два рядки :-)\n",
"# перевіряє тільки вказану помилку."
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"6\n",
"0\n",
"/\n",
"Деление на 0!\n"
]
}
],
"execution_count": 5,
"metadata": {}
},
{
"cell_type": "code",
"source": [
"# з exec але аж в 4 рядки\n",
"\n",
"try:\n",
" exec('print(({0}){2}{1})'.format(input(),input(),input()).replace('mod','%').replace('div','//').replace('pow','**'))\n",
"except(Exception):\n",
" print('Деление на 0!')"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"8\n",
"4\n",
"pow\n",
"4096\n"
]
}
],
"execution_count": 6,
"metadata": {}
},
{
"cell_type": "code",
"source": [
"# Ще один подібний\n",
"\n",
"import operator\n",
"a,b,c = (input() for _ in range(3))\n",
"o = {'+' : operator.add, '-' : operator.sub,'*' : operator.mul,'/' : operator.truediv,'mod' : operator.mod,'pow' : operator.pow,'div' : operator.floordiv}\n",
"try:\n",
" exec(\"print(o[c](float(a),float(b)))\")\n",
"except:\n",
" print('Деление на 0!')"
],
"outputs": [],
"execution_count": null,
"metadata": {
"collapsed": true
}
},
{
"cell_type": "code",
"source": [
"# в один рядок з коментарями :-)\n",
"exec(\"print(eval('(a) {} b'.format({'div': '//', 'mod': '%', 'pow':'**'}[o] if o in ['div','mod','pow'] else o))) if not(o in ['div','mod','/'] and float(b)==0) else print('Деление на 0!')\", {'a':float(input()),'b':float(input()),'o':input()})\n",
"\n",
"'''\n",
"\n",
"'''\n"
],
"outputs": [],
"execution_count": null,
"metadata": {
"collapsed": true
}
},
{
"cell_type": "markdown",
"source": [
"черт, ну кто-то же сделал 2.0! >E~~ гугл сходу на `complexity score` выдает pip-пакет radon, а тут им же считают? конечно все эти однострочные сверхбыстрые исполнения - та еще фаллометрия, и что-то мне подсказывает, что в боевых условиях за такие колбасы по рукам-то хорошенько настукивают. но и вправду хотелось бы почитать про оптимизации, внутреннюю организацию python, вот это вот все. так-то курс вообще легкий, если б не эти скоры - давно б уже закончил :-)\n",
"\n\n",
"[вот офф дока] (https://docs.python.org/3/reference/expressions.html#binary-arithmetic-operations)\n",
"\n",
">и в ней в частности для `floor division` и `modulo` сказано: \n",
">>\"The numeric arguments are first converted to a common type.\"\n",
"\n",
">а для `modulo` еще и особенно подчеркнуто как именно все прекрасно работает и с `floating point`.\n",
"\n"
],
"metadata": {}
},
{
"cell_type": "code",
"source": [
"# Найшвидший\n",
"\nexec(\"exec(\\\"print(eval('(a) {} b'.format({'div': '//', 'mod': '%', 'pow':'**'}[o] if o in ['div','mod','pow'] else o))) if not(o in ['div','mod','/'] and float(b)==0) else print('Деление на 0!')\\\", {'a':float(input()),'b':float(input()),'o':input()})\")"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"8\n",
"8\n",
"*\n",
"64.0\n"
]
}
],
"execution_count": 7,
"metadata": {}
},
{
"cell_type": "code",
"source": [
"# Це цікаве рішення\n",
"a =float(input())\n",
"b =float(input())\n",
"c =str(input())\n",
"\n\n",
"if (c=='mod' or c=='div' or c=='/') and b == 0:\n",
" print('Деление на 0!')\n",
" \n",
"elif c==('mod'):\n",
" print(a%b)\n",
" \n",
"elif c==('div'):\n",
" print(a//b)\n",
" \n",
"# але як калькулятор не працює :-)\n",
"# тільки заявлені в задачі оператори"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"5\n",
"3\n",
"+\n"
]
}
],
"execution_count": 2,
"metadata": {}
},
{
"cell_type": "code",
"source": [
"# Ще одне хороше рішення\n",
"\n",
"a, b, c = [input() for i in range(3)]\n",
"print (\"Деление на 0!\" if c in (\"/\", \"div\", \"mod\") and float(b) == 0 else eval(\"({0}){1}\".format(a, {'pow':'**', 'div':'//', 'mod':'%'}.get(c, c) + b)))"
],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"99\n",
"88\n",
"/\n",
"1.125\n"
]
}
],
"execution_count": 8,
"metadata": {}
},
{
"cell_type": "code",
"source": [],
"outputs": [],
"execution_count": null,
"metadata": {
"collapsed": true
}
}
],
"metadata": {
"kernelspec": {
"name": "python3",
"language": "python",
"display_name": "Python 3"
},
"language_info": {
"name": "python",
"version": "3.6.3",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
},
"kernel_info": {
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment