OmniAICreator/Qiita-1.07M huggingface dataset:
言った言わないを言った時点でそのプロジェクトは終わっている

「この仕様はそうじゃない。こうだって言っただろ。」
「いや、そんなこと言われてない。」
そんなやり取りが、世の中ではひっそりと、または開発現場で苛烈に行われている。
どう作っていくかのみならず、契約の内容にまで及び、訴訟にまで至ることもある。
そんな話の始まりはいつだって、当事者同士の「言った」か「言っていない」かである。
しかし、その話をした時点で実はプロジェクトの失敗は約束されている。
俗に言う、終わってるプロジェクトである。

# 何故か
人間に記憶力はない。
覚えてられるなどと人間の能力を過大に評価するべきではない、記憶力など皆無である。
会議室で話をして部屋を出れば、その瞬間に何を話したかなんて忘れる。
それで正確に要件や仕様に沿ったものが作れるか？他の人に指示を出すときに正確に伝えられるか？
否。
つまり、何を作るのか分からないので、完成すらしないのである。
この状態で完璧に完成させるのは、赤子がモハメド・アリを素手で倒すくらい不可能である。
そうでなくても完璧に完成させることなんてできないのに、だ。

# 原因
こんな言った言わないが起きる原因はなんなのか。
それは口頭のみの伝達にある。
「言う」という行為が問題を引き起こす。
通常、何を開発をするか、どうするのかというのは文書なりでやり取りをするが、それを口頭でのみ伝えて何かを約束したような気になることで起きる。
時間がないとか、時間を短縮するためとか言いながら口頭でやり取りしようなんていうのは、逆に無駄以外の何ものでもない。
何も指標にするものを更新していないのだから、話をした時間まるまる何もしていないのと同じである。
文書を出したり、資料を更新する時間がない？面倒？
そんな契約の基本を守れない奴は何も口を出さず、二度と他人に仕事を出すべきではない。

# どうするべきか？
究極の形は、一切口頭で会話をせずに全てのやり取りをすること。
ただ、これはかなり時間がかかることになる。
なので、最初に何を指標とするかを決め、それのみを信じることにするのがいい。
言っておくが、これは契約の基本である。

口頭でのやり取り、つまり打ち合わせというのは必ず存在する。
そこで話をして決定して動こうとしたくなるが、そこは絶対に動かず、しっかりと文書を出し、それから動かなければならない。
これは、仕事を出す側も受ける側もしっかりと意識をしないといけない。
逆に言えば、これができていないから言った言わないが発生する。
口頭で早く決めて進めたいというのであれば、その場で必要なものを書けばいいだけである。

仮にどうしても口頭のみでやりたいというのであれば、絶対に聞いてはいけない。
それは逆に言った言わないの話に持っていき、不備や間違いを無理に矯正しようと予防線を張っているにすぎない。
その時点でその相手は信用をするべきではないし、そう言った時点で信用を失うと考えた方がいい。

# 最後に
やるべきこと、考えるべきことは書いたと思うので、これを言ったらその瞬間に終わりという言葉を出そうと思う。
- こう言った
- 今言った感じで
- 言った言わないになる
PHP：Docker環境：bcmath関数で浮動小数点の計算を正確にする

浮動小数点の計算は正確にならない。
よって、大前提として浮動小数点の計算は避けた方が良いが、必要な時はbcmath関数を利用するとよい。

ただし、bcmath関数を別途インストールしせねば使えない。
すでに仕込んであればDockerのDockerfileに記述がある。
mbstring zip bcmath


```php
// 加算したい小数点を「文字列として」記述し、最後のパラメータで表示させた桁数を指定
$num = bcadd('0.1', '0.2', 1);
var_dump($num); // string(3) "0.3"
echo PHP_EOL;
var_dump((float) $num === 0.3); // bool(true)

```

一つ目の出力：　0.3と表示される。数値ではなく文字列にしているのに計算ができるのがbcmath関数の機能となる。ただし、文字列になっているため、結果を浮動小数点に戻したければ二つ目の出力にもあるように、float化せねばならない。

二つ目の出力：　今度は 足し算した　$num と　0.3 という浮動小数点とを比較し、真偽値で返すもの。
float化しているので浮動小数点同士の比較がしっかりとできている。
vue-routerを含むvueプロジェクトをビルドして、プレーンなNode.jsでリソースを公開する

タイトルが正しく書けているか不安ですが、vue-routerを含むvueのプロジェクトをビルドして、nginx等を使わずプレーンなNode.js単体でリソースを公開するという感じです。

# 環境

* OS Windows 10
* Node.js v14.18.0
* npm v8.10.0
* vue-cli v5.0.8
* vue v3.2.13

# ビルドとwebサーバーについて
vue cliで作成したプロジェクトを`npm run build`すると、静的ファイル群に変換してくれます。
※ ビルドしたファイルは開発環境とは異なる点がいくつかあります。詳しくは公式ページをご確認ください。

https://ja.vuejs.org/guide/best-practices/production-deployment.html#with-build-tools

このファイルはnginx等のwebで公開するパターンが大多数だと思いますが、筆者はリバースプロキシとアプリケーションのDockerイメージを分けて管理したかったので、Node.jsでwebサーバーを作ろうと思いました。

前述の`vue-router`を使用している場合、リクエストURLは必ずしも静的ファイルの`index.html`を指すわけではないので必要に応じて`index.html`へリダイレクトしてあげる必要があります。

nginxなら一行足すだけですし、Node.jsでもちょっと書けばクリアできます。

まず、筆者はNode.jsをフレームワーク無しで叩いたことのない人だったので下記の記事を参考にスクリプトファイルを書きました。というかほぼコピペしました。

https://developer.mozilla.org/ja/docs/Learn/Server-side/Node_server_without_framework

また、下記の記事にリダイレクト方法がが記載されています。

https://router.vuejs.org/guide/essentials/history-mode.html#native-node-js

これらを踏まえてファイルが見つからなかった場合のリダイレクト先を、`404.html`から`index.html`に変更します。

基本的な記述はMDN Web Docs様のページにあるコードをコピペして、リダイレクトの部分のみ書き換えます。

```serve.js

// ... コピペなので略 ...

if(error.code == 'ENOENT') {

    // ここを修正
    // fs.readFile('./404.html', function(error, content) {
    //     response.writeHead(404, { 'Content-Type': 'text/html' });
    //     response.end(content, 'utf-8');
    // });

    fs.readFile('./index.html', function(error, content) {
        console.log('redirect /index.html')
        // リダイレクトしてレスポンスコード200で返す
        response.writeHead(200, { 'Content-Type': 'text/html' });
        response.end(content, 'utf-8');
    });
}

// ... コピペなので略 ...

```

# 結果

実行してみましょう。

```bash
node serve.js
```

必要最低限のコンソールが上がります。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884998/52fa43aa-696a-6bb4-af26-b09f48827344.png)

`vue-router`で定義したすべてのページに、ブラウザのアドレスバーから直接アクセスできることが確認できました。

皆様のご参考になればと思います。
pythonでhtmlとjavascriptを直接書きたい！

作った！！！

# それを使ったサンプル！

QRコード生成器！！
![qrcode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597237/436215da-f815-4473-687e-7fc21b04bab3.gif)
ソース

https://github.com/am230/py2html/blob/master/examples/qr%20generator.py

簡素なチャット！！
![chat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597237/40173212-8f2e-0e4e-c924-3140d6ff1722.gif)
ソース

https://github.com/am230/py2html/blob/master/examples/form.py


# インストール！
```console
pip install pytohtml
```


# 書き方！
QRコード生成器の中身を見てみよう
```python
# インポート省略
app = Flask(__name__)

this: object
window: object
fetch: object
JSON: object

class document:
    def getElementById(self, id: str): ...

class RequestData(typing.TypedDict):
    content: str

@util.api(app, '/api/generate', json=False, methods=['POST'])
def generate_qr():
    data: RequestData = request.json
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=4,
        image_factory=PilImage
    )
    qr.add_data(data['content'])
    qr.make(fit=True)

    image = qr.make_image(fill_color='#3da0b4', back_color="white")

    buffered = BytesIO()
    image.save(buffered, format="PNG")
    img_str = base64.b64encode(buffered.getvalue())
    return b'data:image/png;base64,' + img_str

@app.route('/')
def index():
    @js
    def main():
        async def generate():
            data = document.getElementById('qr_data')
            image = document.getElementById('result')
            await generate_qr({
                'content': data.value
            })\
                .then(lambda response: response.text())\
                .then(lambda text: image.setAttribute('src', text))

    return html(lang='en')[
        util.cache(lambda: head[
            title['QR Code Generator'],
            SASS(href='styles_qr.scss'),
            Script[generate_qr],
            Script[main]
        ]),
        body[
            div(className='container')[
                div[
                    input(id='qr_data', name='qr_data', placeholder='data here'),
                    button(onclick='generate()')['>']
                ],
                img(id='result', src='', title='')
            ]
        ]
    ].render()

if __name__ == '__main__':
    app.run(debug=True, port=80)
```

まずhtmlを__call__と__getitem__でできるだけそれっぽく書けるようにしてます！
そしてindex()のmain()の中でjavascriptを記述して、
Script[main]で埋め込んでますん

どうやってjavascriptに変換してるかはこれで雑に詳細書いた！

https://qiita.com/230/items/7ad6bdd74ab68692c9ae

# ちなみに
属性も型ヒントで補完できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597237/ec201bcf-b970-e0af-ad91-2810cafa4133.png)
pythonをjavascriptにしたい！

（これは無視 https://github.com/flexxui/pscript ）

pythonからjavascriptに変換したいーー！
ということでpythonでjavascriptを書けライブラリを作りましたー

# インストール！
```console
pip install py2js
```

# 使い方

```python
py2js.convert(コードの文字列 もしくは 関数やクラス)
```
もしくは
```python
@py2js.js
def main():
    // ここに変換したいコードを入れる
```
とするとmainがjavascriptのコードになります

# サンプル！

これが

```python
'generator'
def generator_func():
    yield 1
    yield 2
    yield 3
    yield from [9, 8, 7]
    return 0

for item in generator_func():
    console.log(item)

'for-else'
for i in [0, 1, 2, 3]:
    if i > 2:
        break
else:
    console.log('else')

'f-string'
a = 4
console.log(f'{a} fstring')

'class'
class Main:
    a: int

    def constructor():
        this.a = 1

    def func():
        console.log(this.a)

Main().func()

'try catch else finally'
try:
    raise SyntaxError('syntax error')
except SyntaxError as e:
    console.log('syntax error raised')
except:
    console.log('excepted')
else:
    console.log('else')

try:
    if Boolean(1):
        raise SyntaxError('syntax error')
except:
    pass
finally:
    console.log('finally')

'while'
i = 10
while i > 0:
    i -= 1

'comparator'
i = 5
if 0 < i < 9:
    console.log('true')
```

このように変換されます！

```javascript
`generator`;
let generator_func = function*() {
    yield 1;
    yield 2;
    yield 3;
    yield*[9, 8, 7];
    return 0
};
for (let item of generator_func()) {
    console.log(item)
};
`for-else`;
__else: {
    for (let i of [0, 1, 2, 3]) {
        if (i > 2) {
            break __else
        }
    }
    console.log(`else`)
};
`f-string`;
let a = 4;
console.log(`${a} fstring`);
`class`;
let Main = class {
    constructor() {
        this.a = 1
    };
    func() {
        console.log(this.a)
    }
    a
}
Main = new Proxy(Main, {
    apply: (clazz, thisValue, args) => new clazz(...args)
});;
Main().func();
`try catch else finally`;
__else: {
    try {
        throw SyntaxError(`syntax error`)
    } catch (__err) {
        if (__err instanceof SyntaxError) {
            e = __err;
            console.log(`syntax error raised`);
            break __else
        } {
            console.log(`excepted`);
            break __else
        }
    }
    console.log(`else`)
};
try {
    if (Boolean(1)) {
        throw SyntaxError(`syntax error`)
    }
} catch (_err) {
    {
        /* pass */ }
} finally {
    console.log(`finally`)
};
`while`;
let i = 10;
while (i > 0) {
    i -= 1
};
`comparator`;
i = 5;
if (0 < i < 9) {
    console.log(`true`)
}
```

# 仕組み

pythonを構文木解析してそれをなんかいろいろしてjavascriptに変換！

詳しくは見て

# ソースコード!!!!

https://github.com/am230/py2js
【Power Automate】JSONから配列を作り、配列内の数値を合計する

# aplly to eachは遅すぎるので避けたい
Power Automateで配列にした数値の合計を求めるのは意外と面倒です。ループを回さずJSONの要素同士を合計させる試みです。
ループを回して用意した変数に加算してもよいですが、ご存じのとおりPower Automateのapply to eachは非常に遅いです。そこで、ループを使用せずにJSON→配列→XMLに変換しやすいJSON→XMLを経てxpath関数を使って合計を求めていきます。

xpath関数を使った合計の求め方については、こちらの英文サイトで知ることができました。感謝です。https://www.tachytelic.net/2021/06/power-automate-instant-sum-array/

テストデータとして以下のような都道府県と人口を組み合わせたJSONを用意しました。各都市の人口を合計したいというイメージでステップを進めていきましょう。
```
{
  "prefectures": [
    {
      "name": "Tokyo",
      "population": 1396
    },
    {
      "name": "Osaka",
      "population": 882
    },
    {
      "name": "Aichi",
      "population": 755
    }
  ]
}
```
「作成」に貼り付けて元データとして利用できるようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/bba2caee-885c-5214-2602-fc619ab69b87.png)
# 「選択」を使ってJSONを配列に変換する
今度は「選択」を使います。元となるJSONは入れ子構造になっていますが、今回は人口部分だけを合計することが目的です。開始の欄には「prefectures」の中身を取り出すために以下のような式を設定します。
```
outputs('元データ')?['prefectures']
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/28a4660a-7e61-6a43-98b2-a44cf6dec78d.png)
次に、「選択」のマップ右側にある「T」のようなボタンをクリックして、マップをテキストモードに切り替え、今度は人口だけを取り出すために以下のような式を設定します。
```
item()?['population']
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/1a453c3b-96b9-67f6-05fd-59c71bf92cce.png)
これでテスト実行してみると、みごとに人口の数字部分だけが配列に変換されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/d101f456-0721-3570-2bdb-961517ae652a.png)
# 配列の数値を合計するにはxpath関数を使う
数値を配列として用意することができましたので、次はそれらを合計します。配列の値を合計する関数がPower Automateにはなぜか見つかりません。ぐるぐるとループを回して数値変数に追加していきたくなるところですが、ぐっと我慢してほかの方法を模索していると、xpathという見慣れない関数がありました。解説にはこうあります
```
指定されたxPath式からxmlノード、ノードセット、または値をJSONとして返します。
```
さらにDOCSの該当ページを見てみると、「XPath (XML Path Language) 式と一致するノードまたは値を調べて、一致するノードまたは値を返します」とあります。
https://learn.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#xpath
なんだか難しいのですが、XMLに変換できるよう、まず以下のようなJSONを作成します。
```
{
  "root": {
    "Numbers": [1396,882,755]
  }
}
```
[1396,882,755]の配列部分は前工程で作成した結果をつかうので、画像の「出力」というのは「選択」の出力を使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/2d7f3a85-a12e-4259-e76b-1c3ef5ef27c3.png)
結果はこんな感じのJSONになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/ca6b60bf-1030-5b47-ffab-38e270d2bb78.png)
# JSONをXML関数を使って変換
できたJSONをさらにXMLに変換します。「作成」を使って以下のようにxml関数で囲みます。
```
xml(outputs('作成'))
```
できたXMLがこちら。
```
<root>
    <Numbers>1396</Numbers>
    <Numbers>882</Numbers>
    <Numbers>755</Numbers>
</root>
```
#xpath関数で目的のタグの値を合計する
いよいよxpath関数を使います。合計したいのは<Number>の中身なので、式は以下のような形になります。
```
xpath(outputs('作成_2'),'sum(/root/Numbers)')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/9b71e4cf-6484-78e4-7a16-18afd7766dfa.png)
最後にフローをテスト実行してみると、しっかり配列の値が合計されました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/a91c8fce-c40f-7f54-9671-c597775104c3.png)
CSV


https://csharp.keicode.com/topics/csv-reader.php

```c#:TextFieldParser を使用する例
using(var parser = new TextFieldParser(inputFileName))
{
    parser.Delimiters = new string[] { "," };
    while (!parser.EndOfData)
    {
        Console.WriteLine("~~~~~");
        var fields = parser.ReadFields();
        foreach(var s in fields)
        {
            Console.WriteLine($"{s}");
        }
    }
}
```


CSVHelperを使用する例

https://marunaka-blog.com/csharp-csvhelper-csv-read-write/4690/
Pirate Audio: Speaker for Raspberry Piで自前のプログラムを動かす

# はじめに
Pirate Audio: Speaker for Raspberry Piというボードを千石電商の店頭で見て買ってしまいました。
これは、Raspberry Pi Zeroに被せて使うDAC+スピーカー+カラー液晶+ボタンのついたボードです。

https://shop.pimoroni.com/products/pirate-audio-mini-speaker

もともと、音楽プレイヤーを作るためのキットとなっており、書きを実行するだけで音楽プレイヤーとして機能するようになっています。

```
git clone https://github.com/pimoroni/pirate-audio
cd pirate-audio/mopidy
sudo ./install.sh
```

が、このボードを買う人の大半は、自分好みの画面を出して自分のプログラムで制御したい人ではないでしょうか。

そのための手順をメモしておきます。

# OSのセットアップ
Raspberry Pi Zeroにピンヘッダをはんだ付けし、接続できたら、
Raspberry Pi ImagerでRaspberry Pi OSをセットアップしましょう。

書き込む前に、歯車マークからSSHの有効化とWi-Fiの設定などを済ませておきましょう。
※Wi-Fiは2.4GHz帯である必要があるので注意です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191114/ab3693cd-9c35-6068-5997-5013e1f52505.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191114/40249439-8d3e-6455-7171-de228a957a75.png)

# 初回起動
起動時にはしばらく時間がかかります。数分待ちましょう。

しばらく経ったあと、[Advanced IP Scanner](https://forest.watch.impress.co.jp/library/software/advipscanner/)などを使ってRaspberry Pi ZeroのIPアドレスを探します。

見つかったらSSHで接続しましょう

```
ssh pi@192.168.1.3
```

# セットアップ

まず下記を実行してセットアップを行います

```
sudo apt-get update -y
sudo apt-get upgrade -y
sudo apt-get install -y python3-rpi.gpio python3-spidev python3-pip python3-pil python3-numpy libopenjp2-7
sudo raspi-config nonint do_spi 0
sudo pip3 install st7789
```

次に音声デバイスの有効化を行います。

```
sudo nano /boot/config.txt
```

で/boot/config.txtを開いたあと、下記を最終行に追加して保存

```
gpio=25=op,dh
dtoverlay=hifiberry-dac
```

再起動します。

```
sudo reboot
```

SSHに再接続し、音声の設定をします。

```
aplay -l
```

下記のようにcard0 に HifiBerry DAC HiFi pcm5102a-hifi-0 が認識されていればOKです。

```
**** List of PLAYBACK Hardware Devices ****
card 0: sndrpihifiberry [snd_rpi_hifiberry_dac], device 0: HifiBerry DAC HiFi pcm5102a-hifi-0 [HifiBerry DAC HiFi pcm5102a-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: vc4hdmi [vc4-hdmi], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
```

下記で音がなるはずです。(鳴らない場合はHDMI接続していませんか？そちらで鳴っているかもしれません)

```
aplay /usr/share/sounds/alsa/Front_Left.wav
```

音量が大きすぎる場合はalsamixerコマンドで音量調整してください。

```
alsamixer
```

# サンプルを動かす

画面を映す

```
cd ~
git clone https://github.com/pimoroni/pirate-audio
cd pirate-audio/examples
python3 rainbow.py
```

ボタン入力

```
cd pirate-audio/examples
python3 buttons.py
```

バックライト制御

```
cd pirate-audio/examples
python3 backlight-pwm.py
```

ボタン入力

```
cd pirate-audio/examples
python3 buttons.py
```
No6_ググったこと投稿(5分)_DB with句


## 目次
 [1.With句について](#1-With句について)

 [2.メリット](#2-メリット)

# 1. With句について
- 1つのSQL文の中で共通した表式（テーブル）を簡略的に呼び出すことができる句のこと
- 副問い合わせ（サブクエリ）に名前を付ける機能で、一時的テーブル
```
with 名前1 as(
  select
    カラム名
  from
    テーブル
  where
    条件
)
select 
  カラム名
from
  名前1
```

# 2. メリット
- 副問い合わせに名前を付けるので可読性が上がる
- with句で作ったテーブルは、クエリ内に保存されるため、再度使う場合でもすぐに呼び出せ。再度DBに問い合わせる必要がない。
【環境構築】VyOS

# はじめに
私は2021年に新卒でインフラエンジニアとして働いています。
その中で、個人的な学習としてESXiのサーバを構築しました。
自分専用のESXiがあると、何かと勉強の幅が広がるので、初級インフラエンジニアの方は持っておくことをおすすめします！

話がそれましたが、ルータやファイヤーウォールとして使用することとができるVyOSを、<b>自由</b>に<b>壊れることを気にせず</b>、<b>いじりまくれる</b>VM環境の作成手順をまとめました。

VM作成と簡単な設定についてメモ程度で書いていくので、参考にしてみてください。


VM作成手順は下記サイトへ移動しました。

https://tatsuya-k.net/network/vyos/vyos-setup/

# 各種設定
他の設定については、随時追加していこうと思います。
## ter len 0
セッションごとにコマンド入力する必要があります。
```markdown
set terminal length 0
```

## 基本設定全般
```markdown
# ホスト名
set system host-name <ホスト名>

# タイムゾーン
set system time-zone <タイムゾーン>
## 例：東京
set system time-zone Asia/Tokyo

# ドメイン名
set system domain-name <ドメイン名>
```

## NTPサーバ設定
```markdown
# デフォルトNTP設定削除
delete service ntp 

# NTPサーバ設定
set service ntp server <NTPサーバのIP>

# NTP同期で使用するインターフェース
set service ntp interface <インターフェース名>

# 同期確認
$ show ntp
```

## ユーザ作成
```markdown
# 作成コマンド
set system login user <ユーザ名> authentication plaintext-password <パスワード>
```


## IPアドレス設定
```markdown
# 物理インターフェースにIP設定
set interfaces ethernet <インターフェース名> address <IP>
## 例：eth0に192.168.1.1/24を設定
set interfaces ethernet eth0 address '192.168.1.1/24'

## VLANインターフェースにIP設定
set interfaces ethernet <インターフェース名> vif <vlan番号> address <IP>
## 例：eth0にvlan10として192.168.1.1/24を設定
set interfaces ethernet eth0 vif 10 address '192.168.1.1/24'
```

## スタティックルーティング設定
```markdown
# 設定コマンド
set protocols static route <宛先IPアドレス>/<サブネット> next-hop <ネクストホップIPアドレス>
## 例：ネクストホップ192.168.1.1のデフォルトゲートウェイ
 set protocols static route 0.0.0.0/0 next-hop 192.168.1.1

# ルーティングテーブル確認
$ show ip route
```

## VRF設定
```markdown
# VRFインスタンス作成
set vrf name <VRF名>

# ルーティングテーブル作成
set vrf name <VRF名> table <番号>
## ※番号は100~65535

# VRFが各プロトコルを使用できるようにする
set vrf bind-to-all

# インターフェースを割り当てる
set interfaces ethernet <インターフェース名> vrf <VRF名>
## VLANの場合
set interfaces ethernet <インターフェース名> vif <vlan番号> vrf <VRF名>

# vrf別のスタティックルーティング設定
set vrf name <vrf名> protocols static route <NWセグメン>/<サブネット> next-hop <IP>
```


# 参考にしたリンク集
- [Vyatta(VyOS)のインストール方法](https://changineer.info/network/vyatta/vyatta_os_install.html)
【Mac】SVGからPNGへの変換を高画質で無料で行う方法

## 概要
画像で、SVG 形式ファイルを PNG 形式などのファイルに変換する際に、macOS のコマンドを使ってサクッと行うときの備忘録。

SVGからPNGへの変換はWeb上で無料で変換してくれるWebサイトもあるが、画像サイズが小さすぎたり、画質が悪かったりと、あまり使い勝手が良くない。
しかし、Mac ならば標準搭載の qlmanage コマンドを使用すれば簡単に高画質ファイルの変換が可能なので、これを利用する。
qlmanage は、GUI上でファイルの中身を簡単にプレビューできる Quick Look 機能で使用されているやつです。

## コマンド

#### SVG → PNG 変換のみ

```bash
# 保存先は「ディレクトリパス」なので、ファイル名まで付けないように注意
qlmanage -t -o {保存先のディレクトリパス} {変換対象のファイルパス}
```

コマンド例
```bash
# カレントディレクトリにあるファイルを、現在いる場所に出力
qlmanage -t -o ./ ./TargetPicture.svg
```


#### SVG → PNG 変換(サイズ指定)

`s` オプションでサイズしてできる
```bash
qlmanage -t -s {サイズ指定（px）} -o {保存先のディレクトリパス} {変換対象のファイルパス}
```

コマンド例
```bash
# ファイルサイズの長辺を 1024px にしてデスクトップに出力
qlmanage -t -s 1024 -o /Users/your_name/Desktop ./TargetPicture.svg
```

#### ヘルプを見れば他のコマンドもわかる
help コマンドで他のオプション詳細が確認できるので、ご参考に。

```bash
qlmanage -h
```

### 注意点
大きい辺の長さを基準に正方形にしてしまうので、加工は別にする必要があるでしょう。
【UiPath】俺「ええ！？範囲を指定していないのに範囲外なんですか！？」

# はじめに
業務でロボット稼働監視中にエラーが発生しました。
その時のエラーメッセージに危うく翻弄されかけたので、
記録として残します。



# 結論
この記事でお伝えしたいことは以下2点です。

## 今回のエラーの原因
今回の原因は、
セルの形式的に想定されている値の範囲がいのデータが入っていたことが原因でした。
以下、水科さんのスーパーわかりやすい説明です）


https://twitter.com/minamizushina/status/1627303570956750848?s=46&t=FOm5oE8xHdcUuUgQ39DXCA


（なんかでリンク見れないとかあったら困るので一応全文引用しときます）


>多分コレ、「範囲外」が「指定した範囲の外」ではなく「セルの形式的に想定されてる値の範囲外」なのよね。
Excelの日付って「1900/1/1を1として何日目か」だから、20230219日目は5万年以上先で「範囲外」なの。
わっかりにく！（UiPathよりはExcel側の問題）

## エラーメッセージ以外にも原因特定できる材料を
エラーメッセージが「範囲外～」と出るので実装面を疑いがちですが、
実装が原因でないことも十分にあり得ます。
そのために、エラーメッセージに加えて、ファイルの編集履歴などをつけておくと
原因の特定に役に立つかと思います。

# 実際に再現してみる
こんなデータを今回は用意しました。
## 用意したデータ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/c894874a-9764-3b33-5aff-b02ca8a99bda.png)
このように、セルの書式を「日付」としているのにも関わらず、
20200101のように記載していると、セルの内容が####となってしまっているファイルを
読み込むと、以下のようなエラーが出ます。
（####となっている原因としては、日付が大きすぎると認識されているからのようです）


## 動かした
この表をUiPathの「範囲を読み込み」で読み込もうとすると、
以下のようなエラーが発生します。
~~~
22.12.0-beta.11471+Branch.release-v22.12.0.Sha.d2325c659238e9a5bce4ec0fa2d550b0024490cb

ソース: フローチャート

メッセージ: 範囲  を読み取れませんでした。

例外の型: UiPath.Excel.ExcelException

UiPath.Excel.ExcelException: 範囲  を読み取れませんでした。 ---> System.Runtime.InteropServices.COMException: 範囲外です。 (0x8002000A (DISP_E_OVERFLOW))   at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
   at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Object[] aArgs, Boolean[] aArgsIsByRef, Int32[] aArgsWrapperTypes, Type[] aArgsTypes, Type retType)
   at Microsoft.Office.Interop.Excel.Range.get_Value(Object RangeValueDataType)
   at UiPath.Excel.Helpers.AreaHelper.ExtractRangeTo2DArray[T](Range range, Boolean preserveFormat)
   at UiPath.Excel.WorkbookApplication.ReadRange(String address, Boolean preserveFormat, Boolean& isWholeRange)
	--- End of inner exception stack trace ---
   at UiPath.Excel.Activities.ExcelInteropActivity`1.EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
   at System.Activities.AsyncCodeActivity.System.Activities.IAsyncCodeActivity.FinishExecution(AsyncCodeActivityContext context, IAsyncResult result)
   at System.Activities.AsyncCodeActivity.CompleteAsyncCodeActivityData.CompleteAsyncCodeActivityWorkItem.Execute(ActivityExecutor executor, BookmarkManager bookmarkManager)

~~~

エラーが発生している場所では、セルの範囲などは指定していないにも関わらず、
「範囲外」としてエラーが出ていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/1b21b207-42d0-9430-f6c9-01eca92f3cef.png)


# 参考文献

https://support.microsoft.com/ja-jp/office/-%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AE%E4%BF%AE%E6%AD%A3%E6%96%B9%E6%B3%95-bf801d0a-2a6e-44bd-a70e-0f780ae8f11e

# おわりに
尻すぼみ気味な記事になってしまいましたが、
この記事がどなたかの参考となれば幸いです。
【Android】SoundPool を使って音を鳴らす【Kotlin】

# 準備
resを右クリック→ New → Folder → Raw Resources Folder　でrawファイルを作成し、鳴らしたい音のファイルを作成します。
作成したファイルに音声ファイル(soundと命名)を追加します。
![スクリーンショット 2023-02-19 21.32.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/5aa07a0f-b0dd-0a65-407e-02be6501394e.png)

また、layout上に音を鳴らす条件となるボタンを作っておきます

```activity.main.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    
</androidx.constraintlayout.widget.ConstraintLayout>

```
# ボタンを押したら音が鳴るようにする

```MainActivity.kt
        val button: Button = findViewById<Button>(R.id.button)　　// 1

        val soundPool = SoundPool(                               // 2
            10, AudioManager.STREAM_MUSIC, 0
        )

        val soundId: Int = soundPool.load(this, android.R.raw.sound)  // 3

        button.setOnClickListener {                                   // 4
            soundPool.play(soundId, 1.0f, 1.0f, 0, 0, 1.0f)
        }
```
それぞれ解説していきます。
1.Buttonの ID を取得
2.SoundPoolオブジェクトを作成　（第一引数には音源の最大同時再生数、音を制御するためのAudioManagerの種類、サンプルレート コンバーターの品質とありますが、現在は使われていないのでデフォルトで０を設定）
3.soundPool.load()で流したいリソースを読み込むと非同期で読み込みが開始され、再生用に使うIDが返ってくるので、のちにこれを使用するために変数にする
4.ボタンが押された時の動きにsoundPool.play(）で第一引数から　ロードしたID(3で変数にしたもの), 左音量, 右音量, 優先度, ループ, 再生速度の順に入れていく
音をループさせたい場合は第五引数に-1を設定層でない場合は０を設定する


# 参考
https://android-note.open-memo.net/sub/sound--play-effect-sound-by-SoundPool.html

https://akira-watson.com/android/soundpool.html

https://qiita.com/KeithYokoma/items/3896f5934478fa560a50
Leetcode 103. Binary Tree Zigzag Level Order Traversal

https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/

# アプローチ
### BFS

```java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    
    public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
    if(root == null) return new ArrayList<>();
        
        List<List<Integer>> list= new ArrayList<>();

        Queue<TreeNode> q= new LinkedList<>();

        q.offer(root);

        boolean isReversed=true;
        while(!q.isEmpty()){
            int size= q.size();
            ArrayList<Integer> innerList= new ArrayList<>();
            for(int i=0; i<size; i++){
                TreeNode current= q.poll();
                if(current.left != null) q.offer(current.left);
                if(current.right != null) q.offer(current.right);
                innerList.add(current.val);                
            }
            if(!isReversed){
                Collections.reverse(innerList);
            }

            list.add(innerList);
            isReversed= !isReversed;

        }
        return list;
    }
}

```

 - [こちら]()を参考しました
級数展開法においてFourier-Bessel関数を用いる場合の基底関数の作り方(備忘録)

この記事は筆者(Python初学者)がプラズマトモグラフィーにおけるPythonを用いた級数展開法についての備忘録を示したものです。補足やミスなどがあれば遠慮なくコメントしてください。

# そもそも級数展開法って？
ここでの級数展開法はプラズマのトモグラフィーなどで使用される"級数展開法"を指す。ここでの説明は簡単に済ますが、級数展開法とは<font color="red">**像が基底関数の線形結合で表されるという仮定**</font>の元(ここでの像は再現したい2次元分布などの今わかっていない情報のこと)、得られた観測値(1次元)に基底関数(2次元)の投影図(1次元)を当てはめる(フィッティング)ことによって、展開係数を決定している。この展開係数をそれぞれ対応する基底関数にかけて基底関数の像を足し合わせると、観測値(1次元)から像(2次元)が得られるという手法である。

## Fourier-Bessel関数を基底関数に用いた級数展開法を式で表そう！
文章で説明してもわかりにくいと思うので一旦式で補足を交えながら説明しよう。
```math
g(r,\theta)=\Sigma^{M_{max}}_{m=0}\Sigma^{L_{max}}_{l=0}[a^{(c)l}_{m}cosm\theta+a^{(s)l}_{m}sinm\theta]g^{l}_{m}(r)
\\
g^{l}_{m}(r)=J_{m}(\lambda^{l+1}_{m}r)
```

がFourier-Bessel関数を基底関数に用いた級数展開法を示す式である。第一式からわかるように基底関数系の足し合わせであることがわかる。また第二式はBessel関数を示す。$\lambda^{l+1}_{m}$はモード数mにおける(l+1)番目のゼロ点である。
$a^{(c)l}_m,a^{(s)l}_m$は最小二乗法で決まる展開係数である。

### (補足)Bessel関数とは？
円筒関数とも呼ばれる。ここでは説明を割愛するので詳しくは各自で調べていただきたい。ここでのBessel関数は第一種Bessel関数である。下にBessel関数を記述するコード。そして結果を表示する。
```
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import jv #第一種Bessel関数

# グラフ描画領域を設定
fig = plt.figure(figsize=(8, 5))
ax = fig.add_subplot(111)
ax.set_title("Bessel functions", size=15)
ax.grid()
ax.set_xlim(-10, 10)
ax.set_ylim(-1.5, 1.5)
ax.set_xlabel("$\lambda_{m}^{l+1}r$", size=15, labelpad=10)
ax.set_ylabel("Jm($\lambda_{m}^{l+1}r$)", size=15, labelpad=8)

x = np.linspace(-10, 10, 65)

# 第1種Bessel関数をプロット
for v in range(6):
    ax.plot(x, jv(v, x), label="m={}".format(v))

# 凡例を表示
ax.legend()
```
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916351/b161b65a-1a35-ca7b-5096-df373d1f1885.png)


## 実際に基底関数系をPythonで作ってみよう!
ここまで冗長に話してきたが、実際にコードを載っけて基底関数系を作ってみましょう。(多分大半の人はできればいいはずなので早よ載せろと思っているはず...)
基底関数系のような2次元分布は地図のような等高線で表して高さ(z値)ごとで色を振り分けている。そのためまず、基底関数を構成する関数を作って、等高線を描くようなシーケンスを考えよう。
まずは$J_{0}(\lambda^{0+1}_{0}r)cos0\theta$(m=0,l=0)の時のコードを示す。
```
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import jv

fig = plt.figure(figsize=(5,5))
x = np.linspace(0, 1, 100) #等間隔で値を０～1まで100個作成
y = np.linspace(0, 360, 400) #等間隔で値を０～360まで100個作成
x, y = np.meshgrid(x, y)  #ｘ,ｙからメッシュグリッドを作成
x1 = x*np.cos(np.radians(y))
y1= x*np.sin(np.radians(y))

#第一種ベッセル関数の各モード数に対応する一番目のゼロ点のリスト
B1 = [2.40483, 3.83171, 5.13562, 6.38016, 7.58834, 8.77148, 9.93611, 11.0864, 12.2251, 13.3543, 14.4755]
m = 0 #モード数


def fz(x,y):            #高さデータzを作る関数fz定義
    return jv(m, x * B1[m]) * np.cos(m * np.radians(y))    #ここで基底関数決める→jv(m,r)*cos or sin(mθ)
z = fz(x,y)

ax = plt.contourf(x1,y1,z,cmap='jet')   #等高線レベルに応じて色を塗る
plt.xlim(-1,1)
plt.ylim(-1,1)
plt.gca().set_aspect('equal')

plt.show()
```
結果を以下に示す。
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2916351/c807f3bc-5c73-829d-bb4a-9098d5fa926e.png)
あとはモード数を変えれば、周方向にFourier級数、径方向にBessel関数の特徴を持った基底関数が描ける。
Laravelタスクスケジューラを使って定期実行を行う

# やりたいこと
毎日決まった時間に処理を動かして、バッチ処理のようなものを行う

# 手順
### 1.クラスを作成する
`php artisan make:command testSchedule`をコマンドラインで叩くと、
`App\Console\Commands`配下ににファイルができます。
この部分に実際に行いたい処理を書いていきます。
```App\Console\Commands\testSchedule.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class testSchedule extends Command
{
    protected $signature = 'test:echo';//ここで指定したコマンドを実行すると処理が走るようになる

    protected $description = 'echoする処理です';//コマンドの説明を記載する

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()//ここに実際に行いたい処理を書く
    {
        echo 'schedule_test';
    }
}
```

### 2.Kernelに登録する
```/app/Console/Kernel.php
    protected $commands = [
        Commands\testSchedule::class//追記する
    ];

```

### 3.実行時間を指定する
今回は例として、一時間に一回処理を実行したいとします。
Laravelタスクスケジューラなら他にももっと複雑な指定も可能です。
他に気になる人は[こちら](https://readouble.com/laravel/9.x/ja/scheduling.html)を見てみてください。

```/app/Console/Kernel.php
<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * Define the application's command schedule.
     *
     * @param \Illuminate\Console\Scheduling\Schedule $schedule
     *
     * @return void
     */
    protected function schedule(Schedule $schedule): void
    {
        $schedule->command('test:echo')->hourly();//1の手順で$signatureに記載したものを指定する
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands(): void
    {
        $this->load(__DIR__ . '/Commands');

        require base_path('routes/console.php');
    }
}

```
### 4.動作確認をしてみる
コマンドラインで以下を実行すると処理単体で動作確認を行えます。
ここでも[1.クラスを作成する](https://qiita.com/yusuke1209kitamura/items/c50dd38ed57f311972f1#1%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)の`$description`に追加したものを使います。
```
php artisan test:echo
```

```php artisan schedule:run```を叩くことで登録しているすべての処理を確認できます。
Redux学習メモ

# Reduxとは？
Reduxとは、アプリケーションの状態を管理するためのアーキテクチャパターン。
もしくは上記アーキテクチャパターンを実装するためのライブラリ。

### どんな状態を管理するのか？
アプリケーション全体を通して共有したい状態を管理する。
アプリケーションによるということは前提として
例えば「ユーザー情報」「認証情報」「UIの状態」「キャッシュデータ」
「アプリケーションの設定」など。

### どうやって状態管理するのか？
- Reduxではstoreと呼ばれる唯一のオブジェクトに
アプリケーション全体で共有したい状態を保存する。

- storeにある状態を更新するためには一つの方法でのみ
状態を更新することができる。

- 具体的にはactionをstoreが提供するdispatchメソッドを利用して
reducerメソッドに渡すことでのみ更新することができる。

[画像は公式より](https://redux.js.org/tutorials/essentials/part-1-overview-concepts#why-should-i-use-redux)
<img width="500" src="https://redux.js.org/assets/images/ReduxDataFlowDiagram-49fa8c3968371d9ef6f2a1486bd40a26.gif">


<table>
  <caption>各機能について</caption>
  <thead>
    <tr>
      <th>名前</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td> store  </td> <td>state(状態)が保存されるオブジェクト</td>
  </tr>
  <tr>
    <td> action </td> <td>行う処理の種類が記述されたオブジェクト</td>
  </tr>
  <tr>
    <td> dispatch </td> <td>reducerにactionを通知するためのメソッド</td>
  </tr>
  <tr>
    <td> reducer </td> <td>通知されたactionに従ってstateを更新するメソッド
</td>
  </tr>
</table>

**action**
```javascript
export const login = {
    type: 'LOGIN' //actionの種類を定義
}
```

**reducer**
```javascript
import React from 'react'

const isLoginReducer = (state = false, action) => {
    //actionの種類がLOGINだった場合はstateを反転させて更新
    return action.type === 'LOGIN' ? !state : state
}
export const isLoginReducer
```
**store**
```javascript
import { createStore } from 'redux'
//reducerからstoreを作成
const store = createStore(isLoginReducer)
```

**dispatch**
```javascript
import { useDispatch, useSelector } from 'react-redux';
import { login } from './actions';

function App() {
  //dispatchの準備
  const dispatch = useDispatch()
  //storeからstateを参照
  const isLogin = useSelector(state => state.isLogin) 
  return (
    <div className="App">
        //stateの値によって表示を切り替える
        { isLogin ? <h3>Login中</h3> : <h3>未Login</h3> } 
        //イベントが発火したらdispatchでactionを通知
        <button onClick={() => dispatch(login())}>LOGIN</button>
    </div>
  );
}

export default App;
```


### Reduxを利用するメリット
1. コンポーネントからの「状態」へのアクセスの容易さ
Reactだけでは複数のコンポーネントで同じ状態を共有したりネストが深い場合
propsによるバケツリレーが発生し、データの受け渡しが複雑になる。
Reduxでは単一のstoreがアプリケーション全体で共有したい「状態」を管理しているので、
各コンポーネントから直接アクセスできるようになる。

2. コードの可読性向上
Reduxはactionがdispatchされ、それに応じてstore内の状態が変更されるという、
単純なデータフローのため、コードの可読性やテストの容易性が向上し、状態の変更を把握しやすくなる。

3. ミドルウェアの導入による拡張性の向上
Reduxでは、ミドルウェアを導入することで、アクションのディスパッチと状態の変更の間に
カスタム処理を挟むことができる。
このため、非同期処理やロギング、ルーティングなどの機能を拡張することができる。
Linux(コマンド）

●文字列のクリア　control  + u 途中まで打ったコマンドをクリアしたい場合、 Control キーを押しながら、 u キーを押せばクリア

●現在のホームディレクトリ　 ~ 現在ログインしているユーザーの home ディレクトリはよく使われるので、特殊な PATH が用意されていて ~ (チルダ) という記号で表す 

●コマンドの使い方やオプション・・-- help, man 

●コピー　cpコマンド、デフォルトだとファイルだけが対象。ディレクトリも含めるには-rオプション

●ディレクトリの一括作成　mkdir -p myapp/css/...

●テキストを操作するコマンド・・
１、wc (word count)・
２、wc ーl 行数だけ表示
3,grep ファイルの中身から特定の単語を検索するためのコマンド

●特定のユーザーがどのグループに所属しているか調べるコマンド
groups ユーザー名

●ルートユーザー・・特殊なコマンドである sudo を使うことで必要なときだけルートユーザーの権限を使って作業するのが一般的

●which 実行しようとしているコマンドがどこのディレクトリから呼び出されているか

export は環境変数を設定するための命令
VSCodeでJupyterNotebookを使う際のMarkupフォントサイズ変更方法

## 手順

VSCodeの設定画面を開き、右上のファイルみたいなアイコンをクリックすると、settings.json（VSCodeの設定ファイル）が開ける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2638738/0ae642dc-4b3e-0fd6-5da1-7740c721aa15.png)

環境によってはsettings.json内にすでにいくつか設定項目が書かれているが、そこに以下を追記する。
```
"notebook.markup.fontSize": <好きなフォントサイズ>,
```

以下の画像は14ptに設定した例。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2638738/39f0ec3a-1db3-87a7-2192-3d1d10079c29.png)

## 参考
- https://stackoverflow.com/questions/69176092/how-to-change-font-size-of-jupyter-notebook-in-vs-code
壊れてしまったハードディスク、SSD、USBメモリを復活させる方法の一つ。


壊れてしまったHDD、USBメモリ、SSDなどのストレージデバイスを復活させる方法の一つ。
壊れてしまったストレージデバイスは、パーティションテーブルが壊れているだけで、データが生き残っている場合が多々あります。新しいOSのインストールミスなどでパーティションテーブルが壊れる場合があり、実際まだファイルを書き込んでない場合のストレージデバイスの復活方法を書いておきます。

(1) 手元にあるlinux liveCDのブートディスクで、linuxを起動させます。
(2) ルートになります。
(3) fdiskを起動させます。
    fdisk /dev/sda
(4) dコマンドでパーティションを削除します。
(5) nコマンドで、「新しいパーティション」を作ります。
ここで、d、nコマンドはパーティション削除、新しいパーティションを作ると書いていますが、実際にはパーティションテーブルを書き換えているだけです。
nコマンドで「新しいパーティションを作る」とき、最初のセクタ、最後のセクタを指定しなければいけませんが、これは、壊れる前のスタートセクタとエンドセクタを指定して下さい。解らなければ計算して出して下さい。USBメモリドライブなどは、一つのパーティションで、0から終わりの物理セクタまで目一杯使ってる場合がほとんどです。
(6)wコマンドでパーティションテーブルを書き込み、qコマンドで抜けます。

これで、終わりです。パーティションテーブルが壊れていただけの場合は、これで復活できます。
Next.jsのデバッグ設定で出るエラーの原因と対応方法('NODE_OPTIONS' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません)

(※検索すると[cross-env](https://www.npmjs.com/package/cross-env)入れろとか、ちょっと荒っぽい対策だったので原因を書きました)

## 前書き
* Next.jsのデバッグ方法を調べると、`package.json`の`scripts`を下記のように書き換えて実行すると書いてあります。
```json
 "scripts": {
    "dev": "NODE_OPTIONS='--inspect' next dev",
```

ところが、Windows(VSCode)で実行すると、下記のようなエラーが出て？となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276579/3f4d7af4-42d7-d740-4237-1f006db05ed5.png)

## 原因
npmが`scripts`を実行する際、「コマンドプロンプト(cmd.exe)」を利用するように設定されているからです。
コマンドプロンプトでは、`NODE_OPTIONS='--inspect' next dev`という記述は、構文エラーになります。

* Windowsの場合、例えgit-bashを利用していても、npmの初期設定「cmd.exe」が使われる

### npmが`scripts`実行で利用するシェルの確認方法
```
>npm config get script-shell
C:\WINDOWS\system32\cmd.exe
```

## 対策①(コマンドプロンプトが理解できる記述に変更する)

一番簡単な対応方法は、cmd.exeが理解する構文に変更するのが早いです。
(setで環境変数の設定をして、&& でコマンドを続けて実行)
```
set NODE_OPTIONS=--inspect && next dev
```

## 対策②(シェルをgit-bashに変更する)

```
npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"
```
(シェルをbashにすると、何か別の問題が発生した(詳細は失念)ので、①をお勧めします)
SpringBoot @PostMappingについて

@PostMappingアノテーションが定義しているメソッドは与えられたURI表現式と一致するHTTP POSTの要請を処理します。

```java
// import 省略
@RequestMapping(value = "/api/person") 
@RestController 
@Slf4j
public class PersonController {
    @Autowired
    private PersonService personService;

    @Autowired
    private PersonRepository personRepository;

    @GetMapping("/{id{")
    public Person getPerson(@PathVariable Long id) {
        return personService.getPerson(id);
    }

    @PostMapping
    @ResponseStatus(HttpStatus.OK)
    public void postPerson(@RequestBody Person person) {
        personService.put(person);
        log.info("person -> {}", personRepository.findAll());
    }
}
```
@RestControllerは、PersonControllerクラスはREST API Controllerを使用しますよとの宣言アノテーションです。
クラスに定義している@RequestMappin(value="/api/person")のscopeはクラス全体なので、
postPerson()は("/api/person")のURIに対応します。
log.info()の"{}"には、二つ目のfindAll()が出力されます。log.inforを使うには@Slf4j定義が要！

```java:PersonControllerTest
// import 省略
@SpringBootTest
public class PersonControllerTest {

    @Autowired
    private PersonController personController;

    private MockMvc mockMvc;

    @Test
    void getPerson() throws Exception {
        mockMvc = MockMvcBuilders.standaloneSetup(personController).build();

        mockMvc.perform(
                MockMvcRequestBuilders.get("/api/person/1"))
                .andDo(MockMvcResultHandlers.print())
                .andExpect(MockMvcResultMatchers.status().isOk());
    }

    @Test
    void postPerson() throws Exception {
        mockMvc = MockMvcBuilders.standaloneSetup(personController).build();

        mockMvc.perform(
                MockMvcRequestBuilders.post("/api/person")
                       .contentType(MediaType.APPLICATION_JSON)
                       .content("{\n" +
                        "    \"name\": \"martin2\", \n" +
                        "    \"age\": 20, \n" +
                        "    \"bloodType\": \"A\"\n" +
                        "}"))
                        .andDo(print())
                        .andExpect(status().isCreated());
//                        .andExpect(status().isOk());
    }
}
```
PersonControllerクラスのテストコードです。
personConteollerにDI(Dependency Injection)して、mockmvcを生成してます。
MockMvcRequestBuildersのpostは、PersonControllerの@PostMapping定義メソッドに相当します。
contentにはjsonデータのため、contentTypeにJSONを定義しなければなりません。
PersonControllerのpostPersonに定義したのは「@ResponseStatus(HttpStatus.OK)」のため、
andExpectをstatus().isOK()の確認をしています。
もし、データがちゃんと作られたかを確認したい場合は
isOK　→　isCreated()に変えて
@ResponseStatus(HttpStatus.OK)　→ @ResponseStatus(HttpStatus.CREATED)に変えればOK！
追記で、conetentにjsonのデータが入っていますが、.jsonファイルに以下のように書きコピーして
.content("")に貼り付ければ簡単に整形されます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/fa1e4132-be67-b82c-ec66-c756c7282cae.png)


テスト結果！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3097775/611b6fd6-32e0-50cd-62d6-21c2c983da92.png)
久々のpython3でScrapyを使ってWebスクレイピングをしてみた

こんにちは、ひらきちです。
久々にプログラミング（1年ぶりくらい？）で、Webスクレイピングをしてみました。

昔は、Python3のjsonパース機能と、beautifulsoupを使ったりしていたのですが、
めんどくさいなーと思って調べたら、scrapyという素晴らしいライブラリが存在するじゃないですか！

そこで、今日はscrapyを学ぶのに必要な時間、サイトなど諸々まとめておきます。

# Scrapyを学ぶのに参考にしたサイト
まず全体を学ぶならこちらがおすすめ。

https://ai-inter1.com/python-scrapy-for-begginer/


そして、スクレイピングの中で「HTMLのどの要素を抽出するか」を選ぶために使うのがxpathやCSSセレクタ。今回はxpathを利用。xpathの書き方を学ぶために、以下のサイトを参考にしました。

https://qiita.com/rllllho/items/cb1187cec0fb17fc650a?fbclid=IwAR3qUmbTHTxQzKVdcklsvD7J3kM2UFcR7pNhk_ib9nEpCIsDysSETy1O8sE

また、商業向けに提供されているサイトでプログラミングの練習をするのはまずい（DDoSになりかねない）ので、以下の練習用サイトを使うとよさそうです。

https://books.toscrape.com/

# 学習時間

50分。

MacBookに基本的なターミナル開発環境は揃っている前提で、pip3 installから、スクレイピングがうまくいくまで約50分です。

# 前提条件
以下の条件を満たしていれば同様に短時間で学べると思います。

* python3を一通り理解している
* HTMLを一通り理解している
* pip3を使ったことがある

# 注意点
商用サイトをスクレイピングする際には、DDoS（Distributed Denial of Service）にならないように、プログラムを制御する設定が必須。

以下の設定をすると、
* 次のアクセスまで3秒を開ける
* Robots.txtに従って動作する
という振る舞いをするようです。

```settings.py
DOWNLOAD_DELAY = 3
ROBOTSTXT_OBEY = True
```

あとはお行儀の良いクローリング（Webサイト巡回）をするなら、UserAgentを設定しておいた方が良いかもしれませんね。（ただGoogleがUserAgentを非推奨にした関係で、近い将来、UserAgentがなくなるかもしれませんが）

# Next Action
ちょっと副業でデータ抽出とかこれでサクッと楽してできないかなーと狡いことを考えています（笑）
まぁ実際はそんなにうまくいかないと思うんですけどね。
好奇心が満たされたのでOKです。

# おまけ：はまった点：

「MacBookのターミナル上でころんとドットの区別がつかなかった」

これはMacOS 12にしてから、Terminalの文字を変えたのが原因。
getメソッドの .get() が ,get() になっていたのが判別しづらいフォントでハマりました。

まぁこれは環境要因なので、Webスクレイピングの学びとはちょっと違うので「おまけ」とさせていただきましたw
RDSイベントサブスクリプション

# RDSイベントサブスクリプションについて

## 1.RDSイベントサブスクリプションとは
- RDSに関係するイベントが発生した際、そのことをAmazon SNSで通知できる仕組み。
  ※イベント：DBインスタンスの起動や終了、パラメータグループやセキュリティグループの変更等、
   RDSに関係する様々な設定変更や状態変更のこと。

AWS公式ドキュメント
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_Events.html

### 主なメリット
- 事前にメンテナンス情報を把握することで、「知らないうちにAWSによるメンテナンスが実施されて、サービス影響が発生してしまった...!」なんてことを防げるようになる。

- 本番環境が変更された場合、それが意図したものかどうか確認できる「監視」の役割も担える。

- 設定が簡単で、稼働中のサービスにも影響がない。


## 2.設定方法
- AWSコンソール画面での設定
　Amazon RDS画面
→「イベントサブスクリプション」を選択
→「名前」を入力
→「ターゲット」を選択
　通知先のSNSトピックのARN、もしくは任意のEメールアドレス
→「ソース」と「イベントカテゴリ」を選択
　ソースとイベントカテゴリは任意のものを選択可能。1つのソースに複数のイベントカテゴリを設定することも可能。
　ソースごとに設定可能なイベントカテゴリの確認は、以下のAWS公式を参照
　　https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_Events.Messages.html
→「作成」

## 3.注意点
- ソースごとに設定可能なイベントカテゴリが異なる
 →必ず公式ドキュメントの設定一覧を確認

- DBインスタンスとDBクラスターでは、同じイベントカテゴリを指定しても通知内容が異なる場合がある
　例)イベントカテゴリ：maintenance
　　通知内容：DBインスタンス・・・パッチ適用が通知対象に含まれる
　　　　　　　DBクラスター・・・パッチ適用が通知対象に含まれない
　　　　　　　　　　　　　　　（※maintenanceに加え、「notification」を追加する必要がある)
【Golang】依存モジュールが依存するモジュールのバージョンを決め打ちする【Go 1.16+】

## GitHub dependabot の脆弱性アラートに対処する (`x/crypto/ssh vulnerable to panic via SSH server`)

なんてことない小さな俺様 Go パッケージで、こんなんでました。

![スクリーンショット 2023-02-19 11.21.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78776/b861fbe7-1d81-1fa2-1b4d-49f8abd16a12.png "x/crypto/ssh vulnerable to panic via SSH server. Dependabot cannot update to the required version. One or more dependencies require a version that is incompatible with this update.")

メインのパッケージでは `x/crypto/ssh` は利用していないものの、依存パッケージが利用していました。

つまり `// indirect` で `require` された `golang.org/x/crypto` のバージョンに脆弱性（[CVE-2021-43565](https://nvd.nist.gov/vuln/detail/CVE-2021-43565)）があるらしいのです。

`golang.org/x/crypto` のバージョンを上げればいいのですが、<font color=darkorange>**依存先のパッケージがバージョンを上げてくれない**</font>ため、`go.sum` がない場合、`go tidy` すると古いバージョンに戻されてしまうのです。

## TL; DR <sub><sup>（今北産業）</sup></sub>

1. 普通に `go get -u golang.org/x/crypto && go mod tidy` でアップデートしてみる
1. アップデートできない（バージョンが差し戻される）場合は、以下を試す
    - 依存しているパッケージの管理者に `go.mod` を更新するように依頼する
    - パッチ済みの<font color=darkorange>特定のバージョンを利用するように `go.mod` でキメ打ちする</font>
1. キメ打ちする例

    ```diff:go.mod
      module github.com/KEINOS/example
      
      go 1.16
      
      require (
      	github.com/labstack/gommon v0.4.0
      	github.com/mkideal/cli v0.2.7
      	github.com/pkg/errors v0.9.1
      	github.com/stretchr/testify v1.8.1
      	github.com/zenizh/go-capturer v0.0.0-20211219060012-52ea6c8fed04
      )
      
    + // Fix CVE-2021-43565 (do not forget to update to the latest)
    + require golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b // indirect
    ```

依存しているパッケージの `go.mod` と `go.sum` が永らくメンテナンスされておらず、更新依頼しても反応がない場合の対処として。
GASでgmailの添付ファイルをAzureStorageに送信

Postmanなら英語情報あるけど、GASで書いているところがなかったのでメモで残しておく
テスト用スクリプト

```
var FindSubject = 'subject:(メールで引っこ抜きたいタイトル) ';
 
function getMail(){
 //この辺りはたくさん情報あるのでパクリ
  //指定した件名のスレッドを検索して取得 
  var myThreads = GmailApp.search(FindSubject, 0, 15); 
  //スレッドからメールを取得し二次元配列に格納
  var myMessages = GmailApp.getMessagesForThreads(myThreads);
  // とりあえずGoogleDriveに保存する
  var folder = DriveApp.getFolderById("GoogleドライブのフォルダのURLの最後のところ");

  var finename;

  console.log(myMessages.length);
  
 
  for(var i in myMessages){
    for(var j in myMessages[i]){
 
      //スターがないメッセージのみ処理   
      if(!myMessages[i][j].isStarred()){ 
        
        var strDate　=　myMessages[i][j].getDate();
        var strSubject　=　myMessages[i][j].getSubject();
        var strMessage　=　myMessages[i][j].getPlainBody().slice(0,200);
        var attachments = myMessages[i][j].getAttachments();
        
        // 特に意味ないがGoogleDriveにも保存しておく
        if( attachments.length > 0 ){
          var file = attachments[0];
          filename = file.getName();
          file.setName(filename);
          folder.createFile(file);
          sendFileAzure(file);
        }
 
        //処理済みのメッセージをスターをつける
        myMessages[i][j].star(); 
      }
    }
  }
}

// これがAzureに送信するところ
function sendFileAzure(attachFile){
 // ストレージアカウントのShared Access Signatureで作成出来るURL。コンテナ名とファイル名を忘れずに。今回は固定ファイル名にしている
  var endpoint = "https://ストレージアカウント.blob.core.windows.net/コンテナ名/ファイル名?sv=2021-06-08&ss=bf&srt=o&sp=rwactfx&se=2023-03-31T15:55:29Z&st=2023-02-17T07:55:29Z&spr=https&sig=ほにゃほにゃ";
  
  //post でなく putなのが注意。最低限必要なのはx-ms-blob-type
  x=UrlFetchApp.fetch(endpoint, {
  'headers': {
    'x-ms-blob-type':'BlockBlob'
  },
  'muteHttpExceptions' : true,
  'method': 'PUT',
  'payload':attachFile
  });

  // 201がかえれば成功
  console.log(x.getResponseCode());

}

```
IT用語の「フェールオーバー」と制御システム用語の「フェールセーフ」を念のため再確認

# はじめに
最近、「フェールセーフ」という用語がニュースをにぎわしているので、念のため確認しました。IT業界に移る前は製造業でエンジニアをしておりましたが、「フェールセーフ」な制御を要するミッションクリティカルな事案に参画するわけでもなく、宇宙工学にあこがれていた学生のころ、スペースシャトル・チャレンジャーの機体が爆発消失するという事故が起きたころに知識として覚えた程度でした。IT業界に移ってからは、圧倒的に「フェールオーバー」のが身近で、機器構成上クリティカル点が存在してデータベースが「フェールオーバー」せずにデータセンターで復旧まで徹夜作業というのがいまとなっては懐かしい感じ。

# IT用語の「フェールオーバー」と制御システム用語の「フェールセーフ」
## 「フェールオーバー」

[出典: フリー百科事典『ウィキペディア（Wikipedia）』- フェールオーバー](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A7%E3%82%A4%E3%83%AB%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC)

「フェイルオーバー（英語: failover）は、現用系コンピュータサーバ/システム/ネットワークで異常事態が発生したとき、自動的に冗長な待機系コンピュータサーバ/システム/ネットワークに切り換える機能を意味する。」

## 「フェールセーフ」
[出典: フリー百科事典『ウィキペディア（Wikipedia）』- フェールセーフ](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A7%E3%82%A4%E3%83%AB%E3%82%BB%E3%83%BC%E3%83%95)

「フェイルセーフ（フェールセーフ、フェイルセイフ、英語: fail safe）とは、なんらかの装置・システムにおいて、誤操作・誤動作による障害が発生した場合、常に設計時に想定した安全側に動作するようにすること。またはそう仕向けるような設計手法で信頼性設計のひとつ」

引用だけで終わると引用にならず、なんかまずい気がしますが、「はじめに」でそれぞれの用語の接点は書いたので、なんとかゆるしてもらえるかもしれない。「補助エンジン始動っ！」みたいな感じで予備のSRB-3がフェールオーバーするというのは現実的に無理なのだろうか！？

なんの話かと申しますと、2023年2月17日の次期国産基幹ロケットH3初号機が発射シーケンス中に「フェールセーフ」して発射が中断した状況についてのJAXAさんの「あの」記者会見の質疑応答のことです。

# おわりに
ソフトウエアの関数の実行結果をブール値で返すと、成功(true,success)か失敗(false,failure)かの2値なので、成功でなければ失敗というりくつが成り立ちますが、機体が飛行中に制御不能になって自爆させたとかでないので、失敗確定ではないといいますか、JAXAさん、MHIさんがんばれのスタンスです。
しかし、アナログ制御だと、エラーコードが返ってきてある程度どのあたりの障害がわかるとかではないようですね。
IT業界に移ってからの現役時代は（いまは何時代？）は民間製造業のインターネットシステムに多く携わってまいりましたので、日本の製造業大応援です。H3とか水素っぽいネーミングが日本の将来をしょってるみたいで大好きです。（Hシリーズは液体水素燃料エンジンに由来）

# 参考リンク
https://qiita.com/nanatsu/items/e900841a9f678fa07296
高度人材&永住者申請材料（2023年1月时点）

##### 简单说明
- 高度人才签证纵向分为三种，经营类，研究类，技术类。经营类一般是公司管理者申请，研究类是高校或研究学术机构雇员申请，技术类是一般上班族申请。
- 高度人才签证横向分为两级，根据[入国管理局高度人才分数表计算](https://www.moj.go.jp/isa/publications/materials/newimmiact_3_evaluate_index.html)，70分档和80分档。70档可以在取得高度人才签证3年后申请永驻，80档可以在取得高度人才签证1年后申请永驻。
- 或者不申请高度人才签证，而是在1年（满足80分）或3年（满足70分）后直接申请永驻；此时需要随永驻申请材料一同提交，能够证明申请人在1年，或是3年前，已经满足对应高度人才签证要求的材料。
- 以下证明如果个人逐一申请很花时间，图方便的话可以直接委托行政书士，价格在10～15万日元不等，地方会便宜点，且地方入国管理局排队时间不长。

##### 技术类（一般上班族）申请永驻时所需材料，一年或三年前满足高度人才情况下，直接申请永驻（为防止歧义使用日语描述材料名）
**以下の書類は申請日から3ヶ月以内に発行された物が必要**
- 永住許可申請書
  - [入国管理局网站](https://www.moj.go.jp/isa/applications/procedures/zairyu_eijyu03.html)下载
- 永住申請理由書
  - 谷歌搜索模版
- ４cm x ３cm写真（三ヶ月以内）
- パスポート原本
- パスポートコピー
- 在留カード原本
- 在留カードコピー
- （提出任意）履歴書と職務経歴書
- 住民票（世代全員記載があるもの）
- 在職証明書
- 直近５年度分住民税課税証明書
  - 区役所开设证明，来日期间不满5年的话，来了多久开多久的证明
- 直近５年度分住民税納税証明書
  - 区役所开设证明，来日期间不满5年的话，来了多久开多久的证明
  - 前一年的课税证明与纳税证明需要在当年一月一日户籍所在地的区（市）役所开设，入图例
    ![スクリーンショット 2023-03-03 23.09.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747384/ddf62d1d-09c6-5ca0-55ef-59a025a90601.png)

- 直近５年間住民税は適正な時期に収めている資料（領収書など）
  - 如果是一般上班族且没有副业等需要额外计算的情况，公司会负责上交，一般不需要
- 源泉所得税及び復興特別所得税、申告所得税及び復興特別所得税、消費税及び地方消費税、相続税、贈与税に係る納税証明書
  - 当前所在地方的税务署取得，不需要指定日期
- 年金ネットの「各月の年金記録」の印刷画面
  - 年金ネット网站上有记录，直接打印
- 家族全員分の健康保険証の写し（両面）
- 国民健康保料（税）納付証明書及び国民健康保険料（税）納付領収書の写し
  - 最近两年内才加入国民健康保险的情况下才需要
- 国民年金保険料領収書（写し）
  - 最近两年内才加入国民健康保险的情况下才需要
- 貯蓄金通帳の写し
  - 有实体的「通帳」的话复印账号内容页以及明细页，网上银行的情况打印带有账号的明细页
- （提出任意）推薦状、表彰状などの写し
- 資格の合格証の写し（日本語能力試験など）
- （提出任意）運転免許の写し
- （提出任意）運転経歴証明書
- （提出任意）不動産の登記簿謄本（持ち家あるの場合）
- （提出任意）扶養親族者のリスト及び送金明細の写し（親族扶養がいる場合）
- （提出任意）配偶者の在職証明書
- （提出任意）配偶者の住民税の課税証明書
- （提出任意）配偶者の住民税の納税証明書

**由于跳过了高度人才签证直接申请永驻，因此需要补充高度人才相关的证明**
- 直近1年度分住民税課税証明書
- 直近1年度分住民税納税証明書
- 源泉所得税及び復興特別所得税、申告所得税及び復興特別所得税、消費税及び地方消費税、相続税、贈与税に係る納税証明書
  - 当前所在地方的税务署取得，不需要指定日期
- 年金ネットの「各月の年金記録」の印刷画面
- 健康保険証の写し（両面）
- 高度専門職のポイント計算表（申請時点のもの）
  - [入国管理局网站](https://www.moj.go.jp/isa/publications/materials/newimmiact_3_evaluate_index.html)下载，计算方法参考[入国管理局说明](https://www.moj.go.jp/isa/content/930001657.pdf)
- 高度専門職のポイント計算表（申請時点から一年前のもの）
- 上記ポイント計算表の疏明資料

**身元保証人需要的证明（日籍或者永驻者）**
- 身元保証書（印鑑ある物）
- 身元保証人の職業を証明する物（在職証明書、謄本、確定申告書の写しなど）
- 身元保証人の住民税の課税証明書（直近1年度分）
- 身元保証人の住民税の納税証明書（直近1年度分）
- 源泉所得税及び復興特別所得税、申告所得税及び復興特別所得税、消費税及び地方消費税、相続税、贈与税に係る納税証明書
  - 当前所在地方的税务署取得，不需要指定日期
- 身元保証人の住民票
- 身元保証人の身分証明書の写し（運転免許など）
- 身元保証人のパスポートの写し（顔写真のページ）
  - 只有身元保証人是外国人的情况下需要
- 身元保証人の在留カードの写し
  - 只有身元保証人是外国人的情况下需要