OmniAICreator/Qiita-1.07M huggingface dataset:
GoogleColaboratoryにおけるファイルの読み書き

#はじめに
当記事はある目的を持って必要な技術を調べながら手を動かした記録を要素別にまとめたものの１つです。データ解析全体の流れはリンク先の記事を参照ください。('21/4/29時点未完成)

https://qiita.com/sckln/items/9af07be8df426cbcdb36

#やりたいこと

GoogleColaboratory環境で探索的にデータ分析をしている最中に「セッションが中断されました」となると面倒なので、要所要所でDataFrameをcsvにしてGoogleDriveに置いておきたい。

#使用したライブラリ

###pandas
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_csv.html

```py
import pandas as pd
list1=[1,2,3]
list2=[4,5,6]
sr1=pd.Series(list1, name='list1')
sr2=pd.Series(list2, name='list2')
df=pd.concat([sr1, sr2], axis=1)
df.to_csv('df.csv')
```
pandasでcsv書き出しと言えばコレなのだが、GoogleCoraboratory上でこうすると一体どこにdf.csvがあるのか。最初血迷ってGoogleDrive内を検索したが出てこない。

###google.colab
https://colab.research.google.com/notebooks/io.ipynb#scrollTo=u22w3BFiOveA

ライブラリというのか何なのか分からないが、ライブラリをimportするときのように``from google.colab import drive``とすれば実行中のランタイム上にGoogleDriveをマウントすることが出来る。

```py
from google.colab import drive
drive.mount('/content/drive')
```

これを実行すると
>Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?client_id=hogehoge...

というリンクが返ってくるので、クリックするとこんなページに飛ぶ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1381159/fa7d3a50-04ec-ba8f-475a-1392bf63a2db.png)

#実践

```py
import pandas as pd
from google.colab import drive
drive.mount('/content/drive')

list1=[1,2,3]
list2=[4,5,6]
sr1=pd.Series(list1, name='list1')
sr2=pd.Series(list2, name='list2')
df=pd.concat([sr1, sr2], axis=1)
df.to_csv('/content/drive/MyDrive/df.csv')
```
GoogleDriveマウント前にto_csvしたファイルも左のファイルツリーから確認することができ、content/直下にdf.csvが確認できる。しかしこのままだとランタイムが終われば消えてしまう。content/drive/MyDrive/が、GoogleDriveのルートフォルダになっているので、ここへ書き出しておけば、ランタイムが終わっても消えない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1381159/e96527e7-c295-8637-5cbe-bbb5c28236f1.png)

読み込むときも同様。先にマウントしておかないと、そんなフォルダは存在しないというエラーがでるが、上と同じようにマウントしたあと、以下で読み込むことが出来る。

```py
df1=pd.read_csv('/content/drive/MyDrive/df.csv')
```

#その他の参考記事
GoogleColaboratoryの仕様が日々（ますます便利に）進化しているようで、ググると古い記事にヒットすることが多かったです。

異様に丁寧な説明。これで全て。

https://kenko-keep.com/google-colab-mount/

旧仕様で頑張った方の記事。

https://qiita.com/kado_u/items/45b76f9a6f920bf0f786
mysqlのパスワードわからない時の対処法

#背景
php学習中ですがphpmyadminにmysqlのパスワードがわからずアクセスできなかった。
解決するまでに苦戦してしまったので忘れないように。

#解決方法
1. my.iniファイルを開き、[mysqld]の欄にskip-grant-tablesを追記　(C:\xampp\mysql\bin\my.ini)
2. Mysqlを再起動
3. コマンドプロンプトからmysqlにアクセス(mysql -u root -p)
4. flush privileges;　エラーが返ってくるが無視
5. ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPassword';でパスワードを再設定
6. my.iniの[mysqld]欄skip-grant-tablesを削除し、mysqlを再起動
7. mysql -u root -pで再設定したパスワードでログインできるか確認する。

config.inc.phpのパスワードも今回再設定したものに書き換えた結果、
phpmyadminにアクセスできるようになりました。
睡眠と歩数の相関は？自分の生体データで分析#1

# 最近、運動たりてない？
コロナのロックダウンと、職業柄コマンドラインを叩いてばかりの日々。
バ先の研究室の椅子が座り心地が良く、あまり動かなくなってきた気がする。
２月からスマートウォッチをずっとつけていて、いろんな生体データが溜まってきたので、ここらで一回生活習慣を振り返ってみましょうか。

何回かに分けて試行錯誤して何らかの知見を得ようとしてみます。今回は1回目です。


# 仮説:「歩数の多い日の夜は睡眠の質が高いはずだ」
運動と睡眠の関係はいくつかの研究で既に相関関係があることが示されていますが、そうは言われても、実感は難しいです。自分自身のデータからもし相関があったら、肌でそうしたことが実感できるかもしれませんし。
睡眠の質は定義が難しいので、今回は単純にスマートウォッチによる深い眠りの分数(deepSleepTime)を睡眠の質と捉えてみましょう。 **もしこれでうまくいかなければ、仮説の建て方自体に問題があるかもしれませんね。**

# データ収集：スマートウォッチで歩数と睡眠の質を測定
シャオミのMi Band 5という時計は、様々なシグナルを計測しますが、今回は歩数と睡眠スコアのみのデータを購入時から4/29まで公式アプリ記載の方法でエクスポートし、これを使いました。

エクスポートした生データはcsv形式で保存されていました。それでは生データを覗いてみましょう！

## 歩数を含む生データ
![スクリーンショット 2021-04-29 20.56.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614389/9af16a3e-003f-e6e8-6c7c-4271a5d6edab.png)


## 睡眠の質に関わる生データ
![スクリーンショット 2021-04-29 20.56.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614389/23489c60-c71f-a097-73ae-d33f91a38289.png)

```:私の脳内
＿人人人人人人人人人＿
＞　何もわからへん　＜
￣Y^Y^Y^Y^Y^Y^Y^Y￣
```
ぱっと見何もわからないという知見が得られました。

# とりあえずデータの可視化,相関係数をみてみる
とりあえず生データのぞいたけど、何もわかんねえよ！
というわけで、歩数と睡眠の質に関わるdeepSleepTimeをプロットして可視化してみましょう。
なお、前日の歩数の影響が、次の日に影響が出うると今回仮定しているので、きちんとデータを１日分ずらすことを忘れずにしましょう。
（次の日の睡眠データと、前の日の歩数データを比べるとわけわからんくなります。）

深い眠りの分数 deepSleepTimeは外れ値の処理が難しい（明確な基準がない）ので、生データのまま用いました。
![スクリーンショット 2021-04-29 21.57.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614389/64043bcd-a7cb-0e07-9440-756d2c2b4764.png)

**相関係数は0.2953** となり、この値だと、ほぼ相関無しと判断されることが多いようです。すなわち、**「睡眠の質を、深い睡眠の時間とすれば、前日の歩数が多いほど睡眠の質は高くなる」、という仮説は否定もできないし、肯定も出来ない、というなんとも微妙な結果になりました。**このままでは断定はできないので、他の指標を考えてみる必要がありそうです。ただ、ためしに全ての日付を二つの値の間でずらしてみると、負の相関になるので、これらの二つの指標の間に関係が全くないともいえません。

# 結果
単純に歩数だけを深い眠りの時間と比べたときに、これらの相関は0.2953となり、相関があるともないともいえないことがわかった。


***次回に続く***
***To be continued.***
# 反省点&改善の余地

**僕はデータ分析は全く専門ではありません。**
**Qiitaには素晴らしいデータサイエンティストが溢れているらしい**と思われますので、コメントでみなさんの知見を募集してます。
こうしてみなさんのツッコミをいただき、何かしら今後の学びにします。

以下、自分でツッコミ：

1.睡眠の質として、深い眠りの時間のみを単純に採用するべきではない？
例えば、レム睡眠の時間や、睡眠時間合計などを考慮するべきか？
2.歩数自体だけが睡眠の質に影響する、という仮定は単純すぎないか？
他にも、運動の強度や、カフェインの摂取の有無、人と会った回数など、それらも考慮する必要があるかも？
平日はスクリーンタイムが多いので、平日と休日で別々にデータを扱うのは？
3.データの数は十分だったか？
歩数と深い眠りのペアは80個ほどであった。もっとサンプル数が必要？
だとしたらそれはどのくらいか？

コメントで詳しい方、教えてください：
仮説の立て方にどんな問題がありますか？
指標の選び方にどんな問題がありますか？
もっともっとツッコミお願いします。

# もう寝ます。
この記事を書いていたら夜１０時になりました。
いろいろ考えたいですが、眠いので寝ます。
それではみなさん、ごきげんよう。
Microsoft Office for Macのテンプレートファイル格納先パスの備忘録メモ

Microsoft Office for Macの各種テンプレートファイルの格納先は階層が深くFinderで探すのが大変なため備忘録メモ。筆者は簡単にバックアップ出来る様にシェルファイルを作成しています。また書類ディレクトリにシンボリックリンクを作成しておくと直ぐにアクセス出来ます。

* テンプレートファイル格納先パス  
`~/Library/Group\ Containers/UBF8T346G9.Office/User\ Content.localized/Templates.localized/`
【Laravel 独自ページネーションを作成する方法】

LaravelのbladeとIlluminate\Pagination\LengthAwarePaginatorインスタンスでカスタムページネーションを実装する。

######目的
S3の画像を一覧表示したい

######流れ
S3にあるオブジェクトURLを保存しているDBから配列でオブジェクトURLを取得→その配列をページネーションする。

＃LengthAwarePaginatorクラスを使うときは、自分で配列かコレクションを分割しなければならない。配列ならarray_slice、コレクションならforpageなど。

##1. bladeで表示する準備
・ページネーション済みの配列を回して、s3に保存されている画像を一覧表示させている。

```php
<div class="container">
   @foreach ($s3ImgUrls as $objectrl)
       <img src="https://S3バケット名.s3-リージョン名.amazonaws.com/{{ $objectUrl }}" >
   @endforeach
</div>

{{ $s3imgUrls->links('vendor/pagination/semantic-ui') }}
```

`links()` では、以下のコマンドで生成されたview/vender/pagination内のいくつかあるbladeの一つを指定している。

```php
php artisan vendor:publish --tag=laravel-pagination
```

##2. bladeで表示させるページネーションされた`$s3imgUrls` を生成する。

ポイントは、リクエストされたページ数によって`array_slice()`で切り取る範囲を変えているところ。

```php
$array = //独自ペジネータ配列の全体像
$display_limit = 3
$arrayOfNum = ((int)($request->page ?? 1) - 1) * $display_limit;
$sliced_items = array_slice($array, $arrayOfNum, $display_limit);

$s3ImgUrls = new LengthAwarePaginator(
            $sliced_items, 　　 　// 現在のページのsliceした情報(items)
            count($array),       // 総件数（total）
            $display_limit,      // １ページに表示される数 (perPage)
            $currentPage,        // 現在のページ(ページャーの色がActiveになる)（currentPage）
            ['path' => $url]     // ページャーのリンクを指定
        );
```

##3. bladeのcssを整える。
以下のようなページネーションが作れる。
![94850F14-0E83-44A7-8EAF-506E1DA27498_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530710/eab54752-e10f-ec04-d306-75724b2498ff.jpeg)
Logic AppsとAzure Functions(Java)を連携する

Azureのノーコードツール[「Logic Apps」](https://azure.microsoft.com/ja-jp/services/logic-apps/)を触っていて、Azure FunctionsやAzure App Servicesなどと連携できることを知りました...（今更）！これは便利そう。Azure FunctionsはJavaでも書けるので、基本はノーコードで組み立てて、難しい処理だけJavaで書くみたいなことが簡単にできそうです。ということで早速、連携を試してみました。

![スクリーンショット 2021-04-29 22.09.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/f2bce3d7-7412-c952-ab78-0128baef85ff.png)

あるツイートを検知したら、それに対する情報をつぶやくというものを（かなり雑に）作りました。

![スクリーンショット 2021-04-29 22.20.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/3b856594-3425-f015-9e0e-493f2ec8bfb6.png)

まずはLogic AppsのデザイナーでTwitterのコネクタを作って、Azure Functionsを呼び出します。

![スクリーンショット 2021-04-29 18.42.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/1f679578-b890-7795-94b6-dbfba6a050ce.png)

デプロイしたFunctionが見えるのでポチポチと選んでいくだけです。

![スクリーンショット 2021-04-29 18.42.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/f743e5c4-40ce-dd9e-ef81-5e9dcba82eaa.png)

![スクリーンショット 2021-04-29 18.42.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/98b7be5c-3576-7c02-2f3b-8ef1b05feff9.png)

最後にFunctionsの結果をツイートします。本文をそのまま出すだけです。

![スクリーンショット 2021-04-29 20.08.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/86d5567a-260b-4489-4b7e-d65e9e1ea5c2.png)

ちなみに今回のFunctionsの処理はこれだけです。

```java
@FunctionName("HttpExample")
public HttpResponseMessage run(
     @HttpTrigger(
            name = "req",
            methods = {HttpMethod.GET, HttpMethod.POST},
            authLevel = AuthorizationLevel.ANONYMOUS)             
            HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {
    return request.createResponseBuilder(HttpStatus.OK).body("桃ちゃんのブログはこちらです https://blog.nogizaka46.com/momoko.oozono/").build();
}
```

実際にツイートしてみました。

https://twitter.com/kikutaro_/status/1387725581379260418

しばらくするとFunctionsの応答内容がちゃんとツイートされました。

https://twitter.com/kikutaro_/status/1387725664661344256

今回の例はFunctionsの処理がシンプルでしたが、Logic Appsで実現しにくい処理やJavaでゴリゴリ書きたい処理などを書いて連携すればノーコードベースでも複雑な処理を実現できそうです。
続Laravel5.5でもVue.jsっぽくReact.js x TypeScriptを部分的に導入する

# 概要

[Laravel5.5でもVue.jsっぽくReact.jsを部分的に導入する](https://qiita.com/ProjectEuropa/items/2d8c364b4db2f68b205d)の続きで、TypeScriptを導入します。

## TypeScript導入

```console
$ npm install -D typescript @types/node @types/react @types/react-dom
```

## tsconfig.json作成

```console
$ ./node_modules/.bin/tsc --init
```

```tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "noImplicitAny": false,
    "jsx": "react",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "exclude": [
    "vendor"
  ]
}
```

## Laravel-Mixアップグレード

webpackが4系じゃないとコンパイルがうまくいかないらしい

```package.json
.
.
.
        "laravel-mix": "^5.0",
.
.
.
```

```console
$ npm i
```

## ts-loaderインストール

```console
$ npm i ts-loader@^8 -D
```

## webpack.mix.js編集してtsを使用

```webpack.mix.js
mix.ts('resources/assets/js/app.tsx', 'public/js');
```

## resources/assets/js/app.tsx作成

```resources/assets/js/app.tsx
import * as React from 'react';
import { render } from 'react-dom';

type Props = {
    title: string | null
}
const Example: React.FC<Props> = ({ title }) => (
    <div className="container">
        <div className="row">
            <div className="col-md-8 col-md-offset-2">
                <div className="panel panel-default">
                    <div className="panel-heading">Example Component</div>

                    <div className="panel-body">
                        {title}
                    </div>
                </div>
            </div>
        </div>
    </div>
);

const Element = document.getElementById('example');
if (Element) {
    const title = Element.getAttribute('title');
    render(<Example title={title} />, document.getElementById('example'));
}
```

## resources/views/welcome.blade.phpでprops設定

```welcome.blade.php
.
.
.
    <body>
        <div class="flex-center position-ref full-height">
            <div id="example" title="ts-react"></div>
        </div>

        <script src="{{ asset('js/app.js')}}"></script>
    </body>
```

## コンパイルと画面表示

```console
$ npm run dev
$ php artisan serve
```


![スクリーンショット 2021-04-29 22.29.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133718/3aa8de81-38ac-ee24-b38d-15a1e8a42443.png)

## 参考

- [Laravel bladeからReactコンポーネント(Material UI)にバリデーションエラーメッセージを渡してみる](https://qiita.com/motuo/items/8cdb9d70c11a3447ee7b)
- [[Laravel × React] Laravel×React(Typescript)の環境構築](https://www.alt-plus.jp/archives/2625)
WSL2で躓いたときに読む記事

WSL2に躓いたときの参考資料です。

## ポートフォワーディングする方法
`~/.wslconfig`のファイルを追加し、下記の内容を記述することでポートフォワーディングが可能になる。

```
[wsl2]
localhostForwarding=true
```
windows側でシャットダウン⇒再起動する。

```
wsl.exe --shutdown
```

ブラウザの動作確認に使用したかっただけなので、近日リリース予定のGUIに対応したWSLのWSLgでも良いと思います。
[Microsoft WSLg説明ページ](https://devblogs.microsoft.com/commandline/the-initial-preview-of-gui-app-support-is-now-available-for-the-windows-subsystem-for-linux-2/)
※プレビュー版は`Windows 10 Insiders preview build 21364`でリリース済み

## VSCODEでWSL2のリモート開発をする

VSCODE上で`Remote - WSL`をインストールして、WSLを起動して以下のコマンドを実行する。

```
code .
```
ファイルストレージ オブジェクトストレージ ブロックストレージ とは

## 勉強前イメージ

正直あんまりわかってない・・・
それぞれ聞いたことはあるけど

## 調査

### ファイルストレージ とは

- 概要

フォルダやディレクトリの形式で階層構造で保存されます。
一般的なPCで使用される形式で、直感的に操作が出来るメリットがあります。
また、DASやNASなどにも使用されています。
拡張性や可用性の面で大規模なデータを扱う場合には適していません。

- イメージ図

![1# ファイルストレージ オブジェクトストレージ ブロックストレージ とは - diagrams.ne.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/afa497e0-8e14-2449-6c6c-adca08cefb44.png)


### オブジェクトストレージ とは

- 概要

ファイルストレージとは違い、データはフラットな形式で保存されます。
またメタデータを多く付与することができ、一意のIDを付与してそれを元にアクセスを行います。
大規模なデータを管理するのに向いている点が多くあります。
例えばAWSのs3がオブジェクトストレージにあたります。

- イメージ図

![2# ファイルストレージ オブジェクトストレージ ブロックストレージ とは - diagrams.ne.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/b34f5006-5db5-0850-b249-6a68e19c7861.png)


### ブロックストレージ とは

- 概要

記憶領域(ボリューム)を分割したものをひとまとまりとし、その中をブロックに分割して管理するというものです。
データをブロックに切り分けて、別々のピースとして保存します。
一意のIDをボリュームとブロックに割り振り、それを使用してアクセスを行います。
ブロックストレージは階層構造ではないのと読み込むデータのパスを複数指定できるため高速なアクセスが可能です。
AWSのEBSがブロックストレージにあたります。

- イメージ図

![3# ファイルストレージ オブジェクトストレージ ブロックストレージ とは - diagrams.ne.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/b6b754c6-bda2-ef4d-08df-ee1f29f23526.png)

## 勉強後イメージ

s3の勉強してたから結構オブジェクトストレージはわかりやすかったかも。
雰囲気わかるけどブロックストレージがやや難しい

## 参考

- [ブロックストレージ・ファイルストレージ・オブジェクトストレージの違いを解説](https://www.rworks.jp/cloud/azure/azure-column/azure-entry/21512/)
- [ファイルストレージ、ブロックストレージ、オブジェクトストレージの比較](https://www.redhat.com/ja/topics/data-storage/file-block-object-storage)
- [オブジェクトストレージ、ファイルストレージ、ブロックストレージの違い](https://www.sbcloud.co.jp/entry/difference-between-object-storage-file-storage-block-storage)
【Docker】Error response from daemon: invalid mount config for type "bind": bind source path does not exist

## 問題

```
$ docker compose up -d
[+] Running 0/2
 ⠋ Container 3e5dfe8d1909_docker-laravel-handson_app_1  R...                                                       0.1s
 ⠋ Container be3584c24dc2_docker-laravel-handson_web_1  R...                                                       0.1s
The new 'docker compose' command is currently experimental. To provide feedback or request new features please open issues at https://github.com/docker/compose-cli
Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /host_mnt/Users/ucan/work/ucan-lab/docker-laravel-handson/backend
```

## 原因(?)

Docker Desktop のファイル共有の権限がなくてエラーになる場合があるようです。

`Preferences...` > `Resources` > `FILE SHARING`

![ScreenShot 2021-04-29 22.16.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/82539275-c8c7-78be-b6aa-28ac951c4cfb.png)

今回は `/Users` 配下にあるディレクトリをマウントしようとしているので、問題ない気がします...🤔 `/host_mnt` を追加しないといけないのか...？

## 対処

Docker Desktop自体を一度終了させて、再度 `docker compose up -d` することでうまくいきました。

原因がハッキリしなくて気持ち悪いですが、そんなこともあるんですかね...🤔

## 参考

- https://docs.docker.com/docker-for-mac/#file-sharing
- https://blog.dand.work/article/396
- https://www.takapy.work/entry/2019/02/24/110932
【開発環境構築】

# 執筆の動機
新しくローカルアカウントを作成しました。
そこで、環境構築を一からやり直すことにしました。
今後のエラー対応の際、「何を、どこで、どのようにインストールしたのか」
を知れるようにこのページに集約していきます。

### 作業環境
```
Windows 10 Pro 64bit
Visual Studio Code バージョン: 1.55.2
```
# Python3
https://youtu.be/kb6op3-E_lg?t=544

https://www.anaconda.com/products/individual

https://code.visualstudio.com/download

https://qiita.com/Naturalclar/items/ae9e84fa8cf16a14c7e9#:~:text=%E2%8C%98%20%2B%20P%20(Windows%20%E3%81%A7%E3%81%AF%20Ctrl,(%20Enter%20)%E3%82%92%E6%8A%BC%E3%81%99%E3%81%A0%E3%81%91%E3%80%82

https://deepblue-ts.co.jp/python/conda-comand-basic/

## バージョンの確認
```
conda version : 4.10.1
conda-build version : 3.20.5
python version : 3.8.5.final.0
```
※今後、以下に追加していきます
LeetCode日本語修行16日目- [403-川を渡るのカエル]

###Frog Jump
参考：https://leetcode.com/problems/frog-jump/
###問題の内容:
カエルが川を渡ったいです。川はいくつかの単位に分かれていて、それぞれの単位には石があったりなかったりします。カエルは石の上に飛び乗ることはできますが，水の中に入らない。。。？？？
石の位置（単位）を昇順に並べたリストが与えられたとき、カエルは最後の石に着地して川を渡ることができるかどうかを判断します。最初、カエルは最初の石の上にいて、最初のジャンプは1単位でなければならないと仮定します。
カエルの最後のジャンプが k 単位だった場合、次のジャンプは k - 1, k, k + 1 単位のいずれかでなければなりません。カエルは前進方向にしかジャンプできません。
###例:
例1:
Input: stones = [0,1,3,5,6,8,12,17]
Output: true

0 -> 1 -> 3 -> 5 -> 8 -> 12 -> 17

例2:
Input: stones = [0,1,2,3,4,8,9,11]
Output: false
0 -> 1 -> 3 -> 4 -> X(前のジャンプは 4-3 = 1，次の単位にジャンプ範囲は
（1-1 ~ 1+1 ）、次の単位は8，距離は４ )

###ヒント:
2 <= stones.length <= 2000
0 <= stones[i] <= 231 - 1
stones[0] == 0

---
先ずは　対応のDPの　2DArrayを作ります
dp[石の位置（単位）の数字][前回ジャンプの距離]
今はdp[i][k]
前回は以下の条件の中に必ず一つがtrueです
dp[j][k-1] 
dp[j][k]
dp[j][k+1]
即ち
条件１：**dp[i][k] = dp[j][k-1] || dp[j][k] || dp[j][k+1]**
そして：
最初の一回と二回の　石の位置（単位）の数字と一回のジャンプが固定です、
そして、この後石の位置（単位）の数字が増えるの事は確定です、
その対応の石の位置（単位）が固定の+=1です
ジャンプはkから k-1 k k+1三つの可能性

jump[0] = 0　　            前回ジャンプ
stones[0] = 0　　　　　　　石の位置（単位）の数字
index 0　　　　　　　　　　　石の位置（単位）

jump[1] = 1　　　　　　　
stones[1] == 1　　
index 1　　　

jump[2] = 1,2　のどれが　
stones[2] = 2,3 のどれが
index 2

jump[3] = 1,2,3.  min = 1  max = 3
stones[3] 表示の必要がない
index 3

以上の条件から、以下の結論を導き出す：
条件2：**k≤i**
k = stones[i] - stones[i-1] & k≤i 
->条件3：**stones[i] - stones[i-1] <= i**


```Kotlin

class Solution {
    fun canCross(stones: IntArray): Boolean {
        var n = stones.size
        var dp = Array(n, { BooleanArray(n) })
        dp[0][0] = true
        for(i in 1 until n){
            ///条件3
            if( stones[i] - stones[i-1] > i){
                return false
            }
            for(j in i - 1 downTo 0){
                var k = stones[i] - stones[j]
                ///条件2
                if(k > j + 1){
                    break
                }
                ///条件1
                dp[i][k] = dp[j][k-1] || dp[j][k] || dp[j][k+1]
                if(i == n - 1 && dp[i][k]){
                    return true
                }
            }
        }
        return false
    }   
}

```
Red Hat 認定スペシャリスト試験 - OpenShift Administration -受験メモ

# はじめに

Red Hat 認定スペシャリスト試験 - OpenShift Administration -をリモート試験で受験し合格しました。
その時の忘備録です。

試験の詳細についてはこちらをどうぞ。
https://www.redhat.com/ja/services/training/ex280-red-hat-certificate-expertise-platform-service-exam

# リモート試験環境の準備

下記に日本語ガイダンス資料があるので、こちらを確認してください。
https://www.redhat.com/cms/managed-files/Remote-Exam-Pilot-Windows-jp.pdf

## リモート試験のLive USBの作成

ガイダンス通りの手順を実施すればハマるようなポイントはないと思います。
Live DVDにできないかと試してみましたがFedoraMediaWriterでは作成ができませんでした。

## 利用した端末

自分の場合は下記のような構成でした。  

- ノートPC（内臓カメラ付き）
  - CPU: Core i5 3210M 2.5GHz/2コア
  - Memory: DDR3 PC3-10600 8GB
  - Display: WXGA(1366 x 768)
- 外付けカメラ（ケーブル長が1m以上）
- 有線のマウス（無線はNG！）

セキュリティ等諸般の事情により社用ノートPCを使うことができなかったため、かなり古い私用ノートPCを使いました。
一応上記で受験はできましたが、画面の解像度が低いため文字が読みづらかったです。

デスクトップPCで受けることも考えたのですが、筐体を机の上に置く、または360度から確認できる状態にしておくなどの条件があったためやむなく上記環境で実施しています。

机の上には試験に関係するもの以外は何も置けませんのでキレイにしておきましょう。
普段利用している机の上にはいろいろなケーブルが固定されていたりして整理するのが大変だったため、余っていた机を使って環境を整えました。

要綱に書いてありますが、無線のマウスは利用できず有線のマウスのみ可能です。また有線のキーボードも利用できますが、その場合はノートPCの画面を閉じて別のディスプレイを使う必要があります。（何故？）

## 試験前の確認

Live USBで起動後、言語設定やキーボード設定をしたのちにCompatibility Checkが行えます。
試験の再スケジュールは24時間まえであれば可能なので、それよりも前にチェックを済ませておくことをお勧めします。

# EX280

出題範囲は下記の通りです。

https://www.redhat.com/ja/services/training/ex280-red-hat-certificate-expertise-platform-service-exam?section=%E8%A9%A6%E9%A8%93%E3%81%AE%E5%86%85%E5%AE%B9

- OpenShift Container Platform の管理
  - コマンドライン・インタフェースを使用して、OpenShift クラスタを管理および構成する
  - Web コンソールを使用して、OpenShift クラスタを管理および構成する
  - プロジェクトを作成して削除する
  - Kubernetes リソースをインポート、エクスポート、設定する
  - リソースとクラスタのステータスを確認する
  - ログを確認する
  - クラスタイベントとアラートを監視する
  - 一般的なクラスタイベントとアラートのトラブルシューティング
  - 製品マニュアルを使用する
- ユーザーとポリシーの管理
  - 認証用に HTPasswd ID プロバイダーを構成する
  - ユーザーを作成して削除する
  - ユーザーのパスワードを変更する
  - ユーザーおよびグループの権限を変更する
  - グループを作成して管理する
- リソースへのアクセスの制御
  - ロールベースのアクセス制御を定義する
  - ユーザーにアクセス許可を適用する
  - 機密情報を管理するためのシークレットを作成して適用する
  - セキュリティコンテキストの制約を使用してサービスアカウントを作成し、アクセス許可を適用する
- ネットワークコンポーネントの構成
  - ソフトウェア・デファインド・ネットワークをトラブルシューティングする
  - 外部ルートを作成して編集する
  - クラスタネットワークの進入を制御する
  - 自己署名証明書を作成する
  - TLS 証明書を使用してルートをセキュリティ保護する
- ポッドスケジューリングの構成
  - リソース使用量を制限する
  - 増加する要求に合わせてアプリケーションを拡張する
  - クラスタノードへの Pod 配置を制御する
- クラスタスケーリングの設定
  - クラスタワーカー数を手動で制御する
  - クラスタワーカー数を自動的にスケーリングする

出題された問題については言及しませんが、DO280のコースを一通り流しておけば受かる難易度かと思います。
試験中はOpenShiftのドキュメントも確認できますのでそちらも参考に進めましょう。

CKAやCKADではYAMLをｺﾞﾘｺﾞﾘ書くことが多いですが、EX280はそこまでYAMLを書くことはなかった気がします。
`OAuth` ResourceなどのOpenShiftならではのManifestはある程度覚えておいたほうが良いですが、ドキュメントも利用できますし`oc explain`である程度確認できると思うので問題ないかと思います。

# 受験結果

受験後に3日以内にメールで結果が来ます。自分の場合は受験後2時間くらいで来ました。
スコアは下記で、225/300と合格ライン210点をギリギリ超えた感じです。

| 項目 | スコア|
| --- | --- |
|Manage OpenShift Container Platform|83%|
|Manage users and policies|100%|
|Control access to resources|100%|
|Configure networking components|33%|
|Configure pod scheduling|57%|

もう少しとれているとは思っていたのですが、Configure networking componentsとConfigure pod schedulingがあまり良くなかったようです。
問題の意図を読み取れないものがいくつかあり「解決手段はいくつかあるけど、なにをやってほしいのかわからん」という状況になったのでそれが結果に出ているのかもしれません。英文にしても正直何を言いたいのかよくわからないものもありました。
TwitterのAPIでハッシュタグ作成ツールを作ってみた

【今回作ったサービス：ハシュクリ】
https://hashcre-41b10.web.app/

![Salmon Meet up Event Events Website.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697165/42b2821c-71c1-2623-0851-7e047d8f8db1.png)

【開発環境】
デプロイ先（フロントエンド）：Firebase
デプロイ先（バックエンド）：heroku
フロントエンド言語：JavaScript , nuxt.js , vuetify
バックエンド言語：python

【なぜ作ったか】
エンジニアとして、自分の活動を広めるためにTwitterを始めた。

投稿でハッシュタグを選ぶときに同じようなハッシュタグが煩雑していると思い、
どれを選ぶべきなのか、どれが一番使用されているのか表示できれば、
ハッシュタグを選びやすくなるのではないかと思った。

【アプリの仕様】
◆タグ検索について
TwitterAPIで入力されたキーワードが含まれるツイートの中で
使用されているハッシュタグを検索する。

◆ハッシュタグの使用頻度表示
yahooのリアルタイム検索をスクレイピングし、
各ハッシュタグの使用頻度取得する。

【作った感想】
スクレイピングを実施すると、処理時間が極端にかかり、使用感に影響が出る。
やはり、webサービスとしては、ボタンをクリックしてから数秒でレスポンスがないと、使用感が悪くなるため、レスポンス速度にはこだわった。

スクレイピングは、ボタンをクリックしてから実行されるのではなく、常時裏で実行し、結果をDBに登録する。
ボタンクリック時には結果のみ表示することでレスポンス速度を改善した。

また、個人開発ではサーバレンタルすると運用費が気にかかってしまうため、
無料のheroku,firebaseを使用することでサーバ代を無料にした。

リリースしたばかりだが、誰かに使ってもらえることを期待し、サービスを向上させていきたいと思う。
DjangoでGROUP BYを行う方法

# 例）部署毎の目標合計金額を取得する

目標 - target
部署 - section
社員 - user 


```python:model.py
class Target(BaseModel):
    """ 目標モデル """
    # 金額
    amount = models.IntegerField()
    # 社員ID
    user = models.ForeignKey(User, on_delete=models.PROTECT)
    # 部署ID
    section = models.ForeignKey(Section, on_delete=models.PROTECT)
```

```python:group_by.py
# 部署毎の目標合計金額
total_amount_by_section = (
            Target.objects
            .values("section_id")
            .annotate(section_total=Sum("amount"))
            .values("section_id", "section_total")
        )
```

1度目のvaluesでsection_idにのみ取得項目を絞り込みますが、後続のannotateでamountの合計値を算出してもエラーにはなりません。発行SQLは下記の通り

```sql:total_amount.sql
SELECT
	"target"."section_id",
	SUM("target"."amount") AS "section_total"
FROM
	"target"
GROUP BY
	"target"."section_id";

```
Goの1.16で missing go.sum entry for module ... to add: ...と出るときの対処法

## 起きた事
とあるアプリケーションを起動しようと、コンテナをbuildしていたらこんなエラーに遭遇しました。

![container.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607302/5889a066-fea0-4f84-1974-c3a5284b91a7.png)

`go build ...`のタイミングで落ちているようで。
どうやら`go.sum`にモジュールが載っていないことが原因の模様です。


## 原因
https://golang.org/doc/go1.16#go-command
ここにこんな一文が。

> Build commands like go build and go test no longer modify go.mod and go.sum by default. 

要するに、コード中で`import`していたら今までは`go.sum`とかを変更してくれていたのが、デフォではしてくれなくなったみたいです。
全部ちゃんと書いてね☆

## 対応

```bash
go mod tidy
```
をビルド前に挟めば、今まで通り勝手に更新してくれるようになります。

## 自戒
ちゃんとリリースノートは読もう！
【Python】S&P500の中で最適ポートフォリオを見つけ出す

S&P500(米国優良企業約500社)の組合せの中から，最適なポートフォリオを探索します．

この記事ではソースコードの大まかな流れだけを説明し，**全ソースコードの説明および最適化結果は本記事の最後にあるリンク先で説明します．**


#やりたいこと

S&P500(米国優良企業約500社)の組合せの中から，最適ポートフォリオを見つけたいです．

今回見つける最適ポートフォリオは，

・リスク（ボラティリティ）が最小になるポートフォリオ
・シャープレシオが最大になるポートフォリオ

とします．シャープレシオとは，期待リターンをボラティリティで割った量です．

#ポートフォリオ最適化の概要
以下のような流れで行います．

1.S&P500の株価時系列データを取得する
2.株価データを元に各銘柄の期待リターンとリスク（ボラティリティ，共分散の平方根）を求める
3.色々な割合のポートフォリオでその期待リターンとリスクを計算する．つまり，効率的フロンティアを作成する
4.リスクが最小，シャープレシオが最大になるポートフォリオを各々探す
(5.セクターごとのポートフォリオに直す）

#S&P500の株価時系列データを取得する
まずは，S&P500銘柄の質（期待リターン，リスク）を計算するために，銘柄の株価を取得する必要があります．

S&P500の銘柄取得については，以下のURLにあるCSVから取得することにします．

https://raw.githubusercontent.com/datasets/s-and-p-500-companies/master/data/constituents.csv

S&P500銘柄の取得は，以下でできます．

```python
import pandas as pd
url = "https://raw.githubusercontent.com/datasets/s-and-p-500-companies/master/data/constituents.csv"
sp500 = pd.read_csv(url, encoding="SHIFT_JIS")

sp500 = sp500['Symbol'] #sp500ティッカーコードのデータフレーム
sp500_tickers = sp500.values.tolist() #データフレームをリストに変換
```

そして，取得した銘柄の株価を取得するには，pandas-datareaderなどを用います．

```python
import datetime
import pandas_datareader.data as web
start = datetime.date(2014,1,1)
end = datetime.date.today()

data = web.DataReader(sp500_tickers, 'yahoo', start, end)["Adj Close"] #sp500の株価データを取得
```

ただし，開始日（start）以前に上場していない銘柄については，株価は取得されないことに注意して下さい．
また，何度も株価を取得すると時間もかかり，APIのサーバーにも良くないようなのでCSVファイルに保存しておくことをおすすめします．

```python
data.to_csv('sp500_stocks_data.csv')
```

詳しくは，以下の記事をご覧ください．

https://optrip.xyz/?p=3512

#2.株価データを元に各銘柄の期待リターンとリスクを求める

コード全文は記事の最後に貼ってあるリンク先で説明しますが，簡単に説明すると，ポートフォリオ全体の期待リターンとリスク（ボラティリティ）の計算に必要な各銘柄のリターンおよび共分散行列を以下で計算します．

```python
# calculate daily and annual returns of the stocks
returns_daily = data.pct_change()
returns_annual = returns_daily.mean() * 250

# get daily and covariance of returns of the stock
cov_daily = returns_daily.cov()
cov_annual = cov_daily * 250
```

各銘柄のリターンと銘柄の割合ベクトルの内積をとることでポートフォリオの期待リターンを求めます．
また，各銘柄間の共分散行列を割合ベクトルで挟み，平方根を取ることでリスク（ボラティリティ）を求めます．

#3.効率的フロンティアを作成する

縦軸に期待リターン，横軸にボラティリティを取り，各プロット点がポートフォリオを意味する図を作ります．以下は実際に生成した効率的フロンティアです．

![optSP500_effi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1298289/61344abb-e4ff-c1cc-9965-b45941a80ec8.png)


点が緑色であるほどシャープレシオが大きく，赤色であるほど小さいです．

#4.ボラティリティが最小，シャープレシオが最大になるポートフォリオを各々探す

先ほど作成した効率的フロンティアの図から，ボラティリティが最小のポートフォリオと，シャープレシオが最大になるポートフォリオをピックアップします．

効率的フロンティアの図では，青色の位置のポートフォリオがボラティリティ最小，赤色の位置のポートフォリオがシャープレシオ最大となっています．

これらを円グラフにすると，以下のようになります．

![optSP500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1298289/9c71f656-0989-8145-4ec3-e618bc2e09a7.png)


ひとつひとつの銘柄が描かれているのですが，細かすぎて何が何だか分かりませんよね．そこで，セクター別にまとめて円グラフを表示してみます（また，記事最後のリンク先では表で銘柄別の結果を示しています）．

#5.セクターごとのポートフォリオに直す

これについては，以下のリンク先で説明します．

#全ソースコードと実行結果
##全ソースコード
S&P500の中で最適ポートフォリオを見つけ出し，セクター別でも表示するコード全文は以下です．コードの説明もしています．

https://optrip.xyz/?p=3595

##実行結果
以下の記事では，実行結果の詳細のみを書いています．

https://optrip.xyz/?p=3598

実行結果には，以下が含まれます．
・最適ポートフォリオ（リスク最小，シャープレシオ最大）の銘柄構成割合
・上記の最適ポートフォリオをセクター別構成にまとめたもの
TypeScript 役立ち情報

TypeScriptの役立ち情報をまとめます。

Googleによるコーディングスタイルガイド<br>[Google TypeScript Style Guide](https://google.github.io/styleguide/tsguide.html)

Googleによる命名ガイドライン<br>[Code Health: IdentifierNamingPostForWorldWideWebBlog](https://testing.googleblog.com/2017/10/code-health-identifiernamingpostforworl.html)

Deep Dive<br>[TypeScript Deep Dive](https://basarat.gitbook.io/typescript/)

型実装<br>[GitHub: TypeScript/master/lib](https://github.com/microsoft/TypeScript/tree/master/lib)

<hr>

「急がば回れ」という言葉がよく似合う言語だと思ふ
Laravelでウェブアプリを作ろう

Laravelをアプリケーションサーバーとして動かすための設定を記載していきます

##参考にさせていただいたサイト
https://qiita.com/sano1202/items/6021856b70e4f8d3dc3d

自分の動作環境ではいくつかエラーが出たので、その点も含めて修正したデータを載せていきます

##動作環境
- MacOS Big Sur MacBookAir(13-inch, Mid2013)

##もくじ
ウェブアプリは以下の手順で作成するものとします

###環境設定+プロジェクトの作成
- [composerによるプロジェクトの作成](https://qiita.com/kunrenyouAcount/items/ef790c5ead01e2a88297)

###未定
1. [画面の表示とパラメーターの受け取り]()

###APIの作成
1. [Dockerでコンテナの作成とその接続設定](https://qiita.com/kunrenyouAcount/items/1e5641fa79d255425ecc)
1. [Migrateの作成](https://qiita.com/kunrenyouAcount/items/4ee79e44c4eb8e7cc302)
1. [モデルとシーダーの作成](https://qiita.com/kunrenyouAcount/items/276b5fa3efc01cbc1864)
1. [コントローラーの作成](https://qiita.com/kunrenyouAcount/items/3f6144ed4a615a5c01a4)
Webで使われるデータ形式（フィード,マイクロフォーマット）

# フィード
**フィード**とは、Webサイトなどの更新履歴を配信するためのファイルである。ブログやニュースサイトなど、頻繁に更新が発生するWebサイトで使われ、ユーザーはWebサイトにアクセスすることなく、最新の更新情報を確認することができる。フィードの中身は、主にハイパーリンクのリンクの集まりでWebページの全体や一部が含まれる。
![フィード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999125/de8b98ac-f867-3773-afa6-3dded15b65f4.jpeg)


## RSS,Atom
フィードは、現在RDFという記述言語をベースにした**RSS 1.0**と、XMLをベースにした**RSS 2.0**という２つの系列に分裂して開発が進められている。
分裂して開発されるRSSの代替として、有志により**Atom(アトム)**という形式も構築されている。
## フィードリーダー
Web上のフィードを取得し、管理するためのソフトを**フィードリーダー**、あるいはフィードアグリゲーターと呼ぶ（RSSリーダーと呼ばれることもある）。複数の登録フィードを定期的にチェックし、更新情報をユーザーが閲覧できるようにする。
## ポッドキャスト
**ポッドキャスト**は、Webサーバー上に音楽や動画を配置し、RSSを通してWeb上に配信する手法である。RSSにより、ブログのように簡単に音楽や動画を配信できる。
# マイクロフォーマット
**マイクロフォーマット**は、HTMLやXHTMLでWebページの中に意味を表現する記述を埋め込む書式である。「この文字列は住所を表す」、「この文字列は氏名を表す」といった情報を付け加えられる。
マイクロフォーマットの情報を外部のコンピューターから読み取り、自律的に除法の意味を理解して処理する**セマンティックWeb**を実現できる。
例としては、Google検索のリッチスニペット（検索結果にレビューや営業時間が表示される）やhCard（連絡先情報）、hCalender（イベント情報）などがある。
マイクロフォーマットは、microformatsコミュニティという団体により、用途に応じてさまざまなものが公開されている。しかし、この団体以外にも開発団体があり、書式が統一されていない。
![マイクロフォーマット.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/999125/1ce4c729-18ea-246c-137c-f5df19233e08.jpeg)


# 参考
[イラスト図解式 この一冊で全部わかるWeb技術の基本](https://www.amazon.co.jp/gp/product/B06XNMMC9S/ref=ppx_yo_dt_b_d_asin_title_o05?ie=UTF8&psc=1)
JavaScriptの基礎

#JavaScriptとは

JavaScriptは、Webサイトに「動き」をつけるプログラミング言語です。「JavaScript」を略して使いたいときは「js」といいましょう。
ここでは「js」と略していきたいと思います。この記事ではJavaScriptを理解するために押さえておくべき単語についてまとめていきます。

##変数

jsにおける「変数」とは「箱」のようなものです。
例）私はワタルと言います。ワタルはサッカーが好きです。ワタルのポジションはフォワードです。

このような文章があったとする場合、上司からこの『ワタル』の名前を『ケンタ』に変えといてと言われたとします。
この時便利なのが変数です。変数をnameとしてこのnameに当てたい名前(ここではケンタ）を入れればいいだけです。

##js上でのコメント

「コメント」はプログラムとして実行されないので、書いたコードの説明、メモに使えます。


```
// これで一行コメントをかけます。
```
複数行コメントの書き方


```
/*
コメント
コメント
コメント
*/
```

##データ型

データ型とは数値、文字列、配列、論理値、オブジェクトなどです。ここでは特に重要な文字列と数値について触れていきます。

####文字列(string型)
jsでは、文字列をダブルクォーテーション（”）またはシングルクォーテーション（’）で囲んで表現します。
そのため変数の中に文字列を入れたい場合は以下の記述をします。

```
let cat = "ねこ";//これはOK
let cat = ねこ; //これはNG
```

#####数値(number型)
数値を入れたい場合はそのまま書いてOKです。
数値をクォーテーションでくくってしまうと、文字列として扱われてしまうので注意してください。

```
let num = 1; //これはOK
let num = "1"; //これは文字列の１として扱われる
```

これは文字列と数値をわかりやすくしたコードです

```
console.log(10 + 20);
console.log("15" + "25");
```

10 + 20は「 30 」と表示されて
“10” + “20”は「 1020 」と表示されます。

##配列

簡単に言うとデータ型の複数版です。配列データを作成することで大量の値をまとめて1つのデータとして扱うことができるのです。またその値の一つ一つの要素をインデックス＝住所(添字）と呼んだりします。
WSL2 に VcXsrvをインストール

Windows 10上で軽快に動くLinuxが欲しかったので調査。

## WSL2 の インストール

* [マニュアル](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)

```sh
wsl --install
```

OS再起動

## VcXsrvのインストール

* [参考](https://github.com/microsoft/WSL/issues/4106#issuecomment-706291962)

* [VcXsrvのインストール](https://sourceforge.net/projects/vcxsrv/files/latest/download)

```sh
echo "export DISPLAY=\$(awk '/^nameserver/ {print \$2; exit}' /etc/resolv.conf):0" \
  >> ~/.profile
```

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/b34176d1-9b8d-19dc-3858-c2888c37c61a.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/d14be5fd-0696-5d6f-a79a-7768345d90eb.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/30731b3f-b97d-c8b1-6255-4d5275b6412d.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/02b71fde-cb62-8cc6-39d2-36a33341ebb2.png)


`config.xlaunch` は `shell:startup`にコピーしておく。
authenticate_user!メソッド

authenticate_user!メソッドはログイン状態によって表示するページを切り替えるメソッドでdeviseをインストールをすることで使用できます。

通常はbefore_actiontiと一緒に利用しアクションを実行する前にログインしていなければログイン画面に遷移させられます。
ただindexページ、詳細ページ、検索機能などはログインしていなくても見れる状態にしたいというのがあるので

```ruby
before_action :authenticate_user!, except: [:index, :show, :search]
```

のように`except: [:index, :show, :search]`をつけてあげればindex,show,searchアクションは除かれるのでログインしていなくても遷移させられることはありません。
plantFEMをWindowsで使う方法

# 数値計算ライブラリplantFEMをWindows10で使う方法

## 1. Windowsの機能の有効または無効　＞　Linux for Windowsの有効

こちらのリンクをご確認ください。

https://pc-karuma.net/windows-10-turn-windows-features-on-or-off/

または

https://docs.microsoft.com/ja-jp/windows/wsl/install-win10

## 2. 再起動後、Microsoft StoreよりUbuntu 20.04をインストールし、起動


## 3. 現れた黒い画面に、以下を順に打ち込み、それぞれエンターキーを押す。
 
```
apt update
apt upgrade -y
git clone https://github.com/kazulagi/plantfem
cd plantfem
python3 setup.py
```

### 4. VScodeをインストール・起動し、左下の接続ボタンをクリックしUbuntu20.04を選択

追記します。
sedコマンドと拡張正規表現3

# 正規表現のパターン指定をさらに完結にしたい
※「シス環系女子 season2 第9話」の備忘録です。

## 拡張正規表現テクニック



- [0-9]+

全ての数字を表す。ex)0, 4, 15, 100, 2021, etc...
正規表現の「+」や「*」は、前の文字の表現の繰り返しを表す。

以下テストデータ

```
$ cat test_for_sed2.log 
category100a
category200b
category300c
```

以下は2つは同じ意味。
※mac os で「-e」で後方参照が実行できなかった。

```
$ cat test_for_sed2.log | sed -E "s/category(100|200|300)/category-\1-/"
category-100-a
category-200-b
category-300-c
```

```
$ cat test_for_sed2.log | sed -E "s/category([0-9]+)/category-\1-/"
category-100-a
category-200-b
category-300-c
```

- [^]

ブラケットの中で使うことで後に続く文字列以外を表す。
※「キャレット」あるいは「ハット」と読む。


ex)[a-d]=a~dの文字列ならなんでも良い。
ex)[^a-d]=a~d以外の文字列ならなんでも良い。
ex)[^:]=:以外の文字列ならなんでも良い。

以下テストデータ

```
$ cat test_for_sed3.log 
http://192.160.11.150:3000/
http://penguin:3000/
```

以下2つは同じ意味

```
$ cat test_for_sed3.log | sed -E "s/(192.160.11.150|penguin):3000/\1:13000/"
http://192.160.11.150:13000/
http://penguin:13000/
```

```
$ cat test_for_sed3.log | sed -E "s#(://[^:]+):3000#\1:13000#"
http://192.160.11.150:13000/
http://penguin:13000/
```


- ^

行の先頭文字列のみ表す拡張正規表現。

以下テストデータ

```
$ cat test_for_sed4.log 
# 拡張正規表現のテストデータ
 - hoge
  - fuga - fuga
  - piyo - piyo
   - foo - foo - foo
   - bar - bar - bar
  - baz - baz
```

項目文字の「-」を「*」に変換したい時。
以下だと文字列中の「-」まで変換されてしまう。

```
$ cat test_for_sed4.log | sed -E "s/( |  |   )- /\1* /g"
# 拡張正規表現のテストデータ
 * hoge
  * fuga * fuga
  * piyo * piyo
   * foo * foo * foo
   * bar * bar * bar
  * baz * baz
```

そこで先頭文字を表す「^」を使うようにする。
以下、その例。

```
$ cat test_for_sed4.log | sed -E "s/^( |  |   )- /\1* /g"
# 拡張正規表現のテストデータ
 * hoge
  * fuga - fuga
  * piyo - piyo
   * foo - foo - foo
   * bar - bar - bar
  * baz - baz
```

さらにスペースの表現を以下のように変えるとスッキリする。

```
$ cat test_for_sed4.log | sed -E "s/^( +)- /\1* /g"
# 拡張正規表現のテストデータ
 * hoge
  * fuga - fuga
  * piyo - piyo
   * foo - foo - foo
   * bar - bar - bar
  * baz - baz
```

- $

文字列の最後を表す。

```
$ cat test_for_sed5.log 
hoge。
fuga。fuga。
piyo。piyo。piyo。
```

以下のように使うことで、最後の「。」だけ変換させることができる。

```
$ cat test_for_sed5.log | sed -E "s/。$/./"
hoge.
fuga。fuga.
piyo。piyo。piyo.
```
郵便物の仕分け自動化

〇要件定義（要求定義）

【背景】
　組織では、頻繁に組織変更や人事異動が発生します。
　これにより、古い部署名で届いたり、既に異動してしまった人の郵便物が、誤って届くなどの事象が発生します。
　このような事象が発生することにより、郵便物の仕分けに関わるメンバーの負担が増大します。
　このような負担を軽減するために、業務であつかう郵便物の仕分けを自動化する方法を検討しました。

【やりたいこと】
　郵便物に記載のある部署名をよみとり、自動でポストに投函する。
　投函が終わったら、送付元と送付先に、投函完了のメールを送信する。

【市場分析】（検討中）
〈未来予測〉
テレワークが当たり前になれば、個人宅へ配送する比率が高くなる。
一方、ペーパーレス化とそれに伴うコスト削減の要請も高くなる。

〈想定顧客〉
緊急事態宣言のなかでも、出勤を余儀なくされている、郵便担当者。
自動化による業務の最適化を検討している担当者。

【競合分析】（検討中）
コスト・品質面において、優位性を訴求することが必要となる。

分析対象（検討中）
　Amazon：（検討中）
　アウトソーシングの各社：（検討中）
　日本郵便：（検討中）
　宅配業の各社：（検討中）

〇外部設計
【前提条件】
あて名の記載には、手書き文字が含まれる。
部署名とともに、部署コードが記載される。

１００通の仕分けを３０分で終えられること。
毎月の導入コストが２万円以内に収まること。

【機器構成】
スマホ
　カメラ：(検討中)
　アプリケーションサーバ：(検討中)
　メールサーバ：(検討中)

搬送機構：(検討中)
　人協働ロボットアーム：(検討中)
　　Tinkerkit Braccio（30,000円）
　　Robotiq バキュームグリッパー

　　Rotrics DexArm（120,000円）

ポスト：(検討中)

投資額合計：(検討中)

※メモ
スマホとロボットアームがあれば、システムを構築できそう。
ハードの価格は、１０万～２０万円程度におさまりそう。

【ソフトウェア構成】（検討中）
adobe SCAN:OCRソフト
googlelens:OCRソフト

Google　drive
　Colaboratory：Pythonコード実行
　　OpenCV 輪郭抽出
　　OCR
　　
〇内部設計

【作業フロー】
google lens
・郵便物をカメラで読み込む。
・カメラ画像から部署名部分を切り出す。
・部署名部分をテキスト化する。

google drive
・部署名のテキストを部署名マスタと照合する。

robot arm
・照合結果に対応したポストに投函する。

gmail
・ポストに投函したらemailを送信する。

〇プログラミング(検討中)
PCからGoogle driveに画像をアップロードする

画像の読み込み処理

画像の分類処理
　部署マスターとの突合せをする
　　部署が存在する場合
　　　部署ごとに分類する
　　　　個人ごとに分類する
　　　投函処理を実行する

　　部署が存在しない場合
　　　個人名の記載がある場合
　　　　個人の所属確認をする

　　　個人名の記載がない場合
　　　　手作業で投函処理を実行する

個人の所属確認をする
　所属している場合
　　郵便の投函処理をする
　　　所属していない場合
　　　　異動している場合
　　　　　異動先へ転送する
　　　　退職している場合
　　　　　個人宅へ転送する
　　　　　
郵便の投函処理
　ロボットアームで郵便物をつかむ
　ロボットアームでロッカーに投函する

投函連絡（メール送信）処理

〇単体テスト(検討中)
〇結合テスト(検討中)
〇システム（総合）テスト(検討中)
〇運用テスト(検討中)

※検討事項
adobe SCANで手書きの郵便物を読み取ったときの、変換精度はどのくらいか？
誤変換のパターンから、正しい変換結果を導きだせるか？

google lensとスプレッドシートの連携は可能か？

※参考記事へのリンク
https://prtimes.jp/main/html/rd/p/000000007.000021229.html
https://www.switch-science.com/catalog/2699/
http://www.nihonbinary.co.jp/Products/Robot/robotiq_vacuum_grippers.html

ロボットアーム
https://www.youtube.com/watch?v=qLyFig3nUyY
https://www.rotrics.com/products/dexarm

Expansibility/dp/B08D28XGSV/ref=sr_1_1
https://www.youtube.com/watch?v=DA-0yz_O_u0
https://www.youtube.com/watch?v=3y9N1l7ofYY

アウトソーシング
https://www.noc-net.co.jp/blog/2019/01/column_271/
https://www.todoker.com/

開発手法
https://zine.qiita.com/interview/202103-shift/?utm_source=qiita&utm_medium=recommend

OCR
https://www.itmedia.co.jp/news/articles/2005/08/news053.html
Payjpの決済処理(備忘録)

私の備忘録です

```ruby:purchase.controller.rb
private

  def pay_item #決済処理の記述
    Payjp.api_key = ENV["PAYJP_SECRET_KEY"]
    Payjp::Charge.create( amount: @item.price , card: address_params[:token], currency: 'jpy')
  end
```
【初心者でもわかる】HTMLのコメントをコメントアウトする裏技

#どうも7noteです。HTMLのコメントをコメントアウトする方法

HTMLでのコメントの方法は以下の通りです。
**前後に`<!--`と`-->`を書くことでコメントにできます。**

```html
<!-- ここにメモ書き -->
```
ではこれを使って複数のコメントをまとめてコメントアウトしようとすると・・・うまくいきません。

```失敗.html
<!-- 
  <!-- 複数行をコメントアウト -->
  <!-- したいけどうまくいかない -->
-->
```

この方法では、一番最後の`-->`はコメントとして認識されません。
Qiitaでも文字が白くなっているのがわかると思います。白い文字の箇所は表示されてしまうところになります。

## コメントをコメントアウトする裏技

### ・ `<style>`タグを使う方法

```成功.html
<!-- この方法なら複数行コメントアウトできます↓ -->
<style>
  /*
    <!-- 複数行をコメントアウト -->
    <!-- できる方法 -->
  */
</style>
```

### ・ `<script>`タグを使う方法

```成功.html
<!-- この方法でも複数行コメントアウトできます↓ -->
<script>
  /*
    <!-- 複数行をコメントアウト -->
    <!-- できる方法② -->
  */
</script>
```

## 解説

`<!-- -->`この表記のままではコメントで入れ子構造を組むことはできません。
なので`<!-- -->`をHTMLとして認識させないようにすることで、**HTMLのコメントをstyleやscriptタグ内でコメントアウトすることができます。**

phpが使えるファイルであれば、phpでもコメントアウトが可能です。

```index.php
<?php
  /* 
    <!-- phpでもコメントをコメントアウトできます。 -->
  */
?>
```

## まとめ

コメントをコメントアウトできるとはいえ、あまり乱用するとソースがめちゃくちゃになってしまうので、
一時的にまるごとコメントアウトしておきたい、というようなケースでの使用のみにとどめて置くほうがよいと思います。

もし消し忘れてしまっていたらぐちゃぐちゃのソースが公開されてしまいますし、なにより他の人が見たときに見にくいソースになってしまうので、**乱用は避けましょう。**

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (-3)　解決メモ

https://youtu.be/ltDdZAJli8c

windowsでこれの動画の通りにやるとエラーがでてしまう箇所があって、そのエラーの解決メモ。

エラーはだいたいこんなの

```
Caused by:
Mysql2::Error::ConnectionError: Unknown MySQL server host 'db' (-3)
/app/bin/rails:5:in `<top (required)>'
/app/bin/spring:10:in `block in <top (required)>'
/app/bin/spring:7:in `tap'
/app/bin/spring:7:in `<top (required)>'
Tasks: TOP => db:create
(See full trace by running task with --trace)
ERROR: 1
```

このエラーが出た人は`docker-compose.yml`の

```
version: '3'
services:
  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./mysql-confd:/var/lib/mysql 　<---この行
```

 `- ./mysql-confd:/var/lib/mysql`と書かれている部分を
`- ./src/db/mysql_data:/var/lib/mysql`に書き換えてみてください。

これで僕は治りましたが、この治し方が正しいやり方なのかわからないのであくまでも応急処置といった認識でお願いします。
for文 swift

#■for文一つにしても色々ある。

■数字

```swift
for i in 1..<5 {
  print(i)
}
// 1,2,3,4

for i in 1...5 {
 print(i)
}
// 1,2,3,4,5

for _ in 1...5 {
 print(a)
}
// a,a,a,a,a  _の場合繰り返したいものを5回分返すと言う意味になる。
```

■文字

``` swift
let a = "banana"

for b in a {
  print(b)
}
//  b,a,n,a,n,a 一と文字づつ順番に返される

```

■ 配列

``` swift
let fruits = ["Apple","banana","Orange"]

for a in fruits {
  print(a)
}
// Apple,banana,Orange  順番に返す

let contacts = ["Apple": 200, "Banana": 300, "Orange": 400]

for person in contacts {
 print(person.key)
}
// Apple,Banana,Orange

for person in contacts {
 print(person.value)
}
// 200,300,400

```
8-4.IDFA対応　IDFAの許可リクエストの説明文を日本語に対応する

###完成形
AlertのタイトルはApple側が表示するもので、真ん中に表示されている説明文を日本語にも対応しました。
![Simulator Screen Shot - iPhone 8 Plus - 2021-04-29 at 19.36.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413207/7ef0c448-4047-8935-ab91-b29906876382.png)

###info.plistへ説明文の追加
Privacy - Tracking Usage Description
をKeyとしてValueにユーザにAlertを出した時に表示される文言を追加します。
このままでは、英語の説明文が表示されます。（This identifier will be used to deliver personalized ads to you.）
![Screen Shot 2021-04-29 at 18.35.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413207/0bb52b83-b608-673e-e179-2e852801d386.png)

###ローカライズする言語を追加
プロジェクト設定の info タブにある Localization から日本語を追加します。
![Screen Shot 2021-04-29 at 18.34.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413207/852b06d3-a3ac-ce1d-b4f2-9d0f74bd960c.png)

###InfoPlist.strings ファイルを新規作成
ファイルの新規作成で、Strings File タイプを選択し、ファイル名を”InfoPlist.strings“として作成します。
ファイル名は必ず”InfoPlist.strings”でないといけません。大文字小文字が違っても正しく認識されないので注意。
####InfoPlist.strings ファイルのローカライズを設定
作成した”InfoPlist.strings“ファイルを選択し、右サイドにある情報パネルの Localize… ボタンで日本語を選択します。（先の手順で日本語を追加したのでローカライズ言語が選択できるようになっています）
####InfoPlist.strings にローカライズ用のテキスト設定を記載
“InfoPlist.strings“に、ローカライズ用のテキストを追加します。
![Screen Shot 2021-04-29 at 18.34.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413207/4438e1b0-a75b-c45c-3d4c-1b49a0eedfae.png)
GraphQL-Rubyの認可についてまとめる

#はじめに
最近、GraphQL-Rubyを使って認可を実装する機会があったのでまとめてみます。
用語的には認証と認可がありますが、今回は認可を扱います。（GraphQLは一般的には認証を扱ってません）

# resolverやmutationに認可をつける
まずは、`resolver`や`mutation`に対しての認可に利用できるメソッドについてまとめます。
https://graphql-ruby.org/mutations/mutation_authorization.html
## ready?
`ready?`メソッドは、以下のようにresolverやmutationで使用できます。`ready?`はmutation実行前に自動的に実行されます。戻り値がfalseの場合はnullが返されますが、例のようにGraphQL Errorを発生させた方がベターでしょう。

```mutation.rb
class Mutations::PromoteEmployee < Mutations::BaseMutation
  def ready?(**args) # argsはmutationの引数
    if !context[:current_user].admin?
      raise GraphQL::ExecutionError, "Only admins can run this mutation"
    else
      true
    end
  end

  def resolver(**args)
    # mutation実行
  end
end
```

## authorized?
mutationには`authorized?`メソッドも用意されています。実はこのメソッドは`ready?`メソッドとほとんど同じ動きをします。上の`ready?`を`authorized?`に書き換えても同様に動作します。唯一の違いは`argumentsをロードする`かどうかです。
argumentsをロードするとは、以下のようにargumentを定義した場合にargumentのemployee_idからloadsで定義されているEmployeeオブジェクトを自動的にDBから取得してくれることを指します（多分)。

```mutation.rb
argument :employee_id, ID, required: true, loads: Types::Employee
```
上記の場合だと、引数で指定したidのemployeeオブジェクトが取得されます。故にauthorized?メソッドを利用すると、以下のようにも書くことができます。

```mutation.rb
argument :employee_id, ID, required: true, loads: Types::Employee

def authorized?(employee:)
  context[:current_user].manager_of?(employee)
end
```

# オブジェクトタイプに認可をつける
GraphQL-Rubyでは、関連を持つオブジェクト同士は、クライアント側で自由に取得できます。すると、本来は権限が必要なリソースにもアクセスできてしまうことがあります。それを防ぐためにオブジェクトタイプごとに認可を設定する方法をまとめます。

## visible?を使う
https://graphql-ruby.org/authorization/visibility.html
visible?メソッドはその名の通り、スキーマ自体がユーザから見えなくなります。例えば、実験的な機能を特定のユーザのみに開放するみたいなユースケースが考えられます。
以下の例では、visible?メソッドの戻り値がfalseなら、graphqlエラーが返ることになります

```secret_type.rb
  class secretType < BaseObject
    def self.visible?(context)
     context[:current_user].admin?
    end

    field :hoge, Hoge, null: true
  end
```

## authorized?を使う
https://graphql-ruby.org/authorization/authorization.html
1番、認可っぽいのはこのauthorized?メソッドでしょうか。名前からしてそうですね。
以下の例では、current_userがobject.userと等しい場合は、Objectが返され、等しくない場合は、nullが返ります。

```secret_type.rb
  class secretType < BaseObject
    def self.authorized?(object, context)
     context[:current_user] === object.user
    end

    field :hoge, Hoge, null: true
  end
```

また、authorized?メソッドがfalseの場合にエラーを返したい場合は、schemaのトップレベルにエラーを定義することができます。

```my_schema.rb
class MySchema < GraphQL::Schema
  def self.unauthorized_object(error)
    raise GraphQL::ExecutionError, "An object of type #{error.type.graphql_name} was hidden due to permissions"
  end
end
```


## scopeを使う
https://graphql-ruby.org/authorization/scoping.html
authorized?メソッドは、そのオブジェクトを返すか、返さないかの二択でしたが、ユーザによって返すオブジェクトを制限したい場合もあると思います。その場合は`scope`メソッドが便利です。
以下の場合は、adminユーザならば、オブジェクトを全て返し、それ以外はpublishedなproductを返します。

```product_type.rb
  class prodcutType < BaseObject
      def self.scope_items(items, context)
        context[:current_user].admin? items : items.published
      end
  end
```
このscopeを適用するかどうかは、以下のようにfieldの引数で定義できます。

```.rb
field :products, [Types::Product] scope: true
```
戻り値が配列の場合は、デフォルトでtrueになっており、値の場合はfalseになっています。

#まとめ
以上、GraphQL-Rubyの認可についてまとめました。Graphqlの認可は結構ややこしいので、しっかり整理していきたいです！
～ 順列全探索 ～ チートシート

#目次
**まずは使用するライブラリをインポート** `import itertools`

[全組み合わせを列挙](#全組み合わせを列挙)　`list(itertools.permutations(mat))`
[全組み合わせをfor文で処理](#全組み合わせをfor文で処理)　`for per in itertools.permutations(mat):`

#はじめに

チートシートの扱いついては[ここ](https://qiita.com/ysys_Ba/items/d27282b888abbd1f43e7#%E3%83%81%E3%83%BC%E3%83%88%E3%82%B7%E3%83%BC%E3%83%88%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)を読んでください

#全組み合わせを列挙

```python:permutations.py
import itertools

mat = [1, 2, 3, 4]

per = list(itertools.permutations(mat))
print(per)
```

```python:mat
>>> [(1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2), (1, 4, 2, 3), (1, 4, 3, 2), (2, 1, 3, 4), (2, 1, 4, 3), (2, 3, 1, 4), (2, 3, 4, 1), (2, 4, 1, 3), (2, 4, 3, 1), (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1), (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2), (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]
```

第２引数を指定しない場合は、すべての要素を並べ変えてできる組み合わせとなる。（nCn）


```python:permutations.py
import itertools

mat = [1, 2, 3, 4]

per = list(itertools.permutations(mat, 2))
print(per)
```

```python:mat
>>> [(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4, 1), (4, 2), (4, 3)]
```

第２引数を指定すると、指定した数の要素を選び並べ変えてできる組み合わせとなる。(nCk)

#全組み合わせをfor文で処理
```python:permutations.py
import itertools

mat = [1, 2, 3, 4]
for per in itertools.permutations(mat):
  print(list(per))
```

```python:mat
>>> [1, 2, 3, 4]
>>> [1, 2, 4, 3]
>>> [1, 3, 2, 4]
>>> [1, 3, 4, 2]
>>> [1, 4, 2, 3]
>>> [1, 4, 3, 2]
 :
```

`list()`で配列化する
愚直にfor文で頑張って順列全探索を実装しても速度で勝てないので、`itertools`を使ってスマートに実装

```python:permutations.py
import itertools

mat = [1, 2, 3, 4]
for per in itertools.permutations(mat, 2):
  print(list(per))
```

```python:mat
>>> [1, 2]
>>> [1, 3]
>>> [1, 4]
>>> [2, 1]
>>> [2, 3]
>>> [2, 4]
 :
```

第２引数で要素数を指定
【AWS】VPCの設定について

#プログラミング勉強日記
2021年4月29日

#VPCの設定
　AWSアカウントを作成すると自動的に各リージョンに1つずつデフォルトVPCとデフォルトサブネットが構成される。

- サイズ`/16`のIPv4 CIDRブロックのVPCを作成する
- 各AZにサイズ`/20`のデフォルトサブネットを作成する
- インターネットゲートウェイを作成してデフォルトVPCに接続する
- デフォルトのセキュリティグループを作成して、デフォルトVPCに関連付ける
- デフォルトのネットワークアクセスコントロールリストを作成して、デフォルトVPCに関連付ける
- デフォルトVPCを備えたAWSアカウントにはデフォルトDHCPオプションセットを関連付ける
- パブリックとプライベートのDNSホスト名が付与される

#VPCウィザード

　VPCウィザードを利用することで、頻繁に利用されるVPC構成を瞬時に構成することができる。VPCウィザードはマネジメントコンソールで以下の4つの方式を選択できる。

1. 1個のパブリックサブネットを持つVPCを持つVPC
2. パブリックとプライベートサブネットを持つVPC
3. パブリックとプライベート・ハードウェアVPCアクセスを持つVPC
　(サイト間VPNをオンプレミス側と接続するときの設定を構成するもの。)
4. プライベートのサブネットのみでハードウェアVPNアクセスを持つVPC

　VPCウィザードを利用しない場合は、VPCを作成、サブネットを作成、、と1つずつ作成する。
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/dc9af27f-dbc5-eb0d-511d-62eb0dccdeef.png)
UnityAdsで ATT - App Tracking Transparency

## 環境
MacOS Catalina 10.15.7
Unity 2019.4.17
Advertisement 3.5.2 ※UnityAds
Xcode 12.2

## UnityAdsで対応が必要な手順

基本的には以下のガイドラインに沿って対応します。
https://unityads.unity3d.com/help/resources/ios14-publisher-guide

- 1. UnityAdsのパッケージ`Advertisement`を3.5.1以降にする
- 2. Info.plist に Privacy - Tacking Usage Description を追記する
- 3. AppTrackingTransparency.frameworkを参照するように設定

### 1. UnityAdsのパッケージ`Advertisement`を3.5.1以降にする

`Window > Package Manager > Unity Registty > Advertisement`

UnityAdsに特有なところはここだけです。
SKAdNetworkIdentifierなどはビルド時に自動で追加されてるはずなので改めて対応する必要はありません。

### 2. Info.plist に Privacy - Tacking Usage Description を追記する
### 3. AppTrackingTransparency.frameworkを参照するように設定

- - -
#### 追記
中身を検証してませんが、こんなものがありました。
これで済むならこちらで良さそうです。
https://alanyeats.com/post/unityapptrackingtransparencypopup/

- - -

2,3に関しては以下の記事が参考になりました。

http://blog.be-style.jpn.com/article/188329627.html

ただし、一部記載内容に誤りがあるので注意してください。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ATT対応しないとiOSの審査に通らないらしいので、未対応の人は対応しておくと良いかと。<br><br>僕はこのページで対応した。<br><br>Action -&gt; Action&lt;int&gt;<a href="https://t.co/SsxYzpcAyG">https://t.co/SsxYzpcAyG</a><br>import文<a href="https://twitter.com/hashtag/import?src=hash&amp;ref_src=twsrc%5Etfw">#import</a> &lt;string.h&gt;<a href="https://twitter.com/hashtag/import?src=hash&amp;ref_src=twsrc%5Etfw">#import</a> &lt;AppTrackingTransparency/AppTrackingTransparency.h&gt;<a href="https://t.co/dPbvdx0VCu">https://t.co/dPbvdx0VCu</a> <a href="https://t.co/xyVIvaU7RK">https://t.co/xyVIvaU7RK</a></p>&mdash; ジウ@ゲーム開発者の本音 (@JiuGameEngineer) <a href="https://twitter.com/JiuGameEngineer/status/1386911750570663938?ref_src=twsrc%5Etfw">April 27, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## その他
- 許可を求める文言にすると審査でリジェクトされるらしいです。
- ネイティブのダイアログを表示する直前にクッションでお願いをする画面を表示するアプリもあります。ただし、自分の場合はゲーム開始直後のユーザーに表示する画面を極力減らしたいので見送りました。 ~~やるのが面倒だったわけではない~~

## 参考
http://blog.be-style.jpn.com/article/188329627.html

https://baba-s.hatenablog.com/entry/2020/11/30/093100

https://unityads.unity3d.com/help/resources/ios14-publisher-guide

https://unityads.unity3d.com/help/ios/integration-guide-ios#modifying-the-properties-list