OmniAICreator/Qiita-1.07M huggingface dataset:
gistコマンドでファイルをアップロードできなかった時の解決メモ

## 何が起きているか
gistコマンドでファイルをアップロードしようとしてもエラーになる。

```
> gist hoge.txt
Error: Got Net::HTTPUnauthorized from gist: {"message":"Bad credentials","documentation_url":"https://docs.github.com/rest"}
```

## 原因
gistのログインが外れている。

## 解決方法
gistのログインを行うとアップロードできるようになります。

```
> gist --login
Requesting login parameters...
Please sign in at https://github.com/login/device
  and enter code: ****-****
```

めでたしめでたし。
Serverless FrameworkでDynamoDBをローカル環境で動かす

最近、Lambdaにデプロイするコードを書いてたのですが、DynamoDBへのアクセスがあるためデプロイしないと動作確認ができず、ローカル環境でもDynamoDBを動かしたいなあと思い、調べてみました。

最初はDockerでamazon/dynamodb-localを使ってみたのですが、createTableからプログラムで書いてあげないといけないのがめんどくさくて、最終的にserverless frameworkを使う方法に落ち着きました。

## 必要な物
以下の4つがあれば大丈夫です。

- Nodejs
- npm
- Java (ローカルDynamoDBを起動するために必要)
- aws cli (aws configureで何かしら設定されていればOK。実際のAPIキーじゃなくても大丈夫です)


## 手順

### プロジェクト作成
serverlessコマンドでプロジェクトを作成します。

```shell:
$ npx serverless create -t aws-nodejs -p serverless-local-app
```

こんな感じのディレクトリ構成で作成されます

```shell:
$ tree serverless-local-app

serverless-local-app
├── handler.js
└── serverless.yml
```

### 必要なプラグインをインストール
ローカルでLambdaやDynamoDBを動かすのに必要な物をインストールしていきます。

```shell:
$ cd serverless-local-app
$ npm init -y
$ npm i serverless serverless-dynamodb-local aws-sdk
```

### serverless.ymlを書き換え
serverless.ymlでDynamoDBやLambda Functionの定義をします。

```yaml:serverless.yml
service: serverless-local-app
frameworkVersion: '2'
plugins:
  - serverless-dynamodb-local

provider:
  name: aws
  runtime: nodejs12.x
  stage: dev
  region: ap-northeast-1
  lambdaHashingVersion: 20201221

custom:
  dynamodb:
    stages:
      - dev
    start:
      port: 8000
      inMemory: true
      migrate: true
      seed: true
    seed:
      development:
        sources:
          - table: TableName
            sources: [./migrations/records.json]

functions:
  hello:
    handler: handler.hello

resources:
  Resources:
    TableName:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: TableName
        AttributeDefinitions:
          - AttributeName: attr1
            AttributeType: S
        KeySchema:
          - AttributeName: attr1
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
```

### テーブル初期化用のファイルを用意

```json:migrations/records.json
[
    {
        "attr1": "value1",
        "attr2": "value2-1"
    },
    {
        "attr1": "value2",
        "attr2": "value2-2"
    },
    {
        "attr1": "value3",
        "attr2": "value2-3"
    }
]
```

### LambdaでDynamoDBを参照するように実装

動作確認のための最低限のDynamoDBへのアクセス処理を書きます。

```javascript:handler.js
"use strict";
const AWS = require("aws-sdk");
const dynamodbClient = new AWS.DynamoDB({
  endpoint: "http://localhost:8000",
});

module.exports.hello = async (event) => {
  const params = {
    TableName: "TableName",
  };
  const response = await dynamodbClient.scan(params).promise();
  console.log(JSON.stringify(response));
};
```

### DynamoDBLocalをインストール

ローカルで動くDynamoDBをインストールします。

```shell
$ $(npm bin)/serverless dynamodb install
```

### ローカルでDynamoDBを起動
ローカルDynamoDBを起動します。
↓のコマンドはpackage.jsonのスクリプトに書いておくと便利です。

```shell
$ $(npm bin)/serverless dynamodb start
```

### Lambdaを実行

DynamoDBを起動した状態でLambdaをローカル実行します。helloはserverless.yml内で定義したFunction名です。

```shell
$ $(npm bin)/serverless invoke local -f hello

{"Items":[{"attr2":{"S":"value2-1"},"attr1":{"S":"value1"}},{"attr2":{"S":"value2-3"},"attr1":{"S":"value3"}},{"attr2":{"S":"value2-2"},"attr1":{"S":"value2"}}],"Count":3,"ScannedCount":3}
```

投入したデータを読み取って出力できていることが確認できました！


以上です。
github 特定のディレクトリ（フォルダ）、ファイルをダウンロードする方法

#Subversion
###インストール方法

```
brew install subversion
```
***
###githubの特定のフォルダーをダウンロード
```
svn export URL

#example)
svn export https://github.com/rasbt/python-machine-learning-book-3rd-edition/tree/master/ch13/cat_dog_images

※しかし、これでは、 「このURLは存在しません。」 とエラーが出る。
```

###エラー回避法
githubのURLの tree/master　をtrunkに書き換えるとできる。

```
svn export https://github.com/rasbt/python-machine-learning-book-3rd-edition/trunk/ch13/cat_dog_images
```

＊＊＊
###参考

[subversionの使い方](https://qiita.com/mountcedar/items/e756bb9136e3b1722bb2)
[githubから抽出ダウンロード](https://blog.goediy.com/?p=910)
マテリアルズインフォマティクス旅行記　１　環境構築

マテリアルズインフォマティクス（以下MI）をするにせよ何にせよ、まずは環境構築をしなければいけません。
環境構築というのはつまり、MIをするうえで使うpythonなどの道具を用意して使えるようにすることです。

この環境構築をする際に便利なのがAnacondaというツールです。Anacondaを使えば簡単にpythonなどの必要な道具をまとめてインストール、つまり自分のパソコンに用意することが出来ます。（Anacondaを使う利点は環境の切り替えが簡単にできるなどいろいろありますが初めての人はあまり気にしないでください）

とにかく、
1. anacondaというツールをインストール
2. anacondaを使って簡単に必要な道具をまとめてインストール
をすれば、すぐにMIを始める上で必要な準備ができます！

「1. anacondaというツールをインストール」はQiitaやyoutubeなど様々な場所でやり方が説明されているので割愛します。
今回はMIに必要な道具をそろえる「2. anacondaを使って簡単に必要な道具をまとめてインストール」の部分を説明します。

※わたしのパソコンはWindowsなので、windowsの場合での説明になります。

---
anacondaをインストールできたら、コマンドプロンプトを開き、以下を打ち込みます。
（>>>の後は、出力結果を表しています）


```
conda --version
>>> conda 4.10.1
```
このように出力されたら、anacondaは正常にインストールされています（数字はanacondaのバージョンです。人によって異なります。）

では早速MIの環境構築をしていきましょう！
以下を打ち込んでください

```
conda create -c rdkit -n mi-project python=3.7 rdkit
```
次にごちゃごちゃ出てきて、

```
Proceed ([y]/n)?
```
と出るので、yと入力してエンターです。

するとまたごちゃごちゃしたものが出てきます。これは実はいろんな道具をインストールしている最中だよ、と言っています。上のコードを打ち込んだだけで、まとめていろんな道具を用意してくれる＝環境構築してくれているんですね！

しばらく待つとインストールが終わりますので、以下を打ち込んでください。

```
conda info -e
>>>
base                  *  C:~\Anaconda3
mi-project               C:~\Anaconda3\envs\mi-project
```

こんな感じでmi-projectの文字が見えるかと思います。後ろのC:~\...はわからなければあまり気にしないでください。
これでMIのための環境ができました！
あとは、MIがしたいときは、「今からこのmi-projectという名前の環境で作業するよ」とパソコンに教えてあげれば、いつでもMIができます。どうやって教えてあげるかというと、

```
conda activate mi-project
```
と打ち込むだけです。すると、

```
C:\Users\~>
```
みたいだったのが、

```
(mi-project) C:\Users\~>
```
みたいになると思います。これで、先ほどいろいろインストールした道具が使えるようになります。


以上で環境構築編を終わります。今の段階では「いやこれは一応できたけどだから何？」な人もいると思います。次回から早速この環境を使ってMIをやってみようと思います。

ここまで読んでいただきありがとうございました。
yukicoder contest 304 参戦記

# yukicoder contest 304 参戦記

## [A 1603 Manhattan Social Distance](https://yukicoder.me/problems/no/1603)

*N*=2だと(1, 1) と (H, W) に置くのが最大だなあとなり、*N*=3だと3個目はやっぱり (1, 1) か (H, W) に置くよなあの辺りで、(1, 1) と (H, W) に交互に置けばいいのかと分かる,

```python
N, H, W = map(int, input().split())

print((H + W - 2) * ((N + 1) // 2 * N // 2))
```

## [B 1604 Swap Sort:ONE](https://yukicoder.me/problems/no/1604)

答えは転倒数(蟻本では反転数)なので、過去のコードを貼る.

```python
class BinaryIndexedTree:
    def __init__(self, size):
        self._data = [0] * size

    def add(self, i, x):
        data = self._data
        i += 1
        n = len(data)
        while i <= n:
            data[i - 1] += x
            i += i & -i

    def _sum(self, stop):
        data = self._data
        result = 0
        i = stop
        while i > 0:
            result += data[i - 1]
            i -= i & -i
        return result

    def range_sum(self, start, stop):
        return self._sum(stop) - self._sum(start)


N, *P = map(int, open(0).read().split())

bit = BinaryIndexedTree(N + 1)

result = 0
for x in P:
    result += bit.range_sum(x + 1, N + 1)
    bit.add(x, 1)
print(result)
```
【これで合格！】統計検定2級の勉強ノート

## はじめに
統計検定2級のための勉強ノートを紹介します。勉強方法全般については[こちら](https://qiita.com/oki_kosuke/items/e06bb2e5c06875155652)を参照下さい。なお、以下の内容は[統計WEB](https://bellcurve.jp/statistics/course/)の初級編と基礎編をまとめたものです。

## 勉強ノート
まずは初級編のまとめノートです。基礎的な事項ばかりですね。

![syokyuu1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/7f1174b9-4acd-d29a-791d-b8d93ae9a26f.png)

![syokyuu1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/1b224f39-d530-7e99-ea7b-62c5312f9da5.png)

次に基礎編です。この内容までマスターできれば統計検定2級はばっちりです。
![kiso1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/ff13a1b1-e318-d762-ec90-3fffd9e70a4c.png)

<br>
![kiso1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/36cba4b9-bf1d-747a-d0b8-b0ed540bf9bf.png)
歪度や尖度は過去問でもたまに出題されています。確実に得点したい内容です。

<br>
![kiso2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/a19462f2-ef1e-dfc4-c488-1d6a744b0302.png)
最後の分散の公式は重要です。

<br>
![kiso2-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/3004af28-60d7-e0f0-3a5c-e8d8afa841dd.png)
「二項分布」、「幾何分布」、後述する「指数分布」の違いはしっかりとおさえたいです。

<br>
![kiso3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/0630b0f8-c00c-b956-8981-a133933ac1a4.png)

<br>
![kiso3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/9c9cbed1-5253-5e71-7cfa-9541a53da658.png)
「母集団」と「標本」の関係性は重要です。標本の抽出方法も過去問では頻出です。

<br>
![kiso4-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/1b9e5eea-d29a-8eed-0258-ad9c9a433766.png)
ここから出てくる検定量の理解は必須です。

<br>
![kiso4-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/304b9e3d-2ce0-72a3-5b00-2eba5cc8554d.png)
第1種の過誤や検出力についてもしっかりと理解したい範囲です。

<br>
![kiso5-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/d524723b-a932-d773-d389-dbdc09b9c437.png)

<br>
![kiso5-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/dddce1fd-a77e-623b-1ce7-1b9257595813.png)
<追加分>は過去問を解いていて足りなかった知識をまとめています。

<br>
![kiso6-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/ab11146e-69ff-b5e6-22bd-9a0fc548db80.png)

<br>
![kiso6-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/501cf9f6-9e34-e221-ba94-08784e19c831.png)
独立性の検定も過去問で出題があり、要注意です。

<br>
![kiso7-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057114/0deeedb1-1517-67c0-70d5-834c33aaa183.png)
一元配置、二元配置の分散分析は確実に得点したい内容です。自由度や自由度やF値の算出も自分の手を動かしてマスターしたいです。

## まとめ
統計検定2級の勉強に用いたノートを紹介しました。時間はかかりますが、やはり自分の手を動かしてまとめることで内容の定着度が上がった気がします。
Gmailのフィルタをスプレッドシートで管理する

# はじめに
こんにちは。暑い日が続きますね、水分補給が止まりません、筆者です :innocent: 

さて、今回は、以下記事で作成したGmailのラベル管理が面倒になってきたので、スプレッドシートで管理できるようにしていこうと思います。

https://qiita.com/akitkat/items/f4070b81d85af2f9a354

ちなみに今こんなカオスな状態になっております... 笑 :innocent: 
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/aef87333-180c-e529-ef6f-88e91a08a3a2.png)

# Gmail APIの有効化

使用するGAS内で上記で追加した`Gmail API`を追加をします。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/edfdff7a-9050-9c68-211e-fff4ac470dd5.png)

# 編集対象のフィルタのIDを検索する
編集対象のフィルタIDを探します。
以下スクリプト実行でログに出るので、対象のフィルタのIDを取得して下さい :pray:

```js
const showFilterList = () => {
  console.log(Gmail.Users.Settings.Filters.list('me'))
}
```

# スプレッドシートはこんな感じ

| No. | from | filterId|
|:-:|:-:|:-:|
| 1 | no-reply@mercari.jp | 先ほど取得したfilter_id |
| 2 | inquiry@share.timescar.jp |   |
| 3 | jmbnews@jalmail.jal.com |   |
| 4 | fx-info@invast.jp |   |
| 5 | news@epark.jp |   |

スクリーンショットはこちら↓

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/dc2cb0f4-e07f-0f8f-6ea4-d7b11dee43b9.png)

# スクリプトを作成

```js
const main = () => {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('フィルタ__過去30日で削除')
  const filterId = sheet.getRange('C2').getValue()
  const filter = Gmail.Users.Settings.Filters.get('me', filterId)
  const froms = sheet
    .getRange('B2:B')
    .getValues()
    .map(v => v[0])
    .join(' ')

  // フィルタ情報を生成.
  const parameters = {
    criteria: filter.criteria,
    action: filter.action,
  }
  parameters.criteria.query = `from:({${froms}})`

  // フィルタ作成.
  const res = Gmail.Users.Settings.Filters.create(parameters, 'me')

  if (res) {
    // 新規フィルタIDをスプレッドシートに反映.
    sheet.getRange('C2').setValue(res.id)

    // 旧フィルタを削除.
    Gmail.Users.Settings.Filters.remove('me', filterId)
  }
}
```

# おわりに
これで何か会員登録とかした際に、スプレッドシートでメールアドレスを管理できるのが非常に楽になります :v:

今まで超めんどかったので...。
現在設定されているフィルタ取ってきて、そこに追加したいメールアドレスをスペース区切りで追加していくとか、使い勝手が... :sob:

どなたかの参考になれば幸いです！
それでは！
Python 3.9 で class property を作る

Python 3.9 から `@classmethod` と `@property` の重ねがけができるようになった事に気づきました。

>バージョン 3.9 で変更: Class methods can now wrap other descriptors such as property().
>https://docs.python.org/ja/3.9/library/functions.html#classmethod

ということで、早速実験してみました。

```python
>>> class Foo:
...     @classmethod
...     @property
...     def prop(self):
...         print('Hello class property!')
...         return "hello"
```

こういうクラスを作っておいて、クラス属性 `prop` を呼び出すと、メソッドが呼び出され、値が返ります。

```python
>>> Foo.prop
Hello class property!
'hello'
```

ちなみに、インスタンス化したあともプロパティとして動作します。

```python
>>> Foo().prop
Hello class property!
'hello'
```

これまであまり class property を作ろうと思ったことがなかったのですが、面白い使いみちがないか考えてみようと思います。
StravaのAPIでPayment Requiredが発生する原因

# Strava::Errors::Fault (Payment Required)
どうやら課金ユーザーでないと情報を取得できないようなので
あらかじめユーザー情報を取得した際に有料会員かどうかのフラグをチェックして表示する項目を設定する必要がある。

Stravaの課金機能と同等のものを作らせないようにする仕組みなのだと思った
よく出来てる


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69647/9d4cda6c-cb7a-6ffe-a49f-54a592bce029.png)
JavaScript ファイルの分割

#ファイルの分割

コードの量が増えてくると1つのファイルで管理するのが大変になるので、
複数のファイルでコードを管理することがあります。

そして、複数のファイルを関連付けし、必要な値を渡す必要があります。

渡す方法がこちらです。

まず、クラスを渡す側の記述。
export default クラス名;
これをクラスの定義部分の後ろに置くことにより、そのクラスをエクスポート（出力)し、
他のファイルへ渡すことができます。

次にクラスを受け取る側の記述。
クラスを受け取る、つまり読み込み（インポート）をします。

ファイルの先頭で、import クラス名 from "./ファイル名";を書きます。
このファイル名の.jsは省略できます。

インポートやエクスポートするのはクラスだけではなく、
変数や定数もできます。書き方は同じです。

#デフォルトエクスポート

export defaultはデフォルトエクスポートと呼ばれ、default export 値で
読み込まれます。なので、エクスポートの名前とインポートの名前が違っても問題ありません。
しかし、1つのファイルで1つしか使うことができません。
2つの値をエクスポートする時は以下で記述する名前付きエクスポートを使う必要があります。

#名前付きエクスポート

名前付きエクスポートをする時は、　export {名前}; import {値の名前} from "./ファイル名";
を使います。
2つの値をする時は名前1,名前2を使いましょう。

#相対パス

ディレクトリの構成を考えてみましょう。

例えば、 ./A/Bだと
./A/は同じディレクトリ内のAに移動する。
そして、その後のBを指定します。

../だと一つ上の階層に移動します。


#パッケージ

JavaScriptでは他の誰かが作ったプログラムを組み込むことができます。
このプログラムをパッケージと言います。

例えば、chalkだとコンソールの出力の文字に色を付けることができます。
また、readline-syncはコンソールに値を入力できます。

import 定数名 from "パッケージ名";これを使い、インポートします。

readline-syncを文字列を使う時はreadlineSync.question（質問文)の様に記述して下さい。
しかし、整数を使う時はreadlineSync.questionInt(質問文)を使うようにして下さい。

#最後に

初心者ですので、拙い文章や書き方だと思いますが、最後まで見て頂き
ありがとうございました。もし、ご指摘等がございましたらよろしくお願い致します。
Datadog RUM（Real User Monitoring）を使う

# RUM（Real User Monitoring）って何？
Datadogは、従来型IT（サーバーHW）の監視だけでは無く、クラウドPaaSやWEBサービスも監視できる監視ソリューション（SaaS）ですが、WEBサイトを訪問するユーザ数、アクセスしたユーザのデバイスタイプ、OS種類、セッション時間、ページビューなどを分析することができる。つまり、Google Analytics の様なもの。公式サイトによると出来る事は

- ブラウザとモバイルの性能（を可視化）
- レンダリングのボトルネック（を見つける）
- エラー、リソース、バックエンド要求の収集（を可視化）

### なぜGoogle Analyticsじゃなくて、Datadogを使うの？
分析できる機能は圧倒的にGoogleの方が多い/日本語対応/GUIが見やすいのだが、Datadog RUMを使えばインフラ監視、アプリ性能モニタ、ユーザインタラクション（相互作用、交互作用）を**ひとつのツールで**それぞれのメトリクスを**関連付けて**可視化と分析ができる。

## 百聞は一見に如かず。なので試してみる。
WEBアプリは、バックエンドFirebase＋フロントエンドJavaScriptで構成。

### 例えば、ユーザセッション可視化
うーん；アクセス数が少ないのでデモには物足りないけれど、WEBサイトのアクセス状況を可視化できた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/1138379e-ef6c-8173-49dd-2ef1a4e6d68f.png)

### 例えば、ページをロードする応答時間
あれ？；これってAPMじゃなかったっけ？　あぁそうか、クライアントPC/mobile側のユーザーと同じ視点での可視化か。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/f60aaa1c-c958-6659-57ab-2d31fb8d83bc.png)

## セットアップの流れ
スクリプトコードに scriptタグ を追加できるなら、30分もかからず検査までできる。

### １）Datadogポータルで、アプリに埋め込むコードを生成する
［UX Monitoring］→［RUM Applications］→［+ New Application］
下図では①で[JS]JavaScriptを選んでアプリ名を入力、②でDatadog SDKの読み込みをCDN指定した場合の、アプリに組み込むコードが生成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/8e60fb7b-f4a2-31f0-12d2-a32685a5ff54.png)

### ２）WEBアプリにコードを追加する
Headタグ部分に、１）で生成したコートを追加してWEBサーバーにアプリをデプロイする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/9d921c34-ecfe-9ac6-b2ae-825fca8079e4.png)

### ３）WEBアプリに１回アクセスする
デプロイしたWEBアプリを実行すると、RUMが有効に機能していることを検証してくれる［waiting for data ...］が、成功すると［Data is reporting successfully!］に変わる。よかった成功した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/3c388b20-66a1-6d7a-0c71-f6b86aab5a87.png)


### ４）Datadogポータルで可視化する
［UX Monitoring］→［RUM Applications］→［Session］
お。ユーザーがログインしたとか、エラーとか、ダウンロードしたとか、操作履歴まで表示しちゃうのか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189936/a37ceab3-9dc4-89cb-357a-19c1a0724da2.png)

## まとめ
Datadog 監視ソリューションを使っているなら、セットアップが簡単で、ひとつのツールでWEBアプリを使うユーザー分析もできることが分かった。インフラ監視、アプリ性能モニタに加えて、Google Analytics も一緒にどうぞ、という提案をしようと思う。
Google Apps ScriptでGmailを自動掃除

[Google Apps Script](https://script.google.com/) でGmailに溜まったメールを掃除する方法

## ■用途

* メルマガに登録している場合、指定期間だけ残してからゴミ箱に移動  

## ■設定の流れ

1. URLにアクセスを行い、「新しいプロジェクト」を押下  
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237396/06adacb0-99af-911f-9380-129d855d584f.jpeg)
2. ファイルを追加(Gmail.gs)＆リネーム(main.gs)を行います  
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237396/ffdf8508-bf50-59b9-fae2-00ae698f8dff.jpeg)
3. 掃除を行うためのScriptを記述して保存します
4. main.gsを選択し、試しに記述した処理を実行します
5. 問題がなければ、トリガー画面に遷移します  
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237396/7e985aed-fcbf-d0e0-ec98-ecb868b10471.jpeg)
6. トリガー設定を保存します  
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1237396/c2041225-38cd-c8e1-bd53-473f7b0880fa.jpeg)

## ■「3」のコードについて

ゴミ箱に入れるだけなら「Gmail.gs」は特に触る必要は割りません。
「main.gs」を自身の環境に合わせて修正する必要があります。


```javascript
// Gmail.gs
/**
 * Gmail関連
 */
class Gmail {
  /**
   * 指定ラベルのデータが指定日過ぎた場合にゴミ箱移動
   *
   * @param {string} label 対象のラベル名
   * @param {int}    day   経過日数
   */
  cleanupByLabelAndDay(label, day) {
    const threads = GmailApp.search('older_than:' + day + 'd -is:starred label:' + label);
    for (let i = 0; i < threads.length; i++) {
      threads[i].moveToTrash();
    }
  }
}
```

```javascript
// main.gs
/**
 * Gmailのクリーンアップ
 */
function cleanupGmail() {
  const obj = new Gmail();
  // 「ラベル名」が365日経過したらゴミ箱に移動
  obj.cleanupByLabelAndDay('ラベル名', 365);
}
```
macOSでUSBメモリに書き込むプログラムを作る

#はじめに
普通にやると書き込めなかったのでメモ。
今回はSwiftUIで作ったが、多分他でもいける。

#entitlements の設定
<project名>.entitlements の項目ができているはず。これの変更が必要。
まず、App Sandbox をNOにする。YESだと書き込み先がSandboxになるらしい。
次に com.apple.security.files.user-selected.read-write を追加、TypeはBoolean, Valueは 1
上に　com.apple.security.files.user-selected.read-only があるので、こちらは一応 0 にしておく。

#実際の書き込み
ここまで来たら普通に書ける。

```
let fileman = FileManager.default
fileman.createFile(atPath: <USBメモリなどのパスを含めたファイル名>, contents: nil, attribytes: nil)
let file = FileHandle(forWritingAtPath: <上で作ったファイル名>)
if (nil == file) {
    // エラー処理
}
else {
    file?.write(<書き込みデータ>)
    file?.closeFile()
}
```

#動かすと
初回実行時にはリムーバブルメディアの許可を求める表示があって、許可すると書き込みできる。
Laravelのマイグレーションを理解しよう

#環境
PHP 7.3.24
Laravel 6.20.30
MAMP

#migration(マイグレーション)とは？
マイグレーションとはDBのテーブルの履歴を管理するlaravelの機能です。
テーブルの追加や削除、カラムの追加や削除などをした際にその履歴が分かるような仕組みになっています。
`php artisan migrate`コマンドを実行することで、SQL文を書かなくてもDBの変更や作成等が可能です。

#マイグレーションファイルの作成

`php artisan make:migration マイグレーションファイル名`
を実行することで、マイグレーションファイルを作成することができます。
マイグレーションファイルは`database /migrations`ディレクトリの中に作られます。
migrationsディレクトリ内には、デフォルトでいくつかのマイグレーションファイルがすでに作成されています。

【補足】
マイグレーションの実行コマンドは`php artisan migrate`ですが、
マイグレーションファイルの作成コマンドは`make:migrate`ではなく`make:migration`
となるので混同しないように注意！
（makeは動詞なので、そのあとに動詞であるmigrateがくるのは英文法的にもおかしいですよね）

#テーブル追加のマイグレーションファイルを作成してみる
今回はtestsテーブルを作成していきます。
<font color="red">※テーブル名は複数形</font>
ターミナルでLaravelプロジェクトに移動した後
`php artisan make:migration create_tests_table`
を実行します。

そして`database/migrations`ディレクトリの中に`2021_07_17_103246_create_tests_table.php`が作成されているので中を確認します。

```php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTestsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tests', function (Blueprint $table) {
            $table->bigIncrements('id'); 
            $table->timestamps(); 
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('tests');
    }
}

```
###upメソッド
upメソッドはマイグレーションを実行する際に呼び出される関数です。
laravel初心者のため難しいところは一旦おいといて、重要の箇所のみまとめていきます！

```php
 $table->bigIncrements('id'); 
 $table->timestamps(); 

// bigIncrements・・・莫大な数までを格納できる数値の型
// timestamps・・・自動でデータの作成日時(created_at）と更新日時(updated_at)を作成する型
```
upメソッド内のこの記述でidカラム、created_atカラム、updated_atカラムが作成されています。
これらのカラムはよく使うことが多いので、Laravelがデフォルトで作成してくれます。
他にも自分でカラムを追加したい場合はここに追記していきます。

###downメソッド
downメソッドはマイグレーション実行後に「やっぱりマイグレーション前の状態に戻したいなあ…」となったときに使うメソッドです。（この処理をロールバックと言います）
そのため、マイグレーション実行時にはdownメソッドは使われることはありません。

今の段階では、まだ何もマイグレーションファイルをいじっていないので
・testsテーブルの作成
・デフォルトのカラムを追加(id, created_at, updated_at)
だけをしている状態です。

この場合のマイグレーションを戻す処理は
・testsテーブルの削除
のみになります。

なぜなら<font color="red">今回は「テーブルを作成」したので、ロールバックの処理としては「テーブルを削除」するから</font>です。
テーブルを削除すればカラムも消えるのでわざわざカラムを削除する記述はいらないってことですね。

```php 
public function down()
    {
        Schema::dropIfExists('tests');
    }
```

#マイグレーションの実行
マイグレーションファイルを作成しただけではDBには反映されません。
`php artisan migrate`というコマンドを実行して初めてDBに反映されます。

```
$ php artisan make:migration create_tests_table
Created Migration: 2021_07_17_151343_create_tests_table
```

#参考
[てくてくテック 【Laravel】migrationを理解しよう！](https://tektektech.com/laravel-migration/)
2.11(標準) 確率母関数 (方針で確率母関数を解説)

## 方針

前半のkと後半のkの意味が違うっぽい．略解見る限り，問題文は

---

```math
f_X(x)=\frac{1}{2^{x+1}},\ \ x=0,1,...
```
が確率関数になることを示せ．この分布の確率母関数と積率母関数を求め，正の整数kに対して

```math
\mathbb{E}_{X\sim f_X}[X(X-1)...(X-k+1)]
```

を求めよ．

---

の方がわかりやすいと思う．

この問題のメインは離散確率変数に対して定義される確率母関数．離散確率変数Xに対し，確率母関数G_Xとは，

```math
G_X(s)=\mathbb{E}_{X\sim f_X}[s^X]
```

という，定数sについての関数である．これを微分し，s＝1を代入したものはXの期待値である．

```math
\begin{align}
\left.\frac{d}{ds}G_X(s)\right|_{s=1}&= \left.\frac{d}{ds}\mathbb{E}_{X\sim f_X}[s^X]\right|_{s=1}\\
&= \left.\frac{d}{ds}\sum_xs^xf_X(x)\right|_{s=1}\\
&= \left.\sum_xxs^{x-1}f_X(x)\right|_{s=1}\\
&= \sum_xxf_X(x)\\
&= \mathbb{E}_{X\sim f_X}[X]
\end{align}
```

同様に，これをk階微分し，s=1を代入したものはXのk次階乗モーメントである．

```math
\begin{align}
\left.\frac{d^k}{ds^k}G_X(s)\right|_{s=1}&= \left.\frac{d^k}{ds^k}\mathbb{E}_{X\sim f_X}[s^X]\right|_{s=1}\\
&= \left.\frac{d^k}{ds^k}\sum_xs^xf_X(x)\right|_{s=1}\\
&= \left.\sum_x x(x-1)...(x-k+1)s^{x-k}f_X(x)\right|_{s=1}\\
&= \left.\sum_x x(x-1)...(x-k+1)s^{x-k}f_X(x)\right|_{s=1}\\
&= \sum_x x(x-1)...(x-k+1)f_X(x)\\
&= \mathbb{E}_{X\sim f_X}[X(X-1)...(X-k+1)]
\end{align}
```

## 答案

任意のx=0,1,...に対し，f_X(x)=>0が成り立つ．また，

```math
\sum_{x=0}^\infty f_X(x)=\frac{1/2}{1-1/2}=1
```

より，fは確率関数の条件を満たす．確率関数fに従う確率変数Xの積率母関数は，

```math
\begin{align}
M_X(t)&= \mathbb{E}_{X\sim f_X}[e^{tX}]\\
&= \sum_{x=0}^\infty \frac{e^{tx}}{2^{x+1}}\\
&= \sum_{x=0}^\infty\frac{1}{2}(\frac{e^t}{2})^x\\
&= \frac{1/2}{1-e^t/2}\\
&= \frac{1}{2-e^t}
\end{align}
```

また，Xの確率母関数は，

```math
\begin{align}
G_X(s)&= \mathbb{E}_{X\sim f_X}[s^X]\\
&= \sum_{x=0}^\infty \frac{s^x}{2^{x+1}}\\
&= \sum_{x=0}^\infty\frac{1}{2}(\frac{s}{2})^x\\
&= \frac{1/2}{1-s/2}\\
&= \frac{1}{2-s}
\end{align}
```

確率母関数G_Xより，Xのk次階乗モーメントを求める．

```math
\begin{align}
\frac{d}{ds}G_X(s)&= \frac{1}{(2-s)^2}\\
\frac{d^2}{ds^2}G_X(s)&= \frac{2(2-s)}{(2-s)^4}=\frac{2}{(2-s)^3}\\
\frac{d^3}{ds^3}G_X(s)&= \frac{3(2-s)^2\times 2}{(2-s)^6}=\frac{3!}{(2-s)^4}\\
\frac{d^4}{ds^4}G_X(s)&= \frac{4(2-s)^3\times 3!}{(2-s)^8}=\frac{4!}{(2-s)^5}\\
&\vdots\\
\frac{d^k}{ds^k}G_X(s)&= \frac{k!}{(2-s)^{k+1}}
\end{align}
```

従って，

```math
\mathbb{E}[X(X-1)...(X-k+1)]=\left.\frac{d^k}{ds^k}G_X(s)\right|_{s=1}=k!
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
QGIS 3.20 で変わったこと

# QGIS 3.20 Odense

いつのまにか QGIS 2.x の最後のバージョンである QGIS 2.18 のマイナーバージョンを越えましたね。

さて QGIS 3.20 から少し変わったことがあります。少し検索しましたが英語も含めほとんど情報がみつからなかったので簡単にですが説明しておきます。

なお、機能に関してはの話ではありません。機能面については [Visual Changelog](https://qgis.org/en/site/forusers/visualchangelog320/) を参照してください。

## Release Candidate

![splash](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215290/f4a235f0-a423-31ac-f608-8e0210d6f41e.png)

[スプラッシュ画像](https://github.com/qgis/QGIS/blob/final-3_20_0/images/splash/splash.png)にもあるように現時点でリリースされている 3.20.0 は RC 版（ Release Candidate; リリース候補版）となっています。

あまりちゃんと広報はされていないようですが、 3.20 から X.YY.0 はリリース候補版という位置付けで、開発版というわけではないですが広く問題点や意見などのフィードバックを受け付けるバージョンとし、本格的なリリースは X.YY.1 からとするようです。

詳しくは下記メーリングリストの投稿を参照。

* [\[Qgis-psc\] Release Cycle update](https://lists.osgeo.org/pipermail/qgis-psc/2021-March/009296.html)

## インストーラがでっかくなったよ

QGIS 3.20 から Proj に Proj8 がパッケージされたほか、 [Proj-data](https://github.com/OSGeo/PROJ-data) も一緒に同梱されるようになりました。 PROJ-data だけでも 500 MB あります。

Proj は座標変換を行うライブラリですが、統一的な計算式で変換できない局地的なパラメータのデータで、日本でいえば国土地理院が公開している[日本のジオイド2011](https://fgd.gsi.go.jp/download/geoid.php)が含まれています。（[測量法に基づく許諾は取得されています](https://github.com/OSGeo/PROJ-data/tree/master/jp_gsi)。）

このデータは高精度のジオイド高データであり、楕円体高から高精度な標高値を求める際に使用されます。すなわち [EPSG:6667 - JGD2011 (latitude, longitude, ellipsoidal height)](https://epsg.io/6667) から [EPSG:6697 - JGD2011 (latitude, longitude, vertical height)](https://epsg.io/6697) に変換できます。

詳しくは [PROJ 7.2 の標高変換](https://qiita.com/tohka383/items/e8392db87359e384a91e)をご覧ください。

とはいえ GNSS 測位の座標処理のためユーティリティとしての Proj を使うならまだしも、 QGIS でどのくらい使うかというと疑問です。もしかしたら今後分離されるようなこともあるかもしれません。

## OSGeo4W （ Windows 版ネットワークインストーラ）

従来 testing と呼ばれていたリポジトリがデフォルトになりました。

詳しくはダウンロードページをみてください。
Google Playに新規アプリをリリースするときのメモ

#　初めに
新規アプリをリリースするときに少し躓いた点をメモ。

# Key Store
新しくKey Storeを作成する際、エラーが出た。
![スクリーンショット 2021-07-17 15.53.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/baa70b1f-d03b-a5dd-013d-4562a9821ef2.png)

## 解決策1
私の場合、Key storeのパスワードとAliasのパスワードを同じにしたらエラーが出なくなった。

## 解決策2
ターミナルからKey Storeを作成したらエラーは出なかった。

```
keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias
```

(validityは余裕を持って100000に変更)
参考：https://developer.android.com/studio/build/building-cmdline?hl=ja

# 難読化
Google Play Consoleにaabファイルをアップロードした際、難読化していると警告が発生。
そのため、難読化解除のため、build.gradle(:app)を変更。

```build.gradle
	buildTypes {
		release {
			minifyEnabled true
			shrinkResources true
			proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
		}
	}
```
これでapp/build/outputs/mapping/release/mapping.txtが作成される。
このファイルをGoogle Play ConsoleのApp Bundle エクスプローラ→ダウンロードタブ→ReTraceマッピングファイルにアップロードすれば良い。
参考：https://codeforfun.jp/android-studio-path-to-mapping-txt-and-upload/
Google Colaboratoryについて

#Google Colaboratoryとは何か

Google Colaboratoryとは，環境構築なしでpythonのコードを書いたり，実行したりことができるGoogleのサービスです．
Anacondaやローカルに環境構築するやり方がわからず困っている人，すぐにpythonを触ってみたい人におすすめです．

#まずは動かそう！
Googleのサービスになるので，Googleのアカウントが必要です．持ってない人は，アカウントを作りログインしておきましょう．
次に[Google Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja"Google Colaboratory")にアクセスしましょう．
アクセスすると以下の画面になると思います．

![スクリーンショット 2021-07-17 10.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/46a13d70-b9f3-b577-996c-daf6a406aa4a.png)


次に左上の「ファイル」メニューから「新規作成」を選択しましょう．
すると以下の画面になると思います．
Untitled.ipynbはファイル名になります．選択すると名前変更することができます．

![スクリーンショット 2021-07-17 10.12.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/af239d66-fbb0-33b5-061d-5ac5aeb4fb7b.png)

この画面の灰色の部分がセルと呼ばれるコードを書く場所になります．

![スクリーンショット 2021-07-17 10.35.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/6fa5b008-d2a9-6ff1-2fa0-2410793b915a.png)

このようにコードを分けて書くことができます．
関数名は一緒で，違うコードを試してみたい場合などで非常に便利です．また，エラーがどこで起きているのかすぐにわかります！
実行するときは，セルの再生ボタンを押すか，Ctrl+Enter(Mac→⌘+Enter)で実行することができます．
セルを増やしたいときは，次のセルがない場合，実行すると自動でセルが出てきます．また，コードという部分を選択することでもセルを増やすことができます．
テキストを選択することで，Markdown形式でドキュメントを書くことができます．

![スクリーンショット 2021-07-17 10.35.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/cc2b1c27-466e-d51e-3216-1239ed35c0c4.png)


セルが多くなった場合に全て実行したいとき，一つ一つ実行するのではなく，「ランタイム」→「全てのセルを実行」をするのが簡単です．
![スクリーンショット 2021-07-17 10.29.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/130addae-7d5c-b2c3-0afd-6f3f7ec02a3c.png)

#Google Colaboratoryを扱う上で気をつけるべきこと
Google Colaboratoryは，IPython,Jupyter形式でコードを書くことができます．
この形式では，変数の状態が保持されるので変数に何が入っているかわかりにくい場合があります．

例えば，

```python:Untitled.ipynb
a = 1
b = 2
print(a+b)
>>>3
```

となりますが，このセルを実行した後に，以下のコードを書き換えて実行をすると


```python:Untitled.ipynb
b = 2
print(a+b)
>>>3
```
となります．Python形式(.py)ファイルにコードを書き上記の流れを行うと，NameError: name 'a' is not definedとaという変数に値がないというエラーが表示されます．
Ipython形式(ipynb)ファイルでは，a=1が一度実行されるとその値が保持されているため，エラーが出ずに結果(3)と出てしまいます．
そのため一度実行した変数は保持されてしまうということは覚えておきましょう．
また，Python形式(.py)ファイルでは上から順にコードが実行されますが，Ipython形式(ipynb)ファイルでは，好きなセルを任意の順番で実行することができます．
しかし，セルが多い場合，途中で記述した「全てのセルを実行」を行うことが一般的なので，上から順に実行したときにNameError: name 'a' is not definedのようなエラーが出ないように注意しましょう．

#Google Driveとの連携の仕方
冒頭でも記述したように，Google ColaboratoryはGoogleのサービスです．
そのため，Google Driveと連携させることができます．
まず以下のコードを実行してみてください．

```python:Untitled.ipynb
from google.colab import drive
drive.mount('/content/drive')
```
このコードを実行すると，認証キーが要求されるので表示されるURLから認証キーを取得してコピー＆ペーストします。認証を終えると /content/drive にGoogle Driveがマウントされているので、以下のように ls コマンドで確認すると自分のGoogle Driveのファイルが見られるはずです。

```python:Untitled.ipynb
! ls "/content/drive/My Drive"
```
また，ナビゲーションバーからも確認することができます．
![スクリーンショット 2021-07-17 16.00.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340659/2d826129-df02-3746-81b3-44457725d2fc.png)

#まとめ
このようにGoogle Colaboratoryは，Pythonの環境構築を行わなくてもPythonを使うことができます．
また，Google Driveと連携することができるため，ソースコードはクラウド管理にすることができます．そのため，チーム内で情報共有に活用することができます．
少しPythonを触ってみたい人，プログラミング初心者の方にはおすすめの実行環境ですので，活用しましょう！
ADX2スクリプトで16bit44100Hzに変換

#はじめに
前回[原音再生](https://qiita.com/tatmos/items/86cadb3c3b4daa5ca9fb)をやってみたのですが、
どうもPyAudioだと32bitFloat波形が読めないようなので、
選択中のマテリアルを16bit44100Hzにすることで対処した。

環境:CRI AotmCraft 3.45.00

#説明
変換したいマテリアルをツリーで選択し、スクリプトを実行する。
あらかじめffmpegのインストールが必要かもです。（自分の環境では入れていたので未確認）

破壊的な操作なので中間ファイル(_bak)など
万が一の時のために生成していますが、不要なら削除してください。
（無いように書くこともできるけど、元波形が失われる操作なので注意）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/c760f820-b1d0-6ca8-e8c8-4968c4f86e78.png)
プログラムで消すと後で戻せないから本当に要らなくなった時に手動で消すのが安全

#スクリプト
backup_folder のパスは適宜変えてください。

[ffmpeg-python](https://github.com/kkroening/ffmpeg-python)を使って
wav to wav変換しています。
（レートの指定も外したかったけど、外すと変なファイルができてしまうようでした）

```Conv16bit44100WAV.py
# --Description:[tatmos][Conv]マテリアルを16bit44100Hzに変換する
import ffmpeg
import shutil
import os
import cri.atomcraft.project as acproject
import cri.atomcraft.debug as acdebug

#元波形のコピー先
backup_folder = "C:/MyDearest/backup/"

selectedMaterials = acproject.get_selected_objects("Material")["data"]

if len(selectedMaterials) == 0:
    acdebug.warning("変換するマテリアルを選択してください。")
    sys.exit()

for selectedMaterial in selectedMaterials:
    input_path = acproject.get_value(selectedMaterial, "SrcFileAbsolutePath")["data"]

    print(input_path)
    print(src_path)

    #元ファイルをコピー（作業フォルダへコピー）
    src_path = backup_folder + os.path.basename(input_path)
    shutil.copyfile(input_path, src_path)

    #元ファイルリネーム(念のためその場にもバックアップファイル化）
    os.rename(input_path,input_path + "_bak")
    
	#16bit44100Hzに変換する
    stream = ffmpeg.input(src_path)
    stream = ffmpeg.output(stream, input_path, f='wav',ar=44100,acodec='pcm_s16le')
    ffmpeg.run(stream)
```
Cannot connect to the Docker daemonの一時対応方法

### 問題
`docker`コマンドを実行すると、下記のエラーが出ている：

```bash
~$ docker container list
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```
ネットで調べた方法で試したけど、解決出来なかった。

### 対応方法

新規ターミナルで`sudo dockerd`で実行したままの状態で、別のターミナルで`docker`コマンドを実行できるようになった。

### その後

何日後、Ubuntu 18.04が壊れて（startupでcrashして、進まなくなった。`Cannot start Network Manager`みたいなエラー）、再インストールした。またすぐUbuntu 20.04にupgradeした。
AWS（S3）の概要について

# はじめに
画像投稿機能をもつアプリケーションを公開する場合、多くのユーザーにたくさんの画像データを投稿されると思います。
それらの画像データを、大量かつ安全に保存できる仕組みを取り入れる必要があります。
外部のデータ保管サービスを利用して画像を保存するための事前知識を復習するために投稿します。

# データ保管サービスの利用
TwitterやFacebook等は、毎日ユーザーが写真や動画をアップロードしています。
そして、画像や動画などのデータはユーザーがいつでも見返すことができるように蓄積されます。
なので、サービス側はその大量のデータを安全にそして長期的に保存しておく必要があります。
例えば、自宅に荷物が置けない場合は、レンタル倉庫などを利用して別の場所に荷物を保管することがあります。
それと同様に、インターネットの世界でもオンライン上の倉庫のような仕組みを利用し、大量のデータを安全に長期的に保管しているのです。

# ストレージサービス
インターネット上でデータを保存する場所を提供するサービスのことです。
Herokuを利用してデプロイしている場合、ストレージサービスが必要になります。
なぜなら、ユーザーがアップロードした画像データは、アプリがデプロイ又は再起動（24時間に1回自動で行われる）される度に、消えてしまう仕様になっています。

# AWS （Amazon Web Services）
ストレージサービスには様々な種類がありますが、代表的な「AWS」が提供している「S3」というサービスがあります。
インターネット通販で有名な米Amazonが提供している、サーバーに関するサービスの総称です。
現在200種類以上の様々なサービスを提供しています。

# S3 （Amazon Simple Storage Service）
AWSが提供するサービスの一つです。
S3を利用することで、画像を保存したり、保存してある画像を取得したりすることができます。
保存されたデータは実在の施設に分散して保管されるため、ネットワーク障害に強い仕様になっています。
また、使用した分だけ課金されるシステムであるため、保存できるデータ容量やファイル数の上限がなく使用することができます。
AWSを使用する点で注意が必要なのは、使用容量によって料金が発生してしまうことです。
ただし、個人制作のアプリケーションで保存する画像データの量であれば、基本的に無料でS3を利用することができます。

# おわりに
これからAWSの知識を深めていく上で基礎的なことをしっかりと学び、投稿を続けたいと思います。
修正点などございましたらお手数ですがコメントいただけると幸いです。
よろしくお願いいたします。
ReduxToolkitが便利

# はじめに
ここでは、Redux Toolkitを使ってCRUD機能をもったアプリを作り終えたばかりの初学者の私が、Reduxに関しての理解をまとめてみる。細かい知識は学習過程なので、現時点ではざっくりとした理解になります。

## そもそもReduxとは
一言で言うと、state（状態）をグローバルに管理できるフレームワークの事。
Reactと相性が良いらしい。

## Redux Toolkitとは
Reduxは便利である反面、初期設定の際に自分で用意しなければならないものがとても多く参入障壁が大きなフレームワークでした。
しかし、Redux Toolkit（RTK）の登場によって、導入がとても簡単になりました。アプリの立ち上げ時点でテンプレートを用いてRTKを導入してしまえば、必要となる便利グッズが全部ぶち込まれます。これから学習する方はRTKを導入しましょう。

## Reduxのメリット（結論）
1. **redux-devtools-extentionが超便利**
1. **コードが見やすくなる**
1. **大きめのプロジェクトを管理しやすい**

### 1. redux-devtools-extentionが超便利（要インストール）
みなさんはアプリを作成している際に、ディベロッパーツールを開いてコンソール画面で頻繁にデータの確認をしますよね。それと全く同じノリです。
ディベロッパーツール上でredux-devtools-extentionを使って、状態の確認をすることができます。
例えばAPI通信してきたデータを、ステートに保管できたかどうかや、今のステートに変更を加えた際に変更が成立しているかを簡単に確認できます。
**Reduxを用いて作ったお天気アプリ**
![Screen Shot 2021-07-17 at 10.37.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825163/35e56aaa-ff4e-a262-e408-602e96ad0f8c.png)
右側で常にステートの状態を把握できる便利機能です。

### 2. コードが見やすくなる
Reduxでは、sliceという特殊なファイル内で状態や関数を管理します。

- 見た目を構成するファイル（UI）と、状態の変化やAPI通信などを表す関数を基本的にsliceという別ファイルに記述する為、それぞれのファイルに記述されるコードを少なくすることが出来ます。また、それによってファイルごとの役割が明確に分かれている為、ごちゃごちゃせずに把握しやすくなります。
- 上記のメリットによって、状態だけでなく動作を表す関数もグローバルに管理できるようになり、好きな箇所でいつでも呼び出すことができるようになります。（３に関係してくる）

### 3. 大きめのプロジェクトを管理しやすい
hooksだけで完結できる小さなアプリであれば、あまり特別な恩恵はありません。だた将来的にもっと大きなプロジェクトを開発する一員になったり、チームで開発する場合には、より威力を発揮してくる部分だと思います。
それでも好きな箇所でいつでも状態を参照したり、関数を呼び起こすことができるのはとても便利だと感じています。

## 頻出Redux用語 （ざっくり）
###slice###
状態や動作を表す関数をまとめる為のファイル

###store###
Reduxで管理している状態を保管する場所。

###reducer###
なにか状態に変更を加えたい場合の処理を記述する。基本的にアプリ内だけで完結する状態の変更（API通信はしない）

###createAsyncThunk / extraReducers###
この２つは基本的にセットとなります。
API通信を必要とする動作の関数をcreateAsyncThunkを使って記述。そして通信先とのやり取りの後にはそのデータを元にUIに結果を反映させなければいけないのでextraReducersでその後の処理を記述する。
CRUD機能全般の関数の作成はここで行われることになります。
ただ、これを使わなくてもasync/(axios)/awaitなどを用いた一般的な非同期処理でも書く事は可能です。その場合はextraReducersが使えないので、通信後の変更をUIに反映させるコードを別で書く必要があります。要は、「せっかくreduxを使っているなら非同期通信の際にはこれを使うと便利だよー」という認識です。

> [公式サイト](https://redux-toolkit.js.org/api/createAsyncThunk)
> [参考記事](https://future-architect.github.io/articles/20200429/)

細かい用語の解説などは他の記事に委ねます。


##最後に
使い方や状況によって状態管理はhooksを使ったほうが良い場合があるので、今後はhooksもきちんと学習して、上手な使い分けをできるようにしたい。
まだ学習段階ではありますが、少なくともCRUD機能をもった簡単なアプリをRedux Toolkitを使って３個ほど（TODOアプリ、お天気アプリ、ブログアプリ）作れるようになったので、一度記事にまとめてみました。
間違った認識がありましたら、ご指摘やアドバイスの方よろしくお願い致します。
【解決】PlatformIOのMinitermでANSIエスケープシーケンス制御できなかった件について


# PlatformIOのMinitermでANSIエスケープシーケンス制御できない？

ESP32やArduinoで遊んでいて、moniter（Miniterm）にエスケープシーケンス制御できないので、2時間ほどはまっていた。

ひょんなことから解決してしまった。そんなんしらんがなー。
同じ愚かなドハマリを他の人にしてほしくないので、メモ程度に書いておきます。

## PlatformIOのplatformio.iniで`monitor_filters`を設定してください。

これだけです。
monitor画面をよく見ると、書いとるがな。しらんがなー！！
賢明なあなたは、[`monitor_filters`](https://docs.platformio.org/en/latest/projectconf/section_env_monitor.html#monitor-filters)をGoogle先生にすぐに聞きに行ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103572/3efe1cc5-d7e3-4e90-8480-9af54511c303.png)


##　しらんがな

>--- Available filters and text transformations: colorize, debug, default, direct, hexlify, log2file, nocontrol, printable, send_on_enter, time

どうやら、次のフィルター設定があるようですねぇ。

- colorize
- debug
- default 
- direct
- hexlify 
- log2file 
- nocontrol 
- printable 
- send_on_enter 
- time

で、初期設定はdefaultになっているようです。なので、ANSIエスケープシーケンスの文字制御がMinitermでできていなかった。ということになります。しらんがな。

## かいけつ

### direct

次の設定をplatformio.iniへ追加してから、monitorをみてください。エスケープシーケンス制御が有効になっていると思います。
log2fileとtimeは要らなければ削除してください。

```
monitor_filters = log2file, time, direct
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103572/998092a5-4bd3-4ce0-4bed-1c833960aebb.png)

### default

`\033`や`\x1b`などは、「<sub>ESC</sub>」のようにmoniterに表示されて文字は制御されません。

```
monitor_filters = log2file, time, default
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103572/b0b66194-9d86-9df4-22b1-7fbae5ef0a12.png)

### debug

よくわかりませんが、送受信で何を送ったのかrawデータが見れるようです。

```
monitor_filters = log2file, time, debug
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103572/9e77f93c-0991-5164-18ac-32504150254d.png)

## その他

次の説明は[本家のページ](https://docs.platformio.org/en/latest/core/userguide/device/cmd_monitor.html#filters)の英訳です。（DeepL先生監修）

ESP32, ESP8266のエクセプションデコーダフィルタ名は次の表には書いてません。

| Name | Description |
|:-|:-|
| colorize  |  受信時とエコー時で異なる色を適用 |
|  hexlify | データの16進数表示（各文字のコードポイント）  |
|  log2file |  現在の作業ディレクトリにあるファイル "platformio-device-monitor-%date%.log "にデータを記録する。 |
|  nocontrol |  CR+LFを含むすべてのコントロールコードの削除 |
|  printable |  すべての非ASCII文字の10進コードを表示し、ほとんどの制御コードを置き換えます。 |
|  time |  新しい行ごとにミリ秒単位のタイムスタンプを追加する |
|  send_on_enter |  ENTERでデバイスにテキストを送信 |

## さいごに

なんで、今頃になって気づいたんやろ。しらんかった。。
調べるの疲れた。👍
少しでもお役に立てれば何よりです。

（了）
Elmer の mesh を見てみる

# はじめに
`Elmer`のメッシュを調べたくなりました。
# OpenSCAD
![20210717b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/37f89994-9ebc-01ad-89df-524229d440a1.png)
`OpenSCAD`で普通の直方体を作成します。

```openscad.js
cube([0.05, 0.01, 0.02]);
```
# Elmer
![mesh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/7fb8875a-9049-36b6-9a28-af52dafdd69f.png)
`Elmer`で開きますと、メッシュが切られます。
# ヘッダー
`mesh.header`を見てみます。

```header.cpp
21 30 36 //　ノード数　エレメント数（この場合テトラ数）　境界数（この場合サーフェス数）
2 //　タイプ数（この場合テトラとサーフェスの2種類）
303 36 //　タイプ303が36個
504 30 //　タイプ504が30個
```
# ノード
`mesh.nodes`を見てみます。

```nodes.cpp
1 -1 0.05 0 0.02 //　ノード番号　タグ番号　x座標　y座標　z座標
2 -1 0.05 0.01 0.02
3 -1 0.0346221 0.01 0.02
4 -1 0.0153779 0.01 0.02
5 -1 0 0.01 0.02
6 -1 0 0 0.02
7 -1 0.0148458 0 0.02
8 -1 0.0337217 0 0.02
9 -1 0.05 0.01 0
10 -1 0.05 0 0
11 -1 0.0346221 0 0
12 -1 0.0153779 0 0
13 -1 0 0 0
14 -1 0 0.01 0
15 -1 0.0144143 0.01 0
16 -1 0.0333333 0.01 0
17 -1 0 0 0.01
18 -1 0.05 0 0.01
19 -1 0.05 0.01 0.01
20 -1 0 0.01 0.01
21 -1 0.0245592 0.00502014 0.0099701
```
21個なのは内部にもノードがありました。
![20210717c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/58bc7c81-c5f6-22bd-b3b6-e69162a02bae.png)
ノード1番を緑色にしてます。
# エレメント
`mesh.elements`を見てみます。

```elements.cpp
1 1 504 21 4 3 8 //　エレメント番号　ボディ番号　タイプ　エレメントを構成するノード番号
2 1 504 21 3 4 16 
3 1 504 15 17 20 7 
4 1 504 5 4 20 7 
5 1 504 3 16 11 19 
6 1 504 3 18 8 1 
7 1 504 2 18 19 3 
8 1 504 4 21 16 15 
9 1 504 21 4 8 7 
10 1 504 13 15 17 20 
11 1 504 15 12 17 7 
12 1 504 17 5 20 7 
13 1 504 13 12 17 15 
14 1 504 17 5 7 6 
15 1 504 4 21 15 7 
16 1 504 19 16 11 9 
17 1 504 21 3 11 8 
18 1 504 13 14 15 20 
19 1 504 21 11 3 16 
20 1 504 18 19 11 10 
21 1 504 18 3 11 19 
22 1 504 3 18 11 8 
23 1 504 19 9 11 10 
24 1 504 2 18 3 1 
25 1 504 4 15 20 7 
26 1 504 21 12 16 15 
27 1 504 12 21 8 7 
28 1 504 21 12 15 7 
29 1 504 21 11 12 8 
30 1 504 21 12 11 16 
```
![20210717d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/bd0acf0f-ee0a-4ed8-75a4-e0fbc8666f25.png)
エレメント1番を緑色にしています。
# バウンダリー
`mesh.boundary`を見てみます。

```boundary.cpp
1 1 4 0 303 4 5 7 //　エレメント番号　境界番号　ペアレント１　ペアレント２　タイプ　エレメントを構成するノード番号
2 1 6 0 303 8 1 3 
3 1 14 0 303 5 6 7 
4 1 24 0 303 1 2 3 
5 1 1 0 303 3 4 8 
6 1 9 0 303 7 8 4 
7 2 13 0 303 12 13 15 
8 2 16 0 303 16 9 11 
9 2 18 0 303 13 14 15 
10 2 23 0 303 9 10 11 
11 2 30 0 303 11 12 16 
12 2 26 0 303 15 16 12 
13 3 22 0 303 11 18 8 
14 3 14 0 303 6 17 7 
15 3 27 0 303 8 7 12 
16 3 29 0 303 12 11 8 
17 3 20 0 303 11 10 18 
18 3 13 0 303 13 12 17 
19 3 6 0 303 1 8 18 
20 3 11 0 303 12 7 17 
21 4 24 0 303 2 1 18 
22 4 23 0 303 10 9 19 
23 4 20 0 303 10 19 18 
24 4 7 0 303 19 2 18 
25 5 7 0 303 2 19 3 
26 5 2 0 303 4 3 16 
27 5 25 0 303 15 20 4 
28 5 8 0 303 16 15 4 
29 5 16 0 303 9 16 19 
30 5 18 0 303 15 14 20 
31 5 5 0 303 16 3 19 
32 5 4 0 303 5 4 20 
33 6 12 0 303 20 17 5 
34 6 14 0 303 6 5 17 
35 6 18 0 303 14 13 20 
36 6 10 0 303 17 20 13 
```
直方体なので境界番号が6ですね。
![20210717e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538241/95a8e5f3-b029-cd47-ce20-73b475b81760.png)
エレメント1番を緑色にしています。
# まとめ
+ Elmer さんありがとう
+ OpenSCAD さんありがとう
+ T さんありがとう
超初心者がPythonでYahooファイナンスから為替レートを取得して可視化してみた

タイトル通り。

## 環境

python 3.9.6
細かい環境は省略。

## 参考

https://vector-ium.com/pdr-fx/

https://qiita.com/nkay/items/d1eb91e33b9d6469ef51#21-figureadd_subplot

## コード

``` get_fx_rate.py
import pandas_datareader as pdr
import datetime
from matplotlib import pyplot as plt

# 為替レート取得
pair='USDJPY=X' #AUDJPY=X USDJPY=X EURJPY=X
data = pdr.DataReader(pair, 'yahoo', end='2021-07-10', start='2021-07-04')
tmp = data.head()

print(tmp)

# 可視化
fig = plt.figure(figsize=(12,8), tight_layout=True)
ax = fig.add_subplot(111, xlabel=data.index.name, ylabel='USDJPY')

ax.plot(data['High'])
ax.plot(data['Low'])

fig.savefig('test.png')
```

## 所感

可視化についてはもっと色々できるみたいなので別途勉強したほうがよさげ。
AWS Lambda+pythonからdatadogにカスタムメトリクスを送信


# はじめに
AWS Lambdaの関数からdatadogへカスタムメトリクスを送信する方法のメモです。今回の実装にはpythonを利用しました。

# 参考にした記事
- datadog自身のブログ
- https://www.datadoghq.com/ja/blog/datadog-lambda-layer/
- datadog社「カスタムメトリクス」
- https://docs.datadoghq.com/ja/serverless/custom_metrics/

# 実際にやったこと
## 関数の作成

まず関数を作成。ランタイムはpython3.8を作成

![datadog1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569305/8d9f26f6-0c73-f282-13e7-ccc97baf2875.png)

## レイヤーを追加

オンプレサーバからpythonでカスタムメトリクスを送信するときはpipコマンドでdatadogライブラリを追加しますが、Lambdaなのでレイヤーを追加しておいてライブラリを使えるようにします。
datadog自身がレイヤーを用意してくれているので、それを使うことにします。

関数の概要画面の下部にスクロールして「レイヤーの追加」をクリック
![datadog2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569305/b18e754e-c638-5d0d-97b7-64d923ff48dc.png)
中略
![datadog3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569305/7f3ffbfd-92f4-f5bc-46ac-91788818bcdc.png)

レイヤーの追加はARNを指定して追加します。
datadogがレイヤーを公開しているので、ここから最新版を選ぶ必要があります。
https://github.com/DataDog/datadog-lambda-python/releases

今回の関数はpython3.8にて実装するため以下のARNを使います
- arn:aws:lambda:<AWS_REGION>:464622532012:layer:Datadog-Python38:42

私は東京リージョン(ap-northeast-1)で関数を実装したため、以下のARNを設定することにします
arn:aws:lambda:ap-northeast-1:464622532012:layer:Datadog-Python38:42
![datadog4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569305/c77b3cb1-5a6d-49a0-08cf-fc1868a379ab.png)

## Lambdaにて環境変数を設定する
datadogを利用するためには環境変数の設定も必要なので、設定しておきます。
datadog側でAPIキーを発行しておいて、下記の環境変数を設定します。
- DD_API_KEY：APIキー


## 関数の実装

あとは関数をpythonで実装するのみです。
以下はlambda.test_metricsという名称にて99.99というメトリクス値を送信するプログラムです

```lambda_function.py
import json

from datadog_lambda.metric import lambda_metric
from datadog_lambda.wrapper import datadog_lambda_wrapper

@datadog_lambda_wrapper
def lambda_handler(event, context):
    tags = ['name:testapp']
    metric = "lambda.test_metrics"
    value = 99.99
    lambda_metric(metric, value, tags=tags)
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```

# 結果

datadogのMetrics Explorerで閲覧してみると送信されていることがわかります
datadogに慣れている人ならご存知かと思いますが、メトリクスが反映されるまでに少しかかるので関数実行直後に見に行くとハマります。

![datadog6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569305/494f5e8a-cd4f-21c8-f675-65a47a396c7a.png)

# 課題
公式は非同期メトリクスを有効にすることを推奨(環境変数：DD_FLUSH_TO_LOGを参照)していますが、Datadog Forwarderを使う必要があるようです。ここらへんは試したらまた記事を執筆することにします。

https://docs.datadoghq.com/ja/serverless/datadog_lambda_library/python
「シャボン玉ってなんで丸いの?」をシミュレーションで答えてみた

# はじめに
「ジャボン玉ってなんで丸いの」っていうのに疑問をいだき、
シミュレーションすることで、納得感を得た男の物語である。


# 「なぜシャボン玉は丸いのか」の科学的説明
なんで、シャボン玉って丸いんだろう。
そう思ったとき、google先生に聞いてみるとこんな回答が返ってきた。

>表面張力によって、表面積を小さくしようとしてシャボン玉の膜は、自らを縮めようとする力が働きます。それにより、シャボン玉内の空気に圧力が働くのです。
>それと同時に、空気からもシャボン玉の膜に対して力が働きます。その力が釣り合うときに、シャボン玉の大きさがある程度決まります。
>**そして、同じ体積の立体の中で表面積が最小なのは球であることから、シャボン玉は球の形になるのです。**


![Screen Shot 2021-07-17 at 13.40.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/2830768a-da73-0afb-56bb-813b1d1c550e.png)

(ソース)
https://nazology.net/archives/7622

# 何故かピンと来ない自分がいる
1つ1つのシャボン玉粒子(原子?)は、周辺の粒子と引き合ったり、内外の空気とぶつかったりしているだけで、
「球」という全体構造や、「表面積を最小にする」などと考えて行動しているわけでない。

**なのになぜ、全体構造として「球体」が立ち上がってくるのか。**

確かに数学的には、球が同体積でもっとも表面積が小さいというのは納得できるのだが、
それを何の気なしに行っているシャボン玉が不思議だった。

何故か、手触り感がないというか、ピンと来なかった。

# ならばシミュレーションしてみよう
こんなときに、「構成論的手法」というアプローチがある。
作ってみることで、理解してみようとするアプローチである。

今回は、シャボン玉をコンピュータ上でシミュレーションすることで、
シャボン玉はなぜ丸いのかということを検証してみた。

# シミュレーション環境
今回はシミュレーションに、Planck.jsというJSの2D、物体計算ライブラリーを用いてみた。

https://github.com/shakiba/planck.js

こちらExampleが丁寧に数多く用意されており触りやすかった点と、JSなので完成したものをすぐ共有できるということでこちらを使った。
https://piqnt.com/planck.js/

# シミュレーション条件
![Screen Shot 2021-07-17 at 14.15.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/0a32ff21-5db3-9c7c-dc77-8bc7e43b067a.png)

1 まず、チェーンのような輪っかを作成し、それを四角においた。これが、今回シャボン玉粒子を表している。

(※ 残念ながらゴム状に縮まる素材では作れなかったが、最終的にシャボン玉は中の空気圧と、
膜の表面張力が釣り合うと考えるとその時のシャボン玉粒子の状況であると考えることができる。)

2 次に内部に、自由に動く空気分子を用意した。
コイツらはそれぞれがランダムに動き、他の空気分子やシャボン玉に衝突する。

この条件下で、自然と「円」の形にシャボン玉粒子がなれば実験は成功だ。

# 結果
![trim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/45234d21-963d-2073-07da-bbaf8ddbb0b7.gif)

実際にこちらにアクセスすれば、ブラウザでも動かせるので試してほしい。
https://yuto-ktok.github.io/soup_bubble/

ソースはこちらです。(動けばいい風)
https://github.com/yuto-ktok/soup_bubble

### なんとまあ、円になるではないか！！！素敵すぎる！！


# まとめ・所感
シャボン玉が球になることが、腑に落ちなかった自分だが、
シミュレーションしてみるときれいに円になることを再現できた。

そして、実際に動かしてみるとすごい腑に落ちた。
最初、自然界で球になることに神秘性を感じていた自分だが、
シミュレーション後には、**「球になるのは必然で、むしろこちらが自然な形である」**
とさえ思える。

また、物体シミュレーション初だったが、plank.jsは優秀なライブラリで直感的に動かせた。
今後も機会があったら遊んでみたい！！
Android Studioでライセンス状況が確認できない場合

![スクリーンショット 2021-07-17 13.40.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/5d7bf06d-785a-260f-473b-353f0a3fbc7d.png)
Android Studioでデバッグをしようとした時にこのような、ライセンス状況が不明とエラーが出た場合は！とりあえず、このコマンドでFlutterの依存関係を確認してください。

```
flutter doctor
```
`flutter doctor --android-licenses`を実行して、SDKのライセンスを受け入れてください。と下記内容が出てくるので指示通りに対応していきます。

```
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for
      more details.
```
![スクリーンショット 2021-07-17 14.05.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/e1febd32-3e17-c43c-4655-2d9a0eca69d4.png)
こちらで解決すれば問題ないのですが、`flutter doctor --android-licenses`が実行出来ない場合は、Android Studioの`configure`から`SDK Manager`を選択して

![スクリーンショット 2021-07-17 14.16.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/4285e542-d050-1920-ce9f-e4d38f4c96dd.png)
`SDK Tools`を選択、`Hide Obsolete Packages`のチェックを外して、`Android SDK Tools(Obsolete)`と`Android SDK Command-line Tools(latest)`にチェックを入れたら`Apply`してOKしましょう。

![スクリーンショット 2021-07-17 14.17.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/f2857809-595b-2db8-a5bc-bd111d17850b.png)
あとは`flutter doctor --android-licenses`コマンドで確認するだけです。Android Studioでもデバッグできるようになりました。

![スクリーンショット 2021-07-17 13.15.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/8e13bb48-5694-0de9-f41b-0303f14518e8.png)
【rails】update_attributes→updateを使う

##環境
Rails 6.1.4

##記事を書いた理由
webアプリを作成中、

>undefined method `update_attributes'

というエラーが出てきてしまい、あたふたしてしまったため。
同じように困ってる人の助けになればと思い書きました。

##解決策
タイトルの通り、update_attributesをupdateに変更するだけ。
update_attributesはrails6.1から削除されたそうです。

参考にさせていただいた記事▼

https://github.com/rails/rails/commit/5645149d3a27054450bd1130ff5715504638a5f5

https://railsguides.jp/6_0_release_notes.html#active-record-%E9%9D%9E%E6%8E%A8%E5%A5%A8%E5%8C%96

https://makolog.xyz/post-585/

##（蛇足）そもそも(元)updateとは何なのか？

私は初学者なので、まずこれは何のメソッドなの？と固まりました。
（テキストを見ながら進めていたので、よく分からずに書いていた。）

調べてみたところ、

>>すでにテーブルに保存されているデータを新しい情報に更新するメソッド

だそうです！
このメソッドの詳しい説明は下記の記事に分かりやすく書いてあったのでここでは割愛します。
（すごく分かりやすいのでぜひ読んでみてください！）

▼参考にさせていただいた記事

https://pikawaka.com/rails/update
【React】Module not found: You attempted to import ../../Hoge which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.の対処法

<h2></h2>
別のjsxファイルをimportしたところ、以下のエラーが発生しました。
翻訳すると、「モジュールが見つかりません：プロジェクトのsrc /ディレクトリの外にある../../Hogeをインポートしようとしました。 src /以外の相対インポートはサポートされていません。」でした。

```terminal:エラー
Module not found: You attempted to import ../../Hoge which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
```

ディレクトリ構造は下記になります。、

src
├ Hoge.js
│  
└ App.js

こちらがエラー発生したファイルです。

```App.js
import React from "react";
import {HogeText} from "../../Hoge";

function App() {

  return(
    {HogeText}
  )
}
```


<h2>解決方法</h2>
importのパスを修正したら、エラーが解消されました。
srcより上位の改装のものをインポートしようとしているため、怒られていたようです。

そもそも参照先が間違っているというエラーより、先にsrcより上位からimportするエラーが出てくることが学べてよかったです。

```App.js
import React from "react";
import {HogeText} from "./Hoge";

function App() {

  return(
    {HogeText}
  )
}
```