OmniAICreator/Qiita-1.07M huggingface dataset:
p35 Lake Counting

#### 感想
もっと簡単にできる部分はあった。8方向のところとか。
うまく再帰がつかえていたのでよかった
#### sample

```
※教科書確認
```


#### 自分(正解)

```

using System;
using System.Reflection;

public class Program
{

    public static void Main()
    {
        int n = 10;
        int m = 12;
        string str = "池";//入力めんどくさいからパス
        int res = 0;

        for (int i = 1; r <= n; i++)
        {
            for (int j = 1; r <= m; j++)
            {
                //現在地のポイントを取得
                point = field[i][j];
                if (point == "W")
                {
                    res += 1;
                    field[i][j] = ".";//現在地を. に変更
                    exec(i, j);//8方向確認しにいく
                }

            }
        }
        Console.WriteLine(res);

        void exec(int i, int j)//現在地の8方向に散らばる関数をまとめてる
        {
                check(i, j + 1);//上
                check(i, j - 1);//下
                check(i + 1, j);//右
                check(i - 1, j);//左
                check(i + 1, j + 1);//右上
                check(i - 1, j - 1);//左下
                check(i - 1, j + 1);//左上
                check(i + 1, j - 1);//右下
        }
        void check(int k,int l){//散らばった先で何をするのか
            point = field[k][l];
            if (point == "W")
            {
                field[i][j] = ".";//現在地を. に変更
                exec(k, l);
            }else {
                return;//みた先の方向が"."ならそれ以上探す必要なし
            }

        }
    }

}
```
トーナメント表作成HTML(まとめ)

## はじめに
この記事はまとめページの予定です。
内容を小分けにして各ページでコード及び簡単な解説をつけたいと思います。
最終的には以下のようなものができます↓。

![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/53052db4-c2e8-3f4d-c510-a2e729b63fef.gif)


## リンク
各ページのリンクです
番号順に見ていけば混乱なく読める…と、思いたいです。

１. [実装機能イメージ、ベースのHTML](https://qiita.com/hujinori/private/35c085d386fe289badcd)

https://qiita.com/hujinori/private/35c085d386fe289badcd

２. [Canvas(HTML5)の操作](https://qiita.com/hujinori/private/f5d4ff2ecd41f7788ab8)

https://qiita.com/hujinori/private/f5d4ff2ecd41f7788ab8

３. [トーナメント表の構築(DOM要素の配置)](https://qiita.com/hujinori/private/0a89287f9877de9933a4)

https://qiita.com/hujinori/private/0a89287f9877de9933a4

４. -工事中-[トーナメント表の構築(セレクトボックスの配置)]()
５. -工事中-[トーナメント表の線引き]()
６. -工事中-[トーナメント結果のファイル保存･読込-工事中-]()
７. -工事中-[その他細々とした機能]()


順次作成更新出来たらなと思います。

なお、本人は作成時に設計メモを以下しか残してないので、お察しです。

<img width="300" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/063d3e29-5253-bde8-8677-55738e8eaa22.png">
<img width="300" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605465/4bfe95d5-b2f1-6eea-e82e-234ee31bdb0c.png">
VSCodeの定型文（スニペット）を自作して、p5jsやVueをすぐに書き始められるようにするメモ

## 目標はこんな感じ

[![Image from Gyazo](https://i.gyazo.com/f76d2cb862fea9676ab05c945e41f0c3.png)](https://gyazo.com/f76d2cb862fea9676ab05c945e41f0c3)

index.htmlを新規作成後、`p5` と入力したら候補が出てきて、それを選択すると

[![Image from Gyazo](https://i.gyazo.com/0d904a4952b874cad14fe0a594a3e662.png)](https://gyazo.com/0d904a4952b874cad14fe0a594a3e662)

いつも書く内容が一発ででてくるようにしたいです

[![Image from Gyazo](https://i.gyazo.com/5a7d4422e16c26a13f0c075cc0c86099.png)](https://gyazo.com/5a7d4422e16c26a13f0c075cc0c86099)

vueはこんな感じにしてます

## 設定方法

[![Image from Gyazo](https://i.gyazo.com/d6b5221ed186276f29c701c8e853b70c.png)](https://gyazo.com/d6b5221ed186276f29c701c8e853b70c)

Macであれば、Code > 基本設定 > ユーザースニペット

[![Image from Gyazo](https://i.gyazo.com/cbc69da911a8be7bb17534156b854ffa.png)](https://gyazo.com/cbc69da911a8be7bb17534156b854ffa)

すでに自分はいろいろ作っちゃってますが…`html.json`を選んで

[![Image from Gyazo](https://i.gyazo.com/40fa0021836cfe0464cde7b44b663ead.png)](https://gyazo.com/40fa0021836cfe0464cde7b44b663ead)

exampleがあるので、それに則ってvueやp5jsで最初必ず書くテンプレートを書いていきます
（ダブルクォートやらが面倒ですね、もっといいやり方あったら知りたいですが、一回っきりなので…）

### 自分の記述内容はこちら

```json
{
	// Place your snippets for html here. Each snippet is defined under a snippet name and has a prefix, body and 
	// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the 
	// same ids are connected.
	// Example:
	// "Print to console": {
	// 	"prefix": "log",
	// 	"body": [
	// 		"console.log('$1');",
	// 		"$2"
	// 	],
	// 	"description": "Log output to console"
	// }
	"vue": {
		"prefix": "vue-html",
		"body": [
			"<!DOCTYPE html>",
			"<html lang=\"en\">",
			"",
			"<head>",
			"  <meta charset=\"UTF-8\">",
			"  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">",
			"  <title>Document</title>",
			"</head>",
			"",
			"<body>",
			"  <div id=\"app\">",
			"",
			"  </div>",
			"",
			"  <script src=\"https://unpkg.com/vue\"></script>",
			"  <script>",
			"    const app = new Vue({",
			"      el: '#app',",
			"      data: {",
			"      },",
			"      mounted: async function () {",
			"      }",
			"    })",
			"  </script>",
			"",
			"</body>",
			"",
			"</html>"
		],
		"description": "Quick start vue"
	},
	"p5": {
		"prefix": "p5-html",
		"body": [
			"<!DOCTYPE html>",
			"<html lang=\"en\">",
			"",
			"<head>",
			"  <meta charset=\"UTF-8\">",
			"  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">",
			"  <title>p5</title>",
			"  <script src=\"https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.js\"></script>",
			"  <script src=\"https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/addons/p5.sound.min.js\"></script>",
			"  <script src=\"sketch.js\"></script>",
			"  <style>",
			"    html, body {",
			"      margin: 0;",
			"      padding: 0;",
			"    }",
			"  </style>",
			"</head>",
			"",
			"<body>",
			"</body>",
			"",
			"</html>"
		],
		"description": "Quick start p5"
	}
}
```

p5jsもヴァージョン変わったら更新しなきゃなやつですね
40 代おっさん GASのGmailAppクラスについて学ぶ

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## GmailAppクラス

GmailAppクラスとは
Gmailサービスの最上位に位置するトップレベルオブジェクト
新規のメッセージ送信、スレッドを検索、スレッドやメッセージをまとめて操作するなどのメンバーが提供されている。

＊GmailAppクラスの主なメンバーの図はさすがに作るのがきびしいので、参考資料の本を見ていただくか、ネットで調べください。

ちなみにこちらで書いてありました。
<https://for-dummies.net/gas-noobs/gas-japanese-reference-for-gmail/>

### 新規メッセージを送信する

新規メッセージを送信する場合
sendEmailメソッドを使う。

構文

```javascript
GmailApp.sendEmail(宛先, 本文, 本文[, オプション])
```

必須の引数
宛先のメールアドレス
件名
本文
これらを文字列で指定

オプションはパラメータをオブジェクトで指定する。

|オプション名|データ型|説明|
|-----------|--------|----|
|attachments|BlobSourcel[]|添付ファイルの配列|
|bcc|String|BCCに設定するメールアドレス|
|cc|String|CCに設定するメールアドレス|
|from|String|送信元メールアドレス(エイリアスとして設定されているアドレスのみ)|
|htmlBody|String|指定されている場合、受信側でHTMLメールを表示できる場合は本文の代わりに使用する|
|name|String|送信者名|
|noReply|String|送信したメッセージに返信不要の場合trueを設定する|
|replyTo|String|デフォルトの返信先メールアドレス|

bcc,cc,replyで複数のメールアドレスを指定する場合は、文字列内のカンマ区切りで指定
noReplyをtrueに設定すると、送信元の表示が
noreply@~
になる。

お試し
利用可能な実在アドレスを指定してください

```javascript
function tosiki() {
  const recipient = '×××××××@gmail.com';
  const subject = 'サンプルメール';

  let body = '';
  body += '利樹様\n';
  body += '\n';
  body += 'このメールは利樹が大好きだから送りました。\n';
  body += 'ご確認を！！\n';

  const options = {
    cc: '××××××××@gmail.com',
    name: 'GASからの送信'
  };

  GmailApp.sendEmail(recipient, subject, body, options);
}
```

自動送信メールツールを作ることも可能ですが一日あたり、100件ないしは1500件と言う制限があるみたいです。
正直十分ですが・・・・

### 下書きを作成

メッセージを確認するのであれば
createDraftメソッド
メッセージの下書きを作成するのみで、送信はしない。
確認後、手動で送信することも可能

構文

```javascript
GmailApp.createDraft(宛先, 件名, 本文[, オプション]
```

```javascript
function tosiki() {
  const recipient = '×××××××@gmail.com';
  const subject = 'サンプルメール';

  let body = '';
  body += '利樹様\n';
  body += '\n';
  body += 'このメールは利樹が大好きだから送りました。\n';
  body += 'ご確認を！！\n';

  const options = {
    cc: '××××××××@gmail.com',
    name: 'GASからの送信'
  };

  GmailApp.createDraft(recipient, subject, body, options);
}
```

Gmailの下書きを見ると作られているのが分かると思います。

## 参考資料

<https://www.amazon.co.jp/s?k=google+apps+script+%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80&adgrpid=110264232688&gclid=CjwKCAiA9aKQBhBREiwAyGP5lSl7AJJLCvOEHb4wQgMlyqW1fll5X8GDTT_Rkd1_soUAyIPMXQr26hoClHEQAvD_BwE&hvadid=553833563682&hvdev=c&hvlocphy=1009076&hvnetw=g&hvqmt=b&hvrand=4378489642044417389&hvtargid=kwd-594191211348&hydadcr=4106_13159878&jp-ad-ap=0&tag=googhydr-22&ref=pd_sl_2x1owglv0s_b_p52>
Vite/React/TypeScriptのプロジェクトを立ち上げるだけ

## 概要
題名の通り

---

## 略手順
1. initする
2. プロジェクト名を指定（今回はvite-test） 
3. reactを選択する
4. react-tsを選択する
4. 指定されたコマンドを打つ
4. 指定されたlocalhostにアクセスする

---

### 手順
1

```
$ npm init vite
```

---

2

```
$ npm init vite
? Project name: vite-test
```

---

3

```
✔ Project name: … vite-test
? Select a framework: › - Use arrow-keys. Return to submit.
    vanilla
    vue
❯   react
    preact
    lit
    svelte

```

---

4

```
? Select a variant: › - Use arrow-keys. Return to submit.
    react
❯   react-ts
```

---

5-1 : 出力されるコマンド

```
Scaffolding project in /Users/pauli-agile/Documents/Practice/vite-test...

Done. Now run:

  cd vite-test
  npm install
  npm run dev

```

---

5-2 : 出力されたコマンドを打つ

```
$ cd vite-test
$ npm install

added 88 packages, and audited 89 packages in 12s

8 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

$ npm run dev

> ownd_mirror@0.0.0 dev
> vite

Pre-bundling dependencies:
  react
  react-dom
  react/jsx-dev-runtime
(this will be run only when your dependencies or config have changed)

  vite v2.8.4 dev server running at:

  > Local: http://localhost:3000/
  > Network: use `--host` to expose

  ready in 389ms.
```

---

6
![スクリーンショット 2022-02-23 16.44.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1830441/70262820-32b1-f148-8532-5a1dd871c4fd.png)

---

終わり
WSL2のMySQLでroot@localhostに入れない問題を解決した備忘録

# 症状
WSL2にMicrosoftの指示に従ってMySQLを入れると

https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-database

```
mysql -u root -p
```
でいくらやってもrootuserでmysqlにログイン出来ない。（パスワードが使えないよぅとか言ってくる。インスコ時に入れたくね！？って思うんやけど）
ただし、
```
sudo mysql
```
ならば、ログインできる。

# 原因
とりまログインした状態で
```
mysql> select user,host, plugin FROM mysql.user;
```
をすると、
```
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| iroiro           | localhost | caching_sha2_password |
| root             | localhost | auth_socket           |
+------------------+-----------+-----------------------+
```
みたいな表示が出てくる。で、調べたところによると`mysql-community-server`のインストール時にrootのパスワードをUNIX socketベースの認証をすることができるらしく、それをやってしまっているために<strong>Linux側でrootユーザーならMySQLもrootユーザー</strong>という認証の仕方になってしまっている。

なので、いくら
```
SET PASSWORD
```
だのなんだのやっても、パスワードが変更したり出来ない。

# 解決方法
rootでログインした状態で以下のコマンドを実行する。
```
mysql>ALTER USER root@localhost IDENTIFIED WITH caching_sha2_password BY 'hogehoge';
```
hogehogeにはパスワードを入れる。終わり。

# 感想
今どきの人はみんなDocker使うから設定時点で多分パスワードとか入れるので、こんなこと起きないのかなぁと思いながら、またいつか自分が引っかかったときのために残しておくことにした。

# 追記
僕はNode.jsでMySQLを使うおうとして、このエラーにあたったわけだが
```
npm install mysql
```
でインストールされるmysqlを使うと今度は`caching_sha2_password`がサポートされていない。
ので、
```
npm install mysql2
```
をして、mysql2を使うと良い。

# 参考文献
https://www.chuken-engineer.com/entry/2020/09/04/074216

https://yoku0825.blogspot.com/2020/09/debian-ubuntumysqlroot.html
[serverless] デプロイ時に、At least one of the plugins defines a validation schema that is invalid.が発生

タイトルに記載のエラーが発生し、突如デプロイできなくなった。

# 発生したエラー

```bash
$ sls deploy
Environment: linux, node 16.8.0, framework 3.3.0, plugin 6.1.0, SDK 4.3.1
Docs:        docs.serverless.com
Support:     forum.serverless.com
Bugs:        github.com/serverless/serverless/issues

Error:
At least one of the plugins defines a validation schema that is invalid. Try disabling plugins one by one to identify the problematic plugin and report it to the plugin maintainers.

1 deprecation found: run 'serverless doctor' for more details
```

# 前提条件

以下のpluginをserverlessアプリケーションで使用していること。

```yaml
plugins:
  # Following two plugins are for Request Validation
  - serverless-reqvalidator-plugin
  - serverless-aws-documentation
```

その場合、この記事の対策で効果があると思います。

# 対策

言われた通りにしてみる。

```bash
$ sls doctor
1 deprecation triggered in the last command:

CLI options definitions were upgraded with "type" property (which could be one of "string", "boolean", "multiple"). Below listed plugins do not predefine type for introduced options:
 - ServerlessAWSDocumentation for "outputFileName"
Please report this issue in plugin issue tracker.
Starting with next major release, this will be communicated with a thrown error.
More info: https://serverless.com/framework/docs/deprecations/#CLI_OPTIONS_SCHEMA_V3
```

ふむ、ServerlessAWSDocumentation（`serverless-aws-documentation`）はもう使えないらしい。
serverless frameworkのバージョンが3以上だと、こうなるのかな。

試しにserverless frameworkのバージョンを2.5に戻して、

```bash
$ npm -g install serverless@2.5
```

その後再度デプロイしたらこの問題は出なくなったが、、、

調べてみたら、serevelessには、2.72.2というバージョンがある模様。
この辺でよさそう。

```bash
$ npm -g install serverless@2.72.2
```

を実行してからsls deployしても、デプロイに成功した。


# 補足

## 残った課題

とはいえ、以下のようにwarningが出ており、

```bash
$ sls deploy
 
 Serverless Warning --------------------------------------
 
  CLI options definitions were upgraded with "type" property (which could be one of "string", "boolean", "multiple"). Below listed plugins do not predefine type for introduced options:
   - ServerlessAWSDocumentation for "outputFileName"
  
  Please report this issue in plugin issue tracker.
 
Serverless: Packaging service...
```

このServerlessAWSDocumentationについては、この問題を回避する対策も取られていなさそうなため、遅かれ早かれ廃止しないといけないかも。。。

## serverless frameworkのバージョン一覧

https://github.com/serverless/serverless/releases
SQL サブクエリ・AS

##サブクエリ
SQLでは、クエリの中に他のクエリを入れることができます。この他のクエリをサブクエリと言います。2つ以上のクエリを1つにまとめることができるので、より複雑なデータを取得する際に使われます。

( )で囲むことで、サブクエリを使用できます。サブクエリの書き方は基本的に通常のクエリと同じですが、()内にセミコロン（;）は不要です。
セミコロン（;）はクエリの最後にだけ書くようにしましょう。

サブクエリを含むクエリの場合、サブクエリが実行された後、外側にあるクエリが実行されます。

```
SELECT カラム
FROM テーブル名
WHERE カラム > (
  SELECT カラム
  FROM テーブル名
  WHERE カラム = "文字"
);
```
####関数を率いた場合

```
SELECT カラム1,カラム2
FROM テーブル名
WHERE カラム1 > (
  SELECT 関数(カラム1)
  FROM テーブル名
);
```

##AS

ASを使うことでカラム名などに別名を定義することができます。
「カラム名 AS "名前"」で、カラム名に定義する名前を指定します。

```
SELECT 関数(カラム) AS "変更したい名前"
FROM テーブル名
```
RSpecでページのステータスコードを取得する

##ステータスコードを取得する前に
``Rspec``でのテストの際に``Capybara``を使ったテスト方法が主流だが、``Capybara``にはページのステータスコードを取得できない。そのためステータスの検証ができない。

>**Capybara**
テスト時に実際にブラウザを起動させて行うテストで、エラーがあったときにはエラー時のスクリーンショットを取ってくれる

##テストの設定
ステータスコードを取得するには、テストの設定を``driven_by(:rack_test)``に変えるだけで出来る。

※ ``driven_by(:rack_test)``を記述すると、Capybaraのテスト設定がオーバーライドされてしまい、スクリーンショットをとることができなくなるので注意。

```rb
require 'rails_helper'

RSpec.describe "Samples", type: :system do
  before do
    driven_by(:rack_test) # ここ
  end
end
```

権限を持たない``ユーザー（writer）``がアクセスするとステータスコードが``403``になるかを検証してみる。

```rb
require 'rails_helper'

RSpec.describe "Samples", type: :system do
  before do
    driven_by(:rack_test)
  end

  describe 'Writer' do
    before { login_as(writer) }
     it 'Current_page is 403 error page' do
       visit admin_categories_path
       expect(page).to have_content('You are not authorized to perform this action.'), '403エラーページが表示されていません'
       expect(page.status_code).to eq(403), 'ステータスコードが403ではありません'
    end
  end
end
```

``driven_by(:rack_test)``を使うとステータスコードを取得する``page.status_code``が使用できるようになる。

##参考記事
[RSpecでページのステータスコードを取得する方法](https://sakitadaiki.hatenablog.com/entry/2021/02/08/132250)
[OutSystems]コールバック関数を渡すと自動的にログを取ってくれるClient Action作ってみた

[前回の記事](https://qiita.com/shoji9x9/items/9d316baabbd6b2a49b3d)でClient Actionにはコールバック関数を引数として渡せることがわかったので、今回は実際に役立ちそうな処理を作ってみました。

# 作ったもの
## 引数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337041/b39bcd2d-90ce-80d0-33ff-bf331a1b0563.png)

* Function（Object型）：実際に実行したい関数
* Arguments（Text型）：その関数に渡す引数（JSON）
* Result（Long Integer型）：関数実行結果（今回は例ではテーブルに登録したレコードのid）

## メイン処理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337041/89adf551-bf2e-e165-dca1-d6eb0e98e0e8.png)

* 2行目で引数を与え関数を実行。どうもOutSystemsはこれをすぐに実行するのではなくPromiseとして非同期実行するようで戻り値はPromiseになります
* 4行目で関数の実行結果をPromiseResultから取得しています。おそらくOutSystemsはPromiseを作るときに次のような処理をしていてPromiseResultの中身が複雑ですが、一応この処理でテーブルに登録したレコードのidは取得できました（OutSystemsの内部仕様が変わればすぐに動かなくなりそうなコードですが）
* 7行目で[JavaScript API](https://success.outsystems.com/ja-jp/Documentation/11/Reference/OutSystems_APIs/JavaScript_API)を呼び出し、ブラウザのコンソールとGeneral Logに実行時間のログを出力しています

```JavaScript
new Promise(function(resolve) {
  var obj = {};
  // 実際に実行したい関数の呼び出し
  // objに色々追加
  resolve(obj);
})
```

# 使い方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337041/92eb2cbb-51b1-18c4-17d5-e56f50167220.png)

登録ボタン押下時に呼び出されるClient Actionの中で、登録処理を行うClient Action（もしくはServer Action）の代わりにCallWithLoggingを呼び出します。ここではCallWithLoggingの引数FunctionにProductCreateOrUpdate（Client Action）を設定しています。このようにすれば各ロジック（ProductCreateOrUpdateなど）はログのことを気にせず実装できますし、ログの保管先が変わったりした場合も修正するのはCallWithLoggingだけで済みます。

# 注意点
CallWithLoggingに汎用性を持たせるためArgumentsをJSONにしています。そのため本来ならばProductCreateOrUpdate（Client Action）の引数はProduct Entity型でいいのですが、CallWithLoggingを使うためにText型に変更する必要があります。ProductCreateOrUpdate（Server Action）も同様で、この中でJSONをProduct Entity型に変換しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337041/1ef00557-1030-5f56-f328-f55844ac31ee.png)

# CallWithLoggingは本当に使えるのか？
ここまで書いておいて何なのですが、正直CallWithLoggingはあまり使えない（役に立たない）と思います。既に書いた通りOutSystemsの内部仕様と密接になっていますしJSON変換も面倒です。ResultがLong Integer型なのも汎用性の観点で改良の余地があります。さらに実行時間測定するだけならLifeTimeで賄えると思います。ただ、別の用途で今回のパターンが役に立つことがあるかもしれません。思いついたらまた記事にしようと思います。
JavaのCollections.sort()使っての並べ替え(昇順、降順)

#目次
 - この記事を作成したきっかけ
 - 実際に作ってみる

#この記事を作成したきっかけ
Javaのソースコードの修正時、ソート処理に悩んだので今回の記事を作成した

#実際に作ってみる
###昇順

```:並べ替えるListを用意
//数値のリストを用意
List<Integer> list = new ArrayList<Integer>();
Random r = new Random();

for(int i = 0; i < 10; i++) {
	//0～99までの数値をランダムに設定
	list.add(r.nextInt(100));
}

System.out.println("ソート前：");

//リストを表示する
for(int i = 0; i < 10; i++) {
	System.out.print("[" + list.get(i) + "] ");
}
```


```:昇順にソートする
//昇順にソートする
Collections.sort(list);

System.out.println("\nソート後(昇順)：");

//リストを表示する
for(int i = 0; i < 10; i++) {
	System.out.print("[" + list.get(i) + "] ");
}
```

```:実行結果
ソート前：
[82] [79] [38] [63] [30] [65] [89] [97] [59] [68] 
ソート後(昇順)：
[30] [38] [59] [63] [65] [68] [79] [82] [89] [97]
```

###降順
次に、降順に並び替える
通常、Collections.sort()は昇順でソートが行われる

降順でソートされるように、以下を実施する。

- Comparatorをimplements(継承)したクラスNumberDescendingSortを作成
- compareメソッドをオーバーライドする
- o1 > o2 の場合は正の数が返される(return 1;) → 負の数が返されるようにする(return -1;)
- o1 < o2の場合は負の数が返される(return -1;) → 正の数が返されるようにする(return 1;)

```:降順でソートされるよう定義する
package sort;

import java.util.Comparator;

public class NumberDescendingSort implements Comparator<Integer>{
	//通常は、o1 > o2 の場合は正の数が返され(return 1;)、 o1 < o2の場合は負の数が返される(return -1;)
	//昇順がデフォルトなので、小さい順に並べられる。
	//今回は降順としたいので、返される値を逆にしている。
	//o1 > o2 の場合は負の数が返され(return -1;)、 o1 < o2の場合は正の数が返される(return 1;)
	@Override
	public int compare(Integer o1, Integer o2) {
		//
		if(o1 > o2) {
			return -1;
		}else if(o1 < o2) {
			return 1;
		}else {
			return 0;
		}
	}

}
```

```:降順にソートする
//降順にソートする(NumberDescendingSortクラスを使用する)
//第一引数のリストを、第二引数で定義している通りに並び変える
Collections.sort(list,new NumberDescendingSort());

System.out.println("\nソート後(降順)：");

for(int i = 0; i < 10; i++) {
	System.out.print("[" + list.get(i) + "] ");
}
```

```:実行結果
ソート前：
[82] [79] [38] [63] [30] [65] [89] [97] [59] [68] 
ソート後(降順)：
[97] [89] [82] [79] [68] [65] [63] [59] [38] [30] 
```

#最後に
ソートの処理を修正時に、昇順降順の条件に迷ってしまっていたが、
今回実際に作ってみて理解を深めることができました。
Raspberry PiにOpenMediaVaultをインストールしたら、CPUの最大クロックが上がらない件

# 新しめのRaspberry Pi4では、最大クロックが1.8GHzに上がっている

https://raspida.com/overclock-rpi4-bullseye

上記ページに書いてあるように、基板を見れば1.8GHz対応かどうかわかります。自分のも1.8GHz対応でしたが、実際には最大1.5GHzで動いてる状態でした。

/boot/config.txtで1.8GHzになるように設定します。

```/boot/config.txt
arm_boost=1
```

しかし、この設定で1.8GHzになるはずが、依然として従来の1.5GHzのままなので原因を調査してみました。

## cpufrequtilsをインストールする

CPU周波数関連の設定ツール、`cpufrequtils`をインストールします

```
sudo apt-get install cpufrequtils
```

cpufreq-infoで現在の設定が参照できます。

```
pi@raspberrypi4:~ $ cpufreq-info
cpufrequtils 008: cpufreq-info (C) Dominik Brodowski 2004-2009
Report errors and bugs to cpufreq@vger.kernel.org, please.
analyzing CPU 0:
  driver: cpufreq-dt
  CPUs which run at the same hardware frequency: 0 1 2 3
  CPUs which need to have their frequency coordinated by software: 0 1 2 3
  maximum transition latency: 0.97 ms.
  hardware limits: 600 MHz - 1.80 GHz
  available frequency steps: 600 MHz, 700 MHz, 800 MHz, 900 MHz, 1000 MHz, 1.10 GHz, 1.20 GHz, 1.30 GHz, 1.40 GHz, 1.50 GHz, 1.60 GHz, 1.70 GHz, 1.80 GHz
  available cpufreq governors: conservative, ondemand, userspace, powersave, performance, schedutil
  current policy: frequency should be within 600 MHz and 1.50 GHz.
                  The governor "ondemand" may decide which speed to use
                  within this range.
  current CPU frequency is 700 MHz.
  cpufreq stats: 600 MHz:22.22%, 700 MHz:20.53%, 800 MHz:13.27%, 900 MHz:9.16%, 1000 MHz:3.40%, 1.10 GHz:0.99%, 1.20 GHz:0.23%, 1.30 GHz:0.00%, 1.40 GHz:0.00%, 1.50 GHz:30.20%, 1.60 GHz:0.00%, 1.70 GHz:0.00%, 1.80 GHz:0.00%  (193378)
```

`hardware limits`の項目を見ればわかる通り1.8GHzが最大クロックなのですが、`current policy: frequency should be within 600 MHz and 1.50 GHz.`と、なぜか最大クロックが1.5GHzに抑えられています。

ためしに、`cpufreq-set --max 1800000`で最大周波数を1.8GHzに設定すると、ちゃんと`current policy: frequency should be within 600 MHz and 1.80 GHz.`になりました。

## 誰がクロックを制限しているのか調査

たぶん/etc以下にそれっぽい設定があるのだろうとgrepかけてみました。

```
$ grep -r ondemand /etc
/etc/default/cpufrequtils:GOVERNOR="ondemand"
/etc/default/openmediavault:OMV_CPUFREQUTILS_GOVERNOR="ondemand"
```

２つのファイルの内容をチェックしてみます

/etc/default/cpufrequtils

```
ENABLE="true"
GOVERNOR="ondemand"
MAX_SPEED="1500000"
MIN_SPEED="600000"
```

/etc/default/openmediavault (抜粋)

```
OMV_CPUFREQUTILS_GOVERNOR="ondemand"
OMV_CPUFREQUTILS_MINSPEED="600000"
OMV_CPUFREQUTILS_MAXSPEED="1500000"
```

ということで犯人発見。上記2ファイルの1500000を1800000に書き換えます。

Openmediavaultはオールインワン設計で、Web UIでシステム回りの設定もできるのが便利な反面、こういうところで不意を突かれるので油断なりません。

関連記事：

https://qiita.com/tinoue@github/items/bc380a53fca6b795c9f4
こんなRDBMSはいやだ 〜 データベースの使い方アンチパターン 〜

# はじめに

今までに出会った、実際にあったデータベースの使い方を列挙してみます。

[SQLアンチパターン](https://www.oreilly.co.jp/books/9784873115894/)でも拾いきれない、さすがに想定外の使い方ではないかと思われます。

良い子の皆様にはショッキングな内容と想像されます。
心の弱い方はそっと閉じてください。

# 正規化されていない

正規化されておらず、同じ値があちらこちらにあると、更新処理が無駄に長大なトランザクションになります。
仕様を把握しにくくなり、バグの温床になります。

大昔は、パフォーマンスのためにあえて正規化を崩す（テーブル結合せずに値をとれるようにする）という手段もありましたが、今でも通用するでしょうか？

# 主キーがない

テーブルに主キーがないと、更新対象行を一意に特定できているのかどうかわかりません。
テーブルに主キーがないと、プログラムから使おうとしたとき、面倒な手数が増えます。

# 外部キー制約がない

これはSQLアンチパターンに掲載ありましたね。
外部キーなくして、なんのためのRDBMSかという。


# インデックスがない

インデックスがないと、全行検索になってしまいます。


# 連番専用テーブルを使う

連番が欲しいのならば、データベースの機能を使ったほうがよいです。
単にユニークな値が欲しいのなら、プログラム側からGUIDを格納してあげたほうが幸せです。

どうしてもというのであればフォーマンスを考慮してください。デッドロックにも注意です。

# 数値が全部NUMBER型

intとかbitとか、用途に合わせて型を選ぶべきです。

大抵はO/Rマッパを使うのでしょうから、データ型はコードから生成してあげたほうがよいです。


# 日付/日時を文字列で格納している

パースしないと日付/日時として扱えないのは不便過ぎます。
比較も難しいです。
タイムゾーンへの対応も難しいです。

一周回って、逆にデータベースの日付型が貧弱過ぎるから自前でやる、というのはありです。

# 2022年にもなってShiftJIS

新規構築するシステムでUnicodeを選ばない理由はありません。

鯖の異体字 \&#x9bd6;\&#xe0104; を保存したくなるシーンはないでしょうか？

# テーブル名/列名を無理に略す

長さ制限にひっかからないのであれば、無理に略さなくてもよいですよ。
パッと見で意味を汲み取れません。

# 闇雲に作成日/更新日列をつける

とにかく全てのテーブルに作成日/更新日列をつけます。
さらに作成者/更新者、作成プログラム/更新プログラムのような列がつけられることもあります。

テーブルの趣旨にあわせて、その列が必要かどうか判断してください。

監査/トレース目的なら、また別の方法を検討したほうがよいです。

# ストアドプロシージャが巨大すぎる

データベースに負荷をかけるような処理は、なるべく控えたほうがよいです。
増強が難しくなります。
SQL データのグループ化

##GROUP BY
GROUP BYを用いると、データをグループ化することができます。「GROUP BY カラム名」とすることで、指定したカラムで、完全に同一のデータを持つレコードどうしが同じグループとなります。

グループ化するには、今までの集計関数を取得するFROMの後ろに「GROUP BY カラム名」を追加します。集計関数により、各グループごとにデータが集計されます。

※GROUP BYを用いる場合、SELECTで使えるのは、GROUP BYに指定しているカラム名と、集計関数のみです。

```
SELECT 
関数(カラム),カラム1
FROM テーブル名
GROUP BY カラム1 ;
```

####複数の場合

```
SELECT 
関数(カラム),カラム1,カラム2
FROM テーブル名
GROUP BY カラム1,カラム2;
```
####WHEREとGROUP BY
GROUP BYはWHEREとも併用することができ、その場合はWHEREの後に書きます。
WHEREとGROUP BYと集計関数は以下の順番で実行されていきます。WHEREはまず最初に、そのあとにGROUP BYと関数が実行されます。

```
SELECT 
関数(カラム),カラム1,カラム2
FROM テーブル名
WHERE カラム = "文字"
GROUP BY カラム1,カラム2;
```

##HAVING
GROUP BYでグループ化したデータを更に絞り込みたい場合には、HAVINGを用います。「GROUP BY カラム名 HAVING 条件」のようにすることで、条件を満たすグループを取得することができます。

```
GROUP BY カラム
HAVING 条件;
```
####WHEREとHAVING
グループ化した後のデータを絞り込む際、WHEREではなくHAVINGを使うのは、SQLの各コマンドが以下の順番で実行されていくためです。WHEREはまず最初に、そのあとにGROUP BYと関数が実行され、その後にHAVINGが実行されます。

実行順序によって、WHEREとHAVINGは検索対象に違いがあります。WHEREはグループ化される前のテーブル全体を検索対象とするのに対し、HAVINGはGROUP BYによってグループ化されたデータを検索対象とします。

HAVINGはグループ化された後のテーブルから検索するため、条件文で使うカラムは必ずグループ化されたテーブルのカラムを使います。

```
SELECT 
関数(カラム),カラム1,カラム2
FROM テーブル名
GROUP BY カラム1,カラム2
HAVING 関数(カラム) > 数値;
```
【解決方法1】We're sorry, but something went wrong. If you are the application owner check the logs for more information. 

【事象】
RailsTutorial第６版の7章。
herokuへのデプロイ後に本番環境を確認したところ、なぜか/signupへのリンクで下記エラーが発生。
**「We're sorry, but something went wrong. If you are the application owner check the logs for more information. 」**

開発環境では問題なく作動しているが本番環境の/signupへのリンクで何か問題が起きていることが発覚。

【やったこと】
下記コマンドでログを確認したところ、status=500の赤いテキストを発見。
```heroku logs --tail```

５００エラーとはサーバーのエラーとなり、heroku側のエラー。
本番環境でマイグレーションしていないことに気づき、下記コマンドを実行。解決。
```heroku run rails db:migrate```
AWS App Runner にカスタムドメインを付与してみた

# はじめに

[前回の記事](https://qiita.com/sugimount-a/items/c0b32f1d1152104c1666)では、ECR に Push したコンテナイメージを App Runner にデプロイする方法を紹介しました。

デフォルトでは、App Runner は次の ドメイン名が自動的に割り当てられています。

```
https://xxxxxxxxx.ap-northeast-1.awsapprunner.com/
```



自分たちのサービスを稼働させたい場合は、これを任意のドメイン名で提供したいはずです。今回は、カスタムドメインを使って、任意のドメイン名に変更する方法を確かめていきます。



# Custom Domain の設定

[前回の記事](https://qiita.com/sugimount-a/items/c0b32f1d1152104c1666)で作成した App Runner Service を使っていきます。Service の詳細画面を開き、Custom Domain の設定ページで Lind Domain を押します。

![image-20220214210502544.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/87b9cf80-4a1c-1096-e1fb-58ae8f36a534.png)



任意のドメイン名を指定します。今回は、Route 53 で管理している以下のドメインを、アクセス用として指定します。

```
apprunner.sugiaws.tokyo
```

![image-20220214210608092.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/8d923ae9-f081-0dfc-c2b0-564091ad2ffb.png)



次の画面が開き、ドメイン証明のための DNS レコードが表示されます。これを Route 53 などのドメイン管理サービスで入力をすることで、このドメインを所有していることを証明できます。

![image-20220214210916687.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/4cf03e3c-1296-f7bf-064e-15880c71d639.png)



記事の環境では、Route 53 で管理しており、以下のように指定された 3 つの CNAME レコードを追加しました。

![image-20220216011750589.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/17ea0548-b7c7-e461-3ba5-2a78726d4318.png)



一定時間後、App Runner の Custom Domain の Status が Active に変わります。

![image-20220223160107951.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/16e984ee-3a13-955d-43dc-6b136bfcd14c.png)



# アクセス確認

ここまで設定できれば、カスタムドメインが利用できるようになっています。実際に、Custom Domain で指定した名前でアクセスをしてみましょう。

正常に App Runner のアプリケーションにアクセスすることが出来ました。

![image-20220223160136843.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/93e33977-f1ee-d9a1-0d50-17d965b05ce2.png)
部分和問題

sample

```
// using System;

// public class Program
// {
//     public static void Main()
//     {
//         int n = 4;
//         int K = 13;
//         int[] a = new int[] { 1, 2, 4, 7 };

//         for (int i = 0; i < n; i++)
//         {
//             //使わない
//             res = exec(K,n); 
//             if(ResolveEventArgs == "yes") return 

//             //使う
//             K = K - a[n];
//             res = exec(K,n);

//         }
//     }
//     string exec(int k, int n)
//     {
//       if(k - a[n] == 0) return "yes";
//       if(k - a[n] < 0) return "no";
//     }

// }

```


自分(不正解)

```
// using System;

// public class Program
// {
//     public static void Main()
//     {
//         int n = 4;
//         int K = 13;
//         int[] a = new int[] { 1, 2, 4, 7 };

//         for (int i = 0; i < n; i++)
//         {
//             //使わない
//             res = exec(K,n); 
//             if(ResolveEventArgs == "yes") return 

//             //使う
//             K = K - a[n];
//             res = exec(K,n);

//         }
//     }
//     string exec(int k, int n)
//     {
//       if(k - a[n] == 0) return "yes";
//       if(k - a[n] < 0) return "no";
//     }

// }

```
【AWS SAA(C02)合格体験記】3週間で合格に至るまでのあれこれ

本日AWS SAA(C02)を受験して結果画面に合格と表示されたので、
記憶が新しいうちに合格体験記を残します。
合格体験記はありふれているかもしれませんが、これからの受験者へ少しでもご参考になれば幸いです。
※ 点数等は別途追記予定。
追記
748点でした。結構ギリギリ…

![スクリーンショット 2022-02-25 12.55.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410187/f1e63d95-1666-d66b-cb98-d9b2748cfdd2.png)



## 前提知識
 - モバイルエンジニア4年目。普段はAWSを(ほぼ)触りません。
 - 2021年9月にAWS CLF合格
 - 2021年9月以降はAWSの勉強せず。

## 勉強時間
約6-70時間くらい

2022年2月1日：勉強開始
2022年2月23日：合格 

平日業務後約1時間、休日10時間程で詰め込みました。

## 勉強のロードマップ

### 1. 黒本を読む

https://www.amazon.co.jp/%E6%A8%A1%E6%93%AC%E5%95%8F%E9%A1%8C%E4%BB%98%E3%81%8D-AWS%E8%AA%8D%E5%AE%9A-%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E6%95%99%E7%A7%91%E6%9B%B8-SAA-C02/dp/4295010650/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=SD98VFPYZP2G&keywords=AWS+SAA&qid=1645596527&sprefix=aws+saa%2Caps%2C189&sr=8-1

CLFを合格していたものの、期間が空いて知識の抜けが多かったので総ざらいとして本書から確認。
2周ほどざっと読んで終了。

### 2. ひたすら問題を解く

#### 2-1 Udemyの以下講座を1~6までとりあえず１周解いて、解説見て理解。

https://www.udemy.com/course/aws-knan/

#### 2-2 CloudTechの無料AWSSAA対策問題200問を解いて、解説見て理解。

https://kws-cloud-tech.com/

#### 2-3 公式模試を解いてみる。

https://dev.classmethod.jp/articles/new-aws-official-practice-questions/


#### 2-4 UdemyとCloudTechの繰り返し

Udemyは1~6をだいたい9割くらい、CloudTechは200問をほぼノーミスで解けるくらいまで。
不明点などは都度調べていましたが、メインとして使用していた教材は上記２点だけでした。

## 受験後の感想

#### 本番試験難しい！

と、試験開始時思いましたが、いざ解いてみると問題文が若干長かったり言い回しが今までと少し異なるだけで、この問題はどの辺がポイントなんだろう？ということを意識すれば大きく焦ることもありませんでした。

焦らず問題の本質と向き合いましょう。

## 役に立ったサイトまとめ
| サイト名、文献等 | おすすめ度 | 概要 |
|:-:|:-:|:-:|
| [黒本(アソシエイト教科書)](https://www.amazon.co.jp/s?k=AWS+SAA&__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=107B6M4VI7X36&sprefix=aws+saa%2Caps%2C161&ref=nb_sb_noss_1)  | ★★★  | 各サービスの概要を理解できます。これだけで試験突破は厳しいのでピンポイントに調べたい時に使用 |
| [【2022年版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)  | ★★★★  | 　問題のボリュームが多く、定番かと思います。一度解くと65問解き終えるまで終われないのでまとまった勉強時間を取る必要があるのが少し欠点 |
| [CloudTech](https://kws-cloud-tech.com/)  | ★★★★  | 　200問までですが、1問ごとに答えを見れるので不明点を潰しながら勉強できます。課金すれば+200問できるので、絶対に落ちたくない！不安！という方は課金もあり。 |
| [無料模擬試験](https://dev.classmethod.jp/articles/new-aws-official-practice-questions/)  | ★★★  | 　解説も丁寧で良いですが20問という少なさが少し欠点。無料ですし受ける価値はあります。 |
| [AWSWeb問題集](https://aws.koiwaclub.com/exam/aws-exam2/)  | ★★★  | 　一部の問題がAWSの本番と形式が異なるので優先度を下げて非会員の無料問題だけ解きました。もっと問題を解いておきたいという方には良いかもしれません。 |

----
#### tips
個人的にスプレッドシートに不明点を纏めると、
前日や当日何しよう？ってなった時に不明点をざっと見直せるので良かったです。
$\tiny{(走り書きのメモなので中身は気にしないように)}$

![スクリーンショット 2022-02-23 15.55.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410187/b4e623ec-d0bf-a93d-adba-641fa529c2f7.png)


## まとめ&反省点

### 反省点

1. **もっと早くテスト予約すればよかった** 
    - 受験の4日前くらいに試験予約しようとしましたが、希望日がほぼ埋まってました。**受けるなら早めに予約を！**
1. **受験場所は把握しておこう(テストセンターの場合)**
    - 当日迷子になりました。

----
### まとめ
先に試験日を決めてから勉強に取り組んでもよかったかもしれません。
この体験記がAWSSAAを勉強されている方の一助になれば幸いです。

合格に向けて頑張りましょう！
【M1 Mac】MySQL Workbench から Sequel Ace に乗り換えただけの話【コマンドラインからのDB直接接続】

# MySQLのGUI
皆さんはMySQLのGUIを使っているでしょうか？
自分は今までM1MacでMySQL Workbenchを使用していたのですが、***Sequel Ace***に乗り換えたところ、想像以上に軽くておすすめです。

https://apps.apple.com/us/app/sequel-ace/id1518036000

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659469/efc328a8-f97a-9d91-58ee-2ae5f9be81bd.png)

# おまけ1 -コマンドラインからのDB直接接続-

```shell
open "mysql://root:root@127.0.0.1:3306/db" -a "Sequel Ace"
```

# おまけ2 -言語変更-
英語だと「Relations」となっているページが「関連」となっているのが気になる方は、
アプリ別の言語設定で英語化することができます。

https://support.apple.com/ja-jp/guide/mac-help/mh26684/mac
Android端末で新と旧アプリをpython+Appiumで自動実行させて得たエビデンス画像をExcelファイルに貼り付けて新旧画像の比較結果を示した


(゜д゜)ﾉやぁーどもです。
今回は、割と結構実用的なプログラムを作ってみましたよ！


１年くらい前に↓の記事で、Android端末でアプリケーションをpython＋Appiumで自動実行させることをしましたが、今回、これを使って作った自動実行プログラムで、新アプリと旧アプリそれぞれで貯めたエビデンス画像をExcelファイルに新と旧で並べて貼っていって、「新と旧で差異がないよね」ってことの確認を支援するプログラムを作ってみました。

https://qiita.com/jun_higuche/items/7c6a23ed4f9cda53b8a0

## 背景

私が担当したエンハンスプロジェクトで、現在のアプリ（以降、旧アプリ）で使っていたAPIの全てを別のAPI（そのとき開発中のもの）に置き換えるという案件を実施しました。新APIでは、単純に置きなおしすればよいというものではなく、その１つ１つの動作仕様が違うものやパラメーターも違うものもあり、こちら側のプログラムロジックもだいぶ修正することになったのです。そして、旧アプリと新アプリでまったく同じ動作を保証しなければなりませんでした。

まず、この連結試験で、以前使ったpython＋Appiumで自動実行プログラムを開発して、旧アプリと新アプリで実行してみて、そのエビデンス画像の比較をすればテスト工数がだいぶ省けると考えたのですが、さらに、そこで、そのエビデンス画像を手作業でExcelファイルに貼って、その結果を人の目で確認していくという作業に工数が掛かっているという所に目を付けたのです。
人が判断する箇所も必要でしょうが、新と旧の画像で同一の名前のものを確認してExcelファイルに貼っていくというのは、人でなくてもできることです。なので、そこをpythonにさせようと思いました。さらに、人の目で判断する上で、２画像の差分を示してあげることでより確認作業が楽になるのではないかと思い、比較した類似度と、比較した差異画像を生成するということも同時に行ったのです。
以下、pythonにさせた事と人がやることにした作業の切り分けです。

## 今回作ったプログラムの概要


【前作業】
python＋Appiumで作った自動実行プログラムを新アプリと旧アプリで動作させ、それぞれのエビデンス画像を別フォルダで貯め込んでおく。

【今回の範囲】
１，pythonで、新アプリ、旧アプリの結果フォルダを参照して、同一名称の画像を並べてExcelファイルに貼りつける。
２，pythonで、その２画像の類似度を算出して、Excelファイルに記録
３，pythonで、その２画像の差異を示す画像を作成して、Excelファイルに貼り付ける
　　（※この時点でExcelファイル完成）
４，人（開発メンバー）がExcelファイルを開いて、新と旧の差異を見て確認していく

結果となるExcelファイルを開くと、↓このような感じで差異を示すことができます。

![154729901-8c16a31c-91fe-4f9e-939a-6410ecd3e96e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448092/fbb26cb0-2ecc-e2cc-ca3a-51de634d5721.png)
![154841399-8afad503-48fd-4e2a-8c76-5bf6fe0ec2fe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448092/daf4261b-d5cf-ff2d-22b5-4bac3be8c02c.png)

上部にファイル名と算出した類似度を示すとともに、
新と旧のエビデンス画像を左右に貼り付け、真ん中に差異を示す画像を貼り付けてます。

## 技術解説

### 類似度の算出

↓類似度の算出は、「02_２画像の画素値を比較し類似度を算出」の方で実装しました。
理由は、今回は新アプリと旧アプリで同じ端末を利用するつもりなため、同じ動きであったならば画素的なズレは全く無いはずだからです。もし、新アプリと旧アプリで別端末を利用するのであればヒストグラムでの算出の方が得たい結果に近くなるのではないかと思います。

https://qiita.com/jun_higuche/items/752ef756a182261fcc55

### 差異画像の生成

↓の「02_画像比較して異なる箇所が分かる画像を生成するプログラム」の「03_diff_center.png」のやり方の方で、実装しました。

https://qiita.com/jun_higuche/items/e3c3263ba50ea296f7bf

### Excelファイル作成

pythonでExcelファイルを作成するに当たっては、「openpyxl」というライブラリを利用しました。
ググったら色々サンプル見つかります。

## プログラム

↓Gitに格納しておきました。

https://github.com/jun-higuche/python-ImageCompare-ToExcelFile

ダウンロードして頂いて実行環境がWindowsの方は「install_library.bat」を実行することで、必要なライブラリがインストールされるはずです。LinuxやMacの方は「install_library.bat」の中身を実行してみてください。
そのあと、「main.py」を実行していただければ、動作するはずです。
「tmp01」と「tmp02」に新アプリと旧アプリを想定したサンプル画像が入ってます。

## まとめ

今回、新アプリと旧アプリの動作比較という割とありがちな案件で使えるプログラムを作ってみました。
実は、まだ実運用で利用していなくって、この記事を書いている１～２カ月後くらいに実行する予定なのです。
実案件で利用後にまたレポート書いてみます。

この記事を読んでて、新アプリと旧アプリの比較という用件のある方は是非使ってみて頂きたいです。
SQL 関数計算（合計・平均）などを求めよう

##合計を求めよう
SQLで数値の合計を計算する場合は、SUMを用います。
「 SUM(カラム名) 」のようにすることで、指定したカラムに保存されたデータの合計を計算することが可能です。
SUM関数はSELECTで取得するカラムに用いることで、集計結果を取得することができます。
SUM関数はWHEREと併用することができます。

```
SELECT 
SUM(カラム)
FROM テーブル名
WHERE カラム = "文字";
```
##平均を計算しよう
SQLで数値の平均を計算する場合は、AVGを用います。

```
SELECT 
AVG(カラム)
FROM テーブル名
WHERE カラム = "文字";
```

##データの数を計算しよう
COUNT関数は、指定したカラムのデータの合計数を計算してくれる関数です。「COUNT( カラム名 )」とすることで、指定したカラムのデータの数を計算します。

COUNT関数でカラム名を指定した場合、nullになっているデータの数は計算されません。
nullの数も含めてデータの数を計算したい場合は、COUNT関数で * (全てのカラム)を指定します。* を使った場合、特定のカラムのデータの数ではなく、レコードの数を計算します。この方法で、nullの数を含めてデータの数を数えられます。
COUNT関数もWHEREと併用することができます。

```
SELECT 
COUNT(カラム)
FROM テーブル名
WHERE カラム = "文字";
```

##最大・最小を求めよう
####MAX関数
SQLでMAXという関数を用いると、指定したカラムのデータの中から最大のデータを取得することができます。

```
SELECT 
MAX(カラム)
FROM テーブル名
WHERE カラム = "文字";
```
####MIN関数
MINと言う関数を用いることで、最小のデータを取得することができます。

```
SELECT 
MIN(カラム)
FROM テーブル名
WHERE カラム = "文字";
```
EJS記法まとめ

## `<%= ~ %>` 出力タグ(エスケープあり)

変数をエスケープして出力する。  
変数に禁則文字(<や&など)を含む場合に自動的にエスケープされる。

```html
<!-- 変数を定義 -->
<% const name = 'John' %>

<!-- 定義した変数を出力 -->
<p>Hello, <%= name %>.</p>
<p>Hello, <%= 'Mr. ' + name %>.</p>
```

```html
<!-- 出力結果 -->
<p>Hello, John.</p>
<p>Hello, Mr. John.</p>
```

## `<%- ~ %>` 出力タグ(エスケープなし)

変数をエスケープせずに出力する。(利用時はXSS攻撃に配慮すること)

```html
<!-- 変数を定義 -->
<% const myHtml = '<strong>Timothy</strong>' %>
<% const myMaliciousHtml = '</p><script>document.write()</script><p>' %>

<!-- 定義した変数を出力(エスケープなし) -->
<p>Hello, <%- myHtml %>.</p>
<p>Hello, <%- myMaliciousHtml %>.</p>

<!-- 定義した変数を出力(エスケープあり) -->
<p>Hello, <%= myHtml %>.</p>
<p>Hello, <%= myMaliciousHtml %>.</p>
```

```html
<!-- 出力結果 -->
<p>Hello, <strong>Timothy</strong>.</p>
<p>Hello, </p><script>document.write()</script><p>.</p>

<p>Hello, &lt;strong&gt;Timothy&lt;/strong&gt;.</p>
<p>Hello, &lt;/p&gt;&lt;script&gt;document.write()&lt;/script&gt;&lt;p&gt;.</p>
```

## `<%# ~ %>` コメントタグ

HTMLに出力されたり、実行されたりしないコメントの記載に利用する。
終了タグを後述する改行削除タグ `-%>` にすることでコメント行の不要な改行を除去できる。

```html
<div>
<%# comment %>
</div>

<div>
<%# comment -%>
</div>
```

```html
<!-- 出力結果 -->
<div>

</div>

<div>
</div>
```

## `<% ~ %>` スクリプトレットタグ

このタグ内ではJavaScript構文を用いてロジックを埋め込むことができる。

### 波括弧{}

スクリプトレットのみの場合は{}を使わなくても良いが、  
EJSテンプレートと混在する場合は基本的に{}を省略しないほうが良いとのこと。

```html
<!-- 良くない例({}がない) -->
<% if (true) %>
  <p>Yay it's true!</p>

<!-- 良い例({}で囲っている) -->
<% if (true) { %>
  <p>Yay it's true!</p>
<% } %>

<!-- こちらも正常に動作する例 -->
<% let output,
       exclamation = '',
       shouldOutput = false;

   if (true)
     output = 'true!';

   if (true) {
     exclamation = 'Yay! ';
   }

   if (true) shouldOutput = true; %>

<% if (shouldOutput) { %>
	<!-- EJSテンプレートと混在するため、{}で囲っている -->
  <p><%= exclamation + 'It\'s ' + output %></p>
<% } %>
```

```html
<!-- 出力結果 -->
<p>Yay it's true!</p>

<p>Yay it's true!</p>

<p>Yay! It&#39;s true!</p>
```

### タグ内の改行

EJSとJSのスクリプトレットを混在させる場合を除き、  
`<% ~ %>`タグ内に完全なステートメントとして記載すること。

```html
<!-- OK例 -->
<% const stringToShow = booleanVariable
                      ? 'OK'
                      : 'not OK' %>

<!-- NG例(ビルドエラーが起こる) -->
<% const stringToShow = booleanVariable %>
<%                  ? 'OK'              %>
<%                  : 'not OK'          %>
```

### セミコロン

Javascript同様、適切な改行がなされていればセミコロンはなくても動作する。

### 空白と改行

スクリプトレットを使用すると出力結果に無駄な空白が発生することがある。  
これを防ぐには、開始タグに`<%_`を使い空白を削除し、終了タグに`-%>`を使い改行を削除する。
それぞれ`<%_`はこのタグ前の空白を削除し、`-%>`はスクリプトレットやコメントによって生まれる余分な改行を削除する。(出力タグには効果なし)

```html
<!-- 削除なし -->
<ul>
  <% for (let i = 0; i < 3; i++) { %>
  <li><%= i %></li>
  <% } %>
</ul>

<!-- 削除あり -->
<ul>
  <%_ for (let i = 0; i < 3; i++) { -%>
  <li><%= i %></li>
  <%_ } -%>
</ul>
```

```html
<!-- 出力結果 -->

<!-- 削除なし -->
<ul>
  
  <li>0</li>
  
  <li>1</li>
  
  <li>2</li>
  
</ul>

<!-- 削除あり -->
<ul>
  <li>0</li>
  <li>1</li>
  <li>2</li>
</ul>
```

---

## 参考  

https://github.com/mde/ejs/blob/master/docs/syntax.md
Github版のUnreal Engine 5 Previewを取得してビルドする方法について (リリースタグからのビルド方法)


今回はリリースされたUE5.00 Preview 1を例にタグからのソースコード取得の流れを紹介します。

Github Desktopを用いた管理方法や、ビルドまでの流れは以前書いた記事で紹介しています。
**Github版Unreal Engineのおすすめ管理方法と不具合修正の取り込み方法について - Qiita** 
https://qiita.com/_yu5a_/items/0261de368220f141d1b1

## 取得について
UE5に関するブランチはいくつかあるようですが、5.0 Previewに関しては **5.0ブランチ** からタグ付けされているようです。具体的には5.0ブランチに切り替えた後コマンドプロンプトを開きTagを参考にコマンドでリセットします。
![screenshot_2022_02_23_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1695861/2eaf2c6e-c89d-a284-1778-71a19b140379.png)

(以下の例は5.00 P1のハッシュでリセット)

```
git reset --hard 07493b29bd3344e92d24ac6bb2a71d85a1c1ef13
```

その他各リリースのタグやハッシュは以下URLから確認可能です。
https://github.com/EpicGames/UnrealEngine/tags

## ビルドについて

その後Setup.batやGenerateProject.batを実行してソリューションを作成後、VSでビルドします。
（この流れは以前の記事を参考にしてください）
https://qiita.com/_yu5a_/items/0261de368220f141d1b1
これでわかるLaravel8.Xのマルチ認証(Multi Auth)の設定方法

https://reffect.co.jp/laravel/laravel-multi-authentication-understand#i-5

```web.php
Route::prefix('employee')->namespace('Emplyee')->name('employee.')->group(function(){
    Auth::routes();
});
```

```command
php artisan route:list
```
ここで、修正してもLaravel8を使用している方は、エラーが出ちゃうと思います。
それはルーティングの指定がLaravel7とLaravel8で
変更になったからです。

その対処法はこちら

```php
->namespace('App\Http\Controllers\Emplyee')
```

これで、OKです！

詳しくはこちらの記事を参考にしてみてください！

https://zakkuri.life/laravel-laravel8%E3%81%AE%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E4%BB%95%E6%A7%98%E3%81%8C%E5%A4%89%E6%9B%B4%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%9F/
CryEngine2(Crysis Sandbox2)で人を車両に乗せる

# CryEngine2で人を車両にのせたる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/9d8cedaf-4590-c80c-488e-28d1ce1be742.png)

こんな感じで車両と人を準備する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/09536dce-17e1-e2db-035b-b6d55b1ec3c4.png)

上部のバーから**View >>> Open View Pane >>> Flow Graph**を選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/53920df6-c543-3539-227b-2f65336953c5.png)


こんなやつが出てきたらOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/c6103e9c-fce8-adde-f596-b3d1cf8c8f7f.png)

上部のバーから**File >>> New**を選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/2373a07f-d2ab-bb4d-6e14-51dd4a4eca7c.png)

パネルを右クリックして**Add Node >>> Misc >>> Start**を押下する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/92bf4037-0ced-6ea8-6e50-dd1612c75ff8.png)

こんなのが出てきたらOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/5668ebbe-9401-a74d-0e7e-660ed08c76a2.png)

同じく右クリックして**Add Node >>> Entity >>> EntityId**を押下する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/f69ecd55-51f5-570c-1515-80f002c317d1.png)


次に**Add Node >>> Vehicle >>> Enter**を押下する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/a0acd835-3069-f562-1505-8972d0b1c3f9.png)


これでOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/a25b91a8-f7c4-fd2b-d97b-87be089c8ecb.png)


こんな感じにつなげる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/2b204d8e-b52b-7335-26f4-b593d6e0cce0.png)

車両を選択した状態でパネルのEntity:EntityIdを右クリックする
そのあとに**Assign selected entity**を押下する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/b8afe280-ab21-050a-9ec8-08ef0cfdb5ca.png)


これでOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/98f2e527-7586-0cf6-eaff-64d1ab1582bf.png)

先ほどと同様に人を選択した状態でVehicle:Enterを右クリック
そのあとに**Assign selected entity**を押下する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/a15860c4-8fd4-2609-4e38-4a09ad9b820a.png)


これでOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/0b53e292-d934-b916-5ee9-74dd09d7a77b.png)

Vehicle:Enterをクリックすると右側のInputsにメニューが出てくるので
**Seat**を乗らしたい席に選択する
この場合はDriverにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459889/c6ddf5ed-0bc4-989f-c623-a8f8766a02d6.png)


これで乗ってくれる


終わり
40 代おっさん GASのGmailサービスについて学ぶ

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## Gmailサービス

Gmailサービスとは
Gmailを操作するためのクラスとそのメンバーを提供するサービス

|クラス|説明|
|-----|----|
|GmailApp|Gmailサービスのトップレベルオブジェクト|
|GmailThread|スレッドを操作する機能を提供|
|GmailMesssage|メッセージを操作する機能を提供|
|GmailDraft|下書きを操作する機能を提供|
|GmailAttachemnt|メッセージの添付ファイルを操作する機能を提供|

### スレッドとメッセージ

メッセージとは
一通ごとに送るメールのこと

スレッドとは
Gmailでは、メッセージに対する返信をメッセージの一連のやり取りが自動でまとめられる。
その一連のメッセージをまとめたもののこと

GmailAppからスレッドを収得する場合は、以下のように配列で収得することになる。

```javascript
[スレッド0, スレッド1, ..., スレッドm]
```

### 操作の対象となるオブジェクト

Gmailサービスでは、返信、転送、既読など色々な操作があります。
それらの操作の対象がスレッドなのか、メッセージなのかを整理する。

|操作|GmailAPP|スレッド|メッセージ|
|----|--------|-------|---------|
|新規メールを送信する|　　〇|||
|返信する|||　　〇|
|転送する|||　　〇|
|受信トレイに移動する||　〇||
|アーカイブに移動する||　〇||
|迷惑メールに移動する||　〇||
|ゴミ箱に移動する||　〇|　　〇|
|重要にする/重要を外す||　〇||
|既読にする/未読にする||　〇|　　〇|
|スターを付与する/スターを外す|||　　〇|

## 参考資料

<https://www.amazon.co.jp/s?k=google+apps+script+%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80&adgrpid=110264232688&gclid=CjwKCAiA9aKQBhBREiwAyGP5lSl7AJJLCvOEHb4wQgMlyqW1fll5X8GDTT_Rkd1_soUAyIPMXQr26hoClHEQAvD_BwE&hvadid=553833563682&hvdev=c&hvlocphy=1009076&hvnetw=g&hvqmt=b&hvrand=4378489642044417389&hvtargid=kwd-594191211348&hydadcr=4106_13159878&jp-ad-ap=0&tag=googhydr-22&ref=pd_sl_2x1owglv0s_b_p52>
10: 多次元配列, 

<font color="green"><h1>多次元配列</h1></font>

配列/連想配列の要素として格納できるのは、数値や文字列ばかりでは無い。

任意の型の値、例えば<font color="red">配列そのもの</font>を格納してもかまわない。

<font color="blue">入れ子の配列</font>

具体例

```
$data1 = [
   [‘x-1’, ‘x-2’, ‘x-3’],
   [‘y-1’, ‘y-2’, ‘y-3’],
   [‘z-1’, ‘x-2’, ‘x-3’],
  ];

```

配列$data1

||0|1|2|
|:-:|:-:|:-:|:-:|
|0|[0,0]x-1|[0,1]x-2|[0,2]x-3|
|1|[1,0]y-1|[1,1]y-2|[1,2]y-3|
|2|[2,0]z-1|[2,1]z-2|[2,2]z-3|
上記は二次元配列

このように「配列の配列」を表すようなケースでは、最低限、要素ごとに改行とインデントを加えると構造が分かりやすくなり、コードも読みやすくなる。

構文規則ではないが、少し心掛ける。

配列の配列から値を取り出すには、これまでと同様、ブラケット構文でそれぞれの次元のインデックス番号を指定する。

```
$data[1][0]

//結果: y-1

```

インデックス番号が一つだけの配列を<font color="red">一次元配列</font>、インデックス番号が二個の配列<font color="blue">（配列の配列）</font>を<font color="red">二次元配列</font>、またはより一般的に<font color="red">多次元配列</font>とも言う。

理論的には、同じ要領で[...]を入れ子にすることで、4次元、5次元配列を作成することもできるが、直感的に理解しやすいと言う意味でも、普通に利用するのはせいぜい3次元配列まで。

```
$data2 = [
   [
     [‘s牛肉’, ‘m牛肉’, ‘l牛肉’],
     [‘s豚肉’, ‘m豚肉’, ‘l豚肉’],
     [‘s鶏肉’, ‘m鶏肉’, ‘l鶏肉’],
   ],
   [
     [‘sコーラ’, ‘mコーラ’, ‘lコーラ’],
     [‘sサイダー’, ‘mサイダー’, ‘lサイダー’],
     [‘sファンタ’, ‘mファンタ’, ‘lファンタ’],
   ],
   [
     [‘sポテト’, ‘mポテト’, ‘lポテト’],
     [‘sカレー’, ‘mカレー’, ‘lカレー’],
     [‘sキムチ鍋’, ‘mキムチ鍋’, ‘lキムチ鍋’],
   ],
  ];

echo $data[2][2][0];
//結果: sキムチ鍋

```

上記はインデックス番号が３つなので多次元配列。

また、<font color="red">配列の中に連想配列を含める</font>こともできる。

例

```
<?php
$data3 = [
   [
    ‘name’ => ‘山田孝之’,
    ‘age’  => 35,
    ‘sex’  => ‘男’,
   ],
   [
    ‘name’ => ‘タモリ’,
    ‘age’  => 15,
    ‘sex’  => ‘男’,
   ],
   [
    ‘name’ => ‘釈由美子’,
    ‘age’  => 25,
    ‘sex’  => ‘女’,
   ],
  ];

```

| <font color="blue">[0]</font> ||
|:-:|:-:|
|[name]|山田孝之|
|[age]|35|
|[sex]|男|

| <font color="blue">[1]</font> ||
|:-:|:-:|
|[name]|タモリ|
|[age]|15|
|[sex]|男|

|<font color="blue">[2]</font>||
|:-:|:-:|
|[name]|釈由美子|
|[age]|25|
|[sex]|女|

上記は配列と連想配列の入れ子

このような形式の配列は、データベースからデータを取り出す場合などにもよく使われるので、きちんと理解する。

<font color="green"><h1>通常配列と連想配列の関係</h1></font>

ここまでの説明では、便宜上、数字キーを持つ通常配列と、文字列キーを持つ連想配列とを別物として解説して方が、厳密には、PHPはこれらを区別しない。

唯一の配列型があるだけで、そのキーが数値であるか文字列であるかによって、両者を区別しているに過ぎない。

その理解を踏まえて以下の例をもって配列の理解を深める。

<font color="pink"><h2>通常配列でキーを明示する</h2></font>

通常配列と連想配列とが本質的に同じものであることが分かれば、通常配列でもキー名（インデックス番号）を指定できるのは何ら不思議なことではない。

```
<?php
$data = [1 => ‘山田’, 2 => ‘松本’, 3 => ‘浜田’, 4 => ‘濱田’]

print_r($data);


//結果:

Array
(
　[1] => 山田
　[2] => 松本
　[3] => 浜田
　[4] => 濱田
)

```

通常配列のようにインデックス番号が省略された場合には、ゼロから始まる番号が自動的に振られていた。

一部の値だけにインデックス番号を振ることもできる。

この場合、「その時点での最大インデックス番号+1」が自動的に割り振られる。

例えば下記のようなケースではすでに<font color="blue">4</font>まで番号が振られているので、次の「カツオ」のインデックス番号は<font color="red">5</font>となる。

```
<?php
$data = [1 => ‘マグロ’, 4 => ‘シャケ’, ‘カツオ’];

print_r($data);

//結果:

Array
(
　[1] => マグロ
　[4] => シャケ
　[5] => カツオ

```

ただし最大のインデックス番号が負数である場合は例外。
この場合、次のインデックス番号を決めるルールは、バージョンによって変化する。

例

```
<?php

$data = [-10 => ‘河野’, ‘伊藤’];

print_r($data);

//結果:

//PHP7.4以前

Array
(
　[-10] => 河野
　[0]   => 伊藤


//PHP8以降

Array
(
　[-10] => 河野
　[-9]  => 伊藤

```

PHP7.4以前では、強制的にゼロが割り当てられるのに対して、PHP8以降では整数インデックスの場合と同じく、<font color="blue">「最大インデックス+1」</font>が振られる。

負数インデックスを積極的に利用する機会はさほどないが、互換性のない変更なので、頭の片隅に留めておく。

<font color="green">11:通常配列と連想配列との混在</font>
SQL 検索結果を加工

##重複したデータを省く

####DISTINCT
DISTINCTを用いると、検索結果から重複するデータを除くことが可能です。「DISTINCT(カラム名)」とすることで、検索結果から指定したカラムの重複するデータを除くことができます。

```
SELECT
DISTINCT (省きたいカラム)
FROM テーブル名;
```
####取得したデータを計算する
SQLでは四則演算「足す(+)、引く(-)、かける(*)、割る(/)」が可能です。左の図のような記号を使うことで、右の図のようにカラムのデータを計算することが可能です。かける場合はアスタリスク(*)、割る場合はスラッシュ(/)を用いることに注意しましょう。

```
SELECT カラム * 計算したい数字
FROM テーブル名;
```