OmniAICreator/Qiita-1.07M huggingface dataset:
【備忘録】Pythonで自然言語処理の学習を始めるにあたって参考にしたサイト

こちらは個人的にGPT3とGPT2の自然言語処理について調べた際に参考にしたサイトを備忘録としてまとめたページです。

# GPT2＆GPT3自然言語処理の可能性や実行した際の印象
自然言語処理のスキルが今後必ず必要になると思い立ちました。
GPT3とGPT2を使ったPythonの自然言語処理を実際に行いました。
GPT3は日本語の情報がまだ少ないのですが、精度は高いことを実感できました。
GPT2でテキスト生成された文章はそのまま使うにはクオリティが低いのですが、そのクセのようなものを理解して応用すると文章作成のヒントのような使い方ができます。
GPT2は、ボキャブラリーをたくさん知っている小学3年生といった印象です。


# 自然言語処理の学習するにあたって参考にしたサイト

## OpenAI GPT-3 APIの使い方を解説 
https://data-analytics.fun/2021/12/01/gpt-3-api/

## 【Pythonコード】gpt-3のAPI申請通ったので試してみたら気持ち悪いほど正確なボットができた話 
https://note.com/benao_blog/n/n90bd5478ea04

##  tanreinama/gpt2-japanese
Public
https://github.com/tanreinama/gpt2-japanese

## japanese-gpt-1b 
https://huggingface.co/rinna/japanese-gpt-1b

## 13億パラメータ日本語GPT-2を使ってみる 
https://data-analytics.fun/2022/02/23/gpt-1b/

## GPT-2をファインチューニングしてニュース記事のタイトルを条件付きで生成してみた。
https://qiita.com/m__k/items/36875fedf8ad1842b729

## gpt2-japaneseの使い方 (1) - mediumモデルによる日本語テキスト生成 
https://note.com/npaka/n/n50cec2c7150e

## gpt2-japaneseの使い方 (2) - GPT-2のファインチューニング 
https://note.com/npaka/n/ne55d063e1ed8

## gpt2-japaneseの使い方 (3) - largeモデルによる日本語テキスト生成 
https://note.com/npaka/n/n37c0d9685c69

## GPT-2をファインチューニングしてニュース記事のタイトルを条件付きで生成してみた。
https://qiita.com/m__k/items/36875fedf8ad1842b729

## Huggingface Transformers 入門 (27) - rinnaの日本語GPT-2モデルの推論 
https://note.com/npaka/n/n96dde45fdf8d

## Huggingface Transformers 入門 (28) - rinnaの日本語GPT-2モデルのファインチューニング 
https://note.com/npaka/n/n8a435f0c8f69

## Huggingface Transformersのモデルをオフラインで利用する
https://qiita.com/suzuki_sh/items/0b43ca942b7294fac16a

## GPT-2のファインチューニング試す
https://zenn.dev/tyaahan/scraps/507b64d7c9763f

## rinnaの日本語GPT-2モデルを Google Colab で実行してみる
https://qiita.com/naokomada/items/3ba07414e06ee7d13483

## The Illustrated GPT-2 (Visualizing Transformer Language Models)
http://jalammar.github.io/illustrated-gpt2/

## 【ubuntu-20.10】rinnaの日本語GPT-2モデルを動かしてみる
https://noarts.net/archives/3501

## [japanese-gpt-1b] りんなちゃんに自問自答をさせてみる [自然言語生成] 
https://www.12-technology.com/2022/02/japanese-gpt-1b.html

## 【Python】GPT-2で日本語文章を自動で生成する
https://self-development.info/%E3%80%90python%E3%80%91gpt-2%E3%81%A7%E6%97%A5%E6%9C%AC%E8%AA%9E%E6%96%87%E7%AB%A0%E3%82%92%E8%87%AA%E5%8B%95%E3%81%A7%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B/

## タンテキ
https://ai-tanteki.com/

## AIのべりすと
https://ai-novel.com/
Fast APIでクイズを作ろう

#まずはコードを以下に示す。


```
import requests
import uvicorn
from fastapi import FastAPI, Form
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
from fastapi.requests import Request
from pydantic import BaseModel
import re
import urllib.request, urllib.error
import random
import pandas as pd
import openpyxl
# URLチェック関数
def checkURL(url):
 
    if re.match(r"^https?:\/\/", url):
        try:
            response = urllib.request.urlopen(url)
            response.close()
            return "OK"
        except urllib.request.HTTPError as e:
            print ("NotFound:  " + url)
            return "NG  Error Code: ", e.code
        except urllib.request.URLError as e:
            print ("NotFound:  " + url)
            return "NG  Reason: ", e.reason
    else:
        return u"URLは http://、https:// から記述してください。"



class ProductBase(BaseModel):
    title: str
    message: str

templates = Jinja2Templates(directory='templates')
app = FastAPI()
@app.get("/", response_class=HTMLResponse)
def base_data(request: Request):
    f="NG"
    while f!="OK":
        r=random.randint(1, 124540)
        input_book = openpyxl.load_workbook('ken.xlsx')
        sheet = input_book['sheet1']
        print(sheet.cell(row=r,column=17).value)

        zipcode=str(sheet.cell(row=r,column=17).value).replace('-','')
        url = 'https://zipcloud.ibsnet.co.jp/api/search?zipcode='+str(zipcode)
        f=checkURL(url)
    return templates.TemplateResponse(
        "base.html",
        {
            "request":request,
            "zipcode":str(zipcode)
            
        }
    )
    
@app.get("/zipcode/{zipcode}", response_class=HTMLResponse)
def api_data(zipcode:str, request: Request):
    url = 'https://zipcloud.ibsnet.co.jp/api/search?zipcode='+zipcode
    response = requests.get(url)
    jsonData = response.json()
    return templates.TemplateResponse(
        "index.html",
        {
            "zipcode":'?zipcode='+zipcode,
            "request":request,
            "title": jsonData['results'][0]['address2'],
            "message": "どこの県?"
        }
    )

@app.post("/zipcode", response_class=HTMLResponse)
def api_post(zipcode:str,request: Request,field: str = Form(...)):
    url = 'https://zipcloud.ibsnet.co.jp/api/search?zipcode='+zipcode
    response = requests.get(url)
    jsonData = response.json()
    if field==jsonData['results'][0]['address1']:
        answer='正解'
    else:
        answer='不正解'

    return templates.TemplateResponse(
        "post.html",
        {
            "request":request,
            "title": answer,
            "message": jsonData['results'][0]['address2']+"は"+jsonData['results'][0]['address1']+"です"
        }
    )
```
またhtmlは自分の記述したいように完成させれえばよい
よく作成するLinq拡張メソッドを紹介

Linqにこんなメソッドあったら便利と、C#プロジェクトを作るたび、よく用意する拡張メソッドを紹介したいと思います。

# Partition
条件に対してコレクションを絞りこむならWhereですが、trueだけではなくfalseも両方取りたい場合につかいます。

### 使用例
```C# 
var (trueCollection, falseCollection) = _boolCollection.Partition(x => x == true);
```

### 実装
```C#
public static (List<T>, List<T>) Partition<T>(this IEnumerable<T> sequence, Func<T, bool> func)
{
    var incluedList = new List<T>();
    var excludeList = new List<T>();
    foreach (var x in sequence)
    {
        if (func(x))
            incluedList.Add(x);
        else
            excludeList.Add(x);
    };
    return (incluedList, excludeList);
}
```


# NotNull
Linqでnullをはじく方法にWhere(x => x != null)ってやり方はあるんですが、これだと続けてSelect書こうとしてもWarningになってしまうため、非null型に変換も行ってくれるやつです。

作成する際の注意としては、クラスレベル or プロジェクトレベルでnullableをenableにしてください。

### 使用例
```C#
var_collection = new List<Test?>();
// 警告がでない
_collection.NotNull().Select(x => x.Property); 
```

:::note warn
後述の実装に関しては、versionごとの実装が記述してあります。
:::

### 実装(version 1)
```C#
// クラス用
public static IEnumerable<T> NotNull<T>(this IEnumerable<T?> enumerable) where T : class
{
    return enumerable.Where(e => e != null).Select(e => e!);
}

// プリミティブ型用
public static IEnumerable<T> NotNull<T>(this IEnumerable<T?> enumerable) where T : struct
{
    return enumerable.Where(e => e.HasValue).Select(e => e!.Value);
}
```

コメントで.OfTypeで可能だと情報をいただきました。

https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.oftype?view=net-6.0
> このメソッドは 、型にキャストできる要素のみを返します。

:::note info
こちらの実装であれば、クラス、プリミティブで分けて実装する必要はありません。
:::
### 実装(version 2)
```C#
// クラス、プリミティブ型　兼用
public static IEnumerable<T> NotNull<T>(this IEnumerable<T?> enumerable)
{
    return enumerable.OfType<T>();
}
```


# Diff
コレクションの片方にしかに要素を取得する
※注意としてはクラスなど参照型で使用する際は、参照比較になるため注意

### 使用例
```C#
var (onlyB, onlyA) = a.Diff(b);
```
### 実装
```C#
public static (IEnumerable<T>, IEnumerable<T>) Diff<T>(this IEnumerable<T> a, IEnumerable<T> b)
{
    var onlyB = b.Except(a);
    var onlyA = a.Except(b);
    return (onlyB, onlyA);
}
```

# ForEach(index付き)
デフォルトのForEachのindexを第二引数に取れるバージョン

### 使用例
```C#
_collection.ForEach((x, index) => {});
```
### 実装
```C#
public static void ForEach<T>(this IEnumerable<T> sequence, Action<T, int> action)
{
    int i = 0;
    foreach (T item in sequence)
    {
        action(item, i);
        i++;
    }
}
```
石手川ダムリアルタイムデータをスクレイピングして貯水率を調べる

https://www.skr.mlit.go.jp/matsuyam/river/ishitegawa/chosui/chosui.html

石手川ダムリアルタイムデータ
http://www1.river.go.jp/cgi-bin/DspDamData.exe?ID=1368080150020&KIND=3&PAGE=0

```python
from urllib.parse import urljoin

import pandas as pd
import requests
from bs4 import BeautifulSoup

def fetch_soup(url, parser="html.parser"):

    r = requests.get(url)
    r.raise_for_status()

    soup = BeautifulSoup(r.content, parser)

    return soup


url = "http://www1.river.go.jp/cgi-bin/DspDamData.exe?ID=1368080150020&KIND=3&PAGE=0"

soup = fetch_soup(url)

link = urljoin(url, soup.select_one("body > center > p > a").get("href"))


def dateparse(s):
    date, time = s.split()
    result = pd.to_datetime(date) + pd.to_timedelta(time + ":00")
    return result


df = pd.read_csv(
    link,
    skiprows=9,
    encoding="cp932",
    names=[
        "年月日",
        "時刻",
        "流域平均雨量",
        "流域平均雨量属性",
        "貯水量",
        "貯水量属性",
        "流入量",
        "流入量属性",
        "放流量",
        "放流量属性",
        "貯水率",
        "貯水率属性",
    ],
    parse_dates={"日時": ["年月日", "時刻"]},
    date_parser=dateparse,
    index_col=["日時"],
)

df
```

```python
pd.options.plotting.backend = "plotly"

df["貯水率"].plot()
```
![newplot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36151/925e86ac-6fac-4145-4b21-8efff4231095.png)
Qiitaのスライドモードを試す（不具合？）=> 解決したようです

# スライド１

スライド1本文

↓ 改ページが消えるようだ

---

# スライド２

スライド２本文

* * * 

# スライド３

スライド３本文

* * *

なぜ改ページしないのか不明

以下、Rawテキスト
```
# スライド１

スライド1本文

↓ 改ページが消えるようだ

---

# スライド２

スライド２本文

* * * 

# スライド３

スライド３本文

* * *

なぜ改ページしないのか不明
```

---
AndroidStudioでハマった「android resource linking failed」

※初投稿です

**「android resource linking failed」**

Android開発をしていて、多くの開発者——
特に私のような初学者は、このエラーメッセージを見て台パンしたことでしょう。

この忌々しい「android resource linking failed」
原因は大きく分けて2つです(多分)
 - XMLファイルのミス(だいたいこれ)
 - build.gradleがおかしい

`「build.gradleのバージョンをいじれ」って記事は腐るほど見たけど、よく分からなかった`

という人はXML等のリソースファイルが原因かもしれません。


>build.gradleの設定に関しては、わかりやすい記事があるのでリンクを貼っておきます。
[[Flutter/Android]「Android resource linking failed」というメッセージでビルドエラーになる場合の対処法](https://minpro.net/android-resource-linking-failed)

## XMLファイルのミスを探したい

「エラーを吐いているXMLファイルを探せったって……そんなの時間がかかりすぎるよ！」

――そんなあなたに試して欲しいのが、`Code`にある`Inspect Code`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699935/71db50d6-7c75-e573-c3c7-a19ddafead30.png)

OKを押したら解析してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699935/1d12bd24-575f-a89a-dd75-ff6343479d9a.png)

すると、このようにエラーが起きている場所が分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2699935/486bb1b0-2f28-cd2f-748c-593b3cf196f2.png)

これで出てきたエラーを直したら、「android resource linking failed」とはおさらばできる。筈。
ゴルゴ１３のISBNリストを取得する

# 概要
くだらない話ですが、所有するコミックのデータベースを作ろうとしてます。
ゴルゴ１３は、２００冊を超える状況で、「さいとう・たかを」先生が逝去された後も、まだ続いています。

そんなゴルゴ１３ですが、ISBNが採用された時期よりも前から出版されているので、ISBNリストを使った書籍情報の検索をしようとしてもISBNが書籍にのっていません。
が、、、、版数が版数なので、ISBNが始まった時期より後に増刷となった場合、古い書籍もISBNが採番されます。

そこで、リイド社のゴルゴ１３のページから２００冊を超えるゴルゴ１３のISBNを取得しようとしてます。
（２００冊を超えるISBNのリストがあれば、そこから持っている巻数のISBNを把握すればいい）

# リイド社を見てみる

https://www.leed.co.jp/standardbooks

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222251/8cbc5921-2aa8-dc7c-8dbe-1d2481a64b8e.png)

ゴルゴ１３にもシリーズがあるので、所有しているシリーズを選択してみます。

https://www.leed.co.jp/?paged=2&cond=series&s=%E3%82%B4%E3%83%AB%E3%82%B4%EF%BC%91%EF%BC%93

なるほど、、、、
ざっくり中を見ると、普通に取り出せそうだ・・・

# スクレイピングしてみた

リイド社さん、私個人の目的でソース見てごめんなさい。

```golgo13.py
import requests
from bs4 import BeautifulSoup
import os

if __name__ == '__main__':
    BASE_URL = "https://www.leed.co.jp/"
    FILE_NAME = "golgo13_isbn.csv"

    currentPath = os.path.dirname(os.path.abspath(__file__))
    filePath = os.path.join(currentPath, FILE_NAME)

    for page in range(10):
        param = {
            "paged": str(page + 1),
            "cond":"series",
            "s": "ゴルゴ１３"
        }

        with open(filePath, "a") as f:
            response = requests.get(BASE_URL, param)
            soup = BeautifulSoup(response.text, "html.parser")
            
            if len(soup.find_all("span", class_='search-book-title')) > 0:
                for item in soup.find_all("span", class_='search-book-title'):
                    title = item.text
                    isbn13url = item.find("a").attrs['href']
                    isbn13 = isbn13url.replace("https://www.leed.co.jp/", "")
                    f.writelines(isbn13 + ", " + title + "\n")
            else:
                break

```

現在だと、4ページ分の204巻まであります。（スゴイっす）
```golgo13_isbn.csv
9784845800018, ゴルゴ１３ （1）
9784845800025, ゴルゴ１３ （2）
9784845800032, ゴルゴ１３ （3）
9784845800049, ゴルゴ１３ （4）
9784845800056, ゴルゴ１３ （5）
9784845800063, ゴルゴ１３ （6）
9784845800070, ゴルゴ１３ （7）
9784845800087, ゴルゴ１３ （8）
9784845800094, ゴルゴ１３ （9）
9784845800100, ゴルゴ１３ （10）
9784845800117, ゴルゴ１３ （11）
9784845800124, ゴルゴ１３ （12）
9784845800131, ゴルゴ１３ （13）
・・・
```

無事、必要なISBNがゲットできたので、所有コミックのデータベースにISBNをまとめて登録。
ユーザランド とは

## 勉強前イメージ

ユーザが触れる部分？
でもカーネルにはないような気がするけど・・・

## 調査

### ユーザランド とは

linuxのカーネルでは
OSの中で、カーネル以外のことをユーザランドと言います。
ユーザランドはユーザが権限を持って操作できる箇所になります。

現在のlinuxでは
ざっくりHWとAPPの間にはOSがあり、ユーザが操作できるところをユーザランド、HWとやり取りするところをカーネルといいます。
カーネルは基本的には一般ユーザが設定を変更できず、特権ユーザのみが設定を変更することが出来ます。

`/etc` の設定ファイルや `/bin` のコマンド群、 `/lib` のライブラリなどがユーザランドになります。
ユーザランドで実行するとカーネルで実行するより遅いですが、一般ユーザでも動作するので安全です。
逆にカーネルで実行すると高速になります。

## 勉強後イメージ

文字からの推測だったけど当たったw
ユーザランドって初めて聞いたけど、基本的にはカーネル以外のところがユーザランドなのね。

## 参考

- [ユーザーランド 【userland】](https://e-words.jp/w/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%83%A9%E3%83%B3%E3%83%89.html)
- [カーネルとユーザランドの入れ替え](https://www.openrtm.org/openrtm/ja/content/%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E3%81%A8%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%A9%E3%83%B3%E3%83%89%E3%81%AE%E5%85%A5%E3%82%8C%E6%9B%BF%E3%81%88)
自作のChrome拡張機能をManifest V3へ移行した際の修正内容まとめ

# 自作のChrome拡張機能
[Chord Dictionary](https://chrome.google.com/webstore/detail/chord-dictionary/lnefagbhokamcaedbeopnhdabkcemkcf?hl=ja)

# 修正内容

## manifest.json
```diff_json:manifest.json
{
- "manifest_version": 2,
+ "manifest_version": 3,
  "web_accessible_resources": [
-    "main.js",
-    "main.css",
+    {
+      "resources": ["main.js", "main.css", "sounds/*.mp3"],
+      "matches": ["http://*/*", "https://*/*"]
+    }
  ],
-  "browser_action": {
+  "action": {
    "default_title": "Chord Dictionary"
  },
  ],
  "background": {
-    "scripts": [
-      "background.js"
-    ],
-    "persistent": false
+    "service_worker": "background.js"
  },
  "permissions": [
    "tabs",
    "activeTab",
    "storage"
+    "scripting"
  ]
}
```

## 関数

### chrome.browserAction
`chrome.browserAction`を`chrome.action`にする
```diff
- chrome.browserAction.onClicked.addListener(function (tab) {
+ chrome.action.onClicked.addListener((tab) => {
```

```diff
- chrome.browserAction.setBadgeText({ text: isActiveTo ? "ON" : "" });
+ chrome.action.setBadgeText({ text: isActiveTo ? "ON" : "" });
```

### chrome.tabs.executeScript、chrome.tabs.insertCSS
`chrome.tabs.executeScript`を`chrome.scripting.executeScript`にする
```diff
- chrome.tabs.executeScript(tabId, { file: "main.js" });
+ chrome.scripting.executeScript({
+   target: { tabId: tabId },
+   files: ["main.js"],
+ });
```

`chrome.tabs.insertCSS`を`chrome.scripting.insertCSS`にする
```diff
- chrome.tabs.insertCSS(tabId, { file: "main.css" });
+ chrome.scripting.insertCSS({
+   target: { tabId: tabId },
+   files: ["main.css"],
+ });
```

`manifest.json`の`permissions`に`scripting`を追加する必要がある

### chrome.extension.getURL
`chrome.extension`を`chrome.runtime`にする
```diff
- chrome.extension.getURL("sounds/piano-c2.mp3")
+ chrome.runtime.getURL("sounds/piano-c2.mp3")
```


# 参考
その他に必要な修正は公式のマイグレーションガイドが参考になります。
- [Migrating to Manifest V3](https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/)
Nuxt.jsのSSRをざっくり理解したい

こんにちは。駆け出しフロントエンドです。

Nuxt.jsのSSRを使用しているページで挙動がいまいちわかっていなかったので、まとめてみました。

## SSRとは
Nuxt.jsの公式から翻訳＆引用です。
> サーバー側レンダリング（SSR）は、ブラウザーでWebページをレンダリングする代わりに、サーバー上にWebページを表示することによって貢献するアプリケーションの機能です。


これを読んでもピンときませんよね。SSRとはガチャか何かのランクなのでは？？と思う方もいらっしゃると思います。（私がそうでした）
SSRって何？という方は以下の記事が図解もあり、わかりやすかったのでおすすめです。

https://qiita.com/mtoyopet/items/c211c5bc034be33d0b38

## SSRの挙動
結論から言ってしまうと、SSRの挙動は以下です。
- サーバーからロードされる時はサーバーサイドレンダリング（初回またはブラウザでURL直接指定の時）
- ロードされた以降はクライアントサイドレンダリング（リロード時など）

SSRになった場合とCSRになった場合はcookieの取扱なども変わるので、どちらでも問題なく表示・バグがないように作らないといけません。


### Nuxt.jsのライフサイクル
※イメージは[Nuxt.jsのライフサイクル覚書](https://lab.astamuse.co.jp/entry/2019/05/29/114500)より拝借しました🙇‍♀️
![20190529112056.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305196/ab0c7cb5-c421-f885-faeb-7bbdf3b13df3.png)

### asyncDataについて
`asyncData`はページコンポーネントの初期化前に呼び出される関数のことで、「pages」ディレクトリ配下のコンポーネントのみ使用できます。

https://nuxtjs.org/docs/features/data-fetching#async-data

コンポーネント内ではasyncDataを使用できないため、値を渡したい場合はpropsとして渡すなど工夫が必要のようです。

> 1. Use the new fetch hook that is available in Nuxt 2.12 and later versions.
> 2. Make the API call in the mounted hook and set data properties when loaded. Downside: Won't work for server side rendering.
> 3. Make the API call in the asyncData method of the page component and pass the data as props to the sub components. Server rendering will work fine. Downside: the asyncData of the page might be less readable because it's loading the data for other components.

## まとめ
- 初回の場合はSSR、再描画時はCSRなどライフサイクルが違う
- ライフサイクルは`plugin`→`middleware`→`validate`→`asyncData`→`fetch`→`beforeCreate`の順で処理が実行されている

## 参考にさせていただいた記事
https://www.japon-line.co.jp/tech/post/nuxt-js%E3%81%AEssr-csr%E5%87%A6%E7%90%86%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/

https://nazo.hatenablog.com/entry/nuxt-ssr-lifecycle

https://lab.astamuse.co.jp/entry/2019/05/29/114500

https://zenn.dev/onota/articles/e8e405271653cac3afd7
Playbackプロジェクト作成


GeoSpatial 
https://zenn.dev/tkada/articles/04b44474149130

ARCore extention
https://github.com/google-ar/arcore-unity-extensions

緯度経度から平面座標系へ。
https://yubeshicat.hatenablog.com/entry/2020/08/26/203840

【Unity】スマホの傾き（加速度センサ）で飛行機の回転を実装

https://qiita.com/Sena_0226/items/7d320bb7da59065c4e61

Math(double)
https://github.com/Darkziyu/Mathd
https://baba-s.hatenablog.com/entry/2019/09/06/073000

UnityでARアプリの作り方4/4 コンパスで3Dオブジェクトを操作
https://techblog.raccoon.ne.jp/archives/2019090404.html

PlayBack API
じゅころぐAR
https://www.jyuko49.com/entry/2021/05/27/022934

ARCore Recording and Playplay APIを使って現地に行かずにImmersal開発をする
https://zenn.dev/tkada/articles/e1a74baf722586

AR Foundation で、Android をターゲットとする AR セッションを記録して再生 
https://developers.google.com/ar/develop/unity-arf/recording-and-playback/developer-guide
Rails APIのSerializerで、任意のキーを指定する方法

実務にあたっている中で、気になったので、備忘録的に示しておく。
思いつきで、つらつらと書いた。

### 大きくわけて3つある

### １　key で指定する
```ruby
class PostSerializer < ActiveModel::Serializer
  attributes :id, :title
  attribute :body, key: :post_body
end
```

### 2　メソッド
```ruby
class PostSerializer < ActiveModel::Serializer
  attributes :id, :title
　
  def post_body
　  object.body
  end
end
```

### 3　ブロック
```ruby
class PostSerializer < ActiveModel::Serializer
  attributes :id, :title
　
  attribute :post_body do
    object.body
  end
end
```

### cf. メソッドとブロックの内部では、レコードに対してさまざま処理を書くことができる。
が、個人的には、メソッドはモデルに切り出し、以下のように`attr_reader :メソッド名`として外部から利用可能なインスタンスメソッドとして定義する方が綺麗だと思う。
```ruby
class Post < Model
  attr_reader :post_body
  
  #インスタンスメソッド
  def post_body
    body
  end
end
```
参考資料
https://docs.ruby-lang.org/ja/latest/method/Module/i/attr_reader.html

## ここで気になった。object.bodyのobjectってなんぞや。
`object`とは、インスタンスを指す。上記のモデルの例によれば、`Post.new`されたインスタンスを指す。


## 最後に
経験の薄い学生エンジニアなので、指摘等あれば、ドシドシお願いします！
Goの正規表現 (?<flag>) と和解せよ

# TL; DR

- `(?i)`, `(?m)` 等は、マッチのルールを変更するフラグを表す
    - 大文字、小文字の区別をなくす/行を跨いでマッチできる等
- グループはキャプチャされない
- リファレンス: https://github.com/google/re2/wiki/Syntax

# はじめに

とあるライブラリを調べていたところ、大文字でも小文字でもマッチする謎の正規表現を見つけました。

```go
re := regexp.MustCompile(`(?i)(ab)(c+)`)
fmt.Println(re.FindStringSubmatch("abccc")) // [abccc ab ccc]
// 大文字でもマッチする！？
fmt.Println(re.FindStringSubmatch("AbCcc")) // [AbCcc Ab Ccc]
```

~~実際は謎でもなんでもなかったので~~ 調べた内容を備忘録として残しておきます。

# 正規表現のドキュメント

Goの `regexp` パッケージでは、re2の文法が使われています。([pkg.go.dev](https://pkg.go.dev/regexp)にも説明があります)

https://github.com/google/re2/wiki/Syntax

大文字、小文字の区別がなくなったのは `(?i)` の働きによるものでした。
`(?flags)` はフラグを指定する構文で、フラグは正規表現のルールを一時的に変更します。

> `(?flags)` 現在のグループにフラグを設定する；キャプチャされない

# フラグの種類
## i

冒頭に出てきたフラグ。大文字小文字を区別せずマッチするようになります。

```go
re := regexp.MustCompile(`(?i)(ab)(c+)`)
fmt.Println(re.FindStringSubmatch("abccc")) // [abccc ab ccc]
fmt.Println(re.FindStringSubmatch("AbCcc")) // [AbCcc Ab Ccc]
```

ちなみに、フラグの説明に「キャプチャされない」とあったように、`(?i)` 自体は `FindStringSubmatch` 等の要素に現れません（他のフラグも同様）。特定の文字とマッチするわけではないので、グループの番号がずれないのはありがたいです。

## m

`^` 、`$` が行ごとの先頭、末尾とマッチするようになります。

```go
const text = `hoge
piyo
hige
fuga`

// 普通のモードでは、"^" は文字列全体の先頭としかマッチしない
re := regexp.MustCompile(`^h.ge`)
fmt.Println(re.FindAllStringSubmatch(text, -1)) // [[hoge]]

// ?m だと各行とマッチする
re2 := regexp.MustCompile(`(?m)^h.ge`)
fmt.Println(re2.FindAllStringSubmatch(text, -1)) // [[hoge] [hige]]
```

## s

ワイルドカード `.` が改行 `\n` ともマッチするようになります。行を跨いだマッチが可能です。

```go
const text = `lorem ipsum
dolor
sit
amet`

re := regexp.MustCompile(`(?s)lorem.*amet`)
fmt.Println(re.FindStringSubmatch(text))
// [lorem ipsum
// dolor
// sit
// amet]
```

## U

`*` と `*?`、`+` と `+?` の意味が逆になります。（UはungreedyモードのU）

```go
text := `(foo)(bar)(baz)`

// .*は最長マッチ
re := regexp.MustCompile(`\(.*\)`)
fmt.Println(re.FindStringSubmatch(text)) // [(foo)(bar)(baz)]

// .*が最短マッチになる
re2 := regexp.MustCompile(`(?U)\(.*\)`)
fmt.Println(re2.FindStringSubmatch(text)) // [(foo)]
```

# フラグの応用

フラグは複数組み合わせて指定可能です。

```go
const text = `Abc
d
eEEe`

re := regexp.MustCompile(`(?is)ab.*e+`)
fmt.Println(re.FindStringSubmatch(text))
// [Abc
// d
// eEEe]
```

また、`(?flag:<pattern>)` と書くと、かっこの内部だけフラグを有効にできます。

```go
re := regexp.MustCompile(`(?i:ab)c+`)
// かっこの中では大文字小文字を区別しないが
fmt.Println(re.FindStringSubmatch("ABccc")) // [ABccc]
// かっこの外では区別する
fmt.Println(re.FindStringSubmatch("ABCcC")) // []
```

# おわりに

以上、regexpパッケージのフラグの紹介でした。
正規表現は雰囲気で使っていたので、たまにはしっかりドキュメントを読まないとと痛感しました... :innocent:
🔰【メモ】Railsの基礎中の基礎の用語集①

# はじめに
こんばんは。明日、最終面接を控え、緊張でガクブルの未経験エンジニアです。
今回は今まで学習してきた中で、基礎的な言葉の内容をアウトプットしていきます。

# フレームワーク
最小のコストでWebアプリケーションの作成ができるような仕組み。

# MVC
モデル/ビュー/コントローラーという役割の総称。Webアプリケーションシステムの処理の構造。
### モデル
データベースへのアクセスをはじめとする情報のやりとりに関する処理を担当。
モデルがありことにより、データベースにあるテーブルをRailsで管理できるようになる。
### ビュー
ブラウザにレスポンスとして返す見た目を設定する。
### コントローラー
リクエストに対応する処理をまとめて用意しておき、ルーティングからリクエストを受け取って処理を行った後、クライアントにレスポンスを返す。
MVCにおける橋渡しの役割も持っていて、レスポンスに必要となるデータがあれば、他の役割と連携してデータを取得したり受け渡しを行い、レスポンスを完成させる。

# ルーティング
リクエストを振り分ける。

# アクション
コントローラー内における処理のカテゴリー。
代表的なものとして、index,new,create,show,edit,update,destroyなどがある。
### index
一覧表示ページ表示など。
### new
新規投稿ページ表示など。
### create
データの投稿を行うなど。
### show
個別詳細ページ表示など。
### edit
投稿編集ページ表示など。
### update
データの編集を行うなど。
### destroy
データの削除を行うなど。

# ERB
HTMLにRubyの記述を埋め込むことができるテンプレートから、HTMLファイルを生成できるテンプレートエンジン。
テンプレートエンジンとは、雛形のテンプレートと、そのデータを埋め込むことで、最終的に別のファイルとして生成できる仕組みの１つ。
拡張子は◯◯.html.erbで作成する。

# ActiveRecordメソッド
モデルがテーブルデータを操作する際に使用できるメソッドの総称。
代表的なものとして、all,find,new,saveなどがある。
### all
テーブル内全てのデータを取得
### find
引数にレコードのidを指定し、対応するレコードを取得
### new
クラスのインスタンス（レコード）を生成
### save
クラスのインスタンス（レコード）を保存

# ヘルパーメソッド
Railsにおける、主にビューでHTMLタグを出現させたりテキストを加工するために使用するメソッドの総称。代表的なものとして、form_with,link_toなどがある。
### form_with
フォームを実装するためのヘルパーメソッド
### link_to
リンクを実装するためのヘルパーメソッド

# パラメーター
リクエストに含まれているサーバーの外部から渡されデータ。
### params
送られてきたパラメータを格納したもの。フォームで入力された情報などはparamsに格納されている。


# 終わりに
短めですが、今日はここまで！
明日の最終面接、悔いのないよう頑張ります！！
【#14 エンジニア転職学習】Linux基礎　ソフトウェアパッケージ（CentOS）

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

本日で使用していた書籍の最後まで読み終わり、
Linuxはこれで入門本を1冊終了しましたので、一区切りにしたいと思います。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
本日はLinuxのソフトウェアパッケージに関して学習しました。
私が使用しているディストリビューションはRedHat系のCentOS7を使用していたので、とりあえずそちらだけのコマンド処理をやりました。

* zipコマンド
* **ソフトウェアパッケージ（CentOS）　←Topics!!**

# ソフトウェアパッケージ（CentOS）
何か新しくソフトウェアをLinux環境へ導入したいときの方法です。
パッケージ（コンパイル済みバイナリファイル）を
パッケージ管理システム（ディストリビューションごとに用意されている）からインストールする手法が主流です。

* **依存性の解決を自動的に行う**等、高機能なyumコマンドの利用が主流
* **依存性：別の必要なパッケージが先にインストールされていないといけないこと**
* コマンド入力時のパッケージアーキテクチャ部分は省略しても良い

使用している書籍はこちら↓

https://www.amazon.co.jp/%E6%96%B0%E3%81%97%E3%81%84Linux%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E4%B8%89%E5%AE%85-%E8%8B%B1%E6%98%8E-ebook/dp/B072K1NH76/ref=sr_1_1?adgrpid=113196705062&gclid=Cj0KCQjwzLCVBhD3ARIsAPKYTcR4WAb_4QVrwuBM_1mIPMFsQ6kNDJ-o4yIofVSAI7_eHpWCeva8kKwaAstgEALw_wcB&hvadid=489559881279&hvdev=c&hvlocphy=1009363&hvnetw=g&hvqmt=e&hvrand=10125867468998217428&hvtargid=kwd-1152146940662&hydadcr=21814_10996132&jp-ad-ap=0&keywords=%E6%96%B0%E3%81%97%E3%81%84+linux+%E3%81%AE+%E6%95%99%E7%A7%91%E6%9B%B8&qid=1655473534&sr=8-1




# おわりに
最後までお読みいただきありがとうございました。
明日からしばらくはGit基礎をやっていきます。
アドバイス・応援コメント等いただけますと幸いです。
【コラム】シミュレーションデータを機械学習で解釈する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1275001/329a2fe8-0bd8-4526-65a0-a5588d46741f.png)

前回の記事とコラムで、機械学習の解釈性の向上に触れました。

https://qiita.com/hima2b4/items/98effd1a60959762a92d

その代表格はSHAP。
「機械学習を解釈する技術」において”SHAPは機械学習モデルの予測値を各特徴量に分解”と紹介されていました。なるほどです。

予測値といえば、シミュレーションの結果も予測値です。
シミュレーションモデルには申し訳ないですが、結果をSHAPを使って各特徴量に分解したらより理解が進むのではないか？と思い、やってみることにしました。

https://dropout009.hatenablog.com/entry/2019/01/07/124214

https://www.amazon.co.jp/dp/429712226X/ref=redir_mobile_desktop?_encoding=UTF8&ref_=cm_cr_arp_mb_bdcrb_top



***
実施したのは、建物のエネルギーロスのシミュレーションです。
「CEN/TR 16676:2014　- Energy losses by industrial door」という規格に、ロスの算定モデルが定義されています。
パラメーターは約20種（定数・変数含む）ほどあり「どの特徴量にどの程度の効果があるのか」はシミュレートした結果を見ただけでは、ちょっとよくわかりません。

　
***
**建物のエネルギーロスのシミュレーション**
温暖化により、地球の平均気温が4℃上昇するというシナリオがあります。
そこで、この温暖化が建物のエネルギーロスにどの程度影響を及ぼすかについて確認することにしました。
先の通り、このロスの算定モデルは、かなりのパラメーターで構成されていますので、先の内容を含む目的に絞って特徴量を6つ決め、それぞれ2～4水準を設定し、机上でシミュレートしてみました。


　
***
**SHAP**
次に、SHAPを実行しました。（データは異なりますが、実行内容は以下の記事と同じです）

https://qiita.com/hima2b4/items/94c3195a822960248e59

機械学習モデルはXGBを適用、学習スコアは 0.995、テストスコアは 0.968 。早速、SHAPで特徴量の重要度を見てみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1275001/65337683-90c6-157d-7c59-81014385cff3.png)

取り上げた6つの特徴量のうち、4つの特徴量は直線関係（3つが正、ひとつが負）が見られ、いずれにも交互作用がありました。
別の1つの特徴量は二次的な関係が見られ、これにも交互作用がありました。
温暖化の進行がどの程度影響するかに関する特徴量（添付グラフのΔtemp）は、影響はほとんど見られません・・・でした。

確認したかった特徴量の影響はほとんどないという結果でしたが、交互作用や正負、二次的な傾向等の特徴量がいりまじった関係を SHAPはこうもあっさり可視化してくれるのかと感心し、この結果を見て**シミュレーションデータの解釈にも使えるな**と確信しました。


　
***
**SHAPの後の決定木**
各特徴量がエネルギーロスにどの程度影響しているか、またどのような傾向があるかを掴むことができましたが、この後さらに決定木も描きました。

SHAPで傾向を把握したあとに眺める決定木は、可読性が超絶アップしました。
シミュレーションの結果では、最小値と最大値に20倍以上の差があったのですが、差が生じている理由がスルスル頭に入る感じでした。

「ある条件の値をシミュレーションで求めた」というときと比較すると次元の異なる満足感や達成感です。


　
***
**シミュレーションモデルと機械学習モデルは水と油？**
シミュレーションモデルを機械学習モデルに置き換えるのはムダなことをやっているのではないか？と思われる方もおられるかもしれません。
ホワイトボックスであるシミュレーションモデルを機械学習モデルに置き換える＝ブラックボックス化することになるからです。

しかし、いまの機械学習モデルはSHAP等の登場によりブラックボックスではなくなってきました。モデルの構築は必要ですが、機械学習モデルに置き換えることができればシミュレーションモデルよりも高速化できる可能性があります。
今回の実行においては、20項目近くあるパラメータ（定数・変数含む）で構成されたシミュレーションモデルを、わずか6つの特徴量で精度の確保も解釈もできました。
手当たり次第にシミュレーションすれば、同じ解釈に近づけるかもしれません。ただ時間は圧倒的にかかるだろうと思います。

原理原則をベースに緻密にシミュレーションモデルを組み立てられた方、そのベースとなる物理モデルを考案された方には、機械学習モデルで代用することに申し訳なさも感じますが、「現実と一致しないことがあるが原理原則に忠実なシミュレーションモデル」と、「データを与えれば理屈はどうあれ現実と一致させてくれる機械学習モデル」は、水と油ではないと思うんですよね。

シミュレーションは「実機の結果と合わないなぁ」ということがあります。まったく一致しないということではなく、オフセットが生じたり、特定条件や過渡的な場合で差が見られるということが多いのではないかと思います。
差が生じる要因は様々あると思いますが、シミュレーションはすべての物理モデルを網羅している訳ではありませんので表現できない現実があるのは仕方のないことと思います。

シミュレーションモデルが網羅していない物理モデルが差に影響している場合、シミュレーションモデルに手を加えて対応するのは至難ですが、機械学習モデルで代用できたならば、差を埋める可能性を高めることができます。
結果に影響を与える特徴量を維持し、実機との差に影響するであろう特徴量を機械学習モデルに与えることで精度（差を小さくする）を高めることができるからです。

　
***
**XAIの威力**
話をSHAPやICEに戻しますが、
これらは、機械学習モデルの予測値を分解したり、傾向を把握したい特徴量以外を周辺化し、モデルに当てはめて予測したりしているので、機械学習モデルの精度がそれなりに稼げていないといけないと思いますが、先に述べた可能性の実現につながることも含め、これはあらためてすごいと思います。

仮に機械学習のモデルの精度が”そこそこ”であった場合も、固有技術的観点から傾向との関係性の理解が進み、次のアクションにつながるよりよき気づきが得られる可能性があるようにも思います。

XAIが仕事の質を引き上げてくれる可能性を感じた機会でした。これはいいですねぇ。

***
Deno でウェブ地図の legacy mop-up operation

## 太古のウェブ地図技術をモダンに再実装する
古いウェブ地図技術、特に XML を使うような太古のウェブ地図技術について、その実装を近代化して、その維持コストを下げたいと思います。

この一連の作業に、legacy mop-up operation と名づけたいと思います。いわば、レガシー掃討作戦です。

レガシー技術をモダンに実装する技術に、deno を採用しようと思います。

deno には xml や yaml のライブラリーがあり、それらが割とシンプルでセンスが良さそうです。

## Raspberry Pi への deno のインストール
Raspberry Pi の場合、直接ではなくて rust 経由で deno をインストールするそうです。私は次の通り実行してみました。

```zsh
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install deno --locked
```

## 最初に狙うのは KML SuperOverlay
最初に狙うのは、ZXYタイルにKML GroundOverlay + NetworkLink インタフェースをつける機能としたいと思います。

OSGeo/gdal の gdal2tiles.py に参考になる実装があるので、これを頼りに作っていくことになると思います。

## メモ: 最初は Ruby でやろうと思った
最初は、Ruby で nokogiri でも使って実装しようかと思っていました。しかし、太古の技術を将来に向けて残しておくという目的からすると、できるだけモダンな言語にする方が良いかもしれないと思い、　deno にしてみます。
AWS Lambdaの非同期呼び出し機能やデッドレターキューとか良く分からなかったので検証してみた

## 目次

- [目次](#目次)
- [はじめに](#はじめに)
- [AWS Lambdaの非同期呼び出し機能とは](#aws-lambdaの非同期呼び出し機能とは)
- [検証準備](#検証準備)
  - [SQS](#sqs)
  - [Lambda](#lambda)
  - [EventBridge](#eventbridge)
- [検証内容](#検証内容)
  - [ログ](#ログ)
  - [SQS](#sqs)
- [まとめ](#まとめ)

## はじめに
AWS Lambdaで非同期呼び出し機能がありますが、動作がイマイチ良く分からなかったので実際に検証してみました。

## AWS Lambdaの非同期呼び出し機能とは
Lambdaが非同期呼び出しされた際にエラーとなった場合に、リトライ処理をしたりデッドレターキューにキューを入れることができる機能です。

リトライに関しては以下に記載のあるように、1回目のリトライは1分後、2回目のリトライは2分後に行われます。
> Lambda manages the function's asynchronous event queue and attempts to retry on errors. If the function returns an error, Lambda attempts to run it two more times, with a one-minute wait between the first two attempts, and two minutes between the second and third attempts. 

https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html

言葉で書いてもイメージが湧きづらいと思うので、以下検証してみます。

## 検証準備

### SQS
デフォルトの設定でキューを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/30c8c2d9-1422-5ebb-113a-a9e3bb11bc20.png)

### Lambda
新規作成します。

また、コードはエラーが出るように以下のコードを用意しました。

```javascript
exports.handler = async (event) => {
    // TODO implement
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };
    
    console.error(`ERROR!!!`);
    throw new Error(`ERROR !!!`);
    
    return response;
};
```

また、以下のように非同期呼び出し機能でデッドレターキューサービスに先ほど作成したSQSのキューを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/e78c0705-2755-4a0f-cb4b-25a3d47e9983.png)

### EventBridge
適当に時間を指定し、Lambdaを実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/98669eb0-8b76-4ebf-42c6-c1d0e5358914.png)

## 検証内容

### ログ
以下のように、リトライ処理が行われていることが分かります。

- 20:10 → 初回実行
- 20:11 → 1回目リトライ
- 20:13 → 2回目リトライ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/5c6eff2b-5dde-d24c-228d-0d3df2d40809.png)

### SQS

上記ログのとおり、2回リトライしてもエラーのままであることから、以下のようにデッドレターキューにキューが入っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/20e1dba3-e9c5-dacb-91e1-f5efd7fe96c0.png)

メッセージをポーリングしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/d79edc53-4b33-491b-bc8d-24e7171f0615.png)

中身をみてみると、先ほどのログで確認したリクエストIDやエラーメッセージが入っていることが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882682/d36f6a17-d3e0-9677-7213-0168856c840e.png)

## まとめ

今回はLambdaの非同期呼び出し機能について検証しました。
本機能を使うことで、エラー時にリトライ処理ができること、デッドレターキューにキューが移動することを確認できました。
Lambdaでリトライ処理を実装したい人はこの機能を使ってみても良いかもしれません。
Node.js での認証情報の設定

## はじめに
プログラミング時に認証情報の提供方法によってセキュリティ、保守作業に影響しますので、
どの方式を採用するかを考慮する必要があります。

## AWSのNode.js での認証情報の設定
### AWS 推奨の順序で認証情報を提供する方法
- Amazon EC2 の AWS Identity and Access Management (IAM) ロールからロード
- 共有認証情報ファイル (~/.aws/credentials) から読み込む
- 環境変数から読み込む
- ディスク上の JSON ファイルから読み込む
- JavaScript SDK によって提供されるその他の認証情報プロバイダークラス

### SDK で利用できる認証情報ソースが複数ある場合、デフォルトの選択優先順位
- サービスクライアントコンストラクタで明示的に設定されている認証情報
- 環境変数
- 共有認証情報ファイル
- ECS 認証情報プロバイダーからロードされた認証情報 (該当する場合)
- 共有 AWS 設定ファイルまたは共有認証情報ファイルで指定された認証情報プロセスを使用して取得された認証情報です。
- Amazon EC2 インスタンスの認証情報プロバイダーを使用して AWS IAM からロードされた認証情報 (インスタンスメタデータで設定されている場合)

### 注意点
アプリケーションで AWS 認証情報をハードコードすることは可能ですが、そうしないことをお勧めします。認証情報をハードコーディングすると、アクセスキー ID とシークレットアクセスキーが公開される危険があります。


元Doc：[Node.js での認証情報の設定](https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html)
6 ตำนานนักเตะไทย

เชื่อว่าหลาย ๆ คนนั้นอาจจะเคยได้ยินและรู้จักกับ ตำนานนักเตะไทย บางคนมากันบ้างแล้ว แต่วันนี้นั้นเราก็จะมานำ 6 ตำนานนักเตะไทย ที่หลายคนนั้นอาจจะรู้จักหรือไม่รู้จักกันให้มากขึ้นกับ ตำนานนักเตะไทย เหล่านี้

1.ธวัชชัย ดำรงอ่องตระกูล

ธวัชชัย ดำรงอ่องตระกูล หรือ โค้ชวัง อดีตกองกลางตัวตัดทีมชาติไทยยุคดรีม ลงสนามรับใช้ทีมชาติไทยไปทั้งสิ้น 73 นัด และสามารถ ทำประตูได้ 10 ประตู โดย 1 ใน 10 ประตู ที่สร้างชื่อเสียงฮือฮานั้น คือลูกยิงฟรีคิกระยะไกล ใส่ประเทศเกาหลีใต้ และเป็นประตูชัย ให้ทีมชาติไทยเอาชนะไปได้ 2-1 ....อ่านต่อที่ <a href="https://www.thaileaguefootball.com/6-%E0%B8%95%E0%B8%B3%E0%B8%99%E0%B8%B2%E0%B8%99%E0%B8%99%E0%B8%B1%E0%B8%81%E0%B9%80%E0%B8%95%E0%B8%B0%E0%B9%84%E0%B8%97%E0%B8%A2/">ตำนานนักเตะไทย</a>
【JavaScript】ワンクリックで複数のページが開くリンクをブログに設置する方法

知人の依頼で作成

超簡単です、非エンジニアでもhtmlをいじれればできると思います。

ソースコード
-

```html
<p id="0629" style="color: #0000ee; text-decoration: underline;">ここクリックするとタブが開きます</p>

<script>
document.getElementById('0629').onclick = function(){
	window.open('https://www.google.com/?hl=ja');
	window.open('https://www.google.com/?hl=ja');
	window.open('https://www.google.com/?hl=ja');
	window.open('https://www.google.com/?hl=ja');
	return false;
}
</script>
```

指定したidのものをクリックしたさいに関数が発火するようにしています。

URLは仮でgoogleにしていますが、もちろん任意のもので大丈夫です。
例えばアクセスするとクーポンが取得できるようなページのリンクにすれば、ワンクリックで一括で大量のクーポンが取得できるような形にすることができますね。

`window.open〜`の部分をさらに増やすことも可能ですが、リクエスト先のサーバに負荷がかかるので、悪用厳禁です。
paiza問題集から組になったデータの入力(PHP)

paizaの標準入力問題集から組になったデータの入力をPHPで実装しました。
今回は8番目のデータを標準出力で出力します。

```PHP
 //データの個数を入力する
 $num = trim(fgets(STDIN));
    for($i=1;$i<=$num;$i++){
//データを入力する
        $data = trim(fgets(STDIN));
//８番目のデータの場合、標準出力に出力する。
        if($i == 8){
            echo $data;
        }
    }
```

以上のコードになります。
Railsでデータをランダムに１つだけ取り出す方法

## はじめに
プログラミング初学者の自分用アウトプットです。
誤った知識や記述があれば教えていただけると幸いです。

## 開発環境
- ruby2.6.3
- rails6.1.4

## やりたいこと
データベースに投入したデータからランダムにデータを１つだけ取り出して表示したい。

## 試したこと

① RANDOM()を使用
```posts_controller.rb
@post = Post.order("RANDOM()").first
```
しかし上記では本番環境（MySQL）では動かない。
本番環境用にRANDOM()➡︎RAND()へ変更すると今度はローカル環境で動かない...

② shuffleを使用
```posts_controller.rb
@post = Post.all.shuffle.first
```
上記の記述でうまくいきました！
Tera Term で Ed25519 鍵の読み込みに失敗した件

最近では SSH 鍵作成時の暗号形式に Ed25519 を使用するのがよいとされているらしく、早速コマンドプロンプトを立ち上げ ssh-keygen コマンドでキーペアを作成しました。

Rlogin や Cyberduck では正常に接続できるものの、Tera Term だけは

```
SSH2秘密鍵の読み込みに失敗しました
error:0906D06C:PEM routines:PEM_read_bio:no start line
```

と表示が出て接続に失敗します。

エラーメッセージで検索をかけても解決に至りませんでした。コマンドプロンプトで作成したのが悪いのかと思い、Tera Term で Ed25519 形式のキーペアを作成しましたが、こちらでも同じ状況でした。

### 解決方法

Tera Term を最新版にアップデート （ver4.86 → ver4.106） すると正常に接続できるようになりました。

バージョンが古かったとは言え、Tera Term 自身で作成した鍵が読み込めないとは思わず、無駄に時間を使ってしまいました。
Azure Functions を使って、夕方になると退勤を呼びかけるボットを作ってみる

2回に渡って、LINE WORKS のオウム返しBotを作ってみました。

今回は、夕方になると 「そろそろ帰りましょう」 と優しいメッセージを送ってくれる Bot を作ってみます。

オウム返しBotと同じように、新しい関数を作成します。このとき、テンプレートには `Timer trigger` を選択し、Schedule には `0 30 8 * * 1-5` を指定します。これは、月曜日から金曜日の 17:30 (UTC で 8:30)に動きますよ、という意味です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667330/c8197d1d-9922-ba80-fd0b-efea79ebcd69.png)


新しい関数 (TimerTrigger1) を開いて、以下のコードを貼り付けます。
```powershell
param($Timer)

$clientId       = $env:CLIENTID
$clientSecret   = $env:CLIENTSECRET
$privateKeyFile = $env:PRIVATEKEYFILE
$svcAccount		= $env:SERVICEACCOUNT
$botId          = $env:BOTID
$userId         = $env:SENDTO
$Scope 			= "bot"

# GET Access Token 
$PrivKeyPath    = "D:\home\site\wwwroot\" + $privateKeyFile 

$rsaPrivateKey = Get-Content $PrivKeyPath -AsByteStream

$iat = [int](Get-Date -UFormat %s)
$exp = $iat + 3600

$payload = @{
    sub = $SvcAccount
    iat = $iat
}
    
$jwt = New-JWT -Algorithm 'RS256' -SecretKey $rsaPrivateKey -PayloadClaims $payload -ExpiryTimestamp $exp -Issuer $clientId
    
$requestHeader = @{
    'Content-Type' = 'application/x-www-form-urlencoded'
}

$requestBody = @{
    assertion     = $jwt
    grant_type    = 'urn:ietf:params:oauth:grant-type:jwt-bearer'
    client_id     = $clientId
    client_secret = $clientSecret
    scope         = $Scope
}

$url = 'https://auth.worksmobile.com/oauth2/v2.0/token'
$response = Invoke-RestMethod -Uri $url -Method POST -Headers $requestHeader -Body $requestBody

$sectoken = ConvertTo-SecureString $response.access_token -AsPlainText

# そろそろ帰ろう
$URL = "https://www.worksapis.com/v1.0/bots/$botId/users/$userId/messages"

$reqBody =@{
	content = @{
		type = 'text'
		text = 'そろそろ帰りましょう'
	}
}
$reqBody = $reqBody | convertto-json
$reqBody = [System.Text.Encoding]::UTF8.GetBytes($reqBody) # hack for MOJI-BAKE
Invoke-WebRequest -Method POST -Uri $URL  -body $reqBody -Authentication Bearer -Token $secToken -ContentType "application/json"

$reqBody =@{
	content = @{
		type = 'sticker'
        packageId = "1"
        stickerId = "106"
	}
}
$reqBody = $reqBody | convertto-json
Invoke-WebRequest -Method POST -Uri $URL  -body $reqBody -Authentication Bearer -Token $secToken -ContentType "application/json"
```

［設定］-[構成]-[アプリケーション設定]から、［SENDTO］ という名前の新しいアプリケーション設定に、自分の email アドレス （yourname@yourcompany） を登録しておきます。

以上で完成です。
時間になったら、ボットが退勤を促してくれます。これで、うっかり残業もなくなります。
ABC077 C - Snuke Festival を 3通りで解く 二分探索/イベントソート

https://atcoder.jp/contests/abc077/tasks/arc084_a

- 解法1: 公式解説通りです
- 解法2: イベントソートのように解きます
- 解法3: LeetCodeっぽい解き方をします。入力がソートされていればO(N)です。


# 解法1: すべてソートしておき、B[i]をもとに二分探索
公式解答通りです。
時間計算量はソートに$O(NlogN)$、各探索に$O(NlogN)$です。
空間計算量は$O(N)$です。

<details><summary>実装(Python)</summary><div>

```Python
from bisect import bisect_left, bisect_right
n = int(input())
d1 = list(map(int, input().split()))
d2 = list(map(int, input().split()))
d3 = list(map(int, input().split()))
d1.sort()
d3.sort()
ans = 0
for center in d2:
    ind1 = bisect_left(d1, center)
    ind3 = bisect_right(d3, center)
    ans += (ind1) * (n - ind3)
print(ans)
```
</div></details>

https://atcoder.jp/contests/abc077/submissions/32649275

# 解法2: イベントソート
上中下の各値を時間とみなしてイベントソートします。ここで、$cnt1$をこれまでに出現した上パーツの個数、$cnt3$をこれまでに出現した下パーツの個数とします。
- 中パーツのイベントを処理するとき、$それまでの1の数 \times (n - それまでの3の数)$のパーツを使うことができます
- 同一の時間に上中下のパーツを処理するときの処理に気を付けます。上の式を睨み、下パーツのイベント、中パーツのイベント、上パーツのイベントの順で処理できるようにします。今回の実装ではそれぞれのイベントを$111, 22, 3$としてソートすることで実装しました。

時間計算量はイベントの作成に$O(NlogN)、$ソートに$O(NlogN)$、各探索に$O(1)$です。
空間計算量は$O(N)$です。

<details><summary>実装</summary><div>

```Python
n = int(input())
d1 = list(map(int, input().split()))
d2 = list(map(int, input().split()))
d3 = list(map(int, input().split()))
event = []
for x in d1: event.append( (x, 111) )
for x in d2: event.append( (x, 22) )
for x in d3: event.append( (x, 3) )
event.sort()
cnt1, cnt3 = 0, 0
ans = 0
for _, e in event:
    if e == 111: cnt1 += 1
    elif e == 3: cnt3 += 1
    elif e == 22: ans += cnt1 * (n - cnt3)
print(ans)
```
</div></details>

https://atcoder.jp/contests/abc077/submissions/32832749

# 解法3: ソートして順に見る(ソートされているならばO(N))
上中下パーツがソートされているときに高速に動作します。
- まず、すべてのインデックスを$i1=i2=i3=0$とし、それぞれ上中下パーツのindexとします。
- i2をインクリメントしながら次の処理を行います。
- i1が今のパーツよりも小さい(<)間、i1++します。これにより、`i1の位置はi2のパーツよりも大きな最初のindex`です。
- i3が今のパーツ以下(<=)の間、i1++します。これにより、`i3の位置はi2のパーツよりも大きな最初のindex`です。
- つまり、$i1 \times (n - i3)$個のパーツを使うことができます

これは先のイベントソートと同じように思えますが、イベントのソートが不要のため、最初からソートされているときは高速に動作します。

時間計算量は$ソートに$O(NlogN)$、各探索に$O(1)$です。
空間計算量は$O(N)$です。

<details><summary>実装(Python)</summary><div>

```Python
n = int(input())
d1 = list(map(int, input().split()))
d2 = list(map(int, input().split()))
d3 = list(map(int, input().split()))
d1.sort()
d2.sort()
d3.sort()
i1, i3 = 0, 0
ans = 0
for i2 in range(0, n):
    while i1 < n and d1[i1] <  d2[i2]: i1 += 1
    while i3 < n and d3[i3] <= d2[i2]: i3 += 1
    ans += i1 * (n-i3)
print(ans)
```
</div></details>

https://atcoder.jp/contests/abc077/submissions/32832891
C#フォームアプリの多言語対応時に自国語リソースが参照されず詰まったメモ

# TL;DR
C#プロジェクトプロパティ > アセンブリ情報 > ニュートラル言語 が `(なし)` になってるか確認しよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257042/b2ee1a93-7be2-4129-52d9-f41391b7d00c.png "テスト用C#フォームプロジェクトのプロパティ")

# Environments
* Microsoft Visual Studio Community 2022 (64 ビット) - Preview 
Version 17.3.0 Preview 2.0
* .Net framework 4.8
# What happened
C#フォームプロジェクトをある程度作成進めた後、UIの日本語表示対応に手を付けようとして
`Form1.ja-JP.resx`を追加しフォームエディタでも日本語が表示されていて安心していたが、
いざ実行するとニュートラル用の`Form1.resx`の値しか参照してくれなかった

:::note 
ja-JP.resx等の追加の仕方は [ReMIXのブログ](URL "https://remix-yh.net/1478/") 様を参考にしました
:::
:::note warn
**フォームエディタ上ではこちらの想定通り日本語が表示されてしまう** ため原因把握に時間がかかった
:::

# How to resolve
プロジェクトのプロパティから、アセンブリ情報 > ニュートラル言語 が `日本語(日本)` になっていたので
`なし` に変更したら正しく読めるようになった

どうやら`ResourceManager`は、指定された`CultureInfo`が`NeutralCulture`と一致する場合、
ローカライズ用アセンブリへの参照を行わない挙動らしい
| ニュートラル言語 | UICulture | 挙動 |
|:-:|:-:|:-:|
| 日本語(日本) | ja-JP | `Form1.resx` のみ参照 |
| (なし) | ja-JP | `Form1.resx` + `Form1.ja-JP.resx` を参照 |

# Why it set?
基本的に日本語のアプリだしニュートラルも日本語でええやろ… とかアセンブリ情報入れながら考えてたようなうろ覚え:weary:
NgRxを使ったことがない人間の備忘録

### NgRxを調べることにした背景
- Angularでアプリを作っている中で、NgRxの存在を知った
- 状態管理の必要性もわからないが、せっかくなら一度使ってみるぐらいはしてみたいと思った

以下、調べたことを備忘録としてまとめま〜〜〜す

https://zine.qiita.com/interview/creek-and-river-job-agent/

※5分ルール

#### そもそも状態管理とは
https://zenn.dev/gagaga/articles/state-management

#### なぜNgRxを使う必要があるのか（状態管理をする必要があるのか）

https://dblog.athome.co.jp/entry/2021/12/23/170000

> 今回の開発アプリがSPAであることや、UI面での要求により、状態管理が必要となりました。

> アプリ全体として、「必要なデータ（状態）」を「どのタイミングで取得するか、どうやって更新するか、いつまで保持するか」を考慮しなければならなくなりました。

---

https://qiita.com/Yamamoto0525/items/03155acbce1ffd1d037e

>アプリケーションの規模が大きくなってObservableの数が増え始めると、それぞれのObservableの配線が複雑になって、Stateがどのような状況になっているかが不明瞭になっていきます。

>状態管理が複雑になってしまうと、何か不具合があったときにどのObservableによるものなのかが判断しづらく、解消に時間がかかってしまったり、不要なObservableがメモリを圧迫してパフォーマンスに影響を与えてしまうようなことが考えられます。この事態を避けるために有効な手段が@ngrxライブラリの導入です。

---

https://qiita.com/kouMatsumoto/items/c8297466c1824953632f

> 個人的にngrxを使う理由は主に以下の2つが大きいです。
> - 開発者間での共通な設計思想
> - コンポーネントテストの容易性


#### そもそもNgRxとは

https://qiita.com/kouMatsumoto/items/c8297466c1824953632f

> ngrxとはAngularアプリケーションの状態管理を適切に扱うためのライブラリ集です。
一言で簡潔に説明すると、AngularとRxJSに最適化したReduxです。

>| ライブラリ名 | 概要 |
>| :-|:-|
>| @ngrx/store | Store, Action, Reducerなどの機能を提供するモジュール。 |
>| @ngrx/store-devtools | Redux Devtools Extensionを使う為のモジュール。 |
>| @ngrx/router-store | Routerのデータをngrxで扱う為のモジュール。 |
>| @ngrx/effects | 副作用のある処理を扱う為のモジュール。 |
>| @ngrx/entity | モデルのコレクション処理を扱い易くするモジュール。 |

他にも色々あるみたい

https://qiita.com/Yamamoto0525/items/03155acbce1ffd1d037e

---

##### ※Reduxについて

https://qiita.com/kitagawamac/items/49a1f03445b19cf407b7


#### 何から勉強したら良いだろう

https://qiita.com/Yamamoto0525/items/03155acbce1ffd1d037e

https://dblog.athome.co.jp/entry/2021/12/23/170000

https://ngrx.io/guide/store#tutorial


#### NgRxは難しいらしい
https://tercel-tech.hatenablog.com/entry/2020/01/18/175718


#### lacolacoさん

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

>（32:00~）effectsは好きじゃない

---

https://spectrum.chat/ng-japan/general/~d1434fe1-4253-4568-a2ca-8e37d7a3a511

> チームメンバーの経験のバックグラウンドなど未知数が多いのですが、それでも状態管理に関する責務は一か所に集めておいたほうがいいと思います。NgRxでなくてもよいですが、Storeだけならキャッチアップにもそれほど困難ではないかと思います。（Redux自体にはブログ記事などたくさんあるので）そして初心者ほど、NgRxがサポートしているRedux Devtoolを使ったデバッグにはかなり助けられると思います。Effectsやその他周辺のパッケージのことは置いておいて、Storeだけいれるのをおすすめしたいです。

---

https://github.com/classi/frontend-devkit/issues/248

> NgRxのFeature Storeを小さく使おうというモチベーションは、 @ngrx/component-store やその他の手法のほうが圧倒的に構成要素がシンプルであり、もはや推奨できない。
standalone componentなどの流れも踏まえ、現在推奨したいのはコンポーネントローカルなサービスによる状態管理である。

https://blog.lacolaco.net/2022/05/angular-state-management-patterns/
現場で知らないと大変！？インターフェースとは？

今、職場でよく耳にするのが、インターフェースです。意味がわからないままだと、大変なことになるので、インターフェースについてまとめてみました！

# インターフェース
インターフェースとは、接点、境界面、接触面、接合面、仲立ち、橋渡しなどの意味を持つ英単語です。IT関連では、二つのものが接続・接触する箇所や、両者の間で情報や信号などをやりとりするための手順や規約を定めたものを意味します。「ハードウェアインターフェース」「ソフトウェアインターフェース」「ユーザーインターフェース」の三つに大別できます。

## ハードウェアインターフェース（hardware interface）

ハードウェアインターフェース（hardware interface）とは、ハードウェア間のインターフェースのことです。複数のハードウェアのあいだでデータを転送するときに互いをつなげるケーブルのコネクタ形状、データのフォーマット、送受信の約束事といったもののことです。

例えば、マウス・キーボード、プリンター、外付けHDD、USBメモリーなどがあります。


## ソフトウェアインターフェース（software interface）
ソフトウェアインターフェース（software interface）とは、アプリケーションソフト同士やアプリケーションソフトとOS（オペレーティングシステム）間のデータのやり取りのための手順・データ形式のことです。
アプリケーションの連携に使うAPI（アプリケーション・プログラミング・インターフェース）などが当てはまります。

例えば、API（Application Programming Interface）アプリケーションを連携するものや ABI（Application Binary Interface）、ソフトウェアの互換性を保障するもの、プロセス間通信、ネットワーク越しでソフトウェアを連携させる際のプロトコルなどがあります。


## ユーザーインターフェース（User Interface）
ユーザーインターフェース（User Interface）は一般的にユーザーと製品やサービスとの接点すべてのこと、
言い換えると、「ユーザーの目に触れる部分」がUI(ユーザーインターフェース)です。

つまり、サイト上に表示されるデザイン、レイアウトや画像、文字のフォントフォント、外観などのユーザーの目に触れる全ての情報がUI(ユーザーインターフェース)です。さらに、メニューやボタンの操作性も含まれています。
少し外側のキリのいい数値を求める

<!-- 少し外側の値 -->

# 概要

小ネタです。

今回作成するpythonの関数を使うと

```python
CalcOuterRange([-0.1234, 0.4321])     # 出力：[-0.2, 0.5]
CalcOuterRange([-0.1234, 0.4321], -1) # 出力：[-0.13, 0.44]
CalcOuterRange([-1234, 4321])         # 出力：[-2000.0, 5000.0]
CalcOuterRange([-1234, 4321], -1)     # 出力：[-1300.0, 4400.0]
```

というように少し外側のキリのいい数値を得られます。

# はじめに

測定データの処理で、グラフの表示範囲やパラメータの探索範囲などを自動で設定させるとき、
「この計算値とこの計算値のちょっと外側」
にしておきたいということがあります。

簡単なやり方としては、計算で得た範囲の小さい方が$s_1$で、大きい方が$s_2$なら、
「$0.9 \times s_1$ ～ $1.1 \times s_2$」
というようにして設定範囲を求めます。

しかし、これでは$s_1$や$s_2$が負だと困りますし、2.38472...とかの小数だったりすると結果をレポートするときに「この変な値はなんだ？」と突っ込みが入るのが困りものです。

そこで、ちょっと外側だけどキリのいい数値を自動で求めてしまおうという方法です。

# 方法

まずは数値のオーダーが必要です。

自動化をしたいので、単純に「0.9かけて四捨五入すればいいでしょ」とはなりません。  
温度計だったりマイクロメータだったりといろいろなオーダー感の測定器からのデータへの対応が必要です。  

数値のオーダーといえば対数です。  
そこで、$log_{10}(s_2 - s_2)$を求めて四捨五入することにします。  

この結果を使って10の累乗を計算（これに「解像度」と勝手に名前をつけました）し、それで$s_1$の商を求めて「解像度」を掛け戻してやると、「ちょっと小さくてキリのいい値」が求まります。  
「ちょっと大きくてキリのいい値」は、同様に$s_2$の商を求めた後に1を足してから「解像度」を掛け戻すことで求めることができます。

問題は、「ちょっと」の程度をどうするかです。  
$s_1 = -0.1234, s_2 = 0.4321$だったとき、「-0.2～0.6」にするのか「-0.13～0.44」にするのかは、その人の感性や置かれた状況によります。（「-1～1」がいいという人もいるかもしれない？）

これは四捨五入する相対的な桁の調整ですので、「解像度」の調整用にパラメータを入力できるようします。

そして、できたのが次の関数です。

# python関数

numpyを `import numpy as np` として読み込んでおいてください。

```python
# ====================================
# CalcOuterRange
#  　範囲のちょっと外側の値を返す関数
# 引数：
#  　listX: 範囲の下と上の値を含む数値リスト
#  　param: 解像度調整用パラメータ（デフォルト：0）
# 返り値：
#  　少し外側の値のリスト（少し小さな値,少し大きな値）
# ====================================
def CalcOuterRange(listX, param=0):
    S1 = min(listX)      # 範囲の下の値
    S2 = max(listX)      # 範囲の上の値
    dS = S2 - S1         # 上と下の差

    SOrder = np.round(np.log10(dS),0)    # 差のオーダーを求める
    SRate = 10**(SOrder-1 + param)       # 解像度を計算
    r1 = (S1 // SRate - 0.) * SRate      # 少し小さな値
    r2 = (S2 // SRate + 1.) * SRate      # 少し大きな値

    return [r1,r2]
```

入力する際に、「一番目が上だっけ？下だっけ？」とか「リストからいちいち最大値と最小値をとるのが面倒くさい」とかという人（私だ…）のために、リストで入力を受けるようにしました。

# 付記

浮動小数点数の宿命として、「0.6000000000000001」といった半端がついた値が返ってくることがあります。  
これは、簡単に言えば、「0.6が表示上そうなっているだけ」ですので、半端は無視してください。  
（詳細は浮動小数点数が解説されているサイトを参照してください。
例：[「浮動小数点って何?」](https://qiita.com/angel_p_57/items/24078ba4aa5881805ab2)）
AWSソリューションアーキテクトアソシエイト(SAA)合格体験記 1ヶ月で合格

## はじめに

ご覧いただきありがとうございます。
筆者のえきそんぱいと申します。

2022年6月にAWSソリューションアーキテクトアソシエイトに合格しました。
その体験記を記載します。これから受験する方の参考になればと思います。

## 筆者の前提知識
- AWSに関する業務経験はなし
- AWSクラウドプラクティショナーを保有(過去に取得してほぼ忘れている状態)
- オンプレのインフラ運用開発業務経験あり

## 学習の進め方
udemyの講座のみを利用して約1ヶ月ほど学習しました。3ステップで記載します。

### 1.試験を申し込む
資格試験の第一歩です。試験申し込みを行い勉強するしかない状況に追い込みました。

### 2.AWSのハンズオンをやる

実施期間：約2週間

udemyのこの講座を利用しハンズオン通じて学習しました。
[【2022年版】これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座](https://www.udemy.com/share/101WKk/)

__ただし、全ての講義は全部はやってません。__
IAM、VPC、EC2、S3、ELB、RDSはハンズオンまでしっかり行い、その他サービスは説明を聞いて実際のハンズオンまでやりませんでした。

### 3.過去問をやる

実施期間：約2週間

65問の過去問4回分を解いて正答率80%以上になるまで繰り返し実施しました。
わからないサービスはあとで調べてノートにまとめました。

過去問はこちらを利用しました。
- 2で紹介した講座の過去問2回分
- 以下のudemyの過去問2回分
[【2022年版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/share/101rfM/)

## 最後に

筆者の得点は「788点」でした。合格点720点ですのでギリギリでした。。

学習時間や過去問回数を増やすことで、もう少し安全に合格できると思います。
これから受験する方の合格をお祈りしています:pray:

最後までご覧いただきありがとうございました。
Azure Functions を使って、LINE WORKS のオウム返し Bot を作ってみる (その1:Bot準備編)

今回は、Azure Functions を使って、LINE WORKS API 2.0 を利用したオウム返し Bot を作ってみます。今回も言語には PowerShell を利用します。

まず、Developers Console で、Bot を作成します。
API Interface には API 2.0 を指定し、Callback URL は Off にします。（後で入力します）
![スクリーンショット 2022-06-28 15.18.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667330/b9ca4a1b-b155-a769-8e18-608e9a3b5436.png)
Bot を作成すると Bot ID と Bot Secret が発番されます。後で使いますので、これらの値を控えておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667330/74f21b88-7527-5068-117f-6bdc210d1449.png)


Admin Console でも、［サービス］ - [Bot] から、作成した Bot を追加し、ドメインで利用可能にしておきます。
<img width="640" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667330/caeb0aab-2b37-9f67-8a44-51bc0d269ae6.png">

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667330/5d39ebc9-0429-63f8-9145-81ea79547599.png)

Bot の公開設定もお忘れなく。
<img width="360" alt="img.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667330/6f29c84f-4daa-2e53-8935-beed9378d5d8.png">

Bot 側の準備は、一旦ここまでです。