OmniAICreator/Qiita-1.07M huggingface dataset:
lifecycle-livedata-ktx を使ってみた

`lifecycle-livedata-ktx` とは名前のとおりLiveDataのKTX拡張機能のことである。
具体的には、LiveData ＋ Coroutine で組み合わせて非同期で値を取得して返す仕組みである。

## 導入方法

app/build.gradleに以下を追加するだけ。

```gradle
dependencies {
    implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
}
```

公式にも載っている
https://developer.android.com/kotlin/ktx

## 使い方

ViewModelクラスで、このように書くことができる。

```kotlin
class MainViewModel : ViewModel() {

    // 変数宣言と共に、liveData関数内に非同期処理を実装できる
    val data: LiveData<String> = liveData {
        // 結果を出力
        emit("Hello")
    }
```

そしてFragmentから先ほどのdata変数を購読する。

```kotlin
// observeした時に処理が開始される
viewModel.data.observe(viewLifecycleOwner, Observer { data ->
    // Helloが表示される
    binding.message.text = data
})
```

`observe`した時にliveData関数が呼び出されるので、使用タイミングには気をつけること。

#### 実用的に使うとこんな感じ

ViewModel側

```kotlin
class MainViewModel : ViewModel() {

    // lifeData変数にAPI取得を実装できる
    val ktxLiveData: LiveData<ScreenState> = liveData {
        emit(ScreenState.Loading)
        val data = doSomeThing()
        emit(ScreenState.Data(data))
    }

    // API通信やDB取得などの処理
    private suspend fun doSomeThing(): SomeData {
        delay(3000L)
        return SomeData(123)
    }
```

Fragment側でlivedataをobserveするとAPIなどの処理が実行される

```kotlin
class MainFragment : Fragment() {
    private fun loadKtxLiveData() {
        viewModel.ktxLiveData.observe(viewLifecycleOwner, Observer { state ->
            when (state) {
                is ScreenState.Loading -> {
                    Log.d("MainFragment", "Loading表示")
                }
                is ScreenState.Data -> {
                    Log.d("MainFragment", "取得成功 Data: ${state.someData}")
                    binding.message.text = state.someData.id.toString()
                    Log.d("MainFragment", "Finish")
                }
                is ScreenState.Error -> {
                    // Errorハンドリング
                    Log.d("MainFragment", "Errorダイアログ表示")
                }
            }
        })
    }
```

もしくは、DataBindingにちょくせつViewModelを渡してしまえば、もっとコードを省ける。

## 使用コード
https://github.com/ikemura23/Android-Kotlin-Lab/tree/master/app/src/main/java/com/ikemura/android_kotlin_lab/main
2つの条件の組み合わせで検索する

gemの`ransack`を用いずに複数条件での検索を実装しました。

リレーションのできている異なる２つのテーブルのカラムを用いて検索出来るようにします。

#viewで検索窓を実装

areaテーブルのarea_name（地域）とshopテーブルのname(お店の名前）の組み合わせで検索できるよう実装する。

```ruby:~.html.erb
#フォームで:search_area, :search_shopを受け取れるようにする。

#shops_pathへ送り、　shops/indexページで検索結果を表示させた
<%= form_tag(shops_path, :method => "get") do %> 
 <%= text_field_tag :search_area,"",placeholder: "地域" %>
 <%= text_field_tag :search_shop,"",placeholder: "お店の名前" %>
 <%= submit_tag "検索", :name => nil %>
<% end %>
```

#フォームで入力された情報をコントローラで受け取る
`search`というメソッドにフォームで入力された`:search_area`と`:search_shop`の２つの引数を渡す。

```ruby:shops_controller.erb
def index
  @shops = Shop.search(params[:search_area],params[:search_shop])
end
```
現段階ではこの`search`というメソッドが定義されていない。
その為、この`search`メソッドを`shopモデル`で定義する必要がある。

#検索するための`search`メソッドをモデルに定義する

```ruby:shop.rb
#引数にsearch_area　と　search_shopの２つを取るsearchメソッドを定義
def self.search(search_area,search_shop)
#お店の名前の検索ではLIKE句を用いてお店の名前を部分一致で判断する
    search_area_name= Area.find_by(area_name: search_area)
    search_shop_name= Shop.where("shops.name LIKE ?", "%#{search_shop}%")

#どちらも空白か無効な文字列の場合は全ての店舗情報を返す
    if search_area_name.blank? and search_shop_name.blank?
      Shop.all
    elsif search_area_name.blank?
      search_shop_name
    elsif search_shop_name.blank?
#引数として受け取ったsearch_areaの地域名を地域idに変換する
      search_area_id = search_area_name.id
      Shop.where(area_id: search_area_id)
    else
      search_area_id = search_area_name.id
#shopテーブルのarea_idとnameが一致する店舗の一覧を取得する
      Shop.where(area_id: search_area_id).where("shops.name LIKE ?", "%#{search_shop}%")
    end
  end
```

`LIKE ?`って何？→ https://qiita.com/seri1234/items/765423c2c46ca4114da0

これで先ほどコントローラに記述していた`search`メソッドが使えるようになりました。

#おわり

`joins`メソッドとかを使えばもっと`search`メソッドを綺麗にできそうです。

何でもかんでもgemに頼りたくないなと考えつつ、いろいろ調べたもののどうにも上手くいかず`search`メソッドの中身がかなり力技になった気がします。

２つの要素であれば条件分岐させることで実装できますが、要素が3つ以上になるとこのままでは分岐が大変なことになるのでその場合は`ransack`なり別の方法を使った方が良さそうです。
MySQLでcsvファイルをテーブルにインポートする

####

ログイン時、オプションを指定

```
mysql -u root -p --local-infile=1
```

データベースを選択

```sql
use hogedb
```

インポートするコマンド

```sql
LOAD DATA LOCAL INFILE './huga.csv' --インポートしたいcsvファイル
INTO TABLE hogetable --インポートするテーブル
FIELDS TERMINATED BY '\t' --インポートしたいcsvの区切り文字
LINES TERMINATED BY '\n'; --csvの行区切り指定
```

####おまけ

インポート前に、格納済みのデータをクリアしたいときは

```sql
TRUNCATE TABLE hogetable;
```


別テーブルからデータを移行したいとき

```sql
insert into new_table (
 column1,
 column2,
 column3)
select
 column1,
 column2,
 column3,
from
 old_table;
```
【炎上覚悟】コミュニティから考えるプログラミング教育の行方は

#コミュニティから考えるプログラミング教育
コミュニティの特徴は以下です。

## Windows系(Windows)
- 自分が利益をとって責任を負いたくない人が多く、自己責任論にして金だけとる。
- 『例のアレ』と呼ばれるコンテンツを作り出す原因となった。
- 非互換Linuxを作る努力だけは一等品

## Apple系(iPhone,iPad,MacBook等)
- Apple製品を使っている者には親切だが他のコミュニティの者には不寛容。
- iPad pro利用者のゲーミングコミュニティが豊富
- Apple製品を全て揃える傾向がある

## Google系(Linux/ChromeOS/Android等)
- 去る者は追わず来る者は拒まず。
- オープンソースが好きである傾向にある。
- YouTubeやGoogleスプレッドシート等の無料で優秀なアプリを使えることにワクワクする傾向がある。
- Google以外のコンピュータ愛好家も集まる(主にOSSのOS研究者)

どうでしょうか？日本のプログラミング教育で何が「標準」になるか分かりませんが楽しみです。
デジタルサイネージにログインが必要な画面を表示する

#やりたいこと
画像ファイルをスライドショー表示しているサイネージに、ログインが必要な外部サービスの画面を一緒に表示したい。ちょっと分かりにくいですが、整理すると以下のような感じです。

* 既存サイネージは画像ファイルをスライドショーで表示する仕組み
* サイネージに表示したい画面がある外部サービスはログインが必要
* 外部サービス上ではデータをリアルタイムで可視化しているので画面は逐次更新されている
* このログインが必要な逐次更新される画面をサイネージに表示したい

#使用するもの
* Selenium
* Python
* Chrome
* タスクスケジューラ(Windows10)

#全体の流れ
1. Seleniumを使って、Chromeを起動
1. 外部サービスにアクセスして自動ログイン（Seleniumで）
1. 表示したい画面に移動して画像キャプチャ（Seleniumで）
1. サイネージ公開用のフォルダに画像を保存（Seleniumで）
1. 上記の流れを、タスクスケジューラを使用して定期的に実行

＊SeleniumやPythonなどの環境構築は別途調べてもらえると良いと思います

#ソースコード
ファイル名、保存先、ログイン情報などは、適当に読み替えてもらえると助かります。

```
import os
import sys
import time
import datetime
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import chromedriver_binary

# File Name
now = datetime.datetime.now()
filename = "image/screen_" + now.strftime('%Y%m%d_%H%M%S') + ".png"
FILENAME = os.path.join(os.path.dirname(os.path.abspath(__file__)), filename)

# set driver and url
options = Options()
options.add_argument('--headless')
driver = webdriver.Chrome(options=options)
url = 'https://xxxx/xxxx/'
driver.get(url)

# ID/PASSを入力（ここはサイトごとに要調整）
id = driver.find_element_by_name("xxxx-xxxx")
id.send_keys("xxxx")
password = driver.find_element_by_name("xxxx-xxxx")
password.send_keys("xxxx")
time.sleep(1)

# ログインボタンをクリック（ここはサイトごとに要調整）
login_button = driver.find_element_by_name("xxxx")
login_button.click()

# get width and height of the page
w = driver.execute_script("return document.body.scrollWidth;")
h = driver.execute_script("return document.body.scrollHeight;")

# set window size
driver.set_window_size(1920,1080)
time.sleep(1)

# Get Screen Shot
print ("Get Screen Shot")
driver.save_screenshot(FILENAME)

# Close Web Browser
driver.quit()
```

#まとめ
とりあえず、やりたいことは上記の流れで出来た。あとは、現在はローカル環境でやってるので、これをサーバー環境に移行したい。だいたいの流れは理解出来てきたので、あとは調べてやればなんとかなる感じ。

#ちょっとだけ注意点
自分の環境では、サイネージ公開用フォルダをネットワークドライブに割り当ててたのですが、タスクスケジューラでpythonを直接自動起動した場合はネットワークドライブへのアクセスが上手くいかなかったので、別途、バッチファイルを作成して、バッチ上でネットワークドライブを割り当ててから、pythonを起動するようにしたら上手くいきました。なので、現状はバッチファイルを定期実行するような仕組みになってます。
ログアウト時に確認ダイアログを表示させたい…！(Rails)

## はじめに
ログアウトボタンや、削除ボタンを押したとき、本当に実行するのか確認するアラートを表示させたいなって思うこと、ありますよね！
やり方を調べてみたら、めちゃめちゃ簡単だったので、ご紹介します。

## 今回やりたかったこと
[![Image from Gyazo](https://i.gyazo.com/1cc25d4d29a8ec3252bdc3591e6b2134.gif)](https://gyazo.com/1cc25d4d29a8ec3252bdc3591e6b2134)

こんな感じで、ログアウトボタンを押した際に、確認のアラートを表示させたい…！

「でもどうせ、JavaScriptの知識が必要なんでしょ…？」

そう思っている方、多いと思います。私もそうでした。

安心してください。

JavaScriptの知識は必要ありません。

## 方法
早速やり方です。

```erb
アラートなしの場合

<%= link_to destroy_user_session_path, method: :delete do %>
  <i class="fas fa-sign-out-alt">ログアウト</i>
<% end %>
```
アラートなしのhtml.erbはこんな感じになってます。
ここに少し付け足すだけで、アラートが実装出来ちゃいます。

```erb
アラートありの場合

<%= link_to destroy_user_session_path, method: :delete, data: {confirm: "ログアウトしますか？"} do %>
  <i class="fas fa-sign-out-alt">ログアウト</i>
<% end %>
```

link_to の行に、
data: {confirm: "ログアウトしますか？"}
を追加しました。

これで終了です。

data: {confirm: ""} は、Railsのlink_toのオプションで、
"" の中に、アラートで表示させたいメッセージを入力する事ができます。

え、こんなに簡単なの…？ って、私は知ったときに思いました(笑)

皆さんも是非お試しあれ！
NASのストレージ容量を満杯にしてしまった話

**NAS（ネットワークアタッチトストレージ）**のストレージ容量を一杯まで使い切るという凡ミスをやらかした話をする。

# NASのスペック
NASには、零細企業やSOHOをターゲットとした [QNAP TS-431P](https://www.qnap.com/ja-jp/product/ts-431p) を採用している。QNAPは、同じ台湾メーカーでNASの世界シェア1位のSynologyとよく比較されるが、性能では優位という印象。かつては操作性の面でSynologyに劣ると評価されていたようだが、QTS4.2（LinuxをベースとしたNAS専用OS）のリリース後は追いついた感じ。
TS-431Pは、エントリーモデルながら**RAID6**（2台のHDDが壊れてもデータ復旧可能で転送速度も速い）が組める４ベイタイプのNASで、HDDの付け替えも簡単。
デュアルLANポートなので、NICを束ねて帯域幅を増やし、負荷分散と耐障害性（フォールトトレランス）を高めることも可能。いわゆる**ポートトランキング**とか**リンクアグリゲーション**というやつ（サーバ分野でいうところの**チーミング**）。
機能的にも一般的なNASが備えることは全部できるし、ファンの音も気にならない（サーバルームを持てない零細企業では執務室に置くことになるので静音化対策も重視）。同価格帯の製品と比べてもコスパは悪くないと思う。

HDDは別途調達する必要があるものの、メーカーと記憶容量を自由に選べ、故障すれば交換してリビルドするだけなので、これはむしろメリットと言える（HDDはWestern Digital製、できれば WD Red あたりを選ぶのが無難ではなかろうかと個人的には思う）。
![qnap.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/e1228d24-057c-39f6-dee3-b31c936ec5a6.jpeg)
ちなみに今のRAID構成は次の通りとしている。

|ベイ|構成|
|:-:|:-:|
|HDD 1|RAID1（ミラーリング）|
|HDD 2|RAID1（ミラーリング）|
|HDD 3|ホットスペア用ディスク|
|HDD 4|予備          |

#### （参考）コントロールパネルの画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/c98daf43-0528-417a-6f92-42b9226bd1d1.png)

# 満杯に至った原因
とある、非常に古い業務パッケージが、60GBほどのバックアップファイルを自動で取得し、削除する、という動作を毎日繰り返していたため。
QNAPには「ネットワークごみ箱」と呼ばれる、削除したファイルを`@Recycle`という名前の専用フォルダに移動させる機能がある。誤ってファイルを削除してしまった場合に復活できる便利な機能であるが、ごみ箱にファイルを保存する日数がデフォルトの180日とそこそこ長めに設定されていたため、ストレージ容量を使い切ってしまった。

# 暫定対策
ネットワークごみ箱より、業務パッケージのバックアップファイルを削除した。

# 恒久対策・再発防止策
### １．業務パッケージのバックアップファイルをごみ箱に保存しない
古い業務パッケージだからなのか手抜きなのか分からないが、どういうわけか`lzh`の形式でバックアップファイルを出力する。`lzh`とは、`zip`のような圧縮ファイル形式のひとつで、Windows OSが登場する前から日本人によって開発されたもの。本邦においては事実上の標準圧縮形式だった。
`lzh`で出力するソフトはこの業務パッケージだけなので、拡張子`lzh`をネットワークごみ箱の対象外とした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/3f78fdf8-8923-1ac8-8d07-c75618ca143e.png)
バックアップファイルは、業務パッケージが独自に世代管理しているので、ネットワークごみ箱に保持する必要は無い。

### ２．アラート通知ルールの作成
HDDに異常があったりHDDトレイが外れたりした時はアラートメールを受け取る設定だが、今回のシステムログをもとに、ストレージ容量が不足しそうになった場合でもメールを受け取るようにした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/e192d07f-c121-7ed9-c794-f90bcae65eaf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/68047dd5-b0ae-a559-2b04-cf1fe7fb33a3.png)

# 教訓
予防保守は大事。
変数を箱ではなく付箋で説明してみた（初学者向け）

# はじめに
プログラミング初心者向けの資料や、入門用の技術書において、変数を「箱」で説明しているのをよく見かけます。
私も「変数って箱のようなもの」と教わってきましたし、比較的分かりやすい比喩であると思っています。

ただ、箱で説明するには限界があるというか、もっと良い比喩があるのではないかと思いました。

特に、参照型の変数を表す場合、「箱の中に値そのものではなく、参照が入っている」と説明するのは、初めてプログラミングを学ぶ人にとっては難しいのではないかと思っています。

もちろん（プログラムについて知っている今なら）メモリアドレスのことを指しているのは分かりますが、プログラミング初心者の人にとってはイメージしづらいのではないでしょうか。

そこで今回、プログラミング初心者向けに変数を説明するなら「箱」ではなく「付箋」に例えた方が分かりやすいのではという結論に達しました。

もっと他に良い例えがあったり、付箋ではこんなところが説明できないなどありましたら、コメントいただけると嬉しいです。

# 前提
以下の条件を想定しています。

- 対象はプログラミングの初学者
- 目的は「変数とは何か」理解してもらい、サンプルコードで行なっていることを理解してもらうこと
- 言語はJava（何でも良いのですが、記事の中で出てくるサンプルコードはJavaにしました。）


# 付箋で説明
それでは、付箋に例えて説明します。

変数とは、一言でいうと「**1枚1枚に名前が付いた、色つきの付箋**」のようなものです。

## 変数は「情報の保存と記録」のために使う

まず、変数の機能を説明します。

普段の生活の中で、付箋は「買い物リスト」や「伝言メモ」など、ちょっとした情報を記録しておくために使っています。
買い物をする場合、まず買いたいものを付箋に書き、スーパーに到着したら付箋を見て「買いたいと思っていたもの」を確認します。

ここでは、情報（＝買いたいもの）の保存と取得を行っています。

プログラムの世界で、買い物リストの役割を担うものが「変数」です。

**変数は「情報の保存」と「情報の取得」を行うために利用します。**
情報を保存すること（＝付箋に書き込むこと）を「変数に代入する」と言います。

これをコードして表現すると、以下のようになります。（クラス定義やmain関数は省略）
`item`が変数です。

```java
String item = "りんご"; // 情報を保存（＝itemという変数に代入）

System.out.println("買うものは" + item + "です"); // 情報を取得して表示

// 実行結果
買うものはりんごです

```

余談ですが、買い物メモは買い物が終わったらゴミ箱に捨てちゃうのと同じように、変数も役目が終わったら消えてしまいます。

## 変数には「名前」をつける

普段の生活の中で、付箋1つ1つに名前を付けて呼んでいることはないと思いますが、「この付箋」とか「冷蔵庫に貼ってある付箋」など、たくさんある付箋を識別して特定の付箋を指定しています。

プログラムでも同様で、複数存在する変数を識別する必要があり、変数1つ1つに名前（変数名）をつけます。

イメージでは、「**付箋1枚1枚に名前をつける**」感じです。（←ちょっと分かりづらいかな。この点では箱にラベルを貼る方が分かりやすい。）

先ほどの例では、`item`という変数名をつけています。

```java

String item = "りんご";
```

これによって、`item`という名前で情報を取得することができます。

```java
System.out.println("買うものは" + item + "です");

// 実行結果
買うものはりんごです
```


## 変数にはデータ型が存在する

変数には「データ型」という型が存在し、データ型に一致しない値は変数に代入することができません。

付箋の例で言うと、「黄色の付箋には数字しか書けない。赤色の付箋には文字列しか書けない。というルールが決まっている。」という感じです。

現実世界では、付箋に文字を書いても絵を描いてもOKですが、プログラムの世界では決まった型しか代入できないルールになっています。

先ほどの例では、`item`という変数には文字列（String型）しか代入できません。

```java
// OK
String item = "りんご";

// NG
String item = 10; // 10は文字列ではなく数値なので代入できない。
```

よく使うデータ型は以下です。（これはルールとして覚えるしかないです。）

```
int : 整数を表す型（例：10）
double : 小数を表す型（例：0.5）
String : 文字列を表す型（例：こんにちは）
boolean : trueかfalseのどちらかの値を表す型
```

## 変数には基本型と参照型という種類がある
変数は大きく分けて「基本型」と「参照型」という2種類に分類することができます。

基本型変数は「**付箋に値そのものが書いてある**」イメージです。
基本型には`int`型、`double`型、`boolean`型が含まれます。

一方、参照型は「**付箋に『ノートの〇〇ページを見てね！』と書いてあり、該当のページに値が書いてある**」イメージです。
参照型は`String`型や、配列、クラス型が含まれます。

## 参照型変数を付箋で説明すると

参照型変数の注意点として、値は同じでも参照先が異なる場合があることです。

```java

String nameA = new String("太郎");
String nameB = new String("太郎");

System.out.println( nameA == nameB ) // falseが出力
```

これは、`nameA`の付箋には「1ページを見てね！」と書いてあり、`nameB`の付箋には「2ページを見てね！」と書いてあることと同じなので、`nameA`と`nameB`は別々のものであるということです。1ページと2ページにはどちらも「太郎」と書いてあります。

箱に「参照が入っている」という説明よりは想像がしやすいのではないでしょうか。

また、この比喩を用いると、インスタンス変数に含まれるプロパティも説明できます。
インスタンス変数は参照型の変数なので、付箋には「ノートの〇ページを見てね！」と書いてあります。
該当のページには、いくつかの付箋（プロパティ）が張られているイメージです。

# おわりに

全体的にざっくりとした説明になってしまいましたが、「箱」ではなく「付箋」でも変数の説明ができるのではないでしょうか。

どんな例に例えると分かりやすいかは人それぞれだと思います。

今回の記事は、「変数のことを箱って説明されたけど、よくわからない」と感じた方の役に立ててれば嬉しいです。
CKeditor4と画像アップロード（CKfinder使用しない）


# 行ったこと
- Cakephp にCKeditor4を適用
- 画像アップロードの処理をコントローラに書く

# CKeditor適用

[公式サイト](https://ckeditor.com/ckeditor-4/download/#)

`View(ctp)`ファイル

cdn 経由で呼び出し
※Fullバージョンがおすすめです。

```PHP
<?= $this->Html->script('https://cdn.ckeditor.com/4.14.0/full/ckeditor.js') ?>
```

※コントローラ指定

```javascript
var url = '<?= $this->Url->build(['controller' => 'ImgUpload', 'action' => 'index']) ?>';
```


```javascript

var editor = CKEDITOR.replace('editor', {
    language: 'ja',
    toolbarCanCollapse: true,
    filebrowserUploadMethod: 'form',
    filebrowserUploadUrl: url, /* 上で指定したurl(変数) */
    image_previewText: '画像アップロード',
};
```

ツールバーのオプションなどは今回省略します。

# 画像アップロード処理

上で指定した`ImgUploadController`の内容

```PHP
namespace App\Controller\Admin;
use App\Controller\AppController;

class ImgUploadController extends AppController
{
public function index()
    {
        if (isset($_FILES['upload']['name'])) {

            $uploaddir = WWW_ROOT;
            $file = $_FILES['upload']['tmp_name'];
            $file_name = $_FILES['upload']['name'];

            $file_name_array = explode(".", $file_name);
            $extension = end($file_name_array);
            $new_image_name = rand() . '.' . $extension;
            chmod($uploaddir.'/uploads', 0777);
            $allowed_extension = array("jpg", "gif", "png");

            if (in_array($extension, $allowed_extension)) {
                move_uploaded_file($file, $uploaddir.'/uploads/'.$new_image_name);
                $function_number = $_GET['CKEditorFuncNum'];
                $url = '/uploads/'.$new_image_name;
                $message = '';
                echo "<script type='text/javascript'>window.parent.CKEDITOR.tools.callFunction($function_number, '$url', '$message');</script>";
                return;
            }
        }
    }
}
```



```
webroot
  ∟ uploads
       ∟ ここに画像ファイルが保存される
```



参照サイト： https://www.webslesson.info/2019/01/uploading-image-in-ckeditor-with-php.html
Font-awesomeでcouldn't find file 'font-awesome' with type 'text/css'が出たときにやったこと

#couldn't find file 'font-awesome' with type 'text/css'がエラーが発生

font-awesome便利ですよね〜

今回はfont-awesomeをインストール後に発生したエラーに対してやったことをまとめました。


####font-awesomeをインストールしたとき、、、
```
gem 'font-awesome-rails'
```

```
$ bundle install
```
```
/*
 *= require font-awesome
 */
```
<space>
application.css内にも記載し、ページを開くと、、、

<img width="1440" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/c2f80631-11d0-dbff-4015-acc9f41e8cf6.png">

<strong>上記のようなエラーが発生</strong>
エラー文からfont-awesomeが読み込めていないと予想

application.css内の記述を確認する
割ととんでもない記述をしていたので、修正

<img width="305" alt="２.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/441a9485-0521-5d42-c2f8-dd966f5ee1cb.png">

<strong>*= require treeの下に記述をrequire_treeの上へ移動</strong> 
<img width="301" alt="4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/651da6b9-4f0f-9f60-591b-2fc106952416.png">

また、同じエラー文、、、

<img width="1440" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/7e78986f-b583-1d20-f74e-30b911917f52.png">


その後、何度もエラー内容を調べるも解決の糸口は見えず
<space>
<space>

gem 'font-awesome-sass'のエラー対処は大量に出てくるのにな、、、
<space>
<space>


なんなら自分もsassでfont-awesome使っていたので、sassに切り替えようかとまで思ったり、、、
<space>
<space>
<space>

####<strong>ある程度悩んだ後、もしやと思ってrails sを再起動してみる</strong>
<space>
<space>
<space>

####すると、、、
<space>
<space>
<space>
<space>
<space>

###<strong>起動した</strong>

なんでもっと早く再起動しておかなかったんだと
<space>
<space>

####どうやらPCやターミナルをずっと動かしておくと、予期せぬエラーが発生することがあるらしい
<space>
<space>

<strong>人間と一緒で定期的に休ませてあげるのが大事だなと</strong>
<space>
<space>

さて、気を取り直して頑張ろう
RSpecの起動をスピードアップする files took n seconds to load が気になるあなたへ

dockerでrspec実行してたのですが、毎回アホみたいにファイルのロードが長かったのでなんとかしようと思いました。

## Springを活用する
- `spring-commands-rspec` (https://github.com/jonleighton/spring-commands-rspec) を使えばOK

```
group :development do
  略
  gem "spring-commands-rspec"
```

```
$ bundle install
$ bundle exec spring binstub rspec
$ bin/rspec
```

springに `bin/rspec` を作ってもらい、それ経由でrspecを実行します。

できるファイル
`bin/rspec`

```bin/rspec
#!/usr/bin/env ruby
begin
  load File.expand_path('../spring', __FILE__)
rescue LoadError => e
  raise unless e.message.include?('spring')
end
require 'bundler/setup'
load Gem.bin_path('rspec-core', 'rspec')
```

一回目の実行は0から立ち上げるので普通の早さですが、二回目以降はspringがロードしてくれてるので早くなります。


僕の環境での恩恵はこんな感じでした。
 
**before**

```
Finished in 10.9 seconds (files took 1 minute 34.43 seconds to load)
37 examples, 0 failures
```

**after**

```
Finished in 6.71 seconds (files took 4.68 seconds to load)
37 examples, 0 failures
```

ファイルのロード時間が**1分半 → 5秒弱**に短縮されました。まじか。

## 補足
Springはapplication preloaderです。
> Spring is a Rails application preloader. It speeds up development by keeping your application running in the background so you don't need to boot it every time you run a test, rake task or migration.

(https://github.com/rails/spring#spring より)

バックグラウンドで走らておくことで、スピードアップを図るものですね。
いまSpringが仕事中かどうかは、

```
$ bin/spring status
```
でわかります。
rspecだけでなく、railsやrakeコマンドも早くしてくれるので、活用するとハッピーになれるかもしれません。
railsでhaml変換した後にmissing a templateエラーが発生した際の対処方法

railsでhaml:erb2hamlを実行した後にindex.html.hamlのmissing a templateが発生したので解決方法をメモ。
### 環境

- rails 5.2.4

 
## haml-railsでrails haml:erb2hamlを実行
```terminal
post_app % rails haml:erb2haml
--------------------------------------------------------------------------------
Generating HAML for app/views/posts/index.html.erb...
Generating HAML for app/views/posts/_nav.html.erb...
Generating HAML for app/views/posts/_main_top.html.erb...
Generating HAML for app/views/posts/_main_bottom.html.erb...
Generating HAML for app/views/posts/_sidebar.html.erb...
Generating HAML for app/views/layouts/application.html.erb...
Generating HAML for app/views/layouts/mailer.html.erb...
Generating HAML for app/views/layouts/mailer.text.erb...
--------------------------------------------------------------------------------
HAML generated for the following files:
	app/views/posts/index.html.erb
	app/views/posts/_nav.html.erb
	app/views/posts/_main_top.html.erb
	app/views/posts/_main_bottom.html.erb
	app/views/posts/_sidebar.html.erb
	app/views/layouts/application.html.erb
	app/views/layouts/mailer.html.erb
	app/views/layouts/mailer.text.erb
--------------------------------------------------------------------------------
Would you like to delete the original .erb files? (This is not recommended unless you are under version control.) (y/n)
y
Deleting original .erb files.
--------------------------------------------------------------------------------
Task complete!
No .erb files found. Task will now exit.
```
rails haml:erb2hamlは成功したにもかかわらずmissing a templateエラーが発生しました。
## missing a template
```terminal
ActionController::UnknownFormat (PostsController#index is missing a template
 for this request format and variant.

request.formats: ["text/html"]
request.variant: []

NOTE! For XHR/Ajax or API requests, this action would normally respond with
204 No Content: an empty white screen. Since you're loading it in a web
browser, we assume that you expected to actually render a template, not
nothing, so we're showing an error to be extra-clear. If you expect 204 No
Content, carry on. That's what you'll get from an XHR or API request. Give
it a shot.):
```
テンプレートがないと怒られたのでファイル名やパスを確認するも間違っているところはなさそう。
ここでindex.html.hamlのファイル名をindex.html.erbに変更してみるとエラーが消えました。
ちゃんとコントローラはviews/posts/index.html.erbを呼び出しているようです。

## 解決方法
**rails s でローカルサーバを再起動するだけ！**

```terminal
rails s
```
いくらファイル名やパスを確認してもおかしなところは見あたらず、1時間くらいなんでやー！っとなっていたので同じ境遇の人に役に立てば幸いです。

### 参考記事
- [stackoverflow - HAML on Rails 3 returning “Template is missing” error
](https://stackoverflow.com/questions/3795424/haml-on-rails-3-returning-template-is-missing-error)
- [teratail - アクセスするとエラーが出てしまった。](https://teratail.com/questions/222692)
初心者向け　Arduinoで自作楽器を作ろう！！

皆さん、自作楽器作りたくないですか？
さっそく作りましょう。

楽器の代表例としてピアノを作っていきます。
##準備するもの
- arduino
- スイッチ
- ジャンパー線
- ブザー


##配線の仕方
![piano.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528717/7632248c-9d80-061d-473c-f4351fa24f39.jpeg)
上の写真のように配線していきます。
ブザーが皆さんの手元の物と少し違いますが、形が違うだけで中身は一緒です。

##プログラミング
```c++:arduino_piano.ino
void setup(){
pinMode(2,INPUT_PULLUP);
pinMode(3,INPUT_PULLUP);
pinMode(4,INPUT_PULLUP);
pinMode(5,INPUT_PULLUP);
pinMode(6,INPUT_PULLUP);
pinMode(7,INPUT_PULLUP);
pinMode(8,INPUT_PULLUP);
pinMode(9,INPUT_PULLUP);
pinMode(12,OUTPUT);
}

void loop(){
int frequency=0;

if(digitalRead(2)==LOW){
 frequency=523;//ド
}
if(digitalRead(3)==LOW){
 frequency=587;//ㇾ
}
if(digitalRead(4)==LOW){
 frequency=659;//ミ
}
if(digitalRead(5)==LOW){
 frequency=698;//ファ
}
if(digitalRead(6)==LOW){
 frequency=784;//ソ
}
if(digitalRead(7)==LOW){
 frequency=880;//ラ
}
if(digitalRead(8)==LOW){
 frequency=988;//シ
}
if(digitalRead(9)==LOW){
 frequency=1046;//ド
}

if(frequency!=0){
tone(12,frequency);
}else{
noTone(12);
}
}

```
##コードの解説：
備考：○は何かしらの値が入ると認識してください。
######pinMode(○,INPUT_PULLUP);
これはarduinoの端子を入力モードにするという関数です。
INPUT_PULLUPとはarduino内部の[PULLUP抵抗](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E6%8A%B5%E6%8A%97)を使用するという物です。(よくわからない場合は読み飛ばしてください)

**if(digitalRead(○)==LOW){
 frequency=○;
}**
digitalRead(○) で○ピンがLOWの状態かHIGHの状態か読み取ります。
○ピンがLOWの状態であればLOW==LOWになりif文がTrueになりif文の中のfrequency=○;が実行されます。ここでスピーカーが発生させる音の周波数が決定されます。

**if(frequency!=0){
tone(12,frequency);
}else{
noTone(12);
}**
if(frequency!=0)でfrequencyが0でないか判断し、値が代入されているか判断します。
もし代入されていなかったらnoTone(12);でブザーを停止させます。
されていた場合はtone(12,frequency);で指定した周波数の音を発生させます。


##演奏してみよう
ちゃんと音はなりましか？
ドレミファソラシドとなっているはずです。
自分で改造してみたくなったらfrequencyの値を変えると音が変わります。
またボタンの数を増やしたり、録音モードを作ってみても面白そうですね。
##最後に
皆さん電子工作を楽しんでいただけましたか？
電子工作の醍醐味はブログをみて作った後にいかに自分で改造するかだと思っています。
ぜひやってみてください！！

それでは、**おつかれさまでした！！**
UnityのSliderで作ったHPバーが、角丸になってしまう時の解決方法

最近Unityを触りはじめて学習をしていたところ、本来長方形で作りたいSliderのHPバーが、なぜか角丸になってしまうという事態に陥り１時間程ハマってしまいました。

Unity初心者だと地味に解決しづらい問題だと思うので、書き残したいと思います。

## 何故か角丸になるHPゲージ
問題のHPゲージはこちらです。
<img width="644" alt="スクリーンショット 2020-04-04 14.38.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528941/9726666a-8ac0-6a9e-03f7-62959a8ba362.png">
角丸というより、もはや楕円形です...


## 解決方法
Sliderのコンポーネント「Rect Transform」の拡大/縮小の値を小さくしてあげて、Sliderの幅と高さを大きめに設定してあげることで無事に解決できました。

<img width="453" alt="スクリーンショット 2020-04-04 14.50.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528941/efa00721-a915-0843-54f0-92ea819f4a8a.png">
<img width="635" alt="スクリーンショット 2020-04-04 15.02.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528941/a039c9e8-8de9-705e-7652-8ae0499958f1.png">

早くUnityの使い方に慣れていきたいと思います(´・ω・`)
Surface Laptop 1 に windows 10 pro をクリーンインストール

## USB boot

F6キーを押しながら電源をON

Secure Boot を Disable に設定

電源OFF

USBメモリを差し込んで F5キーを押しながら電源をON

## ドライバー

Windows 10 をクリーンインストールした後は キーボードが効かない。ドライバーを入れる

* [Download drivers and firmware for Surface](https://support.microsoft.com/en-us/help/4023482/surface-download-drivers-and-firmware)
    * [Download Surface Laptop (1st Gen) Drivers and Firmware from Official Microsoft Download Center](https://www.microsoft.com/en-us/download/details.aspx?id=55489)

![スクリーンショット_2020-04-04_15-30-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/0eb90fe9-b2f6-e216-cc7a-43e98d148987.png)
[JavaScript] Arrayメソッド破壊・非破壊チートシート

JSのArrayメソッドで破壊非破壊がまとまっている表が欲しいな〜〜
と思ったので作りました。


## チートシート


| メソッド名 | 破壊 | 非破壊 | 用途 　　　　　　　 |
| :-------|:---:|:-----:|:----------------|
| splice()| ○ |　　　　| 配列から配列の一部を取り出し、新しい配列を返す |
| slice() |  　　　| ○ | 配列から配列の一部を取り出し、新しい配列を返す |
| push()  | ○ |  | 配列の末尾に要素を追加し、新たな配列の長さを返す |
| unshift()| ○ |  | 配列の先頭に要素を追加し、新たな配列の長さを返す |
| pop()   | ○ |  | 配列の最後の要素を取り除き、その値を返す |
| shift() | ○ |  | 配列の先頭の要素を取り除き、その値を返す |
| filter() |  | ○ | 引数として与えられた関数を各配列要素に対して実行し、それに合格したすべての配列要素からなる新しい配列を返す |
| reduce() |  | ○ | 引数として与えられた関数を(左から右へ)各配列要素に対して実行し、単一の値にして返す |
| reduceRight()  |  | ○ | 引数として与えられた関数を(右から左へ)各配列要素に対して実行し、単一の値にして返す |
| map() |  | ○ | 配列内の各要素を引数として与えられた関数で順番に加工し、新しい配列を返す |
| concat() |  | ○ | 配列に他の配列や値をつないでできた新しい配列を返す |
| find() |  | ○ | 引数として与えられた関数を満たす配列内の**最初の要素**の値を返す |
| findIndex() |  | ○ | 引数として与えられた**関数**を満たす場合、配列内の **インデックス** を返す |
| indexOf() |  | ○ | 引数に与えられた**値**と同じ値を持つ配列要素の内、最初のものの添字を返す |
| includes() |  | ○ | 引数の値が配列に含まれているかどうかを true または false で返す |
| sort()| ○ |  | 配列の要素をソートする 　　　　　　　　　　　　　　　　　　|
| reverse()| ○ |  | 配列の要素を反転させ、配列を書き換える　　　 |
| join() |  | ○ | 配列の全要素を順に引数の文字列で連結した文字列を新たに作成して返す。区切り文字や指定されない場合、デフォルトは,になる |
| fill()| ○ |  | 配列中の開始インデックスから終了インデックスまで固定値に変更する |
| copyWithin()| ○ |  | サイズを変更せずに、配列の一部を同じ配列内の別の場所にシャローコピーして返す |


## 最後に
関数自体を詳しく説明はしていないので、必要があれば[MDN web docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array)をご参考ください。
今後も追加していきますが一旦。

## 4/6追記
@yamotuki  さんが、[JavaScriptでArrayに対する破壊的メソッドを安全に使う方法](https://qiita.com/yamotuki/items/99af49bc3de6dae1b134)を書いてくださいました！
破壊的メソッドの使い方が理解できるのでぜひご一読ください！
素人がiPhoneアプリを作った話＜読み物＞

今回で最後です。

読み物は、非公開でアプリ購入者のみが読める情報を毎月2回更新しています。

#やりたかったこと 

+ 資料や参考としての読み物をニュースのように流す 
+ ユーザーが読んで良かったものを評価する 
+ 評価をカウントし、表示する 
+ ユーザーが他のユーザーの評価数を見て読むものを選べるようにする 
+ 毎月1〜2回の更新 

#できたこと 

+ 読み物をニュースのように流す 
   + 読み物はWordPressに投稿する 
   + RSSを利用して読み込み、タイムラインのようにレイアウトする 
+ 評価機能 
 + ニフクラを使ってクリックを登録 
 + ニフクラでユーザーのIDと記事番号をリストする 
+ 評価のカウントと表示
 + ユーザーがページを開いたり画面を更新したタイミングでニフクラのリストから記事番号をカウントして該当の記事番号の横にカウント数を表示する 
+ 他のユーザーの評価
 + ユーザー自身が評価したものはIDで判別し、色をつけることで他のユーザーとの区別がつく 
+ 毎月1〜2回の更新 
 + 通信制の大学へ転入し心理学の知識を勉強、心理学的見地から記事を更新している 
 + その他、文献や動画なども紹介している 

#できなかったこと 

+ ニフクラ対応のバージョンアップができていないため、現在カウント機能は停止中

#今後追加したいこと
ユーザーがお気に入りにした物だけをリストにしたページや、その並び順を変える方法、またWP上ではタグをつけているので、それでフィルターをかけるなどがアプリ上でもできるようにしていきたい。
ActiveStorageで画像をアップロードする方法

#Active Storage
#####Active Storageとは
Active Storageとはファイルをアップロードしてモデルに添付してくれるやつ。Active Storageをインストールして使用することで本番環境でクラウドストレージサービス(S3、GCSとか)にファイル(画像とか)をアップロードして、データベース上でActiveRecordモデル(アプリで使うモデル)のインスタンスに紐付けできるということ。

#####手順
Active Storageをgemを使ってインストール
↓
するとmigrationファイルができる。これは2つのテーブル(モデル)を作るためにできた(active_storage_blobsとactive_storage_attachmentsという名前)。

一つ目のactive_storage_blobsは画像ファイルを管理するためのモデル。
二つ目のactive_storage_attachmentsはActiveRecordモデル(アプリで使うモデル)とactive_storage_blobsの関係性を表すためのモデル。つまりこの二つのモデルの間に存在し、二つのモデルに従属(belong_to)しているテーブル。

上記で説明をしてきたがActiveStorageで画像を紐づける際にこの二つのモデルを意識することは少ない？

![95A30DAB-EF6C-4E57-96C6-2F8EE3981D4D_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510817/8475e58e-e8cb-e490-5197-eb056a430391.jpeg)

↓
db:migrateする
↓
ActiveRecordモデル(appで使用するモデル)ファイルに写真を持つことを記述する

```ruby:models/task.rb
has_one_attached :image
#一つのtaskに一つのimageがつく。
#imageという名前は入力時のform fieldでのタグ名。
```

```ruby:tasks/new.html.slim
= form_with model: task, local: true do |f|
.
.
.
 .form-group
    = f.label :image
    = f.file_field :image, class: 'form-control'
#imageというタグ名で値を送信している　
```

他にもモデルファイルで以下のように記述するとモデルは複数の画像を持つことができる。

```ruby:models/message.rb
class Message < ApplicationRecord
  has_many_attached :images
end 
```


参考文献は[Railsガイド](https://railsguides.jp/active_storage_overview.html#has-one-attached)と[【Rails 5.2】 Active Storageの使い方](https://qiita.com/hmmrjn/items/7cc5e5348755c517458a)
#####設定
・画像ファイルを管理する場所を指定したい
そんな時はconfig/environmentsで各環境での管理場所を指定する。

```development.rb
config.active_storage.service = :local
#開発環境ではファイルを保存する場所をlocalという設定にしている。
```

localがどういう設定になっているかを知りたい場合は

```ruby:config/storage.yml
local:
  service: Disk
  root: <%= Rails.root.join("storage") %>
#localという設定はファイルの保存はアプリのstorogeディレクトリで行われる
```
pyenv+anacondaでconda createした環境にpipを入れる

備忘録です。

```bash
pyenv local anaconda3-2019.10
conda create -n tmp
```
して、

```bash
$ pyenv versions
  system
  anaconda3-2019.10
  anaconda3-2019.10/env/tmp
```
のようなときに

```bash
$ pyenv local anaconda3-2019.10/env/tmp
```
すると

```
$ pip
pyenv: pip: command not found

The `pip' command exists in these Python versions:
  anaconda3-2019.10

Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.

$ conda
pyenv: conda: command not found

The `conda' command exists in these Python versions:
  anaconda3-2019.10

Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.
```
となってしまうことへの対処法。

```bash
$ . ${HOME}/.pyenv/versions/anaconda3-2019.10/etc/profile.d/conda.sh
$ conda activate tmp
$ conda install pip
```
こうすると`pip`のインストール先として

```bash
## Package Plan ##

  environment location: /home/{username}/.pyenv/versions/anaconda3-2019.10/envs/tmp

  added / updated specs:
    - pip
```
となるので安心。

```bash
$ conda deactivate
```
PyInstaller備忘録 2行でPython[.py]の[.exe]化

# はじめに
Pythonのプログラム[.py]が属人化しないようにするためexe化[.exe]した際のメモ。
Pythonのexe化にはいくつか方法がありますが、今回は簡易にできるPyInstallerを用います。

# クイックスタート
参考:[PyInstaller Quickstart](https://www.pyinstaller.org/)

ソースコードを編集せずにpipと下記コマンドでexe化できます。
これだけなので非常に簡単です。exe化だけならここまでで結構です。
後半にPythonコードでPyInstallerを記述する方法を紹介しているので興味があればご参照下さい。

```
pip install pyinstaller
pyinstaller yourprogram.py
```

# オプション一覧
実行時に指定できるオプションがあります。
下記資料を参考に使用頻度の高いオプションをまとめています。
参考:[Using PyInstaller](https://pyinstaller.readthedocs.io/en/stable/usage.html
https://gist.github.com/devlights/2ea169b60063d81f0526eceebeb7a8c6)


## 生成オプション
| オプション       |       機能 |
|:-----------------|------------------:|
|-n, --name       |              生成ファイルの名前指定(defaultはスクリプト名) |
| --specpath DIR         |             生成フォルダの指定(defaultは現在のDIR) |
| -D,--onedir          |     1ディレクトリにまとめて出力する |
| -F,--onefile          |              1ファイルにまとめて出力する |

##OS固有オプション

| オプション       |       機能        |
|:-----------------|-----------------------:|
|-w, --windowed, --noconsole       |      コンソールを非表示にする |
|-i, --icon       | プログラムのアイコン[.ico拡張子]を設定する |


##一般オプション
| オプション       |       機能        |
|:-----------------|-----------------------:|
|--clean, --noconsole       |      ビルドする前にPyInstallerキャッシュを消去し、一時ファイルを削除する |
|-y, --noconfirm      |      出力ディレクトリを確認を求めずに置換する |
|-v, --version       |      プログラムのバージョン情報を表示して終了する |

##その他オプション
| オプション       |       機能        |
|:-----------------|-----------------------:|
|--exclude      |      指定したモジュールまたはパッケージを無視する。複数回使用可能 |

##オプション使用例
```
pyinstaller yourprogram.py --exclude numpy,-v, -i data.icon
```

# PythonコードからPyInstaller実行
公式ドキュメント参考
https://pyinstaller.readthedocs.io/en/stable/usage.html

```sample.py
import PyInstaller.__main__

PyInstaller.__main__.run([
    '--name=%s' % package_name,
    '--onefile',
    '--windowed',
    '--add-binary=%s' % os.path.join('resource', 'path', '*.png'),
    '--add-data=%s' % os.path.join('resource', 'path', '*.txt'),
    '--icon=%s' % os.path.join('resource', 'path', 'icon.ico'),
    os.path.join('my_package', '__main__.py'),
])
```

#まとめ
Pythonのexe化ができるPyInstallerのメモでした。
2行でできるのが便利ですね。
ですが一点懸念もあります。下記を参考にするとexeファイルが大きい点や実行時間が掛かる問題があるようです。
exe化したい対象が処理速度を考慮していなければ是非お試しください.
[【悲報】PyInstallerさん、300MBのexeファイルを吐き出すようになる](https://lets-hack.tech/programming/languages/python/pyinstaller-issue/)

ご一読ありがとうございました。気になる点があれば編集リクエスト、コメントお願い致します。
良ければLGTMもお願いします。
No Firebase App '[DEFAULT]' has been created と怒られた

# 環境

- `React.js`
- `TypeScript`
- `Firebase`

# 怒られたコード

```typescript:main.tsx
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"

const config = {
    apiKey: "<API_KEY>",
    authDomain: "<AUTH_DOMAIN>",
    databaseURL: "<DATABASE_URL>",
    projectId: "<PROJECT_ID>",
    storageBucket: "<STORAGE_BUCKET>",
    messagingSenderId: "<MESSAGING_SENDER_ID>",
    appId: "<APP_ID>",
    measurementId: "<MEASUREMENT_ID>"
}
firebase.initializeApp(config)

ReactDOM.render(<App />, document.getElementById("root"))
```

```typescript:App.tsx
import React from "react"
import * as firebase from "firebase"

const firestore = firebase.app().firestore()

export default function App() {
    return (
        <h1>Hello, World!</h1>
    )
}
```

# 動いたコード

`firebase.initializeApp()` を `import` の前に書いた。

```typescript:main.tsx
const config = {
    apiKey: "<API_KEY>",
    authDomain: "<AUTH_DOMAIN>",
    databaseURL: "<DATABASE_URL>",
    projectId: "<PROJECT_ID>",
    storageBucket: "<STORAGE_BUCKET>",
    messagingSenderId: "<MESSAGING_SENDER_ID>",
    appId: "<APP_ID>",
    measurementId: "<MEASUREMENT_ID>"
}
firebase.initializeApp(config)

import React from "react"
import ReactDOM from "react-dom"
import App from "./App"

ReactDOM.render(<App />, document.getElementById("root"))
```

```typescript:App.tsx
import React from "react"
import * as firebase from "firebase"

const firestore = firebase.app().firestore()

export default function App() {
    return (
        <h1>Hello, World!</h1>
    )
}
```

# 原因

`import` の段階で `App.tsx` 内の `const firestore = firebase.app().firestore()` が実行されたのかも
詳しくはわからない
WSL(2)上でMuJoCoを動かす(GUIも)

WSL2上でもMuJoCoを動かすことが可能です。

WSL2の導入とGUIの導入については大変だった点をまとめて別記事を書いたのでこちらをご参照ください。
[WSL2の導入とGUI環境の構築](https://qiita.com/momomo_rimoto/items/51d533ae9529872696ce)

mujoco-pyを動かしたいときのPythonについては導入済みという前提で進めます。

# MuJoCo導入
## MuJoCoのダウンロード
好きな方法で https://www.roboti.us/index.html からMuJoCoをダウンロードし `~/.mujoco/mujoco200` に展開します。例えば、

```bash
wget https://www.roboti.us/download/mujoco200_linux.zip
unzip mujoco.zip -d /home/{username}/.mujoco
mv /home/{username}/.mujoco/mujoco200_linux /home/{username}/.mujoco/mujoco200
rm mujoco.zip
```

また、`~/.mujoco/mjkey.txt` にライセンスキーを用意します。

## 環境変数の追加
さらに、`~/.bashrc`に

```bash
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/{username}/.mujoco/mujoco200/bin
```
を追加します。

## 依存するものの導入
いくつか必要なものをいれてやります。

```bash
sudo apt update
sudo apt install gcc
sudo apt install libosmesa6-dev
```

ここまでくれば、`pip install mujoco-py` ができます!!

# GUIで描画する
準備として

```bash
sudo apt install libgl1-mesa-dev xorg-dev
```
しておきます。

また、GUIについては[WSL2の導入とGUI環境の構築](https://qiita.com/momomo_rimoto/items/51d533ae9529872696ce)を参考にして導入してください。

```bash
$ cd ~/.mujoco/mujoco200/bin
$ ./simulate ../model/humanoid.xml
MuJoCo Pro version 2.00
ERROR: could not initialize GLFW

Press Enter to exit ...
```
が出たらファイアウォールのうちWindows Defenderファイアウォールのプロパティからパブリックドメインの保護されているネットワーク接続で、wslのチェックを外してください。

ただし、ここで紹介したデフォルトのまま(あるいはいろいろなサイトで紹介されているもの)だと、

```bash
MuJoCo Pro version 2.00
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
ERROR: OpenGL version 1.5 or higher required

Press Enter to exit ...
```
となってしまいます。OpenGLのバージョンが低すぎるようです。世界中で1つだけ?答えに行きついているサイトがありました。 https://superuser.com/questions/1487555/how-to-troubleshoot-opengl-on-ubuntu-under-windows-10-wsl

要するに、
1. `LIBGL_ALWAYS_INDIRECT`は`~.bashrc`で設定するな
2. `LIBGL_ALWAYS_INDIRECT`変数は一切設定するな
3. VcXsrv起動時にはNative openglのやつのチェックを外す。さらに`-wgl`オプションをつけるな。

1、2については、`LIBGL_ALWAYS_INDIRECT`はもともと`\etc\profile.d\wsl-integration.sh`で定義されている（これはシンボリックリンクで本当は`/usr/share/wslu/wsl-integration.sh`）とのことです。
したがって、`~/.bashrc`に

```
unset LIBGL_ALWAYS_INDIRECT
```
をかいてやれば変数が削除できるのでいけます。これで、`./simulate ../model/humanoid.xml`もできますし、mujoco-py 、あるいは OpenAI gym を使った描画もできます。
Androidでハングアウトの着信音が鳴らない症状

## いつの間にかハングアウトの着信音がならなくなった
私はいつもPCやスマホで家族や友人と連絡を取り合う時、だいたいみんな共通で持っているGoogleアカウントだけで使用できるGoogleハングアウトを利用しています。
ある時、友人から「電話出て」と言われスマホを見ると着信に出られませんでしたと表示されていた。
友人に再度かけてもらうと、画面は着信時の表示になるものの、着信音がまったく出ていない状態でした。不思議なことにメッセージの音は鳴るのに、通話での着信音は、どの設定をしても駄目でした。

### 駄目だった設定
* スマホ自体の通知設定の見直し
* アプリケーション毎の通知設定の見直し
* 着信音（メロディ）の変更
* 着信時に音量ボタンを上下してみる（バイブが止まるだけだった）

## 着信音は出るようになりました

結論から言うと、着信音は鳴るようにできました。
簡単にいうと完全に「設定の初期化」LINEだとなかなかこういう初期化作業はできないのですが、ハングアウトはGoogleアカウントに基本データは全て残っているので、スマホ側の設定はカジュアルに初期化しても全く問題がおこりません。
LINEでこんな事態が起きたらやれデータのバックアップだ、バックアップの復旧に失敗してデータが全部飛んだとかアルバムが戻ってこないとか、いろいろ問題が発生しますが、ハングアウトは単純な機能しかなく、スタンプも面白げなものは無いですが信頼性はありますねｗ

### 回復手順

1. スマホの設定メニューから「アプリと通知」を押す
2. アプリ一覧から「ハングアウト」を選択（「最近開いたアプリ」とかに出てるかも）」
3. 「ストレージ」を選択。
4. 「ストレージの消去」を勇気を持って押す
5. 「アプリのデータを削除しますか？」と聞かれますが「OK」を押す
6. 着信を確認して音が鳴ることを確認する

おそらく何かしら無音にする設定が設定画面では見えないところで残ってしまったのでしょう。
キャッシュの削除だけで回復するかな？と思ってやってみたもののキャッシュの削除だけでは着信音はなるようにできませんでした。

リモートワークが推進される中、ハングアウトを選択する機会もあるかもしれません。（Facebookメッセンジャー使えないとかSlack駄目とかTeams駄目とかSkypeは個人アカウント使えないとか…）
ハングアウトはGoogleアカウントに紐付いたサービスであり、ある程度許容されてる率が高いところから汎用性は高いソリューションです。マイナーだけど。
あと、通話品質も海外の方とやりとりするときは、個人的な経験上SkypeやSlackやFBに比べて一番信通話品質が良く、遅延も最も感じられませんでした。
是非これを機にハングアウトつかってみてください。

おっと、友人からの着信が来たみたいだ。それではこれで失礼します。
良いリモートワークを
コーディングしていたらスライムに遭遇した件

## 概要
Vimのポップアップ機能を使って、
`j`を押した時にランダムでスライム(っぽいもの)を表示するようにしてみました

![Apr-03-2020 23-22-15.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68643/341277fa-2e87-0c70-4d20-c2eeb1ba9005.gif)

## コード

```vimscript:.vimrc
function! RandomEncount()
    let l:line = line('.')
    let l:now = localtime()
    let l:random = l:now % l:line
    if l:random >= 5
        call popup_notification("スライムがあらわれた", #{
                \ line: 13,
                \ col: 75,
                \ })
        let l:slime = readfile(expand("~/slime.txt"))
        call popup_dialog(l:slime, #{
                \ maxheight: 40,
                \ minwidth: 40,
                \ moved: "WORD",
                \ })
    endif
endfunction
```

`j` を押した時にポップアップ機能の実行とカーソル移動を行う設定

```vimscript:.vimrc
nnoremap <silent> j j:call RandomEncount()<CR>
```

## 使用したpopup関数
### popup_notification
3秒間 第一引数をVimに表示させる。
第二引数のオプションで表示行と表示列を設定。

### popup_dialog
Vimの中央に枠付きのポップアップウィンドウを表示させる。

第一引数がポップアップの内容。
第二引数のオプションでポップアップのサイズとカーソルを動かした時にポップアップウィンドウを閉じるように設定。

## 参考
[popup - Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/popup.html#popup_notification())
ESLintを導入してVSCode上で問題として検知する

## 概要

既存のVueプロジェクトにLintを導入したかったのでやってみました。

## ゴール

- ESLintを導入する
- VSCode上でLintのエラーが表示される

## 環境

| |Version|
|---|---|
|macOS|Catalina 10.15.4|
|node|10.17.0|
|Vue|2.5.18|

## ライブラリのインストール

```
npm i eslint --save-dev
```

## 初期設定

```
npx eslint --init
```

上のコマンドでconfigファイルが作成される。
選択肢はプロジェクトに合わせて以下のように選択した。
(TypeScript化したい。。)

```
? How would you like to use ESLint? To check syntax and find problems
? What type of modules does your project use? JavaScript modules (import/export)
? Which framework does your project use? Vue.js
? Does your project use TypeScript? No
? Where does your code run? Browser
? What format do you want your config file to be in? JavaScript
The config that you've selected requires the following dependencies:

eslint-plugin-vue@latest
? Would you like to install them now with npm? Yes
```

処理終了後、`.eslintrc.js`が作成された。
json形式のほうが一般的なのかな？

## VSCode

### プラグインのインストール

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

### 必要なライブラリ

eslintのグローバルインストールが必要みたい

```
npm install -g eslint
```

## ルールの設定

ルールを2つ追加してみる。

- 文末のセミコロンは必須
- 複数行の配列、オブジェクトでは最後のコンマは必須

```diff:eslintrc.js
module.exports = {
  ...
+ "rules": {
+   "semi": [ "error", "always" ],
+   "comma-dangle": [ "error", "always-multiline" ],
+ }
};
```

VSCodeを確認すると、これらのルールに反するものが問題として検知された！

## グローバル変数への対応

グローバル変数が`no-undef`のエラーになってしまう。
グローバルであることを明示的に示すことで解決できた。

```diff:eslintrc.js
module.exports = {
  ...
  "globals": {
    "Atomics": "readonly",
    "SharedArrayBuffer": "readonly",
+   "firebase": true,
+   "process": true,
  },
};
```

## おわりに

GitHubActionsを使ったチェックとかやってみたい！

## 参考

- [Getting Started with ESLint - ESLint - Pluggable JavaScript linter](https://eslint.org/docs/user-guide/getting-started)
- [comma-dangle - Rules - ESLint - Pluggable JavaScript linter](https://eslint.org/docs/rules/comma-dangle)
- [[ESLint] "window" is not definedで怒られないようにする - Qiita](https://qiita.com/uggds/items/301c1c43f8b9ffbc52d7)
CodeIgniterをLinuxサーバで使うときにつまづいたこと

#はじめに
PHPのフレームワークのCodeIgniterをxamppの環境で使って開発を進めていてそろそろLinuxのサーバーにあげて開発を進めていこうとし、LinuxのサーバにあげたとたんにURLにアクセスしても繋がらくなり、1時間ほど悩まされこの記事の方法でやっと解決しました。

#命名規則を守ろう

###結論は命名規則を守ろう!!

xamppの環境で開発を進めている時には自分が使っているOSがWindowsでした。
ここのOSで部分が重要になってきます。
自分は、xamppの環境で開発を進めている時にcontrollersとmodelsの部分のフォルダの中身にあるファイルの先頭の文字を小文字で開発を進めていました。
しかし、ここのファイルを小文字で進めていたことに原因がありました。
そう、ファイル名は大文字から始めるということです。(ちゃんと公式のドキュメント読んどけばよかった)
先ほどもいいましたがOSが重要になってくるのはWindowsやMacはファイル名の大文字小文字を区別しないのですがLinuxではそこがちゃんと区別されるからでしょう。

###命名規則は守りましょう!!

#おわりに
もう少しCodeIgniterの日本語のサイトがあってくれると嬉しいです(笑)

#参考
[PHP スタイルガイド — CodeIgniter 3.2.0-dev ドキュメント](https://codeigniter.jp/user_guide/3/general/styleguide.html)
ARMベースのSurface Pro X買って WSL2でARM64 Linux開発環境構築

# はじめに
LTE/4Gでインターネットに常時接続可能で(しかもGoogle Fi SIM使えばほぼ世界中でネット接続可能)、Type-Cで(モバイルバッテリーからも)充電ができて、バッテリーの持ちがそこそこ良くて、軽くて、ペンが使えて ... RAMも(iPad Pro 1TB版のような6GBではなく)16GBあってということで、Surface Pro X購入しました。

Windowsアプリケーションであれば、x86アーキテクチャ(エミュレーション)、またはARM64アーキテクチャであれば動作可能です。裏を返せば、x64アーキテクチャのものは動作しないということになります。

ここいらの話をWindowsネイティブの開発系アプリ目線でまとめたものがこちらです。

- [ARMベースのSurface Pro X買って開発環境構築](https://qiita.com/mfunaki/items/1dc47ab4edb60cef6416)

その一方で、WSL2の中なり、dockerの中なり、Hyper-VのLinux環境の中で開発環境を構築するのであれば、より自由な開発ができるかと思い、こちらにまとめてみました。私個人の考えですが、Surface Pro X + WSL2 + docker + VSCode(remoteWSL)はかなり無敵感の強い開発プラットフォームかと思います。Win32(x86)エミュレーションに頼るよりバッテリーの持ちも良いことが期待できるので(Arduino, M5Stack ... といったドライバ必要系プラットフォームとの相性が良くありませんが)。

# 動いた
## Chromium
Chromeのオープンソース版であるChromiumですが、普通にapt-get chromium-browserでインストール可能です。
(一方でChromeはarm64版が用意されていません。詳しくは下の「動かなかった」の「Chrome」の項を参照。)

# 動かなかった
## Chrome
Qiitaの中でもWSL2でChromeを動かした系の記事があります。

- [WSL2 + Docker(ubuntu18.04) からchromeを起動する](https://qiita.com/chilchil0/items/9c7c56ad1cdafef389c4)

上の記事の手順はSurface Pro X環境でもそのまま実行可能ですが、最終的にChromeのインストールを使用しても、見つからないエラーになってしまいます。

![google-chrome-stable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/701a880a-ed37-6649-455a-aa251beaa642.png)

見つからないってどういう事かと思いきや、amd64版しか用意されていないので、arm64環境では「見つからない」ということでした。

![google-chrome-stable2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/82a2e6a6-c5d9-b89f-4750-eebdabd43795.png)

chromium-browserはarm64アーキテクチャ版が用意されているので、こちらを使うのが近道です。

# 終わりに
(随時書き足していきます。)
nowのデプロイで古い書き方からのマイグレートメモ


now.shを使うときにv2系の書き方でも警告が出るようになってますね。
もう1系は使えないのかも。

nowで詰まった人がいたのでメモ。

## 今まで書いてたやり方と修正点

これまでは、これでよかったのですが......

```now.json
{
    "version": 2,
    "name": "mylinebot",
    "builds": [{ "src": "server.js", "use": "@now/node" }],
    "routes": [
        { "src": "/", "dest": "server.js" },
        { "src": "/webhook", "dest": "server.js" }
    ]
}
```

```bash
now --target production
```

> ![](https://i.gyazo.com/9471521a9ad9f3710b3f4c9f9c355aef.png)

### nameプロパティの注意

まずはここ。

```
❗️  The `name` property in now.json is deprecated (https://zeit.ink/5F)
```

[ここ](https://zeit.co/docs/configuration#project/name)を読むと、書いてますが

> NOTE: The name property has been deprecated in favor of Project Linking, which allows you to link a ZEIT Now Project to your local codebase when you run now.

**nameプロパティが非推奨と言われます。**

なのでnameプロパティを外します。修正版はこちら。

```now.json
{
    "version": 2,
    "builds": [{ "src": "server.js", "use": "@now/node" }],
    "routes": [
        { "src": "/", "dest": "server.js" },
        { "src": "/webhook", "dest": "server.js" }
    ]
}
```

### デプロイコマンド

次にここです。

```
WARN! We recommend using the much shorter `--prod` option instead of `--target production` (deprecated) 
```

もともとの書き方の`now --target production`が`now --prod`で良いよと言われます。短い方が良いですね。

```bash
now --prod
```

これでOKです。

## おまけ: 実行時

実際のデプロイで表示されるコンソールの紹介です。

対話的に質問されます。"deployの設定をしますか?"的な質問です。エンターかYをタイプして進みましょう。

```
Now CLI 17.1.1
? Set up and deploy “~/Documents/ds/playground/mylinebot”? [Y/n] ←ここでエンターもしくはY
```

次にデプロイ先のアカウントを選択。 たぶんチームアカウントとかあると選択肢に載ってくるんだと思いますが、たぶん最初は自分のアカウントだけなので自分のアカウントが表示されるのを確認したらエンター。

```
? Which scope do you want to deploy to? 
● n0bisuke ←ここでエンター
```

次になんて名前でデプロイするか聞かれます。package.jsonのnameプロパティに書いてある名前が表示されるので、エンターかYをタイプして進みます。

```
? Found project “n0bisuke/mylinebot”. Link to it? [Y/n] ←ここでエンターもしくはY
```

これでデプロイできるはず......!
PMBOKを再考する

# ポイント
* PMBOKを肯定も否定もしないけど、改めて思うことを書いてみる
    * 10の知識エリア・5つのプロセス群の位置づけ
    * PMBOK以外の領域の重要性

# PMBOKは一般教養としてはおさえておく
* PM/PMOさえやれたらOKみたいな開発にはならない
    * AWSとかJavaとかk8sとか様々な開発技術は大事
* 一方で、コーディングだけ得意みたいな感じでもダメ
    * テスティングとかアーキテクチャとかドキュメンテーションとか
    * 色々大事なものはあるし、PMBOK的な要素も一般教養としてはあったほうが良い
* ということでPMBOKのポイントって何？みたいなのをおさえていたほうが良いかな

# [10の知識エリア](https://qiita.com/kenji-yokoi/items/f9509ce3cdda97cae268)と言うけれど

* 並列の概念ではない
  * 10あるとさぞかしMeceなんだろうと思ったら、それぞれを関係する統合マネジメントがあったりする
  * QCDSとかもMeceでも排他でもないので、QCDSに直結する内容が多い10の知識エリアも当然そう
* 5つのプロセス群にも濃淡
    * 実行プロセスが定義されているのは品質など一部の知識エリア
    * なので、設計とか実装とかそういう実行プロセスはPMBOKの範囲外で、
    * かつ実行プロセスこそ大事なのでPMBOKだけあればOKみたいにはならない

# やっぱり伝えたいこと
* 役割分担としてはナシではない気もするが、実行プロセスに資するような活動は大事
    * と、考えながら何事も進めるべき
* 若年層の時に、そこを履き違えてPMBOKだけあればOKみたいな感覚を持っている人がいたとしたら、
    * いい悪い別にして立ち止まって再考してみる価値はあるかなと
git: 別ブランチの一部のファイルのみMergeする方法

# git: 別ブランチの一部のファイルのみMergeする方法

## 背景


[semantic-release](https://github.com/semantic-release/semantic-release.git) と [トランクベース開発](https://cloud.google.com/solutions/devops/devops-tech-trunk-based-development?hl=ja) をする中で、
`git branch --contains`に含まれることを必要条件とし、
`CHANGELOG.md`をリリースブランチからmaster ブランチに 持ってくる必要がありました。

今回その方法をご紹介致します。

## 方法

今回は`release/v1.0.x`ブランチから `master` ブランチに`CHANGELOG.md`のパッチを当てることを想定実行します。



### 1. パッチファイル作成

```
git format-patch --histogram '..release/v1.0.x' -- CHANGELOG.md
```
上記を実行すると、`CHANGELOG.md`の`master`と`release/v1.0.x`コミット差分だけパッチファイルが生成されます。

### 2. パッチを当てる
```
git am -3 *.patch
```

１番で生成されたパッチファイルを適応します。

### おまけ
`git merge {リリースブランチのSHA1}`
最後に上記を実行すると、`git branch --contains {tag名}`をすると
ex) `v1.0.0` が含まれることが確認できます。
ずんどこプログラム

```ruby:filename.rb
package zundokoProgram;

import java.util.Random;

public class Zundoco_random {
	public static void main(String[] args) {
		Random random = new Random(); 
		String[] zun_doko = { "ずん ", "どこ " };
		String zundoko = new String();

		while (!(zundoko.equals("ずん ずん ずん ずん どこ "))) {
			zundoko = "";
			for (int i = 0; i < 5; i++) {
				String s = zun_doko[random.nextInt(2)]; // 変数sに、ランダムで選ばれた配列zun_doko要素数[0,1] ＝ ”ずん ”,”どこ ”のどちらか１文字が入る
				zundoko = zundoko.concat(s);            // 変数zundokoに変数sをくっつける
			}
			System.out.println(zundoko);
		}
		System.out.println("きよしぃいい！！！");

	}
}
```


ずんどこプログラム初めて記念に投稿させていただきたい・・・！！
３日くらいかかりました。