Ubuntu 18.04でsleepする方法は以下のとおりです。なお、正しくは"sleep"ではなく"suspend”というそうです。
- Winキーを押す
- "sleep" または "suspend" とキーボードに打ち込む
- 途中で「サスペンド」というアイコンが出てくるので、選択する
10日前まで開催されていたKaggleのSanta's Workshop Tour 2019に参加していました。結果は1620チーム中の142位。Kaggleで初めてのメダルであるブロンズメダルを獲得できました。最適化系のコンテストなのに問題のサイズが小さく、コンテストの序盤から最適解にたどり着く人が徐々に増えていく展開。しかも最適解にたどり着いた人は皆Gurobi や CPLEXなどの商用最適化ソルバを使っているらしいことがわかり、途中で戦意喪失しました。
5000個のファミリーをday1からday100までのいずれかに割り振り、あるコストを最小化する最適化問題です。
各ファミリーには以下の情報が与えられます。
コストは以下の2つの和として計算されます。
基本的には、以下の繰り返しでした。
最終スコアである69410.61には以下のようにして到達しました。
焼きなましで最適解に近づけないかと試行錯誤しましたが、うまくいきませんでした。最適解の割当結果を見るとちょうど125人である日がもう一日多かったのですが、そのような分布を焼きなましで作ることは相当難しいようでした。
Windows Subsystem for Linux (WSL) で動かしているUbuntu 16.04にてscreenを動かそうとすると以下のエラーが出ました。
$ screen Cannot make directory '/var/run/screen': 許可がありません
screenが使用するディレクトリを環境変数で指定する方法があります。例えば~/.screendirをそのディレクトリとして指定するとします。以下のコマンドでディレクトリを用意します。
$ mkdir ~/.screendir $ chmod 700 ~/.screendir
そして、以下に示す環境変数の指定を、.bashrcや.zshrcなどに書けばOKです。
export SCREENDIR=$HOME/.screendir
ベストではない解決策としては/var/run/screen
ディレクトリを作成する方法があります。
$ sudo mkdir /var/run/screen $ sudo chmod 777 /var/run/screen
この方法で一時的にscreenを使うようになりますが、OSを再起動すると/var/run/screen
ディレクトリが消えてしまうので、根本的な解決にはなっていません。
Windows 10で導入されたWindows Subsystem for Linux (WSL) を使ってインストールしたLinuxのホームディレクトリの場所を調べるには、コンソールでホームディレクトリに移動したあと
$ explorer.exe .
とすればよいです。
WSLで導入しているUbuntu 16.04から上記コマンドを打ったところ、
\\wsl$\Ubuntu\home\(ユーザ名)
がエクスプローラーで開きました。
WSL Update Lets You Access Linux Files in Windows Explorer - OMG! Ubuntu! によると、この機能はWindows 10 Version 1903から加わったもので、9P protocolという仕組みを使って実現されているそうです。
Windowsのバージョンを調べるには、Win + Rで出てくるウィンドウにwinver
と入力してください。
robocopyというコマンドを使って、Windowsでタイムスタンプを保持してフォルダまるごとコピーするときの自分用メモです。
基本コマンドは以下の通り。(src)と(dst)にはそれぞれコピー元フォルダ、コピー先フォルダを入れてください。
robocopy (src) (dst) /E /COPY:DAT /DCOPY:DAT /r:3 /w:1 /LOG:copy.log /xd "$RECYCLE.BIN" /xd "System Volume Information"
他のオプションの意味は以下の通り。
/E
: 空のディレクトリもコピー/COPY:DAT
: ファイルのデータ、属性、タイムスタンプをコピー/DCOPY:DAT
: ディレクトリのデータ、属性、タイムスタンプをコピー/r:3 /w:1
: コピー不能なファイルがあったとき、3回リトライ。リトライの間隔は1秒。デフォルト値の設定だとリトライが終わらない。/LOG:copy.log
: ログをcopy.logファイルに保存/xd "$RECYCLE.BIN"
: ごみ箱はコピー対象から外す/xd "System Volume Information""
: 隠しシステムフォルダはコピー対象から外すrobocopy.batというバッチファイルを作って、その中でrobocopyを呼び出すと、robocopyコマンドではなくrobocopy.batが呼び出されてしまうので、無限ループに陥ってしまいます。バッチファイルの名前を変えましょう。
コピー元をドライブ、コピー先をフォルダとすると、なぜかコピー後にコピー先のフォルダが見えなくなる現象が発生しました。以下にそのときの状況を記します。
使ったコマンドは以下です。ここで、 コピー前にはC:\dir1が存在していてC:\dir1\dir2が存在していない状態でした。
robocopy E:\ C:\dir1\dir2 /E /COPY:DAT /DCOPY:DAT /r:3 /w:1 /LOG:copy.log /xd "$RECYCLE.BIN" /xd "System Volume Information"
コピーは行われたのですが、なぜかC:\dir1\dir2フォルダに隠し属性がついていて、エクスプローラーから見えませんでした。恐ろしいことに、エクスプローラーのオプションで「隠しファイル、隠しフォルダー、および隠しドライブを表示する」を有効にしていたとしても、コピー先のフォルダは見えません。エクスプローラーのオプションで「保護されたオペレーティング システム ファイルを表示しない(推奨)」を庵チェックすることでようやくコピー先のフォルダが見えるようになります。
ちなみにCygwinからは何もしなくてもコピー先のフォルダが見えました。
どうも After Robocopy, the copied Directory and Files are not visible on the destination Drive - Stack Overflow で説明されているように、あるドライブのルートを、あるフォルダにコピーしようとしたときに、コピー先のフォルダが見えなくなることがあるようです。
この現象を回避するには、robocopyに
/A-:SH
というオプションをつければOKです。
すでにコピーが終わってしまったあとでも手はあります。コピー先のフォルダに対して
attrib -h -s C:\dir1\dir2
とすれば、隠しフォルダを普通のフォルダに戻せます。
wgetで2.4GBほどある大きなファイルを取得しようとしたとき、以下のようにsegmentation fault (core dumped)が出ました。
$ wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.243_418.87.00_linux.run (略) HTTP による接続要求を送信しました、応答を待っています... 200 OK 長さ: 2572375299 (2.4G) [application/octet-stream] `cuda_10.1.243_418.87.00_linux.run' に保存中 cuda_10.1.243_418.87.00_linux.run 94%[==========================================================================================================> ] 2.27G --.-KB/s 残り1m 49s zsh: segmentation fault (core dumped) wget
今回の場合、wgetの--continue
フラグを使ってファイルを取得を途中からやり直すことで、無事完走することができました。
$ wget --continue http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.243_418.87.00_linux.run (略) HTTP による接続要求を送信しました、応答を待っています... 206 Partial Content 長さ: 2572375299 (2.4G), 129407427 (123M) 残っています [application/octet-stream] `cuda_10.1.243_418.87.00_linux.run' に保存中 cuda_10.1.243_418.87.00_linux.run 100%[+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=====>] 2.40G 786KB/s 時間 1m 52s 2019-10-27 19:29:53 (1.11 MB/s) - `cuda_10.1.243_418.87.00_linux.run' へ保存完了 [2572375299/2572375299]
Pythonのコード改善のためのツール5つを試してみた - minus9d's diary の中で個人的にもっともよさそうだと感じたflake8について、使い方を詳しく調べました。
$ pip install flake8
$ flake8 --version
すると、flake8のバージョンと、インストール済のflake8のプラグインの一覧が出てきます。以下に例を示します。
$ flake8 --version 2.6.2 (pycodestyle: 2.0.0, mccabe: 0.5.3, pyflakes: 1.2.3) CPython 3.6.4 on Windows
これはflake8のプラグインを何も入れていない状態での表示例です。ここで表示されるpycodestyle
, mccabe
, pyflakes
が、flake8が初めから備える基本の3点セットです。pycodestype
は「PEP8のスタイル」を、mccabe
は「複雑度」を、pyflakes
は「エラー解析」をチェックしてくれるものです。
もしあなたが過去にflake8のプラグインをインストールしているとすると表示量が増えます。例えば以前にflake8のプラグインhacking
, flake8-import-order
, flake8-docstring
を以下のコマンド
$ pip install hacking $ pip install flake8-import-order $ pip install flake8-docstrings
でインストールしていたとすると、--version
で表示されるのは以下のようになります。
$ flake8 --version 2.6.2 (pycodestyle: 2.0.0, mccabe: 0.5.3, ProxyChecker: 0.0.1, hacking.core: 0.0.1, pyflakes: 1.2.3, import-order: 0.18, flake8-docstrings: 1.3.0, pydocstyle: 2.1.1) CPython 3.6.4 on Windows
以下ではプラグインは何も入れていないものとして話を進めます。
コードの解析方法は2つあります。1つ目は、以下のように特定のファイルを指定する方法。
$ flake8 sample.py
2つ目は、ディレクトリを指定する方法。
$ flake8 /path/to/dir
以下のPython 3コードをsample.py
という名前で保存して
import time import sys import fractions def func1(varA,varB): '''return sum of a and b''' varC = 42 return (varA + varB) print(func1(fractions.Fraction(1, 2), fractions.Fraction(1, 3))) 3 + 5 sys.exit(0)
$ flake8 sample.py
でコード解析した結果は以下になります。
sample.py:1:1: F401 'time' imported but unused sample.py:5:1: E302 expected 2 blank lines, found 1 sample.py:5:15: E231 missing whitespace after ',' sample.py:7:5: F841 local variable 'varC' is assigned to but never used
読み方は、"ファイルパス":行番号":"列番号":"コード":エラー内容 です。 コードの詳細は Warning / Error codes — flake8 2.6.0 documentation を参照してください。
--show-source
オプションを付けると、ソースコードの該当部分もあわせて表示してくれます。
$ flake8 --show-source sample.py sample.py:1:1: F401 'time' imported but unused import time ^ sample.py:5:1: E302 expected 2 blank lines, found 1 def func1(varA,varB): ^ sample.py:5:15: E231 missing whitespace after ',' def func1(varA,varB): ^ sample.py:7:5: F841 local variable 'varC' is assigned to but never used varC = 42 ^
さらに--show-pep8
オプションを付けると、PEP8のルールを表示してくれます。いちいちメッセージの意味を調べる必要がなくて便利です。
$ flake8 --show-source --show-pep8 sample.py sample.py:1:1: F401 'time' imported but unused import time ^ sample.py:5:1: E302 expected 2 blank lines, found 1 def func1(varA,varB): ^ Separate top-level function and class definitions with two blank lines. Method definitions inside a class are separated by a single blank line. Extra blank lines may be used (sparingly) to separate groups of related functions. Blank lines may be omitted between a bunch of related one-liners (e.g. a set of dummy implementations). Use blank lines in functions, sparingly, to indicate logical sections. Okay: def a():\n pass\n\n\ndef b():\n pass Okay: def a():\n pass\n\n\nasync def b():\n pass Okay: def a():\n pass\n\n\n# Foo\n# Bar\n\ndef b():\n pass Okay: default = 1\nfoo = 1 Okay: classify = 1\nfoo = 1 E301: class Foo:\n b = 0\n def bar():\n pass E302: def a():\n pass\n\ndef b(n):\n pass E302: def a():\n pass\n\nasync def b(n):\n pass E303: def a():\n pass\n\n\n\ndef b(n):\n pass E303: def a():\n\n\n\n pass E304: @decorator\n\ndef a():\n pass E305: def a():\n pass\na() E306: def a():\n def b():\n pass\n def c():\n pass sample.py:5:15: E231 missing whitespace after ',' def func1(varA,varB): ^ Each comma, semicolon or colon should be followed by whitespace. Okay: [a, b] Okay: (3,) Okay: a[1:4] Okay: a[:4] Okay: a[1:] Okay: a[1:4:2] E231: ['a','b'] E231: foo(bar,baz) E231: [{'a':'b'}] sample.py:7:5: F841 local variable 'varC' is assigned to but never used varC = 42 ^ Indicates that a variable has been explicitly assigned to but not actually used.
PEP8で決められている1行79文字制限が厳しすぎると感じる場合は--max-line-length
オプションで制限を緩和できます。
$ flake8 --max-line-length=100 sample.py
既存コードを修正してコミットするとき、既存部分のスタイル違反はいったん見て見ぬふりをして、自分が修正した部分だけにflake8でチェックをかけたいことがあります。そのときに使えるのが--diff
オプションです。git diff
の結果を以下のようにパイプで受けます。
$ git diff sample.py | flake8 --diff
--max-complexity N
(Nは整数)をつけると、コードの複雑度(具体的にはサイクロマチック数)が閾値Nを超えている場合に、警告を出せるようになります。使い方の例は以下です。
$ flake8 --max-complexity 12 sample.py
flake8による解析を行いたくないファイルには、
# flake8: noqa
という行を追加します。
flake8による解析を行いたくない行には、行末に# noqa
を付けます。noqa
とはno quality assurance
の略だそうです。
noqa
を無視して解析をかけるには--disable-noqa
オプションを使います。
特定のルールを無視したいときは--ignore
を使います。例えば以下のようにするとE1, E23, or W503で始まるルールを無視できます。
$ flake8 --ignore=E1,E23,W503 sample.py
逆に、特定のルールだけを有効にしたいときは--select
を使います。例えば以下のようにするとEで始まるルールだけが有効になります。
$ flake8 --select=E sample.py
指摘点を自動修正する機能はflake8にはないようです。autopep8, black, yapfなどのツールを使ってください。(参考:formatting - How do I autoformat some Python code to be correctly formatted? - Stack Overflow)