VS Codeでvenvがうまく動作しなくなった話

結論 venvをあきらめて、Pipenvを導入すればなぜか解決した。 経緯 Pythonの開発環境にVS Codeを使っていましたが、ある日突然、venvで作った環境が見えなくなりました。 PowerShellからは切り替えができるので、venv自体は正しく動いているようでした。 PythonとVS Codeをクリーンインストールしても状況は変わりませんでした[1]。 Pipenvの使い方 最近はPipenvというものがあるらしいので、それを導入することとしました[2][3]。 pip install pipenv 以下のように環境変数を設定することで、プロジェクトのフォルダ直下に仮想環境を構築してくれます。 PIPENV_VENV_IN_PROJECT=true VS Code上にフォルダを作成し、その直下で仮想環境を作成します。 コマンドはVS Code上のPowerShellで行いました。 例えば以下のようになります。パスやPythonのバージョンはご自身の環境に合わせてください。 *pythonの後に半角スペースがあるのでうっかり詰めないでください。 *venvファイルが作成されるという情報もありますが、私の場合はPipfileのみ作られました。 PS PS C:\Users\User Name\Documents\CODE\Python\Test> pipenv install --python 3.8 VS Code上でF1キーを押して、「reload」を検索して実行します。 これで左下のPythonのバージョンセレクトから環境選択できるはずです。 仮想環境から抜けるときは以下のコマンドを使います。 deactivate 参考文献 [1] sota0726 「VScodeを完全にアンインストールする方法(windows10)「拡張機能のホストが予期せずに終了しました。」を改善するために」閲覧日:2020/09/13 https://www.atmarkit.co.jp/ait/articles/1810/12/news026.html [2] KRiver1 「pyenv、pyenv-virtualenv、venv、Anaconda、Pipenv。私はPipenvを使う。」閲覧日:2020/09/13 h

Python:ビット演算

 こんばんは。今回もPythonです。

最近は、苺サーボ(PRS-40M)をPythonから制御しています。
昔はマイコンから制御して実験していたのですが、Pythonだと効率良く開発が進みます。
その時にハマった、C言語辺りからPythonに入った人が陥りやすい罠ついて書きます。

コマンド式サーボモータはコマンド生成や、データを読み込む時によくビット演算を用います。
負の値として苺サーボは二の補数表現を用いています。
これは1の負数である-1を表現するなら以下のようにな流れになります。

① ビット反転する
② 反転した数字から1を足す

これを実際にPythonで実行します。


>>> ~1 + 1
-1


正しそうな値が出てきました。

次に、苺サーボの現在位置を複合してみます。(苺サーボは現在位置を16bitのデータとして送ってくる。)
複合の手順は逆にたどり最後にマイナスを掛けます。
① 値から1引く
② ビットを反転する
③ 値に-1を掛ける(複合した値は正の数のため)

それでは実際に負の限界値である-3600(二の補数表現で61936)を複合します。


>>> ~(61936 - 1)
-61936


①と②を実行しただけでもうすでにおかしいです。
負の値になっています。何が問題なのでしょうか。
疑問としては桁数が不明なPythonでどのよにビット反転をしているのでしょうか?
二の補数表現は一番上位のビットを1にする決まりですが、一番上位とは変数のサイズが決まらないPythonでは表現できません。

そこでPythonではビット反転演算を以下のように定義しいるそうです。


-(値 + 1)


これなら納得です。最初の値が合って、現在位置の複合がうまく行かない理由がわかります。
実際には何が悪いのかわからずかなり戸惑いました。
C言語上がりの私には、こんな罠があるとは思いもしませんでした。

そこでビット反転はXORを使ってやることにします。


>>> -((61936 - 1) ^ 0xFFFF)
-3600


現在位置は16bitとわかっているので、0xFFFFでビット反転することが出来ます。



1111 0001 1111 0000 :-3600の二の補数表現
1111 0001 1110 1111 :-1した値

1111 1111 1111 1111 :0xFFFF

0000 1110 0001 0000 :XORした値(1がひとつだけあるところは1)


以上がビット演算の流れです。
Pythonではビット反転をするときはXORを使って反転するしかなさそうです。
知っていればハマりませんが、思い込むとなかなか抜けられなくて苦労しました。

今回は以上です。

2012/10/01 追記
せっかくなので、負値を二の補数表現に変換するプログラムも記述しておきます。
-3600という値を二の補数表現にします。


>>> p = -3600
>>> (-p ^ 0xFFFF) + 1
61936


これで上記の二の補数表現と同じになりました。

コメント

このブログの人気の投稿

C++11のためにGCCの最新版をインストールする

分解:Logicool M570

MOCO'Sキッチンのフォントに似せるβ版