20210512のPythonに関する記事は30件です。

Windows Terminalのプロファイル設定

はじめに やりたいこと PowerShell、Windows Terminalをインストールする Git・Python用のプロファイルを設定する 説明 そもそも、ターミナル(Terminal) と シェル(Shell) とは? シェル ユーザがOSを操作するためのインターフェース cf) bash, zsh, powershell ターミナル 標準出力を文字として表示したり、キーボード入力を取得したりするプログラム cf) GNOME Terminal, xterm 主に、ターミナルを介して、シェルを操作する 本記事では、Windows Terminal(ターミナル) を介して、PowerShell、Git Bash(シェル) を操作する。 手順 PowerShell をインストールする Microsoft Store 経由で PowerShell をインストールする ダウンロードサイト PowerShell を入手 - Microsoft Store デフォルトでインストールされている "Windows PowerShell" は開発が終わっているため、新しく開発が行われている "PowerShell Core" を利用したほうが良い Windows Terminalをインストールする Microsoft Store 経由で Windows Terminal をインストールする ダウンロードサイト Windows Terminal を入手 - Microsoft Store Gitのインストール Windows10にGitをインストール Pythonのインストール Windows10にPythonをインストール Windows Terminal のプロファイルを設定 Windows Terminal を起動 上部の "V" のようなマークをクリック。 左の一番下にある "JSONファイルを開く" をクリック "settings.json" を編集 ## ~~~ 省略 ~~~ "profiles": { # デフォルトの設定 "defaults": { "acrylicOpacity": 0.9, # 透過率 "colorScheme": "One Half Dark", # カラーテーマ "fontFace": "Cascadia Code", # フォント "fontSize": 10, # フォントサイズ "fontWeight": "normal", # フォントスタイル "padding": "0, 0, 0, 0", # 余白の指定 "useAcrylic": true # 透過を行う }, "list": [ ## ~~~ 省略 ~~~ { ## Git Bash Profile "commandline": "C:\\Program Files\\Git\\bin\\bash.exe", "guid": "{ea627c79-2732-4aa7-84be-e6787190da28}", "hidden": false, "icon": "C:\\Program Files\\Git\\mingw64\\share\\git\\git-for-windows.ico", "name": "Git Bash" }, { ## Interactive mode Python Profile "commandline" : "C:\\Program Files\\Python39\\python.exe", "guid" : "{1850e97f-16dc-4281-9ea9-0100c4e852c5}", "icon" : "C:\\Program Files\\Python39\\Lib\\test\\imghdrdata\\python.png", "name" : "Python", "startingDirectory" : "%USERPROFILE%" } ] }, ## ~~~ 省略 ~~~ 終わり 本記事は終了です。 References シェル、ターミナル、コンソール、コマンドライン
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

二酸化炭素センサー (MH-Z19B) を Raspberry Pi で使ってみた

MH-Z19B を買ってみた 二酸化炭素(CO2)濃度が高くなると、集中力が低下し、また頭痛や眠気の原因になるということが広くまことしやかに囁かれだしたのは新型コロナウイルスの影響で在宅勤務が増えてからだったと思います。厚生労働省のページでは 1000 ppm 以下が推奨されていますが自分の部屋が現在何 ppm なのか測定する装置が無いとまったく分かりません。 ということでミーハーな私は二酸化炭素濃度を測定するセンサーが欲しいなと思ってたんですが今回遅ればせながら MH-Z19B を購入しました。AliExpress だと $20 程度で購入可能です。半田付けの必要がないピン付きのものが便利なようです。 Python mh-z19 モジュール MH-Z19B は単なるセンサーなので Raspberry Pi などに接続しないと実際に値を読むことはできません。しかし結論から言うとここに書いてある通りに接続し mh-z19 モジュールを使用すると簡単に二酸化炭素濃度を読むことができます。 コマンドラインからも簡単に値を読み込むことができますし pi@test:~ $ sudo pip3 install mh-z19 pi@test:~ $ python3 -m mh_z19 --serial_console_untouched {"co2": 1031} Python のプログラムからももちろん値を読むことができます。 pi@test:~ $ python3 Python 3.7.3 (default, Jan 22 2021, 20:04:44) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import mh_z19 >>> mh_z19.read(serial_console_untouched=True) {'co2': 987} ちなみに MH-Z19B は Raspberry Pi のシリアルインターフェイスを使用しているので上記を実行前に sudo raspi-config と実行し 3 Interface Options --> P6 Serial Port Enable/disable shell messages on the serial connection を選択してから Would you like a login shell to be accessible over serial? --> No Would you like the serial port hardware to be enabled? --> Yes と答えてあげる必要があります。 上記設定を行うと /boot/config.txt の最後付近に以下の行が追加され Linux の再起動が促されます。 enable_uart=1 Raspberry Pi のシリアル接続 先人の功績により思いの外簡単に二酸化炭素濃度を読み取ることができました。ここではもう少し遊ぶため(?)に上記モジュールが裏側でどんなことをしているのかを見ていくことにします。 まず図の黄色と青の線ですがそれぞれ TXD と RXD と書いてありますがこれはシリアル通信の送信と受信のための線になります。User's Manualを見ると UART (TXD) TTL Level data output と UART (RXD) TTL Level data input と書いてあります。 UART とはシリアル通信を行うためのプロトコルでこことかこことかここが詳しいです。Raspberry Pi 側から見ると GPIO 14 が送信 GPIO 15 が受信に使用されます。 Linux から見るとシリアルデバイスは /dev/serial0 と /dev/serial1 として見えています。私の例では /dev/serial0 (UART0, PL011) を使用しています。 pi@test:~ $ ls -al /dev/serial* lrwxrwxrwx 1 root root 5 May 12 02:01 /dev/serial0 -> ttyS0 lrwxrwxrwx 1 root root 7 May 12 02:01 /dev/serial1 -> ttyAMA0 /dev/serial0 は /dev/ttyS0 へのリンクとなっていますが /dev/ttyS0 は私のデフォルトの環境では以下のように見えています。ここを見ると違う見え方をしているので Raspberry Pi の種類に依存するようです。ちなみに私は Raspberry Pi Zero WH を使用しています。 pi@test:~ $ ls -l /dev/ttyS0 crw-rw---- 1 root dialout 4, 64 May 12 02:27 /dev/ttyS0 Python mh-z19 モジュールの github には一般ユーザーで実行する方法 が書かれています。 ここで注意すべきは /dev/ttyS0 になんらかの変更を加えても serial-getty@serial0 を(再)起動すると group が tty となり group の権限が書き込みのみとなってしまう点です。尚、私の環境では前述のようにデフォルトでは /dev/ttyS0 の group は dialout となっていました。 pi@test:~ $ sudo systemctl start serial-getty@serial0 pi@test:~ $ ls -l /dev/ttyS0 crw--w---- 1 root tty 4, 64 May 12 03:12 /dev/ttyS0 !!! <--- group が tty で group の書き込み権限なし pi@test:~ $ sudo chmod g+r /dev/ttyS0 !!! <--- group の書き込み権限追加 pi@test:~ $ ls -l /dev/ttyS0 crw-rw---- 1 root tty 4, 64 May 12 03:12 /dev/ttyS0 pi@test:~ $ sudo systemctl stop serial-getty@serial0 pi@test:~ $ sudo systemctl start serial-getty@serial0 !!! <--- serial-getty@serial0 の再起動 pi@test:~ $ ls -l /dev/ttyS0 crw--w---- 1 root tty 4, 64 May 12 03:12 /dev/ttyS0 !!! <--- group が tty で group の書き込み権限なし この状態では root 以外のユーザーではシリアルデバイスからの値の読み込みはできません。serial-getty@serial0 は mh-z19 モジュールを --serial_console_untouched オプションを指定せず実行すると内部で再起動されます。 なので、一般ユーザーで mh-z19 モジュールを使用するには serial-getty@serial0 が停止している状態でかつ /dev/ttyS0 に書き込み権限のあるグループに所属しているユーザーが --serial_console_untouched オプションを指定し実行する必要がありそうです。 pi@test:~ $ sudo systemctl status serial-getty@serial0 ● serial-getty@serial0.service - Serial Getty on serial0 Loaded: loaded (/lib/systemd/system/serial-getty@.service; disabled; vendor preset: enabled) Active: inactive (dead) !!! <--- 無効 Docs: man:agetty(8) man:systemd-getty-generator(8) http://0pointer.de/blog/projects/serial-console.html pi@test:~ $ ls -l /dev/ttyS0 crw-rw---- 1 root dialout 4, 64 May 12 13:19 /dev/ttyS0 pi@test:~ $ egrep dialout /etc/group dialout:x:20:pi pi@test:~ $ python3 -m mh_z19 --serial_console_untouched {"co2": 729} serial-getty@serial0 はこことかここが詳しいようです。コンソール接続時に仮想ターミナルの切り替えができるのですがこれを使用する必要が無ければ恐らく active にする必要は無いと思います。/dev/ttyS0 の group が tty となってしまっている場合は Linux を一旦再起動をすると元に戻ります。 Raspberry Pi でシリアルを使用するプログラムを書いてみる モジュールを使用しないで値を読み込む場合は以下のようなプログラムとなります。 import serial if __name__ == '__main__': serial_dev = '/dev/serial0' ser = serial.Serial(serial_dev, baudrate=9600) result=ser.write(b"\xff\x01\x86\x00\x00\x00\x00\x00\x79") s=ser.read(9) if len(s) >= 4 and s[0] == 0xff and s[1] == 0x86: print(s[2]*256 + s[3]) import serial ができない場合は pip3 で pyserial モジュールをインストールしてください。 pi@test:~ $ sudo apt install python3-pip pi@test:~ $ sudo pip3 install pyserial 上記を実行するとモジュールを使用した際と同等の値を読むことができます。 pi@test:~ $ python3 ./my_mh_z19.py 644 pi@test:~ $ python3 -m mh_z19 --serial_console_untouched {"co2": 644} 上記のプログラムがなにをしているかというとまず serial.Serial(serial_dev, baudrate=9600) で /dev/serial0 を 9600 bps(bit per second) でオープンしています。 次に ser.write(b"\xff\x01\x86\x00\x00\x00\x00\x00\x79") で User's Manual の 7 ページにかかれている Read コマンド (FF 01 86 00 00 00 00 00 79) を MH-Z19B にシリアル経由で送信しています。次に s=ser.read(9) で MH-Z19B からの返答を 9 byte 分読み込んでいます。 ここで仮に FF 86 01 F4 00 00 00 00 85 という値が返ってきたとします。この 2 番めと 3 番めの 01 F4 が二酸化炭素濃度の値となります。16進数なので10進数になおしてあげると 1*256 + 254 = 500 ppm となります。if 文で s[0] と s[1] をチェックしているのは Start Byte と Command が正しい値となっているかの確認となります。 エラー処理をもう少ししっかりする場合には mh-z19 モジュールでされているように以下のようなプログラムを書いてあげると良いかもしれません。シリアル接続に関しても User's Manual の 6 ページに書かれている通り "Set serial port baud rate be 9600, data bytes have 8 bytes, stop byte has 1byte, parity byteisnull." でオープンしています。 import serial import traceback serial_dev = '/dev/serial0'; def connect_serial(): return serial.Serial(serial_dev, baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=1.0) def mh_z19(): try: ser = connect_serial() while 1: result=ser.write(b"\xff\x01\x86\x00\x00\x00\x00\x00\x79") s=ser.read(9) if len(s) >= 4 and s[0] == 0xff and s[1] == 0x86: return {'co2': s[2]*256 + s[3]} break except: traceback.print_exc() if __name__ == '__main__': print(mh_z19()) 上記のプログラムも二酸化炭素濃度の値を読めることを確認します。 pi@test:~/mh-z19b $ python3 ./my_mh_z19_2.py {'co2': 595} あとは任意のプログラムを用いてログをとったり警告を送ったりすることができます。では良い二酸化炭素濃度ライフをお過ごしください! (おまけ) 二酸化炭素濃度センサーの種類について 二酸化炭素濃度センサーを選ぶ際ですが当然 MH-Z19B のような単なるセンサーではなく完成品を買うのが第一の選択肢になるはずです。ただ完成品はこことかここを見るとかなり玉石混交の状態らしく安いものは正確な値が測れなかったりするようです。ちょっと見た限りだと 10,000 円程度のものを買ったほうが良いという印象でした。 後者の記事には MH-Z19B のような赤外線を使った NDIR (Non Dispersive Infrared) 方式の二酸化炭素濃度センサーは消費電力が高いのでバッテリーの駆動は難しいとの指摘があります。Raspberry Pi Zero WH もそれなりに消費電力が高いのでモバイルバッテリーを用いた運用は数日が限界のようです。 電源の問題に関してはパソコンを起動中にのみ二酸化炭素濃度を測れれば良いというのであればここにあるようにUSBシリアル変換モジュールを使用してパソコンに刺してしまうのは良いアイデアだと思いました。 センサーとしてはもう少し簡易的ですが CCS811 を使えばより消費電力が少なくて済むそうです。取得されたデータの比較が ここ でされていました。M5Stack と組み合わせると消費電力が少なくディプレイもついていて便利かもしれません。 MH-Z19B と MH-Z19C の違いについては ここ が詳しいです。両方とも読み取りの誤差は ± (50ppm + 5%) 程度のようです。MH-Z14A は ±(50ppm + 3%) なので単純に型番が大きいほうが性能が良いと言うわけでは無さそうです。MH-Z19C の方が電源投入してから測定値が安定するまでのプレヒート時間が MH-Z19C の 3 分に比べ 1 分と短くなっています。ぱっと見では実用上そこまで大きな違いは無さそうです。 当然完成品のほうが外観が綺麗で手軽に使えるデザインとなっています。値段が高いものだと外部に値を出力する方法を持つものもあるのかもしれません。しかし Raspberry Pi などとセンサーの組み合わせで作ると特に出力先を自由に決められます。配線も比較的少ないですし素晴らしい Python モジュールもあるため作っていて気軽に挑戦できると思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Windows10にPythonをインストール

Windows10にPythonをインストール Windows10にPythonをインストールしたときの、チェックボックスをメモとして残しておく。 インストーラをダウンロード ダウンロードサイト (www.python.org) ダウンロードサイト上部の"Downloads"をクリック "Download Python 3.9.5"をクリック Pythonのインストーラを起動 "このアプリがデバイスに変更を加えることを許可しますか?"は"はい"を押す Install Python 3.9.5 (64-bit) ☑ "Install launcher for all users (recommended)" ☑ "Add Python 3.9 to PATH" ☑ "Customize Installation" "Next" をクリック Optional Features ☑ "Documentation" ☑ "pip" ☑ "tcl/tk and IDLE" ☑ "Python test suite" ☑ "py launcher" ☑ "for all users (require elevation)" "Next" をクリック Advanced Options ☑ "Install all users" ☑ "Assciate files with Python (requires the py launcher)" ☑ "Create shortcuts for installed applications" ☑ "Add Python to environment variables" ☑ "Precompile standard library" ☑ "Download debugging symbols" ☐ "Download debug binaries (requires VS 2017 or later)" "Customize install location" は変更なし [C:\Program Files\Python39] "Install" をクリック Setup Progress インストール中 Setup was successful インストール完了 "Close"ボタンを押す 終わり 本記事は終了です。 References
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

風景を北斎風に変換するアプリつくりました

技育CAMPの初めてのハッカソン~vol.3~に参加した記事です。 開発したもの アップロードされた画像を北斎風に変換して出力するwebアプリです。僕にとっては初めてのwebアプリ開発でした。 URL:https://github.com/koouu/hackathon20210508 チームメンバー 学校の同級生と2人で出場しました。 役割 僕  :画像変換、バックエンド N君 :フロントエンド 使用した技術 変換モデル Googleのcolabで、画像変換の機械学習を行っていました。UGATITというcycleGANの応用したものを使いました。形状の変化に強くて、人間をアニメ風に変換したとかが有名です。全結合層にAttentionを使ってるみたいです。 また記事にまとめるかも。 ※GANとは 偽物作るAI作る時偽物かどうか分別するAIも一緒に学習すれば上手な偽物作れるようになるよねって感じ ※cycleGANとは 本物に戻せる偽物作れるように学習すれば元画像の特徴残せるよねって感じ 論文 U-GAT-IT: UNSUPERVISED GENERATIVE ATTENTIONAL NETWORKS WITH ADAPTIVE LAYERINSTANCE NORMALIZATION FOR IMAGE-TO-IMAGE TRANSLATION https://arxiv.org/pdf/1907.10830.pdf バックエンド pythonのflaskを使いました。flask使うのは初めてだったけど、シンプルで使いやすかったです。 フロントエンド htmlを使いました。ほんとはJS使いたかったけど、Pythonとうまくデータのやりとりができなかったので断念。 大変だったこと UGATITの学習モデルのサイズが1G超えてて、ローカルだと、cuda out of memoryがでて動きませんでした。結局風景を北斎風にする以外の部分全部削って動きました。gitからダウンロードできるモデルもその状態になってます。 あとシンプルにwebアプリ開発初めてだったんで難しかったです。 今後 ローカルでしか実装できなかったんで今度は公開できるように頑張ります。 後発表終わった後に二枚目以降の画像の変換の出力が全部1枚目の画像を変換したものになっていることがわかりました。原因がわからないからもうちょっと勉強します... まとめ 楽しかった!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PythonでのIPアドレスの取扱いについて

はじめに IPアドレスの8進数の不適切な検証の脆弱性(CVE-2021-28918)がPythonのipaddressモジュール影響あるということで、ipaddressにおけるIPアドレスの取扱いを調べた。 また、ドット区切りIPアドレスからドット区切りなしIPアドレスへの変換を行う関数を作成した。 ipaddressモジュールにおけるIPアドレスの扱い 以下のように、ipaddressモジュールがインポートされていることを前提とします。 >>> import ipaddress 例として、ローカルループバックアドレス(127.0.0.1)を用います。 ドット区切りIPアドレスにおける8進数の扱い 先頭の0は単に除外される >>> ipaddress.IPv4Address('127.0.0.01') IPv4Address('127.0.0.1') 3桁を超えるとエラーになる >>> ipaddress.IPv4Address('0127.0.0.1') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python3.9/ipaddress.py", line 1302, in __init__ self._ip = self._ip_int_from_string(addr_str) File "/usr/lib/python3.9/ipaddress.py", line 1199, in _ip_int_from_string ipaddress.AddressValueError: At most 3 characters permitted in '0127' in '0127.0.0.1' ドット区切りなしIPアドレスの扱い 10進数 >>> ipaddress.IPv4Address(2130706433) IPv4Address('127.0.0.1') 8進数 >>> ipaddress.IPv4Address(0o17700000001) IPv4Address('127.0.0.1') 16進数 >>> ipaddress.IPv4Address(0x7f000001) IPv4Address('127.0.0.1') バイト型 >>> ipaddress.IPv4Address(b'\x7f\x00\x00\x01') IPv4Address('127.0.0.1') ドット区切りIPアドレスからドット区切りなしIPアドレスに変換 例として、ローカルループバックアドレス(127.0.0.1)を用います。 10進数 >>> def ipv4d2nd(ipv4): ... return sum((int(n)<<8*d for d,n in enumerate(reversed(ipv4.split('.'))))) >>> ipv4d2nd('127.0.0.1') 2130706433 8進数 >>> oct(ipv4d2nd('127.0.0.1')) '0o17700000001' 16進数 >>> hex(ipv4d2nd('127.0.0.1')) '0x7f000001' 参考文献
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

目次・まとめていきたいこと

勉強し、まとめていきたいもの Figma Figmaを使ったWeb開発の高速化 GCP 資格取得にむけて Python Djangoの開発 今後にむけて 随時内容を更新していこう 将来の見通しはわからないし、どうなるかもわからない でも、そんな中でも自分ができるのは準備しておくこと 今後のためにいろいろ勉強して、準備をしておこうと思う
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Wine での Python のありかのメモ(Python 使う app の cross-compile 用)

背景 Python を使うアプリ(e.g. pybind11)を Linux で cross-compile したい python.org にある embedded(zip)だとヘッダファイルとかが無い. どのようにしてビルドしたかの config.h ファイルが異る(はず)であろうから. .lib/.h だけ適当にディストーションから抜き出して利用というのも問題がありそう. wine を使って .exe(installer)の Python を使うとします. Python 3.9 を想定します. 手順 winecfg で, 利用する Windows バージョンを指定しておきます. 3.9 からは Windows 8.1 以上でないと使えなくなったようです. あとはインストーラー起動してファイルインストールすれば OK デフォルトでは, Windows 10 に設定した wine では(Linux 上では)以下にインストールされました. .wine/drive_c/users/<USERNAME>/Local Settings/Application Data/Programs/Python CI 環境などセットアップしたい場合は, を参考に cli オプションを指定して. TODO Wine 上で conda 環境を作り conda の Python 環境を使って cross compile する.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Lambda (Python 3.8)&Wrike APIで取得したjsonをパースし任意のキーで取り出してみる。

この記事の概要 https://qiita.com/katoiek/items/b2fb9ce7ad759e5fb5aa の続き。 せっかくなのでほしい要素を取り出してみる。 本記事の投稿者 前も来ましたがPython&Lambda初心者(両方とも初めて書いてみた)なのでセオリー的なPerseの仕方などはわからないので力技です。 大まかな手順 Wrikeで永続トークンを生成し、LabmdaでPythonの関数つくって実行し、かえって来たクエリの任意のキーを取り出す。 今回の目的 サンプルソースからpermalink要素を抜き出す。 今回はpermalinkをキーとしましたが、その他クエリに使えそうなキーはWrike公式APIリファレンスを参照してください https://developers.wrike.com/api/v4/tasks/#query-tasks →こちらのResponseです。 APIからのレスポンス(例) sample.json { "kind": "tasks", "data": [ { "id": "TASKID", "accountId": "AccountID", "title": "タスクのタイトル", #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 省略 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "permalink": "https://www.wrike.com/open.htm?id=00000000", } ] } ソース lambda_fucntion_2.py import json import urllib.request from pprint import pprint permanent_token='Wrike API 永続トークン' url = 'https://www.wrike.com/api/v4/tasks' header ={ 'Authorization': 'bearer '+ permanent_token} def lambda_handler(event, context): req=urllib.request.Request(url, headers=header) with urllib.request.urlopen(req) as res: # resは http.client.HTTPResponse json_data = json.loads(res.read().decode('utf8')) # レスポンスボディ headers = res.getheaders() # ヘッダー(dict) status = res.getcode() # ステータスコード # data要素のみを格納 data = json_data['data'] #パーマリンクのみ取得 ここを任意のキーにすることで項目を変えられます。 for entry in data: print(entry['permalink']) キー 今回はpermalinkをキーとしましたが、その他クエリに使えそうなキーはWrike公式APIリファレンスを参照してください https://developers.wrike.com/api/v4/tasks/#query-tasks →こちらのResponseです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Lambda (Python 3.8)からWrikeのAPI経由のJsonをパースし任意のキーを取り出してみる。

この記事の概要 https://qiita.com/katoiek/items/b2fb9ce7ad759e5fb5aa の続き。 せっかくなのでほしい要素を取り出してみる。 本記事の投稿者 前も来ましたがPython&Lambda初心者(両方とも初めて書いてみた)なのでセオリー的なPerseの仕方などはわからないので地下わら技です。 大まかな手順 Wrikeで永続トークンを生成し、LabmdaでPythonの関数つくって実行し、かえって来たクエリの任意のキーを取り出す。 今回の目的 サンプルソースからpermalink要素を抜き出す。 今回はpermalinkをキーとしましたが、その他クエリに使えそうなキーはWrike公式APIリファレンスを参照してください https://developers.wrike.com/api/v4/tasks/#query-tasks →こちらのResponseです。 APIからのレスポンス(例) sample.json { "kind": "tasks", "data": [ { "id": "TASKID", "accountId": "AccountID", "title": "タスクのタイトル", #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 省略 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ "permalink": "https://www.wrike.com/open.htm?id=00000000", } ] } ソース lambda_fucntion_2.py import json import urllib.request from pprint import pprint permanent_token='Wrike API 永続トークン' url = 'https://www.wrike.com/api/v4/tasks' header ={ 'Authorization': 'bearer '+ permanent_token} def lambda_handler(event, context): req=urllib.request.Request(url, headers=header) with urllib.request.urlopen(req) as res: # resは http.client.HTTPResponse json_data = json.loads(res.read().decode('utf8')) # レスポンスボディ headers = res.getheaders() # ヘッダー(dict) status = res.getcode() # ステータスコード # data要素のみを格納 data = json_data['data'] #パーマリンクのみ取得 ここを任意のキーにすることで項目を変えられます。 for entry in data: print(entry['permalink']) キー 今回はpermalinkをキーとしましたが、その他クエリに使えそうなキーはWrike公式APIリファレンスを参照してください https://developers.wrike.com/api/v4/tasks/#query-tasks →こちらのResponseです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python lambdaでの処理

はじめに Pythonのlambda式を自身がよく忘れてしまいがちなので, メモとして残しておきます. 他の方の参考にもなればと思います. 間違っている箇所もあると思いますので, コメントしていただけると幸いです. Pythonはdef()で関数を定義しますが, lambda式で無名関数を定義することができます. def() を用いた関数の場合、引数として直接他の関数に渡すことができず, 違う場所で定義してから値を渡す必要があるのに対して, lambda式は, あくまで「式」であるので, 関数の引数として直接渡すことができます!!!! 次の節から例を紹介していきます. def文とlambda式の対応関係 def add(x, y=1): return x+y print(add(1,2)) # 3 print(add(100)) # 101 上記のdef文を, lambda式に変換した場合 f = lambda x, y=1: x+y print(f(1,2)) # 3 print(f(100)) # 101 しかしながら, 上記のようにlambda式を変数に代入している記法は, PEP8では非推奨となっているので 注意してください lambda式でif文処理 for文で一つ一つ処理する際に, if文の条件分岐が入るケースでもlambda式を活用することができます! number_list = [1,2,3,4,5] odd_number = [] for i in number_list: if i % 2 == 0: print(f"{i}は偶数である") else: print(f"{i}は奇数である") odd_number.append(i) print(odd_number) # [1,3,5] 上記のfor文を, lambda式を使って書き直した場合 number_list = [1,2,3,4,5] odd_number = filter(lambda i : i % 2 != 0, number_list) print(list(odd_number)) # [1,3,5] sorted関数 リストをソートする組み込み関数には引数keyがあります. keyには, ソートの前にリストの各要素に適用される関数を指定します. a = [[0,7,4], [2,5,6], [7,4,2]] b = sorted(a) print(b) # [[0,7,4], [2,5,6], [7,4,2]] 上記のsorted関数で, lambda式を活用した場合 a = [[0,7,4], [2,5,6], [7,4,2]] b = sorted(a, key=lambda x: x[-1]) print(b) # [[7, 4, 2], [0, 7, 4], [2, 5, 6]] map関数 リストの各要素に対して, 一定の処理を行った値を使用する場合はmap関数を適用します. def doubler(x): return x*2 L = [1, 2, 3, 4, 5, 6] mod_list = map(doubler, L) print(list(mod_list)) # [2, 4, 6, 8, 10, 12] 上記のmap関数で, lambda式を活用した場合 L = [1, 2, 3, 4, 5, 6] doubler = map(lambda x: x*2, L) print(list(doubler)) # [2, 4, 6, 8, 10, 12] まとめ 今回はlambdaでの処理について記事にしました. 間違っている部分があった場合はコメントしていただけると幸いです. 今後もpython tipsを記事にしていこうと思います 参考文献 pythonにおけるlambda式の使い方
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Flask-RESTX Swagger ドキュメント表示を無効にするいくつかの方法

FlaskでRest APIを実装するための拡張 Flask RESTX には、Rest API仕様を表示してくれる機能が内蔵されています。その実態はSwaggerというAPI仕様を記述するJSONドキュメントと、それを見やすく表示してくれるSwagger UIの組み合わせ。ほかの多くのWebフレームワークにも同じ機能が載っています。 from flask import Flask from flask_restx import Api, Resource, fields app = Flask(__name__) api = Api(app) @api.route("/sample") class SampleResource(Resource): def get(self): """ サンプル """ pass @api.expect(api.model("Sample", model={"name": fields.String})) def post(self): """ サンプルを追加 """ pass 開発時には便利ですが、公開環境ではAPI仕様を見れるようにはしたくないケースも多くあります。そのためにとれる方法を紹介します。 引数 doc にFalse 指定 Apiクラスの引数 doc に False を指定することで、Swagger UI を無効にできます。 api = Api(app, doc=False) ただし、表示されなくなるのはSwagger UIだけで、JSONで配信されるSwaggerドキュメントは /swagger.json は依然として公開されたままです。 nginxでHTTP/404 へrewrite nginxでプロキシしてるならその設定のなかで、swaggerドキュメントへのリクエストをHTTP/404にリライトすることで、JSONファイルへのアクセスを防げます。 location ^~ /swagger.json { rewrite ^(.*)$ /404 redirect; } 次に述べるやりかたを知るまでは、この方法しかないと思っていました。 init_app で引数 add_specs を指定 Flask拡張は、インスタンス作成時にFlaskオブジェクト (app) を渡して有効にする方法と、インスタンスを作ったあとにinit_appにFlaskオブジェクトを渡す方法どちらかを選べるようになっています。 app = Flask(__name__) api = Api(app) # あるいは api = Api() api.init_app(app) init_appの引数に add_specs=False を指定すると、swagger JSONファイルの配信も止めることができるみたいです。 api = Api() api.init_app(app, add_specs=True) みたいです、というのはdocコメントにその記述がないんですよねえ……。 In [10]: api.init_app? Signature: api.init_app(app, **kwargs) Docstring: Allow to lazy register the API on a Flask application:: >>> app = Flask(__name__) >>> api = Api() >>> api.init_app(app) :param flask.Flask app: the Flask application object :param str title: The API title (used in Swagger documentation) :param str description: The API description (used in Swagger documentation) :param str terms_url: The API terms page URL (used in Swagger documentation) :param str contact: A contact email for the API (used in Swagger documentation) :param str license: The license associated to the API (used in Swagger documentation) :param str license_url: The license page URL (used in Swagger documentation) File: ~/.local/share/virtualenvs/restx-7s1H6SJg/lib/python3.9/site-packages/flask_restx/api.py Type: method 使っていいオプションなのかどうか、よくわかりません。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Django周りの開発環境をインストールする

はじめに 私はプログラミング歴1年の初心者です。 実務でWebサイトのコーディングを1年間行ってきました。 そろそろシステム開発もできるようになりたいということで LaravelやReactをこれから勉強していこうと思っております。 今回の目的 今回はDjangoの環境構築方法を学んでいこうと思います。 Homebrewを使ってインストールしていきます。 本当は仮想環境を立ててインストールするほうがいいらしいのですが 今回は初めてなのでその部分は端折っていきます。 目次 Pythonのインストール Djangoのインストール 実際にやってみる Pythonのインストール # HomebrewでPythonをインストールする $ brew search python $ brew install python3 # PATHの設定 $ echo "export PATH=/usr/local/bin:$PATH" >> ~/.bash_profile $ source ~/.bash_profile # pythonのバージョンを確認する(2系と3系が分かれている) $ python -V → Python 2.7.16 $ python3 -V → Python 3.8.7 # pip3の中身を確認する (pip3はpythonのパッケージマネージャで、python3と一緒にインストールされている。) $ pip3 list Djangoのインストール # pipでDjangoをインストールする $ python3 -m pip install Django # Djangoのバージョン確認 $ python3 >>> import django >>> django.get_version() 一旦ここで終了しておきます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[python] リスト内包表記内でprintしたい

小技です。 検索してもそれっぽい感じの記事があまり出なかったので投稿。 前提 リスト内包表記内で時間のかかる処理を行っているとき、進捗状況をprintしたい! ということが人によってはあると思います。ないかも。 print_in_list_test.py import time def heavy_function(num): time.sleep(1) # めちゃんこ時間かかる処理 return "かたつむりが{num}匹".format(num=num) def print_in_list_test(): #print() # 進捗状況を出力したいけど、全部やった後かやる前しか出力できない outputs = [heavy_function(num) for num in range(1, 10)] # ここでめっちゃ時間かかる… print("、".join(outputs)) print("処理開始") print_in_list_test() print("処理終了") out 処理開始 かたつむりが1匹、かたつむりが2匹、かたつむりが3匹、かたつむりが4匹、かたつむりが5匹、かたつむりが6匹、かたつむりが7匹、かたつむりが8匹、かたつむりが9匹 処理終了 解決策 あまり綺麗ではないですが、 tupleを一時生成する tuple内でprintした後に、メインのデータを選択 というようにすることで、リスト内包表記内でのprintが実現できます。 print_in_list_test2.py import time def heavy_function(num): time.sleep(1) # めちゃんこ時間かかる処理 return "かたつむりが" + str(num) + "匹" def print_in_list_test2(): outputs = [(print("\r処理中:" + str(num), end=""), heavy_function(num))[1] # 一時tuple を作成して即廃棄 for num in range(1, 10)] print() # ↑のprint内で \r を使ってるので行を改める print("、".join(outputs)) print("処理開始") print_in_list_test2() print("処理終了") out 処理開始 処理中:9 かたつむりが1匹、かたつむりが2匹、かたつむりが3匹、かたつむりが4匹、かたつむりが5匹、かたつむりが6匹、かたつむりが7匹、かたつむりが8匹、かたつむりが9匹 処理終了 追記:カウンター側で出力する コメントで頂いた情報です。(ありがとうございます!) 関数を用意する必要がありますが、余計な処理が無くて自然です。 ライブラリもあるんだそうな。 GitHub - tqdm_tqdm A Fast, Extensible Progress Bar for Python and CLI.html print_in_list_test3.py import time def heavy_function(num): time.sleep(1) # めちゃんこ時間かかる処理 return "かたつむりが{num}匹".format(num=num) def progress(seq): for num in seq: print("\r処理中:{num}".format(num=num), end="") yield num print() # ↑のprint内で \r を使ってるので行を改める def print_in_list_test3(): outputs = [heavy_function(num) for num in progress(range(1, 10))] print("、".join(outputs)) print("処理開始") print_in_list_test3() print("処理終了") 感想 べんり!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PyTorchで勾配降下法

PyTorchで勾配降下法をするコードを書いてみました。 最適化したい関数 def rosenbrock(x0, x1): y = 10 * (x1 - x0 ** 2) ** 2 + (x0 - 1) ** 2 return y 関数を可視化する import numpy as np h = 0.01 x_min = -2 y_min = -3 x_max = 2 y_max = 5 X = np.arange(x_min, x_max, h) Y = np.arange(y_min, y_max, h) xx, yy = np.meshgrid(X, Y) 最小値はこのへんですね matrix = rosenbrock(xx, yy) minimum = None min_x = None min_y = None for i in range(matrix.shape[0]): for j in range(matrix.shape[1]): if minimum is None or minimum > matrix[i][j]: minimum = matrix[i][j] min_y = Y[i] min_x = X[j] print(min_x, min_y, minimum) 1.0000000000000027 0.9999999999999147 8.208018832734106e-26 ドットが描かれた場所が最小値になります。 import matplotlib.pyplot as plt plt.contourf(xx, yy, np.sqrt(rosenbrock(xx, yy)), alpha=0.5) plt.scatter(min_x, min_y, c="k") plt.colorbar() plt.grid() plt.show() 勾配降下法 import numpy as np import torch x0 = torch.tensor(0.0, requires_grad=True) x1 = torch.tensor(4.0, requires_grad=True) lr = 0.001 iters = 10000 history = [] for i in range(iters): history.append(np.array([np.array(x0.data), np.array(x1.data)]).flatten()) y = rosenbrock(x0, x1) y.backward() with torch.no_grad(): x0.data -= lr * x0.grad x1.data -= lr * x1.grad x0.grad.zero_() x1.grad.zero_() 結果表示 import matplotlib.pyplot as plt plt.contourf(xx, yy, np.sqrt(rosenbrock(xx, yy)), alpha=0.5) plt.scatter([p[0] for p in history], [p[1] for p in history]) plt.scatter(min_x, min_y, c="k") plt.colorbar() plt.grid() plt.show() 複数箇所からスタート import numpy as np import torch x0 = torch.tensor([0.0, -0.5, -1.5, 1.5], requires_grad=True) x1 = torch.tensor([4.0, 4.0, -1.0, -2], requires_grad=True) lr = 0.001 iters = 10000 history = [] for i in range(iters): history.append([x0.detach().clone(), x1.detach().clone()]) y = rosenbrock(x0, x1) #y.backward() s = torch.sum(y) s.backward() with torch.no_grad(): x0.data -= lr * x0.grad x1.data -= lr * x1.grad x0.grad.zero_() x1.grad.zero_() 結果表示 import matplotlib.pyplot as plt plt.contourf(xx, yy, np.sqrt(rosenbrock(xx, yy)), alpha=0.5) for i in range(4): plt.scatter([p[0][i] for p in history], [p[1][i] for p in history]) plt.colorbar() plt.scatter(min_x, min_y, c="k") plt.grid() plt.show()
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[python3] EUC-JPなのにShift-JISの機種依存文字が入っててUTF-8にできなかったときの対策

表題の通りです。 先人が機種依存文字対策に苦心した痕跡がちらりほらり… ※ はしご高とかそういうタイプの機種依存文字はこの記事では扱いません。 環境 Windows 10 Python 3.8.5 スクレイピング:requests 状況(読まなくても良い) 最近 seesaawiki の記事の自サイトへの移植をごそごそとしているのですが。 seesaawikiからスクレイピングでHTMLソースを取得すると、 <meta http-equiv="Content-Type" content="text/html; charset=EUC-JP"> とあって確かに EUC-JP のはずなのに、wikiソース内で「①」のような Shift-JIS の機種依存文字が使えるせいでたまにこれが紛れてくるんです。 で普通に res = requests.get(url) text = res.html みたいに結果を取得しようとすると、なにやらREPLACEMENT CHARACTERなる特殊文字に変化している文字がある… こまった…… という感じのことになってたいへん苦心したので、対策法を一応記事にしておきます。 誰かの役に立ったらうれしい! 対策 文字コードeuc_jis_2004を使ってbytesをデコードする。 他の言語ではそれっぽい用途にEUC-JP-MS eucJP-win CP51932なる文字コードが使えるらしいのですが、pythonだと全部対応してない…。 decode_test.py def decode_test(): original_string = '①②③ ⅠⅡⅢ ㍉㎜㊤㍾' # 適当に機種依存文字 before_decode = b'\xad\xa1\xad\xa2\xad\xa3 \xad\xb5\xad\xb6\xad\xb7 \xad\xc0\xad\xd0\xad\xe5\xad\xed' trying_encoding_list = ["euc_jp", "euc_jis_2004", "euc_jisx0213"] for enc in trying_encoding_list: try: decoded = before_decode.decode(encoding=enc) if decoded == original_string: print(enc + ": success!!") except UnicodeDecodeError as e: print(enc + ": decode failed...") euc_jp: decode failed... euc_jis_2004: success!! euc_jisx0213: success!! euc_jis_2004とeuc_jisx0213の違いは正直なところ全くわからないのですが、どっちも動くっぽいのでとりあえず2004の方を使いました。 そもそもEUC-JPの範囲外の文字を含んでるなら最初からcharsetに対応する文字コードを書いて欲しい…と思ったけど、一般公開するには一般的なコード名じゃないとダメなんでしょうか。 参考になったサイト シフトJIS / EUC-JPとUnicodeとの妥当な変換表 (なんかいろいろ大変だったらしい…という勉強になりました) pythonで丁寧な文字コード変換 (このブログ記事のおかげで解決に至りました。超感謝です)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Django]ManyToManyの有無でフィルタリングしたい

動機 Django(3.1)で、ManyToManyField(多対多のrelation)を持つmodelを考えます。 このとき、対象のFieldにレコードがセットされているか否かでフィルタリングをしたい場合があります。 例えば以下のようなmodelを考えます。一つの記事に複数のタグがついている想定です。 models.py from django.db import models # タグ class Tag(models.Model): name=models.CharField(verbose_name="名前",max_length=32) # 記事 class Article(models.Model): title=models.CharField(verbose_name="タイトル",max_length=32) text=models.TextField(verbose_name="本文") tags=models.ManyToManyField(Tag,verbose_name="タグ",related_name="articles") ここで、タグが一つでもついている記事の一覧を引っ張りたいとします。まず思いつくのは以下の書き方です。 views.py from django.views.generic import ListView from .models import * class ArticleWithTagsListView(ListView): model=Article template_name="article_with_tags.html" def get_queryset(self): # tags__isnull=Falseで、タグが少なくとも一個ついているレコードだけ引っ張る queryset=Article.objects.filter(tags__isnull=False) return queryset しかしこの方法はうまくいきません。紐づいているTag数に応じてレコードが重複してしまいます。 かといって views.py queryset=Article.objects.all() filtered_queryset=[q for q in queryset if q.tags.count()>0] なんてしようものならループの度にクエリが走って、実行時間がえらいことになります。 distinct()を使おう 最後にdistinct()を絡めれば、isnullフィルターを有効活用できます。 views.py queryset=Article.objects.filter(tags__isnull=False).distinct() annotate()を使おう annotate()を使って各レコードのtag数を算出→countが0より大きいものをフィルタリングという方法をとってもOKです。 views.py from django.db.models import Count queryset=Article.objects.annotate(tag_count=Count('tag')).filter(tag_count__gt=0) 分解すると、まず下記の操作で"tag_count"という値に各レコードのtagの数を格納しています。 views.py queryset=Article.objects.annotate(tag_count=Count('tag')) #例 : 最初のレコードのtag数が3のとき q=queryset.first() print(q.tag_count) # 3 次に、"tag_count"が0より大きいレコードだけを抽出しています。 views.py queryset=Article.objects.annotate(tag_count=Count('tag')) queryset=queryset.filter(tag_count__gt=0) #追加
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python Tips

配列の中に含まれるかどうか hoge.py #domain_listが配列 target_domainが変数 result=target_domain in domain_list #配列内にあればTrue if(result==True): continue メインプログラムの書き出し 「if name == 'main':」の呪文をつけておくと、外部ファイルからhoge.pyファイルを読み込まれたときに、勝手に実行されない。 hoge.py if __name__ == '__main__': 乱数を発生する import random #0-100の乱数を発生させる i=random.uniform(0, 100) #整数化(注意点あり) seisu=int(i) フォルダ内のファイル名を取得する #フォルダ内のファイルパスをすべて取得する import glob import os files = glob.glob("./images/*") for file in files: print(os.path.split(file)[1])
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Python] OpenCVのインストール方法 (mac)

OpenCVとは OpenCVとは Open Source Computer Vision Library の略です。 画像処理や画像解析や機械学習の難しい機能を、誰でも簡単に使えるようにまとめて整えたプログラムの集まりで、誰でも無料で使える機能です。 インストール方法 homebrewを使ってopenCVをインストールします。 以下のコマンドを実行します。(インストールが終わるまで10分ほどかかります。) $ brew install opencv 次に以下のコマンドを実行して、pipで対応するモジュールをインストールします。 $ pip3 install opencv-python インストールできたのかを確認する $ python3 実行して以下のように表示されれば成功です。 Python 3.9.5 (default, May 4 2021, 03:36:27) [Clang 12.0.0 (clang-1200.0.32.29)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> (>>> の後に exit() を実行すると戻ります。)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Discord.pyで翻訳Botを作る

前置き 今回はPythonとgoogletransというGoogle翻訳のAPIを使用して、メッセージを翻訳してくれるDiscordBotを作ります 環境 / インストールするもの 環境 MacOS 11.2.3 VisualStudioCode Python 3.9.4 インストールするもの discord.py 公式ドキュメント わかりやすい記事 googletrans ドキュメント(PyPI) 流れ ① ユーザーがメッセージを送信 ② そのメッセージをbotが取得 ③ googletransを使用して翻訳 ④ 翻訳したものをメッセージとして送信 コード import discord from googletrans import Translator token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" client = discord.Client() translator = Translator() @client.event async def on_ready(): print("run") @client.event async def on_message(message): # botの発言には反応しない if message.author.bot: return # メッセージの言語判別 lang = translator.detect(message.content).lang # 言語が日本語だったら if lang == "ja": trans_text = translator.translate(message.content, src = lang, dest = "en").text await message.channel.send(trans_text) # 言語が英語だったら elif lang == "en": trans_text = translator.translate(message.content, src = lang, dest = "ja").text await message.channel.send(trans_text) client.run(token) コードはこれだけです 実行結果 いい感じ、毎日お肉食べたい 戦ったエラー達 もし同じエラーになった人がいたらすぐに解決できるようざっと書いておきます AttributeError: 'NoneType' object has no attribute 'group' このエラーはgoogletrans側の問題のようで下記のバージョンをインストールしたら解決しました pip install googletrans==4.0.0-rc1 参考 https://qiita.com/maboy/items/9a1336ece11db4630858 TypeError: Object of type Message is not JSON serializable これに関しては自分の問題で、言語判別の記述を - lang = translator.detect(message).lang + lang = translator.detect(message.content).lang こう書いてしまっていました これだとtranslator.detectの引数をstr型で渡せていないのでそれが原因です、恥ずかしい 最後に 流石にスラングなどの精度が微妙ではあるので、今度は普段お世話になっているDeepL翻訳のAPIを使ってみて記事も上げようと思います
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ガチャ沼と確率に出現するネイピア数e

SSR率1%のガチャを100回引いたらどれぐらいの確率で引けるんだろう・・・? ある人は100%! と言う このマヌケが! 箱の中の賞品が有限個なら引くたびに当たりの確率は上がり 全て引き切るまで試行すればもちろん100%の確率となるが ソシャゲのガチャは違う 天井付きのガチャシステムならまだしも、それがないゲームならいくら引いても単発当たりの確率は固定だ 実際に数学的に計算しよう 排出率1%のSSRを引いた時を当たりとするのであれば、単発で当たりを引かない確率は99%だ 今回考えるべき結果は、100回引いて少なくとも1回当たりを引く確率である。 この少なくとも1回以上という条件がなかなか曲者なのだが、中学でちゃんと数学の授業を聞いていた人なら簡単にわかるだろう このような確率は、余事象を考えるとたやすく算出できる。 少なくとも1回以上当たりを出す確率は、100回引いて1回も当たりを引けない確率の余事象であると考えられる。 単発で当たりを引けない確率が99%なので、それが100回連続して起こる確率は$0.99^{100}$となる これの余事象を考えればよいので、$1 - 0.99^{100}$ が今回ほしい確率である。 これを計算すると、$0.63396765872...$となり 確率に直すと約63.4%だと言える さて、今回はSSR排出率1%(1/100)のガチャを100回試行した時にSSRを引ける確率を考えたが、他の数値についても知りたくなった。 一般化してみる 確率1/nの事象をn回試行して、少なくとも1回は事象が起こる確率は、n回連続外れる確率の余事象なので $$1 - (1 - \frac{1}{n})^n $$ となる このnをどんどん大きくして、限りなく∞に近づけたときどうなるだろうか?つまり $$\lim_{n \to \infty}1 - (1 - \frac{1}{n})^n$$ を考えてみる $\lim_{n \to \infty}(1 - \frac{1}{n})^n$ この部分、見覚えないだろうか おそらく高校時代理系だったキミなら思い当たる節があるハズ ネイピア数$e$の定義の形に似ている $$\lim_{n \to \infty}(1 + \frac{1}{n})^n = e$$ $$ e = 2.718281828459...$$ せっかくならこの式を使いたいので、先ほどの $\lim_{n \to \infty}(1 - \frac{1}{n})^n$ をなんとかして変形する。 $1 - \frac{1}{n} \quad$ を $\quad1 + \frac{1}{(-n)}\quad$ としてみると $$\lim_{n \to \infty}(1 + \frac{1}{(-n)})^n$$ さらに次数のnを無理やり $$\lim_{n \to \infty}(1 + \frac{1}{(-n)})^{-(-n)}$$ とすることもできる $-n = N \quad$とおくと $$\lim_{n \to \infty}(1 + \frac{1}{N})^{-N}$$ となり、これは結局$\quad\frac{1}{e}\quad$となることがわかる なので今回求めたい確率は $$\quad1 - \frac{1}{e} = 0.63212055882...$$ ということで、約63.2%となる nがいくつでもあまり確率は変わらない? nが100の場合だと約63.4%、nが限りなく大きい場合は約63.2% となるとこの$\quad f(x) = 1 - (1 - \frac{1}{x})^x\quad$という関数は収束が早そう というわけでグラフ化 numplot.py import numpy as np import matplotlib.pyplot as plt x = np.arange(1, 101, 0.1) y = 1 - (1 - (1/x)) ** x plt.ylim([0.5, 1]) plt.title('$f(x) = 1-(1-\\frac{1}{x})^x$') plt.xlabel('x') plt.ylabel('f(x)', rotation=0) plt.minorticks_on() plt.grid(which="major", color="black", alpha=0.5) plt.grid(which="minor", color="gray", linestyle=":") plt.plot(x, y, c='red') plt.show() とりあえず$\quad x=101\quad$までプロット グラフを見るに案の定収束が早い! $x = 20\quad$の段階ですでに$0.64$ちょいに到達している なので、1/nの確率の事象をn回試行した時に起こる確率は、だいたい63%くらいと言い切ってよさそう。 ギャンブルとかに使えそうだ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Kaggle初心者が入門書から学んだこと

はじめに 『実践Data Scienceシリーズ PythonではじめるKaggleスタートブック (KS情報科学専門書)』を読了したので、そこから学んだことなどをまとめます。 学んだこと Kaggle のコンペの参加の方法からどうやって攻略していくか Titanic を使った分析/予測のやり方 実際のコンペで使われるアルゴリズムや小技 トップランカーのコンペの攻略法 おわりに チュートリアルが配布されているので、一通り動かしてみるだけでも勉強になります。 また、この方々のTwitterも勉強になるので、おすすめです。 https://twitter.com/currypurin https://twitter.com/upura0
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

venvの使い方

環境構築 仮想環境を作成します python -m venv venv1 作成後、以下の様なコマンドで仮想環境に入る .\venv1\Scripts\activate pipコマンドで必要なパッケージをインストールします pip install lxml
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

自動車の走行距離を予測するモデル作成

概要 自動車の属性データからガソリン1ガロンあたりの走行距離を予測するモデル作成を行います。 利用するデータの説明 カラム ヘッダ名称 データ型 説明 1 mpg float ガソリン1ガロンあたりの走行距離 2 cylinders varchar シリンダー 3 displacement float 排気量 4 horsepower float 馬力 5 weight float 重量 6 acceleration float 加速度 7 model year varchar 年式 8 origin varchar 起源 9 car name varchar 車名 ライブラリのインストール import numpy as np import pandas as pd import seaborn as sns from matplotlib import pyplot as plt from sklearn.metrics import r2_score from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error as MSE from sklearn.linear_model import LinearRegression as LR データの読み込み df_train = pd.read_csv('data/train.tsv', sep='\t') print(df_train.head()) ↓ id mpg cylinders displacement horsepower weight acceleration model year origin car name 0 0 29.0 4 135.0 84.00 2525.0 16.0 82 1 dodge aries se 1 3 31.9 4 89.0 71.00 1925.0 14.0 79 2 vw rabbit custom 2 9 19.0 6 156.0 108.0 2930.0 15.5 76 3 toyota mark ii 3 11 28.0 4 90.0 75.00 2125.0 14.5 74 1 dodge colt 4 13 37.7 4 89.0 62.00 2050.0 17.3 81 3 toyota tercel 欠損値の確認 print(df_train.isnull().sum()) ↓ id 0 mpg 0 cylinders 0 displacement 0 horsepower 0 weight 0 acceleration 0 model year 0 origin 0 car name 0 dtype: int64 基本統計量 print(df_train.describe(include='all')) ↓ id mpg cylinders displacement horsepower weight acceleration model year origin car name count 199.000000 199.000000 199.000000 199.000000 199 199.000000 199.000000 199.000000 199.000000 199 unique NaN NaN NaN NaN 71 NaN NaN NaN NaN 167 top NaN NaN NaN NaN 90.00 NaN NaN NaN NaN ford pinto freq NaN NaN NaN NaN 12 NaN NaN NaN NaN 4 mean 200.170854 24.307035 5.296482 183.311558 NaN 2883.839196 15.647739 76.165829 1.582915 NaN std 113.432759 7.797665 1.644562 98.400457 NaN 819.766870 2.701885 3.802928 0.798932 NaN min 0.000000 9.000000 3.000000 71.000000 NaN 1613.000000 8.500000 70.000000 1.000000 NaN 25% 98.500000 18.000000 4.000000 98.000000 NaN 2217.500000 14.000000 73.000000 1.000000 NaN 50% 202.000000 24.000000 4.000000 140.000000 NaN 2702.000000 15.500000 76.000000 1.000000 NaN 75% 294.500000 30.500000 6.000000 250.000000 NaN 3426.500000 17.150000 80.000000 2.000000 NaN max 396.000000 44.600000 8.000000 454.000000 NaN 5140.000000 23.700000 82.000000 3.000000 NaN 相関係数 print(df_train.corr()) ↓ id mpg cylinders displacement weight acceleration model year origin id 1.000000 -0.052688 0.103419 0.098416 0.070563 -0.087649 -0.093272 -0.031421 mpg -0.052688 1.000000 -0.770160 -0.804635 -0.820660 0.379721 0.568471 0.533671 cylinders 0.103419 -0.770160 1.000000 0.950600 0.893256 -0.479561 -0.303462 -0.497373 displacement 0.098416 -0.804635 0.950600 1.000000 0.933038 -0.523955 -0.329817 -0.579805 weight 0.070563 -0.820660 0.893256 0.933038 1.000000 -0.401757 -0.265562 -0.535893 acceleration -0.087649 0.379721 -0.479561 -0.523955 -0.401757 1.000000 0.194854 0.189193 model year -0.093272 0.568471 -0.303462 -0.329817 -0.265562 0.194854 1.000000 0.124279 origin -0.031421 0.533671 -0.497373 -0.579805 -0.535893 0.189193 0.124279 1.000000 相関係数の可視化 mpg(ガロンあたりの走行距離)とdisplacement、weightに強い負の相関関係 相関関係の可視化 sns.pairplot(df_train[["mpg", "weight", "displacement"]]) ↓ 重回帰モデルの作成 # データの準備 y_train = df_train[["mpg"]] # 被説明変数 X_train = df_train[["weight", "displacement"]] # 説明変数 # モデルの生成 lr = LR() # モデルの学習 lr.fit(X_train, y_train) 学習結果 print(lr.coef_) # 傾き print(lr.intercept_) # 切片 print(lr.score(X_train, y_train)) # 決定係数 ↓ [[-0.00513703 - 0.02383218]] # 傾き [43.4901176] # 切片 0.6851901992035567 # 決定係数 y = b1 × -0.00513703 + b2 × -0.02383218 + 43.4901176 学習結果と実データの比較 df_train['pred'] = y_pred_train # 実データと予測結果の差をresとして代入 df_train['res'] = df_train['mpg'] - df_train['pred'] # ソート print(df_train.sort_values(by='res')) ↓ mpg displacement weight model year car name pred res 19.0 122.0 2310.0 73 ford pinto 28.716052 - 9.716052 20.0 140.0 2408.0 72 chevrolet vega 27.783644 - 7.783644 18.0 121.0 2933.0 72 volvo 145e(sw) 25.539515 - 7.539515 19.0 121.0 2868.0 73 volvo 144ea 25.873422 - 6.873422 21.0 140.0 2401.0 73 chevrolet vega 27.819603 - 6.819603 ... ... ... ... ... ... ... 41.5 98.0 2144.0 80 vw rabbit 30.140772 11.359228 43.1 90.0 1985.0 78 volkswagen rabbit custom diesel 31.148217 11.951783 44.6 91.0 1850.0 80 honda civic 1500 gl 31.817884 12.782116 43.4 90.0 2335.0 80 vw dasher(diesel) 29.350257 14.049743 38.0 262.0 3015.0 82 oldsmobile cutlass ciera(diesel) 21.757941 16.242059 model yearが古い時にマイナス、新しい時にプラスにずれている すでにmodel yearとmpgに相関関係が確認 特徴量の追加 説明変数にmodel yearを追加 y_train = df_train[["mpg"]] X_train = df_train[["weight", "displacement", "model year"]] lr = LR() lr.fit(X_train, y_train) y_pred_train = lr.predict(X_train) print(lr.score(X_train, y_train)) ↓ 0.806202914350324 model yearを説明変数に設定したところ決定変数の値が約0.2上昇 再検証 df_train['pred'] = y_pred_train df_train['res'] = df_train['mpg'] - df_train['pred'] print(df_train.sort_values(by='res')) ↓ mpg displacement weight model year car name pred res 19.0 122.0 2310.0 73 ford pinto 25.822268 - 6.822268 22.0 232.0 2835.0 82 ford granada l 28.804316 - 6.804316 19.8 200.0 2990.0 79 mercury zephyr 6 25.711137 - 5.911137 21.5 121.0 2600.0 77 bmw 320i 27.049786 - 5.549786 23.5 173.0 2725.0 81 chevrolet citation 29.040204 - 5.540204 ... ... ... ... ... ... ... 36.4 121.0 2950.0 80 audi 5000s(diesel) 27.133402 9.266598 44.6 91.0 1850.0 80 honda civic 1500 gl 34.205448 10.394552 38.0 262.0 3015.0 82 oldsmobile cutlass ciera(diesel) 27.517075 10.482925 43.1 90.0 1985.0 78 volkswagen rabbit custom diesel 31.838867 11.261133 43.4 90.0 2335.0 80 vw dasher(diesel) 31.161030 12.238970 通常年式だけではなく、車の種類とセットのため、car nameもセットで関係していると予測 ダミー変数化 ダミー変数化できるカラムを自動で認識 X_train = pd.get_dummies( df_train[["weight", "displacement", "model year", "car name"]]) print(X_train) ↓ weight displacement model year ... car name_vw dasher(diesel) car name_vw rabbit car name_vw rabbit custom 2525.0 135.0 82 ... 0 0 0 1925.0 89.0 79 ... 0 0 1 2930.0 156.0 76 ... 0 0 0 2125.0 90.0 74 ... 0 0 0 2050.0 89.0 81 ... 0 0 0 ... ... ... ... ... ... ... 2110.0 85.0 80 ... 0 0 0 3570.0 302.0 78 ... 0 0 0 3433.0 304.0 70 ... 0 0 0 2335.0 90.0 80 ... 1 0 0 2265.0 98.0 73 ... 0 0 0 再度モデルの作成と検証 y_train = df_train[["mpg"]] X_train = pd.get_dummies( df_train[["weight", "displacement", "model year", "car name"]]) lr = LR() lr.fit(X_train, y_train) y_pred_train = lr.predict(X_train) df_train['pred'] = y_pred_train df_train['res'] = df_train['mpg'] - df_train['pred'] print(df_train.sort_values(by='res')) print(lr.score(X_train, y_train)) ↓ mpg displacement weight model year car name pred res 29.0 90.0 1937.0 76 vw rabbit 34.656354 - 5.656354 31.8 85.0 2020.0 79 datsun 210 36.276274 - 4.476274 19.0 122.0 2310.0 73 ford pinto 23.364118 - 4.364118 25.0 116.0 2220.0 76 opel 1900 27.625883 - 2.625883 23.5 173.0 2725.0 81 chevrolet citation 26.067394 - 2.567394 ... ... ... ... ... ... ... 28.0 116.0 2123.0 71 opel 1900 25.374117 2.625883 26.5 140.0 2565.0 76 ford pinto 23.871847 2.628153 30.5 97.0 2190.0 77 volkswagen dasher 27.862259 2.637741 40.8 85.0 2110.0 80 datsun 210 36.323726 4.476274 41.5 98.0 2144.0 80 vw rabbit 35.843646 5.656354 0.9834170393004322 予測データと実データの差が減少 car nameのダミー変数化前に比べて決定係数が約0.3上昇 結果 horsepower、weight、model yearに自動車の走行距離(mpg)に影響 car nameをダミー変数化することで決定係数が大幅に改善 課題 car nameを説明変数に入れると未知の車種を予測できなかった(過学習) →メーカーと車種を分けて分析する必要がある originやcylindersが未検証 null以外の欠損値があとで発見
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Learn Python In Seminars〜自動車の走行距離を予測するモデル作成〜

概要 自動車の属性データからガソリン1ガロンあたりの走行距離を予測するモデル作成を行います。 データはこちらからダウンロードしてください。 Learn Python In Seminars 基本統計量と簡単なグラフ化 欠損値 自動車の走行距離 利用するデータの説明 カラム ヘッダ名称 データ型 説明 1 mpg float ガソリン1ガロンあたりの走行距離 2 cylinders varchar シリンダー 3 displacement float 排気量 4 horsepower float 馬力 5 weight float 重量 6 acceleration float 加速度 7 model year varchar 年式 8 origin varchar 起源 9 car name varchar 車名 ライブラリのインストール import numpy as np import pandas as pd import seaborn as sns from matplotlib import pyplot as plt from sklearn.metrics import r2_score from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error as MSE from sklearn.linear_model import LinearRegression as LR データの読み込み df_train = pd.read_csv('data/train.tsv', sep='\t') print(df_train.head()) ↓ id mpg cylinders displacement horsepower weight acceleration model year origin car name 0 0 29.0 4 135.0 84.00 2525.0 16.0 82 1 dodge aries se 1 3 31.9 4 89.0 71.00 1925.0 14.0 79 2 vw rabbit custom 2 9 19.0 6 156.0 108.0 2930.0 15.5 76 3 toyota mark ii 3 11 28.0 4 90.0 75.00 2125.0 14.5 74 1 dodge colt 4 13 37.7 4 89.0 62.00 2050.0 17.3 81 3 toyota tercel 欠損値の確認 print(df_train.isnull().sum()) ↓ id 0 mpg 0 cylinders 0 displacement 0 horsepower 0 weight 0 acceleration 0 model year 0 origin 0 car name 0 dtype: int64 基本統計量 print(df_train.describe(include='all')) ↓ id mpg cylinders displacement horsepower weight acceleration model year origin car name count 199.000000 199.000000 199.000000 199.000000 199 199.000000 199.000000 199.000000 199.000000 199 unique NaN NaN NaN NaN 71 NaN NaN NaN NaN 167 top NaN NaN NaN NaN 90.00 NaN NaN NaN NaN ford pinto freq NaN NaN NaN NaN 12 NaN NaN NaN NaN 4 mean 200.170854 24.307035 5.296482 183.311558 NaN 2883.839196 15.647739 76.165829 1.582915 NaN std 113.432759 7.797665 1.644562 98.400457 NaN 819.766870 2.701885 3.802928 0.798932 NaN min 0.000000 9.000000 3.000000 71.000000 NaN 1613.000000 8.500000 70.000000 1.000000 NaN 25% 98.500000 18.000000 4.000000 98.000000 NaN 2217.500000 14.000000 73.000000 1.000000 NaN 50% 202.000000 24.000000 4.000000 140.000000 NaN 2702.000000 15.500000 76.000000 1.000000 NaN 75% 294.500000 30.500000 6.000000 250.000000 NaN 3426.500000 17.150000 80.000000 2.000000 NaN max 396.000000 44.600000 8.000000 454.000000 NaN 5140.000000 23.700000 82.000000 3.000000 NaN 相関係数 print(df_train.corr()) ↓ id mpg cylinders displacement weight acceleration model year origin id 1.000000 -0.052688 0.103419 0.098416 0.070563 -0.087649 -0.093272 -0.031421 mpg -0.052688 1.000000 -0.770160 -0.804635 -0.820660 0.379721 0.568471 0.533671 cylinders 0.103419 -0.770160 1.000000 0.950600 0.893256 -0.479561 -0.303462 -0.497373 displacement 0.098416 -0.804635 0.950600 1.000000 0.933038 -0.523955 -0.329817 -0.579805 weight 0.070563 -0.820660 0.893256 0.933038 1.000000 -0.401757 -0.265562 -0.535893 acceleration -0.087649 0.379721 -0.479561 -0.523955 -0.401757 1.000000 0.194854 0.189193 model year -0.093272 0.568471 -0.303462 -0.329817 -0.265562 0.194854 1.000000 0.124279 origin -0.031421 0.533671 -0.497373 -0.579805 -0.535893 0.189193 0.124279 1.000000 相関係数の可視化 mpg(ガロンあたりの走行距離)とdisplacement、weightに強い負の相関関係 相関関係の可視化 sns.pairplot(df_train[["mpg", "weight", "displacement"]]) ↓ 重回帰モデルの作成 # データの準備 y_train = df_train[["mpg"]] # 被説明変数 X_train = df_train[["weight", "displacement"]] # 説明変数 # モデルの生成 lr = LR() # モデルの学習 lr.fit(X_train, y_train) 学習結果 print(lr.coef_) # 傾き print(lr.intercept_) # 切片 print(lr.score(X_train, y_train)) # 決定係数 ↓ [[-0.00513703 - 0.02383218]] # 傾き [43.4901176] # 切片 0.6851901992035567 # 決定係数 y = b1 × -0.00513703 + b2 × -0.02383218 + 43.4901176 学習結果と実データの比較 df_train['pred'] = y_pred_train # 実データと予測結果の差をresとして代入 df_train['res'] = df_train['mpg'] - df_train['pred'] # ソート print(df_train.sort_values(by='res')) ↓ mpg displacement weight model year car name pred res 19.0 122.0 2310.0 73 ford pinto 28.716052 - 9.716052 20.0 140.0 2408.0 72 chevrolet vega 27.783644 - 7.783644 18.0 121.0 2933.0 72 volvo 145e(sw) 25.539515 - 7.539515 19.0 121.0 2868.0 73 volvo 144ea 25.873422 - 6.873422 21.0 140.0 2401.0 73 chevrolet vega 27.819603 - 6.819603 ... ... ... ... ... ... ... 41.5 98.0 2144.0 80 vw rabbit 30.140772 11.359228 43.1 90.0 1985.0 78 volkswagen rabbit custom diesel 31.148217 11.951783 44.6 91.0 1850.0 80 honda civic 1500 gl 31.817884 12.782116 43.4 90.0 2335.0 80 vw dasher(diesel) 29.350257 14.049743 38.0 262.0 3015.0 82 oldsmobile cutlass ciera(diesel) 21.757941 16.242059 model yearが古い時にマイナス、新しい時にプラスにずれている すでにmodel yearとmpgに相関関係が確認 特徴量の追加 説明変数にmodel yearを追加 y_train = df_train[["mpg"]] X_train = df_train[["weight", "displacement", "model year"]] lr = LR() lr.fit(X_train, y_train) y_pred_train = lr.predict(X_train) print(lr.score(X_train, y_train)) ↓ 0.806202914350324 model yearを説明変数に設定したところ決定変数の値が約0.2上昇 再検証 df_train['pred'] = y_pred_train df_train['res'] = df_train['mpg'] - df_train['pred'] print(df_train.sort_values(by='res')) ↓ mpg displacement weight model year car name pred res 19.0 122.0 2310.0 73 ford pinto 25.822268 - 6.822268 22.0 232.0 2835.0 82 ford granada l 28.804316 - 6.804316 19.8 200.0 2990.0 79 mercury zephyr 6 25.711137 - 5.911137 21.5 121.0 2600.0 77 bmw 320i 27.049786 - 5.549786 23.5 173.0 2725.0 81 chevrolet citation 29.040204 - 5.540204 ... ... ... ... ... ... ... 36.4 121.0 2950.0 80 audi 5000s(diesel) 27.133402 9.266598 44.6 91.0 1850.0 80 honda civic 1500 gl 34.205448 10.394552 38.0 262.0 3015.0 82 oldsmobile cutlass ciera(diesel) 27.517075 10.482925 43.1 90.0 1985.0 78 volkswagen rabbit custom diesel 31.838867 11.261133 43.4 90.0 2335.0 80 vw dasher(diesel) 31.161030 12.238970 通常年式だけではなく、車の種類とセットのため、car nameもセットで関係していると予測 ダミー変数化 ダミー変数化できるカラムを自動で認識 X_train = pd.get_dummies( df_train[["weight", "displacement", "model year", "car name"]]) print(X_train) ↓ weight displacement model year ... car name_vw dasher(diesel) car name_vw rabbit car name_vw rabbit custom 2525.0 135.0 82 ... 0 0 0 1925.0 89.0 79 ... 0 0 1 2930.0 156.0 76 ... 0 0 0 2125.0 90.0 74 ... 0 0 0 2050.0 89.0 81 ... 0 0 0 ... ... ... ... ... ... ... 2110.0 85.0 80 ... 0 0 0 3570.0 302.0 78 ... 0 0 0 3433.0 304.0 70 ... 0 0 0 2335.0 90.0 80 ... 1 0 0 2265.0 98.0 73 ... 0 0 0 再度モデルの作成と検証 y_train = df_train[["mpg"]] X_train = pd.get_dummies( df_train[["weight", "displacement", "model year", "car name"]]) lr = LR() lr.fit(X_train, y_train) y_pred_train = lr.predict(X_train) df_train['pred'] = y_pred_train df_train['res'] = df_train['mpg'] - df_train['pred'] print(df_train.sort_values(by='res')) print(lr.score(X_train, y_train)) ↓ mpg displacement weight model year car name pred res 29.0 90.0 1937.0 76 vw rabbit 34.656354 - 5.656354 31.8 85.0 2020.0 79 datsun 210 36.276274 - 4.476274 19.0 122.0 2310.0 73 ford pinto 23.364118 - 4.364118 25.0 116.0 2220.0 76 opel 1900 27.625883 - 2.625883 23.5 173.0 2725.0 81 chevrolet citation 26.067394 - 2.567394 ... ... ... ... ... ... ... 28.0 116.0 2123.0 71 opel 1900 25.374117 2.625883 26.5 140.0 2565.0 76 ford pinto 23.871847 2.628153 30.5 97.0 2190.0 77 volkswagen dasher 27.862259 2.637741 40.8 85.0 2110.0 80 datsun 210 36.323726 4.476274 41.5 98.0 2144.0 80 vw rabbit 35.843646 5.656354 0.9834170393004322 予測データと実データの差が減少 car nameのダミー変数化前に比べて決定係数が約0.3上昇 結果 horsepower、weight、model yearに自動車の走行距離(mpg)に影響 car nameをダミー変数化することで決定係数が大幅に改善 課題 car nameを説明変数に入れると未知の車種を予測できなかった(過学習) →メーカーと車種を分けて分析する必要がある originやcylindersが未検証 null以外の欠損値があとで発見 - Miyata Koki - O:inc.でAmplify×React×React Nativeを使用して開発しています。大学のゼミでは統計学をPythonで行っています。 インターンやゼミで学んだ情報を発信していくので、フォロバもしますのでぜひこちらのアカウントのフォローお願いします!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PythonでTweepyを使ってTwitterをごにょごにょする

TwitterDevelopers 事前設定 初期設定はReadOnlyになっているでツイートするとエラーが発生する。 設定の変更が必要である。 設定を変更したら、各トークンの再発行が必要とのこと! https://qiita.com/butsuli_shine/items/78fd5ee6fdb4a0581652 基本系 import tweepy # 認証に必要なキーとトークン API_KEY = 'xxxxxxxxxxx' API_SECRET = 'xxxxxxxxxxxxxx' ACCESS_TOKEN = 'xxxxxxxxxxxxxxx' ACCESS_TOKEN_SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxxx' # APIの認証 auth = tweepy.OAuthHandler(API_KEY, API_SECRET) auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET) キーワードに関連するツイートを取得 # キーワードからツイートを取得 api = tweepy.API(auth) tweets = api.search(q=['くるま'], count=10) for tweet in tweets: print('-----------------') print(tweet.text) 普通にツイート api = tweepy.API(auth) #tweet api.update_status("hello tweepy") 画像付きでツイート api = tweepy.API(auth) #tweet api.update_with_media(status = "hello tweepy with media", filename = 'hoge.jpg')
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PythonでLINE Notifyへ通知を送る

ここからアカウントを登録してトークンを取得します。 https://notify-bot.line.me/ja/ ターミナルからrequestsをインストールしておく hoge.py pip install requests hoge.py import requests # LINEに通知させる関数 def line_notify(message): token = 'XF8fj16T**************dcqqS9CXOa' url = "https://notify-api.line.me/api/notify" headers = {"Authorization": "Bearer " + token} payload = {"message": message} requests.post(url, headers=headers, params=payload)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【PySide2】Qt Creatorを使って本格的なGUI開発を入門する~#0 環境構築~

はじめに Qt Creatorを使ってPySide2のGUIプログラミングを解説していきます。 当ページではQt Creatorのインストール手順について説明しています。 環境 Windows 10 Python 3.8 以降 Qt Creatorのインストール Qt公式サイトのダウンロードページにアクセスします。 https://www.qt.io/download 右上にあるDownload. Try.をクリックします。 Downloads for open source users → Go open sourceをクリックします。 ページの一番最後までスクロールしたところにあるDownload the Qt Online Installerをクリックします。 Downloadをクリックしてインストーラを取得します。 ダウンロードが完了したらqt-unified-windows-x86-4.1.0-online.exeを実行します。 Qtアカウントが無いことを前提に説明します。Sign upをクリックします。 メールアドレスとパスワードを設定します。 上段(I have read and ...)には必ずチェックを入れます。下段(I am an individual ...)は個人で使用する場合にチェックを入れます。会社や法人(個人事業主も?)として使用する場合はチェックを入れずに会社名・事業所名を入力します。 Nextをクリック。 Qtの使用情報・データの情報提供に協力するか否かの選択。どっちでもいいです。下図では情報を提供する方にチェックしています。 インストールするQtのバージョンを選択します。ここでは旧バージョンのQt 5を選択していますが、これもどっちでもいいです。 ライセンスに同意するにチェックを入れてNextをクリックします。図にあるようにLGPLライセンスになります(GPLよりゆるめのライセンスと思ってください)。インストール後はC:\Qt\Licensesにライセンス情報が保存されます。 そのままNextをクリック。 Installをクリック。 インストール実行中の画面。15~30分くらいかかります。 インストールに成功したら以下のような画面になります。 ちゃんとインストールできていればQt Creatorを開くことができます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

前回作ったブログの見た目をつくるぞ!挑戦・・

前回で作ったモデルで今度は見た目を作っていくことに挑戦してきます。 まずは前回のコードをダウンロードします。 *私はpaizacloudの無料版を使っており㉔時間経過すると消えてします為です そして、データベースを作成 見た目を作った時に何も表示されないと寂しいので ↑のようにデータベースに登録しておきます。 そして、今度はviewとtemplateを作っていく。 ファイルが無い場合は作成しましょう。。 追記・・こちらをインポートし忘れ・・ 続いて Templateの作成 Bootstrapを取り込んだベースTemplateを作成 使いたかったんですよ〜ありがたや・・(ひとりごと) BootstrapとはCSSを自分で書かなくても簡単に見た目を整えられる「CSSフレームワーク」。 ※フォルダがない場合は作成 blog/templates/blog/base.html ↑配置に注意 base.htmlの中に 記述。。 一覧(トップ)ページのTemplateを作成 ※ListViewはこの名前でテンプレートを探すのでこの名前でないとダメ。 blog/templates/blog/post_list.html 個別(詳細)ページのTemplateを作成 ※DetailViewはこの名前でテンプレートを探すのでこの名前でないとダメ blog/templates/blog/post_detail.html 記述。。 URLを設定 BlogアプリのURL設定 blog/urls.py 全体設定のURL設定 pj_blog/urls.py ↑ 追加する所を追加 一覧記事に記事へのリンクを設定 blog/templates/blog/post_list.htmlの6行目を以下に変更 <li><a href="{% url 'detail' post.id %}">{{ post.title }}</a></li> 動かしてみよう 最初に作ったサンプル投稿が一覧に表示されているはずです。 でしたが。。表示されず・・全体のurls.pyを記述しなおしたら できました(´;ω;`) よかったぁ〜!! ブログの新規投稿画面を作ろう Viewの作成 blog/views.pyに以下を追記 一覧と詳細はデータを表示するだけでしたが、新規投稿はcreateとなりますので genericのeditに入ってるみたいです。 Templateの作成 Post用の投稿フォームが{{ form.as_p }}で自動的に生成されます。 {% csrf_token %}はセキュリティ上form内に必ず必要な決り文句。 ※CreateViewはこの名前でテンプレートを探すのでこの名前でないとダメ blog/templates/blog/post_form.html URLの設定 blog/urls.pyのdetailのURL設定の下に以下を追加。 トップページからリンクを貼る blog/templates/blog/post_list.html の次の行に以下を追記。 <p><a href="{% url 'create' %}">新規投稿</a></p> モデルの個別ページのURL設定 デフォルトでは新規投稿したあとに、自動で投稿したばかりのページに移動します。 なので、各投稿のURLを知らせる必要があります。 blog/models.pyのPostモデルに、importとget_absolute_urlメソッドを追記。 まずインポート そして、Postモデルの中に 記述・・ 立ち上げてみると 新規投稿でてきました!! 移動すると・・ お〜!!ぽい!!٩(♡ε♡ )۶ 実際に投稿してみました。 投稿編集画面を作ろう Viewの作成 from django.views.generic.edit import UpdateView class Update(UpdateView): model = Post fields = ["title", "body", "category", "tags"] ↑こちらを追加 Templateの作成 ※UpdateViewはデフォルトでCreateViewと同じTemplateを使うので必要なし! まじっすか〜!! 仕様を変えたい場合などは作って設定すれば良いらしい。。 URLの設定 blog/urls.py createの次に以下を追記。 path('update/<pk>', views.Update.as_view(), name="update"), パスで変える感じやな・・ 個別ページからリンクを貼る blog/templates/blog/post_detail.html {% endblock %}の上に以下を追記。 <p><a href="{% url 'update' object.pk %}">編集</a></p> 動かしてみた 編集できておりました。 投稿削除画面を作ろう Viewの作成 from django.views.generic.edit import DeleteView class Delete(DeleteView): model = Post # 削除したあとに移動する先(トップページ) success_url = "/" Templateの作成 ※DetailViewはこの名前でテンプレートを探すのでこの名前でないとダメ blog/templates/blog/post_confirm_delete.html {% extends "blog/base.html" %} {% block main %} <h2>削除確認</h2> <p>{{ object.title }}を本当に削除してもよろしいですか?</p> <form method="post"> {% csrf_token %} <input type="submit" value="削除" class="btn btn-danger" /> </form> {% endblock %} URLの設定 updateのURL設定の下に以下を追記。 blog/urls.py path('delete/<pk>', views.Delete.as_view(), name="delete"), そして詳細ページに削除ボタンをつくって 動かしてみた。 できました(´;ω;`)。。。 しょぱなから表示されなくてあせりましたが・・・今回もなんとか達成できました!! まだまだ挑戦は続きます
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Pythonの正規表現でURLの特定の文字列から/スラッシュに囲まれた文字列を抽出

URLである特定の部分から手前の/までの文字を抽出したい いまいち文章だと分かりづらいので例を出します。 https://exsample.com/hendou/1234/category というURLがあった場合。 末尾のcategoryのみ分かっていてhendouは動的なので特定できないとします。 この条件下で1234を抽出する正規表現です。 正規表現 とりあえずこれで動くと思います。 '[^/]*(?=/category)' m = re.search('[^/]*(?=/category)','https://exsample.com/hendou/1234/category') print(m.group()) # 1234 解説 [^/]*は/を除く0個以上の文字列です。 [^除外したい文字]で文字の除外ができます。 文字列を除外したい場合[^a-z]等の記述ができます。 別パターン categoryが末尾ではなく手前だった場合 https://exsample.com/hendou/category/1234/hendou2 先ほどの正規表現を少し変えれば抽出できます。 m = re.search('(?<=category/)[^/]*', 'https://exsample.com/hendou/category/1234/hendou2') print(m.group()) # 1234 categoryが手前にある為先読み肯定から後読み肯定になりました。 除外の別の表現 実はこの記事を投稿した時は[^/]*を((?!/).)* と記述してました。 ((?!除外したい文字列).)*でも同じ効果が期待できます。 ただ圧倒的に[^]のが簡素ですね、調査不足でした。 参考サイト 特定の文字列を含まないという正規表現 - Weblog on mebius.tokaichiba.jp Python | 先読みと後読みを使ったパターンの記述 【Python】とっても便利な正規表現! - Qiita
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Lambdaで I/O Errorが発生した場合の対応

はじめに 個人的な備忘録が目的です。 言語は Python のみですが、考え方は他の言語にも流用できるかなと思います。 問題点 Lambdaでファイル作成系のコマンドを実行すると、たまに I/O Error 発生したりします。 例えば、 poppler にある pdftohtml を実行すると、 pdftohtml test.pdf output I/O Error: Couldn't open html file 'outputs.html 原因は、Lambdaではカレントディレクトリにファイルを作成することができないからです。 対応策 上記のStackOverflowの記事にも書かれている通り、 /tmp に作成するようにしたら良いです。 subprocess を使う場合は、以下のような感じですね。 command_list = ["pdftohtml", "-s", "-i", "test.pdf", "output"] process = subprocess.Popen(command_list, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd="/tmp", universal_newlines=True) さいごに 何かありましたら、コメント頂けると助かります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む