OmniAICreator/Qiita-1.07M huggingface dataset:
wifi6 とは

## 勉強前イメージ

普通のwifiと何が違うの？

## 調査

### wifi6 とは

IEEE 802.11ax が正式規格名の最新wifi規格のことになります。
Wi-Fi Alliance という団体がwifi6にすると発表したことで呼ばれるようになりました。

wifiの正式名称である `IEEE 802.11` は企画によって最後のアルファベットが変わり、
以下のようになっております。
- IEEE 802.11n : Wi-Fi 4
- IEEE 802.11ac : Wi-Fi 5
- IEEE 802.11ax : Wi-Fi 6

### 従来のwifiとの違い

- 最大通信速度が9.6Gbpsに

wifi5では最大6.93Gbpsで、約1.5倍程度高速化されています。

- 2.4GHz帯の対応

wifi5では5GHz帯しか対応していなかったですが、wifi6では2.4GHz,5GHzどちらも対応しています。

- OFDMA という技術の対応

同一の通信路を混信することなく共用するための技術を採用しており、
混み合った環境でも高速通信を安定維持出来るようになっています。

### wifi6のメリット

- 高速

上記でも記載したとおり、従来より1.5倍程度高速化されています。

- 安定性が高い

同時接続する台数が多いオフィスや自宅でも
高速通信が可能になります。

- バッテリー消費を抑制

TWTという技術が搭載され、通信の必要がないときは
通信をスリープすることで消費電力を抑えることができます。

### wifi6のデメリット

- wifi6対応機器が少ない

まだwifi6が対応している機器が少ないことが挙げられます。
今後普及につれて増えていき、価格も抑えられると考えられます

## 勉強後イメージ

IEEE 802.11axのことか・・・
てかwifi4,5ってあったのね、忘れてた
どっかでやった気もする。

## 参考

- [初心者向け 次世代Wi-Fi規格“Wi-Fi 6”とは？ Happy Wi-Fi Life](https://www.elecom.co.jp/pickup/contents/00024/)
- [Wi-Fi6とは？ その特徴とWi-Fi5との違い、メリットなど](https://mvno.freebit.com/column/iot-m2m/wifi6.html)
GitLabRunner環境設定

### GitLabRunnerとは  
GitlabのCI/CDと連携してpiplineで処理を実行するアプリケーションです。  
環境を用意し、処理内容をGitlabのリポジトリ内に格納することで、用意した環境での処理実行結果をGitLabで確認することができます。
リポジトリに更新を入れるたびに自動でコンパイルを行うことなどもできます。  

## 環境  
* RunnerServer Ubuntu18.04  
* Gitlab-Runner 14.0.0  

### イメージ図

![runner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106643/6b7aa606-3f02-ac2e-e8fb-7247d1e8d0f5.png)

### 用意するもの

* 実行する環境のImage  

処理用のコンテナを立ち上げるために使用します。

* サーバ  

上記のイメージを使用してコンテナを立ち上げるために使用します。
サーバは無くてもGitLabが用意しているもので行うこともできますが、環境の問題や月ごとの使用制限等が問題になる場合は用意が必要です。  

* 処理を記載したymlファイル

立ち上げたコンテナ内で処理を走らせるために使用します。




## 設定方法  
### GitLabRunnerのインストール  
RunnerServerにGitLabRunnerをインストールします。

```
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
sudo apt-get install gitlab-runner
apt-cache madison gitlab-runner
sudo apt-get install gitlab-runner=14.0.0
```
### Runnerの登録  
処理を行うサーバとプロジェクトを結びつけます。  

```
sudo gitlab-runner register
```

入力画面になるため、環境に合わせて設定を入力していきます。
今回はDockerでImageを作成します。 

```
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
# プロジェクトURL

Please enter the gitlab-ci token for this runner:
# プロジェクトTOKEN

Please enter the gitlab-ci description for this runner:
# runnerの説明

Please enter the gitlab-ci tags for this runner (comma separated):
# tag

Registering runner... succeeded                     runner=2syNsUzh
Please enter the executor: docker, docker-ssh, virtualbox, docker-ssh+machine, kubernetes, custom, para$ lels, shell, ssh, docker+machine:
# executorType

Please enter the default Docker image (e.g. ruby:2.6):
# デフォルトで使用されるイメージ

Runner registered successfully. Feel free to start it, but if it's running already the config should be
```  

URLとTOKENはプロジェクトのSeettings>CI/CD>Runnsers settingsから確認することができます。  


![Runnsers_settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106643/f3752cfe-d578-d788-2bdf-d79c08390abf.png)  


![URLTOKEN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2106643/5df6e706-5913-2564-5d0c-8074ecc01ef2.png)

### Imageの登録  
今回はDockerでImageを作成します。
環境のDockerFileを作成し、ビルド、gitlabへのpushを行います。
登録についてはGitLabのプロジェクト、Packages & Registries > Container Registryにて確認できます。
push後、同ページでimageが確認できれば登録が完了しています。

```
docker build -t registry.gitlab.com/<group_ID>/<subgroup_ID>/<project_name>:tag> .
docker push registry.gitlab.com/<group_ID>/<subgroup_ID>/<project_name>:<tag>
```



## 参考資料  

[GitLab Docs GitLab Runner](https://docs.gitlab.com/runner/)
承認申請をすると、一番最初の承認プロセスが実効される問題について


#本記事の内容
承認プロセスを実行する際に発生した3つの主なエラーをまとめました。
それぞれパターンごとに分けています。

例：「テスト2」の承認プロセスを実行するユーザのはずなのに、「テスト1」が必ず実行されてしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694683/1be2b18a-7671-807c-4691-c2117fc04dec.png)

#エラーのパターンとその原因、回避策
##その1：対象の承認プロセスが実行されない
###エラー原因：対象の承認プロセスの条件を満たしていない。
このエラーは対象の承認プロセスを実行せずにスルーしてしまっている可能性があります。
開始条件を満たしている、申請ユーザが承認プロセスの申請者に含まれているかを確認しましょう。
##その2：対象のプロセスよりも順番の若いプロセスが実行されてしまう。
###エラー原因：対象の承認プロセスよりも順番の若い承認プロセスの開始条件が満たされてしまっている。申請ユーザが申請者に追加されてしまっている。
これは対象の承認プロセスよりも順番が若い承認プロセスが開始条件を満たしてるか、申請ユーザが申請者に割り当てられている可能性があります。
回避策としては下記があります。
・承認プロセスの順番を入れ替える。
・承認プロセスの開始条件で、実行されるべきでない承認プロセスが実行されないように設定する。
・承認プロセスの申請ユーザから対象のユーザを削除する。
##その3：開始条件は満たしていないし、申請者にも追加されていない。しかし一番順番が若い承認プロセスが実行される。
###エラー原因：申請ユーザのプロファイルで、承認申請するオブジェクトへのアクセス権の「すべて変更」にチェックが入っている。
その2で紹介された原因に当てはまらなかったらこれが原因の可能性があります。
Salesforceの仕様で、プロファイルのオブジェクト権限の「すべて変更」にチェックが入っていたらそのオブジェクトで承認申請を行ったら順番が一番若い承認プロセスが実行されます。(システム管理者等が割り当てられたユーザによくあるエラーです)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694683/26182b8f-fbc9-7abd-fc20-768c9f26fbf5.png)
回避策としては下記の3つがあります。
・対象の承認プロセスの順番を一番若く設定する。
・申請者のプロファイルで、オブジェクト権限の「すべて変更」のチェックを外す。(システム管理者等のオブジェクト権限を変更することは出来ない)
・新たにオブジェクト権限の「すべて変更」のチェックが外れたカスタムプロファイルを作成して、申請者ユーザに割り当てる。
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694683/2b1834c0-1b88-7d00-1415-be84a26f54a1.png)

上記3パターンでも解決できない場合は下記のSalesforce公式ヘルプを参照いただければと思います。
承認の制限および考慮事項：
https://help.salesforce.com/s/articleView?id=sf.approvals_considerations.htm&type=5
【Git】cherry-pickを使ってみた

#はじめに#
　ポートフォリオ作成中に、間違ったブランチからブランチを切っちゃった！っていうことがありました。
色々調べてみるとどうやらcherry-pickというコマンドを使うのがいいらしいということがわかったので実際に使ってみました。
　今回はその備忘録として残していきます。


#cherry-pick#
 cherry-pickコマンドを使うことで、ある特定のコミットのみを別のブランチに取り込みたい場合に使用します。この場合、mergeすると余計なコミットまで取り込んでしまうためcherry-pickを使用します。

```
git cherry-pick [取り込みたいコミットID]
```

このようにすることで、特定のコミットのみを取り込むことができます。
（ちなみに、コミットIDは「git log」などで調べることができます。）


#今回の使用例#
　今回は、個人でアプリ作成中にブランチを切る際、間違ったブランチから切ってしまい、コミットしてしまいました。
　修正手順は次の通りです。

①正しいブランチAからブランチA+を切り直す。
②誤って切ったブランチBのコミットIDを調べる。
③ブランチA+にcheckoutする。
④ブランチA+でcherry-pickする。
⑤ブランチBを削除する。


#まとめ#
　本来の使い方とはズレてるかもしれませんが、これでなんとか軌道修正することができました！
[GitHub Actions]プルリクで動かすCIをon: pushで動かしていたらエラーを取りこぼしてマージしてしまった話

GitHubを利用して開発する際、プルリクエストでCIを利用して様々なチェックを走らせることがあると思います。
私もGitHub Actionsを使ってプルリクにPushするたびに様々なチェックを走らせていたのですが、タイトルの通りエラーを取りこぼしてマージしてしまうことがありました。

# 状況再現

例えば下記の場合、fuga ciとhoge ciがコケているのでこのプルリクの修正で何か問題が発生したことを検知できます。

![スクリーンショット 2021-09-30 10.05.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83424/b0fbf869-2d5f-b8ca-42a3-3f5488395a00.png)


説明のためかなり簡素化していますが、上記のプルリクでは下記のコードとそれをテストするGitHub Actionsを定義しています。

```bash:hoge/main.sh
#!/bin/bash

exit 1
```

```bash:fuga/main.sh
#!/bin/bash

exit 1
```

```yaml:.github/workflows/hoge.yml
name: hoge ci

on:
  push:
    paths:
      - 'hoge/**'

jobs:
  hoge:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2.3.4
      - name: run hoge
        run: hoge/main.sh
```

```yaml:.github/workflows/fuga.yml
name: fuga ci

on:
  push:
    paths:
      - 'fuga/**'

jobs:
  fuga:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2.3.4
      - name: run fuga
        run: fuga/main.sh
```

hoge ciはチェック内容が`hoge/**`のファイルに依存しているので、hoge配下のファイルが変更された時だけ実行します。
fuga ciも同様の理由でfuga配下のファイルが変更された時だけ実行します。

今回、hogeもfugaも不具合が埋め込まれたことを表現するためにexit 1としています。そのためCIがエラーになっています。

不具合(exit 1)を修正します。
今回はexit 0に直すだけなので両方一気に直せば良いですが、通常開発の場合、まずはhgoeだけ直すなど1つずつ修正していくことが多いと思います。
今回は最初にhogeだけ直してみます。
hoge/main.shが正常終了するように下記のように`exit 0`に修正してpushします。

```bash:hoge/main.sh
#!/bin/bash

exit 0
```

pushした後、プルリクを確認してみると下記のようになりました。
**「All checks have passed」**
hoge/main.shしか修正しておらず、fuga/main.shの不具合は残ったままにもかかわらずCIが通ってしまいました。

![allcheckshavepassed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83424/3da40d1c-75c9-74a7-77a0-b2ff2f7d1a40.png)

よく見ると、「All checks have passed」の下のchecksにfuga ciが含まれていません。
プルリクのマージボタンの箇所に表示されるChecksの判定は最後に動作したChecksの結果が反映されます。
最後のPushではhoge/main.shしか修正していないため、hoge ciしか動作せず、動作したテストは全て正常終了したためCIがパスしたようです。

fuga/main.shに不具合が残ったままですが、このプルリクを見るとCIはパスしているように見えるのでマージしてしまいそうですよね。
冒頭で記載したエラーを取りこぼしたのはこの状況です。エラーがあることに気づかずマージしてしまい、mainブランチに不具合が混入してしまいました。

では、どのようにすればこの状況を避けられるのでしょうか？

# 解決策

タイトルに「on: pushで動かしていたらエラーを取りこぼした話」と書いた通り、`on: push`の挙動に問題があります。

`on: push`を使うと、Pushに含まれるコードをもとに該当するCIが実行されます。
先程の2回目のPushはhoge/main.shのみしか含まれていなかったため、hoge ciのみ実行されました。
この挙動によりfuga ciが実行されずに不具合を見逃してしまいました。

これを避けるためには`on: pull_request`を使用すればよいです。

Github Actionsのonをpull_requestに変更して同様の作業を行います。

```diff:.github/workflows/hoge.yml
name: hoge ci

on:
-  push:
+  pull_request:
    paths:
      - 'hoge/**'
```

```diff:.github/workflows/fuga.yml
name: fuga ci

on:
-  push:
+  pull_request:
    paths:
      - 'fuga/**'
```

実行結果は下記の通り。
![スクリーンショット 2021-09-30 10.52.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83424/c04ab963-eb22-2e18-253f-293ac2686fc3.png)

先ほどと異なり、hogeだけ修正したPushでもfuga ciも動作しています。
`on: pull_request`はpushと異なりpull_requestに含まれるコードをもとに該当するCIが実行されます。
そのため、最後のPushにfuga/main.shが含まれていなくても、プルリク全体で見ると含まれているためfuga ciも実行されます。

これであればhoge ciがコケていることが一目瞭然なので誤ってマージしてしまうこともありません。

# まとめ

上記の挙動より、プルリクエストのCIとして使う場合は`on: pull_request`を使った方が良さそうです。
過去に私が書いた記事はon: pushになっているものが多いので修正しないとな・・・
FlutterのTextFormFieldのhintTextのStyleを整える

#結論
```dart
hintStyle: TextStyle(color: Colors.black.withOpacity(0.6)),
```

##例
```dart:example.dart
Widget TextFormField(
  style: TextStyle(
    color: Colors.black,
    fontSize: 20,
  ),
  decoration: InputDecoration(
    icon: Icon(
    icon,
    color: Colors.black,
   ),
   hintText: hintText,
   hintStyle: TextStyle(color: Colors.black.withOpacity(0.6)),
   border: InputBorder.none
  ),
)
```
Java 11 to 17

# 概要

JavaのLTSバージョンの「17」がリリースされていたので、Java 11から新しく使えるようになった機能をメインにまとめます！

> こんな機能あるよ！の紹介にとどめ、詳細は追いません。
「触ってみよう」「調べてみよう」のきっかけになればと！

# Switch Expressions

http://openjdk.java.net/jeps/361

switch文を式の中で使用できるようになりました！

```java
jshell> var a = 1
a ==> 1

jshell> var b = switch (a) {
   ...>     case 1 -> "one";
   ...>     case 2, 3 -> "two or three";
   ...>     default -> "other";
   ...> }
b ==> "one"

jshell>
```

ポイント

- `->`と記載することで`break`を書かなくてよくなる
    - break実装漏れによるバグが減る！
- `,`でつなげることで複数項目ぬも対応

# String.transform

```java
jshell> String suffixA(String target) {
   ...>     return target + "A";
   ...> }
|  created method suffixA(String)

jshell> String suffixB(String target) {
   ...>     return target + "B";
   ...> }
|  created method suffixB(String)

jshell> var target = "target";
target ==> "target"

jshell> // transformを使うと

jshell> target.transform(str -> suffixA(str)).transform(str -> suffixB(str));
$9 ==> "targetAB"

jshell> // transformを使わないと

jshell> suffixB(suffixA(target))
$10 ==> "targetAB"

jshell>
```

上記は「末尾にAを付与し」さらに「末尾にBを付与する」実装です。
transformを使用することで、処理の順序と記述の順序が揃えられています！

> 関数インタフェースに慣れていないとキツそう😇

# Text Blocks

https://openjdk.java.net/jeps/378

`"""`で囲うことで複数行にわたって文字列を定義することができるようになりました✨

```java
jshell> var sample = """
   ...> sample
   ...> text
   ...> brock"""
sample ==> "sample\ntext\nbrock"

jshell>
```

# String.formatted

Stringにformattedメソッドが追加され、以下のように文字列の埋め込みができるようになりました！

```java
jshell> "str: %s".formatted("sample")
$3 ==> "str: sample"

jshell>
```

# Helpful NullPointerExceptions

https://openjdk.java.net/jeps/358

`-XX:+ShowCodeDetailsInExceptionMessages`オプションをつけることで、
NullPointerExceptionsのメッセージがこれまでよりも詳細に取得できるようです！

# Pattern Matching for instanceof

https://openjdk.java.net/jeps/394

`instanceof`によるインスタンスのクラスの判定と、キャスト（例：`var str = (String)obj`）が同時にできるようになりました！

```java
jshell> var obj = (Object)"sample";
obj ==> "sample"

jshell> if (obj instanceof String str) { // var str = (String) obj
   ...>     System.out.println("obj is string : " + str);
   ...> }
obj is string : sample

jshell>
```

# Records

https://openjdk.java.net/jeps/395

lombokでいう`@Value`を付与したオブジェクトに近い印象です。
以下は、fieldに `id`と`name`を持つクラスをrecordを使って生成する例です

```java
jshell> record Sample(int id, String name) {}
|  created record Sample
```

インスタンス化と、fieldの参照はこんな感じ

```java
jshell> var sample = new Sample(1, "rhirabay")
sample ==> Sample[id=1, name=rhirabay]

jshell> sample.id()
$6 ==> 1

jshell> sample.name()
$7 ==> "rhirabay"

jshell>
```

# Sealed Classes

https://openjdk.java.net/jeps/395

「継承はさせたいけど、継承させるクラスはしぼりたい」ができるようになります！

例えば、以下のように記述すると`Base`クラスを拡張できるのは`Extended1`と`Extended2`クラスだけという制約をつけられます

```
public abstract sealed class Base permits Extended1, Extended2 {}
```

# おまけ（Preview機能）

## Pattern Matching for switch

switchでインスタンスによる分岐ができるようになります！
ifと同じくキャストまでいっぺんに書けます

```java
jshell> switch (obj) {
   ...>     case Integer i -> "%d is integer".formatted(i);
   ...>     case String s -> "%s is string".formatted(s);
   ...>     default -> "other";
   ...> }
```
PHPでCookieにSameSite属性を付ける方法

# PHP7.2以前の`setcookie`関数には`SameSite`属性をつけるための引数がない！

`header`関数で生の`Set-Cookie`ヘッダを書くのも手ですが・・・

裏技として、Path属性用の引数を利用して`SameSite`属性をつけることができます。

```php:7.2以前の方法（裏技）
/* 関数のインターフェース
setcookie(
    string $name,
    string $value = "",
    int $expires = 0,
    string $path = "",
    string $domain = "",
    bool $secure = false,
    bool $httponly = false
): bool
*/

# pathにわたす文字列内に`;`をいれることで、無理やりSameSite属性を指定する！！！
setcookie('cookie_name', 'cookie_value', 0, '/; SameSite=strict', '', true, true);

# 出力されるレスポンスヘッダ
# Set-Cookie: cookie_name=cookie_value; path=/; SameSite=strict; secure; HttpOnly
```

```php:7.3以降の方法（正規）
# PHP 7.3.0 以降で使える代替のシグネチャ:
# setcookie(string $name, string $value = "", array $options = []): bool

setcookie('cookie_name', 'cookie_value', [
  'expires' => 0,
  'path' => '/',
  'samesite' => 'strict',
  'secure' => true,
  'httponly' => true,
]);

# 出力されるレスポンスヘッダ
# Set-Cookie: cookie_name=cookie_value; path=/; secure; HttpOnly; SameSite=strict
```


逆に7.3以降でPath属性を使って`SameSite`をねじ込もうとすると以下のエラーになるので注意！！！

```php
Uncaught ValueError: setcookie(): "path" option cannot contain ",", ";", " ", "\t", "\r", "\n", "\013", or "\014"
```
userのカラムがありませんを解決~

自分用メモです！！
## 起きたこと
deviceで用意されたサインアップ機能を使用しサインアップを実行した際に
以下のエラー発生

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/880777/2281cfa3-5cc4-ad40-7993-430d1c8f45d1.png)

## 行ったこと
schema.rbのカラムを見てまずusernameがあるか確認する。

なかったので、

```
 rails g  migration add_name_to_users
```
を実行。この際ファイル名はなんでも問題はないが、
・テーブル名
・カラム名
を含ませるとなおよし

次にカラムを追加する

## カラムを複数追加する場合の書き方

```
add_column :テーブル名, :カラム名, :データ型
```
を追加したいカラム分行う

次に

```
rails db:migrate
```
を行うだけ

##　参考にした記事
https://freesworder.net/rails-column-add-remove/
ポケモンの対戦シュミレータを作ってる話

# はじめに
こんにちは、4月から都内のSES企業で働いてる佐々木と申します。
先月ぐらいから勉強がてら毎日少しずつ作ってるポケモン対戦シミュレータが少しぐらい形になってきたので今日はそちらを紹介していきたいと思います。

# 概要
https://github.com/sasakirione/PokemonClone
・仕事ではそこまでコーディングする機会がないので[^1]実際にガッツリコーディングする経験を積みたい
・TDDをやってみたい
・単純にポケモンが好き
・オブジェクト指向的な設計の勉強をはじめて試してみたくなった
・とりあえず研修で勉強してある程度基礎ができてるであろうJavaをある程度のレベルまで持っていきたい

以上の理由からJavaとなんちゃってTDDでポケモンの対戦シミュレータを作ってみました。

# 使い方
もちろんGUIアプリケーションではないのでわざわざ使う人も少ないと思いますが一応簡単な使い方を解説していきたいと思います。テストコード見て貰えばなんとなく分かると思いますが、一応まとめておきます。
まず使用するポケモンのオブジェクトを作ります。

```Java
Pokemon pokemon = pokemonDataGet.getObjectByID(788, 0, new int[]{252, 0, 0, 252, 0, 0}, 1, "たべのこし", "ひかえめ");
```

pokemonDataGet.getObjectByIDはstaticメソッドなのでそのまま呼び出してください。引数は左から図鑑番号、フォーム番号、努力値、特性、道具、性格です。
次に試合のフィールドのオブジェクトを作ります。

```Java
PokemonStadium stadium = new PokemonStadium(pokemon1, pokemon2);
```

あとは実際に技を打つだけです。
次のように技名をいれます。

```Java
stadium.forwardTurn("めいそう", "ハイドロポンプ");
```

前者がpokemon1の、後者がpokemon2の繰り出す技です、実際の順序はきちんとSで決まります。
ただこれでは試合がどうなってるのかが分かりません。なので試合のログを表示する機能も作っています。

```Java
BattleLog.getLogAll();
```

ちなみに次のような感じでログが表示されます。

```
Aは ウーラオス(れんげきのかた) を繰り出した！
Bは ミミッキュ を繰り出した！
ウーラオス(れんげきのかた) の すいりゅうれんだ のこうげきだ！
ミミッキュの ばけのかわ
ばけのかわが みがわりに なった！
ミミッキュの ばけのかわが はがれた！
114/130 緑
急所に 当たった！
45/130 黄色
急所に 当たった！
0/130 赤色
3回 当たった！
ミミッキュ はたおれた
```

以上が大体の使い方です。

# 現状
## できること
 - 攻撃を打てます(技データベースは5世代まで+αから剣盾非対応技を除いた分だけあります)
 - ポケモンの交代ができます
 - 一部連続技が出せます
 - 命中率があります
 - 急所に当たります
 - 確定急所の技が確定で急所になります
 - げきりんなどの数ターン暴れ回る系の技が使えます
 - 一部変化技が出せます(ただここで紹介した使い方では使えませんすいません)
 - 性格の考慮
 - 一部特性や道具が使えます(詳しくは定数クラスをご覧ください)
 - まひします(ただSが下がるだけです)

## できるようにしたいこと
 - ここで紹介した方法で変化技をだす
 - 第6世代以降の技も追加する
 - 技の追加効果の実装
 - 残りの特性や道具の実装
 - まひ以外の状態異常の実装
 - トレーナーの概念を追加(3体瀕死になったら試合終了する)
 
etc...

# 思った事
## やっぱりプログラミングは実践あるのみ
オブジェクト指向をちゃんと勉強しはじめてから初めてガッツリ書くコードだったんですが、やっぱり頭では分かってても身体では分かってない事が多すぎるなって感じる毎日です。あるとき突然、あそこで言ってたのはこういうことだったのか！みたいな発見が実際に知ってからある程度経った時に急にくることが何度もありました。そのたびに「ちょっと前の俺、こんなコード書いててアホちゃうか？」みたいな事を毎日思っています。まあ書いた直後に思う事もよくあるんですけどね。

## テストがないとこわい
なんちゃってTDDをやってて思ったのがテストがないと怖いということです。もちろんテストの粒度とかガバガバでしょうしあんまりキャッチ力がないかもしれませんが、それでもやっぱりテストがあるのは安心感があります。というかテストを書く事によりちょっとリファクタリングしただけですぐ凡ミスで赤くなるのを体験するとどうしてもテストは絶対に必要だなって感じるようになってきました。そして同じような話ですがテストがあると安心してリファクタリングができるのでリファクタリングが楽しい！

## 最後に
なんとなくポケモンが好きだからポケモンの対戦シュミレータを作り始めましたが、いま思うと勉強にはかなりいい題材だったかなと思います。ぼくはどうしても飽き性なのでそろそろ飽きてきたので新しいプログラムを作ろうかなって思ってるのですが、これからも少しずつこっちも更新を続けていきたいと思います。第9世代出るまでにある程度完成するといいなぁ･･･


[^1]: 一応設計工程から入らせてもらってますがレガシーすぎてずっとExcelを弄っています。
LaTeXのTips


# 1. ページの余白を設定する

使用する用紙サイズとフォントのポイントを決めたら、
文書内に\layoutを記述して、レイアウトを調整する。

```latex
\documentclass[a4paper,11pt,dvipdfmx]{jsarticle}

\setlength{\topmargin}{-33pt}
\setlength{\oddsidemargin}{-6.4truemm}
\setlength{\textwidth}{172truemm}
\setlength{\textheight}{246truemm}

\usepackage{layout}

\begin{document}

\layout

\end{document}
```

# 2. 段落の見出しを括弧つきの数字にする

段落の見出しが黒四角だけだと物足りないので、括弧付きの数字に変更する。
プリアンブルに以下を指定する。

```latex
\makeatletter
\renewcommand{\paragraph}{\@startsection{paragraph}{4}{\z@}%
  {1.0\Cvs \@plus.5\Cdp \@minus.2\Cdp}%
  {.1\Cvs \@plus.3\Cdp}%
  {\reset@font\sffamily\normalsize}
}
\renewcommand{\theparagraph}{%
   (\@arabic\c@paragraph)}
\makeatother
\setcounter{secnumdepth}{4}
```

変更前の出力イメージ

|![latex_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192430/b1aa12ac-82b3-c159-6d35-d6289380dc82.png)|
|:--|

変更後の出力イメージ

|![latex.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192430/9aafd69b-d5d4-827a-535b-e229b678e035.png)|
|:--|


# 3. 日本語を含むソースコードを表示する

https://ctan.org/pkg/listings

listingsのみだと英語と日本語の表示順序が入れ替わったりする。
以下のサイトから、jlistingをダウンロードする。

https://ja.osdn.net/projects/mytexpert/releases/p6275

jlisting.styを適切なフォルダーに入れて、mktexlsrコマンドを実行する。
(C:\texlive\2018\texmf-dist\tex\latex\listings など)
デフォルトのままだとフォントが横に間延びした感じに見えるので、basewidthを指定。
左側の余白を設定して、全体を枠で囲む。

```latex
\usepackage{listings, jlisting}
\lstset{
  basicstyle=\footnotesize\ttfamily,%
  basewidth=0.5em,%
  xleftmargin=1em,%
  frame=single
}
```

# 4. 画像の埋め込み

あらかじめextractbbコマンドを使用してxbbファイルを作成しておくと、
ドキュメントの生成時間が短縮される。

```
extractbb *.png
```

# 5. 参考文献を目次に追加する

addcontentslineを指定する。定番。

```latex
\addcontentsline{toc}{section}{\bibname}
\begin{thebibliography}{99}
\bibitem{qiita} プログラマの技術情報共有サービス\url{https://qiita.com/}
\end{thebibliography}
```

通常の節と同じように節番号を付けたい場合は、
sectionを追加、元々の見出しを空文字列にして、余分な空行を削除する。

```latex
\section{参考文献}

\renewcommand{\refname}{}
\vspace{-3em}
\begin{thebibliography}{99}
\bibitem{qiita} プログラマの技術情報共有サービス\url{https://qiita.com/}
\end{thebibliography}
```

# 6. 生成されるPDFの設定

https://ctan.org/pkg/hyperref

ハイパーリンクの色と枠を削除する。
PDFの初期表示を幅に合わせて表示する。
ページサムネイルやしおりは表示しない。

```latex
\usepackage[dvipdfmx]{hyperref}
\usepackage{pxjahyper}
\hypersetup{%
  hidelinks=true,%
  pdfstartview=FitH,%
  pdfpagemode=UseNone
}
```

# 7. 埋め込むフォントを変更する

https://tm23forest.com/contents/veryeasy-latex-meiryo-font

プリアンブルに以下を指定する。

```latex
\special{pdf:mapline rml H meiryo.ttc}
\special{pdf:mapline gbm H meiryo.ttc}
```

これはアドホックな方法。正式には以下のコマンドを使用する。

```
kanji-config-updmap-sys.exe -ja status
```
PythonのModuleNotFoundErrorにがっつりハマった話しと解決した方法

## 結果
結論的には実行対象のpythonのフォルダ名称とpythonファイル自体の名称がライブラリ名称とかぶっていたためそれらを読み込みにいってエラーが発生していた。

```:教訓
ライブラリ名と同じフォルダ名やファイル名を使ってはいけない
```

## 事象
普段Pythonそんなに触らないマンが久々にPythonでスクリプト書きたくなったのでPoetryを使って開発を始めた。
とあるライブラリを試してみることが目的だったため、適当にフォルダ名と実行対象のファイル名を対象のライブラリの名称に命名した。

その後サンプルのコード持ってきてライブラリインポートして実行したが `ModuleNotFoundError` で実行自体ができなかった。


## 調査

ライブラリをどこを参照しにいっているかは以下のコマンドをファイル冒頭に書き足すことで確認が可能

```python:ライブラリ読み込み先確認
import sys
import pprint

pprint.pprint(sys.path)
```

この文言を追記した上で実行すると以下のような配列が出力される。
（一部ユーザー名称など変換してます）

```
['/Users/username/.ghq/github.com/reponame/sandbox/python/abi/pyserum',
 '/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python39.zip',
 '/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9',
 '/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload',
 '/Users/username/.ghq/github.com/reponame/sandbox/python/abi/pyserum/.venv/lib/python3.9/site-packages']
```

どうやらこれらが上から読み込まれていく仕様となっている様子。

実際に使おうとしたライブラリは `pyserum` という名称だった。

実際にimportしたファイルが入っていたのは一番最後のパスが正解

```
/Users/username/.ghq/github.com/reponame/sandbox/python/abi/pyserum/.venv/lib/python3.9/site-packages
```

しかし実行ファイルを配置していたフォルダ名自体も `pyserum` （上記配列の先頭）にしていたため、フォルダの中が散策されそこに実際のファイルが存在しなかったため、そのタイミングでエラーが返されるようになっていた。



## 参考にした記事
https://note.nkmk.me/python-import-module-search-path/
Chrome拡張機能のChrome APIで内部通信でハマってしまったので備忘残す

## 概要
Chrome拡張機能で開発するcontent.js、popup.js、background.js間の通信方法の初歩的なところにガッツリハマってしまったので備忘として残す。

## イベントの定義
イベントの定義自体はcontent.jsもbackground.jsも同じ

```javascript
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
  switch(request.name) {
    case "hello":
      sendResponse({ text: "say hello" });
      break;
    case "bye":
      sendResponse({ text: "say bye" });
      break;
    default:
      break;
  }
});
```

## イベント呼び出し方
イベントの呼び出し方が対象に応じて異なる。

### content.js
content.jsはタブ毎に読み込まれているためどのタブのイベントをキックするかを指定する必要がある。

具体的には以下のようにイベントをキックする必要がある。

```javascript
$("#btn").on("click", () => {
  chrome.tabs.query({active:true, currentWindow:true}, function(tabs){
    chrome.tabs.sendMessage(tabs[0].id, { name: "hello" }, function (response) {
      window.alert(response.text); 
    });
  })
});
```


### background.js
background.jsはブラウザで読み込まれているため、タブの指定が不要。
具体的には以下のようにイベントをキックする。

```javascript
$("#btn").on("click", () => {
  chrome.runtime.sendMessage({ name: "hello" }, function (response) {
    window.alert(response.text);
  });
});
```
GeneXusのGeneXusServerの認証情報を変更したい

# 初めに
GeneXusではソースの管理にGeneXusServerというものを使用しなければなりません。(gitのようなもの)
一度別の認証情報を入れていたが、後々になって変えなければならなくなったときに
どうやったらいいか結構悩んだのでその方法を記載します。

GeneXusとはなんぞやという方は[こちら](https://www.genexus.jp/genexus-v16-jp?gclid=Cj0KCQjwwNWKBhDAARIsAJ8HkheJNK0yFsOCXpeH03Q_YgHn0-3QtlC3wWGJBxskvXMUHD2fmL-N3D0aAiktEALw_wcB)

# 環境
* Windows10
* GeneXus16 -v16.0.19488 U8

# 解決策

1. `ファイル > 新規 > GeneXus Serverからのナレッジべース`をクリック
![gene1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649992/60cfd396-6065-38ba-1db0-d0e06a1b443a.png)

1. `サーバーKBを選択`ボタンをクリック
1. 認証情報を変更したいサーバー名で**`右クリック`**し編集を選択すると
GeneXusServerの認証情報入力画面が開きます。

![gene2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649992/faa4730d-2dbf-6279-d4cd-53310b2a9038.png)


# 終わりに
今回はGeneXusServerの認証情報変更について記載しました。
アプリケーションの作成方法、エラー解決策なども記事にしていきたいと思います。
Ruby Gem Install で Installing required msys2 packagesに失敗するときは

備忘録です。

```
$ gem install rabbit
Installing required msys2 packages: mingw-w64-x86_64-gr
```

Windowsでgem installすると、こんな感じで msys2 関連パッケージをインストールしようとして、うまくいかずに色んなミラーサイトを探し回り、たらいまわしを受けることがあります（エラーメッセージを採取し忘れました）。
最近頻発してたんで、「WindowsとRubyってそんなに相性悪いの？」としょぼんとしていたところ、解決策らしきものが見つかったので置いておきます。

##原因はもしかして
pacmanという「パッケージマネージャ」の情報が古い

##御託は後。まずは解決策
- エクスプローラーでRubyをインストールしたフォルダへ
	- だいたいC直下のはず。Ruby30-x64とかの名前になってる
- さらに、フォルダ msys64 に入る
	- msys32とかの場合もあるかも
- msys2.exeを起動

- 以下のコマンドを打ってパッケージマネージャの情報を更新

```
pacman -Syu
```

- 実行中、Y/n選択形式で色々聞かれるので、全部 Y [Enterキー]を入力
	- すべてのパッケージを更新できずに途中でエラーになるかもしれないが、それでもgem installには支障なかったりするので、めげずに次に進む
- 同じフォルダにmingw32.exeやmingw64.exeというものも見当たるので、それらについても起動し、pacman -Syu を実行する
- 終了したら、通常のコマンドプロンプトに戻ってgem installし直してみる

私の場合はこれでインストールがはかどるようになりました。

##あとはおまけ：msys2 とpacmanについてざっくり
今までよく分からず避けていたので自分なりにまとめ。
###msys2 = WindowsでUnixシェルを実行できるターミナル
Windowsだと動かないコマンドが沢山あるので、それを使えるようにするもの。
###pacman = Unixで動くパッケージ管理ソフト
プログラムに必要なライブラリを保持し、何が既にインストールされているか、更新版はあるかといった情報を管理している。

Windows版Rubyでgemコマンドを実行すると、必要に応じてpacmanがmsys2経由で参照され、パッケージがインストールされる。
しかし、pacmanが保持しているパッケージ更新情報が古いと適切なファイルを取得できない。
そうしたときに、pacman -Syuで情報を更新してあげることで、インストールがスムーズに進むようになる、ということのようです。
エミュレータ起動時に「The emulator process for AVD Pixel_2_API_28 has terminated.」と表示される

# 事象
エミュレータを作成、実行しようとした際、「The emulator peocess for AVD Pixel_2_API_28 has **terminated** .」と表示された。

調べたら`~ has killed`の対処法は出てきたが`~ has terminated`の対処法は出てこなかったのでメモ。

# 結論
ディスク容量不足

# 確認手順
1. `C:\Users\ユーザ名\AppData\Local\Google\AndroidStudio2020.3\log\idea.log`を適当なエディタで開く
2. 「terminated」等で検索をかけると以下のようなログが出てくる

```
2021-09-30 19:38:24,878 [ 503186]   INFO - manager.EmulatorProcessHandler - Emulator: C:\Users\me\AppData\Local\Android\Sdk\emulator\emulator.exe -netdelay none -netspeed full -avd Pixel_2_API_28 
2021-09-30 19:38:26,380 [ 504688]   INFO - manager.EmulatorProcessHandler - Emulator: emulator: ERROR: Not enough space to create userdata partition. Available: 6655.781250 MB at C:\Users\me\.android\avd\Pixel_2_API_28_1.avd, need 7372.800000 MB. 
2021-09-30 19:38:26,380 [ 504688]   INFO - manager.EmulatorProcessHandler - Emulator:  
2021-09-30 19:38:26,386 [ 504694]   INFO - manager.EmulatorProcessHandler - Emulator: emulator: Android emulator version 30.8.4.0 (build_id 7600983) (CL:N/A) 
2021-09-30 19:38:26,386 [ 504694]   INFO - manager.EmulatorProcessHandler - Emulator: Process finished with exit code 1 
2021-09-30 19:38:26,386 [ 504694]   WARN - manager.EmulatorProcessHandler - Emulator terminated with exit code 1 
```

→ `WARN`行の少し上にERROR内容が記載されている

```
2021-09-30 19:38:26,380 [ 504688]   INFO - manager.EmulatorProcessHandler - Emulator: emulator: ERROR: Not enough space to create userdata partition. Available: 6655.781250 MB at C:\Users\me\.android\avd\Pixel_2_API_28_1.avd, need 7372.800000 MB. 
```
JupyterLab Desktopをインストールしメニューを日本語化してみた

　JupyterLab Desktopがリリースされていたので、Windows10にインストールしてみた。
　メニューは英語だがだいたい分かるので困ることはないが、JupyterLabのlanguage-packを使って日本語化してみた。

```python
pip install jupyterlab-language-pack-ja-JP
```
（訂正）
　パケージのインストールに`pip`と`conda`を混在させないほうが良いので、`conda`でインストールしよう。
```python
conda install -c conda-forge jupyterlab-language-pack-ja-JP
```
次のようなメッセージがでたので、JupyterLab Desktop を再起動した。

```python
Collecting jupyterlab-language-pack-ja-JP
  Downloading jupyterlab_language_pack_ja_JP-3.1.post1-py2.py3-none-any.whl (43 kB)
Installing collected packages: jupyterlab-language-pack-ja-JP
Successfully installed jupyterlab-language-pack-ja-JP-3.1.post1
Note: you may need to restart the kernel to use updated packages.
```
　Languageで日本語を選択すると再起動し、そのときにJupyterLab Server が404エラーを表示したが、日本語化されていた。
　これからいろいろ試して不具合がないか調べてみたい。

参考URL
https://github.com/jupyterlab/language-packs/tree/master/language-packs/jupyterlab-language-pack-ja-JP
FluentdでEC2からS3へログを転送

## これは何

FluentdでEC2からS3へログを転送したので、設定ファイルの書き方など書き残しました。

```
要件
Amazon Linux 2
td-agent4
old stableだし、3でもよかったけど、なんとなく4を選択
```

他にこの件で書かれている方がすでにいらっしゃって、参考にさせていただきました。
自分はハマったポイントが何点かあったので、そちらも含めてまとめます。

```
・S3 credentials
・configファイル設定で、もともとあるmatch directiveを削除しなければならなかった。
```

## やってみた

**S3 credentials用意**

```
/// S3 credentials用意
IAMロール設定。EC2へアタッチ。
という方法だと、credentialsのエラーが出て進まなかったので、AmazonS3FullAccessを与えたIAMユーザーのAccess key,Secret keyを利用。
```

**httpd install**

```
yum install httpd
systemctl start httpd
```

**Fluentd install**

```
/// Fluentd install
$ curl -L https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent4.sh | sh

Installed:
  td-agent.x86_64 0:4.2.0-1.amzn2

Complete!

Installation completed. Happy Logging!
↑どうでもいいですが、このノリ好きです
```

**一応バックアップ**

```
/// 一応バックアップ(後々ハマったので、しておいてよかったです)

cd /etc/td-agent/
cp td-agent.conf td-agent.conf.org
```

**関連プラグインのインストール**

```
///関連プラグインのインストール

/usr/sbin/td-agent-gem install fluent-plugin-s3
/usr/sbin/td-agent-gem install fluent-plugin-forest
/usr/sbin/td-agent-gem install fluent-plugin-ec2-metadata
```

**権限変更**

```
/// 権限変更
cd /var/log/
chmod 750 httpd/
chown  root.td-agent  httpd/
ls -ld httpd/

chmod  640 messages
chown  root.td-agent  messages
ls -ld messages
```

**設定ファイルの編集**

```
/// 設定ファイルの編集
vi /etc/td-agent/td-agent.conf

/match
で、該当の行を消去

最下行に以下追記
<source>
  @type tail
  path /var/log/messages
  tag td.messages.access
  pos_file /var/log/td-agent/messages.pos
  format syslog
</source>

<match td.messages.access>
  @type s3
  aws_key_id 
  aws_sec_key 
  s3_bucket バケットの名前
  s3_region ap-northeast-1（利用リージョンに合わせて、任意）
  time_slice_format %Y%m%d%H%M
</match>
  <buffer>
    @type file
    path /var/log/td-agent/s3
    timekey 3600  # 1 hour
    timekey_wait 10m
    chunk_limit_size 256m
  </buffer>
```

**実行ユーザーをrootにする**

```
/// 実行ユーザーをrootにする

vi /usr/lib/systemd/system/td-agent.service

[Service]
User=td-agent
Group=td-agent

↓変更

[Service]
User=root
Group=root
```

**restart**

```
/// 再起動

sudo systemctl restart td-agent.service
```

**test**

```
/// test

logger test

or

ab -n 100 -c 10 http://localhost/
```

**転送成功**


![スクリーンショット 2021-09-30 19.05.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740345/e0aed6d6-96a1-151b-4a45-fce40457d18b.png)




## 参考

```
https://github.com/fluent/fluent-plugin-s3/issues/362
https://stackoverflow.com/questions/67365930/failed-to-flush-the-buffer-fluentd
https://teratail.com/questions/288682
https://docs.fluentd.org/how-to-guides/apache-to-s3
https://techgekka.hateblo.jp/entry/2016/11/08/195406
https://www.tweeeety.blog/entry/20131211/1386728410
https://dev.classmethod.jp/articles/fluentd-s3/
https://stackoverflow.com/questions/33182868/fluentd-s3-output-plugin-configuration
https://qiita.com/xishan/items/81736cb504b7b1ddf59a
https://qiita.com/y-araki-qiita/items/de6638ec7d32d09017c5
https://qiita.com/katuemon/items/7105c24271c07ce7b412
https://qiita.com/VTRyo/items/a4695aeec4fec8220fbb
```

参考にさせていただきました。ありがとうございます。
10年後のために今勉強しておきたい技術

最終日滑り込みで記事を書いています。

https://qiita.com/official-events/12fc7bacec894d33a981

10年後のために今勉強しておきたい技術ということで、個人的に思うところを書いていきたいと思います。

#はじめに
技術=スキルと認識しています。
スキルについてはQiitaなので言語やらがほとんどだと思っています。
個人的にはPythonとかおすすめなんですが、あえてここでは違う視点で考えました。


#そもそも開発言語とは
開発言語とは、人とコンピュータが会話するために必要な言語だと認識しています。
人と人との間でも英語やフランス語など、色んな言語が存在しています。
たくさんの開発言語を覚えていれば色んな所から重宝されます。
なので覚えておいて損はないです。

しかし、「そんなに覚えれないよ。」とか「開発言語が廃れてしまったら意味がなくなる」とかの意見も多々あります。
その通りです。

突き詰めた結果　<strong>開発言語は１つだけ極めればよい。</strong>　でした。

#僕の考え方
開発言語は書き方が違うかもしれませんが、
基本的として
・順次
・条件
・繰り返し
の３パターンです。
なので、１つ理解していれば解読もできるし、調べれば書くこともできます。
自分より<font color="#f00">優秀な人は山ほどいる</font>し、<font color="#f00">ネットで調べれば情報</font>はたくさん出てきます。

なので、10年後の為にもっと勉強しておきたい技術は３つです。

.....

###吸収する技術
いわゆるインプットです。
第100代総理大臣が得意とする「聞く力」もインプットです。
人のソースコードを「読む力」や、相手の顔色を「見る力」もインプットのスキルです。

コミュニケーションスキルの大半もこのインプットだと思っています。
![22125374.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/744261/315e3fb9-f863-9db6-bfce-1aad2f03f29c.png)


###解釈する技術
インプットした情報を自分なりに解釈するスキルです。
このスキルは経験の多さで変わってきます。
聞いたことが自分でも経験したことのない場合、今までで経験したことに置き換えて解釈するため、
経験が多ければ多いほど解釈できるようになります。
![2643006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/744261/f709fa9f-5ac7-4340-5e92-a69f517c838d.png)

###説明する技術
最後に、一番重要ないわゆるアウトプットスキルです。
聞いて、理解することはできても、相手にうまく伝えることができなければ、結局解決に至らなかったり、
「思ってたのとちがーう」と開発者あるあるな状況に陥ります。

いつも思っているのは、色んな人と会話してて、
「なんでこいつわかってくれないんだ！」
って思ったとき、<string>自分の伝え方が悪いから</string>と思うようにしています。
そうすれば、相手に苛立ちも覚えないので、その先もスムーズに仕事ができます。

どちらが悪いって？　「ハーフ・ハーフ」　ですね。

そしてこの説明するスキルができてない人がほとんどです。
かくいう僕もこの記事を書いていて、説明力なさすぎって感じます。
![22196164.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/744261/30ef86dd-3750-c52f-e598-83d7c39a3e70.png)

#最後に
仕事をするために、人と人とのつながりを大事にしています。
そして、与えられた作業を相手の思い以上の結果を出せば信頼につながります。
その信頼から信用され、他の人を紹介され、また仕事をもらえます。

今後、ノーコードやローコードなどがどんどん増えてきてシステム開発をする機会が減ってくると思います。
なので、<font color="#f0f">機械で自動化できない部分</font>それは<strong>人の心</strong>の部分を押し上げる技術を勉強していきたいです。



...10年後の自分がこれを見てどう思うんだろう。
TextFieldのテキスト入力部分をパスワード形式に変更する方法

新規登録機能などでよくあるパスワード入力欄の作り方です。

<h1>該当のTextFieldにobscureText: trueを追加する</h1>

```
TextField(
                    controller: passwordController,
                    decoration: InputDecoration(
                        border: InputBorder.none, hintText: 'password'
                    ),
                    obscureText: true, //これを追加する
                    onChanged: (text) {
                      model.password = text;
                    },
                  ),
```
これだけ。
Material Youのサンプルアプリを触ってみる

#はじめに
こちらの記事はGoogle I/O 2021で発表された『Material You』のAndroid向けサンプルアプリについての記事になります！
そもそもMaterial Youとは？ という方向けの記事も書いてますので、よろしければ[こちら](https://qiita.com/t_nana/items/5f78377346030cb484fd)をご覧ください

#サンプルアプリの取得
##動作環境
・ M1 MacBook Pro
・ Big Sur 11.4
・ Android Studio Arctic Fox
・ Pixcel 3a / Andorid12（ベータ版）　

※確認端末はエミュレータでも構いませんが、Android12が入っていることが前提になりますので、ご注意ください

##GitHubからclone
material-components-androidの中にサンプルアプリ『Catalog』がありますので、そちらを取得しに行きます。
以下のコマンドをターミナルで実行してください。

```
git clone https://github.com/material-components/material-components-android
```
##Android Studioでサンプルアプリをビルド
clonesしたプロジェクトをAndroidStudioで立ち上げ、実行モジュールに『Catalog』を選択して実行します。
しばらく待てば、端末あるいはエミュレータにアプリがインストールされます。

#動作確認
こちらのアプリはもともとMaterial Componentsはどのようなものがあるのかを確認するためのアプリです。
Dynamic Colorsというのが、端末の背景色に合わせて自動的にアプリのテーマを変えてくれる機能です。Material Youの目玉機能になります！
![スクリーンショット 2021-09-30 18.31.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645987/a93bf7ee-ac9c-8be7-1883-f097c1ee1f67.png)

#テーマを変えた時の動作
Androidでは、アプリをライトテーマからダークテーマに切り替えた時、Activityが再生成されていましたが、テーマ切り替えの場合はどうなるのでしょうか？
ログを仕込んで検証してみます。
MainActivityの各ライフサイクルコールバックにログを追加して実行したところ、以下のようなログが取得できました。

```
// アプリを起動した時
2021-09-30 19:00:07.612 10325-10325/io.material.catalog I/LIFECYCLE: onCreate
2021-09-30 19:00:07.756 10325-10325/io.material.catalog I/LIFECYCLE: onStart
2021-09-30 19:00:07.758 10325-10325/io.material.catalog I/LIFECYCLE: onResume
// Dynamic ColorsをONにした時
2021-09-30 19:00:19.458 10325-10325/io.material.catalog I/LIFECYCLE: onPause
2021-09-30 19:00:19.480 10325-10325/io.material.catalog I/LIFECYCLE: onStop
2021-09-30 19:00:19.486 10325-10325/io.material.catalog I/LIFECYCLE: onSaveInstanceState
2021-09-30 19:00:19.506 10325-10325/io.material.catalog I/LIFECYCLE: onDestory
2021-09-30 19:00:19.538 10325-10325/io.material.catalog I/LIFECYCLE: onCreate
2021-09-30 19:00:19.711 10325-10325/io.material.catalog I/LIFECYCLE: onStart
2021-09-30 19:00:19.713 10325-10325/io.material.catalog I/LIFECYCLE: onResume
```
テーマ切り替え時にはやはりActivityが再生成されるみたいです。
利用する際には、ViewModel等を使ってデータの保持をしておく必要がありそうですね。
onSaveInstanceStateも通過するので、テーマ変更が押されたかやテーマを変更したかなどの行動ログを撮りたい場合には使えそうです。
ちなみにAndroid12以降の端末でなければDynamic Colorsは利用できず、デフォルトテーマのままでした。

#終わりに
今回はサンプルアプリを触ってみました。
いままでアプリのテーマは各アプリごとの固有なものでしたが、Dynamic Colorsを使うことで端末に合わせたテーマに変更されます。
企業やサービスとしてテーマカラーに気を付けている場合には使わない方がいいかもしれないです（ゲームなど）。
逆にメモ、TODO、カレンダーなどについてはどんどん使っていってもいいのかななんて思います。
今後のGoogleサービスにはMaterial Youが使用されていくそうですので、今後の動きに注目ですね。
Unity2D 画面の大きさや四隅の座標をワールド座標で取得する方法

##0.0 はじめに
画面端の四隅のポイント(画面左下や右上の位置)や画面のサイズをワールド座標で取得するための方法を記載しています。







##1.0 画面四隅の座標の取得方法


####1.1 CameraのViewportToWorldPointの利用
Camera.main.ViewportToWorldPoint()を使うと画面端をワールド座標で取得できます。引数が(0,0)で左下、(1,1)で右上を指定できます。




👍**ポイント**
Viewport(ビューポート)はカメラで表示されている画面の領域をx座標、y座標を０から１で表しています。左下が(0,0)、右上が(1,1)となります。


```C#:Test.cs
Debug.Log("画面の左下の座標は " + Camera.main.ViewportToWorldPoint(Vector2.zero) + " です");
Debug.Log("画面の右上の座標は " + Camera.main.ViewportToWorldPoint(Vector2.one) + " です");
``` 




####1.2 Screen.WidthとScreen.Heightの利用
Screen.WidthとScreen.Heightを使用して画面四隅のスクリーン座標を取得できます。
その座標をScreenToWorldPointメソッドを使ってワールド座標に変換します。
Camera.main.ScreenToWorldPoint()は引数にスクリーン座標をとり、これをワールド座標に変換するメソッドです。








👍**ポイント**
画面四隅のスクリーン座標はそれぞれ、
左下 (0,0)
右下 (Screen.Width, 0)
左上 (0, Screen.Height)
右上 (Screen.Width, Screen.Height)
となります。



```C#:Test.cs
Debug.Log("画面の左下の座標は " + Camera.main.ScreenToWorldPoint(new Vector2(0,0)));
Debug.Log("画面の右上の座標は " + Camera.main.ScreenToWorldPoint(new Vector2(Screen.width, Screen.height)));
```
👍**ポイント**
Camera.main.ScreenToWorldPoint()を使って取得したワールド座標は


##2.0 画面サイズの取得方法



####2.1 Orthographicの利用
カメラのProjectionがOrthographicのときはCamera.main.orthographicSizeで画面の縦方向のサイズの半分の長さをワールド座標で取得できます。縦サイズが取得できればアスペクト比から横サイズは取得できます。




👍**ポイント**
カメラのProjectionがOrthographicのときはカメラからの奥行きに関わらずワールド座標は一定となります。



```C#:Test.cs
Debug.Log("画面のアスペクト比（横幅 / 縦幅）は " + 2160 / 1080 + " です");
Debug.Log("画面の縦のサイズは " + Camera.main.orthographicSize * 2 + " です");
Debug.Log("画面の横のサイズは " + Camera.main.orthographicSize * 2 * 2160 / 1080 + " です");
```
10年前の自分に伝えたい、勉強しておきたかったこと

# 10年前の自分に伝えたい、勉強しておきたかったこと

## 背景・目的
　[Qiita 10周年記念イベント \- 10年前の自分に伝えたい、勉強しておきたかった技術 \- Qiita](https://qiita.com/official-events/1e99fc384200c38548fd)ということで、10年間を振り返り、今の知識・記憶のまま10年前に戻った場合何を勉強するのかをまとめてみようと思います。


## この10年で勉強したことを棚卸してみる
　10年前は2011年で、その頃はアラサーというところでした。新人期間は終わり、中堅～ベテランと呼ばれるポジションに移行していくタイミングというところでしょうか。
　それからの10年で非IT領域も含め、仕事や自習を通じ次のようなことを学習してきました。今の業務で利用しているものには○、今後使うのではないかというものには△をつけています。おおよそ時系列順です。

- 英語　○
- IBM Notes/Domino(HCL Notes/Domino)
- Linuxサーバ管理
- AIXサーバ管理
- データセンタ運用・管理　△
- VBscript　○
- 交渉学　○
- IBM Cloud
- Python　△
- 量子コンピュータ　△
- RPA・自動化　△
- Microsoft365（Teams/Sharepoint/PowerApps等）　○
- 簿記　○
- マネジメント　○
- 自社事業の概要・基礎知識　○


## 棚卸ししてみて何がわかるか？

　特定のベンダに依存するようなソリューションは自分の環境が変わると使われなくなっていました。また、年齢を経ると管理系のスキルが多かれ少なかれ求められるため、必要に応じて学んできて、それらは今後も使っていけそうなことがわかります。

　自分がなんとなくやりたいと思っていたIT技術は陳腐化したり、年次が上がると使われなくなっていました。陳腐化しなくてもガンガン勉強する若手が後から後からやってくるので、その技術一本でやっていくのは難しくなっていたなぁということが、自分の中で整理できました。


## 棚卸しを踏まえて、10年前に学習しておきたかったことは？

　棚卸ししながらここ10年のことを色々思い返しましたが、とにかく自分の感情を上手にコントロールする力、外部環境からのあらゆるネガティブな情報をうまくさばく力をたくさんつけるべきで、そういった知識をもっと吸収しておきたかったということがあります。このあたりの力や知識が圧倒的に足りていなかったため、これまでの10年の何年かを無駄にしてしまいました。

　それと英語。英語は身につけても腐らないと思います。当時も勉強していなかったわけではなかったのですが、真剣味が足りずモノになっていませんでした。スピーキング・リスニングの勉強度合いはもっと上げるべきでした。喋れない・相手の言っていることがさばけないと意味がないです。
　最近は昇進や転職にTOEICのスコアが当たり前のように絡んできますし、当時も全く影響が無いわけではなかったのですが、どうせ仕事であんまり使わないしなぁ…とあまり勉強に乗り気ではなかったところはありました。

　3つ目は「マネジメント」に関する勉強です。具体的にはいわゆる管理職として部下を率いて仕事をすることに関するあらゆる知識と、管理部門（人事・経理・総務）の基礎知識です。
　SEやIT技術者をずーっとやっていても自然とマネジャーになれるわけではないです。勉強を始めるまでは自分とマネジャーの間のパスが全く見えず断崖絶壁が横たわっているイメージで、マネジャーになるのは無理ゲー感が強かったです。
　なので、「マネジャーにならなくても一生技術者として食っていく」という考え方で3～4年前までは走っていましたが、ある程度年齢を経た後の転職についてはマネジャー経験（あるいはそれに準ずる経験）が重要視されるため、若干泥縄感ありながらも勉強を始めているというところです。勉強を始めたり、環境を変えたりしたところ、徐々に道が見え始まっている、自分で無理だと最初から諦めなくなってきています。

　最後に「自社事業の概要・基礎知識」を挙げておきます。具体的には、自社がどんなビジネスをしていて、どのように収益を上げているのかについて知ることです。目の前のIT技術だけ見ていると、仕事もやらされ感が強くなってきます。そのIT技術がどう自社のビジネスに貢献しているのか、自分の中で具体的なイメージを持つことはとても重要です。
　ここが良く分かっていれば、自社のビジネスに貢献できるIT技術者となれる可能性が上がるので、大分生きやすかった可能性はあります。
uPlaceの都道府県別登録数

# Script
```
#!/bin/bash                                                                                                                                                                                 

echo "pref_code resultCount"
for i in $(seq -w 1 47); do
  echo -n ${i}" "
  curl -s "https://ucopendb.gsi.go.jp/ucode/api/search.json?pref_code=${i}"|jq .resultCount
done
```

# Result
```
pref_code resultCount
01 899
02 574
03 596
04 480
05 324
06 235
07 2338
08 842
09 519
10 323
11 235
12 244
13 10015
14 3732
15 665
16 428
17 158
18 1089
19 139
20 752
21 422
22 1259
23 661
24 449
25 222
26 133
27 149
28 1192
29 352
30 262
31 294
32 632
33 915
34 1144
35 304
36 280
37 270
38 505
39 254
40 556
41 976
42 252
43 212
44 211
45 153
46 580
47 142
```

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18613/b0de0a8b-5b9d-ff25-a25b-8954e383fb3c.png)
1	北海道	899
2	青森県	574
3	岩手県	596
4	宮城県	480
5	秋田県	324
6	山形県	235
7	福島県	2338
8	茨城県	842
9	栃木県	519
10	群馬県	323
11	埼玉県	235
12	千葉県	244
13	東京都	10015
14	神奈川県	3732
15	新潟県	665
16	富山県	428
17	石川県	158
18	福井県	1089
19	山梨県	139
20	長野県	752
21	岐阜県	422
22	静岡県	1259
23	愛知県	661
24	三重県	449
25	滋賀県	222
26	京都府	133
27	大阪府	149
28	兵庫県	1192
29	奈良県	352
30	和歌山県	262
31	鳥取県	294
32	島根県	632
33	岡山県	915
34	広島県	1144
35	山口県	304
36	徳島県	280
37	香川県	270
38	愛媛県	505
39	高知県	254
40	福岡県	556
41	佐賀県	976
42	長崎県	252
43	熊本県	212
44	大分県	211
45	宮崎県	153
46	鹿児島県	580
47	沖縄県	142
```
Live2D Cubism SDK for Webを簡単にカスタムする

Cubism 4 SDK for Web R3をどこから見て良いかわからん、簡単に使いたい人向けの内容です。
SDKサンプルのDemoコードを簡単にLive2Dモデル差し替え、Canvasサイズを変更する手順です。

## 開発環境
- Cubism4 SDK for Web R3

## 修正箇所 
Demoサンプルの修正箇所は、以下2ファイルでOKです。

フォルダ: /Samples/TypeScript/Demo/

- lappdefine.ts
    - 画像やLive2Dモデルのパス、Canvasサイズが指定されてる
- lappdelegate.ts
    - canvasの背景色が黒に指定されている


## lappdefine.tsから修正箇所だけ抜粋（-の行が削除、+の行が追加）
```ts:lappdefine.ts
// Canvasサイズを指定する
- export const CanvasSize: { width: number; height: number } | 'auto' = 'auto';
+ export const CanvasSize: { width: number; height: number } | 'auto' = {
  width: 500,
  height: 500,
};
// 背景画像を消す
- export const BackImageName = 'back_class_normal.png';
+ export const BackImageName = '';

// 歯車画像を消す
- export const GearImageName = 'icon_gear.png';
+ export const GearImageName = '';

// 表示したいモデル1体を指定する。Resourcesフォルダに自分のLive2Dモデルを配置しよう
- export const ModelDir: string[] = ['Haru', 'Hiyori', 'Mark', 'Natori', 'Rice'];
+ export const ModelDir: string[] = ['Hiyori'];
```
この修正で好きなCanvasサイズで指定したLive2Dモデルで表示できます（ここではCanvasサイズ=500x500）
![スクリーンショット 2021-09-30 17.49.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15028/5ffaac26-a7f0-8956-8e6b-4d51739c6dfe.png)

## appdelegate.tsから修正箇所だけ抜粋（-の行が削除、+の行が追加）
```ts:appdelegate.ts
// 透明度を0にする
- gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
```
これでcanvasの背景色が透明になり、Webサイトのメイン部分の表示を阻害しなくなるかと思います。
![スクリーンショット 2021-09-30 17.52.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15028/18c76fa2-6ba3-a62e-7845-21454540b219.png)
あとはcssでcanvasを好きな位置に配置してあげれば、全機能入りでLive2DがWebサイトに導入できます。
webpack buildしてWordPressなどに入れみて下さい。
Python メソッドから元クラスのインスタンス取得

# 初めに結論
メソッドにselfをつけると元のクラスのインスタンスにアクセスできます．

```.py
hoge_class = hoge_method.__self__  # メソッドから元のクラスを取得
```

# 使用場面(というか自分の例)
まず大体こんな感じのクラスを定義します．

```file2.py
class hoge_class_origin:
    def __init__(self):
        self.class_variables = None
    def variable_checker(self):
        print(self.class_variables)
```
以下の様に関数にメソッドのみを渡した場合，クラスの実体？がスコープ内に無いので安直なクラス名.変数名でのアクセスができません．

```file1.py
import file2

def hoge_executer(given_method):
    # ここでgiven_methodが定義されているhoge_class_instance内のクラス変数にアクセスしたい．
    # けどクラスの実体がない．
    got_hoge_class = given_method.__self__  # __self__でクラスを参照
    got_hoge_class.class_variables = 777
    given_method.variable_checker() # 777が表示される

hoge_class_instance = file2.hoge_class_origin() # クラスのインスタンスを生成
hoge_method = hoge_class_instance.variable_checker # メソッドを変数に代入
hoge_executer(hoge_method) # メソッドのみを関数に渡す．
```

こんな感じで外部のクラスなどに渡すオブジェクトを間違えても後から尻ぬぐい出来ますよ～って使い方でした．
本来の用途ではない気がする．．．

参考：https://docs.python.org/3/library/inspect.html

# 謝罪とあとがき
Pythonは完全に我流で習得したため正直なところメソッドやらクラスやらの単語の使い方が合っているかはわかりません．．．sorry...
kabuステーションAPIをTypescriptから呼び出す環境設定

#概要
kabuステーションAPIの呼び出しはpythonで作成したほうが何かと便利だと思いますが
あえてTypeScript+axios+aspidaで呼び出す環境を作成します

# 必要な環境・ソフトウェア
- linux等のコンソール(WSLも可、ただしアクセス方法がやや難しい)
- VisualStudioCode(あれば楽)
- node(ver12以降)
- npm or yarn

# 構築手順
####1.ディレクトリ・ファイル作成

```bash
mkdir kabucomapi
mkdir kabucomapi/src
mkdir kabucomapi/src/api
touch kabucomapi/src/getToken.ts
```

####2.必要なパッケージのインストール

```bash
cd kabucomapi
yarn init -y
yarn add -D @types/node @types/aspida typescript ts-node
yarn add @aspida/axios axios
yarn tsc --init --rootDir src --outDir dist
```

####3.型定義ファイル作成
kabuステーションAPIのopenAPI定義をaspida定義ファイルに変換します

```bash
cd ./src
npx openapi2aspida -i https://raw.githubusercontent.com/kabucom/kabusapi/master/reference/kabu_STATION_API.yaml
```
src/api以下にkabucomapi用のaspida定義ファイルが作成されます

####4.テスト用ソース作成
**※サンプルです。APIのパスワードはソースに含めないでください**

```TypeScript:src/getToken.ts
import aspida from "@aspida/axios"
import api from "./api/$api"

const data = { 'APIPassword': 'xxx' };
const url = 'http://localhost:18080/kabusapi/token';

;(async () => {
  try {
    const client = api(aspida())
    const res = await client.token.post({ body: data })
    console.log(res.body.ResultCode)
    console.log(res.body.Token)
  } catch(err) {
    console.log(err)
  }
})()
```

####5.tsコンパイル・実行
```shell
npx tsc
node dist/getToken
```

## WSLから呼び出したい場合
- windows側にnginxをインストールしてリバプロさせる（リクエストヘッダのホスト名を書き換える）
- src/api/$api.tsのアドレスをwindowsのipに書き換える

## まとめ
aspidaすごい
[Rust] &str と &&str で呼ばれる to_string メソッドが異なる

`to_string` メソッドではレシーバの自動参照外しが行われません (※後述) 。

少なくともバージョン 1.55.0 現在は、`&str` と `&&str` で異なる `to_string` が呼ばれます。
`&str` のときは `String::from` と同じ動作をしますが、`&&str` の場合は違う動作をします。

- `self: &str` のとき: `<str as ToString>::to_string`
- `self: &&str` のとき: `<T as ToString>::to_string`

※ `self: &&&str` 以降の参照も `<T as ToString>::to_string`

# 1. LLVM IR で確認

```rust
let foo: &&str = &"Foo";
println!("{}", case_1(foo));
println!("{}", case_2(foo));

#[inline(never)]
fn case_1(foo: &&str) -> String {
    <str as ToString>::to_string(*foo)
}

#[inline(never)]
fn case_2(foo: &&str) -> String {
    <&str as ToString>::to_string(foo)
}
```

```bash
cargo install cargo-asm

cargo llvm-ir test::main::case_1 | grep ToString
cargo llvm-ir test::main::case_2 | grep ToString
```

```llvm:case_1&nbsp;の&nbsp;LLVM&nbsp;IR
br i1 %2, label %bb20.i.i.i.i.i.i.i.i.i.i.i, label %"<str as alloc::string::ToString>::to_string.exit"
"<str as alloc::string::ToString>::to_string.exit"
```

```llvm:case_2&nbsp;の&nbsp;LLVM&nbsp;IR
br i1 %3, label %bb1.i.i, label %"<T as alloc::string::ToString>::to_string.exit"
"<T as alloc::string::ToString>::to_string.exit"
```

参考「[GitHub - gnzlbg/cargo-asm: cargo subcommand showing the assembly or llvm-ir generated for Rust code](https://github.com/gnzlbg/cargo-asm)」

# 2. `ToString` トレイトの実装

`Display` トレイトは参照に対して再帰的にブランケット実装され、さらに `Display` トレイトを実装する型に対して `ToString` トレイトがブランケット実装されます。

参考「[[Rust] to_string メソッド等は呼び出し時に自動参照外しされない - Qiita](https://qiita.com/kerupani129/items/eaf16e41bc1786a6d049)」

## 2.1. `&str` の場合

バージョン 1.9.0 から、プリミティブ型 `str` が独自に `ToString` トレイトを実装し、`String::from` と同じ動作をするようになっています。

```rust
impl ToString for str {
    #[inline]
    fn to_string(&self) -> String {
        String::from(self)
    }
}
```

参考「[ToString - str - Rust](https://doc.rust-lang.org/std/primitive.str.html#impl-ToString)」(ブランケット実装でないトレイト実装の方)

## 2.2. `&&str` 等の場合

少なくともバージョン 1.55.0 現在は `&&str` 等に対しては独自の実装はされず、`Display` トレイトを実装する型がブランケット実装する `ToString` トレイトの `to_string` メソッドが呼ばれます。

`Formatter` を介して `String` のバッファに書き込まれます。

```rust
impl<T: fmt::Display + ?Sized> ToString for T {
    // ... 略
    #[inline]
    default fn to_string(&self) -> String {
        let mut buf = String::new();
        let mut formatter = core::fmt::Formatter::new(&mut buf);
        // Bypass format_args!() to avoid write_str with zero-length strs
        fmt::Display::fmt(self, &mut formatter)
            .expect("a Display implementation returned an error unexpectedly");
        buf
    }
}
```

参考「[ToString - str - Rust](https://doc.rust-lang.org/std/primitive.str.html#impl-ToString-1)」(ブランケット実装の方)

```rust
impl Display for str {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        f.pad(self)
    }
}
```

参考「[Display - str - Rust](https://doc.rust-lang.org/std/primitive.str.html#impl-Display)」
iOS課金系ライブラリ纏め

##1. storekit　iOS 3.0+
紹介要点：Appleから提供される課金定番フレームワーク。 信頼性が一番高い、実装量とコードが複雑、メンテが大変。

>公式リンク: https://developer.apple.com/jp/documentation/storekit/
>App内課金リンク: https://developer.apple.com/jp/documentation/storekit/in-app_purchase/
>参考ブログ： https://reftec.work/posts/2021/1/221/

##2. storekit2 Xcode: 13 beta(13A5154h)以上~
紹介要点：Appleから提供される次回課金フレームワーク、
既存のstorekitよりシンプルに改善されたイメージ?

>公式リンク: https://developer.apple.com/jp/storekit/
>紹介ブログ: https://ulog.sugiy.com/wwdc-2021-storekit2/
>サンプリコード: ttps://developer.apple.com/documentation/storekit/in-app_purchase/implementing_a_store_in_your_app_using_the_storekit_api

##3. SwiftyStoreKit
紹介要点：StoreKitをラッパーしたもの、シンプルに実装できそう、紹介ブログが結構ある,Star5.7k。バックエンド開発要。

>cocoapods.org:　https://cocoapods.org/pods/SwiftyStoreKit
>Github:　https://github.com/bizz84/SwiftyStoreKit
>関連紹介:　https://qiita.com/fromage-blanc/items/f6aa2c7d090217afddc5

##4. CargoBay
紹介要点：StoreKitをラッパーしたもの。Objective-C、古い、メンテ止め。
>関連紹介:　 https://dev.classmethod.jp/articles/ioscargobay-1/

##5. Stripeサービス
紹介要点：Apple Payを利用した課金サービス、シンプルに実装。別途バックエンド設定あり、運用コストあり。

>公式:　https://stripe.com/jp
>github:　https://github.com/stripe/stripe-ios
>関連紹介:　https://qiita.com/mitsuhiro_K/items/6a434e4dd5984374a49b
         https://qiita.com/shindooo/items/ebe69238368a2d6a7ebb

##6. その他課金サービス Braintree,Venmo, Moltin, Omise,revenuecat ...
紹介しなくてもいいかな...

***********

Flutter+ Firebase 課金
https://tech.studyplus.co.jp/entry/2020/04/13/102204

iOS Swift リソース
https://github.com/jobbole/awesome-ios-cn

#### 課金テスト関連:
> Xcode 12 でのアプリ内購入のテスト
https://qiita.com/MaShunzhe/items/486f45ba39433ce10d8a
https://dev.classmethod.jp/articles/xcode12_storekit_test/

#### swift/Flutter documents Chinese version:
https://gitee.com/wooseng/awesome-ios
シェルスクリプトで規定時間処理を行う

#はじめに

「シェルを用いて数十秒、数分の間処理を行い続ける」
ということを行いたいということがある。
今回はそのサンプルとなるようなシェルスクリプトを紹介する。

#シェルスクリプト

```shell
#!/bin/bash

#開始時刻を取得
date_start=$(date +%Y/%m/%d-%H:%M:%S)
#経過時間計算時使用するスタート時刻を取得
start_time=$(date "+%s")
#経過時刻変数
elapsed_time=0

#経過時間が10秒を経過したらwhile文を抜ける
while :; do
    if [ $elapsed_time -ge 10 ]; then
        echo "ここに行いたい処理を入れる"
        break
    else
        echo "処理中です"
        #1秒停止
        sleep 1
        #現在時間を算出
        current_time=$(date "+%s")
        #経過時間を計算
        elapsed_time=$(($current_time - $start_time))
    fi
done

#終了時間を取得
date_end=$(date +%Y/%m/%d-%H:%M:%S)

echo "ループを抜けました。"
echo "$date_start に処理を開始"
echo "$date_end に処理を終了"

exit 0

```

#使い方
```shell
if [ $elapsed_time -ge 10 ]; then
```
上記の「１０」が処理を行う時間。
この数字を調整することで行う時間を調整する

```shell
echo "ここに行いたい処理を入れる"
```
上記部分に繰り返し行いたい処理を入れる

```shell
sleep 1
```
次に繰り返し処理をするまでのインターバルとして入れる