OmniAICreator/Qiita-1.07M huggingface dataset:
Webデザインに使えるアイコンのサイト

![スクリーンショット 2022-08-12 11.04.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/9e5880bf-942a-630c-0d36-f4fc1ef62b6b.png)
（https://icons8.jp/icons/fluency-systems-regular）
Icons8.jp / windows 11 Outline

（143 アイコン）
https://icon-icons.com/ja/pack/Bitsies-icons/412
![スクリーンショット 2022-08-10 15.51.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/315afc67-573d-18d4-6569-b7f756569dcf.png)


**フラットアイコン**

https://icon-icons.com/ja/%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B3%E3%83%91%E3%83%83%E3%82%AF?style=3
![スクリーンショット 2022-08-10 15.58.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/fd171f91-e2f7-69e1-959d-aa1deb92b55f.png)

https://icon-icons.com/ja/%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B3%E3%83%91%E3%83%83%E3%82%AF?style=3
![スクリーンショット 2022-08-10 16.01.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/97486c9a-0e35-90eb-e00e-8070286a8577.png)

**Long shadow**
https://icon-icons.com/ja/%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B3%E3%83%91%E3%83%83%E3%82%AF?style=8
![スクリーンショット 2022-08-10 16.06.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/a0842fc4-c738-b290-d037-a426c9090939.png)

https://icon-icons.com/ja/%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B3%E3%83%91%E3%83%83%E3%82%AF?style=8&page=2![スクリーンショット 2022-08-24 17.22.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/5f6b4314-e148-872d-e837-a769822d6c26.png)

![スクリーンショット 2022-08-10 16.05.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/9c403ef3-becf-3678-b97a-30923ae6bb5b.png)


***
http://flat-icon-design.com/

![uploading...0]()
***
pandas;queryメソッドで条件に当てはまるものを抽出

# pandasでデータ取り出し
## dfの列参照
`iloc[10,:]`→11番目の列を取ってくる
`loc
## dfからqueryで条件に当てはまるものを抽出

### 正しいコード
~~~python
df_list = [pd.read_excel('pareto_1.xlsx', index_col=0).query('TM_sum > 0.99'),pd.read_excel('pareto_2.xlsx', index_col=0).query('TM_sum > 0.99'),pd.read_excel('pareto_3.xlsx', index_col=0).query('TM_sum > 0.99'),pd.read_excel('pareto_4.xlsx', index_col=0).query('TM_sum > 0.99')]
~~~

### 間違っていたコード
~~~python
    df_all = pd.read_excel('pareto_1.xlsx', index_col=0),pd.read_excel('pareto_2.xlsx', index_col=0),pd.read_excel('pareto_3.xlsx', index_col=0),pd.read_excel('pareto_4.xlsx', index_col=0)
    df_list = [df_all.query('TM_sum > 0.99')]
~~~~

pandasのqueryメソッドで条件に当てはまるものを抽出するときは、dataframeの中じゃないと操作できないのでリストのままでは操作できない
dfの集合(タプル)でも使えないので読み込みの際にqueryを使うしかない
リスト内包表記の場合は[]の中の`pd.read_excel()`の返り値がdfなのでそのままqueryが使える

## queryを複数のファイルに適用する
### 正しいコード
~~~python
df_list = [pd.read_excel(f'pareto_{i}.xlsx', index_col=0).astype(float).query("TM_sum > 0.95") for i in range(1, 5)]
~~~
### 間違ったコード
~~~python
df_list = [pd.read_excel('pareto_1.xlsx', index_col=0).query('TM_sum > 0.99'),pd.read_excel('pareto_2.xlsx', index_col=0).query('TM_sum > 0.99'),pd.read_excel('pareto_3.xlsx', index_col=0).query('TM_sum > 0.99'),pd.read_excel('pareto_4.xlsx', index_col=0).query('TM_sum > 0.99')]
~~~
比較演算子はstring形には使えないので、`.astype(float)`を使ってデータ型を変換する。forループの書き方覚える。`range(1, 5)`は1,2,3,4を示す。0から始まることに注意。ファイル名をそのまま打つよりこっちの方が簡潔
npmインストールでpermission deniedエラーが出た時の改善方法

## 環境

MacOS Montery 12.4
node v16.16.0
npm 8.11.0

## エラーメッセージ

~~~ruby:terminal
npm ERR! path /usr/local/lib/node_modules
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall access
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib/node_modules'
npm ERR!  [Error: EACCES: permission denied, access '/usr/local/lib/node_modules'] {
npm ERR!   stack: "Error: EACCES: permission denied, access '/usr/local/lib/node_modules'",
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'access',
npm ERR!   path: '/usr/local/lib/node_modules'
npm ERR! }
npm ERR! 
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR! 


npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator (though this is not recommended).
 
npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/ユーザ名/.npm/_logs/2022-0808T08_10_21_20Z-debug.log
~~~

## 注目は5行目

`Error: EACCES: permission denied, access '〜〜'`

要約：〜〜にアクセスする権限ねぇから！！

つまり、アクセスする権限があればインストールできるということです！簡単ですね(^ ^)

# 対処方法
以下のコマンドを打つだけです。
`npm config get prefix`

入力すると、次の結果になると思います。
```
/usr/local
```

最後に、以下のコマンドを入力して自分をオーナーにします。
`
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
`

すると自分のPCのPWを求められるので、PWを入力すればOKです。

# 上記で対処できなかった人
```/usr/local```と表示されなかった人は、以下の２つの記事を参考にしてみてください。

①[npmでpermission deniedになった時の対処法[mac]](https://qiita.com/okohs/items/ced3c3de30af1035242d)
②[npmでパッケージをインストールする](https://www.storange.jp/2017/02/npm.html)


## 解決した理由
パーミッション(アクセス権)を変更したからです。
`npm config get prefix`で、npmが使用するディレクトリのパーミッションが変更されます。

そして`
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
`の、`chown -R`により、このディレクトリ以下の権限が全て変更され、ご自身がオーナーとなるのです。
知っていて当たり前-19　オブジェクトのメモリー使用量

# 知っていて当たり前-19　オブジェクトのメモリー使用量

##  `Base.summarysize()`
 
 単位はバイト

- m:n は m, n の 2 * 8 バイト，m:k:n は m, k, n の 3 * 8 バイト


```julia
Base.summarysize(1:100), Base.summarysize(1:1000), Base.summarysize(1:2:1000)
```




    (16, 16, 24)



- collect(m:n) は 40 + 8(n - m + 1)


```julia
Base.summarysize(collect(1:100)), Base.summarysize(collect(1:1000)), Base.summarysize(collect(101:1000))
```




    (840, 8040, 7240)



- 浮動小数点数


```julia
Base.summarysize(Float32(1)), Base.summarysize(Float64(3))
```




    (4, 8)



- 整数


```julia
Base.summarysize(Int8(2)), Base.summarysize(Int16(4)), Base.summarysize(Int32(4)),
Base.summarysize(Int64(3)), Base.summarysize(Int128(3)), Base.summarysize(Int(3))
```




    (1, 2, 4, 8, 16, 8)



- BigInt は精度に関わらず 16 バイト


```julia
Base.summarysize(BigInt(1)), Base.summarysize(BigInt(10000))
```




    (16, 16)



- BigFloat は精度に関わらず 80 バイト


```julia
Base.summarysize(BigFloat(1)), Base.summarysize(BigFloat(10000))
```




    (80, 80)



- 論理値は 1 バイト


```julia
Base.summarysize(Bool(1)), Base.summarysize(false)
```




    (1, 1)



- ASCII 文字列は，文字列の長さ+8 バイト


```julia
Base.summarysize("a"), Base.summarysize("ab"), Base.summarysize("abc"), Base.summarysize("abcdefghijklmnopqrstuvwxyz") 
```




    (9, 10, 11, 34)



- Unicode 文字列は，文字列の長さ*3 + 8 バイト


```julia
Base.summarysize("漢"), Base.summarysize("漢字"), Base.summarysize("漢字は")
```




    (11, 14, 17)



- 文字は 4 バイト


```julia
Base.summarysize('a'), Base.summarysize('漢')
```




    (4, 4)



- タプルはそれぞれの要素の長さの和というわけではないようだ


```julia
Base.summarysize((1, 2.9, 3)) # 3 * 8
```




    24




```julia
Base.summarysize(('a', "foo", 3))
```




    35




```julia
Base.summarysize(('a', 'b', "foo", "bar", 3))
```




    54



- 集合は要素数によらず（空集合でも）同じ 336 バイトのようだ。


```julia
Base.summarysize(Set()), Base.summarysize(Set([1, 2, 3]))
```




    (336, 336)



- 辞書はキーの数によらず（空辞書でも）同じ 456 バイトのようだ。


```julia
Base.summarysize(Dict()), Base.summarysize(Dict(:a => 1, :b => 2))
```




    (456, 456)



- ベクトルは，40 + 長さ*8 バイト


```julia
Base.summarysize([]), Base.summarysize([1]), Base.summarysize([1, 2])
```




    (40, 48, 56)




```julia

```

- 配列は，40 + 全要素数*8 バイト


```julia
Base.summarysize([1]), Base.summarysize([1 2; 3 4]), Base.summarysize([1 2; 3 4; 5 6])
```




    (48, 72, 88)
Todoアプリで Multiplatform を目指す SQLDelight を使う

前回の続きですが。

![Reflector Recording.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588914/c6166770-b97c-a7d5-af6f-d6ed56140d33.gif)
[👉 Jetpack Compose で Todo アプリを作ってみた - Qiita](https://qiita.com/chanzmao/items/2a8a65a2640dedf9a6a3)

SQLDelight を使います。

[👉 Getting Started with Multiplatform - SQLDelight](https://cashapp.github.io/sqldelight/multiplatform_sqlite/)

テキストファイルに、テーブル、クエリーをSQLで記述して、

```text
-- app/src/main/sqldelight/com/your/package/data/Todo.sq

CREATE TABLE todo (
  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  text TEXT NOT NULL,
  updated INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))
);

selectAll:
SELECT * FROM todo ORDER BY updated DESC;

count:
SELECT COUNT(id) FROM todo;

insert:
INSERT INTO todo (text) VALUES (:text);

update:
UPDATE todo SET text = :text, updated = (strftime('%s', 'now')) WHERE id = :entryId;

delete:
DELETE FROM todo
WHERE id = :entryId;
```

ビルドすると、関連テーブルやクラスが自動作成され、そのまま使えるようになります。

```kotlin
class TodoRepository @Inject constructor(
  private val database: Database
) {

  fun load(): Flow<List<Todo>> {
    return database.todoQueries.selectAll().asFlow().mapToList(Dispatchers.IO)
  }

  fun count(): Flow<Long> {
    return database.todoQueries.count().asFlow().mapToOne(Dispatchers.IO)
  }

  fun insert(text: String) {
    database.todoQueries.insert(text)
  }

  fun update(id: Long, text: String) {
    database.todoQueries.update(text, id)
  }

  fun delete(id: Long) {
    database.todoQueries.delete(id)
  }

}
```

Flow に向けて作られており、Kotlin を使ったマルチプラットフォーム向けです。


[👉 KMM や マルチプラットフォーム を見据えて SQLDelight で Repository](https://android.benigumo.com/20220808/sqldelight-repository/)
Apex replay debuggerでThe log must be generated with log categories Apex code at the FINEST level and Visualforce at the FINER level.とエラーが出る場合

# 現象
VSCodeから`SFDX: Launch Apex Replay Debugger with Current File`を行うと下記エラーが発生する場合の対処法  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484310/aae729ac-9be1-e9d3-81b5-d20b3c1c6ca0.png)

# 背景
SalesforceのDEBUG LOG設定は下記になっているのに。。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484310/74e9108f-f0f3-b917-86c9-19f085604333.png)

# 解決法
デバッグを行いたい、logファイルの一行目を確認する。

```
55.0 APEX_CODE,FINEST;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;NBA,INFO;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WAVE,INFO;WORKFLOW,INFO
```

`VISUALFORCE,INFO` を `VISUALFORCE,FINER`に変更するだけ。
IPアドレスとTCPとポート番号の違いをざっくりまとめてみた

IPアドレス、TCP、ポート番号、、、どれもITに関わっていれば少なからず聞いたことはありますが
その意味や違いをいまいち理解できていなかった、、、

というか、よく分からなくて理解できなかったので、違いをざっくりとまとめてみました(・∀・)

# 目次
- IPアドレスとは？
- TCPとは？
- ポート番号とは？
- IPとTCPとポート番号の違い
- 参考文献

# IPアドレスとは？
## そもそもIPとはなんぞや
「IP」というのは「インターネット・プロトコル」の略称です。

IPとは、複数の通信ネットワークを接続し、**互いにデータのやり取りをするための決められたルール**です。
（※ IPによって接続された世界規模のコンピュータネットワークが「インターネット」です）
ネットワーク上でなされるデータの送受信は、すべて「IP」により定められたルールで行われています。

その**決められたルールに従い、相手先にデータを送ること**がIPのお仕事です。

そして、データの届け先の相手の居場所を探し出すために必要となってくるのが、それぞれのコンピュータごとに割り当てられている「IPアドレス」となっています。


## IPアドレスとは
IPアドレスとは、「インターネット(WWW)に接続した**情報端末を特定**することができるインターネット・プロトコル(IP)のユニークな識別番号」です。
色々なサイトで、**『コンピューターの世界における住所』** とよく解釈・説明されています。

これらの情報をまとめると、IPとは**決められたルールに従い、「IPアドレス」の情報（住所）をもとに相手先にデータを送ること**なのです！



# TCPとは？
TCPとは、インターネット通信で標準的に利用される、**データ等を運ぶための手順**です。

IPはデータを運んでくれますが、そのときに、データを壊さずに運ぶことは保証してくれないのです。
宅配業者でしたら大問題ですが、IPはあくまで「IPアドレスの情報をもとに相手先にデータを送るだけ」がお仕事なのです。

でも、そうはいってもデータが破損されたりすることは困ります。
そこで出てくるのが、TCPです。

データという荷物を運ぶ際に、荷物をきれいな状態でIPアドレスの住所に届けるにはどうしたらいいのかをTCPが決めて実行してくれます。


# ポート番号とは？
ポート番号とは、「TCP/IPのプロトコルにおいて、コンピューターの**どのアプリケーション(プログラム)にデータを送付するのかを決める識別番号**」のことです。


先程も記載しましたが、
IPアドレスは確実に荷物を届ける、といったことまでは責任を持ってくれません。
とりあえず送るだけ。

そんな無責任な、、、(-_-;)と思う気持ちはわかります。

IPアドレスは「パソコンの住所」ではあるのですが、その中にはいくつものアプリケーションが存在しています。
そのため、送られてきたものが「メールとしてのデータ」なのか「ファイル共有のためのデータ」なのか、などの区別のつけようがないのですね。

例えば、家に荷物が届いても、宛先が書いてないと『これは自分宛て？それとも父？母？』となって、誰が荷物を開けたらいいかわからないですよね。
IPアドレスには住所の情報しかないので、宛先までは書いてないのです。

じゃあ、宛先はどこにあるの？と思われるかと思います。
そこで出てくるのが、ポート番号です。

ポート番号に宛先が記載されており、それをもとに『この荷物は誰に届ける』というのを識別することができます。


# IPとTCPとポート番号の違い
違いとしては、以下のように例えることができます。
- IPアドレス:データを送る住所
- TCP：データを送る手順
- ポート番号：宛先

例えば、友人Aさんに荷物（データ）を送りたい！というときには、
IPアドレスで送りたい住所への道順を決め、TCPで荷物が壊れないように梱包して、ポート番号の宛先に記載されている『友人A』さんに荷物を届ける、というのがそれぞれの役割のイメージです。


もっとちゃんとした言葉で書くと、以下のようにまとめることができます。
- IPアドレス：情報端末を特定することができる番号
- TCP：データ等を運ぶための手順
- ポート番号：どのアプリケーション(プログラム)にデータを送付するのかを決める番号


私の説明はあくまで一例です。
ネットの中のいろんな記事にいろんな解説や例え方が記載しているので、自分が一番納得できるものを探して読むといいと思います！

# 参考文献
[「ipアドレス」と「ポート番号」の違いとは？分かりやすく解釈](https://meaning-dictionary.com/%E3%80%8Cip%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%80%8D%E3%81%A8%E3%80%8C%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%80%8D%E3%81%AE%E9%81%95%E3%81%84%E3%81%A8%E3%81%AF%EF%BC%9F%E5%88%86%E3%81%8B/)
[ポート番号 【port number】](https://e-words.jp/w/%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7.html)
[「TCP」「UDP」「IP」とは？初心者に違いをわかりやすく解説](https://xn--n8jv600a.net/network/)
[IPアドレスの基礎知識](https://qiita.com/mogulla3/items/efb4c9328d82d24d98e6)
pythonとmysqlを使ってデータベースを作ってみる


## はじめに
mysqlを触り始めた初心者がpythonとMySQLでデータベースを構築するための備忘録。
細かな用語の違いなど多々あると思いますがご容赦ください。随時更新予定。

## python環境構築
mysqlをpythonで管理するにはconnectorなるものが必要。
conecctorには公式配布のものから、サードパーティ製？のものなどいろいろあるが、
どれもpython3.9に対応していないので、anacondaでpython3.7の環境を構築する。

以下構築コマンド
~~~:anaconda prompt
$ conda create -n py37 python=3.7
$ conda activate py37
$ conda install ipykernel
$ conda install panads
$ conda install numpy
$ conda install mysql-connector-python
~~~

## mysqlでデータベースを作る
コネクタの接続はデータベース単位で行うようなので、あらかじめデータベースを作っておく。
作成方法cuiでもguiでも。なんでも可。
cuiコマンド例
~~~:mysql command line client
CREATE DATABASE test_db;
~~~


## mysqlサーバーに接続する
cursorのbufferd=Tureにする理由は調査中。
~~~python
import mysql.connector

config = {
    "user"     : "root",
    "password" : "yourpassword",
    "host"     : "localhost",
    "database" : "test_db"
}
cnx    = mysql.connector.connect(**config)
cursor = cnx.cursor(buffered=True)
~~~

## 新しくテーブルを定義する
cursor.execuite()の引数にSQL文を与えると実行してくれるので、命令文を作って渡すだけ。
try, except処理は実行時のエラー対応。
~~~python
# テーブル名とカラムを定義
table_name = "table1"
columns    = [
    "id INT AUTO_INCREMENT NOT NULL PRIMARY KEY",
    "path VARCHAR(255) NOT NULL",
    "dt DATETIME NOT NULL",
    "label VARCHAR(255) NOT NULL"
]

# SQL文作成
buf = ""
for i, column in enumerate(columns):
    if not i == len(columns)-1:
        buf += column + ", "
    else:
        buf += column
sentence = f"CREATE TABLE {table_name}({buf})"

# 実行
try:
    cursor.execute(sentence)
except mysql.connector.Error as err:
    print(sentence)
    print("==========")
    print(err.msg)

~~~

## テーブルにレコードを挿入する
テーブル作成時と同様にSQL文を作ってcursor.execute()で実行する。
cnx.commit()を行わないと反映しない点に注意。

~~~python
table_name = "table1" 
columns    = ["path", "dt", "label"]
for iter in iterable:
    
    # iterに応じてレコードをつくる
    path    = ~~~
    dt      = ~~~
    label   = ~~~
    values  = (path, dt, label)

    # SQL文作成
    buf1 = ""
    for i, column in enumerate(columns):
        if not i == len(columns)-1:
            buf1 += column + ", "
        else:
            buf1 += column
    buf2 = ""
    for i, value in enumerate(values):
        if not i == len(values)-1:
            buf2 += r"%s, "
        else:
            buf2 += r"%s"
    sentence = f"INSERT INTO {table_name} ({buf1}) VALUES ({buf2})"

    # 実行
    try:
        cursor.execute(sentence, values)
    except mysql.connector.Error as err:
        print(sentence)
        print("==========")
        print(err.msg)
cnx.commit()
~~~

## 既存のテーブルのレコードを参照する
SELECT文の結果がiterableなのでforループで使いやすい形に変換する.
また、下記forループ内でcnx.commit()を実行すると"unread result found"というエラーを吐くので注意
~~~python
# SELECT分でレコードを取得
cursor.execute("SELECT id, path FROM test_db")

# 結果をリストに変換
ids   = []
paths = []
for id, path in cursor:
    ids.append(id)
    paths.append(srcpath)
~~~

## 参照
https://dev.mysql.com/doc/connector-python/en/
Flask/uWSGI備忘録

# Flask
pythonでシンプルなWebAPIが実装できる。
単体でWebサーバにもなれるが、[Werkzeug](https://palletsprojects.com/p/werkzeug/)というWSGIモジュールで実装されているため、後述のWSGIの一つとして使える。

# Web Server Gateway Interface
WebサーバとWebアプリケーションをつなぐものというイメージ。[PEP 3333](https://peps.python.org/pep-3333/)でその仕様が決められている。
それ単体で動くというより、apacheやnginxにアップロードして使うことを目的としている。

# uWSGI
Flaskで作ったWSGIはGoogle App Engine等クラウドにホストする方法もありますが、[uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/)を使いオンプレでホストすることもできます。
c,c++で作られているようです。かなりシンプルなので個人的に好みです。Windowsはサポートされていません。

## 起動方法

まず設定ファイルを作る。設定ファイルの詳細は[ここ](https://uwsgi-docs.readthedocs.io/en/latest/Configuration.html)から

```ini:uwsgi.ini
[uwsgi]
# wsgiファイル
wsgi-file=app.py
callable=app
# アクセス許可ホスト:ポート
http=0.0.0.0:5050
uid = [user1]
gid = [user1]
daemonize = /home/user1/yourapp/app.log
# pidファイルの位置を指定
pidfile = /home/user1/yourapp/app.pid
# 前回異常終了した場合、起動時にpidファイルをクリア
vacuum = true
```

```bash:起動例
uwsgi uwsgi.ini
```

```bash:終了方法
$ kill -INT `cat /home/user1/yourapp/app.pid`
or
$ uwsgi --stop /home/user1/yourapp/app.pid
```

[公式サイト](https://flask.palletsprojects.com/en/2.2.x/deploying/uwsgi/)では、443等WellKnownポートを使いたい場合は、nginxかApacheを使えと言っています。

```:起動確認
yusuke@nyao:~/yourapp
$ ps ux -L | grep wsgi | grep -v grep
user1   24062 24062  0.0    3  0.5 890896  5308 ?        Sl    8月03   0:03 uwsgi uwsgi.ini
user1   24062 24067  0.0    3  0.5 890896  5308 ?        Sl    8月03   0:00 uwsgi uwsgi.ini
user1   24062 24077  0.0    3  0.5 890896  5308 ?        Sl    8月03   0:00 uwsgi uwsgi.ini
user1   24063 24063  0.0    1  0.0  53712   436 ?        S     8月03   0:00 uwsgi uwsgi.ini
```

余談ですがps -Lでスレッド単位で表示されます。



# apache-flask
uwsgiを経由せずにapacheのlibapache2-mod-wsgi-py3というプラグインでapache-flaskのアーキテクチャも構成してみましたがscikit-learnをimportするとレスポンスがなくなるという現象が起きました。
このプラグインは情報が少なく利用者も少なそうなので見送りました。
「第I幕　Netscape：マネージャー」からの学びメモ(1)(リーダーの作法／マイケル・ロップ)

マイケル・ロップ氏の「リーダーの作法　ささいなことをていねいに」を読み解きながら、メモを残しています。

:::note info
各章ごとにまとめていますが、章の原題ではなく**私にとってのまとめ**をタイトルにつけなおしています。
:::

https://www.oreilly.co.jp/books/9784873119892/

この本との出会いと、アウトプットしながら読み解く経緯はこちらの記事で。

:::note warn
本文で登場する「ランズ」は、ロップ氏のネット上のハンドルネームです。
「はじめに」で、自身を「ロップ」とも「ランズ」とも呼ぶと宣言しています。
:::

https://qiita.com/w2mjra555/items/73fcac51e65dc20e8cba

# 第I幕　『人の気持ちが分かる』基本的で難しいこと

「リーダーの作法　ささいなことをていねいに」は、大きくは3部構成になっています。

- 第I幕　Netscape：マネージャー
- 第II幕　Apple：ディレクター
- 第III幕　Slack：エグゼクティブ

今回は **「第I幕　Netscape：マネージャー」の1章～3章**について学びメモを残します。

```
第I幕　Netscape：マネージャー

1章　誰からでも学ぶことがあると考える

2章　会議ボケ
    2.1　抱えすぎ
    2.2　リーダーとして卓越した仕事をするために

3章　難題
    3.1　特に厄介な課題
    3.2　難題に対する意思決定
```

> あなたが手にしているこの本（紙であれ電子書歴であれ）は、私がマネジャーになった最初の数年間に、**しっかりとしたサポートを受けられなかったことへの不満**から生まれたものです。

なんとも痺れます。**物事の原動力に正直**とでも言いましょうか。
共感する気持ちが生まれることで、**読み手の姿勢に『自分ごと化』が起こります。**
だから、本の内容がよりいっそう**大切なこととして入ってくる**のかもしれません。

> ロップ、君は**優秀なエンジニア**だけど、**優れたマネージャー**になれるよ。**人の気持ちが分かるからね。**

この一文を見て、私はこの基本があまりに**語られなさ過ぎている**と感じました。
たとえば私の身近で **『プロジェクト管理の議論』** を設定しても、おそらくほぼ語られない。

しかし一方で、**エンジニアとして仲間と協働する場面**を思い描くとき、この言葉は**シンプルにして、ものすごい真理をついている**ように思います。

:::note info
もうあまり思い出したくない、**本能寺のように燃えるいくつかの過去の現場**をふりかえれば、なおさらです。
:::

## 1章　ストーリーを見つけ出して『主人公』に戻れ

ロップ氏は**1on1を行い、重要なメッセージに耳を傾ける**ことを推奨しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515319/3a5c6674-38f5-9dfe-c6e6-f7d474cbfbd3.png)
この章に限らず **「ストーリーを見つけ出す」** というフレーズがよく登場します。
その意味することは、まさに、

- 目の前の一見不条理な出来事を **『自分ごと化』してとらえなおす**

ことであり、それこそが**リーダーシップの本質**でもあると。

:::note info
一般的にはむしろ **オーナーシップ**と呼ばれる姿勢です。
「リーダー」でなくても、**良い意味で『主人公』** として学ぶには必要ですね。
:::

## 2章　約束を守るために、自分を知る

ロップ氏は**約束を守る**ことを推奨しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515319/3cfbc246-18e4-02a5-09ff-02918e40108a.png)
リーダーが約束を守れないことは **「約束を破っていい」メッセージを発信する**ことです。
いわゆる士気の低下を招きます。

この章では、

- 約束を最初から守る気がない人が、まかり間違ってリーダーになっている

ようなことは問題にしていません。
（あるとすれば、それはもう別の構造的問題ですよね）

**約束を守るつもりなのに、できなくなる**とき。
その背景には、**自分の能力を正しく俯瞰できていない**問題がある。

だから、**約束を守るために自分を知りましょう**と。

:::note info
これは、別にリーダーに限った心得ではなくて、本当に基本的なこと。
まさに「ささいなことをていねいに」だと思います。
:::

> 知彼知己、百戦不殆。（彼を知り己を知れば、百戦して殆からず。） 孫子

## 3章　実力を高める一方で、運を受け入れる

ロップ氏は**トラブル発生時の対応を慎重にする**ことを推奨しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515319/3ce9bb5c-eb68-95d3-9202-c55b3bec8120.png)
この章は取り扱いが難しい。
**理屈でわかっていても、なかなか実践できない**ことが書かれています。

たとえば**バイアスについて具体的に知ることは、判断力を補強する**かもしれません。
が、それだけで**冷静な判断を100%保証するものでもなく。**

ただ、ロップ氏が最後に**運**について言及していることは示唆に富んでいます。

目前の物事を**実力のみでどうにかできる**と考えてしまう。
それは行き過ぎればおごりになり、判断の目を曇らせます。

**実力を高める努力を積み上げる一方で、どうしようもない運を受け入れる。**
この**バランス感覚**が大切だと思います。

:::note info
この世界は、**予想もしなかったことが最悪のタイミングで起きる**こともある。
自分は世界にとって**その程度**である。
**よい意味での諦念を持つことが、自分ができる最善の判断を導きます。**
ときには、誰かを頼って、協力して乗り越える姿勢も。
:::

## ここまでの雑感

学びメモとしてエッセンスのみ抽出すると、気づくこととして…。
大筋は、エンジニア以外の方にも**普遍的に適用できる**ことが書かれています。
それでもこの本は、**エンジニアにこそふさわしい内容**とも感じます。
それは、語られる**エピソード**がエンジニアに焦点の当たったものだからです。

この本の細部から、**ゾクゾクした理屈抜きの臨場感**を感じられるのは誰か？
やはり、エンジニアだと思います。そのゾクゾクが **『自分ごと化』** を推し進めます。
読み手になる私たちエンジニアの**解像度を跳ね上げてくれる**のですね。

だからこそ、おすすめです！

## 続きの記事

https://qiita.com/w2mjra555/items/7ad432dbc99dd2a921c0
UnrealEngineのDatasmithRuntimeで初回3Dモデルのロードができない

UnrealEngineのDatasmithRuntimeで初回3Dモデルのロードができない現象があった調査して対応しました。
一応、UnrealEngineにバグ報告と[pullreq](https://github.com/EpicGames/UnrealEngine/pull/9441)はしてみた（やり方がまずいのか反応なし）のですがその内容についてまとめておきます。

# 確認した環境

UE4.27.2
UE5.0.3

# 発生する現象

CollabViewerでも発生しますがDatasmithRuntimeでランタイム中に3DモデルをADatasmithRuntime::LoadFile()を使ってロードしようとすると初回だけロードできない現象がありました。

# 原因

初回ロード時にFTranslationThread::ThreadEventが非同期に設定されますが、設定される前にFTranslationThread::AddJob（）が実行され、その中でまだnullptrであるThreadEventがジョブに設定されてしまっています。
ジョブがキューから呼び出されて実行される際にThreadEventがnullptrかどうかチェックされ、nullptrの場合はロード処理を終了しています。

## 調査方法

以下の行の前でログを出すと初回ロード時にThreadEventがnullptrです。
https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/DatasmithRuntime.cpp#L359

以下の行の後にログを出すと2、1の順で出力されます（ジョブへのThreadEvent設定の後に、ThreadEventに値が設定されています）。
1. https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/DatasmithRuntime.cpp#L341
1. https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Public/DatasmithRuntime.h#L82

# 対応方法

以下のようにDatasmithRuntimeプラグインのEngine/Plugins/Experimental/Enterprise/DatasmithRuntime/Source/Private/DatasmithRuntime.cppを修正します。
DatasmithRuntimeプラグインを自プロジェクトに配置するとUnrealEngine全体をソースコードからビルドせずに修正できます。

```cpp
bool ADatasmithRuntimeActor::LoadFile(const FString& FilePath)
{
...
            [&, FilePath]() -> void                                                         // <= FilePath追加
			{
				FPlatformProcess::SetThreadName(TEXT("RuntimeTranslation"));
				TranslationThread->bKeepRunning = true;
				TranslationThread->ThreadEvent = FPlatformProcess::GetSynchEventFromPool();
				TranslationThread->AddJob({ this, FilePath });                             // <= 追加
				TranslationThread->Run();
			}
		);
	}
	else                                                                                   // <= 追加
	{                                                                                      // <= 追加
		TranslationThread->AddJob({ this, FilePath });
	}                                                                                      // <= 追加

	// Set all import options to defaults for DatasmithRuntime
	return true;

```
Modelerストリームのインプットとアウトプットのファイル名やテーブル名をmodeler scriptで取得する

Modeler ScriptをつかってModelerストリームの入出力のファイル名や入出力のテーブル名を取得します。
バッチで自動的に取得してみます。

あらかじめModeler Batchの導入が必要です。

https://qiita.com/kawada2017/items/2107702d511b8d0d3a40

以下のようなPythonのmodeler scriptをスタンドアローンスクリプトとして準備しました。

```python:inputoutput.py
import modeler.api
stream = modeler.script.stream()
for node in stream.iterator():
   #print(node.getTypeName())
   if (node.getTypeName() == "variablefile"
        or node.getTypeName() == "excelimport"
        or node.getTypeName() == "statisticsimport"
        or node.getTypeName() == "outputfile"
        or node.getTypeName() == "excelexport"
        or node.getTypeName() == "statisticsexport"):
            print(node.getTypeName()),
            print(node.getPropertyValue("full_filename"))
   if (node.getTypeName() == "database"
        or node.getTypeName() == "databaseexport"):
            print(node.getTypeName()),
            print(node.getPropertyValue("tablename"))
```

以下のストリームから入出力のファイル名や入出力のテーブル名を取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/91e3234d-865e-54d7-05f1-4f8bcc3b846a.png)


ストリームとスクリプトファイルを適当なフォルダに配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/4959367e-2130-fb4c-e94f-5b81922a78cc.png)


clemb.exe(ModelerBatch)をつかって起動します。
|option|内容|
|---|---|
|-stream|ストリームのパス|
|-script|スタンドアロンスクリプトのパス|
|-hostname|Modeler Serverのホスト名|
|-port|Modeler Serverのポート番号|
|-username|Modeler Serverのユーザー名|
|-password|Modeler Serverのパスワード|

Modeler Serverと同じサーバー上であればhostnameやportなどは省略可能です。
結果はUTF-8で返るのでchcp65001でコマンドプロンプトのコードページを変えておきます（適宜フォントも日本語フォントに変えてください）。

```cmd
chcp 65001
"C:\Program Files\IBM\SPSS\ModelerBatch\18.4\bin\clemb.exe" -stream C:\temp\inputoutputdata.str -script C:\temp\inputoutput.py -hostname ms184-win19 -port 28060 -username Administrator -password xxxxx
```

以下のようにノードのタイプとファイル名やテーブル名が返りました。
```cmd:結果
C:\Users\Administrator>"C:\Program Files\IBM\SPSS\ModelerBatch\18.4\bin\clemb.exe" -stream C:\temp\inputoutputdata.str -script C:\temp\inputoutput.py -hostname ms184-win19 -port 28060 -username Administrator -password xxxxx
outputfile C:/data/01basic/credit_新規結果.csv
databaseexport TESTTAB
database HKWD.COND4N_E104
variablefile C:/data/01basic/credit_６か月前.csv
variablefile C:/data/01basic/credit_新規顧客.csv
```
[JavaScript] localStorage JSON　保存・取得

JSONデータをLocalStorageへ保存する方法で溢れていて、
変換して正常に取得する情報がなかなかGoogleヒットしなかったのでメモ程度に記事にします。

<h1>JSONの用意</h1>

①JSONファイルを作成して、データとなる情報を記述。

※JSONは、少しの記述ミスで正常に動作しないので慎重に。
 JSONデータの作成方法は別途検索して下さい。
```data.json
[{
  "userId": "owner10",
  "email": "xxxxxxxxxx@gmail.com",
  "password": "12345678",
  "unisex": "男",
  "age": "24",
  "from": "日本"
}]
```

私は、Angular構成ですので下記PATHへJSONファイルをセットしました
<b>→src/assets/data/user.json</b>

<h1>JSONデータを読み込み</h1>

①JSONデータをlocalStorageへ設定するため、tsファイル(jsファイル)へimport。
②tsファイル(jsファイル)でlocalStorageへ保存するコード記述。

※実際は、JSONファイル呼び出しファイルとlocalStorage保存ファイルは分けて実装していますが、合わせた形で記述します。
※関係ない箇所はコメントアウトまた最初から削除して↓記載しています。
```login.component.ts
import UserJson from '../../assets/data/user.json'; //user.jsonファイル読み込み

export class LoginComponent implements OnInit, OnDestroy {

  localstorageName(){ //userIdをローカルストレージへ保持
    this.storageUserId = this.loginForm.value.userId;
    localStorage.setItem("userId",this.storageUserId);//form入力値
    
    //暫定ローカルストレージ登録情報 (DB接続していないため暫定。後で削除)
    let json = JSON.stringify(UserJson);
    localStorage.setItem('profile',json); //第一引数：key名, 第二引数:value値
  }

```

上記に結果、localStorageへ下記の情報が保存されます。
key : profile 
value : [{"userId": "owner10","email": "xxxxxxxx@gmail.com","password": "12345678","unisex": "男","age": "24","from": "日本"}]


<h1>★JSONオブジェクトlocalStorage取得方法</h1>

```home.ts
export class homeComponent implements OnInit {

  //html部品表示(名前、年齢、出身、性別)
  p_name:any;
  p_age:any;
  p_from:any;
  p_unisex:any;


  constructor(
    private router: Router
  ) {
   }
  ngOnInit(): void {
    //profile部品表示値を(暫定)ローカルストレージから出力
    var localStorageJson = localStorage.getItem('profile');
    var localStorageJsondata = JSON.parse(localStorageJson!);

    //html部品表示(名前、年齢、出身、性別)
    this.p_name = localStorageJsondata[0].userId; //owner10取得。
    this.p_age = localStorageJsondata[0].age; //24取得
    this.p_from = localStorageJsondata[0].from; //日本取得
    this.p_unisex = localStorageJsondata[0].unisex; //男取得
  }

```

上記の通りに、localStorageからJSONオブジェクトデータを取得しました。
これをhtml上に紐づけて表示させると画面表示されます。


Angular構成の場合
========

```home.html
<div class="profile_box">
    <div class="box-title">プロフィール</div>
    <div class="profile_center">
    <img alt="" src="../../assets/image/icon_profile_sample.jpeg" class="profile_figure">
    <div class="profile_name">{{p_name}}</div></div>
    <p>自己紹介文</p>
    <ul>
    <li>性別：{{p_unisex}}</li>
    <li>出身地：{{p_from}}</li>
    <li>年齢：{{p_age}}</li>
    </ul>
</div>
```
参考例：
下記画像のように、localStorage保存した情報を取得したデータをhtml表示させることができました。

![スクリーンショット 2022-08-10 15.08.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677104/aa4a50ce-8c4f-16f0-e1bb-6d23e8803331.png)


<h1>補足</h1>
配列、JSONの扱いは難しいです。
しっかりと書き込み・取得方法を時間設けて学ぶのが良いです。

実務でも、必要な知識です。
UnityでXR Plugin Managementを使ってHMDで映像を見えるようにするために最低限したこと（備忘録）

# この記事の目的
主に備忘録

# 環境
Unity for Windows 2020.3.26f1 Personal
XR Plugin Management 4.2.1

# 手順

1. Unityをインストール
2. プロジェクトを作る
    - テンプレートは3D
3. 上部のWindows→Package Managerを開き上部のPackagesドロップダウンリストからUnity Registryを選ぶ
4. XR Plugin Managementをインストール
5. Hierarchyの何もないところをクリック→XR→Convert Main Camera To XR Rigをクリック→シーンを保存
    - あらかじめMain Cameraをプレイヤーの初期位置に置いておくとよい
6. 上部のEdit→Project Settingsを開き左のXR Plugin Managementの中でWindowsタブのOpenXRをクリック→指示に従うとUnityが再起動する
7. 同じくProject SettingsでXR Plugin Managementの中のWindowsタブのOpenXRの右に現れる黄色の三角をクリック→Lock input ～のFixをクリック
8. 同じくProject SettingsでXR Plugin Managementの下に現れるOpenXRでInteraction Profilesに持っているコントローラを登録する
9. Unityの再生ボタンを押すとHMDにシーンが描画される

# 参考にした記事
https://framesynthesis.jp/tech/unity/xr/

https://qiita.com/Kazu_Sack/items/776accbe1e8582b3d735
バス用語まとめ（エンベデッドシステムスペシャリスト午前Ⅱ）

# 目的
アウトプットによる理解の促進と情報共有。

# バスの構成要件
バスに接続される基本的なブロックは下図の通り。
ブロックはバスマスタ、バススレーブ、バスアービタに分類できる。
これらが決められた仕様に従って動作する仕組みをバスプロトコルという。
![エンベデッドシステムスペシャリスト_バス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110901/5704d62f-0981-9787-81c3-af59cdd19fba.png)
### バスマスタ
自らバスを制御してデータ転送を行うものをいう。
### バススレーブ
自らバスを制御する機能を有しないものをいう。データ転送時にはバスマスタに対して受動的に振舞う。
### バスアービタ
複数のバスマスタがいるバスにおいて、バスマスタ間でのバス使用権の調停を行う。
独立したバスアービタを接続して集中管理する方式と、それぞれのバスマスタにバスアービタの機能を持たせてこれらの間で調停を行わせる方式とがある。

# システムバス構成
### プリンストンアーキテクチャ
データとプログラム(命令)を同一のメモリバス上に配置するアーキテクチャ。
### プリンストンアーキテクチャ
データとプログラム(命令)を別々のメモリバス上に配置するアーキテクチャ。演算の高速処理が可能なため、DSPでの採用例が多い。

# ウェイト機能とレディ機能
低速IOブロックにCPUの動作を合わせる方法としてこれらの機能がある。
**ウェイト機能**は、アクセス時に挿入するダミーサイクルの数を設定することで、特定のデバイスに対するアクセス速度を遅くする。
**レディ機能**は、ブロックがCPUに対してレディ信号を使って実行中のアクセスサイクルを延長するように指示する。

# DMA (Direct Memory Access)
CPUを介さず主記憶と周辺デバイスとの間、または主記憶と主記憶の間でデータを送受信するための仕組み。
DMA転送ではDMACと呼ばれる専用HWがCPUと独立してデータの送受信を行う。
CPUがDMACに対し転送先のアドレスを指定した後、転送開始の指示を行うと、データの転送が開始される。
DMA転送中はDMACがバスマスタとして機能するためCPUから主記憶へのアクセスは制限を受ける。

# 疑問に思ったこと
* プリンストンアーキテクチャのデメリットは？　命令にアクセスしているときデータにアクセスできず低速であることがデメリットで合っている？
参考：http://memes.sakura.ne.jp/memes/?page_id=106
postされたファイル(画像やExcelファイル等)をDBに登録 Part2

前回、MySQLdb.connectのcursorによる直書きSQLでエラーが発生し、
pandasを用いてファイルを丸ごと登録したわけだが(https://qiita.com/v4ns/items/98cf4bdc65d46b3f1764 ) 、
原因というか解決策が判明したので記載する。

# 代入を行う%sを使う場合は、パラメータをまとめる変数を介すること
解決策は、どうやらパラメータ用変数に投げてから%sでSQL文に当てはめることだった。その結果、エラーが出ずに実行できた。

```python:qiita.py
             #現在時刻を取得
             time = datetime.datetime.now()
             # データベースへの接続とカーソルの生成
             connection = MySQLdb.connect(
                 host='localhost',
                 user='root',
                 passwd='passwd',
                 db='db')
             cursor = connection.cursor()
             sql = ('''update example set addresser = %s,file =  %s ,created = %s ,last_updated = %s where id = %s ''') 
             # ここに実行したいコードを入力します
             # 使うパラメータから順に変数に入れていく
             params = (str(request.form['name']),frame,str(time),str(time),str(request.form['id']))
             # SQL文にパラメータをいれて実行
             cursor.execute(sql,params)
             # 保存を実行
             connection.commit()
              
             # 接続を閉じる
             connection.close()
```

これでいけた。ありがとう、パラメータの人。
足りないimportはエラー表示を参考に適宜入れてください。
SPSS Modeler Batch18.4のインストール on Windows Server

SPSS Modeler Batchをインストールします。
Modeler Batchはリモートからも実行可能なので、Modeler Serverとは別マシンに導入することも可能です。

# 解凍

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/826ac932-314e-b5c1-4440-d9f971507eb6.png)

# インストール

Setup.exeを「管理者として実行」します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/084e3b12-ebdb-0a96-95a6-02bea0a9d4d3.png)


「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1fc19ebb-277a-6f69-9d26-047be685a828.png)


「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/053df269-0abe-a9c0-374a-5ed8944bcb94.png)

「使用許諾所に同意します」をチェックし、「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/88c0685c-ce0a-6524-f44d-a07c57639007.png)


「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1cae3f8f-5e54-5b92-9a8e-6fd869acc600.png)


「インストール」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/ffa75f65-0cb3-e7c5-04e0-a1f09708f53b.png)

再起動が必要になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/a0193945-ec8e-5618-d49e-42cd9c2b0a6b.png)

「完了」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/73eaddfc-5299-66cc-ef4e-993415597b55.png)

再起動を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/97793928-0d21-6448-339e-210c069e2fe8.png)

導入ができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/96c19be3-7878-eddd-df17-df8ddda816f3.png)


# テスト環境
* Modeler Server 18.4
* Modeler Batch 18.4
* Windows Server 2019 Standard
[Oculus Quest2] Airlinkの接続が定期的に切れる

# 概要
数日前からか、HMDをpcにAirlinkで接続していると定期的に接続が切れてしまい、oculusのホーム画面に戻されてしまうという状態になっていた。

症状を直すためにいろいろ調べたが、ネットに情報が残っていなかったため共有しておく。
# 症状
具体的には以下のような状態となっていた。
・Airlinkを使用しているとたまに「wifi接続が切れました」と出てホーム画面に戻される
・戻された後はすぐ再接続できる
・Airlinkを使用せずにオキュラス単体で使用しているときはwifiが切れるようなことは一度もなかった。

# 原因
上の状態から原因として考えられるのは以下のとおりであると思われる。
・周りの家のwifiとチャンネルが混み合っている。
・ルーターの場所が悪い
・oculusソフトウェアの問題
・oculus本体の問題


# 原因究明
家の周りのチャンネルを「wifi analyzer 」というフリーソフトで調べてみたところ、チャンネルが非常に込み合っていることが判明。
ルータの設定ページを開き、チャンネルをずらしてみる。しかし、特に解決しなかった。

また、ルーターを真横に置いた状態でも問題は解決しなかった。したがって場所も問題ない。
 
ソフトウェアと本体を初期化してみても同様の問題は発生した。手詰まりである。

# 解決方法
なんとなく wifiを2.4GHz帯を使用してみたところ 、これらの問題は発生しなくなった。

しかし、2.4Ghz帯は一般的にはAirlinkでは非推奨であるため、いずれ何かの問題が発生すると考えられます。
おそらくルータに問題があるため、VR用のルータを購入するべきなのかなぁと思いました。
超個人的 rsync オプション


Concrete CMS のデータをサーバー間で引っ越ししたりするときによく使うオプションです。


# ベース

個人的によく使っている rsync オプション、いつも忘れちゃうので、メモです。

```
rsync -rptgoDLkz --delete --no-H [同期元ディレクトリ] [同期先ディレクトリ]
```

## 同期元・同期先ディレクトリの書式：リモートサーバーの時

```
[SSHユーザー名]@[サーバーアドレス]:/ディレクトリ絶対パス
```

## 同期元・同期先ディレクトリの書式：サーバー内の場合

```
/ディレクトリ絶対パス
```

## 例：参考例

リモートサーバー `example@192.168.1.1` の `/var/www/html` から、サーバー内の `/var/www/html` に同期させる時

```
rsync -rptgoDLkz --no-H example@192.168.1.1:/var/www/html/ /var/www/html/
```

## SSH 鍵を使う

SSH 鍵を使って認証する。
さきほどの例では、同期元のリモートサーバーの `~/.ssh/authorized_keys` ファイルに、サーバーの id_rsa.pub キーを設定したと言う前提。

SSH 鍵を任意で設定した場合は rsync コマンドに

```
-e "ssh -i [キーへのパス]
```

のオプションを追加する。ｃｄ


## ディレクトリ指定の注意

最後にスラッシュをつけることで、同期元・同期先のディレクトリを同じにできる。

同期元のディレクトリにスラッシュをつけないと、ディレクトリ自体もコピーされる。


# 各オプションの説明

自分がなんでそういうオプションを使うのかを理解してから使いましょう。


オプション | 内容
-----|-------
--recursive, -r | 指定されたディレクトリ以下すべてが対象
--perms, -p | 権限を保持
--times, -t | ファイルの更新時間を保持
--group, -g | 所属グループを保持
--owner, -o | ユーザー情報を保持 (sudo のみ)
-D | スペシャルファイル、デバイスファイルを保持
--copy-links, -L | シンボリックリンクなファイルもコピーする
--copy-dirlinks, -k | シンボリックリンクなディレクトリの中身もコピーする
--compress, -z | 転送データを圧縮して送信する
--no-H | ハードリンクを保持しない

-g や -o は必要に応じて使わない。

あと、時々つかうオプション

オプション | 内容
-----|-------
--dry-run,n | まず試す
-v | 詳細を出力する
--progress | コピー途中のファイルなどを表示してくれるけれどその分処理に時間がかかる

参考
https://download.samba.org/pub/rsync/rsync.1
https://atmarkit.itmedia.co.jp/ait/articles/1702/03/news020.html


# おまけ1: 時間計測のために date コマンドをいれる

本番のデータ移行をする時に、どれだけ同期に時間がかかるか、
事前にテスト実行をして時間を計測したい。そのときに `date` コマンドと `&&` で rsync の実行コマンドの前後にいれておく

```
date && rsync [長いコマンド] && date
```

こうすると、開始前の完了後の日付を echo しておいてくれるので、
どれだけ rsync に時間がかかったかの証跡がとれる。

つまり席を外したり、他ごとしてOK。

# おまけ2: SSH の接続が切れてもOKなように noup を使う

同期するファイルの量が多いと、SSH 接続が切れてしまう可能性があるので、
とにかく、SSH 接続が切れても rsync のジョブを続けて実行させたい。

そんな時は nohup コマンドを使う

```
nohup rsync [長いオプション]  &
```

最後の「&」を忘れない

※ tmux コマンドは入っていないサーバーもあるので、ひとまず nohup
SNSのテンプレートを作ってみた

# はじめに
　最近のプログラマーはコードを打たないらしいです。そりゃ、プログラマーたるもの誰もが経験しているとは思いますが、サンプルコードの挙動をテストするためにタイピングをしていれば、どこかでミスが発火するものです。おまけに環境を自分で整えるとなれば作業時間はかなりのものとなります。
　そこで今回はnode.jsでSNSを作るためのテンプレートとなりそうなものを作成してきたので、共有したいと思います。内容はexpress-generatorを基礎としたnode.jsでチャット機能、ログイン機能をつけたというものです。mongodbとnginxも使用しています。
　なお、この記事では解説はせず、GitHubからクローンの方法を置いておくだけだ。解説は以下のURLで行っています。

**passportについてのざつ～な解説**

https://qiita.com/king_dog_fun/items/d6b3565e624b96d6ea9c

**socket.io(chat)についてのざつ～な解説**

https://qiita.com/king_dog_fun/items/f0fc88d5adc20da5183a


# GitHubからクローン

```
git clone https://github.com/DogKingFun/sns_template.git
```

# Docker-compose

　カレントディレクトリをsns_templateへと移し、docker-composeを立ち上げよう。

```
docker-compose up
```

　http:// serverIP　からindex.pugを閲覧できる。index.pugはこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2647158/a15a26c7-5d0d-7b70-68ad-cdc15cd77efe.png)

　各リンクから諸機能に飛ぶことが出来ます。sign in とsign upとsign outはログイン関係の機能。chat roomはチャットに関する機能があります。SNSのテンプレートということで機能はさほど多くありません。

# 最後に
　このテンプレートはGitHubに公開しています。改良点や必要な修正、こうしたほうがいいよなどなどありましたらGitHubの方でもTwitterの方でもいいので教えていただきたいです。

Twitter:

https://twitter.com/dog_king_fun

GitHub:

https://github.com/DogKingFun/sns_template
【TypeScript】async関数のシグネチャを転送する方法

# 結論

```ts:結論
function wrapFn<T extends (...args: any[]) => Promise<any>>(fn: T) {
  return async (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>> => {
    return await fn(...args);
  };
}
```

# 解説
TypeScript 4.7.4で試した。

## 関数のシグネチャを転送するとは

関数を引数にとって同じパラメータおよび戻り値の関数を返す関数を書きたい時がある。例えば関数の呼び出しのログをとる関数をJavaScriptで考える。

```js:非async関数,JavaScript
function wrapLogger(fn) {
  return (...args) => {
    const ret = fn(...args);
    console.log('function called with', ...args, 'and returns', ret);
    return ret;
  };
}

// 使い方
const loggedPlus = wrapLogger((a, b) => a + b);
const result = loggedPlus(3, 4); // コンソール出力: function called with 3 4 and returns 7
```

これをTypeScriptで型付けするには以下のようにすれば良い。

```ts:非async関数,TypeScript
function wrapLogger<T extends (...args: any[]) => any>(fn: T) {
  return (...args: Parameters<T>): ReturnType<T> => {
    const ret = fn(...args);
    console.log('function called with', ...args, 'and returns', ret);
    return ret;
  };
}

// 使い方
const loggedPlus = wrapLogger((a: number, b: number) => a + b);
const result = loggedPlus(3, 4); // コンソール出力: function called with 3 4 and returns 7
```

上のように`Parameters<T>`と`ReturnType<T>`を使うことで引数の関数のシグネチャを戻り値の関数のシグネチャに転送できる。この場合、`loggedPlus`の型は`(a: number, b: number) => number`型としてきちんと認識される。

## async関数の場合
上記はasyncではない普通の関数の場合であった。async関数の場合もそのまま考えれば以下で良さそうなのだが。

```ts:async関数,動かない❌
// これはエラーになる
function wrapLogger<T extends (...args: any[]) => Promise<any>>(fn: T) {
  return async (...args: Parameters<T>): ReturnType<T> => {
    const ret = await fn(...args);
    console.log('function called with:', ...args, 'and returns', ret);
    return ret;
  };
}

// 使い方
(async () => {
  const loggedPlus = wrapLogger(async (a: number, b: number) => a + b);
  const result = await loggedPlus(3, 4);
})();
```

これは3行目の`ReturnType<T>`でエラーになる。

> The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise\<any\>'?

どうやらasync関数の戻り値型には明示的に`Promise`型を指定しないとエラーになるらしい。`ReturnType<T>`は型制約で`Promise<any>`であることがわかっているので通してくれても良さそうだけどね。

ということで明示的に`Promise`を使うために`ReturnType<T>`の部分を以下のように変更する。

```ts:async関数,動く✅
function wrapLogger<T extends (...args: any[]) => Promise<any>>(fn: T) {
  return async (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>> => {
    const ret = await fn(...args);
    console.log('function called with:', ...args, 'and returns', ret);
    return ret;
  };
}
```

`Awaited`は`Promise<T>`型から`T`を抜き出す型関数で、TypeScriptにバージョン4.5以降標準装備されている。よって`Promise<Awaited<T>>`はTが`Promise`の場合`T`そのものになり通常無意味な操作だが、今回は明示的に`Promise`を指定するためにこうしている。こうすればエラーにならない。

### TypeScript 4.5以前の場合
TypeScript 4.5以前では`Awaited<T>`が標準ではないので自作する必要がある。以下のコードで代替できる。

```ts:自作Awaited
type Awaited<T> = T extends Promise<infer R> ? R : T
```
jQueryのparentを使ってテーブルの背景色を操作してみる

## やりたいこと
元々あるこちらのテーブル内のチェックボックスを付けると色を加えるように変更したい。
![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677833/cccf2499-7bd8-799c-25da-5f0e9c1697c9.png)

こんな感じにしたい。
![sample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677833/17349ec1-276c-1acc-6e76-1147c9865839.png)

## 使用言語
- PHP7.0
- jQuery
- CSS

## 実装
チェックボックスに対し、checkClassクラス, trタグにcheckClass2クラスを付与する。
```sample.ctp
<table>
<tbody>
	<tr class="checkClass2">
    <td rowspan="3">
    <?php
       $checkAttr = array(
            'class' => 'checkClass',
            'div' => false);
    echo $this->Form->input('xxx.Id.', $checkAttr);
    ?>
</td>
</tbody>
</table>
```

チェックボックスにチェックが付けられた時の挙動を制御する。
チェックボックスが付けられた状態はthisである。従ってチェックボックスが付けられたタグの一階層上はtdタグ、もう一階層上にはtrタグがあるためparentでそれらを取得する。
そして背景色変更用のクラスをaddClassで加える。
```sample.js
$('.checkClass').change(function() {
    if ($(this).prop('checked')) {
        $(this).parent().parent().find("td").addClass("check1");
    } else {
        $(this).parent().parent().find("td").removeClass("check1");
    }    
})
```
背景色変更用のクラスの操作内容をCSSで定義する。
```sample.css
.check1 {
    background: yellow !important;
}
```
これで終わり。
xraylibを google colab で動かす方法

# xraylib を google colab で動かす方法

xraylib は、主にX線、特に蛍光X線分光に用いられるデータベースなどをまとめたもので、

https://github.com/tschoonj/xraylib

のことです。このツールの背景や使い方については、

https://qiita.com/yamadasuzaku/private/d34996001870d2316de1

に記事を書きましたのでご参照ください。

ここでは、xraylib を使いたいけど、ローカルの python 環境はちょっと、、という方向けに、google colab で動かす方法を紹介します。(記事にしようと思ったのは、ちょっとハマったからであります。)

## google colab での使う方法

- google colab 上で xraylib のインストールからサンプル集は下記に記載しました。
    - [https://colab.research.google.com/drive/1m1y2iTgeV8h_Z22hnGtzaHw7ffBFY2Hf?usp=sharing](https://colab.research.google.com/drive/1m1y2iTgeV8h_Z22hnGtzaHw7ffBFY2Hf?usp=sharing) 

要点は一つだけで、[condacolab](https://github.com/conda-incubator/condacolab
)を使って、　conda を google colab にインストールしてから、xraylib を conda で入れることです。

https://github.com/conda-incubator/condacolab

調べると、condacolab を使わずに、miniconda のインストーラーを wget して入れている例もあるので、それらを試してみましたが、xraylib のインストールに一見成功しているようで、import xraylib で Cのモジュールが無いとかで怒られます。path問題な気がしますが、condacolab だと一発なので、深追いはしてません。

## google colab で使う場合の注意点

- google colab ではmatplotlibでインタラクティブな図が出せません。
    - [mpld3](https://mpld3.github.io/install.html) や、plotly を使うなどで回避はできます。できますが、matplotlibよりも微妙にコードが増えたり、自由度が低い点は考慮の上がよいです。
- google colab で、conda activate で 仮想環境の切り替えはできません(私の知る限り@2022.8.6時点)

## 関連ページ

https://qiita.com/yamadasuzaku/items/633556c2d71997f62cd8
Ubuntu20.04にwgetをインストールする方法

## はじめに
備忘録
タイトルの通りです。
どなたかのお役に立てれば幸いです。
## 手順
### wgetをインストール
```bash
$ sudo apt install wget
```
### wgetのバージョンを確認
```bash
$ wget --version
```
# ブログもあります
https://kyit.net/how-to-install-wget-on-ubuntu/
Git ブランチ指定なしでpushできるように設定する

# 概要

- ローカルリポジトリからpushする際にブランチの指定を行わずpushする方法をまとめる。

# 注意

- 本設定を行うと`$ git push`コマンドだけでpushができてしまいます。
- 意図しないPushにご注意ください。

# 方法

- ローカルリポジトリにて下記を実行する。

    ```
    git config --local push.default "current"
    ```

- `$ git config -l`を実行して`push.default=current`と表示されていることを確認する。
- `$ git push`コマンドのみでpushする事ができる。
さくらのVPSで公式スタートアップスクリプトを使いwordpressを構築してみた

# 初めに

さくらのVPSのスタートアップスクリプトを使って、サーバ自動構築スクリプトを作ろうと画策中。そのために、公式スタートアップスクリプトを使って wordpress を構築したらハマった時のでモ。

# VPSの構築

* さくらのVPSの管理コンソールで、インストール対象のVPSのコンソールを開く
* 「OS再インストール」ボタンをクリック
    * インストールOSとして、Rocky Linux 9 を選択
    * 任意の管理ユーザのパスワードを入力
    * スタートアップスクリプト利用にある「その他のスクリプトを検索」をクリック、「公式」からWordPressを選択
    * 「内容確認」をクリックしインストール実行
* letsencriptに必要な、ドメイン名とメールアドレスを入力
* しばらく待つとVPSが出来上がる

# 初期設定

## サーバへのログイン

sshで、ユーザ　rocky、パスワード：設定したもの　でログイン

## Wordpressへの管理者ログイン

http://（ipアドレス）/ でアクセスすると、初期画面が表示された。なので、http://（ipアドレス）/wp-admin にアクセスし、初期ユーザ admin でログインしようとするものの、パスワードがわからずログインできない。
**どこかにパスワード情報があると思うのだがわからない**

仕方がないので、/var/www/wp_XXXXXXX/ にあった　wp-config.php のDB設定情報を見て、DBにアクセスし、adminのパスワードを変更

```
$ mysql -u [DB_USER] [DB_NAME] -p
Enter password:    <== [DB_PASSWORD]を入力

[snip]
MariaDB [DB_NAME]> select * from wp_users;
+----+------------+------------------------------------+---------------+-----------------------------+----------------------------+---------------------+-----------------------------------------------+-------------+--------------+
| ID | user_login | user_pass                          | user_nicename | user_email                  | user_url                   | user_registered     | user_activation_key                           | user_status | display_name |
+----+------------+------------------------------------+---------------+-----------------------------+----------------------------+---------------------+-----------------------------------------------+-------------+--------------+
|  1 | admin      | $P$B4GLC0D3Kfg2jP1e/JtCye7u0HN1.P1 | admin         | saitamacrewxploit@gmail.com | http://wptest.zukatech.com | 2022-08-09 17:35:22 | 1660099105:$P$Bef0365ngY2Cd.xf0lCzf7cGYILhgV. |           0 | admin        |
+----+------------+------------------------------------+---------------+-----------------------------+----------------------------+---------------------+-----------------------------------------------+-------------+--------------+
1 row in set (0.001 sec)

MariaDB [DB_NAME> update wp_users SET user_pass = "$1$uOBrcYb.$uquyOliTqHPWmJjeEI14n1" WHERE user_login = "admin";
Query OK, 1 row affected (0.001 sec)
```

```$1$uOBrcYb.$uquyOliTqHPWmJjeEI14n1```は 'admin' のパスワードハッシュ。
```openssl passwd -1 admin``` で作成ですが、実行するたびに違うものになります。

無事ログインできれば、管理画面から適切なパスワードに変更しておく。

# 最後に

今回ハマったことは、データベースをまるごとリストアすれば問題ないので、スクリプトでダンプファイルからデータベースに流し込む処理にする予定。
[UiPath]項目を選択アクティビティでワイルドカードを使う

# 項目を選択アクティビティのおさらい
UiPathを使って自動化するときにリスト項目から選ぶ時がある。
例えばこのようなケース

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707463/18ba3896-6997-c879-2a4a-0d10f0aba7ed.png)

この要素を選ぶときには「項目を選択」というアクティビティを使う。
「選択する項目」プロパティには文字列型で値が入る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707463/d2a5e518-8d49-a5bd-a5a1-6f89579f6191.png)

# 文字列が固定ではない場合
この文字列型はリストから選ぶ形式になっている。
多くのケースでは問題ない。例えば「男性」「女性」を選ぶようなケースは動的にリスト項目が変わるものではない。

今回の例では、本日の日付の場合は【本日】というプレフィックスがつき、曜日や祝日が含まれる。
動的に文字列を作れなくはないが、苦労する。

# ワイルドカードを使える
実はワイルドカードを使える。

`"*8月14日*"` 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707463/f817159f-2298-bce3-91b3-5e3af6771cf8.png)

ワイルドカードを使うことで前後の文字列に関わらず選択可能。
以下のように正しく選択できている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707463/2eeb986a-1bdb-cede-6f41-4df926043edd.png)
Ubuntu22.04 で フルアクセス共有フォルダを samba で作成する



Ubuntu のファイルを samba 経由で Windows PC に共有する
GUI の方が簡単だろうけれども、今回は CUI で。
さくっと共有するようにしたメモ。

# 共有方針

- Windows からアクセス
- 認証なしでフルアクセス共有
- ワークグループ共有

# 環境

- サーバ  Ubuntu22.04 LTS AMD64
- クライアント Windows10 Pro 21H2

# samba インストールと設定
## インストール
```
$ sudo apt update
$ sudo apt install samba smbclient cifs-utils
```

## 共有場所をサーバ内ローカルストレージ内に作成

```
$ sudo mkdir /samba
$ sudo chmod 777 /samba
```
## samba.conf を設定し、サーバサービスに反映

```
$ sudo vim /etc/samba/smb.conf
```
[global] に以下のように追記
```
unix charset = UTF-8
dos charset = CP932
```

``` interfaces = 127.0.0.0/8 eth0 ```
とあるところを自分のネットワークに合わせて以下のように書き足し

```
;   interfaces = 127.0.0.0/8 eth0
interfaces = 127.0.0.0/8 192.168.42.0/24
```



以下のようになっているのを確認
```
# This option controls how unsuccessful authentication attempts are mapped
# to anonymous connections
   map to guest = bad user
```


ファイルの最後に共有ポイントを以下のように追記 ここでは 「dekopon」という名前にしました。
```
[dekopon]
   path = /samba
   writable = yes
   guest ok = yes
   guest only = yes
   force create mode = 777
   force directory mode = 777
```

反映
```
$ sudo service smbd restart
$ sudo service nmbd restart
```

# 設定のチェック
```
$ testparm
Load smb config files from /etc/samba/smb.conf
Loaded services file OK.
Weak crypto is allowed
WARNING: The 'netbios name' is too long (max. 15 chars).

Server role: ROLE_STANDALONE

Press enter to see a dump of your service definitions
```

今回はこのまま公開します

# 動作チェック

MS-Windows から、 `\\192.168.42.100` を開けると dekopon が見えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8eff3112-f9e1-bae1-15cc-78a31b3212a6.png)


# トラブルシューティング

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7448474a-a4a9-ee79-c4a9-0c2fdf02aafa.png)

こうなったとき、よく見たら、 smb.conf の中身がミスタイプでした。

```
[dekopon]
   path = /samba
   writable = yes
   guset ok = yes
   gest only = yes
   force create mode = 777
   force directory mode = 777
```