OmniAICreator/Qiita-1.07M huggingface dataset:
Swift 古い非同期関数をasync/awaitで呼び出せるようにラップする

Swift で **Future** や **Promise** にあたるものを使いたくなった時に、毎回ググり直すので自分用のメモです。
わかりやすく **「古い」「新しい」**と書いていますが単純に登場した順番であって、良し悪しの話ではないです。

# 古い関数をラップする

- こういう古い書き方の関数があり、都合によってこれ自体を書き換えれられない場合
 
```Old.swift
func old(completion: @escaping () -> Void) {
    print("処理中...")
    completion()
}
```

- 新しくこういう風にラップしましょう

```New.swift
func new() async {
    try! await withCheckedThrowingContinuation { continuation in
        old {
            continuation.resume()
        }
    }
}
```

```withCheckedThrowingContinuation``` の中で古い関数を呼ぶことがポイントです
上記の例ではエラーが起こらない前提があるので　```try！``` を使っています

# ラップした関数を呼び出す

- すると今までと比べて綺麗に呼び出せるようになります。

```OldAndNew.swift

// 今まで通り old を呼び出す方法
print("処理前")
old {
    print("処理後")
}

/*
  処理前
  処理中
  処理後
*/

// 新しくラップしなおした new を呼び出す方法
print("処理前")
await new()
print("処理後")

/*
  処理前
  処理中
  処理後
*/

```

# おまけ

- ちなみに **SwiftUI** の Button のように非同期のアクションに対応していない箇所から呼びたい場合は **Task** の中で使います。

```SwiftUIButton.swift
...
Task {
    print("処理前")
    await new()
    print("処理後")
}
...
```

- コールバックで値を返す場合やエラーハンドリングに応じて　```.resume(returning:)``` や ```.resume(throwing:)``` , ```.resume(with:)``` といった関数も用意されています。
 
詳しくは withCheckedThrowingContinuation でググりましょう。（結局ググるんかい）
これでようやくSwiftでもコールバック地獄から抜け出せる。やったぜ✌️
プロキシの向こうにあるリモート上のJupyter NotebookにSSHポートフォワーディングでアクセスしたら便利だった

この記事は、プロキシのさらに向こうにあるリモート上のJupyter NotebookにSSHのポート開放のみでアクセスする方法の紹介です。

---------筆者の環境---------
ローカルの端末:Windows 10, TeraTerm, Powershell
プロキシサーバ:Centos(あんまり関係ないと思う)
研究開発用サーバ:Centos(あんまり関係ないと思う)

#何ができるの？

手元のwindows端末のブラウザで、プロキシのさらに向こうのサーバ上のJupyter Notebookを操作できます。このとき、ssh以外のポート開放やJupyter NotebookをSSL(暗号化して)でやりとりする必要がないという特徴があります。

今回やる「SSHポートフォワーディング」を2回使う場合と「ふつうにやる方法」を図で比較してみてください。

![SSHポートフォワーディング2階建てv02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441999/78ce698c-efdc-48e4-810c-3e5da7f83fd0.jpeg)


SSHポートフォワーディングを2回使って接続すると
・通信を暗号化できる
・ファイアウォールのポート:8888を開放しないでOK
・プロキシサーバの設定変更(websocketの許可)をしないでOK
・SSH接続できる人しかJupyter Notebookにアクセスできないので管理が楽
というメリットがありました。

デメリットとしては
・ポート:8889は使えない(jupyterに複数ログインできない)
・起動が面倒。
というのがあります。起動が面倒なのはUNIXのscreenコマンドなどで解決できそうですね。

図の例では、プロキシは「さくら」、jupyterは「GCP(Google Cloud Platform)」という別のクラウドコンピューティングサービスを利用しています。プロキシサーバ⇔研究開発用サーバの間が遠隔地であっても大丈夫なところは強みです。


#やり方
##\<忙しい人向け\>

**①Jupyter Notebook を起動して放っておきます。**
・なんやかんやで研究開発用サーバにsshログイン
　「jupyter notebook」と叩く。このターミナルは開きっぱなしにしておく。
　
**②プロキシサーバ⇔研究開発用サーバのSSHポートフォワーディングをして放っておきます。**
・windows端末で新しくターミナルを開き、プロキシサーバにsshログイン

```sh
$ ssh -L 8888:localhost:8888 [研究開発用サーバアカウント名@研究開発用サーバアドレス] -i [秘密鍵]
```

と叩く。このターミナルも開きっぱなしにしておく。

**③windows端末⇔プロキシサーバのSSHポートフォワーディングをして放っておきます。**
・windows端末の「PowerShell」を**管理者権限で起動**。

```sh
$ ssh -L 8888:localhost:8888 [プロキシサーバアカウント名@プロキシサーバアドレス] -i [秘密鍵ファイル]  
```

と叩く。このPowerShellも開きっぱなしにしておく。

最後にブラウザで「http:\\\\localhost:8888」にアクセスするとJupyter Notebookです。

暇だったら：
ブラウザで「プロキシサーバアドレス:8888」を叩きます→サーバのファイアウォールが機能します
プロキシサーバを通したブラウザ「研究開発用サーバアドレス:8888」を叩きます→サーバのファイアウォールが機能します

#Q&A
###Q. PowerShellでSSHコマンドがエラー？

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions for 'C:\\key\\test\\test\\KeyFile.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
```
「端末に保存してある秘密鍵のアクセス権限が緩すぎる。だから無視するわ」という意味です。
###A. 秘密鍵をユーザーフォルダ以下に移動する。もしくはファイルのアクセス許可を変更してください。
UNIXでいう「chmod 600 秘密鍵ファイル」みたいなことを要求してきたわけです。
秘密鍵の場所を「%userprofile%」以下にするのが手っ取り早いです。
(もし、ユーザー名が日本語でpowershellでパス指定がエラーになるときはPowerShellのエンコードを変更 https://qiita.com/s4i/items/75c19c9feb10b54c1ce9)
どうしても、C:直下やD:ドライブなどに秘密鍵を置いてやるなら、秘密鍵ファイルを右クリックしてプロパティを開き、必要最低限にアクセス権を絞ります。
↓アクセス権の絞り方

```
[ファイルを右クリック]>[プロパティ]
	{セキュリティ(タブ)}
		(アクセス許可を変更…)の[編集]>[追加]を押す
			[選択するオブジェクト名を入力してください]:kawamasa(ログイン中のwindowsのユーザー名を入力)
			[名前の確認]ボタンを押して:「myPC\kawamasa(ホスト名\ユーザー名)」のように表示されたら
			[OK](編集画面をクローズ)
		[グループ名またはユーザー名]:kawamasa(myPC\kawamasa)と書かれたものを選択
		[フル コントロール]:許可をチェック
		[OK](アクセス許可の画面をクローズ)
	({セキュリティ(タブ)}のまま)
	[詳細設定]の画面を開く
		[継承の無効化]>「このオブジェクトから継承されたアクセス許可をすべて削除します。」
		[OK](詳細設定の画面をクローズ)
[OK](プロパティクローズ)
```
BigQueryでどこかしらの列に含まれる文字列を見つける方法

とある1つの文字列型の列に特定の文字列が含まれている行を抽出する場合、以下のSQLで実現できます。

```sql
SELECT * FROM <テーブル名> WHERE col1 LIKE "%検索したい文字列%"
```

それでは、検索対象の列がテーブルの全てになった場合はどうすればよいでしょうか？
愚直に書くならこのようなSQLになりますが、カラムの数が増えるとSQLを書くのが面倒になります。

```sql
SELECT * FROM <テーブル名> WHERE col1 LIKE "%検索したい文字列%" OR col2 LIKE "%検索したい文字列%" OR ...
```

# 解決策
`CONTAINS_SUBSTR` 関数を使う。

https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#contains_substr

この関数は通常は以下のように文字列を2つ渡して、第一引数の文字列の中に第二引数の文字列が含まれているかどうかを判断するものです。

```sql
SELECT CONTAINS_SUBSTR('hoge fuga piyo', 'fuga') AS result;
# -> TRUE
```

しかし、この関数の第一引数にはテーブルを渡すこともできます。
その場合はそのテーブルの全ての列に対して検索を行い、どこかしらの列に検索対象の文字列が含まれた場合にTRUEを返します。
そのため、以下のSQLで　「どこかしらの列」に含まれる文字列を見つけることができます。

```sql
SELECT * FROM <テーブル名> WHERE CONTAINS_SUBSTR(<テーブル名>, "検索したい文字列")
```
【Volta + GitHub Actions】ワークフロー内での Node.js のバージョン管理を自動化するアクションを作った話


本記事は [GitHub Actions Advent Calendar 2021](https://qiita.com/advent-calendar/2021/github-actions) の7日目の記事です🎅

# 作ったきっかけ
プロダクトを運用していると、定期的に言語やライブラリのバージョンアップ対応が必要になると思います。Volta を使用している場合、Node.js のバージョンを上げる時に必要な作業はこの辺りでしょうか。

- volta pin コマンドを実行して、Node.js のバージョンを上げる
- GitHub Actions で Node.js のバージョンを指定している箇所を修正する
- etc...

複数箇所に Node.js のバージョンが記述されていると、いざバージョンを上げよう！となった時に修正すべきファイルが増えてしまうので、一元管理する方法を検討していました。
そこで、今回は Volta + GitHub Actions を使っている場合に Node.js のバージョンアップ業が少しだけ楽になるアクションを作りました。

#Volta とは
Volta は Node.js などのバージョンを管理するためのツールです。本記事では触れませんが、 Node.js 以外に npm や yarn なども管理することができます。詳細については公式のドキュメントを参照ください。

https://volta.sh/

似たツールとしては nodenv や nvm などがあります。以下の記事が参考になると思います。

https://qiita.com/tora_oba/items/8f8b7d3e5fb62bc96a3f

# 作ったアクション
今回作ったアクションはこちらになります。

https://github.com/marketplace/actions/get-node-version-from-volta

具体的な使い方については後述しますが、 package.json に記述されている Node.js のバージョンを取得することができます。

# 使い方
## Volta をインストール
下記を参考にしつつ、環境に応じてインストールしてください。

https://docs.volta.sh/guide/getting-started

## Volta 経由で Node.js をインストールする
`volta install` コマンドを実行して、任意のバージョンの Node.js をインストールします。

```terminal
volta install node@16.13.0
```

## プロジェクト内で使用する Node.js のバージョンを固定する
次に `volta pin` コマンドを実行します。

```terminal
volta pin node@16.13.0
```

上記を実行することで、package.json に Node.js のバージョンが追記されます。
これで プロジェクト内で使用する Node.js のバージョンが固定されました。

```json
"volta": {
  "node": "16.13.0"
}
```

## get-node-version-from-volta アクションをワークフローに組み込む
ここから [get-node-version-from-volta](https://github.com/marketplace/actions/get-node-version-from-volta) アクションを使用していきます。
ワークフローの steps に下記を追加することで、package.json で指定されている Node.js のバージョンを後続の step で取得できるようになります。ここで指定した id は後続の step で使用します。

```yaml
- name: Get node version from volta
  id: get-node-version
  uses: keita-hino/get-node-version-from-volta@main
```

## Volta で指定した Node.js のバージョンを取得する
今回の場合、`steps.get-node-version.outputs.nodeVersion`から volta で指定した Node.js のバージョンを参照できます。（`get-node-version`には、 uses した時に指定した id が入ります。）
今回は例として、取得した Node.js のバージョンを [setup-nodeアクション](https://github.com/actions/setup-node) に渡します。

これで、`volta pin`コマンドを使って Node.js のバージョンを変えると、ワークフロー内の Node.js のバージョンも自動で追従されるようになるため、ワークフローの修正が不要になります🎉

```yaml
- uses: actions/setup-node@v2
  with:
    node-version: ${{ steps.get-node-version.outputs.nodeVersion }}
```

## 全体像のサンプル
下記のサンプルは Node.js をインストールして終わっていますが、実際には後続の step でテストなどを実行します。

```yaml
name: get node version

on: push

jobs:
  buid:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Get node version from volta
        id: get-node-version
        uses: keita-hino/get-node-version-from-volta@main
      - uses: actions/setup-node@v2
        with:
          node-version: ${{ steps.get-node-version.outputs.nodeVersion }}
...
```

# おわりに
今回は、 Node.js のバージョンを上げる時にワークフローの修正が不要になるアクションを作成しました。まだ実プロダクトで試せてないのですが、今後機会があれば投入してみたいと思っています。もし、Volta を使って Node.js のバージョンを管理している方がいれば使ってみていただけると嬉しいです！🙏

気になった技術について Twitter で雑に呟いているので、よかったらフォローお願いします！[@_kt15_](https://twitter.com/_kt15_)

# 参考
- https://volta.sh
- https://qiita.com/tora_oba/items/8f8b7d3e5fb62bc96a3f
- https://github.com/actions/setup-node
BigQueryの権限を与えているのにPowerBIからクエリを実行すると権限エラーになる

# 発生した現象
PowerBIに対して十分な権限を与えているにも関わらず、以下のエラーが発生しクエリの実行が失敗する。

```
Access Denied: Project XXX: User does not have bigquery.jobs.create permission in project XXX.
```

# 解決策
PowerBIで以下のコマンドを実行。

```
Source = GoogleBigQuery.Database([BillingProject="正しい請求先プロジェクト"])
```

参考

https://docs.microsoft.com/en-us/power-query/connectors/googlebigquery#connect-using-advanced-options

# 解説
BigQueryはコンピュートとストレージが高いレベルで分離されているため、権限を考えるときにもそれらについて考慮する必要があります。
詳細は以下の記事で解説しているので、この先を読む前に一読することをおすすめします。

https://techblog.zozo.com/entry/bigquerys-permission-from-architectural-perspective

問題のエラーには「bigquery.jobs.create」というメッセージが入っているので、このエラーはコンピュートに関する権限が不足していることが分かります。
通常であればBigQueryがどのプロジェクトのコンピュートリソースで集計処理を行うのかはサービスアカウントのJSONファイルや個人アカウントの認証情報などから自動的に決定されます。
しかし、何かしらの拍子にそのプロジェクトが間違ったものに切り替わってしまうことがあります。

そのため、明示的に請求先プロジェクトを指定することによって、適切な権限でBigQueryにクエリを発行するようにしてエラーを解消します。
LinuC303 第1章 暗号化まとめてみた

# 目的
LinuC303 第1章 暗号化を学習の為、簡単にまとめました。

# SNI【Server Name Indication】
1台のサーバ(IPアドレス)で、複数ドメインのSSL証明書を運用する為のものです。

https://knowledge.sakura.ad.jp/3160/

# HSTS【HTTP Strict Transport Security】
Webサーバの設定項目の一つ、Webブラウザに対して2回目以降のアクセスは常にHTTPSによる通信を行うよう指示するものです。

https://e-words.jp/w/HSTS.html

# OCSP【Online Certificate Status Protocol】、OCSP stapling
OCSPとは、SSLサーバ証明書が失効していないか確認するプロトコルです。
これを拡張したものがOCSP staplingで、より短時間でSSLサーバ証明書の状態を確認することができます。

https://rms.ne.jp/sslserver/basis/enabling-ocsp-stapling/

# eCryptfs
ファイル・システムの暗号化を行い、個々のファイルおよびディレクトリの保護にも使用できます。

# dm-crypt
ブロックデバイスの暗号化を行います。

# DNSSEC【DNS Security Extensions】
DNS応答が正しいサーバーから届いたものか検証する仕組み

https://www.nttpc.co.jp/technology/dns_security.html

## DANE【DNS-based Authentication of Named Entities】
読み方は、「でーん」です。

https://www.nic.ad.jp/ja/basics/terms/dane.html

https://college.globalsign.com/blog/dane/
AtCoderをRustでやるのにcargo-compete導入してみた

以下の記事で紹介されているcargo-completeを導入してみてとてもよかったので、最低限使うまでのやることをまとめたいと思います。

https://qiita.com/qryxip/items/bff57848ac9310d27f1a

詳しい使い方は[README.md](https://github.com/qryxip/cargo-compete/blob/master/README-ja.md)が超丁寧に書かれているのでご参照ください。

上から順番にコマンドを入力していけば導入できるようになってるはずです。

## 導入

### cargo competeのインストール

```zsh
cargo install --git https://github.com/qryxip/cargo-compete
```

### 初期化

```zsh
cargo compete init atcoder
```

以下のダイアログがでるので、1-3の数字のいづれかを入力

```
Do you use crates on AtCoder?
1 No
2 Yes
3 Yes, but I submit base64-encoded programs
1..3: 2
```

### AtCoderにログインする

```zsh
cargo compete login atcoder
```

Username/Passwordを入力してログイン

導入は以上！！！

## コンテストごとにやること

### 初期化

```zsh
cargo compete new abc189
```

-> これでディレクトリ作成とテストケースがダウンロードされます。

```zsh
cd abc189
```

### 問題を開く

```zsh
cargo compete open
```

-> ブラウザで問題がひらけます

## 問題ごとにやること

### 問題を解く

以下のようなディレクトリ構造になっているので対応する問題のファイルを実装しましょう。

```
-abc189
 - src
   - bin
     - a.rs
     - b.rs
     - ・・・
```

### テスト実行

```zsh
cargo compete test a
```

※この際自分は少し設定を変更して動きました。一番下に記載

### 提出

```zsh
cargo compete submit a
```

す、すごい・・・！！！！便利すぎて感動しました。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561891/35dc7986-3be1-f075-8ab3-e0a0cda06144.png)



## トラブルシュート

`cargo compete test`で`toolchain`が見つからないよというエラーが出た(うろ覚え)

`compete.toml`を見ると、以下の設定になっていた。

```compete.toml
toolchain = "1.42.0"
```
一方、`rustup show`で確認すると`Default host: aarch64-apple-darwin`と表示されていた。
`compete.toml`の設定値を以下に変更したらうまく動いた

```compete.toml
toolchain = ""
```
【Python3】Streamlitで簡単にWebアプリケーション作成

#Streamlitとは
簡単に言うと、__Webアプリケーションフレームワーク__です。
Streamlitを使用する大きなメリットとしては、
Pythonスクリプトを書くだけで、__アプリケーションの構築__が可能であるということです。
Webアプリケーションを作成する場合は、基本的にはJavaScriptやhtml/CSSでフロント部分の構築が必要になりますが、Streamlitを使用すれば、__Python__のみでWebアプリケーションを作成することができます。
また、Pythonの学習のみを行っていて、フロントエンドに関する知識がまだない方や、簡単にWebアプリケーションを作成してみたいという方にお勧めです。

#インストール方法
以下のコマンドをターミナル上で実行することで、インストールが可能です。

```
$ pip install streamlit
```

#実際にインポートしWebアプリケーションの動きを見る
インストールが完了したら、Pythonスクリプトでコマンドを実行するだけで、アプリケーションの起動ができます。

```py
# streamlitのインポート
import streamlit as st
```

```
# ターミナルに以下のコマンドを入力
$ streamlit run main.py
```

コマンド上にLocal URLとNetwork URLが表示されるので、
Local URLをクリックしブラウザにアクセスすることができていれば起動完了です。

#Streamlitの基礎
Webアプリケーション上に文字を表示させるには以下のコードを入力します。

```py
import streamlit as st
st.title('For Qiita')      # タイトルの表示
st.write('Explain')         
```

実際に実行し、Webアプリケーションを更新すると以下の様に画面に表示することができます。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773587/bd08c93b-a920-bfdd-9b02-498d4c6cdaf2.png)

また、マークダウン記法にも対応しています。
以下の様に、ダブルコーテーション内にマークダウン記法を記述することで、Webアプリケーションに適用することができます。

```py
"""
# Qiita
## Qiita2
### Qiita3
　```
　print('Qiita')
　```
"""
```

実際に実行後の画面です。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773587/87c9cc0b-e66b-48fb-2fd0-bdead452cbeb.png)

#表データの作成

###データフレーム
PandasのDataFrameを用いてデータの可視化を行います。
`st.dataframe`で表データを表示させることができます。
また引数に__width,height__を設定することもでき、表の大きさも自分好みにできます。

```py
import streamlit as st
import pandas as pd

st.title('For Qiita')

# Pandasを使用し、データフレームを作成
df = pd.DataFrame({
    '1St':[1,2,3,4],
    '2nd':[10,11,12,13]
})
# Webアプリケーション上に表示
st.dataframe(df,width=300,height=300)
```

実行後の画面です。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773587/62924659-dfb4-b535-9963-beff09535d9e.png)

実際に表データがWebアプリケーション上に作成されています。

###折れ線グラフ
numpyを使用しランダムな値を取得し、それを折れ線グラフで表示させていきます。

```py
import streamlit as st
import numpy as np
import pandas as pd

st.title('For Qiita')

chart_data = pd.DataFrame(
     np.random.randn(20, 3),
     columns=['a', 'b', 'c']
 )
st.line_chart(chart_data)
```

実行後の画面です。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773587/607d8787-1be3-42be-e608-1c4d97592104.png)

Webアプリケーションに表示されたデータに関しては、画像として保存できたりもするので、とても便利です。

###地図データ

緯度経度を使用し、地図上にプロットしていきます。
今回使用しているのは、大阪府の緯度経度です。
以下、実際のコードです。

```py
import streamlit as st
import numpy as np
import pandas as pd

st.title('For Qiita')

df = pd.DataFrame(
    np.random.rand(100,2)/[50,50] + [34.6,135.5],
    columns=['lat','lon']
)
st.map(df)
```

実行後の画面です。

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1773587/39eed58d-65e1-ae73-bb22-79ecfc25edad.png)

#まとめ
今回紹介したのは、ほんの一部のAPIのみになります。
ですが、別の言語を使用することなく、少ないコードでWebアプリケーションを使用することができました。
Streamlitの公式ドキュメントには、今回紹介できていないものが沢山記載されていますので、興味のある方はドキュメントも参考にしてください。
また、StreamlitとGitを使用することで、Webアプリケーションを公開することも可能ですので、公開したい方は調べてみるのもよいかと思います。
まだまだ、初心者ですが皆様の役に立てれば幸いです。
Google Colaboratory の matplotlib で日本語を使う方法

# インストール、インポート

```python
!pip install japanize-matplotlib
import matplotlib.pyplot as plt
import japanize_matplotlib 
```

# 例 
```python
!pip install japanize-matplotlib
import matplotlib.pyplot as plt
import japanize_matplotlib 
import numpy
from scipy.stats import norm
a_05, a_95 = norm.interval(alpha=0.95)
x_value = 4
x = numpy.linspace(x_value * -1 , x_value, 1000)
x_95 = numpy.linspace(a_95, x_value, 100)
x_05 = numpy.linspace(x_value * -1, a_05, 100)
plt.plot(x, norm.pdf(x))
plt.fill_between(x_95, 0, norm.pdf(x_95), facecolor='lightskyblue', alpha=1)
plt.fill_between(x_05, 0, norm.pdf(x_05), facecolor='lightskyblue', alpha=1)
plt.text(0, 0.45, r'正規分布 両側検定の棄却域（有意水準5％）',horizontalalignment='center')
plt.xlim(x_value * -1, x_value)
plt.ylim(0, 0.5)
plt.show()
```

![matplotlib.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545343/e08725b2-5575-d470-0efb-b3c630f0f1dd.png)
え！！1bitでCPUを！？できらぁ！！

世間ではCPUといえばM1ProチップやM1Maxチップなどの話題が熱いですが、この記事では昔に本当に存在した1bit CPUについて紹介します。

# CPUのビット数とは
そもそもCPUのビット数とはどうやって決まっているのでしょうか？
ビット数と一言で言っても、ALUのビット幅を指しているのかデータバス・アドレスバスのビット幅を指しているのかが曖昧です。
以下の記事によると、次のように書かれています。

> しかしどうやら長い歴史の中で、CPUのbit長はALU長でもなくアドレスバス長でもなく「レジスタ長とデータバス長のうち短い方」である、という常識が生まれたようです。

https://www.saluteweb.net/~oss_1bitcpu.html

そのため、1bit CPUとはレジスタ長もしくはデータバス長が1bitのCPUということになります。

# 実在した1bit CPU
そのような1bit CPUは一見したところで使いみちがなさそうです。
そのため空想上の代物かと思いきや、実は1bit CPUが製品として売り出されていたことがありました。
それがMotorola MC14500Bです。

https://en.wikipedia.org/wiki/Motorola_MC14500B

このCPUは機械式リレーやシーケンサで行われていた処理を置き換えるために開発されたそうです。
このチップが開発された1970年代はUVROMが世に出たばかりで、ROMといえばマスクROMが主流だったかと思います。(その時代に生きていないので間違っていたらご指摘ください)
そのため、小ロットの生産であればわざわざマスクを作成することなく、このCPUと数十個のCMOS　ICでロジックを組むのがコスパが良かったのではないかと推測します。

現在であればEEPROMを内蔵したマイクロプロセッサがあるのでこのチップの存在理由は見つからないです。
実際に1990年代に生産中止になったそうです。

# MC14500Bの内部アーキテクチャ
当時の資料を探していたら、内部アーキテクチャの説明が書かれているドキュメントが見つかったので、それを使って説明をしていきます。

![スクリーンショット 2021-11-28 14.32.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/4a9c8c03-daab-933d-0b90-083b873cbf6c.png)

出典: MC14500B Industrial Control Unit Handbook

MC14500Bは1bit CPUであり、レジスタは図の中央にある1bitのResult Reg.(RR)のみです。
Dataは双方向のデータバスでこれも1bitしかありません。
というか、この図にかかれている線は全て1bitの信号線です。

また、命令セットは次のようになっています。
![スクリーンショット 2021-11-28 15.06.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74551/6d60cb79-f25e-ec18-5763-cbd3360d5376.png)

命令長が4bitもあるから1bit CPUではないといった野暮なことは言ってはいけません。
レジスタ長もデータバス長も1bitなので、これは1bit CPUなんです。

通常のCPUとは異なり加算や減算などの算術命令がないのが特徴的です。
レジスタに対する操作はビット演算しかありません。

さて、このあたりでカンの良い人なら気づいているかもしれませんが、このCPUにはプログラムカウンターが内蔵されていません。
そのため、プログラムカウンタを外付けする必要があります。
さらに、そのプログラムカウンタは通常は4bit以上の幅をもたせて、命令コード以外の残りの部分をオペランドにするのが一般的なようです。
そのため、トータルの命令長を何bitにするかということに関してはこのCPUを使った回路を設計する人次第になります。
この自由度はアドレス幅についても同様です。

さらに命令セットを見ていくとIENやOENというやや特殊な命令も見られます。
これらはそれぞれInput EnableとOutput Enableの略で、Data入力とWrite出力の有効化・無効化を切り替えます。
これらのレジスタを利用すると、簡易的な条件分岐機能が実現できます。

# まとめ
1bit CPUという一見すると使いみちがないようなものでも、過去の歴史を紐解くと実在するということが分かりました。
単なる玩具のようなCPUかと思いきや、シーケンサの置き換えという明確な目的をもって作られたCPUでした。
命令セットは今のCPUと大きく異なりますが、目的を果たすために厳選されたわずか16個の命令は本当によく考えられていると感じました。
【データ分析】伊藤園の株価と気温の関係性を調べてみた

## はじめに
スーパーやコンビニなどで売ってある飲み物は、暑いときほど売れやすい気がしませんか？
その過程が正しいならば、`飲料メーカーの株価は気温が高くなるほど上がりやすいのでは？`と考えました。
そこで今回は飲料メーカー大手の**伊藤園の株価**と**東京の気温**データを用いて関連を調査。

## データ・手法

伊藤園の株価データとしてStooqから１日ごとの**終値**を使用。
Pythonで株価データは簡単に取得可能で、取得方法は[こちら](https://atchicken.com/stooq_download/)に記載。

東京における気温データは[気象庁](https://www.data.jma.go.jp/obd/stats/etrn/select/prefecture00)から**日平均気温**・**最高気温**・**最低気温**を使用。
順序通りに進んでいけば、問題なくダウンロード可能だと思います。

対象期間は2013年１月〜2020年12月までの８年間。
株価データは土日祝などが無いため、欠損値は含めずにデータを使用。

そのデータの相関係数を計算することで、株価と気温に関連があるかを調査。
以下のように解釈可能。

- 相関係数が正：気温が高くなるほど株価が上がりやすい
- 相関係数が負：気温が低くなるほど株価が上がりやすい

これを下記３パターンで実施。

- 平均気温 vs. 終値
- 最高気温 vs. 終値
- 最低気温 vs. 終値

なお、対象期間内の各データの変化はこのような感じ。

![image](https://user-images.githubusercontent.com/93382642/143731788-1bc71f5b-d534-41f6-9db7-ea3266346eae.png)

## 結果

全期間で計算した場合における株価と各気温の相関係数はこのようになりました。

|  vs. 平均気温  |  vs. 最高気温  |  vs. 最低気温  |
| :----: | :----: | :----: |
|  0.044  |  0.059  |  0.039  |



季節ごとにも分けてみました。季節は下記で分類。

- 春：３〜５月
- 夏：６〜８月
- 秋：９〜11月
- 冬：12〜２月

| 季節|  vs. 平均気温  |  vs. 最高気温  |  vs. 最低気温  |
| :----: | :----: | :----: | :----: |
|  春  |  -0.02  |  0.013  |  -0.038  |
|  夏  |  -0.064  |  -0.004  |  -0.098  |
|  秋  |  -0.076  |  -0.044  |  -0.082  |
|  冬  |  0.152  |  0.149  |  0.132  |



## まとめ

今回はあまりうまくいかず。
0.2程度ではとても相関が...とかは言えませんね。
当然と言えば当然ですが、株価はそんな簡単なものでは無いということですね...。


## その他

実装したソースコードはGitHubにも置いています。

https://github.com/khfkd/StockPrice-VS-Temperature
javascript記入中に検証ツールでエラーが出た時の原因

![スクリーンショット 2021-11-28 15.11.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/35234552-a3b9-2be6-d87d-1adba7ee3fa5.png)

この　The value "" for key "width" is invalid, and has been ignored. の原因について。
![スクリーンショット 2021-11-28 15.11.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/3d20a992-3303-d696-a5c2-41bc2cf279fa.png)
問題のHTMLファイルはこれ。。。

shift+1でもう一度HTML雛形を確認してみると

![スクリーンショット 2021-11-28 15.12.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/5b688077-1f1a-6a86-97c3-cc44e3f2d432.png)

widthの後の　device-width が抜けている！！
いつ抜けたのかはわからない笑

抜けた場所にdevice-width,(カンマを忘れずに)を入れると

![スクリーンショット 2021-11-28 15.13.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/e1e57daa-b088-4b37-295e-355be7d7a5bf.png)

エラーがなくなった。
Docker コマンド一覧

#login
**Dokerアカウントにログインするコマンド**

```shell
$ docker login
```

###【`docker for mac` or `docker for windows`をご使用の場合】

1. **dockerアイコン**をクリック
1. **sign in/Create Docker ID**をクリック
1. **Docker ID**と**パスワード**の入力で`ログイン可能`

#run
**dockerイメージからdockerコンテナ一つを起動するコマンド**

```shell
$ docker run <イメージ名>
```

###よく使うオプション

##--name
**コンテナに任意の名前を付ける**

```shell
$ docker run --name <任意の名前> <イメージ名>
```

##-d
**コンテナをバックグランドで動作させる**

```shell
$ docker run -d <イメージ名>
```

##-p
**ホスト上のポートをコンテナ内のポートとマッピング（ポート指定）**

```shell
# 構文
$ docker run -p <ホストポート：コンテナポート> <イメージ名>

# ホスト上の3000番ポートをコンテナ内の80番ポートとマッピングして起動する場合
$ docker run -p 3000:80 docker-image
```

##--rm
**プロセスが終了したコンテナを削除**

```shell
$ docker run --rm <コンテナ名> <イメージ名>
```
#-v
**コンテナにボリュームをマウントして共有するオプション**

```shell
$ docker run -v <ホストのパス:コンテナのパス> <イメージ名>
```

#ps
**起動中のコンテナ一覧を表示するコマンド**

:::note alert
停止中のコンテナは表示されない。表示したい場合は、-aオプションを付ける必要がある
:::

```shell
# 構文
$ docker ps

# 停止中のコンテナ一覧も表示
$ docker ps -a
```

#コンテナの操作
- **コンテナは、`コンテナID`、もしくは`コンテナ名`で指定**
 - **コンテナ一つを操作する**
 - **いずれのコマンドも削除はせず、コンテナは残る**

##start
**dockerコンテナを起動するコマンド**

```shell
$ docker start <コンテナ名>
```

##stop
**dockerコンテナを停止するコマンド**

```shell
$ docker stop <コンテナ名>
```

##restart
**dockerコンテナを再起動するコマンド**

```shell
$ docker restart <コンテナ名>
```

##exec
- **起動中のコンテナ内でコマンドを実行**
 - 起動中のコンテナに入らずコマンドを実行
 - `-it`オプションを使うとコンテナに入ることができる

```shell
# 構文
$ docker exec -it <コンテナ名> /bin/bash

# 出力結果
[root@<コンテナID>/]#

# 終了コマンド
$ exit
```

##rm
**停止中のコンテナを削除するコマンド**

- **注意点**
 - **起動中のコンテナは削除することができない**
 - **コンテナ内のデータも消えるので注意！**

```shell
$ docker rm <コンテナ名>

# 起動中のコンテナを削除する場合
$ docker rm -f <コンテナ名>
```

#images
**ローカルにあるイメージを全て表示するコマンド**

```shell
$ docker images
```

#tag
**イメージ名を変更したい時にオススメのコマンド**

- 既存の`Dockerイメージ`に対して名前を複数付与することができるため、別名を付与した新たなイメージを作成することができる。
 - 同じIDが付与された新イメージが作成されるため、旧イメージは必要なければ削除する。

```shell
docker tag <既存のイメージ名 or イメージID> <新イメージ名>

docker rmi <旧イメージ>
```

##prune

**使用していないイメージ`<none>`を一括で削除するコマンド**

- `docker images`で表示されたイメージの**TAG名**が`<none>`というものは、イメージを再構築して最新のものがある場合に表示される使われていない古いイメージのこと
- 削除することでメモリの消費を抑える

```shell
$ docker image prune

# 実行結果
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
```

##rmi
**Dokerイメージを削除するコマンド**

- **注意点**
 - 起動中コンテナのイメージは削除できない
 - Dockerイメージには依存関係があるので、ベースとなるイメージは削除できない

```shell
$ docker rmi <イメージ名>
```

##build
- **Dockerfileからイメージを生成するコマンド**
 - Dockerfileのパス名はディレクトリ名のみの指定でOK

```shell
$ docker build <Dockerfileのパス名>
```

###-t
**作成するDockerイメージのイメージ名およびタグ名を指定するオプション**

```shell
$ docker build -t <イメージ名:タグ名> <Dockerfileのあるディレクトリ名>
```

##cp
- **コンテナとホストマシンでファイルのやりとりを行うコピーコマンド**
 - ログファイルや設定ファイルの取り出しや入力で使用
 - コマンドの実行はホスト側から行う

```shell
# ホストからコンテナをコピーする場合
$ docker cp <ホストファイルのパス>　<コンテナ名>:<コンテナのパス>

# コンテナからホストへコピーする場合
$ docker cp <コンテナ名>:<コンテナのパス> <ホストファイルのパス>
```

##logs
- **Dockerコンテナのログ出力するコマンド**
 - 原因不明のコンテナ停止やアクセスログを確認する時に使用

```shell
# 構文
$ docker logs <コンテナ名>

# リアルタイムでログを確認する場合
$ docker logs -f <コンテナ名>
```

##参考教材

https://www.udemy.com/course/docker-startup
docker-compose  コマンド一覧

#docker-composeとは
**YAMLファイルという形式の設計図で複数コンテナをまとめて管理することができるDockerアプリケーションのためのツールを指します。**

##build
**Dockerイメージを構築するコマンド**

```shell
docker-compose build
```

* **Dockerファイルを更新した場合**
    * キャッシュが有効になっている場合、そのキャッシュをもとに再構築されることで更新内容がうまく反映されないことがある。そのため、`--no-cache`でキャッシュを無効にしてから構築する必要がある。

```shell
docker-compose build --no-cache
```

##up
**コンテナを起動するコマンド**

* イメージが作成されていない場合、イメージ作成後にコンテナを作成・起動
  * すでにコンテナが存在する場合、イメージ・コンテナの再作成は行わず、停止中のコンテナを起動

```shell
$ docker-compose up
```

###-d
- **コンテナをバックグラウンドで起動するオプション**
 - そのため、同ターミナルでコマンド操作が可能

```shell
$ docker-compose up -d
```

###--build
**Dockerfileの書き換えなどのビルド処理の変更をイメージに反映させるオプション**

- ① イメージ作成から② コンテナイメージの作成・起動を同時に行う
 - ① `docker-compose up`
 - ② `docker-compose build`

```shell
$ docker-compose up --build
```

##down
**docker-compose.ymlで管理されているコンテナを停止＆削除する**

- **カレントディレクトリ**の`docker-compose.yml`のみ適用される
 - 同じ階層に`docker-compose.yml`がない場合は**上の階層を探しに行く**

```shell
$ docker-compose down
```

##restart
**docker-compose.ymlで管理されているコンテナをすべて再起動する**

```shell
$ docker-compose restart
```

##ps
- **docker-compose.ymlで管理しているコンテナ一覧の表示**
 - 対象の`docker-compose.yml`で書かれた**コンテナのみ表示**されるのでコンテナを把握しやすくなる

```shell
$ docker-compose ps
```

##run
- **docker-compose.ymlで管理しているサービス一つを指定してコマンドを実行**
 - build前でも実行可能なコマンドで、フレームワークのインストールなどに使うと便利

```shell
$ docker-compose run <サービス名> <実行したいコマンド>
```

- **Gemがインストールできたのか確認する場合（Ruby on Rails）**
 - `docker-compose.yml`の`services`内に`api`という名前の`Rails API`を設定している前提

```shell
$ docker-compose run api bundle info <Gem名>
```
AfterEffects トランジション　円　作成

#■トランジションの円を作成

![トランジション 円.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558142/1f436eb4-1d0a-eea6-5a74-b9ca124de7c9.gif)


###▼1 円のシェイプを作成。
![スクリーンショット 2021-11-28 14.46.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558142/b5f0727c-0e46-4594-fc67-f0e6fa8de4b8.png)

###▼2 円のシェイプの0秒でスケールを0に
![スクリーンショット 2021-11-28 14.48.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558142/1bd84a5a-cdff-7f31-809b-8e2d42b41495.png)

###▼3 円の25フレームあたりで画面を覆うようにスケールを調整。
![スクリーンショット 2021-11-28 14.49.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558142/847b69b6-f73b-1be6-811e-31fba610e216.png)

###▼4 f9でキーフレームにイージーイーズをかける。
command+shift+k
0秒のキーフレーム出る速度80% 
25フレームのキーフレームの入る速度80%にする。

###▼5 command + Dで複製

複製し三つほど同じの作る。
一つずつ色変える。
一つずつ下から6フレームほど下げる。
![スクリーンショット 2021-11-28 14.58.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558142/4b1cf5e8-9f66-ea51-7330-3b49f824095b.png)

###▼6 プリコンポーズ
シェイプレイヤー3を複製。
これでシェイプレイヤーが4つになる。

シェイプレイヤー1,2,3をプリコンポーズでまとめる。

![スクリーンショット 2021-11-28 15.02.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558142/8b4d21c6-afca-949c-5765-c60802a1c7a5.png)

###▼7 アルファ反転マットに変更
プリコンポーズした円のトラックマットをアルファ反転マットに変更。
シェイプレイヤー4を後ろにずらす。
![スクリーンショット 2021-11-28 15.08.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558142/f31f2820-71e2-9bf8-8ad8-d511e3dd1436.png)


完成。

参考Youtube
https://www.youtube.com/watch?v=pxFLnPPB-R4&t=207s
git ブランチ

<h1>git branch <name> (ブランチ作成)</h1>


<h1>git checkout <name> (ブランチ切り替え) </h1>



<h1>gitを特定のコミットまで戻す方法</h1>
$ git log //戻す対象のハッシュ値を調べる
commit ************************
$ git reset --hard ハッシュ値

<h1>gitローカルの変更を元に戻す方法</h1>
git checkout <filename>
git checkout .
TypeScriptのd.tsでCommonJSスタイルのエクスポートの型を記述する際に引っかかったこと

## CommonJS対応プルリク
https://bitbucket.org/atlassian/atlassian-connect-express/pull-requests/254
https://bitbucket.org/atlassian/atlassian-connect-express/pull-requests/257

## d.tsコードの全貌
```ts
type BearerToken = {
    access_token: string;
};

declare class AddOn {}
declare class HostClient {
    getUserBearerToken: (scopes: string[], clientSettings: AddOnFactory.ClientInfo) => Promise<BearerToken>;
}

declare function AddOnFactory(): AddOn;

declare namespace AddOnFactory {
    export type HostClient = InstanceType<typeof HostClient>;
    export interface ClientInfo {
        key: string
    }
    export type AddOn = InstanceType<typeof AddOn>;
    export type AddOnFactory = typeof AddOnFactory;
    export { BearerToken };
}

export = AddOnFactory;
```

## 使い方
`esModuleInterop`が`false`でも動きます。

```ts
import ace = require('atlassian-connect-express');
import { HostClient, ClientInfo, AddOn, AddOnFactory, BearerToken } from 'atlassian-connect-express';
```

## 説明
今回求められたのは、`module.exports`で関数をエクスポートしつつ、名前付きエクスポートで型をエクスポートすることです。
これを実現するためには、`function`と`namespace`を同名で宣言して、`export = AddOnFactory`構文でエクスポートする必要があります。
また、エクスポートするインターフェースは`namespace`内で宣言すると何回も別名を定義する必要がなく、簡潔です。
`typeof AddOnFactory`は`typeof`付けないと循環参照になってエラーになります。
最後に、`typeof HostClient`と書くと型が`"function"`になってしまうので`InstanceType<typeof HostClient>`と書く必要があります。
これ知らなくて知らない人から怒られました:frowning2:
Python3: cos類似度を計算 (ginza わかちがき)

次のページを参考にしました。
[GiNZAを使って分かち書きをしてみた話](https://qiita.com/yusa87/items/e25e2dcfb1b01fde13a4)

```py:ginza_wakati.py
#! /usr/bin/python
#
#	ginza_wakati.py
#
#						Nov/28/2021
#
# ------------------------------------------------------------------
import sys
import spacy

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

# ------------------------------------------------------------------
def to_wakati_proc(sentence_list):
	nlp = spacy.load('ja_ginza')
	list_aa = list(nlp.pipe(sentence_list))

	docs = []
	for unit_aa in list_aa:
		unit_bb = []
		for word in unit_aa:
			unit_bb.append(str(word))
		text = ' '.join(unit_bb)
		docs.append(text)
#	print(docs)	
#
	return docs
# ------------------------------------------------------------------
def output_proc(sim):
	from_id = 0
	# print('doc_id:', from_id)
	for to_id in range(1,len(docs)):
		print('sim[{0}][{1}] = {2:f}'.format(
			  from_id, to_id, sim[from_id][to_id]))
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

sentence_list = [
        '昔ある所に、王様がいました。',  # 文章A
        'ある所に、かわいい女の子がいました。',  # 文章B
        '一人の王様がいました。',  # 文章C
        '昔ある所に、貧しい女がいました。',  # 文章D
        '昔、王様がある所にいました。',  # 文章E
        ] 


docs = to_wakati_proc(sentence_list)
#
vectorizer = TfidfVectorizer(max_df=0.90) # tf-idfの計算
#                            文書全体の90%以上で出現する単語は無視する

try:
	X = vectorizer.fit_transform(docs)

#	print('feature_names:', vectorizer.get_feature_names())
#	print('X:')
#	print(X.toarray())
	sim = cosine_similarity(X) # 類似度行列の作成
	output_proc(sim)
except Exception as ee:
		sys.stderr.write("*** error *** in vectorizer.fit_transform ***\n")
		sys.stderr.write(str(ee) + "\n")
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行結果

```text
$ ./ginza_wakati.py 
*** 開始 ***
sim[0][1] = 0.238241
sim[0][2] = 0.425818
sim[0][3] = 0.315979
sim[0][4] = 1.000000
*** 終了 ***
```
ドローンでマシュマロキャッチができるまで！

どーもドローン芸人の谷＋１。です
![_B2A1351のコピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330364/40492e4a-338f-d9ab-0776-18258e50d848.jpeg)


僕の芸はドローンを使ってマシュマロをキャッチする芸です。
https://youtu.be/WjO3doUsu6k

ドローン芸で使っているドローンは仏Parrot社が生み出したAR.Drone2.0です。
![IMG_9210.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330364/ed74218c-ca47-ccda-3856-2ae838587bbf.jpeg)


この芸が生まれるまでを解説します。

ドローンネタになるまでの経緯としてはまずラジコンネタをやったことが始まりです。
ラジコンを使って猿回しならぬラジコン回しをネタとしてやりました。
ラジコンに紐をつけお腹に貼ったこんにちわ〜って言葉を紐を引っ張って挨拶させたり綱渡りさせたりしたりあとはラジコンが芸をやらずに機嫌が悪いときは満タンのリポバッテリーあげるからっていうボケも行っていましたｗ自分で操作しているのかよ！っという感じもよかったですねｗ好評でウケました！
しかしお客さんのアンケートで後ろのお客さんがラジコンが下で見えないという意見があり見えないならボツにするしかないな〜とおもってやめちゃいました。
もともとガジェット好きだった僕はAR.Drone2.0を持っていたので浮かせたらみえるかもと今度はドローンをネタに取り入れました。
最初はセンターマイクを置きドローンと漫才をしてドローン突っ込んでいました。
ネタとしてはイマイチだったのですがお客さんのピターッと止まってホバーリングしている感じが不思議だったようで釘付けになり会場が沸きましたｗ
そこでドローンネタいろいろネタ帳に書いて考えていましたがイマイチ思い浮かばずネタ帳の紙を丸めてドローンに乗せて遊んでました。AR.Drone2.0にはクルッと回る機能があって丸めた紙が飛んていったのでこれは何かできるかもと思ったことがきっかけですね！そしてドローンにマシュマロ載せて食べる芸の誕生です！！
どこでどんなアイディアが生まれるかはほんとわかりませんね！

それからドローンでマシュマロキャッチが代名詞となってドローン芸人になりました！！
深層学習ではじめる画像ベクトル化

## はじめに

株式会社じげんの伊崎です。
主に全社データ分析基盤の構築を担当しています。

### 内容について

画像のベクトル化を深層学習で行う方法を説明します。
技術的な説明は最小限にとどめて、とりあえずベクトル化し、使ってみることを目指します。
画像検索や画像を使ったレコメンドに興味のある方に役立つ内容です。
はじめにベクトル化のやり方を書き、その後で使い方の例を書きます。

### 画像について

本記事で扱う画像は著作権フリーのものを使用しています。
1枚目: <a href="https://pixabay.com/ja/users/chiemsee2016-1892688/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1192026">Chiemsee2016</a>による<a href="https://pixabay.com/ja/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1192026">Pixabay</a>からの画像
2枚目: <a href="https://pixabay.com/ja/users/vlaaitje-1637107/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1047521">Ilona Krijgsman</a>による<a href="https://pixabay.com/ja/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1047521">Pixabay</a>からの画像
3枚目: <a href="https://pixabay.com/ja/users/pexels-2286921/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1868911">Pexels</a>による<a href="https://pixabay.com/ja/?utm_source=link-attribution&amp;utm_medium=referral&amp;utm_campaign=image&amp;utm_content=1868911">Pixabay</a>からの画像

## ベクトル化の方法

Kerasの事前学習済みライブラリを使う方法を書きます。
実行環境はGoogle Colaboratory（Colab）です。

```python
import numpy as np
import tensorflow as tf

model = tf.keras.applications.EfficientNetB0(include_top=False, pooling="avg")

def image2vec(image_path):
    raw = tf.io.read_file(image_path)
    image = tf.image.decode_jpeg(raw, channels=3)
    image = tf.image.resize(image, [224, 224])
    vec = model.predict(np.array([image.numpy()]))[0]
    return vec
```

Colabに画像をアップロードし、そのパスに対してimage2vecを実行すると、numpyの1次元配列が返ります。
例えば以下の画像が
![cat-g0f125da90_640.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501334/52cfa7f0-bb08-9a2f-413d-c371d93d33b8.jpeg)
以下のような配列となります。

```python
array([-0.03999095,  1.113671  , -0.13362627, ..., -0.13771635,
       -0.14991407, -0.17145288], dtype=float32)
```

これがベクトル化です。

## 画像ベクトルの使い方

### 画像同士の近さ判定

ベクトル同士の近さを測ることにより、画像の近さを測ることができます。
ベクトルの近さ（コサイン類似度）を測る方法は、以下の記事を参考にさせていただきました。

https://qiita.com/Qiitaman/items/fa393d93ce8e61a857b1

計算すると、最初にベクトル化した画像と以下の画像の類似度が0.021059312とわかります。
![puppy-g2ab92e08c_640.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501334/711c7cc4-3f7c-a9c2-b07a-0914fe30b87c.jpeg)
続いて、最初の画像と以下の画像を比べると、類似度は0.11230692となります。
![tiger-g2d648ccdb_640.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501334/0d4e473c-3c71-e3db-b5b5-83bbaab69245.jpeg)
猫と犬より、猫とトラのほうが近いという結果になりました。

### 画像検索

上の例では2枚の画像を比較しました。
大量の画像を用意し、ある1枚の画像とそれぞれの画像との類似度を測ることで、画像を類似度順に並べることができます。
これにより、画像検索が実現できます。
こちらに関しては、以下の記事に詳しく記載されています。

https://www.nogawanogawa.com/entry/image_search

### 画像によるレコメンド

ある商品を見ているユーザーに対し、上記の手法で類似した商品を提示することでレコメンドが実装できます。
さらに、ユーザー行動をもとにした高度なレコメンドを実装する際にも、しばしば画像のベクトルが使われます。
こちらに関しては、以下の記事に詳しく記載されています。

https://techblog.zozo.com/entry/visual_recommend

## ごく簡単な解説

ベクトル化の過程をひとことで言うと
「画像分類の仕方を事前に学習したモデルに、特徴量（ベクトル）の取り出しだけさせる」
ということをやっています。

## 終わりに

駆け足でベクトル化について書きました。
画像ベクトル化の有用さを少しでも感じていただけたら嬉しいです。
機械エンジニアからエンジニアになってみて

機械エンジニアからエンジニアに転職して1年が経つ者です。
どういう境遇の方が読むかわかりませんが、もしエンジニアを目指している方がいれば、背中を押せるような記事になればと思いまとめます。

自分は自動車メーカーで品質管理を行なっていましたが、不満が3つありエンジニアに転身しました。
ここではエンジニアになってみて、その不満が解消されたのか？に加えて、エンジニアとして働くとあった嬉しいことについても書きます。

エンジニアと言っても働き方は会社によって大きく違うかと思います。自分の勤務先は従業員数100未満のWebベンチャーなので、そこを踏まえてお読みください。

# 前職の不満と現在

|前職の不満|転職して解消されたか  |
|---|---|
|仕事が楽しくない|○
|人材価値が上がらない|○
|住む場所が限定される|○

概ね解消されました。

# 詳しく

## 仕事が楽しくなった

仕事がつまらない原因の一つは、何にも貢献できていない感だと思っていて、当時はこれに陥っていました。
製品化のフローが細分化されすぎていて、製品に自分の仕事の形跡が見えなかったからです。

現職では、手掛けた部分のサービスは目に見えて変化するし、自分が提案&実装しなければ存在しない機能もあり、自分の存在意義を感じます。

## 人材価値が上がりそう
人生に使命があるタイプではなので、仕事選びは如何に食っていけるかが重要です。自分の技術を求める企業が多いほど良いと思っているので、やはりエンジニアは優秀です（いつまでこの状態が続くかは懸念点ですが）。

また言語や技術の移り変わりも気にはしていましたが、一度エンジニアとして働いた人間が他言語を習得するのは、それほどコストは高くないと感じています。

## 住む場所が限定されない
エンジニアは業態によると思いますが、Web系はリモートで問題なく仕事ができます。
自分は低気圧だと生産性が落ちるので東南アジアに住んでいましたが、住む国も選べる職業は未だ少ないはずです。

# エンジニアになって気づいた意外な良さ
## 先輩社員にもリスペクトされる
会社は、入社が早ければ無条件で偉いという風潮がありますが、それが一切ないです。
チームには営業やマーケと言った非エンジニアがいます。彼らはいくら社会人経験が上でも、こちらをプロのエンジニアとして頼り、接してくれます。こちらももちろんリスペクトして接します。
この関係がすごく健全で、居心地が良いです。

## 社会的地位がある
無職の時期があったからこそ思いますが、とても楽です。一度、社会的地位が無い人だとジャッジされると、他人に信頼してもらうのに労力がかかり面倒です。
エンジニアは、初対面の人から「安定していて、そこそこ稼いで、真面目」だと思われます。

## 人間関係で疲れない
人間の一番の悩みの原因は人間関係だと聞きます。実務は自分の世界に没頭しているので、この悩みは消えました。
一方反動でコミュニケーションが苦手になった気がします。トイレで同僚にあったときの会話はかなり難しい。。

# 今後の目指したいエンジニア像
最後に。
エンジニアの中にはプログラミングが好きでやっている人たちもいますが、自分はその一員では無いので、勝てるように差別化が必要かなあと思っています。
如何に売り上げを上げられるかと、顧客に信頼されるかが企業の目的な訳で、それゴールに据えてエンジニアの視点での提案ができるエンジニアをやろうと日々もがいています。
ICカード 磁気カードについて

## 勉強前イメージ

確かにICOCAはICカードだけど、他の定期は磁気カード。。。
ただ違いはちゃんと言えないなぁ
情報量とかも違うんだろうね。

## 調査

### ICカード とは

カードにICチップが入ったカードで、様々な規格があります。
FelicaやMifareなどが使われています。
当初は高価なためなかなか普及しなかったですが、だんだん普及してきました。
磁気カードより情報量が多く、セキュリティ性が高いのが特徴です。
種類として `接触式ICカード` と `非接触ICカード` があります。

### ICカードの種類

- 接触式ICカード

見た目としては以下のようにチップが露出しており、
ICチップは端子を介しデータのやり取りを行います。
リーダー、ライターに差し込み書き換えなど行います。

![12021-11-28 # ICカード 磁気カードについて - diagrams.net - Goog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/93955438-6c29-17f6-1e0e-5a7699ed194c.png)


- 非接触式ICカード

見た目としては、チップが内蔵されており見えないカードになります。
リーダー、ライターと接触して電波を利用して電力を供給し書き換えを行います。

![22021-11-28 # ICカード 磁気カードについて - diagrams.net - Goog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/7347e7bd-5554-d188-d830-9d2be85b0111.png)


### 磁気カード とは

磁気カードとは磁気ストライプの中に情報を符号化できるカードのことで、専用端末を利用して書き換えなど行います。
多くの場所で磁気カードが使われているのは、ICカードの半分以下という安さで運用することができます。
カセットやビデオ同様、磁気の+-を利用して情報を記録します。
日本で流通しているのはほとんどがJIS Ⅱというもので、72バイトのメモリ容量です。
ICカードより少ないですが、情報が少なくても問題ないときに使われています。

### 磁気カードの種類

- 時期ストライプカード

少し古いキャッシュカードやクレジットカードなどで使われていました。
以下のように磁気テープが見た目として見られます。

![32021-11-28 # ICカード 磁気カードについて - diagrams.net - Goog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/c0328556-f9d6-c020-99a5-c6fc078f8d6d.png)

- 全面磁気カード

裏面が磁性体で覆われている薄手のカードで、書き込める情報量は磁気ストライプと同じです。
しかし、磁気ストライプカードより安く、折り曲げに強いのが特徴です。

![42021-11-28 # ICカード 磁気カードについて - diagrams.net - Goog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/c857f91f-8e0f-29e0-47b9-78f10b8be4c6.png)

### ICカードと磁気カードの違い

|   \  |  ICカード   |  磁気カード   | 
| --- | --- | --- | 
|  概要   |  ICチップを使用   |  磁気を使用   | 
|  データ容量   |  多い   |   少ない  | 
|  セキュリティ性  |  中～高   |  中～低   | 
|  1枚あたりの価格   |  約120円程度   |  約80円程度   | 

※価格等は参考にしたサイトにて

## 勉強後イメージ

最近はなんでもICカードに移行していってる
でも、スーパーのポイントとか安いから結構磁気カードなのかな

## 参考

- [ICカードと磁気カードの違いについて](https://www.kenbisha-iccard.com/blog/ic_16/)
- [カード解説](http://web.sanwa-newtec.co.jp/card/card_step1/)
Notionを使ってTwitter予約投稿に近いものを作ってみた

# Notionを使ってTwitter予約投稿したい
最近になって、Notionにハマりました。
一通り習得して考えたのが、**Notionを使用してTwitterの予約投稿が簡単に出来ないか**、ということでした。
調べてみると、なんとか出来そうだったのでチャレンジしてみました！

# 全体の構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646663/87954422-ef96-7df7-0de0-19c659bcfc26.png)
※ ちなみに、**無料プランでなんとか出来ないか？**を追及しているので、制限のある中での連携であることをご了承ください。
<dl>
<dt>今までの作業フロー</dt>
<dd>１．スプレッドシートのテンプレートを修正してざっくり投稿内容を作成。
２．Twitterの予約投稿画面を開く。
３．投稿日時を設定して投稿内容をスプレッドシートからコピー＆ペースト。
４．上記コピー＆ペーストを何回か繰り返す。
５．予約投稿の日時と内容を見直して完了。<br>
<strong>【メリット】</strong>
　　Twitterの予約投稿は何個も設定可能。
　　使用ツールが少なくて済む。
　　スプレッドシートの関数が得意な人はテンプレートをカスタマイズしやすい。<br>
<strong>【デメリット】</strong>
　　予約投稿の手順は手間がかかる。（たまに誤爆発生）
　　日付設定の操作が面倒。（初期値の設定・プルダウンでの選択）
　　未送信ツイートの予約済みの一覧が見づらく、確認漏れによる誤爆が発生。
</dd>
<dt>今回の作業フロー</dt>
<dd>１．Notionのテンプレートを修正してざっくり投稿内容を作成。
２．Automate.ioの自動連携をONにする。
３．Notionの投稿したい内容のチェックボックスを入れて投稿。
４．Bufferを開いて文章や投稿時間を微調整。
５．あとはBufferが予定日時に自動投稿してくれる。<br>
<strong>【メリット】</strong>
　　投稿内容のコピー＆ペーストの手間が省ける。
　　Bufferの予約投稿の一覧が見やすく、間違えにくい。<br>
<strong>【デメリット】</strong>
　　無料プランだと機能が制限される。
　　Automate.ioの自動連携のBotを毎回ON/OFFする必要がある。（誤爆防止）
　　それぞれのツールの使い方を、ある程度覚える必要がある。
</dd>
</dl>

# 設定手順
それぞれの設定の概要を説明していきます。

## Notion
こちらで、Twitter投稿用のデータベースを作成します。
それぞれの設定方法は割愛しますが、以下のようなデータベースを作成していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646663/bf52c312-50b9-d73f-4de1-4a57e5b93860.png)
文章は、Notionで使用できる関数で連結して、一番左側の**［投稿内容］**の欄に表示するようにしています。
投稿するかどうかは、左側２列目の**［Tweet］**のチェックボックスで調整します。
左側３列目以降は、［投稿内容］を調整するための文章推敲欄や自分用のメモ欄になっています。

## Buffer
アカウントを作成して、初期値を修正します。
何時間かおきに投稿する設定になっているので、不要な投稿時間を削除しておきます。
また、自分が確認しやすい時間帯に一旦変更しておきます。
ちなみに今回は無料プランを使用しているので、**自動投稿の登録**は**10個**までとなっています。 

## Automate.io
アカウントを作って、NotionとBufferの連携Botを作成していきます。
最初にNotionとAutomate.ioを連携してデータベースをつなぎます。
トリガー(自動連携するタイミング)は、データベースが更新された場合で設定しておきます。
次にBufferとAutomate.ioを連携して自動投稿する設定をします。
新規追加する設定にして、[投稿内容]のデータを投稿する設定にします。
ちなみに今回は無料プランを使用しているので、以下の制限がかかっています。

* アクションの回数が **300回/月**
* １対１の連携の作成は**５つ**まで
* 自動連携のチェック間隔は**５分**ごと

更新するたびに自動投稿してしまうことで起きる誤爆の防止と、月のアクション回数が制限されていることがあるため、Botを使用する際にONするようにした方がいいかもしれません。もちろん使用後はOFFするようにしておきます。

# まとめ
<dl>
<dt>１．それらしいものは作れた！</dt>
<dd>Notionだけですべてが完了するようにしたかったが、一番めんどくさいと感じていた、<strong>コピー＆ペーストの効率化</strong>と<strong>予約投稿日時の間違い削減</strong>が達成できたのでよかった。</dd><br>
<dt>２．Bufferを有料にすればもっと便利にはなりそう。</dt>
<dd>予約投稿の制限があるのがツライ。<br>かといって有料にするほどでもないので、どうにかならないか今後も検討していきたい。</dd><br>
<dt>３．各ツールの今後の機能のアップデート次第では、別の方法が思いつくかも！</dt>
<dd>各ツールの今後に期待したいところ。もちろん他ツールで実現可能であれば研究していきたい。</dd>
</dl>
Python3: cos類似度を計算 (janome わかちがき)

次のページを参考にしました。
[Python, Janomeで日本語の形態素解析、分かち書き（単語分割）](https://note.nkmk.me/python-janome-tutorial/)

```py:janome_wakati.py
#! /usr/bin/python
#
#	janome_wakati.py
#
#						Nov/28/2021
#
# ------------------------------------------------------------------
import sys
from janome.tokenizer import Tokenizer

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

# ------------------------------------------------------------------
def to_wakati_proc(sentence_list):
	tk = Tokenizer()

	docs=[]
	for it in range(len(sentence_list)):
		result = list(tk.tokenize(sentence_list[it], wakati=True))
#		print(it,len(result))
#		print(result)
		text = ' '.join(result)
		docs.append(text)
#
	return docs
# ------------------------------------------------------------------
def output_proc(sim):
	from_id = 0
	# print('doc_id:', from_id)
	for to_id in range(1,len(docs)):
		print('sim[{0}][{1}] = {2:f}'.format(
			  from_id, to_id, sim[from_id][to_id]))
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

sentence_list = [
        '昔ある所に、王様がいました。',  # 文章A
        'ある所に、かわいい女の子がいました。',  # 文章B
        '一人の王様がいました。',  # 文章C
        '昔ある所に、貧しい女がいました。',  # 文章D
        '昔、王様がある所にいました。',  # 文章E
        ] 


docs = to_wakati_proc(sentence_list)
#
vectorizer = TfidfVectorizer(max_df=0.90) # tf-idfの計算
#                            文書全体の90%以上で出現する単語は無視する

try:
	X = vectorizer.fit_transform(docs)

#	print('feature_names:', vectorizer.get_feature_names())
#	print('X:')
#	print(X.toarray())
	sim = cosine_similarity(X) # 類似度行列の作成
	output_proc(sim)
except Exception as ee:
		sys.stderr.write("*** error *** in vectorizer.fit_transform ***\n")
		sys.stderr.write(str(ee) + "\n")
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

実行結果

```text
$ ./janome_wakati.py 
*** 開始 ***
sim[0][1] = 0.238241
sim[0][2] = 0.765241
sim[0][3] = 0.315979
sim[0][4] = 1.000000
*** 終了 ***
```
Python 数値

#はじめに
動くコードは書けるが、基礎となる部分が曖昧だったのでまとめることにしました。
Python 3.8.2
https://github.com/Hirakawa0123/python_learning/blob/main/syntax/how_to_numbers.py
#整数
整数とは、-1,0,10などの数
小数点を含まない数値のこと
正の整数は「自然数」という

整数の計算

```python:how_to_numbers.py
a = 10
b = 0
c = -1

ans = a + b + c
print(ans)
```

出力結果

```
9
```

#浮動小数点数
浮動小数点数とは、-49.3,0.1,23.345などの数
小数点を含む数値のこと

浮動小数点数の計算

```python:how_to_numbers.py
a = 0.1
b = 23.345
c = -49.3

ans = a + b + c
print(ans)
```

出力結果

```
-25.854999999999997
```

#整数と浮動小数点数の計算
整数と浮動小数点数の計算は、結果が浮動小数点数で表示される

```python:how_to_numbers.py
a = 10
b = -49.3
ans = a + b
print(ans)

a = 0.9
b = 0.1
ans = a + b
print(ans)

a = 100
b = 0.1
ans = a * b
print(ans)
```
出力結果

```
-39.3
1.0
10.0
```
#数値を丸める

出力結果の浮動小数点数を丸める際は、roundを使用します。
round(n,2)とするとnを小数点2位に丸めるという意味になります。

roundの動きに関しては公式ドキュメントをチェック
https://docs.python.org/ja/3/library/functions.html?highlight=round#round
>
注釈 浮動小数点数に対する round() の振る舞いは意外なものかもしれません
: 例えば、 round(2.675, 2) は予想通りの 2.68 ではなく 2.67 を与えます。
これはバグではありません: これはほとんどの小数が浮動小数点数で正確に表せないことの結果です。
詳しくは 浮動小数点演算、その問題と制限 を参照してください。

```python:how_to_numbers.py
n = 3.1415926535

print(n)
print(round(n))
print(round(n,2))
```

出力結果

```
3.1415926535
3
3.14
````


#四捨五入
:::note warn
これ以降の内容確認中です。
間違いやドキュメントのここ読めばわかる等ありましたらコメントいただければ助かります。
:::

decimalをインポートします。
正確に四捨五入するには、decimaiにstr型で数字を渡してからroundすること
※strで渡さないと別の結果になるので注意

```python:how_to_numbers.py
from decimal import *

num = Decimal("2.675")
print(type(num))
print(round(num, 2))

num = Decimal(2.675)
print(type(num))
print(round(num, 2))

num = 2.675
print(type(num))
print(round(num, 2))
```

出力結果

```
<class 'decimal.Decimal'>
2.68
<class 'decimal.Decimal'>
2.67
<class 'float'>
2.67
```

#切り上げ、切り捨て
mathをインポートします。
ceilは切り上げ、floorは切り捨て

```python:how_to_numbers.py
import math

n = 3.1415926535
n2 = -3.1415926535

print(math.ceil(n))
print(math.floor(n))

print(math.ceil(n2))
print(math.floor(n2))
```

出力結果

```
4
3
-3
-4
```
以上
知ってるとドヤれる(?) Django(Python)で使える小技でコードをスッキリさせよう！

Djangoでアプリケーション開発をしていると、死ぬほど`self`や、`request`を書くかと思います。

↓これくらいのコード量ならまだしも、書く量が増えていくほど省略できるものは省略しちゃいたいですよね。

```python
class createPost(View):
    def post(self, request):
        self.title = request.POST.get('title') 
        self.body = request.POST.get('body')
        post = Post(
            title=self.title,
            body=self.body
        )
        post.save()
        return redirect('index')
```

そんな時は `=`を2つ使って1行でこう書いちゃいましょう！

```python
class createPost(View):
    def post(self, request):
        self.title = title = request.POST.get('title') 
        self.body = body = request.POST.get('body')
        post = Post(
            title=title,
            body=body
        )
        post.save()
        return redirect('index')
```

地味ながらもスッキリしていいのではないのでしょうか笑

以前までの自分の知識だと、

```python
self.title = request.POST.get('title') 
title = self.title
```

という具合に2行に渡ってしまうため、
わざわざ変数に入れると行数が増えてしまっていました。

しかしながら`self.title = title = request.POST.get('title') `という書き方であれば、
1行でrequestの内容をそのまま変数に格納することが出来るので便利ですね！
php artisan migrate:refreshでMigration not found:になる

##環境
laravel6.20.37
##エラー内容
```
$ php artisan migrate:refresh

Migration not found: 2021_11_28_041826_create_likess_table

```
##原因
DBにmigrationが保存されているため

```
mysql> SELECT * FROM migrations;

+----+---------------------------------------+-------+
| id | migration                             | batch |
+----+---------------------------------------+-------+
| 18 | 2021_11_28_041826_create_likess_table |     1 |
+----+---------------------------------------+-------+
1 row in set (0.00 sec)
```
migration削除

```
mysql> delete from migrations where batch = 1;
```

##参考

https://nanaco-programming.hatenablog.com/entry/2016/04/12/001550
【Vuex】ミューテーションの利用

#はじめに
こんにちは！
今回は【Vuex】ミューテーションの利用についてアウトプットしていきます！


#mutationsとは
ミューテーション（mutations）とはVuexのストアの状態を変更したいときに使うものです。分かりやすくいうとハンドラに近いものです。

#記述法

前記事の続きの内容でアウトプットしていきます。

```store/index.js
const createStore = () => {
    return new Vuex.Store({
        //⏬stateに値を保管する処理 
        state: function() {
            return {
                message: 'Hello Vuex!'
            }
        },
        mutations:{
            updateMessage: function(state){
                // ⏬state.messageを書き換える処理
                state.message = 'Updated!'
            }
        }
    })
}
```

```pages/index.vue
<template>
  <section class="container">
    <div>
          <!--⏬storeフォルダのstateの値messageを利用することができる-->
        <p>{{ $store.state.message }}</p>
        <!--buttonをクリックすると指定したmutationsがstore側に送られ記述した処理が行われる-->
        <button v-on:click="$store.commit('updateMessage')">Update</button>
    </div>
  </section>
</template>
```

index.jsに`state`に続き`mutations`を作り、state.messageを書き換える処理を記述します。
index.vue（テンプレート側）ではbuttonをクリックすると指定したmutationsがstore側に送られ記述した処理が行われるといったように記述します。

![スクリーンショット 2021-11-09 6.17.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/57ffe854-083b-1c84-8386-a512b26b0145.png)

`state`で記述し`<p>{{ $store.state.message }}</p>`で表示させていた部分が、

![スクリーンショット 2021-11-09 6.17.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/108c7ceb-c662-3314-35ff-a50e4658c339.png)

このように`mutations`の処理内容に書き換えられています。

#値渡し
ミューテーションで値渡しする方法を記述します。

```store/index.js
mutations:{
   updateMessage: function(state,payload){
      state.message = payload
   }
}
```

```pages/index.vue
<!--⏬mutationsに値を渡すにはcommitメソッドに追加の引数を渡す。追加の引数は特定のmutationsに対する(paylod)と呼ぶ-->
<button v-on:click="$store.commit('updateMessage','Commit with payload')">Update</button>
```

ミューテーションで値を渡したいときは、`commit`メソッドの第２引数に渡したい値を入れ、`mutations`側の第２引数で値を受け取り、利用する記述を書くことで値を渡すことができます。

![スクリーンショット 2021-11-09 6.34.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2114750/9d3b8430-3f08-c9d1-3536-02d76ba02ef4.png)

このように書きかわります。



#最後に
今回はミューテーションの利用についてアウトプットしました。
今回の記事を読んで質問、間違い等あればコメント等頂けると幸いです。

今後ともQiitaにてアウトプットしていきます！

最後までご愛読ありがとうございました！
Python_timeモジュール

# timeモジュール
Pyhtonの時間に関する関数が使用できるbuild in moduleである。

# unixtimeを取得する
unixtimeとは1970/01/01からの秒数のことである。

```py
import time

print(time.time())
```
> 1638073472.6348443

# 実行時間を計測する

```py
import time

before = time.time()
~~~計測したいプログラム~~~
after = time.time()
print(f"{after-before}秒")
```
> 0.00014710426330566406秒

# .sleep(sec) 実行まで指定した秒数待機する

```py
before = time.time()
time.sleep(10)
after = time.time()
print(f"{after-before:.2f}秒")
```
> 10.01秒


# デコレーターにする

```py
import time
from functools import wraps

def stop_watch(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"実行時間(sec)：{time.time()-start:2f}")
        return result
    return wrapper


@stop_watch
def my_sleep(sec):
    time.sleep(sec)
    print(f"{sec}秒待ちました")


my_sleep(10)
```
> 10秒待ちました
実行時間(sec)：10.017276