OmniAICreator/Qiita-1.07M huggingface dataset:
AOPのロギングのクラス名を各AOP対象のクラス名にする

## 色々考えたが難しかった
* 事前にBeanに"Logger"を付加したロガーを作って登録しておこうかと思ったが、調べるのに時間が掛かりそう。
* PostBeanProcessorにて、Beanは作れない。

## 今の所の実装
1. AOP時に`Bean名+"Logger"`のロガーをmapにキャッシュ。
2. 二回目以降、これを使う

## 
```java
package com.example.aop;

import lombok.AllArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
@AllArgsConstructor
public class MethodStartEndAspect {
    private final Map<String, Logger> map = new HashMap<>();

    @Before("execution(* com.example..*(..))")
    public void start(JoinPoint joinPoint) {
        String loggerName = joinPoint.getSignature().getDeclaringType().getSimpleName();
        Logger logger;
        if (map.containsKey(loggerName)) {
            logger = map.get(loggerName);
        } else {
            logger = LoggerFactory.getLogger(joinPoint.getSignature().getDeclaringType().getSimpleName());
            map.put(loggerName, logger);
        }

        logger.info("START {}#{}", joinPoint.getSignature().getDeclaringType().getName(), joinPoint.getSignature().getName());
    }

    @After("execution(* com.example..*(..))")
    public void end(JoinPoint joinPoint) {
        String loggerName = joinPoint.getSignature().getDeclaringType().getSimpleName();
        Logger logger = map.get(loggerName);
        logger.info("END {}#{}", joinPoint.getSignature().getDeclaringType().getName(), joinPoint.getSignature().getName());
    }

}
```
Reactでnpm ERR! code E404が出た時の対処方法

# Reactでnpx create-react-app コマンドを使用した際に出たエラー

```
コード[ 'creat-react-app@latest' ]で1のインストールに失敗しました
```

# 解決方法

む、よくみるとおかしい・・・

ダメ絶対！

```
creat-react-app
```

◎

```
create-react-app
```

createはeをチャントつけること・・・。
今回は1分で解決。

でも忘れないように投稿しとく。
Javascript基礎知識＃6（while文）

##はじめに
この記事は私の脱コピペを目指すために書いている自分用のメモです。

※内容について、誤った知識やもっとわかりやすい表現等ございましたら、ご指摘いただけますと幸いです。

##目次
1. while文とは
2. while文の書き方
3. while文の例

#1. while文とは
while 文では「（）」の中に記述した条件式が true を返すあいだ、繰り返し処理を行う

#2. while文の書き方
while文の基本形は下記のような感じです。

```javascript
while(条件式) {
  //繰り返す処理を書く
}
```

#3. while文の例
```javascript
let num = 3;
while(num < 100) {
  console.log(num);
  num = num * 3;
}
console.log('end');
```
```javascript
>> 3
>> 9
>> 27
>> 81
>> end
```

こんな感じ。
STM32 nucleoを使う (1)

STM32 nucleoは、STマイクロエレクトロニクスが販売しているSTM32のマイコン評価ボードです。
nucleoを使うために、開発環境としてSTM32CubeIDEのインストールするまで記載します。

# STM32 nucleoについて
nucleoボードは、STM32にArduinoコネクタとST. Morphoヘッダが付いています。
電源はUSBから供給されます。ST-Link内蔵のためPCとUSBで接続するだけで開発ができます。

nucleoボードというかSTM32は種類が多いので目的にあったものを選ぶのが大事です。
プロトタイプとして使うのであれば、CPU性能、メモリサイズ、低消費電力対応、内蔵ペリフェラルなどを考慮しますが、学習で使うのであればCPU性能、メモリサイズと値段から選ぶと良いと思います。

今回は汎用的に使いたいので、CPUクロックとメモリサイズ、それと値段でSTM32F303REを選びました。秋月電子で1600円でした。
STM32F303REは

- ARM Cortex-M4コア
- 周波数：最大72MHz
- Flashメモリ：512KB
- SRAM：80KB
- ADC：12bit x 4ch
- タイマー：10ch
- USART：5ch
- USB2.0：1ch
- CAN：1ch

ととても豪勢なマイコンです。
これにデバッガまでついて1600円で買えるとは、素晴らしいですね。

では使っていきましょう。

# STM32CubeIDEのインストール

開発環境にはmbedの他にEclipseベースのSW4STM32がありますが、今回はSTM32CubeIDEにしました。
インストールしたのはWindows10です。

こちらからインストーラーをダウンロードします。
https://www.st.com/ja/development-tools/stm32cubeide.html

ダウンロードしたインストーラーを実行します。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68712/b05966b2-2bdc-0de3-3eea-9da37108ae83.png)
インストール先を選択
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68712/c16c0350-a47a-8736-180e-392dc2a7b943.png)

コンポーネントを選択
デフォルトのままでOK。Installボタンを押すとインストールが始まります。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68712/53e8d438-d02c-b9e2-b36f-f248c7c0db6e.png)

しばし待ちます。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68712/954520a7-7723-d5a9-d473-a5b0b2b5f7b0.png)

完了です
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68712/f30e804b-f923-bb2e-c177-b8f00a786f24.png)

起動するとworkspaceを聞かれるので、場所を設定します。
（Use this as the default and do not ask againにチェックを入れなけば、起動時に毎回聞かれます）
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68712/07f8febf-ad64-3f3a-0bf3-d3cffc55b944.png)

Home画面が表示されればOKです。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68712/d1c3fa33-5655-8676-db74-7eccefda1a61.png)

この後はボード上のSWとLEDを使って簡単なプログラムを動かしてみます。
古のバージョンのMastodonからはBotフラグがついたアカウントを認知できない、そう、Qiitadonとかからな！

# Botフラグとは

わりと昔から(v2.4.0)「これはBOTアカウントです」というフラグが存在している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94177/31852e3b-061a-97ff-98f8-fb676146fc84.png)

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94177/47f4a8a8-e8a8-da6a-aa38-5e687beefbfc.png)](https://qiitadon.com/@KEINOS/105212003392930468)


ref: https://docs.joinmastodon.org/entities/account/#bot

MastodonのUIからは次のように確認できる。

![Bot](https://docs.joinmastodon.org/assets/image%20%281%29.png)
CC BY-SA 4.0 https://docs.joinmastodon.org/user/profile/

# 古のバージョンのMastodonからはBotフラグがついていると認知できない

2.4.0よりもさらに古いMastodonが動いているインスタンスでは、このBotフラグがついているとアカウントと認識できない。そう、**[Qiitadon](https://qiitadon.com)とかからな！**

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94177/e1f9d914-6aff-d5f5-0fcb-293d0946d30d.png)](https://qiitadon.com/@yumetodo/105211965077641841)


アカウント名は通常リンクになるが、ただの文字列として扱われる。

Botフラグを外すことで認知できるようになる。
Git LFSで特定コミット時点のファイルを別名で保存する

`git lfs checkout`の`--to`オプションが使えそうと思ったけどコンフリクトしていない状態だと使えなかった。
https://github.com/git-lfs/git-lfs/blob/master/docs/man/git-lfs-checkout.1.ronn

❌ダメな例:

```console
$ git lfs checkout --base --to=tmp.png -- file.png
Could not checkout (are you not in the middle of a merge?): Git can't resolve ref: ":1:file.png"
```

LFSじゃない通常のファイルは `git show <commit>:<file>` でできる（参考: https://qiita.com/rbtnn/items/394178862e0a053dfb46 ）けどLFSのファイルだとポインタの内容が表示されるだけ。

例：

```console
$ git show HEAD:file.png
version https://git-lfs.github.com/spec/v1
oid sha256:hogehogehogehoge
size 1234
```

✅`git lfs smudge`でポインタ情報から実体にしてくれるので、パイプしてやればいいだけだった。
https://github.com/git-lfs/git-lfs/blob/master/docs/man/git-lfs-smudge.1.ronn

```console
git show HEAD:file.png | git lfs smudge > tmp.png
```

みたいな感じでお目当てのファイル実体を別名で保存することができた :tada:
初めてのGithub

macでGithubをとりあえず使ってみました。

#Githubアカウント作成
所要時間：１０分

#Qiitaアカウント作成
所要時間：１０分
Githubのアカウント情報を使用するみたいなのを選んだらサクサク登録できた。

ここからはこちらの記事を参考に。
[【GitHub超初心者入門】この前初めてGitHubを使い始めたエンジニア見習いが書くGitHubの使い方と実践～とりあえず一緒に動かしてみようぜ！～](https://qiita.com/nnahito/items/565f8755e70c51532459)

#Githubローカルレポジトリ作成
所要時間：90分

ターミナルを開いて以下のコマンドを入力

```
$ mkdir github
$ cd github
$ mkdir gittest
$ cd gittest   
$ git init
```

テキストファイル作成

LaunchPadからテキストエディットを開き中身作成。
![スクリーンショット 2020-11-19 16.06.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880733/2b840312-114d-132b-de8f-7afd1771be0b.png)


作成したローカルレポジトリgittestにテキストファイルをアップロード
MacのFinderを開いた状態でcmd+shift+Gを押す
入力スペースに「~/git」と入力しEnter→移動
テキストファイルtestを移動させる

新規作成

```
$ git add test.txt
```

ローカルレポジトリに登録（コミット）

```
$ git commit -m '初めてのGithub'
```
#Githubにデータを送信

インデックスをGithubに作成

```
$ git remote add origin https://github.com/"user-name"/HelloGit.git
```

コミットされたデータをGithubに送信(プッシュ)

```
$ git push origin master
```
データが登録されました。

![スクリーンショット 2020-11-19 16.03.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880733/e0b5e43f-0e0b-567e-d202-09c12d4856d5.png)

#プッシュしたデータの更新/変更

testを編集する
![スクリーンショット 2020-11-19 16.08.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880733/f2dffcb1-1ff5-50fd-361f-5dd8367172c1.png)

変更をインデックスに追加

```
$ git add test.txt
```
ローカルレポジトリにファイルを登録(コミット)

```
$ git commit -m '変更'
```
コミットされたデータをGithubに送信(プッシュ)
```
$ git push origin master
```
更新されました。
![スクリーンショット 2020-11-19 16.13.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880733/3f49d017-e30a-bdb4-6fbc-7b81e0ac9bbc.png)

#ブランチ(コピー)を作る

```

$ git branch testbranch
```
testbranchという名前のブランチができる

```

$ git branch
```
で確認するとできている

「*」がついている方にデータが参照・書き込みされるので、今のままだと「master」に書き込みされてしまう

なので

```

$ git checkout testbranch
```
で書き込み先をスイッチ


#手間取ったところ
1. 途中から下記のような「xcrun error」が表示されるようになる

`crun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
`

+ 対処

```
$ xcode-select --install
```
2. ポップアップで出てくるコマンドライン・デベロッパーツールをインストールする(1時間くらいかかる)。

+ コマンドを入力すると`dquote>`と表示され次のコマンドを入力できない



+ 対処
クオーテーションの終わりがないのが原因。
cntl+Cで終了させる。

3. 共通鍵？のエラーでプッシュできない

+ 対処
リモートレポジトリとローカルレポジトリを削除してやり直す
さくらのクラウドでストレージボリュームをアタッチしてマウントするまで


前回に引き続き、｢さくらのクラウド｣でも調査したのでまとめておく。

##さくらのクラウドのコンパネでの作業
###サーバを追加
CentOS7.8を選択
パスワード：(メモしておく)
ホスト名：abc123(今回、テストのため適当)
IP：(メモしておく)

##ターミナルでの作業
###SSHログイン
```
ssh root@***.***.***.***
```
###ディスクの利用状況を確認
```
# df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置  
devtmpfs         481M     0  481M    0% /dev
tmpfs            496M     0  496M    0% /dev/shm      
tmpfs            496M  6.7M  489M    2% /run
tmpfs            496M     0  496M    0% /sys/fs/cgroup
/dev/vda3         16G  2.5G   13G   17% /
tmpfs            100M     0  100M    0% /run/user/0
```
##さくらのクラウドのコンパネに戻る
###ストレージの増設
ストレージ-ディスクで｢追加｣を選択
起動中のサーバは接続先に選択できない（先に停止しておく）
名前：st-abc123
###アタッチ
｢接続先サーバ｣を選択したので、自動的にアタッチされる
###サーバーを起動

##ターミナルに戻る
###確認
```
# fdisk -l
・・・
Disk /dev/vdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト
```
###フォーマット
```
# mkfs.ext4 /dev/vdb
```
###マウント
```
# mount /dev/vdb /strage/
```
###ディスクの利用状況を確認
```
# df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         481M     0  481M    0% /dev
tmpfs            496M     0  496M    0% /dev/shm
tmpfs            496M  6.7M  489M    2% /run
tmpfs            496M     0  496M    0% /sys/fs/cgroup
/dev/vda3         16G  2.5G   13G   17% /
tmpfs            100M     0  100M    0% /run/user/0
/dev/vdb          20G   45M   19G    1% /strage
```
出来てる。
本作業時には以下のコマンドでサーバー起動時に自動マウントされるようにする。

```
# vi /etc/fstab
```
今回は略。
###コンパネでサーバーを停止、サーバーとストレージを削除

以上！
Javascript基礎知識＃5（for文）

##はじめに
この記事は私の脱コピペを目指すために書いている自分用のメモです。

※内容について、誤った知識やもっとわかりやすい表現等ございましたら、ご指摘いただけますと幸いです。

##目次
1. 繰り返し処理とは
2. for文とは
3. for文の書き方
4. for文の例
5. 配列を使った繰り返し処理
6. continue
7. break



#1. 繰り返し処理とは
同じ処理を何回か繰り返したいときに使う処理。

繰り返し処理を使えば何回も同じコードを書かなくて済む。

#2. for文とは 
**決められた回数だけ**処理を繰り返す場合に使用します。
事前にどんな処理を何回繰り返すのかを決めておくのが一般的です。

#3. for文の書き方
for文の基本形は下記のような感じです。

```javascript
for ( カウンタ変数定義と初期化; 繰り返し回数の指定; カウンタ加算幅) {
  // 繰り返す処理を書く
}
```
for文は、3つの引数を与えてあげるのが一般的です。

**1. カウンタ変数定義と初期化**
今何回目の処理かをカウントするための変数定義。
i=0で初期化してね。

**2. 繰り返し回数の指定**
何回処理したいかを指定する。

**3. カウンタ加算幅**
i++と書くと、カウンタを1つづつ加算するという意味になる。

#4. for文の例

```javascript
for(let i = 0; i < 3; i++) {
  document.write('for文だよ');
}
```
```javascript:結果
>> for文だよ
>> for文だよ
>> for文だよ
```

#5. 配列を使った繰り返し処理

配列についての記事はこちら

forを使わないで配列の要素をすべて表示すると

```javascript
let lists = ['山田', '伊藤', '佐藤', '鈴木'];

console.log ( lists[0] );
console.log ( lists[1] );
console.log ( lists[2] );
console.log ( lists[3] );
```

```javascript:結果
1. 山田
2. 伊藤
3. 佐藤
4. 鈴木
```
console.log()を使って表示していますが、同じ処理を6回も繰り返して面倒臭いです。
保守性も低いです。

for文を使うと、、、

```javascript
let lists = ['山田', '伊藤', '佐藤', '鈴木'];

for(let i = 0; i < lists.length; i++) {
  console.log( lists[i] );
}
```

```javascript:結果
1. 山田
2. 伊藤
3. 佐藤
4. 鈴木
```
文が短いし、見やすいです。

#6.continue: 特定のタイミングだけ処理を実行

continueを使うと、繰り返し処理の最中に特定のタイミングだけ処理を実行させないようにできる

for文を使って奇数だけを表示するよ

```javascript
for(let i = 0; i > 10; i++) {
  if(i % 2 === 0) continue; //偶数(2で割れるとき)だけ処理しない
  console.log(i);
}
```
```javascript:結果
1
3
5
7
9
```

#7.break: 途中で処理を中断する
breakを使うと、繰り返しの途中で処理を中断できる

```javascript
for(let i = 0; i > 10; i++) {
  if(i === 7) break; //7以降は中断
  console.log(i);
}
```
```javascript:結果
1
2
3
4
5
6
```

こんな感じ。
border-bottomを使わず文字の下にマーカーを引いた様に見せる

## ■ はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ cssの基礎知識が増える
・ `background`,`linear-gradient`プロパティについて

## ■ メモ

[isara](https://isara.life/)

![isara先輩.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/81002e10-b977-b87d-ffa4-d5c6e6ae8709.png)

`border-bottom`では文字と離れすぎてしまったり、`position`を使いたくない時に使えます
<font color="red">20/11/21(土)追記：</font>普通に線引くなら`text-decoration: underline;`


```scss:index.scss
span {
  font-weight: bold;
  background: linear-gradient(transparent 70%, #ebb94d 70%);
}
```

・ お役立ちリンク
→ [CSSのグラデーション（linear-gradient）の使い方を総まとめ！](https://saruwakakun.com/html-css/basic/linear-radial-gradient)
Visual Stduio for Macを更新しようとしたらエラーが出た

# 現象

Visual Studio for Mac 2019をバージョン8.8にアップデートしようとしたらエラーが出ました。

![スクリーンショット 2020-11-14 10.48.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/7a8f8ab9-548c-e2d4-0b66-9a83fbee515f.png)

「再起動して更新プログラムをインストールする」をクリックすると。。。
![スクリーンショット 2020-11-14 10.48.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/64dad5f9-cddc-3dc8-f43b-e7b3d18b2342.png)

「Failed to attach disk image」だそうです。

# 対処

以下を参考に手動でアップデートしました。
https://developercommunity.visualstudio.com/content/problem/839059/installing-vs-failed-to-attach-dmg-image.html

更新プログラムのダウンロードが済んでいれば`~/Library/Caches/VisualStudio/8.0/TempDownload`にインストーラーがダウンロードされているので実行します。
![スクリーンショット_2020-11-14_10_55_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/da91f350-2df7-4a21-5e77-c66401c0f69e.png)

しばらくすると以下のウインドウが出てくるので、Visual Studio.appをApplicationsにドラックアンドドロップします。
![スクリーンショット_2020-11-14_10_52_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/4223c2bf-b8ac-0625-23ff-093650b5fe24.png)

バージョンアップできました。
![スクリーンショット 2020-11-14 11.30.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342629/4602138e-4a51-b96a-8e15-98d8965ed9e8.png)

結局、再インストールと同じ気がしますが、とりあえず使えるようになります。
アイデアをシームレスに実装する - 考える道具としてのNode-RED - 

# はじめに
Node-REDが手になじんでしまうと手放せなくなります。Node-REDの開発はもちろんのこと、過去の経緯でほかの言語で開発する際にも設計の確認で使うこともあります。なぜ、こんなに手になじんで、ちょこちょこっと始められるのか考えてみました。
# シームレス
ソフトウェア開発でシームレスという言葉を最初に聞いたのは、オブジェクト指向分析が話題になった時でした。
1980年代に話題になった構造化分析/設計では、データフロー図で分析したモデルをプログラムの構造図にする際に、中心となる処理を引っ張り上げて機能モジュール間に無理やり上下関係を持たせるなどしていました。工程間でモデルが異なることで分析(What)と設計(How)で溝ができ、あと戻りが難しい開発方法でした。
オブジェクト指向分析は、分析と設計で同じモデルを用いることで、分析と設計がシームレスに移行できるという点が売りの一つでした。オブジェクト指向設計は実装への移行も容易でした。安定したクラス構造が見つかれば、全行程の作業をシームレスにできました。
「データは機能より安定している」という意見もあるようですが、作業のきっかけとしてはすぐれているもののデータだけを考えていてもなかなかアイデアはまとまりません。システムにはどのような機能が必要で、どんな順序で処理するか、その中でデータはどのように扱われるか、それらを総合的に考えなければ、イメージを固めて、実現可能性を確認することはできません。

#問い
　新しいシステムのアイデアが思い浮かんだとき、あなたはどんなメモを書くでしょうか？
#よくある答え
　スマホがあって、サーバーがあって、対象データを保存して、他のユーザや機器が参照するそんなイメージでしょうか。スマホからサーバーへ認証情報を送ると、現在の状態が示されて、スマホのUIで入力した情報がサーバに送られる。業務フロー、シーケンス図、ユースケース図、ユーザーストーリ、そんな感じの記法で書きませんか？
　さて、実現可能性を確認したいので少し実装を考えだすと、データを洗い出してクラスを考え出すのでしょうか。全体のイメージができているならそれも可能でしょう。でも新しい業務なら画面遷移も考えたいのでペーパープロトタイピングで画面遷移を考えて、これが抜けていたとか、この情報が最初にいる、などと間違いに気づいて、データ構造が徐々に安定していくでしょう。
　このように、業務フローやシーケンス図から開発が始まり、システムへの理解が段階的に進みます。
#Node-REDなら
　業務フローやシーケンス図を描き始めたタイミングで実装を始められます。
「いやいや、そんなことはないでしょう」そう思われるのも無理はありません。しかし、簡単にできてしまいます。
　スマホから呼び出されるAPIをひとまず作成してグローバルデータを返すようにします。これにはhttp inノードとhttp responseノード、データの取り出しにチェンジノードがあれば良いので3ノードでできます。グローバルには何か入れておかないといけないのでJSONで設定したデータを起動時にセットします。起動時のタイミングをインジェクトノートで出力し、テンプレートノードにJSONで設定、チェンジノードでグローバルに入れるようにします。これでサーバ側の実装は終わりです。合計6ノードでできてしまいます。
　画面遷移を確認する場合は、簡単にWeb画面が作成できるDashboardを使ってスマホのテスト画面が作れます。一覧の画面を作ると、意外な勘違いがが見つかったりします。
#データ構造は後から考えても良い
　上の問いへの別解で、型のゆるい言語、あるいは抽象度の高いクラスを使っていきなり実装を始めるという方もおられるでしょう。機能間のインタフェースを明確にしないことで、処理に集中できます。
Node-REDはノードと呼ばれるモジュールの入出力はmsgオブジェクトに統一されています。まずはmsgがどのような順で、どのように流れるかを考えることができます。実装を進めていく中で不足する属性があれば、上流のどこかで準備します。どこで準備するかを考えることが、どのように処理するかを考えることになります。
　もちろん、わかっているデータ構造はあらかじめ実装して構いませんし、プログラムが大きくなるなら早めにデータ構造を考える方が良いでしょう。できたつもりで進めていって、問題が出てくれば追加すればよいのです。
#データストレージも後から考える
　とはいえ、データベースなどのデータストレージはよく考えないといけないので、アイデアを確認する際の障壁になりがちです。まずは別にサーバーを立てないことで、容易に始めることができます。
　もっとも簡単な方法がグローバル変数もしくは（タブ内で参照可能な）フロー変数の利用です。javascriptのオブジェクトを保存できますので、属性名で疑似ハッシュとして用いることができます。使ってはいけない属性名があることと、メモリの消費に注意すれば便利に用いることができます。グローバル変数やフロー変数はコンテキストデータのメニューから参照や削除ができますので、意外と便利です。
　少し複雑な検索もしたいのであれば、SQLiteやNeDBが簡単です。RDBやドキュメントDBのようなことができますので、ひとまず動かして考えるのには便利です。ある程度システムの全貌が見えてきて複雑な検索やサーバー間でデータ共有を検討する際にサーバーを立てると良いでしょう。
#どこまでシームレスに使えるか
　とりあえず動くようになってから仕様を徐々に固めます。機能拡張やDBなどストレージの確保をすると、徐々に本格的なシステムになるでしょう。Node-REDは実運用で使われている例も多いので、品質保証をすれば、そのまま本番に使うことも可能でしょう。ただし、Node-RED単体では冗長化やアプリ間のデータ共有の仕組みはないので、外付けする必要があります。
　あとは開発規模の問題です。Node-REDは高機能なモジュール（ノード）が多いので、あまり大きくならないかもしれません。しかし、アイデアを整理する際のデータ構造を元に始めると、処理の都合で似て非なる属性がどんどん増えることがあります。これは危険な兆候です。「どうだっけ」と少しでも不安に感じたら、データ構造を見直してください（[プロのためのNode-RED再入門](http://sakaba.cocolog-nifty.com/sakaba/2018/03/node-red-46bb.html)）。
#おわりに
　Node-REDの手になじむ感じを整理してみました。他にもいろいろ特徴があるので、ぜひ使いこなしてください。
AWSのVPCのよく使われるコンポーネントについて

## 勉強前イメージ

一応VPCは作って中にインスタンス作れるけど、あんまりちゃんとネットワーク上こう、っては分かってない
特によく使われるやつでもインターネットゲートウェイはあんまり分かってない
今回はちょっだけにしとく。

## 調査

### Subnet

VPCの中に小さなネットワークの集まりを作れるもの。
Subnetでネットワーク空間を区切ります。

下記の例であれば `10.0.0.0/8` という大きなVPCの中に
ネットワークに接続しない、 `10.1.0.0/16` というPrivate Subnetと
ネットワークに接続する、 `10.2.0.0/16` というPublic Subnetが作成されています。
※subnetはかぶってはだめです。

![subnetUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/28774a70-b47d-3be3-f484-eb885f0290ba.png)


### Internet gateway

Internet gatewayは `Static NAT` 、つまりプライベートIPとパブリックIPを1対1で変換します。
以下の図のように、 `10.2.1.1` を `100.100.100.100` に変換してインターネットから出す役割をします。 
インターネットに接続するには必要なコンポーネントです。


![internetgatewayUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/187af945-ab07-ac77-d32b-04ec6af7f90d.png)


### NAT gateway

NAT Gatewayは `Dynamic NAPT` 、 つまりプライベートIPとパブリックIPを多対1で変換します。
複数のインスタンスからの通信が、プライベートIPでNAT gatewayを通過する際、1つのパブリックIPに変換されます。
複数のプライベートIPで1つのパブリックIPに変換してしまうと戻りの通信がわからなくなるので、ポート番号も変換することで正しい通信ができるようになっています。

![natgatewayUntitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/1b908a0b-228b-cc23-f320-52113e6a4d1b.png)

## 勉強後イメージ

基本的にデフォルトのVPCしか使ってなかったからあんまり意識したことなかったかも...
ここちゃんと1回自分でも設定してみたい。

## 参考

- [AWS入門者向け 初心者が最初に理解すべきEC2とVPCの基本的な用語解説](https://avinton.com/academy/aws/)
- [【初心者向け】初めて VPC 環境作成してみた](https://dev.classmethod.jp/articles/myfirstnvpcsetup/)
- [[AKIBA.AWS] VPCをネットワーク図で理解してみる](https://www.slideshare.net/skikuchi/akibaaws-vpc)
- [【図解/AWS】インターネットGWとNAT-GWの違い〜各メリット、パブリックサブネットとは〜](https://milestone-of-se.nesuke.com/sv-advanced/aws/internet-nat-gateway/)
- [NAT Gatewayによるアクセス元IPアドレスの固定](https://dev.classmethod.jp/articles/fix-sender-ip-address-with-nat-gateway/)
SlackはRTMをサポートしなくなるようです

# Slack は RTM をサポートしなくなるようです

先日、slackbotでを新しくBotを作成しようとした際に

動かず困ったので調べてみたところ、SlackはRTMのサポートを終了する ということが判明しました。

現状の回避策と、詳細をまとめてみることにします。

## slackbotを使ったBotの作成

[GitHub - slackbot](https://github.com/lins05/slackbot)

pipパッケージで、簡単に使えるBotフレームワークです。

利用している人も多く見かけます。

> Based on slack Real Time Messaging API

`slackbot` はRTM APIを利用してBotを比較的簡単に実装できるように作られています。

## 新しく作成したApp Tokenでは、どうやらslackbotが動かないぞ

新しくSlack Botを作成しようとして、環境を構築しましたが

``` shell
slacker.Error: missing_scope
```

👆のエラーで異変に気付きました。

### Scope を修正してみた

[Slack API - Your Apps](https://api.slack.com/apps/) から、該当のAppを選択し

`OAuth & Permissions` の項目から `Scope` を確認しました。

以前は、Scopesを定義しなくても `Bot Token` を利用することで

自動的にBot向けのScopeが内部で承認されていました。

しかし、必要なScopeを追加してもエラーは発生し続けました。

#### 余談

slackbot側を調べてみました。

```Python
def start(self, simple_latest=False, no_unreads=False, mpim_aware=False):
    return self.get('rtm.start',
                    params={
                        'simple_latest': int(simple_latest),
                        'no_unreads': int(no_unreads),
                        'mpim_aware': int(mpim_aware),
                    })
```

Pythonのエラーメッセージから、👆の関数でエラーとなっている事がわかります。

## Slackの公式ドキュメントを読んでみる

[Slack - Real Time Messaging API](https://api.slack.com/rtm)

RTMに関することは、👆に書いてあるようです。

読む前に、目立つセクションがありました。

> New Slack apps may not use any Real Time Messaging API method.
> Create a classic app and use the V1 Oauth flow to use RTM.

要約すると

- 新しいAppはRTMを利用できない
- RTMを使いたいんだったら `Classic app` を使ってね

ということです。

### Classic app の作成

`Classic app` の作成は、[Slack - Real Time Messaging API](https://api.slack.com/rtm) の最下部のリンクから行えます。

[Create a Classic Slack App](https://api.slack.com/apps?new_classic_app=1)

Appを作成したら、 `Legacy bot user` を追加する必要があります。

![Screen Shot 2020-11-15 at 10.07.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127585/dd594bd7-3db5-b873-047c-f189bb7c0b82.png)

### Classic app の Scopesを見てみましょう

![Screen Shot 2020-11-15 at 10.46.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127585/c7b5a901-ccb9-93e3-1e03-c3558d98d821.png)

`bot` の OAuth Scopeが `deprecated` となっていることがわかります。

## スコープのアップデートには要注意

[Slack API - Your Apps](https://api.slack.com/apps/)

`App Home` へアクセスすると、 `Tools` セクションに `Update to Granular Scopes` というのが存在します。

つまりは、Slackは 以前のBot向けスコープから

より細かいスコープへ移行することを推薦しています。

しかし、移行しようとすると下記メッセージが表示されます。

> The RTM API is not accessible to updated Bot Tokens.
> If your app requires RTM functionality, please exit this update and continue using your existing scopes.

移行すると、RTM APIは利用できなくなります。

`Classic app` のサポートは、明示的に期間が定められている訳ではなさそうですが

今後RTMを利用したSlack Botの作成は、別の手段へ移行する必要がありそうです。
JavaScript基本文法【関数】

##はじめに

現在、JavaScriptの独学をしています。

復習を兼ねて、今回は関数についてまとめます。

私と同じようにJavaScript初心者の方の参考になればと思います。

##関数とは

関数とは、タスクや値計算を実行する文の集まりのことです。

JavaScriptでは、関数オブジェクトとも呼ばれ、オブジェクトの一種です。

そのため、他の値と同じように変数へ代入したり、関数の引数として渡すことが可能です。

以下のように定義します。

```js
function 関数名 (仮引数) {
	// 色々処理・・・
	return 関数の返り値;
}
```

この定義方法以外にも、関数式で定義することもできます。

##関数式

関数式とは、関数を値として代入している式のことです。

```js
// 関数式
const 関数名 = function() {
    // 色々処理・・・
    return 関数の返り値;
};
```

関数式では右辺の関数名を省略できます。

このような名前を持たない関数を匿名関数とも言います。

関数式には上記のfunctionキーワードを使った方法以外に、Arrow Functionと呼ばれる書き方もあります。

```js
// Arrow Functionを使った関数定義
const 関数名 = () => {
    // 色々処理・・・
    return 関数の返す値;
};
```

##コールバック関数

JavaScriptでは、その場で作った匿名関数を関数の引数として渡すことができます。

引数として渡される関数のことをコールバック関数と呼びます。

また、コールバック関数を引数として使う関数やメソッドのことを高階関数と呼びます。

```js
function 高階関数(コールバック関数) {
    コールバック関数();
}
```

##メソッド

オブジェクトのプロパティである関数をメソッドと呼びます。

JavaScriptにおいて、関数とメソッドの機能的な違いはありません。

```js
const obj = {
    method1: function() {
        // `function`キーワードでのメソッド
    },
    method2: () => {
        // Arrow Functionでのメソッド
    }
};
```

また、ES2015からは、メソッドとしてプロパティを定義するための短縮した書き方が追加されています。

オブジェクトリテラルの中で メソッド名(){ /*メソッドの処理*/ } と書くことができます。

```js
const obj = {
    method() {
        return "this is method";
    }
};
```
CMakeLists.txtのcatkin_package()にハマった件

# はじめに
catkin_makeでビルドしているときに、なぜか実行ファイルが見つからないというエラーが発生したのでその調査結果をメモ

## 前提条件
* 環境はROS melodic
* ビルドツールはcatkin_make

## 結論
* 各パッケージのCMakeLists.txtにcatkin_pacakge()が記載されていないと、実行ファイルが```~/catkin_ws/devel/lib```に格納されず、rosrun等でノードを実行しようとしても以下の様に実行ファイルが見つからないというエラーが発生する。

```text
user@user-ubuntu:~/catkin_ws$ rosrun test_pkg test_pkg_node
[rosrun] Couldn't find executable named test_pkg_node below /home/user/catkin_ws/src/test_pkg
```
* [公式ドキュメント](https://docs.ros.org/en/melodic/api/catkin/html/dev_guide/generated_cmake_api.html?highlight=catkin_package#catkin_package)を参照すると、たしかにパッケージごとに1回呼び出す必要があると書いてある。

> Note
>
> It must be called once for each package. It is indirectly calling``catkin_destinations()`` which will provide additional output variables. Please make sure to call catkin_package() before using those variables.

* この時までcatkin_package()はライブラリとして作成するパッケージにのみ記載すればいいと考えていた。
    * しかし、実際は外部から参照されなくとも引数を空にして必ず1回だけ呼び出す必要があることがわかった。

## 実験
* 以下のようなフォルダ構成でHELLOと表示する簡単なパッケージを用意

```text
.
├── build
├── devel
└── src
    └──  test_pkg
        ├── CMakeLists.txt
        ├── include
        ├── package.xml
        └── src
            └── main.cpp
```

```cpp:main.cpp
#include <ros/ros.h>

int main(int argc, char **argv) {
  ros::init(argc, argv, "test_pkg_node");
  ros::NodeHandle n;

  ROS_INFO("HELLO");
  ros::spin();
  return 0;
}
```

```cmake:CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project(test_pkg)

find_package(catkin REQUIRED COMPONENTS
  roscpp
)
#catkin_package()
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)
add_executable(${PROJECT_NAME}_node src/main.cpp)
target_link_libraries(${PROJECT_NAME}_node
  ${catkin_LIBRARIES}
)

```

```xml:package.xml
<?xml version="1.0"?>
<package format="2">
  <name>test_pkg</name>
  <version>0.0.0</version>
  <description>The test_pkg package</description>
  <maintainer email="user@todo.todo">user</maintainer>
  <license>TODO</license>
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <exec_depend>roscpp</exec_depend>
</package>

```

* この状態でcatkin_makeしrosrunで実行すると以下のようなエラーが発生

```text
user@user-ubuntu:~/catkin_ws$ rosrun test_pkg test_pkg_node
[rosrun] Couldn't find executable named test_pkg_node below /home/user/catkin_ws/src/test_pkg
```
* devel/libディレクトリの中身は空のまま

```text
.
├── build
├── devel
|   └──  lib
└── src
```

* CMakeLists.txtのcatkin_package()を有効にしてビルドするとdevel/libディレクトリ内に実行ファイルが作成される。

```text
.
├── build
├── devel
|   └──  lib
|        └──  test_pkg
|             └──  test_pkg_node
└── src
```
HTTP X-Content-Type-Options ヘッダー概要

## 概要

* `Content-Type` ヘッダー(レスポンスのファイル形式を明示する)で示された MIME タイプに基づいてファイルタイプを判断すべきことを示すためにサーバー側で付与するヘッダー。
  * <u>ファイル**内容**から、ファイルタイプを判断させない</u>。

* MIME タイプのスニッフィングを抑止するために使用する。

  * MIME タイプが欠落している、あるいは MIME タイプが誤って設定されているとクライアントが判断した場合に、リソースを確認しMIME タイプを推測する処理。

  

## 構文

```http
X-Content-Type-Options: nosniff
```


## 指定しない場合に起こり得る脅威:クロスサイトスクリプティング(XSS)

![XSS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/308d62c9-7812-d2d9-d460-6085a33456dd.png)


## 参考情報

* [X-Content-Type-Options](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Content-Type-Options)
* [画像ファイルによるクロスサイト・スクリプティング(XSS)傾向と対策](https://blog.tokumaru.org/2007/12/image-xss-summary.html)
* [The face of X-Content-Type-Options which you may not know](https://speakerdeck.com/yagihashoo/the-face-of-x-content-type-options-which-you-may-not-know)
* [HTTPレスポンスヘッダによるセキュリティ対策](https://qiita.com/mint__/items/a4039d3cc659959d9231)
Javascript基礎知識＃4（比較演算子と論理演算子）

##はじめに
この記事は私の脱コピペを目指すために書いている自分用のメモです。

※内容について、誤った知識やもっとわかりやすい表現等ございましたら、ご指摘いただけますと幸いです。

##目次
1. 比較演算子とは 
2. 比較演算子一覧
3. 比較演算子の基本的な使い方
4. 論理演算子とは
5. 論理演算子一覧
6. 論理演算子の基本的な使い方



#1. 比較演算子とは
if文やfor文・while文などのループ処理の条件式に使われることが多い、
**2つの値を比較することが目的の演算子です**

#2. 比較演算子一覧
|比較演算子|意味|例|結果|
|---|---|---|---|
|>  |左辺が右辺よりも大きい    |2>1   |true    
|>= |左辺が右辺より大きいか同じ|2>=2  |true    
|<  |左辺より右辺が大きい      |2<4   |true    
|<= |左辺より右辺が大きいか同じ|2<=4  |true    
|=== |左辺と右辺の値と型が同じ |2===2 |true    
|!== |左辺と右辺が異なる       |2!==2 |true    


**比較演算子は、2つの値を比較して正しいかどうかを「True / False」で返してくれるのが特徴です。**

#3. 基本的な使い方

```javascript
if(1 === 1) {
  console.log('あってるよ！')
}
```
```javascript:結果
あってるよ!
```

こんな感じ。

#4. 論理演算子とは
『～**かつ**～だった場合』や『～**または**～だった場合』といったような感じです。


#5. 論理演算子一覧

|論理演算子|意味|
|---|---|
|a && b | **aとbどちらも**trueであればtrue  
|a｜｜b | **aかbどちらか**trueであればtrue   
|!a | aがtrueであればfalse、aがfalseであればtrue

#6. 論理演算子の基本的な使い方
```javascript:1
if(true && true) {
  console.log('実行したよ');
} else {
  console.log('実行してないよ')
}
```
```javascript:結果1
>> 実行したよ
```

```javascript:2
if(true && false) {
  console.log('実行したよ');
} else {
  console.log('実行してないよ')
}
```
```javascript:結果2
>> 実行してないよ
```

```javascript:3
if(true || true) {
  console.log('実行したよ');
} else {
  console.log('実行してないよ')
}
```
```javascript:結果3
>> 実行したよ
```

```javascript:4
if(true || false) {
  console.log('実行したよ');
} else {
  console.log('実行してないよ')
}
```
```javascript:結果4
>> 実行したよ
```



って感じです。
【営業向け】無駄な下書きメールを一括で削除するスクリプト

#やりたいこと＆その理由

以前、以下のスクリプトを作成して日程調整メールを半自動化したのですが、カレンダーに更新があるたびに下書きが作られてしまいますので、気づくと下書きのメールが50個ぐらいできてしまうことがある。　

[【営業向け】インサイドセールスでアポ取得できたときのお客様へのメールを自動生成する](https://qiita.com/hirokobe26/items/3a6f1ce721bb833d735c)


毎回一括で消しているのだが、時間が無駄なので（3秒で終わるけど）必要ない下書きを自動で削除しようと思った。


#実装方法
１：　下書きをすべて配列で取得
２：　繰り返し処理でひとつづつ下書きを削除　
３：　１と２の処理を毎日一回だけ朝の1時～2時の間に実行する


#完成系
以下が完成形

```gas.js
function deleteEmailDraft() {
  var drafts = GmailApp.getDrafts();
  drafts.map(function(draft){
    draft.deleteDraft();
  });
}
```
非常にシンプルですね。　GASは便利なメソッドだらけです。

#トリガーの設定
最後に以下のキャプチャのようにトリガーをすれば、終了。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271600/2e293b68-f728-e29d-bdf7-c27c79257f5a.png)


これで毎回手動で消さずとも、無駄な下書きが毎日自動で消されるので、月間のコール数が0.1件ぐらいは増えたかもしれない。
【Swift】compareについて考えてみた

これは初学者である筆者が初めて`compare`と出会った時の思考を綴るものとなっております。

ここでいうcompareはSwiftのStringクラスインスタンスメソッド`compare`を指します。

## compareの返り値って何なの問題
`ComparisonResult`ですね。はい、おしまい。

・・・とならないのが初学者です。
私ももれなくその一人でした。
[AppleDeveloperドキュメント](https://developer.apple.com/documentation/foundation/nsstring/1414082-compare)にも、目立つくらい**`Return Value`**って書いてあるのに！

そんな初歩的なところでつまづいている訳ですが、試行錯誤の過程は良い勉強になったのでこちらにアウトプットという形で残すことにしました。

## どこで出会ったのか？
> Swift実践入門 第３版 P53
> Foundationによる高度な操作 見本コードにて

上記箇所となります。
swiftの学習にと、こちらの書籍を手に取る初学者の方も多いのではないでしょうか。
私は上記箇所で突然現れた次のコードをみて固まってしまいました。

```swift
// P53 見本コード
import Foundation // compareはFoundationというライブラリで提供されているメソッド

// 2つの文字列間の順序の比較
let options = String.CompareOptions.caseInsensitive
let order = "abc".compare("ABC", options: options)
order == ComparisonResult.orderedSame //true
```

> 上記のコードでは、compare(_:option)メソッドで2つの文字列間の順序を検証しています。
--略-- 結果として順序が同じであることを意味する.orderSameという値を得ています。

一読しただけではよく分かりませぬ。

## コードリーディングしてみる
#### まず1行目

```swift
let options = String.CompareOptions.caseInsensitive
```
これはConpareメソッドに用意されているオプションで、大文字と小文字を区別しないというもの。
これを定数optionsとして定義している。

#### 2行目

```swift
let order = "abc".compare("ABC", options: options)
```

右辺では、文字列"abc"に対してcompareメソッドを使用し()内の"ABC"との比較をしている。その際、引数として先ほど定義した`options`を受け取っている。
ここで得られた結果を、定数`order`として定義している。

#### 3行目

```swift
order == ComparisonResult.orderedSame
```

2行目で定義した`order`と`ComparisonResult.orderedSame`を比較演算子にかけ、trueが返ってくる。

### 細かな内容について考えてみる

上記を踏まえ少しコードを簡素にした。
オプションについては疑問点とは関係なさそうなので省略。

```swift
let order = "abc".compare("abc")
order == ComparisonResult.orderedSame // true
```
つまり、`"abc".compare("abc")`の返り値は`ComparisonResult.orderedSame`ということ？

確認してみた。

```swift
let hoge = "abc".compare("abc")
print(hoge) // NSComparisonResult
```

実行結果・・・`NSComparisonResult`

### ComparisonResultとは
見本コードでも何食わぬ顔で現れたこいつを理解する必要がありそう。

[ComparisonResult](https://developer.apple.com/documentation/foundation/comparisonresult)

調べてみると`ComparisonResult`は**列挙型**で、３つのcase定数を持つということが分かった。

```swift
enum ComparisonResult: Int {
    case orderedAscending = -1
    case orderedSame = 0
    case orderedDescending = 1
}
```

ということはcompareメソッドはcaseのどれかを取得した後、ComparisonResultを返すということになると考えられる。

- case orderedAscending ・・・ `<`
- case orderedSame ・・・ `=`
- case orderedDescending ・・・ `>`

今回は比較対象がイコールであったため、`orderedSame`という値を取得し、
`ComparisonResult.orderedSame`が返されたということになります。

## compareの返り値
ということで冒頭のコードに戻ってみる。
せっかくなので、"ABC"だったところを"DEF"に変えてみる。

```swift
let options = String.CompareOptions.caseInsensitive
let order = "abc".compare("DEF", options: options)
order == ComparisonResult.orderedAscending
// true
```
2行目の`"abc".compare("DEF", options: options)`の返り値が`ComparisonResult.orderedAscending`なのでtrueということとなる。
`abc < DEF`という比較結果となっています。

## 後語り
今、自分で書いていても、「なぜこんなことが気になったのだろう？」と感じてしまうような内容ですね・・・

思いつく理由としては、`メソッドの返り値が列挙型`ということに戸惑いがあったからなのかもしれません。

別のメソッドですが、以下のようなシンプルな挙動をイメージしていました。
私が期待していたようなコード及び実行結果

```swift
// 私が期待していたようなコード及び実行結果
"abc".isEqual("abc")
// true
```

今回も上記のような形が頭から離れず「比較系メソッドはtrue/falseが返り値となるものだ」という先入観により、つまづき理解に苦しんでしまいました。

### **結論：さっさと公式ドキュメント読めばよかった。**

おしまい。

ここまでお読みくださりありがとうございましたm(__)m
Rails <%= 式 %> 中身がない時にエラーが起こらない理由

##この記事について
初心者が初心者に対して記述した初心者のRails記事


##ずっと何となく疑問に思っていたこと。

controllerでインスタンス変数に何かしらの値を入れたつもりだったが実は中身が空（nil）やって、その変数をviewに渡しても何のエラーも起こらないことが謎やった。


##なぜエラーが起こらないのか？
理由は**`<%= 式 %>`が出力されるときは、式に対して`to_sメソッド`が呼び出されているから**。

つまり、結果の出力はいつも自動的に`<%= 式.to_s %>`となっている。このメソッドが使える理由はRubyのオブジェクトは全て`to_sメソッド`を持ち合わせているからやねんな。


中身が入っていないインスタンスに対して`to_sメソッド`を呼びだす（`nil.to_s`）と、**空文字を出力するようになっている**。やからエラーが出さず、そしてそのまま何も表示されないんやな。


```ruby
#controller
@name = nil

#view
<p><%= @name.to_s %>さん</p>

#出力
#=> さん

```


##まとめ
学びたての時はエラーが出ないから気付き辛いけど、「裏側ではこうなってるんだよー」って分かるとどんな問題が起こってるか発見しやすくなりそう。
やから、このままちゃんと学習を続けていこうと改めて思えた。
クラウド破産を回避するIaC実践ガイドの写経はまりどころメモ

## この記事について
私の読解力、英語力、あらゆるxxx力の無さに起因し
ハマってしまった事に対するMEMOです

## 第3章 Terraform入門

- Terraform v0.13.5 では ```Enter a value```でリージョン名をSET。

```

ワイ$ terraform plan
provider.aws.region
  The region where AWS operations will take place. Examples
  are us-east-1, us-west-2, etc.

  Enter a value: ap-northeast-1

```

- なるほど。以下でリージョンを都度入力不要なのね。

```
provider "aws" {
  version = "3.5.0"
  region = "ap-northeast-1"
}
```
【Java】ArrayListクラスのオブジェクト操作 (AOJ④数列の反転)

#ArrayListクラス（可変長配列）のオブジェクト操作
* リストは**配下の要素が順序づけられたコレクション**
* ArrayListは内部的に配列を利用したデータ構造になっていて**後からでも要素追加削除可能**
    * cf: 配列は不可
* インデックス値による値の読み書き(ランダムアクセス)は、**位置によらず一定時間でアクセス可能**
* **値の頻繁な挿入削除は低速**
    * 挿入時に確保していたメモリの領域を超えると自動でメモリ再割り当てが発生する(→あらかじめ要素数が想定される場合サイズ宣言しよう)

###定義
* `ArrayList<型> リスト名 = new ArrayList<型>();`
  * <型> にクラス名を指定
  * 指定したクラスの**オブジェクトを要素として格納できるようになる**
  * 基本型を扱うリストを作成したい場合は、ラッパークラスで定義（ex: int型のラッパークラスはIntegerクラス）
  
###要素の並べ替え
* Collectionsクラスの**sortメソッド**
* リストの要素を自然昇順でソート
  * `Collections.sort(ArrayListオブジェクト);`
* 要素を降順にソート
    * `Collections.sort(ArrayListオブジェクト, Collections.reverseOrder());`
    
###要素を逆順に
* Collectionsクラスの**reverseメソッド**
* `Collections.reverse(リスト);`


```java
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.Arrays;

public class Main {
	public static void main(String[] args) {
	    
    ArrayList<Integer> nums = new ArrayList<Integer>(Arrays.asList(50,80,46));
    nums.add(1);
    System.out.println(nums); //[50, 80, 46, 1]

    //sort関数で昇順に並び替え 
    Collections.sort(nums); 
    //表示して確認 
    System.out.println(nums);  //[1, 46, 50, 80]
    //sort関数で降順に並び替え 
    Collections.sort(nums, Collections.reverseOrder());
    //表示して確認 
    System.out.println(nums);  //[80, 50, 46, 1]

    //リストから2番目の値を取得して表示 
    System.out.println(nums.get(2)); //46

    System.out.println("データ数:" + nums.size()); //データ数:4

    for (int i = 0 ; i < nums.size() ; i++){
      int num = nums.get(i);
      System.out.print(num+" "); //80 50 46 1 
    }
  }
}   

```

##数列の反転
>与えられた数列を逆順に出力するプログラムを作成して下さい。
*Input
入力は以下の形式で与えられます：
n
a1 a2 . . . an
nは数列の長さを示し、ai は i 番目の数を表します。
*Output
逆順の数列を１行に出力して下さい。数列の要素の間に１つの空白を入れて下さい（最後の数の後に空白は入らないことに注意して下さい）。
*Constraints
- n ≤ 100
- 0 ≤ ai < 1000


```java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n =scanner.nextInt();
	
        ArrayList<Integer> nums = new ArrayList<Integer>();

        for(int i=1;i<=n;i++){
		    int num = scanner.nextInt();
		    nums.add(num);
        }
        
       /*
       昇順に並び替え 
         Collections.sort(nums)
       降順に並び替え 
         Collections.sort(nums, Collections.reverseOrder());
       サイズ確認 
         System.out.println(nums.size()); 
       */
       Collections.reverse(nums);

        for (int i = 0 ; i < n ; i++){

            if (i==n-1){
                System.out.print(nums.get(i));
            }
            else{
            System.out.print(nums.get(i)+" ");
            }
        }
        System.out.println();
	}
}
```
Amazon ECSアプリ用秘密情報管理パラメータストア作成とアクセス用IAMポリシー設定

## やりたいこと

* API認証情報(クライアントID/シークレット)を保存するためのAWS System Manager パラメータストアを作成する。
* 上記パラメータストアにAmazon ECSタスクで起動するアプリがアクセスできるよう、IAMポリシーを設定する。



## パラメータストアの作成

* AWS CLIを使用して、クライアントシークレットを暗号化保存する場合(AWS KMS利用)

  ```shell
  aws ssm put-parameter \
      --name "API_CLIENT_SECRET" \
      --value "API_CLEINT_SECRET_VALUE" \
      --type SecureString \
      --key-id "YOUR_KMS_KEY_ID"
  ```

  上書きする場合は、`--overwrite`オプションをつける。



## ECSタスク用パラメータストアアクセス用ポリシーの作成

※ECSタスクロール作成済みの場合。

1.パラメータストアアクセス用ポリシー(``ECSTaskRolePSAccessPolicy.json`)を作成する。

   ```json
   {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "Stmt1",
                "Effect": "Allow",
                "Action": [
                    "ssm:DescribeParameters"
                ],
                "Resource": "*"
            },
            {
                "Sid": "Stmt2",
                "Effect": "Allow",
                "Action": [
                    "ssm:GetParameters"
                ],
                "Resource": [
                    "arn:aws:ssm:{YOUR_REGION}:{YOUR_ACCOUNT_ID}:parameter/API_CLIENT_SECRET"
                ]
            },
            {
                "Sid": "Stmt3",
                "Effect": "Allow",
                "Action": [
                    "kms:Decrypt"
                ],
                "Resource": [
                    "arn:aws:kms:{YOUR_REGION}:{YOUR_ACCOUNT_ID}:key/{YOUR_KMS_KEY_ID}"
                ]
            }
        ]
    }
   ```

   ```shell
   aws iam create-policy --policy-name ECSTaskRolePSAccessPolicy --policy-document file://ECSTaskRolePSAccessPolicy.json
   ```
   ※既存ポリシーを更新したい場合は、`create-policy-version`コマンドを利用する。バージョン数制限があるため、古いバージョンは`delete-policy-version`コマンドなどで削除する必要がある。

2.パラメータストアアクセス用ポリシー(`ECSTaskRolePSAccessPolicy`)をECSタスクロール(`ECSTaskRole`)にアタッチする。

   ```shell
   aws iam attach-role-policy --role-name ECSTaskRole --policy-arn "arn:aws:iam::{YOUR_ACCOUNT_ID}:policy/ECSTaskRolePSAccessPolicy"
   ```

   



## 参考情報

* [Systems Manager パラメータの作成 (AWS CLI)](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/param-create-cli.html)
* [タスクIAMロールとパラメータストアを利用したAmazon ECSアプリケーションの秘密情報管理](https://aws.amazon.com/jp/blogs/news/managing-secrets-for-amazon-ecs-applications-using-parameter-store-and-iam-roles-for-tasks/)
【JavaScript】要素に指定したCSSスタイルを取得したい！

#プログラミング勉強日記
2020年11月15日
ドットインストールでJavaScriptを学習中にふと、『CSSのスタイルはどうやって取得するのか？』と気になりました。
自分的には、ややこしかったので今後間違えないように記録していきます。

#取得したいこと
* CSSファイルに記述したbackgroundプロパティの値を取得したいと思います。

![スクリーンショット 2020-11-15 8.37.08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854121/596a8153-c3cc-154d-fc3c-b204d1b4e5d9.jpeg)


```index.html
  <div class="box" id="target"></div>
```
```style.css
.box {
    width: 100px;
    height: 100px;
    background-color: rgb(204,204,204);
}
```

#完成コード
まず最終的に取得できたコードが以下になります。


```script.js

'use strict';
let $target = document.getElementById('target');
console.log(window.getComputedStyle($target)['background']);
```

#完成コードの解説
1.id属性が`'target'`の要素を取得。

2.`window.getComputedStyle($target)[background]`で取得した要素の`CSSStyleDeclarationオブジェクトのbackgroundプロパティの値`を返す。


#つまづいた箇所
ドットインストールで、boxクラスの背景色を変える際に、

```script.js
$target.style.background = 'pink';
```
と記述していたので、背景色を取得する時も、

```script.js
console.log($target.style.background);
```
でいけるかと思ったのですが、コンソール見てみると何も取得できていませんでした。

もし、上記の書き方で取得する際は、


```index.html
  <div class="box" id="target" style='background: pink;'></div>
```
と`要素にstyle属性を直接指定する`もしくは、

```script.js
$target.style.background = 'pink';
console.log($target.style.background);
```
と`jsファイルで先に背景色を変える指定を行い、`取得する必要があると分かりました。


#参考資料
* [CSSStyleDeclaration](https://developer.mozilla.org/ja/docs/Web/API/CSSStyleDeclaration)
* [【JavaScript】要素に指定したCSSスタイルを取得する方法](https://cpoint-lab.co.jp/article/201802/1535/)
pymysqlのLIKEのパーセント

python3.x

ライブラリpymysqlを使って
connection = pymysql.connect(・・・)
部分一致のLIKE文を動かしたかったのだが

```
with connection.cursor() as cursor:
   cursor.execute("SELECT c1 FROM ttt WHERE c2 LIKE 'abc%'", ())
   ary = cursor.fetchall()
```

と書くと

```
TypeError: not enough arguments for format string
```

となる。
pymysqlに%を無視してもらうために
%を%でエスケープしないとダメらしい。

```
with connection.cursor() as cursor:
   cursor.execute("SELECT c1 FROM ttt WHERE c2 LIKE 'abc%%'", ())
   ary = cursor.fetchall()
```

で動いた。
Recoilの概要

この記事は[Core Concepts](https://recoiljs.org/docs/introduction/core-concepts) の翻訳記事です。 (2020/11/15時点)

## Overview

Recoil を使うと、atoms(共有ステート) から selectors(純粋関数)　を通してReactコンポーネントに流れていくデータフローを構築できます。

Atoms は コンポーネントがsubscribeするステートの単位で、selectors は同期的または非同期的にステートを変形します。

## Atoms

atomsはステートを表す単位となるものです。

atomsは更新可能でsubscribe可能な値です。つまりatomは文字通り更新できて、それに依存しているコンポーネントは更新時に新しいatomの値で再レンダリングされます。

また、atomsはランタイムによって構築されます。atomsはReactコンポーネントのローカルなステートと同じ場所で使うことができ、もし同じatomが複数のコンポーネントで利用されているとき、コンポーネントのatomは同じステートを共有します。

atomsは `atom`関数を使って作成します。

```ts
const fontSizeState = atom({
  key: 'fontSizeState',
  default: 14,
});
```

atomsの作成には一意なkeyを設定することが必要です。これはデバッグ、一貫性の維持、全てのatomsを俯瞰するためのadvanced APIなどで使われます。

もしatomsでkeyが重複する場合はエラーを起こしてしまうため、必ずこれは一意な値を使う必要があります。

またReactコンポーネントのステートと同様にデフォルト値を持ちます。

コンポーネントからatomを読み書きするためには、`useRecoilState`と呼ばれるフックAPIを用います。

Reactの`useState`と見た目は似ていますが、ステートはatomsを使うコンポーネント間で共有されている点が異なっています。

```tsx
function FontButton() {
  const [fontSize, setFontSize] = useRecoilState(fontSizeState);
  return (
    <button onClick={() => setFontSize((size) => size + 1)} style={{fontSize}}>
      Click to Enlarge
    </button>
  );
}
```

この例では、ボタンをクリックするとフォントサイズがインクリメントされます。しかもこれは、他のコンポーネントのフォントサイズにも波及します。

## Selectors

**selector**はatomsまたは他のselectorsを入力として受け取る純粋関数です。

上流つまり入力として渡したatomsやselectorsが更新されると、それを受け取るselector関数も再評価(更新)されます。

selectorsをsubscribeしているコンポーネントは、atomsの`useRecoilState`のように、selectorが更新されたときに再レンダリングされます。

selectors は ステートに基づいて派生データを計算するために使用されます。

selectorを使うことでreducerがステートを同期して有効に保つ必要がなくなり、余計なステートが増えることが回避できます。

その代わり、atomsには最低限必要なステートのみが格納され、他のステートはそこから派生する関数、つまりはselectorによって効率的に計算されます。

selectorはコンポーネントが何に依存しているかをトラックしてくれるおかげで関数的なアプローチがより効率的に取れるようになっています。

コンポーネントから見ると、selectorもatomも全く同じインターフェースをしているため、selectorとatomはお互いに置き換え可能になっています。

selectorsは`selector`関数を使って定義されます。

```ts
const fontSizeLabelState = selector({
  key: 'fontSizeLabelState',
  get: ({get}) => {
    const fontSize = get(fontSizeState);
    const unit = 'px';

    return `${fontSize}${unit}`;
  },
});
```

`get`プロパティは派生するステートを計算する関数です。この関数はatomsや他のselectorsの値を `get()` の引数を通して受け取ることができます。atomsやselectorsにアクセスすると依存関係が構築され、依存元が更新されたときに再計算が行われるようになっています。

今回の `fontSizeLabelState` ではselectorは`fontSizeState` atomにだけ依存しています。

コンセプト通り、`fontSizeLabelState` selectorは `fontSizeState` を入力として受け取って、フォーマットされたフォントサイズのラベルを出力する純粋関数のように振舞います。


selectorは`useRecoilValue()`を使って読み取り可能です。これは引数にatomかselectorを受け取り、それに対応する値を返すAPIです。

`fontSizeLabelState` selectorは書き込み不可能なので、`useRecoilState()`は使用しません。 (書き込み可能なselectorについて知りたい場合は[selector API reference](https://recoiljs.org/docs/api-reference/core/selector)参照)

```tsx
function FontButton() {
  const [fontSize, setFontSize] = useRecoilState(fontSizeState);
  const fontSizeLabel = useRecoilValue(fontSizeLabelState);

  return (
    <>
      <div>Current font size: ${fontSizeLabel}</div>

      <button onClick={() => setFontSize(fontSize + 1)} style={{fontSize}}>
        Click to Enlarge
      </button>
    </>
  );
}
```

ボタンをクリックすると、ボタンのフォントサイズが増加し、現在のフォントサイズをフォーマットして表している`${fontSizeLabel}`にもその変更が反映されます。
【CSS3】aタグの下線、リンク色の変更方法

ヘッダーのロゴを画像ではなく文字を使用する場合など、
aタグで囲むと設定されるデフォルト値の下線、リンクの(青)色の解除方法を記載します。

# text-decoration: none;を指定し下線を非表示
![スクリーンショット 2020-11-15 7.45.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640274/b0fa9f5c-b73c-ba49-b5e1-508bc46d1682.png)

```css:style.css
a {
  text-decoration: none;
}
```
![スクリーンショット 2020-11-15 7.58.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640274/ca5f689f-b94f-6bb8-d14c-809b2b97373c.png)

# color: 色コード;を指定しリンクの色を変更
```css:style.css
a {
    text-decoration: none;
    color: #000000; /* 今回は#000000を指定していますが、好きな色を指定できます */
}
```
![スクリーンショット 2020-11-15 8.14.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640274/f5b0c910-1802-5cde-4737-5c1ce17fa838.png)

![スクリーンショット 2020-11-15 8.15.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640274/f26fd98c-f570-a1a1-e57d-ad89328a0a57.png)
★Webページヘッダーのロゴに使用し、クリックするとトップページに遷移させるなど色々と応用できそうです!
【ARKit】'hitTest(_:types:)' was deprecated in iOS 14.0 対処法

iOS 14.0から<code>hitTest(_:types:)</code>は非推奨になっており、Xcodeから注意された時の対処法

|動作環境|バージョン|
|:-----------|:-----------|
|Xcode|12.1|
|iOS|14.1|
|Swift|5|

<hr>

iOS 14.0で<code>hitTest(_:types:)</code>を使用すると、このように注意されます。
![スクリーンショット 2020-11-15 7.11.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678954/c5113e68-0e57-3075-a808-e088c926f55c.png)
>・日本語訳
'hitTest(_:types:)' は　iOS 14.0では非推奨です。
ARSCVView.raycastQuery(from point: CGPoint, allowing target: ARRaycastQuery.Target, alignment: ARRaycastQuery.TargetAlignment)
こちらを使ってね。

ということです。

##hitTest(_:types:)の代わりにraycastQueryを使用
<b><code>touchesBegan</code>でtouchした座標を取得する</b>コードを例として挙げさせていただきました。

```swift:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        // タッチした最初の座標を取り出す
        guard let touch = touches.first else { return }
        
        // タッチで取得した座標をスクリーン座標系に変換
        let touchPosition = touch.location(in: sceneView)

        //これより下がhitTest(_:types:)の代わりのコード
        guard let query = sceneView.raycastQuery(from: touchPosition, allowing: .existingPlaneGeometry, alignment: .any) else { return }
        let results = sceneView.session.raycast(query)
        guard let hitTestResult = results.first else {
            print("no surface found")
            return
        }
        let anchor = ARAnchor(transform: hitTestResult.worldTransform)
        sceneView.session.add(anchor: anchor)
    }
```

<hr>
これで意図した動作が出来ました。
間違いやより良い方法がありましたら、優しく指摘していただけると幸いです。

##参考
<a href="https://stackoverflow.com/questions/64258067/hittest-was-depecrated-in-ios-14-0">stackoverflow: 'hitTest()' was Depecrated in iOS 14.0</a>
vistaでquartus その49

# 概要

vistaでquartusやってみた。
qsysでniosやってみた。
zundokoやってみた。


# サンプルコード


```
#include "sys/alt_stdio.h"

int main()
{ 
  alt_putstr("Hello from Nios II!\n");
	int r;
	int i = 0;
	int j = 0;
	while (j < 1)
	{
		r = rand() % 2;
		if (r < 1)
		{
			alt_putstr("doko ");
			if (i == 4) j = 1;
			i = 0;
		}
		else
		{
			alt_putstr("zun ");
			i++;
		}
	}
	alt_putstr("kiyoshi!!");
  while (1);
  return 0;
}


```

以上。
【Ruby on Rails】NoMethodError: undefined method `t' for #<ActiveRecord::Migration:〇〇〇〇>エラーの対処

#エラー画面![スクリーンショット 2020-11-15 7.34.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722354/580f5a17-647e-3fbe-38c7-99e9e4701136.png)

#該当のソースコード
```ruby
class AddDeviseToUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name,          null: false
      t.text :profile
    end
  end
  t.string :email,              null: false, default: ''
  t.string :encrypted_password, null: false, default: ''
end
```
#原因
メソッドtの定義はそのcreate_tableのdoに対するendまでの範囲でしか使えない

#解決
```ruby
class AddDeviseToUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name,               null: false
      t.text   :profile
      #下の二行をdoの中に入れた
      t.string :email,              null: false, default: ''
      t.string :encrypted_password, null: false, default: ''
    end
  end
end
```
#補足
`rake db:migrate`しても`Schema.rb`に反映されない方は`rake db:migrate:rollback`で一度マイグレーションを落としてからマイグレーションを変更して`rake db:migrate`してください。

【参考資料】https://qiita.com/s_tatsuki/items/3e1f119c91e21b8f0c33
【CSS3】<li></li>の黒丸を非表示にする方法

# CSSでliタグにlist-style:noneを指定する

![スクリーンショット 2020-11-15 7.33.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640274/4a15c1e3-fd76-578f-71c1-19ae2a18b916.png)


```css:style.css
li {
  list-style: none
}
```


![スクリーンショット 2020-11-15 7.38.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640274/769bae9d-cde9-e7dd-8aa7-64ab330d79bb.png)