OmniAICreator/Qiita-1.07M huggingface dataset:
SeleniumをChromeで開いた話


## SeleniumをChromeで開いた話


```powershell:terminal
## Anacondaを使っているので、こちらでseleniumをインストール
python3.8 -m pip install selenium
```

```powershell:terminal
## Pythonで画像処理を行う場合に用いられるライブラリをインストール
pip3.8 install pillow
```

```powershell:jupyterlab
## jupyter labを起動
jupyter lab

## jupyter lab上で、seleniumがインストールされているかチェック
from selenium import webdriver

## Chromeブラウザを開く
browser = webdriver.Chrome()
```

```powershell:terminal
## 「FileNotFoundError...」と怒られたのでChromeドライバーをインストール
brew install chormedriver
```


```powershell:jupyterlab
## Chromeブラウザを開か再トライ
browser = webdriver.Chrome()

## また怒られた
#「"chromedriver"は開発元を検証できないため開けません。」
# @apukasukabianさんのHELPを行った。
# https://qiita.com/apukasukabian/items/77832dd42e85ab7aa568

## Chromeを再起動した後、Chromeブラウザを開くか再々トライ
browser = webdriver.Chrome()

#「Chromeは自動テスト ソフトウェアによって制御されています」っていうChromeブラウザ開いた〜


## とりま、jupyter lab上で、pillowライブラリがインストールされているかチェック
from PIL import Image

#(大文字・小文字に気をつけて)
```
Cent OSのバージョン確認

下記のコマンドでバージョンを確認できます。

```
[root@sandbox ~]# cat /etc/centos-release
CentOS Linux release 7.8.2003 (Core)

[root@sandbox ~]# bash --version
GNU bash, バージョン 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
```
PHPの関数が使用前に定義しなくても呼び出せるのはなぜか

[PHPの関数は使用前に定義しなくても呼び出せる](https://qiita.com/taro-hida/items/f3068e4310a9cf9cc5e7)という記事を書いてる途中にふとなぜそのような仕様になるのか疑問に思い，調べてみました．

**注意：この記事は筆者が途中で力尽きたため，しっかりした根拠のある結論が出ていません．ご了承の上お読みください**

調べた過程やリンク先について共有します，こちらについては役に立てるかと思います．

# 疑問

PHPはインタプリタ言語のはずなのに，定義前の関数を呼び出しても正常に呼び出せるのはなぜ？

# 調べてわかったこと

## Zend OpCodesっていうのに一回コンパイルされるらしい

「how it works」をつけて調べてみました．以下の説明が非常にわかりやすかったです．

https://www.quora.com/How-does-the-PHP-interpreter-work/answer/Gaurav-Kumar-956?ch=2&srid=uBQqa0 

あくまで推測ですが，この「Zend OpCodes」という中間バイナリコードの生成時に，関数は事前に読み込まれ定義されているように見えます．
もしかしたら，定義行のアドレスはここですよって参照が貼られているだけかもしれませんが．

# 関数は中間コード前処理の際になんかされるらしい

Q&Aサイトの記述ですが，それっぽい記載はありました．

<blockquote>
The PHP compiler's job is to parse your PHP code and convert it into a form suitable for the runtime engine. Here are some of its functions:<br>

<ul>
<li>Removes comments</li>
<li>Resolves variables, functions/methods and inserts relevant data into a symbol table</li>
<li>Constructs an abstract syntax tree of your program</li>
<li>Writes out the bytecode</li>
</ul>
...(中略)...<br>

The symbol table is used to store the values of variables and provide the bytecode addresses for functions and methods. Otherwise, functions would have to be defined before use, which is clearly not the case.<br>
</blockquote>
https://www.quora.com/How-is-PHP-interpreted/answer/Ian-Atkin?ch=2&srid=uBQqa0 

この説明によると，

- シンボルテーブルに関数のバイトコードのアドレスが格納される
- そのため，定義前に関数を呼び出そうとしても問題はない

と理解できました．

まだこの情報が間違っている可能性がアリアリ[^1]なのですが，ちょっとこの辺りで終わろうと思います．
[^1]: 古い資料とかも参照したので，5系と7系で挙動が違ったりもしそうです

以下の情報が更に詳しそうですが，もはや理解できませんでしたw
https://blog.krakjoe.ninja/2016/03/hacking-php-7.html

# 参考資料他
Zend Engineについての説明：https://phpbuilder.com/php-and-zend-engine-internals/
ZendAPIについてのマニュアル説明（古い） - https://www.php.net/manual/en/internals2.ze1.zendapi.php
PHP組み込み関数の登録方法 - http://www.phpinternalsbook.com/php7/extensions_design/php_functions.html
OPCODES「DECLARE_FUNCTION」：https://www.php.net/manual/en/internals2.opcodes.declare-function.php#internals2.opcodes.declare-function
Sebastian Bergmann 氏の資料：https://www.scribd.com/document/18171982/PHP-Compiler-Internals
Rails Tutorial 拡張機能の返信機能を作ってみた(その1)

##Rails Tutorialの第14章にある拡張機能について
Rails Tutorialをの第14章には、Tutorialを完了した人向けに、自分で機能を拡張するお題がいくつかあります。
最初のお題である、返信機能に挑戦しています。まだ作成途中ですが、できたところまで投稿します。

###作る要件を確認し、仕様を作る

要件は以下のように書かれています。

>Twitterには、マイクロポスト入力中に@記号に続けてユーザーのログイン名を入力するとそのユーザーに返信できる機能があります。このポストは、宛先のユーザーのフィードと、自分をフォローしているユーザーにのみ表示されます。この返信機能の簡単なバージョンを実装してみましょう。具体的には、@replyは受信者のフィードと送信者のフィードにのみ表示されるようにします。

仕様のヒントも書かれています。

>これを実装するには、micropostsテーブルのin_reply_toカラムと、追加のincluding_repliesスコープをMicropostモデルに追加する必要があると思います。

要件を具体的にブレークダウンします。

・@replyが表示されるのは、以下の3者
replyの受信者
replyの送信者（自分）
replyの送信者のフォロワー

上記以外のユーザーには表示されない

・マイクロポストの先頭に「@reply ユーザーのログイン名」を入力したときに、このポストをreplyと判定

###仕様を深堀する、例示されているtwitterを参考にするため調べる

Tutorialの「6.2.5 メールアドレスの一意性」を読み返したところ、大文字と小文字の区分けをするか書いてありました。
ユーザー名に大文字と小文字で区分けをすべきなのか、TaroとTAROを違うものとするかどうかです。
twitterはどうなのかネットで調べます。

内部では同じだが、入力時に区分けはするという記事が多かったです。ズバリ書いている記事が見つからなかったです。
メアドと同じ仕様で作ることにします。

この大文字小文字の機能は、最初からではなく後で追加することにしました。後から追加するのが簡単そうに見えたためです。

###どういう機能を作るか、以前に追加した機能に似ているので読み返す

以前に追加した機能に似ているので、どの機能と似ているか読み返します。

13章のマイクロポストの機能に似ている
6.7章のユーザー登録の機能に似ている
6.2.5　一意性を検証する　
　　メールアドレスの一意性

その結果をもとに、以下のような機能を考えました。

・replyで表示する／しないの判定ができる機能をmodelに追加
　このpostはreplyかどうか
・@replyの入力を判別する機能をviewまたはcontrollerに追加
・ユーザー名がユニークになるように、modelとviewに追加

最後の「ユーザー名がユニーク」の機能は、最初からではなく後で追加することにしました。まずはユニークなテストデータだけで動くものを作ってみて、後からユニークにする制約の機能を付け加えればよいと考えたためです。

###機能を詳しく設計する　モデル
14章の14.1.1を再度読みます。id間のrelatoinのことでした。

>micropostsテーブルのin_reply_toカラムと、追加のincluding_repliesスコープをMicropostモデルに追加する必要があると思います。

をヒントに、modelをどう変更するか考えます。

microposts

|列名        |属性          |
|:---------:|:----------:|
| id         | integer     |
| content    | text        |
| user_id    | integer     |
| in_reply_to | integer     |
|created_at   | datetime   |
|updated_at   | datetime   |


in_reply_to  の列を追加するとして、型は何になるか？どのユーザーか特定するのだから、idと同じでintegerと考えました。

###機能を詳しく設計する　メソッド
micropostのメソッドを追加するか、既存のメソッドを変更するか。
表13.1を参考にします。
user.micrposts 	　	Userのマイクロポストの集合をかえす	既存の変更
user.microposts.build(arg) 	userに紐付いた新しいMicropostオブジェクトを返す	既存の変更
user.microposts.find_by(id: 1) 	userに紐付いていて、idが1であるマイクロポストを検索する	既存の変更

replyのメソッドを追加するか、考えます。
user.microposts.create(arg,reply:user2) user2へのreplyのマイクロポストを作成する
既存のcreateメソッドを変更することにします。

###機能を詳しく設計する　ビュー
画面は主に2つ修正、replyを入力するところと、replyを表示するところです。

入力項目は増やす必要がない、なぜなら、contentの先頭に@replyと記入するからと考えました。

出力でreply専用の画面が必要か？　
Twitterを調べます。replyは元Tweetをクリックすると別画面に移ってreplyの一覧を表示しています。replyの親子のTweetを一覧で表示しています。

ちょっと複雑なので今回はそこまではやらず、元Tweetと同じ画面に表示することにします。

画面のイメージは、モックを作るのは面倒なのでテキストだけです。
comment box　:　@reply michael Cum aspermatur ..

Feedの表示イメージ
@reply michael Cum aspermatur ..

###機能を詳しく設計する　ビューの入力エラーチェック

user_idが見つからないときは、親切な設計なら入力時にエラーを表示します。createするときにチェックするはずなのでエラーを表示することにします。

postをした後で、user_idが削除されたケースはどうするか？
このmicropostを削除するべきか。もういない人にreplyしたmicropostだけが残っているほうがよいと考え、micropostは削除しないと考えます。


###所要時間
9/27から10/1までの3.0時間です。
PHPの関数は使用前に定義しなくても呼び出せる

有名な話だと思いますが，自分用まとめです．途中で気になって内部仕様について深堀りもしましたが途中で力尽きています．ご了承ください．

# 関数の定義より先に，その関数を呼び出すコードを記述することができる

以下のコードはエラーなく動作します．

```
<?php
 
 func();
 
 function func() {
     echo 'OK';
 }
```

https://3v4l.org/XWgHF

# 関数1の内部で定義した関数2は，関数1を呼び出した後でないと実行できない

以下コードはエラーなく動作します．

```
<?php
 
 func1();
 
 function func1() {
     echo 'func1';
     function func2() {
         echo 'func2';
     }
 }
```

https://3v4l.org/kiG23

しかし，以下は動作しません．

```
<?php
 
 func2();
 
 function func1() {
     echo 'func1';
     function func2() {
         echo 'func2';
     }
 }
```

https://3v4l.org/66faT

以下のように，`func1()` のあとに`func2()` を呼び出すようにするとエラーなく動作しますが，

```
<?php
 
 func1();
 func2();
 
 function func1() {
     echo 'func1';
     function func2() {
         echo 'func2';
     }
 }
```
https://3v4l.org/vPKBS

この順番を逆にすると動作しません．

```
<?php
 

```
https://3v4l.org/bpXPp

余談ですが，関数の内部だけでなく，`if` 文の内部で宣言された関数も同様の挙動になるみたいです．
定義前に呼び出そうとするとエラーが出ます．

```
<?php
 
 func1();
 
 if (true) {
    function func1() {
        echo 'func1';
    }
 }
```

定義後であれば大丈夫です．

```
<?php
 
if (true) {
   function func1() {
       echo 'func1';
   }
}
 
func1();
```
https://3v4l.org/c1KN9

定義後であっても，`if` 式の評価の結果関数定義部分が実行されないと同様に呼び出すことはできません．
以下のコードはエラーが発生します．

```
<?php
 
if (false) {
   function func1() {
       echo 'func1';
   }
}
 
func1();
```
https://3v4l.org/5MmRM

マニュアルでは以下の部分で記載されています．

> PHP では、関数は参照される前に定義されている必要はありません。 ただし以下の二つの例のように、条件付きで関数が 定義されるような場合を除きます。
https://www.php.net/manual/ja/functions.user-defined.php

# PHPはインタプリタ言語

**注意：この先，筆者が力尽きていますのでしっかりとした結論が出ていません**

ん？

ここでちょっと思いました．どうも，PHPインタプリタくんはファイルを実行した際，`function`から始まる行について先に読み込んで，なにか処理をしているようです．

インタプリタ言語って上から一行ずつ読み込んでコンパイルして逐次実行していくイメージです．どういう順序で処理してるんでしょうか．

この疑問については別記事に分割しました．ただ，根拠のある結論は出ていませんので，ご了承ください．
> [PHPの関数が定義前に呼び出せるのはなぜか](https://qiita.com/taro-hida/items/ebb4cd5679c1967f4689)
Swiftでlog(1+x)の近似値を求める

## なぜSwiftなの？
Swiftは環境構築などする必要がなく,MacかiPadがあれば[Playgrounds](https://apps.apple.com/jp/app/swift-playgrounds/id1496833156?mt=12)をインストールするだけで使うことができる。
また,Playgroundsには**ステップ実行**や**ゆっくり実行**という機能があり,for文やwhile分をステップごとに実行し,実行されている時の値の変化を確認することもできる。
さらに,**ビューア機能**を使えば変数の変化の様子を勝手にグラフ表示してくれる。
![2020-10-14 11.16のイメージ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/3f40f66a-ab98-7ef8-49ec-8bec9a137f2d.jpeg)

## log(x+1)のマクローリン展開

$\log(1+x)$のマクローリン展開は



$$
\log(1+x) = x-\frac{x^2}{2}+\frac{x^3}{3}-\frac{x^4}{4}+⋯+\frac{(-1)^{n-1}x^n}{n}+⋯
$$




と表されるのであった。この記事では$\log (1+x)$の近似値をプログラミングを使って求めていく。(言語はSwift)ipadでも大丈夫。

## 1.変数を用意する

マクローリン展開は何回でも微分できる関数$f(x)$を$x$の冪乗関数の級数の展開式の和で近似させるものであるのであった。この記事では$\log (x+1)$の値を`sum`として,`sum`にだんだん値を加えていく。

```swift
var sum = 0
print(sum)    //0
sum += 1
print(sum)    //1
```

また,近似する$x$を入れる定数も用意しなければならない。

```swift
var sum = 0
let x = 1
```

さらに,項として更新され続ける変数を用意する。

```swift
var item = x
```

第一項は定数と同じになるので,`x`を入れておく。

最終的なコードは以下のようになる。

```swift
var sum = 0.0  //int型とdouble型は足算できないので,0.0と書きdouble型にする。
let x = 1.0
var item = x
```

## 2.x=1として第二項までコーディングする

コーディングをする上で小さな値から始めることや具体的な値で試行錯誤することは重要だと思う。(個人の見解)。この記事でもその理念に則り$x=1$として第二項まで,つまり


$$
\log (1+x)=x-\frac{x^2}{2}
$$


までコーディングする。

```swift
var sum = 0.0  //int型とdouble型は足算できないので,0.0と書きdouble型にする。
let x = 1.0
var item = x

sum += 1.0
sum += -(x*x)/Double(2*1)
```

最後に真値と比較する`print`文を加える。

```swift
import Foundation
var sum = 0.0  //int型とdouble型は足算できないので,0.0と書きdouble型にする。
let x = 1.0
var item = x

sum += 1.0
sum += -(x*x)/Double(2*1)
print(sum)//近似値0.5
print(log(2.0))//真値0.6931471805599453
```

## 3.一般化しやすいように工夫する

さっきは第二項を$-\frac{x^2}{2}$としたがこれでは項数が増えるたびに$x$を増やしたり分母をいじったりしなければならない。項数が増えても短くコーディングすることができるように工夫を加える。

```swift
import Foundation
var sum = 0.0  //int型とdouble型は足算できないので,0.0と書きdouble型にする。
var item = 1.0
let x = 1.0
sum += item

for i in 2 ..< 3{
    item *= -(x*Double(i-1))/Double(i)
    sum += item
}
print(sum)//近似値0.5
print(log(2.0))//真値0.6931471805599453
```

マクローリン展開された$\log (x+1)$を観察すると,項が大きくなるたび$x$と$1/n$がかけられているので,それをコードで表現する。

![計算-12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/671f16c2-240b-c7ac-a50d-d0375bd73940.jpeg)




for文を使っているが,1度しか実行されないため,sumの値は変わらない。

## 4.項数をふやす

一般化することによって項数を増やしても対応できる。

```swift
import Foundation
var sum = 0.0  //int型とdouble型は足算できないので,0.0と書きdouble型にする。
var item = 1.0
let x = 1.0
sum += item

for i in 2 ..< 10{
    item *= -(x*Double(i-1))/Double(i)
    sum += item
}
print(sum)//近似値0.7456349206349205
print(log(2.0))//真値0.6931471805599453
```

第９項まで加えても真値とだいぶ差がある。$sinx,cosx$は第6項でほとんど同じだったので,$\log (x+1)$は$sin$や$cos$に比べ,収束するのが遅いことがわかる。
RaspberryPiをGoogleCloudPrint対応プリンタサーバにする(cups)

# これはなに

使っているプリンタの、Google Cloud Print 機能がいま一つ不安定。ときどき使えなくなる。
不都合なので、RaspberryPIをプリントサーバにし、Google Cloud Print に接続した。
安定して稼働するようになった。

##参考
以下を参考にさせていただきました。ありがとうございます。
[はじめての自宅サーバ構築 - Fedora/CentOS -]
(http://kajuhome.com/cups.shtml)
ともの技術メモ [Google Cloud Print Connectorを設定](https://tomono.tokyo/2019/03/25/7547/)

# 手順

##cupsのインストール
cupsをインストールし、プリンタサーバにする。

```
sudo apt install cups
```

設定ファイル/etc/cups/cupsd.confの変更。変更箇所は５か所です。

```
sudo nano /etc/cups/cupsd.conf
１か所目
# Only listen for connections from the local machine.
# Listen localhost:631
# Port631 を追記。ポート631をlocalhost以外に開放
Port 631
Listen 631　
Listen /run/cups/cups.sock

２～５か所目
# Restrict access to the server...
<Location />
  Order allow,deny
# プリンタへのアクセスを開放
  Allow @Local
</Location>

# Restrict access to the admin pages...
<Location /admin>
  Order allow,deny
# 管理ページへのアクセスを開放
  Allow @Local
</Location>

# Restrict access to configuration files...
<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
# 設定ファイルへのアクセスを開放
  Allow @Local

</Location>
# Restrict access to log files...
<Location /admin/log>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
# ログファイルへのアクセスを開放
  Allow @Local
</Location>
```

cupsを再起動する。

```
sudo systemctl restart cups.service
```

操作するユーザがlpadminグループに所属していなければ、追加します。

```
sudo usermod -aG lpadmin ユーザ名
```


webページ http://192.168.0.**:631 で管理ページを開き、ユーザ名でログインします。
GUI 管理画面で、プリンタを追加します。


# google-cloud-print-connectorのインストール
aptコマンドでインストールします。

```
sudo apt install google-cloud-print-connector
```
gcpの初期化をします。


その後は、参考の
ともの技術メモ [Google Cloud Print Connectorを設定](https://tomono.tokyo/2019/03/25/7547/)
さんの手順と寸分変わりませんので、そちらをご参照ください。正確な最新情報をありがとうございます。

```Bash:install_gcp_service.sh
#!/bin/bash

sudo useradd -M -s /usr/sbin/nologin cloud-print-connector
sudo mkdir /opt/cloud-print-connector
sudo ln -s /usr/bin/gcp-cups-connector /opt/cloud-print-connector/gcp-cups-connector
sudo cp gcp-cups-connector.config.json /opt/cloud-print-connector/.
sudo chown cloud-print-connector.cloud-print-connector /opt/cloud-print-connector/gcp-cups-connector.config.json 
ls -la /opt/cloud-print-connector/gcp-cups-connector.config.json
wget https://raw.githubusercontent.com/google/cloud-print-connector/master/systemd/cloud-print-connector.service
sleep 10
install -o root -m 0664 cloud-print-connector.service /etc/systemd/system
sudo systemctl enable cloud-print-connector.service
sudo systemctl start cloud-print-connector.service
sudo systemctl status cloud-print-connector.service
```
Unity上の3Dオブジェクトをfbxフォーマットでエクスポートする

- `ウインドウ -> Package manager`で`FBX Exporter`をインストール。
- インストール後は、オブジェクトを選択して、右クリックメニューに追加された`Export to FBX`でエクスポートできます。
【Laravel】get〜Attributeメソッド

##はじめに
今回はLaravelのget〜Attributeメソッドを利用して、欲しい値を加工する方法をまとめたいと思います。

##アクセサについて
>アクセサを定義するには、アクセスしたいカラム名が「studlyケース（Upper Camel Case）」でFooの場合、getFooAttributeメソッドをモデルに作成します。以下の例では、first_name属性のアクセサを定義しています。first_name属性の値にアクセスが起きると、Eloquentは自動的にこのアクセサを呼び出します。

参考：[Eloquent：ミューテタ 8.x Laravel](https://readouble.com/laravel/8.x/ja/eloquent-mutators.html)

##get〜Attributeメソッドの実装例

```php:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザーの氏名を取得
     *
     * @param  string  $value
     * @return string
     */
    public function getFullNameAttribute($value)
    {
        return "{$this->first_name} {$this->last_name}";
    }
}

```

モデルにこのように定義するとこの値を使用したいコントローラー層やサービス層などで、例えば`$this->full_name`のように実装すると値を取得することができます。

##おわりに
いかがでしたでしょうか。
get〜Attributeメソッドはとても便利なので是非活用してみてください。
マトリクスのパターンを網羅するロジックの書き方

## この記事を書いた理由
よくテスト実施の際に以下のようなパターンを網羅するための表を書くことがあると思う。

|Aデータ|Bデータ|
|---|---|
|○|○|
|○|×|
|×|○|
|×|×|

このパターン網羅がコーディングテストをする際に必要になることがある。
これをプログラミングで書くまでが結構大変だったのでメモしておく。

## プログラム

以下のように書くとパターン表がざっくり取得できる。

```php
<?php
$num = 4; // true/falseの4つのデータがある時
for ($i = 0; $i < (1 << $num); $i++) {
  for ($j = $num - 1; $j >= 0; $j--) {
    if ($i & (1 << $j)) {
      echo '×';
    } else {
      echo '○';
    }
  }
  echo PHP_EOL;
}
```
「<<」や「&」はシフト演算子である。
2進数で値をシフトすることによりパターン網羅の処理が格段に簡単になる。

上記の出力内容は以下のようになる。

```出力内容
○○○○
○○○×
○○×○
○○××
○×○○
○×○×
○××○
○×××
×○○○
×○○×
×○×○
×○××
××○○
××○×
×××○
××××
```

テーブルっぽく書きたいなら多重配列に入れて、テーブルに起こしてあげるといい

```php
<?php
echo array2table(create_pattern(4)); // true/falseの4つのデータがある時

function create_pattern($num){
  $board = [];
  for ($i = 0; $i < (1 << $num); $i++) {
    for ($j = $num - 1; $j >= 0; $j--) {
      if ($i & (1 << $j)) {
        $board[$i][] = '×';
      } else {
        $board[$i][] = '○';
      }
    }
  }
  return $board;
}

// 参考：https://www.pahoo.org/e-soul/webtech/php02/php02-46-01.shtm#array2table
function array2table($arr) {
  if (!is_array($arr)) return false;
  $keys1 = array_keys($arr); //1次元目のキー取得
  $keys2 = array_keys($arr[$keys1[0]]); //2時限目のキー取得
  if (is_array($arr[$keys1[0]][$keys2[0]])) return false; //3次元以上

  $n = count($arr[$keys1[0]]); //要素の数
  $html = "<table class=\"array\">\n";

  //要素名
  $html .= "<tr><th>Key</th>";
  for ($i = 0; $i < $n; $i++) {
    $html .= "<th>{$keys2[$i]}</th>";
  }
  $html .= "</tr>\n";

  //配列本体
  foreach ($arr as $key=>$arr1) {
    $html .= "<tr><th>{$key}</th>";
    for ($i = 0; $i < $n; $i++) {
      $html .= "<td>{$arr1[$keys2[$i]]}</td>";
    }
  }
  $html .= "</tr>\n</table>\n";

  return $html;
}
```

htmlで出力すると以下のような感じで表示される。

![aaa_html.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153118/a63bcb5d-1d24-42f0-2a76-6dcf2ec5da4b.png)

上記のパターン網羅プログラム、コーディングテスト等で必要になる機会が多い印象がある。
便利なのでぜひ活用してみてほしいです。

# 参考
- [PHPで2次元配列をTABLE表示](https://www.pahoo.org/e-soul/webtech/php02/php02-46-01.shtm#array2table)
- [ビット演算子](https://www.php.net/manual/ja/language.operators.bitwise.php)
- [コインの裏表のパターンを表示させたいです](https://dixq.net/forum/viewtopic.php?t=18451)
【C#】Debug.WriteLineとConsole.WriteLineの速度を比べてみた

#注意
多少雑なところがあるかもしれませんがご了承ください
Debug環境での話になります
Releaseでは話は変わります
#Debug.WriteLineとConsole.WriteLineとは
###Debug.WriteLine
デバッグについての情報を Listeners コレクションのトレース リスナーに書き込むメソッドです
VisualStudioでDebugに設定したときに出力の欄にLogを出したりできます
###Console.WriteLine
説明するまでもないと思いますが
コンソールにデータを出力するメソッドです

#遅いと思ったら
Debug.WriteLineは一般に遅いといわれています
あまり使いすぎるとかなり遅くなってしまいます


#検証
どのくらい遅いかをConsole.WriteLineと比べようと思いました

###検証方法
計測はそれぞれ10000回を10回繰り返した時間を計測
10000回の平均値を計算し、さらにそこから一回の速度を計算します
プログラム

```csharp
using System;
using System.Diagnostics;
using System.Linq;

namespace log_speed
{
    class Program
    {
        static void Main(string[] args)
        {
            long[] TempTime=new long[10];
            double AvDebug,AvConsole;
            
            Stopwatch sw = new Stopwatch();
            for (int i = 0; i < 10; i++)
            {
                sw.Start();
                for (int j = 1; j <= 10000; j++)
                {
                    Debug.WriteLine(j + "回目");
                }
                sw.Stop();
                TempTime[i] = sw.ElapsedMilliseconds;
                sw.Reset();
            }
            AvDebug =TempTime.Average();
            for (int i = 0; i < 10; i++)
            {
                sw.Start();
                for (int j = 1; j <= 10000; j++)
                {
                    Console.WriteLine(j + "回目");
                }
                sw.Stop();
                TempTime[i] = sw.ElapsedMilliseconds;
                sw.Reset();
            }
            AvConsole = TempTime.Average();
            Console.WriteLine("Debug10000回の平均速度:" + AvDebug+ " Debug1回の平均速度:" + AvDebug/10000 + "\nConsole10000回の平均速度:" + AvConsole+ " Console1回の平均速度:" + AvConsole/10000);
            Console.ReadKey();
        }
    }
}

```
変なところがあればご連絡ください


#実行
###実行環境

|種類|メーカー|パーツ名|個数|
|:--------:|:------:|:-------------:|:-------:|
|CPU|AMD|Ryzen 5 1600|1|
|マザーボード|ASUS|PRIME B450M-A|1|
|GPU|nVIDIA|GTX960|1|
|RAM|G.Skill|F4-2400C15-4GNT|4|
|SSD|Samsung|860 EVO M.2 500GB|1|

今回の検証ではボトルネックとなる部分は少ないと思います

IDEは**Microsoft Visual Studio Community 2019 Version 16.7.6**です
対象フレームワークは**.NET Framework 4.7.2**です

###実行結果
実行結果はこのようになりました
![結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606743/bb3f1391-3d5b-8000-f327-cd5a3f9fc9af.png)

10000回の平均速度は10000回を10回繰り返したうちの10000回にかかる時間です
約3.4倍遅いようです

#まとめと感想

今回比較してみて思ったことはDebug.WriteLineもそこまで遅くないということです、ただ3.4倍も速度が違うので
極力Console.WriteLineを使うほうがいいと思います
パラボリック解析


#### この記事の対象者
- 個人投資家
- パラボリック解析は何をやっているか知りたい人
- パラボリック解析を自分でcodingしたい人
- パラボリック解析をトレードに使いたい人


#1 この記事は何？

株式投資チャート分析の1つにパラボリック解析というものがあります。パラボリック解析が何かは[こちらの記事](https://www.bonjin-biz.xyz/parabolic-sar-calculation/#6_SAR2)を読んでいただければと思いますが、現在上昇トレンドか、下降トレンドか、トレンドの変換点が一目でわかるテクニカル分析です。スマホのトレードアプリでは、パラボリック解析は実装されていないことも多く、また自身のポートフォリオの中でどの銘柄がトレンド転換をしたかを銘柄ごとにパラボリック解析結果を表示させると手間がかかります。（例えばマネックス証券では、パラボリック解析結果をチャート図にプロットする機能はありますが、1銘柄ごとに表示させると大変な時間と作業量になってしまいます。）トレンドの転換が直近に起きた銘柄のみをまずはスクリーニングし、スクリーニングした銘柄についてボリンジャーや一目均衡表なども用いて分析すると利確できる確率はあがりそうですね。

ここでこの記事では、下記の内容を解説したいと思います。

- パラボリック解析を行うアルゴリズムの解説
- ポートフォリオの中でどの銘柄がトレンド転換をしたかを一見できるWebアプリ

<b>★この記事で作成したアプリの動画です</b>
![techan-vue - Google Chrome 2020-10-18 09-34-48_7_2_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/810713ea-c878-313f-2eb9-77f77465c937.gif)


#2 何がやりたいの？

1. パラボリック解析を行うアルゴリズムの解説

パラボリック解析のアルゴリズムの解説を行います。またJupyterで作成したPythonコードを提供します。

2. トレンドが変換した銘柄を一見で探すアプリ

自分のポートフォリオの情報を管理するアプリを作って運用しております。[詳細こちらの記事をご覧ください。](https://qiita.com/NT1123/items/de1a4a898cfb56d34dbf)このアプリに、パラボリック解析の機能とトレンドの転換点が一見でわかる機能を追加で実装します。


#3 どのようにやるの？

## 3-1 パラボリック解析のアルゴリズム

[こちらの記事：matplotlibでパラボリックSARを描画](https://qiita.com/siruku6/items/76f4072c06a988dfe2cb)に記載されているコードを読み取り、流れ図に落としました(一部コードを追記しております)。
流れ図に落とした情報をまずはエクセルシートに移管しました。このエクセルシートに銘柄のOHLCデータを入力していただくと、パラボリック解析の計算をエクセルシート上でできるようになっています。さらに、jupyterにソースコードを移管しましたので、jupyterでも同じパラボリック解析を実行することができます。
以上のファイルは、GitHubに上げておりますので、触ってみてパラボリック解析の動作を理解してみると面白いと思います。


[こちらにファイルをアップロードしました。](https://github.com/fdfpy/parabolic)

パラボリック解析実行結果 at paraboric.ipynb
![137.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/0cd5ef38-5fe2-ff1a-ea37-fd26eb840aeb.jpeg)

#4 何ができたの?

パラボリック解析の機能を実装しました。自分のポートフォリオの中で、トレンドの転換が過去3日以内に発生した銘柄を抽出できるようになりました。1銘柄ごとにパラボリック解析結果を表示し、トレンドの変換がいつ起きたかを探すのは大変ですがこの機能のおかげで、トレンド変換が直近に発生した銘柄をすぐに抽出できるようになりました。

![142.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/39372adf-2774-d90e-169f-00569481edc4.jpeg)

下記はVOO(バンガードS&P500 ETF)のチャート図です。下降トレンドから上昇トレンドに転換して3日目にBuyし、SARとろうそく足が接近しそうになったので、Sellを行い利確できた例です。

![143.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/d78e6c95-5b08-3cad-41a7-c905bcd8749a.jpeg)
【StereoDepth】AnyNet : 2-stageだけじゃない3-stage,4-stage・・・ネットワーク

<h1>Anytime Stereo Image Depth Estimation on Mobile Devices</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/d14691c7-07d5-621f-6689-98aeb5c5f1b7.png)

Stereo Matchingの場合、左と右の画像からDisparityのerrorを計算出来るから、stageを重ねる毎に推定の精度がよくなっていく。

<h1>Multi Stage</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/5f51eaff-7765-ff9e-718c-baea8c418667.png)

[CRL](https://qiita.com/minh33/items/728653c9d69d9f768a8c)でもあるようにD1とResidual2(差分)を足す事でD2を得る事が出来る。


<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/3c347fa7-4313-59c8-c4e5-41a6cb905dcb.png)
Stageを重ねる毎にErrorは減っているが処理時間は伸びている。

処理時間でStage数を決めるのが良さそう。


<h1>参考文献</h1>
Anytime Stereo Image Depth Estimation on Mobile Devices
https://arxiv.org/pdf/1810.11408.pdf
プログラミングでよく出てくるポエム

備忘のためにメモ

> プログラミングの例でよく出てくるポエムみたいなのありませんでしたっけ？
> https://twitter.com/okuzawats/status/1317255423943045120

---

> https://ja.m.wikipedia.org/wiki/Lorem_ipsum かな？？
> https://twitter.com/rei_m/status/1317256308794380289

---

> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
> https://ja.m.wikipedia.org/wiki/Lorem_ipsum
【StereoDepth】CRL : stereo matchingでもtwo stageネットワーク

<h1>Cascade Residual Learning: A Two-stage Convolutional Neural Network for Stereo Matching</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/055f5c40-5f97-e306-23ec-19853bc3fcf8.png)

Stereo Matchingでもtwo-stage Networkの方がone-stageより精度が高い！

<h1>DipFullNet</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/92b5e100-dfab-7b8b-e0f8-0ff9b09f2b94.png)
DispFullNetは[FlowNetC](https://arxiv.org/pdf/1612.01925.pdf)をHalf ResolutionではなくFull Resolution(入力と同じ解像度)でoutputするように改良したモデル。
入力はLeft ImageとRight Imageで出力がFull ResolutionのDisparity Mapとなる。

<h1>DispResNet</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/b3a4478c-19b4-6ba4-e643-7c3feac8bb6b.png)
IR(右の画像)とd1を使いIL'(左の推定した画像)を作る。
IL(左の画像)とIL'を使いeL(推定のエラー)を計算する。
それらをDispReNetに入力し、d1をdownsampleしたものとr2(s)を足し合わせる事でd2(s)を推定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/0e548a61-4cd2-1693-dc0e-97f18f062307.png)

これをFull Resolutionまで計算し、最終結果d2(0)を出力する。



<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/3c8f4ea2-ee1b-f51a-af02-14f6b3994cfa.png)
two-stageのCRLは他のネットワークより詳細を学習出来ている。


<h1>参考文献</h1>
Cascade Residual Learning: A Two-stage Convolutional Neural Network for Stereo Matching
https://arxiv.org/pdf/1708.09204.pdf
Django Google Cloud Storageから画像やPDFを取得しTemplateに表示する


DjangoでGCSから取得したJPEGの画像や、PDFのファイルをtemplate側で表示する必要があったためその時学んだことを残します。

ここではすでにサービスアカウントの設定、認証キーの取得は完了しているものとします。
今回はbase64にエンコードした情報をtemplateに渡して表示させます。

# コード
```views.py
from google.cloud import storage
import base64
import os

def fetch_image():
    # views.pyまでの絶対パスを取得します。
    base = os.path.dirname(os.path.abspath(__file__))

    # 上記絶対パスから見た認証キーまでのパスを指定
    os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = os.path.join(base, '認証キー.json')

    client = storage.Client()
    bucket = client.get_bucket('バケット名')
    download_blob = bucket.get_blob('バケット名以降の取得対象ファイルまでのパス')
    return base64.b64encode(download_blob.download_as_string()).decode()

class Template(TemplateView):
    template_name = "template.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["image"] = fetch_image()
        return context
```

```template.html

<!-- JPEGの場合 -->
<img src="data:image/jpeg;base64,{{ image }}"  alt="image">

<!-- PDFの場合 -->
<iframe src="data:application/pdf;base64,{{ image }}" alt="image"></iframe>
```

# 参考
[画像やPDFをBase64エンコード（変換）してHTMLに埋め込んでサイトの表示速度を速くする](https://blanche-toile.com/tools/image-to-base64)

[GoogleCloudStorageでPythonからファイルをやりとりする方法](https://sleepless-se.net/2018/05/22/googlecloudstorage%E3%81%A7python%E3%81%8B%E3%82%89%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E3%82%84%E3%82%8A%E3%81%A8%E3%82%8A%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)
ロジックアナライザを試すその５：Wire.setClock()

# Wire.setClock()確認
指定した値どおり、I2Cのクロック(SCL)が出ているかをロジックアナライザで確認する。

## 用いたもの
ESP32搭載のM5Stackおよび光センサー（TLS2561搭載）。ロジックアナライザは[以前の記事](https://qiita.com/infinite1oop/items/508873f660812e52f324)参照。Arduino IDE利用。

## ソースコード

```c++
#include <Wire.h>
#include <Digital_Light_TSL2561.h>

void writeRegisterValue(int deviceAddress, int address, uint8_t val) {
    Wire.beginTransmission(deviceAddress);  // start transmission to device
    Wire.write(address);                    // send register address
    Wire.write(val);                        // send value to write
    Wire.endTransmission();                 // end transmission
}
uint8_t readRegisterValue(int deviceAddress, int address) {
    uint8_t value;
    Wire.beginTransmission(deviceAddress);
    Wire.write(address);                // register to read
    Wire.endTransmission();
    Wire.requestFrom(deviceAddress, 1); // read a byte
    while (!Wire.available());
    value = Wire.read();
    return value;
}

void setup() {
    Wire.begin();
    Wire.setClock(20000);
    Serial.begin(9600);
    TSL2561.init();
}

void loop() {
    writeRegisterValue(TSL2561_Address, TSL2561_Control, 0x03); // POWER UP
    delay(20);
    Serial.printf("Channel 0 Low value = 0x%x\n", readRegisterValue(TSL2561_Address, TSL2561_Channal0L));
    writeRegisterValue(TSL2561_Address, TSL2561_Control, 0x00); // POWER Down

    delay(2000);
}
```

setup()中にある

```
Wire.setClock(20000);
```

でクロックを指定する。上記は20kHZの指定。
なお、TLS2561のハンドリングについては、[以前の記事](https://qiita.com/infinite1oop/items/df0e90480a20e9c6ffd5)参照。参照ソースコードは[こちら](https://github.com/Seeed-Studio/Grove_Digital_Light_Sensor)。ここでは、チャネル０のLow値を定期的に取得している。

## 実験
### 100kHz指定時のデータ（デフォルトらしい、Wire.setClock()未使用時）
![100kHz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/0eb7d970-ac66-579d-e031-f58b8dc256a6.png)
D0がクロック(SCL)（以降同様）。約10μsごとに、SCLが繰り返されているのが見える。

### 50kHz指定時のデータ（Wire.setClock(50000)）
![50kHz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/b0a79abc-2aae-dc45-4092-8ab7929cce90.png)
約20μsごとに、SCLが繰り返されているのが見える。

### 20kHz指定時のデータ（Wire.setClock(20000)）
![20kHz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/a7d3a04f-3e22-80bc-5ee0-a32503597e8a.png)
約50μsごとに、SCLが繰り返されているのが見える。

## 終わりに
当たり前であるが、指定値どおりにクロックが出ている。
[PHP]UTF-8で多言語をファイル出力する際に文字化けする

PHPでUTF-8で中国語をテキストファイルに出力すると、開くアプリケーションによって文字化けが起こる事象に遭遇した。

## 元のプログラム

```php5
<?php

$filePath = 'mojibake.txt';
$value = '你好';

$fh = fopen($filePath, 'w');
fwrite($fh, mb_convert_encoding($value, 'UTF-8'));
fclose($fh);
```
途中の処理は省略している。

```bash
$ cat mojibake.txt
你好%
```
ちゃんと出力されているし、Macのテキストエディタで開いても正しく表示される。しかしこれをExcelで開くと...
![スクリーンショット 2020-10-17 5.08.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354714/12b1d36d-b2d4-7488-967a-297c4e650e99.png)
こんな感じで文字化けしてしまう。

## 原因

アプリケーションによって、Unicodeの符号化方式が判別できず、UTF-8・UTF-16・UTF-32を判別できないため、文字化けが起きてしまう。

## 解決策

上を判別させるために、ファイル出力時の先頭にBOMをつける。

### BOMとは

BOMとは、Byte Order Markの略称で、Unicodeの符号化方式を判別するために、ファイルの先頭につける数バイトのマーク。

>プログラムがテキストデータを読み込む時、その先頭の数バイトからそのデータがUnicodeで表現されていること、また符号化形式（エンコーディング）としてどれを使用しているかを判別できるようにしたものである。
[バイトオーダーマーク - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E3%82%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%83%9E%E3%83%BC%E3%82%AF)

BOMは以下の通り。

|  符号化形式 |  エンディアンの区別  | BOM | 
| ---- | ---- | ---- |
|  UTF-8  | | 0xEF 0xBB 0xBF |
|  UTF-16  | BE | 0xFE 0xFF | 
|  UTF-16  | LE | 0xFF 0xFE |
|  UTF-32  | BE | 0x00 0x00 0xFE 0xFF |
|  UTF-32  | LE | 0xFF 0xFE 0x00 0x00 |

今回はUTF-8なので、`0xEF 0xBB 0xBF`を先ほどのファイルの先頭につけるようにする。

## 修正したプログラム

```php5
<?php

$filePath = 'mojibake.txt';
$value = '你好';

$fh = fopen($filePath, 'w');

// add BOM
fwrite($fh, "\xEF\xBB\xBF");

fwrite($fh, mb_convert_encoding($value, 'UTF-8'));
fclose($fh);
```
Excelで開いても、正しく表示されるようになった。
![スクリーンショット 2020-10-17 5.35.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354714/353d02a5-b479-2a7f-31fe-6adb3c6af624.png)


## BOM付かどうかファイル情報を調べる

ファイルにBOMが付いているかはコマンドで調べることができる。

```bash
$ file mojibake.txt
mojibake.txt: UTF-8 Unicode (with BOM) text, with no line terminators
```
BOMが付いていると`with BOM`と表示される。

```bash
$ file mojibake2.txt
mojibake2.txt: UTF-8 Unicode text, with no line terminators
```
BOMがない場合は表示されない。
Laravel8でのルーティングで、コントローラーの指定の仕方4選

すごい久しぶりにqiita。
久しぶりにLaravel触ろうと思ったらLaravel8が出てて、試してみる。
Laravel7以前のと比べてRouteの書き方変わってたのでメモ。
（ぜんぜん大した話じゃないけどまだインターネッツに残っていないと思ったものは積極的に残すスタイル。）

# 前提： 今までの書き方

```php
Route::get('hoge/fuga', 'Hoge\FugaController@index');
```
Laravel7までは有効。Laravel8ではエラーになります。

# 1: 教科書どおりがいい派

```php
use App\Http\Controllers\Hoge\FugaController;
Route::get('hoge/fuga', [FugaController::class, 'index']);
```

使うクラスはすべてuseで指定しておいたほうが見通しがいい人向け。

# 2: useうざい派

```php
Route::get('hoge/fuga', [App\Http\Controllers\Hoge\HugaController::class, 'index']);
```

useはなくして、並んだ絶対パス眺めるのが好きな人向け。

# 3: 前みたいにシンプルに書きたい派

```php
Route::get('hoge/fuga', '\App\Http\Controllers\Hoge\FugaController@index');
```

Laravel8での新作法に違和感を感じる人向け

# 4: 完全に前のに戻したい派

app/Providers/RouteServiceProvider.php
を変更する必要があり、コメントアウトされている

```php
// protected $namespace = 'App\\Http\\Controllers';
```

のコメントアウトを外して有効にする。

```php
Route::get('hoge/fuga', 'Hoge\FugaController@index');
```

で以前と変わらない書き方ができる。

----

ぼくは2です。
いじょー！ 

<br>

<div><a href="http://twitter.com/M_Ishikawa">@M_Ishikawa</a></div>
【Unity】Asmdefに参照を追加してもVSCode側で反映されない

# TL;DR;

~~UPMでVisualStudioCodeEditorの代わりにこちらを使ってください。~~
~~`git@github.com:wallstudio/com.unity.ide.vscode.git`~~

最新のバージョンでは修正されています。

# 原因っぽいもの

CsProjファイルの`ReferenceOutputAssembly`の項目がfalseになっているからの様で、これを手動でtrueにすると治る。
ただ、これは自動生成ファイルなので、手直しでOKとはいきません。
もう治ってるみたいなことがかいてあったのですが…

https://issuetracker.unity3d.com/issues/referenceoutputassembly-key-is-set-to-false-in-project-references

とりあえず、当時の対処療法を試みるも、UPMのCode拡張を入れていると、`AssetPostprocessor.OnGeneratedCSProject`が呼ばれなくなってしまうらしいです。

```cs
public class FIX : AssetPostprocessor
{
  private static string OnGeneratedCSProject(string path, string content)
    => content.Replace(
      "<ReferenceOutputAssembly>false</ReferenceOutputAssembly>",
      "<ReferenceOutputAssembly>true</ReferenceOutputAssembly>");
  }
}
```

# 対処

`com.unity.ide.vscode`を直接書き換えちゃうのが手っ取り早いということで、こちらです

https://github.com/needle-mirror/com.unity.ide.vscode/compare/master...wallstudio:master

# 追記

OmniSharpの方にIssueが上がっていました

https://github.com/OmniSharp/omnisharp-vscode/issues/4113

ReferenceOutputAssemblyという名前的に本来trueであるべきのような気もするのですが（com.unity.ide.vscide側が悪い）どうなのでしょうか。
今まではfalseで動いていましたが。

Unityがプロジェクトメタファイルの出力クラスを切り替えている部分が分かりました。
[AssetPostprocessor.cs#L159](https://github.com/Unity-Technologies/UnityCsReference/blob/61f92bd79ae862c4465d35270f9d1d57befd1761/Editor/Mono/AssetPostprocessor.cs#L159)
どうやら、これからは`OnGeneratedCSProject`ではなく、[`IExternalCodeEditor`](https://docs.unity3d.com/ja/2019.4/ScriptReference/Unity.CodeEditor.IExternalCodeEditor.html)を使って出力機構丸ごと差し替える形でフックするのがよさそうです。
また、力業ではありますが、[`ReadDirectoryChangesW`（Win32API）](https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-readdirectorychangesw)などで、ファイルの書き換えをフックするという手段もあるにはあります。
Google Drive API V3 で共有ドライブにアップロードしよう

# なぜか404 親フォルダが見つかりませんエラー
Google Drive API V3で共有ドライブを使うときの話です、超ハマったわりに情報が少なかったのでメモ！
共有ドライブ内のフォルダにファイルをアップロードしようとして、`meta.Parents`に親フォルダのIDを指定して動かすと、なぜか`File not found [folderid] 404`というエラーがかえってきてしまいます・・・
ためしに共有ドライブでないMyDrive内のフォルダIDを指定すると成功するので、認証やプログラムの流れは問題なさそうです。

# 共有ドライブのアップロードはひと手間
いきなり結論ですが、以下の２プロパティを設定する必要がありました。
- metaオブジェクトの`DriveId`プロパティ
- CreateRequestオブジェクの`SupportsAllDrives`プロパティ

# DriveIdもURLからコピー
DriveIdは親フォルダのIDと同じく、ブラウザで該当の共有ドライブのルートディレクトリを開いたときのURLの末尾文字列です。
なお`TeamDriveId`というプロパティもありますが`Deprecated 変わりにDriveIdを使え`とのことでした。

# 完成
認証を含んだ全体的なコードは↓のようになりました。
ほぼQuickStartのサンプルコピペですが。
（コードはC#のSDKですけど他のSDKも同じでしょう）

```C#:GoogleDriveUploader.cs
string[] Scopes = { DriveService.Scope.DriveFile }; // アップロードするのでDriveFile
string ApplicationName = "適当にアプリケーション名";

UserCredential credential;

using (var stream = new FileStream("client_secret_～～.apps.googleusercontent.com.json", FileMode.Open, FileAccess.Read))
{
    string credPath = "token.json";
    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
        GoogleClientSecrets.Load(stream).Secrets,
        Scopes,
        "user",
        CancellationToken.None,
        new FileDataStore(credPath, true)).Result;
    Console.WriteLine("Credential file saved to: " + credPath);
}

// Create Drive API service.
var service = new DriveService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
    ApplicationName = ApplicationName,
});

var meta = new Google.Apis.Drive.v3.Data.File()
{
    Name = "作成するファイル",
    MimeType = "application/octet-stream", // 適宜設定しましょう
    DriveId = "共有ドライブのID (0ABcDeJiHiJKLmn23 みたいな)",
    Parents = new List<string> { "親フォルダのID (1auYhd9J9j～みたいな)" }
};

using (var stream = new System.IO.FileStream("アップロードするファイルのフルパス", System.IO.FileMode.Open))
{
    // 新規追加
    var request = service.Files.Create(meta, stream, meta.MimeType);
    request.Fields = "id, name";
    request.SupportsAllDrives = true;
    var ret = request.UploadAsync().Result;

    if (ret.Status == Google.Apis.Upload.UploadStatus.Failed)
    {
        throw ret.Exception;
    }
}
```
Julia早引きノート［07］try, catch, finally

###try, catch, finally(書き方例)

```ruby:note07

try
　(主処理)
catch
　(例外処理)
end

◆finallyを使用した例
　try
　　(例外処理)
　catch
　　(例外処理)
　finally
　　(最終処理)
　end

```

##解説
・catch, finallyはオプショナルです。



##もくじ
[Julia早引きノート［01］変数・定数の使い方](https://qiita.com/ttabata/items/a1ada2c0cba03672e105)
[Julia早引きノート［02］算術式、演算子](https://qiita.com/ttabata/items/90900d0914fa317f652d)
[Julia早引きノート［03］複素数]
(https://qiita.com/ttabata/items/225c77a4d71fafc3e482)
[Julia早引きノート［04］正規表現](https://qiita.com/ttabata/items/8b6e4a2b7c2ca299de03)
....
<details><summary>もくじを開く</summary><div>
[Julia早引きノート［05］if文]
(https://qiita.com/ttabata/items/4f0bcff1e32f60402dfb)
[Julia早引きノート［06］ループ処理]
(https://qiita.com/ttabata/items/2a53825101b0b75fb589)
[Julia早引きノート［07］try, catch, finally]
(https://qiita.com/ttabata/items/1d6fe990526c99b65b5f)
[Julia早引きノート［08］変数の型(Int, Float, Bool, Char, String)]
(https://qiita.com/ttabata/items/2b84a826e39bfe432b62)
[Julia早引きノート［09］関数 (1)基本編]
(https://qiita.com/ttabata/items/d9b4f2728ec0dbcc6394)
[Julia早引きノート［10］関数 (2)応用編]
(https://qiita.com/ttabata/items/462e216c43d519f1969d)
[Julia早引きノート［11］Nothing型]
(https://qiita.com/ttabata/items/0e5a6b21968d8752cf0b)
[Julia早引きノート［12］複合型(Composite Type)型]
(https://qiita.com/ttabata/items/27469216a3c33101c825)
[Julia早引きノート［13］タプル]
(https://qiita.com/ttabata/items/ebe35dbfec4efbc1c29a)
[Julia早引きノート［14］リスト(Array型一次元配列)]
(https://qiita.com/ttabata/items/7528863ccbb282e8260d)
[Julia早引きノート［15］辞書(dictionary)]
(https://qiita.com/ttabata/items/77a4f1d02b51d067bfb7)
[Julia早引きノート［16］集合]
(https://qiita.com/ttabata/items/ca8137922a785122037e)
[Julia早引きノート［17］多次元配列 (1)初期化]
(https://qiita.com/ttabata/items/01fecbd14363460a27a6)
[Julia早引きノート［18］多次元配列 (2)様々な演算や関数]
(https://qiita.com/ttabata/items/f35896a5fa005fba7fbc)
[Julia早引きノート［19］多次元配列 (3)サブ配列]
(https://qiita.com/ttabata/items/045c00406fe45270b42e)
[Julia早引きノート［20］ファイル入出力]
(https://qiita.com/ttabata/items/5a99c3998060d161ace8)
[Julia早引きノート［21］JSON、XMLファイルの入出力]
(https://qiita.com/ttabata/items/65ebec11830271f9be71)
[Julia早引きノート［22］Python関数やPythonモジュールの呼び出し]
(https://qiita.com/ttabata/items/3afc8cef40d1e98a7b17)
[Julia早引きノート［23］JuliaでのMatplotlibによるグラフ描画]
(https://qiita.com/ttabata/items/96a0e172addfac690cca)
[Julia早引きノート［24］CSVFiles(DataFrameとの連携)]
(https://qiita.com/ttabata/items/51446731a703b5aca524)
[Julia早引きノート［25］線形代数演算(ベクトル・行列計算)]
(https://qiita.com/ttabata/items/5abe14d5c510e8ca0f54)
(※引き続きコンテンツを増やしていきます)
</div></details>


##関連情報

:paperclip: Julia - 公式ページ
https://julialang.org/

:paperclip: Julia - 日本語公式ドキュメント
https://julia-doc-ja.readthedocs.io/ja/latest/index.html

:paperclip: 初めてのJuliaとインストール (Windows & Linux)
https://qiita.com/ttlabo/items/b05bb43d06239f968035

:paperclip: Julia - Mathematics
https://docs.julialang.org/en/v1/base/math/


##ご意見など

ご意見、間違い訂正などございましたらお寄せ下さい。
自宅のPC(LAN)から自宅のサーバーにアクセスできない問題

自宅のWEBサーバーを立てた時から疑問だった、「自宅のLANから自宅のサーバーにアクセスできない」問題を調べてみました。

# ことの発端は…

以前、自宅のラズパイにWEBサーバーを立ててSSLの証明書をとってHTTPSに対応させて、安心して寝たのですが…

その翌日…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/4aecff8b-e97f-4349-7d4b-35ee718bf5ec.png)

えええ、、、アクセスできない！？！？！
それに悪意のあるユーザー！？😱😱😱😱

とそんな感じで、翌日からサーバーを乗っ取られてしまったのかと背筋が凍りました…(冗談抜きで)

# 原因は？

しかしながら、Apacheのログなどを見ても全然普通だったので、色々試行錯誤してみるとスマホの4Gからならアクセスできることに気がつきました。
その事から、VPNを繋いでPCから見てみると普通に見れた事から、原因は自宅のLAN経由でつながっている事でした…

なので、ホット一安心して今まで自宅ではVPNに繋いでやっていたのですが、そろそろ面倒になって来たのとモヤモヤして夜しか寝れないので調べてみることにしました。

# ヘアピン NATという機能

どんな風にググればいいのか分からなかったので「自宅サーバー LAN アクセスできない」みたいに調べると、以下のサイトと出会いました。

[ヘアピンNATとは？](https://greenworksjp.com/bg/hairpin-nat/)

このサイトの記事を簡単にまとめと、LAN内から自宅のサーバーのグローバルIPに接続する際にヘアピンNAT非対応のルータだと
PC→ルーター→DNSサーバーまでは出来るようですが、その後のDNSサーバー→ルーターの時に自分で自分の所にアクセスしてるのでルーターちゃんがパニックを起こしてしまうらしいです。
なので、どうやら自宅のルーターではヘアピンNATというものに対応していないのが原因でした。

~~なんだよヘアピンNATってオシャレな名前しやがって…~~

# 対応させる方法

どうやら対応させる方法は大きく4つあるそうで

1. VPNなどから外部のプロキシサーバを経由してWAN側からアクセスする方法
2. ヘアピンNATに対応するルーターを利用してアクセスできるようにする方法
3. プライベート用のDNSサーバーを構築する方法
4. hostsファイルを編集して、ドメイン名を直接サーバーのプライベートIPにルーティングする方法

今やっているのは、1番のやつですね。
そして、自分がもう１つ調べて分かったのが、

- IPv6で接続する

# 結局そのままで行くことに

前述した通り、色々とどうにかする方法はあるみたいで、その中でVPN経由かIPv6でアクセスするのがよさげな感じがしました。

なので、今回はヘアピンNATという言葉の意味と、接続ができない理由と仕組みを勉強することができて良かったです(笑)
プライベートのDNSサーバーは、時間が出来たらやってみたいと思います。
fishもzshも使うんだよ。

#経緯(読まなくていい)
大学を卒業してはや半年。社会人１年目になって触るmacOSは未知の領域すぎた。
windowsとLinuxしか触ってこなかった自分にとってmacOSのターミナル生活は秒で終わりを告げる。新しいシェルと効率化に喜ぶもとある壁にぶつかる。

一人の先輩は言った。
「fishっていう便利なシェル、使ってないの？w😜」

もう一人の先輩は言った。
「うわ〜フィッシュってるよ〜なんでzshないの〜😠」

聞く先輩によって使う環境は様々。
雑魚エンジニアにとっては〇〇言語はA先輩に質問。〇〇言語はB先輩に質問しようと効率よく質問することなんてザラにあるし、どうせならその先輩にも気持ちよくこうすればいいと指摘してもらって、winwinな関係を築きたい。そんな時の備忘録。

#やりたいこと
macOSでzshとfishをパパッと変えたい。(他のシェルも使っていたら好きなシェルに変えれる。多分。)
追記：**あとから一発で変更するコマンド見つけた。**

##一覧の表示
下記のように、`cat shellのパス`で現在インストールされているシェル一覧が表示

``` shell:fish
hoge@MacBook-Pro ~> cat /etc/shells
```
実行結果↓

``` shell:fish
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
/usr/local/bin/fish
```

##切り替え方
切り替えるには`chsh -s 切り替えたいパス`でいける。

``` shell:fish
#fishからzshに切り替える方法
hoge@MacBook-Pro ~> chsh -s /bin/zsh

#zshからfishに切り替える方法
[hoge@MacBook-Pro] ~
% chsh -s /usr/local/bin/fish
```

切り替えた後そのユーザのパスワードを聞かれるので、それでシェルを変えれる。

#終わりに
正直ちょっと考えればこれぐらい誰でもできるかと思うが、こういう深夜テンション記事が
僕みたいな小心者エンジニア仲間の誰か一人に手助けになってくれればと思う。

#追記
なんかエイリアスで切り替える方法見つけよと思ったら、下記のようにshellの名前打ち込んだら
一発で変わること見つけてしまった。
ただiTerm2を終了したりした際に元に戻るんで、短期的に切り替えたいならこれでいいのかなと思ったり。
(まあなんかいい感じにしたら切っても切り替えられる仕組みを作れそうな気もする。)

``` shell:fish
#fish -> zsh
zsh

#zsh -> fish
fish
```

###おまけ
数ヶ月エンジニアとして働き始めて思う二つのシェルの良さ


 - fishの良さ


-> 色々な便利機能がある。色とか雰囲気もなんかおしゃれでみやすい。ghq,pecoとか導入すると一気に自分のレポジトリとかジャンプ、検索、補完とか出来て便利感は強い

 - zshの良さ

-> bash互換のスクリプトがfishだと一部動かない。 昔から使っている人が多い印象。fishに比べて早いらしい。(感じたことない)　調べるとだいたいzshで出てくるから使ってる人は多い印象。
Chainerによる機械学習のためのPython学習メモ　9章 scikit-learn 入門

# What

Chainerを利用して機械学習を学ぶにあたり、私自身が、気がついた点、リサーチした内容をまとめる記事になります。今回は、scikit-learnを勉強します。

私の理解に基づいて記述しているため、間違っている場合があります。間違いは都度修正するつもりです、ご容赦ください。

# Content

### scikit-learn
**このライブラリを使いこなすとモデルの訓練ができるようになるらしい。**
>*米国ボストンの 506 の地域ごとの住環境の情報などと家賃の中央値の情報を収集して作られた Boston house prices dataset というデータセットを使用します。*

使ってみます。
５０６サンプルのデータセットから物件価格の中央値を予想して実際の中央値と比べるようです。

###訓練用データとテスト用データの準備
今、Boston house prices datasetからデータを与えられている状況で、このデータを訓練用（＝モデル最適化）に全て使ってしまうと、５０６サンプルのデータを最適化してしまい、実際にモデルに未知のデータを与えようとしたとき、全く実態と合っていないとなっては訓練した意味がないです。（過学習という）ですので、一部のデータはモデルの妥当性検証に用いると良いようです。**無作為に訓練用、テスト用にデータを割り振ることをホールドアウト法という。**
以下の関数一つで分割できる

```py
# 訓練用データセットとテスト用データセットへの分割
x_train, x_test, t_train, t_test = train_test_split(x, t, test_size=0.3, random_state=0)
```

過学習を防ぐ方法は学術的な研究対象になっているらしい。
このライブラリではデータセットの平均値０分散１になるようにデータの前処理ができる

データの前処理から重回帰分析を行い決定関数で評価するまでの一連の流れは
パイプラインを使うと処理を統合できる

# Comment
せっかく勉強するので、何か形にしたいなーと思っていた矢先
Deep racerという競技をしりました。AWSのDeep racerに出てみたいと思いました。
Trailheadのchallengeでクラスをnewする際の注意

# はじめに

salesforce楽しんでますか？
~~楽しくないよな、うん。
Apexうざいよな。
GUI操作性悪いよな。
宣言型開発うざいよな、コード書かせろよな~~

先日、資格取得のためTrailheadを~~嫌々~~進めていたらchallengeで以下のエラーに当たった。
調査するとTrailheadをクリアしていく上で重要なことが分かったので記事にしておく。

対象Trailhead：Queueable Apex を使用したプロセスの制御
エラー:The 'AddPrimaryContactTest' test class doesn't appear to be using the 'AddPrimaryContact' class
※当然だがchallengeクリア条件は満たしている（カバレッジ100%）
下にテストクラスを載せておく

```
@isTest
public class AddPrimaryContactTest {
	@isTest
    static void aaa(){
        List<Account> accList = new List<Account>();
        for(Integer i = 0;i<50;i++){
            Account acc = new Account ();
            acc.Name = 'Test'+i;
            acc.BillingState = 'NY';
            accList.add(acc);
        }
        for(Integer i = 0;i<50;i++){
            Account acc = new Account ();
            acc.Name = 'Test'+i+i;
            acc.BillingState = 'CA ';
            accList.add(acc);
        }
        insert accList;
        Contact con = new Contact(LastName='aaa');
        insert con;
        AddPrimaryContact target = new AddPrimaryContact (con,'CA');
        Test.startTest();        
        System.enqueueJob(target);
        Test.stopTest();    
    } 
}

public class AddPrimaryContact implements Queueable { 
    private Contact cont;
    private String str;
    public AddPrimaryContact(Contact cont, String str){
        this.cont = cont;
        this.str = str;
    }
    public void execute(QueueableContext context) { 
       List<Contact> contList = new List<Contact>();
        List<Account> accList = [select id FROM Account WHERE BillingState = :str LIMIT 200];
       for(Account uu : accList){
            Contact c = cont.clone(false,false);
            c.AccountId = uu.Id;
           	contList.add(c);
        }
        insert contList;
    }
}
```
# 調査
Trailheadでこういう訳のわからないエラーに当たるのはもちろん初めてじゃない。
またか...と思いながらとりあえずこのエラーをそのままググってみると色々みんな苦労しているようだということだけ分かったが、解決方法はよくわからない。
というかエラーの意味がよくわからない。
テストクラスでちゃんとAddPrimaryContact呼んでるし。。。

# 解決
いつでも答えはエラーログの中にある。
ググってもよくわからないからこのエラーログを考えてみた。
すると答えはそのまま、testクラスのここが問題だった

```
AddPrimaryContact target = new AddPrimaryContact (con,'CA');
```

「new AddPrimaryContact (con,'CA');」このAddPrimaryContactと(con,'CA')の間に**半角スペースが入っている！！！**

なんなんでしょうね、半角スペースが入っていたらクラス'AddPrimaryContact 'を呼び出したとでも思われるんですかね。。それならコンパイルで弾いてくれませんかねぇ。
消したらちゃんとクリアできました。

教訓
**Trailheadではクラスをnewする際クラス名と()の間に半角スペースを入れないようにしましょう**
めんどくさ！
Handsontableのレンダラーまとめ

## レンダラーとは

表示やトリガー(クライアント側からの操作に対してのイベント発火）など、セルの出力を制御する設定。

ハンズオンテーブルにはデフォルトで10個の設定がされている。
以下は公式からの抜粋

> - autocomplete for Handsontable.renderers.AutocompleteRenderer
- base for Handsontable.renderers.BaseRenderer
- checkbox for Handsontable.renderers.CheckboxRenderer
- date for Handsontable.renderers.DateRenderer
- dropdown for Handsontable.renderers.DropdownRenderer
- html for Handsontable.renderers.HtmlRenderer
- numeric for Handsontable.renderers.NumericRenderer
- password for Handsontable.renderers.PasswordRenderer
- text for Handsontable.renderers.TextRenderer
- time for Handsontable.renderers.TimeRenderer

### レンダラーの使用方法

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="mgmgmogumi" data-slug-hash="pobyPPg" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="pobyPPg">
  <span>See the Pen <a href="https://codepen.io/mgmgmogumi/pen/pobyPPg">
  pobyPPg</a> by mogumogu mogumi (<a href="https://codepen.io/mgmgmogumi">@mgmgmogumi</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## カスタムレンダラーとは

自分でレンダラーの設定をしたもの。
[Tutorial: Custom renderers - Handsontable Documentation](https://handsontable.com/docs/8.1.0/demo-custom-renderers.html)

### カスタムレンダラーの使用方法
デフォルトで用意されているレンダラー以外に、自分で設定することができる。
ちなみにデフォルトと同じ名前で設定すると、設定を上書きできる。

`Handsontable.renderers.registerRenderer(rendererName, renderer)` 関数を使用して設定する。

## 参考

[Handsontable 使い方メモ１（基本） - Qiita](https://qiita.com/opengl-8080/items/ac19deec388c357cd498)

おしまい

<!--

## オプションとは

なんか色々設定できるっぽい。
https://handsontable.com/docs/7.0.0/tutorial-setting-options.html

## Handsontableのスクロールが重い

[Tutorial: Scrolling - Handsontable Documentation](https://handsontable.com/docs/8.1.0/demo-scrolling.html)
公式によると、スクロールが重くなる原因が４つあるらしい。

1. セルの量
2. カスタムレンダラーの量
3. 使用している機能(オプション)の量
4. マシンやブラウザのパフォーマンス

改善できそうな部分は**2のカスタムレンダラー**か**3のオプション**。

-->
git ignoreを使って特定のファイルをgitでプッシュしない

開発すれば開発するだけ、プログラミングが楽しくなっているうったむです☺️

今日はenvファイルなど開発者以外の人には見せたくないファイルをgitでプッシュしない方法を見つけたのでメモとしました。

解決法は「git ignore」です！どのように使うかを以下の部分から説明しますね。


`開発環境 macOS Catalina バージョン 10.15.7` 

##git ignoreとは


硬い言葉で説明すると「指定したファイルをgitの追跡対象から除外する」ことを可能にします。パスワードが書かれたファイルなどはgithubにはプッシュしない方が良いですよね。

僕の場合は、mysqlのパスワードなどを書いたenv.phpに適用するために使いました。


##git ignoreをどのように使うか


まず

```
git status
```

で内容の確認します。

おそらくgitでプッシュしたくないファイルが表示されているでしょう。

そのファイルをプッシュしないようにするため


```
vim .gitignore
```

を使います。

そうすると、指定したいファイルなどを打ち込める画面になります。

私の場合はenv.phpをgitでプッシュしたくないので

```
env.php
```

と打ち込みます。

ファイルなら「ファイル名を」、コメントなら最初に「＃」を。ディレクトリなら末尾に「/」を書きます。

その他にも、特定のファイル名の指定をしたいなら「*.ファイル名」とします。例えばphpで書かれたファイル全てを指定したいなら「*.php」と書きましょう。

逆にgitの管理対象にしたいなら最初に「!」を書けばokです。

ではgitの管理対象外にしたいものを指定したら

```
:w
```

で保存しましょう。

```
:q
```

にて終了しましょう！（:wqで保存して終了とどちらもできます）

できたら

```
ls -al
```

で中身の確認です（ls 何がディレクトリ内にあるか確認。-al 隠しファイルや詳細などの表示）。

最後にgit statusで確認すると.gitignoreができていることがわかりますね。


##まとめ


ぜひセキュリティゆえに共有したくないファイルがあったら「git ignore」を使いましょう。