OmniAICreator/Qiita-1.07M huggingface dataset:
【Solidity】新しいInterface記述法を学ぼう

## 前書き
[CryptoZombies](https://cryptozombies.io/jp/)で学んだinterfaceの使用法と今の使用法が異なるようなので自分で調べてみたいと思います。[Solidity by Example](https://solidity-by-example.org/interface/)を主に参考にします。
※筆者はプログラミング初心者です。誤った情報があるかもしれませんがご了承ください。
## Interfaceとは
Interfaceを宣言すると、自分のコントラクトと外部のコントラクトを相互作用することができます。公開されたコントラクトの関数を自分のコントラクトで使用することができます。
## Interfaceの特性とルール
1\.機能を持つ関数を実装することはできない
2\.他のインターフェースを継承することができる
3\.中で宣言する関数はexternalでなければならない
4\.コンストラクタを宣言することはできない
5\.状態変数を宣言することはできない
## Interfaceを書いてみよう
#### 呼び出したい外部のコントラクト
```solidity:NumberIncrement.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;

contract NumberIncrement {
    uint256 public number;
    function increment() public {
        number += 1;
    }
}
```
publicの状態変数は自動的にゲッタ関数が生成され、この場合生成されたnumber()関数を呼び出すことでnumberの値を参照できます。remixIDEでは、デプロイするとnumber()というボタンが現れ、実行できます。
#### 自分のコントラクトとInterface
```solidity:MyContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;

interface NumberIncrement {
    function number() external view returns(uint256);
    function increment() external;
}

contract MyContract {
    NumberIncrement private numberIncrement;

    constructor(address interfaceContractAddress) {
        numberIncrement = NumberIncrement(interfaceContractAddress);
    }

    function useInterfaceFunction() public returns(uint) {
        numberIncrement.increment();
        return numberIncrement.number();
    }
    
}
```
インターフェースの名前はなんでも良さそうですが、Hardhatのテストの際、コントラクト名とInterface名が同じだとエラーが出たので違う方が良さそうです（RemixIDEでは同じでもデプロイできました）。また元の関数にvirtual,overrideが付いている場合、Interfaceではどちらも不要のようです(検証していないので間違っていたらすみません)。

ハードコードでアドレスを指定するよりはコンストラクタ内で動的に指定してあげた方が、interfaceするコントラクトのアドレスが変わった際、自分のコントラクトを編集する必要がないので楽かもしれません。

ちなみに[Solidity by Example](https://solidity-by-example.org/interface/)では、自分のコントラクト内の関数の引数にinterfaceするコントラクトのアドレスを持たせています。こちらでは、interfaceするコントラクトアドレスが変わっても再デプロイする必要がなく、かつ安全だと思います。

Solidity by Example風に書くとこうなります
```solidity:MyContract.sol(Solidity by Example風)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;

interface NumberIncrement {
    function number() external view returns(uint256);
    function increment() external;
}

contract MyContract {
    NumberIncrement private numberIncrement;

    function useInterfaceFunction(address numberIncrementAddress) public returns(uint) {
        NumberIncrement(numberIncrementAddress).increment();
        return NumberIncrement(numberIncrementAddress).number();
    }
    
}
```
関数を呼び出す時は面倒かもしれませんがこっちの方がスマートで安全でいいと思います。

## 関数の実行
先にNumberIncrementコントラクトをデプロイします。そしてそのコントラクトアドレスを指定しMyContractコントラクトをデプロイします。
useInterfaceFunction()を実行するとremixIDEのコンソールに出力されるログの
decoded outputの箇所にインクリメントされた数字が出力されます。

## 考察
BコントラクトでAコントラクトをinterfaceし、Aコントラクトの状態変数を変更する関数を実行すると、その変更はAコントラクトそのものに影響し、保存されるっぽいです。

### 参考文献
https://solidity-by-example.org/interface/

https://qiita.com/negi123/items/5f4b67ee68493f2a622b

https://www.udemy.com/course/dappnft2/
apatch derby with maven

netbeansでjava derbyに接続する際にNo Suitable Driverのエラーがでる。
derbyclient.jarにclasspathを通す必要がある。
maven projectの場合、pom.xmlに以下を記載することでderbyclient.jarがdownload
され、classpathも通る
指定するgroupId, artifactId, versionはhttps://search.maven.org/
で検索

artifactIdをderbyにすると、derbyshared.jarのみdownloadされてerrorが
解消しなかったので、derbyclientに変更したところ、derbyclient.jarも
downloadされ、error解消。

```pom.xml
    <dependencies>
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derbyclient</artifactId>
            <version>10.15.2.0</version>
        </dependency>
    </dependencies>
```
derbyclient.jarがdownloadされている様子
```
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/derby/derbyclient/10.15.2.0/derbyclient-10.15.2.0.pom
Progress (1): 2.5 kB
                    
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/derby/derbyclient/10.15.2.0/derbyclient-10.15.2.0.pom (2.5 kB at 1.8 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/derby/derbyclient/10.15.2.0/derbyclient-10.15.2.0.jar
Progress (1): 4.1/601 kB
Progress (1): 8.2/601 kB
```
AWS ECS の production 環境に rails db:migrate する手軽な方法

RDSにはlocalから直接接続できるようにしておく
database.yaml などで必要な接続設定をしたらlocalからでも直接migrateを実行してしまえば良い

あくまで手軽な方法なので本番運用ではちゃんとやること
(ちゃんとの中身はまだ分からないのだが)

# コマンド例

```
RAILS_ENV=production rails db:create
RAILS_ENV=production rails db:migrate
```

# database.yaml の例

```yaml
default: &default
  adapter: mysql2
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

production:
  <<: *default
  host: *****.ap-northeast-1.rds.amazonaws.com
  username: username
  database: databasename
  password: password


```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
[laravel]webapiでコントローラからjson形式でデータを渡す

## はじめに
バックエンドとフロントをわけて開発する際、JSON形式でデータを渡してあげる必要がある。
これまでlaravelのみで開発をしてきたが、そのときはviewにhttp形式で渡してあげていたので、JSON形式となると少しやり方が変わってくる。

## 環境
laravel9
PHP8

## Controllerでの基本的な渡し方
```TestController.php
$tests = Test::get();

return response()->json($tests);
```
- テーブルからすべてのデータを取ってくる場合、`get`を使ってあげる。
- 受け渡す際はビューへではなく、json形式で引数に取ってきたデータを入れてあげる。基本的にはこの形。

### 渡すデータを絞りたい場合
カラム指定があったりする場合は基本的に下記のような書き方になる。
```TestController.php
$tests = Test::select('id', 'name');

return response()->json($tests);
```
- このように書いてあげることで指定したカラムのみを絞ってJSONで渡すことができる。

### このようにも書ける
```TestController.php
$tests = Test::get();

$result = [];
foreach ($tests as $item) {
    $data = [];
    $data['id'] = $item->id;
    $data['name'] = $item->name;
    $result[] = $data;
}

return response()->json($result);
```
- これでも必要なカラムを送ることができる。
- 厳密に言うと渡されるデータが違うようなので、そのあたりはこれから学んでいく

以上
ネットワーク解析ツールのBatfishを導入する

# はじめに
ネットワーク機器のConfigを解析するBatfishというツールの使い方を説明するための記事です。
初学者向けに書いています。

# 何ができる?
Batfishというツールにより、下記ができるようになります。
・ACLの不備のチェック
・ネットワークの疎通の確認
・configの差分の確認
等など

# 構成概要
下記の構成を作っていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507183/e3f9fd51-22db-ce22-00e3-a0d6e02f1dd1.png)
BatfishはDocker[^1]のコンテナとして配布されており、
利用のためにはDockerコンテナを利用できるようにする必要があります。

[^1]:コンテナ型の仮想化ツールです。PC内にもう一つPCを生み出すイメージ。

# 導入方法
## 1.Dockerのインストール
https://www.docker.com/products/docker-desktop/
上記サイトからDocker Desktop Installer.exe をダウンロード＆実行します。

途中WSLのアップデート必要といった文言が出る場合は、
terminalを管理者として実行し、
```
wsl --update
```
と入力します。

## 2.Docker＆Batfishのセットアップ
PCでTerminalを開き、
```docker pull batfish/allinone```
と入力します。
下記のような表示が出ればbatfishのインストール成功です。
```
Using default tag: latest
latest: Pulling from batfish/allinone
e0b25ef51634: Already exists
0c8c05912979: Already exists
c0bbc0bc4d79: Already exists
a43bdd4c5cf3: Already exists
999be192ad05: Already exists
81a0f4452512: Pull complete
4f4fb700ef54: Pull complete
13b3efa3c511: Pull complete
bfc1fb9d2880: Pull complete
Digest: sha256:d8bfccb303ca2cbf5d576fd7be54562b3272155850f8b37552f73929de5760fd
Status: Downloaded newer image for batfish/allinone:latest
docker.io/batfish/allinone:latest
```

~~その後
```python3 -m pip install --upgrade pybatfish```
と入力します。~~
（必要なさそうなので削除）

Docker Desktopのimagesを開くと、
batfish/allinoneのコンテナイメージが追加されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507183/67c0e061-023c-e832-7d0d-361ab64f3008.png)


右側のRUN ⇒ Optional settingsを押し、
3つportsのところに上から8888、9996、9997と入力しRUNを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507183/352880f9-e95a-f8cd-08c8-b7fa889797f7.png)


## 3.Batfishへのアクセス
Dockerを開き先ほど起動したコンテナイメージの名前をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507183/db73dbe9-37d7-5f11-11d7-8eccfaf34a11.png)

コンテナのログが表示されています。
中に下記のようなurlが表示されているので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507183/e65bb831-0eaf-c155-c2e7-e5598e4b7a62.png)


最後のhttp://127.0.0.1から始まるリンクをクリックします。

下記のような画面が出てくれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/507183/25dd7543-f1b8-dfc8-82e9-d90a1d8ff28e.png)


## 4.Batfishの活用
次の記事で解説します。

# 次の記事
https://qiita.com/Trick_Trick/items/a4d3c69eaa266086aa86

## 参考
https://batfish.readthedocs.io/en/latest/index.html
CodeCommitのリポジトリ作成

# 事前準備

1. HTTPS Git 認証情報の生成
    - [AWS CodeCommit の HTTPS Git 認証情報を生成](https://qiita.com/ryome/items/066d2deea3e6fbe577ad)
2. Linuxコマンドが使用できる環境構築
    - [wsl2にUbuntu環境を構築する【windows】](https://qiita.com/ryome/items/240f36923f5cb989da27)
    - ※ MacOSの方はターミナルからLinuxコマンドが使用できます。

# CodeCommitリポジトリ作成

1.`CodeCommit` を検索する。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/e058b03d-5ed1-cefe-d061-e48b19ab3507.png)

2.`リポジトリを作成` を押下する。

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/65da003b-e1ef-fd8c-f8c4-1715ded679a4.png)

3.`リポジトリ名` を入力して、 `作成` を押下する。

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/ff9ea67c-e16c-1346-8f31-32a7e259ad16.png)

4.`URLのクローン` から `HTTPSのクローン` を押下する。

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/1ada5307-c551-b7f5-95af-bc2976ec07ee.png)

5.URLに `AWS CodeCommit の HTTPS Git 認証情報` を加えて `git clone` コマンドを実行する。
- コマンド
```
git clone https://【ユーザー名】:【パスワード】@git-codecommit.【リージョン名】.amazonaws.com/v1/repos/【リポジトリ名】
```
- 実行例
```
$ git clone https://【ユーザー名】:【パスワード】@git-codecommit.【リージョン名】.amazonaws.com/v1/repos/【リポジトリ名】
Cloning into '【リポジトリ名】'...
```

※ `ユーザ名` と `パスワード` は以下を参照
https://qiita.com/ryome/items/066d2deea3e6fbe577ad

6.`ls` コマンドで `【リポジトリ名】` フォルダが存在すれば成功。

- コマンド
```
ls
```
- 実行例
```
$ ls
【リポジトリ名】
```

# エラー対処

### エラー内容

`git clone` コマンド実行時にエラーになる。

```
$ git clone https://【ユーザー名】:【パスワード】@git-codecommit.【リージョン名】.amazonaws.com/v1/repos/【リポジトリ名】
Cloning into '【リポジトリ名】'...
fatal: unable to access 'https://【ユーザー名】:【パスワード】@git-codecommit.【リージョン名】.amazonaws.com/v1/repos/【リポジトリ名】/': URL using bad/illegal format or missing URL
```

### 対処法

以下の手順を行い、`git clone` コマンドを実行する。

1. AWS CLIのインストール
    - [【Windows/Mac/Linux（Ubuntu）】AWS CLIインストール方法](https://qiita.com/ryome/items/efd37c3a49b54859ba68)
2. AWS IAMアカウントの作成とaws configureの設定
    - [AWS IAMアカウントの作成とaws configureの設定](https://qiita.com/ryome/items/ff2804be600cd5dcd61a)

- コマンド
```
$ git clone https://git-codecommit.【リージョン名】.amazonaws.com/v1/repos/【リポジトリ名】
Cloning into '【リポジトリ名】'...
Username for 'https://git-codecommit.ap-northeast-1.amazonaws.com': 【ユーザー名】
Password for 'https://【ユーザー名】@git-codecommit.ap-northeast-1.amazonaws.com':【パスワード】
```
What's New from CircleCI - 2023/02/07

CircleCIに関する最近2週間(2023/01/31~02/07)くらいの情報をまとめてみました。
気のつく限りの情報は拾ってみたつもりですが、見落としなどありましたら、Twitterで [@CircleCIJapan](https://twitter.com/CircleCIJapan) をメンションしてタレ込んでいただけると幸いです。
少しでもお役に立てていましたら、いいね(❤️)クリックいただけると嬉しいです！

[＜ What's New from CircleCI - 2023/01/31](https://qiita.com/CircleCIJapan/items/43f2f09b66786e0f29c2) | 今週 | [What's New from CircleCI - 2023/02/14 ＞](https://qiita.com/CircleCIJapan/items/fc140f54692b3625e339)
    
# ユーザーブログ・スライド
- CircleCI活用ブログ
    - [【実践編】CircleCIからOIDCを用いて安全にGoogle Cloudにアクセスする](https://techblog.kayac.com/circleci-oidc-google-practice) by カヤックSRE 市川さん
    - [Google TestをCIで実行する](https://qiita.com/skkzsh/items/254a22e5452ba3f8d854) by @skkzsh さん

- CircleCI カスタマーサクセスチームブログ
    - [CircleCI を使って AWS ECR から ECS にデプロイしてみた](https://qiita.com/chisato-ygc/items/fe7cdafe72289028598e) by @chisato-ygc さん
    - [CircleCIとCypressを導入してReactアプリのコンポーネントテストを自動化してみた！](https://qiita.com/Nagisa-kjm/items/5e6b3a294501a71029be) by @Nagisa-kjm さん
    - [CircleCI 公式のデプロイ用 Docker イメージ cimg/deploy](https://qiita.com/suzucir/items/814cea09f08056feca69) by @suzucir さん

# CircleCI 公式ブログ
- [日本語ブログ](https://circleci.com/ja/blog/)
    - [CircleCI から mabl で作成したE2E テストセットを実行する](https://circleci.com/ja/blog/circleci-e2e-test-with-mabl/)
- [英語ブログ](https://circleci.com/blog/)
    - [An update on CircleCI's reliability](https://circleci.com/blog/an-update-on-circleci-reliability/)
    - [Integrate CircleCI with HashiCorp Vault using OIDC](https://circleci.com/blog/oidc-with-vault/)

# Changelog (更新履歴)
- クラウド版の更新履歴: https://circleci.com/ja/changelog/
    - 02/01 [Windowsのリソースクラスでテスト分割](https://circleci.com/ja/changelog/#windowsのリソースクラスでテスト分割)
    - 01/19 [フェイルファスト機能のオープンプレビュー](https://circleci.com/ja/changelog/#フェイルファスト機能のオープンプレビュー)
- サーバー版の更新履歴: https://circleci.com/ja/server/changelog/
- セルフホストランナーの更新履歴: https://circleci.com/ja/changelog/self-hosted-runner/
- プロダクト ロードマップ(今後の提供予定機能): https://circleci.com/ja/product-roadmap/

# YouTube (動画コンテンツ)
- [CircleCI チャンネル (日本語)](https://youtube.com/playlist?list=PL9GgS3TcDh8x71MTG2uvZ-ljhIkuveSHZ)
- [CircleCI Channel (English)](https://www.youtube.com/c/CircleCI-Videos)
    - [Platform Engineering 101 | Everything You Need to Know](https://youtu.be/E10MHY0AbJA)

# CircleCI Knowledge Base
- [CircleCI ナレッジベース (日本語)](https://support.circleci.com/hc/ja)
- [CircleCI Knowledge Base (English)](https://support.circleci.com/hc/en-us/)
    - [Permission error when trying to SSH into a job](https://support.circleci.com/hc/en-us/articles/12520369359515-Permission-error-when-trying-to-SSH-into-a-job)
    - [Kubernetes Troubleshooting](https://support.circleci.com/hc/en-us/articles/12615079346331-Kubernetes-Troubleshooting)
    - [Troubleshooting checkout step failing - Alpine image](https://support.circleci.com/hc/en-us/articles/12619460475291-Troubleshooting-checkout-step-failing-Alpine-image)

# CircleCI 関連のイベント、ウェビナー等
- 02/16(木) [自動テスト・自動デプロイ・自動デリバリーがもたらす効率的かつ強靭なソフトウェア開発体制](https://www2.circleci.com/2023-02-16-Efficient-software-development-brought-by-automated-testing-automated-deployment-and-automated-delivery.html)
---
それでは今週も Happy Building⌨!
【Django+Docker】パッケージを後からインストールする方法

DockerでDjangoの開発をある程度進めてから
追加でパッケージをインストールしたい場合の進め方について書きます。
Dockerがある場合ってどうやるの、、と難しく考えていたので
そんなに難しいはずないじゃん、、ってことで備忘録として記事にしました。


## Djangoのみの場合(仮想環境に入って)

```terminal
pip install djangorestframework
```


## Docker+Djangoの場合

```terminal
docker compose exec web bash
pip install djangorestframework
```



これで
```terminal
Successfully　installed djangorestframework
```

と出れば成功です。
ちなみに

```terminal
pip list
```

でインストール済みのパッケージ一覧が出ます。
以上です。

### 読んでいただきありがとうございました！
TDD

# systemテストやってて困ったことリスト
- fixtureのデータの一部をゼロにしたい
  - Model.destroy_allでもいいんだけどそれなら最初から作らない方が良い
  - かといって部分的に読み込むと何度も読み込むことになってだるい
  - 一部のテストで一部のモデルだけ作成しないっていう処理ができればベスト
  - 予約システムみたいな日付でインスタンスを引っ張ってくるようなテストを書くときによく遭遇する、「その日付にレコードがあるのかないのかわからない現象」
Unityで重なるUIをきれいにフェードする話

# 問題
重なるUIを一緒にフェードしたい場合、CanvasGroupでAlphaを弄っても、それぞれのUIが互いにフェードして、下にあるUIが透けて見える問題があります。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475482/23152f65-8213-a102-717c-4872d75a9c78.png)

# 解決
一番思いつきやすい解決案として、RenderTextureを用いることが考えられます。

しかしRenderTextureの描画はやや手順が複雑、かつ負荷が重いので今回はステンシルバッファを用いる手法を紹介します。

マスクに似たような考え方で、上にあるUIを常に描画するマスクとして、下にあるUIを上のマスク領域内で描画しないようにします。

そうすると下にあるUIが描画順上上にあるUIの後に描画されますが、上にあるUIと重なる部分だけステンシルテストが通らず、描画されなくなります。

それでCanvasGroupでAlphaを一緒に弄っても透けて見える問題がありません。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475482/b06981c6-10d4-073d-8d61-c2a1e49c79eb.png)

# 手順
デフォルトのUIシェーダーですでにステンシルを自由に設定できるので、それのマテリアルを2つ作ればOKです。

1. 新規のマテリアルAを作成する。
2. マテリアルAのシェーダーをUI/Defaultに変える。
3. マテリアルAのインスペクターから、Stencil Comparisonを5（Greater）、Stencil IDを1、Stencil Operationを2（Replace）にする。
    1. つまり参照値（1）が既存のステンシルバッファの値より大きいピクセルのみを描画し、そのステンシルバッファの値を1に書き換えること。
4. マテリアルAを上にあるUI画像のマテリアルに設定する。
5. 新規のマテリアルBを作成する。
6. マテリアルBのシェーダーをUI/Defaultに変える。
7. マテリアルBのインスペクターから、Stencil Comparisonを5（Greater）、Stencil IDを1、Stencil Operationを0（Keep）にする。
    1. つまり参照値（1）が既存のステンシルバッファの値より大きいピクセルのみを描画し、そのステンシルバッファの値をそのままにしておくこと。
8. マテリアルBを下にあるUI画像のマテリアルに設定する。
9. CanvasGroupコンポーネントを付けて上にあるUIと下にあるUIを同時にフェードする。

ステンシル設定の詳細はUnityの[ドキュメント](https://docs.unity3d.com/Manual/SL-Stencil.html)をご参考ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475482/3801b352-cd5e-bcee-e2d5-17623be2d427.png)![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475482/32ccd593-6baa-bc0a-06d5-c9613b2fd82f.png)


# UnityのMaskコンポーネントと一緒に使う時の問題
上記の方法はステンシルバッファを使って実現しているため、同じくステンシルバッファを利用しているUnityのMaskコンポーネントと衝突する場合があります。

それを回避するためにはMaskの代わりにRectMask2Dを使うのをお勧めします 。RectMask2Dはステンシルバッファを用いなく、軽量なので基本こちらのほうを使いましょう。

もしマスクの形が矩形ではないなど、どうしてもMaskコンポーネントを使いたい時は別途対応する必要があります。

まずUI/Defaultみたいなステンシル設定をマテリアルから直接いじられるシェーダーでは、UnityのMaskコンポーネントによって強制的に書き換えられてしまうので、[専用シェーダー](https://gist.github.com/RINNUXEI/951de5924bfbb9c3421c89d7877e09cb)（UI/Defaultの改造）でステンシルを制御します。

UnityのMaskコンポーネントではマスク領域のステンシルバッファの値を1にしているため、上にあるUIを1だったら描画し、かつそのステンシルバッファの値を1増やせば、下にあるUIでは上にあるUIの領域で描画されなくなります。

```
Stencil
{
    Ref 1
    Comp Equal
    Pass IncrSat
}
```
これでMask内でも無事きれいにフェードできるようになりました。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475482/748b464a-d773-3c94-ca70-404f2e113eac.png)
BigQuery ML (BQML) の料金計算方法 2023/02/07版

ちゃお…†
まいおり…†

## はじめに
BigQuery ML (BQML) って知ってる？BQMLは、BigQueryのデータをSQL文みたいな感じで機械学習モデルを作ったりできる便利なサービスです。ローカルのマシンではとてもメモリに乗り切らない130GBのデータでも短時間でよしなにやってくれます。しかもブーストツリーモデルでは前処理もやってくれる！

## 料金計算のドキュメントが古い…
ただ、これを書いてる現在 (2023/02/07) では、[BQMLの料金計算の説明](https://cloud.google.com/bigquery-ml/pricing?hl=ja#bqmlexamples)が古くてドキュメント通りにやろうとしても料金計算ができません……。

> 7.データが入力されたら、[表示設定] をクリックして [カスタム フィールドを変更] を選択します。

Cloud LoggingのUIが変わって`[表示設定]`っていう項目がないんですよね……。

## 2023/02/07時点での料金計算はこれ！
ここではBigQuery ML の CREATE MODEL ステートメントを含むクエリジョブの US での料金を算出する方法を[BigQuery ML の料金の例](https://cloud.google.com/bigquery-ml/pricing?hl=ja#bqmlexamples)をベースに紹介します。

1. Google Cloud Console で [Cloud Logging](https://console.cloud.google.com/logs/query?hl=ja) ページを開きます。

2. プロダクトが BigQuery に設定されていることを確認します。

3. 大きなテキストフィールドに以下を入力します。
```
resource.type="bigquery_resource"
protoPayload.serviceData.jobCompletedEvent.job.jobConfiguration.query.statementType="CREATE_MODEL"
```
4.大きなテキストフィールドの上にある時計アイコンをクリックしてプルダウン リストから、適切な期間を選択します。たとえば、[過去 24 時間] を選択すると、過去 24 時間に完了した BigQuery ML の CREATE MODEL ジョブが表示されます。

5.[クエリを実行] をクリックして、指定した時間枠内で完了したジョブを表示します。

6.「クエリ結果」のすぐ下に、カラム名が「重大度/タイムスタンプ/概要」のバーがあり、そこの「概要」の隣にある「編集」ボタンを押すと、「概要フィールドの管理」画面のポップアップが表示されるので、そこで以下のカスタム概要フィールドを追加します。

```
protoPayload.serviceData.jobCompletedEvent.job.jobStatistics.totalBilledBytes
```

7.ページが更新されたら、BigQuery ML ジョブごとに課金されるバイト数が、各ジョブのタイムスタンプの右側に表示されます。課金されるバイト数が無料枠に含まれる場合、値は表示されません。次に例を示します。

![](https://cloud.google.com/static/bigquery/images/bqml-billing.png?hl=ja)

### BigQuery ML の課金されるバイト数

BigQuery ML CREATE MODEL ジョブの料金を計算するには、課金されるバイト数に BigQuery ML のオンデマンド料金を掛けます。この例では、CREATE MODEL ジョブは 100,873,011,200 バイトを処理しています。このジョブの料金を US マルチリージョン ロケーションで計算するには、課金されるバイト数を TB のバイト数で割り、その数にモデル作成の料金を掛けます。
```
100873011200/1099511627776 x $250.00 = $22.94
```

## さいごに
Google Cloudさん、早くドキュメント更新してくれ〜
AWS データレイク・データウェアハウス基盤：単体テスト、結合テスト、システムテストでやるべきこと

# はじめに
AWSのデータレイク・データウェアハウス基盤における下記構成を例に、このようなフローにおいてどのようにテストを実施すればよいかについて説明します。本実装では、オンプレミスからS3、Redshiftへのデータの転送を、日次で定期的に行います。
![スクリーンショット 2023-01-05 11.10.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263017/bcd2cea8-8124-8100-3e4d-fa9274aa5dae.png)

# 「開発環境」「本番環境」の実施について
「単体テスト」「結合テスト」「システムテスト」全てにおいて、「開発環境」「本番環境」で実施するのがベストであるが、「開発環境」は、開発用の生データを用意できなかったり、「開発環境」分の工数が発生してしまうため、この場合「本番環境」だけでも最低限実施して欲しい。

# 単体テスト
* 各AWSサービスのパラメータ値が正しいことを確認
* 基本的には、IaC（Infrastructure as Code）を使用して構築することをおすすめします

# 結合テスト
* Glueからオンプレミスに接続できること
* ETL処理確認
    * データの整合性の確認（件数及びデータの整合性チェック）
        * データソース元、データ転送先の整合性が一致していることをExcelやSQLを用いて確認
    * データの加工結果の確認（マスキングや日付変換など）
    * 処理結果の確認
        * 正常終了、異常終了：Glueジョブの正常終了、異常終了のパターンを確認
        * 更新対象0件：データソース元のデータが0件の場合の挙動を確認
* ローカル環境からAthena,RedshiftへSQLを実行できること
* ワークフロー(StepFunction)を実行して、オンプレミスからRedshiftまで正常通りにETL処理ができること

# システムテスト
* 機能テスト
    * 数日間期間を設けて、ワークフローの定期実行が正常通りであること
* 性能/負荷テスト
    * バッチ処理時間内に処理が完了すること
* 障害/運用テスト
    * ETL処理成功時に、Slackなどのツールへ通知されること
    * ETL処理失敗時に、Slackなどのツールへ通知されること
    * ETL処理失敗後に、復旧作業が問題なくできること
* セキュリティテスト
    * Athena,Redshiftへの権限のないテーブルに対して、アクセスできないこと
    * Athena,Redshiftのアクセスログが取得できること
    * インシデントや不正操作が発生した場合、Slackなどのツールへ通知されること

# ※ 生データの取り扱い
生データは個人・機密情報が含まれているなど、特にテスト段階では慎重に実施するべきです。
**外部に漏洩しないようプライベート環境内でテストを実施** **/**  **個人・機密情報のカラムをマスキング /** **個人・機密情報のカラムへアクセスできないよう権限を設定** するなどして、工夫して取り組むことで、高品質な環境を構築することができます！

# さいごに
テストの実施方法は、大企業やスタートアップ企業、もしくは現場ごとにやり方は異なります。
本記事は、どの現場にも共通して利用できるものを記述したため、是非参考にしていただけたら嬉しいです！
大学入試問題文?集（第5巻）「考察」を考察してみた。2023年

(1)が考察だったのね問題。
「考察」は、2000年以降トレンドですか?

オリジナル
2023 大学入学共通テスト本試験 数学

# 2023年
### ...考える。
［１］
　　　(1)kを正の定数とし，次の3次関数を**考える。** ...
　　　(2)...である．**(1)の考察** より，
2023　大学入学共通テスト　本試験　数学II・IIB　第2問［1］(2)
https://www.yomiuri.co.jp/nyushi/kyotsu/mondai/__icsFiles/afieldfile/2023/01/15/sugaku_2_mon.pdf#page=8

・(1)が考察だったのね問題。
考える→考察

・「(1)より，」でもつうじると思います。

・［１］と(1)の間に、説明がありませんでした。
［１］
　　　(1)

### ...である。 
2023(同年)　大学入学共通テスト　本試験　数学II・IIB　第2問［2］(2)(ⅱ)
https://www.yomiuri.co.jp/nyushi/kyotsu/mondai/__icsFiles/afieldfile/2023/01/15/sugaku_2_mon.pdf#page=11

「(1)より」でした。
・「考察」いりませんか？

# 過去問
例.2021　大学入学共通テスト　追試験　数学II・IIB
考察1...、考察2...、考察3..
**(3)　これまでの考察を振り返ると，**
https://mathexamtest.web.fc2.com/2021/202110000/2021100000400mj.html#top-0402
　
例.2022 不定方程式　　
　
例.考察　＜　M.E.T.A.様の内部検索

https://cse.google.com/cse?cx=a8908fbc24340ebc5&q=%E8%80%83%E5%AF%9F&oq=%E8%80%83%E5%AF%9F&gs_l=partner-web.12..0i7i30j0i7i30i625j0i512i433i433j0i512l2j0i7i30i625l3j0i7i30j0i7i30i625.2941.5127.0.8985.8.8.0.0.0.0.123.827.1j7.8.0.csems%2Cnrl%3D10...0....1j4.34.partner-web..1.7.704.Vn0Wqg1dfeY


# 私の考察
2023年、出題者に年齢差があるのかな。

# 参考
　
https://www.deepl.com/ja/translator#ja/en/考察
LaravelのテストでCookie::queueを活かす方法

# 前置き

久々に投稿。
LaravelのテストでCookieを扱う際に、やり方が公式でも書いてあるのですが、そもそものやり方が事前にCookieを仕込んでおいてそれを読み取るという方法で、トークンなど動的に変わる値には対応できていません。

要はその、`Cookie::queue`のテストが避けて通れない場合にどうするか、というのが今回のお題です。

ググっても全然ヒットしなかったので、今回頑張って検証してみました。

# 使用したバージョン

|  |  |
|-----------|------------|
| Laravel       | ^9.0        |
| PHP       | ^8.0        |

# 公式のやり方

[公式](https://readouble.com/laravel/8.x/ja/http-tests.html)

```
$response = $this->withCookie('color', 'blue')->get('/');
```

上記を、testCase内に書かないとCookieに書き込まれたことになりません。

# 対応方法

いきなり答えですが、

```
protected function saveCookies($cookies, $cookieNames)
{
    $saveNameAndValues = [];
    foreach ($cookies as $cookie) {
        if (in_array($cookie->getName(), $cookieNames, true)) {
            $decryptedString = decrypt($cookie->getValue(), false);
            $arrayCookieValues = explode('|', $decryptedString);
            $saveNameAndValues[$cookie->getName()] = $arrayCookieValues[1];
        }
    }

    if (count($saveNameAndValues) > 0) {
        $this->withCookies($saveNameAndValues);
    }
}
```

これを

```
$response = $this->get('/test/hoge');
$response->assertStatus(200);
$this->saveCookies($response->headers->getCookies(), ['fuga', 'buga']);
```

こう呼び出します。

何をしているかというと

- ヘッダーのSet-Cookieを取得
- 暗号化されているので復号
- その中から平文だけ取得
- withCookiesでテスト環境のCookieに挿入

です。

これの呼び出し後は、テストするソース内にて`Cookie::get`で取得しているところは正常に値が取得できます。

なお上記のコード内で`explode`しているところは、Laravelのバージョンが変わると仕様も変わる可能性があるので、臨機応変に。

# 暗号化を無効にしている場合

暗号化を無効化している要素の場合なんですが、`withCookies`で値を保存してもなぜか暗号化された状態で保存されてしまいます。

これも検索でヒットしたやり方では上手くいかなかったので、あれこれ試しました。
Laravelのバージョンにもよるのかも。

```
$this->disableCookieEncryption();
```

これをテストの1行目に書けば大丈夫です。

なおCookieが暗号化有効のものとそうでないものが混在していたらどうするのか、というところはまだ調べられておりませぬ。
MAMPを利用してLaravelとPHPの環境を構築したい

## 前書き
表題を実現したく、実際に遭遇したエラーなどを時系列的に書きました。

環境が構築できたら、下記の簡易SNSシステムの作成を行なっていますので、興味のある方はそちらもご参照ください。

https://qiita.com/pocky_tabemasu/items/50490705d2424236c718


## 環境

本記事投稿時点（2023/2）での最新バージョンで構築
・Mac M1
・Laravel 9
・php 8.2.0
・Composer version 2.5.1
・Workbench version 8.0.19 （ターミナルでの操作もできるためなくてもいいです。これは最新ではありません※後述）
・エディタ　：　Visual Studio Code

## 手順
### MAMP公式サイトから手順通りインストール
https://www.mamp.info/en/mamp/mac/

### Composerインストール
今回は2.5.1をインストール
![スクリーンショット 2023-02-03 15.34.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043250/5ee37b8d-5c83-d770-5d8b-d463d01d3aab.png)

https://getcomposer.org/download/

### PHPをインストール
homebrewを使用
※Mac M1以降はphpが標準搭載でないためインストールが必要

https://tech.amefure.com/php-homebrew

### MAMPインストール

https://hiro8blog.com/built-php-enviroment-by-mamp/

### Composerインストール

https://tech.amefure.com/php-composer

### Laravelインストール

~~~.ターミナル
cd /Applications/MAMP/htdocs/
composer create-project laravel/laravel --prefer-dist プロジェクト名
cd プロジェクト名/
~~~

MAMPのドキュメントルート変更
preferance→Server→Choose...から変更
プロジェクト/publicにすると初期画面が表示される
自分は/publicにしておらず、アドレスバーでlocalhost/publicと入力する必要がありました。

![スクリーンショット 2023-02-15 19.14.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043250/1a21034d-c58b-a76b-c116-87f8174cd8a0.png)

![スクリーンショット 2023-02-15 19.14.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043250/ef2eb980-baf4-e30e-e98d-16454e5405ba.png)

#### PATHを通す方法

https://mittaniblog.com/laravel-path-through/

### Workbenchインストール

https://blog.proglus.jp/77/#MySQL_Workbench

・データベース作成
→うまくいかなかったため、ターミナルでユーザーとデータベースを作成しました。

#### .envの編集
~~~.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=データベース名
DB_USERNAME=ユーザー名
DB_PASSWORD=パスワード
~~~

#### Workbenchでの操作

MySQL Connectionsの隣の+ボタンから設定

MAMP![スクリーンショット 2023-02-15 19.37.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043250/4ebb0203-18fa-eaba-650e-14bfc2a756dc.png)

.envファイルにそれぞれ項目を合わせます。PasswordはStore in Keychain...から入力
![スクリーンショット 2023-02-15 19.39.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043250/1cbb5d62-ead9-70eb-1ae1-68cc16f88252.png)

MAMPでStartボタン押下
プロジェクトのディレクトリで以下コマンド入力
~~~
php artisan serve
~~~

ブラウザのアドレスバーに
localhost
または
localhost/public（MAMPの設定で/publicにしていない人はこちら）
と入力

下記画面が表示されればOKです！
![スクリーンショット 2023-02-15 19.58.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043250/4c856707-7eef-f591-6d39-5f236b3b120b.png)


### 遭遇したエラー
・シェルについて無知でした。
自分の使用している環境に合わせてコマンドを変更してください。

https://mykii.blog/what-is-shell-bash-and-zsh/

・phpMyadminにて、うまく接続できなかったためWorkbenchを使用してDB操作
→Workbenchの8.0.32ではエラー、どうやらバグがあるらしいです
アンインストールして再度version 8.0.19にグレードダウンさせました。

https://downloads.mysql.com/archives/workbench/

・MySQLでrootユーザーに接続してしまったため、コマンドからユーザー作成、データベース作成をおこなってから再度接続。

## 参考
・環境構築の流れ

https://kuma-kou.com/make_laravel_dev_env_by_mamp/#toc5

https://www.sejuku.net/blog/106106

https://grune.co.jp/blog/laravel-create-local-environment/

https://www.udemy.com/course/laravelphp/
ant-path line アニメーション（Mapbox GL）

こんにちは
"[Add an ant path animation to a line](https://docs.mapbox.com/mapbox-gl-js/example/animate-ant-path/)" (Mapbox GL JS Examples) を動かしました。

* その際、```'layout': {'line-cap': 'round'}```を条件指定した場合は[^1]、不要な静止点が現れます[^2]。

[^1]: ```map.addLayer({'id': 'line-dashed', ...})```内に追加変更。
[^2]: これは ```line-dasharray``` が長さ ```0``` の場合、点（直径は```line-width```）として描かれるのが原因です。GitHub issue 内で議論されているようですが、当面は改善見込みなさそうです。

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54617/b0d2f4e9-b7ef-23f9-5242-59e35f4240ad.gif)
確実な接続のためのフェルール端子

### より線の配線
　電子工作では、より線を使ってターミナルから配線することが多いです。
　従来はAのように撚り線をよってそのままターミナルに突っ込んでいました。でも緩みます。
　はんだメッキするとほぐれませんが、すごい手間です。
　Bのようにフェルール端子を使うと、確実に接続ができます。圧着端子なので、作業性が良いです。

<img width="600" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/c5f03046-2f83-f79e-0c76-fa976ff7519d.png">


　ブレッドボードで利用するジャンパ線は固いので、このようなところに使うとすぐに緩んだり、折れます。

<img width="400" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/5559940e-4622-836b-fcac-31c49169d051.png">


### フェルール端子
　アマゾンで購入したフェルール端子です。もともとFAの制御盤などの配線に使われるので太いのが多いです。一番細いのがAWG22の内径0.5mmです。

　　[フェルール圧着工具 圧着ペンチ 0.25-10mm² 調整可能 握力 不要 圧着 工具 ペンチ 絶縁閉端子 1200 PCS DIYペンチ エンドスリーブ フェルール端子付き](https://www.amazon.co.jp/gp/product/B08DTT3512/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1)

![IMGP1572.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/1281c2c6-118a-27a2-bac3-d8f09cd07914.png)


　AWGの表記は、単線と撚り線では実際の外形は異なります。

##### 圧着したフェルール端子
　でこぼこができるので、抜けにくくなるようです。

<img width="200" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/4340f59e-1b8a-f76d-7ce7-ab12915e0c5f.png">



##### 細い径のフェルール端子
　検索すると、アマゾン、ミスミ、モモタロウ、アスクルや楽天で販売していますが、現在、在庫がないところが多いです。
　ミスミは、在庫ありの表示が出ます。

![IMGP1574.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/4cc76ca1-23e7-f42f-8b77-658019176cb1.png)

　左から、ワイドミュラーの0.14mm、ミスミオリジナルの0.25mm、ワゴの0.32mm、アマゾン入手の0.5mmです。
　0.25mmは、実際は0.32mmの場合があるようです。
　これら小さいサイズでは、金属スリーブの長さは、8mmと5mmがあります。

##### 実際に使う
　ケーブルの外皮に0.14と書かれた配線材料を使い、0.14、0.25、0.32、0.5、0.75、1.0mmをそれぞれ圧着しました。

<img width="400" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/cc8f457a-8fb4-5947-fd89-de0f15d096d9.png">

　引っ張ると、0.75と1.0mmは抜けてしまいました。0.32mm以下を使うべきだと思います。0.5mmは微妙です。
　最悪、0.5mmの場合、銅線を長めにし、折り返してスリーブの中に入れ、圧着をします。臨時には使えますが、おすすめではありません。
AWS RDS に localからmysql コマンドで接続出来ない時

# チェックポイント

- セキュリティーグループでインバウンドが許可されているか
- VPCのDNS解決は有効か
- VPCでpublicなサブネットで構成しているか
- DB作成後のエンドポイント作成処理は完了しているか
- mysqlコマンドが変わり種なので注意

# コマンド例

すべての準備が出来たら以下のようなコマンドを実行する

>Amazon RDS for MySQL データベースに接続するときは、接続文字列で --enable-cleartext-plugin オプションを使用する必要があります。--enable-cleartext-plugin 構文は、認証トークンとして機能するパスワードを渡すために使用されます。

```
mysql -u admin -P 3306 -h ***.cluster-cgklnrcdw5xr.ap-northeast-1.rds.amazonaws.com --enable-cleartext-plugin --user=admin --password=password
```

https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-mysql-access-denied/



# VPCの作成

パブリックサブネットだけでVPCを作成する
DNS解決は有効を指定する

<img width="1016" alt="image" src="https://user-images.githubusercontent.com/13635059/217185916-8d61fc87-886e-42f4-90d7-57288ad67ccd.png">

# DBの作成

ユーザー名とパスワードを指定する

<img width="834" alt="image" src="https://user-images.githubusercontent.com/13635059/217186343-64af3711-f8c1-4241-a282-08d03d74563b.png">

先程のVPCを指定する
パブリックアクセスをありにする

<img width="904" alt="image" src="https://user-images.githubusercontent.com/13635059/217186490-6abb319d-06a4-4d16-830c-e6b9eef87413.png">

DBを作成したらエンドポイントが有効になるのを待つ
ここでコピーできるエンドポイントをmysqlコマンドでhostとして指定する

<img width="1152" alt="image" src="https://user-images.githubusercontent.com/13635059/217186976-17d2b099-da78-4629-943a-bfe826b15372.png">


# セキュリティグループのインバウンドルールを編集する

インスタンスの方にセキュリティグループへのリンクがある

<img width="1055" alt="image" src="https://user-images.githubusercontent.com/13635059/217187093-0c8f8d32-de5b-4997-99d8-a2fecdbc76be.png">

3306を許可する
(マイIPを許可するのが良い)

<img width="1423" alt="image" src="https://user-images.githubusercontent.com/13635059/217186832-c3d704f8-c16e-4dd0-aac3-886715c492b1.png">

# コマンド実行

冒頭のコマンドを実行する


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
3大クラウドのKubernetes料金を比較(AWS EKS/Azure AKS/GCP GKE)

Region: Tokyo

|                        |AWS EKS|Azure AKS|GCP GKE|
|:-----------------------|------:|------:|-------:|
| Kubernetes Cluster     | $73.00|      0|       0|
| Container Registry(1G) |  $0.20|  $5.01|   $0.05|
| Load Balancer(1G)      | $22.42| $21.00|  $27.76|
| NAT Gateway(100G)      | $51.46| $41.40|   $5.51|
| VPC                    |      0|      0|       0|
| Subnet                 |      0|      0|       0|
| Worker Node            |      -|      -|       -|
Elixir 学習記（1. 環境構築）

# Elixir 学習記

| ← 前 | [目次](https://qiita.com/SF-28/items/197df5e03ab9787f40a0) | 次 → |
| :-: | :-: | :-: |
| - | 1. 環境構築 | [2. データ型](https://qiita.com/SF-28/items/3f4208d51f2bbaa4afe9)


# 環境構築

触ってみなければ始まらないということで、学習環境の構築からです。

- **[Livebook](https://livebook.dev/)** 

    私自身Pythonを主に使ってきたこともあり、Jupyter Notebook に似ていると聞いて飛びつきました。
    コンテナイメージが公開されているので、コマンドでさくっと準備。
    
    ```bash
    docker run --pull always livebook/livebook -p 8080:8080
    ```
    
    コンテナ化されているおかげで手軽、嬉しい。
    
    ```text
    [Livebook] Application running at http://0.0.0.0:8080/?token=<random_token>
    ```
    
    ブラウザで上記URLにアクセスしたら無事表示されました。

    ![Livebook0](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1666407/384a3fd3-ded1-1197-7b9b-ed82745dfb1b.jpeg)
    
    ![Screenshot 2023-02-07 14.48.17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1666407/0bbbc48a-cad6-74f1-4f76-c1932e096c22.jpeg)
    
    学習用のノートブックまで用意されている・・・Elixirの基礎を学んだら覗いてみよう
    
    とりあえず Home 右上の`New Notebook`を押してノートブックを作成、
    セルに式を入力して実行`(Shift+Enter)` します。
    
    ![Livebook1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1666407/80f2c391-ce7c-e1a0-c178-325241349bb7.jpeg)
    
    結果がすぐに確認できていいですね、学習が捗りそうです。
    学習履歴をファイルとして残していけるので、モチベ維持にも一役買ってくれそうです。

- Livebook コンテナの CLI

    基本 Livebook でいけるんですが、`mix`や`iex` を学ぶのは流石に厳しそうでした。
    (もし良いやり方があれば教えてください)

    これらは上記で作成したコンテナに接続し、そこで実行＆学習しています。
    コンテナへの接続は、VSCode拡張機能の`Docker`があるとお手軽です。


# 学習途中の感想

- [Elixir School](https://elixirschool.com/ja)から学び始めたけど、[公式ガイド](https://elixir-lang.jp/getting-started/introduction.html)を先にしたほうが分かりやすかったかも
- 必要な情報はまとめられているが、いざ学ぶと修行感が強い
- 何かモノを作りながら学べる教材があれば違った体験になりそう

# 余談

手を動かしながら本記事を書けたら良かったけれど、
一通り終わったあとでまとめるという流れになってしまった・・・。
常にアウトプットの意識を持って作業できるよう、習慣化していかねば。
Vuetify3の小ネタ - 1

# レイアウト構成
### 参照
* https://next.vuetifyjs.com/en/features/application-layout/

### 要素
* v-app-bar
    * ヘッダーバー
* v-navigation-drawer
    * サイドバー
* v-footer
    * フッター
* v-main
    * メイン画面

* スマホアプリ開発する時に
    * v-system-bar
    * v-bottom-navigation

### サンプル
```

```



----

# グローバルfont family変更
### 参照
* https://stackoverflow.com/questions/45598884/change-default-font-in-vuetify
    * Update 2021

### 対応
App.vue中に
```
$font-family:'Ubuntu'

.v-application {
  [class*='text-'] {
    font-family: $font-family, sans-serif !important;
  }
  font-family: $font-family, sans-serif !important;
}

```


# font-size
### 参照
* https://m2.material.io/design/typography/the-type-system.html

### 内容
* vuetify3に、1rem == 16pxぽい
    * 20px == 1.25rem
    * 14px == 0.875rem


# aliasingを使うと便利
### 参照
* https://next.vuetifyjs.com/en/features/aliasing/


### 対応
```src/plugins/vuetify.vue
import { createVuetify } from 'vuetify'
import { VBtn } from 'vuetify/components'

export default createVuetify({
  aliases: {
    MyButton: VBtn,
  }, 
  defaults: {
    MyButton: { variant: 'tonal' },
  },
})

```

```base.vue
<my-button
  @click="click" >テスト
</my-button>

```
ransackのチェックボックスをtrue/falseで返したい

# はじめに
ransackのチェックボックスを使用した時にはまったのでメモを残します

# 前提
以下のadminテーブルに退職者カラムがあります。

```
class Admin < ApplicationRecord
  endsuspended  :boolean   default(FALSE), not null
end
```
・endsuspended：true(退職している)
・endsuspended：false(退職していない)

View で下記のようにチェックボックスを実装しようとしています。
チェック有り・・・全員表示
チェック無し・・・退職していない人だけ表示
※初期表示は、チェック無しの退職していない人だけ表示させたい
```
= search_form_for @search, url: admin_admins_path do |f|
 = f.check_box :suspended_eq, checked: @suspended, class: "check-box" 
```

# はまったところ
Rancackでチェックボックスをチェックして検索するとtrueのみ検索される。チェック外して検索するとfalseのみ絞り込みされてる。

今回の場合は、チェックして検索した場合はtrueとfalseすべて検索、チェック外して検索した場合はfalseのみ検索して欲しい。

これでチェック外した場合はすべて検索されるが、今回はこれの逆パターン、、、
```
= f.check_box :suspended_true
```

# 解決策
①後ろに```, true, false```を追記して、パラメーターを数字の文字列の取得から、チェックした時にだけ"suspended_eq"=>"true"が送られるように変更
```
= search_form_for @search, url: admin_admins_path do |f|
 = f.check_box :suspended_eq, { checked: @suspended, class: "check-box" }, true, false
```
②コントローラー側に以下を記載し、チェックして検索した場合はtrueとfalseすべて検索、チェック外して検索した場合はfalseのみ検索するように実装
```
params[:q] = {} if params[:q].blank?
params.dig(:q, :suspended_eq).present? ? params[:q].delete(:suspended_eq) : params[:q][:suspended_eq] = false
```
・```params[:q] = {} if params[:q].blank?```は初期表示の場合、ransackのパラメーターが存在しない場合の考慮
・チェック無しの場合(パラメーター送られてこない)・・・suspended_eq: falseが必要 （suspended_eq=falseのみ表示したい） 
・チェック有りの場合(パラメーター送られてくる)・・・suspended_eq: trueが不要 （全量表示したい）

# 参考文献
- [Ransackでチェックボックス検索を実装した時にはまったこと
](https://kenzoblog.vercel.app/posts/ransack-checkbox)
- [Rancackでチェックボックスを外して検索した場合すべて検索するメモ](https://cortyuming.hateblo.jp/entry/20140216/p1)
RSpec長くなりがちなので短くしたい it_behaves_like

## 背景
Rspecで条件が一部違うが比べるところは大体同じみたいなテストが多かった

そこで　`it_behaves_like`　を使う

## 用途

テストのit部分を使いまわす

## 使用例

##### `it_behaves_like`使う前

```Ruby
describe '仕事する' do
  subject { instance.test_suru_method }

  let!(:instance){ Factory.no_yatu }
  let(:target){ Factory.no_yatu }

  context 'conditionsが良いとき' do
    let(:conditions){ "good" }

    it '仕事すること' do
      is_expected
      expect(instance.published).to eq true
      expect(instance.work).to eq (target.work)
      expect(instance.conditions).to eq conditions
    end
  end

  context 'conditionsが悪いとき' do
    let(:conditions){ "bad" }

    it '仕事すること' do
      is_expected
      expect(instance.published).to eq true
      expect(instance.work).to eq (target.work)
      expect(instance.conditions).to eq conditions
    end
  end

  context 'conditionsが絶好調のとき' do
    let(:conditions){ "best" }

    it '仕事すること' do
      is_expected
      expect(instance.published).to eq true
      expect(instance.work).to eq (target.work)
      expect(instance.conditions).to eq conditions
    end
  end

  context 'conditionsが絶不調のとき' do
    let(:conditions){ "worst" }

    it '仕事すること' do
      is_expected
      expect(instance.published).to eq true
      expect(instance.work).to eq (target.work)
      expect(instance.conditions).to eq conditions
    end
  end
end
```

##### `it_behaves_like`使った後

```Ruby
  describe '仕事する' do
    subject { instance.test_suru_method(conditions) }

    let!(:instance){ Factory.no_yatu }
    let(:target){ Factory.no_yatu }

    shared_examples_for '仕事すること' do
      it do
        is_expected
        expect(instance.published).to eq true
        expect(instance.work).to eq (target.work)
        expect(instance.conditions).to eq conditions
      end
    end

    context 'conditionsが良いとき' do
      let(:conditions){ "good" }
      it_behaves_like '仕事すること'
    end

    context 'conditionsが悪いとき' do
      let(:conditions){ "bad" }
      it_behaves_like '仕事すること'
    end

    context 'conditionsが絶好調のとき' do
      let(:conditions){ "best" }
      it_behaves_like '仕事すること'
    end

    context 'conditionsが絶不調のとき' do
      let(:conditions){ "worst" }
      it_behaves_like '仕事すること'
    end
end
```

### まとめ

使用すると非常にスッキリ
コンパクトにできました
Objective-Cで定義した列挙型(enum)をSwiftからrawValueで初期化する際の注意

Swiftが出てきて、非常に協力になったenum。
今回はそのenumとObjective-Cが絡んだ場合に出会った事象について記述します。

# はじめにのenumのおさらい
Objective-Cのenumは、原則Integerを使用した値になります
```Objective-C:
typedef NS_ENUM(NSInteger, Animal) {
    AnimalDog = 0,
    AnimalCat = 1,
    AnimalBird = 2,
};
```

Swiftの場合、Objective-Cとは違って値を持たずとも定義出来ます

```swift:
enum: Animal {
    case dog
    case cat
    case biard
}
```

設定する値もInt以外が使用出来ます。

```swift:
enum: Color: String {
    case red = "red"
    case blue = "blue" 
    case yellow = "yellow"
}
```
値からenumを初期化する場合はイニシャライザを使用します。
定義されていない値を渡した場合は`nil`が返却されます。
```swift:
let enum1 = Color(rawValue: "red") // .red
let enum2 = Color(rawValue: "green") // nil
```

また、protocolに準拠させたり、拡張を記述することも出来ます。→ [参考](https://qiita.com/hachinobu/items/392c96820588d1c03b0c)

# Objective-Cで定義したenumをSwiftから使用する
Objective-C側で定義したenumをSwiftから使用することが出来るのですが、ここで困ったことが。
Objective-Cで定義したenum値
```Objective-C:
typedef NS_ENUM(NSInteger, Animal) {
    AnimalDog = 0,
    AnimalCat = 1,
    AnimalBird = 2,
};
```
こちらをswiftから定義されていない値で初期化した場合、nilが返ってこないのです！
```swift
let animal = Animal(rawValue: 5)
print(animal) // Optional(__C.Animal)
```
# 対処法
一番手っ取り早いのはenumの定義をSwiftファイルに移動させることでした。
移動させるだけで、イニシャライザで定義されていない値を渡すとnilを返すようになります。

# 最後に
良きObjective-Cライフを！
Quick v5からv6へのバージョンアップ時の対応

Quickをv5からv6にバージョンアップをした際にやった対応内容をかんたんにまとめました。

Quick v6のリリースノートはこちらです。
https://github.com/Quick/Quick/releases/tag/v6.0.0

v6で何が変わったかというと一番の大きな変更はこちらのAsync/awaitサポートです。

```Async/await support. All tests now run in an async context.```

テストでasync/awaitが使えるようになったというメリットがあるのですが、
単純にアップデートしたい場合はすべてのテストがasync contextで実行されるように変更されている（いままではmainだった）ので場合によっては結構な影響があります

```Again, with the async support, all tests now run in an async context. This will require you to make changes, especially if you use Nimble.```

## 対応した内容

### waitUntil
NimbleのwaitUntilをつかっていたので、こちらをawait waitUntilに変更しました。

エラー
```
Global function 'waitUntil' is unavailable from asynchronous contexts; the sync version of `waitUntil` does not work in async contexts. Use the async version with the same name as a drop-in replacement; this is an error in Swift 6
```

### toEventually
NimbleのtoEventuallyをつかっていたので、 `expect(Hoge).toEventually(…` の先頭にasyncを追加しました。

エラー
```
Instance method 'toEventually' is unavailable from asynchronous contexts; the sync version of `toEventually` does not work in async contexts. Use the async version with the same name as a drop-in replacement; this is an error in Swift 6
```

### main threadに変更

テストがmain threadで実行されなくなったので、例えばViewModelのdriverのテストなどをしている場合には動かなくなってしまいます。

対応方法としてはclosureをmain threadで走るように指定します。

```swift
it("runs on the main thread") { @MainActor in
    // contents of this closure will run in the main actor.
}
```

または全てmain threadで動かしたい場合はクラス自体をMainActorにすればよさそうでした。
```swift
@MainActor
class MySpec: QuickSpec {
```

ただ全部main threadで実行してしまうと並行でテストを実行できなくなってしまうのでなるべく避けたいですね。
プリザンターでフィルタ条件/ソート条件付の一覧を表示するURLの作り方

# はじめに
[プリザンター](https://pleasanter.org)の一覧画面で、フィルタ条件やソート条件を予めセットしておきたい場合があります。ビュー機能を利用する方法もありますが、JavaScriptなどで動的に変更したい場合などの記述方法について説明します。

## 実装方法
フィルタ条件やソート条件を指定したviewを作成し遷移先URLのクエリパラメータに渡します。
```javascript
let view = {
    ColumnFilterHash: {
        ClassA: "[\"設計\"]"
    },
    ColumnSorterHash: {
        StartTime: 'asc'
    }
};
location.href = '/items/2/index?view=' + JSON.stringify(view);
```

## 遷移先のURL
ブラウザ上でJavaScriptを実行すると下記のようなURLに遷移します。view=の部分にクエリパラメータとしてviewの内容が指定されています。

```url
http://myserver/items/2/index?view={%22ColumnFilterHash%22:{%22ClassA%22:%22[\%22%E8%A8%AD%E8%A8%88\%22]%22},%22ColumnSorterHash%22:{%22StartTime%22:%22asc%22}}
```

## 実行結果
JavaScriptの実行により、作業工程（ClassA）が「設計」のフィルタ条件と開始（StartTime）が昇順のソート条件が適用された一覧が表示されました。

![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78230/f90dd71c-45e0-4cf2-c5f4-8186554a586d.png)

## ビューの指定方法
ビューの指定方法は公式のマニュアルにありますので、下記をご参照ください。
https://pleasanter.org/manual/api-view
sign_and_send_pubkey: no mutual signature supported

たまにしかssh接続しない環境に久しぶりにMacからアクセスしたところ、以下のエラーでアクセスできなくなっていた。

```
sign_and_send_pubkey: no mutual signature supported
```

以下のようにPubkeyAcceptedKeyTypesとHostKeyAlgorithmsを指定すれば解決した。

```diff
Host myhost
  Hostname xxx.xxx.xxx.xxx
  User myuser
  IdentityFile ~/.ssh/mykey.pem
+  PubkeyAcceptedKeyTypes=+ssh-rsa
+  HostKeyAlgorithms=+ssh-rsa
```

MacOSのバージョンアップによってsshクライアントがデフォルトでRSAをサポートしなくなったんだろうか。推奨される方法でキーの再作成がベストらしいが、とりあえず接続はできるようになりました。

参考
https://stackoverflow.com/questions/73795935/sign-and-send-pubkey-no-mutual-signature-supported
ブラウザでTeamsをテナント指定で開く

# 背景
Azure ADのアカウントが複数のテナントのTeamsに入っており、テナントを指定してブラウザで開きたい。
調べてみると、情報が無く、不可となっていたが、出来たのでこちらにメモっておきます。

# 方法
以下のように入力
https://teams.microsoft.com/?tenantId=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

# 調査
以下のサイトなどいくつか見たが、テナント指定での起動は不可となっていた。
- [Teamsテナント固有のURL - Microsoft コミュニティ](https://answers.microsoft.com/ja-jp/msteams/forum/all/teams%E3%83%86%E3%83%8A%E3%83%B3%E3%83%88%E5%9B%BA/109a6548-6d38-4a97-8c46-1481805c9be0#:~:text=Teams%20%E3%81%AF%E8%A3%8F%E3%81%AB%20SharePoint,Teams%20URL%20%E3%81%AA%E3%81%A9%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82)
  > Teams は裏に SharePoint を持っていてそちらで管理されています。
  > そのため、テナントごとの Teams URL などはありません。
新卒SESが入社半年でキャリア採用されて5年目の給料になった話

### はじめに

特定を避けるために一部改変していますが、転職するに至った経緯や面接で気を付けたことなどを書いていきます

記事を書くのは初めてなので冗長になってしまいましたが、読んでいただけると嬉しいです！
(ガキが語るなよ…と思う方は回れ右お願いします)

#### 事前情報詰め合わせお得パック
- 経歴
研修2ヶ月
SESとして5ヶ月現場作業

- スペック
専門2年卒 社会人1年目の21歳
資格・ポートフォリオ等一切無し
スキル的なヤツ Java/C言語/Linux/Oracle

- 現会社の仕事内容など（SES）
基本的に運用の仕事が多く、そのついでに新規機能開発を行う
ウォーターフォール型でSAから本番リリースまで行う
フロントエンドがVB、サーバーサイドがJavaとC言語で構築されている
古いシステムで欲しいスキルが身につかない
いいように言えば歴史あるサービス

- お給料の話
[こちら](https://shukatsu-mirai.com/archives/65598)の記事を参考に5年目の給料と記載しました！




#### 転職を決めたきっかけ
- 参画先でC言語の大規模案件が発生しそうで、自分がやりたいことと違った
- 案件単価が上がっても自分の給料に反映されないためモチベが上がらない（何かあった時の会社の蓄えになる）
- 勢いのある企業で働きたい

#### 転職先の企業に求めるもの
- 案件の選択肢が豊富
- 有給消化率が高く、残業時間が10時間程度
- 案件単価の還元率が高い
その他福利厚生などetc...

## 何はともあれ結論

経験も資格も無い人は特に __やる気・将来性・コミュ力__ を見られる（と感じました）
というか1年未満なんて企業側も技術力無いのわかってるのでスキルシートがスカスカでもﾓｰﾏﾝﾀｲ（~~多分！~~）

__転職無理だったらいまの会社いればいいし！
時間使う以外のデメリット無いじゃん！__
のマインドの元ゆるゆるりと転職の旅へGO！



### ノリと勢いだけの転職開始
アホ面でデスマをシバいてた11月某日…
![37ABF55A-7748-4764-B309-916308111831.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126733/20a8165f-c63a-dae3-d258-28d73abdc1aa.png)


__ｶﾀｶﾀｶﾀｶﾀ…ｯﾀｰﾝ!! せや！転職したろ^^__

そう思い立ち、善は急げということでその日のうちにマイナビ転職に登録。

第二新卒枠かキャリア枠で迷いましたが、自分は専門卒……新卒枠で入ると大卒勢より給料が低い！
（あたりまえ）

__まあキャリア採用で探してみよ！見つからんかったら新卒枠に切り替えればええやん__

ということで早速キャリア採用で企業リサーチ。
でも現実はそんなに甘くない。どこも経験2年から取っているところが大多数、、
![29ACCF69-0343-4C44-8A84-B132FC7FE7BF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126733/4aa1e4d9-c2af-e535-aabc-4184edd3cdbe.png)

__でもそんなの関係ねぇ！
はい！書類ドーン！！__

そんなこと言ってても始まらないので、いい感じの企業に半年間働いてきた集大成(笑)、スッカスカのスキルシートを堂々提出！なんとかなれーッ

### 気合いだけの面接
![CAE4CBCD-C9E8-4CC6-AEFC-F6F2F3730010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126733/eb36f509-ffd0-7035-ad7d-6a76661fb187.png)


__気を付けたこと__
ハッキリとキャリアプランを説明し、新しい技術にも挑戦していく積極的な姿勢のアピール、あとは笑顔を絶やさないことに重点を置きました。
また、企業側から自分の至らない点を指摘された時は素直に受け止め、修正していく旨を伝えられたのが良かったのかなと思います。

※もちろん自分には経験が足りないことも含めて堂々と答えました。謎の自信ってスゲーッ

3社受けましたが、どこも経験1年未満は取ったことが無いそうでイレギュラーだったみたい。
そりゃそうだよね！

> 企業様｢○○くんを雇うならチャレンジ採用になるから｣

とのことで少し不安でしたが、翌日メールにて無事内定をいただきました。やっほーい！

その後同じようなSES会社を2社受けて2社とも内定。
結局社長の印象が良かった1社目に内定承諾を送り、経験1年あった方が案件単価が高くなるよ〜とのことで4月入社に決定しました。
（後から聞いたところ多い時は月に100名ほど応募があるみたいで、誰でも採用しているから自分でも入れた訳ではないみたいです）

あとはメールを丁寧に書きすぎて「昭和みたいなメール送るね笑」と言われるくらい丁寧に書きました。誠意を込めて書くのだいじ。

## 最後に個人的な見解など
結局何を伝えたいかと言うと、
__「スキルが無いから無理」｢最低2年は勤めないと採ってくれない｣「自分には資格も無いから無理」__
などと決めつけずに、チャレンジしないと何も始まらないということです。

企業も将来性があると思えば採用してくれますし、限界は自分で決めるものでは無いですね。
__こいつは伸びるぞ！といかに思わせられるかが大事な気もします__
![773D5E04-B044-4E31-A7C8-800CD05B3045.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126733/efa43f69-b393-7493-fae9-2fe25e4f6a07.png)

 __学歴や経験・資格が無くてもなんとかなる！__ 

勝ったッ！転職活動完！

お読みいただきありがとうございました！
ご意見、ご指摘はコメントにお願いします。
Golang、PresignURLでファイルをアップロードするときハマったところ

GolangでPresignURLを使ってファイルをアップロードすると下記のエラーが出てしまい
```
<Error><Code>NotImplemented</Code>
<Message>A header you provided implies functionality that is not implemented</Message>
<Header>Transfer-Encoding</Header>
```

RequestのHeaderをDumpすると`Transfer-Encoding:chunked`になってる。この値だとAWS側が対応してないみたいです。

## 解決方法
go version 1.19
```
req.ContentLength = #content size <-　ファイルのサイズ値を設定する
```
ContentLengthを設定するだけで解決しました

因みに、`req.Header.Set("Content-Length", xxx)`を設定しても解決できないです。これのせいで結構ハマりました理由です。

Full Codeはここです
```
func uploadFile(filePath, contentType, uploadUrl string) {
	data, err := os.Open(filePath)
	if err != nil {
		log.Fatal(err)
	}
	defer data.Close()
	req, err := http.NewRequest("PUT", uploadUrl, data)
	if err != nil {
		log.Fatal(err)
	}

	info, _ := data.Stat()
	req.Header.Set("Content-Type", contentType)
	req.ContentLength = info.Size()

	client := &http.Client{}
	res, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()

	if res.StatusCode == http.StatusOK {
		log.Println("Upload S3 Success ", filePath)
	} else {
		log.Println("Upload S3 Fail ", filePath)
	}

	respDump, err := httputil.DumpResponse(res, true)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Response:\n%s", string(respDump))
}
```
LaravelでのBootstrap5の導入方法

# A, Laravel UIを使う場合

```php
composer require laravel/ui

php artisan ui bootstrap
// bootstrap以外にもvueやreactのインストールも可能

npm install
 
npm run dev
```
Laravel UIにより、webpack.mix.js
npm run devにより、public/css/app.css
自動で生成されています。

#  Bootstrapでcssとjsを読み込む。
resources/sass/app.scssを生成。
```php
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<script src="{{ asset('js/app.js') }}"></script>
```
----------------------------------
# B, Bootstrapのみをインストールする（Laravel UIを使わない）場合

すでに型ができており余計なものをいれたくない、などLaravel UIをいれたくない理由がある場合はこちらになります。
Bootstrap5のインストール
```php3
npm install
npm install bootstrap
npm install sass
```
上記コマンドでもbootstrap5がインストールされる場所。

```php
└── node_modules/
    └── bootstrap
        ├── js
        └── scss
```

# Viteの場合 
以下追記。
```resources\js\bootstrap.js
import 'bootstrap';
```
resources\sass\app.scssファイル作成後、追記。
```resources\sass\app.scss
// Bootstrap
@import 'bootstrap/scss/bootstrap';
```
修正：
``` wite.config.jp 
～略～
input: [
   　 'resources/css/app.sss',
      //'resources/scss/app.scss', //追加不要みたい
      'resources/js/app.js',
      ],
～略～
```
呼び出し
```php
@vite(['resources/scss/app.scss', 'resources/js/app.js'])
```
```php
npm run dev
```
本番にJS/CSSを出力する場合
```php
npm run build
```
# その他方法での利用したい場合、下記公式サイトを参考

https://getbootstrap.jp/

https://bootstrap-guide.com/outline