From 7dba7403763e62611d1df600b7fd143d4d6c0df0 Mon Sep 17 00:00:00 2001 From: Sergey Lemeshevsky Date: Mon, 9 Mar 2020 14:33:15 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=D1=8B=20?= =?UTF-8?q?=D0=B8=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=BE=20=D1=82=D0=B8=D0=BF=D0=B0=D0=BC=20=D0=BA=D0=BE=D0=BB?= =?UTF-8?q?=D0=BB=D0=B5=D0=BA=D1=86=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + Untitled.ipynb | 656 ++++++++++++++ collections.ipynb | 841 +++++++++++++++++- datatype.ipynb | 72 +- intro.ipynb | 182 +++- src-collections/generate_usernames.py | 72 ++ src-collections/statistics.dat | 8 + src-collections/statistics.py | 95 ++ src-collections/users.txt | 29 + src-collections/users2.txt | 278 ++++++ src-datatype/sample.csv.txt | 5 + .../.ipynb_checkpoints/fib-checkpoint.py | 14 + .../.ipynb_checkpoints/hello-checkpoint.py | 1 + .../.ipynb_checkpoints/test-checkpoint.py | 2 + src-intro/test.py | 2 +- 15 files changed, 2151 insertions(+), 107 deletions(-) create mode 100644 Untitled.ipynb create mode 100755 src-collections/generate_usernames.py create mode 100644 src-collections/statistics.dat create mode 100755 src-collections/statistics.py create mode 100644 src-collections/users.txt create mode 100644 src-collections/users2.txt create mode 100644 src-datatype/sample.csv.txt create mode 100644 src-intro/.ipynb_checkpoints/fib-checkpoint.py create mode 100644 src-intro/.ipynb_checkpoints/hello-checkpoint.py create mode 100644 src-intro/.ipynb_checkpoints/test-checkpoint.py diff --git a/.gitignore b/.gitignore index 8bb6ecf..911ddf6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /.ipynb_checkpoints/*.ipynb +Untitled.ipynb diff --git a/Untitled.ipynb b/Untitled.ipynb new file mode 100644 index 0000000..51c9b17 --- /dev/null +++ b/Untitled.ipynb @@ -0,0 +1,656 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + " 10\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "100\n" + ] + } + ], + "source": [ + "%run src-intro/test.py" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'/home/svl/Projects/Doconce/python-course/ipynb'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%pwd" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "/home/svl/Projects/Doconce/python-course/ipynb/src-intro\n" + ] + } + ], + "source": [ + "%cd src-intro" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello from Python!\n" + ] + } + ], + "source": [ + "%run hello.py" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n" + ] + } + ], + "source": [ + "%run fib.py" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "range(0, 5)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "range(5)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " at 0x7f65857f9c80>\n" + ] + } + ], + "source": [ + "print(i for i in range(5))" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[0;31mInit signature:\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m/\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mDocstring:\u001b[0m \n", + "range(stop) -> range object\n", + "range(start, stop[, step]) -> range object\n", + "\n", + "Return an object that produces a sequence of integers from start (inclusive)\n", + "to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.\n", + "start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.\n", + "These are exactly the valid indices for a list of 4 elements.\n", + "When step is given, it specifies the increment (or decrement).\n", + "\u001b[0;31mType:\u001b[0m type\n", + "\u001b[0;31mSubclasses:\u001b[0m \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "range?" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[10, 8, 6, 4, 2]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(range(10,1, -2))" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n" + ] + } + ], + "source": [ + "%run fib.py" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "can't multiply sequence by non-int of type 'float'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfib\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m~/Projects/Doconce/python-course/ipynb/src-intro/fib.py\u001b[0m in \u001b[0;36mfib\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 5\u001b[0m \"\"\"\n\u001b[1;32m 6\u001b[0m \u001b[0mf0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mf1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0mf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 8\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf0\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mf1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mTypeError\u001b[0m: can't multiply sequence by non-int of type 'float'" + ] + } + ], + "source": [ + "fib(1.0)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> \u001b[0;32m/home/svl/Projects/Doconce/python-course/ipynb/src-intro/fib.py\u001b[0m(7)\u001b[0;36mfib\u001b[0;34m()\u001b[0m\n", + "\u001b[0;32m 5 \u001b[0;31m \"\"\"\n", + "\u001b[0m\u001b[0;32m 6 \u001b[0;31m \u001b[0mf0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mf1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m----> 7 \u001b[0;31m \u001b[0mf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 8 \u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\u001b[0;32m 9 \u001b[0;31m \u001b[0mf\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf0\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mf1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0m\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ipdb> f\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "*** NameError: name 'f' is not defined\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ipdb> f01\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "*** NameError: name 'f01' is not defined\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ipdb> f0\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ipdb> f1\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "ipdb> n\n" + ] + } + ], + "source": [ + "%debug" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 1, 1, 1]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a*4" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1]" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1, 1, 2]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fib(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Once deleted, variables cannot be recovered. Proceed (y/[n])? y\n" + ] + } + ], + "source": [ + "%reset" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'a' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'a' is not defined" + ] + } + ], + "source": [ + "a" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'fib' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfib\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'fib' is not defined" + ] + } + ], + "source": [ + "fib(4)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]\n" + ] + } + ], + "source": [ + "%run fib.py" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8.35 µs ± 194 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n" + ] + } + ], + "source": [ + "%timeit fib(100)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 84 µs, sys: 0 ns, total: 84 µs\n", + "Wall time: 98.5 µs\n" + ] + } + ], + "source": [ + "result = %time fib(100)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 5,\n", + " 8,\n", + " 13,\n", + " 21,\n", + " 34,\n", + " 55,\n", + " 89,\n", + " 144,\n", + " 233,\n", + " 377,\n", + " 610,\n", + " 987,\n", + " 1597,\n", + " 2584,\n", + " 4181,\n", + " 6765,\n", + " 10946,\n", + " 17711,\n", + " 28657,\n", + " 46368,\n", + " 75025,\n", + " 121393,\n", + " 196418,\n", + " 317811,\n", + " 514229,\n", + " 832040,\n", + " 1346269,\n", + " 2178309,\n", + " 3524578,\n", + " 5702887,\n", + " 9227465,\n", + " 14930352,\n", + " 24157817,\n", + " 39088169,\n", + " 63245986,\n", + " 102334155,\n", + " 165580141,\n", + " 267914296,\n", + " 433494437,\n", + " 701408733,\n", + " 1134903170,\n", + " 1836311903,\n", + " 2971215073,\n", + " 4807526976,\n", + " 7778742049,\n", + " 12586269025,\n", + " 20365011074,\n", + " 32951280099,\n", + " 53316291173,\n", + " 86267571272,\n", + " 139583862445,\n", + " 225851433717,\n", + " 365435296162,\n", + " 591286729879,\n", + " 956722026041,\n", + " 1548008755920,\n", + " 2504730781961,\n", + " 4052739537881,\n", + " 6557470319842,\n", + " 10610209857723,\n", + " 17167680177565,\n", + " 27777890035288,\n", + " 44945570212853,\n", + " 72723460248141,\n", + " 117669030460994,\n", + " 190392490709135,\n", + " 308061521170129,\n", + " 498454011879264,\n", + " 806515533049393,\n", + " 1304969544928657,\n", + " 2111485077978050,\n", + " 3416454622906707,\n", + " 5527939700884757,\n", + " 8944394323791464,\n", + " 14472334024676221,\n", + " 23416728348467685,\n", + " 37889062373143906,\n", + " 61305790721611591,\n", + " 99194853094755497,\n", + " 160500643816367088,\n", + " 259695496911122585,\n", + " 420196140727489673,\n", + " 679891637638612258,\n", + " 1100087778366101931,\n", + " 1779979416004714189,\n", + " 2880067194370816120,\n", + " 4660046610375530309,\n", + " 7540113804746346429,\n", + " 12200160415121876738,\n", + " 19740274219868223167,\n", + " 31940434634990099905,\n", + " 51680708854858323072,\n", + " 83621143489848422977,\n", + " 135301852344706746049,\n", + " 218922995834555169026,\n", + " 354224848179261915075]" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "result" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.1" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/collections.ipynb b/collections.ipynb index 3cd433e..649cee7 100644 --- a/collections.ipynb +++ b/collections.ipynb @@ -4,13 +4,13 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "# Тыпы коллекций\n", + "\n", + "# Типы коллекций\n", "\n", " \n", "**С.В. Лемешевский** (email: `sergey.lemeshevsky@gmail.com`), Институт математики НАН Беларуси\n", "\n", - "Date: **Mar 2, 2020**\n", + "Date: **Mar 8, 2020**\n", "\n", "\n", "\n", @@ -406,9 +406,25 @@ "(и рекурсивно, при наличии вложенных элементов, таких как списки или\n", "кортежи в списках).\n", "\n", - "В результате выполнения операции присваивания\n", - "`L = [ – 17.5, \"kilo\", 49, \"V\", [\"ram\", 5, \"echo\"], 7]` мы получим\n", - "список, как показано на рис. [collections:seq:fig:2](#collections:seq:fig:2)\n", + "В результате выполнения операции присваивания" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "L = [ – 17.5, \"kilo\", 49, \"V\", [\"ram\", 5, \"echo\"], 7]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "мы получим список, как показано на рис. [collections:seq:fig:2](#collections:seq:fig:2)\n", "\n", "\n", "\n", @@ -423,7 +439,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": { "collapsed": false }, @@ -491,7 +507,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": { "collapsed": false }, @@ -503,7 +519,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": { "collapsed": false }, @@ -515,7 +531,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": { "collapsed": false }, @@ -540,7 +556,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": { "collapsed": false }, @@ -560,7 +576,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "metadata": { "collapsed": false }, @@ -571,7 +587,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "metadata": { "collapsed": false }, @@ -583,7 +599,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "metadata": { "collapsed": false }, @@ -612,7 +628,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 23, "metadata": { "collapsed": false }, @@ -642,7 +658,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 24, "metadata": { "collapsed": false }, @@ -672,7 +688,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 25, "metadata": { "collapsed": false }, @@ -770,7 +786,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 26, "metadata": { "collapsed": false }, @@ -790,7 +806,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 27, "metadata": { "collapsed": false }, @@ -808,7 +824,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 28, "metadata": { "collapsed": false }, @@ -840,7 +856,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 29, "metadata": { "collapsed": false }, @@ -866,7 +882,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 30, "metadata": { "collapsed": false }, @@ -942,7 +958,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 31, "metadata": { "collapsed": false }, @@ -1060,7 +1076,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 32, "metadata": { "collapsed": false }, @@ -1150,7 +1166,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 33, "metadata": { "collapsed": true }, @@ -1215,7 +1231,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 34, "metadata": { "collapsed": false }, @@ -1244,7 +1260,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 35, "metadata": { "collapsed": false }, @@ -1292,7 +1308,7 @@ "metadata": {}, "source": [ "3\n", - "8\n", + "9\n", " \n", "<\n", "<\n", @@ -1320,7 +1336,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 36, "metadata": { "collapsed": false }, @@ -1365,7 +1381,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 37, "metadata": { "collapsed": false }, @@ -1387,7 +1403,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 38, "metadata": { "collapsed": false }, @@ -1399,7 +1415,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 39, "metadata": { "collapsed": false }, @@ -1422,7 +1438,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 40, "metadata": { "collapsed": false }, @@ -1656,7 +1672,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 41, "metadata": { "collapsed": false }, @@ -1670,7 +1686,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 42, "metadata": { "collapsed": false }, @@ -1714,7 +1730,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 43, "metadata": { "collapsed": false }, @@ -1739,7 +1755,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 44, "metadata": { "collapsed": false }, @@ -1774,7 +1790,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 45, "metadata": { "collapsed": false }, @@ -1800,7 +1816,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 46, "metadata": { "collapsed": false }, @@ -1827,7 +1843,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 47, "metadata": { "collapsed": false }, @@ -1840,7 +1856,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 48, "metadata": { "collapsed": false }, @@ -1867,7 +1883,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 49, "metadata": { "collapsed": false }, @@ -1893,11 +1909,750 @@ "\n", "\n", "\n", + "# Примеры\n", + "
\n", + "\n", + "Сейчас рассмотрим пару примеров, в которых используется многое из\n", + "того, о чем рассказывалось в этой и в предыдущей главах.\n", + "\n", + "Первая программа имеет отношение к обработке текстовой\n", + "информации. Вторая программа содержит примерно девяносто строк и\n", + "предназначена для выполнения математических вычислений. Обе программы\n", + "используют словари, списки, именованные кортежи и множества и обе\n", + "широко используют метод `str.format()`, который был описан в предыдущей\n", + "главе.\n", + "\n", + "## Генератор имен пользователей\n", + "
\n", + "\n", + "Представьте, что мы выполняем настройку новой компьютерной системы и\n", + "нам необходимо сгенерировать имена пользователей для всех служащих\n", + "нашей компании. У нас имеется простой текстовый файл (в кодировке\n", + "UTF-8), где каждая строка представляет собой запись из полей,\n", + "разделенных двоеточиями. Каждая запись соответствует одному сотруднику\n", + "компании и содержит следующие поля: уникальный идентификатор\n", + "служащего, имя, отчество (это поле может быть пустым), фамилию и\n", + "название отдела.\n", + "\n", + "Ниже в качестве примера приводятся несколько строк из файла\n", + "[users.txt](src-collections/users.txt) :" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " 1080:Priscillia:Forbes:Shepard:Cleaning Services\n", + " 4382:Devan::Fielder:Public Relations\n", + " 6285:Grey::Collyer:Public Relations\n", + " 6201:Kierah::Battaile:Catering\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Программа должна читать данные из файла, который указан в командной\n", + "строке, извлекать отдельные поля из каждой строки (записи) и\n", + "возвращать подходящие имена пользователей. Каждое имя пользователя\n", + "должно быть уникальным и должно создаваться на основе имени\n", + "сотрудника. Результаты должны выводиться на консоль в текстовом виде,\n", + "отсортированными в алфавитном порядке по фамилии и имени, например:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Terminal> ./generate_usernames.py users.txt\n", + " Name ID Username \n", + " -------------------------------- ------ ---------\n", + " Battaile, Kierah................ (6201) kbattail \n", + " Blakey, Kelci-Louise............ (0641) kblakey \n", + " Blenkinsop, Keirien............. (4541) kblenkin \n", + " Clifford, Rebbekkah............. (6263) rcliffor \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Каждая запись имеет точно пять полей, и хотя можно обращаться\n", + "к ним по числовым индексам, тем не менее мы будем использовать\n", + "осмысленные имена, чтобы сделать программный код более понятным:" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "ID, FORENAME, MIDDLENAME, SURNAME, DEPARTMENT = range(5)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "В языке Python общепринято использовать только символы верхнего\n", + "регистра для идентификаторов, которые будут играть роль констант.\n", + "\n", + "Нам также необходимо создать тип именованного кортежа, где будут\n", + "храниться данные о текущем пользователе:" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "\n", + "User = collections.namedtuple(\"User\",\n", + " \"username forename middlename surname id\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Основная логика программы сосредоточена в функции `main()`:" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def main():\n", + " if len(sys.argv) == 1 or sys.argv[1] in {\"-h\", \"--help\"}:\n", + " print(\"usage: {0} file1 [file2 [... fileN]]\".format(\n", + " sys.argv[0]))\n", + " sys.exit()\n", + "\n", + " usernames = set()\n", + " users = {}\n", + " for filename in sys.argv[1:]:\n", + " with open(filename, encoding=\"utf8\") as file:\n", + " for line in file:\n", + " line = line.rstrip()\n", + " if line:\n", + " user = process_line(line, usernames)\n", + " users[(user.surname.lower(), user.forename.lower(),\n", + " user.id)] = user\n", + " print_users(users)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Если пользователь не ввел в командной строке имя какого-нибудь\n", + "файла или ввел параметр `-h` или `--help`, то программа просто выводит\n", + "текст сообщения с инструкцией о порядке использования и завершает\n", + "работу.\n", + "\n", + "Из каждой прочитанной строки удаляются любые завершающие пробельные\n", + "символы (такие как `\\n`), и обработка строки продолжается, только если\n", + "она не пустая. Это означает, что если в данных содержатся пустые\n", + "строки, они будут просто проигнорированы.\n", + "\n", + "Все сгенерированные имена пользователей сохраняются в множестве\n", + "`usernames`, чтобы гарантировать отсутствие повторяющихся имен\n", + "пользователей. Сами данные сохраняются в словаре `users`. Информация о\n", + "каждом пользователе сохраняется в виде элемента словаря, ключом\n", + "которого является кортеж, содержащий фамилию сотрудника, его имя и\n", + "идентификатор, а значением – именованный кортеж типа\n", + "`User`. Использование кортежа, содержащего фамилию сотрудника, его имя \n", + "и идентификатор, в качестве ключа обеспечивает возможность вызывать\n", + "функцию `sorted()` для словаря и получать итерируемый объект, в\n", + "котором элементы будут упорядочены в требуемом нам порядке (то есть\n", + "фамилия, имя, идентификатор), избежав необходимости создавать функцию,\n", + "которую пришлось бы передавать в качестве аргумента `key`." + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def process_line(line, usernames):\n", + " fields = line.split(\":\")\n", + " username = generate_username(fields, usernames)\n", + " user = User(username, fields[FORENAME], fields[MIDDLENAME],\n", + " fields[SURNAME], fields[ID])\n", + " return user" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Поскольку все записи имеют очень простой формат, и мы уже удалили\n", + "из строки завершающие пробельные символы, извлечь отдельные поля можно\n", + "простой разбивкой строки по двоеточиям. Мы передаем список полей и\n", + "множество `usernames` в функцию `generate_username()` и затем \n", + "создаем экземпляр именованного кортежа User, который возвращается\n", + "вызывающей программе (функции `main()`), которая в свою очередь\n", + "вставляет информацию о пользователе в словарь `users`, готовый для\n", + "вывода на экран.\n", + "\n", + "Если бы мы не создали соответствующие константы для хранения индексов,\n", + "мы могли бы использовать числовые индексы, как показано ниже:" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "user = User(username, fields[1], fields[2], fields[3], fields[0])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Хотя такой программный код занимает меньше места, тем не менее\n", + "это не самое лучшее решение. Во-первых, человеку, который будет\n", + "сопровождать такой программный код, непонятно, какое поле какую\n", + "информацию содержит, а, во-вторых, такой программный код чувствителен\n", + "к изменениям в формате файла с данными – если изменится \n", + "порядок или число полей в записи, этот программный код окажется\n", + "неработоспособен. При использовании констант в случае изменения\n", + "структуры записи нам достаточно будет изменить только значения\n", + "констант, и программа сохранит свою работоспособность." + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def generate_username(fields, usernames):\n", + " username = ((fields[FORENAME][0] + fields[MIDDLENAME][:1] +\n", + " fields[SURNAME]).replace(\"-\", \"\").replace(\"'\", \"\"))\n", + " username = original_name = username[:8].lower()\n", + " count = 1\n", + " while username in usernames:\n", + " username = \"{0}{1}\".format(original_name, count)\n", + " count += 1\n", + " usernames.add(username)\n", + " return username" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "При первой попытке имя пользователя создается путем конкатенации\n", + "первого символа имени, первого символа отчества и фамилии целиком,\n", + "после чего из полученной строки удаляются дефисы и апострофы. \n", + "Выражение, извлекающее первый символ отчества, таит в себе одну\n", + "хитрость. Если просто использовать обращение `fields[MIDDLENAME][0]`,\n", + "то в случае отсутствия отчества будет возбуждено исключение\n", + "`IndexError`. Но при использовании операции извлечения среза мы\n", + "получаем либо первый символ отчества, либо пустую строку.\n", + "\n", + "Затем мы переводим все символы полученного имени пользователя\n", + "в нижний регистр и ограничиваем его длину восемью символами. Если\n", + "имя пользователя уже занято (то есть оно уже присутствует в множестве\n", + "`usernames`), предпринимается попытка добавить в конец имени\n", + "пользователя символ `\"1\"`, если это имя пользователя тоже занято, тогда\n", + "предпринимается попытка добавить символ `\"2\"` и т. д., пока не будет\n", + "получено незанятое имя пользователя. После этого имя пользователя\n", + "добавляется в множество `usernames` и возвращается вызывающей\n", + "программе." + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def print_users(users):\n", + " namewidth = 32\n", + " usernamewidth = 9\n", + "\n", + " print(\"{0:<{nw}} {1:^6} {2:{uw}}\".format(\n", + " \"Name\", \"ID\", \"Username\", nw=namewidth, uw=usernamewidth))\n", + " print(\"{0:-<{nw}} {0:-<6} {0:-<{uw}}\".format(\n", + " \"\", nw=namewidth, uw=usernamewidth))\n", + "\n", + " for key in sorted(users):\n", + " user = users[key]\n", + " initial = \"\"\n", + " if user.middlename:\n", + " initial = \" \" + user.middlename[0]\n", + " name = \"{0.surname}, {0.forename}{1}\".format(user, initial)\n", + " print(\"{0:.<{nw}} ({1.id:4}) {1.username:{uw}}\".format(\n", + " name, user, nw=namewidth, uw=usernamewidth))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "После обработки всех записей вызывается функция `print_users()`,\n", + "которой в качестве параметра передается словарь `users`.\n", + "\n", + "Первая инструкция `print()` выводит заголовки столбцов. Вторая\n", + "инструкция `print()` выводит дефисы под каждым из заголовков. В этой\n", + "второй инструкции метод `str.format()` используется довольно\n", + "оригинальным образом. Для вывода ему определяется строка `\"\"`, то есть\n", + "пустая строка; в результате при выводе пустой строки мы получаем\n", + "строку из дефисов заданной ширины поля вывода.\n", + "\n", + "Затем мы используем цикл `for ... in` для вывода информации о каждом\n", + "пользователе, извлекая ключи из отсортированного словаря. Для удобства\n", + "мы создаем переменную user, чтобы не вводить каждый раз `users[key]` в\n", + "оставшейся части функции. В цикле сначала вызывается метод\n", + "`str.format()`, чтобы записать в переменную name фамилию сотрудника, имя\n", + "и необязательный первый символ отчества. Обращение к элементам в\n", + "именованном кортеже user производится по их именам. Собрав строку с\n", + "именем пользователя, мы выводим информацию о пользователе, ограничивая\n", + "ширину каждого столбца (имя сотрудника, идентификатор и имя\n", + "пользователя) желаемыми значениями.\n", + "\n", + "Полный программный код программы находится в файле\n", + "[generate_usernames.py](src-collections/generate_usernames.py)\n", + "\n", + "## Статистика\n", + "
\n", + "\n", + "Предположим, что у нас имеется пакет файлов с данными, содержащих\n", + "числовые результаты некоторой обработки, выполненной нами, и нам\n", + "необходимо вычислить некоторые основные статистические характеристики,\n", + "которые дадут нам возможность составить общую картину о полученных\n", + "данных. В каждом файле находится обычный текст (в кодировке ASCII), с\n", + "одним или более числами в каждой строке (разделенными пробельными\n", + "символами).\n", + "\n", + "Ниже приводится пример информации, которую нам необходимо получить:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Terminal> python statistics.py statistics.dat \n", + " count = 129\n", + " mean = 170.49\n", + " median = 51.00\n", + " mode = 50.00\n", + " std. dev. = 269.50\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Здесь видно, что прочитано $129$ чисел, из которых наиболее часто\n", + "встречается число $50$ со стандартным отклонением по выборке $269.50$.\n", + "\n", + "Сами статистические ххарактеристики хранятся в именованном кортеже\n", + "`Statistics`:" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "Statistics = collections.namedtuple(\"Statistics\",\n", + " \"mean mode median std_dev\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Функция `main()` может служить схематическим отображением структуры\n", + "программы:" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def main():\n", + " if len(sys.argv) == 1 or sys.argv[1] in {\"-h\", \"--help\"}:\n", + " print(\"usage: {0} file1 [file2 [... fileN]]\".format(\n", + " sys.argv[0]))\n", + " sys.exit()\n", + "\n", + " numbers = []\n", + " frequencies = collections.defaultdict(int)\n", + " for filename in sys.argv[1:]:\n", + " read_data(filename, numbers, frequencies)\n", + " if numbers:\n", + " statistics = calculate_statistics(numbers, frequencies)\n", + " print_results(len(numbers), statistics)\n", + " else:\n", + " print(\"no numbers found\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Все числа из всех файлов сохраняются в списке `numbers`. Для\n", + "нахождения модальных («наиболее часто встречающихся») значений нам\n", + "необходимо знать, сколько раз встречается каждое число, поэтому мы\n", + "создаем словарь со значениями по умолчанию, используя функцию `int()` \n", + "в качестве фабричной функции, где будут накапливаться счетчики.\n", + "\n", + "Затем выполняется обход списка файлов и производится чтение данных из\n", + "них. В качестве дополнительных аргументов мы передаем функции\n", + "`read_data()` список и словарь со значениями по умолчанию, чтобы она\n", + "могла обновлять их. После чтения всех данных мы исходим из\n", + "предположения, что некоторые числа были благополучно прочитаны, и\n", + "вызываем функцию `calculate_statistics()`. Она возвращает именованный\n", + "кортеж типа `Statistics`, который затем используется для вывода\n", + "результатов." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def read_data(filename, numbers, frequencies):\n", + " with open(filename, encoding=\"ascii\") as file:\n", + " for lino, line in enumerate(file, start=1):\n", + " for x in line.split():\n", + " try:\n", + " number = float(x)\n", + " numbers.append(number)\n", + " frequencies[number] += 1\n", + " except ValueError as err:\n", + " print(\"{filename}:{lino}: skipping {x}: {err}\".format(\n", + " **locals()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Каждая строка разбивается по пробельным символам, после чего\n", + "производится попытка преобразовать каждый элемент в число типа\n", + "`float`. Если преобразование удалось, следовательно, это либо целое\n", + "число, либо число с плавающей точкой в десятичной или в\n", + "экспоненциальной форме. Полученное число добавляется в список numbers\n", + "и выполняется обновление словаря `frequencies` со значениями по\n", + "умолчанию. (Если бы здесь использовался обычный словарь `dict`,\n", + "программный код, выполняющий обновление словаря, мог бы выглядеть так:\n", + "`frequencies[number] = frequencies.get(number, 0) + 1`.) Если\n", + "преобразование потерпело неудачу, выводится номер строки (счет строк в\n", + "текстовых файлах по традиции начинается с 1), текст, который программа\n", + "пыталась преобразовать в число, и сообщение об ошибке, соответствующее\n", + "исключению `ValueError`." + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def calculate_statistics(numbers, frequencies):\n", + " mean = sum(numbers) / len(numbers)\n", + " mode = calculate_mode(frequencies, 3)\n", + " median = calculate_median(numbers)\n", + " std_dev = calculate_std_dev(numbers, mean)\n", + " return Statistics(mean, mode, median, std_dev)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Эта функция используется для сбора всех статистических характеристик\n", + "воедино. Поскольку среднее значение вычисляется очень просто, мы\n", + "делаем это прямо здесь. Вычислением других статистических\n", + "характеристик занимаются отдельные функции, и в заключение данная\n", + "функция возвращает экземпляр именованного кортежа `Statistics`,\n", + "содержащий четыре вычисленные статистические характеристики." + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def calculate_mode(frequencies, maximum_modes):\n", + " highest_frequency = max(frequencies.values())\n", + " mode = [number for number, frequency in frequencies.items()\n", + " if frequency == highest_frequency]\n", + " if not (1 <= len(mode) <= maximum_modes):\n", + " mode = None\n", + " else:\n", + " mode.sort()\n", + " return mode" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "В выборке может существовать сразу несколько значений, встречающихся\n", + "наиболее часто, поэтому, помимо словаря `frequencies`, функции\n", + "передается максимально допустимое число модальных значений. (Эта\n", + "функция вызывается из `calculate_statistics()`, и при вызове задается\n", + "максимальное число модальных значений, равное трем.)\n", + "\n", + "Функция `max()` используется для поиска наибольшего значения в словаре\n", + "`frequencies`. Затем с помощью генератора списков создается список из\n", + "значений, которые равны наивысшему значению. Поскольку числа могут\n", + "быть с плавающей точкой, мы сравниваем абсолютное значение разницы\n", + "(используя функцию `math.fabs()`, поскольку она лучше подходит для\n", + "случаев сравнения малых величин, близких к порогу точности\n", + "представления числовых значений в компьютере, чем `abs()`) с\n", + "наименьшим значением, которое может быть представлено компьютером.\n", + "\n", + "Если число модальных значений равно 0 или больше максимального,\n", + "то в качестве модального значения возвращается `None`; в противном \n", + "случае возвращается сортированный список модальных значений." + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def calculate_median(numbers):\n", + " numbers = sorted(numbers)\n", + " middle = len(numbers) // 2\n", + " median = numbers[middle]\n", + " if len(numbers) % 2 == 0:\n", + " median = (median + numbers[middle - 1]) / 2\n", + " return median" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Медиана* («среднее значение») – это значение, находящееся в середине упорядоченной\n", + "выборки чисел, за исключением случая, когда в выборке присутствует\n", + "четное число чисел, – тогда значение медианы определяется как среднее\n", + "арифметическое значение двух чисел, находящихся в середине. \n", + "\n", + "Функция вычисления медианы сначала выполняет сортировку чисел\n", + "по возрастанию. Затем посредством целочисленного деления определяется\n", + "позиция середины выборки, откуда извлекается число и сохраняется как\n", + "значение медианы. Если выборка содержит четное число значений, то\n", + "значение медианы определяется как среднее арифметическое двух чисел,\n", + "находящихся в середине." + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def calculate_std_dev(numbers, mean):\n", + " total = 0\n", + " for number in numbers:\n", + " total += ((number - mean) ** 2)\n", + " variance = total / (len(numbers) - 1)\n", + " return math.sqrt(variance)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Стандартное отклонение* – это мера дисперсии; оно определяет, как \n", + "сильно отклоняются значения в выборке от среднего значения. Вычисление\n", + "стандартного отклонения в этой функции выполняется по формуле" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "$$\n", + "\\frac{\\sqrt{\\sum(x + \\bar{x})^2}}{n-1},\n", + "$$" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "где $x$ — очередное число, $\\bar{x}$ — среднее значение, а $n$ —\n", + "количество чисел." + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def print_results(count, statistics):\n", + " real = \"9.2f\"\n", + "\n", + " if statistics.mode is None:\n", + " modeline = \"\"\n", + " elif len(statistics.mode) == 1:\n", + " modeline = \"mode = {0:{fmt}}\\n\".format(statistics.mode[0], fmt=real)\n", + " else:\n", + " modeline = (\"mode = [\" + \", \".join([\"{0:.2f}\".format(m)\n", + " for m in statistics.mode]) + \"]\\n\")\n", + "\n", + " print(\"\"\"\\\n", + "count = {0:6}\n", + "mean = {mean:{fmt}}\n", + "median = {median:{fmt}}\n", + "{1}\\\n", + "std. dev. = {std_dev:{fmt}}\"\"\".format(count, modeline, fmt=real, **statistics._asdict()))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Большая часть этой функции связана с форматированием списка модальных\n", + "значений в строку `modeline`. Если модальные значения отсутствуют, то\n", + "строка `modeline` вообще не выводится. Если модальное значение\n", + "единственное, список модальных значений содержит единственный элемент\n", + "(`mode[0]`), который и выводится с той же строкой форматирования, что\n", + "используется при выводе других статистических значений. Если имеется\n", + "несколько модальных значений, они выводятся как список, в котором\n", + "каждое значение форматируется отдельно. Делается это с помощью\n", + "генератора списков, который позволяет получить список строк с\n", + "модальными значениями; строки затем объединяются в единую строку, где\n", + "отделяются друг от друга запятой с пробелом (`\", \"`). Последняя\n", + "инструкция `print()` в самом конце получилась очень простой благодаря\n", + "использованию именованного кортежа. Он позволяет обращаться к\n", + "статистическим значениям в объекте `statistics`, используя не числовые\n", + "индексы, а их имена, а благодаря строкам в тройных кавычках мы смогли\n", + "отформатировать выводимый текст наглядным способом.\n", + "\n", + "В этой функции имеется одна особенность, о которой следует упомянуть\n", + "отдельно. Строка с модальными значениями выводится с помощью элемента\n", + "строки формата `{2}`, за которым следует символ обратного\n", + "слеша. Символ обратного слеша экранирует символ перевода строки,\n", + "поэтому если строка с модальными значениями пустая, то пустая строка\n", + "выводиться не будет. Именно по этой причине мы вынуждены были добавить\n", + "символ `\\n` в конец строки `modeline`, если она не пустая.\n", "\n", "\n", "\n", "\n", - "" + "\n", + "\n", + "# Упражнения\n", + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "## Модификация вывода в генераторе имен пользователей\n", + "
\n", + "\n", + "Модифицируйте программу `generate_usernames.py` так, чтобы в каждой\n", + "строке она выводила информацию о двух пользователях, ограничив длину\n", + "имени 17 символами; через каждые 64 строки программа должна выводить\n", + "символ перевода формата и в начале каждой страницы она должна выводить\n", + "заголовки столбцов. Ниже приводится пример того, как должен выглядеть\n", + "вывод программы:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " Name ID Username Name ID Username \n", + " ----------------- ------ --------- ----------------- ------ ---------\n", + " Warne, Brogan A.. (8985) bawarne Wasling, Elisabet (1853) ewasling \n", + " Webber, Gretchen. (6427) gwebber Weidenmeyer, Deva (6290) dweidenm \n", + " Wennerbom, Emma.. (8115) ewennerb Wennerbom, Keigan (3617) kywenner\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Достаточно большой объем исходных данных вы найдете в файле\n", + "[users2.txt](src-collections/users2.txt).\n", + "\n", + "\n", + "\n", + "**Подсказка.**\n", + "Это достаточно сложно. Вам потребуется сохранить заголовки\n", + "столбцов в переменных, чтобы потом их можно было использовать\n", + "по мере необходимости, и изменить спецификаторы формата, чтобы\n", + "обеспечить вывод более коротких имен. Один из способов обеспечить\n", + "постраничный вывод заключается в том, чтобы сохранить все выводимые\n", + "строки в списке, а затем выполнить обход списка, используя оператор\n", + "извлечения среза с шагом для получения элементов слева и справа и\n", + "применяя функцию `zip()` для их объединения.\n", + "\n", + "\n", + "Имя файла: `generate_usernames_ans.py`.\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" ] } ], diff --git a/datatype.ipynb b/datatype.ipynb index b5c5907..40df308 100644 --- a/datatype.ipynb +++ b/datatype.ipynb @@ -10,7 +10,7 @@ " \n", "**С.В. Лемешевский** (email: `sergey.lemeshevsky@gmail.com`), Институт математики НАН Беларуси\n", "\n", - "Date: **Feb 27, 2020**\n", + "Date: **Mar 4, 2020**\n", "\n", "\n", "\n", @@ -1806,7 +1806,7 @@ "преобразуется к верхнему регистру, а остальные символы – к нижнему. \n", "\n", "\n", - "## `quadratic.py`\n", + "## Решение квадратного уравнения\n", "
\n", "\n", "Квадратные уравнения – это уравнения вида $ax^2 + bx + c = 0$, где $a \\ne 0$,\n", @@ -1845,8 +1845,27 @@ "С коэффициентами $1.5$, $-3$ и $6$ программа выведет (некоторые цифры\n", "обрезаны):\n", "\n", - "Теперь обратимся к программному коду, который начинается тремя инструкциями `import`:\n", - "\n", + "Теперь обратимся к [программному коду](src-datatype/quadratic.py),\n", + "который начинается тремя инструкциями `import`:" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import cmath\n", + "import math\n", + "import sys" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "Нам необходимы обе математические библиотеки для работы с числами типа\n", "`float` и `complex`, так как функции, вычисляющие квадратный \n", "корень из вещественных и комплексных чисел, отличаются. Модуль\n", @@ -1860,13 +1879,12 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 55, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "# Start get_float\n", "def get_float(msg, allow_zero):\n", " x = None\n", " while x is None:\n", @@ -1895,13 +1913,12 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 56, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "# Start 1st block\n", "print(\"ax\\N{SUPERSCRIPT TWO} + bx + c = 0\")\n", "a = get_float(\"enter a: \", False)\n", "b = get_float(\"enter b: \", False)\n", @@ -1919,13 +1936,12 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 57, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "# Start 2d block\n", "x1 = None\n", "x2 = None\n", "discriminant = (b ** 2) - (4 * a * c)\n", @@ -1954,13 +1970,12 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 58, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "# Start 3d block\n", "equation = (\"{0}x\\N{SUPERSCRIPT TWO} + {1}x + {2} = 0\"\n", " \" \\N{RIGHTWARDS ARROW} x = {3}\").format(a, b, c, x1)\n", "if x2 is not None:\n", @@ -1978,7 +1993,7 @@ "использовали некоторые имена Юникода для вывода пары специальных\n", "символов.\n", "\n", - "## `csv2html.py`\n", + "## Представление таблицы `csv` в HTML\n", "
\n", "\n", "Часто бывает необходимо представить данные в формате HTML. В этом\n", @@ -2018,8 +2033,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Предположим, что данные находятся в файле\n", - "\"sample.csv\": \"src-datatype/sample.csv\" и выполнена комадна" + "Предположим, что данные находятся в файле [sample.csv](src-datatype/sample.csv.txt) и выполнена комадна" ] }, { @@ -2091,10 +2105,10 @@ "source": [ "На рис. показано, как выглядит полученная таблица в веб-броузере.\n", "\n", - "\n", + "\n", "\n", "
\n", - "![Таблица, произведенная программой csv2html.py, в броузере](fig-datatype/example_1.png)\n", + "![Таблица, произведенная программой [csv2html.py](src-datatype/csv2html.py), в броузере](fig-datatype/example_1.png)\n", "\n", "\n", "Теперь, когда мы увидели, как используется программа и что она делает,\n", @@ -2105,7 +2119,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 59, "metadata": { "collapsed": false }, @@ -2128,10 +2142,10 @@ "функций в файле (то есть порядок, в котором они создаются) не \n", "имеет значения.\n", "\n", - "В программе `csv2html.py` первой вызываемой функцией является функция\n", - "`main()`, которая в свою очередь вызывает функции `print_start()` и\n", - "`print_line()`. Функция `print_line()` вызывает функции\n", - "`extract_fields()` и `escape_html()`.\n", + "В программе [csv2html.py](src-datatype/csv2html.py) первой\n", + "вызываемой функцией является функция `main()`, которая в свою очередь\n", + "вызывает функции `print_start()` и `print_line()`. Функция\n", + "`print_line()` вызывает функции `extract_fields()` и `escape_html()`.\n", "\n", "Когда интерпретатор Python читает файл, он начинает делать это с\n", "самого начала. Поэтому сначала будет выполнен импорт (если он есть),\n", @@ -2147,7 +2161,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 60, "metadata": { "collapsed": false }, @@ -2190,7 +2204,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 61, "metadata": { "collapsed": false }, @@ -2215,7 +2229,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 62, "metadata": { "collapsed": false }, @@ -2273,7 +2287,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 63, "metadata": { "collapsed": false }, @@ -2292,7 +2306,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 64, "metadata": { "collapsed": false }, @@ -2337,7 +2351,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 65, "metadata": { "collapsed": false }, @@ -2382,7 +2396,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 66, "metadata": { "collapsed": false }, diff --git a/intro.ipynb b/intro.ipynb index 15ff52a..0cd12cd 100644 --- a/intro.ipynb +++ b/intro.ipynb @@ -354,7 +354,10 @@ "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -427,7 +430,10 @@ "cell_type": "code", "execution_count": 2, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -550,7 +556,10 @@ "cell_type": "code", "execution_count": 3, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -660,7 +669,10 @@ "cell_type": "code", "execution_count": 4, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -748,7 +760,10 @@ "cell_type": "code", "execution_count": 5, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -759,7 +774,10 @@ "cell_type": "code", "execution_count": 6, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -770,7 +788,10 @@ "cell_type": "code", "execution_count": 7, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -781,7 +802,10 @@ "cell_type": "code", "execution_count": 8, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -792,7 +816,10 @@ "cell_type": "code", "execution_count": 9, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -818,7 +845,10 @@ "cell_type": "code", "execution_count": 10, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -829,7 +859,10 @@ "cell_type": "code", "execution_count": 11, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -840,7 +873,10 @@ "cell_type": "code", "execution_count": 12, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -851,7 +887,10 @@ "cell_type": "code", "execution_count": 13, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -901,7 +940,10 @@ "cell_type": "code", "execution_count": 14, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -912,7 +954,10 @@ "cell_type": "code", "execution_count": 15, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -943,7 +988,10 @@ "cell_type": "code", "execution_count": 16, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -967,7 +1015,10 @@ "cell_type": "code", "execution_count": 17, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -978,7 +1029,10 @@ "cell_type": "code", "execution_count": 18, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -989,7 +1043,10 @@ "cell_type": "code", "execution_count": 19, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1008,7 +1065,10 @@ "cell_type": "code", "execution_count": 20, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1019,7 +1079,10 @@ "cell_type": "code", "execution_count": 21, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1051,7 +1114,10 @@ "cell_type": "code", "execution_count": 22, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1091,7 +1157,10 @@ "cell_type": "code", "execution_count": 23, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1143,7 +1212,10 @@ "cell_type": "code", "execution_count": 24, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1154,7 +1226,10 @@ "cell_type": "code", "execution_count": 25, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1165,7 +1240,10 @@ "cell_type": "code", "execution_count": 26, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1206,7 +1284,10 @@ "cell_type": "code", "execution_count": 27, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1230,7 +1311,10 @@ "cell_type": "code", "execution_count": 28, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1300,7 +1384,10 @@ "cell_type": "code", "execution_count": 29, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1311,7 +1398,10 @@ "cell_type": "code", "execution_count": 30, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1342,7 +1432,10 @@ "cell_type": "code", "execution_count": 31, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -1370,7 +1463,10 @@ "cell_type": "code", "execution_count": 32, "metadata": { - "collapsed": false + "collapsed": false, + "jupyter": { + "outputs_hidden": false + } }, "outputs": [], "source": [ @@ -2133,7 +2229,25 @@ ] } ], - "metadata": {}, + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.1" + } + }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/src-collections/generate_usernames.py b/src-collections/generate_usernames.py new file mode 100755 index 0000000..3fe9382 --- /dev/null +++ b/src-collections/generate_usernames.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- + +import collections +import sys + +# Start 1st block +ID, FORENAME, MIDDLENAME, SURNAME, DEPARTMENT = range(5) +# End 1st block + +User = collections.namedtuple("User", + "username forename middlename surname id") +# End 2d block + +def main(): + if len(sys.argv) == 1 or sys.argv[1] in {"-h", "--help"}: + print("usage: {0} file1 [file2 [... fileN]]".format( + sys.argv[0])) + sys.exit() + + usernames = set() + users = {} + for filename in sys.argv[1:]: + with open(filename, encoding="utf8") as file: + for line in file: + line = line.rstrip() + if line: + user = process_line(line, usernames) + users[(user.surname.lower(), user.forename.lower(), + user.id)] = user + print_users(users) + + +def process_line(line, usernames): + fields = line.split(":") + username = generate_username(fields, usernames) + user = User(username, fields[FORENAME], fields[MIDDLENAME], + fields[SURNAME], fields[ID]) + return user + + +def generate_username(fields, usernames): + username = ((fields[FORENAME][0] + fields[MIDDLENAME][:1] + + fields[SURNAME]).replace("-", "").replace("'", "")) + username = original_name = username[:8].lower() + count = 1 + while username in usernames: + username = "{0}{1}".format(original_name, count) + count += 1 + usernames.add(username) + return username + + +def print_users(users): + namewidth = 32 + usernamewidth = 9 + + print("{0:<{nw}} {1:^6} {2:{uw}}".format( + "Name", "ID", "Username", nw=namewidth, uw=usernamewidth)) + print("{0:-<{nw}} {0:-<6} {0:-<{uw}}".format( + "", nw=namewidth, uw=usernamewidth)) + + for key in sorted(users): + user = users[key] + initial = "" + if user.middlename: + initial = " " + user.middlename[0] + name = "{0.surname}, {0.forename}{1}".format(user, initial) + print("{0:.<{nw}} ({1.id:4}) {1.username:{uw}}".format( + name, user, nw=namewidth, uw=usernamewidth)) + + +main() diff --git a/src-collections/statistics.dat b/src-collections/statistics.dat new file mode 100644 index 0000000..9d67365 --- /dev/null +++ b/src-collections/statistics.dat @@ -0,0 +1,8 @@ +622 480 899 298 221 940 196 556 -7 593 250 699 966 530 143 22 +-59 164 976 566 -56 960 340 754 620 533 528 308 47.3 14.5 +10 51 22 06 50 79 90 34 68 50 -29 -19 +29 58 73 15 4 6 17 5 4 5 3 7 5.5 9 1 7 8 -17 0 -9.5 5 +299 985 834 72 -100 270 656 -44 255 38 616 845 -6 542 -81 379 279 +7 33 50 88 2 91 20 93 60 80 43 93 67 80 41 14 99 73 59 73 74 26 28 +39 81 41 18 83 30 74 72 51 15 59 +0.9 97 3 35 11 54 50 58 24 11 26 79 21 61 15 diff --git a/src-collections/statistics.py b/src-collections/statistics.py new file mode 100755 index 0000000..49a9f65 --- /dev/null +++ b/src-collections/statistics.py @@ -0,0 +1,95 @@ +import collections +import math +import sys + +#Start 1st block +Statistics = collections.namedtuple("Statistics", + "mean mode median std_dev") +#End 1st block + +def main(): + if len(sys.argv) == 1 or sys.argv[1] in {"-h", "--help"}: + print("usage: {0} file1 [file2 [... fileN]]".format( + sys.argv[0])) + sys.exit() + + numbers = [] + frequencies = collections.defaultdict(int) + for filename in sys.argv[1:]: + read_data(filename, numbers, frequencies) + if numbers: + statistics = calculate_statistics(numbers, frequencies) + print_results(len(numbers), statistics) + else: + print("no numbers found") + + +def read_data(filename, numbers, frequencies): + with open(filename, encoding="ascii") as file: + for lino, line in enumerate(file, start=1): + for x in line.split(): + try: + number = float(x) + numbers.append(number) + frequencies[number] += 1 + except ValueError as err: + print("{filename}:{lino}: skipping {x}: {err}".format( + **locals())) + + +def calculate_statistics(numbers, frequencies): + mean = sum(numbers) / len(numbers) + mode = calculate_mode(frequencies, 3) + median = calculate_median(numbers) + std_dev = calculate_std_dev(numbers, mean) + return Statistics(mean, mode, median, std_dev) + + +def calculate_mode(frequencies, maximum_modes): + highest_frequency = max(frequencies.values()) + mode = [number for number, frequency in frequencies.items() + if frequency == highest_frequency] + if not (1 <= len(mode) <= maximum_modes): + mode = None + else: + mode.sort() + return mode + + +def calculate_median(numbers): + numbers = sorted(numbers) + middle = len(numbers) // 2 + median = numbers[middle] + if len(numbers) % 2 == 0: + median = (median + numbers[middle - 1]) / 2 + return median + + +def calculate_std_dev(numbers, mean): + total = 0 + for number in numbers: + total += ((number - mean) ** 2) + variance = total / (len(numbers) - 1) + return math.sqrt(variance) + + +def print_results(count, statistics): + real = "9.2f" + + if statistics.mode is None: + modeline = "" + elif len(statistics.mode) == 1: + modeline = "mode = {0:{fmt}}\n".format(statistics.mode[0], fmt=real) + else: + modeline = ("mode = [" + ", ".join(["{0:.2f}".format(m) + for m in statistics.mode]) + "]\n") + + print("""\ +count = {0:6} +mean = {mean:{fmt}} +median = {median:{fmt}} +{1}\ +std. dev. = {std_dev:{fmt}}""".format(count, modeline, fmt=real, **statistics._asdict())) + + +main() diff --git a/src-collections/users.txt b/src-collections/users.txt new file mode 100644 index 0000000..bd5ffbf --- /dev/null +++ b/src-collections/users.txt @@ -0,0 +1,29 @@ +1080:Priscillia:Forbes:Shepard:Cleaning Services +4382:Devan::Fielder:Public Relations +6285:Grey::Collyer:Public Relations +6201:Kierah::Battaile:Catering +6671:Madilyn::Helling:Public Relations +4898:Deri-J::Watherston:Research +8954:Alec::Leng:Production +6263:Rebbekkah::Clifford:Cleaning Services +1704:Elorm::Lynes:Sales +2064:Kinza:Roxanna:Farrer:Research +4663:Zackery::Poyntz:Research +1601:Albert:Lukas:Montgomery:Legal +3702:Albert:Lukas:Montgomery:Sales +4730:Nadelle::Landale:Warehousing +4191:Cory:Diljeet:Stockill:Sales +6119:Rhae::Forrester:Sales +4454:Kieara::Milner:Cleaning Services +5502:Taylore:Amellia:Granse:Cleaning Services +7505:Tyra:Deborah:Elting:Research +7506:Tyra:Deborah:Elting:Catering +1183:Bridget:Beverley:Pace:Catering +7337:Nathen::Lemerrie:Customer Service +2462:Ashlee::Hooten:Production +0641:Kelci-Louise::Blakey:Sales +8866:Asir::Cowthwaite:Human Resources +0196:Niven:Cary:Sproule:Warehousing +0199:Niven:Cary:Sproule:Sales +0243:Niven:Cary:Sproule:Legal +4541:Keirien::Blenkinsop:Customer Service diff --git a/src-collections/users2.txt b/src-collections/users2.txt new file mode 100644 index 0000000..b3065fd --- /dev/null +++ b/src-collections/users2.txt @@ -0,0 +1,278 @@ +4760:Samira::Mckellar:Production +3209:Daisy::Cobham:Marketing +0419:Naiya::Emmett:Research +4219:Khailan:Rhyan:Tardiff:Production +5275:Azami:Lilly:Shwenn:Warehousing +1703:Sameeta::Leadbeater:Production +0972:Zamin:Thorfinn:Carden:Warehousing +8036:Maude:Corran:Fairbairn:Climate Change +2095:Kole:Eochaidh:Alwood:Catering +9729:Roisin:Alexsandra:Bissett:Research +5347:Orlaith::Pettitt:Senior Management +4901:Amaar:Burhan:Kaye:Catering +0924:Nekoda::Mcmorran:Sales +5286:Kelsy::Dalzell:Production +0664:Martyna::Clapton:Human Resources +4660:Maninder::Bonnard:Public Relations +9331:Dannica::Willock:Senior Management +2059:Duha::Balderstone:Marketing +8193:Aubrey::Underhill:Human Resources +5027:Keedan::Reddoch:Legal +2004:Kenna::Linsey:Production +1842:Keven::Mcgee:Legal +5604:Josef:Brooke:Martinson:Transport +3894:Kobie::Elsom:Cleaning Services +2253:Khai:Kaira:Yelverton:Production +9837:Enarie:Sharleen:Keys:Senior Management +2570:Robbi:Shaunna:Cecil:Production +3016:Latifatu::Brinnan:Sales +4768:Giselle:Samia-Skye:Girdham:Customer Service +3461:Leighvi:Busra:Frarrer:Warehousing +4159:Dong-Hee::Roson:Sales +6800:Khaliq::Yates:Marketing +8621:Karma::Allison:Customer Service +0847:Rio::Trustram:Legal +2311:Mirrin::Bowstall:Sales +6611:Zarina::Sword:Transport +0149:Fredrick:Jeanie:Spencer:Production +8142:Kallin:Xavier:Ratcliff:Transport +8311:Amy-Louise::Coe:Public Relations +4288:Marek::Mcrae:Production +5956:Eabha::Neelin:Public Relations +7351:Edie::Crow:Public Relations +3025:Billie-Jay::Wingrove:Customer Service +2417:Deborah::Scherger:Production +5859:Mitchell:Donell:Ellerington:Legal +7312:Ailsa:Kianna:Sargesson:Marketing +7282:Lucyanne:Els:Apperson:Legal +6313:Eric::Chaplin:Senior Management +7173:Jaimee-Lee::Calloway:Cleaning Services +7645:Angelo-Carlo::Forrester:Senior Management +5222:Joshua::Matts:Climate Change +7471:Ali::Carradice:Marketing +7155:Nicoline::Eckhold:Sales +1629:Glen::Davies:Sales +1527:Andreas::Morfoot:Research +7908:Oihane:Pearse:Mohr:Public Relations +2921:Ma'az:Sharies:Mann:Cleaning Services +8394:Jay-Alexander:Maia:May:Climate Change +5697:Kian::Sellers:Climate Change +4462:Keryn::Cardno:Cleaning Services +8263:Jarrod::Royal:Cleaning Services +2108:Ayman::Baillie:Sales +8752:Ailis::Calvert:Sales +6299:Haroon::Hindmarsh:Production +9810:Dre::Byrom:Transport +5261:Robbyn::Kropp:Public Relations +1811:Gregor::Knott:Research +8386:Anton::Capes:Production +9486:Alyth::Lisenby:Production +7530:Makayla::Looper:Cleaning Services +0676:Alistair::Gosling:Climate Change +8529:Pia:Alea:Jarvis:Research +5087:Dante::Windham:Production +0743:Mahirah::Ashton:Orders +2654:Niah::Selby:Marketing +9707:Ma-an::Gifford:Senior Management +1278:Kamron::Rohrbach:Climate Change +1506:Tianna::Macfie:Production +5159:Arlene::Behymer:Legal +8208:Anya:Fredrick:Grissom:Cleaning Services +0568:Rubie::Mcgeorge:Legal +5372:David:Rohana:Dalgliesh:Human Resources +9256:Chelsey:Carl:Challenor:Senior Management +2633:Neervana::Annie:Human Resources +9196:Fabrizio::Coombe:Sales +3537:Kirstin::Barret:Orders +5756:Maryann:Anisha:Moodie:Sales +6913:Nurintishar::Cavill:Human Resources +9308:Rehan:Joleen:Brennand:Senior Management +0776:Dawn::Leader:Production +9449:Brendyn:Tiernan:Cummings:Marketing +8985:Brogan:Aisling:Warne:Cleaning Services +9399:Kelsay::Rix:Sales +3021:Ben::Wallace:Customer Service +3928:Primrose:Shelly:Handfield:Human Resources +9942:Arlene::Slater:Cleaning Services +3423:Brendon::Boswell:Marketing +7979:Caitlynn::Bonnetta:Sales +8633:Aydan:Greta:Youll:Production +0703:Jenni::Few:Legal +1081:Gregory::Mell:Legal +8656:Ailee:Bryden:Seabrooke:Sales +9985:Pip:Giulia:Lewie:Climate Change +8469:Fionna::Phipps:Sales +4777:Brogan::Hearn:Sales +2332:Corry::Climo:Sales +0520:Ruqaya:Alexi:Norton:Production +3352:Shiran::Chalifour:Research +9235:Cheuk::Trevannion:Senior Management +1026:Khaliq::Hindley:Sales +9372:Murryn::Mcbride:Production +9379:Nur::Rinn:Cleaning Services +1043:Nya:Hebe:Marnie:Production +0063:Eilis:Jeannie:Macmillan:Sales +5285:Arabella:Samara:Farrer:Transport +1859:Fatemah::Living:Sales +4911:Jin-Hwan:Keris:Carew:Human Resources +0489:Gurpreet::Mulvie:Climate Change +7167:Samad::Whiteside:Marketing +4732:Kian::Emmett:Warehousing +2370:Shatha::Aitkin:Sales +6719:Abbey-Lee:Zakeria:Passmore:Cleaning Services +0851:Abdallah:Krishna:Doherty:Marketing +4073:Harriett::Smorthwaite:Marketing +7195:Kenzi:Stacie-Lee:Greenall:Climate Change +4014:Khadeeja:Madilyn:Malbis:Sales +5837:Reanne:Jaedon:Ellicott:Marketing +2796:Yanis::Hindley:Marketing +6290:Devan::Weidenmeyer:Customer Service +5915:Heather:Aidan:Moorehouse:Climate Change +4626:Lyndsey::Dolling:Transport +6776:Leigh-Ann::Supierz:Public Relations +5043:Jacy::Fryer:Marketing +5681:Jai::Vaill:Marketing +4156:Cameron::Christian:Research +6663:Bronwyn::Rodgerson:Transport +4478:Samanta::Lawrenson:Marketing +8337:Ramsey:Nina:Dimascio:Catering +2402:Julius::Haggar:Climate Change +7010:Tamlynn::Rakestraw:Marketing +2193:Braeden::Hoggins:Sales +0266:Rhea:Ruqaya:Hazelgreave:Climate Change +7106:Rhyce::Lord:Production +8037:Tamunotonye:Yann:Craggs:Cleaning Services +0262:Georgie::Coad:Climate Change +2492:Luisadh:Haigan:Ugill:Sales +2062:Justice::Mathieson:Warehousing +1692:Kailey:Denny:Blain:Sales +2259:Rania:Ciar:Dodwell:Sales +9786:Kristin::Shearer:Production +8874:Rayyan:Anwar:Falhouse:Climate Change +5113:Leland::Kightley:Production +6197:Christina::Dodshon:Climate Change +1012:Ewan::Sergeantson:Research +0827:Lexy::Cramp:Legal +5407:Indi:Alba:Cage:Orders +4645:Farjan::Woodburn:Human Resources +6162:Prabhkaran:Taryn:Garthwaite:Sales +4272:Jaydon:Vincent:Locket:Customer Service +4053:Islam::Krouskup:Senior Management +6110:Keeva::Rumfit:Sales +4234:Amina::Callander:Transport +5680:Julius:Vyctoria:Shepard:Production +3988:Karis:India:Peck:Human Resources +9137:Ross::Godolpin:Legal +3401:Rikki::Plamondon:Climate Change +1853:Elisabeth::Wasling:Human Resources +0475:Roma::Dow:Sales +5998:Elizabeth::Helliwell:Production +1535:Breerah::Mcphail:Customer Service +7156:Nur'Ain::Tighe:Orders +4249:Julius::Jalfon:Warehousing +7817:Kellise:Dania:Whitefield:Sales +6511:Kirstyn:Ayse:Rooke:Research +5505:Heatham::Mcminn:Catering +9695:Vera:Mason:Gidman:Climate Change +2612:Jugjeevan:Declyn:Goldie:Legal +5017:Armin::Connery:Transport +6991:Debbieleigh::Gladwyn:Production +9779:Hawa:Nowaa:Swainbank:Senior Management +5972:Evann::Laird:Marketing +7863:Aleena::Meissner:Orders +6944:Louis::Newbould:Senior Management +0023:Rogan::Rumble:Legal +4887:Tana::Donn:Transport +7499:Ted::Cherry:Senior Management +6742:Jeenan:Clara:Mcnutt:Production +8418:Jonny:Diesel:Elton:Marketing +5520:Samson:Haleema:Senkow:Research +7544:Maryanne:Samuele:Lily:Senior Management +9799:Kole::Scoville:Orders +6271:McLaren::Knapp:Production +4678:Connon::Bottomly:Marketing +4235:Mirza::Whiteside:Senior Management +8958:Shanice:Marilyn:Notman:Transport +8115:Emma::Wennerbom:Production +8963:Michel-Ange:Francesca:Ferrell:Sales +8151:Amaya::Grace:Human Resources +6188:Eve-Rose::Veach:Catering +0716:Kimi::Rorbach:Catering +8776:Lilyjo::Graw:Cleaning Services +8518:Ophelia::Franks:Orders +8906:Bradley::Kelsey:Sales +8733:Aby::Lackland:Orders +0279:Bregan::Blood:Sales +4547:Annabella:Bobi-Lea:Elvy:Marketing +7067:Abrar:Matheullah:Yuile:Sales +6640:Karra:Laseinia:Budden:Sales +7073:Harvey:Haniya:Janssen:Research +1193:Kellise:Mykaela:Kevan:Public Relations +8242:Lowri::Tattersall:Transport +7684:Blane::Thwaits:Production +0926:Tamara:Meadow:Nason:Sales +9304:Karmyn::Farragher:Human Resources +7453:Ossian:Mallory:Dryden:Customer Service +5116:Loreta::Lampkin:Sales +6254:Lara::Baylis:Legal +0600:Wiktoria:Hesle:Helme:Human Resources +0071:Daniela:Marymarie:Halliman:Research +3617:Keigan:Yi-An:Wennerbom:Senior Management +8429:Nicole::Alderson:Sales +9514:Kaylin::Clontz:Production +1664:Baizah::Kilham:Sales +4099:Areeya::Linahon:Human Resources +8801:Vegas::Yelverton:Marketing +9309:Kelly:Waris:Haigh:Research +6531:Kahl::Wyman:Research +6127:Alexzandra:Janica:Bullington:Production +9885:Carrie:Doone:Estes:Production +4386:Julia::Wray:Production +2346:Nell::Cordingly:Production +9539:Quin:Abel:Battaile:Human Resources +7959:Guramrit::Jennison:Production +8000:Braedyn::Buttenshaw:Human Resources +0256:Akamveer::Bellard:Sales +6769:Kirstyn::Archer:Sales +0900:Reen:Oakley:Spurlock:Cleaning Services +6427:Gretchen::Webber:Catering +2432:Aliana::Learmont:Warehousing +8232:Seth::Curwen:Cleaning Services +5422:Erona::Wortham:Transport +0267:Faheez::Lupo:Transport +9205:Bailee:Layna:Julia:Cleaning Services +3862:Alexander-Bruce:Jami:Solley:Customer Service +9230:Paris-Nicole::Smorthwaite:Orders +6813:Allana::Sisley:Climate Change +9521:Liza::Shap:Research +3473:Rebbeca::Farmarie:Research +6893:Ellie-May::Mcmurdo:Research +6880:Joela:Lila:Killigrew:Production +7460:Tammy::Waind:Marketing +9978:Davydas:Julian:Waggoners:Catering +6549:Rianne::Elson:Sales +2939:Eesa:McCody:Duncan:Production +6195:Josey::Bunn:Sales +4579:Nikolaus::Sherwin:Production +9472:Suhayb::Cottingham:Research +9946:Duha::Criswick:Production +4557:Lennan:Musammath:Selby:Production +9785:Deuie:Harvey-Lee:Lawrence:Sales +3097:Yousf:Glet:Capes:Marketing +2312:Katrina::Florack:Human Resources +5695:Kasey::Macpherson:Sales +3023:Tawhid::Tyldesley:Marketing +9894:Omolara::Whitehouse:Senior Management +0833:Khaled::Plats:Orders +8817:Gurkeerat::Hargreaves:Marketing +2903:Rumsha::Kay:Sales +7066:Jay-D::Copland:Sales +1484:Arun:Orchid:Caton:Marketing +8730:Errin::Dodwell:Climate Change +4716:Gerrard::Cautherey:Sales +9097:Madysan::Cawley:Public Relations +7803:Kareem::Moffit:Sales +3010:Jayne-Marie:Baban:Lyster:Research +4669:Iman::Spicer:Sales +0021:Justin::Radclyffe:Sales +8959:Siddharth::Gunn:Production diff --git a/src-datatype/sample.csv.txt b/src-datatype/sample.csv.txt new file mode 100644 index 0000000..3ad115c --- /dev/null +++ b/src-datatype/sample.csv.txt @@ -0,0 +1,5 @@ +"COUNTRY",2000,2001,2002,2003,2004 +"ANTIGUA AND BARBUDA",0,0,0,0,0 +"ARGENTINA",37,35,33,36,39 +"BAHAMAS, THE",1,1,1,1,1 +"BAHRAIN",5,6,6,6,6 diff --git a/src-intro/.ipynb_checkpoints/fib-checkpoint.py b/src-intro/.ipynb_checkpoints/fib-checkpoint.py new file mode 100644 index 0000000..7bcae89 --- /dev/null +++ b/src-intro/.ipynb_checkpoints/fib-checkpoint.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +def fib(n): + """ + Возвращает список первых n чисел Фибоначи + """ + f0, f1 = 0, 1 + f = [1]*n + for i in range(1, n): + f[i] = f0 + f1 + f0, f1 = f1, f[i] + + return f + +print(fib(10)) diff --git a/src-intro/.ipynb_checkpoints/hello-checkpoint.py b/src-intro/.ipynb_checkpoints/hello-checkpoint.py new file mode 100644 index 0000000..7243d25 --- /dev/null +++ b/src-intro/.ipynb_checkpoints/hello-checkpoint.py @@ -0,0 +1 @@ +print("Hello from Python!") diff --git a/src-intro/.ipynb_checkpoints/test-checkpoint.py b/src-intro/.ipynb_checkpoints/test-checkpoint.py new file mode 100644 index 0000000..073a381 --- /dev/null +++ b/src-intro/.ipynb_checkpoints/test-checkpoint.py @@ -0,0 +1,2 @@ +a = int(input()) +print(a**2+a) diff --git a/src-intro/test.py b/src-intro/test.py index ecca88f..073a381 100644 --- a/src-intro/test.py +++ b/src-intro/test.py @@ -1,2 +1,2 @@ a = int(input()) -print(a**2) +print(a**2+a)