OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScript ブラウザイベント

## イベントハンドラとイベントリスナ
- イベントに対する処理自体をイベントハンドラまたはイベントリスナと呼ぶ。
- イベントハンドラは一つの要素、一つのイベントに対して一つしか設定できない。
- イベントリスナは複数設定できる。
- イベントに対する処理の設定方法は以下の通り。
    - HTML要素の属性を指定する（イベントハンドラ）
    - DOM要素のプロパティを指定する（イベントハンドラ）
    - EventTarget.addEventListener()を利用する（イベントリスナ）


### HTML要素の属性を指定する

```javascript
<input id="foo" type="button" value="foo" onclick="alert('bar')">
```
ただしHTMLとJavaScriptを混在させると、可読性が低いので、通常はJavaScript のファイルは一つにまとめる。

### DOM要素のプロパティを指定する

```html

<script>
var btn = document.getElementById('foo');
function sayFoo(){
 alert('foo');
}
btn.onclick = sayFoo; 
//正 ：関数自体(sayFoo)を設定する
//誤り：button.onclick = sayFoo();だと関数実行した返り値設定することになるので誤り
</script>
<input id="foo" type="button" value="foo" onclick="sayFoo()">
```

### EventTarget.addEventListener()
- addEventListener()メソッドを使うと、特定の要素の特定のイベントに対して複数のイベントリスナを設定できる。
- 新しいDOMプロパティは既存のものを上書きする。
- 第3引数でキャプチャリングフェーズとバブリングフェーズを指定できる。
- DOM Level3では、第3引数を省略した場合にバブリングフェーズで実行される。
- DOM Level3では、イベントリスナの実行順序は登録順で実行されると定義されている。

```html
<script>
btn.addEventListener('click' sayHello,false)
btn.addEventListener('click' sayHello,false)// 前のイベントリスナを上書きします
// ...
btn.addEventListener('click' sayHello, true)// フェーズが異なれば別のものとして登録される
</script>
```

## イベントの伝播
- イベントは以下の3つのフェーズに分かれて処理される。
  - キャプチャリングフェーズ
  - ターゲットフェーズ
  - バブリングフェーズ

### キャプチャリングフェーズ
Windowオブジェクトからはじまり、DOMツリーを下に辿りイベントが伝播していくフェーズ。

### ターゲットフェーズ
イベントターゲットに登録されているイベントリスナが実行されるフェーズ。

### バブリングフェーズ
イベントターゲットからDOMツリーを上に辿りイベントが伝播していくフェーズ。

## 標準処理のキャンセル
- ブラウザが標準的に実装している処理を実行させないようにすることができる。
- Event.preventDefault()メソッドを使う。
- 例えばa要素をクリックすると、そのリンク先のページに遷移するが、preventDefault()メソッドを実行すると
その動作が実行されなくなる。
- イベント中にpreventDefault()メソッドで中止できないイベントもある。
- イベントハンドラでfalseを返すのと同じ。

```html

<a href="/" onclick="return false">Click here</a>
or
<a href="/" onclick="event.preventDefault()">here</a>
```

## 参考
[EventTarget.addEventListener() - MDN Web docs]
(https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener)
[JAVASCRIPT.INFO - ブラウザイベントの紹介]
(https://ja.javascript.info/introduction-browser-events)
「リファクタリング 第2版」Swiftでコーディング その16

# 24頁 第1章 計算とフォーマットにフェーズ分割「フェーズの分割(p.160)」「関数の抽出(p.112)」

## Swift版 main.swift

データ生成、結果表示付き。

```swift
import Foundation

makeData()

func playFor(aPerformance:Performance) -> Play {
    return plays[aPerformance.playID]!
}

func volumeCreditsFor(aPerformance:Performance) -> Int {
    var result = 0
    result += max(aPerformance.audience - 30, 0)
    if "comedy" == playFor(aPerformance: aPerformance).type {
        result += Int(aPerformance.audience / 5)
    }
    return result
}

func usd(aNumber:Int) -> String {
    let format = NumberFormatter()
    format.numberStyle = .currency
    format.locale = Locale(identifier: "en_US")
    return format.string(from: NSNumber(value: aNumber / 100))!
}

func totalVolumeCredits(invoice:Invoice) -> Int {
    var result = 0
    for perf in invoice.performances {
        result += volumeCreditsFor(aPerformance: perf)
    }
    return result
}

func totalAmount(invoice:Invoice) -> Int {
    var result = 0
    for perf in invoice.performances {
        result += amountFor(aPerformance: perf)
    }
    return result
}

func statement(invoice:Invoice, plays:Dictionary<String, Play>) -> String {
    var result = "Statement for \(invoice.customer)\n"

    for perf in invoice.performances {
        result += "  \(playFor(aPerformance: perf).name): " + usd(aNumber: amountFor(aPerformance: perf)) + " (\(perf.audience) seats)\n"
    }
    result += "Amount owed is " + usd(aNumber: totalAmount(invoice: invoice)) + "\n"
    result += "You earned \(totalVolumeCredits(invoice: invoice)) credits\n"
    return result
}

func amountFor(aPerformance:Performance) -> Int {
    var result = 0

    switch playFor(aPerformance: aPerformance).type {
    case "tragedy":
        result = 40000
        if aPerformance.audience > 30 {
            result += 1000 * (aPerformance.audience - 30)
        }
    case "comedy":
        result = 30000
        if aPerformance.audience > 20 {
            result += 10000 + 500 * (aPerformance.audience - 20)
        }
        result += 300 * aPerformance.audience
    default:
        print("error")
    }
    return result
}
 
let result = statement(invoice: invoices[0], plays: plays)
print(result)
```
JavaScriptでシークレットモードを検出する方法

## 最新の（Chrome76以降）のシークレットモード検出方法

2020年1月現在、Chromeブラウザのシークレットモードは下記のJSで検出できる。ただし、問題点も残っている。

```javascript
function detectSecretMode () {
  if ('storage' in navigator && 'estimate' in navigator.storage) {
    navigator.storage.estimate().then(function (estimate) {
      var usage = estimate.usage;
      var quota = estimate.quota;

      if (quota < 120000000) {
        console.log('Incognito');
      } else {
        console.log('Not Incognito')
      }
    });
  } else {
    console.log('Can not detect');
  }
```

このシークレットモード検出方法は、`ユーザーのストレージが少なすぎるなら、シークレットモードである`という仮定に基づいているが、この仮定は100%確実ではない。実際に自サイトで利用したところ、およそ一桁%の確率で誤検出が起きる。

これまでの誤検出状況を見る限り、写真等をたくさん保存するユーザーは、本当にストレージが少ないことがそれなりにある模様。

また、OSのバージョンが古い（Android4, 5, 6 等）ときも起きるようだが、ストレージ容量起因の誤検出と原因の分離ができていないためこちらは少し曖昧。

## 少し古い（Chrome76よりも前）シークレットモード検出方法

少し古いChromeでは、下記のJSでシークレットモードを検出できる。

```javascript
function detectSecretMode () {
  var fs = window.RequestFileSystem || window.webkitRequestFileSystem;
  if (fs) {
    fs(window.TEMPORARY,
        100,
        function (fs) {
          console.log('Not Incognito');
        },
        function (fe) {
          console.log('Incognito');
        });
  } else {
    console.log('Can not detect');
  }
}
```

## 参考リンク

[「Chrome」のシークレットモードを検知できる手法、研究者が指摘](https://japan.cnet.com/article/35141200/)
[Bypassing anti-incognito detection in Google Chrome](https://mishravikas.com/articles/2019-07/bypassing-anti-incognito-detection-google-chrome.html)
Windows上のOpenJDKな環境でJava Web Startを使う

\:information_source: この記事は別サイトで執筆した[Windows上のOpenJDKな環境でJava Web Startを使う – ひつじぶどう](https://blog.rumraisin.tokyo/?p=97)の内容を転載しています。

# はじめに
タイトルの通り, OpenJDKな環境でJava Web Startを使いたくなった(外発的動機)のでその時のめもです。

Oracleに頼ることなくJava Web Startを使うにはIcedTea-Webというのを使えば良いみたいですが, Linux環境で使う記事はたくさんあったもののWindows環境で使う記事はあんまり見かけなかったのでまとめました。

# 実行環境
| 項目 | 値 |
|:-----|:-----|
| OS | Windows 10 Pro |
| Build | 1809 |
| JDK Version | OpenJDK 1.12 |

# 導入手順
下記の手順を実施します。
## OpenJDK 12を準備する
そもそもJava Web StartをOpenJDKで使いたいと思う人のPCにはOpenJDKが入っているとは思いますが, 念のため。
12を選んだのは単に記事執筆時点での最新版だったからです。

① [OpenJDKのダウンロードページ](https://jdk.java.net/12/)からOpenJDK 12をダウンロードし, zipファイルを解凍する
![スクリーンショット 2019-05-18 18.57.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/16e6ca5d-da37-37f0-6971-8c689b80d3e5.png)

② 解凍されたフォルダ(jdk-12.0.1)を適当な場所に配置する(今回はC:\直下に配置しました)
③ 「コントロールパネル」>「システム」>「システムの詳細設定」を開く
![スクリーンショット 2019-05-18 19.02.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/91b0f3e6-cc2f-6dd8-112d-85fc96e4c5f0.png)

④ 「詳細設定」タブの「環境変数」からユーザー環境変数"Path"を編集し, `C:\jdk-12.0.1\bin` (②で配置したパスを指定してください)を追加する
![スクリーンショット 2019-05-18 18.57.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/6cc14779-8fc1-3cde-d3bb-5e12b7c83f88.png)

## IcedTea-Webを準備する
[Wikipedia先生](https://ja.wikipedia.org/wiki/IcedTea)によると, [IcedTea](https://icedtea.classpath.org/wiki/Main_Page)とは2007年6月にRedHatが開始したOpenJDK用のビルドおよびシステム統合プロジェクト, ということらしいです。
IcedTeaプロジェクトのIcedTea-Webというものを使ってJava Web Startの機能を利用できるようにします。

① IcedTeaの[ダウンロードページ](http://icedtea.wildebeest.org/download/)に行く

② [icedtea-web-binaries/1.8/windows/](http://icedtea.wildebeest.org/download/icedtea-web-binaries/1.8/windows/) に進む(他のバージョンが良い人は1.8を他バージョンに適宜読み替えてください)

③ itw-installer.msi をダウンロードする
![スクリーンショット 2019-05-18 19.17.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/c622c66d-5e17-2f38-fef5-ba8ba9de8a8a.png)

④ itw-installer.msiを実行し, ウィザードに沿ってインストールする(特に初期設定から設定値は変えていません)
![スクリーンショット 2019-05-18 19.19.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/8c4bd137-bbc3-e734-f693-1dc076172f83.png)

⑤ インストールが終わったら, `C:\Program Files\IcedTeaWeb\WebStart\bin` をユーザー環境変数"Path"に追加する
![スクリーンショット 2019-05-18 19.23.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/b1708480-68f7-cb51-8806-33c033f50d81.png)

# 実行
実行するにはPowerShell等で下記のようにjavaws.exeの引数としてjnlpファイルのパスを渡してあげればOKです。

```PowerShell
PS> javaws.exe TEST.jnlp
```

`C:\Program Files\IcedTeaWeb\WebStart\bin\javaws.exe` をjnlpファイルに関連付けてあげるとjnlpファイルをダブルクリックしたりするだけで実行できるので便利かもしれません。
![スクリーンショット 2019-05-18 19.25.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/3134e562-5f8f-c40b-c2ec-182601baaaec.png)
MJ文字図形取得APIを使って指定した画数の人名用漢字を取得する

#はじめに
子供の名前とか考えるときに画数って気にしますよね。
指定した画数の漢字を次々に表示してくれるサービスとかないかな？と思ったら
なんかそれっぽいAPIがIPAから提供されていたので試しに使ってみました。
[MJ文字図形取得API](http://mojikiban.ipa.go.jp/mji/)

サイトをみれば基本的に使い方など書いてありますが
実際にやってみた、ということで記事にまとめてみたいと思います。

#やりたいこと
冒頭にも書きましたが、子供の名前を決める補助として使いたいと考えています。
そのため、求めるものとしては以下2点です。

- 人名用漢字を取得できる事
- 画数を指定できる事

#やってみた
## 全体の流れ
1. 取得したい漢字の条件を指定してHTTPリクエストを送信します。
2. Responseとして、該当する字の情報がjsonもしくはxmlとして取得します。
4. MJ文字図形名を利用して、文字の画像データを取得します。

# 1.HTTPリクエスト
今回指定したい条件が、`人名漢字`,`画数`です。
今回GETメソッドで取得するようなので、URLの後ろにクエリを加えてあげます。
例えば`画数= 7`の`人名漢字`を取得したいときは以下のような形になります。
HttpResponseをXML,jsonどちらで受信するかはヘッダーにて指定します。

https://mojikiban.ipa.go.jp/mji/q?漢字施策=人名用漢字&総画数=7

上記のリンクをクリックすると該当する漢字に関する情報がjsonの形で表示されると思います。
上限数とかあるんでしょうかね？そのあたりの仕様は不明です。

# 2.HTTPレスポンス
該当する漢字の情報をjsonとして入手できました。
このときjsonには該当する「字」そのものの情報が含まれていません。
その代わりに「字」を特定するユニークな値である`MJ文字図形名`を取得できます。
上の例であれば`MJ006353`、`MJ006415`などがあるかと思います。

# 3.MJ文字図形名を利用して文字画像データを取得する
取得した文字図形名を利用する事で、該当する文字の画像データを取得することができます。
先ほどの例で取得した最初の字のMJ文字図形名が`MJ006353`だったので
この値を使って文字の画像データを取得してみたいと思います。

https://mojikiban.ipa.go.jp/MJ006353.png

「串」という字の画像データが表示できました。
png形式か、svg形式かどちらで取得するかはURLの末尾で選択できます。

記事書いてる最中に気づいたんですが、HTTPレスポンスの中にMJ文字図形のuriの値が含まれているので
これを取得してそのまま叩いてあげれば簡単にできそうです。

#最後に
MJ文字図形取得APIを使って検索から表示まで一連の流れを試してみました。
これ使えば命名アプリとか作れそうですね。
２０２０年個人的にデジタルトランスフォーメーション（DX）元年としてローコードを中心に具体的な実現方法を提案します。

# はじめに
自己紹介から。Qiitaデビューです。今までは貴重な情報源としてお世話になりっぱなしでしたが、今年は自分からも発信していきます。

私は独立系ソフトウェアベンダーに勤めているアラフォー（まだ３０代の方）の男です。業務系を中心とし、提案見積もりから開発、運用保守まで一次受けとして（二次受けもあります、二次の方が多いかも）１０年以上経験を積んできました。

情報発信・ブログはデビューなので皆様暖かく見守ってください。アドバイスなどよろしくお願いいたします。

# この記事のポイント
・DXを実現するためのローコード開発基盤の紹介
・開発基盤の費用感

# なぜ２０２０年情報発信デビューしようと考えたか
冒頭にも書いたとおり、私は業務系システムを１０年以上開発してきました。
しかし、今まで最新の技術を使う機会がありませんでした。
最新イコール誰かの役にたつ情報とは限らないのですが、本で自主学習した内容を発信するより、現場で実際に使用することにより得られた一次情報を発信したほうが価値があると考えております。

そして、今やっと新しい技術、具体的にはローコード基盤にてシステム開発中なので、デジタルトランスフォーメーション（DX）に絡めて情報を発信していこうと考えました。（２０２０年という語呂もいい感じ）

# デジタルトランスフォーメーション（DX）とローコード
デジタルトランスフォーメーション（DX）とローコードについて、[経済産業省資料](https://www.meti.go.jp/press/2018/09/20180907010/20180907010-2.pdf)の「３．３ DX実現に向けたITシステム構築における。。。」のなかで「アジャイル開発方法」、「マイクロサービス化」というキーワードが出てきます。また、システムが実現すべきゴールイメージとして、「ビジネス・モデルの変化に迅速に追従」と記載されています。

マイクロサービスは現場で使用した経験はないのですが、「アジャイル開発方法」と「ビジネス・モデルの変化に迅速に追従」の観点からローコード基盤を活用したデジタルトランスフォーメーション（DX）の実現を提案します。

# DXを実現するためのローコード開発基盤の紹介
ローコード開発基盤として、ローコードという言葉が使われる前からあるものや最近出てきたものなど私が知っている限りでも１０以上ありますが、その中で下記３つのローコード基盤をお客様へ提案しており、採用もされてます。

1. PowerApps
2. AppMaker
3. Outsystems



## PowerApps
マイクロソフトのローコード開発基盤。PowerPointでスライドを作成するように、簡単にアプリケーションの開発ができます。

[PowerApps](https://powerapps.microsoft.com/ja-jp/)

## AppMaker
Googleのローコード開発基盤。PowerAppsと比較しコードを書く場面は多いがその分柔軟なシステムの開発ができます。

[AppMaker](https://www.outsystems.com/)

## Outsystems
Outsystemsのローコード開発基盤。実績は十分、世界でローコードといえばOutsystems。基幹システムのリプレースも可能。（個人的にPowerAppsとAppMakerで基幹システムは無理と考えています。）

[Outsystems](https://gsuite.google.co.jp/intl/ja/products/app-maker/)

# 開発基盤の費用感
### PowerApps
2019年10月からライセンス体系が変更となり、はっきりと書いてある場所はみつけられていないのですが、OFFICE365を契約していれば使用可能です。ただし、データベースを使用することができません。データベースを使用するためにはPowerApps単体ランセンス（1,090円／月）が必要となります。
![powerappsライセンスハードコピー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561340/c22c0367-0526-2ea6-b315-4ec111900981.png)
[ハードコピー引用元](https://products.office.com/ja-jp/business/microsoft-powerapps)

### AppMaker
G SuiteのBussinessプラン（1,360円／月）から使用可能です。Gmailをビジネスで使用中でGドライブの容量が無制限であればBussinessプラン以上の可能性が高いので、追加料金なしで使用することが可能です。ただし、こちらもデータベースを利用する場合、別途準備する必要があります。親和性が高いDBとしてはGoogleCloudPlatformのCloudSqlがあります。従量課金ですが、試しに使ってみるのであれば、月3,000円かからないです。

### Outsystems
Outsystemsの日本代理店の会社担当者と打ち合わせをして、実際のライセンス料金を伺いましたが、ネットで公開されていないためざっくりというと、１００ユーザーで年間数百万円です。
こちらは、学習用のコミュニティバージョンが公開されているため、無料でOutsystemsを試すことができます。


# まとめ
実際に現場で使用しているのは、PowerAppsとAppMakerなので、開発用のTIPSとして情報発信できればと考えております。
よろしくお願いします。
Go1.13とDockerで開発環境構築（ホットリロード有）

# はじめに（背景）
筆者は今までGoでは簡単なツール（Slack用Botとか）しか作ってこなかったが、
Goを使ってWEBアプリを開発してみることにした。 

ところが、開発環境を構築するのに、検索でヒットする情報が微妙だった
- Goのバージョンが古くてGo Modulesを使っていなかったり、
- 使っているライブラリの最終更新が3年前だったり

情報を整理しながら開発環境を構築する必要が有ったので、
せっかくだからアウトプットしておこうと思った。

# 前提
- Goのversionは、執筆時点で最新の1.13系を使う
- docker-composeで立ち上げたい
- せっかくなので、ホットリロードが欲しい

### 以下には触れません
- GoでのWEBサーバーの立ち上げ方
- Go Modulesについて
- Docker、docker-composeの使い方

# 本題
## Goの設定
#### Go Modulesを使う
Go Modulesの導入や使い方などは割愛
↓のコマンドでinitialize
`go mod init github.com/username/project`

#### ホットリロードの設定
色々調べたら、Realizeが良さそう(適当)
https://github.com/oxequa/realize

設定ファイル（後述）を用意して、
`realize start`コマンドを実行するだけ

## Docker環境用意
**Dockerfile**

```

FROM golang:1.13-alpine

WORKDIR /app

COPY . .

RUN apk add --no-cache git \
  && go get gopkg.in/urfave/cli.v2@master \
  && go get github.com/oxequa/realize

```
　
**.realize.yml （ホットリロードの設定）**

```
settings:
  legacy:
    force: false
    interval: 0s
schema:
- name: hoge
  path: path/to/server
  commands:
    install:
      status: true
    run:
      status: true
  watcher:
    extensions:
    - go
    paths:
    - path/from/server
    ignore_paths:
    - .git
```
　
**docker-compose.yml**

``` 
version: "3"
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 8080:8080
    volumes:
      - ./:/app
    command: realize start
```

　

#### ※realizeの設定でエラーが出た。（↑のファイルには反映済み）
**パッケージを取得する時**
解決方法は以下のissueから
https://github.com/oxequa/realize/issues/253
↓の箇所

```
RUN apk add --no-cache git \
  && go get gopkg.in/urfave/cli.v2@master \
  && go get github.com/oxequa/realize
```
　

**Go Modules環境起因でもエラー**
以下のissueから
https://github.com/oxequa/realize/issues/217
↓の箇所

```
  commands:
    install:
      status: true
```

# おわりに
以上で、DockerでGoを開発する環境ができました。
あとはdocker-composeにDBなり何なりを追加すれば進められそうです。
database/sql で INSERT したレコードのIDを取得する

# 概要

Go の `database/sql` を利用して、 INSERT したレコードのIDを取得する

## 参考

- [Inserting records into a PostgreSQL database with Go's database/sql package](https://www.calhoun.io/inserting-records-into-a-postgresql-database-with-gos-database-sql-package/)

## 問題

- 使用しようとした `lib/pq` では `LastInsertId() (int64, error)` が使えない
- `database/sql` は `int64` で ID を返す Interface しか存在しない

### 使用しようとした `lib/pq` では `LastInsertId() (int64, error)` が使えない

`database/sql` では import する [Driver](https://github.com/golang/go/wiki/SQLDrivers) を差し替えることで、異なる SQL Database を利用する場合でも、共通の Interface を利用して SQL を扱える。

今回利用しようとしたのは、 PostgreSQL 用の Driver の一つである `lib/pq`

しかしながら、 `Result` Interface のコメントを読むと下記が書かれており、全てのデータベースでのサポートではないことがわかる。また実際に `lib/pq` でこのメソッドを呼び出そうとしてもエラーが返り、 `lib/pq` では INSERT したレコードの ID を取得できなかった。

>    // LastInsertId returns the integer generated by the database
    // in response to a command. Typically this will be from an
    // "auto increment" column when inserting a new row. Not all
    // databases support this feature, and the syntax of such
    // statements varies.

### `database/sql` は `int64` で ID を返す Interface しか存在しない

また `LastInsertId()` は auto increment された `int64` 型の ID を取得する Interface であり、 ID を `UUID` 型に指定した場合などは、利用できないことがわかる。

## 解決策

>Instead, we get around this by making a few changes. First, we are going to update our SQL statement by adding RETURNING id to the end of the statement. This will tell our SQL database that we want it to return the id of the newly inserted record so that we can do something with it.

その為、まず SQL 側の解決策として、 Result Interface では LastInsertID を利用するのではなく、 SQLを変更して、 Insert した後の レコードの ID を返却するように変更する。

2つ目に Go のコード側も変更する。
`database/sql` では UPDATE・INSERT は基本的に ~.Exec を利用して、 `Result, error` を取得し、 SELECT の場合は、 ~.Query を利用する。

下記は元のコード。

```go
	stmt, err := prepare(repo, "INSERT INTO users(username, password, email) VALUES($1, $2, $3);")
	defer stmt.Close()
	if err != nil {
		return nil, fmt.Errorf("query prepare faild: %w", err)
	}

	_, err = stmt.Exec(user.Personal.Name, user.Password, user.Personal.Email)
	if err != nil {
		return nil, fmt.Errorf("exec faild: %w", err)
	}
```

これを下記に変更する。
QueryRow を使用することで、 Row が返り値として戻ってくるようになり、 `~ RETURNING user_id;` の部分を実行結果として、受け取れるようになる。あとは Row.Scan() して、レコードの値を読み取ることで、 INSERT したレコードの ID を受け取ることができる。

```go

	stmt, err := prepare(repo, "INSERT INTO users(username, password, email) VALUES($1, $2, $3) RETURNING user_id;")
	defer stmt.Close()
	if err != nil {
		return nil, fmt.Errorf("query prepare faild: %w", err)
	}

	err = stmt.QueryRow(user.Personal.Name, user.Password, user.Personal.Email).Scan(&user.Id)
	if err != nil {
		return nil, fmt.Errorf("query faild: %w", err)
	}
```

これで、 `LastInsertId()` 介さないので、 Driver が対応していなくてもよく、また ID の形式も int でなくてもよくなった。

以上、慣れないのでどうするのかわからなかった内容を備忘録として。
誰かの参考になれば幸いです。
「タグ判定」ステップについて

【具体例】
・ポケモンの「もっと見る」を押し切る動作

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/893e473e-0fbc-d01b-c733-a744a788f43c.png)

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/435eaabc-ddab-1d50-0059-00c491cf6018.png)
・ファインダーで指定したタグの中にパターンに書いた文字があるか見る

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/8f549490-b87e-b1f4-80cd-75b89052cefd.png)
・実際のコードは上記の感じ
試しに「OpenID Connect Provider Certification」を通してみた

以前、なんちゃってOpenID Connectサーバを立ち上げました。( [なんちゃってOAuth2/OpenID Connectサーバを自作する](https://qiita.com/poruruba/items/042adba2ac9a34839546) )

それはそれで役に立っているのですが、OpenID Connectに準拠しているかどうかを確認するためのTest Suite があったので、物は試しで通してみました。
結果は、散々でした。Optional機能は実装していないので当然ではありますが。

Conformance Testing for OPs
　https://openid.net/certification/testing/ 

# テストの準備

まずは、準備として、テスト対象のエンドポイントのURLやサポートする機能を指定します。

　https://op.certification.openid.net:60000/ 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/297efc5d-f33f-4cc7-a39f-2ec63e7a7e65.png)

New ボタンを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/b33a2da5-1c9c-bdef-a232-02f84ac65306.png)


Issuerに、サーバで生成するトークンに含めるissの値を指定します。
Response Typeとして「code」を選択しました。

最後に、「Create」ボタンを押下します。

次は、各エンドポイントなどを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/47ac1244-4fba-87f4-d9d0-ef5cd67c97ea.png)

以下の値を指定することで、テストを開始できました。

・contact_email ： 適当な値
・authorization_endpoint ： 認証エンドポイント
・jwks_uri ： 署名を検証するための公開鍵のエンドポイント
・token_endpoint ： トークンエンドポイント
・userinfo_endpoint ： USERINFOエンドポイント
・client_id ： 適当な値
・client_secret ： 適当な値

最後に、「Save & Start」ボタンを押下すると、テスト用のページに進みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/64e8d058-27b4-df5b-efe0-8cecaf606139.png)

# いざ、テスト実施

左側の列にある再生ボタンを押下していくと、それぞれテストが実施されます。
結果はこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/ab031e7e-8b4b-13ff-ab59-244a50910052.png)

まあ、実装を手抜きしているので当然ですね。
右側の列にある「！」マークのボタンを押下すれば、実行経過やエラー理由が確認できます。

エラーとなった理由を列挙しておきます。

（OP-Response-Missing)
・エラーメッセージを返すべきだが、HTTPエラーステータスが返ってきている。Swaggerで必須パラメータを指定しているがそれがないため

(OP-ClientAuth-SecretPost-Static)
(OP-claims-essential)
(OP-nonce-code)
(OP-prompt-none-LotLoggedIn)
(OP-Req-acr_values)
(OP-Req-login_hint)
(OP-Req-max_age=1)
(OP-Req-max_age=100000)
・OpenID Connectの仕様上Optionalな機能であり、対応していません。

(OP-redirect_uri-NotReg)
・リダイレクトURIをチェックしていないため(手抜き実装)

(OP-Oauth-2nd)
(OP-OAuth-2nd-30s)
(OP-OAuth-2nd-Revokes)
・認可コードの期限チェックや利用済みのチェックをしていないため(手抜き実装)

(参考) OpenID Connect Core 1.0 日本語訳
　http://openid-foundation-japan.github.io/openid-connect-core-1_0.ja.html

# 終わりに

なんちゃっての実装でしたが、こうしてやって実施してみると、すんなり確認が通ってよかったよかった。

以上
【Unity】子のAnimatorを親から操作してみるテスト

# 概要
例えば、こんなアニメーションをつけたい時に、
![sample_anim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538310/11dca944-bd48-cb47-90e3-6abbee2e13eb.gif)

子要素が三つあって、動きは同じなんだけど、開始のタイミングだけずらしたい。
動きは同じなんだけど、Animationのキーは、三倍打たなきゃいけない・・・面倒だなぁ。

**Animationで、タイミングだけ指定できないかな？**やってみよう！

# SerializeFieldはAnimationでキーが打てる
そもそもMonoBehaviourスクリプトのSerializeFieldは、Animationで操作できます。ColorをSerializeFieldに出して、Animationで色を変える・・・なんてのは、よくやるテクニックです。

今回は、子要素のAnimatorのパラメーターを、SerializeFieldに用意して、親のアニメーションのキーから操作するようにします。
![hierarchy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538310/3eca64c9-bd66-1e19-7450-28505e89272b.png)

# Animatorの構造
子供のAnimatroはこんな感じ。
シンプルな構造で、Any　StateからBoolパラメーターで、即遷移するようにしました。
※TriggerではなくBoolの方が、アニメーションから制御しやすい
![child.controller](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538310/2f171a44-ea3b-f6c4-fdf7-6a8b0532ad85.png)
子要素は3つありますが、全部同じAnimatorを使っています。
アニメーションの更新があった場合でも、一つのAnimatorを更新すれば良いのでラクチンです。

親のAnimatorはこんな感じです。
![root.controller](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538310/8550e5fb-f245-f0da-bf84-f8746e5d9f74.png)
用途にあわせて自由に作りましょう。
今回は、in Triggerで入って、out Triggerではけるような動きを作っています。

# スクリプト
childにアタッチするスクリプトはこんな感じです。
子要素のAnimatorのパラメーターと同じSerializeFieldを用意し、UpdateでSetBoolするだけです。

```C#:SerializeAnim.cs
using UnityEngine;

public class SerializeAnim : MonoBehaviour
{
    Animator mAnimator;
    [SerializeField] public bool BoolWait;
    [SerializeField] public bool BoolStay;
    [SerializeField] public bool BoolIn;
    [SerializeField] public bool BoolOut;
    [SerializeField] public bool BoolRotate;

    void Awake()
    {
        mAnimator = GetComponent<Animator>();
    }

    void Update()
    {
        mAnimator.SetBool("wait", BoolWait);
        mAnimator.SetBool("stay", BoolStay);
        mAnimator.SetBool("in", BoolIn);
        mAnimator.SetBool("out", BoolOut);
        mAnimator.SetBool("rotate", BoolRotate);
    }
}
```
# root_in.animにキーを打つ
root_in.animに、キーを打ってみます。
Add Propertyを選択すると、子要素のSerializeFieldが追加できます。
![add_property.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538310/efaf12b6-0298-27b9-0ac7-c418e5787362.png)
1秒ごとにズラして、child1のBool in、child2のBool in、child3のBool inのキーを打ちます。
![animation_in.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538310/e91ce1a2-0ee6-92d8-7292-f447eb1ae60c.png)
他のAnimationも同じように準備します。

# さて、実行だ！
![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538310/132c2a66-8564-1cfc-2f4b-cceb1b71e747.gif)
おおー、うまく動いてますねー。
# メリット/デメリット
- 長所
    - 子供の動きを作るのが一つだけでいい
    - 更新があった場合、一つだけ更新すれば良いので、修正が少なくて済む
- 短所
  - Animationウインドウのプレビューで動きを見ることができない

# サンプル
- https://github.com/tabataketarao/serialize_anim_test
マイグレーション関連のエラー解決１

不要なマイグレーションファイルの消し方

１必要なマイグレーションファイルに必要なカラム名を入力する

２rake db:migrateを入力する
　→down->upにする

3不要ファイルを消す
　→すでにupしているものは右クリックで削除
　（この時statusでは削除ファイルはNoFileになるが問題ない）

4rails db:resetを入力する
【サンプルロボ】複数のExcelファイルを開いて データをやり取りするロボット

【アルゴリズム】
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/f2649c21-8eec-a871-c279-4bcaacc4c761.png)
・作成済みのエクセル２つがあり、その中のデータを３つ目のエクセルで計算する


![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/abb7ec74-5b74-ed5f-1521-ca0dbeef7734.png)
・計算式が入れられる

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/a13b42e1-f6a3-d972-742d-09692190ba34.png)
・上記の感じで表示される
「コンピュータはなぜ動くのか」メモ④

最後のメモ。

〜〜〜〜〜〜〜〜〜〜〜〜〜〜
<b>第10章：データを暗号化してみよう</b>
・共通鍵暗号方式(または、秘密鍵暗号方式)・・・暗号と復号で同じ鍵を使う。
・公開鍵暗号方式・・・暗号と復号で異なる鍵を使う。暗号鍵を公開し、復号鍵を秘密にする。

有名なアルゴリズム → RAS

<b>第11章：そもそもXMLってなんだっけ</b>
・XML = Extensible Markup Language（拡張可能なマークアップ言語）
・マークアップ = タグによって意味付けをする行為
・XMLは自由にタグを作ることができる。
・HTMLは「情報を表示するスタイル」を指定、XMLはデータの情報を指定している・

*SOAP(Simple ObjectAccess Protocol)は分散コンピューティングで使われる。
*分散コンピューティング = ネットワークで接続された複数のコンピュータにプログラムを分散して配置し、それらを連携動作させることでコンピュータシステム全体を機能させるもの。
　→XMLのデータの送受信ができれば、どのプロトコルでも使用可能。
　→XMLは異なるマシンの異なるアプリケーションを使用する場合に有効。

<b>第12章：SEはコンピュータ・システム構築の現場監督</b>
-特になし
〜〜〜〜〜〜〜〜〜〜〜〜〜〜

２回読みました（２回目でメモ作成）
ハードウェア系の知識は特に抜けていたので、平易な文章・SEなら当然の知識だから知っておかねばとは思いつつも、何度か「もうやめたい‥」と正直思いました。

が、今は自分の知識の穴があいていた部分が少し塞がった感覚があります。
本当に読んでよかったです。
特に文系SEで「色々勉強してるんだけど、どこか釈然としない…」と言う人は読んでみると良いかもです。

それでは。
SQLのUNIONについて①

年が明けてしまった。お久しぶりです。
今回はSQLのUNIONについて説明したいと思います。
一回メモ書き程度に残した気はするのですが、きちんと説明していなかった気がするので改めて。

まず、UNIONとは2つのSQLの結果をひとまとめにして表示することのできるものです。
以下の二つのテーブルを例にとって説明します。

|果物| 
|:-----|
|りんご   |
|みかん   |
|すいか   |

|野菜| 
|:-----|
|にんじん   |
|じゃがいも   |

果物テーブルと野菜テーブルをそれぞれSELECT文を用いて検索し、
UNIONでひとまとめにしてみます。

```ruby:SQL
SELECT * FROM 果物テーブル
UNION
SELECT * FROM 野菜テーブル
```

すると、以下のような結果となります。

|検索結果| 
|:-----|
|りんご   |
|みかん   |
|すいか   |
|にんじん   |
|じゃがいも   |
Fargate及びECSでコンテナからAWSのIAM認証を利用する

## 概要

AWSでコンテナを利用する場合、FargateやECSが候補に上がると思います。
コンテナからAWSの各種サービスを利用する場合、IAMのCredentialsを利用する必要があります。
いつも意識せずに利用しているIAMですが、裏ではどういう構成になっているのか確認していきます。

## 確認方法

Fargateでsshできるようにして、コンテナ内でCredentialsを探します。

Fargateでsshするには以下の記事を参考にしてください

- https://qiita.com/pocari/items/3f3d77c80893f9f1e132
- https://qiita.com/ryurock/items/fa18b25b1b38c9a0f113
- https://qiita.com/fnaoto/items/c980efa39c2b1597331e

## 結果

Fargateでは`AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`という環境変数にCredentialsへのファイルファイルパスが入っているようです。

- 詳細はこの記事を参考にしてください
   - https://qiita.com/moaikids/items/6481e1027facb5f096bc
   - https://qiita.com/kawachi/items/cb59a44b5430988741be
   - https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-iam-roles.html


### rootユーザでコンテナにログインしても環境変数が設定されていない

実は、この環境変数はPIDが1のプロセスに設定されているようです

- https://aws.amazon.com/jp/premiumsupport/knowledge-center/ecs-iam-task-roles-config-errors/

確認方法

```sh
$ strings /proc/1/environ
```

例えば、Dockerfileで以下のようになっている場合。
この場合、環境変数はPIDが1の`/bin/sh`に設定されます。
そして、`bundle exec rails s`には親プロセスの`/bin/sh`から環境変数が引き継がれます。

```Dockerfile
CMD ["/bin/sh", "-c", "bundle exec rails s"]
```

ちなみに、以下のようにデーモンプロセスを動かす場合。
この場合は起動するデーモンの親プロセスは`/bin/sh`にはならないので環境変数は引き継がれません。

```Dockerfile
CMD ["/bin/sh", "-c", "service ssh start"]
```

### 環境変数に設定されているIAMはどこから設定するのか

このIAMはTask Roleを参照しているようです。
なので、`taskRoleArn`に設定しているIAMから権限を変更可能です。

- https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-iam-roles.html


### RubyライブラリでIAM認証を使う場合

aws-sdk-rubyでは以下のように、`AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`があれば`ECSCredentials.new`するようにしているみたいです。
ちなみに、instance_profile_credentialsはprivateなので外から呼び出しはできないみたいです。
普段、ライブラリを使う場合は特に意識することなくことなく、Credentialsが使われているようですね。

```ruby
# https://github.com/aws/aws-sdk-ruby/blob/704c4a2afbee1bb20a6c47545305684a92771f7e/gems/aws-sdk-core/lib/aws-sdk-core/credential_provider_chain.rb#L110

    def instance_profile_credentials(options)
      if ENV["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"]
        ECSCredentials.new(options)
      else
        InstanceProfileCredentials.new(options)
      end
    end
```

- 詳細はこの記事を参考にしてください
  - https://qiita.com/pocari/items/acdb45dbec3eb0e0656e
  - https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ECSCredentials.html
ubuntu16.04をインストールしたPCに市販のWebカメラをUSB接続してpythonで動画キャプチャする

# 目的
ubuntu16.04をインストールしたPCに市販のWebカメラをUSB接続してpythonで動画キャプチャした際の備忘録です

# 準備
ubuntu16.04をインストールしたPC
市販のWebカメラ

opencv-pythonインストール

```
pip install opencv-python
```

# テスト

```python:capture.py
import cv2
cap = cv2.VideoCapture(0)

while True:
    ret, img = cap.read()
    cv2.imshow('video', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
```

# CodingError対策
特になし

# 参考
[最小限のUbuntuでOpenCVを使用したビデオキャプチャ](https://ja.programqa.com/question/11029400/)
dotfilesのためのがんばらないAnsible

小ネタ集です。

Ansibleを使って環境構築をコマンド一発でできるようにしよう！でもAnsibleを学習するのは大変、そもそもやりたいことはインフラではないし……というあなたに役立つかもしれない知識たち。

サンプルとして、自分のdotfilesを置いておきます。 https://github.com/eihigh/dotfiles/tree/master/ansible

## inventoryを使わない
ssh接続（あとpython）さえあればリモートホストが幾つあっても一発で構築できるのがAnsibleの魅力。だけどdotfilesでは今ある環境さえ構築できればそれでいい。

というわけでホストは `localhost` に固定してしまいましょう。

```yaml
---
- name: My Playbook
  hosts: localhost
  connection: local
  tasks:
    - include: tasks.yml
```

こいつを

```
ansible-playbook path/to/playbook.yml
```

と叩けばOK。 `-i` オプションのことは忘れましょう。

但し環境自体にAnsibleが必要になるのでそこはなんとかしてインストールする必要あり。自分の場合はpythonもないまっさらな環境を使いたかったので、pythonとsshを入れてリモートホストに設定するくらいなら最初から自身にAnsibleを入れても変わらないじゃん、という発想で運用しています。

## タスクをまとめる
ロールとかなんとかで汎用性をもたせられるのもAnsibleの魅力ですが、dotfilesの環境構築なんてどうせ大したことはしないので、1ファイルにまとめてしまいましょう。

上記の起点となるplaybookから `tasks.yml` を呼び出す形にするとインデントを減らせて綺麗に収まるかと思います。自分はこのような内容にまとめています。 https://github.com/eihigh/dotfiles/blob/master/ansible/tasks.yml

同じ発想で `vars.yml` も1ファイルにまとめていて、結果として以下のようなディレクトリ構成になっています。

```
ansible/
|-- setup.yml ... 起点となるplaybook
|-- tasks.yml ... タスクをまとめたyaml
|-- vars.yml ... 変数をまとめたyaml
`-- library/ ... 自作モジュール置き場
    `-- executable.sh
```

## PATHに所定のコマンドがないときだけインストール
dotfilesだとありがちだと思いますが、（自分の探した限りだと）デフォルトでは見つからなかった機能。もしよろしければお使いください。 https://github.com/eihigh/dotfiles/blob/master/ansible/library/executable.sh

使い方は、

```yaml
executable:
  ghq: cd /tmp; go get -u github.com/motemen/ghq
  gopls: cd /tmp; go get -u golang.org/x/tools/cmd/gopls
  lazygit: cd /tmp; go get -u github.com/jesseduffield/lazygit
  goimports: cd /tmp; go get -u golang.org/x/tools/cmd/goimports
  pt: cd /tmp; go get -u github.com/monochromegane/the_platinum_searcher/...
  eslint: sudo npm install -g eslint
  typescript: sudo npm install -g typescript
```

のようにコマンド名とインストールスクリプトをvarsに用意したあと、

```yaml
- name: Install executables
  executable:
    name: "{{ item.key }}"
    action: "{{ item.value }}"
  with_dict: "{{ executable }}"
```

のように `executable` モジュールに `name` と `action` を渡します。 `name` のコマンドが見つからないときだけ、 `action` を実行しますが、存在するときは no change になります。

---

以上です！　簡単ですがやはりAnsibleを使っているというだけで大きな安心感が得られるので是非。
deno v0.28.0の変更点

## 概要

denoのv0.28.0がリリースされたため、変更点をまとめます。

https://github.com/denoland/deno/releases/tag/v0.28.0

## `Deno.dir()`関数に`"executable"`を渡せるようになった(Linux環境のみ)

https://github.com/denoland/deno/pull/3526

```typescript
Deno.dir('executable');
```

下記いずれかが返却されます。

- `XDG_BIN_HOME`
- `$XDG_DATA_HOME/../bin`
- `$HOME/.local/bin`

## 標準ライブラリの各モジュールに`mod.ts`ファイルが追加された

https://github.com/denoland/deno/pull/3509

各標準モジュールに`mod.ts`ファイルが追加されている。

それに合わせて、一部関数名等のリネームも行われている。

- `std/archive/mod.ts`
- `std/encoding/mod.ts`
- `std/fmt/mod.ts`
- `std/http/mod.ts`
- `std/io/mod.ts`
- `std/mime/mod.ts`
- `std/multipart/mod.ts`

### 参考

- [Denoのスタイルガイド](https://deno.land/std@v0.28.0/style_guide.md)

## その他の修正点等

#### Promiseがrejectされcatchされなかった場合、REPLが停止する問題が修正された
- https://github.com/denoland/deno/pull/3527

#### `parseAll`関数(std/encoding/yaml)でマルチドキュメントyamlのパースに失敗する問題が修正された
- https://github.com/denoland/deno/pull/3535
- https://github.com/denoland/deno/issues/3534

```typescript:v0.27.0
import { parseAll } from "https://deno.land/std@v0.27.0/encoding/yaml/parse.ts";

const data = parseAll(`
name: hoge
age: 20
---
name: fuga
age: 30
`);
// error: Uncaught YAMLError: can not read an implicit mapping pair; a colon is missed at line 4, column 1:

```

```typescript:v0.28.0
import { parseAll } from "https://deno.land/std@v0.28.0/encoding/yaml/parse.ts";

const data = parseAll(`
name: hoge
age: 20
---
name: fuga
age: 30
`);

console.info(data); // [ { name: "hoge", age: 20 }, { name: "fuga", age: 30 } ]
```

#### `read*`関数にサイズが0の`Uint8Array`が渡された場合、`0`を返すように修正された。
- https://github.com/denoland/deno/pull/3329
- https://github.com/denoland/deno/issues/3287

0.27.0で下記コードを実行すると、エラーが発生します。
0.28.0にて、この問題が修正されました。

```typescript
const file = await Deno.open('/path/to/file.txt');
try {
  const bytesRead = await file.read(new Uint8Array(0));
  console.info(bytesRead);
} finally {
  file.close();
}
```

#### `Deno.shutdown`関数及び`Deno.ShutdownMode`enumが追加された
- カスタムの`Conn`インターフェースの実装を容易にすることが目的のようです。
- https://github.com/denoland/deno/pull/3558
- https://github.com/denoland/deno/pull/3560

#### uuidモジュールのワイルドカードexportが廃止された
- https://github.com/denoland/deno/pull/3540

#### `Deno.dir`に不正な文字列が与えられた際に、例外を投げるのではなく`null`が返却されるようになった。
- https://github.com/denoland/deno/pull/3531

v0.27.0で下記コードを実行するとエラーが発生しますが、v0.28.0では`null`が返却されるように修正されました。

```typescript
Deno.dir('hoge'); // null
```

#### `console.clear`が同期的に実行されるようになった。
- https://github.com/denoland/deno/pull/3533
- https://github.com/denoland/deno/issues/3532

例えば、下記のコードをv0.27.0で実行すると、`hello`と`world`の両方がクリアされてしまい、画面には何も表示されません。

v0.28.0では、`hello`の出力の後にクリアが行われるようになったため、`world`の出力は画面に残ります。

```typescript
console.info('hello');
console.clear();
console.info('world');
```
新年の抱負 2020


### New Years resolutions 2020



こんにちは　みんなさん、あけましておめでとう

Hello everybody, Happy new year to all



休日のため、ブログを更新できませんでした。Golangのトレーニングビデオも一時停止しましたが、今は元気になりました。

Because of holiday stuff, I haven´t been able to update the blog, I also paused the Golang training videos, but now I´m back, with more energy.



はじめに、これが今年の目標のリストです。

* 7月にJLPT N4に合格
* Golangコースを終了する
* 私は3つのサイドプロジェクトを持っていますが、どちらを先に行うかを決めていません。
* 日本で就職したい
* ブログを続ける
* YouTubeチャンネルを開始しますか？ -（わからない、私はカメラに乗っていない）



To get started, this is my list of objectives for this year.

* Pass the JLPT N4 in July
* Finish my Golang Course
* I have 3 side projects, but haven´t decided which one I´m going to do first.
* Hopefully get a job in Japan
* Continue blogging
* Start a youtube channel? - (not sure, I don´t being on camera)



このようなものの多くは、すでに公開されています。できれば、公開することで、目標を達成するためのサポートを得ることができます。

Much of this stuff, I have already started, hopefully, by publishing it, I can get support from you guys to finish my objectives.



じゃあまたね！

See you later!
XMLHttpRequestについて

### Ajaxとは
- ページ遷移せずに、コンテンツを非同期にロードし、ページを書き換える技術。
- Asynchronous JavaScript + XMLの略。

### XMLHttpRequestとは
- Ajax通信に利用される組み込みオブジェクト。
- XMLHttpRequestのLevel1ではクロスオリジン通信ができないが、 Level2だとクロスオリジン通信が可能になる機能が追加されている。
- クロスオリジンを行うには、サーバー側の設定で"Access-Control-Allow-Orign"のHTTPヘッダをレスポンスに含める。

### 基本的な処理の流れ

```javascript

var xhr = new XMLHttpRequest();

// イベントハンドラ
xhr.onreadystatechange = function() {
    switch ( xhr.readyState ) {
        case 0:
            // open()が呼び出される前
            console.log( 'uninitialized!' );
            break;
        case 1: // send()が呼び出される前
            console.log( 'loading...' );
            break;
        case 2: // サーバーからのレスポンス待ち
            console.log( 'loaded.' );
            break;
        case 3: // サーバーからのレスポンス受信中
            console.log( 'interactive... '+xhr.responseText.length+' bytes.' );
            break;
        case 4: // サーバーからのレスポンス受信完了
            if( xhr.status == 200 || xhr.status == 304 ) {
                var data = xhr.responseText; // XMLによるresponseだとresponseXML
                console.log( 'COMPLETE! :'+data );
            } else {
                console.log( 'Failed. HttpStatus: '+xhr.statusText );
            }
            break;
    }
};
```

### XMLHttpRequestのレスポンス
- JSONで受け取る馬青は、responseTextプロパティの内容をJSONに変換する必要がある。


```javascript

var xhr = XMLHttpRequest();

var json = JSON.parse(xhr.responseText);

alert(json.value);
```

### 参考

https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest
「コンピュータはなぜ動くのか」メモ③

メモ③

〜〜〜〜〜〜〜〜〜
<b>第7章：オブジェクト指向プログラミングを語れるようになろう</b>

・オブジェクト指向プログラミング（Object-Oriented Programming）
・関連する関数や変数をグループ化することで、以下の利点がある。
　　→保守が容易
　　→大規模なプログラムに適している
・オブジェクトが他のオブジェクトの持つ関数を呼び出すこと　＝　メッセージ・パッシング

★別途「オブジェクト指向でなぜつくるのか」をメモするのでここでは以上。

<b>第8章：作ればわかるデータベース</b>
・データベース = そもそも、社内のデータを一元管理できるようにした基地
・DBMS(DataBase Management System) = MicroSoft Access, Oracle, SQL Server, DB2など。簡単にデータファイルを読み書きできるようにし、データを矛盾なく安全に保つ。

・正規化=テーブルを複数にわけ、個々のテーブルのリレーションシップを設定（関係づける）して、データベースの構造を整理すること。
・インデックス（index）= データの検索と並べ替えの速度を向上させる内部的な仕組み

★上記のDB設計が完了したら、ユーザーIFとなるアプリケーションを設計する。なお、このアプリケーションは基本的にCRUD（Create、Refer、Update、Delete）が必要となる。
→これらをDBMSに指示するのがSQL

・トランザクション制御
・トランザクション　＝　DBに対する一つの意味のある操作が複数のSQLになったもの

例：Aさんの口座から-1000円して、Bさんの口座に+1000円する（←2つのUpdate命令）
途中でトラブルが発生して、Aさんの口座からひいたのにBさんの口座に入っていないようなことがおこってしまう。このようなことを防ぐため、
①DMBSにトランザクションの開始を知らせる命令
②トランザクションの終了を知らせるCOMMIT命令
③トランザクションの途中でトラブルが発生した場合に、トランザクション開始前の状態にデータベースの内容を戻すROLLBACK命令

<b>第9章：簡単な実験7つでTCP/IPを理解する</b>
小規模なネットワークを整備する上で必要なハードウェア。
①ネットワーク・カード（Network Interface Card, NIC） -> Eithernet
②ネットワーク・ケーブル
③ハブ（ネットワークケーブルをまとめて結ぶ）
④ルーター（インターネットに接続するための機器）

◆Ethernetの接続のしくみ
①個々のコンピュータはネットワーク・ケーブルに他のコンピュータからの電気信号が流れていないこと＝ネットワークが誰からも使われていない状態であることを確認し、自分の送りたい電気信号を確認する。
②もし同時に複数のコンピュータが電気信号を送信してしまった場合には、ランダムな時間だけまって同じ信号を再送信する。
　→「CSMA/CD」(Career Sense Multiple Access with Collision Detection)
③電気信号を受信したコンピュータは自分宛てであれば受け取り、そうでなければ無視する。
電気信号の宛先はMAC（Media Access Control、メーカー番号＋製品番号）アドレスで指定する。ハードウェア的なアドレス。

ただし、MACアドレスはグループ化されていないので、データを送る上で時間がかかってしまう。
そこで、グループ化されているソフトウェア的な番号がある　→ これがIPアドレス。

IPアドレスのどこがネットワーク・アドレスでどこがホスト・アドレスかを知るためのものがサブネットマスク。

◆DHCPサーバーとは
・DHCP = Dynamic Host Configuration Protocol（動的にホストを設定するプロトコル）
DHCPサーバ内にはLAN内に割り当てられるIPアドレスの範囲とサブネット・マスクの値が記録されている。クライアント端末を起動すると、まだ他のコンピュータに割り当てられていないIPアドレスが知らされる。

*デフォルトゲートウェイ = ルーターのIPアドレス

◆ルーター
・IPアドレスの中のネットワークアドレスを調べ、それがLANの内なのか外なのかを認識し、外であればデータをインターネットに送り出す装置。

*送信データをどこに送るか示すもの = ルーティング・テーブル
*ルータを経由したデータ転送 = routing

◆DNSサーバー
・ホスト名＋ドメイン名（FQDN、完全就職ドメイン） ⇄ IPアドレスの名前解決を行うサーバー
一つで全ての名前解決を行うのではなく、他のDNSサーバーに問い合わせるなどして連携している。

◆ARP(Address Resolution Protocol)
・IPアドレスをMACアドレスに変換する仕組み（データはIPアドレスを情報としてもっているが、結局データの受け取りはMACアドレスで認識されるから）
・LAN内のコンピュータに一斉に問いかけること ＝ 「<b>broadcast</b>」
・なお、MACアドレスを調べる際に毎回broadcastをするのは非効率なので、「ARPキャッシュテーブル」なるものを持っている。

◆TCP/IP
・TCP = データの送信者と受信者がお互いに確認を取り合いながら、確実にデータを受け渡すためのプロトコル。handshake送信方式のひとつ。TCPではデータはpacketにわけられる。受信側でそれを復元するので、そのための情報も付加される。
・IP = IPアドレスの情報でルーティングを行い、データを転送するプロトコル。

〜〜〜〜〜〜〜〜

恐らく次で最後…！
【Angular】ngForでObjectを表示させる際にKey, Valueを利用したい

## はじめに
今回はObjectをngForで表示する際に、KeyValueを利用する方法を共有していく。

## `keyvalue`パイプを使う
```typescript:key-value-example.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
    selector: 'app-key-value-example',
    templateUrl: './key-value-example.component.html',
    styleUrls: ['./key-value-example.component.scss'],
})
export class KeyValueExampleComponent implements OnInit {
    public exampleObject = {
        'イリヤ': '丹下桜',
        'シノブ': '大坪由佳',
        'アカリ': '浅倉杏美',
        'ヨリ': '原紗友里',
        'ミヤコ': '雨宮天',
    };

    constructor() {}

    ngOnInit() {}
}
```

```html:key-value-example.component.html
<ng-container *ngFor="let chara of exampleObject | keyvalue">
    <div>
        <div>キャラクター名：{{chara.key}}</div>
        <div>声優：{{chara.value}}</div>
    </div>
</ng-container>
```

このように表示された
<img width="200" alt="スクリーンショット 2020-01-04 15.18.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316318/1d4fb4fe-e000-19bc-9875-e227d22aab8a.png">

ちなみにObservableの値であれば、

```html
<ng-container *ngFor="let chara of exampleObject | async | keyvalue">
</ng-container>
```

とすれば良い。
## 参考
- [access key and value of object using *ngFor
](https://stackoverflow.com/a/51491848)
Adobe PDFファイルを復号化する方法

一部のWebサイトから一部のAdobe PDFファイルをダウンロードしますが、その一部は読み取り用に開くことができず、Adobe PDFファイルを印刷または編集するときに、パスワードなどの権限を入力するよう求められます。 しかし、時間が経つにつれてパスワードを忘れてしまい、画像を抽出または変更できませんでしたAdobe PDFファイルのパスワードをキャンセルする方法Adobe PDFファイルを復号化する方法

暗号化されたAdobe PDFファイルを復号化する方法はたくさんありますが、その方法は面倒ですので、SanPDFを使用すると、インターフェイスはシンプルで操作が簡単です。 PDFファイルはコピー、印刷、変換できます。
1. ブラウザを開き、sanpdfを検索して、sanpdfの公式Webサイトにアクセスします
2. ナビゲーションバーの[変換]で[PDFファイルのロック解除]を選択して、変換ページに入ります。 ダウンロードボタンをクリックしてインストールします。
3. インストールが完了したら、インストールした場所を見つけて開きます。
4. クライアントを入力したら、「Adobe PDF unlock」を見つけて「select」をクリックします。
5. 「選択」ボタンを開いてクリックして、復号化するAdobe PDFファイルを見つけ、復号化されたパスワードを入力します。
6. 「復号化して保存」をクリックして、復号化後にAdobe PDFファイルを保存します。
7. 完了したら、「ディレクトリを開く」をクリックして、復号化されたファイルを表示します。

簡単じゃないですか？ Sanpdfは、複数の変換機能を備え、安全に使用できる最も人気のあるコンバーターとして賞賛されています。 念のため、ファイルのセキュリティについてまだ心配している場合は、心配しないでください。Sanpdfはプライバシーを尊重します。 ファイル変換の24時間後、それらはサーバーから自動的に削除されます。 また、変換ファイルのファイル情報を削除することもできます。これは、効率を向上させ、時間を節約してカラフルな生活を送るのに役立つ無料のオンラインコンバーターです。 持って行って〜
88e6065のmibを拾う

FreeBSDのethernetswitchでMarvellの100BaseTのSwitchのmibを拾うコードをmruby-etherswitchを使い書いてみました。

```ruby:e6065.rb
# Ingress Counters
# 0x00 – InGoodOctets
# 0x01 – Reserved
# 0x02 – InBadOctets
# 0x04 – InUnicast
# 0x06 – InBroadcasts
# 0x07 – InMulticasts
# 0x16 – InPause
# 0x18 – InUndersize
# 0x19 – InFragments
# 0x1A – InOversize
# 0x1B – InJabber
# 0x1C – InRxErr
# 0x1D – InFCSErr

# Egress Counters
# 0x0E – OutOctets
# 0x0F – Reserved
# 0x10 – OutUnicast
# 0x12 – OutMulticasts
# 0x13 – OutBroadcasts
# 0x15 – OutPause
# 0x03 – OutFCSErr
# 0x05 – Deferred
# 0x11 – Excessive
# 0x14 – Single
# 0x17 – Multiple
# 0x1E – Collisions3
# 0x1F – Late

# Histogram Counters
# 0x08 – 64Octets
# 0x09 – 65to127Octets
# 0x0A – 128to255Octets
# 0x0B – 256to511Octets
# 0x0C – 512to1023Octets
# 0x0D – 1024toMaxOctets

mib = ARGV[0].to_i

t = EtherSwitch.new(0)

port = 1

GLOBAL = 0xf

hireg = t.readreg((GLOBAL << 5) | 0x1d) & 0xc00

while port < 7 do

  while t.readreg((GLOBAL << 5) | 0x1d) & 0x8000 == 0x8000 do
  end

  reg = (1 << 15) | (5 << 12) | hireg | (port << 5)
  t.writereg((GLOBAL << 5) | 0x1d, reg)

  while t.readreg((GLOBAL << 5) | 0x1d) & 0x8000 == 0x8000 do
  end

  reg = (1 << 15) | (4 << 12) | hireg | mib
  t.writereg((GLOBAL << 5) | 0x1d, reg)

  while t.readreg((GLOBAL << 5) | 0x1d) & 0x8000 == 0x8000 do
  end

  hi = t.readreg((GLOBAL << 5) | 0x1e)
  lo = t.readreg((GLOBAL << 5) | 0x1f)
  c = hi << 16 | lo

  if port != 1 then
    print ","
  end
  print c.to_s

  port = port + 1
end
```

実行してみます。

```
# /usr/local/bin/mruby e6065.rb 0
0,0,0,97833,0,68834
```

FON2201などで使われているピンコンパチの88e6060にはmibサポートがないようです。88e6060は.1Qもサポートされていません。Marvellの100BaseTのSwitchは88e6065が最後で、一番よくできているような気がします。

くどいですが、88e6065のサポートコードも私が書いたものです。
Python で Markdown パーサに使えそうなものの調査

Markdown 文書を manupulate したい。

Pythonでそのようなものを調べてみたら、 Markdown を変換して HTML にするものが一般的なようだ。そうではなくて Markdown フォーマットの文書を操作したいとなると AST 的なものを使えるようにしならなければならない。そのものずばりは無かったので、改造のベースとして使えそうなものを探してみた。

# 基礎知識

Markdown 文書の manupulate は大変。

例えば以下のようなコメントを文中に書くと特定のテンプレートが挿入されるというオレオレ拡張(nanbuwks拡張)を作りたいとします。

```

[](nanbuwks:template)
```

Makrdown テキストを対象に、単純に文字列検索／置換でできるかな？

- いやいやコードブロックにこの行が含まれていた場合は無視しないといけないですね。
- コードブロックの開始／終了は 「 \`\`\` 」 ですが、 では「 \`\`\` 」が出てきたら無視するようにしないといけないですね。
- でも「 \`\`\` 」 が \[\]\(\) の中にあったら無視しないといけないですね。
-  \[\]\(\) は埋め込みHTML中にあった場合は無視しないといけないですね・・・

など、結局markdownの文書構造をパースしてrawなテキストとしてみなせるかどうかを判定し、その上で文字列検索／置換しなければなりません。

これはオレオレ拡張に限らず、画像パスの変更、Headingのレベル変更、自動整形などをする場合も同様です。

・・・markdownの文書構造をパースするには？

# 一般的なパーサ

一般的には Markdown を HTMLに出力するものとなるようだ。

Markdown → トーカナイザー → 文書構造データ → レンダラー → HTMLに出力

となる。以下は想像。

## トーカナイザー

こんな感じ？

- markdown には ブロックレベルとスパンレベルがある
- トークンとしてブロックトークンとスパントークンがある
- 最初に、文書全体を1ブロックとする
- 一行ずつ検査
- ブロックトークンを再帰で適合するか調べる
- 余ったテキストにスパントークンが適合するか調べる


## 文書構造データ

トーカナイザーで調べた文書構造を内部データに格納
文書構造データーはツリー構造となる


## レンダラー

文書構造データに基づきタグをつけたり制御テキストをつけたりして文書を再構築する。
一般的にはここでHTMLにするものが多い。

# 求めるもの

## 生 Markdown を操作できるもの

文書構造データを元の Markdown のテキスト構造にひもづけて取得できれば、文書構造を参照しながら操作できますね。
でもそのものずばりは見当たりませんでした。
では既存のものに手を加えようとしてそういうものを作りたかったけれど結構手間がかかりそうなので今回は断念。

## 抽象データからMarkdownを作ることができるもの

文書構造データとコンテキストから、Markdown を再生成できる。けれども抽象データを元にするので元文書は完全には再現できない。それでもいいからそういったものは無いかな？ → 無さそうでした。

## 抽象データを出力できるもの

AST的なものが得ることができるかな？ コードに手を加えずに出力が得られそうなものは無さそう。

（2020/1/4追記 あとで探したら Markdown から JSONに変換するものがいくつかありました。詳細は調べていませんが要件を満たしていたかも知れません。）

## 抽象データからMarkdownを作れそうなもの

既存のコードに手を加えて、Markdown が出力できそうなもの。それができれば更に機能を追加するのは簡単かな？

# 調査

以下の要件で調査

- Python3
- HTMLだけではなく、複数の他のフォーマットにも変換できているのが望ましい。
- 今後生Markdownの操作に発展できそうなもの

# Python-Markdown

https://github.com/Python-Markdown/markdown
標準的ライブラリという感じ。
プラグインが沢山ある。しかしHTML以外にコンバートするものではない感じ。例えば Markdown-LaTeX も、MarkdownにインラインMarkdown-LaTeXTEX表記のものをHTMLにコンバートするもののようだ。
求めるものと勝手が違うようなので断念。

# commonmark.py

https://github.com/readthedocs/commonmark.py

commonmarkのPythonへのポート。
commonmarkはMarkdownの標準規格的な考えで作られているもの。リファレンス実装が以下にある。
https://github.com/commonmark/commonmark.js

リファレンス的なところを重視して、応用的な方向に向いてなさそうなので諦める。

# mistune

処理が高速らしい
Version2が2019/12に出ているが、2019/1/1現在、Ubuntu の pip3 では 0.8.4 がインストールされる。
最新版をインストールするために以下のようにした。

```

$ sudo pip3 install git+https://github.com/lepture/mistune.git
```

ドキュメントが不足していてあきらめる

# mistletoe


mistletoe は標準で HTML以外にLaTeXへの出力がある。

- LaTeX
- JIRA
- Scheme ?

使いやすそうなのでこれを元に作ってみることにする。


# 調査後にわかったもの

上記4つを調べて mistletoe で作った後に出てきた良さそうなもの。
ちゃんと調べてないけどまたの機会に改めて。

## pycmark

https://github.com/tk0miya/pycmark


「拡張性を持っているためGFM (GitHub Flavored Markdown)の対応や独自の記法の追加など、柔軟なパースが可能です」という記述がある
https://www.papercall.io/speakers/tk0miya/speaker_talks/78833-markdown


## marko

https://pypi.org/project/marko/#extend-marko

Among all implementations of Python's markdown parser, it is a common issue that user can't easily extend it to add his own features. 
とある。
【AWS完全に理解したへの道】VPC 基本編

[【AWS完全に理解したへの道】 IAM 基本編](https://qiita.com/y-u/items/cef40fd249947687810e)
に続く、VPC 基本編(項目の然るべき順序的なものは後で整理するかも)

## VPCの作成
ある特定のリージョンを選択してプライベートネットワーク空間を作成する。
プライベートネットワーク空間は /16(65,536個のIPアドレス)から /28(16個のIPアドレス)のCIDR(Classless Inter-Domain Routing)ブロック範囲で作成できる。

VPCを作成する場合は、[RFC1918](http://www.faqs.org/rfcs/rfc1918.html)に指定されているように、以下のプライベートIPv4アドレス範囲からCIDRブロックを指定することを推奨されている。

* 10.0.0.0 - 10.255.255.255
* 172.16.0.0 - 172.31.255.255 
* 192.168.0.0 - 192.168.255.255

## サブネット作成
サブネットを作成時、AZごとに1つ以上のサブネットを追加する必要がある。
サブネットはAZをまたがって作成することはできない。
また、VPC CIDRブロックのサブセットである、サブネットのCIDRブロックを指定する。

#### オプション
IPv6 CIDRブロックをVPCに割り当てて、IPv6 CIDRブロックをサブネットに割り当てることができる。

## ゲートウェイの作成
#### インターネットゲートウェイ(IGW)
##### できること
* インターネットでルーティング可能なトラフィックの送信先をVPCのルートテーブルに追加することができる。
* パブリックIPv4アドレスが割り当てられているインスタンスに対してNAT(ネットワークアドレス変換)を行うことができる。

#### バーチャルプライベートゲートウェイ(VGW)
VPNやオンプレのデータセンタなどと通信するための出入り口となるゲートウェイ。
VGWとVPC毎に**1つだけ**紐づけることができる。

## EC2インスタンスのIPアドレス
VPCサブネット内で起動するEC2インスタンスにはそのサブネット内のプライベートIPアドレスが少なくとも一つ割り振られる。
そのEC2インスタンスにインターネットからアクセスしたい場合、さらにグローバルIPアドレスを割り振る必要がある。AWSのグローバルIPアドレスには以下の2種類がある。

* Public IP : EC2インスタンスが起動した際にランダムに割り振られる動的なグローバルIPアドレス。
* Elastic IP : アカウントに割り当てられる固定のグローバルIPアドレスでEC2インスタンスにアタッチ/デタッチする。
固定のグローバルIPアドレスでの運用が必要な場合に使用する。

※EC2インスタンスのプライベートIPアドレスとグローバルIPアドレスの紐付けはVPCの仮想ネットワークで行われる。
よって、EC2インスタンスのOSにログインしてifconfigコマンドなどでネットワークの設定を見てもプライベートIPアドレスの値しか表示されない。

## ルートテーブルの作成
各サブネットがパブリックなのか、プライベートなのかは各サブネットに適用されているルートテーブルによって決定される。
また、VPC内の通信はルートテーブルでは制御できない。

##### パブリックサブネット
インターネットのアクセスを許可するサブネット
デフォルトゲートウェイのターゲットにIGW(インターネットゲートウェイ)が設定されたルートテーブルが適用されているサブネット。

##### プライベートサブネット
インターネットのアクセスを許可しないサブネット
デフォルトゲートウェイのターゲットにIGWが設定されたルートテーブルが適用されていないサブネット。

## NATインスタンス
インターネットからのアクセスを受け付けないまま、プライベートサブネット内からインターネットやリージョンサービスにアクセスさせたいときに使用する。

* NATインスタンスの実態はEC2インスタンス。
* プライベートサブネット内のEC2インスタンスからトラフィックを受け付ける。
* そのEC2インスタンスのプライベートIPアドレスをNATインスタンスに割り振られたグローバルIPアドレスに変換し、インターネットへのアクセスを可能にする。

## セキュリティグループ
EC2やELBやRDSなどのインスタンスごとのファイアーウォール。
各インスタンスごとに1つ以上のセキュリテイグループを適用する必要がある。

## ネットワークアクセスコントロール(ACL)
サブネットごとのファイアーウォール。

#### セキュリティグループとネットワークACLの違い
||セキュリティグループ|ネットワークACL|
|---|---|---|
|適用単位|EC2、ELB、RDSなどのインスタンス単位|サブネット単位|
|作成、追加可能なルール|許可のみ|許可/拒否|
|デフォルトルール|インバウンド：全て拒否 <br>アウトバンド：全て許可|インバウンド：全て許可 <br>アウトバンド：全て許可
|特徴|ステートフル|ステートレス|

## VPCピア接続
2つのVPCを接続する機能。
2つのVPC間でVPCピア接続を確立すると、双方のVPCにPCXというゲートウェイに相当するものが作成される。
VPCピア接続の制約条件は以下となる。

* 接続するVPCは同じリージョンに存在する必要がある。
* 接続するVPCのプライベートネットワークアドレス空間は重複しないようにする必要がある。
* 1 対 1の接続にする必要がある。
memo用

<?php


//カラム
$join_member = array();

 $user = "root";
 $pass = "";
 $dsn_column = "mysql:host=localhost;dbname=information_schema;charset=utf8";//information_schemaはカラム名が保存されている場所
 try{
  $dbh_column = new PDO($dsn_column, $user, $pass);
 } catch ( PDOException $e ) {
 print ( 'Error:'. $e->getMessage() );
  die();
 }
 $sql_column = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME= 'schedule'";//カラム名を取得したい条件をWHEREにいれる。
 $stmt_column = $dbh_column->query($sql_column);
 if ( !$stmt_column ) {
   echo $dbh_column->errorInfo();
   exit();
 }
 $row_column = $stmt_column->fetch(PDO::FETCH_ASSOC);
 while ( $row_column = $stmt_column->fetch(PDO::FETCH_ASSOC) ) {
   array_push($join_member ,$row_column["COLUMN_NAME"]);
 }
 print_r($join_member);
 $dbh_column = null;

//カラム終了

//セル取得
$dbh =new PDO('mysql:host=localhost;dbname=test;charset=utf8', $user, $pass);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);//dbhのDBに属性を設定
$sql = "SELECT * FROM schedule";//リクエスト分
$stmt = $dbh->query($sql);//stmtに全てのリクエストを取得する。
//セル取得

?>
<html>

<head>
  <title>おみくじ</title>
       <meta charset="utf-8">
   <title>メール送信テスト画面</title>

</head>

<body>
<input type="text" id="id_textbox"><!--このidに紐づき値をメールの本文に出すようにする-->

<table border='1'  id="sampleTable"><!-- NHKテーブル -->
<tr><!-- 1行目各項目名表示 -->
<th>名前</th>


<?php

foreach ($stmt as $row){//繰り返しテーブルの行を追加する。

  echo "<th>".$row['date']."</th>";
 


}
$stmt = $dbh->query($sql);//stmtに全てのリクエストを取得する。

echo "</tr>";
for($i = 0 ; $i < count($join_member); $i++){
echo "<tr>";
echo "<td>$join_member[$i]</td>";
$stmt = $dbh->query($sql);//stmtに全てのリクエストを取得する。
	foreach ($stmt as $row){//繰り返しテーブルの行を追加する。
	
	  echo "<td>".$row["$join_member[$i]"]."</td>";
	  
	}
echo "</tr>";
}

?>



</table>			
<script type="text/javascript">
  function logsend(mail)//メール起動関数
  {
    
    title = "メール件名"
    text = document.getElementById('id_textbox').value//テキストボックスの値を変数に代入。
    window.open().location.href = "mailto:" + mail + "?subject=" + title + "&body=" + text;
   }
</script>

</body>

</html>