OmniAICreator/Qiita-1.07M huggingface dataset:
Docker環境NuxtのaxiosモジュールでbaseURLの設定





## 問題  ページレンダリング後のaxiosだけ動かない...

まず、docker-composeをつかってnodeイメージでnuxt開発環境(frontend)とgoのAPIサーバー環境(app)を作りました。
これで、frontendコンテナからappでコンテナのアドレスを名前解決できるようになったはずです。

そして、SSR: trueの環境でaxiosを実装しますが、

baseURLを設定しているのにbaseURLがlocalhost:3000(デフォルト)に勝手に変わってるのに気づきました。ページレンダリング前に呼びだしている(acyn fetch()で書いた)処理は正しく動いているのに、ページレンダリング後のmethodsに書いた$store.dispatchが動かないという現象に悩まされました。

```nuxt
  axios: {
    baseURL: 'http://app:8080',
    proxy: true,
  },
  proxy: {
    '/api': '/'
  },
```

```js
methods: { 
    axiosFunc() {  // こっち動かない404エラー
        const payload = {....}
        this.$store.dispatch('.....', payload)
    }
},
async fetch({store}) { // こっち動く
    const payload = {....}
    await store.dispatch('.....', payload)
}
```



## 解決

若干、原因の予想はつきますが、やっぱりページレンダリングの前後でサーバーとの通信関係で変化しているようです。そして、下のブログをみつけました。

https://rara-world.com/nuxt-docker-404-api/

SSR(コンテナ)でaxiosを実行するfetch側はbaseURLで動いていて、methodsで定義した関数はブラウザ側で呼び出しているので、browserBaseURLを設定してエンドポイントを切り替える必要がありました。

また、ブラウザにはコンテナ名でアドレスをたどる能力がないようなので

```
net::ERR_NAME_NOT_RESOLVED
```

各コンテナを共通networkにいれて、

```js
browserBaseURL: "http://app:8080",
```

と指定してあげると無事動かせました。
numpy で画像(2D data)からバウンディングボックスを求めるメモ

## 背景

nunmpy で画像の部分領域のバウンディングボックスを求めたい.

ピクセルがあるしきい値を超えている画像領域を求めたいとか.

## 方法

`numpy.where` あたりを使います.

https://stackoverflow.com/questions/4808221/is-there-a-bounding-box-function-slice-with-non-zero-values-for-a-ndarray-in

where では条件にマッチしたインデックスが帰ってくるので, それの端を取れば bound min/max が求まります.

ただ, where だといくらか効率悪いぽいようなので, bounding box のように最終的に bmin/bmax の配列インデックスが取得できればいい場合は. `argwhere` or `nonzero` を使うのがよさそうです.

https://numpy.org/doc/stable/reference/generated/numpy.argwhere.html
特定のページでJavaScriptを動作させる方法

動作環境
Ruby 2.6.5
Rails 6.0.3.2

基本的にJavaScriptは全てのページで発生しているため、JavaScriptを使用していないページでも検証ツールのconsole内でJavaScriptのエラーが発生してしまいます。それが、ようやく解決できたので、投稿してみました。

##実装に必要なコード
```JavaScript:hoge.js
if (location.pathname.match("hoge")){
  //ここからJavaScriptを書き始める。
}
```
これでhogeというパスでのみhoge.jsは動作します。

一応解説を入れておくと、location.pathnameにより現在のパスを取得しmatchでhogeと合っているのかを確認しています。

個人的にconsole内のJavaScriptのエラーが気になっていたので、これですっきりしました。
【JS学習その②】JavaScriptにおけるスコープ

#JS学習シリーズの目的
このシリーズは、私ジャックが学んだJavaScriptのメカニズムについてアウトプットも兼ねて、 
皆さんと知識や理解を共有するためのものです。
(理解に間違いがあればご指摘いただけると幸いです) 

#用語の定義
* 実行コンテキスト・・・ コードを実行する際の文脈・状況(グローバルコンテキストと関数コンテキスト、evalコンテキストが存在する)
* コールスタック・・・実行中のコードがたどってきたコンテキストの積み重ね
* ホイスティング・・・コンテキスト内で宣言した変数や関数の定義をコード実行前にメモリーに配置すること（宣言の巻き上げ)
* スコープチェーン・・・スコープが複数階層で、連なっている状態


#スコープとは
「実行中のコードから値と式を参照できる範囲」

スコープは、実行中のコードからホイスティングされた値や式を参照できる範囲のことをいいます。
ホイスティングされている場所や書き方によって、参照される値や式は変わってきます。

#スコープの種類
* グローバルスコープ
* スクリプトスコープ
* 関数スコープ
* ブロックスコープ
* モジュールスコープ

上記の5つのスコープ存在します。
モジュールスコープに関しては、モジュールを理解している必要があるので、今回は省略します。

#グローバルスコープ
グローバルスコープには、jsファイルの直下に書かれた"var変数"と"functionで宣言された関数"など
があります。
上記の"var変数"と"関数"は、グローバルオブジェクト(windowオブジェクト)の中に格納され、
グローバルスコープは、そのファイル内のどこからでもアクセスできます。
このことから、グローバルオブジェクトそのものがグローバルスコープと言うこともできます。
基本的にグローバルスコープはwindowオブジェクトを省略して記述し、記述方法が次に説明する
スクリプトスコープとほぼ同じなので、スクリプトスコープもまとめてグローバルオブジェクトと呼ばれることもあります。

```main.js
var a = 0;
function b() {}
```

#スクリプトスコープ
スクリプトスコープには、jsファイルの直下に書かれた"const定数"や、"let変数"などがあります。

```main.js
const a = 0;
let b = 0;
```

#関数スコープ
関数スコープとは、宣言された関数の{}(波括弧)の中のスコープのことを指します。

```main.js
function sample() {
    let a = 0;
    console.log(a);
}

sample();
```
上のコードのように、sample()の中で宣言した変数"a"は、sample()関数内のconsole.log()で扱えます。

```main.js
function sample() {
    let a = 0;
}

console.log(a);
```

しかし、sample()の中で宣言した変数"a"を関数スコープの外で使おうとすると、エラーが出ます。
関数スコープの外なので参照できる範囲の外ということですね。

#ブロックスコープ
ブロックスコープは、{}(波括弧)の中のスコープのことを指します。
基本的には、関数スコープと似ているのですが、

* 前述した関数スコープはブロックスコープの影響を受けない
* var変数はブロックスコープを無視する

上記に気を付けてください

```main.js
{
    let a = 0;
    console.log(a); /*正常に動作*/

    let b = 1;


    function sample() {
        let c = 2;
        console.log(c);
    }

    sample(); /*正常に動作*/

    var d = 3;
}

console.log(b); /*エラー*/
sample(); /*正常に動作*/
console.log(d); /*正常に動作*/
```

したがって上記のようにコードを書いた場合、コメントした内容の結果になります。

#おまけ(varについて)
今回の記事でちょくちょくでてきたvar変数は、グローバル変数といって、様々なスコープを無視して
参照できるので、現在のJavaScriptでは非推奨となっています。
できるだけ、constやletで変数は定義するようにしましょう。
composer installのエラー

ターミナルで"composer install"と打ったところ、次のようなエラーメッセージが表示された。

```
Problem 1
    - Installation request for league/flysystem 1.0.66 -> satisfiable by league/flysystem[1.0.66].
    - league/flysystem 1.0.66 requires ext-fileinfo * -> the requested PHP extension fileinfo is missing from your system.
  Problem 2
    - league/flysystem 1.0.66 requires ext-fileinfo * -> the requested PHP extension fileinfo is missing from your system.
    - laravel/framework v5.8.37 requires league/flysystem ^1.0.8 -> satisfiable by league/flysystem[1.0.66].
    - Installation request for laravel/framework v5.8.37 -> satisfiable by laravel/framework[v5.8.37].

```

調べたところ、この”extension fileinfo"というところがキーになるらしい。

```
extension=php_fileinfo.dll
```
をphp.iniで有効化するということだったのだが、私の場合は探してもなかったのでphp.iniに書き加えた。
すると無事インストールできた。

#追記
別環境でcomposer installをしたところ、別のエラーが出た。

```
Problem 1
    - phpoffice/phpspreadsheet is locked to version 1.6.0 and an update of this package was not requested.
    - phpoffice/phpspreadsheet 1.6.0 requires ext-gd * -> it is missing from your system. Install or enable PHP's gd extension.
```
こちらはphp.iniに以下を書き加えることで解決できた。

```
extension=php_gd2.dll
```
ターミナルに戻ってcomposer install。
Metricbeat導入手順の備忘録

# Metricbeat導入手順の備忘録

[公式ドキュメント](https://www.elastic.co/guide/en/beats/metricbeat/current/index.html)

## アーカイブをダウンロードする

```bash
$ curl -L -O https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-7.9.1-linux-x86_64.tar.gz
```

## アーカイブを解凍する

```bash
$ tar xzvf metricbeat-7.9.1-linux-x86_64.tar.gz
```

## 設定ファイルを編集する

```bash
$ diff metricbeat.yml metricbeat.yml.org 
67c67
<   host: "localhost:5601"
---
>   #host: "localhost:5601"
```

## 監視サービス選択する

```bash
$ ./metricbeat modules list
Enabled:
system

Disabled:
activemq
aerospike
apache
appsearch
aws
azure
beat
beat-xpack
ceph
ceph-mgr
cloudfoundry
cockroachdb
consul
coredns
couchbase
couchdb
docker
dropwizard
elasticsearch
elasticsearch-xpack
envoyproxy
etcd
golang
googlecloud
graphite
haproxy
http
ibmmq
iis
istio
jolokia
kafka
kibana
kibana-xpack
kubernetes
kvm
linux
logstash
logstash-xpack
memcached
mongodb
mssql
munin
mysql
nats
nginx
openmetrics
oracle
php_fpm
postgresql
prometheus
rabbitmq
redis
redisenterprise
sql
stan
statsd
tomcat
traefik
uwsgi
vsphere
windows
zookeeper
$ ./metricbeat modules enable nginx logstash kibana elasticsearch docker 
Enabled nginx
Enabled logstash
Enabled kibana
Enabled elasticsearch
Enabled docker
$ ./metricbeat modules list
Enabled:
docker
elasticsearch
kibana
logstash
nginx
system

Disabled:
activemq
aerospike
apache
appsearch
aws
azure
beat
beat-xpack
ceph
ceph-mgr
cloudfoundry
cockroachdb
consul
coredns
couchbase
couchdb
dropwizard
elasticsearch-xpack
envoyproxy
etcd
golang
googlecloud
graphite
haproxy
http
ibmmq
iis
istio
jolokia
kafka
kibana-xpack
kubernetes
kvm
linux
logstash-xpack
memcached
mongodb
mssql
munin
mysql
nats
openmetrics
oracle
php_fpm
postgresql
prometheus
rabbitmq
redis
redisenterprise
sql
stan
statsd
tomcat
traefik
uwsgi
vsphere
windows
zookeeper
```

## セットアップする

```bash
$ ./metricbeat setup -e
```

## 起動する

```bash
$ vi start.sh
$ cat start.sh 
#!/usr/bin/bash
./metricbeat -e > /dev/null 2>&1 &

$ chmod 755 start.sh 
$ ./start.sh 
```

## 動作確認する

![mHqk2pY.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266508/6a11e76b-65f7-4dff-e1ec-29eb35e6a046.png)
1年後の自分よ、この記事を見て「アウトプット」を考え直してほしい。

#1年後の自分へ
「あ～あ去年の今頃はあんなにプロトタイプしてたのになぁ、最近してないなあ」と思っているかもしれない！
__全くその通りだ！__
折角汗水垂らしてプロトタイプをえんやこら頑張っているのになんだその様は！！
Qiita投稿やらnote投稿やら毎週のように頑張っていたのに、「うわあ懐かしいねぇそんなこともあったな」で終わっているのであれば許さんぞ！

今が多分過去で一番アウトプットしているのかもしれない。
受験勉強の時が過去一勉強していたが、それとは別種の辛さだ。
1年後、この記事を読んで「__あの時のアウトプットは、今どう生きているんだろうな__」と考えてみてほしい。

#アウトプットしないこと
まず気を付けないといけないのは、__そのぐうたらしていること自体を非難しているわけではないということ__だ。
きっと色んな仕事に追っかけられてアウトプットする余裕が無いことだろう。
昔趣味でやってた書評noteがあまりに不定期すぎる投稿だったことを思い出せば容易に想像できることだ。

なので、__アウトプットをしないこと__は、それだけの理由があるのだから仕方ないと思うし、「__なんでもアウトプット、とにかくアウトプット__」みたいなのは宗教じみて君も好きではないはずだ。
そもそもなぜアウトプットするのがいいことなのか、という問いに対して「__セルフブランディングができるから__」という答えをよく見かけるよね。
でも、「__セルフブランディングすることが君にとって本当に幸せになるのか？__」「__本当にセルフブランディングになるのか/なっているのか？__」ということや、あまりにセルフブランディングにこだわりすぎて「__うわあこの記事はだめだあ__」とか「__この記事は調子いいね、俺天才__」とかで一喜一憂して体を壊す__承認欲求お化け__になること(ここは個人によって是非が違うと思う）について議論があまりされないように思う。

かつて君がInstagramで承認欲求お化けになりかかったときの辛さを思い出せば、きっとLGTM目当て__「だけ」__で記事を書く姿勢が君のキャラにあっていない(もちろん人によって趣向が違うので、この考え方は絶対他人に押し付けてはいけない）ことは分かるはずだ。
その部分、つまり「__なんでアウトプットするのか__」そして君の大好きな__幸福論__については1年後また考えてみてほしい。

#アウトプットの2つの役割
今の僕を考えを備忘録として載せておこう。
アウトプットには2つの役割があると思うんだ。
1つが「__目的としてのアウトプット__」、1つは「__手段としてのアウトプット__」だ。

目的としてのアウトプットとは、__アウトプットそのものが楽しい！だからやりたいんだ！__ということだ。
Qiita記事は書いていて楽しい。
色々な人が見てくれるし、自分が表現できる場として本当に良いプラットフォームだと思う。

君はいろいろなことを考えたがりなので、頭の中で考えていることを時々吐き出すためにnoteを書いたことがあったと思う。
そういう「__アウトプットしたい__」という気持ちdrivenなアウトプットは非常に気持ちがいいし、「__最近アウトプットが楽しい！__」という気持ちは最高に大事にしてほしい。

ここで注意してほしいのは、アウトプットが楽しくないときに「__最近アウトプットが楽しい！と思いこまないと・・・__」と無理くり考えないでほしい。
楽しくないものは楽しくないし、どんなに好きなものでも余裕が全然ない時は楽しく感じなくなることなんてざらにあるだろう。

__笑いや思いやりにはどこか偽物を感じるけれど、怒りは素の感情だ__的な言葉を聞いたことがあると思うけれど、もしイライラするぐらい楽しくないならば__自己分析する絶好のチャンス__ととらえて、自分の素の部分を掘り起こしてみるのもいいかもしれない。

一方で__手段としてのアウトプットとは、達成したい目的が別にあるときにアウトプットを手段として使う__、ということだ。
君も研究室時代、中間発表というアウトプットの場が無かったらデータ整理なんて全然できてなかっただろう？
それと同じで、アウトプットすることで情報を整理整頓ができて、足らないところは足すし伝えにくいところは勉強するし、という__人の目を使って勉強のインセンティブにすること__ができるだろう。

また、__自分のための備忘録という意味でも非常に優秀だ__。
1年後の自分に向けて書くメッセージとして体裁を整える必要があるし、1年後の自分としても便利な資料になるだろう。
技術力を今後身に着けていきたい、キレイなコードを書いていきたいという意志があるのであれば、是非今後も書いていってほしい。

今は毎週強制アウトプットをしていて正直辛い。
__けれど得られたものもものすごく大きいことを感じている。__
何より物事の価値観が色々ごろごろ変わったのを身に染みて感じている。

この2つのアウトプットを是非是非見直して、色々考えてほしい。

#おわりに
以上が現段階で僕の頭にあるアウトプット論的なのをサクッと書いてみた。
君は地道に頑張ることができる人だけど、__すぐに調子に乗る悪い癖がある__。
今僕はIT業界に入ってまだ2年目だけれど、__上には上がいる__しいちいち一喜一憂していたらとても身が持たない。


この記事を読んで、少しでも何かの考えの刺激になったとしたら嬉しい。
NTP(chrony)を設定した備忘録

# NTP(chrony)を設定した備忘録

サーバのデフォルト設定で運用していたところ、気づいたら時刻同期がずれていたため、NTPを設定した手順を以下に示す。

## 環境

```bash
$ cat /etc/redhat-release 
CentOS Linux release 8.1.1911 (Core) 
```

## 設定手順

```bash
$ cp -pi /etc/chrony.conf{,.org}
$ vi /etc/chrony.conf
$ diff chrony.conf chrony.conf.org 
3,5c3
< #pool 2.centos.pool.ntp.org iburst
< pool ntp.nict.jp iburst
< pool ntp.jst.mfeed.ad.jp iburst
---
> pool 2.centos.pool.ntp.org iburst
$ systemctl restart chronyd.service
$ systemctl enable chronyd.service 
Created symlink /etc/systemd/system/multi-user.target.wants/chronyd.service → /usr/lib/systemd/system/chronyd.service. 
```

## メモ

|ドメイン名|場所|公式ページ|
|---|---|---|
|ntp.nict.jp|国立研究開発法人 情報通信研究機構|https://jjy.nict.go.jp/tsp/PubNtp/index.html|
|ntp.jst.mfeed.ad.jp|インターネットマルチフィード株式会社|https://www.mfeed.ad.jp/ntp/detail.html|
|2.centos.pool.ntp.org|不明|不明|

### 「2.centos.pool.ntp.org」は何者？？

調べたが、わからなかった...

whois情報は返却されなかった。

```bash
$ whois 2.centos.pool.ntp.org
NOT FOUND
>>> Last update of WHOIS database: 2020-09-14T04:47:48Z <<<

Access to Public Interest Registry WHOIS information is provided to assist persons in determining the contents of a domain name registration record in the Public Interest Registry registry database. The data in this record is provided by Public Interest Registry for informational purposes only, and Public Interest Registry does not guarantee its accuracy. This service is intended only for query-based access. You agree that you will use this data only for lawful purposes and that, under no circumstances will you use this data to (a) allow, enable, or otherwise support the transmission by e-mail, telephone, or facsimile of mass unsolicited, commercial advertising or solicitations to entities other than the data recipient's own existing customers; or (b) enable high volume, automated, electronic processes that send queries or data to the systems of Registry Operator, a Registrar, or Afilias except as reasonably necessary to register domain names or modify existing registrations. All rights reserved. Public Interest Registry reserves the right to modify these terms at any time. By submitting this query, you agree to abide by this policy.

The Registrar of Record identified in this output may have an RDDS service that can be queried for additional information on how to contact the Registrant, Admin, or Tech contact of the queried domain name.
```

nslookupも権威サーバではなく、キャッシュDNSサーバが回答してしまっているため、場所を特定できず...

```bash
$ nslookup 2.centos.pool.ntp.org
Server:         118.27.60.132
Address:        118.27.60.132#53

Non-authoritative answer:
Name:   2.centos.pool.ntp.org
Address: 79.143.250.119
Name:   2.centos.pool.ntp.org
Address: 193.25.222.240
Name:   2.centos.pool.ntp.org
Address: 64.225.34.103
Name:   2.centos.pool.ntp.org
Address: 66.85.78.80
Name:   2.centos.pool.ntp.org
Address: 2606:4700:f1::123
Name:   2.centos.pool.ntp.org
Address: 2400:8500:1801:418:a118:27:37:521
Name:   2.centos.pool.ntp.org
Address: 2001:470:fc6f::123
Name:   2.centos.pool.ntp.org
Address: 2606:4700:f1::1
```
環境変数「JAVA_HOME」パス設定手順の備忘録

# 環境変数「JAVA_HOME」のパス設定手順の備忘録

「JAVA_HOME」の設定手順を良く忘れがちなので、備忘録として示す。

## 環境

```bash
$ cat /etc/redhat-release 
CentOS Linux release 8.1.1911 (Core)
```

## 設定手順

JDKのパスを確認する。インストールされていなければ、JDKを適宜インストールしてください。

```bash
$ dirname $(readlink $(readlink $(which java)))
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el8_1.x86_64/jre/bin
```

JAVA_HOMEのパスを設定する。

```bash
$ cp -pi /etc/profile{,.org}
$ vi /etc/profile
$ diff /etc/profile{,.org}
86,90d85
< 
< export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el8_1.x86_64
< export PATH=$PATH:$JAVA_HOME/bin
< export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
<
$ source /etc/profile
$ echo $JAVA_HOME
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el8_1.x86_64
```

以上
【文字列の頭文字を削除】Ruby

#Rubyで文字列の頭文字を削除する方法

```ruby:sample.rb
str = "あいうえお"
str[1..-1] # => "いうえお" 
```

シンプルでした！

ーーーーーーーーーーーーーーーーーーーーーーーー
引用元
https://myridia.com/dev_posts/view/93
ーーーーーーーーーーーーーーーーーーーーーーーー
セグメンテーション用のラベル（マスク）をlabelmeで作成する方法(semantic segmentation mask)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122840/13f8add1-270b-c97a-b3a3-6a2755af1def.png)

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122840/0f1f8e68-5b83-0d4b-0bf0-9b8450503ceb.png)

# 前提知識
以下の知識があることを前提に記事を書いています

* semantic segmentation（#セマンティックセグメンテーション）
* mask（#label）

# labelmeはラベル作成用のアプリ
こんな感じのアプリです

* labelmeはpython製のラベル作成用アプリです。画像に対して複数のラベルを付けることができます。
* 他クラスでも問題ありません。ので、もちろん2クラスのsemantic segmentationでもできます。
* 画像にポイントで線を引き、結果がJSONファイルで出力されます
* JSONファイルが同名で画像と同フォルダに保存されているばあい（デフォルトで同じ名前で保存されます）、画像を読み込んだ時に勝手にJSONもロードされ、アノテーションされた状態で開いてくれる。
* 作成したポイントは再編集可能。

# labelmeの使い方詳細
## labelmeをダウンロード
難しくないので省略
## labelmeでラベル付け
labelmeを開くと、以下のようなウインドウが開きます。(画像はgoogle検索画面のスクリーンショットです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122840/32bf0b14-7820-5b05-06b5-a69c0f633cc0.png)

拡大しながら、ポイントで線を引いていきます。
拡大と移動は非常に簡単にできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122840/95706062-d8a3-a385-2188-e54615d11794.png)

この適当な感じで1minくらいかなー。
かなり使いやすい。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122840/4c470dc6-be13-ea53-8847-26f7876f532f.png)

左側のSAVEからJSONを保存します。
こんな感じのデータができます！

```json
{
  "version": "4.5.6",
  "flags": {},
  "shapes": [
    {
      "label": "dog",
      "points": [
        [
          104.36893203883496,
          66.99029126213593
        ],
        [
          93.44660194174757,
          71.35922330097087
        ],
        ここは省略
        [
          112.13592233009709,
          74.27184466019418
        ],
        [
          107.28155339805825,
          73.30097087378641
        ]
      ],
      "group_id": null,
      "shape_type": "polygon",
      "flags": {}
    }
  ],
  "imagePath": "スクリーンショット 2020-09-14 141400.png",
  "imageData": "省略",
  "imageHeight": 405,
  "imageWidth": 535
}

```

注意！このJSONポイントは、ポリゴンのポイントなので、そのままマスクには使えません。。なので、このポイントをマスクに変換する必要があります。

## labelmeのファイルをJSONからMASKに変換
当初自分で実装しようかと思ってたのですが、それ用の関数が用意されていました。
labelmeにはutilsフォルダにshape.pyというモジュールが用意されており、shape_to_mask関数を使用することでJSONからMASKに変換することができます。

ただ、微妙に実装しないといけないので、サンプルのコードを載せておきます。

```python
import json
with open(path, "r",encoding="utf-8") as f:
    dj = json.load(f)
# dj['shapes'][0]は今回一つのラベルのため。
mask = shape_to_mask((dj['imageHeight'],dj['imageWidth']), dj['shapes'][0]['points'], shape_type=None,line_width=1, point_size=1)
```

```python
mask_img = mask.astype(np.int)#booleanを0,1に変換

#anacondaを使っています
import matplotlib.pyplot as plt
%matplotlib inline

plt.imshow(mask_img)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122840/43d8f774-5c94-16a5-62e2-a733ae9f727f.png)

うまくラベリングできました。
このくらいのレベルであれば、画像開いてから保存までで2-3minくらいでできるのではないでしょうか。

## 最後に
labelme以外におすすめのラベリングツールあったら教えてください。
結構独自に実装したりしてる人もいるのかな。
コンポーネントを分ける基準

特に大事なのは、
- atom
- 分子
- 組織

をどういう基準で分けるか、だと思う。

atomは、それ以上分解できない最小の単位　ex 水素とか
organismは、ページの中にある、一つのまとまりを持った機能　ex 肝臓とか

とすると分子がどう判断するか難しい。
解釈としては、

- atomとorganismの間の全て

が一番正解なのだろうけど、これだと正しいだけでわかりづらい。

そこで思いついたのが、「タンパク質」のイメージ
タンパク質は
1. 化学の世界では、炭素を中心にした元素が合体した、高分子化合物
2. 生物の世界では、生き物の体のエネルギー源の最小単位

という二つの解釈がある。

これをコンポーネントに当てはめると、
1. 見た目としては、いくつかのデータを持っていたり、ある程度複雑
2. だけど、機能としては、単一の機能しか持っていない　ex どこにリンクでとぶ、とか

というイメージで考えるとわかりやすい気がした。
まーそもそも、分子から組織への幅が広すぎるのが問題なのだけど。
無料のアプリアイコン作成ツール

## はじめに
個人開発をする上で、アイコン作成は骨の折れる作業です。
私がいつも行っている作業をまとめておこうと思います。

## 1. 元になる画像を作る
ツールは何でも良いと思いますが、私は使い方を知っているKetnoteで作成しています。

### 1-1. スライドの大きさを1024 × 1024にする
![スクリーンショット 2022-07-24 11.55.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253564/720f7bd3-d999-21a8-f3b3-029f17d6d144.png)

![スクリーンショット 2022-07-24 11.55.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253564/3f061aed-82dc-e044-184a-b08c8a0b725a.png)

![スクリーンショット 2022-07-24 11.56.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253564/2d39c60c-f5a3-d61c-f639-88e6a848b96e.png)

## 2. 画像として書き出す
ファイル > 書き出す > イメージ
![スクリーンショット 2022-07-24 12.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253564/95e5ddcf-841d-c593-7d8e-2144655ba988.png)

PNG化する
![スクリーンショット 2022-07-24 12.03.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253564/f1089ce1-7227-61fa-ac5f-d90ea3d34226.png)

## 2. 作った画像からアイコンを作成するツール
https://appicon.co/#app-icon

画像をアップロードし、Generateをクリックするとダウンロードされます。
![スクリーンショット 2022-07-24 12.05.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253564/0228079a-79eb-0808-44b5-bee36c75d7a5.png)

ダウンロードされたAppIcon.appiconsetをXcodeのAssets内にドラッグすると自動で各大きさにセットされます。
![スクリーンショット 2022-07-24 12.09.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253564/a90e86f2-e494-ab1f-ef52-88d303ffad7d.png)

## 3. 終わりに
以上です。
最後まで読んでいただき、ありがとうございました。
AtCoderBeginnerContest178復習＆まとめ（後半）

# AtCoder ABC178
2020-09-13(日)に行われたAtCoderBeginnerContest178の問題をA問題から順に考察も踏まえてまとめたものとなります．
後半ではDEの問題を扱います．[前半はこちら](https://qiita.com/takaito0423/items/bd6b558ac8bbebd393d7)
問題は引用して記載していますが，詳しくはコンテストページの方で確認してください．
[コンテストページはこちら](https://atcoder.jp/contests/abc178)
[公式解説PDF](https://atcoder.jp/contests/abc178/editorial)

## D問題　Redistribution
> 問題文
> 整数$S$が与えられます。 すべての項が$3$以上の整数で、その総和が$S$であるような数列がいくつあるか求めてください。ただし、答えは非常に大きくなる可能性があるので、$10^9+7$で割った余りを出力してください。

かなり苦戦しました．
$a_n$を$S=n$のときの答えとすると以下の漸化式が成り立つので，漸化式を順に計算していくことで答えを求めることができます．
$a_n = a_{n-3} + a_{n-1}$

```python:abc178d.py
s = int(input())
mod = 10**9 + 7
a_list = [0] * (2000 + 1)
a_list[0] = 1
a_list[1] = 0
a_list[2] = 0
a_list[3] = 1
for i in range(4, s + 1):
    a_list[i] = a_list[i - 1] + a_list[i - 3]
    a_list[i] %= mod
print(a_list[s])
```

## E問題　Dist Max
> 問題文
> 二次元平面上に$N$個の点があり、$i$番目の点の座標は$(x_i,y_i)$です。 同じ座標に複数の点があることもあります。 異なる二点間のマンハッタン距離として考えられる最大の値はいくつでしょうか。
> ただし、二点$(x_i,y_i)$と$(x_j,y_j)$のマンハッタン距離は$|x_i−x_j|+|y_i−y_j|$のことをいいます。

問題見た当初は，点をいくつか結んで，その内側の点は考えなくて済むなーとか思いつつ，最初に選ぶ点をなるべくはじのものにしたいなと思っていたら，解き方に気づきました．やっぱり図を書くって大事ですね．

$x_i+y_i=k_i$から，$(1,1)$に一番近い点($k_i$が最小となる点)と$(10^9,10^9)$に一番近い点($k_i$が最大となる点)を求める．
$-x_i+y_i=n_i$から，$(10^9,1)$に一番近い点($n_i$が最小となる点)と$(1,10^9)$に一番近い点($n_i$が最大となる点)を求める．

$k_{max}$と$k_{min}$のマンハッタン距離か$n_{max}$と$n_{min}$のマンハッタン距離が，考えられるマンハッタン距離の最大となる．


```python:abc178e.py
n = int(input())
point_dict1 = {}
point_dict2 = {}
for i in range(n):
    x, y = map(int, input().split())
    point_dict1[x + y] = (x, y)
    point_dict2[y - x] = (x, y)
min_point1 = min(point_dict1)
max_point1 = max(point_dict1)
min_point2 = min(point_dict2)
max_point2 = max(point_dict2)
print(max(max_point1 - min_point1, max_point2 - min_point2))
```

個人的には普段の問題セットと比べ，E問題までソースコード自体はシンプルで，数学？を使う問題が多かったので，好きな問題セットでした．

後半も最後まで読んでいただきありがとうございました．
Unable to resolve module @react-native-community/toolbar-android

## 概要

久しぶりに`npm i`して、`react-native run-ios`するとerr

![スクリーンショット 2020-09-14 13.30.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317701/70442f20-60fb-745c-d69b-cb18c9c2f002.png)

## 環境

ReactNative 0.61.1 ※多分関係ないと思われる
react-native-vector-icons 6.6.0

## 解決方法

解決策がすでにありました。
https://github.com/oblador/react-native-vector-icons/issues/1211#issuecomment-671138309

``` terminal
yarn add @react-native-community/toolbar-android
```

または

``` terminal
npm install --save @react-native-community/toolbar-android
```

2020年9月14日段階の最新バージョン(7.1.0)でも発生しています。
対応されるまで上記の対応で問題なさそう。
正規表現メモ

正規表現の勉強から逃げてきた情弱だから常識しか書かない

#### 行末の空白

```
\s\+$
```

vimで行末空白を消したいときは `:%s/\s\+$//gc` と書けばよいのね

#### 行頭から特定の文字（:）まで

```
^.*:
```

#### 特定の文字（:）から行末まで

```
:.*$
```

#### AND（論理積）

```
/^(?=.*apple)(?=.*orange)/
```

これはapple → orangeの順番に出てこないと検索できないという理解でいいのかしら



#### abcで始まらない任意の文字列を抽出

```
/^(?!abc).*/
```

#### abcより前を抜き出す

```
/(.*)(?=abc)/
```

#### 正規表現の*とワイルドカードの違い
 Unixのシェル：

```
? → 任意の1文字
* → 長さ0文字以上の任意の文字列
```

正規表現：

```
. → 任意の1文字
* → 直前の表現が0回以上あること
```


| 表現 | 意味 |
|---|---|
| \s | tabなどを含む空白文字全般 |
| \. | 任意の1文字 |
| \* | 直前のパターンの0回以上の繰り返し |
| \+ | 直前のパターンの1回以上の繰り返し |
| \? | 直前のパターンの0回または1回の繰り返し |
| \$ | 行末 |
| \^ | 行頭 |
| \| | OR |
| /^(?=.\*apple)(?=.\*orange)/ | apple AND orange |
| foo(?=bar) | 肯定的先読み <br> 直後にbarがあるfoo（barは含まない）に一致する |
foo(?!=bar) | 否定的先読み <br>直後にbarがないfoo（barは含まない）に一致する |
(?<=bar)foo | 肯定的後読み <br> 直前にbarがあるfoo（barは含まない）に一致する |
(?<!=bar)foo | 否定的後読み <br>直前にbarがないfoo（barは含まない）に一致する |


### 参考
- [正規表現とワイルドカード、そして記号の意味](https://qiita.com/whisky-shunsuke/items/d719c92c566c133f51b1)
- [正規表現の先読み・後読みを極める！](https://abicky.net/2010/05/30/135112/)
- [正規表現で論理積（AND）を実現する](https://qiita.com/liburari/items/dbcd0b8af3781d221424)
GetでGoogleスプレッドシートのセルの値をとってくる方法

GCPのAPIを使ってGoogleスプレッドシートから値を取得します

#GCPからAPIキーを取得する

プロジェクトの選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/d57e3c58-027b-70c8-dc2e-666f4210cd59.png)

新しいプロジェクト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/5addb6d1-822f-5e02-7c81-cddc28958cd9.png)

適当に名前を決めて作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/b59bad46-9f5f-237e-0ec5-a5610246768d.png)

プロジェクト選択から作成したプロジェクトを選択する
APIサービス＞認証情報
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/9fe16f7a-658a-9064-bd71-54a1d8c35f2b.png)

認証情報を作成＞APIキー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/483b97f7-10cc-082e-ebc6-36b7b785616b.png)

これでAPIキーが取得できました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/8a8f4eca-a821-e5a3-af50-6a2e444e4f46.png)

#スプレッドシートを有効にする
このままではAPIキーをGoogleスプレッドシートで使うことができないので、これを有効化します
ライブラリをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/ce466981-46db-d47a-45ae-7611caebf0f6.png)

少しスクロールしたところにあるGoogle Sheets APIをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/3567917f-e36e-cd9c-1ef3-a1c1b4d2d9ac.png)

有効にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/66c91030-aad7-f7ec-e34c-dc9a368e5445.png)


以上で終了です
これでGoogleスプレッドシートでAPIが使えるようになりました

#実際にGetで値を取得する

###スプレッドシートの共有設定を「リンクを知っている人全員」に設定しないと403エラーになります

このURLで取得できます
ブラウザでも実行できます

````
https://sheets.googleapis.com/v4/spreadsheets/{GoogelスプレッドシートID}/values/{シートの名前}!{開始セル}:{終了セル}?key={APIキー}
````
GoogelスプレッドシートIDはURLのこの部分です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/fc0dc6b5-4e91-64f1-b57f-464f8a353589.png)

セルの範囲を「A1:B3」に設定するとこのようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/e1e65857-554e-3916-3612-00942ef264a4.png)
実際のシート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344267/1060373f-dd06-b30f-6c7c-9b1a45406e3e.png)


より詳しい情報はここで
[https://qiita.com/howdy39/items/5473160c93030c386c2d](https://qiita.com/howdy39/items/5473160c93030c386c2d)
Python + Unity 強化学習環境構築

PythonでML-Agentを動かすための環境構築

##使用環境
Python 3.7.6
mlagents 0.17.0
ML-Agents Release3
Unity 2019.2.21f1
Pyenv
Poetry

##前提条件
Unity Hubのダウンロード

###1.Unity ML-Agentsのインストール
(1)以下のサイトからUnity ML-Agents Release3をインストールする
https://github.com/Unity-Technologies/ml-agents

![スクリーンショット 2020-09-14 130014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573931/28d0fc9a-6f6e-badb-5b51-7569a67156ba.png)
![スクリーンショット 2020-09-14 130030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573931/6bf67fd2-3407-3aab-e04b-e9ff54e5280b.png)

(2)コピーしたURLをGit cloneコマンドの後ろに付けて実行　ファイル一式をダウンロードできる
（※git clone する前に作業をするディレクトリを作成！）

```terminal:terminal
mkdir [任意のディレクトリ名]
cd [ディレクトリ名]
git clone [コピーしたURL]
```

(3)ml-agentsディレクトリが作成され、中に以下のようなファイルが入っていることを確認！
![スクリーンショット 2020-09-14 131106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573931/3ebb6bca-5eb5-2f60-9865-02cb6b2dd6db.png)

###2.Python3.7.6の仮想環境の構築！
(1)pyenvをインストール！

```terminal:terminal
brew install pyenv
```
(2)Python3.7.6のインストール

```terminal:terminal
pyenv install 3.7.6
```
(3)このディレクトリはPython3.7.6で実行することを設定

```terminal:terminal
pyenv local 3.7.6
```
(4)Pythonの管理パッケージPoetryをダウンロード＆インストール

```terminal:terminal
curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python
```
(5)Poetryの仮想環境準備
設定を確認
![スクリーンショット 2020-09-14 134557.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573931/d2d87f6d-30bb-0b7e-bcf2-6f3c7e426654.png)
プロジェクト内に仮想環境が作られるように設定し、再び設定状態を確認

```terminal:terminal
poetry config virtualenvs.in-project true
```
(6)Python3.7.6で仮想環境構築
![スクリーンショット 2020-09-14 132533.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573931/5ecba498-46bb-20f3-137a-ebb997d3ef86.png)

(7)mlagent==0.17.0のインストール！

```terminal:terminal
poetry add mlagents==0.17.0
```

(7)mlagents-learnコマンドが実行できることを確認
下のコマンド実行後下の画像のようなものが出てくることを確認

```terminal:terminal
mlagents-learn
```
![スクリーンショット 2020-09-14 132912.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573931/b9454aae-a2c5-f225-61f3-ed8019e97dc6.png)
【自分用メモ】try-catch  まとめ


2020/09/15初投稿
2020/09/18更新

◎今回練習したいメソッドまとめ
tryメソッド---実行したい処理内容
catchメソッド---tryメソッドを実行中にエラーが起きた場合の処理
finallyメソッド---catchメソッドを実行してもしなくても、最後に必ず実行するブロック

◎この記事の内容
"data.txt"という新しいテキストファイルをエクスプローラー内に生成する。
FileWriterを使い　そのテキストファイル内に文字を書き込む。
try-catch-finallyメソッドを使用し、細かなエラー処理と　
closeメソッドを設定する。
（closeメソッドとは・・ファイルを開いた際には必ず書く、”ファイルを閉じるための処理”）

```java
package trycatch;


import java.io.FileWriter;
import java.io.IOException;

public class trycatch1 {

	public void test() {

		FileWriter fw=null;
		/*入出力処理で、自分で何らかのファイルを開くコードを書いたなら、
		必ずファイルを閉じるコードも書く。=closeメソッド*/

		/*closeメゾットをtry-catchメソッドの外に書くために、
		 * ここでFileWriterを登場させる。
		 * なぜtrycatchメソッドの外にcloseメソッドを書くのか？
		 * =tryメソッドでエラーを発見すると、ただちにcatchメソッドに移動してしまうので、
		 * closeメソッドが実行されない可能性があるから*/

		try {
			fw=new FileWriter("data.txt");
			/*ここで"data.txt"という新しいテキストファイルを
			 このプロジェクト下につくってくれる。
			 そのファイルをプロジェクトをWindowエクスプローラーで開くと直接見れる。
			 あらかじめ作ったファイルに書き込むなら(例)("c:\\nameOFfolder\\nameOFfile.txt")*/
			fw.write("hello");
			fw.write("へろー");
		    /*実行してもdata.txtに文字が入っていない時は
		     * close()メソッドがうまく動いていない可能性あり。
		     * write()メソッドでテキスト挿入の指示をだしても、
		     * それをJVMが実際に書いてくれるのはclose()するまえだったりする。タイムラグ*/

			fw.flush();
			//強制的な書き込み指示

		}catch(IOException ioe){
			System.out.println("入出のエラーが発生しました");
			System.out.println(ioe);
		}catch(Exception e){
			System.out.println("なんらかのエラーが発生しました");
			/*↑なぜここでIOEceptionを先に書くのか？＝
			 *javaでは、複数のエラー処理を設定してある場合は、
			うえから順に確認していく。ひとつのエラー処理をすると
			try-catchメソッドの外に出る。*/
			System.out.println(e);

		}finally{
			if(fw!=null) {
			//なぜ↑がnullになる可能性があるのか？＝＞クラスの一番上でnullを入れてるから。
			try {
			fw.close();
			//なぜif文書くの？＝＞ここのfwがnullになったらNullPointerExceptionが発生するので、if文を書く
			}catch(IOException ioe) {
				System.out.println("ファイルを閉じる際に何らかのエラーが発生しました");
			}
			/*◎なぜfinallyブロック内にtry-catchブロックを書くのか？
			＝＝＞[closeメソッドを書く上で予期されるエラー]の対策がないと、IOExceptionが発生するから。
			*/
			}
		}

	}
	public static void main(String[] args) {

	}
}



```

◎mainメソッド

```java
package trycatch;

public class main {
	public static void main(String[] args) {
    //インスタンス生成
	trycatch1 t=new trycatch1();
　　//実行
    t.test();
	}
}

```
AtCoderBeginnerContest178復習＆まとめ（前半）

# AtCoder ABC178
2020-09-13(日)に行われたAtCoderBeginnerContest178の問題をA問題から順に考察も踏まえてまとめたものとなります．
前半ではABCまでの問題を扱います．
問題は引用して記載していますが，詳しくはコンテストページの方で確認してください．
[コンテストページはこちら](https://atcoder.jp/contests/abc178)
[公式解説PDF](https://atcoder.jp/contests/abc178/editorial)

## A問題　Not
> 問題文
> $0$以上$1$以下の整数$x$が与えられます。 
> $x$が$0$なら$1$を、$1$なら$0$を出力してください。

提出したとき，テストケースが複数あってビビりましたが，無事'AC'でした．
case02~09も必要なのだろうか．

```python:abc178a.py
x = int(input())
print(1 - x)
```

## B問題　Product Max
> 問題文
> 整数$a,b,c,d$が与えられます。 
> $a \leq x \leq b, c \leq y \leq d$を満たす整数$x,y$について、$x×y$の最大値はいくつですか。

$x,y$が異符号しかとれない場合，最大値は$a×d$ または $c×b$．
$x,y$が同符号の場合，最大値は$a×c$ または $b×d$．

```python:abc178b.py
a, b, c, d = map(int, input().split())
print(max(a * c, b * d, a * d, c * b))
```

## C問題　Ubiquity
> 問題文
> 長さ$N$の整数の列$A_1,A_2,…,A_N$であって以下の条件をすべて満たすものはいくつありますか。
>　・$0 \leq A_i \leq 9$
>　・$A_i=0$なる$i$が存在する。
>　・$A_i=9$なる$i$が存在する。
> ただし、答えはとても大きくなる可能性があるので、$10^9+7$で割った余りを出力してください。

高校１年生の数Aの問題でした．
$A_i=0$なる$i$が存在する配列の集合を$B$，$A_i=9$なる$i$が存在する配列の集合を$C$とすると，

```math
\begin{align}
n(B \cap C) = n(B) + n(C) - n(B \cup C)
\end{align}
```

で求められますが，このままでは計算が大変なので式変形を行うと，

```math
\begin{align}
n(B \cap C) &= n(B) + n(C) - n(B \cup C) \\
&= n(U) - (n(\overline{B}) + n(\overline{C}) - n(\overline{B \cup C})) \\
&= n(U) - n(\overline{B}) - n(\overline{C}) + n(\overline{B} \cap \overline{C}) \\
\end{align}
```

となり，計算が簡単にできます．
$n(U) = 10^N$
$n(\overline{B}) = 9^N$
$n(\overline{C}) = 9^N$
$n(\overline{B} \cap \overline{C}) = 8^N$

```python:abc178c.py
n = int(input())
mod = 10**9 + 7
print((10**n - 9**n + 8**n - 9**n) % mod)
```

前半はここまでとなります．
最近は公式の解説がとても丁寧に記述してあったので，詳しい解法はそちらを参考にしてもらえたらと思います．
前半の最後まで読んでいただきありがとうございました．

後半はDE問題の解説となります．
[後半に続く](https://qiita.com/takaito0423/items/073f7ec1b562692b8c3c)．
【Git】過去のコミットから特定のファイルを削除したい。GitHubからも


#はじめに
GitHubにpushしてはいけないファイルをコミットしてしまっていた場合に、その履歴をまとめて修正したい場合、どうすればいいかを学んだ。
途中でエラーがでたところもあったので、その解決方法も書く。

#手順

##安全に行う為、ブランチを切る

`git checkout -b delete-check`

##そのブランチ上で、試す

今回は例として.envファイルを削除する。


```shell
git filter-branch --tree-filter 'rm -f .env' HEAD 
```


`filter-branch --tree-filter `で各コミットに対し、その後に続く、`rm -f .env' HEAD `のコマンドを実行する。


```shell:出力結果
WARNING: git-filter-branch has a glut of gotchas generating mangled history
	 rewrites.  Hit Ctrl-C before proceeding to abort, then use an
	 alternative filtering tool such as 'git filter-repo'
	 (https://github.com/newren/git-filter-repo/) instead.  See the
	 filter-branch manual page for more details; to squelch this warning,
	 set FILTER_BRANCH_SQUELCH_WARNING=1.
Proceeding with filter-branch...

Rewrite 7575dc6065c2dbbeef43df034dbe859f5a078 (1/6) (0 secoRewrite 98d96539c8c44062b280efc10e588a99b41b (2/6) (0 secoRewrite 25c2d7bc0e4d3fe23553c7b7607306c300c2dc (3/6) (0 secoRewrite d47862db7be1ab51df7b5e09f351abbf7b (4/6) (0 secoRewrite 2d0e1d8d96a19d35bc3a4453bc653c0cdc3ec5 (5/6) (0 secoRewrite 3fee6b5c30b9ddf9432de818cc5d9d20b13e0 (6/6) (0 seconds passed, remaining 0 predicted)
Ref 'refs/heads/delete-check' was rewritten
```

こういった出力になり、上書きされていることがわかる。


##masterブランチで実行する。

安全のために切ったdelete-check上で実行できることがわかったので、次にmasterブランチ上で同じコマンドを実行する。


```shell
git filter-branch --tree-filter 'rm -f .env' HEAD 
```

すると、

```shell

Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f
```
というエラーになり、

>前のバックアップがあるから、上書きしたいんやったら　-f つけて

と言われたので、

```shell
git filter-branch -f --tree-filter 'rm -f .env' HEAD 
```

`-f`をつけて実行すると成功。

###GitHubにプッシュ


```shell
git push -f origin master
```

これでローカル、リモートどちらも上書きされる。



##終わりに。
最後まで読んで頂きありがとうございます:bow_tone1:
転職の為、未経験の状態からReact,Railsを学習しております。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございました。
mp3ファイルの再生時間をpythonで計測する方法

mp3ファイルの持続時間を取得する方法は2つあります。
一つは mutagenを使用する方法で、もう一つはpysoxを使用する方法です。
それぞれの方法には長所と短所があります。

mutagenを使った方法は、pysoxを使った方法よりも軽量で高速です。

mutagenはmp3ファイルのID3タグをチェックするだけなのはそのためです。一方、pysoxはSox CLIを使ってmp3ファイルのバイナリをチェックするようです。

pysoxの方法では、ID3情報を使わずに持続時間を判定する、つまりID3情報が無効なファイルや、ID3情報がないファイルを認識することができます。pysoxを使うことで、ID3情報を使わずにデュレーションを調べることができる、つまり、ID3情報が無効なファイルや、ID3情報がないファイルのデュレーションを検出することができます。

## mutagenを使う方法

```python
from mutagen.mp3 import MP3

def mutagen_length(path):
    try:
        audio = MP3(path)
        length = audio.info.length
        return length
    except:
        return None

length = mutagen_length(wav_path)
print("duration sec: " + str(length))
print("duration min: " + str(int(length/60)) + ':' + str(int(length%60)))
```

## pysox を使う方法


Note: pysox needs SOX cli.

```python
import sox

def sox_length(path):
    try:
        length = sox.file_info.duration(path)
        return length
    except:
        return None

length = sox_length(mp3_path)

print("duration sec: " + str(length))
print("duration min: " + str(int(length/60)) + ':' + str(int(length%60)))
```
Firebase AuthenticationとIDトークンと更新トークンとセキュリティの話

## 初めに

[Firebase Authentication](https://firebase.google.com/docs/auth?hl=ja)を使用すると簡単にアプリにユーザー認証の仕組みを実装することができます。
自前のWebサーバーでFirebase Authenticationのユーザー認証を検証したい場合、IDトークンをクライアントから送ることで実現できます。
このIDトークンとセキュリティについて記載します。

以下の記事も参考にしてください。
[JWTでセッション管理してはいけない](https://qiita.com/hakaicode/items/1d504a728156cf54b3f8)

## 登場する単語

* IDトークン

ユーザーの情報が含まれたJWT。
有効期限が1時間しかない。

* 更新トークン

IDトークンを取得するために使用するトークン。

## Webサーバーでのユーザー認証の流れ

1. クライアントはFirebase Backendから更新トークンを使ってIDトークンを取得する。
2. クライアントはWebサーバーにIDトークンを送る。
3. WebサーバーはIDトークンを検証し、ユーザーを認証する。

## IDトークンが漏洩した場合

漏洩したトークンが1時間以上前のものなら期限が切れているのでユーザー認証には使用できません。
1時間以内のものならユーザー認証に使用できてしまうので無効にする必要があります。
更新トークンを無効にすることで間接的にIDトークンも無効になります。

注意が必要なのはIDトークンをWebサーバー側で`VerifyIDToken`を使用して検証している場合です。
この場合はIDトークンが無効であっても検証に成功してしまいます。
無効かどうかも含めて判別するためには`VerifyIDTokenAndCheckRevoked`を使用する必要があります。
両者の違いはIDトークンの無効状態をチェックするかどうかですが、無効状態のチェックにはコストがかかります。
(この関数はgoのものですがほかの言語ではチェックするかどうかをフラグで制御します。)

> // This function uses `VerifyIDToken()` internally to verify the ID token JWT. However, unlike
> // `VerifyIDToken()` this function must make an RPC call to perform the revocation check.
> // Developers are advised to take this additional overhead into consideration when including this
> // function in an authorization flow that gets executed often.
> 
> -- firebase-admin-go のauth.go VerifyIDTokenAndCheckRevokedのコメントより引用

## 更新トークンが漏洩した場合

更新トークンは有効期限がほぼないのですぐに無効にする必要があります。
`RevokeRefreshTokens`を使用することでユーザー単位で更新トークンを無効にすることができます。
更新トークンを無効にした場合でも前述の通り`VerifyIDToken`でIDトークンを検証していると成功してしまう点には注意してください。

## まとめ

IDトークンは**期限が1時間ととても短い**。
更新トークンを無効にすることで**IDトークンも無効にできる**。
無効にした場合でも`VerifyIDToken`で検証している場合は成功してしまう。
無効状態もチェックする場合は`VerifyIDTokenAndCheckRevoked`を使用する。
EclipseでCtrlの要素のホバーで遅い時の解決法

Ctrl + クリックで定義先に飛ぼうとすると少しフリーズしてから定義先に移動する現象の発生

よくよく観察するとCtrlでクラス、メソッドなどにカーソルが当たるとフリーズ


ウィンドウ > 設定 > 一般 > エディター > テキスト・エディター > ハイパーリンク
を開き、「オンデマンド云々・・・」

定義先に移動のチェックを外す
JetBrains Mono フォントを VSCode で使う

## 概要
JetBrains Monoは、Intellij IDEAなどのIDEを開発しているJetBrains社が作成したフォントです。
コードの可読性を高めるための工夫がされており、私はJetBrains製品ではこのフォントを使用しています。

他のフォントとの比較はしてどうか？という点は、単純にJetBrains製品が好きというだけで使ってるので分かんないです。なんとなく文字の識別はしやすいかなと思ってます。

公式サイトに情報があるので確認してみてください。

https://www.jetbrains.com/ja-jp/lp/mono/

## JetBrains Monoをダウンロードする 
公式サイトからフォントファイルをダウンロードする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44066/24298d1f-f97c-72fb-cc25-60ff7cee94c6.png)

## フォントをインストールする
### Windows
解凍したZIPファイルのttfフォルダにあるフォントを右クリックしてインストールする
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44066/118992c1-be0c-86ec-6299-699421629e05.png)

### Mac
解凍したZIPファイルのttfフォルダにあるすべてのフォントファイルを選択し、ダブルクリックする。
次に表示されるウィンドウで「Install Font」をクリックします。
![スクリーンショット 2020-09-20 7.06.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44066/e95d4443-c64b-e1ff-595c-db46586613a6.png)


## VSCodeのフォント設定をする
VSCodeを開いて、フォント系の設定をする

```json
"editor.fontFamily": "JetBrains Mono",
"editor.fontLigatures": true
```
【MT7】カスタムフィールドの値によってjsでリダイレクトする

#概要
MT7でカスタムフィールドの値によってリダイレクトを行ったときのメモです。
記事によってその記事を見せずに、別ページやトップに飛ばしたい。といった感じです。

PHPが使えないため、jsで処理を入れました。

#実装
ページを読み込んだ最初に処理したいので、head内にスクリプトを書きました。
チェックボックスのカスタムフィールドで、チェックが入っていればリダイレクトします。

テンプレートタグ：`CFIsRedirect`
ベースネーム：`cf_is_redirect`

```index.html

<head>
:
:
  <script type='text/javascript'>
  var status = <MT:CFIsRedirect encode_js="1">;
  if (status == 1) {
    location.href = 'https://example.com';
  }
  </script>
</head>
```

MTタグの内容をjsで使う場合は、モディファイア`encode_js="1"`を指定します。
このモディファイアを指定することでjsの文字列の値として使えるようにエンコードしてくれます。

チェックが入っていれば値は`1`なので、その場合`location.herf`で指定のURLに飛ばしています。

#まとめ
今回の手法は、アナリティクスなどを正確に計測するため、パラメーターやリファラを正しく引き継ぐようなリダイレクトではないので、実際はもう少し処理が必要なようです。

#参考
- [リダイレクトの方法](https://qiita.com/mimoe/items/ec2f51b13410b9e1024a)
- [やはり、お前らのJavaScriptでのリダイレクト実装は間違っている](https://qiita.com/1987yama3/items/5ff58b6195fe6c3f268b)
順不同な非同期処理を待機して順番どおりに実行する

非同期処理を呼び出された順番どおりに実行するパターンです。processing変数によって、実行時にフラグをたてておいて、それをsetIntervalで監視してよいタイミングになるとsetIntervalを止めて実行します。

# 非同期処理をそのまま実行する例
```js:index1.js
const data = ['a', 'b', 'c', 'd', 'e'];

const randomInt = function(min, max) {
  return Math.floor( Math.random() * (max + 1 - min) ) + min;
};
const process = name => {
  setTimeout(() => {
    console.log('process:' + name);
  }, randomInt(1000, 3000));
}

data.forEach((value) => {
  process(value)
  console.log(value);
})

// 実行結果
// a
// b
// c
// d
// e
// process:e
// process:d
// process:b
// process:a
// process:c
```

# 順不同な非同期処理を待機して順番どおりに実行する例
```js:index2.js
const data = ['a', 'b', 'c', 'd', 'e'];

const randomInt = function(min, max) {
  return Math.floor( Math.random() * (max + 1 - min) ) + min;
};

let processing = false;
const process = name => {
  processing = true;
  setTimeout(() => {
    console.log('process:' + name);
    processing = false;
  }, randomInt(1000, 3000));
}

data.forEach((value) => {
  const intervalId = setInterval(() => {
    if (processing === true) {
      return;
    }
    clearInterval(intervalId);
    process(value);
  }, 50);
  console.log(value);
})

// 実行結果
// a
// b
// c
// d
// e
// process:a
// process:b
// process:c
// process:d
// process:e
```
非同期処理を待機して一番最後に呼ばれたものだけ実行する

キー入力に対してインクリメントに動作するAPI呼び出しの待機処理などに使えるパターンです。
setTimeoutで遅延実行させている間に次の呼び出しがあった場合は、clearTimeoutで前回の呼び出しをキャンセルするので、最後に呼ばれたものだけが実行されます。

# 非同期処理をそのまま実行する例
```js:index1.js
const data = ['a', 'b', 'c', 'd', 'e'];

const randomInt = function(min, max) {
  return Math.floor( Math.random() * (max + 1 - min) ) + min;
};
const process = name => {
  setTimeout(() => {
    console.log('process:' + name);
  }, randomInt(1000, 3000));
}

data.forEach((value) => {
  process(value)
  console.log(value);
})

// 実行結果
// a
// b
// c
// d
// e
// process:e
// process:d
// process:b
// process:a
// process:c
```

# 非同期処理を待機して一番最後に呼ばれたものだけ実行する例
```js:index3.js
const data = ['a', 'b', 'c', 'd', 'e'];

const randomInt = function(min, max) {
  return Math.floor( Math.random() * (max + 1 - min) ) + min;
};

const process = name => {
  setTimeout(() => {
    console.log('process:' + name);
  }, randomInt(1000, 3000));
}


let timeoutId;
data.forEach((value) => {
  clearTimeout(timeoutId);
  timeoutId = setTimeout(() => {
    process(value)
  }, 1000)
  console.log(value);
})

// 実行結果
// a
// b
// c
// d
// e
// process:e

```
JSのArrayに「ランダムに要素を返す」メソッドを生やす

メモ。目新しいことは書いてない。

# 普通にやる

普通にやるとこんな感じ。

```javascript
function randomSelect(array){
  let index = Math.floor(Math.random() * array.length)
  return array[index]
}

let fruits = ["apple", "orange", "banana"]
console.log(randomSelect(fruits)) // →banana
```

# prototype拡張で書く
個人的にはなんかこの書き方が好きじゃないので、`prototype`に直接拡張してみた。


```javascript
Array.prototype.lot = function(){
  let index = Math.floor(Math.random() * this.length)
  return this[index]
}

let fruits = ["apple", "orange", "banana"]
console.log(fruits.lot()) // →banana

```

lotはくじという意味。可読性的にはrandomとかrandomSelectとかのほうがいいと思う。

取り出した要素を配列から削除するバージョン。

```javascript
Array.prototype.pick = function(){
  let index = Math.floor(Math.random() * this.length)
  return this.splice(index,1)[0]
}

let fruits = ["apple", "orange", "banana"]
console.log(fruits.pick()) // →banana
console.log(fruits) // →["apple","orange"]
```

prototype拡張しても大丈夫な時しか使えないけど、メソッドチェーンぽく使えてちょっと便利……かもしれない。好みの問題かな？
今書いてるやつでこういう処理を頻繁にやるので、導入してみたらちょっといい感じになったよというお話でした。
ガイド：Alibaba Cloud Toolkitプラグインを使用してアプリケーションをデプロイ

この記事では、**Alibaba Cloud Toolkit**プラグインを使用してアプリケーションをデプロイする際のコマンドの書き方のベストプラクティスを紹介します。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/alibaba-cloud-toolkit-command-writing-guide_594999)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

この記事では、[Alibaba Cloud Toolkit](https://cn.aliyun.com/product/cloudtoolkit_en)プラグインを使用して以下のアプリケーションをデプロイする際のコマンドの書き方のベストプラクティスを紹介します。

- スタンダードな Java Web Tomcat アプリケーション
- スタンダードなJava Fatjarアプリケーション
- スタンダードなSpring Bootアプリケーション
- スタンダードなGo アプリケーション

#スタンダードなJava Web Tomcatアプリケーション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/b3953e84-8bb5-b6b8-3271-46b498b26939.png)


上図のように，Linux システムの `/root/tomcat/ `が Tomcat アプリケーションのルートディレクトリであるとします．この`/root/tomcat/webapps`ディレクトリにJava WebアプリケーションのWARパッケージ(javademo.war)をデプロイする必要があります．

対応するコマンド構成は以下の通りです。

```
sh /root/sh/restart-tomcat.sh
```

restart-tomcat.shスクリプトの内容は以下の通りです。

```
source /etc/profile
killall java
rm -rf /root/tomcat/webapps/javademo
sh /root/tomcat/bin/startup.sh
```

/ect/profile ファイルは環境変数を設定するために使用され、以下のような内容が含まれています。

```
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi
export JAVA_HOME=/usr/share/jdk1.8.0_14
export PATH=$JAVA_HOME/bin:.....
```

#スタンダードなJava Fatjarアプリケーション
Linux システムの` /root/javademo` ディレクトリが Java アプリケーションのルートディレクトリとして使用されているとします。Javaアプリケーションのjarパッケージを`/root/javademo`ディレクトリにデプロイする必要があります．

対応するコマンド設定は以下の通りです．

```
sh /root/sh/restart-java.sh
```

restart-java.shスクリプトの内容は以下の通りです。

```
source /etc/profile
killall java
nohup java -jar /root/javademo/javademo-0.0.1-SNAPSHOT.jar > nohup.log 2>&1 &
```

#スタンダードなSpring Bootアプリケーション
Linuxシステムの`/root/springbootdemo`ディレクトリがSpring Bootアプリケーションのルートディレクトリとして使用されているとします。Spring Bootアプリケーションのjarパッケージ(springbootdemo-0.0.1-SNAPSHOT.jar)を`/root/springbootdemo`ディレクトリにデプロイします。

対応するコマンド設定は以下の通りです。

```
sh /root/sh/restart-springboot.sh
```

restart-springboot.shスクリプトの内容は以下の通りです。

```
source /etc/profile
killall java
nohup java -jar /root/springbootdemo/springbootdemo-0.0.1-SNAPSHOT.jar > nohup.log 2>&1 &
```

#スタンダードなGoアプリケーション
Linux システムの` /root/godemo` ディレクトリが Go アプリケーションのルート ディレクトリとして使用されているとします。Goアプリケーションの実行ファイル(godemo)を`/root/godemo`ディレクトリにデプロイする必要があります。

対応するコマンド構成は以下の通りです。

```
sh /root/sh/restart-go.sh
```

restart-go.shスクリプトの内容は以下の通りです。

```
source /etc/profile
pkill -f 'godemo'
chmod 755 /root/godemo/godemo; 
sh -c /root/godemo/godemo
```

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*
[備忘録]nginx、unicornとは

#Webサーバとアプリケーションサーバ
unicornとnginxを説明するにあたって、まず知っておく必要がある知識の為、以下にまとめておきます。

__Webサーバーとは__
クライアント(ブラウザ)から送られてきたリクエストに応じたコンテンツをレスポンスとして返すものです。
しかし、リクエストに対してWebサーバ内で処理できるものとできないものがあります。

Webサーバ内で処理ができるものとは、データベースと通信せずに、
静的なコンテンツ(要求内容・人にかかわらずいつでも同じ結果を返すコンテンツ)のみをクライアントに返すものです。

Webサーバ内で処理ができないものとは、動的なコンテンツ(要求内容や要求する人に応じて異なる結果を返すコンテンツ)を生成し、リクエストとして返すものです。

リクエストに対してWebサーバ内で処理をすることができないと判断した場合は、
処理をアプリケーションサーバに依頼します。

アプリケーションサーバに動的コンテンツの生成を依頼し、生成されたコンテンツがレスポンスが返ってくるので、Webサーバはその結果をクライアントに返します。


__アプリケーションサーバとは__
Webサーバから受けたリクエストをもとに、バックエンドで動作するJavaやphp、Rubyなどを実行し、生成した動的コンテンツなど処理の結果をWebサーバに返します。

これらを踏まえてNginx、Unicornの説明に入ります。

# Nginx(エンジンエックス)とは
Webサーバの一種です。フリーで使えるオープンソースのWebサーバですが、
特徴として__同時リクエストを多く処理することに特化している__事が挙げられます。

Nginxにはリバースプロキシ機能と呼ばれる機能がついており、
プロキシサーバーがリクエストをさばき、複数のWebサーバーにリクエスト処理を分散させることができます。（負荷分散）

# Unicorn(ユニコーン)とは
アプリケーションサーバの一種で、Rackアプリケーション用サーバです。
NginxはRackアプリケーションサーバーと直接リクエスト、レスポンスのやりとりをすることができないので、両者を仲介する別のアプリケーションサーバーを立てる必要がある為、nginxと組み合わせて使うことが多いです。

参考URL
https://it-biz.online/it-skills/static-dynamic/
https://academy.gmocloud.com/qa/20160616/2761
[https://chopesu.com/programing/aws](https://chopesu.com/programing/aws%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89-nginx%E3%81%A8unicorn%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%AE%E7%9B%AE%E7%9A%84%E3%82%92%E8%87%AA%E5%88%86%E3%81%AA%E3%82%8A%E3%81%AB%E3%83%A1%E3%83%A2/)
RE:VIEW starterで書籍サイズをA4にして裏表紙もいれてみる

RE:VIEW系で指定できる書籍サイズはB5かA3なのですが、A4にしたかったのでやってみました。裏表紙をいれると裏表紙の後ろに一ページ、あとがきが入ってしまうのが直らない・・・。

# config.ymlの編集
config.ymlを編集してA4サイズにする
LaTeX用のdocumentclassを指定している箇所でA4を指定。
A5やB5を指定しているtexdocumentclassはまるっとコメントアウト。

    # ここでA4を指定
    texdocumentclass: ["jsbook","dvipdfmx,uplatex,papersize,twoside,a4j,10pt,openany"] 

    #以下はA5やB5の指定なのでコメントアウト
    #texdocumentclass: ["jsbook",
    #"dvipdfmx,uplatex,papersize,twoside,b5j,10pt,openright" # B5 10pt 右起こし
    #"dvipdfmx,uplatex,papersize,twoside,b5j,10pt,openany"   # B5 10pt 両起こし
    #"dvipdfmx,uplatex,papersize,twoside,a5j,9pt,openright"  # A5  9pt 右起こし
    #"dvipdfmx,uplatex,papersize,twoside,a5j,9pt,openany"    # A5  9pt 両起こし
    #"dvipdfmx,uplatex,papersize,oneside,a5j,10pt,openany"   # A5 10pt 両起こし>（タブレット向け）
    #    "dvipdfmx,uplatex,papersize,twoside,b5j,10pt,openany"
    #]



裏表紙の指定。
backcoverに裏表紙を生成するtexファイル（後で自分でつくる）を指定。

    backcover: backcover.tex


# backcover.texの作成
config.ymlと同じ階層に、backcover.texを作成。
以下を記述。./images/backcover.pdfはA4サイズの裏表紙PDFを置いておく。

    \clearpage
    \thispagestyle{empty}
    \begin{center}
    \includepdf{./images/backcover.pdf}
    \end{center}


# あとがきページのバグがなおらない。
PDF生成すると、A4サイズのPDFになって裏表紙もつくのだけど、裏表紙のさらに後ろになぜかあとがきと左上に書かれたページが挿入されてしまう。なぜ・・・。
とりあえず、CubePDF Utilityで一番後ろのページを削除するというダサ対応しました。
SCSSのrandom関数で最小値を設定する




ランダムな値を生成したいけど最小値は設定したい
というときのためのSCSS

```
// 指定した最小値($min)と最大値($max)の間のランダムな数を返す
// 単位は$unitに指定（px,%,vw,vh,vmax,vmin）
// minMaxRandom(80, 100, 1%)
@function minMaxRandom($min: 1, $max: 100, $unit: 1%) {
  $num: random($max);

  @while ($num/($num * 0 + 1) < $min) {
    $num: random($max);
  }
  @return $num * $unit;
}
```

##使い方

（例）div100個に幅と高さが100pxから200pxのランダムな数値を指定する

```
@for $i from 1 through 100 {
  div.nth-child(#{$i}) {
      $rondomNum: minMaxRandom(100, 200, 1%);
      width: $rondomNum;
      height: $rondomNum;
  }
}
```


> 参考
> [SCSSでランダムな値を扱う方法](https://qiita.com/tonkotsuboy_com/items/909b4073459ecaf7a435)
> 


デフォで最小値も設定できたらいいのに。。
と思った次第でした。

おしまい。
iOS で 画像の横を画面ギリギリまで広げて、高さをアスペクト比で伸ばした画像にする方法

# やりたいこと

- 端末毎に横サイズが異なるので、横幅を固定値で指定したくない
  - 左右マージン20pxとかにしたい
- 高さはアスペクト比維持していい感じに伸びて欲しい
- 画像のアスペクト比は崩さないで欲しい

# 結論

- 左右に20pxのマージン制約つける
- 画像にアスペクト比の制約をつけて、画像毎のアスペクト比を指定する
- content mode は scale to fit にする


# 蛇足. 試したけどダメだったこと

左右制約 と content mode を aspect fit にする
-> 端末サイズによって横幅が広がりきらない


左右制約と content mode を scale to fit にする
-> 画像アスペクト比が維持されないで崩れる



Android だったら wrap_content 指定するだけなのにね。iOSは大変だ
Gitコマンド超省略版

Linux(Ubuntu)のターミナルからGitを操作する最低限のコマンドをまとめました。
#クローン
```shell
git clone (URL)
```

#コミット関係
基本これの繰り返し
※ cd で更新するディレクトリに予め移動

```shell
git add .
git commit -m 'commit comment'
git push origin master # masterブランチの更新
```
#ブランチを切る
```shell
git branch -a # 一覧 
git checkout (ブランチ名) # 移動
git checkout -b feature # 作成+移動（featureは例）
git merge feature # featureをmasterにマージ（masterだけになる）
```
ここまで使えば個人レベルのgit管理はできそう
#（おまけ）あんまり使ってない編
```shell
git branch -d feature # ローカルブランチ削除
git branch -d -r origin/feature # 追跡ブランチ削除
git push origin :feature # 空ブランチを指定してリモートブランチ削除

git reset --soft HEAD^ # 直前のコミット取り消し
```
resetは以下が参考になりそう
https://qiita.com/ChaaaBooo/items/459d5417ff4cf815abce