{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "# 数字の出現数を数える\n",
    "## プログラムの概要\n",
    "あるシステムが生成する認証コードは6桁の整数です。このコードに現れる各桁の数字(Digit)の分布がどの程度一様なのかを調べます。\n",
    "実際に生成されたコードの一覧から、各桁の数字に分解して頻度を数えます。\n",
    "まずは生成されたcodeの一覧を変数`codes`に割り当てます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "#!python3\n",
    "#-*- coding:utf-8 -*-\n",
    "# '#'以降は行末までがコメントになります。（プログラムとしては実行されない）\n",
    "nlen=6 # コードの桁数は6桁\n",
    "codes=(\n",
    "    227524,    463251,    702567,    601620,\n",
    "    129458,    413239,    629380,    526093,\n",
    "    261547,    666552,    853626,    513298,\n",
    "    142167,    612906,    995697,    660500,\n",
    "    954404,    651454,    566439,    730975,\n",
    "    578967,    603424,    435636,    891667,\n",
    "    757294,    325567,    131075,    757309, \n",
    "    198547\n",
    "    # 012345 のように0から始まるcodeは, 0を省いて書くことにします。\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "source": [
    "次に一つの code の各桁に現れる数字の出現回数を数えます。\n",
    "一番下の桁から順番にみていきます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def count_digits(code,nlen=6): #　関数　`count_digits`を定義します。\n",
    "    # 最大二つの引数を持ちますが、二つ目の引数`nlen`は省略可能で、\n",
    "    # 省略された場合の値(既定値)は6です。\n",
    "    acc={} #これに数字毎の出現回数を入れていきます。\n",
    "    code=code+10**nlen # 最上位が0の場合を取り扱うために、10**nlenを足しておく。\n",
    "    # code =227524 であれば　code=1227524とするということ。\n",
    "    while code>=10:\n",
    "        code, d=divmod(code, 10) #商 `code` と余り `d` に分解します。\n",
    "        # code=1227524　=> code=122752,d=4\n",
    "        acc[d]=acc.get(d,0)+1 \n",
    "        # accのkeyにdがあればその値に1を足したもの、さもなければ 0+1をacc[d]に設定する。\n",
    "    return acc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "source": [
    "一覧表`codes`の全ての`code`に現れる数字に頻度を数えて、足していきます。\n",
    "結果の度数分布表`acc`を関数の値として返します。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def count_digits_in_list(codes,nlen):\n",
    "    acc={}\n",
    "    for code in codes: #codesの中に入っている全てのcodeについて\n",
    "        count=count_digits(code,nlen) #コードの中の数字の出現表を作る。\n",
    "        for d in count: #codeでの数字の出現数をaccに足して行く。\n",
    "            acc[d]=acc.get(d,0)+count[d]\n",
    "    return acc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "source": [
    "`codes`の中の数字の度数分表を印刷し、ヒストグラムを表示させてみます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as pyplot #グラフ作成の準備のおまじない\n",
    "import numpy\n",
    "\n",
    "def main():\n",
    "    counts=count_digits_in_list(codes,nlen) #codeの一覧codesから数字の出現数の表を作成する。\n",
    "    print(\"digit:  count\")# 印刷する表のラベルを印刷する。\n",
    "    for d in sorted(counts): # 出現表にあらわれる数字を整列させた順番に、\n",
    "        print (d,\":\",counts[d]) # 数字(d)とその出現数(count[d])を印刷する。\n",
    "    # print(\"average:\",len(codes)*nlen/10) #数字の出現数の平均値を印刷する。\n",
    "    print(\"average:\", sum(counts.values())/len(counts)) # 6*len(codes)/10\n",
    "    print(\"std. dev:{:4.1f}\".format(numpy.std(list(counts.values()))))\n",
    "    pyplot.bar(counts.keys(),counts.values()) # barグラフを印刷する。\n",
    "    pyplot.draw() #グラフ作成のおまじない\n",
    "    #pyplot.show() #グラフ作成の最後のおまじない. Jupyter Notebookでは不要\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "digit:  count\n",
      "0 : 14\n",
      "1 : 14\n",
      "2 : 19\n",
      "3 : 15\n",
      "4 : 17\n",
      "5 : 25\n",
      "6 : 28\n",
      "7 : 18\n",
      "8 : 7\n",
      "9 : 17\n",
      "average: 17.4\n",
      "std. dev: 5.6\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "if __name__ == \"__main__\":\n",
    "    main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "## pandas/DataFrame\n",
    "Data Analysis分野で最近よく使われるDataFrameオブジェクトを使うと、\n",
    "短いプログラムでデータのリストから度数分表を取出し、またヒストグラムを表示させることができる。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import pandas\n",
    "\n",
    "def split_digits(code,nlen=6):\n",
    "    acc=[] # あらわれた数字を順番に保存する。\n",
    "    code=code+10**nlen # 最上位が0の場合を取り扱うため\n",
    "    while code>=10:\n",
    "        code,d=divmod(code,10)\n",
    "        acc.insert(0,d)\n",
    "    return acc\n",
    "\n",
    "def split_codes():\n",
    "    acc=[]\n",
    "    for code in codes:\n",
    "        acc +=split_digits(code)\n",
    "    return acc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    14\n",
      "1    14\n",
      "2    19\n",
      "3    15\n",
      "4    17\n",
      "5    25\n",
      "6    28\n",
      "7    18\n",
      "8     7\n",
      "9    17\n",
      "dtype: int64\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<AxesSubplot:xlabel='0'>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAAEOCAYAAACQMUyOAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/Z1A+gAAAACXBIWXMAAAsTAAALEwEAmpwYAAAQLElEQVR4nO3dfYxldX3H8fcHdtVYbQV3wBV2u8RQI42P3awafEKkRUkKpA2VVMRgXZOWVhJNuvEfbUjN2taHmLS2UIhrSjXWR1qoQqmWGB/KAisuIIJ2VbYLu0QsVLQKfPvHPdsdpjM7d+feOXN+7PuVTObec87c89l77n7mzO+ce26qCklSe45Y6QCSpKWxwCWpURa4JDXKApekRlngktQoC1ySGrWqz5WtWbOmNmzY0OcqJal5N954431VNTN3eq8FvmHDBrZv397nKiWpeUm+N990h1AkqVEWuCQ1ygKXpEZZ4JLUKAtckhplgUtSoyxwSWqUBS5Jjer1jTySJrNhy1UTP8aurWdMIYmGwD1wSWqUBS5JjbLAJalRFrgkNcoCl6RGWeCS1CgLXJIaZYFLUqMscElqlAUuSY2ywCWpURa4JDXKApekRlngktQoC1ySGmWBS1KjLHBJapQFLkmNWrTAk6xL8sUktyW5NcnbuunvTrI7yY7u63XLH1eStN84n4n5MPD2qropyVOBG5Nc2837QFX9xfLFkyQtZNECr6o9wJ7u9oNJbgeOW+5gkqSDO6Qx8CQbgBcCX+8mXZjkliSXJzlq2uEkSQsbZwgFgCRPAT4FXFRVDyT5MHAxUN339wEXzPNzm4HNAOvXr59GZmlFbNhy1UQ/v2vrGVNKIo2MtQeeZDWj8r6iqj4NUFX3VtUjVfUocCmwab6frapLqmpjVW2cmZmZVm5JOuyNcxZKgMuA26vq/bOmr5212NnAzunHkyQtZJwhlJOB84BvJtnRTXsncG6SFzAaQtkFvHUZ8kmSFjDOWShfBjLPrKunH0eSNC7fiSlJjbLAJalRFrgkNcoCl6RGWeCS1CgLXJIaZYFLUqMscElqlAUuSY2ywCWpURa4JDXKApekRlngktQoC1ySGmWBS1KjLHBJapQFLkmNssAlqVEWuCQ1ygKXpEZZ4JLUKAtckhplgUtSoyxwSWqUBS5JjbLAJalRFrgkNcoCl6RGLVrgSdYl+WKS25LcmuRt3fSjk1yb5M7u+1HLH1eStN84e+APA2+vqpOAlwB/kOQkYAtwXVWdCFzX3Zck9WTRAq+qPVV1U3f7QeB24DjgTGBbt9g24KxlyihJmschjYEn2QC8EPg6cGxV7elm3QMcO91okqSDGbvAkzwF+BRwUVU9MHteVRVQC/zc5iTbk2zft2/fRGElSQeMVeBJVjMq7yuq6tPd5HuTrO3mrwX2zvezVXVJVW2sqo0zMzPTyCxJYryzUAJcBtxeVe+fNetK4Pzu9vnA56YfT5K0kFVjLHMycB7wzSQ7umnvBLYCn0jyZuB7wDnLklCSNK9FC7yqvgxkgdmnTjeOJGlcvhNTkhplgUtSo8YZA9cK2LDlqokfY9fWM6aQRNJQuQcuSY2ywCWpURa4JDXKApekRlngktQoC1ySGuVphJIO2aSnuXqK63S4By5JjbLAJalRFrgkNcoCl6RGWeCS1CgLXJIaZYFLUqM8D1yD56V1NWQreU68e+CS1CgLXJIaZYFLUqMscElqlAUuSY2ywCWpURa4JDXKApekRlngktQoC1ySGrVogSe5PMneJDtnTXt3kt1JdnRfr1vemJKkucbZA/8IcPo80z9QVS/ovq6ebixJ0mIWLfCquh74YQ9ZJEmHYJIx8AuT3NINsRw1tUSSpLEs9XKyHwYuBqr7/j7ggvkWTLIZ2Aywfv36Ja5OK8VLuUrDtaQ98Kq6t6oeqapHgUuBTQdZ9pKq2lhVG2dmZpaaU5I0x5IKPMnaWXfPBnYutKwkaXksOoSS5GPAq4A1Se4G3gW8KskLGA2h7ALeunwRJUnzWbTAq+rceSZftgxZJEmHwHdiSlKjLHBJatSgPpV+KKesDSWHJB2Me+CS1CgLXJIaZYFLUqMscElqlAUuSY2ywCWpURa4JDXKApekRlngktQoC1ySGmWBS1KjLHBJapQFLkmNssAlqVEWuCQ1ygKXpEZZ4JLUKAtckhplgUtSoyxwSWqUBS5JjbLAJalRFrgkNcoCl6RGWeCS1KhFCzzJ5Un2Jtk5a9rRSa5Ncmf3/ajljSlJmmucPfCPAKfPmbYFuK6qTgSu6+5Lknq0aIFX1fXAD+dMPhPY1t3eBpw13ViSpMUsdQz82Kra092+Bzh2SnkkSWOa+CBmVRVQC81PsjnJ9iTb9+3bN+nqJEmdpRb4vUnWAnTf9y60YFVdUlUbq2rjzMzMElcnSZprqQV+JXB+d/t84HPTiSNJGtc4pxF+DPgq8Owkdyd5M7AVOC3JncBruvuSpB6tWmyBqjp3gVmnTjmLJOkQ+E5MSWqUBS5JjbLAJalRFrgkNcoCl6RGWeCS1CgLXJIaZYFLUqMscElqlAUuSY2ywCWpURa4JDXKApekRlngktQoC1ySGmWBS1KjLHBJatSin8gjSUO0YctVEz/Grq1nTCHJynEPXJIaZYFLUqMscElqlAUuSY2ywCWpURa4JDXKApekRlngktQoC1ySGmWBS1KjJnorfZJdwIPAI8DDVbVxGqEkSYubxrVQTqmq+6bwOJKkQ+AQiiQ1atICL+CaJDcm2TyNQJKk8Uw6hPKyqtqd5Bjg2iTfqqrrZy/QFftmgPXr10+4OknSfhPtgVfV7u77XuAzwKZ5lrmkqjZW1caZmZlJVidJmmXJBZ7kF5I8df9t4NeBndMKJkk6uEmGUI4FPpNk/+P8fVV9fiqpJEmLWnKBV9V3gedPMYsk6RB4GqEkNcoCl6RGWeCS1CgLXJIaZYFLUqMscElqlAUuSY2ywCWpURa4JDXKApekRlngktQoC1ySGmWBS1KjLHBJapQFLkmNssAlqVEWuCQ1ygKXpEZZ4JLUKAtckhplgUtSoyxwSWqUBS5JjbLAJalRFrgkNcoCl6RGWeCS1CgLXJIaNVGBJzk9yR1J7kqyZVqhJEmLW3KBJzkS+EvgtcBJwLlJTppWMEnSwU2yB74JuKuqvltVPwM+Dpw5nViSpMVMUuDHAT+Ydf/ubpokqQepqqX9YPLbwOlV9Xvd/fOAF1fVhXOW2wxs7u4+G7hj6XEBWAPcN+FjTGoIGWAYOYaQAYaRYwgZYBg5hpABhpFjGhl+uapm5k5cNcED7gbWzbp/fDftMarqEuCSCdbzGEm2V9XGaT1eqxmGkmMIGYaSYwgZhpJjCBmGkmM5M0wyhHIDcGKSE5I8AXg9cOV0YkmSFrPkPfCqejjJhcAXgCOBy6vq1qklkyQd1CRDKFTV1cDVU8oyrqkNx0xgCBlgGDmGkAGGkWMIGWAYOYaQAYaRY9kyLPkgpiRpZflWeklqlAUuSY2ywCWpURMdxOxLkiOA5wPPBH4C7KyqvSuQ4xjg5Nk5gO1V9ejhlKHLseLbZCAZhrI9VjzHEDJ0OQ6b18WgD2ImeRbwx8BrgDuBfcCTgF8BHgL+Bti23C+QJKcAW4CjgZuBvbNyPAv4JPC+qnrg8Zyhy7Hi22QgGYayPVY8xxAydDkOv9dFVQ32C/gY8Aq6XzRz5h0DXASc30OOPwfWLzBvFXAW8FuP9wxD2SYDyTCU7bHiOYaQ4XB9XQx6D1yStLAmD2Im2ZjkmQPIcWaSFx/uGbocK75NBpJhKNtjxXMMIUOX43H7umjiIOY8/hB4XpJvV9XvrGCOFwPPTbKqql57GGeAYWyTIWQYyvYYQo4hZIDH8eui6SGUJE+tqgdXOocOGMI2GUIGDc/j8XUx+AJP8kvA6Rz4sIjdwBeq6kcrFmqWJKdV1bU9resXgZmq+s6c6c+rqlv6yNCt7xkAVXVPkhng5cAdtYIXM0vynqp65wqu/wTghcBtVfWtHte7HthbVT9NEuBNwIuA24BLq+rhHjL8JnBNVf10udc1RpZXAPdW1R1JTgZeCtxeVVf1mOEpjDprHfAI8G1Gz8/Uz34ZdIEneSPwLuAaDlxr/HjgNOBPquqjK5VtvyTfr6r1PaznHOCDjE5LWg28qapu6ObdVFUvWu4M3breyug0qQDvZVQYO4GXAX9WVZf1kOFDcycB5wEfBaiqP+ohw2er6qzu9pmMts2XGJ37+56q+shyZ+jWvRPYVFUPJXkvo1PVPgu8GqCqLughw0+AHwP/zOhMkC9U1SPLvd55cnyQ0Uc9rmJ0ldRTu0yvBHZU1Tt6yHAO8A7gFuAU4CuMjjU+F3jD1He0lvvUnglPybkDeNo8048Cvt1jjisX+PpH4Mc9ZdgBrO1ubwK+BZzd3b+5x+fim8CTgacD/w08Y9Y22dFThh8Afwe8ETi/+9q3/3ZPGW6edfsrwAnd7TXAN3rcHrfNun0jcMSs+73kYHS+81HAW4DrgHuBvwZe2dfz0OW4ldEv8ycD9wNP7qavZvRmnj4y3DJrvWsY/TIDeB7wlWmvb+gHMQPM9yfCo928vrwceAOjwpotjMq0D0dW1R6Aqvr37g0D/5RkHfM/R8vl51X1EPBQku9U1T1dpvuT9JXjJOBiRn+mvqOq/jPJu6pqW0/rh8c+56uq6j8Aquq+JH2+8/AHSV5dVf8K7GL0Z/v3kjy9xwxVVfcDlwKXdkNs5wBbkxxfVesO/uNTzVGznv/92+hR+jvjLozeeQmjv0qO6YLd0g2BTtXQC/xPgZuSXMOBD1Bez2gI5eIec3wNeKiq/m3ujCSTfsbnuB5M8qzqxr+rak+SVzH6c/lXe8oAUElWV9XPgTP2T0zyJHr6T1KjA1EXJfk14IokV/W17lmen+QBRv9hn5hkbbdNnsDoA0768hZgW5J3A/8F7EiyA3ga8PaeMjxmZ6r7pf4h4ENJfrmnDABXJ/ky8ETgb4FPJPkaoyGU6/vKAHw+yfWMdjD+ASDJ0SzDTufQx8DD6IX4G/z/g5j371+mlvkfMc46ljtHkhcBD1TVXXOmrwbOqaorenou1gF7as7BsSTHAc+pqn/p4bn4v8fvXiO/D7y0qt4w3zLLlOGImuegVJKnMXoevtrnazPJcxi9XXsVcDdww/58PTwXp1TVF8fJuVwZ9q8DeAmjPfGvZfTW+rOB7wOfrKpH+3htAq9l9FfiN6o7wSGj67Osrqr/mWqGPsaFJhhP+hKjczjXz5n+BEYHabYxOpj3uM+xSIZTB/Jc9JKjge3ha9PnopcMQ98DfxJwAfC7wAnAjxhdGOZIRmem/FVV3Xw45BhChqHkMMOwcgwhw1By9J1h0AU+WzdUsAb4Sa3gOeBDyDGEDEPJYYZh5RhChqHk6CNDMwUuSXqsJi9mJUmywCWpWRa4DntJTk9yR5K7kmxZ6TzSuBwD12EtyZGMLjZ0Gt3508C5VXXbigaTxuAeuA53m4C7quq7VfUz4OPAmSucSRqLBa7D3XEcuEwDjPbCj1tgWWlQLHBJapQFrsPdbkZX8NvveA5ce14aNAtch7sbgBOTnNBdSfD1jK71Lg3e0C8nKy2rqno4yYWMPsHlSODyWsGPhpMOhacRSlKjHEKRpEZZ4JLUKAtckhplgUtSoyxwSWqUBS5JjbLAJalRFrgkNep/AcexErYN7wpOAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "df=pandas.DataFrame(split_codes()).value_counts(sort=False)\n",
    "print(df)\n",
    "df.plot.bar()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "## matplotlib.pyplot\n",
    "\n",
    "matplotlib.pyplotを使って、ヒストグラムの表示と度数分布を求めることも可能です。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "counts, digits, chart = pyplot.hist(\n",
    "    split_codes(), \n",
    "    bins=range(0,11)\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(0, 14.0)\n",
      "(1, 14.0)\n",
      "(2, 19.0)\n",
      "(3, 15.0)\n",
      "(4, 17.0)\n",
      "(5, 25.0)\n",
      "(6, 28.0)\n",
      "(7, 18.0)\n",
      "(8, 7.0)\n",
      "(9, 17.0)\n"
     ]
    }
   ],
   "source": [
    "for p in (zip(digits,counts)): print(p)"
   ]
  }
 ],
 "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.9.2"
  },
  "toc-autonumbering": true,
  "toc-showcode": false,
  "toc-showmarkdowntxt": true,
  "toc-showtags": false
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
