OmniAICreator/Qiita-1.07M huggingface dataset:
jetson nanoでscikit learnインストール時にエラー（error: library mach has Fortran sources but no Fortran compiler found）

jetson nanoでscikit learnインストール時にエラー

```
$ pip3 install scikit-learn
...
  error: library mach has Fortran sources but no Fortran compiler found
    ----------------------------------------
    ERROR: Failed building wheel for scipy
  Failed to build scipy
  ERROR: Could not build wheels for scipy which use PEP 517 and cannot be installed directly
  ----------------------------------------
ERROR: Command errored out with exit status 1: /usr/bin/python3 /home/jetson/.local/lib/python3.6/site-packages/pip install --ignore-installed --no-user --prefix /tmp/pip-build-env-jkfyvtro/overlay --no-warn-script-location --no-binary :none: --only-binary :none: -i https://pypi.org/simple -- setuptools wheel 'Cython>=0.28.5' 'numpy==1.13.3; python_version=='"'"'3.6'"'"' and platform_system!='"'"'AIX'"'"' and platform_python_implementation == '"'"'CPython'"'"'' 'numpy==1.14.0; python_version=='"'"'3.6'"'"' and platform_system!='"'"'AIX'"'"' and platform_python_implementation != '"'"'CPython'"'"'' 'numpy==1.14.5; python_version=='"'"'3.7'"'"' and platform_system!='"'"'AIX'"'"'' 'numpy==1.17.3; python_version>='"'"'3.8'"'"' and platform_system!='"'"'AIX'"'"'' 'numpy==1.16.0; python_version=='"'"'3.6'"'"' and platform_system=='"'"'AIX'"'"'' 'numpy==1.16.0; python_version=='"'"'3.7'"'"' and platform_system=='"'"'AIX'"'"'' 'numpy==1.17.3; python_version>='"'"'3.8'"'"' and platform_system=='"'"'AIX'"'"'' 'scipy>=0.19.1' Check the logs for full command output.
```

以下で解決
（なんでscikit-learn install時にfortranがいるの？）

```
sudo apt install -y gfortran
```

# 参考
[pip-failing-to-build-wheels-for-scipy](https://stackoverflow.com/questions/58441549/pip-failing-to-build-wheels-for-scipy)
[errors-during-install-sklearn](https://forums.developer.nvidia.com/t/errors-during-install-sklearn/72622)
30代からのプログラミング勉強　11日目【HTML/CSS】

##学習内容
本日は復習を兼ねてここまでの勉強内容を用いて1からページ作りを実施。
流石に一度で覚えられている筈もなく記事を見返したりしつつ悪戦苦闘…。

二時間程かけてレスポンシブWebデザイン除いた部分が7〜8割出来たといった所か。

##所感
自分のコードの汚さに驚いたり、全然思うように反映されずトライアンドエラーの連続だったりと簡単なページ一つの作成だけで苦難の連続。
ではあったものの、写経だけでは見えてこない楽しさや難しさを垣間見る事が出来たのは良かったと思う。

最初のうちはこんなもんだと割り切りつつもいつかは洗練されたコーディングを…と夢見るのであった。
Android studio：Kotlin：アプリの更新を行う

ビルド時に書き換えるのはバージョン情報

app\build.gradleファイルの

versioncode　と　versionnameを変える。
versioncodeは整数のみ。
versionnameは1.1的なやつ

```gradle:build.gradle
    defaultConfig {
        applicationId "com.shopping.noshoppingbag"
        minSdkVersion 16
        targetSdkVersion 30
        versionCode 2 ←ここ
        versionName "1.1"　←ここ

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
```
ビルドするときは最初にビルドしたときの署名鍵が必要。

android studioの上の
ビルド→署名済みバンドルまたはapkの作成→Android App Bundle

![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700383/a9aa6040-73fd-0eca-16bb-a38090afdaef.png)

ここのキー保管パスに最初にアプリをビルドしたときに作ったjksファイルを指定する。
なくしてたら更新は不可。アプリをplayから削除して出し直すしかない。
Docker開発環境でerbファイルをslimファイルに変換するコマンドを実行したらエラーが出た



Docker開発環境で構築したアプリにSlimを導入したのでRails newした時にできた```.erbファイル```をSlimに変更しようと思い、```docker-compose run web bundle exec erb2slim app/views/layouts/ --delet```を実行したところ下記のエラーがでた

```
bundler: command not found: erb2slim Install missing gem executables with `bundle install`
```

何をわけわからんこと言ってんねん！いれたやろがい！！！ってキレそうになりながら冷静になってみるとDockerのビルド？をしていないことに気づいたので下記を実行

```docker-compose up --build```
無事にDockerが起動したらDockerをもう一度止めて、
```docker-compose run web bundle exec erb2slim app/views/layouts/ --delet```を実行！！

そしたら無事にerbファイルがSlimに置き換わっていた！！やったぜ！！！

Dockerで開発環境を作ってるので、Dockerにしっかり更新したよ〜！っていう旨を伝えなくちゃいけないっぽいわね。勉強不足であってるかわからんけど、そんな感じでやったらとりあえずできたのでヨシ！ということでひとつ

おわり！！！！！！
データラーニングギルドに入ってからの活動を振り返ってみた

# はじめに
こんにちは。今回、[データラーニングギルド](https://data-learning.com/guild)のアドベントカレンダーにて**エンジニアから新規事業企画へ転職した約1年半の振り返り**を行いました。

[データサイエンティストとしてビジネスとテクノロジーを繋ぐポジションを目指した取り組みと得た知見](https://qiita.com/DaikichiDaze/items/980b00e58ede5a70a843)

上記記事を書く際に、2020年4月にギルドに入会してからの主だった活動を書き出しました。いざ書き出してみると8ヶ月の間に数多くの取り組みを行ったことが見えてきて、メンバーの皆のおかげでがんばれたんだなーとしみじみしました。（いつもありがとうございます！！）

本記事では記念に書き出した活動内容を投稿することにしました。

# ギルドに入ってからの活動振り返り

思いつく限りの取組内容を表でまとめてみました。

|項目|概要|取り組みコメント|
|---|----|-------|
|**1. ユーザ検索プロジェクト**|- Slack内で指定トピックに詳しいメンバーを検索する基盤構築を目指す<br>[詳細はこちらの記事へ](https://qiita.com/masso/items/44437b48706483ce9f30#%E7%AC%AC2%E9%83%A8-%E7%AC%AC4%E7%AB%A0-%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E6%A4%9C%E7%B4%A2%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E7%B4%B9%E4%BB%8B)|- GCP関連の学習<br>- APIポートフォリオの理解<br>- 勉強会での発表（[GCP基本編](https://speakerdeck.com/daikichidaze/yuzajian-suo-puroziekutomian-qiang-hui-gcpfalsebu-nil-1)）|
|**2. git・docker講座**|- @massoさん企画の勉強会（大感謝）<br>- データサイエンティストとして必要最低限の使い方紹介|- この勉強会をきっかけにgit・dockerを使うようになりました！！<br>- この後の各プロジェクトで両方ともばりばり使っていくことに|
|**3. sql講座**|- ギルド内特典として受講できるSQL教材<br>- 体系的にSQLを学ぶことができる|- なんとなく利用していたSQLを体系的に初めて学んだ<br>- joinに対する苦手意識がなくなった<br>- pandasでのデータフレーム設計も向上した|
|**4. ギルド1周年記念slack分析**|- 1周年記念としてSlackデータを分析<br>- 内容の詳細は[こちらのレポートを参照](https://guild.data-learning.com/slack-analyzation)|- 実践的なSQL課題として非常に良かった<br>- 上記講座とセットで完璧<br>- この経験を経てレジュメにSQL使用可能と書けるようになった<br>- やっぱりネットワーク分析は面白い|
|**5. ギルド1周年記念LT発表**|- 4.と同時期に実施<br>- テーマは「1年間の取り組みを振り返る」（たしか）|- 社外の活動として、初めてのLT発表参加<br>- ずっと悩んでいた自分の選択に段々自身が持てるようになってきた<br>- この時の発表がなければ[この記事](https://qiita.com/DaikichiDaze/items/980b00e58ede5a70a843)も書いてないと思う|
|**6. kaggle上達会**|- ほかメンバーの提案でKaggle過去コンペを題材に勉強していく会を開催<br>- 色々重なってしまって続けられず|- 少ない開催回数の中でも、他参加者のnotebookを考察することができた|
|**7. ナレッジグラフ**|- ギルド内の知識・知恵を整理したナレッジグラフを構築するプロジェクト<br>- SemanticMediaWikiを用いて構築|- ネットワーク系のテーマだし面白そうというモチベーションで開始<br>- リーダーシップをもって取り組めたと思う<br>- 少しずつメンバーを巻き込んで、一歩ずつ進めている<br>- 関連してQiita記事を4本書いた|
|**8. ABD読書会**|- それぞれ担当章だけを読んで、発表・議論|- 自分では読み終えられないような本を一気に読むことができた<br>- ディスカッションをもって理解が深まる<br>- 一緒に取り組んだ人の考え方もわかって、チームビルディングも進む|
|**9. イベント運営同好会**|- LT会を定期開催するための枠組み作り<br>- きっかけは短期的な思いつきだったが、より長期的な活動に広げて頂いた|- どうやって多くの人に波及させるか？をすごく考えた<br>- まだまだこれからが走り出しなのでがんばりたい|
|**10. AIビジコン**|- ギルド内でアイディアを出し合って、ビジネスコンテストを開催<br>- 一人の発表者として参加|- 本業での取り組みをそのまま活かせるのでたのしかった<br>- 逆に技術面がまだまだ弱いことを痛感<br>- これからチームとして補えていけたらすごく良い|
|**11. 数理最適化おじさん**|- 機械学習領域のデータサイエンティストが多い中で数理最適化の有用性も布教していきたい<br>- というのは建前で、本音はたまたま詳しい領域なのでギルド内でのキャラ付け|- 来年はこの領域でも技術向上を目指していきたい|

# 感想
正直、8ヶ月の間にこんなにもいろんな活動をしているとは考えていなくてびっくりしました。でもここで学んだことで着実にスキルアップしていて、実務にもつながってどんどん活かされている。課題感としては、やはり薄く広く基礎を固めていた感が強いので、来年はもっとそれぞれを深堀りしていけるように頑張りたい。

本当に、日々仲良くさせてもらっている方々に感謝です。これからもよろしくおねがいします！
Android studio：Kotlin：play store へアップロードするaabファイルの作成

android studioの上の
ビルド→署名済みバンドルまたはapkの作成
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700383/69377aae-9ea6-eb6e-7b42-515ad691f888.png)
Android App Bundle→次へ
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700383/8862917b-81f1-8770-d5f6-e0bee510960d.png)
新規作成
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700383/4ba9558a-1627-a131-c9bb-67bb68b246fb.png)
キー保管パスはわかりやすいところを指定。
上のパスワードと下のパスワードを入れる（それぞれ違うやつ）
名前と苗字は入れる。
それ以外は空白でOK。
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700383/369e9c15-a679-8086-d95c-3a215dfbd473.png)
公開済みアプリを登録するための暗号化されたキーをエクスポートする　にチェック(なくてもできるけど一応)
![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700383/e5bb8856-6b8e-7c12-97eb-bfbb9215b99a.png)
release　を選択して完了。

完了するとappフォルダに「release」というフォルダができ、その中にapp-release.aabができるのでそれをplay storeにアップロード。

また新規作成時に指定したフォルダに アプリ名.jksというキーができる。
これをなくすと最新版をリリースできなくなるので注意。
アプリの更新をする場合はキー保管パスにjksファイルのファイルパスを指定する。
Android studio：Kotlin：アプリのプロジェクト作成時にやること


1.プロジェクト作成時にパッケージ名をexampleから変更
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700383/36c449d5-b0a3-37eb-c2ed-f05b072e9716.png)

パッケージ名のcom.exambple.myapplicationのexample部分。
exampleのままだとplay storeでひっかかるので変える。
com.test.applicationみたいな感じで。

もしそのままでつくってしまったらリファクタリング。
手順は以下参考。
https://joh-sys.com/blog/2020/05/12/%E3%80%90android%E3%80%91%E3%80%8Ccom-example%E3%80%8D%E3%81%AF%E7%A6%81%E6%AD%A2%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%9F%E3%82%81%E3%80%81%E5%88%A5%E3%81%AE%E3%83%91%E3%83%83%E3%82%B1/#toc3
ただしbundle.gradeはプロジェクト直下と、app\srcにあるので注意。変えるのはapp\srcにある方。

2.アプリの表示名を変える。
\app\src\main\res\values\string.xmlのアプリ名を変更

```xml:string.xml
<resources>
    <string name="app_name">ここにアプリ名</string>
</resources>
```
最近働き始めたプログラミング塾が最高すぎるから話を聞いてくれ



こちらはNCC Advent Calendar5日目の記事です。

#自己紹介
私は都内の大学の情報系学部でプログラミングに関わる勉強をしている大学2年生です。
大学で学んでいることもことですし、デジタルイラストを描く、DTMを試してみるといったことでPC操作には問題はありませんでしたが、技術力にはさしたる自信はなく、「単発でもいいからプログラミング使ったバイトしてみたいなあ、卒業までに…」などと思っていました。
後述する内容とも関わってくるのですが、生まれてすぐに大病を患って生還し、障碍者手帳1級を持っている5歳下の弟がいます。

#働き始めた経緯
元々は美容部員として接客販売のバイトをしていました。とても好きなブランドで、大学4年間働きたいなと思っていましたが、コロナウイルスの影響で経営難が続き、2020年6月で契約満了を言い渡されました。大学2年6月のことです。
8月ごろに新たなバイトを探して応募し始めましたが、1年間接客販売をしていたにも関わらず販売系で撃沈し、(恐らくは)1年間接客販売しかしていなかったために飲食系でも撃沈し、そろそろ応募していないバイトが見つからなくなってきたので今まで無理だと思って検索すらしていなかったプログラミング系のバイトを探し始めました。
そこでこの記事で紹介する[LITALICOワンダー](https://wonder.litalico.jp/)を見つけました。ここでは小学校低学年から高校生向けの授業を展開していて、自宅から授業をするオンライン枠の講師を募集していました。

#どこが良いのか？
###企業ポリシーが素晴らしい
調べてみると、LITALICOワンダーは事業展開の1つで、元は現代のメジャーな働き方に障害を感じる人のための就業支援でした。弟が発達支援学校に通っており、企業ポリシーを読むうちに「この会社のビジネスを応援したい」という気持ちが湧いてきました。
この時点で販売系のバイトに受かってはいたので、それと並行して働くのが許可されるようであれば、多少無理してでも働きたい！と思いました。
###メンター(講師)どうしの仲がとてもいい
Zoomで顔を見るだけの仲ではありますが、アルバイト同士でも情報交換や相談などが盛んで、1質問や相談をするとその10倍ぐらいの(しかも多角的な)回答が返ってきますので、伸びようとすればするほど成長できる環境になっていると思います。授業自体はZoomのブレイクアウトルーム機能を使って行うので、対面教室のように授業の様子を小耳にはさむことはできませんが、その分教える側のスキルの可視化についてかなり力を入れていると思います。

###障害に対して科学的でフラットな見かたができている
LITALICOは他の塾と比較すると、特性のあるお子さんが多く通っているそうで、じっさい研修期間にもかなり時間を割いて、特性を持つお子さんについて学びました。「学び手は常に正しい」に代表される心構えから、実際にどう接すれば集中力を続かせたり、話を聞いてもらえたりするのか、さらにそこから「どんな声かけをすればその子の人生が拓けるのか」を学びました。
身内に障碍者がいる身としても違和感のある点が無かったのが印象的でした。

#終わりに
たかが大学生のアルバイトと言われてしまえばそれまでですが、個人的には「買い物は投票」以上に「アルバイトは投票」だと思っています。
給料や福利厚生、協賛企業は大事だとは思いますが、「加担したいビジネスか」という視点でアルバイトを選ぶ人が増えるといいなと思います。

##参考
[LITALICOワンダー HP](https://wonder.litalico.jp/)
[株式会社LITALICO 沿革](https://litalico.co.jp/about/history/)
Symfony で composer install --no-dev が失敗する

業務でSymfonyを利用していますが、先日、運用環境のデプロイでエラーが発生したので、備忘録を兼ねて投稿します。

- Symfony 3.0.1

# 発生したエラー

```
$ composer install --no-dev

Uncaught exception 'Symfony\Component\Debug\Exception\FatalErrorException' with message 'Error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Fatal error: Class 'Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle' not found in ...
```

# 原因

Composer scripts に以下のような記載があり、`copmoser install` 時に `cache:clear` が実行されますが、デフォルトでは `--env dev` で実行されます。

```json
    ...
    "scripts": {
        "post-install-cmd": [
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
        ],
        "post-update-cmd": [
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget"
        ]
    },
    ...
```

このため、存在しないバンドルに対してアクセスしようとしてしまい、エラーとなってしまいます。

# 対応方法

今回はデプロイコマンドで `composer install` していたので、`SYMFONY_ENV=prod` で実行してあげるだけでした。

```
SYMFONY_ENV=prod copmoser install --no-dev
```

手動でキャッシュクリアしている場合は、`cache:clear` にも `--env prod` を指定してください。


```
./bin/console cache:clear --env prod
```

同じエラーで悩んでいる方がいましたら、ご参考いただければと思います。

**参照**

https://github.com/symfony/symfony/issues/7403
実装未遂で終わった、GmailAPIとCloud Pub Subを使ったメール受信方法

はじめまして。peiii25です。
Qiita初投稿 & いえらぶGROUP Advent Calendar 2020 5日目 ということで緊張しておりますがお手柔らかにお願いします。

## 実装しようとした背景
2019年12月、Googleより[安全性の低いアプリから、G suite(Google Workspace)アカウントへの接続の無効化予定](https://gsuiteupdates-ja.googleblog.com/2019/12/g-suite_24.html)が発表されました。
※2020年3月、コロナの影響により延期が発表されました。(https://gsuiteupdates-ja.googleblog.com/2020/04/blog-post.html)

自社システムでメーラーを提供しており、GoogleアカウントのIDとパスワードでサーバーに接続をする従来の方法では、今後自社システムから接続できなくなる未来が予想されます。
よって、GmailAPIを利用したメールの送受信を実装しようとしました。

## [Gmail API](https://developers.google.com/gmail/api)を使うための準備
GmailAPIにはプッシュ通知機能が用意されています。これを実装するには
①Google Cloud PlatformでAPIの有効化
②OAuth認証設定
③Cloud Pub/Subでの設定
が必要になります。

## ①[Google Cloud Platform](https://console.cloud.google.com/?hl=ja)でAPIの有効化
APIの有効化を行うため、GCPで「プロジェクトの作成」を行い、GmailAPIとCloud Pub/Subを有効化します。

ここは手順が単純なため省略します。

## ②OAuth認証設定
ここでは大きく分けて2つやることがあります。
### 1.OAuth同意設定
GCPの左側のリスト「OAuth同意画面」で、自社システムから接続できるよう設定します。この時、GmailAPIの利用権限（スコープ）の選択をしないといけません。私はメールの送受信ができる権限`https://www.googleapis.com/auth/gmail.modify`を選択しました。
### 2.OAuthクライアントID作成
自社システムからGmailAPIを利用する際にOAuth認証のためのリダイレクトURLを指定します。

## ③Cloud Pub/Subでの設定
Cloud Pub/Subとは何か、[こちら](https://cloud.google.com/pubsub/overview)を参考にしてください。
Cloud Pub/Subでトピックを作成し、サブスクリプションで配信先（今回で言うと自社システム）を設定します
各アカウントのメールボックスに変更（受信や既読など）があると、変更内容をCloud Pub/Subを経由して、自社システムに送信されるイメージです。

GCPでトピックとサブスクリプションを作成します。
この時、トピックに「gmail-api-push@system.gserviceaccount.com」をPub/Subパブリッシャーとしてロールを与えると、Gmailの変更をCloud Pub/Subに送信できます。

## 自社システム側の実装
自社システム側で、APIからのメッセージを取得するメソッドを作成し、メール受信の変更のみを取得するよう実装をします。
メールボックスにメールが受信されたら、即時で受信メールの内容を自社システムに送ることができ、自社システムに取り込みが可能になります。

## いざ実装、と思ったら・・・
GmailAPIは、連携するWebアプリケーションがGoogleからOAuthの利用承認してもらわない限り機能が制限されるとのことでした。
また、承認には「第三者機関によるセキュリティチェック」が必要とのこと。
※費用感、承認までに期間などは[こちら](https://blog.ingage.jp/entry/2020/05/11/103000)を参考にさせて頂きました。

上記により、すぐに実装はできないと判断し実装未遂となりました。

## 開発してみた所感
* GCPのサービスを社内でだれも触っていなかったため、Cloud Pub/Subについて身近に質問や相談できる人が少なく苦労しました。
* GmailAPIの実装記事が少ない印象でした。GmailAPIやGCPの設定が複雑であるため、まだ本格的に実装を検討しているWebアプリケーションの開発者があまりいないのかなと思いました。

## おわりに
初めてQiitaに投稿させていただき、業務で培ったノウハウのアウトプットは自分の知識の整理になるな、と思う反面、さらに読みやすい記事にしていくため今後も精進していきます。
ご質問などあればコメントしていただければと思います。

最後まで読んで頂きありがとうございました。
Upstartのことも調べてみたよ

## 勉強前イメージ

SysVinitの後継機。
何がよいのかは知らない

## 調査

### Upstartとは

- Upstartの概要・特徴

最初はSysVinitと同様に `initプロセス` が起動します
しかしその後、SysVinitの直列起動ではなく、並列で起動が走ることにより起動時間が短縮されました。
また、 `イベント駆動型` になったのが大きな特徴です。
イベントをトリガーとしてジョブを起動することによって、プロセスが起動します。
イベントというのは、とあるサービスが起動開始したタイミングやランレベルが変わったなどもイベントとして設定でき、
依存関係があっても条件がそろった時点で起動します

- Upstartとは起動の順番でいうとどこか

これは、 SysVinitもUpstartの後継のsystemdも変わらず、
5番目のプロセス実行に値します。

1. 電源を入れる
2. BIOS/UEFIの起動
3. ブートローダーの読み込み
4. カーネルの読み込み
5. プロセス実行 ←ココ！！！
6. ログイン可能

### Upstartの詳細見ていく

#### Upstartの起動順序

- 1. initプロセスが開始される(pid=1)

initプロセスが開始されることについては、SysVinitと変わらず

- 2. 各ジョブが待機状態でイベント待ち

`概要・特徴` で記載したが、Upstartはイベントをトリガーとしているので
「起動する」というイベントを待機する

- 3.システム起動のイベントが発行される

「起動する」というイベントが発行され、このイベントをトリガーとしてジョブが起動され、プロセスが上がってきます

- 4.イベントに対応したジョブが `並列で` 実行される

↑で書いた、「トリガーとしてジョブが起動され、プロセスが上がってきます」 に値する箇所。
そして、SysVinitとの違いが `並列` での実行になります。

#### あれ？/etc/inittabは使わなくなった？

Upstartが適応されている、CentOS6で確認しました。

- 本文ママ

```text:/etc/inittab
[root@localhost ~]# cat /etc/inittab 
# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
# 
id:3:initdefault:
```

- 翻訳

要するにデフォルトランレベルの設定しか書いてないし、
ここになにか追加しても変更されないよ と言われてます。

```
# inittabはupstartがデフォルトのランレベルでのみ使用します。
#
# ここに他の設定を追加しても お使いのシステムには何の影響もありません.
#
# システムの初期化は/etc/init/rcS.confで開始されます．
#
# 個々のランレベルは/etc/init/rc.confで起動されます.
#
# Ctrl-Alt-Delete は /etc/init/control-alt-delete.conf で処理されます。
#
# 端末のgettyは/etc/init/tty.confと/etc/init/serial.confで処理されます。
# 設定は /etc/sysconfig/init で行います。
#
# upstart イベントハンドラの書き方や
# init(5)、init(8)、initctl(8) を参照してください。
#
# デフォルトのランレベル. 使用されるランレベルは以下の通りです。
# 0 - halt (initdefaultには設定しないでください)
# 1 - シングルユーザーモード
# 2 - マルチユーザ、NFSなし (ネットワークがない場合は3と同じ)
# 3 - フルマルチユーザーモード
# 4番 - 未使用
# 5 - X11
# 6 - 再起動 (これに initdefault を設定しないでください)
# 
id:3:initdefault.
```

## 勉強後イメージ

まだinitは生き残ってた。
Upstartでは並列になってるから、結構SysVinitは直列でで起動させるのは遅かったというのがネックだったっぽい...
Upstartになって、誰かからの反応なかったら何もしませんよーって感じらしい。
さて次はsystemdだー

## 参考

- [いますぐ実践! Linux システム管理 / Vol.188 / 読者数:1641名](http://www.usupi.org/sysad/188.html)
- [【初級者向け】Linuxシステムの起動 ～ SysVinit、Upstart、systemd ～](https://tech.pjin.jp/blog/2020/11/11/linux-system-boot-2/)
- [SysVinitとUpstartとSystemdについて](https://blog.goo.ne.jp/ykariunai77/e/e7b741bd9da9b6bd9802ff2c6c0e051b)
フロントエンド開発の作業環境を整備して開発効率を爆上げする

モダンなフロントエンド開発向けに、作業環境をサクッと整備して、ガンガン開発効率をあげましょう。

VSCode + TypeScript + React の構成を想定しています。

# Visual Studio Code

https://code.visualstudio.com/

圧倒的人気[^1]を誇るテキストエディタ。略称 VSCode 。

- **スピード（起動／実行速度）良し**
- **コスト（オープンソース／無料）良し**
- **品質（強力なコード補完、見やすいUI 等々）良し**

で三拍子揃ってるので言うことなし。

[^1]: [The State of JavaScript 2019 の Other Tools における Text Editors](https://2019.stateofjs.com/other-tools/#text_editors) において `Which text editor(s) do you regularly use?` で 56% 以上を取得

# ESLint

https://eslint.org/

JavaScript (EcmaScript) 用リンター。

GitHub Star 数 17.5k 。リントツールとして定番中の定番。

VSCode 拡張機能は VSCode Marketplace から ESLint で検索してインスール。

- [ESLint (dbaeumer.vscode-eslint)](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)

# Prettier

https://prettier.io/

コードフォーマッタ。

HTML 、CSS 、 JavaScript を始めとして様々なプログラミング言語をサポート。
VSCode はもちろん Vim や Emacs 、Sublime Text といったテキストエディタもサポート。

VSCode 拡張機能は VSCode Marketplace から Prettier で検索してインスール。

- [Prettier - Code formatter (esbenp.prettier-vscode)](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)

# Node.js

https://nodejs.org/en/

JavaScript 実行環境。

サーバサイド JavaScript とも言われる。
インストール時に同梱されている **npm**（パッケージマネージャ）がもはやフロントエンド開発において必須になっている。**npx** も便利。

# TypeScript

https://www.typescriptlang.org/

JavaScript 拡張言語。

静的型付け可能な JavaScript と言われる。みんな大好き、型。

# React

https://reactjs.org/

UI 構築用の JavaScript ライブラリ。

Vue.js や Angular とともにフロントエンドフレームワークとして人気。
世界ではその他 2 つよりも圧倒的な人気[^2]がある。

みんな React やろう！

- ["React 未学習者 Q.「React って学習コスト高いんでしょ？」A.「"](https://qiita.com/drytt/private/8122e043c16ddeef924a)

[^2]: [npm trends](https://www.npmtrends.com/react-vs-vue-vs-@angular/core) では React が Vue.js や Angular のダウンロード数を圧倒している。

# 最後に

VSCode のターミナルから以下コマンドを実行して、早速開発を始めましょう！
my-app は任意の名前を設定してください。

```
$ npx create-react-app [my-app] --template typescript
```
赤くなったKindle Fire HDを復活させる(未完)

## はじめに

先に言っておきますが、まだ解決していません。

## 問題の端末

Kindle Fire HD 32GB タブレット(第2世代)
https://www.amazon.co.jp/gp/product/B00960YRBI/
https://developer.amazon.com/ja/docs/fire-tablets/ft-device-specifications-firehd-models.html?v=firehd7_2012

2012年に買った端末ですが、ここ数年はイベントなどでサイネージ端末として活躍していました。

## 障害内容

ある日電源を入れると真っ赤な画面が表示され起動しない状態になる。

すごく赤いです。
![kindle_fire_red_screen.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/811ce904-b87f-0aeb-c428-88e8444f6c8e.jpeg)

## 復活への道

とりあえず工場出荷時に戻そうと色々やってみたが症状は変わらず。
検索するとこいつは、Motorola製の端末らしく、Factory Cableという特殊なUSBケーブルを使用するとFastbootモードというので起動してファームウエアを上書きできるようだ。
検索すると自作方法が出てくるが、面倒臭いのでAliExpressで注文する。

FactoryCable
https://www.aliexpress.com/item/32643090805.html

約2週間後に届いたFactory Cable(なぜか2本入り、おまけ？)

![factory_cable_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/5717f8d3-4782-4743-1088-3b60ea901367.jpeg)

Fastbootモードでの起動に成功

![fastboot_mode_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/d8892240-b946-fe58-69ff-f903a50551b8.jpeg)

しかし、PC(Macbook Pro)からはデバイスとして認識されず。

```
hichon-no-MacBook-Pro:~ hichon$ adb kill-server
hichon-no-MacBook-Pro:~ hichon$ adb start-server
* daemon not running; starting now at tcp:5037
* daemon started successfully
hichon-no-MacBook-Pro:~ hichon$ adb devices
List of devices attached

hichon-no-MacBook-Pro:~ hichon$
```

というわけで、続く(？)

## 参考

https://forum.xda-developers.com/t/bootloader-2nd-bootloader-for-custom-roms-on-kfirehd-7-06-24-cm12-1-twrp-2-8-7-0.2128848/
iOS14 で実装された PIP の操作感を UIKit で再現してみた

# はじめに
今回は、 iOS14 で実装された純正ピクチャ・イン・ピクチャ（PIP と表現）の挙動を再現するにあたってこだわったアニメーション周りの処理についてご紹介いたします。
ご紹介する挙動を皆さんにもより早く体感していただけるよう、この度**自作PIPの実装をサポートライブラリを作成** いたしました！ iOS14 未満でもPIPをプロダクトで利用することが可能となりますので、ぜひそちらも参考にしてみてください。

[🎈FloatingShowable](https://github.com/AkkeyLab/FloatingShowable)

# 前提条件
この記事は [FloatingShowable](https://github.com/AkkeyLab/FloatingShowable) を軸に執筆いたしました。このライブラリの機能を簡潔にご紹介いたします。

- UIViewController を FloatingShowable に準拠させるだけでPIPに対応
- 上下左右の4箇所に静止
- PIP から指を離した時、加速度を加味して静止位置を決定
- PIP の移動可能領域が指定可能

# アニメーション
1. 表示
2. 非表示
3. ドラッグ＆ドロップして所定位置に移動
4. 可動領域が変化したときの移動

1, 2, 4 に関しては比較的単純なアニメーションになります。

```swift
        UIView.animate(
            withDuration: transitionAnimationWithDuration,
            delay: .zero,
            options: .curveEaseOut,
            animations: { [weak self] in
                self?.view.alpha = 1
            }
        )
```
`options` に指定する値に関しては、表示・非表示に `.curveEaseOut` を指定しています。表示・非表示の開始がゆっくりになると、それを「処理が重くて処理落ちしている」という感覚を得ることがあるためです。

可動領域が変化したときの移動に関しては `.curveEaseInOut` を指定しています。可動領域を変化させるということは、PIP が重なってはいけないコンテンツが表示または移動したということです。つまり、「逃げる」という挙動になるため、アニメーションの始まりにも滑らかさを出しています。

3 に関してはバネのような効果を追加したアニメーションになります。

```swift
       UIView.animate(
           withDuration: gravitateAnimationWithDuration,
           delay: .zero,
           usingSpringWithDamping: gravitateSpringWithDampingRatio,
           initialSpringVelocity: gravitateSpringWithVelocity,
           options: .curveEaseOut,
           animations: { [weak self] in
                guard let self = self else { return }
                self.updateFrame(position: self.position)
            }
       )
```
各種パラメータは頑張ってチューニングした箇所になりますので、ぜひ[ライブラリ](https://github.com/AkkeyLab/FloatingShowable)側も参考にしてみてください！
iOS14 純正PIP をじっくり観察してわかることの一つに、このバネ効果があります。停止時に、加速度に合わせて小さく跳ね返っていることがわかると思います。

現在は加速度に関係なく一定のバネ効果を得られるようになっていますが、今後、加速度に合わせたバネ効果となるように改善してい行きます！

# 加速度
厳密には、ジェスチャー時に得られる速度で判定を行います。

```swift
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addGestureRecognizer(
            UIPanGestureRecognizer(target: self, action: #selector(onTransition(sender:)))
        )
    }

    @objc private func onTransition(gesture: UIPanGestureRecognizer) {
        switch gesture.state {
        case .changed:
            ...
        case .ended:
            position = updatePosition(velocity: gesture.velocity(in: nil))
            ...
        default:
            break
        }
    }

```
`gesture.velocity(in: nil)` で速度を取得しています。この値のハンドリングも、ぜひ[ライブラリ](https://github.com/AkkeyLab/FloatingShowable)側を参考にしてみてください！
得られる値は `CGPoint` です。つまりX軸とY軸向きの速度が取れるということです。これによって今移動しようとしている方向とその速さが計算できます。

PIP の静止位置は速度だけでは決定できません。 **今PIPがどこにあるか** を考慮する必要があります。
「画面を上下左右向きの4つに分割した時、現在左上にいて、加速度が右下向きに一定定数以上であれば静止位置は右下」
このような判定処理を行います。

# さいごに
最後まで読んでいただき、ありがとうございます！
今回は日頃の開発での学びをアウトプットするという方法を記事とライブラリという2軸で行ってみました。これが皆さんの学びのきっかけになれることを願っています。
登山アプリについてメモ（2020年の年末）

#登山アプリ
昔はケータイのGPSになんて頼るなんて考えもしませんでしたが、もう位置情報などはスマホアプリで確認するような時代になりつつありますね。
なかなか登山アプリも発展してきて面白そうだなぁと思う今日この頃です。
自分のアプリ開発にも役に立ちそうなので、今現在の登山アプリについてそれぞれ軽くメモしておこうと思います。

<b>ヤマレコ</b>
マップ表示及び山行記録ができます
Webサービスとしてのヤマレコは以前から山行記録サービスとして有名（お世話になりました）
無料だと地図は一度に２つまで
プレミアムプラン（年3400円または4900円）もあり
日記などSNSもあり
App内広告あり
地図はGoogle Map（国土地理院地図）など
（ヤマレコAPIもあります）

<b>YAMAP</b>
マップ表示及び山行記録ができます
ライト層にも使いやすい、初心者に優しい？
シンプルで今風なデザイン（結構なお金かけてそう）
タイムラインとかフォロワーとかSNS的な面も多い
YAMAP STOREもありアウトドアグッズが買える
無料だと地図は一度に５つまで
プレミアムプラン（月４８０円または２９０円、学生無料）もあり
地図はMapboxなど

<b>ジオグラフィカ</b>
個人開発（？）していることが特徴的なGPSアプリ
表示形式など細かい設定が充実している
９８０円で機能制限解除
地図はGoogle Map（国土地理院地図）など


#今日の名言
I think the really good mountaineer is the man with the technical ability of the professional and with the enthusiasm and freshness of approach of the amateur.
（本当に優れた登山家とは、プロの技術力とアマチュアの熱意と新鮮な新しさを持つ人だ。）

-エドモンド・ヒラリー（冒険家・養蜂家）
Build FTP servers on Oracle Linux 7 in the Oracle Cloud Infrastructure

# Step.1 Change OS basic configuration on FTP Server
## Step.1-1 Stop SELINUX and Firewall
```
sudo setenforce 0
sudo sed -i -e 's/=permissive/=disabled/g' /etc/selinux/config
sudo systemctl stop firewalld.service
sudo systemctl disable firewalld.service
```
## Step.1-2 Change OS users password rule (DO NOT for PRODUCTION Services)
```
grep 'password    requisite     pam_pwquality.so' /etc/pam.d/system-auth
grep '= enforce_for_root' /etc/pam.d/system-auth
sudo sed -i -e 's/= enforce_for_root/= /g' /etc/pam.d/system-auth
grep -v '^#' /etc/security/pwquality.conf
sudo sed -i -e 's/ucredit/#ucredit/g' /etc/security/pwquality.conf
sudo sed -i -e 's/ocredit/#ocredit/g' /etc/security/pwquality.conf
echo "ucredit = 0" >> /etc/security/pwquality.conf
echo "ocredit = 0" >> /etc/security/pwquality.conf
```
# Step.2 [FTP Server Installation on OracleLinux7](https://qiita.com/maxc/items/e7e326f408dd1a612c3e)
## Step.2-1 Create user and FTP data directory
```
sudo groupadd -g 55555 ftpgrp
sudo useradd -u 55555 ftpuser -g 55555 -G ftpgrp
sudo echo "ftpuser" | passwd --stdin ftpuser
sudo mkdir -p /var/nfs/ftp
sudo chown ftpuser:ftpgrp /var/nfs/ftp
sudo sed -i -e 's/authtok_type=/authtok_type= enforce_for_root/g' /etc/pam.d/system-auth
```
## Step.2-2 Modify Config file
```
sudo sed -i -e 's/anonymous_enable=YES/anonymous_enable=NO/g' /etc/vsftpd/vsftpd.conf
sudo sed -i -e 's/#chroot_l/chroot_l/g' /etc/vsftpd/vsftpd.conf
sudo sed -i -e 's/chroot_local_user=NO/chroot_local_user=YES/g' /etc/vsftpd/vsftpd.conf
sudo sed -i -e 's/listen=NO/listen=YES/g' /etc/vsftpd/vsftpd.conf
sudo sed -i -e 's/listen_ipv6=YES/listen_ipv6=NO/g' /etc/vsftpd/vsftpd.conf
echo pasv_enable=YES >> /etc/vsftpd/vsftpd.conf
echo user_config_dir=/etc/vsftpd/user_conf >> /etc/vsftpd/vsftpd.conf
mkdir /etc/vsftpd/user_conf
touch /etc/vsftpd/user_conf/ftpuser
echo local_root=/var/nfs/ftp > /etc/vsftpd/user_conf/ftpuser
echo ftpuser >> /etc/vsftpd/chroot_list
```
## Step.2-3 Restart service
```
systemctl restart vsftpd
systemctl status vsftpd
```

# Step.3
## Step.3-1 Install FTP Client
```
sudo yum -y install ftp
```
## Step.3-2 Confirm FTP Connection
```
ftp ftpuser@localhost
```
AWS認定SAA取得までの流れ

## 概要

「AWS 認定 ソリューションアーキテクト – アソシエイト」を取得しました
SAA-C02版の情報がまだ少ないかなと思い、今後取得を目指す方の参考になれば幸いです

## 前提

実務でのAWS経験は2年ほどですが、メインはサーバーサイドエンジニアなので理解できないまま使用している箇所も多い状態でした

## 勉強期間

2020年10月12日-11月29日（約1ヶ月半）

## 試験会場

銀座CBTS歌舞伎テストセンター

## 教材

Udemyの講座のみで受験しました

- [これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）](https://www.udemy.com/course/aws-associate/)
- [【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)

## 費用

- Udemy（セール時に購入） ¥3,430
- AWS ¥1,452
- 受験料 ¥15,000

## 勉強方法

約1ヶ月かけてUdemyの講座を一通り行いました（1日1-2時間ほど）
ここではハンズオンを行いながら、ノートにメモを取るレベルでゆるく受講していました
その後半月かけてUdemyの模擬試験を2周ほど行い90%以上取れる状態にしました（毎日模試を1つ&復習）
わからなかった問題はメモしておき、いつでも見直せる状態にしていました

## 注意点・後悔

Udemyの講座でハンズオンが終わった後AWSの料金は確認するべきでした（余分な費用がかかってしまった）
ストレージ周りの問題が多かったのでもう少し公式資料を読み込んでおくべきでした（[こちら](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)）
テストセンター入り口のエレベーターが10時からで動作しておらず迷いました
NetworkManagerで802.1xプロトコルを使用したwifiのホットスポットに機器を繋げたい

こちらは[ITRC Advent Calendar 2020](https://adventar.org/calendars/5535)の5日目の記事です。
前の記事: 私の[TUNモジュールによるDockerのロードエラーとlinuxカーネル](https://qiita.com/blue_key/items/82facd82e9383c711534)
次の記事: [@himazin_shotaML](https://twitter.com/himazin_shotaML)さんの[超解像技術-SRGAN-実装してみた(Tensorflow 2.0) 推論フェーズ編](https://qiita.com/hima_zin331/items/5e30201c20c04ff16d64)です。

## 事の発端

802.1Xで設定されたwifiのホットスポットにNetworkManagerの```nmtui```によるGUIで設定できないことがわかった。
どうやら```nmcli```によるCLIでの設定なら可能という情報を得たがパスワードを打つとbash_history等に残ってしまうのでパスワードは履歴が残らないようにした。

## 環境

- Arch Linux
- networkmanager-1.26.4-1

## 解決方法

1. ```nmcli```コマンドでホットスポットを接続先に追加する

```sh
nmcli connection add type wifi con-name "[プロファイル名]" ifname [インターフェイス名] ssid "[SSID名]" wifi-sec.key-mgmt wpa-eap 802-1x.eap peap 802-1x.phase2-auth mschapv2 802-1x.identity "[ユーザー名等のID]"

# 具体例
nmcli connection add type wifi con-name "MySSID" ifname wlp3s0 ssid "MySSID" wifi-sec.key-mgmt wpa-eap 802-1x.eap peap 802-1x.phase2-auth mschapv2 802-1x.identity "USERNAME"
```

2. その後```nmtui```でGUIを起動してSSIDを選択し、パスワードを入力する

## 使用したオプションの詳細

| オプション | 詳細 |
| --- | --- |
| connection add | 新しいアクセス先を追加 |
| type wifi | 無線であることを指定 |
| con-name "[プロファイル名]" | 作成されたホットスポット接続プロファイル名を指定 |
| ifname [インターフェイス名] | インターフェイス名(自分のPC,eth0やwlp3s0など) |
| ssid "[SSID]" | ホットスポットのSSID名を指定する |
| wifi-sec.key-mgmt | 暗号化の種類を選択 |
| 802-1x.eap | 認証の種類を選択 |
| 802-1x.phase2-auth | EAPの内部のTLSトンネルに使用するEAPメソッドに許可されるフェーズ2内部の非EAP認証のメソッドを指定する |
| 802-1x.identity | EAP認証方法のIDを指定する |

### コマンドを具体的に見る

```sh
# 接続先の追加する。結論先行型。
nmcli connection add \

# MySSIDという名前でプロファイルを作成し、インターフェイス名をwlp3s0,ssidをMySSIDと指定
type wifi con-name "MySSID" ifname wlp3s0 ssid "MySSID" \

# 暗号の種類をwpa-eapを指定
wifi-sec.key-mgmt wpa-eap \

# 802-1xの認証のEAPメソッドからpeapを指定
802-1x.eap peap \

# フェーズ2内部の非EAP認証のメソッドにmschapv2を指定
802-1x.phase2-auth mschapv2 \

# EAP認証方法のIDをUSERNAMEと指定
802-1x.identity "USERNAME"
```

## 感想

認証の種類や方式を知らなかったので調べるきっかけになり勉強になりました。

## 参考

- [How to connect to an 802.1x wireless network via nmcli Ask Question StackExchange](https://unix.stackexchange.com/questions/145366/how-to-connect-to-an-802-1x-wireless-network-via-nmcli)
- [802.1X 標準を使用したネットワークへの RHEL クライアントの認証 Redhat](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_and_managing_networking/authenticating-a-rhel-client-to-the-network-using-the-802-1x-standard_configuring-and-managing-networking)
- [IEEE802.1X Wiki](https://ja.wikipedia.org/wiki/IEEE_802.1X)
いつ送信されたものなのか「○分前」と表示させたい

#はじめに
　チャットの中で、送信された時刻だけでなく、それが今からどれくらい前なのか簡単に表示させることができないかと考え、調べたものをまとめておく。
　調べるまでは、今の時刻から、送信された時刻を引くのかなぁと漠然と考えていたが、超絶便利なメソッドがあった。

##○分前と表示させる方法

```erb
<%= time_ago_in_words(message.created_at) %>前
```
`message`の部分はコントローラーから渡しているインスタンス変数が入る。
`time_age_in_wordsメソッド`、中学英語みたい。

##終わりに
　アプリケーションを作っていて気づいたが、時間に関するメソッドや機能ってたくさんあって便利！英語が苦手だったけど、プログラミングに出てくる英単語って中学生でもわかるレベルのものがたくさんあって、英語アレルギーが出ないし、逆にわかるから楽しい！！単語一つのメソッドもたくさんあるが、前置詞がついて痒いところに手が届く系のメソッドも面白い。
Raspberry PiのSambaのファイル転送がクソ重かった時の対処メモ


Raspberry PiにSambaを入れてファイル転送してたのですが、最近めちゃめちゃ重くなってきたので調べたときのメモです。

## 原因はSambaではなくパワーセービング機能

SSHも重くなってたので、SSH周りで調べてたら見つけました。

> * [Raspberry Piで無線LANの反応が悪い時の対処法](http://denshikousaku.net/fix-sluggish-response-of-raspberry-pi-wifi-adaptor)
> * [Raspberry PiでSSHの反応が悪いときに実施すること](https://qiita.com/yujimny/items/4008be640c043a3478b4)


どうやら（最近の？）ラズパイはある程度時間が経つと省電力モードみたいな感じになってWi-Fiを受け付けなくなるとのことです。

> *[Raspberry PiのWifiは1日放置するとパワーマネージメントが働いてpingも受けなくなるので設定変更が必要](https://usepocket.com/c/UP1373.html)

## パワーセービング機能をオフ

このパワーセービング機能をオフにすることで、転送速度問題が解消されました。

`/etc/modprobe.d/8192cu.conf`を作成して、設定を書き込むことでオフにできる模様です。

```
sudo vi /etc/modprobe.d/8192cu.conf
```

ファイルの中身に以下を書き込んで保存。

```
options 8192cu rtw_power_mgnt=0 rtw_enusbss=1 rtw_ips_mode=1
```

再起動するとだいぶ反応よくなりました。

```
sudo reboot
```
Redis落とした話

初投稿です！
いえらぶアドベントカレンダー 18日目

1年目インフラエンジニアが自社にあるRedisサーバー移管でやらかしたお話しをします。
関係各所には多大なるご迷惑をおかけしたうえ、復旧作業にもご協力いただきまして感謝と申し訳なさでいっぱいです。
本当にありがとうございました。

# 結論
よく分かってないものを分からないまま触らない

# そもそもRedisとは
- NoSQLデータベースの1つ
- 馴染み深いMySQLのようなRDBとはデータの保存形式が違う
- RDBが1レコードに複数のカラムを紐づけて保存するのに対し、Redisはkey-value型でデータを保存する
- keyを指定することでvalueを呼び出す
- データがすべてメモリに乗っているため爆速

# やらかし詳細
縁あってRedisサーバーを移管することに。
これまでにもサーバー移管は何度か対応していたうえ、自社ではRedisが冗長構成ということもあってそこまで心配ないだろうと思っていた。

### そしてその時はやってきた
今までの対応通り、対象のサーバーをシャットダウン。
続きの作業に取り掛かっていたその時、社内の方から突然の連絡。

「サーバーで何か異常ありませんか？」
「このページが映らないんですけど...。」
見事にRedisを使用しているページである。

((((；ﾟДﾟ))))ｶﾞｸｶﾞｸﾌﾞﾙﾌﾞﾙ

すぐに自分でも教えてもらったページを確認
→ 映らない

同じサーバー構成の別ページを確認
→ 映らない

「え、絶対Redisだよね。。。あれ、冗長化してるんじゃないの！？」

落としていないはずのRedisサーバーを見たところ起動はしている
ただ負荷が低すぎる。。。

「どゆこと...？？？？？？？？？？」

とりあえず落としていたRedisをすぐに起動し、復旧作業へ

### 何が起きていたか
#### 復旧中・復旧後の調査などから分かったRedisの特性
・Redisはクラスター(cluster)という形で冗長化を図っている
・ポート違いで1台のサーバーにマスター, スレーブを持つことが可能
・マスターが落ちた場合は対応するスレーブが昇格する
・クラスター内で互いにpingを飛ばしあい、生存確認をし続けている
・マスターの数が保てなくなるとクラスターごと落ちる

#### 上記特性を踏まえ、こんなことが起こっていたのではないかというシナリオ
・サーバーシャットダウン時にそのサーバー内のRedis(マスター、スレーブ両方)が落ちる
・別サーバーのRedisから生存確認のpingが送られてくるが生存反応がない
・落ちたマスターに対応するスレーブは別サーバーにあるため、そちらをマスターに昇格させようとしたが、サーバーごと落ちているためマスターから「自分、死にました」のpingさえ来ず昇格しようにもできない
・クラスター全体で見たときにマスターの数が保てなくなり無事死亡

#### 多分こうすればよかった
・サーバーシャットダウン前にクラスター内でのマスター、スレーブの関係を確認
・Redisを停止し、対応するスレーブが昇格していることを確認
・上記確認後にサーバーシャットダウン

# まとめ
- ソフトウェア、ミドルウェア、ハードウェアの別に関わらず、作業前には構成をしっかりと把握する
- 似たような作業はやったことがあるかもしれないけどその作業はやったことがないと自覚する
- 手順書をさぼらず書く。
- 慢心しない。油断しない。日々勉強。

# 調査時に参考にさせていただいた記事
Redis Cluster検証: https://qiita.com/ono-soic/items/a41044c977da5231297b
Laravelでメール送信をする驚くほど簡単な手順

ほぼ自分用のメモなので、サクッと書きます。

というかhttps://reffect.co.jp/laravel/laravel-send-email#Mail の内容をまとめているだけです。笑

#とりあえずコントローラー作成。

```
php artisan make:controller SampleMailController
```
#ルーティングの追加

```
Route::get('/mail', 'SampleMailController@send');
```

#MessageSendコントローラーに処理を追加。

```
use Mail;

class MailSendController extends Controller
{
    public function send(){

    	$data = [];

    	Mail::send('emails.test', $data, function($message){
    	    $message->to('111@example.com', 'Test')
　　　　　　　　　　　　->subject('This is a test mail');
    	});
    }
}
```

sendメソッドの解説。
第一引数、メールの本文の内容を記述するビューの名前です。htmlタグが使えます。
第二引数はビューに渡す変数です。
第三引数はメッセージインスタンスを受け取るクロージャ()です。メッセージインスタンスはto, from, cc, subjectなどのメソッドを持っています。詳しくはメッセージインスタンスのマニュアルを確認してください

#メールで送るビューファイル作成
```
views/emails/test.blade.php
中身は適当に好きなように作る
```
#.envファイルの修正

```
MAIL_DRIVER=smtp
MAIL_HOST=XXXXX.jp　//サーバのドメイン名やIPアドレス
MAIL_PORT=587　//ポート番号は各環境に依存
MAIL_USERNAME=XXXXX@XXXXX.co.jp　//メールで利用するユーザ名
MAIL_PASSWORD=XXXXX //メールで利用するパスワード
MAIL_ENCRYPTION=null
```
上記の通り記述。

ここでGmailを使えば無料のSMTPが使えてメールを送信することができる。

開発用なら[MailTrap](https://mailtrap.io/)が便利らしい。

これで簡単なメール機能の実装は終了。あとは好きなようにカスタマイズすればOK。
Vuetifyで最上面に表示する

#Vuetifyで要素を最上面に表示したい
重なり順のお話

###アラート表示が「v-overlay」の下に...
めちゃくちゃ頑張ってアラート機能を作りましたが，画像のように「v-dialog」の「v-overlay」の下に，，，
因みにこのアラートは「App.vue」に記載して「z-index」は99にしてました．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206742/7c0aa248-23b5-14b2-a89a-6ccc97d0a83c.png)

###z-indexを999にして解決
取り敢えず適当に「z-index」を999にしたら解決．
おおー！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206742/36bff1fa-4451-1c78-43bc-5d6dfbe8ce14.png)

###「v-overlay」の「z-index」は201
Chromeのデバッグ機能で覗いた感じ，どうやら「v-overlay」の「z-index」は201っぽい．
これが固定なのか動的に定められているのかはわかりませんが，，，
ま，取り敢えず202にしたら解決

###「z-index」はどこまで？？
これまで「z-index」は99が最大と思ってました．
いやいやVuetifyがルール破るはずがない
この際調べてみたところ，最大値は「2147483647」とか
こりゃもう一時安心，，，
まあ，ブラウザとかによるとも思うので参考まで

ではでは～
あ，因みに私これが多分初記事です
よろしゅうに
【FileMaker】キーチェーン、使ってますか？

iOSでは「キーチェーン」、Windowsだと「パスワードを資格情報マネージャー」と言われる、いわゆるFaceIDやTouchIDなどでログインする仕組み、FileMakerでも使えますが、みなさん使っていますか？

# FileMakerバージョン
意外とTouchIDが標準で装備されたのは、バージョン15のときなので、顔をかざして、とか指紋認証でFileMakerファイルにログインするのは15以上、となります。

# アカウント管理
管理＞セキュリティでアカウントを追加して、アカウントを追加します。
独自にログイン管理をしている（セキュリティのアカウントを使って管理していない）場合は、今回のキーチェーン動作の対象外です。
![スクリーンショット 2020-12-05 19.15.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/938c447b-cb1a-1a06-8fff-9e1669cfa8fe.png)

# ファイルの設定
ファイルオプションで、以下のように設定します。
「次のアカウントを使用してログイン」のチェックを外し、
「保存されている視覚情報による認証を許可」にチェックをします。
これが、キーチェーンを使用する、ということになります。
![スクリーンショット 2020-12-05 19.14.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/a36dc738-0b46-3f90-be11-471b3c5c6de3.png)

# 開いてみる
では、アカウントを設定したファイルをFileMaker Goで開いてみましょう。
最初は、こんな「FaceIDを使うかどうか」の許可画面が出ます。
許可した後は、いくつファイルを開いてもこの画面は出ません。
![IMG_3319.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/410d2cc8-1365-c91c-e0a9-0ce35001cbfa.png)

アカウントをキーチェーンに登録するため、最初はログイン画面が出てきます。
ここでサインインしたアカウント情報がキーチェーンに登録されます。
![IMG_3324.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/5251bf98-7729-32c8-c7d0-451425013599.png)

次回からは、おなじみの顔が出てきて、該当ファイルへのログイン、最初のレイアウトの表示、という流れになります。
![IMG_3322.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/fb8673d0-333e-f6de-0b29-3cbbaae94ea0.png)

# ログインでキーパットを見せない
タブレット端末でログイン動作をする際は、どうしてもアカウント情報を入れるためにキーパットが出てきて、他の人に入力している手元を見られる可能性があります。
こうした漏洩を防ぐという目的で、キーチェーンを活用するのもいいかもしれません。
（いくら毎回入力しなくてもいいとなっても、本当にアカウント情報を忘れてはいけませんよ！）
Simple Proofs of Cointegration Properties Written in English  共和文に関する証明

<B>Cointegration Proofs<B>

The proofs below are what I thought about a long time ago when I was a master student.

Proposition 1.1. Let $x_{t}$ ~ I(1), $y_{t}$ ~ I(1) and $z_{t}$ ~ I(1). Suppose $x_{t}$ and $y_{t}$ are cointegrated and that $x_{t}$ and $z_{t}$ are co-integrated. Then, $y_{t}$ and $z_{t}$ are co-integrated.

(Proof)
Let $x_{t}$ + $ky_{t}$ ~ I(0) and $x_{t}$ + $k΄z_{t}$ ~ I(0). Then, it is claimed that $ky_{t}$ − $k΄z _{t}$~ I(0). 
  
Suppose $ky_{t}$ − $k΄z_{t}$ ~ I(1). Then, ($x_{t}$ + $k΄z_{t}$) + ($ky_{t}$ − $k΄z_{t}$) = $x_{t}$ + $ky_{t}$ ~ I(0). But the left-hand side of the equation is the sum of I(0) and I(1), which is I(1). Thus we have a contradiction.

Corollary 1.2. Let $x_{t}$ ~ I(1), $y_{t}$ ~ I(1) and $z_{t}$ ~ I(1). Suppose $x_{t}$ and $y_{t}$ are cointegrated and that $y_{t}$ and $z_{t}$ are co-integrated. Then, $x_{t}$ and $z_{t}$ are co-integrated. 

(Proof)
Use proposition 1.1. $y_{t}$ and $x_{t}$ are co-integrated , and $y_{t}$ and $z_{t}$ are co-integrated. Then, $x_{t}$ and $z_{t}$ are co-integrated.

Proposition 1.3. Let $x_{t}$ ~ I(1), $y_{t}$ ~ I(1) and $z_{t}$ ~ I(1). Suppose $x_{t}$ and $y_{t}$ are cointegrated and that $x_{t}$ and $z_{t}$ are co-integrated. Then, $x_{t}$ , $y_{t}$, and $z_{t}$ are co-integrated.

(Proof)
Let $x_{t}$ + $αy_{t}$ ~ I(0) and $x_{t}$ + $βz_{t}$ ~ I(0). From the previous proposition, $αy_{t}$ − $βz_{t}$ ~ I(0).Now it is claimed that $x_{t}$ + $2αy_{t}$ − $βz_{t}$ ~ I(0). That is, $x_{t}$, $y_{t}$, and $z_{t}$ are co-integrated. Suppose not. Then, 
$x_{t}$ + $2αy_{t}$ −$βz_{t}$ ~ I(1). 
− ($αy_{t}$ − $βz_{t}$) + ($x_{t}$ + $2αy_{t}$ −$βz_{t}$) = $x_{t}$ + $αy_{t}$~ I(0). 
However, the left-hand side of the equation
is the sum of I(0) and I(1), which is I(1). Thus we have a contradiction.
Juliaスクリプトをros2コマンドからrun/launchする方法

# 環境
- ROS2 Foxy
- WSL2
- Julia 1.4.1

# ディレクトリ構造
- hello
    - CmakeLists.txt
    - launch
        - hello.launch
    - script
        - hello.jl

# Juliaコード
先頭に`#!/bin/julia`を付ける．

```script/hello.jl

#!/bin/julia
println("hello")
```

# Cmake
パーミッションを設定することがポイント．

```CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(hello)

find_package(ament_cmake REQUIRED)

install(FILES
        script/hello.jl DESTINATION share/${PROJECT_NAME}
        PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)

install(DIRECTORY
        launch
        DESTINATION share/${PROJECT_NAME}
)

ament_package()
```

# launchファイル

```launch/hello.launch

<launch>
    <node ns="/hello" pkg="hello" exec="hello.jl" output='screen'/>
</launch>
```

# 実行

```
$colcon build
$ros2 run hello hello.jl
hello
$ros2 launch hello hello.launch

[省略]
[hello.jl-1] hello
[省略]
```
Laravelでメールを送信する手順は3つある。

Laravelでメールを送信する方法はおそらく3つです。

・シンプルにMailファサードのsend()を使う方法
・Notificationを使う方法
・Mailableを使う方法

このような解釈でいいのかなたぶん。

ちなみにNotificationはMailだけでなくSlack通知などの実装に使える便利なやつ。

ユーザーインスタンス（ユーザーのデータ）を使って、一斉送信するならMailableかNotificationを使う必要があるのかな？たぶん。
pythonでPCの壁紙をジブリにする

今回はpythonを用いてPC(Windows)の壁紙をジブリにしてみたいと思います。スクレイピングでジブリ画像を収集し、5秒ごとにランダムなジブリ画像を壁紙に設定します。

#素材集め
selenium等を用いてスクレイピングします。ジブリの画像は[こちら](https://www.ghibli.jp/info/013381/)にあるものを使用します。

```python
from selenium import webdriver
import requests
import time
import os

driver = webdriver.Chrome('d:/python/chromedriver.exe') #chromedriverのパスを入力してください
driver.get('https://www.ghibli.jp/info/013381/')
title_link_list = driver.find_elements_by_xpath('//a[@class="panelarea"]')

if not os.path.exists('ジブリ'):
    os.mkdir('ジブリ')

for i in range(len(title_link_list)):
    time.sleep(1)
    title = driver.find_elements_by_xpath('//a[@class="panelarea"]')[i].get_attribute('title')

    if os.path.exists('ジブリ/' + str(title)):
        continue

    driver.find_elements_by_xpath('//a[@class="panelarea"]')[i].click()
    time.sleep(1)
    img_link_list = driver.find_elements_by_xpath('//a[@class="panelarea"]')

    if not os.path.exists('ジブリ/' + title + '/'):
        os.mkdir('ジブリ/' + title + '/')

    for j in range(len(img_link_list)):
        time.sleep(0.5)
        img_link = img_link_list[j]
        img_link.click()
        time.sleep(0.5)
        img = driver.find_element_by_xpath('//img[@class="pswp__img"]')
        src = img.get_attribute('src')
        res = requests.get(src, stream=True)
        with open('ジブリ/' + title + '/' + title + '_' + str(j + 1) + '.jpg', 'wb') as f:
            f.write(res.content)
        driver.back()

    time.sleep(1)    
    driver.back()
```

となりの山田くん辺りでプログラムがストップしてしまう(element not interactable)ため、その時はもう一度プログラムを実行してください…
全部で950枚(約240MB)もあるため、少し時間がかかります。

#壁紙設定
Windowsの壁紙を変更するにはctypesを使用します。

```python
import glob
import ctypes
import numpy as np
import time

img_list = glob.glob('d:/python/Application/ジブリ/*/**.jpg') #絶対パスを入力してください

while True:
    ctypes.windll.user32.SystemParametersInfoW(20, 0, np.random.choice(img_list), 0)
    time.sleep(5)
```

#参考文献
[Python3でWindowsの壁紙を変更する](https://qiita.com/lobmto/items/6d3649e6c00b98553ca2)
[Rails] 初心者のための事前知識(rbenv、RVM、gem、RSpec、Rubocop、bundler、ローカルインストール、env、フロントエンド関連)

## 背景
Ruby を始めるにあたって環境構築をしようとしたところ、rbenv、RVM、bundler、gem、etc.. のよう言葉が出てきて混乱しました。
ある程度理解できたと思うのでまとめます。

## Rubyのバージョン
ルビーのバージョン2.3で作ったアプリは、ルビーのバージョン2.6が入った端末だといじれない。
ルビーのバージョン2.6で作ったアプリも同様にルビーのバージョン2.3が入った端末だといじれない。
一つの端末に複数バージョンのRubyは共存できない。（rbenv、RVMとか使わない場合）

## rbenv、RVM とは
バージョン管理ツール。入れると1台の端末で異なるバージョンのRubyが共存できるようになる。

▼使用例
・状況
去年から開発してるアプリAのRubyバージョンは2.3
来月から開発するアプリBのRubyバージョンは2.6を使いたい

・問題点
アプリAとアプリBを同時に開発したいが一つの端末に複数バージョンのRubyは共存できない、どうしよう・・

・解決方法
rbenv、またはRVMを使うと一つの端末に複数バージョンのRubyが共存できるようになる
アプリAを開発するときはバージョン2.3に切り替え、アプリBを開発するときはバージョン2.6に切り替えられる

といった感じです。

▼RVMとrbenvの比較
・RVM 
上記で述べたバージョン切り替え機能に加え、特定バージョンのRubyを指定してインストールできる
RVMを入れるとデフォルトのCDコマンドがRVM仕様のCDコマンドに上書きされる
rbenvより重い
bundlerと相性が良くない

・rbenv
上記で述べたバージョン切り替え機能を使えるが、特定バージョンのRubyを指定してインストールできない
ruby-buildを入れると特定バージョンのRubyを指定してインストールできるようになる。
バージョンの切り替えがRVMより簡単
最近はRVMよりrbenvが使われることの方が多い?

など、違いは他にも結構あるみたいです。

## gemとは
ライブラリのこと。別名。有名なwebフレームワークのRailsもgemの一つである。
Railsについて、Rails自体が他の様々なgemに依存しているため、Railsを入れるとRailsが依存するgemも一緒に入れないといけない。
gemの依存関係管理は大変らしい。
同一プロジェクト内で同じ種類のgemの複数バージョンは使えない。（bundlerを使わない場合）

▼下記に大半のgemがある
[https://rubygems.org](https://rubygems.org)
[http://bestgems.org](http://bestgems.org)
GitHubにしか公開されてない隠れgemもある。

## bundlerとは
gemの依存関係管理が楽になる。
gemの種類やバージョンを管理できる。
gemfileに記載したgemを一括インストールできる。ローカルインストールできる。
別端末にGemfileを共有すると、Gemfileに記載されたgemを別端末に一括で入れられる。
同一プロジェクト内で同じ種類のgemの複数バージョンを同時に使えるようになる。
bundler自身もgem。
使ってないと地獄を見ることがある。


#### ローカルインストール
bundlerを介してプロジェクトごとにgemをインストールすること。
bundlerを介さず、Ruby環境全体にgemをインストールすることをローカルインストールとは対にグローバルインストールと言う。

環境構築の際はbundlerのみをグローバルインストールし、その他gemは可能な限りローカルインストールすることが望ましいと感じる。

## RSpecとは
テストプログラムを走らせるために必要なgem。テスティングフレームワーク。
テストデータを用意するためのFactoryBotと共に、利用される事が多い。

## Rubocopとは
Rubyのリンター、フォーマッターのこと。

## envとは
使い分けできる環境のこと。
Railsではデフォルトで`developer` `test` `production`環境が用意されている。
ブランチごとに上記3つの環境を使い分けることができる。それぞれの環境に異なるgemをインストールしたり、異なるDB(テスト用DBなど)を使用できる。
developerで開発し、最終的に`production`をpushするのが一般的。

## フロントエンド関連
Railsに限ったことではありませんが、フロントエンドの主要素は下記3点だという認識です。

### HTML
後述するCSS、Javascriptは、HTMLが存在する前提で使用する。
後述するCSS、Javascriptは、HTMLの見た目の表現と動的な振る舞いを強化する目的で使用する。
WEBサーバーの処理結果によって、HTMLのデータを部分的に動的にするのが「テンプレートエンジン」。テンプレートエンジンを使うとHTMLの記述が楽になることもある。
Railsでは主に下記のテンプレートエンジンが利用される。
・ERB
・Slim
・Haml

### JavaScript、TypeScript(動的な振る舞い)
動的な振る舞いをさせるプログラミング言語。
下記のようなフレームワーク、ライブラリがある。
・Vue(javaScript、TypeScriptのフレームワーク)
・Nuxt(javaScript、TypeScriptのフレームワーク)
・React(javaScriptのフレームワーク)
・Angular(javaScriptのフレームワーク)
・JQuery(javaScriptのライブラリ)

### CSS(見た目の表現)
HTMLのヘッダー部分や、タグ内にstyleで記述される。または外部CSSファイルを読み込む(HTMLヘッダーにCSSファイルを記述する)。
CSSを自分で1から作らなくても見た目の表現ができるCSSフレームワークがある。
CSSフレームワークは上述した動的な振る舞いをさせるプログラミング言語と組み合わせて使用する。
下記のようなものがある。
・vuetify(Vue)
・MATERIAL-UI(React)
・BootStrap

フロントエンドの構成の一例として、下記のような組み合わせが考えられる。
・(HTML+ERB) + (javaScript(vue)) + vuetify
・(HTML+Haml) + (TypeScript(vue)) + vuetify
・(HTML+Slim) + (javaScript(React)) + MATERIAL-UI
etc...

## 蛇足
Rubyで開発をする際は下記のようなIDEやエディタが使われるようです。
NetBeans
eclipse 
RubyMine
Aptana Studio
Atom
vscode
XCode(Mac)

私の記事に不備などありましたらご指摘いただけると幸いです。
はじめての Scala.js

# この記事について
 
フロントエンドの処理を Scala のシンタックスで記述できる Scala.js を試してみたのでまとめてみました。
 [Scala.js公式サイト](https://www.scala-js.org/) の [Basic tutorial](https://www.scala-js.org/doc/tutorial/basic/) の環境を整えるところまでやったことのメモです。
 
# 参考サイト
 
 - [Scala.js公式サイト](https://www.scala-js.org/)
 
# あらかじめやっておくこと
 
JDK / sbt のインストールは行っておきます。
 
# 大雑把な流れ
 
下記のような流れで進めていきます。

- プロジェクトのディレクトリを準備
- Scala.js のプラグインを導入
- build.sbt を用意する
- 実際に動かしてみる
  
# プロジェクトのディレクトリを準備
 
プロジェクトのディレクトリを作成し、そのディレクトリで sbt を起動します。
sbt 起動コマンド : `sbt` 

sbt を起動すると `project/build.properties` (sbt のバージョン記述ファイルなど) など基本的なフォルダやファイルが作られるので、楽をするためこれで済ませてしまいます
 

# sbt プラグインを導入
 
 Scala.js の sbt プラグインがあるのでそれを使用します。
 (※sbt プラグイン = これを使用すると、sbtのプロジェクトに新しいセッティングやタスクを追加できます)
 
 sbt プラグインを導入したい場合は、`project` フォルダに `plugins.sbt`を追加して、`addSbtPlugin("プラグイン")` を記述することで導入できます。


```scala:project/plugins.sbt
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.3.1")
```
 
これで ScalaJsのPlugin が導入が完了します。
あとは、`build.sbt` でプラグインを有効にすることで利用できるようになります。
 

# build.sbt を用意する

アプリケーションの設定 / 導入したプラグインを有効にするために、
下記のような `build.sbt` を用意します。
 
 ```scala:build.sbt
 
 // アプリケーションの設定
 name := "ScalaJsExample"
 scalaVersion := "2.13.1"
 
 // Scala.js Plugin を有効にする
 enablePlugins(ScalaJSPlugin)
 // fastOptJs で生成する js ファイルのメイン処理が Scala の main method に対応したものになる
 scalaJSUseMainModuleInitializer := true
 
 ```

プラグインのおかげで簡潔にかけて嬉しいですね。
アプリケーションの設定は任意に変更してください。

# 実際に動かしてみる

ここまでで開発環境の下地はできたので、
簡単に`.scala`のソースコードから、`.js`ファイルを作成して静的ファイルで読み込むところまでやってみます。
 
## js ファイルの元になる Scala ソースコードを準備
 
適当に元となるソースを用意します。
今回は、`src/main/scala/example/ScalaJsExample.scala` でやってみました。
 
 ```scala:src/main/scala/example/ScalaJsExample.scala
 
 package example
 
 object ScalaJsExample{
     // build.sbt に scalaJSUseMainModuleInitializer := true があるので、js ではここの処理がメインの処理として起動します
     def main(args: Array[String]): Unit = {
         println("Hello world!")
     }
 }
 
 ```

このファイルから js ファイルを作ってみます

## js ファイルを生成する
 
`fastOptJS` コマンドを実行すると、`.scala`のファイルを元に、`.js`ファイルが生成されます。
 
生成された `.js` ファイルは、`target/${Scalaのバージョン}/${アプリケーション名}-fastopt.js` として生成されます。

今回は、
Scalaのバージョンが、`scala-2.13`
アプリケーション名が、`scalajsexample`
なので、`target/scala-2.13/scalajsexample-fastopt.js` が生成されました。
 
## 作った js ファイルを読み込む
 
あとはhtmlから読み込んで実際に試してみます。
プロジェクトのルートに下記のhtmlを追加してブラウザで開いてみます。
 
 ```html
 <!DOCTYPE html>
 <html>
   <head>
     <meta charset="UTF-8">
     <title>The Scala.js Tutorial</title>
   </head>
   <body>
     <!-- Include Scala.js compiled code -->
     <script type="text/javascript" src="./target/scala-2.13/scalajsexample-fastopt.js"></script>
   </body>
 </html>
 ```
 
ブラウザの開発者メニューからコンソールを確認すると、
無事 `ScalaJsExample.scala`のメイン処理が走り、`Hello world!` が表示されました！
 
# まとめ
 
ということで Scala.js の開発環境構築までやりました。
フロントエンドの処理も Scala で書けるので、Scala のシンタックスの恩恵を受けたり、Scala を書ける機会を増やせそうで面白いです。

[公式ページの Tutorials](https://www.scala-js.org/doc/tutorial/) には、SPAやらもできそうなので、もうちょっと掘り下げてみたいです。
(「Hands-on Scala.js」が色々処理について記載されていた非常に面白そうでした。)