OmniAICreator/Qiita-1.07M huggingface dataset:
マウントして、パスも通しているのにGoogle Colaboratoryにモジュールをインポートできない😭👉ランタイムを再起動しましょう

✏️この記事について
---
GPUが手軽に使えるGoogle Colaboratoryですが、モジュールインポートの際にハマったのでメモします

✨教訓👉困ったら、とりあえず、ランタイムを、再起動💻
---
[こちら](https://qiita.com/Kunikata/items/45e731753e97bda28aab)を参考にしながらモジュールのインポートを行なっていたのですが、なぜかうまくいきません...
```ModuleNotFoundError: No module named 'functions'```
🤔
```sys.path.append```でパスも通している、
サイドメニューにもファイルは表示されている...なぜ...?

小一時間悩んだのですが、[こちら](https://blog.mktia.com/file-access-from-colab-to-google-drive/)に答えがありました。

>ドライブ内に新たにファイルを追加したときの注意点
>---
>Colab 実行中にドライブにファイルを新しく入れたり作ったりしても，ランタイム起動時の設定で動いているので反映されません．
>一度 [Restart] > [Restart rumtime] でランタイムを再起動してください．

なるほど〜😂

参考サイト様
------------
[ColabでGoogleドライブ内のファイルを読み込む | mktia's note](https://blog.mktia.com/file-access-from-colab-to-google-drive/)
[Google ColaboratoryでGoogle Drive上の.pyファイルをインポート - Qiita](https://qiita.com/Kunikata/items/45e731753e97bda28aab)
GoogleAppScript+clasp+TypeScriptで作るSlackBot


株式会社アクシスのアドベントカレンダー23日目の記事です🎄

GASを使って社内用のSlackボットを開発しようと思ったのですが
GASのブラウザエディタの使い勝手があまり良くなく、個人的には好みではありませんでした...

なので色々と試してみたところ [clasp](https://github.com/google/clasp) を使えばローカルのエディタで開発でき、さらにTypescriptでのコーディングもサポートしていたのでその手順をまとめてみました!

# 手順
## claspインストール

まずはプロジェクト作成

```bash
$ npm init -y
```

claspインストール

```bash
$ npm install -D @google/clasp
```

最後にGAS用のTypescript定義をインストール

```bash
$ npm install -D @types/google-apps-script
```

## clasp設定

Googleにログイン

```bash
$ npx clasp login
```

ブラウザでGoogleのログインフォームが表示されるのでログイン情報を入力
権限を許可するか聞かれるので「許可」をクリック

ターミナル上に認証成功のメッセージが表示されていればOK

```bash
Authorization successful.

Default credentials saved to: ~/.clasprc.json
```

成功したらclaspプロジェクトを作成
スクリプトの種類を聞かれるので `standalone` を選択

```bash
$ npx clasp create ${プロジェクト名}

? Create which script? (Use arrow keys)
❯ standalone
  docs
  sheets
  slides
  forms
  webapp
  api
```

## push

claspはTypeScriptをサポートしているので、ts拡張子ファイルをpushした場合はJavascriptにトランスコンパイルしてpushしてくれる。

とりあえず動作確認のためにコードをpushしてみる

```bash
$ echo 'const helloWorld = () =>  Logger.log("Hello, App Script!");' >> app.ts
$ clasp push
$ clasp open
```

ブラウザが開くのでコンパイルされたGASコードが表示されたらOK

```js
// Compiled using ts2gas 3.6.3 (TypeScript 3.9.7)
var helloWorld = function () { return Logger.log("Hello, App Script!"); };
```

## bot作成

botの作成については~~時間がなかったので~~ @_nsk_さんがアドベントカレンダーで書いてくれてたので割愛
https://qiita.com/_nsk_/items/b8b2f71cfbecb6e2ec59#2incoming-webhook-%E3%81%AE%E8%A8%AD%E5%AE%9A

## 感想

無料でコードを実行できる環境としてGoogleAppScriptを愛用していましたが
claspのおかげでさらに好きになりました。(時間があればBot作成の部分を詳しく書きたい...)

皆さんもボット開発を行いたいときはGoogleAppScript+claspで開発してみてはいかがでしょうか?
PHP 標準関数を使用せずに一つの文字列から特定の１文字を取得する

今まではsubstrを使っていたが$string[取得したい文字の要素]でも取得できる

```php
$string = "abcdef";
echo $string[1]; // b
echo $string[3]; // d
```

またこの考え方を応用すれば文字列を１文字ずつ取得して配列にする場合も標準関数のstr_splitを忘れている場合でも実装できる

```php

$string = 'abcdef';
// echo $string[3] . PHP_EOL;
$array = [];
for ($i = 0; $i < strlen($string); $i++) {
  $array[] = $string[$i];
}
print_r($array);
```

結果

```
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => e
    [5] => f
)
```

# 配列からも１文字取得してみる

```php
<?php
$teamA = ["cod", "bf", "r6s"];
echo $teamA[0][1] . PHP_EOL; // o
echo $teamA[2][1] . PHP_EOL; // 6
echo $teamA[1][1] . PHP_EOL; // f
echo $teamA[2][2] . PHP_EOL; // s
echo $teamA[2] . PHP_EOL; // r6s
?>
```
【SQL Server】データ型の定義＆使用に相関する知識


varchar：１０（byteMaxLengthValidator）
　　あああああ、abcdeabcde・・・・・・バイト数

nvarchar：１０（maxlength）
　　　　　※Unicodeでデータ保存（文字化け防止できるが、
           SQL文に　【UPDATE/INSERT N'中国語など'】【Where XXX like N'%中国語など%'】で良い）
　　あいうえおあいうえお、abcdeabcde


char:　 1桁の場合、半角1個でもOK
 　　　 2桁の場合、半角2個で、全角1個もOK

nchar: space付で表示されてしまう
【備忘録】SVN（サブバージョン）の使い方メモ

自分のローカルのファイルを最新の状態にしたい場合の手順。
XAMPP/htdocs/最新にしたいフォルダで右クリックで「tortoiseSVN」→マージをクリック。マージ元のURLと作業コピー（コピー先）を確認して実行する。これが所謂「逆マージ」と言われる手法。
Excel Web Api  備忘録

<h2>注意点：
・ストアに上げないと、配布しにくい（手動でしかないようで、かつ、保守しにくい）
・Excel Build Version にめちゃくちゃ関係あるので、注意しなければ開発自体に変な問題沢山でてくる
・excelApi1.1~1.12のサーポトはExcel Build Versionによること。

１．Office JavaScript API　リファレンス　ドキュメント 
　　https://docs.microsoft.com/ja-jp/office/dev/add-ins/reference/javascript-api-for-office

２．Office アドイン ドキュメント 
　　https://docs.microsoft.com/ja-jp/office/dev/add-ins/ 

その他
window10 officeキャシュークリアしたいなら
del /s /f /q %userprofile%\AppData\Roaming\Microsoft\Excel
del /s /f /q %userprofile%\AppData\Roaming\Microsoft\Office\16.0
del /s /f /q %LOCALAPPDATA%\Packages\Microsoft.Win32WebViewHost_cw5n1h2txyewy\AC\#!123\INetCache\
del /s /f /q %LOCALAPPDATA%\Microsoft\Office\16.0\Wef\
【Azure】Blob Storage のライフサイクルについて

#Azure Blob Storage のライフサイクルで出来ること
この度、仕事で Azure Blob Storage のライフサイクル機能を利用することになり、その際に調べた内容となります。

まずは、何事も公式のドキュメントを確認です。
Microsoft 社のドキュメントには以下のように記されています。
[Azure Blob Storage アクセス層の自動化によるコストの最適化
](https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-lifecycle-management-concepts?tabs=azure-portal)

>・パフォーマンスを最適化するためにアクセスされた場合、BLOB をクールからホットに直ちに移行する
・コストを最適化するために、一定期間にわたってアクセスも変更もされていない場合、BLOB、BLOB のバージョン、BLOB のスナップショットをよりクールなストレージ層に移行する (ホットからクール、ホットからアーカイブ、またはクールからアーカイブ)
・ライフサイクルの最後に BLOB、BLOB のバージョン、BLOB のスナップショットを削除する
・ストレージ アカウント レベルで 1 日に 1 回実行されるようにルールを定義する
・コンテナーまたは BLOB のサブセットにルールを適用する (名前のプレフィックスまたは インデックス タグをフィルターとして使用)


#Azure Portal からライフサイクルを設定する
■ライフサイクルの作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287028/910576a8-59af-e3a9-0b7e-a0afc4039c56.png)

・ルールの範囲
Storage アカウント全体、もしくは指定したBlobを対象にルールの範囲を設定することができる。

・BLOB の種類
ルールの対象となる Blob の種類を複数設定することができる。

・BLOB のサブタイプ
基本 BLOB / スナップショット / バージョン の中から複数を対象に設定することができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287028/ab5c9948-8e2f-97eb-ca9a-9f837fc8da62.png)
 
・最終更新日
最終更新日から○日経過した、Blob を対象に設定することができます。

・結果
削除及び、アーカイブの設定をすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287028/cf3cc61b-5a50-e710-e2ca-b88e66610fde.png)
 

#検証
利用するにあたり、簡単な検証を行いました、
ライフサイクル機能を使用する場合、以下の要件が考えられます。
・「365日間更新がない場合、削除を行いたい」
・「30日間更新がない場合、アクセス層をクール層へ変更したい」
仮に30日間更新がない場合アクセス層をクール層へ変更したい場合、ライフサイクルの最終更新日の設定項目には、30 と設定したらよいのか、31 と設定したら良いのか、気になりました。

Azure の処理が24時付近、日付ベースで処理が実行されるのか、それとも時間ベースで処理が実行されるのか、Azure の処理がいつ行われているのか確認します。

・ライフサイクルの設定
・最終更新日：１
・結果：クール層へ移動

・sample Blob を作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287028/57cb76be-54fb-b807-3b04-13d2b2977a21.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287028/c88bdfcf-9518-f85d-8df0-358bf84a8897.png)
 
・結果
最終更新日を含めた、最終更新日時から24時間経過後にホット層からクール層へアクセス層が変更されていることが確認できました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287028/383338c4-b0b8-a682-1ea0-f4596885efb7.png)

保存期間を時間ベースで判定していることから、「30日間の保存を行った後に削除」といった要件では、データの保有したい期間＋１日と設定することがMASTとなりそうです。
switchを使わずにObjectでReducerを書く

# Reducerをオブジェクト(Object)で作りたい
ReactのフックAPIのリファレンスを見ると、以下のようにswitchを使ってReducerを定義している。
しかし、私はswitchがあまり好きではないので、オブジェクトで書くようにしている。

> ```example.js
const initialState = {count: 0};
> 
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}
```
引用: フックAPIリファレンス(https://ja.reactjs.org/docs/hooks-reference.html#usereducer)


# createReducer関数をつくる
以下のようにReducerを書けるようにcreateReducerという関数を作った。

```js
{
    [アクションタイプ1]: (state, action) => ({変更後のステート}),
    [アクションタイプ2]: (state, action) => ({変更後のステート}),
    ...
}
```

``` createReducer.js
export const createReducer = (initialState={}, handlers={}) =>
  (state = initialState, action) =>
    handlers[action.type] && handlers[action.type]({...state}, action) || {...state}
```

説明は割愛するが、これを利用することで、前述のフックAPIリファレンスのサンプルコードを以下のように書くことができる。

```example.js
const initialState = {count: 0};

const reducer = createReducer(initialState, {
  ['increment']: state => ({...state, count: state.count + 1}),
  ['decrement']: state => ({...state, count: state.count - 1})
}), initialState)
```

また、 payloadがある場合には、以下のように書くことができる。

```example.js
const reducer = createReducer(initialState, {
  [UPDATE_SUGGESTION_ITEMS]: (state, {payload}) => ({...state, suggestionItems: payload}),
  [FETCH_POSTS]: (state, {payload}) => ({...state, tmpResult: payload}),
  [FETCH_POST_DETAIL]: (state, {payload}) => ({...state, post: payload}),
}), initialState)
```
DateFormatter(short, medium, long)


DateFormatter
.dateStyle
.timeStyle

それぞれの出力結果


```short.swift

let dateFormatter = DateFormatter()

dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
print(dateFormatter.string(from: Date()))

// 12/23/20, 1:42 PM

```

```medium.swift
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .medium
print(dateFormatter.string(from: Date()))

// Dec 23, 2020 at 1:42:57 PM
```


```short.swift
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
print(dateFormatter.string(from: Date()))

// December 23, 2020 at 1:42:57 PM GMT+9

```
特定のバージョンのCocoaPodsをインストールする

ちゃんとバージョン合わせないと動かない時があるのでちゃんとチームで合わせましょう。

[CocoaPods](https://cocoapods.org/)

※2020/3のブログ記事の転載になります

# 手順0-1 brewでいれたものがあれば削除
podは公式だとgemでインストールする手順が紹介されていますが、brewでもインストールする事ができます。

homebrewでいれたバージョンが入っていると、gemでインストールしてもうまくいかなかったりするので、消してしまいましょう。

今動いているpodが、brewでいれたものかどうかは、pathをみればわかります。

```shell

$ which pod
/usr/local/bin/pod
```

となっていたら、brew版が入っています。brew版は大体古いです。

gemでいれた場合は、↓のような感じになります。（rbenvを使っている場合）

```
/Users/XXXXX/.rbenv/shims/pod
```

削除はこのコマンドで。

```shell

$ brew uninstall cocoapods
```

# 手順0-2 既存のバージョンを削除
```shell

$ gem uninstall cocoapods
```

今入っているバージョンは一旦削除しちゃいましょう。

# インストール
```shell
$ gem install cocoapods -v 1.8.4
```


うまくいけばこうなります。

```shell

$ pod --version 
1.8.4
```

# おまけ
バージョンが違うとこんなwarningが出ることがあります。

```shell

    [!] The version of CocoaPods used to generate the lockfile (1.9.0) is higher than the version of the current executable (1.8.4). Incompatibility issues may arise.
Incompatibility issues may arise.（互換性がない事によるなにかが起こるかもしれないよ）
```

という事なので、おとなしく合わせておきましょう。

# 参考

[CocoaPodsのバージョンアップの方法 - Qiita](https://qiita.com/Yuta/items/a20f4ea3207635b4ef9e)
[Gemのインストール、バージョン指定など - Qiita](https://qiita.com/pugiemonn/items/0c73e99d39d36f6ed56c)
Graphite vs. New Relic　〜監視ツールを比較してみた〜

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614998/0c283896-e06e-6052-11a1-f9f9ecd54cb4.png)


#Graphiteとは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614998/5fab951e-f8b9-c761-4eee-af9e32603eea.png)

Graphiteは、2008年に最初にリリースされたオープンソースの時系列監視ソフトウェアです。プッシュベースの監視ソフトウェアです。つまり、すでに表現されている情報を取得してメトリクスを収集し、それを記録して視覚化します。 Graphiteは通常、StatsDまたはcollectdと連携して、インフラストラクチャから時系列メトリックを取得します。 次に、メトリックは集約され、GraphiteのデータベースであるWhisperに保存されます。 Graphiteは、企業にデータの監視、保存、視覚化、および特定のイベントに関するアラートを提供します。 セットアップやメインテナンスが不要なGraphiteは、パッケージに含まれているGrafanaとともにMetricFireから入手することができます。

[無料トライアル](https://www.hostedgraphite.com/signup?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Graphite%20vs.%20New%20Relic)を入手して、[MetricFire](https://www.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Graphite%20vs.%20New%20Relic)の使用をすぐに開始してみてください。 MetricFireのHostedGraphiteがあなたにぴったりかどうかを確認できます。 ご不明な点がございましたら、いつでも[デモを予約](https://www.metricfire.com/demo-japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Graphite%20vs.%20New%20Relic)して直接お問い合わせください。

#New Relicとは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614998/d363fb44-f828-b1d1-56bb-81efa861ee66.png)

New Relic Oneは、New Relicのプラットフォーム全体の名前です。

- ログ、メトリック、トレース、およびアプリケーション監視をすべて1か所に統合できます。
- New Relic Oneはそれ自体を観測可能性ツールとして主張することが可能
- クラウドおよびデータセンターベースのシステムで利用可能
- New Relic Oneはシステムのどこからでもデータを取り込むことができ、システムに接続し続けるためのアラートを提供
- New Relicはプログラムも可能で、チームはビジネスに最適な新しいアプリケーション監視システムを設計可能
- New Relicには、ページの読み込み時間の短縮とエラーの特定に焦点を当てたブラウザー監視サービスもあり、チームが最も必要な場所に開発者を割り当てることが可能

#MetricFireのHosted graphiteの使用が適している時は？
次の場合はHosted Graphiteを使用してみてください。

- インフラストラクチャの時系列監視が必要である
- 複数の異なるソースからのデータを視覚化する必要がある
- 重要なイベントについて警告する必要がある
- インフラストラクチャが大きすぎて自分で実行できないため、マネージドサービスが必要である

#いつNew Relicを使用するべきか
次の場合にNew Relicを使用が適しています。

- ログ、トレース、メトリック、インフラストラクチャ、アプリなどを監視したい。
- 可観測性のダッシュボードを作成したい。
- ブラウザの速度またはモバイルブラウザの速度を監視したい。

#価格の比較

- Graphiteはオープンソースであり、無料です。
- Hosted Prometheus、Hosted Graphite、GrafanaなどのMetricFireによるビジネス対応のGraphite as a Serviceは、月額99米ドルからです。
- New Relic for businessは、ホストあたり月額149米ドルから始まり、エンタープライズの価格設定段階はそれを上回ります。

#重要なポイント

- Graphiteは、あらゆる種類の時系列データを監視、保存、警告、および視覚化できます。

- Graphiteはオープンソースであり、無料です。
- New Relicには、1つのプラットフォームに組み立てて、可観測性ダッシュボードを作成できるさまざまな製品があります。

Hosted Graphiteについて詳しく知り、[MetricFire](https://www.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Graphite%20vs.%20New%20Relic)が監視環境にどのように適合するかを確認してください。 [無料トライアル](https://www.hostedgraphite.com/signup?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Graphite%20vs.%20New%20Relic)を入手して、今すぐGraphiteの使用を開始してください。 [デモを予約](https://www.metricfire.com/demo-japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=Graphite%20vs.%20New%20Relic)して、HostedGraphiteで何ができるかを確認してください。
WSL2 で Ubuntu を起動すると「プロセスはコード 1 で終了しました」と出たときに対処したこと

原因は後述するけど、対処方法が中々見つからず、諦めてディストリビューションを再インストールしようと調べていたら、見つけたので記録しておきます。

## 対処
Powershell から 以下のコマンドでrootでログインし、規定のユーザーのログインシェルを /bin/bash に変える。

``` PowerShell
wsl -u root
chsh -s <user_name>
```

これで、bashでログインできた。

### 原因
homebrew(linuxbrew)で、zshをいれてログインシェルにしていたんだけど、homebrewをいじっていたらzshがアンインストールしちゃったため。
色々、調べててて Powershel から `wsl sudo <command>` っていうのは見かけたんだけど、それを叩いても直らなかった。

再インストールしようと [公式ドキュメント](https://docs.microsoft.com/ja-jp/windows/wsl/wsl-config#unregister-and-reinstall-a-distribution) を見ていたら、すぐ下に「特定のユーザーとしての実行」セクションがあって良かった。
Unity2019.4.16/Locamotion

[環境]
Unity2019.4.16

[Memo]

・PackageManager

Oculus Desktop
Oculus Android

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/3b417159-4414-89a4-7be1-bbaf6a30a186.png)

・XR managementは使わない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/81b0697a-67f2-e701-51f2-85dd2d467ad3.png)
Workmanager等のバックグラウンド処理を入れたら、FCMが使えなくなった時の対処法

## 環境
- Mac OS Catalina
- Flutter
- Firebase

## やりたいこと
下記のような形でFCMと同時に他のバックグラウンド処理をやりたい

- FCM( remote notification )
    - Foreground
    - Background
    - Killed
   
- [FlutterGeofencing](https://github.com/bkonyi/FlutterGeofencing) 
    - Foreground
    - Background

- [Workmanager](https://pub.dev/packages/workmanager)
    - Background
    - Killed


## 問題
Workmanager等のバックグラウンド処理を実装完了して喜んでたら、iOSで(Android はwork)、FCMを使った通知が来なくなっていた…

## 解決策
[Firebase Cloud messaging でのメソッド実装入れ替え](https://firebase.google.com/docs/cloud-messaging/ios/client#method_swizzling_in) を設定する必要があったみたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/557811/bb608b8f-d76b-df8f-4926-f99b6916ce7e.png)

変更するファイルは、 `info.plist` と `AppDelegate.m` の2つ

```info.plist
    ...
    <key>FirebaseAppDelegateProxyEnabled</key>
	<false/> 
   ...
```

```AppDelegate.m
@import Firebase;

void registerPlugins(NSObject<FlutterPluginRegistry>* registry) {
  [GeneratedPluginRegistrant registerWithRegistry:registry];
}

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //Other plugins
   [GeneratedPluginRegistrant registerWithRegistry:self];
   return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

// このメソッドを追加
- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [FIRMessaging messaging].APNSToken = deviceToken;
    [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}


@end

```
有限オートマトン(finite state machine)を単純化して考える

## 有限オートマトン

Acca Actorでは、有限オートマトン(finite state machine)と呼ばれる振る舞いのモデルを用いることができる。
また、これを実装しやすくするために、FSMというトレイトが用意されている。(自ら実装してもよい)

ただし、有限オートマトンはAkka(Actor)がなくても成立する概念なので、
Actorの要素を取り除き、シンプルな有限オートマトンを実装して説明する。

有限オートマトン(wikipedia)
https://ja.wikipedia.org/wiki/%E6%9C%89%E9%99%90%E3%82%AA%E3%83%BC%E3%83%88%E3%83%9E%E3%83%88%E3%83%B3#UML%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%9E%E3%82%B7%E3%83%B3

## 有限オートマトン(finite state machine)を単純化して考える

```Scala:State.Scala 
/** 状態 */
sealed trait State{
  /** 振る舞い */
  type Behavior = Command => State
  /** 状態名 */
  val stateName: String
  /** 次の状態(コマンド→状態変換の振る舞い) */
  val getNextState : Behavior
}

/** 最終状態(もう状態変化が起こらない状態) */
sealed trait FinalState extends State {
  /** 次の状態(どのコマンドが来ても、今の状態に等しくなる) */
  override final val getNextState : Behavior = {
    case StartProcess => this
    case ProcessFinishSafety => this
  }
}

case object WaitingForRequest extends State {
  override val stateName: String = "WaitingForRequest"
  override val getNextState : Behavior = {
    case StartProcess => Processing
    case ProcessFinishSafety => Terminated
  }
}

case object Processing extends State {
  override val stateName: String = "Processing"
  override val getNextState : Behavior = {
    case StartProcess => Terminated
    case ProcessFinishSafety => Finished
  }
}

case object Finished extends FinalState {
  override val stateName: String = "Finished"
}

case object Terminated extends FinalState {
  override val stateName: String = "Terminated"
}
```

```Scala:Command.Scala 
/** コマンド */
sealed trait Command
/** 処理を開始させるコマンド */
case object StartProcess extends Command
/** 処理中に安全に終了させるコマンド */
case object ProcessFinishSafety extends Command
```

```Scala:FakeActor.Scala 
import java.util.Objects

/** AkkaActor要素を取り除いた有限状態マシン。Akka Actorを使用する場合は、この部分が実際のActorとなる。 */
final class FakeActor(){
  /** 状態(初期状態) */
  private var state : State = WaitingForRequest
  /** 状態の確認 */
  def getState : String = state.stateName

  /**
   * コマンドを送信して、状態を変更する
   * @param command コマンド
   * @return 結果、状態が変動するか
   */
  def goNextState(command: Command): Boolean = {
    val next: State = state.getNextState(command)
    val changed: Boolean = !Objects.equals(state,next)
    state = next
    changed
  }
}
```

### Applicationからの利用

```Scala:trait.Scala 
object Application extends App {
  System.out.println("-------SUCCESS--------")
  val success = FakeActor()
  System.out.println(success.getState)
  System.out.println("changed:" + success.goNextState(StartProcess))
  System.out.println(success.getState)
  System.out.println("changed:" + success.goNextState(ProcessFinishSafety))
  System.out.println(success.getState)
  System.out.println("changed:" + success.goNextState(StartProcess))
  System.out.println(success.getState)

  System.out.println("-------FAILED--------")
  val failed = FakeActor()
  System.out.println(failed.getState)
  System.out.println("changed:" + failed.goNextState(ProcessFinishSafety))
  System.out.println(failed.getState)
  System.out.println("changed:" + failed.goNextState(StartProcess))
  System.out.println(failed.getState)
}
```
PUN2の2


# 前回
Unityアプリを２個起動して同期がとれている事は確認できました。またphotonView.IsMine で自分のオブジェクトを判別できるようになりました。

# PhotonTransformView
[同期用のオブジェクト](https://connect.unity.com/p/pun2deshi-meruonraingemukai-fa-ru-men-sono2)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/4b001bd5-d634-51cb-c253-8d3f4852958e.png)

Unreliable On Change ：　値が変化した場合のみ通信する

# 参考
[ゆめみ](https://github.com/yumemi-inc/vr-studies/wiki)

# パッケージのDEMOS

ロビー、ルーム、ルーム変更のコールバックなどがよくわからないし、動作するサンプルが少ない。コードの一部分だけでは勘違いしてしまうので動くサンプルがほしかった。
↓
パッケージにあった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/1f3955c0-092d-2a2f-fbef-2bd7f3f2a1ca.png)

# DEMOSの注意点

Scene In Buildで明示的に選択してしないと実行後の接続が失敗する。→　シーン遷移するから。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/546f1429-f925-9651-4238-9f6efcacefcc.png)

Launchers.csのOnJoinedRoomでシーンを指定してる
```
		public override void OnJoinedRoom()
		{
			LogFeedback("<Color=Green>OnJoinedRoom</Color> with "+PhotonNetwork.CurrentRoom.PlayerCount+" Player(s)");
			Debug.Log("PUN Basics Tutorial/Launcher: OnJoinedRoom() called by PUN. Now this client is in a room.\nFrom here on, your game would be running.");
		
			// #Critical: We only load if we are the first player, else we rely on  PhotonNetwork.AutomaticallySyncScene to sync our instance scene.
			if (PhotonNetwork.CurrentRoom.PlayerCount == 1)
			{
				Debug.Log("We load the 'Room for 1' ");

				// #Critical
				// Load the Room Level. 
				PhotonNetwork.LoadLevel("PunBasics-Room for 1");

			}
		}

```
わかりにくいvue.jsのwatch（ウォッチャ）のオプションを使った書き方

## 概要

vue.jsのwatchにはdeepとimmediateという2つのオプションがあるのですが、書き方がちょっと特殊なのと、マニュアル上で探しにくくいので、癖があります。
毎回ググってしまうので備忘録として残します。

※2019/9にブログに書いていた記事からの転記です

## watchとは

[vueのドキュメントの説明](https://jp.vuejs.org/v2/guide/computed.html#%E3%82%A6%E3%82%A9%E3%83%83%E3%83%81%E3%83%A3)
[vueのドキュメントの説明（API）](https://jp.vuejs.org/v2/api/index.html#watch)


普通は算出プロパティ（computed）でいいんだけど、複雑な処理（重い処理？）の時はこっちの方が良いよ〜との事。

## オプション

オプションについてはなぜかちょっと遠いところで、APIの中に記載があります。

[vueのドキュメントの説明]https://jp.vuejs.org/v2/api/index.html#vm-watch


### deep

通常、objectのプロパティの変更は、watchが発火しません。

```javascript
  data: () => ({
    someObject: {},
  )},
  watch: {
    someObject(newVal, oldVal) {
       console.log(newVal);
    },
  }
  methods: {
    onClick: function() {
      // watchが発火しない！
       someObject.hoge = 'hoge';
    },
```

deepをtrueにする場合はこう

```javascript
  data: () => ({
    someObject: {},
  )},
  watch: {
    someObject: {
        deep: true,
        handler(newVal, oldVal) {
          console.log(newVal);
       },
    }
  }
  methods: {
    onClick: function() {
      // watchが発火する
       someObject.hoge = 'hoge';
    },
```

handlerという関数を書かないといけないのが唐突なので、いつも書き方忘れる、、、、

### immediate

初期化のタイミングでもwatchが発火するようにしたい場合に使います。

これも、

```javascript
  data: () => ({
    someObject: {hoge: 'piyo'},
  )},
  watch: {
    someObject: {
        immediate: true,
        handler(newVal, oldVal) {
          console.log(newVal);
       },
    }
  }
```

という感じで、handler関数にいつもの処理を書いてあげる必要があります。

## 所感

なんでここだけマニュアルわかりにくいんだろ、、、
Webの仕組みとHTTPについて

##ブラウザとサーバー
ブラウザは今表示されてる画面
サーバーは色んなデータを保存してる大きなPCのようなもの
サーバーからファイルをダウンロードすることでブラウザに表示される
ファイルの中にはHTML、CSS、JSなどの情報が入ってる

図で表すとこんな感じ
　　　　　　
（ブラウザ）　←←←←←←　（サーバー）
　　　　　 　　　ファイル
　　　　　　　(HTML,CSS,JS)
##HTTP
HTTPとはブラウザとサーバーのやりとりの方法
基本はリクエストとレスポンス

　　　　　　リクエスト
　　　　　　→→→→→→
（ブラウザ）　　　　　　（サーバー）
　　　　　　←←←←←←
　　　　　　レスポンス

リクエストで欲しい情報をサーバーに投げてサーバーがその情報を返してくれる
このリクエストとレスポンスのやりとりのルールを作るのがサーバーサイド言語

##HTTPの基本メソッド４つ
1.GET データの取得
Webページを表示するときに使用

　　　　　このページ見たい
　　　　　　→→→→→→
（ブラウザ）　　　　　　  （サーバー）
　　　　　　←←←←←←
　　　　　　ページの情報


2.POST データの送信 
フォームなどでデータを保存するに使用

　       　　　　データ保存して
　　　　　　→→→→→→
（ブラウザ）　　　　　　（サーバー）
　　　　　　←←←←←←
　　　　　　保存したよ

3.PUT　データの更新
既存のデータを書き換えるときに使用

　　　　　データ変更して
　　　　　　→→→→→→
（ブラウザ）　　　　　　（サーバー）
　　　　　　←←←←←←
　　　　　　変更したよ

4.DELETE　データの削除
既存データを消すときに使用

　　     　　　データ消して
　　　　　　→→→→→→
（ブラウザ）　　　　　　（サーバー）
　　　　　　←←←←←←
　　　　　　　消したよ

Twitterで例えると
ツイートを表示 GET
ツイートの新規投稿 POST
ツイートの更新 PUT　（Twitterはできなかったはず）
ツイート削除　DELETE

##IPアドレスとドメイン
IPアドレスとはサーバー内でデータに割り振られている住所みたいなもので数字で管理されている
ドメインとは「~~.com」の部分
IPアドレスだと分かりにくいのでDNSというシステムがIPアドレスとドメインを紐付けている

##最後にWebサイト（Qiita）が表示されるまで

　　　　qiita.comのIPアドレス教えて
　　　　　　→→→→→→
（ブラウザ）　　　　　　（DNS）
　　　　　　←←←←←←
　　　　　IPアドレスを返す



　　DNSから取得したIPアドレスにGETリクエスト
　　　　　　→→→→→→
（ブラウザ）　　　　　　（サーバー）
　　　　　　←←←←←←
　　　　HTML、CSS、JSを返す

こんな感じです
クラウドに関する英単語

自己学習用、都度更新
頻度順でメモしていく。

## ★★★★★

|No.|English|Japanese|
|:-----------:|:------------|:------------|
|001|transaction|トランザクション|
|002|decide|決定する|
|003|performance|パフォーマンス|
|004|intelligence|情報|
|005|via|経由|
|006|stratgy|戦略|
|007|notification|お知らせ|
|008|mandate|委任|
|009|extend|拡張する|
|010|transact|取引する|
|011|multiple|複数の|
|012|startup|起動|
|013|implement|実装|
|014|analyze|分析する|
|015|analysis|分析|
|016|analyst|アナリスト|
|017|provide|供給する|
|018|encrypt|暗号化する|
|019|structure|構造|
|020|efficiency|効率|
|021|cost-effective|費用対効果|
|022|convert|変換する|

## ★★★★

|No.|English|Japanese|
|:-----------:|:------------|:------------|
|001|initiative|主導的|
|002|audit personnel|監査人|
|003|scale|スケール|
|004|increase|増加する|
|005|decrease|減少する|
|006|optimize|最適化|
|007|demand|要求する|
|008|generate|生成する|
|009|static|静的|
|010|aggregation|集約|
|011|detect|検出する|
|012|expect|期待する|
|013|usability|使いやすさ|
|014|collision|衝突|


## ★★★

|No.|English|Japanese|
|:-----------:|:------------|:------------|
|001|certain|特定の|
|002|accommodate|収納する|
|003|negatively|否定的に|
|004|automatically|自動的に|
|005|significant|重要、かなりの|
|006|ingestion|摂取|
|007|simplify|簡素化する|
|008|adopt|採用する|
|009|maintain|維持する|
|010|modify|変更する|
|011|duration|存続期間|
|012|particular|特有の、独特の|
|013|allocate|割り当てる|
|014|sufficient|十分な、足りる|
|015|predictable|意外性のない、予測可能な|
|016|lagged|遅れた|


## ★★

|No.|English|Japanese|
|:-----------:|:------------|:------------|
|001|universally|普遍的に|
|002|formal security policy|正式なセキュリティポリシー|
|003|innovation|革新|
|004|provision|供給|
|005|priority|優先度|
|006|advantage|利点、メリット|
|007|rotate|回転する|
|008|maximize|最大化する|
|009|invest|投資する|
|010|patent|特許|
|011|optical|光学、視覚の|
|012|suboptimal|最適ではない|

## ★

|No.|English|Japanese|
|:-----------:|:------------|:------------|
|001|retailer|小売業者|
|002|identifier|識別子|
|003|perspective|見方、観点|
|004|parcel|小包|
|005|reside|~に備わる|
|006|reproducible|再現性|
|007|agility|機敏的|
|008|elastic|弾性|
|009|indicate|示す|
|010|miscellaneous|その他|
|011|centralize|一元化する|
|012|penalize|罰する|
|013|hamper|妨げる|
|014|correlation|相関|
|015|overwhelm|圧倒される|
|016|entire|全体|
|017|symmetric|対称の|
|018|partial mesh|パーシャルメッシュ|
Code for Fukuoka 2020年振り返りと来年に残すもの

# Code for Fukuoka の2020年振り返り
## 1月
2019年に依頼した公園シェイプデータが福岡市からオープンデータとして公開されました。
福岡市の公園情報のオープンデータは、公園台帳、遊具（設備）台帳、シェイプデータとなりました。

福岡市エンジニアフレンドリーシティアワードをコミュニティ部門として受賞しました。
福岡市の事業であるエンジニアフレンドリーシティというエンジニアが住み良い場所に福岡市をしていくという取り組みにおいてコミュニティとしての活動を認められたものとなりました。![IMG_6779.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539161/9e55995b-625e-63f4-b6c1-ca28350c6174.jpeg)


## 2月
シビックテック✖️自治体イベントにて熊本で九州各地のシビックテックプレイヤーと自治体職員が集まりました。２０１８年Code for Kyushuキックオフから年に一度はこの時期に集まっているというもの。
ここで福岡県自治体職員さんとより一層繋がりました。

3月7日のInternational OpenData Dayの企画会議をしました。
福岡県自治体職員さんも参加いただいたり、新しい人も入ってきました。

## 3月
International OpenData Dayの企画はコロナの流行により中止となりました。
福岡市版のコロナ感染状況ポータルサイト（東京都版から）の作成、運営を始めました。
福岡県版のコロナ感染状況ポータルサイトの作成、運営を始めました。

## 4月
コロナ感染状況ポータルサイトについて読売新聞のWeb記事である「ささっとー」に取材いただきました。
また、担当の新聞社の方が新たにCode for Fukuokaに参加いただきました。
https://sasatto.jp/article/entry-521.html

## 5月
Pre CIVIC TECH FORUM 2020（オンライン開催）にて、Code for Fukuokaにて運営している福岡市版コロナ感染状況ポータルサイト、福岡県版コロナ感染状況ポータルサイトの話をしました。

ものづくり部にて手作りマスク会をしました。（オンライン開催）
希望者にはマスクキットを郵送するように材料の手配もしました。

2020年度キックオフの定例会をしました。（オンライン開催）
WikipediaTownと公園アプリ開発を進めることになりました。
また、コロナサイトの開発に入ってくれた方など新しい方の参加が増えました。

## 6月
アーバンデータチャレンジ2020のキックオフシンポジウム（オンライン）に参加しました。
３年目となる今回はコロナ流行によりオンラインでのイベントとなるため、福岡拠点は久留米と合同で行うこと
テーマはWikipediaTownと公園アプリ開発にすることを報告しました。
![UDC2020キックオフ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539161/921937ec-59f1-02df-f164-3ba126476c14.jpeg)


## 7月
今年度の活動会議（オンライン）を行いました。
更に新しい参加者が増えました。

## 8月
WikipediaTown開催に向けてウィキペディアンである海獺さんによる勉強会（オンライン）をしました。
その後、オンラインでのWikipediaTown開催に向けてメンバーで話し合いました。

## 9月
WikipediaTown体験会を人数限定で行いました。
体験会をしてみて、当初コロナ流行によりWikipediaTownをオンラインで開催することを考えていましたが、メンバーが重要と思う部分のオンラインでの実施が厳しいことがわかりました。

## 10月
九州産業大学の佐藤研究室にて、シビックテックやオープンデータについて話しました。
まちづくり研究をしている学生にとって、初めて聞く話だったようでとても興味を持ってもらいました。
文系学生たちですが、テクノロジーを使わなくとも使う人とまちの人を繋げる役目もあるなど知ることの意味など伝わりました。

## 11月
今年度の福岡市の市長広聴事業にCode for Fukuokaが選ばれ、福岡市長と1時間半の意見交換会をしました。
市長広聴事業は市民活動団体の活動に市長が参加して、意見交換をする事業ですが、コロナ流行のため活動参加は諦め、活動はスライドを使った紹介という形で進め、その後1時間余りのディスカッションをしました。
市長という立場からのご意見が非常に参考になったと共に、Code for Fukuokaの活動を知ってもらう場となりました。
![IMG_8537.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539161/f87b3757-b352-f403-c7b0-f4d100de4fb1.jpeg)

公園アプリ開発のキックオフを開発メンバーで行いました。
コロナ感染状況ポータルサイトの開発で入ってきたメンバーなど若手中心で進めることとなりました。

## 12月
定例会（オンライン）を行いました。
市長広聴事業での話や、公園アプリ開発の状況など共有し、来年の活動についてメンバーと共有しました。


Code for Fukuoka再スタートからの3年目、振り返りました。
当初予定していたアプリ開発も進んでいますが、今年は大学との連携や市長との意見交換会により今後の活動範囲がグッと広がる予感のある年となりました。
コロナ流行によりオンラインでのコミュニケーションがメインとなりましたが、その分いろんな方が新しく参加するきっかけにもなり、活動は進んだと感じました。

今年こそは衛星データを使ったイベントをと思ってましたが、残念ながらそれは実施できませんでした。来年以降タイミング見て行いたいと思います。
また、今年WikipediaTownを試しに行ってみて、その可能性や地域にもたらすものを知ったので来年も引き続き（リアル開催で）実施できたらと思います。

1年の振り返りってやっぱり良いですね。

最後に振り返りグラレコも。![名称未設定のアートワーク 21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539161/7f38d33f-974e-3cea-efa0-5b02ef5d77e5.jpeg)
MacにAnaconda Navigatorを用いてopencvをインストールする


Anaconda環境下でMacでopencvをインストールするときに少し手こずったので備忘録として書き留めておきます．

僕のような状況になった人が少しでも減ればと思います．

#環境

・OS:mac OS Catalina10.15.7
・Anaconda：1.7.2
・python：3.8.5


#Anaconda Navigatorでopencvaがインストールされているか確認

起動してサイドバーのEnvironmentsを選択するとこのような画面になります．

![スクリーンショット 2020-12-23 12.52.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469454/4c41b151-3f23-eb8f-b987-4d5024a889f9.png)

真ん中ぐらいのプルダウンを「Installed」にして「Search Packages」にopencvと入力しましよう．

この段階でopencvが出てきたらインストールされているので，もうこの記事は必要ないと思います．

出てこなかった場合，プルダウンを「Not Installed」に変え「Search Packages」にopencvと入力しましよう．

するとopencvが出てきます．

Applyを押すとインストールが始まります．


#python３．８ではインストールできない

しばらくするとエラーが出てきました．


>UnsatisfiableError: The following specifications were found
to be incompatible with the existing python installation in your environment:
Specifications:
  - opencv -> python[version='>=2.7,<2.8.0a0|>=3.5,<3.6.0a0|>=3.6,<3.7.0a0|>=3.7,<3.8.0a0']
Your python: python=3.8
If python is on the left-most side of the chain, that's the version you've asked for.
When python appears to the right, that indicates that the thing on the left is somehow
not available for the python version you are constrained to. Note that conda will not
change your python version to a different minor version unless you explicitly specify
that.

Deepl翻訳にぶち込みます．
>UnsatisfiableError。以下の仕様が見つかりました。
は、お使いの環境にある既存の python インストールとは互換性がありません。
仕様です。
  - opencv -> python[version='>=2.7,<2.8.0a0|>=3.5,<3.6.0a0|>=3.6,<3.7.0a0|>=3.6,<3.7.0a0|>=3.7,<3.8.0a0']
あなたの python: python=3.8
もし python が連鎖の一番左側にあれば、それはあなたが求めていたバージョンです。
pythonが右に表示されている場合は、左にあるものが何らかの形で
は、制約されている python のバージョンでは利用できません。conda は
明示的に指定しない限り、Python のバージョンを別のマイナーバージョンに変更します。


#対応：pythonのダウングレード

これで一発で解決できました．

エラー文のタイトルぐぐると同じような状況の人がいました．１）

※ちなみに「Mac　Anaconda　opencv　インストール」と調べても欲しい記事に当たりませんでした．

ターミナルを起動しpythonをダウングレードします．

```
$ conda install python=3.7
```


#再びAnaconda Navigatorでopencvをインストール

先程と同じ要領でopencvを見つけApplyを押します．


![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469454/4df54d58-f109-3650-abcc-287049e24856.png)


このような画面になったらインストール完了です．

お疲れ様でした．



##参考
1)AnacondaにOpenCVのインストールができなかったときの対処法-Qiita
URL:https://qiita.com/watalucky/items/6d48c982cdab007b6713
2)AnacondaにopenCVをインストールできなかった時の対処（2020.4）-Qiita
URL:https://qiita.com/c_geru/items/c100b03e9e8b69c7758a
FutureBuilder で、中々snapshotが返ってこない

## 環境
Flutter + Firebase + Providerを MVVMモデルで作っていた

## 問題
```
FutureBuilder 
   - StreamBuilder
       - FutureBuilder
```
のようなbuilder 処理がかなりのネストになっていたせいで、

- `Navigator.push` 後の画面表示や、初回表示(kill後アプリ表示) で、15sくらい処理がローディング状態であった

## 解決策

**`AsyncMemoizer`を使う**

一番top level のFutureBuilder にて、AsyncMemoizer を使ったら、格段に処理が速くなった

`AsyncMemoizer` の使い方は、 [ここらへんの記事](https://qiita.com/ytk_otona/items/c4a18cc155fdf8848ef3) を参照
【PHP】コンソールで変数の中身を確認する方法。var_dump, var_export, print_rの違い

コンソールで変数の中身を確認する関数はいくつか存在する。
結論からいうと`var_export`が一番使い勝手がいい。

##目次

1. [まとめ （var_dump, var_export, print_rの違い）](#まとめ-var_dump-var_export-print_rの違い)
2. [php対話モードの使い方](#php対話モードの使い方)
3. [print_r](#print_r)
4. [var_export](#var_export)
5. [var_dump](#var_dump)



<br>
##まとめ （var_dump, var_export, print_rの違い）

変数の中身を確認サクッと確認したいなら、`var_export`が便利。出力をそのままPHPコードとして使い回すことができる。

値の型も確認したい場合は`var_dump`を使う。引数に変数を２つ同時に指定することも可能。

| 項目 | var_export | var_dump | print_r |
|:-:|:-:|:-:|:-:|
| 値の型表示  | 無し  | 有り  | 無し  |
| $str = "AAA";  | AAA  | string(3) "AAA"  | AAA  |
| PHPコードとして利用  | 可  | 不可  | 不可  |
| $x = array('x' => 1);  | array ('x' => 1)   | array(1) {["x"] => int(1)}  | Array([x] => 1)  |
| 戻り値を返す  |　有り  | 無し  | 有り  |

３行目と５行目は左カラムの変数を引数として渡した場合の出力結果を表示。

一番役に立たたなそうなのが`print_r`。


<br>
##php対話モードの使い方
コード実行のためここでは対話モードを使う。

`php -a`

```
$ php -a
Interactive shell

php >
```


<br>
##print_r
変数の値を表示する。

・`print_r ( $expression [, bool $return = false ] )`

- $expressionには変数が入る。
- 第２引数は出力を戻り値とするか（任意）
    - デフォルトはfalse。戻り値なし。
    - 戻り値として出力する場合はtrueにする。


**▼実際の使い方**
・`print_r( 変数 )`　：変数の中身を確認したい
・`print_r( 変数, ture)`  :変数を代入する場合など


```:引き数１つの場合
php > $obj = array("a" => 1, "b" => 2, "c" => 3);
php > print_r($obj);
Array
(
    [a] => 1
    [b] => 2
    [c] => 3
)
```


###引数２つ（$return = true）
引数ありの場合は、戻り値が返るため変数に代入することができる。

```:第２引数にtureを指定した場合
php > $obj2 = print_r($obj, true);
php > print_r($obj2);
Array
(
    [a] => 1
    [b] => 2
    [c] => 3
)
```

上記処理の場合、いちいち`print_r(変数, true)`としなくても直接代入できる。

```:print_rを使わない処理
php > $obj3 = $obj;
php > print_r($obj3)
php > ;
Array
(
    [a] => 1
    [b] => 2
    [c] => 3
)
```

<br>
戻り値としない場合は代入できない

```:戻り値にしない場合
$obj2 = print_r($obj);
Array
(
    [a] => 1
    [b] => 2
    [c] => 3
)
php > print_r($obj2);
1
```



<br>
##var_export
変数のデータを構造化データとして返す。出力は有効なPHPコードになる。

`var_export ( $expression [, bool $return = false ] )`


```
php > $obj = array("a" => 1, "b" => 2, "c" => 3);
php > var_export($obj);
array (
  'a' => 1,
  'b' => 2,
  'c' => 3,
)
```

出力結果が`array('a' => 1, 'b' => 2, 'c' => 3)`となっており、連想配列の定義そのものになっている。



###第２引数ありの場合

```
php > $obj = array("a" => 1, "b" => 2, "c" => 3);
php > $obj4 = var_export($obj, true);
php > echo $obj4
php > ;
array (
  'a' => 1,
  'b' => 2,
  'c' => 3,
)
```


<br>
##var_dump
`var_dump ( $expression , ...$expressions )`
型や値を構造化したデータを返す。
一度に２つの式（変数）を指定することができる。


```
php > $obj = array("a" => 1, "b" => 2, "c" => 3);
php > var_dump($obj);
array(3) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
}
```

var_exportとの大きな違いは２点

1. 値の型を表示
2. 式（変数）を２つ指定できる


###引数で変数を２つ指定した場合

```
php > $obj = array("a" => 1, "b" => 2, "c" => 3);
php > $x = array('x' => 1);
php > var_dump($obj, $x);
array(3) {
  ["a"]=>
  int(1)
  ["b"]=>
  int(2)
  ["c"]=>
  int(3)
}
array(1) {
  ["x"]=>
  int(1)
}
```
AWS EC2のGraviton2インスタンスにdocker-composeをインストールする

Graviton2のおかげでarm64アーキテクチャの環境が手軽に使えるようになりました。性能面もそうですがIntelやAMDより安価というメリットもあり積極的に使っていきたいと思っています。今のところスポットインスタンスで使えないのがちょっと痛いですが、使う人が増えてくればそのうち対応するでしょう。

とりあえずt4gインスタンスを立てて使おうとしたところdocker-composeのインストールでしばらく詰まったのでメモ。

# 環境

- t4g.microインスタンス
- Amazon Linux 2

# 何が問題か

Dockerは`yum`でAWS公式提供のものをインストールできるので問題ないのですが、docker-composeは自分でインストールする必要があります。

で、リリースされているものはというと、[ここ](https://github.com/docker/compose/releases/tag/1.27.4)にあるようにx86_64のものしか用意されていません。なので、`pip`でインストールを試みます。

```
$ sudo yum install python3 python3-dev python3-pip gcc make openssl-devel libffi-devel
$ sudo pip3 install -U docker-compose
```

これが通らない。Cryptographyというパッケージのビルドでこけます。

# どうしたか

Amazon Linux 2で普通にインストールできるOpenSSLは1.0系のものですが、CryptographyはOpenSSL1.0のサポートを打ち切ったようでした。このため、OpenSSL1.1系を用意する必要がありました。

```
$ sudo yum remove openssl openssl-devel
$ sudo yum install openssl11 openssl11-devel openssl11-libs
$ sudo pip3 install wheel
$ sudo pip3 install -U docker-compose
```

works for me.
Cloud functions `package.json in functions directory has an engines field which is unsupported. The only valid choices are: {"node": "8"} and {"node": "10"}.` エラー解決策

### やりたいこと
- cloud functions を `node 12` でdeploy したい

**事前確認**
- `firebase-tool` のversionを最新
- package.json の `engine: 12` に設定


### エラー
```
$ firebase deploy --only functions
```

```Error
Error: package.json in functions directory has an engines field which is unsupported. The only valid choices are: {"node": "8"} and {"node": "10"}.
```

### 解決策

```
$ yarn firebase deploy --only functions
```

yarn 経由でやる
【Python】座標上の3点からなる角度を計算

点A，B，Cがなす角，∠ABC (点B周りの角度)の算出方法です．

```Python

# 点A,B,Cの座標（3次元座標上の場合）
a = np.array([0,1,2])
b = np.array([10,20,30])
c = np.array([5,7,9])

# ベクトルを定義
vec_a = a - b
vec_c = c - b

# コサインの計算
length_vec_a = np.linalg.norm(vec_a)
length_vec_c = np.linalg.norm(vec_c)
inner_product = np.inner(vec_a, vec_c)
cos = inner_product / (length_vec_a * length_vec_c)

# 角度（ラジアン）の計算
rad = np.arccos(cos)

# 弧度法から度数法（rad ➔ 度）への変換
degree = np.rad2deg(rad)
```
PHPで複数の文字で文字列を分割する

たとえば「#」「/」で分割するとき

### code
```php
$result = preg_split('/(#|\/)/', $str);
```

### sample

```php
$str = 'タグ1#タグ2/タグ3/タグ4#タグ5';
var_dump(preg_split('/(#|\/)/', $str));

// result
array(5) {
  [0]=>
  string(7) "タグ1"
  [1]=>
  string(7) "タグ2"
  [2]=>
  string(7) "タグ3"
  [3]=>
  string(7) "タグ4"
  [4]=>
  string(7) "タグ5"
}
```
Thymeleafのセレクトボックスで生年月日を作る

# セレクトボックスで生年月日を作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566570/9fcde63c-a3c7-907d-ae9b-7e7df0a8ccfc.png)

ちょっと時間かかったので備忘録として残しておきます。

 #numbers.sequenceで選択できる範囲を指定するのがポイント。

```html:index.html
	<div>
		<select id="birtyday" name="birthday">
			<option th:each="i : ${#numbers.sequence(2020, 1920)}"
				th:value="${i}" th:text="${i}" th:selected="${i == birthYear}">
			</option>
		</select>
		
		<select id="birthMonth" name="birthMonth">
			<option th:each="i : ${#numbers.sequence(1, 12)}" th:value="${i}"
				th:text="${i}" th:selected="${i == birthMonth}"></option>
		</select>
		
		<select id="birthDay" name="birthDay">
			<option th:each="i : ${#numbers.sequence(1, 31)}" th:value="${i}"
				th:text="${i}" th:selected="${i == birthDay}"></option>
		</select>
	</div>

```

```java:Birth.java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class Birth {

	@GetMapping("/index")
	public String getIndex(Model model) {
		int birthYear = 2002;
		int birthMonth = 8;
		int birthDay = 3;

		model.addAttribute("birthYear", birthYear);
		model.addAttribute("birthMonth", birthMonth);
		model.addAttribute("birthDay", birthDay);

		return "index";
	}
}
```
Overleafで日本語2カラム原稿を作る（IEICE総合大会を例に）

#はじめに
最近はローカルに構築したTeX環境を使うことがめっきりと減りOverleaf上で行うことが多くなりました。英文論文等ならこれでまったく問題ないんですがやはりどうしても日本語原稿を作る必要があることがありOverleafに一本化したいな～と思いやってみました。Overleafの日本語化はちょこちょこネットにも転がっていますがせっかくなのでもう少し実用に踏み込んだところまでやってみます。

読むのが面倒な人はテンプレートを貼っておくのでご利用どうぞ。
[Overleaf版IEICE総合大会テンプレート](https://ja.overleaf.com/read/vzsvvtpfczwx)

#目次
1. やり方
2. 困ったら

#1. やり方
以下の環境で動作を確認しています。

* オンラインLaTeXエディタ[Overleaf](https://ja.overleaf.com/)
* [IEICE総合大会テンプレート](https://www.ieice-taikai.jp/2020general/jpn/template.html)

1. 新規プロジェクトを作成し、中に以下の"latexmkrc"ファイルを作成する

```TeX:latexmkrc
$latex = 'platex';
$bibtex = 'pbibtex';
$dvipdf = 'dvipdfmx %O -o %D %S';
$makeindex = 'mendex %O -o %D %S';
$pdf_mode = 3; 
$ENV{TZ} = 'Asia/Tokyo';
$ENV{OPENTYPEFONTS} = '/usr/share/fonts//:';
$ENV{TTFONTS} = '/usr/share/fonts//:';
```

2. 左上の"メニュー"からコンパイラを"LaTeX"に変更する
3. 学会で配布されている指定のテンプレート、クラスファイル等をアップロードして使用する

#2. 困ったら
#####1. メインドキュメントが読めているのになぜかエラーになる  
クラスファイルの方で文字化けしている可能性があります。日本語原稿ではクラスファイルの方で図表のキャプションや参考文献の書き方を指定していることが多く、ここが文字化けしていると本文が文字化けしていなくてもエラーになるようです（これに気づかず一旦ハマった）。UTF-8に対応したテキストエディタ等で読み込みなおしてから貼り付ければ問題なく動作します。

#####2. PDF図が表示されないor変な位置に表示される(Cannot determine size of graphic in (fig名) (no BoundingBox).)   
古いテンプレートでは図をepsで貼ることを想定しており、PDF図に対応していない場合があります。この場合ヘッダにdvipdfmxを追加し図挿入の記述も多少変更する必要がある場合があります。eps用の出力パッケージが既に使用されている場合は衝突することがあり、この場合コメントアウトしてください。

```
\usepackage[dvipdfmx]{graphicx}
% \usepackage{epsfig}    %コメントアウト

\begin{figure}[htbp]
    \centering
    \includegraphics[width=0.8\linewidth]{fig/figure.pdf}
    %\epsfig{file=fig/figure.eps}
    \caption{図の貼り方}
\end{figure}
```


#参考文献
Overleaf v2 で日本語を使用する方法
https://doratex.hatenablog.jp/entry/20180503/1525338512
エラーになった時の大体の原因とその対処方法

エラーの原因なんだろうと慌てふためくのはもうやめにしよう。どうも、ぺこぱnonnoです。

様々な原因がある中で、個人的によく遭遇するなぁというエラーは以下に集約されるかなぁと考えています。

# 1 エラーの原因

1. 見てる場所が違う(ファイルの作成場所が違う、現在いるディレクトリではない、dockerで作業しているがローカルに保存)
2. バージョンが違う(マニュアルと同じことをしてるのにエラーになる)
3. 綴りミス(タイポ、名前の打ち間違い、命名規則のミス、大文字を小文字にしている)
4. 足りない、余分(何かが足りない、何かが余分で邪魔をしている)
5. 変数の型が違うのでメソッドが機能してない
6. 言語のルールを把握していない
7. 値が入っていない、値が違う(デバッガーでデバッグする)
8. 再起動してない
9. 前提が間違っている(~という前提でプログラムを組んでいるが、それが間違ってる)
10. 条件を変えれば動く？条件の列挙をする
11. 設定が違う
12. 権限がない
13. 保存してない
14. 外部ライブラリをインストールしてない


これを逐一覚えるのは面倒なので、これらの要素を抽象化して見文法値という名前の語呂合わせにしました。

## 1.1 見文法値
### 1.1.1 見る場所が違う
色々更新したのに再起動してない
色々更新したのに保存してない
ファイルの作成場所が違う
現在いるディレクトリではない
dockerで作業しているがローカルに保存
設定ファイルが指し示す場所が違う

### 1.1.2 文がおかしい
綴りミス
何かが足りない、余分
変数の型が違うのでメソッドが機能してない

### 1.1.3 法律がおかしい(現在のロジックがおかしい)
条件が一致してない
前提が間違っている
設定ファイルが間違ってる
権限がない
言語ルールの把握不足
外部ライブラリをインストールしてない

### 1.1.4 値がおかしい
値が入ってない、もしくは不適切、型が違うなど


# 2 エラーの対応
基本的に上記の通りに対応すればよろし。

具体的な対応方法は
https://qiita.com/zizynonno/items/3a14fe6cbf52451a366c
に記載した気がするのでそちらを参照に。。
Rails チュートリアル 第4章 備忘録

第4章の備忘録

##環境
Rails 6.0.3
Ruby 2.6.3

##目次
[1 配列・メソッド](#1-配列・メソッド)
[2 ブロック](#2-ブロック)
[3 ハッシュ](#3-ハッシュ)
[4 シンボル](#4-シンボル)
[5 CSSの読み込みを解読](#5-cssの読み込みを解読)


###1 配列・メソッド
####1.1 splitメソッド
文字列を配列に変換することが可能

```
# デフォルトは空白で区切る
>> "foo bar  baz".split 
=> ["foo", "bar", "baz"]

# 区切る文字を指定することが出来る
>> "fooxbarxbaz".split('x')
=> ["foo", "bar", "baz"]
```

####1.2 インデックスに−１を使ってみる
配列のインデックスに```-1```を指定すると、配列の最後の要素を取得することが出来る。

```
>> a = [42, 8, 17]
=> [42, 8, 17]

>> a.last
=> 17
>> a[a.length - 1]
=> 17
>> a[-1]
=> 17
```

####1.3 empty?メソッド
空かどうか調べることが出来る

```
>> a = [42, 8, 17]
=> [42, 8, 17]

>> a.empty?
=> false
```

####1.4 include?メソッド
指定した値が含まれているか調べることが出来る

```
>> a = [42, 8, 17]
=> [42, 8, 17]

>> a.include?(42)
=> true
```

####1.5 sortメソッド
配列を昇順（小さい順）に並べ替える

```
>> a = [42, 8, 17]
=> [42, 8, 17]

>> a.sort
=> [8, 17, 42]
```

####1.6 reverseメソッド
逆順に変更する

```
>> a = [42, 8, 17]
=> [42, 8, 17]

>> a.reverse
=> [17, 8, 42]
```

####1.7 shuffleメソッド
ランダムな並びに変更

```
>> a = [42, 8, 17]
=> [42, 8, 17]

>> a.shuffle
=> [8, 42, 17]
```

####1.8 各メソッドに```!```を付ける
メソッドを使用した値自体も変更させる

```
>> a = [42, 8, 17]
=> [42, 8, 17]

>> a.sort
=> [8, 17, 42]
>> a
=> [42, 8, 17] # a自体は変更されていない

>> a.sort!
=> [8, 17, 42]
>> a
=> [8, 17, 42] # a自体も変更される
```

####1.9 push( < )メソッド
配列の最後に要素を追加する

```
>> a.push(6)
=> [42, 8, 17, 6]

>> a << 7
=> [8, 42, 17, 6, 7]
```

####1.10 joinメソッド
splitメソッドの逆。配列を文字列に変換

```
>> a = [42, 8, 17, 6, 7, "foo", "bar"]
=> [42, 8, 17, 6, 7, "foo", "bar"]

>> a.join
=> "4281767foobar" # 連結

>> a.join(',')  
=> "42,8,17,6,7,foo,bar"　# 間にカンマを挟んで連結
```

####1.11 to_aメソッド
配列に変換する
0..9 : 9を含む

```
>> (0..9).to_a 
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
```


###2 ブロック

```
>> (1..5).each do |i|
?> puts 2*i
>> end
2
4
6
8
10
=> 10
```

上のコードのように do~endで囲むとブロックになる
ブロック内が複数行になる場合はこちらの方が主流らしい。


###3 ハッシュ
ハッシュは配列と違って、
・ インデックスに整数値以外が使える（そのハッシュのインデックスをキーと呼び、それに対応するものが値）
・ ハッシュ内の要素の並び順が保証されない


###4 シンボル
Railsでは文字列よりシンボルが使われる。
文字列との違いはクォートで囲まず、コロンが前におかれる。
ハッシュではシンボルをキーとして使うことが一般的。
また、```=>```はハッシュロケットと呼ばれ、下のコードのように書き換えが可能。

```
{ :name => "Test Name" }
{ name: "Test Name" }
```


###5 CSSの読み込みを解読

```
<%= stylesheet_link_tag 'application', media: 'all',
              'data-turbolinks-track': 'reload' %>
```

このコードを理解するためには、
・　Rubyでは丸カッコを使用しなくても構わない
・　ハッシュがメソッド呼び出しの最後の引数の場合、波カッコ省略可能
を把握することが必要。よって、

```
<%= stylesheet_link_tag (
    'application', 
    { media: 'all', 'data-turbolinks-track': 'reload' }
) %>
```
となり、引数は2つであることが判明する。

最初の要素はメディアタイプを指定、
次の要素はturbolinks機能をオンに設定している。

turbolinks : ページ遷移を高速化するライブラリ。Rails4から追加
社内データサイエンス勉強活動の運営（2年目）について

# 概要
私が社内で取り組んでいる、**データサイエンス勉強活動**について振り返り2年目を書き残しておきます。

また、本記事は[データ分析人材のキャリア（データラーニングギルド）アドベントカレンダー](https://qiita.com/advent-calendar/2020/data-learning-guild)の24日目記事になります。（クリスマスイヴ…！）

去年も[Advent Calendar14日目](https://qiita.com/Chobiiiii/items/793819883ef4acc29435)を書いたので、早いものでもう一年以上オンラインサロンに参加させて頂いています。
普段技術記事を書いていない方には、やっぱり年末の勢いで書くAdvent Calenderはおすすめです。
~~この記事は12月23日に書いています。~~

# データサイエンス勉強活動について
社内では去年から引き続き統計学〜機械学習について、市販のテキストを中心に輪読会形式で行っています。
発表者はJupyter Notebookで資料を作成しPythonを実行しながら説明します。
また、メンバーに共有したいニュースやトピックが有れば、自由に発言して共有します。

なんと、**新入社員をメイン参加者とした第二世代の勉強会**も生まれました。
嬉しい限りだったのですが、運営側のリソースを考えるとどちらも運営するのは難しく、
第一世代の機械学習勉強会のちょうどいい区切りでマージすることにしました。

第二世代は新入社員ということもあり、なんと既に統計学を学んだ状態（！）だったので、統計学については第一世代と同じテキストを使いつつも、特急進行の勉強会にしました。

# 課題点・運営変更点
### 第一世代
半期ぐらいごとにアンケートを取り運営に反映させているのですが、結果以下の課題が判明しました。

- 参画しているプロジェクトが忙しくテキストの用意や参加そのものが難しい
 
恐らく他の勉強会でも、同じように忙しくなると疎遠になりがちと思いますが、こちらについては運営が資料を用意・発表まで行うことで参加者の負担を減らし、さらに一回の分量を減らして追いつきやすくするよう運営を変更しました。

- アウトプットする場がもっと欲しい

こちらについてはペアプログラミングを考えてモニタまで購入していたのですが、コロナによって企画倒れとなりました。
その代わり輪読会の後に、自分で自由なテーマで機械学習を実装したものを発表する機会を設けました。

### 第二世代
こちらはアンケートではなく勉強会開始前に一人一人ヒアリングし、また参加者の一部を運営メンバーに取り込みました。
結果、何を勉強会に望んでいるのかの情報を、ある程度分析できる状態でスタートすることになり、以下の要望を叶える運営にしました。

- アウトプットして知識を定着させたい
- 議論や教えあいで効率よく学習したい

第一世代とは運営方法を大きく変えて、特急進行ながらも議論や演習のための時間を十分に持った勉強会となりました。
参加者は同期ということもあり和気藹々・議論も活発でめでたしめでたし…だったのですが、運営側が第一世代も参加していたため第二世代の運営維持が難しくなり、第一世代とマージする流れとなりました…

# 終わりに
プロジェクトの忙しさで勉強会がやや疎遠になっているメンバーもあり、これはもう永遠の課題と考えています。
引き続きいい感じの対応策がございましたら、ぜひ共有をお願いします。
サーバが明示的にキャッシュの有効期限を決めてないときにどうなるか[Heuristic freshness checking]

#本題
サーバ側でキャッシュの有効期限を決めていない場合は以下のような計算で有効期限が決められるようです。

~~~
freshnessLifetime = (Date - Last-Modified) / 10
~~~

つまり、サーバ上の最後の更新(Last-Modified)から時間が経てば経つほど有効期限が伸びていきます。

参考: https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#Heuristic_freshness_checking

##調べるに至った背景
最近、リリースしたシステムで「やっぱりここ直して」系の改修を担当したのですが、
キャッシュが残って変更が反映されないので各端末のブラウザのキャッシュクリアをしないといけなかったんです。
このシステムは結構前からやっているはずなのにキャッシュについてあんまり考えている風ではなかったですね。
おそらくjsファイルはjQueryの仕様なのか知りませんがCache-Bustingされていて※1、
HTMLファイルを編集することがあまりないので気が付く人がいなかったというところでしょうか。
そんなこんなで、なぜHTMLがキャッシュされるのか調べました。
まぁキャッシュされるのは当然で、jsがキャッシュされないのが特殊だったのですが、、

##学んだこと
キャッシュクリアするの面倒なので、有効期限決めた方が良いのではということですね。
私が携わっていたシステムはIISを使っていました。→HTTP応答ヘッダで簡単に決めれそうです。
HTMLファイルの表記揺れくらいなら1日後に更新とかじゃダメなんですかね。。
##補足
※1
jQuery2.x以下で以下の例のようにscriptタグをappendするとcache-bustingされるっぽいです。
キャッシュされたファイルを確認すると `script.js?_=ランダム数` のようになっています。
jQuery3.xでは起こりませんでした。さらに高まる不信感、、

例

~~~javascript
$("head").append('<script src="./script.js"><\/script>');
~~~
Windows VSCode環境で"Debugger terminal error: Process failed: spawn bundle ENOENT"

## お困りごと

Windows VSCodeでRubyをデバッグしたい。
まずは、bundlerを介した環境でデバッグしたいため、launch.jsonの```useBundler```を```true``` で設定することからスタート

``` launch.json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug Local File",
            "type": "Ruby",
            "request": "launch",
            "program": "${workspaceRoot}/main.rb",
            "useBundler": true
        }
    ]
}

```

いざ、デバッグを開始するとVSCodeのDEBUG CONSOLEに以下のエラーが表示される。


``` Debugger terminal error: Process failed: spawn bundle ENOENT ```

swpawnは日本語で"生成"、  ["ENOENT"はError No Etry"の略らしい](https://qiita.com/YumaInaura/items/4b664cd00675502407ba)  
意訳すると、「bundleプロセス生成しようとおもったけど、見つかんない」といったところ。

## 解決策

bundleが呼び出せるようにする記述をlaunch.jsonに記述する。
```pathToBundler```の部分がその記述。

```launch.json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug Local File",
            "type": "Ruby",
            "request": "launch",
            "program": "${workspaceRoot}/main.rb",
            "useBundler": true,
            "pathToBundler": "bundle.bat"
        }
    ]
}

```

以上
GitHub Actionsの編集ができなくなったときの対応方法 (トークン認証の設定方法)

# エラーについて

GitHub Actionsのワークフローのファイル編集を行い、pushしようとしたところ次のエラーが発生した。

```
 ! [remote rejected] (ブランチ名) -> （ブランチ名） (refusing to allow an OAuth App to create or update workflow `（ワークフローのファイル名）` without `workflow` scope)
```

# 前提

環境はMacでGit CLIを使用。リポジトリURLの指定はHTTPS。

# 対応方法

## キーチェーンから既存の認証情報を削除

1. キーチェーンアクセスを開く
2. 名前がgithub.comとなっている項目を削除する

## GitHubのユーザ名をURLに指定

1. .git/configを開く
2. github.comの前に`ユーザ名@`を追加する

## パーソナルアクセストークンを発行

1. https://github.com/settings/tokens にアクセス
2. Personal access tokensを選択
3. Generate new tokenを選択
4. workflowにチェックを入れる
5. Generate Tokenを選択
6. 発行されたトークンをメモする

## トークンのキャッシュを設定

1. [こちら](https://docs.github.com/en/free-pro-team@latest/github/using-git/caching-your-github-credentials-in-git)の指示に従いキャッシュの設定を行う
 
## 普通にpush

1. git pushを実行する
2. パスワードを聞かれるので発行されたトークンを入力する
【Android】ワイアレスでアプリビルドする方法

# はじめに
アプリをビルドする際にUSB-Cケーブルをつなげるのがめんどい人のため、
ワイアレスでビルドする方法を解説します

## この記事を書いてる人
株式会社evoluの駆け出しAndroidエンジニア(3ヶ月目)

## 手順
- adbコマンドを使えるようにする
- 端末とホストPCの設定
- ケーブルなしでも接続完了

### adbコマンドを使えるようにする

terminalにて下記を実行

```
$ nano ~/.bash_profile
```

bash_profileにexportを追加する

```
export ANDROID_HOME=/Users/$USER/Library/Android/sdk
export PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools
```
反映させる

```
$ source ~/.bash_profile
```

adbのバージョン確認ができたら完了になります

```
$ adb version

//Android Debug Bridge version 1.0.41
```

### 端末とホストPCの設定
- 
pixcel 4aでの設定方法
設定 > システム > 開発者向けオプション > ワイアレスデバック > ペア設定コードによるデバイスのペア設定を選択

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320838/bc7f0741-a2a8-35a9-5165-90f428bbd037.png" width="300">

上記画像の場所まで辿りつけたら
- Wi-Fiペア設定コード
- IPアドレスとポート
の二つをメモします

次はこれらをホストPCに設定するためターミナルを使います

ターミナル

```
$ adb pair 192.xxx.x.xxx:xxxxxx
```
上記コマンド入れた後ペア設定コードを入れたら「Successfully paired to 〜」と表示されれば完了になります。