OmniAICreator/Qiita-1.07M huggingface dataset:
npmとYARNのコマンドをまとめる #3

# npmとYARNのコマンド一覧
|   |npm  |YARN  |
|---|---|---|
|package.jsonを生成  |npm init  |yarn init  |
|package.jsonに記載されたパッケージをインストール|npm install|yarn install|
|パッケージをローカルインストール|npm install ＜package＞|yarn add ＜package＞|
|開発用パッケージをインストール|npm install -D＜package＞|yarn add -D ＜package＞|
|パッケージをグローバルインストール|npm install -g ＜package＞|yarn global add ＜package＞|
|パッケージをアンインストール|npm uninstall ＜package＞|yarn remove ＜package＞|
|開発環境用のパッケージをアンインストール|npm uninstall -D ＜package＞|yarn remove ＜package＞|
|グローバルのパッケージ全体の更新|npm update –global|yarn global upgrade|
|ローカルのパッケージ全体の更新|rm -rf node_modules && npm install|yarn upgrade|
|ローカルのパッケージ更新|npm update ＜package＞|yarn upgrade ＜package＞|
|キャッシュクリア|npm cashe clean|yarn cashe clean
|パッケージ情報の表示|npm info ＜package＞|yarn info ＜package＞|
|古いパッケージ一覧の表示|npm outdated|yarn outdated|
|package.json内のscriptで定義されたスクリプトの実行|npm run ＜script＞|yarn run ＜script＞|
|アップデートできるパッケージを表示||yarn upgrade-interactive|
macでADBコマンドのパスをサクッと通す

# はじめに
ADBコマンドみなさん使っていらっしゃいますでしょうか。
apkをインストールしたり、スクショやディレクトリを参照したり等端末を直接操作可能で便利なadbコマンドですが、vimを立ち上げてパスを通すの面倒ですよね。
そんな時にvimを立ち上げずにパスを通すコマンドがあるので、紹介したいと思います。

# パスを通す
パスを通す際のコマンドはたった2つです。

```
$ echo 'export PATH=“sdkのパス/platform-tools"' >> ~/.zshrc
```
上記を実行したあと、以下を実行するだけです。

```
$ source ~/.zshrc
```
以上になります。
※環境によって、bash_profileを使用する場合は、zshrcをbash_profileに変えて実行してください。
※sdkのパスはAndroidStudioのModuleSetting等で確認可能です。

# さいごに
vimを立ち上げずにパスを通すことができるので、楽でいいですよね。
adb以外にも上記を活用できるので、覚えておくと少しだけ幸せになれるかもしれません。
Gatsby.jsで背景に動画を埋め込む方法


特別プラグインやコンポーネントを作成しなければならない訳ではなく簡単に実装できます。
CSSでbackground-imageとして実装するのではなく、index.jsに書き込みます。


Gatsby.js
＊埋め込みたい動画はプロジェクトフォルダ直下のstaticファイルに埋め込みます。
~~~ react
<div class="bg-movie">
    <video　className="video-player"　height="100%"　width="auto"　loop　muted　autoPlay>
        <source src="/movie.mp4" type="video/mp4" />
    </video>
</div>
~~~

CSS
~~~ CSS
.bg-movie{
    width:100%;
    height:700px;
    position: relative;
}

.bg-movie video{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translateX(-50%) translateY(-50%);
    min-width: 100%;
    min-height: 100%;
}
~~~


参考記事:https://spectrum.chat/gatsby-js/general/make-video-a-background-with-no-sound~4fff27a4-a458-4ba3-a767-10734230ed1d
react-table の使い方

こちらのページを参考にしました。
[Reactの機能で簡単にテーブル（表組み）を作る方法【react-table使います】](https://ralacode.com/blog/post/react-table/)

次のようなテーブルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/0bce9a91-3be2-d1a3-f319-f3ababb98024.png)

プロジェクトの作成

```bash
create-react-app ex04
cd ex04
yarn add react-table
yarn start
```

次のプログラムを修正します。
src/App.js
src/App.css

次は加えます。
src/tableData.jsx


```js:src/App.js
// eslint-disable-next-line

import React from "react";
import { useTable } from "react-table";
import { columns, data } from "./tableData";
import "./App.css";

export default function App() {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow
  } = useTable({
    columns,
    data
  });

  return (
    <table {...getTableProps()}>
      <thead>
        {headerGroups.map((headerGroup) => (
          <tr {...headerGroup.getHeaderGroupProps()}>
                            {headerGroup.headers.map((column) => (
              <th {...column.getHeaderProps()}>
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　{column.render("Header")}
　　　　　　　　　　　　　　　　　　　　　　　　　　　　</th>
            ))}
          </tr>
        ))}
      </thead>

      <tbody {...getTableBodyProps()}>
        {rows.map((row, i) => {
          prepareRow(row);
          return (
            <tr {...row.getRowProps()}>
              {row.cells.map((cell) => {
                return (
                  <td {...cell.getCellProps()}>
　　　　　　　　　{cell.render("Cell")}
                 </td>
                )
              })}
            </tr>
                            );
        })}
      </tbody>
    </table>
  );
}
```

```css:src/App.css
/* -------------------------------------------------------------- */
/*

        App.css

                                                Aug/02/2022

*/
/* -------------------------------------------------------------- */
table,td,th {
        width: 80%;
        table-layout: fixed;
        border:1.5px #7e7e7e solid;
}

th { background: #c6c6c6; }


/* -------------------------------------------------------------- */
```


```jsx:src/tableData.jsx
export const columns = [
  { Header: "商品", accessor: "product" },
  { Header: "値段", accessor: "price" },
  { Header: "在庫", accessor: "stock" }
];

export const data = [
  { product: "りんご", price: "120円", stock: "130" },
  { product: "バナナ", price: "100円", stock: "200" },
  { product: "メロン", price: "3400円", stock: "2" },
  { product: "ぶどう", price: "1200円", stock: "6" }
];
```



次の環境で確認しました。

```text
$ node --version
v18.7.0
$ yarn --version
1.22.19
```
Androidで特定のルートに沿って位置情報を変更させる方法

# はじめに
Android開発の中でFakeGPSなどを使用して位置情報を指定した場所に設定したりエミュレーター上で位置を固定する記事はよく見るものの、指定ルートを動くような位置情報を動かす設定を探すのに苦労したので共有します。

チーム内のiOSエンジニアから聞いたのですがiOSだとXcodeから元々保存されているルートを動かす機能があるようですね。
https://maps.multisoup.co.jp/blog/4898/

# Androidでの方法

### まずgpxファイルを作成する
ルート情報を読み込ませるために必要なgpxファイルを適当に取ってくるか以下の方法で特定のルートから作成をします。

https://escape.poo.tokyo/cycling-computers/cycle-computer-with-gps/how-to-make-a-gpx-file-via-googlemap/
https://mapstogpx.com/https://mapstogpx.com/

### 読み込ませ方
1. EmulatorのExtendedControlesを開く
2. Location > Routes > Import GPX をタップし上で取得したデータをImportする

これで完了です。一時停止、再開や位置情報を動かす速度も変更することができます。
一度取り込んだルートは名前をつけて保存しPlayRouteボタンから再度呼び出すことも可能です。


# 最後に
地図を動かしたい時に外出せずともあらゆるルートをシミュレートすることができるのでとても便利でした。
iOSがやっていて便利そうなことを調べると大体最近はAndroidでもできることが多いのでOSが違っていてもチーム内でコミュニケーションやレビューをすることは大切だなと改めて感じました。
IBM RPAのOCR機能を使用してみる

# 3つのOCRエンジンをサポートするIBMRPA
IBM RPAでは複数のOCRエンジンをサポートしており、ツール上から読み取り範囲の指定などをシームレスに行うことが可能です。OCR機能と連携することで、例えばPDFで送付されてきた注文書を読み取り、システムに入力するといった一連のシナリオをボットによって実装することが可能です。この記事ではIBMRPAでの具体的なOCR機能の使用方法について整理したいと思います。
# サポートされるOCRエンジン
IBMRPAでは以下の3つのOCRエンジンをサポートします。
- Tesseract
オープンソースのOCRエンジンです。

- ABBYY
ABBYY社のOCRエンジンです。IBMRPAに組み込まれており、追加のライセンス費用無しで使用することが可能です。サーバー側にモジュールがインストールされ、サーバー側で動作します。

- Google Cloud Vision
Googleが提供するOCRエンジンです。別途ライセンスが必要ですが、APIキーを取得してツールやコマンドに設定することで利用することが可能です。
# コマンドでの使用例
様々なコマンドでOCRを使用することが可能ですが、代表的なものは以下の3つです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117736/9658d41c-b62a-1495-c672-0141d8494aee.png)
- OCRによるクリック
画面上の領域をOCRにより取得し、該当座標をクリックします。
- OCRによるコントロール・テキストの取得
画面上のテキストをOCRによって取得します。
- OCRによるPDFテキストの取得
PDFファイルからOCRを使用してテキストを取得します。

実際に「OCRによるPDFテキストの取得」コマンドを使用してみました。このコマンドを使用するには以下の項目を指定する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117736/92f9c6f4-b265-d229-b2c8-0a798d287732.png)
これらを一つずつ指定するのは少し面倒なのですが、「PDFテキストの抽出」ツールを用いることで、読み取り対象のPDFファイルを用いて、実際にOCRを動作させながら、読み取り領域を簡単に指定することが可能です。今回のケースでは、OCRエンジンとしてABBYYを選択し、「氏名」という文字をアンカーに指定し、そこからの相対的な位置で実際の氏名「田中太郎」を正しく認識することができました。(なお、このバージョン21.0.3ではTesseractでは英語のみ正しく動作し、日本語の認識は動作しませんでした。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117736/cd0a0c78-2e57-0d60-0442-99aeb0ebe9b2.png)
具体的な手順は以下の通りです。
1. アンカー取得用OCRエンジンと言語を選択する(今回はAbbyy,ja-JP)
2. アンカーとなる領域を選択する
3. アンカーとなる文字を入力する
4. プレビュー、もしくはアンカーの検索ボタンをクリックし、正しくアンカーが取得できていることを確認する
5. ターゲット用OCRエンジンを選択する
6. ターゲットの領域を選択する
7. プレビューをクリックして結果を確認する
8. コマンドの生成ボタンをクリックしてコマンドを生成する

# まとめ
いかがでしたでしょうか？IBMRPAでは3つのOCRエンジンをサポートしており、ツール上から簡単にOCR機能を呼び出すことができました。OCR機能を使用することで、画面の上のボタンの位置を探してクリックしたり、PDFファイルからテキストを抽出し、後続のシステムに連携するといった業務シナリオを実装することが可能です。別途ライセンスを購入することなくABBYYを使用できるのは便利ですね。Google Cloud Visionを使う場合にはライセンスの指定が必要なのですが、そちらについても別途記事にしたいと思います。

### ※Japan Business Automation User Groupのご紹介
IBMのコミュニティーである、[Japan Business Automation User Group](http://ibm.biz/JPBizAutomationUG)では、IBMのBusiness Automation製品関連の様々な技術情報、イベント情報の参照や、フォーラムを介した技術的な質問を行うことが可能です。是非ご参加ください。　http://ibm.biz/JPBizAutomationUG
AWSのコスト 

# AWSの料金体系
## 使った分だけ支払う従量制
将来必要だけれど、今必要ない分を借りる必要がない。

## 代表例
### Amazon EC2
インスタンス使用料+EBSの料金+通信量+その他オプション
### Amazon S3
保存容量+転送料
### Amazon RDS
ストレージ料金+DBインスタンスの料金+バックアップストレージの料金+通信量

## AWS料金のメリット・デメリット
イニシャルコストがかからない分、ランニングコストがかかる。
突発的にアクセスが集中するケースはAWSが有効に使える。
アクセス量の変化が少ない場合は、AWSを使用すると運用を任せらるため人件費の削減ができる。
TypeScript 学習記録

## はじめに
TypeScriptの学習で学んだことについて後日自分で振り返るためにまとめていきます。

## TypeScriptとは
JavaScriptが型定義できるようになった言語

## TypeScriptを扱う上で必要な知識
### tsconfig
  TypeScriptをJavaScriptにコンパイルをするときに使う設定ファイル
### webpack
 javascriptファイルをまとめてbundle.jsを作成
### ESLint
 javascriptの為の静的検証ツール
### Prettier
itにコミットするときにソースコードを成形してくれる

## TypeScriptの基本
### 型
TypeScriptは型を推論する。
型アノテーションを用いて型を宣言することができる。
``` const sample: string = "test" ```

○プリミティブ型
string、number、bolean

○存在しないことを表す型
null、undefined
nullは枠組みだけある、undefinedはなにもない
nullはなるべく使わない
nullはobject型、undefinedはundefined

○様々な型を許容する型
any、unknown
anyは入れるものによって型が変化する。
扱いが難しいのでanyはなるべく使わない
```
let sample: any = "panda" 
//type of sample は string
sample = 7
//type of sample は number
```

unknown型の変数を使用するときは、
型を特定してからでないと、オブジェクトのプロパティやメソッドの参照ができない。
```
let sample2: unknown = 7
//sample2 = sample2 + 7;　エラーになる
if (typeof sample2 === 'number') {
  sample2 = sample2 + 7;
}
```

### 関数
〇関数の戻り値で使用する特別な型
void…return文を持たない関数の戻り型
never…エラー発生後などの、決して戻ることのない戻り型

〇パラメータ
オプション…あってもなくてもいい(?をつける)
デフォルト…初期値を設定する
可変長引数…引数をいくつ渡してもいい、なるべく使わない
レストパラメーター…パラメータの最後に定義、...をつける
```
const sampleFunc1 = (para1:string = "デフォルト",...para2:number[]):void {
}
const sampleFunc2 = (para3:string,para4?:string):void {
}
```

〇型シグネチャ
・どのような関数の型定義を行う、関数のひな型のようなもの
```
type FuncTemp1 = (sample: string) => number //簡略型
type FuncTemp2 = {
(sample: string) : number
} //きちんと書いた型シグネチャ

export const Func: FuncTemp1 = (test) => {
return 10
}
```

参考記事
・[【TypeScript】any型とunknown型の違いを具体例で理解する](https://nishinatoshiharu.com/difference-any-unknown/)
・[トラハック 日本一わかりやすいTypeScript入門シリーズ](https://www.youtube.com/watch?v=kd8VH10jXwc&list=PLX8Rsrpnn3IW0REXnTWQp79mxCvHkIrad)
PythonにCSVなどのサンプルデータをヒアドキュメントとして埋め込む際にはio.StringIOが便利

小ネタです。

類似のサンプルはよく見ると見つかるのですが、キーワード検索で引っかかりやすくるために記事を立てました。

Pythonのライブラリ、Pandasの例を記載する場合に、テーブルのサンプルデータをコード中に（ヒアドキュメントとして）埋め込見たくなる場合があります。こういった場合には [io.StringIO](https://docs.python.org/ja/3/library/io.html#io.StringIO) を活用して以下のような書き方をすると比較的可読性と両立しやすいように思います。

```python
import io
import pandas pd
data = '''this,is,header
01,12,sample
'''
df = pd.read_csv(io.StringIO(data))
```
Cost Anomaly DetectionでAWSのコスト異常検知を設定する

# Cost Anomaly DetectionでAWSコスト異常検知
## 背景
- AWSのコストエクスプローラーを見ると、特定の日に急にコストが跳ね上がった日があった

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707757/76c0ceed-ee3c-c940-df8e-d9d77cd3cf66.png)

- なにこれ？やばい！ってなったけど、こういう情報は早く知りたい。


## 解決策
### Cost Anomaly Detectionを活用する
- コストエクスプローラーからコスト異常検知をクリックする
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707757/975faa1b-e027-ce86-7e53-23a3bd684530.png)
- モニタータイプとモニター名を設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707757/87d488d3-d74a-9e0f-b0fc-68579153daf0.png)
- サブスクリプションを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707757/de5daf21-2d22-c0b8-a4ad-4ce114d59dfa.png)


これで何か異常があった際には、アラート通知が飛んできてくれるはず・・・！
この設定の恩恵を受けたら、本記事に追記します。
【AWS】S3のストレージクラス

データを格納するといっても使い方によって必要なスペックは全く異なる。
AWSで提供されているS3のストレージクラスを以下にまとめる。

# S3標準
通常のやつです。
イレブンナインの耐久性（Durability）を誇り、99.99%の可用性（Availability）です。

# S3標準（低頻度アクセス）
データへのアクセスは随時可能だが、データの読み出し容量に対する従量課金が発生する。
その代わり、格納コストが安価。
アクセスしたいときは迅速さが求められるが、そこまでアクセスは発生しない、といった要件の時に出番。

# S3 One Zone-IA
単一のAZのみでデータを複製しておくストレージクラス。名前の通り単一のAZでの保管となるため、当該AZで障害が発生したときはデータが失われてしまう。


# S3 Intelligent
参照頻度を明確に決めることができないデータを取り扱う場合に使う。
S3とS3標準（低頻度アクセス）の二刀流であり、30日以上参照されなかったデータに関してはS3標準（低頻度アクセス）の方に移動される。頻繁に移動が発生する場合はコスト増につながることに注意。

# S3 Glacier
[こちらの記事](https://qiita.com/morinskyy/items/47f6616cbacbb6d389c5)でも記載したように、ほとんど参照されないアーカイブ目的のデータを保存する場所。


# S3 Glacier Deep Archive
S3 Glacierよりもさらにアクセス頻度が少ないデータを想定している。
取り出しに標準で12時間。（すごい。。。）
GBあたりのストレージ単価はS3 Glacierと比較して最大75%OFF！！


# とはいえ、どうやって使い分けるのよ。。。。
以下のフローチャートが大変参考になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665477/d00dff8b-46fa-69c7-c7d1-0a00672d4b9a.png)
画像引用：[6つのS3ストレージクラスの選択に迷った時みるチャートをつくってみた](https://dev.classmethod.jp/articles/should_i_choice_s3_storage_class/)
「データ分析実務スキル検定」に私が２週間で合格できた勉強法

# 「データ分析実務スキル検定」に私が２週間で合格できた勉強法

## データ分析実務スキル検定とは
そもそも本試験はどういうものかというと、「ビジネスにおけるデータ分析人材のための資格試験」と公式サイトに記載されています。
[(データ分析実務スキル検定公式サイト)](https://cbas-exam.jp/)

この資格はどちらかというと、データ領域を初めて学習する人向けだと感じます。実務でデータ分析をしている方であれば、この資格は少し物足りないのかなと思います。


## 試験概要
問題数：60問
試験方法：CBT方式
試験時間：90分
合格ライン：97点満点で64点以上
受験料：11,000円（税込み）

## 私の学習前のスキル

私自身、新卒１年目で、働くまでデータ領域は全く触れてきませんでした。
SQLは基本的なコード、統計学に関しては3級を取得している、ほかの分野に関しては完全にノータッチという状況でした。

そのため今回は、実務経験なし、データ分析領域に精通していない初心者である私の観点から、どのような学習をして合格できたのか、記載したいと思います。


## まずは公式テキストを買う
この試験自体2020年から始まっているものなので、そもそも過去問がネット上にありません。そのため、勉強法は限られてきます。

ただ、試験を行っているCBASが公式テキストを出しているので、まずはこちらを買いましょう。
Udemyでこの試験の講座があるのですが、個人的にはこの動画は見なくても合格まで届くのかなと思います。公式テキストで網羅できるという点と、Udemyの講座は詳しく解説されている箇所と、そうでない箇所の差が激しい点を踏まえると、初めて学習される方は、まずは公式テキストで１通りインプットをすることが好ましいです。

だいたい450ページほどあるので、計画的に学習しましょう。

## 模擬試験を何回も解く
詳しく理解できなくてもよいので、1周公式テキストを読み終えたら、巻末に付いている模擬試験を解きましょう。そこでわからなかった問題を公式テキストを用いて振り返る、というやり方が一番効率が良いかなと思います。

公式テキストだけで網羅できるほど、非常にわかりやすく説明されているのですが、統計学は2級の範囲が入っていたり、機械学習も普段なじみのない人にとっては難しく感じたりする箇所があると思うので、そこはUdemyの講座を購入して学習を進めるとよいです。


ちなみにUdemyの講座は通常価格24,000円なのですが、高頻度でかなりの額を割引されています。必ず割引されているときに購入しましょう。私は1,600円で購入できました。（笑）

## 各分野の問題数
模擬試験、そして本番の試験を受けて、各分野の問題数がほぼ同じだったので、記載しておこうと思います。多少前後はあると思いますが、比重としては下記のとおりです。

SQL：5問
R言語：5問
Python：7,8問
Excel：5問
グラフの読み取り：5問
KPIツリー：3問
個人情報保護法関連の問題：1問
統計学：11,12問
機械学習：15,16問ほど

ちなみに順番もSQLから始まり、統計学、機械学習で終わるという感じです。（ここは前後あると思います）

CBT形式での受験のため、問題を選びながら解くことはできません。前から順に解くようになります。90分で60問解くので、単純計算90秒で1問解き終えなければならないのですが、わからない問題はどんどん飛ばしましょう。

問題の配点は不明ですが、1問に時間をかけすぎないように注意しましょう。

SQL,R,Pythonは、この関数が何を意味しているのかさえ覚えていれば、すぐ解けれる問題ばかりです。ただ、個人的にはExcelが5問あるのですが、最後の4,5問は慣れていないと時間がかかると思うので、後回しでいいと思います。

私は全部解き終えて10分ほど余ったので、5分で残りのExcelの問題を解き、5分で見直しをしました。

## 試験を受ける際の注意点
基本的に4択の選択式なのですが、時々、複数回答の問題があります。そのため、消去法が使えません。すべての選択肢を読んで、判断する必要があるので、そこは時間がかかるかなと思います。

特に複雑な計算をするところはないのですが（Excel以外で）、メモ用紙や電卓は使えないので、その点は注意しておきましょう。

## 最後に
この試験は、まだまだ出てきて年数が浅いので知名度も低いと思います。

ただ、データアナリストやデータエンジニアが、今後需要が増してくることは多くのメディアで予測されています。また、それらの職種以外のマーケターや営業なども、データの知識を有しているのと有していないのとでは、提案の幅も違ってきます。

そのため、データ領域の学習を進めておくことは、どの職種の人でも価値があることです。

ぜひ、様々な分野を体系的に学べる本資格を受験してみてはいかがでしょうか。
アイコンの名前をサイズに変換

あらかじめimagemagickを入れておく

```zsh
brew install imagemagick
```

適当なアイコンがカレントディレクトリにあるとして
renamedフォルダに出力したい場合

```zsh
for a in `ls`
do if [ -f $a ] ; then ;b=`identify -format '%wx%h' $a | cat`; echo $a;echo $b ;cp $a renamed/${b}.png ; fi
done
```

こんな感じで出力される
```zsh
100x100.png     128x128.png     16x16.png       196x196.png     29x29.png       48x48.png       57x57.png       72x72.png       88x88.png
1024x1024.png   144x144.png     172x172.png     20x20.png       32x32.png       50x50.png       58x58.png       76x76.png       96x96.png
```
Xcodeでx86_64エラーとなりビルドできない時の対処法

## 目次
1. はじめに
1. 原因と対処法
1. 最後に

## はじめに
新しいOSバージョンのMac（macOS Monterey 12.3以上）を使っていて、
VisualizerでXcodeビルドをした際に、エラーメッセージとして
**Entry point(_main) undefined. for architecture x86_64**
と表示され、プロジェクトをビルド出来ない場合があります。

![スクリーンショット 2022-08-02 17.27.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/37f86db6-afbb-16f4-3454-88554fd3103f.png)

今回はこの対処法について紹介していきたいと思います！

その他のよく遭遇するエラーについては、以下も併せてご確認ください。

- [Konyでよく遭遇するエラーまとめ ＊Kony Visualizer 起動〜開発編＊](https://qiita.com/Kony_Team/items/0667ca2c8ee346f046d7)
- [Konyでよく遭遇するエラーまとめ ＊Build編（共通）＊](https://qiita.com/Kony_Team/items/4a1ac93faf43b2a92dc3)
- [Konyでよく遭遇するエラーまとめ ＊Build編（iOS）＊](https://qiita.com/Kony_Team/items/2dbb66b34c05e09369f7)

## 原因と対処法
### 原因
macOS Monterey 12.3から、
python 2.7 が廃止され、python3を使用する必要があると発表されました。

>Python
Deprecations
Python 2.7 was removed from macOS in this update. Developers should use Python 3 or an alternative language instead. (39795874)

参考：[macOS Monterey 12.3 Release Notes](https://developer.apple.com/documentation/macos-release-notes/macos-12_3-release-notes)


Monterey以上にアップデートを行うと、
pythonのランタイム（pythonコマンド）に依存するアプリやスクリプトには影響が出てきます。

Visualizerもビルド時に
pythonコマンドを実行しているため今回のようなエラーとなってしまうようです。


### 対処法
pythonのv2の最新をインストールすることで、問題なくビルド出来るようになります。

ダウンロードサイトについては、以下をご確認ください。
- https://www.python.org/downloads/windows/

サイトを開くと以下の画面が表示されますので、
Python2の最新バージョンである
「Latest Python 2 Release」と表示されているものをクリックしてください。

（2022年8月3日時点では、画像の通り`Python2.7.18`が最新バージョンとなります。）
![スクリーンショット 2022-08-03 11.21.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/b8c64cd7-7b57-4649-300d-e15f1a0726f5.png)

`・Latest Python 2 Release - Python2.7.18`をクリックすると
以下の画面が表示されます。

![スクリーンショット 2022-08-03 11.25.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/9da436fe-d8a8-0c59-0986-7d31bf6a85c5.png)
ご利用の端末が
Macの場合、
`macOS 64-bit installer`
Windowdの場合、
32bit版なら
`Windows x86 MSI installer`
64bit版なら
`Windows x86-64 MSI installer`
をクリックしてください。

クリックした後、以下のインストーラが表示されます。
![スクリーンショット 2022-08-03 11.48.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/0f74cefb-b1d6-c7d7-d117-4f617e6132c8.png)
インストーラーの手順に沿っていけば問題なく、インストールできます。
インストールしたPythonの格納先は特に指定する必要はありません。

**インストール確認方法**
ターミナルで下記のコードを実行し、
pythonのバージョンを確認しましょう。
```
python --version
```
ターミナルで表示されたバージョンと、
先ほどインストールしたバージョンが一致していれば、
問題なくインストールが出来ています。

- インストール後
![スクリーンショット 2022-08-03 11.17.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/1462b5b0-5115-6f22-8076-fb194f109e43.png)

## 最後に
Xcodeでx86_64エラーとなり、ビルドができない場合の対処について紹介しました！
MacのOSバージョンが高い場合は、注意が必要なので、
同じように困っている方がいたら参考にしてみてくださいね！

## 参考
https://developer.apple.com/documentation/macos-release-notes/macos-12_3-release-notes
JetpackCompose Coil で GIF 


使い回しのきく基本的な最小構成で。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588914/746ec252-b755-7a62-3663-960dd8c3a492.gif" width="480">


```gradle
implementation "io.coil-kt:coil-compose:2.1.0"
implementation "io.coil-kt:coil-gif:2.1.0"
```

```kotlin
val url = "https://media.giphy.com/media/DhstvI3zZ598Nb1rFf/giphy-downsized-large.gif"

val imageRequest = ImageRequest.Builder(LocalContext.current)
  .data(url)
  .crossfade(true)
  .build()

val imageLoader = ImageLoader.Builder(LocalContext.current)
  .components {
    add(if (SDK_INT >= 28) ImageDecoderDecoder.Factory() else GifDecoder.Factory())
  }
  .build()

AsyncImage(
  model = imageRequest,
  imageLoader = imageLoader,
  contentDescription = null
)
```

ProgressIndicator は常にあるほうがいい。

![Reflector Recording.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588914/954fd469-374c-a713-f10b-e8a31073ab87.gif)


```kotlin
@Composable
fun AsyncImageGif(
  url: String
) {
  val context = LocalContext.current

  val imageRequest = ImageRequest.Builder(context)
    .data(url)
    .crossfade(true)
    .build()

  val imageLoader = ImageLoader.Builder(context)
    .components {
      add(if (SDK_INT >= 28) ImageDecoderDecoder.Factory() else GifDecoder.Factory())
    }
    .build()

  SubcomposeAsyncImage(
    model = imageRequest,
    contentDescription = null,
    imageLoader = imageLoader,
    modifier = Modifier.fillMaxWidth(),
    loading = {
      CircularProgressIndicator(
        modifier = Modifier.requiredSize(48.dp),
      )
    },
    error = {
      Icon(Icons.Filled.Error, null)
    }
  )
}
```

Any? な引数て使いづらいな。

[👉 【最新情報】3つの画像読み込みライブラリ Glide / Picasso / Coil - JetpackCompose 対応の状況](https://android.benigumo.com/20220801/glide-picasso-coil/)
ジョブ管理

# バッチ処理とは？
コンピュータを連続して働かせられない分```無駄な時間が生じます```。
そのな時間待たなくても良いように、時間のかかる処理を、```まとめてコンピュータにやらせておく処理```の仕方を```バッチ処理```という。
バッチファイルはイラストの指示書に似た仕組み
バッチ処理を次々登録しておいて、コンピュータを遊ばせずにキリキリ叩かせる仕組みを```ジョブ管理```という。
バッチファイルをたくさん登録して、自動実行させていける仕組みがジョブ管理
ジョブ管理に使う言語を```ジョブ制御言語(JCL:Job Control Language)```
利用者は、処理させたい一連の仕事を指示書をとしてまとめてコンピュータに投入する。
この一塊の仕事の単位を```ジョブ```という。

## 気づき
バッチファイルは```ジョブ制御言語```が使われているのかな。
```バッチ処理```と```ジョブ管理```の違いがわからない。
バッチファイルを登録してコンピュータを遊ばせずキリキリ働かせる仕組みを```ジョブ管理```
```バッチ処理```は後から説明されるらしい。
とりあえずまとめて命令することで無駄を無くすのか。

# ジョブ管理の流れ
ジョブ管理は、カーネルが持つ機能の一つ。
バッチ処理を次々登録しておいて、```コンピュータを遊ばせずにキリキリ働かせる仕組み```をジョブ管理という。
利用者はバッチファイルの塊を登録したものを管理プログラムに対して渡す。
## マスタスケジューラとは？
利用者との間を橋渡しするのが```マスタスケジューラ```という管理プログラム。
この管理プログラムに対して、ジョブの実行（バッチファイルの実行）を依頼します。

この管理プログラム```マスタスケジューラ```はジョブの実行を```ジョブスケジューラ```に依頼する。
マスタスケジューラは```実行状態の監視```、必要に応じて各種```メッセージを利用者に届ける```。
## ジョブスケジューラとは?
ジョブの実行を依頼されたジョブスケジューラは以下の流れでジョブを実行して行きます。

### リーダ
依頼されたジョブを入力して、```ジョブ待ち行列に登録```する。

### イニシエータ
優先度の高いジョブを持ってきて、```ジョブステップ```に分解します。
CPUや主記憶装置など、ハードウェア資源が```空くのを待って```、ジョブステップを割り当て、```その実行をタスク管理に依頼```します。

### ターミネータ
実行を終えたジョブに割り当てられていたハードウェア資源を```解放```して、```ジョブの結果を出力待ち行列に登録```。

### ライタ
```優先度の高いもの```から順に、```ジョブ結果を出力```します。

### 気づき
マスタスケジューラはジョブスケジューラの監視、利用者に対してメッセージを届ける。
ジョブスケジューラはマスタスケジューラから依頼されたジョブを
* リーダでジョブを登録
* イニシエータでジョブを一つ一つ分解する。
* それをタスク管理に依頼
* 実行が終わった後ターミネータで出力待ち行列に登録
* ライタで優先度の高いものから順にジョブの結果を出力する。

ジョブスケジューラで実行から出力までできるのか。

## スプーリング
CPUと入出力装置とでは、処理速度に大きさが出る。
入出力データを一旦```高速な磁気ディスクへと蓄える```。
例えば印刷データを磁気ディスクに書き出したら、CPUはさっさと次に処理に移る。
その分```無駄な待ち時間は削減できる```。
* 低速な装置とのデータのやり取りを、高速な磁気ディスクを介して行うことで処理効率を高める方法を```スプーリング```という。
* ```一時的な出力領域をスプール(SPOOL）```と言いスプールを使った入出力をスプーリングという。
スプーリングを使うと、CPUの待ち時間を削減することができる。そうすると```単位時間あたりに処理できる仕事量を増やす```ことができる。
単位時間あたりに処理できる仕事量を```スループット```と呼ぶ。

### 入力の場合
入力データを磁気ディスクに一時的に蓄える。必要となったらCPUがそのデータを取る。
### 出力の場合
出力データを一時的に蓄えておいて後で印刷させる。

### 気づき
結果を溜め込まなければいけないくらい
CPUと入出力装置の間の処理スピードが違うのか。
いかにCPUに隙を与えず仕事をさせることが高速処理の鍵になってくるのか。

# 問題を解いた時の気づき
### バッファ
IT分野では、コンピューターが```処理しきれないデータを一時的に保持しておく```ための記憶領域を指し、```「緩衝記憶領域」```とも呼ばれる。コンピューター内部の入出力装置や制御装置などでは、装置ごとに処理速度の差があるため、装置間でデータをやりとりするとタイムラグが生じる。そこで、```処理速度や転送速度の差を緩和```させ、それぞれの処理速度に合わせたデータの保管や送信を行う必要があり、バッファはその役目を果たしている。

例えば、パソコンにつないだプリンターで印刷する場合、パソコンからプリンターへ印刷データを送信する速度と、プリンターで印刷データを出力する速度には差がある。そのため、プリンターにバッファ用のメモリー（記憶装置）を搭載し、そこに印刷データを一時的に保存しておくことで、印刷の進行状況に応じてバッファからデータを取り出して印刷できるようになる。
出典 https://mypage.otsuka-shokai.co.jp/contents/business-oyakudachi/words/buffer.html

正式には```「バッファメモリー」```ですが、略して「バッファ」と言われます。
出典 https://www.unchi-co.com/kaigyoblog/kigyo_kaigyo/buff.html

バッファとは、コンピュータが即座に```処理しきれないデータを一時的に保持しておくための記憶領域を指す```意味で用いられる語である。
出典 https://www.sophia-it.com/content/%E3%83%90%E3%83%83%E3%83%95%E3%82%A1

ディスクキャッシュに関してメモリと補助記憶装置との間の速度緩和装置(造語、あるかわからない）としか認識していない。
もっと勉強が必要だ。

入出力装置とCPUに処理速度の差があるため入出力結果をためてCPUの処理速度をあげようとしている。

# 出典 
https://gihyo.jp/book/2022/978-4-297-12375-8

https://gihyo.jp/book/2020/978-4-297-11781-8
<Rails>scopeの引数のブロック内にメソッドが定義されている場合の挙動

# はじめに

Railsのソースコードにて

```ruby
class Shirt < ActiveRecord::Base
   scope :red, -> { where(color: 'red') } do
     def dom_id
       'red_shirts'
     end
   end
end
```

というコメントアウトを発見。

https://github.com/rails/rails/blob/main/activerecord/lib/active_record/scoping/named.rb#L117-L123

scopeの引数にブロックがあって、その中にメソッドが定義されている。初めて見る書き方だった。

調べてみても意外とどのような挙動をするのか書かれていないので、記事にしてみる。

# 第三引数のブロック内にメソッドを定義するとどうなるか

```ruby
class Post < ApplicationRecord
  scope :ids_less_than_five, -> { where('id < ?', 5) } do
    def hoge
      where(title: 'hoge')
    end
  end
end
```

このようなPostモデルがあったときに、以下のようなコードが書ける

```ruby
Post.ids_less_than_five.hoge
=> #<ActiveRecord::Relation [#<Post id: 2, title: "hoge", body: "おはようございます", created_at: "2022-05-31 08:32:00.964692000 +0000", updated_at: "2022-05-31 08:32:00.964692000 +0000", user_id: 5>]>
```

つまり定義したスコープに対して、チェーンできるメソッドをブロック内に定義することができる。

以下のようにPostに対してhogeメソッドを使うことはできない。

```ruby
Post.hoge
=> NoMethodError (undefined method `hoge' for Post:Class)
```

# 結論

- 定義したスコープにだけチェーンできるメソッドを作れる
- 小分けにクラスメソッドやスコープにした方が使い勝手がいいのであまり使い道がない？？（使い道があったら教えてください、、）
MAC導入メモ

# はじめに
MACを新しいマシンに切り替えました。そのときの手順をメモしておきます。
「MAC版outlookメールファイルの移行」がネット上に情報が全然なかったので、地味に他の方の参考になるかもです。

## ネットワーク設定
自宅用Wifi、ディザリング

## Apple ID登録

## gmail設定

## ATOK導入

https://mypassport.atok.com

からログイン

ATOKを導入したが、いきなりメニューにATOKがないという問題に遭遇し、ググって次の記事を見つける

https://support.justsystems.com/faq/1032/app/servlet/qadoc?QID=058242

(やっとこれで普通にPCが使えるようになった。いかに自分の体がATOK漬けになってしまっているか、改めて実感。。。)

## ブラウザ導入
firefiox、chrome

## アプリ導入
zoom

## MAC版outlookメールファイルの移行
移行前にすごくはまった箇所
インポートとエクスポートというメニューはあるが、グレーアウトしていて使えないのです。

結論としてoutlookを一時的に古いバージョンに戻せばいいのですが、この手順がまたわかりにくい。

下記の「新しい Outlook」のチェックボックスを外すというのが正解です。これに気づくのに何日もかかりました。。。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194151/c3fb6fce-2758-f7ca-c5cf-bffa5ddc7363.png' width=400>

ちなみに、古い版を新しいのに戻すときの設定は下記になります。こちらは、直感的でわかりやすいです。
新しいバージョンにモードを変えると、取り込んだメールは読めなくなります。このこと自体は、メールが見えている段階で、フォルダーごと別の場所に移動することで対応可能です。しかし、もっと重要な話があり、この後で説明します。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194151/a88b2c75-6bb2-cf34-9041-0908d90c4095.png' width=400>

### 今更対応不可能な重要な話
どうも、Mac版outlookで「エクスポート」->「インポート」したメールでは、「受信トレイ」にあったメールの移行が不完全なようです。
（タイトルは残っているが本文が読めない）
「アーカイブ」とか「送信済み」とか他のフォルダーのものはちゃんと本文も読めます。これは、今、気付いても手遅れな重要情報でした。。。



## MS Office系お節介オプションのOff
これ、いつも迷惑しています。最初に使う人向けにボタン一つでこれができるようにしてほしいです。

## 各種アプリの認証設定
twitter, facebook, linkedin, github
Facebookの設定をしていて気づいたが、元々使っていた二段階認証の方式がもうすぐ使えなくなるとのこと。こういう話は、もっと丁寧に教えてほしかった。。。

## 各種アプリの導入
mi, Jupyter Notebook, github desktop

Jupyter Notebookはやや手強いので、詳しめにメモ（参考にしたのは以下の記事）

https://parallelcareerlab.com/?p=2312

ダウンロードサイト
M1用のバイナリがあるので、それを利用する

https://docs.conda.io/en/latest/miniconda.html#macos-installers

ダウンロード後の手順(ターミナルから)

```
% conda config --remove channels defaults
% conda config --add channels conda-forge
% conda install jupyter -c conda-forge --override-channels
% conda install scikit-learn seaborn -c conda-forge --override-channels
% conda install shap -c conda-forge --override-channels
% conda install openpyxl -c conda-forge --override-channels
% pip install  japanize-matplotlib
```

## その他細かい設定

Finder -> 表示　-> タブバーを表示

Outlook -> Outlook -> アラームをオフにする

(2022-08-29 Homebrew未導入でした)

```
% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
% echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/masanori.a.akaishi/.zprofile
% eval "$(/opt/homebrew/bin/brew shellenv)"
% brew install postgresql
```

## もう一つ重要な変更 (2022-10-29追記)

下記のチェックをはずす修正も地味に重要です。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/135fc44f-d40b-8e01-2519-009f24c353cf.png' width=400>
Faker2.0 を使用したダミーデータの作り方

# Faker2.0 を使用したダミーデータの作り方

## Fakerとは

Flaker is a [Snowflake External Functions](https://docs.snowflake.com/en/sql-reference/external-functions-creating-aws.html) wrapper for the popular [Faker](https://github.com/joke2k/faker) python library. It means you can generate a vast array of fake data right from within Snowflake, in large quantities, very quickly and easily.

- ダミーデータが簡単に作成できる pythonライブラリ
- SnowflakeがPythonをネイティブサポートしたため, これまで以上に簡単にダミーデータを使用できるようになった模様

- 今回はサンプルにあるSQLをリリースし確認する
- 他のデータソースは[公式ドキュメント](https://faker.readthedocs.io/en/master/providers.html#)を参照のこと

## 使用方法

#### 1. 以下のクエリを実行する
```sql
--関数の作成
create or replace function FAKE(locale varchar,provider varchar,parameters variant)
returns variant
language python
-- キャッシュに残らないようにする
volatile
runtime_version = '3.8'
-- Anacondaパッケージ
packages = ('faker','simplejson')
-- Fake関数を呼び出す
handler = 'fake'
as
$$
import simplejson as json
from faker import Faker
def fake(locale,provider,parameters):
  if type(parameters).__name__=='sqlNullWrapper':
    parameters = {}
  fake = Faker(locale=locale)
  # 型があいまいの場合は文字型で統一する
  return json.loads(json.dumps(fake.format(formatter=provider,**parameters), default=str))
$$
;
```
#### 2. ダミーデータを出力する
- 50人のダミー個人名
```sql
select
	FAKE('en_US','name',null)::varchar as FAKE_NAME 
from
	table(generator(rowcount => 50));
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/851da720-f6f1-4cfa-89e7-1169cd28de78.png)

- 今日から180日前までの180個のダミー日にち
```sql
select
	FAKE('en_US','date_between',{'start_date':'-180d','end_date':'today'})::date as FAKE_DATE 
from
	table(generator(rowcount => 180));
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/35ad15a8-4cf2-6bed-9e1c-5e94b033bfde.png)


- 100人分の企業、職種、名前のダミーデータ
```sql
with FAKE_PROFILES as (
    select
        FAKE('en_AU','profile',{'fields':'name,job,company'}) as FAKE_PROFILE
    from
        table(generator(rowcount => 100))
    )
select
    FAKE_PROFILE:company::varchar as company,
    FAKE_PROFILE:job::varchar as job,
    FAKE_PROFILE:name::varchar as name
from
    FAKE_PROFILES;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/e6bac04a-8e9e-7478-210e-b43d9ab1b578.png)


# # 参考文献

- [Faker](https://faker.readthedocs.io/en/master/index.html)
- [Faker GitHub](https://github.com/jamesweakley/flaker)
【Google App Script】スプレッドシートのデータを配列として取得する方法

GoogleAppScriptを使って、Googleスプレッドシートにデータを出力することは、よくあると思います。
それとは逆に、Googleスプレッドシート上のデータを使って、GoogleAppScriptで処理を行うことも、同様にありますね。

今回はGoogleスプレッドシートの列データを対象に、GoogleAppScriptの配列データとして扱う方法を解説します。

# セル範囲を取得 ~ getRange()
まずは、取得したいデータの対象セル範囲を特定します。
事前に取得したSheetオブジェクトに対して、**getRangeメソッド**を使い、**Rangeオブジェクト**の形で取得します。
構文は以下の通りです。

~~~syntax.gs
Sheetオブジェクト.getRange(開始行番号, 開始列番号, 行数, 列数);
~~~

実際のサンプルは以下のようになります。
~~~sample1.gs
function myFunction() {
  // 2行目,1列目（A2セル）を開始位置として、3行分を範囲として取得
  // 列数は省略されているので、デフォルトの1列となる
  range = sheet.getRange(2, 1, 3);
}
~~~

行数の指定として、「シート上に存在する最後のデータまで」の条件で指定したいことが多いと思います。
その場合は、別の記事で紹介した**getLastRowメソッド**を使用した、以下の形式が便利です。
~~~sample2.gs
function myFunction() {
  // 2行目,1列目（A2セル）を開始位置として、3行分を範囲として取得
  // 列数は省略されているので、デフォルトの1列となる
  range = sheet.getRange(2, 1, sheet.getLastRow()-1);
}
~~~

# 範囲データを配列として取得 〜 getValues()
上記で取得したRangeオブジェクトに対して、**getValues()メソッド**を使うことで、配列データとして取得できます。
構文は以下の通りです。

~~~syntax.gs
Rangeオブジェクト.getValues();
~~~

先程のsampleコードに対して適用する場合、以下のようになります。

~~~sample.gs
function myFunction() {
  range = sheet.getRange(2, 1, 3);
  list = range.getvalues();
}
~~~

このコードを、以下のサンプルのスプレッドシートに対して適用してみましょう。

### 対象のスプレッドシート例
![スクリーンショット 2022-08-01 14.24.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727639/9a600664-f812-7623-7e2e-603454b150fe.png)

取得結果はこちら。

~~~result.log
[['A2'],['A3']]
~~~

残念ながら、2次元配列の形で取得されています。
今回は1列のデータなので、1次元配列で扱いたいという場合は、繰り返し処理を噛ませて展開してあげる必要があります。
こんな感じになります。

~~~sample2.gs
function myFunction() {
  range = sheet.getRange(2, 1, 3);
  list = range.getvalues();

  // 整形後データを格納するための、空配列
  list_new = [];
  // 2次元配列を展開して、空配列に1次元データとして格納
  for(var i=0;i<list.length;i++){
   list_new.push(list[i][0])
  }
}
~~~


# 参考記事
https://tonari-it.com/gas-spreadsheet-column-data-array/
Nginxでhtml表示する方法

# はじめに
Apacheでhtml表記はできましたが、
Nginxでのhtml表記に少し手こずったため記録します。
※日本語の文字化けも解決

# 仕様
- Linux
- Amazon-linux2
- nginx

# Nginxのインストール
```
# yum search nginx
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
=================================== N/S matched: nginx ====================================
pcp-pmda-nginx.x86_64 : Performance Co-Pilot (PCP) metrics for the Nginx Webserver

  Name and summary matches only, use "search all" for everything.

# amazon-linux-extras list | grep nginx
38  nginx1                   available    [ =stable ]

# amazon-linux-extras info nginx1
nginx1 recommends nginx                      # yum install nginx

# sudo amazon-linux-extras install nginx1
```
インストールが始まり、問題なく終われば
Nginxのインストール完了。
# Nginx起動確認
```
# sudo systemctl start nginx
# sudo systemctl status nginx
# sudo systemctl enable nginx
```
問題なく起動していればOK。

# htmlファイル作成
```
# cd /usr/share/nginx/html
# sudo vi 好きなファイル名.html
# sudo systemctl restart nginx
```
NginxはApacheとはhtmlのファイル位置が違う。
viでファイル内編集。
ファイル内を編集した後は
Nginxをrestartして
「http://パブリックIP/好きなファイル名.html」にアクセス。

# 日本語が文字化けした場合
作成したhtmlファイルが文字化けしていた場合、
Nginxの設定ファイルに
下記を追加すると、解決される。
※「nginx.conf」は/etc/nginx下にある。

```php:nginx.conf
include             /etc/nginx/mime.types;
default_type        application/octet-stream;
charset UTF-8;
```
```
# sudo systemctl restart nginx
```
再起動で、日本語の文字化けが解決された！！
【備忘録】Rustでwasm-pack buildしてnpm run startした時にdigital envelope routines::unsupportedのエラーが出た時の解決法【WebAssembly】

## 背景

RustでWebAssemblyをやってみたいと思い、[こちら](https://rustwasm.github.io/docs/book/game-of-life/hello-world.html)を参考に進めていました。

特にバージョンなど明記がないのですが、2022.0801現在の環境で進めた時にエラーが発生したため、備忘録として残しておきます。

## 環境

```
node: v17.0.1
npm: 8.15.1
```

## 詰まったところ

`npm install`まで終えて、`npm run start`を実行したところ、エラーが出てWebサーバが起動できませんでした。

エラーの内容は下記の通りです。
```
(node:58651) [DEP0111] DeprecationWarning: Access to process.binding('http_parser') is deprecated.
(Use `node --trace-deprecation ...` to show where the warning was created)
ℹ ｢wds｣: Project is running at http://localhost:8080/
ℹ ｢wds｣: webpack output is served from /
ℹ ｢wds｣: Content not from webpack is served from /Users/*/workspace/wasm-tutprial/wasm-game-of-life/www
node:internal/crypto/hash:67
  this[kHandle] = new _Hash(algorithm, xofLen);
                  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:130:10)

（中略）

    at FSReqCallback.readFileAfterClose [as oncomplete] (node:internal/fs/read_file_context:68:3) {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
```

## 原因
簡単に言うと、Node.js v17 以降で OpenSSL 3.0 まわりでハッシュ関数の設定が変わったらしいです。~~よくわかりませんが……~~

使ってるモジュールが OpenSSL 3.0 に対応してないために弾かれているようです。

## 解決法

主に下記の方法で対応できます。

* オプションで`--openssl-legacy-provider`をつけて実行する
* `export NODE_OPTIONS=--openssl-legacy-provider`として環境変数を設定しておく
* `webpack.config.js` に`output.hashFunction: "xxhash64"`を追加する


## 参考文献
* https://github.com/gh640/nextjs-blog-example-ja/issues/49
* https://qiita.com/cnloni/items/1c83cac956599fb24158
* https://nodejs.org/en/blog/release/v17.0.0/#openssl-3-0
「ド・モアブルの定理(De Moivre's formula)」をwolframalphaとsympyで証明したい。

**以下は、「ド・モアブルの定理」の証明になりますか？**

オリジナル

https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%BB%E3%83%A2%E3%82%A2%E3%83%96%E3%83%AB%E3%81%AE%E5%AE%9A%E7%90%86

https://en.wikipedia.org/wiki/De_Moivre%27s_formula

# wolframalphaで
https://www.wolframalpha.com/input?i=+%28cos%28k%CE%B8%29%2Bisin%28k%CE%B8%29%29%28cos%CE%B8%2Bisin%CE%B8%29&lang=ja

別の形
cos(θ (k + 1)) + i sin(θ (k + 1))

# sympyで

```python
from sympy import *
var('k θ')
yk=I*sin(θ*k)+cos(θ*k)
y1=I*sin(θ*1)+cos(θ*1)
print("#",yk)
print("#",y1)
print("#",(yk*y1).trigsimp().simplify().rewrite(exp,sin,cos))
# I*sin(k*θ) + cos(k*θ)
# I*sin(θ) + cos(θ)
# I*sin(θ*(k + 1)) + cos(θ*(k + 1))
```

# 入試問題
＞　数学的帰納法

http://kamelink.com/blog/2022/07/29/1-9-20-kouritutitosekagidai-rikou-2/

＞　sin(7θ)

https://mathexamtest.web.fc2.com/2016/201611311/2016113110100mj.html#top-0107

# 内部検索

https://cse.google.com/cse?cx=a8908fbc24340ebc5&q=%E3%83%89%E3%83%BB%E3%83%A2%E3%82%A2%E3%83%96%E3%83%AB&oq=%E3%83%89%E3%83%BB%E3%83%A2%E3%82%A2%E3%83%96%E3%83%AB&gs_l=partner-web.12..0i512l10.1946.1946.0.3919.1.1.0.0.0.0.139.139.0j1.1.0.csems%2Cnrl%3D10...0....1.34.partner-web..0.1.139.P1B2lwwvC88

http://kamelink.com/blog/tag/%e3%83%89%e3%83%bb%e3%83%a2%e3%82%a2%e3%83%96%e3%83%ab%e3%81%ae%e5%ae%9a%e7%90%86/

https://www.google.com/search?q=site%3A%2F%2Fmathmathmass.exblog.jp+%E3%83%89%E3%83%BB%E3%83%A2%E3%82%A2%E3%83%96%E3%83%AB&rlz=1CAUHAM_enJP1038JP1038&oq=site%3A%2F%2Fmathmathmass.exblog.jp+%E3%83%89%E3%83%BB%E3%83%A2%E3%82%A2%E3%83%96%E3%83%AB&aqs=chrome..69i57j69i58.3187j0j4&sourceid=chrome&ie=UTF-8

google検索

https://www.google.com/search?q=%E3%83%89%E3%83%A2%E3%82%A2%E3%83%96%E3%83%AB%E3%81%AE%E5%AE%9A%E7%90%86+%E5%80%8D%E8%A7%92&client=ms-android-huawei&sxsrf=APwXEdc-vhCIj_TtDsvwJnaWzGX8uzH6Lg%3A1684216648610&ei=SBtjZIbtJNHN-Qbf6ZtI&oq=%E3%83%89%E3%83%A2%E3%82%A2%E3%83%96%E3%83%AB%E3%81%AE%E5%AE%9A%E7%90%86+%E5%80%8D%E8%A7%92&gs_lcp=ChNtb2JpbGUtZ3dzLXdpei1zZXJwEAM6BAgAEEc6CQgAEAQQJRCABDoHCAAQBBCABDoGCAAQBBAeOgUIABCiBEoECEEYAFCtE1i6eGC4gQFoBXACeACAAcEIiAGYF5IBDTAuNy40LTEuMS4wLjGYAQCgAQHIAQrAAQE&sclient=mobile-gws-wiz-serp

# 文献

#### ドモアプル定理から倍角の公式を導け。

問題解法三角法辞典(昭和39年11月)
2772

問題解法解析幾何学辞典(昭和42年10月)
2333


# 未整理

https://www.wolfram.com/language/12/complex-visualization/complexplot-introduction.html.ja

https://stackoverflow.com/questions/52026962/plot-an-implicit-equation-with-a-complex-variable-in-sympy


https://math-fun.net/20211224/21139/
JavaScript コンソールのレヴェルの扱いの違い

JavaScript コンソール (`console.log()` など) は事実上の標準化が為されていますが，エラーレヴェルの扱いについては違いがあります。以下に表を示します。
## Firefox

| Level | 説明 | デフォルトで表示 | 特記事項 |
|-------|-----|----------------|--------|
| debug | `console.debug()` | **no** | アイコン無し |
| **log** | `console.log()` | yes | アイコン無し |
| info | `console.info()` | yes |
| warn | `console.warn()` | yes |
| error | `console.error()` | yes |

## Chrome

| Level | 説明 | デフォルトで表示 | 特記事項 |
|:------|:----|:--------------|--------|
| debug | `console.debug()` | **no** | アイコン無し |
| **info** | `console.log()`, `console.info()` | yes | **アイコン無し** |
| warn | `console.warn()` | yes |
| error | `console.error()` | yes |

## Safari

| Level | 説明 | デフォルトで表示 | 特記事項 |
|-------|-----|----------------|--------|
| **debug** | `console.debug()` | **yes** | **breakpoint アイコン** |
| **log** | `console.log()` | yes | **log アイコン** |
| info | `console.info()` | yes | info アイコン |
| warn | `console.warn()` | yes | warn アイコン |
| error | `console.error()` | yes | error アイコン |

ただし，Safari ではこれらのログが All，Errors，Warnings，Logs の3段階でフィルタ可能です。それぞれのフィルタレヴェルで表示されるログは以下の通りです：

| フィルタレヴェル | 表示されるログ |
|---------------|--------------|
| All | error, warn, info, log, debug |
| Errors | error |
| Warnings | warn |
| Logs | info, log, debug |

Safari ではこの他にも， Evaluations (コンソールに入力した式の評価結果) もフィルタ可能です。
GitLab 修正、プッシュ、マージリクエストの流れ

# GitLabでのマージリクエストの手順
マージリクエスト⇒GitHubでいうプルクエストのこと

---
1git clone
2ブランチ作成（移動）
3ファイル修正
4プッシュ
5マージリクエスト

---

## 1 git clone 
※ディレクトリ毎でしたclone出来ない
⇒ファイル単位でのclone×

```
git clone URL（git@X.X.X.X~~~）
URLはgitlabのブラウザ上で確認できる
```

## 2 ブランチ作成（移動）
```
git checkout -b ブランチ名
ブランチを作成して移動するコマンド
```

## 3 ファイル修正
Viコマンドなどで直接修正したり、統合開発環境などで修正

## 4 プッシュ
```
git add .
git commit -m "修正内容の説明"
git push origin ブラウザ名
```


## 5 マージリクエスト
①ブラウザの画面で操作する。
②左サイドバーの「ブランチ」をクリック
③対象のブランチを選択
④「マージリクエスト」をクリック
⑤「作成マージリクエスト」ボタンをクリック

## 6 マージリクエスト各種オプションの意味
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1193125/05ccfe60-e498-5053-21c5-cb6a4b11c3b4.png)

| オプション | 説明                                                                                            |
|:-:|:-:                                                                                                       |
|Assignee(※1)  |マージリクエストの責任者を割り当てます。（レビューする人）                                        |
|Reviewer(※1)  |マージリクエストのレビュワーを割り当てます。（レビューする人）                                    |
|Milestone |タイム・センシティブな変更を追跡します。                                                          |
|Time tracking   |マージリクエストに費やした時間です。                                                        |
|Labels   |マージリクエストをカテゴライズし、適切なイシューボードに表示します。                               |
|チェック項目||
|Delete source~|masterにマージされたらブランチを削除します。|
|Squash commits~(※2)|マージする際にスカッシュマージします。|

※1
基本は、assigneeとreviewerは同じ人になる。
【ユースケースの例】
大きなプロジェクトにおいてサブリーダーがreviewerを担当し、プロジェクトリーダーがassigneeを担当する。
プロジェクトリーダーはサブリーダーのコメントを受け、マージするか最終決定する。

※2
スカッシュマージ(圧縮マージ)とは...
ブランチ先でのすべてのコミットを１つにまとめて、現在チェックアウトしているブランチにステージングすること。
バットケース　マージコミットを検知して動作するツール等を利用している場合影響が出てしまう可能性がある。


## 公式ドキュメント
https://gitlab-docs.creationline.com/ee/user/project/merge_requests/creating_merge_requests.html
arm64 プログラミング

x86_64: [x86_64 プログラミング](https://qiita.com/k0kubun/items/99b53fcb3100c54b0069)

* 参考資料:
  * [Linux で Arm64 アセンブリプログラミング](https://www.mztn.org/dragon/arm6400idx.html)
  * [Arm64 Assembly Language](http://nw.tsuda.ac.jp/lec/arm64/mac_m1/)

# 文法
```nasm
mov w0, #5
```

右から左に代入される。

## メモリアクセス
`[x0]` はx0のアドレスのメモリを読む。[Arm64 Assembly Language](http://nw.tsuda.ac.jp/lec/arm64/mac_m1/)の「A64 メモリアドレッシング」のところを見てしまうのが早い。

## レジスタ
* 汎用レジスタ: 64bit 29個。X0-X29 (64bit) または W0-W28 (32bit)。
* フレームポインタ(FP): 汎用レジスタX29
* リンクレジスタ(LR): 汎用レジスタX30。関数呼出命令(BL)の実行後、戻り番地が入る。
* スタックポインタ(SP): 汎用レジスタX31。16バイトalign。
* FPUレジスタ: 128bit 32個。V0-V31 (128bit)。FPU命令からは64-bit以下でしかアクセスできない。 D0-D31(64bit), F0-F31(32bit), H0-H31(16bit), B0-B31(8bit)。

### プレフィクス
* `X`: 64bit (例: X0)
* `W`: 32bit (例: W0)

### スタック
TODO

## 関数呼び出し
* 関数呼出しでは、整数の実引数は8個まではレジスタ(X0-X7 or W0-W7)に入れて、それ以上はスタックに積んで渡す。
* 関数呼出しでは、実数の実引数は8個まではレジスタ(V0-X7)に入れて、それ以上はスタックに積んで渡す。
* 関数呼出の返り値はX0 (W0) に入れて返す。構造体を返す場合は、構造体のアドレスをX8に入れて返す。浮動小数点数の場合は V0に入れて返す。
* 関数呼出しでは、X0-X18の値は保存されない(volatile)。X19-X29とSP(X31)は保存する必要がある(non-volatile)。
* 関数呼出しでは、V0-X7およびV16-V31の値は保存されない(volatile)。V8-V15は保存する必要がある(non-volatile)。

## 命令
TODO

### 命令サフィックス
TODO

# 開発環境
## 実行方法

```nasm:a.s
.globl _main
.p2align 2
_main:
    mov	w0, #0
    ret
```

```bash
$ clang a.s
$ ./a.out
```
EC2インスタンス内のMySQLをdumpしてS3に保存する

## 概要

- 対象
EC2にMySQLを配置しており、バックアップを定期的に実行したい人
- ざっくりとした流れ
MySQLのdumpファイルを作成し、S3に保存するシェルを作成
cronで上記のシェルを定期実行する



## mysqldumpを実行するシェルスクリプト作成

※AWS CLIを利用するためのcredentialsは登録済みと仮定します。
```bash
#!/bin/sh

# dumpの実行結果を保存するファイルパスを指定
filename=~/test.sql
database=[DBの名前]
mysqldump -u root --quote-names --skip-lock-tables --single-transaction --flush-logs --master-data=2 $database > $filename

aws s3 cp $filename s3://[backet_name]
# s3にアップロードした後、ローカルからdumpファイル削除
rm $filename

```

試しにこのシェルを実行しようとしたところ、
`mysqldump: Error: Binlogging on server not active`
といったエラーが発生し、うまく動かないということがあるかと思います。

その時は/etc/my.cnfを編集します。

```/etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=1
```

`log-bin`に任意の名前を設定し、server-idを指定します。

また、mysqldump実行時にパスワードを要求されることがありますが、cronで実行することを想定する場合、パスワードなしで実行できるようにしたいです。

そこで、ユーザーディレクトリ配下に.my.cnfを作成し、以下の設定を記述します。

```~/.my.cnf
[mysqldump]
user='username'
password='password'
```

これで任意のユーザー名・パスワードを指定してあげれば、mysqldumpコマンドをユーザー指定・パスワード入力を求められずに実行できます。

## 定期実行

`crontab -e` を実行し、以下設定を追加
```
00 9 * * 1-5 [dumpを実行するシェルのパス]
```

cronの実行時刻は各自好きなように設定してください！
EC2ではデフォルトでタイムゾーンがUTCとなっているので、月曜から金曜の日本時間18時に実行したい場合は以上のように記述します。

## 参考
[【MySQL】EC2インスタンスなどからデータをdumpする](https://blog.aiandrox.com/posts/tech/2020/10/01/)
[MySQLのバイナリログとレプリケーションとserver-idの関係](https://ybalexdp.hatenablog.com/entry/mysql-binlog)
[mysqldumpをパスワード無しで使う方法](https://www.masashi.org/blog/2018/05/16/mysqldump-without-password/)
x86_64 プログラミング

arm64: [arm64 プログラミング](https://qiita.com/k0kubun/items/72d7e8c05eef14b00228)

* 参考資料:
  * [アセンブラに手を出してみる](https://qiita.com/edo_m18/items/83c63cd69f119d0b9831)
  * [x86_64 プログラミング入門](https://tanakamura.github.io/pllp/docs/asm_language.html)
  * [x86_64 機械語入門](https://tanakamura.github.io/pllp/docs/x8664_language.html)
  * [x86-64のCalling Convention](https://freak-da.hatenablog.com/entry/2021/03/25/172248)

# 文法
## 構文
### AT&T

```
sub $0x8, %rsp
```

* `%` がついていればAT&T。
* 右オペランドに代入される。
* `gdb` や `objdump -d` はこの出力
* GCCのインラインアセンブラでも使える

### Intel

```
sub rsp, 8
```

* 左オペランドに代入される。
* libcapstoneではこちらが使われていそう。
* `objdump -M intel -d` するとこっちが出せる。
* `gdb` でも `set disassembly-flavor intel` すると使える。

## メモリアクセス
### AT&T

```
mov 0x10(%rbx), %r15
```

括弧 `(` `)` がつくとメモリアクセスになる。括弧の前の数字がオフセットになっており、この場合は `RBX + 16` の位置がアクセスされている。

### Intel

```
mov DWORD PTR [ebx], 2
```

という感じで書くらしい。size directiveを指定しない場合は推論される。

## レジスタ
[Registers in x86 Assembly](https://www.cs.uaf.edu/2017/fall/cs301/lecture/09_11_registers.html) を見た方が良い。

* rax : 汎用レジスタ
* rbx : 汎用レジスタ
* rcx : 汎用レジスタ
* rdx : 汎用レジスタ
* rsi : 汎用レジスタ
* rdi : 汎用レジスタ
* rbp : 汎用レジスタ
* rsp : 汎用レジスタ兼スタックポインタ
* r8 : 汎用レジスタ
* r9 : 汎用レジスタ
* r9 : 汎用レジスタ
* r10 : 汎用レジスタ
* r11 : 汎用レジスタ
* r12 : 汎用レジスタ
* r13 : 汎用レジスタ
* r14 : 汎用レジスタ
* r15 : 汎用レジスタ
* rip : プログラムカウンタ
* eflags : フラグレジスタ
* cs : セグメントレジスタ
* ss : セグメントレジスタ
* ds : セグメントレジスタ
* es : セグメントレジスタ
* fs : セグメントレジスタ
* gs : セグメントレジスタ

### プレフィックス
* `e`: 32bit (例: %eax)
* `r`: 64bit (例: %rax)

### スタック関連
* %rbp: ベースポインタ。元のスタックポインタが入っている
* %rsp: スタックポインタ。デクリメントしてスタックを拡張する。

## 関数呼び出し
x86_64 で用いられる呼び出し規約は2種類ある。

* System V AMD64 ABI: Linux, macOS, FreeBSD, Solaris
* Microsoft x64 calling convention: Windows

### System V AMD64 ABI
* 引数:
  * 整数, ポインタ: RDI, RSI, RDX, RCX, R8, R9
  * 不動小数点: XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7
  * 残りはスタック。右から左にスタックに積む。
* 返り値:
  * 整数64ビットまで: RAX
  * 整数128ビットまで: RAX & RDX
  * 不動小数点: XMM0 & XMM1
* caller/callee-save
  * RBX, RSP, RBP, R12–R15: non-volatile (= callee save)
  * RAX, RCX, RDX, RSI, RDI, R8-R11, XMM0-XMM15, YMM0-YMM15, ZMM0-ZMM31: volatile (= caller save)
* システムコールでは RCX の代わりに R10 を使用

## 命令

* [x86 and amd64 instruction reference](https://www.felixcloutier.com/x86/)
  * 一番見やすいかも
* [General-Purpose Instructions (x86 Assembly Language Reference Manual)](https://docs.oracle.com/cd/E19120-01/open.solaris/817-5477/6mkuavhs7/index.html)
  * Intel/AMD Mnemonic を見る。

### cmp命令
ステータスフラグ `ZF`, `CF` を更新する。

### 命令サフィックス
* `b`: 1バイト (8bit)
* `w`: 2バイト (16bit)
* `l`: 4バイト (32bit)
* `q`: 8バイト (64bit)

メモリをオペランドに取るときは必ずサフィックスが必要。

# 開発環境
## 実行方法
Intel構文を使いたい場合は `.intel_syntax noprefix` を書く。

```nasm:a.s
.globl main
main:
    mov $0, %rax
    ret
```

```bash
$ gcc a.s
$ ./a.out
```

## gdb
### レジスタの値を見る
```
p/x $rdi
```

などすると %rdi がhexで見れる。 `*(void **)($rsp + 0x10)` とすると `0x10(%rsp)` が見れる。

### アセンブリレイアウト
* `layout src`: Cのソース
* `layout split`: Cのソース + アセンブリ
* `layout asm`: アセンブリ
* `layout regs`: レジスタ + Cのソース or アセンブリ (直前のlayoutに依存)

`C-x o` でウィンドウ切り替えで、↑↓でスクロール。`C-x a` で閉じたり入ったりできる。

## objdump
### asmを眺める
```
objdump -d a.o
```

`.text` が出てくる。

### デバッグ情報を混ぜる

```
objdump -dS a.o
```
CloudStorageからダウンロードしたファイルの中身を取得

GCPのCloudStorageに設置されたバケット内にあるファイルの内容を取得する方法について説明します。
CloudSDKの[ライブラリ](https://www.npmjs.com/package/@google-cloud/storage)を使用して以下のコードで取得が可能です。


```Node.js
import { Storage } from '@google-cloud/storage';
const bucketName = 'test-qiita-bucket';
const fileName = 'test-file.txt';
storage = new Storage();
const data = await storage.bucket(bucketName).file(fileName).download();
const contents = data[0].toString();
console.log(contents);
```


```qiita:出力(ファイル内容)
test1
test2
```

<参考ページ>
[googleapis/nodejs-storage Public](https://github.com/googleapis/nodejs-storage/blob/main/samples/downloadFile.js)
オブジェクト(Generics・総称型)を使用して未知のクラスのメンバ変数を列挙する

# Generics・総称型を使用して未知のクラスのメンバ変数名とメンバ変数の中身を列挙します

``` java
public class Hoge {
    public static void report(Object input_row) throws IllegalArgumentException, IllegalAccessException {
    	for(Field field: input_row.getClass().getFields()) {// publicメンバだけ
        //for(Field field: input_row.getClass().getDeclaredFields()) { // 全てのメンバ
    		//field.setAccessible(true); // これが必要な場合もあるらしい
    		System.out.println("###: " + field.getName() + " : " + field.get(input_row));
    	}
    }
}
```

## field.setAccessible(true); について
こちらのサイトより
https://www.glamenv-septzen.net/view/449#id45308a

> Test5.javaでIllegalAccessExceptionが発生したのは、Java言語のアクセス制御チェックがprivateなのでアクセス不可能と判定>したからである。
> java.lang.reflectパッケージには Field の他に Constructor, Method というクラスが用意されているが、これらは java.lang.reflect.AccessibleObject というクラスを基底クラスとしている。
> そして AccessibleObject クラスには、対象Field/Constructor/Methodに対するアクセス制御チェックの有効/無効を設定する setAccessible(boolean) というメソッドがある。
> setAccessible(true)とすることで、アクセス制御チェックを抑制し、privateなメンバも外部からアクセスできるようになる。

とのことで field.get でExceptionが起きるパターンもあるので覚えておいたほうが良いと思います

## 作成中やらかしたミス
Exception の handle をしなかったためビルドが通らなかった

``` java
public static void report(Object input_row) throws IllegalArgumentException, IllegalAccessException {
```

こうすべき箇所を

``` java
public static void report(Object input_row) {
```


こう書いていたのでビルドが通らず結構な時間悩んでました
Javaの基本なのでなにやってんだという感じではあります
unhandled ～～ Exception とメッセージが出ていたのでちゃんとメッセージ読もうねという話でした


以上です
Rails6 × Docker × MySQL × M1 Macでherokuデプロイ


現在、制作中のRailsアプリのHerokuデプロイに大苦戦しました。
何度もエラーに遭遇したのですが、その中の1つを記録として残しておきます。

環境
---
* M1 Mac
* Rails6
* MySQL バージョン5
* Docker

前提
---
本番環境DBはHeroku無料枠のMySQLを使用します。
HerokuでMySQLを使用する場合は無料枠でもクレジットカード登録が必要です。
詳しくは[こちら(Heroku公式)](https://devcenter.heroku.com/articles/cleardb)

Herokuデプロイに必要なファイル追加、DB追加、環境変数設定などは
[こちら](https://qiita.com/kenz-dev/items/8f95967601e587e14812)の記事を参考にさせて頂きました。

Herokuデプロイ
---
まず通常通りにコマンドを打っていきます。
dockerを使用しているのでContainer Registryにログインし、
imagesをpushする必要があります。

imagesをpushするのは結構時間がかかるので気長に待ちます。
今回、app名は、my-rails-appとします。

詳しくは[Docker使用でのデプロイ方法(公式)](https://devcenter.heroku.com/ja/articles/container-registry-and-runtime)

```
$ heroku container:login
$ heroku container:push web -a my-rails-app
$ heroku container:release web - a my-rails-app
$ heroku run rails db:migrate -a my-rails-app
```
### M1に起こるエラー

マイグレートをすると下記のようなエラーが出てきます。
```
Error: Exec format error
```

下記のコマンドで原因を探ってみます。
```
 $ docker inspect registry.heroku.com/my-rails-app/web

[
....
 "Architecture": "arm64",
 "Os": "linux",
....
]
```

色々と書いているかと思うのですが、下の方に
アーキテクチャが**arm64**と書いてあり、こちらがエラーの原因となっているようです。
dockerのimagesをプラットフォームと合わせる必要があるみたいです。
解決方法はいくつかあるようですが、今回はDocker BuildxというDockerのプラグインを使用し、
プラットフォームを指定します。（このあたりよく理解できていないです....)

エラー対処コマンド
---
``` 
docker buildx build --platform linux/amd64 -t my-rails-app .
docker tag my-rails-app registry.heroku.com/my-rails-app/web
docker push registry.heroku.com/my-rails-app/web
heroku container:release web -a my-rails-app
heroku open -a my-rails-app
```

上記コマンドで無事にherokuにデプロイできました！
理解が追いついてないので、もう少し深掘りし随時更新していきます(＠_＠;)