OmniAICreator/Qiita-1.07M huggingface dataset:
Stripe Billing(Subscription)ユーザー向けのニッチな消費税増税対応の情報

# StripeのTax Rate変更対応について

https://support.stripe.com/questions/2019-10-1

に税率の設定方法などが掲載されています。
ここではWebhookを使った対応方法が載っていますが、年額の場合にはWebhookでinvoice.upcomingが発火するのは結構先になってしまうユーザーがでてきてしまう？とも思ったので、スクリプトを組んで変換をしようと考えています。

# Subscriptionのcurrent_period_endの状況を確認する

変換スクリプトの実行を開始するタイミングが悩みどころですが、9月中に新しいInvoiceが発行されない、つまりSubscriptionのcurrent_period_endが9月中で一番最後が例えば 2019年 9月 30日 18:00 であれば、それ以降はSubscriptionのTaxを変更しても既存のInvoiceには影響がありません。

また逆に10月1日以降に最初のInvoiceが発行されるタイミングが 2019年 10月2日 10:00 であればまあそこまでは猶予があるとも言えます。（プラン変更などが発生しなければ）そこで9月中最後のInvoiceが発行されるタイミングおよび10月中最初のInvoiceが発行されるタイミングを調べるスクリプトを用意してみました。

なおこれは現時点でのSubscriptionの状況を確認するためのスクリプトなので、今後9月30日の夜から10月1日の朝に新しいSubscriptionが生成される可能性があることも考慮しておく必要がありますね。

月額、年額だけの場合、すでに10月1日まで1ヶ月を切っているので、current_period_end が 10月1日 直前のデータを調べればよいことになります。

日額や週額などの場合、current_period_end が10月1日までに複数回来ることがありこの方法は使えませんのでご注意ください。
Mac上で動作確認をしています。
動作にはjqが必要です。
誤りなどあればご指摘くださいませ。

https://stripe.com/docs/api/subscriptions/list#list_subscriptions-current_period_end-lt

# 9月中最後のcurrent_period_endがあるタイミングを調べるスクリプト

9月30日12時以降にcurrent_period_endを迎えるsubscriptionを10件取得しています。
ケースに応じて適宜 SUBSCRIPTION_LIMITとEIGHT_PERCENT_DAY を変更してみてください。

```shell

YOUR_SECRET_KEY=***YOUR_SECRET_KEY***
SUBSCRIPTION_LIMIT=10
EIGHT_PERCENT_DAY=`date -j -f "%Y-%m-%d %H:%M:%S" "2019-09-30 12:00:00" "+%s"`
TEN_PERCENT_DAY=`date -j -f "%Y-%m-%d %H:%M:%S" "2019-10-01 00:00:00" "+%s"`
date -r ${TEN_PERCENT_DAY}
RES=$(curl -s --globoff https://api.stripe.com/v1/subscriptions?limit=${SUBSCRIPTION_LIMIT}\&current_period_end[lt]=${TEN_PERCENT_DAY}\&current_period_end[gte]=${EIGHT_PERCENT_DAY} \
  -u ${YOUR_SECRET_KEY}: \
  -G)
CURRENT_PERIOD_END=`echo ${RES} | jq '.data[] | .current_period_end' | sort`
for TIME in ${CURRENT_PERIOD_END}
do
  date -r ${TIME}
done
```

# 10月中最初のcurrent_period_endがあるタイミングを調べるスクリプト

10月1日12時までにcurrent_period_endを迎えるsubscriptionを10件取得しています。
ケースに応じて適宜 SUBSCRIPTION_LIMITとTEN_PERCENT_FIRST_DAY を変更してみてください。

```shell

YOUR_SECRET_KEY=***YOUR_SECRET_KEY***
SUBSCRIPTION_LIMIT=10
TEN_PERCENT_FIRST_DAY=`date -j -f "%Y-%m-%d %H:%M:%S" "2019-10-01 12:00:00" "+%s"`
TEN_PERCENT_DAY=`date -j -f "%Y-%m-%d %H:%M:%S" "2019-10-01 00:00:00" "+%s"`
date -r ${TEN_PERCENT_DAY}
RES=$(curl -s --globoff https://api.stripe.com/v1/subscriptions?limit=${SUBSCRIPTION_LIMIT}\&current_period_end[gte]=${TEN_PERCENT_DAY}\&current_period_end[lte]=${TEN_PERCENT_FIRST_DAY} \
  -u ${YOUR_SECRET_KEY}: \
  -G)
CURRENT_PERIOD_END=`echo ${RES} | jq '.data[] | .current_period_end' | sort`
for TIME in ${CURRENT_PERIOD_END}
do
  date -r ${TIME}
done
```

## 調査の結果
9月30日 23時台と10月 1日 01時台にcurrent_period_endを迎えるsubscriptionがあることが判明。。。
HTMLをPHP記述に変換

<h1>HTMLをPHP記述に変換</h1>
WordPressを使うので、嬉しい機能です。

[HTML TO CODE CONVERTER (BETA)
... CONVERT HTML TO YOUR FAVOURITE SCRIPTING LANGUAGE.]
(http://htmltocodeconverter.nexmedia.de/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442057/b1e73948-3a84-daa7-c208-6b630c0de4b7.png)

HTMLをコピペして、PHPボタンを押すだけです。

[まったり　こんふぃでんしゃる](http://deltablog01.com/archives/958)から引用しました。
PowershellでADオブジェクトの「誤って削除されないようにオブジェクトを保護する」チェックを一斉に外す

## サブネットが対象今回は

```
Get-ADReplicationSubnet  -Filter * | Set-ADObject -ProtectedFromAccidentalDeletion $false
```
## チェックが外れるところ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/c6fbb95e-2763-aa2a-e0ab-7822c821cb8b.png)
preg_match は型変換されてマッチングする

`preg_match` の第 2 引数には**検索対象の文字列**を渡します。

```php
preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] ) : int
```

別の型を渡したらどうなるか確認します。

ちなみに `preg_match` の返り値は下記です。

> 返り値
> 
> preg_match() は、pattern が指定した subject に**<ins>マッチした場合に 1 を返します。 マッチしなかった場合は 0、エラーが発生した場合は FALSE を返します。</ins>**
> 
> 引用：[PHP: preg_match - Manual](https://www.php.net/manual/ja/function.preg-match.php)

論理型が文字列型に変換された場合、下記のようになります。

> boolean の **<ins>TRUE は文字列の "1" に、 FALSE は "" (空文字列) に変換</ins>**されます。 これにより boolean と文字列の値を相互に変換することができます。
>
> 引用：[文字列への変換](https://www.php.net/manual/ja/language.types.string.php#language.types.string.casting)

```php
<?php

class A {}

$int = 111;
$float = 1.23;
$bool_true = true;
$bool_false = false;
$array = ['aaa'];
$obj = new A;

var_dump(preg_match('/111/', $int));
var_dump(preg_match('/1.23/', $float));
var_dump(preg_match('/1/', $bool_true));
var_dump(preg_match('/^$/', $bool_false));
var_dump(preg_match('/Array/', $array));
var_dump(preg_match('/A/', $obj));
```

```php:結果
int(1)
int(1)
int(1)
int(1)

Warning: preg_match() expects parameter 2 to be string, array given in /in/HVBhj on line 16
bool(false)

Warning: preg_match() expects parameter 2 to be string, object given in /in/HVBhj on line 17
bool(false)
```

実行結果：[3v4l](https://3v4l.org/HVBhj)

**結果を見ると整数型、浮動小数点数型、論理型は文字列に変換されてマッチングします。**

配列とオブジェクトは変換されず、エラー `false` が返ります。
Hands on Table で 便利だと思ったやつ 殴り書き

# Hands on Table
地味に組み込み関数が多いので、公式リファレンス様is神
[Hands on Table 公式](https://handsontable.com/examples?headers)
あと個人的にめっちゃまとまっててよかったのでこちらも勝手に紹介
[Handsontable 使い方メモ 1](https://qiita.com/opengl-8080/items/ac19deec388c357cd498)
[Handsontable 使い方メモ 2](https://qiita.com/opengl-8080/items/9d25e106ff48b66cb908)
[Handsontable 使い方メモ 3](https://qiita.com/opengl-8080/items/ccf5cbccd0ceb0a6bb47)
[Handsontable 使い方メモ 4](https://qiita.com/opengl-8080/items/e756af444147771fab18)
# セルの値を取得
`.getSelected`選択されたセルの配列を返す
　　(0,2,4,5)なら(0,2)から(4,5)までが選択されているので
　　一つだけなら(0,2,0,2)とかになるよね
`getValue`選択されているセルの値を取得
`getDataAtCell(row, col)`座標でセルを指定して、そこの値を取得
# セルのCSSを変える
`getCellMeta`セルのメタ情報を取得
`this.setCellMetaObject(col, row, {className: 'qwq'})`3つめの引数がメタデータのセット
　　ここでクラスが変わればCSSが変えられる
# セル内にhtmlを
たとえばセルに入れる値を
`<a href="javascript:void(0)" onclick="document.getElementById("ZAQ").click()">わっほい</a>`
というStringにして
html上に
`<input id="ZAQ" type="button" diplay:none onclick="method();">`
とかってしとけば、セル上でリンクを押したらhtml上のダミーボタンが押され
そこでJavaScriptのmethodが発火されるって感じになります
# 条件分岐
renderer関数を使ってロジックを組めます
[公式より抜粋](https://handsontable.com/docs/demo-custom-renderers.html)
# renderer関数
たぶん困ったらだいたいこれで解決できると思う
例

```
{
  title: aaa,
  data: aaa
},
{
  title: bbb,
  data: bbb,
  renderer : function (instance, td, row, column, prop, value, cellProperties) {
     Handsontable.renderers.TextRenderer.apply(this, arguments);
     // TextじゃなくてHtmlRendererにすればhtmlのリンクもできる
　　 selectedやgetDataAttCellなどを、instance.getDataAtCellなどで使う
     td.メソッドで背景色や文字色なども変えられる
     row,col,valueなどを組み合わせて、表に乗った値に応じてさまざまな変化を書ける
　　 td.innerHtml
     return td
  }
}
```
# で？
基本的に表示する目的で使っていますが、Excelのようにクライアント側からの操作に対してのイベントを発火できるのが魅力
今回はただ表の代わりに使っています
まぁ一切ビジュアル的な解説がなく、まじで殴り書いた感じですけどｗ
地味にこの辺便利とはいえど分かりにくいので、覚えていきたいですね
計算列とメジャーについて（PowerBI/PowerPivot）

PowerBI/Power Pivotにおける重要な要素に、計算列とメジャーがあります。これらはとても良く似た機能に見えますが、使われている概念はそれぞれ全く異なっています。この違いを理解することがPowerBI/Power Pivotを理解するための重要な一歩となります。

## 計算列について
計算列を追加することは、Excelで列を追加する場合とほぼ何も変わりません。計算列は、PowerBI/PowerPivot内で使われるテーブル内の他の列と全く同じで、他のテーブルの行、列でも使用（参照）できます。
Excelの場合と概念が若干異なっているのは、PowerBI/PowerPivotの計算列が「行コンテキスト」で動作する点です。計算列の評価および処理は、テーブル内の現在の処理行を参照して行われます。同じテーブル内の他の行の値に直接アクセスすることはできません。（現在の処理行を無視して、他の行を直接参照することはできません）

## メジャーについて
メジャーとは一言で言えば「集計処理」を行うものです。計算列は現在の処理行を参照して行われますが、メジャーはテーブルの合計を参照します。
全体の合計値を基にして計算を行う場合に便利です。例えば、各商品別に売上と利益をデータとして持つテーブルから、売上総利益率を出したい場合を考えてみます。この場合は、まず総売上高と総利益を集計し、割合を計算する必要があります。全体の合計値を参照する必要があるため、行レベルの参照ではうまくいきません（上記の例では、各行においては間違いではありませんが、「総計」において、割合を合計することになってしまいます）

![メジャーと計算列.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499774/0d2375bd-9ae2-800e-f3aa-8855856f5cbf.png)


## 計算列とメジャーの使い分け
計算列とメジャーをどう使い分けるかについては、「何を計算したいか」が判断基準になります。
計算列は行レベルの参照になりますので、例えばある列の文字列から数値を抽出したい場合や、列同士を加算、減算する場合（この場合は「総計」も正しい計算結果となります）などに使用できます。
メジャーは、合計値を参照します。各列の合計値には暗黙的にメジャーが使用されます。そのほか標準集計 (SUM、COUNT、MIN、MAX、DISTINCTCOUNT、または AVG) で暗黙的なメジャーが使用されます。
また、合計値の割合を算出する際にもメジャーが使われます。

両者は計算処理のタイミングも異なります。計算列はデータベース処理中に計算され、モデルに保存されます。つまり、メモリを占有するということです。非常に複雑な計算列を作成する場合には、中間的な計算列を作成することでクエリ時間の短縮につながりますが、一方でメモリ消費量が増えるという欠点も抱えることになります。一方、メジャーはクエリ時に処理されるため、メモリを消費しません。ただし、場合によってはクエリ処理時間が増えることになります。
これらは非常に大きなデータを扱う際にのみ関係することですが、処理方法の違いについては覚えておいたほうがよいでしょう。
phpの可変関数をメソッドの中で呼び出すと未定義と怒られてしまう場合

##環境
php7

## プログラム

これは、未定義とエラーが出てしまう。
関数はちゃんと定義してるし、メソッド内からの関数呼び出しなので$thisも
つけているのに。。。

```php:hoge.php
$doProcess = "getData";
$this->doProcess();


function getData(){
  echo "データなんてないんだよなぁ";
}
```

さすがにミスの仕方がひどすぎて草生えない。
次に、エラーが出なくなるプログラム。
クラスの関数を呼び出す際は「->」の後は「💲」はつけないが、
今回は可変関数ということで文字列から関数を呼び出す感じになるので、
「->」のあとに「💲」をつけることで、その文字列が認識されて、うまく呼び出せる

```php:hoge.php
$doProcess = "getData";
$this->$doProcess(); 

function getData(){
  echo "データなんてないんだよなぁ";
}
```
## 結果
ふぅ〜！呼び出せた！
Higher-order-components dev community

- problem
  - duplicate logic when you make function which is used orver your app. like tool tips.



ex）

```javascript

function add (x, y) {
  return x + y
}

function addFive (x, addReference) {
  return addReference(x, 5)
}

function addTen (x, addReference) {
  return addReference(x, 10)
}

function addTwenty (x, addReference) {
  return addReference(x, 20)
}

addFive(10, add) // 15
addTen(10, add) // 20
addTwenty(10, add) /
```

- 解決策（for DRY）

```javascript
function add (x, y) {
  return x + y
}

function makeAdder (x, addReference) {
  return function (y) {
    return addReference(x, y)
  }
}

const addFive = makeAdder(5, add)
const addTen = makeAdder(10, add)
const addTwenty = makeAdder(20, add)

addFive(10) // 15
addTen(10) // 20
addTwenty(10) // 30

※note

avaScript's ".bind" method is a common example of this.
```

- solution
  - higher order comonent


```javascript
function higherOrderFunction (callback) {
  return function () {
    return callback()
  }
}
```

```javascript:Reactの場合

function higherOrderComponent (Component) {
  return class extends React.Component {
    render() {
      return <Component />
    }
  }
}

```




- 記事


https://dev.to/tylermcginnis/react-higher-order-components-10c3
macOSをMojaveにアップグレードしたらgit-svnが使えなくなった。

OSのアップグレードに消極的なので、2019年9月時点でしぶしぶSierraからMojaveにアップグレードしたのですが、それによってSourcetreeでSVNと連携しているgit-svnのプッシュができなくなりました。

結論としてはOSに対応した Command Line Tools をインストールして解決しました。 自分が行った手段をまとめます。(当然のことなのかもしれませんが、自分は)

まず以下がSourcetreeエラーの内容です。

```
git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree svn rebase 
Can't locate SVN/Core.pm in @INC (you may need to install the SVN::Core module) (@INC contains: /usr/local/Cellar/git/2.21.0/share/perl5 /Applications/Xcode.app/Contents/Developer/Library/Perl/5.18/darwin-thread-multi-2level /Library/Developer/CommandLineTools/Library/Perl/5.18/darwin-thread-multi-2level /Applications/Sourcetree.app/Contents/Resources/git_local/lib/perl5/site_perl /Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18 /Network/Library/Perl/5.18/darwin-thread-multi-2level /Network/Library/Perl/5.18 /Library/Perl/Updates/5.18.4 /System/Library/Perl/5.18/darwin-thread-multi-2level /System/Library/Perl/5.18 /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level /System/Library/Perl/Extras/5.18 .) at /usr/local/Cellar/git/2.21.0/share/perl5/Git/SVN/Utils.pm line 6.
BEGIN failed--compilation aborted at /usr/local/Cellar/git/2.21.0/share/perl5/Git/SVN/Utils.pm line 6.
Compilation failed in require at /usr/local/Cellar/git/2.21.0/share/perl5/Git/SVN.pm line 25.
BEGIN failed--compilation aborted at /usr/local/Cellar/git/2.21.0/share/perl5/Git/SVN.pm line 32.
Compilation failed in require at /usr/local/Cellar/git/2.21.0/libexec/git-core/git-svn line 22.
BEGIN failed--compilation aborted at /usr/local/Cellar/git/2.21.0/libexec/git-core/git-svn line 22.
Completed with errors, see above
```

エラーの内容を詳しくは理解できませんでしたが、gitとかsvnが見つからないみたいなことを言われてるのかなと思い、gitとsvnのバージョンを確認するとsvnが見つからない的なエラーがでる（エラーの内容は保存していません）のでその辺りをヒントにググると、OSをアップグレードしたから Command Line Tools をインストールしなければいけないのではないかと気づきました。

インストールされているかの確認

```
$ gcc
```
されてないのでインストール

```
$ xcode-select --install
```

終わったらバージョンを確認

```
$gcc --version
```

一応再起動してもう一度sourcetreeのプッシュを試みると今度はうまくいきました。
sitemap.xmlをつくってみた

##sitemap.xmlとは
sitemap.xmlをサーバ上に置くことで、クローラーを呼び、検索エンジンがインデックスしやすいようにしてあげる。

##つくってみる
タグの種類

```
<?xml version=’1.0′ encoding=’UTF-8′?>
<urlset>　【必須】 全体を囲むタグで、現在のプロトコル標準を参照。 
<url>　   【必須】 各URLエントリの親タグ。その他のタグを囲むだけのタグ。 
<loc>　   【必須】 ページのURLを記述。末尾にスラッシュを含める必要があり、 値は 2,048 文字以下で指定する必要がある。 </loc>
<lastmod>　   【オプション】 ファイルの最終更新日。 </lastmod>
<changefreq>　【オプション】 ページの更新頻度。 </changefreq>
<priority>　  【オプション】 URL の優先度。0.0 から 1.0 までの値が指定できる。デフォルトは0.5。
　　　　　　　　          サイト内のすべての URL に高い優先度を設定しない。 
</priority>
</url>
</urlset>
``` 
####ページ更新頻度（changefreq）一覧
- always　アクセスするたびに内容が更新される
- hourly　1 時間に 1 回以下
- daily　1 日に 1 回以上
- weekly　1 週に 1 回以上
- monthly　1 月に 1 回以上
- yearly　1 年に 1 回以上
- never　定期的にクロールされる（更新しなくてもいいページ）

##ファイルを置く場所
sitemap.xmlはルートディレクトリに置く。

##複数のサイトマップファイルを使用する場合
50,000URL以上になると複数のサイトマップが必要になる。その場合は、サイトマップインデックスファイルを作成し、サイトマップが複数あることをクローラーに知らせる。

```
<?xml version=’1.0′ encoding=’UTF-8′?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <sitemap>
      <loc> 【必須】 １つ目のサイトマップファイル名</loc>
      <lastmod> 【オプション】 ファイルの最終更新日</lastmod>
   </sitemap>
   <sitemap>
      <loc> 【必須】 2つ目のサイトマップファイル名</loc>
      <lastmod> 【オプション】 ファイルの最終更新日</lastmod>
   </sitemap>
</sitemapindex>

```

##指定URLを除外
###robots.txt　

クローラーにアクセス制限するためのファイル。アクセス制限する理由として２つ

- クローラーは内部リンクや被リンクを辿ってやってくること。サイト内で多くのリンクを獲得しているページには、クローラーも多く訪れてしまう。
- ドメインごとにクローラーが訪問するページ数には限りがあること。限られた中で、重要なページに多くクロールしてもらいたい。

```
User-agent: クローラー名
Disallow: /アクセス拒否したいディレクトリ名/
```

####注意点
- ユーザーはrobots.txtを閲覧できる
- 重複コンテンツにはrobots.txtを使用せず、URL正規化対応






##動作確認する
[Google Search Console](https://search.google.com/search-console/about?hl=ja&utm_source=wmx&utm_medium=wmx-welcome)は、Google 検索結果でのサイトのパフォーマンスを監視、管理できる Google の無料サービス。Google にどのように認識されるかを確認し、検索結果でのサイトのパフォーマンスを最適化できるようになる。
英単語 for enginner Dev communityを読み続けて


# 単語

- So let me get this straight
  - スッキリさせるよ

- briefly
  - 簡単に
  - briefly explor the tools.

- boilerplate
  - 定型

-  dedicated
  -  dedicated page
  -  専用ページ

- capabilities
  - 能力

- inducing
  - 誘導する
- identical
  - 同一

- tackle
  - 取り組む
  - I couldn’t find anything that tackled this

- serve
  - This product vision will serve more use

- co-presenter
  - 共同開発者

- participants
  - 参加者

- Comparisons 
  - 比較
  - Performance Comparisons　パフォーマンスの比較

- Rehydration
  - 水分補給　break的な意味合いだろう
  - React rehydrates and takes over the application. 情報をserverから取ってくるの意味かも

- Methodology
  - 方法論

- Consistent
   - 一貫した
- crawlers
  - クローラー

- use case
  - ユースケース

- props  cons
  - 良し悪し

- Important Prerequisite
  - 事前準備

- diagram
  - 図

- equation
  - 方程式

- precisely
  - 正確に

- mandetory
  - 義務

- note 
  - 注意
- outcome
  - 結果、成果物？

- disservice
  - 失業？（dis：否定 service: 奉仕、勤務）

- cultish
  - カルト　（文では、呪文的な意味合いだったような）
  - the (almost cultish) mantra of Don't Repeat Yourself   こんな感じのように使われた。呪文のように Don't ...

- too far
  - やりすぎ
 
- duplicate
  - 重複

- reference
  - 参照

- in mind
  - 念頭に置いといて

- encapsulate
  - カプセル化（en + capsulate）

- naming collision
  - 名前衝突

- unsure
  - I am actually really unsure on what that actual error is
  - このエラーまじでわからない

- is used to verb
  - is used to get some DNS
  - DNSに慣れてるんだよね

- preamble
  - 前文

- afterthought
  - 結果論

- presume
  - 推論

#　表現
- There's two important things to note before
  - ooの前に、2つの注意すべき大事な事

- It's not really even a React thing
  - Reactに限った事じゃない

- To do this the React way,
  - do（v）　this（o）  the React way （c） かな?

- explore the solution
  - 解決策を深掘りしてみよう
- duplicating our hover logic anytime
  - 重複したロジックを使っている

- what if the component 
  - もしooだったら？
【PHP】単語を組み合わせたランダムなパスワードの生成

## はじめに
ここでは、PHPを使ったランダムな文字列のパスワードを生成し、ファイルに生成したパスワード保存するプログラムを作っていきます。
すでにパスワード生成に関しては色んな方が記事を出してます。しかしエンジニア歴が浅く、かつPHP触った事ない私にとっては少々わかりづらかったので、そんな方にもわかりやすく向けた解説付きの記事となります。

少しでも参考になれば嬉しいです:relaxed:

## 目的
パスワード変更の際、毎回毎回どんなパスワードにしようか考えていては疲れてしまいます。定期的なパスワード変更を実施している場合などは特にそうです。なのでPHPで人間が頭を使う部分を自動化させようというのが目的です。
パスワードの定期的な変更は賛否ございますが、パスワードを知っている職員が退職し、情報漏洩防止の為にパスワードの変更を余儀なくされるケースはあるかと思います。そんなシーンを想定しています。

なぜ、規則性のない英数字ではなく単語なのか。という点に関しては、
・その方がパスワードを覚えやすい。
・入力もしやすい。
・人に伝えやすい。
という理由です。

単語じゃなくていいという方は、こちらの記事→[ランダムなパスワードを1行で生成する](https://qiita.com/suin/items/c958bcca90262467f2c0)が参考になります。

## 完成品

```random_password.php
<?php
function password()
/* パスワード生成 */
{
  $word = array('fire', 'dragon', 'magic');
  $keys = array_rand($word, 3);
  shuffle($keys);
  $pws = "";
  foreach ($keys as $key) {
    $pws = $pws.$word[$key];
  }
  return $pws;
}
file_put_contents("sample.csv", password());
?>
```
こちらです。
サンプルコードの為、配列の中に単語を3つしか用意していませんがもっと入れておくといいと思います。

### 解説
まずはphpファイルを作って、それの中にphpタグ<?php ?>を作りましょう。
このタグの中に書いていけば、phpを書いたことになります。

```random_password.php
<?php
function password()
/* パスワード生成 */
```
パスワード生成をする関数を作成します。`function password() {}`とすることで、password()で関数を実行できます。


```random_password.php
<?php
function password()
/* パスワード生成 */
{
  $word = array('fire', 'dragon', 'magic');
```
phpでは`$`で変数を定義します。なのでここでは`$word`に配列が与えられ、その配列の中にはパスワードに使用する単語が入っています。

```random_password.php
<?php
function password()
/* パスワード生成 */
{
  $word = array('fire', 'dragon', 'magic');
  $keys = array_rand($word, 3);
  shuffle($keys);
```
`$keys = array_rand($word, 3);`では、配列`$word`の中から3つの単語をランダムに抜き出して、変数`$keys`と定義しています。

`shuffle($keys);`では、`$keys`が持っている3つの単語の順番をランダムに入れ替えている、文字通りシャッフルをしています。

```random_password.php
<?php
function password()
/* パスワード生成 */
{
  $word = array('fire', 'dragon', 'magic');
  $keys = array_rand($word, 3);
  shuffle($keys);
  $pws = "";
  foreach ($keys as $key) {
    $pws = $pws.$word[$key];
  }
  return $pws;
}
```
最終的に`return`で生成した文字列を返したいので、`$pws = "";`を定義しています。現在`$pws`の中身は空ですが、ここに生成したパスワードを入れていきます。

`foreach`は**配列専用のfor**です。使い方はforと同じです。
`array_rand($word, 3);`で抜き出した単語の数だけforeachが回るので、それを`$pws`の中に足していきます。

`$pws = $pws.$word[$key];`とすることで、

```
fire
firedragon
firedragonmagic
```
のようになります。

`return $pws;`で先ほどの`firedragonmagic`を返り値としています。

```random_password.php
<?php
function password()
/* パスワード生成 */
{
  $word = array('fire', 'dragon', 'magic');
  $keys = array_rand($word, 3);
  shuffle($keys);
  $pws = "";
  foreach ($keys as $key) {
    $pws = $pws.$word[$key];
  }
  return $pws;
}
file_put_contents("sample.csv", password());
?>
```
`file_put_contents("sample.csv", password());`とすることで、sample.csvファイルを新規作成、そのファイルの中に`password()`で返ってくる値が書き込まれます。すでにsample.csvが存在する場合は、上書きとなります。

## さいごに
ここまで読んでくださってありがとうございました。
誤字脱字・発信した情報に間違い等ございましたら、指摘して頂けますと幸いです:bow:
また、説明にわかりづらい点がございましたら、改善致しますのでぜひコメントください:pray:
IE11でボタンの ::after や ::before がうまく表示されない理由

下図のようにアクティブ時に吹き出し風にタブボタンの下にちょっとした三角をつけましたが、IE11でうまく表示されません。
三角は `position: absolute;` で配置をコントロールしています。

<img width="416" alt="tab-button.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419907/83b874d7-6fdc-8661-8df3-9c638af80aea.png">

```html
<ul class="tablist" role="tablist">
  <li class="tab"><button class="tab-button" role="tab">タブボタン</button></li>
  <li class="tab"><button class="tab-button" role="tab">タブボタン</button></li>
</ul>
<div></div>
```

```css
.tablist {
  display: flex;
  justify-content: space-between;
}

.tab-button {
  background-color: #002bab;
  border: none;
  color: #fff;
  font-size: 18px;
  outline: none;
  padding: 16px;
  position: relative;
  width: 100%;
}

.tab-button::after {
  border-top: 15px solid #002bab;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  bottom: -15px;
  content: "";
  left: 50%;
  margin-left: -8px;
  position: absolute;
}
```

▼IE11で三角が表示されない例
<img width="413" alt="スクリーンショット 2019-09-19 10.20.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419907/597d8f01-a6b5-2293-816c-2f34e44913a2.png">

直下に `div` をくっつけているので重ね順の問題かと思い `z-index` で設定しましたが、ダメでした。

## `button` はIE11のデフォルトで `overflow: hidden;` だった

IE11で `button` の `overflow` が `hidden` になっていたため、 `position` で `button` の範囲外に置いた三角が隠されて見えていなかったのでした。
`overflow: visible;` を追記して解決できました。
コンポーネントCSS設計 小技や思想まとめ

##目的
今回社内のプロジェクトにて、CSS設計がキモになるようなプロジェクトを担当することになりました。
ざっくり概要をまとめると、
**”ユーザーがサイトのブロック単位の要素を好きに並べ変えてLPを簡単に作れるようにする”**
というもの。（なんだか楽しそうですね）

お気付きの通りバリバリのコンポーネント思考でのCSS設計が求められてます！
でも私はまだCSS設計についてはウブ中のウブ...
色々調べ倒して学んで行くしかありませんね。
そこで得た「これ使えるんじゃない？」といった考え方や小技をまとめて行きたいと思います。

綺麗で完結で再利用しやすい美しいCSSを目指して！

【随時更新予定です。】

##環境・設計思想

- CSSはstylusを用いる。
- CSS設計はFLOU+BEMを用いる。


##FLOU+BEM
`BEM+FLOCSS`については以前記事でまとめたhttps://qiita.com/irico/items/2f1b6ce4e1649e5e78f1
⇧こちらを参考にしてください。
思想に関してはFLOCSS、命名規則に関してはBEMを使用するといった感じですね。

今回はFROCSSではなく`FROU`を使用してみます。

###FROUとは？
https://webnaut.jp/technology/20170407-2421/
こちらを参考にしました。
**FROCSS**が

 - Foundation
 - Layout
 - Object

 そしてObjectがさらに細分化して

 - Component
 - Project
 - Utility
 - 
となっているのに対して、

**FLOU**は

- Foundation
- Layout
- Object
- Utility

に分けてしまおう、となっています。
Projectの実質的廃止です。
今回のようなコンポーネント大量生産のプロジェクトの場合、実質固有のスタイルというものは存在しないのでうってつけであると考えました。
(ただその場合、大きいコンポーネントにくっついている小コンポーネントの多くの情報を持たせることになりそうです。
componentが肥大化したらprojectをつけるかもしれません）
そして今後のコンポーネントが増えていくことも見通し、Objectの粒度は割と細かく設定する予定です。

##stylusの小技
記述や設計に役立ちそうな小技達です。

###①stylusのFlie globbing
知らなかったー。
stylusは`@import`時にワイルドカードが使えるんですね。
【参考サイト】https://2inc.org/blog/2016/12/08/5483/

```stylus:flie_globbing
@import component/*
```

これでcomponent以下のファイルを全て読み込みます。
むっちゃ便利だし完結！使い倒して行きます。

###②block mixin
【参考サイト】https://qiita.com/tkn_e/items/a60c4c9ebaff29887bc2
まだまだ使いこなせてない`block mixin`。
これを機に使ってみたいです。

こちらの参考サイト様ではbreak pointの切り替え時に使用していますね。

```stylus:block_mixin
SP_MAX = 768px
sp(){
   @media screen and (max-width: SP_MAX){
      {block}
   }
}

/* 使用時 */
.box {
   display none
   +sp() {
      display  block
   }
}
```

block mixinは　定義時の`{block}`部分に 
`+sp(){ }`の中括弧内に記述した部分を吐き出してくれます。
自由に付け足せるってわけですね！
これを応用してsp時の振る舞いを簡単に付けせますね。使います。

###③ビルドイン関数
【参考】https://gist.github.com/ejointjp/8e0992cbf83565095adbf695d8bf65fc
Stylusには色々と便利な関数があるんですね。
今回コンポーネントにて明度のみが異なるコンポーネントなどが出そうなので役立ちそうです。

```stylus
lightness(hsl(50deg, 100%, 80%))
// => 80%

lightness(#00c, 80%)
// => #99f
```
例えば`lightness`は明るさを出したり、明るさを設定すると色のコードを出してくれたりします。
画像のファイル名から実験条件を取得する

心理学の実験では、ある画像を呈示してそれに対してキーボードやマウスで実験参加者に反応をさせるということをよくやります。このとき、呈示した画像は特定のカテゴリー（例えば、快・不快や、高魅力・低魅力など）に分けられることが多く、その情報をプログラム内で利用したいということがあります。そのため、ファイル名に画像のカテゴリー（実験条件）の情報を加えておくと便利です。

この例では、人物の画像を刺激として用いて、高魅力・中魅力・低魅力の３つに分けられるとします。さらに、メガネをかけている人物とかけていない人物がいて、メガネをかけている人物が呈示されたら左矢印キーを、メガネをかけていなかったら右矢印キーを押すという課題をすることにしましょう。

このとき、刺激で用いる人物の画像のファイル名を次の命名規則でつけておくと便利です。

**魅力度-カテゴリー内の通し番号-メガネの有無**

図で説明すると次のようになります。

![attractive.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495823/852b88e6-1ff4-e000-4d56-56b1494533e4.jpeg)

数字の割り当ては次のようにしています。

|実験条件|数字|
|:---|:---|
|高魅力|1|
|中魅力|2|
|低魅力|3|
|メガネあり|1|
|メガネなし|0|

# 実験条件の取得

では、実際にファイル名から実験条件を取得してみましょう。
Codeコンポーネントを配置して、Begin Experimentに以下のコードを書いてください。

```python:BeginExperiment
import re
import os

full_fileName = '/Users/xxx/Documents/PsychoPy3/practice/images/3-2-0.jpg'
fileName = os.path.basename(full_fileName)
print(fileName)
conditions = re.findall(r'\d+', fileName)
print(conditions)
print(conditions[0]) # 魅力度
print(conditions[1]) # 通し番号
print(conditions[2]) # メガネの有無
```

`full_fileName`にはパスの情報（パソコン内でファイルがどこに存在するかを示す情報）が含まれているので、`fileName = os.path.basename(full_fileName)`としてファイル名のみを取得しています。
そして、ファイル名から数字だけを取得しているのが、`conditions = re.findall(r'\d+', fileName)`です。findallについて、正確に理解しようとすると正規表現の知識が必要になります。興味のある人は、[【Python入門】正規表現の使い方を初心者向けに解説](https://www.sejuku.net/blog/23232)をご覧ください。とりあえずここでは、上のようにすれば、ハイフンで区切られた数字（実験条件）の情報を取得できるのだという理解でも十分だと思います。

上のコードでは、呈示している画像は、**3-2-0.jpg**で、それは**低魅力のメガネなしの画像**ということになります。

メガネをかけている人物が呈示されたら左矢印キーを、メガネをかけていなかったら右矢印キーを押すという課題であれば、次のようにコードを書くことができます。

```python
if pressedKey  == 'left':
    if conditions[2] == 0: # メガネなし
        correct = 0 # 不正解
    else: # メガネあり
        correct = 1 # 正解
else: # The right key was pressed
    if conditions[2] == 0: # メガネなし
        correct = 1 # 正解
    else: # メガネあり
        correct = 0 # 不正解
```
Oracle Database と ojdbc のバージョンについて

仕事の中に、OracleDatabaseとojdbcのバージョン関係の質問は何回聞かれました。OracleのFAQに明確に記載されています。

引用元 [Oracle JDBC FAQ](https://www.oracle.com/technetwork/jp/database/application-development/jdbc/overview/default-090281-ja.html#01_01)

* Oracle JDBCのリリースとJDKのバージョン

    |Oracle Databaseのバージョン |リリース固有のJDBC jarファイル |
    |---|---|
    |18.3|ojdbc8.jar（JDK 8、JDK 9、JDK 10およびJDK 11）|
    |12.2または12c R2|ojdbc8.jar（JDK 8）|
    |12.1または12c R1|ojdbc7.jar（JDK 7およびJDK 8） ojdbc6.jar（JDK 6)|
    |11.2または11g R2|ojdbc6.jar（JDK 6、JDK 7、およびJDK 8）**（注：JDK 7とJDK 8は、11.2.0.3と11.2.0.4のみでサポートされます）** ojdbc5.jar（JDK 5）|

* Oracle DBバージョンのクライアント/サーバー相互運用性マトリックスまたは認定マトリックス

    | 相互運用性マトリックス | Database 18.3 | Database 12.2および12.1 | Database 11.2.0.x |
    |---|---|---|---|
    | JDBC 18.3 | 対応 | 対応 | 対応 |
    | JDBC 12.2および12.1 | 対応 | 対応 | 対応 |
    | JDBC 11.2.0.x | 対応 | 対応 | 対応 |

* Oracle JDBCのリリースとJDBCの仕様の関連

    | Oracle Databaseのバージョン | JDBC仕様の準拠 |
    |---|---|
    | 18.3 | ojdbc8.jarのJDBC 4.2 |
    | 12.2または12c R2 | ojdbc8.jarのJDBC 4.2 |
    | 12.1または12c R1 | ojdbc7.jarのJDBC 4.1、ojdbc6.jarのJDBC 4.0 |
    | 11.2または11g R2 | ojdbc6.jarのJDBC 4.0、ojdbc5.jarのJDBC 3.0 |

* JDBC jarファイルはどこから入手できますか。

   必要なJDBC jarファイルは、Oracle Technology Networkの[SQLJ & JDBCダウンロード・ページ](https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html)からダウンロードしてください。
クローム使い方ページまとめ

クロームデバックで使うポイント

共有とメモ書き。

使いやすいクローム
https://www.buildinsider.net/web/chromedevtools/01#page-2
https://coliss.com/articles/build-websites/operation/work/how-to-use-chrome-devtools-by-ibrahim.html

<h4>・ブレークポイントを設定する</h4>
https://ics.media/entry/190517/

<h4>・レスポンシブデザイン対応</h4>

・3G回線でエミュレートする
[Network] タブにして、[No throttling]をクリックすると様々なネットワーク環境でテスト出来ます。
カッコの中の数字は左からそれぞれ Latency（待ち時間） Download Upload を表しています。
[Disable Cache] にチェックを入れるとキャッシュを使わない状態でのテスト

・デバイスモード
デバイスモードで表示→サイズを支持したら更新するとデバイス表示化する。
選べる端末を増やす＝複雑になるのでおススメしない。

・難読化されたCSSやJSを整形する
https://haniwaman.com/check-library/

https://www.doe.co.jp/hp-tips/browser/chrome-devtools-techniques/
https://ascii.jp/elem/000/000/999/999122/


<h4>デバック処理</h4>
https://www.buildinsider.net/web/chromedevtools/01#page-2



現在の要素を手に入れる
https://coliss.com/articles/build-websites/operation/work/how-to-use-chrome-devtools-by-ibrahim.html#h211
「Elements」パネル
ElementsパネルエディタでDOM要素を選択。
コンソールをクリックし、それにアクセスするために「$0」を書いてください。

［Network］パネル
Kotlin Reference 宣言箇所変性

この記事は、以下を基本的に引用した内容となっております。
一部翻訳がわかりづらい部分があったため、自分なりにわかりやすく修正した内容となっております。

[ジェネリクス - Kotlin Programming Language](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/generics.html#%E5%AE%A3%E8%A8%80%E7%AE%87%E6%89%80%E5%88%86%E6%95%A3)

# 記事を読む前に

この記事の内容を理解するためには、ジェネリクスについて知っておく必要があります。
以下サイトが初心者にもわかりやすくまとめられていました。
[JavaジェネリックスのPECS原則、extendsとsuperの勘所 -- ぺけみさお](https://www.xmisao.com/2014/02/12/java-pecs-producer-extends-consumer-super.html)
[Javaジェネリクス：共変、反変、非変（これ以上簡単にはならない） | GWT Center](https://www.gwtcenter.com/covariance-and-contravariance)

この辺について把握していないと、以下の話についていけないかと思います。。

# 宣言箇所変位

ジェネリックインターフェイスの```Source<T>```があると仮定します。また、パラメータとして```T```を返すメソッドのみを持つとします。

```java

// Java
interface Source<T> {
  T nextT();
}
```

それは```Source<Object>```型の変数（呼び出せるコンシューマメソッドがない）内で```Source<String>```のインスタンスへの参照を保持するのに完全に安全です。 – しかし、Javaはこれを知っているし、まだそれを禁止していません：

```java

// Java
void demo(Source<String> strs) {
  Source<Object> objects = strs; // !!! Java では許可されていない
  // ...
}
```

これを修正するために、```Source<? extends Object>```型のオブジェクトを宣言する必要があります。全ての同メソッドを前のような変数で呼ぶことができるので、順序に意味はなく、より複雑な型で追加することに価値はありません。しかし、コンパイラはそれを知りません。

Kotlinでは、コンパイラにこの種の問題を説明する方法があります。これは、 宣言箇所変性と呼ばれています：ソースの 型パラメータ```T```を```Source<T>```のメンバからのみ 返し （プロデュースする）、消費されることがないということを確認するために、アノテーションを付けることができます。これを行うために、我々は```out```修飾子を提供します。

```kotlin

abstract class Source<out T> {
  abstract fun nextT(): T
}

fun demo(strs: Source<String>) {
  val objects: Source<Any> = strs // これは OK 、なぜなら T はoutパラメータのため
  // ...
}
```
STM32マイコン体験セミナー（モータ制御編）P-NUCLEO-IHM002 2019年9月18日実施

STM32マイコン体験セミナー（モータ制御編）はP-NUCLEO-IHM002を使用して行われました。（2019年9月18日）

![IMG_0426.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/3668d601-7ac4-648c-15ae-ab5e644f2539.jpeg)
![IMG_0424.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/2c58b08e-f916-9f02-e059-7c7e49c10e64.jpeg)

P-NUCLEO-IHM002は
・NUCLEO-F302R8
・X-NUCLEO-IHM07M1
・BR2804-1700 kV
・ACアダプター
のセットになります。
https://www.st.com/ja/evaluation-tools/p-nucleo-ihm002.html

準備にあたり、
##・X-CUBE-MCSDK
https://www.st.com/en/embedded-software/x-cube-mcsdk.html
##・STM32CubeMX
https://www.stmcu.jp/design/sw_dev/pc_soft/52798/
##・STM32CubeF3
https://www.stmcu.jp/design/sw_dev/firmware/52724/
##・STM32CubeProgrammer
https://www.stmcu.jp/design/sw_dev/pc_soft/58442/

コンパイラに
#IAR Embedded Workbench® for Arm® (v8.40.1)
https://www.iar.com/jp/iar-embedded-workbench/#!?architecture=Arm
を指定されていました。
IAR Workbenchはコード制限版ではなく、30日の試用版を選択します
が・・・早速洗礼を受ける僕
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3238353334342f35393738343038332d373663612d316564652d643931322d3935663932326333373833382e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/a1797648-b380-ded5-e21a-c8c2f20d3919.png)

なぜか、ライセンスがあるのに、動かないIAR Workbench・・・
仕方なく、30日版からコード制限の永久ライセンスへ変更しました・・・

<img width="400" P-NUCLEO-IHM002 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/adb1804f-0222-1241-e421-93e550ef66a9.jpeg>

<img width="600" MotorControl Workbench src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/c79ebaf6-59b3-3241-dda8-632876044f86.png>

ちなみに、ソフトウェアのバグなのか、GenerateするときにJSONのエラーが起きることがあります。
素直に、再インストールしましょう（原因は、あるファイルが悪さをしているものでした\.stmcufinder\plugins\mcufinder\mcu）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/0b2635d6-37d9-1f65-b4f7-96bfbfd1511f.png)

なかなかマイコンボードから直接モーターを動かすセミナーが無いので、非常に良かったです。
次は、これを活用する手法を教えてほしいですが、個別案件になりますかね？

STマイクロのセミナーは今年から上級編がスタートしていますが、今度は、座学コースも欲しいですね・・・ｗ

特記事項として
#X-CUBE-MCSDKについて
##X-CUBE-MCSDK
・一部ソースコードが非公開
ベクトル演算は変わらないが特定のアルゴリズム (MTPA, CORDIC, flux weakening , rev up..) のソースコードが非公開
##X-CUBE-MCSDK-FUL
•フル・ソースコード
St.com から登録とSTの認証でダウンロード可能
https://www.st.com/ja/embedded-software/x-cube-mcsdk-ful.html
WKWebViewを使ってローカルの自己署名証明書を使ってhttps接続をしようとして苦労した話

(2019/10/06 SecTrustEvaluateでXcodeに文句を言われたので修正)

WKWebViewでローカルのサーバにhttps接続しようとしてもどうしても繋がらずまっしろい画面になってしまう

```swift
override func viewDidLoad() {
    super.viewDidLoad()

    let webConfiguration: WKWebViewConfiguration = WKWebViewConfiguration()
    self.webView = WKWebView(frame: CGRect.zero, configuration: webConfiguration)
    self.webView.uiDelegate = self
    self.webView.navigationDelegate = self
    self.view.addSubview(webView)

    let url: URL = URL(string: "https://localhost:8080")!
    let request: URLRequest = URLRequest(url: url)
    self.webView.load(request)
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let width: CGFloat = self.view.bounds.size.width
    let height: CGFloat = self.view.bounds.size.height
    let frame: CGRect = CGRect(x:0, y:0, width: width, height: height)
    self.webView.frame = frame
}
```

信頼できない証明書を使っている場合はプロトコル`WKNavigationDelegate`の関数?`didReceive`で失敗した認証に対して適切に処理を行う必要があるそう。

```swift
	func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
		// 認証の種類を確認してSSL/TLS認証以外はデフォルト処理
		if challenge.protectionSpace.authenticationMethod != NSURLAuthenticationMethodServerTrust { return completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil) }
		// 証明書が取得できなかった場合はデフォルト処理
		guard let trust: SecTrust = challenge.protectionSpace.serverTrust else { return completionHandler(URLSession.AuthChallengeDisposition.performDefaultHandling, nil) }
		// とりあえず信頼してみる
		return completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: trust))
	}
```

どうしてもうまくいかず悩んでいたが、WKWebViewでロードするアドレスを https://localhost:8080 から https://127.0.0.1:8080 にしたら繋がるようになった
理由はよくわからない
テストはおもしろい

# はじめに
DeNA 様主催の「DeNA QA Night #3 」というイベントに行ってきました。
https://dena-qa-night.connpass.com/event/131229/

プログラムで以下のことを話されていました。

- テスト観点に関する取り組み事例
- パネルディスカッション
    - QAエキスパートが喋り倒す夜

パネルディスカッションのなかで「テストってなにがおもしろいですか？」
という質問があがったのだが、自分にもとっても考えさせられる内容だった。

人それぞれのたのしさがあるので、何が正しいのかを問うものではなく自分としてテスト業務の楽しさ、すばらしさを伝えれるようになりたいと思った

# テストとは

様々な定義があるのはちょっとはわかったうえで、テストとは、基本は健康診断や診療（バグ発見）や体力測定（性能評価）と思っている。

病巣となっている部分を確実に発見することが使命であり、このテスト工程で適当な診断をして見逃すとあとあと大変なことになる。

単なる風邪と診断されて適当に処方箋もらったが、その2日後息苦しくて精密検査すると後肺炎だったという実績ありｗｗ


#テストは楽しい？

健康診断や体力測定自体が楽しいかというと、残念ながら、それ自体はそれほど楽しいわけではない。

病気(バグ)を見つけても懸賞金などないし、見つけると健康診断と同様に再検査しなければならないし、後工程などでリリース間近になると煽られるし。。。

しかも、子供のころは、かーちゃんが飯を作ってくれるのが当たり前的な感じで、特別に目立って感謝される仕事ではないという事実。

そんなことで、与えられたテストケースをこなすだけのテスト実施のみだけだと、あまり楽しいものではないと思う。



# それでもテストはおもしろい

ネガティブなことばっかり書いたが、それでもテストはおもしろい
上記に書いたテストケースをこなすだけではないことが前提ではあるが。。。

まずは、バグを見つけるため、いろいろなテスト技法と経験などでテストを考えれること。
そのテストで狙ったようにバグが出ると、テストのやり甲斐があったと感じる。
湯本さんが「カッコいいバグを見つけたい」と言っていたかな？それに当たるかもしれない

テストに関する技術や手法、考え方も、さまざまなものが出てくるので、それを取り入れて自分なりの工夫で実践できるのもおもしろい。

そして、誰よりも早く最新の製品やらツールに触れることができるので、新しいもの好きにはたまんない。さまざまなOSやらファームウェア、ツールの知識も得られるし、そしてプログラム(職業プログラマーまで行かないけど)もできるので、幅広く技術情報を得ることもできる。

最後に、直接的な開発(製造)はしていないけど、やっぱり物作り、モノ(機能)を育成している感が一番おもしろいし、そしてたのしいと思う。
macでawsのwindowsを使う


macの上でwindowsを操作する時の画面。アプリ経由でawsのwindowsを操作してる。
この形式増えてもいい気もする。クライアントPCにOS入れるなんて古いって世界観。
<img width="1278" alt="スクリーンショット 2019-09-19 9.28.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64334/75899d48-0629-5975-60d6-0eb942f3a0f6.png">


クラウドの時代の前はこんなのが一般的だった。

- マルチブートニしてwindowsとmacを入れる

一昔前はマルチブート当たり前だったけど、最近はバーチャルボックスとかの方が一般的。

- バーチャルボックスで１つのOSの上で複数のOSを動かす

VMWareとかViturelBoxとか使うとOSの上にOSが乗る。
今はもっと最適化されたdocker。そのクラスタ化するk8sとか流行ってる。


# リモートデスクトップツール入れる

賛否両論あるようだけど、今回はこれ入れる。

Microsoft Remote Desktop 10
https://apps.apple.com/jp/app/microsoft-remote-desktop-10/id1295203466?mt=12


# awsでwindows

今回はwindows server 2019 baseを立てる。

<img width="1241" alt="スクリーンショット 2019-09-19 9.11.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64334/3c502d9f-83c4-4247-0acb-90622c4a14ef.png">

セキュリティグループはいつものポートとは少し違うので新しく作る。
もちろんキーはちゃんと保存しておくこと。

<img width="1224" alt="スクリーンショット 2019-09-19 9.12.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64334/30cca704-6870-2000-bb79-5c1885115289.png">

キー情報からパスワードを作成する必要がある。


<img width="519" alt="スクリーンショット 2019-09-19 9.26.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64334/c940489a-0352-d0aa-9a9e-2e41252df4cd.png">


Add Desktopでpc名にdns名を入れる。

<img width="503" alt="スクリーンショット 2019-09-19 9.42.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64334/645d8247-642a-1ebb-6e51-98ef1c6715c1.png">

この時の情報をメモしとく。
どうせ消すので全部晒す。


```
パブリック DNS   ec2-52-23-181-138.compute-1.amazonaws.com
ユーザー名   Administrator
パスワード   
Rkj?R-Uc;Ih4-5Ehi6kUcWuwV?Kjpe=-

```



<img width="748" alt="スクリーンショット 2019-09-19 9.26.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64334/c4a37afb-c6eb-c512-3dd5-34e22f64f39d.png">



<img width="731" alt="スクリーンショット 2019-09-19 9.26.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64334/d3f3e3b0-6b36-c9ff-681c-df498612a9e8.png">

ユーザIDとパスワードを入れる。

<img width="560" alt="スクリーンショット 2019-09-19 9.27.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64334/d69ccccb-9f3b-b18c-304b-f9ec24f90c1d.png">

進む

<img width="595" alt="スクリーンショット 2019-09-19 9.28.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64334/d9668d5f-5702-42ef-5008-9d9eb76273d9.png">

これでログインできる。

<img width="1278" alt="スクリーンショット 2019-09-19 9.28.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64334/6f2ef6b3-4e10-bb33-b66b-9a6dac8d9b4d.png">


最後は使わないならちゃんと消すこと。
ダウンロードしたアプリケーションのインストールがうまくいかない時（Mac）

ダウンロードしたアプリケーションをインストールしようとした時に、インストーラーをダブルクリックしてもインストールが開始しなかった。
解決方法は、Mac で別のユーザーアカウントを作ってそのアカウントからインストールする。
普段のアカウントの設定やファイルに原因があったようです。特定することはできませんでした。
CentOSの対応CPU一覧 のリンク

## 公式

* [intel](https://access.redhat.com/support/policy/intel)
* [AMD](https://access.redhat.com/support/policy/amd)


## 感想

CentOS 6.10 は、

* Intel `Cascade Lake-SP`の`Xeon 42xx`、`Xeon 62xx`
* `Kabylake（第7世代Coreシリーズ）`
* AMD `Epyc`

に非対応の様子。

* `Skylake（第6世代Coreシリーズ）`には対応している。

## CentOS6にkernel4.4を入れてみる (elrepo)

elrepo を使って kernel 4.4 を入れてみた。

```sh:CentOS6.10
wget "https://www.elrepo.org/elrepo-release-6-9.el6.elrepo.noarch.rpm"
yum install -y "elrepo-release-6-9.el6.elrepo.noarch.rpm"

# kernel-lt-headers と競合するため削除
yum remove kernel-headers

# 2019/9/19時点では kernel 4.4 だった。
yum --enablerepo=elrepo-kernel info kernel-lt

# インストール
yum --enablerepo=elrepo-kernel install kernel-lt kernel-lt-headers kernel-lt-devel
## yum remove kernel-headersで消えた分入れる
yum install -y \
  gcc gcc-c++ gcc-gfortran glibc-devel glibc-headers libtool systemtap systemtap-devel

vi /etc/grub.conf
```

```diff:/etc/grub.conf
- default=1
+ default=0
```

![スクリーンショット_2019-09-19_11-18-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/7a094161-5a15-cdda-a7ca-0e4ebe685f80.png)

```sh:kernelのconfig確認
rpm -qal kernel-lt-devel | head
cd /usr/src/kernels/4.4.193-1.el6.elrepo.x86_64
yum install ncurses-devel

sudo make menuconfig
```

`/lake`で検索するも、skylakeまでしか対応していないような気がする。
以下をチェック付けて再コンパイルするか、もしくはkernel持ってくるか。。
そこまでするならCentOS7に上げるのも一つ考えるのが良いと思う。

![スクリーンショット_2019-09-19_11-29-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/c5615647-ab29-bc6a-1336-0ea662e84c5f.png)



## その他参考

* [CentOS 6.x系がサポートしているCPU - Qiita](https://qiita.com/nkojima/items/945f07c33ba541f90f45#kabylake%E3%81%AE%E5%A0%B4%E5%90%88)
* [Hardware upgrade, now can't install Centos6 - CentOS](https://www.centos.org/forums/viewtopic.php?t=65360)
* [Kaby Lake new Intel CPUs and Centos 6.8 graphics support - CentOS](https://www.centos.org/forums/viewtopic.php?t=61300)
String型をTimestamp型に変換する

#String型からTimestamp型に変換する

```java
			//String型からTimestamp型へ変換をする		
			//formから値を受け取り結合する
			String delivery = form.getDeliveryDate() + " " + form.getDeliveryTime();
			//format変換する為の記述
		    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh");
		    java.util.Date parsedDate = null;
			try {
				parsedDate = dateFormat.parse(delivery);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		    Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());
```

備忘録として残します。
他に何か良いやり方があればご教授お願いします！
frontend[react]、backend[rails]間でJSONのcasing（camelCase、snake_case）が異なる場合olive_branchが便利

# 問題

## frontend -> backend

```json
{
  "userId": "abcd1234"
}
```
camelCaseで送りたいし、受け取りたい


## backend -> frontend

```ruby
{
  user_id: "abcd1234"
}.to_json
```
snake_caseで受け取りたいし、送りたい

# そこでolive_branch
https://github.com/vigetlabs/olive_branch

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/93988af7-e180-7282-300c-171231e8b887.png)


## 使用法

```ruby:config/application.rb
...
...
# 全てはcamelCaseで来るのならここで指定[inflection]
# そうでなければClient側のリクエスト時にヘッダーで指定[Key-Inflection]
config.middleware.use OliveBranch::Middleware, inflection: "camel"

```

```ruby:controller.rb

def create
  params[:user_id] # => ClientはuserIdで送ってるが、これで受け取れる

  render json: { user_id: "abcd1234" }.to_json # で送れば、Clientでは json.userId で取れる
end
```

```tsx:Client.tsx
fetch("url", {
  method: "post",
  headers: {
    // OliveBranch側はContent-Type JSONを期待しているので、これがないと処理されない
    "Content-Type": "application/json; charset=utf-8",
    // 毎度指定が面倒なら config/application.rb で
    // config.middleware.use OliveBranch::Middleware, 
    //   content_type_check: -> (content_type) { true }
    // などとする
    // https://github.com/vigetlabs/olive_branch/issues/23
  },
  body: JSON.stringify({ userId }),
})
  .then((response) => response.json())
  .then(({userId}) => console.log(userId))
```
LispWorks Editorでifのインデントをそろえる

久しぶりにLispWorks 5.1を起動してPAIPを勉強しています。

PAIP（Paradigms of Artificial Intelligence Programming）はこちらで公開されているので、クラシカルなAIを知りたい方は皆さん読みましょう。

https://github.com/norvig/paip-lisp

LispWorks付属のエディタでは、ifのインデントがこのようにずれてしまいます。

![lw_befor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/b9ec31bb-1bfb-afd8-cb0f-3bb6447c6546.png)

ちょっとやりにくいので対応を調べました。これを.lispworksに加えればOK

```lisp
(editor:setup-indent "if" 2 4 4)
```

![lw_after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/aedb4ca8-96a2-56f3-e569-7516e00890b9.png)

期待通りのインデントになりました。
GCP アップデート (9/13-9/19 2019)

### IAM: [Aug 20, 2019 (feedの日付不正?)](https://cloud.google.com/iam/docs/release-notes#August_20_2019)
- 短期間のみ利用できるShort-lived service account credentialsがGAになったよ。
  - サービスアカウントキーは明示的に削除するまで恒久的に残るが、これは数時間とかの単位で残る。

### Compute: [Sep 13, 2019](https://cloud.google.com/compute/docs/release-notes#september132019)
- 仮想ディスプレイを利用できる機能がGAになったよ。
  - GPU等まではいらないライトユース用。

### Compute: [Sep 16, 2019](https://cloud.google.com/compute/docs/release-notes#september162019)
- intelのcascade lakeベースのC2マシンタイプがus-east1リージョンで使えるようになったよ。


### Dataprep: [Sep 16, 2019](https://cloud.google.com/dataprep/docs/release-notes#september_16_2019)
- dataprepのAPIが公開されたよ。
  - これまではdataprepで作成したdataflowのAPIを操作する必要があった。継続して使えるけどTrifactaの推奨はdataprepのAPI利用。
  - dataflow templatesは2019年12月に終わる予定。

### Ai Platform: [Sep 16, 2019](https://cloud.google.com/ml-engine/docs/release-notes#september_16_2019)
- デプロイしたモデルや、2つのモデルを比較できるWhat-Ifツールが公開されたよ。

### GKE: [Sep 16, 2019](https://cloud.google.com/kubernetes-engine/docs/release-notes#september_16_2019)
- GKEクラスタがバージョンアップされたよ。
  - 1.11は1.12に。1.14来たので1.11はdeprecate。
- 9/9のリリースノートは間違いがあって、セキュリティパッチの情報に関しては[ここ](https://cloud.google.com/kubernetes-engine/docs/security-bulletins#sep-16-2019)を確認して下さい。

### ディスクレーマ
- アップデートの内容はあくまでも個人の理解していることを書いています。正しい内容はリリースノート等を確認下さい。
- リリース内容できるだけ拾うようにしているのですが、抜けていそうなリリースノートが追加するのでぜひ教えて下さい！(一覧[ここ](https://qiita.com/kenzkenz/items/ac18a359b803dbb6b490)で更新してます。)
To Doが増えすぎて困る時。仮説（179）

issueが溜まりすぎて困るのと同様に、To Doが増えすぎて困ることがあります。

仮説(96) open な issue がどんどん溜まる現象を解決するために
https://qiita.com/kaizen_nagoya/items/efe22d9a23ad2e9934d6

やらなきゃいけないことはいっぱいある。
誰かが、何かをしてくれれば、自分のTo Doにしておく必要はない。
issueにあげると、溜まりすぎて困る。

# 案1
issueとTo Doを並べて、優先順位をつける。

issue の優先順位上位３つより優先順位の高いTo Doがあれば、issueにあげる。

直近の１ヶ月に実施しなくてもよい, issueは、翌月始め（あるいは終わり）に自動的にreopenする設定にしてcloseする。

To Doの優先順位付きの一覧をissueにあげて、協力を要請する。

課題：あの人のTo Doにつきあうと底なしで終わらないという評判が消えない。

# 案2
issueとTo Doを並べて、優先順位をつける。

優先順位が上位５以内で、１日で終わりそうなissueとTo Doを午前中に着手する。

昼までにどれくらい進捗したかで昼休み終了時点で判断する。

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
ElixirでCircleCI(GitHub連携も)

# 記事概要
ElixirConf JP 2019 Kokurajo後の話題にもなったみたいですが、CIツールを使うのは品質保証の上でも大事なことです。何より、一々マージ前のpull requestに同じ簡単な確認をしなくていいのが素晴らしいです。CIを正しく導入すると、プロジェクトのソースコードに統一性が出て(フォーマットチェック設定）、常にテストが完全に通る状態（テスト設定）が保たれます。ぜひ例え個人の趣味プロジェクトでも無料で導入できるので、CIツールは是非入れて下さい。

この記事ではElixirのプロジェクトでのCircleCI連携を簡単に説明します。

# CircleCI(GitHub連携)の導入
CircleCIの説明は[こちら](https://tweeeety.hateblo.jp/entry/2018/02/09/195345)に譲ります。というか、ぶっちゃけここ見ればわかる気がしますが、とりあえずElixirに特化した最低限の手順での実現への記事ということで。

CircleCIの導入は簡単です。もしアカウントがなければGitHubのアカウントと連携して作って下さい。無料でも制限付きで動かせます。個人での開発等なら無料でも問題ないと思います。

## CircleCIとGithubの連携
最初に連携しちゃいます。後述の`config.yml`を先に書いても大丈夫ですが、先に連携しておくと`config.yml`をmasterにpushもしくはPull Requestした際に実行を確認できます。

### プロジェクトを追加する
CircleCIに登録したら、[ダッシュボード](https://circleci.com/dashboard)に行って下さい。
ダッシュボードに行ったら左のメニューからプロジェクトの追加を選択して下さい。

![addproj.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82295/33582f96-cc94-4404-fbc2-2aaeba677649.png)

### 対象プロジェクトの選択
ADD PROJECTSを押したらプロジェクトの一覧が出るので、対象のプロジェクトの`Set Up Project`を選択します。 
<img width="1115" alt="スクリーンショット 2019-09-18 12.30.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82295/c49a6cbb-b91b-58b2-d8ae-50299c81f0f6.png">

次は`config.yml`の作成ですが、Set Upが終わると雛形が表示されるのでそれを使っても構いません。

## config.ymlの作成
プロジェクト直下に`.circleci`ディレクトリを作って、下記のような`config.yml`ファイルを作成して下さい。雛形は連携の設定時のものの他に[CircleCIのページのPhoenix用のconfig.yml](https://circleci.com/docs/ja/2.0/language-elixir/)もあります。

```yml
version: 2
jobs:
  build:
    docker:
      - image: circleci/elixir:1.9.1
        environment:
          MIX_ENV: test
    steps:
      - checkout
      - run:
          name: Check format
          command: mix format --check-formatted
      - run:
          name: Install Hex
          command: mix local.hex --force
      - run:
          name: Run deps.get
          command: mix deps.get
      - run:
          name: Run mix compile
          command: mix compile
      - run:
          name: Run test
          command: mix test
```

## CircleCIの実行
後はmasterにpushしたり、Pull Requestを出すと自動で`config.yml`に設定したコマンド群が走ります。

場合によっては

```yml
      - run:
          name: Install Rebar
          command: mix local.rebar --force
```
も追加する必要があると思います。コマンドは必要に応じて足して下さい。
また、Elixirのバージョン指定を変える場合、dockerのimageのバージョン指定を変更して下さい。

今回は下記の順に処理を実行しています

- mix format --check-formatted(フォーマッターあたってるか)
- mix local.hex --force(Hexインストール)
- mix deps.get(依存性解決)
- mix compile(コンパイルが通るか)
- mix test(テストが通るか)

### ローカルでの実行
ローカルにcircleciをインストールしたら、プロジェクトルートで

```bash
$ circleci build
```
これで:okです。

# まとめ
- CircleCI簡単使おう(他のCIツールでも良いので何かしら導入しよう)
- CIツールの導入は品質を担保する
- CIについてもっと学びたい人は[継続的デリバリー](https://www.amazon.co.jp/dp/4048930583)を読もう
- [CircleCIのバッジをGitHubのREADMEにつけたり](https://qiita.com/Hanocha/items/8ad74258eb43d0959590)もできます
WebricのFancyIndexingにスタイルシートをあてる

頑張ってあてます。ApacheでいうIndexStyleSheetです。

> IndexStyleSheet ディレクティブ
> http://httpd.apache.org/docs/2.2/ja/mod/mod_autoindex.html#indexstylesheet

Webricの起動時にDocumentRootオプションを渡してやると、ファイルのリストアップが自動的に表示されます。FancyIndexingと言うそうです。

```ruby
require "webrick"

server = WEBrick::HTTPServer.new({
  DocumentRoot: '.'
})

server.start
```

しかしながらWebricには、IndexStyleSheetのようなオプションはありません。
ソースコードをみてみると、set_dir_listと言うメソッドの中でHTMLを生成して返却しているようです。

https://github.com/ruby/webrick/blob/4b5c58a60b399178012c9d5354c3ba2ddec0ee32/lib/webrick/httpservlet/filehandler.rb

無理やり上書きします。

```ruby
require "webrick"

server = WEBrick::HTTPServer.new

server.mount_proc('/') do |req, res|
  handler = WEBrick::HTTPServlet::FileHandler.new(server, Dir.pwd, {
    :FancyIndexing => true,
    :IndexStyleSheet => "/style.css",
  })
  
  original = handler.method(:set_dir_list)
  handler.define_singleton_method(:set_dir_list) do |req, res|
    original.call(req, res)
    if @options[:IndexStyleSheet]
      res.body.gsub!("</style>", "</style><link rel=\"stylesheet\" href=\"#{@options[:IndexStyleSheet]}\">")
    end
  end

  handler.service(req, res)
end

server.start
```
Elixirのパフォーマンス測定にBenchfellaを使ってみた

# 記事概要
ElixirConf JP 2019 Kokurajoでパフォーマンス計測を行っていた際にBenchfellaを使ってみたのですが、取り扱っている記事がなかったので、1つのトピックとして取り上げることにしました。元々は[LTで学んだTips](https://qiita.com/muramasa8191/items/50386a77c4a497493c77)の1つとして書く予定でした。

この記事では簡単にBenchfellaの使い方を説明します。
### 2019/10/01 訂正
[プロジェクトのUsage](https://github.com/alco/benchfella#usage)にあるように、`prj_root/bench/` のファイル名は `xxx_bench.exs` と_benchである必要があります。

## Benchfellaとは
[Benchfella](https://github.com/alco/benchfella)はExUnitのような使い勝手で簡単にパフォーマンス測定ができるパッケージです。複数回実行して平均を取るようなことも自動でやってくれるのでパフォーマンス測定が楽になります。

## Benchfellaでパフォーマンス測定した流れ
Elixirでデータ構造を作ってみて、スプレーヒープの普通の再起と末尾再帰のパフォーマンス計測していた時に@zacky1972 先生に助言頂いてBenchfellaを使ってみました。
<img width="597" alt="スクリーンショット 2020-03-23 15.04.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82295/432b566a-995a-6173-7981-351d60158130.png">

# Benchfellaの使い方
というわけで早速使い方！
## mix.exsのdepsに追加

```elixir
  defp deps do
    [
      {:benchfella, "~> 0.3.0", only: :dev}
    ]
  end
```
envは適切に。

## パフォーマンス測定用のコードを書く
必要なこと

- プロジェクト直下にbenchディレクトリを掘ってxxx_bench.exsに書く
- use Benchfella
- ExUnitのtestの部分をbenchと書く感じで、処理を中に。

```elixir
defmodule SplayHeapBench do
  use Benchfella

  @nums 1..1_000_000 |> Enum.to_list |> Enum.shuffle

  bench "normal" do
    DataStructureEx.SplayHeap.from_list_org(@nums)
  end

  bench "tail call" do
    DataStructureEx.SplayHeap.from_list(@nums)
  end
end
```

## mix benchの実行
```
$ mix bench
```
と実行すればbench配下のexsファイルを実行してくれます。
<img width="456" alt="スクリーンショット 2019-09-18 11.56.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82295/d48784f0-6aef-6b16-857a-02212e0f4b25.png">
あれ、末尾再帰の方が速い…
durationの期間内に回せるだけ処理を回して平均の時間を取っているようです。iterationを増やしたい場合、`mix bench -d 10`というような感じで秒数を指定しましょう。これは10秒ずつ実行する設定です。この時間が切れたときに始まったiterationまでで実行が終わるようなので、長い処理は大抵iterationが1になります。

# まとめ
- Benchfella簡単使ってみて
OculusとSteamVRの両方を同時に開発する方法

# はじめに
　Unityで利用できるOculus Integrationはクロスプラットフォームで開発することができます。
そのためOculus Integrationのみで開発を行えばPCでも実行でき、OculusGoを始めとするOculusのモバイルやPC版でも実行できるようになります。
まだ未完成ですが、今後編集していくので間違ってるところとかあったら教えてください！
# コントローラーの割り当て
　基本的にコントローラーの情報を取得するときは`OVRInput`を使って取得してきます。

```c#

OVRInput.Get(); //Get()は押している
OVRInput.GetDown(Button.PrimaryThumbstick); //GetDown()は押した瞬間
OVRInput.GetUp(); //GetUp()は離した瞬間
```

### HTC Viveコントローラーの場合
-**トラックパッド（タッチパッド）**が`Axis2D.PrimaryThumbstick`になっています。
-**トラックパッド(タッチパッド) **の押し込みは`Button.PrimaryThumbstick`に割り当てられています。