OmniAICreator/Qiita-1.07M huggingface dataset:
Googleデータアナリティクス：SQLで複数のソースを組み合わせる

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/21a12cb1-a49a-802f-d903-6f68758eca0c.png" width="800">

# 表計算ソフトで複数のソースを組み合わせる


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/5a1b0ad2-c4e4-47f3-d88b-1cefd10852fb.png" width="700">

SQL には、CONCAT という 複数のソースから得た複数の文字列を 結合できる、同様の関数が存在します。 その CONCAT を使って 複数のテーブルから文字列を結合し 新しい文字列を作ってみましょう。 

この例では、ニューヨークの 公共自転車共有システムである Citi Bike の一般公開データセットを 使用します。 

最初にすべきなのは、 どの列が必要かを把握することです。 SQL で必要な文字列がどこにあるのかを 示す必要があるためです。 たとえば、このシェアサイクルの会社には 都度払いと定額払いの 2 種類のユーザーがいます。 この 2 種類のユーザーの間で どのルートが最も人気かを 調べるとします。 そのために、識別可能なルート名の 文字列を作成し、それを数えて 並べ替えられるようにします。 必要な情報は、stations と trips という テーブルにあることが分かっています。 クエリにそれを入力していきましょう。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/d313513a-b424-66fd-38f1-4593655a8d17.png" width="700">


- まず、SELECT user type と入力し 列として user type が必要であることを SQL に指示します。 
- 次に、CONCAT を使用して 各ルートの開始駅と終了駅の名前を 新しい列にまとめます。 これで、ユーザーの移動ルートを示す 1 つの列が作成されます。 CONCAT で結合した開始駅と 終了駅の名前を使用して ルート列に名前をつけるために AS route と入力します。 こうすることで、ルート名を 読みやすく、わかりやすくできます。 
- その後、SQL で移動回数を カウントすることにします。 そこで、COUNT と入力します。 アスタリスクを使えば、 選んでいるデータの行数を 数えるように指示できます。 この場合、各行が 1 つの移動を 表しているので、選んだ行を すべて数えればよいのです。 この出力を AS で num_trips と 名付けます。
- では、各ルートの平均所要時間も 求めてみましょう。 この場合、正確な平均値は必要ないので、 ROUND 関数を使って切り上げます。 ROUND を最初に置いて、括弧の中で average を使って平均所要時間を求めます。 また、この計算ではデータを 整数型にしたいので cast を as int64 と入力します。 BigQuery では 64bit の メモリシステムで数値を格納しているので、 整数(integer) の後に 64 と 入力するのです。 次に、 これを行数で割り 小数点以下 2 桁で繰り上げると指示します。 この出力は duration と名付けます。 この情報をどこに格納するかを SQL に指示する必要があります。 
- FROM を使用し、その情報を 取得する場所を指定します。
- ここでは Select 句で COUNT 関数と AVERAGE 関数を使用しているので GROUP BY を使ってサマリー行を グループ化する必要があります。 このクエリでは開始駅、終了駅、 ユーザータイプでグループ化します。 
- 最後に、ORDER BY を使って このデータをどう整理するかを指示します。 今回は、最も多い移動回数を 把握したいので、移動回数列を入力し DESC で降順に並べます。
-  最後に、上位 10 件だけを 表示したいので LIMIT 10 を追加します。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/5a1b0ad2-c4e4-47f3-d88b-1cefd10852fb.png" width="700">


このように、CONCAT のおかげで ルート名を簡単に読み取れ その場所まで把握できます。 どのようなユーザーが どのルートを利用しているかが分かるので シェアサイクル会社が 市内のさまざまな地域における ユーザー層を把握し、レンタル用自転車を もっと増やすべき場所を 特定するのに役立ちます。 

:::note info
複数のデータを組み合わせることで データの整理や分析に役立つ 新たな方法を見出すことができます。 
:::
【基本情報】用語集②

# 用語集
|用語|内容|
|-|-|
|チェックポイント|メモリ上に記憶されている更新内容を、ディスク上に記録されているデータベースに反映する時点のこと|
|NAT|プライベートIPアドレスとグローバルIPアドレスを相互に変換|
|NAPT|１つのグローバルIPアドレスで、複数の端末が同時にインターネットを利用できるようにNAT機能を拡張したもの|
|ネットワークアドレス|IPアドレスをネットワーク部とホスト部に分け、ホスト部のビットをすべて０にしたアドレス|
|サブネットマスク|IPアドレスのネットワーク部とホスト部の境界を指定するもの。サブネットマスクを2進数に変換したとき、1のビットの範囲がネットワーク部、0のビットの範囲がホスト部になる|
|論理積（AND）|入力が両方とも1のとき１、それ以外は０になる論理演算|
|公開鍵暗号方式|受信者の公開鍵で暗号化し、受信者の秘密鍵で復号|
|共通鍵暗号方式|暗号化用と復号用に共通の鍵を使用|
|チャレンジレスポンス|チャレンジとレスポンスと呼ばれる値を使った認証方式。サーバは異なる値（チャレンジ）を送信し、利用者はチャレンジに自分のパスワードをつなげてハッシュ化した値（レスポンス）を送り返す。|
|シフト演算|ビット列を右または左にずらす演算。ずらした結果、はみ出たビットは捨てられる。|
|スタック|最後に格納したデータを最初に取り出す後入れ先出し型のデータ構造|
|MTBF|システムが1度故障してから次に故障するまでの稼働時間の平均|
|MTTR|システムの修理にかかる時間の平均|
|ロールバック|トランザクション実行前の状態に復元|
|ロールフォワード|トランザクション完了後の状態に復元|
|ブルートフォース攻撃（総当たり攻撃）|１つの利用者IDに対して、考えられるパスワードを総当たりで試してみる攻撃手法。|
|FRR|False Rejection Rate:本人拒否率。生体認証で本人を誤って拒否する確率。|
|FAR|False Accept Rate:他人受入率。他人が誤って本人として認証される確率。|
|JIS Q 27001|情報システムマネジメントシステム（ISMS）の基準を定めた国際規格ISO/IEC27001を日本語化した規格。|
|SOA|Service Oriented Architecuture:サービス指向アーキテクチャ。業務過程の個々のプロセスをサービスとみなし、複数のサービスを組み合わせてシステムを構築する設計手法|
文系大学生が初めてハッカソンに参加して感じたこと

# はじめに
　ずっと一人でプログラムを勉強するのも、あまりよろしくないと思ったので、ハッカソンに初挑戦しました。この記事では、ルポ・ハッカソンということでやってまいります。

　今回はこちらのハッカソンに参加させていただきました。

https://talent.supporterz.jp/geekcamp/

# チーム開発に参加
　当初は一人で参加しようかな、と思っていました。しかしキックオフ時の「チーム開発」の勧めに打たれ、即席チームで参加することにしました（正直申し込んだ後、ものすごい不安が襲ってきました）。
　
　チームメンバーは私を含めて5人で、ハッカソンの経験をもった方もいらっしゃいました。技術レベルは高いわけでも、低すぎるわけでもありませんでした（Pythonならある程度使えるよ～という感じ）。
### チーム開発の流れ
　今回参加したハッカソンではキックオフ後（本番の2週間前）の事前開発が認められていました。私たちのチームはチーム発表当日にDiscordで顔合わせを、本番の1週間ほど前に制作物の決定を行いました。

　目指す制作物は「面接対策を行えるLINEbotとそれを広めるInstagramツール」となりました。役割の振り分けとしては、
<table>
  <caption></caption>
  <thead>
    <tr>
      <th>LINEbot</th> <th>3人</th>
    </tr>
  </thead>
  <tr>
    <th>Instagramツール</th> <th>2人</th>
  </tr>
</table>
というようになりました。私はLINEbotの方を担当しました。
　

　LINEbot制作では2~3日おきにミーティングを行い、本番を迎えました。詳しい機能などは長くなりますので、別の記事で書きたいと思います（出来たら）。一部のみですが発表資料はこんな感じです。

https://twitter.com/geek_pjt/status/1647507936695160834

　当日もかなりギリギリまで作業しましたが、とても良い経験になりました。
# チーム開発のメリット・デメリット
　ここでは（即席）チーム開発のメリット・デメリットについて考えたいと思います。
## メリット
### メリット①思いもしない化学反応
　これは即席チームに限るかもしれません。今回のチームは完全ランダムに選ばれました。そのためチームメンバー全員が初対面の状態で、それぞれ異なるバックグラウンドを持っています。大学や就職、プログラミング経験など、自分のかかわりのない分野・領域の話ができるのはとても良いことでした。また、実際に制作物を作るにあたっても「～～がいいよ」などの自分の知らない技術、トレンドを取り入れることができます。
　知り合いとのチーム開発しかしたことない方は、即席チームでの開発も刺激的で面白いかもしれません。
### メリット②チーム開発の経験
　チーム開発の経験はとても貴重なものです。インターンの募集などでもチーム開発経験の有無の記載などがあります。チーム開発では、個人開発で求められにくいコード管理やコミュニケーション能力が必要となります。ハッカソンという正式な場でチーム開発を行ったという事実は、今後プログラマーとしての成長に大きくつながることでしょう。
　ちなみに私はGitHubは使ったことがなかったので、詳しいチームメンバーに手取り足取り教えていただきました。
### メリット③制作物のスケールアップ
　チームメンバーで開発を行うということなので、単純にマンパワーが発動します。今回は5人組だったので、安直ですが労働効率が個人よりも5倍あることになります。その分、ハッカソンで作り上げる成果物のクオリティもスケールも大きくなります。
　しかし今回、最優秀賞を受賞した方は個人だったのでその限りではないですし、逆にチーム開発でしょぼいものを作ってしまうと……というのも考えられます。
## デメリット
### デメリット①情報共有の難しさ
　情報共有というのは人が集まれば必ず発生する問題です。今回の場合ですと、コード・進捗・時間の共有などがスムーズにいきませんでした。誰かが作業している間、ほかの人が何もすることがないという状況は非常にもったいないです。
### デメリット②若干の遠慮
　今回は即席チームということで、チームメンバーとは初対面でした。そのため、何かお願いしたいときや「～～したほうがいいのでは」というような提案も億劫になってしまいました。またそれぞれのレベルがわからないため、他のメンバーに仕事を回すことができませんでした。

以上が、（即席）チーム開発のメリット・デメリットです。
# ハッカソンの結果
　ハッカソンの結果ですが、なんと優秀賞をいただくことができました。:congratulations:
　正直、努力賞を逃したときは絶望していました。

https://twitter.com/geek_pjt/status/1647531907352248320

嬉しすぎて審査員様のコメントが正確に思い出せないのですが、
・制作物の完成度の高さ
・就活対策というサービスの妙
・chatGPTやWhisper、Linebotなどの要素を複合したこと
・LineとInstagramを掛け合わせたこと
が評価されたのだと思います。

# ハッカソンによって得たもの
### 貴重な経験
　今回のハッカソンを通じた人との交流、技術的な進歩、制作物を作り上げる高揚感は、普段味わうことは到底できないでしょう。そのような素晴らしい経験を得ることができました。
### 向上心
　ほかの方の作品を見る中で、すごい成果物やとても高度な技術を使われているのを見てとても驚きました。そのような同世代の方々を見て、自分も負けられないぞ、という気持ちがふつふつと湧いてきました。きっとプログラミングを勉強する原動力となることでしょう。

　他にも言葉にしきれないほどいっぱいのことを得ることができました。（経験したらきっとわかるはずです）

# 今後自分に必要な知識
　今後の自分に必要な知識はこんな感じです。
###### ・フロントエンド
###### ・GitHub
###### ・Python以外の武器になる言語
###### ・チームでの開発手法
　いずれ来るであろうハッカソンに備えてこれらを勉強していきたいです。

# 最後に
　初めてのハッカソンということで、最初はとても怖かったのですが、いざ参加してみると違った世界が見えました。あの時、参加申し込みをしてなかったらと思うとぞっとします。
　次にマンスリーハッカソンに出られるのは、早くても2か月ほど後（人気すぎ）なので、それまでは牙を研いでようと思います。
　東京で開かれるアドバンスにつきましては（まだ詳しくはわかりませんが）、参加しようと思います。追加開発もします。
　
　最後になりますが、2週間支援していただきましたチームメンバーの皆様、サポーターズ様、スポンサー様、本当にありがとうございました。今後ともよろしくお願いします。
django-allauth で、認証済みのユーザーに別の認証を追加（統合）する方法

　検索しても「認証機能自体を『追加』する」記事しかヒットしなかったり、ChatGPT 4 君に聞いても上手く動かなかったりして、けっこう試行錯誤したので、誰かの助けになるかなと思って記事を書きます。

# 背景

　イーロンが Twitter の方針をアレコレ変えるせいで、半永続的なインフラと思われていた Twitter の OAuth 認証がマジで使えなくなる危険が出てきました。万が一の事態に備えて、別の認証手段を追加し、既存ユーザーにそれを統合させる手段を用意しておいた方が安全です。

　本記事では Discord 認証を想定しています。

# Discord 認証を追加

　この記事が必要になる方は、既に他のサービスでの認証は実装していると思われるので、細かい説明は省きますが、Discord でも同様にプロバイダーの追加や、コールバック URL の設定などをしていきます。

　この時点で認証はできますが、**認証済のユーザーが Discord ログインを行った場合、新規ユーザーとして登録されてしまう**、という問題が起きます。

　理想は、

・認証済み→統合される
・認証済みでない→新規ユーザーとして登録

　なので、これはちょっと期待した動きではありません。

# ChatGPT 君に聞こう

　こういう時は ChatGPT に聞くに限ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/e13dcabc-97bb-1ad1-ac1b-c5337c5cd8d7.png)
　ふむふむ、アダプターというのを設定すればいいのね。

　`settings.py` に以下を追記した上で、

```python:settings.py
AUTHENTICATION_BACKENDS = (
   ...
   'myapp.adapters.CustomAccountAdapter',
   'myapp.adapters.CustomSocialAccountAdapter',
   ...
)
```

　`adapters.py` を作って以下をコピペ。

```python:adapters.py
from allauth.account.adapter import DefaultAccountAdapter
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter

class CustomAccountAdapter(DefaultAccountAdapter):
    pass

class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):
    def is_auto_signup_allowed(self, request, sociallogin):
        return False

    def save_user(self, request, sociallogin, form=None):
        if request.user.is_authenticated:
            sociallogin.connect(request, request.user)
            return request.user

        return super().save_user(request, sociallogin, form)
```

　結果：**解決せず**

　おいおい、AI さんよお……。ちゃんと仕事してくれなきゃ困るぜ。

## 解決手段

　コードをよくみると、ChatGPT 君は `save_user` の段階で認証済みかどうかをチェックしているのですが、これは認証済みであっても匿名ユーザー扱いになってしまうようです。いろいろ調べた結果（海外のどっかの掲示板だっけ？）、`pre_social_login` というメソッドをオーバーロードすると、既存ユーザーの認証具合を調べられるようです。

　結果的に、以下のようにコードを改造するとうまくいきました。

```python:adapters.py
from django.http import HttpResponseRedirect
from django.urls import reverse
from allauth.account.adapter import DefaultAccountAdapter
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter

class CustomAccountAdapter(DefaultAccountAdapter):
    pass

class CustomSocialAccountAdapter(DefaultSocialAccountAdapter):

    def pre_social_login(self, request, sociallogin): 
        # print(request.user)
        if request.user.is_authenticated:
            sociallogin.connect(request, request.user)
        return

    def is_auto_signup_allowed(self, request, sociallogin):
        return True

    def save_user(self, request, sociallogin, form=None):
        if request.user.is_authenticated:
            sociallogin.connect(request, request.user)
            return request.user

        return super().save_user(request, sociallogin, form)
```

　さらっと、`is_auto_signup_allowed` が `True` を返すようにしていますが、これにしないとメールアドレスを記入する画面とかが挟まれるようになります。後半の `save_user` の `if` 文は無意味になってる気がしますが、まあ**とりあえずこれで動いている**以上、余計な改変や解説はせずにそのまま載せています。詳しい人から見たら無駄な実装や間違いがあるかもしれませんが、とりあえず解決事例を報告した方がいいと思ったので。

# 注意事項

　これをやる場合、既に連携しているソーシャルプロバイダを更に追加しようとするとアサーションエラーが起こります。例えば、Discord に認証していない時のみ、ブラウザ上で「Discord 認証」ボタンを押せるようにするとかすれば、普通のユーザーがトラブルになることはないと思います。
Go言語のポインタレシーバと値レシーバの使い分け

### はじめに
Go言語では、メソッドの実装時にポインタレシーバと値レシーバのどちらを使うかが重要な選択となります。
この記事では、それぞれの使い分けについて確認していきたいと思います。

### ポインタレシーバについて
ポインタレシーバは、メソッドが呼び出される際に、構造体のアドレス（参照）が渡されます。これにより、メソッド内で構造体のデータを直接変更することができます。また、メソッドの呼び出しに伴って構造体がコピーされないため、メモリ使用量が削減されることがあります。

#### メリット
1. メモリ使用量が削減される: ポインタレシーバを使用すると、構造体がコピーされないため、パフォーマンスが向上し、メモリ使用量が削減されます。
2. 構造体のデータを変更できる: ポインタレシーバを使用すると、構造体のデータを直接変更できます。これにより、副作用を持つメソッドを実装することができます。

#### デメリット
1. 構造体の内容が変更される: ポインタレシーバを使用すると、メソッド内で構造体の内容を変更すると、オリジナルのデータも変更されます。これは、構造体のコピーが行われないためです。

### コードでの確認
以下の例では、銀行口座を表す`Account`構造体があり、`Deposit`メソッドを実装しています。
このメソッドは、ポインタレシーバを使用しています。

```go
package main

import "fmt"

type Account struct {
	owner   string
	balance float64
}

// ポインタレシーバを使ったDepositメソッド
func (a *Account) Deposit(amount float64) {
	a.balance += amount
}

func main() {
	account := Account{owner: "Goher", balance: 1000.0}

	// ポインタレシーバを使った場合
	account.Deposit(500)
	fmt.Printf("After deposit with pointer receiver: %v\n", account) // {Goher, 1500.00}
}
```
この例で、`Deposit`メソッドを使って口座に500ドルを預けた後、残高が正しく更新されています。
ポインタレシーバを使っているため、オリジナルの構造体のデータが直接変更されています。

### まとめ
ポインタレシーバは、メモリ効率を向上させるためや、構造体のデータを変更するメソッドを実装する際に有用です。ただし、オリジナルのデータも変更されるため、その点に注意が必要です。一般的に、以下のケースでポインタレシーバを使用することが推奨されます。

1. 構造体が大きく、コピーによるパフォーマンスの低下が懸念される場合
2. メソッド内で構造体のデータを変更する必要がある場合

これらのポイントを考慮して、ポインタレシーバを適切に使用することで、効率的かつ安全なアプリケーションの実装が可能になります。

https://go.dev/tour/methods/4
AccessVBAでIDを1から最後まで順に取得する

AccessでExcelみたいに1行目から順にデータがなくなるまで繰り返し処理するようなプログラムをAccessで実現する方法


***
テーブル名
| ID| フィールド1| フィールド2|
|:-:|:-:|:-:|
| 1| a| z|
| 2| b| y|
| 3| c| x|
| 4| d| w|
***

```vb:vba
Sub Test()
    Dim i
    i = 1
    Do While DLookup("ID","テーブル名","ID=" & i) <> ""
       Debug.print DLookup("ID","テーブル名","ID=" & i)
       i = i + 1
    Loop
End Sub

```

```:実行結果
1
2
3
4
```

上の例だと、DLookupを使うことで「テーブル名」という名前のテーブルから「IDのフィールドの値がi」である「IDのフィールドの値を取得」することができる。
該当するIDがないときは「Null」を返すことを利用し、IDを1から順に最後まで繰り返し処理することが可能
魔法使いが繁栄しないワケ

魔法使いが繁栄しないのはズバリ職業がないからである。

人間は社会において職業を持つことにより、コミュニケーションが生まれる。
魔法使いはいわゆる作業の自動化が可能だ。
彼らにコミュニケーションは必要なのか、生きるうえで他の魔法使いと協力する必要はあるか。否。

ChatGPT などが生まれた今でも全自動などの技術は決して生まれない。
そして生まれるべきなのだろうか。
生まれた先の未来にも期待を寄せながら
Railsで「お気に入り機能」をAjaxを用いて実装する

今回は、Railsでお気に入り登録機能をAjaxを使って非同期処理化していきます。

### おおまかな手順
1. いいねボタンに`remote: true`　を追加する
2. ビューファイルに目印となる`id`を付与する
3. create, destroyアクションの`redirect_back ...`を削除する
4. Ajax用のcreate, destroyファイルを作成する



### いいねボタンに`remote: true`　を追加する
いいねボタンは複数のビューで扱うためパーシャルファイルとして定義し、
・ ユーザーがログインしているか
・ ログインユーザーの場合は、いいねしている楽曲があるか
上記2つの条件をもとに分岐表示をしています。
[![Image from Gyazo](https://i.gyazo.com/15b607b562ddcc39e6c9420653109389.png)](https://gyazo.com/15b607b562ddcc39e6c9420653109389)


以下の`link_toタグ`に`remote: true`を追加し、Ajaxで処理できるようにする。
```ruby:app/views/likes/_like_button.html.erb
<% if logged_in? && current_user.liked_by?(music: music) %>
  <%= link_to like_path(music), method: :delete, remote: true do %>
    <i class="fa-solid fa-heart" style="color: deeppink;"></i>
  <% end %>
<% else %>
  <%= link_to likes_path(music), method: :post, remote: true do %>
    <i class="fa-regular fa-heart"></i>
  <% end %>
<% end %>
```

### ビューファイルに目印となる`id`を付与する
Ajaxを使用して、処理する場合対象となるHTMLファイルに目印となる`id`を指定してあげる必要がある。
今回は`<div id="favorite_button_<%= music.id %>">`を指定しました。

```ruby:app/views/shared/_music_view.html.web
<div class="max-w-screen-2xl py-5 md:px-6 mx-auto">
         
       #省略

    <div class="flex items-center">
      <div id="favorite_button_<%= music.id %>">
        <%= render '/likes/like_button', music: music %>
      </div>
    </div>
    <div class="text-center">
         <p class="text-md flex flex justify-center">該当する楽曲が見つかりませんでした。</p>
      </div>
    <% end %>
</div>
```

### create, destroyアクションのredirect_back ...を削除する
`redirect_back`を削除することで、処理がJSファイルへと移動します。

```ruby:app/controllers/likes_controller
class LikesController < ApplicationController
    
     #省略

  def create
    @like_music = Like.new(user_id: current_user.id, music_id: params[:format])
    @like_music.save
    redirect_back fallback_location: search_result_index_path #ここを削除する
  end

  def destroy
    @like_music = current_user.likes.find_by(music_id: params[:id])
    current_user.unlikes_music(@like_music)
    redirect_back fallback_location: search_result_index_path, success: t('.success') #ここを削除する
  end
end
```

### Ajax用のcreate, destroyファイルを作成する
最後にcreate, destroyアクションで使用するJSファイルを作成します。
作成する際は、`views/コントローラー名/アクション名.js.erb`でファイルを作成するので注意！


```ruby:app/views/likes/create.js.erb
id = "<%= @like_music.music_id %>";
target = document.querySelector(`#favorite_button_${id}`);
html = "<%= j(render 'likes/like_button',  music: @like_music.music_id) %>";
target.innerHTML = html;
```

```ruby:app/views/likes/destroy.js.erb
id = "<%= @like_music.music_id %>";
target = document.querySelector(`#favorite_button_${id}`);
html = "<%= j(render 'likes/like_button',  music: @like_music.music_id) %>";
target.innerHTML = html;
```

ここまでファイルを変更すれば、楽曲をお気に入り登録した際に画面が再レンダリングされることなく、ハートマークの色が変わることが確認できると思います。
Macのシェル・ターミナル

**Macのシェル・ターミナルについて**
>シェルスプリクトを作成しようとした際、そもそもMacのターミナルでは、
シェルはbashではなく、**zsh**という点でつまずいたのでメモ記事にする

**ターミナルとは**
macOSにコマンドラインインターフェースを提供するアプリ
初期から設定変更等していなければ、以下で確認できる
Dock >Launchpad > その他 > ターミナル
>usernameという名前のユーザがzshシェルを使用している場合、以下のようなプロンプトが表示される

```
Last login: Mon Apr 17 00:00:56 on ttys001
username@MacBook-Pro ~ %
```

**そもそも、そのzshシェルでいう”シェル”って、、、？**

**シェル**:コンピュータのOSを構成するソフトウェアの一つで、
利用者からの操作（コマンド）の受付や、そのOSからの実行結果を表示するもの

なお、次のコマンドで今、使用している**シェルの確認**ができる
```
username@MacBook-Pro  ~ % echo $SHELL
/bin/zsh
```
>macの場合、デフォルトは"zsh"、標準とされるのは”bash”で、
"zsh"の他にも、”tcsh”や”sh”などがある

Macは、もともとデフォルトシェルに”bash”を採用していたらしいが
Catalina世代からデフォルトシェルをzshに変更したらしい。

:::note
以下、おまけ
:::
**bash**
Linixで標準採用されているシェルで、
UNIX上の一番古いシェル：”sh”に拡張機能を追加したもの

**zsh**
"sh","bash","csh","tcsh"の機能をほぼ網羅している
また、表示や操作についてのほどんどの要素がカスタマイズできるらしい。
Lambdaでprismaを利用する

# prismaによるDBへの登録処理の構築
Typescriptを利用しているのでprismaを使って　DB(mysql)へ個人情報を登録するロジックです。

Lambdaでprismaを使う場合、Lambda関数にPrismaモジュールを一緒にデプロイする方法とLambdaLayerを使ってprismaを別レイヤーにアップロードする方法があります。

Lambda関数にPrismaモジュールを含めてしまうと結構な容量になるので工夫が必要です。
また、何も考えずにLambda関数をデプロイすると、schema.prismaファイルが見つからないとか`prisma generate`を実行してくださいなどのエラーが発生します。

これはprismaモジュールを動かすために以下もデプロイファイルに含める必要があるためです。
* Prisma Engine
* Prisma Schema

Lambda関数デプロイ時にPrismaモジュールを含める方法は以下の記事が参考になります。

https://kiririmode.hatenablog.jp/entry/20220619/1655622443


## AWS CDKを使ってLambdaLayerを作成する方法
CDKでprismaのLambdaLayerを作成する場合は詳しい方法は以下のサイト(英語)に書かれています。

https://medium.com/ama-tech-blog/deploying-prisma-with-aws-lambda-layers-in-cdk-10608f5598c5

## Serverless Frameworkを使って作成する方法
Prismaの公式サイトではServerlessFrameworkを利用する方法が紹介されています。

https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-aws-lambda

## Amplifyを利用する方法
Amplifyを利用してamplify add functionでLambdaLayerを作成し、そこにprismaのインストールを行う方法です。

https://aws.amazon.com/jp/blogs/mobile/how-to-use-lambda-layers-with-the-amplify-cli/

prisma及びLambdaLayerについての知識が必要になります。

# まとめ
現在は、複数のLambda関数から同じDBに接続する用件がないため、Lambdaレイヤーの利用までは至っていませんが、そのうち必要になりそうですのでその際にはこれらの情報を参考にしたいと思います。
AWS Lambdaの開発環境を整える

# Docker-Lambdaの利用
Lambda関数の開発時に、都度Cloudにプッシュしてテストするのは非効率です。
ローカルにLambda関数を動かすDockerを構築してくれるコンテナをOSSとして提供してくださっているのでこちらを利用しています。

https://github.com/lambci/docker-lambda

https://qiita.com/sentorei/items/3c8f7752fdae8f185812

# テストプロセス
最終的に以下のような構成にしてテストを進めました。

![スクリーンショット 2023-04-17 11.42.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1926542/f7b14ad7-73dd-9f13-96d6-0893c6ed7445.png)

1. jestを用いて単体テスト
1. lambda-dokerでLambdaハンドラをテスト
1. Lambda関数をデプロイし、マネジメントコンソールからテスト
1. APIGatewayをデプロイし、マネジメントコンソールから結合テスト

jestでテストする際に環境変数を利用したいと思ったのですがそれについては別の記事で記載しましたのでご参照ください。

https://qiita.com/itty-star/items/93ecd54b4e8d1075d674

# フロントエンド開発
パソコン上に環境を構築して開発を進めていたのですが、過去にパソコンが故障して困ったことがあったので、開発環境は徐々にCloud9に移行を進めているところです。
そのため、Cloud9上にnodejs、typescript、Amplify、Nuxtjsなどをインストールして開発をする形にしています。

注意点としてCloud9上でAmplifyを動かし、がんがんnodejsを使おうと思うとEBSは32GBくらいは必要です。

# AWS Amplifyの利用
Amplifyを利用することで以下の作業が楽になります。

* フロントエンドファイルのS3へのアップロード
* CloudFrontの設置(カスタムドメインの設定は別途必要)
* RESTAPIのデプロイ(APIGateway、Lambda)
* 認証認可にAmazonCognitoを利用する

# まとめ
以上の構成で今のところ落ち着いています。
CI/CD環境も少しづつ改善しながら効率化していきたいと思います👍
「WolframAlphaのEqual」と「sympyのEq」を調べてみたい。

オリジナル
WolframAlphaのドキュメントより

https://reference.wolfram.com/language/ref/Equal.html

sympyのドキュメントより
**docをさがしています。**

https://www.programcreek.com/python/example/52232/sympy.Eq

# WolframAlphaで
勉強中

# sympyで 

```python
from sympy import *
A,B,C=symbols('A,B,C',real=True,positive=True)
print("#",Eq(3-2,1))
print("#",Eq(3-2,7))
print("#",Eq(A-B,C))
print("#",Eq(A-B,C).subs({A:3,B:2,C:1}))
print("#",Eq(A-B,C).subs({A:3,B:2,C:7}))
# True
# False
# Eq(A - B, C)
# True
# False
```

```python
from sympy import *
x,y=symbols('x y',real=True)
myEq=Eq((x-y)**3,x**3-3*x**2*y+3*x*y**2-y**3)
print("#",myEq)
print("#",myEq.lhs)
print("#",myEq.rhs)
print("#",myEq.subs({x:3,y:2}))
#
print("#",myEq.lhs.subs({x:3,y:2}))
print("#",myEq.rhs.subs({x:3,y:2}))
print("#",Eq(myEq.lhs.subs({x:3,y:2}),myEq.lhs.subs({x:3,y:2})))
# Eq((x - y)**3, x**3 - 3*x**2*y + 3*x*y**2 - y**3)
# (x - y)**3
# x**3 - 3*x**2*y + 3*x*y**2 - y**3
# True
# 1
# 1
# True
```
①私の環境は,pycharmです。
②よく聞くのは、Jupyterです。
③web上で、上記のソースを「SymPy Live shell」に、コピー貼り付けでもできました。
黒背景の右上に、マウスを移動すると、コピーマークが発生します。資源の無駄使い。ごめんなさい。
④web上で実行時間は、約1分です。グラフもそれらしく出力されます。

https://live.sympy.org/

???　タブレット環境で、コピー貼り付けが実行できませんでした。???
Amplify&Lambdaにおける環境変数戦略

Lambdaの環境変数を使用しようと思うと色々と工夫が必要になります。
私なりの環境変数の管理方法をメモしておきます。

# 利用環境
* nodejsでLambda関数を構築
* 実際のLambda関数にはAmplifyでデプロイ
* ローカルではjestでテスト

試行錯誤した結果、結果的に以下のような構成にしています。

![スクリーンショット 2023-04-17 11.42.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1926542/b35a03b8-03e5-327a-dbac-0c3ad7037088.png)



# Amplifyでの環境変数利用
amplify add functionでLambda関数を作成する際に環境変数の設定が可能です。
設定した環境変数は基本的にprocessで取得可能になります。

```typescript
const parameter = process.env.PARAMETER
```

また、SSMに暗号化させて保存することもできます。
その場合はaws-cdkを用いて取得する必要があります。

```typescript
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"
const config = { region: "ap-northeast-1" }
const client = new SSMClient(config)
const input = {
    Name: "PARAMETER_NAME",
    WithDecryption: true,
}
const command = new GetParameterCommand(input)
const response = await client.send(command)
```

このようにAmplifyを利用すれば、商用環境とテスト環境で環境変数を使い分けることが可能です。

# jestでテストするときにどうするか？
しかし、amplifyでデプロイする前にローカルでjestを利用して単体テストを行おうと思うとAmplifyで設定した環境変数はjest利用時には読み込まれません。
そのため、jest起動前に都度環境変数をprocess.envに設定してあげる必要があります。

これについてはこちらの記事を参考にしながらjest.config.jsを設定し、テスト前にスクリプトを起動するようにしました。

https://zenn.dev/ncdc/articles/jest-environment

また、jestでテストする際は自動的にprocess.env.NODE_ENVに'test'が設定されますので、単体テスト時のみに何かしらの処理を行いたい場合に利用できます。

```typescript
if(process.env.NODE_ENV == 'test'){
    // 単体テスト時にのみ行いたい処理、例えば・・・
    console.log('debug・・・')
}
```

これでjest利用時も環境変数を利用できます。

# まとめ
以上の方法でAmplify,jestを利用して環境変数をコントロールできるようになりました。
Lambda関数の開発はまだまだベストプラクティスが確立されていないようで色々工夫が必要そうです。
効率的な独学でのWeb開発：シンプルなライブラリと生成AIの活用法

現在のプログラム開発では、適切なライブラリを選択するのに時間がかかっている。
決定してからも、ライブラリの特定の部分の使い方を調べる必要がある。
特定用途のライブラリは複雑で、ソースファイルが大きく、完成度が低い問題も抱えている。バグを回避するために、特定のテクニックが必要になる。
例えば、みんなが使っていない使い方は避けるなど。

このため、実績があり、多くの人が使っているライブラリを選ぶという矛盾が生じ、進歩を阻害することがある。

私にとっての問題は、ライブラリの使用が自分の成長に必ずしもつながらないことである。
高度な抽象化がなされたライブラリを使用して特定用途のアプリケーションを作成することが、私の成長につながると考えている。

スキルが向上した後にライブラリを使うことで、問題を回避しやすくなる。
ライブラリの設計思想を理解することで、その長所や短所を把握しやすくなる。

そのため、単純なライブラリだけを使用してプログラムを作成することは重要だと思う。
この際、ChatGPTのような生成AIを使用すると、学習速度が向上する。
プログラムを作成するよりも、読むことに重点を置くことで学習速度を上げたい。

自力でプログラムを作成することも重要だが、時間がかかりすぎる。

ChatGPTにプログラムを作成してもらいそれを理解することを繰り返しながら、階層を上げて特定用途のライブラリも取りれていきたい。

階層を上げるとは、最初は抽象度が高いライブラリだけを使い理解できたら、抽象度の低いライブラリも徐々に取り入れていく。

最新のライブラリを使いたいと思いがあり、それを理解して使いこなすには私のような新規参入者にとっては、上記のような過程が必要である。

本で勉強しようとすると、歴史的な過程などを追って勉強する必要がどうしても生じる。
だから、自分にとって直接的には必要でないことも学ばなければならない。

このようなアプローチを通して、勉強をする必要がある。
DockerのMySqlコンテナへFlaskで接続して、Select表示させる

### ■ DockerでMysqlコンテナ作成

```
# コンテナイメージ ダウンロード
＄docker pull mysql

# コンテナ作成
＄docker create --name tossymysql -e MYSQL_ROOT_PASSWORD=root -p 33306:3306 mysql

# コンテナ開始
＄docker start tossymysql

```
### ■ ・flaskファイルを をwindows D ドライブ直下へ作成（コマンドプロンプト）

```
＄ cd /d d:
＄mkdir flask_app_test
＄cd flask_app_test
＄type nul > app.py
```

### ■ Flask ソース
```python

from flask import Flask
import mysql.connector

# === DB 接続情報

"""

テスト用 DB & テーブル

CREATE DATABASE sample_db;
USE sample_db;

CREATE TABLE users (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
email_address VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);

use sample_db;
insert into users (name, email_address) values
('John Smith', 'john@example.com'),
('Jane Doe', 'jane@example.com'),
('Bob Johnson', 'bob@example.com'),
('Alice Lee', 'alice@example.com'),
('Mike Davis', 'mike@example.com');

"""


def conn_db():
    conn = mysql.connector.connect(
        host='127.0.0.1',
        user='root',
        password='root',
        port='33306',
        # db='flask_db_01'
        db='sample_db'
    )

    return conn


# SQL 文
sql = 'SELECT * FROM users'

try:
    conn = conn_db()
    cursor = conn.cursor()
    cursor.execute(sql)
    rows = cursor.fetchall()
except(mysql.connector.errors.ProgrammingError) as e:
    print('エラー')
    print(e)

print('select開始')

for r_val in rows:
    print(r_val[0], r_val[1], r_val[2])


```
【GROWI】設計書をMarkdownで管理したい！

# はじめに
設計書をExcelやWordを用いて管理していると不便だと思うことが多々あります。
* 探したい情報がどこに記述されているかわからない。全体から検索ができない。
* 誰がどこを変更したのかわからない。変更履歴が管理しづらい。
* ファイルサイズが大きいと処理が重い。強制終了して編集内容が消えることも。

こういった点を解消するため、設計書をMarkdownで管理したいと思い立ちました。
そして、利用できそうなツールを調査してみたところ「GROWI」が見つかりました。

# 「GROWI」とは？

MITライセンスで公開されているオープンソースソフトウェアです。
有料でクラウド版も提供されていますが、オンプレ環境が用意できれば無料で利用することができます。

https://growi.org/ja/

他にも様々なツールがありましたが、以下の点からこのツールを選定しました。

* 無料で利用できる
* 日本語対応している
* 全文検索や更新履歴が利用可能

# インストール

まずは個人での試用であるため、Dockerを用いてインストールしました。
以下のコマンドを実行するだけでセットアップ完了となり、非常に簡単でした。

```powershell
git clone https://github.com/weseek/growi-docker-compose.git growi
cd growi
docker-compose up
```

詳しい内容は以下のサイトに記載されています。

https://docs.growi.org/ja/admin-guide/getting-started/docker-compose.html

# 試用してみて良かったと思った点

## Markdownの編集がしやすい
左画面で編集しながら右画面にプレビューが表示されるので体裁が整っているかリアルタイムで確認ができます。  
またエディタにテーブルやリンク等の入力ボタンが用意されているため、Markdownに慣れていない人にとっても扱いやすいと感じました。
さらにテンプレートを保存して利用できるため、設計書で様式を統一しなければならない際に利用できそうです。

## diagrams.net（Draw.io） や PlantUML が利用可能
シーケンス図やクラス図の作成に用いられる作図ツールが利用できます。
AWSの構成図などの作成にも役立ちそうです。

## 全文検索が可能

高速検索を可能とする検索エンジン（Elasticsearch）を利用した検索が可能であるため、探したい情報をすぐに見つけることができます。
ExcelやWordで設計書を管理する際に感じていた不便な点が解消されそうです。

# 課題

## Markdown形式での全体エクスポートができない

確認した限りでは個別のファイルはMarkdown形式でエクスポート可能ですが、一括で全体のエクスポートはできないようです。  
会社のルール上、社内のファイルサーバにMarkdownのファイルを残しておく必要あるので、別途方法を検討しなければなりません。

# おわりに

課題は残りましたが、「GROWI」は設計書をMarkdownで管理するための有用なツールであると思いました。  
個人の範囲でした試用できていないので、ぜひ次回のプロジェクトで活用していきたいです。
extends とはなにか

## クラスの継承を行い、スーパークラスのフィールドやメソッドを継承

- クラスの継承を行うためのキーワード

あるクラスが別のクラスを継承することで、継承元のクラスのフィールドやメソッドを継承することができる
また必要に応じてオーバーライド（上書き）することもできる
→直接使用することが可能

継承元クラス：スーパークラス、親クラス
継承されるクラス：サブクラス、子クラス

- 1つのクラスを継承することができる

クラスの継承は階層的な関係を作成

既存のクラスを拡張するために使われる
Google Cloud ShellにphpMyAdminをインストール

```bash
wget https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-all-languages.zip \
  && unzip phpMyAdmin-5.2.1-all-languages.zip \
  && cd phpMyAdmin-5.2.1-all-languages \
  && cp config.sample.inc.php config.inc.php \
  && echo '$cfg["AllowArbitraryServer"] = true;' >> config.inc.php \
  && echo '$cfg["blowfish_secret"] = "JOFw435365IScA&Q!cDugr!lSfuAz*OW";' >> config.inc.php \
  && php -S localhost:8080
```

簡単です。Cloud SQLをご利用の場合は、IP制限緩和もお願いします
「マーケティングデータ共有」

[Pardotの質問と回答をまとめに戻る](https://qiita.com/Keiji_otsubo/items/a3ccd1370697dd914723)

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


テクサポ 日本 4月10日 13:35 より

「マーケティングデータ共有」機能とは、Account Engagement と連携している Salesforce 組織において、どの Salesforce リードまたは取引先責任者、商談、その他カスタムオブジェクト（連携設定をしている場合）のレコードを、どの Account Engagement ビジネスユニットに同期させるか、を制御する機能です。
 

Account Engagement Advanced エディション以上で利用可能な機能となりますが、例えば B2B と B2C などビジネスモデルや、製品・サービス取扱部署などの単位でビジネスユニットを分けて利用している際に、運用方法に併せて Salesforce 顧客レコードなどの同期先ビジネスユニットを指定できます。

または、どのビジネスユニットとも同期させない、という制御もできますので、マーケティング活動において必要な分の顧客データのみをプロスペクトレコードとして作成させる運用も可能となります。

+ [サクセスナビ：Account Engagement マーケティングデータ共有機能について](https://successjp.salesforce.com/article/NAI-000695)
+ [ Account Engagement (旧Pardot) に関するよくある質問のリンク集 ](https://help.salesforce.com/s/articleView?id=000353695&type=1&language=ja)
【Rails】refileで画像投稿機能作成

## この記事の目的
現在学習中のRailsについての理解とアウトプット、振り返り用
Railsのユーザ認証についてまとめています

## 前提条件
下記のインストールが完了していること
●Railsでプロジェクトが作成できていること

こちらについては[Railsプロジェクト作成からMVCまで](https://qiita.com/pikimaru/items/e7e80c003d8e9729b4ea)で記載しています。

## リファイルとは
- ファイルのアップロード先を柔軟に設定できる
- 簡単に組み込める
- 画像のサムネイルを生成できる

[refileのGitHubページはこちら](https://github.com/refile/refile#1-backend)

## imagemagickとは
ImageMagick（イメージマジック）は画像を操作したり表示したりするためのソフトウェア。
GIF、JPEG、PNG、PDF、TIFFなど100種類以上の画像ファイルフォーマットに対応しており、プログラム上からの画像の変換・編集などに必要な多数の機能を備えている。
「画像のアップロード → サムネイル生成 」など、画像を加工・変形するWEBサービスを組みたい場合に使う。

## imagemagickインストール
```
$ sudo apt-get update
$ sudo apt-get -y install imagemagick libmagick++-dev
または
$ brew install ImageMagick
```
macOSを使用している場合は`command not found`が出たので`brew`の方を使用しました。

## Gemfileにユーザー認証用のgem追加
Gemfileの最後に以下を追加する
deviseとはrailsで作ったwebアプリケーションに簡単に認証機能を実装できるgemのことですlogin,logout機能のこと

```Gemfile
#　ファイルアップロードを簡単に実装するためのGem,Githubのリポジトリからインストールされる。
gem "refile", require: "refile/rails", github: 'manfe/refile'
#　ファイルを自動的にリサイズするために使用されるRefileのアドオンGem
gem "refile-mini_magick"
```
### bundle install
```
$ bundle install
```

## Modelにattachment追加
対象のModelに`attachment :image_id`を追加する
今回はuserモデルに作成しており、ユーザーテーブルのカラムに`profile_image_id`を指定しているので`attachment :profile_image`としています
<font color="Red">※カラム名が`profile_image_id`ですが`id`をつけないところが注意点</font>
```app/models/user.rb
class User < ApplicationRecord
  # ユーザー認証機能を有効化するためにdeviseを使用
  # 有効にしたい機能を引数に指定
  devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable

  # 画像アップロードのためgemを使用してattachmentメソッド使用
  # profile_imageカラムに画像をアップロードするための設定
  attachment :profile_image
end
```

## ファイルアップロードのフォーム
対象の場所に`<%= f.attachment_field :profile_image %>`を記載する
今回はユーザー一覧ページにユーザ画像を出すため`app/views/users/index.html.erb`に記載していきます
<font color="Red">※こちらもカラム名が`profile_image_id`ですが`id`をつけないところが注意点</font>
```app/views/users/index.html.erb
<section class="section">
    <div class="container">
        <div class="columns is-multiline">
        <% @users.each do |user| %>
            <%= attachment_image_tag user, :profile_image, fallback: "no-image.png" %>
            <%= user.username %>
        <% end %>
        </div>
    </div>
</section>
```
現在画像は登録していないので`fallback`に設定している`no-image.png`が出ました
![スクリーンショット 2023-04-09 22.41.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462658/202d14cd-b23b-4c65-de9d-6d8dd13512dc.png)
メール-to-ケース 新しいスレッドの動作


テクサポ 日本 4月14日 15:10 より

+ [新しいメール-to-ケースの作成時にインライン画像が削除される](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007TqjKg)


# 説明

メール-to-ケースのこれまでの動作では、Salesforce が受信したメールの件名または本文の Ref-ID（ref:XXXXX）という文字でどのケースに紐づくかを判定しておりました。そのため Ref-ID を消してしまうと既存のケースに紐付きませんでした。


その後、メールヘッダーベースのスレッド機能が利用できるようになり、In-Reply-To および References ヘッダーに含まれる Message-ID を使用してケースと照合できるようなりました。

+ Message-ID、In-Reply-To、References はメールのメッセージヘッダー上に存在します。
+ メール送受信のスタンダードである RFC に則ったメールの規則では、通常、これらの値がメッセージヘッダー上に存在します。

 新たに Spring ‘23 から Lightning スレッド 機能が利用できるようになり、トークンベースのスレッドとメールヘッダーベースのスレッドを組み合わせてケースと照合できるようになりました。

+ 受信メールは、メールの件名または本文のトークンを使用してケースと照合されます。一致するトークンがケース上で存在しない場合、メールヘッダーベース（ Message-ID、In-Reply-To、References ）のスレッド機能が使用されます。

# メール-to-ケースの現在の設定の確認方法

参照 ID スレッド
+ [設定] の [メール-to-ケース] ページに移動します。[メール件名にスレッド ID を挿入] と [メール本文にスレッド ID を挿入] という設定が表示されている

メールヘッダーベースのスレッド
+ [設定] の [メール-to-ケース] ページに移動します。[メール件名にメールスレッドトークンを挿入] と [メール本文にメールスレッドトークンを挿入] という設定が表示がされていて、有効にしていない

Lightning スレッド
+ [設定] の [メール-to-ケース] ページに移動します。[メール件名にメールスレッドトークンを挿入] と [メール本文にメールスレッドトークンを挿入] という設定が表示がされていて、有効にしている

+ [メール-to-ケースのスレッド](https://help.salesforce.com/s/articleView?id=sf.support_email_to_case_threading.htm&language=ja&type=5)

+ [メール送信に関するよくある質問 ](https://help.salesforce.com/s/articleView?id=000315356&type=1)

# 関連資料

+ [スレッドトークンを使用できるオブジェクトの増加 Summer 24](https://qiita.com/Keiji_otsubo/items/519219015cad95a086da)
+ [参照 ID の無効化および Lightning スレッドへの切り替え](https://qiita.com/Keiji_otsubo/items/a2bd176d0b2f07504d87)
.NET MAUI カスタムポップアップの表示

#  NuGetパッケージの追加

CommunityToolKit.Mauiのパッケージをインストールをします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958553/137faa5e-512b-15dc-c58f-4554aa7f32f2.png)

#  パッケージの初期化
MauiProgram.csでCommunityToolkitを有効化する必要があります。

```cs:MauiProgran.cs
using CommunityToolkit.Maui;

namespace MauiApp2;

public static class MauiProgram
{
	public static MauiApp CreateMauiApp()
	{
		var builder = MauiApp.CreateBuilder();
		builder
			.UseMauiApp<App>()
			.UseMauiCommunityToolkit()
			.ConfigureFonts(fonts =>
			{
				fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
				fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
			});

		return builder.Build();
	}
}
```

#  ポップアップの表示

デザインはボタンを表示させる為だけなので適当です。
今回はボタンをクリックした際にポップアップを表示させるようにしてみます。

```MainPage.xaml
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="MauiApp2.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">

            <Label
                Text="ポップアップを表示するボタンです"
                FontSize="18"
                HorizontalOptions="Center" />

            <Button
                x:Name="PopupBtn"
                Text="Click me"
                Clicked="OnClicked"
                HorizontalOptions="Center" />

        </VerticalStackLayout>
    </ScrollView>

</ContentPage>
```

クリック時に拡張メソッドを使用してPopupを表示します。

```MainPage.xaml.cs
using CommunityToolkit;
using CommunityToolkit.Maui.Views;

namespace MauiApp2;

public partial class MainPage : ContentPage
{
	public MainPage()
	{
		InitializeComponent();
	}

	private void OnClicked(object sender, EventArgs e)
	{
        var popup = new Popup
        {
            Content = new VerticalStackLayout
            {
                Children =
                {
                    new Label
                    {
                        Text = "ポップアップです"
                    }
                }
            }
        };
        this.ShowPopup(popup);
	}
}
```



実際にdebugで画面を確認してみるとボタンをクリック時にポップアップが表示されています。
画面外をクリックする事でポップアップは閉じます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958553/46dd11dc-b712-19ba-134b-a89dd9c79edf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958553/a84fca6e-d37b-b9e0-05e7-fb41997f9fb4.png)


画面外をタップしてもポップアップを閉じないようにしたい場合は
Popupに対して以下の用に設定すると閉じなくなります。
```
CanBeDismissedByTappingOutsideOfPopup = false
```

#  参考資料

https://learn.microsoft.com/ja-jp/dotnet/communitytoolkit/maui/views/popup
Azure上でノートブックを作成する

Azure上でpython notebookを使った分析ができるそうなので試しに使ってみました。

## 準備
Azure上でNotebookを使った分析を行うには下記のリソースを作成する必要があります。
 - AzureMachineLearning
 - Computer instance
分析を始める前にこれらのリソースを作っていきます。

### MachineLearningリソースの作成
AzurePortralにログインし画面左上のリソースの作成へ移動します。  
リソースの作成画面のサイドバーから分析を選択すると、AzureMachineLearningが表示されますので、こちらからリソースを作成することができます。  
なお作成に当たってはリソースグループとワークスペース名を入力する程度で、残りはデフォルトのままで問題ないかと思います。
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161396/77cca86b-7a05-9e2c-4580-6ada59d32ef9.png)

### コンピュータインスタンスの作成
コンピュータリソースはAzureMachineLearningStudioの中で作成することができます。
先ほど作成したAzureMachineLearningリソースに移動し、画面中央の下側にスタジオの起動というボタンがあるので、  
そこからAzureMachineLearningStudioへ移動します。
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161396/a986c190-28c1-efce-ef37-088a5bec37e3.png)

スタジオに移動したらCreate newボタンがありますので、そこから『Compute instance』を選択します。
『Computer instance』を選択するとインスタンス作成画面へ移動します。
おすすめのインスタンスが表示されますので、適当なスペックのインスタンス選択し作成してください。
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161396/5b053de0-47f2-b9bf-888f-affd48016714.png)
コンピュータインスタンスが作成できたら準備は完了です。

### ノートブックの作成
ノートブックの作成もコンピュータインスタントを作成した際と同様にAzureMachineLearningStudioから作成します。
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161396/50235b84-5ded-20a4-9d4a-af1ae6fb101c.png)
ファイル名とファイルタイプの入力が求められますので、ファイル名をUntitled.ipynb、ファイルタイプはNotebookを選択しました。
ノートブックの作成完了後の画面が下記です。
![スクリーンショット 2023-04-12 095134.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161396/8507aa01-e673-6656-b9d7-03ac4c37f8bb.png)

## 動作確認
最後に動作確認を兼ねてHelloWorldを行いたいと思います。
下図のようにノートブック上でコードを記載します。下図の赤枠内に実行したいコードを記載しています。
![スクリーンショット 2023-04-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161396/e695fc32-7286-0a66-5c6a-d2ae20038d9b.png)

上図の状態でシフトとエンターを同時押しすると実行されます。
実行後の状態が下図です。 赤線の箇所に結果が出力されているのが分かります。
![スクリーンショット 2023-04-12 3735.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3161396/9ade565c-4155-bc07-5f5f-e6cb615b7448.png)

以上でAzure上でノートブックを使う準備が整いました。
次回からはこのノートブックを使って具体的な分析を行っていきたいと思います。
[Flutter]WillPopScopeについて

　今回は、Flutterフレームワークで提供されるウィジェットの一つである「WillPopScope」について紹介します。このウィジェットは、Androidデバイスのシステムボタンの「戻る」ボタンを押した時に発生する動作をカスタマイズするために使用されます。

　

簡単に使う理由についてまとめると
<b>・アプリ内で戻るボタンを押したときの動作をカスタマイズできる。</b>




# WillPopScopeを効果的に使えるタイミング
・<b>パスワード入力画面での戻るボタンの無効化</b>
→パスワードを入力する画面では、誤って戻るボタンを押してしまうと入力したパスワードがクリアされ、再度入力する必要があります。このような場合、WillPopScopeを使用することで戻るボタンを無効にすることができます。

・<b>フォームの編集内容の保存確認</b>
→フォームを編集中に誤って戻るボタンを押してしまうと、編集した内容が失われてしまいます。このような場合、WillPopScopeを使用することで、編集内容を保存するかどうかの確認のためのダイアログを出すことができます。

・<b>アプリの終了確認</b>
→最初の画面などで誤って戻るボタンを押してしまうとアプリが閉じてしまいます。このような場合、WillPopScopeを使用することで、戻る動作の無効化やアプリを終了するかどうかのダイアログを出すことができます。



# WillPopScopeを使用したサンプルコード

例えば、以下のようなコードを使用することで、戻るボタンを押しても画面が戻らないようにすることができます。こちらのコードで確かめるには、Androidのシュミレーターなどで確かめてみると、確認できると思います。

```dart
class SamplePage extends StatelessWidget {
  const SamplePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: WillPopScope(
        onWillPop: () async {
          //falseにすると、戻るボタンの動作が無効になる。
          return false;
        },
        child: const Center(
          child: Text("Hello, world!"),
        ),
      ),
    );
  }
}

```

ちなみに、試してみた動画はこちらになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/11d04df9-47cb-be1d-b345-60252d17291d.gif" width=50%>


# 最後に

この機能の実装はAndroidでは特に重要になっていくと思います。そのため知っておくと便利だと思います。
考え方によっては色々な実装ができそうでいいですね。
【Kotlin】次世代のコレクション表現 Collection Literals がやってくる！

## はじめに

先日の KotlinConf'23 内の Keynote にて、Kotlin 2.0 以降で複数の待ち望まれた新機能が実装される予定であることがアナウンスされました。

本記事では新機能の1つである Collection Literals について、YouTrack 内の議論を参考にしながら紹介したいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/eb29fa57-5f80-6448-477a-35128e4db1a4.png)

https://youtrack.jetbrains.com/issue/KT-43871

:::note warn
注意
Collection Literals は検討中の機能であるため、内容が変更される可能性があります。
:::


## Collection Literals とは

ざっくり言うと、これまでリストを作成する際は `listOf(1, 2, 3)` のように記述していましたが、これが `[1, 2, 3]` のように記述できるようになります。また、List だけではなく、Map や Set も同じシンタックスで記述できます。

**【Kotlin】**

```kotlin
val list = [1, 2, 3] // list literal
val map = ["one": 1, "two": 2, "three": 3] // map literal
val set: Set<Int> = [1, 2, 3] // creates a Set<Int> 
```

## Collection Literals の検討背景

Collection Literals は Kotlin コミュニティにおいて多くの関心を集めていました。Collection Literals は Python、JavaScript、Swift、Rust といった今日使用されているプログラミングに搭載されています。

**【Python】**

```python
# List
my_list = [1, 2, 3, 4]

# Dictionary
my_dict = {'apple': 1, 'banana': 2, 'orange': 3}
```

**【JavaScript】**

```javascript
// Array
let myArray = [1, 2, 3, 4];

// Object
let myObject = {'apple': 1, 'banana': 2, 'orange': 3};
```

**【Swift】**

```swift
// Array
let myArray: [Int] = [1, 2, 3, 4]

// Dictionary
let myDict: [String: Int] = ["apple": 1, "banana": 2, "orange": 3]
```

Collection Literals を導入することは Kotlin にとっても多くの利点があります。

1. 簡潔にデータを表現することができる
    * 特にデータサイエンス等のデータ重視のアプリケーションで恩恵が大きい
2. 各種のコレクション(`listOf`、`mapOf`、`setOf` など)を共通のシンタックスで記述することができる
3. 型推論と相性良く共存できる
4. `vararg` を使用せずに効率よくコレクションを作成できる


ちなみに C# においても同様の機能が近い将来実装予定となっています。

https://ufcpp.net/blog/2023/1/collection-literal/

## Collection Literals について詳しく見る

### シンタックス

現状は List や Map などコレクションの種類を問わず、大括弧`[]` を使用することが検討されています。


```kotlin
val list = [1, 2, 3] // list literal
val map = ["one": 1, "two": 2, "three": 3] // map literal
```

### 要件

Collection Literals において検討されている要件は以下の通りです。

1. 型が指定されなかった場合はデフォルトで `List<T>` か `Map<K, V>` に推論されること
    ```kotlin
    val list = [1, 2, 3] // has type of List<Int>
    val map = ["one": 1, "two": 2, "three": 3] // has type of Map<String, Int>
    ```
1. 型を指定することでその型に推論されること
    ```kotlin
    val set: Set<Int> = [1, 2, 3] // creates a Set<Int> 
    val map: MutableMap<String, Int> = ["one": 1, "two": 2, "three": 3] // creates a MutableMap
    ```
1. 右辺で型を指定できること
    ```kotlin
    val array = Array [1, 2, 3] // creates Array<Int>, note that "Int" was inferred here
    ```
1. typealias とも上手く機能すること
    ```kotlin
    typealias IntList = List<Int>
    IntList [1, 2, 3] // works
    ```
1. ユーザーが独自に定義したコレクションにも対応していること
1. コンパイラが特別な最適化を行わずとも効率的に設計されていること

### 懸念点

Collection Literals は汎用性が高いため、例えば以下のような `Point` 型がコレクション型であるかのように振る舞うことで `[1,2]` のように記述することが可能になります。従って、Collection Literals の設計は簡単なオブジェクトリテラルの設計と切り離して考えるべきではないとされています。

```kotlin
data class Point(val x: Int, val y: Int)

fun drawLine(from: Point, to: Point) { ... }

drawLine([1, 2], [3, 4])  // <---
```

## まとめ

Kotlin の Collection Literals について紹介しました。実装されるのは Kotlin 2.0 以降になるので使えるようになるにはまだしばらくかかりそうですが `List<T>` や `Map<K, V>` を共通のシンタックスで簡潔に記述できるようになることが非常に楽しみです。
[Flutter]コマンドまとめ表


![Open-a-Terminal-Window-in-Mac-Step-7-Version-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/5e60313b-1c36-e8e3-7cce-45109a045e80.jpeg)


こんにちわ。いせきです。
最近は、内定者アルバイトでたくさんコードがかけてとても幸せです。質の良いレビューが本当に勉強になっているのでどんどん成長を実感できている気がします。もっと頑張りたい！！


何かの生成などをする際に、コマンドを打つことがあると思います。その際に、Packageのサイトを検索して、コマンドをコピペがめんどくさいと感じることはないでしょうか？そんな方にこのサイトを見れば、コマンドを網羅できるようにまとめてみました。

:::note 

<b>もし、「これもあるよ！！」と思った方はどしどしコメントください！！僕も見つけ次第追加していこうと思います！！</b>
:::



# flutterのセットアップ

####  Flutterのプロジェクトを作成
```
flutter create (app_name)
```

####  SDKバージョンのチェックをするコマンド
```
flutter --version
```

####  Flutter packageの更新
```
flutter pub get
```

####  Flutterのバージョンなどをチェックするコマンド
```
flutter doctor
or
flutter doctor -v
```

####  FlutterをCleanするコマンド
```
flutter clean
```

####  Flutter packageのアップグレード
```
flutter pub downgrade
```

####  Flutter packageのアップグレード
```
flutter pub upgrade
```

####  Flutter SDKチャンネルの確認をする

```
flutter channel 
```

####  ~/.flutter_settingsに設定ファイルがあり、これを更新するコマンド
```
//Flutter-Webを有効化
flutter config --enable-web

//Flutter-Desktop-Linuxを有効化
flutter config --enable-linux-desktop

//Flutter-Desktop-macOSを有効化
flutter config --enable-macos-desktop

//Flutter-Desktop-Windowsを有効化
flutter config --enable-windows-desktop
```

####  ライブラリの依存関係をツリーで表示する
```
flutter pub deps
```



# ビルド関連

####  アプリ実行
```
flutter run
```

####  リリースモードで実行する
```
flutter run --release
```

####  デバッグモードで実行する
```
flutter run --debug
```

```デバイスの指定をしてビルドする
//destop
flutter run -d macOS
//web
flutter run -d Chrome
```

####   既にビルド済みであれば、再ビルドなしでアプリを実行する
```
flutter run --no-build
```

#### flutter runコマンド実行中の詳細ログを表示する
```
flutter run --verbose

```


#### Xcodeを開く

```terminal
open ios/Runner.xcworkspace
```

####  AndroidのBundleを生成する

```terminal
flutter build appbundle
```

#### iOSで画面録画をするコマンド
```terminal
xcrun simctl io booted recordVideo test.mov
```


# コード生成(build_runner)

```terminal
flutter pub pub run build_runner build
```

```terminal
flutter packages pub run build_runner build
```

```terminal
//ユーザー パッケージ内の競合する出力が以前のビルドからのものであると想定し、通常提供されるユーザー プロンプトをスキップする。
flutter pub run build_runner build --delete-conflicting-outputs
```


# packageのコマンド

####  `l10n`の生成コマンド

```terminal
flutter gen-l10n
```

####  `flutter_launcher_icons`の生成コマンド
```terminal
flutter pub run flutter_launcher_icons
```

####   `import_sorter`の生成コマンド
```terminal
flutter pub run import_sorter:main
```





# 最後に

開発をしているとどうしてもコマンドを忘れてしまう問題に対して少しでも楽にコピペからのコード生成などができたらとても便利になると思います。ぜひお使いください。
ORA-06512 Oracleエラーが発生する原因

## ORA-06512 Oracleエラーが発生する原因

ORA-06512は、Oracleデータベースで発生する一般的なエラーです。このエラーは、PL/SQLブロックの実行中に異常が発生したことを示します。

以下は、ORA-06512エラーが発生する主な原因です。

- **エラーが発生した行番号が表示される:** ORA-06512エラーは、PL/SQLブロック内でエラーが発生した行番号を示します。この情報を使用して、どの部分が問題を引き起こしているかを特定することができます。
- **エラーメッセージが表示される:** 通常、ORA-06512エラーにはエラーメッセージが付随して表示されます。このメッセージを読んで、エラーの原因を特定することができます。
- **バグ:** Oracleデータベースには、バグが存在する場合があります。これらのバグは、ORA-06512エラーを引き起こす可能性があります。
- **不足している権限:** PL/SQLブロックが必要とする権限がユーザーに割り当てられていない場合、ORA-06512エラーが発生する可能性があります。
- **不足しているリソース:** データベースに必要なリソースが不足している場合、ORA-06512エラーが発生する可能性があります。

### "insufficient privileges or does not exist"エラーメッセージの対処法

ORA-06512エラーのメッセージとして"insufficient privileges or does not exist"が表示されている場合、可能性としては、実行しようとしているユーザーに必要な権限が割り当てられていないためです。

以下の手順に従って、権限を確認してください。

1. SQLコマンドラインにログインします。
2. 実行しようとしているコマンドを入力します。
3. "insufficient privileges or does not exist"が表示された場合、次のコマンドを入力します。
    
    ```
    SELECT * FROM USER_SYS_PRIVS;
    
    ```
    
    このコマンドは、ユーザーが持つシステム特権を表示します。
    
4. 必要な特権が表示されているか確認してください。特権が表示されていない場合は、データベース管理者に問い合わせて、必要な特権を割り当ててもらってください。
Mysql 開発環境のdumpファイルをローカルで使う　メモ

# 使用するタイミング

### 環境
- Mysql
- dockerを使用

### 複雑なMigrationファイルを実行する時など
- 開発環境用(本番用)のDBのデータをローカルに入れて、migrateとrollbackを試して、正しくデータが移動するか確認する
→本番のデータを使って正常に動くか検証したい時

## RDSのダンプファイルを取得
importしたいTableを選択してExportする。
SQLの形式を選択する
![sakusaku-prod___heroku_d8022610f51cf2c_-_MySQL_5_6_50_と_GitHub_Desktop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2422935/c9589aac-0e4b-e0aa-5336-96d3186a9c10.png)


## 取得したダンプファイルをローカルのDBにインポートする方法
ダウンロードしたdumpファイルのパス
`~/Download/dev_mysql_dump`

### dbのコンテナの中にExportしたdumpファイルを置くディレクトリを作成する
1. `(例)docker compose exec db bash`でコンテナの中に入り、
2. コンテナの中に任意のディレクトリ(db_dump)を作成する
3. exitする

### コンテナにコピーする方法
（注意点）コンテナの中ではなく、ローカルで行う。

1. `docker cp ~/Download/dev_mysql_dump <コンテナId>:/db_dump/`

2. コンテナに入り、`/db_dump` に移動して、新しいdbにdev_mysql_dumpファイルを移動させる
`mysql -u root -proot -D test < dev_mysql_dump`
↑↑（mysql -u ユーザー名 -pパスワード　-D databaseの名前）
*mysqlの中には入らないこと。
Googleデータアナリティクス：表計算ソフトでデータの入力規則を活用する

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/21a12cb1-a49a-802f-d903-6f68758eca0c.png" width="800">

# 表計算ソフトでデータの入力規則を活用する

### <font color="MediumBlue">ドロップダウンリスト</font>

通常、データの入力規則は あらかじめ決まった選択肢のある セルに、ユーザーが選択する用の ドロップダウンリストを 追加するために使用されます。 多くの共同作業者がいる スプレッドシートの場合、 この機能を使うことで、 複数の作業者がテーブルを 操作しやすくなります。 これは、クイズにおける 複数選択肢のようなものと 考えてください。 ワークシートに入力されるデータを 自分でコントロールできるので 後でデータクリーニングを する手間が省けます。 

では、その方法を見てみましょう。 

この例では、マイルストーンと 締め切りが多数あるプロジェクトで 進捗をトラッキングします。 チームには、全員の進捗状況を 把握するためのシートがあります。 しかし、各自の進捗状況を 入れてもらうのではなく 「未着手」「進行中」「完了」など 複数の選択肢のドロップダウンメニューを 作成し、入力してもらうことにします。 そこで、ドロップダウンメニューを 追加する列、 この場合はステータス列を選択します。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/c423c31b-5e03-28b8-21ac-6b801c7c0251.png" width="７00">

次に、上部にある「データ」の プルダウンメニューから 「データの入力規則」をクリックします。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/d165d9d0-952b-5644-7e86-d197b6b784e6.png" width="７00">

すると、 オプションのポップアップメニューが 表示されます。 ここでは、項目のリストを追加して 他のユーザーが選択できるように するのが目的です。 そこで、選択可能な条件から 「リストを直接指定」を選び 作成したい選択項目を入力します。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/f0d2361f-ed09-5777-8d13-40a153c63b7b.png" width="７00">

これで、すべてのセルに ドロップダウンメニューが表示され 各タスクの進捗を簡単に マークできるようになりました。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/c5c6634b-aa46-6365-7d77-1fbb40c5048b.png" width="７00">

### <font color="MediumBlue">カスタムチェックボックス</font>

レビュー列の下のセルを選び タスクが承認されたかどうかを 示すチェックボックスを 作成してみましょう。 

データの入力規則メニューに戻ります。 今回は「リストを範囲で指定」ではなく 「チェックボックス」を選択します。 カスタムのセル値を使用する、の オプションもあります。 これを選択し、承認済みと 未承認と入力しましょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/baca3bb8-c14b-b5c5-c5ae-53b9ead3b23f.png" width="７00">

これで、プロジェクトマネージャーなど レビューする人がこれらのタスクに チェックを入れられるようになります。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/8698ac15-0493-0bd8-9ea5-6a0a67107263.png" width="700">

### <font color="MediumBlue">構造化データや計算式を 保護する</font>

表計算ソフトでは、一緒に作業する人が 多ければ多いほど、 誰かが誤って数式を壊してしまう 可能性が高くなります。 データの入力規則のメニューには 無効な入力を拒否する オプションがあります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/2067368d-d692-360e-66b6-5189df839029.png" width="500">

これにより 誰かが誤ったデータを入力しても 正常に動作させ続けることができます。
REST APIについてちゃんと理解する

## はじめに 
APIについてちゃんと理解しないまま使っていたのですが、気になったので今回調べました。

## APIとは
- 「API」とは、「Application Programming Interface」の略で、アプリケーションプログラム同士がデータのやり取りを行うためのインターフェースや規約のことです。データや機能を提供するプログラムと、それを利用するプログラムの間の仲介役として機能します。
- なかでもWeb上で提供されるAPIをWebAPIと呼びます。WebAPIはHTTPやHTTPSといったプロトコルを利用するため、Web上の様々なデバイスやプログラムから利用出来ます。

## REST APIとは
- WebAPIの中でも主流なのがREST APIです。REST APIとはRESTというアーキテクチャー・スタイルの設計原則に準拠するAPIです。(REST APIとRESTful API微妙な違いはあるのですが、あまり気にしなくていいようです。)
- 以下のような原則に則って設計されるサービスをRESTfulなサービスといいます。
### 統一インターフェース 
- クライアントとサーバがやり取りする際に、決まったルールに基づいて通信することです。例えばHTTPのGETメソッドやPOSTメソッドなど、あらかじめ情報の操作方法が定義されています。

### 接続性
- 情報内部に他の情報や状態へのリンクを含めることができることです。これにより、RESTfulなシステム同士の情報連携を円滑に行うことができます。


### アドレス可能性 
- リソースがアドレス指定可能なURIで公開されていることが必要です。これにより、クライアントはURIを介してリソースにアクセスすることができます。


### ステートレス性 
- リクエスト間でクライアントの状態が保持されないように設計されています。これにより、シンプルで拡張性の高いシステムを実現することができます(ステートレスの逆がステートフルで以前の状態を保持したまま処理を行います)。

## REST API以外のWeb Apiの例
- SOAP API: XMLをベースにしたプロトコルで、WSDL(ウェブサービス記述言語)によってAPIの詳細な仕様を記述します。

- GraphQL API: Facebookによって開発されたAPIで、RESTful APIと比較してより柔軟なデータ取得が可能です。クライアント側で必要な情報だけを指定して取得することができます。


## まとめ
今後はRESTの原則を意識しながらAPIの実装をおこなっていきたいです!

## 参照
https://wa3.i-3-i.info/word12428.html

https://wa3.i-3-i.info/word12429.html

https://tech.012grp.co.jp/entry/rest_api_basics　

https://ramble.impl.co.jp/2886/#toc4

https://www.infraexpert.com/study/sdn09.html

https://qiita.com/TakahiRoyte/items/949f4e88caecb02119aa

https://qiita.com/pink/items/f1a22840619d3b79c4f2