OmniAICreator/Qiita-1.07M huggingface dataset:
Pre-Signed URLでS3に直接ファイルをアップロードする


# S3にファイルをアップロード
S3にファイルをアップロードするときLambdaやEC2経由にすることが多いかと思いますが、大容量のファイルだとS3に直接アップするほうが効率が良さそうです。
そういった場合はPre-Signed URLを取得して直接S3にファイルをPUTしてやると良さそうです。

# Pre-Signed URLの取得
以下のコードでPre-Signed URLが取得できます。

```js:Lambda
const s3 = new AWS.S3()
const params = {
  Bucket: '<バケット名>',
  Key: '<ファイルパス>',
  Expires: 100 // 期限（秒）
}

async function getPresignedUrl(){
  return new Promise((resolve,reject)=>{
    s3.getSignedUrl('putObject', params, (err, url) => {
      if (err) {
        reject(err)
      } else {
        resolve(url)
      }
    })
  })
}

exports.handler = async (event) => {
  const url = await getPresignedUrl()
  return {
    url: url
  }
}
```

# アップロード
以下のcurlコマンドでファイルをアップロードしてみます。

```
$ curl -X PUT --upload-file <ファイルパス> "<取得したPre-Signed URL>"
```

S3のバケットにファイルが有れば成功です。
Pre-Signed URLの期限が切れていたり、間違っている場合は以下のようなエラーのxmlが返ってきます。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>AccessDenied</Code>
  <Message>Request has expired</Message>
  <Expires>2020-04-09T09:02:03Z</Expires>
  <ServerTime>2020-04-09T16:06:00Z</ServerTime>
  <RequestId>xxxxx</RequestId>
  <HostId>xxxxx</HostId>
</Error>
```

Pre-Singed URLを使えば簡単にファイルアップロードもできますね！
次世代NEM「symbol wallet」を利用したDappsアプリ開発　〜前篇〜

#次世代NEM「Symbol wallet」の魅力とは？

2020年４月以降に、NEMが大型アップデートを予定している。

その名も**「NEM2.0（Symbol from NEM）」**

コードネーム「Catapult (カタパルト)」 に替わる次世代の仮想通貨として注目が集まっています。

私がNEMに注目した理由は、何と言っても”**開発のしやすさ**”に尽きる。

例えばイーサリアムだとブロックチェーン（つまり箱ごとの割り当てた暗号）を一旦構築し、動き出してしまうと再設定しづらい。
一方、NEMはすでに用意されている暗号が使え、再設定が可能です。再設定が可能であれば、関わる人間の出入りがしやすくなり、開発や事業面から柔軟に対応しやすいのがメリットです。

**これは、プラットフォームとして普及させるには大変なアドバンテージとなります！**

他にもーーーー
**取引き頻度などでより経済を回している人が報酬を得やすい**
**送金速度も手数料も断然安い**　※聞くところによると手数料のかからない「DAG」が登場したらしい。

ここでは、NEMを使ってアプリ開発を試みますので、「DAG」についての最新情報は近日お伝えします。


現在、コアデブやNEM財団、提携企業、有志の個人たちによって、世界中でNEM2.0であるSymbol ブロックチェーンのテストネットが稼働中。

テストネットによるストレステストやバグを炙り出すため、世界中の方が[SymbolテストNODE](https://symbolnodes.org/nodes/)を建てています。

ブロックチェーンに対して、私はピカピカの一年生なので、サーバーやノードといった専門的な知識はありません。

そんな私でも簡単にノード構築してテストネットで遊べるようになりました。
最終目標のDappsアプリにたどり着く前に、まずは「symbol wallet」に触れてみるというのが今回の趣旨です。

以下のGIFは、[テストネット用の仮想通貨を無償で購入できるサイト](http://faucet-01.symboldev.network/?recipient=TCIIV6Q4ADZ5K7B36RRXZSHTMLLQXLOP7JI6ARPL&message=goodyear&amount=5000)から、個人の財布に入れる工程をご紹介しています。


![セグメント 1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461900/fc6e2b51-6255-df90-bebc-c367dda1fe32.gif)

#Symbol Walletをダウンロード
財布がなければNEMを購入できません。まずは[財布](
https://github.com/nemfoundation/symbol-desktop-wallet/releases/tag/v0.9.6-beta1)を持ちましょう。
![スクリーンショット 2020-04-09 21.52.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461900/4b27b2b6-f285-55fa-6d7b-428013b10ca3.png)

#ノード構築
ダウンロードができたら、[ノード](https://www.allnodes.com/)を建てましょう！
注）ノードを立てる際は、**２０ドル**ほど費用がかかります。
　　決済方法は、主にクレジット（デビットOK)です。

設定の手順は[こちらの記事](https://nemlog.nem.social/blog/39787)をご参考下さい。

#作成ノードからIPアドレスを確認
次に、ノードができたらIPアドレスを見つけましょう。

[Symbol node list](https://symbolnodes.org/nodes/)から今作成したノードの名前を見つけます。
![スクリーンショット 2020-04-09 23.55.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461900/4e76a787-7ecf-4f56-156f-43a4dda27e72.png)


NAME：yot nem(Hosted on Allnodes)
IPアドレス：139.162.99.202(今回はテストネット用ですが、本ネットでは厳重に管理しましょう。）

#Symbol Walletをノードに接続
Symbol ウォレットを起動したら、右上の「●TEST_NET」をクリックして、先ほどのIPアドレスを入力して右側の「+」ボタンをクリックします。

![スクリーンショット 2020-04-10 0.04.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461900/eb6717c9-59d8-75b2-9241-659423af7c1d.png)

ノードに接続できたらポップアップが出て↑の●が緑になっているはず！

#Symbol Walletに無償NEMを購入
あとは冒頭に出てきたGIFの手順に従って、テストネット用の仮想通貨を無償で購入できるサイトにアクセスし、財布に入れましょう！

次回、Dapps開発篇をお楽しみに。
autohotkeyでscrapboxの新規カード作成のショートカットを作成する方法

#scrapboxになぜか存在しないカード新規作成ショートカット

最近scrapboxを使い始めてとても使い勝手が良くていいなあと思っていたのですが唯一不満なのがなぜか新規作成のショートカットが存在しないことでした。
カードを連続で何個も作成したいときにいちいちマウスに手をのばさなければならないので結構なストレスを感じていました。
調べてみても見つからないし、ないなら自分で作るの精神でショートカットを作成しました。

ショートカット作成には王道のautohotkeyを使用しました。これめっちゃ便利なのでほかのことにも使っていきたい。

##autohotkeyのインストール
導入はこちらを参考にしました。
https://qiita.com/chr/items/47f50e36703d3bb20371

注意点として、なぜかGoogleChromeからは悪意のあるプログラムとしてダウンロードできないので他のブラウザを使用しましょう。Microsoft Edgeからはインストールできることを確認しています。

インストールが終わったら適当なテキストファイルを作って以下のスクリプトを記述します。



```ahk
Move_URL(targetURL)
{
	send, !d ; アドレスバーにフォーカスする
	sleep,10　;環境によってはここの数字を大きくしなければいけない可能性あり
	send, %targetURL% ; ログインフォームを開く
	sleep,100 ;環境によってはここの数字を大きくしなければいけない可能性あり
	send, {enter}
	sleep,100 ;環境によってはここの数字を大きくしなければいけない可能性あり
}

IME_SET(SetSts, WinTitle="A")    {
    ControlGet,hwnd,HWND,,,%WinTitle%
    if    (WinActive(WinTitle))    {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
        NumPut(cbSize, stGTI,  0, "UInt")   ;    DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
                 ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
    }

    return DllCall("SendMessage"
          , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
          , UInt, 0x0283  ;Message : WM_IME_CONTROL
          ,  Int, 0x006   ;wParam  : IMC_SETOPENSTATUS
          ,  Int, SetSts) ;lParam  : 0 or 1
}

;新規カード作成ショートカット
^+c::
 Move_URL("{新規カード作成URL}")
Return
```

IME_Set関数は入力時のモードが全角だとURLが全角になってしまうことの対策です。問答無用で半角にする処理を入れております。
autohotkeyではIMEの状態を取得するのが難しいようなので標準では搭載していません。自分も以下のGitHubを参考にしました。

https://github.com/karakaram/alt-ime-ahk/blob/master/IME.ahk

上記のコードの{新規カード作成URL}の部分にはscrapboxで新しいカードを作成するときに使用される既定のURLを入力します。


既定のURLの形式は以下のようになっています。

```
https://scrapbox.io/{アカウント名}/new
```
scrapbox使っている時のURLを見ればアカウント名が分かると思うので適宜入力してください。


>参考URL
https://scrapbox.io/scrapboxlab/%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AE%E6%96%B0%E8%A6%8F%E4%BD%9C%E6%88%90%E7%94%BB%E9%9D%A2%E3%81%AB%E5%8D%B3%E5%BA%A7%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9


あとはテキストファイルを.ahkファイルとして保存した後にそのファイルをダブルクリックすればautohotkeyが有効になりショートカットを入力することで一発で新規カードを作成できます。

上記のソースコードではctrl+shift+cがショートカットキーになっているので同時に押すことで起動できます。

ショートカットキーを変更したい場合は下記のURLを参考にしてスクリプトを書き換えてください。ショートカットキーの書き換えだけならすぐできるはず。

https://freesoft-100.com/review/autohotkey.html

ブラウザが立ち上がっていない時はこのコマンドは使用できません。ブラウザを立ち上げるコマンドは記述していない（毎回ブラウザを起動するとウィンドウが増えてしまうため）のでブラウザが立ち上がっている時に使用しましょう。

参考URL
http://www.sakuranomichi.jp/wordpress/2018/12/24/adressbar-at-firefox/


ChromeであればShortKeysという拡張機能を使うことで実現できるようです。ただし有料拡張機能。プログラミングが分からない人向け。
http://hokoxjouhou.blog105.fc2.com/blog-entry-1308.html
printf/引数/変数/型に関して

<h2>printf</h2>
printfは、引数を渡すことができる</p>
＜引数を渡すことができるとは？＞
自らが作成した定型フォーマットに対して、設定した文字を自由に入れることができる。
JavaScriptで言うところのテンプレートリテラルに値する？？。
<br>
ーJavaのprintfの場合
int num = 5;
int num2 = 10;
System.out.printf("%d + %d = %d", num, num2, num + num2).println();

↓
５+１０=１５

<h2>変数と型</h2>
変数とはデータを一時的に保管する箱のような物。何度でも変更がかけられる。
どの型で変数を指定するかによって、中に入れられるデータの種類、容量（文字数）が変わる。
また、変数名は基本的には自由に決めることが可能だが、いくつかのルールがある。

＜変数の型の種類＞
byte：より短い数字（大体２桁くらいまで）
short：4桁くらいまで
int：9桁くらいまでの数字
long：世界人口などの大きい桁数
float：浮動小数点。よく分からんが、あんまりおすすめしないらしい
double：浮動小数点。こっちのが一般的らしい。扱え桁数はfloatより大きい。
char：一文字だけの文字
String:文字列
boolean：真偽値どこで使うかは今のところあまりイメージできてない。

＜変数名のルール＞
・変数名は英数を使うことができるが、記号はアンダーバー[_]と、ドルマーク[$]意外のその他記号は使用できない。
・Javaで使われている予約語は使用できない。
・数字から始めることはできない。
・文字数に制限はない
・大文字/小文字は、区別する。
・キャメルケースを使うのが一般的（そうしないとJavaが読み取らない訳ではない。）
 ex）telephonNumber, firstName, populationOfWorld　のように
　　２単語以上ある英語の1単語目の頭文字を小文字、それ以降の単語の頭文字を大文字で表記する。


<h2>今日実行したコード</h2>
jshell> int x = 4
x ==> 4

jshell> int y = 10
y ==> 10

jshell> int z = 5
z ==> 5

jshell> System.out.printf("%d + %d + %d = %d", x, y, z, x + y + z).println()
4 + 10 + 5 = 19

jshell> x = 7
x ==> 7

jshell> System.out.printf("%d + %d + %d = %d", x, y, z, x + y + z).println()
7 + 10 + 5 = 22

jshell> y = 66
y ==> 66

jshell> System.out.printf("%d + %d + %d = %d", x, y, z, x + y + z).println()
7 + 66 + 5 = 78

jshell> z = 43
z ==> 43

jshell> System.out.printf("%d + %d + %d = %d", x, y, z, x + y + z).println()
7 + 66 + 43 = 116

jshell> Double d = 3.4
d ==> 3.4
Windows10で Socks プロキシを「設定」アプリで指定する方法がわからなかった

リモートワークのために以下の記事を参考に設定を行おうとしたが、Windowsの場合どうして良いかわからなかった

* [どこへ行っても安心！SSHサーバーを踏み台にしてWebアクセスする方法](https://linuxfan.info/ssh-dyamic-forward)

## 前提

* WSL2を使用していて localhost forwarding の機能を有効化済み
* `ssh -D 10000 踏み台サーバ` コマンドでダイナミックポートフォワードした状態で踏み台に接続済み
* Firefox についてはブラウザのプロキシ設定で、Socks ホストに `localhost` ポート `10000` を指定してプロキシとして利用できていることが確認済み
 
## やりたいこと

担当案件ではブラウザ毎に異なる挙動をテストするため IE11 や Edge で社内向けにホストしているサーバにアクセスしたい。

## 問題

Window10 のプロキシ設定の画面にはプロトコルを選択したり入力することができないため、Socks ホストをプロキシとして設定する方法がわからない

## 解決方法

コントロールパネルを開き、「インターネットのプロパティ」>「ローカルエリアネットワーク(LAN)の設定」>「プロキシの設定」の画面を開いて以下の様に設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8219/30a6638b-34a3-58b7-62ff-e156552538d7.png)

結果として「設定」アプリ側には以下のように設定された。

```
http://socks=localhost
```

~~`http://` の後に `socks=` と入力するなんてこと分かるわけない~~ → この画面で同じように入力してもだめだった。あくまでも Socks プロキシの設定はコントロールパネル経由で行う前提らしい。


実際の画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8219/75545a1f-4e8c-31f1-41bd-1fb443bc0864.png)

とりあえずこれで、IE11, Edge から socks プロキシ（踏み台）経由でアクセスすることができた。
祝！プログラミング入門 Webアプリ」完走〜N予備校を始めて30日間の成長記録~

『N予備校を始めて20日間の成長記録』( https://qiita.com/Molly95554907/items/58172e1a7994c5b6ad4c )の続きです。

21日目(3/23)〜23日目(3/25)
N予備校の復習と絡めた『スラスラ読める　JavaScriptふりがなプログラミング』の読書記録を書いていたのでN予備校はノータッチ。
JavaScriptの基礎、オブジェクトとは・クラスとは、基本的な関数の構成などなどを学ぶ。

24日目(3/26)
4章３項途中まで
「ExpressのAPI」についての項目で苦戦。

「（wikipediaより）アプリケーションプログラミングインタフェース（API、英: Application Programming Interface）[1]とは、広義ではソフトウェアコンポーネント同士が互いに情報をやりとりするのに使用するインタフェースの仕様」

つまり、Expressのフレームワークを使えばソフトウェアやいろんなパッケージ同士の連携がやりやすくなるってことなのかな？

「GitHub を使った外部認証」も難しかったけど、これができればwebアプリでできることが増えると思うと楽しい内容。
passportモジュール（ http://www.passportjs.org/ ）を使って外部認証を行う実装。

passportモジュールでサポートされていないアプリとの連携はどうやるのか気になる。


25日目(3/27)
（期末で忙しく学習時間が取れず）

26日目(3/28)
４章６項まで
ここら辺はフレームワークの学習
テストや静的解析ツールをちゃんと使いこなせるようになりたい。
CircleCIは、授業で紹介されてるのと現在のとで、画面の表示が若干違うので混乱した。
仕様変更があったのかな？それとも何か間違えてた・・・？

27日目(3/29)
４章１１項まで
主にデータベースについて。
データベースについてはProgateで予め少しやっていたけれど、実践的なプログラムのなかで使うのはまた感じが変わるなと実感。

28日目(3/30)
４章１４項まで
postgreSQLにログインできなくなり焦る。
実は、postgreSQLにすでに入っていたのに、気づかず再度「sudo su postgres」をやっていたのでおかしくなってただけだった。
N予備校のフォーラムで質問したら、翌日には解決したので大感謝。

29日目(3/31)
４章１６項途中まで
実装した内容をテストする。テストするポイントも参考になる。
これからWebアプリ作っていく中でも、テストをちゃんと書く習慣をつけていきたい。

30日目(4/1)
４章１７項途中まで
JavaScriptでSQLを取得し、コード上で操作する。
ここら辺は分かったようで定着してないのでちゃんと復習&数をこなして理解したいところ。
Node.jsのsequelizeモジュールを使ってデータベース を扱う。
sequelizeモジュールについてちゃんと理解したい。

31日目(4/2)
４章１８項途中まで
予定調整くん実装段階になって、格段に難易度が上がった気がして進みが遅くなる。
早いうちからテキストだけでなく授業VTRもみとけばよかったんだけど、この段階ではまだテキストだけで勉強してた。

フレームワークを使った実装、sequelizeを使ったデータベースの処理の実践編。

32日目（4/3)

33日目(4/4)
４章１８項終了。
実装量が多い、コード一行ごとの意味が取れない、テキストだけでやってた、などが絡んでだいぶペースが落ちてて心おれそうだった。
何とか一項目終える。いつかは「完全に分かった」と言えるようになってたい。

34日目（4/5)
４章１９項終了

35日目(4/6)
４章２０項終了
bootstrapについて、３章でやった時よりも詳しく説明してくれたのでその後の応用にも繋がりそうな話だった。
bootstrapで何ができるかは、やはり公式サイトの説明を見たり、公式サイトでつけたい機能について検索するのがベスト。

36日目(4/7)
４章２２項終了
セキュリティ対策について、何が脆弱性なのか。どんな時、何を対策すべきか。今回は対策しなくていいものの理由などの解説があったのが実践的でわかりやすかった。やはりフレームワークを作ると実装が楽！

今回は、私はすんなりHerokuにデプロイできたのでHerokuと和解できた気分。
Herokuの使用は３章以来だったから、良い復習になった。

●今後
引き続き、Webアプリ入門のおまけを進める。
終わったら何か、卒業制作となるアプリを作りたい。過去のN予備校のコンテスト作品を見て、何ができるか考えておく。

基本情報午前試験のこともそろそろ考えないといけないので、N予備校のコンピューターサイエンスも並行して視聴予定。

JavaScriptである程度何かできるようになったら、次はpythonを扱うN予備校のカリキュラムにいきたい
Pythonで毎日AtCoder #31

### はじめに
[前回](https://qiita.com/taxfree_python/items/5e15be3bf8e0603b2b0e)
\#24の続きです。今日は[ARC031-B](https://atcoder.jp/contests/arc031/tasks/arc031_2)を解きます。

### #31
[ARC031-B](https://atcoder.jp/contests/arc031/tasks/arc031_2)

**考えたこと**
最初はDFSの書きかたが分からなかったので、[記事](https://qiita.com/ally772221/items/cd6436723dc379c1d83e)を読みました。しかし、検索しても再帰関数を使ったものしか出てこなかったので、今回はstackを使って解きます(それしか知らない)。
[この問題の一つ前の問題](https://atcoder.jp/contests/atc001/tasks/dfs_a)との違いはゴールが設定されていないことです。最初はこれで躓きました。ゴールが無いので探索の終了条件をうまく設定できなかったからです。ですので、ゴールを考えます。この問題は**'o'が全て繋がっているかどうか**を聞いている問題なので、探索した'o'数が入力の'o'の合計になることがゴールです。また、埋め立ては二重forで計算しています。**変数名が汚ないのは許してください。**

```python
from collections import deque
field = [list(input()) for _ in range(10)] #strで受け取ると埋め立て時にエラー吐くのでlistにしてます

def dfs(field,visited_list,stack):
    step = 0
    while len(stack) > 0:
        h, w = stack.pop()
        for j, k in ([1,0],[-1,0],[0,1],[0,-1]):
            new_h, new_w = h+j, w+k
            if new_h < 0 or new_h >= 10 or new_w < 0 or new_w >= 10:
                continue
            if field[new_h][new_w] != 'x' and visited_list[new_h][new_w] == 0:
                visited_list[new_h][new_w] = 1
                stack.append([new_h,new_w])
                step += 1 #ステップを計算
    return step

count_step = 0
for i in range(10):
    for j in range(10):
        if field[i][j] == 'o':
            count_step += 1
ume = 0
for i in range(10):
    for j in range(10):
        if field[i][j] != 'o':
            field[i][j] = 'o'
            count_step += 1 #埋め立てた分'o'が増える
            ume = True
        visited_list = [[0]*10 for _ in range(10)]
        visited_list[i][j] = 1
        stack = deque([[i,j]])
        step = dfs(field,visited_list,stack)
        step += 1
        if step == count_step:
            print('YES')
            quit()
        if ume:
            field[i][j] = 'x' #埋め立て後は戻す
            ume = False
            count_step -= 1
print('NO')
```

### まとめ
少しずつ慣れていって使いこなせるようになりたい。おもしろい問題があったらリプください。ではまた、おやすみなさい。
translation missing〜　エラーについて

## はじめに
作成した個人アプリのテストを行っていた際にエラーが出てテストに失敗しました。
調べて解決出来たので、備忘のために残しておこうと思います。

### エラー内容
---
Userモデルのバリデーションのテストをしていたら以下のエラーが発生し、テストに失敗しました。

```
translation missing: ja.activerecord.errors.models.user.attributes.nickname.blank
```

調べたところ、エラー内容としてはdeviseを日本語訳したファイルがないというエラーのよう。
（gem deviseを使ってユーザー管理機能を実装）


### エラー原因
---
自作アプリで、ページネーションを日本語表示にするために
config>application.rb　に　”config.i18n.default_locale = :ja”と
日本語化する設定をしていたのですが、deviseのエラーメッセージに関しては日本語化していませんでした。
そのため、deviseの日本語のファイルがないよとエラーになってしまったみたいです。

```ruby:config>application.rb
class Application < Rails::Application
    ~省略~
    #以下で日本語化の設定をしていた
    config.i18n.default_locale = :ja 
  end
```

### エラー解決方法
---

解決するには上記の日本語化を削除するか、deviseの日本語ファイルを作成してあげればOKのよう。
私はページネーションを日本語で表示させたいので、後者のやり方で解決することにしました。
</br>
#### deviseの日本語化
config/localesディレクトリ内の以下のファイルを2つ新規で作成します。
作成したファイル内に、それぞれリンク先に載っている記述内容をそのまま全てコピーして貼り付けるだけです。

- [devise.ja.yml](https://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml)
- [ja.yml](https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml)

これで日本語化することが出来たので、最初のエラーは出なくなりました。
ただ、日本語化したのでテストの際のエラー文言も日本語で書く必要があります。
INA219の使い方

## 概要
電流計測と，電源ラインの電圧監視ができる．
本質情報→[データシート](http://www.tij.co.jp/jp/lit/ds/symlink/ina219.pdf)
秋月にモジュールが売ってる．
[ＩＮＡ２１９使用　電流センサーモジュール（カレントセンサー）](http://akizukidenshi.com/catalog/g/gM-08221/)

## I2Cレジスタ

|アドレス|機能|
|:---:|:---|
|0x00|コンフィグ|
|0x01|シャント電圧|
|0x02|バス電圧|
|0x03|消費電力|
|0x04|シャント電流|
|0x05|キャリブレーション|

## 計算式
### 乗算器
2つの乗算器が入ってる
（シャント電流）＝（シャント電圧）＊（キャリブレーション）／4096
（消費電力）＝（シャント電流）＊（バス電圧）／5000
※（キャリブレーション）はデフォルトでは０なので，設定を書き込まないと（シャント電流）は機能しない
### ADC
（バス電圧）の単位は4[mV]
（シャント電圧）の単位は0.01[mV]

## 実験
### 条件
1[kΩ]の抵抗とシャント抵抗0.1[Ω]を直列につなぐ
電源はiphoneの充電器（5[V]）
バス電圧は5[V]=5000[mV]=0x04E2[4mV]
シャント電流は5[V]/1[kΩ]=5[mA]
シャント電圧は5[mA]*0.1[Ω]=0.5[mV]=0x32[0.01mV]

### コード

```c:main.c
#include <stdio.h>
#include <stdint.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>

#define DRIFT -11

int fd;
int BusV,SntV,SntA;
uint16_t BusV_raw,SntV_raw,SntA_raw;

int init(int adr){
    fd = wiringPiI2CSetup(adr);
    // Config
    // wiringPiI2CWriteReg16(fd,0x00,0x399F);
    // Caribraion 0.1ohm 1%
    // wiringPiI2CWriteReg16(fd,0x05,0x0000);
    return 0;
}

uint16_t swap(uint16_t hoge){
    return ((hoge & 0xFF00)/0x0100 + (hoge & 0x00FF)*0x0100); 
}

int update(){
    BusV_raw = swap(wiringPiI2CReadReg16(fd,0x02)) >> 3;
    SntV_raw = swap(wiringPiI2CReadReg16(fd,0x01));
    SntA_raw = swap(wiringPiI2CReadReg16(fd,0x04));
    BusV = BusV_raw * 4;
    SntV = SntV_raw - 0x10000 - DRIFT;
    SntA = SntA_raw;
    return 0;
}

int main(void){
    init(0x40);
	for(;;){
        update();
		printf("Bus:%5u[mV] ",BusV);
		printf("Snt:%5d[0.01mV] ",SntV);
        printf("Cur:%5d[0.01mA]",SntV*10);
		printf("\n");
		delay(100);
	}
	return 0;
}
```

## コンフィグ
####[15]
リセットビット
1をセットするとレジスタをクリアする
リセットされるとリセットビットは0になる
####[13]
バス電圧の計測範囲(0:16V/1:32V)
####[11:12]
シャント電圧の測定可能範囲
(00:±40mv/01:±80mv/10:±160mv/11:±320mv)
####[7:10]
バスADCの分解能
####[3:6]
シャントADCの分解能
####[0:2]
動作モード(0b111にしとけば全部動く)
フォトクリエイトのチーフエンジニアを退任しました

## はじめに
先日、ツイート[^tweet]しましたが、2020年3月末で、フォトクリエイトさんとの業務委託契約を終了しました。
自動的に、チーフエンジニアも退任ということになりました。

過去に、チーフエンジニアになりましたという記事[^chief_engineer]を書いた以上、チーフエンジニアでなくなりましたという記事も必要だろうということで、振り返りしてみようと思います。

## やってきたこと
フォトクリエイトでやってきたことについては、アドベントカレンダーなどに記事を投稿しているので、興味ある方はご覧になってください。

- [Symfony2のプロジェクトにひたすら機能テストを書いた話](https://qiita.com/imunew/items/9fc2cdb184d7ffd4682c)
- [リモートワークの業務委託だけどチーフエンジニアになりましたという話（Photocreate Advent Calendar 1日目 ）](https://qiita.com/imunew/items/257c943cb92661629b96)
- [ららびゅう座談会を開催しました （Photocreate Advent Calendar 5日目 ）](https://qiita.com/imunew/items/e3bd371fa4cd38b9e374)
- [ららびゅう座談会を開催してみて （Photocreate Advent Calendar 16日目 ）](https://qiita.com/imunew/items/11a243b9dda6a83a6dd6)
- [Laravelで作ったらすべて解決ではないよ？](https://qiita.com/imunew/items/ff2b61eb62b5ac4ffac7)

## 総括
トータルで3年3ヶ月ほどお手伝いしていたのですが、ざっくりまとめると以下のようになります。

- 1年目は、`Symfony2`のプロジェクトにひたすら機能テストを書き
- 2年目は、`Laravel`+`Vue.js`でいくつかAPIやWebアプリを開発したり、色々
- 3年目で、`Laravel`でAPIをガッツリ実装しつつ、`Amazon ECS`でインフラ構築したり

## フォトクリエイトさんへの謝辞
大した成果を出せずにくすぶっていた私にたくさんの成長機会をいただきありがとうございました。
特に3年目、`スナップスナップ`のリニューアル[^snapsnap]において、`Amazon ECS`でインフラを構築できたことは貴重な経験となりました。

## 今後は？
これまでの知識と経験をフル活用して、企業向けのSaaSを`Laravel`と`Nuxt.js`を使って開発していきます。
フロントエンド、API、インフラ、全部やります。

## おわりに
私のキャリアはまさに叩き上げといった感じなので、これからも環境を変えることで、強くなっていきます。
お仕事の相談などありましたら、[imunew](https://twitter.com/imunew)までご連絡ください。
ではでは。

[^tweet]: https://twitter.com/imunew/status/1244894970571456512?s=20
[^chief_engineer]: https://qiita.com/imunew/items/257c943cb92661629b96
[^snapsnap]: https://www.photocreate.co.jp/news/press/1031/
include_pathについて整理

# include_pathとは
- require()、include()、fopen()、file_get_contents()などのPHPのファイルを読み込む関数がファイルを検索するディレクトリのこと。
- php.iniに設定しておくことでフルパスや相対パスで指定しなくても読み込める。
- 「環境変数PATHに通す」のと似たような感じ

# 相対パスを指定した時の優先度
- ※include(),require()関数しか調べてません
- パスを指定しない場合
    - まずinclude_pathから探す
    - 無ければスクリプトと同ディレクトリから探す 
- 相対パスあるいは絶対パスを指定した場合
    - まずスクリプトと同ディレクトリから探す
    - 無ければinclude_path

# コマンドラインでinclude_pathの設定を確認したいとき

```php
php -r 'echo get_include_path() . "\n";'
```

# 参考
http://engineer-memo.goodhead.work/pages/212#title_415
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11189406816
https://jutememo.blogspot.com/2008/04/php-include.html
snowman でpythonのリストを整理

<h1>pythonの配列の書き方</h1>
整理したかったけど、なかなか理解できないので、隠れジャニヲタなわたしがジャニーズを使って
公式を覚えるためのものです。

※補足
今回使用するsnowmanというグループはそもそも6人で活動
その後3人増員され9人でデビュー。
しかし2020/4/8現在　1人が活動自粛中です。

この情報とっても重要

<h2>リストの基本構文</h2>

```旧snowman.py
snowman = [
          "深澤辰哉",
          "岩本照",
          "渡辺翔太",
          "宮舘涼太",
          "阿部亮平",
          "佐久間大介"
          ]
print(snowman)
```
上記を実行すると下記のようになる。

```旧snowman.py実行結果
['深澤辰哉','岩本照','渡辺翔太','宮舘涼太','阿部亮平','佐久間大介']
```

<h2>1人だけ取得したいとき</h2>
リストは0~始まる番号で中身を特定しており、[]内に番号もしくは、変数を指定してあげれば、取得できる。
今回はシンプルに番号で取得

```1人だけ取得.py
snowman = [
          "深澤辰哉",
          "岩本照",
          "渡辺翔太",
          "宮舘涼太",
          "阿部亮平",
          "佐久間大介"
          ]
print(snowman[0])
   
```

```1人だけ取得.py実行結果
　深澤辰哉
```

<h2>リストの追加</h2>
現在snowmanは3人追加して9人で活動しているので、追加してあげる
<h3>変数.append()</h3>
この場合は、1つの追加しかできない。

```新snowman.py
snowman = [
          "深澤辰哉",
          "岩本照",
          "渡辺翔太",
          "宮舘涼太",
          "阿部亮平",
          "佐久間大介"
          ]
snowman.append("向井康二")
snowman.append("目黒蓮")
snowman.append("ラウール")
print(snowman)
```

```新snowman.py実行結果
['深澤辰哉', '岩本照', '渡辺翔太', '宮舘涼太', '阿部亮平', '佐久間大介', '向井康二', '目黒蓮', 'ラウール']
```

<h3>複数の値の追加 +=</h3>
```新snowman.py
snowman = [
          "深澤辰哉",
          "岩本照",
          "渡辺翔太",
          "宮舘涼太",
          "阿部亮平",
          "佐久間大介"
          ]
snowman += ["向井康二","目黒蓮","ラウール"
print(snowman)

```
```新snowman.py実行結果
['深澤辰哉', '岩本照', '渡辺翔太', '宮舘涼太', '阿部亮平', '佐久間大介', '向井康二', '目黒蓮', 'ラウール']
```

<h3>複数行の追加その2 変数.extend()</h3>
```新snowman.py
snowman = [
          "深澤辰哉",
          "岩本照",
          "渡辺翔太",
          "宮舘涼太",
          "阿部亮平",
          "佐久間大介"
          ]
snowman.extend(["向井康二","目黒蓮","ラウール"])
print(snowman)

```
```新snowman.py実行結果
['深澤辰哉', '岩本照', '渡辺翔太', '宮舘涼太', '阿部亮平', '佐久間大介', '向井康二', '目黒蓮', 'ラウール']
```

<h2>リストの値の削除</h2>
現在snowmanは岩本照くんが活動停止中。
そのためリストから外す

```snowman.py

snowman = [
          "深澤辰哉",
          "岩本照",
          "渡辺翔太",
          "宮舘涼太",
          "阿部亮平",
          "佐久間大介"
          ]
snowman.extend(["向井康二","目黒蓮","ラウール"])
print(snowman)

snowman.remove("岩本照")
print(snowman)
```

```snowman.py実行結果
['深澤辰哉', '渡辺翔太', '宮舘涼太', '阿部亮平', '佐久間大介', '向井康二', '目黒蓮', 'ラウール']
```

<h2>リストの中身の数を確認　メンバーの数確認</h2>

```snowman.py

snowman = [
          "深澤辰哉",
          "岩本照",
          "渡辺翔太",
          "宮舘涼太",
          "阿部亮平",
          "佐久間大介"
          ]
snowman.extend(["向井康二","目黒蓮","ラウール"])
print(snowman)

snowman.remove("岩本照")
howmany = len(snowman)
```

```snowman.py実行結果
8
```

思い立ったら追記します。
Docker入門(1)/忘備録

##Dockerとは
・アプリの実行環境をラップしてくれる
=> ホストがライブラリやミドルウェアで汚れない(node.jsやrubyなどをホストに入れなくて済む)
=> 環境構築が楽になる。

・実行環境を共有できる
=> チーム開発でもチーム間で同じ環境を一瞬で揃えられる
=> ネット上の猛者たちが作ってくれたコンテナ(開発環境)がネットに沢山転がっている。

・VMと比べて軽い

##イメージ[ Image ]とは
・オブジェクト志向で言うところのクラス(設計書)
・Dockerfileを基にビルドされる。
・Dockehubを用いてイメージそのものの共有も可能
	=> Dockerfileも共有可能だけどDockerfileをbuildして作成されたイメージの共有も可能
・もう大体のケースを想定して作られたイメージが既にDockerhubに配布されている
・Dockerfileをビルドするコマンド
	=> $ docker build [Dockerfileのpath]

##コンテナ[ container ]とは
・オブジェクト志向で言うところのインスタンス(具現化)
・イメージで作成された実際の動作環境
・起動時のコマンドが終了すると自動で終了する(?)
・原則一つのコンテナに一つのアプリケーション
	=> データベースのコンテナ、アプリのコンテナに分けるといいらしい
・起動のコマンド 
	=> docker run : imageからコンテナを作成して起動
	=> docker start : 既にあるコンテナを起動
	例えば、Nginxのコンテナを起動
		=> docker run nginx
		=> Docker をインストールしてこのコマンドを叩くだけでnginxのwebサーバが立つ！！
		=> docker -volume で操作したい対象(例：app/ とか)をマウントが可能
		=> volume : コンテナを削除しても情報をコンテナの外に残す(例：DBとか)

##Dockerfileとは
・このファイル内でライブラリやミドルウェアのインストールを記述できる
・これを他人に配布すると同じ環境が作れる
・既に便利なイメージがあるので(初心者は)そこまで書くことはないかも
・docker build でビルドが可能
【わかばちゃんと学ぶ Git使い方入門】本の感想を書く 

# これを見て Git が理解できない人はいない

![alt](https://m.media-amazon.com/images/I/51oMuvNCF3L.jpg)
[わかばちゃんと学ぶ Git使い方入門](https://www.amazon.co.jp/%E3%82%8F%E3%81%8B%E3%81%B0%E3%81%A1%E3%82%83%E3%82%93%E3%81%A8%E5%AD%A6%E3%81%B6-Git%E4%BD%BF%E3%81%84%E6%96%B9%E5%85%A5%E9%96%80-%E6%B9%8A%E5%B7%9D%E3%81%82%E3%81%84-ebook/dp/B071D4D6XX/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1Q4EVLUK3PSN0&dchild=1&keywords=%E3%82%8F%E3%81%8B%E3%81%B0%E3%81%A1%E3%82%83%E3%82%93+docker&qid=1586439780&sprefix=%E3%82%8F%E3%81%8B%E3%81%B0%E3%81%A1%E3%82%83%E3%82%93+%2Caps%2C366&sr=8-1)

## ◇ 感想
Git という言葉を聞いたことはありましたが、「 なんだか難しそう … 」と思い込んで Git を避けてきました。しかし、至る所で Git を聞かない日がなくなってきた今日、さすがに無視はできないと思い本書を購入させていただきました。

本書は女子大生のわかばちゃんが Web 系のゼミに入るところから物語が始まり、そのゼミの Web サイトを編集していく中で Git の概要だったり、使い方をどんどん学んでいくという構成です。主人公のわかばちゃんになりきった感じで本書を読み進めることができるため、なぜ Git が必要なのか、Git を使うと何が便利になるのかが分かりやすく、ストーリを読み進める度に Git をどんどん理解することができました。また、本書では「Sourcetree」を使って実際に手を動かして Git を体験できる工夫が施されているため、言葉だけではイメージしずらいことが「Sourcetree」の操作を通して理解できたり、リモートリポジトリとして有名な「GitHub」や「Bitbucket」との連携を学べたりと、Git の仕組全体を俯瞰できるような構成になっていたことも初学者としては嬉しいところでした。ただ、実際の現場では「Sourcetree」のような GUI よりも CUI を用いているところの方が多いような気がするのと、単純にコマンドべースで操作できた方が楽だと思うので CUI での操作も学んでいこうと個人的に思いました。

「Git ってなにそれ … 美味しいの？」と思っているエンジニア、実際の現場で Git が使われていて早急に Git を学ぶ必要がある方、資料更新の際にいにしえの手動バックアップを未だに行っている方、そんな方々におすすめできる一冊です。

※ ちなみに私の現場のバージョン管理システムは TFS です …
xserverでコマンドが使えなくなってしまった時

flaskを使いたくてssh接続したあとにターミナルで

```
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
```
と打ったところ

```
-bash: curl: コマンドが見つかりません
-bash: ls: コマンドが見つかりません
```
のようなエラーが出てしまいました。


いろいろ調べていたら、
[「コマンドが見つかりません」の直し方について](https://teratail.com/questions/211283)
上のteratailの記事の通りに進めていったら使えるようになりました。ありがとうございます。

```
/usr/bin/vi ~/.bash_profile
```
で.bash_profileの中身を確認し、

```
PATH=$PATH:$HOME/bin
export PATHeval $(/home/XXXXX/.linuxbrew/bin/brew shellenv)
```
を

```
PATH=$PATH:$HOME/bin
export PATH
eval $(/home/XXXXX/.linuxbrew/bin/brew shellenv)
```
のように改行させたところ、lsとかのコマンドが使えるようになりました。
【Github】ブランチ名の変更

一人でアプリを作る時ブランチ作って作業すると思うんですけど気付いたら全然違う作業してたりして、前まではブランチ消してその作業にあった名前をつけてコードをコピペする...これを繰り返してました。なんかいい方法あるやろと思い調べたらいい方法ありました。備忘録として残しとこう。いやーやっぱ分からなければすぐ調べるべきですね。

```
git branch -m 新しいブランチ名
```

はい、これだけです...
今までのコピペ作業がなくなって楽になりました。

ちなみにこれは今作業中のブランチの名前を変える方法で違うブランチを開いてた場合は

```
git branch -m 今のブランチ名 新しいブランチ名
```
で出来るみたいです。こっちは試してないんでまた今度機会があれば。
ではでは
Docker で立てた WordPress を検証した後からブラウザで特定ポートへのアクセスができなくなる

# 問題

- ローカルで WordPress を Docker で構築した
    - 使ったイメージは [ここ](https://hub.docker.com/_/wordpress/) のDocker Official
    - ページに記載されている通り `-p 8080:80` のポート割り当てで起動
- この時点で初回の検証をする場合は特に問題は起きなかった
- 改めて起動して `http://localhost:8080` にアクセスすると、 `http://localhost` にリダイレクトされてアクセスできない
- WordPressコンテナを落として次の日、WordPress 以外のアプリケーション開発で `http://localhost:8080` にアクセスすると `http://localhost` の表示となり、`8080` にアクセスできていないように見える
    - ただし、`/` 以外 ( `http://localhost:8080/login` など ) にアクセスはできる
- curl などでは普通に `http://localhost:8080` へはアクセスできる

この問題の原因を探る。


# 調査結果

- WordPress の `home` および `siteurl` はコンテナ内部のポートに依存した初期設定が行われるので、 `http://localhost` で初期データが作成される
    - どうも WordPress ではアクセスしてきたドメインと `wp_options.home` に登録されているドメインが違う場合、 `home` のドメインに 301リダイレクトが発生する……らしい。
        - なんでこんな機能があるんだろう…、リバプロとかすごく挟みづらそう…
- そのため、この状態のWordPressが動作している状態で `http://localhost:8080` にアクセスすると、 `http://localhost` に 301 リダイレクトされる
- そして **ブラウザでは 301 リダイレクトもキャッシュする**
- ので、キャッシュが残っている間は `http://localhost:8080` へのアクセスを行うと、一瞬でリダイレクトされるので `http://localhost:8080` に対してアクセスができないように見える


# 解決策

- ブラウザのキャッシュをクリアする
- WordPressが利用するDataBase の `home` および `siteurl` を `http://localhost:8080` に書き換える
    - ただし、WordPress 内部から home および siteurl を参照して自分自身にアクセスするような場合、`http://localhost:8080` はコンテナ内部で閉じているので動かない
    - サンプルには `-p 8080:80` と書いてあるが、もう複雑すぎるので `-p 80:80` 以外で動かさない方がいいんじゃないかな？
    - もしくは、そもそもローカルで構築せずにグローバルなFQDNを割り当ててそれで外中両方のアクセスを適切に解決できるようにすればよい


# 参考

というか同様のトラブルにハマった方の記事。

- [トラブル事案｜dockerでWordPressを動かしたらlocalhost が転送される事態になった件](https://qiita.com/tomokei5634/items/034e3e5154e8e077ef60)


# 余談

WordPress、システムを管理する側から見るとものすごくハマりどころが多い印象でつらい。
正規表現(Ruby)

###\d は「半角数字1文字」を表す
\d は「1個の半角数字（0123456789）」を意味するメタ文字です（文字の集合を表しているので、特に 「文字クラス」 と呼ばれます）。
<br>

###{n,m} は「直前の文字が n 文字以上、m 文字以下」であることを表す
/\d{1,3}/
=>１桁以上３桁以下
○　1,　43,　576
✖️　3451,　05969
<br>

###{n} は「直前の文字がちょうど n 文字」であることを表す
/\d{4}/　　=>　4桁
/3{5}/　　=>　33333
<br>

###[AB] は「AまたはBが1文字」であることを表す
/[OK]/　　　=>　OかK
<br>

###[a-z] と [-az] ではハイフンの意味が異なる
/[a-c]/　　　=>　abc
/[-ac]/　　　=>　-かaかc
<br>

###正規表現の正確さと複雑さはトレードオフになることが多い

メールアドレスの正規表現は下記の通り。
複雑で考えていると莫大な時間を使ってしまうため、ある程度に抑えることもしばしばある。

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

###区切り文字が1文字、 もしくは区切り無し

 「～が1文字、または無し」を表現するためには ? というメタ文字を使います。（文字量を指定するので 量指定子 のひとつです）
/フランシスコ・?ザビエル/　　=>　フランシスコ・ザビエルかフランシスコザビエル
<br>

###任意の１文字
「任意の1文字」を表す . というメタ文字（文字クラス）があります。
/オリバー.カーン/　　　=>　オリバー　カーンやオリバー・カーンやオリバー＠カーン
<br>

###対象の言葉を含む１行を抜き出す
オリバーカーン等を含む１行を文章から抜き出す。

```ruby:ruby
text.split(/\n/).grep(/オリバー.?カーン/)
```
<br>
【Terraform】for_each で AWS SSM パラメータストア に パラメータを一括登録する

# はじめに

TerraformでAWSの環境構築を行う際に`for_each`を利用して**AWS SSM (System Manager) パラメータストア**にパラメータを一括登録する方法を備忘録として投稿させていただきます。

# terraform

```hcl:variables.tf
variable "list" {
  description = "AWS SSM パラメータストアに登録する名前と値のセット"
  type        = map(string)
  default = {
    "DB/HOST "    = "xxxxx"
    "DB/USER"     = "xxxxx"
    "DB/PASSWORD" = "xxxxx"
    "DB/DATABASE" = "xxxxx"
  }
}
```

```hcl:main.tf
resource "aws_ssm_parameter" "list" {
  for_each = var.list

  name  = "/${each.key}"
  value = each.value
  type  = "String"
}
```

# 実行結果

![qiita-ssm-parameter-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/669ac2de-6a6e-3ca5-6c65-2299d15ca808.png)

![qiita-ssm-parameter-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/0a49743c-862a-f624-f929-18e1c9081cbb.png)
特徴エンジニアリングのコツ

# はじめに
kaggleのコンペを始めた際に特徴エンジニアリングで学んだときに凄い納得したことの備忘録。
コンペをやった人ならわかると思うのですが、モデル自体は皆ほとんど似たようなモデルを使ってるんですよね…
どこでこんなにスコアを離されるんだろうと思っていました。
ならどうして1位の人と差が出るのか、それは**特徴エンジニアリング**にあります。
# 特徴エンジニアリングとは
特徴エンジニアリングとは、まぁご存じのとおり、与えられた特徴の他に新しい特徴を追加してモデルを学習させることですね。
これは
**1．全く新しいデータを集める方法**
**2．もともとある特徴量から、新たな特徴量を算出する方法**
の2種類が主になるかと思うのですが、
新しいデータを集めるのは難しいし、どんな特徴量を足せばいいのかわからん！
そもそも計算で算出してるならもともとの特徴量の情報も持ってるから無意味やろ！
ってツッコミたくなるかもしれません(僕もそうでした)
過去の僕も何回か適当に特徴量を追加してみたこともあったのですが、あまりスコアを上げることができませんでした。
しかしそれは特徴エンジニアリングのコツを全く理解せずに学習させていたことが原因でした。
# コツ
コツは以下の2つになります！
**重要なことには過敏に反応すること**
**重要でないことには反応しないこと**
初めてこのコツを知ったとき目から鱗でしたよ全く(勉強不足)
簡単な例を挙げると、University of California at Irvine(UCI)が公開しているデータセット「小麦データセット」があります。
これは小麦の種の面積や長さ幅から小麦の品種を予測するものなのですが、特徴量の中に**密集度**といったものがあります。
この密集度は前述したような、他の特徴量から計算して求められた特徴量なのですが、式としては
`(種の面積)/(種の周囲長さ)^2`
となっています。
この特徴量は種の形が同じであれば面積に関わらず同じ値になります。しかし形が細長くなったり、丸くなったりするとこの特徴量の値は大きく変化します。(適当に代入してみてください)
このように分類に重要な特徴に反応し、重要でない特徴に反応しない特徴量は、学習に非常に有効だといえます。
# 検証
時間があったら更新します。
# おわり
特徴量を作成する際に忘れたくないコツであったので備忘録として記事にしました。
**重要なことには過敏に反応する**
**重要でないことには反応しない**
このコツを意識するだけでモデルのスコアは格段に向上するでしょう！
-これからポートフォリオを作成する方へ-　設計図の作成方法：前半

ポートフォリオを作成する際に、何から始めれば良いかわからない・・・という方に向けて。
第１歩目として設計図を作成する事を強くオススメします。理由は以下の通りです。
>
・自分が今どの部分を実装しているか把握が容易になるため、迷子にならない![スクリーンショット 2020-04-09 23.08.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553621/f5011286-f054-51fa-7f89-fd66f9bfa52c.png)

・少しずつ目標に近く感覚を可視化でき、モチベーションの維持に繋がる
>

そのためにどのようなツールを使用し、どのような物を作成すれば良いかまとめました。

#●使用ツール
こちらはCacooというサービスをオススメします。
https://cacoo.com/

会員登録から一定期間は無料ですので、無料期間中にさくっと作ってしまいましょう。
またPDF出力が可能なので、作成した設計図をPDFとして保存してしまえば無料期間中だけでも事足ります！

#●作成すべき物①　-ER図-
ER図は下記のような物をいいます。
![スクリーンショット 2020-04-09 23.08.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553621/a52e562e-4c56-2cc6-ef0d-9b06276c9911.png)

詳しい作成方法はこちらの投稿が非常にわかりやすかったのでオススメです。
「やさしい図解で学ぶ　ER図　表記法一覧」
https://qiita.com/ramuneru/items/32fbf3032b625f71b69d

あくまでポートフォリオ作成時の準備なので、ここに学習コストを割く必要はないかと思います。
ポートフォリオ作成レベルであれば、上記の記事にかかれている内容を把握すれば十分記載できるかと思います。


#●作成すべき物②  -テーブル設計図-
テーブル設計は以下のようにまとめるとわかりやすいかと思います。
![スクリーンショット 2020-04-09 23.03.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553621/f8d40f62-877a-7bd7-6146-700a3c13a73f.png)

ポートフォリオは就職活動用に作成する物なので、期限も限られていますし他に労力を割く必要もあるかと思います。
ですので、自分が作成する最低限のサービスをまず作成し、その後に状況にあわせ機能追加していく形で計画すると良いと思います。

カラムの型の種類や、カラムの追加・削除・編集方法を簡単にまとまっているのがこちらです。
「カラムの型」
https://qiita.com/mokku/items/39ced66550e9b623b5a8

railsを勉強してる人にとってDB周りは苦手意識のある方が多いと思うので（というか自分ですが）、まずは基本的なことから。

残すはサイトマップとワイヤーフレームです。そちらに関しては今後またまとめたいと思います。
VBAの基礎文法等（VBAを使うときに自分がよく使う基本的な内容）


#変数の宣言・代入
Dim hoge As 型
hoge = 1　　　　　　　　　　　　　オブジェクトではない基本型
set hoge = Worksheets(1)　　　　　オブジェクトの場合はsetで代入


#型
Integer　　　　整数型
Single　　　　単精度浮動小数点型
String　　　　文字列型

参考：[Excel VBA 入門講座へようこそ!!-5章 2.変数のデータ型](http://excelvba.pc-users.net/index.html)

#while文
Do While 条件式
　処理
Loop

参考：[よねさんとWordとExcelの部屋](http://www.eurus.dti.ne.jp/yoneyama/index.html)
参考：[よねさんとWordとExcelの部屋-繰り返し処理(For～Next,Do～Loop)](http://www.eurus.dti.ne.jp/yoneyama/Excel/vba/vba_for_next.html)

#For文
For i=0 To 10 (Step 1)
　処理
Next

参考：[よねさんとWordとExcelの部屋](http://www.eurus.dti.ne.jp/yoneyama/index.html)
参考：[よねさんとWordとExcelの部屋-繰り返し処理(For～Next,Do～Loop)](http://www.eurus.dti.ne.jp/yoneyama/Excel/vba/vba_for_next.html)

#If文
If 条件式1 And 条件式2 then
　処理
Elseif
　処理
Else
　処理
End if

#連想配列
●連想配列オブジェクト作成
Dim dic As Object
Set dic = CreateObject(“Scripting.Dictionary”)

●データ追加
dic.Add "key1", "data1"
dic.Add "key2", "data2"
dic.Add "key3", "data3"

●データ取り出し
hoge = dic("key1")　　　　　　　←どこで調べたか忘れたけど、Itemプロパティを付けなくてもこれで取り出せる。
hoge = dic.Item("key1")

参考：[Samurai Blog-VBA入門】Dictionaryオブジェクト(連想配列)の使い方](https://www.sejuku.net/blog/29736)

#クラスの作成・使い方
●クラスの作成
1.vba画面の「挿入」-「クラスモジュール」クリック
→プロジェクトエクスプローラーのクラスモジュールフォルダ内に「Class1」クラスが作成される

参考：[いつも隣にITのお仕事-【初心者でもできる】エクセルVBAで最も簡単なクラスを作る方法](https://tonari-it.com/excel-vba-simple-class-module/)

●クラス名変更
1.プロパティウィンドウを開いて、プロジェクトエクスプローラーの作成したクラスをクリック
2.プロパティウィンドウのオブジェクト名を変更

参考：[いつも隣にITのお仕事-エクセルVBAでクラスに最も簡単なプロパティを追加する方法](https://tonari-it.com/excel-vba-class-property/)

●プロパティの宣言
作成したクラスのファイルにコードを追加
public hoge as Integer
public hogehoge as String

参考：[プチモンテ-クラスの作成と使い方[ExcelのVBA]](https://www.petitmonte.com/excel/excel_vba_21.html)

●クラスオブジェクトを使う
Dim clsobj As HogeClass
Set clsobj = New HogeClass
clsobj.hoge = 1 
clsobj.hogehoge = "aaa"

参考：[プチモンテ-クラスの作成と使い方[ExcelのVBA]](https://www.petitmonte.com/excel/excel_vba_21.html)

#ワークシートの取得
Dim tSheet As Worksheet
Set tSheet = Worksheets(インデックス番号)
Set tSheet = Worksheets("シート名")

[Office Pro 初心者でもわかりやすいサイト-Worksheetオブジェクトの取得](https://www.officepro.jp/excelvba/sheet/index1.html)

#セルの値取得
x = WorkSheetsオブジェクト.Cells(行番号, 列番号)

#セルの列の表示を数字に切り替える方法(バージョン確認していない)
[ファイル]→[オプション]→[数式]→[R1C1参照形式をを使用する]

参考：[Tipsfound-列の表示を数字とアルファベットで切り替える](https://www.tipsfound.com/excel/01204)

#入力ダイアログ
No = inputBox("番号を入力してください。", "番号入力ダイアログ", "")

#その他
[VBA公式リファレンス（日本語）](https://docs.microsoft.com/ja-jp/office/vba/api/overview/)
db インデックスについて

##インデックスについて

###インデックスとは
インデックスとは、テーブルの情報を探すときに、検索しやすいようにしておいたもの。
テーブルに格納されたデータは、順番に並んでいるわけではないので、検索していくときは上から順に調べていくのは、非常に効率が悪い。
このようなときに、インデックスを作成すると効率よく検索できる場合がある。例えば、idカラムとnameカラムがあった場合、インデックスをnameカラムを対象に作成すると、nameカラムを昇順に並び変え、nameカラムを検索するときに高速で検索することができる。

###デメリット
インデックスはテーブルとは別にデータを保持するので、テーブルにデータを追加するとインデックスにもデータが追加される。そのため、再度並び替えなどを行うと、データを追加する時の処理が遅くなる。なので、格納されているデータが少ないテーブルではインデックスを作成しても効果は期待されない。
気軽にブラウザ上でV化してteams等の会議ソフトで使おう

必要なものはwebカメラと少しの知識だけ！！
そしてノートでも動きます！！
ということで内容は題名通りです

# ブラウザ上でV化する
V化とはなんぞやとかは説明しません。全人類可愛くなれ

このサイトでV化できます。ほんとすごい。

https://facevtuber.com/

また、自分な好きなモデルも使うことが出来ます。
書かれていますが、MMD(mikumikudance等)、FBX(blender等)、VRM(VR系)形式のモデル対応となっています。
背景が欲しい人はクロマキー合成できるようにGBとBBにできる設定もあります。親切。

が、一つだけ設定が必要になるかもしれません

#### 手の操作に関する設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/197f5518-69a0-2aff-52f3-b7f1075444ab.png)

チェック欄にかかれているように両手がマウスに追従されて動きます。
女々しくての動きみたいになるので嫌な人は外しておきましょう。

# 子ウィンドウで表示させよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/b743c7a7-769f-c0ea-8f9b-3146dd6e6639.png)

見出しのとおりに[popWindow]のボタンを押すとモデルが動いているところが別ウィンドウになります。
これでブラウザ側は終わりです。

# OBSにOBS-VirtualCamを入れる
OBSで映像を取得するわけですが、その映像をWebカメラ出力として扱うためには一工夫必要となります。
そのため、このプラグインを使い、Webカメラ出力扱いとします。

https://obsproject.com/forum/resources/obs-virtualcam.539/

入れ方はかんたんで、右上にあるGo to downloadを押し、インストーラーをダウンロードして指示に従うだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/eafa0a60-38df-0f1c-6fd3-ff359b097adc.png)
利用許諾に了承したらこの画面が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/1b63e796-7593-4e45-0f6f-88e1ff5931e4.png)
これは上の1を選択してください。

操作の最後にもしOBSが起動していたら一旦落とす旨の画面が出るので了承し操作を進めると終わりです。

# OBSで画面を取得する
ソースにウィンドウキャプチャを選択してください。
プロパティはこの画像のように設定してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/4a435123-5a2b-d4d8-8e11-a2a89ec4828d.png)


これで取得した映像をなんかだいたい真ん中あたりに配置してください。
ここで見れる画面が写ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/79b511e2-abcc-8c7b-4c8c-b6b5519c1006.png)

# カメラ出力を出す
ではOBSの上にあるツール(T)を開きその中から先程入れたVirtualCamを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/9ea2d591-f8a8-874a-b549-508001abbbdf.png)
この画面が出てくるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/c995ad10-c90c-3884-4d38-a9ea3b97ebce.png)

一番下のは遅延の設定のはずなので０にしておいてください。
その他は開いたままの設定でいいです。



ではStartを押してください。
これでカメラ出力として出力されたはずです。

# 会議ソフトで使う
ここではteamsを例に出します。
デパイスの設定からカメラ設定をみるとWebカメラとOBS-Cameraの１～４までが出ているはずです。(Many cam...は後述します)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/fc8063ec-e5e2-c03b-f326-9dba89d89f12.png)


# 出来なかった人向け
「おいごらぁ！お前の言う通りにしてもでねぇぞ！！！」
という方の話です

・「おい！なんか別ウィンドウにした瞬間止まったぞ！！」
なんかそうゆうもんらしいです。
最低限の操作が欲しい人は別ウィンドウにして小さくしているとハッピーになれたりします。別に操作いらないという人は生きてる状態で最小化させていても動くのですると気持ちよく出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/fa440306-8bc9-c3f9-e60f-04687b92da89.png)


・「てめぇの言う通りにしてもカメラ出力きてねぇんだが！が！！！」
自分も同じような症状が出たので、自分はmanycamというソフトを使って改善しました。
manycamとは仮想Webカメラツールとなっています。
Video Sourceの右にある+からadd camera sourceをしてOBS-cameraを選択すると他アプリでも認識し始めました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604861/4d2d3012-5380-8e88-5c30-42290ec3624a.png)
【Rails】 deviseで新規登録後またはログイン後にroot_path以外のページに飛ばす

#deviseで新規登録したけどroot_path以外のページに飛ばしたい...
今までdevise使ってきたけど新規登録やログインをするとroot_pathのページに勝手に戻ってログインしている状態になってたんですが（いやー便利）、サイト作っている途中にroot_path以外のページに飛ばしたことになりまして調べてみました。
##コントローラーに記述して飛ばす
root_path以外のページ遷移は多分コントローラに書かないと出来ないかも
調べてたらapplication_controller.rbにまとめて書く方やそれぞれの動作に合わせてregistrations_controller.rbやsessions_controller.rbに書く方がいましたが今回はapplication_controller.rbにまとめて書きました。

###その前にrails routesで飛ばしたいpathを確認
<img width="582" alt="3e319ab23a667d951a0ea7f6b885d3ee.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29153/4adc6ca1-6ea7-3871-8067-de49ce83b677.png">
今回は下から２番目のuser_pathに飛ばします。

##application_controller.rbへ記述

```application_controller.rb
class ApplicationController < ActionController::Base
  def after_sign_in_path_for(resource)
    user_path(resource)
  end
end
```

この'after_sign_in_path_for(resource)'でログイン後にどこのページに飛ぶか指定できるんで中にpathを書けばそこに飛んじゃいます。今回はuser_pathですね。

ちなみにpathの横に(resource)と書いているのはURI Patternが/users/:idなのでこの:idを渡すために(resource)が必要になります。これないとエラー出ます。

##補足
今回は新規登録後やログイン後に指定したページに飛ばすやり方だけどログアウトした後にも同様のやり方で指定したページに飛ばせるので紹介

```application_controller.rb
class ApplicationController < ActionController::Base
  def after_sign_out_path_for(resource)
    index_path #今回は仮にindex_pathを置いていますがここにログアウト後のpathを書く
  end
end
```
まあ何もしなければroot_pathに飛ぶのであんま使うことなさそう

ではでは
【React Router】URLパラメーターを取得する

TyepeScriptでReactRouterを扱う際に、URLパラメーターを取得するところで失敗した。

```App.tsx
import React from 'react';

const Characters: React.FC<{}> = (props) => {
  return (
    <>
      {props.match.params.name}
    </>
  );
}

export default Characters;
```

エラーメッセージは
Property '**match**' does not exist on type '{ children?: ReactNode; }'.  TS2339


###RouteComponentPropsを用いる
matchはpropsに渡るオブジェクトに定義されてない。
そこでRouteComponentPropsとpropsの型を結合することで**match**が渡される。

```diff:App.tsx
import React from 'react';
+import { RouteComponentProps } from 'react-router';


+//interfaceの結合
+type urlProps = {} & RouteComponentProps<{name: string}>;

const Characters: React.FC<urlProps> = (props) => {
  return (
    <>
      {props.match.params.name}
    </>
  );
}

export default Characters;
```
URLパラメーターが渡った:grinning:

###ちなみに...

VSCode上でRouteComponentPropsに左クリックしてGo to Definitionで定義ファイルを開くと**match**がプロパティにあることがわかる。

```index.t.ts
export interface RouteComponentProps<Params extends { [K in keyof Params]?: string } = {},C extends StaticContext = StaticContext,S = H.LocationState>
  {
    history: H.History<S>;
    location: H.Location<S>;
    match: match<Params>;
    staticContext?: C;
  }
```
Django 汎用クラスビューでアクセス元を一意に識別する方法

2020-04-08 作成: windows10/Python-3.8.2-amd64/Django-3.0.4

Django でユーザーの行動解析を行うためには、アクセス元の IP アドレスをログに残すだけでは不足しています。ユーザーを一意に識別するには、誰がアクセスしたかを HTTP サーバーのログに残すのが簡単です。

HTTP サーバーのログに Django のユーザー ID を残すには、レスポンスヘッダをカスタマイズします。汎用クラスビューで Django のユーザー ID をリクエストヘッダに追加する方法を書いておきます。

参考
https://blog.howtelevision.co.jp/entry/2014/09/05/170917

Django を初めて使う人は、こちら。
[10 分で終わる Django の実用チュートリアル](https://qiita.com/taiyaki/items/352d36cda37af74eb826)


# レスポンスヘッダを追加したビュークラスを定義

追加したいレスポンスヘッダ userid を汎用ビュークラスに追加。

```py:custom_views.py
class CustomListView(generic.ListView):
    def dispatch(self, *args, **kwargs):
        response = super().dispatch(*args, **kwargs)
        response['userid'] = self.request.user
        return response
```

# 実際に呼び出すビュークラスを定義

ListView を継承するのではなく、CustomListView を継承して、実際に使用するビュークラスを宣言。

```py:views.py
from .custom_views import *
from .models import MyClass
from django.contrib.auth.mixins import LoginRequiredMixin

class MemoListView(LoginRequiredMixin, CustomListView):
    model = MyClass
```

ListView だけでなく他のビュークラスでも同様のことは可能。

Nginx などの HTTP サーバーの設定を変更して、新たに作成したレスポンスヘッダをログに残せば、ログにアクセス元が記録される。


おしまい
Alexaスキル開発でスロットが空のときの条件分岐をしたいとき

スロットに入力がないときにどうやって条件分岐させるかの解説です。

#結論
例えば、a というスロット名を用意しておいて、それが空のときの処理をしたいときは、

```
var a = handlerInput.requestEnvelope.request.intent.slots.a.value;
const str_a = String(a);

if(str_a  === "undefined"){
〜〜空の時の処理〜〜
}else{
〜〜スロットに値が入力されてたときの処理〜〜
}
```
【Solved】Oracleパスワード関連でORA-01017/ORA-28007エラー発生

# はじめに


# ORA-28007対応時のポイント
```sql:oraora_password2.sql
-- プロファイル確認
SQL> SELECT PROFILE, RESOURCE_NAME, LIMIT FROM DBA_PROFILES WHERE PROFILE='DEFAULT' AND RESOURCE_TYPE='PASSWORD' ORDER BY 1;

SQL> select profile, resource_name, limit from dba_profiles where resource_type='PASSWORD' order by 1,2;

-- 対応案1(プロファイル毎)
SQL> alter user SCOTT profile default;

-- 対応案2(個別設定)
ALTER PROFILE SCOTT LIMIT FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1;

```

## 参考サイト
◆Oracle Database 11g の標準セキュリティ設定について#2
　https://koutashiobara.blogspot.com/2012/02/oracle-database-11g-2.html
◆Oracle Autonomous Databaseに慣れる（１）
　https://qiita.com/plusultra/items/213b754cc7732ae75c78
◆[oracle-memo] パスワード管理ポリシー
　http://orcl.usamimi.info/?orcl&ctgr=06&part=02
◆ORA-28007: the password cannot be reused
　https://www.thegeekdiary.com/ora-28007-the-password-cannot-be-reused/
◆ALTER PROFILE
　https://docs.oracle.com/cd/E16338_01/server.112/b56299/statements_2008.htm

# ORA-01017対応時のポイント
どうも、systemユーザーのログイン誤りを何回も繰り返してロックかかっていたようで...
合っているはずなのに「as sysdba」を付与しないと下記エラーでログインできなかった。

ORA-01017: ユーザー名/パスワードが無効です。ログオンは拒否されました。
ORA-01017: invalid username/password; logon denied

```sql:oraora_password.sql

-- これはOK
> sqlplus system/manager@XE as sysdba

-- ORA-01017発生...なぜだ
> sqlplus system/manager@XE

-- 各アカウントのパスワード状況を簡潔に出力
-- （※この時点でsystemがLOCKED(TIMED)になってた...）
select username || '／' || profile || '／' || account_status || '／' || to_char(lock_date,'HH24:MI:SS') as account_password_status from dba_users;

-- デフォルトのプロファイルのパスワード有効期限を無期限に
--  ※これはなくてもOKだが、毎回定期的に設定するの大変なので
--    （セキュリティ的には微妙ですが）
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;

-- エラーでログインできないユーザのパスワードを再設定
ALTER USER system IDENTIFIED BY manager;

-- ロックされているアカウントのロックを解除
ALTER USER system ACCOUNT UNLOCK;

-- これで以下がOKとなる
> sqlplus system/manager@XE

```

## 参考サイト

◆ORA-28001:パスワードが期限切れです
　https://www.dbsheetclient.jp/blog/?p=716
　　※対応することは、ここに書いてあることを実施

◆Oracle 19cのユーザーのパスワードの有効期限を無期限に変更する手順
　https://souiunogaii.hatenablog.com/entry/Oracle-PasswordLifeTime

◆アカウントステータスの遷移と対処方法のまとめ
　https://cosol.jp/knowledge/knowledge_post/ob0004_account_status/

◆ユーザーアカウント状態とロックされた日付を確認
　https://qiita.com/AtsushiTamashiro@github/items/c6b0aeab2aa89ff2f328
　　※今回は「LOCKED(TIMED)：ログイン失敗再試行回数上限オーバーによるロック」だった

◆Oracle 11g でパスワードの大文字・小文字を区別しないようにする
　https://www.projectgroup.info/tips/Oracle/Oracle_000014.html
　　※「Oracle Database では 11g 以降、パスワードの大文字と小文字を区別するのが標準になりました。」とのこと。これにも気をつけないと...はまったので。

◆Oracle Database 12c 以降のパスワード管理で気をつけるべき事例
　http://www.intellilink.co.jp/article/column/ora-report20180925.html
　　※下記条件が一致するとORA-01017発生とのこと
　　　・初期化パラメータ : SEC_CASE_SENSITIVE_LOGON = false
　　　・sqlnet.ora に設定するパラメータ : SQLNET.ALLOWED_LOGON_VERSION_SERVER = 12
Jupyter notebook 上で Rを使えるようにする

Jupyter notebook 上でRを使えるように環境設定を行うための備忘録
#環境
macOS Catelina

# Rをインストール
この [R for macOS](https://cran.r-project.org/bin/macosx/)からページ左側にあるR-3.6.3.pkg(本記事執筆時の最新版）を押してRをインストール

#Jupyter notebook 上でRを使えるようにする

以下をターミナル上で

```:ターミナル
R
```

を入力しRのインタプリタを起動．
以下を入力し必要なパッケージをダウンロードする


```:R
> install.packages(c('repr', 'IRdisplay', 'evaluate', 'crayon', 'pbdZMQ', 'devtools', 'uuid', 'digest'))
> install.packages('IRkernel')
> IRkernel::installspec()
```

ダウンロード終了後

```:R
> quit()
```

でRのインタプリタを終了．
ターミナルからjupyter notebookを開く,

```:ターミナル
jupyter notebook
```

するとjupyter notebookのNewからRを使えるようになる．
<img width="229" alt="スクリーンショット 2020-04-09 22.36.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319390/2df58d23-bed9-da67-a059-136a74ee3332.png">
Editor実行はできるが、Android ビルドしようとすると Gradle Error が出たので解消した

Unity with Oculus Integraiton で Editor実行は問題ないので、apk にビルドしようとすると Gradle Error が出る問題に遭遇したので、その解決？方法。（？が付いているのは後述）

# 前提
名前                | バージョン
-------------------|-------------
Unity              | 2019.3.0f6
Oculus Integration | 13.0.0

# エラーの内容
<img width="436" alt="スクリーンショット 2020-04-09 21.57.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/f357dd49-3850-a448-d8b0-e9e50f24a0d7.png">

```
Gradle Error: Resource Not Found
Resouce 'xml/newtork_sec_config' not found in AndroidManifest.xml:52.
(See the console for details)
```

# 直し方
`Oculus` フォルダを、Assets フォルダ配下に戻した。
（リファクタリングのために、インポートしたアセットをあるフォルダ配下（Assets/hogehoge/）にまとめていたので、Assets配下に戻した。）

## 後述の内容
* 戻しただけで、フォルダの移動はまだ実現していなので、？ということである。
* 時間ができたら調べて直したいとは思っています。（時間ができたら・・・）
    * コメントをもらったので追記
        * OVRManagerのEnable NSC Configurationをチェックすると、ビルド時に `/Assets/Oculus/VR/Editor/OVRGradleGeneration.cs` が `/Assets/Oculus/VR/Editor/network_sec_config.xml` を必要なフォルダにコピーして `AndroidManifest.xml` にもパスが追加されるとのこと。  
        * で、Oculus Integration 12.0.0 までは、コピー元は固定パスなので、Oculusフォルダを別フォルダに移動すると、network_sec_config.xmlをコピーできないのでファイルが見付からずにエラーが出るとのこと
        * 13.0.0 から相対パスでコピーするようになったので、Oculusフォルダを別フォルダに移動してもエラーは出なくなりそうなのだが、ここは未調査の状態です m(_ _)m

# 補足
## xml/network_sec_config とは？
network_sec_config は Oculus/VR/Editor/network_sec_config.xml にある。

## 無駄だったこと
* Resource フォルダ配下を色々見てみたが特に無し
* Plugin/Android/AndroidManufest.xml 見てみたが特に無し
VSCodeの拡張機能Remote-WSLによってWSL上での開発を快適にする

#はじめに
先日VS Codeを立ち上げたところ、右下に以下のようなメッセージが出ていました。
![suisho-WSL.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610292/843980ae-7d7d-3a61-4c58-246ec5c3f6a0.png)

Windows側のVS CodeからWSL上のファイルにアクセスできる拡張機能であるらしく、大変便利そうだったのでインストールすることにしました。
「install」ボタンによってインストールした後、左下に緑色の「＞＜」のような形のボタンが出るようになるので、これをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610292/64374409-9825-5ae2-7cc1-f8baffb81380.png)
それによって以下のようなメニューが現れるので、「Remote-WSL:New Window」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610292/a888bb8d-b7ab-6947-6633-ea7d7be57768.png)
すると新しいウィンドウが立ち上がり、そこからWSL上のフォルダを開けるようになりました。Windows側からバグを発生させずにWSL上の開発ができるのはお手軽でとても便利ですね！
2020/04現在　僕が思う最適なmac + python + tensorflow 環境構築

# 環境
macOS Catalina
python 3.7.5
pyenv 1.2.18
tensorflow 2.1.0

※本記事は、macにpython3とtensorflowを入れるだけの記事です。
 editorを使った環境構築の話などは一切含まないのでご了承ください:clap:

# python環境　全然上手くいかない
もう嫌というほど、作っては壊しを繰り返しました。
そこで得た知見をシェアさせていただきます。

# まずリセットしましょう
とにかくGitから取ってくる方法やダウンロードで展開する方法、brewなど色々な方法がインターネットに転がっていますから混乱します。
とりあえず落ち着いて酒飲もや。ではなく、uninstallしましょう。

僕は、こちらの記事が参考になりました。:clap:
https://kandai.hatenadiary.jp/entry/2018/07/16/105940

すべてリセットしたら、以下の考えで構築します。
- 面倒くさいですが、環境ごとに `pip install ●●` する
- 要らなくなったら壊しやすい
- tensorflowを入れれること　←　僕のゴールでした。

以下、3Stepで終わらせましょう。

# Step1: pyenvをインストール ~ python3.7.5をインストール
大事なところです。
**なぜpython3.7.5** か？
僕はこの記事に出会うまでずっとpython3.8.0を使用していました。
https://github.com/tensorflow/tensorflow/issues/37205

**tensorflowはpython3.7までしか対応していない** とのことです。
それを踏まえてinstallしていきましょう。

```
% brew install pyenv

% vi ~/.zshrc # 環境変数
# 以下を入力
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
if command -v pyenv 1>/dev/null 2>&1; then
  eval "$(pyenv init -)"
fi

% zsh -l # 環境変数を更新

% pyenv install 3.7.5 # python3をインストール
% pyenv global 3.7.5 # python3をグローバルに設定

% python --version
Python 3.7.5
```

# Step2: projectディレクトリ作成〜仮想環境構築
仮想環境構築はpython同梱のvenvを使用します。
デメリットとして、いちいち `pip install ●●` をしないと空っぽということなんですが、
メリットとして要らなくなったら `deactivate` コマンドを叩いてディレクトリごとポイッでOKです。

```
% mkdir project # 作業ディレクトを作成

% python3.7 -m venv project # 作業ディレクトに仮想環境を構築

% cd project
% source ./bin/activate # 仮想環境開始

(project)% python --version
Python 3.7.5

(project)% deactivate # 仮想環境終了
%
```

# Step3: Tensorflowをインストール

```
% source ./bin/activate # 仮想環境開始

(project)% pip install --upgrade pip 
(project)% pip install tensorflow
```

以上です。
参考になりましたら幸いです。