OmniAICreator/Qiita-1.07M huggingface dataset:
Flutter (初級) override に関して

親クラスで定義した機能を他のクラスに引き継がせるのに使われる`override`ですが今回は簡単な鍋料理レシピを題材にコードで流れを書いてみました。
```cook.dart
// なべ料理のレシピを表すクラスを作成
class Cook {
  // 具材の名称をtoolNameとする
  final String _toolName; 
  // 下処理の工程をpreparationとする
  final String _preparation; 
  // Cookクラスのインスタンスにthisを使って入れれば使用可能な状態になる
  Cook(this._toolName, this._preparation);
  // Getterを利用してCookクラスのプライベート変数を参照できるようにする
  String get toolName => _toolName;
  String get preparation => _preparation;

  // 細かい処理のポイントを記述する為のメソッド
  List point(p) {
    return p;
  }
  // 継承させる具材の為のメソッド
　List tool(t) {
    return t;
  }
}
```
```ingredients.dart
import 'cook.dart';
//　料理の具材を表すクラス 
class Ingredients extends Cook {
  // superで親クラス(Cook)のコンストラクタを呼び出すことができる
  Ingredients(String _toolName, String _preparation)
      : super(_toolName, _preparation);
}
```
```soup.dart
import 'cook.dart';
//　合わせ出汁を表すクラス
class SoupStock extends Cook {
  SoupStock(String _toolName, String _preparation)
      : super(_toolName, _preparation);
}
```
```pod.dart
import 'cook.dart';
// 完成した鍋を表すクラス
class Casserole extends Cook {
  Casserole(String _toolName, String _preparation)
      : super(_toolName, _preparation);

  // 親クラスのポイントを継承させて返す
  @override
  List point(p) {
    return ["合わせ出汁に", "下の材料を順に入れ", "一煮立ちさせる"];
  }
  // 試しにこちらも継承させてみる
   @override
  List tool(t) {
    return ["豚肉", "人参", "白菜", "小松菜"];
  }
}
```
```main.dart
import 'cook.dart';
import 'ingredients.dart';
import 'soup.dart';
import 'pod.dart';
//メイン関数でそれぞれのメソッドを呼び出しログ(print)にだす
void main () {
  Cook pork = Ingredients("豚肉", "お酒で臭いを消す");
  print(pork.toolName);
  print(pork.preparation);
  var pointA = pork.point(["酒につけた後かるく揉み込む", "一口大にカット"]);
  print(pointA);
  print("");

  Cook vegetable = Ingredients("野菜", "しっかり洗浄する");
    print(vegetable.toolName);
  print(vegetable.preparation);
  var pointB = vegetable.point(["白菜", "小松菜", "人参", "それぞれ一口大にカット"]);
  print(pointB);
  print("");

  Cook soup = SoupStock("和出汁", "煮干しを水から煮る");
  print(soup.toolName);
  print(soup.preparation);
  var pointC = soup.point(["煮干し", "沸騰したら削り節", "削り節を投入したらすぐ漉す"]);
  print(pointC);
  print("");
  // pointD・Eでは継承されてきた内容が入ってくる
  Casserole pot = Casserole("鍋完成", "それぞれの材料を合わせて火にかける");
  print(pot.toolName);
  print(pot.preparation);
  var pointD = pot.point(p);
  print(pointD);
  var pointE = pot.tool(t);
  print(pointE);
}
```
ちょっと冗長になってっしまいましたが、親クラスである`Cook`クラスのメソッドの`point()`と`tool()`を子クラスである`Casserole`クラスで使えているよと、伝われば。
![スクリーンショット 2022-12-21 12.23.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/492009b7-25ce-3928-0f12-088a61dd3b52.png)
【25日目】Discordに危険なURLが送られたら自動で削除

# はじめに
こんにちは、なりかくんです。
今回は、discord.jsを使って危険なURLが送られた場合に自動で削除するBotを作ってみようと思います。

# 危険なURLの判断
今回、危険なURLの判断はGoogleのSafe Browsing Lookup APIを利用します。このAPIにURLを投げてあげると危険かどうかを判断してくれるという優れものです。
詳しくはドキュメントをお読みください。
https://developers.google.com/safe-browsing/v4/lookup-api

# 実際に作ってみる
では実際に作ったプログラムはこちらになります。
```js:googlesafebrowsing.js
const request = require("request");
const { Client, GatewayIntentBits, IntentsBitField } = require('discord.js');
const { token } = require('./config.json');

const client = new Client({ intents: [GatewayIntentBits.Guilds, IntentsBitField.Flags.GuildMessages, IntentsBitField.Flags.MessageContent] });

client.on('ready', () => {
	console.log(`${client.user.tag}でログインしました。`);
});

client.login(token);

client.on('messageCreate', async message => {
	try {
        if (message.author.bot) return;
        let urls = String(message.content).match(/https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#\u3000-\u30FE\u4E00-\u9FA0\uFF01-\uFFE3]+/g);
        if (urls) {
            let safeResult = await getSafe(urls);
            if (safeResult.matches) {
                message.delete();
            }
        }
	} catch (error) {
		console.error(error);
	}
});

function getSafe(urls) {
    return new Promise((resolve, reject) => {
        request({
            url: `https://safebrowsing.googleapis.com/v4/threatMatches:find?key=<API Key>`,
            json:  {
                "client": {
                    "clientId":      "<clientId>",
                    "clientVersion": "1.5.2"
                },
                "threatInfo": {
                    "threatTypes":      ["MALWARE", "SOCIAL_ENGINEERING"],
                    "platformTypes":    ["WINDOWS"],
                    "threatEntryTypes": ["URL"],
                    "threatEntries": urls.map(f => {
                        return { "url": f }
                    })
                }
            },
            method: "POST"
        }, function (error, response, body) {
            if (error) {
                reject(error);
            } else {
                resolve(body);
            }
        });
    });
}
```
まあ、投げるデータはドキュメントを読んでもらえればわかりますが、URLを複数個検知した時用に
```js
urls.map(f => {
    return { "url": f }
}
```
で配列にしてから投げるようにしています。

また含まれていれば、matchesという配列が現れるのでそれを確認して、検出しています。

検知時
```js
{
  matches: [
    {
      threatType: 'SOCIAL_ENGINEERING',
      platformType: 'WINDOWS',
      threat: [Object],
      cacheDuration: '300s',
      threatEntryType: 'URL'
    }
  ]
}
```

無検知時
```js
{}
```

なお、危険なURLで試したい場合は以下のページが便利です。
https://testsafebrowsing.appspot.com/

以上です、最後までお読みいただきありがとうございました。
最近 brew upgrade したら asdf が何か変だ

最近 [Homebrew](https://brew.sh/) で提供される [adsf](https://asdf-vm.com/) のバージョンが 0.10.2 から 0.11.0 に[更新されました](https://github.com/Homebrew/homebrew-core/commit/3a31db63369fae772411e6a01192ccd10403d3d7)。が、インストール済みの asdf を単に `brew upgrade` で更新しただけだとうまく動かなくなりました。

## asdf.sh の場所が変更されてるぞ

以前はシェルの初期化スクリプトに

``` bash
    . "$(brew --prefix asdf)/asdf.sh" 
```

と書いてましたが、今後は以下の様に記載する必要があります。

``` bash
    . "$(brew --prefix asdf)/libexec/asdf.sh" 
```

シェルの初期化スクリプトを更新したらシェルを再起動すると反映されます。

## reshim がうまく動かないぞ

asdf でインストールした各種ツールは `~/.asdf/shims` の中にあるスクリプトを経由して起動されるのですが、このスクリプトの中には古いバージョンの asdf のパスがハードコーディングしてあるので、スクリプトを更新する必要があります。

そのためには `asdf reshim` を実行すればいいはず……なのですが、asdf 0.11.0 だとなぜかうまくいかないみたいです。 `rm -fr ~/.asdf/shims` でスクリプトを削除してから `asdf reshim` を実行するとうまく動きました。

ちなみに、[この件に関する修正](https://github.com/asdf-vm/asdf/pull/1311)が先ほど入った様なので、0.11.0 の次のバージョンでは直る予感がします。
【Alpine.js】x-initでAPIを扱っていく

# x-initとは
Alpine.jsを呼び出すときに最初に行う処理です。
こちらで説明してます。

https://qiita.com/yowatsuyoengineer/items/13caa80417ce08f0bef5

# x-initでAPIを叩く例
JSONplaceholderからデータを持ってきてます。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="XWBJMar" data-user="gorimatyan" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/gorimatyan/pen/XWBJMar">
  Untitled</a> by gorimatyan (<a href="https://codepen.io/gorimatyan">@gorimatyan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


取ってきたtodoはオブジェクトなので、生のJavaScriptと同じ記法で取り出すことができます。
```
todo.title
```

# 持論
Laravelを使うならこの辺のデータ取得はコントローラーやLivewireで行った方が、フロントエンドとバックエンドを分けて実装できてメンテもしやすい気がします。
私は今回紹介した記法は使わず、コントローラーやLivewireで今後もデータを渡すつもりですが、一応紹介してみたという試みでござんした。

# まとめ
こういう書き方があることを知っておくと、どこかで使えることに気付けるからヨシ！！！
Vue.jsでページをリロードするとstate(Vuex)がリセットされるのを防ぎたい

# 追記

なし

# はじめに

Vuex の仕様上ブラウザがリロードされると Store の保持している情報が消えてしまいます。
それを防ぎたい同じ気持ちの方へ、防ぐ方法をシンプルにお伝えします。
今回は、vuex-persistedstate を使用します。
具体的にはStore のデータを localstorage や sessionstorage に保存することになります。

今回は、sessionstorageに保存します。（私がこちらで実装した為）

# インストール

### npm
```Bash
npm install --save vuex-persistedstate
```

### yarn
```Bash
yarn add vuex-persistedstate
```

# storeファイル設定

### store.js
```Javascript
import { createStore } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import sample from '@/store/sample'

const store = createStore({
    modules: {
        sample  : sample,
    },
    plugins: [createPersistedState({storage: window.sessionStorage})]
})

export default store
```

### app.js
```Javascript
import App from '@/App.vue'
import store from '@/plugins/store'
import { createApp } from 'vue/dist/vue.esm-bundler'

const app = createApp(App)
app.use(store)
app.mount('#app')
```

今回はsessionstorage を使用するので storage: は window.sessionStorage を指定しています。
デフォルトでは localstorage が使用されます。

# 確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3076818/9b069db7-1f54-880f-f29b-98a82c280b69.png)

上記を参考にGoogleChromeの開発者モードで アプリケーション を選択し、セッションストレージ を選ぶと保存できているかが確認できます。

# まとめ

vue3、vuex4でも使えるのはありがたいです。

# 参考リンク

- https://github.com/robinvdvleuten/vuex-persistedstate
VMware ESXi HostClient ブラウザ要件(6.5/6.7/7.0/8.0)についてまとめてみた(:3[▓▓]

# はじめに
<!-- 発端や概要を記載 -->
セキュリティがちがちのVDI端末とかで作業する際に、通常と同じような最新に近いブラウザバージョンで作業できるとは
限らないのでブラウザ要件起因でまともに作業（オペレーション）できないとかあるかもしれません。

ときにはオフライン版を申請して持ち込んだりしないと作業ができないかもしれないですし、
比較的時間のあるPJなら設計段階で最初に確認する要件とは思いますが、毎回調べるのもだるいですし備忘としてもまとめて残しておきます。

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [ESXi 6.5 HostClientのブラウザ要件](#Chapter1)
1. [ESXi 6.7 HostClientのブラウザ要件](#Chapter2)
1. [ESXi 7.0 HostClientのブラウザ要件](#Chapter3)
1. [ESXi 8.0 HostClientのブラウザ要件](#Chapter4)
1. [まとめ](#Chapter5)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# ESXi 6.5 HostClientのブラウザ要件
|サポート対象ブラウザ  |Mac OS  |Windows 32 ビットおよび 64 ビット  |Linux |
|---|---|---|---|
|Google Chrome  |75 以降  |75 以降  |75 以降  |
|Mozilla Firefox  |60 以降  |60 以降  |60 以降  |
|Microsoft Edge  |該当なし  |79 以降  |該当なし  |
|Safari  |9.0+  |該当なし  |該当なし  |

<a id="#Chapter2"></a>
# ESXi 6.7 HostClientのブラウザ要件
|サポート対象ブラウザ  |Mac OS  |Windows 32 ビットおよび 64 ビット  |Linux |
|---|---|---|---|
|Google Chrome  |75 以降  |75 以降  |75 以降  |
|Mozilla Firefox  |60 以降  |60 以降  |60 以降  |
|Microsoft Edge  |該当なし  |79 以降  |該当なし  |
|Safari  |9.0+  |該当なし  |該当なし  |

<a id="#Chapter3"></a>
# ESXi 7.0 HostClientのブラウザ要件
|サポート対象ブラウザ  |Mac OS  |Windows 32 ビットおよび 64 ビット  |Linux |
|---|---|---|---|
|Google Chrome  |89+  |89+ |75 以降  |
|Mozilla Firefox  |80+  |80+  |60 以降  |
|Microsoft Edge  |90+  |90+  |該当なし |
|Safari  |9.0+  |該当なし  |該当なし  |

<a id="#Chapter4"></a>
# ESXi 8.0 HostClientのブラウザ要件
|サポート対象ブラウザ  |Mac OS  |Windows 32 ビットおよび 64 ビット  |Linux |
|---|---|---|---|
|Google Chrome  |89+  |89+ |75 以降  |
|Mozilla Firefox  |80+  |80+  |60 以降  |
|Microsoft Edge  |90+  |90+  |該当なし |
|Safari  |9.0+  |該当なし  |該当なし  |

<a id="#Chapter4"></a>
# まとめ
* Linux では、6.5/6.7/7.0/8.0全て同要件である。
* Safariブラウザを使う場合は、Mac OS一択で且つバージョンは9.0+で変わらず共通して6.5/6.7/7.0/8.0で同じである。
* ESXi6.5/6.7のブラウザ要件は共通であり、多少古めから使われているので動いてしまう可能性が高い。
* <font color="blue">ESXi7.0/8.0のブラウザ要件は共通であるが、6.7から7.0にメジャーバージョンアップされる際にブラウザ要件が跳ね上がっているため、</font>
<font color="red">その影響で油断しているとブラウザ要件起因で問題が発生する可能性があります。(:3[▓▓]</font>

別途、vSphere Clientもまとめますかねぇ...(¦3[▓▓]

<a id="#reference"></a>
# 参考文献
- [ESXi 6.5 HostClientのブラウザ要件 - VMware docs ](https://docs.vmware.com/jp/VMware-vSphere/6.5/com.vmware.vsphere.upgrade.doc/GUID-83042A09-281D-4B74-9176-8E882AD23432.html)
- [ESXi 6.7 HostClientのブラウザ要件 - VMware docs ](https://docs.vmware.com/jp/VMware-vSphere/6.7/com.vmware.vsphere.html.hostclient.doc/GUID-83042A09-281D-4B74-9176-8E882AD23432.html)
- [ESXi 7.0 HostClientのブラウザ要件 - VMware docs ](https://docs.vmware.com/jp/VMware-vSphere/7.0/com.vmware.vsphere.hostclient.doc/GUID-83042A09-281D-4B74-9176-8E882AD23432.html)
- [ESXi 8.0 HostClientのブラウザ要件 - VMware docs PDF Page.11  ](https://docs.vmware.com/jp/VMware-vSphere/8.0/vsphere-esxi-host-client-25-guide.pdf)
Seleniumレシピまとめ【スクレイピング】【Selenium4】

# はじめに
スクレイピングでSeleniumを使用した際に記述したコードのレシピをまとめました。Selenium4に対応しています。不備があるかもしれませんが、順次追記していきます。

# パッケージのインストール
chromedriver_binaryはChromeの「設定」→「Chromeについて」でバージョンが確認できます。
```
pip install selenium
pip install chromedriver_binary==xx.x.xxxx.xx
```

# import 
```
from selenium import webdriver
import chromedriver_binary
```
# URLを開く
```
driver=webdriver.Chrome()
driver.get('URL')
```

# 要素の検索
以下のコードをimportに足す必要がある。
```
from selenium.webdriver.common.by import By
```
### クラス属性で検索
sampleというクラス名の場合以下のようになる。
```
element = driver.find_elements(By.CLASS_NAME,"sample")
```
ID属性の場合は、`By.ID`、タグ名の場合は、`By.TAG_NAME`、name属性の場合は`By.NAME`に変更する。

### どうしても取得できない時はXPathを使う
#### XPathの取得手順
1. サイトの適当な場所で右クリック
1. 検証を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461625/e17a6615-f6d6-577e-1093-f004452fd049.png)
1. 左上のボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461625/5e2069ee-9c76-3c41-b8d6-47d002a29a2c.png)
1. 目的の要素部分にカーソルを合わせてクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461625/a10396dd-9a54-47ab-eead-5d35ad4d0dbe.png)
1. 水色で塗られた部分を右クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461625/6224aa42-d49a-aa46-1776-aa74c4b042c8.png)
1. Copy→Copy XPathまたはCopy full XPathをクリックし、パスをコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461625/3443908c-30be-0c83-49d3-2604d040a499.png)
これでパスのコピーは完了したので、あとはこれを貼り付けるだけです。
```
element =　driver.find_element(By.XPATH,"パス")
```

### ある要素の中に限定して要素を取得
```
element1=driver.find_element(By.XPATH,"パス")
element2=element1.find_element(By.CLASS_NAME,"sample")
```
### 条件を満たすすべての要素をリストで取得
find_elementをfind_elementsというように複数形に変更すればよい。単数形の場合は、条件を満たす一番最初の要素だけ取得される。リスト型なので、一つ一つの要素を取得する場合には`for e in elements:` といったようにfor文で記述します。

```
elements=driver.find_elements(By.CLASS_NAME,"sample")
```


# 要素の操作
### テキストボックスに入力
```
element.send_keys('入力したい文字')
```
### クリックする
```
element.click()
```
### 要素内のテキストを取得
```
element.text
```
上記方法で空の文字列が返ってくる場合は以下の方法で取得。
```
element.get_attribute("textContent")
```
参考URL：https://qiita.com/riikunn_ryo/items/68c7621baaa54cf27230

# その他使えるレシピ
### ヘッドレスモード
ヘッドレスモードはざっくりいうと、ウェブページを表示しないモードです。
まず、importの部分で以下を追記します。
```
from selenium.webdriver.chrome.options import Options
```
そして、`webdriver.Chrome` 付近で以下のように追記します。
```
options = Options()
options.headless = True
driver = webdriver.Chrome(options=options)
```

### 別のウィンドウに移動する
ボタンをクリックした際に、別のウィンドウへ切り替えたい場合は以下のように記述します。
```
driver.switch_to.window(driver.window_handles[1])
```
1の数字の部分を変えることで、どのウィンドウかを指定することができます。

### フレームに移動する
以下の例のように記述すると、フレームに移動することができます。  
例)
```
driver.switch_to.frame(driver.find_element(By.NAME,"sample"))
```
### エラー処理
for文を使って、スクレイピングを実行している途中でエラーが起きることがよくあるので、以下のように記述するといいと思います。
```
try:
    エラーが起きそうな処理
except:
    continue
```
【24日目】Mackerelの通知先にDiscordが無いがどうすればいいのか

# はじめに
こんにちは、なりかくんです。
今回は、Mackerelの通知設定画面でDiscordという選択肢がありませんがどうしたら通知させることが出来るのかを紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/2b22d40c-060a-3739-f46c-5d9c6eabadbb.png)


# Slackの設定を使う
なんとDiscordでは、Slackとの互換性を持っているためSlackの設定でDiscordに通知することが出来ます。
しかし、少しDiscordのWebHookのURLをいじる必要があります。

通常は以下のような形式のURLになります。
```
https://discord.com/api/webhooks/<Id>/<Token>
```
このURLの最後に`/slack`と付け足してやります。
```
https://discord.com/api/webhooks/<Id>/<Token>/slack
```

なおこの仕様は以下の公式ドキュメントに書かれているものです。
https://discord.com/developers/docs/resources/webhook#execute-slackcompatible-webhook

つまりこのように設定してあげることが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/84c11d10-8097-37bd-805b-08b1709c84af.png)

テストしてみると、しっかりと送られていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549951/b5de29dc-43a1-0e52-b888-26b57226580f.png)

以上です、最後までお読みいただきありがとうございました。
AWS Copilot なるものを触ってみた！



[UdonTech Advent Calendar 2022](https://qiita.com/advent-calendar/2022/udontech)の23日目です。

フライング・メリークリスマス:santa_tone2::santa_tone2::santa_tone2:　明日は、いよいよクリスマスイブですね。

ところでみなさん、ご存知でしたか？　

クリスマスイブは、クリスマス（Christmas：「キリストのミサ」）　＋　イブ（evening：「夜」）という意味なので、24日の夜から25日の日没という意味ですよ。なので25日の夜は、正確にはクリスマスではないんですね。



## 自己紹介
本当は、AWSの資格の話を書きたかったんですが、忙しくて資格の勉強時間がなかなか取れず(言い訳)・・・。今の職場で初めて触ることになったAWS Copilotについての記事を書こうと思います。

## AWS Copilotとは何か
ということで、本題のAWS Copilotの話に移ります。

AWS Copilotは、公式サイトによると以下のような説明がされています。

https://aws.amazon.com/jp/blogs/news/introducing-aws-copilot/

> AWS Copilot は、低レイヤなインフラの手動管理から脱却し、自身のアプリケーションとそのライフサイクルにフ> ォーカスしたい ECS ユーザのためにデザインされました。....
>つまり、Copilot を使うことで、アイデアから実装までをより早く、プロダクションレディな形で構築されたインフラに自信をもってデプロイできるようになるわけです。

だそうです！！！！！！

つまり、どういうことかというと「**Amazon ECSのデプロイツール**」ということなんですね。

## AWS Copilotのインストール
```
# Homebrewでインストール
$ brew install aws/tap/copilot-cli

# 直接ダウンロードでインストール
$ curl -Lo /usr/local/bin/copilot https://github.com/aws/copilot-cli/releases/download/v0.1.0/copilot-darwin-v0.1.0 && chmod +x /usr/local/bin/copilot && copilot --help

# インストール確認
$ copilot --version
copilot version: v1.21.0
```

上記コマンドで、最新のcopilotがインストールされます。おそらくv.1.2系がインストールされると思います。

## AWS Copilotを動かしてみる
あとはこちらのページの内容をまるパクリさせていただきました。

https://qiita.com/takeh/items/23d7b3300dc008bb9dbc

こんな感じのDockerfileを用意してあげます。
```
FROM nginx
EXPOSE 80
COPY index.html /usr/share/nginx/html
```

copilotを使ってデプロイを開始します。

```
# このコマンドが出発点となる
$ copilot init

  What would you like to name your application? [? for help]    # アプリケーション名を指定

  Which service type best represents your service's architecture? [Use arrows to move, type to filter, ? for more help]
  > Load Balanced Web Service    # インターネットフェイシングなパブリックサービス
    Backend Service              # プライベートなバックエンドサービス

  What do you want to name this Load Balanced Web Service? [? for help]    # サービス名を指定

  Which Dockerfile would you like to use for nginx-test? [Use arrows to move, type to filter, ? for more help]
  # 自動検出されるDockerfileを選択します。copilot init実行配下のフォルダの中のDockerfileも見つけてくれます。

  #用意する環境にデプロイをするかどうか聞かれます。
  Would you like to deploy a test environment? [? for help] (y/N)

```

このコマンドで自動的にデプロイまでされちゃいます。

以下のコマンドでcopilotにおける環境一覧が、

```
copilot env show
```

https://aws.github.io/copilot-cli/ja/docs/commands/env-show/

以下のコマンドでcopilotにおけるサービス一覧が、

```
copilot svc show
```

https://aws.github.io/copilot-cli/ja/docs/commands/svc-show/

表示されます。

## おまけ
v.1.1系からv.1.2系になるときに大幅なアップデートがあり、私がいる現場でも更新する際にめっちゃ苦労しました・・・。　
その苦労話もどこかで記事にしようと思います。
VSCodeにApex テストのコードカバレッジのハイライトを付ける

Apex テストクラスを実行した後に通ったコードと通らないを見分けするためにテスト後に本体のクラスファイルにハイライト表示させることができます。それはsalesforce本体のコンソールだけでなくVSCodeでも同じことができます。もし、テスト実行した後に不表示の場合は設定がたりないかもしれません。この記事ではその設定方法を詳しく紹介します。
## 1.settingを開く
Ctrl+,でSettingパネルを開くことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/539d623e-26b1-8805-e947-3cccf9a21844.png)
## 2.設定変更
salesforcedx-vscode-coreと検索して範囲を絞り込み、salesforcedx-vscode-core.retrieve-test-code-coverageにチェックを付ける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/587a2e92-fc0f-6462-1e68-1e4a847d1e78.png)
## 3.テストを行い変更を確認
settingを変更した後にテストを実行して確認しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705822/3e410333-c4c0-5251-0e3f-1acb42b35dbf.png)
Alibaba Cloud にサービスを移行することになったとさ

# はじめに
「なんとかなれ～」がマイブームな、とあるエンジニアです

AlibabaCloudに稼働中のとあるサービスを移行する機会があったので共有させていただきます。
このタイミングで AlibabaCloud に移行することになった理由や移行する際に苦労したことなどについて書きます。

## 移行する理由
簡潔に言うと、社内事情的なもの(<font color="lightgray">~~上からの圧~~</font>)です。
半分冗談ですが、メインの目的はコスト削減です。

Aucfan では AWS をメインに使っていますが、移行対象のサービスは何故か Az○re で稼働しています。私が入る以前に構築されていました。
(あなたの会社にもそんなことありませんか？)

Azureで稼働中のサービスにかかっているコストが高く、AWS に移行できないか以前検討されたようですが、移行しても安くならないということで断念したそうです
時を経て、Alibaba Cloud さんとのご縁があり、**コストが削減できそう** ということで移行することになりました

まじか...。本当にやるんだ...。そんな気持ちでした。

### どれぐらい下がるのか？

結論から言うと下がりましたが、具体的な金額は **大人の事情** で記載出来ません。話せません。すみません。
(それっぽい感じの韻？を踏んでみた)

軽い冗談はさておき、そもそも何にコストがかかっているのか整理すると以下の3つです。
- SQL Database
- General Block Blob
- VM

この中で特に掛かっているのが SQL Database です。
AWSに移行するのを断念したのは、おそらくライセンス料絡みだったと思います。

MySQL や PostgreSQL といったオープンソースに比べると割高になってしまう SQL Database さんですが、
昨年、AWSがオープンソースとして提供した **Babelfish for PostgreSQL** を使うことで、技術的にコストを下げることが可能になりました。
技術面でコストを下げれるのであればエンジニアにとっては嬉しいことですし、パフォーマンスに問題がなければ、SQL Database から Babelfish for PostgreSQL に移行を検討すべきだと思います。

今回は Babelfish for PostgreSQL を使ってコストを下げました 的な話をしたかったんですが、やっていません。
検証する時間が取れませんでした...。

ちなみに宣伝とかではないですが、Alibaba Cloud でも利用が可能です。
普段の業務は、RDSを構築するだけなので、いづれは触ってみたいものです。

## Alibaba Cloudってどうなの？
コスト削減が出来るとはいえ、色々と不安がありますよね。
特にセキュリティ関連ですかね...。

でも実績を見れば、少しその不安が減るかもしれません。
### 実績
公式: https://www.alibaba.co.jp/service/alibabacloud/

- 国際オリンピック委員会(IOC)とのパートナーシップ契約を締結している(2018年から2028年)
    - 2020年の東京オリンピックでも使われていたんですね...(知らなかった)
- W11(11月11日,独身の日) を支えている
- まだ多くはないですが、日本の大手企業も使用している

何をもって安心できるかは要件などで変わりますが、不安な部分があるのであれば Alibaba Cloud さんへ問い合わせるのが一番です。

## 使用感
忖度無しで書きます。

- Webコンソールは AWS と似た感じで、使いづらいことはない（慣れの問題）
- 日本語も対応しているが、翻訳が若干おかしい部分があるため英語を使ったほうが無難
- ユーザーの技術記事が少なく、公式ドキュメントを見るか自分で対処しないといけない

Alibaba Cloud の日本支部？の方のお話では、AWSライクに作られているそうです。
サービス名やパラメータ名が違えど、AWSを触っていれば雰囲気で分かりました。

当然ですが、サービスの機能が全く同じではないので注意が必要です。
その中でも Resource Orchestration Service (ROS) というサービスに関して共有したいと思います。

### Resource Orchestration Service (ROS)
ROS は AWS でいう CloudFormation と同じようなサービスです
Aucfan では、多くのリソースを CloudFormation で管理しているため、Alibaba Cloud でも同様に出来たらいいと思っていたんですが、簡単にはいきませんでした

例えば、
- Auto Scaling と Server Group の紐づけが出来ない
Server Group は AWS でいう Target Group のことですが、ROSでは紐づけが出来ない...。それなら手動でやるよね...。
- LaunchTemplateは作ることしか出来ない
ROSからは作ることしか出来ません。
バージョン管理の機能はついていますが、更新してバージョンを上げることもあるので、差分出ますよね...。
リソース管理の意味が...。

といったことが検証中に分かったので、Terraform を使って運用することにしました。
Terraform を使ったことがなかったので学習から行ったので時間がかかりました...。
個人的には、業務中に学習できたのでラッキーでした！

その他にも、CloudFormation のテンプレートを ROS 用のテンプレートに書き換えてくれるツールも存在していますが、短縮形(`!Ref`)は変換してくれないので、なんだかなーって感じでした。

## さいごに
そんなに濃い話は出来ませんでしたが、Alibaba Cloud に移行する際に感じたことなどを書きました。

実際に検証していく中で AWS では出来たから Alibaba Cloude でも出来るだろうという感覚でいたので痛い目に合いました...。
まあ Terraform で何とかなったので良かったです。

その他のサービスに関してはご自身でご確認していただければと思います。
読んでいただいた方のちょっとしたネタになればと思います。
コードで作ろう良いキック

# 導入 

私事ですが、最近作曲にハマっていて電子音楽とか作っています。いわゆるEDMみたいな、そういうやつですね。電子音楽をやっている人は大抵サンプルパックを漁ってるんですが、なぜかっていうと電子音楽はサンプルを使いまくって成り立ってるからです。スネアやキックはほとんどサンプルが使われていますね。ところで、サンプルパックを漁る以外にもシンセサイザーでこれらの音を作ることが出来て、例えばノイズの音量を急激に下げるとスネアの音みたいになったり、正弦波の音程を急激に下げるとキックの音みたいになります。正弦波の音程を下げるくらいならプログラミング出来そうですね！という訳でコードからキックを生成したいと思います。

# キックとは

ドラムの一番大きいやつをイメージして頂けると良いかなと思います。下でドンドンいってるやつですね。

https://sleepfreaks-dtm.com/dtm_word/1-7ki/kick/

下の画像の様に、音程を急激に下げるとキックの音が人工的に合成できます。

![スクリーンショット 2022-12-21 112931.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190721/4cd4d860-0024-521e-169a-cfeb58df5025.png)

# 技術選定

Pythonで音声を扱えることは知っていたのですが、動的型の言語は好きじゃないのでC#を検討しました。
調べてみると、どうやらC#はwavファイルのサポートが薄く、ヘッダーから実装する必要がありそうだったのでkotlinを選択しました。
kotlin(Java)はwavファイルの出力をサポートしているみたいなので安心ですね。

# 実装

下のサイトを参考に、とりあえず矩形波を出力してみます。
https://mocha-java.com/create-square-wave-1/
https://www.youfit.co.jp/archives/1418

出来ました。

![スクリーンショット 2022-12-21 113915.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190721/441cf23c-3887-9c9c-b911-bad866952471.png)

バイナリエディタでみると以下のようになっています。かわいいですね。
FF7Fの連続が波形の上半分にあたり、0180の連続が下半分にあたります。wavファイルは符号付きintでデータを表しているので最大値はFFFFではないんですね。(一敗)

![スクリーンショット 2022-12-21 114100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190721/679d24e0-16cf-2e3a-3b92-411e8a480c2f.png)

改造して正弦波を出力します。

![スクリーンショット 2022-12-21 114603.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190721/3329c8c3-11cf-aeb9-e080-1d5c673f958d.png)

周波数を段階的に落としていきます。
![スクリーンショット 2022-12-21 114621.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190721/de24fee2-2d47-ae5d-d2c7-ae15c844a821.png)

周波数の繋ぎ目が尖ってしまってるので、周波数を変える時に前の位相(Θ)からスタートします。

![スクリーンショット 2022-12-21 114636.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190721/0c01a28a-edb8-4bd8-cf2f-9ad13ba1ec5e.png)

音量も変化させます。
![スクリーンショット 2022-12-21 114727.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190721/2faac3a2-105c-a94b-16c1-2915305abf4b.png)

やや繋ぎ目が尖っていますが、完成です。

# 完成！

https://www.dropbox.com/s/74w6o7hdqi6jrck/square_440_1671160069056.wav?dl=0

繋ぎ目のノイズが気になりますが、気にしたら負けです。

# コード

https://github.com/negitorogithub/Kicklin
createの条件分岐ができない

## まえがき
新規ユーザーの登録ページにて情報を登録できたら`redirect_to`でトップページへ。
登録できなかった場合は`render`で新規登録ページに遷移するという分岐を設定したかったのですが・・・
登録できても、できなくてもトップページに遷移してしまうという症状に悩んでいました。
解決策が分かったので、記録します。

__参照先：__
[Taroken　Fintech様：【Rails】createメソッドとnew+saveメソッドの使い分けを解説](https://tarokenfintech.com/%E3%80%90rails%E3%80%91create%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%A8newsave%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AE%E4%BD%BF%E3%81%84%E5%88%86%E3%81%91%E3%82%92%E8%A7%A3%E8%AA%AC/)　
お陰様で解決できました！ありがとうございます！:bow_tone3:

以下がその時の記述です。
```ruby
def create
    if Prototype.create(prototype_params)
      redirect_to root_path
    else
      render :new
    end
  end

  private

  def prototype_params
    params.require(:prototype).permit(:title, :catch_copy, :concept, :image).merge(user_id: current_user.id)
  end
end

```

## 結論
### 条件分岐ではcreateメソッドは使わずに、new + saveメソッドを使うこと！

   __なぜなら__

__・ createメソッドは保存できる、できないに関わらず戻り値にインスタンスを返すのでtrue扱いになってしまう。__
__・ saveメソッドは実行結果にtrue、falseを返してくれる。__

このように直したらキチンと分岐できました！
```ruby
def create
    @prototype = Prototype.new(prototype_params)
    if @prototype.save
      redirect_to root_path
    else
      render :new
    end
  end

  private

  def prototype_params
    params.require(:prototype).permit(:title, :catch_copy, :concept, :image).merge(user_id: current_user.id)
  end
end
```
## あとがき
createメソッドあれば、saveメソッドは使わないと思っていました・・・
大学のWi-Fi接続の入力の手間を省きたい

## できるようになったこと
大学のWi-Fi接続時にポップアップが出てきます．
そこにユーザIDとパスワードを毎回入力しなくてよくなりました．

HTMLファイルを開き，ボタンを押すだけになりました．

## 方法
ポップアップではなく，ブラウザ上に認証画面が出てくることがありました．
そのときにURLをメモしました．

chromeの場合，右上の方の三つの点からその他のツールのデベロッパーツールを開きます．

HTMLファイルを作り，その内容を写経します．
ユーザIDなどの入力欄を
```html
<input name="name" type="text" value size="30" maxlength="63">
```
から
```html
<input name="name" type="text" value="***">
```
のようにします．
value sizeやmaxlengthを残しているとうまくいきませんでした(片方だけ残すのは試していません)．

また，
```html
<form method="POST" action="/***">
```
のように送信先が載っているところがあります．
ここで，
```html
<form method="POST" action="<メモしたURL>/***">
```
のようにします．

## 今後
大学に限らず，カフェとかでフリーWi-Fiに接続しようとすると，ポップアップが出てくることがあります．
それらに自動で接続できるようにしたいですね．

Wi-Fiにつながっていないときに自分で作ったファイルからログインできませんでした．
ポップアップからはなぜログインできるのでしょうか．
Comptia Cloud Essentails＋に合格した話

本エントリーはAdvent Calendar 2022「[NKC-UG Advent Calendar 2022](https://qiita.com/advent-calendar/2022/nkc-ug)」の1日目のエントリーです！

# はじめに

こんにちは。[ノル](https://twitter.com/noll6451)です

今回は「NKC-UG」主催のアドベントカレンダー「[NKC-UG Advent Calendar 2022](https://qiita.com/advent-calendar/2022/nkc-ug)」の1日目にエントリーしました
## きっかけ
Comptia Cloud Essentails+ という資格を勉強した際、日本語の記事などが少なく勉強に苦労したので、書きました。
~~NKC-UGの代表だから仕方なくではない~~

#この記事の対象者

- 世界で通用するクラウドの資格を取りたい
- Comptia系の資格を取りたい

## この資格の説明
[公式](https://www.comptia.jp/certif/additional_professional/comptia_cloud_essentials/)では
>CompTIA Cloud Essentials+は、テクニカルな認定資格ではなく、ビジネスでクラウド導入の意思決定をする際に 検討するべき要件を理解し、適切にクラウド導入を推進するビジネス部門とIT部門の人材のスキルを証明する認定資格です。

となっております。

簡単に言うと、クラウド使う人なら身に着けるべき知識・スキルがあることを証明してくれることですね。

お察しの通り、難易度は、クラウドの資格の中でも基礎の部分にあたります。
結構勉強したら一発合格できると思います。

ちなみにComptia系の資格はあまり日本で聞きなれないですが、海外では有名です。
米国国防総省では、この資格ではありませんが、習得が必須になっていますよ。
https://www.comptia.jp/information/2019/05/comptia-dod.html

## 勉強方法
自分は運よくこの資格を取るためのトレーニング講座が当たり、一日だけですが、みっちり教えてくれる講座に参加しました。
ちなみに使った教材は[こちら](https://jp-store.comptia.org/p/CLE-002-JPDB-21-C)です。

ですが、正直に言うと、わざわざこれを買う必要がないと思います。
~~Comptiaさんごめんなさい~~

自分のおすすめとして,Azureの基礎の資格であるAZ-900の勉強をするとこちらの勉強になります。
https://learn.microsoft.com/ja-jp/certifications/exams/az-900
上記のサイトの下にスクロールすると、勉強できるようにラーニングパスがあるので
それに沿って勉強すれば十分です。(もちろん無料です)

ただ問題集もやったほうが合格率高まります。(TACがいいと聞いたことがあります
自分は使ったことないので、分かりません)

ただここの注意点があって、Comptiaの資格はどのクラウドにも使えるような基礎知識を解いてくるので、Azure特有のサービスを覚える必要はありません。
他のクラウドの特長も覚えるといいです(ただほとんどAZ-900で出てくるサービスは他のクラウドでもあるので、どんなサービスだったかは覚えるといいです。)


# 試験を受けるときの注意点

- 日本語がおかしい場合がある(英語に直す、察する)
- 採点されない問題が出てくる
- 出題範囲にない問題が出てくる(たぶん採点されてない？)
- 人によって問題数が違う(最大75問)
- 意外と時間がないので、サクサク進める(60分しかない。後から回答し直せる)
- 8割合格っぽいので、分からなくてもとりあえず何かしら選ぶ(900点中750点)

ぜひこれをきっかけにComptiaの資格を取りましょう。(お仲間になってください)
またComptiaの資格は色んなのがあるので、見てみるといいかもですね。
Azure Automationの実行アカウント廃止に伴う対応について

Azure Automationを利用することで仮想マシンの起動停止の自動化などで運用されている場合があると思います。

[Azure Automation の実行アカウントを管理する]
https://learn.microsoft.com/ja-jp/azure/automation/manage-run-as-account

しかしながら2023年9月30日をもって実行アカウントは廃止されるとマイクロソフトから広報がありました。

[Azure Automation の実行アカウントは、2023 年 9 月 30 日に廃止されます。]
https://learn.microsoft.com/ja-jp/azure/automation/migrate-run-as-accounts-managed-identity?tabs=run-as-account

実行アカウントでは、AutomationのRunbookやその他の自動化機能使用して、ARMもしくはAzureクラシックモデルのリソースを管理する為の認証を提供しているのですが廃止されてしまう為、マネージドIDに移行する必要があります。
また、実行アカウントの認証ですが、証明書の期限が1年となり証明書を更新する必要があります。しかしながら、マネージドIDへ移行することで証明書の更新を行う必要がなくなりますので早めに移行することをお勧めいたします。

■前提条件
Runbook内のAzureRMモジュールやAzモジュールなどで実行アカウントを利用するコマンドが存在する場合のみ、移行作業が必須です。

・確認方法
Runbookのスクリプトで利用されているコマンドを確認します。

[1.Runbook に実行アカウントを利用しているコマンドが存在するかを確認]
https://jpazmon-integ.github.io/blog/automation/MigrateRunAsAccountsToManagedIdentity/#1-Runbook-%E3%81%AB%E5%AE%9F%E8%A1%8C%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%8C%E5%AD%98%E5%9C%A8%E3%81%99%E3%82%8B%E3%81%8B%E3%82%92%E7%A2%BA%E8%AA%8D

Azモジュールコマンドを利用している場合、下記のような記述となります。

例)
————————————–
$connectionName = “AzureRunAsConnection”
$servicePrincipalConnection = Get-AutomationConnection -Name $connectionName
Add-AzureRmAccount -ServicePrincipal -TenantId $servicePrincipalConnection.TenantId -ApplicationId $servicePrincipalConnection.ApplicationId -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
————————————–

Runbookのスクリプトで実行アカウントを利用しているコマンドを確認したら下記を参考にしてマネージドへ移行を行って下さい。

■マネージドIDへの移行方法

①該当のAutomationアカウントにてマネージドIDを作成します。
マネージドIDにはシステム割り当てとユーザー割り当ての2種類あります。
システム割り当てをすると該当のリソースを削除すると一緒に削除されます。ユーザー割り当てにすると個別のAzureリソースとなりますのでマネージドID専用のアカウントがAzureADに作成されます。
利用用途などを鑑みてどちらを利用するかを決定します。

[マネージド ID の種類]
https://learn.microsoft.com/ja-jp/azure/active-directory/managed-identities-azure-resources/overview#managed-identity-types

「Automationアカウント 」→ 「アカウント設定[ID]」にて、作成したい種類のマネージドIDの状態を[オン]にして保存することで作成されます。

![マネージドIDへの移行方法①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920715/fba231ae-f8bf-1e17-3766-74ce7921bd74.png)

②”①”で作成したマネージドIDに対し、必要最低限のロールを割り当てます。
マネージドIDの状態の[オン/オフ]設定項目の下にあるアクセス許可[Azureロールの割り当て]をクリックするとAzureロールの割り当て設定画面が表示されます。
[＋ロールの割り当ての追加(プレビュー)より、割り当てが可能となります。

![マネージドIDへの移行方法②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920715/48dbd7c4-19da-8148-fe19-7abe78f8146f.png)

③Runbookスクリプへトへマネージド ID による認証コマンド（Connect-AzAccount -Identity）に書き換えます。
実際に運用されているRunbookのスクリプトのコピーを作成し、コピーしたRunbookにて動作テストをしてください。
※運用中のRunbookへ認証コマンドを書き換えて更新すすることをマイクロソフトで推奨をしています。

サンプルスクリプトは下記をご参照下さい。

[サンプルスクリプト]
https://learn.microsoft.com/ja-jp/azure/automation/migrate-run-as-accounts-managed-identity?tabs=sa-managed-identity#sample-scripts

実際の運用ではAzure Automationを作成して自動化してしまうとあまり気にすることはないと思います。しかしながら、このように廃止される機能などがあり運用に影響を及ぼしかねない場合もありますのでご注意ください。
AWS Lambda を ECR のコンテナイメージで動かすとき、:latest を指定して良いのか悪いのか

以下の状況のときに、Lambda 関数はいい感じに更新できるのかどうか不安になったので試してみたログ。

- CodeBuild で Lambda 用コンテナイメージをビルドして ECR に push する
    - このとき ECR のコンテナイメージにはタグを付けず、 `latest` を更新し続ける
- ECR のコンテナイメージを Lambda で動かす

## 動かすサンプルアプリ
``` Dockerfile:Dockerfile
FROM public.ecr.aws/lambda/python:3.9

COPY main.py ${LAMBDA_TASK_ROOT}

CMD ["main.handler"]
```

``` main.py
def handler(event, context):
    return "foo"
```

実行したら `foo` と返ってくるだけの Lambda 関数

## 事前準備
- `lambda-test` という名前の Lambda 関数を作っておく
- `lambda-test` という名前の ECR リポジトリを作っておく

## とりあえず動かす
ECR にログイン

``` console
$ aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com
```

ビルドして ECR に push

``` console
$ docker build -t ${AWS_ACCOUNT_ID}.dkr.ecr.${$AWS_DEFAULT_REGION}.amazonaws.com/lambda-test .
$ docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${$AWS_DEFAULT_REGION}.amazonaws.com/lambda-test
```

実行

``` console
$ aws lambda invoke --function-name lambda-test /dev/stdout
foo
```

動いた

## 書き換えてみて動作検証
試しに main.handler の返り値を変更

``` main.py
def handler(event, context):
    return "bar"  # 書き換えた
```

再度 build & push してから再実行

``` console
$ aws lambda invoke --function-name lambda-test /dev/stdout
foo
```

変わらない  
→ もし Lambda ランタイムの内部で毎回 docker pull しているならもしかしたら変わるかもと思っていたが、そんなことはなさそう

update-function-code してから再実行

``` console
$ aws lambda update-function-code --function-name lambda-test --image ${AWS_ACCOUNT_ID}.dkr.ecr.${$AWS_DEFAULT_REGION}.amazonaws.com/lambda-test:latest
```

``` console
$ aws lambda invoke --function-name lambda-test /dev/stdout
bar
```

変わった  
→ 同じタグ (`latest`) であっても update-function-code すれば最新のコンテナイメージに更新されるらしい
Azure Administrator(AZ-104)：Azure管理者向けの前提条件「ARMテンプレートの出力」

Microsoft Learnを用いたMicrosoft Azure Administrator(AZ-104)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始め、AZ-900取得後の資格としてAZ-104取得を目指している方の参考になれば幸いです。
※AZ-900の内容は本投稿では省略しております。再度復習したい方は下記をご参照ください。
[Azure Fundamentals(AZ-900)：試験合格に向けた学習内容のまとめ](https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8)

## 今回の学習内容
**◆「ARMテンプレートの出力」**
◇対応するMicrosoft Learn ラーニングパス
[AZ-104:Azure 管理者向けの前提条件](https://learn.microsoft.com/ja-jp/training/paths/az-104-administrator-prerequisites/)
◇対応するモジュール
[パラメーターと出力を使用して Azure Resource Manager テンプレートの柔軟性を高める](https://learn.microsoft.com/ja-jp/training/modules/create-azure-resource-manager-template-vs-code/4-add-flexibility-arm-template?tabs=azure-powershell)

※前回の投稿は下記から確認できます。
[Azure Administrator(AZ-104)：Azure管理者向けの前提条件「ARMテンプレートのパラメーターコード例」](https://qiita.com/fsd-jume/items/f6591a117e9d84b47b87)

## ARMテンプレートの出力
### ARMテンプレートの出力
**デプロイが成功した後に返される値を指定可能**
⇒デプロイ時に指定したパラメーターを他でコピーして使うために、デプロイ後に出力させることが可能
例)ストレージアカウントを作成し、ストレージアカウントのリソース名を出力

**◆出力セクションを構成する要素**
```:JSON
"outputs": {
  "<output-name>": {
    "condition": "<boolean-value-whether-to-output-value>",
    "type": "<type-of-output-value>",
    "value": "<output-value-expression>",
    "copy": {
      "count": <number-of-iterations>,
      "input": <values-for-the-variable>
    }
  }
}
```
**・output-name**
コード内で使用される出力の管理名
**・condition**
この出力値が返されるかどうかを示すブール値(省略可能)
　-true：出力する(既定値)
　-false：出力しない
**・type**
出力値のデータ型を指定(パラメーターと同じ)
**・value**
出力値(省略可能)
**・copy**
出力に複数の値を返すために使用(省略可能)
　-count：出力値で必要な反復回数を指定
　-input：繰り返すプロパティを指定

### ARMテンプレートにおける出力の使用例
・ストレージアカウント作成時にストレージアカウントの名前を出力するテンプレート
(出力に関わる部分以外は省略)
```json:test.json(出力)
 "outputs": {
        "output1": {
            "type": "string",
            "value": "[parameters('storageName')]"
        }
    }
}
```
```powershell:PowerShell
New-AzResourceGroupDeployment `
 -Name testdeployment1 `
 -TemplateFile "test.json" `
 -storageName "outputstoragetest"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/4613b2ff-f7ae-6819-9d25-5f3840e38e37.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/69e9e69d-8bdd-cade-13e2-9d88d6a04b93.png)
**※コードの意味**
**・output1**
コード内で使用される出力の管理名
**・type**
出力のデータ型を指定
**・value**
出力したい値を指定
⇒今回の場合はリソース用にパラメーターで指定したストレージアカウントのリソース名を指定

## 次の学習内容
**◆Azure ADの利点と機能**

https://qiita.com/fsd-jume/items/10ccc889bd1696c0a05e

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/6eda24728c9c03c36bc3
2022年に世界的に流行ったゲームのクソアプリ版【Noodle】をつくったよ

クソアプリ [Advent Calendar 2022](https://qiita.com/advent-calendar/2022/kuso-app) カレンダー3 の22日目の記事です。
## 二番煎じ

2022年に流行ったwordle
英単語が苦手な私は流行に乗り遅れたので悔しくてつくりました。

ラーメン二郎ならきっとできるはず
（Noodleといっていますが、ラーメン二郎限定です。）

 **こちらから遊べます！**
[Noodle](https://noodle-three.vercel.app/)


チートシートはこちら
[ラーメン二郎まとめ 宅麺様](https://www.takumen.com/magazines/jiro-matome)



## 画像の利用について

今回[ラーメンデータベース](https://ramendb.supleks.jp/)様から画像を借りています。
許可いただきありがとうございます。

## 利用した技術

 **vite + react + emotion**

今回簡単なアプリなので、技術的なことはあまり書くことがありません...


## 勉強になったこと

入力後の色の移り変わりについて

 **animation-fill-mode**を使うことで
CSS アニメーションの実行の前後にどう対象にスタイルを適用するかを設定できます。
くるっとしてから、色が変わるようにしたかったのでjsでアニメーション終わるのを検知して...とやろうとしましたがanimation-fill-modeでやりたいことができたので助かりました。

まだまだ知らない便利なCSSプロパティありそうですね...


![noodle.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390321/0c855335-5a1b-56e9-bc33-a267488daf3d.gif)




## 妥協したこと

### 失敗時の処理
本家に倣って6回入力できるようにしていますが、二郎自体がそれほど多くないのでそもそも6回入力するパターンが少ないです。
なので、6回失敗したときの実装は省きました。

極端に単語数が少ない場合は、存在しない単語入力も可能にするのがゲームバランス的にいいのかなと思いました。


### 独自ドメイン
クソアプリで独自ドメインとるの大変だしいいかと思って妥協しています。

調べたところ、無料で独自ドメインを取得できるかもしれないサービスがありました。


[Dot TK](http://www.dot.tk/ja/index.html)
ニュージーランドの領土であるトケラウの国別コードトップレベルのドメインらしいです。

今回のような一時的に公開したいクソアプリにぴったりかなと思いました。

## 苦労したこと
正解データを集めるのが大変でした。平仮名を手入力したのですが、

新宿小滝橋通り店のおたき？こたき？とおり？どおり？
池袋東口店のくち？ぐち？

などどう読むか分からない店舗がいくつかあって毎回調べるのが大変でした。

## あとがき

かなしいことですが、Noodle制作中にラーメン二郎 茨城守谷店が閉店してしまいました。
解答データから省くときには涙がこぼれ落ちたものです。
茨城守谷店様、今までとてもおいしい二郎をありがとう、お疲れ様でした。
【Alpine.js】Collapse Pluginでヌルっと出てくるドロップダウンが作れる

# CollapseはAlpine.jsのプラグインです
https://alpinejs.dev/plugins/collapse


# Collapseでできること
<b><font color="red">ヌルっと出てくるドロップダウンが作れる</font></b>
※応用すればアコーディオンメニューも作れそう

# 導入方法
## CDN
HTMLファイルに張り付けるだけです。
<b><font color="red">ただし以下のようにAlpine.js本体のscriptの前に配置する必要があります。</font></b>

```html
<!-- Collapseプラグイン -->
<script defer src="https://unpkg.com/@alpinejs/collapse@3.x.x/dist/cdn.min.js"></script>
 
<!-- Alpine本体 -->
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>

```
## npm
まずnpmでインストール
```
npm install @alpinejs/collapse
```
その後、バンドルするjsファイルにこう書きます。
```js
import Alpine from 'alpinejs'
import collapse from '@alpinejs/collapse'
 
Alpine.plugin(collapse)
```
これで使えます。

# 使用例

https://alpinejs.dev/plugins/collapse#x-collapse

ニョイっとメニューが出てきます


# 使い方
x-showを付けた要素にx-collapseを付けるだけです。

```html
<p x-show="expanded" x-collapse>
    ...
</p>
```
オプションを付けることもできます
```
x-collapse.durantion.1000ms　→　1秒かけて要素を開く
x-collapse.min.50px　　　　　 →  閉じたときに50pxだけ要素を見せる
```
### x-collapse.durantion.1000msの例

https://alpinejs.dev/plugins/collapse#dot-duration

### x-collapse.min.50pxの例

https://alpinejs.dev/plugins/collapse#dot-min

# まとめ
これを応用すればアコーディオンメニューも作れると思います。
AWS CLIでFailed to connect to proxy URLでエンドポイントにアクセスできなかった話し

# はじめに
`aws lambda publish-layer-version`コマンドを実行すると、
> 「Failed to connect to proxy URL: "http://{PROXY-URL}:80"」

となり、プロキシは正しく設定されているが、なぜかコマンドが通らずに三日程原因が特定できませんでした。同じようなエラーで困っている方に向けて情報を共有したいと思います。
# 結論
タイムアウトによりエラーが発生していました。`--cli-connect-timeout 6000`オプションをつけることでタイムアウトエラーを回避できます。
```bash
aws lambda publish-layer-version --cli-connect-timeout 6000
```
デフォルトのタイムアウト時間は60秒で設定されているため、通信が良くない環境で重いファイルをアップロードする際には同じエラーが発生する可能性があります。
https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html
# 試したこと
### プロキシが正しく設定されていることを確認する
こちらのコマンドで現在のプロキシに設定されている環境変数を確認します。
```bash
printenv | grep proxy
```
環境変数が設定されていなければ、こちらのコマンドでプロキシを設定してください
```bash
export http_proxy=http://proxy-url:80
```
```bash
export https_proxy=http://proxy-url:80
```
### 設定ファイルと認証ファイルを確認する
`.aws`ディレクトリにある`config`と`credentials`ファイルを確認して、複数の設定がある場合には、環境変数として設定したい設定ファイルと認証ファイルが指定されている必要があります。設定ファイルは`cat .aws/config`で、認証ファイルは`cat .aws/credentials`で確認できます。
##### configの確認
```bash
cat .aws/config
[default]
region = ap-northeast-1
output = json

[profile sample1]
region = ap-northeast-1
output = json

[profile sample2]
region = ap-northeast-1
output = json
```
##### credentialsの確認
```bash
cat .aws/credentials
[sample1]
aws_access_key_id = sample1xxxxxxx
aws_secret_access_key = sample1xxxxxxxxxxxxxxxxxxxx

[sample2]
aws_access_key_id = sample2xxxxxxx
aws_secret_access_key = sample2xxxxxxxxxxxxxxxxxxxx
```
sample2をクレデンシャルとして環境変数に設定する場合は下記のコマンドを実行します。
```bash
export AWS_PROFILE=sample2
```
### リージョンを確認する
Lambdaはリージョンごとのサービスのため、環境変数もしくはオプションでリージョンを正しく指定する必要があります。
##### 環境変数で設定
```bash
export AWS_REGION=ap-northeast-1
```
##### オプションで設定
```bash
--region us-east-1
```

# 感想
プロキシエラーと表示されるため、プロキシの設定を何度も確認しましたが、一向にエラーが回避されず困り果てていました。偶然こちらの記事を見つけ、`--cli-connect-timeout 6000`を指定して実行したら上手くいきました。

https://github.com/aws/aws-cli/issues/3842

`aws lambda publish-layer-version`のようなアップロードサイズが大きい処理をCLIで実行すると、タイムアウトエラーとなる可能性があるため、参考になれば幸いです。
Pythonで簡単なAPIを作成してみた

# はじめに
PythonでAPIを作成するには、次のような手順を踏むことができます。

1.使用するWebフレームワークを選択する。Pythonでは、FlaskやDjangoなどの人気のあるWebフレームワークがあります。

2.Webフレームワークを使用してAPIエンドポイントを作成する。APIエンドポイントは、APIを呼び出すためのURLであり、HTTPリクエストを受け取り、必要に応じてデータを返すものです。

3.HTTPメソッド（GET、POST、PUT、DELETEなど）を使用して、APIエンドポイントを処理する関数を定義する。

4.APIを使用するためのクライアントを作成する。クライアントは、APIを呼び出すためのアプリケーションやスクリプトです。

5.クライアントからAPIを呼び出す。APIを呼び出すには、クライアントは、APIエンドポイントのURLを指定し、必要に応じてHTTPリクエストを送信します。

# コード
```python
from flask import Flask

app = Flask(__name__)

@app.route('/api')
def api_endpoint():
    # APIエンドポイントの処理をここに書く
    return 'Hello, API!'

if __name__ == '__main__':
    app.run()
```

# 説明
FWにFlaskを使用するとします。
Webフレームワークを使用することで、APIの作成や管理が容易になります。
```python
from flask import Flask
```

Flaskのオブジェクトを作成します
```python
app = Flask(__name__)
```

APIエンドポイントを作成するには、@app.routeデコレータを使用します。
ここでは、/apiというパスをAPIエンドポイントとして定義しています。
```python
@app.route('/api')
def api_endpoint():
    # APIエンドポイントの処理をここに書く
    return 'Hello, API!'
```

Flaskを起動させます
```python
if __name__ == '__main__':
    app.run()
```

# 補足
@app.routeデコレータを使用することで、APIエンドポイントを複数作成することもできます。
クソコードに対する怒りの記事を読んで共感できたことをまとめてみた

# クソコードとは
- 第三者が読んだときに苛立ちや頭を抱えてさせてしまうような状態のコード

# クソコードの特徴
- 動いているように見えて、そのまま納品できないような状態の未完成のまま
- 命名規則が終わっている、一発で理解できない
- 条件分岐が分かりづらい、フローが複雑で最悪
- 一貫性がない、周りのコードと合わせる意識が欠けている
- 第三者が読むことを想定できていない（配慮が足りない）
- 後で追加要件などを組み込みやすい構成になっていない
- その場しのぎで埋め込んだコードがそのまま放置されている
- etc

# クソコードを見たときの感情
※引用
> - メンテ不可能なコードに対する怒り
> - 意図がわからないコードに対する怒り
> - 設計や命名、テスト等の考慮不足に対する怒り
> - 書いた人の無知に対する怒り

# 優れたコードにしていくための心構え
- 実装しながら、レビューの観点を持つ
    - 誰が読んでも理解できる状態か
    - 条件文は適切な指定ができているか
    - 変数のスコープは適切になっているか
- 予め守るべきルールを明確に知っておく
    - スペースを付ける箇所
    - 一般的に変数やメソッドに使用される英単語
- こまめに綺麗に直す癖をつける
    - 見かけたら後回しにせず、その場で直す
- ハードコーディングしたものをそのまま放置しておかない
    - コミットするまえに直す
    - プルリクで弾く
- 他人が書いたコードと比較する
    - 条件の付け方
    - 命名規則の癖
    - 定義のタイミングや頻度
- 後で眺めたときに美しい状態過ぎて、手直しの余地がない状態にする
[メモ] WinのGitサーバからcloneするとき"hoge does not appear to be a git repository"と怒られる。

# 経緯
もろもろの理由からローカルのWindow8（古る！）のPCでGitサーバを立てることにした。
GitとOpenSSHをインストールしリポジトリを作成して、Ubuntu20.04のクライアントからCloneを試みたところ、次のように怒られた。

```shell
$ git clone ssh://GitServer/c/repository/hoge.git
Cloning into 'hoge'...
fatal: ''/c/repository/hoge.git'' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

もちろんレポジトリは正しく作成してるしSSHの設定・接続に間違いはなかった。

# 解決
参考元：[How do I git clone from a Windows machine over ssh?](https://stackoverflow.com/questions/53834304/how-do-i-git-clone-from-a-windows-machine-over-ssh)

参考元では次のコマンドを実行してWindowsのOpenSSHで使われるデフォルトのShellをbashに変えることを提案してる。

```powershell
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Program Files\Git\bin\bash.exe" -PropertyType String -Force
```

自分はこれで修正できた。
認知症フレンドリーテックハッカソンに参加しました

### 認知症フレンドリーハッカソンについて
認知症フレンドリーテックハッカソンとは福岡の認知症テックフレンドリーテックの取り組みの一つとして行われたハッカソンです。
在宅医療に携わっている精神科の内田医師が主催して行われました。
認知症フレンドリーテックとは、認知症の人の周囲にいる困った人を助けるサービス、認知症当事者が安心して生活し、力を発揮するためにテクノロジーを活用してこうという取り組みです。
内田医師は「認知症の人がより良く生きるためのテクノロジー」だと言われています。

### 参加の経緯
LINE Developper groupから紹介があったこと、主催者の内田医師自らが感じている課題感から実際に行動を起こし、参考書籍を紹介したり、啓蒙記事を書くなど取り組みに本気度を感じたこと、なにより面白そうであったことから今回の参加と至りました。

### 認知症の基礎知識
認知症についての基礎知識としては、
・認知症の人はたくさんいて、これからも増え続ける（2060年には人口の8人に1人が認知症になると言われている）
・認知症の最大のリスク要因は加齢
・認知症に対して重度に偏ったイメージを持っている人が多い
等、避けることのできない問題だと考えられます。
<br>
実際に、偏ったイメージとして
・自分はなりたくない
・介護が難しい
・迷惑をかける
・家族になってほしくない
・大変
というものがあり、自分もこのようなイメージを持っていました。<br>
それはなぜかと考えたときに、このようなイメージを持ってしまうのは、認知症のことをあまり知らない不安から来ているのではないかと考えました。
そこで認知症になる前から、お互いに助け合う互助の精神を持つ仕組みが必要ではないかという考え方に共感して、なかまのなかまチームに加わることにしました。

### なかまのなかまとは
「なかまのなかま」とは認知症フレンドリーテックハッカソンで生まれたプロダクトです。<br>
シビック（市民）× 地域DXで創るサイバーフィジカルシステムを目指している互助アプリです。
詳しくは[こちら](https://protopedia.net/prototype/3380)を見てください。<br>
https://protopedia.net/prototype/3380

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/b70ae55d-2ad3-8faa-e19f-3833a04c8cef.png)

地域情報とユーザーをつなげるインターフェースとしてLINEを、情報をユーザーに届けるトリガーとしてを使用することを想定しています。
今回デモ用のプロトタイプの作成には、enebularを採用しました。

### enebualarを採用した理由
・ウェブブラウザとアカウントがあれば使用できるので、準備するのが簡単であること
・Node-REDベースのローコードで扱えるので、誰にでも扱えること
・TLSが使用できるので、通信のセキュリティが担保されること
    を理由としてenebularを使用することになりました。

enebularとLINEの連携も簡単で、
・http inノードで簡単に受信することができる
・http requestノードを利用することでLINEのAPIを利用できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/3d72a1bb-c47b-1973-e485-76237dcec246.png)

・TLS環境が準備されているので、サーバー証明を準備する必要がない<br>
という利点があります。

さらに、Node-REDを利用してCivicTech向上に取り組んでいる、株式会社ウフルのenebularは今回のプロダクトの趣旨とあっていると考え選択しました。

### DXへの思い（感想）
なかまのなかまというプロダクトは、地方自治体によるオープンイノベーションの実例になるのではと考えています。
オープンイノベーションとは、 組織内部のイノベーションを促進するために、 意図的かつ積極的に内部と外部の技術やアイデアなどの資源の流出入を活用し、 その結果組織内で創出したイノベーションを組織外に展開する市場機会を増やすことである。と定義されています。
オープンイノベーションでは、外部のリソースを探索するために、外部への開発環境の提供、ハッカソンやアイデアソンや、オープンイノベーションの啓発活動としての少人数によるワークショップ等を行うことが必要になります。
enebularを利用することで、オープンイノベーションの環境を準備することも可能ではないか考えています。

### まとめ
テクノロジーを活用した仕組みと地域づくりを両輪で進めていくことで、認知症フレンドリーな街づくりに繋がっていくと良いと思います。


### 参考情報
#### 記事
[認知症フレンドリーテックについて知ってもらいたい](https://zenn.dev/tarocl/articles/ddce051465a24c)
[認知症フレンドリーについて](https://note.com/naokiuc/n/n7c7017dccfdb)
[認知症の有無に関わらず、安心して外出ができる地域とテクノロジー二ついて考えてみたこと](https://www.canva.com/design/DAFUggJRU_w/y8r68a9sQVsQ_C90TJfttg/view?utm_content=DAFUggJRU_w&utm_campaign=designshare&utm_medium=link2&utm_source=sharebutton#1)
[enebularブログ](https://blog.enebular.com/event/node-red-con-2021/)
[オープンイノベーションの重要性と変遷](https://www.nedo.go.jp/content/100879995.pdf)
[なかまのなかま](https://protopedia.net/prototype/3380)
#### 動画
[認知症フレンドリーテックとは何か](https://youtu.be/D3VCc9sdw-E)
[なかまのなかま動画](https://youtu.be/lEV2tibOJQM)
【Nginx / gunicorn】タイムアウト時間を変更する

## 概要
Nginx と gunicorn を用いてデプロイ後、一部のページで「502 Bad Gateway」エラーが発生。。
とりあえず表示させたいので、タイムアウト時間を延ばして解決させました。

## 環境
Python 3.9
Django 3.2

## 解決方法
nginx.conf に一文追加する
gunicorn 再起動時、コマンドライン引数を追加する

## 手順

nginx.conf を編集する

```
sudo vi /etc/nginx/nginx.conf
```

状況に応じて下記を追加する (デフォルトは60秒です)

```
http{
   ...
   proxy_read_timeout 300;
   proxy_connect_timeout 300;
   proxy_send_timeout 300;
   ...
}
```

各設定値について

- proxy_connect_timeout
静的Webサーバ ( Nginx ) とアプリケーションサーバ ( gunicorn ) との接続タイムアウト秒数を指定
アプリケーションサーバに接続要求を送り、n秒間接続できない場合に発生します
つまり「n秒経っても TCPコネクション が確立できない場合にエラーを吐くよ」という設定

- proxy_send_timeout
静的Webサーバ ( Nginx ) からアプリケーションサーバ ( gunicorn ) へのデータ送出の接続タイムアウト秒数を指定
つまり「TCPコネクション確立後、n秒経っても Nginx から gunicorn にリクエストを送信できない場合にエラーを吐くよ」という設定

- proxy_read_timeout
アプリケーションサーバ ( gunicorn ) から 静的Webサーバ ( Nginx ) へのデータ送出の接続タイムアウト秒数を指定
つまり「TCPコネクション確立後、n秒経っても gunicorn から Nginx へのレスポンスを受信できない場合にエラーを吐くよ」という設定

私の場合、一部のページのみ「502 Bad Gateway」エラーが発生していたので、レスポンスの受信時間のみ延ばしたかったので下記のように設定しました

```
http{
   ...
   proxy_send_timeout 300;
   ...
}
```

nginx を再起動して設定ファイルを読み込んでもらう

```
sudo systemctl restart nginx
```

つづいて gunicorn を再起動 ( ※コマンドライン引数に --timeout を追加が必要です )

```
# 現在起動中の gunicorn のポート番号 (PID) を確認
ps aux | grep gunicorn

# 指定のポート番号 (PID) を kill
kill <PID>

# gunicorn を起動
gunicorn config.wsgi:application --timeout 300
```

gunicorn のタイムアウト時間のデフォルトは 30秒なので --timeout を追加してあげましょう

## まとめ

無事 502 エラーが発生しなくなりました！
今後は速度改善に取り組みます。

## 参考記事

この備忘録は以下の情報を参考にさせていただきました。感謝です。

http://vatchcjplog.blog.shinobi.jp/nginx/%E3%80%90nginx%E3%80%91%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%A2%E3%82%A6%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%83%A1%E3%83%A2
シンタックスシュガー！名前、かわいい！♡

## 読んで欲しい人！
・過去の自分
→過去の自分が知ったらモチベ上がりそうと思ったから
・プログラミングを教えている人
→初学者がどのタイミングでモチベが上がるか知って欲しい！



[AtCoder](https://atcoder.jp/home)で[C++入門 AtCoder Programming Guide for beginners (APG4b)](https://atcoder.jp/contests/apg4b/tasks/APG4b_j)の問題を
解いていたらシンタックスシュガーと出会いました！
え、かわいい魔法少女みたいなおまじないで雑魚い敵ぐらいなら倒せそう！が
第一印象で、思わず、、、人差し指を前に出して、、、

# <font color="Red">シ</font><font color="orange">ン</font><font color="#DEB732">タ</font><font color="green">ッ</font><font color="blue">ク</font><font color="nany">ス</font><font color="purple">シ</font><font color="Red"></font><font color="magenta">ュ</font><font color="red">ガ</font><font color="orange">ー</font><font color="#DEB732">！</font>

と叫んで満足できたので色々調べてみました。
AtCoderにはインクリメントとデクリメントを説明の際に省略するやり方があるよって
教えてくれていて
その省略した書き方をシンタックスシュガーと呼びますと書いてありました。
語源何？と思ってググってみたら

>[引用](https://eow.alc.co.jp/search?q=syntactic+sugar#:~:text=syntactic%20sugar%E3%81%A8%E3%81%AF&text=%E3%82%B7%E3%83%B3%E3%82%BF%E3%83%83%E3%82%AF%E3%82%B9%E3%82%B7%E3%83%A5%E3%82%AC%E3%83%BC%E3%80%81%E6%A7%8B%E6%96%87%E7%B3%96,%E7%B0%A1%E7%95%A5%E5%8C%96%20%E3%81%95%E3%82%8C%E3%81%9F%E6%A7%8B%E6%96%87%E3%80%82&text=%E3%80%90%E8%AA%9E%E6%BA%90%E3%80%91%E3%80%8C%E5%8F%96%E3%82%8A%E6%89%B1%E3%81%84,%E3%81%84%E3%80%8D%E3%81%A7%E3%81%82%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8B%E3%82%89%E3%80%82)
シンタックスシュガー、構文糖、糖衣構文◆プログラミング言語において、ある構文と等価で、かつ人間にとって読み書きしやすいように簡略化された構文。◆【語源】「取り扱いやすい」を意味するsweetの第一義が「（砂糖のように）甘い」であることから。

と調べていたら魔法少女熱も落ち着いてきた。

# まとめ

省略記法のことをシンタックスシュガー！という。でした。

# おわり
<font color="Red">シ</font><font color="orange">ン</font><font color="#DEB732">タ</font><font color="green">ッ</font><font color="blue">ク</font><font color="nany">ス</font><font color="purple">シ</font><font color="Red"></font><font color="magenta">ュ</font><font color="red">ガ</font><font color="orange">ー</font><font color="#DEB732">！</font>
この部分ですが大文字にしたかったのですが
”＃”をつけて見出して大文字にする方法しか調べられなかったので
見出しにしないで大文字にする方法があればどなたか教えてください。