OmniAICreator/Qiita-1.07M huggingface dataset:
第三回 Flutter + VScode でLinuxアプリを作成する(完成編)

##はじめに
全3回に分けFlutterでLinuxのGUIアプリを作成する手順をまとめています。
開発環境はVScodeを使用し、タイマーアプリを作成します。

第一回　[環境構築編](https://qiita.com/fia/items/435b72b9ef6ca9e0410c "第一回 Flutter + VScode でLinuxアプリを作成する(環境構築編)")
第二回　[画面作成編](https://qiita.com/fia/items/3ac710fa0a441162b149 "第二回 Flutter + VScode でLinuxアプリを作成する(画面作成編)")
第三回　完成編(今回はここ)

今回は前回の続きから完成までの記事です。

##完成画面
![02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180892/a7b7e897-ee85-7b54-a7c0-e3a2e8e75a14.jpeg)
![03.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180892/70c60d48-67aa-d709-427a-49ed517ce1e3.jpeg)


では、早速始めていきます。
ソースコードは[ここ](https://github.com/fia-119556/flutter-linux-timer)

##タイマー処理
前回のプロジェクトに処理を追加していきます。前回の記事を読んでいない方は先にそちらをお読みください。
変更していくファイルは、前回同様`app/lib/main.dart`です。

まず、タイマーを作成するのに必要なものをインポートします。

```main.dart
import 'dart:async';
```

つぎに、スタートボタンの処理を記述します。
`setState`は設定内容を画面に反映させるために使用します。
`Duration(seconds: 1)`により1秒ごとに処理が流れるようにしています。
書き方はJavaやC#とほぼ一緒なのでその辺の経験がある方は、理解できると思います。
注意する点は除算の計算で`/`は、浮動小数になるため、整数切り捨てにするために`~/`を使用します。

```main.dart

  void _startPressed() {
    if (_time == "00:00") return;
    setState(() {
      if (_start == "START") {
        _start = "STOP";
      } else {
        _start = "START";
      }
    });
    Timer.periodic(
      Duration(seconds: 1),
      (Timer timer) => setState(
        () {
          if (_start == "START") {
            timer.cancel();
          } else {
            List t = _time.split(':');
            int sec = int.parse(t[0]) * 60 + int.parse(t[1]);
            sec--;
            _time = (sec ~/ 60).toString().padLeft(2, "0") +
                ":" +
                (sec % 60).toString().padLeft(2, "0");
            if (sec == 0) {
              timer.cancel();
              _start = "START";
            }
          }
        },
      ),
    );
  }
```
最後に、数字ボタンの処理を記述します。
今回は、タイマーが動いている最中はボタンを押しても無視するようにします。
数字を押したら右端に追加しています。
lengthを取っている理由は「99:99」など異常値になりえるものが入力されたときの対策です。

```main.dart
  void _numberPressed(String number) {
    setState(() {
      if (_start == "START") {
        int len = _time.length;
        _time = _time[len - 4] + _time[len - 2] + ":" + _time[len - 1] + number;
      }
    });
  }
```

以上で、処理の追加は終了です。

##出力アプリ名の変更
前回までは、リリースビルドした際、`app`という名前で出力されていました。
それを変更します。
変更ファイルは`app/linux/CMakeLists.txt`です。

```CMakeLists.txt
//4行目
set(BINARY_NAME "Timer")
```

##アプリヘッダー名の変更
前回までは、アプリのヘッダーが`app`という名前で表示されていました。
それを変更します。
変更ファイルは`app/linux/my_application.cc`です。

```my_application.cc
//43行目
gtk_header_bar_set_title(header_bar, "Timer");

//48行目
gtk_window_set_title(window, "Timer");
```

#終わりに
全3回を通してLinuxアプリを作成しました。
LinuxでGUIアプリを作ることは、あまりないかもしれませんが、
何かのお役に立てれば幸いです。

最後まで読んで下さり、本当にありがとうございました。

間違い等がありましたらご指摘・コメントをお願いします。
webカメラでストリーミング再生

## 概要
手元にあったRaspberry pi 4でストリーミング再生できるカメラを設置しようと思いったので、その手順をまとめます。

## 準備
- Raspberry Pi 4 Model B
- Micro SD(初回のみUSBブート設定に必要)
- USB
- webカメラ(C960)
参考：https://www.amazon.co.jp/gp/product/B07MBQ1PT3/
- ubuntu server 20.10(RPI 3/4/400)


## 手順

まずは、下記の記事を参考にRaspberry piにubuntu server 20.04をセットアップする。
[Raspberry Pi 4でUSBブートのubuntu serverを建てよう](https://qiita.com/____easy/items/15d3348b7fb5a32b1ba8)

無事OSのインストールが完了したらストリーミング再生に必要なライブラリをインストールする。

```
sudo apt update
sudo apt install nginx
sudo apt install libnginx-mod-rtmp

sudo apt install v4l-utils
sudo apt install alsa-utils
sudo apt install ffmpeg
```

### nignx の設定

`/etc/conf.d/rtmp`の中身を書く。ファイル名を`rtmp.conf`にするとエラーを吐くので注意。

```conf
rtmp {
    server {
        listen 1935;
        chunk_size 4096;
        allow play all;
        access_log /var/log/nginx/rtmp_access.log;

        application live {
            live on;
            hls on;
            record off;
            hls_path /var/www/html/live/hls;
            hls_fragment 1s;
            hls_type live;
        }
    }
}
```

`/etc/nginx/nginx.conf`に下記の行を追記。

```
include /etc/nginx/conf.d/rtmp;
```

### htmlファイルの作成

`/var/www/html/`以下に雛形の`index.html`を作成する。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8"/>
  <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>

<body>
  <video id="video" controls width="100%"></video>
  <script>
    if(Hls.isSupported()) {
      var video = document.getElementById('video');
      var hls = new Hls();
      hls.loadSource('live/hls/stream.m3u8');
      hls.attachMedia(video);
      hls.on(Hls.Events.MANIFEST_PARSED,function() {
      video.play();
    });
   }
  </script>
</body>
</html>
```

### ストリーミング動画の保存場所を作成
また、`/var/www/html/`以下に`live`フォルダを作成しシンボリックリンクを貼る。


```
mkdir live
cd live
sudo ln -s /dev/shm hls
```


## ストリーミング再生
```sh
ffmpeg \
        -f alsa -ac 1 \
        -thread_queue_size 8192 \
        -i hw:2 \
        -i /dev/video0 \
        -vcodec libx264 \
        -vsync 1 -g 16 \
        -c:a aac -ar 44100 -af "volume=30dB" \
        -f flv rtmp://localhost/live/stream
```

音声デバイスの確認

```
arecord -l
```

webカメラの確認

```
v4l2-ctl --list-device
```
iotaでコンパイル時fizzbuzz

# コード

```go
package main

import (
	"fmt"
)

const (
	sp = 8203
)

const (
	_ = string(sp-8101*(((iota+2)%3)>>1)) +
		string(sp-8098*(((iota+2)%3)>>1)) +
		string(sp-8081*(((iota+2)%3)>>1)) +
		string(sp-8081*(((iota+2)%3)>>1)) +
		string(sp-8105*(((iota+4)%5)>>2)) +
		string(sp-8086*(((iota+4)%5)>>2)) +
		string(sp-8081*(((iota+4)%5)>>2)) +
		string(sp-8081*(((iota+4)%5)>>2)) +
		string(sp-(8155-(iota/10%10))*(1-((((iota+2)%3)>>1)|(((iota+4)%5)>>2)|-((iota-10)>>65535)))) +
		string(sp-(8155-(iota%10))*(1-((((iota+2)%3)>>1)|(((iota+4)%5)>>2))))
	_1
	_2
	_3
	_4
	_5
	_6
	_7
	_8
	_9
	_10
	_11
	_12
	_13
	_14
	_15
)

func main() {
	fmt.Println(_1)
	fmt.Println(_2)
	fmt.Println(_3)
	fmt.Println(_4)
	fmt.Println(_5)
	fmt.Println(_6)
	fmt.Println(_7)
	fmt.Println(_8)
	fmt.Println(_9)
	fmt.Println(_10)
	fmt.Println(_11)
	fmt.Println(_12)
	fmt.Println(_13)
	fmt.Println(_14)
	fmt.Println(_15)
}
```

```
1
2
fizz​​​​​​
4
buzz​​
fizz​​​​​​
7
8
fizz​​​​​​
buzz​​
11
fizz​​​​​​
13
14
fizzbuzz​​
```

# しくみ

## iotaとコンパイル時計算

iotaはenumとしてよく使われますが、`Hoge = iota` だけでなく式の形でも宣言できます(数列のように扱えます)。

[Effective Go - The Go Programming Language](https://golang.org/doc/effective_go#constants)

また、intからstringの型変換もコンパイル時計算可能なため、`string(i)`でunicodeの文字コード`i`の文字列を取得可能です。

```go
fmt.Println(string(65)) // A
```

あとは、iotaの余りに応じてfizzbuzzの文字列に変換すればOKです。

## ゼロ幅スペース

しかし、`string(i)`の方法には1つ欠点があります。なにかしらの文字が常に出力され、**文字を表示しないことができない**のです。

そこで、目には見えない文字「ゼロ幅スペース」を使用します。

[​ - ゼロ幅スペース: U+200B - Unicode キャラクター図鑑](https://unicode-table.com/jp/200B/)

デフォルトでは各文字がゼロ幅スペース(`sp`)になるようにし、条件を満たすときのみ別の文字列に変更しています。

```go
_ = string(sp-8101*(((iota+2)%3)>>1)) + // "f"(3で割れる) or ""
		string(sp-8098*(((iota+2)%3)>>1)) + // "i"(3で割れる) or ""
		string(sp-8081*(((iota+2)%3)>>1)) + // "z"(3で割れる) or ""
		string(sp-8081*(((iota+2)%3)>>1)) + // "z"(3で割れる) or ""
		string(sp-8105*(((iota+4)%5)>>2)) + // "b"(5で割れる) or ""
		string(sp-8086*(((iota+4)%5)>>2)) + // "u"(5で割れる) or ""
		string(sp-8081*(((iota+4)%5)>>2)) + // "z"(5で割れる) or ""
		string(sp-8081*(((iota+4)%5)>>2)) + // "z"(5で割れる) or ""
		string(sp-(8155-(iota/10%10))*(1-((((iota+2)%3)>>1)|(((iota+4)%5)>>2)|-((iota-10)>>65535)))) + // iotaの10の位(3でも5でも割れず、iotaが10以上) or ""
		string(sp-(8155-(iota%10))*(1-((((iota+2)%3)>>1)|(((iota+4)%5)>>2)))) // iotaの1の位(3でも5でも割れない) or ""
```

コメントを書くと冗長なのが丸わかりですね... :sweat_smile:

- 3項演算子が無い
- boolをintとして使えない
- 関数が使えない（実行時計算になる）

という縛りがあったので、ビット演算のべた書きになっています。「もっといい方法があるよ！」という方は、ぜひコメント欄に書いていただけるとありがたいです！
Pythonでパッケージをimportしたあと怒られる：'most likely due to a circular import'

（原因）importしようとしているパッケージ名と同じファイル名でpythonスクリプトを作成している。

（対策）次を確認すること：`import pyocr` しているスクリプトのファイル名が `pyocr.py` になっていないか？
→ YESならファイル名をパッケージ名とは異なるものに変える(ocrtest.py等）。同じ名前だと循環参照になってしまう。

エラーの例

```shell
Traceback (most recent call last):
  File "pyocr.py", line 6, in <module>
    import pyocr
  File "pyocr.py", line 8, in <module>
    tools = pyocr.get_available_tools()
AttributeError: partially initialized module 'pyocr' has no attribute 'get_available_tools' (most likely due to a circular import)
```
【UE4】Control Rig試し中④／ぷちコン15 進捗 - 2021/03/07

[1]:https://historia.co.jp/ue4petitcon15
[2]:https://pafuhana1213.hatenablog.com/entry/ControlRig-Inversion


[株式会社ヒストリアさん主催の第15回UE4ぷちコン][1]の作業進捗。
Control Rigの続き④。

# イマココ

【参考URL】[UE4.26で追加されたControlRigの反転機能(Inversion)の使いかたについて - ぼっちプログラマのメモ][2]

> 反転機能(Inversion)を最初「左右反転機能」かと思ってました。
> 実際は、ボーンのアニメーションをControl Rigのアニメーションに変換するもの。
> ある意味、Conversionと捉えてもよいかと。

上記参考URLに従って、既存のアニメーションシーケンスをControl Rigのアニメーションにベイクして、お好みな動きに編集するところまでやった。

![20210306_2340_AnimRun.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/2f1ccb52-dd38-2ca2-8373-f54f737c6818.gif)
右のマネキン男子の走りアニメーションを、左のマネキン女子にベイクして、Control Rigでエディットして女子っぽい動きに変更。
ちょっと動きが左側に偏っていることと、ちょっと腰振りすぎたことが気になっているが、正直、大変面倒くさかったので、もう弄る気はない。

少なくとも、あまり動作確認をできないまま、不安に思いながら組んでいた `Backward Solve` の動作確認はできた。

# やったこと

おおむね上記の[おかずさんのページ][2]に載っていることそのまんまです。
おかずさん、いつもありがとう！な気持ちでいっぱいです。

## 手順
１）Sequencerにスケルタルメッシュを投入する（今回はマネキン女子 SK_Mannequin_Female）

２）そのマネキン女子のアニメーショントラックに、アニメーションを追加する。
アニメーションを追加するには、Animationトラックの横の「＋」ボタンを押す。
もし、Animationトラックがないなら、SK_Mannequin_Female の横の「＋」ボタンを押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/171f6a8e-a950-dd6e-9c6f-2b296365b9b0.png)</dd>

３）【ハマりポイント】ここでアニメーション再生をやってみて「あれ？動かないじゃん！」と思って焦る。
アニメーションが動かないのは、すでにControl Rigのトラックが存在するのが原因。おそらく、アニメーションの計算後、Control Rigの計算をやるのだろう。
つまり、アニメーションが何であれ、Control Rigのポーズになるということ。

４）なので、Control Rigのトラックを消す。これで、正しく再生できるはず。

５）あとは、[おかずさんのページ][2]の通りに、SK_Mannequin_Female のトラックを右クリックして「Bake To Control Rig」を実行。
そうすると、Animationトラックがグレイアウトされ、キーが打たれたControl Rigのトラックが追加される。
（何なら、Animationトラックを消してしまっても大丈夫）

６）Control Rigを使ってアニメーションを編集する。今回は自分なりに女子っぽくしてみた。
超ハマった（後述）

７）SK_Mannequin_Female の右クリックから「Bake Animation Sequence」を実行すると、アニメーションシーケンスアセットが生成できる。

## Sequencer でのアニメーション編集でハマった集

- ベイク機能は便利だが、大量のアニメーションキーが打たれてて、途方に暮れる。
    - Bake To Control Rig 機能で「Tolerance (許容誤差)」が指定できるが、この値を調整するのも手間。
        - なぜなら、このTolerance値では、spine のカーブにはちょうどいいキーの数になるが、foot にとっては妙に多すぎる、みたいな現象が起きるから。
        - 「帯に短し、たすきに長し」
    - ひたすら、消しても構わないキーを消して回る作業が発生。
    - これはもう仕方がない。DCC ツールでもそんなもん。（事実上、根性が必要）
- 足のIKのリグをいわゆる Reverse Foot の形で組んだが、それをええ感じに汲み取ってベイクしてくれるわけではない。
    - 大雑把にいえば、足のTranslationとRotationを別のリグに分けて担当させていたのだが、ベイク側はそんなことは知らないので、片方のリグにひたすらTranslationとRotationの両方が焼き込まれた。
    - これをひたすら組み替えるのがものすごく骨だった。
    - 似た感じで、ボーンでいうpelvisとspine_01を、リグではpelvisとspineとcenterの３つに分けていたが、pelvisリグとcenterリグに似て非なるキーが打たれるという憂き目にあった。
    - 【自分TODO】Backward Solve をええ感じに組めば、なんとかなるかもしれない。
- ループアニメーション特有の「０フレーム目のポーズと、最終フレームのポーズを合わせる」作業がしんどい
    - しばらく試行錯誤した後、Sequencerのあのキーのリストが、DCCツールの「Dope Sheet」に見えてきてからは、楽になった。（ただ単にSequencerに慣れてないだけか…）
- カーブを編集して、Ctrl+ZでUNDOすると選択が外れてしまいカーブが消える（見えなくなるだけ）。カーブを選択しなおすのが手間。（あと、正しくUNDOできたがどうかが不安になる）
- 右足の数値と左足の数値を見比べながら作業したいが、どうしたらいいのだろう？
    - ひとまず、スクショと手書きメモで対応。

【感想】

- ベイク結果はいっそ参考値として、１から手で組んだ方が早い説
- １から手で組むと、気は楽だが、実は膨大な時間がかかる説

…悩ましい。
 
> 「Sequencer のアニメーション編集機能が使えない」という意味ではない。
> 使いやすさでは DCC ツールに劣るかもしれないが、ちゃんと実用には耐える。
> 少なくとも、このためだけに DCC ツールを買うかどうかとか迷うほどではない。
> <b>UE4と根性</b>さえあれば、有料・無料で入手したアニメーションを、自分好みの／状況に即したものにカスタマイズできるのは間違いない。
[Swift][CAGradientLayer]グラデーションに使用する色をUIColorのプロパティに設定する

# 環境
 Xcode12.0/Swift5

# 実装

```swift:ViewController.swift
import UIKit

extension UIColor {
    // グラデーションの開始色
    static let gradationStartColor = #colorLiteral(red: 1, green: 0.07205364853, blue: 0.1780711412, alpha: 1)
    // グラデーションの終了色
    static let gradationEndColor = #colorLiteral(red: 0, green: 0.4784313725, blue: 1, alpha: 1)
}

class ViewController: UIViewController {

    @IBOutlet private weak var GradationView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = [UIColor.gradationStartColor.cgColor, UIColor.gradationEndColor.cgColor]
        //グラデーションレイヤーをViewに合わせる
        gradientLayer.frame = GradationView.bounds
        //グラデーションレイヤーをビューの一番下に配置
        GradationView.layer.insertSublayer(gradientLayer, at: 0)
    }
}

```

`Main.storyboard`

![スクリーンショット 2021-03-07 15.12.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595260/53a454b3-e494-b4d1-77c7-c7515c2a8e24.png)

`実行結果`

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595260/f4afb121-4f22-1e1c-5cc8-26ef32576b4d.png">


- (大規模な画面だと、AutoLayoutで設定したviewにグラデーションを設定する場合、プロパティにしないと上手くいかないことがある。)

# 参考
- https://qiita.com/kikumas/items/ac737fb3305da3389bf9
- https://medium.com/@bj1024/swift-cagradientlayer-direct-c09e5e370f69
- [Apple公式のドキュメント](https://developer.apple.com/documentation/quartzcore/cagradientlayer)を見ると、UIColorのプロパティで設定していた
ksnctf #2 Easy Cipher

#Easy Cipher
Easy Cipher：簡単な暗号

簡単な暗号を解く問題。[シーザー暗号](http://www.iwakuni-h.ysn21.jp/teachers/yamashita/h30site/site26/f2605/h2605.html)になっていてこれを復号してflagを手に入れる。
シーザー暗号は文字をずらして暗号化する技術で、例えばappleを前に3文字ずらすとdssohになる。
問題では以下のテキストのみ与えられる。

```
EBG KVVV vf n fvzcyr yrggre fhofgvghgvba pvcure gung ercynprf n yrggre jvgu gur yrggre KVVV yrggref nsgre vg va gur nycunorg. EBG KVVV vf na rknzcyr bs gur Pnrfne pvcure, qrirybcrq va napvrag Ebzr. Synt vf SYNTFjmtkOWFNZdjkkNH. Vafreg na haqrefpber vzzrqvngryl nsgre SYNT.
```
空白、コンマ、ピリオド等から英文のように見えるからシーザー暗号だと思った。

復号してみる。今回はとりあえず後ろに13文字ずらしてみた。13文字の理由は問題文の4単語目の「n」は「a」を暗号化したものだと思ったから。英文でaってよく使われるよね。I hane a pen、This is a carとか。
 [ASCIIコード表](http://www3.nit.ac.jp/~tamura/ex2/ascii.html)でみてみるとa=97,n=110で13の差があるのがわかるから後ろに13文字ずらしてみる

###python
```python

text = "EBG KVVV vf n fvzcyr yrggre fhofgvghgvba pvcure gung ercynprf n yrggre jvgu gur yrggre KVVV yrggref nsgre vg va gur nycunorg. EBG KVVV vf na rknzcyr bs gur Pnrfne pvcure, qrirybcrq va napvrag Ebzr. Synt vf SYNTFjmtkOWFNZdjkkNH. Vafreg na haqrefpber vzzrqvngryl nsgre SYNT."
ans = ""
st = ""
for char in text:
    if(32==ord(char) or 44==ord(char) or 46==ord(char)):
        ans += char

    if(65 <= ord(char) <= 90):
        if(ord(char) <= 77):
            st = chr(ord("Z") - (13 - (ord(char) - (ord("A") - 1) )))
        else:
            st = chr(ord(char) - 13)
        ans += st
        
    if(97 <= ord(char) <= 122):
        if(ord(char) <= 109):
            st = chr(ord("z") - (13 - (ord(char) - (ord("a") - 1) )))
        else:
            st = chr(ord(char) - 13)
        ans += st
print(ans)
```

空白、コンマ、ピリオドは変換しない。A~Z,a~zを後ろに13文字ずらす。
ASCIIコード表でaを単純に後ろに13ずらすとTになちゃうから、そのあたりを気をつけながら。

```
ROT XIII is a simple letter substitution cipher that replaces a letter with the letter XIII letters after it in the alphabet. ROT XIII is an example of the Caesar cipher, developed in ancient Rome. Flag is FLAG_xxxxxxxxxxxxxxxxxx. Insert an underscore immediately after FLAG.
```


##まとめ
古代ローマで開発された、ROT XIIっていうシーザー暗号の一種の暗号らしい。
もっと綺麗なプログラムが書けるようになり。
Rails のRouterについて

Routerについて個人的にまとめます。
＊訂正などありましたらぜひよろしくお願いします。

#Router

まず書かれているファイルは
`config/routes.rb`

＊ここではmessageとしています。

```


Rails.application.routes.draw do
  # CRUD
  get 'messages/:id', to: 'messages#show'
  post 'messages', to: 'messages#create'
  put 'messages/:id', to: 'messages#update'
  delete 'messages/:id', to: 'messages#destroy'

  # index: show の補助ページ
  get 'messages', to: 'messages#index'

  # new: 新規作成用のフォームページ
  get 'messages/new', to: 'messages#new'

  # edit: 更新用のフォームページ
  get 'messages/:id/edit', to: 'messages#edit'
end
```
これらを簡単に記述したのが、↓
`  root to: 'messages#index'`はトップページにアクセスする時の記述
`resources :messages, except: [:index]`と`expect:`を使うことで指定したアクションを外すことができる。

`resources :コントローラー名`

```
Rails.application.routes.draw do
  root to: 'messages#index'　

  resources :messages
end
```
`(index, show, new, create, edit, update, destroy)`これらを`RESETful`なルーティングと言う。

# Router の確認

```
rails roues


   Prefix Verb   URI Pattern                  Controller#Action
        root GET    /                            messages#index
    messages GET    /messages(.:format)          messages#index
             POST   /messages(.:format)          messages#create
 new_message GET    /messages/new(.:format)      messages#new
edit_message GET    /messages/:id/edit(.:format) messages#edit
     message GET    /messages/:id(.:format)      messages#show
             PATCH  /messages/:id(.:format)      messages#update
             PUT    /messages/:id(.:format)      messages#update
             DELETE /messages/:id(.:format)      messages#destroy
```
docker  for RaspberryPi にwiresharkを導入する

## RaspberryPiにdockerでwiresharkを入れてみた

はじめに、以下のコマンドを入力して、dockerを導入します。
`snap install docker`
次に、


あとは、dockerの[wireshark][wd]に記載されている通りにことを進めていく。

```shell
mkdir ws
cd ws
touch docker-compose.yml
vi docker-compose.yml
```

!!注意!!
記載されている通りに進めていると...`network_mode`の部分で、 
`network_mode: host`と記載されていることによりエラーが発生する事がある。
そこで、`docker network ls`で、ネットワーク関連を調べる。
今回自分の場合は、`docker network inspect bridge`で、
dockerのネットワークが管理されていたので、`host`ではなく`bridge`に変更した。
dockerのネットワーク構成によってもコンテナが作成されないので、注意が必要だ。
`docker network ls` =>で確認。

```yml:docker-compose.yml
version: "2.1"
services:
  wireshark:
    image: ghcr.io/linuxserver/wireshark
    container_name: wireshark
    cap_add:
      - NET_ADMIN
    network_mode: bridge
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Tokyo
    volumes:
      - /root/ws/config:/config
    ports:
      - 3000:3000 #optional
    restart: unless-stopped
```

最後に、下記のコマンドを実行してコンテナを作成し、起動します。

```shell
docker-compose up -d
```
あとは、`http://{ラズパイのIPアドレス}:3000/`にブラウザーで接続すれば、起動の確認ができる。


以上、現場からでした。

[wd]:https://hub.docker.com/r/linuxserver/wireshark
疾患ゲノム解析の備忘録

##初めに
仕事として、遺伝子系のプログラムを手伝うこととなり、初めてのことが多くて困惑しています(´;ω;｀)
ということで、学んでいったことを忘れる前にどっかに書こうと思って、この記事を書いてみました。

あくまで備忘録なんで、図とかコード追加するかは不明だけど、何とかわかりやすく書ければなと。

ここでは疾患ゲノム解析についての大まかな内容と、きっとこういうことだろうという自分なりの解釈を書いています。
もちろん専門家でも何でもないんで、ぜひ間違っていたら教えてほしいです!!

というわけで、まずは全体像から!!
##ワークフロー
この章ではこの作業でやりたいことと、全体の手順について述べる。
疾患ゲノム解析とは、一般的な遺伝子との違いを確かめることで、遺伝子由来の疾患を探すというものである。

「えっ？」って言いたくなる人もいると思う。
簡単に言うと…　(言える自信はないが…)

A君「病気って、遺伝子情報のせいで起こることもあるらしいよね。」
A君「遺伝子情報から糖尿病になりやすいとか、目が悪くなりやすいとかいろいろ分かればいいのに!」

B君「じゃあ、糖尿病の人とそうじゃない人の遺伝子情報を比較して、違いを見ればわかるんじゃない??」

A君「いやでも、その遺伝子情報が本当に糖尿病の違いを表してるかわからないじゃない。」
A君「違いが10個見つかったとして、全てが糖尿病を引き起こすものとは言えないし…」

B君「じゃあ、大量に人の遺伝子情報を手に入れて、遺伝子のテンプレを作ろう!」
B君「そのテンプレと比較したら、少なくとも他の人と自分でどんな遺伝子の違いがあるのか分かるだろ」

A君「違いが分かったって、同じことだろ?」
A君「結局その違いがなんの病気を引き起こすかは分からないじゃないか」

B君「うーん」
B君「でも、その違いを大量に集めて、傾向をつかむってのはできるんじゃない??」
B君「この遺伝子が違うと、こういう症状になりやすいとかぐらいは分かるんじゃない??」

お分かりいただけただろうか???
多分わからないと思うが、要は…

- 左に一般的なの遺伝子を、右に被験者の遺伝子を置いて、間違い探しをする。
- 見つかった間違いから、遺伝子による疾患の傾向をつかむ。

ということだ。

今回はそれを様々なツールの紹介とともに行っていく。

##シーケンスデータ
まず、被験者のデータを持ってくるとこから解析が始まる。
とは言っても、遺伝子の情報を一本丸ごと持ってこれるわけではないらしい。
すなわち、断片的な遺伝子情報を大量に持ってくることしかできないということだ。

間違い探しの例に直すと、被験者の絵が1枚絵ではなく小さな絵が大量にあるイメージ。

ここでTrimmomaticというツールを使う。
このツールは、バラバラの遺伝子情報に対して解析しやすいように加工するためのツールらしい。
(場合によってはやらなくてもよいらしいが、それについてはよくわかってないです…泣)

##リファレンスゲノムデータ
次に、遺伝子情報のテンプレが必要になる。
間違い探しでいうと、もう片方の絵というイメージかな。

ここでは、このデータをリファレンスゲノムデータと呼ぶ。
##マッピング
ここで解析するデータを1つ1つ見ていくこととなる。
まず、リファレンスゲノムデータの中で一番近いと思われる場所を探していく。

間違い探しの例でいうと、この小さな絵はここらへんじゃないかな??
と、テンプレの絵を見ながら、小さな絵が当てはまりそうな場所を探していくイメージ。
これにより、被験者側の小さな絵を1枚1枚置いてって、1枚絵を作成していく。

この作業はBWAというツールを使って、被験者の遺伝子をマッピングしていく。

その後、PicardやSamtoolsというツールを使って、データを解析しやすくなるよう加工をする。
例えば、index付の作業では、遺伝子の番地を作成する。

間違い探しの例でいうと、絵を格子状にブロック分けして、
間違いはAの2番にあります!!
ってな感じで、ほかの人に伝えやすくする作業といえばいいのかな??
##データとの差異を見る
マッピングしたデータから、遺伝子の欠損や挿入を探す。
先ほどの過程でリファレンスゲノムデータに、シーケンスデータをマッピングした。
これにより、リファレンスゲノムデータとの差異が発見しやすくなっている。

間違い探しの例でいうと、ここでやっと2枚の絵が完成したので、間違い探しを行おうというわけだ。
この間違い探しを行うことで、一般の人と被験者のデータの差異を見つけることになる。

ここでGATK(Genome Analysis Toolkit)を使うことで検出を行う。

##意味づけ
前章でGATKを使って、遺伝子の間違い探しを行った。
もちろんこれで終わりではなく、その違いがどのような変化を及ぼすかを知りたくなる。
そこで、これまでの研究で分かったデータと照らし合わせて、
その遺伝子の違いによってどんな病気や障害が発生するかを調べる必要がある。

間違い探しの例でいうと、やっと間違い探しが終わったので、
この間違いがどんな意味があるのかなと、調べてみる感じ。

…いや、間違い探しでこの過程は見たことないけど( ´∀｀ )

ここで使うのがAnnvorである。

##感想
正直、まだまだ始めたばっかりで、分からないことが多いっす…。
そもそも遺伝子についても中学や高校でやったはずだけど、ほとんど覚えてない…。

けど、雇ってもらった以上迷惑はかけたくないので、頑張りたいと思います。

また色々分かったことがあれば備忘録としてQiitaに書いていこうかな～
(でも書くの大変だから、次はいつになるかなあ…なんて笑)

もし「ここが違うよ!」とか、
「こんなツールがあるよ!」などあれば、気軽にコメントいただけるとありがたい。

WCLとか使ってプログラムを書かせていただいているので、
その辺についてもいろいろ備忘録として書ければなあ…と思います。
##参考文献
(2015)清水厚志、坊農秀雅．『細胞工学別冊　次世代シークエンサーDRY解析教本』．株式会社学研メディカル秀潤社．p142~193．
EBSスナップショットを定期実行する方法

# はじめに

本記事では、EBSスナップショットを定期実行する方法をご紹介します。
この記事の内容を実装することで、

- EBSスナップショットを手動で行う必要がなくなる
- EBS内のデータのバックアップ（スナップショット）を取れる

# EC2バックアップの種類

EC2のバックアップ方法には、2種類あります。

|　サービス　| バックアップ対象 | スケジュール |
|---|---|---|
| EBSスナップショット | EBSスナップショット | 〇 |
| AWS Backup | 構成情報＋EBSスナップショット | 〇 |

# EBSスナップショット定期実行実装

[サービス]👉[EC2]👉[ライフサイクルマネジャー]👉ライフサイクルポリシーを作成をクリック

https://console.aws.amazon.com/backup/home

![スクリーンショット 2021-03-07 13.49.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538355/b034f2dd-f297-b6e3-f3cc-36bb33c4cc72.png)


ライフサイクルポリシーを作成

```
ポリシータイプ：EBS スナップショットポリシー
リソースタイプを選択：ボリューム
これらのタグを持つターゲット：スナップショットを取得したいEC2のタグを指定
説明：num 👈　わかりやすい説明を設定
IAM ロール：デフォルト
スケジュール名：num 👈　任意の名前を設定
頻度：毎日
毎:１時間
開始時刻：09:00　👈　UTCで設定する必要があります。日本時刻とUTCとの時差は、9時間です。
保持タイプ：カウント
保持する：５　👈　最大で5つを保持し、古いものから削除していきます。
作成後のポリシーのステータス：ポリシーを有効にする
```

これで完成、これにより、毎日一定の時間にスナップショットを取得してくれます！

# EC2スナップショットの復元手順

[サービス]👉[EC2]👉[インスタンス]👉インスタンス選択👉ストレージタブ
ルートデバイス名をメモ　＿φ(￣ー￣ )

![スクリーンショット 2021-03-07 14.14.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538355/aa7d6591-b0aa-2d17-c94a-df388144fbdf.png)

インスタンスの状況👉インスタンス停止

![スクリーンショット 2021-03-07 14.16.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538355/c0b417be-fe0b-a452-f1b6-261b44fcfb70.png)

[EC2]👉[スナップショット]👉復元したいスナップショットを選択👉アクション👉ボリューム作成

スナップショットの作成

```
ボリュームタイプ：汎用 SSD (gp2)
サイズ(GiB)：８
アベイラビリティーゾーン：ap-northeast-1a
```

[EC2]👉[ボリューム]👉現在EC2にアタッチ中のボリュームを選択👉アクション👉ボリュームのデタッチ

![スクリーンショット 2021-03-07 14.27.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538355/b94b4f7f-a819-773f-e963-773330c5249a.png)

[EC2]👉[ボリューム]👉先ほど作成したボリュームを選択👉アクション👉ボリュームのアタッチ

![スクリーンショット 2021-03-07 14.28.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538355/8a8e1271-0def-33c2-9e99-e1db09983978.png)

ボリュームのアタッチ

```
インスタンス：アタッチしたいEC2を選択
デバイス：先ほどメモしたデバイス名を指定
```

[EC2]👉[インスタンス]👉インスタンス選択👉インスタンスの状況👉インスタンス開始

![スクリーンショット 2021-03-07 14.30.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538355/026ce635-65ba-855d-709a-b1a8059a9fdc.png)

これでスナップショットの内容を反映することができました！♪(´ε｀ )
Compose for Desktopを触ってみた

#やったこと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309466/53b6588f-46be-6b15-b102-bb9eddf7b266.png)

JetBrains社が出しているCompose for Desktop
KotlinでAndroid/デスクトップアプリ両方作れるという技術を学習してみた。
※実装に当たりAPIの仕様などは本家側の資料を翻訳しながら理解。
https://developer.android.com/jetpack/androidx/releases/compose-ui?hl=ja

コードの雰囲気
あれこれ色々やろうと思うとswingとかの知識があった方が良いのかも

``` main.kt
package code.viewer

import androidx.compose.desktop.Window
import androidx.compose.ui.unit.IntSize
import code.viewer.ui.MainView
import java.awt.image.BufferedImage
import javax.imageio.ImageIO
import javax.swing.SwingUtilities.invokeLater


// 起点になるポイント
fun main() {

    //イベントディスパッチスレッド以外のスレッドからGUIの描画処理を行う場合
    //javax.swing:invokeLater() メソッドを使用
    invokeLater {
        // 指定されたコンテンツでウィンドウを開きます。
        Window(
            title = "Clone Code Viewer",
            size = IntSize(1280, 768),
            icon = loadImageResource("ic_launcher.png")
        ) {
            MainView()
        }
    }
}

private fun loadImageResource(path: String): BufferedImage {
    val resource = Thread.currentThread().contextClassLoader.getResource(path)
    requireNotNull(resource) { "Resource $path not found" }
    return resource.openStream().use(ImageIO::read)
}
```

画面コンポーネントは@Composableのアノテーションを付けた関数で作成する

```MainView.kt
// UIコンポーネントはfun形式で返却値はUnit
// @Composableのアノテーションが必ず必要
@Composable
fun MainView() {

    // remember:状態管理を行うための関数、
    // 内部の値は初回の表示時に保存され再描画の際も返される
    val codeViewer = remember {
        val editors = Editors()

        CodeViewer(
            editors = editors,
            fileTree = FileTree(HomeFolder, editors),
            settings = Settings()
        )
    }

    // テキスト選択無効
    DisableSelection {
        MaterialTheme(
            colors = AppTheme.colors.material
        ) {
            PlatformTheme {
                /**
                 * Surface:マテリアルデザインの中心的なコンポーネント
                 * content: @Composable()の内容をマテリアルデザインのルールにのっとって描画する役割を持つ
                 */
                Surface {
                    CodeViewerView(codeViewer)
                }
            }
        }
    }
}
```





#そんなこんなで出来た成果物
[CloneCodeViewer](https://github.com/TakuyaShirosaka/CloneCodeViewer)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309466/6f83d1dd-29d4-8064-5f62-cd38908ea37c.png)

公式にあったCodeViewerアプリを写経した結果の物、
Andorid側の実装はいらないなと思ったのでマルチプラットフォームではない形で実装しています。

デスクトップアプリはほぼやったことがなかったのですが、
これはかなり設計が丁寧にできていると感じました。


何かメモ帳アプリもできました。
[MemoApp](https://github.com/TakuyaShirosaka/MemoApp)

本来は前述のCodeViewerをエディターに改造しようかと思ったのですが失敗
というわけでメモ帳から始めてみようと思って作ったアプリ

#余談
Flutter2.0が出ましたね。
正直Flutterの方が強いです。。。ぐぎゃー
EXCELで使える関数のスニペット（基本編）

# はじめに
EXCELを使ってて頻繁に使う関数の記述を備忘録として記載。

# 本編
## 形式を揃えるための処理
### 数値に変換する
```
=VALEU(B1)
```
A1の内容をVALUE()関数で処理する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/40c91178-d22a-f043-01e0-0c76d1979fa6.png)
A1の文字列が数字になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/dba80251-462e-8a74-efbc-8253f951f8b6.png)

どのような時に使うか？

- CSVから取り込んだ社員IDが「012345」となったり「12345」となったりする場合があって揃えたい。<br>
EXCELで「012345」=「12345」はFALSEです。「12345」=[12345」になるように整えます。


## 位置を取得するための処理
### 行番号の取得
```
=ROW()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/f65ac863-33e4-8f50-2bf7-8e379c3f40fc.png)


### 列番号の取得
```
=COLUMN()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/3c23c1e7-d742-62ac-d8a1-2fac84c1282a.png)



### アドレスの取得
```
=ADDRESS(ROW(), COLUMN())
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/b705a959-c9df-4459-8afe-cdc36871fb48.png)


### 列名（英語表記）の取得
```
=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(ADDRESS(ROW(),COLUMN(),4,1),"$",""),"0",""),"1",""),"2",""),"3",""),"4",""),"5",""),"6",""),"7",""),"8",""),"9","")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/7f1f1923-b917-4e68-1267-13eb1e6ff721.png)

解説：
ADDRESS()で取得した\$A\$1形式の文字列から$と数字を除くという処理をしています。
正規表現が使えればスマートな記述が可能なのですが、正規表現を使う方法が見当たらなかったため、SUBSTITUTE()を何度も使って文字列を置換して処理しています。
rails Model

初心者でrails の環境構築にかなり手こずってやっとスタート地点に立てたので簡単に備忘録としてまとめる。
#Model


・①

```
rails s
```
これだけだとエラーになるので、
・MySQLが起動しているか。

```
rails db:create
```
したかを確認。
↑で成功するまでにかなりの時間がかかった、、、
***


・②Modelのマイグレーションファイルの作成
※モデル名は必ず最初を大文字にして、単数形にすること。

```
rails g model　（モデル名）　(content:string　など)
```
作成されるファイル
・`db/migrate/年月日時_create_xxxxxx.rb`

・`app/models/xxxxxx.rb`

idカラムは自動で作成される
***

・③ ②をしただけだとデータベースに変更が反映されないので以下をする

```
rails db:migrate //マイグレーションの実行
rails db:migrate:status　//マイグレーションファイルが既にテーブルに反映されているか確認
rails db:drop //テーブルを一度削除（すべてのマイグレーションを無かったことに）する
rails db:migrate //再構築（あらためてマイグレーションを実行）する 
rails db:migrate:reset　＝　rails db:drop + rails db:migrate
```
`rails db:drop`,` rails  db: reset`
コマンドは、テーブルを削除するので、その時点までに保存されていたデータは全てなくなります。

#カラムを増やすマイグレーション

```
rails g migration Addカラム名Toテーブル名 カラム名:カラムのデータ型
```
その後しっかりと以下を忘れずにする

```
rails db:migrate
```

#カラムが増えたことによって発生する作業
以下参照


https://techacademy.jp/my/rails/rails5-2/message-board#chapter-11
windowsでiverilog その92

#概要　

windowsでiverilogやってみた。
ナップザック問題、やってみる。

#参考にしたページ

https://qiita.com/drken/items/68b8503ad4ffb469624c


#問題

|価値|容量|
|:--|:--|
|4|2|
|5|2|
|2|1|
|8|3|

容量のリミットは、８
最も、価値が大きくなった時の価値を答えよ。


#サンプルコード


```
module nap(input clk, input rst, output [7:0] out);
	reg [7:0] dp[0:10];
	reg [7:0] va[0:4];
	reg [7:0] wt[0:4];
	assign out = dp[8];
	integer i,
		j;
	always @(posedge clk or negedge rst)
	begin
		if (!rst)
		begin
			va[0] <= 4; wt[0] <= 2;
			va[1] <= 5; wt[1] <= 2;
			va[2] <= 2; wt[2] <= 1;
			va[3] <= 8; wt[3] <= 3;
			dp[0] <= 0;
			dp[1] <= 0;
			dp[2] <= 0;
			dp[3] <= 0;
			dp[4] <= 0;
			dp[5] <= 0;
			dp[6] <= 0;
			dp[7] <= 0;
			dp[8] <= 0;
			dp[9] <= 0;
		end
		else
		begin
			for (i = 0; i < 4; i = i + 1)
			begin
				for (j = 0; j <= 8; j = j + 1)
				begin
					if (j >= wt[i])
					begin
						if (dp[j] < (dp[j - wt[i]] + va[i]))
						begin
							dp[j] = dp[j - wt[i]] + va[i];
						end
					end
				end
			end
		end
	end
endmodule

module test();
	reg clk;
	reg rst;
	wire [7:0] out;
	nap u(.clk(clk), .rst(rst), .out(out));
	initial
	begin
		$monitor("%d", out);
		clk = 0;
		rst = 1;
		#1
			rst = 0;
		#1
			rst = 1;
		#10
			$finish;
	end
	always
	begin
		#5
			clk = 1;
		#5
			clk = 0;
	end
endmodule





```

以上。
図解 CSR, SSR, SSG, ISR

何周も遅れてしまっているのですが、フロントエンド周りの勉強に取り組んでいます。色々と遠回りをしつつ、Next.jsに流れ着きました。SSRとかSSGとか分かりにくい言葉が多くて難しそうに感じたので、自分なりの理解を図にしてみました。

## Server Side Application

![スライド1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9148/0adf1d05-72ee-a95d-aa70-9be381af436d.png)

サーバーはリクエストを受けると動的にHTML文書を生成して返却する。

1993年にCGIが登場した時から基本的に同じ仕組みであり、今でも主要なアーキテクチャです。

## Ajax

![スライド2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9148/c7d51904-b3cb-c808-249c-eaf8c9aee798.png)

クライアント（ブラウザ）側のJavaScriptでサーバーから追加データを取得し、DOM操作でページの内容を書き換える。

ページ遷移することなくコンテンツを書き換えることができる手法です。このアーキテクチャが登場してから、Webアプリケーションで実現できるUIや表現の幅が飛躍的に広がりました。

## CSR (Client Side Rendering)

![スライド3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9148/227559eb-7e22-7fb5-549d-18d52b94a66a.png)

Ajaxとの違いが分かりにくいですが、同じといえば同じです。特徴的なのは、最初に取得するHTMLがほぼ空で、ページ全体をJavaScriptで生成するという点です。ページ遷移することなくページ全体を書き換えることができるのでインタラクションが高速です。このように作られたアプリケーションをSPA（Single Page Application）といいます。

一方で初回アクセスでは大きなJavaScriptコードを読み込み、ページ全体を処理することになるので、初回ロードが重くなりがちです。

また、原始的なクローラではコンテンツを取得できない場合があるため、SEO的に不利です。

## SSR (Server Side Rendering)

![スライド4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9148/a63e6c47-631f-6d65-300a-7de8d1528c52.png)

CSRのデメリット（初回の重さやSEOの問題）を解決するため、リクエストに対して動的にHTML文書を返却するのがSSRです。

…あれ？それって1周回って従来のサーバーサイドアプリと同じじゃない？となりますが、はい実際同じですね。

特徴としてはCSRのクライアント側と同じ技術スタック（JavaScript、仮想DOMなど）をサーバーサイドでも利用するということです。Next.jsなどのフレームワークでは同じロジックをクライアントサイド、サーバーサイドと容易に使い分けることができるようになっています。

デメリットはやはりサーバーサイドの重さです。特にフロントの実装と同じ感覚でAPI通信などを利用すると、レスポンスに時間がかかります。

## SSG (Static Site Generating)

![スライド5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9148/a2bf6fb2-0cd9-c29f-bd10-56f28ff63d43.png)

SSRはレスポンスが遅いので、それを解決するため事前に静的なHTMLを生成しておこう。というのがSSGです。

…あれ？それって2周回って静的HTML？サイトジェネレーターやMovableTypeみたいなやつ？となるんですが、そうです。

これも特徴はCSRやSSRと同じ技術スタックが使われる点です。対応したフレームワークを利用すれば、1つのアプリケーションの中でCSR、SSR、SSGを適材適所で使い分けることが可能です。

SSGではビルド時にHTMLを生成するので、配信は非常に高速な一方、デプロイした後はページの内容を動的に変更することができません。

## ISR (Incremental Static Regeneration)

![スライド6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9148/c26aadfd-252f-8f16-19b1-f5e6bfe6c9cd.png)

SSGは速いけど内容を更新させられない。ISRはそれを解決する方法で、SSRとSSGのハイブリッドといえるものです。SSRもSSGも既視感のあるアーキテクチャでしたが、ISRはこれまで見たことのない仕組みです。

ISRではSSRのようにリクエストに応じてHTMLを生成するのですが、生成はバックグラウンドでやりつつ、すでに生成されている古いほうのHTMLを返却します。そのため、内容は少し古い代わりにSSGと同じレベルで高速にレスポンスされます。

## 最後に

ISRは非常に強いですが、最新のコンテンツを返すことはできないので、どの場面でも使える。というわけではありません。Next.jsを利用すれば、CSR, SSR, SSG, ISRを適材適所で容易に使い分けられる。というのがポイントだと思います。サーバ側もクライアント側もまとめて単一コードベースのモノリシックなアプリケーションとして開発を始めることができます。このような特徴は、特に1人開発でスモールスタートするような場合に初速度的な点で有利になりそうだと感じました。
AtCoder Beginner Contest 194

冷え冷えしました。

##[A - I Scream](https://atcoder.jp/contests/abc194/tasks/abc194_a)

O(1)
問題文が難しい。

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }
 
int main() {
    int a, b;
    cin >> a >> b;
 
    if(a+b >= 15 && b >= 8) cout << 1 << endl;
    else if(a+b >= 10 && b >= 3) cout << 2 << endl;
    else if(a+b >= 3) cout << 3 << endl;
    else cout << 4 << endl;
 
    return 0;
}
```

##[B - Job Assignment](https://atcoder.jp/contests/abc194/tasks/abc194_b)

O(N^2)
N<=1000なので全探索

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }
 
int main() {
    int n;
    cin >> n;
 
    vector<int> A(n), B(n);
    rep(i, n) cin >> A[i] >> B[i];
 
    int res = 1e9+7;
    for(int i=0; i<n; i++){
        for(int j=0; j<n; j++){
            if(i != j) res = min(res, max(A[i], B[j]));
            if(i == j) res = min(res, A[i]+B[j]);
        }
    }
    cout << res << endl;
 
    return 0;
}
```

##[C - Squared Error](https://atcoder.jp/contests/abc194/tasks/abc194_c)

O(N^2)
N<=200
組み合わせを使用しまとめて計算する問題です。

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int n;
    cin >> n;

    map<ll, ll> dist;
    rep(i, n){
        int a;
        cin >> a;
        dist[a]++;
    }

    ll res = 0; 
    for (pair<ll, ll> p2:dist){
        for(pair<ll, ll> p1:dist){
            if(p2.first<p1.first) continue;
            res += ((p2.first - p1.first) * (p2.first - p1.first)) * p2.second * p1.second;
        }
    }
    cout << res << endl;

    return 0;
}
```
ECS(Fargate)でLaravelの環境変数の設定方法

AWS ECSでLaravelのコンテナを動かす場合、DB接続情報などの環境変数を設定する方法を考えました。
結論から言うとFargateのタスク定義の環境変数に設定する方法が一番いいのでは？と考えました。

# 環境変数の設定方法

Laravelでは.envに環境変数を記述します。ECSで公開する場合、本番環境用の.evnファイルをDockerイメージに入れてビルドするという記事が多いように思います。
この方法だと少し面倒で.envファイルを2種類用意しなければなりません。
また、Volumesを使ってEFSなどを参照する方法もあるかと思いますがどちらにしろ.envファイルが2種類必要になります。

# 環境変数の参照方法

Laravelで環境変数を取得する場合`env()`関数を使用します。

```php:databese.php
        ...
        'mysql' => [
            'driver' => 'mysql',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST', '127.0.0.1'),
            ...
```

この`env()`関数ではOSの環境変数も取得することができます。
例のdatabase.phpのDB_HOSTが、もし.envに無くOSの環境変数にDB_HOSTがあればその値を参照します。

# ローカルのDockerで試してみる

1. .envファイルからDB_HOSTを削除します。
1. DockerのenvironmentでDB_HOSTを設定します。

```yaml:docker-compose
  php:
    container_name: myWork-php
    ...
    environment:
      DB_HOST: myWork-db
    ...

  db:
    image: mysql:5.7
    container_name: myWork-db
```

これでDockerを起動した場合、コンテナの環境変数にはDB_HOSTがセットされ、Laravelはそれを参照するようになります。

```bash
# env | grep DB_HOST
DB_HOST=myWork-db
```

# Fargateでも環境変数を設定できる

ECSのタスク定義はdockerと同じことができるので、コンテナの環境変数をセットすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29324/2cc4d3ab-8709-0e8d-a34a-953acdb26496.png)

環境変数はSSMのパラメータリストから取得することができるので、よりセキュアで疎結合な設定が可能です。

# まとめ

以上によりローカルの開発環境の.envファイルをそのまま本番環境でも使用できるようになります。
獣医師が必死にバイオインフォマティクスPythonによる実践レシピをwin10で動かす（その4）

# 仮想環境の自動実行
その4とか言っているけど番外編な気がする
## Anaconda3のPATHを通す
最初にインストールする際にやっていた人は必要なし
コマンドプロンプトから`Jupyter notebook`って打って開けばOK
ダメな人は以下へ↓
コントロールパネル＞システム＞システムの詳細設定＞詳細設定＞環境変数＞システムの環境変数
pathに以下を追加

```
C:\Users\今アクセスしているアカウントの人\anaconda3
C:\Users\今アクセスしているアカウントの人\anaconda3\Scripts
```

追加するパスがわからない人は
Windowsスタートメニュー＞Anaconda3（64bit）＞Jupyter Notebook (anaconda3)を右クリック
その他＞ファイルの場所をクリックして出てきたJupyter Notebook (anaconda3)のプロパティからリンク先を見るとanaconda3の場所が書いてあるので、上記のanaconda3より前のアドレスをそれに直す。
そうしたらコマンドプロンプトから

```
Jupyter notebook
```

怒られた。
`distutils_patch.py:25: UserWarning: Distutils was imported before Setuptools. This usage is discouraged and may exhibit undesirable behaviors or errors. Please use Setuptools' objects directly or at least import Setuptools first.`

更にpathを追加していく

```
C:\Users\今アクセスしているアカウントの人\anaconda3\Library\share\zmq
C:\Users\今アクセスしているアカウントの人\anaconda3\Library\bin
```

まだ駄目なので
Windows:「スタート」>「すべてのプログラム」>「Anaconda3 (64-bit)」>「Anaconda Prompt」から実行

```
pip uninstall pyzmq
pip install pyzmq
```

再度コマンドプロンプトから

```
Jupyter notebook
```

無事に起動
ここまでやったけど、Anaconda3の再インストールをして、pathを通す設定にした方が楽な気がする

ここから自動的に動かしたいのでバッチファイルを作成
とは言えやっているのは単にテキストで下のコマンド書いて、保存後に拡張子を`.bat`に変えただけ

```bat:Auto_Jupyter_notebook.bat
@echo off
call activate bioinfomatics
cd C:\Users\Anaconda3が置いてある場所
jupyter notebook
```

クリックして動くことを確認
コンソールが動くと邪魔で、バックグラウンド処理で実施したいのでvbsファイルを作成
これもテキストで下のコマンド書いて、保存後に拡張子を`.vbs`に変えただけ

```vbs:Jupyter_notebok_Bg_run.vbs
Set ws = CreateObject("Wscript.Shell")
ws.run "cmd /c Auto_Jupyter_notebook.bat", vbhide

```

作成したvbsファイルのショートカットを作成し、プロパティからリンク先と作業フォルダの情報を取得
更に楽をするために「スタート」>「Windowsシステムツール」>「コマンドプロンプト」を右クリックしてタスクバーにピン止め
タスクバーのコマンドプロンプトを右クリックして、更にコマンドプロンプトを選んで右クリックしてプロパティを動かす
ここでリンク先と作業フォルダをvbsファイルの物と同一にする

ほら、これで楽に動くでしょ？
FT-857D CAT-USB変換ケーブルの製作

# はじめに
　先ごろ打ち上げられた超小型人工衛星 WARP-01 や RSP-01 から発信されるテレメトリを受信すべく、既存衛星のテレメトリ受信を試している。衛星からの電波はドップラー効果のたため受信周波数が変化していく。手で周波数の変化に追随さえていくのは面倒である。アマチュア無線の衛星通信用ソフト[CALSAT32](http://jr1huo.my.coocan.jp/jr1huo_calsat32/index.html)を使えば、衛星の動きに合わせてPCからトランシーバーの受信周波数を合わせてくれる。手持ちのトランシーバー YAESU FT-857DM にはCATインターフェイスがあり、そのIFとPCとケーブルでつなげばよい。
　純正オプションの[ＣＡＴインターフェイスケーブル CT-62](http://www.yaesu.com/jp/amateur_index/product/ft857/option.html) は、トランシーバーのCATインターフェイスとD-SUB 9ピン端子を接続するケーブルで、標準価格3,500円（税抜）でちょっとお高い。1,000円強の同等品もあるが通販で届くまで時間がかかりそうなので、自作することにした。

# レベル変換は面倒だぞ
　変換ケーブルの一方はD-SUBなので、RS-232C規格なのだが、トランシーバー側のTX D/RX DはTTLレベルで、ケーブルでレベル変換に対応してやらないといけない。自作した人の情報を見てもレベル変換ICを入れている。
　PCに接続するには、D-SUB（9ピン）-USB変換ケーブルが必要だし、受信しかしないのだから、TX D/RX D/GNDをUSB-シリアル変換アダプタにつないでやればいいと気づいてやってみた。

# 材料
* Macintosh RS-232Cケーブル
    * iMac登場前のMacintoshのシリアルポートがミニDIN 8ピンだったので、昔使っていたRS-232Cケーブルを引っ張りだしてきた。~~PCのPS2 キーボード、マウスもミニDIN 8ピンなので、そのケーブルを流用してもよい。~~（PS/2はミニDIN 6ピンでした）
* 秋月電子通商 [FT234X 超小型ＵＳＢシリアル変換モジュール
AE-FT234X](https://akizukidenshi.com/catalog/g/gM-08461/)
    * 何度も使っているので信頼している変換モジュールである。
![20210306_100851079_iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/6da74c18-678c-e86d-2ebb-392ece1485a8.jpeg)

# 配線
1. RS-232Cケーブルを途中で切断し、ピンと芯線の対応関係をテスターで確認
1. 図のように配線
![FT-857D_CAT.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/e0940821-399f-1dd0-c296-babac28681fe.png)
![20210306_140949893_iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/78f5384c-fa57-b1b1-6c61-7eda666b3b52.jpeg)
1. トランシーバーに差し込んでみるとプラグの角ばった部分が引っかかりしっかり差し込めないので、でっぱりを削った
![20210306_141606088_iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/4ad125f4-fa45-62e8-7df4-396cfd4882a8.jpeg)

# CALSAT32の設定
1. コントロール(R) ＞ トランシーバ(T) で FT847を選択
![CALSAT32_トランシーバ設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/5e460703-4b83-da67-771a-9847e678df30.png)
1. FT847コントロールパネル シリアルポート設定
    * ポート番号：USBシリアル変換アダプタのCOMポート番号を選択
    * スピード：FT-857DMのデフォルトが4800baudなので、4800に設定
![CALSAT32_FT847コントロールパネル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/7a0df20b-abe1-111a-4f77-2122856f6c18.png)

# 試運転
　FT847コントロールパネルの「COM」、「CAT」をクリックすると、FT-857DMの周波数がビーコン周波数に切り替わり、VFOダイヤルを回しても周波数が変化しなくなった。
　ちょうど、CAS-4A衛星が近づいてきていたので、CWテレメトリを受信してみた。
<iframe width="560" height="315" src="https://www.youtube.com/embed/ZxfKVxai92c" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
　FT-857DのCATとコマンドはFT-847とほぼ同じだが、FT-857Dはサテライトモードに対応していないので、FT847コントロールパネルの「SAT」をクリックしても変化がなかった。
# 仕上げ
　動くことがわかったので、USBシリアル変換アダプタとケーブルをしっかり固定した。自分しか使わないので、これくらいで十分でしょう。
![20210306_141628997_iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112480/97ac79df-a118-ef2e-bb8e-0dc44207c77d.jpeg)
STM32を使おう　Resetピンが無いSTM32と通信する方法～SoftwareReset～

STM32への書き込み方法として、主に、JTAGとしてST-Linkや、UARTによる接続があります。
ST-Linkとの接続にはResetピンが必須ではありませんし、一部のハードウェアにはついていません。
このため、リセットに入ることができず、STM32と通信できない事があります。
これは、初期設定が、HardwareResetになっているために通信出来ないのです。
今回は、HardwareResetからSotwareResetへ変更してみましょう
##STM32 ST-LINK Utility
STM32 ST-LINK Utilityを起動します。
初期状態では、当然接続できません。
![HardwareReset.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/2476f01b-6c5a-72c8-9f92-42cfc534597a.jpeg)
##設定変更
Target⇒Settings
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/1336b3ae-8b0f-39e8-691c-f5528062561d.png)
Reset ModeをSotwareResetに設定します。
![SoftwareReset-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/6d54bd6f-74fe-8fc9-ee5a-33e94a162421.jpeg)
これで通信できるようになりました。
![SoftwareReset-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/c12d4608-72a1-b591-a6d9-1b7467334bea.jpeg)
##STM32CubeIDE
特に設定しないでも通信できました。
もし、通信出来ない場合は、以下を行うことで使えるようになると思います。
Run Configulation
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/155025df-2041-6a39-4ac3-61e6b9a9325a.png)
デバッガ⇒Reset Behaviorに設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/45581821-75fc-1228-043a-4208c3818e8e.png)
これでSTM32と通信できるようになると思います。
コードで確認するニューラルネットワーク・アルゴリズム

# はじめに

本記事は、下記コース受講の一環として、（併せて提供される「超AI入門講座」に含まれる動画および資料を）学習した内容について、理解を深めるため、かつ備忘として整理したものです。

[![JDLA](http://ai999.careers/bnr_jdla.png)](http://study-ai.com/jdla/)

コード自体は本記事単体のみにて完結したものとなるよう整理してありますが（ただし入力データは構造のみを記述）、事前の知見のない方へ向けての解説・説明とはなっていません。知識確認の参考としていただくか、必要に応じ上記コース等ほかの情報と併せてご活用ください。

## 前提
### 学習するデータとネットワークとの関係
- １レイヤー2次元配列（白黒画像）
- 縦横28(px)のデータを、`784`個の入力値として扱う
- 誤差の算出には二乗誤差を用いる
- 学習係数 $\eta$ は用いない


# 利用ライブラリ
```python
import numpy as np
```
# ネットワーク定義
## シグモイド関数
```python
def sigmoid(a):
    return 1 / (1 + np.exp(-a))
```

# 重みWの定義
```python
w1 = np.random.normal(0.0, 1.0, (10, 784))
w2 = np.random.normal(0.0, 1.0, (2, 10))
W = [w1, w2]
```
# バイアスBの定義
```python
b1 = np.ones((10, 1))
b2 = np.ones((2, 1))
B = [b1, b2]
```


# ネットワーク更新のための関数定義
## パラメータ更新式公式

### wの更新式

```math
w = w - \frac{\partial E}{\partial w} = w - \frac{\partial E}{\partial y} \frac{\partial y}{\partial a} \frac{\partial a}{\partial w}
```

### 誤差関数Eのbによる偏微分の公式
```math
\frac{\partial E}{\partial b_j^l} = g_j^l
```

### 誤差関数Eのwによる偏微分の公式

```math
\frac{\partial E}{\partial w_{kj}^l} = g_i^{l} x_k^{l}
```
### 更新式の公式g
#### 最終レイヤー



```math
g_j^l = (y_j - t_j)f'(a_j^l) 
```

#### 最終レイヤー以外

```math
g_j^l = \sum_{i=1}^{m} (g_i^{l+1} w_ji^{l+1})f'(a_j^l) 
```


## 活性化関数fの微分
```python
def f(a):
    return (1 - sigmoid(a)) * sigmoid(a)
```
## 更新式の公式gの実装
```python
def g(l, j):
    if max_layer == l:
        return (y[j] - t[j]) * f(A[l - 1][j])
    else:
        output = 0
        m = A[l].shape[0]
        for i in range(m):
            output += g(l + 1, i) * W[l][i, j] * f(A[l - 1][j])
        return output
```
## 誤差関数の微分
### パラメーターwによる微分
```python
def diff_w(j, k, l):
    return g(l, j) * X[l - 1][k]
```
### パラメーターbによる微分
```python
def diff_b(j, l):
    return g(l, j)
```


# データ

### 入力

１レイヤー2次元配列（白黒画像）

````inputs.npy`
[
 [
  [0.0 0.0 0.0 ... 0.0 ]
  ...
 ],
 ...
]
```

### 教師データ

２クラス分類

````true_values.npy`
[
 [
  [0],[1]
 ],
 ...
]
```


```python
xs = np.load('inputs.npy')[0:101]
ts = np.load('true_values.npy')[0:101]
```
# 実行



```python
for x, t in zip(xs, ts):
    # 入力層
    x1 = x.flatten().reshape(784, 1)
    # 中間層入力
    a1 = W[0].dot(x1) + b1

    # 中間層出力
    x2 = sigmoid(a1)
    # 出力層入力
    a2 = W[1].dot(x2) + b2

    # 出力値
    y = sigmoid(a2)
    # 正否（本格的な実装としては結果保存・学習終了判定が行われる部分）
    if np.argmax(y) == np.argmax(t):
        print("正解")
    else:
        print("不正解")

    # パラメーター更新に用いる変数
    X = [x1, x2]
    A = [a1, a2]

    # ネットワークのレイヤーサイズ
    max_layer = len(X)

    # パラメーターw, bの更新
    for l in range(len(X)):
        for j in range(W[l].shape[0]):
            for k in range(W[l].shape[1]):
                W[l][j, k] = W[l][j, k] - diff_w(j, k, l + 1)
            B[l][j] = B[l][j] - diff_b(j, l + 1)

np.save("w1.npy", W[0])
np.save("w2.npy", W[1])
np.save("b1.npy", B[0])
np.save("b2.npy", B[1])
```
Flutter2 にしたら RaisedButton が deprecated になっていたので ElevatedButton に置き換えた

# 概要
先日Flutter2がリリースされたので更新してみたら。
[RaisedButton](https://api.flutter.dev/flutter/material/RaisedButton-class.html) が deprecated(非推奨) となっていました。
[ElevatedButton](https://api.flutter.dev/flutter/material/ElevatedButton-class.html) に置き換わるようです。
(正確には `v2` からの更新ではなく `v1.25.0-8.1.pre` からの更新のようです。)

今回は、自分が実装していたボタンの一例を用いて置き換えについて例を示します。

# ボタンのイメージ
こんなボタンを作ってました。
![Screenshot_1615090197.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142886/4b000914-8d93-5ac5-2af2-d66a8ed05752.png)
# コードの変更
## 変更前 (RaisedButton)
```dart
RaisedButton.icon(
  icon: Icon(Icons.event_note),
  label: Text("いつまで"),
  shape: const RoundedRectangleBorder(
    borderRadius: BorderRadius.all(Radius.circular(10)),
  )
)
```

## 変更後 (ElevatedButton)

`RaisedButton` で、 `shape` を適用していたのですが、
`ElevatedButton` には `shape` 項目がないようです。
その代わり、 `style` でデザインを指定する形となっています。
また、デフォルト配色が変わっていたので、そちらの指定も追加しています。

```dart
ElevatedButton.icon(
  style: ElevatedButton.styleFrom(
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(10)),
    ),
    primary: Color.fromARGB(255, 224, 224, 224), // 背景色
    onPrimary: Color.fromARGB(255, 0, 0, 0) // 文字色
  ),
  icon: Icon(Icons.event_note),
  label: Text("いつまで")
)
```

### Styleを指定しなかった場合
Styleを指定しないデフォルトのデザインはこんな感じになってました。
![Screenshot_1615090162.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142886/8906e424-b91a-7d7d-bb2c-09f860fbf593.png)


```dart
ElevatedButton.icon(
   icon: Icon(Icons.event_note),
   label: Text("いつまで")
)
```

# 補足
自分のコードでは利用していなかったので、サンプルは示しませんが、
以下Widgetも変更があったようです。

|変更前|変更後|
|-|-|
|[FlatButton](https://api.flutter.dev/flutter/material/FlatButton-class.html)|[TextButton](https://api.flutter.dev/flutter/material/TextButton-class.html)|
|[OutlineButton](https://api.flutter.dev/flutter/material/OutlineButton-class.html)|[OutlinedButton](https://api.flutter.dev/flutter/material/OutlinedButton-class.html)|

マイグレーションについては、以下にGoogleドキュメントの資料がありましたので、
詳細な情報が必要な方はこちらを参照してみてください。

*Migrating to the New Material Buttons and their Themes*
https://docs.google.com/document/d/1yohSuYrvyya5V1hB6j9pJskavCdVq9sVeTqSoEPsWH0