【Haskell】【Stack】Encountered error while migrating Pantry database
stackでHaskell入門していたら stack build
時に下のようなエラーに遭遇しました。
Encountered error while migrating Pantry database: SQLite3 returned ErrorNotFound while attempting to perform step: database disk image is malformed Please report this on https://github.com/commercialhaskell/stack/issues As a workaround you may delete Pantry database in /Users/dyoshikawa/.stack/pantry/pantry.sqlite3 triggering its recreation. cp: /bin/bootstrap: No such file or directory make: *** [all] Error 1
As a workaround you may delete Pantry database in /Users/dyoshikawa/.stack/pantry/pantry.sqlite3 triggering its recreation.
cp: /bin/bootstrap: No such file or directory
とあるので何らかの操作で ~/.stack/pantry/pantry.sqlite3
の内容がおかしくなってしまった際に発生するっぽい。
この通りにファイルを削除してみます。
rm ~/.stack/pantry/pantry.sqlite3
これで一旦解決しました。
【Ubuntu 20.04】トップバー (画面上部) に日付と時刻が出ていない場合の対処
設定をずっと見てたんですが indicator-datetime
をインストールする必要があったみたいです。
盲点。
sudo apt install indicator-datetime
さらにUbuntu Tweaksというのを入れるとより詳細に設定できるようです。
【boto3】DynamoDBの自動テストで使えるかもしれないスニペット
LocalStackのようなエミュレータを活用したテストコードでよく使うやつ。
- Python 3.8.3
- boto3 1.16.14
- pytest 6.1.2
ここで記載するサンプルメソッドは下のようなクラスに所属している前提になります。
import boto3 import mypy_boto3_dynamodb.service_resource as dynamodb_resources class DynamoDefiner: dynamo: dynamodb_resources.DynamoDBServiceResource def __init__(self, endpoint_url: str = None): dynamo: dynamodb_resources.DynamoDBServiceResource = boto3.resource( "dynamodb", endpoint_url=endpoint_url ) self.dynamo = dynamo
テーブルがない場合は作成
def create_my_table(self, table_name: str) -> None: # すでにテーブルがあるかチェック (二重にテーブルを作成しようとするとエラーになるため) tables = list(self.dynamo.tables.all().__iter__()) if list(filter(lambda t: t.name == table_name, tables)): # すでにある場合は終了 return self.dynamo.create_table( TableName=table_name, KeySchema=[ {"AttributeName": "partition_key", "KeyType": "HASH"}, {"AttributeName": "sort_key", "KeyType": "RANGE"}, ], AttributeDefinitions=[ {"AttributeName": "partition_key", "AttributeType": "S"}, {"AttributeName": "sort_key", "AttributeType": "S"}, ], BillingMode="PAY_PER_REQUEST", # GSI貼る場合 GlobalSecondaryIndexes=[ { "IndexName": "sort_key-index", "KeySchema": [ {"AttributeName": "sort_key", "KeyType": "HASH"}, ], "Projection": { "ProjectionType": "ALL", }, }, ], )
テーブルのItemを全件削除
def clear_my_table(self, table_name: str) -> None: my_table = self.dynamo.Table(table_name) # scanでItems取得 scanning_result = my_table.scan() items = scanning_result["Items"] # 0件なら終了 if not items: return # scanで取得したItemsを全件削除 # TODO batch_writeに変えたら高速化できそう for item in items: shop_table.delete_item( Key={"shop_id": item["shop_id"], "sort_key": item["sort_key"]} ) # 再帰 self.clear_shop_table(table_name)
1回のscanで全件取得できるとは限らないため、取得しきれなかった場合は再帰呼び出しで繰り返すようにしています。
使い方
テストフレームワークはpytest、DynamoエミュレータはLocalStackを使用しているものとします。
setupでテスト毎に
- テーブルがなければ作成
- テーブルのクリア
をします。
import boto3 import mypy_boto3_dynamodb.service_resource as dynamodb_resources class TestShopDynamoRepository(object): def setup_method(self) -> None: dynamoDefiner = DynamoDefiner(endpoint_url="http://localhost:4566") dynamoDefiner.create_shop_table("my-table") dynamoDefiner.clear_shop_table("my-table")
こうすると前のテストの状態に依存しないように各テストを実施できます。
参考
【Python】Pythonプロジェクトで良い感じに使えるMakefile
僕はこうしてます。
- Python 3.8.3
- Poerty 1.1.4
- pytest 6.1.2
- black 20.8b1
- flake8 3.8.4 (mccabe: 0.6.1, pycodestyle: 2.6.0, pyflakes: 2.2.0)
- mypy 0.790
lint: poetry run black --check ./src ./tests poetry run flake8 ./src ./tests --exclude __init__.py --ignore E402,E501,W503 poetry run mypy ./src ./tests --config-file ./mypy.ini test: poetry run pytest ./src ./tests export: poetry export --output requirements.txt vendor: pip -r requirements.txt -o vendor
【pytest】E ModuleNotFoundError: No module named 'src'
Pythonのモジュール解決周りは難解ですね・・・
- Python 3.8.3
- Poerty 1.1.4
- pytest 6.1.2
$ poetry run pytest ./src ./tests ImportError while importing test module 'project_dir/tests/foo/test_bar.py'. Hint: make sure your test modules/packages have valid Python names. # 省略 E ModuleNotFoundError: No module named 'src'
project_dir ├ src │ └ foo │ └ bar.py └ tests └ foo └ test_bar.py # ここでエラー
# project_dir/src/tests/foo/test_bar.py from src.foo.bar import Bar # 以下省略
この from src...
の src
が見つけられないようです。
原因ですが、pytestはデフォルトで test*
を満たすファイル名を探して実行しようとします。
そのため test*
の名前のファイルが1つもない src
下をロードできていないのではないかと考えました。
解決策として、 src
ディレクトリ直下に test*
を満たす適当なファイルを作成します。
今回は test_init.py
としました。
pytestにロードさえしてもらえれば良いのでファイルの中身は空です。
project_dir ├ src │ ├ test_init.py # 空ファイルを追加 │ └ foo │ └ bar.py └ tests └ foo └ test_bar.py # ここでエラー
そうするとちゃんと src
を読んでもらえるようになりました。
【mypy】Cannot find implementation or library stub for module named 'foo.bar'
- Python 3.8.3
- Poerty 1.1.4
- mypy 0.790
$ poetry run mypy ./src src/foo/__init__.py:1: error: Cannot find implementation or library stub for module named 'src/foo/bar' src/foo/__init__.py:1: note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
こんなエラーが出ました。
この時のディレクトリ構成は下記。
project_dir └ src └ foo ├ __init__.py # ここでエラー └ bar.py
この __init__.py
の内容はこんな感じ。
# project_dir/src/foo/__init__.py from src.foo.bar import Bar
ちゃんとsrc直下にも __init__.py
を置いてあげないとmypyが辿れないようです。
project_dir └ src ├ __init__.py # 追加 └ foo ├ __init__.py └ bar.py
新しく作成した __init__.py
の内容は空で良いです。
$ poetry run mypy ./src Success: no issues found in xx source files
解決しました。
【AtCoder】abc179 C - A x B + C
解説動画を見ながら自分なりに噛み砕いたメモ。
A * B + C = N
式変形するとこうなる。
C = N - A * B
つまり、CはAとBが決まれば自動的に決まる。
なのでAとBの組み合わせだけを考えれば良いという状態に持っていきたい。
A * Bの範囲を確定させたいので、Cの値について考える。
まずCの値が0の場合、これはNG。
A, B, Cいずれも正整数という制約があり、0は正整数ではないから。
なのでCに入り得る最小の値は1なので、これを最初の式に代入すると、
A * B + 1 = N A * B = N - 1
よって、
1 <= A * B <= N - 1
がいえる。
(ちなみに、Cは 1 <= C <= N - 1
)
ここでAに最小の正整数1を代入してみる。
1 <= 1 * B <= N - 1
この場合は、Bの範囲は
1 <= B <= N - 1
になる。
続いてA = 2の場合。
1 <= 2 * B <= N - 1
だから、Bの範囲は
1 <= B <= (N - 1) / 2
となる。
これはNにも具体的な数値を代入して考えてみるとわかりやすい。
もし N = 10 の場合、
1 <= 2 * B <= 10 - 1 1 <= 2 * B <= 9
となり、Bの範囲は 9 / 2 の商の小数点切り捨てが最大となるのがわかるはず。
1 <= B <= 9 / 2 1 <= B <= 4
考察の材料が揃ってきたので、AにもBにも代入せずに考えると、
1 <= A * B <= N - 1
Bについて、
1 <= B <= (N - 1) / 2
と一般化できる。
あとは、Aが取り得る全ての値について考え、合算すると答えになる。
Aの範囲は
1 <= A <= N - 1
なので、コードは下記のようになる。
#include <iostream> typedef long long ll; int main() { ll n; cin >> n; auto res = 0; for (auto a = 1; a <= n - 1; a++) { res += (n - 1) / a; } cout << res << endl; return 0; }