OmniAICreator/Qiita-1.07M huggingface dataset:
FerenOSインストールメモ

# FerenOSインストールメモ
## はじめに

普段Ubuntuを使っていて、より良いLinuxを求めて調べていました。

比較的最近出てきて、使いやすそうなFerenOSに注目して、試してみました。



## 使いやすそうなポイント
 - 直感的なファイル操作
 - わかりやすいNotifications
 - [Steam](https://feren-os-user-guide.readthedocs.io/en/latest/steam.html)も使える


## 環境, 周辺機器
 - PC (Ubuntu)
 - PC (FerenOSインストール用)
 - USBメモリー
 - Wifi環境(有線ネットワークが提供されていない環境)の場合
     - スイッチングハブ
     - LANケーブル (2本)

## インストール用USB作成
 - [ISOをダウンロード](https://ferenos.weebly.com/get-feren-os.html)
 - [balenaEtcher](https://www.balena.io/etcher/)をダウンロード
 - [USBにISOを書き込む](https://feren-os-user-guide.readthedocs.io/en/latest/writetousb.html)


## インストール
今回はデュアルブートする設定で進めます。

 - PCのパーティショニング
     - Windows:[Create and format a hard disk partition](https://support.microsoft.com/en-us/windows/create-and-format-a-hard-disk-partition-bbb8e185-1bda-ecd1-3465-c9728f7d7d2e)
     - Mac:[Partition a physical disk in Disk Utility on Mac](https://support.apple.com/guide/disk-utility/partition-a-physical-disk-dskutl14027/mac)
 - PCにUSBメモリーを挿入して起動し、「Replace a partition」の設定でインストール
     - Windows:[Installing Feren OS alongside Windows](https://feren-os-user-guide.readthedocs.io/en/latest/installwithwindows.html)
     - Mac:[Installing Feren OS alongside macOS](https://feren-os-user-guide.readthedocs.io/en/latest/installwithmacos.html)


## ネットワーク環境
有線ネットワークが提供されている環境では、デバイスドライバのインストールのみで完了です。

Wifi環境(有線ネットワークが提供されていない環境)の場合、スイッチングハブの準備から順に進めていきます。

今回は有線LANを構築し、FerenOS側からインターネットに接続できるようにします。


## スイッチングハブの準備
 - スイッチングハブとPC(２台)をLANケーブルで接続します

## Ubuntu側の設定
 - 無線接続をWAN, 有線接続をLANとして設定します
     - 参考:[How to build Linux Router with Ubuntu Server 20.04 LTS](https://www.networkreverse.com/2020/06/how-to-build-linux-router-with-ubuntu.html)
     - netplan設定ファイル:[01-network-manager-all.yaml](https://github.com/ani-amou/memo-for-feren-os-install/blob/master/01-network-manager-all.yaml)

## FerenOS側の設定
 - Manualで有線接続を設定します
![Manualで有線接続を設定](https://raw.githubusercontent.com/ani-amou/memo-for-feren-os-install/master/img/wire_connection_setting02.jpg "Wired Connection Setting")

## デバイスドライバのインストール
 - USBメモリーを挿入します
 - Driver Managerを起動し、必要なデバイスドライバをインストールします
     - 参考:[Driver Manager](https://feren-os-user-guide.readthedocs.io/en/latest/drivermanager.html)

## おわりに
Wifiのみの環境では、Ubuntuのインストールに比べるとかなり大変でした。

今のところ、使いやすさは良い印象です。

アップデートに期待しつつ使っていきます。
技術と流行　～　オブジェクト指向を通しての考察

#１．オブジェクト指向が持て囃された時代

私がソフトウェア開発に関わり始めたのは2006年。その当時、Webシステムの開発が盛んになりはじめて、Java、Perl、PHPでの開発することが多かった。

2006年はmixiがSNS企業として上場をした年で、当時、SNSを開発する会社は多かった。

https://ja.wikipedia.org/wiki/Mixi

当時、開発手法としてはJavaでオブジェクト指向設計で開発することが良いとされており、UMLでモデル設計をして、クラス設計をして開発しようという「号令」が開発現場ではよく聞かれた。Javaに限らず、PHPでもオブジェクト指向設計を取り入れようという動きは当然あった。

あくまでも「号令」であって、実際に、オブジェクト指向できれいに組めている現場はあまりみたことがないのだけど、とりあえず、オブジェクト指向設計を使うことが「指向」されていた。

https://daiyamamoto.hatenablog.com/entry/2021/01/25/110425

ソフトウェア開発の「流行り」の技術は、耳目を引きたいがために、最初は良さしか喧伝されない。
そして、その「流行りの技術」は「神聖視」され、それがわからない、使いこなせない人は「老害」、「時代についていけない」、「能力がない」というレッテルを貼られがちだと思う。
それは昔も今も変わらないと思う。

そうした背景を「オブジェクト指向」をもっていたように感じる。なので、理解しているか否かは別にして、「号令」としては「オブジェクト指向設計」を採用していた。

#２．Javaやクラスを使えば「オブジェクト指向」？

では、オブジェクト指向設計を取り入れることで開発は効率化したのだろうか？
その答えは難しい。

というのがおそらく、JavaやPHPでクラス文法をつかっていれば「オブジェクト指向」だと思っている、または、そうとしか考えられないようなコードを現場でたくさんみてきた。

つまり、実際、「オブジェクト指向」という「号令」はあれど、内実はCOBOLでしてたのと同じく、手続き指向的な設計でされていたのが多かったように思う。
よく指摘されるのは、「static」を多用しているコードがあげられるだろう。

https://qiita.com/ue_knnk/items/fa84b8bc30ba319e5744

#３．オブジェクト指向への批判、関数型パラダイムの台頭

また一方で、オブジェクト指向の要素は取り入れているのだけれど、多階層の抽象化による実質GoTo文のような「スパゲッティ・コード」がたくさんあったりと、「オブジェクト指向」の要素を取り入れようとして形を変えた既知の問題が発生したり、逆に手続き型のコードよりわかりにくくなるものもあった。

その他、オブジェクト指向設計自体の問題、または、それを使いこなせないことが原因で、2015年あたりにはオブジェクト指向への批判がみられるようになった。
「OOP harmful bad waste」などのキーワードで検索すればいくらでもそうした記事は見つけられる。

https://medium.com/@konradmusial/why-oop-is-bad-and-possibly-disastrous-e0844fa96c1f


https://suzdalnitski.medium.com/oop-design-patterns-bd2c4fb3014c

https://www.leaseweb.com/labs/2015/08/object-oriented-programming-is-exceptionally-bad/

最近は、Go、Rust、Nimなどの次世代言語がクラス文法を採用しないことや、関数型言語のパラダイムが取り上げられることで、益々、オブジェクト指向への風当たりはきつくなっている。


https://fj.hatenablog.jp/entry/2019/04/22/111451

https://medium.com/@shaistha24/functional-programming-vs-object-oriented-programming-oop-which-is-better-82172e53a526


最近は、Javascript、特に、Reactの開発においても関数型のパラダイムが取り入れられており、オブジェクト指向一辺倒な設計ではなくなっている。

https://career.levtech.jp/guide/knowhow/article/394/

#４．設計手法に銀の弾丸はなく適材適所

個人的に、オブジェクト指向設計が有害だとも思わず、そこにまつわる単一責任、カプセル化、ポリモーフィズムなど処理を共通化させ、コード量を削減する手法は有益だと思う。

要は、オブジェクト指向一辺倒でアプリケーションすべてを構築するのは限界があるということで、利用領域によっては向かない部分もあるということだと思う。

値・状態の加工がメインの場合、オブジェクト指向は有効な手段だろうし、一方で、状態より値と値の関係に注目し、冪等性を担保する場合、副作用をなくすなどの関数型のパラダイムの方が有効だろう。

また、Webやスマホのアプリでは、クリーンアーキテクチャやコンポーネントなどモデルとインタフェースとの関係を深堀りして考えた設計手法などに意識を向ける必要もある。オブジェクト指向の否定というより、それも踏まえて、さらに深化した設計の観点が必要だということだと思う。


#５．「流行り」に潜む問題点

ソフトウェア業界は「最新技術」への関心が高く、「最新マウント」を取りたがる人もたくさんいる。
技術系の記事や書籍は最新技術の告知が一つの売り物なので、それは仕方ないし、それによる恩恵もある。

流行るにはそれなりの論理的な意味もある。
けれど、「商売」「マウント」というものが発信される裏にはあり、ともすれば、「メリット」しか喧伝されない。

おそらく、これまでもそうでったように、これからも技術には「メリット」「デメリット」「限界」「守備範囲」というものがあり、ある技術だけですべての問題を解決することはないと思う。

できれば、「流行り」の技術の「デメリット」「限界」「守備範囲」などがあるという意識をもって情報を読んだり、
または、発信する側もそこへの配慮もないと信憑性が薄いと思う。
母国語ルビ検討

# 内容
これまでアイデアレベルで、思いついては立ち消えしていた企画であるが、
試行錯誤の中で、ようやく薄っすらと方法論が見えてきた。

## これまでの経緯
[日本語読み歌詞WEB-API開発](https://qiita.com/EasyCording/items/ae1d9d1ee2e27d7671b7)
[ミスチルの歌詞を外国語で音読できないかの検討](https://qiita.com/EasyCording/items/3b220201fb661cb35e69)

# 方法論
### 音素分析
* 英語の「get on your case」というフレーズを、１００回以上音読していると、最終的には日本語で「月曜　荷受け　椅子」と脳内変換できる。

[参考資料　Smoking in the boys room](https://motochan1969.hatenablog.com/entry/20210602/1622584281)

### 脳内解析
* 自分の頭の中の処理を具体化すると、次のステップとなる。

##### 1) 母音／子音　→　音声のつながりを正す

英語の語尾が子音で終わるが、これが続く単語の先頭と合体して日本語読みが構成される。

```　get on your case →　ge tu you ni u ke　i su →　げつようにうけいす ```

##### 2) カナ文字　→　漢字当てはめ

次にカナ読みに対して、漢字の語句を当てはめ、瞬時に日本語脳がはたらく当て字が付与される。
 
```  げつようにうけいす　→　月曜　荷受け　椅子 ```
```plantuml
@startuml
skinparam monochrome true
skinparam ArrowColor black
skinparam ActivityBackgroundColor white
skinparam ActivityBorderColor black
skinparam ActivityArrowColor black

title 脳内解析フロー

start

:英語の語句を音読;

partition "母音／子音の処理" {
  :英語の語尾の子音と続く単語の先頭を合体;
  :日本語読みを構成;
  note right
    例：
    get on your case
    ↓
    ge tu you ni u ke i su
    ↓
    げつようにうけいす
  end note
}

partition "カナ文字から漢字への変換" {
  :カナ読みに対して漢字の語句を当てはめ;
  :日本語脳が瞬時に当て字を付与;
  note right
    例：
    げつようにうけいす
    ↓
    月曜　荷受け　椅子
  end note
}

:母国語での理解;

stop

@enduml
```

# 課題感
* コーパス辞書なら　テキストでよい　→　英語をローマ字読みに変えるテキストＡＩ
* 連文ならＲＮＮか？　ＢＥＲＴか？　→　前後の語句のつながり学習が必要
* 音節を音声解析で変換するのがベスト →　音声解析に踏み込むのは、まだ時間がかかりそう

```plantuml
@startuml
skinparam componentStyle rectangle

title Mother Language Ruby Conversion

package "Data Preparation" {
  component "English Corpus" as EC
  component "Japanese Corpus" as JC
}

package "Text-based Conversion" {
  component "English to Romaji Conversion AI" as E2R
  component "Context Learning Model (RNN/BERT)" as CLM
}

package "Audio-based Conversion" {
  component "Speech Recognition" as SR
  component "Phoneme Conversion" as PC
}

EC --> E2R
JC --> CLM
E2R --> CLM

CLM --> SR
SR --> PC

note left of E2R
  Convert English text
  to Japanese Romaji reading
end note

note left of CLM
  Learn the context and
  connections between words
end note

note right of SR
  Future integration with
  speech recognition AI
end note

note right of PC
  Convert phonemes to
  Japanese characters
end note

@enduml
```

# 参考資料

https://qiita.com/EasyCording/items/ae1d9d1ee2e27d7671b7

https://qiita.com/EasyCording/items/3b220201fb661cb35e69
JavaScriptで現実世界の文字を読み取る方法を調べてみた

機械学習のml5.jsについて学んだので何かを作ろうと思い、普通の温度計の**デジタル表示された数字をで読み取る**ものを作ろうと思い調べました。

![0606-thermo-0606.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1289676/9f1383b6-c914-d056-9f47-75fc5a174a67.jpeg)


#ml5.jsが対応しているモデルから探す

https://examples.ml5js.org/

まずは学びたてのml5.jsで探してみますが……うーん、なさげ、でしょうかね……。「OCR」「character」「number」で検索しましたが見つからず。カメラに映った文字を読み取る機能は需要的にもメジャーどころかと思っていたのですが……。

Teachable Machineでそれぞれの体温の写真を撮って学習させればいけるとは思いますが手間がかかりすぎて本末転倒ですし、なにより**狙った体温にできたらお前は人間ではない**。


#Google先生に訊く

以下のサイトによくまとまっていて助かりました。そこで知ったライブラリについて実装記事などをさらに調べていきます。

https://urusulambda.wordpress.com/2018/07/28/web%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%A8%E3%81%8B%E3%81%A7ocr%E3%82%84%E6%89%8B%E6%9B%B8%E3%81%8D%E8%AA%8D%E8%AD%98%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8Bjavascript/

##tesseract.js
https://tesseract.projectnaptha.com/

デモ用サイトを見る感じなかなかテンションあがる感じです。
「Tesseract.js can run either in a browser and on a server with NodeJS.」とのこと。

ちなみに「人が書いた文字を認識したいときはOCRではなく手書き認識(Hand written recognition)と呼ぶ」という知見を得ました。**・・・デジタル表示された数字を読み取りたい場合は？**


https://tech.prog-8.com/entry/2020/12/10/090000

>tessedit_char_whitelist で読み取る文字列をホワイトリストで指定できる

よく缶コーヒーについてる、数字10桁くらいを手入力するのが面倒なので自動化してみた、という実装例です。これは私も面倒で結局応募してないので素敵です。
文字列ホワイトリストに数字をそれぞれ入れれば認識精度上がるかな。

https://qiita.com/hiroism/items/bd537e014e71d3cab1f9

>Tesseractの対応形式は広く、Canvas要素をそのまま投入可能なのも便利なところです。

色々試されています。今回のサンプルコードに使わせてさせていただきます。(*- -)(*_ _)ペコリ

https://note.com/umaniel_/n/n276684dad31e

https://furutahisashi.com/js-ocr-tesseract/

https://blog.capilano-fw.com/?p=8085

https://qiita.com/keito1024/items/dff19c95ca7c9b6c5d0c


##ocrad.js
https://github.com/antimatter15/ocrad.js/

##MyScript
https://webdemo.myscript.com/

有料。

#まとめ
評判と実装例の情報量からtesseract.jsを試してみましょう。
Google Map Reactを簡単に試す

完成形
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/666fbb18-d3a3-5ffb-87a2-8135268dccf8.png)

## Google Map React

https://dev.to/devdefinitive/33-github-projects-i-have-bookmarked-and-you-should-298o

でも紹介されているGoogle Map React。いくつか過去記事がある。

https://qiita.com/Mitsuw0/items/b026c637c4294de0ccbf

https://qiita.com/theFirstPenguin/items/dc94aeb1595df1a0aa56

今回使うのは以下。

https://github.com/google-map-react/google-map-react

`npm install --save google-map-react`


### サンプル

```Main.js
import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';

const AnyReactComponent = ({ text }) => <div>{text}</div>;

class SimpleMap extends Component {
  static defaultProps = {
    center: {
      lat: 35.66, // 緯度経度
      lng: 139.74
    },
    zoom: 15
  };

  render() {
    return (
      // Important! Always set the container height explicitly
      <div style={{ height: '100vh', width: '100%' }}>
        <GoogleMapReact
          bootstrapURLKeys={{ key:'{API キーをここに}' }}
          defaultCenter={this.props.center}
          defaultZoom={this.props.zoom}
        >
          <AnyReactComponent
            lat={35.667345081692176}
            lng={139.7401442420512}
            text="アークヒルズはここ"
          />
        </GoogleMapReact>
      </div>
    );
  }
}

export default SimpleMap;

```


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

### 依存関係の解決

https://qiita.com/koh97222/items/c46d1ef2a63b92bb6c15

`npm install --save --legacy-peer-deps google-map-react`


### APIキー

https://developers.google.com/maps/documentation/android-sdk/get-api-key?hl=ja

> このページでは Google マップが正しく読み込まれませんでした。JavaScript コンソールで技術情報をご確認ください。

https://club.jidaikobo.com/knowledge/127.html

> 「Google Maps JavaScript API」で「有効にする」ことで、このエラーを抑止して、利用できるようになります。

> You must enable Billing on the Google Cloud Project at https://console.cloud.google.com/project/_/billing/enable 
> Learn more at https://developers.google.com/maps/gmp-get-started

### Zoomとは

https://developers.google.com/maps/documentation/javascript/maxzoom

Zoom は 0 to 18。


ということで超簡単にできた！という以上メモ書きだが、なにがしか参考になればさいわいです。
量子コンピュータの基本 - 異なる固有値に対する固有ベクトルは直交することの確認

## :sagittarius: この記事の目的

量子コンピュータ理論の基本、または線形代数の基本である公理「**異なる固有値に対する固有ベクトルは直交する**」ことについて、具体的に確認します。

なお、本記事の前に以下の記事を見て頂くとスムーズに読み進めることができます。

:paperclip: 量子コンピュータの基本 - エルミート行列の固有値が実数であることの確認
https://qiita.com/ttabata/items/26bd49f0ab526c0f6cd0

## :sagittarius: 命題「異なる固有値に対する固有ベクトルは直交する」の確認

では、さっそく数式を用いて確認します。

行列$A$をエルミート行列、異なる2つの固有値(スカラー値)を$\lambda_1,\lambda_2$、異なる2つの固有値に対する列ベクトル(固有ベクトル)をそれぞれ$X_1,X_2$とすると、**固有値・固有ベクトルの関係**から、以下のように表すことができます。

```math
AX_1=\lambda_1X_1\quad(式1)\\
AX_2=\lambda_2X_2\quad(式2)
```

ここでは説明を易しくするために固有値を2つの場合に限定します。
以下が自明の条件です。

```math
\lambda_1\ne\lambda_2\quad(式3)
```

(式1)に左から$X_2$のエルミート共役である$X_2^\dagger$をかけると、

```math
\begin{align}
X_2^\dagger AX_1&=X_2^\dagger \lambda_1X_1\\
&=\lambda_1X_2^\dagger X_1\quad(式4)
\end{align}
```

同様に、(式2)に左から$X_1$のエルミート共役である$X_1^\dagger$をかけると、

```math
\begin{align}
X_1^\dagger AX_2&=X_1^\dagger \lambda_2X_2\\
&=\lambda_2X_1^\dagger X_2\quad(式5)
\end{align}
```

(式5)について両辺のエルミート共役を取ると、

```math
(X_1^\dagger AX_2)^\dagger = (\lambda_2X_1^\dagger X_2)^\dagger\\
X_2^\dagger A^\dagger (X_1^\dagger)^\dagger = \lambda_2^*X_2^\dagger (X_1^\dagger)^\dagger\\
X_2^\dagger A^\dagger X_1 = \lambda_2^*X_2^\dagger X_1
```

行列$A$はエルミート行列であるから、$A^\dagger = A$です。また、エルミート行列に対する固有値は実数なので、$\lambda_2^*=\lambda_2$です。これらを代入すると、

```math
X_2^\dagger AX_1 = \lambda_2X_2^\dagger X_1\quad(式6)
```

改めて(式4)と(式6)を並べてみると以下となります。

```math
X_2^\dagger AX_1=\lambda_1X_2^\dagger X_1\quad(式4)\\
X_2^\dagger AX_1 = \lambda_2X_2^\dagger X_1\quad(式6)
```

上記の2式を引き算すると、

```math
0=(\lambda_1-\lambda_2)X_2^\dagger X_1
```

ここで、(式3)より$\lambda_1-\lambda_2\ne0$のため、上式が成立するには、

```math
X_2^\dagger X_1 = 0\quad(式7)
```

となります。
(式7)は複素線形空間におけるベクトル$X_1$とベクトル$X_2$の内積を意味します。つまり、

```math
(X_1, X_2)=0
```

内積が0なので、2つのベクトル$X_1,X_2$は直交することがわかります。

このことから、命題「異なる固有値に対する固有ベクトルは直交する」は真である(正しい)と言えます。


## :sagittarius: 関連情報

:paperclip: 量子コンピュータの基本 - exp(iA) がユニタリー行列になる理由
https://qiita.com/ttabata/items/0415cd004c450b64cec1

:paperclip: 量子コンピュータの基本 - エルミート行列の固有値が実数であることの確認
https://qiita.com/ttabata/items/26bd49f0ab526c0f6cd0

## :sagittarius: ご意見など

ご意見、間違い訂正などございましたらお寄せ下さい。
量子コンピュータの基本 - エルミート行列の固有値が実数であることの確認

## :libra: この記事の目的

量子コンピュータ理論の基本、または線形代数の基本である公理「**エルミート行列の固有値は実数である**」ことについて、具体的に確認します。

## :libra: 命題「エルミート行列の固有値は実数である」の確認

では、さっそく数式を用いて確認します。

行列$A$をエルミート行列、列ベクトル$X$を固有ベクトル、$\lambda$を固有値(スカラー値)とすると、**固有値・固有ベクトルの関係**から、以下のように表すことができます。

```math
AX = \lambda X
```

両辺に左から、$X$のエルミート共役行列である$X^\dagger$をかけます。

```math
\begin{align}
X^\dagger AX&=X^\dagger\lambda X\\
&=\lambda X^\dagger X\quad(式1)
\end{align}
```

両辺のエルミート共役を取ると、

```math
(X^\dagger AX)^\dagger = (\lambda X^\dagger X)^\dagger\quad(式2)
```

以下の公式を使用します。

```math
(AB)^\dagger = B^\dagger A^\dagger
```

(式2)を丁寧に展開すると、

```math
((X^\dagger A)X)^\dagger = (\lambda(X^\dagger X))^\dagger\\
X^\dagger (X^\dagger A)^\dagger = (X^\dagger X)^\dagger \lambda^*\quad(式3)
```

(式3)の右辺の記号$^*$は複素共役の意味です。$\lambda$はスカラー値なので、エルミート共役を取れない代わりに複素共役を取ります。
よって、(式3)は、

```math
X^\dagger A^\dagger (X^\dagger)^\dagger = \lambda^*X^\dagger (X^\dagger)^\dagger\\
X^\dagger A^\dagger X = \lambda^*X^\dagger X
```

当然ながら、$(X^\dagger)^\dagger = X$です。
ここで、$A$はエルミート行列なので$A^\dagger =A$を代入すると、

```math
X^\dagger A X= \lambda^*X^\dagger X\quad(式4)
```

(式1)と(式4)を比較すると、以下のようになります。

```math
X^\dagger AX=\lambda X^\dagger X\quad(式1)\\
X^\dagger AX=\lambda^*X^\dagger X\quad(式4)
```

これより、以下が導けます。

```math
\lambda = \lambda^*
```

$\lambda$はスカラー値であるから、上記が成立する条件は、$\lambda$が実数の場合になります。

よって、命題が真である(正しい)ことが確認できました。


## :libra: 関連情報

:paperclip: 量子コンピュータの基本 - exp(iA) がユニタリー行列になる理由
https://qiita.com/ttabata/items/0415cd004c450b64cec1


## :libra: ご意見など

ご意見、間違い訂正などございましたらお寄せ下さい。
【WPF】Pythonの標準出力をリアルタイムに表示する

Pythonで機械学習を回すGUIアプリを作っているときに、進捗状況を確認できればいいなーと思い色々調べたのでメモ

## コード
結果から言うとこれで上手いこといきました。恐らくこれが一番シンプルだと思います。

sumple.pyの出力結果を非同期で取得して、textbox(名前はtb1)に表示しています。
sumple.pyは1秒ずつ文字列を出力するだけのプログラムです。
GUIにはボタンとtextboxだけ置いてます。

```c#:MainWindow.xaml.cs
using System;
using System.Windows;
using System.Diagnostics;

namespace ConsoleRead
{
    public partial class MainWindow : Window
    {
        Process pr = null;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Start(object sender, RoutedEventArgs e)
        {
            HeavyMethod();
        }

        /// <summary>
        /// pythonコードを非同期で実行
        /// <summary>
        public void HeavyMethod()
        {
            pr = new Process();

            // pythonファイル(sumple.py)の指定
            pr.StartInfo.FileName = "python.exe";
            pr.StartInfo.Arguments = "-u sumple.py";

            // コンソール画面を表示させない
            pr.StartInfo.CreateNoWindow = true;

            // 非同期実行に必要
            pr.StartInfo.UseShellExecute = false;
            pr.StartInfo.RedirectStandardOutput = true;

            // イベントハンドラ登録（標準出力時）
            pr.OutputDataReceived += process_DataReceived;

            // イベントハンドラ登録（プロセス終了時）
            pr.EnableRaisingEvents = true;
            pr.Exited += onExited;

            pr.Start();
            pr.BeginOutputReadLine(); //非同期で標準出力読み取り
        }

        /// <summary>
        /// 標準出力があった時に実行
        /// </summary>
        public void process_DataReceived(object sender, DataReceivedEventArgs e)
        {
            string output = e.Data + "\r\n";
            Dispatcher.BeginInvoke(new Action(() =>
            {
                tb1.Text += output;
            }));
        }

        /// <summary>
        /// プロセス終了時に実行
        /// </summary>
        public void onExited(object sender, EventArgs e)
        {
            if (pr != null)
            {
                pr.Close();
                pr.Dispose();

                MessageBox.Show("end");
            }
        }
    }
}
```

```python:sumple.py
import time

for i in range(10):
    time.sleep(1)
    print("process" ,i*1)
}
```

## ポイント
### 1. 非同期実行
```pr.BeginOutputReadLine()``` を記述することで非同期で標準出力を読み取ることができます。

### 2. 標準出力の検知
```pr.OutputDataReceived``` にメソッドを追加することで、標準出力が行われたときに処理をすることができます。

### 3. UIスレッドからのtextboxの操作
```BeginInvoke``` でUIスレッドに戻してからtb1に結果を追加しています。

### 4. python実行時に-uオプションを付ける
これを付けないと標準出力が最後にまとめて表示されます。
これで半日悩んで結局teratailに質問投げたんですが、小一時間で回答が返ってきて解決してしまいインターネットしゅごい…となりました。

## 余談
最初async/awaitを使っていたのですが、awaitを使うとpythonの実行が終わるまで待たなければならず上手くいきませんでした。
標準出力が一つだけのコードを繰り返し使うような場合には良いかもしれません。

## 注意
全体的にふんわりとした理解なので（特にイベントハンドラ周り）、間違ったことを言っている可能性は十二分にあります。
何かありましたらご指摘いただけると有難いです。

## 参考
* C# GUIアプリケーションからPythonスクリプトを実行する  <br>
https://qiita.com/kimisyo/items/0879fc9f1315e2abfd1f
* 非同期で標準出力(コンソールアプリケーション)の内容をプログラムで受け取る - C#プログラミング  <br>
https://www.ipentec.com/document/csharp-get-standard-output-async
* Taskを極めろ！async/await完全攻略  <br>
https://qiita.com/acple@github/items/8f63aacb13de9954c5da
Talendを使ってシステム間連携を作るには　（EAI的な使い方）

# はじめに
<!-- 発端や概要を記載 -->
Talendを使ってみようてきな記事や、コンポーネントの使い方についての記事は
よくいるが、会社でどのように使っているかなど、具体的な利用などについて
を個人的にまとめてみる

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [システム間連携とは？](#Chapter1)
1. [環境](#Chapter2)
1. [ETLを用いたシステム間連携の概要](#Chapter3) 
1. [高頻度連携の作り方](#Chapter4) 
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#システム間連携とは？"></a>
# システム間連携とは？
システム間連携とは、社内のシステムAからシステムBへ連携することで、
例えば給与システムと勤怠管理システムのデータ連携など。

システム間の接続口として利用されているのがEAIツール。
複数のソースのデータを、DWHに集約するなどを行うのがETLツール。

TalendはOSSであり、Javaのコードジェネレーター※つまりGUIで開発したものが
Javaプログラムに変換され、javaとして動作する。

さらにざっくりと違いを整理
ETL：たくさんのデータを、低頻度で連携
EAI: 少ないデータを、高頻度で連携

<a id="#Chapter2"></a>
# 環境

Talend Data Integration 7.3（有償版）
(i) Talend Studio　・・・eclipseにGUI機能などを追加した開発環境
(ii) Talendサーバー　・・・ユーザー/ソース管理、スケジューラー機能、JOB実行サーバーなど
   
　　サーバーは下記の運用管理サーバーとジョブ実行サーバーを、図のように別々で持つことも
　　1つのサーバー内に持つことも可能
　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608742/e4bc144d-5d45-0ab3-5dc3-066b93ee8f04.png)
<a id="#Chapter3"></a>
# ETLを用いたシステム間連携の概要

システムAのIFテーブルを監視し、データがあれば変換し、システムBのテーブルへInsert後
システムBの取り込み処理をTalendが実行することで、連携時間を短くする。
特に、いつデータが来るかわからないときになど、ポーリングする際にデータがある時だけ皇族処理に
流すような作りにすることで、システム全体の負荷を下げる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608742/09f5d30f-bd34-fbcf-7b47-3980a09c5bcd.png)


<a id="#Chapter4"></a>
# Talendによる高頻度連携ジョブ
Talendのジョブスケジューラーは最短1分間隔での実行となるが、
1分間隔の実行だと、DBやサーバーに毎回接続したり、ログが増えたり、サーバー負荷が上がるなどの
課題がある。
また、最短で1分間隔のため、準リアルタイムのように、もっと短い間隔の実行をしたい場合、少し工夫が必要となる。


※現在作成途中


<a id="#reference"></a>
# 参考文献
- [リンクテキスト](URL)
- [リンクテキスト](URL)
yukicoder contest 298 不参戦記

# yukicoder contest 298 不参戦記

寝落ちして起きたら終わってた(笑).

## [A 1527 Input Constant is Good](https://yukicoder.me/problems/no/1527)

AとBを比較するだけです.

```python
A, B = map(int, input().split())

if A <= B:
    print('Yes')
else:
    print('No')
```

## [B 1528 Not 1](https://yukicoder.me/problems/no/1528)

ざっくりで考えると、2, 4, 6, 8, 10, ..., N で良いのかなと思いつくので、それでは上手く行かないパターンを考える. まず、N が奇数だと1つ足りない. それ以外に入れるなら3かなと思うと、3との行き来できる6が隣接する必要があるので、2, 4, 8, 10, ..., N-1, 6, 3 で良いんじゃないかと思い付く. 後はこれらを適用できない N=1, 2, 3, 4, 5 を別途処理して完成.

```python
N = int(input())

if N in [1, 2]:
    print(1)
elif N in [3, 5]:
    print(-1)
elif N == 4:
    print(2, 4)
else:
    t = [2, 4]
    for i in range(8, N + 1, 2):
        t.append(i)
    t.append(6)
    if N % 2 == 1:
        t.append(3)
    print(*t)
```
[Firebase] Storageのemulatorで"Failed to retrieve a download URL." が出る時の暫定対処

# 追記

[v9.13.0](https://github.com/firebase/firebase-tools/releases/tag/v9.13.0) で修正されました :clap: 

--- 


先日のGoogle I/O でFirebase Storageのエミュレータが発表されました! :clap: :clap: :clap: 

早速使ってみたところ、#getDownloadUrlを行う際に、表題のようなエラーが出てしまったので、(暫定的な）対処の覚書です。

# TL;DR

Emulator > Storage内のアイテムそれぞれについて、`Create New Access Token`を行う。


# 問題

emulator上ではファイルの存在が確認できるのに、#getDownloadUrlで `[firebase_storage/unknown] Failed to retrieve a download URL.`のようなエラーがでてしまう。

# 再現

自分は以下の手順を行うことで再現できました。 (`環境: MacOS BigSur M1, Flutter`)


1. emulatorを起動し、適当に画像をemulator上のstorageに保存する
1. `firebase emulators:export hode/fuga`により、エミュレータの状態をexport
1. emulatorを停止
1. `firebase emulators:start --import=hoge/fuga`により、exportされた情報を保持した状態でemulatorを起動
1. #getDownloadUrlを発火

# 解決法?の発見

ググったら、ほぼ同じ状況のissueがありました。 https://github.com/firebase/firebase-tools/issues/3451
emulator内で各ファイルで`Create New Access Token`のボタンをポチポチすることで解決できたというので、試してみたところ、解決できました。

# ちゃんとした解決策あったら教えてください。。。

一応emulatorを動作させることはできるので解決としてはありますが、毎回ぽちぽちするのは絶対的に非合理なので、もっとちゃんとした解決法をご存知の方いらっしゃいましたらご教授いただけると幸いです。。。 :bow: :bow: :bow:
Railsのrake assets:precompile RAILS_ENV=productionでJSON::ParserErrorが出る

業務でRuby on Railsを使っているのですが、RubyのバージョンアップとGemパッケージのバージョンアップ実施後からprecompile時に`JSON::ParserError`が出るようなりました。
解決に時間を要したので、メモを残します。この記事が助けになりましたら幸いです。

# 結論
--traceをつけて実行し、エラー文をよく見ると、execjsでエラーが出ていることがわかったので、
Gemfile.lockのexecjsの部分を

#### 修正前
```
execjs (2.8.0)
```

#### 修正後
```
execjs (2.7.0)
```

に変更して、`bundle install`したところ、precompileが通りました。

# 補足
execjsはJavascriptの圧縮に使われているようで、圧縮の指定をしている場合は`config.assets.js_compressor`を消すだけでも解消しますが、本番環境ではJavascriptの圧縮は必要かと思われますので、この対応方法は基本的にはなしかと思います。


execjsの[Githubのrelease](https://github.com/rails/execjs/releases)を見たところ、
2.8.0のリリース後2日ほどで2.8.1がリリースされているようで、こっちなら起きなかった疑惑...
ラインチャートレースをFlourishを使い作成【新車販売台数2012年～2021年5月】

##統計ダッシュボードからデータ取得

以前、「消費支出推移データ」を使い[バーチャートレース（アニメーショングラフ）を作りました](https://qiita.com/text_owleyes_0214/items/cb8cfee52dd9f2a8e75d)。
その際の操作をある程度覚えていたので、比較的省ステップでにラインチャートレースを作成できました。
データを取得して、時間ごとに区切る列の形に表を整形し、[Flourish](https://app.flourish.studio/)で読み込んで少しパラメータを調整して完成、という感じです。
データは総務省統計局の[「統計ダッシュボード」](https://dashboard.e-stat.go.jp/)から取得しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/6ec98b83-b1cc-6923-3edf-4dcc70ab61c8.png)

##月別アニメーションを作成

「Flourish」にログインし、「Line chart race」（with filtering）を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/5f6129a8-8c50-08e3-b48d-18ffa1a1bfd6.png)

サンプルデータが入っているので、それを参考にします。
「Upload data」をクリックしてデータ（xlsx）をアップロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/7300de2d-165a-62d5-85cc-f9d4d09f171d.png)

アップロードした状態が以下になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/4cfd7dfe-e948-4999-c995-ceeb27b71ced.png)

設定に使う「列」を調整します。
画面は調整後の状態です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/c2345773-91d1-e05e-26f4-198b5853336f.png)

##アニメーションを再生

「Preview」をクリックするとアニメーションが再生されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/2f425ac1-717c-54d0-f78b-a045aba9ca33.png)

画面右隅の「Export & publish」をクリックすると、クラウド経由で保存や公開が可能になります。
Embedするコードも取得できます。

**了**
golang-migrateをコード状から動かした時だけエラーになる

## 概要
golang-migrateをコマンドラインで実行した際は特に何も起きないのに、Golangコード上から動かすとエラーが出る。。。


## 環境

Mysql: `8.0.19`

golang-migrate: `v4`


## エラー内容

```
migration failed in line 0: ALTER TABLE `casts` ADD `secret` VARCHAR(255) DEFAULT '' NOT NULL AFTER `capacity`;
        ALTER TABLE `casts` MODIFY `secret` VARCHAR(255) NOT NULL AFTER `capacity`;
         (details: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ALTER TABLE `casts` MODIFY `secret` VARCHAR(255) NOT NULL AFTER `capacity`' at line 2)
```

## 実行SQL
```sql
ALTER TABLE `casts` ADD `secret` VARCHAR(255) DEFAULT '' NOT NULL AFTER `capacity`;
ALTER TABLE `casts` MODIFY `secret` VARCHAR(255) NOT NULL AFTER `capacity`;
```

## 解決法
`multiStatements=true`オプションを追加する

```
user:pass@tcp(host:port)/database?multiStatements=true
```

## 参考
https://github.com/golang-migrate/migrate/issues/313
GitHubのREADMEを書く為のいろは

## はじめに
綺麗なREADMEを書くためにはどうすれば良いのか、自分なりのルールを作ったので記事にまとめたいと思います。

## 使用するGitホスティングサービス
- GitHub

https://github.com/

## まず初めに
GitHubでリモートリポジトリを作成する場合、GitHubがデフォルトとしてREADMEのテンプレートを用意してくれていますので、それを利用するようにしましょう。
以下はPHPのフレームワークであるLaravelを使い、MITライセンスでプロジェクトを公開する場合の設定のサンプルです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490767/e043d950-df24-60f9-6920-53493cf3edf6.png)

https://wisdommingle.com/mit-license/

## 書いた方が良い項目
- バッジ一覧  
    - よく見かける↓です。詳細は下記を参照下さい  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490767/380fe08a-cc51-b7d0-60d9-89f1c3647266.png)
- Introduction
    - そのプロジェクトの簡単な紹介文を1行程度で簡単にまとめます。
- Demonstration
    - そのプロジェクトの簡単なデモ画像やgif動画を貼り、ひと目でどういうプロジェクトなのかが分かるようにします
- Features
    - そのプロジェクトの特徴、このプロジェクトを使うことでどういった目的を叶えることができるのかを詳細に記載します
- Requirements
    - そのプロジェクトの必要要件。必要な言語やライブラリのバージョンなどを記載します
- Installation
    - そのプロジェクトがパッケージとして公開されている場合には、インストール方法、インストールコマンドを記載します
- Usage
    - そのプロジェクトの使い方を箇条書きで記載します。なお、詳細な使い方については別項目やwikiなどに記載します
- Sample
    - そのプロジェクトを使うためのサンプルコードなど、プロジェクトを使う上での詳細なイメージや使い方を記載します
- Contributing
    - プロジェクトへの貢献の仕方についてのリンクを記載する
        - CONTRIBUTING.mdというファイルを用意し、そこにプロジェクト貢献のためのルールを記載し、そのリンクをREADMEには記載します
- License
    - ライセンスについて記載します

```
This package is open-sourced software licensed under the [MIT license](https://choosealicense.com/licenses/mit/)
```

## まとめると...
```
# Hogehoge Project
[![Laravel 6|7|8](https://img.shields.io/badge/Laravel-6|7|8-orange.svg)](http://laravel.com)
[![License](https://poser.pugx.org/stepupdream/blueprint/license)](//packagist.org/packages/stepupdream/blueprint)

## Introduction

## Demonstration

## Features

## Requirements 

## Installation 

## Usage

## Sample

## Contributing
 
## License

The Blueprint is open-sourced software licensed under the [MIT license](https://choosealicense.com/licenses/mit/)
```


## READMEに使うバッジについて
以下で作ることができます。URLを自分のREADMEに貼り付けるだけで見た目の綺麗なREADMEにすることができます。
※数値部分の値は反映に少し時間がかかる場合があるようです

https://poser.pugx.org/

https://shields.io/

その他、各種サービスに関するバッジについてはそれぞれのサービス内で配布されていますのでそれを利用します。
※GitHub Actionsのバッジであれば、GitHub Actionsのページ内でリンクが提供されています

## GitHub Actionsのバッジについて
こちらからリンクを取得することができます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490767/b8db6d8e-71f3-ec52-1f8b-cce45e49edc7.png)

## 参考
https://github.com/matiassingers/awesome-readme

https://qiita.com/Kyome/items/2112e9d1871ec0a367ea
Django web サイトを AWS を使って自分のドメインで公開するまでにやることリスト


事前にローカルで作っておいたwebサイト（Django）を、aws のサーバーを使って公開するまでにやったことをまとめました。
ウェブサーバは Nginx, アプリケーションサーバは gunicorn を使いました。
ウェブサーバ、アプリケーションサーバの概念の理解には https://view-s.co.jp/product/webapp/concept/ がとても役に立ちました。

まとめるとやったこととしては
- EC2 インスタンスを作成して、IPアドレスにアクセスするとサイトが表示されるようにする
- ドメインを購入して、http://hogehoge.com にアクセスするとサイトが表示されるようにする
- SSL証明書を発行して、https://hogehge.com からサイトにアクセスできるようにする
- その他雑多なもの

## AWS アカウントを作って、いろいろな初期設定をする

https://qiita.com/tmknom/items/303db2d1d928db720888

自分は適当な人間なので、この辺をおろそかにしたら後で後悔した。

## AWS EC2 インスタンスを起動し、環境を構築

下URLを参照して、EC2インスタンス起動と環境構築を行った

https://qiita.com/tachibanayu24/items/b8d73cdfd4cbd42c5b1d

- 前に作ったインスタンスのキーがあったので、ssh key は「既存のキーを利用する」を選択した
- PostgreSQL は入れなかった

## EC2 セキュリティグループのインバウンドに自分のIPアドレスを設定

途中で急に ssh できなくなった。

```
$ ssh -i "aws-ubuntu.pem" ubuntu@****.compute.amazonaws.com
ssh: connect to host ****.compute.amazonaws.com port 22: Operation timed out
```

下を参考にセキュリティグループに編集を加えてみた。

https://qiita.com/yokoto/items/338bd80262d9eefb152e

しかし後から、インスタンスのパブリックDNSを間違えて指定して ssh しようとしていたことが原因だったと気づいた。なので、多分このセキュリティグループへの編集はいらなかったが、上の記事設定はそのままにしておいた。パブリックDNSはインスタンスの再起動で更新されるので、毎回取ってくる必要がある。Elastic IP を取得して紐付けたらその必要は多分ない。


## .gitignore を追加
作ったwebアプリケーションのコードは git でバージョン管理をしていたが、基本的に個人で進めており雑な運用をしていたため、.gitignore を置いていなかった。サーバーにもコードを置いて、ローカルでコードを編集するとデータベースあたりでコンフリクトが起きて面倒なことになりそう。なので、.gitignore をしっかり置いてやることにした。
https://www.toptal.com/developers/gitignore で Django のための .gitignore コードを生成して使った。
一度 git add されたファイルはそのままだと .gitignore を無視してしまうので、下のようにキャッシュを全てクリアしてプッシュした。

```
git rm -r --cached .
git add -A
git commit -m "removed all cache to use .gitignore and reregistrated all files"
git push 
```

## SECRET_KEY を隠した
settings.py に記載されている SECRET_KEY は本来隠さないといけないものなので、おのおののローカルのみで管理されるように設定した。今更感はある。

https://qiita.com/haessal/items/abaef7ee4fdbd3b218f5

## EC2 サーバーで github に鍵認証
次の記事を参考に

https://qiita.com/nishina555/items/127f691a9e11e0fc5999

## ssh 接続を長持ちさせる
ssh 接続がわりとすぐ切れて面倒だったので、待機できる時間を長く設定した

https://qiita.com/qualitia_cdev/items/b7138b1280e693585267

上の記事は効かなかったので下を試した、機能している気がする

https://qiita.com/hide4649/items/804c1f67a05ee38d4234


## Django admin のユーザー登録をする
管理者ユーザを登録する

https://qiita.com/murabo/items/66e56803bf53d39fe640


## ドメインを取得して使えるようにする
お名前.comを使った

https://qiita.com/nakanishi03/items/25278fb4dfad60ebfac4

これにより、ブラウザに取得したドメイン名を打ち込むと自分のサイトが表示されるようになった。
設定をした直後は、welcome nginx みたいな画面が出るが数分待つと自分のサイトが表示されるようになる。

## SSL証明を使う
 
ドメインにアクセスしたときに「安全ではありません」と出るのが気になった

![image.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539480/5a91b402-5cad-bce5-2e60-e10425615718.jpeg)

https://qiita.com/miyuki_samitani/items/1734dc13c6b7af601bd9

これで https://*** からアクセスできるようになり、「安全ではありません」の代わりに鍵のマークがついた。google は http ではなく https を推奨しており、SEO 対策としてもこれをやっておくのは大事らしい。


## vscode でサーバー上のコードを編集できるようにする

SSH remote の方がメジャーなようですが、SSH FS を使っています（理由はない）。

https://qiita.com/informationsea/items/5c9f05c81a41fb885460
主キー以外を外部キーに設定する時に詰まった話

お久しぶりです、やすのりです！

今日はLaravelでテーブル作成時に詰まったので備忘録も兼ねて記事を書いていきたいと思います。

#結論
外部キーと参照元カラムの設定は同じにしよう！！


#何があったのか？
業務上でLaravelアプリを使用していますが、その中で新しいテーブルを3つ作って全部リレーションさせて、尚且つその内の2つは『外部キーの参照元を主キー以外に設定』する仕様になっていました。

1つ目のテーブルを作成するのは難なくできましたが...2つ目のテーブルを作成する時にエラーが出まくりました！

```sql
SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint (S  
  QL: alter table `test2` add constraint `test2_test1_id_foreign` foreign key (`test1_id`) references `test1` (`test1_id`))
※カラム名は仮称にしてあります。
```

とSQLの『test2テーブルのtest1_idは外部キー設定が出来ませんよ！！』というエラーが出てきました...

このエラーでよく見かける解決ほうに**『主キーの型と外部キーの型が間違っている』**というものがありました。

そして実際のコードを見てみましょう。

```php
    public function up()
    {
        Schema::create('test1', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id')->unsigned();
            $table->integer('test1_id')->unsigned()->unique();
            $table->timestamps();

            $table->foreign('user_id')
                ->references('id')
                ->on('users')
                ->onDelete('cascade');
        });
    }

    public function up()
    {
        Schema::create('test2', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('test1_id');
            $table->integer('test2')->unique();
            $table->timestamps();

            $table->foreign('test1_id')
                ->references('test1_id')
                ->on('test1');
        });
    }
```

はい、この時点で分かる人には分かりますね。
そう、『test1テーブルのtest1_idに'符号なし'を意味する'unsigned'を設定しているのに、test2テーブルの外部キーである'test1_id'には設定していない』からでした！

今思えば単純なことだし、初歩的なことなんですけど...
エラーが発生している時は**『主キーの型と外部キーの型が間違っている』**という部分に引っ張られて『え〜？主キーである'id'と'test1_id'は同じinteger型なんだけどなぁ』とか思っていました...
いや、普通はそれでいいんだけど、今回は主キー以外を外部キーにしてるから**『外部キーと参照元のカラムが同じ型かどうか？』**を確認しないとダメでした!

いやぁ、意外と初歩的なことって間違えちゃいますね！！

ってことで型が間違ってないか分かりやすくするためにさっきまで使用していた**『unsigned』**という記述ではなくて、そもそもの型の記述を**『unsignedInteger』**に変更しちゃいました！

```php
    public function up()
    {
        Schema::create('test1', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('user_id');
            $table->unsignedInteger('test1_id')->unique();
            $table->timestamps();

            $table->foreign('user_id')
                ->references('id')
                ->on('users')
                ->onDelete('cascade');
        });
    }

    public function up()
    {
        Schema::create('test2', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('test1_id');
            $table->unsignedInteger('test2')->unique();
            $table->timestamps();

            $table->foreign('test1_id')
                ->references('test1_id')
                ->on('test1');
        });
    }
```

これならパッと見で違ってたらわかるでしょう！！


#感想
みなさん、初心は忘れないようにしましょう...
お兄さんとの約束ですよ！！
ボタンを押した際に値を取得する方法

これも備忘として書いておきます。


```html:test2.html
<html>
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <button id="button1" name="baka" value="500" onclick="cal()">計算実行</button>
    <script type="text/javascript">
    //ボタン押下時実行
    function cal(){
      alert(document.getElementById("button1").value*100);
    }
   </script>
 </body>
</html>
```
Apisnote-Acitivity-viewer の使い方(exeバージョン)

#Apisnote-Activity-viewerとは
[APISNOTE]( https://www.apisnote.com/ )での活動量を時系列に可視化できるツール"Apisnote-Activity-viewer (aav)"の使い方を簡単に紹介する．
詳細は[APISNOTE for DevelopersのUseCase] (https://community.apisnote.com/#usecase)を参照

##Quick Start (手順)
1. [Apisnote-Activity-viewerのGitHubリポジトリ](https://github.com/Apisnote-Community/Apisnote-Activity-viewer) にアクセス

2. リストから「aav5.exe」をクリック (※現在の最新はaav6)
<img width="800" alt="リスト画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1607026/c643f4e2-d1c9-e8ef-5bec-bafc63b98ce1.png">

2. 「Download」を選択しexeファイルをローカルに保存
<img width="800" alt="ダウンロード画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1607026/ee98776b-ff8f-d23f-d1db-5ac71abfc13a.png">

2. 保存先で実行
※windowsで実行すると「実行しない」という選択肢が出てくる場合があるが，「さらなる情報」を押すと実行できる．
※お気づきの点があれば以下から投稿お願いします．
https://github.com/Apisnote-Community/Apisnote-Community.github.io/discussions
<img width="385" alt="ダウンロード画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1607026/8a559bc0-951e-b4ba-8b0b-e9dd391dbb0b.png">　<img width="385" alt="ダウンロード画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1607026/1a935851-3686-8b50-43cb-61b681b61d6d.png">

3.  実行すると入力画面が立ち上がる．
<img width="600" alt="リスト画像" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1607026/ed437428-e5b7-9ae4-ff28-0a9294abf284.png">

3. 入力欄にそれぞれ入力．これで出力可能
 
| 入力欄 | 説明 | 入力例 |
|:-----------|:------------|:------------:|
| Folder       | APISNOTEから出力したcsvファイルがあるフォルダを選択| D:\APISNOTE\ |
| CSV File list |使用するcsvファイルを一覧にしたtxtファイルを作り,上記フォルダに保存しておく。※csv一括ダウンロードした際はこの欄は空欄としておく | list.txt |
| Starting/Ending Datetime |出力したい開始・終了時刻を指定する | 09/30/2020 at 7:53PM |
| Time Interval |出力したい活動量の単位計測時間(min)．例えば20minなら活動量の20分間の平均が20分ごとに可視化される| 20 |
| Color |出力したいノートの活動量の色を指定できる．例えば"yellow"なら黄色ノートの活動量のみが可視化される．allはすべての色が対象．| 20 |
| Action |出力したいノートの活動量の活動種類を指定できる．例えば"add"ならノートの追加の活動量のみが可視化される．allはすべての活動が対象．| 20 |
| Figsize |出力したい図のサイズ(横×縦)． | 27 9 |

　　list.txtの記載例
　　・使用するcsvファイルを列挙する
　　・特定の色のノートの活動量を見たい場合，csvファイル名の後ろに",色"を追加する
　　※aav6から対応したcsv一括ダウンロード（ワークブックの共有ボタンから選択可能）の際はlist.txtは設定不要
　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1607026/aaa9e006-7632-8cce-660e-73abc3fa25a3.png)
##出力例
例①　アイデア発想，アイデア評価，アイデア精緻化それぞれのノートブックの活動量を可視化したもの
　・time interval は20min
　・色が濃い部分でAPISNOTE上の活動が活発
　・この班は10/28に順調に進捗していることがわかる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1607026/5c70549b-e899-d60f-2ed4-9268d873183f.png)
Postmanのリハビリ No.01 〜WebページにGETを送ってレスポンスを得る〜

# 目的

- APIサーバーの実装を最近しておらず、Postmanの使い方を完全に忘れたのでリハビリがてら触ってみる

# 環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

# 情報

- 筆者のPCは環境に記載されている通りMacである。
- Windowsとは作業が若干異なる可能性がある。
- 今回はQiitaの筆者のhome画面のURL宛にGETを送りどんなものが帰ってくるのかを調べてみる。

# 方法

1. Postmanを起動する。
1. 下記画像の赤矢印が指している「+」　をクリックする。

    ![Postman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5cf24d8c-0cb2-67b1-80f6-6ad4f8368253.png)

1. 「GET」の部分に筆者のQiitaのhome画面のURLを記載する。

    ![Postman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/cd5f6529-462a-2dd0-9fb7-07253981f042.png)

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

    ![Postman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5a654792-e086-3b7c-f066-e5e3ae2a5289.png)

1. レスポンスが帰ってきてBodyに記載されている。

    ![Postman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/75c33ba4-aa7a-31d5-911f-dfd06dc59b57.png)

1. 特定のURLにGETを投げてレスポンスを得る事ができた。
[2021年対応] Slackのemojiを一括でダウンロード

```
今居るワークスペースに魅力的なemojiが一杯... そんな素敵emojiを別のワークスペースにも輸出したい！
```
Qiitaで供養する

# 1. Slack API登録
## App登録
Tokenが無いと始まりません。 `xoxb` ではじまるTokenを入手します。
https://api.slack.com/apps?new_app=1 から登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124191/b2256911-e075-9ddb-c6a4-c6ebcbecf840.png)
ワークスペースを選んで作成

## 権限追加
左ペインの `OAuth & Permissions` から Scopes に `emoji:read` 権限を追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124191/699dd3f9-f92f-884c-8510-6500079045fa.png)

## Install to Workspace!
ワークスペースにAppをインストール（これで動くようになる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124191/f772ea29-aa29-8f9d-0688-62f4b4f6d542.png)

こうなればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124191/9073968e-0cad-a318-123f-55ad1bc7b5df.png)

Tokenゲットできたので :ok:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124191/d47cb7ac-771b-ce3f-991a-f61d9b4135f3.png)

# 2. 試し打ち
APIリファレンスからAPI試し打ちができるのでやってみる
https://api.slack.com/methods/emoji.list/test

Tokenをつけてリクエストすると、リクエスト時のパラメータとレスポンスが確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124191/21f5ee12-351c-aa8f-89cb-1e3aeed59d24.png)

# 3. Nodeでやろう
先にシェルでnpmで必要なものを揃えておく

```
npm install fs
npm install request
```

jsファイルと同じ階層に `image` ディレクトリを作っておく

```
touch slack-emoji-exporter.js
mkdir image
```

コードはここに
https://gist.github.com/notchi590/9c62bcc6508f26c4dcde315a79520777

あとは slack-emoji-exporter.js に上書きして保存、実行すればOK

# 4. 謝辞
めちゃくちゃ参考にさせて頂きました
https://qiita.com/ne-peer/items/cbdef4f02b1bb6103e51
個人学習で書くコードはpublic公開した方がよい理由

## はじめに
コロナ禍の影響で、エンジニア転職が増えてるという肌感です。
私もまったくの異業種からの転職でこの業界にきました。
昔の自分に会えたらこう言ってあげたいという思いをポエムとしてまとめましたので一つの記事としたいと思います。
この記事が一人でも多くの未経験エンジニアの役に立てば幸いです。

[2021.06.08追記]
反響がありとても驚いています。
同時に内容が一部不十分であったこと反省しています。
セキュリティ面についての内容を追記いたしました。

## コードはGitで管理しよう
個人開発であってもコードはgithubなどのGitのホスティングサービスで管理するようにしましょう。
業務ではgitを使うのが一般的ですし、バージョン管理ができるので「正確に動作していた時に戻す」なども簡単にできます。

個人開発であってもdevelop一本化ではなく、git-flowに則ってバージョン管理したり、リーダブルコミットを意識してコミットログを書いておくと、とても勉強になります。

https://www.atmarkit.co.jp/ait/articles/1708/01/news015.html

https://speakerdeck.com/cocoeyes02/recommendation-of-readable-commit

## コードはpublic公開しよう
過去の自分に強くこれを伝えたいと思っています。
Githubなどのホスティングサービスでは一般的に非公開（privateリポジトリ）と全世界への公開（publicリポジトリ）の二種類が選択可能ですが、個人開発であってもpublicリポジトリを強くオススメします！！
そして可能であれば、QiitaやTwitterなどにGithubのURLを載せるなどして常に人に見られるかもしれないという状況にしておくことを推奨します。

人に見られるかもしれないという意識があると、自ずとコードをキレイに書くことを意識しやすくなりコーディングスキルが高まりますし、何よりもpublicリポジトリにすることで以下様々なメリットが受けられるようになります。

## publicリポジトリにすることで受けられる恩恵

- GitHub Actionsが無料で制限なく使えます
    - 様々なことを自動化してくれるCI/CDツールが使えます
- styleciが無料で制限なく使えます
    - Laravel公式などで使われているツールです。コーディング規約から外れている場合は自動で修正提案してくれます
- codeclimateが無料で使えます
    - 書いたコードの品質を自動でレビューし、指摘箇所があればなぜ悪いのかを理由付きで教えてくれます
- sonarcloudが無料で使えます
    - 書いたコードの品質を自動でレビューし、指摘箇所があればなぜ悪いのかを理由付きで教えてくれます
- Coveralls
    - プログラムのテストを行った時にどれくらいの範囲がテストされているかを調べて表示してくれるサービスです。

https://sonarcloud.io/

https://codeclimate.com/

https://styleci.io/

https://qiita.com/Yuuki557/items/5ea3d46b8f6251805c4e

https://coveralls.io/

## セキュリティについて
学習した内容や方法によっては外部サービスのトークンや鍵を使用する場合があるかと思います。
これらの情報は外部公開すべきではない秘密情報であるため、取り扱いには十分注意し、コードに直接埋め込まないようにしましょう。

これらの内容を扱う場合は、環境設定の情報だけをまとめた環境設定ファイルを用意し（Laravelであればenvファイル）、そのファイルはgitignoreにしておくことで誤った情報流出を防ぐことができます。

そのほか、「git-secrets」というツールを導入することでも万が一を防ぐことが可能です。
秘密性の高いものをプロジェクトファイル内におく必要性がある場合にはこういったツールの導入を検討しましょう。

https://qiita.com/pottava/items/4c602c97aacf10c058f1

## IDEを使おう
プログラムはエディタでも書くことはできますが、機能の多さが桁違いなのでIDEを使うようにしましょう。
個人的に推しているのは、jetbrains社の各種IDEです。
高機能なプラグインが豊富ですし、コード補完機能がとても優れています。
弘法筆を選ばずとは言いますが、駆け出しエンジニアだからこそお金を出してでも良い筆（IDE）を使って足りない技術力を補いましょう！
学生さんであれば無料で使うことも可能です。

https://www.jetbrains.com/ja-jp/

https://www.jetbrains.com/community/education/#students

https://qiita.com/nagareboshi/items/69dc6d5b6a0b7cc4cf27

## コミュニティに参加しよう
プログラム学習は孤独なこと多いかと思います。
よく分からない現象に陥って1日で作業が何も進まなかったということもあるかもしれません。
そんな悩み相談やエラー解消などには各言語やフレームワークごとに存在するコミュニティに参加するのがオススメです。
人に教えたり、アウトプットしたりすることが好きな人が多いので、気持ちを伝えれば快く返答してくれると思います。
ただし、お礼や感謝の気持ちはいつも忘れずに！！

## 最後に
この記事が一人でも多くの人の役に立てば幸いです。
そして、強いエンジニアになったあとは、各種サービスやIDEの社内普及や業務利用などを通し、「お金」という形で各種サービスに還元し、業界の発展に繋がっていくことを願います。
AWS EC2にてport 22: Operation timed outの解決策。



## sshからEC2に接続の際にタイムアウトして接続できなかった問題。


### 結論

何故かVPCのインターネットゲートウェイがDetattchされていました。故に切できるはずもなく。


### 解決策
![Screen Shot 2021-06-06 at 0.25.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/685152/e5c04ceb-7f2c-cb34-bac7-d24a5ff658de.png)

Attachedにて再度試して接続出来ました。
Javascriptを久しぶりに触ってみました。


html文書にJavaScriptを埋め込んで処理する時の記載方法を備忘で記載しておきます。

次に試したいのは、与えている変数をブラウザから取得する方法です。

```html:test.html
<html>
  <head>
    <meta charset="utf-8" />
  </head>
  <body>
    <h1>線</h1>
    <canvas id="line" width="100" height="100"></canvas>
    <h1>四角</h1>
    <canvas id="rectangle" width="100" height="100"></canvas>
    <h1>円</h1>
    <canvas id="circle" width="100" height="100"></canvas>
    <script type="text/javascript">
    //読み込み時に実行する
    onload = function() {
      /* 線を引く */
      var line_canvas = document.getElementById("line"); 
      var line_ctx = line_canvas.getContext("2d");
      line_ctx.beginPath();
      // 開始位置に移動する
      line_ctx.moveTo(20, 20);
      // 線を引く
      line_ctx.lineTo(80, 80);
      line_ctx.closePath();
      line_ctx.stroke();
      /* 四角を描く */
      var rect_canvas = document.getElementById("rectangle");
      var rect_ctx = rect_canvas.getContext("2d");
      rect_ctx.beginPath();
      // 四角を描く
      rect_ctx.strokeRect(20, 20, 60, 60);
      /* 色の付いた円を書く */
      var cir_canvas = document.getElementById("circle");
      var cir_ctx = cir_canvas.getContext("2d");
      // 塗りつぶす色を指定する
      cir_ctx.fillStyle = 'rgb(0, 255, 0)';
      cir_ctx.beginPath();
      // 円を描く位置を決める
      cir_ctx.arc(50, 50, 40, 0, Math.PI * 2, false);
      // 実際に円を書く
      cir_ctx.fill();
    }
    </script>
  </body>
</html>
```
ビデオゲームの描画プログラム、サンプルと実務での実践の間にある物

# 初めに
ネットには描画プログラムのサンプルやデモは沢山転がっています。しかしながら実際仕事での使い方とは乖離している物もあり、そこの間を埋める資料は無くはないけど少ないので、サンプルを理解した後の次の実践的な実装で悩んでいる人も多いと思います。
細かい事は沢山ありますが、今回は大きい所を2つだけ紹介します。

# マルチスレッド
ある程度の規模以上のゲームではゲームスレッドと描画スレッドが分かれています。

自前で定義した描画の書式(描画パケットと言ったり、仮想描画コマンドと言ったりチームよって様々)を積んで、同期タイミングで描画スレッドへ転送、描画スレッドではそれを解釈しながら描画API(Dx12やVulkan)を呼んでいく実装が多いと感じます。

初回の実装は大変ですが、一旦この実装を書いてしまうと、解釈部分にプラットフォームのコードをまとめられるので、その後のマルチプラットフォーム化は楽になる事が多いです。

描画スレッドの実装により、ゲームも描画も同じスレッドで処理していた時に比べ処理速度は大幅に上がりますが、例えばボタンを押してから画面に表示されるまでの応答速度は遅くなる可能性もあるので、ゲームでの重要性を見ながら処理速度と応答速度のバランスを調整する必要があります。
CPU側で書き換える可能性のある頂点やテクスチャのリソースは実装によってはダブルバッファ化する必要があります。

また、描画リソースの開放は描画スレッド側での使用が完了したのを待ってから解放するようタイミングを管理する必要があります。

負荷に困っていない小規模なタイトルでは無理して実装しなくてもいいと思います。


# バッファの管理
多くのサンプルではリソース毎に直接APIから確保しています。しかしながらVulkanなどでは確保数に上限があったりするので現実的な実装ではありません。
予め大きなバッファを確保しておいて、それを管理するアロケータ経由で必要な分を確保して使う実装をする必要があります。
ディスクリプタなども同様です。
また、同時に使う事のないレンダーターゲット同士のメモリの共有の仕組みなども節約のために作る事が多いです。

# 最後に
細かい所だともっと色々ありますが、本やネットのサンプルと、実際仕事で使うコードとの差が大きいと感じる2つを上げてみました。具体的な実装は何も書いてなくて申し訳ないです。

最近は上記に加えて、indirect系のAPIや非同期CSも複雑に絡むので、最初に見た人は戸惑う事が多い気がします。例えば学校出たての描画エンジニアにここら辺教えるのは大変だと思うのですが、OJT以外で何かいい方法や資料＆サイトあれば教えて下さい！
Pythonの学習記録

PythonでWEBアプリを作りたいと考え、勉強したことを記載していく。

#1.環境

Visual Studio 2019を使用する。

## 1-1.pytestの環境構築

テストコードを書いていこうと考え、pytestを勉することにしたが、最初にはまったことを記載する。
### 1-1-1.プロジェクトのテストフレームワークを設定。

ソリューションエクスプローラで、プロジェクトを選択し、右クリック。
[テスト]タブで、テストフレームワークから[pytest]を選択する。

### 1-1-2.pytestのインストール
なぜかテストメソッドを作成しても、認識しないと困っていたが、pytestのインストールが必要だった。
【Javascript】Strings(2)学習ノート

# 初めに
Stringについて学習した内容のoutput用記事です。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。
※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。

前回の記事：
https://qiita.com/redrabbit1104/items/d68a8f79420a2a0320a6

# 文字列の大小
英語の文字列に大文字と小文字が混ざっている場合、文字列を小文字にするにはtoLowerCase()、大文字にするにはtoUpperCase()を使います。

```javascript
const bank = "Mitsubishi UFJ Bank";

console.log(bank.toLowerCase());
//mitsubishi ufj bank
      
console.log(bank.toUpperCase());
//MITSUBISHI UFJ BANK
```

これを応用すれば名前が大小混ざっている文字列を最初の文字だけ大文字にし、残りの部分を小文字にすることができます。

```javascript
const accountName = "toMaS";
const accountNameCorrect =
accountName[0].toUpperCase() + accountName.toLowerCase().slice(1);

console.log(accountNameCorrect);
//Tomas
```
# trim()メソッドで要らない空白を削除
emailが正しいかどうかをチェックする場合に、trim()メソッドを使い空白を取り除くことができます。

```javascript
const email = "test@yahoo.co.jp";
const inputEmail = "　  Test@YahoO.co.Jp \n";

const lowerEmail = inputEmail.toLowerCase();
const trimmedEmail = lowerEmail.trim();
console.log(trimmedEmail);
//test@yahoo.co.jp
```
コンソールで確認するとemailと入力したinputEmailが一致しています。

```javascript
console.log(email === trimmedEmail);
//true
```

# 文字列の変更
replace()メソッドを使えば、対象の文字列を変更することができます。

```javascript
const pages = "The page you were looking for doesn't exist.";
console.log(pages.replace("doesn't exist", "exists"));
//The page you were looking for exists exist.
```
また、replaceAll()で対象の文字列を全て変更できます。

```javascript
const replaceTest = "Home Home Home Home";
console.log(replaceTest.replaceAll("Home", "School"));
//School School School School
```

# Boolean
文字列が存在するか調べるにはincludes()メソッド、対象の文字列で始まるかどうかを調べるにはstartsWith()メソッド、対象の文字列で終わるかを調べるにはendsWith()メソッドを使います。結果はtrueかfalseになります。

```javascript
const pages = "The page you were looking for doesn't exist.";

console.log(pages.includes("you"));
//true

console.log(pages.startsWith("page"));
//false
     
console.log(pages.endsWith("exist."));
//true
```

#参考サイト
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/trim
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/replace
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
【kotlin】ListView Adapter 変更可能なリスト①

#■Adapter 
作ったデータをListViewの各行に表示する働きをするオブジェクト



■Adapterオブジェクトを作るには
Adapterインターフェイスを実装したクラスを利用します。
よく使われるのは3種類ありますが今回は
ArrayAdapterを使います。

▼ArrayAdapter
元データとしてArray.もしくはMutableListを利用するアダプタクラス

``` kotlin
val adapter = ArrayAdapter(第一引数,第2引数,第3引数)
```

第一引数
context:Context
どこの画面

``` kotlin
//例
this@MainActivity
```

第二引数
resource: Int
リストビューの各行のレイアウトを決める。
用意されているものも書けるし自分で用意したレイアウトも渡せる。
▼用意されている1行を表すコード

``` kotlin
android.R.iayout.simple_list_item_1
```

第3引数
objects: MutableList<T>
リストデータ
配列名など

``` kotlin
 //リストデータ
 val menuList = mutableListOf("ごはん","ラーメン","チキン","野菜","漬物")
 //アダプター
 val adapter = ArrayAdapter(this@MainActivity,android.R.layout.simple_list_item_1,menuList)
```

■ListViewにアダプタオブジェクトをセットする。

``` kotlin
 //リストビュー
 val lvMenu = findViewById<ListView>(R.id.lvMenu)
 //リストデータ
 val menuList = mutableListOf("ごはん","ラーメン","チキン","野菜","漬物")
 //アダプター
 val adapter = ArrayAdapter(this@MainActivity,android.R.layout.simple_list_item_1,menuList)
 //リストビューアダプターにアダプターをセット
 lvMenu.adapter = adapter
```

![スクリーンショット 2021-06-05 23.33.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558142/08a89f06-a581-db77-0cdb-ff50aada9ad2.png)