OmniAICreator/Qiita-1.07M huggingface dataset:
社内proxy環境下においてGitlabでfetchやpullはできるけどcloneやpushができなくなってしまった際の解決方法

# 前提
* 社内のサーバにGitlabが乗っている(そのため今回の事象は少々特殊な状況であると言えます)
* 直近でサーバのIPアドレスの付け替えが発生した
* IPアドレスが変わって以降、fetchやpullはできるのにcloneやpushができなくなってしまった
* 利用している端末はWindows10
* 社内GitlabへのSSHでの接続は禁止されている
* IP付け替え後、git remote set-url でリポジトリのURLは変更済

# 事象
社内サーバのGitlabに対して、pushやcloneを実行すると下記のエラーメッセージが表示され実行に失敗してしまう。
(前述の通りfetchやcloneは問題なし)

```
remote: HTTP Basic: Access denied
fatal: Authentication failed for 「リポジトリのURL」
```
見た感じ、リポジトリに対する権限不足や、fetch, pullはできるためURLのミスということではなさそう。
調べてみるとSSHに変えろという意見がちらほらありましたが、前提にある通りSSHでの接続は禁止されているため、それ以外の解決方法を模索することになりました。

# 解決方法
下記に解決方法がありました。
https://stackoverflow.com/questions/47860772/gitlab-remote-http-basic-access-denied-and-fatal-authentication

『Windowsの資格情報マネージャーから古い情報を消してみてくれ』という内容。
上記に従って、資格情報マネージャーを確認したところ古いIPアドレスの社内サーバGitlabの資格情報が残っていた。
社内サーバGitlabの資格情報をすべて消してみたところ、push, cloneが問題なくできるようになりました。

# まとめ
解決してしまえばなんてことはない、資格情報マネージャー内の情報が混乱していたようです。
チーム内でWindows10端末を利用しているのは私ぐらいで、今回の事象が発生したのは私だけでした。
Windows7ではこの事象は起きないかもしれません。

今回はWindows10のお話でしたが、
Mac利用の方で同様の事象が発生した場合は、『KeychainAccess』を確認してみるといいかもしれません。

エラーメッセージでぐぐったら検索結果の上の方に出ていたけど、
英語が苦手すぎて気づけず2時間近くハマるという情けない結果に...
英語に拒否反応示したらだめですね。
あとちょうどエイプリルフールでStackoverflowのサイトがへんてこな表示になっていたのも...という言い訳です。

# 参考サイト
GitLab remote: HTTP Basic: Access denied and fatal Authentication
https://stackoverflow.com/questions/47860772/gitlab-remote-http-basic-access-denied-and-fatal-authentication
Vue.jsでtemplateでclassを複数定義したいならこうしよう

# 結論

Vue.jsでこんな感じでかけます

```vue
<template lang="pug">
.hoge-container
  .box-wrapper(:class="[propsClass, { active: isActive }]")
</template>

<script>
export default {
  name: 'hoge-container'
  props: {
    propsClass: {
      type: String,
      required: false,
    },
    isActive: {
      type: Boolean,
      required: true,
    }
  }
}
</script>
```

# 説明

この書き方の場合、 `propsClass` には class名が `String` で渡ってきたら、そのまま classに入る。そして、 `isActive` は `true` で渡ってきたら、 `active` クラスが付与される。


# 補足：これでもok

```vue
<template lang="pug">
.hoge-container
  .box-wrapper(:class="[propsClassA, propsClassB, propsClassC]")
</template>
```

```vue
<template lang="pug">
.hoge-container
  .box-wrapper(:class="{active: isActive, big: isBig}")
</template>
```
RHEL7 ルートCA証明書インストール方法

### 1. 証明書を配置

```:配置場所
# cd /etc/pki/ca-trust/source/anchors
# wget https://---/xxxx.cert
```

### 2. インストール

```:実行コマンド
# update-ca-trust extract
```

### 3. 確認

```:インストール先
# view /etc/pki/tls/certs/ca-bundle.crt
```
LAN内で利用されているIPアドレスを調べる



# IPアドレスを調べる

- sudo arp-scan -I eth0 -l
- sudo nmap -sP 192.168.1.*


```
arp-scan ,nmap で、MACからのベンダ情報は異なる
```
- PowerShell: Get-NetNeighbor もしくは、arp -a |Select-string '192'
 
# IPから MAC アドレスを調べる

- arping 192.168.1.1 -f


# Windows の　ＰＣ名を調べる
nmblookup -A 192.168.1.83

# Windows の　ＰＣ名からＩＰアドレスを調べる
nmblookup ＰＣ名

# MAC アドレスからベンダー名割り出し
[参考](https://pslabo.hatenablog.com/entry/2016/03/18/%E3%80%8CMAC%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%81%8B%E3%82%89%E3%83%99%E3%83%B3%E3%83%80%E3%83%BC%E3%82%92%E6%A4%9C%E7%B4%A2%E3%81%97%E3%81%A6%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B%E3%82%B3%E3%83%9E)

```
#!/bin/sh

while [ $# -gt 0 ]; do
        echo -n "$1="
        curl "http://api.macvendors.com/$1"
        echo ""
        shift
done
```
# DHCP のリリース

```
- Windows
ipconfig /release
ipconfig /renew

- Linux 
dhclient -r device
dhclient  device
```
# 特別のアドレス

- 239.255.255.250 UPnPが使うアドレス
- x.x.x.255 ブロードキャストアドレス(ネットマスク 255.255.255.0 の場合）
php-master-changes 2019-04-01

今日は Win32 版での処理系起動時の CRT 互換性チェック修正、コードページの処理で ASCII が含まれているかのチェックの高速化、JIT のマージ、travis 用に一部テストの無効化、timezonedb の更新があった！

# 2019-04-01
## weltling: Implement stricter CRT check
- https://github.com/php/php-src/commit/dd0aca0c11f2572e37fd9583866f37d895a80e4e
- [7.4~]
- Win32 版で、処理系起動時に CRT の互換性チェックを行うよう修正

## weltling: Rework conditions and make them more future proof
- https://github.com/php/php-src/commit/f7b053f5da62514a0f9735ee342e322a19455399
- [7.4~]
- Win32 版で、[昨日の拡張ロードの方](https://qiita.com/sj-i/items/dadd77bb5f9d3b4cd498#weltling-implement-stricter-extension-compatibility-check)とあわせて条件指定のリファクタリング

## weltling: Improve ascii check
- https://github.com/php/php-src/commit/1686c3fa47155d9c3884726b2ade4dede2eeb99f
- [7.4~]
- Win32 版のコードページの処理で、ASCII が含まれているかのチェックを高速化
- OR で載せてって一括で見る、なるほど

## dstogov: Added JIT compiler for x86 and x86_64
- https://github.com/php/php-src/commit/9a06876072b9ccb023d4a14426ccb587f10882f3
- [JIT](https://wiki.php.net/rfc/jit) の master へのマージ
- 話としては @rana_kualu さんの[記事](https://qiita.com/rana_kualu/items/ba312d2789bd228f887a)が日本語でよくまとまってる
- 英語だと krakjoe の人が JIT というのが何か、どうして入るのか、どんな局面で使えそうか、開発への影響についてみたいな[記事](https://blog.krakjoe.ninja/2019/03/php-gr8.html)を出してる
- 現状実装だとほぼ opcache の中でやってるけど、[これから VM と深く統合していく](https://externals.io/message/104991#104991)みたいな話もしてる

## smalyshev: Unfortunately, travis CI has old oniguruma library
- https://github.com/php/php-src/commit/0eea9a642941ab5d4c612f8092f186977afbb73e
- [7.4~]
- travis で oniguruma が古くてテストがこけるので一部テストを無効化

## derickr: Updated to version 2019.1 (2019a)
- https://github.com/php/php-src/commit/a22bd7a3a8365f546827ab19efa3e19d3a64c6a6
- [7.3~]
- ext/date で、timezonedb の更新

## krakjoe: fix zts jit build
- https://github.com/php/php-src/commit/e9c49b73b7d65d40e7345353426da144cd063d01
- ext/opcache で、JIT のマージで enable_maintainer_zts のままになっていた箇所を enable_zts に修正
初めてのオリジナルWebサービス

## はじめに
プログラミングを学びはじめて3ヶ月。
初のオリジナルサービスを作成しましたので、公開させていただきます。

**MemoMa**
https://memoma-yyc.herokuapp.com/

## 内容説明
・問いに答えることで自己分析ができるサービス
・話題の[メモの魔力](https://www.amazon.co.jp/%E3%83%A1%E3%83%A2%E3%81%AE%E9%AD%94%E5%8A%9B-Magic-Memos-NewsPicks-Book/dp/4344034082)（前田裕二: 著）のノート術をWeb上で出来るメモアプリ

<img src="https://qiita-image-store.s3.amazonaws.com/0/329827/85407e98-ed9b-6457-7bd6-90f5c5355b77.png" alt="スクリーンショット 2019-04-02 7.13.06.png" width="1000 * 1000">

<img alt="スクリーンショット 2019-04-02 7.14.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/329827/085ad11a-367a-463b-0939-2f34dc5a6ff6.png" width="1000 * 1000">

## なぜ自己分析サービスを作ったのか？
理由は単純で、自分が使いたかったからです。
オリジナルサービス作成期間は仕事を辞めて、これからの転職活動に向けて人生の棚卸し中でした。
ちょうどその頃[メモの魔力](https://www.amazon.co.jp/%E3%83%A1%E3%83%A2%E3%81%AE%E9%AD%94%E5%8A%9B-Magic-Memos-NewsPicks-Book/dp/4344034082)に出会い、このメモ術がWeb上で出来たら便利だなーという思いで作り始めました。

## 主な機能
１つ特徴としては一般公開（share）機能があることです。
基本的に自己分析のためのサービスなので、問いに対する答えはログインユーザー（自分）にしか見られません。
ただ、ユーザー自身の意思で一般公開も出来るようにshare機能を作りました。

その他の機能は

- 投稿（問いに対する答え）の一覧表示、詳細表示、新規作成、編集、削除機能
- ユーザー登録、ログイン、退会機能
- 画像アップロード機能
 
など、ごくごく一般的です。

## サイト設計
サイト設計は[Cacoo](https://cacoo.com/ja/home)というオンラインサービスで行いました。

・サイトマップ
<img width="500 * 500" alt="スクリーンショット 2019-04-02 7.51.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/329827/da16a8e9-8d43-1b8b-2f02-6ac70210de23.png">

・データベース図(ER図)
<img width="500 * 500" alt="スクリーンショット 2019-04-02 7.51.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/329827/5ced668c-3a70-1b7c-0526-b672d71fc8cb.png">


## 反省点
**データベース設計が甘かった！！**
技術的な詳しいことはまた別の機会で書こうと思いますが、当初上記の中間テーブル（share_permissions）はありませんでした。
そのせいで無駄に難しいことをしようとして大幅に時間がかかることに...
データベース設計の大切さを痛感いたしました😅


色々遠回りもしましたが、全てが良い勉強になりましたし、一応の形にできたことは素直に嬉しいです。

今後も工夫した点や苦労した点など上げていきたいと思います。

最後まで読んでいただきありがとうございました。


オリジナルサービス
https://memoma-yyc.herokuapp.com/

ソースコード(GitHub)
https://github.com/Fiddler25/MemoMa
Sass(Scss)  学習記録

#Sass(Scss) 学習記録

##Sass(Scss)の学習を始めたので、備忘録として残しています。


## @mixin　@include

 1.@mixinで定義したスタイルを@includeで何度でも呼び出せ、関数的な使い方ができる。
 2.引数を使用できる

``` Scss
 @mixin common_card($color) {
   width: 350px;
   padding: 15px, 30px;
   font: 15px;
   color: $color;

 }
```  



``` Scss
.card_sample1 {
  @inculed common_card(##ff768a);
}

.card-sample2 {
  @inculed common_card(#FFE404);
}
```
【Java7】Javaのlistを分割して処理を実行する

# Javaのlistを分割して処理を実行する(Java7)

## はじめに
環境によっては、古いコードをあえて書かなければならない場合も多々あると思います。
Listを分割して処理を実行するコードを Java7 で書く機会があったので、初投稿してみました。

## 実装
``` java

public class Sample {
	public static void main(String[] args) {

		List<String> sampleList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
		int size = 2;	// 一度に処理を行うリスト数

		for (int i = 0; i < sampleList.size(); i += size) {
			List<String> list = new ArrayList<>(
					sampleList.subList(i, Math.min(i + size, sampleList.size()))
			);
			System.out.println(list);	// ここで処理を実行する
		}
	}
}

```
##### 実行結果
```
[aaa, bbb]	// sampleList.subList(0, 2)
[ccc, ddd]	// sampleList.subList(2, 4)
[eee]		// sampleList.subList(4, 5)
```

## 説明
`subList(int from, int to)`は`from`(含む)から`to`(含まない)までのListを返します。
for文で`from`と`to`を分割する数ずつ増やし、処理対象のListを取得しています。

`Math.min(int a, int b)`は2つのint値のうち小さいほうを返します。
Listのサイズが分割する数で割り切れない場合は、`to`について考慮する必要があり、
最後の繰り返しの場合、`to`に`sampleList.size()`を入れています。

## subListの注意点
`subList`で取得したListは元の値とデータを共有しています。つまり、`list`の値を変更すると`sampleList`の値も変更されます(例1)。
しかし、newしてから変更を行うことで、元のListを変更をせずにsubListのみを変更することが出来ます(例2)。

##### 例１　subListを変更すると、元のlistも変更される。
```java

public class Sample {
	public static void main(String[] args) {

		List<String> sampleList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
		int size = 2;	// 一度に処理を行うリスト数

		System.out.println(sampleList);		// 処理前
		for (int i = 0; i < sampleList.size(); i += size) {
			List<String> list = sampleList.subList(i, Math.min(i + size, sampleList.size()));
			list.set(0, "zzz");				// 処理実行
			System.out.println(list);
		}
		System.out.println(sampleList);		// 処理後
	}
}
```
##### 実行結果
```
[aaa, bbb, ccc, ddd, eee]	// 処理前
[zzz, bbb]
[zzz, ddd]
[zzz]
[zzz, bbb, zzz, ddd, zzz]	// 処理後
```
上記の通り、`list`を更新した結果、`sampleList`も更新されたことが分かる。

---

##### 例2　newすることで、subListを変更しても元のlistが更新されない。
```java

public class Sample {
	public static void main(String[] args) {

		List<String> sampleList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
		int size = 2;	// 一度に処理を行うリスト数

		System.out.println(sampleList);		// 処理前
		for (int i = 0; i < sampleList.size(); i += size) {
			List<String> list = new ArrayList<>(
					sampleList.subList(i, Math.min(i + size, sampleList.size()))
			);
			list.set(0, "zzz");
			System.out.println(list);
		}
		System.out.println(sampleList);		// 処理後
	}
}
```
##### 実行結果
```
[aaa, bbb, ccc, ddd, eee]	// 処理後
[zzz, bbb]
[zzz, ddd]
[zzz]
[aaa, bbb, ccc, ddd, eee]	// 処理後
```
上記の通り、`list`を変更しても`sampleList`は変更されないことが分かる。

## 参考
- [Math (Java Platform SE 7) - Oracle Docs](https://docs.oracle.com/javase/jp/7/api/java/lang/Math.html)
- [List (Java Platform SE 7) - Oracle Docs](https://docs.oracle.com/javase/jp/7/api/java/util/List.html)
- [JavaのListで任意の件数ごとに処理 - Qiita](https://qiita.com/namidame_Ba/items/ccd954cc04eac8a5defd)
最初の言語(Your First Language)について

![image.png](https://qiita-image-store.s3.amazonaws.com/0/257568/9bb3a5a7-9571-1f68-21ff-b4fd951bb3bd.png)

こちらの本を読んでパターンを1つずつまとめ
個人的に実践可能そうなものから

## アプレンティスシップ・パターンとは
アプレンティスシップとは徒弟制度のことで、よく起きる問題への共通の解決策に実際なっているものをパターン化したもの

### アプレンティスであるということは
**今まで行ったことや今やっていることをより良く、さらに賢く、もっと速く行う方法が常にあるという態度を基本的に持つこと**

## 前提
- あなたの曖昧で暗黙の知識を他の人々が共有できると、安易に思い込まない事
- パターン同士は結びついているので、あるパターンを既に知っているという事は未知のパターンを辿る事ができる
- 優れたプログラマになる方法を教えるのではなく、優れたプログラマになるための学び方を教える

## 最初の言語(Your First Language)とは
色々な指標で考え、言語を1つ選びましょうということ

## 状況
あなたは1つか2つのプログラミング言語を理解しているだけ

## 問題
- 自分の仕事の評価が特定のプログラミング言語を使って、一定の品質基準のプログラムを提供することにかかっている
- 仕事を得るのに、特定のプログラミング言語を習熟することにかかっている

## 解決方法
言語を1つ選定し、その言語に精通する。

## ポイント
- その言語でオープンソースのプロジェクトを構築する
- 知り合いで最も経験があるプログラマに継続的に支援を求める
- 解決すべき実際の問題をもつ
- 学習はインタラクティブに小さく行う
- その言語を使用しているプロジェクトにおいて、専門家と一緒に定期的に働けること
- その言語を習熟したことによって、他の言語を学ぶことや使用することを妨げない

## 行動
- あなたが選んだ言語の仕様を読む 
- 習得した最初の言語をどのようにして選択したか、一緒に働いている人に尋ねてみる
- 身近な専門家からフィードバックを得る
- デザインパターン(プログラミング)を知り、命名の背景を知る(そのパターンが元々解こうとしていた問題を突き止める)

## 関連パターン
- [壊してよいオモチャ(Breakable Toys)](https://qiita.com/dich1/items/3a818c477b62d30bae42)
- 徹底的に調べる(Dig Deeper)
- 良き指導者を見つける(Find Mentors)
- 長い道のり(The Long Road)
- ソースを活用する(Use the Source)

## 書籍情報
Dave H. Hoover (著), Adewale Oshineye (著), 柴田 芳樹 (翻訳), アプレンティスシップ・パターン
https://amzn.to/2UCKF9D

## 雑感
馬鹿げたほど小さなステップから始める
Dart-Build-in types

#Dart Build-in types
Dartの変数における型の種類を整理します。

## Numbers
Dart言語における数値型を整理します。

- int 整数型
- double 少数型

```dart
int i = 1;
double d = 2.0;
```

## Strings
Dartの文字列型はStringで定義します。
Dartの文字コードセットはUTF-16です。

```dart
// シングルクォーとダブルクォートの両方で宣言可能です。
String s1 = 'hoge';
String s2 = 'hogehoge';
```
ちなみに、String型の文字列比較は「==」で可能です。Javaと違って楽ですね〜

```dart
assert(s1 == s2);
```

## Boolean
Dartの真偽値型は「bool」で宣言します。

```dart
bool b = true;
```

## Lists
Dartでは一連の値をまとめて格納しておくオブジェクトでList型が用意されています。

```dart
// 宣言の仕方
List<String> list1 = ['1','2','3'];
var list2 = [1,2,3];

//  値の追加
list2.add(4);
```

## Sets
SetはListと似ていますが、Setは項目を重複できないという特性があります。

```dart
// 宣言の仕方
// かっこの違いに注意
Set<int> sets = {1,2,3,4}
```
## Maps
keyとvalue形式で値を保持する型のこと

```dart
Map<String,String> maps = Map();
maps['banana'] = 'バナナ';
```
rubyでクローラーを作りたい

## 作りたいと思ったきっかけ
仕事上、更新情報やwebページの表記間違いを自動検知して、slackに通知出来たら便利だなあと思いクローラーを作ってみようと思いました。
また、最近、SEO関連の話を聞く事があり、Googleのクローラーを意識するようになった事が主なきっかけです。
長くなりそうなので、今回は、クローラーとは何かという事と大まかな仕組みについてのみ書きます。

[Rubyによるクローラー開発技法 巡回・解析機能の実装と21の運用例](https://www.amazon.co.jp/Ruby%E3%81%AB%E3%82%88%E3%82%8B%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%A9%E3%83%BC%E9%96%8B%E7%99%BA%E6%8A%80%E6%B3%95-%E5%B7%A1%E5%9B%9E%E3%83%BB%E8%A7%A3%E6%9E%90%E6%A9%9F%E8%83%BD%E3%81%AE%E5%AE%9F%E8%A3%85%E3%81%A821%E3%81%AE%E9%81%8B%E7%94%A8%E4%BE%8B-%E4%BD%90%E3%80%85%E6%9C%A8-%E6%8B%93%E9%83%8E/dp/4797380357/ref=sr_1_fkmrnull_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=ruby+%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%A9%E3%83%BC&qid=1554145855&s=books&sr=1-1-fkmrnull)を参考にして地道に勉強していきます。

## クローラーとは
クローラーとは、自動的にwebページを巡回して情報を収集するプログラムの事です。
一番有名なのは、Googleなどの検索エンジンのクローラーだと思いますが、これは自動でwebを巡回し、更新情報などを持ち帰りデータベース化します。
持ち帰ったデータを元にGoogle独自のアルゴリズムでランキングされ、検索結果ページに反映されます。

## クローラーの仕組みを把握しよう
クローラーを作るには、webを巡回し、こちらが指定した条件に引っかかった文字列を取得する仕組みが必要です。
この仕組みを実現するには、htmlのページからString#scanを使用し、条件に指定した文字列を取得すれば実現出来ます。
ここでは、Rubyist Magazineの最新号のタイトルを取得するクローラーを想定して、機能の一部を作っていきましょう。

まず取得対象のRubyst Magazineのトップページを```wget -O ruby_magazine.html https://magazine.rubyist.net/```で```ruby_magazine.html```という名前でローカルに保存してテストします。

今回は、データ取得だけなので問題ないと思いますが、クローラーの中には自動ログインしたり、パラメーターに値を入れて情報を収集するようなものもあります。
テスト状態でこいう事を行うとバグの原因になったりと迷惑をかける事になるので、良く理解するまでローカルもしくは、自分のサーバーでテストします。

では、まずtop_pageという変数にhtmlの中身をopenして入れます。

```rb
top_page = open("rubyist_magazine.html", &:read)
```
トップページの文字列が入ったtop_pageにtop_page.scanとしてテキストマイニングしていきます。
取得したい最新号の記述は下記のようになっています。

```
<ul>
  <li><a href="./articles/prerubykaigi2019/preRubyKaigi2019-index.html">RubyKaigi 2019 直前特集号</a></li>
</ul>
```
このパターンにマッチする正規表現を書き、scanします。

```rb
latest_article = top_page.scan(%r!<ul>\n\s\s<li><a href="(.+?)">(.+?)</a></li>\n</ul>!)
```

正規表現にマッチした部分を出力してみましょう。

```
p latest_article
```

下記のような感じで出力されれば成功です！

```
[["./articles/prerubykaigi2019/preRubyKaigi2019-index.html", "RubyKaigi 2019 直前特集号"]]
```


例えば、こいつを定期的に起動してSlackに最新号を通知したりする事も出来そうですね。
最終目標は、webページ内の間違いやスパムを検知して通知する事ですが、まだよくわからないので、しばらく色々遊んでみよう。

書く事が溜まってきたら、次回も書きます！
#Slack #API を叩いて #jq コマンドで チャンネル名からチャンネルIDを取得する例

```
curl -s "https://slack.com/api/channels.list?token=xoxp-*****************&pretty=1" | jq --raw-output '.channels[] | select(.name == "your_channel") | .id'
```

ref

https://api.slack.com/methods/channels.list/

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1018








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
#Twitter が気になってプログラミングに集中できない人のための #GoogleChrome 拡張

[Block Site - Website Blocker for Chrome™ - Chrome Web Store](https://chrome.google.com/webstore/detail/block-site-website-blocke/eiimnmioipafcokbfikbljfdeojpcgbh/)

# いんすとーるできましたか？

右上から色々できます。UIも良い感じです。

今見ているサイトをブロックできるみたいです。間違ってもGitHubをブロックしてはいけません。

![image](https://user-images.githubusercontent.com/13635059/55295889-6843ce80-544d-11e9-93ce-b466fbce9fee.png)

# 歯車のボタンから設定をしてみましょう。

e.g. facebook.com  と書かれていて笑いを誘います。

![image](https://user-images.githubusercontent.com/13635059/55295754-cff91a00-544b-11e9-8cba-44eec82f410b.png)

# twitter.com を入力しましょう。

![image](https://user-images.githubusercontent.com/13635059/55295755-d1c2dd80-544b-11e9-9eb1-f5ef6243fa3f.png)

# アクセスできません。やったぜ。

![image](https://user-images.githubusercontent.com/13635059/55295756-d2f40a80-544b-11e9-842e-3bdab3cad7a7.png)

# おばあちゃんも喜んでいます。

![image](https://user-images.githubusercontent.com/13635059/55295830-b86e6100-544c-11e9-82ed-a8a3646ae576.png)

# おまえふざけてんのか？と。

![image](https://user-images.githubusercontent.com/13635059/55295878-41859800-544d-11e9-8629-5c6e0a4e345c.png)

# スケジュール機能もあるみたいです。

![image](https://user-images.githubusercontent.com/13635059/55295788-3f6f0980-544c-11e9-9963-94799feca02a.png)

# Work Mode がタイマー機能みたいです。

30分固定なのかな。

![image](https://user-images.githubusercontent.com/13635059/55295781-29614900-544c-11e9-825f-3c48759083c7.png)

![image](https://user-images.githubusercontent.com/13635059/55295852-f4092b00-544c-11e9-8b2e-658a8d0fc22e.png)

# アダルトサイトもブロックしてくれるみたいです。アダルトサイトなんて見たくない僕らにはありがたいですよね。

![image](https://user-images.githubusercontent.com/13635059/55295792-4bf36200-544c-11e9-8c5a-4854b335c02b.png)

# どうしても見たい時はスマホで見ましょう。

え、意味がないって？ いやいや違うんです。PCの大きなディスプレイで無限の注意力を消費するのとは。



# Original by GitHub issue

https://github.com/YumaInaura/YumaInaura/issues/1017








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
CondaでPythonを管理する（パート２）

#環境マネジメント
###新しい環境を追加する
たとえば*my_new_env*という名前の新しい環境を作成するには（Pythonバージョン3.4を含む）、次のように実行する。
`$ conda create --name my_new_env python = 3.4`
パッケージ管理コマンドを使用して、Pythonバージョンの環境を変更できる。

###環境を活動化および非活動化する
新しいCondaのインストールでは、root環境がデフォルトで有効になっているので、アクティブ化しなくても使用できる。それ以外の場合で、環境を使用したい場合（例えば、パッケージを管理したり、その中でPythonスクリプトを実行したりする）、それを活動化する必要がある。
`$ source activate my_new_env`

次のコマンドを使用して、セッション終了後に元のPython環境に戻ります。
`$ source deactivate`

###利用可能な環境を一覧表示する
`$ conda info –envs`
結果の例：

```console
$ conda info –envs
$ 
my_new_env D: \ Miniconda \ envs \ my_new_env 
tensorflow-cpu D: \ Miniconda \ envs \ tensorflow-cpu 
root * D: \ Miniconda
```
このコマンドのおかげで、あなたはあなたのすべての環境（ルートディレクトリとすべての追加の環境）をリストすることができる。アクティブな環境はアスタリスクでマークされている。

###GitHubのコマンド
Gitリポジトリを作成し、作成したファイルをコミットする
`$ git init && git add environment.yml `
`$ git commit -m 'initial commit'`

作成したリポジトリをGithubにプッシュしたい場合は、Githubにリポジトリを作成して次のコマンドを使用する。
`git push -u origin master`

###Condaのバージョンを知る方法
あなたが使っているCondaのバージョンをチェックし、あなたの環境の他のパラメータを知っておくと便利のだ。現在アクティブな環境のCondaバージョンを入手するには、次のコマンドを実行する。
`$　conda --version`

結果の例：

```console
$　conda --version
conda 4.3.33
```
環境情報の詳細なリストを入手するには、次のようにします。

- Condaバージョン
- プラットフォーム（オペレーティングシステムとビット数 -  32または64ビット）
- Pythonのバージョン
- 環境ディレクトリ

このコマンドを実行する。
`$ info conda`
[図解]SwiftでARCのメモリ解放の仕組みを理解するために実施したこと(weak版)

#はじめに
ARCのメモリ解放の仕組みを、インスタンスの参照関係を操作可能なプログラムを作って動作確認を行って実際に確認してみました。
その結果を図解でまとめます。

##関連記事
[[図解]SwiftでARCのメモリ解放の仕組みを理解するために実施したこと(unowned版)](https://qiita.com/sakamotoyuya/items/76b1b792f57ad2d4fff4)
[[図解]SwiftでUIAlertControllerが何故循環参照するのかを理解するために実施したこと](https://qiita.com/sakamotoyuya/items/6914bfd4f885ce7a8733)

#環境
Xcode 10.1
Swift 4.2

##作成したプロジェクト一式
https://github.com/sakamotoyuya/proj1
![スクリーンショット 2019-04-02 2.10.04.png](https://qiita-image-store.s3.amazonaws.com/0/377612/32b9429e-cec4-0873-ae6f-6b7eeec9210a.png)

このプログラムは(1)から(5)のメモリを以下の参照関係となるように作成して、いずれかのメモリをnilにしたとき、ARCのメモリ解放がどう動くのかを確認できるものとなっています。
色々試してみてこんな感じで動いたというのを図解でまとめました。

#参照関係の図
![スクリーンショット 2019-04-02 1.35.23.png](https://qiita-image-store.s3.amazonaws.com/0/377612/035456c4-4d4c-cb1d-99f6-ca1276040c75.png)

#(2)にnilを入れたときのARCの動作
![スクリーンショット 2019-04-02 13.55.49.png](https://qiita-image-store.s3.amazonaws.com/0/377612/f07d7150-e70b-0cec-c811-582811c30a9c.png)
![スクリーンショット 2019-04-02 13.55.55.png](https://qiita-image-store.s3.amazonaws.com/0/377612/61a52e6c-9d4a-dc42-f374-69a5ce785e06.png)
![スクリーンショット 2019-04-02 13.56.01.png](https://qiita-image-store.s3.amazonaws.com/0/377612/6b91f32e-1dbc-7a7b-8921-f3f36329b635.png)
![スクリーンショット 2019-04-02 13.56.06.png](https://qiita-image-store.s3.amazonaws.com/0/377612/7d2911d4-82da-cd1c-1a74-a25fa26a2505.png)

#(3)にnilを入れた時のARCの動作
![スクリーンショット 2019-04-02 13.56.11.png](https://qiita-image-store.s3.amazonaws.com/0/377612/c7d2dff5-2be4-d760-1e98-a26353270f65.png)
![スクリーンショット 2019-04-02 13.56.17.png](https://qiita-image-store.s3.amazonaws.com/0/377612/6f4e4bfe-c05d-a57c-f069-011a8efe4b21.png)
![スクリーンショット 2019-04-02 13.56.23.png](https://qiita-image-store.s3.amazonaws.com/0/377612/02e824fa-d098-4e69-6ee9-e899d32e851a.png)

#(1)にnilを入れた時のARCの動作
![スクリーンショット 2019-04-02 13.56.28.png](https://qiita-image-store.s3.amazonaws.com/0/377612/7f95adc8-27dd-445c-7d56-a568e9ba61ed.png)
![スクリーンショット 2019-04-02 13.56.37.png](https://qiita-image-store.s3.amazonaws.com/0/377612/01115436-6f18-0d02-1e56-a6bcf6f06add.png)
![スクリーンショット 2019-04-02 13.56.42.png](https://qiita-image-store.s3.amazonaws.com/0/377612/be9475d7-7845-1869-d287-0e99f2538a64.png)
![スクリーンショット 2019-04-02 13.56.47.png](https://qiita-image-store.s3.amazonaws.com/0/377612/56f8d6db-3074-f196-2f52-5b1cd7edfeac.png)
![スクリーンショット 2019-04-02 13.56.53.png](https://qiita-image-store.s3.amazonaws.com/0/377612/549c7f4f-9f61-4fc7-ab27-37ffc720fa21.png)
![スクリーンショット 2019-04-02 13.57.00.png](https://qiita-image-store.s3.amazonaws.com/0/377612/7ea2aa58-7ea1-a594-27df-60991fc1bd3c.png)


#ここまでやってみて
メモリをnilにしたからといってメモリが解放されないことがあるということが明確にわかりました。
今回の実験ではweakを含めた参照関係を作成して、ARCによるメモリ解放の流れを確認しました。[次回](https://qiita.com/sakamotoyuya/items/76b1b792f57ad2d4fff4)はweak箇所をunownedに変えたらどうなるのか実験してみたいと思います。
sed コマンドで複数の条件-e, -E, -r(拡張正規表現)を指定する方法

`sed` で複数の条件を指定したいときの方法。

`-E`, `-r`（拡張正規表現）を指定したときに `-e` と同じようにオプションをつなげていくと、
`sed: -E: No such file or directory` となったのでメモ。

:information_source: Mac 標準の BSD sed, Homebrew で入れた gnu-sed 4.7 に基づきます。

# `-e` オプション

```shell
$ sed -e 's/aaa/bbb/g' -e 's/ccc/ddd/g' -e 's/eee/fff/g'
```
つなげでいくだけ。

```shell
$ sed -e 's/aaa/bbb/g; s/ccc/ddd/g; s/eee/fff/g'
```
`;` で区切っても良い。

# `-E`, `-r`（拡張正規表現）オプション

```shell
$ sed -E 's/aaa/bbb/g; s/ccc/ddd/g; s/eee/fff/g'
```
`;` で区切らないとダメ。

# 参考文献
https://stackoverflow.com/questions/26568952/how-to-replace-multiple-patterns-at-once-with-sed
私は git rebase -i あなたの履歴を守ります

# 

c.txt と d.txt を一緒にcommitしちゃってる！
分けたい！分けたい！（大事なことなので2回言いました)

```shell-session
❯ git log
commit 3320bf4a4c8d7165e30282cdcd6795602d00bdc3 (HEAD -> master)
Author: yamazoon <xxxx@gmail.com>
Date:   Tue Apr 2 02:06:54 2019 +0900

    add b.txt & c.txt

commit d5f820d0fd366702fa388ebad947b76f9c7ed1b1
Author: yamazoon <xxxx@gmail.com>
Date:   Tue Apr 2 02:06:32 2019 +0900

    add b.txt

commit 540edae6ace436c9c1817afd5d549fc422a5d34d
Author: yamazoon <xxxx@gmail.com>
Date:   Tue Apr 2 02:06:25 2019 +0900

    add a.txt


```
<br>
私は、git rebase -i 
あなたの履歴を守ります  (HEAD~1で直近のコミット履歴を編集します)

```shell
❯ git rebase -i HEAD~1
```
<br>
エディタ上で先頭のpickをeditに変えて保存します

*before*

```vim

pick bbaedb1 add c.txt & d.txt

# Rebase 76a09a7..bbaedb1 onto 76a09a7 (1 command)
# 〜略〜
```

*after*

```vim

edit bbaedb1 add c.txt & d.txt

# Rebase 76a09a7..bbaedb1 onto 76a09a7 (1 command)
# 〜略〜
```

<br>
1つ前のコミットに戻します(zshなので^を¥でエスケープしています)

```shell
❯ git reset HEAD\^
```
<br>
Untrackedになっています

```
❯ git status
interactive rebase in progress; onto d5f820d
Last command done (1 command done):
   edit 3320bf4 add b.txt & c.txt
No commands remaining.
You are currently editing a commit while rebasing branch 'master' on 'd5f820d'.
  (use "git commit --amend" to amend the current commit)
  (use "git rebase --continue" once you are satisfied with your changes)

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	c.txt
	d.txt

nothing added to commit but untracked files present (use "git add" to track)

```
<br>
1つずつコミットします (c.txt)

```
❯ git add c.txt
❯ git commit c.txt -m "add c.txt"
```

<br>
1つずつコミットします (d.txt)

```
❯ git add d.txt
❯ git commit d.txt -m "add d.txt"
```

<br>
git rebase -i を終了します

```shell_session
❯ git rebase --continue
Successfully rebased and updated refs/heads/master.
```
<br>

```shell-session
❯ git log
commit 0478f9e80bc4f4a11683ef9e1271f2dda0f56cbf (HEAD -> master)
Author: yamazoon <xxxx@gmail.com>
Date:   Tue Apr 2 02:27:43 2019 +0900

    d
commit 3320bf4a4c8d7165e30282cdcd6795602d00bdc3 (HEAD -> master)
Author: yamazoon <xxxx@gmail.com>
Date:   Tue Apr 2 02:06:54 2019 +0900

    add b.txt & c.txt

commit d5f820d0fd366702fa388ebad947b76f9c7ed1b1
Author: yamazoon <xxxx@gmail.com>
Date:   Tue Apr 2 02:06:32 2019 +0900

    add b.txt

commit 540edae6ace436c9c1817afd5d549fc422a5d34d
Author: yamazoon <xxxx@gmail.com>
Date:   Tue Apr 2 02:06:25 2019 +0900

    add a.txt


```



<br>
reflogすると、履歴の編集を(start)と(finish)の間に書いてくれています

```
❯ git reflog
21d9934 (HEAD -> master) HEAD@{0}: rebase -i (finish): returning to refs/heads/master
21d9934 (HEAD -> master) HEAD@{1}: commit: add d.txt
3a322e7 HEAD@{2}: commit: add c.txt
d5f820d HEAD@{3}: reset: moving to HEAD^
3320bf4 HEAD@{4}: rebase -i: fast-forward
d5f820d HEAD@{5}: rebase -i (start): checkout HEAD~1
3320bf4 HEAD@{6}: commit: add b.txt & c.txt
d5f820d HEAD@{7}: commit: add b.txt
540edae HEAD@{8}: commit (initial): add a.txt
```

疲れたので一旦おしまい
<br>
補足：もちろん、git logも 「add c.txt」 と 「add d.txt」で分かれてコミットされています
今年は令和何年.com を作った: AMP + Route 53 + CloudFront + S3

## TL; DR

- [今年は令和何年.com](https://xn--v9ju72gjc6vj9sx3pea.com/) を作った
- 4月1日21時位から作って25:30頃完成したので4時間半くらいかかった
- AMP対応のペライチHTMLと画像を S3 に置いて、CF でキャッシュしつつ HTTP/2 で待ち受け、 Route 53 のエイリアスを使って apexドメインで Aレコードとして CF のIPアドレスを返す


## はじめに

需要がありそうだったら各手順をもう少し詳細にまとめようかなと思っていますが、一旦今日は大まかに触れるくらいにしています。

眠い目をこすりながら書いているので、厳密さに欠けたり誤りがある可能性があります。お気づきの方は編集リクエストかコメントでお知らせ頂けると幸いです。 :bow: 

## [AMP](https://www.ampproject.org/ja/)

これはあらかじめ表示できる要素を限定したり、特定のタグの使用を強制することで表示を早くできるようにする技術です。例えば、`a` タグは `target="_blank"` 以外には使用不可だったり、画像の表示には `img` タグではなく [`amp-img`](https://www.ampproject.org/ja/docs/reference/components/amp-img) を使うといった制約があります。

ただ、これ以外にも他にもたくさんの技術が組み合わさってAMPが成り立っています。詳しくは[AMP Start](https://www.ampstart.com/)が参考になります。

## [HTTP/2](https://www.nic.ad.jp/ja/newsletter/No68/NL68_0800.pdf)

これはサーバとクライアント間でファイルの送受信毎に接続を繋がないで1つの接続を使い回す（並列で利用する）ことにより、無駄な通信をカットして早く表示できるようにする仕組みです。

他にも要件として[接続のプロトコルがhttpは許容されない](https://ssl.sakura.ad.jp/column/http2/)等いろいろあります。

実際にどれくらい速さが変わるのか、デモを見られるサイトがあるので紹介します。
[http://www.http2demo.io/](http://www.http2demo.io/)

## SSL/TLS証明書の利用

証明書の利用により、通信を全て暗号化しています。これにより、通信経路上の第三者に通信内容を盗聴される危険性を大幅に減らし、仮に通信内容を改竄された時に、そのことが検知できるようになっています。

ペライチのページにそこまでは正直オーバースペック気味ですが、前述のHTTP/2の恩恵を受けるためには必須です。

証明書は [ACM](https://console.aws.amazon.com/acm/home?region=us-east-1) を使用して無料で発行してもらいました。特に証明書の発行維持にはお金はかからないのですが、[CF に紐付けるのなら `us-east-1` で作らないとダメ](https://qiita.com/tearoom6/items/750aac4276ba4d8334b6#acm-%E3%81%A7%E8%A8%BC%E6%98%8E%E6%9B%B8%E7%99%BA%E8%A1%8C)なので注意が必要です。

## サーバレス

前述の通りサーバを持たず、配信は CF + S3 で行っています。

任意のDNSで CNAME を設定することで、CloudFront に独自ドメインを設定することができます。つまり、一般的なDNSサーバを使用すると [www.example.com](http://www.example.com) や [https://test.example.com](https://test.example.com) にアクセスされた時、 CF に到達することができます。

しかし、 CNAME を apexドメイン（www.等のサブドメインが付かないドメイン）に設定することが RFC 上できません。つまり、 [example.com](http://example.com) や [https://example.com](https://example.com) には CF を設置することができません。

ところが、Route 53 は独自の「[エイリアス](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/resource-record-sets-values-alias.html)」という機能を持っており、これを使うと apex ドメインに対し、 CloudFront, ELB 等を A レコードのように設定することができます。これにより、従来は CNAME を設定できないはずの apex ドメインにおいて CloudFront による待ち受けを実現しています。

## IPv6

これは CF を使っていることと Route 53 を使っていることで簡単に実現できたので、おまけ程度に有効化しました。

手順は単純で、 CF の設定項目で `General` -> `IPv6`: `Enabled` にして、Route 53 で AAAA レコードをエイリアスで作成するだけです。

動作の確認をするIPv6環境が手元にないのでテストしていませんが、おそらく動くのでは無いかと思います。

## おわりに

ここまでご覧いただきありがとうございました。この記事のどこか一部でも参考になれば幸いです。
参考になったらページ左側の「いいね」ボタンを押したり、 [今年は令和何年.com](https://xn--v9ju72gjc6vj9sx3pea.com/) をツイートしていただけると励みになります :pray:

本記事中で何かあれば、編集リクエスト、コメント欄、[TwitterのDM](https://twitter.com/dogwood008)、[ここ](https://qiita.com/dogwood008)に記載のメールアドレスまでお願いします。
8ヶ月の長期インターンを終えて

# 休学からインターン終了まで
3月を持って長期インターンを終了しました。
とてもとても濃い時間だったなと終わってからしみじみ感じております。
そんな中で、インターンを通じて学んだことを順番に説明していきます。
## 4月〜7月
僕は前期を休学して4月に色彩検定３級をなんとなく取ったのち、5月ごろから[RainbowApps](https://www.school.rainbowapps.com/)に２ヶ月間通っていました。講義ペースは２週に１回ほど。その後に先月まで働いていたインターン先でモバイルアプリエンジニアとしてインターンを始めました。
セミナーでは主にStoryboardを使って一つのアプリを完成させていくというものでした。そのため初日にStoryboardは基本使わないと言われた時は「終わったー」と思いました笑
あえてインターン生が誰もいないところを選んだのですが、この時は同期のインターン生がいてくれればと思ったこともありました。
## 7月〜9月
7月から9月にかけてGithubで投稿されていた[iOS Training](https://github.com/mixi-inc/iOSTraining)を扱いながら勉強していました。同時にGitの扱い方も勉強していきました。
インターン先では口頭質問ではなくSlack(最初はChatworkでした)上で会話をすることが基本です。そのため最初は横にメンターの方がいてもチャット上で質問することにかなり違和感がありました。また、質問をしても返答がないことがしばしば。そこで分からないことがあった時は質問をするのではなくてググるのを先にする習慣をつけなさいと学びました。この頃は休学中だったため週４の８時間とかで働かさせてもらっていたと思います。

## 9月〜10月
夏に学んだことを生かしていざ実践！といきたかったのですが、TableViewのセルを押したら画面遷移したり、モーダルの出力方法であったり、Gitが毎回コンフリクトしたりとまだまだ1行1行他人に説明できるほど理解できておらず、できたら違うことを忘れてをひたすら繰り返していました。この頃は学校が始まり、また留年するわけにも行かなかったので週２〜３の４〜８時間働かさせてもらっていました。

## 10月〜3月
この頃からインターン先の自社アプリのタスクをやらしていただくようになりました。タスク内容は簡単なものからまったく手が出ないもののありました。画像やアプリ名のタイトルを変更してcommitするものや、シェアに情報をJSONから出力させるようなものなどです。中には１週間ほぼ手をつけられずひたすらググって試してエラー出てを繰り返していたりしました。
とても申し訳なかったのですが、学校が始まると同時に勉強時間が夏と比べると全く取れなくなっていて、ただインターンにいくだけになってしまっていた時期もありました。
年を越した辺りからわかることが増えていき、一度やることを言語化をして箇条書きにするとすぐにわかったりするようになりました。

これらがインターン先で行なっていた主なことです。
次にインターン先で行なっていた1ON1の内容です。

# 1ON1
1ON1とは週に１回メンターの方と１対１で話す時間のことです。
時間が合わずあまりできなかった時期もありましたが、この時間が僕にとってはとてもかけがえのないものだったなと思います。
以下1ON1の内容です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/311344/bbc52336-4a06-557c-0086-e0c457f3d392.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311344/cf1bf816-5f94-1a1e-fe31-36691c48674c.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311344/acf5093a-f332-0b6c-66cb-a95766aa14aa.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311344/77282dd2-2516-77c2-26fc-15bf527b6c8e.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311344/eff4c0b9-c5f7-c2f1-a819-78bf9f790c9d.png)

見返してみて改めて思ったことは本当にGitには苦戦したなーということです笑
言語化する力、時間を見極める力、調べる力、設計力や実装力以外にも多くのことを学ばさせていただきました。

# 最後に
3月に指摘していただいたことの中から印象的に残っていてメモしていたものを箇条書きにしました。

- 影響範囲やエビデンスなどをちゃんと記載する
- 相手の目線で文章を書いた方が良い。特に主語が抜けているので気をつけた方が良い。
- ロジックとかは間違えても経験の浅いうちはスキル不足なのはわかっているから、怒られたり評価が極端に下がることはないと思うが、適切な言葉を使えていなかったり、消し忘れとかコーディングスタイル（いわゆるマナー）ができていないのは多分どこ行っても怒られるか、評価が下げられると思う

後半タスクをこなしていくごとに気の緩みが生まれてご迷惑をおかけした時に教えてもらったことです。
ただのインターン生にここまで真剣に将来自分がエンジニアとして働いていくことを考えて教えてくれたことに感謝しかありません。

インターン先のエンジニアの方々は常に勉強をしていたり、インプットアウトプットを実践していたりしてとても刺激になりました。もし今エンジニアでインターンをするか悩んでいる方がいたら絶対挑戦した方がいいと思います！ネットやSNSにある情報よりも肌で感じた方が絶対にいいと思います。

就職活動をしていく中でサーバーサイドやウェブを勉強してみたいと思ったため、Swiftは個人で勉強を進めていこうと考えています。
これからも精進します。読んでいただきありがとうございました。
UE4でAndroid向けビルドを行うとrungradle.batでエラーが出る問題

#環境
Windows10
UE4.21.2


#現象
こちらと同様です
https://answers.unrealengine.com/questions/720605/android-packaging-build-fail-ue-418.html
私の場合はOculusGoのビルド環境を整えていた時にこの現象に遭遇しました


    LogPlayLevel: Error: ERROR: cmd.exe failed with args /c "C:\UE4_Prj\TestVR\Intermediate/Android/APK\gradle\rungradle.bat" :app:assembleDebug

いろいろ調べて解決方法はブログでまとめられている方がいらっしゃいましたが、断片的になってしまっておりまとめている人がいなかったので備忘録的にまとめておきます


↑のAnswerHub通りに


    1. run NVPACK/android-sdk-windows/tools/android.bat

    2. click on "Deselect All"

    3. update Extras/Android Support Repository

を行っても解決しない！なぜだ！

という現象が発生します

### Ant使えばBuildできちゃう
一応
Project Setting > Android > Enable Gradle instead of Ant
のチェックを外すとビルドは成功できちゃいます

![enableGradle.PNG](https://qiita-image-store.s3.amazonaws.com/0/138731/f5d72c2b-b4c5-65bf-4218-21112e035085.png)

しかし、これは根本的な解決になっておらず単純にGradleを使わずにAntでビルドしちゃいましょうという話なのでそれはちょっと・・・という感じなのでこれはダメ

#原因と解決方法
原因はGoogleがライセンスを更新したのですが、その対応がUE4.21では間に合っていないことらしいです

なので

1. [こちらのpackage.xml](https://github.com/EpicGames/UnrealEngine/blob/4.22/Engine/Source/ThirdParty/Android/package.xml)から中身をコピーする
2. Engine/Source/ThirdParty/Android/package.xml にコピーした内容を上書き
3. プロジェクトを立ち上げ「Project Setting > Android > Accept SDK License ボタンを押す

これで無事ビルドできました
詳細なことは↓のepic gamesのおかずさんのブログで解説してくれているので目を通しておくといいと思います

### 追記  
1のリンクが404になる場合があるようです
このリンクを開くにはGithubアカウントをEpicGamesのUnealEngineリポジトリを開けるようにする必要があります
その方法は以下のリンクを参照してください
[公式ドキュメント-GitHubとは？](https://www.unrealengine.com/ja/ue4-on-github?sessionInvalidated=true)

#参考
http://pafuhana1213.hatenablog.com/entry/2019/02/06/010250
【Unity(C#)】GVRのコントローラーに操作説明を表示する

##GVRとは？
Google VRという、iOSおよびAndroid用にGoogleが開発しているVRのSDKです。

[コントローラーの入力](https://qiita.com/OKsaiyowa/items/f0bcaf90adc1bc35f6b9)に引き続き、忘れないうちにまとめておきます。

##コントローラーの操作説明
![SampleController.png](https://qiita-image-store.s3.amazonaws.com/0/244071/702e998c-271d-2729-001f-ad8d13afd943.png)
画像のように操作説明が表示される機能のテンプレが最初からありました。
二つPrefabが用意されていました。(さすがですGoogleさん)

`GoogleVR`-`Prefabs`-`Controller`-`Tooltips`の中の
**GvrControllerTooltipsSimple**と**GvrControllerTooltipsTemplate**です。


##使い方
`GvrControllerTooltipsSimple`と`GvrControllerTooltipsTemplate`のどちらか使いたい方を
Prefabから引っ張ってきた`ControllerPointer`の下の階層にある
`ControllerVisual`の子にします。


これだけでも表示されますが、デフォルトの設定で
`GvrControllerTooltipsSimple`がInstanciateされてしまうので
二重で説明文が表示されてしまいます。

なので、Instanciateしている箇所をコメントアウトしておきます。

```C#:GvrControllerVisual
   void Awake()
    {
        Initialize();
        //CreateAttachments();
    }
```

これで準備はOKです。
後は使いたいPrefabに応じて設定していきます。

##GvrControllerTooltipsSimple
![TooltipsPreview.png](https://qiita-image-store.s3.amazonaws.com/0/244071/e39eccea-41f3-23ee-65fd-cd3a16c932cc.png)
`GvrControllerTooltipsSimple`はシンプルに、
上の画像のようなオブジェクトが表示される仕組みです。

表示を変えたい場合はMaterialのTextureを変更すればいけました。

独自のデザインをPhotoShop等で頑張るのであれば
`GvrControllerTooltipsSimple`を利用するといいと思います。

##GvrControllerTooltipsTemplate

![TemplePrefabPreview.png](https://qiita-image-store.s3.amazonaws.com/0/244071/13f749dd-bc40-fbcc-b3cf-9262ec3549d1.png)
デフォルトはこのようなビジュアルです。

![TemplePrefab.png](https://qiita-image-store.s3.amazonaws.com/0/244071/da9461f8-ada8-131e-760a-d974a7d49ea1.png)
こんな感じでUIがCanvas上に表示されているような形なので
Editor上でカスタマイズできます。

**テキストのフォントサイズを変更すると、背景のパネルの大きさも勝手に変わります。**
(地味だけどめっちゃ便利↑)
なので、フォントサイズと色を変えるだけでそれなりに満足のいくクオリティーで使えます。

デフォルトで用意されているのは、Homeボタン(Daydreamボタン)以外なので、
Homeボタン(Daydreamボタン)に説明を加えたい場合は、
`Canvas`の一つ下の階層にある`Gvr Tooltip`の`Location`を`Custom`にします。

![GvrTooltip.png](https://qiita-image-store.s3.amazonaws.com/0/244071/95173fd4-8a82-5b99-d3b3-116ca751428f.png)

これでそれぞれの説明文のゲームオブジェクトを好きなTransformに変更できるようになります。

また、コントローラーの説明文は特定の範囲内に入ると表示されるようになっていますが、
`Always Visible`にチェックを入れると
常に表示されるようになります。

---
Daydreamあんま人気無いっぽいですね...
Daydreamに幸あれ...
Capybara の e2e テストで Chrome が Selenium::WebDriver::Error でたまにクラッシュする

# 問題

Capybara と Headless Chrome で e2e テストを走らせてる時、以下のような例外が**たまに**起きて困っていた。CIとかVMで走らせてる時に起きがちだった。

```
Selenium::WebDriver::Error::UnknownError:
  unknown error: session deleted because of page crash
  from unknown error: cannot determine loading status
  from tab crashed
```

こんなんとか

```
Selenium::WebDriver::Error::NoSuchDriverError:
  invalid session id
```

こんなん。

# 解決策(対症療法だけど)

同じ問題になってる方がいた。 [Selenium::WebDriver::Error::NoSuchDriverError - Today I Learned](https://selleo.com/til/posts/mxkjoppuxm-seleniumwebdrivererrornosuchdrivererror)

> Finally, after spotting [this comment](https://bugs.chromium.org/p/chromedriver/issues/detail?id=1884#c13) we’ve reduced chrome window size from `1920,1200` to `1440,900` and the problem is no longer present.

「テストに使うブラウザのサイズを小さくしたら起きなくなった」とのこと。上記のリンクを辿って Chromium のバグリポート読むと、原因不明だけどメモリーが切れ気味になると起こる、みたいな報告がいくつか。[Issue 1884: headless : session deleted because of page crash](https://bugs.chromium.org/p/chromedriver/issues/detail?id=1884)

じゃあそうしてみよう。このあたりを参考に

- [Capybara.register_driver](https://www.rubydoc.info/github/jnicklas/capybara/Capybara.register_driver)
- [Capybara::Selenium::Driver#initialize](https://www.rubydoc.info/github/teamcapybara/capybara/master/Capybara/Selenium/Driver#initialize-instance_method)
- [Selenium::WebDriver::Chrome::Options#add_argument](https://seleniumhq.github.io/selenium/docs/api/rb/Selenium/WebDriver/Chrome/Options.html#add_argument-instance_method)
- [List of Chromium Command Line Switches - Peter Beverloo](https://peter.sh/experiments/chromium-command-line-switches/)
    - Chromium の開発されてる方のページ。個人サイトっぽいが[公式からもここにリンクしてたので公式ドキュメント扱いなのだろう](https://www.chromium.org/developers/how-tos/run-chromium-with-flags)

```config/capybara.rb
Capybara.register_driver :selenium_chrome do |app|
  options = Selenium::WebDriver::Chrome::Options.new
  options.add_argument('headless')
  options.add_argument('window-size=1440,990')
  Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end
```

で、なんとなく起きなくなった。また起きたらもうちょっとウィンドウサイズを小さくしよう。


TODO: 根本解決の方法がわかったら更新する。

# 追記(結論)

CIのスペックをあげるのが正解だと思う。メモリ盛ると起こらないです。
なぜ日本のソフトウェア開発の生産性が低いのか？

# 一般的には
よく言われてるのが、SIerの存在。自社ソフト開発がメインのアメリカに対して、SIerに任せるから、アジャイルみたいなことがやりづらい。だから問題だと。
これが一番よく言われている理由で、確かに大きな理由の一つだと思う。

# 几帳面な日本人

今回言いたかったこと。

**日本人は几帳面で、単純作業を間違いなく、綺麗にこなす。**

これは5ヶ国くらいの人とこの業界で話してて間違いないと思ってるし、アメリカに住んでた人もあの人たちは折り紙さえ折れないとよく言ってる。
ただこの几帳面さという一見強みであるこの特性がソフトウェア開発の現場では生産性の問題を引き起こしている。

例えば、コードコンプリートに書いていた自動テストをやる理由に、「手動テストは50％、操作ミス等による間違いが発生する。」
と書いてある。

？

これは有り得ない、一般的なSIerとして活動している日本人にとっては。
特に優秀だとされる開発会社の人たちはそれはもうかなりの精度で手動テストを行うし確証も取っている。それでもたまに漏れや考え違いがあり、90％以上の正確さはあると思う。

これがいけない。

さっき書いた折り紙の話のように日本人以外は90%以上の品質を確保するためには、コンピュータに任せるしかないのだ。どうやっても。一方で日本人は、目の前に起きた自分の作業が一番正しいと思えてしまうし、ほとんどの場合、正解だったりする。だから自動テストのメリットが弱い。

これはテストだけの話ではない。
リリース作業や、システム化など、全てにおいて、ソフトウェア作るくらいなら、マニュアル作業のクオリティを上げてやる、という職人気質？几帳面さがもたらす、ソフトウェア開発らしからぬ発想。

几帳面が悪いわけじゃないし、プラスに働く仕事もいっぱいあると思う。日本人の誇れる特性だとも思う。
例えば、一発で決めなくちゃいけないビジネス以外のスポーツなどの分野であれば、この特性はいいほうに転がると思う。

だけどソフトウェア開発はコンピュータに作業を振る仕事だ。人にやらせるための仕事じゃない。
実際のところ、この部分は開発者だけでなく、直接のユーザーやエンドユーザーについても言える。完璧を求めてしまうのだ。少しでも字がずれてたら？色がダサかったから？特定の操作でうまく動かなかったから？いろんな部分で、几帳面さを発揮し、指摘が入り、下手したらインシデントとして処理されてしまう。
これも昔みたいにコンピューターのリソースが足りず、テスト自動化ができなかった時代ならよかった。ハードウェアの性能がアップすることで、すべてをコンピューターに任せ、最初から完璧さを作らず求めず、言われたときにどんどん直していく手段をとっていたソフトウェア先進国は、最小の工数で日本の匠以上のユーザインタフェースを作りこめるテクニック、サービスを作り上げてしまった。

こんな状況で、ソフトウェア先進国と戦おうと思ったら、少し頭を切り替えて、コンピュータにもっと仕事を振ってあげません？そこで初めて、日本人の几帳面さが世界と戦える強みとして花開くのではないでしょうか？
人の気持ちとかいう意味わからんものが一切ないプログラミングという世界

寝る前にふとエンジニア、プログラマーという仕事について思ったことがあるので、書いてます。

僕は新卒で入った不動産デベロッパーでマンション販売の営業をしていましたが、今はそこから回り回ってWeb系のエンジニアをしてます。

で今の仕事と営業を比べて思うことを素直に書こうと思います。

営業っぽい仕事をしている人で、プログラミングとか興味あるひとは読んだらいいかもしれないっす。

##むずかった営業
まず営業職を否定するつもりはありませんし、実際結構稼げると思ってて、めっちゃ価値がある汎用性の高い仕事、今度価値がもっと上がっていく仕事だと思ってます。

が僕は自分なりにまーまー頑張った割に期待した成果は出なかった。

今思うと運もあったかもしれないし、センスが無かっただけかもしれない。
営業で接客がうまくいず、なぜ失敗したのか考えても、正解なんて分からない。
もう「自分だったらどう思うか？」て予想するしかない時がある。

そして、その自分の思考が一般的な人とずれてるとその予想がもう当たらない当たらない。笑
「人の気持ちとか知らんし！」って何回も思ったが、それでもひたすらトライアンドエラーするしかなかった。

##なぜ努力が報われない？！
まずその頃思ってたことは、高校までやってたサッカーや、学生の頃やった受験や資格の勉強では努力に対してリターンがほぼ確実にあったのに、営業ではそれがない、おかしい！ってこと。

シンプルに努力量が足りなかったかもしれんが、1番は人の気持ちがあまりわからない、人の気持ちに敏感でない僕は結局、多くのお客さんの気持ちが分かってなかったんだと思う。
※僕はコミュ障ではなく、けっこう普通にコミュニケーションとれます。笑

まーこのへんの人の気持ちがわかるわからない、敏感であるそうでないってのは結局向き不向きが確実にあり、
その差が顕著に出るのが営業かなと思っている。
言い訳みたいになってしまうが。

##エンジニア、プログラマーってシンプル〜
一方、エンジニアとして働いていて、プログラミングをしている時にも、もちろんうまくいかないことがある。
エラーに出くわしたりとか。

そしてそのときプログラミングには理論的な原因や解決するための答えが必ずある。
気分でプログラムが動くことなんて100ぱーありえない。

正直、**この理論的な世界**はなんて素晴らしいんだと思う。

もう**訳のわからんお客さんの気持ち**とかいうものを理解するより、楽すぎる。楽すぎてうける。

もちろんエラー出て詰まるとストレス溜まるが、かならず原因があるし、粘り強くやれば正解までたどり着ける。

##つくりたいものつくれるって素敵
またエンジニア、プログラマーは何か作りたいものを自分で形にできる技術がある。
僕はものづくりがすきなので、
故にとても素晴らしい職業だと思っている。

##プログラミングおすすめ！
ということで、
試験や受験が得意な人、
ある程度理論的な思考ができるかなーという人、
コミュ力に自信ない人、
お客さんの気持ちとか考えるの面倒て人、
プログラミングやってみるのがいいと思う。

普通に楽しいから。

どっちもできそうだけど、確実に成果を出したいって人はこっちを選んだらいいと思う。
なぜなら、社会人として一番見られる結果・成果へのプロセスに**人の気持ち**という不確実性、運要素、を含むものがほとんどなくて、シンプルだから。

マネージメントになってくるとこの要素は薄くなるかもしれないが。

あ、仕事する上で必要になる最低限のコミュニケーションはエンジニア、プログラマーでも、もちろん必要です！
19日目: Cross-Subject Transfer Learning in Human Activity Recognition Systems using Generative Adversarial Networks

# Cross-Subject Transfer Learning in Human Activity Recognition Systems using Generative Adversarial Networks 要約
## 読んだ論文
Cross-Subject Transfer Learning in Human Activity Recognition Systems using Generative Adversarial Networks
Elnaz Soleimania, Ehsan Nazerfard
https://arxiv.org/abs/1903.12489v1

上記の論文を読んだので簡単にまとめます．まだプレプリントのみ？の様子．

## 3行でまとめる
- 行動認識系研究では，事前に訓練したモデルを新規ユーザに対しては制度が大幅に下る．
- 一方，新規ユーザに対してラベル付きデータを獲得することは不可能であるらしい．
- ユーザ適応を行うSubject Adapter GAN（SA-GAN）を提案する．


## 提案手法
### 提案モデルと損失関数
![20190401_001.png](https://qiita-image-store.s3.amazonaws.com/0/376859/4dbfccb3-2148-526b-314f-141d2205d5dd.png)

　前提として不特定多数ユーザのデータがラベル付きで与えられていて（ソースドメイン$D_s$），新規ユーザがラベル無しで与えられている（ターゲットドメイン$D_t$）こととする．
　提案手法はFigure1の通り，Generatorはソースドメインの$X_s$から$X_{fake}$を生成し，Discriminatorがこれを弁別する（$X_t,X_{fake}$を見分ける）．このとき識別率が50％になることが望ましい（一般的なGANと同じ）．Classifierはソースドメインのデータを元に分類器を訓練するが，$(X_s, Y_s)$の組み合わせと$(X_{fake}, Y_s)$の組み合わせ両方を，損失関数$V_{cls}$で訓練する．
　$V_{cls}(G, C)=E_{x_s,y_s}\[-y_s\log(C(G(x_s)))-y_s\log(C(x_s))\]$
最終的に全体の損失関数は次式で定義される．
　$\min_{G,C}\max_{D}\lambda_{adv}V_{adv}(D,G)+\lambda_{cls}V_{cls}(G,C)$

### 訓練方法
以下，Algorithm1を要約する．
1. $X_s,y_s,X_t$からmサンプルずつランダムにミニバッチとして選択する．
2. 同様にm個のノイズ$\\{z^{(1)},...z^{(m)}\\}$を決定する．
3. 確率的勾配効果法でDを訓練する．
4. 同様にCを訓練する．
5. 同様にGを訓練する．
6. これをミニバッチ分＊イテレーション数分繰り返す．

結果はよくなったよという話だけなので省略する．

## まとめ
- 行動認識の新規ユーザ適応問題においてGANベースの手法を提案した．

## 所管
　読了に１時間半くらい．前々回は行動認識のユーザ適応，前回はデータセット間転移，今回はまたユーザ適応の話．ただ，新規ユーザを不特定モデルに適応するのではなく，不特定ユーザたちを新規ユーザに適応するエキサイティングなアプローチでした．
　気になる点はいくつかあって，まず一つは本手法だと新規利用者が来るたびにモデルを作って学習から始めなければならない点である．不特定ユーザたちを適応させているのが難点というところ．もう一点は，今回結果的にうまく働いたものの，学習手法の一部に疑義ありという点である．この手法だと$X_s$を$X_t$に変換するようにGを学習しているが，これはあくまで$X_t$っぽいかどうかという点のみを考慮するため，$(X_{fake},y_s)$で学習する際に$y_s$が正しいことは保証されないという点である．まぁこれは$X_t$が教師なしだから仕方がないのかもしれないが，何ともふんわりした仕様という気持ちが漂う．
過去に元号に使われた漢字の使用回数を数えてみた

新元号は「令和」に決まったようですが、令和の［和」の字は昭和にも使われています。考えてみると元号に何度も登場する漢字とほとんど登場しない感じがある筈です。せっかくなので、大化以降のすべての元号に使われている漢字を取得して、登場回数ランキングを作ってみたいと思います。

元号はwikipediaの表にあるものをExcelにコピペして使用しました。
https://ja.wikipedia.org/wiki/%E5%85%83%E5%8F%B7%E4%B8%80%E8%A6%A7_(%E6%97%A5%E6%9C%AC)
wikipedia.xlsxとして保存したExcelファイルを読みこんでみます。

```python
import os
import pandas as pd

df = pd.read_excel('./wikipedia.xlsx')
df2 = df.iloc[1:,:]
df2.columns = df.columns + df.iloc[0,:]
df2
```
<img src="https://qiita-image-store.s3.amazonaws.com/0/277233/832e20cf-ac12-36c7-fd45-642fbd40ee7f.png">
コピペしただけなのであちこちに隙間が残っていて欠損値になりますが、今回必要なのは漢字表記された元号だけですから構いません。欠損値を除去して元号だけ取り出します。

```python:python
era_name = df2['元号名漢字'].dropna()
era_name = [each for each in era_name if each != '－']
print(len(era_name))
era_name[:5]
```
```python:out
248
['大化', '白雉', '朱鳥', '大宝', '慶雲']
```
大化の改新以降、248の元号があったようです。昔は災害とかある度に改元していたので変更頻度が高かった事も原因しているかもしれません。

```python:python
era_name_letters = [[letter for letter in each] for each in era_name]

letters = []
for s in era_name_letters:
    letters.extend(s)

print(len(letters))
letters[:5]
```
```python:out
506
['大', '化', '白', '雉', '朱']
```
重複含めて506文字の漢字が得られました。では数えていきましょう。登場回数ごとの漢字一覧を作成します。

```python:python
from collections import Counter
c = pd.Series(Counter(letters)).sort_values(ascending=False)
index = c.unique()
df = pd.DataFrame([', '.join(c[c==each].index) for each in index], index=index, columns=['元号に登場する漢字'])
df.index.name = '登場回数'
pd.options.display.max_colwidth = 100
df
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/277233/5d2ae238-14e6-95f8-32a6-4e728b4970aa.png)
登場回数が特に多いのは29回の永、27回の元、天などですが、令和の「和」も20回登場の同率5位とかなりの人気ですね。一方、令和の「令」は初めて使われたようです。

ついでなので、漢字ごとの登場回数をプロットしてみます。

```python:python
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib

plt.figure(figsize=(16, 4))
bar_list = plt.bar(np.arange(len(c)), c, tick_label=c.index)
bar_list[5].set_color('red')
bar_list[-1].set_color('red')
plt.xlim([-1, len(c)])
plt.ylim([0, max(c)+2])
plt.ylabel('元号に登場した回数')
plt.title('元号に用いられた漢字と登場回数')
plt.savefig('./barplot.png', dpi=300)
plt.show()
```
![barplot.png](https://qiita-image-store.s3.amazonaws.com/0/277233/8952a62c-ec30-c3df-d655-89bc65d845ec.png)
多いところと少ないところに位置してるのが分かりますね。

ヒストグラムも見てみましょう。

```python:python
plt.figure(figsize=(5,4))
bar_hist = c.hist(bins=29)
plt.title('漢字の登場回数のヒストグラム')
plt.ylabel('漢字の数')
plt.xlabel('登場回数')
plt.savefig('./histogram.png', dpi=100)
plt.show()
```
![histogram.png](https://qiita-image-store.s3.amazonaws.com/0/277233/41c0ee5c-59f1-c647-4b45-258600056e10.png)
1度しか使われていない漢字が圧倒的に多いですね。分布だけから考えると「令」の字も次回以降使われない可能性が高いと言えそうです。一方で複数回登場する漢字は結構多いので、もし次の元号をあてずっぽうで予測するなら何度か登場した漢字＋まだ使われていない漢字の組み合わせで考えることで的中率を上げることができそうです。

## 結論
- 令は初めて使われた
- 和は20回使われていて、永、元、天、治に続いて5番目に使用回数が多い


皆さまにとって令和の世が幸せに満ちた時代になりますようお祈り申し上げます。
javascriptによるバイナリデータの送信

ブラウザで選択したファイルのバイナリデータをAzureのComputer Vision APIにJavascriptで渡すサンプルソースを掲載します。

まず、Computer Vision APIに渡すファイルを選択するためのfileタイプのinputタグと、呼び出したAPIの戻り値（boundingBox）を表示するためtextareaを置きます。

```HTML
<input id="loadFile" type="file" name="fname" accept=".bmp, .jpg, .jpeg, .png">
<textarea id="responseTextArea" style="width:600px; height:400px;"></textarea>
```

以下、ブラウザで選択したファイルのバイナリデータを渡すサンプルソース（Javascript）です。
※jqueryを使用しています。

```HTML
<script>
  document.getElementById("loadFile").onchange = function () {
    var targetfile = null;
    if (!this.files.length) {
      // 選択されたファイルを初期化
      this.value = "";
      return;
    }
    targetFile = this.files[0];
    var reader = new FileReader();
    reader.onload = readImgFile;
    reader.readAsArrayBuffer(targetFile);
    // 選択されたファイルを初期化
    this.value = "";
  };

  function readImgFile(evt) {
    // Computer Vision APIを呼び出すためのURLと引数
    // 東日本リージョンだと以下。
    // var uriBase = "https://japaneast.api.cognitive.microsoft.com/vision/v2.0/ocr";
    var uriBase = "[自身の環境に合わせて設定]";
    var subscriptionKey = "[自身の環境に合わせて設定]";
    var params = {
      "language": "ja",
      "detectOrientation": "true",
    };

    var bin = evt.target.result;

    // REST API呼び出し
    $.ajax({
        url: uriBase + "?" + $.param(params),

        // リクエストヘッダー
        beforeSend: function(jqXHR){
            jqXHR.setRequestHeader("Content-Type", "application/octet-stream");
            jqXHR.setRequestHeader("Ocp-Apim-Subscription-Key", subscriptionKey);
        },

        type: "POST",
        data: bin,
        // ajaxがdataを整形しないようfalseを指定
        contentType: false,
        processData: false,
    })
    .done(function(data) {
        // Azure Computer Vision APIの戻り値（boundingBox）
        $("#responseTextArea").val(JSON.stringify(data, null, 2));
    })
    .fail(function(jqXHR, textStatus, errorThrown) {
        // エラー内容を表示
        var errorString = (errorThrown === "") ?
                "Error. " : errorThrown + " (" + jqXHR.status + "): ";
        errorString += (jqXHR.responseText === "") ? "" :
                (jQuery.parseJSON(jqXHR.responseText).message) ?
                jQuery.parseJSON(jqXHR.responseText).message :
                jQuery.parseJSON(jqXHR.responseText).error.message;
        alert(errorString);
    });
  }
</script>
```

以上
GASのWebAPIをReactで取得

# 概要

GASでWebAPIを公開して、Reactで取得します。

参考

- https://qiita.com/takatama/items/7aa1097aac453fff1d53
- https://qiita.com/kunichiko/items/7f64c7c80b44b15371a3
- https://developers.google.com/apps-script/guides/web
- https://developers.google.com/apps-script/reference/content/

# Web API作成(Get)

1. Googleアカウントにログインして、スプレッドシートを作成する。https://docs.google.com/spreadsheets/
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215001/b51259a4-cb72-eefe-9288-99827a20cd24.png)

2. スプレッドシートにデータを入力する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215001/8dd65ebe-5ee6-d65c-29f0-e4c37b81e35f.png)


3. ツール-スクリプトエディタを起動する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215001/51313e95-551e-ca81-fe71-d03937ad8e67.png)

4. doGet(e)関数を実装する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215001/cfb8eda4-203e-fe9a-20d1-fe59ef84a05c.png)

5. ウェブ アプリケーションとして導入する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215001/216a9bd7-bfa7-bf29-8b54-ae09ce5d988d.png)

6. ブラウザからURLにアクセスして動作確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215001/ddccd4da-dccf-3ca9-b8d5-9919d3a7bb4f.png)

7. Reactで取得

https://qiita.com/y_ohr/items/09e8b3983fbca7c02a23 にて、クラスのプロパティで保持していたデータを、Web APIからの取得に置き換え。
Web APIのURLはぼかしています。

```tsx:App.tsx抜粋
private expressions: Expression[] = [
    /*
    new Expression(0, 0, Operator.plus, 1),
    new Expression(1, 2, Operator.minus, 3),
    new Expression(2, 4, Operator.times, 5),
    new Expression(3, 6, Operator.divide, 7),
    */
];

public constructor(props: any) {
    super(props);
    this.state = {
        list: this.expressions
    };

    this.handleXChange = this.handleXChange.bind(this);
    this.handleOChange = this.handleOChange.bind(this);
    this.handleYChange = this.handleYChange.bind(this);

    fetch('https://script.google.com/macros/s/***/exec')
        .then(response => response.json())
        .then(data => data.map((d: Expression) => new Expression(d.n, d.x, d.o, d.y)))
        .then(e => this.expressions = e)
        .then(() => { this.setState({ list: this.expressions }); });
}
```

# 感想

- Reactでサーバと通信できた
- 更新(`doPost()`)もやってみたい
- `fetch()`と`promise()`は、もう少しこなれた書き方はできないか？
- TypeScriptの`: type`と`as type`が混同する
- TypeScriptの`number + number`がstringのコンカチになった


以上