OmniAICreator/Qiita-1.07M huggingface dataset:
ChatGPTを使用したサービスを考えてみる

最近登場した対話型AI(ChatGPT)を使用したサービスには何があるのか考えたいと思います。
既にあるサービスはLINEとChatGPTを連携させた公式LINEです。
誰もが利用しているLINEとChatGPTを合わせることにより多くの人が手軽に利用できるようになっています。

下記のサイトを参考にしてください。
[AIチャットくん](https://appllio.com/line-chatgpt-aichatkun)

既存のサービスとChatGPTを合わせることで何か生まれるかもしれません。
下記にどんなサービスがあるか書いていきます。

1. noteとChatGPTを組み合わせることで小説などを書いてもらい記事を投稿するサービス。
1. 家庭教師とChatGPTを組み合わせて受験生が問題をAIに聞き勉強を教えてもらうサービス。
1. 子供が気軽に質問できるようなサービス例(空はなぜ青いのか？)
1. 悩み事を相談するサービス悩みを聞いてその解決策をChatGPTに答えてもらう。
1. 作業の効率化用のアプリをChatGPTに作ってもらうサービス。例(Excelの自動化)

随時更新します。
知識いろいろ箱

* ステート**レス**アプリケーションは負荷分散アプリケーションのパフォーマンスを向上させる傾向がある
* STSの設定
ウェブID：OpenID Connect互換のIDプロバイダーを使用してユーザーがサインインする場合に使用
SAML ID：

* デフォルトでデータを暗号化するサービス
Javascriptについて



●constの注意点

const で定義した定数でできないのは socres = 10; といったような scores そのものへの再代入であって、配列の要素への代入はできる

●配列の命令
・unshift()・先頭に配列を追加
・push()・末尾に配列を追加
・shift()・先頭から要素を削除
・pop()・末尾から要素を削除
・splice(変化が開始する位置,削除数,追加する要素)

●スプレッド構文・・...を配列の中で使うことで、そこに別の配列を展開。

●アラート・・・alert() を使えば何かお知らせを出すときに便利

●確認・・・ユーザーに確認を求める confirm()

●setTimeout()を使って、指定した時間後に処理を実行する

●例外処理・・予期せぬエラーを例外というが、システム障害などでっすテムが止まってしますことがある。処理を止めたくない時の処理を例外処理という。
try...catch
シェルスクリプト

●間違いやすい点・・name = "taguchi" のようにスペースを入れてしまうとエラーになる。値を割り当てる時にはスペースを入れない。変数では$のあとに変数名をつける。

●内容を書き換えてほしくない変数を作りたい時には、readonlyを用いる

●特殊変数・・$0 でスクリプトの名前、それから $# で引数の数、それから $@ もしくは $* で全ての引数を取得することができる

●readを使ってユーザーから入力を受け付ける方法　read 変数　ex) "hello $name"
入力前にテキストを表示したい場合には、 -p （プロンプト）オプションを使ってあげて read -p "Name: " name のように書く

●配列・・colors=(red blue pink)　echo ${colors[0]}

●数値計算・・((3 + 5)) echo$((3 + 5))

●比較・・文字列やファイルの比較には [[]] 、そして数値の比較には (()) がよく使われる

●条件分岐・・条件分岐は、ファイルが存在するかどうかの判定もよく使われる。種類を問わず存在しているかどうか調べるには -e 、ファイルが存在しているかは -f 、ディレクトリが存在しているかどうかは -d
DeepLabCutを使って、速度や移動距離を求める:D

# DeepLabCutとは？
　深層学習を用いて、正確なトラッキングをGUI(CUIもあります)で可能にするツールです。[ドキュメント](https://deeplabcut.github.io/DeepLabCut/README.html)を見て頂ければ、雰囲気が分かると思います。ワクワクするツールです。筆者のDeepLabCutの追っかけ歴は、約一年半となりますが、進化がものすごいですよ。Attentionが実装されたり、なんかtutorialが更新されたり、レイアウトが変化したりと、追っかけていて楽しいです。

# AIで「何がわかるか」って、難しい。
　DeepLabCutで位置情報(xy座標)を得られたとしても、それは単なる数字の羅列であり、下手したらデータの海に溺れてしまいます。YOLOもそうですよね。YOLOのモデルを作るのは、難しくありません。しかし、YOLOを"使って、何かする"というのは、壁があると個人的に思います。インターンの時、「人工知能のモデルを作るのは、今の時代簡単なんだよ。難しいのは、そこから何がわかるかなんだよね。」と言われたことが今でも忘れられません。

# DeepLabCutで「何がわかるか」に挑む。
　DeepLabCutをやってみたという記事は多いですが、日本語でのその解析記事はまだ見たことがありません。この記事を見てる方の参考になったら、嬉しいです:)
　ただ、「本当にこれであってるんかな？」と正直、思っています。間違っていたら、訂正の程、よろしくお願いします！

https://github.com/DeepLabCut/DLCutils/blob/master/Demo_loadandanalyzeDLCdata.ipynb

https://github.com/DeepLabCut/DLCutils/blob/master/time_in_each_roi.py

上のノートブックを参考にしました。

https://github.com/Banboo-glich/Banboo-glich.github.io/blob/main/Velocity_distance.ipynb

Githubに上げたので、良ければどうぞです。

DeepLabCutを操作できる前提で、記事を書いていきます。DeepLabCutの操作方法は、[こちら](https://qiita.com/suginaga/items/1e1a10e98ee85b930ef0)を参考にして進めて下さい。

https://github.com/DeepLabCut/DLCutils/blob/master/time_in_each_roi.py

まず、このpythonファイルを落としてください。このpythonファイルの一部の関数を使います。

deeplabcutのパッケージを落としてください。
```
!pip install deeplabcut
```
ライブラリーのをインポートしてください。
```python
import deeplabcut
import pandas as pd
from pathlib import Path
import numpy as np
import os
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import seaborn as sns
%precision 3
%matplotlib inline
```
DeepLabCutの結果をDataframeに格納する。
```python
#絶対パスでdatanameにDLCの結果を格納する
dataname = 'プロジェクト名+イテレーション回数.h5'
#"scorerを入力"
DLCscorer = 'プロジェクト名+イテレーション回数'
Dataframe = pd.read_hdf(os.path.join(dataname))
```
ここの移動距離を知りたいな～という部位をbodypartsに入れてください。
```python
bodyparts = 'atama'
```
```python
x = Dataframe[DLCscorer][bodyparts]['x'].values
x = np.nan_to_num(x, nan=0)
y = Dataframe[DLCscorer][bodyparts]['y'].values
y = np.nan_to_num(y, nan=0)
#二点の移動距離を連続するフレームから算出する。その合計値(総合移動距離)を出す。
vel = time_in_each_roi.calc_distance_between_points_in_a_vector_2d(np.vstack([x.flatten(), y.flatten()]).T)
distance= np.sum(vel)

print('総合移動距離:{}px'.format(distance))
```
```python
# 2点の距離をfpsで割り、速度を出す
vel_av = np.average(vel*px/fps)
print('平均速度:{}px/s'.format(vel_av))
```

詳しくは以下のレポジトリーでコードを動かしています。

https://github.com/Banboo-glich/DeepLearing_poseestimation




以上。
「プログラミング 初めて つらい」で悩んでいる人へのアドバイス（ChatGPTで書きました）

# プログラミング初心者が直面するつらい状況とは？

掘り下げて考えていきます。
- 暗記や記憶力の負担
- ロジカルシンキングの困難
- エラーの発生と修正に時間がかかる
- ソースコードの難解さ


## 暗記や記憶力の負担
プログラミングを最初に学ぶときは、新しい言語や概念を理解するために多くの情報を覚えないといけません。これがかなり辛いです。

まずは次のことを知っておきましょう。
- 暗記力よりも理解力が重要。つまり、コードの書き方やその意味を理解する。
- コードを実際に書いてプログラムを動かす。概念をより深く理解し、覚えやすくなる。
- 本やネットの情報を丸暗記しなくていい。理解を深めることに注力する。

## ロジカルシンキングの困難
どういうことか？理由と対処法を述べます。

### [理由1] 環境の複雑さに適応するための訓練不足

- [解決1] 問題解決能力を養うためには、問題解決の実践が必要になる。
- [解決2] 小さなプログラムから始め、徐々に複雑なものに移行する。

### [理由2] プログラミング言語の文法を理解するのが難しい。
- [解決1] 簡単なチュートリアルから始め、文法のルールを学ぶ。
- [解決2] 複雑なプログラムを実行することで、文法ルールの理解を深める。

### [理由3] 抽象的な概念を理解するのが難しい
- [解決1] 抽象的な概念を実践的な問題に結び付ける。
- [解決2] コーディングのプロセスに注目し、概念を理解する。

## エラーの発生と修正に時間がかかる
次のことを知っておくと精神的に安心します。特に最初と最後の内容は大事。
- エラーはプログラミングで必ず発生するものであり、経験者でも慣れるまで時間がかかることがある。
- エラーが発生した場合、まずはエラーメッセージを読む。
- コードを読みやすく整形することで、エラーを見つけやすくすることができる。
- エラーが発生しても、焦らずに冷静に対処し、解決策を見つけるために検索（ググる、Bing）や質問（ChatGPT）が大切である。

## ソースコードの難解さ

- プログラムの実行結果が自分が思ったものと異なる場合、原因を追うのが難しい。
- 長いコードは読みづらく、理解が難しい。
- 自分以外の人が書いたコードを読むと、その人が何を意図して書いたのか理解するのが難しい。
- コードを書くために必要な言語やライブラリの知識が不足している場合、コードを書くこと自体が難しい。

# まとめ
この記事では、プログラミング初心者が直面する課題について述べました。

- 新しい言語や概念を理解するために暗記や記憶力が必要で、ロジカルシンキングの困難を感じることがある。
- 環境の複雑さやプログラミング言語の文法の理解が難しいときは、問題解決の実践や実際にプログラムを書くことが大切である。
- エラーの発生と修正に時間がかかるが、エラーメッセージを読んだり、コードを整形することで解決策を見つけることができる。
- ソースコードの読みづらさや理解の難しさは、短いコードから始めたり、抽象的な概念を実践的な問題に結び付けることで克服することができる。
秋月のOLEDシリーズのまとめ(リンク集)



０．９６インチ　１２８×６４ドット有機ＥＬディスプレイ（ＯＬＥＤ）　白色
通販コード　P-12031
発売日　2017/11/27

SSD1306互換
128x64
アドレスは、「3C」

![o_cop433.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ee361817-28ef-932d-817e-eebfc7a700c8.jpeg)


![o_cop440.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/13b1cb08-fd40-4371-031f-5107e62178f9.jpeg)



https://qiita.com/caa45040/items/25c3c4407bb0a5e14e28


-----------------------------------------------------------


「色ちがい」
０．９６インチ　１２８×６４ドット有機ＥＬディスプレイ（ＯＬＥＤ）　青
通販コード　P-15870
発売日　2020/11/23

SSD1306互換
128x64
アドレスは、「3C」


![o_cop434.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e8329ecc-30f0-db9a-81ea-ca7cfea48087.jpeg)


![o_cop439.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a874c444-dd5d-e568-896e-f11912abe3af.jpeg)



https://qiita.com/caa45040/items/c8a0151f77ccca4955e4


-----------------------------------------------------------


有機ＥＬディスプレイ　１２８×３２　白色
[AL12832AWWB-H-U02]
通販コード　P-14686
発売日　2020/03/07

SSD1306互換
128x32
アドレスは、「3C」

![o_cop435.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/96413be9-0615-d02a-dd93-d7f8384f97cf.jpeg)


![o_cop438.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/fa441927-c7bf-8bbb-53c6-55a53f77f9da.jpeg)



https://qiita.com/caa45040/items/6c98cc044d7813a753a3


-----------------------------------------------------------


「カラー」でちょっと高いけどおすすめ(Arduino UNOではなにもデキない(感想))	
有機ＥＬディスプレイ　０．９５インチ　９６×６４ドット　ＲＧＢ
[QT095B]
通販コード　P-14435
発売日　2019/09/02

SSD1331互換
96x64



![o_cop436.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8c431666-e4cb-2779-ba52-5b04b36e9c8b.jpeg)


![o_cop437.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/378f7177-cdcb-f7e3-3f51-e52bf0b5547d.jpeg)



https://qiita.com/caa45040/items/f9f4fd3207173e1c3d13


https://qiita.com/caa45040/items/75f384c762eb278c7ecb
vue.jsでAjax通信（Laravel）

## はじめに
vue.jsでAjax通信を実装しました。
備忘録として残しておきます。

## 開発環境
| 開発環境    |バージョン |
|-----------|------------|
| __Laravel__ | 10.1.5 |
| __PHP__     | 8.2.3  |
| __vue.js__     | 3.2.47 |

## 実装内容
```vuejs:AjaxComponent.vue
<template>
    <form  @submit.prevent="regist">
        <div>設定画面</div>
        <button type="submit" class="btn btn-primary set-button">Ajax開始する</button>
    </form>
</template>

<script>
    export default {
	      data() {
              return {
                ajaxURL: "通信先URL"
              }
	      },
	      methods:{
            regist:function() {
                  const data = {
                    ajaxdata: '渡したい値'
                    }
                    axios.post(this.ajaxURL, data)
                        .then(
                            response => {
                                console.log('通知成功です', response);
                        }).catch(
                            error => { 
                                console.log('通信失敗です（error情報）', error); }
                        );
                },
	      }
    };
</script>
```

```PHP:web.php
   Route::any('/home/regist', [App\Http\Controllers\HomeController::class, 'regist'])->name('home.regist');

```

```PHP:AjaxController.php
    // ... 略

    // 設定情報を登録する
    public function regist(Request $request){

        // 入力された情報を取得する
        $postData = $request->all();
        
        // js側に渡したい値を返す
        return response()->json("js側に渡したい値");
    }
```
__@submit.prevent__ をつけることで、画面遷移を防ぐことができます。

## 終わりに
最後までご覧いただきありがとうございます。
ご指摘、ご意見ありましたらよろしくお願いいたします。
Pythonバックエンドでmatplotlibで描画された画像をクライアントサイド（React）に表示する方法

# 最初に結論
1. （バックエンド）BytesIOを使ってmatplotlibの画像のByteデータを取得する
1. （バックエンド）`media_type="/image/png"`で送信
1. （クライアント）axiosなどで、画像データを含むResponseを取得し、<img>タグのsrcに、受け取った画像のByteデータオブジェクトを指定する


以下、サンプルコードを示します。
# バックエンド（FastAPI）
```Python
import io
from fastapi import FastAPI, Response
import numpy as np
import matplotlib.pyplot as plt

app = FastAPI()

@app.get('/my/backend-api/endpoint')
def plot_png():
    # データの生成
    x = np.arange(0, 10, 0.1)
    y = np.sin(x)
    # グラフの描画
    fig, ax = plt.subplots()
    ax.plot(x, y)
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    # グラフを画像ファイルに保存
    png_output = io.BytesIO()
    fig.savefig(png_output, format='png')
    # 画像ファイルをクライアントに送信
    png_output.seek(0)
    return Response(content=png_output, media_type="/image/png")

```

`hypercorn main:app --reload`でFastAPIサーバを起動します。


# クライアント（React）
コンポーネントだけ記述します。useState, useEffectを用いて初回レンダリング時に画像を取得してimageDataという変数に画像データを格納するコードになっています。

```JavaScript
import React, { useState, useEffect} from 'react';
import axios from 'axios';

const ImageComponent = () => {
  const [imageData, setImageData] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios.get('/your/backend-api/endpoint');
      setImageData(result.data);
    };

    fetchData();
  }, []);

  return (
    <div>
      {imageData && (
        <img src={imageData} alt="wordcloud"/>
      )}
    </div>
  );
}

export default ImageComponent;

```

以上、matplotlibの画像をAPIで送信してレンダリングするまでの流れを簡単なサンプルコードと共に紹介しました。

ちなみに、以上で紹介した内容はAPIのレスポンスが画像のみの場合ですが、他にテキスト情報と共に返送したい場合は、Base64エンコーディングで画像データをシリアル化（＝データ形式を変換すること）して、JSONオブジェクトのフィールドの項目の一つとして送信することが一般的なようです。
androidでnadesiko

# 概要
androidでnadesikoやってみる。
構想編

# 手順
# androidタブレットを購入する。
# wifiに、入る。
# userlandをインストールする。
ubuntu18.04
# 日本語環境に変更

```
$ sudo apt -y install language-pack-ja
$ sudo update-locale LANG=ja_JP.UTF8
$ sudo dpkg-reconfigure tzdata
$ sudo apt install uim-fep uim-mozc
```

.uimの設定ファイルを作成。

```
(define default-im-name 'mozc)
(define-key generic-on-key? '("<Control> " "<Control>g"))
(define-key generic-off-key? '("<Control> " "<Control>g"))
```

# nadesikoをインストールする。

```
$ sudo apt install -y nodejs npm wget
$ sudo npm install -g npm

$ npm install -y nadesiko3

```

以上。
SREだけど初PHPerKaigi行ってきた！

そういやそこそこ投稿してきてて「OSS作ってみたわ！」以外の記事が殆どないなｗアウトプットとは？ｗｗ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/f7c2a32d-10d4-3dcf-73dd-3f209c087064.png)

# なんで行ったん？
同僚が登壇するとかでお手伝いとして参加しました。
開発チーム勢がブランディングについて色々頭悩ませるなか、人足枠として参加を志願しました。
~~という名目だったのにあんまりお手伝いしてなくてすいません、、~~

### だってLAPRASの技術タグ、エグい量なのにPHP書いた事ほぼ無かったですので・・ｗ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/2f70f188-28f0-746c-8e3a-69bbc5bcb9b9.png)


# どうでしたか？

### でも楽しかったよ！

SREだから話ついてけない、みたいな事は一切なくて、色々な人と沢山おしゃべりできました。
10年以上PHPに関わってる人と喋ってると、懐の深さ、技術的な深さから、フダンの仕事と繋がる事がおおくて
「ああ、あれはそういうことだったのか・・・」と思わされる学びがちょいちょいあった。
これは、**技術的答え合わせ**、ってかんじだ。
また、IT経験値がそこまで高くない人に自社サービスを改めて説明するのも頭の中が整理されて良かった
質問内容が普段あたりまえに認識している点をもっと分かりやすく言わなければならなかったり、そこでも気づきがあった。

# また行きたい？
是非是非ー！
学生時代、学校行事好きじゃなかったけど、学園祭みたいに外に向けて発信するようなものは好きだったのよね。
一丸という言葉だとちょっとカタいんだけど、みんなでブランディングするのって楽しいな、と改めて。
PHP自体への理解と興味も深まったのでOSS一本書いてみようかなんて気持ちになってる。
OSSコミッターとしてちょっとでもできる貢献として

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/be98cf97-0777-4632-87a5-22b5216c3bd0.png)

数年ぶりの懇親会だったそうで、みんなで乾杯したのがまた打ち上げぽかった！（学生は酒呑まないだろｗ
立食パーティーなんかもしてさぁ。良い一日だったなぁって。

あと、喋ってて印象深かったのは**PHPerはコミュニティがギスギスしてなくてそこが良いのよ**って話が
幾つかあって、体感しながら、ああ、確かにそうだなぁ、なんて思ったりもした


# まとめ
- **技術的答え合わせ大事**
- **学園祭ノリは永遠**
- **PHPerコミュニティ最高！**

オチとしてPHPerマカロンを持って帰ってきましたが、
色々ノベルティやらもらって来たので、ど根性ガエルみたいに平面マカロンになってましたｗ
Vuetify2のv-iconってどうなってるの？？？

## Vuetify2のv-iconって一体どうやって動いてるのよ！！！

こんにちは、Vueに触れて1年以上経過するもVueの仕組みを何一つ理解していない自信があるとれいすです。

記事名の通り、v-iconってどういう仕組みで動いているのかを知りたくなったため、せっかくなら記事にしてみようと思った次第です。

というのも

```vue:v-iconの使いかた
<v-icon>mdi-XXXX</v-icon>
```

って書いてアイコンになるのは不思議だなーと、無知ワイは思ったわけです。

それでは早速見ていきましょー

:::note alert

この記事はVuetify 2をターゲットにした記事です。
Vuetify 3では中身が違うので、「Vuetify 3の記事じゃないじゃん」とか言われても困ります。

:::


## ソースコードを見る

ソースコードを覗いてみましょう。

なお、気になったところだけ抜粋します。

```ts:VIcon.ts
getIcon() {
  let iconName = '';
  if (this.$slots.default) iconName = this.$slots.default[0].text.trim();
  return remapInternalIcon(this, iconName);
}

// 中略 //

render (h: CreateElement): VNode {
  const icon = this.getIcon()

  if (typeof icon === 'string') {
    if (isSvgPath(icon)) {
      return this.renderSvgIcon(icon, h)
    }
    return this.renderFontIcon(icon, h)
  }

  return this.renderSvgIconComponent(icon, h)
}
```

`this.getIcon()`でアイコンの名前である`mdi-XXXX`を`this.$slots.default`から引っ張ってきて、アイコンの名前と一緒にヘルパー関数の`remapInternalIcon()`に飛んでいます。

その中身が↓

```ts:helpers.ts
function remapInternalIcon (vm: Vue, iconName: string): VuetifyIcon {
  // Look for custom component in the configuration
  const component = vm.$vuetify.icons.component

  // Look for overrides
  if (iconName.startsWith('$')) {
    // Get the target icon name
    const iconPath = `$vuetify.icons.values.${iconName.split('$').pop()!.split('.').pop()}`

    // Now look up icon indirection name,
    // e.g. '$vuetify.icons.values.cancel'
    const override = getObjectValueByPath(vm, iconPath, iconName)

    if (typeof override === 'string') iconName = override
    else return override
  }

  if (component == null) {
    return iconName
  }

  return {
    component,
    props: {
      icon: iconName,
    },
  }
}
```

`remapInternalIcon()`は`$cancel`や`$vuetify.icons.cancel`のような内部名を、そのアイコンの正しい？名前、またはコンポーネントにリマップしてくれるものだそうです。

## 結論

    `slot`を使って指定されたアイコンの名前を取得し、一意に定まるアイコンを取得してレンダリングしている

という理解に落ち着きました。違ったらコメントでご指摘ください。

ではまた。
Swift 関数の基本

今回初投稿です。
1/20よりiOSエンジニアを目指し、スクールで日々Swiftを勉強しています。

この記事では私個人的に苦手な分野を記事にまとめながら
自分自身も勉強になるようにしようと思います。

もし間違ってたら指摘してください笑

今回は関数の基本を記事にしたいと思います。

目次
-関数とは
-1.基本構文
-2.引数とは
-3.引数を持つ構文
-4.戻り値とは
-5.戻り値を持つ構文
-6.引数と戻り値を持つ構文
-最後に




# 関数とは
・特定の処理を1つの塊として定義したもの
・入力値＝引数　出力値＝戻り値が存在する
・メソッドとも呼ばれる

## 1.基本構文
①記述方法
```php
func sayHello() {
    print("Hello！")
}
```

・関数はこのようにキーワードfuncの後に任意の関数名（今回は「sayHello」）と（）を
　記述することで定義できる
・関数名の後の{}内に記載された内容がこの関数の処理内容となる

②処理実行方法
```php
sayHello()
```

・関数は関数名＋（）を記述することで処理が実行される

__このように関数は特定の処理を1つの塊として名前をつけることができる__
また関数には引数を持つ構文も存在する

## 2.引数とは
・1つの関数内で少し処理を変更したい場合に使用
・上記構文は「Hello！」のみしか処理ができない
・引数を使用することで、「Hello！」以外の文字列を使用することができるようになる
・関数には関数を呼び出す時に値を渡すように定義ができる
・この時の値を引数という
![引数イメージ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121562/a87d85c7-304c-d4b6-2a61-bbddaa83016a.jpeg)
引数付きの関数イメージ

（引数の定義・イメージ図は　https://atmarkit.itmedia.co.jp/ait/articles/1509/10/news021_3.html
より引用）

## 3.引数を持つ構文
①記述方法
```php
func say(text: String) {
    print(text)
}
```

・通常の関数の定義方法（基本構文参照）に
　引数名（text）と:に続いて型（String）を指定することで定義できる

②処理実行方法
```php
say(text :"Hello!")
```

・関数名＋（引数：指定された型の値）を記述することで処理が実行される
・引数がある場合は、指定された型（String）の値（"Hello!"）を
　記述する（「渡す」という）ことで処理が実行される


また引数を含む関数だけでなく戻り値を含めた関数も存在する


## 4.戻り値とは
・関数の中で処理をさせ結果をもらいたい時に使用
・上記までの構文は一方的に呼び出す構文だった
　※基礎関数＝「Hello！」を呼ぶ　引数のある関数＝文字列の「Hello！」を呼ぶ

・関数の中で処理したい結果を呼び出し元に返すよう定義ができる
・この返す値を戻り値（返り値）をいう
![戻り値イメージ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121562/5a3c2825-2e29-f04c-6d7d-4360d80e5a31.jpeg)
戻り値を使用して関数の実行結果を受け取るイメージ

（戻り値の定義・イメージ図は　https://atmarkit.itmedia.co.jp/ait/articles/1509/10/news021_3.html
より引用）

## 5.戻り値を持つ構文
①記述方法
```php
func number() -> Int {
    let result = 10 * 2
    return result
}
```

・関数（1.基本構文 参照）の{}の前に　-> 戻り値の型名（Int）を指定する
・この時、関数内（{}内）でreturnと元に返したい値（result）を書くことで
　戻り値を指定することができる

②処理実行方法
```php
let result = number()
print(result)
```

・呼び出した関数（number()）から返された値を定数(result)に代入することで処理が実行される

引数と戻り値を含めた関数も存在する


## 6.引数と戻り値を持つ構文
・引数のみの関数の場合、「関数を計算し結果を表示する」という機能を持っていた
・そこに戻り値を使用し、「関数の中で割合を計算し、計算結果の値を呼び出し元に返す」
　という機能に書き換える

![引数＋戻り値.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3121562/ff211e9a-10cb-f6c4-94ad-7408c954de29.jpeg)
（引数と戻り値を持つ関数の定義・イメージ図は　https://atmarkit.itmedia.co.jp/ait/articles/1509/10/news021_3.html
より引用）


①記述方法
```php
func double(number: Int) -> Int {
    let result = number * 2
    return result
}
```

・上記例文は、引数としてInt型が渡され（double(number: Int)）
　その値を2倍にし(let result = number * 2)
　戻り値に返す（-> Int { ...return result }）ように定義


②処理実行方法
```php
let originNumber = 10
let doubleNumber = double(number: originNumber)
print(doubleNumber)
```

・定数originNumberを定義（let originNumber = 10）
・doubleメソッドを呼び出す（double(number: originNumber)）と同時に
　定数doubleNumberを定義（let doubleNumber =）することで処理を実行する



## 最後に
今回初めての投稿でMarkdownも調べつつ投稿しました。
ご指摘あればぜひご連絡ください。
Linux基礎

# Linux

## linuxとは
OS(コンピューター動かすソフトウェア)の一種
オープンソースソフトウェア(誰もが使えたり、改良できる)

## Linuxを学ぶ理由
1.ワークフローを改善
　→ツールのインストールがCUIでできるように
2.セキュリティ
　→オープンソースだから脆弱性があっても誰かが直してくれる
3.ツールの充実
　→wget, curl, etc...
4.タスクの自動化
　→タスクをテキストで実行
5.本番環境で使われている
　→上記の理由から現場で使われている

## Linux ディストリビューション
**カーネル** OSの中核となるソフトウェア
**デュストリビューション** カーネルに色々なソフトウェアを組み合わせ、使いやすくしたもの
→Red Hat系 ・Red Hat Enterprise Linux ・Cent OS ・Fedora
→Debian系 ・Debian GNU/Linux ・Ubuntu

## シェル
コマンドを入力する場所
CLI(キーボードで入力するインターフェース)
```
[tanaka(ユーザー名)@localhost(ホスト名) ~]$(プロンプト)
```
**ターミナルとシェルの違い**
ターミナルは画面を担当するソフトウェア
シェルはコマンドを解釈するソフトウェア

**シェルの種類**
sh(最古), bash(標準), zsh(拡張)

## ショートカットキー
**カーソルの移動**
Ctrl + f 1文字次へ移動
Ctrl + b 1文字前へ移動
Ctrl + a 行の先頭に移動
Ctrl + e 行の最後に移動
Meta + f (esc + f) 1単語次へ移動
Meta + b (esc + b) 1単語前へ移動

**文字列の編集**
Ctrl + h カーソルの左を1文字削除
Ctrl + d カーソルの部分を1文字削除
Ctrl + w カーソルの位置の単語を削除（カーソルの前部分）
Ctrl + u カーソルの位置から行頭まで削除
Ctrl + k カーソルの位置から行末まで削除
Ctrl + y 最後に削除した内容を挿入

**トラブル時の対応**
Ctrl + c 実行中のコマンドを強制終了
Ctrl + l 画面の消去。文字化けした時のクリアにも使える
Ctrl + s 画面表示のロック(キーボードから文字の入力を受け付けない)
Ctrl + q 画面表示のロックの解除

**補完・コマンド履歴**
Tab コマンドやパスの補完
Ctrl + p, または↑キー 1つ前の履歴を見る
Ctrl + n, または↓キー 1つ後の履歴を見る
Ctrl + r コマンド履歴のインクリメンタル検索
文字の入力 コマンド履歴から検索
Ctrl + r 1つ前の検索結果へ移動
Enterキー 現在の検索結果を実行
Escキー 現在の検索結果を表示したままコマンドラインに戻る
Ctrl + g 検索結果を放棄し、コマンドラインに戻る

## 仮想環境について
今回はUTMを使いUbuntuを導入
https://www.youtube.com/watch?v=v2AFkuvt0-w
↑
こちらの動画を参考にさせていただいた
秋月謎SoC基板用の buildroot_am3352_aki をカスタマイズしてsshログインしてみる

# はじめに

秋月謎SoC基板へsshログインできるよう、カスタマイズしてみる話です。

[秋月謎SoC基板用の buildroot_am3352_aki をビルドしてみる(AWS EC2編)](https://qiita.com/rukihena/items/fe04677ad556621fa85d)
あるいは
[秋月謎SoC基板用の buildroot_am3352_aki をビルドしてみる(WSL2編)](https://qiita.com/rukihena/items/de8f29101a027635ea51)
の続きです。

# 設定

`make` したときのディレクトリで、`make menuconfig` を実行します

![menuconfig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104360/8d693825-8659-1970-b14e-b5869dff3520.png)


以下、変更項目を挙げていきます。スクショなしですいません。
（メニュー順に挙げます）

```
  System configuration  --->
   () Root password
```
パスワードが設定されていない場合、sshでつながった直後に切られてしまうので、なんかしらパスワードを設定します。

`akizuki` とでもしておきましょうか。

```
  System configuration  --->
   () Network interface to configure through DHCP
```

起動時にDHCPで設定させるインターフェース名を指定します。
ここでは `eth0` を指定します。

```
Target packages  --->  
  Networking applications  ---> 
     [*] avahi
     [*]   IPv4LL network address configuration daemon
     [*]   mDNS/DNS-SD daemon
     [*]   libdns_sd compatibility (Bonjour)
     [*]   install default service definitions
```

外部からホスト名で接続できるようにするため、avahi を選択します。avahi を選択すると下の項目が増えます。とりあえず全部選択しておきす。

```
Target packages  --->  
  Networking applications  ---> 
     [*] dropbear
     [*]   client programs
     [*]   disable reverse DNS lookups
     [*]   optimize for size
```

sshデーモンの軽量版、`dropbear` を選択します。
`disable reverse DNS lookups` は、ログに吐くときにホスト名を調べるのをサボって、コネクション時の引っ掛かり感をなくす設定と思います。

なお、`dropbear` でなく `openssh` を選んだらログインできませんでした。`openssh`を使うには何らかの設定が必要と思います。（セキュリティレベルを落とすとか、ちゃんと鍵ファイルを置くとか、そんな感じの設定が必要なのかな？）

# ビルド

ここで `make` ・・・したらドハマリしました。

`make clean` してから、`make` してください。

ここで `make clean` をしない場合、`/etc/network/interfaces` が書き換えられず、起動後に `eth0` が上がってきません。

`make` が終わったら、念のため `/etc/network/interfaces` に `eth0` の記述があることを確認しましょう。（デフォルトでは `lo` の記述だけでした）
イメージファイル内のファイルシステムを作る元となるファイルは`output/target/`配下にあります。

```
$ cat output/target/etc/network/interfaces
# interface file auto-generated by buildroot

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
  pre-up /etc/network/nfs_check
  wait-delay 15
  hostname $(hostname)
```

:::note
正しく設定できていれば関係ない話ですが、起動後に eth0 が上がってきてない場合にコマンドから固定IPを振るには以下のようにします。

```
# ip link set eth0 up
# ip addr add 192.168.0.xxx/24 dev eth0
# ip route add default via 192.168.0.1
```

一行目は寝ているインターフェースを起こすものです。整った環境ではまず必要のないコマンドなので知らずにドハマリしました。これを打たずに `ip addr add ～` するとコマンドは正常に通っているように見えるものの、ping で内部ネットワークにも届かないという症状になります。
:::

# ssh 接続

`make`が終わったら、`./output/images/sdcard.img` microSDに書き込み、謎基板に挿して起動してみましょう。

ホスト名は、変更していなければ `buildroot` となっているので、sshの接続先の名前は `buildroot.local` です。（ポートは当然 22 です。）

書くまでもないですが、ユーザー名は `root` パスワードは先に設定した`akizuki`です。

# おまけ

## Lチカ

led1 ～ led4 が定義されています。

led1 はmicroSDと電源LED(緑) との間。
led2 ～ led4 はmicroSDを挟んで反対側にあります。

LED1 ON
```
# echo 1 > /sys/class/leds/led1/brightness
```

LED1 OFF
```
# echo 0 > /sys/class/leds/led1/brightness
```



## 温度センサー

温度センサーのADC生値取得
```
# cat /sys/bus/iio/devices/iio:device0/in_voltage6_raw
```

# おわりに

ドハマリした時間を供養するために記事を書きましたが、成功する手順だけ書くとかなりアッサリした記事になってしまいました。

なかなかルートイメージを作る機会はないと思いますが、この基板との出会いをきっかけに、buildrootの世界に触れてみてはいかがでしょうか。私もその一人です。
秋月謎SoC基板用の buildroot_am3352_aki をビルドしてみる(WSL2編)

# はじめに

秋月電子で謎の基板が売り出されていました。（現在売り切れ）

https://twitter.com/aki_soku/status/1636532913947959297

これを解析して動かした方がいらしゃいます。

https://twitter.com/bakueikozo/status/1638790897172357122

これをWSL2環境でビルドしてみようという記事です。

（[AWS EC2編はこちら](https://qiita.com/rukihena/items/fe04677ad556621fa85d)）

# 前提知識

ラズパイなどのイメージをSDに書き込んだことがある
dialog(raspi-config みたいな画面)の操作ができる
WSL2 - Ubuntu を使える
buildroot は初めて
（つまりは3日前の自分）

# WSL2 - Ubuntu 準備

WSLのUbuntuは、ストアからバージョン表記なしの Ubuntu を選びました。22.04.1 がインストールされました。

素の状態から試したので、必要パッケージに漏れはないものと思います。

元の記事にも言及がありますが、PATHを綺麗する操作をここでしておいてください。

また、WSL1 ではビルドが失敗します。動かしているUbuntuがWSL2上で動いていることを改めてご確認ください。

確認方法は以下の通り。（コマンドプロンプトまたはPowerShellでの操作）
```
C:\>wsl --list -v
  NAME      STATE           VERSION
* Ubuntu    Running         2
```

（WSL2で動いているものと思いこんでてかなり時間を無駄にしてしまった・・・）


# パッケージのインストール

ビルドに必要なパッケージをインストールします。
（以下、Ubuntu内での操作です）
```
$ sudo apt update
$ sudo apt -y install build-essential bc libssl-dev unzip ncurses-dev
```

`build-essential` は、make などの全部入りです。
`bc` `libssl-dev` `unzip` は、無いとビルド時にエラーがでます。
`ncurses-dev` は、`make menuconfig` するときに必要となります。

# ソースの入手とビルド

ソースを取得します。ディレクトリは1階層作られるので、明示的に作成しておく必要はないでしょう。
```
$ git clone https://github.com/bakueikozo/buildroot_am3352_aki
```
作られたディレクトリに移動します。
```
$ cd buildroot_am3352_aki
```

ビルドします。
```
$ make akiduki_am3352_defconfig
$ make
```
手元の環境(i7-4790k 4コア8スレッド 4GHz)では20分ほどかかりました。

:::note
`-j` オプションを付けて高速化したほうがいいのでは？と思いましたが、buildroot側で良きに計らってくれるみたいなので、付けなくていいっぽいです。`make menuconfig` の中にジョブ数を指定するところがあり、デフォルトでは自動になっています。
:::

正常にビルドできたら、最後のメッセージは以下のようになります。
```
INFO: hdimage(sdcard.img): adding partition 'u-boot' (in MBR) from 'boot.vfat' ...
INFO: hdimage(sdcard.img): adding partition 'rootfs' (in MBR) from 'rootfs.ext4' ...
INFO: hdimage(sdcard.img): adding partition '[MBR]' ...
INFO: hdimage(sdcard.img): writing MBR
$
```

成果物は、`./output/images/sdcard.img` です。

```
$ ls -la ./output/images/sdcard.img
-rw-r--r-- 1 username username 79692288 Mar 26 06:17 ./output/images/sdcard.img
```

これをSDに書き込み、謎基板に挿して起動してみましょう。

シリアルコンソールは 115200bps です。

なお、ログインプロンプトが出た数秒後、3Gモジュールの認識メッセージが被ります。

# つづき

dhcp,mdns,ssh を有効にしたイメージを作り、有線LAN経由でログインしてみます。
USBシリアル変換ケーブルなどを持っていなくてもログインできるようになります。

[秋月謎SoC基板用の buildroot_am3352_aki をカスタマイズしてsshログインしてみる](https://qiita.com/rukihena/items/4bc45330b0589c5cbe15)
秋月謎SoC基板用の buildroot_am3352_aki をビルドしてみる(AWS EC2編)

# はじめに

秋月電子で謎の基板が売り出されていました。（現在売り切れ）

https://twitter.com/aki_soku/status/1636532913947959297

これを解析して動かした方がいらしゃいます。

https://twitter.com/bakueikozo/status/1638790897172357122

これをAWS EC2でビルドしてみようという記事です。

（[WSL2編はこちら](https://qiita.com/rukihena/items/de8f29101a027635ea51)）

# 前提知識

ラズパイなどのイメージをSDに書き込んだことがある
dialog(raspi-config みたいな画面)の操作ができる
AWS EC2を使える
buildroot は初めて
（つまりは3日前の自分）

# EC2準備

EC2のインスタンスタイプはArm系で最新のc7gがコスパ的にいいかと思います。

ビルド時間を計測したところ、次のようになりました。

| インスタンスタイプ | vCPU |ビルド時間 |
|:-:|:-:|:-:|
|c7g.xlarge   |4|16分   |
|c7g.2xlarge   |8|10分   |

mシリーズはメモリが過剰かもしれません。っていうかm7gはまだ無いみたいです。

純粋にコンパイルしているときは、ほぼ100%使ってくれますが、なにかのcheckやファイルのダウンロードなどで空き時間が増えるため、コア数が増えるほど速くはなるもののコスパは悪くなります。

あと、これを試すときに気づきましたが、Amazon Linux 2 後継の Amazon Linux 2023 が使えるようになっています。ここでは 2023 のほうを使っています。2023にするとTeraTermで接続できなくなるのですが、TeraTerm5（今のところベータ版）を使うと接続できます。

ディスクはデフォルトの8GBで足りますが、結構ギリギリです。`make menuconfig`で機能を追加すると足りなくなってきます。

# パッケージのインストール

ビルドに必要なパッケージをインストールします。

```
$ sudo yum -y groupinstall "Development Tools"
$ sudo yum -y install openssl-devel ncurses-devel
```

`groupinstall "Development Tools"` は、make などの全部入りです。
`openssl-devel` は、無いとビルド時にヘッダが見つからないというエラーがでます。
`ncurses-devel` は、`make menuconfig` するときに必要となります。

# ソースの入手とビルド

ソースを取得します。ディレクトリは1階層作られるので、明示的に作成しておく必要はないでしょう。
```
$ git clone https://github.com/bakueikozo/buildroot_am3352_aki
```
作られたディレクトリに移動します。
```
$ cd buildroot_am3352_aki
```

ビルドします。
```
$ make akiduki_am3352_defconfig
$ make
```

先に書いたビルド時間は、この`make`の時間です。

:::note
`-j` オプションを付けて高速化したほうがいいのでは？と思いましたが、buildroot側で良きに計らってくれるみたいなので、付けなくていいっぽいです。`make menuconfig` の中にジョブ数を指定するところがあり、デフォルトでは自動になっています。
:::

正常にビルドできたら、最後のメッセージは以下のようになります。
```
INFO: hdimage(sdcard.img): adding partition 'u-boot' (in MBR) from 'boot.vfat' ...
INFO: hdimage(sdcard.img): adding partition 'rootfs' (in MBR) from 'rootfs.ext4' ...
INFO: hdimage(sdcard.img): adding partition '[MBR]' ...
INFO: hdimage(sdcard.img): writing MBR
$
```

成果物は、`./output/images/sdcard.img` です。

```
$ ls -la ./output/images/sdcard.img
-rw-r--r-- 1 username username 79692288 Mar 26 06:17 ./output/images/sdcard.img
```

これをSDに書き込み、謎基板に挿して起動してみましょう。

シリアルコンソールは 115200bps です。

なお、ログインプロンプトが出た数秒後、3Gモジュールの認識メッセージが被ります。

# つづき

dhcp,mdns,ssh を有効にしたイメージを作り、有線LAN経由でログインしてみます。
USBシリアル変換などを持っていなくてもログインできるようになります。

[秋月謎SoC基板用の buildroot_am3352_aki をカスタマイズしてsshログインしてみる](https://qiita.com/rukihena/items/4bc45330b0589c5cbe15)
WindowsでStable diffusion WEB UI（AUTOMATIC1111 fork）を動かしてみる

Diffusersを使っているのですが、試したくなりStable diffusion WEB UIを入れてみました。
使えるようになるまでの自分用メモです。
WEB UIが表示できるまでの所要時間はエラーがあっても約1時間半ぐらいでした。

## 参考にしたページ

https://viasnake.com/how-to-run-stable-diffusion-web-ui-on-windows/

## 環境

CPU:Core i5-10600KF
メモリ:DDR4 48GB
グラフィックスボード:Geforce RTX3060 12GB
OS:Windows11 Pro 64bit
Gitはインストール済み

## やったこと

* WSLインストール（インストールしてあったがエラーになったため再インストール）
* Dockerインストール（docker desktop4.17.1）
* git clone
* Stable diffusion WEB UIの準備（ダウンロードと起動）
* ブラウザにて表示

## WSLインストール

以前WSLのインストールをしていたので使えるかどうか試してみたところ以下のエラーが出た。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238748/92450c2a-9097-5769-4b93-a89f55841147.png)

色々調べると皆さんいろんなやり方で解決されているようでしたが、私はとりあえず再インストールすればいけるだろうと愚直に再インストールしたら行けました。
* Microsoft StoreにあるUbuntuを一旦消す
* 「コントロール パネル\プログラム\プログラムと機能\Windowsの機能の有効化または無効化」より、Linux用Windowsサブシステムのチェックを外す
* PCの再起動を求められるので再起動する。
* 「コントロール パネル\プログラム\プログラムと機能\Windowsの機能の有効化または無効化」より、Linux用Windowsサブシステムのチェックをつける
* Microsoft StoreにあるUbuntuをインストールする。

上記でインストールが完了し、無事Ubuntuが起動してパスワードの設定を行えました。

## Dockerインストール

Dockerも以前インストールしていたので立ち上げてみたのですがエラーがでました。調べると再インストールするべしとのことなのでそのまま再インストールしました。
無事立ち上がりHello worldできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238748/e01a5313-1bef-1cfd-b280-317885944f9b.png)

## git clone

念のためにgitのバージョンを確かめます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238748/af05af52-526a-6e02-c154-adff6d67e43b.png)
バージョンが出てくれば正常にインストールされています。

cloneするディレクトリでstable-diffusion-webui-dockerをcloneをします。

```
git clone https://github.com/AbdBarho/stable-diffusion-webui-docker.git
```

## Stable diffusion WEB UIの準備（ダウンロードと起動）

Cloneが終わったらstable-diffusion-webui-dockerディレクトリに移動します。

```
cd stable-diffusion-webui-docker
```

以下のコマンドを実行してモデルデータをダウンロードします。とんでもなく長いです。約20～30分程度

```
docker compose --profile download up --build
```

ダウンロードが終わったらStable diffusion WEB UIを実行します。初回起動はとんでもなく長いです。1時間程度

```
 docker compose --profile auto up --build
```

Attaching to webui-docker-auto-1とでてスタックしてしまったのですが、調べるとDocker4.17.1だとこの現象が起こるそうで、ダウングレードしろとのことでした。

https://github.com/AbdBarho/stable-diffusion-webui-docker/issues/369

ダウングレードしたところすべて消えたため、モデルデータのダウンロードからやり直します。
既にダウンロードされているからか、1回目よりも早くダウンロードが終わりました。

WEB UIの起動中に
```
Download aborted. URI=https://github.com/AbdBarho/stable-diffusion-webui-docker/releases/download/5.0.0/xformers-0.0.17.dev449-cp310-cp310-manylinux2014_x86_64.whl
```
というエラーが出ましたが、調べるとどうやら単にタイムアウトしただけらしいので、再実行するとすんなり進みました。

WEB UIの起動が約1時間ぐらいで終わり、localhost:7860にアクセスをするとStable diffusion WEB UIが表示されました。
そのままGenerateを押すとぼやっと写真みたいなのが生成されました。
あとはCheckpoint入れてみたり、いろいろパラメーターいじったりしてみようと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238748/81c36c59-d757-73cf-d6f8-5287c54c874c.png)

おわり
VSCodeでテキストファイルのインデントに表示される縦線は要らん

# はじめに
VSCodeはデフォルト設定ではインデントの箇所に縦線(ガイド)が表示されます。
ソースコードの場合はあった方が良いのですが、テキストファイルの時は要らんと思いませんか？私は要らんと思いました。

![plaintext_indent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3143045/7ceaa61b-43da-9459-4b8b-68382774661a.png)

消す方法をググったが、なかなかヒットしなかったので(情弱)、備忘録的に記事として残すことにする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3143045/a2caaff6-86a0-f2ba-98de-72dbb46f72d3.png)
ソースコードの場合はガイドがあった方が見やすい

# 1. 設定内容

## 1.1. ファイルタイプにかかわらず何が何でも表示させたくない
1. Ctrl+, で設定画面を開く。
2. `guides-indentation`で検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3143045/6d8966e2-7034-ad6c-717f-8a62adea8c40.png)
3. Editor > Guides: **Indentation** のチェックを外す。

すべてのファイルタイプでインデントにガイドが表示されなくなります。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3143045/b4989717-a86b-82be-e1ba-02b92dbd6a0e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3143045/7eaa695d-6fb9-7e76-2d2b-ed3183e2caad.png)

## 1.2. テキストファイルのみガイド表示させたくない

1. 上記の Editor > Guides: **Indentation** のチェックは入れておく。
2. 設定(JSON)を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3143045/1fd3cec9-4ff7-73a5-fad5-15218aa02250.png)
3. settings.json に以下のような内容を追記
```json:settings.json
    "[plaintext]": {
        "editor.guides.indentation": false
    }
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3143045/fe20f249-8ac9-8362-8ee1-64f0c2327dd8.png)

以上！
Python 3 エンジニア認定実践試験勉強記録①

python実践認定試験に向けて勉強した内容を共有したいと思います。
受験をする際は是非参考にしてください。

## defaultdict-デフォルト値を持った辞書
通常の辞書は存在しないキーを参照するとKeyErrorが発生します。
defaultdictは存在しないキーを参照した時にデフォルト値が返されます。

### コード解説
```python
from collections import defaultdict

def value():
    return 'default-value'
d = defaultdict(value, spam=100)
con = d['ham']
print(con) # 存在しないキーを投げるとデフォルト値が返る
con = d['spam']
print(con)
```
実行後は下記の画像のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759758/95c76410-3e74-b6ee-5a86-7d8f875d5d58.png)
default_factory引数にintを指定するとデフォルト値が0になります。
同様にlist,dict,setを指定すると空のリスト、辞書、セットがデフォルト値となります。

### コード解説
```python
from collections import defaultdict

d_int = defaultdict(int)
con = d_int['ham'] # 存在しない場合は0をデフォルトで返す。
print(con)
d_int['ham'] += 1
con = d_int['ham']
print(con)

d_list = defaultdict(list)
d_list['a']
con = d_list['a']
print(con)

# appendで追加していく。
d_list['a'].append('b')
d_list['a'].append('c')
d_list['a'].append('a')
print(d_list['a'])
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759758/54c04bfd-036c-9e33-b03b-87986589e648.png)

defaultdictの活用方法はデータをまとめる時などに使用します。
### コード解説
```python
from collections import defaultdict

detaset = [('野球', '大谷選手'),('サッカー', '久保選手'), ('野球', '村上様'), ('野球', '吉田選手'), ('サッカー', '長友選手')]
data_list = defaultdict(list)
for category, name in detaset:
    data_list[category].append(name)

print(list(data_list.items()))

```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759758/d376b733-db21-2fdb-3e1c-67a4a42300ff.png)

itemgetter()関数→リストやタプルのソートに使う要素をインデックス値で指定できる。
インデックスを見てタプルを並び替える。

### コード解説
```python
from operator import itemgetter
data = [(1, 40, 200), (3, 10, 100), (2, 20, 300), (1, 30, 300)]
print(sorted(data)) # キーを指定しないでソート
print(sorted(data, key=itemgetter(2))) #インデックス2でソートをしてそれ以外は元の順番を保つ
print(sorted(data, key=itemgetter(2, 0))) # 最初はインデックス2でソートし数値が同じ場合はインデックス0でソートする。
```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759758/e12b44ca-d0f1-4d03-898e-733da59a48f3.png)
【はじめてのwebアプリ開発】Django + MySql + phpMyAdmin のDocker環境構築

## はじめに
Django＋MySqlを使用するDocker環境を構築したので記録として残します。開発を進める上で適宜修正していく予定です。

## 前提環境
PC: MacBook Air M2
OS: macOS Ventura Ver. 13.2.1
Homebrew: 4.0.9
Docker: 20.10.23
docker-compose: v2.15.1

## プロジェクト作成後のディレクトリ構成
プロジェクト名は`twoo`です。

``` shell
twoo
├── reservation
│     ├── __init__.py
│     ├── asgi.py
│     ├── settings.py
│     ├── urls.py
│     ├── wsgi.py
│     └── __pychache__
├── manage.py
├── Dockerfile
├── requirements.txt
└── docker-compose.yml
``` 

## PythonのDockerfile
```Dockerfile:Dockerfile(Python)
FROM python:3.11.0 
ENV PYTHONUNBUFFERED 1

RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

COPY . /code/
```

## requirements.txt
```text:requirements.txt
Django==4.2
mysqlclient
```

## docker-compose.yml
```yml:docker-compose.yml
version: '3.9'
services:
  db:
    container_name: mysql
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    healthcheck:
      test: ["CMD-SHELL", "mysqladmin ping -h localhost -u $$MYSQL_ROOT_USER -p$$MYSQL_ROOT_PASSWORD || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s
    volumes:
      - db_data:/var/lib/mysql

  django:
    container_name: django
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_ROOT_USER: ${MYSQL_ROOT_USER}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      db:
        condition: service_healthy

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    platform: linux/amd64
    depends_on:
      db:
        condition: service_healthy
    environment:
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_ROOT_USER: ${MYSQL_ROOT_USER}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    ports:
      - "3000:80"
    volumes:
      - ./phpmyadmin/sessions:/sessions

volumes:
  db_data:
```

## 参考サイト
[Django+MySQLの開発環境をdocker-composeで構築する](https://qiita.com/bakupen/items/f23ce3d2325b4491a2dd)
メモリアライメントについて調べた

メモリアライメントについて気になったので調べた。

## 実際に確認してみた

```rust:main.rs
use std::mem::size_of_val;

#[warn(dead_code)]
#[repr(C)]
struct Foo {
    a: u8,
    b: u32,
    c: u16,
    d: [u8; 3],
}
impl Default for Foo {
    fn default() -> Self {
        Self {
            a: 0,
            b: 0,
            c: 0,
            d: [0, 0, 0],
        }
    }
}

fn main() {
    let foo = Foo::default();

    let ptr: *const Foo = &foo;
    let a_ptr: *const u8 = &foo.a;
    let b_ptr: *const u32 = &foo.b;
    let c_ptr: *const u16 = &foo.c;
    let d_ptr: *const u8 = foo.d.as_ptr();

    let base = ptr as usize;

    println!(
        "foo\taddr:\t{}\tsize:\t{}",
        ptr as usize - base,
        size_of_val(&foo)
    );
    println!(
        "foo.a\taddr:\t{}\tsize:\t{}",
        a_ptr as usize - base,
        size_of_val(&foo.a)
    );
    println!(
        "foo.b\taddr:\t{}\tsize:\t{}",
        b_ptr as usize - base,
        size_of_val(&foo.b)
    );
    println!(
        "foo.c\taddr:\t{}\tsize:\t{}",
        c_ptr as usize - base,
        size_of_val(&foo.c)
    );
    println!(
        "foo.d\taddr:\t{}\tsize:\t{}",
        d_ptr as usize - base,
        size_of_val(&foo.d)
    );
}
```

```
$ cargo run
foo     addr:   0,      size:   16
foo.a   addr:   0,      size:   1
foo.b   addr:   4,      size:   4
foo.c   addr:   8,      size:   2
foo.d   addr:   10,     size:   3
```

確かにpaddingが入っていることがわかった。

| | | | |
| :---: | :---: | :---: | :---: |
| foo.a | (padding) | (padding) | (padding) |
| foo.b | foo.b | foo.b | foo.b |
| foo.c | foo.c | foo.d | foo.d |
| foo.d | (padding) | (padding) | (padding) |

なお、Rustのデフォルトでは構造体のレイアウトを変えて最適化が走り、上記のようにはならない様。（`repr(C)`を外すとわかる）

[Rustの構造体メモリレイアウト - ryochack.blog](https://ryochack.hatenablog.com/entry/2018/03/23/184943)

## なぜ必要なのか

調べていると「CPUがメモリにアクセスしやすくする」「メモリにアクセスする回数が増える」的なことが多く見られたがあまりイメージがつかないでいた。

[２．アラインメントは何か？ | データ型のアラインメントとは何か，なぜ必要なのか？](http://www5d.biglobe.ne.jp/~noocyte/Programming/Alignment.html#WhatIsAlignment) を見て雰囲気わかった気になった。

CPUとメモリ間にはデータをやりとりするためのデータバスというものがあり、一度にアクセスできるバイト数が決まっているらしい。
そのサイズにアライメントされていない場合、複数回のメモリアクセスが必要になったり、SIGBUSが発生してコアダンプする様。（CPUによって異なる様）

## Refs

- [データ型のアラインメントとは何か，なぜ必要なのか？](http://www5d.biglobe.ne.jp/~noocyte/Programming/Alignment.html)
- [バス幅の決定](http://diode.matrix.jp/R8/DESIGN/RETROF_03_04.htm)
- [Rustの構造体メモリレイアウト - ryochack.blog](https://ryochack.hatenablog.com/entry/2018/03/23/184943)
心理教育統計学　培風館　肥田野直・瀬谷正敏・大川信明先生

```r

#多群の共分散分析 p.213

GX1=c(4,8,14,11,5)
GY1=c(6,9,11,9,9)

GX2=c(5,7,12,9,12)
GY2=c(5,7,13,12,14)

GX3=c(10,8,11,4,7)
GY3=c(13,12,16,9,11)

GX4=c(11,12,8,10,7)
GY4=c(11,17,10,13,9)

GX=cbind(GX1,GX2,GX3,GX4)
GY=cbind(GY1,GY2,GY3,GY4)

K=4
N=length(GX)

#Xについて一元配置
STX=sum((GX-mean(c(GX)))^2)
SWX=sum((t(GX)-apply(GX,2,mean))^2)
SBX=STX-SWX
fX=(SBX/(K-1))/(SWX/(K*(N-1)))
qf(1-0.05,K-1,K*(N-1))

#Yについて一元配置
STY=sum((GY-mean(c(GY)))^2)
SWY=sum((t(GY)-apply(GY,2,mean))^2)
SBY=STY-SWY
fY=(SBY/(K-1))/(SWY/(K*(N-1)))
qf(1-0.05,K-1,K*(N-1))

STXY=sum((GX-mean(c(GX)))*(GY-mean(c(GY))))
SWXY=sum((t(GX)-apply(GX,2,mean))*(t(GY)-apply(GY,2,mean)))
SBXY=STXY-SWXY
bTXY=STXY/STX
bWXY=SWXY/SWX
bBXY=SBXY/SBX
aTXY=mean(c(GY))-mean(c(GX))*bTXY
aWXY=mean(c(GY))-mean(c(GX))*bWXY
aBXY=mean(c(GY))-mean(c(GX))*bBXY

SET=sum((GY-GX*bTXY-aTXY)^2)
SET=STY-bTXY*STXY
SEW=SWY-bWXY*SWXY
SEB=SET-SEW

f=(SEB/(K-1))/(SEW/(N-K-1))
qf(1-0.05,K-1,N-K-1)

```
日本語の勉強

**大人の言葉づかい**

|||
|--|--|
|①承知しました/承服いたしかねます|⑪九分九厘できています|
|②存じております/ご教示ください|⑫些少にて恐縮ですが|
|③心ばかりのものですが|⑬ご放念ください/査収・笑納・高覧|
|④失念しておりました/肝に銘じます|⑭ご内聞に願います/内々に願います|
|⑤お暇します/+お名残惜しいですが|⑮身に余るおもてなし|
|⑥感服しました|⑯ご高名は伺っております|
|⑦ 冥利につきます|⑰天衣無縫のお人柄/健啖家|
|⑧最善を尽くします/ 鋭意進めております|⑱薫陶を受け、ここまでこれました|
|⑨ご猶予いただけませんか|⑲鬼籍に入られて3年...|
|⑩織り込みずみです/心得ました|⑳有為転変は世の習いですね|
ChatGPT が苦手とするプログラム

# これは何？

なんとなく ChatGPT ですごくちゃんとしたコードが手に入ったよ、という記事が多くて、だめだったよ、という記事が少ない気がしたので、そういう記事を書いておく。

# 課題1

こんな課題を与えてみた。

> 正の整数 n, m を与えます。n<a_1<a_2<...<a_m となる整数の列 {a_i} で、逆数の合計が 1 になるものをすべて出力するプログラムを書いてください。

初心者にはぱっと書けない感じかなとは思うけど、決して高難易度ではない。という感覚。

## 回答

回答はこうなった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/4942e0ea-d967-5d2a-8c0c-5f06bcfd8e16.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/1d6d4408-6ec1-c99d-4396-e108e33e1334.png)

なんというか、拾うところがなくて論評できない感じ。
そのアルゴリズムではどうにもならないところもまずいんだけど、「# 出力」とされるものが出力されるようなコードではないところがなによりまずい。

2, 3, 4, 5, 7 の逆数の和は全然 1 じゃないし、1/2+1/3+1/4 の時点で 1を超えている。

## 拙実装

ruby で書いたら 20行ぐらい。
ちょっと自信ないけど。

```ruby
def find_series_impl(lo, m, rest_inv, list, block)
  if m==1
    block[list + [rest_inv.to_i]] if rest_inv.denominator==1
    return
  end
  b = [lo, 1+rest_inv.floor.to_i].max
  e = m*rest_inv.ceil.to_i
  (b...e).each do |x|
    find_series_impl(x+1, m-1, 1r/(1r/rest_inv-1r/x), list+[x], block)
  end
end

def find_series(n, m, &block)
  find_series_impl(1+n, m, 1, [], block)
end

find_series(*ARGV[0,2].map(&:to_i)){ p _1 }
```

実行例（抜粋）

```text
$ ruby find_series.rb 2 5
[3, 4, 5, 6, 20]

$ ruby find_series.rb 5 11
[6, 7, 8, 9, 10, 11, 12, 13, 18, 21, 40040]
[6, 7, 8, 9, 10, 11, 12, 14, 15, 24, 2772]
[6, 7, 8, 9, 10, 12, 13, 14, 15, 18, 2184]
[6, 7, 8, 9, 10, 12, 14, 15, 18, 24, 28]
```

Python にも有理数クラスがあるので大差ないと思う。

# 課題2

もう少しかんたんなのを。

> a^2+b^2=c^3 を満たす正の整数 a, b, c の組を、c の値が小さい順に 10個挙げるプログラムを書いてください。a≦b とします。

## 回答

回答はこうなった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/ae31c68e-a01c-5faa-0fd4-27e0b6c11767.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6854/84243e1c-da99-a50a-814f-b5eea4c5a23f.png)

課題1 よりは惜しいけど、全然正しくないし、そんな結果は出力されない。

勝手に上限を 100 に決めるべきじゃないし、c についてはループを回す必要はない。どうしてもループ回すにしても回す範囲が間違っている。

それにしても、 `2 6 10` とか `8 15 17` とかどっから湧いてきたんだろと思う。

## 拙実装

こちらも ruby で書いたら 20行ぐらい。

```ruby
def hoge
  (1..).each do |c|
    (1...Math.sqrt(c**3/2).ceil).each do |a|
      b=Math.sqrt(c**3-a**2)
      yield [a, b.round, c] if b==b.round && a<=b
    end
  end
end

count=0
last_c=0
hoge do |x|
  break if last_c<x.last && 10<=count
  p x
  count+=1
end
```

「c の値が小さい順に」が面倒で、同率 10位が複数あったらそれを全部出す、ということのために手間がかかっている。実際は 10位と11位は c の値が違うのでどうでもいいのだけれど。


実行例

```text
$ ruby fuga.rb
[2, 11, 5]
[5, 10, 5]
[10, 30, 10]
[18, 26, 10]
[9, 46, 13]
[26, 39, 13]
[17, 68, 17]
[47, 52, 17]
[16, 88, 20]
[40, 80, 20]
```

# 全体感想

これぐらい書けてほしいとは思ってないんだけど。

書けない場合に「書けません」とか言うこともなく、自信なさげな素振りも見せないのは困るなと思った。

この例では明確に間違っているから実際に困ることはないわけだけれど。

ChatGPT が役に立ちそうなコードを出力する場合であっても、そのコードにまずい点があったらそれを発見できる人間がいないと困るということだと思う。

計算誤差でたまに正しくない結果が出るとか、セキュリティホールとか、そういうやつ。

まだ今の所そうだということで、明日には大幅に改善しているかもしれないけれど。
Reactでコンポーネントが正しいPropsで呼び出されていることをテストする

# はじめに

Reactにおいてコンポーネントの中で異なるコンポーネントを呼び出している実装のテストを書くのに苦労したのでまとめました。

# 実装
```react:テスト対象のコンポーネント
import React from "react";
import {Child} from "Child";

export function Parent() {
    return (
        <div>
            <Child test='hoge'/>
        </div>
    );
}
```

上記のような実装に対して
Parentコンポーネント内でChildコンポーネントにtest='hoge'をPropsにして呼び出していることを確認するテストを書きます。


# テスト
```react:Parentコンポーネントのテスト
import React from 'react';
import { render } from '@testing-library/react';
import { Child } from "Child";
import { Parent } from 'Parent';

jest.mock('Child') // ①

describe('Parent component', () => {
    it('Childが正しいPropsで呼び出されていること', () => {

        const child = Child as any // ②
        render(<Parent />) // ③

        expect(child).toHaveBeenCalled() // ④
        expect(child.mock.calls[0][0]).toEqual({test:'hoge'}) // ⑤
        
    });
});
```
順を追って解説します。
①jest.mock('Child')
　ここでChildコンポーネントをmockにします。mockにすることで
　このファイル内のテストでChildコンポーネントが使用されるときは本物のChildコンポーネントの代わりに
　このｍockが使用されることになります。
　この記述はdescribeの外に記述しないとテストが通りません。

②const child = Child as any
　呼び出されていることを確認したいコンポーネントを変数に格納します。
　型推論ができないので　as anyで　コンポーネントの型チェックを無効にしておきます。
　ここでChildが代入されていますが①でChildはモックに置き換えられていますので
　代入されるのはmockオブジェクトです。

③render(<Parent />)
　Parentコンポーネントをレンダリングします。

④expect(child).toHaveBeenCalled()
　toHaveBeenCalled()で　child関数が呼び出されたことを確認します。

⑤expect(child.mock.calls[0][0]).toEqual({test:'hoge'})
　ここが一番複雑です。
　②で説明した通りchildはChildコンポーネントをmock化したオブジェクトです
　そのオブジェクトのmockプロパティはモックオブジェクトの情報を持つオブジェクトになります。
　次にcallsプロパティはモックオブジェクトが呼び出されたときに渡されたすべての引数を格納しているプロパティです。
　次に[0][0]は最初に呼び出されたときに渡された最初の引数なので[0]が2回続きます。
　最初に呼び出されたときの2個目の引数なら[0][1]となります。
しかしコンポーネントのPropsの場合Propsがオブジェクトとしてまとめて一つの引数になるので
[0][1]と書いても2つ目のpropsにアクセスすることはできません。
[0][0]と書いてオブジェクトの比較を行いましょう。




# まとめ
あまり情報がなく苦労しましたがしっかりテスト書けてよかったです。
このように子コンポーネントをmockにして
親コンポーネントでは正しく子コンポーネントを呼び出していることの確認に留めておくことで
テストファイルをコンポーネントごとに分割するのが容易になります。

間違い等ありましたらご指摘お願いします。
【WordPress】パーマリンクに勝手にindex.phpが入ってしまうようになってしまった場合の原因と解決方法

# 概要
* WordPressをテスト環境から本番環境に引っ越したら、なぜかパーマリンクに`index.php`が入ってしまうようになってしまった。ということで、その原因と解決手順を残します。

## Wordpress環境
* サーバー（AWS EC2インスタンス）
    * OS：Ubuntu 18.04.3 LTS
    * Web Server：Apache/2.4.29
    * Wordpressバージョン：6.1.1
    * PHPバージョン：7.4.33

# 解決手順
* WordPressの管理画面にログインし、「設定」→「パーマリンク設定」を選択します。パーマリンクの形式で`index.php`が入ってしまっていると思うので、任意のものを指定します。
* これで自動的に更新されますが、反映されていない場合は、`.htaccess`ファイルを手動で更新する必要があります。自分の場合は更新されなかったです。
* まずは以下のディレクトリ（sampleのところは各自置き換えてください）に移動します。

```
$ cd /var/www/html/wpsample_homepage
```

* ルートディレクトリ直下にある`.htaccess`に、警告で表示されている以下を先頭に追加します。

```.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
```

* これにより、`index.php`がパーマリンクに含まれなくなります。

# なぜパーマリンクに`index.php`が含まれてしまうようになったのか？
* ちなみに、どうして`index.php`がパーマリンクに含まれてしまうのか調べたところ、`.htaccess`ファイルが存在しない場合や書き込み権限がない場合に発生することがあるようです。パーマリンクの設定は、URLリダイレクトやURL書き換えのルールを記述する`.htaccess`と関係があるからですね。書き込み権限がなかったかもなので、その場合は、以下のコマンドを実行します。

```bash
chmod 664 .htaccess
```

* これで根本的に解決できたはずです。パーミッションは666でもいいですが、セキュリティ上の理由からあまり推奨されていないので、664が良いとされています。（所有者とグループには読み取りと書き込みの権限を、その他のユーザーには読み取りの権限を与える）

## 参考：Apacheの設定ファイルを編集する方法も
* ちなみに、Apacheの設定ファイルを編集することで解決するという記事がありました。こちらで解決できた、という記事も多いので、ご参考までに。
    * 参考：[WordPressのパーマリンクにindex.phpが入る](https://enlico.net/blog/wordpress%E3%81%AE%E3%83%91%E3%83%BC%E3%83%9E%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%ABindex-php%E3%81%8C%E5%85%A5%E3%82%8B/)
 
```apache2.conf
<Directory "/var/www/html">
・・・
　　AllowOverride None　## ここのNoneをAllにする
・・・
</Directory>

```
[AWS Q&A 365][Pinpoint]AWSのよくある問題の毎日5選 #15

# 1. Amazon Pinpointとは何ですか？
回答：Amazon Pinpointは、メール、SMS、音声、プッシュ通知などの複数のメッセージングチャネルを介して顧客と関わるのを支援するマーケティング自動化サービスです。

# 2. Amazon Pinpointの機能は何ですか？
回答：Amazon Pinpointは、オーディエンスセグメントを定義し、メッセージングキャンペーンでオーディエンスを引き付け、ユーザージャーニーを作成し、テンプレートで一貫したメッセージングを提供し、パーソナライズされたコンテンツを配信し、ユーザーの行動を分析することができます。

# 3. Amazon Pinpointを始めるにはどうすればよいですか？
回答：Amazon Pinpointを始めるには、プロジェクトを作成し、データをインポートしてセグメントを作成し、キャンペーンを作成し、キャンペーン分析を表示する必要があります。 Amazon Pinpointユーザーガイドでは、これらの手順についてステップバイステップの説明が提供されています。

# 4. Amazon Pinpointでサポートされている異なるチャネルは何ですか？
回答：Amazon Pinpointは、メール、SMS、音声、プッシュ通知などの複数のメッセージングチャネルをサポートしています。また、アプリ内メッセージやカスタムチャネルにも対応しています。

# 5. Amazon Pinpointでキャンペーンのパフォーマンスを監視および分析するにはどうすればよいですか？
回答：Amazon Pinpointは、キャンペーンのパフォーマンスを監視するための詳細な分析とメトリックスを提供します。メッセージの配信、エンドポイント、インポートジョブ、ワンタイムパスワード、イベントに関するメトリックスを表示することができます。また、CloudWatchアラームを作成し、ダッシュボードをエクスポートしてデータを分析することもできます。
M1 MacでRailsの環境構築してみた

# はじめに
M1 MacでRailsの環境構築をしました。
備忘録として残します。

:::note info
今回の環境構築はhomebrew、anyenv、rbenvがインストールされている事が前提に行われています。
そこまでの環境構築は以下の記事をご参照ください。
* [M1 Macで初めての環境構築 (homebrew, anyenv, nodenv使用)](https://qiita.com/mavengr/items/e13a4486cdeb6f447436 'M1Mac環境構築')
* [M1 MacでRubyの環境構築したらエラーで詰まった話](https://qiita.com/mavengr/items/e2658c7f58ea44b7e819 'M1MacRuby環境構築')
:::

# Rails環境構築

### Railsをインストール
`gem`でRailsをインストールします
```zsh
gem install rails
```
### インストール成功しているか確認
`gem list`でインストール済みのパッケージを表示
```zsh
# 一部分のみ表示しています
rails (7.0.4.3)
rails-dom-testing (2.0.3)
rails-html-sanitizer (1.5.0)
```

#### bundlerインストールされているか確認
`which bundle`でディレクトリを確認
以下のように表示されていればbundleがインストールされている
```zsh
/Users/ユーザー名/.anyenv/envs/rbenv/shims/bundle
```

#### 念の為bundleのバージョン確認
`bundle -v`で確認
```zsh
Bundler version 2.4.9
```
バージョンの確認ができた

## yarnをインストール
Webpackerが必須になったのでyarnをインストールする
>WebpackerがRails 6のデフォルトJavaScriptコンパイラになる

[Ruby on Rails 6.0 リリースノート](https://railsguides.jp/6_0_release_notes.html 'Rails6')より

### homebrewよりyarnをインストール
```zsh
brew install yarn
```

#### yarnがインストールされているか確認
`yarn -v`で確認
```zsh
1.22.19
```
インストールされていることが確認取れた

# Railsプロジェクト作成
任意のディレクトリで以下コマンドを実行しプロジェクトを作成する
```zsh
rails new プロジェクト名
```

### ARMアーキテクチャで動作しているか確認
作成したプロジェクトのディレクトリに移動し`uname -m`を実行
```zsh
arm64
```
`arm64`と表示されていればARM上で動作している

## Railsローカルサーバー起動
以下コマンドでローカルサーバーを起動する
```zsh
rails server
```
`http://127.0.0.1:3000`をブラウザで表示し以下の画面が表示されていれば成功

![スクリーンショット 2023-03-26 13.27.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2860566/98f79f7c-cb38-e8d5-bc90-b35d1c23f2b0.png)

# 参考記事
[M1 Mac上でRubyとRailsの開発環境構築やっていきます](https://zenn.dev/osuzuki/articles/a535b2840bbea3#%E5%8B%95%E7%94%BB(ruby%E3%81%A8rails%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89)%E3%81%AE%E7%9B%AE%E6%AC%A1 'M1MacRuby環境構築')
非常に助かりました。ありがとうございます。