OmniAICreator/Qiita-1.07M huggingface dataset:
ZabbixでWEB監視＆URL監視

WEB監視とURL監視って何ですか？状態からスタート。

#目的
AWSのEC2でWebサーバを構築したので、ZabbixでURLの死活監視を行います。
対象はApacheデフォルトのテストページ。
Webサーバにsshしてhttpdをstopしたら障害検知アラートが出るかのテストも行います。

#環境
■Webサーバ
Centos7系
Apache2.4
MySQL5系

■Zabbixサーバ
Centos7系
MySQL5系
※リージョンとセキュリティグループは同じ、インスタンスは別で構築

#参考にしたサイト
とてもわかりやすくまとめられており、大変勉強になりました。
http://www.wivern.com/security20170119.html

#エラー
グラフの設定まで完了したがデータが取れない。ブラウザで見れる＆Zabbix側の設定も間違いなし。
これは一体。。と思っていたらインスタンスのポート制限してたの忘れてた。
EC2インスタンスのインバウンドの80ポートを開けてアクセスを0.0.0.0/0にしてあげて解決（これが最適かはさておき）。
※Zabbixサーバのパブリックじゃなくてプライベートを許可すればいいのではと書いていて気がつきました

#気になったこと、次の課題
ZabbixのGUIトップページにWeb監視カテゴリがデフォルトで存在するのですが、これ何でしょうかｗ
もっとスマートにやれる設定だったり、カテゴライズができるのかな？
今回の範疇から外れるので割愛しますが、追って調べてみようと思います。

#知らなかったCLIコマンド
・バージョン確認
zabbix_server -V

・viの編集モードで全行を削除
:%d
[Excel]セルをクリックしたときに他のセルの値を変える（VBA無し）

これは夏休みの自由研究の一部を記事にしたものです。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">データの参照程度ならVBAを使わなくてもゴリゴリすればいろんなやり方で何とかなる事が分かりました。<br>旅行中に考えたアイデアがうまくいけば更新系もノンプロでできるはずなんですが・・・。後日試してみます。 <a href="https://t.co/gW6EE5v1Ft">pic.twitter.com/gW6EE5v1Ft</a></p>&mdash; パパセンセイ (@10mikiya) <a href="https://twitter.com/10mikiya/status/1030511327758835717?ref_src=twsrc%5Etfw">2018年8月17日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こんな感じでクリックするとセルの値が変わります。VBAは使っていません。
![選択動画.gif](https://qiita-image-store.s3.amazonaws.com/0/97601/ad94d09a-ea49-9c6d-0817-5080c35248ab.gif)

# いきなりお詫び
タイトルは少し語弊がありました。申し訳ありません。
正確には「セルをクリックしたように見せかけて他のセルの値を変える」です。
また、実際に同様の仕様を実装する場面があるのでしたらVBAで作った方が手軽で自由度も高いです。
VBAが使えない場面ではワンチャンあるかもしれませんがこれを実務で使用するのはあまりお勧めしません。
ネタと思って見ていただければ幸いです。

# ネタバレ
見る人が見たらこの下の画像だけで分かります。以降は読まなくても大丈夫です。
![ネタバレ1.png](https://qiita-image-store.s3.amazonaws.com/0/97601/a310da99-734d-110c-d5e4-11ab9f641e70.png)

# 解説
オプションボタンをセルの上に重ねているだけですね。
オプションボタンは開発タブから挿入できます。
また、リンクするセル(A15)を指定して、そのセルに書き込まれる数値をもとに条件付き書式で色を付けたり詳細データを引っ張ってきたりしています。
ただそれだけです。

ここで課題なのは1点。
オプションボタンの「◎」は列の非表示で見えなくすることができません。常に画面に表示されてしまいます。
ボタンを隠すにはちょっとしたコツが必要です。

それは**ウィンドウ枠の固定**を使うことです。
ウィンドウ枠の固定は、スクロールをしても指定した行や列を常に表示してくれる機能ですが、見せたくない部分を逆に隠すことができます。

やり方は簡単で、見せたくない列や行を画面外に外してから固定化するだけです。
今回の場合、ボタンが配置されているA列～B列付近を隠したいので、A列とB列が隠れるように横スクロールしてから画面を固定します。
↓イメージ
![ウィンドウ枠の固定動画.gif](https://qiita-image-store.s3.amazonaws.com/0/97601/e4a1f8d7-cc20-420c-9c3f-a161748a11d0.gif)
これでボタンを隠すことができます。左に横スクロールしようとしてもウィンドウ枠の固定が働いてA列とB列だけは表示されません。
ボタンが見えないのでなんとなくセルをクリックしているように見えます。実際はオプションボタンをクリックしているんですね。
勘の鋭い方はもうわかるかもしれませんが、このやり方、表がシートの左端付近にないと使えません。あとC列とD列付近もクリックできてしまします。さらに言えばセルが触りづらいです、コピペが大変です。

# ということで
使う場面は少ないですがどこかで活用出来たら幸いです。

# その他の自由研究

[[Excel]データを絞り込んで別シートに表示する（データ数が1万件以下の場合）](https://qiita.com/tomikiya/items/dcd195b5db46de11c31f)
[初心者向け] WindowsでGit (2024年12月決定版)


# Gitといってもインストール方法が多い

まず、検索するといろんな情報が出てくる。

* Cygwin + Git
* MinGW + MSYS2 + Git
* Git for Windows
* GitHub Desktop
* Windows Subsystem for Linux (WSL) + Git
* Windows Subsystem for Linux 2 (WSL2) + Git

何が違うのかわからない。
どれを選べばいいのかわからない。
ここでつまずく初心者多数。

# 実際どれを選べばいいか

長期的にみて、CygwinもMinGWも過去の遺産だよねと考えることは正しい。
だからと言って、WSL + Gitのみで完結するかというと、そうでもない。
Windows側で動くIDEからの連携等を考えると、WSL上のソフトウェアは圧倒的に使いにくい。

現在は、 **Git for Windows** 一択である。インストール方法はGit公式サイトからダウンロードしてインストールする方法と、wingetを利用する方法の２種類あるが、実態はどちらもGitHub上のGit for Windowsインストーラーを実行することに変わりないので、どっちを選んでもOK。

# インストール方法 (Git公式サイトからダウンロード)

1. Git for Windowsを[公式サイト](https://git-scm.com/)からダウンロードする。
1. インストーラーを実行する。
1. エディタの設定以外は全部デフォルトのままで十分。  
   設定はこっちの方がいいとか説明するサイトもあるが、初心者が一番使いやすい設定はデフォルトそのまま。  
   先にVisual Studio Code入れておけばデフォルトエディタにも設定してくれる。 

# 特徴

特徴として、

* Git公式からダウンロードできる公式環境
* インストーラーでインストールし再起動するだけで使えるようになる
* Git LFSやGit Credential Managerもインストールしてくれる
* Microsoftがちゃんとメンテナンスしている

が挙げられる。

ソフトウェアの実態はMSYS2上で動作しているため、MinGWとあまり変わりないが、それを意識せずに使えるところが大きく異なる。

また一緒にインストールされる、Git Credential Managerの使い勝手も良い。
GitHubやBitbucketへの接続の場合、ログインをブラウザで行うのでSSOや2段階認証に対応しており、セキュリティと使い勝手の両方を満たす。

# 問題点

一般的な利用だと問題ないが、一部の環境だとめんどくさいことになる。

* デフォルトでGit Credential Managerをインストールするので、HTTPS、SSH、GitHub、Bitbucket、Azure DevOps以外の認証方法を利用するとき面倒。  
  Google Cloud Source RepositoriesやAmazon CodeCommitなど、特殊な認証方式を使うときなどに困るかも。
* MSYS2上で動くので、ほかのMSYS2をインストールするとバージョン衝突が発生することがある。  
  ただ、すべてデフォルトを選択するとほぼ問題にならない。
node.jsでCSV出力(npm csv-writer)

# 概要 
- 【目的】手軽にCSV出力したい
- - 環境
    - Windows10
    - VSCode
    - Node v8.11.3
- 参考
    - [ npm cav-writer ](https://www.npmjs.com/package/csv-writer)
    - [ Object.keys() メソッド](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/keys)
    - [ map() メソッド ](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

#CSV出力サンプルコード
```js:csvwrite.js
const {createObjectCsvWriter} = require('csv-writer');
const csvfilepath =  __dirname+'/message.csv'
const csvWriter = createObjectCsvWriter({
    path: csvfilepath,
    header: [
        // {id: 'name', title: 'NAME'},      //Headerつける場合
        // {id: 'lang', title: 'LANGUAGE'}　 //Headerつける場合
        'name','lang' //Headerなしの場合
    ],
    encoding:'utf8',
    append :false, // append : no header if true
});
// Data for CSV
const records = [
    {name: 'Bob',  lang: 'French, English'},
    {name: 'Mary', lang: 'English'},
    {name: 'Alef', lang: 'English', age:23},
];
//Write CSV file
csvWriter.writeRecords(records)       // returns a promise
    .then(() => {
        console.log('...Done');
    });

```
作成されるCSV 

```:message.csv
Bob,"French, English"
Mary,English
Alef,English

```
# （本題？）Headerを自動でつけたい [Object.key]

Headerを出力したいObject配列から作成する。

```js
//ObjectのKeyを{item:key, title:key}配列で返す関数の例
function makeHeader(obj){
    let header=[]
    header = Object.keys(obj).map( v => ({ id:v, title:v }) ) 
    return header;
}
```

ヘッダー自動生成サンプル

```js:csvwrite_autoheader.js

const {createObjectCsvWriter} = require('csv-writer');
const csvfilepath =  __dirname+'/message.csv'

// Data for CSV
const records = [
    {name: 'Bob',  lang: 'French, English'},
    {name: 'Mary', lang: 'English'},
    {name: 'Alef', lang: 'English', age:23},
];

// Header Create from data
const csvWriter2 = createObjectCsvWriter({
    path:csvfilepath,
    // header: Object.keys(records[0])           // Headerなし 
    header:Object.keys(records[0]).map( v => ({ id:v, title:v })) // Header==Keys
})

//Write CSV
csvWriter2.writeRecords(records)       // returns a promise
    .then(() => {
        console.log('...Done');
    });
```
作成されるCSV

```bash:csv
name,lang
Bob,"French, English"
Mary,English
Alef,English
```
iOSのフォーム要素のスタイルをリセット

ECサイト制作時に、Chromeのデベロッパーツールでスマートフォンの表示を確認していました。
その後実機でチェックしてみるとカートに入れる箇所やセレクトボックスなどが、CSSの指定を無視して角丸とかになっていて困ったので対応を下記に記録。

```css
input[type="submit"],
input[type="button"] {
  border-radius: 0;
  -webkit-box-sizing: content-box;
  -webkit-appearance: button;
  appearance: button;
  border: none;
  box-sizing: border-box;
  cursor: pointer;
}
input[type="submit"]::-webkit-search-decoration,
input[type="button"]::-webkit-search-decoration {
  display: none;
}
input[type="submit"]::focus,
input[type="button"]::focus {
  outline-offset: -2px;
}

select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: none;
    outline: none;
    background: transparent;
}

button,
input[type="submit"] {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    padding: 0;
    border: none;
    outline: none;
    background: transparent;
}

input[type="radio"] {
    display: none;
}
input[type="radio"]:checked + label {
    background: #ff0000;
}

```
opnode_sum.pyによるHoudiniのノード一覧、VEXなどの関数一覧を取得する

Houdini16.5.557からopnode_sum.pyがノードの一覧だけでなく、VEX、houの情報までもがPython辞書で出力できるようになりました。

Houdiniはデイリービルドレベルでバグ修正だけでなく、新機能も追加されます。
そういった情報はSideFXのジャーナルのページ( https://www.sidefx.com/changelog/ )で確認することができます。
そのため、そこでopnode_sumで検索すると以下の内容が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154191/d1416331-23af-f6b6-bf1c-9e4f34c85342.png)
Houdini16.5.550からVEXが、さらに16.5.557からはHScript、エクスプレッション、SobVerbまでもの情報を出力できるようになっているじゃないですか！！！

このopnode_sum.pyは、Houdiniインストールディレクトリ/houdini/python2.7libsの直下にあります。
このディレクトリ内にはHoudini関連の便利なモジュールが他にも色々あります。典型的なのがtoolutils.pyです。
これはオンラインヘルプ( http://www.sidefx.com/ja/docs/houdini16.5/hom/tool_script )に使い方あるので参考にしてください。

#opnode_sum.pyによるJSONの出力
Houdini Terminal(Windowsならスタートメニュー->Side Effects Software->Houdini16.5.x->Utilities->Command Line Tools)を起動して、

Windows:
```hython %HH%/python2.7libs/opnode_sum.py > result.json```
Mac,Linux:
```hython $HH/python2.7libs/opnode_sum.py > result.json```

これで、JSONファイルとしてノード一覧などのリストをファイルとして書き出すことができます。
JSONファイルをFireFoxブラウザで開いてみるとこんな感じです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154191/e3e86596-ab15-6249-69f6-7efb3b83ea03.png)
Houdini16.5.550以前までのバージョンだとNodes、Shelvesの項目しかリストに出なかったのですが、EXPR、Verbs、Vex、hscriptまで出力されるようになっています！これは嬉しい機能追加ですね。

EXPRを展開:
利用可能なHScriptエクスプレッションの一覧が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154191/54b45744-b7f8-18d4-cc43-5b23cb0ba26a.png)

Nodesを展開:
ノードの一覧が表示されます。めちゃめちゃあります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154191/34a7bfc4-561b-84a3-2d86-d29972840179.png)

Shelvesを展開:
シェルフタブとその中に定義されているツール群の情報が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154191/642d5d8a-9a7c-29ee-7ce8-800151c579ca.png)

Verbsを展開:
Verbが表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154191/5119dae7-c3e2-dc5f-d838-d8a4cb86b057.png)
Verbって何？って思う人がいるかもしれませんね。
Verb="動詞"です。たしかコンパイルブロックへの対応のために提案されたものだったと思いますが、
通常のノードの処理は、"Houdiniが○○に対して△△を実行する"という命令形体です。Houdiniが主語(Subject)、○○が目的語(Object)、△△が動詞(Verb)です。英文法で言うと、SVOです。
複数ノードの組み合わせの処理を一つの処理形体にまとめるためには、目的語(Object)を共有して動詞(Verb)の部分だけを複数の組み合わせにできるようにさせたいのでこのような概念があり、Python SOPで使用します。
オンラインドキュメント( http://www.sidefx.com/ja/docs/houdini/model/compile#verbs )

Vexを展開:
VEX関数の一覧が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154191/a4f7415e-8323-f443-1c0f-5d0d938dad71.png)

hscriptを展開:
HScript関数の一覧が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154191/9af9db74-899f-a70c-c65e-72b95caac764.png)

#オプション
opnode_sum.pyのソースコードを見ると、オプションが用意されています。
`-p`:パラメータ情報も出力します。
`--briefparms`:名前/ラベルのパラメータ情報を出力します。

Windows:
```hython %HH%/python2.7libs/opnode_sum.py -p > result.json```
Mac,Linux:
```hython $HH/python2.7libs/opnode_sum.py  -p > result.json```

-pなし:
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154191/94bd612f-e05e-4022-c4b7-99c2e4d88917.png)
-pあり:
![image.png](https://qiita-image-store.s3.amazonaws.com/0/154191/3755556c-1874-5ca0-f067-c1817e873c37.png)

#まとめ
Houdiniはデイリービルドレベルで新しいノードが追加されたり、廃止されたノードが削除されたりします。
それはVEX関数もPython関数も同様です。
バージョンアップの度に、どのような変更が加えられたのかを調べる時にはSideFXのジャーナルのページで確認するのも大事ですがopnode_sum.pyを使うことで綿密に調べることができます。非常に便利ですね。
Vue CLI 3でsrcパスの変更方法

#はじめに
Vue CLI 3がリリースされ、2から乗り換えを検討するため、いろいろと検証した中でsrcのパスを標準のパス「{project_root}/src」から別の場所に変更しようとしてはまったので、解決方法をメモしておきます。(webpackに慣れている人なら何でもない事なんでしょうが、、)

#環境
* Vue CLI: 3.01
* Typescript: 3.0.1 

#パス構成
|  |           | デフォルト    | 変更後        |
|:-:|:-----------|:----------- |:------------ |
| 1 |ソースルート           | src/ |src/main/client/    |
| 2|出力先ルート          | dist/| src/main/resources/static/    |
| 3 |index.htmlテンプレート |public/index.html |src/main/client/public/index.html|

spring bootとの連携するためのフォルダ構成になっています。

#手順
@vue/cliのインストール、プロジェクトの生成についてはここでは記載しません。

@nunulkさんの記事が参考になります。
[Vue CLI 3.0 で TypeScript な Vue.js プロジェクトをつくってみる](https://qiita.com/nunulk/items/7e20d6741637c3416dcd)

###1. vue.config.jsの作成
プロジェクトルート直下にvue.config.jsを作成します。

vue.config.jsの詳細については下記を参照してください。
[Vue CLI 3 Configuration Reference](https://cli.vuejs.org/config/#global-cli-config)

```
const path = require('path')

module.exports = {
    configureWebpack: {
        resolve: {
          alias: {
            '@': path.join(__dirname, '/src/main/client') // 1. @の参照先の変更
          }
        }
    },
    outputDir: 'src/main/resources/static', // 2. 出力先
    pages: {
        index: {
            entry: 'src/main/client/main.ts', // エントリーポイント
            template: 'src/main/client/public/index.html', //3. index.htmlテンプレート
            filename: 'index.html' // 省略可
        }
    }
}
```

### 2.tsconfig.jsonの編集

```
...
// pathsの編集
"paths": {
      "@/*": [
        // "src/*"
        "src/main/client/*"
      ]
    },

...
// includeの編集
// src/** ..の部分を変更後のパスに書き換える
"include": [
    "src/main/client/**/*.ts",
    "src/main/client/**/*.tsx",
    "src/main/client/**/*.vue",
    "test/main/client/**/*.ts",
    "test/main/client/**/*.tsx"
],

```
以上です。

# まとめ

簡単な設定変更なのかもしれませんが、数時間悩みました。
私自身フロントエンドのビルドツールはまだまだ経験がありませんので、間違いがあればご指摘いただけると幸いです。

この次はspring boot 2(+ kotlin) + gradle + vue cli3( + typescript + scss)あたりで環境構築についての記事が書けたらいいなと思います。
Go言語に関するサイトをまとめてみた【備忘録】

# Goの公式ページ
- [公式ページ](https://golang.org/)
- [日本語ページ](http://golang.jp/)


# 開発環境
## gocode
https://github.com/nsf/gocode
Goプログラミングにオートコンプリート機能を実現するためのコマンドラインツール。

## Visual Studio Code
https://code.visualstudio.com/
Micosoft社から提供されているフリーの開発環境。
【HTML】ブラウザでのメモ帳機能

#### テスト環境
* OS
    * macOS High Sierra Version 10.13.6
* ブラウザ
    * Google Chrome Version 68.0.3440.106 (64-bit)
    * Firefox Quantum 61.0.2 (64-bit)
    * Safari Version 11.1.2 

---
### 仕様
ブラウザでは、即席にメモ帳機能を使用できます。

HTML5の「contenteditable」属性を利用し、HTMLタグに対して指定することでページ内全体が編集可能になります。

### 使い方
URLに以下の文を入力することで、使用できます。

```
data:text/html, <html contenteditable>
```

入力した内容は、テキストファイルとして保存することもできますが、
検証したところ、以下3つの中にFirefoxだけが対応できます。

| Browser | Save as text file? |
|:--------|:-------------------|
|Chrome   | NO     |
|Firefox  | Ctrl+S |
|Safari   | NO     |

また、HTMLタグにスタイル文を追加することで、Backgroun, Font, Layoutなどの属性を変更することができます。尚、検証したところで、ChromeとSafariは、当ファイのStyle属性をサポートしますが、Firefoxは対応できません。

```
data:text/html, <html contenteditable><style>body{background-color:#000000;color:#00FF00;font-family:menlo;margin:50px 50px}</style>
```


| Browser | Style Availability |
|:--------|:-------------------|
|Chrome   | YES |
|Firefox  | NO  |
|Safari   | YES |



#### 参考
[contenteditable でブラウザでメモを書く](http://please-sleep.cou929.nu/instant-browser-note-useing-contenteditable.html)
[スタイルシートリファレンス（目的別）](http://www.htmq.com/style/)
[原色大辞典](https://www.colordic.org/)
Golangでクラスを分割したら疑問点が出た話

## 前提
* [Golangで超シンプルにローカルでwebアプリ起動するところまで](https://qiita.com/nitt_san/items/aa535a1b8c02c32ddb74)　の続き
* 筆者はほとんどJavaしかやってきていない

## 目的
* `handler()`を別クラスにわけたい。mainがあるクラスに機能が集約するのが生理的に気持ち悪いため。

## やったこと
### ディレクトリ構成
``` Directory
golang_webapp_sample
└── src
    └── main
        ├── golang_webapp_sample.go
        └── handler
            └── http_handler.go
```

### ソース
とりあえず`handler()`を別クラスにする。　
この時`Handler()`と先頭大文字にすることで外部参照可能なメソッドとなる。

```http_handler.go
package handler

import (
	"fmt"
	"net/http"
)

func Handler(writer http.ResponseWriter, request *http.Request){
	fmt.Fprintf(writer, "Hello World!")
}

```
次にメインクラス。
importは以下のように`"golang_webapp_sample/src/main/handler"`とすれば別クラスのメソッドが呼べる。

```golang_webapp_sample.go
package main

import (
	"golang_webapp_sample/src/main/handler"
	"net/http"
)

func main() {
	http.HandleFunc("/", handler.Handler)
	http.ListenAndServe(":8080", nil)
}
```

参考：[Go言語のpackageの作り方: 長くなったコードを別ファイルに切り出す方法](https://qiita.com/suin/items/f4ad02e4123c8a3c75eb)

### 確認
1. `go run golang_webapp_sample.go` で起動  
1. http://localhost:8080/ にアクセス
1. 画面に `Hello, World!` と表示されたら勝ち   
![screenshot2.png](https://qiita-image-store.s3.amazonaws.com/0/162984/631a1dbe-10c4-63cf-4ff9-9e78d3a5dfcb.png)

勝った。

## この段階で発生した疑問点
### クラス…？
なんとなくファイル名を分けてこそみたが、よくよく考えてみると、**ここまでクラス定義なんかしていない**ことに今更気づく。
参考： [golang メソッドについてまとめてみた。](https://qiita.com/pei0804/items/2a3010df39623fadc3c6)

> ではクラスの説明〜と言いたいところなんですが、golangにはクラスという概念がありません。ではクラスの説明〜と言いたいところなんですが、golangにはクラスという概念がありません。なので、メソッドは型に対して紐づくものまででそれ以上はありません。

なるほど、**Golangにはクラスという概念はない。**
メソッドの先頭文字が大文字かどうかで参照可能範囲が決まるだけである。
目的に`mainがあるクラスに機能が集約するのが生理的に気持ち悪い。` と記載したが、この発想が前提から間違っていたのだ。
(とはいえ、振る舞いを役割によって分割するのは設計上好ましいことに間違いはないだろう。結合は疎に、凝集度は高く)

### メソッドの引数…？？(未解決 → 解決)
…？これ何で動いてんの？

```golang_webapp_sample.go
〜〜
	http.HandleFunc("/", handler.Handler)
〜〜
```

```http_handler.go
〜〜
func Handler(writer http.ResponseWriter, request *http.Request){
〜〜
```

* **`handler.Handler`がもうわからない。**百歩譲って`handler.Handler()`ならわかる。そんなメソッドは定義していないが。
* **引数いらんの？？？何で？？？？**
* メソッドと思って書いた`Handler()`は、**メソッドのようでメソッドじゃない、少しメソッドな関数**なのではという仮説。ここはGolangワールド、Javaのお作法とは違うのだ。

#### 8/26 追記
@K-juju さんからのコメントにて腹落ち。ありがとうございました！

```
func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
    DefaultServeMux.HandleFunc(pattern, handler)
}
```
> http.HandleFuncの定義は上記になります。
> 引数を見ていただくとわかると思うのですが、第二引数の型が func(ResponseWriter, *Request) となっています。

> 今回の場合で考えてみると、
> handler.Handler の型は func(ResponseWriter, *Request) です
> handler.Handler() は(引数は省略します)そもそも返り値がないので、型とかありません。

> おそらく勘違いされている点は、

> http.HandleFunc("/", handler.Handler)
> の handler.Handler の部分は、関数を引数としているだけで、関数を呼び出しているわけではないです。
> したがって引数はいらないということだと思います。

**関数を引数としているだけで、関数を呼び出しているわけではない**
Java的にメソッドじゃメソッドじゃと思ってたんですが、そもそもこの時点で関数を呼び出してるわけじゃなかった。
ありがとうございます！

## 次やること
* ~~上記、メソッドについての疑問を解決する~~ → 解決
* Dockerのimageにして起動する → [https://qiita.com/nitt_san/items/6cba1e422dcdd6098f06](https://qiita.com/nitt_san/items/6cba1e422dcdd6098f06)
* Kubernetesに放り込んで色々試す
メール認証を実装してしまった人のためのTwitterログイン認証の実装方法

https://qiita.com/keeya/items/c96a0393c76f5560ee41
https://qiita.com/puremoru0315/items/f1d459b663fd3b715dee
https://qiita.com/To_BB/items/01863aa50d628c069b64

Twitterログイン認証を解説する記事は数多いですが、Railsチュートリアルなどでメール認証を実装してしまった後だと、残念ながら上の記事にあるコードをそのままコピペしてもログイン認証は機能しません。

なんでって？
`self.find_or_create_by(provider: provider,uid: uid)`では、バリデーションに弾かれてしまうからです。

`find_or_created_byメソッド`は、引数で渡したカラムでfindをかけて引っかからなかったらcreateします。
createはsaveまで行ってしまうので、メール認証で設定したemailやpasswordのvalidatesで弾かれてしまいます。

この問題を解決するためには、上の記事にあるfind_or_created_byを`find_or_initialize_by`に変更する必要があります。
このメソッドは、引数で渡したカラムでfindをかけて引っかからなかったらnewしてくれます。
あとは、インスタンスにバリデーションを回避できるだけの情報を与えて、saveすればいいだけです。

```models/user.rb
 #Twitter認証用メソッド
  def self.find_or_initialize_from_auth(auth)
    provider = auth[:provider]
    uid = auth[:uid]
    user_name = auth[:info][:name]
    email = "#{('a'..'z').to_a.shuffle[0..10].join}@gmail.com"
    password = "foobar"
    image_url = auth[:info][:image]
    profile   = auth[:info][:description]

    self.find_or_initialize_by(provider: provider, uid: uid) do |user|
      user.name = user_name
      user.email = email
      user.password = password
      user.image_url = image_url
      user.profile = profile
      user.activated = true
    end
  end
```

```sessions_controller.rb
def twitter
    @user = User.find_or_initialize_from_auth(request.env['omniauth.auth'])
    @user.save
    session[:user_id] = @user.id
    if session[:user_id]
      flash[:success] = "ユーザー認証が完了しました。"
      redirect_to @user
    else
      flash[:danger] = "ユーザー認証に失敗しました。"
      redirect_to root_url
    end
  end
```


バリデーション以外にも、**activatedをtrue**にするのも忘れないようにしましょう。

ちなみに、僕はemailをランダム生成してますが、API設定の方でPrivacy Policy URLとTerms of Service URLをきちんと設定すれば、email情報も取得できるそうです。

https://qiita.com/shitake/items/fd592bce7d0be8fadd47

omniauthを使って他にどんな情報が取得できるかは、以下のリンクが参考になります。

https://github.com/arunagw/omniauth-twitter#authentication-hash

以上。
誰かの役に立ちますように。
UnityEditorのLayoutを切り替えれるTabWindowを作ってみた

# UnityTab

UnityEditorのlayoutを切り替えるWindowを作成しました。
[UnityTabSample](https://github.com/MizoTake/UnityTabSample)
![Sample.gif](https://qiita-image-store.s3.amazonaws.com/0/127761/2e4b67ae-0d51-78d2-6b04-356d72767bcd.gif)

Unityでアニメーションをしよう、GameViewを大きくみよう、カスタムViewをメインでいじる...etc
のように制作をしていれば、切り替えたいタイミングが出てくることもあるかともいます。
なので、別Windowにtabを出して切り替えれたら便利じゃないかな？と思い作りました。

VisualStuidoでForm使って制作したので、Windowsのみの対応となっています。
[UnityTab](https://github.com/MizoTake/UnityTab)

プロジェクトは勢いで作って公開してます。
もしかすると、Windowsでも動かない場合もあるかもしれません。
UnityEditorのlayoutファイルである*.wltは、自分の場合/Users/UserName/AppData/Roaming
/Unity/Editor-5.x/Preferences/Layouts/*.wltという感じにあったのでEditor-5.xが違うかもしれません。

## 少し解説

dll側は大したことはしてなく、Windowを出して*.wltを読み込んでTabControllerに突っ込んでTabを出してるだけです。
Tabを押したときのeventをUnityに通知する方法が思い浮かばなかったのでdelegateを渡すことで解決させています(力技感あるので変えたい…)

Unity側は

```csharp:TabEditor.cs
public class TabEditor : Editor
{
	[MenuItem ("UnityTab/LaunchWindowStart")]
	static void LaunchWindowStart ()
	{
		UnityTab.TabMain.Launch (
			(int index) =>
			{
				var path = UnityTab.TabMain.GetFilePath[index];
				var tyWindowLayout = Type.GetType ("UnityEditor.WindowLayout,UnityEditor");
				var method = tyWindowLayout.GetMethod ("LoadWindowLayout", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof (string), typeof (bool) }, null);
				var assetPath = Path.Combine (Directory.GetCurrentDirectory (), path);
				method.Invoke (null, new object[] { assetPath, false });
			});
	}

	[MenuItem ("UnityTab/LaunchWindowStop")]
	static void LaunchWindowStop ()
	{
		UnityTab.TabMain.Stop ();
	}
}
```

となっており、またもや力業ぽいです。というか正式なAPIが提供されてないけど、メソッドたたきに行ってます。

[WindowLayout.cs](https://github.com/Unity-Technologies/UnityCsReference/blob/cc0513fdae7a5624a12f99f3a05bd0a82dd9a366/Editor/Mono/GUI/WindowLayout.cs)
を参照するとlayout系のメソッドが読めます


## まとめ
結構力業を使ってるところがあるので、今のままだと使えない時がいずれ来るかもしれません。

使ってみたい方は使えるうちにお願いします。

今後は
- タブを可変にして好きなやつだけ追加できるようにする
- MacOS等の対応
- UnityEditorの上に追従するようにする

とか考えてますが、いつできるかはわからないです。やれればやります。(やるならElectron化とかかも)

変数命名とかFormは詳しくないので変なところある気はしてますが、ご容赦ください…
Jestでd.tsがファイルあるときCoverage出力がエラーになる場合の対処法

# はじめに

[restify + TypeScript + Jestの開発環境をセットアップしてみる](https://qiita.com/bathtimefish/items/82f886f6d2353af14e7a) な感じでTypeScript + (TS)Jestで開発しているときに `"collectCoverage": true` としてカバレッジレポートを出そうとして以下のようなエラーが出た

```
Running coverage on untested files...Failed to collect coverage from /Users/user/src/project/types/example.d.ts
ERROR: Debug Failure. Output generation failed
STACK: Error: Debug Failure. Output generation failed
    at Object.transpileModule (/Users/user/src/project/node_modules/typescript/lib/typescript.js:100526:29)
```

どうも `*.d.ts` がカバレッジ計測に含まれてしまってエラーになっているようだ。`*.d.ts`が入っている`types`フォルダをカバレッジ対象から除外しないといけない。

# 対策

[Code Coverage: Uncovered lines/statements in file that only defines interfaces.](https://github.com/kulshekhar/ts-jest/issues/378)

```package.json
"collectCoverageFrom": [
  "src/**/*.ts",
  "!src/**/*.d.ts"
]
```

`"!src/**/*.d.ts"` がミソ。`!`を先頭につけたパスはカバレッジから外れるみたい。

これで通った。
cloud9 (node)でnode.jsとnpmを最新にする

cloud9のnodejsとnpmのデフォルトのバージョンをアップデートする際のメモ。

デフォルト（2018年8月現在）

```
$ node -v
v6.11.2

$ npm -v
3.10.10
```

nodeのバージョンアップ
（バージョンは任意のものを。ここでは2018年8月現在の推奨版(v8.11.4)をインストール）

```
$ nvm install v8.11.4
$ nvm alias default v8.11.4

$ node -v
v8.11.4
```

npmのバージョンアップ

```
$ npm update -g npm

以下を実行するように警告が出たので実行
$ npm i -g npm

$ npm -v
6.4.0
```

備考：
anyenvでnodeを管理しようとするとnpmのアップデートでエラーがでて、ググっても原因が解消できそうになかった。
エラー内容は「Error: Cannot find module 'strip-ansi'...」みたいなエラー
WindowsのDocker環境でnpm install実行時にエラーが出た場合の対処法メモ

このやり方が正しいとは思えないけどとりあえずメモ。

# 要点
* `npm install`はコンテナでマウントされていないディレクトリで行う
* `npm install`には`--no-bin-links`オプションを付ける

# 事象
Dockerのコンテナ内で`npm install`を行うと以下のようなエラーが出ることがある。

```bash
npm ERR! path /usr/local/hoge/node_modules/abbrev/package.json.920591357
npm ERR! code ETXTBSY
npm ERR! errno -26
npm ERR! syscall rename
npm ERR! ETXTBSY: text file is busy, rename '/usr/local/hoge/node_modules/abbrev/package.json.920591357' -> '/usr/local/hoge/node_modules/abbrev/package.json'

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2018-08-04T08_11_53_004Z-debug.log
```

調べた結果、ホストであるWindowsからコンテナにマウントされているディレクトリで`npm install`を行うとこのようなエラーになるらしい。
（試していないが、Vagrantの共有フォルダでも同じことが起こるらしい。）

例えば、以下のようなコマンドで立ち上げたコンテナの`/usr/local/hoge`で`npm install`を行うとエラーになる。

```bash
$ docker run hogehoge -it -v `pwd`:/usr/local/hoge
```

# 解決策

要は、マウントされているディレクトリで実行しなければいいのだから、以下のようにしてエラーを回避した。

* マウントされていないディレクトリへpackage.jsonを移動
* package.jsonを移動させたディレクトリで`npm install --no-bin-links`を実行
* node_modulesディレクトリを元々`npm install`を実行する予定だったディレクトリに丸ごと移動

```bash
$ cd /tmp
$ cp /usr/local/hoge/package.json
$ npm install --no-bin-links

 :
 :

$ mv ./node_modules /usr/local/hoge/
```

`--no-bin-links`オプションを付けることで、`npm install`の過程でシンボリックリンクを作成しなくなる。
Virtual Boxでは共有フォルダにシンボリックリンクを作成できないため、このオプションを指定しないと、node_modulesディレクトリをマウントされているディレクトリに移動させるときにエラーとなってしまう。

参考
[【npm】【Vagrant】Vagrantの共有フォルダ上でnpm installすると失敗する原因と、–no-bin-linksオプションをつけると成功する理由](http://eiua-memo.tumblr.com/post/117361529158/npmvagrantvagrant%E3%81%AE%E5%85%B1%E6%9C%89%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E4%B8%8A%E3%81%A7npm)
pythonでタイムゾーンを反映した今日の日付を取得する

#はじめに
python3の標準ライブラリであるdatetimeでは、以下のようにtimezoneの設定が可能です。

```python
from datetime import datetime, timedelta, timezone

JST = timezone(timedelta(hours=+9), 'JST')

now = datetime.now(JST)
print(now)
print(type(now))
```

```text:実行結果
2018-08-25 22:55:19.911794+09:00
<class 'datetime.datetime'>
```



しかし、日付のみの形式であるdatetime.dateクラスで
タイムゾーン反映済の現在日付を取得したいような場面では、ひと手間必要になります。



#今日の日付を取得する
結論を述べると以下のようにdate関数を使うのがBESTです。

```python
from datetime import datetime, timedelta, timezone

JST = timezone(timedelta(hours=+9), 'JST')

now = datetime.now(JST)
today = now.date()
print(today)
print(type(today))
```

```text:実行結果
2018-08-25
<class 'datetime.date'>
```

#できなかったパターン
以下のようにした場合、タイムゾーンが反映できた場合と、できない場合がありました。
timezoneで指定した時間がモジュールのどこかに保存されて、today関数に影響を及ぼすのでしょうか？

```python
from datetime import datetime, timedelta, timezone

JST = timezone(timedelta(hours=+9), 'JST')
today = datetime.today()
```

#おわりに
できなかったパターンの原因わかる方いらっしゃいましたらご助言お願いします！

#参考
Python3のdatetimeはタイムゾーンを指定するだけで高速になる
https://qiita.com/mattsu6/items/5511c5631e7a54550f7f
【PHP】連想配列向けのarray_diff

[array_diff](http://php.net/manual/ja/function.array-diff.php)の連想配列対応バージョン

```php
function array_diff_recursive($keys, $array1, ...$arrayn)
{
	foreach ($arrayn as $arrayi) {
		$array1 = array_udiff($array1, $arrayi, function($a, $b) use ($keys){
			foreach ($keys as $key) {
				$cmp = $a[$key] <=> $b[$key]; 
				if ($cmp) return $cmp;
			}
			return $cmp;
		});
	}

	return $array1;
}
```

`$array1`とその他いくつかの`$arrayn`を`$keys`について比較し、`$array1`にのみ存在する要素を返します。

```php
<?php

$a = [
    [ 'id' => 123, 'name' => aa, 'removed' => true, 'state' => 2 ],
    [ 'id' => 4532, 'name' => bb, 'removed' => false, 'state' => 1 ],
    [ 'id' => 772, 'name' => cc, 'removed' => true, 'state' => 0 ],
    [ 'id' => 6956, 'name' => dd, 'removed' => true, 'state' => 0 ],
    [ 'id' => 832, 'name' => ee, 'removed' => false, 'state' => 1 ],
];

$b = [
    [ 'id' => 498, 'name' => ff, 'removed' => true, 'state' => 2 ],
    [ 'id' => 4532, 'name' => bb, 'removed' => false, 'state' => 1 ],
    [ 'id' => 832, 'name' => ee, 'removed' => false, 'state' => 1 ],
];

$c = [
    [ 'id' => 498, 'name' => ff, 'removed' => true, 'state' => 2 ],
    [ 'id' => 783, 'name' => gg, 'removed' => false, 'state' => 1 ],
    [ 'id' => 6956, 'name' => sd, 'removed' => true, 'state' => 0 ],
];

$d = array_diff_recursive(['id'], $a,$b,$c);
print_r(array_keys($d));
/*
Array
(
    [0] => 0
    [1] => 2
)
*/

$d = array_diff_recursive(['id','name'], $a,$b,$c);
print_r(array_keys($d));
/*
Array
(
    [0] => 0
    [1] => 2
    [2] => 3
)
*/
```
GoogleAppsScriptでTwitter上で動作するタイマーを作ってみた

# 概要

GoogleAppsScript(以降GAS)とTwitterAPIでTwitter上で特定のツイートをしたらタイマーをセットし、指定時間にリプライを返すアプリを作ってみた。全部無料。
[リポジトリ](https://github.com/jiro4989/twit-timer)も一応作った。ソースコードとGASのプロパティ情報とかも全部明記してます。
**自分用に作ったので他の人に対してはタイマーは機能しないはず。動かしたい場合は自身でTwitterAPIを使えるようにしてシステム構築してください:innocent:**

## なぜ作ったか

サーバレスなWebアプリを作ってみたかった。
定期実行を利用したアプリを作る場合は、cronを動かすために何らかのサーバを用意しないといけないけれど、それをサーバレスに実現するための選択肢にGASがあったので、今回それを試してみた。

GASには定期実行トリガーというものがあって、毎分とか、何時から何時みたいな特定の時間指定で自動でスクリプトを実行することができる。
今回のアプリはその定期実行トリガーを使用してタイマーを作った。

## 使用例

![2018-08-25-221605_1920x1080_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/69665/dd9f1475-2925-a376-c2b8-26b91c5c1ed7.png)

こんな感じ。自分のメンションリストを取得するのと、自分の名前しか許可してないはずなので、他のユーザが自分宛てに「@jiro_saburomaru timer 3m ラーメン」とかやっても多分動かないはず。動いてしまったら僕の実装バグです。
あとユーザ名に時刻が設定されているのもGASで作った全く別のアプリだけれど、それについては今回は触れない。

## 使用したサービス

- GoogleAppsScript (処理ロジック,定期実行トリガー)
- GoogleSpreadsheet (DB)
- TwitterAPI (画面表示)

## 処理フロー

処理イメージは下記のシーケンス図の通り。実装前に処理フローを整理しておきたかったのでPlantUMLで書いた。

![sequence.png](https://qiita-image-store.s3.amazonaws.com/0/69665/76a731d3-6492-f6c4-28ad-9f499751e354.png)

処理の肝は3つの定期実行トリガー。

1. (毎分)タイマーツイートで返信する時間をDB(GoogleSpreadsheet)に登録する
2. (毎分)時間になった旨をツイートする
3. (毎日午前2時)DBのクリーンアップ

### タイマーツイートで返信する時間をDBに登録する

毎分自身のメンションリストを取得して、タイマーセット関連のツイートの有無をチェックする。
存在したらDBに「何時に時間になった旨をツイートするのか」の情報を登録する。

注意点は、GASのトリガーは最短でも毎分起動までしかできないので、秒指定のタイマーはセットできないこと。

### 時間になった旨をツイートする

毎分DBから論理削除フラグのたっていないレコードを取得して、タイマー系のレコードが存在するかをチェックする。
存在した場合に、GASの現在時刻(JST)がタイマー時刻より超過しているかをチェックする。
超過していた場合はリプライして、レコードに論理削除のフラグを立てる。

![2018-08-25-224120_1920x1080_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/69665/e96193a8-7bb5-e8d9-e06e-1cb6e432bf1f.png)

### DBのクリーンアップ

DBから取ってこれるレコード数には上限があるので、定期的にDBに存在するリプライ済みのレコードを削除する必要がある。
毎日深夜２時に論理削除フラグのたっているレコードをDBから物理削除してしまう。
上記の画像のデータはdone_flagがtrueなので、明日の深夜2時には物理削除される。

## 所感

**すべて無料**かつ**サーバレス**でDBとも連携してコンパクトなWebアプリが作れることがわかった。
GoogleSpreadsheetはDBとして非常に有用で、GASとすごく連携しやすい。
無料でcronとDBまで使えてしまうのでエンジニアの遊び場としてはすごく良い環境が整ってると感じた。

ただしGASはJavascriptでしかもES6をサポートしてないので比較的新しいJS記法を使えない。
この問題を解決するアプローチはググったら色々出てくるけれど、僕の場合は諦めて古い書き方を我慢する方針にしました。
まぁ、ブラウザのIEなどをサポートすることを徹底してる企業なのでES6をサポートするわけないか...
[Google Javascriptコーディング規約和訳](http://cou929.nu/data/google_javascript_style_guide/)

## このアプリの問題点

毎分TwitterAPIを2回叩くので1時間のTwitterAPIの使用回数上限をかなり圧迫する。
(数年前の記憶だけれど1時間あたり180くらいが上限だったかな...)
なので、一つのアカウントで他にもTwitterAPIを使うアプリが存在するとそっちに影響がでる可能性がある。
Python入門直後にやった方がいいと思うこと

# 概要
ProgateやPythonの入門書を読んだ後に何したらいいか分からないという人をよく見かけるので、自分なりの経験をもとに考えをまとめてみようと思います。

結論から言うと**「プログラミングに慣れる、プログラミングによる問題解決の経験値を積む」**という目的で、**ディレクトリ操作**をオススメします。

以下、なんでディレクトリ操作がオススメなのか解説していきます。



# 対象
- Python勉強し始めたばかりの人
- プログラミングでやりたいことが見つかっていなくて次に何を勉強したらいいか分からない人
- Pythonをもっと使えるようになりたい人



# プログラム入門後の課題
Pythonに限らない話ですが、プログラミング言語の基本的な文法を少し触ったあとに**「次にどうしたらいいのかなぁ」**という状態になってしまうことがあります。

![nayamu_boy2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250063/55fc4f4b-8cc8-877e-b932-5f0f9014aa9c.png)
⬆︎
「次にどうしたらいいのかなぁ状態」
  
  
明確に作りたいものがあってプログラミングを始めた人は、作りたいものに必要なことを自分で調べて、次にやるべきことを作り出していけると思います。
その一方で少しずつプログラミングの経験を積んでいってから自分のやりたいことを見つけるタイプの人もいると思います。

後者のタイプは上記したような「次にどうしたらいいのかなぁ状態」になってしまい、結果、Progateを何週もしたり、基礎の本を何回も写経するというループにはまってしまうのではないかと思います。

![pose_necchuu_computer_woman.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250063/9870f0d9-d093-dddf-4611-f6a68807f6f8.png)
⬆︎
「取り憑かれたように本を何周も写経する人」
  
# よくあるアドバイス
Twitterとかで「入門後に何したらいいいですか」という質問に対して、よく見るアドバイスとして以下のようなものがあります。

- 「自分の作りたいものを見つけてそれを作りなよ。」
- 「他の人のプログラム（ゲームとかサイトとか）を読んだり、改造したり、真似してみたら。」
- 「機械学習楽しいよ。流行っているしね。」

どれもためになりそうなアドバイスなのですが、こういうのは

**実際にやろうとすると調べることが多い。
-> プログラム書く時間より調べている時間の方が多くなる。
-> 飽きる。疲れる。挫折する。**

![pose_zasetsu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250063/f1100124-7169-fbe6-a989-91bfe3e0b88b.png)


になると思います。自分だったらこうなります。


Pythonの基本的なことを勉強したら、その後はプログラムを書く回数を増やして慣れていく必要があると思います。しかし、例えばゲームは実現するための予備知識が多くて、手を動かすまでに挫折してしまう可能性が高いと思います。


機械学習に関しては、最近ではAidemyとかUdemyで初心者にもとっつきやすい講座があるので、機械学習興味あるんだという人はそういうのやるのもいいと思いますが、こういうものはPython以外の知識も必要になってくるので、Python入門後は、まずはPythonに慣れてから講座を受けるのがいいと思います。
（機械学習やりたいという人は、やりたいこと見つかっているので、今回の課題にはぶつかってないですが。）



# Python入門直後にやってみたほうがいいと思うこと
最初に書きましたが、**ディレクトリ操作に関するプログラムを書く**がいいと思っています。

ディレクトリ操作というは例えば

- フォルダの中のファイルのサイズ一覧を出力する。
- フォルダの中の全てのファイルの名前を変える。
- フォルダの中の画像ファイルの一覧をテキストで出力する。
- フォルダの中の特定の名前のファイルを別のフォルダに移動する。

などです。
キーワードは**「フォルダの中のあるファイルに対して〜する」**です。

なぜこれがオススメなのかというと

**1. 使用するモジュールが簡単なものが多い。**（調べることが少ない）
**2. サンプルコードがたくさんある。**（参考資料がたくさんある）
**3. フォルダ内の複数ファイルを操作するプログラムは実用的**（日常の問題をプログラムで解ける）

だからです。
特に重要なのは3です。



# 実用的なことがいい理由
作るプログラムが実用的（な課題に関するもの）だと、**プログラムを書くきっかけが多くなります**。

「フォルダ内の複数ファイルを〜したい」というのは、プログラマが仕事をする際によくある課題です。
また、プログラマ以外の仕事でもこういった課題がよくあると思います。書類を〜したいとか。あとは趣味で写真撮ったりする人が画像を整理するときとか。

こういうちょっとした課題は日常のあらゆる場面に存在するので、その都度「Pythonで自動化してみよう」ということをやっていくと、

**課題を見つける
->Pythonで書いてみる
->課題が解決する
->嬉しい楽しい
->Pythonに慣れる、できることが増える
->また新しい課題を見つける**
・
・
・
になります。

私は、プログラムを書いていて嬉しいと思う瞬間の一つに**「困っていることを解決できたとき」**というものがあります。

ゲームとかサイトを作るのも良いと思うのですが、最初からみんなに使われるような良いものを作るのは難しいと思います。
経験が浅いうちは「作ったけど誰にも使われない->楽しくない」ということになったりします。

「フォルダ内の複数ファイルを〜したい」という類の問題は誰しも抱える問題だと思うで、解決するプログラムを書くと、ゲームのプログラムなどよりはプログラムを使ってくれて喜んでくれる人が多いのではないかと思います。



# 具体的に勉強すること

Pythonでディレクトリ操作をするには以下モジュールを使います。

- os
- shutil

使い方は簡単なのでサンプル見ればわかると思います。
以前まとめ記事書いたので参考にしてください。
[Pythonでディレクトリ,ファイル操作のやり方まとめ](https://qiita.com/takurooo/items/f648e8e7cd1da4b1b61c)

画像を〜したいという場合は、PILライブラリとか必要になります。標準ライブラリではないのでインストールする必要ありますが。




# まとめ

ディレクトリ操作は地味ですが、日常的な問題をプログラムで解決するというのは楽しいです。そういうことを続けていくとプログラミングの考え方やPythonの知識が向上していって、脱初心者できるのではないかと思います。
AWSの名前付きプロファイル非対応ツール用にdirenvで自動でアクセスキーをロードする

# はじめに

AWS関連ツールでは[名前付きプロファイル](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-multiple-profiles.html)によって認証情報を切り替えることができます。

しかし、ときどきこのプロファイルに対応していないツールがあり、その場合は個別にアクセスキーIDとシークレットアクセスキーを渡す必要があります。

その都度キーを設定するのはイマイチなので、[direnv](https://github.com/direnv/direnv)でプロファイル名を指定するとAWS CLIの設定から情報を取り出して環境変数に設定してくれる設定を用意しました。

# direnvの設定

設定は`~/.config/direnv/direnvrc`に行います。

```sh:~/.config/direnv/direnvrc
use_aws_profile() {
  profile_name=$1

  export AWS_DEFAULT_PROFILE=$profile_name
  export AWS_PROFILE=$profile_name

  export AWS_ACCESS_KEY_ID=$(aws configure --profile $profile_name get aws_access_key_id)
  export AWS_SECRET_ACCESS_KEY=$(aws configure --profile $profile_name get aws_secret_access_key)
  export AWS_DEFAULT_REGION=$(aws configure --profile $profile_name get region)
  export AWS_REGION=${AWS_DEFAULT_REGION}
}
```

AWS CLIの`configure`サブコマンドを利用して値を取り出しています。


# 使い方

この設定を行ったあと、必要な場所で`direnv edit`で次のように設定すると自動でロードされるようになります。

```sh:.envrc
use aws_profile <プロファイル名>
```

`use_aws_profile`ではなく、`use aws_profile`になっているのは、direnvでは`use_`プレフィックスの付いた関数はこのように`use <関数名のプレフィックス以降>`で呼び出すことができるためです。

これで毎回キーを指定する手間が省けるだけでなく、キーを再生成することになってもプロファイル側に設定したキーを変更するだけで済みます。
[iOS 12] Portrait Matteで背景分離／セグメンテーション

iOS 12の新機能"Portrait Matte"（ポートレート・マット）の概要と、実装方法を紹介します。[^nda]

<img width="393" alt="20180822200133.png" src="https://qiita-image-store.s3.amazonaws.com/0/3180/cd502cbe-685d-ae59-f48e-94d84a3f964e.png">

## 深度マップとセグメンテーション

昨今のiPhoneではデュアルカメラ（iPhone 7Plus, 8 Plus, Xの背面に搭載）、あるいはTrueDepthカメラ（iPhone Xの前面に搭載）から深度マップを作成し、奥行きを知ることができるようになっています。

深度マップは、

- AR表現における回り込み（オクルージョン）
- モノや人物の背景を差し替える [^chromakey]

といった用途に用いられます。

[^chromakey]: グリーンバックのように彩度をキーとして背景合成を行う技術はクロマキー合成と呼ばれる

どちらの例も要は人物やモノの境界を検出して分割する（セグメンテーション）ところがキーで、深度マップはそのセグメンテーションにおけるマスクとして有用なわけです。

<img width="482" alt="Screen Shot 2018-08-22 at 19.04.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/3180/432aa511-c06e-65da-a6ec-54b7c9b51f11.png">

<span style="font-size: 80%">（撮影した画像（左）と深度マップ（右））</span>



## iOS 12の新機能 "Portrait Matte"

深度マップ関連APIはiOS 11から追加されたわけですが、iOS 12では新たに"Portrait Matte"なる新機能が追加されました。"Portrait Effect Matte"とも呼ばれます。

[^nda]: 本記事はNDAに配慮し、Xcode 10やiOS 12のスクショは使わず、公開情報のみで構成しています。

<img width="512" alt="20180822200059.png" src="https://qiita-image-store.s3.amazonaws.com/0/3180/54f7848a-ed3e-8a5b-1fb7-27735d9b96fe.png">

<span style="font-size: 80%">（従来の深度マップ（左）とPortrait Matte（右））</span>

聞き慣れない用語ですが、たぶんApple独自用語です。WWDC18の"Creating Photo and Video Effects Using Depth"から、「Portrait Matteとはなにか」という説明をしている部分を引用してみます。

> so what is a portrait matte? A portrait matte is a segmentation from foreground to background and what this means precisely is that you have a mask which is 1.

> 0 in the background and you get soft and continuous values in between.

つまり、**背景と前景の分離に用いるセグメンテーションに特化したフォーマット**で、

- 前景領域のピクセル値は1（白）
- 背景領域のピクセル値は0（黒）

とスッパリ分かれており、輪郭部分の髪の毛のような詳細もその間の連続値で表現される、というもののようです。

<img width="393" alt="20180822200133.png" src="https://qiita-image-store.s3.amazonaws.com/0/3180/f8d3238c-34e4-5ba7-e4bf-f71c1ce2dc16.png">

**True Depthな前面カメラからだけではなく、背面カメラからも取得できる**ようです。

>  It is available for both the front and the rear facing camera.

ただし、**<span style="color: #ff0000">静止画のみ</span>**（動画では取得不可）かつ<span style="color: #ff0000"><b>人間が写っている場合だけ</b></span>取得可能です。

>  It is available to you with portrait still images and at the moment only when there are people in the scene. 


## Portrait Matteの取得方法

Portrait Matteの取得方法は従来の深度データ（`AVDepthData`）の取得方法と非常に似ています。

`CGImageSource`を作成したら、`CGImageSourceCopyAuxiliaryDataInfoAtIndex`で`kCGImageAuxiliaryDataTypePortraitEffectsMatte`を指定してAuxiliaryデータを取得すれば、

```swift
guard let info = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypePortraitEffectsMatte) as? [String : AnyObject] else { return }
```

それをそのまま`AVPortraitEffectsMatte`のイニシャライザに渡せます。

```swift
let matte = AVPortraitEffectsMatte(fromDictionaryRepresentation: info)
```

`AVPortraitEffectsMatte`は`CVPixelBuffer`型の`mattingImage`プロパティを持っており、そこからセグメンテーション用のマスクとしてCore ImageなりMetalなりで用いることができます。

```swift
var mattingImage: CVPixelBuffer { get }
```
[Unity]遺伝的アルゴリズムでサッカーボールを蹴ってみた

こちらは[Unityゆるふわサマーアドベントカレンダー 2018](https://qiita.com/splas_boomerang/items/e6619fb1e6dd92fd231f)の8/25記事になります

遺伝的アルゴリズムを使ってどれだけ遠くにサッカーボールを蹴り飛ばせるかやってみました
# 結果

### 1世代目
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">遺伝的アルゴリズム1世代目 <a href="https://t.co/Idat2iMmIz">pic.twitter.com/Idat2iMmIz</a></p>&mdash; ふみ (@hitsumasf) <a href="https://twitter.com/hitsumasf/status/1033321852427333632?ref_src=twsrc%5Etfw">2018年8月25日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
### 最終世代
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">最終世代 <a href="https://t.co/jxaQEcf8sq">pic.twitter.com/jxaQEcf8sq</a></p>&mdash; ふみ (@hitsumasf) <a href="https://twitter.com/hitsumasf/status/1033322303667335168?ref_src=twsrc%5Etfw">2018年8月25日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
### 全過程
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">最適化過程<a href="https://t.co/6SZfu4Ex3w">https://t.co/6SZfu4Ex3w</a></p>&mdash; ふみ (@hitsumasf) <a href="https://twitter.com/hitsumasf/status/1033324556327383040?ref_src=twsrc%5Etfw">2018年8月25日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
# ざっくりとした方法説明
## 遺伝的アルゴリズムとは
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/196266/88135009-d3ca-964a-2019-1b1012eca695.png)
遺伝子をたくさん用意して
交配させて　
最適な遺伝子を見つけ出す…
要するに__最適化__です

今回は足のモデルをたくさん用意して
シミュレーションを行い
できるだけ遠くにボールを蹴りだした上位20足のみに交配することを許しました
なお，100位以内にランクインしなかった足は子孫を残す機会を失うことにしました…

## サッカーボールを蹴る方法

### 足のモデル
足のモデルはこんな感じです
赤い部分が関節の可動域です(平面での動きに制限しました)
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/196266/d2e2f1e7-da5a-daec-23bb-1698244c064c.png)
ひざから下の部分(第2足)にのみ力をかけて足を動かしていきます 


### 遺伝子には何の情報を入れるか
遺伝子には足にかける力(正確にはトルク)の値を入れました(範囲は-60~100)
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/196266/7c56d55b-e96d-cfeb-06b1-9377f6f7eb9b.png)
上の画像のように，時間がたつと左の値から順にトルクをかける仕組みです
つまりこの問題は正確に言うと，
__時間内にサッカーボールをできるだけ遠くに蹴り飛ばせる遺伝子はなにか__
ということになります

### 遺伝的アルゴリズムの設定
細かい設定は次の通りです　

符号化：実数値（符号化しない）
評価：ボールの到達距離
選択：エリート主義（ボールの最長到達距離のフォームを知りたいため）
交叉：SPX(変数間に依存関係がある可能性があるため)
突然変異：必要ない（SPX,BLXでは親個体の分布よりも子個体の分布のほうが広い傾向があるため）

※[SPXについての参考リンク](http://www.sist.ac.jp/~kanakubo/research/evolutionary_computing/lbx_spx.html)

# まとめ
これくらい簡単な問題だと結構すぐ最適化されちゃうんですね
10世代くらいでもう変化がなくなってきました
拡張率を大きく設定しすぎてSPXがうまく働いていない気が…

__GitHubで公開しました__: [SocckerGA](https://github.com/fumi1995/UnitySocckerGA)
ARKit 2.0の画像トラッキングとARKit 1.5の画像検出の違い

ARKit 2.0では、「画像トラッキング」という新機能が加わりました。既知の2次元画像を検出・トラッキングできるので、ポスター等の現実世界に存在する2D画像を基盤にしてAR体験を開始することができるようになる、というものです。これを聞いて<span style="color: #ff0000">「あれ、その機能、既になかったっけ」</span>と思った方もいたのではないでしょうか。

その既視感はある意味では正しく、<b>ARKit 1.5で既に「画像検出」という機能が追加</b>されています。

では、これらはどう違うのでしょうか？ARKit 1.5の画像検出機能を強化したものが2.0の画像トラッキングで、リプレースされたのでしょうか。それとも別々の機能として共存しているのでしょうか。

結論としては後者で、**それぞれ強みを持つ別々の機能**として共存しています。

## コンフィギュレーションの違い

まず実装面でみると、ARKit 1.5で搭載された画像検出は、検出対象とするリファレンス画像をARKit 1.0から存在するコンフィギュレーションである`ARWorldTrackingConfiguration`（平面検出を行うのもこれ）の検出対象の一種として指定することで実装します。

```swift
let configuration = ARWorldTrackingConfiguration()
configuration.detectionImages = [referenceImage]
```

一方ARKit 2.0で追加された画像トラッキングは、新たなコンフィギュレーション`ARImageTrackingConfiguration`を使用します。

```swift
let configuration = ARImageTrackingConfiguration()
configuration.trackingImages = [referenceImage]
```

どちらの実装もリファレンス画像のセットをコンフィギュレーションのプロパティに渡すところは共通で、コンフィギュレーションだけが違っています。

![](https://qiita-image-store.s3.amazonaws.com/0/3180/75c2f780-7a4b-9d86-7daa-d6ba9dbedadf.png)

実は、ここに両者の違いが大きく表れています。

`ARWorldTrackingConfiguration`は、現実世界を検出・トラッキングするコンフィギュレーションです。現実世界の面（Surface）を検出し、そこにある画像やオブジェクトも検出します。

一方で`ARImageTrackingConfiguration`は、**既知の2D画像だけをトラッキング**します。その周囲の面は検出しません。

## パフォーマンスの違い

上のコンフィギュレーションの違いにより、パフォーマンスに大きな差が出てきます。`ARWorldTrackingConfiguration`はカメラに映る世界の面を全て見ているのでパフォーマンスコストが高く、対象画像は静止している必要があります。

一方で`ARImageTrackingConfiguration`は対象画像しか見ないので60fpsでその画像の位置と向きを推定します。そして対象画像が移動しても追従します。

また、同じ理由から、一度に復数の対象画像を検出する場合も、`ARImageTrackingConfiguration`の方がよりより多くの画像をより確実に処理できます。

実際に同じデバイスで両コンフィギュレーションによる画像検出／トラッキングを試してみると（NDA期間中につきスクリーンキャプチャ動画は載せられませんが）、次のような結果になりました。

- `ARWorldTrackingConfiguration`
  - `trackingState`が`normal`になるまでが遅い
  - 検出した画像の位置・向きの更新が遅い
- `ARImageTrackingConfiguration`
  - 一瞬で`trackingState`が`normal`になる
  - 検出した画像の位置・向きを毎フレーム正確に追従する


## それぞれのユースケース

画像への追従性、パフォーマンス面だけで見ると画像トラッキングの方が圧倒的に利点がありそうですが、こちらはワールド自体は見ていないので、たとえばその対象画像がカメラの視野から外れた場合に、その画像に仮想コンテンツを固定し続けることができません。一方で（`ARWorldTrackingConfiguration`）の画像検出では、対象画像が見えなくなった後でもワールド空間におけるそのコンテンツの位置を追跡し続けることができます。

画像検出は、美術館の絵画や映画のポスターのような静的画像にARコンテンツを連携させるようなケースに適しているとされ、また画像トラッキングは、卓上でのカードゲームやボードゲームのように移動する物体上の画像に対してARコンテンツを連携させるようなケースに適しているとされています。[^usecase]

[^usecase]: https://developer.apple.com/documentation/arkit/arimagetrackingconfiguration
pandas DataFrameをs3から読む・s3に出力するメモ

## この記事について

AWS EC2上とかで作業する際、s3上においたファイルにアクセスする機会は多いと思います。
そういう際にぜひ利用してください。
(環境やpermission周りの設定にも大いに依存する気がするので、これが最適解だとは思ってないですしそこらへんどういう設定に依存するのかちゃんと整理できてないのであとでちゃんと勉強したい…)

## s3からcsvを読み込む

これはread_csvの引数にs3のバケットを指定してあげれば一発。

```.py
import pandas as pd

df = pd.read_csv('s3://your-backet/your-file.csv')
```

## s3にcsvを書き出す

こちらは色々なやり方があるようですが、今回は`s3fs`を使った方法を紹介します。

```.py
def write_df_to_s3(df, outpath):
    """
    s3にファイルを書き出す処理
    """
    import s3fs
    key = "your-aws-access-key"
    secret = "your-aws-secret-access-key"
    bytes_to_write = df.to_csv(None, index=False).encode()
    fs = s3fs.S3FileSystem(key=key, secret=secret)
    with fs.open(outpath, 'wb') as f:
      f.write(bytes_to_write)

# dfという名前のDataFrameを's3://your-backet/your-file.csv'に書き出す
write_df_to_s3(df,'s3://your-backet/your-file.csv')
```
Golangで超シンプルにローカルでwebアプリを起動するところまで

## 目的
* Golangの最初の勉強。ド初級からやっていく
* とりあえずwebアプリを起動するところまでやる
* `こんなもん他に記事いくらでもあるやろ`というのは一旦置いておいて、自分への備忘録

## ファイル構成
### ディレクトリ構成
```Directory
golang_webapp_sample
┗ golang_webapp_sample.go
```

### ソース
```golang_webapp_sample.go
package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

func handler(writer http.ResponseWriter, request *http.Request){
	fmt.Fprintf(writer, "Hello World!")
}
```
参考：
[Goプログラミング実践入門　標準ライブラリでゼロからWebアプリを作る](https://www.amazon.co.jp/dp/B06XKPNVWV/ref=cm_sw_r_tw_dp_U_x_x0wGBbAZAQ4WB) 
 の [ソースコード](https://github.com/sausheong/gwp/blob/master/Chapter_1_Go_And_Web_Applications/first_webapp/server.go)

### 起動
1. `go run golang_webapp_sample.go` で起動  
1. http://localhost:8080/ にアクセス
1. 画面に `Hello, World!` と表示されたら勝ち

### 確認
![screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/162984/8eda29a3-5d3b-0b3d-5606-d905cb6300cc.png)

勝った

## この段階で発生した疑問点
### webサーバーいらんの？
このレベルだといらない模様。 tomcatだのspring-bootだのなくてもいいの？すごいねえ。
でもそのうちnginxで起動するようにするだろう。


## 次やること
* クラスをわける。
kotlinでandroid入門 GPS

GPS : LocationManager =  ロケーション
スマホにあるGPSで現在位置を取得する方法です

### 1. パーミション

  GPSを有効にするにはパーミッションが必要です
  後は、外部ストレージのパーミッションを有効にした方法と同じで

有効にするパーミッションは  
・ACCESS_COARSE_LOCATION 
・ACCESS_FINE_LOCATION
単純にGPSの使用と、ネットワークから位置を取得することの許可

### 2.   位置情報取得

```
   override fun onCreate(savedInstanceState: Bundle?)  {
       // ・・・
       
       // 位置情報使用時に準備
       if ((PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION  )) and
           (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)))
       {
            // 位置情報を管理している LocationManager のインスタンスを生成
            var locationManager: LocationManager? = getSystemService(LOCATION_SERVICE) as LocationManager
            var locationProvider : String = ""
            
            if (null !== locationManager) {
                // GPSが利用可能になっているかどうかをチェック
                if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                    locationProvider = LocationManager.GPS_PROVIDER
                } else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                    locationProvider = LocationManager.NETWORK_PROVIDER
                } else {
                    // いずれも利用可能でない場合は、GPSを設定する画面に
                    val settingsIntent = Intent(ACTION_LOCATION_SOURCE_SETTINGS)
                    startActivity(settingsIntent)
                    return
                }

                // 変化検出時に呼ばれる
                locationManager.requestLocationUpdates(
                    locationProvider,
                    500, // 通知のための最小時間間隔（ミリ秒）
                    1.0F, // 通知のための最小距離間隔（メートル）
                    object : LocationListener {
                        override fun onLocationChanged(location: Location) {
                            // ここで座標をもとめている
                            val lat = location.latitude
                            val lng = location.longitude
                            LatitudeView.text = R.id.LongtudeView.toString() +" : " + lat.toString()
                            LongtudeView.text = R.id.LongtudeView.toString() +" : " + lng.toString()
                            Log.d("GPS", lat.toString() + "-" + lng.toString())
                        }
                        override fun onProviderDisabled(provider: String) {}
                        override fun onProviderEnabled(provider: String) {}
                        override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
                    }
                )
            }
       }
   }
 ```

Log.d()で位置を表示してます
エミュレータでのデバックなので、位置情報はかえれるのでそれを使ってデバック

やったことないけど、これ使うと何とかGOで世界中いけるのでは
[Swift]TextFieldに文字が入力される度に処理を実行する

#はじめに
UITextFieldに文字が入力される際に処理を実行させたかったので、そのやり方をメモ

#動作環境
Xcode9.4.1
Swift4

#ポイント
###textField(_:shouldChangeCharactersIn:replacementString:)を使う
公式サイトを見る限り、textField()メソッドはUITextFieldDelegateプロトコルに宣言されていて、textFieldに文字が入力される際に呼ばれるらしい。
戻り値に`true`を返すと入力した文字がTextFieldに反映され、`false`を返すと入力した文字が反映されない。
[AppleDeleloper: textField(_:shouldChangeCharactersIn:replacementString:)](https://developer.apple.com/documentation/uikit/uitextfielddelegate/1619599-textfield)


#サンプルコード
以下のようにコードを記述した

```swift:ViewController.swift

class ViewController: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if string == "、" || string == "。" {
            return false
        }
        return true
    }

}

```

`textField()`メソッドの`string`引数には入力した文字が入っている。
そのため、if文にかけてやれば一部の文字などを入力させないようにできる。
このコードでは`、`と`。`をTextFieldに入力できないようにしている。

#実行結果
![ezgif-1-14fde015a5.gif](https://qiita-image-store.s3.amazonaws.com/0/278251/9aa0b663-90d8-b7bf-22b7-c163591fe824.gif)

#参考サイト
[UITextFieldで入力判定を行う (UITextFieldTextDidChange)](http://www.project-unknown.jp/entry/ios-uitextfield)
このサイトだと他のやり方も書いてあります。