物理の駅 by onsanai

Physics Station → PhSt 質問・疑問・間違いの指摘は、コメントに書くか、直接伝えるときっと良いことがあります。主にWindows or Ubuntu用の記事です

PowerShellのGet-ContentはStringではなくObject[]=配列を返す

よく考えたら当たり前なのかもしれないけど、初めてなのでハマった

PS C:\Users\Administrator\Desktop> $content = (Get-Content "path.txt" -last 11)
PS C:\Users\Administrator\Desktop> $content.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array


PS C:\Users\Administrator\Desktop> $content_str=""
PS C:\Users\Administrator\Desktop> foreach($c in $content){$content_str+=$c+"`n"}
PS C:\Users\Administrator\Desktop> $content_str.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

そりゃ、帰ってきた値に改行コードが含まれてないわけだ。

Windows + Jupyter Labで拡張機能をインストールする

nodejsをインストールする。12.16.1 LTSで良い。

nodejs.org

qiita.com

例えば、Table of Contentsをインストールしてみる

  1. 拡張機能 パズルのピースっぽいマークを選択。なければSettings->Enable Extension manager (Experimental)をクリック
  2. toc を検索
  3. @jupyterlab/toc が出てくるので、Installをクリック
  4. Rebuildをクリック

f:id:onsanai:20200325113857p:plain

  1. はしばらくかかる。リビルドが終わるとポップアップが出てくる。

Visual Studio 2019 16.6でファイルシステムReFS上のstd::filesystem::removeが正しく動くようになった

Visual Studio 2019 プレビュー版の16.6が3月16日に公開されていたので、先日報告した件が修正されているか試した。

phst.hateblo.jp

docs.microsoft.com

#include <filesystem>
#include <iostream>
#include <fstream>
#include <stdio.h>

int main(int argc, char** argv) {
    std::error_code ec;
    std::ofstream ofs1(std::string(argv[1]) + "/a.tmp");
    ofs1.close();
    std::cout << ec.value() << " " << ec.message() << std::endl;

    std::filesystem::remove(std::string(argv[1]) + "/a.tmp", ec);
    std::cout << ec.value() << " " << ec.message() << std::endl;

    std::ofstream ofs2(std::string(argv[1]) + "/a.tmp");
    ofs2.close();
    std::cout << ec.value() << " " << ec.message() << std::endl;

    std::filesystem::rename(std::string(argv[1]) + "/a.tmp", std::string(argv[1]) + "/b.tmp", ec);
    std::cout << ec.value() << " " << ec.message() << std::endl;

    remove((std::string(argv[1]) + "/b.tmp").c_str());
    std::cout << ec.value() << " " << ec.message() << std::endl;
    return 0;
}

HドライブのファイルシステムはReFSである。

16.6でコンパイルしたとき

PS C:\Users\Administrator\Desktop> .\VSTest.exe H:
0 この操作を正しく終了しました。
0 この操作を正しく終了しました。
0 この操作を正しく終了しました。
0 この操作を正しく終了しました。
0 この操作を正しく終了しました。

16.5でコンパイルしたとき

PS C:\Users\Administrator\Desktop> .\VSTest.exe H:
0 この操作を正しく終了しました。
50 この要求はサポートされていません。
50 この要求はサポートされていません。
0 この操作を正しく終了しました。
0 この操作を正しく終了しました。

正しく修正されている。正式リリースが待ち遠しい。

Ubuntu 18.04 LTS でSwapをオフ・オンにする

sudo swapoff -a で全てのSwapをオフにできる

実行例

$ free
              total        used        free      shared  buff/cache   available
Mem:      263780492   255330568     1012936       20260     7436988     6640228
Swap:       2097148      560720     1536428
$ sudo swapoff -a
[sudo] password for administrator:
$ free
              total        used        free      shared  buff/cache   available
Mem:      263780492   240880644    14408928       30200     8490920    21090140
Swap:             0           0           0

Swapをオンにする場合は sudo swapon -a で良い。

$ free
              total        used        free      shared  buff/cache   available
Mem:      263780492   247228928     1057056       30200    15494508    14701708
Swap:             0           0           0
$ sudo swapon -a
[sudo] password for administrator:
$ free
              total        used        free      shared  buff/cache   available
Mem:      263780492   247920988     1176664       30200    14682840    14008940
Swap:       2097148         256     2096892

Pythonで引数付きのマルチスレッドとマルチプロセスを簡単に実装する

concurrent.futuresThreadPoolExecutor と、 ProcessPoolExecutor を使うのがセオリーだろう。 スレッド内、プロセス内で例外が出たらprintする機能、スレッドやプロセスを順番に回収して残りスレッド数・プロセス数を表示する機能を実装してある。 使い方は __main__ を参考にして欲しい。

import time
import random
import concurrent.futures
from logging import StreamHandler, Formatter, INFO, getLogger


def test_func(i):
    import random
    time.sleep(3 + random.random() * 3)
    if i % 5 == 4:
        raise Exception("Error: i % 5 == 4")


def init_logger():
    handler = StreamHandler()
    handler.setLevel(INFO)
    handler.setFormatter(Formatter("[%(asctime)s] %(message)s"))
    logger = getLogger()
    if not logger.hasHandlers():
        logger.addHandler(handler)
        logger.setLevel(INFO)


def multi_process(func, max_workers, targets):
    init_logger()
    getLogger().info("multi_process begin")

    with concurrent.futures.ProcessPoolExecutor(max_workers=max_workers) as executor:
        futures = [executor.submit(
            func, *target if type(target) == tuple else (target,)) for target in targets]

        while len(futures) != 0:
            futures_buf = []
            done_flag = False
            for f in futures:
                if f.done():
                    if f.exception() != None:
                        print(f.exception())
                    done_flag = True
                else:
                    futures_buf.append(f)
            if done_flag:
                getLogger().info(
                    f"multi_process {len(futures_buf)} tasks rest")
            futures = futures_buf
            time.sleep(0.01)

    getLogger().info("multi_process end")


def multi_thread(func, max_workers, targets):
    init_logger()
    getLogger().info("multi_thread begin")

    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = [executor.submit(
            func, *target if type(target) == tuple else (target,)) for target in targets]

        while len(futures) != 0:
            futures_buf = []
            done_flag = False
            for f in futures:
                if f.done():
                    if f.exception() != None:
                        print(f.exception())
                    done_flag = True
                else:
                    futures_buf.append(f)
            if done_flag:
                getLogger().info(f"multi_thread {len(futures_buf)} tasks rest")
            futures = futures_buf
            time.sleep(0.01)

    getLogger().info("multi_thread end")


if __name__ == "__main__":

    multi_process(test_func, max_workers=4, targets=range(10))
    multi_thread(test_func, max_workers=4, targets=range(10))