OmniAICreator/Qiita-1.07M huggingface dataset:
どうやって初めてのAIプロジェクトを選ぶか？(Harvard Business Reviewより)

#記事を書いたきっかけ
「Pythonで学ぶ強化学習　入門から実践まで」を執筆されている久保隆宏さんが毎週発信されているWeekly Machine Learning、いつも楽しく読ませて頂いております。
https://www.getrevue.co/profile/icoxfog417

そのうち面白そうなものを自分なりに解釈し、皆さまへもご紹介出来たらと思ったためです。

#今回の記事
Harvard Business Reviewの「How to Choose Your First AI Project」です。
https://hbr.org/2019/02/how-to-choose-your-first-ai-project

この記事は何といっても執筆者です、CourseraのMachine Learningコースで有名なあのAndrew Ng先生です！
GoogleとBaiduを率いた経験からの含蓄のある記事となっています。

#まとめ
・企業がAIを使ったプロジェクトを行うのは簡単ではないため、まずは実験的な小案件から始めるべき。
・その案件が適切なものかどうかは、①短期的に結果が出るか、②案件規模が適切か、③自社産業に固有の案件か、④良いパートナーがいるか、⑤価値を生み出すか、の5点を自問自答することでわかる。
・必ずしもBig dataは必要ない、データの有無ではなく価値を生み出すかどうかの観点で判断。
・プロジェクト実行前に、プロジェクトの時間軸と望まれる成果を明確にし、十分な予算を付ける。
・すでにAI分野を牽引している企業と競争せず、自分たちの産業に合ったAIの活用方法を理解することが大事。


#記事要約
(意訳なので必ずしも原文に忠実ではありません)
・100年前に人類の生活が電気によって激変したように、今はAIで我々の暮らしを大幅に変えようとしている。
・マッキンゼーの予想では、2030年までにAIによってものすごい額のGDPが生み出され、その大部分が製造業や農業などのインターネット以外の分野である。
・AIを活用することはどの産業・どの企業にとってもビジネスの差別化を図り自社を存続させるきっかけになる。
・ただ、実際にAIを使った戦略を実行するのは簡単ではない。
・まずは実験的な小さい案件からスタートし、そこから知見を得るべき。
・案件の良し悪しを問うの5つの質問は以下。
①短期的(6~12ヵ月以内)に結果が出るか？->スピードが大事、2・3個の案件を同時並行で進めると勝率が上がる
②案件が小さすぎ/大きすぎやしないか？->投資家を納得させられるか？
③自社の産業に固有の案件か？->その方が投資家が理解しやすい。
④信頼できるパートナーと案件を進められるか？->いきなり自社でAI開発チームを持とうとすると時間がかかりすぎるので、まずは外部から良いパートナーを探すべき。
⑤その案件は価値を生み出しているか？->コスト削減/収益増大/新たなビジネス開発、のどれかに該当するか？
・Big dataがなくともAIプロジェクトを行える。Big dataを過大評価されていて、100~1000のデータでも価値を生み出せる(無論、多いに越したことはないが)。
・大量のデータがあるという観点ではなく、いかに価値を生み出すか、が重要。
・AIを使うアイデアの源泉は、人間がやっている作業を教師あり学習を用いて自動化することであり、人間がやっていて自動化できそうな作業を探す。
・プロジェクト実行前に、プロジェクトの時間軸と望まれる成果を明確にし、十分な予算を付けるべき。
・AIとビジネスの橋渡しができる人材をリーダーにする->目的はAIのスタートアップを構築することではなく、案件を成功に導き将来の更なる案件へと繋げること。
・ビジネスとして価値があることに加え、技術的に実現可能であることを事前に検証する。
・小規模なチームで始める(15人程度)->全員がお互いを知り、複数の役割を担って動くことが出来る。
・プロジェクトが上手くったらそれに報いる->報酬や外部へのPRでチームをねぎらうこと。
・すでにAI分野を牽引している企業と競争するのではなく、自分たちの産業にとって有用なAIの活用方法を理解することが大事。

#所感
スピーディに成功案件を積み上げ、経験を蓄えて更なる案件に繋げるということで、非常に実践的な見解だと思います。
5つの質問は役に立ちそうです。更にこれに付け加えるとすれば、「人々の暮らしをよくすることが出来るか」、という質問でしょうか。
しかし、Andrew先生からAIリーディングカンパニーと競争するなと言われると、重みがある。。。

これからも定期的に記事を書きたいと思います。
皆さまも、何か面白い記事やネタ、情報ソースをお持ちでしたらぜひ教えて下さい！
cpulimitで同一プロセス名の複数のpidのプロセスを捕捉するスクリプトを書いた

どうも、haniokasaiです

cpulimitはプロセス名でプロセスを捕捉できますが、同一名で複数のプロセスは捕捉はされずまったくランダムにpidを決定して捕捉します。

それだと少なくとも私は結構困りますから、pythonスクリプトですべてのプロセスを捕捉するスクリプトを書きました。


https://github.com/haniokasai/cpulimit-multiple

コメントでconfigと書いているらへんを修正して、

```
python3 cpumultilimit.py
```

で実行できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/159888c1-7345-03d7-ecc0-7dd362054aee.png)
rails generate controllerで同時にいくつ作れるのか気になった話

## オレ generate スキ
コマンド一つで必要なものがザッと作れるgenerate、ほんと好き。
生産性が高いってこういうことなんですかね？と入門したばかりなのに楽しくて仕方がない。
そこでふと気になったんですよ、*「アレっていくつくらい同時に作れるのかなぁ？」*って。
そんな小学生のような疑問を大切にしていきたい今日このごろ。

## 環境
- cloud9
- Rails 5.2.2

## とりあえずアルファベットを1巡してみよう

ググって1ページ目にそれっぽいものがなかったのでとりあえずアルファベット並べてみました。

```
$ rails generate controller sample a b c d e f g h i j k l m n o p q r s t u v w x y z
```

こんなに同時に作るプロジェクトあるのかなぁ…。
知的好奇心を満たしたいだけなので疑問をスポイル。
流石に多すぎって怒られるかなぁ？と思いながらEnterぽちー！

```
$ rails generate controller sample a b c d e f g h i j k l m n o p q r s t u v w x y z
Running via Spring preloader in process 4430
      create  app/controllers/sample_controller.rb
       route  get 'sample/a'
get 'sample/b'
get 'sample/c'
get 'sample/d'
get 'sample/e'
get 'sample/f'
get 'sample/g'
　　：
　(中略)
　　：
      invoke    coffee
      create      app/assets/javascripts/sample.coffee
      invoke    scss
      create      app/assets/stylesheets/sample.scss
```

**マ？**
通っちゃったよ。
じゃあもう1巡、つまりアルファベット52文字なら？

```
$ rails generate controller sample a b c d e f g h i j k l m n o p q r s t u v w x y z aa bb cc dd ee ff gg hh ii jj kk ll mm nn oo pp qq rr ss tt uu vv ww xx yy zz                             
Running via Spring preloader in process 4570
      create  app/controllers/sample_controller.rb
       route  get 'sample/a'
get 'sample/b'
get 'sample/c'
get 'sample/d'
get 'sample/e'
get 'sample/f'
get 'sample/g'
　　：
　(中略)
　　：
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/sample.coffee
      invoke    scss
      create      app/assets/stylesheets/sample.scss
```

**ウッソだろお前！**
ということで、そこそこたくさんを一回でgenerateできそうです。

## おまけ：最後の一撃はせつない

消す時はgenerateをdestroyに書き換えて実行。

```
$ rails destroy controller sample a b c d e f g h i j k l m n o p q r s t u v w x y z aa bb cc dd ee ff gg hh ii jj kk ll mm nn oo pp qq rr ss tt uu vv ww xx yy zz
```

~~まぁブランチ切っといて、ブランチごと捨てる方が楽だけどさ~~
NuGetグローバルパッケージキャッシュの場所を変更する

# はじめに

今や.NET系言語を開発するのに必需品となったNuGetだが、気が付くとパッケージキャッシュフォルダが数～数十GB溜まってしまう。
パッケージキャッシュフォルダは [MSのドキュメント](https://docs.microsoft.com/ja-jp/nuget/consume-packages/managing-the-global-packages-and-cache-folders)によると、デフォルトは`%userprofile%\.nuget\packages`(win)、あるいは`$HOME/.nuget/packages`(mac,linux)とのことで、気が付くとシステムドライブがまずいことになってたりすることもある。

対処療法的には`dotnet nuget locals global-packages -c`で定期的にクリアすればいい話だが、他の選択肢として、他のディレクトリにキャッシュフォルダを逃がすという手がある。この記事では、他のディレクトリをキャッシュフォルダに指定する方法を書きたいと思う。

また、CI/CDサーバーでコンテナ等を使用してビルドする場合にも、キャッシュディレクトリを指定することによって、他のコンテナと領域を共有してビルド速度の短縮を図ったり(競合に気を付ける必要はあるが)、あるいはメモリディスク領域を指定することによって、IO負荷を減らす等の用途にも使用できる。ただし、**nugetパッケージ領域は割と大きくなる場合があるので、注意は必要。最低でも1Gは見積もった方が良い**。

実は、容量ということならば`http-cache`領域も結構あったりする場合もあるが、こちらは環境変数`NUGET_HTTP_CACHE_PATH`のみ受け付ける仕様で、増加量もグローバルパッケージキャッシュよりも緩やかなため、今回は説明しない。

# 変更方法

## 環境変数

環境変数に`NUGET_PACKAGES`で、フォルダを指定する。スクリプトで実行するならば、他にも影響を与えないため有効な方法だと思う。また、ファイル書き込みを行わないため、CI/CDとも相性が良い。
ただし、指定し忘れるとデフォルトの領域を使用するため、却ってキャッシュフォルダが散在することになり非効率になってしまうので注意が必要。

## 構成ファイルでの指定

NuGet.configファイルに設定を追加する方式。NuGet.configの場所は、[MS公式ドキュメント](https://docs.microsoft.com/ja-jp/nuget/consume-packages/configuring-nuget-behavior)に記載がある。ユーザーグローバルに設定を反映させたい場合、`%appdata%\NuGet\NuGet.config`(win)または`$HOME/.config/NuGet/NuGet.config`(mac,linux)を編集する。
プロジェクトローカルの場合、プロジェクトルート(大体slnの隣)にNuGet.configファイルを作成して編集する。雛形が必要な場合、`dotnet new nugetconfig`で作成可能。
旧packages.config方式の場合は`repositoryPath`、新方式(3.x以降)は、`globalPackagesFolder`を使用する。
.net coreの開発ならば、`globalPackagesFolder`の方の指定のみで良い。

あるいは、[nuget本サイトのダウンロードページ](https://www.nuget.org/downloads)から、nuget.exeをダウンロード(monoの場合は同梱されてるのでそちらでも可)して、`nuget.exe config -set globalPackagesFolder=[キャッシュディレクトリ] -configfile [NuGet.configファイルへのパス]`というようにしても変更が可能。`-configfile`は省略可能で、省略した場合はユーザーグローバルのNuGet.configが指定される。

### 設定例

NuGet.configの中身は、以下のようになる。

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  ...
  <config>
    <add key="globalPackagesFolder" value="c:\bin\nuget-packages" />
  </config>
</configuration>
```

上記のように設定すると、`c:\bin\nuget-packages`フォルダにキャッシュファイルが格納されるようになる(ない場合はディレクトリが作成される)。
ユーザーグローバルの場合は絶対パスのみ許容され、プロジェクトローカルの場合は相対パスも許容される。相対パスを指定した場合は、NuGet.configからの相対パスが適用される。

# 終りに

自分の場合はシステムドライブの容量圧迫回避のため変更しているが、初回ビルド時等には結構効いてくるところなので、ビルド速度アップの目的で検討してもいいかもしれない。

## 参考リンク

* [キャッシュフォルダーについて](https://docs.microsoft.com/ja-jp/nuget/consume-packages/managing-the-global-packages-and-cache-folders)
* [nuget.configについて](https://docs.microsoft.com/ja-jp/nuget/reference/nuget-config-file#config-section)
* [nuget.configの場所について](https://docs.microsoft.com/ja-jp/nuget/consume-packages/configuring-nuget-behavior)
zshの出力の最後に追記される謎の文字の話(パーセント)

# はじめに
先日DonutsさんのGo言語勉強会に参加した際に、golangの出力結果に謎の文字が出力されてそれについて唸ったので原因と解決方法をば。

# なにがあったの
golangの出力結果に謎の文字(% percent パーセント記号)が出力された。
<img width="291" alt="Screenshot_2019-02-15 22.17.01_xP8zzN.png" src="https://qiita-image-store.s3.amazonaws.com/0/270408/71a34c1e-93aa-cbc4-404a-d24a1a616fce.png">
該当コード

```go:hoge.go
package main

import "fmt"

func main() {
	str := "text"
	fmt.Print(str)
}
```

# 原因と解決方法
zshは出力結果の最後が改行されていない場合、zsh側で自動的に改行を行ってくれる。
そして、その際に勝手に改行したことを示す記号として％が出力される。
##### 試しにbashで同じコードを実行してみるとこう
<img width="235" alt="Screenshot_2019-02-15 21.56.10_XaUMoD.png" src="https://qiita-image-store.s3.amazonaws.com/0/270408/aac8ed2f-8d83-e1ee-6548-59052d8e0328.png">

zshとは違い自動的に改行されていないのがわかる。

##### 試しにgolang側で最後に改行をしてあげるとこう

```go:hoge.go
func main() {
    str := "text"
    fmt.Println(str)
}
```
<img width="294" alt="Screenshot_2019-02-15 22.19.14_GpBbY4.png" src="https://qiita-image-store.s3.amazonaws.com/0/270408/6709125d-9d68-ab32-ca9a-60c3f10171dc.png">

なるほどね？

このzshが勝手に出力してくれる文字列は`$PROMPT_EOL_MARK`という環境変数で任意に設定できる。
<img width="300" alt="Screenshot_2019-02-15 22.03.56_DdM2Ps.png" src="https://qiita-image-store.s3.amazonaws.com/0/270408/5d06a2b3-f2e8-ee1c-22c1-8de5b2b961dd.png">

良いですね。

表示したくないと思った場合はこんな感じに.zshrcに

```zsh
export PROMPT_EOL_MARK=''
```
空文字を設定してあげれば大丈夫です。

## 現状
<img width="497" alt="Screenshot_2019-02-15 22.07.59_QSipba.png" src="https://qiita-image-store.s3.amazonaws.com/0/270408/89eebc34-38d2-484e-6a66-339b7e3b7331.png">
<img width="353" alt="Screenshot_2019-02-15 22.08.43_t84i0X.png" src="https://qiita-image-store.s3.amazonaws.com/0/270408/98ffc2c6-c7ba-2535-9129-2305f9e603ec.png">
GitHub上で動くChrome拡張で、PRやIssueのページに遷移した時にContent Scriptsを発火させる

GitHub上で動くChrome拡張では、単純にmanifest.jsonで指定するだけではPRやIssueに遷移した際に毎回Content Scriptsを発火させることができません。

# 発火させたい

Content Scriptsはbackgroundからメッセージを受け取った際に発火するようにしておき、backgroundでは`chrome.runtime.onMessage`イベントによって、メッセージを送信するようにしました。
遷移時にタブのURLが変わるので、このURLをコールバックの中で受け取り、各ページのURLパターンにマッチした場合に、PRやIssueのページに遷移したとみなしています。

ただし、PRの一覧ページにクエリパラメータ付きで遷移する場合、URL的にはIssue一覧ページに遷移した後でPR一覧ページにリダイレクトするようで、この場合のみIssueの一覧に遷移した後でPRの一覧に遷移する動作をしてしまう問題が残っています。

## サンプル
### manifest.json
```json
{
  "manifest_version": 2,
  "name": "Sample for GitHub",
  "version": "1.0.0",
  "description": "Sample Chrome extension for GitHub issue and pull request.",
  "permissions": ["https://github.com/*"],
  "background": {
    "scripts": ["scripts/background.js"],
    "persistent": false
  },
  "content_scripts": [
    {
      "matches": ["https://github.com/*"],
      "run_at": "document_end",
      "js": ["scripts/main.js"]
    }
  ]
}
```

### main.js

```javascript
`use strict`;

// GitHub has async compile dom so kick script by ajax http access via background
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
  console.log(message);
  return;
});
```

メッセージを受け取っています。処理を実行する場合、ログを出力している部分に処理を記述します。messageには、遷移したページの種別が入力されます。
## background.js
```javascript
`use strict`;

class PageType {
  constructor(urlPattern, type) {
    this.urlPattern = urlPattern;
    this.type = type;
  }
}

class PageTypeMap {
  constructor(pageTypes) {
    this.pageTypes = pageTypes;
  }

  getMatchType(url) {
    let result = this.pageTypes.filter(t => t.urlPattern.test(url));
    if (result.length === 0) {
      return null;
    }

    return result[0].type;
  }
}

const PR_LIST_PATH_REGEX = /^https:\/\/github.com\/.*\/pulls.*/;
const PR_FILES_PATH_REGEX = /^https:\/\/github.com\/.*\/pull\/[0-9]+\/files.*/;
const PR_COMMITS_PATH_REGEX = /^https:\/\/github.com\/.*\/pull\/[0-9]+\/commits.*/;
const PR_CHECKS_PATH_REGEX = /^https:\/\/github.com\/.*\/pull\/[0-9]+\/checks.*/;
const PR_PATH_REGEX = /^https:\/\/github.com\/.*\/pull\/[0-9]+$/;

const ISSUE_LIST_PATH_REGEX = /^https:\/\/github.com\/.*\/issues[^\/]*$/;
const ISSUE_PATH_REGEX = /^https:\/\/github.com\/.*\/issues\/[0-9]+/;

const PAGE_TAPES = [
  new PageType(PR_LIST_PATH_REGEX, "PR_LIST"),
  new PageType(PR_FILES_PATH_REGEX, "PR_FILES"),
  new PageType(PR_COMMITS_PATH_REGEX, "PR_COMMITS"),
  new PageType(PR_CHECKS_PATH_REGEX, "PR_CHECKS"),
  new PageType(PR_PATH_REGEX, "PR"),
  new PageType(ISSUE_LIST_PATH_REGEX, "ISSUE_LIST"),
  new PageType(ISSUE_PATH_REGEX, "ISSUE")
];

const PAGE_TYPE_MAP = new PageTypeMap(PAGE_TAPES);

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
  if (changeInfo.url == null) {
    return;
  }

  kick(PAGE_TYPE_MAP.getMatchType(changeInfo.url));
});

function kick(type) {
  chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, type, function(response) {});
  });
}
```
chrome.tabs.onUpdatedに対して処理を定義しています。ここでは、URLパターンに対してページの種別を判定し、Content Scriptsにメッセージとして送信しています。

各ソースは[こちら](https://github.com/inabajunmr/gh-chrome-extension-transition-hook)です。
Python の基本構造

今日はPythonの基本構造についてまとめてみました。

----

### 構造

- パッケージ ... **初期化モジュール(\_\_init\_\_.py)**と**その他モジュール群(.py)**で構成されたフォルダ
    - モジュール ... **.py**の拡張子を持つファイル
        - クラス ... **class**で定義され、**初期化関数(\_\_init\_\_)**と**その他関数群**で構成される
            - 関数 ... **def**で定義されるもの

構造のイメージ
![python_stracutre.png](https://qiita-image-store.s3.amazonaws.com/0/287890/35532678-a864-c37b-8377-36e59724890e.png)


### 特徴

#### パッケージ
モジュール群(.pyファイル)で構成されたフォルダ。初期化モジュールは必ず必要であるが、不要の場合は中身を空(**pass**を記入)にしておくとよい。インポートの方法は
```from パッケージ import モジュール``` が一番シンプルである。また、パッケージは多層化が可能である。
#### モジュール
クラスや関数などで構成されたファイル。一つのライブラリに相当する。パッケージ化されていない場合、インポートの方法は```import モジュール```となる。
#### クラス
関数群で構成されたもの。初期化関数は必ず必要であるが、不要の場合は中身を空(**pass**を記入)にしておくとよい。
#### 関数
最小単位の定義。クラスとしてではなく、単体としても定義することができる。

---

今日はここまで。質問等があればぜひおしらせください！
CircleCI で GCR(Container Registry) の private な Docker image を利用する方法

CircleCI 2.0, 2.1 で確認。

会社のプロジェクトなどで、 GCR等で private にした Docker image をそのままCircleCIのジョブで使用したいことがあると思います。特に GCR はやり方を忘れそうだったので備忘録として残しておきます。

# 手順
### ① GCRにアクセスするための適当なサービスアカウントをIAMで作成
GCR のDocker imageは GCS に自動作成されたバケットに保存されており、
CircleCI からそのバケットにアクセスする必要がある。

### ② GCRのimageが保存されているGCSバケットに対して、①に閲覧権限を付与
GCRにDocker imageを置いていれば `artifacts.プロジェクト名.appspot.com` のような名前のバケット名が自動的にできており、そこにimageが保存されている。
(GCRのリージョンによっては `asia.artifacts.プロジェクト名.appspot.com` のようになる)

GCSの画面にて、このバケットの `ストレージオブジェクト閲覧者` の権限を ①で作成したサービスアカウントに対して付与する。
（GCR自体にアクセスするためのロールは存在しないことに注意。 参考: https://cloud.google.com/container-registry/docs/access-control#permissions_and_roles ）

### ③ 権限を付与したサービスアカウントのJSONキーをCircleCIの環境変数に設定
②で権限を付与した後にサービスアカウントのJSONキーをダウンロードし、CircleCIの環境変数に設定する。 (今回は `GCR_CREDS` という名前に。)
JSONキーの内容をコピーしてそのまま環境変数の値として入れればOK。

### ④ `.circleci/config.yaml` に認証情報を記述

③で設定した環境変数を使って以下のように記述すれば完成。

`_json_key` は、GCRにサービスアカウントからアクセスする際のユーザー名らしい。
(参考: https://cloud.google.com/container-registry/docs/advanced-authentication )

```..circleci/config.yaml
docker: 
  - image: gcr.io/プロジェクト名/イメージ名:タグ
    auth:
      username: _json_key
      password: $GCR_CREDS
```

参考: [Impossible to use a private gcr.io base image on Circle 2.0?](https://discuss.circleci.com/t/impossible-to-use-a-private-gcr-io-base-image-on-circle-2-0/15965)
iOS 12.2 beta で PWA 対応が進展してたらしい

iOSの対応状況ってどんなだろうと調べたら割とタイムリーだったので。

## 雑にリンクをシェアする
https://medium.com/@firt/pwas-on-ios-12-2-beta-the-good-the-bad-and-the-not-sure-yet-if-good-a37b6fa6afbf
https://medium.com/dev-channel/progressive-web-app-progress-in-ios-12-2-beta-1-build-16e5181f-a18cd05ca361

## どんな
詳しくは上のリンクを。以下特に確かめてません。

* Web Share API level 1
    * 知らなかったけどこういうセマンティックなAPI好き
* マルチタスク時にも状態を維持
    * [Page Lifecycle API](https://developers.google.com/web/updates/2018/07/page-lifecycle-api)未実装
    * 例えばバックグラウンドになったイベント、戻ってきたイベントで処理を発火させることなどができない
* [Abortable Fetch](https://developers.google.com/web/updates/2017/09/abortable-fetch) 
    * fetchをタイムアウトさせられる。
* ジェスチャーによるナビゲーション（右にスワイプで戻るとか）
* カラーピッカー的なフォーム
* Experimental で気になったやつ
    * Media Recorder
    * Web Authentication

など。
こういう記事を書くととりあえずそれが何者であるか程度は調べるので健康に良いですね。

## 雑リンク（参考）：11.3のとき
https://medium.com/@takeshiamano/ios%E3%81%AE11-3%E3%81%8B%E3%82%89%E3%81%AEpwa%E5%AF%BE%E5%BF%9C%E3%81%A7%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8-313f638a172b
Amazon Echoでの「予定」と「リマインダー」


#概要

（2019.2.15時点）

AmazonEcho買いました。

理由は「今日何曜日だっけ？」って何度もじーちゃんに聞かれるのがつらく、また「さっき言ったやんけぇ！！」と返してしまうのも申し訳ないと反省したからです。
あと「え？今日だっけ？」とか予定忘れまくられるのでどうしようもなかったってのもあります。

Twitterでこれ見て即買いしました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">認知症の祖母に新しい家族をプレゼントしました。<br>祖母は「アレクサ、今日何曜日？」と何度きいても、アレクサはちゃんと答えてくれる。<br><br>スマートスピーカーって実用性あるのか疑っていたけど、間違いなく介護業界には役立つと確信した。 <a href="https://t.co/0jrQrMJADz">pic.twitter.com/0jrQrMJADz</a></p>&mdash; 中野湧仁🌟#STOP電話de詐欺 (@kageroupro44) <a href="https://twitter.com/kageroupro44/status/1092945337319211009?ref_src=twsrc%5Etfw">2019年2月6日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Googleカレンダーとの連携をして、「アレクサ！」から始まる音声入力でのカレンダー予定の登録も出来ました。

「アレクサ！　今日の予定は？」での確認も出来ました。

しかし！！！！！！！！！！！！！！！！！！

時間になっても通知してくれない！
リマインド設定の30分前になっても通知してくれない！



#原因

Amazon Echoで通知してくれるのは、**リマインダー**。

予定＝カレンダーの予定
↓
通知されない

リマインダー
↓
通知される


なんじゃそりゃ


#余談

Google Homeでは通知としてピカピカLEDが光って（？）教えてくれるらしい。
けれど確認するにはやっぱり「今日の予定は？」と聞かなきゃいけないそうな。

こんなの老人相手にどうしようもない仕様ですよ。
「じっちゃん！今日の予定を確認するには”アレクサ！今日の予定は？”って聞いてね！」
なんて伝えたって覚えられるわけもなし、言うわけもなし


#対策

幸い、Alexaアプリでスマホからリマインダー登録出来ます。
なのでちまちま追加すれば、まぁ告知出来ますね……。


#発展

連携したGoogleカレンダーの予定をすべてAlexaのリマインダーに変換登録すれば良いんですよね……。

~~なんか2018年10月からと、つい最近からリマインダーAPI出来たみたいなので、誰も作ってないみたいなら作りたいと思います。~~

(2019.3.16)
全然分かんねぇです。誰か作って……
【Laravel5.7】カラム名でBETWEENしたい

`SELECT * FROM table WHERE id BETWEEN 1 AND 10`と書きたい場合は普通に書けます。

```php
$response = Table::whereBetween('id', [1, 10])->get();
```

こうすると`` `id` BETWEEN ? AND ?``というSQLが発行され、正しく想定通りの結果を得られます。

ところで、たとえば表示開始時刻から表示終了時刻までは表示する、といった仕組みを作りたい場合はどうすればいいか。
つまり`SELECT * FROM table WHERE NOW() BETWEEN display_start AND display_end`ということです。

これを調べてみたのだけど、意外と見当たらなかった。

```php
$response = Table::whereBetween('NOW()', ['display_start', 'display_end'])->get();
```

こう書くと、`` `NOW()` BETWEEN ? AND ?``とかいうSQLが発行されてしまいます。
当然`NOW()`なんてカラムは無いのでエラーです。

仕方ないので試しにやってみたらこれで動いた。

```php
$response = Table::whereBetween(DB::raw('NOW()'), [DB::raw('display_start'), DB::raw('display_end')])->get();
```

いや、うん、想定通りのSQLが発行されてるし、結果も正しいけど、なんというかこれでいいのか？
goのchannelを使って失敗してもリトライする処理を書いてみた

ある処理を行うデーモンを何個か作って並列に実行し
あるデーモンでエラーが起きたら再起動させる処理を書いてみました。

traceしやすいので
Daemon interface に自身のIDを出せるように設定しました。

interfaceとgoのchannelは便利だなぁと実感できるかと思います。

[playground](https://play.golang.org/p/XoM7JrDCmlI)

```go
package main

import (
	"context"
	"errors"
	"fmt"
	"sync"
	"time"
)

type Daemon interface {
	Do(ctx context.Context) chan error
	ID() string
}

type Sample struct {
	interval int
	id       string
}

func (a *Sample) Do(ctx context.Context) chan error {
	errCh := make(chan error)
	go func() {
		time.Sleep(time.Duration(a.interval) * time.Second)
		fmt.Printf("%#v, %#v\n", "fire", a.ID())
		errCh <- errors.New("err!!!")
	}()
	return errCh
}

func (a *Sample) ID() string {
	return a.id
}

type ConnTable struct {
	list map[chan error]Daemon
}

func (a *ConnTable) Start(ctx context.Context, d []Daemon) chan error {
	errCh := make(chan error)
	for _, item := range d {
		ch := item.Do(ctx)
		a.list[ch] = item
	}

	go func() {
		for ch, daemon := range a.list {
			go func(noticeCh chan error, d Daemon) {
				for {
					err := <-noticeCh
					fmt.Printf("[%#v] receive Err %#v\n", d.ID(), err)
					noticeCh = d.Do(ctx)
				}
			}(ch, daemon)

		}
	}()

	return errCh
}

func main() {
	ss := []Daemon{
		&Sample{
			interval: 1,
			id:       "1",
		},
		&Sample{
			interval: 2,
			id:       "2",
		},
	}
	ctx, cancel := context.WithCancel(context.Background())

	ct := &ConnTable{
		list: map[chan error]Daemon{},
	}

	ct.Start(ctx, ss)

	time.Sleep(10 * time.Second)
	cancel()
}

```

**結果**

```
$ go run connpool/main.go
"fire", "1"
["1"] receive Err &errors.errorString{s:"err!!!"}
"fire", "2"
"fire", "1"
["1"] receive Err &errors.errorString{s:"err!!!"}
["2"] receive Err &errors.errorString{s:"err!!!"}
"fire", "1"
["1"] receive Err &errors.errorString{s:"err!!!"}
"fire", "2"
["2"] receive Err &errors.errorString{s:"err!!!"}
"fire", "1"
["1"] receive Err &errors.errorString{s:"err!!!"}
"fire", "1"
["1"] receive Err &errors.errorString{s:"err!!!"}
"fire", "2"
["2"] receive Err &errors.errorString{s:"err!!!"}
"fire", "1"
["1"] receive Err &errors.errorString{s:"err!!!"}
"fire", "1"
["1"] receive Err &errors.errorString{s:"err!!!"}
"fire", "2"
["2"] receive Err &errors.errorString{s:"err!!!"}
"fire", "1"
["1"] receive Err &errors.errorString{s:"err!!!"}
"fire", "1"
["1"] receive Err &errors.errorString{s:"err!!!"}
```

Todo
再起動時の処理をサーキットブレーカにすればもっとよくなるはず
get post アクション

# 1. get postの意味
get 　　「取得」 情報をデータベースから**取ってくる**。　
post 　「作成」/保存情報をデータベースに**置いてくる**。 

# 2. アクションの意味
index　　一覧（←索引） 
show　　詳細(←見せる←明らかにする)

create　保存(newとややこしい)
new　　新規作成
【Mac】隠しファイルを常に表示させる

# 概要
`.git`や`.gitignore`を作ってあるか気になった時に、いちいちショートカットを入れるのは不都合が多かったので、忘備録として。

# 具体的方法

下記のコマンドをターミナルで実行。

```Shell:ターミナル
$ defaults write com.apple.finder AppleShowAllFiles TRUE
$ killall Finder
```


# オフにしたい場合
下記を実行します。

```Shell:ターミナル
$ defaults write com.apple.finder AppleShowAllFiles FALSE
$ killall Finder
```

# ちなみに

キーボードショートカットで表示/非表示を切り替えるには

`⌘` + `Shift` + `.`

をfinder上で入れてあげればOKです。


# 参考文献
[Mac - Finderで隠しファイル・フォルダを表示する方法 - PC設定のカルマ](https://pc-karuma.net/mac-finder-show-all-files/)
ディスク容量を圧迫しているOracleの一時表領域を縮小する

# 経緯

一時表領域の肥大化により、Oracleのディスク領域が圧迫されていた際に、一時表領域を縮小した方法です。

# 筆者の環境

* Azure Virtual Machines
* Oracle Linux Server release 7.4
* Oracle Database 12c Standard Edition Release 12.2.0.1.0

# ファイルサイズの確認

一時表領域のファイルサイズを確認します。PDBを利用している前提で、PDB名をPDB1とします。

```sh
ls -la /u01/app/oracle/oradata/cdb1/temp01.dbf
ls -la /u01/app/oracle/oradata/cdb1/pdb1/temp01.dbf
```

# 一時表領域の縮小

CDB側の一時表領域を縮小します。

```
$ sqlplus / as sysdba
SQL> select * from dba_temp_free_space;
SQL> alter tablespace TEMP shrink space;
SQL> select * from dba_temp_free_space;
```

PDB側の一時表領域を縮小します。

```
$ sqlplus / as sysdba
SQL> alter session set container=PDB1;
SQL> select * from dba_temp_free_space;
SQL> alter tablespace TEMP shrink space;
SQL> select * from dba_temp_free_space;
```

以上で、一時表領域のファイルサイズが縮小されました。
Hyper-V


* Hyper-Vネットワークの基本
  http://www.vwnet.jp/Windows/WS12R2/Hyper-V/Hyper-V_Network.htm
* Hyper-Vのネットワーク設定についての覚え書き
  https://qiita.com/kit/items/56916c4285f353e89ea0
* Hyper-Vのネットワーク（接続の種類）について
  https://uncle-atsushi.com/hyper-v_virtual_switch_configuration
* Windows Server 2012 R2における共有フォルダーの作成
  https://thinkit.co.jp/story/2015/11/12/6542
* Windowsで共有フォルダを作成してファイル共有を簡単に設定する方法
  https://i-think-it.net/windows-share-folder-easy-setting/
Herokuの導入手順

#はじめに
railsチュートリアルではcloud9上でHerokuを導入していましたが、今回ローカル環境に導入したのでその手順をメモします。

#手順
###1.[Heroku Toolbelt](https://devcenter.heroku.com/articles/heroku-cli)の導入
上記リンク先やrailsチュートリアルを参考に以下コマンドを実施(mac)

```
$ brew tap heroku/brew && brew install heroku
$ heroku　--version
$ heroku login
$ heroku keys:add # 前提としてSSH設定済み
```
###2.アセットをコンパイルする
作成しているアプリのディレクトリに移動して以下コマンドを実施。

```
$ rails assets:precompile RAILS_ENV=production
```

###3.pgライブラリをインストール
Herokuでは標準でPostgreSQLを提供しています。
単純に`rails new`をした場合はデフォルトでsqlite3が使われるため、本番環境ではPostgreSQLがどうにゅうされるように（つまり、sqlite3が本番環境で導入されないように）、pg gemをインストールします。

```ruby:Genfile
group :production do
  gem 'pg'
end
```
私はPostgreSQLをローカル環境でインストールし`rails new -d postgresql`としたため、初めからpg gemは入っており、この作業は不要でした。

###4.アプリをデプロイする
```ruby
$ heroku create
$ git push heroku master
$ git push heroku ブランチ名:master #ブランチをpushしたい場合はこのコマンド
$ heroku run rails db:migrate # マイグレーション

# 作業を進めていてデータを直したい場合は以下コマンド
$ heroku pg:reset DATABASE
$ heroku run rails db:migrate
$ heroku run rails db:seed  # seedを作成していれば
```

###5.確認
`heroku create`で生成されたアドレスをブラウザで開ければ完了です。
ローカル環境であれば`heroku open`でもブラウザ表示が可能です。
iOSでAndroidのFragmentのような実装をする　(iOSで画面入れ替え)

# はじめに
iOSでAndroidのFragmentのような実装をしたいと考えました。
AndroidのFragmentのような…というのは、ここでは1画面の中に固定View(Activity)と複数可変View(Fragment)があり、可変Viewがそれぞれ入れ替わるようなイメージしています。
![image.jpeg](https://qiita-image-store.s3.amazonaws.com/0/93899/88fbc2d1-a79b-8793-e15d-5e282b9a5f75.jpeg)


# 実現方法
今回は、ボタンを押したら2つのViewが切り替わるサンプルをつくりました。

## storyboard
![image.png](https://qiita-image-store.s3.amazonaws.com/0/93899/076c684e-bb15-aba2-8912-1920f7493732.png)
このような構造にしました。薄い青いViewがContainerです。

## ViewController
Swiftは4.2です。

```ViewController.swift

class ViewController: UIViewController {
    
    @IBOutlet weak var container:UIView!
    let redView:UIView = UINib(nibName: "RedView", bundle:nil).instantiate(withOwner: self, options: nil)[0] as! UIView
    let blueView:UIView = UINib(nibName: "BlueView", bundle:nil).instantiate(withOwner: self, options: nil)[0] as! UIView
    var changeFlag = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        changeView()
    }
    
    
    func changeView() {
        let width = self.container.bounds.size.width//containerの横幅を取得
        let height = self.container.bounds.size.height//containerの縦幅を取得
        let frame = CGRect(x:0, y:0, width:width, height:height)//containerの幅に設定
        
        //フラグによってViewをaddSubView、removeFromSuperviewして入れ替える
        if changeFlag {
            blueView.removeFromSuperview()
            redView.frame = frame
            container.addSubview(redView)
            changeFlag = false
        } else {
            redView.removeFromSuperview()
            blueView.frame = frame
            container.addSubview(blueView)
            changeFlag = true
        }
    }
    
    @IBAction func click(sender:AnyObject){
        changeView()
    }
}

```

addSubViewと、removeFromSuperviewを用いてContainerの中にViewを追加したり削除したりし、Viewの入れ替えを実現しました　。


# DEMO
![demo.gif](https://qiita-image-store.s3.amazonaws.com/0/93899/97da7ab9-7423-ceb4-237d-d40bc15f37ef.gif)

このように、ボタンを押したら青と赤のViewが入れ替わります！


# 全ソース
サンプルコードはこちらに置いてあります！
https://github.com/mii-chang/ChangeViewSample


参考になれば嬉しいです◎！
下線にpaddingを指定したい text-decoration : underline

text-decoration : underlineにpaddingを指定されたようなデザインがある場合…、CSSのデフォルトでは対応ができません😕

そんな場合の対応法です。
`border-bottom`と `display:inline`を使って対応できます。

#CSS

```
h2{
  border-bottom:2px solid #f00;
  padding-bottom:5px;
  display:inline;
  line-height:2;
}
```

#デモ

<p class="codepen" data-height="260" data-theme-id="0" data-default-tab="result" data-user="harumi-sato" data-slug-hash="qgJKKL" style="height: 260px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="下線が2行でpadding-bottomを指定したい">
  <span>See the Pen <a href="https://codepen.io/harumi-sato/pen/qgJKKL/">
  下線が2行でpadding-bottomを指定したい</a> by harumi-sato (<a href="https://codepen.io/harumi-sato">@harumi-sato</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
TypeScriptでamazon-connect-streamsを利用して電話かけてみる

世界130億超のAmazonConnectユーザのみなさん、こんにちは。

UIをカスタマイズしてAmazonConnectを使いたい！！
そんな皆さんの強い味方である[amazon-connect-stream](https://github.com/aws/amazon-connect-streams)、便利ですよね。

ですが、TypeScriptから利用するにはヒトクセあります。

## What is ヒトクセ?

- npmに公開されてない
- [公式Doc](https://github.com/aws/amazon-connect-streams)を参考にgulpでbuildしてもimportできない
- npm i aws/amazon-connect-streams --saveしてもimportできない（実体がない）
- でもindex.d.tsはある

こんな具合でできそうでできない...ｸﾞﾇﾇって感じな癖があります。


## 解決策

- [公式Doc](https://github.com/aws/amazon-connect-streams)を参考にgulpでbuild
- index.d.tsと同じDirectoryにいれる

これだけです。
構成やファイルは以下を参考にしてください。
サンプルはAngularです。

```markdown:ディレクトリ構成
/app/Modules/Connect
  /index.d.ts
  /index.js
```

```typescript:app.component.ts
import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core';
import './module/index';
import Endpoint = connect.Endpoint;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements AfterViewInit {
  title = 'applicatioin';

  state: string;
  @ViewChild('ccp') ccpContainer: ElementRef;

  ngAfterViewInit() {
    connect.core.initCCP(this.ccpContainer.nativeElement, {
      ccpUrl: 'https://YOUR-ENDPOINT.awsapps.com/connect/ccp#',
      softphone: {
        allowFramedSoftphone: true,
      },
    });
    connect.agent(agent => {
      // ここで自分のステータスを出してみた
      this.state = JSON.stringify(agent.getState());

      const phoneNumber = '+819012341234';
      const endpoint = Endpoint.byPhoneNumber(phoneNumber);
      // 電話かけてみた
      agent.connect(endpoint, {});
    });

  }
}
```

コレ、いい感じに補完が効いてますし、カスタマイズしたUIから電話の発信までできました！


## おまけ

connection.core.initCCP()の ccpUrlの最後に `/` が入ってると駄目だったのも注意点です。
No.034【Python】文字列の置換について①

![python-logo-master-v3-TM-flattened.png](https://qiita-image-store.s3.amazonaws.com/0/336067/8fb9f6aa-57f7-dc4b-b4bf-a648969d315c.png)

####今回は、「文字列の置換」について書いていきます。
I'll write about the replacement of strings in python" on this page.

###■ 文字列指定による置換 : replace
&emsp;The replacement of strings

```
>>> # string型 replace()を利用する
>>> 
>>> w = "one two three four five"
>>> 
>>> print(w.replace(" ", "-"))
one-two-three-four-five
>>> 
>>> 
>>> # 上記処理の削除方法：空文字列""にする
>>> 
>>> print(w.replace(" ", ""))
onetwothreefourfive
```

```
>>> w = "one two three four five"
>>> 
>>> print(w.replace("one", "egg"))
egg two three four five
>>> 
>>> print(w.replace("three", "mayonnaise"))
one two mayonnaise four five
```
``` 
>>> # 複数の文字列置換
>>> 
>>> # replace()を適用することで置換が可能
>>> 
>>> print(w.replace("two", "egg").replace("four", "salt"))
one egg three salt five
>>> 
>>> W = "one two one two one"
>>> 
>>> print(W.replace("one", "XtwoY").replace("two", "YYY"))
XYYYY YYY XYYYY YYY XYYYY
>>> 
>>> print(W.replace("two", "ZZZ").replace("one","XtwoY"))
XtwoY ZZZ XtwoY ZZZ XtwoY
>>> # ↑上記の様に、順番には注意すること
``` 
```
>>> # 改行文字による置換
>>> 
>>> w_lines = "one\ntwo\nthree"
>>> 
>>> print(w_lines)
one
two
three
>>> 
>>> print(w_lines.replace("\n", "-"))
one-two-three
>>> # Unix系OS：\n 　Windows系：\r\n
```

``` 
>>> w_lines_multi = "one\ntwo\r\nthree"
>>> 
>>> print(w_lines_multi)
one
two
three
>>> 
>>> print(w_lines_multi.replace("\r\n", "-").replace("\n", "-"))
one-two-three
>>> 
>>> 
>>> print(w_lines_multi.replace("\n", "-").replace("\r\n", "-"))
one-two
-three
>>> # ↑順番によっては求める結果が得られないことがある
```

####■ 複数文字指定による置換: translate
&emsp;Replacement of multiple string assignments: translate

```
>>> # str型のtranslate()を利用する

>>> # translate()に指定する変換テーブル：str.maketrans()にて作成
>>> 
>>> w = "one two one two one two"
>>> 
>>> print(w.translate(str.maketrans({"o":"O", "t":"T", "e":"E"})))
OnE TwO OnE TwO OnE TwO
>>> 
>>> 
>>> print(w.translate(str.maketrans({"o":"ZZZ", "t": None})))
ZZZne wZZZ ZZZne wZZZ ZZZne wZZZ
```

``` 
>>> # 辞書ではなく、3つの文字列を引数として指定することも可能
>>> 
>>> print(w.translate(str.maketrans('ow', 'ZW', 'n')))
Ze tWZ Ze tWZ Ze tWZ
```

``` 
>>> # 以下の場合、第一・第二引数の文字列の長さは一致が必要
>>> # 置換先文字列に長さ2つ以上文字列は指定不可
>>> 
>>> print(w.translate(str.maketrans('ow', 'ZZW', 'n')))
Traceback (most recent call last):
  File "<pyshell#88>", line 1, in <module>
    print(w.translate(str.maketrans('ow', 'ZZW', 'n')))
ValueError: the first two maketrans arguments must have equal length
```


随時に更新していきますので、<br>定期的な購読をよろしくお願いします。
I'll update my articles at all times.
So, please subscribe my articles from now on.

本記事について、<br>何か要望等ありましたら、気軽にメッセージをください！
If you have some requests, please leave some messages! by You-Tarin

また、「Qiita」へ投稿した内容は、随時ブログへ移動して行きたいと思いますので、よろしくお願いします。
Lambdaでfirebase realtime databaseを使う


# firebase側

firebaseのプロジェクトを作成し、新しい秘密鍵の生成をする。

```
設定>>プロジェクトの設定>>サービスアカウント>>新しい秘密鍵の生成
```

<img width="1440" alt="izvote_–_設定_–_Firebase_console.png" src="https://qiita-image-store.s3.amazonaws.com/0/195882/4774ea47-f820-62a4-b742-84fb11e5cf2f.png">

ダウンロードできたJSONファイルをプロジェクトのどっかに置く。

# index.js

初期設定的なやつ。

```js

var admin = require("firebase-admin");

var serviceAccount = require("./serviceAccountKey.json");

// appNameをプロジェクト名にする
admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://appName.firebaseio.com"
});
var db = admin.database();
var ref = db.ref("/path");
```

# データの保存

## set データの書き込みor置換

`/users/`以下に保存
***子ノード全てを更新してしまうので、既存のデータも上書きしてしまう。更新には`update`を使う***

```js
var usersRef = ref.child("users");
await usersRef.set({
  user01: {
    name: "imajo"
  }
});
```

## update データの更新

```js
var usreRef = usersRef.child("user");
userRef.update({
  "nickname": "imajojo"
});
```

# 取得

## once 

```js
await usersRef.once("value", function(snapshot) {
  console.log(snapshot.val());
}, function (errorObject) {
  console.log("The read failed: " + errorObject.code);
});
```

パラメータ（クエリ）指定して取得する方法は以下
https://firebase.google.com/docs/database/admin/retrieve-data?authuser=0#section-queries


# 参考

https://firebase.google.com/docs/admin/setup?authuser=0
変数展開

#変数展開
変数展開とは...
*変数を代入している値に置き換えて、文字列の中に含めること*

```
name = '佐藤'
puts "こんにちは#{name}さん"
```

`ダブルクォーテーション「""」`じゃないと変数展開できないので注意！

数値と文字列を足し算で連結することはできないが、
**変数展開を使えば、数値の入った変数と文字列を連結することができる。**
【rails5】railsアプリをAPIモードで作り、ブラウザにjsonで返すまで

#railsアプリをAPIモードで作り、ブラウザにjsonで返すまで

APIモードではビューを使わないので、serializerを使ってjsonで返す。

serializeとは、並列のデータを直列に直すこと。

元となるモデルとは別に、serializer用のモデルを作る必要がある！

```
gem 'active_model_serializer'
```

```
bundle
```

```
XXX.serializer.rb

class XXXSerializer < ActiveModel::Serializer
  attributes :id, :title ←モデルのカラムを追記
end
```

コントローラー

```
def index
  @XXXs = XXX.all
  render json: @XXXs
end
```

この後、localhost:3000/projectsへアクセスするとデータが表示される。

ポストマンに同じURLを入れてもレスポンスが返ってきます。

404エラーが返ってくるときは、自分が関係ないURLにアクセスしている可能性あり。

例えば、projects＝projects/indexに対してのアクションしか書いてないのに、
projects/1にアクセスしてたりすると、showアクションはまだ定義してないのでnot foundになる

４００番はクライアント側のエラー（ユーザーの操作ミス）

５００番はサーバー側のエラー

参考

https://qiita.com/m_nakamura145/items/75fd7c0934daf9bcc21d

https://qiita.com/jiggaman0412/items/e0e10e0f5d116a1bcb9a
docker buildする際にhost側のssh keyを使ってbuildする


docker buildする際にhost側のssh keyを使いつつbuildしたいことがある。
docker run -vなら~/.sshをmountするとかでhost側のssh keyが使えるけど、buildではできなかった。
これがDocker v18.09からできるようになった。(まだexperimental扱いではある)
keyをADDして最後に消す、みたいなワークアラウンドが不要になりそう。

## buildkitの有効化

```
$ export DOCKER_BUILDKIT=1
```

## Dockerfile

```Dockerfile
# syntax=docker/dockerfile:1.0.0-experimental

FROM ubuntu:18.04
RUN apt-get update

RUN apt-get install -y git
RUN apt-get install -y openssh-client
RUN apt-get install -y ruby

RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.e >> ~/.ssh/known_hosts
RUN --mount=type=ssh git clone git@github.e:org/repo.git
```

### build
```
$ docker build --ssh default .
```

* 先頭に`# syntax=docker/dockerfile:1.0.0-experimental`を書くのがポイント
* ssh-keyscanでknow_hostsにhost情報を書いとかないと、`Host key verification failed.`で蹴られてしまう
* 上記の例だとforward agentを使っている。

## hostのssh keyを直接mountする場合

```
RUN --mount=type=secret,id=ssh,target=/root/.ssh/id_rsa git clone 〜
```

### build

```
docker build --secret id=ssh,src=$HOME/.ssh/id_rsa .
```

* これはssh key以外のmountにも使える

## 参考
* https://medium.com/nttlabs/docker-v18-09-%E6%96%B0%E6%A9%9F%E8%83%BD-%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%83%93%E3%83%AB%E3%83%89-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3-9534714c26e2
* https://github.com/moby/buildkit/blob/b5003d53eb522f629c41ad8c48b31c2d6c340afc/frontend/dockerfile/docs/experimental.md
HTMLで使う文字実体参照一覧

いつもググってしまうので
コーディングでよく使う実体参照一覧メモしておきます📝

|   | ブラウザ表示  | 実体参照|
| ------------- | ------------- | ------------- |
| 三点リーダ  | &hellip;  | `&hellip;`  |
| 引用符  | &quot;  | `&quot;`  |
| 左ダブル引用符  | &ldquo;  | `&ldquo;`  |
| 右ダブル引用符  | &laquo;  | `&rdquo;`  |
| 終わり二重山括弧引用記号  | &raquo;  | `&raquo;`  |
| アットマーク  | &#64;  | `&#64;`  |
| アンド  | `&amp;`  |`&amp;`  |
| 著作権表示記号  | &copy;  | `&copy;`  |
| 登録商標記号  | &reg;  | `&reg;`  |
| 不等号(より小)  | &lt;  |`&lt;`  |
| 不等号(より大)  | &gt;  |`&gt;`  |
| 円記号  | &yen;  |`&yen;`  |
|  全角スペース | &emsp;  | `&emsp;`  |
| 半角スペース  | &ensp;  | `&ensp;`  |

#参照

文字実体参照一覧
http://rinrin.saiin.net/~aor/hms/cer
MySQLで該当DBの全`table create statement`を出力する

## 訂正
コメントで @akinomyoga さんに指摘していただいた部分を取り込みました。

## 本文

MySQLで該当DBの全`table create statement`を出力する方法を探したが、どうやらループで `mysql` 回すしかないらしく、苦手なshell scriptを書いた。

```sh:mysql-all-statement
#!/usr/bin/env bash

function usage {
    cat <<EOF
$(basename "${0}") is a tool for print all tables create statement

Example:
    $(basename "${0}") -p -h localhost -u root master_database > report.txt

Usage:
    $(basename "${0}") [-p password] [mysql options] [database]

Options:
    --help            print this.
    -p, --password    database password.
                      If password is not given it is asked from the tty.

mysql options:
    other options see "mysql --help"
EOF
}

case ${1} in
    --help|-help|'')
        usage
        exit
    ;;

    -p|--password)
        if [[ ${2} == -* ]]; then
            read -sp "Password:" PASSWORD 2> /dev/tty
            echo > /dev/tty
        else
            PASSWORD=${2}
            shift
        fi
        shift
    ;;
esac

if [[ -z ${PASSWORD} ]]; then
  SCRIPT_MYSQL="mysql $@"
else
  SCRIPT_MYSQL="mysql -p\"\${PASSWORD}\" $@"
fi

LIST=(`echo "SHOW TABLES" | eval "${SCRIPT_MYSQL}" 2> /dev/null`)
if [[ ${LIST} != Tables_in_* ]]; then
  echo "mysql command error: run \`${SCRIPT_MYSQL}\`" >&2
  exit 1
fi

for t in "${LIST[@]:1}"
do
    echo "SHOW CREATE TABLE $t\G" | eval "${SCRIPT_MYSQL}" 2> /dev/null
done
```

基本的には[MySQLで既存のテーブルのCREATE文を取得: Usoinfo blog](http://blog.usoinfo.info/article/285751623.html)のコードをベースに汎用的にしただけです。

`-p` オプションだけ先頭に書かないといけないというなんともスマートじゃない感じになってしまったので、そこだけご注意を。

もっと色々セフティー作れる気がするんですが、とりあえずのツールなのでここまで。
何か他にいい方法や、こここうしたら？みたなのがあればコメントください。
【Unity】 GridLayoutGroup×ScrollView

今回はUnityのUIにおいて超便利な機能、**GridLayOutGroup**について解説します。

今回はScrollViewにGridLayoutGroupを使って、

![pazu-10441.jpg](https://qiita-image-store.s3.amazonaws.com/0/360619/475ec3b9-05a0-875f-5df9-94ab75fd0d08.jpeg)

よくゲームで見るこんな感じの図鑑のように、画像などを等間隔に表示することが簡単にできます！

イメージ↓
![GridLayOut.gif](https://qiita-image-store.s3.amazonaws.com/0/360619/6e9da95d-ddb7-1a1c-a7c8-4a516618ee35.gif)


#UnityでScrollViewを作る

CanvasScalerのUIScaleModeをScale with screen sizeにして、

<img width="359" alt="スクリーンショット 2019-02-15 18.29.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/360619/8eeefcd3-7608-cd86-1af7-77977f821213.png">


Create→UI→Scroll ViewからScroll Viewを作りましょう。
AnchorPresetsから右下のStretchを選び、RectTransformの全ての値を0にしてCanvasと同じ大きさにしましょう。
（Stretchは親オブジェクトから何ピクセル離れるか、というイメージです。今回は全て０にしているので親オブジェクトと同じ大きさですね）

<img width="362" alt="スクリーンショット 2019-02-15 18.23.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/360619/847d9bd2-08e8-690c-da66-7e642da93431.png">

<img width="739" alt="スクリーンショット 2019-02-15 18.30.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/360619/cdf1d172-7e23-2f99-54fa-dc37b5ed84c4.png">
これで画面いっぱいにScroll Viewが表示されました。

今回は縦方向の移動だけで良いとするので、Scroll RectのHozirontalのチェックを外して、Scrollbar horizontalのオブジェクトも削除しちゃいましょう。

さて、ここから本題ですが、ScrollViewのViewPortの子にContentがあります。ここに画像やボタンを配置するのですが、ここで使える便利な機能が**GridLayOutGroup**です。

#GridLayoutGroup

contentにAdd Componentから
・*GridLayoutGroup*
・*Content size Flitter*
の２つを追加しましょう。

<img width="366" alt="スクリーンショット 2019-02-15 18.42.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/360619/b9e785ba-8447-5a1a-61cc-cbf9319ad655.png">
最初はこんな感じ。

GridLayoutGroupについてそれぞれの機能は公式にわかりやすくのってるので以下参照。
[Grid Layout Group - Unityマニュアル](https://docs.unity3d.com/jp/current/Manual/script-GridLayoutGroup.html)

ContentSizeFlitterについては、GridLayoutGroupで指定した子の要素の大きさに合わせて、オブジェクトの大きさを調整するという便利なものです。この２つはセットで使われることが多いです。

今回は以下のように数値を設定します。
<img width="369" alt="スクリーンショット 2019-02-15 19.12.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/360619/771624df-ddb1-6ba8-59dc-d8d3f49496ed.png">

簡単に上から見ていくと、
・Gridの左右25ピクセル、上下10ピクセルは間をあける。
・子のサイズは縦横共に210ピクセル。
・子の要素同士は縦横50ピクセルづつ間隔をあける。
・列数は3で固定する。（Consraint column count）
という感じです。

また、ContentSizeFlitterのFitを**Preferred Size**にするのを忘れずに。これをしないと、Sizeがずれてしまう可能性があります。

ではどんな感じで並ぶのか見てみましょう。今回は最初のGifのようにボタンを並べてそのボタンに数字を表示してみます。

以下のコードをオブジェクトにアタッチして、

```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Create : MonoBehaviour
{
    public RectTransform contentRectTransform;
    public Button button;
    private void Start()
    {
        for(int i = 1; i <= 30; i++){
            var obj = Instantiate(button,contentRectTransform);
            obj.GetComponentInChildren<Text>().text = i.ToString();
        }
    }
}
```

contentRectTransformの部分にContentを、buttonの部分に作成したボタンをいれてあげれば、完了です！

![GridLayOut.gif](https://qiita-image-store.s3.amazonaws.com/0/360619/8e4c5078-342b-fd9b-f07d-257594ad45fb.gif)


自分でCellSizeやSpacingなどをいじって、間隔や要素の大きさなどを変更してみましょう！

以上です！！
Node.js v11.10.0リリースノート

https://nodejs.org/en/blog/release/v11.10.0/

# deps
- Updated libuv to 1.26.0.
    - libuvを1.25.0から1.26.0に更新
- Updated npm to 6.7.0. 
    - npmを6.5.0から6.7.0に更新

# http, http2
- response.writeHead now returns the response object.
    - response.writeHead()が今まで何も返さなかったのを、レスポンスを返すように変更
        - これからさらにend()を呼び出すことが可能になった

# perf_hooks
- Implemented a histogram based API.
    - 頻度分布に基づいた測定用APIを作成？

# process
- Exposed process.features.inspector.
    - inspectorを使っているかどうかを判断する方法が、process.config.variables.v8_enable_inspectorからprocess.features.inspectorに変更

# repl
- Added repl.setupHistory for programmatic repl. 
    - プログラムでREPLをするときに履歴ログを初期化できる関数repl.setupHistory()を追加

# tls
- Introduced client "session" event.
    - sessionイベントが通知されるようになった
AWS Cloud9でファイルやフォルダを削除しようとするとエラー

AWS Cloud9のコンソール上で左ペインのファイルエクスプローラー上からファイルやフォルダをGUIから削除しようとすると、「Failed to delete folder 'null'.Access denied accessing this folder.」というエラーが出てしばらくのあいだ削除できない場合があります。

![スクリーンショット 2019-02-15 18.14.42.png](https://qiita-image-store.s3.amazonaws.com/0/258416/61bfa993-2213-bb51-4d6e-a9d027456f50.png)

削除しようとしているのはもちろん'null'なんていうファイルやフォルダではありません。


rmコマンドで強制削除しようとしてもPermission denied。

```shell
ec2-user:~/environment $ rm -r ＜ファイルまたはフォルダ＞ -f
rm: cannot remove ‘＜ファイルまたはフォルダ＞’: Permission denied
```

ファイルモードを見てみると、削除できないファイルの所有者がなぜかrootとなっています。

```shell
ec2-user:~/environment $ ls -l 
-rw-r--r-- 1 ec2-user ec2-user  #削除できたファイル
-rw-r--r-- 1 root root          #削除できないファイル
```

root権限で削除できました。

```shell
ec2-user:~/environment $ sudo rm -r ＜ファイルまたはフォルダ＞ -f
```
HTV 資料

# H17

JIS のソフトウェア安全規格と HTV のソフトウェア安全要求の比較【追加説明資料】
http://www.mext.go.jp/b_menu/shingi/uchuu/haifu/h17/anzen/05102401/001.pdf

宇宙ステーション補給機(HTV) に係る安全評価のための基本指針(案)
平成17年 月 日 宇宙開発委員会安全部会
http://www.mext.go.jp/b_menu/shingi/uchuu/haifu/h17/anzen/05102401/002.pdf

「宇宙ステーション補給機(HTV)に係る安全評価のための基本指針」(案) と JEM安全評価基本指針との対照表 (1/5)
http://www.mext.go.jp/b_menu/shingi/uchuu/haifu/h17/anzen/05102401/003.pdf

ロケットの打上げ及び再突入機の再突入に関する安全確保の概要
http://www.mext.go.jp/b_menu/shingi/uchuu/haifu/h17/anzen/05102401/004.pdf

安全6-1-5
HTVの打上げ・再突入時の安全性について
宇宙開発委員会 安全部会資料
http://www.mext.go.jp/b_menu/shingi/uchuu/haifu/h17/anzen/05102401/005.pdf

宇宙開発委員会安全部会の今後の予定について
平成17年9月9日 宇宙開発委員会事務局
http://www.mext.go.jp/b_menu/shingi/uchuu/haifu/h17/anzen/05102401/006.pdf

宇宙開発委員会 第5回安全部会 議事録(案)
http://www.mext.go.jp/b_menu/shingi/uchuu/haifu/h17/anzen/05102401/007.pdf

#H22
宇宙開発委員会 安全部会（平成22年）（第7回）　議事録
http://www.mext.go.jp/b_menu/shingi/uchuu/015/001/gijiroku/1300934.htm

総合技術監理キーワード集２０１９
http://www.mext.go.jp/result_js.htm?q=HAZOP&search=x#resultstop
Jupiter Labにgoogledriveを連携する

#拡張機能のインストール
- jupyter labを起動。
- 上部のtoolbarから"setteings" → "Advanced Setteings Editor"を開く。
- "Extension Manager"を選択し、右側の"User Override"に`{"enabled": true}`と書き込み、右上の保存ボタンで保存する。
- 左のサイドバーにExtensionの項目が出るので、そこで"jupyterlab/google-drive"をインストールする。

# API設定
連携にはAPIを利用している。

- [Doc](https://github.com/jupyterlab/jupyterlab-google-drive/blob/master/docs/setup.md)に書いてある指示に従うだけ。
- と思ったがうまくいかなかったので[こちら](https://stackoverflow.com/questions/43964539/google-api-not-a-valid-origin-for-the-client-url-has-not-been-whitelisted-for)も参考にした。
- Docの"setup instruction"の手順2のあと、ライブラリから"Analytics API"と"Google Plus API"をそれぞれ検索してAPIを有効にする。
- 以降Docに戻り、指示に従う。
最新バージョンのdSYMアップロードをほぼ自動化する

fastlaneの[download_dsyms](https://docs.fastlane.tools/actions/download_dsyms/)と[upload_symbos_to_crashlytics](https://docs.fastlane.tools/actions/upload_symbols_to_crashlytics/)を組み合わせれば，dSYMのダウンロードからアップロードまでを簡単に自動化できます．
ただし，bitcodeを有効にしている場合には，App Store Connect上での処理完了を待つ必要があります．

[メール受信をトリガにする方法](https://speakerdeck.com/qmihara/bitcode-woyou-xiao-nisitaapuridemo-dsym-falseatupurodowozi-dong-hua-suru)などもありますが，自分のチームではもう少しお手軽な方法で(ほぼ)自動化しているので，そのやり方を紹介します．


まずは以下のlaneを作成します．

``` ruby:Fastfile
lane :refresh_dsyms do |options|
  version = options[:version] || 'latest'

  download_dsyms(
    version: version
  )

  upload_symbols_to_crashlytics(
    api_token: ENV['CRASHLYTICS_API_TOKEN']
  )

  clean_build_artifacts
end
```

作成したlaneは以下のように使用します．

```sh
# 最新バージョンのdSYMをアップロード
$ fastlane refresh_dsyms

# 任意のバージョンのdSYMをアップロード
$ fastlane refresh_dsyms version:1.2.3
```

自分のチームでは，これらを以下のようなやり方で運用しています．

1. 毎週，CI上で `fastlane refresh_dsyms` を実行し、最新バージョンのdSYMに更新
  - 毎週1回のペース(金曜に申請し、翌週リリース)で定期的にリリースをしているので、  
土曜0時に実行すれば最新版のdSYMに更新できる
2. 非定期リリース(Hotfixなど)があれば，ローカルからバージョンを指定(= `version: x.x.x`を指定)してdSYMを更新

ローカルでの実行も混ざり得るのでもっといい感じの運用にしたいところではありますが，今のところ定期的なリリースサイクルを回せているので，手動での更新はほとんど必要ないです．

チームのスケジュールを考慮することで，完全自動化までは行かなくとも，それに近い結果を手軽得ることができます．
eccube4を下層ディレクトリへリバースプロキシ（nginx対応）

# はじめに

表題の件での対応メモです。

# やりたいこと

(1)webサイト(wordpress) : https://hoge.com
(2)ecサイト(eccube4) : https://shop.hoge.com

リバースプロキシで別サーバにあるecサイトを本家サイトのサブフォルダ配下にあるように見せたい。
https://hoge.com/shop -> reserve proxy - > https://shop.hoge.com

[eccube4を下層ディレクトリへリバースプロキシ](https://qiita.com/yasunobuaoki/items/485a0a87ae759d31e0d2)の続き。
以前はapacheだったのですが、nginx対応版です。

# 設定(1) - webサイト側

フォルダ権限を直したくないのとapacheに戻すことも考慮。

```/etc/nginx/nginx.conf
user=apache
```

# 問題点

(1)リバースプロキシが動作しない！

→ログを確認すると、ecサイト側へはipで接続している様子。バーチャルホストで設定していたので、ipでも参照できるようにapacheの設定を修正

(2)画像などのファイルが読み込めない

→ログを確認すると、テンポラリフォルダの権限の問題

```
＃chown apache.apache -R /var/lib/nginx
```
酒が飲めるワンライン

### perl (5.18.2 で確認)

```perl
perl -E 'say"$_月は横浜で酒が飲めるぞ"for(1..12)'
```

### ruby

```ruby
ruby -e '12.times{|i|puts"#{i+1}月は横浜で酒が飲めるぞ"}'
```

### bash

```bash
echo -e {1..12}月は横浜で酒が飲めるぞ"\n"
```

### python3 (3.7.2 で確認)
```python
python3 -c 'for n in range(1, 13): print(f"{n}月は横浜で酒が飲めるぞ")'
```

### emacs-lisp (GNU Emacs 26.1 で確認)
```emacs-lisp
(require 'cl)(let ((x 0))(while (< x 12) (cl-incf x)(insert (format "%d月は横浜で酒が飲めるぞ\n" x))))
```

### php (PHP 5.6.30 で確認)
```php
php -r 'for($i=1;$i<13;$i++){echo $i."月は横浜で酒が飲めるぞ\n";}'
```

### Elixr (1.6.4 で確認)
```elixir
elixir -e "1..12 |> Enum.map(&(\"#{&1}月は横浜で酒が飲めるぞ\n\")) |> IO.puts"
```

### MySQL版 (MySQL 8 で確認)
```SQL
CREATE DATABASE s;CREATE TABLE s.y (m int auto_increment, PRIMARY KEY (`m`));INSERT INTO s.y value (),(),(),(),(),(),(),(),(),(),(),();SELECT CONCAT(m, '月は横浜で酒が飲めるぞ') FROM s.y;DROP DATABASE s;
```

### PostgreSQL (9.3 で確認)
```sql
psql -c "WITH RECURSIVE seq(i) AS (SELECT 1 UNION ALL SELECT i + 1 FROM seq WHERE i < 12) SELECT i || '月は横浜で酒が飲めるぞ' FROM seq;"
```

### JavaScript (node.js v10.14.2)
```javascript
node -e "for(let i=1;i<13;i++)console.log(i+'月は横浜で酒が飲めるぞ')"
```

### Haskell (ghc8.4.4)
```shell
ghc -e 'mapM_ (\n-> putStrLn $ show n ++ "月は横浜で酒が飲めるぞ") [1..12]' 
```

### GAWK(GNU Awk 4.1.3)
```shell
gawk 'BEGIN{for(i=1;i<13;i++) print i"月は横浜で酒が飲めるぞ"}'
```

### ｼﾞｬﾊﾞ (OpenJDK11)
```shell
echo "IntStream.range(1, 13).forEach(m -> printf(\"%d月は横浜で酒が飲めるぞ\n\", m));" | jshell PRINTING -
```
Elixir~表を外部APIから呼び出し、Google Chartsでグラフ化！ドン！~

#ここまでのあらまし

piacereさんの [Excelから関数型言語マスター5回目：Webにグラフ表示](https://qiita.com/piacere_ex/items/290b76b76d5ff8e019bf)の前半部分までを復習して記事にしました。

そもそもの経緯として、この連載の3回目からsample_dbのPJを生成し直して復習したいのですが何をやってもうまくいかず、MacのTimeMachineバックアップから履修済みの5回目データをサルベージして、いま一度写経と理解を深めようという意図があります。

#本題

前回の記事で外部APIデータを表にしたので、今回はGoogle Chartsを使い派手にグラフ化します。

実際のコードややり方はご本人の記事にあずけるとして、今回わたしはGoogle Chartsに付与する部分のコードだけを抜粋したいと思います。

```elixir
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
  google.load( "visualization", "1", { packages:[ "corechart" ] } );
  google.setOnLoadCallback
  (
    function()
    {
      var data = new google.visualization.DataTable();
      data.addColumn( 'string', 'コラム名' );
      data.addColumn( 'number', 'いいね数' );
      data.addRows
      ( [
<%= for record <- data do %>
        [ '<%= record[ "title" ] %>', <%= record[ "likes_count" ] %> ], 
<% end %>
      ] );
      var options = 
      {
        title: 'Qiitaコラム「いいね」数',
        width: 1000, 
        height: 600, 
        chartArea: { width: '30%' }, 
        legend: { position: "none" }, 
      };
      var chart = new google.visualization.BarChart( document.getElementById( 'likes' ) );
      chart.draw( data, options );
    }
  );
</script>
<div id="likes" style="margin: 0px; padding: 0px; border: 10px #0000ff;"></div>
```

かなり物量の多いコードで、Elixir的にここはおぼろげに掴めるな...とかここはグラフの大きさとかGUIに関わる部分の設定なんだろうな...ごめんなさい、はっきり言って高度すぎていまのわたしにはお手上げ寸前です。

<img width="1552" alt="Screen Shot 2019-02-15 at 18.11.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/306722/dfe10caf-0643-c8bd-ab57-f42281e718f9.png">

iex -S mix phx.serverで最終的にlocalhost:4000に表示されるグラフがこちらです！
タイムリーなことに自分のものが上のほうに入っています。
ドラムシーケンサーのやつが7いいねくらいついていますね。

はっきり言って構文理解といったところでいうと手も足も出ないのが現状ですが、Elixirと各種外部APIの組み合わせによって一発でデータが可視化できる、ということを再確認できました。
これにVue.jsが関わってくるとどんな発展をみせるのか楽しみです。
うまずたゆまず、頑張ります。
Kento Mizuno