OmniAICreator/Qiita-1.07M huggingface dataset:
MacBook Airの環境設定について

## 背景
私が入社した2年半ほど前はWindowsしか選べない状況でした
先日、端末のスペックで相談したところ、Macも選べるよとお聞きし、手配してもらいました
なお、MacBook Proと勝手に思い込んでいたのは内緒です

プライベートではずっとMacを使い続けていますが、開発環境を構築するのはいつ以来になるのやらw

お仕事はAWSプラットフォーム上でバックエンドシステムの開発を行うsoftware developerで、Python, TypeScriptあたりをよく使います

## セットアップ内容
### インストールしたアプリ
#### IDE
<dl>
  <dt>Intelli J</dt>
  <dd>一番完成度の高いIDEではないでしょうか、メインはこちらを使っています</dd>
  <dt>VS Code</dt>
  <dd>Inntelli Jはメモリをかなり使うのと、TypeScriptの補完はこちらが良いので適当に使い分けています</dd>
</dl>

#### ターミナル
<dl>
  <dt>iTerm2</dt>
  <dd>Macの開発環境では定番ですよね。取り敢えずはtmuxとfish入れて、HotKeyをセットして快適ターミナル生活を過ごしています</dd>
</dl>

#### (軽量)エディタ
<dl>
  <dt>neovim</dt>
  <dd>Windowsの時はnotepad++を愛用していましたが、折角の機会なのでnvimを使うことにしました<br/>
設定まわりに時間を取られたくないので、ちょっとした編集作業用です</dd>
  <dt>MacVim</dt>
  <dd>ターミナル以外での編集作業はこちらで</dd>
  <dt><a href="http://www.artman21.com/jp/jeditOmega/">Jedit Ω</a></dt>
  <dd>vimでしんどい時はこちらかと<br/>
JEdit Xがなくなったと思っていましたが、復帰してくれて嬉しいです</dd>
</dl>

##### その他
* office365
* Docker
* slack
* chrome
* Display Link Manager
* Remote Desk Top
* [homebrew](https://brew.sh/index_ja)
* [Volta](https://volta.sh/)

### Finderの設定変更
サイドバーに下の項目を表示
* アプリケーション
* 書類
* ダウンロード
* home
* ハードディスク
詳細の下の項目にチェック
* すべてのファイル名拡張子を表情

### brewで入れたもの
* python@3.9
* neovim
* tmux
* fish
<dl>
  <dt>powershell</dt>
  <dd>Windows環境で作ったPowerShellファイルの実行用です</dd>
  <dt>[marta](https://marta.sh/)</dt>
  <dd>Finderが優秀ですが、[あふ](http://akt.d.dooo.jp/akt_afxw.html)みたいに動いてくれれば嬉しいです</dd>
</dl>


### OSの設定で変更した点
#### LauchPadのキーバインド
⌘ + L

#### 日本語変換とスポットライトのキーバインド
家のMacと同じように
* 日本語変換を ⌘ + Space
* スポットライトをCtrl + Space
と逆にしました

#### セキュリティ > アクセシビリティ > Logicoolにチェック
マウスホイールでのスクロールが有効に！

#### 画面収録にDisplay Linkを追加
これで３画面化が可能に

### 今後やりたいこと
<dl>
  <dt>HHKBのFnキー、日本語変換キーの割り当て追加</dt>
  <dd>英語配列のキーボードを使っていますが上記は不便ですよね<br />
使っていない右⌘、右Optあたりに割り当てたいと考えています</dd>
  <dt>キーボードブリッジ</dt>
  <dd>今はパームレストにキーボードを置いていますが、何か安心出来ません。<br />
キーボードブリッジなるものも市販されていますが、ちょっとお高いようでして...<br/>
ホームセンターでアクリル板とウレタンシートを入手してうまいこと出来ないかなぁと考えています</dd>
</dl>

### 出来なかったこと
#### pyenvのインストール
検索すると情報は色々出てきますが、出来ませんでした
現在はbrewでインストールした3.9を使っています
必要に迫られたらvirtualenv等で対応していく予定です


## 最後に
Touch IDでの認証は思ったより快適です

Type CハブやDisplay Link用のアダプタの購入が必要だったり、WinMergeといった便利ツールが存在しなかったり、M1 Macならではのpyenvのインストール不備、設定ファイルのメンテナンス等、マイナスな面も確かにありますが、トータル的にはプラス面が上回っていて、快適Software Developer生活を過ごせています

fishやtmuxの設定は、最小限に留めていますので、当Blogでは割愛します
[TypeScript]具体例で理解する、配列から"その配列型"と"その要素のUnion型"を定義する方法とその使い道

# この記事でできるようになること
- 配列を１つ定義するだけで、それを元にその配列型とその要素のUnion型を定義することができる。

# メリット
- 配列の要素を増やすと、TypeScriptがUnionタイプの要素も自動で追加して解釈してくれる。
- 上記により同じ情報を複数箇所で定義・管理する必要がなくなる

# 方法

```typescript
const STATUSES = ['A','B','C'] as const
type Statuses = typeof STATUSES;
// readonly ["A", "B", "C"]
type Status = Statuses[number]
// "A" | "B" | "C"
```
忘れてはいけないのは`as const`をつけて配列を定義することである。
`as const`がない場合、TypeScriptは`['A','B','C']`を`A,B,Cだけからなる配列`としてではなくこれを抽象的に解釈した`文字列の配列(string[])`として解釈してしまうからである。

`Statuses[number]`で配列の要素をメンバーとするUnion型を生成できる理由はsuinさんの[この記事](https://qiita.com/suin/items/25588b2beba7a3fcce4f)が大変参考になった。

# 具体的な使い道
## 前提
例えば、Trelloのようなタスク管理アプリケーションを作っていたとき、
アプリ内のカードは`NotStarted`,`In Progress`,`Completed`という3つのステータスを持つとする。
それぞれのカードはこの状態のうちどれか１つを保持していて、ユーザーの選択によって別の２つの状態に変更できるとする。

このとき、各カードが持つステータスは次のようなUnion型で定義できる

- カードの持つStatus型

```typescript

type STATUS = 'NotStarted' | 'In Progress' | 'Completed';

```

次にカードの状態を選択するセレクターの描画部分は次のようにかける

```typescript
const STATUSES = ['NotStarted','In Progress','Completed'];
```

```tsx
<select
  value={task.status}
  onChange={onStatusChange}
>
  {STATUSES.map(status=>(
    <option key={status} value={status}>{status}</option>)
   )}
</select>

```

セレクターのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/7824db14-8f2f-e032-591b-a83bfb7c6f9b.png)


## 何が問題になるか

これによって、確かに目的は達成されるが、仮にステータスのオプションの種類が１つ増え以下のようになったとする。

```typescript

const STATUSES = ['NotStarted','In Progress','Completed','Archive'];

```

このとき、`STATUS`型を定義している部分でも新たに'Archive'を許容するようになって欲しいが実際は以下のようにエラーが出る。これは当然で、配列STATUSESとStatus型になんの紐付けも存在しないからである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/f1784048-ca60-97b2-999d-4f57a9e7fe08.png)

## 解決方法
ここで今回の記事で紹介した方法で定義し直すと以下のようになる。

```typescript
const STATUSES = ['NotStarted','Doing','Completed','Archive'] as const;
type StatusesType = typeof STATUSES;
type Status = StatusesType[number]
```
今回はエラーも起きず、Status型に'Archive'が動的に追加されていることが確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366323/a2039fee-e065-4b8a-845a-efdbefba4786.png)

# おわりに
今回のポイントは以下２つ。
- 配列の定義に`as const`を使う
- 配列型に[number]でアクセスすることでその要素のUnion型を作ることができる

後者に関しては、記事内でも紹介したようにsuinさんの[この記事](https://qiita.com/suin/items/25588b2beba7a3fcce4f)が参考になった。
前者に関しては、TypeScriptのType Wideningという挙動を知るとさらに理解が深まるはずである。Type Wideningに関しては自分の場合は[Effective TypeScript](https://www.oreilly.com/library/view/effective-typescript/9781492053736/)が参考になった。

# 参考
- [TypeScript: 配列型からその要素のユニオン型を導出する方法。](https://qiita.com/suin/items/25588b2beba7a3fcce4f)
- [Effective TypeScript](https://www.oreilly.com/library/view/effective-typescript/9781492053736/)
プリザンターのサーバスクリプトをVSCodeでデバッグする

# 概要

[Pleasanter](https://pleasanter.org/)の[サーバスクリプト](https://pleasanter.org/manual/table-management-server-script) をビジュアルにデバッグしたい!と思う貴方は必見です。
デバッグするためにはVisual Studio Code(以降VSCode)が必要になります。
VSCodeからリモートデバッグをします。

# 制限事項

デバッグ中はデバッガが接続するまでスクリプトが途中で停止しテーブルを利用できません。
**本番環境では使用しない**でください。


# 前提条件

1. プリザンターは2021/10/31リリースの`ver.1.2.14.0`以上が必要です
1. プリザンターが稼働するサーバのポート`9222`が開いている必要があります。
1. デバッグを行うPCにVSCodeがインストールされている必要があります。


# 準備

Visual Studio Codeを起動し、`.vscode`フォルダ内に`launch.json`を配置します。

```json:launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Attach to ClearScript V8 on port 9222",
            "type": "node",
            "request": "attach",
            "protocol": "inspector",
            "address": "192.168.1.101",
            "port": 9222
        }
    ]
}
```


- デバッグするプリザンターが動作する環境への接続情報です
- 必要に応じて`address`を対象のサーバのアドレスに変更します
- ローカルPC上にプリザンターがある場合には`localhost`を指定します。


# 操作手順

1. ブラウザでプリザンターにアクセスしデバッグする「サーバスクリプト」の内容の先頭行に、`//debug//`を記述し保存します。
1. デバッグする「テーブル」を開きます。
1. サーバスクリプトがデバッグモードで待機状態となり画面の応答が無い状態になります。
1. VSCodeで`Run` → `Start Debugging`を選びます。
1. 対象のソースコードが読み込まれ、デバッグが可能となります。


# 動作イメージ

対象ソースが読みこまれてブレイクしているところ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912766/797f48ba-3639-6108-606a-a9b47c5895bf.png)

グローバル変数やマウスホバーで変数の中身も見えます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912766/168801ad-e397-f5cf-3c53-72d53e284eb2.png)
[Flutter Web] VRouterを使ってURLからパラメータを取得する

この記事は、【 [可茂IT塾 Advent Calendar 2021](https://qiita.com/advent-calendar/2021/kamo-it) 】の12日目の記事です。

FlutterWebのアプリ作成で実装したことを記事にしました。
誰かのお役に立てれば、幸いです。

## VRouterについて

https://pub.dev/packages/vrouter

このパッケージは、FlutterWebのルーティングをいい感じにしてくれます。

[可茂IT塾のブログ](https://www.kamo-it.org/blog/24/)でも一度紹介されていて、

ブログでは、`hashモード`と`historyモード`について解説されています。

ドキュメントにもある、基本的な実装は下のコード例のようになります。

```dart
// main.dart

import 'package:flutter/material.dart';
import 'package:vrouter/vrouter.dart';
import 'package:web_test/pages/home_page.dart';
import 'package:web_test/pages/setting_page.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return VRouter(
        debugShowCheckedModeBanner: false,
        mode: VRouterMode.history,
        routes: [
          VWidget(path: '/', widget: const HomePage()),
          VWidget(path: '/setting', widget: const SettingPage()),
        ]);
  }
}
```

main.dartでVRouterを返して、そこにルーティングを書きます。（`routes:`の部分）

```dart
// home_page.dart

import 'package:flutter/material.dart';
import 'package:vrouter/vrouter.dart';

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("ホームページ")),
      body: ElevatedButton(
        onPressed: () => context.vRouter.to('/setting'),
        child: const Text("セッティングページへ"),
      ),
    );
  }
}


```

上記のような形で、ページ遷移できます。

## 動的なルーティングでURLからパラメータを取得する

なにかしらのIDを渡したりして、URLを動的に変化させたい場合は、ルーティングの書き方を少しだけ変える必要があります。

```dart
      VWidget(
        path: '/user/:userId',  // ここを変える
        widget: UserScreen(),
      ),
```
動的な部分にコロンを付けるだけです。

パラメータを反映させたURLを指定して、ページ遷移させます。

```dart
ElevatedButton(
   onPressed: () => context.vRouter.to('/user/$userId'), //URLにパラメータを入れる
   child: Text('Go to $user'),
 ),
```
遷移したページで、このパラメータを取得するには、下のようになります。

```dart
final _userId = context.vRouter.pathParameters['userId'];
```






## 参考
https://vrouter.dev/guide/Examples/Path%20parameters
RaspberryPi Compute Module 4 について

### RaspberryPi Compute Module 4
本家
https://www.raspberrypi.com/products/compute-module-4/?variant=raspberry-pi-cm4001000
https://www.raspberrypi.com/products/compute-module-4-io-board/ IOボード
Switch Science
https://www.switch-science.com/catalog/6713/
https://www.switch-science.com/catalog/6689/ IOボード
RSコンポーネンツ
https://jp.rs-online.com/web/p/raspberry-pi/2064853
https://jp.rs-online.com/web/p/raspberry-pi/2064868 IOボード

### Teensy
Teensy 3.2 https://www.switch-science.com/catalog/2447/ 5Vトレラント
Teensy 3.5 https://www.switch-science.com/catalog/3078/ 5Vトレラント、120 MHz ARM Cortex-M4
Teensy 4.0 https://www.switch-science.com/catalog/6570/ 600 MHz ARM Cortex-M7
Teensy 4.1 https://www.switch-science.com/catalog/6571/

### Arduino
ATmega32u4-AU
https://www.switch-science.com/catalog/721/ CPU単体
https://www.switch-science.com/catalog/1120/ ピンヘッダ付き

### FTDI USB-UART
FTDI本家
https://ftdichip.com/ トップページ
https://ftdichip.com/products/ft232hl/ 1ch IC
https://ftdichip.com/products/ft2232hl/ 2ch IC
https://ftdichip.com/products/ft4232hl/ 4ch IC
https://ftdichip.com/products/um232h/ 1ch
https://ftdichip.com/products/ft2232h-mini-module/ 2ch
https://ftdichip.com/products/ft4232h-mini-module/ 4ch
RSコンポーネンツ
https://jp.rs-online.com/web/p/communication-wireless-development-tools/7300146 4ch-module
[Flutter Web] onCallでCloud Functionsの関数を呼び出す

この記事は、【 [可茂IT塾 Advent Calendar 2021](https://qiita.com/advent-calendar/2021/kamo-it) 】の10日目の記事です。

FlutterWebのアプリ作成で実装したことを記事にしました。
誰かのお役に立てれば、幸いです。

## 準備
Firebaseの初期設定は、

https://firebase.flutter.dev/docs/overview

を参考にしてください。

####CloudFunctionsの初期設定

pubspec.yamlに

https://pub.dev/packages/cloud_functions

```dart
dependencies:
  flutter:
    sdk: flutter
  firebase_core: "^0.7.0"
  cloud_functions: "^0.9.0" //追加
```

を追加して、`$ flutter pub get`

`index.html`にSDKを追加します。

```html
<html>
  ...
  <body>
    <script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.6.1/firebase-functions.js"></script> // 追加
  </body>
</html>

```

## 実装
ElevatedButtonを押すと、関数が呼び出されるようになっています。

```dart
import 'package:cloud_functions/cloud_functions.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';

class FunctionsPage extends StatelessWidget {
  const FunctionsPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('テスト'),
      ),
      body: Column(
        children: [
          const Text('テスト'),
          ElevatedButton(
            onPressed: () async {
              final functions = FirebaseFunctions.instanceFor(
                  app: Firebase.app(), region: 'asia-northeast1');
              final callable = functions.httpsCallable('FUNCTION NAME',
                  options: HttpsCallableOptions(
                      timeout: const Duration(seconds: 300)));
              await callable();
            },
            child: const Text('テスト'),
          ),
        ],
      ),
    );
  }
}

```


上のコード例では、リージョンや、タイムアウトなども設定して関数を呼び出すようにしています。

デプロイの際にリージョンを指定していなければ、下の形でも動きます。

```dart
ElevatedButton(
       onPressed: () async {
       final functions = FirebaseFunctions.instance;
       final callable = functions.httpsCallable('FUNCTION NAME');
       await callable();
     },
```




## 参考
https://firebase.flutter.dev/docs/functions/overview

https://firebase.google.com/docs/functions/callable?hl=ja#:~:text=%E3%83%95%E3%82%A3%E3%83%BC%E3%83%89%E3%83%90%E3%83%83%E3%82%AF%E3%82%92%E9%80%81%E4%BF%A1-,%E3%82%A2%E3%83%97%E3%83%AA,-%E3%81%8B%E3%82%89%E9%96%A2%E6%95%B0%E3%82%92

https://qiita.com/aimno13/items/42e6a4ab9bed8bd47b4c
inputタグにつけることのできるオプションをいくつか紹介します。

#概要
こんにちは！今日はinputタグにつけることのできる代表的なオプションを紹介したいと思います。
とはいっても僕が開発の時に有用だと感じたものをずらっと簡単に紹介します！
コード例ではReactのJSXを用いています。

#内容
コード例

```typescript
          <input
            className="form-field"
            placeholder="姓"
            type="text"
            required={true}
            maxLength={19}
　　　　　　　　　　　　　　　　　　　　　　　　autoComplete="family-name"
          />
```

1.className
これはReact特有の書き方になります。普通のHTMLではclassで良いです。
ここでクラスの名前を指定することでCSSファイルで指定したCSSが適用できるようになります。

2.placeholder
最初にフォームを開いた時、ここに設定した値がフォームの入力欄に薄い色で記入されます。

3.type
どのようなデータを入力するのかを指定します。これによりウェブページの動きがかなり変わってきます。

4.required
入力が必須な時はここをtrueにしておきます。するとReactでは入力されていない時にメッセージを出してくれます。

5.maxLength
入力できる文字の最大の長さを指定できます。これ以上入力しようとすると入力されなくなります。

6.autoComplete
ここで入力するデータの種類を指定します。これによりブラウザに入力されたデータを保管する必要があることを示唆します。
入力できるデータには"given-name"や"nickname"など色々あります。
Alertmanager: 通知テンプレートの展開を確認する

## はじめに
Alertmanager の[通知テンプレート](https://prometheus.io/docs/alerting/latest/notification_examples/)を設定するとき、テンプレートが想定通りに展開されるか手元で確認したいことはないでしょうか。そんなとき、任意のデータを使ってテンプレートを展開できる、[amtool](https://github.com/prometheus/alertmanager#amtool) の `template render` サブコマンドが便利です。

## amtool のインストール
[amtool](https://github.com/prometheus/alertmanager#amtool) は、Alertmanager の CLI ツールです。amtool は [リリースのバイナリ](https://github.com/prometheus/alertmanager/releases) に含まれる他、`go get` で単体のインストールが可能です。通知テンプレートの展開を行う `template render` サブコマンドは、[v0.23.0](https://github.com/prometheus/alertmanager/releases/tag/v0.23.0) から実装されています。

```
go get github.com/prometheus/alertmanager/cmd/amtool
```

## テンプレートの展開を確認する
テンプレートの展開には `amtool` の `template render` サブコマンドを利用します。

例えば `slack.tmpl` というテンプレートファイルの `slack.text` という名前のテンプレートを利用したい場合、以下のように実行します。`data.json` はテンプレートに渡す JSON 形式のデータ(後述)になります。

```bash
amtool template render \
  --template.glob=slack.tmpl \
  --template.text='{{ template "slack.text" . }}' \
  --template.data=data.json
```

実行後、テンプレートが展開された結果が表示されます。

```console
• *<https://1.example.com/|alert1>*: desc1
• *<https://2.example.com/|alert2>*: desc2
```

`--template.glob` は必須の引数になっていますが、`/dev/null` などダミーを指定することで、 `--template-text` でテンプレート文字列だけを確認することもできます。

```bash
amtool template render \
  --template.glob=/dev/null \
  --template.text='{{- .Status | toUpper }}{{ if eq .Status "firing" }} {{ .Alerts.Firing | len }} ALERTS{{ end }} ({{ .GroupLabels.cluster }})' \
  --template.data=data.json
```

同様に結果が表示されます。

```console
FIRING 2 ALERTS (cluster-A)
```

## テンプレートデータの準備
テンプレートのデータは `--template.data` 引数で、JSON 形式のファイルとして指定します。省略時は、[デフォルトのダミーデータ](https://github.com/prometheus/alertmanager/blob/v0.23.0/cli/template_render.go#L28-L85)が使用されます。しかし、ラベルやアノテーションなどのキーや値は環境ごとに違うため、多くの場合は自分でデータを準備する必要があるでしょう。

テンプレートに渡されるデータ形式は [NOTIFICATION TEMPLATE REFERENCE](https://prometheus.io/docs/alerting/latest/notifications/) に記載されています。例えば前項の確認では、以下のデータを使いました。残念ながら v0.23 時点では YAML 形式には直接対応していませんが、次項で紹介する方法を使って YAML を利用できます。

```json
{
  "Status": "firing",
  "Alerts": [
    {
      "Status": "firing",
      "Labels": {
        "alertname": "alert1"
      },
      "Annotations": {
        "runbook": "https://1.example.com/",
        "description": "desc1"
      }
    },
    {
      "Status": "firing",
      "Labels": {
        "alertname": "alert2"
      },
      "Annotations": {
        "runbook": "https://2.example.com/",
        "description": "desc2"
      }
    }
  ],
  "GroupLabels": {
    "cluster": "cluster-A"
  }
}
```

## YAML 形式でテンプレートデータを利用する
JSON 形式でデータを編集するのが辛い場合、YAML でデータを用意して実行時に JSON に変換するのが便利です。以下の例では bash のプロセス置換(`<(command)`)で [yq](https://github.com/mikefarah/yq) を使って、`data.yaml` を JSON に変換しています。

```bash
amtool template render \
  --template.glob=/dev/null \
  --template.text='{{- .Status | toUpper }}{{ if eq .Status "firing" }} {{ .Alerts.Firing | len }} ALERTS{{ end }} ({{ .GroupLabels.cluster }})' \
  --template.data=<(yq e -o=json . data.yaml)
```

## おわりに
Alertmanager に限りませんが、テンプレートでは、編集時に余計な空白や改行を付加してしまうようなミスをしがちです。複雑なテンプレートを書いた場合は、ぜひ `amtool` の `template render` を活用してみてください。
検索結果を着色する【ExcelVBA】


## 概要
パワークエリでまとめる前に絞り込みとかしたくて、でもグループ化がピボットテーブルだと面倒な形があったので生データを直接着色して整理することにしたのでその時に作ったやつ。

## 使い方

### `検索してヒットしたものを着色`
セル範囲選択を3回行う。

1. 検索ワード
1. 検索範囲
1. ColorIndexを指定<br>デフォルト値をランダムで1~20にしてある<br>範囲を変えたければここを変える→ `WorksheetFunction.RandBetween(1, 20)` 



### `検索してヒットしたものを着色_一気に`
選択範囲内で重複したものを同じ色にする。
セル範囲選択は1回。
色番号はセル範囲の上からDictionary追加時に1から順に追加している。

## コード

``` vb
Option Explicit

Sub 検索してヒットしたものを着色()
  On Error Resume Next
  Dim KW As Range
  Dim Area対象 As Range
  Set KW = Setセル範囲("検索ワードのセルを指定", "セル選択")
  Set Area対象 = Setセル範囲("検索範囲を指定", "セル選択")
  
  Dim my色Index
  my色Index = InputBox("色番号を指定", "", WorksheetFunction.RandBetween(1, 20))
  
  Application.ScreenUpdating = False
  Dim e As Range
  For Each e In Area対象
    If e.Value = KW.Value Then
      Call 着色(e, my色Index)
    End If
  Next
  Application.ScreenUpdating = True
End Sub

Private Function Setセル範囲(Prompt, Title) As Range
  Set Setセル範囲 = _
        Application.InputBox(Prompt, Title, , , , , , Type:=8)
End Function

Private Sub 着色(Cell対象 As Range, my色Index)
  With Cell対象
    .Interior.ColorIndex = my色Index
    .Font.ColorIndex = my色Index + 1 '黒文字と同系統色だと見づらいので文字色も変えて回避する
  End With
End Sub

'====================================================

Sub 検索してヒットしたものを着色_一気に()
  On Error Resume Next
  Dim KW As String
  Dim Area対象 As Range
  Set Area対象 = Setセル範囲("検索範囲を指定", "セル選択")
  
  Dim myList
  Set myList = Get重複無しリスト(Area対象)
  
  Application.ScreenUpdating = False
  Dim i: i = 0
  Dim ub: ub = UBound(Area対象.Value2)
  Dim e As Range
  For Each e In Area対象
    Call 着色(e, myList(e.Value))
    i = i + 1
  Next
  Application.ScreenUpdating = True

End Sub

Private Function Get重複無しリスト(Area対象 As Range)
    Dim Dic, i As Long, myKey As String, myColorIndex As Long
    Set Dic = CreateObject("Scripting.Dictionary")
    
    myColorIndex = 0
    Dim e As Range
    For Each e In Area対象
        myKey = e.Value
        If Not Dic.Exists(myKey) Then
            myColorIndex = myColorIndex + 1
            Dic.Add myKey, myColorIndex
        End If
    Next
    Set Get重複無しリスト = Dic
End Function

```

## 振り返り・新しく知ったこと
### セル範囲を拾うInputBoxは引数が無駄に多いので自作関数化しておくと扱いやすい

大体使い硬いのは`Prompt`, `Title`くらいなので他はマスクしちゃう

``` vb
Private Function Setセル範囲(Prompt, Title) As Range
  Set Setセル範囲 = _
        Application.InputBox(Prompt, Title, , , , , , Type:=8)
End Function
```

細かく指定したい場合は以下を参照

https://docs.microsoft.com/ja-jp/office/vba/api/excel.application.inputbox

http://officetanaka.net/excel/vba/tips/tips37.htm
よく使ったES6の新機能

### 一、constとlet
この前のバッジョンにおいて、varしかないが、es6からconstとletを新規追加されます。
それぞれの機能は下記の通りです。

- **const**: constを使えば、定数を実現できる。

```javascript
const a = 1
a = 0 //compile error
```

- **let**: 以前はvarで宣言される変数はブロック外でも参照できるので、本番環境で怪しい問題が起こるかもしれません。es6からletで宣言される変数はブロック内しか参照できない。

```javascript
var x = 'グローバル変数';
{
  let x = 'ブロック変数';
  console.log(x); // ブロック変数
}
console.log(x); // グローバル変数
```

### 二、アロー関数
アロー関数とは、もっと簡潔なプログラミング方式の一つです。
アロー関数を使うと、下記のよいポイントをもらえます。

- function というキーワードを書く必要がなくなる。
- returnというキーワードを書く必要がなくなる。
- 直前のthisキーワードを継続する。

例えば、

```javascript
// ES5
var add = function (a, b) {
    return a + b;
};
// アロー関数
var add = (a, b) => a + b;
```

### 三、for...of と for...in
- for...ofで配列などのデータを繰り返す。

```javascript
let letter = ['a', 'b', 'c'];
letter.size = 3;
for (let letter of letters) {
  console.log(letter);
}
// result: a, b, c
```
- for...inでオブジェクト中の属性を繰り返す。

```javascript
let stu = ['Sam', '22', '男'];
stu.size = 3;
for (let stu in stus) {
  console.log(stu);
}
// result: Sam, 22, 男
```
### 四、クラス
es6から、クラスを作れますのでオブジェクト指向プログラミング出来ます。

```javascript
class Student {
  constructor() {
    console.log("I'm a student.");
  }
 
  study() {
    console.log('study!');
  }
 
  static read() {
    console.log("Reading Now.");
  }
}
 
console.log(typeof Student); // function
let stu = new Student(); // "I'm a student."
stu.study(); // "study!"
stu.read(); // "Reading Now."
```
かつ、es6で親のクラスを継承出来ます。

```javascript
class Phone {
  constructor() {
    console.log("I'm a phone.");
  }
}
 
class Iphone extends Phone {
  constructor() {
    super();
    console.log("I'm a phone designed by Iphone ");
  }
}
 
let myIphone= new Iphone ();
```
### 五、promise
promiseとは、JavaScriptにおいて、非同期処理の操作が完了したときに結果を返すものです。

```javascript
const promise = new Promise((resolve, reject)=>{
  if (/* success */){
    resolve(value);
  } else {
    reject(error);
  }
});
```

ここでは、
**resolve関数**はpromise対象の状態を**pending**から**fulfilled**に変換して処理結果を戻す。
**reject関数**はpromise対象の状態を**pending**から**rejected**に変換してエラーをスローする。

```javascript
promise.then((value)=>{
  // success
  console.log(value)
}, (error)=> {
  // failure
  console.log(error)
});
```

### 最終に
最後まで読んでいただき、ありがとうございます。
その他のes6の新機能について、下記のサイトをご参照ください。
ECMAScript 6: New Features
http://es6-features.org
Next.js メモ　＆　爆速セットアップ

>前提：Next.jsは、JavaScriptライブラリであるReact開発におけるフレームワーク

Zennというサイトに
爆速セットアップというありがたいサイトがあったので多分こっちの方がいいよ🐾✨

https://zenn.dev/a_da_chi/articles/181ea4ccc39580


Vercelへデプロイもしておきたい！

https://tomosta.jp/article/nextjs-basic/#ib-toc-anchor-25


<br>

以下自分でやったやつ

```作業手順(プロジェクトの作成手順）
1.npx　コマンドが使えること

2.フォルダ作成（vscordでファイルを開く)

3.npx create-next-app --example with-typescript {プロジェクト名}

4.起動確認　プロジェクト名の階層に移動して「npm run dev」

5サイトの作成完了


6.Next.jsでSSR、SSGの方法

基本的にpagesディレクトリ配下に作成したページに以下の関数を追加するだけです。

SSGしたい場合
APIなどから取得したデータを元にページを動的に作成する場合・・・getStaticPaths + getStaticProps
動的なページ作成は不要な場合・・・getStaticPropsのみ
SSRしたい場合・・・getServerSideProps
以下はSSGのAPIなどから取得したデータを元にページを動的に作成する場合のサンプルコードです。(残りは公式ドキュメントを参考にしてください。)




```/pages/piyo/[id].tsx
import React from 'react';
import { GetStaticPaths, GetStaticProps } from 'next';

// 型定義：一覧
type Piyo = {
  id: string;
};

// 型定義：詳細
type PiyoDetail = {
  id: string;
  name: string;
  value: string;
};

// 3. あとはgetStaticPathsとgetStaticPropsで作成されたpropsを使用して画面描画する処理を記述してあげればOK
const piyoPage: React.FC<PiyoDetail> = ({ id, name, value }) => (
  <div>
    {`idは${id}、nameは${name}、valueは${value}です。`}
  </div>
);

// 1. まずはここで動的に作成するページデータを取得
export const getStaticPaths: GetStaticPaths = async () => {
  // API叩いて一覧データを取得と仮定
  const response: Piyo[] = await fetch('https://.../piyos');

  // paramsの中のid:はファイル名の[id]の部分と合わせること
  const paths = response.map((piyo: Piyo) => (
    { params: { id: piyo.id } }
  ));

  // これでgetStaticPropsでparamsが使用可能に
  // fallback=falseは存在しないページは404
  return { paths, fallback: false };
};

// 2. ここでpiyoPageでpropsとして使用するデータを取得・作成します
export const getStaticProps: GetStaticProps = async ({ params }) => {
  // API叩いて詳細データを取得と仮定
  const piyoDetail: PiyoDetail = await fetch(`https://.../piyos/${params.id}`);

  // これでpiyoPageでpropsとして使用可能に
  return { props: { piyoDetail } };
};

export default piyoPage;

```

これでawait fetch('https://.../piyos')で1〜3のidが取得できた場合、
ビルド後に
http://localhost:3000/piyo/1
http://localhost:3000/piyo/2
http://localhost:3000/piyo/3
といった感じでアクセスできるようになります。





8.Chakra UIで遊んでみよう（✖ダークモード）
https://zenn.dev/knjname/articles/20210105tryoutchakraui

Next.jsにChakura導入
https://fwywd.com/tech/next-chakra-ui




```
Safari の contextmenu から<input type="file">をクリック

そもそもの目的は、
JavaScript のイベントリスナーで contextmenu から \<input type="file"\> を発火させて "ファイル選択ダイアログ" を開かせる、というものでした。
結果、
Edge、FireFox、Chromeは、Win・Mac両方で問題なく "ファイル選択ダイアログ" が開きました。

ところが「Safari では開かない」というのが本記事です。
超マイナーですみません。

それでは、\<input type="file"\> を含むHTMLです。
JavaScript は head 内に、css はインラインで記入しています。

```HTML
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Safari頼むよ</title>
<script>
    window.onload=()=>{
        const rc_area=document.getElementById("right_click_area");
        rc_area.addEventListener('contextmenu',(e)=>{
            e.preventDefault();
            const select_file=document.getElementById("select_file");
            select_file.click();
        });
    }
</script>
</head>
<body>
    <div style="position: fixed; top: 0; left: 0; width: 100%; height:100%; display: flex; flex-direction: column; align-items: center; justify-content: space-around;">
        <input type="file" id="select_file"> 
        <div id="right_click_area" style="height: 100px; width: 200px; background-color: lightskyblue; border: solid 2px; display: flex; flex-direction: column; align-items: center; justify-content: space-around;">右クリックエリア</div>
    </div>
</body>
</html>
```

\<input type="file"\> はブラウザで見ると『ファイル選択』という表示になります。
これを "左クリック" すると "ファイル選択ダイアログ" が開きます。
Edge、FireFox、Chrome、Safariで問題なく機能します。

"右クリック" では "ファイル選択ダイアログ" は開きません。
"右クリック" をするとブラウザのデフォルトのメニューが表示されます。
Edge、FireFox、Chrome、Safari同様です。
"右クリック" で \<input type="file"\> は反応しないということですね。

さて、『右クリックエリア』というものを作っています。
この場所で "右クリック" をすると JavaScript では、
イベントリスナーで contextmenu (右クリック)を検知、
e.preventDefault() でブラウザのデフォルトのメニューを非表示、
\<input type="file"\> エレメントを document.getElementById で select_file に代入、
それを click()する、ということが起こります。

ご承知のとおり、click()は "左クリック" をするメソッドです。
なので、実際にブラウザで、『右クリックエリア』で "右クリック" を行うと、
\<input type="file"\> が "左クリック" されて "ファイル選択ダイアログ" が開きます。
簡単に言えば、"右クリック" → "左クリック" → "ファイル選択ダイアログ" という流れができるのです。

Edge、FireFox、Chromeで問題なく機能しました。

ところが、Safariでは、上記の流れがうまく行きません。
「もしかして、contextmenu からのclick()は "左クリック" にならないのではないか?」
と考えました。
まさか "右クリック" → "右クリック" → \<input type="file"\> 反応せず
となってしまっているのかと。

そこで、HTML に書き足します。

```HTML
<!--input type="file"にonclickを取り付けて、左クリックされたら反応するようにする-->
        <input type="file" id="select_file" onclick="console.log('左クリックされました')"> 
```

\<input type="file"\> が左クリックされたらコンソールに"左クリックされました"と返すようにしました。

そして、Safariで確認です。
『右クリックエリア』で "右クリック" をすると、、、
なんとコンソールに "左クリックされました" と現れました。
contextmenu からのclick()は、"左クリック" としてちゃんと\<input type="file"\>に届いていました。

いやしかし、それならなぜ "ファイル選択ダイアログ" は開かないのか?　
謎です。
最近の Java がすごい!!(switch 式　)

switch 式は Java 14 より正式に追加されたようです!!!
以下のように switch 式により値を返すことができるようになりました。ラクチン！！

```java
int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};
```

また、以前の switch 文では以下のように case のブロックごとに break を書く必要がありましたが、アロー構文 -> により <b>break を省略することができる</b>ようになりました。

```java
switch (day) {
    case MONDAY:
    case TUESDAY:
        int temp = ...
        break;
    case WEDNESDAY:
    case THURSDAY:
        int temp2 = ...
        break;
    default:
        int temp3 = ...
}
```
【Swift】PDFThumbnailViewの実装

SwiftでPDFKitを使ってPDFThumbnailViewを実装する方法。

## 実装コード
SwiftでPDFKitを使ってPDFThumbnailViewを実装する方法。


```swift
import UIKit
import PDFKit

let pdfView = PDFView()//細かい設定は省略します
let pdfThumbnail = PDFThumbnailView()

pdfThumbnail.frame = CGRect(x: 0, y: view.frame.maxY - 100, width: view.frame.width, height: 100)//縦幅100、横幅全部のサイズ
pdfThumbnail.layoutMode = .horizontal//横向き
pdfThumbnail.pdfView = pdfView //PDFViewを紐付け
self.view.addSubview(pdfThumbnail)
```

## 参考

https://developer.apple.com/documentation/pdfkit/pdfthumbnailview

https://qiita.com/misakiagata/items/a105ac1b25024c07231f

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
WordPressのハイパーリンクを設定した

##初めに
PCが余っていたのでUbuntu入れてWordpress入れてハイパーリンクを設定したが404エラーが表示されてしまった。
##解決方法
今回はApacheでの解決方法です

ggってみると``mod_rewrite``を有効化すればよいと書かれていましたがダメでした...
そのほかの``htaccess``の書き換えもダメでした

設定ファイルを見ているとAllowOverrideがNoneのままでした。
なので``/etc/apache2/conf.d``を以下のように変更すればしっかりパーマリンクが機能してくれました。
変更する前

```/etc/apache2/conf.d
 <Directory “/var/www/html”>
      AllowOverride None
 </Directory>
```
した後

```/etc/apache2/conf.d
 <Directory “/var/www/html”>
      AllowOverride All
 </Directory>
```
CronJobで決まった時間のみにJob実行させたいときにはstartingDeadlineSecondsが必要

# まとめ
- CronJobがJobが生成出来ない場合(Masterがdownしていた,suspend=trueなど)にしていた場合、デフォルトではJobが生成出来るようになったときに再実行されてしまう。
- しかし、深夜・早朝バッチなど実行してもよい時間帯が限定されているときにJobが実行されてしまうと困る。
- Jobを実行が出来る時間帯の範囲指定が必要な場合には`startingDeadlineSeconds`を設定して、Jobを生成してもよい時間を限定する必要がある
 
## 実験
- KubernetesのCronJobのサンプルを利用して実験します。
    - 環境はminikube v1.8.2,kubernetes v1.14を利用

- application/job/cronjob.yaml 

```yaml

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure
```

- 一分毎にechoをするCronJobです。

- まずはapply

```
kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        <none>          24s
```

- JobとPodの実行状況を確認する
- Job
```
kubectl get job
NAME               COMPLETIONS   DURATION   AGE
hello-1585028460   1/1           5s         70s
hello-1585028520   1/1           4s         10s
```
- Pod
```
kubectl get po
NAME                     READY   STATUS      RESTARTS   AGE
hello-1585028460-kw8lh   0/1     Completed   0          84s
hello-1585028520-wqqc9   0/1     Completed   0          24s
```
- 無事一分毎に実行されています。

- Jobのsuspendをする。
- CronJobではsuspendというパラメーターをfalseにすることで、CronJobの実行を一時止めることが出来ます。suspendを利用することでCronJobがJobを生成出来ない状態を再現します。
```
kubectl patch cronjob hello -p '{"spec":{"suspend":true}}'
cronjob.batch/hello patched
```

- ここから待ってからsuspendをfalseに戻して、Jobが実行出来る状況に変更します。
- 数分経過

```
kubectl get cronjob
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   True      0        4m              13m
```

- suspend=falseにする。

```
kubectl patch cronjob hello -p '{"spec":{"suspend":false}}'
cronjob.batch/hello patched
```

- jobの実行状況を確認

```
k get job
NAME               COMPLETIONS   DURATION   AGE
hello-1585108380   1/1           9s         70m # suspend=true前に作ったやつ
hello-1585112580   1/1           6s         6s  # suspend=falseにしたらすぐ実行される
```

- `startingDeadlineSeconds: 300` を追記します。

## 参考資料
- https://kubernetes.io/ja/docs/concepts/workloads/controllers/cron-jobs/
[ServiceNow]ナレッジ記事 ファイル添付時の利用方法

ナレッジ記事にファイルを添付する際の利用方法について記載します。
基本的なことではありますが、Docsからだと見つけにくい（？）ですかね。

#Version
- Rome

#記事に添付したファイルを表示するためには・・・
ナレッジ記事執筆時に添付ファイルを追加します。
![ナレッジ１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/ae9f82cc-d856-0e13-63ca-aa070a1f192b.png)

必須項目を入力して、
![ナレッジ2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/51fc6b4a-4c88-1edc-cb3f-45297bfb3c13.png)

公開してみます。![ナレッジ3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/5b76c86f-a227-d2e5-fabc-3f83cf39b09a.png)

↑添付ファイルが表示されません。理由は・・・設定が足りないからです。
[編集]ボタンを押して、[添付ファイルの表示]にチェックを入れて、
![ナレッジ4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/9e1ede3d-d4b3-3f0f-db0a-27201ec7ad48.png)

更新すると、
![ナレッジ5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/e6067c38-f74c-cdca-2143-fc0f0664b210.png)

↑添付ファイルが表示されるようになります。

#添付ファイルへ直接リンク
ナレッジ記事の設定にもう一つチェックボックスがあります。
[添付ファイルへ直接リンク]です。

チェックを入れて、
![ナレッジ6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/54a3a14d-dc5c-e6f0-90d7-894ea57573dd.png)

更新して、
![ナレッジ7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/9ef30c6f-29a6-df85-f477-2bc78400b047.png)

記事のタイトルをクリックすると・・・
![ナレッジ8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636124/57e9f64a-0ccb-9c82-6033-4dea4ad38e24.png)

↑記事へは遷移せず、ファイルに直接アクセス（ファイルがダウンロード）できます。
OutSystems Neo クラウドネイティブアーキテクチャが意味するもの

先日(２０２１年１１月)、OutSystems は マイクロサービスアーキテクチャとクライドネイティブアーキテクチャをキーワードに、Project Neo を発表しました。本記事では、クラウドネイティブアーキテクチャについて、少し解説してみたいと思います。マイクロサービスアーキテクチャについては、別記事で触れる予定です。

私自身は OutSystems インサイダーですが、本記事は OutSystems の公式文書ではなく、私の個人的な意見が含まれています。執筆時点で GA (製品化)はまだ先で、変更になる可能性があります。

#クラウドネイティブアーキテクチャ

##技術スタックの考え方

クラウドネイティブアーキテクチャは、つまるところクラウドサービスを統合するアーキテクチャということになります。考え方を単純化してOutSystems 11 との違いを表現すると下記のような図になります。

![Project Neo Cloud Architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348467/b315d2a4-23b9-6b3d-8a0d-7c869880135d.png)

OutSystems 11 はミドルウェアを統合するアーキテクチャでした。アプリケーションサーバやデータベースは、あくまでソフトウェアとして認識し、それをホストするオペレーティングシステムも含めて動作要件が出されていました。

Project Neo ではそのような思想とは、一線を画しています。動作要件は、原則クラウドサービスであり、オペレーティングシステムやデータベース製品ではありません。自前の物理サーバーにインストールすることは想定されていません（注：ユーザーが契約したクラウドサービスで実行するオプションは、計画の有無も含めて発表されていません）。

##なぜクラウドサービスアーキテクチャか

このアーキテクチャに肯定的な方は、このような課題感を持っている方だと想像しています。

+ アプリケーションは、クラウドサービスを組み合わせて設計している。けれども、それぞれサービス仕様を理解して、比較して契約して、連携設計、運用設計するルーチンは、負担感が強まっている。
+ アプリケーションは、ミドルウェアから設計し、インストールなどをやっている。しかし、クラウドサービスだと当たり前にできることが、自分のシステムではあきらめることが多い。やらないといけないときは、かなり工数を積まざるをえないが、ユーザー部門との交渉は負担感が強い。

OutSystems 自身、２番目のポイントに近い課題感を持っていたと思います。OutSystems ユーザーの "これはできて当たり前だろう" という感覚の事柄に、迅速に対応する基盤を備えるために、採用したと思います。

一方で、クラウドサービスに依存しないスタック構成を取りたいユーザーが存在することは想定されています。OutSystems Next Step 2021 においては、OutSystems 11 は継続されると発表されました。

ただ、クラウドサービスを開発基盤におく潮流は、力強いものがあります。個人的に、日本企業ではクラウド利用は抵抗があり、あまり進まないのではないかと予想していましたが、今では、マイノリティでは全くないと認識を改めています。OutSystems 11 は、オンプレミス / PaaS 利用の選択肢があるため、ご検討中のお客様に考え方を伺う機会が多くありますが、ここ数年の変化は目を見張るものがあります。クラウドネイティブでのシステム構築は、競争力のある構築方法と認知が広がっているいることを日々実感しています。
Ubuntu で Go の最新版を使う

Ubuntu 20.04 にて Go の最新版を使う手順です。
Windows 10 WSL2 上の Ubuntu の場合は、下記手順となります。

## 最新の golang-go リポジトリを追加する

```
sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt install golang-go
```

なお、 golang-go は 最新の Go をデフォルトのGoとしてインストールします。
代わりに golang-1.17 をインストールしたい場合、 `/usr/lib/go-1.17/bin` のバイナリを使用してください。


## パッケージを更新する
パッケージを更新したい場合は、いつもの手順でOKです。

```
sudo apt update
sudo apt upgrade
```

## Hello World

動作確認をしてみます。
hello フォルダを作成し、 go mod init にて hello フォルダに モジュールを作成します。
go.mod ファイルが作成されます。

```
$ mkdir hello
$ cd hello
$ go mod init example/hello
go: creating new go.mod: module example/hello
```

hello.go として保存します。

```go:hello.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
```

実行してみます。

```
$ go run .
Hello, World!
```


## 参考
https://github.com/golang/go/wiki/Ubuntu
遊技機開発ならではのノウハウ　【パチスロ】

# はじめに
以前、[遊技機開発ならではのノウハウ　【パチンコ】](https://qiita.com/nekoharuyuki/items/f9bfe3924c0818058172)をまとめました。多くの人に読んで頂き、とても嬉しく思います。
私自身、数年前の仕事でパチスロのプロジェクトでもエンジニアの経験しましたので、リール制御や液晶演出やサウンドなど様々な開発について、旧来の開発フローや手法ですが、用語の解説も合わせてザックリと紹介します。
*※ 秘密保持契約（NDA）に基づき、すでに公開済みのものや独自にないし別ソースから入手されたものなどの紹介です。*

# パチスロ開発について
パチスロの開発フローについては、以前まとめた[記事](https://qiita.com/nekoharuyuki/items/f9bfe3924c0818058172)とほとんど同じです。
![https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_229633_52e7acd8-cf87-fbe4-121c-cb23656eedd1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229633/48a9f2b1-7ba4-42df-9437-563b0984c129.png)
下記の記事が分かりやすくまとまっています。

[潜入！SANKYO調査隊！～パチスロ開発篇～
皆さんからの要望が多かったパチスロの開発現場に潜入調査！](https://www.sankyo-fever.jp/research/pc/column.php?id=4)

## エンジニアがやる事
* 使用するプログラム言語
(C言語 / C++、アセンブラ)

* 担当する業務
遊技機用の制御プログラム(抽選/役物/ランプ/サウンド/液晶など)

# リール制御
パチスロは一見すると回したリールを自力で止めるゲームのようですが、実際にはパチンコと同じで抽選によって当たるものが決められています。レバーを叩いた時点で、当たり、小役、ハズレなどの各種抽選が行われており、その抽選結果に応じた位置でリールが止まります。パチンコと違う部分は役によってはしっかり狙わないと揃わず、揃わなければ出玉は得られません。

リール制御は、しっかりと、法律で定められており、ボタンを押してから、0.19秒以内に止まらなければなりません。
また、法律上は、最大5コマまで、リールがスベる事ができます。
※　停止の時間は、メーカーによって、バラバラで横並びで決まっているわけではありません。

実装には以下の方式があります。

- コントロール方式
条件装置を最大限すべらせて揃えようとする方式

- テーブル方式
最初に止めたリールの位置により第２リール、第３リールの停止する位置をあらかじめ決めておく方式

# 液晶演出
遊技機映像の需要拡大や液晶パネル品質向上も伴ない、より一層、高品質な表現が求められるようになってきています。開発会社では各社で、映像制作ツールの導入や検証研究を行い、制作技術向上に取り組んでいます。中でもAfter Effectsのスキル習得は注力されており、デザイナーだけでなくエンジニアもAEに接することが多くありました。

ベースとなる仕組みはパチンコ開発でまとめた通りですが、パチンコ開発との違いとして、開発会社によってはリアルタイムCGで開発している事もあります。
https://qiita.com/nekoharuyuki/items/f9bfe3924c0818058172

> リアルタイムCGとは
即時にレンダリングされるCGのこと。ゲーム、VR、イベント、シミュレータなどで用いられています。これに対して、事前にレンダリングされているCGのことをプリレンダーと呼びます。リアルタイムCGの制作においては、リアルタイム性を最優先とし、プリレンダーよりも表現精度を落とす場合が多くあります。そのため制作者には、限られたデータ容量のなかで、最大限豊かな表現をするための様々な工夫が要求されます。

# サウンド
エンジニアはパチンコやパチスロ台の映像に対するサウンドの制御を行います。効果音やBGMなどの実装などが中心になりますが、サウンドと合わせて役物の制御実装も行います。

# まとめ
以前、まとめた [遊技機開発ならではのノウハウ　【パチンコ】](https://qiita.com/nekoharuyuki/items/f9bfe3924c0818058172) よりもスッキリとした内容になっていますが、参考にして頂けたら嬉しいです。
【Unity】オブジェクトの座標値を取得してテキストファイルに書き込む

Unityのシーン実行時にこのスクリプトをアタッチしたオブジェクトの座標(x,y,z)を取得し，テキストファイルに書き込むコードの例です．

```C#:RecordPos.cs
using UnityEngine;
using System.Collections;
using System.IO; //ファイルに書き込むために必要
using System; //Convertを使うために必要

public class RecordPos : MonoBehaviour
{
	void Start(){}

	void Update()
    {
		//transformを取得
		Transform myTransform = this.transform;

		//ワールド座標を基準にスクリプトをアタッチしたオブジェクトの座標を取得
		Vector3 worldPos = myTransform.position;
		float x = worldPos.x;
		float y = worldPos.y;
		float z = worldPos.z;

		//ファイルパスを定義
		string filePath = Application.dataPath + @"\Scripts\File\ObjectPos.txt";

		//ファイルの末尾に値を追加（Convertでfloat型の座標値をString型に変換している）
		File.AppendAllText(filePath, Convert.ToString(x)+","+ Convert.ToString(y)+","+ Convert.ToString(z) + "\n");
	}
}
```

出力先のテキストファイルをMATLAB等で読み込めば良い感じのグラフが描けそう．
上の例のようにUpdate関数内で書き込みするとサンプル数が多すぎるので改善の余地あり．

【追記】
1秒ごとにテキストに記入するように変更を加えたコードの例．Prefab生成タイミングも記述するようにした．

```C#:RecordPos.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO; //ファイルに書き込むために必要
using System; //Convertを使うために必要

public class RecordPos : MonoBehaviour
{
	private float elapsedTime;
	[SerializeField]
	private float timeWriteTxt = 1f; //WriteTxtを実行する周期

	void Start()
	{
		//ファイルパスを定義
		string filePath = Application.dataPath + @"\ObjectPos.txt";
		//ファイルの末尾にPrefabが新しく生成されたことを示すメッセージを追加
		File.AppendAllText(filePath, "Prefabが新しく生成されました！\n");
	}


	void Update()
	{
        //時間を数えてtimeWriteTxtの時間になったらWriteTxt関数を実行
		elapsedTime += Time.deltaTime;
		if (elapsedTime >= timeWriteTxt)
		{
			elapsedTime = 0f; //時間リセット
			WriteTxt();
		}
	}

	void WriteTxt()
    {
		//transformを取得
		Transform myTransform = this.transform;

		//ワールド座標を基準にスクリプトをアタッチしたオブジェクトの座標を取得
		Vector3 worldPos = myTransform.position;
		float x = worldPos.x;
		float y = worldPos.y;
		float z = worldPos.z;

		//ファイルパスを定義
		string filePath = Application.dataPath + @"\ObjectPos.txt";

		//ファイルの末尾に値を追加（Convertでfloat型の座標値をString型に変換している）
		File.AppendAllText(filePath, Convert.ToString(x)+","+ Convert.ToString(y)+","+ Convert.ToString(z) + "\n");
	}
}
```

___

【参考サイト】
[C#でファイルの読み込みと書き込み](https://gametukurikata.com/csharp/readwritefile)
[Unityで毎フレーム実行している処理の回数を減らす](https://gametukurikata.com/basic/reducethenumberofprocesses)
Firebase Storageにてmetadataがうまく適応されない場合の対応

NG

```typescript
const storage = getStorage();
const storageRef = ref(storage, 'images/mountains.jpg');

const metadata = {
  contentType: 'image/jpeg',
  'location': 'Yosemite, CA, USA',
  'activity': 'Hiking'
};

uploadBytes(storageRef, image as Blob, metadata);
```

OK

```typescript
const storage = getStorage();
const storageRef = ref(storage, 'images/mountains.jpg');

const metadata = {
  contentType: 'image/jpeg',
  customMetadata: {
    'location': 'Yosemite, CA, USA',
    'activity': 'Hiking'
  }
};

uploadBytes(storageRef, image as Blob, metadata);
```

公式ドキュメント:
https://firebase.google.com/docs/storage/web/file-metadata?hl=ja#custom_metadata

検証のために利用したベースコードメモ：
https://codesandbox.io/s/thyb0?file=/pages/index.js

上記コードをNext.js用に書き換えた検証コード:

```typescript
import { useState } from 'react'
import type { ChangeEvent, MouseEvent } from 'react'
import type { NextPage } from 'next'
import { getStorage, ref, uploadBytes } from "firebase/storage"

const Privacy: NextPage = () => {
  const [image, setImage] = useState<File>();
  const [createObjectURL, setCreateObjectURL] = useState<string>();

  const uploadToClient = (event: ChangeEvent<HTMLInputElement>) => {
    if (event.target.files && event.target.files[0]) {
      const I = event.target.files[0];

      setImage(i);
      setCreateObjectURL(URL.createObjectURL(i));
    }
  };

  const uploadToServer = async (event: MouseEvent<HTMLButtonElement>) => {
    const body = new FormData();
    
    const storage = getStorage();
    const storageRef = ref(storage, 'images/mountains.jpg');

    const metadata = {
      contentType: 'image/jpeg',
      customMetadata: {
        'location': 'Yosemite, CA, USA',
        'activity': 'Hiking'
      }
    };

    uploadBytes(storageRef, image as Blob, metadata);
  };

  return (
    <div>
      <div>
        <img src={createObjectURL!} />
        <h4>Select Image</h4>
        <input type="file" name="myImage" onChange={uploadToClient} />
        <button
          className="btn btn-primary"
          type="submit"
          onClick={uploadToServer}
        >
          Send to server
        </button>
      </div>
    </div>
  );
}

export default Privacy
```

---

＼プログラミング相談Slackコミュニティやってます／

月額9,800円のサブスクで質問し放題です
プログラミング学習や個人開発などに利用ください

https://codeqa.me/
Sympyによるシンボリック変数での微分積分


#sympyの導入


```php
import sympy as sym
```
sympyをこれで導入します。
うまくいかない場合は、


```php
!pip install sympy
import sympy as sym
```


としてみましょう。
#シンボリック変数の導入
Scipyのモジュールでは、シンボリック変数というものを用いて計算を行います。なので、まず、シンボリック変数を導入します。
例えば、x、y、ｚの三変数を用いたいときは、


```php
x , y , z = sym.symbols('x y z')
```

という風にコードを書きます。
これをやらないとエラーが起こるので注意しましょう。

特殊な数字を扱うこともできます。

```php
ensyuritu = sym.S.Pi
sizentaisu = sym.S.Exp1
kyosu = sym.S.ImaginaryUnit
mugen = sym.oo
```

#微分
sympyを用いれば、数式の微分をすることができます。
今回は、x<sup>2</sup>の微分をしてみましょう。
次のコードを入れて実行してみましょう。


```php
sym.diff(x**2,x)
```


結果は、2x　と出力されます。

複数の変数で微分することもできます。今度はx<sup>5</sup>y<sup>2</sup>z<sup>4</sup>をx,y,zでそれぞれ一回ずつ微分してみよう。


```php
sym.diff(x**5*Y**2*z**4, x, y, z)
```


結果は、40x<sup>4</sup>yz<sup>3</sup>　と出力されます。


同じ変数で複数回微分することもできます。
x<sup>4</sup>を4回微分してみましょう。

```php
sym.diff(x**4, x, 4)
```

24と出力されるはずです。


これらを組み合わせることで様々な微分を計算をすることができます。ぜひ、いろんな数式を入れてみてください。



#積分
sympyを用いれば、不定積分をすることができます。
7y/xを積分してみましょう。

```php
sym.integrate(7y/x,x)
```

結果は、7ylog(x)　と出力されます。


定積分をすることもできます。
1/x<sup>2</sup>を1から無限大まで定積分してみましょう。

```php
sym.integrate(1/x**2, (x, 1, sym.oo))
```
結果は、１と出力されます。

これで広義積分も求められます。

積分は答えが求まるとは限りません。
次の式を計算してみましょう。

```math
\int\frac{x}{sinx}dx
```

```php
sym.integrate(x/sym.sin(x))
```

そのまま式の状態で出力されるはずです。

#最後に
sympyを使っていろんな計算をしてみよう。
***
補足：プログラムはgoogle colaboratoryで実行しました。
朝起きたらPCがWin11になっていたので、WSLgを試してみた

　こんにちは。この記事は株式会社[Works Human Intelligence Advent Calendar 2021](https://qiita.com/advent-calendar/2021/advent-works-hi) 23日目の記事です。

　昨日の記事は@h4ya5eさんの[弊社名を文法解析してみた(できるとは言ってない)](https://qiita.com/h4ya5e/items/5e0da18718d6aa45165c)です。
　よろしければカレンダーの他の記事も見ていってください。

# 朝起きたらPCがWindows 11になっていた

　WSLとは、Windows Subsystem for Linuxの略で、Windows上で仮想マシンのオーバーヘッドなしにLinuxを直接実行できる機能です。[^1]
　そんなWSLがWindows 11からはGUIをサポートするようになりました。

[^1]: https://docs.microsoft.com/ja-jp/windows/wsl/about

　正確にはWindows 10でもWindows Insider Programに参加してDevチャネルを選択すれば使うことができたのですが、私はWindows上にXServerを立ててGUIアプリを使うことができていた[^2]のでOSをアップデートしてまで利用するほではないと判断していました。

[^2]: https://www.eisbahn.jp/yoichiro/2021/06/wslg.html

　しかしある朝、気がついたらタスクアイコンが中央に寄っていました。
　ウィンドウから角が取れ、スタートメニューアイコンの水色タイルは正面を向き、黒系統の落ち着いていたデザインは透明感を目指した方向に統一されていました。

　まだそのつもりはなかったのですが、期せずして私のPCはWindows 11にアップデートされてしまっていたのです。

　スタートメニューとタスクバーのピン止めが全て吹き飛んでいるのを見て正直やっちまったと思いましたが、普段からWSL2をよく使っていた私はさっそくWSLgを試してみることにしました。

　この記事では、私の従来の手法(WindowsにVcXsrvをインストールし、そこにWSL2から接続する)の問題点がWSLgによって解決されることや、WSLgを使ってみて得た感触などを書き連ねていきたいと思います。

## 従来の手法の問題点

　私が従来WSL上でGUIアプリを利用する際に使っていた手法は、ホストマシン上でXServer (VcXsrv)を起動し、そこにWSLから接続するというものでした。恐らく他の人でも同じ手法を使っていると思います。

　非常に単純で良い手法なのですが、以下の3つの大きな問題がありました。

- VcXsrvを起動せずにWSL2上でテキストエディタを開くと、起動に滅茶苦茶時間がかかる
    - クリップボードアクセスのために`$DISPLAY`を見に行ってタイムアウトしていたのが原因でした。
    - https://github.com/microsoft/WSL/issues/5223#issuecomment-652309457
- `DISPLAY`環境変数を設定するのがやや大変（WSL2限定）
    - WSL2からネットワーク空間がホストと共有されなくなり、ホストのIPアドレスを指定しないとホストマシンに接続できなくなりました。その結果`DISPLAY`の設定がやや大変になりました。やり方は色々あると思いますが、私は下のように`DISPLAY`を設定していました。

    ```bash
    LOCAL_IP_HOST=$(ipconfig.exe | grep IPv4 | grep -o -E '192\.168\.1\.[0-9]{1,3}')
    export DISPLAY=${LOCAL_IP_HOST}:0.0
    ```

- ホストマシンがスリープすると、GUIアプリが閉じていることがある（WSL2限定）
    - TCPセッションが切断されてしまってGUIを維持できないことが原因でした。
    - https://github.com/microsoft/WSL/issues/4992

## WSLgでは上で挙げた問題点が全て解決された

　WSLgにしてからは、今のところ上記の問題点は全て解決されたように見えます。

　また今まではVcXsrvを起動しないとクリップボードをホストと共有できませんでしたが、WSLgにしたらクリップボードが初めからホストとシームレスになり、地味に嬉しいです。

## 困った点

　WSLgに切り替えることで今まで困っていたものが解決されたのはいいのですが、新たにWSLgになって発生した問題がいくつかあったので、それら問題点とその解決方法を紹介したいと思います。

### WSLg導入以後もGUIアプリが開かない

　Microsoft公式のガイド[^3]では、`wsl --update`をしてWSLを再起動するだけでWSLgを有効化できるとのことでしたが、私の手元ではアップデート以後も`Error: Can't open display: 0`となってGUIアプリを開くことができませんでした。

[^3]: https://github.com/microsoft/wslg#install-instructions-existing-wsl-install

　下の記事を参考に、`/tmp/.X11-unix`の向き先を変えてやることで解決できました。

https://qiita.com/blancshio/items/f2d9b6b885a0ee3ad912

### GUIへの入力でキーボードが日本語配列で認識されてしまう

　私が普段使っているキーボードはUS配列なのですが、WSLgで開いたGUIには日本語配列で認識されてしまいました。
　以下を`.profile`に追記して`source`で取り込むことで解決できました。

```bash
setxkbmap -layout us
```

### ディスプレイの電源を落とすとGUIが消えてしまう

　WSLgのGUIを配置しているディスプレイの電源を落とすとGUIが閉じてしまう現象に遭遇しています。
　issueにコメントを付けておいたので、今後改善されるといいなと思っています。

## おわりに

　ウィンドウの角を引き換えに、WSL2での開発がますます便利になりました。
　今のところ、やはりWSLg目当てで無理してWindows 11にアップデートするほどのものではないと感じていますが、Windows 11へのアップデートを行った際にはぜひWSLgをお試しください。
Android UITest実行前にChromeのキャッシュを削除したい

## 結論

```kotlin
UiDevice.getInstance(getInstrumentation()).executeShellCommand("pm clear com.android.chrome")
```

こいつをsetUp時に呼ぶ

## 背景

https://developer.android.com/training/testing/ui-automator?hl=ja

UI Automatorを利用したAndroidのUITest実行時に**SNSログインなどのアプリ外の動作を検証するテストを作りたかった**

もちろん各SNS連携後のブラウザでの動作はUI Automatorを使って自動化することができるのですが、
FacebookやYahoo!ログインでは**ブラウザのキャッシュに残っている状況によってパスワード入力がスキップされたりメールアドレス入力が既に入力されている状態になったりと実行時によって動作が変わってしまう**

よって先にすべてのChromeブラウザのキャッシュを毎度クリアしてテスト実行しようとした

## 解説

```kotlin
UiDevice.getInstance(getInstrumentation())
```

UI Automatorを利用してアプリ外の動作を行います

```kotlin
.executeShellCommand("pm clear com.android.chrome")
```

adb shell commandを実行します。
これでchromeアプリのストレージを削除します

## 補足
### chrome以外のアプリのストレージを削除したい

```shell
$ adb shell pm list packages
```

アプリパッケージの一覧が表示されますのでそれを引数に指定してください

## 参考
https://stackoverflow.com/questions/61480388/clear-delete-cache-before-evrey-test-case-using-espresso-in-android-studio
WindowsでClionのコンソールが文字化けする

ClionのCmakeやWSL toolchainのmake等の出力が文字化けする

## 環境

- Windows 11
- Clion 2021.3
- WSL (Ubuntu 20.04)

## 対処

Help -> Edit Custom VM Options...を開く
以下を追記

``` xxx.xxxx.xxx.vmoptions
-Dconsole.encoding=UTF-8
-Dfile.encoding=UTF-8
```
QAエンジニア目線のAPIテストでの気付き

#**記事の概要**
日頃画面検証の業務が多いのですが今回API新規開発で組み込み前の振る舞い動作検証の依頼を頂いた。
その中で気づいた、こうすればよかった、、あーすればよかったを記載していきたいと思います！

##**検証で利用したツール**
[Postman](https://www.postman.com/)
※めちゃめちゃお世話になっています・・・！！

デスクトップ版のアプリを利用しており、
TeamWorkspaceを使えば同時並行で作業(Collectionやリクエストの追加等)が可能です！
ペアを組んで作業しているので効率的に作業を進められました！
※ちなみに参考にさせて頂いた記事
https://qiita.com/Molly95554907/items/e367e83129ea1173c317
https://blog.linkbal.co.jp/4447/

##**検証ボリューム**
今回の検証が対象のAPIにデータセットの情報を送り、
統計モデルで計算された値が期待値通りに増減するか？という観点でした。
※画面も見えないので初めはポカン状態。

開発者やPOの方々と期待値の仮説を立てて、実験的に検証し答えを出していく。という検証方針です。

ユーザーストーリーマッピングに沿った検証パターンとデータセットの値をmin、max、中央値のパターンのかけ合わせやシステムで再現したい仕様の動きもコミコミでテスト計画～設計を行ったのでスクリプトを作成し、ある程度データセット作成の自動化も行いましたが手動検証時に必要なリクエストが**💀3000件以上💀**となりました。
※実はまだ絶賛対応中です😹
![test123.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243487/0cf34604-e54b-5704-0052-4dd9e95e26fc.jpeg)


##**工夫した点**
・**TeamWorkspaceをうまく利用した。**
　初めはメンバー各々ローカルでリクエストを作成していましたが、
　TeamWorkspaceでスクリプトを同時作成し、他の人が作成したリクエストは積極的に流用した。

・**FindandReplaceで置換作業などを行い、リクエスト作成を簡略化した。**
　これがなかったら本当に詰んでました。大分助かりました。
　但し注意しないといけない点としては、Collection単位での置換となり、
　Collection配下の特定のリクエストだけ置換したいという事であれば一度別のCollectionに移して置換する等工夫が必要。
![honnbanpost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243487/5368c435-80b3-66f8-9e33-3887f3a3f7e5.png)


##**こうすればよかった・・・・**
リクエストをAPIの種類毎で管理していたのですが、これが失敗。

FindandReplaceの活用シーンで感じた点で、
シナリオベースで分けた方が一括でパラメータやtoken情報等も更新出来るので
リクエストを管理する際にもう少し考えておけばよかったなぁと思いました。

ユーザーストーリマッピングの観点が含まれている際はテストシナリオベースで管理すべきだと気づいた。

##**最後に**
つらい検証ですが、答えのない検証をプロダクトチーム一丸となって挑戦出来たのは良い経験になりました。

またこれまで画面上での検証が多かったのですが、データ観点で検証出来た事も新たな取り組みだったので今後QAチーム内にノウハウを落とし込んでいきたいと思います。

最後まで読んでくれてありがとう御座いました！