OmniAICreator/Qiita-1.07M huggingface dataset:
【Jest】new Date()をモック化する方法

### この記事の概要

`new Date()`はテスト時には固定の値を返して欲しいのでその方法を記載した簡易メモ

### 方法１：useFakeTimers, setSystemTimeを使う
```hoge.spec.ts
const mockDate = new Date(2021, 0, 1, 1, 1, 1);
jest.useFakeTimers();
jest.setSystemTime(mockDate);
```
Jest公式通りの多分一番簡単なベストな方法
https://jestjs.io/ja/docs/timer-mocks

<font color="Red">【追記】
非同期処理が入っているとreactのコンポーネント生成が終わる前にDOMの判定をしてしまったり、Timeoutになってしまったりします。
その場合は</font>
```
.useFakeTimers({
    doNotFake: [
      "nextTick",
      "setImmediate",
      "clearImmediate",
      "setInterval",
      "clearInterval",
      "setTimeout",
      "clearTimeout",
    ],
  })
```
<font color="Red">と記述すると直ります
参考: https://github.com/nock/nock/issues/2200#issuecomment-1280957462
なので個人的に方法2の方が良いのではないかと思えてきました・・</font>
※`@types/jest`のversionが古いと`doNotFake`指定できません

### 方法２：globalのDateにspy
```hoge.spec.ts
const mockDate = new Date(2021, 1, 2, 2, 2, 2);
const spy = jest.spyOn(global, 'Date').mockImplementation(() => mockDate);
```
<font color="Red">※dayjsも内部ではnew Dateしているので、mock化できます</font>
※`@types/jest`のversionが古い場合は`mockDate as unknown as string`
※Date.now()を使っている箇所があるとエラーになるので方法1にした方が良いかもしれません

### 方法３：spy用の関数を別途用意
```date-utls.ts
export function getNow() {
    return new Date();
}
```
```hoge.spec.ts
import * as DateUtils from './date-utils';

const mockDate = new Date(2021, 2, 3, 3, 3, 3);
const spy = jest.spyOn(DateUtils, 'getNow').mockReturnValue(mockDate);
```
※`new Date()`を使うのは`getNow()`だけ。他は全て`getNow（）`を使わないといけない

<font color="Red">ひと手間かかるけど個別のテストごとに値変えて確認する時などに割と便利</font>

### その他

`Math.random()`の固定化も上記2、3の感じでイケる
https://stackoverflow.com/questions/41570273/how-to-test-a-function-that-output-is-random-using-jest

コード全体、バージョン情報等はこちら

https://github.com/yamatoto/jest-sample
`https://github.com/yamatoto/jest-sample/tree/master/src/views/clock`
ResourceHintsを簡単に使えるようにするためのカスタムフックの紹介

## はじめに

[Qiita株式会社 Advent Calendar 2021](https://qiita.com/advent-calendar/2021/qiita)の23日目(2)の担当は、Qiita株式会社プロダクト開発グループの@getty104です！

https://qiita.com/advent-calendar/2021/qiita

## これは何
Qiitaでは、フィードページなどで記事ページのロードを高速化するために、ResourceHintsを用いたページのprefetchを行っています。
これをQiitaではどう実現しているかを紹介します。

## ResourceHintsって何
細かい説明は省きます。ページの事前読み込みを行うためのブラウザの機構です。
詳しい説明は以下をご覧ください。

https://qiita.com/ohakutsu/items/9b8d4ca39d23774c2e5a

## ResourceHintsを使う方法
↓のようなタグをHTMLのheadに追加します。

```html
<link rel="prefetch" href="/" as="document">
```

↑のタグをQiitaに追加するとすると、Qiitaのトップページを`prefetch`してくることになります。
`prefetch`は「ブラウザのリソース取得までのフロー」のリソースの取得まで事前に行います。
よって、このタグを追加することで、次にトップページに訪れるとトップページはリソースの取得はスキップし、描画から始めることができるようになり、ページ表示速度が高速化します。

## 悩みどころ
ResourceHintsの仕組みとしては前項の内容の通りなのですが、一つ悩みどころがあります。
それは「prefetchするリソースをいかに動的に取得するか」です。
単純にprefetch用のタグを事前に埋め込むとすると、訪れなかったページのprefetchは余分になります。
逆に全てのページのprefetchを行わずに特定のページのみのprefetchを行うとすると、prefetchできないページに訪れる確率が上がり、思ったほどの高速化は見込めません。
Qiitaの場合フィードページは記事は初期ロードで30、またランキングやその他リンクなど、数え切れないほどのリンクが存在します。
その中からユーザーが実際に訪れるページを予測するのはとても難しいです。

ResourceHintsを実際に使うとすると、以下のような条件を満たした運用を行いたいと思うはずです。

- 不要なページのprefetchは行わない
- 訪れるページのprefetchは（ほぼ）必ず行う


## 解決方法
QiitaではフロントエンドにReactを用いており、Reactのカスタムフックで動的にResourceHintsの実行を行う機構を作っています。
ResourceHintsのカスタムフックは以下のようなものです

```ts
import { useCallback, useRef } from 'react'

interface FetchType {
  rel: 'dns-prefetch' | 'preconnect' | 'prefetch'
  url: string
  resourceType: 'document' | 'image' | 'script' | 'style'
}

export const useResourceHints = () => {
  const fetchedRef = useRef(new Set<string>())

  const fetchResource = useCallback(({ rel, url, resourceType }: FetchType) => {
    if (document && !fetchedRef.current.has(url)) {
      const linkElement = document.createElement('link')
      linkElement.rel = rel
      linkElement.href = url
      linkElement.as = resourceType
      document.head.appendChild(linkElement)

      fetchedRef.current.add(url)
    }
  }, [])

  return { fetchResource }
}
```

このカスタムフックは、以下のような処理を実現します

- fetchResource({rel, url ,resourceType })を実行する
- urlが以前prefetch済みだったら→何もしない
- urlがまだprefetchしたことがなかったら→`head`タグ内に以下のようなタグを追加する
    - `<link rel={rel} url={url} as={resourceType}></link>`
    - このタグを追加したタイミングで、タグの処理が発火しprefetchが始まる

このカスタムフックはコンポーネント内で以下のように利用しています。

```tsx
const Component = ({ url }: { url: string }) => {
  const { fetchResource } = useResourceHints()

  return(
    <a href={url} onMouseEnter={() => fetchResource({rel: 'prefetch', url: url, resouceType: 'document' })}>
      Click me!
    </a>
  )
}
```

このように`onMouseEnter`のイベントで`fetchResource`を実行するようにすることで

リンク先のページに訪れようとする→リンクの上にカーソルを持ってくる→事前にデータをprefetchする→クリックする→ページを移動する

という処理を実現しています。これがまさに先ほど上げた条件の

- 不要なページのprefetchは行わない
- 訪れるページのprefetchは（ほぼ）必ず行う


を実現している方法になります。

## 課題

このような方法でprefetchを過不足なく行う状態を実現していますが、この方法にもまだ課題があると思っています。
課題は「prefetchが完了するまでにリンクをクリックしてしまうとページの高速化は行えない」ことです。
これはページ自体の表示速度を上げ、`prefetch`が完了するまでの速度を上げていくしかありません。
Qiitaのパフォーマンスを上げることはそのままユーザー体験の向上につながります。
より快適な体験を提供するためにも、引き続きQiitaの改善を行っていきます。


## 最後に

Qiita株式会社ではMeetyを開設しています。
Qiitaの技術について情報交換をしたい方がいれば、ぜひこちらから気になるをよろしくお願いします！

https://meety.net/matches/JkVrBQmJVoST
PHP8.1で利用可能になった$_FILESのfull_pathを試してみた

随分前に「[&lt;input type="file"&gt;でディレクトリを丸ごと送信したい](https://qiita.com/akase244/items/f5f7287cfe28bebe00fc)」という記事を書いたんですが、この時点ではディレクトリ構造をサーバー側で受け取るには送信時にクライアント側で別途対応する必要があり少々面倒でした。

[PHP 8.1.0がリリース](https://www.php.net/archive/2021.php#2021-11-25-1)され、その新機能の中でスーパーグローバルの `$_FILES` に `full_path` という項目が追加されました。これによりアップロードしたファイルのディレクトリ構造の情報を取得することができるようになりました。

- 参考URL
    - [複数ファイルのアップロード](https://www.php.net/manual/ja/features.file-upload.multiple.php)
    - [Directory Uploads in PHP 8.1](https://php.watch/articles/php81-directory-uploads)
    - [PHP 8.1: $_FILES: New full_path value for directory-uploads](https://php.watch/versions/8.1/$_FILES-full-path)
    - [【PHP8.1】PHP8.1がリリースされたので新機能全部やる](https://qiita.com/rana_kualu/items/e350b8ff80f929626eb9)

---

実際に試してみるためにいくつか準備を行います。

まずは、「[&lt;input type="file"&gt;でディレクトリを丸ごと送信したい](https://qiita.com/akase244/items/f5f7287cfe28bebe00fc)」の記事の際に利用したものと同じ構成ですが、以下のようなファイル群を準備します。

```
top
├ test.html
└─ second
    ├─ test.html
    └─ third
        └─ test.html
```

次にファイルをアップロードするための画面となる `index.html` を準備します。

```
<html>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
    <input type="file" name="upfile[]" webkitdirectory>
    <input type="submit" />
</form>
</body>
</html>
```

アップロード時に `$_FILES` の中身を確認するための `upload.php` を準備します。

```
<?php
var_dump($_FILES['upfile']['name']);
var_dump($_FILES['upfile']['tmp_name']);
var_dump($_FILES['upfile']['full_path']);
```

---

動かす環境は何でもよいのですが、今回はDockerを利用することにしました。

まずは PHP7.4系 の最新バージョンである 7.4.27 を起動して、上記の `index.html` と `upload.php` を配置します。

```
$ docker container run -it -p 8080:8080 --rm php:7.4.27-cli /bin/bash
```

次に、Dockerコンテナ内でビルトインサーバーを起動します。

```
# php -S 0.0.0.0:8080
```

ブラウザで http://localhost:8080/ にアクセスすると、以下のような画面が表示されるかと思います。
![スクリーンショット 2021-12-22 21.08.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23093/e1d6916d-f4ab-d1ad-96d1-f6d3d5ec5896.png)

「ファイル選択」ボタンから事前に準備しておいたファイル群の「top」ディレクトリを選択して「送信」ボタンをクリックします。

PHP7.4系なので、 `$_FILES` の `name` と `tmp_name` の内容は確認できますが、未対応の `full_path` の中身は `NULL` となっています。

```
array(3) {
  [0]=>
  string(9) "test.html"
  [1]=>
  string(9) "test.html"
  [2]=>
  string(9) "test.html"
}
array(3) {
  [0]=>
  string(14) "/tmp/php0xAVds"
  [1]=>
  string(14) "/tmp/phpcGnajr"
  [2]=>
  string(14) "/tmp/phpTOKfVq"
}
NULL
```

---

それでは本題の PHP8.1系 の最新バージョンの 8.1.1 を起動して、同様にアップロード画面からファイル群を送信してみます。

```
% docker container run -it -p 8080:8080 --rm php:8.1.1-cli /bin/bash
```

PHP8.1系では `$_FILES` の `full_path` 対応しているので、今度は送信したファイル群のディレクトリ構造の情報が取得できました。

```
array(3) {
  [0]=>
  string(9) "test.html"
  [1]=>
  string(9) "test.html"
  [2]=>
  string(9) "test.html"
}
array(3) {
  [0]=>
  string(14) "/tmp/phpIXmVWi"
  [1]=>
  string(14) "/tmp/phpupEHqh"
  [2]=>
  string(14) "/tmp/phpeCYwdi"
}
array(3) {
  [0]=>
  string(13) "top/test.html"
  [1]=>
  string(20) "top/second/test.html"
  [2]=>
  string(26) "top/second/third/test.html"
}
```
ロボコンサークルの新入生教育ってむずくね

#概要
今年ロボコンサークルで新入生教育担当になった僕が大変だったことを書く記事です。アドベントカレンダーのネタが思いつかなかったのでとりあえず書いてみました。

# 大変だったこと

## 1.コロナ
まずはコロナ系です。コロナ禍特有の事情でいろいろ大変でした。
### 予定が崩壊
コロナのせいで予定がいろいろ狂いました。
僕が新入生教育担当になったのは大体今年の3月くらいだったのですが、そのときに他の新入生教育担当と3人でどんな感じで進めていこうかって計画を何度も練っていました。
最初には大体このくらい来て、学祭ではこれくらい入ってくれて、このあたりで人員増やして対応して、ここで一旦部内戦挟んで…みたいな感じで考えてました。
しかし、いざ4月になって新入生が入学した矢先、<font color="red">緊急事態宣言</font>が発令されちゃいました。
大学の活動はもちろんほぼストップ。大学が始まって1週間くらいでオンライン授業になったせいで対面授業お試し期間とか言われてましたね。（うちの学部はそもそも対面授業なかったけど）
やるはずだった大学祭は中止になり、対面でやる予定だった新入生向けの勉強会とかも全部オンラインになっちゃいました。部内戦も計画していたんですが、開催できませんでした。
結局この緊急事態宣言は9月まで延長されました。
今振り返ってみると、当初の予定は大体コロナで狂ったなあと思います。

### 人が集まらない
今でこそうちのサークルは昨年以上に1回生が入部してくれていますが、前期はとても少なかったです。
オンラインで開催している勉強会は最初こそ10人弱来てくれていたものの、だんだん数が少なくなり、前期の中間明けでは4,5人しかいませんでした。回路の勉強会に至っては1人しか参加者がいないこともありました。
入部の申請を出してくれている人数に対して、勉強会の参加者がかなり少ないという状況でした。
2回生の周知不足、中間試験などの要因もありましたが、この人数にはちょっと危機感を覚えましたね。
なんとか人数が集まってくれて良かったです。

### 対面で会えない
前期の後半からは大学の活動基準が緩和されて、対面で新入生を迎え入れることができたのですが、前期の前半は完全オンラインでお互いに顔を合わせられない状況でした。勉強会もオンラインだとどこまで理解できていてどこがわからないとかがうまく把握できず、もどかしい思いをしました。やっぱり、ものづくり系サークルで勉強会がオンラインっていうのは致命的だと思ってます。加工ができない、マイコンが触れないって状況だと正直何もできません。やってもらうことで初めてわかることがほとんどなのに、こちらから一方的に教えるだけになってしまうのは良くないですね。（仕方ない部分もありますが…）

## 2. 環境構築、カリキュラムの組み方
### 環境構築
うちのサークル、環境構築することがめちゃくちゃ多いんです。まずは連絡ツールとしてslack, 各班でCADやコンパイラなど様々なソフトを新入生のPCにぶちこむ必要があります。

特に制御班でプログラミングをするとなると、環境変数をいじったりするところがでてきたりコマンドプロンプトを使わざるを得ないこともあります。普通の人だったら怖くて触らないところですよね。僕もあんまり触りたくないです。
こういう環境構築をときにはオンラインで、上回生数人で一斉にさばいたりしてました。結構大変でした。
新入生が持っているPCは十人十色で、PCのメーカーは当然違いますし、授業の関係で環境をすでに構築していたせいで、Python周りや環境変数がぐちゃぐちゃになっていることもよくあります。授業ではオンラインコンパイラ以外使わんでほしい（）

また、今年からの事情ですが、生協でM1 Macを販売し始めたため、新入生でも数人M1 Macを所有している人がいました。
こいつが曲者で、Windowsでしか入らないソフトがあったり、ARMコア使ってるせいで動かなかったりするんですが新しい機種だから全然情報がなくてまじで苦労しました。
Macは元をたどればLinux系なんでうまく使えば開発向きの優良PCになれると思うんですが、如何せん新しすぎましたね...来年はもっと楽に環境構築できると信じてます。
### カリキュラム
今年は勉強会のカリキュラムの組み方にも悩みました。通常、先輩達が作ってきた資料を用いて勉強会を行うのですが、オンラインでの勉強会にも対応できるよう、内容や演習量を調整しました。
ただ、どうしても教えたいことと実際にわかってくれていることには差が生まれてしまいます。ほとんどが大学からロボコンを始めるうちのサークルで、学部でも学ばないケースが多いプログラミングをどうやって少ない時間で教えようか、というのはとても難しい問題でした。結局、勉強会では教えたいことは十分には教えきれず終わってしまいました。
個人的にはここがかなり後悔しているところです。新入生にもちゃんとした知識を教えられないままロボコンに向かわせることになってしまい、申し訳なく思います。

# おわり
長々と自分の苦労話をしてしまいました。すみません。
結局僕たち2回生世代は、コロナ禍で新入生教育を受け、コロナ禍で下の世代に新入生教育をすることになる初めての世代でした。2年もコロナを経験しているんだから、この先もまだ続くであろうこの状況に対する最適解が思いついてもおかしくないと思うのですが、全然浮かばないですね。どう考えても対面でできる方がいいです。来年はずっと対面でできるといいな…
統計学入門p65 ブートストラップ法の実装


まずはデータを準備します。

```Python
import numpy as np
import pandas as pd

from sklearn import datasets

iris_all = datasets.load_iris(as_frame=True)
iris = iris_all['data']
iris_target = iris_all['target']
iris.shape,iris_target.shape

# iris_all.keys()
# iris_all['DESCR']

iris = pd.concat([iris,iris_target],axis=1)
iris_0 = iris.query('target==0')
```
### ブートストラップ法による標本平均の分布のサンプリング
対象 Petal length 花びらの長さ
##### 1. 一様分布に従って乱数を len(iris_0) 個生成
##### 2. そのPetal lengthの平均を標本平均とする
##### 3. 1~2を200回繰り返す
##### 4. 標本平均の分布の様子を観察

```Python
cycle = 200
sample_mean_list = []
for i in range(cycle):
    # 1.Generate a uniform random sample from np.arange(len(iris_0)) of size 50:
    random_numbers = np.random.choice(len(iris_0), len(iris_0))
    # 2.
    sample = iris_0.iloc[random_numbers]
    sample_mean = np.mean(sample['petal length (cm)'])
    sample_mean_list.append(sample_mean)

import matplotlib.pyplot as plt
plt.style.use('ggplot')
plt.hist(sample_mean_list)
```
結果は以下の通り。単純で強力な手法だなと思いました。詳しくは統計検定準１級の内容らしいの今回はここまで。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1347377/524d926f-b850-bab5-285c-ed51d3165bd4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1347377/1000da36-6326-0237-0b5a-d3fceffe6c7b.png)
【Db2】PID1問題の回避策【Docker】

# はじめに

IBM Cloud Paks Advent Calendar 2021 22日目です。
CP4Dのカートリッジ製品であるDb2のネタについて書いていこうと思います。

## まずは、Dockerの 「PID1問題」 ご存知でしょうか？

PID1問題とは、コンテナ上で実行されるアプリケーションのプロセスが PID1 で実行されることで、コンテナに対して SIGTERM などのシグナルを送信してもコンテナ内のプロセスが正常に終了しないというものです。

詳細は `Docker PID1` で検索するとたくさんヒットしますので、検索してみてください。

本記事ではDb2のコンテナ(Client側)でこの問題に遭遇しましたので対処法についてお話しします。

## 何が発生していたのか？

Client側のコンテナの動作確認時の流れが下記となります。
コンテナ起動後、rootでDb2の環境設定とカタログ設定をシェルで実行し、
以降はユーザーを切り替えて、任意のタイミングでDb2を操作するシェルを実行する。
と一見問題なさそうな流れです。(有識者ならそうでもないのかもしれませんが…)

しかし、<font color="Red">rootでDb2の環境設定とカタログ設定をシェルで実行</font>ここが落とし穴で、rootでシェルを実行するとPPID1となり結果的に、PID1のプロセスが適切に終了できず**Db2のプロセスがdefunctとして残ってしまいます。**

## どう回避するか

色々と試しました。
tiniの利用、停止シグナルの変換、Docker→Podmanに置き換え…
が、最終的には下記の様な対策に落ち着きました。

1. DockerfileのCMDに、「Db2の環境設定とカタログ設定を行うシェル」を指定
1. 指定したシェルの中の末尾に無限ループを追加

### 解説

1.は必ず必要な処理となるので言わずもがなCMDに指定…ですが、指定しているシェルは環境設定およびカタログ設定さえできれば良いので、逆にそれができれば**終了する必要のないプロセス**でもあるので、2.の無限ループを入れることで終了しない様にしてあげます。

こうすることでdefunctが残ることもなく、以降ユーザーを切り替えてDb2を操作するシェルを実行しても問題ない状況となります。

<font color="Gainsboro">年末年始時間のある時に図などを追記できればと思います…</font>
Macで矢印（↑など）を簡単に入力する

##矢印変換キー

日本語入力にして下記を入力すると自動的に変換されます

|　キー　|　出力　|
|:-----------|------------:|:------------:|
|　zk　|　↑　|
|　zh　|　←　|
|　zj　|　↓　|
|　zl　|　→　|


##ちなみに

他にも「z」から始まるショートカットキーはいくつかあるようです。

|　キー　|　出力　|
|:-----------|------------:|:------------:|
|　z[　| 『　　|
|　z]　| 』　 |
|　z.　|・・・|
|　z,　|　　・・　|
|　z/|　　・ |


などもあるみたいですが**Macは対応していない**みたいです。
(四面体の体積)「2021 奈良女子大学 数学 問題Ⅱ」をsympyでやってみた。(その1)

公式ページ
問題Ⅱ<令和3年度一般選抜個別学力検査【後期日程】

http://koto.nara-wu.ac.jp/nyusi/R3Rsugaku_q.pdf#page=3

出題意図・解答例

http://koto.nara-wu.ac.jp/nyusi/R3Rsugaku_a.pdf

ホームページ

http://koto.nara-wu.ac.jp/nyusi/toukei.html


# 問題

https://mathexamtest.web.fc2.com/2021/202110631/2021106310200mj.html#q-0202

# Pycharmで

classで何とかなりますか？アドバイスよろしくお願いします。
四面体の体積の計算に行列式は、使っていません。


```python
from sympy import *
var('d11')
d12=d11*Rational(1,2)/sqrt(3)*2
h11=d11*Rational(1,2)*sqrt(3)
h12=sqrt(d11**2-d12**2)
v11=(Rational(1,2)*d11*h11)*h12*Rational(1,3)
v12=v11.subs({d11:d11*Rational(1,3)})
d20=h11*(Rational(1,3)*Rational(2,3))
d21=sqrt((h12*Rational(1,3))**2+d20**2)
d22=d20*Rational(1,2)*sqrt(3)*2
h31=h12*Rational(1,3)
v31=v11*Rational(1,3)**3
d41=sqrt((d11*Rational(1,2)*Rational(1,3))**2+(h11*Rational(1,3))**2)
h41=sqrt(d41**2-(d41*sqrt(2)*Rational(1,2))**2)
v41=d41*d41*h41*Rational(1,3)*2
mySubs={d11:1}
print("#(1)体積-1,2",v11,v12)
print("#(2)正四面体 ",d21,d22)
print("#(3)体積-重心",v31)
print("#(4)体積-八面",v41)
print("")
print("#(1)体積-1,2",v11.subs(mySubs),v12.subs(mySubs))
print("#(2)正四面体 ",d21.subs(mySubs),d22.subs(mySubs))
print("#(3)体積-重心",v31.subs(mySubs))
print("#(4)体積-八面",v41.subs(mySubs))
print("")
print("#(1)体積-1,2",float(v11.subs(mySubs)),float(v12.subs(mySubs)))
print("#(2)正四面体 ",float(d21.subs(mySubs)),float(d22.subs(mySubs)))
print("#(3)体積-重心",float(v31.subs(mySubs)))
print("#(4)体積-八面",float(v41.subs(mySubs)))
#(1)体積-1,2 sqrt(2)*d11**2*sqrt(d11**2)/12 sqrt(2)*d11**2*sqrt(d11**2)/324
#(2)正四面体  sqrt(d11**2)/3 d11/3
#(3)体積-重心 sqrt(2)*d11**2*sqrt(d11**2)/324
#(4)体積-八面 sqrt(2)*d11**2*sqrt(d11**2)/81

#(1)体積-1,2 sqrt(2)/12 sqrt(2)/324
#(2)正四面体  1/3 1/3
#(3)体積-重心 sqrt(2)/324
#(4)体積-八面 sqrt(2)/81

#(1)体積-1,2 0.11785113019775792 0.004364856673991034
#(2)正四面体  0.3333333333333333 0.3333333333333333
#(3)体積-重心 0.004364856673991034
#(4)体積-八面 0.017459426695964137
```
書き捨てるためのRust

# はじめに

Rustは「きちんとしたプログラムを書く時にはいいけど、書き捨てのプログラムを書くには向いていない」と言われることがあるようです。「一般論としては全くその通り」と思う一方で、自分自身を振り返ってみると、これまでPythonで書いていたような書き捨てに近いプログラムも全部Rustで書くようになっています。

なぜ書き捨てのプログラムもRustで書くのかを考えてみると

* 最初は書き捨てだと思っていても、手直ししながら使い続けることは意外と多い
* コンパイラが割と多くのエラーを捕捉してくれるのでデバッグの時間が短くて済む
* 記述量の多さはエディタの補完があってあまり気にならない

といったあたりが理由になっています。

そうはいってもRustがいろいろと面倒な言語であることには違いないので、書き捨てるときは普段のRustプログラミングとは少し違った書き方をした方がより早く書けるのではないかと思います。
この記事ではそのようなときのためのTipsをまとめてみました。他にもありそうならコメント欄でお願いします。

# ライフタイムを避ける

なんらかの文字列を構造体に入れたいときに、「この文字列は変更されないから `&str` で入れよう」とか思ってしまうかもしれませんが、これはいけません。

```rust
struct<'a> A {
    name: &'a str,
}
```

参照を入れるということはライフライム修飾が必須となり、この構造体を扱うあらゆるところにライフタイムが出現することになります。全然書き捨て易くありません。

素直に `String` を持たせましょう。

```rust
struct A {
    name: String,
}
```

同様にたとえ固定値の配列だったとしても `&[u32]` ではなく `Vec<u32>` にしましょう。
こうすることで、その構造体を作る度に文字列のメモリコピーが発生したりしますが、現代のマシンにおいて（たいていの場合）メモリコピーなどたいしたことではありません。

`clone`も積極的に使うといいでしょう。「Borrow checkerに怒られたらとりあえず`clone`する」くらいでもいいと思います。
`Rc`や`Arc`でBorrow checkを回避するというのも考えられますが、そこまでやると書き捨ての範囲を超えてくるような気がします。

# unwrapする

Rustでは失敗するかもしれない関数から `Result` が返ってくるのでエラー処理をきちんとする必要があります。
しかし書き捨てるときにはエラー処理をする必要はないので、`unwrap`で結果を取り出せばいいでしょう。

```rust
let mut f = File::open("foo.txt").unwrap();
```

きちんとしたプログラムでは `?`を使ってエラー処理したり、パニックさせる場合でも `expect` を使って理由を明示した方がいいですが、書き捨てる場合はとりあえず `unwrap` でいいと思います。

# dbg/Debugを使う

何か表示したいときは `dbg!` マクロを使うといいでしょう。フォーマットの制御などはできませんが「なんでもいいから表示したい」というときには十分です。このときとりあえず `&` で参照にしておくと所有権を取られないので付けておきましょう。

```rust
dbg!(&hoge);
```

これを使うために構造体にはとりあえず `#[derive(Debug)]` を付けておくといいでしょう。

# examplesをコピペする

何かライブラリを使いたいと思ったときは、そのリポジトリの `examples` というディレクトリを探しましょう。たいてい簡単な使用例がコンパイル可能な状態で置かれているので、それをコピペして作業を始めればいいと思います。
`examples`ディレクトリはライブラリ本体をCargoでコンパイルすると一緒にコンパイルしてチェックされるので、古くなっていて使えないということはめったにありません。

# まとめ

Rustを書き捨てるときのTipsをまとめてみました。Rustのいいところは、ここで書いたような雑な記述をしても、後々のリファクタリングがやりやすいところです。
`unwrap`している箇所はgrepすれば一目瞭然なので、そこをちゃんとしたエラー処理に直せばよいですし、`clone`しすぎて遅くなっているならその部分だけ改善することもできます。
データ構造に参照を持たせるのはさすがに大改修になってしまいますが、それでも修正が必要な箇所はコンパイルエラーとして明示されるので1個づつ潰していけばなんとかなることが多いです。
WSL2 でnpm installが遅い時のもう一つの対策

はじめまして。ウチイダです。Qiita初投稿です。
普段はブログを書くのですが、今回はQiitaにも書きます。

# 結論から
WSL2で、Linux側のファイルシステムにファイルが置いてあってもnpmがとても遅いときに試してみてほしいことです。
パッケージ配信サーバの名前解決ができてないことが原因の場合があります。
以下のコマンドでWSL2が利用するネームサーバーを8.8.8.8に変更すると改善するかもしれません

``` bash
$ sudo rm /etc/resolv.conf
$ sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
$ sudo bash -c 'echo "[network]" > /etc/wsl.conf'
$ sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'
$ sudo chattr +i /etc/resolv.conf
```

コマンド実行後、Powershellやコマンドプロンプトから`wsl --shutdown` を実行してWSL2を再起動してください。

# 環境情報
- OSバージョン: Windows 11 Pro 21H2(ビルド 22000.376)
- WSLカーネル バージョン: 5.10.60.1-microsoft-standard-WSL2
- Ubuntu バージョン: 20.04.3 LTS (Focal Fossa)

# WSL2 でnpm がめちゃ遅い問題
ウチイダもずっと悩まされていたこの問題。
コンソール上のスピナー（点がくるくる回るやつ）が止まってしまうし、プログレスバーも動かない。
最終的にタイムアウトになってしまい、なかなか開発に着手できないことが多々ありました。

解決しようと思って検索すると、だいたい「/mnt 配下にファイルを置いてはいけない」という内容のページが出てきます。
WSL2のファイルシステム上でもやっぱり改善せず。
結構時間をかけて調べたけど、原因が特定できず、長いこと放置していました。

# 名前解決の問題だった？resolve.confを修正したら改善した
WSLの通信状況について別の問題も出てきたので、改めて調べてみました。
どうやら名前解決ができてないことが原因のようでした。
その方向でググり直してみたら、以下のページを見つけました。

https://www.reddit.com/r/bashonubuntuonwindows/comments/nt8asc/npm_install_extremely_slow_on_wsl2/

こちらのコメントの中で、`resolv.conf` を修正する解決策を提示しているものがありました。

``` bash
$ sudo rm /etc/resolv.conf
$ sudo bash -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf'
$ sudo bash -c 'echo "[network]" > /etc/wsl.conf'
$ sudo bash -c 'echo "generateResolvConf = false" >> /etc/wsl.conf'
$ sudo chattr +i /etc/resolv.conf
```

上記のコマンド実行後、PowerShellや cmdで`wsl --shutdown` を実行してください。

ウチイダの環境では、これでWSLのネットワーク関係で困っていたことがいくつかまとめて解決しました。
是非試してみてください！

# その他の効能
この設定を行ってから、ウチイダの環境で改善した事象がいくつかありました。

1. git clone の動作不良
名前解決の問題に気づいた原因になったのが、これでした。
github.comの名前解決に失敗することがあり、git コマンドでリモートリポジトリにアクセスできなくなることがしばしばありました。

2. docker コマンド の速度改善
きちんと時間を測ったわけではないのですが、docker pullでイメージを取ってくる時間や、ビルドにかかる時間が短くなりました。

# 余談、なぜQiitaに書いたのか
ここからは余談です。
じつは同じような内容を自身の備忘録ブログにも書いたのですが、今回はQiitaにも書いてみようと思いました。
理由はいくつかあります。

## ひとつめ、日本語の検索キーワードに引っかかるように
これが大きな理由です。
日本語の情報では、この事象に対してresolv.conf を変更するという方法が紹介されているものが検索上位に表示されませんでした。
Qiitaのドメインパワーで上位に表示されないかな…と考えて、こちらでも記事にしてみることにしました。

## ふたつめ、副作用についての知見を得たい
とりあえず解決はしましたが、この変更によってWSL2になにか他の問題が起こりそうでドキドキしています。
ふつうのLinuxならともかく、Windowsと密接に連携しているので、なにが起こるのか理解しきれていません。

もともと設定されていたvEthernetじゃないとうまくできないことがあるかもしれない…と心配なので、
自身のブログだけでなく、人目につきそうなQiitaにも書いておくことにしました。

WSL2とWindows ホストの名前解決の連携について、どなたか詳しい方がいれば、問題や懸念点などをご指摘いただけると嬉しいです🙇

# まとめ
改めて、英語で情報を取りに行くことの効果を実感しました…
日本語での検索で引っかからなかったものは、今回のようにまたQiitaに書いていこうと思います。
RESTコンポーネントで外部に送信したHTTPリクエストヘッダの内容を見る方法

# はじめに
先日、RESTコンポーネントについて調査する機会があったのですが、送信したHTTPリクエストのリクエストヘッダの内容を確認しようとして少しはまりました。
RESTコンポーネントをダブルクリックすると起動する「RESTのテスト」ダイアログでテスト実行を行えば一応確認できるのですが、実際にフローを動かしたときの内容を知りたいときにはこの方法が使えないので困ります。
そんな場合にぴったりなツールを最近教えてもらったので、みなさんにも紹介したいと思います。

# 準備
HTTP Toolkitをインストールしてください。

https://httptoolkit.tech/

# テストに使用するAPI
HTTP通信のテスト用に、今回はこちらのAPIを使用させていただきます。

https://weather.tsukumijima.net/

# フローサービス管理コンソールの設定
「設定＞プロキシ」画面でプロキシサーバーの設定を次のように設定します。

| タイプ | アドレス | ポート番号 |
|:-----------|:-----------|------------:|
| HTTP       | localhost  | 8000        |
| HTTPS      | localhost  | 8000        |
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/b22bdd2a-4800-d9df-acbc-bacf53b98b80.png)

「設定＞SSL＞サーバー認証局」画面で「追加」ボタンを押して、次の場所にある認証局証明書をインポートします。
C:\Users\[ユーザー名]Appdata\Local\httptoolkit\Config\ca.pem
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/cc2651ab-9caa-a9a4-0802-68fb7ea8a5fb.png)

# フローの作成
フローはRESTコンポーネントを置いただけになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/25421a13-d645-b5e6-9eef-b6242b1cecc6.png)

RESTコンポーネントのプロパティを次のように設定します。

##### 基本

| プロパティ名 | 値 |
|:-----------------|:--------------------------------|
| URL              | https://weather.tsukumijima.net/|
| プロキシ設定を使用 | はい                            |
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/45a27708-7872-50bf-e089-2b2d94b240d4.png)
##### URLパラメーター

| パラメーター名 | データ型 |  値    |
|:--------------|:--------|:------:|
| city          | String  | 130010 |
※値は東京の地域ID

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/e318e937-eecb-bee6-e29b-a86b9ddc0161.png)

# 実行
HTTP Toolkitを起動した状態でフローを実行すると、左側のリストにHTTPイベントが追加されます。また、右側には選択したイベントの詳細が表示されます。
確認したかったHTTPリクエストヘッダの内容も表示されているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151881/1d64b079-44f9-cd0b-8384-ee40fab068f8.png)

# さいごに
RESTコンポーネント以外でも、HTTP通信を行っていてプロキシに対応しているコンポーネントであれば同じ方法でHTTPリクエストの内容を確認することができます。
HTTP通信で問題が発生した場合は通信内容の確認が問題解決への足掛かりになります。そんなときに今回紹介したツールを使ってみてください。
Postman レスポンスで100MBのファイルが変えるようにしたらエラーが出た

## 目的

- Postmanを用いてファイルダウンロードの処理を実装していたら、エラーが出たため解決策をまとめる

## 出力されたエラー

- `Could not get response`
- `Error: Maximum response size reached`

    ![Postman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/00d059b0-8383-3b4e-7e3f-101b937c2177.png)

## 原因

- Postman側でリクエストのサイズを制限しているようだ。
    - [https://learning.postman.com/docs/getting-started/settings/](https://learning.postman.com/docs/getting-started/settings/)

        ![Setting_up_Postman___Postman_Learning_Center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/526014a0-8f1e-b966-e001-443059bd68de.png)
        ![郵便配達員の設定__郵便配達員学習センター.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7061e91d-d46b-1d31-3665-336aaecc958e.png)

- Postman側で当該の設定を0に設定すればサイズの制限がなくなるっぽい。

## 方法

1. Postmanで右上の歯車のアイコンをクリックする。

    ![Postman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0782cf1b-8ff0-f3f1-3410-ba06b451fbd4.png)

1. 「Settings」をクリックする。

    ![Postman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/2031a153-f41f-bbf0-5f67-d7c95c0e70b4.png)

1. 開いたウインドウの「General」の「Max response size in MB」を任意の値に設定すればOK（制限を設けない場合0を設定する。）

    ![Postman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5268a115-14e1-f269-2f35-59ebafd0b651.png)
C#でカノジョをつくる（22日目）

お疲れ様です。たなしょです。
今日は辞書クラスを改良して形態素解析した名詞を辞書に取り組めるようにしていきたいと思います。この実装でだいぶ会話のバリエーションが増えますね。

## 辞書クラスと単語を分割するクラスの改良
studyメソッドにランダム辞書に登録する処理とパターン辞書に登録する処理を2つ記載していきます。
1.ランダム辞書に存在しない場合、ユーザー発言をランダム辞書に追加します。

```c#
public void StudyRandom(string userInput)
{
    if (_randomList.Contains(userInput) == false)
    {
        _randomList.Add(userInput);
    }
}
```
2.パターン辞書に追加します。ここはちょっと複雑なので細かく説明します。
2-1.形態素と品詞情報を取り出します

```c#
foreach (string[] morpheme in parts)
```
2-2.品詞情報がKeyWordCheck()にマッチするか判定します。

```c#
if (Analyzer.KeyWordCheck(morpheme[1]).Success)
```
2-3パターンマッチした場合はParseItemオブジェクトに格納します。

```c#
foreach (ParseItem item in _patternList)
{
    if (!string.IsNullOrEmpty(item.Match(userInput)))
    {
        depend = item;
        break;
    }
}
```
2-4.ParseItemオブジェクトに存在する場合はParseItemに名詞を追加、形態素のパターンにマッチしなかった場合はパターン辞書に追加します。

```c#
if (depend != null)
{
    depend.AddPhrase(userInput);
}
else
{
    _patternList.Add(new ParseItem(
        morpheme[0],
        userInput));
}
```
2-5.キーワード認定されたユーザ発言を辞書に追加します。

```c#
public void AddPhrase(string userInput)
{
    foreach (var p in _phrases)
    {
        if (p["phrase"] == userInput)
            break;
    }
    _phrases.Add(
        new Dictionary<string, string> {
            { "need", "0" }, {  "phrase", userInput }
        });
}
```
2-6.パターンリストの整形して辞書型に保存して、パターン辞書ファイルに書き込みます。

```c#
List<string> patternLine = new();
     
foreach (ParseItem item in _patternList)
{
    patternLine.Add(item.MakeLine());
}

File.WriteAllLines(
    @"dics\pattern.txt",
    patternLine,
    System.Text.Encoding.UTF8
    );
```
2-7.辞書に登録するためのテンプレートを整形します。名詞とそれに対する応答フレーズを作成しています。イメージは`0##晴れ\t0##今日は晴れだね|0##晴れているよ`のような文字列を整形する。

```c#
public string MakeLine()
{
    string pattern = Convert.ToString(_modify) + "##" + _pattern;
    StringBuilder responseList = new();
    foreach (var dic in _phrases)
    {
        responseList.Append("|" + dic["need"] + "##" + dic["phrase"]);
    }
    return pattern + "\t" + responseList;
}
```

## 少しは賢くなったカノジョ
こんな感じで少しは賢くなりました！ぱちぱち。
![qiita1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268048/cfcde2f4-bf04-d412-aee1-f3c0203607eb.gif)

pattern.txtにも今回のワードが保存されていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268048/cdbe9ef5-69f2-d7d3-e79d-43c8499870d8.png)

## 最後に
形態素解析を取り入れたことによって会話のバリエーションがアップしました！
明日はテンプレートを用意してさらに会話していきます。
残すところあと3日ですね。最後まで頑張ります。
社内の複数のiOSアプリの証明書をどう管理するのか

# はじめに

この記事は[株式会社Diverse Advent Calendar2021](https://qiita.com/advent-calendar/2021/diverse) 22日目の記事です。

直近、社内で扱っている複数のiOSアプリの証明書の管理方法を整えたのでその内容を共有しようと思います。

弊社ではプロダクトごとにチームが別れており、それぞれのチームのエンジニアが手動で証明書の更新などの対応をしていました。

そのため証明書の管理が属人化してしまい、管理者が特定の人に偏っていました。
また新しくジョインしたメンバーは誰がどのように証明書を管理しているのか分かりづらい状況でもありました。

この課題を解決するために導入したのが [fastlane match](https://docs.fastlane.tools/actions/match/) です。

※この記事ではfastlaneの詳しい使い方については触れません。
詳細については公式ドキュメントと以下の記事をご覧ください。
・[公式ドキュメント](https://docs.fastlane.tools/)
・[fastlane match を使用して iOS の証明書管理を行う](https://qiita.com/kotarella1110/items/840af2cf80aaea1fb035#%E5%89%8D%E6%9B%B8%E3%81%8D)
・[[iOS]大規模プロダクトにfastlane matchを導入した話](https://qiita.com/ARATAYOKOYAMA/items/9b98b07461a71c47eac4#match%E3%81%AE%E5%88%9D%E6%9C%9F%E8%A8%AD%E5%AE%9A)


# fastlane matchとは

簡単に説明するとfastlane matchは証明書の作成と削除がコマンドのみで行うことができるツールです。
作成した証明書は以下のストレージに保存され、開発者はここからfastlane matchを使って証明書を取得します。
・Git repo
・Google Cloud
・Amazon S3

# 社内の複数のアプリの証明書をどう管理するのか

###1. App Store Connectに共有アカウントを作成する

fastlane matchで証明書を作成する際に使うアカウントを作成します。
ここで使用するアカウントは社内の誰にも依存しないアカウントを使用するのが望ましいです。

※作成するアカウント権限は**App Manager以上**の権限が必要です。


###2. GitHubに証明書管理用のリポジトリを作成する
社内のiOSアプリの証明書を1つのリポジトリで管理することにしました。
`ios-certificates`のような名前でプライベートリポジトリを作成します。

###3. 各アプリごとにfastlane matchを導入する

社内の各iOSアプリのリポジトリをクローンしてそれぞれのプロジェクトでfastlane matchを導入します。
※ fastlane matchだけを導入することも可能ですが、先にfastlaneを導入し、作成されたfastlaneディレクトリでmatchの導入をすることでfastlaneに関連するファイルが集約されるのでわかりやすいかなと思います。

```
fastlane init

cd /fastlane

fastlane match init
```

Matchfileは以下のようになります。

```
// 2で作成したGitHubのリポジトリのURL
git_url("git@github.com:xxx/ios-certificates.git") 

storage_mode("git")

type("development")

app_identifier(["アプリのBundleID"])

// 1で作成したアカウントのAppleID
username("apple developerのアカウント")
```

app_identifierは各プロジェクトごとに違いますが、それ以外は同じです。

###4. 各アプリごとにfastlane matchを実行する
Matchfileの作成を終えたらfastlane matchを実行して証明書の作成を行います。
弊社では開発用証明書はAutomatically manage signingを使っているので
adhoc, appstore用の証明書だけをmatchで作成しました。

※ 作成時に設定するパスワードは他の人がmatchで証明書を取得する際に必要なので忘れないようにしてください。
※ 1passwordなどのセキュアに社内のメンバーに共有できるツールで管理するのが良いと思います。

```
// 配布用証明書の作成
fastlane match adhoc

// 申請用証明書の作成
fastlane match appstore
```

上記を実行すると指定したGitHubのリポジトリに作成した証明書とプロビジョニングプロファイルが保存されます。
![スクリーンショット 2021-12-22 19.33.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106260/3291eede-a998-2376-5653-6c678506694a.png)


## 証明書の更新

更新は削除と作成を組み合わせて行います。


###1. 期限切れの証明書を削除

```
fastlane match nuke distribution
```
上記のコマンドで期限切れの証明書を削除します。

###2. 各プロジェクトごとに証明書,プロビジョニングプロファイルを作成

nukeで削除した証明書を参照しているプロビジョニングプロファイルも再度作り直す必要があるので各プロジェクトで以下の対応を行います。

```
// 配布用証明書の作成
fastlane match adhoc

// 申請用証明書の作成
fastlane match appstore
```

## デバイスの追加
新しいデバイス追加した際は `--force_for_new_devices` オプションをつけることで更新が可能です。

```
fastlane match adhoc --force_for_new_devices
```


## おわりに

fastlane matchを使うことで煩わしい証明書の管理をとても楽にすることができます。
fastlneを導入したことでコマンドを叩くだけで作成、更新、削除ができるので、READMEなどに手順を記載しておけば開発に関わるエンジニアなら誰でも楽に証明書の管理ができるようになったと思います。

またCIを組む際にもこのfastlane matchはとても便利なので積極的に使っていきたいツールですね！！
neosでlogix その34

#概要

niosでlogixやってみる。
TouchableEventsRelyコンポーネント
Touchable Eventsノードを使ってみた。

#写真

![2021-12-22 06.57.05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/29df70cb-8e74-9a62-d05b-6542ed55b056.jpeg)


#Touchable Events

```
Inputs
 	TouchEventRelay	EventSource
Outputs
 	Impulse	OnEvent
 	EventState	Hover
 	EventState	Touch
 	Float3	Point
 	Float3	Tip
 	TouchType	Type
 	Component	Source
```

#手順

- 新規->3d->box
- インスペクターを開く
- TouchableEventsRelyコンポーネント追加
- TouchableEventsRelyのインターフェースを取り出す
- ノードブラウザを表示
- TouchableEventsをスポーン
- つなぐ

以上。
All About ACS: IBM i Access Client Solutions は Log4j の脆弱性の対象外

# All About ACS: IBM i Access Client Solutions は Log4J の脆弱性の対象外

「[Apache Log4jの任意のコード実行の脆弱性（CVE-2021-44228）に関する注意喚起](https://www.jpcert.or.jp/at/2021/at210050.html)」「[JVNDB-2021-005429 - Apache Log4j における任意のコードが実行可能な脆弱性](https://jvndb.jvn.jp/ja/contents/2021/JVNDB-2021-005429.html)」など、Log4J の脆弱性が騒がれています。

Java 関連の脆弱性なので ACS は大丈夫なの? と思われるかもしれません。

IBM から影響がないと確認できた製品や対応が完了したサービスの情報が発信されています

* [An update on the Apache Log4j CVE-2021-44228 vulnerability - Products not Impacted](https://www.ibm.com/blogs/psirt/an-update-on-the-apache-log4j-cve-2021-44228-vulnerability/#list-of-products)

その中に「IBM i Access Client Solutions」が明記されています。
安心してご利用ください。

同様に PCOMM や HOD も脆弱性の対象外です。

HMC や WebQuery は対象に含まれます。

下記に IBM i 関連の Log4j 脆弱性情報をまとめました。

* [Log4j 脆弱性 IBM i 関連情報まとめ](https://qiita.com/6onoda/items/80a63fc6318392a4d58b)

# ACS 1.1.8.6 までは CVE-2021-4104 (log4j version 1.x) の影響を受ける(2022/01/11 追記)

CVE-2021-4104 (log4j version 1.x) の影響を受ける製品の情報が公開されました。

* [Security Bulletin: IBM i components are affected by CVE-2021-4104 (log4j version 1.x)](https://www.ibm.com/support/pages/node/6539162)

下記が影響を受ける製品に、1.1.8.6 までの ACS が含まれています。

* IBM i Access Client Solutions
 * 1.1.8.6 and earlier

log4j 1.x は含まれていたが使われていなかったようです。対策は 1.1.8.7 以降への更新になります。

> IBM i Access Client Solutions version 1.1.8.6 and earlier included an unused log4j v1.x jar file.  The issue can be fixed by upgrading to ACS version 1.1.8.7 or later.  

***
2021-12-22 作成
2022-01-22 「# ACS 1.1.8.6 までは CVE-2021-4104 (log4j version 1.x) の影響を受ける(2022/01/11 追記)」を記載

***
「All About ACS」では IBM i に対する新しいクライアント「IBM i Access Client Solutions」の情報をいろいろ提供していきます。
[記事一覧はこちら](http://qiita.com/6onoda/items/2dc925586d8d3b8644f2)で確認いたけます。

許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。
***
neosでlogix その33

#概要

niosでlogixやってみる。
On Grabbable Grabbedノードを使ってみた。

#写真


![2021-12-22 06.46.48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/8b71bdf7-357e-45f1-8084-e2c26e62d7d4.jpeg)

#On Grabbable Grabbed


```
Inputs
 	IGrabbable	Grabbable
Outputs
 	Impulse	OnGrabbed
```

#手順

- 新規->3d->box
- インスペクターを開く
- Grabbableのインターフェースを取り出す
- ノードブラウザを表示
- On Grabbable Grabbedをスポーン
- つなぐ


以上。
VCIアイテム音量の設定を考える 

#はじめに
こちらの記事は[VCI Advent Calendar 2021](https://qiita.com/advent-calendar/2021/vci)の第２４日目の記事です。

#VCI音の大きさどうしてますか？
VCIでは簡単に音を出すことができます。
音量調整やループ再生などが簡単にできるのでとても便利です。

ではVCI作成するときに音の大きさはどうやって決めていますか？

とうことで、今回はこの二つを書いていきたいと思います。

１．なんで音の大きなVCIがリリースされるのかを考察
２．今回はVCIの音の大きさの決め方 by にゃふ屋

（音がでかくてびっくりした時のイメージ画像です）
![2021122220094357.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545584/18463762-10bf-64d2-81a2-f7cd1e9673eb.jpeg)

#なんで音の大きなVCIがリリースされるのかを考察
VCIの作者さんは動作確認を行っているので、音の大きさも確認していると思います。
それなのに、たまにびっくりするくらい音の大きなVCIが有ったりします。

とある作成中のVCIを見せていただいたときに音が大きかったので、お話を伺いました。
どうやら、アイテム音量を小さく設定しているため、作者さんはちょうどいい音に聞こえていたようです。

アイテム音量？
これです、これ。

システム＞音量＞アイテム音量
![2021122220195578.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545584/0f82f7ac-b269-9a82-b8d7-cd22f2bfb09a.jpeg)

Vキャスの中でVCIアイテムの音量を全て小さくしたり大きくしたりできます。

とある公式ルームに１０人くらいいるときに突然音の大きなVCIを使われると、アイテム音量を小さくすることがあります。
（よくある事なので、特に気にもしませんが、びっくりします）
VCI個別の音量変更もできますが、面倒なのでついついアイテム音量を小さくします。

さて、アイテム音量を小さくすると何が起こるでしょう？

その前ににゃふ屋流のVCIアイテム作成時の音量調整手順です。

#VCIの音の大きさを調整する
VCIに音を入れてテストして、大きさを調整って感じで作業しています。

- 音源ファイル（wavやMP3)の準備（ここはだいたい音がでかいけど、問題ない）
- VCIに音源ファイルを入れる（ここは入れるだけ）
- Luaスクリプトでの音量パラメータの設定（ここで音の大きさを調整しています）
- Vキャス上でのアイテム再生（音の大きさを確認して、大小の調整をLuaで行います）

特別なことは何もなくて、作ってテストして音の大きさを調整しているだけです。
VCI作者さんはみんな同じだと思います。

#VキャスでVCIアイテム音を確認する？
音の大きさはあちこちで設定できますが、Vキャスの中で適切な音量になっていれば問題ないはずです。

Vキャスの中で適切な音量とは？

テストして聴いてみていい感じの音の大きさにすれば良いと思います。

みんなやってるはずですよね？

実は、Vキャス内のアイテム音量がどうなっているかによって、出来上がるVCIの音の大きさが違ってきます。
ちなみに、Vキャス内のアイテム音量は「６５」です。（2021/12ごろの話）
![2021122220201769.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545584/e4566676-9e40-2336-1a1e-90503fc751c5.jpeg)

例１：作者さんがデフォルトの音量６５でVCIを作成
他の方がアイテム音量65ならだいたい良い感じに聞こえます。
同じVCIアイテムをアイテム音量100の人が聴くと大きな音に聴こえます。
同じくアイテム音量30の人が聴くと、小さい音になります。

例２：作者さんが音量３０でVCIを作成
アイテム音量３０で良い感じに音量調整したVCIアイテムはアイテム音量６５の方には大きな音で聴こえます。
デフォルトの６５なのに大きな音がでます。

VCI作成時にアイテム音量が小さいままだと「大きな音VCI」の作者になっちゃいますね。

#大きな音のVCIで困る事は有るの？
びっくり箱みたいなVCIであれば大きな音で脅かすのも有りなので、問題ないです。

でも、折角作ったVCIが音が大きいと言うだけで「この部屋でそのVCI使用禁止」とか「そのVCIはやめて」とか言われるのは悲しいですよね。

特にお座敷みたいに見ていないところでVCIを出されて、大きな音がするとすごくびっくりします。（特に私が）

Vキャスエキスパートのみなさんはいろいろ対策をしていると思いますが、初心者さんは設定がデフォルトになっているので大きな音のVCIの洗礼を受けちゃいますね、気を付けたいです。

#まとめ
:::note info 
今回のポイントは
　Vキャス内のアイテム音量はデフォルトの６５で動作確認すると良いんじゃないかな
ってことです。
:::

#最後に
自分のVCIでも久しぶりに見ると音が大きいものが有ったりするので、そのうち修正していきたいと思います。
画像はイメージです、実在のVCIとは関係ありません。
![2021122220123829.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545584/a2506174-5208-6f67-a0c7-7793fd4885b7.jpeg)

そんなことを気にしながら作ったVCIを公開しています。
気が向いたらDLしてみてください。
[TSO にゃふ屋](https://seed.online/users/106600#products)

それでは、まったね～。:blush:
neosでlogix その32

#概要

niosでlogixやってみる。
mouseノードを使ってみた。

#写真

![2021-12-22 05.20.00.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/4dd67c69-183b-15b8-40bb-5b6be091bed4.jpeg)

#Mouse Scroll Wheel Delta


```
Inputs
Outputs
 	Float
```

#Left Mouse Button Held

```
Inputs
Outputs
 	Bool
```

#Right Mouse Button Held

```
Inputs
Outputs
 	Bool
```

以上。
AWS Auroraのwriterとreaderで一部パラメータに差異があったので調査してみた

# 概要
AWS Auroraのwriterとreaderでパラメータを確認したところ、差分があったので調査してみました。
RDSに直接入ってパラメータを確認した所、一部パラメータがreaderは「MyISAM」になっているので気になったというのが経緯です。

## writer

``` 
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| default_storage_engine               | InnoDB |
| default_tmp_storage_engine           | InnoDB |
| disabled_storage_engines             |        |
| ignore_default_storage_engine_errors | OFF    |
| internal_tmp_disk_storage_engine     | InnoDB |
+--------------------------------------+--------+
```

## reader

```
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| default_storage_engine               | InnoDB |
| default_tmp_storage_engine           | MyISAM |
| disabled_storage_engines             |        |
| ignore_default_storage_engine_errors | OFF    |
| internal_tmp_disk_storage_engine     | MyISAM |
+--------------------------------------+--------+
```

## 確認したエンジンバージョン
5.7.mysql_aurora.2.10.1

# 結果
文献は見当たりませんでしたが、仕様のようです。

検証してみましたが、readerのロールになったRDSは一部パラメータが「MyISAM」になるようで、フェイルオーバーしてもロールがreaderになれば一部パラメータが「MyISAM」に、writerであれば「InnoDB」になりました。

# 終わりに
何故こんな動きをするかとても気になる。。
neosでlogix その31

#概要

niosでlogixやってみる。
Standard Controllerノードを使ってみた。

#写真


![2021-12-22 05.14.16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/47255a25-f585-8c4b-d587-13d144258394.jpeg)

#Standard Controller


```
Inputs
 	User	User
 	ControllerNode	Node
Outputs
 	Bool	IsActive
 	Float	BatteryLevel
 	Bool	IsBatteryCharging
 	Type	Type
 	Bool	Primary
 	Bool	Secondary
 	Bool	Grab
 	Bool	Menu
 	Float	Strength
 	Float2	Axis
```


以上。
propsに渡すオブジェクトはmemo化しなければならない（戒め）

# はじめに
不要なレンダリングを回避するための備忘録です。

# よくないやりかた
`NameList`のpropsにオブジェクトを直で渡してしまうと、`someOtherState`が変化するたびに`NameList`が再レンダーされてしまう。

```NameList.tsx
...
export const NameList: React.FC<string[]> = ({names}) => {
 return (
  <>
   {names.map((name, key) => (<div key={key}> {name} </div>))}
  </>
 )
} ​
```
``` Users.tsx
...
interface IUser {
 name: string;
 id: number;
}

const Users: React.FC<> = () => {
 const [users,setUsers] = useState<IUser[]>(initialUsers)
 const [someOtherState, setSomeOtherState] = useState<ISomething>(initialSomething)

 return ( <NameList names={users.map(user => user.name)}> )
}
```

# 正しいやり方
`NameList`のpropsに渡すオブジェクトをmemo化する。そうすれば`someOtherState`が変化しても`NameList`は再レンダーされない。

```NameList.tsx
...
export const NameList: React.FC<string[]> = ({names}) => {
 return (
  <>
   {names.map((name, key) => (<div key={key}> {name} </div>))}
  </>
 )
} ​
```
``` Users.tsx
...
interface IUser {
 name: string;
 id: number;
}

const Users: React.FC<> = () => {
 const [users,setUsers] = useState<IUser[]>(initialUsers)
 const [someOtherState, setSomeOtherState] = useState<ISomething>(initialSomething)
 
 // ここ！！
 const names = useMemo(() => users.map(user => user.name), [users])

 return ( <NameList names={names}> )
}
```
Rustでの他スレッドの待ち合わせ(条件変数, wait, notify)

rustで他スレッドから通知を待ち合わせるにはMutexとCondvar型の条件変数を用います。使い方は一般的な条件変数と同じで、待ち合わせる方のスレッドはMutexのロックを取得したあと条件変数に対してwaitを呼び出します。通知を行う方のスレッドは条件変数に対してnotifyを呼び出します。

実際に条件変数による待ち合わせを行うコードを以下に示します。
ポイントは以下の通り。

* 条件変数はMutex変数と対で用います。タプルでまとめて管理すると良いかもしれません。
* 条件変数とMutex変数はスレッドをまたいで共有されるのでArcでくるみ、Arc::clone()で複製を作って使用します。
* cond.wait(mutex)は内部でmutexのロックを外してnotifyを待ちます。notifyを受けてwaitから復帰する時にはロックを取得した状態で復帰します。
* wait関数は実装の都合上notifyを受けていないのに復帰することがあります(偽wakeup)。偽wakeupのケースをケアするためにwaitから復帰した直後にmutexの内容を検査します。

```rust
use std::sync::Condvar;
use std::sync::Mutex;
use std::sync::Arc;
use std::thread;
use std::time;

fn main() {
	let cond = Arc::new(Condvar::new());  // 条件変数
	let go = Arc::new(Mutex::new(false)); // ミューテックス変数

	// waitスレッド起動
	let cond_c = Arc::clone(&cond);
	let go_c = Arc::clone(&go);
	let t1 = thread::spawn(move || {
		loop {
			// ロック取得
			let mut go = go_c.lock().unwrap();
			while !*go { // 偽wakeupの場合は再度waitする
				// wait: 内部でロックを外しnotifyを待つ
				//       waitから復帰する際にはミューテックスのlockを取得している
				go = cond_c.wait(go).unwrap();
			}
			println!("wakeup!");
			*go = false;
		}
	});

	// notifyスレッド起動
	let cond_p = Arc::clone(&cond);
	let go_p = Arc::clone(&go);
	let t2 = thread::spawn(move || {
		loop {
			thread::sleep(time::Duration::new(0, 1_000_000_000u32));

			println!("notify!");
			// ミューテックスのロック取得
			let mut go = go_p.lock().unwrap();
			*go = true;

			// 条件変数に対してnotify
			cond_p.notify_all();
		}
	});

	t1.join().unwrap();	
	t2.join().unwrap();
}
```

* waitの他にタイムアウトを指定できるwait_timeが存在します。
* また、偽wakeupのケアをしてくれるwait_whileも存在します。
Power BI Desktopのダウンロードは2種類の方法あり

# はじめに
　Power BI Desktopには2種類あります。
入口はこちらのページですね。

https://powerbi.microsoft.com/ja-jp/downloads/

## Microsoft Store

入口ページの「ダウンロード」からのよびだし、またはMicrosoft Storeで「Power BI Desktop」からの検索です。

https://aka.ms/pbidesktopstore

## ダウンロードする

「高度なダウンロード オプション」からダウンロードします。

通常は 上のx64版を選択します。

https://aka.ms/pbiSingleInstaller

Surface Pro Xは、ARMプロセッサのような場合は、下のPBIDesktopSetup.exeを選ぶ。


# おわりに
　自動アップデートが便利なので、Microsoft Storeがおすすめです。
CircleCI で Heroku Postgres(SSL) を利用する

今年もやってきました、こちらは、[CircleCI Advent Calendar 2021](https://qiita.com/advent-calendar/2021/circleci) ゆかちゃんの誕生日。12月23日です!!　毎年お世話になります、しょっさんです。

今年の CircleCI ネタは、[Heroku]()でございます。今年もかよ。

---

## Heroku Postgres の自動テストがうまくいかない

1年放置していた、とある Typescript + Sequelize のアプリが、CircleCI で何をどうやってもエラーをはき続けてしまう現象に巡り会いました。

エラーの内容はこうです。

```bash
> webapp@1.0.2 migrate /home/circleci/project
> sequelize db:migrate


Sequelize CLI [Node: 12.17.0, CLI: 6.3.0, ORM: 6.11.0]

Loaded configuration file "src/config/config.json".
Using environment "development".

ERROR: The server does not support SSL connections
```

ははーん？

## Heroku Postgres が SSL 必須になるの巻

本年 2021/2/23 の changelog です。[All Heroku Postgres client connections require SSL](https://devcenter.heroku.com/changelog-items/2035) にあるとおり、Common Runtime 環境下でも PostgreSQL への接続に SSL が必須となりました。

これには二つの対処が必要です。

1. Sequelize の SSL 化
1. CircleCI 側の PostgreSQL の SSL化

### 1. Sequelize の SSL 化

こちらについては、既にちょうど良い記事があるので、こちら参考に。

[heroku-postgresをSSLエラーが阻む問題の解決](https://qiita.com/ameryu716/items/6387133a46ff7594244f)

ちな、Sequelize の `config.json` をこんな風に書けば十分です。

```json:config.json
  "production": {
    "use_env_variable": "DATABASE_URL",
    "dialectOptions": {
      "ssl": {
        "require": true,
        "rejectUnauthorized": false
      }
    }
  }
```

### 2. CircleCI 側の PostgreSQL の SSL化

そして二つ目、これが厄介で厄介で仕方ない。

結果としてはこれ。`openssl` で作成したオレオレ証明書をベースに、起動shell に無理矢理それを食わして起動させるパターンです。

ポイントは、local Postgres用の Docker Image で、バージョン指定しておくこと。これ -> `image: circleci/postgres:13.0`。他のバージョンだとちょっとまた手はずが変わってくると思われ。

```yaml:/.circleci/config.yml
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: cimg/node:16.13.1
        environment:
          DATABASE_URL: postgres://testing:password@localhost:5432/sample

      # local postgresql server
      - image: circleci/postgres:13.0
        environment:
          POSTGRES_USER: testing
          POSTGRES_PASSWORD: password
          POSTGRES_DB: sample
        entrypoint: bash
        command: >
          -c '
            openssl req -nodes -new -x509 -subj "/CN=localhost" -keyout server.key -out server.crt &&
            chown postgres server.key &&
            chmod 600 /server.key &&
            exec /docker-entrypoint.sh -c ssl=on -c ssl_cert_file=/server.crt -c ssl_key_file=/server.key
          '
```

ということで、れっつえんじょい CircleCI + Heroku ライフ。
VRChatプレイヤーによるParticle System解説 ～External Forces, Noise Module編～

:::note warn
この記事はUnity 2019.4.29f1の記事です
:::
[Force over Lifetime, Color/Size/Rotation over Lifetime, by Speed Module編](https://qiita.com/abcde_kind/items/96710d4e401ca88abbb5) <<  ここ  >> 次
# はじめに
この記事は**ちょっとParticle System触れるようになったけどまだまだ知らないパラメーターだらけで抵抗感がある人向け**にじゃあ全項目解説しようという記事です。

**パーティクル？シェーダー？憧れるけどよくわかんない…**という人は最近は[VRCUnity勉強会][link-1]などで初歩の初歩から解説してくれる講座などが解説されているのでそこに参加してみたりするといいでしょう。
[link-1]:https://discord.gg/mtvTTyM
その他にこの記事はアドベントカレンダーにしてParticle Systemの記事を増やしてパーティクルへの抵抗感を減らしてやろうという企みもあります。

##External Forces, Noise Moduleってどこ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2386883/6e8bc8a6-fe54-13d5-21ed-aae87f16e5b4.png)
ここ
##External Forces
主にWind ZoneやParticle Force Fieldを使う時に関係するところ
アバターだと関係ない
###Multiplier
デフォルト 1 (0~3.402823e+38)
単位 倍
**パーティクルが影響をどれだけ受けるか決めるパラメーター**
###Influence Filter
デフォルト Layer Mask
**どのレイヤーのモノの影響を受けるか、どのオブジェクトの影響を受けるか指定するパラメーター**
##Noise
**パーティクルの動きやサイズにカスタムできるランダム要素を足すModule**
この記事の主題と言っていい
<font color=red>基本的に二次元の波をイメージして考えると分かりやすい</font>
###Separate Axes
デフォルト OFF
**ノイズをXYZに分けて操作できるようにするパラメーター**
###Strength
デフォルト 1 (-100,000~100,000)
**ノイズの強さのコントラストを決めるパラメーター**
<font color=red>波で言うところの高さの幅を調整するところ</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2386883/80a9ebd8-eeb6-2d37-466a-7d9c16f7920d.png)
実際にデフォルトでParticle System出した状態からShapeだけOFFにしてNoiseONにしてここだけ弄った方が分かりやすい
###Frequency
デフォルト 1 (0.0001~100,000)
**ノイズの密度を決めるパラメーター**
<font color=red>波で言うと横幅をギュッと詰めて密度を上げる感じ</font>
値が小さくなると密度も小さくなり値が大きくなると密度も大きくなる
###Scroll Speed
デフォルト 0 (-100,000~100,000)
**ノイズの流れる速度を決めるパラメーター**
<font color=red>波で言うと流れる速さ</font>
値が小さいとパーティクルがゆっくり揺れて値が大きくなればパーティクルがブルブル暴れる
###Damping
デフォルト ON
**ノイズの急激な変化を抑えるパラメーター**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2386883/774b20bf-fa11-1a83-f907-de71ea463ae1.png)
<font color=red>波の急勾配をなだらかにするイメージ</font>
###Octaves
デフォルト 1 (1~4)
単位 枚
**ノイズテクスチャを何枚重ねてノイズを計算するか決めるパラメーター**
複数のノイズを重ねて1枚のノイズを作るための項目、ちなみに乗算
数を増やすほど生成するノイズの数が増えるため<font color=red>負荷が跳ね上がる</font>
####Octave Multiplier
デフォルト 0.5 (0~1)
**重ねるレイヤーの濃さ**
0から少しずつ増やしてみるとグラデーションが見えて何となく分かる
####Octave Scale
デフォルト 2 (1~4)
単位 倍
**重ねるレイヤーの大きさ**
###Quality
デフォルト High(3D)
**ノイズ生成の方式を決めるパラメーター**
1D,2D.3Dノイズから生成する方法がある(perlin noiseとかで検索してください)
###Remap
デフォルト OFF
**これまでに生成されたノイズを元に改めて値を振るかどうか決めるパラメーター**
下のRemap Curveで振り分ける値を調整するが<font color=blue>縦軸が振り分ける値、横軸が生成されたノイズの値(0~1)</font>
上のSeparate AxesをONにするとXYZに分かれる
###Position/Rotation/Size Amount
デフォルト 1/0/0
**ノイズの値をパーティクルの動き/回転/大きさにどれだけ反映させるか決めるパラメーター**
##おわり
というわけでExternal Forces,Noise Moduleでした
External Forcesはアバターで使うことないのもあって端折りましたがNoiseはちょっと使うだけで一気に単調じゃないパーティクルになるのでなんか今ひとつだな…って時は使ってみると良いです
次はCollision Moduleです
****
[Force over Lifetime, Color/Size/Rotation over Lifetime, by Speed Module編](https://qiita.com/abcde_kind/items/96710d4e401ca88abbb5) <<  ここ  >> 次
WPF DatePickerで、IMEをオフにする。

DatePickerのテキストボックスの入力欄で、IMEをオフにする方法。
通常のTextBoxでIMEをオフにするのとは違い、工夫が必要。

### XAMLとスタイル

手間がかからない方法。
PreferredImeStateとスタイルを指定。

```
<DatePicker
  InputMethod.PreferredImeState="Off"
  Style="{StaticResource DatePickerStyle1}" />
```

DetaPickerのデフォルトのスタイルの PART_TextBox に次を追加

```
<Style x:Key="DatePickerStyle1" TargetType="{x:Type DatePicker}">
（省略）
<DatePickerTextBox x:Name="PART_TextBox"　　（省略）
InputMethod.PreferredImeState="{Binding Path=(InputMethod.PreferredImeState), RelativeSource={RelativeSource TemplatedParent}}" />
```

### コードで追加する場合
DatePickerコントロールにスタイルと、PreferredImeStateをセットします。

``` csharp
var datePicker = new DatePicker();
datePicker.Style = (Style)Application.Current.Resources["DatePickerStyle1"];
InputMethod.SetPreferredImeState(datePicker, InputMethodState.Off);
RootStackPanel.Children.Add(datePicker);
```
### コード
.NET Framework 4.7
https://github.com/mikihiro-t/IMEStudy

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/17506a3a-85fc-946b-9989-d64535801ad2.png)

### 参考
XAMLで直接Templateを変更。この場合、"PART_TextBox"は必要では無いようだ。
https://stackoverflow.com/a/27300604/9924249

### 備考

- 先人の研究やコードを参考にしました。いろんな方法があったのですが、上記の方法は、まだ記されていないようでした。
- 物事を解決するのに、様々な方法があるのはいいのですが、どの方法がベストプラクティスか、判断が難しい。

#### 履歴
2021-12-23 IMEを無効　→　IMEをオフ　に変更。　IMEの有効無効は、SetIsInputMethodEnabledで設定するため。
Ubuntu18.04に後から無線LAN USBを追加したらネットが不安定になった

# Ubuntu18.04で有線LANと無線LANを使う場合
今回、元々有線LANを使っていたマシンにUSBの無線LANを追加した後、インターネットからのリクエストがたまに戻ってこないか、とても時間がかかる現象があった。
はじめに、外に出る場合にどっちから出ているかをtracerouteで調べてみたが、有線LANから出ている事が確認できた。

有線LAN : 192.168.1.0/24
無線LAN : 192.168.10.0/24

```
junk@ubuntu18:~$ traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  _gateway (192.168.1.1)  0.872 ms  1.038 ms  1.248 ms
 2  * * *
 3  xxx.xxx.xxx.xxx  10.069 ms xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)  10.307 ms 
 4  xxx.xxx.xxx.xxx (27.80.241.109)  10.575 ms xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)  10.753 ms 
 5  * * *
 6  dns.google (8.8.8.8)  9.104 ms  8.885 ms  9.253 ms

```

# ルーティングテーブルを疑う(route)
tracerouteでは有線LANから外に出ていることが確認できたが、確実とはいえないのでrouteを調べる。

```shell
junk@ubuntu18:~$ route
カーネルIP経路テーブル
受信先サイト    ゲートウェイ    ネットマスク   フラグ Metric Ref 使用数 インタフェース
default         _gateway        0.0.0.0         UG    100    0        0 eno1
default         _gateway        0.0.0.0         UG    600    0        0 wlx7cc
link-local      0.0.0.0         255.255.0.0     U     1000   0        0 eno1
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 eno1
192.168.10.0    0.0.0.0         255.255.255.0   U     600    0        0 wlx7cc

```
* 思った通りdefault gatewayが２つある…。
* Metricが100と600なので有線LAN側が優先度高になるが場合によって無線LANから外にいっているリクエストもあるような気配。

## 無線LAN側のdefault gatewayを止める
* Wifiの設定画面からIPv4のタブの「この接続はネットワーク上のリソースのためだけに使用」にチェックをし、Wifiの再起動を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84915/b15a3157-4c1b-671f-380e-a78571f8f067.png)


## 設定後

```
junk@ubuntu18:~$ route
カーネルIP経路テーブル
受信先サイト    ゲートウェイ    ネットマスク   フラグ Metric Ref 使用数 インタフェース
default         _gateway        0.0.0.0         UG    100    0        0 eno1
link-local      0.0.0.0         255.255.0.0     U     1000   0        0 eno1
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 eno1
192.168.10.0    0.0.0.0         255.255.255.0   U     600    0        0 wlx7cc

```
* 無線LAN側のdefault gatewayが無くなり、ネットワークの迷走が無くなりました。
ダンジョンのデッドロック 3 Python3編

https://paiza.jp/works/mondai/steinsgate/moving_deadlock_step3



```py
N,M = map(int,input().split())

room = [-1]*(N+1)
req_l = [-1]*(M+1)

ans = []

for i in range(M):
    a,b = map(int,input().split())
    room[a] = i+1
    req_l[i+1] = b
    
p = 1
q = req_l[p]

while True:

    if room[q] == -1:
        ans.append(p)
        break
    
    elif p == room[q] and p==1:
        ans.append(p)
        break

    elif p == room[q]:
        p += 1
    
    ans.append(p)
    p = room[q]
    q = req_l[p]
       
print(*ans[::-1])

```