OmniAICreator/Qiita-1.07M huggingface dataset:
【Python】Docker で OpenCV 環境構築 ( cv2.imshow() も動く )

以前このような Qiita ( [Ubuntu, Python, OpenCV な環境を Docker 上でつくった ](https://qiita.com/RyuGotoo/items/8b3f48057ce61641b877)) を書いたのですが `cv2.imshow()` が機能せずいろいろ試行錯誤していました。

この記事では Docker 環境でもちゃんと `cv2.imshow()` が動くようにする方法を書きます。

ホスト OS は MacOS Catalina です。

# 1. XQuartz インストール

https://www.xquartz.org/

インストールしたら XQuartz の環境設定からセキュリティタブのネットワーク・クライアントからの接続を許可にチェックを入れる。

# 2. xhost 開放

```bash
xhost +
```

# 3. Docker run

```bash
docker run -it \
-v $(pwd):/code \
-v ~/.Xauthority:/root/.Xauthority \ # Docker と GUI のやり取りをするために必要
-e DISPLAY=$(hostname):0 \ # Docker と GUI のやり取りをするために必要
-p 8888:8888 \ # Jupyter 用
--name opencv \ 
ubuntu /bin/bash
```

# 4. 各種アップデート・インストール

コンテナ内で以下を実行

```bash
apt-get -y update && apt-get -y upgrade && \
apt-get -y install python3-pip vim libgl1-mesa-dev libgtk2.0-dev && \
pip3 install numpy opencv-python jupyterlab pandas matplotlib scikit-learn seaborn scipy
```

# 5. 動作チェック

1. ホスト PC で XQuartz 立ち上げる

2. Jupyter 起動 ( コンテナ内 )

```bash
jupyter lab --ip=0.0.0.0 --allow-root --LabApp.token=''
```

3. ホスト PC のブラウザで http://localhost:8888/ にアクセス

4. Jupyter で以下を実行

```python
import cv2

img = cv2.imread('test.jpeg') # なにか適当な画像を入れておく
img.shape # => ( 画像の縦の長さ, 横の長さ, 3 ) が返ってくる

cv2.imshow('img', img) # 画像を表示したいときはこの 3 行セットで実行する
cv2.waitKey(0)
cv2.destroyAllWindows
```

---

以上がエラーなく動作すれば OK !! お疲れさまでした !!!
dbpediaの研究 その36

#概要　

dbpediaが難解なので、手出してみる。
鉄道駅LODやってみた。

#参考にしたページ

https://qiita.com/uedayou/items/3ba823c5d3bede12af9c


#データモデル

##class:駅

rdfs:label			駅名
wdt:P833			乗り換えが可能な駅
wdt:P465			路線の色
schema:description	駅についての説明
wdt:P81				路線
propja:所属路線		路線の名称
wdt:P137			鉄道会社
dbpediaowl:operatedBy	鉄道会社の名称
geo:lat				緯度
geo:long			経度
owl:sameAs			同一駅についての別サイト
foaf:homepage		駅の公式サイト
dbpediaowl:address	住所
ic:住所				住所LOD


##class:路線

rdfs:label			路線名
wdt:P527, dcterms:relation	路線内の駅
wdt:P2043			路線距離
wdt:P465			路線の色
schema:description	路線についての説明
wdt:P137			鉄道会社
dbpediaowl:operatedBy	鉄道会社の名称
owl:sameAs			同一路線についての別サイト
foaf:homepage		路線の公式サイト


##class:鉄道会社

rdfs:label			会社名
wdt:P527			鉄道会社が運営する路線
schema:description	会社についての説明
owl:sameAs			同一会社についての別サイト
foaf:homepage		会社の公式サイト
skos:altLabel		会社の別名
wdt:P2002			会社のTwitter ID
wdt:P2397			会社のYouTubeチャンネルID










#エンドポイント

https://api.jrslod.uedayou.net/sparql

#使える語彙


PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dcterms: <http://p.org/dc/terms/>
PREFIX schema: <http://schema.org/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX propja: <http://ja.dbpedia.org/property/>
PREFIX dbpediaowl: <http://dbpedia.org/ontology/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX ic: <http://imi.go.jp/ns/core/rdf#>
PREFIX class: <https://uedayou.net/jrslod/Class/>

#サンプルクエリー

```
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX class: <https://uedayou.net/jrslod/Class/>

SELECT distinct * 
WHERE {
    ?uri a class:駅;
        rdfs:label ?label.
    FILTER(regex(?label, '東京'))
}
```

#成果物

http://embed.plnkr.co/plunk/JKtumLaKsK7XtG5P

以上。
dbpediaの研究 その35

#概要　

dbpediaが難解なので、手出してみる。
温泉宿・適応症LOD、やってみた。
山形の温泉、leafletで表示してみた。

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/17b656f3-6da3-f1ff-2e7b-b488f941eb6a.jpeg)


#投げたsparql


```
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX schema: <https://schema.org/>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX prop-ja: <http://ja.dbpedia.org/property/>
PREFIX hs: <http://purl.org/net/hotspring/>
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>

SELECT DISTINCT ?title ?lat ?lon
WHERE {
    ?link schema:name ?title;
        geo:lat ?lat;
        geo:long ?lon;
        schema:address ?address.
    FILTER regex(?address, "山形")
} 

```

#成果物

http://embed.plnkr.co/plunk/Kgu63NRHDvt7h6jV

以上。
【Laravel】Collectionのpluckメソッド

##はじめに
今回もLaravelのCollectionのメソッドについてまとめたいと思います。

##pluckメソッドで指定したキーの配列を取得する

例えば、nameの値のみをを取得する場合下記のような実装になります。

```php:
$collection = collect([
    ['id' => 1, 'name' => '山田', 'age' => 18],
    ['id' => 2, 'name' => '佐藤', 'age' => 38],
    ['id' => 3, 'name' => '小林', 'age' => 25],
]);

$names = $collection->pluck('name');

print_r($names->toArray());
```

実行結果は下記になります。

```
Array
(
    [0] => 山田
    [1] => 佐藤
    [2] => 小林
)
```

`pluck('id', 'name')`のようにidとnameなど複数指定するとその指定した値のみを配列にして取得することもできます。

##おわりに
いかがでしたでしょうか。
指定したキーの配列を取得をして試してみてください。
with_optionの使い方

##with_optionとは
同じオプションを使った記述が複数存在している場合、
それらを一つにまとめることができるもの。
記述量を少なくできることが利点。


##使い方
例　app/models/item.rbファイルに、以下の同じオプションを使っているコードが複数あるとする。

```
validates :category_id, numericality: { other_than: 1 }
validates :days_to_send_id, numericality: { other_than: 1 }
validates :item_condition_id, numericality: { other_than: 1 }
validates :prace_id, numericality: { other_than: 1 }
validates :fee_id, numericality: { other_than: 1 }
```







この時、with_optionを使えば、以下のように記述量を少なく、みやすいコードにすることができる。


```
with_option numericality: { other_than:1} do
 validates :category_id
 validates :days_to_send
 validates :item_condition_id
 validates :prace_id
 validates :fee_id
end

```

以上になります。
経歴の浅いエンジニアがOSSにプルリクを送ってみた話

## EC-CUBEプルリクを送ってみた話

タイトルにもございますように、オープンソースソフトウェアであるEC-CUBEコミットしましたので、記したいと思います。

私は経歴１年半程度のエンジニアで「OSSコミッター」というと、いかにもツヨツヨでギークな方がやっているイメージが強かったのですが、こんな私でもできたので、少しでも多くの方がやってみようと思えるように、手順と心構えを記したいと思います。

## なぜEC-CUBEか
EC−CUBEとの関わりは業務で使用したことがきっかけです。
カスタマイズをしていた印象としては、[開発ドキュメント](https://doc4.ec-cube.net)があるため経歴の浅いエンジニアだった私にとって、お作法を学ぶ上でもいい題材であると感じました。

当時私よりも更に経験の浅いエンジニアにタスクの割り振りをしていた私は「このタスクはちょうどいいな、Aさんの勉強になる」と無意識に、経験を積む上でいい題材を選んでいることに気づきました。そこでEC-CUBEを使ったタスク集があれば、エンジニアを目指している人やエンジニアになったばかりの人が、実務で経験するようなタスクを体験できるのではないかと思ったのです。実務では通常ソースコードはセキュリティ上の問題で一般公開することができないですが、OSSであるEC-CUBEは実務でも広く使われている上に、誰でも見ることができます。それで作ったのが[未経験からエンジニアがキャリア初期に、任されるあろう３つのタスクを出題してみる](https://qiita.com/morry_48/items/7dea1145d2db8bb7f570)でした。こちらの記事は多くの方に読んでいただき、EC-CUBE社の方の目にも止まったようで、中の人と個人的なお付き合いができました。そんなやり取りの中で「よかったら、モーリーさんも開発に参加してみてください。簡単なタスクもあるのでお気軽に」と言っていただけたことがきっかけでした。

## OSSに参加するメリット
### ①日頃お世話になっているプロダクトに貢献できる（課題解決の経験ができる）
なんと言ってもこれが大きい
### ②エンジニアとしてちょっとした錯覚資産が得られる
関わる前に当初私が抱いていたように、エンジニア仲間にOSSコミット経験があると伝えると一目おいてもらえるようなケースがありました。
### ③転職市場において有利になる（多分）
知らんけど。

## 手順を記してみる
本当であれば、自分で問題点を上げてISSUEに上げることが一番の貢献かなと思うのですが今回はコミットすることへの心理的な障壁を下げることが目的なので、最も手軽に参加できる方法を取ります。

それはまずたくさんのISSUEの中から、自分でもできそうなタスクをみつけることです。
いっぱいあって難しそうなものばかりのように思えますが「EASY」とタグが付いているISSUEに絞ってみると比較的簡単そうなタスクもあることがわかると思います。→https://github.com/EC-CUBE/ec-cube/issues?q=is%3Aopen+is%3Aissue+label%3AEasy

私の初挑戦となったISSUEはこちら→https://github.com/EC-CUBE/ec-cube/pull/4709
登録の際の管理項目で必須項目となっているものに「必須」というラベルをつける内容になります。

issueの内容見ると自分でもできそうな気がしますよね？？
ラベル部分にspanタグを追加するだけのタスクで且つ別画面には、すでにこの対応はされているため、実質コピペするのみでした。

手順としては
①自分のgithubアカウントにプロジェクトをフォーク（ドキュメント通りにやれば簡単です）
https://doc4.ec-cube.net/contribution-guide/pull-request
②ISSUEに自分が対応することを意思表示
③コードを修正する
④プルリクエストを作成します。他の方が挙げているのを参考にすればOK

私の場合は、簡単なタスクだったので一発でLGTMでした！

## コミットしてみて
これを読んで、「何だただの文言修正か」と思う方もいらっしゃると思いますが、いまつよいエンジニアの方も最初から、いきなり難しいことができたわけではないと思うので、まずは参加してみることが大事なのかなと思いました。

エンジニアのの会話のきっかけにはなりますし、皆様も是非挑戦してみてください。

意外と簡単そう！と思っていただけると幸いです。

なにかご指摘等ございましたら、コメントください！
UnityCollabの登録/共有ユーザーの追加方法

ゲーム開発に向けてチーム共有のためデータ共有の方法を調べているとUnityCollabなるものを見つけたので、わからないながらも使ってみました。
自分用の備忘録でもあります。

#UnityCollabにプロジェクトを登録する
①Unityの右上のほうにCollabというボタンがあるので押してユーザーを登録し、プロジェクト名を登録する。

ーとかだったような気がする。
ー覚えていない。
ーググりながらやってた。
ー次はメモりながらやろう。（戒め）

#「組織」を作成する
①Unity開発者ダッシュボードで「組織」を作成する
②UnityHub右上のアカウントをクリックすると「開発者ダッシュボードに移動」というのがあるので移動する。
③組織を適当に作成する。
**組織名はあとからでも変更できるし、クレジットカードなどを登録する必要はないので気軽に適当に作成する。**

![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501431/19549972-e08a-df1d-b3b1-1a0d87f3e3fc.png)

#メンバーを追加する
①組織画面からだと画面右下に「メンバーグループ」のとなりに「すべてを見る」ボタンがあるのでクリックする。

![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501431/cafdf66a-cd7a-587a-1197-844af2a4cee2.png)

②「メンバーを追加」ボタンをクリックすると追加画面に移るので追加したいユーザーのメールアドレスを入力し、役割を適当に設定し招待する。
**※メンバーの役割はあとででも変更可能**

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501431/f32c1ef8-73b8-ba03-3e7f-6c9d592b63ca.png)

ただ、このままでは追加したユーザーは変更箇所をプッシュしても共有できないようなのでUnityダッシュボードでも追加する。

③UnityID画面が全画面表示の場合、左側にメニューが表示されるので「プロジェクト」をクリックする。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501431/db3ac559-78d9-404e-8640-e056d03fa5a3.png)

④すると、今まで作ったプロジェクトの一覧が表示されると思うのでユーザーを追加するプロジェクトをクリックする。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501431/5c860f17-7aff-2dd3-3ac8-0f4cf237a6ba.png)

⑤画面左のSetting→Usersをクリックすると現在のプロジェクトに登録されている共有ユーザーの一覧が表示されるのでドロップボックスから組織で登録したユーザーを選択し、追加する。
これで該当プロジェクトでユーザー共有ができていると思う。

![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501431/c21a823b-dccc-f58c-6544-6f33f0cd5f59.png)

#所感
お金はかからないし、共有サイズは1GBのみだけどゲームデータのみだけだし特に問題はないかなと今のところ思っています。
Libraryフォルダは参照していないのでキャッシュは含めていないようです。DropBoxなどローカルフォルダとクラウド同期型のAssetフォルダ参照のみということでしょうかね？
無料でも3人まではチーム共有できるので悪くはないのかなと思います。VisualStudioでのチームエクスプローラーやSourceTreeよりかは導入としては楽なような気がするので今後はこれで進められたら楽そうですかね。

あと、記事を書いている途中で思ったんですけどメンバー追加の①②では組織には所属するけどプロジェクトには追加していないっていうことなんですかね？③④⑤でプロジェクトに追加するみたいな感じかな？
他のプロジェクトを見る限りユーザーを追加していなければそこのプロジェクトの所属ユーザーは自分のみだし、組織には追加されていても共有はされないっぽいので確かにプロジェクト単位での追加方法になるのかなと思いました。
終わり。

【参考リンク】
[【Unity】Unity Collaborateでリアルタイム通信コンテンツの制作フローを効率化](https://qiita.com/OKsaiyowa/items/4c314b33f583c9d1f798)
[初心者向け！Unity Collaborateを使ってみる](https://qiita.com/warapuri/items/bfb2a7cdbbcebaa172cc)
Rails + Postgres + github actions でCIを構築する

# 結論から
最初に完成版を先に提示するとこうなりました。

```yml
name: Verify
# This workflow is triggered on pushes to the repository.
on: [push]

jobs:
  build:
    # Job name is Greeting
    name: verify
    # This job runs on Linux
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:12
        ports:
          - 5432:5432
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: password
          POSTGRES_DB: test
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
    container:
      image: ruby:2.5.3
      env:
        RAILS_ENV: test
        POSTGRES_HOST: postgres
        RAILS_DATABASE_USER: postgres
        RAILS_DATABASE_PASSWORD: password

    steps:
      - name: checkout
        uses: actions/checkout@v2
      - name: bundler set up
        run: |
          gem install bundler
          bundle install
      - name: install node
        uses: actions/setup-node@v1
        with:
          node-version: '12'

      - name: db migrate
        run: |
          bundle exec rails db:migrate

      - name: verify
        run: |
          bundle exec rubocop
          bundle exec rspec

```

# postgresの構築
処理順番として先にpostgresを立てて、その後にrailsが駆動するようにしています。

```yml
  service:
     postgres:
        image: postgres:12
        ports:
          - 5432:5432
        env:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: password
          POSTGRES_DB: test
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
```

ここのoptionでヘルスチェックをして問題なければ、railsの構築処理に進むようになっています。
postgresのイメージを使っているのですが、パスワードの未指定or空文字列を受け付けてないので必ず指定しましょう。


# rails の環境構築

* bundlerをインストール
* bundlerでgemをインストール
* DBをmigration 
* テスト、lintを実行

上記の順序で作業が行われます。
ただrailsを環境構築する場合、ruby と jsを実行、解析できる環境が必要になるので、

```yml
     - name: install node
        uses: actions/setup-node@v1
        with:
          node-version: '12'
```

の部分でnodeを導入しています。

# postgres連携

```yml
    container:
      image: ruby:2.5.3
      env:
        RAILS_ENV: test
        POSTGRES_HOST: postgres
        RAILS_DATABASE_USER: postgres
        RAILS_DATABASE_PASSWORD: password
```
DBmigrationのために環境変数をrailsに対して色々設定しています。

### 名前解決

```
POSTGRES_HOST: postgres
```

は接続するpostgresのホストを名前解決しています。
この右側の`postgres`と言う文字列は、postgresの構築で出てきた、
service直下のやつを指定しています。

こんな感じでservice名を指定することで名前解決をできたりします。

左の`POSTGRES_HOST`はrailsのdatabase.ymlの使用したい環境のhostでどの環境変数が使われているかを確認して、
変えるようにしましょう。

### 環境指定

RAILS_ENVを指定することで、railsをどの環境で動かすかを指定します。
今回はテストを動かしたいため、testと指定しています。

### その他の環境変数
当たり前ですが、 env:以下に環境変数を色々追加できるので、
実行時に必要となる環境変数を書きましょう。
ただし、外部へのAPIキーなど機密性が高いものに関しては secretを活用しましょう。


# 終わりに
railsを初めて触ったのですが、DB - Railsの名前解決にやたらと時間がかかりました。
また、やっつけ仕事で作ったのでキャッシュなどはまだやってないので時間が開けば追加したいと思います。
Railsで本番環境(EC2, AmazonLinux)でPDF出力ができない

## 本番環境(EC2, AmazonLinux)でPDF出力ができない
`wicked_pdf`と`wkhtmltopdf-binary`というGemを使ってPDF出力機能を付けていますが、開発環境ではうまく行くのに本番環境では下記のエラーが発生。
Railsのバージョンは4.2です。

```ruby
RuntimeError (Failed to execute:
["/var/www/~~~/shared/bundle/ruby/2.4.0/gems/wkhtmltopdf-binary-0.12.6.3/bin/wkhtmltopdf", "--encoding", "UTF-8", "--page-size", "A4", "file:////tmp/wicked_pdf20201007-11835-gppxfs.html", "/tmp/wicked_pdf_generated_file20201007-11835-j83wu8.pdf"]
Error: PDF could not be generated!
 Command Error: /var/www/~~~/shared/bundle/ruby/2.4.0/gems/wkhtmltopdf-binary-0.12.6.3/bin/wkhtmltopdf_centos_7_amd64: error while loading shared libraries: libpng15.so.15: cannot open shared object file: No such file or directory
):
```

`libpng15.so.15`というライブラリがない様ですが、同様のエラーをネットで調べて色々と試しましたが解決しませんでした。

## Gemを変更し解決
2016年の記事ですが、下記が参考になりました。
https://qiita.com/s-mori/items/00aef46e6a10499f8254
https://qiita.com/yaboojp/items/526c9397070ca5d05256

`wkhtmltopdf-binary`はAmazonLinuxに対応していない様で、
AmazonLinuxに対応している`wkhtmltopdf-binary-aml`を使うことでうまくいきました。

修正前のGemfile

```Gemfile
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary-aml'
```
修正後のGemfile

```Gemfile
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary-aml', git: 'https://github.com/insphire/wkhtmltopdf-binary-aml'
```
修正前の`wicked_pdf`

```config/initializers/wicked_pdf.rb
WickedPdf.config = {
  :exe_path => "#{Gem.loaded_specs['wkhtmltopdf-binary'].full_gem_path}/bin/wkhtmltopdf"
}
```
修正後の`wicked_pdf`

```config/initializers/wicked_pdf.rb
WickedPdf.config = {
  :exe_path => "#{Gem.loaded_specs['wkhtmltopdf-binary-aml'].full_gem_path}/bin/wkhtmltopdf"
}
```

Bundlerのバージョンが変更されない様にして、bundle installしました。
`$ bundle _1.16.1_ install`

## 日本語表示に対応させる

本番環境にデプロイすると、日本語表示がされていませんでした。
なのでIPAフォントを本番サーバでインストールします。

```
cd /usr/share/fonts

$ yum install -y ipa-gothic-fonts ipa-mincho-fonts
```

フォントを変更したことでレイアウトが崩れてしまったので、CSSなどを整えて、領収書機能を完成させることができました。

## 開発環境でのエラー
AmazonLinux対応のGemに変更したことで、今度は開発環境でエラーが起こる様になってしまいました。

```
RuntimeError - PDF could not be generated!
 Command Error: /Users/~~~/vendor/bundle/ruby/2.4.0/bundler/gems/wkhtmltopdf-binary-aml-e5340ed88aa8/bin/wkhtmltopdf:15:in `exec': Bad CPU type in executable - /Users/~~~/vendor/bundle/ruby/2.4.0/bundler/gems/wkhtmltopdf-binary-aml-e5340ed88aa8/libexec/wkhtmltopdf-darwin-x86 (Errno::E086)
```

開発環境でも本番環境でもうまくやるには、`wicked_pdf.rb`を`if Rails.env.production?`などを使ってかき分けたり、
Gemfileを以下の様にして環境別に切り替えればできます。

```ruby
group :development do
 gem 'wkhtmltopdf-binary'
end
```

```ruby
gem 'wkhtmltopdf-binary', group: :development
```
MacBookの設定

## はじめに
皆さんが常日頃使っている、MacBookの設定について記事にしました。
この記事で得られることは以下の通りです。

・ MacBookの設定を最適化する事で、作業効率が良くなり生産性が上がる

# トラックパッドの設定

![スクリーンショット 2020-10-10 9.03.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/0e454ed3-7592-dfa5-c2e1-a25a894a32a2.png)

#### ・ タップでクリック（1本指でタップ）にチェックを入れる
→ 操作時間の短縮・効率化

#### ・ 軌跡の速さを速いに設定する
→ 動きを速くする事で、操作時間を短縮し効率化&疲労減少にも繋がります

# Dockの設定
![スクリーンショット 2020-10-10 9.24.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/0abadfd0-a825-a4f9-6166-de1a9d726ecf.png)

#### ・ サイズ（Dockアイコンの大きさ）
→ お好みですが、小さくして操作の機能性をとるか、大きくすることで正確性をとるかの違いだと思います

#### ・ ウィンドウをしまうときのエフェクトをスケールエフェクトにする
→ ジニーエフェクトの場合
![ジニーエフェクト.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/56078821-11cf-9bb7-907d-a029409271ea.gif)

→ スケールエフェクトの場合
![スケールエフェクト.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/1b534271-3b46-aa02-b707-8790103a8636.gif)

#### ・ Dockを自動的に表示/非表示にチェックを入れる
→ Dockが表示されている分、常に画面領域を取られているので、非表示にする事で画面を広く使えます

# ディスプレイの設定

![スクリーンショット 2020-10-10 10.13.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/712cd028-c23d-99b2-9083-aa96d52ed30e.png)

#### ・ 「ディスプレイ」より「解像度：変更」をクリックし、「スペースを拡大」をクリックする
→ ディスプレイのデフォルトに比べ、表示領域が格段に広くなります

![スクリーンショット 2020-12-16 10.53.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/0e4edc54-c228-fb6d-3d6a-a5aa2e3fbdc5.png)

#### ・ 「Night Shift」の「スケジュール」を「カスタム」にし、開始を「0:00」、終了を「23:59」にする
→ Night Shiftを常にONにし、ブルーライトをカットする事で、目が疲れにくくなります

#### ・ 色温度を「暖かく」最大に設定する
→ すごく違和感がありますが、次第に慣れてくると思います

![スクリーンショット 2020-12-16 11.06.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/4261c253-f8e8-4653-38ca-5a8efd69501c.png)

#### ・ 「デスクトップとスクリーンセーバ」より、壁紙をブラックにする
→ 集中力向上、電池の消費が減るメリットがあります

![スクリーンショット 2020-12-16 11.12.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/692cea54-1be5-037c-b2c8-893efa6d6fd2.png)

#### ・ 「一般」より、外観モード：ダークに設定する
→ 壁紙をブラックにすると同様で、目とバッテリーに優しく、集中力UPが期待できます

# アクセシビリティの設定

![スクリーンショット 2020-10-10 15.02.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/15a4b2c6-c0f2-2b19-48f9-035e05daba16.png)

#### ・ 「アクセシビリティ」より「ポインタコントロール」、「トラックパッドオプション」をクリックし、スクロールの速さを「速い」に設定する
→ Webページ等でスクロールする際の速度を速くする事で、労力を減らし、目的の情報に素早く辿り着きます
Docker Desktop for Mac をHomebrewでインストールする

# 目的

- HomebrewでDocker Desktop for Macをインストールする方法をまとめる

# 前提条件

- Homebrewが使える状態になっていること。（$ brewコマンドが実行できること）

# 詳細

1. 下記コマンドを実行してHomebrewを最新状態にする。

    ```terminal
    $ brew update
    ```
1. 下記コマンドを実行してDockerをインストールする。

    ```terminal
    $ brew install docker --cask
    ```
1. 下記コマンドを実行してインストールしたファイルを開く。

    ```terminal
    $ open /Applications/Docker.app
    ```
1. ユーザパスワードを聞かれたら入力する。
日別訪問者数の最大平均区間(large)

#0.問題
対象となる全日数をDDとし、全日数のうちあるN日間に訪問してくる
人数の平均が最大になる区間の開始日の候補日の数と、それらの候補日の中で
最も早い日をあげなさい。

![0C94A4B5-A272-4603-A43D-1A638670F165.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/e34ef4bf-fa3e-c86d-220f-0f4de5b84595.png)


この問題を解くに当たり考えたことをまとめてみた。
下記の手順でクリアできた。

#1.最初に図を書いてみる

与えられのは以下の二行。

```math
一行目に全日数(DD)と求めたい区間の日数(N)\\
二行目にそれぞれの日数の訪問人数(A_i(i=1,,,DD))
```

`5 3`
`1  2  3  2  1`

![IMG-2991.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689780/7bffa1cb-1649-be61-bdba-a9b0130480fd.jpeg)

上記のように考えていくと、
開始日が2日目が日別訪問者数が8人となり最大平均区間になる。
また、この訪問者数が最大になるのは開始日が2日の時のみなので、候補日の数は
1となる。
答えは「1 2」となることがわかる。



#2.考え方(パターン分け)

ここで__`平均が最大になる＝ある区間の日別訪問者数の和が最大になる`__と考える。


##`(1)DDとNが同じ場合`

⇒DDまでの訪問者数の計算する必要はない
候補日も、区間のパターンも一つしかないので、[1 1]が答え

##`(2)DD>NでかつN>1の場合`


```math 
X_1=A_1+...+A_{N}\\
max1=X_1(max1:N日間での最大訪問者数)\\
C_{day}=1(C_{day}:候補日の数)\\
S_{day}=d(S_{day}:N日間での最大訪問者数の開始日)
```

```math 
X_d:dを開始日とした時のN日間の訪問者数とする
前の章より、下記のことがわかる。
この漸化式により、計算回数も減らせる。
```
```math 
X_d=X_{d-1}-A_{d-1}+A_{d-1+N}(d=2,,,DD-N+1)-★\\

``` 

###` ⅰ)ある開始日dのN日間の訪問者数>最大訪問者数の処理`


```math
C_{day}=1\\
max1=X_d\\
S_{day}=d

```

###` ⅱ)ある開始日dのN日間の訪問者数＝最大訪問者数の処理`

```math
C_{day}=C_{day}+1\\
max1=X_d

```


##`(3)DD>NでかつN=1の場合`


```math
X_d=A_d(d=1,,,DD)
```
上記に(2)の場合の1)、2)の条件の処理を考えればよい。



#3.コード例

```python

in1=input()
in2=input()
arr1=in1.split()
arr2=in2.split()

dn=0

num1=int(arr1[1])
#print(num1)

if num1>1:
    i=0
    for i in range(num1):
        dn=dn+int(arr2[i])

    max_t=dn
    max_i=0
    k_cnt=1

    for i in range(1,int(arr1[0])-num1+1):
        dn=dn+int(arr2[i+num1-1])-int(arr2[i-1])

        if max_t<dn:
            k_cnt=1
            max_i=i
            max_t=dn

        else:
            if max_t == dn:
                k_cnt=k_cnt+1
                max_t=dn

    max_i=max_i+1
    print(str(k_cnt)+' '+str(max_i))

elif num1>1 and num1 == int(arr1[0]):
    print('1 1')
else:
    max_i=0
    max_t=0
    k_cnt=1
    for i in range(int(arr1[0])):
        dn=int(arr2[i])
        if max_t<dn:
            max_t=dn
            k_cnt=1
            max_i=i
        else:
            if max_t == dn:
                max_t=dn
                k_cnt=k_cnt+1

    max_i=max_i+1
    print(str(k_cnt)+' '+str(max_i))

```
【AWS】APIGatewayにキャッシュを設定する際にハマったこと

#はじめに
先日APIGatewayにキャッシュを設定しようとしてハマったので記事にしておきます。

#キャッシュを無効化させたくない！
エンドポイントへのHTTPリクエストヘッダに**[Cache-Control: max-age=0]**が含まれていた場合も、APIGatewayの後ろに控えたLambdaを実行させたくない！**キャッシュがある場合は必ずキャッシュを受け取ってほしい**。

#APIGateway設定
キャッシュの設定自体はキャッシュ有効化にチェックをつけ、キャパシティーやTTL等を自由に設定しておしまいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663118/7843e19e-48d7-2e63-3951-76ec4bdfa081.png)
キャッシュコントロールヘッダについての設定は「キーごとのキャッシュの無効化」にあたります。
画像の設定では「認可されたリクエストで無ければ、HTTPリクエストに**[Cache-Control: max-age=0]**が含まれていた場合403エラーとして返すよ」という状態。

#キャッシュ無効化できる…！？
この状態でターミナルから以下curlコマンドを叩いても、何事も無かったかのように応答が返ってきます。
ついでにCloudWatchでログを見るとキャッシュが効いていないログが確認できます。

```cmd
curl <APIGatewayエンドポイントURL> -H "Cache-Control: max-age=0"
```

#HTTPリクエストメソッド単位の設定が必要
先ほどキャッシュを設定した画面ですが、実はステージ単位だけではなくHTTPリクエストメソッド単位でも設定できるようになっています。
ここでステージ単位の設定を上書きしてしまっていたことが原因でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663118/934f69c5-ee74-350a-ba23-5257d2d0c7fd.png)
認可が必要にチェックが入っていないのでキャッシュ無効化し放題です。

#解決！
リクエストメソッド単位でもステージ単位と同様にキャッシュの設定を行うことで、**[Cache-Control: max-age=0]**付きのcurlコマンドを実行すると無事エラーで応答されるようになりました。

以上です。お疲れ様でした:cat2:
three.js tiletipの切り取り

### onload で切り取る。
https://codepen.io/gnjo/pen/wvWBRbG

```js
//...

function tip(num,size){return (tex)=>{
  size=size||16,num=num||0;
  let img=tex.image,w=img.naturalWidth,h=img.naturalHeight
  ,c=document.createElement('canvas'),ctx=c.getContext("2d")
  ,nw=~~(w/size),nh =~~(h/size),x=num%nw,y=~~(num/nw)
  ;
  c.height=c.width=size
  ctx.drawImage(img,x*size,y*size,size,size, 0,0,size,size)
  tex.image.src=c.toDataURL()
  tex.needsUpdate=true////
 }
}

//var loader=new THREE.TextureLoader()
//let tex=loader.load(url,tip(number,size))

```
node.js(express)でパスワードのハッシュ化   〜bcryptモジュールの使い方〜

## bcryptとは
`password`を`$2b$10$7f9myKwdo9BDUOkybKpQoOSMeEX90aRRFfOdj.c3dG6RIjZxZ/a4m`みたいな感じにぐっちゃぐちゃにしてくれるnpmモジュール


## 使い方
まずはrequireで読み込み

```js
const bcrypt = require('bcrypt')
```
ハッシュ化

```js
const hashed = bcrypt.hash(req.body.password, 10)
//bcrypt.hash(ハッシュ化したいpassword, ストレッチング回数)
//ストレッチング回数 =ハッシュ化の回数で、2のn乗のnのことで4~31を指定できる
```
照合

```js
const compared = bcrypt.compare(req.body.password, docs.password)
//bcrypt.compare(ハッシュ化前のpassword, ハッシュ化後のpassword)
```

## ポイント
- bcrypt.hashは時間がかかる為、非同期処理としてコントロールする必要。`async` `await`をつける  
- hash後にhash化したパスワードをデータベース等に保存する処理を書くことが多いと思いますが、その場合`async` `await`をつけないとハッシュ化が終わる前に次の保存処理を実行してしまう為、passwordがみつかりませんよ！みたいなエラーが出る。
- bcryptには`hashSync`というメソッドも用意されており、これを使っても`async` `await`同様の同期的な動きをとる。が、どこかで非推奨？と見た事があります。


## 使用例　
現在勉強のため制作しているTodoアプリでexpress, mongooseを使っていますので、そこで使ったユーザー登録とログイン処理での使用例を記載致します。


<新規ユーザー登録>
クライアントからのフォーム送信で受けた新規ユーザーのpasswordを、ハッシュ化しデータベースに登録


```js
router.post('/register', async (req, res) => {
  const hashedPassword = await bcrypt.hash(req.body.password, 10)
  
  console.log(hashedPassword);
//hashedPasswordにpromiseが返ってくるためawaitで処理の完了を待つ
//試しにawaitを外すとPromise{pending}がlogされる
//pendingは「わたし待ってます」状態
  
  const userData = new User({
    username: req.body.username,
    password: hashedPassword
//ここでhashedPasswordのpromiseが解決している必要がある
//そのためbcrypt.hashにawaitをつけて10回hashされるのを待ってから次の処理に進むように制御する
  })
 
// --- 以下DB登録処理 --- 
    User.find({ username: userData.username }, (err, docs) => {
    if (docs.length) {
      res.send({
        msg: 'そのユーザー名は使えません'
      })
      return
    } else {
      User.insertMany(userData)
      .then(() => res.send({
        msg: '登録が完了しました！ログインしてください'
      }))
    }
  })
})
```

<ログインユーザーの照合>
クライアントからのフォーム送信で受けたユーザーネームとpasswordをデータベースと照合し、合致するデータを取り出す

```js
router.post('/login', (req, res) => {
// ユーザー名でデータベース検索する処理のサンプル
 
 User.find({
    username: req.body.username,
  }, async (err, docs) => {

    if (!docs.length) {
      res.send({
        msg: 'ユーザー名 か パスワード が間違っています',
        isLogin: false
      })
      return
    }
      
// ここからハッシュ前のpasswordとDB内のハッシュ済のpasswordとの照合
      
    const compared = await bcrypt.compare(req.body.password, docs[0].password)
// bcrypt.compare(ユーザーが入力したpassword, DBから引っ張ってきたハッシュ化済のpassword)
// bcrypt.compareもPromiseが返してくるのでasync,awaitで制御を加える
// 照合が終わったら次の処理へ進むようになる
    
    console.log(compared)
// passwordがあってればtrue まちがっていればfalse


    if (!hassed) {
      res.send({
        msg: 'ユーザー名 か パスワード が間違っています',
        isLogin: false
      })
      return
    } else {
      res.send({
        msg: 'ログインできました',
        isLogin: true,
        username: req.body.username
      })
    }
  })
})

```
以上です。
.NET CoreとVSCodeでNuGet

# 概要

Visual Studio CodeでNuGetを使う方法

# 手順

1. アクティビティ バーから「拡張機能」を選択
2. 検索ボックスに`nuget`を入力
3. `NuGet Package Manager`をインストール
![nuget1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/d0b3bde3-ee06-f782-0347-57dd49c42f07.png)

`F1`でコマンドパレットを開き、`nuget`と入力、`NuGet Package Manager: Add Package`を選択
![nuget2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/a93afc08-4b99-19c9-0fe3-4ef42e67b0e0.png)

インストールしたいパッケージのキーワードを入力して`Enter`
![nuget3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/73e2b5c7-525a-971e-28fd-cb166827b97d.png)

インストールしたいパッケージを選択して`Enter`
![nuget4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/8adbf934-00a3-e6f4-572e-37aea205b763.png)

インストールしたいバージョンを選択して`Enter`
![nuget5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/df8a2fca-d7bd-1e55-40cb-bfbd19fa6bcc.png)

![nuget6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/e76299f4-6120-8655-0bb2-0444cb67e2eb.png)
個人的に必須なUIColorのextension

先にコードだけ載せておきます

```Swift
//宣言
extension UIColor {
    class func rgba(r: Int, g: Int, b: Int, alpha: CGFloat) -> UIColor{
            return UIColor(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: alpha)
        }
}
```

```Swift
//呼び出し
let white: UIColor = .rgba(r: 251, g: 250, b: 245, alpha: 1)
```

UIcolorのデフォルトのイニシャライザは0〜1の値でしか指定できないので扱いづらいですよね。
他にもオススメのextensionがあればぜひコメントで教えてください！
docker-machine のインストール方法

# docker-machine のインストール方法

docker-machine のインストール方法

## 結論

https://github.com/docker/machine/releases/ で記載されている手順でインストールする。

## 具体例

2020/10/10 時点での最新版 v0.16.2 は以下からダウンロードできる。
https://github.com/docker/machine/releases/tag/v0.16.2

上記サイトで Linux のインストール手順として以下のように記載されているのでこれをそのまま実行すればよい。

```
$ curl -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
    chmod +x /tmp/docker-machine &&
    sudo cp /tmp/docker-machine /usr/local/bin/docker-machine
```

## 内容説明

処理内容的には、 `curl`  で `docker-machine` のバイナリを `/tmp` に取得して、実行権限をつけてから `/usr/local/bin/docker-machine` にコピーしている。


ここで `/usr/bin/docker-machine` にコピーしたい場合は以下のようにすればよい。

```
$ curl -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
    chmod +x /usr/bin/docker-machine &&
    sudo cp /tmp/docker-machine /usr/bin/docker-machine
```

`uname -s` と `uname -m` の処理は、ダウンロードする docker のURLが CPU や OS によって異なるのでそれを自動判断
している。逆に、インストールマシンと異なるマシンでダウンロードする場合、必要なものをダウンロードしてコピーすればよい。

https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-Darwin-x86_64
https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-Linux-aarch64
https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-Linux-armhf
https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-Linux-x86_64
https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-Windows-i386.exe
https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-Windows-x86_64.exe
React Hooks学習メモ

#React Hooks
関数コンポーネントでもstateを扱う

##Hookとは
- クラスの機能(stateやライフサイクル)を`Functional Component`でも使える機能
- React 16.8から導入された(2020/2に正式リリース)
- 100%後方互換<br/>→古い書き方をしているコンポーネントなどに影響を及ぼさない<br/>→小さく導入できる

##なぜHookを使うのか
###シンプルさを保つため
- `Class Component`は複雑になりやすい
  - `this`という悪魔
  - stateを扱うロジックが複雑
  - **複数のライフサイクルメソッド**に副作用のある処理がまたがる

##`useState()`を使う
- ステートフックと呼ばれる
- クラスコンポーネントでいう`this.state`と`this.setState()`の代替
- 複数のstateを扱うときはstate毎に宣言する

1.useState関数をインポート

```javascript
import React, {useState} from 'react';
```

2.宣言する

```javascript
const [isPublished, togglePublished] = useState(false);
```

3.JSX内で使う

```javascript
<input /略/ onClick={() => togglePublished(!isPublished)} />
```

##Functional Componentでもライフサイクルを扱う

`useEffect()`を利用する

###`useEffect()`のメリット
- ライフサイクルメソッドを代替できる
- Functional Componentでライフサイクルを扱える
- コードをまとめることができる
  - 🙆‍♀️ 機能ベース（何をやっているのか）
  - 🙅‍♀️ 時の流れベース（ライフサイクルのメソッド毎）

##`useEffect()`の仕組み
- レンダー毎に`useEffect()`内の処理が走る
- 代替できるメソッド
  - `componentDidMount()`
  - `componentDidUpdate()`
  - `componentWillUnmount()`

##`useEffect()`の使用

###パターン① レンダー毎

```javascript
useEffect(() => {
  console.log('Render!');
  return () => {
    console.log('Unmounting!');
  }
})
```

- 基本形
- `useEffect()`内にCallback関数を書く
- Callbackはレンダー毎に呼ばれる
- returnするCallback関数はアンマウント時に呼ばれる。（クリーンアップ関数）

###パターン② マウント時のみ実行

```javascript
useEffect(() => {
  console.log('Render!');
}, [])
```

- 第二引数の配列内の値を前回レンダーと今回レンダーで比較
  - 変更があればCallback関数を実行
- 第二引数に空の配列を渡すと最初の１回（マウント時）のみ実行される

###パターン③ マウント&アンマウント時に実行

```javascript
useEffect(() => {
  console.log('Render!');
  return () => {
    console.log('Unmounting!');
  }
}, [])
```

- ①と②の複合形
- 通常のCallbackはマウント時のみ
  - 配列が空の場合はUpdating期間は処理が実行されない
- アンマウント時はretrun内のクリーンアップ関数が実行される

###パターン④ 特定のレンダー時に実行

```javascript
const [limit, release] = useState(true);

useEffect(() => {
  console.log('Render!');
}, [limit])
```

- マウント時に実行される
- limitの値が変わった時に実行される
React モジュールのimport、exportについて

##モジュール化について
- 他言語では昔からある概念
- JavaScriptではES2015(ES6)から採用
- 基本的に1ファイル=1モジュール
- 任意の場所で読み込んで使用できる

##モジュール化のメリット
1. 分割統治できる<br/>大規模プログラムでも管理しやすくなる
2. 任意の場所で読み込める<br/>必要なものを必要な分だけ
3. 再利用できる<br/>何度も同じコードを書かなくていい

##名前付きexport
1モジュールから複数の関数をexport
クラスはexportできない

```index.js
export function Foo() {
  return (
    <h1>FOO</h1>
  );
}
export const Bar = () => {
  return (
    <h1>BAR</h1>
  );
}
```

##名前なし(default)export
- 1ファイル(1モジュール) 1export
- **ES6で推奨されているexport方法**
- アロー関数は宣言後にexport
- クラスをexportできる

```Foo.js
export default function Foo() {
  return (
    <h1>FOO</h1>
  );
}
```

```Bar.js
const Bar = () => {
  return (
    <h1>BAR</h1>
  );
}
export default Bar;
```

```Hoge.js
export default class Hoge extends Fuga {
  render() {
    return (
      <h1>Hoge</h1>
    );
  }
}
```

##モジュール全体のimport
- 名前なし(default)exportしたモジュールをimportする
- モジュール全体のimport

```Blog.jsx
import React from 'react';
import Article from "./Article";
```

```Article.jsx
const Article = (props) => {
  return (
    <div>Article</div>
  );
}
export default Article;
```

##関数ごとのimport
- 名前付きexportされたモジュールをimportする
- {}内にimportしたい関数名

```Hoge.js
import { Foo, Bar } from "./FooBar";
```

```FooBar.js
export function Foo() {
  return (
    <h1>FOO</h1>
  );
}
export const Bar = () => {
  return (
    <h1>BAR</h1>
  );
}
```

##別名import
- 別名（エイリアス）をつけてimportできる
- モジュール全体なら `* as name`
- モジュール一部なら `A as B`

```Blog.jsx
import React from 'react';
import * as AnotherName from './Article';
import { Foo as MyFoo } from './FooBar';
```

```Article.js
const Article = (props) => {
  return (
    <div>Article</div>
  );
}
export default Article;
```
React コンポーネントのライフサイクル

#コンポーネントのライフサイクル
##ライフサイクルとは
- コンポーネントの「時間の流れ」
- 生成、変更、破棄までの循環
- それぞれの段階で必要な処理を記述

##３種類のライフサイクル
`Mounting`：コンポーネントが生成される期間
`Updating`：コンポーネントが変更される期間
`Unmounting`：コンポーネントが破棄される期間

##なぜライフサイクルを使うのか
- `関数外に影響を与える関数`を記述するため<br/>e.g. DOM変更、API通信、ログ出力、setState() ...etc
- 副作用 = 適切な場所に配置すべき処理

|order|Mounting|Updating|Unmounting|
|:--|:-:|:-:|:-:|
|1|constructor()|||
|2|render()|render()||
|3|componentDidMount()|||
|4||componentDidUpdate()||
|5|||componentWillUnmount()|

##主要メソッド
###Mount
`constructor()`：初期化（stateなど）
`render()`：VDOMを描画（JSXをreturn）
`componentDidMount()`：render()後に一度だけ呼ばれる。リスナーの設定やAPI通信に使われる。

###Updating
`render()`：VDOMを描画（JSXをreturn）
`componentDidUpdate()`：再render()後に呼ばれる。スクロールイベントや条件付きイベント。

###Unmounting
`componentWillUnmount()`：コンポーネントが破棄される直前に呼ばれる。リソースを解放するために使う。（リスナーの解除など）
Reactコンポーネントの基本

#コンポーネントの基本

## コンポーネントとは？
UIは2つに分類される
1. 見た目（View）
2. 機能（Controller）

コンポーネント = 見た目 + 機能

Webページはコンポーネントのツリー構造になっている

##なぜコンポーネントを使うのか
- 再利用性するため
- 分割統治するため
- 変更に強くするため

##コンポーネントの種類
1. `Class Component` : クラスによって定義されたコンポーネント
2. `Functional Component` : 関数型で定義されたコンポーネント

###Functional Component
- ES6のアロー関数で記述
- stateを持たない（stateless）
- propsを引数に受け取る
- JSXをreturnする
- **シンプル**

```Article.jsx
import React from 'react';

const Article = (props) => {
    return (
        <div>
            <h2>{props.title}</h2>
        </div>
    );
};

export default Article;
```

###Class Component
- React.Componentを継承
- ライフサイクルやstateを持つ
- propsにはthisが必要
- renderメソッド内でJSXをreturnする

```Article.jsx
import React from 'react';

class Article extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <div>
              <h2>{this.props.title}</h2>
            </div>
        );
    }
}

export default Article;
```

###最近の主流はFunctional Component
- 記述量が少ない
- コンポーネントにstateを持たせたくない

##propsでデータを受け渡す

親コンポーネント

```Blog.jsx
import React from 'react';
import Article from "./Article";

const Blog = () => {
    return (
        <React.Fragment>
            <Article title={'Hello, React'}/>
        </React.Fragment>
    );
}

export default Blog;
```

子コンポーネント

```Article.jsx
import React from 'react';

const Article = (props) => {
    return (
        <div>
            <h2>{props.title}</h2>
        </div>
    );
};

export default Article;
```

###受け渡せるデータ型
- `{}`内に記述
- 文字列、数値、真偽値、配列、オブジェクトなどなんでも渡せる
- 文字列は`{}`なくてもOK


```Blog.jsx
import React from 'react';
import Article from "./Article";

const Blog = () => {
    const authorName = 'Eric Clapton';
    return (
        <React.Fragment>
            <Article
                title={'Hello, React.'}
                order={3}
                isPublished={true}
                author={authorName}
            />
        </React.Fragment>
    );
}

export default Blog;
```

###再利用する
コンポーネントは再利用できることが最大の利点

```Blog.jsx
import React from 'react';
import Article from "./Article";

const Blog = () => {
    const authorName = 'Eric Clapton';
    return (
        <React.Fragment>
            <Article title={'出生について'}/>
            <Article title={'Cream時代'}/>
            <Article title={'ソロ活動時代'}/>
        </React.Fragment>
    );
}

export default Blog;
```
React環境構築

# 環境構築
##create-react-app

###必要なもの
- node 8.10以上
- npm 5.6以上

上記インストールのためにhomebrew、nodebrewが必要

####homebrewのインストール
https://brew.sh/index_ja

####nodebrewのインストール

```
$ brew install nodebrew
$ nodebrew -v // インストールの確認
```

####nodeのインストール

参考：https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09

```
$ nodebrew ls remote // インストール可能なnodeのバージョン確認
$ nodebrew install stable // 安定版のインストール
$ nodebrew ls // 現在インストールされているnodeのバージョン一覧
$ nodebrew use v{インストールしたバージョン} // currentへの追加
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zprofile // zshの場合
```

####npmのインストール

nodeを入れた時点でnpmも入る
バージョンが5.6以上であることを確認する

```
npm -v
```

###create-react-appによるプロジェクトの作成

```
$ npx create-react-app react-blog-app
```

###create-react-appとは
React開発環境を超簡単に構築できるツール。
**Reactを学習するのに最適な環境**
(React公式documentから引用)

- React開発環境の構築は難しい
- トランスパイラのbabelやバンドラーのwebpackの設定が必要

create-react-appなら1コマンドで環境を整えてくれる

###create-react-appの環境構成
1. `src` : コンポーネントを作るJSファイルなど
2. `public` : htmlファイルや設定ファイルなど。`manifest.json`はPWAを開発する際に使用する設定ファイル
3. `build` : 本番環境用のファイル

###基本コマンド

```
$ npm run build
```
srcとpublic内のファイルを1つにまとめて（バンドル）、buildディレクトリに出力する

```
$ npm start
```
ローカルサーバを起動してReactアプリを動かす

```
$ npm run eject
```
babelやwebpackの設定を変更したい時に使用する

##その他の環境構築ツール
- Next.js → サーバーサイドレンダリング（SSR）
- Gatsby → 静的ウェブサイトに最適（SSG）
JSXの基礎知識と文法

#JSXの基礎知識と文法

##JSXとは？
- JavaScript内でHTMLを簡単に記述するための言語
- JavaScriptの拡張言語
- Facebookが開発
- React公式ドキュメントはほぼJSXで記述されている
- Reactでは業界標準

##なぜJSXを使う？
通常のJavaScriptでHTMLを記述（DOM操作）

```javascript
const fuga = "<h1>Hello, World!</h1>"
document.getElementById('hoge').innerHTML = fuga;
```

量が増えると。。

```javascript
const fuga = "<h1>Hello, World!</h1>"
const foo = "<h2>React Commentary</h2>"
const bar = "Hi, I'm Billy Gibbons."
document.getElementById('hoge').innerHTML = fuga;
document.getElementById('foo').innerHTML = foo;
document.getElementById('bar').innerHTML = bar;
```

JSXを使うと。。

```javascript
return (
  <React.fragment>
    <div id="hoge">
      <h1>Hello, World!</h1>
    </div>
    <div id="foo">
      <h2>React Commentary</h2>
    </div>
    <p id="foo">Hi, I'm Billy Gibbons.</p>
  </React.fragment>
)
```

可読性が高い！

ただJSXは実際のところJavaScriptではない。
JSXの構文をブラウザは理解できない。

そこでトランスパイラが必要。

##トランスパイラ
「翻訳」のような役割。
JSX → JavaScript(ES6) → JavaScript(ES5)

Reactのトランスパイラは**Babel**

トランスパイラを主たる実装として開発されている言語の例
CoffeeScript、TypeScript...etc

##もしJSXがなかったら。。
React.createElementを使う

```javascript
React.createElement(
  "h1",
  null,
  "Hello, World!"
)
```

JSXを使用して記述したJSをBabelでトランスパイルするとReact.createElementを使用した形に変換される

##JSXの基本文法
1.Reactパッケージのインストールが必要

```javascript
// .jsxファイル内の先頭に宣言
import React from "react";
```

2.HTMLとほぼ同じ文法（ただ`class`は`className`に）

```javascript
const App = () => {
  return (
    <div id="hoge" className="fuga">
      <h1>Hello, World!</h1>
    </div>
  );
};
```

3.`{}`内に変数や関数を埋め込める

```javascript
const foo = "<h1>Hello, World!</h1>"
const App = () => {
  return (
    <div id="hoge" className="fuga">
      {foo}
    </div>
  );
};
```

4.変数名などは全てキャメルケースで記述する

```javascript
const fooBar = "<h1>Hello, World!</h1>"
const App = () => {
  return (
    <div id="hoge" className="fuga">
      {fooBar}
    </div>
  );
};
```

5.空要素は閉じる

```javascript
const App = () => {
  return (
    <div id="hoge" className="fuga">
      <input type="text" id="blankElement" />
      <img src="/assets/icon/icon.png" />
    </div>
  );
};
```
Reactの基礎知識

# Reactの基礎知識
## Reactとは？
- Facebookが開発
- JavaScriptのライブラリ（フレームワークではない）
- WebのUIを作る
- React ≠ SPA

## コンポーネントとは？
UIは2つに分類される
1. 見た目（View）
2. 機能（Controller）

コンポーネント = 見た目 + 機能

Webページはコンポーネントのツリー構造になっている

###なぜコンポーネントを使うのか
- 再利用性するため
- 分割統治するため
- 変更に強くするため

## Virtual DOM
###そもそもDOMとは？
→ Document Object Modelの略
→ インターフェース
→ HTMLにアクセスする窓口
→ HTML構造、見た目、コンテンツを変更したいときはDOMを通して操作を行う

###Virtual DOMとは？
Reactで管理するDOM。
通常のDOMはブラウザのレンダリングによって管理されるが
Reactではブラウザのレンダリングと別で管理を行う
→効率よくDOM操作できる

通常のDOM操作

```javascript
document.getElementById('hoge').innerText='fuga';
```

ReactのVirtual DOM操作

```javascript
render(
  <div id='hoge'>fuga</div>
);
```

##差分描画
Reactでは変更されたVirtual DOMの**差分**のみを再描画する

##JSX
JavaScript内でHTMLっぽく書ける

```javascript
ReactDOM.render(
  <div className={hoge}>
    <h1>Hello World!</h1>
  </div>
)
```
dbpediaの研究 その34

#概要

dbpediaが難解なので、手出してみる。
温泉宿・適応症LOD、やってみた。


#データモデル

![](http://mdlab.slis.tsukuba.ac.jp/lodc2019/onsen/data_model.jpg)

#エンドポイント

http://mdlab.slis.tsukuba.ac.jp/lodc2019/onsen/query

#使える語彙

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX schema: <https://schema.org/>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX prop-ja: <http://ja.dbpedia.org/property/>
PREFIX hs: <http://purl.org/net/hotspring/>
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>

#成果物

http://embed.plnkr.co/plunk/CCTvCzln18K0mNBq

以上。
jsライブラリ選定はopenbaseが超絶便利

![](https://storage.googleapis.com/zenn-user-upload/8ytbhrkpue1zx3z9c6ng8ifgfsy4)

## openbaseとは
https://openbase.io
Find and compare open-source packages with user reviews, categorization, and unparalleled insights about packages' popularity, reliability, activity, and more.

手を抜いてdeeplでw
>ユーザーレビュー、カテゴリ分け、パッケージの人気、信頼性、アクティビティなどについての他の追随を許さない洞察力で、オープンソースパッケージを見つけて比較してください。

現在、多くのプログラミング言語はパッケージマネージャがあって、何らかの方法でパッケージについての情報を取得することができると思います。

## パッケージの選び方
自分の場合はjs系が殆どなので、ライブラリを選ぶ方法は以下のような感じです

1. npmで検索  
2. descriptionを読んで良さそうなもの、ダウンロード数がある程度あるもの、  
最終更新が数ヶ月以内のものピックアップ  
3. GitHubページのReadmeと公式ドキュメントがどの程度整備されているか確認  
issueとPRを軽くチェックし、デモがあれば、それもチェック  
   ちなみにドキュメントの有無だけでは、決めないようにしていますreact-draggableのようにドキュメントはあっさりしているけれど、定期的にリリースされていて、issue boardで開発者やコントリビュータが意見を頻繁に交換しているケースもあるため

その上で、数個に絞った上で簡単に試してみて、決めています。
激しく、外すことはないのですが、時々ざっと、Readme読んでああこれなら良さそうと思って入れて、使い始めたら勝手にあると思い込んでいた機能が実はサポートされてなくて、自分で実装するくらいならちょっとあれだけど、もう一個の最終候補に残ったやつに切り替えるかという事があります。
大抵の場合、凄い特殊な使い方というわけでは、何ので自分の他にも同じような経験の人いるだろうから、レビューとかあれば助かるなぁと思っていました。

## openbaseのいいところ Review
そんな時に見つけたのが、openbase.ioです。
先にあげた選ぶ時の指標が全部入っている上に、ユーザーからのReviewも載っているという至れり尽くせりのサイトです。　
個人的には、もう少し明るい色のサイトだといいなぁとか思ったりしますが、機能面は本当に大満足です。

Reviewは投稿者のレーティング星の数と使った感想が掲載されています。
また、Review自体にLikeを付けられるので、Reviewを見た人の視点でReviewそのものをチェックしても良さそうという判断の助けになるかと。
ちなみに、Reactだと570件以上のReviewがついています

[基本情報]
![](https://storage.googleapis.com/zenn-user-upload/s1clltyy6rfmycn2g6t2krslpn2d)

[レビュー]
![](https://storage.googleapis.com/zenn-user-upload/vdamn7blticatjme0y08vjw4k2kx)


## openbaseのいいところ tutorialをすぐ確認できる
サイドバーの`tutorial`をクリックすると簡単にチュートリアルにアクセスできます。Youtubeのビデオも含まれているので、ざっくりと使い方を掴むのに非常に便利です。
![](https://storage.googleapis.com/zenn-user-upload/s44khn5923fqmqpkn4nzw1brmikh)

![](https://storage.googleapis.com/zenn-user-upload/h1ryt2fszm22kg502v1slkgd5rv3)


## openbaseのいいところ 代替パッケージの情報
サイドバーのAlternativesをクリックすると、代替パッケージの情報が表示されます。下記はReactの結果なので、まぁそんなに新しい発見みたいなものはないですが、パッケージによっては面白い発見がある可能性もあるかと思います。
この機能の良いところは自分でリサーチした時の漏れをカバーすることができる点だと思います。あとは、有名なパッケージだけ、検索かけて最初から候補をAlternativesからピックアップするという方法もありではないかと。
![](https://storage.googleapis.com/zenn-user-upload/7iwligihz98uwfzs8acz32kfe9wc)
MkDocsのテーマとそのカスタムについて

##はじめに
個人的にDjangoをやっていたのですがサーバー代が馬鹿にならないので静的サイトジェネレーターについて調べ始めました。巷ではGatsbyなどが流行っているようですが出来るだけPythonで楽をしたいのでMkDocsについて書きます。なおこの記事はテーマの自作について取り扱うのではなく、あくまで既存のテーマとそのカスタムに範囲が留まっています。

##既存のテーマを使おう
[公式のドキュメント](https://www.mkdocs.org/#installation)に記載がありますが、デフォルトでインストールされているテーマを使用する場合には```theme: テーマ名```という一文を```mkdocs.yml```に記述するだけで大丈夫です。

例として```readthedocs```というテーマを設定する場合には```theme: readthedocs```という一文を追記するだけで追記するだけでいいのです。簡単ですね！

MkDocsにはコミュニティによって作られたテーマが沢山あります。中でもかなり有名なのがマテリアルデザインを取り入れた```mkdocs-material```です。外部のテーマを取り入れるのもかなり簡単で

```terminal
pip install mkdocs-material
```

から

```mkdocs.yml
theme:
  name: material
```

とするだけです。このテーマに関しての詳細は[公式のgithubページ](https://github.com/squidfunk/mkdocs-material)をご覧ください。他にも面白テーマや実用的なテーマが[このページ](https://github.com/mkdocs/mkdocs/wiki/MkDocs-Themes)に多く載っています。ぜひ確認してみてくださいね。

##カスタムCSS/Javascript
CSSやJavascriptを追加したいだけならばとても容易にできます。Documentation directoryに追加したいCSSやJavascriptのファイルを置くだけです。[ここ](https://www.mkdocs.org/user-guide/configuration/#extra_css)により詳しく書いてありますが、例えばdocumentation directory以下にある

```
extra_css:
    - css/extra.css
    - css/second_extra.css
```

のような構造ではextra_cssをcssというサブディレクトリと共に追加することによってcssを追加しています。Javascriptの場合も同じ要領で追加できます。

##テーマの上書き
[公式ドキュメント](https://www.mkdocs.org/user-guide/styling-your-docs/)によるとテーマのカスタマイズには新しいディレクトリをdocumentation directoryと同じ階層に作る必要性がありそうです。

```
mkdocs custom_theme
```

それができたら```mkdocs.yml```にてカスタムテーマがどこにあるのか指示してあげましょう。

```mkdocs.yml
theme:
    name: mkdocs
    custom_dir: custom_theme/
```

custom_dir内で使用しているテーマに含まれているファイルと同じファイル名のファイルを作成すると自動的に現在使用しているテーマのファイルが新しく作ったファイルに置き換えられます。また、使用しているテーマに含まれない名前のファイルを作成すると自動的に既存のテーマに追加されます。

##テンプレートブロックの上書き
htmlファイルを上書きする際には```base.html```を継承する方が楽です(もちろん```base.html```自体を上書きする場合はその限りではありません)。

```
{% extends "base.html" %}

{% block htmltitle %}
<title>Custom title goes here</title>
{% endblock %}
```

このような形でテンプレートブロックを書くことで簡単に継承ができますね。これも詳細は前述の公式ドキュメントに詳しく載っています。

##最後に
近々テーマの自作についての記事も書くかもしれません。間違いがあるようでしたら編集リクエスト等を積極的に送っていただけるとありがたいです。

###参考
[MkDocs](https://www.mkdocs.org/#installation)
[Material for MkDocs](https://github.com/squidfunk/mkdocs-material)
[Styling your docs](https://www.mkdocs.org/user-guide/styling-your-docs/)
[Custom themes](https://www.mkdocs.org/user-guide/custom-themes/)
「脱Java」という言葉があるらしい。

電子入札コアシステム（新方式：脱Java）への移行について
http://www.cals.jacic.or.jp/coreconso/inadvance/data/20191122_oshirase.html

脱Javaは、日本だけですか?
英語があれば教えて下さい。
Raspberry Pi上でUbuntu server 20.04を動かしてsshできるようにするまで

# 経緯
Raspbian環境が壊れたので新しく環境を用意しようとしたところ、私の大好きなUbuntuが使えることを知りました。しかし、インストールからsshできるまでかなりの時間を割かなければならなかったので、ここにメモがてら書き留めることにしました。

# イメージ焼き
特に難しいことはないです。[Install Ubuntu Server on a Raspberry Pi 2, 3 or 4 | Ubuntu](https://ubuntu.com/download/raspberry-pi) から使いたいRaspberry Pi向けのイメージをダウンロードしてください。
その際、zipではなくxzで圧縮されていますので、Windowsユーザーの方は7zipなどを使ってください。

# 起動
初期パスワードだけ注意してください。

|ユーザー名|パスワード|
|---|---|
|ubuntu|ubuntu|

その際、パスワードの変更を求められます。もう一度初期パスワードの入力をしなければならないのでご注意ください。

# openssh-serverの設定
openssh-serverはインストールされていますが、hostkeyが設定されていません。
次のコマンドを使ってhostkeyを自動生成させてください。

```shell
$ sudo dpkg-reconfigure openssh-server
```

生成出来たらopenssh-serverを再起動してください。

```shell
$ sudo service ssh restart
```

# 参考
- Ubuntu 20.04 LTS Server を Raspberry Pi 4 にインストール - Qiita, https://qiita.com/azumabashi/items/182f365cf7405156788c, 2020.10.10 参照.
- How To: Ubuntu / Debian Linux Regenerate OpenSSH Host Keys - nixCraft, https://www.cyberciti.biz/faq/howto-regenerate-openssh-host-keys/, 2020.10.10 参照.
【Python】Seleniumでブラウザ内部の(クライアント)ウィンドウサイズを設定する方法

# やりたいこと

selenium(ブラウザ自動化フレームワーク)で、クライアントウィンドウサイズの設定をしたい。

（タブやURLなどを含めた、「実際の」windowサイズを設定の設定は簡単にできます。ただ、実際のHTMLが表示される「内部の」windowサイズを指定するのが少しだけ面倒です）

# コード

実際のウィンドウサイズと内部のウィンドウサイズの差分をとることで、外枠の大きさを得られます。
あとは設定したいサイズに外枠を足せば、設定するべき実際の画面サイズがわかります。

```python:pythonで書きます
width = 600 # 設定したい内部の横幅(ClientWidth)
height = 400 # 設定したい内部の縦幅(ClientHeight)
driver = webdriver.Chrome(options=options) # 設定は省略

# 現在のwindowサイズをdriverから抜き出す
current_window_size = driver.get_window_size()

# htmlタグからクライアントのwindowサイズを抜き出す
html = driver.find_element_by_tag_name('html')
inner_width = int(html.get_attribute("clientWidth"))
inner_height = int(html.get_attribute("clientHeight"))

# 「設定したい内部の幅+外枠の幅」をwindowサイズにセット
target_width = width + (current_window_size["width"] - inner_width)
target_height = height + (current_window_size["height"] - inner_height)
driver.set_window_rect(
    width=target_width,
    height=target_height)

print("Window size changed: [{}, {}]".format(target_width, target_height))
```

参考にした記事
https://stackoverflow.com/questions/36333708/how-to-set-browser-client-area-size-using-selenium-webdriver
TypeScriptから生成したJavaScriptを圧縮(minify)してソースマップを有効にする方法

#1. はじめに

TypeScript から JavaScriptを生成する際にソースマップを生成することができます。これにより、デバッグする際にTypeScriptのソースコードに対してブレイクポイントを設定し、変数の中身を参照できます。

このJavaScriptのファイルサイズを減らすために圧縮(minify)すると、ソースマップが使えなくなるので、ソースマップを維持したままJavaScriptを圧縮する方法を説明します。

#2. 環境設定
開発環境はVisual Studio Code （以後vscodeと省略）を使います。
完成形のイメージは以下の通りです。
![スクリーンショット 2020-10-10 9.57.12-min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514612/113745e8-a47a-b042-ebc2-0ec5df4644b8.png)


まず、空ディレクトリを作成し、npm からパッケージをインストールします。
> npmパッケージは通常は指定ディレクトリへインストールされるが、「-g」を付けるとグローバルインストールされ、異なるディレクトリでも実行できる。

```
mkdir 【空ディレクトリ】
cd 【空ディレクトリ】
npm install -g typescript
npm install gulp gulp-uglify gulp-terser gulp-typescript gulp-sourcemaps --save-dev
```

次に、TypeScriptの初期設定ファイルを作成します。

```
tsc --init
```

次にvscodeで上記でコマンド実行したディレクトリを開き、tsconfig.json ファイルを開きます。
そこで「"sourceMap": true」 のコメントアウトを解除してください。


- tsconfig.json でソースマップを有効にする設定

```json
{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",       /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs",  /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "sourceMap": true,     /* Generates corresponding '.map' file. */
  }
}
```

次にvscodeでtsconfig.jsonと同じ階層に「gulpfile.js」を作成し、以下のように記述してください。

```js
const gulp = require('gulp');
const uglify = require('gulp-uglify');
const terser = require('gulp-terser');
const sourcemaps = require('gulp-sourcemaps');
const proj = require("gulp-typescript").createProject("tsconfig.json");

// 全てのtsファイルから js と js.map を生成
gulp.task('default', build);
// srcフォルダの変更を監視してビルド
gulp.task('watch', function(){
  gulp.watch('./src/**/*.ts', build);
});

function build() {
  return proj.src()
    .pipe(sourcemaps.init())
    .pipe(proj()).js
    // ES2015以降の場合はuglifyをterserに変更
    .pipe(uglify({
      // ステップ実行するためカンマ区切りで繋げない
      compress: {
        sequences: false
      }
    }))
    .pipe(sourcemaps.write('.', {
      sourceRoot: './',
      includeContent: false
    }))
    .pipe(gulp.dest("src"));
}
```

以上で設定完了です。
vscode からコンパイルするには、メニューのTerminal > Run Task >
「gulp: default」を選択すると、distフォルダにjsとjs.mapが生成されます。
デバッグする際には「ts, js, js.map」の3つを同じディレクトリへ入れてください。

今回説明した方法とは別に、サーバーからクライアントへ転送する際にgzip圧縮する方法があります。JavaScriptのminifyと組み合わせることで転送データ量を減らすことができます。