OmniAICreator/Qiita-1.07M huggingface dataset:
【MotionBoard】GEO上に経路情報を表示する（登山Ver.）

#目標
iPhoneに無料アプリを入れてGPSデータを取得、経路情報としてMotionBoard上にそのまま表示する

#経緯
お客さまとの雑談の中で「商品を配送する車の経路を描けないかな？」という話が。
実際にやろうとするとハードルが沢山あるがまずは描いて見てみようと。
見ないとイメージ湧かない、アイデアも出ないからねぇ。

#題材
車で高速＋一般道を使って山へ行く～登山

#準備（GPSログアプリ）
・iPhoneにアプリを入れ、設定しておく
　今回こちらを使ってみました。ルートヒストリー。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/4be10274-773b-ba3d-88aa-01e79b559c63.png)

設定はデフォルトでいってみました。
![02A84465-31C0-44C4-9235-ABFC42C27A3A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/027864e8-89a8-7ae8-2090-2b8c60ca9443.png)

・出発時、記録一覧画面から＋クリック、「開始」する
![350A07C6-8F7B-4652-ABD1-6559DEF2D595.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/71701780-9442-c284-500a-6cf2de074f85.jpeg)
![968A4ABB-256B-457B-9FBF-C043D4C79003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/19939612-ec44-87a1-0c01-1750972cc60a.png)

#結果
###登山中
時間も出せるのでルート上をどれくらいで通過したか分かる！嬉しい！のは私だけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/e98283b1-a419-c19f-c51f-ed2e419f1ced.png)

###車で移動してる時
移動速度が速い事を示す青は高速道路、緑は車で一般道、赤は徒歩（登山中）。
車で同じ道を行き来したのでよく見ると時間が重なってる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/6b884a81-c392-852d-0a21-8b33029e1e51.png)

###時速で色分け
MotionBoardのGEO設定のデフォルトでこうなってました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/50881209-05ff-d321-8955-4652d6b5b76d.png)

#MotionBoard設定
###(1)スマホ内データを取得
私はメール添付して自分宛に送りましたが、ビジネスチャットなど導入されていればSNS共有が便利そう。吉原さんご教授ありがとうございます！
やったことはないけどサービスによっては受け取ったファイルをプログラム的処理に流せるのもあるんじゃないかな？そこで後述する課題を解決できれば・・・
![2DB1621D-3362-49B0-8969-AA3CC40C77B4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/d533f97f-0c9e-7dfe-fc30-693eb22768f6.png)


###(2)ボード作成
新規ボードにGEOを起き、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/c880fc88-cea7-9b24-2ed7-66b648b0f17e.png)
適当なデータソースを作成しておいて、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/76585176-7315-8760-7f18-ec52f4497a36.png)
経路情報設定タブで、選択ボタンをクリックし、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/a28ec946-e2bd-a5ad-f36c-2272542d8b02.png)
取得したgpxファイルをアップロードしてOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278265/187de4a4-88ee-1d52-c98c-5da155d4a7ca.png)


#課題
・gpxファイルの時刻は世界標準時のため、日本時間とは+9時間のずれが発生
　　→できるだけ手を掛けたくない、自動化したい。どうするか。

・各スマホに出来るgpxファイルをどう回収する？
　　→環境が整っていれば共有が一番楽？
　　本人が何もしないで回収できるのがいいけどな･･･それはそれで問題になるんかな。

・現場の協力をどうやったら得られるか
　　→いかにも「監視されてる！」と思われそうｗ 
　　見られて困ることをしてるのが問題なんだけど、そんな正論ではとても現場を動かせないだろ。

#MotionBoard Cloud IoT Editionではもっと色々できる！
こちらもぜひご覧ください。MotionBoardマニアからの情報提供です。

MotionBoardオンプレは白地図ですが、Cloudは地図そのものがそもそも良いのだなぁ。
[いやいやオンプレでも地図の種類は増やせるよ！という話はこちら](https://qiita.com/ratsbane666/items/3fd008c11e2a6a340016)

https://data.wingarc.com/iotdata-3557?fbclid=IwAR1UDKA2t0-jTYvRSTxn9jfnLFqsgN3kOz_uyGHultUTekkfHYfZShgrBy4


#ウイングアークのユーザコミュニティ「nest」
私も参加しています。多くの有益な情報があり、交流があります。
世の中が変わり、社外活動の重要性がより増していると考えております。
社外で自分の価値を計れるものさしを持とう。

https://www.wingarc.com/wug-nest/

以上
Service Cloud の効率性 ⇒ モバイルを使用して顧客や従業員とつながる

１．組み込みサービスを使用すると、モバイルアプリケーションに何を配信できますか?
２．モバイルセルフサービスサイトによって顧客がやりやすくなることは次のどれですか?
３．Field Service は、電話からフィールドまで、サービスチームの作業を次のどれによって、よりスマートにしてくれますか?
４．メッセージングは、次のどれによって最新のコンタクトセンターを実現しますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/3ebe4aa9-5a7b-49a6-0738-385c74575e1c.png)
【ジョークアプリ】壊れたファイルを生成するツール

## はじめに
大学の課題が終わらない。そんなことありますよね？
そんな時に役立つツールを開発しました。
<font color="gray">(ジョークアプリです。このアプリの使用により起きたトラブルに当方は一切責任を負いません。)</font>


## 概要
　拡張子、ファイルサイズ、ファイル名を指定することで、あたかも提出する際に壊れてしまったかの様なファイルを作成します。締め切りに間に合わなくてもとりあえず出したという既成事実を得られるのではないでしょうか？
　そんなコードを紹介します。
　まずは雛形であるmain関数を作成し、そこから文字化け作成用の関数をimportすることで動作する仕組みです。

```Python:main.py
import os.path
import mojibake as moji

def main(func):
    file_name = input("ファイル名を入力してください:")
    ext = input("拡張子を入力してください:")
    size = float(input("ファイルサイズを入力してください(MB):"))

    size *= 1024 ** 2
    file_size = 0

    while(size > file_size):
        file = file_name + '.' + ext
        f = open(file, "a")
        f.write(func)
        f.write('\n')
        file_size = os.path.getsize(file)
    f.close()

if __name__ == '__main__':
    main(moji.yabainari)

```
　これは、importした関数に引数を与えるだけのプログラムなので文字化けアルゴリズムであるパッケージは自分で用意する必要があります。mainにあたえる引数を変えてお楽しみください。
　文字化けアルゴリズムの作成例を2つ書きました。

## 例1
　ダイバージェンス1％の向こう側へいけずに、課題提出できなかった人がお使いください。

```Python:mojibake.py
def suzuha(size, file):

    s = '失敗した' # 任意の文字列
    s_size = 18  # 文字列のbyte数

    with open(file, 'w', encoding='utf-8') as f:
        i = 0 
        while size > i:
            f.write(s)
            i += s_size
        else:
            f.write('わたしは失敗した') # 任意の文字列にするときはelse文をコメントアウト

```


このコードの出力結果をテキストエディタで見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679131/e9aff6fd-8ce8-66c7-a089-0e2ea7307bc4.png)

最後だけ処理を変えているため、多少ファイルサイズは変わります。大まかなサイズがあっていればよいでしょう。
pdfビューアで開くとこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679131/8f299b2e-f7aa-5e8c-00e1-24d41f15146c.png)

バッチリ壊れてます。
メモ帳で開かれたら失敗したどころではなくいろいろと終わります。
任意の文字列とそのサイズに書き換えることで好きな言葉でファイルを埋められますが、教授への悪口などは絶対にやめましょう。　

## 例2
　例1では文字化けと言うより、テキストファイルを拡張子を変えて開くことで、あたかも壊れているかのように見せるコードでした。例2ではよりリアルな文字化けを引き起こすプログラムを作成しました。そんなコードがこちらです!

```Python:mojibake.py

def yabainari(size, file):
    import struct, random

    with open(file, 'wb') as f:
        for i in range(0, int(size)):
            f.write(struct.pack('B', random.randint(0, 255)))
```
ランダムなbit列を作成して、バイナリモードで書き込むことで文字化けを引き起こします。

実際に出力結果をテキストエディタで見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679131/e815bf7f-36fe-afd2-919c-6f931c329190.png)

完璧ですね。もちろんpdfビューアでも開けません。


## まとめ
　こんなコード書いてる暇があったら、課題にとりかかりましょう。
今回のコードはgithubにものせています　-> https://github.com/yoh333/broken_maker



最後に一言…  

<B>    課題は期限内に!(戒め)
MYSQLdbのexecuteメソッドに文字列を代入する時の注意点

メモ帳がわりの記事

http://blog.yuku-t.com/entry/20090622/1245691874

python側のコードから直接SQLを書いてMySQLに投げる時の注意点

これはエラーにならない

```  python3
hoge = 1
cursor.execute("""
            SELECT 〜いろんなカラム〜
            FROM てーぶる名
            WHERE カラム1=%s
            ;
        """, (hoge,))
```

これはエラーになる

``` python3
hoge = ' IN (0, 1)'
cursor.execute("""
            SELECT 〜いろんなカラム〜
            FROM てーぶる名
            WHERE カラム1%s
            ;
        """, (hoge,))
```

下記のようなエラーが表示される。改行コード\nが含まれている。
文字列が入ると改行コードも含まれてしまうようになる？
（よくわからないので、詳しい人は教えていただきたい

```
django.db.utils.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''=1 '\n            AND latitude IS NOT NULL\n            AND カラム1 IS NOT NULL' at line 4")
```

なので下記のようにするとよい。
**重要なポイントは先にquery文を変数に格納することだそうです。** （query = f"""のところ）

``` python3

        hantei = True
        hoge = ' IN (0, 1)' if hantei else ' =1 '

        query = f"""
            SELECT いろんなカラム
            FROM テーブル名
            WHERE カラム1{hoge};
        """

        cursor.execute(query)
```

文字列を入れると改行コードを急に含むようになるとか、その辺り良い感じにやってほしい（文句）
この記事と関係ないけどf''''''はとても便利
WinodwsServerのディスクの拡張

# はじめに
AWSやAzureでは、それぞれの管理画面でディスクを拡張しても、サーバにすぐに認識されるわけではなく
サーバでディスクを認識させなければならない。
今回は、サーバのOSバージョンごとに拡張の方法を説明する。

# Windows2016
コントロールパネルからコンピュータの管理　画面を開く

ディスクの管理を選んで、右クリックをして、最新の情報に更新を押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/b4aa2b56-31c1-f14e-729e-7a6079264a53.png)

ディスクが表示される。拡張した５０GBは、まだ利用できない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/19d9378b-5993-f371-c162-405446eb7dc1.png)

ボリュームの拡張を選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/2dd77ab9-2f81-04c1-0f94-4f86618ded16.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/6694bc19-fe56-d8f2-5d66-ccd8267f05a2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/bacbf7a5-d6cc-b06d-9456-4ee778d163d3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/c9acb067-24f2-91f6-e06a-65e5a8185d67.png)

ディスクが拡張される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47172/63af3558-9499-c90d-a299-b7a38e9166f0.png)
Nuxt.jsでGoogleFontを使用する方法


Nuxt.jsでGoogleFontsを使用するには
**nuxt-webfontloader**という、パッケージを使う事でとても簡単に導入出来るため、
こちらのパッケージを利用します。

#1.パッケージをインストールする

まずは、パッケージをインストールしていきます。

```
#webfontを使用するためのパッケージ
$ npm install nuxt-webfontloader
```

#2. nuxt.config.jsにモジュールを追加する

インストールがされたら、nuxt.config.jsに設定を追記していきます。

```ruby:nuxt.config.js
export default {

    ...

    modules: [
        'nuxt-webfontloader'
    ],

    ...

    webfontloader: {
		google: {
			families: ['使用するフォント名', '使用するフォント名2', ...] 
		}
	}
    ...
}
```

#3.あとはCSSに追記するのみ

最後に、フォント名をCSSに記述すれば反映されます。

```ruby:example.scss
h1 {
  font-family: '使用するフォント名';
}
```
MySQLであるデータベースのテーブルの行数をテーブル毎に表示するSQL文

#備忘録なので

```
SELECT table_name, table_rows
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '<database_name>';
```

[参考](https://stackoverflow.com/questions/286039/get-record-counts-for-all-tables-in-mysql-database)
ffmpegで、ストリーミングビデオをダウンロードする

## はじめに

`YouTube`のビデオは、`youtube-dl`でダウンロードすればよい。
そのほかのストリーミングビデオを、どうやってDLすればいいかわからなかった。

`ffmpeg`を使うとかんたんらしい。URLを拾うのが（ウェブサイトのソースコードを読んでも）わからないことがあって、Chrome拡張の`Video Downloadhelper`を使った。


## 環境

ここで書いていることは、下記のバージョンで実施しました。

- Video DownloadHelper バージョン 7.5.0.3
- Google Chrome バージョン: 89.0.4389.114（Official Build）
- macOS BigSur 11.1


## 手順

### インストール（詳細略）

- ffmpeg
- Video DownloadHelper

### ストリーミングビデオのダウンロード

- Google Chromeで、DLしたい動画のURLを開く
- Video DownloadHelperで「URLのコピー」

![SS 2021-04-12 16.37.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/cc542130-e369-8a47-1f23-748f54f6faa8.png)


- コピーしたURLを下記に入れる

```bash
$ ffmpeg -i "<ここにコピーしたURL>" -c copy -bsf:a aac_adtstoasc rec.mp4
```

※`rec.mp4`は適当に。拡張子を見て変換は自動的にやってくれる（らしい）。`-bsf:a`のところは、参考にしたサイトのパクリで、考えはじゅうぶんでない。


## リソース


[ffmpeg を使い、HTTP Live Streaming(HLS)をファイルに保存し、保存したファイルからストリーミングを行う方法について][01]

を参考にした。理解不足かもしれないが、URLのところは`""`で括らないとうまく動かなかった。

[01]: https://qiita.com/uupaa/items/c76c76cb149470bf89f2
【GCP】環境変数の設定方法について

#GCPで環境変数を使用するシチュエーション
・プロジェクトIDを環境変数に格納し管理しやすくする（打ち間違いを防ぐことも）

#設定方法
```
export environmentVariable=格納したい値
```


（例）

```
export environmentVariable=projectID1234567890
```

#確認方法
確認はechoコマンドで確認可能
変数名の前に**$を付けること**に注意。

```
echo $environmentVariable
```

出力結果

```
projectID1234567890
```
PHP-CS-FIXERでコマンドライン引数でパスを指定すると構成ファイルのパスが無視される


タイトル通り。

## 環境

PHP-CS-FIXER: 2.18

## 内容

> By default --path-mode is set to override, which means, that if you specify the path to a file or a directory via command arguments, then the paths provided to a Finder in config file will be ignored. You can use --path-mode=intersection to merge paths from the config file and from the argument:

PHP-CS-FIXERでコマンドライン引数でパスを指定すると構成ファイルのパスが無視される。

ちなみに、オーバーライドする状態で実行すると、 *Paths from configuration file have been overridden by paths provided as command arguments.* が出力される。

## 所感

- コマンドライン引数と構成ファイルのパスをマージしたいユースケースが思い浮かばない。基本的に構成ファイルで管理して、コマンドはシンプルにしておくべきだろう。

## 参考

- [PHP-CS-Fixer/usage.rst at 2.18 · FriendsOfPHP/PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/2.18/doc/usage.rst)
String変数の比較

# String変数を比較する場合の注意点  
Javaの学習で、String型変数を比較する場合の処理が分かり辛かったので復習のために記事にしてみます。

## 関係演算子(==)で比較してみる

String型変数を関係演算子（==）で比較する場合の挙動を下記のコードで一度確認してみましょう。

``` JAVA
String a = "hoge";
String b = new String("hoge");
String c = "hoge";
String d = b.intern();

System.out.println("a = b : " + (a == b));
System.out.println("a = c : " + (a == c));
System.out.println("a = d : " + (a == d));
System.out.println("b = d : " + (b == d));
```
変数aはnewを使用していないため、Stringが管理する領域に文字列("hoge")が作成され、参照されます。  

変数bはnewを使用しているため、ヒープ領域に文字列("hoge")が作成され、参照されます。  

変数cは変数aと同じく、newを使用していないため、Stringが管理する領域の文字列("hoge")を参照を参照します。  

※変数aの作成時にStringが管理する領域に"hoge"が生成されているため、変数cの作成時は同じものを参照するようになります。

変数dは変数bに対してintern()メソッドを使用した値を代入していますが、intern()メソッドは参照先ではなく参照先の値を返しているため、Stringが管理する領域に同じ文字列が存在しないか確認し、存在する場合はその領域を返します。  
  
### 実行結果
``` JAVA
a = b : false
a = c : true
a = d : true
b = d : false
```

実行結果  
1行目：変数aとbが比較されますが、参照先が違うため（aはStringの領域、bはnewで作成されたため別の領域）falseになります。

2行目：変数aとcは同じ参照先（Stringの領域の"hoge"）なので、trueになります。

3行目：変数aとdは同じ参照先（Stringの領域の"hoge"）なので、trueになります。

4行目：変数bとdされていますが、参照先が違うため（bはnewで作成された領域、dはStringの領域）falseになります。

このように参照型変数を関係演算子(==)で比較する場合、参照先の値ではなく参照先が比較され、同じ参照先の場合にtrueを返します。  

## equals()メソッドを利用してみる
関係演算子(==)を利用するだけではString型変数の参照先の値では比較できないのでequals()メソッドを利用して参照先の値で比較を行ってみます。

``` JAVA
String a = "hoge";
String b = new String("hoge");
String c = "hoge";
String d = b.intern();

System.out.println("a.equals(b) : " + (a.equals(b) ) );
System.out.println("a.equals(c) : " + (a.equals(c) ) );
System.out.println("a.equals(d) : " + (a.equals(d) ) );
System.out.println("b.equals(d) : " + (b.equals(d) ) );
```
### 実行結果
``` JAVA
a.equals(b) : true
a.equals(c) : true
a.equals(d) : true
b.equals(d) : true
```

equals()メソッドでは参照先の値を比較しているため、全てtrueとなります。

## まとめ
* 参照型変数（String等）を関係演算子（==）で比較すると参照先の値ではなく、参照先が一致しているかを比較する。
* 参照型変数をnewを使って生成すると、値が同じものでも別の領域に値が生成されて参照される。
* String型変数の参照先の値を比較したい場合はequals()メソッドを利用すれば比較できる。
terminalからregistry.gitlab.com にdocker loginするときのエラー

## 概要

久しぶりにPCをフォーマットし、gitlabのコンテナレジストリに再度ログインしようとしたとき、
はまりました。。

terminalからregistry.gitlab.com にdocker loginするとき

```
Error saving credentials: error storing credentials - err: exit status 1, out: `Error calling StartServiceByName for org.freedesktop.secrets: Timeout was reached`

```

もしくは

```
Error response from daemon: Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password
````

などのエラーになる。


## 解決策

```
sudo apt install gnupg2 pass
```

上を実行することが必要でした、、、
PCをクリーンインストールしたあとなどは注意すること。
「Grid」を使用した聖杯レイアウト

「Grid」を使用した聖杯レイアウトについてまとめました。
※使うメリットはdivタグの使用頻度が減り、コードが見やすい。

完成形
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1162001/3957bf2b-3062-f54d-0f82-16874d8bd38d.png)

HTML
====
親子関係を作ること。
親のclassに「グリッドコンテナー」(grid-container)を指定し、レイアウト対象である「グリッドアイテム」を囲む。

```html
<div class="grid-container">
  <header>ヘッダー</header> 
  <nav>ジャンル</nav>
  <main>メモ</main>
  <aside>辞書</aside>
  <footer>フッター</footer>
</div>
```

CSS
====
**グリッドライン**で分割をする。

![スクリーンショット 2021-04-12 15.52.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1162001/cc3d2e1c-14f3-9dd1-46b5-59660884987c.png)

**親クラス**

- display: grid;を記述。
- 横を分割し、グリッドラインを作る。
　grid-template-columns: 1fr 3fr 1fr;
- 縦を分割し、グリッドラインを作る。
　grid-template-rows:1fr 6fr 1fr;

※今回はfr（比率）で区切る。px、%でもOK！



**グリッドアイテム**
区切ったグリッドラインの範囲を数値で指定する。

- 横は、**grid-column: 始まりのライン / 終わりのライン;**
- 縦は、**grid-row: 始まりのライン / 終わりのライン;**


```css
.grid-container {
  display: grid;
  grid-template-columns: 1fr 3fr 1fr;
  grid-template-rows:1fr 6fr 1fr;
  height: 100vh;
}

header {
  grid-column: 1 / 4;
  grid-row: 1 / 2;
  background-color: #E6FFE9;
}


article {
  grid-column: 2 / 3;
  grid-row: 2 / 3;
  background-color: white;
}


nav {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
  background-color: #EEEEEE;
}

aside {
  grid-column: 3 / 4;
  grid-row: 2 / 3;
  background-color: whitesmoke;
}

footer {
  grid-column: 1 / 4;
  grid-row: 3 / 4;
  background-color: #E6FFE9;
}
```

引用　https://goodsan.jp/wp/gridholy/

プログラミング初心者です。色々ご指摘頂けると幸いです。
【M1 Mac】zsh: command not foundと出た時の解決策。

M1 Macだと`zsh: command not found`というエラーが発生することがあると思います。

このようなときはパスを通しましょう。

ではまずはパスの確認から。

```
echo $PATH

//実行結果
/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```

これで`/opt/homebrew/bin`がないなら、パスを通す必要があります。


まずは自分の使ってるシェルを確認しましょう。

```
echo $SHELL

//実行結果（下記のどちらかが表示されるはず。）
~/.zshrc
~/.bash_profile
```

上記で表示されたファイルを下記コマンド開く。

```
vi ~/.zshrc
```

ちなみに`open ~/.zshrc`コマンドで開いても良い。

これで下記を追加。

```
export PATH=/opt/homebrew/bin:$PATH
```

そして、更新。

```
source ~/.zshrc
```

これでOK。

これでもダメならすいません、わかりません、、、m(__)m

## これでも上手くいかなかった人へ

この記事の通りにやっても、上手くいかない人は『[【解決済み】Error: Cannot install in Homebrew on ARM processor in Intel default prefix (/usr/local)!のエラーを解消する方法](https://shiro-changelife.com/error-cannot-install-in-homebrew/)』を一度読んでみてください。

今回の`zsh: command not found`が出るのはM1 Macの人が多いはずです。

m1 macからhomebrewのインストール先のディレクトリが変更になった（推奨される場所が変わった）のが原因です。

そして、もしhomebrewが2つインストールされている場合は、パスの優先度が原因でエラーが発生している可能性が高いです。

わからない人はTwitterとかで質問くれても良きなので、頑張ってください！！！
Service Cloud の効率性 ⇒ 双方向のデジタルメッセージングへの移行

１．双方向モバイルメッセージングがカスタマーサービスの新しい流れである理由は次のどれですか?
２．企業にとっての双方向メッセージングの利点は次のどれですか?
３．Service Cloud メッセージングは、最先端の双方向カスタマーサービスメッセージングです。その特長は次のどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/bda7d9c1-cdb9-31d9-96bd-770cff92dc70.png)
php-fpm + apache環境での環境変数の持たせ方

php-fpm環境下でApache httpdのSetEnvで設定された環境変数は、PHPの`env()`等では取得できるが、
**execで実行されるコマンドには、SetEnvで設定された環境変数が反映されなかった**のでfast-実施した回避策を書く！

## 要約
- ApacheのSetEnvは使わず`/etc/environment`に環境変数を記載して利用する

## `/etc/environment`の環境変数利用手順
### `/etc/systemd/system/httpd.service`を作成
- 以下内容で作成する

```
.include /lib/systemd/system/httpd.service

[Unit]
After=network.target remote-fs.target nss-lookup.target httpd-init.service cloud-config.service

[Service]
UMask=002
EnvironmentFile=/etc/environment
```

### `/etc/systemd/system/php-fpm.service`を作成
- 以下内容で作成する

```
.include /lib/systemd/system/php-fpm.service

[Unit]
After=syslog.target network.target cloud-config.service

[Service]
UMask=002
EnvironmentFile=/etc/environment
PrivateTmp=false
```

### `/etc/php-fpm.d/www.conf`に1行追加
- 以下を追記

```
clear_env = no
```

あとは`/etc/environment`に環境変数を記載していくだけ！
MacでDockerエラー：Couldn't connect to Docker daemon. You might need to start Docker for Mac.

Dockerについて何の知識もないのでありのままを書きます。

## コマンドを実行しようとしたらエラーが出た

入力したコマンドはこれ

```
$docker-compose build
```

出てくるエラーメッセージは以下のとおり

```
Couldn't connect to Docker daemon. You might need to start Docker for Mac.
```

他のコマンドを入力しても同様でした。

## 原因と解決策

Dockerアプリが起動していませんでした。

Macの上のバーにクジラがいなければ動いてないです。

なので解決するにはDockerを起動させるだけ。

初心者あるあるだといいなぁ。
【Terraform】 countからfor_eachへ書き換えたらスプラット演算子の動きが変わった

いままで`count`で記述していたものを`for_each`に直してみたところスプラット演算子の動きが変わったのでメモ

## 状況
いままではVPCのサブネットリソースを`count`で複数作ってそれを`output`で他のモジュールに渡して利用しておりました

```tf
resource "aws_subnet" "private_data" {
  count                   = length(var.azs)
  vpc_id                  = aws_vpc.vpc.id
  cidr_block              = cidrsubnet(aws_vpc.vpc.cidr_block, 8, 11 + count.index)
  availability_zone       = element(var.azs, count.index)
  map_public_ip_on_launch = false
}

output "data_private_subnets" {
  value = aws_subnet.private_data
}
```

他のモジュールで使うときはこんな感じで使ってた

```tf
resource "aws_db_subnet_group" "db" {
  name        = "${var.name}-${terraform.workspace}-db-subnet"
  description = "Database Subnet Group for ${var.name}-${terraform.workspace}"
  subnet_ids  = var.data_private_subnets[*].id # この部分
}
```

そんでもって、`for_each`を使って書き直したのがこちら

```tf
resource "aws_subnet" "private_db" {
  for_each          = var.azs
  cidr_block        = cidrsubnet(aws_vpc.vpc.cidr_block, 8, index(values(var.azs), each.value) + 11)
  availability_zone = each.value
  vpc_id            = aws_vpc.vpc.id
  map_public_ip_on_launch = false
}
```

すると以下のようなエラーが出るようになった

```tf
Error: Unsupported attribute

  on modules/aws/database/subnet_group.tf line 4, in resource "aws_db_subnet_group" "db":
   4:   subnet_ids  = var.data_private_subnets[*].id

This object does not have an attribute named "id".

```

## Issue
とりあえずIssueを漁ってみたら以下が見つかった

https://github.com/hashicorp/terraform/issues/22476
https://github.com/hashicorp/terraform/issues/23245

Issueを読んでみると以下のように修正すれば大丈夫っぽいことがわかった
>The short answer is that if you were to modify your code to values(aws_route53_record.record)[*].fqdn it will work as you're expecting it to.


## 修正
Issueに書いてあるとおり、`aws_db_subnet_group`のリソース作成部分を以下のように修正したら問題なく動くようになった

```tf
resource "aws_db_subnet_group" "db" {
  name        = "${var.name}-${terraform.workspace}-db-subnet"
  description = "Database Subnet Group for ${var.name}-${terraform.workspace}"
  subnet_ids  = values(var.private_subnets_db)[*].id # この部分
}
```

## おわりに
`for_each`便利だけど思わぬ落とし穴？にハマってしまいました
WindowsPCで、OS以外のパッチ適用していますか？


企業でWindowsPCを導入している場合、WSUSなどで修正プログラムの適用状態を監視しているはずです。
しかし、Intelの脆弱性、ドライバなどの修正プログラムも修正、監視してますか？

https://www.dell.com/support/kbdoc/ja-jp/000178282/intel-me-txe-advisory%E3%81%AE%E3%83%87%E3%83%AB-%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88-%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%A1%E3%83%B3%E3%83%88-intel-sa-00086

https://jvndb.jvn.jp/ja/contents/2017/JVNDB-2017-010519.html

例えば、上記dellのPCの上記脆弱性は以下の深刻度となっています。
CVSS v3 による深刻度 基本値: 7.8

比較としてMSから提供されたい以下の脆弱性は 7.5となっており、上記脆弱性よりも脅威度が低く設定されています。

https://jvndb.jvn.jp/ja/contents/2021/JVNDB-2021-001268.html

Dellだけではなく、IntelMEの脆弱性のため、各社のPCで同様の脆弱性が存在します。

このような修正は、統合管理がされていないことが多く漏れていることが多いのではないかと考えて、記事にしてみました。
VBOXManage.exe

```
C:\"Program Files"\Oracle\VirtualBox\VBoxManage.exe

VBoxManage.exe list vms
VBoxManage showvminfo [仮想マシン名]
VBoxManage showvminfo [仮想マシン名] | findstr "host port"
```

https://note.mokuzine.net/virtualbox-cmd/#%E4%BB%AE%E6%83%B3%E3%83%9E%E3%82%B7%E3%83%B3%E3%81%AE%E7%8A%B6%E6%85%8B%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B
Djangoで作成したアプリをHerokuにデプロイする際の環境変数の扱い

## 環境変数の扱いについて
自分自身も完全に忘れていたため、投稿。

settings.pyにSECRET_KEYなどを直書きして、そのままgitなどにpushすると、漏洩の問題が出てきます。
そこで環境変数を用いて、管理することができます。

django-environをインストールして使用します。

```
$ pip install django-environ
```

Djangoプロジェクトのmanage.pyがある階層に.envファイルを作成して、その中に変数を書いていきます。

```python:.env
SECRET_KEY=xxx # settings.py内の値を代入
```

local環境では、先ほど作成した.envファイルを読み込み、記述した変数を使用します。

```python:settings.py
import environ

if not HEROKU_ENV:
    env.read_env('.env')
SECRET_KEY=env("SECRET_KEY")
```

この.envファイルは.gitignoreに追加しておきます。

```python:.gitignore
.env
```

ローカル環境では、これで環境変数を読み込むことができます。
しかし、.envファイルは追跡対象から外しているため、Heroku環境では使用することができません。
そのため、下記コマンドでherokuの環境変数に追加する必要があります。

```shell:
$ heroku config:set SECRET_KEY=xxx # settings.py内の値を代入
```

これで、Heroku環境でも環境変数を使用することができます。
RuboCop::Cop::Style::GlobalStdStream違反になったとき

## 現象
rakeタスクでログ出力させるときに

```
    logger = Logger.new(STDOUT)
```
と書いたら `RuboCop::Cop::Style::GlobalStdStream` rubocoopに怒られた。

```
C: [Correctable] Style/GlobalStdStream: Use $stdout instead of STDOUT.
```

## 対応

https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/GlobalStdStream

ドキュメントを読むと
`STDOUT/STDERR/STDIN` are constants, and while you can actually reassign (possibly to redirect some stream) constants in Ruby, you'll get an interpreter warning if you do so.

つまり、STDOUTにログを追記していくのって、定数に再割り当てしてるのと同義のようで、インタープリターから警告が出るっぽい。よってグローバル変数 `$stdout` を使うほうがベター。

```
    logger = Logger.new($stdout)
```
Linuxコマンド覚書

# ディレクトリ削除  
rmdirコマンドは、空のディレクトリを削除するコマンドである。  
ディレクトリにファイルが存在する場合は以下を実行する。  

```  
$ rm -f [ディレクトリ名]  
```  

# 標準出力と標準エラー出力  
```  
$ [command] 2>&1  
```

# 何も出力しない  
```
$ [command] > /dev/null 2>&1
```
Javascript で PDFのページ数を取得するだけの処理(PDF.js)

###Javascript で PDFのページ数を取得するだけの処理(PDF.js)

```javascript
	function fToBase64Convert(file) {
		return new Promise((resolve, reject)=>{
			const reader = new FileReader();
			reader.onload = () => {
				resolve(reader.result);
			}
			reader.onerror = reject;
			reader.readAsArrayBuffer(file);
		});
	}

	function getPdfPageNums(file){
		return new Promise(async(resolve, reject)=>{
			try{
				pdfjsLib.GlobalWorkerOptions.workerSrc ="https://cdn.jsdelivr.net/npm/pdfjs-dist@2.7.570/build/pdf.worker.min.js";
				var base64FObj = await fToBase64Convert(file);
				var pdfobj = pdfjsLib.getDocument({data: base64FObj });
				pdfobj.promise.then(function(pdf) {
					resolve(pdf.numPages);
				});
			}catch(e){
				resolve(-1);
			}
		});
	}

	var pdfPageNums = await getPdfPageNums(ファイルオブジェクト);
TeX で目次を作ろう

TeX では以下のように簡単に目次を作成することができる。例えば、以下のように。

```main.tex
\documentclass{jsbook}
\nofiles
\pagenumbering{roman}
\begin{document}
\tableofcontents
\end{document}
```

TeX の目次は table of contents(toc) ファイルに記述する。

```main.toc
\contentsline {chapter}{Hello TeX}{1}
\contentsline {chapter}{\numberline {Chapter 1}hoge}{1}
\contentsline {section}{\numberline {1.1}hogehoge}{2}
\contentsline {chapter}{\numberline {Chapter 2}huga}{4}
\contentsline {section}{\numberline {2.1}hugahuga}{5}
```

以上の2ファイルを同じディレクトリに置き、コンパイルすればok。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546197/425adfc8-b55d-6acb-3123-9cca62c45824.png)
Macでフォルダ内のファイルのmd5ハッシュ一覧を取得する


gnu-sed を brew install した後、

```bash
ls | xargs md5 | gsed -r 's/^(.+)( = )(.+)$/\3/'
```

これでOK。

```
52678b54e48683beacb75bec1994c993
5a08a62f419bf58ea622aadf00d33264
7618fb41478ec94684ddd301fedc4354
146ba4cd0f30fbdd580828e70f1555ad
```

こんな感じに表示される。
Gitのブランチ、Headとは

GitのHeadとは何か？
結論を言うと、今自分が作業しているブランチを指すポインタ。

では、ブランチとは何か？
結論を言うと、各開発フローの中で最新のコミットを指すポインタ。  

ということは、Headとは、今作業している最新のコミットを指すポインタのポインタ。
配列に要素を動的に追加するプログラム(Java)

#はじめに
Javaで配列に要素を追加するプログラムをメソッドの形にまとめて投稿したいと思います．「Java　配列　要素　追加」と検索しても、Pythonの```append()```などのように要素を追加すると，それに伴って大きさも増えてくれるメソッドなどがなさそうなのかなと思ったので，備忘録も兼ねて残します．

Javaの```List<>```とか使って```.add()```などを利用すれば，やりたいことは実現できそうなのですが，```List<>```を使わずに動的な要素追加ってできないだろうかと考えて書いてみました．

#コード
##確認用のコード
実行したら要素を追加する前の配列と追加した後の配列を標準出力するプログラムです．

```Main.java
class Main{
	public static void main(String[] args){
		// 追加対象の配列
		int[] oldArr = {0, 1, 2, 3, 4};
		// 追加したい要素
		int newElement = 5;
		// 追加後の配列を格納する配列
		int[] newArr;
		// forを回すための制御変数
		int n;
		
		// 追加前の配列を表示
		System.out.println("追加前の配列");
		for(n = 0 ; n < oldArr.length ; n++){
			System.out.println(oldArr[n]);
		}
		
		// 要素を追加する関数を実行
		// ここで配列に要素が追加されてます．
		newArr = AddElement(oldArr, newElement);
		
		// 追加後の配列を表示
		System.out.println("追加後の配列");
		for(n = 0 ; n < newArr.length ; n++){
			System.out.println(newArr[n]);
		}
	}
	
	// 追加前の配列と追加したい要素を受け取って，追加後の配列を返すメソッド
	public static int[] addElement(int[] oldArr, int newElement){
		// 追加後の配列を宣言
		// 大きさは追加前の配列の大きさより1だけ大きい
		int[] newArr = new int[oldArr.length + 1];
		
		// 追加後の配列に追加前の配列をコピー
		// ここの処理が肝
		System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);

		// 追加後の配列の末尾に追加したい要素を代入
		newArr[oldArr.length] = newElement;
		
		// 追加後の配列を返却
		return newArr;
	}
}
```

「要素を追加して追加後の配列を返すメソッド」だけを利用する場合は，下のように```AddElement()```の部分をコピペしていただければと思います．

```AddElement.java
class AddElement{
	public static int[] addElement(int[] oldArr, int newElement){
		int[] newArr = new int[oldArr.length + 1];
		System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
		newArr[oldArr.length] = newElement;
		return newArr;
	}
}
```

また，今回は配列の中身の変数型が```int```ですが，必要でしたら```int[]```の```int```の部分を```String```や```double```などに変えて文字列配列や```double```配列などに変えてください．

##実行結果
実行するとこんな感じになります．

```
追加前の配列
0
1
2
3
4
追加後の配列
0
1
2
3
4
5
```

#おわりに
Javaの```List```以外で配列に要素を追加するプログラムを書けないかなと思って書いてみました．もしかしたら```List<>```を呼び出して```List<>```を配列にキャストして返した方が速いプログラムかもしれませんが，すみませんそこまでは試してないです泣

「Java　配列　要素　追加」で検索しても「Listを使わずにやる方法ってないのかなあ」とか「要素の大きさを追加に伴って自動的に増やしたいんだけど別の方法ないのかな」といった風に感じられていらっしゃる方に貢献出来たらと思います．
RxSwiftのSubjectとRelayについて簡単にまとめる

## はじめに
RxSwiftの勉強を始めてObservableについてある程度理解できたので、まとめとして残しておきます。

## BehaviorSubject
BehaviorSubjectは初期値を設定することができ、onNext, onError, onCompleteの3つのイベントを流すことができます。

``` Swift
        //初期値に0を設定、Intが流れるストリームを作成
        let behaviorSubject = BehaviorSubject<Int>(value: 0)
        
        //ストリームを購読して、流れてきたイベントに応じた処理を定義
        behaviorSubject
            .subscribe(onNext: { value in
                print(value)
            }, onCompleted: {
                print("onCompleted")
            })
            .disposed(by: bag)
        
        behaviorSubject.onNext(1)
        behaviorSubject.onNext(2)
        behaviorSubject.onNext(3)
        behaviorSubject.onCompleted()
//        0
//        1
//        2
//        3
//        onCompleted
```

(エラーは流れないのでonNextとonCompletedの場合だけを定義しています)

## PublishSubject
PublishSubjectは初期値の設定ができず、イベントはonNext, onError, onCompleteの3つのイベントを流すことができます。


```Swift
        let publishSubject = PublishSubject<Int>()

        //イベントが流れてきたときの処理
        publishSubject.subscribe { value in
            print(value)
        }
        .disposed(by: bag)

        //onNextでイベントを流せる
        publishSubject.onNext(1)
        publishSubject.onNext(2)
        publishSubject.onNext(3)
        publishSubject.onCompleted()

//        next(1)
//        next(2)
//        next(3)
//        completed
```

## BehaviorRelay
BehaviorRelayは初期値を設定することができ、イベントはonNextのみ流れます。

```Swift
        let behaviorRelay = BehaviorRelay<Int>(value: 0)
        
        behaviorRelay
            .subscribe(onNext: { value in
                print(value)
            })
            .disposed(by: bag)
        
        behaviorRelay.accept(1)
        behaviorRelay.accept(2)
        behaviorRelay.accept(3)
        
//        0
//        1
//        2
//        3
```

RelayはonNextではなくacceptでイベントを流します。

## PublishRelay
PublishRelayは初期値の設定ができず、イベントはonNextのみ流れます。

``` Swift
        let behaviorRelay = PublishRelay<Int>()
        
        behaviorRelay
            .subscribe(onNext: { value in
                print(value)
            })
            .disposed(by: bag)
        
        behaviorRelay.accept(1)
        behaviorRelay.accept(2)
        behaviorRelay.accept(3)
        
//        1
//        2
//        3
```

## 使い分け
- Subject  
  通信処理等でエラー処理を行いたいとき

- Relay  
  UIに表示するデータを格納するとき
AWSサーバーにおけるデプロイの方法(AWS EC2、Unicorn、Nginx)

今回の記事ではデプロイの概要と反省をしていきます。


# AWSを用いたデプロイまでの流れ

EC2の初期設定(IPアドレスの取得)
　　　　　↓
データベースの設定(mariaDB)
　　　　　↓
EC２のRailsを起動(Unicorn)
　　　　　↓
Webサーバーの設定(Nginx)
　　　　　↓
自動デプロイの設定（Capistrano）

# 大変だったこと

初期設定で生成したインスタンスを再起動すると、起動していたDB、サーバーが停止してしまっています。そのため、IPアドレスをブラウザに貼っても、画面遷移する事ができずエラーになってしまいます。そのため、EC2からCapistranoまでは一蓮托生であるということを忘れないようにする。
##Cookieとセッションについて

###〜アウトプットメモ〜
##前提知識
・HTTPの理解必要
・リクエスト、レスポンスなどの理解
・HTTPはリクエストし、レスポンスする、この1往復で通信が切断される→以前の状態を全く覚えていない。これを**ステートレス**と言う。
・ステートフルにするには、サーバーがクライエントに対して識別できる一意の値を渡し、クライエントはリクエストする時にその値を教えてあげればサーバー側で識別できるようになる。この役割を果たしているのが**Cookie(クッキー)**。
##Cookieについて
・クライアントに保存された情報のこと
<初回>
①リクエスト
②レスポンス（Cookieを保存してください）
③レスポンスの指示に従い、パソコンにCookieを保存
<2回目>
①リクエスト（保存しているCookieの情報も送信）
②レスポンス
・具体的にサーバーはレスポンスメッセージにSet-Cookieヘッダを付与することで、クライエントに対して「Cookieを保存してください」と指示する事が可能。Set-CookieヘッダにはCookieの有効期限やCookieを送るドメイン、有効パスなどの各属性があり。
・クライアントは、リクエストメッセージにCookieヘッダを付与する事で、
「このようなCookieが保存されています」と教える。
・Set-Cookieヘッダの定義
setcookie(Cookie名, Cookie値, 有効日時, パス, ドメイン, HTTPS接続のみ, Javascript無効）
・PHPでCookieを取得する
`$_COOKIE = array(
    'name' => 'sato';
)`
`$name = $_COOKIE['name'];
echo $name;`
連想配列に格納された値を取得するときは`$変数名[キー]`のように記述する。
##セッションについて
・セッションとは、**一連の処理の始まりから終わりまでを表す概念のこと。**
・PHPでセッション開始するには`session_start();`関数を利用します。
・セッションを管理するには、Cookieに一意の値を入れて、リクエストしてもらうことで、一連の処理として扱える。この一意の値の役割をするのがセッションID。
・`session_start()`を記述だけで、自動でセッションIDを発行してくれる。

**<リクエストメッセージにセッションIDがない場合>**
・セッションIDを発行し、セッションIDをCookieに保存するようにレスポンスメッセージを送信
・セッションIDを発行する時に、サーバー側ではセッションIDごとにセッションファイルを作成

**<リクエストメッセージにセッションIDがある場合>**
・セッションIDがあれば、該当するセッションファイルにある情報を参照
Arch Linuxでインストールされてるカーネルの一覧を取得する

# mkinitcpioのプロファイルを調べる

```bash
find /etc/mkinitcpio.d/ -name "*.preset" -type f -printf "%f\n" | cut -d . -f 1
```

```bash
ls /etc/mkinitcpio.d/ | sed "s|.preset||g"
```

# /bootのカーネルファイル

```bash
find /boot -maxdepth 1 -mindepth 1 -name "vmlinuz-*" -printf "%f\n" | sed "s|vmlinuz-||g"
```

# /bootのinitramfs
```bash
find /boot -mindepth 1 -maxdepth 1 -name "initramfs*" -printf "%f\n" | sed "s|initramfs-||g; s|.img||g" | grep -vE "\-fallback$"
```

# /usr/srcのカーネルのやつ
```bash
find /usr/src -mindepth 1 -maxdepth 1 -type l -name "linux*" -printf "%f\n" | sort
```
YouTubeに3秒巻き戻し／早送りボタンを追加するブックマークレット

```js
javascript:(()=>{const e=document.createElement("div");e.setAttribute("class","🔘"),e.textContent="＜",document.body.appendChild(e);const t=document.createElement("div");t.setAttribute("class","🔘"),t.textContent="＞",document.body.appendChild(t);let n=document.getElementsByClassName("🔘");n=[].slice.call(n);const o=e=>{const t=n.indexOf(e.target);document.getElementsByTagName("video")[0].currentTime+=3*(2*t-1)};for(let e=0;e<2;e++)n[e].style.cssText="z-index:99999;position:fixed;bottom:120px;"+`right:${20-60*(e-1)}px;`+"color:#222;font-size:10pt;text-align:center;height:50px;width:50px;line-height:50px;border-radius:50px;border:1px solid #aaa;background:#eee;opacity:.5;user-select:none;-webkit-user-select:none;",n[e].addEventListener("click",o);document.body.style.touchAction="manipulation",document.styleSheets.item(0).insertRule("c3-material-button {pointer-events: none}",0)})();
```

# これは何？

スマホで動画を視聴している時に3秒だけ戻したい、という願望を実現するものです。

# 使い方

1. youtube.comでこのブックマークレットを実行します。
2. ボタンが表示されるので、ここぞという時に押します。

# 簡潔な説明

上記コードは以下のコードを圧縮したものです。

```js
(() => {
// --------

// BTN_0
const btn_0 = document.createElement('div');
btn_0.setAttribute('class', '🔘');
btn_0.textContent = '＜';
document.body.appendChild(btn_0);

// BTN_1
const btn_1 = document.createElement('div');
btn_1.setAttribute('class', '🔘');
btn_1.textContent = '＞';
document.body.appendChild(btn_1);

// BTNs
let BTNs = document.getElementsByClassName('🔘');// HTMLCollection
BTNs = [].slice.call(BTNs);// => array

// skip
const skipp = (e) => {
    const idx = BTNs.indexOf(e.target);
    // 🔘[0] => back
    // 🔘[1] => forward
    document.getElementsByTagName('video')[0].currentTime += 3 * (2 * idx - 1);
}

// BTNs: style and EventListener
for(let i=0; i<2; i++){
    BTNs[i].style.cssText = 
        'z-index:99999;' +
        'position:fixed;' + 

        'bottom:120px;' +
        `right:${20 - (i - 1) * 60}px;` +

        'color:#222;' + 
        'font-size:10pt;' + 
        'text-align:center;' +

        'height:50px;' +
        'width:50px;' + 
        'line-height:50px;' + 
        'border-radius:50px;' +

        'border:1px solid #aaa;' +
        'background:#eee;' +
        'opacity:.5;' + 
        'user-select:none;' + 
        '-webkit-user-select:none;';
    BTNs[i].addEventListener('click', skipp);
}

// body => double tap: off
document.body.style.touchAction = 'manipulation';

// c3-material-button => touch: off
document.styleSheets.item(0).insertRule('c3-material-button {pointer-events: none}', 0);

// --------
})();
```

1. ``<div>``を２つ作り、これをボタンとみなして``EventListener``を指定する。
2. ボタンがタップされてイベントが発生するたびに、``document.getElementsByTagName('video')[0].currentTime``の値が増減する。秒数のところはお好みで変更して欲しい。
3. ボタンの大きさと色合いとかたち、表示位置についてstyleを記述。このあたりも微調整するといい。
4. また、ダブルタップの無効化、一部要素のタッチイベントの無効化を施している（が、使用環境によって機能しない場合がある）。

# あとがき

外国語学習、特に動画を見ながらリスニングの訓練をする時に便利なんじゃないかと思います。
よかったら使ってください。

本日もありがとうございました。

# 参考
感謝します。
- https://qiita.com/takahasinaoki/items/60af70d47dee904caf27
Rails aタグのリンクに変数を入れる方法

リンクを書く際になんども調べる事が多いので、備忘録として…

users/:id/showへのリンクをaタグを使って書きたい場合…

```rb
<a href="/users/<%= @user.id %>/show">
```

※Rubyの場合(二重引用符" "の中で式展開)

```rails
<%= link_to "詳細", "/users/#{@user.id}/show" %>
```
Macでpythonダウンロード、仮想環境構築、OpenCVダウンロード

#Python,venv,Opencvまで最短ルート
###実行環境
    macOS Catalina 10.15.7
    zsh
    python 3.9.4

一行ずつ実行してください。

    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

    brew install python

    python3 -V

    mkdir [your directory(project)]
    
    cd [your directory(project)]

    python3 -m venv (new env name)

    source (new env name)/bin/activate

    pip install opencv-python

    deactivate

##説明
Homebrewをダウンロードする

    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
pythonをダウンロードする
この時は明示的にpython3と書かなくてもpython3がダウンロードされる

    brew install python
pythonのversionを確認

    python -V
スクリプト保存するための特定の場所を作り、移動する

    mkdir [your directory(project)]
    cd [your directory(project)]
    
仮想環境を作成し、起動

    python3 -m venv (new env name)

    source (new env name)/bin/activate
OpenCVダウンロード

    pip install opencv-python
仮想環境を終了

    deactivate


###注意点

- pythonのversionは初めに入れたものに固定
- pythonのversionごと変更したければconda使うのもあり

####参照リンク
https://qiita.com/7110/items/1aa5968022373e99ae28

https://docs.python.org/ja/3/library/venv.html
human_attribute_name

###前提条件

ruby 2.5.1
rails 5.2.5


###結論

ActiveRecord::Baseのクラスメソッドであり、I18nモジュール（翻訳機能）を利用する為のもの。
config/locales/ja.ymlに定義してあるものを翻訳する。

```
　モデル名.human_attribute_name(:カラム名)
```
DockerでMaptilerサーバーを立ち上げて、QGISから利用する方法

## DockerでMaptilerサーバーを立ち上げて、QGISから利用する方法


- Dockerイメージをダウンロードします。
`docker pull maptiler/server`
![](https://i.imgur.com/xb7UgfV.png)

- ワークフォルダを作ります。
`mkdir maptiler && cd maptiler`
- Argsの説明書
![](https://i.imgur.com/5Myji0h.png)


- `.env` にMaptilerのキーなどのパラメーターを書きます。
![](https://i.imgur.com/PjqjmgP.png)

- `.env` に書いたパラメーターを以下コマンドでシステムに読み込みます。
 
```
set -o allexport; source .env; set +o allexport
```
 
- サーバーをDockerで起動

```
docker run -p 3650:3650 maptiler/server  --licenseKey=$KEY --rasterization=$RASTERIZATION
```
![](https://i.imgur.com/5sGz5Xz.png)


- [Localhost:3650](http://localhost:3650)を開くと下みたいな画面が見える
![](https://i.imgur.com/salJEOG.png)
- `Administration`を押したらパスワードを入れるところが出ます。
- コンソールで上で設定したパスワードを入れる。
![](https://i.imgur.com/d56yEVG.png)

- 地図スタイルがない場合は下みたいな画面が出ます
![](https://i.imgur.com/fMzM0dn.jpg)

- もし地図スタイルのZipファイルがある場合は**Upload**が書いてるボタンを押してください。そうすると下みたいな画面が出ます。
![](https://i.imgur.com/Fnx46tL.png)
- サインインした後で下みたいな画面を見えます。ダウンロードボタンを押してください。
![](https://i.imgur.com/I8brxwL.png)

- ダウンロードが終わったらそのZipファイルをMapTilerの画面にある**Upload**ボタンでアップロードをしてください。
![](https://i.imgur.com/G1pQuLn.jpg)



- アップロードが終わったら下みたいな画面が出ます。
![](https://i.imgur.com/bodZLzQ.png)


- 一つ地図を開いてそして `TilesJSON XYZ`が書いてあるところで　URLをコピーしてください。
![](https://i.imgur.com/8IU0HMZ.png)

- QGISでその情報を読むために **XYZ Tiles** で **New Connection** を選んでそしてタイルのパスを書いて保存します。
![](https://i.imgur.com/Ppw2KPt.jpg)

![](https://i.imgur.com/pk8RQsS.jpg)

- XYZ の下に出たメニューをクリックしたらタイルのレイヤが出ます。
![](https://i.imgur.com/qJ0zKgN.jpg)
AmigaOSのインストール後に発生する"ERROR: can't load picture"の修正方法

# TL;DR
"Devs:DataTypes/*.info"の、"Default Tool:"を"AddDataTypes"から"C:AddDataTypes"に修正する。

# 発生する問題
FS-UAEなどのAmigaエミュレータを使用してAmigaOSをインストールしたあと、"ERROR: can't load picture"というエラーが発生することがある。また、この状態ではjpgファイルなどを開こうとすると"Unknown data type for filename"となり失敗する。
![fs-uae-crop-2104121326-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587135/f114bcc6-b0f7-b223-3019-4675d04f8663.png)
![fs-uae-crop-2104121338-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587135/7198ecd2-84ee-830e-dbd6-52d19d8aa16f.png)

# 原因
"Devs:DataTypes/"には、DataTypeの定義が保存されている。各定義ファイルにはinfoファイルが付属していて、それらを実行すると"Default Tool"に設定された"AddDataTypes"コマンドが実行される仕組みになっている。

この"Defaut Tool"に設定するコマンドは、infoファイルからの相対パスか、絶対パスでなければならない。また、PATHは考慮されない。

したがって、"AddDataTypes"をコマンドにしたかったら、"Default Tool"には絶対パスである"C:AddDataTypes"を設定するべきだが、いくつかのinfoファイルにはなぜか"AddDataTypes"が設定されてしまっていた。

# 修正方法
Workbenchで"Devs:DataTypes"を開く。
![fs-uae-crop-2104121402-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587135/4f0be690-dd59-6e07-3e50-a0536e3166e8.png)

アイコンを一つ選択して、Workbenchのメニューから"Icons->Information..."を開く。
![fs-uae-crop-2104121403-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587135/4167329e-912a-a53a-8ce7-91e09f2e6695.png)

"Icon"タブの"Default Tool:"を確認し、"AddDataTypes"になっていたら"C:AddDataTypes"に変更する。変更後のセーブを忘れずに。
![fs-uae-crop-2104121403-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587135/6fb13a2e-34c2-0089-4250-6c0f9ecd89d7.png)

上記の工程をすべてのアイコンに対して行う。
その後に再起動すれば、エラーは解決しているはずである。
  
> ちなみに、"C:AddDataTypes"ファイルを"Devs:DataTypes/"にコピーしてもエラーは解決できてしまう。でもあまり賢い解決方法では無い。

# 考察
[私がインストールの参考にしたページ](https://eab.abime.net/showthread.php?t=67429)のコメント欄でもこのエラーは報告されており、以下の解決法が提示されていた。

> Yes. This is a problem with build in CDROM implementation (2.4 haven't this issue).
> Try to use
> cdrom_0_controller = ide1
> And reinstall your system.

なのでインストール中に"Default Tool"の設定をするプロセスがあって、エミュレータではそれがうまく行かないらしい、というのが私の予想だった。
ところがこの問題を調査しているとき、"Default Tool"はインストールCDの時点で誤ったパスが設定されていることに気がついた。
つまり、Amigaの実機ではこのパスを設定していても問題なく"AddDataTypes"が実行出来るか、エミュレータでは再現できないインストールプロセスが存在するということである。

私はAmigaの実機も持っていないし、現バージョンのFS-UAEはcdrom_0_controllerのオプションも持っていないので、CDROMドライバが原因でこの問題が起こったのかはわからない。
まだまだ謎の多い問題なので、今後わかったことがあれば追記していく。
WEBフォントデータを読み込んでTailwind.cssで使う方法

##はじめに

・TailwindでWEBフォントを使用したい。
・このAdobeのwoffフォントを使いなさいと指示を受け、woffファイルを貰った。
##使い方

1. woffファイルをVSCodeのsrc / fontにインポートする。
2. App.cssに以下を追加。

```
@font-face {
 font-family: Degular-Bold;
 src: url(./font/Degular-Bold.woff2);
}
```
３．Tailwind.config.jsに以下を追加。

```
module.exports = {
  theme: {
   extend: {
     fontFamily: {
       'degular_bold': ['Degular-Bold'],
     },
```

４． App.tsxにfont-使用できるようになる。

```
<h1 className="font-degular_bold">Hi</h1>
```
独学でHTML/CSS/Javascriptを学んだ素人がもう一度1から学びなおす Part2

<h1>Sass/Scssを使ってみる</h1>

cssについてはHTMLを多少学習した人であるなら、おそらくみんな最低限名前くらいは知っていると思う。しかし、Sassというものの存在は知らない人も多いのではないか。（私もその一人だった）

今回はSassの記述方法と特徴をまとめてみようと思う。




<h3>事前準備</h3>
+ Visual Studio CodeにLive Sass Compilerを追加しておく

<h3>サンプル用HTML</h3>
```html
<html>
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="container">
        <button class="btn">Button</button>
    </div>
</body>
</html>
```
※linkタグの参照先はファイル名.cssにしておきます。（ファイル名.scssをcssにコンパイルする為）

<h3>Sass</h3>
```sass
$cWhite: white;
$cBlack: black;

.btn{
    background-color:$cWhite;
    color:$cBlack;
    border: 1px solid $cBlack;
    padding: 10px 40px;
    font-weight: 600;
    cursor: pointer;
    margin: 50px 0;
    transition: all 0.5s;

    &:hover {
        background-color: $cBlack;
        color: $cWhite;

    }
}

```

入れ子の中の&(アンパサンド)は親セレクタを意味する。
(今回だとclassがbtnである要素がマウスオーバされた時のスタイルを指定)

<h3>通常のCSS（コンパイル後）</h3>
```css
.btn {
  background-color: white;
  color: black;
  border: 1px solid black;
  padding: 10px 40px;
  font-weight: 600;
  cursor: pointer;
  margin: 50px 0;
  transition: all 0.5s;
}
.btn:hover {
  background-color: black;
  color: white;
}
```

従来のcssだと、どのタグやclassに属しているかをそれぞれ分けて記載する必要があり、第三者には読みずらい点がある。一方Sassの場合、入れ子構造（ネスト）で記述出来る為、プロパティの記述されている箇所が一目瞭然。変なところでスタイルが重複したりしにくくなる。


<h3>感想</h3>
今回、初めてSass方式での記述をしてみたが、確かにこれはイケてる。
(サンプルの量が少なかったので、これだけだとメリットを感じずらいかもしれないが…)
自分と同じように初めて知ったという人は是非使ってみてほしい。
【Swift】添字付けについて

#はじめに
今回は添字付け(subscript)についてみていきたいと思います。

#subscript
subscriptとは、複数個のプロパティがある時に、配列のように、アクセスできるようにする機能です。配列以外のリストやデータ構造でも利用できます。

```swift
struct FoodMenu {
    let menu = ["menu1", "menu2", "menu3"]
    var submenu = ["submenu1", "submenu2", "submenu3"]
    var count: Int { menu.count + submenu.count }
    subscript(i: Int) -> String {
        get {
            return i < 3 ? menu[i] : submenu[i-3]
        }
        set {
            if i > 2 && i < 6 {
                submenu[i-3] = newValue
            }
        }
    }
}

var foodMenu = FoodMenu()
for i in 0..<foodMenu.count {
    print(foodMenu[i])
}
//menu1
//menu2
//menu3
//submenu1
//submenu2
//submenu3
```

`foodMenu[i]`としているので、`subscribe`のgetが呼ばれます。
`i < 3 ? menu[i] : submenu[i-3]`から、出力結果からもわかるように、配列`menu`と配列`submenu`が繋がったような配列`foodMenu`になっていますね。

次はsetを使ってみます。

```swift
var foodMenu = FoodMenu()
foodMenu[1] = "set1"
foodMenu[5] = "set5"
for i in 0..<foodMenu.count {
    print(foodMenu[i])
}
//menu1
//menu2
//menu3
//submenu1
//submenu2
//set5
```

`"set1"`は条件`i > 2 && i < 6`を満たさないのでsetできていないのがわかります。
また、以下のように、subscriptに対してもstaticを使うこともでき、その場合は`Face[2]`のようにアクセスすることができます。

```swift
struct Face {
    static subscript(i: Int) -> String {
        let index = (i < 0) ? 0 : (i > 4 ? 4 : i)
        let faces = ["😭", "🤔", "🥳", "😉", "😡"]
        return faces[index]
    }
}
print(Face[3]) // 😉
```


#おわりに
おわりです。
シェルやパス、npmについてのメモ

macでパッケージをインストールしたのに、`zsh: command not found: clasp`と表示される。

いい機会なので、シェルやパスについて調べてみることにしました。

今回の記事はその時のメモです。

## シェルとは

コマンドだけでパソコンを操作するためのもの。

Mac ではTerminalアプリでの操作。
Windows ではコマンドプロントアプリでの操作。

## シェルにはいくつか種類がある

sh / bash / ksh / csh / tcsh / zsh / ash …など。

## bash（バッシュ）とは

主にMacやLinuxで使われるシェル。

## zsh（ジーシュ | ゼットシェル）

bashの進化版。

最近のMacで使われている。

読み方は色々あるらしい。

##使用しているシェルの確認

```
echo $SHELL

//実行結果
/bin/zsh
```

##通しているパスの確認

```
echo $PATH

//実行結果
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```

パスは`:（コロン）`で区切られている。

## npmについて
パッケージマネジャー。node.jsをインストールすると自動的にインストールされる。

### npm install

・指定のパッケージをグローバルインストールする
・指定のパッケージをローカルインストールする
・package.jsonに記載された依存パッケージをまとめてローカルインストールする

主に上記の3つのために利用するコマンド。オプションがいっぱいある。

グローバルにインストールするときは`-g`をつける。

npm installは`npm i`や`npm add`がエイリアスとして存在する。つまり、`npm add`はinstallと同じ意味。

参考：[PCにコマンドをインストールする](https://www.codegrid.net/articles/2020-npm-install-1/)

##パスを通す

```
open ~/.zshrc
```

でファイルを開く。

ちなみに、パスを通す記述をする場合は、
・zshを利用している場合は、`.zshrc`ファイル
・bashを利用している場合は`. bash_profile `ファイル
を書く必要がある。

下記コマンドでパスを記述。

```
export PATH=(パス):$PATH
```

パスのところに今回追加するパス。
`:$PATH`は既に通しているパスに追加するよって感じの記述。


パスを追加したら下記コマンドで、シェル（ターミナル）を再起動。

```
source ~/.zshrc
```



パスについては『[「パスを通す」でやっていること](https://knmts.com/become-engineer-2/)』を読むのがおすすめ。

初心者にはむっちゃわかりやすい記事でした。m(_ _)m

###whichコマンド（コマンドの位置がわかる）

どこにコマンドファイルがあるのかすぐにわかって便利。

```
which ls  

//結果
/bin/ls
```
rails db:rollbackで複数個のファイルを差し戻す方法

migrationファイルで上段のmigrationファイルをrollbackするのに、一回ずつrials db:rollbackコマンドを入力するのは面倒ですよね。そこで、rails db:rollback STEP=○（数字が入ります）を入力すると、指定した数だけ差し戻されます。例えば、ファイル数が6個ある場合は、6を入力すると全てのファイルが差し戻されます。(rails db:migrate:statusで全てのファイルがdown状態になります。)

% rails db:rollback STEP=5
== 20200313144929 CreateComments: reverting ===================================
-- drop_table(:comments)
   -> 0.0051s
== 20200313144929 CreateComments: reverted (0.0069s) ==========================

== 20200313142605 RemoveNameFromTweets: reverting =============================
-- add_column(:tweets, :name, :string)
   -> 0.0385s
== 20200313142605 RemoveNameFromTweets: reverted (0.0387s) ====================

== 20200313134628 AddUserIdToTweets: reverting ================================
-- remove_column(:tweets, :user_id, :integer)
   -> 0.0296s
== 20200313134628 AddUserIdToTweets: reverted (0.0297s) =======================

== 20200313092641 AddNicknameToUsers: reverting ===============================
-- remove_column(:users, :nickname, :string)
   -> 0.0362s
== 20200313092641 AddNicknameToUsers: reverted (0.0364s) ======================

== 20200313085008 DeviseCreateUsers: reverting ================================
-- remove_index(:users, {:column=>:reset_password_token})
   -> 0.0253s
Minecraft 1.10.2 不定形レシピの追加



## 概要
- 3×3グリッド以外でレシピを指定するTips。


## コード
### 特定の形を指定したい

- 2×2のレシピの場合

```ExampleMod.java
GameRegistry.addShapedRecipe(new ItemStack(Items.DIAMOND),
                "AA",
                "AA",
                'A', new ItemStack(Blocks.DIRT));
```

- 横並びのレシピの場合

```ExampleMod.java
GameRegistry.addShapedRecipe(new ItemStack(Items.REDSTONE),
                "AAA",
                'A', new ItemStack(Items.WHEAT_SEEDS));
```

### 形を指定しないで、アイテムの数だけ指定したい

- りんご2つ、パン1つをどこかに置いたらエメラルドが作れるレシピの場合

```ExampleMod.java
GameRegistry.addShapelessRecipe(new ItemStack(Items.EMERALD),
                new ItemStack(Items.APPLE),
                new ItemStack(Items.APPLE),
                new ItemStack(Items.BREAD));
```


## 解説

- 形のあるレシピを作りたい場合、```addShapedRecipe()```を使う
- 形のないレシピを作りたい場合、```addShapelessRecipe()```を使う