OmniAICreator/Qiita-1.07M huggingface dataset:
Laravelインストール手順

#Laravelとは
Laravelは、フルスタックなPHPフレームワークで、ルーティング、コントローラ、ビュー、ORMなど基本的な機能を備え、さらに近代的なWebアプリで活用されるジョブキューやWebストレージなども積極的に統合している。

MITライセンスの下でリリースされており、そのソースコードはGitHubにホスティングされている。

#Laravelインストールの流れ
composerをインストール。
composerを使ってLaravelをインストール。

#composerとは
PHP用のパッケージを管理するためのツール

#composerのインストール
ComposerをPHPのパッケージ管理システムをインストールします。

```
$ curl -sS https://getcomposer.org/installer | php
```

composer.pharが存在する階層にいる場合、composerコマンドが使える。
どこでもcomposerコマンドが使えるようにcomposer.pharを下記のとする。

```
$ mv composer.phar /usr/local/bin/composer
```

移動後、ターミナルで

```
$ composer --version
```

コマンドを実行しバージョン番号を確認します。

#Laravelのインストール
Composerで専用インストーラをインストールします。

```
$ composer global require "laravel/installer=~1.1"
```

Laravelコマンドが実行できるように、~/.composer/vendor/bin
（Windowsの場合は、C:\%HOMEPATH%\AppData\Roaming\Composer\vendor\bin）
ディレクトリにPATHを通します。

```
$ export PATH="$PATH:~/.composer/vendor/bin"
```

以下のようにコマンド１つでLaravelプロジェクトが作成できます。

```
$ laravel new [プロジェクト名]
```

#動作確認

プロジェクトのルート（プロジェクト名）に移動し、

```
$ php artisan serve
```

を実行すると、

```
Laravel development server started on http://localhost:8000/
```

と表示されるので、ブラウザでhttp://localhost:8000/ にアクセスしてみます。


![laravel.png](https://camo.qiitausercontent.com/07dbe2ffe1af8a104f779f2485cbc0c52f68ad2d/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3135313130362f66313561643637322d663235662d623938382d343334302d6338623231643864313736352e706e67)


このような画面が表示されれば、環境構築完了。

#Laravel IDE補完機能をインストールする


```
$ composer require --dev barryvdh/laravel-ide-helper

Package manifest generated successfully.
```
Modelプロパティの補完

```
$ composer require --dev doctrine/dbal

Package manifest generated successfully.
```

Facadeプロパティの補完

```
$ php artisan ide-helper:generate

A new helper file was written to _ide_helper.php
```

modelファイルに書き込む場合`yes`
別ファイルで作成する場合`no`

```
$ php artisan ide-helper:models --dir="path/to/models" --dir="app/src/Model"

 Do you want to overwrite the existing model files? Choose no to write to _ide_helper_models.php instead? (Yes/No):  (yes/no) [no]:


Written new phpDocBlock to /********
```
【Ruby】配列をループしている合間に二重配列にしていく

やろうとするたびに忘れるので，めも

```sample.rb
#hogeはお好きなように
array.map{|word|[word,hoge]}
#array.map{|word|[word,hoge]} 冗長
```

ループしているうちに配列が前の方から次々と二重配列になっていく．
適宜，書き直してください．
他の処理も追加できます．
コードが汚いので，もっといい方法あったら教えてください．
MySQL5.7でsudo無しでrootログイン

MySQL5.7では__sudoを使用しないとrootユーザーでログインできません__。（これで最初かなりハマりました）

外部公開するサーバーとかでは適切な設定なのですが、vagrantとかで開発環境で利用するには不便です。

そこでsudo無しでもログインできるようにする方法を紹介します。（ubuntu18を前提に記述しています）

# インストール直後にする操作

## mysql_secure_installationの実行

インストール直後にmysql_secure_installationを実行します。（これしないとパスワード設定できないので）

```
sudo mysql_secure_installation
```

## VALIDATE PASSWORD PLUGINの無効化

MySQL5.7では簡易なパスワードを設定できなくする__VALIDATE PASSWORD PLUGIN__というものがあるのですが、これも開発環境では面倒なのでOFFにします。

mysql_secure_installationを実行すると下記のように聞かれますのでyとかYes以外の適当な文字を入力してEnterを押します。（下記ではNoを入力してます）

```
VALIDATE PASSWORD PLUGIN can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No: No
```

## パスワードの設定

次に聞かれるのがパスワードです。
ここで設定したパスワードがrootユーザーのパスワードになるので覚えておいてください。

```
Please set the password for root here.
New password:
```

もう一回入力しろと言われるのでもう一回同じパスワードを入力します。

```
Re-enter new password:
```

これ以降の質問は__y__を入力してEnter押していけばとりあえずは大丈夫です。

# sudo以外でもrootログインできるようにする

ここからついにrootログインできるように設定していきます。

## MySQLにログイン
まずはsudoでログインします

```
sudo mysql -uroot -p
```

上記コマンドを入力するとパスワードを求められるので、__パスワードの設定__で設定したパスワードを入力します。

## MySQLでの操作
MySQLにログインできたら下記コマンドを実行します。
最後の方の__password__の部分は__パスワードの設定__で設定したパスワードを入力します。

```
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
```

次に設定を反映するコマンドを実行します。

```
FLUSH PRIVILEGES;
```

これで完了です。
後は

```
quite;
```
でログアウトして
```
mysql -uroot -p
```
でsudoなしで設定したパスワードでログインできれば成功です。
Bootstrap で 文字 の 太さ を 設定

## 〜宣伝〜

:::note info
個人開発でエンジニア専門マッチングサービスを開発しましたので、是非未経験からエンジニア目指している人！現役エンジニアで教えたい人！使ってみてください！

β版リリース記念キャンペーン中です！

10名様限定、抽選でお好きな技術本1冊プレゼント！
🎉当選者にはメッセージ差し上げます(送付の際に住所はお聞きしません)
詳しくはこちらから↓

https://x.com/dokupro01/status/1796837336145436846
:::
https://dokupro.dev/

## 目的

Bootstrapを用いてCSSでの設定のfont-weightプロパティと同じ表示にする方法をまとめる。 

## 前提条件

- Bootstrapの設定が読み込まれるようになっている
- Bootstrapのテンプレートを使用してHTMLファイルをコーディングしている。  
※Bootstrapの設定を反映させるためのテンプレートは[こちら](https://getbootstrap.jp/docs/4.2/getting-started/introduction/)のスターターテンプレート内のコードをコピーする。

## 押さえるポイント

- Bootstrapで既に定義された内容を設定したい時はHTMLファイルのクラス名に定義名を記載する。
- 通常の文字を太字に設定するときはクラス名にfont-weight-boldを追加する。
- 太字を細字に設定するときはクラス名にfont-weight-normalを追加する。

## 書き方の例

- p要素のテキストを太字に設定する。
- 下記にHTMLファイルの内容を記載する。

``` html
<p class="font-weight-bold">おはようございます。</p>
```

- h1要素のテキストを細字に設定する。
- 下記にHTMLファイルの内容を記載する。

``` html
<h1 class="font-weight-normal">おはようございます。</h1>
```
ApplicationInsightsのjavaagentを仕込んで実行されたSQLをトレース

ドキュメントにある内容をやっただけです。

https://docs.microsoft.com/ja-jp/azure/azure-monitor/app/java-agent

こんな感じになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52527/99a698da-da33-996b-3c79-1d98b6cfc368.png)

黒塗りばかりのこの画像は所要時間が5分かかった謎のリクエストを調べたときのものです。
4回SQLクエリが実行されている様子と、2個ほどクソクエリがある様子が分かります。クエリのどれかをクリックすると、右のコマンドにSQLが出てきます。

SQLの内容はPreparedStatementを使っているためかPreparedなSQLになっており、パラメータは「?」になっているまでは見れないようです。（逆に埋められても機密情報が見えかねないのでこれはこれで良いと思います）
呼び出されたコードの位置もわかりません。でも実装者なら十分役立つことでしょう。

もちろん、DBクエリの情報をApplicationInsightsに送るため、転送量がかかるのでその点は注意してください。

### 前提

- Javaアプリ
- ApplicationInsightsは導入済み


### 仕組み

JavaAgentを使って、クラスローダでクラスを読み込む際にクラスファイルに手を加え、テレメトリを書き出す仕組みになっているようです。

JavaAgentを組み込むだけでよいので、動いているコードには手を加えずに利用できます。


導入
----------------

- javaagentファイルをダウンロード
- 同じ場所にAI-Agent.xmlを作成
- JVM引数に`-javaagent:...`を追加
- アプリケーション再起動

導入手順はAzure WebApp上を想定していますが、JavaのWebアプリケーションならAzure WebAppに限らずちょっと読み替えるだけで導入できます。


### ApplicationInsightsのjavaagentを導入する

https://github.com/microsoft/ApplicationInsights-Java/releases/ で公開されているので、導入済みの**ApplicationInsightsのバージョンにあったagent**を入れます。

Azure WebAppなら、kudu上でこんな感じに操作。`D:\home\data` 辺りなら邪魔にならないかと思いますが、適宜変更してください。

```

cd D:\home\data
curl -LO https://github.com/microsoft/ApplicationInsights-Java/releases/download/2.1.1/applicationinsights-agent-2.1.1.jar
```

### `AI-Agent.xml`ファイルを作成

`AI-Agent.xml`というファイルを先ほどダウンロードした**jarファイルがある場所と同じ場所に作成**してください。

内容は以下をコピペで良いです。

``` AI-Agent.xml
<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsightsAgent>
    <Instrumentation>
        <BuiltIn enabled="true"> <!-- ここのenabled属性も見ているため忘れずに。 -->
            <JDBC enabled="true" /> <!-- JDBCでクエリを投げた時にクエリの実行時間とPreparedなSQLのテレメトリを送信 -->
        </BuiltIn>
    </Instrumentation>
</ApplicationInsightsAgent>
```

今回はJDBCのみですが、設定でいくつかのHTTP呼び出しなどもトレースできるようです。


### JVM引数に`-javaagent:...`を追加

JVM引数に以下を追加します。ファイルパスは適宜置き換えます。

```
-javaagent:D:/home/data/applicationinsights-agent-2.1.1.jar
```

Tomcatで動かすアプリなら環境変数`JAVA_OPTS`や`CATALINA_OPTS`でよいです。

Azure WebAppならアプリケーション設定かkudu上からweb.configで。ただし、**アプリケーション設定の方が優先される**ので、その点を考慮してください。


### アプリケーション再起動

javaagentを読み込ませるために再起動が必要です。

以上。


その他
----------

### 冗長なテレメトリを抑制したい

現状、時間がかかった場合だけ送る、といったことは出来ないようです。

例えば、十分に早いことが分かっているクエリや、コネクションプーリングを使っているとプールから取り出したときに腐ってないかチェックするときの`SELECT 1`でもテレメトリが送られてしまいます。
もし防ぎたい場合は、フィルタを書く必要があります。以下のIssueにTelemetryProcessorの実装例があります。

参考: https://github.com/microsoft/ApplicationInsights-Java/issues/837#issuecomment-471610584
Bootstrap で 要素 の テキスト を 中央 に 配置する 方法

# 目的
Bootstrapを用いてCSSで設定する所のtext-aline: center;と同じ表示にする方法をまとめる  

# 前提条件
- Bootstrapの設定が読み込まれるようになっている
- Bootstrapのテンプレートを使用してHTMLファイルをコーディングしている。  
※Bootstrapの設定を反映させるためのテンプレートは[こちら](https://getbootstrap.jp/docs/4.2/getting-started/introduction/)のスターターテンプレート内のコードをコピーする。

# 押さはえるポイント
- Bootstrapで既に定義された内容を設定したい時はHTMLファイルのクラス名に定義名を記載する。
- テキストを要素の中央に配置するにはクラス名にtext-centerを追加する。
- 右寄り、左寄りの設定も可能

# 書き方の例
- h1要素のテキストを中央に配置する。
- 下記にHTMLファイルの内容を記載する。

``` html
<h1 class="text-center">おはようございます。</h1>
```

- h1要素のテキストを左寄りに配置する。
- 下記にHTMLファイルの内容を記載する。

``` html
<h1 class="text-left">おはようございます。</h1>
```

- h1要素のテキストを右寄りに配置する。
- 下記にHTMLファイルの内容を記載する。

``` html
<h1 class="text-right">おはようございます。</h1>
```
Bootstrapとは

# 目的
Bootstrapとはなんなのかをまとめる

# この記事のターゲット
- Bootstrapと言う言葉を聞いたことはあるがなんなのかわからない方
- Bootstrapで具体的に何ができるか知りたい方
- CSSでいちいち設定を行うのが面倒な方
- Webページ作成時間を短縮したい方
- Webページを作ってみたいがheaderのイメージが決まらな方  
※実際の詳しいBootstrapの使い方はたくさんの先駆者の皆さんが取り上げているので自分は詳しくはまとめないことにする  
※本記事を読んで｢ふーん、Bootstrapってこんな感じのものなんだなー、使ってみようかなー｣となっていただければ幸い


# Bootstrapを簡単に言うと
- よく使う設定が既に定義されている便利なもの。
- いちいちCSSファイルで背景色などを設定しなくても良い。
- かっこいい見た目のリストを作れるテンプレートが沢山ある。
- Bootstrapの公式サイトからプレビューを見た上でテンプレートをコピー出来る
- ただ、全ての設定が定義されてる訳では無いので自分でもCSSを書く必要がある

# 使ってみよう
[こちら](https://getbootstrap.jp/)からBootstrapの日本語リファレンスをのぞいてみよう
1. 新規ファイルとして「index.html」という名前のファイルをPCの任意の場所に作成する。
2. 「index.html」を エディタで開く。
3. ドキュメント → 中央付近に記載のある「スターターテンプレート」に記載されているHTMLファイル用のテンプレートをコピーしてエディタで開いた「index.html」に張る。
4. 保存して「index.html」をダブルクリックする。
※この時エディタは開いていてもOK
5. ブラウザ画面が起動し「Hellow, World!」と表示されたことを確認する。
6. エディタで開いた「index.html」のbody要素の中のh1要素にclassを作成しクラス名を「bg-primary」とする
7. 保存して「index.html」をダブルクリックする。
8. ブラウザ画面が起動し「Hellow, World!」と表示されている背景色が青色に変化する。

※このほかのBootstrapでの設定は日本語リファレンスで閲覧可能である。
※背景色などの設定はドキュメント → 左側のサイドバーのユーティリティ → 左側のサイドバーのColorsから確認できる

# まとめ
1. Bootstrapの設定を反映したいときはクラス名で指定する。
2. ドットインストールやQiitaでもより細かい使い方やテクニックがまとめられている。
3. Bootstrapを活用することにより素早いコーディングか可能となる。
PythonでGoogleスプレッドシートに結合cellを作成する方法

# Motive
単にスプレッドシートにデータを入力したい場合は `gspread ` ライブラリを使えば `sheet.update_acell('A1', "AAA")` でよいし、 cellに線や色を付ける、文字のタイプ、文字フォント、または文字寄せなどを設定する場合は `gspread-formatting` を使って

```Python:
import gspread_formatting as gsformat

fmt = gsformat.cellFormat(
    backgroundColor=gsformat.color(0.0, 0.5, 0.0),
    textFormat=gsformat.textFormat(foregroundColor=gsformat.color(0, 0, 0)),
    horizontalAlignment='LEFT',
)

gsformat.format_cell_range(sheet, 'A1:A10', fmt)
```
とすると反映は可能です。

ですが、
`A1:A5`までcellを結合したい！
思った場合、`gspread`、`gspread-formatting`にそれっぽいメソッドはないです。 

レイアウトを整えるのは重要事項なのでもっとコードでなんとかしたい！:dancer::100:

と思った時は、下記の例はresponseで送るjson形式に似たものを用いる方法をまとめたので記述します。:japanese_goblin:

# Method
対処法としてですが `gspread` の `batch_update(dict)` メソッドを用います。

### code

```:value.json
{
	"requests" : [
		{
			"mergeCells": {
				"range": {
					"startRowIndex": 0,
					"endRowIndex": 1,
					"startColumnIndex": 0,
					"endColumnIndex": 5
				},
				"mergeType": "MERGE_ALL"
			}
		}
	]
}
```

```:setting.ini
[googleSpreadSheet]
book_id = {{ スプレッドシートのID }}
keyfile_name = {{認証に必要なjsonファイル}}.json
```


```Python:

import configparser
import json
import os
import json
from oauth2client.service_account import ServiceAccountCredentials
import gspread

def main():

	config = configparser.ConfigParser()
	ini_file = os.path.join("./", 'setting.ini')
	config.read(ini_file)

	scope = ["https://spreadsheets.google.com/feeds",
			"https://www.googleapis.com/auth/drive"]
	book_id = config.get("googleSpreadSheet", "book_id")
	path = os.path.join("./", config.get("googleSpreadSheet", "keyfile_name"))
	credentials = ServiceAccountCredentials.from_json_keyfile_name(path, scope)        
	client = gspread.authorize(credentials)
	gfile = client.open_by_key(book_id)

	dst = {}
	with open("value.json", encoding='utf-8') as fin:
		dst = json.load(fin)

	gfile.batch_update(dst)

if __name__ == "__main__":
	main()

```

これで `A1:A5` のセルが結合されました。
<img width="603" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288206/d508ceb2-032f-a94b-d9ec-43ffe16b054e.png">

# Future
`batch_update` メソッドはcell結合以外にもcopy&pasteやsortもできるみたいで、内部では`POST https://sheets.googleapis.com/v4/spreadsheets/{spreadsheetId}:batchUpdate`にリクエストをかけています。ヒントは(https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request)
にあります。

# Reference
[gspread](https://pypi.org/project/gspread/)
[gspread-formatting] (https://pypi.org/project/gspread-formatting/)
[PythonでGoogleSpreadSheetのセルにコメントを付加したり色や枠線をつける](https://qiita.com/mokemokechicken/items/ac81448c1b5f036786d4)
[Basic Formatting](https://developers.google.com/sheets/api/samples/formatting)
[Method: spreadsheets.batchUpdate](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/batchUpdate)
キーボードの打ち方講座

#基本#
***押したい文字を見つけて押す***
aを打ちたい場合aを打ちましょう。
もし大文字で書いてあるのに小文字がでてきた場合は仕様です。
#もし、キーキャップの上の方に書いてある文字を打ちたくなったとき#
そんなときに使うのが、Shiftキーです。(私は数年間このキーの使い方で悩んでいた)
例えば、1キーをshiftキーと同時に押した場合
`!`が入力されます。これで感情の薄いメールともおさらばですね！

#追記#
ここだけの秘密なのですが。
shiftキーとアルファベットの書いてあるキーを同時に押すと大文字が打てます。

`QIITA`　かっこいいですね（笑）。

####CapsLockキーは絶対に触らないようにしましょう####
キーボードの法則と秩序が乱れます。
Maya でメッシュの頂点位置差分を可視化する

## 背景

facial capture などで deform するなどして変形したメッシュの各頂点が, 元のメッシュに比べてどれくらい変形しているか確認したい.
トポロジと頂点数は同じとする;.

Maya の標準機能にありそうな気もしますが, どうも無いっぽいようですね.

## ツール

すでに先人たちによりありました. ありがとうございます.

C++ 版
https://github.com/dgovil/MeshCompare

dgovil さんのところには, neural net で skinning を簡略化する FDDA の実装もあります. 素晴らしいですね.

https://github.com/dgovil/MLDeform

Python 版
https://github.com/Meatplowz/MeshCompare

とりあえずは python 版を使い,インタクティブに確認したいなど性能が必要であれば C++ を使うと良いでしょう.

頂点カラーに差分では, メッシュにマテリアルを割り当て, また Maya viewport 2.0 で screen-space ambient occlusion をきらないと頂点カラーそのものを表示できないので注意です!

Python 版を Emily model で試してみました. 

![meshcompare.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/f3f36b30-9200-ad14-2319-af6e01683174.png)

適当に三つ領域で少し頂点位置を変えました. 変えたところが赤くなっています! 可視化素晴らしいですね :smiley: 

似たようなやり方で UV の差分や法線の差分にもチャレンジしてみましょう!

## TODO

* facial capture 時系列データで試す.
* OpenFlipper や libigl, meshlab で差分の可視化をしてみる https://www.openflipper.org/plugins/mesh
【機械学習】進捗状況をさくっと表示

機械学習などで重たい処理を走らせると、進捗状況の見えない処理待ちでデスクを離れるに離れられなく途方に暮れる事が多々あるのですが、進捗を簡単に表示出来る外部パッケージがしっかり用意されていました。

#インストール
自分はanaconda環境なので初めから入っていましたが、もし入っていない場合はpipでインストールできます。

```
pip install tqdm
```
#使い方は超簡単

```
from tqdm import tqdm_notebook as tqdm
```
インポートをしたら

```
for i in tqdm(range(10000000)):
    result = i * i
```

for文などのイテレータ部を囲って引数にするだけでOK！
するとこんな感じでプログレスバーが表示されるので、その間に安心してひと息入れる事ができます。
![スクリーンショット 2019-07-19 15.22.32のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196214/3ac6ab6c-f23e-2c25-7f80-e2e443f04721.png)

因みに対話モードでも使用できます。

定番ツールのようですが、まだ知らない誰かの役に立つと幸いです＾＾
Excel 備忘録

Excelでよく使うけど、覚えるほどでも無いテクニックを小ネタ程度にまとめてます（随時更新中です）。

# シート名を取得する関数
```
RIGHT(CELL("filename",A1),LEN(CELL("filename",A1))-FIND("]",CELL("filename",A1)))
```
※この方法はファイル名からシート名を取り出すため、一度も保存していない場合、ファイル名に"]"が含まれる場合などでは正しく機能しない。

# ファイル名を取得する関数
```
REPLACE(LEFT(CELL("filename",A1),FIND("]",CELL("filename",A1))-1),1,FIND("[",CELL("filename",A1)),)
```
※この方法はファイル名からシート名を取り出すため、一度も保存していない場合、ファイル名に"]"が含まれる場合などでは正しく機能しない。

# フォルダパスを取得する関数
```
CELL("filename")
```
※この方法はファイル名からシート名を取り出すため、一度も保存していない場合、ファイル名に"]"が含まれる場合などでは正しく機能しない。

# 空白以外をカウントする
counta() でカウントすると、空文字（""）までカウントしてしまうので思い通りに数えてくれない。
そんなときは以下のcountif()で以下の様にカウントする。
```
countif([カウント対象], "?*")
```


# グループ化の＋アイコンを上向きに変更する
グループ化を行うと、デフォルトでは＋アイコンが下向きに表示される。
これを上向きに変更するには以下の手順にて変更する。

![上向きアイコンになった様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339580/edb44a62-8dc2-4f7a-5c90-d3615a285af2.png)

1. リボンの「データ」タブを選択し「アウトライン」のプロパティを選択する。
![アウトラインのプロパティ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339580/15dea96a-1a6e-a51c-b31a-fa336e503693.png)

1. 集計行または列の位置の「詳細データの下」のチェックを外すと、＋アイコンが上向きに表示されるようになる 

# ブックの全シート名をテキスト取得する
1. Visual Basic Editorを起動する（ALT + F11）
1. イミディエイトウインドウ表示する（Ctrl + G）
1. 以下のコードを入力し、Enter で実行する  
```
For Each i In ThisWorkbook.Sheets: debug.print i.name : next i
```  
すると、下に全シート名が出力される。

# R1C1参照形式になってしまった場合に、元のA1形式に戻す
1. ［Excelのオプション］ダイアログを開く
1. ファイル → オプション
1. 「数式」→「数式の処理」欄の［R1C1参照形式を使用する］のチェックボックスを外す。

※ マクロを使う人はよくこういう設定をするらしい。

# 図のリンク貼り付け（カメラ機能）を使う
※ かつてのExcelでは「カメラ機能」としてメニューにコマンドボタンが存在したようですが、
2013以降では奥に隠れてしまった（ユーザー設定をしないと表示されない）ため、その操作方法のメモ。

1. リンク対象となるセルをドラッグで選択し、コピーする
1. 貼り付け先となるセルを右クリックし、[形式を選択して貼り付け] から [リンクされた図] をクリックする

# Excelの作業領域を全画面表示する（ショートカットキー）
1. ショートカットキーで  Alt + V, U  を入力する。  

※ 2013からボタンがなくなっているためショートカットキーで出すしかない。
※ あと、これを覚えるぐらいならリボンを畳んだ方が早かったりする）。

# Excelセットアップ時の初期設定メモ（Windows）

1. 起動時、シート追加時の既定テンプレートを設定する  
適応させるテンプレートを作成し、以下のパスに「Book.xltx」、「Sheet.xltx」として保存する。  
```
C:\Users\（ユーザー名）\AppData\Roaming\Microsoft\Excel\XLSTART
```
1. エクスプローラーの新規作成メニューで作成するExcelブックを設定する  
テンプレートを適応させたExcelブックを作成し、以下のパスに「EXCEL12.XLSX」として保存する。  
（テンプレート（.xltx）ではなく、ブック（.xlsx）であることに注意！）  
```
C:\Windows\ShellNew
```
1. 開発タブを有効にする  
ファイル→オプション→リボンのユーザー設定→「開発」にチェック。
ユーザー追加したあとSSHで接続できない人へ

# 参考

[こちらでAWSの実践方法が良くわかりました！](https://amzn.to/2ZNgx0S)



# 解決方法

ご存知の方が多いかと思いますが、こちらの解決策はすでに公式に解凍がございます。
[AWS公式リンク](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-user-account-cloud-init-user-data/)

AWSのSSHは癖が強い！単にわたしの技術不足なのだけど。

ユーザ接続しようとすると

```
Permission denied (publickey,gssapi-keyex,gssapi-with-mic)
```



####解決方法

1. SSHでec2インスタンスに接続
2. cloud-initをインストール

```
sudo yum install cloud-init
```

３. インスタンスを停止
４. キーベアからパブリックキーを取得

```
ssh-keygen -y -f /path_to_key_pair/my-key-pair.pem
```

５. ユーザデータの表示変更に次のスクリプトを貼り付ける。usernameとssh-rsaはご自分のものを入力してください。


```#cloud-config
cloud_final_modules:
- [users-groups,always]
users:
  - name: username
    groups: [ wheel ]
    sudo: [ "ALL=(ALL) NOPASSWD:ALL" ]
    shell: /bin/bash
    ssh-authorized-keys: 
    - ssh-rsa AB3nzExample
  ```


詳しくはAWS公式サイトをご確認ください。
https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-user-account-cloud-init-user-data/
What is Devops?

Devops is a set of practices that automates the process between the IT teams and software
development in order to test, release and build software more reliably and faster. Devops
comes up with several advantages such as faster software release, manages unplanned work
better, increased trust and capable of solving critical issues.

➼ Plan and write code: The Dev team plan and write code using Code Configuration
Management tools such as Git.
➼ Build and Test: While writing the code we can build and test with a tool like Jenkins.
➼ Release and Deploy: They are tools that help automate the process of delivering that
code to a cloud environment or a server.

DevOps is one of the fastest-growing technologies these days. If you want to learn DevOps and take <a title="devops training " href="https://intellipaat.com/devops-certification-training/">devops training </a>
 in order to build a career path in it, then I would suggest you choose any of these platforms:
● Intellipaat
● Lynda
● Edx
These are few good platforms for learning DevOps, which will help you learn DevOps in depth
and will help you become an expert by providing efficient hands-on knowledge in DevOps.
プログラミング初心者がHTML&CSSの学習を始めて最初に学んだクラスを解説！

 [未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている<@y_mishima_miraidenshi>です。
理系学生でありながらプログラミングは全くできません。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。
プログラミング学習の最初の一歩としてHTML&CSSを学習しています。
今回はその中で学んだクラスについて記しておきます。

#クラス分け
HTMLでは各タグにクラスを指定することができます。
クラスを指定することで、CSSにおいてクラスごとの変更を加えることができます。
例えば、文字の色やサイズを変えるといったことができます。
 <img width="251" alt="class練習2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449719/730fd6b0-f99b-ec41-95da-6bc3131853ea.png">
HTMLのコード
 <img width="302" alt="class練習3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449719/57636053-37c2-25c6-74d0-306128d40651.png">
CSSのコード
 <img width="384" alt="class練習.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449719/9123c260-a191-67da-c769-9cc59fa0228c.png">
上図のように、それぞれのクラスごとに表示を変えることができます。
レイアアウトを細かく変えたいときに便利ですね。


#おわりに
まだまだ学びたてで右も左もわからない状態ですが、これからさらに学習し成長していきたいと思います。
htopをインストール

参考記事：
https://www.tecmint.com/install-htop-linux-process-monitoring-for-rhel-centos-fedora/

```
wget dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm
sudo rpm -ihv epel-release-7-11.noarch.rpm
sudo yum install htop
```

<img width="927" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133516/3c3db2c1-6f5f-0272-19ba-e7603223f93a.png">
EC2をflexibleにrebootされる前に手動で実行してみる

#はじめに
タイトル通りの通知がヘルスイベントから来たので対応します。
ただし対象のEC2は本番稼働中でして、そーゆー時（運用の観点）は何するの？でしたので調べました。
いくらぼくでも再起動の手順くらいわかるw
が、サービスインしてるコンテナでもないインスタンスの再起動ってどうやるの？って聞かれると意外と答えられず。。むむむ

#作業環境
EC2（コンテナとかオーケストレーションとかしてない直立てのインスタンス）
mac

#作業開始
##1.ググる
古来からの伝統に則りググります。よきサイトが見つかりました、めっちゃわかりやすい。
4年前なので情報が現在と結構変わってますので脳内で読み替え。
https://sole-color-blog.com/blog/428/

システムリブートとインスタンスリブートで結構変わるんですね。
今回は通知内容からインスタンスリブート（のように読める）なので、基盤レイヤー側で再起動した場合に確認すべきこと・しておきたいことは省く。

というかまず公式ドキュメントを読むべきだった。。のでこちらも目を通します。
※先のサイトのリンクから飛びました

https://aws.amazon.com/jp/maintenance-help/

スケジューリングされたインスタンスの再起動をどう変更するのかとか、その前に手動でやっちゃってもいいよとかの具体的な手順が書いてますね。
その中でキーワードではないですがポイントになりそうな1文を発見。
> DNS 名や IP アドレスといったユーザー設定は変わらず、ローカルインスタンスストアのデータにも影響はありません。

ということは再起動前後でユーザー設定が変わってないことを確認できればいい気がします。

##02.検証作業
ブログと公式ドキュメントどちらにも書かれていますが、以下の項目をクリアできればOKですね。

```
1.パブリックDNS名が変更されていないか
2.プライベートIP（ついでにEIP）が変更されていないか
3.インスタンスストアに格納されたすべてのデータが保持されているか。消えていないか。
4.加えてsshできるかもリブート後にテスト
```


インスタンスストアだけやり方がわからないので調査。
リブートではデータはすべて保持されるとのこと。
蛇足ですが停止＆終了では削除されるらしいので、覚えておこうと思います。

http://tmnj.hatenablog.com/entry/2016/11/26/155804

ここでちょっとハマる。インスタンスストアの概要は理解したのですが、具体的な手順は？何をどうするのかがわからない。
頭から煙が出てきてちょっと嫌になりましたがw、以下に記載がありました。
やっぱり公式ドキュメントですよね()！

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/add-instance-store-volumes.html

df -hコマンドとlsblkでマウント状況を確認するようです。
コマンドの意味は以下の通り。

>$ df -h
ファイルの空き容量を集計する。-hオプションは人間に読みやすくするHumanとのこと。
確かに読みやすいw

https://www.atmarkit.co.jp/ait/articles/1610/24/news017.html


>$ lsblk
現在利用できるブロックデバイスを一覧表示する。今回は特にオプションつけずこのままで。

https://www.atmarkit.co.jp/ait/articles/1802/02/news021.html


お、先ほど列挙した条件、これで具体的な手順できそう！

```
1.パブリックDNS名が変更されていないか
→作業前後にRoute53で目視確認 ※ここコマンド化できる？

2.プライベートIP（ついでにEIP）が変更されていないか
→作業前後にコンソールで目視確認　※ここコマンド化できる？

3.インスタンスストアに格納されたすべてのデータが保持されているか。消えていないか。
$ df -h
$ lsblk

4.加えてsshできるかもリブート後にテストします
$ ssh ホスト名　※この手順は3.の前に行う
```

OSSでもSaasでもいいんですが、何かしらのサービス入れてるならリブート前後にサービスを止める必要があると思います。
もしくは自動起動にしとくとか。

#おわりに
めっちゃ作業途中ですが今回は一旦ここでストップ。
ほぼ固まったのでこれベースで作業して、完了したタイミングで結果を追記したいと思います。

誰かのお役に立つ記事。。になることを目指してw
JavaScriptでハッシュ関数（SHA256）を使う

# はじめに
JavaScriptでハッシュ関数を使いたくて、いろいろな記事を見ていたのですが、node.jsでインポートして使うのが多かった印象でした。

しっかりとは私も理解していないのですが、JaveScriptでハッシュ関数（sha256）を使うことができたので、それを記事にしました。

# ハッシュ値をWebページに出力まで

まずこのページへ飛んで、ダウンロードしてください。→[jsSHA](https://github.com/Caligatio/jsSHA)

そしてダウンロードしてきたフォルダを解凍するとjsSHA-masterというフォルダが手に入ると思います。
そのフォルダ内にあるsrcフォルダに入ると、「sha256.js」というファイルがあるので、それをこれから作る、「index.html」「main.js」ファイルと同じフォルダに置いてください。

あとは以下のようにコードを書けばハッシュ化できるはずです。

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>SHA256</title>
</head>
<body>
  <div id="test"></div>

  <script type="text/javascript" src="sha256.js"></script>
  <script type="text/javascript" src="main.js"></script>
</body>
</html>
```

```main.js
"use strict";
{
  const SHA_OBJ = new jsSHA("SHA-256","TEXT");
  const TEST = document.getElementById("test");

  window.onload = () => {
    let _text = "ハッシュ関数";

    SHA_OBJ.update(_text);
    TEST.textContent = SHA_OBJ.getHash("HEX");
  }
}
```

<img width="393" alt="ハッシュ1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/621719ec-5440-32d7-ef68-156e2e526e6d.png">

index.htmlをブラウザで起動すると、上図のように表示されるはずです。
ここではハッシュ関数という文字列をハッシュ化しています。
マルチテナンシー（Multitenancy）を簡単に実現できるgem「acts_as_tenant」を実装

##背景
:relaxed:仕訳記録用の会計ソフトを開発しています。ユーザのサインアップ、検証、ログイン、ログアウト機能は既にできています。
:frowning2:ただし、例えばユーザＡが登録した仕訳が、新しくサインアップしてログインしたユーザＢに漏れなく見られてしまいます。つまり、全てのデータは全員共有という状態です。
:point_right:望ましいのは、ユーザＡが登録した仕訳がユーザＡのみに見られ、ユーザＢがサインアップしてログインすると、またきれいな環境になり、ユーザＢがユーザＢのみ見られる仕訳を登録できるようになるということです。
ただし、一部の汎用勘定科目はＡもＢも見れます。
また、アプリのＵＲＬは変わらないです。ＡもＢも同じURLで同じシステムをログインします。
##いろいろ調べた結果
:one:希望な機能は「マルチテナンシー」（[Multitenancy](https://en.wikipedia.org/wiki/Multitenancy)）と呼ばれます。
:two:幸いなのは、Railsの中に既にいくつかのGemがありました。苦労せず実現できそうな感じです。
:three:一番流行っているらしいのが「[Apartment](https://github.com/influitive/apartment)」というGemです。違うテナントは違うsubdomainを通じてデータの隔離することを実現します。
:four:Apartment+PostgreSQLの場合、微妙な問題がありそうです。未だに完璧に解決できていないようです。
:five:二番目有名なGemは「[acts_as_tenant](https://github.com/ErwinM/acts_as_tenant)」というGemです。今回使ってみたのはこれです。
##いよいよ始めよう
:one:　**インストールはとっても簡単**

1. `gem 'acts_as_tenant'`をGemfileに入れます

2. `Bundle Install`を実行します。
3. 完了です。

:two:　**データを隔離したいテーブルにテナントを代表するＩＤの列を追加**

`rails g migration addAccountToTables`でMigration Fileを生成させ、下記のように書きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305759/3db15743-0dd3-1cc4-2386-d0880f4bc914.png)

説明：
①　dealsは仕訳を保存するテーブル、bank_accounts は銀行口座を保存するテーブルです。そしてユーザごとにデータを隔離したいテーブルです。両方とも既にあったテーブルです。

②　usersは既にあったユーザを保存するテーブルです。今回はuserごとにデータを隔離したいので、ここでは:user_idを入れてＯＫです。もし一つのAccount(Tenant)に複数のuserが含まれ、同じTenantのuserたちはデータを共有するという形がほしかったら、別途Accountテーブルを作る必要があります。

③　勘定科目を共有したいため、勘定科目テーブルgl_accountsはそのまま変わらないです。

p.s.Migration Fileの名前は「AddAccountToTables」じゃなくても何でもいいです。

:three:　**Modelに`acts_as_tenant(:user)`を追加**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305759/3af21d0c-f8e2-55ba-9e61-922dfa0a1448.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305759/c69de7e3-664f-fdef-0e4c-6dbbed06389d.png)
隔離したいModelだけが必要です。勘定科目のmodel-GlAccountはそのまま何も変わらないです。

:four:　**テナントを判別するコードをcontrollerに入れる**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305759/695794fa-9cb7-eeca-863d-e6843bb6f5db.png)
説明：
① ここの`set_current_tanant_through_filter`はgemが提供してくれる関数です。名前は変えられないです。
② `find_current_tenant`は自分で作ったprivate関数です。好きな名前にしてもＯＫです。
③ `set_current_tenant`はgemが提供してくれる関数です。名前は変えられないです。
④ パラメータの`current_user`は自分がその前に書いた関数です。目的はログインしているユーザをゲットすることです。
:sunny:
以上だけ設定すると、ユーザＡもＢも自分しか見れない/作れないデータをできるようになりました。
非常にシンプルで分かりやすいＧｅｍだと思います。
Wi-Fi接続状況を監視するのにCONNECTIVITY_ACTIONが廃止予定なので、requestNetworkで監視してみた

#はじめに
タイトル通り、今までWi-Fi接続状況を監視するのに、`ConnectivityManager#CONNECTIVITY_ACTION`をBroadcastReceiverに登録して監視していましたが、公式を見るとAPIレベル28で廃止されるとのことなので、`ConnectivityManager#requestNetwork`を使用して監視してみました。

#ConnectivityManager#CONNECTIVITY_ACTION
```CONNECTIVITY_ACTION.kt
// Receiver登録
IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).also {
    registerReceiver(wifiBroadcastReceiver, it)
}

// Receiver
val wifiBroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        context ?: return
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val activeNetwork = cm.activeNetworkInfo
        activeNetwork.also { info ->
            val isConnected = info.isConnectedOrConnecting
            val isWifi = info.type == ConnectivityManager.TYPE_WIFI
            val isMobile = info.type == ConnectivityManager.TYPE_MOBILE
        }
    }
}
```

#ConnectivityManager#requestNetwork
```requestNetwork.kt
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

val request = NetworkRequest
    .Builder()
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
    .build()

val networkCallback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network?) {
        super.onAvailable(network)
        // ネットワークが使用可能になったときの処理
        val capabilities = cm.getNetworkCapabilities(network)
        val isWifi = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
        val isMobile = capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
    }

    override fun onLost(network: Network?) {
        super.onLost(network)
        // ネットワークの接続が切れたときの処理
    }

    override fun onUnavailable() {
        super.onUnavailable()
        // ネットワークが使用不可になったときの処理
    }
}

cm.requestNetwork(request, networkCallback)
```

#おわりに
`ConnectivityManager#requestNetwork`はWi-Fiだけでなく、様々なネットワークと状態を監視できます。より汎用的になった、ということでしょうか。


#参考
[ConnectivityManager](https://developer.android.com/reference/android/net/ConnectivityManager.html)
[Android Q の機能と API](https://developer.android.com/preview/features)
Open-Closed Principle(開放閉鎖の原則)についてまとめた

# はじめに
前回こちらの記事で、SOLID原則について調べつつまとめていきました。
https://qiita.com/kkkkkkkkkkk/items/ad5a7aeaee16bf55b3e2

今回は、SOLID原則のうちのひとつである**Open-Closed Principle**(開放閉鎖の原則)について考えていきたいと思います。

### Open-Closed Principle(OCP)とは？
前回の記事でざっくり概要だけは触れましたが、改めて原則について確認していきます。

Open-Closed Principleとは、**クラスは、拡張に対して開放され、修正に閉鎖されるべきである**という原則でした。

この原則を聞くだけだとイマイチ理解できないと思うので、さらに噛み砕いた表現をすると、**簡単に拡張できて、修正が不要になる**ようにしよう！という原則です。

これでなんとなく原則意味の意味はつかめたと思います。

次は実際にコードを見ながら、原則の意味を確認していきます。


## OCPに違反した例
まずはOCPに**違反した例**から見ていきたいと思います。

例としては、支払いを行うサービス(PaymentService)があり、そこで課金を行う仕組みがあるとします。

とりあえず、最初はカード支払いだけだったのでこんな感じで実装したとします。

その例がこちらです。

```php5
<?php
ini_set( 'display_errors', 1 );

class PaymentService {
    public function __construct(CardPayment $cardPayment){
        $this->cardPayment = $cardPayment;
    }

    public function pay()
    {
        $this->cardPayment->pay();
    }
}


class CardPayment {
    public function pay(){
        echo("<p>pay with card</p>");
    }
}


// カード支払い
$cardPayment = new CardPayment();
$payment = new PaymentService($cardPayment);
$payment->pay();

// 銀行支払い
// コード自体の修正が必要になる。
```

いかがでしょうか？

コード内のコメントにも記載していますが、現状のコードだと銀行支払いが必要になった場合の考慮がされておらず、コード自体の修正が必要になりますよね。

これは、OCPの**修正に閉鎖されるべきである**に確かに違反していることがわかりますね。



## OCPに遵守した例
今度はOCPに遵守した例を見ていきます。

こちらはさっそくコードを見てみましょう！

```php5
<?php
ini_set( 'display_errors', 1 );

class PaymentService {
    public function __construct(PaymentMethod $paymentMethod){
        $this->paymentMethod = $paymentMethod;
    }

    public function pay()
    {
        $this->paymentMethod->pay();
    }
}

interface PaymentMethod {
    public function pay();
}


class CardPayment implements PaymentMethod {
    public function pay(){
        echo("<p>pay with card</p>");
    }
}


class BankPayment implements PaymentMethod {
    public function pay(){
        echo("<p>pay with bank</p>");
    }
}


// カード支払い
$cardPayment = new CardPayment();
$payment = new PaymentService($cardPayment);
$payment->pay();

// 銀行支払い
$bankPayment = new BankPayment();
$payment = new PaymentService($bankPayment);
$payment->pay();

// アプリ支払い
// コレならコードを修正しなくてもアプリ支払いを追加できる
```


いかがでしょうか？

こちらは**OCPに遵守**していることがわかりますよね！

コード内のコメントにも記載していますが、これなら**アプリ支払いが増えてもコードの修正が不要**になります。



## まとめ
今回は、**Open-Closed Principle(OCP)**について学習しました。

業務の都合でしばらくQiitaの更新が途絶えてしまいましたが、SOLID原則の記事はやりきりたいと思います。
【備忘録】Swift4.0以降で音を鳴らす

#音を鳴らしたいだけ
　ある教材でアプリ開発を学んでいたら、音を鳴らすところがうまくいかない。そりゃそうだ。その教材、Swift3.0なんだもの。まぁ、私が過去に書いた4.2を引っ張ってきてぶち込んだから問題なくできたけど。。。こんな感じで今後も「音を鳴らすだけ」のためにわざわざ過去のProject開いて確認するのめんどいな、、と思ってここに書いておく。
#こんな感じ

```swift:ViewController.swift
import UIKit
import AVFoundation

class ViewController: UIViewController {
    
    var audioPlayer: AVAudioPlayer!
    
    @IBAction func btn(_ sender: UIButton) {
        
        playSound(name: "yourFileName")

    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

extension ViewController: AVAudioPlayerDelegate{

    func playSound(name: String){

        guard let path = Bundle.main.path(forResource: name, ofType: "mp3") else {
            print("I cannot find any music file...")
            return
        }
        do{
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
            
            audioPlayer.delegate = self
            
            audioPlayer.play()
        } catch {
        }
    }
}

```

yourFileName.mp3っていうファイルを入れておくと、ボタンを押した時にそれが流れる。
Bigqueryで内積計算

役に立つときがあるかもしれないので残しておく。


例えば [1, 1, 2] [1, 2, 3] の内積を求める場合こんな感じで出来る。

```sql

select
  sum(a.x * b.y)
from
  (select * from unnest([1, 1, 2]) as x with offset as i ) a
join
  (select * from unnest([1, 2, 3]) as y with offset as j ) b
on a.i = b.j
```

select 部分をこうすれば、2つの配列のcos類似度も出せる。

```sql
sum(a.x * b.y) / (sum(a.x * a.x) + sum(b.y * b.y))
```
Hyperledger FabricのConnection Profileについて

本記事では、オープンソースのブロックチェーン基盤の1つであるHyperledger Fabricのv1.4で導入されたConnection Profileについて調べた結果をまとめます。

Connection Profileは、v1.4の[What’s new](https://hyperledger-fabric.readthedocs.io/en/release-1.4/whatsnew.html)では、アプリケーション開発関係のところで一言だけ触れられている程度の非常に地味な扱いですが、アプリケーション側に対してブロックチェーンネットワークを抽象化するという点や、クライアントSDKがブロックチェーンネットワークへどのようにトランザクションを投げるか規定するという点で、重要な機能、コンセプトだと思います。

## Connection Profileとは

Connection Profileは、ブロックチェーンネットワークの各構成要素(組織、チャネル、Peer、Ordererなど)をまとめて記載した定義ファイルです。FabricのSDKが、この定義ファイルに従ってブロックチェーンネットワークにトランザクションを投げてくれるので、アプリケーション開発者は、どのPeerやOrdererに接続すべきかを考慮する必要がなくなり、ビジネスロジックの実装に専念することができるようになります。v1.4以前からも似たような抽象化がある程度されていたと思いますが、Connection Profileの導入によってより洗練されたという印象です。

## 静的構成と動的構成

Connection Profileは、静的な構成と動的な構成の2つをサポートしています。前者は、存在するPeerなどを全てConnection Profileに記載し、それに基づいてトランザクションを送信するのに対し、後者は、最小限のPeer(本番環境では少なくとも2つ以上を推奨)だけ記載しておき、あとはService Discoveryの機能を用いて動的にConnection Profileの定義を拡充し(e.g., Peer数)、トランザクションを送信します。

Service Discoveryは、チャネルに参加しているPeerの数や、エンドースメントポリシーを問い合わせるためのAPIです。このAPIにより、Connection Profileに問合せ可能なPeerが記載されてさえいれば、あとは自動的に対象Peerを見つけてきてトランザクションを投げてくれるようです。

なお、デフォルトの挙動は動的構成のため、もしService Discoveryをオフにしたい場合は明示的に指定する必要があります。

## Endorsing Peerの選択アルゴリズム

Service Discoveryを用いて動的にConnection Profileを構成する場合は、エンドースメントポリシーも自動的に取得して、必要なPeer数を計算しながら賢くトランザクションを投げてくれるようです。このあたりが、v1.x初期の頃はできていなかったように思うので良く改善されているなと思います。

気になるのは、例えば、ある組織の複数のPeerのうち1つだけからエンドースしてもらえば良いという状況下でどのPeerが選択されるのかという点です。[ドキュメントのサンプルプロファイル](https://hyperledger-fabric.readthedocs.io/en/release-1.4/developapps/connectionprofile.html#sample)を見る限りは、特に指定項目や関連する記載がなく、お任せのようなのですが、[Go SDKのテスト用のプロファイル](https://github.com/hyperledger/fabric-sdk-go/blob/master/test/fixtures/config/config_test.yaml)には、Balancerというオプションがあり、RoundRobinかRandomが選択できるようになっています。

Peerのスペックが均一であれば上記のような選択アルゴリズムで十分だと思いますが、不均一な構成を想定するのであれば、今後、負荷に応じて投げる先を切り替えるなど、ロードバランス的なことができるようになると良いのではないかと思います。

## Fabric SDKでの利用方法

- [How to use a common connection profile](https://fabric-sdk-node.github.io/release-1.4/tutorial-network-config.html)
メモ：VBAで2次元配列を行方向に結合

二次元配列AとBを行方向に（下方向）に結合したい。
ReDim Preserveは、最終次元しか拡張できない。つまり、結合可能なのは列方向のみ。そのため、下記の手順で結合する。
使い道があるかは不明。。。大量のブックを高速に集約するのに役立つかも。

・AとBを転置してAtとBtにする。
↓
列方向に結合に動的に結合（At　←　Bt）
↓
結合後の配列をさらに転置して元の向きを戻す。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250449/1cbf21a3-22ab-6362-3493-6409debae19c.png)


```vb
Sub merge_array()

Dim array_A(), array_B(), array_At(), array_Bt()

array_A = Range2Array(4, 1)
array_B = Range2Array(10, 1)

'①AとBを転置。AtとBtにする。
'配列の１次元のインデックスは1からになっている。
array_At = WorksheetFunction.Transpose(array_A)
array_Bt = WorksheetFunction.Transpose(array_B)
former_i = UBound(array_At, 2)
add_i = UBound(array_Bt, 2)

'AtとBtを列方向に結合
'AtをBtと同じサイズ分拡張。拡張したところにBt格納。
'①に合わせて「1 To ～」と宣言しないといけない
ReDim Preserve array_At(1 To UBound(array_At, 1), 1 To (UBound(array_At, 2) + add_i))
For j = 1 To UBound(array_Bt, 2)
    For i = 1 To UBound(array_Bt, 1)
        array_At(i, j + former_i) = array_Bt(i, j)
    Next i
Next j

'結合後の配列を転置して向きを戻し、貼り付け
Cells(4, 17).Resize(UBound(array_At, 2), UBound(array_At, 1)).Value = WorksheetFunction.Transpose(array_At)

End Sub

```

レンジを2次元配列にする関数↓

```vb

Public Function Range2Array(begin_row As Long, begin_column As Long) As Variant
    last_row = Cells(begin_row, begin_column).End(xlDown).Row '終端行
    last_column = Cells(begin_row, begin_column).End(xlToRight).Column '終端列

    Range2Array = Range(Cells(begin_row, begin_column), Cells(last_row, last_column))
End Function

```
JFreeChart-PolarChart-極座標


目次 ⇒ [JFreeChartサンプル](https://qiita.com/artery/items/3e9c63e5c14a9e965c97)

```java
package jp.avaj.lib.chart;

import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PolarPlot;
import org.jfree.chart.renderer.DefaultPolarItemRenderer;
import org.jfree.chart.renderer.PolarItemRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
■ JFreeChart-PolarChart-極座標

・(1)データセットはXYSeriesCollectionを使う.
・(2)データには角度と値を指定する.
  ・角度はラジアンではなく度.
・(3)レンダラはDefaultPolarItemRenderer.
・軸は一つだけ必要で、NumberAxisを指定した.
・プロットはPolarPlotというものがあるので、これを使う.

 */
public class Chart20_00 {
  // PolarChar/極座標.
  A_Chart20 a_Chart20;
  // 目次-Artery-JFreeChart用のライブラリ
  A_Chart00 a_LibChartSampeContents;

  public static void main(String[] args) {
    XYSeriesCollection dataset = new XYSeriesCollection(); // (1)
    XYSeries data0 = new XYSeries("data0");
    data0.add(0.0D, 2.0D); // (2)
    data0.add(90.0D, 13.0D);
    data0.add(180.0D, 9.0D);
    data0.add(270.0D, 8.0D);
    dataset.addSeries(data0);
    XYSeries data1 = new XYSeries("data1");
     data1.add(90.0D, 0.0D);
    data1.add(180.0D, 22.0D);
    data1.add(250.0D, 18.0D);
    data1.add(355.0D, 10.9D);
    dataset.addSeries(data1);
    //
    DefaultPolarItemRenderer renderer = new DefaultPolarItemRenderer(); // (3)
    NumberAxis radiusAxis = new NumberAxis(); //(4)
    PolarPlot polarPlot = new PolarPlot((XYDataset)dataset,(ValueAxis)radiusAxis,(PolarItemRenderer)renderer);
    JFreeChart jfreeChart = new JFreeChart("PolerPlot",(Plot)polarPlot);
    //
    ChartFrame cFrame = new ChartFrame("PolerPlot",(JFreeChart)jfreeChart);
    cFrame.pack();
    cFrame.setVisible(true);
  }
}

```

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278568/d000e72b-bcc5-cc4e-a2d1-a9f5359a7e0f.png)
PHPで簡単なBANをする

攻撃的な発言をする人などをBANしたい時に.使えるかも…？
#前提
- php 7.0
- apache2
- ubuntu 18.04 

##BANしたいユーザーのipを書く(BAN.php)
```php:BAN.php
<?php
$ip = $_SERVER["REMOTE_ADDR"];
$nguser = array('123.456.789.012', '111.222.333.444');
?>
```
- 123.456.789.012とか111.222.333.444のところはBANしたいIP名に書き換える
- 最初と最後の<?php と ?>を書かないと後々htmlとして読み込まれるので注意...
- IP増やしたい時はコンマで区切って増やしてね

##メインページでの処理(index.php)
```php:index.php
<?php
include 'BAN.php';
if (in_array($ip, $nguser)) {
  header('Location: https:/mysite.mysite/banuser.php');
 }
?>
<!--ここからhtmlとか内容を書いてね-->

```
- include 'BAN.php';のところはそれぞれの環境に応じてパスを変えてね。（この例だと同ディレクトリにBAN.phpが置いてある）
- https://misite.misite のところは自分のサイトに書き換えてね

##BANされた人向けのページ(banuser.php)
```php:banuser.php
<?php
include 'BAN.php';
if (in_array($ip, $nguser)) {
 }else{
  header('Location: https://correctjp.work');
 }
?>
<!--ここから先は自由に書いてね-->
<h1>あなたはBANされました。</h1>
```
- 別になくてもまあいいですがnot foundだとあれなので...
- phpのところはBANされてない人にURLから飛んでこられても見せないためです。
- リンクの書き換えとかはさっきと同じ

##その他
個人的には誰にでもわかるように書いた...つもりです。
初心者が思いつきで考えたのでもっといい方法があると思います..
Apache２でBANすればいいんですが面倒だった時とかに使えればいいかもです。
どう動いてるかとかは今後追記するかもしれませんが他の人の見たりggって見てください..
一応これ、そのまま怪しい日本語ジェネレーター(https://correctjp.work )で使ってます..
お疲れ様でした！
テスト対象のクラスの一部のメソッドをモック化する方法

最近noteに書くか、Qiitaに書くか迷い中です。

いつも忘れる、いつも一部をモック化したいときの書き方。

- mock化したいメソッド

```java
@Slf4j
@Service
public class HighHolidayService {

	// 一月単位でまとめた休日リスト
	Map<String, List<LocalDate>> highHolidayCache = new HashMap<>();
	
    // テスト対象のメソッド
	public List<LocalDate> getHolidayList(LocalDate targetDate) {
		String key = String.format("%d%02d", targetDate.getYear(), targetDate.getMonthValue());
		if (highHolidayCache.containsKey(key)) {
			return highHolidayCache.get(key);
		}
		List<LocalDate> holidayList = selectRecords(targetDate);
		highHolidayCache.put(key, holidayList);
		return holidayList;
    }

    // このメソッドをモック化したい!!!!
	List<LocalDate> selectRecords(LocalDate targetDate) {
            return null;
	}
}

```
- テストの書き方

```java
package jp.co.hogehoge.service;

import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.doReturn;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.mock.mockito.SpyBean;

public class HighHolidayServiceTest {

	@SpyBean    // springboot の@spyの書き方
	HighHolidayService highHolidayService;
	
    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }
	@Test
	public void 対象の休日リストを取得する() {
		List<LocalDate> returnHolidayList = new ArrayList<>();
		returnHolidayList.add(LocalDate.of(2019, 07, 28));
		returnHolidayList.add(LocalDate.of(2019, 07, 21));
		returnHolidayList.add(LocalDate.of(2019, 07, 15));
		returnHolidayList.add(LocalDate.of(2019, 07, 14));
		returnHolidayList.add(LocalDate.of(2019, 07, 7));
        // doReturn(返却するオブジェクト).when(spyしたオブジェクト).method()
        // この書き方忘れる！！
		doReturn(returnHolidayList).when(highHolidayService).selectRecords(anyObject());

		LocalDate date = LocalDate.of(2019, 7, 15);
		List<LocalDate> holidayList = highHolidayService.getHolidayList(date);
		holidayList.forEach(System.out::println);
	}
}
```

クラスごとMock化するのはよくやるからいいんだけど、テスト対象の一部をモック化するのはたまにしか出てこないから忘れるんですよね。。
というか、クラス分けたほうがいいって話が多数で（そうなんだけど、そこまでするまでもないロジックだったりするし）
WDM波長分割多重 - 理想的な高速光ファイバ伝送と拡張

ＷＤＭ（波長分割多重）ＷＤＭシステムは、高速で大容量の情報を長距離伝送するための実装が容易な解決策を提供し、それは通信ネットワークの伝送および拡張を容易にする。

伝統的な光伝送方法は、一本のファイバが一回に一波長信号しか伝送できないのに対し、ＷＤＭは一本のファイバ上で２つ以上の光波長信号を搬送することを実現する。 ＷＤＭは、主に、コンバイナとスプリッタを介して波長多重化および逆多重化を実現し、送信側では、複数の波長の信号がコンバイナによって多重化され、同じ光ファイバに結合されて伝送される。 最後に、異なる波長の光信号がスプリッタによって分離されて元の信号が復元されます。 波長分割多重装置は多重化機能と逆多重化機能の両方を有する。 長距離伝送では、伝送中の光信号を増強するために、光信号伝送における減衰を避けるために光増幅器を途中で使用することもできる。
![16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463940/173ac313-e356-51c4-0df4-e0dc71f1e402.jpeg)
WDMの特性には、挿入損失、リターンロス、偏波損失、チャネルアイソレーション、動作温度などがあります。測定される2つの主な特性は、挿入損失とアイソレーションです。 挿入損失とは、WDMフィルタを光伝送システムに挿入することによる減衰量のことで、挿入損失が小さいほど優れています。 アイソレーションとは、あるチャネルが別のチャネルと干渉する度合いのことです。アイソレーションが高いほど、優れています。
![15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463940/3c8185ed-de53-266b-e97d-36e7c5b31dca.jpeg)
特徴：
伝送容量を掛けます。 ＷＤＭの特徴は、それがファイバの帯域幅資源を最大限に利用することを可能にし、その結果、１つのファイバの伝送容量が単一波長よりも複数倍増加する。 10 Gbit / sまたは2.5 Gbit / sのチャネルレートでは、WDMチャネル数は32以上にもなり、300〜400 Gbit / sの伝送容量が保証されます。

相性がいい。 WDMは異なる信号との互換性がよく、画像、データ、音声などの異なる性質の信号を伝送する場合、各波長は互いに独立しており、互いに干渉しないため、伝送の透明性が保証されます。

既存のネットワークの基本構造を変更しないことに基づいて、できる限り帯域幅を広げ、データ伝送容量を増やすために、WDMは企業が実現できる単純な拡張方法であると言えます。

HYC は光通信パッシブ基本部品の研究開発、製造、販売およびサービスを専門とする国家ハイテク企業です。 同社の主力製品は以下のとおりです。光ファイバコネクタ（データセンター高密度光コネクタ）、波長分割マルチプレクサ、光スプリッタおよびその他の3コア光パッシブ基本コンポーネント、家庭用光ファイバ、4Gモバイル通信で広く使用されている、 インターネットデータセンター、防衛通信、その他の分野
詳しくはウェブサイトをご覧ください。http://www.hyc-system.com
F#でt検定　2クラスの試験成績の比較

# 概要


データ分析なら「Python」か「R」がいいよね。

・・・ということで「**F#**」で「対応なしのt検定」を行なってみました。内容は「[Pythonでt検定　2クラスの試験成績の比較](https://qiita.com/code0327/items/a96dd2fbd8a491d2eeaa)」の移植です。統計量の解説などは Python版 のエントリを参照ください。

なお、F#でデータ分析するにあたって **Accord.NET** というパッケージを利用しました。あらかじめ nuget で Accord.Statistics を導入しておいてください。ここではバージョン 3.8.0 を使いました。

# コード

```FSharp:対応なしt検定
open System
open Accord.Statistics.Testing
open Accord.Statistics.Distributions.Univariate

type m = Accord.Statistics.Measures

[<EntryPoint>]
let main argv =

  let xa = [|75; 87; 89; 80; 84; 81; 88; 83; 88; 88; 82; 72; 74; 93; 77; 67; 88; 84; 68; 84; 80; 78; 75; 71; 82; 74; 84; 77; 79; 76; 83; 75; 86; 76; 80; 76; 68; 72; 75; 85 |] 
           |> Array.map float
  let xb = [|64; 77; 79; 73; 89; 82; 59; 85; 80; 75; 65; 79; 65; 74; 73; 72; 69; 83; 90; 73; 88; 59; 62; 80; 64; 74; 81; 70; 69; 67; 81; 67; 72; 71; 72; 78; 78; 82; 72; 71|]
           |> Array.map float

  printfn "A組の平均点 = %.2f" <| m.Mean(xa)
  printfn "B組の平均点 = %.2f" <| m.Mean(xb)
  printfn "2群の平均点の差 = %.2f" <| Math.Abs( m.Mean(xa) - m.Mean(xb))

  printfn ""
  printfn "標本Aの母集団の平均の推定値 = %.2f" <| m.Mean(xa)
  printfn "標本Bの母集団の平均の推定値 = %.2f" <| m.Mean(xb)
  printfn "標本Aの母集団の標準偏差の推定値（不偏標準偏差）= %.2f" <| m.StandardDeviation(xa,true)
  printfn "標本Bの母集団の標準偏差の推定値（不偏標準偏差）= %.2f" <| m.StandardDeviation(xb,true)

  printfn ""
  printfn "シャピロ・ウィルク検定"
  let swa = new ShapiroWilkTest(xa)
  let swb = new ShapiroWilkTest(xb)
  printfn "標本A p値 = %.3f" <| swa.PValue
  printfn "標本B p値 = %.3f" <| swb.PValue

  printfn ""
  let t = new TDistribution( float (xa.Length-1) )
  let CI1 = m.Mean(xa) + m.StandardError(xa) * t.InverseDistributionFunction(0.025)
  let CI2 = m.Mean(xa) + m.StandardError(xa) * t.InverseDistributionFunction(0.975)
  printfn "標本Aの母平均の95%%信頼区間CI = [%.2f , %.2f]" CI1 CI2
   
  printfn ""
  printfn "ルビーン検定"
  let lvt = new LeveneTest([|xa;xb|], false)
  printfn "p値 = %.3f" <| lvt.PValue
  
  printfn ""
  printfn "対応なしt検定"
  let tt = new TwoSampleTTest(xa,xb,true)
  printfn "p値 = %.3f" <| tt.PValue
  printfn "t値 = %.2f" <| tt.Statistic
  printfn "平均値の差   = %.2f" <| tt.ObservedDifference
  printfn "差の標準誤差 = %.2f" <| tt.StandardError

  let CI1 = tt.ObservedDifference + tt.StandardError * tt.StatisticDistribution.InverseDistributionFunction(0.025)
  let CI2 = tt.ObservedDifference + tt.StandardError * tt.StatisticDistribution.InverseDistributionFunction(0.975)

  printfn "平均値の差の95%%信頼区間CI = [%.2f , %.2f]" CI1 CI2

  Console.ReadKey() |> ignore
  0
```

# 実行結果 

Python で scipy.stats により処理したときと同じ結果が得られています。

```:実行結果
A組の平均点 = 79.60
B組の平均点 = 74.10
2群の平均点の差 = 5.50

標本Aの母集団の平均の推定値 = 79.60
標本Bの母集団の平均の推定値 = 74.10
標本Aの母集団の標準偏差の推定値（不偏標準偏差）= 6.42
標本Bの母集団の標準偏差の推定値（不偏標準偏差）= 7.89

シャピロ・ウィルク検定
標本A p値 = 0.558
標本B p値 = 0.747

標本Aの母平均の95%信頼区間CI = [77.55 , 81.65]

ルビーン検定
p値 = 0.272

対応なしt検定
p値 = 0.001
t値 = 3.42
平均値の差   = 5.50
差の標準誤差 = 1.61
平均値の差の95%信頼区間CI = [2.30 , 8.70]
```
surface laptop でUbuntuをデュアルブートする際、キーボードを使えるように設定しよう！

#はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているにのみやです。

プログラミング初心者なので、間違いも多いと思います。
間違いがあれば、ぜひ教えてください。

# Ubuntuのインストールまで
インストールまでの流れは[この記事](https://qiita.com/tsuyoshi0514/items/b465cc33ff74719895a0)を参考にして行いました。
インストールが完了してパスワードなどを登録する際に、キーボードが使えなくなりましたが、デスクトップの右上にある仮想キーボードを使うと入力できます。
Surface LaptopにはUSBの差込口が一つしかないので、インストールが完了するまでは、外付けのキーボードが使用できないので注意が必要です。

# 本体のキーボードを使用できる状態にする
Ubuntuのインストールが完了したら、本体のキーボードが使えるようにしましょう。
この作業の間は外付けのキーボードを使用するとコードが打ちやすいので楽ちんですよ。

## 手順1.Linux-Surfaceのインストール
[Linux-Surface](https://github.com/jakeday/linux-surface)に書いてある手順通りに進めていきます。

<img width="709" alt="2019-07-19 (2).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423451/ac1b92ce-6511-25d5-3e68-b005690e2620.png">
この部分をやります。

コードを打つには、Linuxの画面左上のマークをクリックし、「端末」という名前のやつをクリックします。
![Ubuntu-ctrl_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423451/0f482123-3c88-8e79-facb-cb630bdc3440.jpeg)


##　手順2.Secure Bootの設定
一度再起動します。
System setupを選択します。（この画面はキーボードの十字キーで操作します）
![system-setup.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423451/76513579-222f-b0e3-3f6f-b7c54877d020.jpeg)
Securityを選択します。
![secrity.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423451/bec1156b-c4ad-a381-7ce7-271b762c5d81.jpeg)


Secure　BootをNoneにします。

![boot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423451/76122429-5a2c-db69-4287-bf6a2043482d.jpeg)
　exitを選択します。
## linuxを変える
今度はAdvanced Options for Ubuntuを選択します。
![options.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423451/345fbe28-f6d8-eda4-af93-c3ab595c82d2.jpeg)
次にsurfaceと書いてあるやつを選択します。（recovery modeじゃないやつ）
![linuxfor.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423451/051d55cd-b429-5d9f-a8ff-fd3332cde098.jpeg)
これでUbuntuが起動すると思います。

##起動しない場合
起動しない場合はUbuntuを最新版にアップデートしてください。
僕は最新版にアップデートしてから、インストールを行ったのでアップデート前にきちんと動作するか確認できていません。ごめんなさい。。。

#終わりに
Ubuntuのインストールの後にwindowsの方を使おうとしたら回復キーが求められることがあります。（僕は求められました）
その場合は[Microsoftのサイト](https://support.microsoft.com/ja-jp/help/4026181/windows-10-find-my-bitlocker-recovery-key)の手順に従って取得してください。
zshでtypoした時に好きな画像を出したい！

探し方を忘れるので自分メモ。

```
$ typo
zsh: command not found: typo
```

これを

```
$ typo
[画像]
typoとかないっちゃろ？
```
にしたい。

を叶えるメモです。
要はtypoした時にしょんぼりしたりイラッとしたりするより好きな画像を見てよし今日もがんばるぞい！って言いたいなって言う話です(大袈裟)
職場で推しメンのセクシー画像だすようにしたらふぁーーーやらかしたファーーー！ってなりました。オススメ()

# 方法

## iTerm2をDL
https://www.iterm2.com/downloads.html
https://qiita.com/noraworld/items/ea59c37e48ac0977cc72
version3以上で。

## imgcatをインストール

iTerm2の公式からシェルスクリプトをコピーします

https://iterm2.com/utilities/imgcat

/usr/local/bin/imgcat

を編集モードで開いてコピーしたシェルスクリプトを貼り付け

ファイルに権限を付与

```
sudo chmod +x /usr/local/bin/imgcat
```

## .zshrcに追記
```
  1 function command_not_found_handler()
  2 {
  3   if [ -e /usr/local/bin/imgcat ];then
  4     if [ -e ~/Pictures/command_not_found.jpg ];then
  5       imgcat ~/Pictures/command_not_found.jpg
  6     fi
  7   fi
  8   echo "$1とかないっちゃろ？"
  9
 10   return 127
 11 }
```

追記したら

```
source ~/.zshrc
```

して反映。

そしてtypoしてみる

ﾀﾊｰ(ﾉ∀`)