goでよく使うスニペット(随時更新)
go modでのモジュール管理
以下のようなパスでプロジェクトを作成。 プロジェクトのパスは、以前はGOPATH配下に置かないとだめだったようだが、今はgo modで管理すればどこでもOK.
dirtest ├── go.mod ├── main.go └── subpkg └── sub1.go
$go.mod
はdirtest
配下でgo mod init dirtest
とすると、自動で作られる。
go.mod
module dirtest go 1.19
main.go
package main import ( "dirtest/subpkg" "fmt" ) func main() { fmt.Println("main is called.") subpkg.PrintHoge() }
sub1.go
package subpkg import "fmt" func PrintHoge() { fmt.Println("Hoge is called from subpkg") }
go mod を指定しないとmain.go:4:2: package dirtest/subpkg is not in GOROOT (/usr/local/go/src/dirtest/subpkg)
となる。
ちなみにvscodeで編集している場合、一度再起動しないと、補完が効かずずっとエディタ上でimportのエラーが解決しない問題があった。(これの調査に2時間くらいかかった。。。)
Tutorial: Create a Go module - The Go Programming Language
ファイルの読み込み
f, err := os.Open("words.txt") if err != nil { fmt.Println(err) } defer f.Close() b, err := ioutil.ReadAll(f) fmt.Println(string(b))
読み込み方法は複数あるようなので、ケースに適した方法を使用する。
for文
for i, v := range []string{"foo", "bar", "baz"} { fmt.Println(i, v) }
標準入力
var str string fmt.Scan(&str) fmt.Println(str, str)
s := bufio.NewScanner(os.Stdin) // 標準入力を受け付けるスキャナ s.Scan() // 1行分の入力を取得する fmt.Println(s.Text(), s.Text())
命名規則
関数名
- キャメルケース
- 公開する場合はアッパーキャメルケース
- 公開しない場合はローワーキャメルケース
seleniumで要素(モーダル)に対してscrollする
python - Scrolling to element using webdriver? - Stack Overflow より、
element = driver.find_element_by_id('some_id') element.location_once_scrolled_into_view
スクロールするアクションではないが、副産物的にスクロールされると。
これ調べるのに半日くらい費やしたー
調査力のなさ。。
最初の方はモーダルでのscrollに固執して
「selenium modal scroll」
とかで調べていて全然情報出てこなかった。
「selenium element scroll」
とかで調べたら普通に出てきた。
AWS lambdaのpythonで並列実行する方法
普通の並列実行は、こちらを参考にして実装できました。
lambdaで実行するとなると若干修正しました。
import time from multiprocessing import Process, Pipe hoge_list = [1, 2, 3, 4] def wait_and_print(i, *args, **kwargs): print(f'start {i}') for j in range(i): print(f'{i}: {j}') time.sleep(1) def lambda_handler(event, context): processes = [] parent_connections = [] for hoge in hoge_list: parent_conn, child_conn = Pipe() parent_connections.append(parent_conn) process = Process(target=wait_and_print, args=(hoge, child_conn,)) processes.append(process) for process in processes: process.start() for process in processes: process.join()
iphone, ipadでkindleの本をオーディオブックにする方法
最近本を読むように心がけていますが、電車移動などのスキマ時間を使って時間を作るようにしていますが、徒歩での移動中などの時間はまだまだ有効活用できていない感がありました。
近ごろまではpodcastやvoicyを聞きながら歩いていたり、部屋の掃除をしていたりしましたが、本当だったらオーディオブックを読みたいと思っていました。
しかしオーディオブックを公式に探すとなると、出版されているものがかなり少ないなということがわかり一時期は諦めていましたが、最近iphoneでも「読み上げ機能」なるものを使えばオーディオブック化できることを知り、活用中です。
ただし、機械的に読み上げるだけなのでイントネーションなどは英語での読み上げ機能などに比べかなり精度が悪く平坦な音を組み合わせているだけです。
加えて、技術書はほとんどまともに読み上げることができません。
ビジネス書や自己啓発本なんかが適していますね。
設定は1分で終わります。
iphone の設定アプリより、「一般」を選択
「一般」より、「アクセシビリティ」を選択
「アクセシビリティ」より、「スピーチ」を選択
画面の読み上げをオンにする
kindleアプリで、「画面上部から下に2本指でスワイプ」
これで読み上げてくれます。
ipadでも同様の方法でできました。
これで読書がちょっと捗るようになりました! 代わりに机の前でガッツリ時間を取れるときには技術書を読み込んでいきたいと思います。
よく使うpython3のスニペット集(随時更新)
pythonスニペット
unixtime⇔datetimeの変換
import datetime # datetimeのnowをつくる now = datetime.datetime.now() # => datetime.datetime(2018, 6, 20, 12, 37, 50, 642687) # datetiemをunixtimeに変換 unixtime = int(now.strftime('%s')) # => 1529465870 # unixtimeをdatetimeに変換 datetime.datetime.fromtimestamp(unixtime) # => datetime.datetime(2018, 6, 20, 12, 37, 50)```
datetime⇔strの変換
import datetime # datetime型にする date_str = '2018/2/1 12:30' date_dt = datetime.datetime.strptime(date_str, '%Y/%m/%d %H:%M') print(date_dt) # str型にする dt_now = datetime.datetime.now() print(dt_now.strftime('%Y-%m-%d %H:%M:%S')) # 2018-02-02 18:31:13
boto3でデフォルト以外のprofileを使う
import boto3 from boto3.session import Session profile = 'hoge' session = Session(profile_name=profile)
配列のループをindexと一緒に
teams = ["Packers", "49ers", "Ravens", "Patriots"] for index, team in enumerate(teams): print index, team >>> 0 Packers >>> 1 49ers >>> 2 Ravens >>> 3 Patriots
2つの配列を同時にループ
nfc = ["Packers", "49ers"] afc = ["Ravens", "Patriots"] for teama, teamb in zip(nfc, afc): print teama + " vs. " + teamb >>> Packers vs. Ravens >>> 49ers vs. Patriots
正規表現
match
import re pattern = r"ca" text = "caabsacasca" matchOB = re.match(pattern , text) if matchOB: print matchOB.group() # 'ca'
search
pattern = r"ca" text = "caabsacasca" matchOB = re.search(pattern , text) if matchOB: print(matchOB) # <_sre.SRE_Match object; span=(0, 2), match='ca'> print(matchOB.group()) # マッチした文字列を返す # ca print(matchOB.start()) # マッチの開始位置を返す # 0 print(matchOB.end()) # マッチの終了位置を返す # 2 print(matchOB.span()) # マッチの位置(start, end)を含むタプルを返す # (0, 2)
ロギング
import logging from logging import getLogger, StreamHandler, Formatter # loggerオブジェクトの宣言 logger = getLogger("Log") # loggerのログレベル設定(ハンドラに渡すエラーメッセージのレベル) logger.setLevel(logging.DEBUG) # handlerの生成 stream_handler = StreamHandler() # handlerのログレベル設定(ハンドラが出力するエラーメッセージのレベル) stream_handler.setLevel(logging.DEBUG) # ログ出力フォーマット設定 handler_format = Formatter('[%(levelname)s]\t%(asctime)s : %(message)s') stream_handler.setFormatter(handler_format) # loggerにhandlerをセット logger.addHandler(stream_handler) # ログ出力 logger.error("ERROR") logger.warning("WARN") logger.info("INFO") logger.debug("DEBUG")
ファイル操作
ファイル読み込み
file_name = 'hoge.csv' with open(file_name) as f: for line in f: cols = line.split(",") print(cols[0].strip())
- strip()しないと、最後のカラムに改行も含まれてしまう。
ファイル書き込み
file_name = 'dest.txt' with open(file_name, mode='w') as f: f.write(s)
AWS Lambdaでdatetimeを使うときにコンテナが再利用される罠
lambdaのpythonでdatetime
を使おうとしてコードを書いて、いざ動かしてみると、どうもちょっとおかしい。
明らかにおかしいというよりは時折おかしくなることがある。
これが逆に厄介でした。
原因は、lambdaの実行コンテナのコンテキストは再利用されることがあるためでした。
こちらの公式ドキュメントに詳しく書いてあります。
たとえば、Lambda 関数がデータベース接続を確立する場合、連続した呼び出しでは接続を再確立する代わりに元の接続が使用されます。接続を作成する前に接続が存在するかどうかを確認するロジックをコードに追加することをお勧めします。
DB接続なんかの情報も再利用されるとのことで、いつかつまづきそうな気がするので書いておく。
datetimeも、先頭の方で定義しておくだけだと、ずっとそれが使い回されるようです。
じゃあ、どうすればいいか。
こちらの記事のコメントにありました。
lambda_handler関数の中で逐一定義してあげればいいのだそうです。
本当かどうか、検証コード書いて試してみます。
import json from datetime import datetime dt_global = datetime.now() def lambda_handler(event, context): dt_inside = datetime.now() dt_inside_str = dt_inside.strftime('%Y-%m-%d %H:%M:%S') dt_global_str = dt_global.strftime('%Y-%m-%d %H:%M:%S') # こちらは毎実行ごとに取得される print(f"dt_inside: {dt_inside_str}") # こちらはコンテナが再利用される限り変更されない print(f"dt_global: {dt_global_str}") return ''
確かに、テスト実行を連打してみると、dt_global
の方は更新されていないのに、dt_inside
は毎回更新されています。
これで1ヶ月くらいずっと正常に動いてたと思っていたlambdaがおじゃんになりました〜
AWS SSMセッションマネージャーでvimのインサートモードから抜けられない問題
会社でAWS SSMを使って開発をしてたのが初めてだったのですが、罠にハマりました。
ブラウザからsshつなぐっていう感じの認識で、あまり深い理解はしていないのですが、とりあえずsshみたいに使えるもんだと思ってやってましたが、vimでハマりました。
vimでインサートモードになってから、ECSを押してもノーマルモードに戻れません。
詳しく説明すると、ECSを押した瞬間、ブラウザの中のssh画面の入力にフォーカスがあたっている部分から外れてしまう状態です。
vim中のECSとして認識されるというよりは、ブラウザに対してのECSとして認識されているようです。
これに1〜2時間位格闘した末、ブラウザから使うssmは諦めてターミナルから普通にsshすることにしました。
後日わかったのですがこれ、chromeのvimライクに操作できるようにする拡張機能"vimium"、これが原因でした。
これのせいでECSが謎のブラウザに対してのECSコマンドとして認識されてしまっていたのだっった。。。
これに限らず、同僚曰く「vimiumのプラグインはメリットよりも予期せぬ不具合によるデメリットの方が大きい」とのことだったので、もともとそんなフル活用できていなかったのでこれを機にやめてみたいと思います。