OmniAICreator/Qiita-1.07M huggingface dataset:
rangerでPDFとMSワードとMSエクセルをターミナルでplain text形式で開いたりプレビューするスクリプト

この記事ではrangerでPDF、MS office ワードとエクセルをテキスト形式でプレビュー表示する方法を紹介します。
[ranger](https://github.com/ranger/ranger)はPython製CLIファイラーです。

## 準備

* [ranger](https://github.com/ranger/ranger)と[poppler](https://poppler.freedesktop.org/)と[catdoc](https://linux.die.net/man/1/catdoc)と[docx2txt](https://github.com/ankushshah89/python-docx2txt)と[xlsx2csv](https://aur.archlinux.org/packages/python-xlsx2csv/)が必要です。
* MS Officeは必要ありません。
* Archlinuxユーザーなら、`pacman -S ranger catdoc docx2txt poppler`でPDFとワードのプレビューに必要なツールが手に入ります。
* エクセルプレビューに必要なツールはAURにあるので`yay -S python-xlsx2csv`

## Enterしたときにpdf/doc/docx/xls/xlsxファイルをplain text形式でターミナルで開く方法

開くアプリの選択は`~/.config/ranger/rifle.conf`に書きます。

```rifle.conf
--snip--

#-------------------------------------------
# Documents
#-------------------------------------------

--snip--
ext pdf, has pdftotext,     terminal = pdftotext -layout -nopgbrk "$@" - | "$PAGER"
ext doc?, has catdoc,       terminal = catdoc -- "$@" | "$PAGER"
ext docx?, has docx2txt,    terminal = docx2txt "$@" - | "$PAGER"
ext xls?, has xls2csv,    terminal = xls2csv -- "$@" | "$PAGER"
ext xlsx?, has xlsx2csv,    terminal = xlsx2csv -- "$@" | "$PAGER"
--snip--
```

## 選択中にpdf/doc/docx/xls/xlsxファイルをplain text形式でターミナル上にプレビューするスクリプト

プレビュースクリプトは`~/.config/ranger/scope.sh`に書きます。

```scope.sh
--snip--

# wraps highlight to treat exit code 141 (killed by SIGPIPE) as success
highlight() { command highlight "$@"; test $? = 0 -o $? = 141; }

case "$extension" in

--snip--
    # PDF documents:
    pdf)
        try pdftotext -l 10 -nopgbrk -q "$path" - && \
            { dump | trim | fmt -s -w $width; exit 0; } || exit 1;;

    # DOC documents:
    doc)
        try catdoc "$path" && \
            { dump | trim | fmt -s -w $width; exit 0; } || exit 1;;
    # DOCX documents:
    docx)
        try docx2txt "$path" - && \
            { dump | trim | fmt -s -w $width; exit 0; } || exit 1;;
    # XLS documents:
    xls)
        try xls2csv "$path" && \
            { dump | trim | fmt -s -w $width; exit 0; } || exit 1;;
    # XLSX documents:
    xlsx)
        try xlsx2csv "$path" && \
            { dump | trim | fmt -s -w $width; exit 0; } || exit 1;;
--snip--
```
Javaの標準出力を利用し配列から最大値を出力する

某サイトのJavaの練習問題。標準入力で整数nを入力した後、n個の任意の数値を入力してその中から最大値を出力するプログラムのメモ。

```java
import java.util.Scanner;

public class Main{
   public static void main(String[] args){
      Scanner sc = new Scanner(System.in);
      //整数nを入力
      int num = sc.nextInt();
      int max = 0;
      int[] array = new int[num];

      //n回任意の数値の入力を行う
      for(int i = 0; i < num; i++){
         array[i] = sc.nextInt();
         if(max < array[i]){
            max = array[i];
         }
      }
      System.out.println(max);
   }
}
```
VScode(Visual Studio Code)の日本語切替

# この記事でわかること
VScodeを使用していて、表示が英語設定になってしまった時
日本語設定に切り替える方法。

:thinking:「japanese language pack for visual studio code」をインストトールしている前提で説明していきますので注意ください。
　
　　
　　
　　
# 手順
＜はじめに＞
※本来は英語で表示されていると思いますが、今回は日本語表示の画像で説明しています。特に分かり難さはないと思うので不安な方はご自身のわからない部分を和訳するとマッチすると思います。
　
　　

①VScodeを開いて、メニューバーの「表示」をクリックする
![スクリーンショット 2020-08-20 17.44.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/e85b4b2f-25bd-d7c2-fdc7-c8613ee4409a.png)
　　
　　
　　
②コマンドパレットを選択、もしくは「Shiftキー」＋「command」＋「P」でショートカットしてもオッケー。この場合①を飛ばしても良い。
![スクリーンショット 2020-08-20 17.46.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/0669ba15-cea2-5090-f439-b7f8fc720875.png)
　　
　　
　
③コマンドパレットが開いたところで、「language」と打ち込む。
　すると、候補が下に現れるので「Configure Display Language」を選択。
![スクリーンショット 2020-08-20 17.51.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/a1375b29-cfba-febd-ccdc-efe0373e7157.png)
　　
　　
　　
④表示言語の選択というインプット欄が表示され、その下に候補が現れるので「ja」を選択。
![スクリーンショット 2020-08-20 17.53.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/5e34375e-f56e-3d49-5a91-f15603c60cd4.png)
　　
　　
　　
⑤再起動が必要だと表記したアラートが出るので「再起動」を選択。
![スクリーンショット 2020-08-20 17.59.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661441/2fffb805-1c96-9c23-8e03-52d9661bd208.png)
　　
　　
　　
これでVScodeが再起動するのでその際には日本語になっていると思います:blush::crown:
お疲れ様でした！！

 
  
#ひとことMemo
自分の場合、VScodeを開いた時に突然英語表示に戻っていることがあり
毎回毎回調べて直すのが手間だったのでこの記事を書きました。
なぜ突然日本語設定が解除されてしまうのかは不明です。


## 参考サイト
https://www.atmarkit.co.jp/ait/articles/1805/18/news032.html
Macで簡単にUPPERCASE、lowercaseの切り替えを行う方法(Alfred使用)

コード書いててUPPERCASE、lowercaseとかに変換したいときありますよね。

今まではいちいちブラウザ開いたりメモ帳開いたりして変換してそれをコピーしていたんですがそれが非常にめんどくさくなってきたので探したらめちゃめちゃいいのがありました。

ただ、Alfredを使用しているのでWinの方やAlfredを使っていない方はブラウザバック推奨です。

それでは紹介していきます。

# 導入方法
今回導入するのは以下のAlfredのワークフローです。
https://github.com/gillibrand/alfred-change-case

まずは以下の画像にあるリンクからワークフローをDLしてきてください。
![gillibrand_alfred-change-case__An_Alfred_workflow_to_change_the_case_of_text_on_the_clipboard_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403521/11f1c269-e7bd-16a0-3ebc-bdcfa07fbd57.png)

DL出来たらそのworkflowを起動するだけです。

起動したらAlfredに切り替わって以下のような画面がでるのでImportボタンを押すだけです。
簡単。
![Alfred_Preferences.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403521/81c74e2d-132c-9837-bc59-f7dbf1990ce7.png)

# 使用方法
導入出来たらAlfredのボックスに'case'と入力するだけで現在クリップボードにコピーされている文章を以下のように変換できます。
CamelCaseやsnake_caseにも対応していて非常に便利です。
![スクリーンショット 2020-08-20 18.04.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403521/53fdf46e-deb3-f2d7-fa49-ddfe01a8a7e4.png)

# あとがき
地味によく使う機能だと思うので気になった方は是非導入してみてください！
JenkinsでiOSビルドする際に、プロビジョニングファイルを指定する

# はじめに
Jenkinsで開発版をビルドしていて、いざAppStore向けにもビルドするとなったとき、プロビジョニングプロファイルを新しく作りました。

開発版ビルドはプロビジョニングプロファイルを自動指定だったので、このままだと開発版ビルドがどのプロビジョニングプロファイルを使うか分からないので明示的に指定する必要が出てきました。

秒で終わる内容ですが、その時の対応を備忘録としてメモしておきます。

# 環境
MacBook Pro(16-inch,2019)
macOS Catalina 10.15.2
XCode 11.3

Jenkinsジョブ設定済みで、バッチビルドのセットアップは済んでいる状態とします。
ビルドしたのはUnityで作ったプロジェクトです。
# 対応
## ビルド時に使うplistにプロビジョニングプロファイルのIDを指定する
plistの<dict></dict>内に以下の設定を追加します。

```exportOption.plist
    <key>provisioningProfiles</key>
    <dict>
        <key>プロビジョニングファイルに紐付いたBundleID（ex:com.xxx.xxx）</key>
        <string>プロビジョニングファイルのName（ex:MyApp_Distribution）</string>
    </dict>
```

##XCodeにプロビジョニングプロファイルをダウンロードする
XCodeを開いて、プロビジョニングプロファイルをダウンロードします。

メニューバー→Xcode→Preferencesで設定を開きます。
次にAccountsタブで、指定したプロビジョニングプロファイルに含まれているチームやユーザを指定して「Download Manual Profiles」をクリックします。

##おわり
ダウンロードが終わるまで待てば完了です。
ジョブを動かして正しくビルドされるか確認します。
#補足
この設定が無い場合は、自動でプロビジョニングプロファイルを選択してビルドします（おそらくXCode内にダウンロードしてあり、ビルド対象プロジェクトで使えるものが選択される？）

XCodeのプロビジョニングプロファイルが古い時は、「~/Library/MobileDevice/Provisioning Profiles/」ディレクトリの中のプロビジョニングプロファイルを削除してから、上記のダウンロード操作をします。
#参考リンク
https://qiita.com/taisuke_h/items/e37d96c96a811b630c0c

plistの各種設定の確認に。

https://qiita.com/roworks/items/7ef12acabf9679561d84

plistのxcodeビルド周り全般の参考に。
RAMとROMの分類、主記憶装置と高速化手法

#RAMとROM
特徴
　・RAMは読み書きが自由にできるという特徴を持つが、中身は電源を切ると消去される。この性質を**揮発性**という。
　・ROMは基本的には読み出し専用のメモリ。動作に必要なプログラムやデータは、あらかじめメモリ内に書き込まれた状態で工場から出荷されます。
　　この時に書き込まれた内容は、電源の状態に関係なく消えることはない、この性質を不揮発性と呼ぶ。
**RAMとROMの分類図**
 ![図62.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686519/0adba84a-15d8-f989-2cf7-6acd9473054b.png)

#RAMの種類
RAMはさらに、**主記憶装置に使われるDRAM**と**キャッシュメモリに使われるSRAM**の２種類に分かれる。

**DRAM(Dynamic RAM)**
　・安価で容量が大きく、主記憶装置に用いられるメモリ。ただ読み書きはSRAMに比べて低速。
　・記憶内容を保つためには、定期的に内容を再書き込みするリフレッシュ動作が欠かせない。
　　![図63.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686519/b2353f2e-8224-f8dd-6a56-229ab44af958.png)


**SRAM(Static RAM)**
 
　・DRAMに比べて非常に高速だが価格も高い
　・小容量のキャッシュメモリとして用いられるメモリ
　・記憶内容を保持するのん、リフレッシュ動作は必要ない
　![図64.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686519/b4d7cbd7-23de-757f-21ab-2dd153772ccd.png)

#ROMの種類
 POMの種類は以下の通り
　・マスクROM
　　　読み出し専用のメモリです。製造時にデータを書き込み、移行は内容を書き換えることができない・
　・PROM
　　プログラマブルなROM。つまり、ユーザの手で書き換えることができるROM、PROMには下記のような種類がある。
　　　・EPROM：赤外線でデータを消去して書き換えることができる
　　　・EEPROM：電気的にデータを消去して書き換えることができる
　　　・フラッシュメモリ：EEPROMの１種。全消去ではなく、ブロック単位でデータを書居して書き換えることができる。

#主記憶装置と高速化手法
　記憶装置間の速度ギャップを埋めて、町時間によるロスを防ぐための手法が**キャッシュ**です。
  装置間のギャップyを緩和させるために用いる手法で、レジスタとメモリの間に設けるキャッシュメモリと
　メモリとハードディスクの間に設けるディスクキャッシュ等がある。
 **キャッシュメモリ**
  仕組み
　　![図65.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686519/79f03a74-a7d7-5774-aadf-41aa6dab9a5d.png)

**ディスクキャッシュ**
 主記憶装置と磁気ディスク装置の間で担う、専用に半導体メモリを搭載したり、主記憶装置の一部を曲がりするなどして実装している。

**記憶階層**
  ![図66.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686519/18f23e33-7b2a-9fd2-5fd8-449738037276.png)


#主記憶装置への書き込み方式
　キャッシュメモリは読み出しあけじゃなくて、書き込みでも使われている。ただし、読み出しと違って書き込みの場合は、
　「書いて終わり」とはいかない。更新した内容をどこかのタイミングで主記憶装置にも反映してあげないといけない。

　・**ライトスルー方式**
　　この方式では、キャッシュメモリへの書き込みを行う際に、主記憶装置へも同時に書き込みを行います。

　・**ライトバック方式**
　　 この方式では、普段はキャッシュメモリにしか書き込みを行いません。
　　 キャッシュメモリから追い出されるデータが発生した際に、その内容を主記憶装置へ書き戻して更新内容を反映させます。
　
#ヒット率と実行アクセス時間
　ヒット率
　　・目的とするデータがキャッシュメモリに入っている確率のこと
　
　キャッシュメモリを利用したコンピュータの平均的なアクセス時間（**実行アクセス時間**）は、ヒット率を使って以下のように求めることができる。
　　
![図67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686519/48a26be6-532c-b42c-902a-c439fde06d02.png)


#以上
for文について

for文
for 文は決められた回数だけ、処理を繰り返しを行います。以下のの通りです。
for 変数 in イテラブルオブジェクト:
    実行する文

イテラブルオブジェクト
イテラブルとは、「繰り返し可能なオブジェクト」のことです。
for文において、文字列や数字を繰り返すことが可能であり、「for i in X:のXの部分に該当することができるもの」です。
例えばリスト、タプルやrange関数で生成したオブジェクトなどがイテラブルに該当します。
 
イテレータとは
イテレータは、「イテラブルオブジェクトを使用した連続データ」のことです。
イテレータは以下のようにiter()という関数を用いて作成することができます。
iter()の引数にはイテラブルを与えてあげる必要があり、イテラブルがなければイテレータを作成できません。
>>list_x = [1,2,3,]
>>iter_x = iter(list_x)
これでiter_xという変数にイテレータを格納することができます。
イテレータはnext()という関数を用いて要素を順に取り出すことが可能です。
ただ、リストなどとは違って要素を取り出すごとに、取り出された要素は消滅して行きます。
これがイテレータの特徴です。

for文(for..else文)
for 文はイテラブルオブジェクトの要素の数だけ繰り返し処理を行いますが、全ての要素を取得したあとに最後に実行される処理を else 節のあとに記述することができます。
>>for 変数 in イテラブルオブジェクト:
    実行する文1
    実行する文2
else:
    実行する文1
    実行する文2


for 文の次に記述した場合と基本的には変わりません。 for 文が終了すると、 for 文の次に記述されている文が実行される。
>>for 変数 in イテラブルオブジェクト:
    実行文a
    実行文b

>>実行文a
>>実行文b


ただ for 文の中で break 文が実行された場合だけ異なります。 break 文が実行されると else 節のあとに記載されているブロック内の処理は実行せずに for 文の次へ処理が移るためです。 else 節を使わなかった場合は break 文が実行されたかどうかに関わらず for 文の次に記述された処理が実行されます

if – break文の使い方
if – break文は以下のような形式で使うことが可能です。
>>while 条件a:
>> if 条件b:
>>   break


while文でもfor文でも使用方法は同じです。
そして、繰り返し処理の中でif-break文を書くことで繰り返し処理を中断させることができます。
 
if文での分岐方法
if文で条件が複数の場合は以下の形式を使用します。
>>if 条件a:
>>  処理a
>>elif 条件b:
>>  処理b
>>else:
>>  処理c


プログラムは上から順番に条件を満たしていくため、条件aで一致すれば処理aを行います。
条件aに一致せずに条件ｂで一致すれば処理ｂを行い、条件aも条件bも一致しない場合は処理cを行います。elif 条件を使用した場合には、さらに条件文を増やすこともできます。
nvmをインストールしたのに、-bash: nvm: command not foundになる。

https://github.com/nvm-sh/nvm#install--update-script
こちらの

```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
```

を使ってnvmをインストールし、特にエラーもなく完了したはずなのに

```
$ nvm --version
```
で
-bash: nvm: command not found
と言われた。

色々試した結果、

```
$ source ~/.nvm/nvm.sh
```
を実行することで解決。

頑張った末に、手順の下の方に”Troubleshooting on macOS”を見つけたので、ドキュメントを読むのが大事だと思いました。


追記（2020年8月21日）

このままだと、起動のたびに同じコマンドを叩かないといけなかったので、起動のたびに有効化してくれるように、/etc/profile.d/以下にシェルを置いておきます。
>/etc/profile.d/nvm.sh

```
$ source ~/.nvm/nvm.sh
```

参考：https://www.yoheim.net/blog.php?q=20161202
クラウドサービスとは？

##クラウドサービスは「どこ？」が分からないサービス
クラウドという言葉を耳にすると、多くの人が**「クラウド＝雲」**を想像します。実は、この「雲」のイメージが先立ってしまい、クラウドの理解を妨げていることが多いようです。ここではまず一旦「雲」のことは忘れ、例えとして「ピザの宅配」を取り上げて、話をしてみます。

宅配ピザを注文するとき、大体の方は、自宅の郵便受けに入っていたピザ屋さんのチラシを見て、電話で注文します。30分もすると、バイクに乗ったピザ屋さんが箱入りのピザを届けてくれます。

ここにはちょっとした不思議があります。多くの人は、ピザが自宅に届けられるまで、ピザ屋さんを見ることがありません。自分が電話したピザ屋さんがどこにあるのか？どんな場所でピザが焼かれているのか？そういったことが分からないまま注文しています。

クラウドサービスは、このような、「どこにあるのか？」「どんな場所で作られているのか？」「どこの人が作業をしているのか？」が分からないけれども利用できるサービスのひとつです。私たちは「どこ？」が分からなくても、多くの商品やサービスを利用しています。


##クラウドサービスとは？
**クラウド（クラウド・コンピューティング）**は、コンピューターの利用形態のひとつです。インターネットなどのネットワークに接続されたコンピューター（サーバー）が提供するサービスを、利用者はネットワーク経由で手元のパソコンやスマートフォンで使います。  クラウドの特長のひとつは、利用にあたって、コンピューター（サーバー）の所在地（どこ？）が意識されない点です。たとえるならば、雲（クラウド）の中にあるコンピューターを地上から利用しているようなイメージです。そして、クラウドの形態で提供されるサービスを「クラウドサービス」と言います。  従来のコンピューターの利用形態では、利用者は手元のパソコンの中にあるソフトウェアやデータを利用していました。しかしクラウドサービスでは、ネットワークを経由して、雲（クラウド）の中にあるソフトウェアやデータをサービスの形でつかうのです。

##「どこ？」がわからないまま使っているクラウドサービスの例
クラウドサービスの代表的な例にはWebメールがあります。「Gmail」や「Yahoo!メール」などが有名です。これらのWebメールサービスは、サーバーがどこにあるかを意識させません。一般的なメールとどのように違うのかを、もう少し詳しく見てみましょう。  例えば、多くの会社ではメールサーバーを、自社の中や自社が利用しているデータセンターなどに持っていたり、レンタルのメールサーバーを利用していたりします。そしてメールを受送信・閲覧するためには、自分のパソコンにインストールしてある「Windows Liveメール」や「Outlook」や「Thunderbird」などのソフトウエアを使っています。

Webメールではまず、このようなソフトウエアを自分のパソコンにインストールする必要がありません。Webの閲覧に使用している「Internet Explorer」や「Chrome」などのブラウザーがあればサービスを利用できます。また、自前のメールサーバーを用意する必要もなく、ユーザー登録だけすれば、「どこにあるかは分からないが、どこかにあるだろうサーバーとメールソフト」を使って、メールの受送信や閲覧ができます。

このように、ネット上のどこかにあって仕事をしてくれているが、どこにあるかはよく分からないサービスを、クラウドと呼びます。

##クラウドではないことが普通だったから、クラウドという言葉ができた
Webメールのような誰でも使っているサービスがクラウドなら、どうして今さら"クラウド"などという言葉が出きたのでしょうか？それは、これまでのパソコンやシステムの多くが"クラウド"ではなかったからなのです。特に、会社の業務に使っていたソフトウエアは、ほとんどがクラウドではありませんでした。  最も分かりやすい例として、エクセルやワードといったアプリケーションについて説明しましょう。これらのアプリケーション（ソフトウエア）は、どこにあるのでしょう？ほとんどの方は、自分のパソコンの中にあるとお答えになると思います。そして、そのアプリケーションで作った表やワープロ文章のデータも、パソコンやサーバの中など明確な場所に置いていると思います。この状態は、クラウドではありません。  最近、このような「クラウドでないサービス」も、クラウドにした方がメリットがあることがわかりはじめました。そのため、従来の「特定の場所にソフトウエアやデータを持つシステムの使い方」に対して、「どこか分からない場所にソフトウエアやデータを持つシステムの使い方」を、簡単に言い表すために、クラウドという言葉が使われはじめたのです。

_※「クラウド」という言葉は、米Google社 エリック・シュミットCEOの2006年8月の発言に由来すると一般的に言われています。また、エンジニアたちがネットワーク図を作成する際に、ネット上のどこかにあるものを雲の絵を使って表わすからとも言われています。_


引用元記事
https://jpn.nec.com/cloud/smb/column/01/index.html
Material-UIのTextFieldコンポーネントで、Inputフォームにスタイルを適用する

# 問題
- Material-UIのTextFieldコンポーネントを使用してフォームを作成する
- この入力フォームやPlaceholderのスタイルを変更しようと、コンポーネントStyleを当てようとしても、反映されない

# 原因
- TextFieldコンポーネントは、input要素を含んだdivのため、直接スタイルを反映することができない

# 解決法
- inputフォームを変更したい場合は、TextFieldコンポーネントの`inputProps`を、                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        - placeholderを変更したい場合には、同様の`InputLabelProps`を変更する
- どちらもpropsとして渡す要素・方法は同じ
- これらはinput要素、label要素のattributesを変更するためのprops
- [公式ドキュメントのComponentAPI](https://material-ui.com/api/text-field/)に書いてあります

## makeStylesを使用している場合
- makeStylesで作成したclassNameを、inputPropsに渡す
- これによって、input要素がmakeStylesで作成したclass名を持つことになり、スタイルが適用される

```react:sample.js
import { makeStyles, TextField } from '@material-ui/core'

const useStyles = makeStyles(() => ({
  title: {
    fontSize: 30,
  },

export default function Home() {
  const classes = useStyles();

  return(
      <form>
        <TextField inputProps={{className: classes.title }} InputLabelProps={{ className: classes.title }} label="タイトル" name="title"/>
      </form>
  )
```

## makeStylesを使用していない場合


```react:sample.js
import { TextField } from '@material-ui/core'

export default function Home() {

  return(
      <form>
        <TextField inputProps={{style: {fontSize: 140} }}  InputLabelProps={{ style: {fontSize: '30px', color: 'red'}}} label="タイトル" name="title"/>
      </form>
  )
```
GAEデプロイ時の「DEADLINE_EXCEEDED」レスポンスエラーを解決する方法

## 問題のエラー

> ERROR: (gcloud.app.deploy) Cloud build failed. Check logs at https://console.cloud.google.com/cloud-build/builds/*******************?project=*********** Failure status: UNKNOWN: Error Response: [4] DEADLINE_EXCEEDED

どうやらタイムアウトエラーっぽい

## 解決方法
- Cloud SDKコマンドラインで、以下のコマンドを実行してタイムアウトの秒数を指定する

```bash
gcloud config set app/cloud_build_timeout 3600
```

※ 引数の秒数は任意の数値を指定

## 参考
- [gcloud config set  |  Cloud SDK のドキュメント  |  Google Cloud](https://cloud.google.com/sdk/gcloud/reference/config/set)
- [Google App Engine: Build Timed Out during Deployment - Stack Overflow](https://stackoverflow.com/questions/50046545/google-app-engine-build-timed-out-during-deployment)
コーヒー店のWebサイト開発－午後

平成31年春期 午後問題8

ファイル：2019h31h_ap_pm_qs.pdf

１、本文のaに入れる適切な字句を答えよ。
参照答えは、「レスポンシブWebデザイン」（responsive-web-design）です。
定義だから、知る、知らないだけですね。

私は、自適応　と答えてしまいました。。。


＜＜案実現の検討＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/d8707361-0d9f-fa65-97de-9e207bb65fbf.png)

・「レスポンシブWebデザイン」とは、PC、タブレット、スマートフォンなど、異なる画面サイズの幅を基準にWebサイト表示を柔軟に調整し、見やすく最適な表示にすることを指します。

２、bに適切な字句を入れて答えよ。
bは、簡単ですね。HTMLです。「html」も正しいと思います。

＜＜表１　両案の特徴＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/fac8e0dc-333d-1a59-1ae6-224d8bcd468b.png)

３、c,dに入れる適切な字句を解答群から選ぶ。
c,dはブラウザの何らかの情報ですね。その情報により、案２で異なるHTMLを作ること。
では、c,dはブラウザの「種類」と「バージョン」情報ですね。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/d9622908-4740-8627-4b69-b84b13f908e8.png)


４、本文中の下線①について、開発コストが大きくなる理由を３５字以内で述べよ。
開発コストは、初期開発と将来のデザイン変更両方ですね。
・初期開発は、デバイスごとに最適化した複数HTMLファイルを準備しておく要。
・将来は、デバイスが増えると、追加するのは必要。

つまり、「デバイスごとHTMLファイルを準備しておくが必要」とのことですね。


Webブラウザの種類とバージョンがどんどん増えるので　（※私の答え）
→
デバイスごとのHTMLファイルを開発する必要があるから

多分、私の答えとすると、減点か、得点できないかもしれませんね。
デバイスがWebブラウザだけではなくだし、未来のことだけでもないですね。
恥ずかしい。。。（笑）

＜＜表１　両案の特徴＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/be1ae5d6-53b4-28b3-42b7-8fe05d46dc2a.png)


５、e~hに入れる適切な字句を答えよ。
設問の図２には、「タブレット用のCSSを記述」ですので、eは768px、fは1,023pxですね。
gは表３により、「/images/topimage_w768.jpg」ですね。
hは、デザインイメージの作成　により、繰返し表示は行わないことので、「no-repeat」ですね。

＜＜図２＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/fb11a693-ab2a-e9ba-c322-1b5ab844c3ba.png)

＜＜表３　CSSで使用する書式及びデータの一部＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/c45580b9-8349-a271-fa8e-1faa1b7b746f.png)

＜＜デザインイメージの作成＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/0d781f18-4667-d638-4591-fbcbdd3d4bf9.png)

＜＜表２　K君が決定したウィンドウ幅の範囲＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/e3dc1b13-cb45-c95b-df6f-3d3a48b4b6a2.png)


６、K君が本文中の下線②の方針とした目的を２０字以内で述べよ。
表１の「表示速度」項目に、画像の理由で、表示の遅延が発生するとのことですね。
下線②の方針は、デバイスごとにサイズの異なる画像を用意して、その表示の遅延を解消しようとの目的ですね。
なので、「画像表示の遅延を発生しないようにするため」ですね。

表示の遅延が発生しないようにする（私の答え）
→
画像表示の遅延を防ぐため


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/19348da8-59fc-3230-42dc-d4d1444ee0db.png)

＜＜表１　両案の特徴＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/fac8e0dc-333d-1a59-1ae6-224d8bcd468b.png)


結論：
Webサイト設計の質問は、難しくないですが、
注意点もいくつありますね。
例えば、
・min-widthとmax-widthの単位　px　が付いていたか
・表示の遅延　だけど、何の表示ですか？　「画像表示。。。」ですね
・概念の「レスポンシブWebデザイン」は覚えていますか。私にとっては難しいかも



参照：
レスポンシブWebデザイン　responsive-web-design
https://digitalidentity.co.jp/blog/creative/responsive-web-design.html
![Something went wrong]()
Unityでファイル選択画面を使う

###↓こんな感じのダイアログボックスを使ってファイルを選択したい:thinking:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374827/f9f5105a-79ad-52f1-e39d-663f51ae2b8b.png)

追記
※ビルド後にこのダイアログボックスを使用することはできないらしい
ビルド後に使うなら[OpenFileDialog](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.openfiledialog?view=net-5.0)を使うのが正解
[ここ](https://qiita.com/otochan/items/0f20fad94467bb2c2572)とか[ここ](https://qiita.com/koukiwf/items/47b05e3df41928959ff9)の記事が使えそう

#Script
```c#:script
using UnityEditor;

 public void OpenFile()
    {
        //パスの取得
        var path = EditorUtility.OpenFilePanel("Open csv", "", "CSV");
        if (string.IsNullOrEmpty(path))
            return;
        Debug.Log(path);

        //読み込み
        var reader = new StreamReader(path);
        Debug.Log(reader);
    }
```

#詳細 //ここでダイアログボックスを出す

##１つのファイルを選択

```c#:script
        var path = EditorUtility.OpenFilePanel("Open csv", "", "CSV");
        var path = EditorUtility.OpenFilePanel(ダイアログボックスの名前, ディレクトリのデフォルト設定,読み込むファイルの拡張子 );
```
[EditorUtility.OpenFilePanel](https://docs.unity3d.com/ja/current/ScriptReference/EditorUtility.OpenFilePanel.html)


##複数種類のファイル拡張子を指定する場合

```c#:script
var path = EditorUtility.OpenFilePanelWithFilters("Open Music", "", {"音楽ファイル","mp3,ogg,wav"});
```
[EditorUtility.OpenFilePanelWithFilters](https://docs.unity3d.com/ja/current/ScriptReference/EditorUtility.OpenFilePanelWithFilters.html)

##フォルダーを選択する場合
```c#:script
var path = EditorUtility.OpenFolderPanel("Open Folder", "", "");
```
[EditorUtility.OpenFolderPanel](https://docs.unity3d.com/ja/current/ScriptReference/EditorUtility.OpenFolderPanel.html)
kintoneの標準機能 ソートとフィルターの動作の調査と個人的に思った起きやすい不具合を少し、ご紹介

### ■kintoneの標準機能である、ソートとフィルターの動作
ソートやフィルターは一覧画面の標準機能として使える。
実行すると、一覧画面用にjsファイルを設定している場合は再度、実行される。

### ■画面遷移せずに、ソートやフィルターを行うには？
標準機能で遷移せずにソートやフィルターを行う方法は標準では見つからなかったため、遷移せずに行いたいなら、JSで独自に実装するか、CybozuのCDNで提供されている「DataTables.js」を使用するのが有効だと思う。

### ■ソートやフィルターをした時に起きやすい不具合
一番起きやすい不具合は、一覧画面のヘッダー部にボタンなどを設置した時だと思う。
ヘッダーにボタンを設置する時、増殖バグを防ぐために、

      if (document.getElementById('ID') !== null) {
        return;
      }
とすると思う。しかしこれではボタンの増殖は防げるが、以降の処理を実行したい時に対応できなくなってしまう。そこで上記のコードを少し変更する。

      if (document.getElementById('id') !== null) {
          $('#id).remove();
      }
「return」を「$('#id).remove()」に置き換えて、一度、要素を削除し、もう一度同じ要素を追加することで、増殖バグを防ぐことが出来る。そして、以降の処理も実行可能になります。

この記事がお役に立ったら、LGBTを押していただけると次の記事の励みになります。

以上、マイスター・ギルドのフクロウでした。
cv2.VideoCaptureで設定可能なカメラパラメーターの一覧を取得して辞書型にする

困っていたこと：cv2.VideoCapture()を利用するとき、カメラ出力設定を手動で入力しなければならない。

```Python:例
WIDTH = 100
HEIGHT = 100
FPS = 10
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, WIDTH)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, HEIGHT)
cap.set(cv2.CAP_PROP_FPS, FPS)
ret, frame = cap.read() #うまくいったりいかなかったり
```
出力設定によっては最も値の近い解像度やFPSに自動設定されたり、またはcap.read()でエラーを吐いたりと様々。opencvからはusbカメラの対応する設定情報にアクセスできなかったので、v412-ctlコマンドから取得する。

```Python:一覧を出力するコマンド
import subprocess
import re
cmd = 'v4l2-ctl --device /dev/video0 --list-formats-ext'
proc = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
outs_bytes = proc.communicate()[0]
outs_str = outs_bytes.decode('utf-8')
outs_str_lists = outs_str.split('\n')

d = {}
i = 0
for line in outs_str_lists:
    if "Pixel Format" in line:
        pixelformat = line.split(":")[-1].strip()
    if "Size:" in line:
        resolution = line.split()[-1]
    if "Interval" in line:
        fps = re.findall("(?<=\().+?(?=\))",line)[0].split()[0]
        _d = {"format":pixelformat,"height":resolution.split("x")[1],"width":resolution.split("x")[0],"fps":fps}
        d[i] = _d
        i +=1
print d
```
```python:結果
{0: {'format': "'MJPG' (compressed)",
  'height': '2880',
  'width': '3840',
  'fps': '15.000'},
 1: {'format': "'MJPG' (compressed)",
  'height': '2880',
  'width': '3840',
  'fps': '10.000'},
 2: {'format': "'MJPG' (compressed)",
  'height': '2880',
  'width': '3840',
  'fps': '5.000'},
```

これで辞書型として対応する設定を取得することができたので、プログラム内部にカメラ情報を変数として利用することが可能になった。
メール受信に反応するシステムを作りたかったが、結局Wordpressに行き着いた

# あらまし

ブログ更新が毎回3日坊主になる。

これはひとつにはブログ管理画面にまで行くのがめんどくさいからだろうと考える。

そんなとき手元のSimplenoteアプリの「共有」にメールが含まれているのをみて、

メールを送信するだけで更新してくれるブログを作れば自分でも更新できるかもと思いついたのだった……。

# 1st チャレンジ　AWS使用

AWS の SimpleEmailService は、メールを受信できるだけでなく lambda のトリガーにできるようなので、

「これいいんじゃね」と思ってしばらく取り組んだ。

- SimpleEmailService がメール受信
- lambda 関数1がメール内容をS3に投げる
- S3 がファイルを作成
- lambda 関数2が リポジトリにファイルをアドし、コミット

ここまではできたのであとはGithubなりにプッシュするだけだったのだけど、

そこでつまずいた。

lambda 上で使ったGitクライアントは boto3 というもので、慣れているGitと使い勝手が違った上に外部にプッシュする方法がわからなかった。

この方向はやめることにした。

# 2nd チャレンジ Wordpress使用

そういえば Wordpress にメール更新機能があったなあと思い出し、

こちらで行くことに。

せっかくなので Gatsby で静的サイトにしてみたかった。

結論から言うと、こっちのほうが楽だった。

## Wordpress 立ち上げ

AWS の Lightsail の一番やすいやつで立ち上げてみた。

ちなみにパスワードはインスタンス内の `bitnami_application_password` というファイルに書いてある。

## メール受信

Postie というプラグインを使用した。

Gmail の場合、`IMAP-SSL`, `993`, `imap.gmail.com`, `Googleユーザー名`, `Googleパスワード` で行ける。

時々機嫌悪いことがあるので手動更新しよう（画面右上の`Proccess Email`）

## JAMstack Deployments

Netlify に更新を知らせるのに使用したプラグイン。

これのおかげで Netlify が反応し、Gatsby サイトをデプロイしてくれる。

## Gatsby

一度使ってみたかった。

React にあまり慣れていないのでテーマづくりに手こずったが慣れてる人なら楽だと思われる。

## Netlify

Github からのデプロイなどができる。

今回はGitに上げた Gatsby 側の更新と、

JAMstack Deployments が知らせてくれる Wordpress 側の更新両方に対応してデプロイするようにした。

## marked.js

本文のみ、マークダウンをHTMLにするのに使った。

初期状態では`<br />`や`<p>`などが入ってきていたので、ちまちま処理してカットした。

そののち `marked( content )` みたいな感じにして変換した。

# 完成


![スクリーンショット 2020-08-20 16.41.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92027/8d6f2346-a6ab-1258-c98f-31b280a1dd20.png)

[Selfishelf](https://selfishelf.netlify.app/)

更新できるかな……、できるといいな……。
java8でOpenCVを使えるようにする。（自分用）

コマンドラインでJavaを実行する原始人

大学の卒研でOpenCVを使わざるをえないので導入した
その道しるべ
今検索してもほとんどがPythonやC++での話でjavaの話が少ないので苦労した。

######参考サイト
基本的に以下のサイトに従順してやりました。基本的にこっちのほうが丁寧です。ただ、今の最新のVer（4.4.0）だとテストコードがうまく実行できないのでそこは書きます。
 [JavaでOpenCVを使う | JProgramer](https://jprogramer.com/java/2332 "JavaでOpenCVを使う | JProgramer")

####イソストール
ダウンロードした.exeファイルを実行、Cドライブに展開するのが良いとのことで私はOpenCVなるフォルダを作成しそこに展開。
![7-Zip self-extracting archive 2020_08_20 15_43_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664492/18bedb0d-f82e-4454-d864-931aefadea4c.png)

パスを通す

参考サイトではユーザ変数ですが私はシステム変数に追加しました。
「Path」を選択し、[編集]をクリック。一番下に
C:\OpenCV\opencv\build\java\x86
を追加、OpenCVをjavaで使うだけならこれだけの追加でいい、Pythonで使うとか、VisualStudioで利用するとかならこれだけじゃダメです。
私は一応VS2017が入っているんでそれ用にもパスを通してます。
![クラスパス.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664492/28dfa1ea-34c0-81e6-1d1d-005c7b6509c3.png)


最後の部分はjavaが32bitなら[x86]、64bitなら[x64]
私はマシンが64bitなので、64bitだと思ってテストコード（後述）を実行したら「俺は32bitだ！64bitのプログラムなんてムリ！」みたいなエラーがでたんで、必ずしもマシンとjavaのbitが同じとは限らないみたいです。
####テストコード

参考サイトのテストコードはVer.4.4.0ではエラーが出ます。
具体的には画像の出力するクラスが``highgui``ではなく、``imgcodecs``に移っています。

```java:Test.java
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
 
public class Test{
    public static void main(String[] args){
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat redImg=new Mat(100,200,CvType.CV_8UC3,new Scalar(0,0,255));
        Imgcodecs.imwrite("test.jpg",redImg);
    }
}
```

コンパイルコマンドは以下↓

```
javac -classpath “C:\保存したフォルダ\opencv\build\java\opencv-バージョン.jar” Test.java
```


これを

```
java -cp .;C:\保存したフォルダ\opencv\build\java\opencv-バージョン.jar Test
```

で実行すると同じフォルダに真っ赤なJPG画像が出力（保存）されました。

クラスパスを設定すると

javac Test.java
java Test

で実行できます。詳しくは参考サイトを見てくだちい。
【個人アプリ開発メモ】undefined method `id' for nil:NilClassの解決法

ログアウトしようとしたらエラーが出てしまった。

## エラー文

```
undefined method `id' for nil:NilClass
```

```ruby:posts_controller.rb
def index
  @posts = Post.all.includes(:user).order("created_at DESC").page(params[:page]).per(5)
  @post = Post.new

  #エラーが出たのはこの部分↓↓↓
  @calorie_sum = Post.where(user_id: current_user.id, created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day).sum(:calorie)

  gon.today_sum = @calorie_sum
  @standard = Standard.find_by(user_id: current_user.id)
  @calorie_standard = @standard.calorie
  gon.standard = @calorie_standard
  if @calorie_sum >= @calorie_standard
    @difference = @calorie_sum - @calorie_standard
  else
    @difference = @calorie_standard - @calorie_sum
  end
end
```

## なぜこのエラーが生じたのか？

```ruby:posts_controller.rb
@calorie_sum = Post.where(user_id: current_user.id, created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day).sum(:calorie)
```
エラーが出たこのコードはどういう意味かというと、

Postモデル（投稿データが入ってる）から、
今日1日のcurrent_userの投稿を検索して抽出して、calorieカラムの数値を合計した結果を`calorie_sum`というインスタンス変数に代入してる。

なんでエラーになるかというと、
ログアウトすると`user_id: current_user.id`のidのところがnilになってしまうから。

## 解決するにはどうすればいいのか？
current_user.idがnilでもエラーにならないようにするためには、
posts_controller.rbを条件分岐で書けばいい気がする。

こんな感じでどうだろうか？

```ruby:posts_controller.rb
  def index
    @posts = Post.all.includes(:user).order("created_at DESC").page(params[:page]).per(5)
    @post = Post.new
    
    # サインインしてる時だけ今日の摂取カロリーを表示するグラフを作るためのデータを取得する下記の関数が動く
    if user_signed_in?
      @calorie_sum = Post.where(user_id: current_user.id, created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day).sum(:calorie)
      gon.today_sum = @calorie_sum
      @standard = Standard.find_by(user_id: current_user.id)
      @calorie_standard = @standard.calorie
      gon.standard = @calorie_standard
      if @calorie_sum >= @calorie_standard
        @difference = @calorie_sum - @calorie_standard
      else
        @difference = @calorie_standard - @calorie_sum
      end
    else
      # サインインしてない時は何も動かない
    end
  end
```

これにあとviewのグラフの部分を`- if user_signed_in?`で条件分岐して、サインインしてない時はグラフが出てこないようにしたら、無事解決しました。
Django: テンプレートのコメント内でおこるNoReverseMatch 

Djangoのテンプレート内においてコメントを使用している際、

```post_detail.html
<!--
{% if object.author == user %}
<a　href="{% url 'blog:post-update' object.id%}">Update</a>
<a href="{% url 'blog:post-delete' object.id %}">Delte</a>
{% endif %}
-->
```

のようにコメント内で記述したurl内に'blog:url名'のようにネームスペース名に言及した行があり、そのネームスペースが存在しない/一致しない場合にNoReverseMatchを起こす。

コメントで括った中にネームスペースが存在していてもエラーを起こすというのは予想外だったためハマりました。
typescript-eslint/typescript-estree で未サポートのバージョンの TypeScript を使ったときに表示される警告を消す

https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/typescript-estree

公式のドキュメントにもあったけど見落としていたのでメモ。

typescript-estree は未サポートの TypeScript を使ってパースをしようとすると警告を吐くけど、出ないでほしいときがたまにある。(See https://github.com/prettier/prettier/pull/8982)

`parse` のオプションとして `loggerFn` に `false` を渡すとでなくなる。

```ts
import { parse } from "@typescript-eslint/typescript-estree";

parse(code, { loggerFn: false });
```
[Python]標準入力ファイルにコメントを付す

２．標準入力ファイルにコメントを付すためのモヂュール
・前回、標準入力にテキストファイルを使う方法をアップしました。
・このテキストファイルに計算条件を記述する際に、その値が何かが記されていないと不便です。
・そこで、ルールを決めてコメントを記載できるような入力モヂュールを作成しました。
・ルールは、Pythonコードに合わせて、'  # '以降をコメントと判断することにしました。

    def input_aif():  # '  # 'の前までを有効データとする
        s = input()
        start = s.find('  # ')  # '  # '最初の位置を探す
        if start > 0: s = s[:start]  # その前までをスライスで抽出
        s = s.rstrip()  # 右側の空白を削除（タブ、改行も削除されるらしい）
        return s

このような使い方はあまりされないのかもしれませんが、pythonのコーディングルールに合わせたので、使いやすいと思います。
監修、よろしくお願いします。
CakePHPで繰り返し可能、かつ一発でmigrate,seed,bake modelを実行するシェルスクリプト

# やりたいこと
* 初期開発時にmigrationファイルを増やしたくないので、１テーブル１ファイルで運用したい。
* そうすると都度`migrations rollback`が必要になる。
* 都度`migrations rollback`して`migrate`して、、というのを一つずつコマンドで打ちたくない。
ということで全部一括でできるシェルを作っておく。

# 環境(今回の作業に関連ないものも記載)
* MacBookPro(macOSCatalina10.15.5)
* PHPStorm2020.2
* docker desktop2.2.0.3
* cakephp4.1.2

# 実装

```app/migrate.sh
bin/cake migrations rollback -d 20200101
bin/cake migrations migrate
bin/cake migrations seed
bin/cake bake baked_model all -f
```
rollbackはマニュアルに書いていないが、-dで日時指定ができる。（`migrations rollback -h`で他のオプションも確認可能）
十分に古い日時を指定すれば一発で初期状態に戻せる。

seedは全実行にしているが` --seed LocalSeed`とかで指定しても良い。
[参考](https://qiita.com/learn_tech1/items/8e19c58d4daefcf5ccf3#seeds)

baked_modelはbakeを繰り返し実行できるようにするための独自のコマンド。
[参考](https://qiita.com/learn_tech1/items/9556eea585dcac6eab6d)

# 実行方法
```
bash ./migrate.sh
```

# その他
開発環境が少しずつ整ってきていて気分がいいです。
[Python]標準入力をキーボードからテキストファイルに変更

Qiita初投稿で書き方も良くわかりませんが、pythonの便利な使い方を少しずつメモに残していきます。
１．標準入力をキーボードでなくテキストファイルに変更する方法
・同種のデータを条件を変えながら繰り返し計算する場合、キーボードから毎度入力するのは大変。そこで条件をテキストファイルにして入力する方法を探しました。
・ネット情報も踏まえていくつか試みて、もっともシンプルな次の方法にたどり着きました。

    import sys  # 標準入力をファイルに切り替えるときにsys.stdinが必要となるため
    fn = input()  # テキストファイル名を入力／キーボードのままなら'--'
    if not fn == '--':  # '--'がキーボード
        sys.stdin = open(fn)  # fnをstdinとすることで以降inputがファイルfnから実行される
    ...  # 処理を記述
    sys.stdin.close()  # 標準入力ファイルを閉じる

初心者です。監修の方、よろしくお願いします。
【個人アプリ開発メモ】ArgumentError (wrong number of arguments (given 0, expected 2)):の解決

## 直面している問題
投稿しようとしたらできない。
なぜ？

ターミナルに以下のエラー文が表示された。

## エラー文
```:ターミナル
ArgumentError (wrong number of arguments (given 0, expected 2)):
app/controllers/posts_controller.rb:21:in `create'
```
argumentとは引数のことらしい。
2つの引数がなければいけないのに、それが0になってるからダメだという。

引数が2つ必要？何のことだろう？

```ruby:posts_controller.rb
def create
  @post = Post.new(post_params) ← ここで止まってしまってる
  if @post.save
  redirect_back(fallback_location: root_path) # なぜredirect_to root_pathじゃダメなのかわかってない
else
  @posts = Post.includes(:user)
  flash.now[:alert] = '必須項目をしてください。' # フラッシュメッセージが出るか確認する
    redirect_back(fallback_location: root_path)
  end
end

private
  def post_params
    params.require(:post).permit(:food, :calorie, :protein, :fat, :carbo, :text, :image).merge(user_id: current_user.id)
  end
```
## 試してみたこと
binding.pryでpost_paramsの中身を確認してみよう。

```ruby
[1] pry(#<PostsController>)> post_params
=> <ActionController::Parameters {"food"=>"うどん", "calorie"=>"10", "protein"=>"10", "fat"=>"10", "carbo"=>"10", "text"=>"うどんを食べました", "image"=>#<ActionDispatch::Http::UploadedFile:0x00007fc7e7b4eae0 @tempfile=#<Tempfile:/var/folders/sy/26p55v5j47s2zjd8h7vr8f6h0000gn/T/RackMultipart20200820-34304-1e1sjww.png>, @original_filename="image4.png", @content_type="image/png", @headers="Content-Disposition: form-data; name=\"post[image]\"; filename=\"image4.png\"\r\nContent-Type: image/png\r\n">, "user_id"=>17} permitted: true>
```
ここが原因ではないようだ。

https://teratail.com/questions/164134
によれば、

```:ターミナル
ArgumentError (wrong number of arguments (given 0, expected 2)):
```
これは呼び出し側の引数の数 ＝ 0
メソッド側の引数の数 = 2
という意味らしい。

呼び出し側の引数の数と、メソッド側と引数の数はそれぞれどこで設定してるのだろうか？


### 試したこと
画像を選択せずに、画像以外を投稿してみた。
その結果、これは問題なく投稿できた。
この結果からわかったのは、やはり問題は画像関連だということ。

画像を選択して、画像も投稿しようとするとエラーが生じる。
画像を投稿しようとすると、メソッド側の引数が2になる？

## 解決した。原因は「え？そこ？」という感じ
```ruby:image_uploader.rb
#[300, 200][100, 100]という感じで2つあるとダメ
process resize_to_fit: [300, 200][100, 100]

#1つに戻したら解決した
process resize_to_fit: [300, 200]
```
前に投稿画像サイズの設定で、2通りのサイズを設定したいと思って上記のように設定していたが、これが邪魔だったみたい。
https://qiita.com/naota7118/items/33943b8887a4990645a9

余計なことしなければよかった。
RustをCodeLLDBでデバッグするときにデバッグサイドバーで文字列が表示されないときの解決方法

# 現象
VSCodeの拡張機能[CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)でRustのコードをデバッグ実行したときに、
デバッグサイドバーで文字列が表示されない。スクショの左上参照。
![スクリーンショット 2020-08-20 14.48.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/ee58b818-dc43-6183-9986-fdd8dbabd421.png)


OSはmacOS Catalina 10.15.5です。
デバッグコンソールを見ると

```
Could not initialize Python interpreter - some features will be unavailable (e.g. debug visualizers).
```

というエラーが吐かれてます。

# 解決策

ワークスペースの`.vscode/settings.json`に

```json
   "lldb.libpython": "/usr/local/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib"
```

を追加します。
環境によって`libpython`の場所は違う可能性がありますので、そのときは適宜読み替えてください。


![スクリーンショット 2020-08-20 14.48.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/53224646-b6d2-e54f-b2d4-44a89f236747.png)

これで開発効率が爆上がりしました👍
nuxt vue-composition-api tsx でemitでケバブケースにするとハマる

# tsxでのemitについての注意事項
ケバブケースでemitを書いた場合、親componentで受け取ることができなくなるので注意
`emit('child-clicked')`

上記の場合では動作せず
`<child-component onChildClicked={exampleFunction}/>`

キャメルケースなどで対応すると動作する
`emit('childClicked')`


## 環境
"@vue/composition-api": "^1.0.0-beta.9"
"vue-tsx-support": "^2.3.3"
"@vue/babel-sugar-v-model": "^1.1.2"
"babel-preset-vca-jsx": "^0.3.6"

```nuxt.config.ts
~~
  build: {
    babel: {
      plugins: ['module:@vue/babel-sugar-v-model'],
      presets: ['@nuxt/babel-preset-app', 'vca-jsx'],
    },
  }
~~

```

## sample

```child.tsx
import { defineComponent } from '@vue/composition-api';
export default defineComponent({
  setup: (_, {emit}) => {
    const onClick = ()=>{
      emit('fooBar', 'Some messages');
      
      // ! emit('foo-bar', 'Some messages') だと動作せずハマる
    }
    return () => (
      <div onClick={onClick} >Child Component!</div>
    );
  },
});
```

``` parent.tsx
import { defineComponent } from '@vue/composition-api';
import ChildComponent from '@/components/example/emit';
export default defineComponent({
  setup: () => {
    const handleEmit = (message: string )=>{
      console.log(message);
    }
    return () => (
      <ChildComponent onFooBar={handleEmit} />
    );
  },

```
Laravelのpaginationで取得したcollectionデータの更新方法

Laravelのpaginationで取得したデータは特殊なcollectionクラスであるため、
新しいcollectionクラスを返すfilterやmapのような操作では要素が更新できません。

```php5
$articles->getCollection()->transform(
            function ($article, $key) {
                 //操作
               return $article;
            }
        );
```
のようにgetCollectionを使ってからtransformで変形することが必要です。

ここで、注意しなくてはいけないのは、articleの下にさらにcollectionがネストしている場合[1]も、
新しいcollectionクラスを返す操作ではそのcollectionクラスが更新できないという点です。

その場合はgetCollectionなしのtransformで更新できますが、
要素を削除する場合はunset等の新しいcollectionを返さないで削除できる手段を用いる必要があります。


ただこれネストしているのでもっといい方法あるかもしれないけど


```php5
//articleの下にhashtagがネストしている
$articles->getCollection()->transform(
            function ($article, $key) {
                $article["tags"]->transform(function($tag,$key){
                        //タグ更新の場合。ちなみにここで何もreturnしなかった場合、nullが代入される。
                        return $tag;
                }

                //要素削除の場合
                foreach($article["tags"] as $key=>$tag){
                    //条件を入れる。ここは例えばタグの名前がtestの場合
                    if(($tag["name"]==='test')){
                        //条件に合致したものをunset
                        unset($article["hashtags"][$key]);
                    }
                }

                return $article;
            }
        );

```

[1]元データがModelでwith等を使ってクエリを作っている場合等。
【Windows】忘備録：WindowsUpdateをオフラインで適用したい

# 主旨
WindowsクライアントPCやWindows Serverなどの構築過程において、企業によってはLANを挿し、
インターネットに接続してからUpdateをすることが結構多くなってきた……ように見える。

自動でWindowsUpdateを適用した場合、サーバごとに適用内容が変わる場合がある。
バージョン番号は一緒だけど適用している内容が違うなんてことがざらである。

正直な話、あまりよくは思ってないので、極力ローカルで適用したい派。
こういうところが品質のレベルを統一することだと思っている。

# 1.前段

#### wsusscn2.cabをダウンロード

下記のリンクからCABファイルをDLしてくる。

https://catalog.s.download.windowsupdate.com/microsoftupdate/v6/wsusscan/wsusscn2.cab

このファイルで確認できるKB番号は原則としてその時点で公開されている更新ファイル一覧になる。
このファイルが更新されるのは毎月第二週水曜日（米国時間だと火曜日）になるのでそのタイミングでDLする。
※基本的にWindowsUpdateのパッチ公開はMicrosoft本社のある米国時間が基準になる。
　

# 2.VBスクリプトの作成
下記のプログラムソースコピペし、VBスクリプトを作成する。
プログラムソースはMicrosoftのリンクにも原本が載っている

WUA を使用したオフライン更新プログラムのスキャン
https://learn.microsoft.com/ja-jp/windows/win32/wua_sdk/using-wua-to-scan-for-updates-offline


4行目のパスの部分はwsusscn2.cabファイルの置いた場所によって適宜変更する。

```vbs:Check_UpdateList.vbs

Set UpdateSession = CreateObject("Microsoft.Update.Session")
Set UpdateServiceManager = CreateObject("Microsoft.Update.ServiceManager")
Set UpdateService = UpdateServiceManager.AddScanPackageService("Offline Sync Service", "c:\wsusscn2.cab")
Set UpdateSearcher = UpdateSession.CreateUpdateSearcher()

WScript.Echo "Searching for updates..." & vbCRLF

UpdateSearcher.ServerSelection = 3 ' ssOthers

UpdateSearcher.ServiceID = UpdateService.ServiceID

Set SearchResult = UpdateSearcher.Search("IsInstalled=0")

Set Updates = SearchResult.Updates

If searchResult.Updates.Count = 0 Then
    WScript.Echo "There are no applicable updates."
    WScript.Quit
End If

WScript.Echo "List of applicable items on the machine when using wssuscan.cab:" & vbCRLF

For I = 0 to searchResult.Updates.Count-1
    Set update = searchResult.Updates.Item(I)
    WScript.Echo I + 1 & "> " & update.Title
Next

WScript.Quit

```

# 3.当該ファイルを対象コンピュータへ置く

# 4.コマンドの実行
```bat:Command
cscript Check_UpdateList.vbs
```

Powershellではエラーになる。
PSを開く　→　cmd実行 すること

※VBSファイルをダブルクリックしても出るけど好きじゃないのでコマンドでやってます。

# 5.KBファイルの検索とダウンロード
出力されたKB番号を以下Windows Update カタログにて検索し、ダウンロードする

https://www.catalog.update.microsoft.com/home.aspx

あとは実行するればおｋ

# 6.エラーで結果が出ない！
サービス(Serveces.msc)起動させ、WindowsUpdateサービスを再起動させる。
スクリプトを実行させる。

※Windows Server2019あたりからWindowsUpdateサービスを切っても自動で立ち上がるようになった。
　Microsoftってそういうところが嫌い。
【Rails】Enumを使う

## どんな時に使う?
カラム**status**の値が
`0`だったら`未処理`
`1`だったら`進行中`
`2`だったら`処理済み`
みたいな時に、いい感じに書くことができます。

## 定義
```rb:migrationファイル
def change
  add_column :orders, :status, :integer, default: 0 # デフォルト値は0に設定する
end
```
```app/models/order.rb
class Order < ApplicationRecord
  enum status: { waiting: 0, working: 1, completed: 2 }
end
```

## できること
### インスタンスを作成
```rb
order = Order.new(
          item: 'ボールペン',
          price: 150,
          status: 'working' # 今まで「1」と数値でセットしていた部分を文字列でセットできる。DBには「1」が保存される
        )
```

### インスタンスの中身を確認
```rb
pry(main)> order.status
=> "working"
pry(main)> order.working?
=> true 
pry(main)> order.completed?
=> false
```

### インスタンスを更新
```rb
pry(main)> order.status
=> "working"
pry(main)> order.completed!
=> "completed"
pry(main)> order.status
=> "completed"
```

### DBを検索
```rb
pry(main)> completed_orders = Order.completed
=> SELECT `orders`.* FROM `orders` WHERE `orders`.`status` = 2 LIMIT 11
```

## 複数カラムで同じ名前を使いたい場合
```rb:こういう場合
class Order < ApplicationRecord
  enum hoge_status: { waiting: 0, working: 1, completed: 2 }
  enum fuga_status: { waiting: 0, working: 1, completed: 2 }
end
```
`Order.waiting?`としても、`hoge_status`と`fuga_status`のプログラムはどちらを見れば良いかわかりません。
こういった場合、`_prefix: true`を使って解決します。

```rb:prefixで解決
class Order < ApplicationRecord
  enum hoge_status: { waiting: 0, working: 1, completed: 2 }, _prefix: true
  enum fuga_status: { waiting: 0, working: 1, completed: 2 }, _prefix: true
end
```
```rb
pry(main)> Order.hoge_status_completed?
=> SELECT `orders`.* FROM `orders` WHERE `orders`.`hoge_status` = 2 LIMIT 11
`
pry(main)> Order.fuga_status_completed?
=> SELECT `orders`.* FROM `orders` WHERE `orders`.`fuga_status` = 2 LIMIT 11
```

## 参考
- [【Rails】Enumってどんな子？使えるの？ - Qiita](https://qiita.com/ozackiee/items/17b91e26fad58e147f2e)
HerokuへデプロイしたアプリのDBを操作する方法！ CLEARDB_DATABASE Sequel_Pro

#環境
rails 6.0.3
Mysql 0.4.4
アプリケーションはHerokuへデプロイ済

#概要
Herokuへデプロイは出来たものの保存されたデータって見れないものだろうか
テストのために色々データ値を変更したり追加したりしたい

#方法
### 1.Sequel Proをダウンロード
Mysqlデータベースを難しいコマンド等必要なくGUIで操作できるアプリ
[Sequel Proダウンロードリンク](https://sequelpro.com/download)


### 2.ターミナルでherokuの設定を確認
デプロイしたアプリケーションのディレクトリ下で（ターミナル）`heroku config`を実行
下記のような設定が出力される（実際には///の部分はもっと長い）

```
CLEARDB_DATABASE_URL:     mysql://
DATABASE_URL:             mysql2://
DB_HOSTNAME:              ///
DB_NAME:                  ///
DB_PASSWORD:              ///
DB_PORT:                  ///
DB_USERNAME:              ///
LANG:                     ///
RACK_ENV:                 ///
RAILS_ENV:                ///
RAILS_LOG_TO_STDOUT:      ///
RAILS_SERVE_STATIC_FILES: ///
SECRET_KEY_BASE:          ///
```


### 3.Sequel Proにデータベース情報を入力
![sequrepro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659708/bb84217f-fa6e-a014-37ed-422a90952c51.png)

一番上のタブを「標準」に設定して
2.でターミナルに出力した`CLEARDB_DATABASE_URL:`の情報をもとにSequel Proに入力
※ポート名は空白でOK

```
CLEARDB_DATABASE_URL:  mysql://ユーザー名:パスワード@ホスト/データベース?reconnect=true
```

次に「接続」と青いボタンを押したいところだがちょっとまった！
次回からもデータベースに接続を行うなら`お気に入りに追加`をしておこう

そして最後に「接続をテスト」をクリックして接続テストに成功すれば完了

#最後に
Sequel Proの使い方は各々で調べてみて下さい。
私みたいなSQLコマンドひとつもわからない初心者でも簡単にDB操作が出来ちゃいます。かなり便利。
vue composition-api(1.0.0-beta.9) で css module 利用

`useCSSModule` を利用

```vue

<template>
  <div :class="style.title" @click="clickHandler()">{{ title }}</div>
</template>

<script lang="ts">
import { defineComponent, useCSSModule } from '@vue/composition-api';
export default defineComponent({
  props: {
    title: {
      type: String,
      required: true,
    },
  },
  setup: (_, { emit }) => {
    const clickHandler = () => {
      emit('clicked');
    };
    return { clickHandler, style: useCSSModule() };
  },
});
</script>

<style module lang="scss">
.title {
  color: #ffffff;
}
</style>
```

## 参考
https://github.com/vuejs/composition-api/pull/420#issuecomment-653874173
Power AutomateにLeft, Right, Mid はないので全部 substring

タイトルの通りですが、Power Appsから使い始めてPower Automateに進むと割と躓くポイントです。 (N番煎じ)

#Power Appsの場合
Excelにも用意されていて、Power Appsで文字列を操作するときによく使う、[Left, Right, Mid関数](https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-left-mid-right) ですが、
まず前提として**文字列の1文字目は1番目**です。 

これを意識するのは特にMid関数を利用する場合です。

```
Mid("あいうえお", 2, 3)
```

このように書いた場合、返ってくる結果は ```いうえ```です。Mid関数の2つ目の入力が何文字目からスタートするかを表していて、上の例では```あいうえお```の2番目は Power Appsでは```い```です。
2文字目の```い```からスタートして3文字を要求しているので、結果が```いうえ```になります。

Left, Right, Midの利用例は下図をご覧下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/ad895bdf-fc29-f7e5-da01-37eb0712497b.png)

繰り返しですが、Power Appsでは・・・

1. Left, Right, Mid関数が用意されている
2. 文字の順番は1番から始まる

という点が重要です。

もちろん、Left, Right は Mid関数を使って以下のように書き直せる点も覚えておくと便利です。

```
Left(BaseText, 3) ==> Mid(BaseText, 1, 3)

Right(BaseText, 3) ==> Mid(BaseText, 1+Len(BaseText)-3, 3)
```
右側の Mid関数に入っている```1```は、いずれも文字数の数え方が1からであることを反映しています。

#Power Automate の場合

Power AutomateにはLeft, Right, Mid関数はありませんが、かわりに [substring関数](https://docs.microsoft.com/en-us/azure/logic-apps/workflow-definition-language-functions-reference#substring) が用意されています。

Power Appsの場合と大きく異なるのは、前提が**文字列の1文字目は0番目**と数えること です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/a21fc435-dffb-a3bf-65b8-99d2080233fe.png)

このことに由来して、関数の中の数字も変更をうけます。
例えば Left関数をPower Automateで書き直すとすると、substringを使って以下のように書けます。

```
Left(BaseText, 3) ==> substring(BaseText, 0, 3)

Right(BaseText, 3) ==> substring(BaseText, sub(length(BaseText),3), 3)
```

Right関数の書き換えで出てくる```sub(length(BaseText),3)```ですがこれはちょうど```Len(BaseText)-3```と同じ操作です。
( Power Automateでは四則演算も関数なので少し長くなる )

このように、Power Apps で使われる文字列操作関数と Power Automate で使われる文字列操作関数は

1. そもそも使う関数が異なる (Power Appsでいえば全部Mid関数で書くイメージ)
2. 文字列の数え方は・・・Power Apps : 1 , Power Automate : 0 からスタート

という大きく2つの違いに注意する必要があります。


# おわり
Power Appsが最近よく使われるようになってきて、そこからPower Automateを使い始める人も少なくないのではと思います。
2つのサービスは非常に親和性が高いのですが、今回紹介したような注意点 - 主には順番の数えかたに由来 - もありますので、うまく頭を切り替えながら活用していきましょう！

**Power Appsは1始まり、Power Automateは0始まり！**
PowerShellでファイルの一覧をCSVで取得する方法

諸般の事情からファイルの一覧を取得して分析をしたかったのだけれど、標題の件のやり方がなかなか解らなかったのでメモっておきます。

## はじめに
メインはLinuxなどのUNIX系OSな人です。よってPowerShellは本当によくわかっていません。なので、本記事の読者は似たような人を想定しています！

## 本編
### やりかた
```powershell:dir-csv.ps1
$target = "c:\path\to\target\dir"
$outfile = "c:\path\to\result.csv"

Get-ChildItem -Recurse $target | Where-Object { ! $_.PSIsContainer } | Select-Object FullName, Length, CreationTimeUtc, LastWriteTimeUtc, LastAccessTimeUtc | Export-CSV -path $outfile -Encoding UTF8 -NoTypeInformation
```

### （若干の）解説
#### まず前提として
従来のDOSやLinuxコマンドとは異なり、PowerShellの場合、大ざっぱにいうと、コマンドの実行結果は何らかのオブジェクトのインスタンスが返却されます。なので、パイプで多段化する際に、 `grep` のように絞り込んだり `awk` のように変形させるだけではなくて、**情報を増やす事も可能**だったりします。  
そして、コマンドの表示結果のカスタマイズ（e.g. 表示項目を増やしたり形式を変えたり）というのは `--help` 相当の `Get-Help` を使っても出てきませんので、**各コマンドがどんなインスタンスを返却するのかを考えつつ、絞り込んだり表示項目や書式をカスタマイズする必要**があります。

#### Get-ChildItem
Get-Helpだと殆どオプションが出てきませんが、 `Get-Help Get-ChildItem -Online` だと、上記で利用した `-Recurse` 等も出てきます。今回のサンプルだと、再帰的に見たかったので `-Recurse` のみ入れました。

#### Where-Object
今回はディレクトリ不要でファイルだけ取りたかったので、フォルダでないものになるように絞り込みをしています。こちらもローカルで見れるヘルプは大した事が載っていないので、 `-Online` をつけてヘルプを見ましょう！

#### Select-Object
ここがDOSやLinuxのshellと特に異なっている部分です。コマンドはインスタンスを返しているため、何も指定しないと既定の出力（全部ではなくてメジャー項目を適当なフォーマットで出力する）となります。必要項目をちゃんと指定してあげると、**指定した項目は漏れなく表示されます。**

#### Export-CSV
こちらは直感的なのでまずまずわかりやすいと思いますが、 `-NoTypeInformation` をしないと1行目にゴミが入ります。これは入れましょう。また、エンコーディングを指定しないとASCII扱いとなり、日本語等々思い切り文字化けになるので、こちらも基本指定しましょう。

#### その他注意点
260文字を超えるPATHがあるとエラーになります。この場合はWindows10やWindows Server 2016以降であれば、 `LongPathsEnabled` を有効にすると制限を解除できるようです。それ以前の場合はどうにもなりませんので、サードパーティのツール等々を使用しましょう。

## 個人的な感想
LinuxのShellとはだいぶ異なるので、正直取っつき辛いなと思っていたのですが、実は結構高機能（今回は紹介していませんが、.Netのちょっとした処理もすぐに実行できる）なので、ちょっとしたことなら意外と出来たりします。パス問題のように、どうにもならないケースも多々あるのでそれが難しいところですが…。
SNS認証　facebookだけ通らなかった原因

# 前提
- 今回、sns認証(google, facebook)を実装していました。
- そこで、googleは既存のusersテーブルと紐づくのに、facebookだけ認証が通らないエラーが発生しましたので、原因を記録します。(そのため、sns認証の細かい実装方法に関しては割愛します。)
- 原因は判明しましたが、根本的な解決には至っていませんので、あくまで原因を探す参考程度にご覧ください。

# 実行環境
#### rails _6.0.0_
#### mysql 5.6.47

# エラーの内容
　今回、snsの認証とともに、userの情報を紐付けて保存する仕様にしていました。
ところがログインしようとすると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663896/568aacac-5f08-e7a8-14dd-b1b7465963d6.png)
おかしい、、、
Googleでは確かにログインができるのに、Facebookでは新規登録画面へ飛ばされてしまいました。

# 原因
原因は、user.rbにありました。apiから送られてくるデータの検索方法がまずかったようです。
【user.rb】

```ruby
  def self.from_omniauth(auth)
    sns = SnsCredential.where(provider: auth.provider, uid: auth.uid).first_or_create
    # sns認証したことがあればアソシエーションで取得
    # 無ければemailでユーザー検索して取得orビルド(保存はしない)
    user = sns.user || User.where(email: auth.info.email).first_or_initialize(
      nickname: auth.info.name,
        email: auth.info.email
    )
    # userが登録済みの場合はそのままログインの処理へ行くので、ここでsnsのuser_idを更新しておく
    if user.persisted?
      sns.user = user
      sns.save
    end
    { user: user, sns: sns }
  end
```

　この記述の中だと、auth(apiから送られてくるユーザーデータ)の中から、:emailを参照してしまいます。
　しかし、私自信、facebookのアカウントにemailを登録していなかったため、この検索に引っかからず、snsの情報をDBに保存していないよねと判断され、弾かれていたようです。
　その後、Facebookのアカウント設定でemailを登録したところ、無事にログインできるようになりました。

# 今後の課題
 このままだと、emailをもたないfacebookユーザーは原因がわからないまま永遠にログインできない状態になってしまいます。ですので、データ参照の仕様を工夫する必要がありそうです、、、
javaにelse-ifは存在しないらしい

# 検証すること
私はある日、`else if`について、javaでは

```java
if (flag) {
    System.out.println("Hi!");
}
```
を波括弧を省略して（三項演算子を使ったほうがいいですが、ここでは考えないこととします）

```java
if (flag)
    System.out.println("Hello!");
```
とすることができる。もしかしたら、else-ifは、

```java
if (flag) {
    System.out.println("Hello!");
} else {
    if (flag2) {
        System.out.println("Hello World");
    } else {
        System.out.println("hi");
    }
}
```
の波括弧を省略したものではないかと考えました。
# 判定方法
波括弧を省略したものとそうでないもののバイトコード（classファイル）が合致するかどうかを調べます。
# 結果
fcコマンドで比較したところ同じらしい。
# 参考
https://arakik10.hatenadiary.org/entry/20161206/p1
https://www.k-tanaka.net/cmd/fc.php