ガイカーカウンター GM-10 のPythonプログラム

なぜか部屋にガイカーカウンターが落ちていて、遙か昔にプログラムを書いていたようで、せっかくなので置いておく。 みたところ、matplotlibでプロットするプログラムになっているようだ。

import datetime

import serial

import matplotlib.pyplot as plt

import pandas as pd

ser = serial.Serial('/dev/tty.usbserial-FTSBTSEU', baudrate=38400, dsrdtr=True)
ser.read(2)

df = pd.DataFrame(columns=['time', 'count'])
df = df.set_index('time')
plt.ion()
fig, ax = plt.subplots()
while True:
    # measure
    ser.read(1)
    t = datetime.datetime.now()
    df.loc[t] = 1

    # aggs
    df_minutely = df.resample('1min').sum()

    # plot
    plt.cla()
    ax.set_title('RadiationCount - Geiger Counter Black Cat Systems GM-10')
    ax.set_xlabel('Time')
    ax.set_ylabel('Count')
    ax.set_ylim(0, df_minutely['count'].max()+1)
    df_minutely.plot(y='count', ax=ax)
    ax.plot_date(df_minutely.index.to_pydatetime(), df_minutely)
    plt.draw()
    plt.pause(0.1)

ser.close()

食べログで指定した地点の近くの飲食店の一覧を取得する

会社の近くの飯屋をピックアップしたかったので。

import click

import scipy.optimize

import geopy.distance

import requests

import xml.etree.ElementTree as ET


def listup(lat, lon, radius_km):
    maxlat = scipy.optimize.bisect(lambda x: geopy.distance.distance((lat, lon), (x, lon)).km - radius_km, lat, 90)
    minlat = scipy.optimize.bisect(lambda x: geopy.distance.distance((lat, lon), (x, lon)).km - radius_km, -90, lat)
    maxlon = scipy.optimize.bisect(lambda x: geopy.distance.distance((lat, lon), (lat, x)).km - radius_km, lon, 180)
    minlon = scipy.optimize.bisect(lambda x: geopy.distance.distance((lat, lon), (lat, x)).km - radius_km, 0, lon)
    print(maxlat, minlat, maxlon, minlon)

    lst = 100
    params = {
        'maxLat': maxlat,
        'minLat': minlat,
        'maxLon': maxlon,
        'minLon': minlon,
        'lst': lst,
        'SrtT': 'trend',
    }

    pg = 1
    cnt = 9999
    rst_list = []
    while lst * (pg - 1) < cnt:
        params['pg'] = pg
        r = requests.get('https://tabelog.com/xml/rstmap', params=params)
        root = ET.fromstring(r.text)
        if pg == 1:
            cnt = int(root.find('srchinfo').attrib['cnt'])
        print('{:d} / {:d}'.format(min(cnt, lst * pg), cnt))
        for marker in root.findall('marker'):
            rst_list.append(marker.attrib)
        pg += 1

    return rst_list


@click.command
@click.argument('latitude', type=float)
@click.argument('longitude', type=float)
@click.option('--radius-km', type=float, default=0.5)
@click.option('--sort-by-score', is_flag=True)
def main(latitude, longitude, radius_km, sort_by_score):
    rst_list = listup(latitude, longitude, radius_km)
    if sort_by_score:
        rst_list = sorted(rst_list, key=lambda x: x['score'], reverse=True)
    for (i, rst) in enumerate(rst_list):
        print(rst['rstname'], end=' ')
        print('https://tabelog.com' + rst['rsturl'], end=' ')
        print(rst['rstcat'], end=' ')
        print(rst['holiday'], end=' ')
        print(rst['score'], end=' ')
        print('https://www.google.co.jp/maps?q={},{}'.format(rst['lat'], rst['lng']), end=' ')
        print()


if __name__ == '__main__':
    main()

こんな感じで動く。

$ python tabelog.py 35.697011 139.682878 --radius-km 0.1 --sort-by-score | head -n 10
華吉 https://tabelog.com/tokyo/A1319/A131903/13040836/ 中華料理、餃子 日曜日 3.55 https://www.google.co.jp/maps?q=35.69677753867941,139.6825075846003
カフェ デ カリー https://tabelog.com/tokyo/A1319/A131903/13130776/ カレー、カフェ 日曜日 3.50 https://www.google.co.jp/maps?q=35.697083182016286,139.68391515140476
ハイランダー イン トウキョウ https://tabelog.com/tokyo/A1319/A131903/13093730/ バー、パブ、ヨーロッパ料理 無し 3.44 https://www.google.co.jp/maps?q=35.697413738679,139.68246788460678
トリッペリア トリッパ https://tabelog.com/tokyo/A1319/A131903/13129637/ イタリアン、ワインバー 日 3.41 https://www.google.co.jp/maps?q=35.696570638679795,139.68326538459766
すし割烹悠水 https://tabelog.com/tokyo/A1319/A131903/13070320/ 海鮮、寿司、居酒屋 日曜日 3.38 https://www.google.co.jp/maps?q=35.6975662386793,139.68367858460743
坂上刀削麺 https://tabelog.com/tokyo/A1319/A131903/13188505/ 中華料理、刀削麺、居酒屋 無し(ビル休館日に準ずる) 3.38 https://www.google.co.jp/maps?q=35.697492738678896,139.68230588460767
麺家 たいせい https://tabelog.com/tokyo/A1319/A131903/13282456/ ラーメン なし 3.32 https://www.google.co.jp/maps?q=35.69720583867907,139.6822479846048
六味膳食 https://tabelog.com/tokyo/A1319/A131903/13161291/ 居酒屋、創作料理 日・祝日 (ご宴会予約のみやっています) 3.25 https://www.google.co.jp/maps?q=35.69620813868004,139.683320584594

ソーラーオフで最もコスパの高い太陽光パネルを探す

  1. requestsとbs4をインストール
$ pip install requests
$ pip install beautifulsoup4
  1. コードを書く
import requests
from bs4 import BeautifulSoup

import re

import pandas as pd


def parse_solaroff(url):
    soup = BeautifulSoup(requests.get(url).text, 'html.parser')

    records = []
    for li in soup.select('.category-list li'):
        if not li.select_one('.price'):
            continue

        url = 'https://www.solar-off.com/' + li.select_one('.name').select_one('a').get('href')

        title = li.select_one('.name').get_text()
        m = re.match('【([^0-9]+)([0-9]+)W( (.*)発電)?】(.*)( | )太陽光パネル( | )([a-zA-Z0-9-]+)', title)
        material = m.group(1) if m else None
        power = float(m.group(2)) if m else None
        face = (m.group(4) or '片面') if m else None
        manufacture = m.group(5) if m else None
        model = m.group(8) if m else None

        price = li.select_one('.price').get_text()
        m = re.match('([0-9,]+)円\\(税込\\)', price)
        price = float(m.group(1).replace(',', '')) if m else None

        records.append({
            'url': url,
            'title': title,
            'material': material,
            'power': power,
            'face': face,
            'manufacture': manufacture,
            'model': model,
            'price': price,
        })
    return records


if __name__ == '__main__':
    records = []
    url = "https://www.solar-off.com/shopbrand/solarpanel/"
    records += parse_solaroff(url)
    url = "https://www.solar-off.com/shopbrand/solarpanel/page2/recommend/"
    records += parse_solaroff(url)

    df = pd.DataFrame(records)
    df = df.dropna()

    df['コスパ'] = df['price'] / df['power']
    df.to_excel('output.xlsx')
  1. 実行する
$ python solar-off.py
$ open output.xlsx
  1. 見る

  2. これがW単価49.5円で最安だった。注文50枚からだったけど。

www.solar-off.com

Google Mapの履歴から勤怠を生成する

1 https://takeout.google.com/settings/takeout/custom/location_history からzipをダウンロード

2 zipを展開

$ unzip takeout-20220405T052057Z-001.zip

3 jqで抜く

$ cat Takeout/ロケーション履歴/Semantic\ Location\ History/2022/2022_MARCH.json | jq -r '
    .timelineObjects[].placeVisit |
    select(.) |
    {n: .location.name, s: .duration.startTimestamp, e: .duration.endTimestamp} |
    .s |= (.|sub("(?<time>.*)\\.[\\d]{3}(?<tz>.*)"; "\(.time)\(.tz)")|fromdate|.+32400|todate) |
    .e |= (.|sub("(?<time>.*)\\.[\\d]{3}(?<tz>.*)"; "\(.time)\(.tz)")|fromdate|.+32400|todate) |
    [.s, .e, .n] |
    @csv' | grep '会社名'

"2022-03-12T09:59:34Z","2022-03-12T17:34:38Z","会社名"
"2022-03-23T09:42:07Z","2022-03-23T17:23:33Z","会社名"
"2022-03-31T10:03:57Z","2022-03-31T20:30:25Z","会社名"

ヨシ!

今年やってみたいこと 100個

  1. エポスカードプラチナ契約
  2. コンシェルジュサービスで宿予約
  3. コンシェルジュサービスで店予約
  4. ダイエット 69kg
  5. ダイエット 68kg
  6. ダイエット 67kg
  7. ダイエット 66kg
  8. ダイエット 65kg
  9. ダイエット 64kg
  10. ダイエット 63kg
  11. アンテナ取り付け
  12. ダウンキャビネット取り付け
  13. スクロールカーテン取り付け
  14. Python pylint
  15. Python asyncio
  16. Python geopy/geopy - ジオコーディング
  17. Python Textualize/rich - ターミナルリッチテキスト
  18. Python brython-dev/brython - クライアントサイドPython
  19. Python kevin1024/vcrpy - VCR(WebAPI Mock)テスト
  20. Python lucidrains/big-sleep - テキストtoイメージ
  21. Python tiangolo/fastapi
  22. Python pypa/pipenv
  23. Python google/budoux
  24. Python google/atheris
  25. Python kivy/kivy
  26. OSS home-assistant/core
  27. OSS google-github-actions
  28. OSS Ansible Molecule
  29. OSS Redash
  30. OSS Metabase
  31. サービス Sentry
  32. サービス Streamlit
  33. サービス カーシェア
  34. サービス タイムチケット
  35. サービス PowerBI
  36. サービス Power Automate
  37. サービス AWS Athena
  38. サービス AWS SQS
  39. サービス MDM
  40. 本「SAML入門」
  41. 本「輪より詭弁」
  42. 本「システム障害対応の教科書」
  43. 本「間違いだらけの設計レビュー」
  44. 本「V時回復の経営」
  45. 本「ゼロからのOS自作入門」
  46. 本「7つの週間」
  47. 本「How Google Works」
  48. 本「もしマネ」
  49. 本「仮設効果検証入門」
  50. 本「月の光」
  51. 本「料理の四面体」
  52. 本「日本電力戦争」
  53. 本「興亡――電力をめぐる政治と経済」
  54. 本「電力システム改革の突破口 DR・VPP・アグリゲーター入門」
  55. 本「仕事ではじめる機械学習
  56. 本「実践Django Pythonによる本格Webアプリケーション開発」
  57. 本「Pythonではじめる数理最適化 」
  58. アニメ「僕のヒーローアカデミア
  59. アニメ「Akira
  60. アニメ「鬼滅の刃
  61. 安全・機械 資格 消防設備士 乙1類
  62. 安全・機械 資格 消防設備士 乙2類
  63. 安全・機械 資格 消防設備士 乙3類
  64. 安全・機械 資格 消防設備士 乙4類
  65. 安全・機械 資格 消防設備士 乙5類
  66. 安全・機械 資格 消防設備士 乙6類
  67. 安全・機械 資格 消防設備士 乙7類
  68. 安全・機械 資格 危険物取扱者 乙1類
  69. 安全・機械 資格 危険物取扱者 乙2類
  70. 安全・機械 資格 危険物取扱者 乙3類
  71. 安全・機械 資格 危険物取扱者 乙5類
  72. 安全・機械 資格 危険物取扱者 乙6類
  73. 安全・機械 資格 第3種冷凍機械責任者
  74. 安全・機械 資格 公害防止管理者
  75. 安全・機械 資格 衛生管理者
  76. 安全・機械 資格 ボイラー技士
  77. 安全・機械 資格 劇物取扱者
  78. 安全・機械 資格 火薬取扱者
  79. 電気・通信 資格 工事担当者 第2級デジタル通信
  80. 電気・通信 資格 電気通信主任技術者
  81. 電気・通信 資格 応用情報技術者
  82. 電気・通信 資格 陸特三種
  83. 電気・通信 資格 エネルギー管理士
  84. 資格 CCNA
  85. 資格 LPIC
  86. 資格 PMP
  87. AWS 資格 Cloud Practitioner
  88. AWS 資格 Solution Architect - Associate
  89. AWS 資格 SysOps Administrator - Associate
  90. AWS 資格 Developper - Associate
  91. AWS 資格 Solution Architect - Professional
  92. AWS 資格 DevOps Engineer Professional
  93. AWS 資格 Security Specialty
  94. AWS 資格 Database Specialty
  95. AWS 資格 Machine Learning Specialty
  96. AWS 資格 Data Analytics Specialty
  97. AWS 資格 Advanced Networking Specialty
  98. 検査 MYCODE
  99. 検査 WAIS-III
  100. 検査 アレルギー検査

pip install tablesでerror: implicit declaration of function 'H5close' is invalid in C99 [-Werror,-Wimplicit-function-declaration]

こんなエラーが出る。hdf5が無いらしい。

$ pip install tables
Collecting tables
  Using cached tables-3.6.1.tar.gz (4.6 MB)
    ERROR: Command errored out with exit status 1:
     command: /Users/taisyo/.pyenv/versions/3.9-dev/bin/python3.9 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-install-ovh_8boi/tables/setup.py'"'"'; __file__='"'"'/private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-install-ovh_8boi/tables/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-pip-egg-info-n71yibiu
         cwd: /private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-install-ovh_8boi/tables/
    Complete output (11 lines):
    /var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/H5closee3bba902.c:2:5: error: implicit declaration of function 'H5close' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        H5close();
        ^
    1 error generated.
    cpuinfo failed, assuming no CPU features: py-cpuinfo currently only works on X86 and some PPC and ARM CPUs.
    * Using Python 3.9.2+ (heads/3.9:2c0a0b0, Mar  8 2021, 14:56:53)
    * USE_PKGCONFIG: True
    .. ERROR:: Could not find a local HDF5 installation.
       You may need to explicitly state where your local HDF5 headers and
       library can be found by setting the ``HDF5_DIR`` environment
       variable or by using the ``--hdf5`` command-line option.
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

hdf5を入れる。

$ brew install hdf5
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/cask).
==> Updated Casks
Updated 1 cask.

==> Downloading https://homebrew.bintray.com/bottles/hdf5-1.12.0_1.arm64_big_sur.bottle.1.tar.gz
Already downloaded: /Users/taisyo/Library/Caches/Homebrew/downloads/2519c56431b045efadebccfd6f8ca4fc45e82ef450ba91f825d9746f7f0b8c05--hdf5-1.12.0_1.arm64_big_sur.bottle.1.tar.gz
==> Pouring hdf5-1.12.0_1.arm64_big_sur.bottle.1.tar.gz
🍺  /opt/homebrew/Cellar/hdf5/1.12.0_1: 268 files, 19.4MB

再度試してみるが、hd5を見つけられないようだ。

$ pip install tables
Collecting tables
  Using cached tables-3.6.1.tar.gz (4.6 MB)
    ERROR: Command errored out with exit status 1:
     command: /Users/taisyo/.pyenv/versions/3.9-dev/bin/python3.9 -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-install-n07_epor/tables/setup.py'"'"'; __file__='"'"'/private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-install-n07_epor/tables/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-pip-egg-info-l0st9pe_
         cwd: /private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-install-n07_epor/tables/
    Complete output (11 lines):
    /var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/H5close7arid9o4.c:2:5: error: implicit declaration of function 'H5close' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        H5close();
        ^
    1 error generated.
    cpuinfo failed, assuming no CPU features: py-cpuinfo currently only works on X86 and some PPC and ARM CPUs.
    * Using Python 3.9.2+ (heads/3.9:2c0a0b0, Mar  8 2021, 14:56:53)
    * USE_PKGCONFIG: True
    .. ERROR:: Could not find a local HDF5 installation.
       You may need to explicitly state where your local HDF5 headers and
       library can be found by setting the ``HDF5_DIR`` environment
       variable or by using the ``--hdf5`` command-line option.
    ----------------------------------------
ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

hdf5を指定してみるが、lseekが見つけられないらしい。

$ HDF5_DIR=/opt/homebrew/Cellar/hdf5/1.12.0_1/ pip install tables
c-blosc/internal-complibs/zlib-1.2.8/gzlib.c:256:24: error: implicit declaration of function 'lseek' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
            state->start = LSEEK(state->fd, 0, SEEK_CUR);
                           ^
    c-blosc/internal-complibs/zlib-1.2.8/gzlib.c:14:17: note: expanded from macro 'LSEEK'
    #  define LSEEK lseek
                    ^
    c-blosc/internal-complibs/zlib-1.2.8/gzlib.c:256:24: note: did you mean 'fseek'?
    c-blosc/internal-complibs/zlib-1.2.8/gzlib.c:14:17: note: expanded from macro 'LSEEK'
    #  define LSEEK lseek
                    ^
    /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h:162:6: note: 'fseek' declared here
    int      fseek(FILE *, long, int);
             ^
    c-blosc/internal-complibs/zlib-1.2.8/gzlib.c:355:9: error: implicit declaration of function 'lseek' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
            ^
    c-blosc/internal-complibs/zlib-1.2.8/gzlib.c:14:17: note: expanded from macro 'LSEEK'
    #  define LSEEK lseek
                    ^
    c-blosc/internal-complibs/zlib-1.2.8/gzlib.c:396:15: error: implicit declaration of function 'lseek' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
            ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
                  ^
    c-blosc/internal-complibs/zlib-1.2.8/gzlib.c:14:17: note: expanded from macro 'LSEEK'
    #  define LSEEK lseek
                    ^
    c-blosc/internal-complibs/zlib-1.2.8/gzlib.c:492:14: error: implicit declaration of function 'lseek' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        offset = LSEEK(state->fd, 0, SEEK_CUR);
                 ^
    c-blosc/internal-complibs/zlib-1.2.8/gzlib.c:14:17: note: expanded from macro 'LSEEK'
    #  define LSEEK lseek
                    ^
    4 errors generated.
    error: command '/usr/bin/clang' failed with exit code 1
    ----------------------------------------
ERROR: Command errored out with exit status 1: /Users/taisyo/.pyenv/versions/3.9-dev/bin/python3.9 -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-install-__cbmmuq/tables/setup.py'"'"'; __file__='"'"'/private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-install-__cbmmuq/tables/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record /private/var/folders/zb/tn25979s7fd82bkj_tj6hd0r0000gn/T/pip-record-zl9x2spz/install-record.txt --single-version-externally-managed --compile --install-headers /Users/taisyo/.pyenv/versions/3.9-dev/include/python3.9/tables Check the logs for full command output.

無いわけがないので、-Wnoしてみる。

$ HDF5_DIR=/opt/homebrew/Cellar/hdf5/1.12.0_1/ CFLAGS=-Wno-implicit-function-declaration pip install tables
Collecting tables
  Using cached tables-3.6.1.tar.gz (4.6 MB)
Requirement already satisfied: numpy>=1.9.3 in /Users/taisyo/.pyenv/versions/3.9-dev/lib/python3.9/site-packages (from tables) (1.20.1)
Requirement already satisfied: numexpr>=2.6.2 in /Users/taisyo/.pyenv/versions/3.9-dev/lib/python3.9/site-packages (from tables) (2.7.3)
Using legacy 'setup.py install' for tables, since package 'wheel' is not installed.
Installing collected packages: tables
    Running setup.py install for tables ... done
Successfully installed tables-3.6.1

入った。