OmniAICreator/Qiita-1.07M huggingface dataset:
【新サービス】AppRunnerの留意点

## AppRunnerについて
App Runnerの基本的な説明に関しては既に良い記事がありましたので、紹介させて頂きます。

https://iselegant.hatenablog.com/entry/2021/05/19/142254

<br>

**かなり便利そうなサービスなのですが、いくつか留意点を紹介します。**

##プライベートサブネット内のリソースにアクセスできない
FARGATEではサービス単位やタスク単位でVPCやセキュリティグループの設定ができますが、
AppRunnerではそもそもVPCと紐づける設定が存在しない為、プライベートサブネット内のリソースにアクセスできません。
プライベートサブネット内のDBにアクセスできないのがやはり痛いと思います。
プライベートサブネット内のリソースへのアクセスはAppRunnerのロードマップでも１番要望が大きいようです。

https://github.com/aws/apprunner-roadmap/projects/1

##VPC内のAWSリソースからAppRunnerにアクセスする際にインターネットへトラフィックを露出してしまう
こちらはVPCエンドポイントを設定することによって回避できそうです。S3などと同じですね。

https://docs.aws.amazon.com/ja_jp/apprunner/latest/dg/security-data-protection-vpce.html

##タスク定義を管理できない
ECSではタスク定義を管理することにより、DockerComposeのような事が可能でしたが、AppRunnerには今のところそのような機能はありません。そのため、コンテナの環境変数を変えたい場合は最初から設定し直す必要がありそうです。

##カスタムドメインを使用する際、既に取得したサーバー証明書を流用できない
FARGATEを使用する場合、ACMなどで取得したサーバ証明書をロードバランサーに設定することでhttpsを有効化できました。しかしAppRunnerでは証明書の設定ができない為、カスタムドメインを使用したい場合はAppRunnerのコンソール画面からカスタムドメインを登録し、再び検証用のレコードを作成する必要があります。その為、ワイルドカードを含めた証明書を流用して手間を省く、といったような事もできなさそうです。
<br>
# まとめ
いくつか留意点を挙げましたが、VPC、サブネット、ロードバランサー、ターゲットグループなどの事を考えずにスケーラブルにコンテナをデプロイする事ができるのは強力なサービスだと思います。ロードマップを見る限りプライベートサブネット内のリソースへのアクセスもいずれ可能になりそうです。AWSでコンテナを扱う際の標準的なサービスになる日も近いのではないでしょうか。
【Rails】link_toにFontawesomeを適用する方法

#概要#
`link_to`を用いた場合にFontawesomeを適用させる方法を説明します。

#開発環境#
・データベース：PostgreSQL
・railsのバージョン：6.1.3.2
・Bootstrap：4.5.1
・PC：macbook pro

#目標#
下記画像のように編集と削除にFontawesomeを適用させます。

**変更前**
![スクリーンショット 2021-05-27 3.56.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521366/52931c02-c6ad-4512-4681-d2a31ecdc737.png)

**変更後**
![スクリーンショット 2021-05-27 3.56.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521366/9a862488-e041-00a4-2207-fb1b8fc8707e.png)

##ポイント##
`<% link_to 〜 %>`の末尾に`do`を入れて`ブロック化`することがポイントです。

#コード#

```erb:変更前
<% @memos.each do |memo| %>
  <p>
    <%= memo.title %>
    <%= memo.body %>
    <%= link_to "削除",memo_path(memo), method: :delete, data: {confirm: "削除しますか?"} %>
    <%= link_to "編集",edit_memo_path(memo) %>
  </p>
<% end %>
```
```erb:変更後
<% @memos.each do |memo| %>
  <p>
    <%= memo.title %>
    <%= memo.body %>
    <%= link_to memo_path(memo), method: :delete, data: {confirm: "削除しますか?"} do %>
      <span class="far fa-trash-alt"></span>
    <% end %>
    <%= link_to edit_memo_path(memo) do%>
      <span class="far fa-edit"></span>
    <% end %>
  </p>
<% end %>
```
zipファイルを探すときのために

あのzipファイル、どこに置いたっけ、
使っていないzipファイルを探して削除したい、
そんなときのために。

WindowsのCドライブ以下を探す場合を想定しています。

```py:search_zip_file.py
import os
import pathlib

def get_path_recursive(path):
    for p in path.iterdir():
        try:
            if p.is_dir():
                get_path_recursive(p)
            elif p.is_file():
                if p.suffix == '.zip':
                    print(f'{p}')
        except PermissionError:
            pass
        except OSError:
            pass

path = pathlib.Path('C:\\')
get_path_recursive(path)
```
BLEの仕様書の読み方

# ProfileとServiceの仕様書

BLEのProfileやServiceの仕様書は以下のサイトにまとめられています。
https://www.bluetooth.com/specifications/specs/

たとえば、自転車のスピードセンサーのBLE仕様を確認したい場合は、以下のpdfを見ればよいです。

- [CSCP Cycling Speed and Cadence Profile 1.0](https://www.bluetooth.com/specifications/specs/cycling-speed-and-cadence-profile-1-0/)
- [CSCS Cycling Speed and Cadence Service 1.0](https://www.bluetooth.com/specifications/specs/cycling-speed-and-cadence-service-1-0/)

# Characteristicのデータ型

Serviceの仕様書にはCharacteristicのフィールドのデータ型は記載されていません。
データ型は以下の補足資料に記載されています。

- [GSS GATT Specification Supplement 4](https://www.bluetooth.com/specifications/specs/gatt-specification-supplement-4/)

![スクリーンショット 2021-05-27 2.14.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9875/00d74637-b6e6-2a98-a48e-447245b91ca0.png)

# ServiceとCharacteristicのUUID

ServiceとCharacteristicのUUIDは、以下のPDFに記載されています。(PDFのリンクは[Assigned Numbers](https://www.bluetooth.com/specifications/assigned-numbers/)ページにあります)

- [16-bit UUID Numbers Document](https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf)

![スクリーンショット 2021-05-27 2.17.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9875/60d736b8-e964-1f70-450a-ba9c7a750c29.png)
![スクリーンショット 2021-05-27 2.17.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9875/03e51ef5-bf97-fdbc-bd14-107b4b4bd87e.png)
Visual Studio Codeの拡張機能まとめ

#Visual Studio Codeの拡張機能まとめ
###・[Bracket-Pair-Colorizer-2](https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer-2)
<img src="https://raw.githubusercontent.com/CoenraadS/BracketPair/master/images/example.png" width="600">
---
###・[Auto Rename Tag](https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag)
<img src="https://raw.githubusercontent.com/formulahendry/vscode-auto-rename-tag/master/images/usage.gif" width="600">
---
###・[Code alignment](https://marketplace.visualstudio.com/items?itemName=cpmcgrath.codealignment-vscode)
---
###・[Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
<img src="https://raw.githubusercontent.com/streetsidesoftware/vscode-spell-checker/master/packages/client/images/example.gif" width="600">
---
###・[Live HTML Previewer](https://marketplace.visualstudio.com/items?itemName=hdg.live-html-previewer)
<img src="https://raw.githubusercontent.com/HarshdeepGupta/live-html-preview/master/Resources/Images/SidePreview.gif" width="600">
---
###・[Material Icon Theme](https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme)
<img src="https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/main/images/fileIcons.png" width="600">
---
###・[Trailing Spaces](https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces)
<img src="https://shardulm94.gallerycdn.vsassets.io/extensions/shardulm94/trailing-spaces/0.3.1/1554790489790/Microsoft.VisualStudio.Services.Icons.Default">
---
###・[TODO Highlight](https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight)
<img src="https://raw.githubusercontent.com/wayou/vscode-todo-highlight/master/assets/material-night-eighties.png" width="600">
---
###・[Reverse Search](https://marketplace.visualstudio.com/items?itemName=DanishSarwar.reverse-search)
---
表1にない配列を表2の上ではじいて保存する方法

#概要
識別番号と名前が入った表1と、識別番号と名前と年齢が入った表2を比較して、表1にない人間を表2から弾きたいと思ったのですが、表1をチラチラみながら消すのは怖かったので自動化しました。

###前提
1.Macユーザー
2.jupyter notebookユーザー

###用意した配列
表1.csv 
一列目：識別番号
二列目：名前

表2.csv
一列目：識別番号
二列目：名前
三列目：年齢


#手順

以下のようなコードを書いて実行します。

```php
#表1,2を読み込む。区切り文字が,文字のタイプはunicodeを指定(つまり文字として読み込む)
table1 = np.loadtxt('表1.csv', delimiter=',', dtype = "unicode")
table2 = np.loadtxt('表2.csv', delimiter=',', dtype = "unicode")

#空のリストを作成
sy2 = []

#table2の中の1行目0列目の要素がtable1にあるかを確認。
#もしあればsy2という列にtable2の一行目の要素を追加する。
for i  in range(len(table2[:,0])):
    if table2[i,0] in table1[:,0]:
        sy2.append(table2[i,:])       

# sy2.csvという名前で保存。区切り文字は,で、文字の入った配列として保存する。
np.savetxt("sy2.csv",sy2,fmt="%s", delimiter=',')

```
HTTPメソッド(CRUD)の対比

学習したことが抜けていたので、HTTPメソッドのCRUDの対比について簡単にメモでまとめました。

# HTTPメソッド
HTTPメソッドはHTTP通信における処理の種類のことを指し、その種類は８種類(GET,POST,PUT,DELETE,HEAD,OPTIONS,TRACE,CONNECT)が存在します。
このうち、使用頻度の高いGET,POST,PUT,DELETEの意味をまとめると、

| メソッド   |       意味         |  
|:--------:|:------------------:|
| GET     |　取得する       |
|  POST   |  送信する、追加する |
| PUT     |  更新する、作成する  |
| DELETE  |  削除する         |

のようになります。

# CRUD（クラッド）について
CRUDはアプリケーションのデータの取り扱いに関して、基本的な処理の頭文字を並べたもので、

| C(Create) |  R(Read) |  U(Update) | D(Delete) |
|:---------:|:--------:|:------------:|----------:|
| 生成       |   読み取り |  更新       | 削除　     |
 
を意味しています。
さきほど記載したHTTPメソッドに照らし合わせると

| C(Create) |  R(Read) |  U(Update) | D(Delete) |
|:----------:|:----------:|:------------:|:----------:|
|  生成      |   読み取り     |   更新   |削除   |
| POST/PUT  |　GET      |  PUT       | DELETE   |

となります。
【AdMob】OpenBidding導入後の効果

#はじめに
2021年4月からAdMobのOpenBidding機能が一般開発者にも開放されました。
私のアプリにも導入して一定期間経ったのでその効果などを記します。

先に書いておくと、多少は効果がありましたが大きく収入が伸びたわけではありません。
まだ導入して2ヶ月程度なのでこの先伸びる可能性はありますが…


#OpenBiddingとは
一般的に広告枠には特定の広告配信会社の広告を表示します。
ところがOpenBiddingは複数の広告配信会社に一斉にリクエストを飛ばし、一番高い単価を提示した会社の広告を表示するというものです。
しかもリクエストを飛ばすのはAdMob(Google)側のサーバが担うため、スマホ側への負荷は無くいい事だらけの技術です。
リアルタイムオークションと言ったほうが伝わりやすいかもしれません。
日本語では「公開入札」と呼んだりします。

なお、各広告配信会社とは個別に契約する必要があります。（契約といってもユーザ登録＋αレベル）

また、一部の広告配信会社はアプリにSDKを組み込む必要があります。
SDKが出てくると難しく感じるかもしれませんが、想像しているより10倍は楽に終わりました。
詳しくは公式サイトを参照。
https://support.google.com/admob/answer/9234488?hl=ja

以降は広告配信会社のことを「広告ソース」と呼称します。

#実績
早速ですが過去1週間のレポートです。
見てもあまり意味の分からない数値もありますが、OpenBiddingを使っている人が見比べられるように載せておきます。
今現在（2021/5/27）OpenBiddingに22個の広告ソースが対応していますが、私は6個利用しています。
効果のない広告ソースもありますが害もないのでそのままにしています。

なお、このアプリはAndroidのツール系アプリで主にバナー広告とネイティブ広告を使用しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1098991/82fb407b-40a2-152a-aa7d-312cf6a4bffa.png)

それぞれの列の意味は以下です。

| 単語       |       意味 |
|:-----------------|:------------------|
| 推定収益額             | おおよその収益額。<br>推定収益額をそのまま載せるのは良くないらしいので下2桁はブラインドしています。|
| 有効CPM             | eCPMのこと。eCPMとは広告1000回表示あたりの収益のこと。<br>広告が500回表示されて40円の収益が発生した場合、eCPMは80円となります。|
| 有効なリクエスト             | オークションへの参加資格があった回数|
| 入札リクエスト             | 広告ソースへのリクエスト数|
| オークションに参加している入札数             | 実際にオークションへ参加した回数|
| 一致したリクエスト数             | オークションで落札でき、アプリに広告を返した回数|
| 表示回数             |広告がユーザに表示された回数| 

###上記実績の補足
- eCPMがかなり低いですが、私のアプリの作り的にそうなってしまっているので他の方のアプリであればもっと高いと思います。
- ほとんどAdMobが落札していますが、他の開発者の方も同じような感じらしいです。
- 一部の広告ソースの入札がほとんどありませんが、正常らしいです。<br>又聞きですがアプリの種類（ゲーム/ツール）や広告の種類（バナー/インステ/リワードなど）、配信している国などにより広告ソース側の在庫が無いみたいです。
- AdMob以外の広告ソースで全体収益の15%程度なので、今の所効果は限定的といえます。<br>OpenBiddingを使用していなかったらその15%の枠もAdMobが取っていて収益が生まれたはずなので、収益が15%伸びたというわけではありません。



#各広告ソースの導入
先述した通り、OpenBiddingを使用するには各広告会社へユーザ登録しなければなりません。
また、登録・申請後の審査で却下される場合もあります。

私が申請した広告ソースについて軽くどんな流れであったか記載します。
一番最初に行う申請の方法はAdMob公式ページを参照。

なお、申請し許可されたものの導入しなかった広告ソースもあります。
ゲーム系に強いため効果が出なさそうだから、などの理由です。

| 広告ソース| 申請後の流れ|その他|
|:-----------------|:------------------|:------------------|:------------------|
| Facebook Audience Network(FAN)             | 申請後は個別のやり取りなし。楽。| 要SDK|
| Applovin             | 申請後は個別のやり取りなし。楽。|要SDK|
| AdColony| 申請後は個別のやり取りなし。楽。|要SDK|
| Fluct             | 申請後は担当者とメール（日本語）で4往復くらいやり取り。<br>色々と準備があるらしく広告が表示されるまで1ヶ月程度かかりました。||
| Chocolate Platform             | 申請後は担当者とメール（英語）で1往復だけやり取り。<br>契約書への署名あり。||
| Media.net            | 申請後は担当者とメール（英語）で1往復だけやり取り。<br>ただOpenBiddingの配信に問題が起きているらしくまだ表示できませんと連絡がきました。||
| TapJoy            | 申請後速攻で許可されました。個別やり取りなし。|要SDK|
| Index Exchange            | 許可されてるけどなにも覚えてません。。。||
| Ad Generation| 総合的判断により拒否されました||
| PubMatic            | 様々な理由により拒否されました||
| YieldOne| 個人開発のため拒否されました。<br>法人のみ許可しているとのこと。||
| OpenX| 申請後音沙汰なし||
| Rubicon            | 申請後音沙汰なし||

Ad Generationに拒否されたのは少し痛かったです。
個人開発者でも使っている方が多く、単価が高いらしいので…

ちなみに拒否と書くと堅くて怖いイメージですが、実際はどの会社も大変丁寧な内容のメールが送られてきました。


#その他注意
各広告ソースのapp-ads.txtへの反映を忘れないようにしましょう。
特にSDK導入の広告ソースについてはAdMob公式の導入手順にapp-ads.txtついて触れていないので注意です。
更新しないとその広告ソースからは配信されないはず…たぶん。

#まとめ
多少は効果が出ますがあまり期待しすぎないほうが良いかもしれません。
ただ、副次効果としてリワード広告の在庫切れを防ぐといった効果は見込めると思います。
$_getと$_postと$_REQUEST

//html
<form action="submit.php" method="get">
    <label for="my_name">お名前：</label>
    <input type="text" id="my_name" name="my_name" maxlength="255"
    value="">
    <input type="submit" value="送信する">

このとき、method="get"に注目する。
method="get"の記述がされているときは、phpで下記のように記述する。
<pre>
    お名前: <?php print(htmlspecialchars($_get['my_name'], ENT_QUOTES)); ?>
</pre>

注目すべきは、$_get['my_name']の部分。

htmlでmethod="get"と指定しているので、phpでも$_getとしている。
他にも、method="post"と指定すると、phpでも&_postとする必要がある。

両者の違いは、パスワード等の秘密にしたいものをpostで記述し、それ以外のものをgetとすることが多い。

また、同様の動きをするものにphpで$_REQUESTと記述することもできる。
これは、先に受け取るものがgetかpostか分からない場合に使用する。
アプリケーションがコンソールで実行されているかどうかを確認する方法

## はじめに
Laravelでのアプリケーションがコンソールで実行されているかどうかを確認する方法についての解説記事です。

## 動作確認環境
- PHP 8.0
- Laravel 8.0

※下位環境でも動作する場合がございます

## 書き方（その1）
```php
if (!$this->app->runningInConsole()) {
    // コンソールでの実行時以外の時のみ通したい処理
}
```

## 書き方（その2）
```php
if (!app()->runningInConsole()) {
    // コンソールでの実行時以外の時のみ通したい処理
}
```

## 該当のLaravelのロジック
```php
Illuminate\Foundation\Application

/**
 * Determine if the application is running in the console.
 *
 * @return bool
 */
public function runningInConsole()
{
    if ($this->isRunningInConsole === null) {
        $this->isRunningInConsole = Env::get('APP_RUNNING_IN_CONSOLE') ?? (\PHP_SAPI === 'cli' || \PHP_SAPI === 'phpdbg');
    }

    return $this->isRunningInConsole;
}

```
Firebase Auth を用いてTwitter ID(@ユーザー名)を取得

FirebaseのTwitterログインを使用したWebアプリを開発している際、TwitterのID(ユーザー名)の取得で手間取った為、記事にしました。
(ユーザー名だと表示名と混同しそうなため、ユーザー名ではなくTwitter ID と呼びます)

# 前提

以下の2つの公式の記事を参考に、Twitterを用いたログイン機能を実装し、ユーザー情報の取得を試みました。

https://firebase.google.com/docs/auth/web/twitter-login?hl=ja

https://firebase.google.com/docs/auth/web/manage-users?hl=ja

ユーザー情報は、ログイン後に以下のコードを実行すれば取得できます。(JavaScriptを想定)

```
import firebase from 'firebase/app'
import 'firebase/auth'
var user = firebase.auth().currentUser
```

この`user`変数の中にユーザー情報が入っており、以下のコードによりTwitterの表示名や、Twitterアイコン画像URLをコンソールへ出力できます。

```
console.log(user.displayName)//Twitterの表示名を出力
console.log(user.photoURL)//TwitterアイコンのURLを出力
```

開発当初はTwitterの表示名とアイコンが取得できれば十分だと思ったのですが、表示名はアカウント固有では無い為、アカウント固有のTwitter ID(@から始まる文字列)も取得したいと思いました。(Twitter IDが取得できれば、そのユーザーのTwitterページへのリンクも作成できる)

しかし、上記のuser変数にはTwitter IDは含まれておらず、Twitter IDを取得するには別の手法が必要となります。

# 解決策

ユーザー名を得るには__additionalUserInfo__というデータを取得する必要があります。直訳で「追加のユーザー情報」。そのまんまですね。

additionalUserInfo に関するFirebaseの公式記事は日本語化されておらず(2021/05/27 現在)、頑張って読みます。(日本語検索ばかりしていたのも苦戦した原因ですね...)

https://firebase.google.com/docs/reference/js/firebase.auth#additionaluserinfo

additionalUserInfoはフェデレーションIDプロバイダーから取得すると書いてあります。

これだけでは、どうやって取得できるのか分からなかったのですが、以下のサイトに回答が書かれていました。

https://stackoverflow.com/questions/56177525/firebase-auth-is-it-possible-to-see-users-twitter-id

「フェデレーションIDプロバイダーから取得する」つまりTwitterログインを成功させた直後に取得できるということだったようです。
以下のコードでTwitterログイン処理と、Twitterユーザー名の取得ができます。

```
firebase.auth().signInWithPopup(new firebase.auth.TwitterAuthProvider())//Twitterログイン
  .then((userCredential) => {
    console.log(userCredential.additionalUserInfo.username);
//このusernameにユーザー名が入っており、Twitterのユーザー名が取得できる
  })
  .catch((error) => {
  });
```
これで、めでたしめでたし...と思いきや...

# リダイレクトを用いたログインでのユーザー名取得

FirebaseのTwitterを用いたログインには以下の二種類があります。

- signInWithPopup(ポップアップウィンドウでログインを行う)
- signInWithRedirect(ログインページにリダイレクトしてログインを行う)

signInWithPopupを用いてTwitterログインを行う場合は上記のコードで問題ないのですが、signInWithRedirectを用いた、リダイレクトによるログインを行う場合、一旦別のページに飛んでから戻ってくるので、上記のような書き方ではadditionalUserInfoを取得できません。


この場合は、ログイン後にページが読み込まれた際に`getRedirectResult`を呼び出すことで、additionalUserInfoを取得できます。
(私はVue.jsで開発している為、watchを用いてログイン後かの判別を行って呼び出しています)

```
firebase
 .auth()
 .getRedirectResult()
 .then((userCredential) => {
   this.twitterId = userCredential.additionalUserInfo.username //Twitter ID を取得
   //ついでに最新の表示名とアイコンも取得
   this.displayName = userCredential.additionalUserInfo.profile.name
   this.photoURL =
    userCredential.additionalUserInfo.profile.profile_image_url
})
```
## 補足
上記のコードでは、Twitter IDに加え、表示名とアイコンも取得しています。これは、additionalUserInfoはプロバイダーから情報を取得しているため、最新のTwitter表示名とアイコンを取得できるためです。
additionalUserInfoから最新の情報を取得し、`updateProfile`を用いてユーザー情報を更新しないと、昔のアイコンや表示名が更新されずに古いままになってしまいます。
その為、additionalUserInfoからはユーザー名だけではなく、表示名やアイコンも取得して常に更新するのが良いと思われます。

# おわり
誤り等がありましたら、ご指摘頂けると幸いです。

# 参考
https://firebase.google.com/docs/auth/web/twitter-login?hl=ja
https://firebase.google.com/docs/auth/web/manage-users?hl=ja
https://firebase.google.com/docs/reference/js/firebase.auth#additionaluserinfo
https://stackoverflow.com/questions/56177525/firebase-auth-is-it-possible-to-see-users-twitter-id
Pipenv構築手順(Anacondaからの乗り換え)

さようならAnaconda。はじめましてPipenv。仲良くなろうね。

# 1.環境
さあ、まずは、AnacondaをアンインストールしたWindows10 PCを用意しておこう！

# 2.インストール
## (１)Pythonのインストール
Anacondaをアンインストールしたら、Pythonも消えちゃったんだよね。Anacondaをインストールしたときに、一緒にやってきたPythonだったから。仮想環境で使用したいバージョン(本記事では3.8.4)のPythonをダウンロードして、インストールし直しましょ！！

これは、朝飯前だね。

https://www.python.org/downloads/

インストールするときは、後で自分でパスを通すの面倒なので、[Add PythonX.X to PATH]にチェックを入れておく。パス通さないと、次の(2)Pipenvのインストールでpipコマンドが無いって怒られるよ。
![環境変数Python.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259531/41bfd455-5f12-bf4a-20ec-af520afe6403.png)

## (2)Pipenvのインストール
pipで簡単に入れられるよ！！
コマンドプロンプトで、

```
pip install pipenv
```
って打ち込みます。

下記設定をすると仮想環境をプロジェクト直下に作れるようになるよ。
ユーザ環境変数に変数名：PIPENV_VENV_IN_PROJECT、値：Trueを追加します。

万が一、環境変数の設定方法を忘れちゃった場合は、こっそり下のサイトをカンニングしておきましょう。

https://www.atmarkit.co.jp/ait/articles/1805/11/news035.html

# 3.仮想環境の構築

新しいプロジェクトを始めましょう。
まずは、プロジェクトのフォルダを好きな場所(D:\MyTest)に作成します。

コマンドプロンプトから、作成したプロジェクトの直下に移動します。
ドライブ移動が必要な場合は、「ドライブ名:」コマンドが必要なので、忘れないように。

```
d:
cd D:\MyTest
```

下記コマンドを実行し、仮想環境を構築します。

```
pipenv --python 3.8.4
```

![仮想環境構築成功.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259531/b3e7f672-c8d0-a6a4-2695-3e40b770165e.png)

無事に作成できました！！！

# 4.仮想環境へのライブラリインストール

下記コマンドを実行し、ライブラリをインストールします。

```
pipenv install matplotlib==3.4.2
```
仮想環境を構築し、ライブラリをインストールするとプロジェクトフォルダ(D:\MyTest)にPipfile、Pipfile.lockの2種類のファイルが追加されまーす。

なお、Pipfileには、installコマンドで指定したライブラリ名とそのバージョン、Pipfile.lockにはインストールされた依存関係も含むライブラリ情報が記述されます。

# 5.仮想環境からライブラリのアンインストール

下記コマンドを実行し、ライブラリをアンインストールします。

```
pipenv uninstall matplotlib
pipenv clean　//依存ライブラリを削除
```
アンインストールしたライブラリ情報は、Pipfile、Pipfile.lockから削除されます。

# 6.仮想環境の削除
下記コマンドを実行し、仮想環境を削除します。

```
pipenv --rm
```

# 7.仮想環境の複製

ここでは、新しくプロジェクトフォルダ(D:\MyTest2)を作り、この中に仮想環境を複製することにします。
複製元仮想環境のPipfile、Pipfile.lockを入手しときます。

新規のプロジェクトフォルダに移動します。

```
d:
cd D:\MyTest2
```

下記コマンドを実行し、仮想環境を複製します。

```
pipenv install
```

# 8.仮想環境内でのコマンドを実行

実行したいコマンドの先頭に、pipenvをつけます。めんどくさいね。

```
pipenv run pip list
```

![piplist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259531/6778d5f3-5625-b0c0-7ca2-f80443379a60.png)

# 9.困ったら
このドキュメントを真面目に読む。

https://pipenv-ja.readthedocs.io/ja/translate-ja/
ポートフォリオを作りたい～環境作り編～

ポートフォリオページを作りたいので、とりあえず環境周りを整えます！
どなたかの参考になれば幸いです:baby_tone2:


#環境
- Windows10
- Node.jsはnvm-windowsで今の推奨版14.17.0を設定中
- npmはしれっと入っていた6.14.13

※nodeとnpmは以前導入の記事をあげてますのでよければどうぞ！
→ [nvm-windowsでnode.jsのバージョン管理をする【Windows】](https://qiita.com/nezumori/items/504b26d26f3e6e3009e3)


#目次
1. Vue CLIでプロジェクトを作る
1. GitHubで管理できるようにする
1. Firebaseでデプロイしてみる

#1. Vue CLIでプロジェクトを作る

##1-1. Vue CLIをインストール
```
$npm install -g @vue/cli
// わーっとインストールが走ります

$vue —-version
// バージョンの数字が出ればインストールOK！
```

##1-2. UIを起動
```
$vue ui
```
ブラウザでUI画面が起動します。
コマンドの方は自動で終了しませんが、これでブラウザが見れるようになっているので
作業が終わるまで終了しないようにしてください。


##1-3. Vueプロジェクトを作成
ブラウザのUIで作業していきます。
黒い画面アレルギーには大変うれしい機能ですね！

1. 「作成」タブを開く
1. フォルダを指定して、「ここに新しいプロジェクトを作成する」をクリック
1. 「詳細」タブでプロジェクト名などを指定し、「次へ→」
1. 「プリセット」タブで「Default preset(Vue 3)」を選択する
1. 「プロジェクトを作成する」！
1. ちょい待ちます（2〜3分くらい）
1. プロジェクトフォルダができました！

2で指定したフォルダを確認してみましょう！


##1-4. 起動してみる
コンソールで作ったフォルダに移動して、起動します。

```
$npm run serve
```

うにゃうにゃ出た後に```Local:http://localhost～```というのが出るので
ブラウザで開いてみます。

「Welcome to Your Vue.is App」というVueの画面が出ればOKです！やったー！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213821/38caa88d-0942-f40e-8e2e-a7859eda4055.png)


#2. GitHubで管理できるようにする

ローカルで作ったフォルダをGitHubでバージョン管理できるようにしていきます。

1. GitHubで空のリポジトリを作る
1. ```$git init```（gitプロジェクト化する）
1. ```$git add.```（全部addする）
1. ```$git commit -m "first commit"```（コミット）
1. ```$git remote add origin https://github.com/xxxx/xxxx.git```
1. ```$git push -u origin master```

5では1で作ったリポジトリを指定します。
GitHubで、Code→HTTPSにあるURLを使ってください。

GitHubのリポジトリページを更新してみましょう、コミットした内容が出るはずです！


#3. Firebaseでデプロイしてみる

デプロイの工程は最後に行うので環境なども最後でもいいんですが、
手順把握のためとここまでで問題ないかの確認のため、
ページができたらすぐアップできるぞ～というモチベのために
環境を整えてアップしてみます。

この辺りはきれいにまとまっている記事があり、
特筆することもなく見事にそのままできたので参考にした記事をご紹介します！

## Firebaseのインストール～デプロイする
まず、こちらのページにある手順を通します！

→ [Firebaseでデプロイしよう！](https://qiita.com/hiroki-harada/items/ca22ac177db68e3c3796)

## 400エラーになった

こちらの記事でインストールからデプロイまではできたのですが、コンソールに

```
Failed to load resource: the server responded with a status of 400 ()
```

というエラーが出て画面が真っ白に・・
修正方法の記事もございました、ありがたいです！

→ [【Firebase】Vueプロジェクトでfirebase deploy した時に、Failed to load resource: the server responded with a status of 400 () が出た時の対処法](https://qiita.com/wakki_haya/items/e487fb3fea12b3905dda)


ローカルじゃないURLで確認ができました！

そのままでも問題ありませんが、
私はなんとなく気持ち悪かったのでデプロイは取り消しておきました。
実装が終わったらまたデプロイします:hugging:たのしみですね！


#まとめ
初回のみのインストール作業などもありますが、
次回からはこの手順を通せばサクッと作業が始められるようになったかと思います！
初期作業がめんどくさいという言い訳封じができたのでモリモリ作っていきたいですね:muscle:

ありがとうございました:sunglasses:
cmdによるMySQL　コマンドやクエリ　備忘録

#使用環境
Windows10
MySQL version 5.7

インストールは、こちらのサイトを参考にさせて頂きました
https://prog-8.com/docs/mysql-env-win

#コマンド
以下の例のように入力します

```shell-session:コマンドプロンプト
net start mysql57
mysql --user=root --password
Enter password: rootのパスワード
mysql> CREATE database データベース名
mysql> SOURCE ファイル名
mysql> USE データベース名
mysql> exit;
net stop mysql57
```

#雑記(2021/05/27)
執筆環境が非常に悪い関係ので、コマンド内容の説明は省きます。
コマンドの内容からなんとなく察してください。
暇ができたら、見やすく編集し直します。
機械学習における次元の呪いとは

#概要
次元の呪いとは次元数が増えることで計算時間が指数関数的に増大する、というのが一般的だが
今回は機械学習における次元の呪いについて学んだことをメモしました

**機械学習における次元の呪いとは
データが高次元になると予測精度が悪くなる現象**


主な原因
・学習データの不足
・高次元空間の特殊な性質

#学習データ数の不足
まず10000レコードあるデータを考え、それらは10通りの値の変数をもつとする
この変数の数が2つだと、表現できるデータの組み合わせは10の2乗で100通り
しかしこの変数が10あると10の10乗で100億通りとなる

これにより学習データとデータの組み合わせの比が
変数の数によって小さくなります

よってデータ空間内にデータがほとんどなく(データ空間が疎)
データ空間にデータのないところが多いにもかかわらず
その場所に対しても予測を立てなければならないため予測精度が悪くなります

##過学習とは
過学習とは学習データに対応しすぎて汎用性が失われることです

<details><summary>詳しい解説</summary><div>
>学習データについての予測結果精度は良いのに
実際のデータを使うと予測結果精度が良くないというもので
原因の一つとして学習データの予測結果の精度をあげようとしすぎて
とても細かい予測をしてしまうということがあります
例えば決定木分析において、個人単位で予測してしまえば
学習データの予測精度は100％正しくなりますが
実際のデータに使うとなると一般性を欠いてしまい予測精度は悪くなります</div></details>

#高次元空間の特殊な性質
まずは5通りの値(1~5)の変数が2つ(変数x,変数y)ある空間を考える
これは5×5の二次元空間である
今回は1辺が長さ5の正方形を考えてみる

正方形の中心から面（正方形では辺）までの距離は2
正方形の中心から各頂点までの距離は、2×√(次元数)である
<details><summary>詳しい解説</summary><div>
>座標平面で考えると、この正方形の中心は(変数x,変数y)=(3,3)となる
中心から各面までの距離は、|3-1|もしくは|3-5|で2となる
また中心と各頂点(1,1),(1,5),(5,1),(5,5)との距離は√(2^2+2^2)=2√2となる
<img width="200" alt="正方形の中心からの距離" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1514389/76a7ceb2-770e-12d5-8116-53d32161bac6.png">
また３次元を考えると、1辺5の立方体になる
中心は(3,3,3)で各面までの距離は同様に2
各頂点(1,1,1),(1,1,5),(1,5,1)...までの距離は√(2^2+2^2+2^2)=2√3である

これを一般的に考えると
中心から各頂点までの距離を計算するときに
次元数に応じて、各座標の差分の計算が増えることから
(各頂点までの距離)＝√{(各面までの距離の２乗)×(次元数)}
　　　　　　　　　＝(各面までの距離)×√(次元数)
であることがわかる</div></details>

つまり、次元数が増えるにつれて中心から頂点までの距離は大きくなるが
面までの距離は変わらないということです

これが高次元空間の特殊な性質です

この性質によって、距離による類似度の計算だと
中心付近のデータが学習に高い頻度で採用され
機械学習がうまく働かないということが起こってしまいます

また高次元空間の特殊な性質として
**球面集中現象**というものもあります

<details><summary>詳しい解説</summary><div>
>まず半径1の二次元空間での球、つまり円を考えます
この円の中心から中心から0.9以上離れた部分を表面付近とし
円全体と表面付近の面積との比を計算します
(円全体の面積)=π×1×1=π
(表面付近の面積)=(円全体の面積)-(半径0.9の円の面積)
　　　　　　　　=π-π×0.9×0.9=0.19π
よって表面付近の面積は全体の19％ということが分かります


>次に半径・表面付近の定義はそのままで、三次元の球を考えると
(球の体積)=π×1×1×1=πで変わらないのに対して
(表面付近の体積)=(球の体積)-(半径0.9の球の体積)
　　　　　　　　=π-π×0.9×0.9×0.9≒0.27π
よって表面付近の体積は全体の27％ということが分かります


>2つの例から次元が増えると、半径(0.9)をかける回数が増え
内側の体積が減少するのが分かります
逆に表面付近の全体に占める割合は大きくなっています
</div></details>

つまり高次元空間では球の体積のほとんどが
球の表面近くになってしまうということになります

これの球をメロンパン、表面付近をメロンパンのサクサク部分（皮）に例えて
サクサクメロンパン問題という人もいます笑

この球面集中現象の何が問題なのかというと
ほとんどのデータが表面付近になるということは
中心に近い部分がなくなることを意味し

それによって類似していると考えられていた学習データが
変数が増えるごとに少なくなり重要度の高い変数がわからなくなる

という問題が発生してしまうのです

#さいごに
今回は次元の呪いについて調べる機会があったので
自分なりにまとめてみました

図や計算を使うと、高次元空間が自分のイメージと大きく異なることが分かり
説明変数が増えることでこんなことが起こるのかと深く実感できました

これからもわからないことを調べたときに自分なりにアウトプットする媒体として
Qiitaを活用していきたいと思います
numpy完全攻略

numpyで?ってなったことをまとめる。イディオム的に。
#1.     image.shape==[3.64,64] を [1,3,64,64]に変更する

```
image=np.stack([image])
```

#2. numpyをTensor型にしてcudaに乗せる
```
image=torch.from_numpy(image).cuda()
```

#3. csvから数字データを取ってきてnumpy配列に格納する
```
with open('name.csv','r') as f:
    reader=csv.reader(f)
    l=[row for row in reader]
    l=np.array(l).astype('int64')
```
csvから取ってきた後にastypeでキャストするのを忘れないようにする
ペーパークラフト変換ツールthree.js react.js

ペーパークラフトに興味を持っている開発者の僕がこのツールを作成しました。
Pepakura Designerに似ている無料なものです.
https://papercraft-maker.com/
公開した機能は
１．３Dモデルをインポート。特長は様々なフォーマットをサポート：STL, FBX, GLTF, GLB, OBJ, DAE.
　※　 Pepakura のファイルフォーマットPDO　もサポート。
２.　テクスチャ、カラーをサポート。
３．３Ｄモデルから２Ｄに展開　　＋　糊代をつける
４．ワンタッチで展開
５．Undo/redo無制限
６． PDF, PNG, SVGをエクスポート

今、まだフィードバックを求めながらツールを改善や機能追加しています。

以上のツールを作成するために、以下の技術を活用しています
react.js
three.js
canvas
...
&複数のアルゴリズム
![186532541_309467200709534_9194984623093027556_n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289628/d2179e7d-0521-8be1-afae-db3d9cfbbe6c.png)
ラズパイカメラでdetected=0になった私の場合

#概要
ラズパイをちょっと使おうとしたらずっと、

```
detected=0
```
で苦労しました(´;ω;｀)

#原因
固定に使っていたボルトで導通していました。![IMG_20210527_000354372.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/6e0c2996-a266-cc66-888d-5d6cdf57a350.jpeg)

あくまで私の場合なので、ほかの場合もあり得ます。
ちなみに、USBカメラでは$detected = 1$になりません。



#追記

```
mmal: mmal_vc_component_enable: failed to enable component: ENOSPC
mmal: camera component couldn't be enabled
mmal: main: Failed to create camera component
mmal: Failed to run camera app. Please check for firmware updates
```
というエラーにも遭遇しました

さっきまで動いていたのに突然、このエラーが出ました。

原因は
カメラのフレキシブルケーブルが緩んでいました。
ちょっとひっぱったら、すぐ抜けました

刺しなおしたところ、解決しました。
JavaScriptの論理演算子の返り値は論理値ではない

# 経緯

先日JavaScriptで以下のような記述を見かけた．

```js
len = (obj.arr || []).length
```

今までC++をメインに使っており，論理演算子の返り値は論理値(Boolean型)であると思い込んでいたが，どうやらJavaScriptでは仕様が違うらしい．

# C++の場合
`100 && 200`を出力してみる．

```C++
#include <iostream>
#include <typeinfo>
#include <cxxabi.h>
using namespace std;

int main() {
    int x = 100, y = 200;
    cout << (x && y) << endl; 

    // 完全な型名の取得
    const type_info& id = typeid(x && y);
    int stat;
    char *name = abi::__cxa_demangle(id.name(),0,0,&stat);
    
    cout << name << endl;
}
```

以下が出力．bool型である．

```
1
bool
```

# JavaScriptの場合
```js
x = 100
y = 200
console.log(x && y)
console.log(typeof(x && y))
```

以下が出力．`y`の中身が返ってきている．

```
200
number
```

### リファレンスに書いてあった

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_AND
> expr1 && expr2
> expr1 が true に変換できる場合は expr2 を返し、それ以外の場合は expr1 を返します。

> 一般的には Boolean (論理) 値で使用されます。その場合は論理値を返します。ただし && 演算子は実際には指定されたオペランドのうち一つの値を返すので、この演算子が論理値以外で使用された場合は、論理値以外の値を返すことになります。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_OR
> expr1 || expr2
> expr1 が true に変換できる場合は expr1 を返し、それ以外の場合は expr2 を返します。

# Pythonの場合
ちなみに，Pythonもこの仕様のようだ．

```python
x = 100
y = 200
print(x and y)
print(type(x and y))
```

```
200
<class 'int'> 
```
【ターミナル】「dquote> 」の解決方法

# 概要
アプリ作成途中に、ターミナル上で **dquote>** が表示され、exitできなくなるエラーが発生しました。

エラーは以下の通りです。

```
% heroku config:set BASIC_AUTH_USER="abc'
dquote> 
dquote> exit
dquote> 
dquote> 
dquote> c
dquote> exit
dquote> exit
dquote> 
```

# 原因
「"」（ダブルクォーテーション）を左右に記述していなかったのが原因。
dquote は double quotation 略のことでした。

# 解決方法
語尾に「"」を追加すればOK

```
% heroku config:set BASIC_AUTH_USER="abc'
dquote> 
dquote> exit
dquote> 
dquote> 
dquote> c
dquote> exit
dquote> exit
dquote> 
dquote> "　　　# 「"」を実行
 ›   Warning: heroku update available from 7.51.0 to 7.53.1.

Setting BASIC_AUTH_USER and restarting ⬢ 〇〇〇〇... done, v15
BASIC_AUTH_USER: abc

--------@MacBook-Pro-van-〇〇〇〇〇〇 ------ %
```
終了できました。
「"」（ダブルクォーテーション）で囲う必要があったんですね。

他にも調べたら
 「**Ctrl + g**」でコマンドを破棄しても終了することができます。

(「'」（シングルクォーテーション)の場合、 「quote」と表示されるようです)
SQLについて　備忘録

# SQLとはDBを操作する言語
ターミナルで直接データベース操作する際以下の言語を使います。

DDLとは、データを定義する命令のこと
CREATEは、データベースやテーブルを作成できる文のこと
SHOWは、データベースやテーブルを一覧表示できる文のこと
DROPは、データベースやテーブルを削除できる文のこと
USEは、使用するデータベースを選択する文のこと
ALTERは、データベースやテーブルを編集できる文のこと

DMLとは、データを操作する文のこと
SELECTとは、データを取得する句のこと
ワイルドカードとは、文字の代わりとして使うことができる記号のこと　＊
INSERTとは、テーブルにデータを登録する文のこと
UPDATEとは、テーブルのデータを更新する文のこと
DELETEとは、テーブルのデータを削除する文のこと

# 関連する操作
rails db:createコマンドや、
Sequel Pro（シークエルプロ）を使用したデータの書き換え。
しかし、「特定のコマンド実行」や「GUI操作」が用意されていない処理を行う場合は、
直接SQLを使用する必要があります
TikZ 入門（Part.3）　グリッドを引く

いぇと（[@yetput_ikura](https://twitter.com/yetput_ikura)）です．
TikZ 入門 Part.3 です．今回はグリッドの引き方を説明します．

# グリッドを引く
座標 $(x_1,y_1)$ と座標 $(x_2,y_2)$ を対角成分に持つグリッドを描くためには `grid` を使います．

```TeX
\begin{tikzpicture}
\draw (x1,y1) grid (x2,y2);
\end{tikzpicture}
```

例として，$-3\le x\le 3, -2\le y\le 2$ のグリッドを引いてみましょう．

```TeX
\begin{tikzpicture}
\draw (-3,-2) grid (3,2);
\end{tikzpicture}
```
![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545738/e56ce343-8b38-6ca0-1a2d-daadafa4dbb2.png)

## グリッドのオプション
グリッドにも色々オプションがあります．グリッド特有のオプションとして間隔 `step` や $x, y$ 方向の間隔 `xstep, ystep` があります．`step = ` といった感じで指定します．

たとえば，$x,y$ 両方の間隔を $0.5$ にしてみます．

```TeX
\begin{tikzpicture}
\draw (-3,-2) grid[step = 0.5] (3,2);
\end{tikzpicture}
```
![img7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545738/0499577b-8e2a-96cb-49d0-1ad72af49adc.png)

今度は，$x$ 方向の間隔のみを $0.5$ にしてみましょう．

```TeX
\begin{tikzpicture}
\draw (-3,-2) grid[xstep = 0.5] (3,2);
\end{tikzpicture}
```
![img8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545738/3e249782-e3f7-8007-6daf-2d8b84108c49.png)

基本的にはこんな感じですが，普段使う際には点線にしたり薄くしたりすることが多いですね．

```TeX
\begin{tikzpicture}
\draw[dotted, thin] (-3,-2) grid (3,2);
\end{tikzpicture}
```
![img9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545738/eb81a0db-9ba1-728d-b31e-00888a7b69b9.png)
TikZ 入門（Part.2）　長方形を描く＋おまけ

いぇと（[@yetput_ikura](https://twitter.com/yetput_ikura)）です．
TikZ 入門 Part.2 です．今回は長方形の描き方を主に説明します．

# 長方形を描く
座標 $(x_1,y_1)$ から座標 $(x_2,y_2)$ への線分を対角線に持つ（辺が $x$ 方向と $y$ 方向の）長方形を描くためには `rectangle` を使います．

```TeX
\begin{tikzpicture}
\draw (x1,y1) rectangle (x2,y2);
\end{tikzpicture}
```

例として $(0,0)$ と $(2,1)$ を対角にもつ長方形を描いてみます．

```TeX
\begin{tikzpicture}
\draw (0,0) rectangle (2,1);
\end{tikzpicture}
```
![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545738/290fa778-cc9d-c666-16f2-4e1f88048640.png)


# おまけ
## 横と縦のみで描く
いい見出しが思いつきませんでした．
$(x_1,y_1)$ から $(x_2,y_2)$ へ横方向の線と縦方向の線のみでつなぐためには `|-` や `-|` を用います．

```TeX
\begin{tikzpicture}
\draw (x1,y1) |- (x2,y2);
\draw (x1,y1) -| (x2,y2);
\end{tikzpicture}
```

これだけみてもよく分からないと思うので，$(0,0)$ から $(2,1)$ へ，それぞれ描いてみます．

```TeX
\begin{tikzpicture}
\draw (0,0) |- (2,1);
\end{tikzpicture}
```
![img3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545738/4a323715-1844-a228-2824-2edfafcc77f3.png)


```TeX
\begin{tikzpicture}
\draw (0,0) -| (2,1);
\end{tikzpicture}
```
![img4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545738/0c395a7b-81c1-4657-1b9e-846fb2218898.png)

## つないでみる
前回 [Part.1](https://qiita.com/yetput_ikura/items/1dee03c506ca159c47e3) で線分と線分をつなぐ方法を説明しました．
基本的にはその時と同じで，行内で続けて書くとつないで図形を書くことができます．

たとえばこんなんとか．

```TeX
\begin{tikzpicture}
\draw (0,0) rectangle (2,1) rectangle (3,3);
\end{tikzpicture}
```

![img5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545738/a5fe62d5-f6fb-bfc3-041f-2acfaa8c1c53.png)

```TeX
\begin{tikzpicture}
\draw (0,0) rectangle (2,1) -- (3,3) rectangle (5,5) -| (6,0);
\end{tikzpicture}
```

![img6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1545738/636f10b8-04d1-0441-9546-154c490cfe3c.png)
【ngrok】を使用してスマホでローカル起動のRailsアプリを確認する方法


ローカル環境で開発中のスマホ向けRailsアプリを、実際にスマホの画面で動作確認するために「ngrok」を使用しました。
自分用のメモとしてngrok導入〜使用方法をまとめます。

# まずはngrokのインストール

```:ターミナル
$ brew cask install ngrok
```

※caskがインストールされていないとエラーが出ます。
その場合、caskをインストールしてから上記コマンドを実行しましょう。

# ngrokコマンドを実行

インストールが完了したら早速 ngrokコマンドを実行しましょう。
開発中アプリの起動ページのポート番号が```http://localhost:3000```の場合は次のようにコマンドを記入します。

```:ターミナル
$ ngrok http 3000
```

![スクリーンショット 2021-05-26 22.54.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295385/c4e3b18c-d08c-ead1-05d1-0503c1d0add8.png)

ターミナルにこのような結果が出ればコマンドは成功です。

# 実行結果からURLを取得しアクセスする

実行結果画面のForwardingにURLの記載があるので、httpsのURLをコピーしてブラウザのアドレスバーにペーストしアクセスします。

![スクリーンショット 2021-05-26 23.02.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295385/7c501ccd-f4b0-5536-5eff-cf7278140e66.png)

上記のようにアクセスがブロックされますが、画面の指示通りアクセスの許可を設定すればOKです。
```config/environments/development.rb```に以下を追記しましょう。
※記載するコードはブラウザに表示されたものをコピペしてください。

```ruby:config/environments/development.rb
Rails.application.configure do

//中略

config.hosts << "1366147bc404.ngrok.io"
end
```

Railsアプリを起動済みの場合は、```Ctrl＋C```で一度落としてから```rails s```で再起動して、先ほどのブラウザをリロードするとアクセスできるはずです。

# QRコードを作成してスマホで読み込む

ここまで完了すれば先程のURLをスマホのブラウザに入力してアプリにアクセスできますが、URLをポチポチ打つよりQRコードを作成する方が楽です。
GoogleChromeとmacの組み合わせを例にすると、ブラウザ上で簡単にQRコードを作成することができます。

![スクリーンショット 2021-05-26 23.22.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295385/67f9bbdd-f208-b39f-268f-0c6b399f6df3.png)

右クリックから「このページのQRコードを作成」を選択すると...

![スクリーンショット 2021-05-26 23.26.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295385/f9473451-fadf-9279-f01c-c9a93b268bea.png)

このように恐竜のマークのかわいいQRコードを作成できます。

他にも、以下のようなサイトを利用すれば無料ですぐにQRコードを作成できます。
https://qr.quel.jp/

作成したQRコードをスマホで読み込んでURLにアクセスしたら、ローカル起動のRailsアプリをスマホで動作確認することができます！

# 補足

この記事で紹介した「ngrok」は無料かつ登録無しでも使用できますが、その場合は一定の時間が経過するとアクセスできなくなってしまいます。
ちょっとした動作確認程度に使用するだけなら十分ですが、もっと使いたい人はユーザー登録してみても良いかと思います。
pythonでpng画像をjpg画像に変換するスクリプト

# 動機
pythonスクリプトで画像表示ができるようになったので、その次のステップとして画像の形式の変換、PNG画像からJPG画像への変換を行ってみる。PIL(Pillow)を使うと簡単にできた。以下そのスクリプト

```python:png2jpg.py
#!/usr/bin/env python3

import sys
from PIL import Image

if __name__ == '__main__':
    if sys.argv[1].endswith(".png"):
        img = Image.open(sys.argv[1])
        newImg = img.convert("RGB") # パレットモードのままJPG形式には変換できないようなのでRGBモードにコンバートする。
        newImg.save(sys.argv[1][0:-3]+"jpg")
```

# 課題
* PILを使わずmatplotlibを使ってnumpyのアレイ形式を変換してできないものだろうか。
* FFTを使ってJPG形式へ自作スクリプトで変換できるようになりたい。
オリジナルから差異のないファイルだけを削除

オリジナルから差異のないファイルだけを削除して、
差異のあるファイルだけ残したディレクトリ work/ を作るメモ。


```bash
# ubuntu でのみ確認。

# オリジナルから差異のないファイルだけを削除
# diff の引数に出現する work/ は後ろの sed の中にもあるので注意する
diff -rqs orig/ work/ | grep "identical$" | sed -E 's/^Files .* and (work\/.*) are identical$/\1/g' | xargs -I {} rm '{}'

# 空ディレクトリの削除
find work/ -type d -empty -delete
```

work を tar 圧縮するのは既存の記事にたくさんある。

* [[Linux]ファイルの圧縮、解凍方法](https://qiita.com/supersaiakujin/items/c6b54e9add21d375161f)
自作PC（構想編）

## モチベーション

作ることが目的。
IT系とか言いながら全然IT詳しくないのやばいなと思い、PC作り、その工程で詳しくなることが目的。

ちなみにPCゲームとかはやったことない。

## ゴール

とりあえず、つくってみる。
素人がどこまでできるのか（もしくはできないのか）。

## 予算

よくわからんけど10万弱。
自作だから売り物よりも安いくらいの予算で抑えたいので、このくらいかな。

## 参考にしたサイト

Youtube：[吉田製作所](https://www.youtube.com/channel/UC9WJo5ZJVXMZiA5XV2jLx5Q)、[とモヤシ](https://www.youtube.com/channel/UC1EVRR14B8PtgszWOwu1opA)
書籍		：[自作PC自由自在2021](https://www.amazon.co.jp/%E8%87%AA%E4%BD%9CPC%E8%87%AA%E7%94%B1%E8%87%AA%E5%9C%A82021-%E8%8B%B1%E5%92%8C%E3%83%A0%E3%83%83%E3%82%AF/dp/486730008X)

次回につづく（たぶん）
【所要時間1分】テストデータの入ったpostgresqlコンテナ環境を爆速で構築する


この記事では、テストデータが入ったpostgresコンテナ環境を構築し、postgresの学習を行うための環境の構築手順について記載する

## テストデータが入ったdokcer image build
```sh
docker build -t test -<<EOF
FROM postgres:13.3-alpine
RUN echo 'wget https://www.postgresqltutorial.com/wp-content/uploads/2019/05/dvdrental.zip' >> /docker-entrypoint-initdb.d/start.sh
RUN echo 'unzip dvdrental.zip' >> /docker-entrypoint-initdb.d/start.sh
RUN echo 'pg_restore -h localhost -p 5432 -U postgres -d dvdrental dvdrental.tar' >> /docker-entrypoint-initdb.d/start.sh
EXPOSE 5432
CMD ["postgres"]
EOF
```
## コンテナ環境起動
```sh:
docker run -i --rm -d\
    --name test \
    -p 15432:5432 \
    -v postgres-tmp:/var/lib/postgresql/data \
    -e POSTGRES_HOST_AUTH_METHOD=trust \
    test
```

## コンテナ環境ログイン
```
docker exec -it tesh sh
/# psql -U postgres
```
```
postgres=# \l

                                List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-----------+----------+----------+------------+------------+-----------------------
 dvdrental | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 | 
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(4 rows)

\c dvdrental
You are now connected to database "dvdrental" as user "postgres".
dvdrental-# \dt

             List of relations
 Schema |     Name      | Type  |  Owner   
--------+---------------+-------+----------
 public | actor         | table | postgres
 public | address       | table | postgres
 public | category      | table | postgres
 public | city          | table | postgres
 public | country       | table | postgres
 public | customer      | table | postgres
 public | film          | table | postgres
 public | film_actor    | table | postgres
 public | film_category | table | postgres
 public | inventory     | table | postgres
 public | language      | table | postgres
 public | payment       | table | postgres
 public | rental        | table | postgres
 public | staff         | table | postgres
 public | store         | table | postgres
(15 rows)


```

### 参考
https://www.postgresqltutorial.com/postgresql-sample-database/
【最低限覚えたい】Microsoft Teamsのショートカットキー

# はじめに
デスクトップアプリのTeamsには多数のショートカットキーが割り当てられていて、 `ctrl .`で一覧を見ることができる。
しかしながら、「本当に必要？」と感じたショートカットキーが多く存在したため、最低限覚えたい項目のみ抜粋した記事を作成することにした。
また、公式の説明では実際の使用シーンがイメージしにくいものがあると感じたため、当記事では意図的に一部のショートカットキーに独自の名前・説明を割り当てている。
(公式のほうが良くない？等、改善案あればぜひコメントで教えてください)

# メッセージ作成
#### `ctrl shift X` 誤送信防止
暗記必須。
通常モードの場合、Enterキーでメッセージが送信されてしまうので、
少し長めのメッセージを投稿する際には、あらかじめ当該キーを打っておき、
`ctrl Enter`でメッセージ送信することを推奨する。

#### `Enter → Enter` 新規メッセージ入力画面にカーソル移動
チャネル選択後、Enterキーを押すだけでメッセージ入力画面にカーソルが移動される。地味に便利。
(1回Enterを押すだけでも移動可能であるものの、反応が悪いときがあるため、2回押すことを推奨する)

#### `##`→ `ctrl B` 太字の見出し設定 
`##`のみでは、フォントが細くて見づらいと感じた。
長めの文章を書く際には、見出しのサイズは本文と区別する必要があると感じていて、個人的に重要視しているキー。

#### `>` 引用
markdown記法に馴染みのない人にもぜひ使ってほしい。

# 検索
#### `ctrl E` なんでも検索
「チーム」の画面から、特定の誰かに「チャット」したいときによく使う。
(チャット相手の名前検索→enterでチャット画面に飛べる)
#### `ctrl F` チャネル内のメッセージ検索
選択中のチャネル内のメッセージを検索したいときに使う。
#### `ctrl G` チーム・チャネル検索

# 会議
#### `ctrl shift M` ミュート/ミュート解除
これを覚えると、ミュート切替をバランスよくできるようになる。
覚えないと、切替が面倒くさくなって、不要なミュート・不要なミュート解除が発生しがち(な気がする)。

# カレンダー
#### `alt ctrl →(←)` 次(前)の週へ移動

# その他
#### `alt ↑(↓)` １個上(下)のチャネル・チャットに移動

#### `ctrl 数字` アプリ切替
個人的にオススメの並び順は、
`ctrl 1` チーム
`ctrl 2` カレンダー
`ctrl 3` チャット
`ctrl 4` アクティビティ
`ctrl 5` 通話

#### `ctrl ,` 設定画面を開く
【rails6】ransackを用いた複雑検索まとめ

こんにちは！
今日はransackを用いた複雑検索の仕方について纏めていきます

まずは完成形から見てみましょう！

![750b72997082592a53f30ef6a3d2bd91](https://user-images.githubusercontent.com/80019801/119677089-603f1800-be79-11eb-8566-dc276d5b82ff.gif)

やっていることは
- フォームに入力されたキーワードと商品名で曖昧検索する
- 結果商品を一覧表示させている（今回は一つしかない）
以上です！
今回は簡単な検索機能を実装していきましょう

### 環境
- Ruby 2.6.5
- rails 6.0.0
- DB: MySQL

### 参考資料
https://github.com/activerecord-hackery/ransack

他様々インターネットで「 rails ransack 使い方 」と検索して出てくる記事はたくさん見ました

### ① gemをインストールする
まずはransackを導入していきます

```Gemfile
gem 'ransack'

→ ターミナルに移り
% bundle install
```
初期設定はこれでOKです

### ② どのコントローラーに記述するか決定する
場合によっては限定されたページでの利用も想定されますので、
「**どの場面で使用するのか**」「**逆に検索フォームが登場しない場面はいつか**」
を予め纏めておきましょう

私のアプリは、ほぼ全てのページに検索フォームが登場しますので、「 application_controller.rb 」を使います。
※便利ですが、やはり使用すべき箇所はできる限り限定した方がいいと思います

以下の様に記述をしてください

``` application_controller.rb
before_action :set_search

private
def set_search
  @q = Item.ransack(params[:q])
  @items = @q.result(distinct: true)
end
```

ここで、

```
params[:q]
```
についてですが、この「 :q 」はデフォルトのキー名ですので、今は変更しない様にしてください

また、

```
(distinct: true)
```
この記述をすることで、resultの重複がない様に整えてくれます。
必要がない場合はこの記述は削除してくださいね。


### ③ルートの設定（必要な人のみ）
次はルートの記述をしていきます。
**検索結果を別のページに表示したい！**という方向けの手順です。
不要な方は飛ばしてください

下記の様に書いていきましょう

```routes.rb
get 'items/search'
```
これでルートを確認すると、「 items_search_path 」と設定されました。

今後、この「 **items_search_path** 」を使用していきます。
コピペの際に間違えない様にご注意ください

### ④検索フォームを作成する

では検索フォームを作成していきましょう
下記は私の一例としてご覧ください

```_header.html.erb
<%= search_form_for @q, url: items_search_path, class:"search-form" do |f| %>
  <%= f.search_field :name_cont, placeholder: 'キーワードから探す', class:'input-box' %>
  <%= f.button type: "submit", class:"search-button" do%>
    <%= image_tag "search.png", class:"search-icon" %>
  <% end %>
<% end %>
```

分解していきます

```
<%= search_form_for @q, url: items_search_path, class:"search-form" do |f| %>
```

「 search_form_for 」、これはransackにおいてのフォーム生成タグです。HTMLのform_withと同様です。
@qはコントローラーで生成した変数です。今回はitemsテーブルについての検索をしていきます。
urlには検索結果を表示する先のパスを記述していきます。自由に設定してください。

```
<%= f.search_field :name_cont, placeholder: 'キーワードから探す', class:'input-box' %>
```
次の行ですが、
serch_fieldもransack流の書き方ですので、覚えておいてください。
:name_contは、「 itemsテーブルのnameカラムを曖昧検索してください 」という意味になります。
_contはマッチャと呼ばれるオブジェクトで、これは曖昧検索を意味しています。
（参考：_eqにすると完全一致となります。）

他にもたくさんあるので、下記を参考に最適なものをご選択くださいね

http://nekorails.hatenablog.com/entry/2017/05/31/173925

ここで、検索キーワードの送信
までは完成しました。

検索結果を表示するために、「 search.html.erb 」を作成し、「 @items 」を表示する記述をしていきましょう。

### ⑤検索結果を表示する

下記は本当に参考程度に見てください笑

```search.html.erb
<%= render "shared/header" %>
<div class='main'>
  <%# 商品一覧 %>
  <div class='item-contents'>
    <div class="item-container">
      <ul class='item-lists'>
        <% if @q.name_cont != nil %>
          <h3 class="subtitle"><%= "#{@q.name_cont} の検索結果" %></h3>
        <% else %>
          <h3 class="subtitle"><%= "検索結果" %></h3>
        <% end %>
        <%= render partial:"item", collection: @items, locals: {item: @item} %>
      </ul>
    </div>
  </div>
  <%# /商品一覧 %>
</div>
<%= render "shared/footer" %>
```

これで動画と同じ簡単なransack検索機能の実装は完了となります。
次回は複雑検索について書いていきますね
また読んでいってくださいね！！
【随時更新予定】Qiitaの使い方(備忘録）

##この記事について

・プログラミング学習を進める際に備忘録としてQiitaを活用したい!
・そのためにはQiitaの使い方を知る必要がある!
・したがってひたすらQiitaの使い方をまとめていきます。（随時更新予定）

##目的
####1.情報のインプット
　アカウント登録をすることで「タグ」や「ストック」の機能を使うことができ、
　より効率的な情報のインプットが可能。
####2.情報の整理
　自分で学習したことを記事としてまとめることで、情報を自分なりに理解することができ、
　後から見返すこともできる。
####3.情報のアウトプット
　情報をアウトプットすることでより理解が深まり、同じ悩みの人の手助けになる！

##Qiitaへの登録
①まず、QiitaのTopページへアクセス
　→画面右上に**ユーザー登録**ボタンがあるのでこちらをクリック
　→ユーザ登録画面が表示され、以下より登録方法を選択します。

　　　　**GitHubアカウントで登録(連携)**
　　　　**Twitterアカウントで登録(連携)**
　　　　**Googleアカウントで登録(連携)**
　　　　**Qiita用アカウントを作成して登録**

②選択できたら、画面案内に従って登録を進めてください。

##Qiitaの使い方
ここまでくればあなたも立派なQiitaユーザーの仲間入りです！
ではここからは投稿の仕方を説明していきます！

とはいっても投稿はとても簡単です。

①「新規作成の投稿」ボタンをクリックすれば、記事の編集画面を開くことができます。
②タイトル、タグを設定
③いざ本文へ！

###注意事項
**100MB制限**
Qiitaの記事中に画像を挿入する際に注意しておきたいのが「100MB制限」。

これは、月間で100MBまでの制限があるというポイントです。

記事の内容などによっては画像をふんだんに使用したい場合もあるかと思います。

そういう際には画像容量に注意して投稿する必要があるでしょう。

画像圧縮などを活用するのも1つのアイディアかもしれません。


**MarkDown記法**
Qiitaの記事本文を執筆する際には、Markdown記法が利用できます。

Markdown記法については説明が多岐に及ぶため、公式のチートシートをご覧ください。

以下のリンクからチェック可能です。

[Markdownチートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)

上手く使いこなせれば、執筆の効率やスピードを劇的に向上させることができるでしょう。
Flipper をオプトアウトして React Native の CIビルドを速くする【iOS】


# 概要

最近 React Native CLI で作成したiOSアプリのビルドが遅くて気になる場合は、Flipper をオプトアウトするとビルドを短くできるようです。

# Flipper

[Flipper](https://fbflipper.com)は、React Native アプリなどをデバッグするときに使うツールで、React Native 0.62 以降からデフォルトで Flipper を使うためのモジュールが組み込まれるようになりました。

# 普段使わないのにビルドに時間がかかる

iOSアプリの初回ビルドでは、Flipper関連のモジュールのビルドに時間がかかります。
ビルドキャッシュがあるときはよいですが、CIビルドなどでキャッシュがない場合ビルドに時間がかかることがあるので、改善したくなります。

# 対処

Flipper のトラブルシューティングのページに書かれているとおり、`ios/Podfile`でFlipper をコメントアウトすると、ビルド時間を短くできる場合があります。

```ios/Podfile
  # use_flipper!
  # post_install do |installer|
  #  flipper_post_install(installer)
  # end
```

コメントアウト後、pod installが必要です。

```
cd ios && pod install
```

CI実行時だけ無効化したい場合、環境変数で分岐するようにするといいみたいです。
CI環境で、CIという環境変数が定義されている場合の例。

```
  if !ENV['CI']
    use_flipper!
    post_install do |installer|
      flipper_post_install(installer)
    end
  end
```

# 参考

- https://fbflipper.com/docs/troubleshooting/#opting-out-from-flipper-ios
- https://github.com/facebook/flipper/issues/1326
簡単！画像解析AI　実装方法

#まえがき
今回は画像解析のAIの実装方法について解説します。
難しそうと思うかもしれませんが、PCがあればできてしまいます。
機械学習に興味がある方は、やってみてください。
スタートを切るのにはもってこいです！


#目次
・環境
・手順
・参考文献



#環境
windows10
SublimeText


#手順
##１．googleアカウントを作る
googleアカウントを持ってない方は作成。

##２．googlePlatformに登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855269/01bafbe8-1683-a2b4-f1c7-51715025a567.png)

[GooglePlatformCloud](https://console.cloud.google.com/)

↑このリンクにアクセスして、無料で開始（あるいは画面右上「有効化」）をクリック
すると必要な情報の入力に移る。
この登録を進めていく上での注意点や不安解消をさせてもらいます。

###2-1　完全無料なの？
厳密にはNOです。
ただ、お金がかかる条件というのが、月に１０００回実行するとかなので、個人的に利用する分にはお金がかかる心配はないです。
###2-2　支払い先情報
これは必須です。
Netflixやfuluなど、無料期間を利用するのには、クレカの情報が必要なのと一緒です。
ただ、GoogleCloudPlatformに関しては、期間ではなく利用回数によって優良になるよ。ということです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855269/478d0c70-cbe2-1584-1198-f1af9444433b.png)
請求先アカウントを選択。

登録が一段落すると、ようこそ！と表示が現れ、利用が可能になります。




##３．プロジェクトの作成
コンソール画面に辿り着いたら、プロジェクトを作っていきます。
AIの利用設定みたいなことをやっていきます。


プロジェクトの選択　→　プロジェクトの作成　→　適当に入力して作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855269/e813d493-5762-d91d-e435-42616c00ac3b.png)
画面上の検索窓にvisionAPIと検索し、有効化する。

使用するAPI　→　CloudvisionAPI
～でこのAPI使う？　→　いいえ
キーのタイプ　→　JSON
ロール　→　なし

##AIを利用できるようにする。
###鍵の生成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855269/a7a41ca8-8525-29d7-2c79-4cf790b14404.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855269/3dd5e6b8-d245-e347-648d-4064f404b204.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855269/b1c7cf06-8e7f-e1a6-deec-026de8b848b8.png)

JSONファイル（鍵）が生成され、ダウンロードされます。大事にとっておいてください。

###環境変数の設定
自分のPC上にフォルダを作成し、そのフォルダを入れます。
windowsならば、windowsの検索ツールで、「システムの詳細設定」と検索
システムのプロパティ　→　詳細設定　→　環境変数　→　新規
「変数名」→　GOOGLE_APPLICATION_CREDENTIALS
「変数値」→　参照　→　さっきのJSONファイル

ここで一度再起動を行うと設定が反映されやすいかもしれないです。


##４．コーディング
いよいよコーディングです。
が、とりあえずコピペして解析するのがいいと思います。

画像をimg_01という名前で保存して、プロジェクトフォルダ内に追加しておくのもお忘れなく

```
from google.cloud import vision

with open("img_01", 'rb') as image_file:
	content = image_file.read()

# visionAPIが扱えるデータ形式
image = vision.Image(content=content)
# print(image)

# インスタンスを生成
annotator_client = vision.ImageAnnotatorClient()

response_data = annotator_client.label_detection(image=image)

labels = response_data.label_annotations

print('--------RESULT--------')
for label in labels:
	print(label.description, ':', round(label.score * 100, 2), '%')
print('----------------------')	
```

##５．実行結果を見る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855269/00453bd6-a631-467e-f5b3-f2b9e5121168.png)


#参考文献
https://cloud.google.com/vision/docs/setup?hl=ja

#さいごに
自分もここから初めてまもないので、共に楽しみましょう～
[Android]Handlerの非推奨の解決策&ちょっと理論的な事も

#非推奨になっちゃうやーつ

```kotlin:
const val DELAY_TIME = 1000

fun delayDelay() {
     Handler().postDelayed({
             // 遅延させたい処理
          }, DELAY_TIME)
}
```
正しくは

```kotlin
Handler((Looper.getMainLooper())
```
Handlerの引数を指定してあげてください。
#なんで？
ついでに、Handlerについて理論的な事を少しだけ喋ります。

登場人物が多いですが、こう例えてください。
Handler ＝「トラック」
Message Runnable ＝「荷物」
Looper  ＝「工場」
Queue   ＝「先入れ先出し」
Message Queue ＝「ベルトコンベアー」

Androidのメインスレッド（UIスレッドと同じ）には、工場（Looper）が元々あります。
そして、工場内にはMessage Queueという「ベルトコンベアー」があります。
ベルトコンベアーは、Queue「先入れ先出し」方式でMessage、Runnable「荷物」を管理しています。
先入れ先出しとは、先に入れたものが先に出るということで、コンビニとかスーパーでバイトしたことある人は分かるかなと。

そして、ベルトコンベアの先はトラック「Handler」です。
このHandlerが荷物（Message）を処理してくれます。

またHandlerは、他の工場（スレッド）から荷物（Message,Runnable）を受け取り、ベルトコンベアー（Message Queue）に流す役割もあります。

よく見るpostとpostDelayは、ベルトコンベアーに荷物を送る作業なんです。

と、ここでHandlerの引数の話に戻します。
引数を指定しないと、暗黙的にLooperが指定されてしまいます。

メインスレッドには、メインスレッド用の工場があります。
Androidは、UI操作をメインスレッドでしか担えないのはご存じかと思います。

つまり、暗黙的なLooperの指定は場合よってはクラッシュのもとになるので、明示的にLooperを指定してあげないといけないよ！

という意味での非推奨だったのです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599059/f695fe7a-ca9f-ac32-9ab2-bd4b41dc584e.png)
注）エンジニアに絵心を求めてはいけない

#終わり
Handlerについてもっと深く掘り下げたかったのですが、まだ理解が足りなかったようで、これくらいにしておきます。
ただ、この工場の比喩を元に考えたり、実際に実装したり、比喩の整合性を整えたりすると理解するのは時間の問題かなと思いました。

工場長は、いつでもツッコミお待ちしております＾＾
キューではなく、スタックでお受けします。
MAC OS Big Surにしたら案の定xcrun: error: invalid active developer pathほにゃららが出たから備忘録

#前置き

みなさん、お疲れ様です。
Big Surのことをつい最近までビッグシューって呼んでました。
本当はビッグサーと呼んで、カリフォルニアの人口少ない場所らしいです。
ちなみにMojaveも今までモジェイブって呼んでました。
#課題

ところで、OSアップデートしてからgitやらandroid studioでビルドしようとしたら毎回

```
xcrun: error: invalid active developer path
```
って出ませんか？
#対策
その度にググって「ああーそうそう、ターミナルでこれ打てばいいんだったわ」ってなるので
備忘録として書いておきます。

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

これで忘れない！