OmniAICreator/Qiita-1.07M huggingface dataset:
【EC2】Appachのディレクトリ ＆ EC2ログイン時のルートディレクトリ構造

#Appachのディレクトリ ＆ EC2ログイン時のルートディレクトリ構造


EC2上に作成したappachのディレクトリ構造の理解用のメモ。

##EC2のルートディレクトリ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/5829a083-4358-ccf2-171e-24fe237d136a.png)


<br>
##Appach関連の主要フォルダ

- var: ドキュメントルートやログファイルがある
- usr： ライブラリやhttpd本体のプログラムがある
- etc： 設定ファイルがある


##varフォルダ配下
・wwwフォルダ
公開するファイルを格納するフォルダ

・run
Appachのプロセスファイルが格納されている

・log
logファイルが格納されている

 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/1740b304-36fa-60d5-261b-8a534a6fe69f.png)




##wwwフォルダ配下(var/www/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/0cfe2ca0-b6a5-bfcb-8820-9a8ba367ac80.png)

**・htmlフォルダ**
　└ /var/www/html配下
　└ 公開するページを格納
　└ `ドキュメントルート`と呼ぶ。


▼使用例
公開用のファイルを保存する場合はルートディレクトリに移動してから、配下にフォルダやファイルを保存。

```
cd /var/www/html
```


<br>
##usrフォルダ配下

フォルダlib64配下にインストールしたライブラリやhttpdのモジュールが格納されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/c32d27b6-547d-729f-d15e-6a2e90c65cc6.png)




###lib64配下(usr/lib64/)

python、php、mariadb,　httpdが格納されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/5c58facd-1aa1-03ff-5cd1-634661296ba9.png)




<br>
##etc/httpd/配下
Appach設定用のファイルが入っている。

・conf：基本設定用のファイルがある
・conf.d: 拡張設定用のファイルがある
・modules: /usr/lib64/httpd/modules/フォルダへのショートカット
・logs: /var/httpd/logs/フォルダへのショートカット（アクセス権なし）
・run: /var/run/フォルダへのショートカット（アクセス権なし）
*正式にはシンボリックリンク

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/a38b5e19-c9e1-68bc-54e0-ea7e9b8cb673.png)



###①conf配下(etc/httpd/conf/)
`httpd.conf`
・Appach基本設定用のファイル。
・WEB上からファイル一覧を見れなくする設定などができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/af77ed9d-d46b-cae6-55d3-63d1d8d5cf83.png)






###②conf.d配下
Appach拡張機能用のファイルがある。
・httpd.confファイルが読み込まれた後、途中で読み込まれるファイル群。

`welcom.conf`
・ルートURLにアクセスしたときに表示するファイルを設定できる。
・Appachのデフォルトは403エラーページが設定されている。

```conf:
<LocationMatch "^/+$">
    Options -Indexes
    ErrorDocument 403 /.noindex.html
</LocationMatch>
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/b885454f-61c3-32c8-c9a2-160eac81059a.png)




<br>
##EC2サーバーログイン後のルートフォルダ
下記のようにログインした状態でアクセスしているフォルダの場所は、`/home/ユーザー名/`のフォルダ。

```
[ユーザー名@ip- ~]$ ls
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/2d9df0fb-ef0c-ed43-5d62-cc0e6e9972df.png)
この中にユーザー名のフォルダがある。
arduino-cliを使ってSPRESENSE向けのビルド環境を構築してみた(Windows編)

[こちら](https://qiita.com/baggio/items/94b1ab74e63ff4edee63) に投稿した`arduino-cli` ツールを使って SPRESENSE 用のビルドスクリプト(Windows バッチファイル) を作成してみました。

こちらからダウンロード可能です。
https://github.com/baggio63446333/spresense-cli/releases
https://github.com/baggio63446333/spresense-cli/archive/v0.1.zip

`arduino-cli`を使うためには、Arduino IDEによるビルド環境を構築済みであることが前提です。
IDE ビルド環境の構築は公式サイト [Spresense Arduino スタートガイド](https://developer.sony.com/develop/spresense/docs/arduino_set_up_ja.html) が参考になると思います。

# spresense-cli ツール for Windows

[Arduinoマルチコア環境](https://developer.sony.com/develop/spresense/docs/arduino_tutorials_ja.html#_tutorial_multicore) を使うケースを考慮して各コアごとのバッチファイルを用意しました。

|Filename|Description|
|--------|-----------|
|spresense-cli-main.bat| MainCore用バッチファイル |
|spresense-cli-sub1.bat| SubCore1用バッチファイル |
|spresense-cli-sub2.bat| SubCore2用バッチファイル |
|spresense-cli-sub3.bat| SubCore3用バッチファイル |
|spresense-cli-sub4.bat| SubCore4用バッチファイル |
|spresense-cli-sub5.bat| SubCore5用バッチファイル |

スケッチをアップロードする際のUSBポートのCOM番号は自動で検出します。

自分のPC環境では、書き込みのボーレート`500000`でOKなのですが、エラーが出る場合はバッチファイルを直接書き換えて`115200`に変更してください。

```powershell:spresense-cli-main.bat
@echo off
setlocal enabledelayedexpansion
cd %~dp0

set BAUDRATE=500000
```

## 使い方

お好きな方法でどうぞ。

**MS-DOSコマンドプロンプト上で、スケッチフォルダを引数に指定してバッチファイルを実行する**
![dos2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432852/7416ef3e-fd4c-bb5b-a6a5-5f289b8904ba.png)

**バッチファイルをダブルクリックして開いたDOS窓にスケッチフォルダを指定（ドラッグ&ドロップも可）する**
![enter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432852/d92d46b8-8d60-e7e7-97de-fee3cc112c63.png)

**スケッチフォルダをバッチファイルにドラッグ＆ドロップする**
![drop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432852/246f715a-11c7-0c91-ee70-50c6e7a50750.png)

## その他

コンパイルは省略して**アップロードだけを行いたい**ケースもあると思います。
Arduino IDEだとこれができないんですよね。。

スケッチをビルドするとスケッチフォルダ内に `スケッチ名.SPRESENSE.spresense.spresense.spk` というファイルが生成されています。バッチファイルの引数としてスケッチフォルダを指定する代わりに、この spk ファイルを指定するとコンパイルはせずに**アップロードのみ**を行います。
Customized Regression Model for Airbnb Dynamic Pricingのメモ

何番煎じか分かりませんが、Airbnbの宿泊価格についてのダイナミックプライシングの[論文](https://www.kdd.org/kdd2018/accepted-papers/view/customized-regression-model-for-airbnb-dynamic-pricing)を読んだので、メモをします。

# 他の人の記事

- [【KDD2018】論文『Customized Regression Model for Airbnb Dynamic Pricing』を読んでまとめた](https://honawork.hatenablog.com/entry/2018/08/24/181947)
- [【論文メモ: Airbnb Pricing Model】Customized Regression Model for Airbnb Dynamic Pricing](https://www.nogawanogawa.com/entry/airbnb_pricing_model)
- [論文『Customized Regression Model for Airbnb Dynamic Pricing』ダイナミックプライシング考察](https://dev.dynamic-pricing.tech/post/miyamoto-airbnb-dynamic-pricing/)
- [Customized Regression Model for Airbnb Dynamic Pricingを読んだ](https://haltaro.github.io/2018/10/14/airbnb-dynamic-pricing)
- [slide share](https://www.slideshare.net/harmonylab/customized-regression-model-for-airbnb-dynamic-pricing-151453509)

# メモ
*the adoption (of a suggested price) is often biased towards higher suggestions*
へー

*additional personaliza- tion logic incorporating hosting goals, special events, etc*
割と泥臭いんだろうなー

*we found that a better performance, in terms of global AUC, can be achieved by training a separate GBM model for each market with an adaptive training data sampling rate*
モデルとパラメータ多そう、データどれくらいあるんだろ、データの少ない物件どうするんだろ

*the searches or listing views are usually nega- tively correlated with the price feature*
リスティングはリスティングでマイクロサービスだろうし、相互作用多いですよね、データ整形...

*We randomly sample about 10% of all listing-nights to form our evaluation set*
A/Bテストか

*the strategy model in general significantly improves both PDR and BR metrics*
$PDR$が上がったのと$BR$が下がったのだけで、評価していいのかな、significantって言っているが、統計的に有意という意味かな?

データのN数も出ていないな、企業だからしょうがないのかもだが


# 感想

ちょいちょい論文や記事を読んでいて思うのは、妥当なモデルを作りつつも、それを使う使わない、使うときのインターフェースなど、うまいことホストユーザーのことを考えてプロダクトデザインしているんだろーなーと。
モデルが良くても、実装面で使いづらかったら、利用されなくなりますからね。
ここら辺は実務で分析/モデリング/運用をしているところならではかと。

論文の内容とは全く関係ありませんが、直近のコロナの影響で、需要予測系の分析や予測は軒並み使えないと言われていますね。
この期間の変動は、予測もできなかったでしょうし、データとしても将来使えないですよねー。
予測とは斯くも難しい。
while文とcontinue文とbreak文

```python
count = 0
while count < 5:
    print(count)
    count +=1

count = 0
while True
    if count >=5:
        break
    print(count)
    count += 1


count = 0
while True:
    if count >=5:
        break
    if count == 2:
        count +=1
        continue

    print(count)
    count += 1
```
連想配列を条件分岐で使う

私がプログラミングを学び始めた当初、連想配列の使い所が分かりませんでした。

現在もまだあまりわかっていませんが、連想配列の使い所の参考になれば嬉しいです。

# 連想配列とは
連想配列とは、**キーとそのキーに対応した値を格納した配列**のことです。

言語によっては「辞書」とも呼ばれます。

通常の配列では、値を取り出す時はインデックスを使いますが、**連想配列ではキーと呼ばれるものを使います。**

詳しくは以下のサイトを参考にしてください。

[PHPで連想配列を使う方法](https://techacademy.jp/magazine/4917)

例えば、次のような宣言をしたとします。（以下、**Python**で書きます。）

```python
dict = {"リンゴ" : 100, "キャベツ" : 150}
```

配列と違い宣言には、{ }を使います。(通常の配列は[ ]を使う言語が多いと感じます)

そして、キーから値を取り出すには次のようにします。

```python
apple_price = dict["リンゴ"] #apple_priceには100が格納されます
kyabetsu_price = dict["キャベツ"] #kyabetsu_priceには150が格納されます
```

では、本題に移ります。

# 制御構文(if, Switchなど)での条件分岐

連想配列を条件分岐で使う利点はコードがシンプルで読みやすくなること(可読性向上)と、条件を追加しやすくなること(拡張性、保守性向上)です。

例えば、食物を買おうとする客が1000円出した際に、そのお釣りを求め表示したいとしましょう。

そうすると`if`で書くと一例として次のようになると思います。

```python
food = input() #input()は標準入力の関数　ここでは「リンゴ」や「キャベツ」など商品名を入力するとする
oturi = 1000
if food == "リンゴ":
    oturi = oturi - 100
elif food == "キャベツ"
    oturi = oturi - 150
print(oturi)
```

これを連想配列で書くと

```python
name2price = { #食品名と値段の対応表
    "リンゴ" : 100, 
    "キャベツ" : 150
    } 

food = input() #input()は標準入力の関数　ここでは「リンゴ」や「キャベツ」など商品名を入力するとする
oturi = 1000
oturi = oturi - name2price[food]
print(oturi)
```

となります。
2つくらいであればまだifやswitchで書けるのですが、数が多くなってくると大変なことになります。

ここから２つ増やすだけでも

```python
#ifの場合
food = input() #input()は標準入力の関数　ここでは「リンゴ」や「キャベツ」など商品名を入力する想定
oturi = 1000
if food == "リンゴ":
    oturi = oturi - 100
elif food == "キャベツ":
    oturi = oturi - 150
elif food == "きゅうり":
    oturi = oturi - 50
elif food == "もやし":
    oturi = oturi - 10
print(oturi)

#------------------------------------------

#連想配列の場合
name2price = { #食品名と値段の対応表
    "リンゴ" : 100, 
    "キャベツ" : 150,
    "きゅうり" : 50,
    "もやし" : 10,
    } 

food = input() #input()は標準入力の関数　ここでは「リンゴ」や「キャベツ」など商品名を入力するとする
oturi = 1000
oturi = oturi - name2price[food]
print(oturi)
```

となり、連想配列を使うことでコードが美しくなることがわかると思います。

以上、何かの参考になれば幸いです。

コーディングに慣れてくるまでは、とにかく動くコードを書くことが大切です。<br>
しかし、ある程度慣れてきたら他に効率よくコーディングする方法がないか考えることがさらに大切になります。<br>
私も常に考えてはいるのですが、まだまだなかなかうまくいかないですが．．．<br>
でも焦らず頑張っていこうと思います。

ちなみに余談ですが

`oturi = oturi - ○○`の箇所はすべて`oturi -= ○○`

という風にも書けます。
AWS 認定ソリューションアーキテクト – プロフェッショナル 合格への道#26

#はじめに
今日受験してきました。
結果は残念ながら不合格でした！

ですが前回と比べて得たものが多いのでまた次も頑張ります。

#よかった点
* 見直しができた
    * 前回は最後まで完走できませんでした。
    * １５分を残す

#悪かった点
* 知識不足を感じた

#対策
* 復習しやすいようにブログ記事のハブとなる記事を設定し、自分なりの再入門記事をコンテンツとして作る
    * 誰が見ても分かるように記事を書く
    * サービスアップデートの際に更新することで自分専用の取説ができる

* 試験範囲は昨日発見したEラーニングで扱われた範囲をこすり続ける。
    * 受験した感覚だとあの範囲以外は出てきてなかったです。

#HUB記事
今後は以下の記事をHUBとします。
https://qiita.com/fjisdahgaiuerua/items/998a7e41bd6bb990b078
JSPカスタムタグを簡単に作る方法

### はじめに
  今のところ、画面を作成する際に、jspをよく使われています。ある程度、JSPカスタムタグは必要になる場合もあります。
　本記事は簡単にJSPカスタムタグを作る方法を解説します。

### 概念解説
   本記事はwebプロジェクトをベースにJSPカスタムタグを開発していきますよ。
また、少しだけ、JSPカスタムタグに関するの知識をまとめています。

 - **SimpleTagSupportクラス**: インタフェースSimpleTagを実現するクラスです。JSPカスタムタグを開発する際に、よく親のクラスとしての使われています。
 - **doTag()メソッド** : このメソッドをOverrideして実際の業務ロジックを実現する。
 -  **tldファイル**: JSPカスタムタグのタグ名、タグ属性、タグクラスなどの情報を定義する場所。

   本記事は**\<hyman:hello　name="">**というカスタムタグを作成します。
タグ名はhelloですし、タグの属性はnameです。
このタグを使うと、画面上にnameのvalueを含めて出力します。

### 作る方法
#### 一、java側の実装
　　簡単に言うと、新しいjavaクラスを作成して親のSimpleTagSupportクラスを継承し、doTagメソッドを実装します。
　　ソースコードは下記の通りです。

```java:HymanTag.java
package tag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class HymanTag extends SimpleTagSupport {

    private String name;

    @Override
    public void doTag() throws JspException {
        try {
            getJspContext().getOut().println("Hello, " + name);
        } catch (Exception e) {
            throw new JspException(e);
        }
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
```
#### 二、tldファイル作成
下記のように、タグの名、属性、クラスなどの情報を記入します。
その後、hyman.tldファイルを/webapps/WEB-INFディレクトリの下に格納します。
**例：/webapps/WEB-INF/hyman.tld**

```xml:hyman.tld
<?xml version="1.0" encoding="UTF-8" ?>
<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>2.0</jsp-version>
  <short-name>Example TLD</short-name>
  <tag>
    <name>hello</name>
    <tag-class>tag.HymanTag</tag-class>
    <body-content>empty</body-content>
    <info>Hello tag with parameters.</info>
    <attribute>
        <name>name</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
     </attribute>
  </tag>
</taglib>
```
#### 三、JSPカスタムタグ使用
> 前提：hyman.tldファイルを/webapps/WEB-INFディレクトリの下に格納します。
> **例：/webapps/WEB-INF/hyman.tld**

先ずはjspファイルを作ってJSPカスタムタグを導入し、使います。
導入：
><%@ taglib prefix="hyman" uri="/WEB-INF/hyman.tld"%>

jspのソースコードは下記の通りです。

```html:index.jsp
<%@page pageEncoding="UTF-8"%>
<%@ taglib prefix="hyman" uri="/WEB-INF/hyman.tld"%>
<html>
   <head>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
       <title>JSPカスタムタグを簡単に作る方法</title>
   </head>
   <body>
      <h2 style="color:red;">
         <hyman:hello name="hyman's custom tag"/>
      </h2>
   </body>
</html>
```
#### 四、JSPカスタムタグの表現
ここまで、JSPカスタムタグの実装はすべて完了しまして、プロジェクトを起動して画面上で確認しましょう。
イメージが以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225740/d50d6fba-14af-823d-94f7-6c1124080a0e.png)

### 最後に
最後まで読んでいただき、ありがとうございます。
おかしいと思う部分は遠慮なくご指摘いただければと思います。
よろしくお願いします。
iSCSI環境で起動時にZFS import-cacheが失敗する問題

# 概要
iSCSIターゲット上のブロックデバイスをZFS(ZFS on Linux)で利用している際、再起動後にZFSの自動起動に失敗する。zpoolコマンドでZFSプールを確認しようとしてもうまくいかず、手動でzfs-import-cacheサービスを起動するとうまくいくようになる。

とりあえず調べてみると、systemdでサービスを起動する順番に問題があり、iSCSIターゲットを認識するより先にzfs-import-cacheが呼び出されるため、うまく動作しないのだと思われる。

# 対策方法
いろいろ試したけど、うまくいってない…

zfs-import-cacheの起動順を調整して楽勝かと思い、下記のような設定をしてみたが、再起動時にフリーズするようになってしまった。

```diff:/etc/systemd/system/zfs-import.target.wants/zfs-import-cache.service
    [Unit]
    Description=Import ZFS pools by cache file
    Documentation=man:zpool(8)
    DefaultDependencies=no
    Requires=systemd-udev-settle.service
    After=systemd-udev-settle.service
    After=cryptsetup.target
    After=systemd-remount-fs.service
+   After=remote-fs-pre.target
    Before=zfs-import.target
    ConditionPathExists=/etc/zfs/zpool.cache
```

と思ったら[Order zfs-import-*.service after multipathd #9863](https://github.com/openzfs/zfs/pull/9863)というknown bugだったらしく、[zfs-0.8.4](https://github.com/openzfs/zfs/releases/tag/zfs-0.8.4)で修正済みとのこと。ただ、現時点で ``yum update`` で降って来ないので修正されたことを確認できていない。
pipするとインストール済みなのに、importできない場合

pipするとインストール済みなのに、importできない場合です。
単純な話ですが、例えば、

```python
>>> import django
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'django'
```

djangoをimportしようとするとエラーになります。
エラーの内容はそのままですが、モジュールが見つかってません。

そもそもdjangoがないのかなと思って、pipしてみると、

```python
C:\Users\aaa>pip install django
Requirement already satisfied: django in c:\users\aaa\anaconda3\lib\site-packages (3.0)
Requirement already satisfied: sqlparse>=0.2.2 in c:\users\aaa\anaconda3\lib\site-packages (from django) (0.3.0)
Requirement already satisfied: asgiref~=3.2 in c:\users\aaa\anaconda3\lib\site-packages (from django) (3.2.3)
Requirement already satisfied: pytz in c:\users\aaa\anaconda3\lib\site-packages (from django) (2019.3)
```
already satisfiedなので、「既にあるよ」と言われています。
ということは、単純にパスが通ってないということです。

パスはsys.pathで確認できます

```python
>>> import sys
>>> import path
>>> pprint.pprint(sys.path)
['',
 'C:\\Users\\aaa\\Anaconda3\\python37.zip',
 'C:\\Users\\aaa\\Anaconda3\\DLLs',
 'C:\\Users\\aaa\\Anaconda3\\lib',
 'C:\\Users\\aaa\\Anaconda3',
 'C:\\Users\\aaa\\Anaconda3\\lib\\site-packages',
 'C:\\Users\\aaa\\Anaconda3\\lib\\site-packages\\win32',
 'C:\\Users\\aaa\\Anaconda3\\lib\\site-packages\\win32\\lib',
 'C:\\Users\\aaa\\Anaconda3\\lib\\site-packages\\Pythonwin',
```

確かに、djangoのパス「django in c:\users\aaa\anaconda3\lib\site-packages (3.0)」がありません。

ここまでわかれば、あとは環境変数にパスを追加してあげるだけです。
sys.path.appendで環境変数に追加できるので、

```python
sys.path.append("c:/users/aaa/anaconda3/lib/site-packages (3.0)")
```

突っ込めたら再度確認で

```python
>>> pprint.pprint(sys.path)
 'c:/users/aaa/anaconda3/lib/site-packages (3.0)'
```
が追加されていればOKです。

```python
>>> import django
>>> print(django.get_version())
3.0
```

djangoが使えるようになったことが確認できました。


#誤りパターン
ちなみに、コピペして環境変数に突っ込もうとすると、こんなエラーがでます。

```python
>>> sys.path.append("c:\users\aaa\anaconda3\lib\site-packages (3.0)")
  File "<stdin>", line 1
SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \uXXXX escape
>>> sys.path.append("c:/users/aaa/anaconda3/lib/site-packages (3.0)")
```
これは\マークがエスケープなので、\uでエスケープシーケンスと認識されているからです。
sys.path.append("c:\users\aaa\anaconda3\lib\site-packages (3.0)")を
sys.path.append("c:/users/aaa/anaconda3/lib/site-packages (3.0)")にすればOKです。
NestJSのインストール〜新規プロジェクト作成方法

# NestJSのインストール〜新規プロジェクトの作成方法
NestJSの議事録を残すための記事です。
## NestJSとは
こちらの記事が詳しく記載してくれています。
[NestJSのススメ ～Expressを超えてゆけ～](https://qiita.com/elipmoc101/items/9b1e6b3efa62f3c2a166)
公式サイト
https://docs.nestjs.com/

## NestJSのインストール
```
npm i -g @nestjs/cli
```
## インストールの確認
```
nest --version
7.1.5
```
## 新規プロジェクトの作成
```
nest new nest-test-project
⚡  We will scaffold your app in a few seconds..

CREATE nest-test-project/.eslintrc.js (599 bytes)
CREATE nest-test-project/.prettierrc (51 bytes)
CREATE nest-test-project/README.md (3370 bytes)
CREATE nest-test-project/nest-cli.json (64 bytes)
CREATE nest-test-project/package.json (1905 bytes)
CREATE nest-test-project/tsconfig.build.json (97 bytes)
CREATE nest-test-project/tsconfig.json (336 bytes)
CREATE nest-test-project/src/app.controller.spec.ts (617 bytes)
CREATE nest-test-project/src/app.controller.ts (274 bytes)
CREATE nest-test-project/src/app.module.ts (249 bytes)
CREATE nest-test-project/src/app.service.ts (142 bytes)
CREATE nest-test-project/src/main.ts (208 bytes)
CREATE nest-test-project/test/app.e2e-spec.ts (630 bytes)
CREATE nest-test-project/test/jest-e2e.json (183 bytes)

? Which package manager would you ❤️  to use? (Use arrow keys) # 好きな方のパッケージマネージャーを選ぶ
❯ npm
  yarn 
✔ Installation in progress... ☕

🚀  Successfully created project nest-test-project
👉  Get started with the following commands:

$ cd nest-test-project
$ npm run start
```

## アプリケーションの起動
インストール完了時に出たコマンドをそのまま実行 

```
cd nest-test-project
npm run start

> nest start

[Nest] 98853   - 2020/05/16 19:13:18   [NestFactory] Starting Nest application...
[Nest] 98853   - 2020/05/16 19:13:18   [InstanceLoader] AppModule dependencies initialized +11ms
[Nest] 98853   - 2020/05/16 19:13:18   [RoutesResolver] AppController {}: +5ms
[Nest] 98853   - 2020/05/16 19:13:18   [RouterExplorer] Mapped {, GET} route +3ms
[Nest] 98853   - 2020/05/16 19:13:18   [NestApplication] Nest application successfully started +2ms
```

## 起動確認
http://localhost:3000 にアクセスし、下記画面が表示されればOK!

![スクリーンショット 2020-05-16 19.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296391/068e26e9-a8d1-4313-ecbc-2e7f6ca7c54e.png)

## 最後に
初投稿のため、愛想のない文字列が並んだだけになったような。。。
これから、勉強の内容を色々投稿していこうと思う。
Guzzleを使って外部APIへPOST送信

## Guzzleとは
PHP用のHTTPクライアントライブラリです。
WEBサーバに外部APIへPOST送信などを行いたい際にGuzzleが非常に便利でした。

導入方法・簡単な使い方をまとめてみました。


## インストール方法
composerコマンドでguzzlehttp/guzzleパッケージのインストール

```
composer require guzzlehttp/guzzle
```

2020年5月現在、最新は6.5のようです。

``` composer.json
{
    "require": {
        "guzzlehttp/guzzle": "^6.5"
    }
}
```

## 使い方


```  app/src/Controller/Front/ApiController.php
use GuzzleHttp\Client;

public function getSession()
{
    $session = $this->request->getSession(); //セッションを取得
    $data = $session->read('data');          //Formで入力しているデータを取得します

    $this->postApi($data); 
    //略
}

public function postApi($data)
{
    $url         = "https://external.api";                  //API側（受取側）のURLを指定
    $basic       = "basic-id:basic-password"                //basic認証のIDとPASSWORD　※envに格納しましょう
    $encodeBasic = base64_encode($basic);                   //basic認証をエンコーディング
    $config      = ['base_uri' => 'https://www.this.com/']; //送信元のURLを指定

    $client = new Client($config);
    
            $option = [
            'http_errors' => true,                             //エラーを出力
            'verify'      => false,                            //SSL認証を無視

            'headers' =>    //ヘッダーにBASIC認証などを追加
            [                                     
                'Authorization' => 'Basic ' . $encodeBasic,    //エンコードしたbasic認証です。外部API側でデコードしてください
                'Host'          => "external.api",             //外部APIのホスト指定
                'Content-Type'  => "text/plain",               //コンテントタイプを指定　無くてもできました。
            ],

            'form_params' => //application / x-www-form-urlencoded POSTリクエストを送信するために使用
            [
                "username"      => $data["name"],      //外部APIとカラム名が異なっていたのでここで修正。
                "tel"           => $data["telephone"], //同上
                "address"       => $data["mail"],      //同上
                "contents"      => $data["content"],   //同上
            ],
        ];

    $response = $client->request("POST", $url, $option); //第１引数はPOST or GET、第２引数は受取側のAPI,第３引数はPOST送信データ
}
```

### レスポンスのステータスコードのチェック

```  app/src/Controller/Front/ApiController.php
    $response->getStatusCode（）; 
```

## 参考にした資料

Guzzleドキュメント
http://docs.guzzlephp.org/en/stable/index.html

Guzzle Httpを試してみたよ  clustfe様
https://qiita.com/clustfe/items/f9ff2b12da7a501197f8

Guzzleでファイルアップロードする zaburo様
https://qiita.com/yousan/items/2a4d9eac82c77be8ba8b
seleniumで自動取得してみた際の備忘録

##説明
あるサイトの情報を自動で取得するためのアプリケーションを作成してみました。
https://github.com/jajaja12345-code
その際に調べたことの備忘録として書きます。

##備忘録
###複数のclass名がある
クラス名とクラス名の間にスペースがある時、
`<p class = "servings_for yield">`
のような物の時、
`find_element_by_css_selector("servings_for yield")`
ではエラーが出てしまう。
そのため次のように記述する
`find_element_by_css_selector(".servings_for.yield")`

参照
[seleniumでby_class_nameでスペースが入った要素が取得できずエラーになる時の対処法](https://qiita.com/hanonaibaobabu/items/e547410865d857aa25ec)

###複数の要素を取得
`find_elements`で行う。
elementではなくて、elements

参照
[seleniumでWebElement object is not iterableが出るときの対処方法](http://www.asnm4.com/2018/11/selenium%E3%81%A7webelement-object-is-not-iterable%E3%81%8C%E5%87%BA%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E5%AF%BE%E5%87%A6%E6%96%B9%E6%B3%95/)

###NoSuchElementExceptionのキャッチ
try文で存在するかを確かめ、exceptでNoSuchElementExceptionをキャッチする
(exceptは複数記述可能)

参照
[Python、Seleniumの基本](https://narito.ninja/blog/detail/69/#_3)
[Pythonの例外処理（try, except, else, finally）](https://note.nkmk.me/python-try-except-else-finally/)

###何もしない処理の定義
pass文を使う

参照
[何もしない関数を定義したい](https://teratail.com/questions/852)

###要素を見つけるまでの待ち時間を一括設定する
`driver.implicitly_wait(10)`
driverの各要素を見つけるために10秒まつ。

参照
[【Python】implicitly_wait・・・指定したドライバの要素が見つかるまでの待ち時間を設定する](https://www.seleniumqref.com/api/python/time_set/Python_implicitly_wait.html)

##感想
スマホからも入力できるようにしたいなぁ。
VSCodeで不要なスペースを可視化する

## やりたいこと
- 空行の不要なスペースを可視化したい
- 行末の不要なスペースを可視化/削除したい
- ファイルの末尾に空行を入れたい

## やったこと
- 拡張機能 [Whitespace+](https://marketplace.visualstudio.com/items?itemName=davidhouchin.whitespace-plus) を入れた
- 拡張機能 [zenkaku](https://marketplace.visualstudio.com/items?itemName=mosapride.zenkaku) を入れた
- `"files.trimTrailingWhitespace": true` を設定した
- `"files.insertFinalNewline": true` を設定した

![スクリーンショット 2020-05-16 18.45.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145075/1b3cab91-0343-d5fd-2b79-5b054899c692.png)


## 不要なスペースを可視化する
拡張機能[Whitespace+](https://marketplace.visualstudio.com/items?itemName=davidhouchin.whitespace-plus)をインストールした後、コマンドパレットから`Whitespace+ Toggle`を選択するとスペースを可視化してくれる。
コマンドパレットの開き方はMacだと`Command`+`Shift`+`p`、Windowsだと`Ctrl`+`Shift`+`p`
ちなみに拡張機能検索はMacだと`Command`+`Shift`+`x`、Windowsだと`Ctrl`+`Shift`+`x`でいける。

デフォルトの設定だと↓のように見辛いので、設定ファイルを編集する。

![スクリーンショット 2020-05-16 18.48.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145075/d591d715-c6e4-8de5-8a07-c252a7c5770c.png)

設定ファイルを開くにはコマンドパレットから`Whitespace+ Config`を選択する。
`space`, `tab`, `newline`, `trailing`の4つのモードが設定されており、この設定ファイルで可視化する箇所の条件やスタイルを変更することができる。
`autoStart`を`true`にすることで常に有効にすることができる。

**spaceモード**
可視化する箇所はデフォルトでは

```
"pattern": "\\s"
```

となっており、全てのスペースが表示されてしまう。ここを

```
"pattern": "^\\ +$"
```

に変更することで、空行のスペースだけを表示してくれる。

**newlineモード**
改行を表示するモードだが、不要なので `"enabled": false` にする

**trailingモード**
行末のスペースを表示してくれる。`"enabled": true` にする。

## 全角スペースを可視化する
拡張機能 [zenkaku](https://marketplace.visualstudio.com/items?itemName=mosapride.zenkaku) をインストールした後、コマンドパレットから `Enable Zenkaku` を選択することで全角スペースを表示してくれるようになる。

## 不要なスペースを自動削除する
VSCodeの設定ファイルに

```
"files.trimTrailingWhitespace": true
```

を設定することで、ファイルの保存時に自動で文末のスペースおよび空行のスペースを削除してくれるようになる。
ちなみに設定ファイルはMacは`Command`+`,`、Windowsでは`Ctrl`+`,`で開ける。

## ファイルの末尾に改行を挿入する

設定ファイルに

```
"files.insertFinalNewline": true
```

を設定することで、常にファイルの末尾で改行されるようになる。
[Flutter] 自前の画像をタップして処理を走らせる（GestureDetector、onTap）

# はじめに
画像をタップして処理を走らせるためには、GestureDetectorとonTapを用います。
今回はAndroidStudioでプロジェクト作成時に作られるカウンターアプリを改変してみます。

# 完成図
ピーターパン症候群のおじさんをタップするたびにカウンターが上がっていきます
![画面収録 2020-05-16 19.00.34.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135663/18d81ee2-685f-4f06-3638-d76bd8c8d40e.gif)


# 実装
GestureDetectorでラップし、タップしたときに走らせる処理と、対象の画像を記述するだけです。

```dart
GestureDetector(
  onTap: () {
    // タップしたときの処理を記述（ここではカウンターを+1）
    setState(() {
      _counter++;
    });
  },
  // 対象の画像を記述 
  child: Image.network(
      'https://3.bp.blogspot.com/-QxAapI2H1Pk/VhSAsJpLPhI/AAAAAAAAzG0/80qjXfZlomk/s800/peterpan_syndrome.png'),
),

```

# 参考
■公式ドキュメント

https://flutter.dev/docs/cookbook/gestures/handling-taps
https://flutter.dev/docs/cookbook/images/network-image
Chrome拡張機能で右クリックメニューを作る方法

この記事では下記のメニュー作成のコードとクリック時のログ出力を載せています。

| <img width="600" alt="2020-05-16_18h40_53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/626d958f-563a-f3e1-b45b-41997d7cf21a.png"> |
|:-:|



```:フォルダ構造
フォルダ
 ├ manifest.json
 └ event.js
```

```json:manifest.json
{
  "manifest_version": 2,
  "name": "context menus",
  "version": "1.0",

  "background": {
    "scripts": ["event.js"],
    "persistent": false
  },
    
  "permissions": [
    "activeTab",
    "contextMenus"
  ]
}
```


```javascript:event.js
'use strict';

{
  chrome.runtime.onInstalled.addListener(() => {
    const parent = chrome.contextMenus.create({
      id: 'parent',
      title: '親メニュー'
    });
    chrome.contextMenus.create({
      id: 'child1',
      parentId: 'parent',
      title: '子メニュー1'
    });
    chrome.contextMenus.create({
      id: 'child2',
      parentId: 'parent',
      title: '子メニュー2'
    });
    chrome.contextMenus.create({
      id: 'child3',
      parentId: 'parent',
      title: '子メニュー3'
    });
    chrome.contextMenus.create({
      id: 'grandchild1',
      parentId: 'child1',
      title: '孫メニュー1'
    });
    chrome.contextMenus.create({
      id: 'grandchild2',
      parentId: 'child1',
      title: '孫メニュー2'
    });
  });

  // メニューをクリック時に実行
  chrome.contextMenus.onClicked.addListener(item => {
    console.log(item);
    console.log(item.menuItemId);
  });
}
```

孫メニュー1、子メニュー2をクリックしたときのログ

|<img width="1000" alt="2020-05-16_18h44_57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/a7d21916-9954-398c-e29a-06e3bc195509.png">|
|:-:|

```
孫メニュー1のログ
{editable: false, frameId: 0, menuItemId: "grandchild1", pageUrl: "https://www.google.com/?hl=ja", parentMenuItemId: "child1"}
grandchild1
子メニュー2のログ
{editable: false, frameId: 0, menuItemId: "child2", pageUrl: "https://www.google.com/?hl=ja", parentMenuItemId: "parent"}
child2
```

この記事は[Chrome拡張機能の作り方](https://qiita.com/plumfield56/items/680ce9a166282b7ae84c)の一部のコンテンツです。
rails6にbootstrapを反映させるときのファイル状況

##本記事の対象者
著者自身。
自分用なので未来の自分が分かるように書いています。

##環境

Ubuntu18.04 (Windows10home on VirtualBox)
rails 6.0.3
ruby 2.7.1
bootstrap 4.5.0
　以下の事前インストールでは`4.3.1`だが、`bootstrap`が上手く反映されず見当違いの対処をして余計なインストールなどした結果、このバージョンになった。
　`package.json`では`4.5.0`となっているため、記事には書いていないが途中の`npm install`でこのバージョンになったと思われる。

##事前インストール

```
yarn add bootstrap@4.3.1 jquery popper.js
```
@以下はお好きなバージョンでいいと思われる。
調べてはいないが、@以下を記載しなければ最新版がインストールされるのではないだろうか。
`jquery`,`popper.js`は`bootstrap`で必須らしい。


##注意事項
・最終的にはgemなしで動いたが、途中でgemを追加して`bundle install`しているのでその影響がどこかで出ているかもしれない。

##ファイル状況

```ruby:Gemfile
この記事ではgemは使用しない

```

```javascript:config/webpack/environment.js
const { environment } = require('@rails/webpacker')
const webpack = require("webpack")

//プラグインを追加。
//ProvidePluginは、自動的にモジュールをロードする。
//importが不要になる

environment.plugins.prepend(
  "Provide",
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',//$に格納
    jQuery: 'jquery/src/jquery',
    Popper: "popper.js"
  })
)
module.exports = environment

```

```javascript:app/javascript/packs/application.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")

//以下を追記（1，3行目がなくてもjqueryは動いた。
//2行目がなかったらcssが反映しなかった。）
import "bootstrap"
import "../stylesheets/application"
import "./bootstrap_custom.js"
```
```scss:app/javasctipt/stylesheets/application.scss
@import "~bootstrap/scss/bootstrap";
```

```javascript:app/javascript/packs/bootstrap_custom.js
//すべてコメントアウトしてもjqueryは動いた。
//environment.jsで設定しているからいらない？
import "bootstrap/js/dist/alert"
import 'bootstrap/js/dist/button'
import 'bootstrap/js/dist/carousel'
import 'bootstrap/js/dist/collapse'
import 'bootstrap/js/dist/dropdown'
import 'bootstrap/js/dist/index'
import 'bootstrap/js/dist/modal'
import 'bootstrap/js/dist/popover'
import 'bootstrap/js/dist/scrollspy'
import 'bootstrap/js/dist/tab'
import 'bootstrap/js/dist/toast'
import 'bootstrap/js/dist/tooltip'
import 'bootstrap/js/dist/util'
```

```erb:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>hogehoge</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%# bootstrapに関係する箇所は
        css,javascriptを反映させるための以下２行 %>

    <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>

```

```json:package.json(参考)
// package.jsonはGemfileみたいなもの
// npm installでこれらが入る
{
  "name": "hoge",
  "private": true,
  "dependencies": {
    "@rails/actioncable": "^6.0.0",
    "@rails/activestorage": "^6.0.0",
    "@rails/ujs": "^6.0.0",
    "@rails/webpacker": "4.2.2",
    "bootstrap": "^4.5.0",
    "jquery": "^3.5.1",
    "popper.js": "^1.16.1",
    "turbolinks": "^5.2.0"
  },
  "version": "0.1.0",
  "devDependencies": {
    "vue-loader": "^15.9.2",
    "vue-template-compiler": "^2.6.11",
    "webpack-dev-server": "^3.11.0"
  }
}

```

##参考

Webpackerを使用したRails 6でのjQueryの紹介
https://www.botreetechnologies.com/blog/introducing-jquery-in-rails-6-using-webpacker#

ProvidePlugin
https://webpack.js.org/plugins/provide-plugin/
[CSS]画像を重ねる時、positionやz-indexを反射的に使っていませんか？

CSSで画像を重ねて表示させたいだけなのに、
position:rerative、absoluteやz-indexを反射的に使っていませんか？

背景画像に別の画像を単純に重ねるだけなら、
CSS1行だけで表現することができます。
もっと簡単に実装してしまいましょう！

## 完成イメージ
![cat.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273801/b3164c98-786b-6a57-8f12-670b634f8762.png)

テキスト：タイトルテキスト
画像：木目調のテクスチャ
画像：猫
の3点を今回は表示します。


## サンプルコード
```html:main.html
<div class="aClass bClass">
  タイトルテキスト
</div>
```
テキストは、HTMLの中に直接書いています。

```css:main.css
.aClass {
        background: no-repeat bottom right 
        url(画像のパス),
        no-repeat
        url(画像のパス);
}
.bClass {
        color: #fff;
        height: 200px;
        width: 320px;
}
```
画像を重ねているのは、**aClassの方だけ**です。
１番上のurl(画像のパス),が手前に表示されます。
猫の画像をbottom rightで右下に配置しています。

bClassは、テキストの色などを指定しています。
画像の重ねるサンプルがわかりにくくなってしまうので別にしています。


## [応用]画像を３つ重ねたい場合
画像を３つ重ねたい場合は、url(画像のパス)を増やすと、重ねる画像を増やすことができます。


## まとめ
position:rerativeやz-indexは大変便利です。
やろうと思えばなんでも配置できてしまいます。

ただ後になって修正しようとすると、
どれが親要素で子要素なの？、画像の重ね順はどうなってるの？
と、調べる手間が発生してしまいます。

単純に重ねたいだけであれば、こういった書き方ができることも知っておくとコーディングの幅がもてます！


### 【参考】CSS での複数の背景の利用方法
https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds
GASでQiitaAPIを使い、記事一覧を取得する

# はじめに
今までGoogleのAPIを利用していたので、外部のAPIを使ってみたく、Qiia APIを利用して自分が投稿した記事の情報を取得してみました。[認証認可](https://qiita.com/api/v2/docs#%E8%AA%8D%E8%A8%BC%E8%AA%8D%E5%8F%AF)の部分のやり方がわからず、参考にさせていただいた、[GASでQiita APIを使ってView・いいね・ストック数の一覧を取得する](https://qiita.com/tksnino/items/7e6a587ff6e1817490ad)にかなり助けてもらいました。感謝です。

# シートの説明
Qiita APIを利用し、取得した情報を以下の形式で書き込みます。

### QiitaListシート
| id | title | body | url | createdat | updatedat |
|:--:|:--:|:--:|:--:|:--:|:--:|
| c686397e4a0f4f11683d | Example title | # Example | https://qiita.com/Qiita/items/c686397e4a0f4f11683d | 2000-01-01T00:00:00+00:00 | 2000-01-01T00:00:00+00:00 |
| ... | ... | ... | ... | ... | ... |

### 項目説明
* id
    * 記事の一意なID
    * Example: "c686397e4a0f4f11683d"
* title
    * 記事のタイトル
    * Example: "Example title"
* body
    * Markdown形式の本文
    * Example: "# Example"
* url
    * 記事のURL
    * Example: "https://qiita.com/Qiita/items/c686397e4a0f4f11683d"
* created_at
    * データが作成された日時
    * Example: "2000-01-01T00:00:00+00:00"
* updated_at
    * データが最後に更新された日時
    * Example: "2000-01-01T00:00:00+00:00"

※詳細な説明は下記参照
[Qiita API v2の仕様](https://qiita.com/api/v2/docs#%E6%8A%95%E7%A8%BF)


# コード
getQiita.gs

```javascript
  var sheet = SpreadsheetApp.getActive().getSheetByName('QiitaList');

  // 定義
  const QIITA_TOKEN  = '※アクセストークンを記入※'; // 
  const API_ENDPOINT = 'https://qiita.com/api/v2';
  const API_MY_ITEMS = '/authenticated_user/items';

  //APIヘッダ
  var headers = {'Authorization' : 'Bearer ' + QIITA_TOKEN};
  var params = {'headers' : headers};

  // 認証中のユーザの記事の一覧取得
  var paramstr = "?per_page=100&page=1";
  var res = UrlFetchApp.fetch(API_ENDPOINT + API_MY_ITEMS + paramstr, params);
  var json = JSON.parse(res.getContentText());
  json.forEach(function(item, i){
    sheet.getRange(i + 2, 1).setValue(item["id"]);
    sheet.getRange(i + 2, 2).setValue(item["title"]);
    sheet.getRange(i + 2, 3).setValue(item["body"]);
    sheet.getRange(i + 2, 4).setValue(item["url"]);
    sheet.getRange(i + 2, 5).setValue(item["created_at"]);
    sheet.getRange(i + 2, 6).setValue(item["updated_at"]);
  });
```


# 参考
* [GASでQiita APIを使ってView・いいね・ストック数の一覧を取得する](https://qiita.com/tksnino/items/7e6a587ff6e1817490ad)
* [QiitaのAPIv2を使用して自身の記事取得](https://qiita.com/tatsuo-iriyama/items/c1e56c1a197e39087b6e)
Wio TerminalのUSB書き込みエラーの回復方法

# どんな内容か？
Arduino IDEを使ってWio Terminalを早速動かしてみたらUSB書き込みに失敗して少し焦ったので回復方法？紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/5c90d050-9442-d983-c0f1-d5a97692f5cf.png)


# 現象
Wio TerminalをPCのUSBポートに接続すると最初はCOMポートで認識されているのですが、少し時間が経過すると切断されて、そのうちUSBは認識されていないエラーをWindowsが出してきます。もちろん、USBに接続した直後にArduinoから書き込みボタンを押してもシリアルポートに接続できないエラーが発生しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/f0190a7d-71eb-6faf-9ca3-7b1401a56372.png)

```
最大507904バイトのフラッシュメモリのうち、スケッチが31964バイト（6%）を使っています。
processing.app.debug.RunnerException
	at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:152)
	at cc.arduino.UploaderUtils.upload(UploaderUtils.java:77)
	at processing.app.SketchController.upload(SketchController.java:732)
	at processing.app.SketchController.exportApplet(SketchController.java:703)
	at processing.app.Editor$UploadHandler.run(Editor.java:2070)
	at java.lang.Thread.run(Thread.java:748)
Caused by: processing.app.SerialException: シリアルポート「COM4」をタッチできませんでした。
	at processing.app.Serial.touchForCDCReset(Serial.java:107)
	at cc.arduino.packages.uploaders.SerialUploader.uploadUsingPreferences(SerialUploader.java:136)
	... 5 more
Caused by: jssc.SerialPortException: Port name - COM4; Method name - openPort(); Exception type - Port busy.
	at jssc.SerialPort.openPort(SerialPort.java:164)
	at processing.app.Serial.touchForCDCReset(Serial.java:101)
	... 6 more
```

# 回復方法
回復方法は、本体横についている電源スイッチを素早く２回ONしてブートローダーの書き換えモードにすることです。本家のサイトで「[この辺（ブートローダーに投入するには）](https://wiki.seeedstudio.com/jp/Wio-Terminal-Getting-Started/)」に書いてあります。しかしその操作タイミングまでは記載がないので、どの程度で２回ONすれば分からずに焦りました。個人的な感覚的にはかなり素早く入れる必要がありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/4544ee75-0511-824e-b9c9-0e055a52fc77.png)

動画にしましたのでタイミングをこちらで確認してください。
[![動画がみつかりません](http://img.youtube.com/vi/yr0RSgCv0tY/0.jpg)](http://www.youtube.com/watch?v=yr0RSgCv0tY)

上手くリセットすると、ArduinoがUSBドライブとして認識されます。
あとは、Arduino IDEから書き込みボタンを押せば無事に書き込めるはずです。

以上
gitコマンドまとめ

# Gitを始めよう

```
# ローカルリポジトリの新規作成
 git init
```

# GitHub上にあるプロジェクトから始めよう
```
#Gitリポジトリのコピーを作成する
 git clone <リポジトリ名>
 git clone ＜リポジトリ名><プロジェクト名>
```

# 変更をステージに追加しよう
```
#変更をワークツリーからステージへ追加する
#コミットする変更を準備
 git add <ファイル名orディレクトリ名>
 git .
```

# 変更を記録しよう
```
#ステージからリポジトリへ変更を記録する（コミット）
 git commit
 git commit -m <メッセージ>
#メッセージ付きで記録する。エディタが立ち上がる
 git commit -v
```
# 現在の変更状況を確認しよう
```
#現在の変更状況を確認する。ワークツリーとステージの間で変更されたファイル、ステージとワークツリーの間で変更されたファイルを表示する。
 git status
```
# 何を変更したのかを確認しよう
```
#git addする前(ワークツリーとステージの間）の変更差分を確認する
 git diff
 git diff <ファイル名>
#git addした後(ステージとリポジトリの間）の変更差分を確認する
 git diff --staged
```
# 変更履歴を確認しよう
```
#変更履歴を確認する。最新のコミットから順に表示される。
 git log
#１行で表示する
 git log --oneline
#ファイルの変更差分を表示する
 git log -p <ファイル名>
#表示するコミット数を制限する
 git log -n <コミット数>
```
# ファイルの削除を記録しよう
```
#ファイルごと削除する。リポジトリ、及びワークツリーから削除される。
 git rm <ファイル名>
#ディレクトリごと削除する。リポジトリ、及びワークツリーから削除される。
 git rm -r <ディレクトリ名>
#ワークツリーにはファイルを残したいとき
 git rm --cached <ファイル名>
```
# ファイルの移動を記録しよう
```
#ファイルの移動を記録する
 git mv <旧ファイル><新ファイル>
#以下のコマンドと同様
mv <旧ファイル名><新ファイル名>
 git rm <旧ファイル名>
 git add <新ファイル名>
```
# GitHubにpushしよう
```
#リモートリポジトリを新規追加する
 git remote add ＜ショートカット名> <GitHubのリポジトリのURL>
#リモートリポジトリへ送信する
 git push <リモート名><ブランチ名>
 git push remote master
```
# バージョン管理しないファイルは無視しよう
.gitignoreファイルに指定することで管理しないファイルをGitの管理から外す
# 変更をもとに戻そう
```
#ファイルへの変更を取り消す。ワークツリーの状態をステージと同じにする。
 git checkout --<ファイル名>
 git checkout --<ディレクトリ名>
#全変更を取り消す
 git checkout -- .
```
# ステージした変更を取り消そう
```
#ステージした変更を取り消す。指定した変更をステージから取り出すだけなのでワークツリーには影響しない。
 git reset HEAD <ファイル名>
 git reset HEAD <ディレクトリ名>
#全変更を取り消す
 git reset HEAD .
```
# 直前のコミットを取り消そう
```
#直前のコミットを取り消す。リモートリポジトリにPushしたコミットはやり直してはいけない。
 git commit --amend
```
# リモートの情報を確認しよう
```
#リモートを表示する
 git remote
#対応するURLを表示する
 git remote -v
```
# リモートから取得しよう（フェッチ編）
```
#リモートから情報を取得する(フェッチ編)。リモートリポジトリからローカルリポジトリに情報を取得する。
 git fetch <リモート名>
 git fetch origin
#リモートから情報を取得する。ローカルリポジトリからワークツリーに変更を反映する
 git merge
```
# リモートから取得しよう（プル編）
```
#リモートから情報を取得してマージまでを一度にやる
 git pull <リモート名><ブランチ名>
 git pull origin master
#下記コマンドと同様
 git fetch origin master
 git merge origin/master
```
# リモートの情報を詳しく知ろう
```
#リモートの詳細情報を表示する
 git remote show <リモート名>
 git remote show origin
```
# リモートを変更、削除しよう
```
#変更する
 git remote rename <旧リモート名><新リモート名>
 git remote tutorial new_tutorial
#削除する
 git remote rm <リモート名>
 git remote rm new_tutorial
```
# 新しいブランチを作成しよう
```
#ブランチを新規作成する
 git branch <ブランチ名>
 git branch feature
#ブランチの一覧を表示する
 git branch
#リモートリポジトリを含めた全てのブランチの一覧を表示する
 git branch -a
```
# ブランチを切り替えよう
```
#ブランチを切り替える
 git checkout <既存ブランチ名>
 git checkout feature
#ブランチを新規作成して切り替える
 git checkout -b <新規ブランチ名>
 git checkout -b <新規ブランチ名><派生元ブランチ名>
```
# 変更をマージしよう
```
#変更履歴をマージする
 git merge <ブランチ名>
 git merge <リモート名/ブランチ名>
 git merge origin master
```
# ブランチを変更、削除しよう
```
#ブランチを変更する
 git branch -m <ブランチ名>
 git branch -m new_branch
#ブランチを削除する。masterにマージされていない変更が残っている場合削除しない。
 git branch -d <ブランチ名>
 git branch -d feature
#強制削除
 git branch -D <ブランチ名>
DataTablesを使って遊戯王カードの表を作る!(1)

# はじめに
こんにちは。hyです。 現在は某IT企業でエンジニアとして働いています。大学4年のときにweb系の会社で開発のアルバイトをしていました。そこで得た知識を今更ながらアウトプットしていきたいと思ったので、得た知識を使って簡単なアプリケーションを作っていきたいと思います。
今回は,バイト先で使用していたjQueryライブラリのDataTablesを使って遊戯王カードを表示させるアプリを作っていこうと思います。
# 使う技術
- [DataTables](https://datatables.net/)
    - 簡単に綺麗な表や機能を追加できるjQueryライブラリ
- [Mustache.js](https://github.com/janl/mustache.js/)
    - javascriptのテンプレートエンジンで,今回は主にDataTableと併用して使います。
- [Vue.js](https://jp.vuejs.org/index.html)
    - javascriptのフレームワークの一つ。学習コストが低いことが特徴
- [Yu-Gi-Oh! API by YGOPRODeck](https://db.ygoprodeck.com/api-guide/)
    - 遊戯王カードの画像や効果などの情報を取得できるAPI  


# 完成品

以下のような物を作りました！

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="hgaiji" data-slug-hash="LYpgZNX" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="datatable-app">
  <span>See the Pen <a href="https://codepen.io/hgaiji/pen/LYpgZNX">
  datatable-app</a> by higakin (<a href="https://codepen.io/hgaiji">@hgaiji</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 最後に
次回、これらのコードについて解説してきたいと思います。何かコメントなどがある人はお気軽にお願いします。
5 月 LeetCode 挑戰, W3D2, Odd Even Linked List (Linked List), in Swift

資料結構與演算法： `Linked List`

- 挑戰頁面 - [Odd Even Linked List](https://leetcode.com/explore/challenge/card/may-leetcoding-challenge/536/week-3-may-15th-may-21st/3331/)
- 原題目頁面 - [328. Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/)

## 題意

- 給一個單向鏈結
- 把這個單向鏈結分第奇數個及第偶數個兩堆，然後以把偶的那堆放在奇後面

例如

``` text
1 -> 3 -> 5 -> 7
```

第奇數個有 1 和 5 ，第偶數個有 3 和 7

因此結果是

``` text
1 -> 5 -> 3 -> 7
```

題目要求的條件是：時間複雜度 O(n), 空間複雜度 O(1)

## 思考方式

- 宣告兩個鏈結，分別裝奇數項節點和偶數項節點
- 走訪完之後，把偶數項的鏈結接到奇數項鏈結的後面即可

注意點：

- 偶數的陣列需要把最後一個節點的 .next 設成 nil 。因為如果原先後面有接一個奇數節點的話，我們必須把它斷開。
  - 因為奇數鏈結的最後一個節點會接上偶數鏈結的第一個節點，因此不用特別做斷開的處理

### Linked List （鏈結）的操作技巧

- 建立 dummy node 作為 head node
  - 為了保留第一個位置的資訊，就像港口的繫纜柱一樣的作用把繩子定住。雖然和繩子繫在一起，但是他在資料上並沒有任何意義。
  - 回傳的時候回傳 head.next ， head.next 才是這個鏈結的真正起點
- 保留 `最後一個位置` 的節點資訊方便街上下一個節點

## 程式碼

``` swift
class Solution {
    func oddEvenList(_ head: ListNode?) -> ListNode? {

        var oddHead: ListNode? = ListNode()
        var oddCurrent: ListNode? = oddHead

        var evenHead: ListNode? = ListNode()
        var evenCurrent: ListNode? = evenHead

        /// 用來走訪傳入的鏈結
        var current: ListNode? = head
        /// 用來判斷現在是奇還是偶
        var isOdd = true

        while current != nil {
            if isOdd {
                oddCurrent?.next = current
                oddCurrent = oddCurrent?.next
            } else {
                evenCurrent?.next = current
                evenCurrent = evenCurrent?.next
            }
            isOdd.toggle()
            current = current?.next
        }

        oddCurrent?.next = evenHead?.next
        evenCurrent?.next = nil

        return oddHead?.next
    }
}
```

## 複雜度分析

n 為總節點數

- 時間複雜度： O(n)
  - 只有走訪過一次
- 空間複雜度： O(1)
  - 標誌奇數偶數項的變數是常數個
  - dummy heads 也是常數個

## 執行結果

``` text
Runtime: 28 ms (beats 94.52%)
Memory Usage: 22 MB
```
arduino-cliのススメ

Arduino IDE は起動が遅いし、コーディングは使い慣れたエディタの方が効率良いし、という方には、**arduino-cli** がおススメです:thumbsup:

# arduino-cli

Arduinoビルドのコマンドラインツールです。

#### 実行ツールのダウンロード
GitHub リポジトリの Releases ページから実行ツールをダウンロードできます。
Windows, Linux, macOS の各種プラットフォームごとに用意されています。
https://github.com/arduino/arduino-cli/releases

#### --fqbnオプション

`arudino-cli` で指定する `--fqbn` オプションは、Arduino IDE のビルドログから抜粋するのが簡単です。

1. Arduino IDEの `ファイル->環境設定` からコンパイルの詳細表示オプションをチェックしておきます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432852/2ce30150-c343-6531-fd1b-bba8359fd898.png" width="100%">

2. スケッチをコンパイルしたときのログにfqbnオプションが表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432852/b7599b34-d92c-87a3-d400-8d00938389be.png" width="100%">

#### コンパイル実行方法

`arduino-cli compile` に先ほどの `fqbn` オプションと、スケッチが存在するフォルダを指定します。
以下は、SPRESENSE環境でのコンパイル例ですが、他のボードでも同じ方法でいけます。

```
% arduino-cli.exe compile --fqbn SPRESENSE:spresense:spresense:Core=Main,Debug=Disabled <スケッチフォルダ>
```

初回実行時のみ、ctags, serial-discovery ツールのインストールが走ります。
(Windowsの場合、%USERPROFILE%\AppData\Local\Arduino15\packages\builtin\tools にインストールされるようです)

```
Downloading missing tool builtin:ctags@5.8-arduino11...
builtin:ctags@5.8-arduino11 downloaded
Installing builtin:ctags@5.8-arduino11...
builtin:ctags@5.8-arduino11 installed
Downloading missing tool builtin:serial-discovery@1.0.0...
builtin:serial-discovery@1.0.0 downloaded
Installing builtin:serial-discovery@1.0.0...
builtin:serial-discovery@1.0.0 installed
```

#### アップロード方法

`arduino-cli upload` でアップロードできます。

```
% arduino-cli.exe upload --fqbn <FQBN> -p <COMポート> <スケッチフォルダ>
```

`platform.txt` の `{runtime.os}` を正しく解釈してくれないようでいくつかのボード環境ではアップロードに失敗します。。`platform.txt` の`{runtime.os}` のところを `windows` のように直接書き換えればアップロードできるようになります。

`arduino-cli`ツールをバッチファイル化した例を[こちら](https://qiita.com/baggio/items/25d5caff31f71252f330)に書きました。
MacのTerminalをカッコよくする

# はじめに
カッコよく＝あくまで私が思うカッコ良いTerminalの見た目。
タイトルの通り今回はiTerm2ではなく、あえてTerminalに焦点を当てて、カッコよくカスタマイズしていきます。
ちなみに、ここで紹介する内容はiTerm2でも同じことができるので、ご安心ください。

まずは以下のBeforeとAfterをご覧くださいw 
Afterの方が良くないすか？

# Before
<img width="682" alt="before.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/87eebaca-3e06-8725-d424-7d285be470a3.png">


# After
<img width="762" alt="after.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43096/038fabe9-579a-094a-76f7-9597f913b1eb.png">


# カスタマイズの仕方

####①[pure(Terminalの表示内容)](https://github.com/sindresorhus/pure)を設定

```shell
npm i -g pure-prompt
echo "autoload -U promptinit; promptinit\nprompt pure" >> ~/.zshrc

```

####②[Terminalのテーマ](https://github.com/sindresorhus/hyper-snazzy)のダウンロード＆設定
- [terminal-snazzy(テーマ)](https://github.com/sindresorhus/terminal-snazzy)にアクセス後、Snazzy.terminalリンクをクリックし、ローカルにダウンロードを行います。（[こちら](http://cocopon.github.io/iceberg.vim/)のテーマもおすすめです）
*※iTerm2の方は[ここ(iterm2-snazzy)](https://github.com/sindresorhus/iterm2-snazzy)*

- ダウンロード完了したら、拡張子がterminalであることを確認する。

- ```Terminal``` > ```環境変数``` > ```プロファイル``` > ```左下の歯車(設定)マーク``` > ```読み込む...``` > ```ダウンロードしたプロファイルを選択``` > ```左下のデフォルトボタン選択``` でTerminalのテーマを変更する

- カーソルの不透明度を２５％に設定


####③[構文のハイライト](https://github.com/zsh-users/zsh-syntax-highlighting)
```echo``` や ```pwd``` などの有効なコマンドを入力した場合、緑色になるやつ。無効なコマンドは赤色になる。

```shell
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git
# 非表示にしたいので、隠しフォルダにへ変更
mv zsh-syntax-highlighting .zsh-syntax-highlighting
echo "source ~/.zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ~/.zshrc
```

####④[コマンドの自動提案](https://github.com/zsh-users/zsh-autosuggestions)
履歴と補完に基づいて入力するコマンドを提案します。

```shell
git clone https://github.com/zsh-users/zsh-autosuggestions.git
# 非表示にしたいので、隠しフォルダにへ変更
mv zsh-autosuggestions .zsh-autosuggestions
echo "source ~/.zsh-autosuggestions/zsh-autosuggestions.zsh" >> ~/.zshrc
```
Heroku + Sinatra でオウム返しのLINE Botを作るときに詰まったことメモ 

LINE Botの開発に初めて挑戦してみました。
まずは簡単なモノから、ということでおうむ返しのLINE Botです。
「認識が違う」などの指摘がございましたら、教えていただけますと幸いです。

# Sinatraを使って LINE Botを作ってみる

[Heroku+Ruby+SinatraでReplyにオウム返しするLineBotを作った](https://qiita.com/fullmated/items/81d1a49ed3d49eda2285)

大枠はこちらの記事に沿ってやっていきました.
最後までいったものの、**「返事が返ってこない」**という状況になったのでその解決方法をメモとして残しておきます.

![スクリーンショット 2020-05-16 14.14.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326789/0f31a2ee-736b-01c9-611b-a617c03e8561.png)

# 「返事が返ってこない」ことに対しての原因/やったこと

## 原因1:コード内に直接、トークンやチャンネルシークレットを入力していた

https://github.com/line/line-bot-sdk-ruby

LINE BotのSDKの中にこういった↓コードがあるのですが、僕は直接控えたTOKENなどを入力してしまっていました。
これは間違いで、Herokuの[Config Vars]で環境変数として設定するので、これはこのままで大丈夫でした。



```ruby:app.rb
# app.rb
require 'sinatra'
require 'line/bot'

def client
  @client ||= Line::Bot::Client.new { |config|
# 以下3つに控えたID,SECRET,TOKENを入力していた.これはこのままでOK!
    config.channel_id = ENV["LINE_CHANNEL_ID"]
    config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
    config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
  }
end
```


↓↓Herokuの設定画面↓↓
ここでID, SECRET, TOKENを設定します

![スクリーンショット_2020-05-16_14_41_21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326789/86086026-24d0-f517-1df0-475f6e8607cf.jpeg)


# 原因2:ローカルの変更をHerokuにpush（反映）していなかった

原因1を修正するために、ローカルでコードを変更しました。
その変更はローカルで変更しただけなので、Herokuにはその変更が反映されていませんでした。
よくみたらHerokunにもこんな記述がありました。
以下のコマンドを実行してHerokuにpush

>Deploy your changes
Make some changes to the code you just cloned and deploy them to Heroku using Git.

> $ git add .
> $ git commit -am "make it better"
> $ git push heroku master

この2つを試すと、無事に返ってくるようになりました。

# 無事、完成

![gazou.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326789/1f770a96-e48b-ae4a-9bb6-ac788ccb0908.jpeg)


# 完成したけど、まだわからないこと
## Herokuのadd onであるFixieは必要なのか？？

試行錯誤する中で、以下の記事を見つけました。
記事を見てFixieを入れてみたものの、削除しても動いてるのでもうちょっと調べて行こうと思います。

[LINE BOT をとりあえずタダで Heroku で動かす](https://qiita.com/yuya_takeyama/items/0660a59d13e2cd0b2516)

[LINE BOT APIではまったこと](https://qiita.com/cherubim1111/items/36f1bd51a51042cc2e96)
Kubernetesのcert-managerでブラウザを信用させる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193036/434140d8-189c-43df-294f-753815add99f.png)
画像転用元[https://letsencrypt.org/ja/]

# 悪用厳禁です
この記事で紹介するのはLet's EncryptのSSL証明書を使って、一般的なブラウザからアクセス可能にするための手順を示します。
決して悪用しないでください。

# Let's Encryptにハマった。。。
弊社のKubernetesにcert-managerを使って、ステージング環境のSSLを構築してありそこにIstioを導入したのがそもそもの始まり
「このサイトの通りやってある」と渡されたのがこのページ＝＞ https://docs.microsoft.com/en-us/azure/aks/ingress-tls#verify-a-certificate-object-has-been-created

しかし、cert-managerにIstioの設定が絡むとどうしてもClusterIssuerからの要求がcert-manager-webhookに届かない様でIstioを外すために一旦cert-managerを削除

このサイトと
https://cert-manager.io/docs/installation/kubernetes/

このClusterIssuerのACME設定
https://cert-manager.io/docs/configuration/acme/

でさくっと再構築しました。
しかし、なぜかブラウザからアクセスできず。。。

curlでは `--insecure` を付けないと上手く接続できない事から証明書がよろしくない事が判明

# 何が起きたのか
[こちら](https://letsencrypt.org/ja/docs/staging-environment/)のLet's Encrypt公式ガイドによりますと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193036/479270a5-0f4c-a165-bd7b-baa461391560.png)

まさにこれに引っかかっていました。
ChromeはそもそもこのFakeルート証明書を見せてくれず、悩みまくっていました。Safariでは「証明書のFakeルート局なんて信頼してないからダメ」って教えてくれたから理解できたけど、Chrome中途半端に開いてくれたもんでなかなか気づけなかった。。。

# なぜこのバグを埋め込んだのか
参考にしたサイト間で推奨してくれた認証局が違ったみたい
そもそもLet's Encryptには２つの証明書種別があり

- ステージング用
- 本番用

でACME / server に設定するべきURLが異なります

[Microsoftのcert-manager導入手順](https://docs.microsoft.com/en-us/azure/aks/ingress-tls#verify-a-certificate-object-has-been-created)では本番用を
[cert-managerの導入手順](https://cert-manager.io/docs/configuration/acme/)ではステージング用を

設定する様になっていたのに気づかなかったのでした :joy:

# 対処
ACMEのserverにLet's Encryptの本番用URLを設定する事で回避できます。

- 本番用URL
    - `https://acme-v02.api.letsencrypt.org/directory`

反対にブラウザやその他のツールではNGとされる状態を作りたい場合はステージング用のURLを設定するとたぶん再現できます

- ステージング用URL
    - `https://acme-staging-v02.api.letsencrypt.org/directory`

# おわり
SSLやネットワークが絡むトラブルシューティングは構成が複雑になりがちなのでとってもむずっこいです。。。