OmniAICreator/Qiita-1.07M huggingface dataset:
個人開発ぐうたら日記２　～素材集め編～

# 前回のあらすじ
ひょんなことから、また個人でゲーム開発することを決めた。
基本的なゲーム内容は以下の通り。

- **空から食材が降ってきて、その中からフルーツを集めるゲーム**
- **柑橘系をゲットするとボーナスポイント**
- **野菜をゲットするとマイナスポイント**

# 素材集め
最低限どんなゲーム内容にするかを決めたら、次はゲームに使う素材を洗い出してみる。
ただしこれも「**最低限**」。
というのも、どうせこの後ゲームの機能は増えていくのだから、必要な素材は随時集めていけばいい。
今回の場合、ゲーム内容に対して最低限必要な素材は

- 通常フルーツの画像
- 柑橘系フルーツの画像
- 野菜の画像
- プレイヤーの画像

この4つである。
特にプレイヤーは無機物、有機物にするかすら決めていないので難航するかと思われた。
が、適当に「鳥　イラスト」とか検索していたら、安定のいらすとや様でいい素材が見つかった。

![bird_aoitori_bluebird.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/56f71e76-f956-e5b3-4b6d-c1c4b0e19bb3.png)


>出典：[いらすとや「青い鳥」の検索結果](https://www.irasutoya.com/search?q=%E9%9D%92%E3%81%84%E9%B3%A5)

しかもこれ、[燃え上がる鳥](https://www.irasutoya.com/2016/01/blog-post_888.html)や[氷漬けの鳥]
(https://www.irasutoya.com/2017/09/blog-post_567.html)の素材もあり、これらも使えそうである。
今は深く考えないが、野菜を受け付けなくなるブーストモードとか一部の食材以外を跳ね返すかちんこちんモードとか実装したら面白そう。

こんな感じで素材から妄想しつつも、画像を集めていく。
もう全部いらすとやでええやん！？となるが、どっこいそうもいかない。
なぜならいらすとや様の素材は「1つの制作物につき20点までしか無償利用できないから（商用利用の場合）」である（参考：[ご利用について](https://www.irasutoya.com/p/terms.html)）。

アプリ制作に限らず、**画像や音声などのフリー素材をネットから探して使う場合、必ず利用規約をまず参照しなければならない。**

いらすとや様のように点数制限がある場合もあれば、クレジット表記の有無、加工OK/NGなどなどサイトによって異なる。
利用規約を熟読してから素材をダウンロード、使用するようにしよう。

そんな感じでネットを徘徊しつつ、紆余曲折あって何とか各画像を集めることができた。
こんな感じである。

- 通常系・柑橘系フルーツの画像
![fruit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/b9e5e7c1-70ef-3d83-b95f-3f76b6663181.png)

- 野菜の画像
![vegetable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/2364b11b-1c21-3707-33e3-451b49ca751c.png)

- プレイヤーの画像
![player.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/7b5b5b9a-90f7-959b-166d-9634d4cdc43a.png)

どこが「最低限」やねんという話だが、ごもっともだ。
集めるにつれて楽しくなってしまい、量がすごいことになってしまった。
また一部、突っ込みたい素材画像もあるかもしれないが、目を瞑っていただけると嬉しい。
なお、ファイル名は分かりやすいようにオリジナルから変更している。

# ざっくり、本当にざっくりした画面イメージ
最低限？の画像素材も集まったので、**次は画面イメージを簡単に組み立ててみる。**
XDとか使えないので、パワポで。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635329/25869e25-6b2b-80a0-d3fb-58100c2a1a18.png)

手抜きでかなりシュールだが、イメージこんな感じである。~~XDとか口にした自分が恥ずかしい。~~
もはや作る意味すらあったのか謎である。

**画面イメージがざっくり決まったら次は最低限の「機能」を考える。**
ゲームの骨子とも言える部分で、実装はまずここから入ってそれをベースに肉付けしていく。

上記の画面イメージを機能ベースで簡単にまとめてみると、

- **プレイヤーは指によって自由に画面内を動かすことができる**
- **画面上からフルーツや野菜などの食材が降ってくる**
- **プレイヤーが食材に接触すると食材が消える**

こんなものか。
プラスポイント、マイナスポイントについては自機やスコア周りをまだ何も考えてないので、一旦置いておく。
今回はここまで。ちょっとずつ楽しくなってきた。

# 次回予告
次回はいよいよ実装に入る。
先ほど出した機能ベースで、1つずつ作っていく予定である。
どちらかといえば、UnityやC#の技術ブログっぽくなるかもしれない。
Macで RubyMine を起動したときに 「Java 11 or newer is required to run the IDE」というエラーが出たときの解決方法

# 解決方法
起動しようとしている RubyMine の jdk ファイルを削除してください

例

```shell
rm ~/Library/ApplicationSupport/JetBrains/RubyMine2020.3/rubymine.jdk
```


参考:
[Selecting the JDK version the IDE will run under](https://intellij-support.jetbrains.com/hc/en-us/articles/206544879-Selecting-the-JDK-version-the-IDE-will-run-under)
2월14일



사스에 대해서 사용은 하고 있었지만 사스의 기술을 제대로 활용하지는 못하고 있었다.
그래서 사스관련 소스를 볼때마다 조금 헷깔렸었는데 오늘 react를 공부하는 과정에서 사스에 대해서
다시 공부해볼수 있었고 이제 조금은 원리에 대해서 알것 같다.

우선 첫번째 단계는 가까스로 완료한것 같다.

이제 실전이다.
Oracle Analytics Libraryの拡張方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/fecf843e-e736-b936-519b-d19ee6c62f14.png)

オラクルアナリティクスの拡張機能をご存知でしょうか。
デフォルトのグラフ以外でよりCOOLな見やすいグラフィックが可能になります。
拡張の仕方もだいぶ簡単なので是非やってみましょう。

## 今回やること
オラクルのアナリティクスクラウドで、可能なBI描写を追加するために、ライブラリからアドオンモジュールをダウンロードしてOAC（Oracle Analytics Cloud）にアドオンします。
要はOACの機能拡張を行います。


## OACにアドオンする方法
ここからlibraryに飛びます
https://www.oracle.com/jp/business-analytics/data-visualization/extensions.html

### ライブラリからとりあえず使ってみたいものをダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/ba837726-23d3-3096-7d53-45681041fb5e.png)


利用規約的なものが出てくるのでアクセプトするとzipファイルがダウンロードできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/a255006f-1935-b945-d89c-6de4cf38ee00.png)

### オラクルアナリティクスを開きます。
ここはOAD(Oracle Analytics Desktop)でもOAC(Oracle Analytics Cloud)でも同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/20cd23cb-79e2-4441-b356-bd83d5396989.png)
コンソールを開き、この拡張機能のアップロードに先ほどのzipファイルをドラッグ＆ドロップで入れると追加されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/f9ba6ab1-1e9c-bfd5-bfa4-125a1d2d66bd.png)

#### ※OADの場合、再起動（アプリを一回閉じて、再度開く）が必要です

OACの場合はリアルタイムで読み込んでくれるかもしれませんが
少なくともOADでは再起動が必要でした。


### そうすると、通常のグラフ選択のところにアドオンしたグラフが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/a676805b-4080-ec44-db08-eddbea9b75c9.png)

このアドオンではカレンダー別でこんな表現ができるようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064900/3d72ccab-0d59-dc2a-bad9-488ba44f1d7e.png)

以上で設定は終わりです。
これで使いたいグラフをどんどん追加していくことが出来ます。
jQueryで要素の属性を指定する方法 attr()

```index.html
<a>リンク</a>
```
aタグに対してリンク先をjQueryで動的に選択したい場合は　attr()を使います。

```main.js
$('a').attr('href','./sample.html');
```

このように書くと動的にhref属性を指定することができます。
また、このattr()ではhref以外の属性も指定が可能で
例えばid属性も指定することができます。

```main.js
$('a').attr('id','link');
```

複数の属性を指定することも可能です。
その場合はオブジェクト型で指定してあげれば大丈夫です。

```main.js
$('a').attr({
  id: 'link',
  href: './sample.html',
  name: 'sample'
});
```

このように書いてあげると自由に属性値を指定してあげることができます。
ぜひ使ってみてください！
【Swift】UILabelに取り消し線を引くには

# はじめに
アプリ開発をしていく中で、UILabelに取り消し線を表示させたいと思い調べたのでご紹介します。

# 開発環境
- macOS Catalina version10.15.7
- Xcode version12.2
- Swift5

# NSMutableAttributedString
取り消し線を実装するには、`NSMutableAttributedString`を使用します。

### NSMutableAttributedStringとは？
NSMutableAttributedStringは、属性付きの文字列コンテンツを変更するための追加メソッドを宣言しているクラスとのこと。このクラスを用いて、属性の変更（今回であれば、取り消し線の追加）を行う。

属性の追加は、`addAttribute()`を使用する。このメソッドより、どういった属性を対象の文字列のどの範囲に追加するかを設定する。

参考
[NSMutableAttributedString](https://developer.apple.com/documentation/foundation/nsmutableattributedstring?language=occ)
[addAttribute:value:range:](https://developer.apple.com/documentation/foundation/nsmutableattributedstring/1417080-addattribute?language=occ)


#実装と解説
全体コード

```swift
let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: "対象の文字列")
            
attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: 2, range: NSMakeRange(0, attributeString.length)) 
            
Label.attributedText = attributeString
```

---

```swift
let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: "対象の文字列")
```
こちらの処理で、NSMutableAttributedTextを宣言している。

---

```swift
attributeString.addAttribute(NSAttributedString.Key.strikethroughStyle, value: 2, range: NSMakeRange(0, attributeString.length)) 
```

こちらの処理で属性を追加している。addAttribute()メソッドを用いて、追加したい属性や適用範囲を指定する。
addAttribute()メソッドでは3つの引数を指定する。

・name：属性名を指定する
属性名に関しては、今回テキスト属性を指定するため`NSAttributedStringKey`を使用する。その中で、取り消し線を実装したいため`strikethroughStyle`を指定する。

・value：属性値を指定する
初期値が0で、数値を大きくすると取り消し線の太さが太くなる。

・range：対象の文字列への適用範囲を指定する
今回は、対象の文字列全体に取り消し線を追加したいため`NSMakeRange()`を用いて文字列全体を範囲として指定している。


参考
[strikethroughStyle](https://developer.apple.com/documentation/foundation/nsattributedstring/key/1529956-strikethroughstyle)
[NSAttributedTextやNSMutableAttributedTextの使い方](https://jprogramer.com/iosandcocoa/3590)

---

```swift
Label.attributedText = attributeString
```

最後に属性付きの文字列を、UILabelに反映させてあげれば完了。

こんな感じになります。
![スクリーンショット 2021-02-11 16.47.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381376/2606bfee-2241-5494-dd56-2c145689a5a6.png)


# まとめ
今回は、取り消し線を実装するにあたり調べてみたことをまとめてみました。

以上
【Slack】【esa.io】研究室改善活動あれこれ

以前こんなツイートが話題になっていたので、研究室の改善活動で行ったあれこれを書いてみた。
<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">良い研究室のヒミツ <a href="https://t.co/yGKK10zvdT">pic.twitter.com/yGKK10zvdT</a></p>&mdash; 森野キートス (@ki1tos) <a href="https://twitter.com/ki1tos/status/1338797538845941762?ref_src=twsrc%5Etfw">December 15, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# やったこと
研究室に[Slack](https://slack.com/intl/ja-jp/)と[esa.io](https://esa.io/)を導入した。

# 背景
元々私が所属していた研究室では、連絡ツールとしてGmailを、研究室の共有ドキュメントとしてLaTeXで作成したPDFを使用していた。（2019年時点）
インターン先の企業でチャットツール（Slack）とドキュメント共有ツールを使っていたことがきっかけで、研究室内の情報共有を加速させたいと思っていた。

# 導入前
研究室のGmailによるコミュニケーションに関して、気軽に研究に関する議論ができない、論文紹介が手間などの問題があった。
研究の議論は直接話しても良いしその方が深く議論できることもあるが、テキストで済む分には可能な限り議論の内容や知識を共有したいと思っていた。

また、LaTeXに関しても情報が探しずらい、気軽にドキュメントを書けないなどの不満があった。

## ツール選定
他システムとの連携が容易で使い勝手が良かったチャットツールとして、Slackが人気でありかつ**無料**で使用できたのでSlackを選んだ。
<font color="DarkGray">（当時はMS TeamsがSlackをここまで引き離すとは思っていなかった…）</font>

ドキュメント共有ツールの選定は割と悩んだ。
[PukiWiki](https://pukiwiki.osdn.jp/)（昔から他研究室でよく使われているイメージがある）や[Knowledge](https://information-knowledge.support-project.org/ja/)、[Kibela](https://kibe.la/)なども検討したがPukiWiki、KnowledgeはOSSでカスタム性が高いが、研究室にサーバを立てなければならないのでサーバ管理の知識が必要+学生にサーバ管理の手間を増やしたくないということで除外。
KibelaはSaaSでサーバ管理が不要だが無料で使える範囲が5人までだったため選ばなかった。
一方esa.ioはSaaSでありかつ、[アカデミックプラン](https://docs.esa.io/posts/129)（教育機関で使う分には実質無期限で**無料**）という素晴らしいプランがあったため、esa.ioを選んだ。

## 導入にあたって
esa.ioはもちろん今ではかなり有名になったSlackも研究室内では知っている人が限られている状況であり、知らないものを必要か聞くのも難しいため、人数を絞って導入した。（Slack→esa.ioの順で導入した）
結果かなり使いやすかったため、先生に話をつけて研究室全体に導入した。

ちなみに当たり前だがチャットツールは全員が参加して全員が通知に気付かないと全体連絡ができず、ツールとして用を為さない。
<font color="DarkGray">メールで招待しても参加しない人が研究室に来るタイミングで捕まえて参加させるのが大変だった、、、</font>

# 導入後
Slackで論文を紹介するのがかなり気軽にできるようになった。また、ちょっとしたプログラミング関係のTipsも共有できるようになったので良かったと思う。

esa.ioについてもMarkdownで書きやすくなった。階層構造によって一部のメンバーに関係する記事も書くことができ、かなり気軽にドキュメントを書けるようになったと思う。
（Incoming WebhookでSlackと連携して、esa.ioドキュメントを更新したらSlackに通知が飛ぶようにしているので承認欲求も満たせる）

現在も新型コロナウイルスの影響による在宅化も相まって、特にSlackがかなり使われている様子だった。

# 導入できなかったこと
研究室のコードをちゃんと管理したかったのでGitLabを導入したかったが、自分のGit・GitLabへの知識が薄く、導入・布教まで到底できそうになかったので導入しなかった。

# 反省点
各種ツールの利用のためのルール・ガイドラインを整備するべきだった。口頭でしか使い方を伝えていなかったので、多いに反省。
のちに後輩がガイドラインを作ってくれたので感謝しかない。

# 課題・問題点
無料プランではSlackのメッセージが1万件までしかストックされないので、導入から1年足らずでオーバーしてしまった。。。
バックアップを取るなど[対策](https://katblog.manadream.net/index.php/2019/05/09/slack-free-message-count/)が必要かもしれない。（~~有料プラン使いたい~~）

加えて、研究室の合意形成が難しかったという問題もあった。
基本的に指導教員が一番偉いのでそこに許可を取りに行くわけだが、他の学生にも合意を取らなければならないのでスマートな合意形成プロセスがほしいと感じた（独りよがりにならずに導入するのが難しかった）。。。

# 最後に
こうしたツールの研究室における運用に関する記事はまだまだ少ないように思えるので、自分の研究室の事例やノウハウをコメントで共有して頂けるとありがたいです！！

# 参考
- [研究室にSlackを導入するまで](https://qiita.com/hrkd1316/items/9ec709abc4760548c11a)
- [研究室Slack化のすすめ](https://qiita.com/nkchan/items/04ae0f0cdc61346cd804)
RasPi 3B+ から FPGA を簡単にコンフィグレーションする (分割ダウンロード編)

#はじめに
前回の記事

[RasPi 3B+ から FPGA を簡単にコンフィグレーションする (Xilinx Artix-7編)]
(https://qiita.com/kan573/items/efa1261b163395bdd304)


で解説した spidev_test で設定可能なバッファサイズは、4MB まででした。

引数指定してダウンロードした top.bin は 3.7MB で、バッファに収まります。

FPGA のコンフィグレーションデータは、搭載ロジック量に比例して大きくなりますので、将来もっと大きなデバイスに、大きなデータをダウンロードしたくなります。

spidev_test を改造してバッファサイズを変更できればよいのですが、ハード屋の私はソフトさっぱりわかりませんので、別の方法を検討します。


#FPGA のダウンロードデータの大きさ
Vivado の Webpack ライセンスで使用できる FPGA は、下記の通りです。
このうち、XC7K160T や XC7A200T は、ali で安価に入手できますので、アマチュア利用でも検討する余地があります。
(UG973 表1)
![webpack_device.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/a476c5d4-0d33-b558-935a-c5d3593cb64f.png)

Webpack で使える Xilinx 7 シリーズ FPGA のコンフィグレーションデータの大きさは、下記の通りです。
(UG470 Table 1-1)
![UG470 Table 1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/a8146b9a-2859-eaa2-694a-a6020f647e70.png)

XC7K160T で 5.2MB、XC7A200T で 7.6MB あります。
バッファサイズの上限 4MB を超えています。
これをダウンロードできないものでしょうか？

#CLK/DATA が途中で停止してもよい？

前記事
[RasPi 3B+ から FPGA を簡単にコンフィグレーションする (Xilinx Artix-7編) #RasPiからのダウンロード]
(https://qiita.com/kan573/items/efa1261b163395bdd304#raspi-%E3%81%8B%E3%82%89%E3%81%AE%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89)

では、Slave Serial コンフィグレーション中に CLK/DATA が途中で一時停止しても、エラーにならない事がわかりました。

これを積極的に利用して、top.bin ファイルを分割して、複数回に分けてダウンロードする事を試してみます。

前回作成した top.bin ファイルを 2 つに分割します。


```
pi@raspberrypi:~$ split -n 2 -d top.bin top.bin
```

実行すると、ちょうど半分で分割され、top.bin00 と top.bin01 という２つのファイルができました。

これをダウンロードしてみます。

```
pi@raspberrypi:~$ ./spidev_test -D /dev/spidev0.0 -i top.bin00 -s 50000000
pi@raspberrypi:~$ ./spidev_test -D /dev/spidev0.0 -i top.bin01 -s 50000000
```

問題なくダウンロードが完了して D1 が点灯し、HDMI 出力にカラーバーが現れました。


試しに、

```
pi@raspberrypi:~$ ./spidev_test -D /dev/spidev0.0 -i top.bin00 -s 50000000
pi@raspberrypi:~$ ./spidev_test -D /dev/spidev0.0 -i top.bin00 -s 50000000
pi@raspberrypi:~$ ./spidev_test -D /dev/spidev0.0 -i top.bin01 -s 50000000
```

として、前半部を 2 回送り込んでみたところ、ダウンロードに失敗しました。
単純にシフトレジスタに送り込まれて、前の方からシフトアウトされるわけではないようです。


#3 分割ではどうか？
今度は 3 つに分割してみます。

```
pi@raspberrypi:~$ split -n 3 -d top.bin top.bin
```

実行すると、top.bin00 と top.bin01 と top.bin02 という 3 つのファイルに分割されました。

これを 3 回に分けてダウンロードしてみます。

```
pi@raspberrypi:~$ ./spidev_test -D /dev/spidev0.0 -i top.bin00 -s 50000000
pi@raspberrypi:~$ ./spidev_test -D /dev/spidev0.0 -i top.bin01 -s 50000000
pi@raspberrypi:~$ ./spidev_test -D /dev/spidev0.0 -i top.bin02 -s 50000000
```

やはり、問題なくダウンロードが完了して D1 が点灯し、HDMI 出力にカラーバーが現れました。
100MHz で実施しても、結果は同じでした。
4 分割でも問題ないです。

#まとめ
Xilinx Artix-7 へ Slave Serial ダウンロードを行う際、コンフィグレーションファイルを分割して、複数回に分けてダウンロードできることがわかりました。

大きな FPGA へのダウンロードでも、既存のツールを利用して分割でダウンロードできそうです。

Intel (Altera) FPGA でも分割ダウンロードが可能かどうかは、実験していないためわかりません。
Qiitaマークダウン記法 備忘録

初投稿の記事です。
マークダウンの書き方も色々ある中で、よく使うQiitaマークダウン記法をまとめました。
すべてを網羅しているのではないですが、初心者だとこれだけ覚えておけばなんとか記事かけるかな。

# 目次
[1.見出し](#見出し)
[2.文字の装飾](#文字の装飾)
[3.空行と改行](#空行と改行)
[4.番号付きリスト](#番号付きリスト)
[5.リスト](#リスト)
[6.画像の挿入](#画像の挿入)
[7.リンクの挿入](#リンクの挿入)
[8.水平線の挿入](#水平線の挿入)
[9.引用](#引用)
[10.テーブルの挿入](#テーブルの挿入)
[11.コードの挿入](#コードの挿入)
[12.その他](#その他)



# 見出し
` # 見出しh１ `
` ## 見出しh2 `　

> # 見出しh1
## 見出しh2

# 文字の装飾
` *Italic* `
*Italic* 

` **太字テキスト** `
**太字テキスト**

` ~~打ち消し線~~ `
~~打ち消し線~~

` <font color="Red">赤字テキスト</font> `
<font color="Red">赤字テキスト</font>

# 空行と改行  
` 半角スペース２つ 
<br> `

# 番号付きリスト
`1. aaa`
`　1. bbb`
`　2. ccc `
タブで字下げができる

1. aaa
    2. bbb
    3. ccc

# リスト
` * aaa `
`　* bbb `
`　* CCC `
タブで字下げができる


* aaa
    * bbb
    * ccc

# 画像の挿入
` ![代替テキスト](画像のURL) `
` ![Qiita](https://qiita-image-store.s3.amazonaws.com/0/45617/015bd058-7ea0-e6a5-b9cb-36a4fb38e59c.png "Qiita") `
![Qiita](https://qiita-image-store.s3.amazonaws.com/0/45617/015bd058-7ea0-e6a5-b9cb-36a4fb38e59c.png "Qiita")

# リンクの挿入
` [リンクテキスト](URL "タイトル") `
` [Qiita](https://qiita.com/) `
[Qiita](https://qiita.com/)

# 水平線の挿入
` *** `
` --- `

# 引用
` 文頭に 「>」 を置く `
>  文頭に 「>」 を置く

# テーブルの挿入
` 3x2 `
入力補完「テーブルを挿入」を選択する
3x2の「x」は半角英のエックス

| 1 | 2 | 3 |
|:-:|:-:|:-:|
|   |   |   |
|   |   |   |

# コードの挿入

```` ```(改行)text = "Hello World!"(改行)``` ````
` はバッククオートです。

```
text = "Hello World!"
```


# その他
Qiita記事URLの末尾に「.md」をつけると、どのように書かれているか確認することができます。
(備忘録)MVCモデルの概要　※自己解釈

<header>
<h2>記事を作成するにあたり</h2>
現在、私はアプリ作成を勉強中です。今回の記事は、MVCモデルの概要について、自分なりの概念を説明するとともに、あわせてアプリ作成をする上で気を付けるべき部分を共有すべく、記事を投稿します。
</header>

<body>
<h2>ルーティング</h2>
まさにルートを決めるということで、リクエストの内容から行先を決めます。特定のリクエストを受け取り、動作する処理を決めます。

```ruby
 root to: "prototypes#index"
```


<h2>M - モデル</h2>
データベースとのアクセス制御を中心に行います。DBへのアソシエーションやバリデーションの設定を行うことから、DB関連のエラーが発生する場合モデルを最初に確認すべきでしょう。

```ruby
  belongs_to :user
  validates :text, presence: true
```

<h2>V - ビュー</h2>
文字通り、エンドユーザーへのレスポンスを表示します。画面の表示についてはHTML等の知識が必要です。

<h2>C - コントローラー</h2>
ルーティングにて指定されたアクション(処理)を行います。実際にアプリ等を実装する場合、コントローラーの制御や処理の記載が非常に多く、エラー解決においてはコントローラーへの処理や記載方法に誤りがある場合が多いです。

```ruby
def edit
    @prototype = Prototype.find〜
end
```

<h2>DB</h2>
各種データの保管先。特に注意すべきは各キー項目とテーブルとの関連性や、カラムのデータ保持の方法(null制約)等でしょうか。モデルを定義する際にあわせて意識することが多いです。


<h2>最後に</h2>
実際に機能や処理を実装する際、上記の役割を念頭におきながら手を動かすことで、より理解は深まります。またエラー発生時に上記のような役割が頭で理解できていると、原因特定の一助になるかと存じます。
LaravelでViewインスタンスに渡した値を取り出したい

# はじめに
こんにちは。昨日の地震、皆さまご無事でしてでしょうか。自分自身も周りの人も無事でほっとした筆者です:pray:

さて、共通で使用したい値をVIewインスタンスにあらかじめセットした際に、あとで取り出して使いたいケースがあったので、方法を共有します(そんなケースあるのか:thinking_face:、と思うのですが、あったんです...)。

# 結論
```php:Controller.php
$data = [];

// Viewインスタンスに共通で値をセット.
view()->share(compact('data'));

// Viewインスタンスから値を取り出す.
$data2 = view()->shared('data');

// Viewインスタンスを返却.
return view('home');
```

# おわりに
上記のような使い方はしないと思います。
私のこれを使用したケースは、**親Controller**で共通値をセットして、その値が**子コントローラー**で上書きされるものの、元の値も必要だったので、取り出して別名でセットし直すケースでした:thinking: 

本当はこの機構になっている構造自体が間違っているのですが、現行機能・構造を踏襲する使命が下っているので止む無く使用しました:sob:

もっと平和な使い方をしたいものです:innocent:
【jquery,js】jsの処理をリファクタリングする１ [each,prop] [js02_20210214]

####  <font color='orange'>処理の概要</font>
重量別の鉄アレイを選択した時、一定の条件（5kg以上、且つ2個以上）をクリアすると送料を無料にする

##### 処理のフロー：
　(1)鉄アレイを選択する（複数可能）
　(2)実行ボタンを押下
　(3)チェックボックスにチェックが入っているかを判断
　(4)チェックされている場合は、重量とカウントを増分させる
　(5)送料を判断する

####  <font color='orange'>画面イメージ</font>


#####画像１
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647299/a2c03e3c-9b06-268e-e43c-cc1d93e39cd4.png" width="300px">

#####画像２
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647299/c1b2a1de-3a71-746d-3fb8-a17a8b94e2a0.png" width="240px">


####  <font color='orange'>ソースコード</font>
```html:index.html
<body>
	<input type="checkbox" id="item1" value="1">鉄アレイ:1kg<br>
	<input type="checkbox" id="item2" value="2">鉄アレイ:2kg<br>
	<input type="checkbox" id="item3" value="3">鉄アレイ:3kg<br>
	<input type="checkbox" id="item5" value="5">鉄アレイ:5kg<br>
	<input type="checkbox" id="item10" value="10">鉄アレイ:10kg<br><br>
	<input type="button" id="execbutton" value="実行" >
	<br>
	<div id="output"></div>
</body>
```

#### リファクタリングする前
```javascript:main.js

$(function() {
    $("#execbutton").click(function(){
        var weight = 0;
        var count = 0;

        if($("#item1").prop("checked")){
            weight += $("#item1").val() * 1;
            count += 1;
        }

        if($("#item2").prop("checked")){
            weight += $("#item2").val() * 1;
            count += 1;
        }

        if($("#item3").prop("checked")){
            weight += $("#item3").val() * 1;
            count += 1;
        }

        if($("#item5").prop("checked")){
            weight += $("#item5").val() * 1;
            count += 1;
        }

        if($("#item10").prop("checked")){
            weight += $("#item10").val() * 1;
            count += 1;
        }

        if(weight >= 5 ){
            if(count >= 2){
                $("#output").text("送料は無料です。");
            } else {
                var lobjValue = weight * 110 ;
                $("#output").text("送料は" + lobjValue + "円です。");
            }
        } else {
            $("#output").text("送料は無料です。");
        }
    })
});
```

#### リファクタリング後
```javascript:main.js

$(function() {
    $("#execbutton").click(function(){
        var weight = 0;
        var count = 0;

        $("input[type='checkbox']").each(function(){
            if($(this).prop("checked")){
                count += 1;
                weight += $(this).val() * 1
            }
        });

        if(weight >= 5 && count >=2 ){
            $("#output").text("送料は無料です。");
        } else {
            var lobjValue = weight * 110 ;
            $("#output").text("送料は" + lobjValue + "円です。");
        }
    })
});
```



####  <font color='orange'>ポイント</font>
html：
(1)選択したチェックボックスには該当する値を設定する（value）
js：
(1)propで属性を取得する
(2)「$("input[type='checkbox']").each」でページ全体のチェックボックスについて、配列を取得する。これをeach文で、無名関数に渡す。
(3)ここでのthisはeachで取得した要素を指す
(4)画面オブジェクトから入力される値は基本的に文字列

####  <font color='orange'>参考資料</font>
JavaScript(仕事の現場でサッと使える！デザイン教科書)　p120
anyenvでgoの開発環境を構築



## goenvのインストール
```bash
$ anyenv install goenv

/var/folders/hk/_11v61jd5kn65bw_v55f9fjr0000gn/T/goenv.20210214134326.1521 ~
Cloning https://github.com/syndbg/goenv.git master to goenv...
Cloning into 'goenv'...
remote: Enumerating objects: 69, done.
remote: Counting objects: 100% (69/69), done.
remote: Compressing objects: 100% (58/58), done.
remote: Total 14402 (delta 15), reused 22 (delta 8), pack-reused 14333
Receiving objects: 100% (14402/14402), 2.61 MiB | 685.00 KiB/s, done.
Resolving deltas: 100% (9760/9760), done.
~

Install goenv succeeded!
Please reload your profile (exec $SHELL -l) or open a new session.
```

## go(v1.15.7)のインストール

```
$ goenv install 1.15.7
$ goenv global 1.15.7        
```

- バージョンの確認を行う

```bash
$ go version
go version go1.15.7 darwin/amd64
```

## サンプルファイルの実行

- 適当なディレクトリ配下に`main.go`ファイルを作成

```go:main.go
package main

import "fmt"

func main()  {
    fmt.Println("Hello,World!")
}
```

- ターミナルから`go run main.go`を実行して**Hello,World!**が出力されれば無事にgoの開発環境構築は完了。

```
$ go run main.go
Hello,World!
```
brew updateしたらhomebrew-core is a shallow clone.が発生する問題


## 動作環境
- macOS Catalina バージョン 10.15.7

## エラー文

```
Error:
  homebrew-core is a shallow clone.
  homebrew-cask is a shallow clone.
To `brew update`, first run:
  git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
  git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow
These commands may take a few minutes to run due to the large size of the repositories.
This restriction has been made on GitHub's request because updating shallow
clones is an extremely expensive operation due to the tree layout and traffic of
Homebrew/homebrew-core and Homebrew/homebrew-cask. We don't do this for you
automatically to avoid repeatedly performing an expensive unshallow operation in
CI systems (which should instead be fixed to not use shallow clones). Sorry for
the inconvenience!
```

詳細に関して確認していきます。

### homebrew-core

- Homebrewのpackage manager

[Homebrew/homebrew-core](https://github.com/Homebrew/homebrew-core) 

### shallow clone

- Gitの機能。
- git cloneは元のリポジトリを全て取得する。
- shallow cloneを使うことによって最新版だけ取得することができる。

git shallowの詳細は下記から確認できます。

```
--depth <depth>
Create a shallow clone with a history truncated to the specified number of commits. Implies --single-branch unless --no-single-branch is given to fetch the histories near the tips of all branches. If you want to clone submodules shallowly, also pass --shallow-submodules.

--shallow-since=<date>
Create a shallow clone with a history after the specified time.

--shallow-exclude=<revision>
Create a shallow clone with a history, excluding commits reachable from a specified remote branch or tag. This option can be specified multiple times.
```

[Git - git-clone Documentation
](https://git-scm.com/docs/git-clone#Documentation/git-clone.txt---depthltdepthgt)

### git fetch --unshallow

- リポジトリにフェッチされていない全履歴を確認することができる。
- shallow cloneしたリポジトリであっても、`git fetch --unshallow`を実行することで過去の履歴も取得することができる。


## 解決方法
homebrew-coreはshallow cloneなので、`git fetch —unshallow` することによって全ての情報を取得しましょう。

下記2つのコマンドを実行する。

```
git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core fetch --unshallow
git -C /usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask fetch --unshallow
```

## 注意点

- リポジトリサイズが大きいためコマンドの実行には時間がかかります。

## 参考
[update.sh: refuse to update shallow homebrew-core/cask clones. #9383](https://github.com/Homebrew/brew/pull/9383)
Elasticsearchでカタカナも引っ掛かるようにしたい！【kuromoji】

# 悩み
Elasticsearchで色々検索しなければいけない機会があり、その時に「あれ？これカタカナで検索しても引っかからないぞ？？？」となって大変困ったことになりました。
例えば、「ライトセイバー」を「らいとせいばー」と検索しても引っかからなかった訳です。

この時、色々調べてなんとかなったので、それをまとめてみました。
この記事では、この問題の解決法しか書いていないので、
「そもそもElasticsearchとは？」みたいな説明はしませんので、ご注意ください。


# 初手結論
indexの`settings`にこれを追加すればできるようになりました。
`analyzer`の`kuromoji`の`filter`部分はお好みで追加したり、削除したりしてください。

```json
"analysis" : {
  "filter" : {
    "kuromoji_multiplexer" : {
      "type" : "multiplexer",
      "filters" : [
        "lowercase",
        "lowercase, porter_stem",
        "kuromoji_readingform"
      ]
    }
  },
  "analyzer" : {
    "kuromoji_analyzer" : {
      "filter" : [
        "kuromoji_part_of_speech",
        "cjk_width",
        "kuromoji_stemmer",
        "lowercase",
        "kuromoji_multiplexer"
      ],
      "char_filter" : [
        "icu_normalizer"
      ],
      "tokenizer" : "kuromoji_tokenizer"
    }
  }
},
```

詳しく説明していきます。

まずは`"flter"`の部分でカスタムフィルターを定義しています。（ここでは`kuromoji_multiplexe`）

ここで重要なのは`"type": "multiplexer"`の部分です。 
Elasticsearchの`multiplexer`のタイプをつけた場合、そのフィルターは一つの検索後に対して複数のトークンを作成してくれます。
例えば、「this is a pen」と検索した場合、「THIS IS A PEN」とも検索してくれるような感じですね。

この時の小文字から大文字への変換をどうするか？というのを決めるのが`"filter"`の項目になります。
今回はフィルターに`lowercase`、`lowercase, porter_stem`、`kuromoji_readingform`の三つのフィルターを指定していますので、これらを使ってトークンを別の文字列として複製してくれます。

(`kuromoji_readingform`では「だいふく」を「ダイフク」とも検索してくれます。)


そして、`"analyzer"`項目の`"filter"`部分で先ほど作ったカスタムフィルターである`kuromoji_multiplexe`を追加しています。
これで、ひらがなで検索した際にもカタカナのものが検索に引っ掛かるようになりました！
Web制作用語　まとめ　入門②

自分用です。

Web制作で使う用語まとめ、入門②
引用元はこちら
https://www.youtube.com/watch?v=0jdvH4U0ANo
お世話になってます。

##HTML
HyperText Markup Language
webページを表現するために使われる
文章の構造をマークアップするための言語
最新バージョンはHTML5.2

##CSS
Cascading Style Sheets
webページのスタイルを指定するための言語
HTMLと組み合わせて使用する言語
文書のスタイルを指定する技術をスタイルシートという

##JavaScript
Webブラウザ上で、実行処理を行うプログラミング言語の一種
プロトタイプベースのオブジェクト指向スクリプト言語
　プロトタイプベース→試作ベース
　オブジェクト指向→互いに関連性を持つデータとコードをひとまめにしてオブジェクトとし、オブジェクト同士でプログラムを全体構築していくソフトウェアの開発手法
　スクリプト言語→簡易的なプログラミング言語

##Wordpress
Webサイトの更新・管理をしやすくするためのシステム、世界シェアNo.1のCMS
CMS→コンテンツマネージメントシステム、Webサイトのコンテンツを構成するテキストや画像、デザイン、レイアウト情報などを保存・管理するシステム

##PHP
The PHP Groupによって開発されているオープンソースの汎用プログラミング言語
サーバーサイドで動的なwebページを作成するための機能を多く備えている

WordpressやEC-CUBEなどもPHPで作られている
処理の違い
JavaScript→Webブラウザ上で動作する
PHP→サーバー側でプログラムの処理が行われ、ブラウザ上に処理結果を出力する


##DB
データベース
記事や商品データ、個人情報を保存して表に整理した情報のかたまり

##MySQL
サン・マイクロシステムズ(現在はOracleの傘下)が開発したリレーショナルデータベース管理システム
Oracle→アメリカのテキサス州に本社がある世界第２位のソフトウェア会社
リレーショナルデータベース→データを表形式で扱っているデータベース

##phpMyAdmin
PHPで構成された、MySQLの管理ツール、SQL文を作成せずにブラウザから操作できる

##Saas（サース）
Software as a Service
インターネット経由でサービスを提供・利用する形のことサース


##ASP
Application Service Provider　アプリケーションサービスプロバイダ
サービスの事業者

##FTP
File Transfer Protocol　ファイルトランスファープロトコル
インターネットを使用してファイルを送受信するための通信の手段


##絶対パス、相対パス
リンク先の記述方法
絶対パス：リンクスページや読み込むファイルのURLを指定して情報がどこにあるかを確実に伝える「ルートディレクトリからカレントディレクトリまで完全に記述する方法」
相対パス：今いる階層を基準にして情報がどこにあるのかを伝える記述方法


##デバッグ
バグを見つけて修正する作業

##Basic認証
Webサイトの特定のページやファイルにアクセス制限をかける認証方法

##パーミッション
フォルダやファイルに対するアクセス権限
サーバ内のフォルダ、ファイルにどの程度のアクセス権を与えるのかを設定することができる

```
権限　   アクセス権
読み込み　オーナー
書き込み　グループ
実行　   その他
```

##SSL
Secure Sockets Layer
WebブラウザとWebsサーバーの間のデータの通信を暗号化して、送受信させる仕組みのこと
Https化されていればSSLによって暗号化されていることを表す

##API
Application Programming Interface
アプリケーションプログラミングインターフェース
あるひとつの機能に特化したプログラム共有可能なものや、ソフトウェア、システムの機能を共有する仕組み

##APIとライブラリの違い
ライブラリは汎用性の高い複数のプログラムを、再利用な形でひとまとまりにしたもの


#まとめ
Web制作において、どれも必須で覚えないと話にならないと思う。
[JavaScript]for文、forEach関数ついて

#for文とは
for文とは、繰り返し処理を実行するためのJavaScriptの構文です。

for文の構文は以下のようになります。

```javascript:コンソール
for ([①初期化式]; [②条件式]; [③加算式]) {
  // 繰り返す処理の内容
}
```

#①初期化式
for文の中で使用する変数を定義します。ここで定義した変数は「今何回目の処理か」を判定するために参照されます。

#②条件式
for文の処理を何回繰り返すかを指定します。この条件式の戻り値がtrueで有る限り処理は行われ続けます。

#③加算式
初期化式として定義した変数の増減を記述できます。

i++と記述することで、カウンタを1ずつ加算するという意味になります。

#for文の例

```javascript:例１
for (let i = 0; i < 10; i++){
  console.log(`腹筋${i+1}回目`)
}
#実行結果
腹筋1回目
腹筋2回目
腹筋3回目
腹筋4回目
腹筋5回目
腹筋6回目
腹筋7回目
腹筋8回目
腹筋9回目
腹筋10回目
```

カウンタは0から始まるため、今回は( i + 1 )の形で処理しました。

```javascript:例２（配列を利用）
let muscle = ["ベンチプレス","スクワット","デットリフト","懸垂","腹筋"]

for (let i = 0; i < muscle.length; i++){
  console.log(muscle[i])
}
#実行結果
ベンチプレス
スクワット
デットリフト
懸垂
腹筋
```

fruits.length の形で繰り返し回数を指定しています。

 i < 5 と指定しても動作はするのですが、配列の「length」プロパティを使うと自動的に配列の大きさを取得できるので、この指定方法が効率が良いです

#forEach関数とは
forEach関数とは、配列に格納されている要素1つひとつに対して、繰り返し処理を行う場合に用いられる関数です

以下のようになります

```javascript:コンソール
配列.forEach( function(value){
  // 処理の記述
})
```

```javascript:例
let muscle = ["ベンチプレス","スクワット","デットリフト","懸垂","腹筋"]

muscle.forEach(function(workout){
  console.log(workout)
})
#実行結果
ベンチプレス
スクワット
デットリフト
懸垂
腹筋
```

筋トレの名称が格納された配列「muscle」を使い、それぞれの名称をコンソールログで表示するという内容です。

コールバック関数の引数としてworkoutを設定していますが、この変数に配列の値となる筋トレの名称が１つずつ代入されるようになります。

for文と違って、繰り返し回数やカウンタ変数などをまったく意識せずに扱えるので、非常にシンプルにコードが書けているのが特徴です

#まとめ
JavaScriptで繰り返し処理を行う場合はfor文を使用すること
JavaScriptで配列の繰り返し処理を行う場合は、for文またはforEach()関数を使用すること
No application encryption key has been specifiedを解決する

# エラー発生
ソースコードをcloneした後に、ローカルでサーバーを立ち上げてページアクセスすると画面に「**500 | SERVER ERROR**」が表示。

# 原因調査

`storage/logs/laravel.log`でエラー内容を確認します。
エラーの原因は下記の通り。

```:storage/logs/laravel.log
[2021-02-14 03:34:41] production.ERROR: No application encryption key has been specified. {"exception":"[object] (Illuminate\\Encryption\\MissingAppKeyException(code: 0): No application encryption key has been specified. at /Users/******/dev/laravel-project/laravel-blade-sortable-demo/vendor/laravel/framework/src/Illuminate/Encryption/EncryptionServiceProvider.php:79)

```

これは「プロジェクトに**暗号化キーが未設定**」だと意味しています。
なので、暗号化キーを設定する必要があります。

## 暗号化キーの確認
プロジェクトで暗号化キーがセット済みかどうかの確認は３通りあります（セットされた暗号化キーの値も確認できます）。

* `.env`ファイルのAPP_KEYに値がセットされているか確認
* コマンド`cat .env | grep "^APP_K"`で確認
* コマンド`php artisan key:generate --show`で確認

# [解決]暗号化キーの設定

下記コマンドで設定する。

```
$ php artisan key:generate
Application key set successfully.
```

コマンド実行後、`.env`ファイルのAPP_KEYに値がセットされていました。

設定した値が反映されていない可能性があるため、（サーバーを一旦停止した後に）下記コマンドでキャッシュをクリアしときます。

```
$ php artisan config:clear
Configuration cache cleared!
```

この後にサーバーを立ち上げ、ページアクセスするとエラーが解消されていました。
# 参考

* [No application encryption key has been specified.となったときの対応方法](https://qiita.com/ponsuke0531/items/197c76fcb9300d7c5f36)
* [[Laravel]エラー"No application encryption key has been specified."が出るとき](https://akamist.com/blog/archives/2178)
メモ帳探して2年 Notionにたどり着いたお話

## はじめに
コロナワクチンが最近日本に上陸したということで、少し明るい兆しが見えてきた今日この頃。私のメモ帳探しにも明るい兆しが見えてきたので紹介させていただきます。

## おすすめのメモ帳 Notion
皆さんはメモ帳ってどんなものを使ったことがありますか？
紙のノートにとるのが好きだとか、MacやWindowsに標準でついているもので十分って方もいるかもしれませんが、こだわりたい方も少ないないはず。

私自身、メモをとるのが超絶下手くそでメモをとっても乱雑になりすぎてどこに何が書いてあるかわからなくなることが多々あったので、自分に合うメモ帳を探していました。

### 私がメモ帳に求めていた機能
1. <b>同期がとれる</b><br>特定の端末に依存して、メモが乱雑になっていました。

2. <b>メモを階層管理できる</b><br>大トピック、中トピック、小トピックと関係性のあるものが視覚的にまとめて管理できないと探すのだけで時間がかかっていました。

3. <b>文字のレイアウト変更が簡単</b><br/>視覚情報に頼りすぎている私なので、一目で重要な箇所を把握したい。けど手間はかけたくない。

これらを満たしてくれたのが <b>Notion</b> でした。

### Notionの機能紹介
機能紹介と言っても Notion のできることがありすぎて、私もまだまだ使いこなせてはいないです。
なので、先程の私の求めていた機能と突き合わせて紹介していきます。

1. <b>同期がとれる</b><br>
Mac、WindowsともにアプリがありますがGoogleアカウントでログインすればとりあえずどんなPC、スマホでも同期が簡単にとれちゃいます。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662048/4e6863ce-70d5-3e62-9976-5784f44decf7.png">

2. <b>メモを階層管理できる</b>
正直もっとうまいこと階層にできる人からしたら感はあるんですが、でも個人的に今の所これで結構スッキリして見えていい感じです。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662048/edf073ff-fa81-74d6-5edd-f2f9274e90fb.png">

3. <b>文字のレイアウト変更が簡単</b><br>このメモ帳なんと <b>Markdown</b> がかけました。その他にも、```/〇〇``` と入力することで <b>テーブル</b> や <b>外部リンク</b> などを簡単挿入することができちゃいます。（テーブルは簡単な関数、フィルタ機能などが使えます。）
<img width="700" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/662048/dcc16890-0245-4b5c-337f-e8d917000cfb.png">

## まとめ
まだまだ機能の一部しか使いこなせていないのですが <b>Notion</b> の良さが少しでも伝われば幸いです。

他の機能は youtube でも ブログ でもたくさんの方が紹介しているので、気になった方は見てそして使ってみてください！
ありがとうございました(＾人＾)感謝♪
Nuxt の scrollBehavior のサンプルをそのまま使用すると Firefox でページ内でのアンカーポイント (#id など) への移動にクリックが 2 回必要になる

# Nuxt の scrollBehavior のサンプルをそのまま使用すると Firefox でページ内でのアンカーポイント (#id など) への移動にクリックが 2 回必要になる

IE や Chrome ではだいじょうぶっぽいです。

## scrollBehavior

[scrollBehavior - router プロパティ - NuxtJS](https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-router/#scrollbehavior)

上記には以下のような事例が載っています。

```js:scrollBehavior
export default function (to, from, savedPosition) {
  return { x: 0, y: 0 }
}
```

これを使用すると nuxt-link などによるページ遷移の際に、画面のトップにスクロールします。

そのまま Nuxt を使用した際にリンクによる遷移を行うと遷移先でもスクロールした位置を保持されたりするようなので、
ページの遷移後には画面の上部を表示したい場合などに便利なようです。

## Firefox での挙動

しかし前述の scrollBehavior のサンプルをそのまま使用すると、
Firefox 使用時にアンカーポイントへの画面内遷移で妙な挙動を示します。

[アンカーポイントとして指定する使い方 - HTMLアンカーリンク（a hrefタグ）とは～使い方と別ページ（target blank）について - SEO ラボ](https://seolaboratory.jp/44165/#p02b)

具体的には 1 度クリックしただけでは移動せず、もう 1 度クリックするとスクロールします。
この挙動は Chrome, Edge, IE では確認されませんでした。

## 挙動の違い

そこで scrollBehavior に alert を挿入した事例にて挙動の確認を行ってみます。

<https://codesandbox.io/s/dreamy-booth-m26zy?file=/app/router.scrollBehavior.js>

```js:scrollBehavior-alert
const scrollBehavior = (_to, _from, _savedPosition) => {
  alert(`scrollBehavior`);
  return { x: 0, y: 0 };
};

export default scrollBehavior;
```

### Chrome の場合

Chrome の場合「b」をクリックした直後 alert が表示され、そのあと対象のポイントへ移動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116435/7a013385-346d-ba85-1258-02577e80a4d4.png)

### Firefox の場合

Firefox の場合「b」をクリックして alert が表示されたタイミングで画面内の遷移が行われ、
この後には画面のトップに戻ってしまいました。

alert の実行後に scrollBehavior に定義したトップへの移動が行われているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116435/df639243-ac3c-c457-7502-9171bb9ab662.png)

その後改めて「b」をクリックしたところ、 **alert は表示されず** 対象のポイントへ移動しました。

Firefox ではこのポイントへの移動タイミングの違いによりクリックが 2 回必要になっていると思われます。

## Firefox でも大丈夫な事例

以下は軽く確認したものですが Firefox でも 1 回のクリックで遷移するようにしたものです。

`#id` などのフラグメントの値は route.path に含まれ ~~る~~ ないため、
to, from の path を比較し、そこに差異がある場合にトップにスクロールする制御をかけています。

```js:scrollBehavior-firefox
/** @type {import('@nuxt/types').NuxtOptions['router']['scrollBehavior']} */
const scrollBehavior = (to, from, _savedPosition) => {
  if (to.path !== from.path) {
    return { x: 0, y: 0 }
  }
  return undefined
}

export default scrollBehavior
```
初心者がサイトを作るにあたって覚えたことを書き殴る

#初心者がサイトを作るにあたって覚えたこと

## はじめに
　今回はdot installのjavascript編にある、「タイピングゲームを作ろう」を拡張して、英単語の勉強もできるタイピングゲームを作るにあたってうまくいかずに躓いたため、検索して得た知識を、ほぼ自分のために書き残すものになります。HTML, CSS, Javascriptのみで作ろうともがいています。

##1.さまざまな要素の取得や削除
　作成するときに、すべてにidやらclassを着けるわけにはいかないのでJavascriptにはさまざまな要素の取得方法があります。

####1. `element.firstElementChild;`
 要素の最初の子要素を取得する。
####2. `element.nextElementSibling;`
 要素の隣り合う次の要素を取得する。
####3. `element.previousElementSibling;`
 要素の隣り合う前の要素を取得する。
####4. `element.parentNode;`
 要素の親要素を取得する。
####5. `element.removeChild;`
 要素内の子要素を削除する。`removeChild`はDOMから削除してもメモリには残るらしい。削除した後はoldChildを使うと再利用することができるらしいがまだやったことはない。

##2.透明にする`transparent`
 カテゴリなどを作るときに横に矢印のような「＞」をdivを使ってCSSで作ろうとするときに使っていたプロパティ。borderで辺を作って反対部分を`transparent`にして＞を作っている。
因みに他にも「＞」の画像を`background`にして当てていたりするサイトもあった。どれが一番良いのかな。自分は無理矢理`positiion:absolute;`で指定してやったけど、何が正解かわからん。

##3.headerタグ、 `position: absolute;` 効かない問題
    <!-- html -->
    <header>
      <h1>タイトル</h1>
    </header>
    <div class="side-bar">
      <ul>
        <li></li>
        <li></li>
        <li></li>
      </ul>
    </div>

    /* css */
    .side-bar {
      width: 300px;
      height: 100%;
      position: absolute;
      background: #543;
    }
　このようなコードを書いてもside-barクラスのdivは左上には来ず、headerの左下を起点に位置づけされる。どこかで聞いたような気がするが、headerタグは特別で上に被らないようにできてる。用途を考えたタグ選択がもっと素早くできるように日々邁進していきたい。

##4. Javascriptでの import, export
 全ては[こちら](https://qiita.com/minato-naka/items/39ecc285d1e37226a283)。
(初めて書くので色々なMarkdown記法を試しています。よろしく。)
モジュールを作っていて一番躓いたのは、___自分のローカル開発環境ではimport, exportができない___ということ。しっかりとネットに公開するなどすればうまくいくのかな。まだ試してはいない。

##5. `display:none;`の要素を`transition`させるときの注意点
全ては[こちら](https://qiita.com/gonshi_com/items/4ae066ef4bea6d519854)
`display: none;`の要素を`:hover`やらJSの`element.classList.add('class')`を使って出現させつつ、`transition`で動かしたい！、そんなときしかない今日この頃。しかしうまくいかない。

出現させるための`display: block;`などをしたときに生成されるため、初期値がなく、動かないとのこと。

0 ---> 100 …０から１００に移動ダァー。だけど、

0 --- (hoverなどで)***...俺、参上！*** ---> 100  ...これだと１００に参上してしまう。

ですので、

    @keyframes fadeIn {
      from {
        opacity: 0;
      } to {
        opacity: 1;
      }
    }
と、cssに書いて、`animation`プロパティでfadeInを指定すればうまくいく。

___因みに、___ `transition`も`animation`も
順不同で値を一括指定でき、時間は初めに書いた値が動く時間、２個目の値が遅延時間になる。



長くなったので２個に分けて書き留めておこう。１個目終わり
デザインまとめ

#流体シェイプが簡単に作れるサイト「[Blobmaker](https://www.blobmaker.app/)」
![スクリーンショット 2021-02-14 13.00.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619224/28216a57-b01a-879a-094b-e0b0d238f1fd.png)

#モックアップが簡単に作れるサイト「 [Mockup Photos](https://mockup.photos/) 」
作成したデザインをアップロードすれば、MacbookやiPhoneに表示させたときのイメージモックアップを簡単に作成できる

#グラデーションが簡単にブラウザで作れるサイト [Grabient](https://www.grabient.com/)

#カラーの相性チェックできる系のサイト
・二色の相性が確認できる[Pigment](pigment.shapefactory.co)

・[Adobe Color](https://color.adobe.com/ja/create/color-wheel)
気に入った色はブラウザに保存とかもできる
#商用フリーの素材サイト
###無料
####・ 洒落た写真素材なら「 [O-DAN](https://o-dan.net/ja/) 」
商用フリー画像を配布している複数のサイトを一括検索できる便利なサイト。プロのカメラマンカラーグレーディング(色味をお洒落に加工する技術)してくれた画像などもあってとても便利。

####・　[Unsplash](https://unsplash.com/)
####・　[Kaboompics](https://kaboompics.com/)

####・　[PhotoAC](https://www.photo-ac.com/)
###有料
####・ 日本人の高品質画像なら「 [shutterstock](https://www.shutterstock.com) 」
アジア人以外にも、人種が選べたりする。正直予算があるならこれ一択。

####・ [ENVATO](https://elements.envato.com/)
プレゼン、イラスト、グラフィック、ロゴ、写真、Instagram投稿用デザイン、WordPressテーマまで、クオリティの高いデザインが5300万点使い放題。
・月額1700円




#商用フリーアイコン素材
✔︎商用フリー かつ　✔︎クレジット表記不必要
のもののみ掲載


###・ [icooon-mono](https://icooon-mono.com/)
色などの指定がしたいならこれ一択
![スクリーンショット 2021-02-14 12.59.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619224/6a42a99d-ca7c-e197-c86a-597c092a9035.png)



###・ [iconmonstr](https://iconmonstr.com/)
海外のアイコンサイト。SNSアイコンなどはこれ一択。
![スクリーンショット 2021-02-14 12.57.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619224/bf7fc16d-7a4f-59be-39f2-e79e0fdc0bdf.png)


#商用フリーのイラスト素材
・ [illustimage](https://illustimage.com/?id=12193)


#ギャラリーサイト
ディスプレイ広告のバナーサイズ一覧。GDN・YDNごとに紹介

###・ スマホのデザインまとめサイト「[AGT](https://agtsmartphonedesign.com)」


#Figma勉強サイト

・[Webデザイナー独学入門](https://web-design.school/tutorials/figma/outline)
アラフィフからITエンジニアを志すおっさんの軌跡

#初めに
ずいぶん前にITエンジニアに転向しようとして、
それまでずいぶん苦労してきたが、
ようやく長いトンネルを抜け出てきたような気がする。

#三年前
思い起こせば三年前　https://qiita.com/hagetaka/items/7b8468c20f2467f6bf43
あれから、かれこれ長い年月を経て、まあまあの知見を得て、
今のIT業界の事がうっすらと見えてきた気がする。

その軌跡を少し振り返ってみる

#それまで
製造メーカの生産プロセス開発で、たまにVBAでデータまとめるぐらい
プライベートではホームページをHTMLで作っていたぐらい
（プロバイダにFTPでアップロードするぐらいしか知らなった）

言語と言えばC言語を大学時代に触ったぐらいで、あの頃は
アルバイトでコンピューター学校の教師をやっていたぐらい

就職前に、アルバイトでUnixのx-ターミナルのバグ取りを
やったがIT業界に行くのは、キツイ、体に悪そうと言うことで
やめた思い出がある。

#きっかけ

長らくメーカの開発をやっていたが、製品開発のスケジュール管理は
EXCELシートでガントを作ったり、製品の故障解析でPDPCチャートや
QCツールを使ったいたが、やはりexcelベースが大半であった。

その頃から本屋へ行くたびに、pythonでAIというのを
頻繁に見かけるようになった。

プライベートではFXのトレードをやっていて、
メタトレードのインジケータなどを作っていた。

しかしながら、有用な戦略が見つからず、これはAIじゃないと
ダメなのではないかと思い立ち、真剣にIT勉強をしたいと思った。

別件では父親の介護などで、いわゆる行政サービスの現場との
やり取りの中で、実にアナログのやり取りが続き、
これからの少子高齢化社会を支えるのは、IT技術しかないと危機感を覚えていた。

#それから

pythonを学んだのは、EXCELで取得したデータをヒストグラムを書かせるために
データ集計から始まった。

pandasの使い方にとまどい、Jupiterノートに出会って、ずいぶん苦しんだ。

excelとの親和性が高いACCESSを触り、当時はVBAさえできれば、
そこそこの仕事は片づけられた。

プログラミングではｃ＃というものを知り、当初はvisualstudioを使い始めたが
JAVAなどの言語もあり、そこからはUMLチャートの書き方やら、ソフトデザインパターンの学習に苦しんだ。

そもそも、CからJAVAの歴史を知るのに、ずいぶんとタイムラグがあり
歴史を２０年ぐらい遡って勉強する羽目になる。

今思えばlinuxやJAVAの本を買い、目指していたところが少しブレていたように思う。

一年ぐらいはpythonの本で勉強してきたので、
仕事で何かアプリが作れないかと思い検討し始めた。

着手したのはCADのPDF図面から、設計寸法を読み取るというもの

OPENCVというライブラリを使って、簡単にマッチング検索を実施して、
OCRで文字認識させるところを作ってみた。

ここまでは意外に簡単で、二、三日でアプリ化の目途が立った。


しかしながら、これをサービス化するときに苦戦させられる羽目になった。

当初はVBAとexcelがメインだったので、いきなりWEBには走らなかった。

visualstudioでexcelのプラグインのようなものを考えていた。

そもそもpythonというのは、windowsメインの職場の環境では、
著しく使いにくい言語であった。

#転機点

転換点としては、社内でAIを推進するというＰＪＴがあり、
ＡＷＳクラウドサービスを利用し始めたと情報を得る。

これでPYTHONを職場で使える可能性が出てきたので、
完全にWEBアプリ前提で立ち上げることにした。

そこからはWEBフレームワークの勉強
DJANGOはいきなりは厳しすぎた。

そもそもMVCの概念も分かっていない。

データベースの使い方も分からない。ACCESSは何となく分かっていたが

GIThubや[TERATAIL](https://teratail.com/users/yuujiMotoki#reply)やQIITAなどの、IT業界系のSNSの存在を知る。

しかしながらgitの使い方はさっぱり分からなかった。

このころからエディタをVSCODEにしている。それまではPYCHARMなど、右往左往した。

FLASKのソースを見よう見まねで動かして学んだ。

getとかpostの仕組みが分からず、webの本を読みまくった

フロントエンド部分のuiを作るのに、HTML、cssを学んだ。

JSを始めたが、Jqueryというもののコードの読み方に随分苦労させられた。

#AI

そうこうしている間に、なんとかアプリケーションが完成できて、ecサーバー上で動かせた。

職場でキャリアマッチング制度があり、たまたま社内でAI人材が欲しいという案件があった。
もちろん社内なので、興味本位でもいいとのこと。（普通に転職者だったらありえないだろう）

面接の場でPYTHONがそこそこ使えることと、AIサービスは作れる自信はあった。

そんなこともあり、面接を通して、AI開発部門に異動することができた。

コロナの影響もあり、そこからはたっぷりとg検定の勉強に取り組んだ。

自然言語処理のため、AIの中では難しい部類であるが職務で取り組める環境になった。

#今後

現在は特許分類のシステムについて、データ前処理をPYTHONで書いている。

これからは特許業界もai真っただ中にあるので、今年はいろんな交流に参加する予定。

e資格以外にも、データベーススペシャリストなども目指していきたいと思う。

JAVAスクリプトはいろんなフレームワークがあり混乱している。

java,c#などのデスクトップ開発はしばらくはないだろうと思う。

クラウドやサーバーの立て方など、もう少しサービス側のこともやっていければと思う。

htmlについては、デザインセンスも必要だし、もっと仕事でもつかえるデザインもやりたい。

PHP、ルビーは全く分からない。

当面はPYTHONで開発ができれば十分だと思う。

nodeJSはそこまでがっつりJSには取り組まないので、少し負担が減った気がする。
数年たてばJSのフレームワークも何かに落ち着くだろうと予想。


そんなこんなで、２０１８，２０１９，２０２０年の三年間を過ごした。
（まだエンジニアやっていました、なんて語れもしないが、
ai資格さえあれば、何かのきっかけがつかめるのかもしれない）

また自分でもaiサービスをやってみたい

ワードプレスとredmineをNASで運用し、インターネットで公開できたのが、直近の一番の成果
ROS melodic環境で`Controller Spawner couldn't find the expected controller_manager ROS interface.`のエラーが表示されるときの解決策

ROS melodic環境で`Controller Spawner couldn't find
the expected controller_manager ROS interface.`のエラーが表示されるときの解決策

以下の２つで解決できたので備忘録です

### 1.パッケージのインストールを試みる

```
sudo apt-get install -y ros-melodic-joint-state-controller
sudo apt-get install -y ros-melodic-effort-controllers
sudo apt-get install -y ros-melodic-position-controllers
sudo apt-get install -y ros-melodic-ros-control
sudo apt-get install -y ros-melodic-ros-controllers
```

### 2.モデルのパスを通す

.worldや各種モデルファイルのパスが通っていない可能性がある。
この場合は`GAZEBO_MODEL_PATH`などの環境変数を設定すると解決するかもしれない。

# 参考
[6. ロボットシミュレータ上でのロボットモデルの作成と行動生成¶](https://edu.isc.chubu.ac.jp/naga/ri/ri6.html)
[Problem with start controller with roslaunch: controller spawner couldn't find the expected controller_manager ROS interface](https://answers.gazebosim.org//question/12673/problem-with-start-controller-with-roslaunch-controller-spawner-couldnt-find-the-expected-controller_manager-ros-interface/)
【Rails】データのマイグレーションの理解と内容制限

#マイグレーションの適用を理解する
DBのマイグレーションは、1つのマイグレーションが1つのバージョンとして扱われるので、1つのマイグレーションを適用することでバージョンを1つ上げることができ、適用済みのマイグレーションを1つ取り消すことでバージョンを1つ下げることができます。

rails g migrationコマンドで生成されるファイルのchangeメソッドの処理は、コマンド rails db:migrate でバージョンが上がり、コマンド rails db:rollbackでバージョンが下がります。このchangeメソッド内の処理は自動的に、適切に処理してくれます(例外あり)。

##schema.rb
Railsは現在のDBの構造はdb/schema.rbに自動出力されます。マイグレーションの適用や外しで自動的に出力されます。

#データ内容の制限
データには想定される「内容の範囲」があり、そぐわない値が格納されないようできるものがあります。
一般的に以下の4つがRailsアプリでよく利用されます。

+ データ型
+ NOT NULL制約
+ 文字列カラムの長さの制限
+ ユニークインデックス

#データ型
DBのカラムには型を指定します。主なデータ型は以下の表です。

| データ型      | 説明         |
| :--------- | :---------- |
| :boolean  | 真偽値        |
| :integer  | 符号付き整数     |
| :float    | 浮動少数点数     |
| :string   | 文字列(短い文字列) |
| :text     | 文字列(長い文字列) |
| :date     | 日付        |
| :datetime | 日時           |

#NOT NULL制約
DBのカラムの値としてNULL(空の値)を格納する必要がない場合は、NOT NULL制約を物理的にNULLを保存できないようにしてくれます。
作成した投稿アプリでは、Postモデルの「投稿内容」(content)につけるのが適当でしょう。
postsテーブルのcontentカラムにNOT NULL制約をつける、つまり既に作ってあるテーブルに制約をつける場合にも、マイグレーションを利用します。

マイグレーションを作るには、まずgeneratorを使って雛形ファイルを生成します。名前は「ChangePostContentNotNull」とします。

```
bin/rails g migration ChangePostsContentNotNull
Running via Spring preloader in process 10646
      invoke  active_record
      create    db/migrate/XXXXXXXXXXXX_change_posts_content_not_null.rb
```
雛形を生成したら、ファイルの中身を次のように編集します。

```ruby:db/migrate/20210210122203_change_posts_content_not_null.rb
class ChangePostsContentNotNull < ActiveRecord::Migration[5.2]
  def change
    change_column_null :posts, :content, false
  end
end
```

change_column_nullのtrue,falseでNOT NULL制約のつけはずしができます。
編集を終えたたら、マイグレーションを実行して完了です。

#文字列カラムの長さ指定
DBのカラム定義で、必要以上に長いデータの保存を防ぐことができます。マイグレーションで文字列カラムに対してlimitオプションを使います。
今回は投稿内容(content)を50文字に制限する処理を書いて、適用しています。

```ruby:db/migrate/XXXXXXXXXXXX_change_posts_content_limit50.rb
class ChangePostsContentLimit50 < ActiveRecord::Migration[5.2]
  def up
    change_column :posts, :content, :text, limit: 50
  end
  def down
    change_column :posts, :content, :text
  end
end
```

change_columnでは、バージョンを戻す際の処理を、バージョンを上げる際のコードから自動生成できません。そのため、changeメソッドではなくupメソッドにバージョンを上げる処理、downメソッドにバージョンを下げる処理を書いています。

#ユニークインデックス
あるテーブルのあるカラムのデータが、全レコード内で一意である(他と被らない)場合には、ユニークインデックスを作成することで一意性を確保できます。仮にcontentにユニークインデックスを追加したい場合は以下のようなファイルを作ると良いでしょう(実際には行っていません)。

```ruby:/XXXXXXXXXXXX_add_index_to_posts.rb
class AddIndexToPosts < ActiveRecord::Migration[5.2]
  def change
    add_index :content, unique: true
  end
```

カラムにユニークインデックスを追加することで、重複した値がDBに存在することが防げます。
なお、NULL同士は常に異なる値だとみなされるので、ユニークインデックスを追加したカラムの値がNULLのレコードは複数存在することができます。

#参考
[現場で使える Ruby on Rails 5速習実践ガイド](https://www.amazon.co.jp/gp/product/B07JHQ9B5T/ref=ppx_yo_dt_b_d_asin_title_o03?ie=UTF8&psc=1)
EC-CUBE4 Amazon SES を利用してメールを送信する

## Amazon SES の設定

### Terraform を使う

**Terraform v0.14.6**

```terraform
resource "aws_ses_domain_identity" "my-ses" {
  domain = aws_route53_record.my-www.name
}

resource "aws_route53_record" "my-route53-record-ses-validation" {
  zone_id = aws_route53_zone.my-route53-zone.id
  name    = "_amazonses.${aws_route53_zone.my-route53-zone.name}"
  type    = "TXT"
  ttl     = "600"
  records = [aws_ses_domain_identity.my-ses.verification_token]
}

resource "aws_ses_domain_dkim" "my-ses-dkim" {
  domain = aws_ses_domain_identity.my-ses.domain
}

resource "aws_route53_record" "my-route53-record-dkim" {
  count   = 3
  zone_id = aws_route53_zone.my-route53-zone.id
  name    = "${element(aws_ses_domain_dkim.my-ses-dkim.dkim_tokens, count.index)}._domainkey.${aws_route53_zone.my-route53-zone.name}"
  type    = "CNAME"
  ttl     = "600"
  records = ["${element(aws_ses_domain_dkim.my-ses-dkim.dkim_tokens, count.index)}.dkim.amazonses.com"]
}

resource "aws_iam_user" "my-smtp-user" {
  name = "ses-smtp-user"
}

resource "aws_iam_user_policy" "my-smtp-user-policy" {
  name = "ses-smtp-user-policy"
  user = aws_iam_user.my-smtp-user.name
  policy = jsonencode({
    Version : "2012-10-17",
    Statement : [
      {
        Effect : "Allow",
        Action : [
          "ses:SendEmail",
          "ses:SendRawEmail"
        ],
        Resource : "*"
      }
    ]
  })
}

resource "aws_iam_access_key" "my-smtp-user-access-key" {
  user = aws_iam_user.my-smtp-user.name
}

output "aws_iam_access_key" {
  value = aws_iam_access_key.my-smtp-user-access-key.id
}

output "aws_iam_secret" {
  value = aws_iam_access_key.my-smtp-user-access-key.secret
}

output "aws_iam_smtp_password_v4" {
  value = aws_iam_access_key.my-smtp-user-access-key.ses_smtp_password_v4
}
```

※ SESをアジアパシフィック（東京）リージョンで利用する場合は、**パスワード著名バージョンv4** を利用します。
　https://qiita.com/charon/items/ab62742d8baf4d275456

※ SESがサンドボックス状態の場合、**検証済みメールアドレス** に対して送信できます。
　AWSコンソールの `Verified identities` にメールアドレスを登録して、`Verified` にします。

![スクリーンショット 2021-02-14 12.55.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2019/b34635a3-7dbc-3051-b53a-28ba64388ff3.png)

* SESのサンドボックス解除には1日ぐらいかかるそうなので、事前準備が必要です。  
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/request-production-access.html  
https://laraweb.net/knowledge/7083/

## EC-CUBE4 の設定

```diff:.env
- MAILER_URL=null://localhost
+ # MAILER_URL=null://localhost
+ MAILER_URL=smtp://email-smtp.ap-northeast-1.amazonaws.com:587?encryption=tls&auth_mode=login&username=YOUR_NAME&password=YOUR_PASSWORD
```

username と password には、 Terraform の出力を設定します。

`YOUR_NAME` → `aws_iam_access_key`
`YOUR_PASSWORD` → `aws_iam_smtp_password_v4`

### 注意1

`aws_iam_smtp_password_v4` に、 `/` や `+` が含まれている場合があります。
その場合、URLエンコードした文字列を使います。

```php
<?php

echo urlencode('YOUR_PASSWORD');
```

### 注意2

今回は、SMTP 経由でメールを送信する方法でした。

AWS SDK を使ってメール送信をする場合は、アクセスキーIDとアクセスキーシークレットを使います。
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/send-an-email-using-sdk.html
react/javascript 삼항연산자

#조건문과 삼항연산자

```react

  const todos = [
    {
      id:1,
      할일:'소희 한글 프린트하기',
      done:true
    },
    {
      id:2,
      할일:'메모하기',
      done:false
    }
  ];

  const filtered = todos.filter(todo => todo.id !==2);

  const toggled = todos.map(todo => todo.id == 2?{
    ...todo,
    done:!todo.done
  }:todo);

```

정말 무슨뜻인지 몰라서 고민했다.

const filterd 는 알겠는데
const toggled 의 뜻을 몰라 한참동안을 생각했다.
위 toggled 는 
첫째 todos 가지고 맵을 이용해서 조건을 돌린다.
둘째 todo.id ==2 와 같다면 출력 그리고 done 을 반대로 설정하고 출력하라는 뜻
    그리고 그외 는 그대로