OmniAICreator/Qiita-1.07M huggingface dataset:
【JavaScript】値のundefinedと空値チェックメモ


####何故メモするの？
*　kintoneのJavaScriptカスタマイズを行う際に、undefinedか空文字かのチェックをすることが多いことと。
*　今まで厳格な等価評価でundefined評価をしていたけどどうやら推奨されていないと知ったため。
[詳細はMDNを参照](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/undefined)

####良く使用していたチェック
```javascript
// if文
if(val === undefined){

}else if(val === ''){

}else{

}

// 三項演算子
val === undefined ? '' : val === '' ? '' : val;

```

####なんで推奨されないのか。
~~`undefined`は、グローバルスコープ内の変数だから。
予約語ではないため、上書きしたりしてグローバル汚染してしまう恐れがあるため。
なるほど。~~
@StormSurge様から以下の理由によりundefinedが書き換えられることはなく厳密等価演算子での比較も成立するとご指摘頂きました。保守性を考慮して以降のプログラムも`val === undefined`の厳密な等価評価式に変更しました。以前記載していた評価式(`val === void 0`)はコメントアウトしています。

>最近のブラウザー (JavaScript 1.8.5 / Firefox 4 以降) での undefined は、 ECMAScript 5 仕様により、設定不可、書込不可のプロパティとなります。 (そうでない場合でも、上書きは避けてください。)

####（結局）どのようにしたの？

```javascript
// 空値 or undefinedチェック
if (!checkValUndefined(val)) {
   // 空値 or Undefined時の対応
} else {
   // それ以外の時の対応
}

/**
  * 引数の値がundefinedか確認する。
  * @param {*} val - undefinedかチェックする値
  * @returns {string} - undefinedの場合：空値/それ以外の場合：チェックする値
  */
const checkValUndefined = (val) => {
   //　return val === void 0　
   return val === undefined   
     ? ''
     : val;
};
```

「void 0」の「0」の部分は「0」でなくても良いそうです。「void」はあらゆる値に作用して、`undefined`を返すらしいです。全く知りませんでした。


よくkintoneでフィールドに値を入れたり取得したりする際に使用しています。

####今後
kintoneで推奨されていないけど、最低限名前空間オブジェクトにして全体反映のJavaScript置き場に上のプログラムを配置すると、どのアプリからでも参照できるようになるから使い勝手めっちゃ良くなる。他にも共通しているような関数はここにまとめちゃってしまった方が良いのかなとも思い始めた…。

####終わりに
もっとこうしたら良いとか、そこおかしいのとか等あったら教えてください。

####参考
　@quicksort様[JavaScript undefined値の判定](https://qiita.com/quicksort/items/3b7776aba7bd2e97cf46)

####更新履歴
20201/1/7 @StormSurge様コメントの指摘からコードの判定条件の仕方を厳格な等価評価に変更
VRサーフィンデバイス『In The GreenRoom(ITGR＝アイティーギア)』のプロトタイプを作成

# 誰もがGreenRoomを体験できるようにしたい
サーファーの中でも、選ばれ者しか入ることのできない神聖な場所『GreenRoom』。
それは、最高の天気と、最高の波が作るチューブの中にのみ出現する世界。
[![](https://img.youtube.com/vi/hD2E5qc6HVs/0.jpg)](https://www.youtube.com/watch?v=hD2E5qc6HVs)
人生でこのGreenRoomを体験できる人は一握りしかいません。
僕が作りたいデバイスは、この世界を誰もが体験できるデバイス『In The GreenRoom(ITGR＝アイティーギア)』です。
しかも、ただ360度の画像をVRで表現したものではありません。
このデバイスのためだけに撮影された画像を使い、これを不安定なサーフィンの板の上という状況を再現した上で、板の上にたちがるタイミングか適切かどうかを判定することで、より『リアル感』を追求したデバイスを作ることです。
今回は、このデバイスのプロトタイプを作成しました。
実物は以下の通りです。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">VRデバイスのプロトタイプが完成！<br>サーフィンの近未来感が出てるwww<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/deployorlose?src=hash&amp;ref_src=twsrc%5Etfw">#deployorlose</a> <a href="https://t.co/seTyVOScBr">pic.twitter.com/seTyVOScBr</a></p>&mdash; 北城雅照|プログラミングにはまったサーフィン好きの整形外科医 (@teru3_kitashiro) <a href="https://twitter.com/teru3_kitashiro/status/1346747479136509952?ref_src=twsrc%5Etfw">January 6, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 今回のプロトタイプで目指したもの
今回の実現したいVRデバイスの肝は以下の3つです。
①　このデバイス専用に撮影された360度画像
②　海の上のサーフィンの板の不安定感を擬似体験できる板デバイス
③　音ゲーの様にテイクオフのタイミングが正しいかどうか判定できるプログラミング
①は現在撮影中、②にはすでにあるもので代用できるため、③について今後開発が必要になります。

そこで今回のプロトタイプでは、③について考えるべく、不安定な板の上でテイクオフ（板の上に立つ）のタイミングを感圧センサーで感知し、それを別のデバイスに通知することを目指して作成しました。
最終的なセンターの通知先は3D空間ですが、今回はLINE Notifyを通知先に設定しました。

また、VRで視界が奪われた状況で、テイクオフがしっかりできるかどうかも確認する必要があるため、Oculusを使用し、Youtbube３６０のサーフィン画像を出しながら、トライアルを行いました。

## 実際使用したデバイス
①　Oculus quest
②　[Mr.Takeoff](https://item.rakuten.co.jp/mrtakeoff/10000000/)
[![](https://img.youtube.com/vi/4gDOejXs3GY/0.jpg)](https://www.youtube.com/watch?v=4gDOejXs3GY)
③　下記で作成した感圧センサーデバイス

最終的には下記の様にこれらを下記の様に配置しました。
![IMG_2340.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581193/43ee7637-ac19-211f-6de0-0aa1dc963621.jpeg)

## 感圧センサーデバイス
感圧センサーデバイスについては下記の記事にコードを記載してありますので、ご確認ください。
[感圧センサーを押すと、LINE Notifyに通知を出す方法のまとめ](https://qiita.com/Teru_3/items/5eb6df7f2084887316a8)

# いざ実験！

## スタッフの石井君登場
自分が医療法人の理事長であることを利用し、当院スタッフの石井君に被験者になっていただきました。
パワハラじゃないですよ！
見てください、この屈託のない笑顔を！
![IMG_2337.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581193/1aaa1045-b792-4a93-ab70-dfc0d6f7a132.jpeg)

## 実験でわかったこと
①　圧センサーが小さすぎる
この部分を正確に踏むのは結構何度が高い

②　Oculusで視界が見えないので、Mr.テイクオフのレベルが激ムズになる
事前にMr.テイクオフ自体の練習が数回必要
ワイプで画面の左上に自分の姿を上から見た様な映像を載せても良いかも

③　動画と状況が合っていないといまいち気分が乗らない
これは専用の動画を撮影することで解決可能

今後も試作機を作って、問題点を洗い出して行こうと思います。
忘備録２　プログラミングに置いての”＝”の意味

私はコードを実装していたり、書籍やプロゲートで疑問に思ったことはすぐに調べています。キータでアウトプットする癖をすれば、自分は徐々にプログラムが書けるようになるのではないか？と考えました。初歩的なこともキータにアウトプットしています。

代入　　
数学で使うイコールという意味ではなく、「変数の箱の中に値を入れる」という意味である。
代入演算子と呼ばれる。
”右側の値を左の変数に代入する”という意味である。
右辺を左辺に代入する。　

```
fruit = "りんご"
put fruit
→りんご
```
EC2(AmazonLinux2)でnode.jsを起動するまでの過程記録(nodemonを使う)

###前提として行ったこと
①AWSへの登録
②EC2サーバーの新規立ち上げ
③RDBの新規構築
④ローカル環境で制作したフォルダの、EC2へのアップロード

<strong>今回はnodemon を使いました。</strong>
これによってシステムの内容に変更があった時、再起動しなくても適応される(はず)。

以下、EC2サーバー上で正しく動作させるために行ったことを記録する。
##目次
・<strong>行ったこと</strong>
→パーミッション設定
→「npm start で起動するようにする」
→必要なもののインストール
→DB情報の書き換え
→エラー「Permission denied」
→nodemonのインストール
・<strong>おまけ(永久実行)</strong>
・<strong>参考文献</strong>


#行ったこと(失敗も含む)
##パーミッション設定
編集したいファイルは、フォルダごと権限を777にした。
``$sudo chmod 777 フォルダ名orファイル名``
権限を変えるのは危ないので「ローカルで書き換えてアップロード」を繰りかえす方がいいかも。
(今回は個人製作でいじられても重大事件になるようなシステムではないので気軽に変えた)

##「npm start」で起動するようにする

package.jsonに以下を追加

```json
  "scripts": {
    "start": "nodemon ./bin/www"
  }
```

これは絶対に必要ではない。
直接``nodemon ./bon/www``と打ち込んでも実行できる。

##必要なもののインストール
npm install
``$curl --silent --location https://rpm.nodesource.com/setup_10.x | sudo bash -
$sudo yum -y install npm``

node.js install
``$sudo yum -y install nodejs``

nodemon install
``$sudo npm install -g nodemon``

postgresql install 
[ここを見ました](https://yohei-a.hatenablog.jp/entry/20200924/1600941789)

express install
``$npm -g install express``

##DB情報の書き換え
ローカル環境で開発した際、index.jsのソースコードの中に書いた接続情報は、ローカル環境でしか動作しない。
EC2サーバー上で正常に動作させるために、

```
host: 'localhost'　→　host: '[AWSで作成したDBのエンドポイント]'　←変更
port: 5432　←追加
```

と書き換えた。


ここで
```$npm start (もしくは$nodemon ./bin/www)```
を実行したが、`Permission denied` (権限エラー)で実行できず。
##エラー「Permission denied」

```
/node_modules/.bin/nodemon: Permission denied
npm ERR! code ELIFECYCLE
npm ERR! errno 126
npm ERR! ths-web-page@1.0.0 start: `nodemon ./bin/www`
npm ERR! Exit status 126
npm ERR!
npm ERR! Failed at the ths-web-page@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
```

<strong>wwwがあるフォルダまでのすべてのフォルダの権限をゆるくしてみる</strong>
権限エラーが出ていたので権限制限ゆるくしてみた。
※当たり前ですが会社のシステムとかで勝手に権限ゆるくするのは絶対にダメ！

→まだ同じエラーが出ます。多分この操作は意味がなかった
##nodemonをインストールする
``$sudo npm install -g nodemon``
このコマンドを打ったらインストールされ、
正常に``$npm start　(もしくは$nodemon ./bin/www)``を実行できた！！

それにしてもなぜ権限エラーに？？

#おまけ(永久実行)
node.jsを、AmazonLinuxからログアウトした後もそのまま起動しておくには、
``$sudo npm install -g forever``
でインストールして
``$sudo forever start ./bin/www``
というコマンドを叩く。

#参考文献URL
[Amazon EC2でnode.js,Expressアプリケーションを立ち上げる](https://qiita.com/Sugima/items/670924901e38cf9eb84a)
[Amazon Linux 2 に PostgreSQL 11 をインストールする]
(https://yohei-a.hatenablog.jp/entry/20200924/1600941789)
[npm start の使い方]
(https://techacademy.jp/magazine/16393)
[node.js バージョンアップコマンド]
(https://note.com/mono01012/n/n7fe82a0ba979#6uQX6)
[AWS EC2 AmazonLinux2 Node.jsをインストールしてnpmコマンドを使用できる様にする
]
(https://qiita.com/miriwo/items/4ac80bc51bb072ace652)
Python数学シリーズ③ 行列式(置換)

## このシリーズについて
数学の理解を深めるためにpythonで実装しながら、理解を進めてます。当分は線形代数やろうと思います。数学はそんなに好きではありませんでしたが、最近好きになってきたかもしれません。シリーズの目次は[こちら](https://qiita.com/Hiroaki-K4/items/90b2f86558ef825e5d21)。

## 行列式と置換
行列式は以下の式で定義されます。[参照元](https://mathtrain.jp/determinant)
![Screenshot from 2021-01-05 23-00-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/770f8c45-35db-a66a-fa39-975a963c338d.png)
いきなり、行列式を実装しようとしても色々と知識が足りなかったので、とりあえず置換をまずやっていこうと思います。
置換は以下のように定義されます。[参照元](https://oguemon.com/study/linear-algebra/permutation/)
![Screenshot from 2021-01-06 22-33-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/142cbca6-f79d-d102-5b82-0b5514ab00c5.png)
(1, 2, 3)とかだと(3, 1, 2)とかが置換されたものの例になります。n文字の置換は全部でn!通りあることになります。今回は置換の積を実装していこうと思います。
置換の積は以下のように表されます。[参照元](https://oguemon.com/study/linear-algebra/permutation/)
![Screenshot from 2021-01-06 22-42-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/79f6c02f-a2f1-2e7a-dfd0-dc37ba45cf6d.png)
[こちら](https://oguemon.com/study/linear-algebra/permutation/)の記事いわく、2つの置換の対応関係（「A→B」と「B→C」）を3段論法的な感じで1つにギュッとまとめる(「A→C」)感じだそうです。詳しく突き詰めると、自分の場合沼にはまりそうなのでこのイメージでとどめておきます。今回はこの置換の積を実装していこうと思います。

## 置換の積
置換の積ができるpythonのライブラリが見つからなかったので、自分の実装が合っているか不安です。もしライブラリがあれば教えてください。下のような感じで実装してみました。シンプルに定義どおりにやってみました。

```python3
def permutation(list1, list2):
	list_len = len(list2[1])
	final_list = []
	first_list = []
	ans_list = []
	for i in range(list_len):
		a = list2[1][i]
		ans = list1[1][a - 1]
		if list1[0][i] != ans:
			first_list.append(list1[0][i])
			ans_list.append(ans)
	final_list.append(first_list)
	final_list.append(ans_list)
	return final_list

def main():
	print("~~permutation_test~~")
	pm1 = [[1, 2, 3], [2, 3, 1]]
	pm2 = [[1, 2, 3], [3, 2, 1]]
	print("my_answer:", permutation(pm1, pm2))
    # 出力結果
    # ~~permutation_test~~
    # my_answer: [[2, 3], [3, 2]]
```
これは改善の余地が大いにありそうですが、とりあえずこんな感じで今回はやってみました。

## まとめ
大学の数学の授業、予備のりたくみの動画でいい説。

**間違いや質問、ご意見等ありましたらお気軽にコメントください。頑張って答えますので(笑)。**
【フロントエンド学習③】CSSの詳細度について

# 詳細度とは？

ざっくり説明すると「CSSが適用される優先度」の順序のこと。
詳細度が高い方が優先してCSSが適用される。

## そもそもCSSが適用される順序って？

- あるセレクタを同じ方法で指定した場合、CSSは後に書いたものが優先されます。
- 異なる方法で指定した場合、<font color="red">詳細度</font>が高い方が優先されます。

## もうちょい詳しく

#### ここで言う「詳細度が高い」とは

より詳しくセレクタを指定している = 詳細度が高い
言い換えると__「より絞ってセレクタを指定している」__ほうが詳細度が高い、ということになる。

## よくわからないんだけど？

単一の指定方法の場合だと、

1. HTMLタグに「style属性」を用いて記述されたスタイル(<font color="gray">てすと3</font>の部分)
2. idを指定して記述されたスタイル(<font color="green">てすと2</font>の部分)
3. classを指定して記述されたスタイル(<font color="purple">てすと1</font>の部分)
4. HTMLタグ名を指定して記述されたスタイル(<font color="blue">てすと0</font>の部分)
5. 親要素を指定して記述されたスタイル(<font color="red">てすと</font>の部分)

<font color="red">__番号の小さい方__</font>が詳細度が高くなり、優先的に適用されます。

デモ

<p class="codepen" data-height="400" data-theme-id="dark" data-default-tab="css,result" data-user="tanakatarou590" data-slug-hash="BaLrwVg" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="BaLrwVg">
  <span>See the Pen <a href="https://codepen.io/tanakatarou590/pen/BaLrwVg">
  BaLrwVg</a> by 転職活動中の なーちゃん@Webエンジニアに転職2020 (<a href="https://codepen.io/tanakatarou590">@tanakatarou590</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>



## 複数の方法で指定した場合はどうなる？

結論としては、__指定に使われているidやclass等が多い方が詳細度が高い__ となります。

具体的には、

1. idを使って指定されているスタイル
2. classをより多く使って指定されているスタイル
3. idやclassが同じ数だった場合、より多くセレクタで指定されているスタイル

こちらも<font color="red">__番号の小さい方__</font>が詳細度が高くなります。

デモ

<p class="codepen" data-height="400" data-theme-id="dark" data-default-tab="html,result" data-user="tanakatarou590" data-slug-hash="RwGMjOr" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="RwGMjOr">
  <span>See the Pen <a href="https://codepen.io/tanakatarou590/pen/RwGMjOr">
  RwGMjOr</a> by 転職活動中の なーちゃん@Webエンジニアに転職2020 (<a href="https://codepen.io/tanakatarou590">@tanakatarou590</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

上記の1~3が全て同じだった場合、後に書かれたスタイルが適用されます。

## 例外

```css:style.css
p {
  color: red; !important
}
p {
  color: blue;
}
```

上記の例では、通常pタグの内容は青色になるはずですが、
「!important」をつけることで強制的に最優先に適用することができます。

ただし、多用すると何が最優先なのかわからなくなる恐れがあるので、
使用するのは非推奨となっているようです。

おわり
Effective Python 学習備忘録 5日目 【5/100】

## はじめに
Twitterで一時期流行していた 100 Days Of Code なるものを先日知りました。本記事は、初学者である私が100日の学習を通してどの程度成長できるか記録を残すこと、アウトプットすることを目的とします。誤っている点、読みにくい点多々あると思います。ご指摘いただけると幸いです！

## 今回学習する教材

- [Effective Python](https://www.amazon.co.jp/Effective-Python-%E2%80%95Python%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%82%92%E6%94%B9%E8%89%AF%E3%81%99%E3%82%8B59%E9%A0%85%E7%9B%AE-Brett-Slatkin/dp/4873117569/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=Effective+python&qid=1609408832&sr=8-3)
    - 8章構成
    - 本章216ページ

## 今日の進捗

- 進行状況：48-55ページ
- 本日学んだことの中で、よく忘れるところ、知らなかったところを書いていきます。

### 動的なデフォルト引数を指定するときにはNoneとドキュメンテーション文字列を使う

#### デフォルト引数は一度しか評価されない

キーワード引数のデフォルト値に、現在時刻を使うプログラムを考える。

``` code
from datetime import datetime
from time import sleep

def log(message, when=datetime.now()):
    print('%s: %s' % (when, message))

log('Hi there!')
sleep(0.1)
log('Hi again!')
```

出力結果

``` result
2021-01-06 14:52:16.518219: Hi there!
2021-01-06 14:52:16.518219: Hi again!
```

キーワード引数はモジュールロード時の関数定義の時だけなので、時刻は変化しない。デフォルト値をNoneにして、ドキュメンテーション文字列に実際の振る舞いを文書化することで、可読性を担保しつつ、正しい動作を得ることができる。

``` code
def log(message, when=None):
    """Log a message with a timestamp.

    Args:
        message: Message to print.
        when: datetime of when the message occurred.
            Defaults to the present time.
    """
    when = datetime.now()
    print('%s: %s' % (when, message))

log('Hi there!')
sleep(0.1)
log('Hi again!')
```

出力結果

``` code
2021-01-06 15:20:07.665323: Hi there!
2021-01-06 15:20:12.870457: Hi again!
```

### キーワード専用引数で明確さを高める

関数の引数が多くなった際に、位置引数を用いると可読性が落ちる。
例として、4つの引数を持ち、初めの2つはint型、最後の二つはboolian型を受け取る、関数を考える。

``` code
def sample(int_a, int_b, bool_c, bool_d):
    # ...

sample(1, 2, True, False)
```

この場合、bool_c, bool_dを容易に位置を取り違える可能性がある。
キーワード引数であれば、そのような心配は無くなる。Pythonでは、位置で引数を指定できなくする、キーワード専用引数が用意されている。
**引数リストの中の*記号が、位置引数の終わりと、キーワード専用引数の始まりを示す。**

``` code
def sample(int_a, int_b, *, bool_c, bool_d)
    # ...

sample(1, 2, True, False)                 # Error になる
sample(1, 2, bool_c=True, bool_d=False)   # 動作する
```
ストレージと電源を挿すだけでRaspberry Piを動かす(Raspberry Pi OS編)

# はじめに

Raspberry Piをサーバとして使用するのにセットアップのためだけにディスプレイとキーボードをつなげるのは面倒...と思ったことはありませんか？

こんな煩わしさを解消するために、Raspberry Piのセットアップを手元の端末でほぼ完結するやり方をまとめておきます。

# お品書き

今回は以下のパターンのセットアップについて見ていきます。

* Raspberry Pi OS(**今回はここにフォーカスします**)
    * SDカード使用
    * USBメモリ使用
* Ubuntu Server
    * SDカード使用
    * USBメモリ使用


# 本題に入る前に

今回インストールディスクの書き込みには[Raspberry Pi Imager](https://www.raspberrypi.org/software/)を使用します。使用端末に合わせたものをインストールしてください.

# Raspberry Pi OSでのセットアップ
**SDカード、USBメモリ共通の手順です**

## Raspberry Pi Imagerでのディスクの書き込み

### OSの選択
Raspberry Pi OS Lite(32bit)を選択します
![スクリーンショット 2021-01-06 22.18.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172922/448d9845-05f8-a21f-a420-8a70fcba17fe.png)

### ディスクの選択
端末に起動用のディスクを挿入し選択画面から選択してください
![スクリーンショット 2021-01-06 22.20.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172922/f8a15b82-cdc6-e9a7-8fe5-87b0aeb4fd3e.png)

### 書き込み
`WRITE`を押して書き込み。
書き込み完了後ディスクはアンマウントされてしまうので再度装入し直してください。

## wifi接続設定ファイルの作成

### ベースとなる接続設定ファイルについて
以下を用いていきます。
SSID名とパスワードのハッシュ値を埋めていきます。
SSIDは接続先のものをそのまま書き込んでください。

```wpa_supplicant.conf
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
	ssid="{SSID名}"
	psk={暗号化キー}
}

```

### 暗号化キーについて

ブラウザで生成する場合にはhttp://jorisvr.nl/wpapsk.html のページで生成するやり方があります。

上記のページでは入力したSSID/WPAキー/生成された暗号化キーの送信をサーバに送信しているわけではなさそうです。
ただ、心配な人は以下のdockerコマンドを叩くことで暗号化キーの生成ができます。(事前にdockerのインストールが必要です。)

```shell
$ docker run -it ubuntu:20.04 /bin/bash -c "apt update && apt install -y wpasupplicant && wpa_passphrase {SSID名} {WPAキー}"
```

生成されたキーを上記の `{暗号化キー}`の部分に埋め込んでください。

## 設定ファイルをSDカード/USBメモリに転送
先程作成したwpa_supplicant.confをSDカード/USBメモリのルートディレクトリに配置してください。
また、RaspberryPiが起動したあとにsshができるよう　`ssh`というファイル名のからファイルを作成してください。

macでの手順は以下です

```shell

$ ls wpa_supplicant.conf
wpa_supplicant.conf
$ cp wpa_supplicant.conf /Volumes/boot/
$ touch /Volumes/boot/ssh
$ ls -1 /Volumes/boot/wpa_supplicant.conf /Volumes/boot/ssh
/Volumes/boot/wpa_supplicant.conf
/Volumes/boot/ssh
```

SDカード/USBメモリをRaspberryPiに挿し電源を入れてください。
ssh をする際には `ssh pi@raspberrypi.local`でログインできます。(PWは`raspberry`)
個人忘備録　Model.find(params[:id]) について

railsのアプリを実装している際、気になったことがあった為、調べました。個人用忘備録なので書いてあることが間違っているかもしれません。その際はご指摘よろしくおねがいいたします。



```tweet.controller.rb
  def show
    @tweet = Tweet.find(params[:id])
  end
```
インスタンス変数→controllerからviewに受け渡す役割を担っている。
インスタンス変数とは？

```
class クラス名
  def メソッド名
    @変数名 = 値  # インスタンス変数
  end

インスタンスが個別に持つ属性値が入る。そのインスタンスのすべての動作に使用できる変数ということ。
変数を利用することで、値を再利用したい場合に、変数の名前を使うだけで呼び出すことができます。
```
なぜ先頭に＠をつけるのか？
特に意味はなく、ruby言語文法の決まり事である。気にしなくて良い。
findとは？
指定したモデルのインスタンス（すぐに利用できるデータ）を返す記述。

paramsとは?
Railsで送られてきた値を受け取るためのメソッド.値を持たずコンパクトに記述をすることが可能。
params[:カラム名]と表される。
golangでmultipart.File型の画像をリサイズ〜S3にアップロードするまで

# 概要
golang製のAPIサーバーを個人開発する中で、フロント側から受け取った画像ファイルをリサイズ等編集して、S3にアップロードするロジックを実装しました。その際、結構苦戦したので、要点をまとめていきたいと思います。

# 実践
## multipart/form-dataをパース
~~~go
file, _, err := r.FormFile("image")
~~~
fileにmultipart.File型としてgoで扱えるようになります。

## バッファーに内容を流し込む

~~~go
img := &models.Image{
		UserID: uid,
		Buf:    &bytes.Buffer{},
	}

	_, err := img.Buf.ReadFrom(file)
	if err != nil {
		return &models.Image{}, err
	}
~~~

今回のアプリはレイヤードアーキテクチャ＋DDDを採用しているので、Imageモデルをポインタ型で宣言して、参照渡しでバッファーにデータを流し込んでます。この時バッファーを格納するBufも宣言してあげないと、アドレス領域が確保されずnilエラーが発生してしまうので、注意が必要です。

## 画像編集
~~~go
func ResizeImage(i *models.Image) error {
img, t, err := image.Decode(i.Buf)
	if err != nil {
		return err
	}

省略

err = jpeg.Encode(i.Buf, m, nil)
		if err != nil {
			return err
		}
~~~

バッファー型にすればデコード・エンコード可能になるので、ここでリサイズ等画像編集する。

## S3にアップロード
~~~go
uploader := s3manager.NewUploader(sess)
		_, err = uploader.Upload(&s3manager.UploadInput{
			Bucket: aws.String("example"),
			Key:    aws.String(img.Name),
			Body:   img.Buf,
		})
~~~
バッファー型のままアップロード可能なので、対象のバケット、名前等定義すれば完了！！

# 参考資料
[Goでmultipart/form-dataをparseする](https://qiita.com/r9y9/items/35a1cf139332a3072fc8)
[AWS SDK for Go S3バケット基本操作](https://qiita.com/nightswinger/items/df6050ea8f8f541360f4)
[リアルタイム画像リサイズAPIをGo + Serverless Application Modelで作った時の感想](https://qiita.com/NaotoFushimi/items/2d4e1ae36b8158ec2493)
Autowiredの定義忘れ

### 起こった事象

以下のようなエラーが出力

```
Description:

Field サービスクラス内のAutowiredしている変数 in サービスクラス required a bean of type 'Daoインターフェース（Autowiredしているインターフェース）' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'Daoインターフェース（Autowiredしているインターフェース）' in your configuration.
```

### 原因

インターフェース実装クラスのアノテーションが漏れていたため、Autowiredする時に対象が見つからなかったためエラーが発生していた。

```
public class UserDaoJdbcImpl implements UserDao
```

↓

```
@Repository
public class UserDaoJdbcImpl implements UserDao
```
SQLの基礎について学ぶ＃０２

# SQLの基礎について学ぶ＃０２
## ０．accountテーブル
「[SQLの基礎について学ぶ＃０１](https://qiita.com/TAISEI-050523/items/31dd74cd386fe4dc46bf "Qiita")」に引き続き、accountテーブルでSQLに共通する基本ルールなどをまとめていきます！！
### accountテーブル
|    date（日付）    |    name（項目名）       |    price（金額）     |
|:-----------:|:------------:|:------------:|
| 2020-12-03 |　　　お弁当  　 | 9000         |
| 2021-01-03 |　　　飲み代 　 | 3000         |
| 2021-05-22 |　　　電車代  　 | 3000         |
| 2021-03-14 |　　　日用品  　 | 2000         |
| 2021-04-02 |　　　ローン  　 | 4000         |
| 2021-01-12 |　　　医療費  　 | 3000         |

## 1. 基本ルール#０１
### ・文の途中に改行を入れることができる<br>・行の先頭や途中に半角の空白を挿入できる

```SQL
/* SELECT文を一行で表示 */
SELECT price FROM account WHERE price > 3000
```
```SQL
/* SELECT文を改行して表示 */
SELECT price 
 FROM account      /* 先頭に半角の空白*/
WHERE price > 3000;  /* 末尾のセミコロンで終了を表す */
```
### 👉改行を長いSQL文で用いることで予約語(キーワード)が一目で分かるようになる。

## ２. 基本ルール#０２
### ・SELECTやWHEREなどの命令語は「予約語」である<br>・「<sapn color="red"">予約語</span>」の表記は大文字、小文字の区別がない<br>・テーブル名や列名に「予約語」を使用することはできない

## ３． データ型とリテラル
### 代表的なデータ型
|   データ種別    |   区分     |    代表的なデータ型名     |
|:-----------:|:------------:|:------------:|
| 数値   |  整数　 | INTEGER型        |
| 数値   |  小数 　 | DECIMAL型、REAL型         |
| 文字列 |　固定長  　 | CHAR型       |
| 文字列 |　可変長  　 | VARCHAR型         |
| 日付・時刻 |　-  　 | DATETIME型、DATE型、TIME型         |
▶利用可能なデータ型は利用するDBMSによって異なるが、数値型、文字列型、日付型は使用されている。
▶テーブルの各列にはデータ型が必ず指定されている。
▶日付型は各DBMS間で比較的違いが大きいため注意が必要である。
▶固定長はあらかじめ格納できる文字列の領域が指定されている。
（例：CHAR(10)=10バイトの領域を確保、7バイトの文字列が格納されると残り3バイトは空白で格納される。）
▶可変長は格納された文字列に応じた領域が確保される。
（例：VARCHAR(10)=10バイトの領域を確保、7バイトの文字列が格納されても残り3バイトは空白で格納されない。）
### リテラルの記述に関するルール
SQL文中に書き込まれたデータそのものを<b>リテラル</b>と呼ぶ。
以下のSQL文ではVLAUEのあとに続く（）に囲まれたもの。

```SQL
INSERT INTO account VALUES ('2021-04-04', 'お茶', 900)
 /* 900が「'」シングルクォーテーションで囲まれていない */
```
▶「'」でくくらずに記述されたリテラルは<b>数値情報</b>で扱われる。
▶「'」でくくられて記述されたリテラルは<b>文字列情報</b>で扱われる。
▶「'」でくくられ、'2021-04-04'のようにある形式で記述されたリテラルは<b>日付情報</b>で扱われる。

# まとめ
今回はここまでです！SQLについて引き続き学び、また次回投稿していきたいと思います！！
Pythonで環境変数にアクセスする方法

# 環境変数にアクセスする方法

### モジュールのインポート

```
import os
```

### 環境変数にアクセスする

Pythonでは、osモジュールの`environ`に環境変数が格納されている。
型は、マップ型です。

```
user_name = os.environ['USERNAME']
print(user_name)
```

また、`os.getenv(key, default=None)`を使用することでも取得できます。

```
user_name = os.getenv('USERNAME', 'dummy')
print(user_name)
```

`os.getenv()`は第1引数で環境変数のキーを指定します。
指定されたキーが存在していない場合は、第2引数の値を返却します。

# まとめ

環境変数にアクセスする方法は2つある。

* 1つ目は、`os.environ`を使用する方法
* 2つ目は、`os.getenv()`を使用する方法

場合によると思いますが、単純にアクセスするだけなら、環境変数が存在していない場合に任意の値を返却してもらえる`os.getenv()`を使用するのが良いと思います。
Sourcetreeでクローン時remote repository not found.　のエラー

#Sourcetreeでクローンが上手くいかない

こんにちは。
Sourcetreeでクローンしようとするとエラーが出て困ったので
備忘録にしようと思います。

＊M1 MacBook使用
＊Sourcetreeのバージョンは4.0.2です。

#URLをクローンする
GithubとSourcetreeを導入する際に、
アカウントの連携などは上手くいきましたが、
**「URLをクローン」する**ところで詰まりました。

![スクリーンショット 2021-01-06 22.11.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/910050/879c2c16-a62b-fa79-5abe-155f3a89702f.png)
※これは入力する前の画面です

・ソースURL：Githubからコピーしたhttps~のURL
・保存先のパス・名前などを入力

すると、左下に**「有効なソースパス/URLではありません」**
と出てきたので、クリックすると
**remote repository not found.**
などのエラー。

「リモートリポジトリが見つかりません」とはなんぞや・・・
となりました。

色々調べて解決しようとしましたが、解決せず・・・
試行錯誤して先ほどのエラーが出なくなり「いける！」と思っても、
次はエラーが出ていた**左下の部分がぐるぐる**して
永遠にクローンに辿り着けず・・・

#キャッシュを消す
そこで辿り着いたのが**「キャッシュを消す」**ことでした。

Macの場合
SourceTreeのメニューバー → SourceTree → 環境設定 → 高度な設定 
ここに過去に認証したことがあるホスト名とユーザー名がでます。

Githubの場合はホスト名「github.com」
**これを削除して、パスワードを再度入力し、クローンし直す**
という作業を何回かすると無事クローンできました！

２日越し・・・

#おわりに
解決すると「あれ？あっけないな？」となりましたが
不慣れでかなり困ったので誰かの役に立つと嬉しいです。
Oracle DBのデータ移行で少し詰まった話

# はじめに
OracleDataBaseのデータ移行で詰まったので、メモ程度ですが記事書かせて頂きます。

# 移行内容
OracleDataBase19cからダンプをEXPORTして、12cにIMPORTするだけの簡単なお仕事

# ポイント
ダンプを12cにIMPORTする際、以下のエラーが発生した。

```
ORA-39358: エクスポート・ダンプ・ファイルのバージョン19.0.0.0.0はターゲットのバージョン12.2.0と互換性がありません
```

見ての通り、互換性が無いとのこと。調べたら下位バージョンにデータを移行する際は、エクスポートの際にバージョンを明示的に指定する必要があるみたい。

# 回避方法

### エクスポート時のコマンド
今回はスキーマ"SCHM01"をエクスポートする。
ポイントは`version=X.X.X`で下位バージョンを指定すること。

```
user1/password schemas=SCHM01 directory=DATA_PUMP_DIR dumpfile=SCHM01.dmp logfile=EXP_SCHM01.log version=12.2.0
```

### インポート時のコマンド
バージョン指定したダンプをいつも通りインポートする。

```
user2/password schemas=SCHM01 directory=DATA_PUMP_DIR dumpfile=SCHM01.dmp logfile=IMP_SCHM01.log
```
<投稿一発目> Rubyの勉強はじめました

##前置き
初めてQiitaで記事を書いてみます。
自分の性格的に、出来ればQiitaの機能等について詳しく知り尽くした上で投稿を始めたいのですが、そんな調子だと石橋を100回叩いても一歩を踏み出せない気がするので、Rubyの勉強を開始したこのタイミングでとりあえずはじめてみます。
ひとまず学習内容の記録を備忘録的に残していく形で書いてみました。これからどのように記事を書いていったらいいかもまだ曖昧ですが、書き方・内容についても少しずつブラッシュアップしていければと思います。
自己紹介等はおいおい機会があるごとに少しずつ書いていけたらと思います。

##学習教材について
「Progate」の「Ruby学習コース」を活用して勉強をはじめます。
今回は「Ruby学習コースⅠ」を終わらせました。

##ちょっとした雑記・学習後の所感
プログラミングって学び始めて直ぐの段階から、「面倒なこと・重複作業をしないため、要らないミスをなるべく減らすために、ここはこういうふうにしましょう」ってことを考えさせ・勉強しますよね。
「だってそれがプログラミングの要でしょ？」って言われてしまうかもしれませんが、そんな当たり前なところにものぼくはものすごく魅了を感じます。

以前勤めていた職場でも、空き時間等を使って様々な業務の簡素化・自動化にチャレンジしてました。
- アナログ且つマニュアルな業務をエクセルのフォーミュラ等を駆使して改善してみたり
- 毎回のように新しく作っていたエクセルシートやワードの資料をテンプレート化して都度使用するごとに改善を加えたり
- 人に業務手順とか作業方法聞かれたときに毎回手とり足取り教えるのが嫌になり業務マニュアル作ったり（自分も解決できない疑問点があると納得いくまで人に聞きまくるが、これを他人からされると辛い…）

まあ、要は主な動機として単純作業に毎日多くの時間を費やすのをやめて、なるべく付加価値を付けたアウトプットを出したかったからですね。副次的にはいずれその努力から得られるメリットがチームや部署に普及してみんなで得をしていければいいなとの思いもありました。最初はExcelの独学に時間を費やしていましたが、いろいろ壁にぶち当たるうちに知ったのがプログラミングやRPA。特にある程度のプログラミングの知識とスキルがあれば、異なるソフトウェアを跨いで作業を自動化させたり、なんならお高いERPパッケージを買わなくても、チームや部署内で使える簡易webアプリケーションとかを組めることを知りました。

大学院でビジネスを学んでいたときも、アイデアはピッチするものの技術的なスキルや知識（ソフトウェアもハードウェアも）が圧倒的に不足していたので、机上の空論を並べるだけで抽象的なイメージを具現化することができず、いろいろと悔しい思いもしました。（当時思いついたアイディアはどれもデジタルやIoTがシステムに組み込まれてやっと完成するものばかりだったのです… 結局、課題選定時にはボツにされたアイディアが、後に海外でほとんど瓜二つのビジネスモデルとしてマーケットに出現してまあまあ利益を上げていることを知ったり…これはもうコロンブスのたまごですが。）

プログラミングでなにかを作るって、究極的に利便性や効率化を追求する手段・作業ですよね。自分は今でも普段から、「あーこういうことが出来ればいいのにな。こんなサービスがあれば世の中もっと便利にになるはずなのにね。」なんてことをぼーっと考えてます。そんなひらめきや思いをもっと簡易に実現する手段でもあるプログラミング・ソフトウェアを本腰を入れて学んでみることにしました。
このあたりの話はまたこれから機会あるごとに少しずつ書いてみようと思います。

##「Ruby学習コースⅠ」備忘録・気づき
- なぜプログラミングにおいて変数を使うのか
    - 同じ要素を繰り返し使える
    - 後からの変更に対応しやすくなる
    - なんの要素かわかりやすくなる

- 変数名のルール
    - 英単語で記載する
    - 2ワード以上は空白部分をアンダーバーで区切る
    - 望ましくない変数名 => ローマ字表記、日本語表記等々…
    - エラー発生する変数名 => 数字始まりの

- 文字列における変数展開
    - 文字列内に「#{変数名}」で変数展開が可能
    - 注意点：
        - 変数展開はダブルクォーテーションの文字列内でのみ可能
        - シングルクォーテーション文字列では文字列として出力されてしまう
        - 変数になっている数値と文字列は足し算で連結不可のため(エラー発生する)
        - 上記の理由から、変数を文字列に含めたい場合は、変数展開を使用すること
- その他
    - true or false をダイレクトにコンソールに表示するには, 変数定義後にputsで可能
    - 2者が等しいかの式　「==」
    - 2者が異なるかの式　「!=」
    - 「且つ」の式は 「&&」
    - 「又は」の式は 「||」
    - インデントはTABキーで。パッと見たときの読みやすさを意識すること
【UE4】動画を書き出すと色が濃くなる問題

#発端
こないだ初めてUE4でアニメーションを書き出したのですが、書き出した動画がEditorで見ているより暗くなっていました。
![スクリーンショット 2021-01-06 222326.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144702/d244a04f-ae8b-4641-cd0b-698eb9b46933.png)
困りました。

#解決方法
Edit/Project Settings/Engine/Rendering/Default SettingsのAuto Exposureのチェックを外すと、見た通りに書き出せます。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144702/210ae59d-bf96-a581-a09b-dd6187e1e2d9.jpeg)

デフォルトでは明るさの調整が自動になっているようです。

#謝辞
ありがとうNguyễn Thuận。
![スクリーンショット 2021-01-06 220050.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144702/7c3e5d24-104c-a166-c237-5782c1b2aa8f.png)
SQL 一般的には大きく3つに分類される。

#【SQL 一般的には大きく3つに分類される。】

業務でDDLの簡単な理解が必要になるので学習しました。
SQLは、とても重要なので積極的に学びたい。
SQLチューニングの業務があるのできっちりこなしていきたい。

##前提

・データベースの操作を支持する立場（DML）
・データベース自体の操作を支持する立場 （DDL、DCL）

##DML（Data Manipulation Language） データ操作言語

<strong>DB、特にテーブルのデータに対して命令する言語</strong>
データに対しての命令

・SELECT : 検索、抽出など。
・INSERT : 削除
・UPDATE : 更新
・DELETE : 登録

※SELECTは、DBのテーブルに対して、データを問い合わせている。
→SELECT文を確実に抑えておくことで、他の言語にも応用が効く。

##DDL（Data Definition Language） データ定義言語

<strong>DBの定義に対して命令する言語</strong>
テーブルやビューなどに対しての命令

・CREATE : 新しいデータベースオブジェクトの作成
・DROP : 既存のデータベースオブジェクトの削除
・ALTER : 既存のデータベースオブジェクトの変更
・TRUNCATE : テーブル内のデータ全体の削除

※テーブルやビューに対して、操作をするといったような認識

##DCL（Data Control Language） データ制御言語

<strong>データに対するアクセスを制御する言語</strong>
DMLやDDLの利用に関する許可や禁止を設定する命令

・GRANT : 権限の付与
・REVOKE : 権限の剥奪

##※SQLは必須知識　

SQLは、ANSI（米国規格協会）で国際的に規格化されている。
そのため、どのSQLを使用しても大きな大差はない。
（プログラム言語の他言語ほどの差はない。）
→SQLの基本を早いうちから覚えておくと将来的に大きく役に立つ。
vscodeの色を変えたい時に参考にする記事

1 各ディレクトリに .vscode/settings.jsonファイルを作成し、好きな色を着ける。
2 誤ってコミットしないようgitのグローバル設定から.vscode/settings.json をignoreする。


https://qiita.com/mottox2/items/a5813feeaf653ef3e2c3
https://qiita.com/yam86/items/056f1f54c67086a57458
http://vdeep.net/gitignore-global


3 好きな色に変更する

```json
{
    "workbench.colorCustomizations": {
      "titleBar.activeBackground": "#d83520",
      "activityBarBadge.background": "#d83520",
      "menubar.selectionForeground":"#d83520",
      "statusBar.background": "#d83520",
      "statusBar.noFolderBackground": "#d83520",
      "statusBar.debuggingBackground": "#d83520",
    }
  }
```
[RDSとElasticache]のマルチAZとレプリカの違い

# 背景
RDSとElasticacheのコストを削減をしてます。

RDSインスタンスのマルチAZを無効にすることでコストを半減した。考えずにElasticacheのインスタンスで同じことをやってみたら、全然効果がなかったです。ちゃんと両者のマルチAZの違いを理解してなかったのでまとめた。

# 前提
ここのElasticacheはRedisを指してます。

# 違い
## RDS
- マルチAZ
    - 有効すると、スタンバイインスタンスを自動的に立ち上げられる
    - コストはマルチAZ無効の２倍
- レプリカ
    - 別で手動で作成する必要
    - インスタンスタイプはプライマリと異なっても大丈夫

## Elasticache
- マルチAZ
    - レプリカの存在はマルチAZ有効の前提条件なので、レプリカがないと、マルチAZを有効することができない
    - マルチAZ自体は無料
    - 故障のとき
        - 有効
            - 一番遅延が短いレプリカへの自動フェイルオーバーを行われる
        - 無効
            - 新しいリソースを自動的にリクエストする
- レプリカ
    - Redisクラスターを作成するときか、その後追加することができる
    - インスタンスタイプはプライマリと一緒

# コスト削減例
例|効果|説明
---|---|---
RDSインスタンスのマルチAZを無効にする|  O |自動的にスタンバイを削減されるため、コスト半額
RDSのレプリカを消す|   O |インスタンス数が減ったから|
ElasticacheクラスターのマルチAZを無効にする|   X |マルチAZは無料；無効にすると、プライマリが故障するときに、レプリカへの自動フェイルオーバーが行われないだけ、レプリカのコストはかかるまま|
Elasticacheクラスターのレプリカを減らす| O   |インスタンス数が減ったから|
    
# 参照
- [Redis Multi\-AZ \| Jayendra's Blog](https://jayendrapatil.com/tag/redis-multi-az/)
Javaでラッパークラスは使うべきではない３つの理由

今までなんとなくでやっていたのですが、変数の指定の際にラッパークラスのプリミティブ型の違いがやっとわかったのでメモとして残しておきます。

理由1: ラッパークラスを使うとプログラムのパフォーマンスが悪くなるらしい
理由2: ラッパークラスはnullを許容してしまうため、行動を読む人に「nullが入ってしまう可能性がある」と誤解させてしまう可能性がある
理由3: ラッパークラスはオブジェクトの1つであるため、値同士を比較演算子で以下のように比較しようとした場合、falseになってしまう。
![スクリーンショット 2021-01-06 21.52.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637360/41b156a9-2f95-67e6-fa94-41e7c2203cd5.png)

またラッパークラスはメリットとしてメソッドが使える点が挙げられるが、それらはスタティックメソッドであるため、変数宣言にラッパークラスを用いなくてもメソッドを使いたいときだけそれらを呼び出せば良いので、基本は変数宣言もプリミティブ型で問題ない。
【SAP】SAP TechEd 2020　~セキュリティ編~

#はじめに#
昨今、セキュリティの重要性は叫ばれており、大企業でも情報漏洩のニュースを頻繁に見るようになった。これまで私自身もSAP導入時はクライアントのセキュリティポリシーに外れていないかどうかのチェックはするものの、あらかじめセキュリティについて考え、とるべき対策をしっかり検討することはしてこなかった。今回、TechEDに参加するにあたり、SAPとしてセキュリティについてどのように考えているかを確認するべく、以下のトラックを中心に受講した。

メイントラック：Integrated Intelligent Suite 
サブトラック：Consistent security and identity management​

#講義内容#

**SAP Security by Design and Default [IIS129]**
今回の講義の中で一番基礎的ですぐに役立ちそうな内容であった。
セキュリティ対策を講じるにあたり、下記の階層別にどのような対応をするかをOperation Mapという形でまとめていた。これを見れば、どのような対策を講じるべきか最初チェックでき、漏れなくセキュリティ事項の対して対応できるようになっていた。

組織：セキュリティガバナンスやリスク管理
プロセス：監査対応、事故発生時の対応
アプリケーション：ユーザ管理、ロール管理、SSO、カスタムコーディングのセキュリティ
システム：ハードニング、セキュアコーディング
環境：ネットワーク、OS、データベースセキュリティ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/792264/c0f861ee-cc93-8089-8dcd-4c67975c587c.png)



**Road Map : SAP Cloud Identity Access Governance [IIS817]**
新製品であるSAP Cloud Identity Access Governanceの紹介がメインであった。
この製品により、ユーザ管理、権限管理、アクセス分析ができ、本製品とオンプレミス、クラウドのシステムを接続することで、一元管理することができ、システム管理者の負荷を削減することができる。
また、ロードマップを使って、これから提供するサービスについての紹介もあった。
[IIS206]がSAP Cloud Identity Access Governanceを利用した事例の説明であった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/792264/d5330175-40e0-dd45-f987-6942abe0685f.png)


**Intelligent Role Provisioning in Integrated H2R Business Processes [IIS206]**
これはHRシステムから、イベントトリガでユーザ管理を簡素化するための新製品の事例紹介だった。
Success FactorsとSAP Cloud Identify Access Governanceを連携することで、複数のシステムに対してユーザ関連の作業を自動化できるものであった。

例えば、
社員が追加となった場合にSuccess Factorsにユーザを登録すると、SAP Cloud Identify Access Governanceにイベントが発行され、SAP Cloud Identify Access Governance上に登録したルールにしたがい、S/4HANAやAriba、Fieldgrass、Azureなどにユーザが登録される。
これを使えば、マニュアルで各システムにログオンしてメンテナンスするなどの情システム部の工数は大きく削減されることであろう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/792264/b4ce12c6-19db-5d6f-15f9-ca8e070d8a1d.png)

#まとめ#
SAPのセキュリティに対する取り組みを確認し、改めてどうあるべきかを見直した方がよいと感じた。事前に取り組んでおくのと、システム導入後に対応するには工数も大きく異なるため、クライアントに対して、システムを提案する側の責務として、セキュリティリスクをしっかりと説明し、そのために必要な対応であることを理解してもらって進めていきたい。
また、複雑化するクラウドシステムのユーザ管理を一元化や各システムのSSOログオンは、情報システム部員の負荷を減らすことになるため、提案できるように今後も継続的に情報のキャッチアップが必要であると感じた。
Microsoft Azure "App Service"とは

## はじめに
* 「”App Service”について初見です」という方向けとなっております。

## AzureサービスのPaaSに分類される"App Service"について整理してみました
Microsoft Azureが提供しているPaaSサービスに、「App Service」という仮想Webサーバのようなものがあるとのこと、正体を探ってみることにしました。

* <b>App Serviceとは何ぞや？</b>
  * HTTPベースのアプリケーションを動かすための環境です。
  * 複数サービスの総称です。（Web Apps/Mobile Apps/API Apps）

* <b>App Serviceの種類</b><br>下記の3種類があります。

  * Web Apps<br>
    一般的なWebアプリケーション実行環境を提供

  * Mobile Apps<br>
  OSやAndroidなどモバイルアプリ向けの実行環境を提供

  * API Apps<br>
    外部から呼び出されて結果を返すプログラムを作るための環境を提供

つまり、アプリケーションの作り方によって呼び方を変えているようです。

* <b>App Serviceの構成<br></b>
2つのリソースから構成されており、どちらも設定する必要があります。

  * Web Apps(App Service　要するにアプリ)<br>
    アプリの実行環境。OSにIISをインストールするようなもの。
    言語を指定し、アプリに実行環境を決める。

  * App Serviceプラン<br>
    仮想マシンのようなもの。作成時にCPUやメモリ、ストレージ容量などのHWリソースを決める。
    一つのApp Serviceプランの上に複数のアプリを機能させることも可能。
    
    

    上記どちらもロードバランサーがついており、自動スケーリング可能です。
* <b>App Serviceプラン比較</b>

|                        |        Free         |        Shared        |   Basic    |  Standard  |  Premium   |
| :--------------------: | :-----------------: | :------------------: | :--------: | :--------: | :--------: |
|          CPU           | 共有<br />(60m/day) | 共有<br />(240m/day) | 1,2,4Core  | 1,2,4Core  | 1,2,4Core  |
|         メモリ         |         1GB         |         1GB          | 1.75GB~7GB | 1.75GB~7GB | 3.5GB~14GB |
|       ストレージ       |         1GB         |         1GB          |    10GB    |    50GB    |   250GB    |
|    カスタムドメイン    |          -          |          ○           |     ○      |     ○      |     ○      |
|       SSL証明書        |          -          |          -           |     ○      |     ○      |     ○      |
|      自動スケール      |          -          |          -           |     -      |     ○      |     ○      |
|    Traffic Manager     |          -          |          -           |     -      |     ○      |     ○      |
|  ステージングスロット  |          -          |          -           |     -      |    5個     |    5個     |
| 自動バックアップ(日次) |                     |                      |            |    10個    |    50個    |


  価格の最新版は下記を参照。
  　[[Azure App Service] の価格](https://azure.microsoft.com/ja-jp/pricing/details/app-service/windows/)

  Azure Potalから「Basic～Premium」のリソースを選択する際、”ACU”という表記がありますが、これは”Azure Compute Unit”(ACU)といってAzureの性能を相対的に評価するための指標です。
  （標準でACU=100、性能が倍となればACU=200　など）

  

## まとめ

  - [x] App Surviceは、Webアプリケーションの実行環境です。
  - [x] 利用する際、まずは"App Serviceプラン"を作成することから始めます。
  - [x] ”App Serviceプラン”で決めたサイズによって、HWリソースの量やオプション機能、および価格が決定します。
  - [x] 自動スケールや自動アップデートなど、PaaSならではの管理負荷を軽減する機能が備わっています。


ひとまず、以上です。

**End**

***
Exchange Onlineのメッセージサイズ制限

# Exchange Onlineのメッセージサイズ制限

## 3行で
　Exchange Onlineの送受信メッセージ制限はメールボックスの以外にもメールフロールール設定でもかけられる。
　例外を認めず一律でメッセージサイズ制限を効かすのであれば、ルール設定のほうが便利。
　メールボックス自体の制限しか見てないとルールでのサイズ制限は盲点だった。


## 背景・目的・読み手

### 背景
　送受信メールサイズ制限が設定されているはずなのに、通常設定されていると思われる個所が空欄やデフォルト値だったため、どこで設定しているか不明だったことがあった。

### 目的
　Exchange Onlineのメッセージ制限がかけられる場所をまとめておき、今後の運用に活用する。
　色々探してしまったため、忘れないためにメモ。

### 読み手
　Exchange Onlineの管理者



## メッセージサイズ制限の既定値は？
 メッセージサイズ制限値は最初35MBに設定されている。管理者はこれを1～150Mの間で設定することが可能。なおメッセージサイズに関する値については変更されることもありうる[^1]ため、最新情報は以下を当たると良い。

- [Exchange Online の制限 \- Service Descriptions \| Microsoft Docs](https://docs.microsoft.com/ja-jp/office365/servicedescriptions/exchange-online-service-description/exchange-online-limits?redirectedfrom=MSDN#message-limits)


## メッセージサイズ制限の変更方法

　3つあるためそれぞれについて記載。


### 既定のメッセージのサイズ制限変更
1. Exchange管理センターより、「受信者」→「メールボックス」→「……」→「既定のメッセージのサイズ制限を設定」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/087bb6f0-dc9d-efc6-7dbf-55043333685e.png)

2. 次に表示される画面で既定のメッセージのサイズ制限が可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/c59adf32-5b58-669d-31cd-1a089dddfb68.png)


### 2. 個々のメールボックスの設定を変更
　[メールボックスのメッセージ サイズ制限を構成する \| Microsoft Docs](https://docs.microsoft.com/ja-jp/exchange/recipients/user-mailboxes/mailbox-message-size-limits?view=exchserver-2019)に詳しい。
　例えば、規定のサイズは10Mだが、管理職などは20Mにする、などの設定とする場合はこちらの設定から変更すると良い。


### 3. ルールによる変更
1. Exchange管理センターより、「メール フロー」→「ルール」→「＋」→「サイズによってメッセージをフィルタリングする…」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/2cd30da5-0ccb-956c-2d46-e217702f3155.png)

2. 以下のようなウィンドウが表示されるため、上限サイズを決め、「メッセージをブロックする」→「メッセージを拒否してその説明を加える」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151198/a35668d3-0cd0-9a7a-f686-ebe914c9672a.png)




## 参考
- [Exchange Server でのメッセージサイズと受信者の制限 \| Microsoft Docs](https://docs.microsoft.com/ja-jp/exchange/mail-flow/message-size-limits?view=exchserver-2019)
- [Exchange Online のメール フロー ルール \(トランスポート ルール\) \| Microsoft Docs](https://docs.microsoft.com/ja-jp/exchange/security-and-compliance/mail-flow-rules/mail-flow-rules)

[^1]: [Office 365は、最大150MBのより大きな電子メールメッセージをサポートするようになりました\-Microsoft365ブログ](https://www.microsoft.com/en-us/microsoft-365/blog/2015/04/15/office-365-now-supports-larger-email-messages-up-to-150-mb/)
React Native Paperをimportしたときのオーバーロードエラー

# 詰まった点

React-native-paperをimportして使おうとするとオーバーロードがないというエラー

```
{
	"resource": "/Users/hoge/Desktop/fuga/src/components/screens/MyPageScreen.tsx",
	"owner": "typescript",
	"code": "2769",
	"severity": 8,
	"message": "この呼び出しに一致するオーバーロードはありません。\n  2 中 1 のオーバーロード, '(props: Pick<Props, \"ref\" | \"style\" | \"removeClippedSubviews\" | \"hitSlop\" | \"onLayout\" | \"pointerEvents\" | \"testID\" | \"nativeID\" | \"collapsable\" | \"needsOffscreenAlphaCompositing\" | ... 49 more ... | \"elevation\"> & { ...; }, context?: any): ReactElement<...> | ... 1 more ... | null' により、次のエラーが発生しました。\n    型 '{ children: Element; }' には 型 'Pick<Props, \"ref\" | \"style\" | \"removeClippedSubviews\" | \"hitSlop\" | \"onLayout\" | \"pointerEvents\" | \"testID\" | \"nativeID\" | \"collapsable\" | \"needsOffscreenAlphaCompositing\" | ... 49 more ... | \"elevation\">' からの次のプロパティがありません: accessibilityComponentType, accessibilityTraits\n  2 中 2 のオーバーロード, '(props: PropsWithChildren<Pick<Props, \"ref\" | \"style\" | \"removeClippedSubviews\" | \"hitSlop\" | \"onLayout\" | \"pointerEvents\" | \"testID\" | \"nativeID\" | \"collapsable\" | \"needsOffscreenAlphaCompositing\" | ... 49 more ... | \"elevation\"> & { ...; }>, context?: any): ReactElement<...> | ... 1 more ... | null' により、次のエラーが発生しました。\n    型 '{ children: Element; }' には 型 'Pick<Props, \"ref\" | \"style\" | \"removeClippedSubviews\" | \"hitSlop\" | \"onLayout\" | \"pointerEvents\" | \"testID\" | \"nativeID\" | \"collapsable\" | \"needsOffscreenAlphaCompositing\" | ... 49 more ... | \"elevation\">' からの次のプロパティがありません: accessibilityComponentType, accessibilityTraits",
	"source": "ts",
	"startLineNumber": 23,
	"startColumn": 8,
	"endLineNumber": 23,
	"endColumn": 12
}
```

# 解決策
https://github.com/callstack/react-native-paper/issues/2442#issuecomment-747366550
同様の問題がissueに上がっていて

`yarn add @types/react-native@0.63.40 --dev` で別のバージョンの型定義ファイルを入れことで解決
【最新】Google画像検索を保存するPythonライブラリの使い方＆ChromeDriverをubuntuで使う

あけましておめでとうございます。

結構知ってる人が多いとは思いますが私が何度も迷うので書き留めておきます。
機械学習の際の学習データにご利用ください。

2020年8月ごろ？に検索結果の提供方法が大きく変わったらしく、Windows用ソフトの「ImageSpider」が使えなくなりました。（結構便利だったんですけどね...）
そこでこれからはPython用ライブラリの**「google_images_download」**を使うことにしました。

## インストール

### **【注意】pipではインストールしないでください！**

```
pip3 install google_images_download
```

PIPにあるバージョンではGoogle側の変更に対応できていないため、インストールしても使えません。
なので直接インストールします。

```
git clone https://github.com/Joeclinton1/google-images-download.git
cd google-images-download && sudo python setup.py install
```

これでインストールは終わりです。

## 使い方
ここでは代表的な使い方としてコマンドライン上での利用方法を載せておきます。

```
 googleimagesdownload --keywords "apple" --limit 20
```

上記の例だと「**apple**」の検索結果を**20件**、カレントディレクトリに保存します。
Python上での使い方やその他の条件設定等は**[公式ドキュメント](https://google-images-download.readthedocs.io/en/latest/examples.html)**を見てください。

## 100件以上を取得する場合
取得したい画像が100件を超える場合は**chromedriverをインストールする必要があります。**
※Ubuntu20.04 LTSでの操作方法です。Windowsの場合は各自お調べくださいm(_ _)m

**まずドライバの最新バージョンを確認**
以下のサイトに行って最新版の「chromedriver_linux64.zip」のURｌをコピーしてください。
https://sites.google.com/a/chromium.org/chromedriver/downloads 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/4e20cd19-66d6-e611-a9ba-6756c5cbce20.png)
因みに2021年1月6日現在はhttps://chromedriver.storage.googleapis.com/88.0.4324.27/chromedriver_linux64.zip でした。

**次に以下のコマンドを続けて入力してください。**（[こちら](https://qiita.com/pyon_kiti_jp/items/0ba98f140142d4ac6b25)の記事を参考にさせていただきました。）

```
sudo apt install unzip
cd /tmp/
curl -O <<<<<ここにさっき確認したURLを入れる>>>>>
unzip chromedriver_linux64.zip
mv chromedriver /usr/local/bin/
rm chromedriver_linux64.zip
```

これでインストールは以上です。

**100件以上取得する際のコマンド**

```
googleimagesdownload --keywords "apple" --limit 120 --chromedriver /usr/local/bin/chromedriver
```

さっき紹介したやつに --chromedriver オプションでインストール先を選択するだけです。


↓取得結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/e9e54eff-1e66-0dac-8493-4991b38aabc5.png)

ちゃんと取得できていますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/c480aa7b-4fdb-a06c-6303-05855db87fef.png)
Dockerについて雰囲気でまとめてみる

Qiitaではわかりやすい記事がたくさんある中で、
簡単にDockerについて書こうと思います。初投稿なので甘めに見てください。


##Dockerとは何か

Dockerとは
コンテナ型仮想環境を作成、実行、管理の３つのプロセスを行うためのプラットフォームである。

　→コンテナ型仮想環境とは？
　　　まずコンテナは、みんなが想像する船で運ぶ箱とイメージは一緒。仮想環境とは、その名の通り仮想的な環境のこと。もっとくだけて言うとパソコンの中に、環境を構築したソフトウェアがサーバーの中でひとつ宙に浮いてる。みたいなイメージですかね。それがコンテナみたいにいくつもの箱があって、それを１台のハードウェアで複数あるコンテナごとに動作、実行ができる。それがコンテナ型仮想環境。

なにが便利なのかと言うと、コンテナ型仮想環境（今回はDocker）を使うことで、コンテナの中で作った環境を素早く起動することができて、かつ複数のアプリケーションを実行することができるということ。
最大の利点は、仮想的な環境を作っているので、WindowsやMacなど、異なるOSのPCから同じ条件で中身を動かせると言うこと。OSの違いによる実行環境の不具合がなくなることが嬉しいポイントではないか。

ここでメリットを少しまとめてみる。

##Dockerのメリットは何か

・実行環境を構築しているので、プログラムの起動が早い
・開発環境と本番環境での差をなくせる
・ファイルの共有で同じ環境を立ち上げることができる
・自信のPCの中身を構築するわけではないので、ソフトウェアのインストールなどしなくてもよい

などがある。

##Dockerにまとわりつく用語集
###Dockerイメージ
　Dockerイメージとは、コンテナを作成するにあたって必要な「土台」を総じてこう呼ぶ。
コンテナのマトリョシカ的なイメージで、アプリケーションを実行する際に必要な設定やライブラリがまとめて入ってるもの。
これを別のサーバーに渡すとそのまま再現できる。

###Dockerコンテナ
Dockreイメージを作成するとコンテナになる。
このコンテナを実行すると中のDockerイメージに設定した機能を呼び起こせる。
Dockerイメージはあくまでイメージ、よし、実際にやろう!ってなるとコンテナになる。（適当）

###DockerHub
　GitHubを想像してもらえるとわかりやすいと思う。
なんかどっかのサイトでまずはDockerHubのユーザー登録をします。みたいなところから入ったので最初は本当にわからなかったけどとりあえず登録した記憶。（騙されやすい）
Dockrerイメージは保存して自由に受け渡しができるのでそれを保存してみんなに配ってるサービス。
様々なユーザーが作ったイメージをDLして保存できるので、実行するだけでコンテナが起動できる、ライブラリと同じ感じかな。
GitHubもクローンして己のリポジトリに保存できるじゃん？そんな感じ。

こういった保管の機能を持ったサービスや場所のことをレジストリというらしい。覚えよう。

###Dockerエンジン
コンテナの仮想化を実際に行うために役割。
車と一緒で、箱だけあっても動力ないと進まないよね、みたいな感じだと思う。
Dockerエンジンによってコンテナ作成や起動や停止や削除などの機能が使える、程度の認識でいいと思う。

###Dockerデーモン
強そう。常駐型のプログラムといわれるもの。
コンテナの作成やDockerイメージの作成など、操作や命令はDockerデーモンが受け取って処理をする。
伝言ゲームの最後の人みたいな位置で、仮想化したソフトウェアの中にいる人。この人がしっかり準備してないと処理を実行してくれない。

もし停止していたら起動しておく必要がある。

###Dockerクライアント
クライアントソフトのこと。
Dockerコマンドをつかって指示を出す人。そのまんま。



##まとめ

とりあえずDockerというなの付く単語の説明だけでしたが、
学習したばかりの浅い知識なので、誤りの箇所もあるかと思います。
その際はキツめに言っていただければと思います。

後日、Dockerコマンドの解説やDockerファイルやホスト型仮想化の違いなど細かい部分もまとめられればいいなと思います。
ありがとうございました。
terraformで入れ子の値を無視（ignore_change）する方法


# ignore_changes 基本的な使い方

terraformで、特定の項目をterraformで管理したくない場合、`lifecycle`の`ignore_changes`が使えます。

[The lifecycle Meta\-Argument \- Configuration Language \- Terraform by HashiCorp](https://www.terraform.io/docs/configuration/meta-arguments/lifecycle.html#ignore_changes)

ドキュメントからの引用ですが、これが基本的な設定の仕方になります。

```terraform
resource "aws_instance" "example" {
  # ...

  lifecycle {
    ignore_changes = [
      # Ignore changes to tags, e.g. because a management agent
      # updates these based on some ruleset managed elsewhere.
      tags,
    ]
  }
}
```

# 入れ子の場合

では、入れ子の（nested）な値の場合はどうすれば良いのでしょうか？

例えば、

```terraform

resource "aws_eip" "test" {
  tags = {
    test = "testValue"
  }
}
```
の `tags.test` をignoreしたい場合です。

これはドキュメントに記載がありまして、

>  The arguments are the relative address of the attributes in the resource. Map and list elements can be referenced using index notation, like tags["Name"] and list[0] respectively.

```terraform

resource "aws_eip" "test" {
  tags = {
    test = "testValue"
  }

  lifecycle {
    ignore_changes = [
      tags["test"],
    ]
  }
}
```

で、ignoreされるようになります。

# 入れ子の場合の落とし穴

で、ここからが本題なのですが、`ignore_change`したい場面で考えられるのが、先にコンソールから手動で値を設定した場合です。

具体例を挙げると、画面から↓の様にtagを新たに追加して、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32169/296f4dda-3d9b-bd29-94fd-7768d67c27c5.png)

terraformではこうなっている時です。

```terraform

resource "aws_eip" "test" {
  tags = {
    Name = "名前"
  }
}
```
この状態で、`terraform plan`をすると、まだignore設定をしていないので、差分が表示されます。

``` terraform
      ~ tags                 = {
            "Name"                           = "名前"
          - "test"                           = "testValue" -> null
        }
    }
```

なので、ignore_changeを追加します。

```terraform

resource "aws_eip" "test" {
  tags = {
    Name = "名前"
  }
  lifecycle {
    ignore_changes = [
      tags["test"], // 追加
    ]
  }
}
```

ぱっと見よさそうですが、実はこれでは `ignore_changes` がうまく扱われずに、まだ差分があると認識されてしまいます。


正解はこうです。


```terraform

resource "aws_eip" "test" {
  tags = {
    Name = "名前"
    test = "" // これが必要
  }
  lifecycle {
    ignore_changes = [
      tags["test"],
    ]
  }
}
```

`ignore_changes` で指定している値を、resourcesに実際に書いてあげる必要があります。値自体は無視されるので、内容はなんでも良いです。keyが（例だと`test`）が設定されている必要があります。



# 補足

`Terraform v0.13.5` で動作確認しました。
smallタグの正しい使い道を考える

# どうも7noteです。HTMLには様々なタグがありますが、そのなかでsmallタグの使い道について考察します。


そして独自で出した結論としては・・・

***「正直、コピーライトでしか使わないと思う。」***

これが私なりの結論です。
**文字サイズを小さくしたい時には絶対に利用しない**。

## smallタグの説明文


> 『`<small>` …… 免責・警告・著作権などの注釈や細目を表す』
>引用元：HTML5タグリファレンス（http://www.htmq.com/html5/small.shtml）

またこのようにも書いています。

> 『`<small>`はメインコンテンツではなく、あくまで注釈や細目などの短いテキストに使用する要素です。
`<small>`を複数の段落、複数のリスト、複数のセクションなどの長いテキストに対して使用するべきではありません。』
引用元：HTML5タグリファレンス（http://www.htmq.com/html5/small.shtml）

ほかのサイトではこのように説明されています。

>『HTML の `<small>` 要素は、表示上のスタイルとは関係なく、著作権表示や法的表記のような、注釈や小さく表示される文を表します。』
引用元：MDN Web Docs（https://developer.mozilla.org/ja/docs/Web/HTML/Element/small）


## smallタグの使い道

一般的に一番使われている箇所は**コピーライト**ではないかと思います。
逆にコピーライト以外でsmallタグを見かけることがほぼありません。

```index.html
<small>© 2011 hogehoge Inc.</small>
```

※コピーライトの書き方については[コチラ](https://qiita.com/7note/items/7ff818c2e37405c985fb)

とはいえqiitaやmdnのサイトを見ると別に`<small>`タグを使っていません。
つまりは**使わなくてもなんの問題もない**と思って大丈夫でしょう。

一応紹介されている使い方としては、文章の注釈としていれる使い方も間違いではなさそうです。

```index.html
<p>なんと、おにぎりの具の量3倍！！！<sup>※</sup></p>
<small>※自社比較</small>
```

さらっと`<sup>`を使っていますが、sup要素は上付き文字に使います。
http://www.htmq.com/html5/sup.shtml

このように文中で入れる注釈は`<sup>`等が使われるので、その注釈の内容を表すのに`<small>`が使えなくもない・・・


## でも結局`<div>`や`<p>`で書いてもなんの問題もない。


結局は、smallタグを使うメリットがないのが痛いところですね。
正しいタグを使う方がSEO的には正しいのかもしれませんが、おそらく<small>タグじゃなくdivやpで書かれていたとしても何も影響はないと思います。

## まとめ

ほんとに使いどころのない要素なのかも。

`<span>`を2重にしたくないからかわりに`<small>`を使うのは使い方的には間違っていますし、`<small>`タグの代わりにpやdivでも問題ないのなら好きな方を使えばいいかなと思います。
私はいろいろなタグを使ってる方が識別しやすいので、コピーライトだけは`<small>`を使おうかなと思います。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
Windows10でECLをビルド



## はじめに
ECL(Embeddable Common Lisp)ってWindows上でも動くらしいけど実際使えるのかな？　ということで試してみました。結果、対話環境は問題なく起動しました。マニュアルに書かれていないyasmなどのツールを用意しておく必要があったので、メモとして残しておきます。

## ECLのバージョン
現在ECLは2020年の4月にメジャーアップデートがあり、[バージョン20系](https://common-lisp.net/project/ecl/posts/ECL-20424-release.html)がリリースされているので、それを使います。

## ビルド環境

- Windows10
- Visual Studio Community
- Windows SDK
- yasm

Visual Studioをインストールし、Visual C++ 2015 x64 Native Build Tools Command Prompt(以下Command Prompt)というプログラムが実行可能になっているかを確認します（スタートメニューにあるはず）。

次に、rc.exeというコマンドを使うため、Windows SDKのbinディレクトリをPath環境変数に登録します。自分の環境だと、次の場所を登録しました。

```
C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x64
```

最後にyasmを使うためインストールします。これはGitHubの[https://github.com/cseri/yasm-1.3.0-win64](https://github.com/cseri/yasm-1.3.0-win64)からexeファイルをダウンロードできるので入手し、Pathの通ったディレクトリに配置します。

事前の準備はこれで完了です。

## ビルド実行

[https://common-lisp.net/project/ecl/static/files/release/](https://common-lisp.net/project/ecl/static/files/release/)からecl-20.4.24.tgzをダウンロードし展開します。展開するとmsvcディレクトリがあるため、Command Promptを起動し、ECLのソースコードを展開した場所のmsvcディレクトリ移動します。

```
> cd C:\Path\to\ecl-20.4.24\msvc
C:\Path\to\ecl-20.4.24\msvc>
```

ビルドにはnmakeコマンドを使用します。prefixの値でインストール先を変更できます。

```
C:\Path\to\ecl-20.4.24\msvc> nmake install prefix=C:\tools\ecl2 ECL_WIN64=1 GMP_TYPE=AMD64
```

途中で失敗する場合には、rc.exeやyasm-1.3.0-win64.exeの存在するディレクトリがPathに登録されているかを確認してみてください。

インストールが完了すると、ecl.exeという実行ファイルと、実行に必要なファイルが生成されます。

ecl.exeを起動し、ECLのREPLが起動すれば完了です。


## インストーラーを作成する

[NSIS](https://nsis.sourceforge.io/Download)を使ってWindows用のインストーラーを作成できると書いてあったのでそれも試してみます。NSISをインストールし、```C:\Program Files (x86)\NSIS\Bin```にパスを通しておきます(makensis.exeを使用するため)。

その後、次のコマンドでインストーラーを作成できます。

```
C:\Path\to\ecl-20.4.24\msvc> nmake windows-nsi
```
msvcディレクトリにecl-20.4.24.exeという名前でインストーラーが作成されます。ダブルクリックでインストーラーが起動し、インストール先の選択とインストールが問題なく行われることを確認します。

REPL環境の起動は確認できましたが、色々なパッケージが正常に動くかどうかは確認していません。今後Windowsで何か試すときがあれば確認してみたいと思います。