OmniAICreator/Qiita-1.07M huggingface dataset:
【VRChat】複製(Duplicate)したアバターをNew Avatarとしてアップロードする

１つのプロジェクトの中でアバターを編集したくなった時にDuplicateして編集することが多いのですが、そのアバターをアップロードしようとするとUpdate Avatarになってしまって困っていた現象の解決方法のメモ。
![スクリーンショット 2023-07-14 013452.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492509/3480b7c8-4fce-d591-602b-c5ed425ebd8e.png)
![スクリーンショット 2023-07-14 014050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492509/5687db0e-f48a-7e13-7931-e54c87ab7413.png)

## 結論
inspectorから`Pipeline Manager(Script)->Detach(Optional)`を押して`Blueprint ID`をリセットすると解決する。
![スクリーンショット 2023-07-14 013519.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492509/6c4ee06d-b9af-2d57-6ad0-a89b27b7e68a.png)
![スクリーンショット 2023-07-14 013537.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492509/57a88a5f-ceac-3c79-93d7-594e288daaba.png)
![スクリーンショット 2023-07-14 014207.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492509/07a6b085-b302-d2fa-f7f4-e16e06799007.png)
（Python）jsonオブジェクト内のfloat⇔Decimal一括型変換

## 概要
AWSでLambdaからDynamoDBを操作していると、jsonオブジェクトのfloat⇔Decimalの型変換が必要なタイミングが多々発生する。
ネストされたjsonの構造をいちいち調べて変換するのは大変であるため、一括での変換方法を作成してみた。

実行環境：Python 3.10

## Decimal→floatの場合
こちらは検索でも何件かヒットした。
json.dumpsのdefaultを利用する。
```python
import json
from decimal import Decimal

#Decimal->float,int変換用の関数を作成
def decimal_to_num(obj):
    if isinstance(obj, Decimal):
        return int(obj) if float(obj).is_integer() else float(obj)

#ネストされたDecimal型の要素を持つjsonを定義
json_decimal = {'key1': 'value1', 'key2': Decimal('12.3'), 'key3': {'key4': Decimal('456.7'), 'key5': 100, 'key6': [1, Decimal('8.9'), {'key7': Decimal('10.1')}]}}

#json.dumpsでstrに変換するタイミングでDecimalをfloatにする
json_str = json.dumps(json_decimal, default=decimal_to_num)

#jsonに戻す
json_float = json.loads(json_str)

#変換結果の出力。Decimal型はすべてfloat型になっている
print(json_float)
#print結果：{'key1': 'value1', 'key2': 12.3, 'key3': {'key4': 456.7, 'key5': 100, 'key6': [1, 8.9, {'key7': 10.1}]}}
```

## float→Decimalの場合
こちらはあまり情報がなく難儀したが、[公式ドキュメント](https://docs.python.org/ja/3.10/library/json.html)に記載の通りjson.loadsのparse_floatを使って、floatをDecimalに変換可能。

```python
import json
from decimal import Decimal

#ネストされたfloat型の要素を持つjsonを定義
json_float = {"key1": "value1", "key2": 12.3, "key3": {"key4": 456.7, "key5": 100, "key6": [1, 8.9, {"key7": 10.1}]}}

#一度strに変換
json_str = json.dumps(json_float)

#jsonに戻すタイミングでfloatをDecimalにする
json_decimal = json.loads(json_str, parse_float=Decimal)

#変換結果の出力。float型はすべてDecimal型になっている。intは影響なし。
print(json_decimal)
#print結果：{'key1': 'value1', 'key2': Decimal('12.3'), 'key3': {'key4': Decimal('456.7'), 'key5': 100, 'key6': [1, Decimal('8.9'), {'key7': Decimal('10.1')}]}}
```
【VSCode】Markdownの拡張機能の作り方

## はじめに
VScodeの拡張機能のうち､Markdownの拡張機能を作る方法を紹介します｡
とても簡単です｡

ちなみに､VScodeの拡張機能の作り方と公開方法は以下を参考にしてください｡
- [【VSCode】拡張機能を自作する方法 - Qiita](https://qiita.com/yusu79/items/96dd9b09d0cebb86f1be)
- [【VSCode】自作した拡張機能を公開する方法 - Qiita](https://qiita.com/yusu79/items/44520c4c67864b0bb3e9)

## 前提知識
VScodeの拡張機能の`extension.js`は大抵以下のように､`context.subscriptions.push()`に設定を反映させるという形をとります｡
```js:extension.js
const vscode = require("vscode");

function activate(context) {
    let disposable = vscode.API.関数...
    context.subscriptions.push(disposable);
}

function deactivate() {}

module.exports = {
    activate,
    deactivate
}
```

## Markdown-itプラグインを反映させる方法

### 1.extension.jsの編集
実は､markdown-itプラグインを反映させるだけなら`context.subscriptions.push()`を使う必要がありません｡
以下のように､`extendMarkdownIt(md) {}`内で､`md.use(require(プラグイン))`とするだけでいいです｡
```js:
function activate(context) {
    return { 
        extendMarkdownIt(md) {
            md.use(require("プラグイン"));
            return md;
    }};
}

function deactivate() {}

module.exports = {
    activate,
    deactivate
}
```


### 2.package.jsonの編集
`"contributes"`を以下のように変えます｡
```json:package.jsonの"contributes"
"contributes": {
    "markdown.markdownItPlugins": true
}
```

## まとめ
これでmarkdownのVScode拡張機能が完成です｡
つまり､markdown-itプラグインをあらかじめ作って`npm`で公開しておけば､たったこの2つのステップを踏むだけでMarkdownの拡張機能を作ることが出来ます｡
【環境構築】DockerでReactをyarnで起動して作成&起動する方法（TypeScript編）

## 背景
- [【環境構築】Reactのプロジェクト作成&起動方法について 〜npm・yarn & TypeScript・TypeScript〜](https://qiita.com/takuma-1234/items/ce8c815ae05678f5a403)で、`React`には複数のプロジェクトの起動＆作成方法があることをご紹介しました。
- この記事は、「2.2.`yarn`で`TypeScript`を使用して`React`プロジェクトを作成する方法」の解説記事になります。

## 目標
- `yarn`で`TypeScript`を使用して`React`プロジェクトを作成できるようになる。

## `yarn`で`TypeScript`を使用して`React`プロジェクトを作成する方法
- [docker-react-yarn-typescript](https://github.com/takuma-competition/docker-react-yarn-typescript)を`clone`し、起動に必要な`dockerfile`をローカルに準備します。

https://github.com/takuma-competition/docker-react-yarn-typescript

- `Dockerfile`の中身は以下のようになっており、`node`をベースイメージとして使用しています。
```dockerfile:Dockerfile
#nodeの19.4.0をベースに使用する
FROM node:19.4.0
```
- 以下のコマンドで`docker`を起動します。
```bash:docker起動コマンド
$docker-compose up -d --build
```
- `vscode`でコンテナ内部に入ります。`vscode`でコンテナ内部に入る方法は[【環境構築】Docker container内部にVS Codeで入って作業する方法](https://qiita.com/takuma-1234/items/822823ce151340945975)を参照ください。
- `vscode`でターミナルを起動し、作業用に`docker-compose.yml`でマウント時に作成された作業用のディレクトリに移動します。
```bash:作業用ディレクトリに移動
$cd ../react_yarn_typescript_workdir/
```
- `yarn`で`react`のアプリの雛形を作成します。
- `create react-app`の後ろにくる文字列が作成されるディレクトリ名になります。（ここでは、`react_yarn_TypeScript`というディレクトリが作成されることになります。）
```bash:reactアプリの雛形の作成
$yarn create react-app react_yarn_typescript --template typescript
```
- 作成されたディレクトリに移動します。
```bash:作成されたディレクトリに移動
$cd react_yarn_typescript/
```
- `react`を起動します。
```bash:react_start
$yarn start
```
- 起動が成功すればご自身のPCで設定されているデフォルトのブラウザで`react`が起動されます。

## 参考資料
https://docs.docker.jp/v1.12/compose/reference/overview.html

https://qiita.com/keitean/items/d83254090405aa714b15

https://qiita.com/RyosukeSomeya/items/974d4308c194a804162a

https://create-react-app.dev/docs/getting-started/#yarn

## 個人ブログ
MySQLWorkbenchで1175エラー発生

- 事象
MySQLのワークベンチでUPDATE文を実行すると以下のエラーが発生。
`Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect. `

- 解決策
`SET SQL_SAFE_UPDATES = 0;`　を実行

- 備考
恒久対応は後程
8年運営したSaaSの化石のようなカスタマイズコードに向き合う

# 化石みたいになったカスタマイズ、つらい
もっと長く運営しているシステムをお守りしている方には8年程度と怒られるかもしれないですが、これくらい経つともう何のためのカスタマイズかわからないコードが割とあります。

こういうのはバグの温床になったりQAのコストを増加させたりしますし、何なら重要なビジネスロジックの中に複雑にカスタムコードが入り込んでいたりするので摘出するのも大変です。

SaaSの王様Salesforceの話ですが、初期に超王手金融クライアントのためにカスタマイズをしてしまって、その後そのカスタマイズによってインシデントを引き起こしてこれじゃダメだとなってAPIを提供するプラットフォーム化を進めることになったという話があります。プラットフォーム化した今でもそのカスタマイズコードは切り離せずに残ってしまっているそうですw
(参照→ https://open.spotify.com/episode/58TPAKYpVVkOBWlwQuFQF7)

今日はそんなカスタムつらいよ話をします。

# 遭遇したカスタマイズのパターン
### controllerやviewにif-elseが連なっている
安直でわかりやすいのでさほど厄介ではないだろうか。カスタマイズを認知するのも標準機能化するのも摘出するのも容易と思われる。
しかしfat controller拒絶症のエンジニアがいたら発狂してしまうので注意。
### メールアドレスなどのハードコード
これもわかりやすいので厄介ではないはず。
### enumにカスタマイズ用の値が定義されている
テストが漏れていると危ない。
### ページファイルがクライアントごとに分かれている
ファイルごと分かれているので、改修時には見落としてしまってバグになりがち。
### 機能ごと特定のクライアントしか使ってない(または使えないようになっている)
そもそもカスタマイズであることが忘れられていく。この機能誰が使ってるの？と言って削除してしまうと後で怒られてインシデントになりがち。(自分が経験したわけではないです、一応。。)

他にも思い出せそうですが胃が痛くなってきたのでやめておきます。もっと別なパターンがあったら教えてください。

# なぜカスタマイズが混入してしまうのか
サービスを方向転換することがあればどうしても当初の設計に無理が生じるためと考えます。
自分の経験だと、最初はSaaSでもなんでもなかった→2社が共同利用するようになった→マルチテナント展開するようになったという経緯で成長したサービスでしたが、マルチテナント化の最終的な意思決定をするまでの間に(後から見れば)カスタマイズになるコードが混入することになってしまいました。

# カスタマイズに向きあうための考え方
- 全て除去しよう、負債を返済しようと思わないこと
    - 上記Salesforceの話しかり、影響度的に摘出不可能なものもある
- 抱えてしまった負債は仕方ないと考えて、むしろこれと一生付き合う覚悟を持つ
- ただしカスタマイズを全て一覧化して把握する努力はする
- カスタマイズはバグの温床なので、それを踏まえてテスト設計をする
【PlantUML】リンクを挿入する方法


## PlantUMLでリンクを貼る方法

次のように`[[URL{tooltip} label]]`と記述することでPlantUMLにリンクを貼ることができます。

```:sample.puml
@startuml Sample
skinparam ClassFontSize 30

entity "[[https://example.com{example.com} users]]" as users {
}
@enduml
```

```plantuml
@startuml Sample
skinparam ClassFontSize 30

entity "[[https://example.com{ツールチップ} users]]" as users {
}
@enduml
```

## 参考

https://plantuml.com/ja/link#:~:text=%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88%E5%AE%9A%E7%BE%A9-,%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AA%E3%83%AA%E3%83%B3%E3%82%AF,-%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AA%E3%83%AA%E3%83%B3%E3%82%AF
【環境構築】DockerでReactをyarnで起動して作成&起動する方法（JavaScript編）

## 背景
- [【環境構築】Reactのプロジェクト作成&起動方法について 〜npm・yarn & JavaScript・TypeScript〜](https://qiita.com/takuma-1234/items/ce8c815ae05678f5a403)で、`React`には複数のプロジェクトの起動＆作成方法があることをご紹介しました。
- この記事は、「2.1.`yarn`で`JavaScript`を使用して`React`プロジェクトを作成する方法」の解説記事になります。

## 目標
- `yarn`で`JavaScript`を使用して`React`プロジェクトを作成できるようになる。

## `yarn`で`JavaScript`を使用して`React`プロジェクトを作成する方法
- [docker-react-yarn-javascript](https://github.com/takuma-competition/docker-react-yarn-javascript)を`clone`し、起動に必要な`dockerfile`をローカルに準備します。

https://github.com/takuma-competition/docker-react-yarn-javascript

- `Dockerfile`の中身は以下のようになっており、`node`をベースイメージとして使用しています。
```dockerfile:Dockerfile
#nodeの19.4.0をベースに使用する
FROM node:19.4.0
```
- 以下のコマンドで`docker`を起動します。
```bash:docker起動コマンド
$docker-compose up -d --build
```
- `vscode`でコンテナ内部に入ります。`vscode`でコンテナ内部に入る方法は[【環境構築】Docker container内部にVS Codeで入って作業する方法](https://qiita.com/takuma-1234/items/822823ce151340945975)を参照ください。
- `vscode`でターミナルを起動し、作業用に`docker-compose.yml`でマウント時に作成された作業用のディレクトリに移動します。
```bash:作業用ディレクトリに移動
$cd ../react_yarn_javascript_workdir/
```
- `yarn`で`react`のアプリの雛形を作成します。
- `create react-app`の後ろにくる文字列が作成されるディレクトリ名になります。（ここでは、`react_yarn_javascript`というディレクトリが作成されることになります。）
```bash:reactアプリの雛形の作成
$yarn create react-app react_yarn_javascript
```
- 作成されたディレクトリに移動します。
```bash:作成されたディレクトリに移動
$cd react_yarn_javascript/
```
- `react`を起動します。
```bash:react_start
$yarn start
```
- 起動が成功すればご自身のPCで設定されているデフォルトのブラウザで`react`が起動されます。

## 参考資料
https://docs.docker.jp/v1.12/compose/reference/overview.html

https://qiita.com/keitean/items/d83254090405aa714b15

https://qiita.com/RyosukeSomeya/items/974d4308c194a804162a

https://create-react-app.dev/docs/getting-started/#yarn

## 個人ブログ
https://takuma-tech.com/2023/07/13/592/
[AWS Q&A 365][ECR]AWSのよくある問題の毎日5選 #94

# Q1: Amazon ECRとは何ですか？
A1: Amazon Elastic Container Registry（Amazon ECR）は、AWSが提供するマネージドコンテナイメージレジストリサービスです。ユーザーはこれを使用して、安全にコンテナイメージをストア、管理、デプロイすることができます。また、AWS IAMを用いてリソースベースの権限を持つプライベートリポジトリをサポートします。

# Q2: Amazon ECRのコンポーネントは何ですか？
A2: Amazon ECRのコンポーネントには、レジストリ、認証トークン、リポジトリ、リポジトリポリシー、イメージが含まれます。レジストリは、各AWSアカウントに提供されるプライベートレジストリです。認証トークンはレジストリへの認証に必要です。リポジトリはDockerイメージ、OCIイメージ、およびOCI互換アーティファクトをストアするために使用されます。リポジトリポリシーはリポジトリへのアクセスを制御します。イメージはリポジトリにプッシュおよびプルされます。

# Q3: Amazon ECRはどのような機能を提供しますか？
A3: Amazon ECRは、ライフサイクルポリシー、イメージスキャン、クロスリージョンおよびクロスアカウントレプリケーション、そしてプルスルーキャッシュルールなどの機能を提供します。ライフサイクルポリシーはイメージのライフサイクルを管理し、イメージスキャンは脆弱性を特定し、レプリケーションはリージョンおよびアカウント間でのイメージ利用可能性を実現し、プルスルーキャッシュルールはリモートの公開レジストリでのリポジトリのキャッシュを可能にします。

# Q4: Amazon ECRを始めるにはどうすればいいですか？
A4: Amazon ECRを始めるには、まずAWSコマンドラインインターフェイス（CLI）とDockerをセットアップする必要があります。[ドキュメント](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)は、Amazon ECRのセットアップおよびAWS CLIを使用したAmazon ECRの使用方法についての手順を提供します。

# Q5: Amazon ECRの価格はどのように決定されますか？
A5: Amazon ECRの価格は、リポジトリに格納されたデータの量と、イメージのプッシュおよびプルに伴うデータ転送に基づいています。ユーザーはそれぞれの使用量に応じて課金されます。詳細な価格情報は、Amazon ECRの価格設定ドキュメントで確認することができます。
[AWS Q&A 365][ECR]Daily Five Common Questions #94

# Q1: What is Amazon ECR? 
A1: Amazon Elastic Container Registry (Amazon ECR) is a managed container image registry service provided by AWS. It allows users to securely store, manage, and deploy container images. It supports private repositories with resource-based permissions using AWS IAM. 

# Q2: What are the components of Amazon ECR? 
A2: The components of Amazon ECR include the registry, authorization token, repository, repository policy, and image. The registry is a private registry provided to each AWS account. An authorization token is required for authentication to the registry. Repositories are used to store Docker images, OCI images, and OCI compatible artifacts. Repository policies control access to the repositories. Images can be pushed and pulled from the repositories. 

# Q3: What features does Amazon ECR provide? 
A3: Amazon ECR provides features such as lifecycle policies, image scanning, cross-Region and cross-account replication, and pull through cache rules. Lifecycle policies help manage the lifecycle of images, image scanning helps identify vulnerabilities, replication allows for image availability across Regions and accounts, and pull through cache rules enable caching of repositories in remote public registries. 

# Q4: How can I get started with Amazon ECR? 
A4: To get started with Amazon ECR, you need to set up the AWS Command Line Interface (CLI) and Docker. The [document](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html) provides instructions on setting up with Amazon ECR and using Amazon ECR with the AWS CLI. 

# Q5: How is pricing determined for Amazon ECR? 
A5: Pricing for Amazon ECR is based on the amount of data stored in repositories and data transfer for image pushes and pulls. Users are charged accordingly for their usage. Detailed pricing information can be found in the Amazon ECR pricing documentation.
flaskで簡単にページネーションを作成した

# flask学習中
簡単にページネーション付けたいなー
![hirameki_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228723/a8cc7fe8-bb38-ba42-e905-3e7505e549c2.png)

## 最終目標
一覧画面のリストにページネーションを付ける

## まずは設定
~~~md:python3
pip3 install Flask-Paginate
~~~

~~~md:cafe.py
from flask_paginate import Pagination, get_page_parameter
~~~
## 早速書いていきます
### パスを準備しておきます
~~~md:cafe.py
@app.route('/cafe/list')
def list():
~~~

#### メソッド内です

~~~md:cafe.py
@app.route('/setting/cafe/menu/list')
def list():
------------ここから追記-------------
  # 一覧のレコードを取得
  menus = Menu.query.all()
  # ページネーション
  ## 現在のページ番号を取得
  page = int(request.args.get(get_page_parameter(), 1))
  ## ページごとの表示件数
  per_page = 10
  ## ページネーションオブジェクトを作成
  pagination = Pagination(page=page, per_page=per_page, total=len(menus))
  # 表示するデータを取得
  start = (page - 1) * per_page
  end = start + per_page
  displayed_menu = menus[start:end]
  # テンプレートを表示
  return render_template('/cafe/list.html', menus=displayed_menu, pagination=pagination)
~~~
#### html
どこでもページネーションを表示したい場所にしたのコードを設置します
~~~md:.html
  {{ pagination.links }}
~~~
こうなります
![スクリーンショット 2023-07-13 23.10.44.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228723/f8bf1a9c-4a5c-5290-a33f-781776ea9051.jpeg)




#### css
見た目がちょっとダサいので好みの形に変えてあげましょう

~~~md:フォーム
.content nav {
  background-color: #fff;
  padding: 10px;
  z-index: 9999;
}

.page-item.active .page-link {
  color: #212529;
  border-color: #f2f2f2;
  background-color: #f2f2f2;
}

.pagination {
  list-style-type: none;
  display: flex;
  align-items: center;
  margin: 0 0 3px 0;
}

.pagination li {
  margin: 0 5px;
}

.pagination li.active a {
  font-weight: bold;
}

.pagination li a {
  text-decoration: none;
  color: #000;
  padding: 5px 10px;
  border: 1px solid #ccc;
  border-radius: 5px;
}

.pagination li a:hover {
  background-color: #f5f5f5;
~~~
こうなりました![スクリーンショット 2023-07-13 23.11.02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1228723/d41d147c-af13-0a0c-740e-9034c5e1f230.jpeg)


## その他
余談ですが、flaskって記事少ないですよねー。そんなに困らないですが困ります（笑）
Laravel Pint ファイルが保存されたら自動でPintを実行する

## プロジェクトディレクトリの構成

https://github.com/ucan-lab/docker-laravel

```
.
├── compose.yml
├── infra
│  └── docker
│     ├── mysql
│     ├── nginx
│     └── php
├── README.md
└── src # Laravel project root dir
```

## Laravel Pint

https://readouble.com/laravel/10.x/ja/pint.html

## Laravel Pint のルール設定

Pintのおすすめルールはこちらの記事でご紹介しています。

https://qiita.com/ucan-lab/items/8807a092eb6d87ddfe34

## PhpStorm

`Settings...` > `Tools` > `File Watchers`

![ScreenShot 2023-07-13 21.43.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/a08db2b0-6086-1310-5b5a-85f955b6a56e.png)

`+` > `Choose Template` で `Custom` を選択

![ScreenShot 2023-07-13 21.44.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/1b9eb9a7-5bea-0d2a-58ca-6d6387d60eec.png)

### ローカルで動かす

![ScreenShot 2023-07-14 11.02.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/efe4520a-a8cb-0671-7412-3353a9dded01.png)

```
Name: Pint
File type: PHP
Scope: Project files
Program: $ProjectFileDir$/src/vendor/bin/pint
Arguments: $FileRelativePath$ --config $ProjectFileDir$/src/pint.json
Output paths to refresh: $FileRelativePath$
Working Directory: $ProjectFileDir$
Environment variables:
Advanced Options:
  ✅ Auto-save edited files to trigger the watcher
  ✅ Trigger the watcher on external changes
  Trigger the watcher regardless of syntax errors
  Create output file from stdout
```

プロジェクトディレクトリの直下にLaravelを配置してる場合は `Program` の `src` をディレクトリ部分を削除してもらえれば動くと思います。

### Dockerで動かす

![ScreenShot 2023-07-13 22.49.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/e972ca70-16da-9ec9-ae6e-df26c42bae9c.png)

```
Name: Pint
File type: PHP
Scope: Project files
Program: docker
Arguments: compose exec app ./vendor/bin/pint
Output paths to refresh:
Working Directory:
Environment variables:
Advanced Options:
  ✅ Auto-save edited files to trigger the watcher
  ✅ Trigger the watcher on external changes
  Trigger the watcher regardless of syntax errors
  Create output file from stdout
```

Docker で動かす場合の例です。
`src` ディレクトリを切ってしまったため、ライブテンプレート変数を使ってもうまく変更したファイルパスだけ指定するということができませんでした。

もし良い方法をご存知の方がいたら教えて下さい🙏
ただ、Pintはローカルで動かした方が速いのでパフォーマンス的にDockerで動かさなくても良いかな。

### 参考

- https://pleiades.io/help/phpstorm/using-file-watchers.html
- https://gilbitron.me/blog/running-laravel-pint-in-phpstorm

## VSCode

### Laravel Pint 拡張機能

https://marketplace.visualstudio.com/items?itemName=open-southeners.laravel-pint

### Pint 手動実行

`Command` + `Shift` + `P` でコマンドパレットを開く。

- `Format active workspace files using Laravel Pint`
- `Format document using Laravel Pint`

上記のコマンドを選択するとPintが適用される。

### Pint 自動実行

`.vscode/settings.json` ファイルを配置するとファイル保存時にPintが適用される。

```json:.vscode/settings.json
{
  "editor.formatOnSave": true,
  "laravel-pint.enable": true,
  "laravel-pint.enableDebugLogs": true,
  "laravel-pint.configPath": "src/pint.json",
  "[php]": {
    "editor.defaultFormatter": "open-southeners.laravel-pint"
  }
}
```

### 参考

- https://code.visualstudio.com/docs/editor/tasks
- https://codebysamgan.com/how-to-add-laravel-pint-to-vs-code-formatter
- https://github.com/open-southeners/vscode-laravel-pint/issues/21
ReactとCSSでスロットゲームを作ってみた

最近暑いですね！
気分転換を兼ねて、ReactとCSSでスロットゲームを作ったので、共有します！

今回の[Gitはこちら](https://github.com/gYama/my_jungle_55)です！

ChatGPTを活用したので、記事は感想がメインです。

## なぜ作ったのか
[弊社](https://diamond-f.co.jp)では、今夏、納涼会を開催することになりました！
納涼会のLT大会で登壇するので、急遽、ネタを作ることに。

また、最近の業務でReactを使うので、ReactとCSSでスロットゲームを作ることにしました。

時間短縮のため、ChatGPT（有料版）も活用してます。
（※完成後、ちゃんとロジックを理解してます。）

## 要件
以下の要件を伝えてます。
・リールは3行*3列
・絵柄は3,7,🍒,🍇,🐯,🔔,🤡
・各リールで3秒間、ランダムに回転させて、絵柄が揃ったらボーナスを獲得
・横、斜めのどちらかで揃えばOK
・獲得したボーナスは保持する
・Reactのみで作成
・レトロ感のあるデザイン

## 最初に感じた壁
リール配列って、意外と難しいです。
複数の絵柄が同時に揃わないように、考えて配置しなければなりません。

## 解決策
実績がある配列を使ってみよう！
ということになり、マイジャグラーのリール配列を拝借しました！

おそらく計算しつくされた配列になっているはずなので、間違いありません！

サイトにはリール画像しかなかったので、確認しながら、絵文字と数字の配列にしました。
```javascript
const leftReel = ['🔔', '7', '🐯', '🍇', '🐯', '🍇', '3', '🍒', '🍇', '🐯', '🍇', '7', '🤡', '🍇', '🐯', '🍇', '🍒', '3', '🍇', '🐯', '🍇'];
const centerReel = ['🐯', '7', '🍇', '🍒', '🤡', '🐯', '3', '🍇', '🍒', '🐯', '🔔', '🍇', '🍒', '🐯', '3', '🍇', '🍒', '🐯', '🔔', '🍇', '🍒'];
const rightReel = ['🍇', '7', '3', '🔔', '🐯', '🍇', '🤡', '🔔', '🐯', '🍇', '🤡', '🔔', '🐯', '🍇', '🤡', '🔔', '🐯', '🍇', '🤡', '🔔', '🐯'];
```
## ゲームの名前決め
マイジャグラーのリール配列を使ったので、敬意を込めて
`My Jungle 55（マイジャングル ゴーゴー）`
にしました！
（パクリではなく、敬意を込めてます！）

さらに、要件に以下を追加しました。
`・ボーナスが揃ったら、55ランプを点灯`

いいですね！
せっかく作るなら、楽しく作りたいものです:smile:
昔よく打ってたので、イメージが湧きます！

## 実際に作ってみて、どうだったか
### 思ったより大変
ChatGPT、すごく便利です。
便利なんですが、一発で完成形に持っていくのは、至難の業。
何度もやりとりして、ようやく満足のいくものになります。

### 伝え方って大事
これはChatGPTに限らず、人間同士、特にオンラインで感じるのですが、伝え方というのは、非常に大事です。
ChatGPTは基本的にテキストで受け取るので、簡潔に、かつ明確に伝えなければ、違った解釈になることがあります。

## 実際に作ったもの
こちらです！
このCSSもChatGPTに依頼したのですが、シンプルでいい感じだと思います。
<img width="90%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/8273a1a4-b46c-a6b4-3183-9b73ef914049.png">

ちゃんとランダムに止まってくれます
<img width="90%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/3e7c2562-aea2-8eba-5af7-5f59e3d24393.png">

### 気になる55ランプ
3または7が揃った際、ちゃんと55ランプが点灯しました！
<img width="90%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407770/8ecf9b4e-6148-ca98-57ed-560f45a738b5.png">

実際にはなかなか揃わないので、テストモードでは、3回転ごとに7が揃うお祭り仕様にしてます🏮

キャプチャが取れなかったので載せていないですが、絵柄が揃ったら、右下に獲得枚数が1秒間表示されます。（+500 など）

ボーナスや子役の確率は入ってないので、次は設定を入れてみようと思います！

## 今回のソース
冒頭でも共有しておりますが、[Gitはこちら](https://github.com/gYama/my_jungle_55)です。3時間しかなかったので、全然整理できてないです🙇‍♂

それにしても、メーカーのリール配列は凄いです、、感謝を込めて打ちましょう。

## 最後に
今回はChatGPTを活用し、自分が興味があるものを作ってみました。
単に作るだけでなく、学習用途で利用することにより、より効率的に学習していけるのではないかと思います。

AIの発展はまだまだこれからだと思うので、今後が楽しみです！

うまく活用して、飛躍的に成長しましょう！
モダンアクティビティを使ってみた(Excel編Part8～シート複製とシート名を変えたい～)

## はじめに
①本記事は、2023年7月開催の「UiPathブログ 発信チャレンジサマー」の13日目のブログです。
ブログの詳細、参加方法については以下のブログを参照ください。

https://note.com/shumpei_w/n/nd082bdf28853

②このブログ情報は、2023/7時点の情報です。
③UiPathはCommunity Edition、Versionは2023.6.1を使用しています。

## 前回までのあらすじ
モダンアクティビティのシリーズを色々書いています。前回はシートの挿入、削除を行ってみました。

https://qiita.com/saosao885/items/2156cef91ce6e32b2c6c

## シートを複製アクティビティ
「シートを複製」アクティビティは、指定したシートを複製できるアクティビティです。
(そのまんまやんとか、言わないこと)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/8f1337c5-96c4-52da-55d2-53bae3a01ba1.png)

## シート名を変更アクティビティ
「シート名を変更」アクティビティは、対象のシート名を新しいシート名に変更することのできるアクティビティです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/82d13fe8-731d-73d5-e855-b3c67b730bc6.png)


## やってみよう
あるExcelがあります。
今回はSheet3を使っていきます。
これから2つやってみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/24c63c8a-f745-c6b3-1265-03139ad52b7e.png)
①ExcelのSheet3を複製して名前を"UiPath"にしてみよう。
以下のように設定しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/5da58720-ef88-1edd-3b2a-e227751fdf86.png)
新しいシート名：新しいシート名に設定できます。
複製するシート：複製対象のシート

②シート名を"UiPath"→"UiPath_Automation"に変更してみよう。
以下のように設定しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/d0e909c8-94f5-a7f0-1146-3f66620c61e4.png)
変更するシート：変更対象のシートを設定
新しいシート名：新しく設定するシート名

## 実行結果
①Excelのシートを複製して名前を"UiPath"にしてみよう。
見てみると...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/761b2abf-95d6-0f34-161a-f540db825c9b.png)
お、シートを複製していますね！
では、もうひとつはどうでしょう。
②シート名を"UiPath"→"UiPath_Automation"に変更してみよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/e37dadfb-ec11-5341-c52b-f27954d43918.png)
シート名が変わっていました！

## まとめ
シートの複製、シート名の変更は使う方も多いと思うのでぜひ使ってみましょう。
最後までお読みいただきありがとうございました。
ゼロETLから学ぶ今後の展望について


re:Inventで発表された ゼロETLについて
---

文章をツラツラと書くのも読みづらいので
流行りの生成系AIのチャット形式でお届けします。
ぜひ最後までお付き合いいただけますと幸いです！


そもそもETLって？
---

　ETL＝Extract/Transform/Loadの略
　機械学習においてはデータ管理が重要になってきますが
　１．データの抽出(Extract)
　２．データの変換(Transform)
　３．データの取り込み(Load)
　の英語の頭文字をとってETLと略されているよ。

ETLってどんな機能？
---
文字通り、機械学習において重要となる
データの抽出、変換、取り込みを行うパイプラインのような機能だよ。

文字だとわかりずらいからイメージを図で教えて？
---
こんな感じのイメージだよ。
![画像１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2840619/1f2261d3-4d6a-d6f9-534d-ea66b0610828.jpeg)

なんとなくわかったけどゼロETLって何なの？
---
ニアリアルタイムでのデータ連携をシンプルに実現するよ。
・複雑化しやすいデータベースとデータウェアハウス(DWH)の間のETLを排除しているよ
・Amazon Auroraで発生した大量のトランザクションデータを、
　ニアリアルタイムで分析し機械学習に利用できるよ
・複数のAuroraクラスタのデータをRedShiftに集約して分析もできちゃうんだぜ！

うーん、やっぱり文章だとわかりづらいからイメージ図で教えて！
---
はいはい。イメージはこんな感じでETLが存在しないよ。
![画像２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2840619/366866f3-8355-be91-91f8-2615d101a124.jpeg)

へぇ～ダイレクトで分析できるんだね！
ところで、このサービスは僕が普段使う東京リージョンでも利用できるの？
---
そうなんだよ！実は2023年6月28日に発表されたばかり(執筆時点は2023/7/13)なんだけど、東京リージョンでも、Amazon Aurora MySQL8.0と互換性のあるバージョンで利用できるようになったんだ！

https://aws.amazon.com/jp/about-aws/whats-new/2023/06/amazon-aurora-mysql-zero-etl-integration-redshift-public-preview/

おお！トレンドじゃん。このゼロETLを利用するメリットを教えて？
---
データ分析にはゼロETL以外にも「バッチ方式」での連携もあるんだけど、データの鮮度が重要視される分析においては
ゼロETLのようなニアリアルタイムでの分析が重要になってくるよ！

なるほど。なるほど。どんな活用事例があるんだろう？
---
ゼロETLにより処理時間が短縮され、よりニアリアルタイムでの分析ができるようになることはわかったよね？
それらの活用事例(メリットを活かせる事例)としては以下のようなものがあるんじゃないかな？

・例１）金融業界
---
　→例えば株の値動きを分析してトレーダーに通知するサービスなんて流行りそうじゃない？

・例２）ヘルスケア業界
---
　→医療機関におけるデータ分析など
　例えば急病人が救急車で搬送されている間
　ニアリアルタイムでの分析結果を搬送先の病院へ連携することや、
　搬送先の病院の受入状況を可視化することで救える命が増えるかもしれないよ！

なんだかすごい可能性を秘めているんだね！ChatGPT先生、今日も色々教えてくれてありがとう！
---
はい。AWSさんではゼロETLの展望に向けて以下の新機能をリリースしているみたいなので、こちらも併せてご確認くださいね！

https://aws.amazon.com/jp/about-aws/whats-new/2022/12/aws-announces-two-new-capabilities-to-move-toward-a-zero-etl-future-on-aws/


コメントやいいねをいただけると励みになりますのでお願いいたします。
KAGOYA CLOUD VPS に Docker で Bitnami/Redmine5.0.5 入れてみた

Redmineをインターネット上で使おうと思ったときに、AWSのEC2に以前無料枠で利用したこともあったが、有料だとちょっと高いかも。そこで、KAGOYA CLOUD VPS でDockerを利用したRedmineサーバを立ててみることにした。KAGOYA ではアプリケーションセットアップの中にRedmine もあるが、2023年7月13日時点でUbuntu22.04では対応せず、Ubuntu20.04にRedmine4.1.1とバージョンがやや古いため、Ubuntu22.04LTSにアプリケーションセットアップはDockerを選択して、最新のStable版Redmine5.0.5 をインストールすることにする。

スペック（CPU/メモリ）：２コア/２ＧＢ
費用：月額６６０円
ＯＳ：Ubuntu22.04
アプリケーションセットアップ：Docker

1. KAGOYAにアカウントを作成。人による確認が入るので、１～２日かかる。
2. 仕様を決めて(今回は上記)インスタンスを作成。
3. しばらくするとインスタンスが起動するので、VPSコントロールパネルから作成したインスタンス名をクリック
4. [コンソール]->[コンソールを起動]をクリックし、しばらく待つ
※コンソールへのログインは、root/インスタンス作成時に設定した「コンソールログインパスワード」を使用）
5. https://hub.docker.com/r/bitnami/redmine を参考に以下を実行。
 ```
apt update
apt install docker-compose
mkdir /docker
mkdir /docker/redmine
cd /docker/redmine
curl -sSL https://raw.githubusercontent.com/bitnami/containers/main/bitnami/redmine/docker-compose.yml > docker-compose.yml
docker-compose up -d
```
これでRedmineのサーバが立ち上がるので、VPSコントロールパネルに記載のIPアドレスをブラウザで表示させる。
Redmineのログイン画面が表示される。[先ほどのページ](https://hub.docker.com/r/bitnami/redmine)に初期ＩＤ(user)、パスワード(bitnami1)が書いてあるので、早速ログインしてＩＤ、パスワードは変更しておく。

速くはないが、個人的には問題ないレベルの動作をするようになりました。

##### 再起動
インスタンスを再起動した際は、Dockerも再起動する
```
cd /docker/redmine
docker-compose up -d
```
【Next.js】備忘録：Error: Objects are not valid as a React child (found: [object Promise])〜でハマった時と解決策

Next.jsでブログサイトを作成している際、`getStaticProps`を実行したところ、以下のようなエラーが表示されました。

```
Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.
```

このエラーの解決に時間がかかったため、このエラーが起きた時の解決策をまとめました。

<br>
<br>

# ◆ エラーの意味

>Nextjs エラー: オブジェクトは React の子として有効ではありません (見つかった: [オブジェクト Promise])。子のコレクションをレンダリングする場合は、代わりに配列を使用してください

Google翻訳ですが上記のような意味になります。

正直何のこと言っているのか意味がわかりません...。


取得した結果を見たけど取得結果も配列じゃないし。


<br>
<br>

# ◆ このエラーが出たときに疑うことは


どの現象でこのエラーが出るのか全パターンを行ったわけではないのですが、このエラーが出たときは、

<font color="red">**基本的にソースの書き方がどこかで間違っている**</font>

ってことでいいのではないかと思います。

いわゆる初歩的な単純ミスです。


<br>
<br>

# ◆エラーの原因① ~不要なasync~

不要なasyncがあるとこのようなエラーが出るそうです。
自分の原因はこれではなかったのですが、同様のエラーが出ている方がQ&Aを出されていたため、参考に。

https://qiita.com/HANAMU/questions/491fa389bc1cd2292f1d

<br>
<br>

# ◆エラーの原因② ~export defaultの間違い~

自分の場合の原因はこれでした。
pages配下で表示するページコンポーネントをdefaultにするのではなく、`getStaticProps`の方をexport defaultしていたことが間違いでした。

（getStaticPropsどうこうではなく、そもそもページが開けないソースになってました..。）

```react
import { client } from "../../lib/api";
import { getPostBySlug } from "../../lib/api";

type props = {
  title: string;
  publish: string;
  content: string;
  eyecatch: any;
  categories: any;
};

export const TestPage = ({
  title,
  publish,
  content,
  eyecatch,
  categories,
}: props) => {
  return (
    <>
      <h1>{title}</h1>
      {content}
    </>
  );
};


export default async function getStaticProps() {
  const slug = "test";

  const post = await getPostBySlug(slug);

  return {
    props: {
      title: post.title,
      publish: post.publishDate,
      content: post.content,
      eyectch: post.eyecatch,
      categories: post.categories,
    },
  };
}
```

getStaticPropsを`export`にし、ページコンポーネントを`export default`に変えたら普通に解決しました。

<br>
<br>

エラーに惑わされて本質は全然違うことよくありますよね...。
これで全てが解決するかはわかりませんが、宜しければ参考にしてください！！
npm install パッケージ -g の「-g」について調べた

# 何？何に使うの？
「-g」オプションは、「パッケージをグローバルにインストールするためのオプション」です。
グローバルにインストールすることで、コマンドを省略して実行できます。
例えばtypescriptをコンパイルするコマンド「tsc」ですが、npm installしただけでは使用することはできません。
```
> npm install typescript
> tsc
tsc : 用語 'tsc' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前が正しく記述されていることを確
認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してください。
発生場所 行:1 文字:1
+ tsc
+ ~~~
    + CategoryInfo          : ObjectNotFound: (tsc:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
```
実行するには以下のように「npx」を使用しなければなりません。
```
> tsc .\sample.ts　　    --- NG
> npx tsc .\sample.ts　　--- OK！
```
しかし「-g」を指定することで、「tsc」だけで実行することができるようになります。
```powershell:グローバルインストール
> npm install typescript -g
```
```
> tsc .\sample.ts      --- OK!
```

# インストール先の違い
-g オプションを指定せずにinstallした場合、パッケージは作業ディレクトリにインストールされる。
```powershell:powershell
npm install パッケージ
```
```
- 作業ディレクトリ
  - node_modules
    - .bin
    - ★ここに追加される★
  - package.json
  - package-lock.json
```

-g は通常FALSEに設定されており、指定することで有効にすることができます。
```powershell:powershell
npm install パッケージ -g
または
npm install パッケージ --global
```
「-g」をした場合、作業ディレクトリのnode_modulesには追加されない。
その代わり「%AppData%/npm」に追加される。（Windowsの場合）
```powershell:powhershell
> ls $env:AppData

～略～
d-----        2023/07/13     21:55                npm
～略～
```

# 補足： npm install オプション
npm install にはいくつかのオプションが用意されています。
npm help install を実行することで一覧を表示（ブラウザが開く）することができます。
```
save
save-exact
global
install-strategy
legacy-bundling
global-style
omit
strict-peer-deps
package-lock
foreground-scripts
ignore-scripts
audit
bin-links
fund
dry-run
workspace
workspaces
include-workspace-root
install-links
```
【Python】CSVを読み込むと文字列の中に\ufeffが入ってしまう場合の原因と解決方法

# 概要
Djangoで、ユーザーがアップロードしたCSVファイルのヘッダー名が指定のヘッダー名と一致している場合のみアップロードを成功させるという認証方法を実装していました。しかし、ヘッダー名を一致させても頭にBOMの文字列が入っているのが原因で、失敗してしまいました。本記事ではその原因と解決方法を記載します。


# エラーが発生したコードと原因


```py
def upload_file(request):
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            csvfile = request.FILES['file']
            decoded_file = csvfile.read().decode('utf-8').splitlines()
            reader = csv.reader(decoded_file)
            header = next(reader)

            if header == ['hoge', 'foo']:
            # 省略
```

上記のコードでCSVをアップロードするとなぜか`if`分のところで引っかかってしまいます。
おかしいなぁ、と思って`header`に何が入っているかデバッグしてみました。
すると、以下のように出力されました。

```
['\ufeffhoge', 'foo']
```
 
ん、`\ufeff`ってなんだ？CSV開いても特に頭には何もつけていません...
調べてみると、この`\ufeff`っていうのは、バイト順マーク、通称BOM（Byte Order Mark）と呼ばれる特殊な文字列とのこと。テキストデータの先頭に配置され、Unicodeエンコーディングを示すために使用されます。テキストの始まりをプログラムに伝える目印みたいなものです。

`\ufeff`は、ユニコード文字`U+FEFF`を表し、不可視文字とも呼ばれます。
ということで、解決策はこのBOMを除去することということがわかりました。

BOMについては、[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E9%A0%86%E3%83%9E%E3%83%BC%E3%82%AF#cite_note-1)にも以下のように記載されています。

> プログラムがテキストデータを読み込む時、その先頭の数バイトからそのデータがUnicodeで表現されていること、また符号化形式（エンコーディング）としてどれを使用しているかを判別できるようにしたものである

# 解決方法
BOMを除去するためには、ファイルを開く際に`utf-8-sig`のエンコーディングを使用すればOKとのこと。このエンコーディングであれば、BOMを自動的に検出して削除できます。

```py
decoded_file = csvfile.read().decode('utf-8-sig').splitlines() 
```

上記のように修正したら、BOMが除去され、ヘッダー名も正しく一致されました。
よかったよかった。

# 参考
- [\ufeffって？？？](https://qiita.com/msk02/items/c3a1c4a1e1ef94c37228)
- [バイト順マーク - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E9%A0%86%E3%83%9E%E3%83%BC%E3%82%AF#cite_note-1)
textlint の実行結果を Codecov に送信する


## はじめに

Qiita CLI が beta release されました。

https://blog.qiita.com/qiita-cli-beta-release/

Beta release 後に textlint の結果を Codecov に記録するように設定しました。
設定に必要な情報や設定を簡単になりますが記載します。

## 実行環境

今回背屮した repository の version は記載の通りです。
また、 textlint は設定済みの環境を想定しています。

```sh
> node -v
v18.14.2
> yarn -v
1.22.19
```

この記事では `yarn` を使って設定します。
`npm` を使っている方は読み替えてください。

## 使用する パッケージ や action

### npm packages

https://www.npmjs.com/package/codecov.io

https://www.npmjs.com/package/textlint-formatter-codecov

### actions

https://github.com/codecov/codecov-action

## 必要な package を install する

先ほど記載した package を install します。

```sh
yarn add -D codecov.io textlint-formatter-codecov
```

必要に応じて `package.json` の `scripts` に textlint の実行条件などを記載します。
私は以下のように記載しました。

今回は `tnp/` directory いかに JSON ファイルを出力するように設定しています。
`mkdir tmp` 等で事前に `tmp` directory を作成しておいてください。

```json:package.json
{
  "scripts": {
    "textlint:codecov": "textlint --config .textlintrc.json -f codecov -o tmp/codecov.json *"
  }
}
```

## action を設定する

`tmp/codecov.json` に実行結果が出力されるように設定できました。
次に、 CI/CD 上で実行した textlint の結果を Codecov に通知する設定をします。

### Codecov にアクセスし Token を取得する

Codecov にログインし token を取得します

https://about.codecov.io/

Token の取得方法は以下記事を参考にしてください。

https://docs.codecov.com/docs/quick-start

Token を取得出来たら GitHub の Secret variables に定義します。

https://docs.github.com/en/actions/security-guides/encrypted-secrets

Secret variables に定義まで終わったら yml の準備をします。

### GitHub Actions の設定をする

先ほど設定した Secret variables を用いて、 textlint の結果を Codecov に送信する設定を書きます。
参考までに最低限の設定を記載します。

```yaml:.github/workflows/test.yml
name: Text

on:
  push:

permissions:
  contents: read

jobs:
  textlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          cache: 'yarn'
      - run: yarn install
      - run: yarn run textlint:codecov
      - uses: codecov/codecov-action@v3
        env:
          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
```

ここまで終わったら実際に GitHub に push して textlint と Codecov を動作させ確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55950/821a16f7-0f6a-d353-8aa5-972ce7ffc9b3.png)

https://app.codecov.io/github/mziyut/qiita-articles/commit/0bbf2d71145d48353b83926a1a3a237d92a030f2

GitHub Actions 上で実行が確認出来たら完了です。

## References

https://github.com/mziyut/qiita-articles/pull/50

https://app.codecov.io/github/mziyut/qiita-articles/pull/4

https://github.com/azu/textlint-formatter-codecov

https://github.com/codecov/codecov-action
heroku scheduler

## heroku schedulerを使い、タスクスケジュールを実行する
heroku schedulerとは
Paasサービスherokuにてデプロイしたアプリの定期的なタスクスケジュールを管理する無料のadd-onです。


## 私の取り組んでいるアプリ
初学者です。JavaEEで、フードロス対策の視点から、食料品店の売れ残り商品を値下げしたものを各店舗が公開し、消費者が閲覧する簡易なアプリを作っています。

## schedulerを使用した箇所
各商品に販売開始・終了時間を設定し、終了時刻になったら商品を終了表示にする。という部分にsqlとheroku schedulerを使用しました。

## SQL
SQLはpostgreSQLです。
	
````
		 String sql = "INSERT INTO endGoods(カラム)select
　　　　　　 カラム　from goods where end_time <= clock_timestamp()" ;
	
````
・２つのテーブルgoodsとendGoodsを用意し、指定条件時にテーブル間をデータが移動します。

・ <=clock_timestamp()　は現在時刻または現在時刻以前のものを対象とします。

##  heroku scheduler
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/842570/e8d67e61-873c-4734-71c1-8a0bdcc83e0c.png)


・scheduler の設定方法は以下を参考にしました。
　https://devcenter.heroku.com/ja/articles/scheduler

・curl　コマンドでsql実行文を記述したservletを指定します。
　curlコマンドとは、Web サイトへ http リクエストを送信してコンテンツを表示するというものだそうです。以下サイトなどを参考にしました。
　https://tech-lab.sios.jp/archives/29999

・heroku はUTCの設定なので時差を考慮します。
　herokuのアプリのTZをbashで確認し、JSTに変更するには、、以下のサイトを参考にしました。
　https://qiita.com/Horie1024/items/85688099707610f70fa6
Bootstrap　jsDelivr 経由の CDN

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/6e212919-c8fb-e2b0-cd1f-a42ed5bb9cdf.png)
　jsDelivrは、ファイルの格納をせずに使用できる仕組みを持っているネットワークとなります。
つまり、jsDelivrを使用するためのコードをアプリ内に記述するだけでCSS, JSの機能を使用することが可能になります。
RubyでAtCoder ABC233(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC233のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - 10yen Stamp
https://atcoder.jp/contests/abc233/tasks/abc233_a
```ruby:a-233.rb
x, y = gets.split.map(&:to_i)
y -= x
if y < 0
  puts 0
  exit
end

ans = y / 10
puts y % 10 == 0 ? ans : ans + 1
```

# B - A Reverse
https://atcoder.jp/contests/abc233/tasks/abc233_b
```ruby:b-233.rb
l, r = gets.split.map(&:to_i)
l -= 1
r -= 1
s = gets.chomp
s[l..r] = s[l..r].chars.reverse.join
puts s
```

# C - Product
https://atcoder.jp/contests/abc233/tasks/abc233_c
```ruby:c-233.rb
n, x  = gets.split.map(&:to_i)
array = Array.new(n){ gets.split.map(&:to_i)[1..] }
puts [1].product(*array).count{ _1.inject(:*) == x }
```
## 解説
（他の方の提出結果を参考にしました）

`product`メソッドを使って各配列から要素を１つ取得することができます。なお、`*array`の形にすることで配列を展開しています。そして、`inject`メソッドを使って各組み合わせにおける総積を求め、`count`メソッドでその値が`X`と一致しているものの数を求めています。

# 参考
https://docs.ruby-lang.org/ja/latest/method/Array/i/product.html

https://qiita.com/koshilife/items/63ad4088adcd77b71e52

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
Kubernetes概要

こんにちは。

業務でEKSを使用することがが決定したので、まずは基礎からと思いまして、Kubernetesについて簡単にまとめていきたいと思います。

https://www.youtube.com/watch?v=iAW6gfbvPMQ

こちらの動画を見ながら学習したことをまとめています。


 # Kubernetesとは
- コンテナオーケストレーションサービス
    - コンテナ単体では実現できなかったことを補う
    - スケジューリング、死活監視、ロードバランシングなどを引き受けてくれる。


# Kubernetesの構成要素
- Control Plane
    - クラスターの制御を受け持ち、スケジューリングやイベント検知などクラスタ全体に関わる管理を行う。
- Worker Node
    - アプリケーションコンテナの稼働場所。
    - コンテナランタイムが稼働し、コントロールプレーンと連携してコンテナの起動、実行などを行う。

## Cotrol Planeの各要素について
- API Server
    - KubernetesへのAPIリクエスト(CLIなど)をRESTで受け付けるフロントエンドサーバー
    - オブジェクトのCRUDやユーザーなどおよびサービスアカウントの認証認可、リクエストの制御を行うAdmssion Controlなどがある。

- Scheduler
    - Podを最適なNodeに配置する
- Cloud Control manager
    - クラウドプロバイバーの機能と連携してロードバランサやディスクボリュームなどのリソースを管理する
- Contorl Manager
    - Kubernetesリソースの状態を管理して、要求される各リソースの状態を維持する
- etcd
    - Kubernetesクラスタに登録される全ての情報を保存するデータストア(キーバリューで保存)

AWS(EKS)、GCP(GKE)、Azure(AKS)などのサービスはこれら


## Worker Nodeの各要素について
- kubelet
    - NodeへのPodへのスケジューリングを監視し、コンテナランタイムを利用してPodの生成、更新、破棄などを行う
- コンテナランタイム
    - kubeletによるコンテナイメージの取得とコンテナの作成、更新、破棄などを実行。
- kube-proxy
    - 各Nodeで動作する、Serviceオブジェクトが持つ仮想的なClusterIPやNodePort宛のトラフィックをPodへ正常に転送するネットワークプロキシの役割を担う。

## Pod
- 1つまたは複数のコンテナをデプロイする最小単位
- Pod内のコンテナは同じホスト名とIPアドレスを持つ
- Pod内のコンテナは同じポート番号を持つことはできない
- Pod内のコンテナはローカルホスト通信
- Pod内のコンテナは同じNode上で稼働、Nodeをまたぐことはできない

## ReplicaSet & Deployment
- ReplicaSetは、Podのレプリカを作成して、マニフェストファイルで定義されたレプリカ数(replica)を保証し、定義された数のPodを常に起動させる仕組み
- Deploymentは、ReplicaSetの作成、更新、履歴管理を行う。

## Service
- クラスタ内外からのリクエストをPodにアクセスする為のルーティングやDNS機能を提供。

## Ingress
- 外部からのHTTP(S)トラフィックを内部Serviceにルーティングし、レイヤ7のロードバランシングを提供。
- パスベースルーティング、HTTPS終端、名前ベースのバーチャルホスティングも可能。 
    
## Volume
- コンテナ側からマウント可能なボリューム領域。
- 保存領域の実態をポイントする。

## PersistentVolume
- 永続ボリュームと連携して、Kubernetesクラスタにボリュームを登録するリソース。

## PersistentVolumeClaim
- PersistentVolumeClaimは、PersistentVolumeをアサインするリソース。
- PodからPersistentVolumeを利用する場合、PodのマニフェストにPersistentVolumeClaimを定義して利用

## ConfigMap
- 環境変数、引数等の設定情報をコンテナに渡すために使用。
- Volumeとしてコンテナにマウントしてコンテナからはファイルとして認識される。

## Secret
- 機密性の高いデータを保持する上で使用するVolume。

## Namespace
- 複数のユーザー間でクラスタリソースを分割する仕組み。
- 1ユーザー毎に1個のNamespace
- Namespaceにおけるリソースの名前はNamespace内で一意である必要がありますが、Namespace間では一意である必要はない。
- Namespace毎にリソースの利用上限を設定可能


すごく簡単でしたが以上になります。

今度EKSのハンズオンなどやってみたいと思います。
初心者による初心者のためのSPA (Docker + Vue.js)

# はじめに

カメラをラズパイで制御した観測装置を使用しており、その装置に合わせたダッシュボードを作成したいと考え、忘れないようにVue.jsを使用したSPA（シングルページアプリケーション）の作成方法についてまとめてみた。




# 環境

・Raspbian GNU/Linux 11 (bullseye)
・Docker version 23.0.1
・node version 14.17.0
#### 一応ね、nodeのインストール
 ###### インストールスクリプトのダウンロード
```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
```
 ###### NVMをセッションにリロード
```
source ~/.nvm/nvm.sh
```
######  NVMでNode.jsをインストール
```
nvm install 14.17.3
```
 ##### インストールできたかNode.jsとnpmのバージョンを確認
```
node -v
npm -v
```



# 作っていきやしょー
#### Vue CLIのインストール
なんかVue CLIを使ったほうがいいらしいのでそれで。
```
npm install -g @vue/cli
```


#### プロジェクトの作成
vueってわかりやすくしたいので vue-app にする。
作ろうと思ってるパスで以下コマンド
```
vue create vue-app
```

#### Dockerfile
カレントディレクトリにある`vue-app`ディレクトリ内に`Dockerfile`を作り、以下のように記述。
```
FROM node:14.17.0-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

RUN npm run build

EXPOSE 8080

CMD ["npm", "run", "serve"]
```
・FROM ~ <- イメージの設定
・WORKDIR ~ <- 作業ディレクトリの作成
などなど

意味は適当に`Dockerfile`に関する他の記事見ればわかると思います。

#### イメージビルド
以下コマンドでDockerイメージをビルド(当然だけど`Dockerfile`あるパスでね).
```
docker build -t vue-app-image .
```
:::note warn
###### ここでgitがどうこうって言われたら、、、
まずgitディレクトリがビルドコンテキスト内にあるか確認。
もし存在していたらrmかなんかで除外してから再ビルド。

まぁ〜、「??」ってなった場合は .dockerignore ファイルを作成して以下のように記述。
```
.git
.gitignore
```
んで再ビルド。
:::

#### コンテナの実行
オプション加えるだけだけど**開発におけるビルド**と**バックグラウンドでの実行**に分けた。そこは適当に使い分けてもろて。

<details><summary>開発におけるビルド</summary>

```rb
docker run -p 8080:8080 vue-app-image
```
</details>

<details><summary>バックグラウンドでの実行</summary>

```rb
docker run -d -p 8080:8080 vue-app-image
```
</details>


***
そんなこんなで[http://localhost:8080](http://localhost:8080 "SPA")に以下のようなのが表示されてると思われる。
![スクリーンショット 2023-07-13 19.30.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092947/ebf9d215-e8d2-bc66-11ec-8f43dd27a79f.png)



# あとは自分次第()

これからはそれぞれデザイン等していこう。
常識かもしれないが`vue-app/src`ディレクトリ内にwebデザインを扱うファイルがある。


**以下主な関連ディレクトリ・ファイルとその役割**
| 主なディレクトリ・ファイル | 役割 |
| :---: | :---: |
| `src/main.js` | Vueの初期化やプラグインの設定等が行われる |
| `src/App.vue` | 全体のレイアウト等UIを整えるアプリケーションのルートコンポーネント |
| `src/components/` | コンポーネント(ヘッダーコンポーネントやフッターコンポーネントといったアプリケーションの部品)を格納するディレクトリ |
| `src/router/` | `index.js`を用いて各ページのルートパスとコンポーネントをまとめる |



# 最後に
とまあこんな感じで一応SPAを Docker + Vue.js で作成するための手順が完了！
今後はMySQLやFastAPIを使うなどいろんなことをしていくつもり()
Django私的学習備忘録 -get_context_dataメソッドは何をしているか-

# はじめに
Djangoの私的学習メモです。
ChatGPT4にて調べた内容と追加で調べた内容を見返せるように記事としてまとめました。

# 役割
Djangoのget_context_dataメソッドは、特にクラスベースのビュー(CBV)でテンプレートにデータを渡すために使われます。このメソッドは、テンプレートコンテキストと呼ばれる、テンプレートエンジンがテンプレート内の変数をレンダリングするために使用するデータの辞書を返します。

# テンプレート
get_context_dataメソッドは、通常は次のようにオーバーライドされて使用されます。
```Python:views.py
class MyView(TemplateView):
    template_name = "my_template.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)    #親クラスのメソッドを実行
        context['my_data'] = "This is my data"          #新しいデータを追加
        return context
```

- context = super().get_context_data(**kwargs)
親クラスの get_context_data メソッドを呼び出しています。この親クラスのメソッドは、テンプレートに渡す基本的なコンテキストデータを作成します。その結果は context 変数に保存されます。
- context['my_data'] = "This is my data"
contex に新しくデータを追加します。これにより、親クラスの get_context_data メソッドが提供する基本的なコンテキストデータに加えて、新しいデータをテンプレートに渡すことができます。

この例では、get_context_dataメソッドがmy_dataという新しい変数をコンテキストに追加しています。これにより、my_template.html内で{{ my_data }}とすることで、"This is my data"という文字列にアクセスできます。

# 使用場面
1. テンプレートに追加の情報を渡す必要があるとき
Djangoのクラスベースのビューでは、テンプレートに情報を渡すために get_context_data メソッドをオーバーライドします。親クラスのメソッドを呼び出すことで基本的なコンテキストが提供され、その上に新しいデータを追加することができます。

2. URLから抽出したパラメータをテンプレートに渡す必要があるとき
URLからキーワード引数を抽出してビューに渡す場合、これらの引数は get_context_data メソッドの **kwargs に含まれます。これらの引数をテンプレートに渡すには、親クラスの get_context_data メソッドを呼び出し、結果として得られるコンテキストにこれらの引数を追加します。

# まとめ
get_context_dataメソッドはテンプレートに値を渡す際に任意のデータを追加している
【Nuxt3】APIのエラーをNuxtのレスポンスに引き継ぐ方法

# 結論

`userAsyncData` のレスポンスの `error` を `createError` の引数に指定して 
`throw createError(error.value)` とすればよい。

```vue
<template>
  <h1>{{ healthcheck?.status }}</h1>
</template>

<script setup lang="ts">
interface Healthcheck {
  status: string
}
const { data: healthcheck, error, status } = await useAsyncData<Healthcheck>(
  "healthcheck",
  () => {
    return $fetch("/healthcheck", {method: "GET"})
  }
)

if (error.value) {
  console.error(error.value)
  throw createError(error.value)
}
</script>
```

こんな感じで、APIの404エラーをそのままNuxtのレスポンスに引き継ぐことができる。

![スクリーンショット 2023-07-13 213447.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92383/2e34bc81-b0b0-e24b-82b8-14a07dbca065.png)


ちなみに `createError` は下記のように任意のステータスコードとエラーメッセージを指定することもできる。

```typescript
throw createError({ statusCode: 404, statusMessage: 'Page Not Found' })
```

# 参考

https://nuxt.com/docs/api/utils/create-error
Xcode15 beta インストール方法

Xcode15Beta版のインストールに少しだけ躓いたので、記載しておきます。

Xcode15のインストールは下記リンクにアクセスします。
https://developer.apple.com/download/all/?q=Xcode

AppleID、パスワードを入力して、以下の画面に遷移します。
Platformのチェックマークを全て外した状態で、Xcode 15 beta 4 and Selected Platformsをクリックすれば、Xcodeのxipファイルがインストールができます。
**なぜか選択できるPlatformにチェックマークが入っていると、xipファイルがインストールされないです。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128814/5e375120-b327-2abb-3024-3aef382b97d5.png)

エンジニアのキャリアについて記事を描いてみたので、ぜひご覧ください。
https://qiita.com/p__kiba/items/9b0ea854f5f293d474f2
ノウハウの形式知化を実現するIT技術

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)


# ノウハウの形式知化が重要視される背景
少子高齢化となるこれからの日本にとって、働き手の数が少なくなることは承知の事実だと思います。生産年齢人口の数が激減した時、__日本の現場力を保つために、ベテラン社員の持つノウハウを形式知化することが非常に重要__ となってきています。

# ノウハウの形式知化のメリット/デメリット
### ■メリット
- ノウハウの共有が容易になる
形式化された知識や手順は、誰でもアクセスできるため、__組織全体でベストプラクティスを共有__ することができます。
- ノウハウの保存と継承が可能になる。
経験豊富な従業員が退職したり、組織が変化したりしても、ノウハウが失われる心配がありません。
- グローバル化がしやすい。
技術が属人化している場合は、グローバル展開の際に、その社員がその場に行って伝授する必要がありますが、数値や言葉で形式知化できていれば、__海外でも同品質の作業__ を行うことができます。
### ■デメリット
- 技術力が真似される。
ノウハウが数値化されているため、簡単に他企業に真似される恐れがあります。

# ノウハウの形式知化を実現するためのIT技術
### ■IoTとセンサーテクノロジー
[IoT](https://qiita.com/7_inai_/items/f2a56498b70b39befa0b)とセンサーテクノロジーは、製造現場でのデータ収集と解析を可能にする重要な要素です。センサーを装備した機械や設備から収集されたデータは、IoTネットワークを通じて収集・蓄積されます。これにより、製造プロセスや設備の稼働状況、生産ラインのパフォーマンスなどのデータが得られます。収集されたデータは、ノウハウの形式知化に役立つ情報として活用されます。例えば、__異常な動作パターンの検出や予知保全__ に活用することができます。

### ■データ分析とAI
データ分析と[AI](https://qiita.com/7_inai_/items/095f95279a7257eaa01b)は、製造業におけるノウハウの形式知化に革新をもたらします。大量のデータを分析し、パターンや洞察を抽出することで、生産プロセスや品質管理に関するノウハウを形式化することが可能です。機械学習アルゴリズムや自然言語処理技術を活用することで、製造工程の最適化や品質向上に寄与します。さらに、AIを用いた自動化や予測モデルの構築により、生産性の向上と故障予知が実現されます。`匠の技術を持つベテラン社員は、カンコツに頼っている場合も多く、自身で言語化/数値化できない値を、AIを用いることで具体化`することができます。

# 終わりに
ノウハウの形式知化は、組織の成長と競争力の向上に欠かせない要素です。IT技術の進歩により、ノウハウの形式知化は以前よりも容易になり、組織内での共有と継承が実現されています。しかしながら、技術の導入だけでなく、文化の変革や積極的なノウハウ共有の推進も重要です。ノウハウの形式知化に取り組むことで、組織は持続的な競争力を獲得し、成長を遂げることができるでしょう。

最後までお付き合いくださりありがとうございました。
Seleniumから呼ぶと便利なJS（増やし中）

Seleniumからexecute_scriptを呼び出すことで、seleniumのメソッドを使わずに、DevToolsだけで動きが確認できる。タイトルはSeleniumと書いてるが、Rubyのchrome_remoteやPythonのPyChromeDevToolsでもJSは素通しで動かせる。

その際にちょっとした便利なJSを紹介。
（徐々に増やす予定）

### 画面遷移せずにHTML（or JSONを取得したい）

```js
await fetch('/').then(res => res.text());
```
今開いてる画面のHTMLならpage_sourceメソッドでいい。ただそれだと画面レンダリングしちゃう。レスポンスBODYをそのままもらいたいならそういうJSを書けばいい。

### レスポンスヘッダーを知りたい

```js
Array.from(await fetch('/').then(res => res.headers.entries()));
```

レスポンスヘッダが配列の配列として帰ってくる。
[Watson Discovery] 助詞で引っかかった文書が検索結果として返ってくる

## 概要
Watson Discovery の Document Retrieval プロジェクトで検索を行うときに、「の」や「てにをは」などの助詞で引っかかった文書が検索結果として返ってくる場合があります。
Watson Discovery v2 の日本語処理では、助詞で引っかかった文書を検索結果から除外するストップワードがデフォルトで適用されていないため、ユーザーが明示的にストップワードとして設定する必要があります。

## 例

今回は、以下のサンプル文書を登録しています。
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/83b83cf6-a59d-f5e9-c1a0-ff6d4039f409.png)

この状態で「振込の限度額」というキーワードで検索をしてみます。すると、「の」というキーワードで検索に引っかかってしまっている文書（「振込」と「限度額」とは無関係な文書）が検索結果として返ってきていることがわかります。

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/1ea60a39-7c52-b943-8f77-e6f77d7facda.png)

## 設定手順

### 1. ストップワード・リストを用意する

下記リンク先から「custom_stopwords_ja.json」をダウンロードします。
「custom_stopwords_ja.json」は、「の」「てにをは」「〜において」「〜による」などの単体では意味を持たない日本語をまとめてストップワードとして登録するためのJSONファイルです。

https://github.com/watson-developer-cloud/doc-tutorial-downloads/blob/master/discovery-data/custom_stopwords_ja.json

### 2. ストップワード・リストをコレクションに適用する

画面右側の「Improvement tools」から「Stopwords」をクリックします。
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/efd106a2-0116-c2c7-6b5a-ccedc44faaa7.png)

「Upload stopwords」をクリックし、ダウンロードしてきた「custom_stopwords_ja.json」をアップロードします。
![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/941d85a1-8f06-cecc-4fea-c8f7e7cef78e.png)

「Stopwords added」が表示されればOKです。

![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/76973fec-1845-9dd4-f96d-805a811e8e55.png)

### 3. 検索して確認する

先ほどと同じように「振込の限度額」というキーワードで検索をしてみます。今回は「振込」と「限度額」のキーワードで引っかかった文書のみが表示されることが確認できます。

![image6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134250/3495ebe3-4482-8d26-fd83-54b9386cf49d.png)

## 参考文献
https://cloud.ibm.com/docs/discovery-data?topic=discovery-data-stopwords
Elixirでつぎのステップの動作を確認してみた

# 概要
Elixirでつぎのステップの動作を確認してみました。以下のページを参考にしました。

https://dev.to/gumi/elixir-23--50ik

# 実行
以下のコマンドを実行しました。
```
$ mix new example
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/example.ex
* creating test
* creating test/test_helper.exs
* creating test/example_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd example
    mix test

Run "mix help" for more commands.
```

# まとめ
何かの役に立てばと。