OmniAICreator/Qiita-1.07M huggingface dataset:
InfoMotionをインライン埋め込みしたら、Firebaseのダウンロード量が急増した話



## 発生背景
GoogleサイトでInfoMotionを共有しようと思い、GoogleサイトにInfoMotionのHTMLの埋め込みを行っていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/888363/8a755b3d-0d94-ae0b-508b-60e81b3c535d.png)

その後、Firebase Realtimeを確認したところ、ダウンロード量が急増してしまい、無料枠をあっという間に越えてしまいました。
スパイクの部分が、GoogleサイトにInfoMotionのHTMLの埋め込みを行った時の、ダウンロード量です。ダウンロード量が急激に増えていることが分かります。
![image (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/888363/d6e8f165-336f-1bd9-9d97-7bbefe74d07e.png)



enebularアカウントから、InfoMotionを確認しましたが、ダウウンロード量が急増することはなかったので、InfoMotionのインライン埋め込みがNGの可能性があります。

## 原因は？
googleサイトではInfoMotionのチャートをインライン表示しています。
そのため、データ自体はfirebaseからとってきていますが、それを表示させるためのscriptなどをInfoMotionから取得して、そのscriptでfirebaseに接続しているのが原因ではないかと思います。Googleサイト側で繰り返しデータを取得している可能性もありますが、詳しい原因は分かっていないです。。。

## 解決策は？
Googleサイトではなく、S3の静的ホスティングを使ったほうが良いのではないかと思います。
InfoMotionの共有方法については以下のサイトを参考に、InfoMotionのHTMLを取得して共有することができます。
(InfoMotionの共有：https://docs.enebular.com/ja/infomotion/shareinfomotion)


## おわりに
enebularのInfoMotion画面は正常で、google sitesだと異常になるため、InfoMotionのインライン埋め込みがNGな可能性があります。InfoMotionを公開する場合は、ダウンロード量を確認しながら行うことをお勧めします。
Microsoft Graph API 利用のための Python による Azure Access Token の取得


## 概要
Microsoft Graph API を利用するために必須となる アクセストークン を取得するためだけの Python プログラムです。
事前に必要なクレデンシャル情報については、[この記事](https://qiita.com/kura_yu/items/cd2ebc1763a8923f3d7a) を参考にして取得しました。

## 実行環境
macOS Big Sur 11.1 
python 3.8.3

## クレデンシャル情報の定義
事前に取得したクレデンシャル情報は .zshenv で定義しています。

```
# AzureAccessToken取得のための定義
export TENANT_ID=zzzzzzzzzzzzzzzzzzzzzzzzzz
export CLIENT_ID=xxxxxxxxxxxxxxxxxxxxxxxxxx
export CLIENT_KEY=yyyyyyyyyyyyyyyyyyyyyyyyy
```

## 実行プログラム

```python:GetAzureAccessToken.py

import json
import os
import requests
import argparse
import time

# Microsoft GraphAPI クレデンシャル情報の取得
TENANT_ID = os.environ['TENANT_ID']
CLIENT_ID = os.environ['CLIENT_ID']
CLIENT_KEY = os.environ['CLIENT_KEY']


# Azureアクセスのためのアクセストークンの取得
def get_azure_access_token() -> str:
    
    # access_token を取得するためのヘッダ情報
    headers = {
        'Accept': 'application/json',
        'Content-Type': 'application/x-www-form-urlencoded'
    }

    payload = {
        'client_id': CLIENT_ID,
        'scope': 'https://graph.microsoft.com/.default',
        'grant_type': 'client_credentials',
        'client_secret': CLIENT_KEY
    }

    # access_token を取得するためのURLを生成
    TokenGet_URL = "https://login.microsoftonline.com/" + \
        TENANT_ID + "/oauth2/v2.0/token"
    # print(TokenGet_URL)

    # 実行
    response = requests.get(
        TokenGet_URL,
        headers=headers,
        data=payload
    )
    # requrest処理のクローズ
    response.close

    # その結果を取得
    jsonObj = json.loads(response.text)
    return jsonObj["access_token"]


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Azureアクセスのためのアクセストークンの取得')
    args = parser.parse_args()

    start = time.time()
    access_token = get_azure_access_token()
    generate_time = time.time() - start

    print("")
    print("取得時間:{0}".format(generate_time) + " [sec]")
    print("取得アクセストークン：")
    print(access_token)
    print("")

```

## プログラムの実行
 
最初にヘルプを表示してみます。

```
$ python GetAzureAccessToken.py -h
usage: GetAzureAccessToken.py [-h]

Azureアクセスのためのアクセストークンの取得

optional arguments:
  -h, --help  show this help message and exit
```


では、アクセストークンを取得してみます。

```
$ python GetAzureAccessToken.py   

取得時間:0.2260270118713379 [sec]
取得アクセストークン：
iJKV1QiLCJub25jZSI6ImRx  ・・・中略・・・  KjjJQGdwR-5CusZ0Nc0ON62Z0Jm
```

## 参考情報
以下の情報を参考にさせていただきました。感謝いたします。

[Microsoft GraphAPIをつかってみよう。-- 事前準備 編--](https://qiita.com/kura_yu/items/cd2ebc1763a8923f3d7a)
[Microsoft GraphAPIをつかってみよう。-- 実践 編--](https://qiita.com/kura_yu/items/772d68498eb47de09cf8)
[PythonでSharePointの特定サイトの特定リストの特定レコードのURLを取得する方法](https://qiita.com/rnakamuramartiny/items/dca6023fa0b503429f68)
[訳あってMicrosoft Graph API調べてみた](https://qiita.com/massie_g/items/fe7540161aa4a5f86bf5)
【カウントダウン】何秒経ったらゲーム終了と表示する【テンプレスクリプト】

下記スクリプトがアタッチされたオブジェクトは、
fltTimeCountで指定された分だけカウントダウンを行い、
ゼロになったら「ゲーム終了」とされます。

```CountDown.cs
using UnityEngine;
using UnityEngine.UI;
public class CountDown : MonoBehaviour
{
    public float fltTimeCount;
    public Text txtCountDown;
    void Update()
    {
        fltTimeCount -= Time.deltaTime;
        txtCountDown.text = fltTimeCount.ToString("f0");
        if (fltTimeCount <= 0) txtCountDown.text = "ゲーム終了";
    }
}
```
第13回 AZ-900(Azure Fundamentals)受験記録



お久しぶりです。
久々のクラウド系に関する記事になりますが、Azureの**AZ-900**を受験し一回で合格しました。
今後、クラウド資格の入門として受験する方、またはAWSのSAAに加えて、さらに守備範囲を伸ばそうと思っている方に対して、受験した結果や所感などを共有できればと思います。

##結果
AZ-900(日本語)
825/1000で合格(700点がボーダー)

#試験構成

時間60分
問題数28問

・4択から1つを選択or複数選択
・ドラッグ＆ドロップ
・問題文に対してYESかNOかの2択問題

※シミュレーション型や記述式の試験は無し
※問題数ですが、ほかの試験会場や受ける時期によっては多少前後あるかもしれません

##試験範囲
クラウドの概念について説明する (15-20%)
Azure のコアサービスについて説明する (30-35%)
セキュリティ、プライバシー、コンプライアンス、信頼について説明する (25-30%)
Azure の価格サービス レベル アグリーメントとライフサイクルについて説明する(20-25%)
引用:https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900

##勉強法
学習期間:**3週間**
クラウドの知識:AWSの研修を受講したことがあり、EC2やELBなど**クラウドの基本は理解している**
クラウド系の保有資格:**無し**

###step.1(3日)教材学習
・Azureのアカウント開設(１カ月は無料)
・[Microsoft Azure実践ガイド]
(https://www.amazon.co.jp/Microsoft-Azure%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear/dp/4295002798/ref=pd_lpo_14_t_2/355-1318091-5406259?_encoding=UTF8&pd_rd_i=4295002798&pd_rd_r=2e79292a-c64f-4272-a19d-3e9efa182b48&pd_rd_w=nxoSy&pd_rd_wg=Ga0oV&pf_rd_p=4b55d259-ebf0-4306-905a-7762d1b93740&pf_rd_r=NNTZWEXWWTAYTKZEC88P&psc=1&refRID=NNTZWEXWWTAYTKZEC88P)
→1週目なので内容をざっくりと読み、テキストの内容を真似しながら手を動かす。どうしてもわからない箇所は飛ばす！

###step.2(7日)ハンズオン学習
・Udemyの[作りながら覚えるMicrosoft Azure入門講座（IaaS編）]
(https://www.udemy.com/course/microsoft-azure-iaas-part/)
・[Microsoft Azure実践ガイド]
(https://www.amazon.co.jp/Microsoft-Azure%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear/dp/4295002798/ref=pd_lpo_14_t_2/355-1318091-5406259?_encoding=UTF8&pd_rd_i=4295002798&pd_rd_r=2e79292a-c64f-4272-a19d-3e9efa182b48&pd_rd_w=nxoSy&pd_rd_wg=Ga0oV&pf_rd_p=4b55d259-ebf0-4306-905a-7762d1b93740&pf_rd_r=NNTZWEXWWTAYTKZEC88P&psc=1&refRID=NNTZWEXWWTAYTKZEC88P)
→2週目はハンズオンで説明されている内容を照らし合わせながら読む

###step.3(7日)問題演習
・会社から配布されている模擬試験(１週間で**7週以上**解く)
→1周目は正答率を気にせず、１日で全て解く
 2週目からは問題を解きながら、わからないことを教材だけでなく
[Azureドキュメント]
(https://docs.microsoft.com/ja-jp/azure/?product=feature)
ここから問題で問われている技術を調べて問題を理解する
・[Microsoft Azure実践ガイド]
(https://www.amazon.co.jp/Microsoft-Azure%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear/dp/4295002798/ref=pd_lpo_14_t_2/355-1318091-5406259?_encoding=UTF8&pd_rd_i=4295002798&pd_rd_r=2e79292a-c64f-4272-a19d-3e9efa182b48&pd_rd_w=nxoSy&pd_rd_wg=Ga0oV&pf_rd_p=4b55d259-ebf0-4306-905a-7762d1b93740&pf_rd_r=NNTZWEXWWTAYTKZEC88P&psc=1&refRID=NNTZWEXWWTAYTKZEC88P)
→3週目以降は模擬テストで間違えた個所をラインマーカーでチェックし、理解したことを教材に書き込む

###step.4(3日)最終調整
・会社から配布されている模擬試験を**毎日1周**し、問題を忘れないようにする
・模擬問題を解くうえで、よく間違える問題や理解してない技術をノートにまとめる

###step.5(2日)直前確認
・会社から配布されている模擬試験を**毎日1周**
・Udemyの[Microsoft Azure Fundamentals (AZ-900) - Practice Tests]
(https://www.udemy.com/course/microsoft-azure-fundamentals-az-900-practice-tests/)
英語でも内容を推測し、**初見で６回分の模擬試験の正答率がすべて合格点とるレベル**が理想
問題自体は模擬試験と同じだけど、若干問われてくる角度が違います
※注意※
Udemyは本試験と内容が若干異なるので、**あくまで記憶の確認**のために最終確認でテストを6回全て解いて、解説を読んだら、**絶対にそれ以上やらない。自分の覚えた技術が正しいかどうかを確認するだけにとどめてください。**特にUdemyの教材は**すべて英語**なので**日本語でも理解不足なことは、英語でもっとわけわからなくなってしまう**こともあるので。。！

##受けた感想
受験して思ったことは、ひっかけ問題もなく模擬試験の内容と教材の技術を理解していれば難しくはない試験だと思いました。
またAzureの知識がなくても、例えばAWSに少しでも関わったことのある方でしたら、似ている概念が多いので比較的早く技術の理解が進むと思います。
Elixirで速度を追い求めるときのプログラミングスタイル PartⅡ，Pelemayの近況もあるよ

この記事は[fukuoka.ex Elixir／Phoenix Advent Calendar 2020](https://qiita.com/advent-calendar/2020/fukuokaex) 25日目の記事です。

昨日は @Yoosuke さんの[「高校生に教えていた Elixirのカリキュラムの一部をクリスマスイブに公開します。（５時間分まで）」](https://qiita.com/Yoosuke/items/6c623a882acdf7956589)でした。

[fukuoka.ex Elixir／Phoenix Advent Calendar 2020](https://qiita.com/advent-calendar/2020/fukuokaex)は，[WebテクノロジーのLGTM数順](https://qiita.com/advent-calendar/2020/ranking/feedbacks/categories/web_technologies)で堂々1位となりました。 素晴らしいことです！

さて，今日は[「Elixirで速度を追い求めるときのプログラミングスタイル」](https://qiita.com/zacky1972/items/5963a8bf5f2a34c67d88)の第2弾ということで，「Elixirで速度を追い求めるときのプログラミングスタイル PartⅡ，Pelemayの近況もあるよ」をお送りします。

# BasicBenchmarkElixir

今回のベンチマークのコードはこちらです。

https://github.com/zacky1972/basic_benchmarks_elixir

# 検証環境

```bash
> elixir -v
Erlang/OTP 23 [erts-11.1.1] [source] [64-bit] [smp:36:36] [ds:36:36:10] [async-threads:1] [hipe]

Elixir 1.11.2 (compiled with Erlang/OTP 23)
```

iMac Pro 2017 のCPU/GPU全部盛りで検証しています。

# 結果

```
## EnumBench
benchmark name iterations   average time 
Enum.map               50   55946.10 µs/op
recursive              50   56215.64 µs/op
## ListAddBench
benchmark name iterations   average time 
add long list  1000000000   0.01 µs/op
add head       1000000000   0.01 µs/op
add tail       1000000000   0.01 µs/op
## ListPopBench
benchmark name iterations   average time 
pop head        100000000   0.02 µs/op
pop tail               50   37582.68 µs/op
## ListReverseBench
benchmark name iterations   average time 
reverse               200   9471.07 µs/op
## ProcessBench
benchmark name iterations   average time 
echo              1000000   1.42 µs/op
send list         1000000   1.42 µs/op
```

* `EnumBench`は`Enum.map`と`recursive`の実行時間を比較しています。ご覧の通り，ほぼ差はなく，`Enum.map`を選ばない手はないかなと思います。
* `ListAddBench`は次の3つのベンチマークです。どれも速度に差はなく，極めて高速に処理できることがわかります。
    * `add long list`は長いリスト2つを`++`で結合します。
    * `add head` は先頭に1つ要素を追加します `[:a | @list]`
    * `add tail` は末尾に1つ要素を追加します `@list ++ [:a]`
* `ListPopBench`は次の2つのベンチマークです。先頭から要素を取り出すのは極めて高速ですが，末尾の要素を無理矢理取り出すのは極めて低速です。
    * `pop head` は `[head | tail]`を実行します。
    * `pop tail` は `List.delete_at(@list, -1)`を実行します。
* `ListReverseBench`は`Enum.reverse`を計測しています。リスト長が長くなると実行時間がかかりますが，他の操作に比べると比較的高速です。
* `ProcessBench`は，`spawn`→`send`→`receive`の一連の操作にかかる時間を計測しています。プロセスを起動しているとは思えないくらい，極めて高速に実行できます。ちなみにプロセスをプールするよりも高速に実行できることがわかっています。送るメッセージの長さを変えても実行時間は変わりませんでした。ノードを起動して，分散実行した時を検証してみたいところです。

# 所感

次の結果は，今までの常識を塗り替える物だったので，特に驚きました。

* `++`は結合するリストの長さによらず，極めて高速に実行できること
* `Enum.map`と再帰スタイルの実行時間に差がないこと
* プロセスの起動は極めて高速で，1〜数μ秒オーダーであること，プールするよりも速いこと

ElixirおよびErlangのアップデートにより，これらの改善が図られてきたのではないかと思うと，胸熱です。

# この結果を今後どう活かすか？

なぜこのような基礎的なベンチマークを取っていたかというと，Pelemayのマルチコア並列処理版を作ろうとしているからです。プロトタイプ版はすでに動いていて，従来のFlowやPmapはもちろんのこと，EnumやPelemayよりも高速に動作できることを確かめています。数々の試作を重ねて基礎データを積み重ねてきたことで，設計・実装する上での肝となる部分が把握できたので，現在，プロトタイプ第2弾を実装しているところです。

この成果については，論文発表をしてから改めて発表する予定です。

本研究成果は、科学技術振興機構研究成果展開事業研究成果最適展開支援プログラム A-STEP トライアウト JPMJTM20H1 の支援を受けた。
ポート指定で通信を発生させる(疎通確認)

####1.目的
Windows環境でポートを指定した場合の疎通確認方法に関して記載します。

####2.環境
・Windows10
・powershell

####3.方法
powershellで下記コマンドを実行。
■ Test-NetConnection IPアドレス -Port ポート番号
実行結果

~~~
PS C:\Users\username> Test-NetConnection IPアドレス -Port ポート番号


ComputerName     : IPアドレス
RemoteAddress    : IPアドレス
RemotePort       : Port番号
InterfaceAlias   : イーサネット
SourceAddress    : 自端末のIPアドレス
TcpTestSucceeded : True or False
~~~
TcpTestSucceeded 部分が「True」の場合、疎通OK。
[バッチ] 3秒おきに、何かのアプリのショートカットをたたき続けるバッチ

# もくじ

https://tera1707.com/entry/2022/02/06/144447

# やりたいこと

アプリの起動時に起きるバグの調査をしているときに、何度も繰り返しアプリを起動しなおすのが面倒なので、繰り返しアプリを起動してくれるバッチを書きたい。

# バッチのコード

下記を実行すると、3秒おきに「MyApp.exe.lnk」というショートカットをたたくのを99回行う。

※これだとアプリが3秒おきにどんどん複数立ち上がっていってしまうので、終わらせる処理もほんとは必要。(今回実験時は、アプリの中に、勝手に終わってくれる処理をテスト用で追加したのでバッチには入れてない)

```test.bat
@echo off
setlocal enabledelayedexpansion
cd %~dp0

for /l %%i in (0,1,99) do (
    MyApp.exe.lnk
    timeout /nobreak 3
)

pause

```

今回は入れてないが、MyApp.exeを(強制的に)終わらせても差し支えない場合は、下記でkillすることができる。

```.bat
taskkill /f /im MyApp.exe
```


# 参考

Windowsバッチまとめ
https://qiita.com/tomotagwork/items/5b9e08f28d5925d96b5f
【LookAt関数】オブジェクトAが、指定のオブジェクトBを常に向くスクリプト【テンプレスクリプト】

下記スクリプトがアタッチされたオブジェクトは、
targetObjectで指定されたオブジェクトの方向を常に向くようになります。

```LookAt.cs
using UnityEngine;
public class LookAt : MonoBehaviour
{
    public GameObject targetObject;
    void Update()
    {
        this.transform.LookAt(targetObject.transform);
    }
}
```
アジャイルから学ぶスコープの定義について

スコープは、プロジェクト定義の中で不可欠な要素の一つです。その上で、何をすべきかという「実行する作業の量」を想像しますね。

それでは、最初にスコープという言葉の意味について辞書で調べてみましょう：

イタリア語のscopo（「目的」）より、ラテン語のscopus（「ターゲット」）から

おお、ちょっと待ってください。元の意味は、実行する作業の量ではなく、目的に関するもののようです・・・興味深いですね。アジャイルには多くの捉え方があるので、勘違いを避けるためにここではScrumについて話しましょう。

アジャイルスクラムプロジェクトにおける進捗は、実行されたタスクの数ではなく、提供された利用者経験の項目、つまりユーザーストーリーで測定されます。それは、進捗を確認するために「作業の量」で計測するそれと根本的に異なります。何を開発したとしても、利用者経験を提供できない限り全てが無駄です。厳しく聞こえますが、それがアジャイルスクラムプロジェクトのスコープを正しく理解するための元です。

さて、スコープが何であるかを明確に理解したら、より具体的に話してみましょう。

アジャイルスクラムプロジェクトにはスプリントがあります。
スプリントとは何でしょうか？ある意味ミニプロジェクトです。非常に短い期間で、明確な目標と明確に定義された提供内容を持つミニプロジェクトです。アジャイルスクラムは「やるべきこと」ではなく「利用者への提供内容」にフォーカスするので、「タスク」ではなく「提供」となります。スプリントのサイズは、その中のユーザーストーリーのサイズの合計であり、ストーリーポイントとも呼ばれます。それはパラダイムによって異なる場合があります。

ストーリーポイントとは何でしょうか？それはユーザーストーリーの複雑さを測定するための単位です。特定の時間やその他の物理的計測値に拘束されない任意の数値です。プロジェクトでストーリーポイントを計測する方法を決定したら、そのモデルは最後まで使いましょう。そうしないと、見積もりが正確でなくなります。

ここでは、よく使われている期限付きのベースラインを使用したユーザーストーリーポイントを測定する1つの方法をご紹介します。

言葉で表現すると、一定量のストーリーポイントがあります。特定の適度に短い期間で実行できるタスクを表してベースラインと呼ばれます。ベースラインより上または下のストーリーポイントは、実現の相対的な難しさを表しています。難易度は通常、未知数の量に関係しているため、タスクがベースラインの3倍もしくは4倍難しいかどうかを確実に見積もることはできません。ここではフィボナッチ数列を使います。フィボナッチ数列は、上に行くほど幾何学的に大きな数を生成する優れた特性を備えているため、未知数が多すぎてわからない時は必然的に大きな数になります。大きすぎるタスクは推定できませんよね。トートロジーになってしまいごめんなさい。そのため、通常はストーリーポイントの量に上限を設けます。

概略的にしますと：

 ![agile_scrum_scope.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905684/449df29c-ec0d-c38c-4508-327580720550.png)

さて難易度を見積もる方法がわかりましたので、スコープの話に戻しましょう。

途中でスプリントを変更するのは悪い考えだと聞いたことがありますが、最近のアジャイル業界は少し緩くなっています。ですが、実行中のスプリントのスコープは変更してはいけません。実行中にスコープが変更されると、終了すべきストーリーポイントの量に影響がでるので、メンバーが過労して苦しむことになります。あまり自信がないですが、本来であれば人間は残業を嫌うはずです。必然的に品質も落ちます。残業をしたくない場合は、スプリントスコープで遊んではいけません。

特にコーポレートアジャイルにおいて見過ごされがちな１つに、作業要求者と実行者の間の契約という存在です。いわゆる契約とは、顧客とのビジネスニーズの短い定義であり、そのニーズを実装した明確な定義です。よって契約とは、ビジネスニーズの短いステートメントと、そのニーズを実装するためのユーザーストーリーのリストであると言えます。

「契約」を取り上げた理由は、変わらずスコープの問題です。我々は顧客から要求された仕事をします。要求されていない仕事をする必要はありません。顧客が依頼していないものを提供することは優しいことと思うかもしれませんが、契約に記載されていることを行うのであって、記載されていない仕事はしてはいけません。その理由は、頭に浮かぶすべてのベルやホイッスルではなく、利用者の提供に重点を置き、ユーザーの価値を最大化するためです。最低限までスコープを減らして品質を提供するという考えです。ストーリーポイントは、ユーザーストーリーを提供する難しさを測定するためのものですが、ユーザーストーリー自体は非常に単純なステートメントであり、特定のビジネスニーズに到達するためにソフトウェアがどのように動作するかを説明しています。

まとめますと、アジャイルスクラムのスコープは利用者価値の量で表される。ということです。ユーザーストーリー、ストーリーポイントは、利用者価値を表現する単なる方法であり、それ以上でもそれ以下でもありません。

このような用語でスコープを抑えると、開発者が正気を保ちながら（つまり、仕事しすぎて倒れない）、最大限に効率的になる（つまり、ユーザーが望むものを提供する）のに役立つことになります。
[Spring Boot] Customなバナーを作ってみよう

# バナーの作り方


## org.springframework.boot.Bannerインターフェイスを実現してカスタムバーナーを開発

``` java
@SpringBootApplication
public class SampleApplication {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(SampleApplication.class);
        springApplication.setBanner((environment, sourceClass, out)->{
            out.println("Spring Boot! Corn!");
        });
        springApplication.run(args);
    }
}
```

## src/main/resourc/banner.txtファイルを作成してbannerを代替

http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type
サイトでテキストを素敵なアスキー文字に変えてからスプリングブートバナーに登録しよう!!

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/f965d334-130e-e1a2-3cd3-0d01e17975c6.png)


Bannerで表示できる変数

``` 
${application.version}: MANIFEST.MF に設定された Implementation-Version
${application.formatted-version}: ${application.version} 
${spring-boot.version}: 使用されているSpring Bootバージョン
${spring-boot.formatted-version}: ${spring-boot.version} 
```
【Mac】VS codeでCommand+zで戻しすぎた際の対処(Command+y設定方法)

よく知られているように、コードを一つ戻す時はCommand+zというショートカットが有ります。


この逆は？というとCommand+yがあると思うのですがmacではvscodeの初期状態ではこちらは使うことができないです。

その際の方法を下に示します。簡単で便利！

```
まずvscode上でCommand+shift+Pを押します。
下のようにバーが出てくると思います。
```



![スクリーンショット 2020-12-25 13.31.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/845264/6b8ab911-c798-7f0a-4d77-2b916c11afd8.png)


```
下でopen keyboard shortcut(json)というものを探します。
keybまで入力すると出てくると思います。

```

![スクリーンショット 2020-12-25 13.33.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/845264/65902ec3-0ab7-d527-8502-a4db10471ffa.png)



```
開くとこのような[]
のみのjsonコードが出てくるのでそこで以下を[]の間に入れます。

{
    "key": "cmd+y",
    "command": "redo",
    "when": "editorTextFocus"
}

#下のような形で入れたら大丈夫です。
```
![スクリーンショット 2020-12-25 13.38.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/845264/623ba88f-69b6-9250-8bf7-a4e20bcd897c.png)

これで保存したら設定完了です。
試してみると無事使えることがわかります。

お疲れ様でした。
[JAVA]  ストリーム（Stream）の種類

# ストリーム（Stream）の種類

Java8に追加されたjava.util.streamパッケージを見てみましょう。
https://www.developer.com/java/data/stream-operations-supported-by-the-java-streams-api.html

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/02de483e-d31b-3897-32fe-9257721f7dde.png)


全てのストリームで使用できる共通メソッドは、Base Streamに定義されており、
Streamはオブジェクト要素を処理するストリーム、IntStream、LongStream、DoubleStreamはそれぞれ基本タイプのint、long、double要素を処理するストリームである。

## コレクションからストリームを得る

``` java
List<String> list = Arrays.asList("あ", "い", "う");
Stream<String> stream = list.stream(); // Collection . stream()
```

## 配列からストリームを得る

``` java
String[] strArray = {"あ", "い", "う"};
Stream<String> stream = Arrays.stream(strArray); 
int[] intArray = {1, 2, 3, 4};
IntStream intStream = Arrays.stream(intArray); 
```

## 数字の範囲からストリームを取得

``` java
IntStream stream = IntStream.rangeClosed(1, 100);
```

## ファイルからストリームを取得

``` java
public static void main(String[] args) throws IOException{
        
        Path path = Paths.get("src/stream/list.txt");

        
        Stream<String> stream = Files.lines(path, Charset.defaultCharset()); 
        stream.forEach(System.out :: println);
        System.out.println();

        
        File file = path.toFile();
        FileReader fileReader = new FileReader(file);
        BufferedReader br = new BufferedReader(fileReader);
        stream = br.lines();
        stream.forEach(System.out :: println);
}
```

## ディレクトリからストリームを取得

``` java
public static void main(String[] args) throws IOException{
        Path path = Paths.get("c://");
        Stream<Path> stream = Files.list(path);
        stream.forEach(p -> System.out.println(p.getFileName()));
}
```
ソースコード解読の方法論


#はじめに
引継ぎや途中参入する場合、ソースコードの解読をすることになる。
その方法論のメモである。

#ソース以外の情報を集める
何をするプログラムなのかを依頼者に聞く。
関係者を調べて、ざっくり情報を集める。
資料の有無と所在を確認する。
全ての資料をざっくりは目を通す。
退職者の引継ぎであり残されたPCがある場合は、中身を調査する。

情報の時系列には注意すること。


#ソースの保全
元のソースファイル一式をコピーしてZipにする。
バージョン管理されていない場合は適用する。（GitやSVN）
　差分チェックやRevertを酷使しよう。

とにかく、いつでも最初の状態に戻せるようにしておくこと。


#ソース解析の第一歩
ソースファイルの行数をExcelなどにまとめる。
エントリポイントを見つける
何らかの区分で信用点数をつけて推測していく。

モチベーションを保つためにも、記録やメモをつけること。


#ソースをビルドしてデバッグできるようにする。
ビルドが通らない場合は、関連ライブラリやファイルが足りないか、ビルド環境が違うことが考えられる。
ビルドができてエントリポイントを通れば、問題の半分以上は解決している。
エラーメッセージは読んで調べること。


#地道に作業を繰り返し
変更したり、リファクタリングをして理解を深めていく。
ログ機構が組み込まれている場合は利用して片っ端から出力して確認する。
　ログ機構がない場合は組み込むことを検討する。
御用聞き営業からソリューション営業に代わって感じたこと

こんにちは。
ウェブクルー Advent Calendar 2020 の25日目の記事です。
昨日は @haruka_kouyamaさんの	[国全体の課題解決「引越しワンストップサービスの実現」に奮闘している話](https://qiita.com/haruka_kouyama/items/367722b453c89031d9a1)でした。

# はじめに
私は今年の夏にWebcrewへ転職した社会人5年目のセールス担当です。
既存事業と新規事業の2軸でソリューション営業を行っています。

同社は3社目ですが、最も長い期間在籍した建材メーカーでの営業と今の営業手法が大きく異なっております。
この記事では２つの営業手法とそれぞれ営業員目線でのメリット・デメリットについて書きたいと考えています。


# メーカーで経験した「御用聞き営業」とは
御用聞き営業とは
<strong>「常に客の困りごとを聞き、近い存在としてサポートをして継続的な受注を取る」</strong>営業手法と考えています。

いわゆるルート営業で、同じ顧客に用が無くても何度も足を運び顔を覚えてもらうことが大事になります。
ぶっちゃけ<strong>前時代的</strong>ですね。


# 御用聞き営業のメリット・デメリット
■メリット
①スーパー聞き上手になる。
└基本的に顧客さんの話をどんな内容でも「うんうん、はぁー、なるほど。」と聞くことが重要になります。なのでどんな話でも興味ありげに聞くことが可能になります！（いい事なのかな…？）
<strong>「人って基本的に自分の話をしたいんだな…」</strong>
とメーカーでの営業時代に気づき、初対面の人との会話もそこまで困らなくなりました。

②スピード感を養える
└顧客が求めることは<strong>どんなに小さなことでも</strong>速攻で叶えないといけないというマインドになります。問い合わせがあれば即答し、できない場合でも3時間以内に進捗を伝える等をして<strong>あなた（顧客）のことを一番に考えております！</strong>速攻というアピールが上手になってきます。

■デメリット
①価格戦略以外の営業戦略があまり見につかない（かも）
└これは私が単純に想像力がない可能性も充分にありますが…
御用聞き営業がメインの業界は得てして
・商材がシンプル
・競合他社と大きな違いがない
場合が多かったりします。
よって、プレゼンやアイデアで勝ち取る！という場面が比較的多くないです。


# 今の会社で求められる「ソリューション営業」とは
ソリューション営業は<strong>「顧客課題を抽出し、解決策を提案し自社商品を販売する</strong>」営業です。
Webcrewは「比較サイト」を武器に顧客の集客面での課題を解決していきます。
顧客がどんな悩みを抱えているかを見つけることが重要になります。


# ソリューション営業のメリット・デメリット
■メリット
①仮説構築力が養われる
└「顧客が何に悩んでいる？」「こういう点が課題じゃないか？」と様々な仮説を一つの商談に建てる為、仮説構築力が養われます。

②めちゃくちゃ良い事をしてる気分になれる。
└本気で顧客が解決したい内容を必死で取り組んでいくので、商談が成立して顧客が満足しているとすごいやりがいを感じます。

■デメリット
<strong>①めっちゃくちゃ難しい</strong>
└私の場合ですが、かなり仮説の構築などに苦手意識を持っており「顧客が何を求めてる？課題を感じている？」と考えるのがすごい時間がかかってしまいます。
めっちゃくちゃ難しいです。いつも頭を抱えています…。


# まとめ
「御用聞き営業」と「ソリューション営業」について、自分なりに感じたことをまとめてみました。
「ぶっちゃけどっちが良い営業手法なの？」といわれると、正直どっちも必要なスキルなんじゃないかと考えます。どちらも難しさも、やりがいも感じられる営業手法です。
ただ私は圧倒的にソリューション営業は苦手なので、これから積極的に学んでいければと思います。

夢は人情的な部分（主に御用聞き営業）と戦略的な部分（主にソリューション営業）をどちらも持ち合わせた最強の営業マンです！

最後までお読みくださり、ありがとうございました！
【超簡単】GitHubの流れを大雑把に理解する！

## はじめに
この記事はGitHubの使い方ではなく、大まかな流れや概要を書いていきます。
自分自身プログラミンングスクールでGitHubの使い方を教わりましたが、流れや仕組みを理解せずに使っていたため、たいへんな思いをしたのがこの記事のきっかけです。
一人でも多く同じ境遇の方々のためになればと思います。
実際、流れを掴んでしまえば簡単に使えるようになります！！（慣れも必要ですが）

## GitとGitHubは違うモノ
勘違いを解消します。
GitとGitHubは違うモノです。
大雑把な理解が目的なので違うという事だけをわかっていれば良いですが、
簡単にお互いの関係を説明すると**Gitの技術を使ってGitHubが作られている**という事です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914577/58924458-231a-c4da-8438-f78a8964bc78.png)

# GitHubとは
> 公式文章 https://guides.github.com/activities/hello-world/
> GitHub is a code hosting platform for version control and collaboration. It lets you and others work together on projects from anywhere.

**要するには、『バージョンコントロール』と『グループで働く』ためのコードをアップできるプラットフォームです。**

- バージョンコントロール
- グループで働く

を目的に色々な機能があるのです！！

# GitHubの流れ
## 1. そもそもの考え方
GitHubはコードを管理するためのプラットフォームなので、GitHub上でコードを置いておくことができます。これを**リモートリポジトリ**と言います。

GitHub上でコードを管理できますが、実際にコードを書くのは自分のパソコンです。自分のパソコン上に置いてあるコードを**ローカルリポジトリ**と言います。

リモートリポジトリもローカルリポジトリも管理しているコードは同じプロジェクトのものです。
(わかっていたら当たり前ですが、自分はここで躓きました…)

脳内イメージ↓
![スクリーンショット 2020-12-25 13.00.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914577/e34c6052-c764-d1cd-7fe9-c3d5fafa3097.png)

## 2. GitHub上にコードを上げて編集する
まず、ローカルリポジトリ（パソコン上）でリモートリポジトリを編集するデータを確定させるためにCommitします。
Commitとはゲームで言うセーブみたいなものです。(正確には違いますが、正確性重視ではなく大雑把な流れを理解すると言う意味で良いです)

Commitで自分の編集しているコードをセーブした後は、Pushをする事によってリモートリポジトリに変更を加えることができます。
PushとはローカルリポジトリでCommitした内容をリモートリポジトリに送って更新することを言います。

脳内イメージ↓
![スクリーンショット 2020-12-25 13.20.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/914577/f5050fbb-8f70-60e0-5d0c-ff29b251b53e.png)

## 3. 本当はまだまだあります
実は他にもGitHubには様々な機能があります。
説明した内容は基礎オブ基礎。
しかし、とっかかりを掴んじゃえばトントン拍子で理解できると思います！
もっと知りたい、もしくは使い方を知りたい場合は、
https://qiita.com/nnahito/items/565f8755e70c51532459
がわかりやすいと思います。

# 最後に
自分がプログラミングを勉強し始めた時にあったら良いなと思うものを書いてみました。
いかがでしたでしょうか。
間違っている点やわかりにくい点があったらお気軽に教えてください！
では次回の投稿でお会いしましょう。
その `@Binding var` 本当に必要？

よくこのようなコード目にします：

```swift:MainView.swift
struct MainView: View {
    
    @State var inputText: String
    
    var body: some View {
        
        VStack {
            TextField("Text Input", text: $inputText)
            LabelView(outputText: $inputText)
        }
        
        
    }
    
}
```

```swift:LabelView.swift
struct LabelView: View {
    
    @Binding var outputText: String // ←この `@Binding var`
    
    var body: some View {
        
        Text(outputText)
        
    }
    
}
```

何故このようなコードを書くかと言うと、おそらく多くの人は特に深く考えたことなく、単純に「`@State var` の `inputText` の値を流し込むから、`@Binding var` を条件反射で書いた」的な思考ではないかと思います。

しかし、実は `outputText` に関しては、`@Binding var` にする必要なく、単純に `let` でも問題ないのです。

何故 `let` でいけるのかと言うと、`@Binding` の役割と、`View` が何のかを理解しておく必要があります。

まず `@Binding` はどう言う役割かと言うと、これは「この値を変更するので、変更された値を参照元にも反映させてね」と言うことです。つまりどう言うことかと言うと、もし `LabelView` において `outputText` を変更することがあって、さらにその変更を元の `MainView` の `inputText` にも反映させたいなら、`@Binding` を使う必要があると言うことです。そう、平たく言えば `@Binding var outputText` は、単純に `@State var inputText` の `set` メソッドを暴露してるわけです。SwiftUI の哲学に「Single source of Truth（単一の真実の情報源）」があり、`@Binding` は、その「情報源」である `@State` への操作の窓口を提供しているだけです。

「でもそしたら、`inputText` が変わっても `outputText` の描画が更新されないのでは？」

この問題を理解するのは、次の話：`View` は何なのか？を理解すればわかるものです。

まず筆者含め、おそらく多くの人が `SwiftUI` の `View` は `class` ではなく `struct` であることに驚きを感じたはずかと思います。`struct` は値型であり、「オブジェクト」と言う考え方には当てはまらないですし、当然ながらライフサイクルも存在しません。代入操作がある時はすべての値がコピーされ[^cow]、`var b = a` の代入後に `b.p` を変更してもそれが `a.p` に反映されることは絶対にあり得ませんし、`a` の保持がなくなったら例え `b` の保持がまだ残っていても `a` のインスタンスが破棄されます。これは今まで参照型の `UIView` を使い慣れてきた我々 iOS エンジニアには大きなショックを与えたでしょう、何故なら今まで我々が当たり前のようにやってきた「ビューオブジェクトを参照して描画内容を変更」することが理屈上できなくなったのです。

[^cow]: 正確には Swift にはパフォーマンス最適化のために Copy-on-Write と言う仕組みがあって、値型でも代入時に値が即コピーされるわけではなく、変更を加えるときに初めて値がコピーされます。ここはその仕組みではなく、あくまでイメージがしやすいために敢えてこの表現を使いました。

実際も確かにそれができません。それでも SwiftUI がちゃんと描画できるのは、そもそも `View` はビューオブジェクトそのものではなく、ビューの描画レシピです。つまり「ここをこんな風に描画してね」の指示書に過ぎないのです。

そして、SwiftUI は非常に賢く、「この部分の描画に関わる情報が変わったら、この部分を再描画する」ことがわかっているのです。だから `@Binding` が全く必要なく、`LabelView` の描画に `inputText` の値が使われたから、`inputText` の値が変わったら `LabelView` を再描画する必要があることを、SwiftUI がわかっているのです：

```swift:MainView.swift
struct MainView: View {
    
    @State var inputText: String
    
    var body: some View {
        
        VStack {
            TextField("Text Input", text: $inputText)
            LabelView(outputText: inputText) // ←Binding していないので `$` も必要ありません
        }
        
        
    }
    
}
```

```swift:LabelView.swift
struct LabelView: View {
    
    let outputText: String // ←ここ `outputText` がそもそも変更することがないので `let` でいけちゃいます
    
    var body: some View {
        
        Text(outputText)
        
    }
    
}
```

無駄な `@Binding` をやめて、より簡潔で保守しやすいコードを書いていきましょう :muscle:
Tensorflow.jsの世界

TensorflowはニューラルネットによるAIを容易に作成できるライブラリだ。その中のJavascriptバージョンはインストール不要でWebページを開けるだけで動作する、GPUも自動的に活用できる環境だ。いままで作ったものの一覧は下。すべてプログラム付き。

https://randomwalkjapan.blogspot.com/2020/12/tensorflowjsthe-world-of-tensorflowjs.html

PoseNet 姿勢表示PostureAnalysis
FaceAPI 顔解析FaceAnalysis
BodyPix 体部分表示BodyAnalysis
ImageClassifier 話す画像分類
EasyPoC 概念検証ツールInstantProofOfConcept
StockPrediction 株価予測
TemperatureControl 温度管理
Interpolation 数値補間
YOLO 形状認識
MobileNet 話す形状分類
TeachableMachine手軽なAI教育

あそんでみてください！
Pepper SDK入門(22) Chatbotで実時間コミュ！

#Chatbotの正体に這い寄ろう！👽🐾
Chatbotはユーザの発話に対して何かしらPepperを反応させることが出来る機能で、リアルタイムのやり取りを可能にします。空中浮遊はできませんが、Pepperの首や手に動きをつけたり移動させたりすることもできます。
![k0045_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/b1757ead-f238-f5c8-78a3-11ba573be3b8.png)$\tiny{これはむり。}$
今回はChatを使用するので、[Chatの回](https://qiita.com/kskrin/items/ab6376fe27aaa613c362)も読み返してみてください。

#Chatbotマイスターになるために
使い方に応じていくつかのChatbotを統合することが出来ます。
例えば、次のような3つのChatbotを組み合わせて会話することも可能です。

* 小売の質問を管理するためのQiChatbot。店内のことなら庭レベルに把握している。
* 一般的な短いやりとりを管理するためのMicrosoft、IBM、GoogleなどWebベースのChatbot。挨拶上手。
* Wikipediaを管理するChatbot。Wikiが知ってることで知らないことはない。

~~Chatbotのキメラです🦁🐐🐍~~

#👉QiChatbot👉BaseChatbot
QiChat[^1]を利用したい場合はQiChatbotクラスを使い、外部のツールを利用したい場合はBaseChatbotクラスを拡張して独自のChatbotクラスを作成してください。

詳しくは双方ともに、今後の記事で説明します。
[^1]: QiSDKにあるスクリプト言語で、会話の内容を簡単に定義できます。

#空耳アワーへの先手⛅️👂
この章では、setMaxHypothesesPerUtteranceという少しマニアックなメソッドの使い方を見ていきたいと思います。

例えば「Hello Pepper」と言ったのを、Pepperが「Hello paper」と聞き取る可能性がありますね。真実はいつも一つですが間違いは無限の可能性を秘めています。
そこでChatbotは、そんな聞き取りミスをカバー出来るようになっているのです。音声認識の成功時にはいくつかの候補を取得できます。「こんばんは」の場合であれば、「こんばんわ」、「こんばんは」、「今晩は」などです。

Chatを実行中にPepperが音声認識すると、Chatbot.replyTo()が呼ばれ引数で音声認識の候補が渡されます。上記のように候補が複数の場合は、信頼度が高い2つの候補に絞ってChatbot.replyTo()が2回呼ばれることになります。(ChatbotがReplyPriority.NOMALの応答を返した場合、それ以降は呼ばれないと思われます。)

そしてここからが、setMaxHypothesesPerUtteranceメソッドの話です。基本的には使用されないのですが、このメソッドに値を設定するとChatbot.replyTo()の呼び出し回数を変更することが出来ます。
1にした場合は1つの候補に絞ってChatbot.replyTo()が1回呼ばれ、3にした場合は信頼度が高い3つの候補に絞ってChatbot.replyTo()が3回呼ばれるのです。

```java
Chatbot chatbot = new MyChatbot(qiContext);

//アクションをビルド
Chat chat = ChatBuilder.with(qiContext)
                       .withChatbot(qiChatbot, chatbot)
                       .build();

// アクションを非同期に実行
chat.async().run();
chatbot.setMaxHypothesesPerUtterance(3);
```

先出の例で言えば、数値を10にした時には「mallow vapor」や「allow neighbor」のように韻を踏んでも、Pepperにとっては「Hello Pepper」と挨拶されたことになるかもしれません。
以下の画面は<ins>[これ](https://github.com/aldebaran/qisdk-tutorials/tree/master/app/src/main/java/com/softbankrobotics/qisdktutorials/ui/tutorials)</ins>の"Mastering Chat locale"でsetMaxHypothesesPerUtteranceメソッドの値を変更し、台詞を変えてみたものです。
ここでは遠い恒星にいらっしゃる旧支配者クトゥグアを、ハム語の挨拶を引き金に召喚するようにしました。
![スクリーンショット 2021-01-05 12.25.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574697/c385fcfe-d5b9-1f44-3825-9acd87a37336.png)
setMaxHypothesesPerUtteranceメソッドに10を設定した時には、あうはーとかかるはーなどと言っても「はむはー」と言ったことになる、かなり緩い判定をします。
逆にsetMaxHypothesesPerUtteranceメソッドに1を設定した時には、明確に「はむはー」と発音しないと呪文を唱えてくれません。
よってジェットエンジンの傍らのように賑やかな場所では、１を設定することで多少誤認識が減る可能性があります。逆に、真夜中の郊外のように静かな場所ではデフォルトの2以上が推奨です。  
#あとがき
今回も例によって[PepperSDKforAndroid](https://android.aldebaran.com/sdk/doc/pepper-sdk/ch4_api/conversation/reference/chatbot.html)を参考に書かせていただきました。
さらに言羊しくは[ChatbotのAPIリファレンス](https://android.aldebaran.com/sdk/doc/javadoc/qisdk/com.aldebaran.qi.sdk.object.conversation/-chatbot/index.html)を参照してください🐏

次回はQiChatbotです。ワイヤレス充電の国際標準規格Qi(チー)の登場はありません。それでは〜:tada:
Smalltalk Zoo（Smalltalk処理系のオンライン＆インタラクティブな歴史資料館）の紹介

[Smalltalk Zoo](smalltalkzoo.thechm.org/) は CHM (コンピュータ歴史博物館）にホスティングされた、歴代の特に1970年代のSmalltalk環境をWebブラウザ内で動かすことで体験することができるWebアプリケーション＆関連資料集です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49275/3d27a872-e16a-2094-0524-66e45d68d8ee.png)

2020年12月17日付けの同館ブログで紹介されました。

- [Introducing the Smalltalk Zoo](https://computerhistory.org/blog/introducing-the-smalltalk-zoo-48-years-of-smalltalk-history-at-chm/)

目玉は Simulations 欄にリンクがある Smalltalk-72、Smalltalk-78、Smalltalk-80 という三世代の処理系およびその環境ですが（Smalltalk-80 は残念ながら本稿執筆時点では動かせないようです…→[ちょっと無理矢理ですが、なんとか動かす方法を書きました](https://qiita.com/sumim/items/5612addf90942a15e7c6)）、Papers 欄の論文や、Bootstrap Files 欄にある処理系起動時に読み込まれるそのバージョンの Smalltalk 自身で記述された基本的な定義が収められたファイル群なども是非参照してください。

このサイトからたどれる情報は、今年9月に開催されるはずだったACM（Association for Computing Machinery, 米計算機協会）のHistory of Programming Languages カンファレンス（通称HOPL IV）のためにダン・インガルス氏が書いた論文（Papers 欄にもリンクがある「The Evolution of Smalltalk from Smalltalk-72 through Squeak」）の背景資料を集めたものでもあるので、発案者であるアラン・ケイ氏から見た「[The Early History of Smalltalk](http://worrydream.com/EarlyHistoryOfSmalltalk/)」とはまたひと味違った実装者視点からの Smalltalk の変遷を記した同論文をよりよく理解するのにも大いに役立つことでしょう。

現在の Smalltalk（Smalltalk-80 の子孫）とはずいぶん違った仕組みで動く Smalltalk-72 については昨年いろいろ書きましたのでこちらもよろしかったら読んで遊んでみてください！

- [Smalltalk-72で学ぶOOPの原点 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/smalltalk-72)
PATHを通すについて

#PATHを通すとは
PATH（パス）を通すとしての意味合いは、『コマンドサーチパス』を使えるようにすると言うことです。
<b>コマンドサーチパス</b>とは、使いたい実行ファイルがどこにあるのか記入して置くことでファイル名だけで起動出来るようにしておくこと。
本来ならアプリを起動させるのにその実行ファイルが置いてある所まで、きちんと入力しないといけないのだが面倒くさいので手間省きましょと言う事みたい。
　

```
# bananaアプリを bananaコマンドだけで使えるようにしたい
% /usr/local/bin/banana       ←　　これで起動していたアプリを banana だけにしたい

% export PATH=$PATH:/usr/local/bin       ←　　PATHに場所登録

% source ~/.zshrc             ←　　設定の有効化    

% which banana                ←　　うまく出来たか確認

/usr/local/bin/banana         ←　　出来た！　
```
　


●　PATHを通すためのコマンド

```
% export PATH=$PATH:追加したいコマンド検索パス 
```
###export
export はつけないでもパスは通るようになるが、ターミナルを閉じてしまったら無効となってしまう。exportをつけて値を設定した場合は、<b>環境変数</b>となり引き続きの設定となる。
基本的にパスを通す時には、<b>export</b>はつけましょうという話。

###PATH　
PATH と言う<b>変数</b>に設定値を入れる。　今回、こいつに覚えて帰ってもらいたい。

```
% PATH="設定値"
```

###$PATH　とは　
$PATH　→　PATH変数にもともと入っていた情報。　今回、こいつの仲間になりたい。

```
% $PATH　　　　　← と入力すると自分の場合は下記出力
/Users/ユーザー名/.rbenv/shims:/Users/ユーザー名/.rbenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin
```

　
###設定を有効にする
```
% source ~/.zshrc　　　　　または    ~/.bash ,  ~/.bashrc 　などなど
```

###確認する方法
```
% echo $PATH　　　　　または　　whichコマンドを使う
```

<b>printenv</b>　→　現在有効な環境変数を全て表示するコマンド

```
% printenv
```
　
##PATHを消す
```
% unset PATH　　　　　　    ←　　PATHを消すコマンド
% set -e PATH 　　　　　　  ←　　設定
% echo $PATH              ←　　消えたか確認
```
また新たにPATHを設定し直すときは

```　
% PATH=追加したいコマンド検索パス　   →　PATHに値が入っていないので ＄PATH はいらない
```
　
　

##参考
https://reffect.co.jp/windows/full_understanding_mac
https://www.garunimo.com/program/linux/linux80.php
https://qiita.com/sta/items/63e1048025d1830d12fd
https://blog.ojisan.io/path-del-daijobu
=（イコール）打った後の""（ダブルクォーテーション）って遠くない？？？解決策は・・・

皆さんこんにちは！

今回は、テキストエディタで「VScode」を使っている方に是非見てもらいたい記事なので、もしよかったらご覧ください。

今は主にVue.jsを使ったサイト制作を行っているのですが、ふと、皆さんも「=打った後の""（ダブルクォーテーション）って遠いなぁ」と思ったことってありませんか？

例えば、if文の（===）打った時とか、、、

僕は(=)を打つたびに思っています。

今日はそんな方に必見！！！！！

簡単！！20秒で自分の好きなようにテキストをショートカットキーを設定！

もちろん、""（ダブルクォーテーション）だけでなく、p、a、imgタグなどのよく使う項目をショートカットに設定することもできます！初心者の方に限らず、色々な方々にも役立つと思うものでぜひ参考にして見て下さい！！！

モジュールのインストールもないので、気軽にご覧下さい。

それでは順を追って説明していきます。

#keybindigs.jsonを開く#

**「設定」（Macの方は基本設定？）→ 「キーボードショートカット」（Ctrl+K,Ctrl+S）**

![img1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/be899862-07f6-225a-833a-16997380fe2d.jpeg)


![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/bcf98e8b-9f4d-0841-3742-c8a1d9f4997e.png)

画像の矢印ボタンをクリックし、keybinding.jsonを開きます。

「Ctrl+K」を２回押し、自分の好きな組み合わせを設定してください。

今回は、＝を打った後にすぐそばにある「shift+0」を設定します。

そして、以下のように編集します。（textの部分に自分の好きなテキストを入れてください）

```keybindings.json
[
    {
        "key": "shift+0",
        "command": "type",
        "args": { "text": "\"\""},
        "when": "editorTextFocus"
    }
]
```

""はエスケープ文字「\（バックスラッシュ）」で表現します。

そして、VScodeを再起動してください。

ショートカットキーを押すと、表示されるはず、、、

何かエラーが起きた際には、気軽にコメントでご報告ください！

以上、「簡単！！20秒で自分の好きなようにテキストをショートカットキーを設定」でした！！！

良ければ、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

Thank you for reading
MicrosoftのRPA - Power Automate Desktop 12月アップデートについて

皆さんこんにちは、マイクロソフトの川端です。
2020年12月初旬に既にGA(一般公開)となりましたPower Automate Desktopですが、追加で12月のアップデート情報がありましたのでご紹介します。

参考：
12月10日（日本時間）[Power Automate Desktop GA発表の内容]
[Power Automate Desktop GA発表の内容]:https://qiita.com/YutoKa/items/a4aef2989642d4caf786

#1. はじめに
元の情報（英語）はこちらになります。
https://flow.microsoft.com/ja-jp/blog/power-automate-desktop-ga-release-update/

本内容はUIフローのインストールの際に確認できる下記バージョン(2.2.128.20340)での動作内容となります。
https://docs.microsoft.com/ja-jp/power-automate/ui-flows/setup
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/08b4633e-d26d-bad5-6f45-bea317bfcf1e.png)

既にPower Automate Desktopを導入済みの場合には、一度Power Automate Desktopを端末からアンインストールし、最新版のインストーラーでお試しいただければと思います。

#2. Power Automate Desktop(プレビュー版)の12月アップデート情報
###ポータル上からデスクトップフローの詳細(Power Automate Desktopの実行結果）が参照可能に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/45e1dfe9-9912-c96d-4855-da25c3ab3857.png)


###Power Automate Desktopの無料トライアルをデスクトップ環境から直接開始可能に

試用開始が直ちに可能となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/75d2737b-3287-0a52-9f4c-9bc9c4286673.png)
試用期間の残り日数も表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/eb141986-f355-67d1-d459-ca6096564638.png)

###クラウドフローからの機密データの文字列の受け渡しが可能に
セキュリティ上取り扱い注意なデータをクラウドフローからデスクトップフロー側に受け取るときに、暗号化された形で安全にデータを受け渡しすることが可能となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/788381c5-6d0f-fb84-e488-f344c79a8e2b.png)

###変数としてのパスワード入力が選択できるように
[Excelの起動]アクションを開くと、変数としてのパスワード入力ができるようになり、よりセキュアにパスワードデータを保持してデスクトップフローを構成することが可能となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/417a20ba-7d3c-cbaa-4c56-047cd347699d.png)

###ダイレクト機密テキストの入力が可能に
[Webオートメーション]>[Webフォーム入力]>[Webページ内のテキストフィールドに入力する]から、ダイレクト機密テキストの入力を指定し、直接Webページ内のテキストフィールドに入力することが可能となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/c8459f9a-95a9-cd05-fc56-00d0af07bd45.png)

デスクトップレコーダーを立ち上げている際に入力テキストを[機密テキスト]として指定することで、レコーダーからも直接機密テキストを保持して扱うこともできるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/db077c65-94b9-a053-d8f8-2b9d24a9bdb3.png)

###PDFに関係する新しいアクションが加わりました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/d1caef4d-7dfd-ff19-ee48-f0cb9a7ab6ac.png)

###条件のなかで新しい演算子を指定可能に
新たな演算子として[空である]、や[先頭（始まる文字列）]が加わり、より様々な条件設定を行えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/fde978ec-a5e7-422f-52b9-145ed1f8cb3a.png)

###タイムアウトを指定して待機アクションを設定することが可能に
[ファイルを待機します]アクション内で[タイムアウトエラーで失敗しました]のトグルをオンにすることで、指定期間に設定する動作が行われない場合には
エラーを返すようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/808554/490ee30c-f3cb-da2b-58db-911f159c41fa.png)


#3. まとめ
特に今回の内容では、機密データ、機密文字列を扱うためのセキュリティ関連のアップデートが多くなりました。
今月はGA(一般公開)内容の発表、月次のアップデートと合計2回の大きなアップデートが行われた月となりましたが、また新たなアップデートの更新にご期待ください！

Power Automate Desktopの[無料トライアルはこちら]
[無料トライアルはこちら]:https://flow.microsoft.com/ja-jp/robotic-process-automation/
SAMでEvent Bridgeを設定ファイルで記述する方法 [serverless.tsの場合]

記事がなかったのでメモ。

yamlだと[こちら](https://www.serverless.com/framework/docs/providers/aws/events/schedule/)の記事に書かれているようですが、テンプレートとして、aws-nodejs-typescriptを選択した場合、設定ファイルが、serverless.yml→serverless.tsになり、微妙に記述方法が違った経緯もあります。

eventsで配列を作って、eventBridgeを定義して、中にscheduleを追加して完了。
注意点として、scheduleで定義する時間は、UTCになるので要注意。

```typescript:serverless.ts
  functions: {
   functionName: {
      handler: 'handler.example',
      events: [
        {
          eventBridge: {
            schedule: 'cron(0 2 ? * TUE *)'
          }
        }
      ]
    }
  }
```
ビジュアルリグレッションテストをSlack通知するgithub actionを作ってみた

こんにちは[@glassmonkey](https://twitter.com/glassmonekey)です。

この記事は[GitHub Actions Advent Calendar 2020](https://qiita.com/advent-calendar/2020/github-actions)最終日の記事です。


みなさんクリスマスはいかがお過ごしだったでしょうか？
私はこの記事のネタのactionを作ることを忘れてて夜なべでつくりました。

わりと私自身の個人開発で使うことをメインに据えているので、機能など色々足りていないところは少しずつ足していけたらとは考えています。

# はじめに

今回はビジュアルリグレッションテストを行うGithub Actionを作ってみました。

[マーケットプレイス](https://github.com/marketplace/actions/image-regression-notification)にあげているので、興味がある方はご覧ください。

ソースコードも[glassmonkey/image-regression-notification](https://github.com/glassmonkey/image-regression-notification)に置いています。


実装の詳細に関しては過去の私が書いた[GitHub Pagesをビジュアルリグレッションテストをしてみた]
(https://qiita.com/glassmonkey/items/8002695c375284476a37)に詳細を記載しているので気が向いたらご覧ください。


# どんなactionか

下記のようにBASE_URLとCOMPARE_URLの２つのURLを与えてそのスクリーンショットを撮影し、
差分画像をSlackに投稿するActionです。


```yml

- uses: glassmonkey/image-regression-notification@v1.1
  with:
    BASE_URL: https://example.com
    COMPARE_URL: https://test.example.com
    SLACK_TOKEN: ${{ secrets.SLACK_TOKEN }}
    SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
    ENABLE_SHOW_DIFF: false
```

なお`SLACK_TOKEN`にはSlackのbotのトークンを指定します。
[files.upload](https://api.slack.com/methods/files.upload)を行う必要があるのでそれが可能なbotを作成していただく必要があるのでご注意ください。

# 例

実験で`https://ore-timer.xyz/`と変更差分を表す`https://stage-ore-timer.netlify.app/`での変更を比較してみます。（ページは私の個人開発のLPです）

![スクリーンショット 2020-12-25 12.12.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/68985d28-7f9d-f7bf-5f47-4455198a74d8.png)

h1テキストを`作業の集中を可視化`から`作業の集中を可視化します`と変更してみたのですが、
変更部分が赤い矩形で囲まれていることがわかります。

このような感じで、簡単に表示の変更影響がslackで確認できるようになります。

PRの際はローカルでdocker-composeなどでCI環境でホスティングしたページを`COMPARE_URL`に指定あげることで、PRに対応した差分検知に利用することもできます。

# 課題
Github Container Resistoryをチャレンジしようと思ったのですが、
時間の関係上断念しちゃいました。アクションの実行時間はこれで大幅に短縮できる見込みです。

スクリーンショットのサイズも柔軟にできるようにしようと思ってるので、ここも変更予定です。

# まとめ
画像回帰をslack通知するactionを追加してみました。とりあえず個人で使う分で色々やってみようかなという感じなのでフィードバックなどあったら嬉しく思います。
APIを使ってオンラインでビジネスパフォーマンスを高める方法

このブログ記事では、**API**を利用してオンラインでパフォーマンスを向上させる方法を紹介しています。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/gaining-an-api-advantage-for-your-business_595674)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

APIは今や、イノベーション、収益成長、生産性の向上を目指す企業にとって不可欠なツールとなっています。しかし、これらの利点を最大化するためには、洗練されたAPI戦略を実装する必要があります。

#APIとは？
APIはApplication Programming Interfaceの略です。これらのソフトウェアは、効果的に2つのアプリケーション間の安全なリンクを提供し、互いに話をすることを可能にします。その結果、新しいプログラムを書く必要があるたびにホイールを再発明する必要がなくなり、組織の時間とリソースを解放することができます。

その代わりに、開発者は新しいアプリケーションによる真のビジネス価値の創造に集中することができます。

API を使用してアプリケーションを強化しようとしている企業は、ビジネスパフォーマンスを向上させるために様々な要因を考慮する必要があります。

#メリットその1：統一性
API を最大限に活用したい場合は、デプロイメントのあらゆる側面で統一性を確保する必要があります。

これには、開発者が安心して API を使用できるようにするためのアーキテクチャの統一、効率的な通信を可能にするためのインターフェイス仕様の統一、すべてのタイプのリソース間の相互作用の統一、およびセキュリティに関する統一された姿勢が含まれます (これについては後述します)。

#メリットその2：自動化の重要性
自動化はAPIの管理に役立ち、さまざまなコネクタ、データベース、テスト、ファイルシステムをシームレスに動作させることができます。

当社の[API Gateway](https://www.alibabacloud.com/product/api-gateway?spm=a2c65.11461447.0.0.430c2a54kwcbs5)ホスティングサービスは、これを実現するためのさまざまな自動化ツールを提供します。APIの定義と公開、テスト、リリース、削除を提供します。APIとSDKの命令を生成することができ、無料で使用できる[OpenAPI Explorer](https://www.alibabacloud.com/products/openapiexplorer?spm=a2c65.11461447.0.0.430c2a54kwcbs5)サービスを介して可視化されたデバッグツールも提供しています。

#メリットその3：セキュリティの確保
APIは多くの企業にとって重要な役割を果たしていますが、そのようなツールがビジネスに脆弱性を持ち込むのではないかと懸念している企業も少なくありません。

当社のAPI Gatewayには、暗号化、認証、権限管理、アンチリプレイ、その他さまざまな防御オプションなど、さまざまなセキュリティオプションが標準で搭載されています。

さらに、当社の[アンチボットサービス](https://www.alibabacloud.com/products/antibot?spm=a2c65.11461447.0.0.430c2a54kwcbs5)は、APIやその他のWebアプリケーションにターゲットを絞ったセキュリティのもう一つの層を提供します。このサービスは、特定の脆弱性から保護し、エンドユーザーの体験に影響を与えることなく、自動化されたプログラム（クローラー）やその他の悪意のあるトラフィックを特定してフィルタリングします。

特に、このサービスは、チケットのひったくり、クレデンシャルのスタッフィング、インターフェイスの不正使用、スキャルピングなど、クローラーを使用する広範囲の潜在的な脅威から保護します。

#メリットその4：再利用性を可能にする
APIの再利用性は、他のビジネスにとって非常に価値のあるものとなります。当社のAPI Gatewayサービスはこの原理を利用しており、APIを中央のリポジトリでパートナーやクライアントに公開することができます。

また、当社のマーケットプレイスでAPIを公開することも可能で、他の企業がAPIを購入することも可能です。

#結論
API はどこにでもあり、私たちのオンライン生活に浸透し、私たちのつながりを維持するのに役立っています。APIを開発する際にビジネスの革新性と安全性を維持するためには、API戦略に統一性、自動化、セキュリティ、および再利用性を統合することが重要です。

アリババクラウドのAPI Gatewayには[こちら](https://www.alibabacloud.com/product/api-gateway?spm=a2c65.11461447.0.0.430c2a54kwcbs5)からアクセスできます。アリババクラウドの製品およびソリューションの詳細については、[https://www.alibabacloud.com/blog](https://www.alibabacloud.com/blog?spm=a2c65.11461447.0.0.430c2a54kwcbs5) を参照してください。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*
yaml個人メモ

```playbook.yml
--- #YAML開始
 - hosts: server_01
   tasks:
     - name: Ping Connection
       ping:

... #YAML終了
```

```
 - shell: cd aaa; cd bbb; cd ccc

#リテラルスタイル　|:改行を文字列として変換 -:最終行の改行コードを削除
 -shell: |-
  cd aaa
  cd bbb
  cd ccc
#折りたたみスタイル >:改行をスペースに変換 -:最終行の改行コードを削除
 -shell: >-
  cd aaa
  cd bbb
  cd ccc
 
```

プレイブック構成

```
---
#1play
 - host: all # Targetsセレクション：ターゲットノードの特定
   vars: # Varsセレクション：変数の設定
     xx: xx
   tasks: # Tasksセレクション：処理の定義
     - xx: xx
   handlers: # Handlersセレクション：実行制御処理
     - xx: xx

#1play
 - host: server_01
   tasks:
     - xx: xx
```
Flash Advent Calendar 25日目 - ありがとうFlashPlayer -

途中、何度も記事が遅延しましたが・・・
なんとか、`Flash Advent Calendar 2020`を走り切れました。
`swf2js`を作る事で多くの知識と経験が得られました。

10年たった今でもFlashPlayerより軽量で高速な描画エンジンは存在しないと思います。
Webの標準機能だけでは、まだFlashPlayerに追いついていないと思ってます。

ですが、そこは諦めずに試行錯誤してより良いものを作っていこうと思っています。
2021年からはJavaScript製FlashPlayer「swf2js」が引継ぎ
既存のコンテンツをこれまで通り配信できるようになりたいと思っています。

最終日ですので、色々と宣伝させて頂ければと思います。

# swf2jsとは？

SWFファイルをリアルタイムで分解・解読してCanvas(WebGL)に描画出力し
ActionScriptをVMでエミュレートする`JavaScript製FlashPlayer`です。
(なにげに、WebGLフル対応してます)

無料版の更新はすでに終了していますが、GitHubにはこれからも公開していきます。
[GitHub(swf2js/swf2js)](https://github.com/swf2js/swf2js)

有償版はSONICMOOVにてご相談を承ります。
[SONICMOOV](https://www.sonicmoov.com/)

無料版・有償版共にこちらのサイトでデモをお試し頂けます。
[swf2js web site](https://swf2js.com/)

# FlashLoverとは？

SONICMOOVとswf2jsが共同で制作しているFlashコンテンツのアーカイブサイトです。
このサイトにSWFファイルを投稿することで有償版のswf2jsを無料でご利用頂けます。
また、Adsenseの設置もできるように作っているので、ご自身の広告も配信可能です。

こちらは引き続きメンテナンスをこなっていくので、是非ご期待ください。
[FlashLover](https://flashlover.jp/)

# 次のプロジェクト

swf2jsで実装した描画エンジンを使って、もっと便利なアニメーションや開発が行えるツールを作ろうと思ってます。
こちらはいつ公開など未定です。
(自分でいうのもなんですが中々、いいプロジェクトだと思っているのでやりきたいと思います。)
[Next2D(仮)](https://github.com/Next2D)

# 最後に

記事を書いて頂いた @tkihira さん
自分の記事の内容への指摘や構成などサポートして頂いた @yoya さん
ありがとうございました！！:bow:

FlashPlayerは2020年12月でサポートを終了しますがAdobe Animateは今後も利用可能です。
優れたオーサリングツールとして、これから飛躍していくのを期待しています。

最後までFlash Advent Calendarをご覧頂き、ありがとうございました！！
Splunkサーバの中の不要なデータを見る（大掃除には最新のツールを使おう！）

さてさて、大掃除。
お風呂場の鏡は100均でダイヤモンドスポンジ買ってやったけど、ぜんぜんとれやしない。レモン汁をかけてラップで20分位浸してクエン酸でアルカリ成分を溶かすととれるらしいよ。やってみよう。油汚れは主婦の友人によると、アルカリ電解水がいいらしい。これ数年前に開発された製品で、小さいころ年末の親の換気扇掃除を手伝ってた僕にとっては「マジックリン」一択だったのにそこまで強力でなく手軽に使えるらしい。化学薬品企業の方も日夜たゆまぬ努力をされているんですね。ただ手袋はしたほうがいいそうです。

Splunkサーバの中にも、バックアップファイルとか古いログデータとかあるんですよね。試しに入れたAppの残骸とかね。基本的にAppは
/opt/splunk/etc/apps/ の下のディレクトリにあるので、不要なのは消してしまいましょう。
古いバージョンのtgzとかも眠ってたりしますね。

試しに入れたAppやインデックスってだんだんAppやユーザ増えてくるとわからなくなってくるので、そこはSplunkで表にしちゃいましょう。

| table title maxDataSize maxTotalDataSizeMB homePath tstatsHomePath
| sort count by maxTotalDataSizeMB

このちっこいファイルサイズのがテストで入れたAppだったりすので、消してサーバーちゃんの負荷を消して、綺麗にしてあげて、2021年に臨みましょう！

P.S. お風呂の黒カビ、あいつ撲滅したいんだけど、これも主婦によると、銀イオンで焚く？らしい。
カビキラーで一生懸命擦ってたんだけど、これでカビを絶滅できるだろうか。

常にSplunkのような「イイ」ツールの最新技術を使うって事は重要なんですね。


Happy Splunking!
djangoのモデルを特定の条件でソートする

# djangoのモデルを特定の条件でソートしたい
```models.py
class Tag(models.Model):
    # タグに振られるID
    tag_id = models.AutoField(primary_key=True, verbose_name='タグID')
    # タグの名前
    tag_name = models.CharField(max_length=20, verbose_name='タグ名')

    def __str__(self):
        return str(self.tag_name)

class IdeaTagMap(models.Model):
    ideatag_id = models.AutoField(primary_key=True, verbose_name='アイデアタグのID')
    # 紐づけられる投稿
    idea = models.ForeignKey(PostIdea, on_delete=models.CASCADE)
    # 紐づけられるタグ
    tag = models.ForeignKey(Tag, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.idea) + '_' + str(self.tag)
```

このようなモデルがあった時、Tagモデルは基本的に追加された順に表示されるが、その表示順をIdeaTagMapで参照された回数順に表示できるようにしたい。

方法としてはmodels.Managerを利用するのが一番早そう

```models.py
# TagManagerとして追加
class TagManager(models.Manager):
    # IdeaTagMapでそれぞれのタグが何回使われているかを表示し、多い順にソートする。
    def get_queryset(self):
        return super().get_queryset().annotate(
            ideatagmap_count= models.Count('ideatagmap')
        ).order_by('-ideatagmap_count')

class Tag(models.Model):
    tag_id = models.AutoField(primary_key=True, verbose_name='タグID')
    tag_name = models.CharField(max_length=20, verbose_name='タグ名')
    # 追加
    objects = TagManager()

    def __str__(self):
        return str(self.tag_name) + '(' + str(self.ideatagmap_count) + ')'

class IdeaTagMap(models.Model):
    ideatag_id = models.AutoField(primary_key=True, verbose_name='アイデアタグのID')
    # 紐づけられる投稿
    idea = models.ForeignKey(PostIdea, on_delete=models.CASCADE)
    # 紐づけられるタグ
    tag = models.ForeignKey(Tag, on_delete=models.CASCADE)

    def __str__(self):
        return str(self.idea) + '_' + str(self.tag)
```

このTagManagerを作成することで順番をソートすることができます。

参考画像
![スクリーンショット (13).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667059/52bfe8d0-8744-affe-2b58-feba9ea9db10.png)

# 考察、感想
トレンド機能などはこれらにさらに時間軸の設定も行っていると考えられるので、もっと勉強して実装できるようにしたい
EC2 R5インスタンスにEBSをアタッチするときにはまった話

## EBSをEC2にアタッチしたい
アタッチしたはずのEBSがアタッチされてない。なぜ。

## CloudFormationを見直してみた
#### 修正前

```yaml
Type: AWS::EC2::Instance
Metadata:
  AWS::CloudFormation::Init:
	configSets:
		mountebs:
			- "01_set_ebs_volume"
			- "02_mount_ebs_volume"
	01_set_ebs_volume:
	  commands: 
		01mkdir_data:
		  command: "mkdir /data"
		02mkfs:
		  command: "mkfs -t ext4 /dev/xvdf"
		03vi_fstab:
		  command: "echo \"/dev/xvdf	/data	ext4 defaults,discard 0 0\" >> /etc/fstab"
	02_mount_ebs_volume:
	  commands:
		01mount_ebs:
		  command: "mount -a"
```
あやしそうなのは`mkfs -t ext4 /dev/xvdf`かなと思いドキュメントを確認してみました。


> EBS ボリュームは、Nitro システム上に構築されたインスタンスで NVMe ブロックデバイスとして公開されます。デバイス名は、/dev/nvme0n1、/dev/nvme1n1 などです。ブロックデバイスマッピングで指定したデバイス名は、NVMe デバイス名 (/dev/nvme[0-26]n1) を使用して名称変更されます。

▶ [Linux インスタンスの Amazon EBS および NVMe - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html)

なるほど。


>以下のインスタンスが Nitro System に基づいています。
仮想化: A1、C5、C5a、C5ad、C5d、C5n、C6g、C6gd、G4、I3en、Inf1、M5、M5a、M5ad、M5d、M5dn、M5n、M6g、M6gd、p3dn.24xlarge、R5、R5a、R5ad、R5d、R5dn、R5n、R6g、R6gd、T3、T3a、z1d

▶ [インスタンスタイプ - Amazon Elastic Compute Cloud](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances)

なるほど。なるほど。


#### 修正後

```yaml
Type: AWS::EC2::Instance
Metadata:
  AWS::CloudFormation::Init:
	configSets:
		mountebs:
			- "01_set_ebs_volume"
			- "02_mount_ebs_volume"
	01_set_ebs_volume:
	  commands: 
		01mkdir_data:
		  command: "mkdir /data"
		02mkfs:
		  command: "mkfs -t ext4 /dev/nvme1n1"
		03vi_fstab:
		  command: "echo \"/dev/nvme1n1	/data	ext4 defaults,discard 0 0\" >> /etc/fstab"
	02_mount_ebs_volume:
	  commands:
		01mount_ebs:
		  command: "mount -a"
```

ドキュメントにある通り`/dev/xvdf`を`/dev/nvme1n1`に変更したところアタッチできました。
 
 ドキュメントはちゃんと読まないとダメですね、、