OmniAICreator/Qiita-1.07M huggingface dataset:
[python] bogo sort (ランダムな整列)の勉強

# はじめに
アルゴリズム問題の定番はsort問題だと思う。
ここではsort方法として原始的かつ基本的ではあるが、一番効率の悪いbogo sortについてまとめた。

# Code


```python
import random
from typing import List
import time


def in_order(numbers: List[int]) -> bool:
    return all(numbers[i] <= numbers[i+1] for i in range(len(numbers)-1))
    # リストのすべての要素の右側が等しいもしくは大きい場合、True でなければ False 

def bogo_sort(numbers: List[int]) -> List[int]:
    while not in_order(numbers):
        random.shuffle(numbers)
        # ランダムに要素を混ぜる
    return numbers


if __name__ == '__main__':
    start = time.time()
    nums = [random.randint(0, 1000) for _ in range(10)]
    print(bogo_sort(nums))
    print(time.time() - start)

```


```terminal
[69, 206, 253, 355, 500, 509, 552, 591, 846, 853]
47.737563133239746

[228, 259, 323, 344, 363, 555, 564, 577, 913, 943]
38.77899479866028

[44, 67, 156, 185, 248, 452, 616, 859, 906, 936]
41.5284309387207

[122, 209, 223, 283, 311, 357, 363, 378, 707, 913]
9.765328168869019
```

１０個の要素をsortするのに約30~40ほどかかったことがわかる。
たまに運が良い時は10秒以下もみられた。
ｎ個の要素を並べる方法はn!個存在するので、要素が１個増えると単純に n+1 倍に時間が増えることが考えられる。

このように、非効率的な作業をコンピューターにさせないためにも、アルゴリズムの勉強をしないといけないことを実感した。
①Layout Editor 入門

拡大・縮小の方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039522/eba4c445-b0af-76b5-b565-7db09dcd8570.png)
マウスのホイールを回すと拡大・縮小が可能
（右下のスケール<font color="red">**赤枠部**</font>で確認可能）

画面の移動方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039522/277264e9-2cf2-7ff4-c40d-cc8b98393cc8.png)
右クリックしながらドラックすることで画面を移動させることが可能
（<font color="red">**赤丸**</font>で囲った部分の黒い点（x,y）=(0, 0)が移動していることが分かりますね）

背景色の変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039522/4204b61e-26c9-6cc1-f04a-c99ce60b4e5b.png)
左上のタブからUtilities→setup→Displayと進みます
すると次の様な画面になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039522/3e29223a-9680-2fae-5b39-37fc103388a0.png)
ここでcolorsタブからblack backgroundを選択し、OK
すると真っ黒な画面になりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039522/8f2df21b-4b91-ab8c-3247-2890eb8b4dd7.png)

今回の記事はここまで！
DynamoDB で複合キーに # が入ってる場合の読み込み方。TypeScript 経験者には当たり前のお話

# 背景
DynamoDB でも 複合キーが使える

Partition & Sort Key って意味ではなく
それぞれの Key の値自体が複合キーという意味で。

> [country]#[region]#[state]#[county]#[city]#[neighborhood]

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-sort-keys.html

てっきり、属性を定義してやれば、勝手に Partition/Sort Key に参照値が入るのかと思ったんですが・・以下しかないそうな

1. 複合キーを # で分割して、元の値を取得
    - 上記例で言えば、split(key value, "#") みたいにして、[country], [region] を取り出す
1. 複合キーとは別に、元の値を保存
    - 上記例で言えば、[country], [region] の属性を別に用意しておいて、利用する

でもって、PK/SK の命名もまた摩訶不思議
1. 色々なデータを格納できるように、PK/SK とする
1. 属性名を # 区切りで命名
    - 例）userID#timestamp

で、今回の本題

# TypeScript で、# を含んだ属性名をどうやって取得するのか？

普通の属性ならこんな感じ
```typescript: Stream からの取得
const itemID = record.dynamodb.NewImage.UserID.S;
```

同様にして、以下のようにやろうとすると

```typescript: Stream からの取得
const itemID = record.dynamodb.NewImage.userID#timestamp.S;
```

> SyntaxError: Unexpected identifier

TypeScript/JavaScript に慣れた人にとっては簡単なんでしょうけれど、素人はここで嵌まりました :laughing: 

で、TypeScript の文法を調べて解決したのが、以下

```typescript: 特殊文字などを含む場合の取得
const uidTime = record.dynamodb.NewImage["userID#timestamp"].S;
```

この後で、Splitする必要があるってのが面倒なんですが・・

# 複合キーの件を最終的に上記認識になった Q&A

AWS ドキュメントを色々探したり、実際に テーブル作成をしてみて、最終的に以下の回答を見て、認識とした。

> When reading the records back, **if you don't want to parse the combined field back out** to its individual parts, then you'll **have to add additional separate fields** for InvoiceNumber and LineItemID.

https://stackoverflow.com/questions/32620215/3-fields-composite-primary-key-unique-item-in-dynamodb

# あとがき
10年ほど前？は JavaScript はなんか読みにくくて嫌いな言語だったんですが、
TypeScript を触ってみると、あれ？こんなに書きやすいんだっけ？とビックリしてます。

VS Code のおかげなのか、チェーンが快適だからなのか、言語間で互いに良い点を取り入れていってくれてるおかげですかね？
Zabbix6.2でEC2の監視テンプレートを試してみた

# はじめに
先日、[Zabbix Conference Japan 2022](https://www.zabbix.com/jp/events/conference_japan_2022)に行ってきたんですが、そこで渡邉さんが便利なTemplateの紹介をしていて「おお！これは便利！実際に使ってみたい！」と思い、せっせこ設定をしてみました。
この記事はその作業内容をまとめたものです。

# 概要
Zabbix6.2で新たに追加された、AWSのEC2監視テンプレート、「AWS EC2 by HTTP」を使用します。
EC2のモニタリング情報（CloudWatchで取れる情報）をZabbixで監視できるようにするテンプレートです。
ちなみに、EC2以外にもRDS、S3とかも監視できるテンプレートも追加されていますよ。

# 手順

### Zabbixサーバの準備
まず、バージョン6.2以降のZabbixを用意します。でもそこの手順は割愛します（何）
手っ取り早くテンプレートを試したかったので、私は以下の構成でZabbix6.2を立ち上げました。

- EC2：AlmaLinux OS 9 (x86_64)
- インスタンスタイプ：t3.small
- Zabbix：6.2.4
- Apache：Apache/2.4.53
- DB：MySQL 8.0.30
- PHP：8.0.20

立ち上げてダッシュボード画面を見てみると「Geomap」なるものも表示されていて見た目が楽しそう(?)です。

![スクリーンショット 2022-12-08 22.58.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128331/3a0c0a09-229c-db3e-dd82-9a3e88a2d84d.png)

### AWSコンソール側の設定

まずはAWS側の設定です。
コンソール画面に入って、専用のIAMユーザーを作成します。
- ユーザー名：zabbix_template_aws_ec2（例です）
- AWS 認証情報タイプを選択：アクセスキー - プログラムによるアクセス
- アクセス許可の設定：ここではまだ設定をせずに、一旦ユーザーの作成を完了します。

※アクセスキー・シークレットキーがこの時点で払い出されるので、手元でメモっておきます。

次に、専用のIAMポリシーを作成します。
- ポリシー名：zabbix_template_aws_ec2_policy（例です）
- ポリシー：以下のJSONを登録します。

```
{
    "Version":"2012-10-17",
    "Statement":[
        {
          "Action":[
              "cloudwatch:Describe*",
              "cloudwatch:Get*",
              "cloudwatch:List*",
              "ec2:Describe*"
          ],
          "Effect":"Allow",
          "Resource":"*"
        }
    ]
  }
```

その後、先ほど作成したIAMユーザーにポリシーを紐付けます。
IAMユーザーの「アクセス権限を追加」で、 `既存のポリシーを直接アタッチ` を選び、同じく先ほど作成したIAMポリシーを紐付けます。
   
### Zabbixサーバ側の設定

Zabbixの `設定＞ホスト` から対象のホスト名をクリックしホスト設定内容の編集画面に入ります。
「マクロ」タブをクリックして以下の項目を設定していきます。
- {$AWS.ACCESS.KEY.ID}：メモっておいたやつ
- {$AWS.SECRET.ACCESS.KEY}：メモっておいたやつ
- {$AWS.REGION}：東京だったら、ap-northeast-1
- {$AWS.EC2.INSTANCE.ID}：対象EC2のインスタンスID

![スクリーンショット 2022-12-08 23.14.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128331/8d3d470c-8acf-f7ec-6468-f110c8fe15a8.png)

### 確認
監視データ＞最新データ で、`AWS EC2:なんちゃら` という項目が並びます！

![スクリーンショット 2022-12-08 23.16.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128331/cff77b8b-0279-a128-17c6-f3e004f995e0.png)

# おわりに

時おり、こうやって新しい情報に飛びつくようにしておかないと、化石みたいなエンジニアになってしまいますねｗ
日々精進です！
[interactions.py] Discord Botの作り方 #00 - Botの構築

# はじめに
この記事ではinteractions.pyというモジュールを使用してDiscord Botを作りたい人向けです。


#00ではBotの根幹の作り方について解説していきます。


:::note warn
Botの作成にはDiscordアカウントが必要です。アカウントがなければ登録しましょう。この記事では持っている前提で進めます。
:::

## Botの作り方
Discord上でBotを動かすためには [Discord Developer Portal](https://discord.com/developers/applications) にアクセスしてBotを作成する必要があります。


![ADF0CFB2-533C-4726-AEF2-323F59AC5049.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039218/3336a9e7-93b9-2ce0-365f-55e795114d4c.jpeg)
右上のNew Applicationを選択してして、アプリケーション名を入力して、下のチェックボックスにチェックし、Createを押します。
![E30E57CE-3A34-4A99-A136-726E92FF4974.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039218/66e352f0-9357-0ce4-6d9f-007461a3dda1.jpeg)
このような画面が出るのでBotというところを選択し、Add Botを選択します。確認メッセージが出てきたらYes, do it!を押しましょう。
![87EBBB65-3256-41CF-A60E-B6A30969A22C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039218/85177e99-c09f-6298-d289-7bc3cd0edbf7.jpeg)
こんな画面が出るので、Reset Tokenをクリックし、表示された文字列をコピーしてどこかにメモしておきましょう。次に下の方にスクロールして、
![DB706DA5-ADC9-428C-953E-DF687E9D9D65.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039218/7ae26830-19bc-5a42-bb61-cf50901e1033.jpeg)
下から3つにチェックを入れましょう。

これでBotが作成されました、次は自分のサーバーに追加していきましょう！

## Botをサーバーに追加する
![1FCE69E8-94D3-499F-B035-E11D6294E7CF.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039218/27e1ccea-b04e-0fc7-dd42-872b8469ba6d.jpeg)
次にQAuth2というところを選択し、Scopesというところを表示します。interactions.pyではbotとapplications.commandsというところを選択しましょう。
![7A7C6510-35C8-4832-8004-C4BC476FC059.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039218/8122ff2f-97ff-2fc9-9b4b-fd2025d5dd50.jpeg)
下の方にスクロールするとBot Permissionsというところが出ます。ここは権限設定などです。ここではAdministrator(管理者)にしておきました。
![C3C1F09C-6408-4181-8B52-D1E953E16569.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039218/4c9e7487-39a9-1520-de6d-38beffd83c83.jpeg)
最後にここに出てきたurlをコピーしてアクセスしましょう。
![6913CEDD-ADEE-430A-8AE3-1F2BDF0A03D9.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039218/d16d6c1a-5090-9012-be17-fa050fae4f81.jpeg)
Botの招待設定が出るので、入れたいサーバーを選択します。
そのまま進めていくと自分のサーバーにBotが追加できています。
![C6E3F12C-7769-43D4-B6FE-5F82800FE083.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039218/010b9923-8d67-8129-4d32-7030ba90df22.jpeg)
自分のサーバーにオフラインのBotが追加されていたら成功です！お疲れ様でした。

# 最後に

今回はBotの根幹の作り方について解説しました。
次回からは簡単なBotを作っていきます。

もし分からないところがあれば `Azusa#5812` に気軽にDMしてください。

# Discordサーバー

この度、bot開発者が話し合えるようなDiscordサーバーを開設しました！
ぜひ見に来てください！

https://discord.gg/nxBsFDgbFJ
JaCoCoのカバレッジをコンソールに出力する（Kotlin版）

とうとうサーバーサイドKotlinに片足を踏み入れようとしています。アプリ本体だけでなく、ビルドスクリプト（`build.gradle.kts`）もKotlinで書くと型があっていいのだとか。

でも、今まで動いていたあれやこれやが使えなくなって、正直二度手間感があります。というわけで、これのKotlin版。

https://qiita.com/oohira/items/d9dc72a0276834243bfd

## 動作確認バージョン

* Kotlin 1.6.21
* OpenJDK 17.0.5
* Gradle 7.5.1
* JaCoCo 0.8.8

## ビルドファイル

こんな感じか。GroovyもKotlinもビルドスクリプトは雰囲気で書いているので自信なし。

```kotlin
import org.w3c.dom.Element
import javax.xml.parsers.DocumentBuilderFactory

plugins {
    jacoco
}

tasks.test {
    useJUnitPlatform()
    finalizedBy(tasks.jacocoTestReport)
}

tasks.jacocoTestReport {
    dependsOn(tasks.test)
    reports {
        xml.required.set(true)
        html.required.set(true)
    }
    doLast {
        val report = file("${jacoco.reportsDirectory.get()}/test/jacocoTestReport.xml")
        printCoverage(report)
    }
}

fun printCoverage(xml: File) {
    if (!xml.exists()) return
    val factory = DocumentBuilderFactory.newInstance()
    factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false)
    val document = factory.newDocumentBuilder().parse(xml)

    val metrics = LinkedHashMap<String, Double>()
    val nodes = document.documentElement.childNodes
    for (i in 0 until nodes.length) {
        val node = nodes.item(i)
        if (node is Element && node.nodeName == "counter") {
            val type = node.getAttribute("type")
            val covered = node.getAttribute("covered").toDouble()
            val missed = node.getAttribute("missed").toDouble()
            metrics[type] = (covered / (covered + missed)) * 100
        }
    }
    logger.quiet("----- Code Coverage ----------")
    metrics.forEach { (key, value) -> logger.quiet(" - %-11s: %6.2f%%".format(key, value)) }
    logger.quiet("------------------------------")
}
```

## 出力イメージ

テスト実行するとカバレッジがコンソールに出力されます。

```shell
$ ./gradlew test
...
> Task :jacocoTestReport
----- Code Coverage ----------
 - INSTRUCTION:  15.00%
 - LINE       :  28.00%
 - COMPLEXITY :  25.00%
 - METHOD     :  25.00%
 - CLASS      :  60.00%
------------------------------
```

## まとめ

[GitLab CI](https://docs.gitlab.com/ee/ci/pipelines/settings.html#merge-request-test-coverage-results) などで必要になる、JaCoCoのカバレッジをコンソールに出力する方法のKotlin版を紹介しました。JaCoCo 本体で対応してくれてもよさそうなものですが、作者にその気はないので望みなしです。

* [Add TotalCoverage output to maven report #488 · jacoco/jacoco](https://github.com/jacoco/jacoco/pull/488)

他にも↑のPRにawkで抽出する方法なども紹介されているので、よかったら参考にどうぞ。
【個人的備忘録】これは使いたい！Djangoベストプラクティス2022

# この記事について
Djangoのベストプラクティスに関して調査して、これは使いたいと感じた事柄を記録として残します。

# Django基本構成

####  『[実践的Djangoプロジェクトの設計―開発・運用が楽になる設定ファイルを書こう！ アンチパターンとベストプラクティス](https://eh-career.com/engineerhub/entry/2022/11/14/093000#%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%A7%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AF%E3%81%A9%E3%81%93%E3%81%AB%E3%81%82%E3%82%8B%E3%81%AE%E3%81%8B)』

#### settings.pyを分割
- project/config/settings/以下にdev.py, prod.py, stat.pyのように環境ごとの設定を分けて用意しておく。それぞれは大元となるbase.pyをimportして、必要な箇所のみ上書きして使用する。
- 指定のsettingを使用したい場合は、環境変数DJANGO_SETTINGS_MODULEにファイルを指定する。

#### 秘密鍵等も環境変数から読み込むようにする
- 環境変数からsettingsへ読み込む際はdjango-environというライブラリを使用する。
- 環境変数一覧はpipenvを使用して、`.env`ファイルとして管理する。※ただし、実際の値はgitにあげないように注意する。あくまでテンプレートのみ。実際の値は手入力？

#### 疑似SMTPサーバーに接続する
- localhostにMailHogを立ててテストする。開発環境用。
- テストする時は、python manage.py sendtestmail "message"
- MailTrapというサービスも使えるよ。

#### メディアのアップロード
- 基本的には開発環境ではS3やCloud Storage等へはアップロードしない。
- する場合はdjango-storagesが使える

#### ログ
- 最低限ローテションする
- クラウドを利用している場合は、streamhandlerで吐き出して、cloud watch logsやcloud logging等に渡すのもアリ

#### Djangoのディレクトリテンプレート作成
- cookiecutter-django

# データベース設計のTips

- http://www.code-magagine.com/?p=697
    - 論理削除したユーザのログインIDを使えるようにするべきか？　もう二度と使えないままでいいのか?
- [DBの寿命はアプリより長い！ 長生きするDBに必要な設計とリファクタリングを実践から学ぶ](https://eh-career.com/engineerhub/entry/2018/12/11/110000)
- [データベース設計の際に気をつけていること](https://tech.tabechoku.com/entry/2020/06/15/132518#4-%E4%B8%80%E6%99%82%E7%9A%84%E3%81%AA%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A8%E6%B0%B8%E7%B6%9A%E5%8C%96%E3%81%8C%E5%BF%85%E8%A6%81%E3%81%AA%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E5%90%8C%E3%81%98%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AB%E3%81%AF%E5%85%A5%E3%82%8C%E3%81%AA%E3%81%84)
- https://security.stackexchange.com/questions/187426/how-to-get-better-iam-understanding
【UE4,UE5】UnrealC++をカテゴリー事にフォルダで分ける

皆様、いかがお過ごしですか。
今回はUnrealC++で新しいクラスを作る際にカテゴリー事に分ける方法を記事に書いていきます。

# 1 . 最初

「ContentBrowserで右クリックすればできるのでしょ？」

確かにBPでは可能ですが、C++ だと少し挙動が違います。
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/221052fd-487d-683b-cfb9-b51ccc365110.png)

# 2 . 事前準備
1.LiveCodingをOFFにする
2.「Private」「Public」フォルダを作る


## LiveCodingをOFFにする
Editorの右下点が3つ並んでいる場所をクリック
「Enable Live Coding」にチェックが付いている場合外してください
![2022-12-08-22-07-17_Trim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/aac1098e-7b78-53ff-7d49-3c73bb71d60b.gif)

## 「Private」「Public」フォルダを作る
以下の画像の様に「Private」「Public」フォルダを作ってください
### 最初の「P」は必ず大文字で！
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/6df60290-906c-3f24-0687-98e0d2b2411c.png)
```
プロジェクト名
 └ Source
   └ プロジェクト名
     └ Private
       Public
```

# 3. クラス作成

- 「New C++ Class」で継承する親クラスを選択
- 「Name」の上部にある「Public」「Private」のいずれかを選択
　（全部「Public」で大丈夫です）
- 「Header File」と「Source　File」が以下のPathになっている事を確認
```
プロジェクト名/Source/プロジェクト名/Private/クラス名.h
プロジェクト名/Source/プロジェクト名/Private/クラス名.cpp
```
- フォルダーアイコンをクリックし任意の名前を付けてフォルダの作成
- 「Create Class」を選択
- 勝手にコンパイルが走るので待機
- コンパイルが成功するとフォルダ分けされているかと思います。
![hoto.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/7256e657-e9aa-e4ff-42de-2fbd1698b7cb.gif)
![きゃぷぼ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/fa152eb6-992d-fe45-de9b-be6586d79c42.png)


# 4.締め

いかがだったでしょうか
自分もまだUnrealC++に慣れず悪戦苦闘の毎日です.....
これからも細かい記事を投稿していきますので、よろしくお願いします！！！
Go/Gin  HTMLテンプレートの使い方

<h2>Gin勉強の備忘録</h2>


***multitemplateのインストール***
```
go get github.com/gin-contrib/multitemplate
```

```:構成
Project名
    ├── main.go
    └── views
        ├── templates
        │   ├── template.html
        └── index
            ├── index1.html
            └── index2.html
```

***render.AddFromFiles(name string, ...filename string)
第一引数"name"をctx.HTML(http.statusOK, "\*\*\*\*\*", gin.H{})の第二引数に入れる***


```go:main.go
package controller

import (
    "net/http"

	"github.com/gin-contrib/multitemplate"
	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.Default()
	router.LoadHTMLFiles("views/**/*.html")
	router.HTMLRender = createMyRender()

    router.GET("/1", func(ctx *gin.Context) {
		ctx.HTML(http.StatusOK, "index1", gin.H{
            "title": "index1",
        })
	})

    router.GET("/2", func(ctx *gin.Context) {
		ctx.HTML(http.StatusOK, "index2", gin.H{
            "title": "index2",
        })
	})

	router.Run()
}

func createMyRender() multitemplate.Renderer {
	render := multitemplate.NewRenderer()
    //render.AddFromFiles(name string, ...filename string)
	render.AddFromFiles("index1", "templates/template.html", "index/index1.html")
	render.AddFromFiles("index2", "tmeplates/template.html", "index/index2.html")

	return render
}

```


```html:template.html
<!DOCTYPE html>
<html lang="en">
<head>
    <title>{{.title}}</title>
</head>
<body>
    {{template "index" . }}
</body>
</html>
```




```html:index1.html
{{define "index"}}
    <h1>this is index1</h1>
{{end}}
```



```html:index2.html
{{define "index"}}
    <h1>this is index2</h1>
{{end}}
```
amazon linuxに秒でmysql

ポイント
・もともとはいってるmariadbを消す
・キーをインポートする

sudo yum remove mariadb-libs -y
sudo yum install mysql57-community-release-el7-11.noarch.rpm -y
sudo rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
sudo yum install mysql-community-server -y
sudo systemctl enable mysqld.service
sudo systemctl start mysqld.service
sudo systemctl status mysqld.service
Javaで何か作ってみる(2022/12/8 Day49)

## 今日やった事
- オブジェクト指向の動画教材を見た。（**J2-03_カプセル化** まで見た。）
## 参考にしたもの
- [Spring 入門 ～ SpringBoot 2 を使ってお問い合わせアプリとToDoアプリを作る ～](https://www.udemy.com/course/java_spring_beginner/)  
- [【超初心者も必見】Javaプログラミングの「オブジェクト指向」が絶対理解できる講座【プロ講師が丁寧解説】](https://www.udemy.com/course/uz-java-obj/)  
## 所感
- private、protected、publicを意識するの、久しぶりだなと思った。
- C#をやってた頃は、privateを多用していた気がする。
- アクセス制御は、適切に出来るようになりたいなと思った。
## 明日の予定
- 引き続き、動画教材を進めていく。
VMwareCloud on AWSとAmazon FSx for NetApp ONTAPを使ったクラウドDRを考えてみた

## はじめに
VMwareCloud on AWS の利用を想定した現実的なコストで実装できるオンプレ環境のクラウドDRについて考えてみました。実環境での検証も実施したいのですが、まずは考え方のみの投稿です。

## 何がうれしいの？
- そこそこのコストでそこそこすぐ立ち上げ可能なDR環境の構築が実現できます

## 前提条件
- オンプレでONTAPストレージをvSphereのNFSデータストアとして利用している
- SnapMirrorのライセンスがある
- AWSのアカウントがある
- VMwareCloud on AWS のアカウント登録が完了していてSDDCの構築が可能

## このアイディアに思い至った仕様
- **VMware Cloud on AWSはホストが起動していなければ費用がかからない**
- VMware Cloud on AWSではAmazon FSx for NetApp ONTAPの既存NFSボリュームをデータストアとしてマウントが可能
- マウントしたNFSデータストアのvmxファイルをvSphereクラスターに登録可能（当然Power onも可能）

## 普段の運用
- VMware Cloudは契約のみでSDDCのデプロイはしないがいつでもデプロイできる状態にしておく
- オンプレのNFSデータストアをAmazon FSx for NetApp ONTAPにSnapMirrorでレプリケーションしておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1835328/8ad00c2e-294b-87fb-1811-47b56291cff0.png)


## DRシナリオ
- 災害でオンプレ環境が使えなくなる
- **VMware CloudにSDDC作成し必要なホスト数でvSphereクラスター作成（1時間くらい）**
- **転送しておいたNFSデータストアをマウント（5分くらい）**
- **データストア内のvmxファイルから仮想マシンを登録（リストア不要ですぐに利用可能）**
- **登録した仮想マシンを起動**
- **ネットワークまわりの設定を実施**
- 必要に応じてAmazon FSx for NetApp ONTAPの性能を動的拡張
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1835328/f47827c0-febd-4828-5e80-c112f3d9e26c.png)




## 注意点(2022/12/08時点）
- VMware CloudはSDDCバージョン1.20以降でAmazon FSx for NetApp ONTAPのNFSデータストア接続をサポート
- ストレッチクラスター構成はNFSデータストア接続を未サポート
- Amazon FSx for NetApp ONTAPのSingle AZ構成は未サポート


## まとめ
AWS上のAmazon FSx for NetApp ONTAPにデータストアのレプリケーションを実施しておく事でサーバーの準備なしでも緊急時にちゃんと稼働するDR環境が実現可能です。
今回のDRシナリオでは実際に災害時に初めてSDDCを作成しDR環境を起動するとなるとデプロイ後にネットワークまわりの設定も必要になり、その他vmxファイルの登録や登録した仮想マシンの起動も含めて自動化しておいた方がより短いリカバリ時間を実現可能です。

自動化のハードルが高い場合はVMCを2ホスト構成で作成しておき、災害時に必要な数だけホストを追加する運用であれば、よりスムーズなシステム復旧が可能です。


## 参考リンク
- **[外部ストレージとしての Amazon FSx for NetApp ONTAP の構成](https://docs.vmware.com/jp/VMware-Cloud-on-AWS/services/com.vmware.vmc-aws-operations/GUID-D55294A3-7C40-4AD8-80AA-B33A25769CCA.html)**
【VSCode】デフォルトターミナルを変更する方法

## デフォルト

デフォルトではLinuxおよびMacOSの場合`SHELL`に代入されているシェルが起動します。  

VSCodeを終了させた後にターミナルで次のコマンドを実行して再度起動します。  

```terminal
SHELL=/bin/bash code .
```

ターミナルを起動するとBashが起動します。  

![スクリーンショット 2022-12-08 16.19.52のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/3ecc4312-4466-aeae-2839-b7ae1cfcde14.png)

```terminal
SHELL=/bin/zsh code .
```

ターミナルを起動するとZshが起動します。  

![スクリーンショット 2022-12-08 16.26.52のコピー2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/effe7cdf-7cd6-7a82-f60e-84dae5675256.png)

特に`SHELL`の値を指定しない場合にはログインシェルのフルパスが`SHELL`に代入されます。  

`SHELL`の値を確認するには`echo $SHELL`を実行します。  

```terminal
$ echo $SHELL
/bin/zsh
```

## 既定のシェルを変更する方法

`settings.json`に以下のように記述します。  

```settings.json
{
  "terminal.integrated.profiles.linux": {
    "zsh (login)": {
      "path": "zsh",
      "args": ["-l"]
    }
  },
  "terminal.integrated.defaultProfile.windows": "zsh (login)"
}
```

するとLinuxでターミナルを起動するとの`zsh`がログインシェルとして起動します。  

また下画像の箇所より選択することでも設定できます。  

![スクリーンショット 2022-12-08 22.39.51のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/8b469013-04a7-4a07-538a-2b994ce8224d.png)
ABAP Keyword Documentation（ウェブ版）をChrome標準の翻訳機能で翻訳する

こんにちは。

小ネタです。
help.sap.comの[ABAP Keyword Documentation](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap.htm)のサイトが、ABAP7.57の情報が掲載されたタイミングでリニューアルされました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/e0cd19e9-241b-a0ec-e337-7ad47adb65d4.png)

しかし、このサイトリニューアル後にChrome標準の翻訳機能が使用できなくなっているようです。
検出された言語も日本語しかなく、さらには日本語に翻訳されていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/3a41255a-fd15-226c-b347-5eed6a41782c.png)

ウェブ版のABAP Keyword Documentationをブラウザで日本語訳ができるからと利用していた方には大ダメージではないかと思います:disappointed_relieved:
もちろん、Chromeの拡張機能を使う、Edgeなどの他ブラウザを使用することでページの日本語訳はできるのですが、そういった拡張機能はインストールできないし、別ブラウザのインストールもちょっとNG…と言う場合もあるかと思います。そのような場合にChromeの標準翻訳機能でページを日本語訳したい方は以下を参考にしてください。

・方法
１．記事のページを開きします。
「CREATE OBJECT」のページで確認してみましょう。
https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapcreate_object.htm
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/b0888f6f-04d2-08b1-a6f0-89f9c4df0fb9.png)
２．ページのURLから「index.htm?file=」を削除したURLのページを開きます。
左側のツリーの表示がなくなり、右側の記事だけのページになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/106dc891-0f33-4b0e-fdd0-b4b66475fee7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/5d37001c-2ad5-8599-d4e1-fcf70eb1154f.png)
３．このページは、Chrome標準の翻訳機能が使用できます。
先ほどと違い、英語と日本語が表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/2b86815e-82de-9545-4a50-bdcfd7ce0411.png)
そして、翻訳機能でページを日本語訳できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/fb25f47e-2c34-8364-e9bd-724b1e555b73.png)

※反面、ツリー表示がなくなってしまうので、ほかの記事に遷移したい場合はページ最上段の検索ボックスから記事を検索して遷移する必要があります。

## まとめ

・記事のURLを一部変更することで、ABAP Keyword Documentationの記事ページをChrome標準の翻訳機能で日本語訳できるようになる。

今回は以上となります。ありがとうございました。
Latexのコンパイルが終わらない原因(文字コード編)

### 短く終わります
---

citeのページ等で使われがちな"–"には気をつけましょう．
文字コードの問題でlatex側が読めないことがあるようです．

[ダッシュのWiki](https://ja.wikipedia.org/wiki/%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5_(%E8%A8%98%E5%8F%B7))
リファクタリング (refactoring) の際に大事なこと

## はじめに

こちらの記事は「[リファクタリングでシステムを安定化！日頃の取り組みや工夫を教えてください by カオナビ Advent Calendar 2022](https://qiita.com/advent-calendar/2022/kaonavi)」の 8 日目の記事として投稿しています。

[私(@changeworlds)](https://twitter.com/changeworlds)からは、私が普段から行っている取り組みや工夫についてご紹介いたします。

## 前提

よく機能追加とリファクタリング (refactoring) をごっちゃにして理解している人がいるため、リファクタリング (refactoring) とはどういうものなのかについてご説明します[^1]。

[^1]: 違いは十分理解しています！と多くの方がおっしゃるのですが、そういう人に限って、機能追加の Pull Request で機能追加と既存機能のリファクタリング (refactoring) やリアーキテクティング （re-architecting）の変更を同時にされるので、念の為ここでどういう意味でこの用語を使っているのかご説明しています。

### リファクタリング (refactoring)

> プログラムの外部から見た動作を変えずにソースコードの内部構造を整理すること

です。

## リファクタリング (refactoring) の際に最も重要なこと

リファクタリング (refactoring) の際に最も重要なことはリファクタリング (refactoring) の定義をご覧いただければ分かる通り、「プログラムの外部から見た動作を変えずに」行うということです。

プログラムの外部から見た動作を変えずに行わないと、リファクタリング (refactoring) したことが害悪にさえなります(=「プログラムの外部から見た動作を変えてしまった」)。

そのため、リファクタリング (refactoring) の際は自動テストで、「プログラムの外部から見た動作を変えずに」行っているかどうかチェックできるようにしておくことが大事になってきます。

## リファクタリング (refactoring) と自動テストの関係

リファクタリング (refactoring) における自動テストとは「プログラムの外部から見た動作を変えない = 挙動/振る舞いが変わっていないことをテストするもの」になります。

そのため、リファクタリング (refactoring) において自動テスト(を行っているテストコードへ)の変更をしてはいけないということです。

もし、あなたがリファクタリング (refactoring) の最中にテストコードの変更が必要になったのであれば、それは「プログラムの外部から見た動作を変えてしまっているため、リファクタリング (refactoring) ではない」か「自動テストのテストコードが適切なレベルで書かれていなかった」ことを意味しています。

## リファクタリング (refactoring) における適切なテストコード

プログラムの外部から見た動作を変えてしまっている、いないは簡単に分かることです。では、適切なレベルのテストコードとはどういうものかと言われてすぐに答えられる人はいないと思います。

リファクタリング (refactoring) における適切な自動テストコードとは end-to-end のテスト をするテストコードになります。

end-to-end のテストが何かわからない人はいないと思うのですが、「リファクタリング (refactoring) 際に end-to-end のテストコードを変更しないとテストに失敗する」とおっしゃる人が時々いらっっしゃいます。

実際、テストコードを見せてもらうのですが、常にそのテストコードは end-to-end のテストコードではありませんでした。

end-to-end のテストのつもりで、 end-to-end のテストになっていないケースは

* 直接関数を呼んでテストしている
* 状態をテストしていない

といったことがよくあります。

## 機能追加とリファクタリング (refactoring) の流れ違い

ここまでリファクタリング (refactoring) の際に大事なことをご紹介してきました。最後に実際に私自身が行っている機能追加とリファクタリング (refactoring) の流れについてご紹介します。

### 機能追加の場合

1. 機能追加するプロダクトコードを書く前にテストコードを書き、それが失敗することを確認する
2. テストに成功するように機能追加のプロダクトコードを書く

### リファクタリング (refactoring) の場合

1. リファクタリング (refactoring) する箇所の自動テストコードがあるか確認する
    * なければリファクタリング (refactoring) する箇所の自動テストコードを追加し、テストに成功することを確認する
2. テストコードとプログラムの振る舞いを変えずに、プロダクトコードを整理する

## おわりに

今回、私自身がリファクタリング (refactoring) の際に大事にしていることと、実際に私自身が行っている流れをご紹介しました。

ご紹介したリファクタリング (refactoring) の際に大事なことを行ってリファクタリング (refactoring) をすることで、システムが不安定になったり、ましてデグレードすることがなくなります。

適切なテストコードのレベルなど考える要素は増えてしまいますが、それによってシステムが不安定になったり、ましてデグレードすることがなくなるのであれば、みなさんにとって少しでも好ましい状況に変わるのではないかと思っていますので、今までされていなかったみなさんは今後試してみてください。
私の勉強法

# はじめに

私は、いつのまにか五十路になってしまいました、若い20代の自分に送る手紙として書きます。少しでも皆さんの役に立てれば幸いです。

# Udemyを使わないわけ
Udemyを使わないわけは三つあります。

1 コスパが悪い
2 信頼できる講師がいない
3 学習履歴の活かす機会がない

一つ目のコスパが悪いというのは、一つのコンテンツが、3000円くらいのことが多いようです。その金額を出せば専門書購入できます。

二つ目の信頼できる講師がいないというのは、誰でも講師になれるというのはいいことではありますが、専門書が大学の先生により書かれていることが多いことに比べると見劣りします。

最後に、後述しますが勉強した結果をログとして残すには機能が不足しているように思われます。

**Udemyを見るより、専門書を読みましょう。**

# 私の勉強法
私の勉強法は、私の読書法に他なりません。そこで、次の本をお勧めします。
この本は専門書ではありませんが、読むことお勧めします。

私の読書法　https://www.iwanami.co.jp/smp/book/b267406.html

この本は、20人くらいの人文科学者、自然科学者の方が読書法を書いています。

トップバッターの清水先生は次のように書いています。

::: note info

一口に読書法といっても、そこには二つの問題があるようである。

:::

## 一つ目の問題

::: note info

一つは、どういう書物を、どこで、いつ、いかに読むか、という問題で、、、

:::

何を勉強するのかは、その時の仕事の内容によります。したがって、専門書にしても、Udemyのコンテンツにしてもどれを選ぶかは人によります。プログラミング言語もpython node.js c 色々あります。

例えば、私は新人の頃e-learning担当としてコンテンツ開発の仕事をしました。そのため、取引先の方の紹介で、次の本を読みました。この話は、別にまとめたいと思います。

実践インストラクショナルデザイン 事例で学ぶ教育設計 

## 二つ目の問題

::: note info

そこで、もう一つの問題は、どんな本にしろ、読んだ本の内容をいかに保存するか、どうして後日の役に立たせるか、そのために、どんな工夫をするか、という点である。

:::

清水先生は、その後、ノート、情報カード、ルーズリーフに行ったあと、本に直接書き込むことを結論とされています。

私は次のことを結論とします。

**技術ノートをつけること**

理由は五十路になった時に自分の技術の遍歴がログとして見返せることが大切と考えるからです。

技術ノートというのは、博士が研究ノートをつけるように日々の技術の取り組みをログとして残すものです。

紙でなく、webサービス、例えばgitを使うことでも良いと考えますが。50年後もそのサービスが残っていそうなものを選ぶのがいいです。

# おわりに
この記事では、以下の要点でまとめて終わりたいと思います。

* 専門書を読もう。
* 専門書を読んだ後、技術ノートをつけよう。

技術を磨き、五十になった時に困らないように頑張ってください
Autify使ってみた

　テストの中でも時間を要するE2Eテストは自動化のコストが大きいし、作っても保守しづらくて大変である。これまでどれだけの開発チームがSeleniumで自動化しようとして心が折れたか想像に難くない。
　この難題を解決するために、E2Eテスト自動化サービスのAutifyを導入して自動化への道を歩み始めたので感想を話す。

# Autifyとは

　Autifyは、[Autiy, Inc.](https://autify.com/ja)が提供するノーコードE2Eテストである。ブラウザを操作することでその操作を記録し、その操作記録をそのまま自動テストとして使うことができる。
　Autifyの強みは、何といってもAIによるテスト自動メンテナンスだ。E2Eテスト自動化の難しいところとして、GUIに変更が入るとこれまで作成した自動テストが全てパーになる点である。Autifyは、GUIに変更が入ってもAIが勝手にそれっぽい部分を操作するようにテストシナリオを修正する。もし操作が間違っていても、AIに間違っていると教えることで次のテストから修正してくれる。
![テスト結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957034/f86ecf59-c68a-8f77-0a22-e1fef4dabe3c.png "Aiによる修正")
↑こんな感じで。
ここから、Autifyを使ってみて「良かった点」と「うーんな点」を紹介する。

# 良かった点１: テストが作りやすい・保守しやすい

　Seleniumを使っていた身からすると、この容易性と保守性は非常にありがたい。E2Eテスト自動化で苦労する点としては、コードから操作を想像しにくい点だ。
　Seleniumでテストを作る際は、
1. Chromeで検証タブを開く
1. 操作したい要素のXpathをコピー
1. Xpathを操作メソッドに食わせる

　と非常に手間であった。テストシナリオを一つ作るのに1時間かかることが普通であった。
　しかし、Autifyは画面を操作するだけでテストを記録できるので、1時間あれば3つのテストシナリオを作ることも可能である。しかも、操作だけでなくアサーションやURL遷移、別ウィンドウへの切り替えも記録してくれるためブラウザ一つで完結する。 以下は、アサーション追加のイメージ。対象のテキストが一致しているか、そもそも表示されているかなどもチェックが可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957034/931b7668-0af9-c9fe-58f0-e2a7a283bf6b.png)

　また、テストシナリオの編集画面も何をしている試験なのかが直観的で非常にわかりやすい。レコーディングした時の画面キャプチャがサムネイルに使われるため、どの画面で何を操作しているかが一目で判別できる。また、操作と操作の間に別の操作をレコーディングして挿入することも可能なので、テスト漏れがあっても簡単に修正できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957034/5495b9bc-9b99-452d-d52d-4d0e0091069c.png)

# 良かった点２: テスト結果がわかりやすい

　イメージに関しては、最初の画像を参照。前回のテストと今回のテストの操作画面を並べておいてくれるため、失敗したときに何故失敗したかが非常にわかりやすい。また、操作画面の差異を出力する機能が追加されたことでUI崩れの検知もできるようになった。以下の画像のように差異部分を色付けで示してくれる。
![Screen Shot 2022-06-30 at 19.48.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957034/08926c6d-44a7-559a-2c88-e37dd33b2abc.png)


# 良かった点３: メールテストが可能

　どうしても手動になりがちなメールのテストまで自動化可能。ランダムでも固定でもメールアドレスを作成し、受信したメールをブラウザに表示するため、メール文面チェックも自動でできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957034/0afb64ea-92cb-247e-6dc5-18c1e9d1e549.png)
　また、JSステップというJavaScriptを実行する操作を使うことで、メール内から文字列を抽出して別の操作に使用することもできる。これによりパスワードリセットなどでメールで届くパスワードを抽出して、ログインできるかを試験可能である。

# うーんな点： GUIのデザイン次第では想定と異なる動作をしがち

　AI君は優秀だが、張り切りすぎて異なる操作をすることがある。特に苦手なのは、表形式で表示されたデータである。
　以下の画像の赤線で囲んだ部分に注目してほしい。AutifyのAI君はこの4つのアイコンの区別が付かないのである。厳密に言うと上から2番目のアイコンを押したと記録した時は、絶対に上から2番目のアイコンを押してしまう。その横に表示されるデータが異なっていてもお構いなしに押してしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2957034/7fe9a49c-0ab0-7409-5fd8-0fdb938cda60.png)
　これにより、想定と違うデータを編集したり削除したりするため、一度成功したのに次は失敗するということが発生し、過去のテストを遡って原因を探す羽目になる。そのため、検索機能などを実装して表形式で表示するデータを絞る、いっそ自動化しないなど対策が必要となる。

# まとめ

　いかがだろうか。最後の欠点はともかく、E2Eテスト自動化ツールの中ではとても優秀なサービスである。ノーコードなので学習コストも高くないし、使いこなすことができればどんなITサービスでもある程度自動化できるだろう。Seleniumでもう苦しみたくないという方には、検討を手放しでお勧めする。
ここが辛いよSIer

# プログラマーとして
- 設計書からプログラミング言語に翻訳するだけ
- 社内フレームワークを使っているため技術介入ゼロ
- 分からないことはググっても出てこない、おっさんに頭を下げて聞かなければならない
- 自分が作ったプログラムがなんの役に立つのか分からない
- でもバグったときはちゃんと仕様理解して作ったのかとか詰められる


# サラリーマンとして
- あまり勉強に時間を割いていないおっさんと過ごすことになる
- パワハラ気質
- AIだーDXだーと世の中の流行に振り回されるけど、廃れてから導入される
- 配属先、上司、取引先ガチャ

# そんな中で何ができるか
- 技術者でありたいという気持ちを捨ててワークライフバランスを味わう
- いつか来るであろう昇格昇進のときを指をくわえて待つ
- おっさんとのコミュニケーションを省エネでやり過ごす
- マネジメント経験を積み、かろうじて転職への望みを残す
【Playdate】フォントを自作して読み込んで使ってみる

Playdateでは`Caps`というブラウザベースのフォント作成エディタがあり、フォントを自作することができます。
英数字の他、ひらがなやカタカナ、記号なども対応しています。
<img width="843" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100912/0590bba4-6651-8e36-06f1-ec2847a3bf77.png">

今回はCapsでPlaydate用のフォントファイルを自作し、プロジェクトに読み込んで使ってみます。
ベースとなるプロジェクトは[こちら](https://qiita.com/sada_lp1/items/1751040555361bae33b7)を使用します。

## Capsからフォントファイルを生成する

https://play.date/caps/

Capsはplaydateサイトにログインした状態で上記URLにアクセスすると起動することができます。
左側メニューの Font がフォント全体の設定で、制作済みフォントの読み込みもここから行えます。
Glyphs が各文字の一覧となり、ビットマップとしてフォントを描画します。
Kerning が文字同士の間隔を調整する画面ですが、英文テキストの多いゲームで無い限り使う機会はほぼないと思います。

一つひとつフォントを作成していっても良いですが、今回は美咲ゴシックをベースにして予め作ってあるデータを使います。
下記URLから、`Misaki.fnt`と`Misaki-table-8-8.png`をダウンロードします。

https://github.com/sadakitchen/playdatecaps_jp

次に Font メニューから`OPEN`を押下し、`Misaki.fnt`を選びます。
選択後以下のダイアログが表示されるので`OPEN`を押下し、`Misaki-table-8-8.png`を選び、`FINISH`を押下するとフォントが読み込めます。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100912/c93754a8-1292-e6ac-0720-72f8cfa85fa4.png">

読み込んだ後、統合されたフォントファイルとしてダウンロードします。
左側の`SAVE & DOWNLOAD`の下を`All-in-one`にし、`SAVE & DOWNLOAD`を押してファイルをダウンロードします。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100912/cad50c99-29a4-0635-ac11-d4a488851cb9.png">

## フォントファイルを読み込んで使用する

ダウンロードしたフォントファイルをプロジェクト内に配置します。
格納先は以下のようにしました。

```
myProjectName/
    source/
        main.lua
        Images/
            playerImage.png
            background.png
        Fonts/
            Misaki.fnt ← 追加
```

次のフォントの読み込みです。

```main.lua
import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
import "CoreLibs/timer"

local gfx <const> = playdate.graphics

local playerSprite = nil

function myGameSetUp()
	
	local fontFamily = gfx.font.new( "Fonts/Misaki" ) -- フォント読み込み
	gfx.setFont(fontFamily) -- 読み込んだフォントをセット

	local playerImage = gfx.image.new("Images/playerImage")
	assert( playerImage )

	playerSprite = gfx.sprite.new( playerImage )
	playerSprite:moveTo( 200, 120 )
	playerSprite:add()

	local backgroundImage = gfx.image.new( "Images/background" )
	assert( backgroundImage )

	gfx.sprite.setBackgroundDrawingCallback(
		function( x, y, width, height )
			backgroundImage:draw( 0, 0 )
			
			gfx.setImageDrawMode(gfx.kDrawModeFillWhite) -- 塗りを白くする
			gfx.drawText("こんにちは!", 176, 80) -- テキスト描画
			gfx.setImageDrawMode(gfx.kDrawModeCopy) -- 塗りをそのままにする
		end
	)

end

-- 以下略 --
```

`gfx.font.new( "Fonts/Misaki" )`でフォントファイルを指定して読み込み、`gfx.setFont`で読み込んだフォントをセットしています。
制作したフォントは黒塗りなので`gfx.setImageDrawMode(gfx.kDrawModeFillWhite)`で塗りを白くするようにし、
`drawText`でテキスト描画後、`gfx.setImageDrawMode(gfx.kDrawModeCopy)`で塗りをそのままにするよう戻しています。
ビルド後は以下のような画面で出力されるはずです。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100912/eb38c701-c8e5-de75-a2b2-26fcee1d9319.png">
某魔法高校に通う"さすおに"の拳銃型の術式演算を補助してくれそうなものを作る

Covid-19が流行し始めたころ、著者はサークルの３Dプリンタで推しキャラが使用しているデバイス的なやつを作りたいと思ったので作りました。

## 準備
まず、資料を入手します。今回は**偶然**私が作りたいと思っていた作品のイメージに近いものが登場する[魔法科高校の劣等生の設定資料集](https://www.amazon.co.jp/%E3%82%A2%E3%83%8B%E3%83%A1%E3%80%8E%E9%AD%94%E6%B3%95%E7%A7%91%E9%AB%98%E6%A0%A1%E3%81%AE%E5%8A%A3%E7%AD%89%E7%94%9F%E3%80%8F%E3%83%8E%E5%85%A8%E3%83%86-%E9%9B%BB%E6%92%83%E6%96%87%E5%BA%AB%E7%B7%A8%E9%9B%86%E9%83%A8/dp/4048929968)を購入します。
![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/873754/109c2487-e8b3-a094-ca8f-a9bc79ffb3ae.jpeg)
引用: https://movie.mahouka.jp/special/icon.html
角度が悪いけど、手にもっているやつ（Casting Assistant Device 通称CAD（読みはキャドではなくシーエーディー））がイメージに近い。

## 設計
寸法は設定資料集に書かれていたので、それを参考にしました。寸法が書かれていない箇所は定規で計って寸法が書かれている箇所との比をとった値にしました。
寸法が分かったあとは、CAD（こちらはComputer Aided Designの略）でCADみたいなやつをモデリングします（紛らわしい）
そして、モデリング出来たものがこちら。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">自分をトーラス・シルバーと思いこんでいるのでCADでCADをモデリングした。 <a href="https://t.co/W42bEk7hzm">pic.twitter.com/W42bEk7hzm</a></p>&mdash; よしみ✴︎. (@labo_4423) <a href="https://twitter.com/labo_4423/status/1251899179628036096?ref_src=twsrc%5Etfw">April 19, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

刻まれている文字に関しては、本家が"SILVERHORN TRIDENT"なので、著者は"Twilight"にしました（トライデントと語感が似てる＆意味もなんか良さそうだった）

## 印刷
手近な３Dプリンタを使って印刷します（今回はABSで後から塗装しやすいように白のフィラメントを選択）
出来上がったものがこちら
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">出来た <a href="https://t.co/d3vmKJlkD5">pic.twitter.com/d3vmKJlkD5</a></p>&mdash; よしみ✴︎. (@labo_4423) <a href="https://twitter.com/labo_4423/status/1263392278657118208?ref_src=twsrc%5Etfw">May 21, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 塗装
著者はプラモデルとかの塗装経験が無い（家の物置や自作したベンチの塗装ならある）ので、成績優秀高身長イケメンの頼れる後輩（先輩の威厳皆無）に手伝ってもらいました。（といっても、インクの準備など9割ぐらいやってもらった記憶がある）
出来上がったものがこちら
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">塗装を手伝って貰った！ <a href="https://t.co/tby11hMGez">pic.twitter.com/tby11hMGez</a></p>&mdash; よしみ✴︎. (@labo_4423) <a href="https://twitter.com/labo_4423/status/1265575529979293696?ref_src=twsrc%5Etfw">May 27, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

マスキングテープを使うと塗装が楽にできることを学べた。
これで好きなときに、「さすがはお兄様！」と言って貰えそうな気分になれますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/873754/8f05abf1-3fad-8618-18b3-37e0fc8567a7.png)
引用: https://twitter.com/mangatimekirara/status/1580877325574369280?s=20&t=hEar7GDTkLMIEMpfBqkzWg
【ActiveRecord::PendingMigrationError】Migrations are pending.

# エラー内容
* `ActiveRecord::PendingMigrationError`というエラーが表示された。 Migrations are pendingらしい。
![ActiveRecord PendingMigrationError.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/f11db91b-b00c-34a2-3955-b35e114abc75.png)

# 解決方法
* 以下をもう1回実施したら解決した。
    * `rails db:create`
    * `rails db:migrate`
error Your lockfile needs to be updated, but yarn was run with `--frozen-lockfile`　のエラー解決方法

# エラー内容
* Herokuのデプロイ時に以下エラーが発生。`--frozen-lockfile`に問題があるのか？

```
remote:        error Your lockfile needs to be updated, but yarn was run with `--frozen-lockfile`.
remote:        info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/ajax-app-37383.git'
```

![error Your lockfile needs to be updated, but yarn was run with `--frozen-lockfile`..png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/78117ece-73fe-c057-1b31-3e2e938ddc7f.png)

# やってみたこと
* bundlerのバージョンがエラーの原因かと思い確認したが、特に問題なし。
* `package.json`に記載のバージョンが違うかどうか確認したが、特に問題なし。
* 同じような症状があったので`git pull origin master`を実行したが、変わらず。
    * [HerokuへPushしたら ! [remote rejected] master -> master (pre-receive hook declined)　が出た](https://qiita.com/momo1010/items/b376ba1463425b792efa)
* `--frozen-lockfile`が関係ありそうなので、以下記事を参考に`yarn install --frozen-lockfile`を実行したが、変わらず。
    * [error Your lockfile needs to be updated, but yarn was run with `--frozen-lockfile`](https://gist.github.com/kenmori/2b31d0cde603751cf92afe2e2bb20263)

# 解決方法
* HEROKUのエラーは黒字の所にもあるので、英語を読んでみるのが良い。以下が書いてあるので、一つずつ実行してみる。
```
remote:        $ yarn install
remote:        $ git add yarn.lock
remote:        $ git commit -m "Updated Yarn lockfile"
remote:        $ git push heroku main
```
* 上記実行したところ、解決！
* 結論、原因はわからないが`yarn`に問題があったということ。
    * アプリごとに作成するものだが、ajax_app作成時にエラーになったのか、パソコンの不具合でこうなったのかまでは不明。
* そして、赤字ばかりにとらわれずにしっかり黒字の部分もみろ！という教訓になりました(;'∀')

# 新たなるエラー
* 上記と関係あるかよくわからないが、以下画面になったので解決方法をメモしておく。
![image7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/90e621be-2911-a4ac-44a4-69003755c02b.png)

* やってみたこと・解決手順
    * `heroku logs --tail --app ajax-app-37383` でログを確認してみる
    * `heroku run rails db:migrate`
    * `Mysql2::Error::ConnectionError: Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)`というエラーがあったので、以下記事を参考に`socket: /tmp/mysql.sock`をいれてみたが変わらず。
        * [【Rails】ローカル環境におけるmysql接続エラー対処法【Can't connect to local MySQL server through socket】](https://qiita.com/ngron/items/306ffbf6a0e3d0abd385)
    * `heroku addons:add cleardb`の実行エラーと思われる。こちら再実施で解決！！
【AirPlay】MacBookやiPhoneで再生中の動画をワイヤレスでテレビやモニターに映して、かつWi-Fiスピーカーを使用する方法

# ◆前書き
## 動機
MacBookやiPhoneで再生中の動画を他のディスプレイに映し出せたら便利だなぁと思う場面、たまにあると思います。
で、これはChromecastやFire TV、Apple TVなどを使えば簡単に実現できるのですが、一つ問題が発生します。

それは、「音はWi-Fiスピーカーで再生したい」という場合。

![IMG_3408.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169376/dd64ba76-cfc5-7c9e-09fa-589767c2e353.jpeg)

「(あそこのディスプレイとWi-Fiスピーカーで、アマプラ観れたら便利だよなぁ...)」

実は、動画は他のディスプレイでも「音は手元のデバイス or 他のディスプレイに付いているスピーカー」ということであれば何も難しいことはありません。
しかし、**「音はWi-Fiスピーカーで再生したい」と思った瞬間、急に苦戦する**ことになります。

なんで苦戦するかというと、この構成にする人が少ないからなのか、全然情報が出てこないからです。

というわけで、私がまとめておくことにしました。

## 準備
[Apple TV](https://amzn.to/3uxyizh)が必要です。
![IMG_3384.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169376/177b423c-0cff-2257-d2be-1487f3e75796.jpeg)
![IMG_3388.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169376/98ee949c-a848-3e84-e6a9-867ec6361ce5.jpeg)
![IMG_3389.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169376/b2e5202a-b8b8-9ab3-7a69-8295bc854566.jpeg)


# ◆本編
## 構成
### うまくいくパターン
▼うまくいくのはこのパターンだけです。
![IMG_3406.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169376/bebe4e5c-c47f-7469-5cc1-27edfb23937d.jpeg)

### うまくいかないパターン

▼MacBookやiPhoneでは、AirPlayではなくミラーリング機能を使うと、Apple TV 4Kに画面をそのままキャストできます。しかし、このやり方では、Wi-Fiスピーカーを設定することができません。
![IMG_3404.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169376/d928f596-e5b8-37fe-5e06-9da64cbec7a9.jpeg)


つまり、Wi-Fiスピーカーを使うためには、ミラーリングではなくAirPlayによるキャストが必須というわけです。

#### さらに解説

▼そもそも、ワイヤレスでなく有線であれば次の構成でうまくいきます。
![IMG_3407.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169376/0af69916-daca-e9cb-b592-b9a9bc18d960.jpeg)

Apple TV 4Kは、この有線の構成におけるApple製品の役割を果たしてくれてるわけですね。
このApple TV 4Kに、MacBookやiPhone上の動画をキャストする仕組みが「AirPlay」です。

## 設定
### Apple TV 4KでのWi-Fiスピーカーの設定方法
+ Apple TVの「設定」を開きます。
+ 「ビデオとオーディオ」を選択します。
+ オーディオ出力でWi-Fiスピーカーを選択します

この状態で、Apple TV 4Kに、AirPlayでキャストすれば映像はディスプレイから、音はWi-Fiスピーカーからが実現します。

### AirPlayの設定方法
iPhoneの場合、大抵の動画配信サービスでは、AirPlayのボタン(テレビマークみたいなやつ)が出てきます。それをクリックして、Apple TV 4Kを選べばすぐにディスプレイに映像がキャストされます。
※このとき一緒にWi-Fiスピーカーを選ぶと、せっかくApple TV 4Kに設定したWi-Fiスピーカーが解除されてしまうのでNGです。

MacBookの場合、AirPlayボタンはApple TVのアプリや、**Safariブラウザでしか表示されません**。ChromeやFirefoxなど、他のブラウザは非対応なので注意が必要です。(誰かChromeにAirPlayボタン表示するExtension作ってくれ)

# ◆後書き

これで無事に、映像はテレビから、音はWi-Fiスピーカーからが実現しました。

![IMG_3395.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169376/3f076bfa-fe97-1cd5-cd2e-78a1211d7e71.jpeg)
SECCON Beginners CTF 2022解けなかった問題を勉強した記録

# gallery

gallery (83 pt) 
author:task4233
easy
絵文字のギャラリーを作ったよ！ え？ギャラリーの中に flag という文字列を見かけた？
仮にそうだとしても、サイズ制限があるから flag は漏洩しないはず...だよね？

https://gallery.quals.beginners.seccon.jp


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/cf92de00-5b9e-82c5-b57f-5f8d9f7bb7ea.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/68d15c82-7ace-e818-a172-910f81185118.png)

```go:main.go
func middleware() func(http.Handler) http.Handler {
	return func(h http.Handler) http.Handler {
		return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
			h.ServeHTTP(&MyResponseWriter{
				ResponseWriter: rw,
				lengthLimit:    10240, // SUPER SECURE THRESHOLD
			}, r)
		})
	}
}
```

10240までしかレスポンスで返ってこない。

HTTP Range Requestsを知ってれば解ける問題だった。

```
$ curl -X GET -H 'Range: bytes=0-10239' https://gallery.quals.beginners.seccon.jp/images/flag_7a96139e-71a2-4381-bf31-adf37df94c04.pdf --output - > 0.pdf
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 10240    0 10240    0     0  37785      0 --:--:-- --:--:-- --:--:-- 37925

$ curl -X GET -H 'Range: bytes=10240-20479' https://gallery.quals.beginners.seccon.jp/images/flag_7a96139e-71a2-4381-bf31-adf37df94c04.pdf --output - > 1.pdf
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  5845    0  5845    0     0  29670      0 --:--:-- --:--:-- --:--:-- 29821

$ cat 0.pdf 1.pdf > ans.pdf
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/78baf235-f07a-3a2b-caf8-498b8e884cc0.png)

# H2

H2 (69 pt)
author:xrekkusu
easy
バージョン2です。
h2.tar.gz

まさかのpcapをctf4bで検索するだけ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/dc9abec5-5f83-e116-ebca-7537522219df.png)
NRQLの最新アップデートベスト5

特にNew Relicを使い倒したいエンジニアに好まれるNRQL。
NRQLは日に日に進化しているのですが、そんなのキャッチアップする時間ない！という方々の方が多いのではないかと思います。
そこで、独断と偏見で選んだ便利なアップデートを皆様にご紹介します！

1, NRQLのQuery Builderで改行
　クエリを書いていると、そんなに長くなくても可読性を上げるために改行したい場合があ理ますよね？
　そんな時は 「Shift + Enter」! 
　なんとついにクエリを改行できるようになったのです！
　この記事はこれで終わりと言ってもいいくらいNRQLコーダーにはハッピーな機能なのでこれだけは覚えておいても損はないかと。
![スクリーンショット 2022-12-08 21.43.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44982/077c8f72-17c5-ed7d-aebb-b15951d14b56.png)


2, WITH句でクエリ本文をスッキリ見せる
　NRQLウキウキしながら書いてるとついつい長くなってしまいますよね。ならないですか？
　例えば長い文章から文字を引っ張ってくれる aparse。マッチングルールって長くなりがちなのでちょっとクエリのなかに入れるのも・・・
　そんな時にWITH句に逃してやればあら不思議！クエリがこんなにシンプルに。
　解析した結果をSELECT句で使いたかったりWHERE句で使いたかったりしたときに、いちいち個別に解析していたのがまとめて解析して利用できるようになりました。
　![スクリーンショット 2022-12-08 21.43.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44982/42652461-9631-fd39-419f-ad73ce0fe4cb.png)


3, if文でデータを ~~改ざん~~ 改善
　コードを見てもよくわからない！わかる言葉で話して！私もよく言われがちですが、ログだったりステータスコードもそうですよね。IF文を使えば、条件に応じて値を変更して表示できます！
![スクリーンショット 2022-12-08 21.44.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44982/dbbaa867-a83f-379b-68a6-f870e52e3e85.png)


4, concatで文字をつなげる
　チャートタイプがTableの場合、文字列がURLの場合外部リンクとなる特性があります。クエリできる情報を使うと、New Relic の他の画面へのリンクを作ったり、外部のサービスへのリンクを作ったり・・・　夢が広がりますね！詳しくはこちらをご確認ください。
![スクリーンショット 2022-12-08 21.45.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44982/604b54d0-4934-87c4-c6e5-0568d9dd3fbe.png)


5, その他諸々の文字列操作
　aparseやconcatもそうなのですが、今年の後半でかなり文字列操作が増えました。アイデア次第で表示や分析の幅が広がりますね！

concat(val, val…) : 値を繋げて文字列とする
aparse(str, pattern) : 文字の一部patternに従って抽出する
substring(str, start, [length]) : 文字列の一部を切り出す
Position（str, substr, [occurrence]) : 文字の位置を
upper(str) : アルファベットを全て大文字にする
lower(str) : アルファベットを全て小文字にする


最近の機能追加だけでもかなり強力になってますね。すごいぞNRQL！

今後も進化していくNRQLにご期待ください！
オーケストレーション型のSagaパターンのトランザクション周りの考察


# 前提　
この投稿は[ZOZO　アドベントカレンダー２０２２ #1](https://qiita.com/advent-calendar/2022/zozo)　9日目の記事になります。

マイクロサービスの特にSagaパターンについてあれこれ調査したので、そのアウトプットになります。
今回の記事は、マイクロサービスの詳細や実装、コレオグラフィ型のパターン、envoy周りの実装、またはAkkaなどフレームワークの使用については述べず、単にオーケストレーション型のSagaパターンの特にトランザクション周りについて記事にしたいと思います。

# 非同期API連携

Sagaパターンで分散トランザクションを実現しようとしたとき、各サービスとやりとりについては、非同期APIを利用してすることになるかと思います。（一旦envoyのようなPROXY経由でのアクセスについては置いておきます）

図にするとこんな感じになるかと。

![木目モ (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150455/722a39b8-558c-6a4a-325e-76e30be617ec.jpeg)


ポイントになるのはWコミットを避けるため、トランザクションは各サービスごとに行い、問題があれば、各サービスで実施した内容の逆をもう一度行いリセットするいわゆる「補償トランザクション」を行う点になります。

このとき、自分が気になったのは、各サービスの実行とレスポンスを返す処理（メッセージ送信）間のトランザクションです。

たとえば、下図の場合、SeviceBが失敗した場合、レスポンスし、SeriveAのオーケストレーターでServiceAのDBを元に戻す処理を行います。

![木目モ (4).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150455/7996465d-a485-7fac-e239-e344ceece533.jpeg)

気になるのはこの後で、最初のServiceAの処理でDBには登録できたが、Request1のリクエストでコケた場合どうなるか、これも図にしてみました。

![木目モ (5).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150455/ff52f571-9a8a-02a5-e598-28ad99f2986e.jpeg)

補償トランザクションの処理を書く場所は一つにまとめられているし、オーケストレーションするサービス内に全てあるので、複数箇所から呼ばれるのはあまり問題ないようにも見えるのですが、複雑度はあがるなぁと思いました。

# Outboxパターンを併用

すごく細かいですが、Outboxパターンを併用すると各補償トランザクションは1箇所からしか呼ばれないのでスッキリします。図にするとこんな感じ。

![木目モ (7).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150455/1d061ebc-639e-26d3-ec82-572256c99acd.jpeg)


# まとめ

基本的にアーキテクチャをシンプルにするとコードは複雑になりがちで、コードをシンプルに保とうとするとアーキテクチャが複雑になりがちです。
そのあたりはトレードオフかと思いますが、良い選択をしていくためにもまずはこういった考察は必要かなと思っています。
【Flutter】keyboard_actionsでAndroidの実機のみ、bottomに固定されたままキーボードの下に隠れてしまう問題

どうも個人でアプリ開発をしているYuKiOです。

今回紹介するバグは、特殊な状況だと思いますが、原因を発見するためにかなり悩まされたので記録として残しておきます。
どなたかの役に立てば。

## 実現したかったこと。
今回アプリの入力フォーム使用時に、キーボードにボタンを導入したかったため、keyboard_actionsを導入しました。このpubを使えば、簡単にキーボード上部にボタンを追加できます。
https://pub.dev/packages/keyboard_actions

## バグの内容
導入自体は問題なかったのですが、Androidの実機だけkeyboard_actionsで追加したメニューバーが下部に固定されたまま、キーボードの下に張り付いてしまう現象がありました。

## 原因
android/app/src/main/res/values フォルダーのstyles.xmlに以下を追加していたのが原因でした。

```styles.xml
<item name="android:windowFullscreen">true</item>
```
おそらくAndroid12あたりの対応で、スプラッシュスクリーンを全画面表示にしたくて入れたのかな？と思います。今のところ全画面表示にするか、keyboard_actionを使うか選ぶしかなさそうな感じです。


アプリについていろいろ発信しているので、ぜひ覗いてみてください。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">HackerMemoを大幅にアップデートしたので、<br><br>海外向けのPVを作ってみました😆<br><br>夜なべして頑張って作ったので、拡散頂けたら泣いて喜びます😭🙏<br><br>音有りがオススメです！<br><br>元ネタわかる人いるかな〜🤔<br><br>アプリはこちら🔽<br>■iPhoneの方<a href="https://t.co/6T10L94Ld1">https://t.co/6T10L94Ld1</a><br><br>■Androidの方<a href="https://t.co/uBevCXrNw2">https://t.co/uBevCXrNw2</a> <a href="https://t.co/wiGLv46kaG">pic.twitter.com/wiGLv46kaG</a></p>&mdash; YuKiO｜アプリ個人開発｜Flutter × Firebase (@oo_forward) <a href="https://twitter.com/oo_forward/status/1348103082769453056?ref_src=twsrc%5Etfw">January 10, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Symbol XYM 買いボット tikutikukun

皆様、こんにちは。こんばんは。
昨年末からの下落相場に遠い目になっている @curupo です。
Symbol XYM も同様に下落しておりまして、なんとかならんものか…と思っておりました。
そんなときに自動売買ボットを開発している @noway_pway さんのツイートが目に止まりました。

https://twitter.com/noway_pway/status/1599363626728849412

あぁそうかと。売り圧に対して買い圧が足りないんだねー。
買い圧が増えなきゃねーと思い、さっそく自分も少額でボットを動かしてみました。
おー、ちくちく買い増してんなと。
自分も以前phpで下落したところを自動で買いを入れるボット作ったりしてみたんですが長続きませんでしたね、ハイ。で、VPSを借りるまでいかなくても、とりあえず手持ちのPCで tikutikukun ボットを動かす人が少しでも増えたらいいんじゃないのかなと思いました。良かったら動かしてみてください。

tikutikukun作者は https://twitter.com/noway_pway さんです。
ありがとうございます！

前提
-
* Zaifにアカウントをもっていること。
    * https://zaif.jp/
* ZaifのAPI接続を可能にするkeyとsecretを発行してあること。要厳重管理！
    * https://zaif.jp/api_keys
* Zaifのアカウントに1万円～程度の軍資金を円で用意しておく

事前にインストール
-
* VirtualBox
    * https://www.virtualbox.org/
* Vagrant
    * https://www.vagrantup.com/
* Git Bash
    * https://gitforwindows.org/

tikutikukun をWindows上で動かすまで
-

[Git Bash]で操作
-
仮想サーバをPC内に作成します
$ mkdir /c/local/vagrants/tikuvm
ディレクトリを移動します
$ cd /c/local/vagrants/tikuvm
LinuxはUbuntuにしておきました。※なんでもいいです
$ vagrant init bento/ubuntu-22.04
VMを起動します
$ vagrant up

最新のスクリプトをgigafileからダウンロードし、エクスプローラーで /c/local/vagrants/tikuvm 配置にします。
最新版は tikutikukun_v1_13.py です。
https://twitter.com/noway_pway/status/1600568389579046912

↓こうします。
/c/local/vagrants/tikuvm/tikutikukun_v1_13.py

VMにログインします
$ vagrant ssh

[VM内]で操作
-
最新化
$ sudo apt update
python3とpipをインストール
$ sudo apt install python3-pip
バージョン確認
$ pip3 --version
Zaifのライブラリをpipでインストールします
$ pip install zaifapi
自身のAPIキーとSecretを書き換えます。
※viを使ったことがなければ、Windows側でメモ帳などで編集してください。
$ vi /vagrant/tikutikukun_v1_13.py
```
zaif_KEY    = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Apiキーを入力
zaif_SECRET = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" # Secretキーを入力
```
自分のお好みの設定にします
$ vi /vagrant/tikutikukun_v1_13.py
```
bid_amount = 1 # 一回のトレード枚数
wait_time = 10 # 何秒に1回トレードするか(実際は処理時間+ wait_time(秒))
jackpot = 10 # 円儲かる板が買い板にできたら、取得済XYMを売る（0は無効、1以上で有効）
```
$ cd /vargrant
tikutikukunを実行
$ python3 tikutikukun_v1_13.py
Ctrl + C で停止します

とりあえず書きました。間違いがあったらごめんなさい。数日旅に出るので反応遅くなります。🙏

* 最新版v1.15が出ています。
    * https://twitter.com/noway_pway/status/1606603986706268161