OmniAICreator/Qiita-1.07M huggingface dataset:
Vue.jsを使ってBULMAのtabsを切り替える

## 概要
Vue.jsを使う際にCSSのフレームワークを何にするかは、今のところスタンダード的なものは無いように思います。
JQueryを使っていた時代はBootstrap一択だったように思えますが、Vue.jsでBootstrapを使うにはJQueryが必要になってしまうため、いまいちスッキリしません。

そんな訳で今はBULMAを実験的に使ってみています。BULMAは純粋なCSSのみのフレームワークなので何にでも合わせることができますが、動きについては自分でコーディングしなければいけません。

## タブの切り替えをVue.jsを使って行う
[BULMAのページ](https://bulma.io/documentation/components/tabs/)にはタブのスタイルについては定義がありますが、切り替え方については全く記載がなかったので、Vue.jsを使って切り替えて部分をコーディングしてみました。
特に難しいことはしていませんので、ほぼそのまま組み込むことができると思います。

<p class="codepen" data-height="328" data-theme-id="dark" data-default-tab="html,result" data-user="jhanyu" data-slug-hash="rEpZQp" style="height: 328px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Vue + bulma tabs">
  <span>See the Pen <a href="https://codepen.io/jhanyu/pen/rEpZQp/">
  Vue + bulma tabs</a> by jhanyu (<a href="https://codepen.io/jhanyu">@jhanyu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
npmでStorybookをインストールした際にでたエラー

Macで、vue.jsをインストールしてて、storybookをインストールしようしたら、以下のエラーがでた

``no such file or directory, open '/private/var/root/package.json
``
とりあえず、
npm init
を実行したら。package.jsonが作成されて、インストールはできた
CoreOSで定期的にジョブを実行する

# はじめに
CoreOSは、CentOSやUbuntu等のLinuxと違い、cronの仕組みがありません。
本記事は、CoreOSなどcronがない場合に、定期的にジョブを実行するための方法について記載しています。

## 設定手順
CoreOSは、Sytemdでサービスに対するタイマーを設定することで、cronのように定期的にジョブを実行することができます。

本記事では、任意のスクリプトを1分毎に、実行する場合の手順について記載します。
はじめに、serviceファイルとtimerファイルを作成します。

- serviceの作成   
`sudo vim /etc/systemd/system/＜スクリプト＞.service`

```text
[Unit]
Description=＜スクリプトの説明＞

[Service]
Type=oneshot
ExecStart=＜スクリプトのフルパス＞
```

- timerの作成   
`sudo vim /etc/systemd/system/＜スクリプト名＞.timer`

```text
[Unit]
Description=＜スクリプト名＞.service timer

[Timer]
OnCalendar=*:0/1

[Install]
WantedBy=multi-user.target
```

- タイマーの有効化   
`sudo systemctl enable ＜スクリプト名＞.timer`
- タイマーの起動   
`sudo systemctl start ＜スクリプト名＞.timer`

## 動作確認
設定が完了したので、動作確認を行います。
`systemctl`コマンドでタイマーの状態を確認し、`journalctl`コマンドでログを確認します。

- 時間確認   
`systemctl list-timers`

```console
NEXT                         LEFT     LAST                         PASSED       UNIT                         ACTIVATES
Fri 2019-06-28 14:57:07 UTC  10h left Fri 2019-06-28 02:57:07 UTC  1h 35min ago rkt-gc.timer                 rkt-gc.service
Sat 2019-06-29 00:00:00 UTC  19h left Fri 2019-06-28 00:00:00 UTC  4h 32min ago logrotate.timer              logrotate.service
Sat 2019-06-29 01:56:43 UTC  21h left Fri 2019-06-28 01:56:43 UTC  2h 35min ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
n/a                          n/a      Fri 2019-06-28 04:32:12 UTC  7ms ago      ＜スクリプト＞.timer            ＜スクリプト＞.service

4 timers listed.
Pass --all to see loaded but inactive timers, too.
```

- ログ確認   
`journalctl -f -u ＜スクリプト＞.service`

```console
-- Logs begin at Wed 2019-05-08 23:58:13 UTC. --
Jun 28 04:29:09 docker-CoreOS systemd[1]: Started ＜スクリプト＞.
Jun 28 04:30:25 docker-CoreOS systemd[1]: Starting ＜スクリプト＞...
Jun 28 04:30:25 docker-CoreOS systemd[1]: ＜スクリプト＞.service: Succeeded.
```

# おわりに
CoreOSにcronが実装されなかったのには、理由があると思うので調べてみるのも面白いと思います。
brew searchで見つかるaws関連ツール全部試す（2019-06-29現在: 9/18 完了)

こんにちは。毎日 `aws-cli` のお世話になる中で、もっと楽しく効率的に業務を進める余地があるんじゃないか、と思いました。
そこで、2019-06-29現在、 `brew search aws` で見つかるコマンド全部試してみようと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/2275f9b9-dbb4-24db-c03e-f7d6145f3ecd.png)

# aws-apigateway-importer
API Gatewayの初期に、swagger.yamlなどからAPI Gatewayのリソースの定義を生成するために利用されていたツールのようだ。現在はaws cliなどに機能が取り込まれた、とのことで調査対象から除外。

# aws-iam-authenticator
Kubernetesクラスターとの通信用のAPIセキュリティトークンを取得するためのコマンドでしたが、`aws eks get-token` が実装されたために現在では不要なようです。

https://dev.classmethod.jp/cloud/aws/eks-update-get-token-cmd/

# aws-sns-cli
とりあえずインストールはしたものの、動かし方が全くわからない。
AWSのツール一覧にも掲載されていないので、サポート外になったのかな？調査対象から除外。

# aws-as
情報がまったくない...調査対象から除外。

# aws-keychain
[作者によると](https://github.com/pda/aws-keychain)、 `aws-vault` を使ってほしい、とのことらしい。メンテもしない、とのことなので調査対象から除外。

> Note: I recommend https://github.com/99designs/aws-vault instead, and will not be maintaining aws-keychain.

# aws-cfn-tools
おそらくaws cliに機能統合されているのでは？
私がaws cliを触り始めたのはここ1年の話なので知らないのだけど、どうも昔は`AWS API Tools`というJVMベースのaws cliがあったらしい。

# aws-mon
https://github.com/moomindani/aws-mon-linux

EC2インスタンスのメモリやCPU、ディスク使用量などを計測＆カスタムメトリクスに送信してくれるシェルスクリプトらしい。EC2インスタンスを運用する際には便利かもしれない。
私はだいたいFargateとLambdaで済ませてしまうけど、何かでは使うかも。
HomeBrewで入れる必要は感じないので、調査対象から除外。

# awslogs
クラメソさん記事でも紹介されているCloudWatch LogsをCLIから検索できるようにするツール。CloudWatch InsightsのCLI版ってところかな？
https://dev.classmethod.jp/cloud/aws/show-cloudwatch-logs-with-awslogs-command/

streamを取得するときにprofileを指定すると動作が怪しかったり、Lambdaが出力するStream名に特殊文字が入っているのに対応できていなかったり、困るポイントもあるけど便利なツールだなと思いました。


# 途中経過
2019-06-29現在: 9/18 完了。続きはいずれ...
C++/OpenCV行列積の単純なミスについて error: (-13:Image step is wrong) Step must be a multiple of esz1 in function 'cv::Mat::Mat'

C++ / OpenCVで行列積を計算したら、

```
cv::Mat a = b * c;
```

`Image step is wrong`というエラーが出た。

```
OpenCV(3.4.5) C:\bin\opencv-3.4.5\sources\modules\core\include\opencv2/core/mat.inl.hpp:592: error: (-13:Image step is wrong) Step must be a multiple of esz1 in function 'cv::Mat::Mat'
```

原因は単純に、`b.type()`と`c.type()`が違っていた。`b.type() == CV_32F`（float）、`c.type() == CV_64F`（double）でした。

OpenCVで行列積を計算するにはfloatまたはdoubleどちらかに合わせる必要がある。

typeをfloatに合わせたらちゃんと計算できた:smile:

```
// bはもともとCV_32FC1
c.convertTo(c, CV_32FC1);
cv::Mat a = b * c;
```

わかりにくいエラーメッセージでした:anguished:
Ruby で AWS S3 にある ファイルをダウンロードせずに読み込む例

https://github.com/aws/aws-sdk-ruby

```rb
credentials = Aws::Credentials.new('AWSAccessKeyId', 'AWSSecretKey')

region = 'ap-northeast-1' # some region
s3_resource = Aws::S3::Resource::new(region: region, credentials: credentials)

bucket = s3_resource.bucket('some-bucket-name')

# ファイル一覧を見る
# bucket.objects.each { |object| p object.key }

io = bucket.object('path/to/some.txt').get.body

str = io.read
```








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
JPAでのエラー　No Persistence provider for EntityManager named XXX

#概要
JPAで「No Persistence provider for EntityManager named　XXX」が発生したときの対処方法について記載します。

#対象読者
Eclipse初心者
JPA初心者

#サマリ
* persistence.xmlがソースフォルダのMETA-INFフォルダ存在するか確認する
* persistence.xmlの定義内容について確認する
* コードからユニット名を指定していることを確認する
* 依存関係が解決しているか確認する

#persistence.xmlがソースフォルダのMETA-INFフォルダ存在するか確認する
ソースフォルダならどこでも大丈夫ですが、以下が自然かと思います。
src/main/resources/META-INF/persistence.xml
![スクリーンショット 2019-06-29 6.36.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164224/807efd15-9cbf-f03e-332f-61996caa0ad9.png)

ちなみに、ソースフォルダはEclipseでプロジェクト→右クリック→ビルドパス→ビルドパスの構成→ソースタブで確認できます。
![スクリーンショット 2019-06-29 6.34.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164224/879a80b3-009d-a2af-4457-7a6afdc8d6f6.png)

#persistence.xmlの定義内容について確認する
persistence.xmlに必須の定義がない場合、タイトルのエラーが発生することがあります。
以下にサンプルを記載します。

```xml:persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
	xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">

	<persistence-unit name="TestJpaUnit">
		<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
		<class>org.arquillian.example.SampleEntity</class>
		<properties>
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306" />
			<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver" />
			<property name="javax.persistence.jdbc.user" value="mysql" />
			<property name="javax.persistence.jdbc.password" value="mysql" />
		</properties>
	</persistence-unit>
</persistence>
```
注意点のみ記載します。

* provider定義は必須です
* class定義はそのユニットで使用するEntityを記載します。
JavaEEサーバでアプリを動かさない場合（バッチとか）は必須です

#コードからユニット名を指定していることを確認する
EntityManagerを取得する際は、persistence.xmlに定義したpersistence-unit nameを指定します。

```java:SelectSampleEntity.java
public class SelectSampleEntity {

	@PersistenceContext(unitName="TestJpaUnit")
    private EntityManager em;

	public void execute(){

		List<SampleEntity> resultList = em.createQuery("SELECT e FROM SampleEntity",SampleEntity.class).getResultList();

		for(SampleEntity sampleEntity:resultList){

			System.out.println(sampleEntity.toString());

		}
	}
}
```

#依存関係が解決しているか確認する
上記を行っても　No Persistence provider for EntityManager named XXXが出る場合、
persistence.xmlに定義したproviderの依存関係が解決していない可能性があります。
今回の場合は、以下をpom.xmlに追加し、Maven更新を行ってみてください。

```
<!-- https://mvnrepository.com/artifact/org.eclipse.persistence/eclipselink -->
<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>2.5.0</version>
</dependency>
```
canvas+videoタグで視線情報を可視化

動画を見たときの視線情報をブラウザで可視化したい機会があったので、HTMLのcanvasで可視化しました。
下記のURLでデモが見れます。
https://jsfiddle.net/nakao324/r4epjdmo/16/

視線情報以外にも、動画の上に図形を描画したいときに利用できます。

# 実装
・HTML

```html
<div class="wrapper">
  <video id="video" src="test.mp4" disablepictureinpicture controls controlslist="nodownload nofullscreen" playsinline></video>
  <canvas id="canvas" class="canvas"></canvas>
</div>
```
・CSS

```css
.canvas{
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}

.wrapper{
  position: relative;
}
```

構造としては、まずはvideoタグで普通に動画を表示します。
そのvideoタグの上にcanvasを作り、canvasに視線情報を描画します。
videoタグとcanvasの位置と大きさがぴったり一致するようにCSSとJavascriptで調整します。
位置に関しては、CSSのpositionsを使って揃えます。

・Javascript

```javascript
const ctx = document.getElementById("canvas").getContext("2d")
const videoEl = document.getElementById("video")
//1秒毎の視線情報
const trackings = {1: [100,-80],2: [130,20],3: [130,50],4: [-100,30],5: [100,30],6: [-30,-10],
7: [-50,30],8: [100,30],9: [10,35],10: [40,60],11: [150,50],12: [120,70],13: [130,60]}
```
今回、視線情報のデータ構造は、{時間:[x座標, y座標], ...}としています。
中央の座標は(0,0)、一番右下は(180,90)、x座標は-180~180、 y座標は-90~90としています。

```javascript
videoEl.addEventListener("timeupdate", function() { 
  const currentTime = Math.round(videoEl.currentTime)   //現在の再生時間
  //ビデオタグの縦横幅を取得し、canvasに代入
  let w = videoEl.clientWidth; 
  let h = videoEl.clientHeight; 
  $('#canvas').attr('width', w)
  $('#canvas').attr('height', h)
  
  //視線の所に赤い丸を描画
  ctx.beginPath()
  ctx.clearRect(0, 0, w, h) 
  if(trackings[currentTime] != null){
  	ctx.arc(trackings[currentTime][0]*w/360 + w/2, trackings[currentTime][1]*h/180 + h/2,  20, 0, Math.PI * 2)
    ctx.strokeStyle = "red"
    ctx.lineWidth = 2
    ctx.stroke()
  }
}, true)
```

1行目のtimeupdateで、動画の再生時間が変わる毎に処理が実行されます。
4~7行目で、videoタグの縦横の長さを取得しcanvasに渡します。
この処理を入れないと、動画再生中に画面幅が変わった時にcanvasの描画がずれてしまいます。
最後に、現在の再生時間の座標が存在するときに図形を描画します。

[追記]
heatmap.jsを使うと、多人数の視線情報でも見栄え良く描画できます。
ルティングをネストする意味

ユーザーのツイートに対して、コメントできる機能の実装において、ルティングをネストする理由をアウトプットする。

#理由
各ユーザーのツイートにコメントするためには、コメントする対象であるツイートid先を知らなければならない。そのため、コメントのルーティングは、tweetのルーティングの中でを設定してしまう。その方が、コメントする際にそのツイートに対すコメントであるのかを一発で判断できるからである。つまり、アソシエーション先のレコードのidをparamsに追加してコントローラに送れることが最大のメリットとなるのである。

以下のように、ルーティングを設定する。

```ruby

Rails.application.routes.draw do
  resources :tweets do
    resources :comments, only: [:create]
  end
end
```
ネストをする際は、親のルーティング(？)の後に子のルーティングをdoとendで挟むことでできる。

ネストの記述ができたら、ターミナル上にてrake routesコマンドを実行して、ルーティングのネストができているかを確認する。成功していれば、以下のような表示になる。
https://gyazo.com/e331d78f258b4dc86345e143237be600
KotlinでAndroidアプリ作成〜準備編〜

##はじめに
html、css、javascript、phpとプログラミング勉強始めて３ヶ月
Androidアプリをつくりたいと思って情報収集、準備をはじめました

なにからはじめていいか分からない！
でも、言語はKotlinつかって書こうと思ってるよ！
そんなザックリ手探り状態の中進めていっている内容をメモ！

### 参考書籍
[作って楽しむプログラミング Androidアプリ超入門](https://www.amazon.co.jp/%E4%BD%9C%E3%81%A3%E3%81%A6%E6%A5%BD%E3%81%97%E3%82%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-Android%E3%82%A2%E3%83%97%E3%83%AA%E8%B6%85%E5%85%A5%E9%96%80-WINGS%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88-%E9%AB%99%E6%B1%9F-%E8%B3%A2/dp/4822253902/ref=zg_bs_3229699051_27?_encoding=UTF8&psc=1&refRID=7FT5411A9EQTRWGH4T6V)
※Windows用の書籍だが手順はMacでも変わらないのでおすすめ

##内容
- 開発環境
- 必要なソフトウェア
- Android端末がない場合の模擬実行環境
- Android端末での動作確認


##開発環境
###PC
- MacBook Pro (Retina, 13-inch, Early 2015)
- macOS Mojave 10.14.3

###Android端末
- AQUOS SH-M08
- Androidバージョン8.1.0


###必要なソフトウェア
下記リンクよりダウンロードする
- [Android Studio](https://developer.android.com/studio/)

※SDK Components Setup画面で**Android Virtual Device**にチェックをいれる
→それ以外はNextやFinishをクリックして進めていく

###Android端末がない場合の模擬実行環境
Androidエミュレーターで動作確認ができる

###Android端末での動作確認
以下の方法がある
- USB接続
- アプリインストールファイルをSDカードなどでインストール
- Google Playストア経由

##メモ
基本的に書籍の手順どおりで問題なく準備ができる
いろんなサイトで開発環境準備について記載されているが、本１冊買って進めるほうが迷子にならないのでいいよー
違法コピーWordPressテーマを使用するとウイルスに感染するかもしれません

半分愚痴になるんですけど。

ワードプレスのテーマを作って売ってるんですが、いえ、こちらはストレスが溜まる趣味程度の副業になってきていまして。最近は採算合わないし。ピークは2013年頃に過ぎたと思ってます。いまだにワードプレスのテーマ売って稼いでられる方は凄いですね。

で、昨日の深夜にですね、「おまえんとこのテーマインストールしたら、サイト動かんごつなったやんけぇ！なんで応対が遅いの？おまいら最悪じゃくさ！最低評価つけたる！」（英語からの日本語超訳）とメキシコ人と思われる方から苦情のメッセージが入りました。

勘弁してください。私共はサイボーグじゃありません。メンタルは豆腐より柔らかくてもろいです。

さてさて、気を取り直して診断いたしました。以下はサイト診断のチラ裏・日記です。

#### 症状は「ワードプレステーマをインストールしたら、サイトがメッセージを出したまま動かなくなる。」と言うものです。

確かに我々のサイトのテーマをアクティベートすると止まります。スペイン語でメッセージが表示されているので、何が書いてあるのかわかりません。そのままエラー文を思われるものをコピーして、WordPressのソースを検索するのも大ありですが、ここは言語設定を英語にしてから、再びエラーをわざと起こさせてみます。すると、

```
The site is experiencing technical difficulties. Please check your site admin email inbox for instructions.
```

日本語版ではこの様に表示されるようです。

```
サイトで技術的な問題が発生しています。サイト管理者のメールを確認して指示に従ってください。
```

何回もエラー出させてみましたが、メール来ません。ログ探したけどなかったので、どうにかしてエラーログか何かを取りたい。

とりあえず、エラー文そのままソースコード検索してみました。すると、ワードプレスの"wp-includes/class-wp-fatal-error-handler.php"とう言うファイルにエラーメッセージを表紙している該当箇所が見つかります。

WP_Fatal_Error_Handlerクラス内のdisplay_default_error_templateという保護されたメソッド内で表示されている様です。このメソッドには\$errorが渡されているので、var_dump($error);を試しに入れてみるとエラー内容が表示されました。内容は。。。「functions.phpのnamespaceの前にコードがあるので致命的なエラー発生しました。」みたいなことが書いてありました。

なるほど。それでは、エラーが出ていたテーマのfunctions.phpをみてみましょう。

え？こんなコード書いた覚え無いんですけど。どうやら、テーマを起動するたびに、この変なコードが勝手に挿入されてしまうらしい。

我々のテーマではnamespace使っているけど、他のテーマでは使われていない。だから我々のテーマでだけエラーが出ていた。

それでは、更に、インジェクトされたコードを追ってみましょう。

どうやらサイトのどこかにあるwp-tmp.phpと言うファイルを読み込む様になっているみたいです。ルートになかったらwp-includes/wp-tmp.phpと言う様に。

![Screen Shot 2019-06-28 at 18.56.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145550/9c2e59eb-936a-f4ca-115d-b61a815e9a76.png)

wp-tmp.phpありました。wp-vcd.phpというファイルもあります。こいつらはWordPressのファイルじゃない曲者です。wp-vcd.phpの中身をみてみましょう。

![Screen Shot 2019-06-28 at 18.57.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145550/1e1c207a-e908-e2ca-c908-15736392adae.png)

なにやら毒々しい英数字の羅列が。試しにこいつをどうせお約束のBase64だろうと持ってデコードしてみると、先ほどのインジェクトされていたコードそのまま出てきました。犯人はこいつです。

#### ウイルスに感染したら

ただちにその道の先生に連絡して、ウイルスを完全除去してもらいましょう。できれば明日より今日、あとで〜より$今すぐ$が良いです。

今回のウイルスはどんな悪さをするか調査さえしていませんが、過去に出くわしたウイルスでは、SEO評価をズタズタにしてサイトの信用度を徹底的に下げる様に動くものがありました。しかも消したら増える系。一旦被害にあってSEO評価が下がると、挽回するまで色々と時間とか労力かかりますので。他にも何をされるかわからないし、サイト訪問者への何らかの被害がでるかもしれない。なので駆除は今すぐです。

#### 感染する前に気をつけておくこと

分かり易すぎるパスワードは絶対に使わない。パスワードの使い回しはしない。パスワードを共有しないなど、常識レベルの防御策に加えて、サイトセキュリティのプラグインをインストール直後にしっかりと導入することです。やつらはどこからいつやってくるかわかりません。気がついたら入っています。

#### 感染経路は違法コピーWordPressテーマ？

いえ、決して、このお客様が違法コピー(英語圏ではnulledと言われている)をしているとはもうしませんが、一般的に、可能性としてはありうるということです。[wordpress.orgのフォーラムスレッド](https://wordpress.org/support/topic/warnings-unknown-file-in-wordpress-core-wp-includes-wp-tmp-php/)に、その可能性を指摘している方がいました。

というわけで、[WordPressは未だにシェアダントツ一位](https://news.mynavi.jp/article/20190604-836392/)。すでに34%になってる。この前25％超えたと話題になっていたばかりの気がするのに。悪い人のターゲットにもされやすくなったと言うことで。

#### WordPress業の次を考えてる

シェアが伸びている割には、WordPress関連の商売は儲けるのが難しくなってきた気もします。お客様の期待するレベルが上がり、初心者も使う様になったのでサポートが凄く面倒くさくなってきた上に、競争がすごく激しくなってきていますし。もうそろそろWordPress関連業も潮時かな。。。
CRUD機能のC(Create)の仕組み

CRUD機能とは、ほぼ全てのソフトウェアが有する4つの永続的な基本機能の頭文字をそれぞれ並べた用語のことをいう。 その4つの機能とは、Create（生成）、Read（読み取り）、Update（更新）、Delete（削除）を指す。

今回は、CのCreateについての仕組みを解説する。そのため、主にコントローラのnewアクションとcreateアクションについて解説する。Createは、新規投稿である。つまり、データベースに何も既存のデータが存在しない場合において、新しくデータを作り出す(文字通りCreate)ことを意味する。



#1.Createの処理の流れ

新しいデータを入力する処理
　　　　　↓
入力した新しいデータをデータベースに保存する処理


#2.新しいデータを入力する処理

新しいデータを入力するためには、投稿画面(入力画面)に移動する必要がある。

ルーティングを設定する。

```ruby

get   'tweets/new'  =>  'tweets#new'
```

コントローラを設定する

```ruby

def new
end
```
newアクションは、データを新たに入力するために画面に移動するためのアクションを行うだけである。そのため、モデルを経由したデータベースとのやりとりを行わないので、データベースへの処理の記述はしなくてよい。

newアクションによって、それに紐づいたビューファイルを呼び出す。このファイルが新規投稿画面となる。

#3.入力した新しいデータをデータベースに保存する処理

newアクションによって呼び出された新規投稿画面に新規投稿する。その際、ビューの方であらかじめ、ルーティングが呼び出される記述をする。(今回は、form_tagを使う。)

```html
<%= form_tag('/tweets', method: :post) do %>
```
これにより、新規投稿した時にルーティングが呼びだされる。

ルーティングの設定

```ruby

 post  'tweets'      =>  'tweets#create'
```
これにより、新規投稿した時にコントローラのcreateアクションが実行するようになる。


コントローラの設定

```ruby
def create
    Tweet.create(image: tweet_params[:image], text: tweet_params[:text], user_id: current_user.id)
end
```
createアクションは、newアクションの時とは異なり、モデルを経由してデータベースに新しくデータを保存する処理が必要となる。そのため、createアクションの中にデータベースにデータを保存するための処理を記述する必要がある。今回は、画像とテキストとuserのidをデータベースに保存する。
DNN_後編

##Day 3

####要点
https://qiita.com/taktakeuchi/items/5e095d660099744ab7b2

####確認テストの考察
https://qiita.com/taktakeuchi/items/20ab216af945fc36bf16

####Jupyter演習
https://qiita.com/taktakeuchi/items/f7e20795c829c5bb4983


##Day 4

####要点
https://qiita.com/taktakeuchi/items/f5b445297bf9a17a8074

####確認テストの考察
https://qiita.com/taktakeuchi/items/64d34eab607449a80673

####Jupyter演習
https://qiita.com/taktakeuchi/items/d506caaef4cce47d0e7a
CSSだけでトリミング (IE対応)

object-fitを使えば簡単ですが、これがIEに対応していないのですよね…。
<img width="1250" alt="object-fit.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129766/9965d320-60f9-1f5f-b49b-ffa081583ff3.png">
https://caniuse.com/#feat=object-fit

そのためtransformを使って、正方形の画像を任意のサイズに拡大・縮小して表示する方法についてまとめます。

# トリミングする画像
<img width="258" alt="1x1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129766/6d2d58ca-0120-7757-7a78-1ad734d2cf54.png">

縦横500pxの正方形の画像です。

# 2:3の縦長にトリミング
<img width="255" alt="2x3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129766/1dc5af46-a355-1ead-e105-44ce4a22de4c.png">

## HTML
```
<div class="_2x3">
  <img src="500x500.jpeg">
</div>
```
## CSS
```
._2x3 {
  position: relative;
  width: 500px;
  overflow: hidden;
}

._2x3::before {
  content: " ";
  display: block;
  padding-top: 150%; // 3/2*100=150
}

._2x3 > img {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  width: auto;
  height: 100%;
}
```

ポイントは500pxのブロックに疑似要素でpadding-topを使って、縦に150%（3÷2×100）の領域を追加している点です。width:100%のときは疑似要素は要らないので、ブロックに直接領域を追加してもOKです。
そして、imgタグにabsoluteで重ねて、transformで中心から表示させています。（transformについては割愛します）
また、トリミング前の画像の高さが500pxなのに対して、領域は750pxのためheightを100%に設定しておくことで画像が拡大されています。
当然、画像は荒れるのでトリミングするサイズにはご注意をください。
これは悪い例で、widthは333px（500÷(3÷2)）にするとheightは500px以内に収まります。

# 16:9の横長にトリミング
<img width="258" alt="16x9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129766/b2b5e0e3-a765-ad71-0d76-e30a6723114d.png">

## HTML
```
<div class="_16x9">
  <img src="500x500.jpeg">
</div>
```

## CSS
```
._16x9 {
  position: relative;
  width: 500px;
  overflow: hidden;
}

._16x9::before {
  content: " ";
  display: block;
  padding-top: 56.25%; // 9/16*100=56.25
}

._16x9 > img {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  width: 100%;
  height: auto;
}
```

前述の縦長とやり方は同じですが、異なる点は、
・縦に56.25%(9÷16×100)の領域を設定
・widthを100%に設定 ※サイズは足りているので設定しないでも大丈夫です
の2つです。

# まとめ
トリミングしたい比率を計算してpadding-topなどで領域を作ります。
トリミングする画像サイズより大きい領域を作る場合は、縦長のときはhightを100%を設定し、横長のときはwidthを100%を設定します。このとき、画像は荒れているのでご注意を！
LambdaからAPI Gateway(IAM認可)へのアクセス方法 [Node.js版]

AWS上でServerlessかつMicroservicesな構成の場合、Lambda内から別サービスのAPI Gatewayにアクセスすることがある。
API GatewayがIAMでアクセス制限がかかっている場合のアクセス方法が分からなかったので調査した。

※ Python版は[こちら](https://qiita.com/t_sugawara-01/items/d85e963e35b7fb3212bf)

## 前提
- Lambda (Node.js 10.x)
- LambdaにIAM Role付与済み
- API Gateway(IAM認可)作成済み

※ API Gatewayの設定方法やIAM Roleの内容などはここでは取り扱わない

## 結論
aws-sdkのSigners.V4で署名する。

```javascript:index.js
const https = require("https")
const AWS = require("aws-sdk")

exports.handler = async (event) => {
  const HOST = "XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com"
  const STAGE = "dev"
  const PATH = "/your/resource"

  const url = `https://${HOST}/${STAGE}${PATH}`
  const req = new AWS.HttpRequest(url, process.env.AWS_REGION)
  req.method = "GET"  // Default => "POST"
  req.headers.host = HOST

  // Sign
  const signer = new AWS.Signers.V4(req, "execute-api", true)
  signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate())

  // Request
  const res = await new Promise(resolve => https.get(req.endpoint.href, req, resolve))
  const body = await new Promise(resolve => res.on("data", resolve))

  // Do something 
}
```

AWS.Signers.V4 で AWS.HttpRequest を署名する。
⇒ 下記のようなHeadersが設定される

```javascript:req.headers
{
  'X-Amz-Date': '20190628T180333Z',
  'x-amz-security-token': 'AgoJb3JpZ3luX2VjEBgaDmFwLW6vcnRoZWFzdC0xIkcwRQIgXKqUW7xJYR7xjI8r3A8867/J/258UZa3dVZTZXJhZdoCIQCtfBGGCJQR2RIGAaFMUzXdr4MXYzVapq0dUV8tN6QWGSqAAghhEAIaDDM1OTAzMDQzODQ5MSIMuUdqb7U/zKQD0S6GKt0BOkhXekZuxE8LCL9u8ktGjEeQJGHXiRvyfQ8ohzGRlWzmql66Ao1ArjTjYB1Bw7hbnFs4EUylvwc1XBvbEG/OEyWm1rpbZqe5U5Jg0Z9HY8UvJ2wrjKTH4OBMIYMXk4ZdHu9djIx+6d1Ap0E2F2SAtyMsaG75gFuNOx6frG7T0ZFj9t/pT+5HfxE5349VbxaBX6PvRvOIDfLXqv2UacY9eq3gRkkCNOlBm/4Z+iHyQLkWxkOeG05YIx2r7oeeBqN/459KeKU/pDJMcc/QbnTilCQx+oedEmlV+HRfVIswmPbY6AU6tAHD/gc0T1Rszlg1QgZ7aytsID5JvZCaO6/0SYx0C6mx2G/vrQQivQlxCkK396anWK+sVu69goOxay8cs+wov5+TVtL+1ybPYsMJIv6Pb0/zNS82jyh2Va1YOZ8Ep/i/VHrvPVgVLL1419Ly92MhkPZqMecDiniomEzfBchLYpB+eZ/+B+8+SnqOBuooz+QiF+y8doSBMj24ahhEaa7ErGC/rTI1VuT0GSN8a43N1hpkZ7O9Vlg=',
  Authorization: 'AWS4-HMAC-SHA256 Credential=ASIAVHFXXXXXXXXXXXXX/20190628/ap-northeast-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date;x-amz-security-token, Signature=ac00aaab0b00fe0a000000e0fd0a00c00aab00000b0000a0a000bddb0b000d'
}
```

AWS.HttpRequest 自体はリクエストを発行してくれないので、別途httpsやrequestsなどでリクエストを送る必要がある。

## 参考
https://docs.aws.amazon.com/ja_jp/general/latest/gr/sigv4_signing.html
https://www.cloudspecialist.uk/2017/04/08/How-to-make-custom-IAM-authenticated-requests-to-AWS-API-Gateway/
https://qiita.com/paper2/items/cea6021512132f070403
https://qiita.com/toshihirock/items/a92cbda51d5f469bb0ac
https://qiita.com/crifff/items/6dff429555c898a19758
WindowsでOpenJDKを手動ビルドする

手動ビルドとかおなかがきっと痛くなってしまうやつ。たぶん苦行。覚書。
[README](https://hg.openjdk.java.net/jdk8u/jdk8u/raw-file/tip/README-builds.html#get_source)にそって作業をする。

## 手順

#### 環境準備編

1. Cygwinをインストールする。別にCygwinじゃなくっても好きなやつでいいと思う。
2. Mercurialクライアントをインストール。  
   [ここ](https://www.mercurial-scm.org/wiki/Download#Windows)から好きなのをインストール。  
   楽そうな響きに弱いので、TortoiseHgをインストール。（無心でNextを押す）  
   ちょっとggrとGUIクライアントで人気らしい
4. Cygwinの場合、OpenJDKのビルドに必要なツールがそろってないと思われるので[README](https://hg.openjdk.java.net/jdk8u/jdk8u/raw-file/tip/README-builds.html#get_source)の表に書いてあるものをすべてインストール。
ちなみに、パッケージの追加は、Cygwinのインストールに使ったsetup.exeをもう一度起動すればOK。  
インストールの時と同様に進めて、SelectPackagesのところで、ViewをNotInstalledにして必要なものを選択する。（画像はzipのインストール例）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212399/0dc15de1-896f-14af-1c8b-d3ae1b53775c.png)  
次へを押した後に出てくるインストールするものの一覧。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212399/dc6d1aa7-563a-bea8-dd6d-7d9e7cc6976f.png)

### ビルド編

1. OpenJDKのソース全体を取ってくるために、ルートリポジトリにあるget_source.shを実行する。  
<pre>
$ cd /cygdrive/d
$ hg clone http://hg.openjdk.java.net/jdk8/jdk8
$ cd jdk8
$ bash ./get_source.sh
スクリプト実行が成功したらフォルダの中身は下記のようになる（たぶん）
$ ls
ASSEMBLY_EXCEPTION  hotspot    LICENSE   README-builds.html
common              jaxp       make      test
configure           jaxws      Makefile  THIRD_PARTY_README
corba               jdk        nashorn
get_source.sh       langtools  README
</pre>

2. ビルド開始。
<pre>
$ bash ./configure
</pre>
何やらエラーが出た。
<pre>
configure: Your cygwin is too old. You are running 3.0.7(0.338/5/3), but at least cygwin 1.7 is required. Please upgrade.
configure: error: Cannot continue
configure exiting with result code 1
</pre>
Cygwinのバージョンが悪いらしい。一見、1.7以上が必要で3.Xなのでよさそうだけど、jdk8/common/autoconf/basics_windows.m4 を見ると下記のような記述が。
<pre>
CYGWIN_VERSION_OK=`$ECHO $CYGWIN_VERSION | $GREP ^1.7.`
    if test "x$CYGWIN_VERSION_OK" = x; then
      AC_MSG_NOTICE([Your cygwin is too old. You are running $CYGWIN_VERSION, but at least cygwin 1.7 is required. Please upgrade.])
</pre>
どうも1.7系以外ははじかれる？
autotoolsの知識ほぼ０なので、こっちの設定を1.7以上に書き換えるか、1.7系の古いCygwin取ってくるか悩む。前者をいったん頑張ったほうが学びはありそう。

今日はここまで。作業進めたら随時更新。
V言語コトハジメ

## The V Programming Language

公式サイトは[こちら](https://vlang.io/)。

> Please note that the name of the language is "V", not "Vlang" or "V-Lang" etc. 

正式名称は「V」だそうです。
「Vlang」や「V-Lang」などと呼ばないでね。ということですが、それってググラビリティ悪すぎるのでは？

ドキュメントは@MikuroXinaさんが和訳してくださっているので、こちらを参考にすると良いでしょう。
[V プログラミング言語](https://qiita.com/RkEclair/items/be3d4d9198cab32aed64)

## 導入

まずは導入しましょう。
いつものごとくDockerでサクッと。

```shell-session
kajiken@kajiken:~$ docker run --rm -it ubuntu
root@5ec2d954e645:/# apt-get update
root@5ec2d954e645:/# apt-get install vim git make curl gcc -y
root@5ec2d954e645:/#
root@5ec2d954e645:/# git clone https://github.com/vlang/v
root@5ec2d954e645:/# cd v/compiler
root@5ec2d954e645:/v/compiler# make
cc -std=gnu11 -w -o v v.c
./v -o v .
Looks like you are running V for the first time.
Setting VROOT to "/v".
root@5ec2d954e645:/v/compiler# ln -s /v/compiler/v /usr/local/bin/v
root@5ec2d954e645:/v/compiler# cd
root@5ec2d954e645:~#
root@5ec2d954e645:~# echo println\(\'Hello World\'\) > hello.v
root@5ec2d954e645:~# v hello.v 
println
println
Generating main()...
root@5ec2d954e645:~# ll hello
-rwxr-xr-x 1 root root 65824 Jun 28 0:15 hello*
root@5ec2d954e645:~# ./hello 
Hello World
root@5ec2d954e645:~# v run hello.v 
println
println
Generating main()...
============running hello==============================
Hello World
root@5ec2d954e645:~#
```

先にコンパイルしておいてから実行するのも、実行時にコンパイルすることも出来ます。

## Web Serverを立てる

本当はこれをやりたかった。

> Powerful built-in web framework [wip]
>
```golang
['/post/:id']
fn (b Blog) show_post(id int) vweb.Result {
  post := b.posts_repo.retrieve(id) or {
     return vweb.not_found()
  }
  return vweb.view(post)
}
```

コンパイラのソースを見てもvwebが見つからない。
どうやら、この部分は7月上旬まで掛かるそうです。
https://github.com/vlang/v/issues/695

出てからやりましょう。

## お天気情報を取ってくる

このままHello Worldだけでは終われないので、HTTPで何か取ってくる処理を書きます。
はい、というわけでサクッと作ってみました。

```javascript:weather.v
import http
import json

struct Description {
  text   string
}

struct User {
  title  string
  description Description
}

fn main() {
  data := http.get('http://weather.livedoor.com/forecast/webservice/json/v1?city=260010')
  weather := json.decode(User, data) or { return }
  println(weather.title)
  println(weather.description.text)
}
```

```shell_session
root@5ec2d954e645:~# v run weather.v 
============running weather==============================
京都府 京都 の天気
 近畿地方は、前線や湿った空気の影響でおおむね曇り、激しい雨の降っている所があります。

 今夜の京都府は、前線や湿った空気の影響で北部を中心に雨や雷雨となる所があるでしょう。北部では夜のはじめ頃まで激しく降る所がある見込み。
 
 明日の京都府は、前線や湿った空気の影響で曇り、北部では昼前から、南部では夜から雨となる見込みです。また、夕方まで雷を伴う所があるでしょう。
root@5ec2d954e645:~#
```

できた！

JSONを扱うには構造体を用意する必要があるみたいです。
複雑なJSONを使うときはちょっと面倒かもしれません。

ちなみに、`V`からHTTPを投げる際には`curl`を使っているようなので、エラーになったら`libcurl4-openssl-dev`を入れてやりましょう。

```shell-session
root@5ec2d954e645:~# v run weather.v 
/root//.vlang//weather.c:73:10: fatal error: curl/curl.h: No such file or directory
 #include <curl/curl.h>
          ^~~~~~~~~~~~~
compilation terminated.
V panic: clang error
root@5ec2d954e645:~# apt-get install libcurl4-openssl-dev -y
```
DjangoをWindowsServer + Apache環境で使おうとしてハマりまくった

#DjangoをWindowsServer + Apache環境で使おうとしてハマりまくった
##この記事について
Djangoで簡単なWebアプリケーションを作ったので、せっかくだからWebサーバを構築して公開しようと思ったらハマりまくった。なんとか先人達の知恵を頼りに構築ができたので備忘もかねて書いていく。

#環境
WindowsServer2012R2
Apache2.4.39
django2.2.1

#Apacheをインストールしてみたら早速ハマる
手始めにApacheをインストールし、起動しようとしたら「The requested operation has failed!」メッセージが。管理ツール→サービスタブからApacheを起動しようとすると「 [エラー 1053](https://support.microsoft.com/ja-jp/help/3065893)」が出ていた。
色々調べてみた結果、Apacheを実行するために「Microsoft visual C++ 再頒布可能パッケージ (x64)」が必要と記載された[記事](https://yoshiyoshifujii.hatenablog.com/entry/2013/08/31/001002)を発見！
上記のパッケージを入れたらApacheが問題なく起動するようになった。（ちなみにこのパッケージを入れるとき、特定のセキュリティパッチが当たっていないとエラーが発生するらしい。とりあえずこの時は当たっていないセキュリティパッチを全部当ててから作業を行った）

#mod_wsgiをインストールしようとしたらやっぱりハマる
Apacheが正常起動したので、次はmod_wsgiだ！と思い以下のコマンドを打った


```console
pip install mod_wsgi
```

が、大量のエラーが出てもはや原因が追えない。。
仕方ないので、[この記事](https://qiita.com/hatai/items/279ec1dfd28cb9693a1f)を参考に自分の環境に合わせたホイールファイルをダウンロードした上でpipを使ってインストールを行うと見事成功！

#mod_wsgiをインストールできたはいいが
インストール後、python.exeがあるフォルダに「mod_wsgi.so」というファイルができるらしいが・・・あれ、見当たらない。。
[他の記事](http://cream-worker.blog.jp/archives/1071537855.html)が編集しているhttpd.conf内のLoadModule情報が「mod_wsgi～.pyd」になっていることに気づく。自環境のPythonフォルダ内を探してみると「Python37→Lib→site-packages」フォルダ内に同名ファイルを発見！.soの代わりに.pydファイルを使ってみることにした。

#httpd.confを編集
作成したdjangoファイルをドキュメントルートフォルダ配下に格納し、httpd.confを以下の通り編集。

```config

(略)
#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to 
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 80
(略)
#
# ServerName gives the name and port that the server uses to identify itself.
# This can often be determined automatically, but we recommend you specify
# it explicitly to prevent problems during startup.
#
# If your host doesn't have a registered DNS name, enter its IP address here.
#
ServerName localhost:80
(略)

#httpd.conf末尾に追記
LoadModule wsgi_module "C:/python37/lib/site-packages/mod_wsgi/server/mod_wsgi.cp36-win32.pyd"

WSGIPythonHome "C:/python37"
WSGIScriptAlias /mysite "C:/documentroot/mysite/mysite/wsgi.py"
WSGIPythonPath "C:/documentroot/mysite"

<Directory C:/documentroot/mysite/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

```

これを保存し、Apacheを再起動したところ、無事作成したwebアプリケーションがブラウザで確認できるようになった。

#参考文献
参考にさせていただいた記事は以下の通り。ありがとうございました。

http://cream-worker.blog.jp/archives/1071537855.html
http://nyarurato.hatenablog.com/entry/2017/07/18/171421
https://qiita.com/hatai/items/279ec1dfd28cb9693a1f
https://www.sejuku.net/blog/27637
https://yoshiyoshifujii.hatenablog.com/entry/2013/08/31/001002
DNN_後編2 (要点)

#Section1：TensorFlowの実装演習
実務では、numpyを使ってフルスクラッチでNNを組むような事は少なく、TensorFlowなどを利用する事が多い。
TensorFlowはGoogleが開発したフレームワークもので、世界中でユーザ数が最も多い。
TensorFlowを使う事で、簡単にディープラーニングの実装を行う事が出来る。
numpyなどと作法が違うところがあるので、tensorFlowの作法は、演習を通して覚える必要がある。

Keras：
TensorFlowのラッパーのライブラリ。
TensorFlowをそのまま使うよりも、CNNなどは簡単にコーディングする事が出来るようになっている。
初心者にはすごく使いやすいディープラーニングのライブラリになっている。

但し、簡単に書ける分、複雑な構造を書きたい場合は、TensorFlowで書く必要がある。




#Section2：強化学習
###Section2-1：強化学習とは
長期的に、報酬を最大化出来るように、環境の中で、行動を選択出来るエージェントを作る事を目標とする機械学習の一分野。
行動の結果として、与えられる利益（報酬）をもとに、行動を決定する原理を改善していく仕組み。

これまで見てきた、教師あり学習/教師なし学習とは違った、新しい分野。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/bb42eff6-cbe6-2205-62f6-82b2bd48303b.png)

###Section2-2：強化学習の応用例
####【マーケティングの場合】
環境：
　会社の販売促進部
エージェント：
　プロフィールと購入履歴に基づいて、キャンペーンメールを送る顧客を決めるソフト
行動：
　顧客ごとに送信、非送信の2つの行動を選ぶ
報酬：
　キャンペーンのコストという負の報酬と
　キャンペーンで生み出されると推測される売り上げという正の報酬を受ける

####【囲碁の場合】
環境：
　対戦相手のモデル
エージェント：
　盤面に応じて、次の一手を考えるソフト
行動：
　手を打つ
報酬：
　勝敗


###Section2-3：検索と利用のトレードオフ
強化学習については、事前に完璧な知識があるという前提ではなく、
不完全な知識をもとに行動しながら、データを収集して、最適な行動を身についていく事になる。

そこで、過去のデータの中で、ベストだった行動ばかりを常に取り続けると、他の可能性を見つける事が出来ない（他にもっといい行動があるかもしれない）。

逆に、過去のデータにない、未知の行動ばかりを取り続ければ、過去の経験を生かせない、全く学習しない行動ばかりになってしまう。

強化学習では、過去のベストな行動と、未知の行動とのトレードオフを調整する事が重要になる。


###Section2-4：強化学習のイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/858059fe-beb3-3c7e-b8af-f06805973309.png)
①（行動）エージェントが、環境に対して、方策πを実施する。
②環境が、状態sになる。
③状態sをエージェントが観測する。
④状態sにおける報酬価値vを、エージェントが受け取る
という①～④が一連の強化学習の流れになる。


###Section2-5：強化学習の差分
これまでやってきた、教師あり/なし学習と、強化学習との違いは、
教師あり/なしでは、データに含まれるパターンを見つけ出して、データから分類や回帰を予測する事が目標だったが、
強化学習では、優れた方策を見つける事が目標になる。


###Section2-6：行動価値関数（Q関数）
行動価値関数：
価値を表す関数は、状態価値関数と行動価値関数の2種類ある。

状態価値関数：ある状態に注目する場合
行動価値関数：状態と価値を組み合わせた価値に注目する場合

Q学習は、行動のたびに、行動価値関数を更新する学習を行う。


###Section2-7：方策関数
方策関数：
方策ベースの強化学習において、
ある状態で、どのような行動をとるのかの確率を与える関数。

例）
状態aであれば、行動Aをとる確率が80%、行動Bをとる確率が20%
状態bであれば、行動Aをとる確率が20%、行動Bをとる確率が80%
というように、同じ行動でも状態によって、確率が変わってくる。


###Section2-8：方策勾配法
方策勾配法とは、方策を再帰的に更新していくようなモデル。
数式は次の通り：

$\theta^{(t+1)} = \theta^{(t)} + \epsilon \nabla J(\theta) $

勾配降下法の時と同じような数式になっていて、
次の方策の時に、$\epsilon \nabla J(\theta) $を加えるような形になっている。

ここで$J(\theta)$は、方策の良さを表しているもので、これについては、いくつか定義方法がある（何をもって良いと判断するかの基準）。
次のような定義方法がある：
・平均報酬：行動をとった時に生まれる、価値全部の平均をとったもの。
・割引報酬和：報酬を足し合わせる時に、行動した時間に対して、未来の報酬ほど価値を減衰させる方法（一番時間の近い価値を重要視する）。
配列の中の数字の数を数えるメソッド

配列の中に複数の数字を入れて9だけカウントして、その数を出力させるメソッドを作る。


```ruby

numbers = [9, 2, 5, 5, 9, 3, 9, 2, 4, 3]

def array_count9(nums)
  count = nums.count(9)
  puts count
end
```

array_count() 関数は、配列内の要素の数を返すメソッドである。
処理の流れは、配列内の9という数字の数をか添えて、countという変数の中に代入する。そして、putsメソッドでcountという変数の中に代入された数字を出力する。



＜参考記事＞


・https://ref.xaio.jp/ruby/classes/array/count
・https://www.ibm.com/support/knowledgecenter/ja/SSULQD_7.1.0/com.ibm.nz.sqltk.doc/r_sqlext_array_count.html
・https://www.ibm.com/support/knowledgecenter/ja/SSULQD_7.1.0/com.ibm.nz.sqltk.doc/r_sqlext_array_count.html
rails + vue 環境構築

## Vueの導入

### Gem の導入

```ruby:Gemfile
gem "webpacker", github: "rails/webpacker"
```

bundle install

### yarn の導入

versionが出ればインストール済

```
$ brew install yarn

$ yarn -v
yarn install 1.15.2
```

### webpacker のインストール

```
$ bundle exec rails webpacker:install 
```

Rails で webpack を使うために必要な設定ファイルが自動作成される。

### Vue の初期ファイルの導入

```
$ bundle exec rails webpacker:install:vue
```

Vue を動かすのに必要なファイルが自動的に作成されます。


## vueを表示する設定

### 各ファイルの修正

```ruby:config/routes.rb
Rails.application.routes.draw do
+  root 'homes#index'
  resources :articles
  resources :users, defaults: { format: :json }
-  get 'homes/index'
end
```

```ruby:controllers/homes_controller.rb
class HomesController < ApplicationController
  def index
  end
end
```

```ruby:views/homes/index.html.erb
<%= javascript_pack_tag 'hello_vue' %>
<%= stylesheet_pack_tag 'hello_vue' %>
<h1>Homes#index</h1>
```

### サーバー立ち上げ

二つ必要

```ruby
# Rails server の立ち上げ
$ bundle exec rails s

# Frontend server の立ち上げ
$ bin/webpack-dev-server
```

以下のようになっていれば、Vue の導入はひとまず OK！

<img width="512" alt="helloVue.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434376/4529c045-0787-03e5-c5c6-fef4d847fd99.png">
SequelizeのtoJSON()とget()とgetDataValues()の違い

<h2>get(), toJSON()</h2>
get()は, モデルにカラムとして定義されたプロパティーを取得。
toJSON()はget()を引数なしで呼び出すのと同じ。

##getDataValues()
モデルのカラム定義のgetterを無視した生のデータを返す。
Zabbix をインストールするとき、yum install zabbix-web-japanese も実行しましょう。

以上。(コマンドだけではわからんということでタイトルを変えました。)

・・・で終わっていいんだけど。いや、タイトルに肝心な情報書いちゃってあとは愚痴とか重要ではない情報とかなんで。

なお、ここで言及するのは基本的に Zabbix を RedHat系(Cent OS等) にパッケージで入れる場合の話です。他の Linux Distribution でも問題自体は同様にあるようだが触っていないので。

## 最近のバージョンの Zabbix の Install手順に従って構築した場合のグラフでの文字化け

古い Zabbix に関しては日本語のマニュアルがあるが、最近のバージョンの Zabbix には日本語のマニュアルは無い。[Zabbix Documentation](https://www.zabbix.com/documentation/4.2/manual)

RedHat系へパッケージを使ってインストールするための手順は、例えば Zabbix 4.2 の場合は [4.4 Installation from packages-1 Red Hat Enterprise Linux/CentOS]
(https://www.zabbix.com/documentation/4.2/manual/installation/install_from_packages/rhel_centos "4.4 Installation from packages-1 Red Hat Enterprise Linux/CentOS") にある。しかしながら、この手順で構築し、言語を日本語にした場合、次のような問題が発生する。
> グラフで文字が正しく表示されない。

この問題への対処法は後述。
## Zabbix 2.0 の日本語の Install手順に書かれていること

通常、もはや10年以上前のバージョンのマニュアルなんて見ることはない。
しかし、たまたま Zabbix 2.0 の日本語のマニュアルのインストール手順を見た。

[3.3 ディストリビューション・パッケージからのインストール](https://www.zabbix.com/documentation/2.0/jp/manual/installation/install_from_packages)

すると

> 日本語環境で利用するためにはzabbix-web-japaneseパッケージをあわせてインストールしてください。 

と記述されており、例にも

> `# yum install zabbix-server-mysql zabbix-web-mysql zabbix-web-japanese`

と書かれている。

これは Zabbix Document 2.0 の日本語版にのみ記述されており、同バージョンの他の言語には書かれておらず、また Zabbix Document 2.2 の日本語版、Zabbix Document 1.8 の日本語版にも書かれていない。

しかしながら、[Zabbix Download](https://www.zabbix.com/download) で OS DISTRIBUTION として RedHat系を選択した場合に表示される Zabbix Repository のフォルダ https://repo.zabbix.com/zabbix/4.2/rhel/7/x86_64/ 等を参照すると zabbix-web-japanese の rpmパッケージが存在する。[^1]

従って、Zabbix Frontend のインストール (`yum install zabbix-web-pgsql` あるいは `yum install zabbix-web-mysql`) の後に `yum install zabbix-web-japanese` をするのが正しい手順であり、後からでもこの手順を踏むとグラフでの文字化けは発生しなくなるのである。[^2]

以上。

[^1]: Zabbix Server と Zabbix frontend が deplicated となっている Zabbix 4.2 の RedHat 6 用のリポジトリには Zabbix Server. Zabbix frontend 同様に無い

[^2]: RedHat系の distribution 以外では ググれば出てくるが フォントをインストールすることでグラフでの文字化けは発生しなくなる。。
コントローラにリダイレクトを設定する方法


ログインしていないuserが、コントローラのnewアクションのルーティングパスを入力した時、リダイレクトを設定していなければ、コメントの投稿ができてしまう。そのようなことを防止するために、コントローラにリダイレクトを設定する。


#1.redirect_toメソッドを使う
redirect_toメソッドは、リダイレクトを設定できるメソッドである。引数は、キーとバリューを設定する。

```
redirect_to キー: :バリュー
```

今回は、indexアクションにリダイレクトを設定したいので、キーにはactionを、バリューにはindexをそれぞれ記述する。そして、リダイレクトがアクションする条件として、ユーザーがログインしていないという記述を加える。

```ruby


redirect_to action: :index unless user_signed_in?
```

また、上記の書式でActionController::UrlGenerationErrorが出た場合、
https://gyazo.com/bc3d223e71b0358e8423b0ab1a4c75e1
以下のような書式にすると解決できる。

```ruby

redirect_to controller: :コントローラ名, action: :アクション名
```


#2.メソッドをコントローラの中に定義する

今回は、move_to_indexという名前にメソッド名とした。このメソッドが呼ばれると、リダイレクトの処理が走るようになる。　

```ruby
def move_to_index
    redirect_to action: :index unless user_signed_in?
end
```

#3.before_actionを定義する。
before_actionメソッドは、それ以下に:メソッド名を記述し、さらにそれをコントローラの一番上に記述する。これにより、コントローラの中に定義されているそれぞれのアクションが実行される前に、そのメソッドを実行することができる。

```ruby

before_action :メソッド名
```

今回は、move_to_indexという名前のメソッド名をbefore_actionメソッド以下に記述する。しかし、このままではログインしていないユーザーであっても、indexアクションが実行せず、データの一覧表示が閲覧できなくなってしまう。そのため、indexアクションの場合を除いてあげることを最後に記述する。

```ruby
before_action :move_to_index, except: :index
```

exceptはオプションで、before_actionの実行を制限することができる。他にもonlyなどがある。

リダイレクトのオプション設定は、readの機能を実装する時に使用する。readの機能は、index(一覧)とshow(詳細)である。この両者は、サインイン（ログイン）していなくとも、すべてのユーザーが利用することができる。よって、ユーザーがサインイン（ログイン）しなければならないという条件を満たす必要はないため、exceptなどのオプションを使う必要がある。
WSL上でElixirを使うときにモニタリングツールが起動できなかった件

# はじめに
某会社さんでElixirを始めて触った時に、WSL上のElixirでライブラリをインストールするときにエラーが発生したのでその解決策をメモ

もう一つ、WSL上でElixirを動かすときにライブラリがインストールできなかったのでそちらもどうぞ→[WSL上でElixirを使うときにライブラリがインストールできなかった件](https://qiita.com/sasasoni/items/c94dba790d31025bd13f)

## 環境

```
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.1 LTS
Release:        18.04
Codename:       bionic
```
## 問題
WSLのUbuntu環境にて、モニタリングツールを実行時にエラーが起きた

```
$ iex
Erlang/OTP 22 [erts-10.4.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]

Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :observer.start
** (UndefinedFunctionError) function :observer.start/0 is undefined (module :observer is not available)
    :observer.start()
```

`$ sudo apt-get install -y erlang-observer`実行後、もう一度試したら次のようなエラーが起きた

```
iex(1)> :observer.start
00:28:52: Error: Unable to initialize GTK+, is DISPLAY set properly?
                                                                    {:error,
 {{:einval, 'Could not initiate graphics'},
  [
    {:wxe_server, :start, 1, [file: 'wxe_server.erl', line: 65]},
    {:wx, :new, 1, [file: 'wx.erl', line: 115]},
    {:observer_wx, :init, 1, [file: 'observer_wx.erl', line: 107]},
    {:wx_object, :init_it, 6, [file: 'wx_object.erl', line: 372]},
    {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]}
  ]}}
```

## 解決

Windows上でVcXsrv Windows X Serverをインストール
https://sourceforge.net/projects/vcxsrv/

VcXsrvを起動
https://www.atmarkit.co.jp/ait/articles/1812/06/news040.html

WSL上で以下のコマンドを実行

```
$ echo ‘export DISPLAY=:0.0’ >> .profile
$ source .profile
```

改めてiexからコマンドを実行

```
$ iex
Erlang/OTP 22 [erts-10.4.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]

Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> :observer.start
:ok
iex(2)>
```

うまく起動できました

![image](https://user-images.githubusercontent.com/43914847/60354789-0709a800-9a08-11e9-8c37-692acd12435c.png)

Macと比べると面倒ですね・・・はやくMacBookほしいです

## 参考サイト
https://www.walknsqualk.com/post/elixir-on-wsl/
https://www.atmarkit.co.jp/ait/articles/1812/06/news040.html
https://torisky.com/wsl%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC%EF%BC%9Aerror-cant-open-display%E3%81%AE%E5%AF%BE%E5%87%A6/
スクラム関連勉強会に参加してきた

スクラム関連の勉強会に参加しました。
内容のまとめと自身が感じたことをメモ。

#内容
開発手法には大きく分けて２つありますとね、それぞれこんな特徴があります。
ウォーターフォール：管理することに重きをおいた方法論
アジャイル　　　　：目的を達成することに重きを置いた方法論
よく聞く話ですよね。目的が大きく違うってことを理解してください。

これを理解して、適切な環境に適用しないとうまくいかない。
なんとなく良さそうだからアジャイル、なんとなく今までやってきたからウォーターフォール、というやり方じゃ失敗する確率は上がっちゃう。

したがって、その組織が解決したい目的を正確に把握し、組織の構造にあった手法をとるのがベスト。
その時々でどっちの手法があてはまるかはその場になってじゃないとわからないけど、手段先行で進めるのは最悪。
 目的から方法を検討する
 方法から目的を達成できるように工夫する

なんでウォーターフォールでやってたの？という問いかけもありました。
私も働き始めて最初に出会ったのはウォーターフォールでした。
そしてそれが普通になじんでました。
作業するときはまず、全量把握して、構造化して、タスクに落として。。。という具合。

でもあらためて問いかけられると、なんでだろうと思い回答に窮しました

登壇者の意見としては、会社というピラミッド構造の組織に対して、トップダウンで管理するウォーターフォールの手法は取り入れやすく、浸透していったらしいです。
でも上記のように目的が違うので、プロジェクトという目標を達成するためには向かないことが多いとのこと。

で、いろいろお話がありましたが、これが一番響きました
「コミュニケーションはビジネスでも大事、でもコミュニケーションで解決できることには限界がある。というかできないことが多い」
ということ。人間だし仕事をする気分もむらもある。そのムラやパフォーマンスを個人の感情や周囲との協力で進めるのは、リスク。

そういった心理的な問題も仕組みを工夫して解決して一定のパフォーマンスを出せるようにする必要がある。
さらに失敗を報告したり、遅れを報告するのは心理的にもハードルがありますよね。
そういった問題はスクラムだと解決できる
心理的な状況を、 コントロールするのではなくマネジメントすることに重きを置く 、とのこと。

スクラムは「組織論」「集団心理」を研究された結果生み出された手法。
スクラムを勉強したいと思ったときは、まずこの2つを学ぶのがおすすめ
そのうえでスクラムという手法を改めて学ぶと、理解はずっと深くなる。
プロジェクトを進めていくうえで問題は多々発生する。
その問題は表面的なものなのか、別の問題が根本にあってその一部が顕在化しただけなのか、そこを深堀することも大事
そのような機会が仕組みとしてあるのもスクラムの良い所、らしい。

#まとめ
・明確な問題を定めたうえで、手法を選ぶことが一番重要。なぜスクラムでやるの？なぜウォーターフォールなの？これを明確に。手法が先はダメ。
・仕組みとして成果を上げることに取り組もう。現代の難しいプロジェクトだからこそ、その人の気分や人間関係に左右されにくい仕組みをリードして作っていく必要がある。それがスクラムじゃなくてもいい。考えて選んでいこう。
・表面的な問題は多々ある。問題に対処する前にまず、その問題は本当に問題か？根本的な問題は別にないか？を一度立ち止まって考えることは最重要。
WSL上でElixirを使うときにライブラリがインストールできなかった件

# 初めに
某会社さんでElixirを始めて触った時に、WSL上のElixirでライブラリをインストールするときにエラーが発生したのでその解決策をメモ

もう一つ、WSL上でElixirを動かすときにモニタリングツールが利用できなかったのでそちらもどうぞ→[WSL上でElixirを使うときにモニタリングツールが起動できなかった件](https://qiita.com/sasasoni/items/5ddb16d550e398cd49b6)

## 環境

```
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.1 LTS
Release:        18.04
Codename:       bionic
```
## 問題
WSLのUbuntu環境にて、ライブラリを組み込む際に以下のようなエラーが出た

```
$ mix deps.get

23:33:01.754 [error] Unable to load crypto library. Failed with error:
":load_failed, Failed to load NIF library: '/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1: version `OPENSSL_1_1_1' not found (required by /usr/lib/erlang/lib/crypto-4.5.1/priv/lib/crypto.so)'"
OpenSSL might not be installed on this system.


23:33:01.884 [warn]  The on_load function for module crypto returned:
{:error, {:load_failed, 'Failed to load NIF library: \'/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1: version `OPENSSL_1_1_1\' not found (required by /usr/lib/erlang/lib/crypto-4.5.1/priv/lib/crypto.so)\''}}

** (Mix) httpc request failed with: {:failed_connect, [{:to_address, {'repo.hex.pm', 443}}, {:inet, [:inet], {:eoptions, {:undef, [{:crypto, :supports, [], []}, {:tls_record, :supported_protocol_versions, 1, [file: 'tls_record.erl', line: 658]}, {:tls_record, :supported_protocol_versions, 0, [file: 'tls_record.erl', line: 344]}, {:ssl, :handle_options, 3, [file: 'ssl.erl', line: 1504]}, {:ssl, :connect, 4, [file: 'ssl.erl', line: 522]}, {:http_transport, :connect, 4, [file: 'http_transport.erl', line: 109]}, {:httpc_handler, :connect, 4, [file: 'httpc_handler.erl', line: 786]}, {:httpc_handler, :connect_and_send_first_request, 3, [file: 'httpc_handler.erl', line: 812]}]}}}]}

Could not install Hex because Mix could not download metadata at https://repo.hex.pm/installs/hex-1.x.csv.
```

## 解決
以下のコマンドを実行

```
sudo apt-get install aptitude
sudo aptitude install erlang-crypto
```

`erlang-crypto`のインストール中画面が変わって色々聞かれるが、OK→Yes

改めて`mix deps.get`をする
Hexをインストールしていない場合、Hexをインストールするか？と聞かれるのでYでインストール

```
$ mix deps.get
Resolving Hex dependencies...
Dependency resolution completed:
New:
  poison 4.0.1
* Getting poison (Hex package)
```

これで解決しました！

### 参考サイト
https://elixirforum.com/t/problems-with-elixir-erlang-crypto-module-on-ubuntu-arm/13846/2
【Oracle DB】EXP-00091:不振な統計をエクスポートしています

# 事象：EXP-00091:不振な統計をエクスポートしています
下記コマンドが書かれたBATファイルを実行し、
テーブルのレコードをエクスポートしようとした。

```bat:export.bat
exp USER/PASS@SAMPLE file=D:\work\SAMPLE.dmp log=SAMPLE.log tables=TABLE_SAMPLE query=\" WHERE DAY BETWEEN '20190101' AND '20191231' AND TYPE IN('A','B','C') \" 
```

▼結果

```bat:コマンドプロンプト：LOG
指定された表をエクスポートします... 従来型パス経由...
.. 表　TABLE_SAMPLEをエクスポート中　100行エクスポートされました。
EXP-00091:不振な統計をエクスポートしています
EXP-00091:不振な統計をエクスポートしています
EXP-00091:不振な統計をエクスポートしています
エクスポートは正常に終了しましたが、警告が発生しました。

```
と警告が表示された。

▼実行環境
OS：Windows
DB：Oracle

# 結論：表の一部分を抜き出したため、統計情報の意味がなくなったから。
実行したBATファイルでは、
query=\" WHERE DAY BETWEEN '20190101' AND '20191231' AND TYPE IN('A','B','C')
とWHERE句を指定している。

エクスポートを行う際、テーブルの統計情報も一緒に抜き出される。
テーブルの一部のみを抜き出した場合、統計情報が有効でなくなる（場合がある）。
「EXP-00091:不振な統計をエクスポートしています」
はそんな感じの話を伝えてくれていたようだ。

# 解決策：オプション[statistics=none]をつける
statistics=none　をコマンドの最後に付ければ、統計情報の抜き出しを行わない。

```bat:export.bat
exp USER/PASS@SAMPLE file=D:\work\SAMPLE.dmp log=SAMPLE.log tables=TABLE_SAMPLE query=\" WHERE DAY BETWEEN '20190101' AND '20191231' AND TYPE IN('A','B','C') \" statistics=none
```

# 補足
- 「統計情報」って？？
効率的なデータ探索をどう実行できるか？（＝実行計画）を決めるためのデータ。
表/インデックス内のデータ分布なんかも保管しているそうな。

- エクスポート　サンプル

```bat:export.bat
exp USER/PASS@接続情報 file=ファイルパス query=\" WHERE句 \" <OPTION>
```

※サンプルを使う場合は注意して自己責任で使ってください。
　だいぶん疲れた状態でこの記事を書いているので。。。笑
Oculus QuestのWebXRを試す (Oculus Browser 5.9)


Oculus Goは3DoFだったので特にWebXR使いたいシーンはなかったのですが，Oculus QuestでWebXRのReferenceSpaceが欲しくなったので試したときのメモ．

[Oculus BrowserのRelease Notes](https://developer.oculus.com/documentation/oculus-browser/latest/concepts/browser-release-notes/)によると，5.4 の時点で `WebXR is now available under an experimental feature flag.` とあります．5.4のリリースから半年くらいたった気がするので，そろそろサポート進んでるだろうと思って現状の挙動を確認してみました．

ここでは触れませんが，事前にADBをTCP/IP接続できるようにして，Chromeのリモートデバッグ機能を使うと捗ります．


(2019-07-27追記) **Oculus Browser 6.0でChromium 74ベースになりました．なのでこの記事の内容はもう古いです．**


## Chromiumのバージョンを確認

おもむろにブラウザのURLに`chrome://version`と入力．

```
Oculus Browser: 66.0.3359.203 ...
```

ちょっと残念な結果になる予感がします．．．でも最近ブラウザのアップデートが何度かあったし，なんだかんだいっても活発に開発しているはず．

## navigator.xr

まだ`chrome://flags`からWebXR Device APIを有効にする必要がありました．

有効にしてもhttps接続じゃないと `undefined` が返ります．最近のChromeだとWebXRは[オリジントライアル](https://github.com/GoogleChrome/OriginTrials/blob/gh-pages/developer-guide.md)の対象になってたはずですが，Oculusのブラウザにはそういう気配なはさそう(？)

[WebXR Device API](https://www.w3.org/TR/webxr/)を見ながら試す．WebXR周りはまだ仕様が固まってない上に，どの時期の仕様を実装したのかよくわからないので何度か試す．

## XRSession

`xr.requestDevice()`とかは生えてないので極端に古い実装じゃななそう．(手元で使ってるTHREE.jsはちょっと古くてrequestDevice()を使うバージョンだったのでここでエラー出た)

```js
let session = await navigator.xr.requestSession("immersive-vr");
// → Uncaught (in promise) TypeError: Failed to execute 'requestSession' on 'XR': cannot convert to dictionary.
```

よくわからないけど，何かをdictionaryにして欲しいらしい．ちょっと古い仕様を実装してそう．


```js
let session = await navigator.xr.requestSession({mode:"immersive-vr"});
// → XRSession {environmentBlendMode: "opaque", mode: "immersive-vr", outputContext: null, renderState: XRRenderState, …}
```

Questの表示がVRモードに切り替わった．使えそう．ちなみにimmersive-arはサポートされてなかった(カメラ画像にオーバーレイされたりしたら良い意味でびっくりだったのだけど)．

## XRSpace

XRReferenceSpaceがほしいのが今回の動機なので，本番はここから．requestReferenceSpaceにも文字列じゃなくてオブジェクトを渡す．

```js
let space = await session.requestReferenceSpace({type:"identity"});
// → XRReferenceSpace {originOffset: XRRigidTransform, onreset: null}
```

中身は単位行列とゼロベクトルでした．

```js
let boundedSpace = await session.requestReferenceSpace({type:"bounded"});
// → Uncaught (in promise) DOMException: This device does not support the requested reference space type.
```

残念．Questのガーディアンの情報がboundsGeometryで取れれば夢が広がったのに．

# まとめ

- Oculus QuestのWebXRはまだっぽい
- WebVRは普通に使えてます
- 最近ブラウザのUI何度か変わった気がするけどChromiumのバージョンは変わってないっぽい
（メモ）オンプレOracleとRDS for Oracleの違い

[コーソルさんの記事](http://cosol.jp/techdb/2013/09/at_first_glance_amazon_rds_for_oracle_database.html)によくまとまってます。

- SYSユーザーでインスタンスに接続できない
- RDS作成後にDBに接続できるユーザはマスターユーザ（RDS作成時に指定した管理ユーザ）のみ。
- マスターユーザはDBA権限を持っているが、SYSDBA権限、SYSOPER権限はもっていない。
- SYSDBA権限（またはSYSOPER権限）が必要なバックアップやoradebugなどの診断機能も利用できない。
- 初期化パラメータファイルの変更はマネージメントコンソールでやるみたい。
- expdp/impdpは使えない。エクスポート/インポートはDBMS_DATAPUMPパッケージを使うみたい。
- 接続はリモート接続。ローカル接続はできないっぽい。

- 以下が気になる。
    - バックアップ・リストアはどうするのか
        - AWS側でやるからRMANは使用しない？ 
    - アーカイブログモード、非アーカイブログモードの切り替えはどうやるのか。
        - shutdown/startup文 や alter database文 は実行できない模様。
    - CREATE PFILE FROM SPFILE文は？
        - ホストOSにアクセスできないため、PFILEを作成したところで中身をみれない。 

オンプレOracleとRDS Oracleの操作の違いは[公式](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.Oracle.CommonDBATasks.html)にまとまってました。