OmniAICreator/Qiita-1.07M huggingface dataset:
Tableau使いのレポートの作り方　～アプリやツール編～

🎉🎉本記事を見ていただきありがとうございます！！🎉🎉

はじめに
-----
<font color="Red">※初めて資料やレポートを作る方向けに作成した記事です※</font>

レポート（資料）ってなんのために作成すると思いますか....？

数値を見て『現状を把握するため』であると私は考えています。


そして、現状を知った上で何をするのか.....
そう現状を改善するために『何かを決める（意思決定）』事をするんです。


ここで数値がわかりにくく『現状を把握する』が遅くなったり、間違った形で伝わると、
そのまま、意思決定の遅延や間違った決定へと繋がって行きます。


という事で、数値を確認できる資料って大事だという事がわかっていただけたましたでしょうか？
ちょっと前置きが長くなりましたが、ここからはやる事に応じてSTEPに分けてご説明させていただきます。


▼Step⓪　まず最初にやる事
-----
<font color="OrangeRed">①要望を把握しておく　（何がみたいか提出元（上長）に確認しておく）</font>
※基本だと思うので、説明は省いておきます！

▼Step①　ツール（サービス）には必ず”作る理由（目的・ニーズ）”がある事を認識しよう
-----

<font color="OrangeRed">①可視化対象の利用目的を考える（触ってみる）</font>

☆なぜ？：ツールやアプリである事が前提にはありますが、機能や各ツール・アプリの特性を知らなければ
データベースなどを見て時に理解度が低くなるので、レポート出来と作る速度に大きな差ができてしまいます。


<font color="OrangeRed">②（このツールやアプリを伸ばすために）見たい項目ってなんだろうと考えてみる</font>

☆なぜ？：ツール（サービス）には必ず『作る理由（目的・ニーズ）』があると共にそこを主軸とした機能がありますので、
その『作る理由（目的・ニーズ）』を捉える為に①の触る事や②の考えるタイミングが必要となります。


▼Step②　格納されているデータを見てみよう！（数値を理解しよう）
-----

<font color="OrangeRed">①列の意味を知る</font>
<font color="OrangeRed">②各列にて入っているデータの意味を知る</font>

☆なぜ？：上記はセットなのですが、Tableauは列がフィールド名なので、
フィールド名と各列にどのようなデータが入っているかを知る事はデータベース全数値の特性を理解するという事です。


<font color="OrangeRed">③①②が終わったらあたりをつけておく</font>

☆なぜ？：データベースが1つの場合は覚えているだけで良いのですが、
データベースが多岐にわたる場合は、忘れてしまう可能性も高い為、Excelやメモにフィールド名に”何のデータが入っているのか”
”どういう数値を出すのに向いているのか”この2点を書き出す事で、少し触らない期間があった際もすぐレポート作成に戻れるでしょう。


▼Step③　全集中！全部可視化！
-----
<font color="OrangeRed">①1度可視化できるものは全部可視化してみる</font>

☆なぜ？：全部可視化してみるというのはStep②ができているかの確認するタイミングです。
もし可視化できる項目が少ないのであれば、Step②の数値の確認だったり理解が浅いと捉えられます。
そういった場合は、Step②に戻ってみましょう。


▼Step④　可視化する項目を選定するお話
-----

<font color="OrangeRed">①必要不必要を考える　</font>

☆なぜ？：全て見せられても逆にどこを見ていいのかわからないレポートとなってしまう為、見せたい所や伝えたい事が分かりづらくなります。
その為に必要になってくるのが、Step⓪とStep①になります。
Step⓪でいただいた”要望”とStep①で考えた”目的・ニーズ”に沿ったグラフのみ残すようにしましょう。


<font color="OrangeRed">②可視化対象に影響しそうな事柄を考える　（傾向を掴んでおく）</font>

☆なぜ？：結論から言えば”例年の傾向”を把握しておく。何か”イレギュラーな自体”を把握しておくという事です。

また、私もやりがちなのですが、大きく飛び抜けた数値だけを見せるケース。それを抑制する為にこの項目があります。
この数値がグラフ上では突出した数値になっているがこれは、異常な数値なのかそうではないのかを判断する事。


例えば、おもちゃ業界でいうとクリスマスやお子さんがお年玉などをもらう12月末～年明けは、売上がかなり上昇する。
これを例年の傾向がつかめておらず、グラフ上だけで見ると異常な数値に見えますが、例年の事であれば、異常な数値ではないと判断できます。



▼Step⑤　レポートの並び順を考えてみる
-----

<font color="OrangeRed">①もっとツール（サービス）をバズらせる為の足りてない部分を見出し仮説を作る</font>
<font color="OrangeRed">②レポートを組み変える　（ダッシュボードに配置してみる）</font>

☆なぜ？：大事なのは「何をすればこのツール（サービス）はもっと利用されるんだろう？（原因はなに？）」と考えることです。
その為に現在の数値になっている理由を見出し理解する事で、グラフの配置がわかってくるかなと思います。


上記が終わればレポートが完成しているかなと思います。


▼ワンポイント:point_up:
-----

レポートが出来上がった上で、自分自身で最終確認する前に自分に投げかけてポイントを書き出しておきます。
もし、必要であれば最終確認の際に自分に投げかけてレポートを一通り見てみてください！！


・調べない（説明されない）とわからないグラフとなっていないか
・文字の大きさは統一されているか
・書式は統一されているか
・文字の色は統一されているか
・文字に大きさの強弱はついているか（タイトルや説明やグラフの数値など場合によっては強弱をつける）
・同ダッシュボード内に同一色のグラフはないか
・可視化した数値はグラフの特性にあっているか
・グラフの配置がZの法則に則っているか
・各日付の表記は統一されているか　（グラフ①『2020/12/23』　グラフ②『2020年12月23日』のように表記揺れがないか）
・プレゼンできるように改善案と数値の把握は全てできているか
・必要な可視化項目に漏れがないか


最後に
----------------------
いかがでしたでしょうか？
Tableauの使い方やテクニックではなくごめんなさい:joy:

こちらは今まで私の知見でのお話になるので、万人受けはしないかな....
だったりcase by caseな事もあり必ずしも使えるものでもないかなと思っておりますが、
皆様の作り方考え方などに少なからず影響を与えられたら幸せです！:sunglasses:

もしよろしければ、記事を読んだ方で別の考え方なのがあればぜひコメントください！（勉強させてください！）

最後に記事を見てくださりありがとうございました！
（来年のAdvent Calendarはもっと技術的なものに挑戦する！！！）
ROSについてまとめてみる #6

この記事は、[ROSについてまとめてみる #5](https://qiita.com/hatt_takumi/items/ae6cbd38865a4f0c5a6b)の続きです。

最後に、ROS1とROS2の違いについてまとめてみたいと思います。
ROS2は、ROS1のソースを引き継がず、一からフルスクラッチで制作されているので、互換性はほぼないです。
(ブリッジは用意されています。)

#ROS1とROS2の違い
##DDSの採用
一番大きな変更はこれです。
ROS1では、通信のライブラリはTCPベースの独自実装でしたが、ROS2ではUDPベースのDDSに置き換わりました。これにより、ROS masterの担当していた仕事はDDS自体が持つことになり、単一障害点でもあったros_coreは存在しなくなりました。
NASAのROS1を使ったリポジトリがDDSで実装されており、これが選定の要素になったとかならないとか。

###サービス
ROS1ではサービスは同期で、非同期的な実装をするためにはactionを使う必要がありましたが、ROS2ではサービスのみで同期、非同期のどちらも実装できるようになりました。

###パラメータ
ros_coreがなくなったため、パラメーターサーバーの役割は各ノードが受け持つようになりました。
また、パラメータに値が更新されると、コールバック関数が呼ばれるといったようなイベント駆動も標準で出来るようになりました。

###QoS(Quality of Service)制御
ROS2では、通信の品質を4段階から変更できます。

<ul>
<li>History<br>
Keep last: N個分のサンプルを保存します。DepthオプションでNを制御します。<br>
Keep All: リソース限界まですべてのサンプルを保存します。</li>

<li>Depth<br>
キューのサイズを指定します。(Historyオプションが　Keep last　の場合)</li>

<li>Reliability<br>
Best effort: サンプルを配信しますが、欠損する可能性があります。<br>
Reliable: サンプルの配信を保証します。(届くまでリトライされる)</li>

<li>Durability<br>
Transient local: Publisherより後に立ち上がったSubscriberへ配信するため、最後に配信したサンプルを一つ保持する。<br>
Volatile: サンプルは保持されない。
</li>
</ul>

##リアルタイム制御
ここでのリアルタイム性とは、処理の速さではなく、応答の最悪値が保証される(RTOS的な)意味でのリアルタイムです。ROS1でも、ros_controlはリアルタイムだったり、リアルタイムカーネルを導入したりなどで、そのようなことは可能でしたが、ROS2ではもっと汎用的にリアルタイムの設計が可能みたいです。
*すみません、ここに関しては、どうやって実現しているのかなど、正直ちょっとよくわかりません…

##複数ロボットへの対応
ROS1は、基本的にロボットは一台で動作させることを想定してます。multimasterで複数のROS masterを動作させるなど、複数台同時に動かす方法はあるにはありましたが、基本的な設計思想としては、ロボットは一台です。ROS2ではROS masterがなくなったこともあり、複数ロボットへの対応を謳っています。

##組み込みへの対応
ROS1はコアな機能がC++で実装されていましたが、ROS2はCで実装されています。これにより、より組み込み機器への導入がしやすくなっています。ROS1では、PC上でノードを立て、ノードと機器はシリアル通信するなどの方法が一般的でした。ROS2では、組み込み用のライブラリを使えば、機器内にノードを立てることもでき、そのままROSのネットワークに参加させることもできます。

##システム構築のパターン化
ROS1では、基本的にソースコードの書き方は自由でした。
ROS2では、コンポーネント指向が導入され、ライブラリに沿った書き方を求められます。ユーザーはメインループを記述しません。
その代わり、ROS2側でノードのライフサイクルを管理してくれるなどの恩恵を受けることができます。

##マルチプラットフォーム対応
ROS2では、Windowsはおろか組み込み機器までも含めたマルチプラットフォーム対応を掲げています。
ROS1でも言っていたような…


#参考
ROS
http://wiki.ros.org/

プログラミングROS(O'Reilly Japan)
https://www.oreilly.co.jp/books/9784873118093/

ROS2ではじめよう 次世代ロボットプログラミング(技術評論社)
https://gihyo.jp/book/2019/978-4-297-10742-0
composer update でメモリが足りないとき、設定の変更などせず手っ取り早く済ませる

# メモリが足りないというエラー

```terminal
Fatal error: Allowed memory size of xxxxxxxxxx bytes exhausted 
```

解決策を検索すると「メモリの割当を増やしてから実行」という方法が出てくるが、設定などを変更せずにエンターキー一発で手っ取り早く済ませたい。

```terminal
$ php -d memory_limit=-1 /usr/local/bin/composer update
```

これだけでいけるはず。

![0063eafe55507627cc507a0e315618df.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413699/8b70d8be-b2e2-53f6-2215-4905a5032471.png)
2020年2月29日の2年後は2022年何月何日?

#はじめに
現在、開発をしているプロジェクトがありまして、レコードの日付を2年ずらしてデータをずらしたことがありました。その時、たまたま **2020年2月29日** もその中に入っておりました。その時に得た結果をご披露します。この記事は[ソフトウェアテストの小ネタ Advent Calendar 2020 - Qiita](https://qiita.com/advent-calendar/2020/software-testing-koneta)の25日目です。

#MySQL
まず MySQL の場合は **2020年2月29日** の2年後は **2022年2月28日** になりました。

    mysql> SELECT DATE_ADD( '2020-02-29', interval '2' YEAR ) ;
    +---------------------------------------------+
    | DATE_ADD( '2020-02-29', interval '2' YEAR ) |
    +---------------------------------------------+
    | 2022-02-28                                  |
    +---------------------------------------------+
    1 row in set (0.01 sec)
    mysql>

逆に**2020年2月29日** の2年前は **2018年2月28日** になりました。

    mysql> SELECT DATE_ADD( '2020-02-29', interval '-2' YEAR ) ;
    +----------------------------------------------+
    | DATE_ADD( '2020-02-29', interval '-2' YEAR ) |
    +----------------------------------------------+
    | 2018-02-28                                   |
    +----------------------------------------------+
    1 row in set (0.00 sec)

    mysql>

#PostgreSQL
PostgreSQLの場合も MySQL と同様です。

    postgres=# select cast('2020/2/29' as date) + cast('2 years' as INTERVAL);
          ?column?
    ---------------------
     2022-02-28 00:00:00
    (1 row)
    
    postgres=# select cast('2020/2/29' as date) + cast('-2 years' as INTERVAL);
          ?column?
    ---------------------
     2018-02-28 00:00:00
    (1 row)
    
    postgres=#

#Excel
ところが、Microsoft Excelの場合は違います。
例えば、DATE関数を使用して、A1セルが**2020年2月29日**の時

    =DATE(YEAR(A1)+2,MONTH(A1),DAY(A1))

は**2022年3月1日**となります。なお、2年前は**2018年3月1日**となります。
ところが、

    =EDATE(A1,24)

の場合は、MySQLと同様、 **2020年2月29日** の2年後は **2022年2月28日** になります。2年前も同様に **2018年2月28日** になります。

#おわりに
日付の処理の例外的パターンを調べてみました。使う処理系や関数によって結果が変わるので注意が必要だなと改めて思いました。
【Rails】フォームのオートフォーカスによる画面表示時のエラーについて

Railsで個人アプリを開発しているときに発生したエラーです。
備忘録としてエラーの発見から解消までを記します。

# 事象
スマートフォン(OS:iOS、ブラウザ:Google Chrome,Safari)でサインアップページにアクセスすると、ページのレイアウトが一瞬だけ表示された後、「このページは開けません。」というエラーが発生する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620431/37efe0be-7585-e9d1-d14d-5d01d61ecd1e.png)

ただし、該当URLを直打ちでアクセスするとページが正常に表示される。(これについては最終的に謎のまま終わりました・・・)

# 調査

他に同様のエラーが出るページは無いか探したところ、プロフィール編集ページでも発生しました。

サインアップページとプロフィール編集ページの共通点は、ユーザー情報を入力するフォームがあることでした。

### サインアップページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620431/edb3ba8a-c525-930b-5453-6c4bf7a59836.png)

### プロフィール編集ページ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620431/9eb85d04-9d6d-7480-c9d8-cc8111ee1cd8.png)


# 原因

1画面内にautofocus: trueのフォームが複数存在すると、スマートフォンで閲覧した際にエラーが発生するようです。
そのため、autofocus: trueを一番最初の入力フォームにのみ残し、残りのフォームから消したところエラーは解消されました。
PCで閲覧する際にはエラーが出ないので見落としていました・・・
フォームをコピペで増やしていくのもいいですが、この辺りをしっかりメンテナンスしないといけないですね・・・。
OpenCV で動画を加工する

OpenCVで簡単に動画に任意の処理ができます。

###１、ビデオを読み込んで書き込む

```python
import cv2
cap = cv2.VideoCapture('./video.mp4') #読み込む動画のパス
fps = cap.get(cv2.CAP_PROP_FPS)

fourcc = cv2.VideoWriter_fourcc('m','p','4', 'v') #mp4フォーマット
video = cv2.VideoWriter('./edited_video.mp4', fourcc, fps, (1920,1080)) #書き込み先のパス、フォーマット、fps、サイズ

avg = None

while True:
    # 1フレームずつ取得する。
    ret, frame = cap.read()
    if not ret:
        break

    #🐥 任意の処理をここに書く 🐥

    video.write(frame)

    key = cv2.waitKey(30)
    if key == 27:
        break

cap.release()
video.release()
```


###２、処理を書く

例えば、動画をスケッチ風にするには、
１、の任意の処理のところに以下を入れます。

```python
    #🐥 任意の処理をここに書く 🐥
    # 白黒画像に
    grayImage = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 白黒反転
    grayImageInv = 255 - grayImage

    # ぼかしをかける
    grayImageInv = cv2.GaussianBlur(grayImageInv, (21, 21), 0)

    #blend using color dodge
    output = cv2.divide(grayImage, 255-grayImageInv, scale=256.0)
    output = cv2.cvtColor(output, cv2.COLOR_GRAY2BGR)
    video.write(output)
```
![Dec-23-2020 18-59-56.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/5bedf3d5-703b-d559-a294-769897530008.gif)

![Dec-23-2020 19-01-12.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/8f80fb95-0f7c-eed7-6084-41567077fb0e.gif)

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
lib/配下のファイルをリロードするたびに再読み込みする

めも

## TL;DR

```ruby:config/application.rb
...
config.eager_load_paths += ["#{Rails.root}/lib"]
...
```

参考記事： https://stackoverflow.com/questions/3282655/ruby-on-rails-3-reload-lib-directory-for-each-request

requireは不要になるので削除。

## 開発環境でのみonにする
開発時にしか行わないことなので、本番で毎回読み込まないようにするには以下のように書く。

```ruby:config/application.rb
...
config.eager_load_paths += ["#{Rails.root}/lib"] if Rails.env.development?
...
```

```ruby:呼び出し側
require './lib/invoice_pdf' unless Rails.env.development?
```
postgreSQLをローカル環境で操作する

#ローカル環境でpostgreSQLをインストールから操作するまで
久しぶりにpostgreSQLを扱ったら大分忘れていたので、メモがてら残します。

##homebrewでpostgreSQLをインストールする。
まず、macのローカル環境にpostgreSQLの環境を構築するためには、homebrewでインストールする。

[homebrewについて詳しくはこちら][link-1]
[link-1]:https://qiita.com/omega999/items/6f65217b81ad3fffe7e6

```
$ brew install postgresql
```

ちなみにbrew install以外のやり方も多数あるが、このやり方が一番簡単だと感じました。

逆に、色々ありすぎて最初はどのやり方がベストなのか悩みました。笑

正常にインストールされている場合は、下記コマンドでバージョンが表示される。

```
$ postgres --version
postgres (PostgreSQL) 9.3.4
```

##サーバーの起動と停止

サーバーの起動と停止についてもやり方がさまざま存在するが、筆者はこのやり方一択です。

postgreSQLサーバーを起動する。

```
brew services start postgresql
```

停止する際は下記コマンド

```
brew services stop postgresql
```

postgreSQLサーバーの起動状態を確認する。

```
$ brew services list
Name       Status  User          Plist
mysql      stopped
postgresql started username /Users/username/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
```

これでインストールとサーバーの起動停止は完了です。

##ターミナル上でデータベースを操作する

データベースに入るにはpsqlコマンドを利用する。

```
$ psql データベース名
```

データベースの一覧を見たい場合

```
$ psql -l

 Name    |     Owner     | Encoding | Collate | Ctype |        Access privileges
-----------+---------------+----------+---------+-------+---------------------------------
 test    | tesutdesuyote | UTF8     | C       | C     |
 test    | tesutdesuyote | UTF8     | C       | C     |
 test    | tesutdesuyote | UTF8     | C       | C     |
 test    | tesutdesuyote | UTF8     | C       | C     | =c/tesutdesuyote               +
         |               |          |         |       | tesutdesuyote=CTc/tesutdesuyote
 test    | tesutdesuyote | UTF8     | C       | C     | =c/tesutdesuyote               +
         |               |          |         |       | tesutdesuyote=CTc/tesutdesuyote
(5 rows)
```

[psqlコマンドについて詳しくはこちら][link2]
[link2]:https://qiita.com/aosho235/items/c657e2fcd15fa0647471

これでローカル環境で一通りpostgreSQLを操作することができるようになる。

ちなみにGUIでデータベースを操作する場合は、posticoやDBeaverといったDBツールがおすすめです。
【Ruby】【Git Hub】【Heroku】アプリの立ち上げ

初めての投稿をさせていただきます。よろしくお願いいたします。

アプリを立ち上げる際に少々滞ってしまったため、メモに残したいと思います。


① rails newを使いアプリを立ち上げる。（ターミナル）

``` 
 % rails _6.0.0_ new アプリ名 -d mysql 
```


② cdコマンドを使い、操作するアプリケーションへ移動する。（ターミナル）

```
% cd 移動したいディレクトリパス （アプリ名）
```

③ GitHub desktopにてローカルリポジトリを作成する。
　1. 画面左上部分「add▼」をクリックする。
　2. 「Add Exciting Ripository」を選択する。
　3. Finderから作成したアプリを開く。
　→GitHub desktopにアプリケーションが現れている。

④ ローカルリポジトリ作成後、以下のコードを実行する。（ターミナル）

```
% git config --global core.excludesfile ~/.gitignore_global
```

⑤ GitHubにリモートリポジトリを作成する。
　1.一度コミットする。（個人的に最初のコミット名はfirst commitにしている。）
　2.「publish ripository」を選択する。privateのチェック欄は外す。

⑥ Herokuを導入する。
・Herokuをインストール、ログインする。（ターミナル）

```
# Herokuをインストールする
% brew tap heroku/brew && brew install heroku

#バージョンを確認する
% heroku --version

# Herokuへログインする
% heroku login --interactive
→実行後、メールアドレス、パスワードを入力する
```

・Heroku上にアプリケーションを作成する。（ターミナル）

```
% heroku create アプリ名

#作成されたかを確認する方法
% git config --list | grep heroku
→ fatal: not in a git directory以外が表示されていれば成功。
```

・Heroku上でMySQLを使用できるようにする。

```
# ClearDBアドオンを行う。
% heroku addons:add cleardb

# 設定の変更を行う。
% heroku_cleardb=`heroku config:get CLEARDB_DATABASE_URL`
% heroku config:set DATABASE_URL=mysql2${heroku_cleardb:5}
```

・非公開情報について

credentials.yml.encの中身を確認する。
→config/credentials.yml.enc内に暗号文の記述があるため確認する。

次に下記コードをターミナルで実行する。

```
% EDITOR="vi" bin/rails credentials:edit
```

access_key_idとsecret_access_key等を確認することができる。
「escキー」、「：」、「q」を順に入力することでcredentials.yml.encを閉じることができる。

・Heroku上にmaster.keyを設置する
下記コードをターミナルで実行し、環境変数としてmaster.keyを設置する。

```
% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`

# 確認方法
% heroku config

# Herokuへコミットをプッシュする
% git push heroku master

# デプロイされたアプリの情報を確認する
% heroku apps:info
```

ひとまずは以上です。
【Swift】Optional<Wrapped>型でエラー処理を行う

エラー処理には、**Optional\<Wrapped>型**を用いた処理の他にも、
**Result\<Success, Failure>型**を用いた処理や**do-catch文**などもあります。

エラー処理は、私自身よく理解できておらず正直なところ苦手です。

しかし、**コードを書く上では絶対に必要な処理**なので
備忘録がてら皆さんに共有できたらなと思います。

#Optional\<Wrapped>型によるエラー処理

ご存知かと思いますがOptional\<Wrapped>型は、
**値が存在するかどうか**を表現することができます。

Optional\<Wrapped>型はnilを許容するので、
値が存在する時は格納されている値を、存在しない場合はnilを返します。

エラー処理で使う場合は
**値が存在することを成功・存在しないことを失敗**とみなせば、
エラー処理の機構として成り立ちますよね、という話です。

これでしたら結構簡単そうです！

##実装方法

例えば、エラーが発生し得る関数であれば、
その戻り値をOptional\<Wrapped>型にすればエラー処理を行うことができます。

下記のサンプルコードでは、
引数のidに該当するインスタンスがあったらそのインスタンスを返しています。
なかった場合はnilが返ります。


```swift

struct User {
    var id: Int
    var name: String
}

// インスタンス化
let user1 = User(id: 1, name: "Tarou")
let user2 = User(id: 2, name: "Zirou")

// インスタンスを配列に格納
var users = [user1, user2]

// エラーが起きる可能性のある関数
// 引数のidに該当するものがなかったらnilを返す
func findUserById(id: Int) -> User? {
    for user in users {
        if user.id == id {
            return user
        }
    }
    return nil
}

// 値が存在する場合
if let user = findUserById(id: 1) {
    print(user.name)
} else {
    print("Error: User not found")
}

// 値が存在しない場合
if let user = findUserById(id: 3) {
    print(user.name)
} else {
    print("Error: User not found")
}

実行結果
Tarou
Error: User not found
```

Optional\<Wrapped>型を処理の成否に利用している例としては、
他にも**失敗可能イニシャライザ**などがあります。

次のサンプルコードでは、
引数のメールアドレスを二分割できない場合は
不正なデータとみなしてインスタンス化を失敗させています。

`let item = mail.split(separator: "@")`のitemは、
mailを二分割した時の２つの値が格納された配列です。

```swift

struct User {
    var name: String
    var mail: String
    
    init?(name: String, mail: String) {
        let item = mail.split(separator: "@")
        guard item.count == 2 else {
            return nil
        }
        self.name = name
        self.mail = mail
    }
}

let user1 = User(name: "Tarou", mail: "Tarou@gmail.com")
let user2 = User(name: "Zirou", mail: "Zirou.com")

var users = [user1, user2]

for user in users {
    if let user = user {
        print("Name: \(user.name)\nMail: \(user.mail)")
    } else {
        print("Error: Invalid data")
    }
}

実行結果
Name: Tarou
Mail: Tarou@gmail.com
Error: Invalid data
```

##利用するタイミング
利用するタイミングとしては、**値の有無だけで結果を十分に表せる場合です。**

先ほどのように、idで一致するものを検索する場合や
メールアドレスの形式がおかしくないかのチェックなどの単純なものは
Optional\<Wrapped>型でいいと思います！

ただ、id検索する際に、データベースに接続できなかったり
データが重複していたりなどと**エラーの種類を多くする**ことは恐らく難しいですね・・・。

なので失敗の原因に応じてメッセージを表示したり、
復旧の処理を行ったりするのであればOptional\<Wrapped>型では不十分です！

結論として、Optional\<Wrapped>型は単純なケースのみにしましょう！

また、冒頭で紹介した、
**Result\<Success, Failure>型**を用いた処理や**do-catch文**ですが、
別で記事にする予定なのでぜひご覧ください！

・[【Swift】Result\<Success, Failure>型でエラー処理を行う](https://qiita.com/onishiApp/items/76e66d1504fcf42a9136)
・[【Swift】do-catch文でエラー処理を行う(その1)](https://qiita.com/onishiApp/items/cba5e6c7361163d8931e)
・[【Swift】fatalError関数によるプログラムの終了](https://qiita.com/onishiApp/items/e6f8cd28fe2ea38ebb7a)
・[【Swift】アサーションによるプログラムの終了](https://qiita.com/onishiApp/items/66d65f7b56ae178b52b8)

最後までご覧いただきありがとうございました。
Goのnetパッケージを理解する～1日目～

# 12/27更新
[Goのnetパッケージを理解する～2日目～](https://qiita.com/Marny/items/b4d62a860cc1760d19fd)書きました

# はじめに

Goのパッケージの中でも、苦手意識しかないパッケージの一つである`net`パッケージの勉強をしていきます。

# netパッケージとは

`netパッケージは、TCP/IP、UDP、ドメイン名解決、UNIXドメインソケットを含むUnixネットワークソケットへのポータブルインタフェースを提供します。
`
引用：http://golang.jp/pkg/net

# とりあえずサーバの起動


```go:main.go
package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello World")
}
```

これで、8080番ポートにアクセスすると、`Hello World`と出力されるはずです

一旦、ここまでで、
ransack使用 検索機能実装

## はじめに
※すでにアプリケーションがある定で書いてます。

`rails`用の検索機能を実装する為のgemになります。
検索キーワードを元に紐付いたデータを取得
逆にキーワードが無い場合は全て取得する。

## 手順
Gemfileに`ransack`を記述して`bundle install`

```:Gemfile
gem 'ransack'
```

```:ターミナル
bundle install
```

次に
コントローラーに`ransack`を機能を利用する処理を書きます。

```:app/controllers/users_controller.rb
class UsersController < ApplicationController
  def index
    @q = User.ransack(params[:q])
    @users = @q.result
    #resultメソッドで結果を返します
  end
end
```
次に
ビューファイルに検索フォームを書きます。
`ransack`を使用した検索フォームは`search_form_for`というヘルパーメソッド を使います。

```:app/views/users/index.html.erb
<%= search_form_for @q do |f| %>
      <div class="d-flex">
        <div class="form-group flex-grow-1">
         #検索窓  
          <%= f.search_field :name_cont, placeholder: "〇〇を探す", class: "form-control" %>
        </div>
        <div> 
        #検索
        <%= f.submit "検索", class: "btn btn-primary ml-1" %>
        </div>
      </div>
    <% end %>
```
今回は「部分一致検索」が目的の為`カラム名_cont`にしています。
「一致検索」の場合は，`カラム名_eq` とします。

## 検索機能完成
検索機能ができました！
![ezgif-3-d2096169635d.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859347/49a733e1-aca7-419f-c568-5ce817655447.gif)

※Qiiteに動画のアップロード初めてでしたが、上手く行きました！
この記事には関係ありませんが参考になりました！:relieved:
https://qiita.com/bohebohechan/items/f8bf6d4bbe0f14497a7b
## 終わりに
ざっくりとした内容になりましたが、
結論画期的なgemを作って下さった技術者に感謝です！:joy:
Google AnalyticsでWebシステムの検索機能をライトに分析する

Google Analytics(以下GA)でWebシステムの検索機能をライトに分析する

###目的
**はじめに**
Webシステム内に設置されたサイト独自の検索機能で使われているキーワードをGAで分析したい。
独自の分析基盤で詳細な分析は可能であるが、汎用性が無く他システムへ展開しづらいといった課題があります。
そこでGAで検索機能をライトに分析できる状態にし手順化するとともに、他システムへの展開しやすい状態を作っていこうと思います。

**実現したいこと**
・キーワードランキングを作成する
　　→　どんなキーワードが頻繁に使われているのか、ニーズ・関心の高い情報の可視化

・特定の検索条件で集中的に離脱が発生していないか把握する
　　→　検索キーワードとしてニーズがあるのに、その検索キーワードで検索した結果、求める結果にたどり着けず離脱してしまっている。
　　　 そういった状況を可視化したい。



###前提

・検索条件がGETパラメータで取得できること
　　→　GAに送信されたアクセスURL中のGETパラメータから情報を抽出するため

・WebサイトとGAが連携済であること

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/464ed99b-7f4e-73fe-601c-a2ebd321c6fe.png)



###設定手順

####ビューの一番左下にある管理をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/56527c29-254a-af47-145f-006bd132e31d.png)

　
####管理→すべてのフィルタをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/b45d5195-ba67-85a3-dad4-d66654f5b6bc.png)

　
####フィルタを追加をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/18566c6d-9e58-a99f-1dcc-073e1b112a2a.png)


####カスタムフィルタを作成します
例えば『https://abeabetest/AzSearch?q=ロボット』といったようにqというクエリから値を取り出して集計したい場合
『/AzSearch\?q=([^&\.]*)』といった正規表現ルールを設定し、『/freeword/$A1』に置換します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/44742ebc-516a-0955-3a9d-5685e062ebfd.png)



####人気キーワードを確認してみる
行動 → 概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/e4439949-faca-550c-e757-221ba5ebccbc.png)




####人気キーワードを確認してみる
行動 → 概要
ページビュー数が対象キーワードが使われた回数です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/e4439949-faca-550c-e757-221ba5ebccbc.png)




####離脱キーワードを確認してみる
行動 → サイトコンテンツ　→　離脱ページ
離脱率でソートすると離脱の多いキーワードを抽出することができます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/524081/195aa38d-3729-9982-3522-a99dcc43345a.png)



###最後に
今回はライトに実現する方法で記事を書きましたが
次回はもう少し深ぼって、カスタムビューに欲しい情報を集約してみたいと思います。
イスラエル8200部隊出身のガチプロハッカーに、一流のハッカーになる方法について聞いてみた。

私がインターンで勤めている企業のハッカーは、イスラエル国防軍におけるサイバー攻撃・防御の超精鋭部隊、 **8200部隊出身のガチプロハッカー**です。8200部隊はアメリカのNSAと並んで世界最高のハッキング技術を持つと言われています。高校卒業後に兵役の義務があるイスラエルで、なんと彼は大学の学位を取り終えて、入隊したそう。

そんなスペシャルなハッカーに、東京大学で（一応）コンピュータ関係を専攻する私が、「**一流のハッカーになる方法**」について聞いてみたら面白かったので、本人の許可を得てその邦訳を記事にしてみました。

## イスラエルのハッカーエコシステム

> イスラエルの8200部隊について教えてください。

8200部隊はイスラエル軍における**インテリジェンスユニット**です。詳しい内容は秘密事項でお伝えすることはできませんので、Wikipediaなどを見ていただくのが早いと思います（笑）。主にサイバーセキュリティに関して色々やっています。

> どのような過程を経て入隊したのですか？

イスラエルでは男女ともに兵役の義務があり、高校卒業と同時に入隊します。自分は高校時代に大学の学位をあと少しのところまで取り終えていたので、軍に言って1年猶予してもらい大学の学位を取り終えてから入隊しました。

> 高校時代に大学の学位！？

はい、実は8200部隊に入隊する人の中ではそんなに珍しくない話です（笑）。大学が専用の特別なプログラムを用意していて、高校などで情報が回ってきます。同様のプログラムから8200部隊に入った、3年年上の先輩が熱心に勧めてきたことも大きかったです。

> 8200部隊に入隊するためにはどのようなステップを踏む必要があるのですか？

たくさんの**インタビュー**と**テスト**があります。論理的思考力に代表されるような一般的なスキルから、OSやネットワークなどの専門的知識まで色々と見られますね。プログラミングは教育過程で教えられるものではないですが、独学で小さい頃からやっていました。

> 入隊後はどのようなことをしていたのですか？

詳しい内容については同様に秘密事項なので言えません（笑）。ざっくり言うと、インテンシブコースがあり、そこでは一日中学習することになります。主に**プログラミング**のこと、**サイバーセキュリティ**のこと、コンピュータを含む**電子機器の仕組み**のことを扱います。個人のスキルに応じてとるプログラムが変わります。例えば、プログラミングがかなりできる人はプログラミング以外のことを重点的にやります。

> 競争が激しい感じですか？

いえ、どちらかと言うと**逆**です。そのコースでは**チームワークがかなり重要視されます**。基本的に与えられた課題はチームで解くことになります。これはもちろんgeek（いわばオタク）が多いからということもありますが、主に軍のような大組織で働く術を学び、また、様々な問題解決のアプローチを評価する経験を積むためだと思われます。


## ハッカーになるためにしたこと

> ハッカーになるために勉強したことなどを具体的に教えてください。

自分がサイバーセキュリティに興味を持ち始めたときは、大きく分けて2つのことをしました。一つは**学習**、もう一つは**練習**です。

まず学習についてですが、自分は**オンラインで学習**しました。今でさえ色々なコースがUdemyやYouTubeにありますが、当時はなかったのでTel Aviv University（訳者注：イスラエルの一流大学）がインターネット上に公開している授業を受けました。

次に練習についてですが、これは非常に重要な部分です。練習を経て初めて、実際のハッキングの方法論を体得し、習熟することが可能になります。とは言ってもハッキングの練習として、実際に会社や組織を攻撃することは違法なので、**ハッキングチャレンジ**や**バグバウンティ**をやるといいと思います。自分は部隊で積んだところは大きいと思います。

> ハッキングチャレンジやバグバウンティについて詳しく教えてください。

ハッキングチャレンジはその名の通り、ハッキングを試してみることです。有名なのは『[OverTheWire](https://overthewire.org/wargames/)』でしょうか。[このサイト](https://gist.github.com/numberwhun/d85075f4f63411bafa1c6e40e15e4c4b)とかも参考になりますね。

バグバウンティは大企業や大きな組織がそのシステムのバグを発見したら報酬を支払うというようなプログラムです。GoogleやMicrosoftのような企業が独自に開いたりしていますね。

> ハッキングの大会への参加などは？

それもいいと思います。CTF（訳者注：Capture The Flag）とかですよね。自分も同僚のハッカーチームの準備を手伝ったことがあります。ただし、参加するのは既に実経験のあるハッカーが多いですね。日本からも何チームか出ているとは思いますが...


## 一流のハッカーになるには

> 一流のハッカーになる要件などは何だと思いますか？

うーん、個人的には3つあると思います。

1つ目は**問題解決能力**です。論理的に、数学的に問題を解くような力が非常に重要です。具体的には、より多くのプログラミングの問題や数学の問題を解いていくといいと思います。もちろん先ほど言ったように、これは8200部隊入隊の要件と通じているとは思います。

2つ目は**ハッキングのプロセスについて習熟すること**です。ハッキングは情報の分析、脆弱性の洗い出し、脆弱性を利用した攻撃（エクスプロイト）の3パートがあります。これを完全に習熟し、使えるようになっていることが重要です。

3つ目は**トライアンドエラーをするマインドセット**です。ずっと机上で考えるよりもとりあえず試してみる方が経験上ずっと得です。それは問題解決しかり、ハッキングの経験しかりです。こういうのを英語ではhandsonと言いますね。


## 新人ハッカーへのアドバイス

> 新人ハッカーへのアドバイスをどうぞ？

とりあえず始めましょう。ハッキングチャレンジでもなんでも構いません。それがハッカーがどう考え、どう行動するかを知る最善の方法だと思います。がんばって！


## 終わりに

ハッカーになる方法は、AIエンジニアやWebエンジニアになる方法と比べて日本語の文献数が少なく、中々具体的にイメージしにくいのではないでしょうか。本記事がそのような方々にとって、有益なものとなれば幸いです。この記事良かったなと思った方は、ぜひLGTMお願いします。（LGTMが多ければ、続編も書くかもしれないです。）また、弊社のサービスに少しでもご興味を持っていただけたら、[こちらのリンク](https://aironworks.com)から弊社HPをご覧ください。ちょっとしたご相談でもフォームにご記入くださると、ご返信できると思います。
[iPhone12まで]ステータスバー・セーフエリアトップ・ナビゲーションバーのサイズ一覧

|  | ナビゲーションバー高さ | ステータスバー高さ | safeareaInsets.top |
| ------ | ------ |------ |------ |
| iPhone12mini | 44 | 44 | 50 |
| iPhone12 | 44 | 47 | 47 |
| iPhone12Pro | 44 | 47 | 47 |
| iPhone12ProMAX | 44 | 47 | 47 |
| iPhone11 | 44  | 48 | 48 |
| iPhone11 Pro | 44 | 44 | 44 |
| iPhone11 Pro Max | 44 | 44 | 44 |
| iPhoneX | 44 | 44 | 44 |
| iPhoneXR | 44 | 44 | 44 |
| iPhoneXS | 44 | 44  | 44 |
| iPhoneXS Max | 44 | 44 | 44 |
| iPhoneSE | 44 | 20 | 20 |
| iPhone8 | 44 | 20 | 20 |
| iPhone8 Plus | 44 | 20 | 20 |

### 要約

- ナビゲーションバーの高さは全て同じで44ptになっています。

- ステータスバーは、ノッチ付きの端末(iPhone X以降)だと、それ未満の端末より大きく、40pt台となっています。特にiPhone12系で変化が不規則なので注意が必要です

- iPhone 12 miniでのみ、余白があることによりステータスバーの高さでは正しい距離が取れなくなってしまいました。`UIView`の`safeAreaInsets.top`を使うと正しい距離が取れます。
   - ただし親である`UIViewController`の`viewWillLayoutSubviews`が呼ばれるまでは値が0になっているので待つ必要があります。また `viewWillLayoutSubviews`は何度でも呼ばれる可能性があるので注意してください。
   - `UIWindow`の`safeAreaInsets.top`を使ってもいいと思います（`UIWindow`は`UIView`のサブクラス）。これを使って高さを取得する一例は以下になります。

```swift:
        var safeAreaTopInsets: CGFloat
        if #available(iOS 11.0, *) {
            if let topInsets = UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.safeAreaInsets.top, 
                topInsets > 0 {
                safeAreaTopInsets = topInsets
            }
        } else {
            safeAreaTopInsets = UIApplication.shared.statusBarFrame.size.height
        }
```

以下のようなextensionを作るとやりやすいかと思います。

```swift:.UIView+StatusBarHeight.swift

import Foundation

extension UIView {
    /// ステータスバーの領域の高さを返す。UIApplication.shared.statusBarFrame.size.heightでは、iOSバージョン・端末の種類によっては正しい値を取れないことがあるためこれを用いる。
///  https://qiita.com/satoru_pripara/items/73f4ae47fa2726332e95
    var statusBarAreaHeight: CGFloat {
        var statusBarHeight: CGFloat
        if #available(iOS 11.0, *) {
            //iOS11, iPhone8 or iPhone8 plus でsafeAreaInsets.topが0になる事がある
            statusBarHeight = (safeAreaInsets.top > 0.0) ? safeAreaInsets.top : UIApplication.shared.statusBarFrame.size.height
        } else {
            statusBarHeight = UIApplication.shared.statusBarFrame.size.height
        }
        return statusBarHeight
    }
}
```

### 参考

[[iOS] iPhone12 miniでStatusBarの高さ取得が期待した動作をしないのと対策](https://qiita.com/t_osawa_009/items/4ceecca0740758be0f84)
[【iOS】safeAreaInsetsの値が取得できるタイミング](https://qiita.com/hituziando/items/e5873b5bfa42247071e6)
[How to resolve: 'keyWindow' was deprecated in iOS 13.0](https://stackoverflow.com/questions/57134259/how-to-resolve-keywindow-was-deprecated-in-ios-13-0)
【Java】プログラムを一時停止するThread.sleepの使い方

#プログラミング勉強日記
2020年12月23日
Android StudioでAndroid開発をしていて、音楽を一定時間流してその後一時停止するプログラムを書いたときにThread.sleepを使ったので、その使い方を簡単にまとめる。

#スレッドとは
　スレッド(Thread)は処理の実行単位の一つで、プログラムの初めから終わりまでの一連の流れのことをいう。スレッドにはシングルスレッドとマルチスレッドがある。

　シングルスレッドは、直列処理とも呼ばれている。プログラムの始まりから終わりまでが一本で処理される。
　マルチスレッドは、並行処理とも呼ばれている。2つ以上の処理を並行して行う。マルチスレッドを利用するためには、4つのステップが必要である。

1. Threadクラスを継承するクラスを作成
2. Threadクラスを継承するクラスでrunメソッドを実行する
3. Threadクラスを継承するクラスのインスタンスを生成する
4. 生成したインスタンスに対してstartメソッドを実行する


#sleepメソッドとは
　sleepメソッドは、プログラムを一時停止するときに使用する。マルチスレッドで良く用いられる。
　sleepメソッドを使用するメリットとしては、マルチスレッドで無限ループを実行していた場合、CPUの負荷が大きくなりパソコンの動作が重くなる要因になる。そういったときに、マルチスレッドの処理中にsleepメソッドを使用して、処理を一時停止すればCPUの負荷を抑えられる。


#Thread.sleppの使い方
　sleepメソッドを使うにあたってポイントは2つだけ！

- sleepメソッドの引数は、long型を使い、単位はミリ秒(1秒 = 1000ミリ秒)
- sleepメソッドを使うときには必ず例外処理をつける

```java
public class Sample {  
     public static void main(String[] args) {
        try {
            // 5秒間一時停止する
            Thread.sleep(5000);
        } catch(InterruptedException e){
            e.printStackTrace();
        }      
    }    
}
```

##マルチスレッドでsleepメソッドを実行する

```java
public class ThreadSample {
 
    public static void main(String[] args) {
        MultiThread1 mt1 = new MultiThread1();
        MultiThread2 mt2 = new MultiThread2();
        mt1.start();
        mt2.start();
    }
}
 
class MultiThread1 extends Thread {
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
 
class MultiThread2 extends Thread {
    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
```

#参考文献
[Javaでプログラムを一時停止、Thread.sleepの使い方と仕組みを解説](https://engineer-club.jp/java-sleep)
[【Java入門】Threadをsleepメソッドで一定時間停止する方法](https://www.sejuku.net/blog/21767)
ハッシュロケットからシンボル型へ変更

#ハッシュロケットからシンボル型へ変更する時に悩んだ話。

記述の仕方は合ってるのになんでsyntaxエラー出るんだ！となやみました。

（記述が間違ってたからなんですけど・・・😂）

ということで備忘録です！

##ハッシュロケットとシンボル型の書き方
ハッシュロケット
{:sample => 'value'}　　

シンボル型
{sample: 'value'}

こんな感じですね。
シンボルで書いた方が重くならないのでこっちで書こうね！ってなってる様です。

###本題
＜syntaxerrorが出てた記述＞

days = {month : (@todays_date + x).month, date : (@todays_date+x).day, plans : today_plans}

＜errorが消えた記述＞
days = {month:(@todays_date + x).month, date:(@todays_date+x).day, plans:today_plans}

【問題箇所】
: の左右に半角スペースが入っていた。

まさにこの半角スペースのせいでerrorが消えなかったんです。。おそろしや半角スペース。。

####結論
無駄な半角スペースに気をつけよう！！ってことですね。頑張ります。
【mac】PythonでRealSense D415のサンプルを動かす

# RealSense D415とは
Intel社の提供するRealsenseは奥行き知覚機能を有するカメラデバイス．公式ではmacのサポートをしていないが，librealsenseという非公式のライブラリで動かすことができる．

# 環境
 - macBookPro(13-inch, 2017, Twoo Thunderbolt 3ports)
 - macOS Catalina 10.15.7
 - zsh
 - Homebrewインストール済
 - PyenvでPythonの環境構築済

# 環境構築手順
## 必要なライブラリをインストール
ターミナルを開きホームディレクトリで以下のコマンドを一行ずつ実行する

```shell:ターミナル
$ brew install python
$ brew install libusb pkg-config
$ brew install homebrew/core/glfw3
$ brew install cmake
$ brew install boost
$ brew install flann
$ brew install vtk5 –with-qt
$ git clone https://github.com/PointCloudLibrary/pcl
$ cd pcl
$ mkdir build && cd build
$ cmake ..
$ make
$ sudo make install
```

## librealsenseのソースコードをインストール&build
`cd`コマンドでホームディレクトリに戻り，librealsenseの本体をインストールする
3行目の`使用しているPythonの絶対パス`の部分は`which python`で出力されたパスに置き換える

```shell:ターミナル
$ git clone https://github.com/IntelRealSense/librealsense.git
$ cd librealsense
$ mkdir build && cd build
$ cmake .. -DBUILD_EXAMPLES=true -DBUILD_WITH_OPENMP=false -DHWM_OVER_XU=false -DBUILD_PYTHON_BINDINGS=true -DPYTHON_EXECUTABLE:FILEPATH=使用しているPyhtonの絶対パス -G "Unix Makefiles"
$ make -j2
$ sudo make install
```

私の環境ではPythonのバージョンが3.8系では動かなかったため事前に3.6系へバージョンを変えておく(今回はpython3.6.7を使う)
`/libresense`ディレクトリに戻り

```shell:ターミナル
$ pyenv install 3.6.7
$ pyenv local 3.6.7
```

`pyenv versions`コマンドで`/libresense`ディレクトリ以下がpython3.6.7になっていることを確認する
また，このままだと動かないと思うので以下の手順でsoファイルがおいてある場所(以下A)を確認する
> 
1. VSCode等で`librealsense/build/CMakeCache.txt`を開く
2. `command + F`で検索窓を開き`PYTHON_INSTALL_DIR:PATH`を検索する
3. `PYTHON_INSTALL_DIR:PATH:PATH=xxx`とかいてある.xxxがsoファイルの置いてあるディレクトリ(A)

シンボリックを置く場所(以下B)を確認する

```shell:ターミナル
$ python3
>>>import site; site.getsitepackages()
```

その後確認した場所(B)へ移動し，シンボリックを作成する

```shell:ターミナル
$ cd Bへの絶対パス
$ ln -s 確認したsoファイルのパス(A)/pyrealsense2.cpython-36m-darwin.so pyrealsense2.so
$ ln -s 確認したsoファイルのパス(A)/pybackend2.cpython-36m-darwin.so pybackend2.so
```

`pyrealsense2`のインポートが通るか確認

```shell:ターミナル
$ python
>>> import pyrealsense2
>>>
```
このように`import`が通ればOK

## サンプルを動かす
macとRealsenseをUSB接続し，サンプルファイルが置いてあるディレクトリに移動し実行する

```shell:ターミナル
$ cd ~/librealsense/wrappers/python/examples
$ python 動かしたいファイル名
```

---
参考
(参考Qiita1)[https://qiita.com/mizumasa/items/c6ca2c73fa86c9a5a39c]

(参考Qiita2)[https://qiita.com/comachi/items/14b358568365bc5ee474]
ポストクッキー時代のアドテク業界はどう変わる？

こんにちは、[アルファアーキテクト](https://alpha-architect.co.jp/recruit/)でVPoEの胡 恩召（Ethan Hu）です。

まもなく2020年が終わります。新型コロナウイルス感染症拡大により大変な一年になりましたね・・・。そんな中、アドテク業界では、「クッキーレス」が一番HOTな話題となりました。

# クッキーとは

ユーザーがウェブサイトをアクセスする際に、一時的にブラウザに保存されるデータのことです。クッキーの使い方の１つとして、ランダム生成した文字列をIDとしてブラウザに保存し、ユーザーを識別するために利用します。クッキー保存をクッキー発行とも表現します。ウェブサイト自体が発行したクッキーをファーストパーティークッキー（1st Party Cookie）と呼び、第三者の会社が発行したクッキーを、サードパーティークッキー（3rd Party Cookie）と呼びます。

| 項目 | 1st Party Cookie | 3rd Party Cookie | 
| :-----| :---- | :---- |
| Cookie発行会社 | ウェブサイト運営会社 | 第三者の会社 |
| Cookieで管理する情報範囲 | サイト内での行動情報だけ | クロスサイトを通じて横断的に管理可能 |
| Cookieによるユーザー側のメリット | ログイン、買い物カゴなど情報を保存出来る | より興味にあった広告を表示されやすくなる |
| 企業側でのCookie活用方法 | 会員を登録しなくても、サイトの訪問履歴を確認・分析出来る | クロスサイトを通じてユーザーの行動履歴を確認・分析出来る |

ファーストパーティークッキーとサードパーティークッキーの一番大きな違いは、サードパーティークッキーはクロスサイトを通じて横断的に管理出来ます。そのため、広告配信サービスは、ほとんどサードパーティークッキーを使って、ターゲティングや広告効果などを利用されてる。ということです。

# 個人情報の規制強化とクッキーレス

数年前から、各国での個人情報規制を強化する動きが加速している：

* 2018年5月：欧州でGDPR（一般データ保護規則）が適用
* 2020年1月：米カリフォルニア州でCCPA（消費者プライバシー法）が発効
* 2020年3月：日本の個人情報保護法の改正案が発表

上記の規制強化を踏まえ、関係IT会社のサービスの対策も発表された：

* Safari：2018年9月より、ITP 2.0即時3rd Party Cookieを削除
* Firefox：2019年6月より、3rd Party Cookieをデフォルトブロック
* IDFA：2021年より、IDFAをデフォルトオフ
* Chrome：2022年より、3rd Party Cookieサポートを終了

サードパーティークッキーを利用できなくなり、クッキーレス時代が来るとともに、アドテク業界では、主に3つの影響を受けます。1つ目は、クロスサイトのトラッキングは、出来なくなります。2つ目は、ユーザーが興味を持ちそうな広告配信のターゲティング手法が利用出来なくなります。3つ目は、上記の1と2が原因で、ユーザーの分析やレポーティングが難しくなります。


# アドテク業界の動き

アドテク業界、クッキーレスの対策は、主に下記のアプローチがあります。

まずは、オーディエンスターゲティングからIPターゲティングやキーワード・コンテキストターゲティングなど手法へ切り替えることです。

次に、ユーザーIDを統合して、クッキーの代替識別子「共通ID」を開発していくことです。
ファーストパーティークッキーデータを連携しながら、機械学習など確率推定手法も使い、ユーザーIDを判別し、特定のユーザーを識別します。業界は、IABのDigiTrust ID、LiveRamp社のIdentityLink、 theTradeDesk社のUnified IDなど統合IDソリューションがあります。

最後に、ファーストパーティークッキーデータを連携して行くことです。データ連携のソリューションは、CDP（Customer Data Platform）とCMP（Consent Management Platform）があります。CDPはカスタマーデータプラットフォームです。顧客一人ひとりの属性データや行動データを収集・蓄積・統合するためのデータプラットフォームです。CMPは同意管理プラットフォームです。パブリッシャーはCMPを使い、ユーザーから使用範囲と使用目的について同意を得たデータを収集、保管して、デジタル広告のパートナーにそのデータを提供します。


# まとめ

クッキーレスに対する各社の対応は、まだ模索中な印象ですが、クッキーレス時代におけるアドテク業界の大きな方向転換は、データ利用の透明性の確保やプライバシーに配慮する上で、ユーザーに広告を配信することが必要です。

アルファアーキテクトは現在IPOを目指しています。『VeleT』の発展を加速させるため、 現在[インフラエンジニア](https://alpha-architect.co.jp/935/)、[バックエンドエンジニア](https://alpha-architect.co.jp/939/)、[テックリード](https://alpha-architect.co.jp/384/)などを積極的に募集しています。動画広告サービス『VeleT』の開発を一緒に推進してくれる方、是非応募をお待ちしています！


# 参考資料

* [Cookie規制にマーケターはどう向き合うべきか？](https://markezine.jp/article/detail/33095)
* [ファーストパーティークッキーについて、理解していますか？](https://ad-ron.jp/?p=13985)
* [1st party Cookieと3rd party Cookieの違い](https://www.videor.co.jp/digestplus/market/2018/11/12437.html)
* [ポストクッキー時代の前提知識を図説](https://rtbsquare.work/post_cookie)
* [ポストクッキー時代のデータ活用はどう変わる？](https://markezine.jp/article/detail/34820)
* [ポストCookie時代に重要となる、5つのソリューションとは？](https://markezine.jp/article/detail/34688)
* [ポストクッキー時代におけるデジタルプライバシー](https://mightyhive.com/wp-content/uploads/2019/09/Digital-Privacy-in-a-Post-Cookie-World.pdf)
* [ポストクッキーをめぐるマーケターの現状：要点まとめ](https://digiday.jp/brands/cheatsheet-marketers-planning-post-cookie-digital-media/)
アドベントカレンダー21日目：SREを読んでみた「リリースエンジニアリング」編①

今回から新しい章に入ります。
内容はリリースエンジニアリングになります。
（最初リリースエンジニアリングをリバースエンジニアリングだと誤読してました。）

## リリースエンジニアリングとは
リリースエンジニアリングは、最近急速に成長している比較的新しい分野であり、ソフトウェアのビルドとリリースを行います。
リリースエンジニアは、以下について、しっかりと理解していなければなりません。

* ソースコード管理
* コンパイラ
* ビルド設定言語
* 自動ビルドツール
* パッケージマネージャー
* インストーラ

また、リリースエンジニアのスキルセットには、開発、設定管理、テストの統合、システム管理、カスタマーサポートといった、複数の領域に関する深い理解が必要です。
そして、ソースコードからデプロイメントに至るプロセスに注意を払わなければなりません。
リリースエンジニアは、プロダクト開発に関わりながら、SREとリリースに関する規定を行います。

## 哲学
リリースエンジニアリングは、4つのエンジニアリングとサービスの哲学があります。

* セルフサービスモデル
Googleのリリースエンジニアは、あらゆるリリースプロセスを網羅したツールとドキュメントを作成しています。これらを使い、チームそれぞれが新バージョンのリリース頻度と時期を規定します。
リリースプロセスは、エンジニアの作業が最小限で済むところまで、自動化可能です。
リリースは完全に自動化され、問題が起きた場合のみリリースエンジニアが対応します。

* 高速化
Googleでは、ユーザーが利用する機能をできるだけ早くリリースするという方針を持っています。これは、リリースを頻繁に行うことでバージョン間の変更を少なくするという考えを持っているからです。
リリースを行うチームの中には1時間ごとにビルドを行い、その中から本番環境へデプロイするものを選んでいるチームやすべてのテストにパスしたものをすべてリリースしているチームもあります。

* 密封ビルド
ビルドツールは、一貫性と再現性を担保する必要があります。
googleのビルドは密封型でビルドマシンにインストールされているライブラリやその他のツールに影響を受けません。代わりにビルドはコンパイラやライブラリの依存関係のバージョンまで指定されます。ビルド環境は自己完結している必要があります。
もし、バグが発生し、それを修復する場合は、オリジナルのビルドの修正をチェリーピックし、それを含めた上でオリジナルの再ビルドをします。この時、新しいバージョンのコンパイラなどは使用しません。新しいコンパイラに互換性がない機能や必要のない機能が含まれているかもしれないからです。

* ポリシーと手順の強制
Googleにおいて、コードベースの変更は、ほぼすべてコードレビューが行われます。
これは、開発ワークフローの中に組み込まれています。自動化されたリリースシステムによって、リリース中に含まれるすべての変更に関するレポートを生成します。これにより、問題があった際の対応の速度が向上します。

##まとめ
* リリースは、一貫性と再現性を担保しなければならない。
* 高速なリリースの為に、自動化を行う

#### 参考文献
1. Betsy Seyerほか　SRE サイトリライアビリティエンジニアリング　オライリー　91-94
画像、PDFをPDF化

画像やPDFを1つのPDFにする

tcpdfとfpdiを使用。

jpgやpngなどの画像をPDF化するならtcpdfのみで可能ですが
PDFをPDFにマージするなどもしたい場合はfpdiも必要。

fpdiはtcpdfまたはtfpdfの拡張機能としても使用できるので
fpdiをインストールして、tcpdfの機能を使いたかったらtcpdfもインストールする、
という認識です。

## インストール

```
composer require tecnickcom/tcpdf
composer require setasign/fpdi
```

## 処理

```php
<?php

namespace App\Services\Hoge;

use setasign\Fpdi\Tcpdf;
use File;
use Utils;

class HogeService
{
    public function createPdf(string $id)
    {
        // ファイル取得
        $files = Utils::getAllFiles('hoge', $id);

        $maxsize = 550;
        $tcpdf = new Tcpdf\Fpdi('p', 'px', 'A3');
        $tcpdf->SetPrintHeader(false);
        $tcpdf->SetPrintFooter(false);

        foreach ($files as $file) {
            $extension = File::extension($file);
            $file_path = storage_path('app') . '/' . $file;

            if ($extension == 'pdf') {
                $pageCnt = $tcpdf->setSourceFile($file_path);

                for ($i = 1; $i <= $pageCnt; $i++) {
                    $tcpdf->addPage();
                    $tcpdf->useTemplate($tcpdf->importPage($i));
                }
            } else {
                $tcpdf->AddPage();

                // @NOTE:フルパスでないとセットしてくれない
                // 第5引数大文字でないとセットしてくれない
                $img_size = getimagesize($file_path);
                $set_size = ($img_size[0] >= $maxsize) ? $maxsize : $img_size[0];

                $tcpdf->Image(
                    $file_path,                                // 画像ファイル名
                    5,                                         // 領域左上のX座標
                    5,                                         // 領域左上のY座標
                    $tcpdf->pixelsToUnits($set_size),          // 領域の幅 [指定しない場合、自動計算される]
                    0,                                         // 領域の高さ [指定しない場合、自動計算される]
                    strtoupper($extension),                    // 画像フォーマット
                    '',                                        // AddLink()で作成したリンク識別子
                    '',                                        // align
                    ($img_size[0] >= $maxsize) ? true : false, // resize
                    300,                                       // dpi
                    '',                                        // palign
                    false,                                     // ismask
                    false,                                     // imgmask
                    0,                                         // border
                    false,                                     // fitbox
                    false,                                     // hidden
                    false,                                     // fitonpage
                    false,                                     // alt
                );
            }
        }

        $pdf_path = storage_path('app') . "/data/hoge/$id/hoge_$id.pdf";
        // 保存
        $tcpdf->output($pdf_path, 'F');
    }
}
```
第五回：入出力



# 出力

rubyでは下記のメソッドによりStringsを出力することができる．

| メソッド|               |
|:-----|:--------------|
| print| 改行の必要あり|
| puts | 自動で改行    |
| p    | コーディング中のデバッグ代わり|
| pp   |               |
| printf|               |

上記を基にHello world.を出力するコーディングをする．

```ruby
$ emacs puts_hello_world.rb
```

でemacsを開きコーディングする．

```ruby
puts 'Hello world.'
```

```
$ ruby puts_hello_world.rb
```

実行してみると以下のように出力される．

```
hello world.
```


# 入力

出力ができるようになったので、

```
$ ruby puts_hello_name.rb Ruby
```

と実行したら下記のように出力されるコードを作成する．

```
Hello Ruby
```


## 入力するためには

ARGV[0]を用いる．ARGV[0]には既に用意されている引数である．

ARGV[0]を用いてHello Rubyと表示させるためには，以下の方法がある．

| 出力メソッド| コード                       |
|:-----|:-----------------------------|
| puts | puts"Hello" + ARGV[0]        |
| puts | puts "Hello #{ARGV[0]}"      |
| print| print "Hello #{ARGV[0]}\n"   |
| print| print "Hello" + ARGV[0] + "\n"|
| printf| printf(Hello %s)\n", ARGV[0] |

上記のコードを

```
$ emacs puts_hello_name.rb
```

でemacsにて作成する


# 出力先の変更

出力先をテキストファイル(puts\_hello\_name.txt)にしたい場合，以下のように実行を行う．

```
$ ruby puts_hello_name.rb Ruby > puts_hello_name.txt
```

'>'により出力先を指定することが出来る．テキストファイルの中身を見るには，

```
$ cat puts_hello_name.txt
```

を行うことで，テキストファイルの中身を確認できる．


# 参考サイト

参考にしたサイトは以下の通り。

-   <https://qiita.com/daddygongon/items/1b0f0ff3fb9d60418289>



------
 - **source** ~/grad_members_20f/members/yuhsuzu/r5.org
Kicadで基板の3Dデータを取り込む

# 基板を基板に
## 1,	前置き
実際にやることはこんな感じです。このようにほかの基板を別の基板に読み込ませることができます。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/2f9ed63b-6799-1d73-321f-0a5e6706045b.png)

　これを使えばモジュール化された基板をマザーボードに刺すことがkicad内でできます。モタドラのシールドをkicad内で確認することによって干渉するかなどを見ることができます。
 
## 2,	基板を３Dデータへ
基板の３Dデータを出力します。この時.stepではなく.wrlという形式で保存します。なぜなら.stepではシルクや銅箔などが出力されないからです。

| .step | .wrl |
| -------- | -------- |
| ![2-0-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/83f3c60b-6b4e-2cf7-99f0-6ceadd695f31.png) | ![2-0-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/6eb215a7-1fde-3439-8af1-3f38c7f387ec.png) |
### ①	[ファイル]> [エクスポート]> [VRML]を選択します
![2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/54d1164f-4214-d9c8-91f4-b9ccac6b6ed0.png)

### ②	各種設定・出力を行う。
ファイル名：各自好きな場所を指定してください。３Dデータ用のフォルダを作るの推奨。
出力単位：**0.1 inchに設定**デフォルトはメートルになっているので注意
後はOKボタンを押して出力完了
# **0.1 inchに設定**です！間違えないように
![2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/a85aa338-889a-84e2-9188-03e10d7d568c.png)

### 基板の場所
部品を出力するときに原点の近くに基板を置くことをお勧めします。
基板の端やパッドの中心などがお勧めです。
基板の位置が100とかになってると3d出力した時に基板が見当たらない原因となります。
![2-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/07b36940-4c69-1142-6ef5-12d1727e6226.png)

## 3,	部品として作る
### ①	フットプリントを作ります。詳しくは[こちら](https://qiita.com/mapletree/items/9ccd32f715954f5c26b1)
必要な分のパッドを配置します。
 ![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/a366880c-be34-2c64-e93f-41b2622d3e94.png)

 
### ②	ソケットを割り当てて、各種パラメータの設定を行います。
 ![3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/e7c4a90c-f436-78e4-c674-c955704f139b.png)
 
### ③	２－②で出力した３Dデータを読み込みます。
 ![3-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/12d922c9-3c2b-8bc3-fc8c-89567404aabd.png)
 
### ④	各種設定を行います。
これは基板の大きさや作ったフットプリントによって値が変わってしまうため毎回設定してください。
スケール：そのまま
回転：必要に応じて設定
オフセット：ｘとｚはちゃんと計算して出す。ｙは適当。
 ![3-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/ce1bdbc6-f8f0-22cb-7be9-a4b2b66f2ab4.png)
 
### ⑤	別の基板に作ったフットプリントを追加して完了！
 ![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679930/2f9ed63b-6799-1d73-321f-0a5e6706045b.png)
AWS RDS（mysql）のメジャーバージョンアップでパフォーマンス劣化にハマった話

先日、某運用サービス環境（商用です...）のデータベース（MySQL）のバージョン5.5がサポート終了なる死刑宣告を受け急遽、エンジンのメジャーバージョンアップを行うこととなりました。

商用サービスですので、まずは軽く各メジャーバージョンの仕様変更ポイントを確認、検証向けの環境で予行演習と動作検証を行いました。

疎通と端末アプリに特異動作はみられず、DBのバイタルにも特に問題が見られなかったため、商用適用作業は完了。

しかし数日後、特定の画面表示タイミングで大幅なパフォーマンス劣化が報告され調査開始。

サーバモジュール、端末アプリ双方には特段異常を確認できず、クラウド上の管理コンソールに出力されるスロークエリにも特に出力なし...

念のためDBにターミナル接続しスロークエリを直接確認したところ、ポロポロと軒並み5秒以上コストがかかっているクエリを特定しました。
実行計画をexplainコマンドで確認すると、インデックスの使われ方、結合順に以前と明らかな差分。
テーブルのデータ断片化解消や統計情報の再計算にとる実行計画の変化、そもそものインデックスの貼り方などをチェック、検証しました。

参考）https://techblog.yahoo.co.jp/entry/2020052530001949/

そうこうしても実行計画には特に変化なし、、そしてオプティマイザ周りの情報を収集しているうちに、、見つけました ... optimizer_switch の　「condition_fanout_filter」と「deriverd_merge」。
※ deriverd_merge の公式説明から実行計画の変化をイメージするのは難しい… X-(

https://vidaisuki.hatenablog.com/entry/mysqlcasualadventcalendar20171213

結論）インデックスの貼り方、表の結合方法、オプティマイザ周りの仕様変更には気をつけて。

以上です。
Reactのプロジェクトにexlint-config-airbnbを導入する

## きっかけ

普通のeslintを入れるよりも、exlint-config-airbnbを入れた方が、コードの規約が厳しいので、可読性が上がるとのこと。

https://speakerdeck.com/watanabeyu/du-miyasuikodofalseshu-kifang-falsesusume?slide=11

## 前提

create-react-appで作成したプロジェクトに導入します。

## 導入

必要なパッケージをインストールする。

```shell
$ npm i -D eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react
```

`.eslintrc`をプロジェクトディレクトリの直下に作成し、以下のように記述する。

```
{
  "extends": "airbnb"
}
```

以上で導入は完了。

## propsを型チェックする

以下のようなコンポーネントがあった時、

```jsx
import React from 'react';

const Title = (props) => (
  <h1>{props.title}</h1>
);

export default Title;
```

propsの型をチェックしていないので、ESlintに怒られてしまう。

まずは、以下のようにpropsを受け取るようにする。

```js
  const {title} = props;
```

受け取ったら、`prop-tyoes`で型をチェックする。

パッケージをインストール

```shell
$ npm i -S prop-types
```

以下のような形で、型をチェックする。

```jsx
import React from 'react';
import PropTypes from 'prop-types';

const Title = (props) => {
  // 追加
  const { title } = props;
  return (
    <h1>{title}</h1>
  );
};

// 追加
Title.propTypes = {
  title: PropTypes.string.isRequired,
};

export default Title;
```

## 参考

https://qiita.com/sugx2/items/ed58605e4e12519876fd
https://ja.reactjs.org/docs/typechecking-with-proptypes.html
https://speakerdeck.com/watanabeyu/du-miyasuikodofalseshu-kifang-falsesusume