OmniAICreator/Qiita-1.07M huggingface dataset:
CircleCIでapt-get updateするとコケる

# TL;DR
- circleciでapt-get updateをするとエラーが出て失敗する。


# 環境
- circleci/node:9.3.0

## sudo apt-get -y -qq update
```bash
$ #!/bin/bash -eo pipefail
sudo apt-get -y -qq update
Get:1 http://security.debian.org jessie/updates InRelease [44.9 kB]

Ign http://deb.debian.org jessie InRelease

Get:2 http://deb.debian.org jessie-updates InRelease [7340 B]

Get:3 http://deb.debian.org jessie Release.gpg [2420 B]

Get:4 http://security.debian.org jessie/updates/main amd64 Packages [849 kB]

Get:5 http://deb.debian.org jessie Release [148 kB]

Get:6 http://deb.debian.org jessie/main amd64 Packages [9098 kB]

Fetched 10.2 MB in 1s (8527 kB/s)
W: Failed to fetch http://deb.debian.org/debian/dists/jessie-updates/InRelease  Unable to find expected entry 'main/binary-amd64/Packages' in Release file (Wrong sources.list entry or malformed file)

E: Some index files failed to download. They have been ignored, or old ones used instead.
Exited with code 100
```

# 解決法
`-stretch`をつけたimageを使えば問題ないらしい。
`circleci/node:9.3.0-stretch`に変えたら問題なく動いた。

# 参考
["sudo apt-get update" failing on default images #269](https://github.com/circleci/circleci-images/issues/269)
[New #269 error with upstream issue with the Debian mirrors #370](https://github.com/circleci/circleci-images/issues/370)
H2 Databaseのコンソールタイムアウト（セッションタイムアウト）を設定する

# TL;DR

* [H2 Database](https://www.h2database.com)のWebコンソールのセッションタイムアウトは、デフォルトで30分
* これを延長する場合は、システムプロパティ`h2.consoleTimeout`で秒数を指定する


# コンソールタイムアウト

H2 Databaseを起動すると、`http://localhost:8082`でアクセス可能なWebコンソールが起動します。

これのことですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309669/6f3102e6-8c6b-773c-8308-e1bd1c46b11c.png)

このセッションタイムアウトは、デフォルトで30分になっています。

人によっては、短いと感じるかもしれません。少し放置する時間があって、タイムアウトするとそれまで書いていたクエリがなくなったりするわけです。


# `h2.consoleTimeout`を設定する

Webコンソールのタイムアウトを設定するには、`CONSOLE_TIMEOUT`を設定すればよいみたいです。

[SysProperties](https://www.h2database.com/javadoc/org/h2/engine/SysProperties.html)

[CONSOLE_TIMEOUT](https://www.h2database.com/javadoc/org/h2/engine/SysProperties.html#h2.consoleTimeout)

デフォルトは`1800000`で、実際にシステムプロパティとして指定する時は`h2.consoleTimeout`を指定します。

https://github.com/h2database/h2database/blob/version-1.4.200/h2/src/main/org/h2/engine/SysProperties.java#L153-L158

`SysProperties`のプロパティの`id`が、このキーになっていましたね、記事を書いていて気づきました。

`https://www.h2database.com/javadoc/org/h2/engine/SysProperties.html#h2.consoleTimeout`

これを、H2 Databaseの起動時にシステムプロパティとして指定します。

指定方法は、こちらを参考に。

[Settings Read from System Properties](http://www.h2database.com/html/advanced.html#system_properties)

H2 Databaseのバージョン1.4.200で実行しました。

```shell
$ java -cp bin/h2-1.4.200.jar -Dh2.consoleTimeout=[秒数] org.h2.tools.Console
```

以下は、デフォルト値の30分（1800000秒）を明示的に指定した例です。

```shell
$ java -cp bin/h2-1.4.200.jar -Dh2.consoleTimeout=1800000 org.h2.tools.Console
```

これで、コンソールのタイムアウト（セッションタイムアウト）を変更することができるようになります。

確認に使用したJavaのバージョンは、こちらです。

```shell
$ java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~18.04.1-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
```
Google Codelabs形式のコンテンツを作ってGitHub Pagesで公開するまで

Google Codelabs形式のコンテンツを作るハンズオン資料をCodelabs形式で作り、GitHub Pagesで公開しました。
[ハンズオン](https://k-tomoyasu.github.io/codelab-handson)
Codelabs形式コンテンツを作るツールの存在は[DeNA SWETチームの記事](https://swet.dena.com/)で知りました。

## Google Codelabsとは
Googleが公開している様々な実装のガイド、チュートリアル、ハンズオンのコンテンツです。
[Google Codelabs](https://codelabs.developers.google.com/)
GoogleがこのCodelabs形式のコンテンツを作れるツール、`claat`(Golang製のCLI) を公開しています。

## Codelabs & GitHub Pagesのメリット
Codelab形式のコンテンツをGitHub Pagesで公開するメリットは以下のようなものがあると考えています。

- コンテンツの体裁が統一される。しかも綺麗。見た目大事
- masterをpushしたら即公開なので楽
- GitHubで修正のプルリクを受け付けられる
- GitHub Enterpriseを利用していると、社内向けなど限定的な公開が簡単にできる

## Google Codelabs作成・公開ハンズオン
### 作成・公開の流れ
作成・公開は次のような手順で行います。
1. Google Docsでドキュメント作成
2. CLIツールのclaatでコンテンツを生成
3. 2.のコンテンツをGitHubにpush
4. GithubのSettings > Github Pagesで公開
[具体的な手順はCodelabs形式で書いています。](https://k-tomoyasu.github.io/codelab-handson)
[GitHubリポジトリ](https://github.com/k-tomoyasu/codelab-handson)

![スクリーンショット 2019-10-21 12.33.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329122/5adf62ce-7624-0d59-faa9-9108097ee5ad.png)


## 最後に
簡単な編集作業で体裁の整った資料が作れるので、これから使っていきたいと思えるツールでした。
Vimマクロ、言って聞かせてさせてみて

Vimマクロ、知らんかったけど、カンタンだったよ、という話

###たとえば

```html
<a href="/hogehoge/#FUGA_xxx">
↓
<a href="/hogehoge/xxx.html">
```

に変換したいとする。
これが50個くらいある。

変換したくない箇所もところどころあるし。
50個くらいなら手でやってしまうか？

そんなとき、Vimマクロ。

チョー簡単です。


①
`#FUGA`を消すのは、
`#`にカーソルをあわせて
`df_`で消せる。

②
そのあと`.html`は
一回`w`を押して`xxx`の末尾に移動したあと
`i`して`.html`を手入力ESCすればいい。

③
あらかじめ`\/hogehoge\/`を/検索して、
`wwl`とかやれば、カーソル移動もできる

`n`で移動すれば、次も確認しながらイケる。




この①②③を
マクロで記録してしまおう

###マクロ記録開始
`qa`（aじゃなくても、a〜zまでの文字ならなんでもいいはず）
（recordingとか表示される）

###マクロ記録
①②③をやって
1行処理する

###マクロ記録終了
`q`

###マクロ実行

`@a`（aじゃなくても、a〜zまでの文字なら、対応するマクロが実行されるはず）

マクロ内に`n`を入れてしまったので
マクロ終了時、次の変換候補場所に移動してくれる。

あとは`@a`押してくだけ

###直前のマクロを実行

`@@`

というキーバインドも用意されているので
目視しながら

`@@ @@ @@ @@ @@ @@ @@ @@ @@`・・・

と連打していくだけ。

変換したくない場所は箇所は`n`で次の候補へ移動すればOK。

（確認するまでもないなら`100@q`とかもできる）

まるで、
Vimという部下に一回、手順操作を見せてあげたあと、
あと同じようにやっておいて、

って言うような気軽さ。

クッソ便利で
なんで今までコレ活用しなかったのか、と
頭を抱えるレベルなので

みんなVim初心者に教えてあげよう。




###おまけ
ヤンクしてデリートして、
デリートした内容じゃなくてヤンクした内容を貼りたいときは
`"0p`
でいける


###マクロの中身を確認する

マクロはずっと保存されるっぽい。

`:reg`
でなんか見れる

特にqwとかでやりがちなwには
パニック時の操作が記録されてるかも（笑）

###マクロの消し方

`qa q`とかで、何もしないを上書きしちゃうのが覚えやすいか。

###nを先にするかあとにするか

nを先にすると、@@した瞬間、変換した箇所が表示されるので
それで問題ないか目視する。

シンタックスハイライトで、なんか壊れてないか確認できる。

nを前にすると、変換する前に、
そこを書き換えて大丈夫か目視する。

nをあとにすると、別ファイルを開いた時とかに
nを押し忘れると、文頭が壊れちゃうので注意。
nを押してから@@する

どっちでもいいんだけど、
どっちを多様するか決めておいた方が混乱しなくてすみそう。
フレームワークと言語の関係性は、インスタント食品と料理の違いと言える

## はじめに
- **フレームワークとはいったいなんなのか？**
- **言語との違いや関係性はなんなのか？**
- **アプリの開発力を高めるためには フレームワークをたくさん勉強するべき？**

初心者が勉強を進めていくと一度はぶつかるこの疑問について。

たまにある、
「Ruby on Railsでの開発力を高めたいと思っている。RailsはRubyの”上位の技術”だから、Railsの勉強を集中して行うべき？」
という疑問にも回答すべく、今回はRubyとRailsを例に使って言語とフレームワークの関係性や違いを分かりやすく解説しました。
<br>

## フレームワークについて
### フレームワークと言語に上下関係はない

ちなみにRailsとRubyに技術的な上下関係はありません。
また、ある程度まで上達してなおRailsの開発力を高めたかったら、むしろ**Ruby言語の勉強を優先**して行った方がいいと言えます。

### フレームワークでこんなものが簡単に作れる

Ruby on Railsを構築するプログラミング言語Rubyは、Webアプリを作る以外にも以下のような様々なことができます。

- **チャットボット**
- **スマホアプリ**
- **ゲーム**
- **Webスクレイピング**
- **Webクローリング**

Ruby on Railsは「**Webアプリケーションを**」「**決まった流れに従って**」構築することに特化したフレームワークです。

### フレームワークはインスタント食品

Ruby on RailsとRubyの関係は、料理における「**インスタント食品**」と「**生の食材**」との関係に近いと私は考えます。
Railsのような**フレームワークは、インスタント食品**に該当します。

例えばインスタント食品であるカップラーメンは

1. **お湯を沸かす**
2. **お湯を注いで数分待つ**

の手順を踏襲するだけで、我々は

- **お湯を注いだときカップラーメン内部で何が起こっているか**
- **カップ麺にはどのような具材が入っているか**
- **調味法はどうするのか**
- **麺はどのように作られたのか**

を「**食べる側は一切気にする必要がなく**」美味しく食べることができます。
Railsフレームワークの良いところの一つは、「**決まりきった方法に従って実装を行うのであれば、開発者側が内部構造を深く理解する必要がない**」ことです。

なぜこのようなことが可能かというと「**Railsの設計者が内部で、開発者側が深く実装を意識しなくて済むよう親切に**」設計をしてくださっているからです。

### 言語はオーダーメイドの料理

Ruby言語そのものは生の食材に該当します。
生の食材で料理をしようと思うと、例えば肉じゃがを作るときに

- **何の具材を入れるか**
- **調味料の割合**
- **具材の切り方**
- **煮込む時間**
- **盛り付け方**

などを逐一考慮しなければならず相応の手間がかかります。
加えてその過程で包丁や火の扱い方、栄養素についての知識が必要とされるかもしれません。

Ruby言語そのものは「**多様なことができる**」故に、「**用途によって深い基礎知識を持って逐一考慮し開発者側が設計を行う**」必要があります。

**Railsの開発力をあげようと思ったら**、Rails内部でどのような実装が行われているかを理解する必要がありますが、それはRailsライブラリ内の**Rubyコードを読むこと**に他なりません。
当然Ruby言語の文法知識が要求されます。

料理に例え直すと、「**食材であるジャガイモ本来の性質を理解し、具材の切り方や煮込み時間などを考慮する**」ことでより美味しい肉じゃがを作れる、といったところでしょうか。

また、インスタント食品と生の食材に上下関係が無いように、フレームワークと言語に上下関係はありません。
あくまで**言語の用途特化機能群がフレームワーク**です。
<br>

## まとめ

言語とフレームワークの関係性や違いについて解説しました。
アプリ開発の経験も浅くて慣れていない最初は、もちろんフレームワークをガンガン使ってアプリ開発の経験と学びを積みましょう。

そこからさらにアプリ開発のスキルを深めていきたい場合にはぜひ言語に対する理解を深めていくのがいいかと思われます。
<br>

## 参考
この記事は「CodeShip」内での実際の質疑応答や指導・アドバイスの一部を基に作成しています。
docker-compose の .env ファイルとは？ コンテナの中で使える環境変数ではなく、あくまで docker-compose の記法で評価されるらしい。( #docker ))

# .env

```
MESSAGE=yes
```

# docker-compose.yml

```
version: '3'
services:
  message:
    image: alpine
    command: "echo ${MESSAGE}"
  display-env:
    image: alpine
    command: env
```

# run

コマンドとして渡したメッセージは表示されるが、環境変数が増えているわけではない。

```
$ docker-compose run message
yes
$ docker-compose run display-env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=925b3197c65a
TERM=xterm
HOME=/root
```

# .env ファイルよりも docker-compose コマンドに渡す環境変数のほうが強い

```
$ docker-compose run message
yes

$ MESSAGE=overwritten docker-compose run message
overwritten
```

# ref

[Environment variables in Compose | Docker Documentation](https://docs.docker.com/compose/environment-variables/)

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Mac + #docker で Can't add file ~ Listeners to tar: archive/tar: sockets not supported とか言われますが？

`/tmp/Dockerfile` を置いて build しようとしたら。

```
docker build .

ERRO[0000] Can't add file /private/tmp/com.apple.launchd.liRpYf6FMf/Listeners to tar: archive/tar: sockets not supported
```

`~/tmp/Dockerfile `

にだとエラーが出なかったのでディレクトリや権限問題っぽい気がした。

[linux - Docker build error, archive/tar: sockets not supported - Stack Overflow](https://stackoverflow.com/questions/56215440/docker-build-error-archive-tar-sockets-not-supported)

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
jQueryでHTMLのツリーを編集する

結局使わなかったコードをお焚き上げ。
`<link>`タグの追加と指定したタグ削除をjQueryで行うコードです。
リストが6件以下だったらタグ消してCSS1読み込んで、違ったらCSS2読み込む、といった流れです。

```html
<script type="text/javascript">
	$(function() {
	if (6 >= $('#foo_list').children().length ) {
		// リストが6件以下

		// CSS1を読込む
		$('head').append('<link rel="stylesheet" href="css/style_1.css" media="all" />');

		// タグの削除
		$('#bar_list').remove();
		$('#hoge_list > label').remove();
	} else {
		// リストが6件以上

		// CSS2を読込む
		$('head').append('<link rel="stylesheet" href="css/style_2.css" media="all" />');
	}
	});
</script>
```
asp.net coreでサービス作ったから宣伝兼ねて技術公開する -2. アーキテクト解説-

##構想アーキテクト
「当初の構想１」
![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/b68df1ed-293c-7752-99ef-6c85680655c6.png)


最初はOpenCVを使って、いい感じに１冊の本を認識させることが出来るんじゃないかという予想からC++で試してみましたが、
現時点でOpenCVだけで１冊の本を判定させるのは無理ですね。
特に黒い本。これが複数あった場合に、直線検出の精度がかなり落ちてしまいました。
残念ながら、現時点では、人間の手で判定させるしかないかなと。。。

ということで、こんな感じになりました。

##実装アーキテクト

![TanaToru_qiita_2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/d33d164d-8b92-49bd-103a-ff32634aa181.png)


これらを実装するにあたり、様々な環境設定が必要だったので、随時記載しておきます。

---

【是非お試しください】※完全無料です
TanaToru -本棚管理サービス-
　https://app.zero-one-system.co.jp/TanaToru/
Hugo+GitHub Pages+GitHub Actionsで自動デプロイする方法

## branch:gh-pagesにdeployする場合

```yml:.github/workflows/gh-pages.yml
name: githubpages

on:
  push:
    branches:
    - master

jobs:
  build-deploy:
    runs-on: ubuntu-18.04
    # runs-on: macOS-10.14
    # runs-on: windows-2019
    steps:
    - uses: actions/checkout@master

    - name: Setup Hugo
      uses: peaceiris/actions-hugo@v2.2.0
      with:
        hugo-version: 'latest'

    - name: Build
      run: hugo --gc --minify --cleanDestinationDir

    - name: Deploy
      uses: peaceiris/actions-gh-pages@v2.3.1
      env:
        ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
        PUBLISH_BRANCH: gh-pages
        PUBLISH_DIR: ./public
```

## branch:masterにdeployする場合

なぜかgithub-jekyll-build,deployがok表示されるのに、ページが表示されなかったので、github-pagesを`.nojekyll`で制御する。

```yml:.github/workflows/gh-pages.yml
name: github pages

on:
  push:
    branches:
    - src

jobs:
  build-deploy:
    runs-on: ubuntu-18.04
    steps:
    - uses: actions/checkout@master
      with:
        ref: src
        submodules: true

    - name: Setup Hugo
      uses: peaceiris/actions-hugo@v2.2.2
      with:
        hugo-version:
        # extended: true

    - name: Build
      run: |
           hugo --gc --minify --cleanDestinationDir
           touch ./public/.nojekyll
           cp ./CNAME ./public/

    - name: Deploy
      uses: peaceiris/actions-gh-pages@v2.5.0
      env:
        ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }}
        PUBLISH_BRANCH: master
        PUBLISH_DIR: ./public
```

## 概要

`.github/workflows/gh-pages.yml`にファイルを置く


```sh:鍵を作る
$ ssh-keygen -t rsa -b 4096 -C "$(git config user.email)" -f gh-pages -N ""
```

gh-pagesが秘密鍵で、gh-pages.pubが公開鍵。公開鍵は見られても平気。

秘密鍵をgithub(リポジトリ設定)の`secrets`に登録する。公開鍵を`deploy keys`に登録する。名前は何でもいい。

```sh
# 秘密鍵
$ cat gh-pages|pbcopy
# 公開鍵
$ cat gh-pages.pub|pbcopy
```

一応、設定にてbranchをソースがあるブランチに変更しておく。あとは、pushすればgh-actions(ci)が動く。
TypeScriptでThree.jsのOrbitControlsの最新版を使う

## 背景

TypeScriptでThree.jsのOrbitControlsを使う際、TypeScript用のnpmモジュールで [three-orbitcontrols-ts](https://www.npmjs.com/package/three-orbitcontrols-ts) を見つけて導入してみたが、OrbitControls内でwarningを吐いていた。

最後の更新が約3年前で、最新版のThree.jsの処理と噛み合っていなかったことが原因だった。

バージョンの差によるエラーなどは避けたいので、Three.js内の最新のOrbitControlsを参照する方法を探った。

## 環境

- Webpack, TypeScript, Three.js

```package.json
  ...
  "dependencies": {
    ...
    "@types/three": "^0.103.2",
    "three": "^0.109.0"
    ...
  },
  "devDependencies": {
    ...
    "ts-loader": "^6.2.0",
    "typescript": "^3.6.4",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.9",
    ...
  },
  ...
```

## 方法

threeパッケージ内のjsmからOrbitControlsを参照する。

```typescript

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

...

const controls: OrbitControls = new OrbitControls(camera, renderer.domElement);
controls.update();
```
Google Drive Apiの始め方(つまづきポイントメイン)

# Google DriveをGoでいじる
目標: GoのDriverでapiをいじれるようにする。
動機: Goの勉強がてらGCPにも慣れたかった。
前提: GoがインストールされているMacOS Mojave 10.14.5。GoogleAccountを持っている。

## [Google Drive Apiの公式](https://developers.google.com/drive/api/v3/quickstart/go)の通りに進めると...

- 
quickstart.goを実行した際に、URLで認証を行う必要があるのですが、自分が実行した際に以下のような感じでアクセスができない状態になってしまいました。(なんていうのか知らん)

<img width="1137" alt="スクリーンショット 2019-10-21 11.42.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243100/c1e99b5f-4bff-b24e-7705-002ac4155a37.png">

<img width="846" alt="スクリーンショット 2019-10-21 11.46.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243100/65e45f67-ccfd-3259-9464-c9b17dc227b1.png">

あれ、でもなんか安全じゃないけど見に行けるボタンみたいなのあったよなーと思い、開発者ツールから `euZgNe`にかかっている`display: none`を取り除き、アクセスしました。前まで普通に表示されていたと思うのですが、なぜかを知っている方がいたら教えていただきたい。。
<img width="413" alt="スクリーンショット 2019-10-21 11.50.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243100/a6cc7987-0781-00d0-838a-57b44bb540ff.png">

あとは許可ボタンを押し続ける作業です。この時、サンプルコードで設定されているドライバーのスコープ(これはそのアプリケーションのGoogle Driveへのアクセス権限を表すスコープの意味)がreadonlyになっているのでアップロードしたいとか権限を調整したい時には[ここ](https://godoc.org/google.golang.org/api/drive/v3#pkg-constants)を見て`google.ConfigFromJSON(b, drive.DriveScope)`の部分を変更してください。
このとき、tokenは1スコープに対して1tokenの関係なので(多分)、readonlyでtoken.jsonを作っていたならそれは削除してください。サンプルコードではスコープの変更によってtoken.jsonを使い分けができるようには作られていないので削除する必要があります。

## まとめ
自分の躓いたポイントで諦める人が出ないことを祈って初めてQiitaで簡単に書きましたが、書くのって難しい。。

[GoogleApiのDocument](https://godoc.org/google.golang.org/api)
GCP StackDriver を触ってみて。Zabbixと


## 設定例

設定例の画像はこちらから。
https://qiita.com/shun-koto/items/fb47187349a3f7182ed9

## 基本の仕組み
https://cloud.google.com/logging/docs/basic-concepts?hl=ja

## Metric　監視

これみないと監視項目わからない

### GCP metrics
https://cloud.google.com/monitoring/api/metrics

### Agent metrics
https://cloud.google.com/monitoring/api/metrics_agent

## Uptime Check 監視

## Process health 監視

https://cloud.google.com/monitoring/alerts/ui-conditions-ga?hl=ja

## 通知する内容 Document の変数

通知内容をカスタマイズしたければ、ここをみる

https://cloud.google.com/monitoring/alerts/doc-variables?hl=ja

# Logging & Log 監視

## エージェントインストール
https://cloud.google.com/logging/docs/agent/installation?hl=ja

## Log収集
https://cloud.google.com/logging/docs/agent/configuration?hl=ja

## 所感

* 結論から言うと、ちゃんと監視したい人は使ってはいけない。
ただ Cloud SQLなどは使わざるをえない、か。。。
StackDriverは、コンセプト的に大規模監視向きではないと思う。
リソース問題ではなく、監視設定の労力的に。
せいぜい 10台以内の世界。
ただほとんどのホストで取得した結果から計算を要しないこと、同じ設定ならばあり。
それがあると、ホストごとに監視設定作らないといけない。

* シビリティの設定がない。全部アラート。。。

* 通知設定が監視項目に紐づくので、通知を分けたい場合、その分監視設定を増やさなければならない。

* 通知設定のグローバルな設定がない。1監視項目ごとに設定するのはつらいって。ミスるって。設定漏れるって。
もし変更がおきたら。。。考えたくもない。致命的だなこれ

* Zabbix より監視設定自体は、なれればたぶん楽。Zabbixの数式めんどい。間違ってないか心配になる。。。
Memory とか初めから％表示なので ちょっと感動した
でも、計算させたい場合（設定のプルダウンにSUMとかある）、ホスト事に監視設定を別けないとだめ。
（全ホストが対象で計算されちゃうから）ちょーめんどい。
結局のところテンプレートの機能は必要なんだと思う。

* しきい値を変数化できない。１つずつ変更するのはつらいって。。。

* ログ監視のアラートで検知したログ本文を通知できない。

* 監視項目のグラフを見たい機関をすぐ出せない。また古いのは流れる。GCSにバックアップしないとだめ。

* 設定のインポート、エクスポートができない。設定をバックアップできない？管理できない？
品質を求められる、運用ツールとしても向いてないかも。

* ログの保持期間も決まっているので、ほかのStorageに逃がす設定もしないといけない。

* サービス監視は、海外の外部のサーバから監視してくれるのでいいかも
ただ、developとか開発用サーバで、ポートを制限している場合は逆にだめ。VPC内部から監視できるオプションもほしい。


## おまけ Zabbix マーケップレイス

Zabbixも導入も簡単。GCPだからって、StackDriverにこだわらない方がいいかも。

https://console.cloud.google.com/marketplace/details/click-to-deploy-images/zabbix?q=Zabbix&id=478d0e81-0fae-44da-b2c8-91700f2098df
asp.net coreでサービス作ったから宣伝兼ねて技術公開する -1.はじめに-

##きっかけ

「本買っても、また同じ本買っちゃうんだよね！」という村田さんの一言から始まったプロジェクトとなります。

##要件
- 本屋さんで本を探すのが好きなため、所持している本をWebでどこからでも参照可能
- 本が多いため、一冊一冊の処理はしなくない



##検討言語
新しい技術を使いたいことと、業務系のシステムのバックグラウンドばかり構築しているため、HTML+JS+CSSの知識があまり無くても構築できる言語を検討しました。
「asp.net Core 3」で検証したのですが、HTMLの書き方が Core 2系とかなり異なっており(現時点で未実装？)、サンプルがかなり少なく、「asp.net Core 3」は断念しました。
ということで、「asp.net Core 2.2」に決定しました。

Pythonは、AIとの親和性抜群ですが、フレームワークの選択が出来ない(複数あるためどれが最適解か不明)・・・。どれが今回のサービスに最適化を検証できない。そんなに時間かけたくない。あとからAI部分のみをAPI化すればよいかと考え、除外。
Javaは、有償化の話があるため、除外。

##「asp.net Core 2.2」で構築した感想

「asp.net Core 2.2」で良かったと考えております。
フレームワークは特にないため、選定する時間が不要。
プロジェクト作成時のウィザードの選択だけで、メールアドレスのユーザ認証機能まで自動で作ってくれる。
Microsoft製なのにCentOS 7.2で動くし、公式マニュアル、技術サンプルが豊富。
DB接続もEntityファイルからSQL(CRUD)作ってくれるため、SQLコーディングは不要

Microsoft Docs(テクニカル ドキュメント、API、コード サンプル)に、Cent OSへのリリース方法まで載せてくれてるもんだから、他の記事を見てわからなかったらDocsを見たりもしておりました。

##サービス概要
アーキテクトは別途説明いたしますが、棚の写真をスマホから撮り、PCで本の認識させ、一覧化するというサービスです。

##サービス連携
このサービスを構築するのに使用した外部サービスは以下の通り

| サービス | 目的 |
|-----------------|------------------|
| Amazon S3 | 画像データ保存(バックアップ用) |
| Google Vision | 画像から文字列を認識 |
| Google Books API | 文字から本を検索 |


##新サービス「棚撮る = TanaToru」
こんな感じで新サービスを作ってみました。
完全無料となっておりますので、是非試してみてください。
対象は、小説、ビジネス書のような、背表紙で分かる本のみです。
コミックは、何度やっても文字として認識してくれない。。。あれはロゴだ。いい案求む。

将来的には、「本屋さんの棚卸しは写真取るだけ！」にしたいのですが、
流石に無理だとわかっているので、補正作業を外注したり、あるタイムスタンプで写真だけ撮っておき、
暇な時間にカウントしたりすることができると素敵だなぁと考えております。

まだまだ理想には程遠いですが、一旦リリースまでは出来ました。

【是非お試しください】※完全無料です
TanaToru -本棚管理サービス-
　https://app.zero-one-system.co.jp/TanaToru/
UIButtonのTitleを中央揃えにする

UIButtonのTitleはデフォルトで中央揃えですが、なぜか左に寄ってしまうバグがあったのでコード上で中央揃えに設定しました。
何気に非常によく使います…！

## 環境
- Xcode 11.0
- Swift 5.1

## ボタンのタイトル中央揃え
`button.titleLabel?.textAlignment = NSTextAlignment.center`
で設定。

## ボタンのタイトル上下中央揃え
上下の位置も、下に寄ってしまっていたのでプロパティで設定。
`button.titleLabel?.baselineAdjustment = .alignCenters`

## その他のプロパティ
その他のよく使うボタンタイトルに関するプロパティをまとめました。
（ボタンのタイトルはUILabelなので、UILabelのプロパティを使っているだけですが）

```swift
//Buttonのタイトルを左揃えにする
button.contentHorizontalAlignment = .left

//LabelやButtonのサイズに合わせてフォントサイズを可変にする
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.titleLabel?.numberOfLines = 1
//縮小時の最小サイズを設定（文字がはみ出る場合は、この数値までは縮小される）
button.titleLabel?.minimumScaleFactor = 0.8

//lineBreakModeの設定
//表示できる部分のみを切り取る
button.titleLabel?.lineBreakMode = .byClipping
//複数行の場合、文字単位で折り返す
button.titleLabel?.lineBreakMode = .byCharWrapping
//複数行の場合、単語単位で折り返す
button.titleLabel?.lineBreakMode = .byWordWrapping
//文末を...で省略する
button.titleLabel?.lineBreakMode = .byTruncatingTail

//ボタンのタイトルラベル変更
button.setTitle("Change Title", for: .normal)
```

タイトルを左揃え（または右揃え）にする場合は、textAlignmentでは効かない場合がありcontentHolizontalAlignmentを使うことで反映されました。


## 参考
- https://stackoverflow.com/questions/5712937/how-to-make-uibuttons-text-alignment-center-using-ib
- https://i-app-tec.com/ios/button-code.html
- http://www.hnyssh.net/?p=281
正規表現を使って特定の文字列から前を削除したい

```php

$array = Array(
    0 => 'ユーザー1|一郎',
    1 => 'ユーザー2|次郎',
    2 => 'ユーザー3|三郎',
    3 => 'ユーザー4|四郎',
);

```

文字列「｜」　から前を削除して

```php

$array = Array(
    0 => '一郎',
    1 => '次郎',
    2 => '三郎',
    3 => '四郎',
);
```

のようにしたい。

##やったこと

```php

$array = preg_replace('/.*[|])/', '', $array);  
```

####解説

```

preg_replace関数
preg_replace( $正規表現パターン , $置換後の文字列 , $置換対象の文字列 )

正規表現
//　正規表現パターンの範囲を明示する（デリミタ）。
.*　とにかくなんでもいい１文字がまったくないか、連続するかという意味
[|] ｜だけだとメタ文字になってしまうので[]で文字列化

```
Laravelのフォームリクエストで認可(authorize)が不可だった場合のエラーメッセージの変更方法

Laravelのフォームリクエストの`authorize`メソッドがfalseだった場合に返されるエラーメッセージを日本語にしたかったので方法を調べました。

フォームリクエストクラス内で`failedAuthorization`メソッドをオーバーライドして、`AuthorizationException`にメッセージを引き渡してやれば、メッセージを任意のテキストできました。

```PHP
    protected function failedAuthorization()
    {
        throw new \Illuminate\Auth\Access\AuthorizationException('この操作は許可されていません。');
    }
```

ちなみ、`FormRequest`クラスでは以下のように定義されており、デフォルトだとここで指定されているメッセージが返されるようです。

```PHP:vendor/laravel/framework/src/Illuminate/Foundation/Http/FormRequest.php
  /**
     * Handle a failed authorization attempt.
     *
     * @return void
     *
     * @throws \Illuminate\Auth\Access\AuthorizationException
     */
    protected function failedAuthorization()
    {
        throw new AuthorizationException('This action is unauthorized.');
    }
```


より適切なエラーメッセージの変更方法があれば、コメントいただければ幸いです。
Firefoxでlocalhostの通信をBurpに通す方法

ブラウザのURLに以下のように**`about:config`**と入力します
（警告が出ますがそのまま進む）

<img width="1436" alt="スクリーンショット 2019-10-21 11.39.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253111/e1a49680-494a-f718-2030-71407b8cb931.png">

<input type="text" value="aa">

次に、検索欄に**`network.proxy.allow_hijacking_localhost`**と入力する

<img width="1440" alt="スクリーンショット 2019-10-21 11.42.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253111/d75fa36d-599b-caba-5062-596460fb2fad.png">


青い欄をダブルクリックして、値を`false`から**`true`**にする。
<img width="1440" alt="スクリーンショット 2019-10-21 11.43.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253111/e3755f92-a360-9350-a8b5-ca74494c04fc.png">


次に、右上のメニューから**『⚙ 設定』**をクリック
<img width="702" alt="スクリーンショット 2019-11-25 0.07.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253111/24d9d4d1-f5d3-e2b5-90b5-1a291dc43c37.png">
一番下まで行き、**『接続設定』**をクリック
<img width="590" alt="スクリーンショット 2019-11-25 0.07.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253111/f6695c89-5d3a-8a26-cf40-b479fae5940e.png">
**『プロキシーなしで接続』**の欄の`localhost,127.0.0.1`を削除すればBurpにlocalhostの通信が通るようになります。
<img width="701" alt="スクリーンショット 2019-11-25 0.06.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253111/e4528632-67f9-d442-28ba-cbc2df0aefa0.png">


<a href="https://support.portswigger.net/customer/portal/questions/17532258-burp-interception-does-not-work-for-localhost-in-chrome">参考</a>
Laravel: Vessel によるローカル開発用コンテナ環境を使う

## 環境

- Laravel 6.0
- [Vessel](https://vessel.shippingdocker.com)

## 概要

Laravel のローカル開発環境を Docker Compose で動作させるための設定とショートカットコマンドを提供してくれる。

## 導入

### インストール

```shell
$ composer require --dev shipping-docker/vessel
```

### 設定の取り込み

```shell
$ php artisan vendor:publish --provider="Vessel\VesselServiceProvider"
```

これにより以下が生成される。

- docker/ 配下 ... イメージ作成のための設定
  - app/
  - mysql/
  - node/
- docker-compose.yml
- vessel ... コマンド

docker/ 配下はファイルがいろいろあるが、これをベースに直接カスタマイズしていくのでコミットしてしまって良いと思う。

### 初期化

```shell
$ bash vessel init
```

このコマンドでおこなわれること。

- composer require predis/predis
  - キャッシュとセッションに Redis を使うためにインストール

- .env の設定変更

  ```file
  DB_HOST=mysql
  CACHE_DRIVER=redis
  SESSION_DRIVER=redis
  REDIS_HOST=redis
  ```

  - データベースのホストを mysql コンテナに向ける設定
  - キャッシュとセッションの保存先を Redis に向ける設定
  - ※.env.example は変更されないので、必要があれば転記してコミットする

- vessel コマンドへの実行権限追加

例)

### 起動

```shell
$ ./vessel start
```

docker-compose up -d と同じ。デフォルトで以下のコンテナが起動する。

- app : Ubuntu 18.04 ベース。supervisord (nginx + php-fpm)
- mysql:5.7
- redis:alpine

データベース名、ユーザー等は .env から取得して初回起動時に作成される。DB_USERNAME に root を指定するとユーザーを作成しようとしてエラーになるので別のものにする。

他に必要なものがあれば docker-compose.yml を編集する。

### 停止

```shell
$ ./vessel stop
```

docker-compose down と同じ。

### コンテナイメージの再ビルド

Dockerfile は docker/ フォルダ配下にあるので、必要に応じて編集し、再ビルドする。

```shell
$ ./vessel build
```

docker-compose up -d と同じ。

### ログイン

```shell
$ ./vessel exec app bash
```

docker-compose exec app bash と同じ。

### composer コマンド実行

```shell
$ ./vessel composer (コマンド)
```

app コンテナで composer を実行するショートカット。

### artisan コマンド実行

```shell
$ ./vessel artisan (コマンド)
```

app コンテナで php artisan を実行するショートカット。
Drone CI Open Source Edition のコンテナイメージをビルドする

Docker Hub に用意されているものは [Enterprise Edition](https://drone.io/enterprise/) のため、一定規模以上での無償利用にはビルド数に制限がある。機能は少ないが制限なしで使える [Open Source Edition](https://www.drone.io/enterprise/opensource/#features) をコンテナで動作させる。

## 環境

- [Drone CI](https://drone.io) 1.6.0

## ビルド手順

### Drone Server のビルド

[BUILDING_OSS](https://github.com/drone/drone/blob/master/BUILDING_OSS) を参考にビルドする。

デフォルトのビルドは glibc にダイナミックリンクされるため、素の alpine 上では動作しない。そのため、`-ldflags "-extldflags \"-static\""` をつけてスタティックリンクする。以下は golang コンテナで drone-server をビルドする例。

```shell
$ DRONE_VERSION=1.6.0
$ git clone -b v${DRONE_VERSION} https://github.com/drone/drone drone_${DRONE_VERSION}
$ cd drone_${DRONE_VERSION}
$ docker run -it -v `pwd`:/src golang bash
# cd /src
# go build -tags "oss nolimit" \
    -ldflags "-extldflags \"-static\"" \
    -o release/linux/amd64/drone-server \
    github.com/drone/drone/cmd/drone-server
# exit
```

### Docker イメージ作成

[Dockerfile.server.linux.amd64](https://github.com/drone/drone/blob/master/docker/Dockerfile.server.linux.amd64) を参考に Dockerfile を作成する。(Datadog は無効化したくらい。)

```dockerfile
# docker build --rm -f docker/Dockerfile -t drone/drone .

FROM alpine:3.9 as alpine
RUN apk add -U --no-cache ca-certificates

FROM alpine:3.9
EXPOSE 80 443
VOLUME /data

RUN [ ! -e /etc/nsswitch.conf ] && echo 'hosts: files dns' > /etc/nsswitch.conf

ENV GODEBUG netdns=go
ENV XDG_CACHE_HOME /data
ENV DRONE_DATABASE_DRIVER sqlite3
ENV DRONE_DATABASE_DATASOURCE /data/database.sqlite
ENV DRONE_RUNNER_OS=linux
ENV DRONE_RUNNER_ARCH=amd64
ENV DRONE_SERVER_PORT=:80
ENV DRONE_SERVER_HOST=localhost
#ENV DRONE_DATADOG_ENABLED=true
#ENV DRONE_DATADOG_ENDPOINT=https://stats.drone.ci/api/v1/series

COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

ADD release/linux/amd64/drone-server /bin/
ENTRYPOINT ["/bin/drone-server"]
```

ビルドする。

```bash
$ docker build -t drone${DRONE_VERSION} .
```
Laravel tymon/jwt-auth でトークンを Cookie に保存する

## 環境

- Laravel 6.0
- [tymon/jwt-auth](https://github.com/tymondesigns/jwt-auth) 1.0.0-rc.5

## 概要

jwt-auth では、JWT トークンを以下の順番で検索する。

- Authorization ヘッダ (Bearer)
- Request->query('token')
- Request->input('token')
- Route パラメタ (token)
- Cookie (token)

ということで、トークンを発行したら、`token` という名前の Cookie を設定してあげればよい。

## 設定手順

### Cookie 設定例

```php
class AuthController extends Controller
{
    public function login(Request $request, CookieJar $cookie): Response
    {
        $credentials = request(['email', 'password']);
        $token = auth()->attempt($credentials);
        ...
        return response(...)
            ->withCookie($cookie->make(
                'token',
                $token,
                config('jwt.refresh_ttl'), // minutes
                null, // path
                null, // domain
                $request->getScheme() === 'https', // secure
                true // httpOnly
            ));
    }
}
```
Laravel: 開発時だけ他ホストからの要求を許可する (CORS)

## 背景

開発時のみフロントエンドを別ホスト・ポートで動作し、クロスサイトでのリクエストを許可したい。本番には適用しない。

## 実装

CORS ヘッダを設定するミドルウェアを作成する。

クロスサイトで認証情報つき(withCredentials)リクエストをおこないたい場合は `Access-Control-Allow-Origin: *` が許可されないため、リクエスト元のホスト名を入れて返している。
参考) [Reason: Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials)

```php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class Cors
{
    public function handle(Request $request, Closure $next): Response
    {
        /** @var Response $response */
        $response = $next($request);

        if (env('APP_DEBUG') && $request->header('Origin')) {
            $response->headers->set('Access-Control-Allow-Credentials', 'true');
            $response->headers->set('Access-Control-Allow-Origin', $request->header('Origin'));
            $response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
            $response->headers->set('Access-Control-Allow-Headers', 'Origin, Authorization, Accept, Content-Type, X-XSRF-Token');
            $response->headers->set('Access-Control-Expose-Headers', 'Authorization');
        }

        return $response;
    }
}
```

このミドルウェアを有効にする。

```php
namespace App\Http;

use Illuminate\Foundation\Http\Kernel as HttpKernel;

class Kernel extends HttpKernel
{
    ...
    protected $middleware = [
        ...
        \App\Http\Middleware\Cors::class
    ];
    ...
}
```
【Java】フィルターを作成

重複する内容はフィルターを作成してスッキリとしたコードに！！！

```ruby:EncodingFilter.java
package tool;

import java.io.IOException;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;

@WebFilter(urlPatterns = { "/*" })
public class EncodingFilter implements Filter {
	public void doFilter(
		ServletRequest request,
		ServletResponse response,
		FilterChain chain
	) throws IOException, ServletException {
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");

		System.out.println("フィルター処理前");

		chain.doFilter(request, response);

		System.out.println("フィルター処理後");

	}

	public void init(FilterConfig filterconfig) {}

	public void destory() {
	}
}
```
Pythonの関数のデフォルト値は後から変更できる

前書き
---
このように、ミュータブルなデフォルト値を持っている関数pileを定義したとする。

```python
>>> def pile(num, lst=[]):
...     lst.append(num)
...     return lst
...
>>>
```

このデフォルト値は、当該関数オブジェクト自体が保持している。

```python
>>> pile(1)
[1]
>>> pile(2)
[1, 2]
>>> pile(42)
[1, 2, 42]
```

他言語に慣れている人から見れば随分奇怪な挙動であるが、これが仕様なのだから致し方ない。
[公式リファレンス](https://docs.python.jp/3/faq/programming.html#why-are-default-values-shared-between-objects)に至っては、『キャッシュに使えば？』なんて提案をしているほどである。[^1]

[^1]: 『ミュータブルなオブジェクトを指定するな』という、真っ当なアドバイスもしている。

デフォルト値の確認
---
ユーザ定義関数の特殊属性を参照すれば、デフォルト値を確認することができる。

| 属性             |  意味              |
|:----------------:|:------------------|
| `__defaults__`   | デフォルト値を持つ引数に対するデフォルト値が収められたタプルで、<br>デフォルト値を持つ引数がない場合には None になります | 
| `__kwdefaults__` | キーワード専用パラメータのデフォルト値を含む辞書です。 |

引用元： [Python 言語リファレンス » 標準型の階層 » 呼び出し可能型](https://docs.python.jp/3/reference/datamodel.html#the-standard-type-hierarchy) (一部抜粋)

```python
>>> def func(arg1, arg2=10, *, kwarg1=20, kwarg2=30):
...     pass
...
>>> func.__defaults__
(10,)
>>> func.__kwdefaults__
{'kwarg1': 20, 'kwarg2': 30}
```

デフォルト値は変更可能である
---
次のような操作が可能である。

```python
>>> def pile(num, lst=[]):
...     lst.append(num)
...     return lst
...
>>>
>>> pile(1)
[1]
>>>
>>> pile.__defaults__[0].append(42)
>>> pile(2)
[1, 42, 2]
```

特殊属性`__defaults__`はタプルであるので、直下の要素を置き換えることはできない。
しかし、丸ごとごっそり書き直す分には何の問題もない。[^2]

[^2]: 書き込み可能であるとドキュメントに明記されている。

```python
>>> pile.__defaults__
([1, 42, 2],)
>>>
>>> pile.__defaults__ = [],
>>> pile(3)
[3]
```

元々デフォルト値が無い仮引数に影響することすら可能である。

```python
>>> pile.__defaults__ = -1, []
>>>
>>> pile()
[-1]
>>> pile()
[-1, -1]
>>> pile()
[-1, -1, -1]
```

デフォルト値の割り振られ方
---
過少あるいは過剰なデフォルト値を与えた場合、それらの割り振られ方は独特である。

```python
>>> def func(arg1, arg2, arg3):
...     print(arg1, arg2, arg3)
...
>>> func.__defaults__ = 1, 2
>>> func()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func() missing 1 required positional argument: 'arg1'
>>>
>>> func.__defaults__ = 1, 2, 3
>>> func()
1 2 3
>>>
>>> func.__defaults__ = 1, 2, 3, 4
>>> func()
2 3 4
>>>
>>> func.__defaults__ = 1, 2, 3, 4, 5
>>> func()
3 4 5
```

使いどころ
---
特に思い浮かばない。
多用する引数のデフォルト値を決めたい場合は、ラッパー関数を書けば良いわけで。
githubのリポジトリ名を変更する方法とした後の設定変更

githubでリポジトリを一度作成した後に、諸事情でリポジトリ名を変えたいなーって時はたまにあると思います。
そんな時の変更方法です。

## リポジトリ変更方法

[``Settings``]→[``Repository Name``]→[``Rename``]です。

※変更は管理者権限のあるユーザのみ可能です。

ちなみに、リポジトリ変更してもURL変わったり色々参照している箇所の変更が面倒では？
と思うかもしれませんが、
旧URLからでもトップのURLやissues、wikiなどは**自動でリダイレクト**が効くようになるのであまり気にしないでいいので便利です。

## clone済みのローカル側の変更

```
git remote set-url origin {新しいURL}
```
この変更をしなくても自動リダイレクトは効きますが、しておくに越したことはないでしょう。

### 変更が反映されているかの確認は

```
git remote -v
```

### clone済みのフォルダ名は

ローカルのclone済みのフォルダは、そのままディレクトリ名を変更するだけでOKです。
ローカルのルートのディレクトリ名は管理対象ではないので。


## 参照

https://help.github.com/ja/github/administering-a-repository/renaming-a-repository
ggmapパッケージを用いて住所から緯度経度のデータを得る

文字のインプットに対して、緯度経度のデータを取得する方法の一つで、自分が普段使う方法を記録しておきます。

自分が用いいるのは、CRANにも上がっていて、使い方が非常に簡単な、**[ggmapパッケージ](https://github.com/dkahle/ggmap)**です。

+ [ggmap公式ドキュメント](https://cran.r-project.org/web/packages/ggmap/ggmap.pdf)
+ [ggmap開発(GitHub)ページ](https://github.com/dkahle/ggmap)

# セッティング
```{r}
# install.packages("ggmap") # まだインストールしていない人用に
# devtools::install_github("dkahle/ggmap") #開発版をインストールしたい場合

library(ggmap)
register_google("XXXXXXXXXXXXXXXXXXXXXXXXXXX") # 個人で取得したgoogle apiの登録が必要
```

これで設定が完了。

# 住所より緯度経度を取る方法

ggmapパッケージでは```geocode()```という関数が提供されており、第一引数の```location```に文字列で、住所をインプットすることにより、緯度経度データを取得できます。

| Place        | Location           |
| ------------- |:-------------:|
| 東京駅    | 東京都千代田区丸の内１丁目 | 
| 東京スカイツリー      | 東京都墨田区押上１丁目１−2      |  
| 豊洲マーケット | 東京都江東区豊洲６丁目３      | 


上記のようなデータがあり、右に緯度と経度のコラムを挿入したい場合には下のような処理を行います。

```{r}
dat %>% 
  mutate(緯度 = geocode(Location)$lat,
         経度 = geocode(Location)$lon)
```

```{r}
             Place                   Location     緯度     経度
1           東京駅 東京都千代田区丸の内１丁目 35.68124 139.7671
2 東京スカイツリー 東京都墨田区押上１丁目１−2 35.71006 139.8107
3   豊洲マーケット   東京都江東区豊洲６丁目３ 35.64574 139.7879
```


# 可視化 
このように文字列で記録された住所を座標データとして取り扱えることで以下のような可視化も可能です。

```{r}
library(leaflet)
leaflet(data = dat) %>% 
  addProviderTiles("Stamen.TonerLite") %>% 
  setView(lng = mean(dat$経度), lat = mean(dat$緯度), zoom = 12.5) %>% 
  addCircleMarkers(~経度, ~緯度, popup = ~paste(Place, ":", Location),
                   clusterOptions = markerClusterOptions())
```

![Screen Recording 2019-10-21 at 10.51 AM.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83838/7227c54f-1a0f-7edd-1af5-88e8d5625225.gif)


このように簡単に操作ができるため自分としては活用しています。某nateで開催中の学生限定コンペ等で活用もできるでしょう。
Windows IIS ログローテーション

@ECHO OFF
::#############################################################
::#                                                           #
::# <スクリプト名>   iis-log-rotate.bat                        #
::# <機能概要>       IISログの圧縮ローテーション                #
::#                  7日より以前のファイルを圧縮               #
::#                  180日後圧縮ファイルの削除                 #
::# <引数>           5                                        #
::#                  ※引数なしは起動しない（誤動作防止）       #
::# <入出力ファイル> なし                                      #
::# <注記>           なし           　                         #
::#-----------------------------------------------------------#
::#                                                           #
::#############################################################

::引数チェック　バッチファイルに引数をつけて実行ダブルクリックでの実行防止
if not "%1"=="5" ( exit /b )
setlocal enabledelayedexpansion
SET LPAS=C:\inetpub\logs\LogFiles\W3SVC1
::#圧縮対象ファイルの確認なければ終了
forfiles /P %LPAS% /M *.log /D -7 > nul 2>&1
if not %ERRORLEVEL% EQU 0 (exit /b)
::#ログファイルの圧縮 7日より以前のログファイル
for /f %%i in ('forfiles /P %LPAS% /M *.log /D -7') do (
SET Z=%%i
SET X=!Z:~-11,6!
powershell Compress-Archive -Path %LPAS%\*!X!.log -DestinationPath %LPAS%\IIS_20!X!.zip -ErrorAction Stop > nul 2>&1
powershell Start-Sleep -s 1
powershell Remove-Item %LPAS%\*!X!.log -ErrorAction Stop > nul 2>&1
)
::#180日より以前の圧縮ログファイルを削除
forfiles /P %LPAS% /M *.zip /C "cmd /c if @isdir==FALSE del /s @path" /D -180 > nul 2>&1
exit /b
台風19号の影響をスクレイピングしてみた！

##台風の概要
　日本気象庁より、10 月6 日に南鳥島近海で発生した。台風第19 号の接近・通過に伴い、広い範囲で大雨、暴風、高波、高潮となった。
　雨については、静岡県や新潟県、関東甲信地 方、東北地方の多くの地点で3、6、12、24 時間降水量の観測史上1 位の値を更新す るなど記録的な大雨となった。
　風については、東京都江戸川臨海で最大瞬間風速43.8 メートルとなり観測史上1 位を更新したほか、関東地方の7 か所で最大瞬間風速40 メートルを超えた。
![1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/24984047-d1a7-e662-5463-6c01f994e7c3.gif)
　Yahooニュース10/16(水) 17:40配信により、台風19号による記録的な大雨による死者は増え続け、16日までに12都県で計79人に上った。
　こう言う史上最強と呼ばれた第19号台風はTwitterにホット話題になりました。
だから私たちは、第19号台風について人々が何のツイートしているのかを簡単なデータ分析をしようと思います。[ScrapeStorm](https://www.scrapestorm.com/jp/)を通じで、[スクレイピング](https://www.scrapestorm.com/jp/)して、ツイートを抽出します。
##抽出したツイート
　調査結果を共有する前に、Twitterから抽出したデータについて説明します。
時間制限のため、台風の影響をキーワードとして1003件のツイート（もちろん1003件以上があるはずです）を収集しました。各ツイートから抽出したデータには以下が含まれます：
**· 名前**
**· 投稿時間**
**· コンテンツ**
**· 画像のURL**
**· ツイートのURL**
**· コメント、リツイート、いいねの数**
![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/7ceeaf87-ca79-0de1-da5a-32cf0c25c8cc.gif)
##交通が影響されます
台風19号の影響で日本各地に洪水が発生しています。洪水のせいで、車の運転、電車、バスなどの運営が影響されました。例えば、自動改札機が使えなくなったとか、人々の日常生活に影響を与えました。また、福島県郡山市では90台のバスが水没し、市内のほぼすべてにあたるおよそ70の路線が運休する件は特に注目します。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/ff769736-8d43-2983-e79b-514f0dfea218.png)
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/0d8fc97c-30c4-ca97-a972-c8b4c268546b.png)
##日本環境への影響
台風の豪雨に伴う洪水の原因で、日本福島原発地域の放射性廃棄物が流出する大型事故と福島県郡山市にある工場で猛毒のシアン化ナトリウムが流出事件はTwitterにホットトピックになりました。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/ca924b74-ba2b-1683-142f-26bb9b5512fc.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482909/9ecbd517-8e9f-9cf1-7104-76a951ec79a7.png)
##まとめ
　第19号台風は今消えてしまいましたが、台風に連れて来た影響はまだまだ続けています。日本政府は力を尽くして防災対策しています。人々はまた、防災や災害救援活動にも積極的に参加しています。自然災害に直面した人間はどれほど無力で小さいか。私たちは常に自然に敬意を払うべきです。最後は、被災地の早期復旧に祈ります。

参照リンク：
台風第19号による大雨、暴風等　令和元年(2019年)10月10日～10月13日（速報）
https://www.data.jma.go.jp/obd/stats/data/bosai/report/2019/20191012/20191012.html
台風被害、死者79人に＝なお10人不明、夜通し捜索－東北、週末に大雨恐れ
https://headlines.yahoo.co.jp/hl?a=20191016-00000093-jij-soci
devise導入時、既にUserモデルがある場合の対応

## 既にUserモデルがあるんだけど、deviseでUserモデルを作成するときはどおすればいいんだろう？
結論：普段通りdeviseを導入する形で大丈夫です🙆‍♀️

### 導入前

```rb:db/schema.rb
create_table "users", force: :cascade do |t|
    t.string "name"
    t.integer "age"
    t.string "sex"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end
```
###手順
既にUserモデルが存在します。

1. gemfileにdeviseの追加
2. bundle install
3. deviseのインストールする `rails g devise:install`
4. deviseでUserモデルのインストールする `rails g devise User`
5. rails db:migrate

4.の時点でuser.rbにインサートされているのが分かります。

```terminal
create    db/migrate/20191021010023_add_devise_to_users.rb
insert    app/models/user.rb
route  devise_for :users
```
*❇︎モデルの新規作成か否かはrailsが判断してくれるそうです*
*❇︎既にあるUserモデルのカラムと被りが合った場合はmigrationに失敗するらしいです*

###導入後

```rb:db/schema.rb
create_table "users", force: :cascade do |t|
    t.string "name"
    t.integer "age"
    t.string "sex"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end
```
[Vue.js]propsのdefaultの値の指定について

## 型ミス

以下のような記述をし、ビルドエラーを起こした。

```javascript

 props: {
            dialogOtherAlertMessage: { type: String, default: false }
        },

```

##原因

typeはStringなのに、defaultがBooleanで渡してたからエラーになってた。
正しくは以下でした。

```javascript

 props: {
            dialogOtherAlertMessage: { type: String, default: () => "" }
        },

```
JAVASCRIPTの練習（２）


前の続きで、はたと詰まってしまった。
https://github.com/karldoenitz/html_table_immediate_edit

セレクタの要素の中に、HTMLのタグを示す＜＞が入ってきているパターン。。。
えー、いろいろ調べたけど、日本のサイトでは見つからない。

ここは一体なんなんだろうか？
ちょっと分からなかったので、いろいろ調べてみたら
htmlのタグをそのまま書くと、要素を生成することらしい。。。

```javascript

    var input = $("<input>");
    input.attr("value",tdText);
    td.append(input);
    input.blur(function(){
        var input = $(this);
        var inputText = input.val();
        var td = input.parent("td");
        td.html(inputText);
        td.click(tdClick);
    });
```

メソッドattr  属性を取得したら、設定できるらしい
メソッドappend 引数にしめしたコンテンツを追加する
メソッドblur マウスポインタが外れた時に、実施するコマンドをバインドする
メソッドhtml 内容を書き換える

ここは全般的にみると、新しく作った入力BOXに対して、
クリック後にテキストを親の＜td＞要素のテキストに変更させる処理になっている

```javascript

    input.keyup(function(event){
           var myEvent = event || window.event;
           var keyCode = myEvent.keyCode;
           if(keyCode == 27){
               input.val(tdText);
           }
    });
 
    var inputDom = input.get(0);
    inputDom.select();
    td.unbind("click");
```

この先は、ほとんど意味不明。
ゴニョゴニョ書かれているけれども
そうしないといけないんだろう。。。
centos8.0でopenssh-serverの設定を行う

**yumを使ってopenssh-serverとvimをインストールする。**

    sudo yum -y install openssh-server
    sudo yum -y install vim

**vimを使ってssh_configを編集しセキュリティー設定を行う**

    sudo vim /etc/ssh/ssh_config

**キーボードの<font color="Red">a</font>をクリックした後以下のように編集**

    PermitRootLogin no
    PasswordAuthentication yes


**<font color="Blue">[esp]キー</font>をクリックし<font color="Red">:wq</font>でssh_configが保存される。**

**サービス起動&確認**

    sudo systemctl start sshd.service
    sudo systemctl status sshd.service

**でIPアドレス<font color="Blue">192.●●●.●●.●●</font>を確認することができる。**
   
    ip a



同じネットワーク環境にあるPCからターミナル(コマンドプロンプト )で以下のコマンドからssh接続できる。

    ssh -Y [ ユーザ名 ]@[ IPアドレス ]
[超よく見るやつ] Gitで自分の環境だけ無視するファイルを追加してコミットしないやつ

# 背景

あんまり使わないけど覚えておかないと面倒になるやつ。
調べるのもだるいので覚書しておく。

## .gitignore じゃあない。

あ、Windows環境やで

```
notepad .git/info/exclude
```

したら .gitignore とおんなじ感じで無視したいファイルを追加する

```
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

# ここらへんにてきとうに
```

## Gitのアレを更新する

あれだよ…ﾎﾗ…ｱﾚ…

```
git update-index --assume-unchanged <FILE_PATH>
```

おっけ、消えた。
LIFFと相性がいいのはFlex Message?それともTemplate Message?

LINE botといえばLIFFというLINE botと連携するWebアプリを作りたいときにとても便利なフレームワークです。このLIFFはLINE Developersで設定した独自のURLからアクセスして使うものですが、URLをそのまま使う方法もありますが、例えばbotのやり取りで取得した値をLIFFのリンクの中にパラメータとして付与して動作したいときがあります(つまり、```LIFF_URL?value=hoge```という形)。botのやり取りの中で動的に生成するときには、リンクのテキストをそのまま返信するよりもLINE botを使ってるならFlexMessageを使ってボタンを押したらリンクにアクセスして、LIFFを立ち上げるなんてことをやってみたいわけですよ。ところが実際にやってみるとハマってしまったので、その覚書です。

# FlexMessageを使ってみた
FlexMessageでボタンの実装はやったことありませんでしたが、[こちら](https://developers.line.biz/console/fx/)のシミュレータを使って簡単に作成出来ました。実際に動かしたところがこちらです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">結構ハマったけど、flex messageとLIFFの連携ができて良かった！ <a href="https://t.co/T4gxAuRtNM">pic.twitter.com/T4gxAuRtNM</a></p>&mdash; K.Miura (@k_miura_io) <a href="https://twitter.com/k_miura_io/status/1185623315911593984?ref_src=twsrc%5Etfw">October 19, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こちらは冒頭で話していたパラメータを付与していないパターンの動作ですが、問題なく動いています。そして、今度は同じFlexMessageでボタンで立ち上げるURLにパラメータを付与すると以下の画面が表示されます。

<img width="375" alt="IMG_6988.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170520/5f2d5410-41a3-19c8-29f8-53d6c6ecf7ba.png">

あれ？LINEアプリの方はすでに最新バージョンになっているのに、これはどういうことでしょう？パラメータを付与するURLはFlex Messageに対応していないのでしょうか？知っている方いらっしゃったら教えて下さい。

# 色々調べてみたら
やはりFlex Messageにパラメータを付与したURLを使っている事例は見つからず、仕方ないので他の方法を探してみました。すると、Template Messageが見つかりました。Flex Messageとよく似ていますが、こっちは予め決められたテンプレートに対してカスタムを行うメッセージです。こちらにもボタンの中に埋め込んだURLを実行するアクションを入れてみました。先程失敗したパラメータを付与したLIFF URLをこのテンプレートメッセージを入れて再度試してみたら、問題なくLIFFが立ち上がりました。

<img width="375" alt="IMG_6989.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170520/0c9567e9-eba3-4f6a-1fde-3d60db9bbcd8.png">

# この動作の違いは一体…
Flex MessageとTemplate Messageではアクションの違いがあることが分かりました。これは中で動作しているプログラムに違いでもあるのでしょうか？とりあえず、現時点での結論としては ~~「LIFF URLをそのまま立ち上げるだけならどちらでもいいが、パラメータを付与したLIFF URLを立ち上げるときにはTemplate Messageのほうが良い」となりました~~。
※この内容については、[補足記事](https://qiita.com/K_M95/items/a5da9abfa6f609e9467a)を書いたのでそちらをご覧ください。
Matlab 円の認識

matlabを使うことにより、多くの画像処理を簡単にすることができる。
その中で今回の記事は円の認識の方法についてまとめていきたいと思う。
1. 画像(ペイント）から読み取る
2. 画像ファイルを読み取って認識
3. リアルタイムで画像処理
この3段階で進めていく。(まず、1だけ投稿。2,3は時間に余裕があったら投稿していきたいです）
[参考記事 Acquisition Using the Image Acquisition Tool(英語版)](https://jp.mathworks.com/help/imaq/acquisition-using-the-image-acquisition-tool.html?s_tid=CRUX_lftnav)
#使用環境
- matlab 2019a 
- windows 10

#1. 画像(ペイント）から読み取る
下の画像内の円を認識していく。楕円も含んでいるため、どこまでが円と認識されるかのテストも含めてやってみる。(fig1.png)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/05906187-94c1-ddc4-5e83-aa8583a5cb75.png" width=40%>
##1.1画像を読み込む(+前処理）

```matlab:matlab
 rgb=imread(fig1.png);
```
本来はこの段階で、カラー画像からグレースケールへの変換➀やグレースケールから2値化のバイナリイメージを生成➁して、画像処理を進めていく方が計算量は少なくなるが、今回は変換は省略する。(変換する関数は以下の通りである）

```matlab:matlab
gray=rgb2gray(rgb) % ➀ カラー→グレー
BW=imbinarize(gray) % ➁ グレー→2値化
```
##1.2円の探索
ハフ変換を用いる方法でimfindcircles関数を使う
[参考記事 imfindcircles関数](https://jp.mathworks.com/help/images/ref/imfindcircles.html#d117e127960)
使用例は以下の通り

```matlab:matlab
 [centers, radii] = imfindcircles(A, [Rmin Rmax])
```
(入力引数)
(1) A <-探索したい画像(イメージ）を入力
(2)[Rmin Rmax] <- 探索する円の半径の範囲: 閉区間[Rmin,Rmax]を表し,Rmin<=r<=Rmaxに当てはまる半径rの円を探す
注意）あまり範囲を広くとりすぎると精度が落ちるので
　・Rmax < 3×Rmin
　・(Rmax - Rmin)<100
に収まるように範囲設定すること。（ただし本記事ではソースコードの簡略化のため、分割せずに書いている）

もし、難しいようであれば。以下のように範囲を分割した方がよい。

```matlab:matlab
	[CENTERS1, RADII1, METRIC1] = IMFINDCIRCLES(A, [20 60]);
	[CENTERS2, RADII2, METRIC2] = IMFINDCIRCLES(A, [61 100]);
```

(出力引数)
(1) centers <- 円の中心の座標
(2) radii<- 推定半径

##1.3 円の作成
viscircles関数を使って、上記で特定した円を書いていく。

```matlab:matlab
 viscircles(centers, radii,'Color','g')
```
オプションとして、'Color'を加えると、円の色を変更することができ（設定しなければ赤色）、bで青色、gで緑色というように指定できる。

#1.4 まとめ
全体のコードをまとめると以下のようになり、下の図のように緑色の囲われた3つの円を認識することができた。

```matlab:matlab
%コードまとめ
 %画像を読み込む
 rgb=imread(fig1.png);
 [centers, radii] = imfindcircles(rgb, [10 100])
 imshow(rgb);
 hold on;
 viscircles(centers, radii,'Color','g')
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/d3b6c3cc-bdc0-ffaa-df42-a9eec415153a.png" width=40%>
上図のように、緑色の囲われた円3つを認識できた！