OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScriptで配列を検索するメソッドについて

### 記事

JavaScriptで配列を検索する方法は、やり方はさまざまあります。さまざまあるがため、便利である反面、どれを使うのがベストプラクティスなのか判断に迷うこともよくあります。

そんなときには、自分の中で、このような検索をしたい場合は、必ずこのメソッドを使おう。と、決めてしまうことがいいかと思っています。

配列の検索でよく使うメソッドは次の３つです。

- includes
- find
- filter

３つのメソッドは次のように使い分けるといいかと思います。

配列の中に特定の要素が含まれているかどうかだけを知りたい場合は、includesを使う。includesはtrueかfalseを返します。存在すればtrueで、存在しなければfalseを返します。

includesの代わりにindexOfを使って判断をすることもできます。includesがtrueかfalseを返すのに対し、indexOfは存在すれば配列のインデックスを返し、存在しなければ-1を返します。インデックスを知る必要がない場合は、includesを使った方が個人的にはシンプルでいいかと思っています。indexOfを使わざるを得ない用途は個人的にあまり思いつきません。

配列の中に条件にマッチした要素を取得する場合は、findかfilterを使います。マッチするかしないかの判断をするだけでなく、マッチした場合は要素の値を取得したい場合に使います。

条件にマッチした要素が複数存在した場合、最初にマッチした１つの要素だけを取得する場合はfindを使いますが、マッチした要素全てを取得したい場合はfilterを使います。filterの方がfindよりも詳細な情報を取得できるため、イレギュラー要素が発生した場合は、後から調査するために役立つかと思います。findは使わずに、filterしか使わないと決めてしまってもいいかと思います。

### サンプル例

サンプルで次のような配列を作成しました。
```
var ary = ["滋賀県","京都府","大阪府","兵庫県","奈良県","和歌山県","滋賀県"]
var ret;
var msg;
```

配列の中に特定の要素が含まれているかを判断する場合、includesを使います。この場合「滋賀県」が含まれているため、includesはtrueを返します。
```
ret = ary.includes("滋賀県");
msg = ret ? "存在します" : "存在しません";
```

「愛知県」は含まれてないため、includesはfalseを返します。
```
ret = ary.includes("愛知県");
msg = ret ? "存在します" : "存在しません";
```

includesの代わりにindexOfを使うと次のようになります。「愛知県」は含まれないため、indexOfは-1を返します。含まれれば、配列のインデックスを返すため、必ず、0以上が返ってきます。
```
ret = ary.indexOf("愛知県");
msg = (ret => 0) ? "存在します" : "存在しません";
```

このように記述しても同じです。-1より小さい数（-2など）が返ってくることはありません。
```
ret = ary.indexOf("愛知県")
msg = (ret != -1) ? "存在します" : "存在しません";
```

配列の中から文字数が３の要素を選び出します。全角文字も１文字としてカウントされます。配列の中で「和歌山県」以外の要素は全て３文字です。配列の先頭要素から順番に検索して、３文字の条件に該当する「滋賀県」だけを返します。
```
ret = ary.find(el => el.length == 3);
```

条件に該当しない場合は、undefinedが返ります。文字数が１の要素は１つも存在しないため、この場合はundefinedが返ります。
```
ret = ary.find(el => el.length == 1);
```

findを使って「滋賀県」が含まれているかを調べることもできます。ただし、findを使った場合、配列の中に「滋賀県」が１つだけ存在するのか、複数存在するのかまでは分かりません。「滋賀県」が複数存在する場合、いくつ存在しているかを知りたいときは、filterを使えば分かります。
```
ret = ary.find(el => el == "滋賀県");
msg = (ret == "滋賀県") ? "存在します" : "存在しません";
```

文字数が３である要素を全て抜き出したいときは、filterを使います。先ほども書きましたが、findを使うと条件に該当する要素が複数存在していても、一番最初にマッチした１つの要素しか返しません。次の記述では、文字数が３以上の要素、つまり「和歌山県」以外の要素である、[ '滋賀県', '京都府', '大阪府', '兵庫県', '奈良県', '滋賀県' ]を返します。文字列で返すのではなく配列で返します。
```
ret = ary.filter(function(el) {
    return el.length == 3;
});
```

次の記述では、配列で[ '滋賀県', '滋賀県' ]を返します。配列の中に「滋賀県」の要素値が２つ含まれるためです。findでは「滋賀県」が２つ含まれていても「滋賀県」１つを文字列として返します。この辺が、findとfilterの違いということになります。
```
ret = ary.filter(function(el) {
    return el == "滋賀県";
});
```
【Redux】Redux Toolkitを使ってみた

## コンポーネントにどこからでもアクセス！

> Reduxを利用している場合はindex.jsのProviderで包んでいるコンポーネント以下にあるコンポーネントからであればどこからでもアクセスすることができます。その時にはuseSelector Hookでアクセスを行い、useDispatch Hookを利用して更新を行います。


参考にさせていただいた記事

https://reffect.co.jp/react/redux-toolkit#useSelector

## コード

```html:public>index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
```

```js:src>index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { store } from './redux/store';
import { Provider } from 'react-redux';

ReactDOM.render(
  // index.js（親）→store.js（子）?
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);
```

```js:src>App.js
import './App.css';
import { useSelector,useDispatch } from 'react-redux';
import {decrease,increase} from './redux/counterSlice';

function App() {
  const count = useSelector((state) => state.counter.count);
  const dispatch =useDispatch();
  return (
    <div className="App">
      <h1>Count: {count}</h1>
      <button onClick={()=>dispatch(increase())}>Up</button>
      <button onClick={()=>dispatch(decrease())}>Down</button>
    </div>
  );
}

export default App;
```

```js:src>redux>store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';

export const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
});
```

```js:src>redux>counterSlice.js
import { createSlice } from '@reduxjs/toolkit';

export const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    count: 100,
  },
  reducers: {
    increase: (state) => {
      state.count += 1;
    },
    decrease: (state) => {
      state.count -= 1;
    },
  },
});

export const { increase, decrease } = counterSlice.actions;
export default counterSlice.reducer;
```

## ファイルの関係性

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524160/191b0db5-039e-d71c-e31c-c799690219e9.png)

## 疑問

- store.jsの役割？
Windows11にインストールしたDockerの動作確認

1. Docker Desktopを起動する
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258265/afcf9919-f2f0-0383-9e45-d862b5a61edc.png)


2. WindowsスタートからWindowsターミナルをクリックする
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258265/f3dc241b-ec21-d2a8-ceb2-6892bb1783b9.png)

3. Windows PowerShellが起動する
 ∨をクリックしてUbuntuをクリックする 
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258265/366f60dc-25ef-89ff-90c3-82259c69b211.png)

4. docker ps -a のコマンドを入力すると、起動していないコンテナが表示される
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258265/53e29b93-faa9-5d49-85c4-0100837beb8c.png)

5. docker run hello-world のコマンドでhello-worldを実行してみる
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258265/b74ec71e-8d2b-1980-c591-8aea48c3bef2.png)

6. exit　コマンドでUbuntuを終了する

7. WSLのディレクトリにアクセスする　\\wsl$\Ubuntu\home
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258265/23782c11-1af5-ae67-0269-81ff677bc41c.png)
k6で負荷試験を学んだ（Smokeテスト/Loadテスト/Stressテスト/Spikeテスト/Soakテスト）

k6という負荷試験のツールを見つけました。Grafana Labsのプロダクトです。負荷試験の勉強になりましたので、翻訳しながら紹介します。

https://k6.io/

# 負荷試験の種類

* スモークテスト
* 負荷テスト
* ストレステスト
* スパイクテスト
* ソークテスト

![](https://raw.githubusercontent.com/grafana/k6-docs/main/src/data/markdown/translated-guides/en/05%20Test%20Types/images/test-types.png)

## スモークテスト

スモークテストの役割は、システムが問題なく最小限の負荷を処理できることを確認することです。

**目的**

* テストスクリプトにエラーがないことを確認します。
* 最小の負荷でシステムがエラーをスローしないことを確認します。

**例**

一人のユーザーが1分間アクセスし、リクエストの99%以上が1.5秒以内にレスポンスを返却することを確認

**アクセス数**

![](https://github.com/grafana/k6-docs/blob/main/src/data/markdown/translated-guides/en/05%20Test%20Types/images/smoke-test.png?raw=true)

## 負荷テスト

負荷テストは主に、同時ユーザーまたは1秒あたりのリクエスト数の観点からシステムのパフォーマンスを評価することに関係しています。

**目的**

* 通常の負荷とピーク負荷の下でのシステムの現在のパフォーマンスを評価します。
* システム（コードとインフラストラクチャ）に変更を加えるときは、引き続きパフォーマンス基準を満たしていることを確認してください。

**例**

運用のピーク時に100人のユーザーがいるとします。はじめの5分間でユーザーが0人から100人に増加し、ユーザーが100人の状態で10分間アクセスを継続。その後5分間かけてユーザーが0人まで減少する。このリクエストを行い、リクエストの99%以上が1.5秒以内にレスポンスを返却することを確認。

**アクセス数**

![](https://github.com/grafana/k6-docs/blob/main/src/data/markdown/translated-guides/en/05%20Test%20Types/images/load-test.png?raw=true)

## ストレステスト

ストレステストは、システムの限界を判断するために使用される負荷テストの一種です。このテストの目的は、極端な条件下でのシステムの安定性と信頼性を検証することです。

**目的**

* 極端な条件下でのシステムの動作。
* ユーザーまたはスループットの観点から、システムの最大容量はどれくらいですか。
* システムの限界点とその障害モード。
* ストレステストが終了した後、手動の介入なしでシステムが回復する場合。

**例**

2分ごとに100ユーザー増加し高負荷状態で5分継続。インフラストラクチャが自動スケーリングするように構成されている場合、自動スケーリングメカニズムが負荷の増加にどれだけ迅速に反応するか、スケーリングイベント中に障害が発生しないかを確認することができます。

**アクセス数**

![](https://github.com/grafana/k6-docs/blob/main/src/data/markdown/translated-guides/en/05%20Test%20Types/images/stress-test.png?raw=true)

## スパイクテスト

スパイクテストはストレステストのバリエーションですが、負荷が徐々に増加することはありません。代わりに、非常に短い期間で極端な負荷に急上昇します。ストレステストではSUT（テスト対象システム）のインフラストラクチャを段階的にスケールアップできますが、スパイクテストではできません。

**目的**

* 突然のトラフィックの急増の下でシステムがどのように機能するか。
* トラフィックが落ち着いたらシステムが回復するかどうか。

**例**

スパイクテストの典型的な必要性は、スーパーボウルや人気のある歌の競技会などの大きなテレビイベントで広告を購入した場合です。

**アクセス数**

![](https://github.com/grafana/k6-docs/blob/main/src/data/markdown/translated-guides/en/05%20Test%20Types/images/spike-test.png?raw=true)

## ソークテスト

ソークテストは、長期間にわたるシステムの信頼性とパフォーマンスについて教えてくれます。

**目的**

* システムにバグやメモリリークが発生していないことを確認します。これにより、数時間の操作後にクラッシュまたは再起動が発生します。
* 予想されるアプリケーションの再起動によってリクエストが失われないことを確認します。
* 散発的に発生する競合状態に関連するバグを見つけます。
* データベースが割り当てられたストレージスペースを使い果たして停止しないことを確認してください。
* ログが割り当てられたディスクストレージを使い果たしていないことを確認してください。
* 依存している外部サービスが、一定量のリクエストが実行された後も機能を停止しないようにしてください。

**例**

想定されるアクセス数の80%のアクセスを4時間継続させて実施する

**アクセス数**

![](https://github.com/grafana/k6-docs/blob/main/src/data/markdown/translated-guides/en/05%20Test%20Types/images/soak-test.png?raw=true)
dig コマンドインストール

# dig コマンドインストール

`dig`コマンドは、`bind-utils`というパッケージに入っている。

```
$ rpm -qf /usr/bin/dig
bind-utils-9.11.36-3.el8.x86_64
```

なので、bind-utilsをインストールするとdigが使えるようになる。
bind-utilsは(RockyLinux8の場合)appstreamのリポジトリに入っているので、
そのまま`dnf install bind-utils`でインストールできる。

```
# dnf install bind-utils -y
メタデータの期限切れの最終確認: 1:25:22 時間前の 2022年06月19日 13時14分40秒 に実施しました。
依存関係が解決しました。
================================================================================
 パッケージ               アーキテクチャー バージョン                  リポジトリー        サイズ
================================================================================
インストール:
 bind-utils               x86_64           32:9.11.36-3.el8             appstream           451 k
依存関係のインストール:
 bind-libs                x86_64           32:9.11.36-3.el8             appstream           174 k
 bind-libs-lite           x86_64           32:9.11.36-3.el8             appstream           1.2 M
 bind-license             noarch           32:9.11.36-3.el8             appstream           102 k
 fstrm                    x86_64           0.6.1-2.el8                  appstream            28 k
 protobuf-c               x86_64           1.3.0-6.el8                  appstream            36 k
 python3-bind             noarch           32:9.11.36-3.el8             appstream           149 k

トランザクションの概要
================================================================================
インストール  7 パッケージ

~~略~~

インストール済み:
  bind-libs-32:9.11.36-3.el8.x86_64 bind-libs-lite-32:9.11.36-3.el8.x86_64
  bind-license-32:9.11.36-3.el8.noarch bind-utils-32:9.11.36-3.el8.x86_64 fstrm-0.6.1-2.el8.x86_64
  protobuf-c-1.3.0-6.el8.x86_64     python3-bind-32:9.11.36-3.el8.noarch  

完了しました!
```

以上。
laravel + react + typescript でtypescriptの設定

typescriptの書き方がbuildでエラーになったりして、少しハマったので、記録

webpack.mix.jsに下記を定義する

```
mix.webpackConfig({
    module: {
        rules: [
            {
                test: /\.(tsx|ts)$/,
                loader: "ts-loader",
            },
        ],
    },
})
```
AngularでSSR環境を作成する

# Express で AngularSSR を利用する

## table of contents

0. Angulr のプロジェクトを作成する
1. `@nguniversal/express-engine` を利用して SSR を実装する

## before development

環境

|Package                        | Version|
|:--------------------------|-------------------------------|
|@angular-devkit/architect      | 0.1303.8|
|@angular-devkit/build-angular  | 13.3.8|
|@angular-devkit/core            |13.3.8|
|@angular-devkit/schematics      |13.3.8|
|@angular/cli                    |13.3.8|
|@nguniversal/builders           |13.1.1|
|@nguniversal/express-engine     |13.1.1|
|@schematics/angular          |   13.3.8|
|rxjs                          |  6.6.7|
|typescript                     | 4.6.4|

## 1. Angular の Project を作成する

`ng command`を利用して Angular のプロジェクトを作成します。

```terminal
% ng new angular-ssr-express
? Would you like to add Angular routing? Yes
? Which stylesheet format would you like to use? SCSS   [ https://sass-lang.com/documentation/syntax#scss

% cd angular-ssr-express
```

起動して、angular が動くか確認します。

```
% npm run serve
```

[localhost:4200](http://localhost:4200/)を起動して確認します。
また、[serverからの返却データ](view-source:http://localhost:4200/)も同様に確認します。

![base-angular.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/fa2797eb-0625-3236-d5aa-a242b7eda9ee.png)
![スクリーンショット 2022-06-19 12.17.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/fb57c035-c76e-f773-e295-89d06986cc22.png)


## 2. `@nguniversal/express-engine` を利用して SSR を実装する

`@nguniversal/express-engine`を install して環境を整える。

```
% ng add @nguniversal/express-engine
The package @nguniversal/express-engine@13.1.1 will be installed and executed.
Would you like to proceed? Yes
```

Manual インストールではないため、SSR の環境も同時に設定されます。

設定ができたか確認するため、Server を起動してみます。

```
% npm run dev:ssr
```

[Browser](http://localhost:4200)からは同様に変更がないことを確認します。
[SSR Localhost:4200](view-source:http://localhost:4200/)で Server からのデータを確認します。

![base-angular.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/8386e123-bf5b-23d5-4b75-0dc7cf69f65f.png)

![スクリーンショット 2022-06-19 12.43.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144543/7f6c26a1-d758-3f77-5a5c-1f8531fba08a.png)
首のヘルニアを知ってもらいたい

# 知っていれば予防できた首のヘルニア

首のヘルニアになり、思うように仕事ができず、困ったことがある。
知っていれば予防できたので、少しでも多くの方に知って頂ければと思い、書きました。

## 原因

1. __悪い姿勢__
    - 猫背
    - アゴを前に出した、首に負担がかかる姿勢（※モニタやスマホを見る時になりやすい）

1. __加齢__
    - 30～50代に多い

## 予防法

1. __作業中の姿勢を見直す__
    - 背筋を伸ばす、胸を張る
    - アゴを少し引くように意識する（※これが一番、伝えたいこと）

1. __作業環境を見直す__
    - イスの高さは、高過ぎないか（※高過ぎると、首を大きく曲げるため、負担がかかる）
    - モニタやスマホの位置は、なるべく顔の正面に（※首に負担をかけないようにする）

1. __枕を見直す__
    - 枕を見直すことで、睡眠中も、首に負担をかけないようにする

## 症状 

1. __手や足が痺（しび）れる__
    - 身体を動かすと、「ピリピリ」と一瞬しびれる

1. __身体の感覚が鈍くなった__
    - 身体を動かした際、感覚が鈍く感じられる
        - 例：物に触れた際の感覚が、一瞬遅れて感じられるなど、タイムラグがある

1. __めまい、頭痛、耳鳴りがする__
    - 乗り物酔いのような、吐き気を伴う気分の悪さが続く

1. __目が疲れやすい__
    - 目の奥の方が痛い
    - 目薬をさしても、あまり良くならない

## 免責

* 医療の専門家ではない私が、ネットや本から得た情報をもとに書いた記事ですので、正確ではないかもしれません。
* 不調が続く場合は、医療機関を受診されることをおススメします。（※受診する場合は「整形外科」）
OSI 参照モデル

ネットワーク接続において、基本となるモデルがosi参照モデル

アプリケーション、プレゼンテーション、セッション、トランスポート、ネットワーク、データリンク、物理の７層ある


tcp/ip  は４層ある（アプリケーション、トランスポート、インターネット、NIC）

TCPとUDP

TCPはSTATEFUL CONNECTION-BASED RELIABLE

udp STATELESS REALTIME RAPID 

PACKET IP
FRAME DATALINK

PACKET HEADER PAYLOAD

SOURCE DESTINATION IP/PORT
CHECKSUM
SEQUENCE NUMBER 
FLAG
仮想マシン上にDockerをインストールする

# 構築環境
macOS Catalina 10.15.7
VirtualBox 6.1.14
* CentOS 7
* docker 20.10.17

# 参考文献
https://docs.docker.jp/engine/installation/linux/docker-ce/centos.html#id17

## 構築について
macOSへのdockerの導入にはGUI操作のものもあるが
+ とにかくCLI操作に慣れるため
+ ファイル管理に慣れてからメイン機器に導入したい
+ 操作ミス、詰まりの際のやり直しの簡易さ

上記の理由で仮想環境上での構築を始める

# 導入
```
# yum update
```
上記でインストール済みパッケージのアップデートをしておく

```
$ sudo yum install -y  yum-utils device-mapper-persistent-data lvm2
```
リポジトリからのセットアップに必要なパッケージのインストールを上記コマンドで行う

自分の環境ではすでにインストール済みになっていた。
```
$ sudo yum-config-manager --add-repo https://download.docker.com/licux/centos/docker-ce.repo
```
リポジトリをセットアップ
Edge版やテスト版は使う予定がないので今回は有効化の手順はスキップ
```
最新版のインストール
$ sudo yum install docker-ce
 or
インストールするバージョン確認
$ sudo yum docker-ce.x86-64 --showduplicates | sort -r
$ sudo yum install docker-ce-<パッケージ文字列>
```
上記どちらかでdockerを導入
鍵の確認があるため'-y'オプションで飛ばさないほうが良い
```
$ sudo systemctl start docker
＄ sudo systemctl status docker
```
システムの起動を行い、念のためstatusコマンドでちゃんと稼働しているか確認
(running)表記があればOK

```
$ sudo docker run hello-world
```
上記コマンドでdocker-hubからイメージのダウンロードと実行を行い何事もなければ無事インストール終了

## 終わりに
今回は導入バージョンに拘らなかったがメイン機器への導入はしっかり安定版などの情報を収集してから行う。
Java使いからPHPerに転身した際にはまったこと

# 概略
業界に入ってから長らくJavaをメインで使っていたプログラマである筆者が、業務でPHPを使うようになった際にはまったことを思い出して列挙していく。
詰まった時しか公式リファレンスとか見ないから何となくでやるとびっくりしてしまう。

## マルチスレッド
Javaだとマルチスレッド当たり前なので、シングルトンだったりstaticな変数を更新していたりすると「そんなバカな、死にたいのか！？」と思ったりしたが、Webアプリケーションとして動くPHPでは通常リクエストごとに別プロセスが起動していてそんな問題になることはないようだった。

## arrayがプリミティブ風に動く
内部的にどういう扱いになっているのか具体的にわかっていないけれど、arrayを代入したら別の配列となる。
Java的な常識だと同じオブジェクトの参照となるイメージだったから衝撃だった。
javaだと
```java:Main.java
public class Main {
  public static void main(String[] args) {
    int[] array1 = {10, 20, 30};
    int[] array2 = array1;
    array2[1] = 40;
    System.out.println(array1[1]); // 40
  }
}
```
PHPだと
```PHP
<?php
$array1 = [10, 20, 30];
$array2 = $array1;
$array2[1] = 40;
echo $array1[1]; // 20
```

## ~~組み込み関数がユーザ~~ issetは通常の関数と異なる動作をする

~~issetなどに渡すものは内部が実行された結果を渡されるのではない。~~
issetは関数ではなく言語構造なのだそうだ。指摘ありがとうございます。
確かに公式にちゃんと書かれていた。
https://www.php.net/manual/ja/function.isset.php#refsect1-function.isset-notes

Javaかけるから何とでもなるでしょーって調子こくとダメだな。。

```
$null = null;
echo isset($null[1]); // ここでアクセスできないとなるかと思いきやfalseが返る
some_method($null[1]); // ここではエラー発生する
```

## ケースインセンシティブなところがある
大文字小文字を気にしてないところがある。
気にするところもある。
なんだこれ
```
<?php
function hoge(){
    echo 'hogehoge';
}

class MyClass {
    function fuga(){
        echo 'fugafuga';
    }
}

HOGE(); // hogehoge
ECHO PHP_EOL;
$class = new MYCLASS();
$class->FUGA(); // fugafuga
```

## 変数の$が重ねられる
僕自身がJavaから入ったとか関係なく衝撃だった
リフレクションとかのイメージ

```PHP
<?php
function some_method(){
    echo 'piyo';
}
$hoge = 'some_method';
$fuga = 'hoge';
$$fuga(); // piyo
```

## 参照渡しできる
これは単純にJavaにないからほえーっとなった

```PHP
<?php
function some_method(&$hoge){
    $hoge = 'fuga';
}
$hoge = 'hoge';
some_method($hoge);
echo $hoge; // fuga
```

## ブロックスコープがない
以下のコードだとコンパイル通らないという感覚になってしまう。
```PHP
<?php
$bool = true;
if ($bool) {
    $message = 'hoge';
} else {
    $message = 'fuga';
}
echo $message; // hoge
```

一旦これくらいで。
anacondaアプデ備忘録

#　はじめに
navigatorからアプデがよく失敗するので自分用に残しておく。

## anacondaのアップデート方法

本体のアップデート
~~~
conda update -n base conda
~~~

パッケージ一式アップデート
~~~
conda update --all
~~~

navigatorの調子が悪いときはnavigatorのアプデをする
~~~
conda update anaconda-navigator
~~~

# おわりに
とりあえずこれらを実行すればanacondaのアプデはできる。
Webサイト公開手順を解説(前編)

---
## 挨拶
こんにちは！私はWebエンジニア志望の大学3年生です。エンジニア志望としてアウトプットをしたいと思い、Qiitaを始めました。実務未経験、かつ文系大学出身なので、内容に怪しい点は多々あると思いますが、初心者にもわかりやすい内容の記事にしていきたいと思います。

## はじめに
### ・Webサイトをインターネット上に公開するには？
HTMLやCSSのファイルを作った後、サーバーとドメインを取得して、ファイルをサーバーに配置して公開します。

サーバーやドメインは、有料のものから無料のものまで様々なサービスがあり、初心者のうちはどれにしたらよいか見当もつかないほどの種類があります。今回は無料かつ複数のファイルでも対応できる**firebase**という、Googleの超便利なサービスを利用します。

よくGitHubPagesというGitHubのサービスを利用したほうが楽だということもたびたび言われていますが、あちらは動的なサイトが表示できない、つまり**複数のファイルを読み込めない**という欠点があるので、今回は省略します。


### ・firebaseとは？
モバイルアプリやWebアプリケーションの様々な機能がそろったプラットフォームのことです。2014年にGoogleが買収し、それ以降Googleのサービスとして利用されています。
魅力は何といっても**無料**で利用できるところです。一部有料な部分はありますが、Webサイトを個人的に公開したいという人にとっては最適のサービスです。

## firebaseを使ってみよう！
### ①Googleアカウントの取得
当然ですが、GoogleのサービスなのでGoogleのアカウントが必要です。
持っていない方は事前にアカウントを作成しておきましょう。
### ②firebaseへログイン！
下記のURLからへGoogleアカウントを使ってログインします。
https://firebase.google.com/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706504/6a28a0fc-fff4-7e9a-b3a2-bc6ac96ab055.png)

### ③プロジェクトの作成
ログイン後、プロジェクトの項目があるので、そこをクリックしてプロジェクトの追加を選択します。
![スクリーンショット (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2706504/40d29929-f104-8b7d-9e6e-642f7ce16b7d.png)

## 環境設定
### ①node.jsのインストール
え？node.jsってなに？と思うかもしれませんが、firebaseを使うためには必要なものです。node.jsは簡単に言えばjavascriptという言語の実行環境のことです。下記のURLで”LTS推奨版”をインストールします。
https://nodejs.org/ja/
### ②インストールされたか確認
インストールしてFinishをクリックした後、コマンドで確認します。
node –version
このコマンドを打ち込んで、バージョンが表示されればインストールは完了です。
### ③firebase toolのインストール
npm install -g firebase-tools
このコマンドを入力してインストールすることで、firebaseの様々な機能を利用することができます。
### ④ログイン
ここでインストールされたか確認するため、下記のコマンドで再度ログインします。
firebase login
Successと表示されれば準備は完了です。

今回はここまでです。ちなみにコマンドで操作する際、うまくいかなかった人はユーザーでコマンドを起動していませんか？コマンドは管理者権限で実行するとトラブルなく作業できると思います。私はfirebaseを利用するまでコマンド機能を利用したことがほぼなかったので、今回の作業だけでもかなり苦労しました。この先もコマンドは利用しますので、逐次調べながら作業していくといいと思います。

次はいよいよWebサイトを公開するまでについて解説していきます！
最後までお読みいただき、ありがとうございました！
Railsでcheckboxとvalidationを使っただけなのに

## 結論

- `form.check_box`はfalse値を送信できない。
- Ruby on Railsでmodelの真偽値(true/false)のvalidationを書くときは、`presence: true`ではなく`inclusion: [true, false]`を使わないといけない。

## 経緯

[Rails をはじめよう](https://railsguides.jp/getting_started.html)に沿ってrailsを触ってみていました。ただ、そのままやるのはおもしろくないなと思ったため、ガイドでは記事(`Article`)を表示するウェブページを作成したところを、少しだけアレンジして`Todo`を表示するものとして作成していました。`Todo`は`Article`のもつ値に加えて`hasDone`という完了済みか否かを表す値を持ちます。

`hasDone`は`Todo`を作成するときに、View側からは

```erb
  <div>
    <%= form.label :hasDone %><br>
    <%= form.check_box :hasDone, {checked: false}, true, false %>
  </div>
```

`form.check_box`を使って指定するような形にしました。

また、バリデーションも有効化してありました。

```ruby
class Todo < ApplicationRecord
  validates :title, presence: true
  validates :body, presence: true
  validates :hasDone, presence: true
end
```

## 現象

check_boxをチェックすると問題なくレコードが作成されるのですが、check_boxをチェックしていないと、`@todo.save`を実行時保存に失敗するようになってしまいました。

## 問題点

１つ目は、`form.check_box`がfalseの値を送信**しない**ことです。これは[Railsのcheck_boxのチェック時、アンチェック時にどんな値がサーバに送られるか](https://mnmandahalf.hatenablog.com/entry/2017/08/20/164442)が詳しいのでこちらを参照ください。

２つ目は、真偽値のバリデーションに`presence:`を使ってはいけないことです。[Railsガイドのpresence](https://railsguides.jp/active_record_validations.html#presence)や[公式ドキュメントの該当箇所](https://guides.rubyonrails.org/active_record_validations.html#presence)には、このケースの取り扱い方法が載っています。

`presence: true`を指定すると、Railsは内部でfieldが存在するかどうかを`.blank?`で調査しています。しかし、`false.blank?`は必ず`false`を返すため、真偽値のバリデーションに`presence`を使ってはならず、かわりに`inclusion: [true, false]`を使うようにとのことでした。

## 解決方法

本当は`form.check_box`になんとかして`false`値を送ってもらいたかったのですが、難しそうだったので以下のようにController側で処理することにしました。

```ruby
def create
    # もとのオブジェクトは変更できない
    p = todo_params
    # フォームの入力がfalseの場合、keyなしのparamsが渡されるため
    # validation前にfalseを埋め込む
    if !p.respond_to? :hasDone
        p[:hasDone] = false
    end
    @todo = Todo.new(p)

    if @todo.save
        redirect_to @todo
    else
        render :new, status: :unprocessable_entity
    end
end

private
  def todo_params
    params.require(:todo).permit(:title, :body, :hasDone)
  end
```

また、model側もドキュメントの通りに変更を加えました。

```ruby
class Todo < ApplicationRecord
  validates :title, presence: true
  validates :body, presence: true
  validates :hasDone, inclusion: [true, false]
end
```

この状態でフォームから送信したところ、問題なくレコードが作成されました。

## まとめ

- check_boxはfalse値を送信しない。なにかしらのハンドリングや、真偽値の送信に別の方法(0/1など)を使わないといけなさそう。
- modelのvalidationは、それぞれの型にあったものを選ぶ。真偽値の場合は`inclusion: [true, false]`。

今回はなにげなく２つ知らなかったことを踏んでいたので、解決にだいぶ時間がかかりました。この記事が私と同じように「ちょっと試してみただけなのに」で大ハマリした人を抜け出せさせられたらなと思います。
Unityでも単体テストを書こう！

### 謝罪

社内勉強会向けのスライドをQiitaに移植したものです。
レイアウトが崩れている箇所がございますが、何卒ご了承下さい。

---

### Unityエンジニアへ

---

### 単体テストを一緒に書こうぜ！！

---

### こんな経験ありませんか？

バグを１つ修正したら、
今までちゃんと動いていた別の箇所がバグった！

---

### バグを直すと別の箇所がバグる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/1d6cb530-807e-35f3-3b96-fa0f41188a5c.png)

※矢印はクラスの参照を表します。

B君とC君の都合を考えてからA君を修正すればいいの？

---

### 現実はもっと複雑・・・

様々な登場人物が複雑に参照しあっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/ed3995e5-30a3-7ce5-e700-2d1354852f71.png)

すべての登場人物の都合を考えるのは無理！！

---

### 勝手な変更されないように単体テストを作って監視しよう


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/6c1ad4df-9513-5aa8-8572-6b5140b7629a.png)

単体テストを作ってクラスの動作を保証しよう！

---

### 単体テストを書こう！

---

### Unityで単体テストを書くには？

---

### asmdefがないとUnityで単体テストが導入できない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/a8c45a86-841b-a6c4-4a4c-944f2c6fa572.png)

---

### asmdefがあればUnityで単体テストが導入できる！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/ed6804ad-1b0d-fc4b-60e9-8f36d76e0a97.png)

asmdefを導入しよう！

---

### asmdef(AssemblyDefinition)とは？

Unityでは、C#ファイルのまとまりをアセンブリと定義することができる。

Unityにおけるアセンブリとは？

- C言語でいう .so , .lib 
- .NETでいう .dll
- Javaでいう .jar

のようなもの

---

### asmdefを導入しよう！

---

### 参照先が対応していないと参照元が対応できない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/2d83a039-6731-7213-d51b-fa0885a6fb74.png)

---

### 参照先が対応していないと参照元が対応できない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/eb94d270-4daa-cf52-caa0-a01a9c68fe52.png)

---

### 参照先が対応していないと参照元が対応できない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/e74db1cc-2abd-0332-d077-60bfc5760d99.png)

末端からasmdefを導入しよう！

---

### 末端から少しずつasmdefを導入しよう！

---

### 現実はもっともっと複雑・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/0a4a16d1-c106-29fc-ffec-34727f376b17.png)

末端はどこ？

---

### 参照方向をそろえよう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/63b9b471-264e-8afe-ab26-a2168219a14e.png)

泥臭い作業が必要だけど、参照方向をそろえよう！

---

### 参照方向をどうやってそろえるの？

大変だけど様々な方法を駆使すればできます！

- 依存性逆転の原則
- 依存性の注入

詳しくはググってください

---

### すごく大変そうだけどそこまでやる価値あるの？

---

### やる価値あります！

---

### 単体テストなし vs あり

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/6b95c42f-4aa5-b9c2-c4c7-cf3d8a323d94.png)

---

### プログラマーの学習コストが大幅に下がります！

---

### 学習コストが下がれば多人数開発がしやすくなります

---

### 多人数開発ができれば製品の開発スピードが向上します

---

### これがいわゆる疎結合！

---

### 泥臭い作業が必要なのは自分の代だけ！
（ババ引いたとか言わないで）

---

### 単体テストを書こう！
今日の予算なんだっけ？私が簡単音声やり取りで教えてあげましょう！

こんにちは！
千葉県在住、商業デベロッパーの会社で新規事業の企画検討をしています。
様々な分野への知見を広げるために、絶賛デジタル技術を勉強中です。

今回は「**Voiceflow**」を使って、指定した日の予算や実績、予算比を教えてくれるシステムを作ってみました！！

https://www.voiceflow.com/

 ## 朝礼での数値共有、右から左に流れる、あると思います。
私は現在本社部署ですが、
数年前までは店舗勤務という商業施設にある管理事務所に勤務していました。
店舗の管理事務所では毎日朝礼があり、その日の予算、前日の実績等々を**口頭で共有**していました。
正直流れ作業のようになっている面もあり、毎日聞いているといざというときにパッと出て来ません。。笑
私だけではないはず。。。
その度に売上管理システムやExcelの管理表を見てもいいんですが、
**聞いたらサッと教えてくれる仕組み**欲しいなーと思い、「**Voiceflow**」でチャレンジしてみました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667978/0bcbed9f-49c7-e896-3074-7dde6f8ca067.png)
そう、まさに**このイメージ**！ではいきます笑

 ## まずは完成品をどうぞ！！
肝の音声認識の部分はテキストでご勘弁を！
なにを聞きたいのか、何日なのかを話すとその数値を教えてくれます！

https://twitter.com/Shinmura_opa/status/1538192422504919040

 ### 続いて開発画面をどうぞ！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667978/97797e89-4dc6-1389-ab20-da9313d090a8.png)
これ予算・実績・予算比の分岐からそれぞれほぼ同じノードで作ってるんですが、
なんか**ひとつにまとめられる気はする**。。今回は一旦これで！！笑

 ## 細かい画面を見ていこう
今回は予算・実績・予算比の３つを教えてくれるものを作ったので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667978/89d0aa7d-6cb8-fdec-a263-0ffba82f6667.png)
「Choice」ノードを使って「**yosan**」「**zisseki**」「**yosanhi**」の**３つの分岐**を作りました。
ここからそれぞれをGoogleスプレッドシートのデータ表に繋ぎたいんですけど、全然うまくいかず。。
どのノードを使ったらいいのか、、めちゃ調べました。。
結論としては今回はこれ！「**Capture**」というノードを使いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667978/672f55b5-b840-94ea-ef4e-58abc84a7d45.png)
ひとつ前のノードで受け取ったユーザーの声を「**date**」**という変数にしている**と解釈してます。違ったらすみません！！笑

これを「Google Sheets」ノードに繋げます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667978/6805063f-4018-5385-0d57-037b69ecd0a1.png)
今回はデータの取得なので、１番上の「Retrieve Data」ですね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667978/768ac76e-2801-00ac-838a-056258bcb55d.png)
「date」変数にしたユーザーの声とスプレッドシートの日付を照合して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667978/b5439a88-4fcf-3802-7f5e-02e9e9130094.png)
該当する日付の予算の列をアウトプットするように設定！
<details><summary>参照元のスプレッドシートはこちら！</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667978/9acdccd7-01fb-3920-74c6-20f7f1362a2a.png)
ご参考までに！

</details>

最後にそれぞれの変数を喋るように設定して完了！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667978/020a20bd-02ae-9a24-b61c-22167ae977bf.png)
これを３つそれぞれの分岐で設定しています。

 ## 作ってみた感想
私事ですが、デジタル技術を勉強し始めて**約１か月**が経ちました。
実用性はまあプロトタイプなので置いといて、
初期の頃に比べると**思ったものをしっかりカタチにすることが出来ています**。
成長したなぁと。。しみじみ。
まだまだ色んなツールを使いこなせているわけでもない**初心者**なのですが、
これまで勉強した技術を総動員して、ちゃんとなにかの役に立つものを作りたいなと思います！
引き続き、応援よろしくお願いします～！！

では！ここまで読んでいただきありがとうございました！！
基数変換の仕組み

# 基数変換とは
普段私達が扱う数字は10進数の場合がほとんどですよね！
ただIT業界に飛び込み、
・基本情報をとる！
・組み込み系の現場で計算が結構必要！？
となると2進数や16進数への変換は避けて通れないです。。。

さてここでは基数変換の方法や
よく耳にする「重み」という言葉について
説明します！

ここで説明する変換のやり方は参考書によく載っている内容では
ないかもしれません。

言われれば当たり前のことしか言っていない内容かもしれませんが、
以下の内容を理解すれば、基数変換は簡単に感じることができている
はず！

それでは言ってみましょう！

# 重みとは
参考書を開くとよくこの言葉を見かけますよね。
まあ書いてる通りなのかもしれませんが、まず以下の
例を見てみてください。

### 例
10進数： 51
これって以下のように表現できることはお分かりでしょうか？

```
(10¹　✖︎ 5) + (10⁰ ✖︎ 1) = 50 + 1 = 51
```
ご確認ありがとうございます。
さてなぜこんな書き方をしたのか？

この表現は「重み」という言葉を分かりやすくするための
ものになります！

では次に
10進数： 1847
はどう表現できますでしょうか？
```
(10³ ✖︎ 1) + (10² ✖︎ 8) + (10¹　✖︎ 4) + (10⁰ ✖︎ 7) = 1000 + 800 + 40 + 7 = 1847
```
お気づきの方もいらっしゃるかもしれませんが、10進数の場合
それぞれの位を「10ⁿ」という数値で扱ってます。

この「10」を、<font color="Red">重み</font>と呼ばれています。

### 2進数
では2進数はどうなるか見てみましょう。
2進数： 1010
これを先程の方法で表現すると。。。
```
(2³ ✖︎ 1) + (2² ✖︎ 0) + (2¹　✖︎ 1) + (2⁰ ✖︎ 0) = 8 + 0 + 2 + 0 = 10(10進数)
```
先程の違いは、重みが「2」に変わっていることです。
おや？10進数で表すことができましたね！

一見当たり前のようですが、
この重みについて理解しておけばN進数→10進数への変換は容易です！

では次に10進数→N進数をやってみましょう！

# 10進数→N進数
正直言うとこの方法では値が大きくなると
少々時間がかかります。

参考書によく載っているやり方の方が早いよと感じる方は
そちらを使用してください！

あくまで本記事は基数変換の仕組みを解説する内容になります。
それを考慮された上で閲覧いただけると幸いです。

### 例
10進数： 94
これを2進数に変換してみましょう！
2ⁿで表すには、どうすればいいか？
まず以下を考えてみます！
```
2ⁿ < 94 2(n+1乗)
```
※すみません、n+1乗の表記ができませんでした。。

これを求めると、n=6になることはお分かりでしょうか？
```
2⁶ = 64、 2⁷ = 128
64 < 94 < 128
```
2進数で64は以下のようになります。
・2進数：1000000 (64)
では94から64をひいた３０の値を同様に求めていきます！
```
2⁴ = 16、 2⁵ = 32
16 < 30 < 32
```
・2進数：1010000 → 80
・残り14
```
2³ = 8、 2⁴ = 16
8 < 30 < 16
```
・2進数：1011000 → 88
・残り6
```
2² = 4、 2³ = 8
4 < 6 < 8
```
・2進数：1011100 → 92
・残り2

最後に「２」は「2¹」の位に「1」をつければ表現できるので、
答えは
・2進数：1011110 (94)
となります！ 

正直周りくどいというか、
時間がかかりますのでやり方としてはスマートではないかもしれません。


# 最後に
いかがでしたでしょうか？
重みについて理解いただければN進数→10進数の変換は
決して難しくありません。

反対は時間がかかりますが、他のやり方が抜けた場合や
慣れてくると暗算で求めることもできるかと思いますので
そういった場合に思い出していただけると幸いです。

重みがどういった役割をしているかを意識して、
取り組んでみてはいかがでしょうか？
SREを理解する（SLI / SLO / SLA）

# 【SREを理解する（SLI / SLO / SLA）】
SREの基礎をざっくり学習
通常は、SLA → SLO → SLI の順番で設定することが一般的

## SLI (Service Level Indicators)：サービスレベル指標
**あらかじめ決めたユーザーの利用するサービスがユーザーが許容できる範囲で完了するまでの指標**

- 良いイベント数 / すべてのイベント数 ✕ 100 = SLI

- 良いイベントの設定はユーザーがサービスを利用するにあたり、最も重要に考えられることを設定する必要がある
    - データ処理の正確性
    - データの鮮度
    - スループット ..etc

- SLIはシンプルにしよう！！
    - 2~6個にする

- SLIを設定する際の定義（例）
    - 定義1：リクエスト・レスポンス
        - 可用性、応答スピード、品質
    - 定義2：データ処理
        - 可用性、正確性、鮮度、スループット
    - 定義3：ストレージ
        - 耐久性、冗長性、復旧時間

## SLO (Service Level Objectives)：サービスレベル目標
**SLIで設定した値以内で完了したサービス提供回数がすべてのサービス提供回数のうち、 どのぐらいの割合で提供できればいいかという目標値**

- SLOを90%と定義していた場合に、SLIが95%であれば、SLOを達成していることになる
    - **SLI** 
    - **期間**：SLIを計測する期間となり、 先月一ヶ月間とか過去の特定の期間 (30日間、 1週間) となります
    - **目標**：特定の期間に期待する 「良好なイベント」 のイベント全体に占める割合などになります

- GoogleからSLOを定義する際に留意すべきルールが紹介されている
    - 現在のパフォーマンスに基づいてターゲットを選択してはならない
    - シンプルさを保つ
    - 「絶対」を避ける
    - SLOは最小限に設定する
    - 最初から完璧を目指すな

## SLA(Service Level Agreement)：サービスレベル契約
**SLOが達成できなかった場合に、ユーザーに対して何らかの補償などを約束する法的な契約**

- SLAの可用性ついて
    - 巧妙に設計されたソフトウェアは99.9%（スリーナイン）
    - 巧妙に設計された運用は99.99%（フォーナイン）
    - 巧妙に設計されたビジネスは99.999%（ファイブナイン）

## おわり
参考にさせていただいたUdemyの講座はSRE学習の初めに最適だと感じました。
[SRE サイトリライアビリティエンジニアリング――Googleの信頼性を支えるエンジニアリングチーム](https://www.oreilly.co.jp/books/9784873117911/) は積読ぎみなので、少しづつ読んでいこう。。

## 参考
- [SRE（サイト・リライアビリティ・エンジニアリング）が”ざっくり”「スッキリ」分かる講座](https://www.udemy.com/course/sre-training/)
iPhoneで日本語OCR、文字認識が使える

# 文字認識をかんたんにつかえる
iPhoneで文字認識できたら、板書の書き起こしや、標識認識アプリなど便利につかえます。

![Jun-19-2022 12-07-44.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/5de37e08-2ecf-a599-74b1-bc6ea98647fa.gif)

# ２０２２年のアップデートで日本語が利用可能に
２０２２年のiOS16から、日本語の文字認識が可能になりました。
組み込みのフレームワークのみで可能です。
精度もかなり良く、さまざまなアプリで実用に耐えるレベルだと個人的には思います。

# つかいかた

VisionのVNRecognizeTextRequestをつかいます。
**recognitionLanguages に "ja" を指定します。**
macOS13、Xcode14、iOS16以降が必要です。

```swift
let request = VNRecognizeTextRequest()
request.recognitionLanguages = ["ja"] // 日本語を指定
let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer)
do {
    try handler.perform([request])
} catch let error {
    print(error)
}
guard let observations = request.results as? [VNTextObservation] else { return }
for observation in observations {
    let box = observation.boundingBox // 位置のボックス
    let topCandidate = observation.topCandidates(1)
    if let recognizedText = topCandidate.first.string { // 検出したテキスト
        print(recognizedText)
    }
}
```

これだけ。
入力には、画像を与えるなり、カメラフレームを与えるなりすれば認識できる。

![Jun-19-2022 11-30-21.gif](https://user-images.githubusercontent.com/23278992/174463551-50a7314c-7480-4e62-9b4b-07f292d277b7.gif)
cloud monitoring でlogを監視する方法

# はじめに
業務でcloud monitoringを使うようになり、見よう見まねで進めていたらハマったので、
ここでまとめようかと思います。
こちらの記事で紹介するのは、cloud loggningからの指標をcloud monitoringで監視、アラートする内容になります。

# cloud monitoringとは
クラウドサービスのインフラストラクチャリソースやアプリケーションのパフォーマンスを監視する Google Cloud の監視ツールのサービスになります。

リソースを監視することで、トラブルシューティングやパフォーマンスを向上させるために設計されており、カスタム指標、分析情報、アラート通知、稼働時間チェック、カスタム ダッシュボードなど様々な方法でリソース監視の設定をすることができます。

私は上記で、アラート通知の設定をしました。


## アラート通知
今回はcloud loggningからの指標を取ってくるので、loggingでの指標作成を行います。

## 指標作成手順
1. GCP>logging>ログベースの指標>指標の作成
1. 指標タイプはCounterを選択
    1. Counterは対象ログをカウントする
    1. Distributionは対象ログの発生率を見る
1. 詳細の設定
    1. nameを指定する（required）
    1. 指標の説明を入れる（任意）
    1. 単位はメトリック値が報告される単位を設定（任意）
        1. [参考](https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.metricDescriptors?hl=ja#:~:text=%E3%81%BE%E3%81%99metricKind%E3%80%82valueType-,unit,-string)
1. 対象のログを抽出する際のフィルタを指定
    1. [参考](https://cloud.google.com/logging/docs/view/query-library-preview?hl=ja)
1. 指標を作成

## アラートポリシー作成手順
1. monitoring>アラート>create policy
1. new conditionで先ほど作成した指標を選択
    1. ローリングウィンドウは監視時間の間隔を指定する
    1. ローリングウィンドウ関数は検知されたログの計算方法を指定する
        1. 例：ローリングウィンドウ5分、関数sum >>> 5分間に検知されたログの件数の合計値
1. トリガーの設定を行う
    1. condition typeを指定する
        1. thresholdは閾値を設定が設定でき、それを超えると発火する
            1. 例：閾値５で、5分間に検知されたログの件数の合計値が5件を超えた場合検知
        1. metric absenceはログの不在を検知でき、それを超えると発火する
            1. 例：不在5分で、5分間に検知されたログの件数の合計値が0件だった場合検知
1. 通知と名前は任意のものをつける
1. ポリシーの作成

※複数条件のアラートポリシーを作成したい場合は、add alert conditionボタンで指標を増やす
複数条件の例：条件Aのログが5件を超え、条件Bのログが0件だった場合は発火

上記でも実現できなそうな条件のアラートポリシーを作成したい場合、MQL
を試してみるのも良いかもしれません。
[参考](https://cloud.google.com/monitoring/mql?hl=ja)

## まとめ
今回はcloud loggingとcloud monitoringを使用したアラートポリシーの作成方法について、
紹介させていただきました。
GCPで使用中のリソースが増えるにつれて全体の管理が難しく、アラートポリシーの必要性が増してくるなと感じました。
バグの発生おきにログを追っている方などは、アラートを取り入れるのも悪くないかもしてません。

# 参考文献
- [cloud monitoringとは](https://www.topgate.co.jp/teck-blog01)
Tmux不要論

こちらの記事はMac OS用になります。

Tmuxをご存知ですか？
私は最近知りまして、
udemyの
https://www.udemy.com/share/105ozG3@6NHOz3oRcFUtEjRbrWRrtovKMEc8_qNzxIGVp6j03vgt_FiBoqbMk4RKCdvShyVDPA==/
こちらの講座にて導入を始めました。
簡単に言ってしまうと、ターミナル画面を分割できるツールになります。
まさにこんなツールが欲しかったと思い、感動しておりました。

ただ自分の中で一つ疑問に感じることがありまして、
"iTerm2に同等の機能は存在しないのだろうか"
と。
そこで、ググってみるとやっぱりありましたのでご紹介するとともに、
簡単に比較したいと思います。

## iTerm2とは？
こちらに関しては知ってる方も多いと思いますので、割愛します。
https://iterm2.com/

## Tmuxとは？
ターミナルを分割してくれるツールで、
https://qiita.com/shin-ch13/items/9d207a70ccc8467f7bab
こちらに詳しい記事がありますのでぜひ参考に。

## Tmuxを導入してみて
### いいなと感じたこと
- 生産性が上がる
今までは一画面でしか作業していませんでしたが、実際に個人開発で導入してみました。
3画面で分割していて、
![tmux-qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680780/c05e2357-5754-3cc3-aa5a-0b31ff101458.png)
上記のように分けて使用していました。
vimを触っているときに階層を知りたい、とかコンテナ内でコマンドを実行したいと感じることがたびたびあり、それが解決できたことはまさに革命でした。
### 微妙だと感じたこと
- 各種ショートカットが煩雑
例えば、最もよく使用するであろうペインの左右分割のショートカット
Ctrl b + %
こちらなのですが、Ctrlとbという比較的遠いキーを押した後にshiftを押して5という少し遠いキーを押すのは少々手間だと感じました。
上記で紹介させていただいたudemyの講座ではconfigを編集してコマンドを打ちやすいように変更していますが、仮にサーバで使用するとなるとまたconfigを編集し直して...ということになり、少しナンセンスだと感じました。
- 自分が使用しているバージョンで不具合が発生
これに関しては完全に自分の技術不足の可能性がありますが、ダウンロードしたバージョンでdeleteキーを押すとspaceキーになってしまう不具合がありました。
解決方法が見つからず、エラーが解決されたときまた最新バージョンで使用するのはアリかなと感じています。

## iTerm2の画面分割機能
### いいなと感じたこと
- tmuxと同等の機能が実現されている
tmuxのように一つのウインドウで複数のターミナルを起動することができるので、tmuxでいいなと感じたことをまるっと享受できます。
- コマンドが超簡単
コマンドがとても簡潔で、
Cmd d
これで横方向の分割ができてしまいます。

### 微妙だなと感じたこと
今のところはないです。

## tmuxとiTerm2の画面分割機能を比較して
- コマンドの手軽さ
ここが一番大きいかなと感じていて、
ある程度慣れていればコマンドを押すことは手間には感じなくなるかもしれませんが、
キーボードを入力する時間はできるだけ削減できた方が負担が少なくてすみますので、
iTerm2のコマンドの手軽さを考えるとこちらに関してはiTerm2に軍配が上がると考えています。
- セッション管理
tmuxの強みは完全にここであると感じています。
tmuxは、サーバを起動することで複数のターミナルを管理することができるようになり（セッション、完全には詳しくないので誤記がありましたらコメントください）、一度に画面分割できる数は限られているもののセッションを増やせば無制限に作業画面を増やせることになりますので、CLI上で無双したい系のエンジニアの方であればとてもそそる内容ではないかと感じています。

### どちらを選ぶのか
結論、僕はiTerm2の画面分割機能を選びます。
理由は2つで、
- コマンドの手軽さ
こちらは上記の通り。
- セッション管理は自分には不要、代替案がある
僕の場合は、コマンドを叩いてセッションを切り替えるよりも、Macのデスクトップを切り替えてそれぞれにiTerm2のウインドウを持っていれば十分ではないかと感じています。
また、どうしても3画面以上のターミナルが同じウインドウでほしいとなった場合は、iTerm2にタブ機能がありますので、そちらも簡単なコマンドでタブの作成、移動ができるためそちらで必要十分だと感じました。

以上のようになっております。
個人的な意見ですが、CLIの便利さを学習によって享受し、そちらを最大化するのにリソースを先すぎるよりも、GUIをつかってCLIで得られる利便性をさらにブーストするのが一番生産性が高いと感じています。(VSCodeにvimのキーバインドを導入する etc.)

長文失礼いたしました。
スマホを使わずにAWSの二段階認証を行う

### 履歴

- 2022/6/19 初版
- 2023/1/6 誤植修正

## 動機

- AWSにログインするにはID・パスワードに認証だけでなく、仮想MFAデバイスなどを用いた多要素認証を行う方がセキュリティ上良いとされています
- 仮想MFAデバイスにはスマホアプリのGoogle AuthenticatorやMS Authenticatorが用いられることが多いのですが、以下のような問題があります
    - AWSにログインするたびにスマホが必要になり、PC上のブラウザにOne Time Password（OTP）を手入力する必要がある。
    - スマホをなくしたり、壊れたりするとAWSにログインできなくなる


## やりたいこと

- スマホアプリのAuthenticatorは今まで通り使える
- 自分の所有するPCからはスマホなしでAWSにログインできるようにする


## 前提など

- AWSへのログインをテーマにしていますが、他のサービスにも使えます
- Linuxを前提します（他のプラットフォームで同じことができるかは未確認）


## MFAデバイスの設定

- AWSにログインして、画面右上のユーザー名をクリックして、「セキュリティ認証情報」の設定を開きます

![ksnip_20220619-104842.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147328/0e2ac210-fcd4-c9db-d2bf-7b6ab2b9442f.png)

- 多要素認証の欄から「MFAデバイスの管理」を開きます
    - すでにMFAデバイスを登録済みの場合は、一旦削除する必要があります。

![ksnip_20220619-105814.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147328/a5650c09-df07-437e-43a4-5166228a4d20.png)

- 下記の画面で以下のように操作します
    - 「QRコードの表示」をクリックして、スマホのAuthenticatorアプリにアカウントを追加します
    - 「シークレットキーの表示」をクリックして表示される文字列をコピーしておきます
    - スマホのAuthenticatorからMFAコードを2回取得して、MFAコード1と2に入力します
    - 「MFAの割り当て」を押下します

![ksnip_20220619-105820.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147328/862d7253-cf55-3dd5-abcc-31988eff45bf.png)

ここまででスマホのAuthenticatorアプリは通常通り使えるようになります

## 仮想MFAシェルスクリプトの仕様

スマホのAuthenticatorの代替となる、シェルスクリプトを作成します。
使い方は以下のようなものにします。IAMユーザー名はhogehogeとします

```
$ mymfa hogehoge
hogehoge
123456
```
ここで123456がMFAコードです。
これを手でコピーしても良いのですが、MFAコードをクリップボードにコピーするところまでシェルスクリプトで行うようにします。

## 仮想MFAシェルスクリプトの実装 mymfa

シークレットキーなどの情報は別ファイルに分けておきたいので、まずはロジックの部分を以下のように実装します。

ファイル名は仮にmymfaとします。


```bash
#!/bin/bash

. $HOME/.mymfa_keys

genotp() {
  oathtool --totp --digits=6 --time-step-size=30s --base32 ${secrets[$1]}
}

if [ $# -gt 0 ]; then
  key="$1"
else
  key="$defaultKey"
fi

otp="$(genotp $key)"

echo $key
echo $otp

if which xclip > /dev/null 2>&1 && [ $"$DISPLAY" != x ] ;then
    echo $otp | xclip
    echo $otp | xclip -sel c
fi
```

MFAコードの生成部分はoathtoolというツールを使っています。
生成したMFAコードをクリップボードにコピーするのにxclipを使っています。
それぞれパッケージのインストールが必要です。

```
$ sudo dnf install oathtool xclip
```

xclipがない場合や、Window Systemが立ち上がってない場合は、クリップボードへのコピーは行いません。

## 仮想MFAシェルスクリプトの設定ファイル

シークレットキーなどのデータは $HOME/.mymfa_keys としてシェルスクリプトから読み込まれます。
以下のような形式で記述します。

```txt
declare -A secrets=(
  ["hogehoge"]="ABCDEFG"
  ["awsroot"]="ZYXWVUTS"
)
defaultKey=hogehoge
```

- secretsはシークレットキーをkey-value形式で記述します。keyはアカウント名などの任意の文字列、valueはAWSの画面でコピーしたシークレットキーです。
    - 普段使うアカウント以外にも、AWSのrootユーザーのキーや、他のサービスのキーも追加できます
- defaultKeyはシェルスクリプトに引数を渡さなかったときに使われるデフォルトのユーザー名です。

## 使う

```
$ mymfa
```
とするだけで、デフォルトのアカウントのMFAコードがクリップボード（およびセレクション）にコピーされます。
各デスクトップ環境のランチャーから起動するのも便利でしょう。
cscの作法 その201

# 概要
cscの作法、調べてみた。
qiitapi叩いてみた。
練習問題やってみた。

# 練習問題
qiita投稿フォームを作れ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e096e703-7068-1521-9cd0-73b9cc7d9861.png)

# サンプルコード

```
using System.Collections;
using System.IO;
using System;
using System.Text;
using System.Net;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

class form1: Form {
	TextBox bo1;
	TextBox bo2;
	TextBox bo3;
	public form1() {
		this.Text = "qiita";
		this.ClientSize = new Size(400, 520);
		bo2 = new TextBox();
		bo2.Location = new Point(50, 30);
		bo2.Width = 100;
		bo2.Height = 30;
		bo2.Text = "tag";
		Controls.AddRange(new Control[] {
			bo2
		});
		bo3 = new TextBox();
		bo3.Location = new Point(50, 80);
		bo3.Width = 300;
		bo3.Height = 30;
		bo3.Text = "title";
		Controls.AddRange(new Control[] {
			bo3
		});
		bo1 = new TextBox();
		bo1.Location = new Point(50, 130);
		bo1.Width = 300;
		bo1.Height = 300;
		bo1.Multiline = true;
		bo1.Text += "# 概要";
		Controls.AddRange(new Control[] {
			bo1
		});
		Button btn1 = new Button();
		btn1.Location = new Point(250, 460);
		btn1.Text = "投稿";
		btn1.Click += btn1_Click;
		Controls.AddRange(new Control[] {
			btn1
		});
	}
	void btn1_Click(object sender, System.EventArgs e) {
		string tag = bo2.Text;
		string title = bo3.Text;
		string body = bo1.Text;
		body = body.Replace(System.Environment.NewLine, "<br>");
		string json = "{\"body\": \"" + body + "\", \"private\": true, \"title\": \"" + title + "\", \"tags\": [{\"name\": \"" + tag + "\", \"versions\": []}]}";
		ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
		WebClient wc = new WebClient();
		string TOKEN = "";
		wc.Encoding = System.Text.Encoding.UTF8;
		wc.Headers.Add("Authorization", "Bearer " + TOKEN);
		wc.Headers[HttpRequestHeader.ContentType] = "application/json";
		string response = wc.UploadString("https://qiita.com/api/v2/items", "POST", json);
		Console.WriteLine(response);
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```


以上。
【解決策】npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.

数日前に突然```npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.```なるエラーが出るようになりました。

npmのグローバルインストールで```--location=global```推奨のメッセージが出てしまうそうです。

npm8.12.1ではすでに修正されているので、```npm -g update```でアップデートすれば直るとのこと。
エラー時点では、8.11.0を使用していました。

アップデートで直らない場合は、以下のファイルを手動で修正します。

## 手動による解決策

解決策としては、program Files > nodejsフォルダ内
npm、npm.cmd、npx、npx.cmdの4つのファイルを以下のように変更すればOK。

```diff_batchfile:npm 23行目
- NPM_PREFIX=`"$NODE_EXE" "$NPM_CLI_JS" prefix -g`
+ NPM_PREFIX=`"$NODE_EXE" "$NPM_CLI_JS" prefix --location=global`
```

```diff_batchfile:npm.cmd 12行目
- FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" prefix -g') DO (
+ FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" --location=global') DO (
```

```diff_batchfile:npx 32行目
- NPM_PREFIX=`"$NODE_EXE" "$NPM_CLI_JS" prefix -g`
+ NPM_PREFIX=`"$NODE_EXE" "$NPM_CLI_JS" prefix --location=global`
```

```diff_batchfile:npx.cmd 13行目
- FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" prefix -g') DO (
+ FOR /F "delims=" %%F IN ('CALL "%NODE_EXE%" "%NPM_CLI_JS%" --location=global') DO (
```

参考にさせていただいた元記事です。

https://stackoverflow.com/questions/72401421/npm-warn-config-global-global-local-are-deprecated-use-location-glo
localstackでAWS SAM開発環境

# 目的

ローカル開発に飽きてきたのでAWSを始めようと思ったが、１週間前にやった作業をほとんど忘れてしまっていたので、備忘録がわりに雑に投稿。

# 前提
基本的なツールはインストール済みとする。
* Docker
* awscli, aws-sam-cli
などなど・・・

# チュートリアル

公式のチュートリアルでHelloWorldの動作を確認しておく

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-getting-started-hello-world.html

ローカルでの動作確認は`sam local invoke`で良さそう

# localstack設定

localstack用のプロファイルを設定しておく、IDやtokenはdummyでOK

```
$ aws configure --profile localstack
AWS Access Key ID [None]: dummy
AWS Secret Access Key [None]: dummy
Default region name [None]: us-east-1
Default output format [None]: json
```

こちらも公式（？）からクローンしてきて`docker-compose up`でローカル環境にlocalstackを立ち上げる

https://github.com/localstack/localstack

なんかエラーがでたので、docker-compose.ymlの下記の一行だけコメントアウトした。
`
#- "${TMPDIR:-/tmp}/localstack:/tmp/localstack"
`

# localstack上にS3のbucket作成

bucket名を`sample-bucket`とする場合、以下のコマンドでbucketを作成できる
```
aws s3 mb s3://sample-bucket --endpoint-url=http://localhost:4566
```

作成したbucketの確認
```
aws s3 ls --endpoint-url=http://localhost:4566
```

bucket内ファイル一覧取得
```
aws s3 ls s3://sample-bucket --endpoint-url=http://localhost:4566
```

bucketにファイルアップロード
```
aws s3 cp [file_path] s3://sample-bucket/ --acl public-read --endpoint-url=http://localhost:4566
```

bucket内ファイルの中身を確認するにはブラウザでアクセスすればよし。
例えばsample-bucket内にtest.pngを置いているなら、
```
http://localhost:4566/sample-bucket/test.png
```

# sam local invokeで動作確認

先のチュートリアルで取得しているHelloWorldのapp.pyを以下のように編集。
やっていることはlocalstackにアクセスしてbucket名を取得して返しているだけ。

```python:app.py
import json
import boto3
import os

s3 = boto3.client('s3', endpoint_url='http://host.docker.internal:4566')

def lambda_handler(event, context):

    bucket = 'sample-bucket'
    response = s3.list_objects(Bucket=bucket)


    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": response["Name"],
        }),
    }
```

`sam local invoke`で作成したbucket名が出力されれば成功


```
{"statusCode": 200, "body": "{\"message\": \"sample-bucket\"}"}%   
```

テストする時には`sam build`でビルドし直さないといけないみたい。
煩わしいが、AWS上で開発するよりも回転早いよね、、、

# localstack起動時にbucket作成

こちらの記事を参照。

https://tech.fusic.co.jp/posts/2022-06-13-aws-localstack-minio-docker-compose/

デフォルトでは`/docker-entrypoint-initaws.d`に実行したいスクリプトファイルを置く。環境変数`INIT_SCRIPTS_PATH`を設定しておけば、設定したフォルダ内の.shファイルを実行することも可能。
今回はdocker-compose.ymlのenvironmentおよびvolumesに以下を記載。
これでdocker-compose.ymlと同じ階層にあるentrypointフォルダ内の.shを自動実行できる。

```
    environment:
      ~中略~
      - INIT_SCRIPTS_PATH=/entrypoint
    volumes:
      ~中略~
      - './entrypoint:/entrypoint'
```
Dockerの知識自己整理（まとめ）

# 概要
Docker関連を数年触らなかったので、自己整理を兼ねて記事を書き始めたところ、Docker関連の記事が増えてきてしまったので、ここでまとめてリンクを貼っておこうというものです。

# Dockerのインストール関連
●Windows10にDocker DesktopをインストールしてDockerを使い始めるまでの手順を書いたもの

https://qiita.com/TAKANEKOMACHI/items/f1aaa378d93b4ace9513


# DockerのImage/Containerの操作
●DockerのImageを取得して操作するまでを書いたもの

https://qiita.com/TAKANEKOMACHI/items/15eca19efebeefa87660

●ImageからContainerを生成して使う手順などを書いたもの

https://qiita.com/TAKANEKOMACHI/items/2b1575ecb1d8dba51657

●Apache HttpdとMariaDBのContainerを生成して使う手順を書いたもの

https://qiita.com/TAKANEKOMACHI/items/da860415d9f79789a3b4

# Dockerfile関連
●Apache HttpdのImageからContainerを作成する際に、COPYなどをしてみる。
「-v」（ボリュームのマウント）もここで説明。

https://qiita.com/TAKANEKOMACHI/items/da8eef17f46ea4cf1093

# Docker-Compose関連

（書く予定）

# その他

今のところ、ないけど「Docker Desktop」以外でDockerを使う方法（Vagrant/VirtualBox関連）とか、なんか思いついたら記事を書いて増やす予定
CircleCiとCodeシリーズの料金比較

## 概要
現在はAWSのcodeシリーズを使っているが料金をもっと最小化したくCIrcleciの料金体系を調査し比較した記事です

## codeシリーズ(aws)
### CodePipline
- アクティブなパイプライン1つにつき1.00USD/月
- (作成後１ヶ月は無料)

### CodeBuild
- コンピューティング→general1.medium(メモリ7 GB: CPU:4)
- ビルド1分辺り0.01USD


## CircleCi

### Freeプラン
- 毎月30,000クレジット付与
- ジョブの同時実行30(macOSは1)
- 10クレジット = 0.006USD
- コンピューティング→ Large(メモリ8 GB: CPU:4、1分２０クレジット)
- ユーザー数は無制限で無料
- **ホストOSのスペックが制限される**


### Performanceプラン
- 毎月55,000クレジット付与
- ジョブの同時実行80(macOSは5)
- アクティブユーザ枠5人分がついてくる(+1人につき15ドル)
- ジョブの実行のIPアドレス範囲設定
- freeプランでは使えないコンピューティングリソースが使える
- 営業時間中の SLA


## 料金例

- ビルド作業をする人は基本的に３名
- 月に2000分ビルド行う

### AWS
```
general1.medium(メモリ7 GB: CPU:4)の場合ビルド1分辺り0.01USD
・ 人員値段→0円(code系にユーザーの値段というのは存在しない)
・ ビルド値段→200ドル
合計 : 30ドル
```

### CircleCi(Freeプラン)
```
Large(メモリ8 GB: CPU:4)の場合ビルド1分辺り20クレジット
無料クレジット30000クレジット

20クレジット * 2000(分) = 40000クレジット

・ 人員値段→0円(Freeプランはユーザー料金無料)
・ ビルド値段→※0.6ドル

合計 : 0.6ドル
※無料クレジットが30000クレジットあるので課金されるのは10000クレジットのみ
10クレジット = 0.006ドルだから
10000クレジット = 0.6ドル

```

### CircleCi(Performanceプラン)
```
Large(メモリ8 GB: CPU:4)の場合ビルド1分辺り20クレジット
無料クレジット55000クレジット
人員は用意されている5人のみで追加はされていない

20クレジット * 2000(分) = 40000クレジット

・ 人員値段→0円()
・ ビルド値段→※0ドル
・ プラン値段→15ドル

合計 : 15ドル
※無料クレジットが55000クレジットあるので課金されない
```

## まとめ

**CodeBuildとCirecleCiを比べて**

- CIrcleCi無料枠が増えたので料金面だけを見るとCircleCiがダントツして安い
- CircleCIの同時実行使用の速さがすごいみたい(ためしてない)

CirecleCiのプランを比べて
- そこまで規模が大きくない場合はFreeプランで十分
- Freeプランはマシンスペックの制限があるのでその場合Performanceプランを検討する必要も出てくる
クラウドコンピューティングのサービスモデル比較（自分用メモ

【クラウドコンピューティングのサービスモデル】
AWSなどのクラウドコンピューティング（クラウド）とは「インターネット越しに、必要なリソースにアクセスして使用する」環境のこと。
代表的なサービスモデルに、IaaS、PaaS、SaaSがある。

・IaaS (Infrastructure as a Service)
ネットワークやストレージを含むサーバー機能を提供するサービス。ユーザーはサーバーのスペックを選択し、OSやミドルウェアの導入を行う。
　ユーザー管理：アプリケーション、アプリケーション実行環境、ミドルウェア、OS
　クラウドサービス管理：サーバー

・PaaS (Platform as a Service)
OSやミドルウェア、ランタイムなどのアプリケーション実行環境を含むプラットフォームを提供するサービスです。ユーザーはインフラを意識せずに、アプリケーションの開発・導入ができる。
　ユーザー管理：アプリケーション
　クラウドサービス管理：アプリケーション実行環境、ミドルウェア、OS、サーバー

・SaaS (Software as a Service)
アプリケーションを含むすべての機能を提供するサービス。ユーザーは機能のオプションを設定するだけでアプリケーションを利用できる。
　ユーザー管理：なし
　クラウドサービス管理：アプリケーション、アプリケーション実行環境、ミドルウェア、OS、サーバー


クラウドサービスを利用することによって以下のメリットが得られます。
・固定費の削減ー必要なリソースを必要なだけ購入すればよい（従量課金制）ため
・コスト面のメリットー多数の顧客に対応可能な機器を調達するため
・需要変化に対応ークラウドサービスは数分程度でリソースを用意できるため
・対応速度の向上ー開発や検証に必要な実環境と同様の環境をすぐに用意することができる
・運用、保守に関する費用の削減ー設備を購入、管理する必要がないため
・グローバル化ークラウドサービスはインターネット経由で利用できるため、世界展開も容易


また、自社設備を自社運用する環境のこと「オンプレミス」という。
自社運用では、機器故障の対応・稼働中に対応可能な人員の確保が必要になり、ピーク需要の変化に柔軟に対応できない。
laravel Unitテスト 作成したテストクラスでsetUp関数をオーバーライドしたらエラーが出た

# 概要

- laravelのUnitテストにて作成した独自のクラスにsetUp関数を使って継承元の関数をオーバーライドしようとしたときにエラーが出たのでまとめる。

# エラーまでの経緯

- 下記のように独自のテストクラスにsetUp（）関数を記載した。（継承元のsetUp（）も実行しないと行けない。）

    ```FooTest.php
    public function setUp()
    {
        parent::setUp();

        // その他のテスト実行時の初期処理
    }
    ```

# エラー

```
当該テストクラス名::setUp() must be compatible with テスト継承元クラス名::setUp(): void in 当該テストクラス名
```

# 解決までの経緯

- エラーを見るとどうやら当該テストクラスで定義しているsetUp()関数は返却値をタイプヒンティングで指定して上げる必要があるようだ。（継承元の関数をオーバーライドしたいなら戻り値の宣言も含めて同じ記載をしないと行けないっぽい）
- 下記の様に記載したらエラーは解消した。

    ```FooTest.php
    public function setUp(): void
    {
        parent::setUp();

        // その他のテスト実行時の初期処理
    }
    ```