OmniAICreator/Qiita-1.07M huggingface dataset:
非同期通信の初回挙動不良の対処方法

#なんで動かないの！？

アプリ作成をしていてjavaScriptで非同期やインクリメンタルサーチをしたけど、なぜか初回の挙動だけがうまくいってくれない、、！なんてなことないですか？？

今回は同じ事象で困っている人のために解消方法を紹介します。

#turbolinksを停止しよう

turbolinksとはgemとしてRailsアプリケーションに導入されている機能です。
今回の挙動の動作不良は手作業で作成したAjaxとturbolinksが競合してしまい、うまく作動しない可能性が考えられます。

1.Gemfileからturbolinksの部分をコメントアウトする

```ruby
gem 'turbolinks', '~> 5'
< --- コメントアウトしましょう --- >
# gem 'turbolinks', '~> 5'
```
bundleinstallも忘れず実行する

```
$ bundle install
```


2.application.html.hamlからturbolinksの関連部分を削除する

```application.html.haml
!!!
%html
  %head
    %meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
    %title PracticeApp
    = csrf_meta_tags

    / 修正前 
    = stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' ← このオプションを消す
    = javascript_include_tag 'application', 'data-turbolinks-track': 'reload' ← このオプションを消す

    / 修正後
    = stylesheet_link_tag    'application', media: 'all'
    = javascript_include_tag 'application'
  %body
    = render "layouts/notifications"
    = yield
```


３.application.jsからturbolinksの関連部分を削除する

```
//= require jquery
//= require jquery_ujs
//= require turbolinks　 <--- こいつを消してあげる
//= require_tree .
```

以上
GCPのCloud Shellのpythonバージョンの更新方法

こちらのstack overflowを参考にして書かせていただいています。

>[How do I install Python 3.7 in google cloud shell](https://stackoverflow.com/questions/53468831/how-do-i-install-python-3-7-in-google-cloud-shell)

GCPのCloud Shellのpythonが以前からずっと2.7とかで、検索してもあまり結果が出てこなかったので更新方法をまとめておきます。

pyenv を使用します。

```
#install pyenv to install python on persistent home directory
curl https://pyenv.run | bash

# add to path
echo 'export PATH="$HOME/.pyenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
echo 'eval "$(pyenv virtualenv-init -)"' >> ~/.bashrc

# install python 3.7.4 and make default
pyenv install 3.7.4
pyenv global 3.7.4

# source で更新する
source ~/.bashrc
```

これで終わったら一度新たなウィンドウに飛ぶなりしてリセットして、以下のコマンドを打てば更新されていることがわかるはずです。

```
$ python -V
Python 3.7.4
```
Ubuntuで絵文字 fonts-noto-color-emoji インストール後に一部のアプリで文字がおかしくなる

Ubuntu 20.04で確認。

Ubuntuで絵文字を表示するには、`fonts-noto-color-emoji` パッケージをインストールする。
インストールするだけで、Chromeなどでも絵文字が適用されるようになる。

```
sudo apt install fonts-noto-color-emoji
```

しかし、それ以降、数字が黒文字の全角になったり、妙なSerif（明朝体）になったりした。

![2020-05-16_13-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3413/2513bc92-ac9b-c1f8-806a-18f2ef60e440.png)

![2020-05-16_13-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3413/c61d4bc9-f9e6-ac4a-8d96-05325058aa43.png)

何の文字があたっているかfont-managerで調べていると、Noto Color Emojiが該当した。

![2020-05-16_13-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3413/a309a9a4-3258-9cb7-71a3-37178d3c4f19.png)

フォントの優先順位を確認するfc-matchを使うと、Noto Color Emojiが最初に出てくるようになった。

```
fc-match -a | head -5

NotoColorEmoji.ttf: "Noto Color Emoji" "Regular"
DejaVuSans.ttf: "DejaVu Sans" "Book"
DejaVuSansCondensed.ttf: "DejaVu Sans" "Condensed"
DejaVuSans-ExtraLight.ttf: "DejaVu Sans" "ExtraLight"
DejaVuSans-Bold.ttf: "DejaVu Sans" "Bold"
```

おそらく、Noto Color Emojiのインストールでこれが優先順位の先頭になり、一部最も上位のフォントしか使わないアプリケーションで、このフォントだけが使われるようになって、このようなことになっていると思われる。

フォントの優先順位を操作する ~/.config/fontconfig/fonts.conf をみてみると、Noto Color Emojを先頭に挿入する操作が書かれていた。

```xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
 <match>
  <test name="family">
   <string>sans-serif</string>
  </test>
  <edit mode="prepend" binding="strong" name="family">
   <string>Noto Color Emoji</string>
  </edit>
 </match>
 <match>
  <test name="family">
   <string>serif</string>
  </test>
  <edit mode="prepend" binding="strong" name="family">
   <string>Noto Color Emoji</string>
  </edit>
 </match>
```

これに、Noto Sans/Serif CJK JPに変更した。


```xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
<fontconfig>
 <match>
  <test name="family">
   <string>sans-serif</string>
  </test>
  <edit mode="prepend" binding="strong" name="family">
   <string>Noto Sans CJK JP</string>
  </edit>
 </match>
 <match>
  <test name="family">
   <string>serif</string>
  </test>
  <edit mode="prepend" binding="strong" name="family">
   <string>Noto Serif CJK JP</string>
  </edit>
 </match>
```

確認すると、順位が下がっていた。

```
fc-match -a | head -10

NotoSansCJK-Regular.ttc: "Noto Sans CJK JP" "Regular"
NotoSansCJK-Medium.ttc: "Noto Sans CJK JP" "Medium"
NotoSansCJK-DemiLight.ttc: "Noto Sans CJK JP" "DemiLight"
NotoSansCJK-Light.ttc: "Noto Sans CJK JP" "Light"
NotoSansCJK-Thin.ttc: "Noto Sans CJK JP" "Thin"
NotoSansCJK-Bold.ttc: "Noto Sans CJK JP" "Bold"
NotoSansCJK-Black.ttc: "Noto Sans CJK JP" "Black"
NotoColorEmoji.ttf: "Noto Color Emoji" "Regular"
```

引き続きChromeなどでは絵文字が利用でき、加えてNoto Color Emojiが不必要にあたっていたアプリでも正常に表示されるようになった。
pythonで画像を送信、phpで保存する

色々わr･･･面白いことに使えそうだからメモしとく

```python:pic_post.py
import requests
#こちら送信側→ローカルに置く
with open("img.jpg", "rb") as f:#画像をopen(読み込みみたいな？)する
	url='http://hogehoge.jp/pic_save.php'#送り先
	r = requests.post(url, f.read())#送信
```
```php:pic_save.php
<?php
//こちら受信側→サーバ側に置いておく
	$bin = file_get_contents("php://input");//受信したモノを取り出し
	file_put_contents('./img.jpg',$bin);//同じディレクトリに『img.jpg』というファイル名で保存する
?>
```
とりあえずは上のコードで動くはず
f.read()の意味は何だよとかは追記するかも
拡張子が違う場合(png、gif)やら画像を選びたい場合やらとかも本当は考えたいところ
###参考
[PHP]画像をダウンロードしてサーバーの特定のディレクトリに保存する
http://codaholic.org/?p=341
テンプレートリテラル記法を用いるとデプロイ時にエラーが出る

#背景

個人アプリをデプロイしようとしたが、エラーが出てうまくいかない。。。
javaScriptでテンプレートリテラル記法を用いた記述をするとどうやらエラーが出るみたい。

#解決策

######修正前

```config/environments/production.rb

config.assets.js_compressor = :uglifier
```

######修正後
```config/environments/production.rb

# config.assets.js_compressor = :uglifier
```


Uglifierというgemがあり、これはJavaScriptを軽量化するためのものです。
今回のアプリ中では、JavaScriptで使用しているテンプレートリテラル記法（`）に対応していません。
そのため、デプロイ時にエラーの原因となります。
上記部分をコメントアウトすることで解決します。

以上
Laravel + Oracle 12c 以前の名残と向き合うために

## 対象読者

- 様々な事情で、DB Oracle バージョン12c以前を利用している
  - もしくは、12c以前の名残が残っており、SEQUENCEオブジェクトから取得した番号をIDカラムに指定してINSERTしている
- Laravelを利用している

## 環境

- Oracle 12c
- Laravel 5.4

## 結論

`yajra/laravel-oci8` パッケージを利用して IDの採番を意識しなくても済むようにする

## 本題

Oracle 12c でIdentity Columnsの登場により、以前よりIDの自動採番を意識しなくて済むようになりました。

内部的にはSEQUENCEオブジェクトを生成して、 `.NEXTVAL` を取得してます。

```sql
CREATE TABLE　HOGE (
    ID    NUMBER    GENERATED AS IDENTITY,
    ..
```

もしくは、12c以降だと カラムのDEFAULT値にSEQUENCEを指定できるようにもなっています。

```sql
CREATE TABLE　HOGE (
    ID    NUMBER    DEFAULT HOGE_SQ.NEXTVAL  NOT NULL,
    ..
```

これから新規に作成するテーブルは、これに準じて作成すればいいと思うんですが、

なかなか既存のテーブルの変更に踏み込めていなかったりするわけです。

12c以前の名残で、SEQUENCEオブジェクトから `.NEXTVAL` で次の番号を取得して INSERT の際に ID に指定しているというサービスも少なくはないと思います。

```sql
CREATE TABLE　HOGE (
    ID    NUMBER    NOT NULL, -- IDENTITY も DEFAULT SEQUENCE も使えていない名残
```

```sql
INSERT INTO HOGE (ID, ..) VALUES ({SEQUENCEオブジェクトから .NEXTVAL で取得した値}, ..)
```

データを登録する度に、アプリ側のコードでIDを考慮してSEQUENCEオブジェクトから番号を取得して、IDに埋め込んで..

というのは、手間で、なるべくサービスのアプリケーションコードでは気にしたくないですよね。

　　

幸いにも、Laravelを利用していると、 `yajra/laravel-oci8` パッケージというものが見つかりました 👀

使い方は簡単で、モデルクラスに `$sequence` メンバ変数を定義するだけです。

```php
class Hoge extends Model -- Illuminate\Database\Eloquent\Model
{
    public $sequence = 'HOGE_SQ';
    ..
```

参考: https://yajrabox.com/docs/laravel-oci8/master/sequence

これを定義してあげると、わざわざIDに埋め込む必要もなくなります。

  

ただし、もともとIDを指定してデータを作成しているようなアプリケーションコードがあれば注意が必要です！

```php
Hoge::create(['ID' => 1, 'NAME' => 'hoge']);
```

例えば、上記のようなコードがもともと存在していたとすると、 `ORA-01036: illegal variable name/number` エラーが発生します。

原因は、Oracleの `RETURNING句` と `INTO句` です。

内部的に実行されるクエリを確認してみましょう。

```php
DB::enableQueryLog();
// 実行されるクエリを確認したいコード
Hoge::create(['ID' => 1, 'NAME' => 'hoge']);
dd(DB::getQueryLog());
```

```
insert into "HOGE" ("ID", "NAME") values (?, ?) returning "ID" into ?
// bindされる値は順に、 1, hoge, {.NEXTVALから採番された値} 
```

Oracleの `RETURNING句` と `INTO句` を組み合わせることで、

INSERTによって影響を受けたレコードに対しての評価（IDは {.NEXTVALから採番された値} ですよね? という評価）をしています。

結果、 `1` と `{.NEXTVALから採番された値}` が異なるのでエラーとなってしまいます。

もし、 `$sequence` メンバ変数を定義する際には、既存コードの影響を確認した上で変更を加えてください。
【エラー集】AWSデプロイ時MySQLエラーまとめ

#参考文献

- [共有ライブラリの依存関係のエラー `cannot open shared object file: No such file or directory`](https://qiita.com/pollseed/items/65e3fac05fc21980d2b2)
- [[Linux]共有ライブラリが見つからない時にやること](https://qiita.com/kouyan/items/c52fab36291a505e6122)
- [ERROR 1045 (28000): Access denied for userとなったときの対応方法](https://qiita.com/ponsuke0531/items/df51a784b5ff48c97ac7)
- [Linux error while loading shared libraries: cannot open shared object file: No such file or directory](https://stackoverflow.com/questions/480764/linux-error-while-loading-shared-libraries-cannot-open-shared-object-file-no-s)
- [mysql2 gem not working after updating to Ubuntu 16.04 - libmysqlclient.so.18](https://stackoverflow.com/questions/41538713/mysql2-gem-not-working-after-updating-to-ubuntu-16-04-libmysqlclient-so-18)


#エラー①   "cannot open shared object file"
```
LoadError: libmariadb.so.3: cannot open shared object file: No such file or directory
```

###解決策①  検索パスの設定
```
$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib64
```

###解決策②  共有ライブラリの依存関係の再設定
```
$ cat /etc/ld.so.conf
```

```
$ echo "/usr/lib64/XXXXX/lib" >/etc/ld.so.conf
```

###解決策③　MySQLのgemを再度インストール
```
$ bundle exec gem uninstall mysql2
```

```
$ bundle install
```


#エラー②    "Access denied for user"
```
ERROR 1045 (28000): Access denied for userとなったときの対応方法
```

###解決策① 特定のDBにのみ全権限有効なユーザを作成する
```
grant all privileges on 'DB名'.* to 'ユーザ名'@'ホスト名' identified by 'password' with grant option;
```

###解決策②　ホスト名がRDSの場合
```
mysql -u 'RDSユーザ名' -p -h XXXXXXXXXX.ap-northeast-1.rds.amazonaws.com
```
Typescript で React useState の引数を明示的にアノテートする

`useState`の引数に`string`や`number`でなく、定義したオブジェクトやオブジェクトの配列を渡す場合、うまく推論できないことがある。

```typescript
const [examples, setExamples] = useState([]);
```

その場合、関数呼び出し時にコンパイルエラーになる。こんな風に明示的にアノテートしてあげるとうまくいく。

```typescript
type SomeExample = {
  id: number
  example: string
}

const [examples, setExamples] = useState<SomeExample[]>([]);
```

これがどんなことをやっているのか解説する。例えば以下のような`map`関数があったとする。

```typescript
function map<T, U>(array: T[], f: (item: T) => U): U[] {
  let result = []
  for (let i = 0; i < array.length; i++) {
    result[i] = f(array[i])
  }
  return result
}
```

パラメータと戻り値がジェネリックで抽象化されているので、様々な引数を設定できる。

```typescript
map(['a', 'b', 'c'], i => i === 'a')
map([1, 2, 3], i => i === 1)
```

引数を明示的に書くこともできる。

```typescript
map<string, boolean>(['a', 'b', 'c'], i => i === 'a')
map<number, boolean>([1, 2, 3], i => i === 1)
```

上記の`useState`の例では、空配列のみ引数に渡していたので適切に型推論できていなかった。そのため、明示的なアノテーションが必要だったというわけ。
nuxt-property-decorator コンポーネントを読み込まなくても@Componentは書きましょう

# 前提
- @nuxtjs/axios: ^5.10.3
- nuxt: ^2.0.0
- nuxt-property-decorator: ^2.7.2
- Typescript 3.8.3
 


# エラー内容
下のコードをyarn devで動かすと
```Cannot set property 'components' of undefined```
とエラーが出て動かない．

```sample/index.ts
<script lang="ts">
import Vue from "vue";
import { Component } from "nuxt-property-decorator";
import { Context } from "@nuxt/types";

export interface FactResponse {
  id: string;
  text: string;
  type: string;
}

export default class index extends Vue {
  facts!: FactResponse[];

  async asyncData(context: Context): Promise<object | void> {
    const response = await context.app.$axios.$get(
      "https://cat-fact.herokuapp.com/facts"
    );
    const facts = response.all;

    return { facts };
  }

  get filterResponse(): FactResponse[] {
    return this.facts.filter(f => {
      return f.type == "cat";
    });
  }
}
```

# エラーの原因
Component宣言が抜けていた．
Componentを外部から読み込んでいなくても書かないといけない．
自分は無意識に2回経験しました．．．

# 解決策
```+ @Component({ computed: {} })```

```sample/index.ts
<script lang="ts">
import Vue from "vue";
import { Component } from "nuxt-property-decorator";
import { Context } from "@nuxt/types";

export interface FactResponse {
  id: string;
  text: string;
  type: string;
}
+ @Component({ computed: {} })
export default class index extends Vue {
  facts!: FactResponse[];

  async asyncData(context: Context): Promise<object | void> {
    const response = await context.app.$axios.$get(
      "https://cat-fact.herokuapp.com/facts"
    );
    const facts = response.all;

    return { facts };
  }

  get filterResponse(): FactResponse[] {
    return this.facts.filter(f => {
      return f.type == "cat";
    });
  }
}
```
ConohaでUbuntu 18.04のVPSを立ち上げ、Djangoをデプロイ（Nginx+Gunicorn）

実際の処理はrootユーザで行っているので、sudoいらないのだが、色々なところからのコピペコマンドだったりするので、そのまま残して書いてあるところがあります。

#下準備と必要なソフトウェアのインストール
passwd
（パスワード変更）

shutdown -r now
（一度再起動）
（再ログイン）

sudo apt update

sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl

#PostgreSQLの設定
sudo -u postgres psql


CREATE DATABASE Database名;
CREATE USER DBユーザ名 WITH PASSWORD 'DBパスワード';
ALTER ROLE DBユーザ名 SET client_encoding TO 'utf8';
ALTER ROLE DBユーザ名 SET default_transaction_isolation TO 'read committed';
ALTER ROLE DBユーザ名 SET timezone TO 'UTC';
GRANT ALL PRIVILEGES ON DATABASE Database名 TO DBユーザ名;

\q


#Virtual Environmentの導入
sudo -H pip3 install --upgrade pip
sudo -H pip3 install virtualenv


#Django用のディレクトリを作成
cd /home
mkdir django
cd django



(開発環境で作成したDjangoのデータを/home/djangoディレクトリ配下にコピー）


#Virtual環境を作成してActivate
cd testdjango（ <-Djangoのプロジェクト名）
virtualenv venv
source venv/bin/activate


#Djangoに必要なソフトウェアのインストール
pip install django gunicorn psycopg2-binary
pip install django-allauth
pip install django-cleanup
pip install pillow


#Djangoの設定ファイルの変更/修正
vi /home/django/testdjango/testdjango/settings.py


ALLOWED_HOSTS = ['VPSのIP', ‘localhost']


DATABASES = {
 'default': {
 'ENGINE': 'django.db.backends.postgresql_psycopg2',
 'NAME': 'Database名',
 'USER': 'DBユーザ名',
 'PASSWORD': 'DBパスワード',
 'HOST': 'localhost',
 'PORT': '',
 }
}

STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
（# STATICFILES_DIRSセクションをコメントアウト）
(:wqでviを抜ける）



#Djangoの設定
python manage.py makemigrations
python manage.py migrate
python manage.py collectstatic
　（Type 'yes' to continue, or 'no' to cancel: yes）
python manage.py createsuperuser


#gunicornの動作確認
sudo ufw allow 8000
gunicorn --bind 0.0.0.0:8000 testdjango.wsgi
（WebブラウザからVPSのIPアドレス:8000にアクセスを確認。確認が出来たらCtrl+cでgunicornを停止）
deactivate


#gunicornの設定
sudo vim /etc/systemd/system/gunicorn.socket


[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target



sudo vim /etc/systemd/system/gunicorn.service


[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=root
Group=www-data
WorkingDirectory=/home/django/testdjango
ExecStart=/home/django/testdjango/venv/bin/gunicorn \
 --access-logfile - \
 --workers 3 \
 --bind unix:/run/gunicorn.sock \
 testdjango.wsgi:application

[Install]
WantedBy=multi-user.target



#gunicornの起動（と自動起動）
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket


#nginxの設定
sudo vim /etc/nginx/sites-available/testdjango

server {
 listen 80;
 server_name VPSのIP;
 location = /favicon.ico { access_log off; log_not_found off; }
 location /static/ {
 root /home/django/testdjango;
 }
 location / {
 include proxy_params;
 proxy_pass http://unix:/run/gunicorn.sock;
 }
}


#実際にnginxが使用するファイルとして認識させる（ためにシンボリンクリンクを作成）
sudo ln -s /etc/nginx/sites-available/testdjango /etc/nginx/sites-enabled

#nginxの再起動とファイアウォールの設定
sudo systemctl restart nginx
sudo ufw allow 'Nginx Full'


（アクセスを確認）
Matroskaコンテナを利用してMP4ファイルをより安全に結合する

# 概要
複数のMP4ファイル (H.264 + AAC) を結合します。
また再エンコードは行わず、動画の品質の劣化無く結合します。
※ 複数の動画ファイルは、解像度、コーデック、アス比などが同じで有ることが前提です。

# 問題としている課題

## (課題1) 結合後のmp4で音ズレが発生する
結合方法についてはffmpegやmp4boxを用いた方法が簡単に見つかる。
しかし、AndroidやKindle Fireなどで再生すると音ズレが起きてしまう。
HWデコーダーで発生するため、プラットフォームの相性より、データ異常の方が可能性は高いと考える。

## (課題2) チャプターを維持したまま結合が出来ない
MP4のチャプターについては微妙な位置づけだが。
既にチャプターのある動画同士を結合するのであれば、
せめてチャプターが維持されていると嬉しい。
しかし、ffmpegで結合した場合、チャプターは無くなってしまう。

# 対策
Matroskaコンテナを用いて動画の修正を行う。
MatroskaコンテナはMP4で主に使用されるH.264とAACをサポートしているため、
品質の劣化なく情報の修正が可能。
また、同様の発想で、FLVをMKVで結合してMP4化など、他のコンテナにも応用可能。


# 利用ツール

|アプリ                                                |用途                            |
|-----------------------------------------------------|--------------------------------|
|[ffmpeg](https://www.ffmpeg.org/)                    |コンテナ変換<br /> (mkv ⇔ mp4,flv)|
|[mkvmerge (MKVToolNix)](https://mkvtoolnix.download/)|動画の結合、チャプター編集など    |




# 手順

## (手順1) MP4をMatroskaコンテナに変換
Matroskaで作業をするためにコンテナを変換します。

``` sh
ffmpeg -i "part_001.mp4" -f matroska -vcodec copy -acodec copy "part_001.mkv"
ffmpeg -i "part_002.mp4" -f matroska -vcodec copy -acodec copy "part_002.mkv"
ffmpeg -i "part_003.mp4" -f matroska -vcodec copy -acodec copy "part_003.mkv"
```

## (手順2) MKVを結合

``` sh
mkvmerge "part_001.mkv" + "part_002.mkv" + "part_003.mkv" -o "all.mkv"
```

## (手順2.1) チャプター修正など修正作業
MKVToolNixGUIでMKVの情報の修正が行なえる。
結合によりチャプターに振られている連番の修正を行いたいなどあれば、修正を行う。
またその他、なにかあればMKVの状態で。

## (手順3) MKVをMP4にコンテナ変換
``` sh
ffmpeg -i "all.mkv" -vcodec copy -acodec copy -f mp4 "all.mp4"
```

# 余談
MatroskaはMP4に比べて編集用のツールが充実している様に思われる。
チャプター周りもMP4では実用的な編集ソフトが見つけられなかった。
H.264+AACの
MKVをMP4作成用の中間フォーマットとして活用するのも大いにありかもしれない。



# 謝辞
* ffmpeg <br />https://www.ffmpeg.org/
* MKVToolNix <br /> https://mkvtoolnix.download/
LINE [BETA] Blockchain Serviceって何だろう？

なんかLine Developers consoleにある日いきなり追加されてました。

![developers.line.biz_console_provider_1598302065.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/b1d949b6-702b-d4da-3442-17b249346365.png)

## 想像してみる

- LinePlatform上でトークンを発行できるサービス？
- Lineのウォレットが使える？
- 発行したトークンはMessaging API等のLineサービスで活用できる？
- Line Mini アプリとやらで独自のポイントを運用できたりする？
- Line Payで売り買いできる？

## とりあえず試してみる。

### Create a channel

| title | value |
| :---- | :---- |
|Channel type|[BETA] Blockchain Service|
|Provider|任意|
|Channel name|任意|
|Channel description|任意|
|Category｜個人|
|SubCategory| 個人(IT･コンピュータ) |
|App types| Webapp |
|Email Address｜任意|

![developers.line.biz_console_channel_new_type=blockchain&provider=1598302065.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/58bc084e-fce9-1b9b-072e-29385764c366.png)


[Create and got to [BETA] Blockchain Service Developer Center] を押すと・・

LINE Blockchain Developersのサイトに飛びました。
Beta program？
このまま突き進んでしまっていいのだろうか・・

![blockchain.line.biz_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/979a7542-936f-6f2c-807c-1a1d3f7ffd4b.png)

## Beta program

https://blockchain.line.biz/

LINEとBlockchainを試したい、的な事を書きつつ、フォーム送信してみました。

![blockchain.line.biz_ (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/6f17ca5c-4484-cc29-fbeb-f770b41aca67.png)

なんか申請中になりました。敷居とかぜんぜんわかんないのですが、ダメなら落ちるだけでしょう。

## LINE Blockchain Developers

https://blockchain.line.biz/#/notice

このサイト、4/27オープンなのですね。

![blockchain.line.biz_ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/cb593a20-03a7-8100-14b0-263a841ef711.png)

詳しくはわかんないけど、`blockchain ecosystem`とある。
[Topページ](https://blockchain.line.biz)見た感じだと、トークンにウォレット、APIとなんか想像した通りのサービスだろうか。

<img width="807" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/cfb56863-55da-00f8-315f-6aa3b8de5a56.png">

- Building an independent token economy
- Tokenizing assets of all kinds
- Cloud-based user key management
- Accessing blockchain through API calls
- Built-in AML and KYC solutions
- Linking wallet service to LINE ID

ちなみにLine Developers consoleだとこんな感じになってます。

![developers.line.biz_console_channel_1654221227_blockchain.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/99030381-c25f-a652-c5e8-fe5b87e63652.png)

## 結論

わからんかった。
Swift学習記＃3「条件分岐式について」

#はじめに
今回は、前回の繰り返し文と同じく開発の中で頻繁に用いられる
条件分岐についてです。

その中でも、僕が「特に使うのではないか」と思う
`if`、`switch ~ case`、`guard`の3つについて解説して行きます！

##**if ( if ~ else, if ~ else if )**

書式はこんな感じ、、、

```test.Playground
if 条件式 {

  // 正の場合の処理

} else {

  // 負の場合の処理

}
```

`if`文の条件分岐式は、対象になる変数（または定数）が
**設定された条件に対して正（正しい）か、負（間違っている）か**
によって行う処理が変わるというもの。

実際には、

```test.Playground
var num = 12

if num % 2 = 0 {
  // 正の場合の処理
  print("numは偶数")

} else {
  // 負の場合の処理
　print("numは偶数ではない")
}

// 表出結果
＝＞　numは偶数
```
こんな感じで行う処理を分けて行きます！

また`if`文では、条件を複数設定することもできます。
それを可能にするのは、`if ~ else if`です。

書式はこんな感じ、、、

```test.Playground
if 条件式1 {

  // 正の場合の処理

} else if 条件式2 {

  // 正の場合の処理

} else {

  // 負の場合の処理

}
```
この様に、 `else if`を使うと条件式を複数使用できます。

ちなみに、分岐の条件として「負の場合」と書いていますが、
どちらかといえば「正でない場合」と言い方が正しいかもしれません。

##**switch ~ case**
書式はこんな感じ、、、

```test.Playground
switch 変数（または定数）　{
case 条件１:
  // 処理
case 条件２:
  // 処理

    ・
    ・
    ・

default:
  // 全ての条件に一致しなかった場合の処理
}

```
`switch ~ case`の条件分岐式では、対象になる変数（または定数）に
`case`ごとに条件を設定して行き、`if`と同様に
**設定された条件に対して正（正しい）か、負（間違っている）か**によって
行う処理をが変わる。

`switch`の文は`if`文とは違い、変数(または定数)の定義が
１回でいいので、複数の条件を設定する場合に有用である。

実際の使用法は、、、

```test.Playground
var age = 17

switch age {
case 0...6:
  print("幼稚園児")
case 7...12:
  print("小学生")
case 13...15:
  print("中学生")
case 16...18:
  print("高校生")
default:
  print("社会人 or 大学生")
}

// 表出結果
＝＞　高校生 
```
こんな感じになります！

##**guard**
`guard`文は上の2つの条件分岐とは違う判定を行う条件分岐式です。
しかし、swiftで開発を行う場合はとても有用で重要です！

まず、書式はこんな感じ、、、

```test.Playground

guard 条件式 else {

  // 条件式が負の場合に処理を実行

}
```
書式を見ての通り、
`guard`文は**「条件式が負の場合」に処理を実行します。**
ちょうど上2つとは真逆の条件分岐式になりますね。

初めて見ると「こいついるの？」と思うかもしれないが、
swiftでは割と重要なので知っておいて損はないと思います！
（個人の感想です‼︎）

ちょっと難しいですが、実際に使うと、、、

```test.Playground
// 関数の定義
func test(_ a: Int) {

//guard文定義
  guard a > 0 else{

　　//条件式が負の場合に処理を実行
    print("数値は0未満です")
    return
  }
  print a
}

// 関数に値を挿入
test(1)

//表出結果
＝＞　1
```
今回使った関数の定義は次回説明します！

#これまで
今回は、`if`、`switch ~ case`、`guard`の3つの条件分岐式
についてやりました。

条件分岐式は開発に進めば頻繁に目にすることになるので、
この3つだけでも覚えておいてください‼︎
10分でReact × Dockerの環境構築

##概要
React×Dockerの環境構築ではまったのでメモとして書きました:pencil2:

##環境構築

#####作業ディレクトリを作成

```terminal 
$ mkdir react-docker
```
#####Dockerfile作成

```dockerfile:Dockerfile
FROM node:8.16.0-alpine
WORKDIR /usr/src/app
```
#####docker-compose.ymlを作成

```yml:docker-compose.yml
version: "3"
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    stdin_open: true
    volumes:
      - ./:/usr/src/app
    command: sh -c "cd react-sample && yarn start"
    ports:
      - "3000:3000"
```

#####ビルド

```terminal 
$ docker-compose build
```

#####create-react-appとReactのインストール（数分かかります）

```terminal 
$ docker-compose run --rm web sh -c "npm install -g create-react-app && create-react-app react-sample"
```
#####コンテナ起動
```terminal 
$ docker-compose up
```
#####終了！
<img width="600" alt="スクリーンショット 2020-05-16 11.55.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550573/e19c8c94-26bd-80bc-28d1-13bf51cec033.png">


##ちょっとはまったところ

```stdin_open: true```の記述をなしで構築するとコンテナ起動後にすぐコンテナが停止してしまう。
docker run の「-it」オプションに当たるもの。これを指定しないと、コンテナを起動してもすぐ終了してしまう:sob:

```terminal 
$ docker-compose up
Creating docker-react_web_1 ... done
Attaching to docker-react_web_1
web_1  | yarn run v1.15.2
web_1  | $ react-scripts start
web_1  | ℹ ｢wds｣: Project is running at http://172.20.0.2/
web_1  | ℹ ｢wds｣: webpack output is served from 
web_1  | ℹ ｢wds｣: Content not from webpack is served from /usr/src/app/react-sample/public
web_1  | ℹ ｢wds｣: 404s will fallback to /
web_1  | Starting the development server...
web_1  | 
web_1  | Done in 12.50s.
docker-react_web_1 exited with code 0
```

参考:　https://github.com/facebook/create-react-app/issues/8688


```yml:docker-compose.yml
version: "3"
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    stdin_open: true
    volumes:
      - ./:/usr/src/app
    command: sh -c "cd react-sample && yarn start"
    ports:
      - "3000:3000"
```


####参考記事
-[Reactの開発環境をDockerで構築してみた](https://blog.web.nifty.com/engineer/2714)
archive.today のIPアドレス一覧

#はじめに

`robots.txt`に従わない [Archive.today](http://archive.today/) のブロックに必要なIPアドレスの一覧
[個人サイト](https://www.cloudremix.net/)のアクセスログが元データ
編集リクエスト・情報提供は大歓迎

> Why does archive.is not obey robots.txt?
>
> Because it is not a free-walking crawler, it saves only one page acting as a direct agent of the human user. Such services don't obey robots.txt (e.g. Google Feedfetcher, screenshot- or pdf-making services, isup.me, …)
>
> https://archive.is/faq

# IPアドレス一覧。ただし...

確認できたのは次のとおり。ただし

```
173.254.241.162
188.143.233.210
213.174.145.218
45.135.229.10
47.90.253.149
```
# Tor経由のリクエスト

結構数があったのでGitHubで公開と思ったのですが、IPアドレスでググるとTorのIPアドレスが結構含まれていました。
※上のリストは Tor 以外のIPアドレス（たぶん）

どうやら自前サーバでエラーになると、Tor経由でアクセスを試みるようです。
というわけで Archive.today をブロックしたければ、TorのIPアドレスもブロックが必要です。


Tor のIPアドレス一覧
https://check.torproject.org/exit-addresses
【Laravel7】PHPUnitの設定をしてテストを実行してみる

##### はじめに
プロジェクトを作成するたびにPHPUnitの設定方法忘れて都度調べてるので、忘備録として残して忘れないようにしておきたいと思います。
PHPUnitの設定方法は何通りかあるかと思いますが、この記事では `SQLiteのインメモリ機能` を用いて開発用のDBを汚さない設定方法を使用します。

##### 実行環境
今回PHPUnitの設定は下記のバージョンで行います。厳密に同じ環境でなくてもメジャーバージョンがあっていれば同様の設定で動くかと思います。

| 言語・ツール    |  バージョン  |
|:------------:|:---------:|
| Laravel      |   7.10.3  |
| PHP          |   7.2.26  |
| PHPUnit      |   8.5.4   |


#### 設定方法
PHPerからするとMySQLと比較してあまり馴染みがないかもしれませんが、本記事ではテスト用DBにSQLiteを使用します。

**SQLiteとは？**
`SQLite`はオープンソースのリレーショナルデータベースです。主に以下の特徴を持っています。

```
・サーバ側に設置する必要がなく、アプリケーションに組み込みこんで使用することができる
・動作が軽量
・データ量の少ないデータを扱うのに適している
・ローカルのファイルを直接データベースとして扱うので、複数のサーバとネットワーク越しに同時接続するのには不向き
```

**インメモリ機能とは？**
`インメモリ機能（インメモリデータベース）`とはデータストレージを主にメインメモリ上で管理する、データベースシステムです。今回の場合ですと、PHPUnitでテスト実行時にメモリにデータベースが作成されて、テスト終了時にデータベースは存在しなくなります。そのため開発用のデータベースを汚さずにテストを実行することができます。

**設定**
それでは実際に、設定をしていきましょう。

まずはデータベースの接続設定を`config/datbase.php`に追加します。`database`の項目に`:memory:`を指定している点がポイントです。こうすることによりデータベースのメインメモリ機能を使用することができます。

```database.php
'connections' => [
  ....
  ....
  'testing' => [
    'driver'   => 'sqlite',
    'database' => ':memory:', // SQLiteのインメモリ機能を使用
    'prefix'   => '',
    'options'  => [
      PDO::ATTR_PERSISTENT => false,
    ],
  ],
],
```

次にPHPUnitの設定を行います。`<server>`にて環境変数が指定されるので、`DB_CONECTION`を追加して、値を上記の`config/database.php`で設定したキー`testing`を使用します。

```phpunit.xml
  <php>
    <server name="APP_ENV" value="testing"/>
    <server name="BCRYPT_ROUNDS" value="4"/>
    <server name="CACHE_DRIVER" value="array"/>
    <server name="DB_CONNECTION" value="sqlite"/>
    <server name="DB_DATABASE" value=":memory:"/>
    <server name="MAIL_MAILER" value="array"/>
    <server name="QUEUE_CONNECTION" value="sync"/>
    <server name="SESSION_DRIVER" value="array"/>
    <server name="TELESCOPE_ENABLED" value="false"/>
    <server name="DB_CONNECTION" value="testing"/>  // この行を追加
  </php>
```

**テストの実行**
Laravelのプロジェクトを作成した際にデフォルトで用意されている`ExampleTest.php`を実行してテストが通るか確認します。テスト結果が下記のように`OK`となれば正しくPHPUnitの設定ができているかと思います。

``` terminal
$ vendor/bin/phpunit tests/Feature/ExampleTest.php
PHPUnit 8.5.4 by Sebastian Bergmann and contributors.
.                                                                   1 / 1 (100%)
Time: 1.85 seconds, Memory: 18.00 MB
OK (1 test, 1 assertion)
```
##### おまけ 
テスト実行時に`vendor/bin/phpunit`と毎回入力するのは煩わしいかと思うので、その際は下記のように、コマンドをエイリアスを設定してあげるといいかと思います。こうすることで、`pu`とコマンドを叩いてあげることで、画面がリフレッシュされた後でテストを実行することができます。

```
$ alias="clear && vendor/bin/phpunit"
```
Chrome拡張機能の作り方


【公式ドキュメント】
[拡張機能とは？](https://developer.chrome.com/extensions)

Manifestの作り方については下記を参照
[Chrome 拡張機能のマニフェストファイルの書き方](https://qiita.com/plumfield56/items/92a3656d6b24aa5e9f7e)

## 注意点
第二引数でアロー関数が動かないことがあるので、その場合はfunction()を使用



## よく使うコード
| メソッド | 説明 | 公式ドキュメントのリンク |
|:---|:---|:---|
| chrome.runtime.onInstalled.addListener() | 拡張機能がインストールされた時に実行 | [リンク](https://developer.chrome.com/extensions/runtime#event-onInstalled) |
| chrome.browserAction.onClicked.addListener() | ブラウザアクションで設定したアイコンがクリックされた時に実行 | [リンク](https://developer.chrome.com/extensions/browserAction#event-onClicked)
| chrome.tabs.query() | 全てのタブを取得 | [リンク](https://developer.chrome.com/extensions/tabs#method-query) |
| chrome.tabs.executeScript() | JSかCSSのコードを実行 | [リンク](https://developer.chrome.com/extensions/tabs#method-executeScript) |


## よく使うchrome.tabsのメソッド

| メソッド | 説明 | 公式ドキュメントのリンク |
|:---|:---|:---|
| chrome.tabs.query | 全てのタブを取得 | [リンク](https://developer.chrome.com/extensions/tabs#method-query) |
| executeScript | JSかCSSのコードを実行 | [リンク](https://developer.chrome.com/extensions/tabs#method-executeScript) |



## 用途に応じて下記の記事を参照
・popupの使い方
[Chrome拡張機能でポップアップを表示させる方法](https://qiita.com/plumfield56/items/82a001759d0ade9ab319)
・popup,tabsの使い方
[Chrome拡張機能でタブの情報を取得する方法](https://qiita.com/plumfield56/items/99f5cfc1bf5fd03e8040)
・background,contextMenusの使い方
[Chrome拡張機能で右クリックメニューを作る方法](https://qiita.com/plumfield56/items/e98c247888d82a79c7ea)
・content_scripts,backgroundの使い方
[Chrome拡張機能でContent ScriptでMessage Passingする方法](https://qiita.com/plumfield56/items/5d5da9e467ff41422ba9)
・[追加したChrome拡張機能のコードを見る方法](https://qiita.com/plumfield56/items/c6d1c9c91110c49daa32)
NlogNの計算量

# ソースコード
```cpp
  long N=pow(10,18);
  printf("[N][logN][NlogN][N^2]\n");
  for(double i=10;i<=N;i*=10){
    printf("[%.0g][%.0g][%.0g][%.0g]\n",i,log2(i),i*log2(i),i*i);
  }
```

# 実行結果
```
[N][logN][NlogN][N^2]
[1e+01][3][3e+01][1e+02]
[1e+02][7][7e+02][1e+04]
[1e+03][1e+01][1e+04][1e+06]
[1e+04][1e+01][1e+05][1e+08]
[1e+05][2e+01][2e+06][1e+10]
[1e+06][2e+01][2e+07][1e+12]
[1e+07][2e+01][2e+08][1e+14]
[1e+08][3e+01][3e+09][1e+16]
[1e+09][3e+01][3e+10][1e+18]
[1e+10][3e+01][3e+11][1e+20]
[1e+11][4e+01][4e+12][1e+22]
[1e+12][4e+01][4e+13][1e+24]
[1e+13][4e+01][4e+14][1e+26]
[1e+14][5e+01][5e+15][1e+28]
[1e+15][5e+01][5e+16][1e+30]
[1e+16][5e+01][5e+17][1e+32]
[1e+17][6e+01][6e+18][1e+34]
[1e+18][6e+01][6e+19][1e+36]
```

# 考察
Nが$10^6$のときにNlogN(底は2)は2*$10^7$なので
1秒間に余裕を持って計算できるNlogNはNが$10^6$ぐらいまでですかね〜。
javascriptのthisとbind、apply、callの使い方

# 参考
thisの違いはこちらが分かりやすい。
[JavaScriptの「this」は「4種類」？？](https://qiita.com/takeharu/items/9935ce476a17d6258e27)

bind()
[Function.prototype.bind()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)

# 自分なりのまとめ
javascriptのfunction内のthisが示すものはは関数の呼び出し方によって異なる。
関数呼び出し時にthisを明示するために用いるのが下記の関数

- call
- apply
- bind

## call、apply

関数呼び出し時にthisを指定する。
callとapplyの違いは引数の取り扱いが違うくらい。

## bind

関数のthisに予め任意のものを指定した関数を返す。
bindを使って受け取った関数はthisが固定されているためcallとapplyで呼び出し時に上書きすることは不可能。


# 確認

https://paiza.io/projects/ZJir-GpI4yZHafpMuZMmcQ?locale=en-us 

```javascript
process.stdin.resume();
process.stdin.setEncoding('utf8');
// Your code here!
value = 'global';

var myObject = {
  value: 'myObject',
  show: function() {
    console.log(this.value);
    return this.value;
  }
}
myObject.show(); // myObject

var show = myObject.show;
show(); // global
show.call(myObject); // myObject
show.apply(myObject); // myObject

show = myObject.show.bind(myObject);
show(); // myObject
show.call(global); //  myObject bindしたため無効
show.apply(global); // myObject bindしたため無効

show = myObject.show.bind(global);
show(); // global
show.call(myObject); // global bindしたため無効
show.apply(myObject); // global bindしたため無効
```
RailsとReactをdocker-composeを使って立ち上げる

GraphQLをRails, Reactで使うための第１歩として、RailsのAPIモードとReactをdocker-composeを使って同時に立ち上げられる環境を構築したのでその手順をメモしておきます

※このやり方で動くことは確認済みですが慣れておらず試行錯誤した部分もあるので効率的でない部分も多いかと思います。もしそのような箇所を発見したら指摘していただけると助かります

### Railsをdocker-composeで立ち上げる
まずはAPIモードでRailsを立ち上げます

※筆者は[こちらの記事](https://utano.jp/entry/2016/07/rails-bundle-install-gem-inner-project/)の内容を参考にディレクトリ内にbundle installの内容を残す形で作成しています

```:Gemfile
source "http://rubygems.org"
gem "rails"
```

```
bundle install --path .bundle/
bundle exec rails new rails_test  --api --skip-bundle
mv rails_test/* .
rm -rf rails_test/
bundle install
```

この時点で`rails s`をするとRailsを起動することができます

![rails起動画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638400/614d84bf-aa51-79b5-9875-f36894cb0eaf.png)

※ちなみに画像にもありますが動作環境はRails 6.0.3, Ruby 2.7.1です

つづいてこのRailsをdockerで立ち上げられるようにします

```:docker-compose.yml
version: '3'

services:
  rails:
    build:
      context: .
      dockerfile: Docker_rails
    command: /bin/sh -c "cd app && rm -f /app/tmp/pids/server.pid && bundle install && bundle exec rails s -b 0.0.0.0"
    stdin_open: true
    tty: true
    volumes:
      - .:/app
    ports:
      - 3000:3000
```

```:Docker_rails
FROM ruby:2.7.1
```

これで`sudo docker-compose up -d`を行うとdockerでrails環境が立ち上がります

※docker-composeの実行は最初はsudoが必要です。sudoを外す方法は[こちらの記事](https://unskilled.site/docker%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E3%81%AB%E3%83%A6%E3%83%BC%E3%82%B6%E3%82%92%E7%99%BB%E9%8C%B2%E3%81%97%E3%81%A6sudo%E3%81%AA%E3%81%97%E3%81%A7docker%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89/)を参考にしてください

### Reactをdocker-composeで立ち上げる
Reactも同じように作っていきます (同じディレクトリ内に作ります)

```
create-react-app frontend
```
Reactの一番簡単な構築はこれだけでできます

```
cd frontend
yarn start
```
で起動します

![react起動画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638400/180df9b6-93a1-bbfa-6420-3bfe8da0dce1.png)

これもdocker-composeで起動できるようにします

先程のdocker-compose.ymlに追記します

```:docker-compose.yml
version: '3'

services:
  rails:
    build:
      context: .
      dockerfile: Docker_rails
    command: /bin/sh -c "cd app && rm -f /app/tmp/pids/server.pid && bundle install && bundle exec rails s -b 0.0.0.0"
    stdin_open: true
    tty: true
    volumes:
      - .:/app
    ports:
      - 3000:3000
    
  react:
    build:
      context: .
      dockerfile: Docker_react
    command: /bin/sh -c "cd frontend && yarn && yarn start"
    stdin_open: true
    tty: true
    volumes:
      - ./frontend:/frontend
    ports:
      - 4000:3000
```

```:Docker_react
FROM node:8.16.0-alpine
```

これで`docker-compose-up -d`をすると

`http://localhost:3000`→Rails

`http://localhost:4000`→React

というようにRailsとReactを同時に立ち上げることができます

### 課題点
Railsを立ち上げるのに時間がかかる (毎回bundle installし直すのなんとかしたい)

Dockerfileが余計 (image取ってくる方法があるはず)

この辺は分かり次第追記していこうと思います
Chrome拡張機能でタブの情報を取得する方法

この記事ではChrome拡張機能でタブの情報を取得する方法として
htmlファイルからJavaScriptファイルを呼び出す方法と
backgorundからjsファイルを呼び出す方法を紹介しています。

またタブの情報取得はchrome.tabs.queryで行います。
chrome.tabsの公式ドキュメントは[こちら](https://developer.chrome.com/extensions/tabs)

chrome.tabs.queryの第一引数で使用できるパラメーターと
実行時に第二引数の仮引数に入るオブジェクト情報はそれぞれ下記です。

・[パラメーター](https://developer.chrome.com/extensions/tabs#method-query)
・[タブが持っているオブジェクト情報](https://developer.chrome.com/extensions/tabs#type-Tab)


# htmlファイルからjsファイルを呼び出す場合

```:フォルダ構造
フォルダ
 ├ manifest.json
 ├ popup.html
 ├ popup.js
 └ icon.png
```

```json:manifest.json

{
  "manifest_version": 2,
  "name": "Show Tab Info",
  "version": "1.0",

  "browser_action": {
    "default_icon": {
      "16": "icon.png"
    },
    "default_popup": "popup.html"
  },

  "permissions": [
    "tabs"
  ]
}
```

htmlファイル内のscriptタグ内でJavaScriptを書いても実行されないので、
必ず別ファイルを読み込ませる。

```html:popup.html
<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
</head>
<body>
  <script src="popup.js"></script>
</body>
</html>
```

## 全てのタブ情報を取得する場合
第二引数でタブ取得時の実行内容を記載
タブの情報を仮引数に代入して処理を実行

```javascript:popup.js
'use strict'
{
  chrome.tabs.query({}, tabs => {
    const results = document.getElementById('results');
    const titles = [];

    for(let i=0; i<tabs.length; i++){
      // console.log(tabs[i].title);
    }
  });
}
```

## 現在のタブ情報のみを取得する場合
`lastFocusedWindow:true`で最後にフォーカスが当たったウィンドウを選択
`active: true`でアクティブなタブを選択

```javascript:popup.js
'use strict'
{
  chrome.tabs.query({active: true, lastFocusedWindow:true}, tabs => {
    const results = document.getElementById('results');
    const titles = [];

    for(let i=0; i<tabs.length; i++){
      console.log(tabs[i].title);
    }
  });
}
```

ログを出す場合は作成されたアイコンを右クリック⇒ポップアップを検証のConsoleタグで確認が可能です。

|<img width="800" alt="2020-05-16_13h09_02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/d7033888-1a7b-c33d-8dbe-f4a30ea34299.png">|
|:-:|




# backgroundで直接jsファイルを呼び出す場合

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

```json:manifest.json
{
  "manifest_version": 2,
  "name": "Show Tabs Info",
  "version": "2.0",

  "browser_action": {
    "default_icon": {
      "16": "icon.png"
    }
  },

  "background": {
    "scripts": ["event.js"],
    "persistent": false
  },

  "permissions": [
    "tabs"
  ]
}
```

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

{
  chrome.tabs.query({}, tabs => {
    for(let i=0; i<tabs.length; i++){
      console.log(tabs[i].title);
    }
  });
}
```

backgroundのログを見る場合は下記から確認

<img width="361" alt="2020-05-16_17h49_46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428239/edfb4220-819a-c83c-7f28-b980d5472e26.png">


この記事は[Chrome拡張機能の作り方](https://qiita.com/plumfield56/items/680ce9a166282b7ae84c)の一部のコンテンツです。
Go言語での集合(Set)の扱い方とテスト

# はじめに

Go言語には標準で集合(Set)は用意されていません。

# 実現方法

## 1. Slice

```go
strSet1 := []string{"element1", "element2", "element3"}
```

シンプルな方法。
重複は許されるし、ただのスライス。
簡易的な場合はこれで十分。

## 2. map[interface{}]struct{}

```go
strSet2 := map[string]struct{}{
	"element1": struct{}{},
	"element2": struct{}{},
	"element3": struct{}{},
}
```

`map`を利用する方法。
struct{}はメモリを圧迫することはない。


## 3. github.com/deckarep/golang-set/mapset

```go
strSet3 := mapset.NewSet()
requiredClasses.Add("element1")
requiredClasses.Add("element2")
requiredClasses.Add("element3")
```

パッケージを利用する方法。
Setを操作する便利メソッドが多く実装されている。
内部実装では`map[interface{}]struct{}`が用いられている。
https://github.com/deckarep/golang-set にソースコードがある。


# 用途

個人開発しているときに、RedisのSMembersのテストをする必要があった。
RedisではSetでデータを保持することができ、SMembersで取得することができる。
goにはSet型はないため、`go-redis`の`SMembers`では`[]string`が返る。
集合どうしを比較する場合に`[]string`では要素間の順序が担保されず、テストが失敗するためSet型を利用した。
3の`github.com/deckarep/golang-set/mapset` を利用するのは大袈裟と思い、2の`map[interface{}]struct{}`を利用した。
`[]string`を集合として扱い比較したい場合には、それぞれの要素が過不足なく含まれていることを確認するために`for`ループをたくさん回すことになるだろう。

```go:sample.go
package sample

import (
	"testing"

	"github.com/go-redis/redis/v7"
)

type RepositoryImpl struct {
	Client *redis.Client
}

func New(addr string) (*redis.Client, error) {
	client := redis.NewClient(&redis.Options{
		Addr: addr,
	})
	if err := client.Ping().Err(); err != nil {
		return nil, errors.Wrapf(err, "failed to ping redis server")
	}
	return client, nil
}

func (r RepositoryImpl) GetStringSet(key string) ([]string, error) {
	result, err := r.Client.SMembers(key).Result()
	if err != nil {
		return nil, err
	}
	return result, nil
}
```

```go:sample_test.go
package sample

import (
	"testing"

	"github.com/go-redis/redis/v7"
)

func NewMockRedis(t *testing.T) *redis.Client {
	t.Helper()

	s, err := miniredis.Run()
	if err != nil {
		t.Fatalf("unexpected error while createing test redis server '%#v'", err)
	}

	client := redis.NewClient(&redis.Options{
		Addr: s.Addr(),
	})
	return client
}


func TestGetStringSet(t *testing.T) {
	client := NewMockRedis(t)
	r := RepositoryImpl{
		Client: client,
	}

	client.SAdd("testKey", "hoge", "fuga", "piyo")

	actual, err := r.GetStringSet("testKey")
	if err != nil {
		t.Fatalf("unexpected error while GetStringSet '%#v'", err)
	}
	expected, err := []string{"hoge", "fuga", "piyo"}

	// 順番が担保されないため、テストが失敗する
	if diff := cmp.Diff(actual, expected); diff != "" {
		t.Errorf("Diff: (-got +want)\n%s", diff)
	}

	// sliceではcmp.Diffで順序が考慮されてしまうのでSetに変換して比較する
	expectedSet := make(map[string]struct{})
	for _, v := range expected {
		expectedSet[v] = struct{}{}
	}
	actualSet := make(map[string]struct{})
	for _, v := range actual {
		actualSet[v] = struct{}{}
	}

	// 順番が担保されるため、テストが成功する
	if diff := cmp.Diff(actualSet, expectedSet); diff != "" {
		t.Errorf("Diff: (-got +want)\n%s", diff)
	}
}
```

# 参考
[GoでSet型を実現する場合の選択肢](http://kitakitabauer.hatenablog.com/entry/2017/04/04/204701)
【revert】【rebase】git revert か rebaseで特定のコミットでの作業をなかったことに

#はじめに
開発を進める中で、あのコミットの作業だけ取り消したいなーという時に使える。
自分の場合は、デバッグする中で行ったprecompileが余計だったのだが、以下の手順でその実行結果が入ったコミットだけなかったことにすることができた。

方法としては2つあり、コミットIDを特定する等の途中までの手順は同じ。


#コミットIDの確認など


まずは、git logでなかった事にしたいコミットIDを確認

```shell
git log --name-status --oneline
```

念の為、コミットしたファイルのリストを確認

```shell
git log --name-status コミットID
```

（更に念押し）そのコミットを行う直前との差分を確認

```shell
git diff コミットID^..コミットID
```
ここで、
>　**^** は、コミットIDの一つ前を指す記号。

>　**..** は、例えばa..b とした場合にはaからbまでの差分を表す。


ここまでの確認で、自分の取り消したいコミットの内容が明確に把握でき、問題なければそれぞれ、**revert**か**rebase**に進む。




#git revert
そのIDを指定してrevert

```shell
git revert コミットID
```

#git rebase


git rebase -i [コミットID]^



```

```

###


** **:　

** **: 

** **: 

** **: 

** **: 

** **: 


#

[]()

>

>
>
>



###参考にさせて頂いた記事
- []()
- []() 
- []()
- []()


###終わりに。
最後まで読んで頂きありがとうございます:bow_tone1:
転職の為、未経験の状態からRailsを学習しております。正しい知識を着実に身に着け、実力のあるエンジニアになりたいと考えています。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
今現在、初心者だからといって言い訳はできないですが、投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございました。






コマンドでprecompileをしてしまい、
19:30
そのコミットの内容だけ削除したいのですが、
19:31
そういった場合はどういった方法が安全なのでしょうか？

precompileの実行結果だけが一つのコミットに入っている状況であれば、そのコミットを無かったことにすれば大丈夫です。

こちらの方法、
git logでコミット番号を確認し、
git revert コミット番号
19:33
で良いのでしょうか？

GENDOSU(新しいタブが開きます)  19:33
そのやり方でも良いですし
19:33
自分は
たとえば消したいコミットが特定できている場合は
 git log --name-status [コミットID]
で一応ファイルのリストを出して
19:34
確認して
git diff [コミットID]^..[コミットID]
差分出して
19:34
問題なければ
19:35
git rebase -i [コミットID]^
して、[コミットID]の行を削除してます

青山(新しいタブが開きます)  19:35
ありがとうございます！
git diff [コミットID]^..[コミットID]
こちらの　^..　はなにを表しているのでしょうか？

GENDOSU(新しいタブが開きます)  19:37
^は、コミットIDの一つ前を指す記号ですね。
19:38
で、..は、a..b とやった場合にはaからbまでの差分を表示します。

青山(新しいタブが開きます)  19:40
git diff [コミットID]^..[コミットID]
で、消したいコミット単体でなにを変更したかわかる、ということですね！
:+1:
1

19:41
それで、
git rebase -i [コミットID]^
で特定のコミットの一つ前まで表示して、
消したいコミットの行を削除する。
19:41
ということですね！
:+1:
1


GENDOSU(新しいタブが開きます)  19:44
rebaseなので、履歴は書き換わってしまう方法ではあります。
19:45
個人的には revertで履歴が残るのはコミットツリーが長くなるからやだなぁと言う感じでrebaseにしてます。

izszzz(新しいタブが開きます)  19:54
precompile実行の際のコミットを取り消す際にprecompile以外のファイルの変更がある場合conflictなどが起こる可能性があるので、その作業量を加味した上でrevertするか判断してください。

青山(新しいタブが開きます)  19:46
rebaseだと履歴の書き換え、
revertだと特定のコミットを打ち消すコミットを作成するため、その履歴が増える。ということですね。
19:47
ありがとうございます！
すぐにrebaseで確認します。

GENDOSU(新しいタブが開きます)  19:54
デメリットがあるとしたら、書き換わるので、戻したい！って思った時に手順がめんどくさくなるのと
失敗すれば戻せなくなる。というのはあります。

青山(新しいタブが開きます)  20:06
コミットツリーの長さについて気にしないのであれば、慣れないうちは、rebaseのほうが安全ではあるのですね。


20:06
今回は一度rebaseの方で確認します！

git revert　すると
vimに入るので
:q
で抜ける



<img width="519" alt="スクリーンショット 2020-05-09 10.26.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597926/4f8d4a85-0c35-18a9-a2f9-4384f447281a.png">

```shell
git log --graph --date=short --decorate=short --pretty=format:'%Cgreen%h %Creset[%cd] %Cred%d %Creset%s'
```
で
Revert "precompile実行"
が行われている事を確認

念には念で
git diff [コミットID]^..[コミットID]
でrevertした結果、その前後でファイルが戻っているか確認する。
Deno: http クライアントの使い方 (Post)

次のページを参考にしました。
[ky を Deno から使う](https://qiita.com/kt3k/items/4bc0af4ccf595739fc08)

## プログラム

```ts:http_post.ts
// ---------------------------------------------------------------
//	http_post.ts
//
//					Feb/27/2023
//
// ---------------------------------------------------------------
import ky from 'https://esm.sh/ky'

console.error ("*** 開始 ***")

const url = 'https://httpbin.org/post'
const args = { user: "jiro", password: "123456" }
const parsed = await ky.post(url, { json: args }).json()

console.log(JSON.stringify(parsed, null, 2))
 
console.error ("*** 終了 ***")
// ---------------------------------------------------------------
```

## 実行結果

```text
$ deno run  --allow-net http_post.ts
*** 開始 ***
{
  "args": {},
  "data": "{\"user\":\"jiro\",\"password\":\"123456\"}",
  "files": {},
  "form": {},
  "headers": {
    "Accept": "application/json",
    "Accept-Encoding": "gzip, br",
    "Content-Length": "35",
    "Content-Type": "application/json",
    "Host": "httpbin.org",
    "User-Agent": "Deno/1.0.0",
    "X-Amzn-Trace-Id": "Root=1-5ebf5319-b211bb785b6a7b78cbd26ea0"
  },
  "json": {
    "password": "123456",
    "user": "jiro"
  },
  "origin": "210.138.6.64",
  "url": "https://httpbin.org/post"
}
*** 終了 ***
```

## 確認したバージョン

```text
$ deno --version
deno 1.40.5 (release, x86_64-unknown-linux-gnu)
v8 12.1.285.27
typescript 5.3.3
```
Herokuにデプロイした時に自動でマイグレーションを走らせる

デプロイ後、毎回手動で`heroku run rails db:migrate`を打つのは面倒だし、実行を忘れてしまうリスクもあるので、デプロイ時に自動でマイグレーションする方法を探しました。

最初はCircleCIでゴニョゴニョするのかと思ったのですが、Herokuの[Release Phase](https://devcenter.heroku.com/articles/release-phase)という機能を使うとすごく簡単に実装できました。

## 実装
プロジェクトルート(READMEとかがあるとこ)に`Procfile`というファイルを作成し、以下を書き込むだけ

```:Procfile
release: bin/rails db:migrate
```

`bin/rails db:migrate`の部分を編集すれば、他にも自由にコマンドを走らせることができます。

## 参考
- [HerokuのRelease PhaseでDBマイグレーション忘れを防ぐ - shimoju.diary](https://shimoju.org/2018/07/29/heroku-release-phase/)
Deno: http クライアントの使い方 (Get)

次のページを参考にしました。
[ky を Deno から使う](https://qiita.com/kt3k/items/4bc0af4ccf595739fc08)

## プログラム

```ts:http_get.ts
// ---------------------------------------------------------------
//	http_get.ts
//
//					Feb/27/2023
//
// ---------------------------------------------------------------
import ky from 'https://esm.sh/ky';

console.error ("*** 開始 ***")

const url = "https://httpbin.org/get"

const json_str = await ky(url).text()

console.log(json_str)

// const data = JSON.parse (json_str)
// console.log(data["url"])

console.error ("*** 終了 ***")
// ---------------------------------------------------------------
```

## 実行結果

```text
$ deno run  --allow-net http_get.ts
*** 開始 ***
{
  "args": {},
  "headers": {
    "Accept": "application/json",
    "Accept-Encoding": "gzip, br",
    "Host": "httpbin.org",
    "User-Agent": "Deno/1.0.0",
    "X-Amzn-Trace-Id": "Root=1-5ebf5270-1e16ff058c0938e601d3ba47"
  },
  "origin": "210.138.6.64",
  "url": "https://httpbin.org/get"
}
*** 終了 ***
```

## 確認したバージョン

```text
$ deno --version
deno 1.40.5 (release, x86_64-unknown-linux-gnu)
v8 12.1.285.27
typescript 5.3.3
```
git flowとは

##git flowとは
Gitのブランチ構成のルール、及びそのルールを実現するためのツール名です。
構成のルールというと、CSSのSMACSSのようなものですね。

Git flowでは
メインブランチである**master**、**develop**
サポートブランチである**features**、**releases**、**hotfixes**
の全5種類のブランチを利用します。

##各ブランチの説明
###メインブランチ
各メインブランチは、種類ごとに常に1つだけ存在します。
####master
本番リリース用のブランチです。

####develop
開発用のブランチです。開発時にはこのブランチに対してプルリクエストを出します。

###サポートブランチ
サポートブランチは、機能追加やバグの修正などが行われるたびに新たに作成され、不要になったら削除されます。
####features
機能追加のためのブランチです。サービス公開前は大体このブランチで作業し、developブランチに対してプルリクエストを出します。**ブランチ名はなんでもOK**。

####releases
リリースの前段にあるブランチ。機能追加中で未使用のコードなどを本番に反映させないようにするために必要。

####hotfixes
本番環境（masterブランチ)で重大なバグが発生した時に、masterブランチから派生して作成されるブランチです。
修正後、masterブランチとdevelopブランチの両方に取り込まれます。

## 結局何をすれば良いか
- 基本はfeatureブランチを作る→developにマージの繰り返し
- いろいろ要件がある時に他のブランチを使う


##参考
[Git-flowって何？](https://qiita.com/KosukeSone/items/514dd24828b485c69a05)
[【図解】git-flow、GitHub Flowを開発現場で使い始めるためにこれだけは覚えておこう](https://www.atmarkit.co.jp/ait/articles/1708/01/news015.html)
[A successful Git branching model を翻訳しました](http://keijinsonyaban.blogspot.com/2010/10/a-successful-git-branching-model.html)
[Gitを最大限に活用できる「Git flow」で、効率よく開発を進めよう！](https://liginc.co.jp/248864)
vscodeでpythonが認識されない

# だめ
windows10上のvscodeでpythonが認識されない．はじめからはいっているのはどうもないんですが，新しく入れるとだめみたい．

# 症状
1. python.orgから3.8.3 32-bitをinstall
2. vscodeをinstall
3. python extensionをinstall
4. powershellでpythonを実行
5. pathを選択

しても動きません．pathがうまく書き込まれていない．

# 再現法
1. vscodeをclean unsintall
2. python3.2.3, python laucherをコントロールパネルからuninstall

そのあと，症状どおりの操作をすると再現します．

# 対処法はmodify
1. python.installを再度ダウンロードして保存．
  - https://python.org

1. 起動したのちmodifyを選ぶ
![cap1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/1de44201-3cbb-f5da-de7b-3f9fa2d13db4.png)
![cap2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/3d97f089-e703-7203-f607-ad3865d20f01.png)

1. つぎでadd python to environment variablesをチェック．
![cap3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151211/bec234a6-cf6e-baff-d7d7-7e6470983032.png)
してinstallするとvscode側で認識してくれます．

Happy coding!!

# 参考サイト
1. [「Pythonが動かない…」の簡単な解決方法（Windows）](https://gammasoft.jp/blog/resolve-not-to-run-python/)
iPhoneでtracerouteを行う方法

外出先で出会った回線でtracerouteを実行したいと思ったことがあったので、iPhoneで実行する方法がないか調べてみました。

##### 条件

- 基本無料
- 怪しくない　←曖昧注意
- 脱獄不要　　←これ重要





#####調べた結果

#####- Hurricane Electric　　Network tool
https://apps.apple.com/jp/app/he-net-network-tools/id858241710

言語は英語のみですが、このアプリ一本で様々なネットワーク系のツールが実行できます。
おすすめです。

提供元のHurricane Electronic社(以下HE社)とは、主にプロバイダ向けのプロバイダです。(憶測あり)
大手プロバイダーのBGPをみると高確率でHE社が出てきます。
IPv6に至っては世界最大規模のバックボーンネットワークを有するとか有していないとか


ちなみにこのHE社自体、様々な無料ネットワークツールを提供しています。
例えばv6トンネルとかBGPを視覚化するツールなどなど
興味がある方は是非ホームページを覗いて見るといいかもしれません。
https://www.he.net/

特にBGPツールはおすすめです
https://www.bgp.he.net/



#####- a-shell
https://apps.apple.com/jp/app/he-net-network-tools/id858241710

ギガジンでも紹介されたオープンソースのアプリです。
スマホでターミナルの簡易版を実行するアプリです。

tracerouteの使い方は簡単。
tracerouteのコマンドを打ち込んでenterするだけです。
個人的には毎回打つのは面倒と思っています笑

end
シリコンバレーエンジニア 酒井潤さんのyoutube　まとめ


### モチベーション

- 危機感を感じれる環境

酒井さんは海外に行った事があり、貧しい人達にあった事や、
シリコンバレーで、ホームレスの人などにあった時に明日は我が身と思う（ここまでは思っていないと思うけど）環境が周りにあるから、モチベーションを高めて仕事ができると。

それはすごい分かるなと思った。自分も、お金に対する危機感を感じた事があったので、大金持ちになりたいまでは行かずとも、年収1000万円は超えないと貧しい人生が待っているという危機感から、休みの日も勉強出来ていると思う。

### コード量について

- 酒井さんは一日200行ほどらしい。

結論、コード量ではなく、コードに込めた意図、配慮の量が大事。
大手になればなるほど、コード量が少なくなる。

大手になればなるほど、1行の修正が影響を及ぼす範囲は多くなる。
自分も1行の修正で数百万円の損失を出しそうになって、冷や汗を書いた事がある

### シリコンバレーで必要な年収

- 平均年収 1200万円
- 税金 30%
- 使えるお金 6,70万円
- 家賃 40万円（家族4人）
- 日本人の400万円の年収と変わらない感覚らしい
- 貧困エリアで子育ては大変（差別）

### webエンジニアはいるのか

- webエンジニアは、djangoなどのフレームワークを利用してサービスを開発する人
- pythonが多い
- マイクロサービス


### キャリア戦略

1.海外転職
2.海外留学して就職
3.海外の支店がある会社で海外転職する

1.海外転職


情報系の大学院に入る
HMB
アメリカの日系企業を狙う


H1Bとは

2.海外留学

学費の貯蓄する
アメリカの大学院

3.


## アメリカで働くビザの条件


- カナダ, オーストラリア,シンガポール
- 条件