OmniAICreator/Qiita-1.07M huggingface dataset:
ローカル5Gでビジネスはどう変わる？

# はじめに
IT×ビジネスという視点で週1本記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)

# ローカル5Gとは
　ローカル5Gとは、地域・産業のニーズに応じて地域の企業や自治体等が個別に利用できる5Gネットワークのことです。
　総務省は2019年12月、様々な主体が5Gを自ら構築できるように、ローカル5G制度を開始しました。ローカル5G用の周波数が確保され、免許申請することで、ローカル5Gを構築できます。
　ほとんどの企業・自治体は、自らの建物や敷地内にプライベートネットワークを構築していますが、従来の有線LANやWi-Fiなどに加えて、5Gも新たに利用可能になりました。

※通信事業者が全国的に通信サービスを提供している、所謂普通の5Gネットワークのことを「パブリック5G」と言います。

# ローカル5Gでビジネスはどう変わる？
なぜ「パブリック5G」ではなく「ローカル5G」をわざわざ構築する必要があるのでしょうか。ローカル5Gを構築する主なメリットは以下の通りです。
1. プライベート空間で構築できるためデータの __秘匿性__ が高い
2.  災害時等にパブリック5Gに障害が生じても、ローカル5Gなら自身のネットワークに被害がなければ影響を受けない
3. 柔軟性が高い。 
例えば、パブリック5Gは基本的に下り(受信)重視の設計になっていますが、上り(送信)重視の設定にすることができたり、重要な帯域だけ広くしたりできます。

上記のようなメリットが実際のビジネスではどう活かせるでしょうか？ローカル5Gを使用した具体例からビジネスがどう変わるか見ていきましょう。

### ■スマートファクトリー化
　工場のIoT化により様々なセンサーやロボット、データ収集装置が有線ネットワークで繋がっている昨今、こうしたネットワークを無線化するのにローカル5Gは適しています。
　機械制御や生産管理には低遅延・高信頼性が何より求められます。IoT用途では、大量のデータを収集するための高速・大容量通信、膨大な数のIoTデバイス／センサーを収容できる多数同時接続という5Gの特性が活かせるからです。


# Wi-Fi6ではダメなのか？
ローカル5GはWi-Fi6と比較して __コストが高い__ だけでなく __免許申請手続き__ 等も必要であり余分な労力を要します。しかし、通信品質の安定度、セキュリティ強度、低遅延においてはローカル5Gが上回ります。こういった点を考慮し、ローカル5Gが必要なのか判断する必要があります。


# 終わりに
　ローカル5Gはまだまだ黎明期にあるため、導入コストが高額になります。しかし、今後は機能の絞り込みや需要の増加により価格が下がってくるでしょう。自身が解決したい目的に対してローカル5Gが必要なのか見極めが重要になってきます。

最後までお付き合いくださりありがとうございました。
Storybookのデフォルトのpaddingをなくす

# はじめに
Storybook初心者である自分ための備忘録。

```json:package.json
  ...
  "devDependencies": {
    ...
    "@storybook/react": "6.2.1",
    "@storybook/addon-a11y": "6.4.22",
    "@storybook/addon-essentials": "6.4.22",
    "@storybook/builder-webpack5": "6.4.22",
    "@storybook/manager-webpack5": "6.4.22",
    ...
  }
  ...
```

# 問題
Storybookでは、デフォルトでpaddingが1rem適用されてしまう。
![sb1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/0ab83049-d9cd-834d-bec4-5d2e28075627.png)

marginは0なのだが、paddingは上下左右に1remと指定されている。
デフォルトのpaddingが気になる人も多いはず...。
![sb2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1504894/c97d117f-ad4b-6ca6-d23d-99ed499a7c61.png)

# 解決
`.storybook/preview.js`に下記を記述することで、このpaddingをなくすことが可能。

```js:preview.js
export const parameters = { layout: 'fullscreen' };
```

Storybookの公式ドキュメントには、`layout`パラメータは3種類あると説明されている。
> layout accepts these options:
centered: center the component horizontally and vertically in the Canvas
fullscreen: allow the component to expand to the full width and height of the Canvas
padded: (default) Add extra padding around the component

`layout: 'padded'`がデフォルトで、コンポーネントの周りに1remのpaddingを付与する。
`layout: 'centered'`はコンポーネントを中央に配置する。
`layout: 'fullscreen'`が今回paddingをなくすために指定するもので、コンポーネントをキャンバスの幅と高さいっぱいに配置できるようにする。

コンポーネント単位や、さらに細かくストーリー単位でも`layout`パラメータを指定することが可能。

参考文献は以下のissue。

https://github.com/storybookjs/storybook/issues/12109
yumでDBが壊れた場合はrpm --rebuilddbでDBを再作成する。


EC2を何度か再起動した時にネットワークは出られているがyumができないイベントに遭遇したので備忘

## 発生事象

```
# yum install
error: rpmdb: BDB0113 Thread/process 1162/281472916105904 failed: BDB1507 Thread died in Berkeley DB library
error: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery
error: cannot open Packages index using db5 -  (-30973)
error: cannot open Packages database in /var/lib/rpm
CRITICAL:yum.main:
```

こんな感じでCRITICALがでてそれ以降コマンドが動かなくなる

## 対処方法

組み込みのBerkeley DBの故障が原因なので再作成をする。


```
# mkdir /var/lib/rpm/backup
# cp -a /var/lib/rpm/__db* /var/lib/rpm/backup/
```

DB再作成ができなくなると困るので切り戻し用のバックアップを準備


```
# rm -f /var/lib/rpm/__db.[0-9][0-9]*
```

壊れているDB情報を削除


```
# rpm --quiet -qa
# rpm --rebuilddb
# yum clean all
```

DBを再作成してYumの情報も綺麗にする。


参考URL:
大体これの受け売り
https://hirosetakahito.hatenablog.com/entry/2018/12/25/122316

海外ニキのメモ
https://dba010.com/2021/05/20/rpm-qa-gets-thread-died-in-berkeley-db-library/#:~:text=Reason%3A,the%20RPM%20database%20is%20corrupted.
GitHubのアクセストークンの作成

・GitHubのアクセストークンの作成

①
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596732/4528225e-8ab3-06cc-4fe4-13762d58800e.png)

②
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596732/78a03920-db9f-50ca-98b1-1194416e65bc.png)

③
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596732/db75f735-07ba-13bd-2adb-fdaff8124944.png)

④
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596732/4c5c33f6-709d-e098-3586-7d0c5ac89f1e.png)

⑤
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2596732/13cef1d5-52ff-8a00-faf9-249ab275fe2d.png)
Azure App Service の Authentication/Authorization(EasyAuth)で認証しないURLを設定する


前回の投稿では AuthN/AuthZ(EasyAuth) をWebアプリのすべてのURLに対して設定する場合に OpenIdConnect の Claim 情報を  ClaimPrincipal に設定する方法をご紹介しました。

https://qiita.com/takashiuesaka/items/0c1a008c7c23625f5932

実際のWebアプリでは認証していない匿名ユーザーと呼ばれるユーザーがアクセスできるページと、認証済みユーザーだけがアクセスできるページがあります。少し前まではこれを AuthN/AuthZ(EasyAuth)で実現するために authorization.json というファイルを用意して URL ごとに認証する/しないを記載し、それを site/wwwroot 直下に配置する、という方法がありました。

しかし、この authorization.json を使う方法の紹介は MS 公式ページからは消えてしまいました。またこの方法は Azure App Service on Linux では動作しませんでした。

さらにいうと、この authorization.json を使うと私が前回紹介した方法では ClaimPrincipal に値がセットされません。

これを全てまるっと解決する方法がありますのでご紹介します。この方法であれば、 Azure App Service on Linux でも綺麗に動作しますし ClaimPrincipal に値もセットされます。

# どこに何を設定するのか

設定そのものは拍子抜けするぐらい簡単です。ここでご紹介する設定方法は次のページの方法をもっと簡単にしたものです。

https://docs.microsoft.com/ja-jp/azure/app-service/configure-authentication-file-based

ページの中を見ていただくと、構成ファイル リファレンス の箇所にずらっと json のスキーマが記載されているのがわかると思います。次の箇所に注目します。

```json:authsettingsV2
    "globalValidation": {
        "unauthenticatedClientAction": "RedirectToLoginPage|AllowAnonymous|RejectWith401|RejectWith404",
        "redirectToProvider": "<default provider alias>",
        "excludedPaths": [
            "/path1",
            "/path2",
            "/path3/subpath/*"
        ]
```

exludedPaths 、という箇所あります。もうおわかりだと思います。この例のように認証が不要な URL をここに登録すればいいだけなんです。

# Azure Resource Explorer を開く

お手軽な方法は Azure Resource Explorer での設定です。

https://resources.azure.com

開いたらログインして、該当の WebApps へ辿っていきましょう。階層が深いのですが、次のように辿っていきます。目的地は authSettingsV2 という場所です。

```
- subscriptions
  - <your subscription>
    - resourceGroups
      - <your resourceGroup>
        - providers
          - Microsoft.web
            - sites
              - <your WebApps>
                - config
                  - authSettingsV2
```

次のように認証が不要な URL を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222127/39fa2381-a69e-7dd5-850d-c09a41d99bf4.png)

念のため文字でも書いておきます。

```json
    "globalValidation": {
      "requireAuthentication": true,
      "unauthenticatedClientAction": "RedirectToLoginPage",
      "redirectToProvider": "azureactivedirectory",
      "excludedPaths": [
        "/"
      ],
      "id": "(String)",
      "name": "(String)",
      "kind": "(String)",
      "type": "(String)",
      "properties": {
        "requireAuthentication": "(Boolean)",
        "unauthenticatedClientAction": "(String)",
        "redirectToProvider": "(String)",
        "excludedPaths": [
          {}
        ]
      }
    }
```

"excludedPaths": [] という要素を手で追加してください。[] の中にはカンマ区切りで複数の URL を指定可能です。 URL はダブルクォーテーションで囲みます。

編集が終わったら右上の モードを ReadOnly から Read/Write に切り替えて、 PUT をクリックすれば更新されます。
この例では "/" を認証から除外しています。たったこれだけです。

設定が終わったら念のため Webアプリを再起動することをお勧めします。

# 最後に

最後に注意ですが、 authorization.json を使っていた時は匿名ユーザーでのアクセスを許可するように認証の設定変更が必要だったと思いますが、このやり方ではその設定は不要です。むしろしてはいけません。
【FileMaker】カスタムダイアログの入力が確定されない？ここをチェックだ！

FileMakerの[カスタムダイアログ](https://help.claris.com/ja/pro-help/content/show-custom-dialog.html)は、便利なことに入力値をダイアログの中で入力することができます。
いや、そりゃ他の言語でもできるでしょ、
という声もあると思いますが、ちょっとした入力をさせるだけなのに小さなウインドウをわざわざ作って実装しなくても済むので比率高めに（何比率？）結構便利に使っています。

例えばこんな。
![スクリーンショット 2022-04-27 21.46.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/def46b4d-40a5-83b6-ccc2-2a2f72903bb8.png)

便利なカスタムダイアログですが、せっかく入力フィールドを設定してダイアログを出しても、入力後のボタンの設定によってはその入力内容が反映されません。
あれ、なんで？
とスクリプトデバッガを走らせる前に、「[カスタムダイアログを表示](https://help.claris.com/ja/pro-help/content/show-custom-dialog.html)」ステップを確認してみましょう。

# 現象
こんなこと、ないですか？
![スクリーンショット 2022-04-27 21.47.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/790404bd-12e0-b7bb-f1d7-370eb3d4a745.png)
入力フィールドに入力して、上部画面の場合、「上書き」をクリック。

確認のために表示したカスタムダイアログでは、入力されたID(val1)とPWD(val2)に何も入っていない。。。
![スクリーンショット 2022-04-27 21.47.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/17eb6c8a-96ff-ddd8-16a9-aa9a8c575a27.png)

猛者の方々は、当然お気づきですよね。

# スクリプトを確認
では、実装しているスクリプトを確認してみましょう。
![スクリーンショット 2022-04-27 21.45.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/15a5b0aa-edff-ac7b-16ef-04e8a63da2df.png)
なんの変哲もない、カスタムダイアログの実装ですが、3行目のカスタムダイアログの設定を見てみます。
入力フィールドの実装は、入力フィールドの変数もラベルも設定されていて、問題なさそうです。
![スクリーンショット 2022-04-27 21.45.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/f1d3a3e3-5d23-f4e5-dd54-2f4800ffe094.png)

一般設定はどうでしょう。
ボタン２の「上書き」の設定で、「データを確定」にチェックが入っていません。
![スクリーンショット 2022-04-27 21.45.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/48e00fa1-b093-fed0-c61c-f1db075aa226.png)

# 「カスタムダイアログを表示」の「データを確定」とは
[Claris FileMaker Pro 19 ヘルプの「カスタムダイアログを表示」](https://help.claris.com/ja/pro-help/content/show-custom-dialog.html)より、引用してみます。

>・[データを確定] チェックボックスを使用すると、各ボタンの動作に基づいてダイアログボックスからターゲットフィールドまたは変数に入力データを渡すことができます。フィールドがターゲットになったときにレイアウト上にアクティブなフィールドがない場合はデータが確定されます。フィールドがアクティブな場合は、レコードが確定したときにデータも確定します。ボタンのチェックボックスが無効な状態でユーザが入力フィールドにデータを入力した場合、ユーザがボタンをクリックしてもレコードに対してデータが確定されないか、またはデータが変数に格納されません。

つまり、入力したデータの確定するかどうかを設定せよ、ということですね。

# 「カスタムダイアログを表示」の修正
「データを確定」をボタンの設定に追加しないと、せっかく入力フィールドで設定した内容が変数に確定されないということなので、入力フィールドの入力値をスクリプトで確定したい場合、もしくはテーブルのフィールドに設定したい場合は、このチェックを忘れないようにしましょう。
![スクリーンショット 2022-04-27 21.47.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/0d5d5d5c-0f48-f0a6-4c3f-33b6d0a3fabd.png)

:::note info
入力フィールドの設定がなく、単純に3択のつもりでボタンを設定する場合は、「データの確定」はなくてもOKです。
:::

# 再度テスト
では、修正したスクリプトを実行して、「上書き」ボタンをテストしてみましょう。
![スクリーンショット 2022-04-27 21.47.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/32821605-cb81-d9a3-7dd1-8d2332024ef1.png)
入力したら、「上書き」ボタンをクリックします。

変数に入力値が確定されましたね！
![スクリーンショット 2022-04-27 21.48.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/289ca2f7-03a7-1d8b-3b36-2e0b41c6414d.png)

# ポイント
そんなに大層なことではないのですが、FileMakerのスクリプトは簡単に書ける反面、設定内容がGUI（懐かしい言い回し。。。）なので、一見すると正しく見える実装も意図しない設定の漏れがあるかもしれません。
なんか思った動きをしないな、と思ったら、ざっとスクリプトを確認するだけでなく、スクリプトステップの設定ボタン（歯車マーク）を表示して内容も確認してみてくださいね。
pyinstallerで作ったexeをタイムスケジュールで実行する際のエラーの対処方法

# 概要
タスクスケジューラでpyinstallerでexe化した実行ファイルを実行させようとすると。"Failed to execute script"と出る問題

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/5678583d-c349-9ca0-70ea-493243aa2e17.png)

試したこと
1. exeを指定ー＞上記のエラー
1. cmd経由の実行ー＞不可能

# 解決法
バッチファイルを作り、バッチファイルを実行させる

exeのあるファイル内に次のようなバッシュファイルを入れます

```bash:test.bat
@echo off
cd "C:\Users\name\Documents\Python Scripts\Oyasumi\dist"
start test1.exe

```
cdはexeのある作業フォルダへの移動
startで実行です
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/f86b6606-869f-037a-61a1-94d00f26624d.png)
プログラムスクリプトにはバッシュファイルを指定します。

私の場合はこれで解決しました。
GNOME Connectionsでパソコンを操作する【リモートデスクトップ】

# GNOME Connectionsとは
GNOME Connectionsとは、GNOMEのリモートデスクトップクライアントです。
RemminaよりシンプルなUIで高性能です。

# GNOME Connectionsをインストール

```bash
sudo apt install -y gnome-connections
```

# GNOME Connectionsを起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/f6568d1a-6068-2672-08d9-4797fb8c58f0.png)
![Screenshot from 2022-04-27 21-59-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/9f049be5-ac95-b10c-539b-3c15d18f0f24.png)

# ＋をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/551f40a9-c97a-28e7-7f15-7d0c5c2c5294.png)


# ネットワーク識別子を入力し、接続をクリック
![Screenshot from 2022-04-27 22-00-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/647b03a2-e172-f56a-6697-5e4b5fadbaa6.png)


# ユーザー名とパスワードを入力し、サインインをクリック
![Screenshot from 2022-04-27 22-01-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/cace639e-a9f5-6350-1dca-dd4c9081e1e3.png)


# 接続完了🎉
![Screenshot from 2022-04-27 22-01-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/c3d6ebd5-3396-7e2c-aaf9-1b2d42867099.png)


![ezgif-5-3306e5d334.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/6ada759f-c9c7-d800-3580-b4d81789bd36.gif)

スクリーンショットを撮ったり、フルスクリーンやキーコマンドの送信ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/a001aaa8-fa02-f0f2-a089-63c47baa479e.png)
[ARFaceTracker] ARFaceTrackerを認識してみる　メモ

## ARKitでFactTrackingをしてみる

実際の実装方法
1 ARFactTrackingConfigurationをインスタンス化
2 ARsessionにセットしてrunする。


ここまで実装するとRealityKit側でARFaceAnchorに対応したエンティティを追加するようになる。

エンティティとは何か？
UnityでいうGameObject,SceneKitでいうNodeのこと。
これにコンポーネントをアタッチしていくことで機能や見た目を追加していく。ARKitではARViewを根元にして
木構造として分岐して表現される。

https://developer.apple.com/documentation/realitykit/entity


ARFaceAnchorを追加することでARKit側が生成してくれたエンティティを扱うためには下記のコードのようにARViewのSceneをsubscribeする必要がある。
``` swift
var eventAddEntity: Cancellable?
var arView: ARView!
.
.
// エンティティが追加されたイベントをキャッチする。
func setupSubscribe() {
//このsubscribeは全てのエンティティの変化も検知する。検知した際に第二引数に設定したメソッドを呼ぶ
  eventAddEntity = arView.scene.subscribe(to: SceneEvents.DidAddEntity.self,
                                          実行したいメソッド)
}
```

SceneEventsとは

https://developer.apple.com/documentation/realitykit/sceneevents

ARシーン上で起こるイベントの種類のこと
エンティティが追加されたときを示すDidAddEntity以外にも下記のものが存在する。

```swift
 SceneEvents.Update
// フレーム間隔ごとに1回トリガーされるイベント
　　　　SceneEvents.AnchoredStateChanged
// アンカー状態が変更されたときにトリガーされるイベント。
```

Entityが追加されるたびに実行したいメソッドを定義する
```swift
// 実行したいメソッド例 DidAddEntityを引数から取ってこれるようになる
func 実行したいメソッド（_ events: SceneEvents.DidAddEntity) {
// 追加されたEntityを変数に入れる。ただ、顔のトラッキングで生成されたEntityかどうかわからないので、、 HasModelという型に型キャストする
let entity = events.entity
}

```
HasModel型とは何か？
エンティティの見た目を定義するためのメッシュやマテリアルを提供するプロトコル

https://developer.apple.com/documentation/realitykit/hasmodel

型キャストするメソッド
```swift
 // 顔のトラッキングのエンティティならHasModelにキャストして返す
    func asFaceEntity(_ entity: Entity) -> HasModel? {
        let component =  entity.components[SceneUnderstandingComponent.self] as? SceneUnderstandingComponent
        
        // シーン認識コンポーネント（物理空間をマッピングするためのコンポーネント）
        if entity.components.has(SceneUnderstandingComponent.self) && 
// シーン認識コンポーネントあるかどうか
            entity.components.has(ModelComponent.self) && 
// モデルコンポーネントあるかどうか エンティティの見た目を構成するコンポーネントかどうか
            component?.entityType == .face { 
// その中でも顔の見た目を構成するものかどうか
            
            return entity as? HasModel
        }
        return nil
    }
```

HasModelはMaterialを持っているので自由に表面をコーディングできる！

```swift
guard let entity = asFaceEntity(event.entity) else { return }
 entity.model?.materials = <-ここにMaterialの配列セットする
そしたらライブ映像の顔が指定したMaterialでコーディングされる！
```
開発業務効率化のための小技集

## はじめに

業務での開発を進めていく上で効率を上げるために導入しているツールや小技を紹介します。

開発環境は macOS で、主にRubyを使ったソフトウェアの保守を行っています。

## コマンド操作の短縮 / Oh my zsh

[Oh my zsh](https://ohmyz.sh) という zsh のプラグインを使って、よく打つコマンドはエイリアスを使っています。
長めのコマンドが、数文字になってスッキリします。

機能はたくさんあるので、便利なエイリアスコマンドがあるか [ドキュメント](https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/) を見てみるといいかもしれません。

### git

|元のコマンド|エイリアス|
|-|-|
|git status|gst|
| git commit -m 'コミットメッセージ'| gcmsg 'コミットメッセージ' |
| git checkout| gco                  |
|git log --oneline --decorate --graph --all|gloga|
|git rebase -i|grbi|
| git reset --hard | grhh                 |

### bundler

|元のコマンド|エイリアス|
|-|-|
| be   | bundle exec|
|bundle exec rails serve| be rails s |

### 差分チェック

ログの比較やJSONの比較で重宝します。
VSCodeの場合、Oh my zshの拡張機能を使ってIDEの差分比較機能を呼び出します。

```
vscd /tmp/a.log /tmp/b.log
```

エイリアスなしなら
```
code --diff /tmp/a.log /tmp/b.log
```

シェルの話からずれますが、IntelliJ Ideaの diff を呼び出す場合
```
idea diff /tmp/a.log /tmp/b.log
```

## IntelliJ Idea

有償のJava用IDEです。PHP/Rubyにも対応しており、これ１本でいろいろできます。
Visual Studio Code も便利ですがメインはこっちで使っています。

https://www.jetbrains.com/ja-jp/idea/

主にこれらが便利で離れられません :laughing: 

- DBクライアント
- コード補完
- コード追跡
- Gitクライアント

## SSHデフォルト設定

業務でリモートのサーバーにSSHして作業する事が多いので、 ~/.ssh/config に接続情報をまとめています。
これによりsshコマンドがより短く済みます。

https://tech-blog.rakus.co.jp/entry/20210512/ssh

私が最も重宝しているのはデフォルトユーザーで、 `ssh 127.0.0.1` のように打つと指定したユーザーでログインできるようになります。 

Amazon Linux2 を最もよく使うので、設定ファイルに下記の通り書きます。

```
Host *
    User ec2-user
```

これにより、 `ssh 0.0.0.0` のコマンドが `ssh ec2-user@0.0.0.0` と同義になります。

## さいごに

日々の開発をすすめるために便利な小技を紹介しました。

少しでも役に立てば幸いです :dog2:
なぜ Rails の前段に Nginx を置くのか

# 追記（2023.09.13）

X にて、この記事が引用されて多くの議論が投稿されました。
それらの多くは以下の通り「ALB等の利用できる環境の現代であればもうNginxコンテナは不要」という内容が多数です。
その上で、本文に入って頂ければと思います。一部「いいね」が多いポストを貼り付けさせていただきます。

本文にショートカットしたい場合は、[ここをクリック](#ここから本文)

https://twitter.com/shibu_jp/status/1700725698707796149

https://twitter.com/sonots/status/1700778982092980654

https://twitter.com/fujiwara/status/1700828746801152130

https://twitter.com/voluntas/status/1700779173147799833

# ここから本文

以前、チームで以下のような会話が生まれました。

> 「コンテナに nginx 立てずに、直で rails Appサーバに　ALB　から流せばいいじゃん？」

みたいな話。その際に理由を即座にレスできなかったので、調査しました。

- puma や Unicorn はあくまでAppサーバなのでユーザ直アクセス用途として設計されていない
  - バッファリング処理が弱い
  - バッファリング処理（処理速度や処理にかかる時間の違いを調整すること）
- nginxから静的ファイルを配信するような構成も後からできる
- App側で静的ファイルの配布すると遅いが、CloudFrontを持ち出すまでもないような構成の場合など
- 本番環境では様々なアクセスを想定して nginx を前段において裁くことを想定すべき
- Webサーバのアクセスログは解析とかする際に都合が良い

的な理由が多いです。ALB とか WAF でも事前に裁くことができますが...

## ちなみに

`config/environments/production.rb` には以下のようなコメントがあります。

```
  # Apache or NGINX already handles this.
  config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
```

つまりRails思想としては、Railsサーバーの手前（まさに前段）にApacheやNginxを設置する前提がベースだったと言えます。

# 参考記事

- [EC2にRuby on Rails製のアプリケーションをデプロイする際におけるnginx等のWebサーバの必要性がわかりません](https://teratail.com/questions/298076)
- [【Rails】Webサーバー「Unicorn」の基本情報と実装方法](https://www.autovice.jp/articles/146)
- [Mac1台にnginxでWebサーバとPumaでアプリサーバを立てる](https://blog.mothule.com/web/nginx/web-nginx-getting-started-step3-on-mac#puma%E3%81%A8%E3%81%AF)
- [Rails アプリケーションで unicorn を nginx と共に使わなければならない理由](https://qiita.com/strike_yanagi/items/7e31041d05ab29edc8df)
- [なぜrailsの本番環境ではUnicorn,Nginxを使うのか? 　~ Rack,Unicorn,Nginxの連携について ~【Ruby On Railsでwebサービス運営】](https://qiita.com/takahiro1127/items/fcb81753eaf381b4b33c)
Bronze DBA 模試 復習アウトプット1

# はじめに
今回は、章末勉強している期間に、空白できてしまったが
現状の確認で忘れてしまっている項目についておさらい。
第1章~9章までは2022/2月まで勉強
2022/3,4月は繁忙期に流されて、今に至る。
先日から10章,11章を勉強して
模試を実施。
結果を踏まえて復習する部分について整理のためのアウトプット。
自分用。

# UNDO/REDO
・直感での考え(内容を忘れていたので)
UNDOってUN(否定) と DO(する)だから単純に動かない。
REDOはRE(再度) とDO(する)だからもう一度動かすみたいに考えていました。

・実際
UNDO：変更を元に戻すためのデータ。
REDO：一貫性の読み取りからの保護。

# ORACLE_HOME環境変数
Oracleソフトウェアを配置するディレクトリ。
暗記。

# リスナー制御
リスナー制御ユーティリティ(lsnrctlコマンド)というものがある。
暗記。

# アーカイブモードについて
アーカイブモードは2種類
<font color="Red">NO</font>ARCHIVELOGモード
　<font color="Red">インスタンス</font>障害の場合、<font color="Red">インスタンス</font>リカバリ
ARCHIVELOGモード
インスタンスリカバリ、メディアリカバリ両方可能
　<font color="Red">メディア</font>障害の場合、<font color="Red">メディア</font>リカバリ(障害発生直前まで戻す)
　非一貫性バックアップ可能　＝オンラインバックアップ

# リレーショナルデータベース
・データ整合性
・オブジェクトまたはリレーションの集合
・表を管理するための一連の演算子

#### 「表を管理するための一連の演算子」とは？
SQLの条件にする[AND]とか[OR]の事。

# 接続記述子の読み方
　ネットサービス名　＝　（
　HOSTとかはそのままなので省略。
CONNECT_DATA = <font color="Red">[データベース名].[ネットワークドメイン]</font>
）

例)
CONNECT_DATA = test.sample.com
の場合、
sample.comというドメインのtestというデータベースに接続する。

# OUIの仕様
・前提条件のチェック
・root起動はしない(root実行はあり)
暗記。
コイン問題（動的計画法）をpythonで実装

# 問題を解く前に
## 動的計画法とは
動的計画法とは
* いくつかの小さな問題の解や計算結果を利用してより大きな問題を解く。
* 同じ計算をすることを防ぐため、表に計算結果を記録し利用する。

というような条件を満たすアルゴリズムである。

# 問題
https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_1_A&lang=jp
* コイン問題
  * 額面がc1, c2,..., cm　円の　m　種類のコインを使って、 n 円を支払うときの、コインの最小の枚数を求めて下さい。各額面のコインは何度でも使用することができます。
  * 入力
  M N
c1 c2 ... cn
  * 出力
  コインの最小枚数を１行に出力してください。
  * 制約
    * 1 ≤ n ≤ 50,000
    * 1 ≤ m ≤ 20
    * 1 ≤ 額面 ≤ 10,000
額面はすべて異なり、必ず1を含む



# なぜ動的計画法をつかうのか
なぜ動的計画法を使うのか、それは`計算が入れ子構造になっている`からである。例えば、使えるコインの枚数が2枚で5円を支払う時、2枚目のコインが2円だったとする。(1枚目は1円)
2枚目のコインを1以上枚使うと考えると、5-2=3円となりN=3のときの問題に帰着する。つまりN=5の時の問題はN=3の時の問題を利用できる。また、N=3の時の問題もN=1の時の問題を利用していると考えられる。これは入れ子構造になっているといえる。つまり、この問題は動的計画法が有効であると考えられる。

# 考え方
実際にmを行としてnを列とした表を書いてその時のコインの最小枚数を埋めていく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627192/d9b3644e-5cef-4baf-f42c-07639ebb64dc.png)
引用：https://o-treetree.hatenablog.com/entry/DPL1A


そこである規則に気づき以下のような漸化式が立つ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627192/c8e5a494-2839-2d6d-c768-a93c0eb94904.png)
引用：https://o-treetree.hatenablog.com/entry/DPL1A

i:コインの番号
j:払う値段
ci:i番目コインの値段
を表す。
* 払う値段がi番目のコインより小さい場合(j<ci)の時
 表の1つ上の枚数と等しくなる。これは表を見れば分かるが、i=3,j=4,ci=7のときがそうである。
* 払う値段がi番目のコイン以上の場合
dp[i][j-ci]+1はj(払う値段)からci(i番目のコインの値段)を引いた値である。これは「なぜ動的計画法をつかうのか」で説明したことを式に表している。ciのコインを使うと仮定してそのコインの値段分を引いたところの枚数をみている。そこにciのコイン分の+1をすればよい。その枚数と今までの最小枚数を比べることで最小枚数を決定する。


# 実装
## プログラム
pytnonで実装した。
```python
#%%
n = int(input("n>>"))
m = int(input("m>>"))
C = []
inf = 100000

T1 = [[inf for _ in range(n+1)] for __ in range(m)]
for k in range(m):
    T1[k][0] = 0

for i in range(n+1):
    for j in range(m):
        if(i < C[j]):
            T1[j][i] = T1[j-1][i]
        else:
            T1[j][i] = min(T1[j-1][i],T1[j][i-C[j]]+1)


print(T1[-1][-1])

```
`先ほどの説明と違ってiとjが逆になっていることに注意`
* infで2次元配列T1を初期化している。
* for文で0円支払うときを表す0列目を0にする。
* 2重ループで漸化式を作る。
* 最後に配列の末尾を出力


## 出力結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627192/7279a3e2-b401-bb60-44d6-c79ef0d20c3d.png)

入力は
15 6
1 2 7 8 12 50
とした。その出力が2となった。これは7と8の組み合わせであり最小枚数であるから正しいと言える。
Gitで学んだこと　バージョン管理システム　

# Git
高機能の便利なバージョン管理システムです。

## バージョン管理システム
ファイルの履歴を管理するシステム
### 使う時
・プログラムにバグを入れてしまって以前のファイルの状態に戻したくなる時
・そうでなくても以前のファイル内容を見たくなったりする時

### チェックイン
ファイルの今の状態を保存しておきたい時ファイルの内容をバージョン管理システムに入れる行為

### バージョン
・チェックインされた状態

### リポジトリ
バージョンを入れる場所

### チェックアウト
バージョン管理システムに入っているバージョンを取り出す行為

### コミットする（動詞）
・チェックインすること

## Gitでのバージョン管理

### バージョン
あるディレクトリを根とする木（ディレクトリツリー）

### コミット（名詞）
・現在のディレクトリツリーの状態をコミットすると、そのディレクトリツリーが一つのバージョンとなってリポジトリに入る。Gitではこの一つのバージョンのこと

## Gitのディレクトリ構成
### 作業ツリー
開発をしているディレクトリだ。
プログラマがプリグラムを編集したりコンパイルしたりする場所

### .git
ディレクトリを作って、リポジトリなど必要な情報をここに入れる

### ステージ
作業ツリーとリポジトリの間にある領域
プログラマは作業ツリーの内容をステージにコピーする

また続きを書きます。
N+1問題の重要性

N+1問題とは、アプリケーション開発でデータベースへのアクセス回数が多くなってしまう時に注意すべき問題である。
ユーザーが何かを投稿や検索した際にその都度データベースへアクセスしていては、パフォーマンスが下がってしまう。
そのような問題点を解決する際に活用されるのが、includesメソッドである。このメソッドを活用することで、引数に指定されたものが一度のアクセスで取得できるのでぜひ活用して、パフォーマンス維持を図りたいと思う。
【Laravel】フォームのデータの受け取り

LaravelでCRUD機能を持つ簡単なブログを製作中

製作過程で調べたこと、忘れたくないことを記録中

# PHPでフォームのデータを受け取る
PHPでは、POST/GETリクエストで送信したデータは
$_POST/GET(スーパーグローバル変数)を使ってデータの受け取りを行う。

※POSTとGETの違い
・POST：データの登録、書き換えが必要なリクエストに利用する
　例）ユーザー登録、SNSやブログなどの投稿
・GET：データの受け取りに使用される
　例）ブラウザの検索、ページ遷移
　　　※リクエストの送信内容がURLに表示される

※
PHPのスーパーグローバル変数には$_REQUESTというものもあるらしい。
これはPOST, GET, COOKIEのすべてを一つにまとめたスーパーグローバル変数とのこと。

じゃあ全部$_REQUESTにしたらPOSTとGETを間違えてしまうこともないからいいじゃん！
と思ったが、どうやらそれは良くないらしい
POSTとGETはしっかり区別して使用した方が色んな面で良いらしい
（色んな面は勉強中）

# Laravelでフォームのデータを受け取る

 方法：Requestクラスを使う

例）ブログの投稿を受け取る
```PHP:sampleController.php
 public function sample(Request $request) {
       $title = $request->title;
       $post = $request->post;
 }
```
※Requestクラスをつかうためには
　`use Illuminate\Http\Request;`
 が必要


※メソッドインジェクション（依存注入）
　関数の引数にクラスと変数を入れることで、指定の変数に、指定したクラスのインスタンスを入れることができる

・メリット:コードの簡略化
```
 public function sample() {
       $request = new Request();
       $request->all();
 }
```
 ↓
```
 public function sample(Request $request) {
      $request->all();
 }
```

と、new 変数();のインスタンス生成を省略することができる


RequestクラスはHTTPリクエストに関するデータ処理をまとめたようなクラス？
と一旦解釈しましたが、まだ勉強中です。
ksnctf q38 Canned Can Opener

ksnctf q38 Canned Can Opener

https://ksnctf.sweetduet.info/problem/38

以下の2ファイルがダウンロードできる。
flag.jpg.enc
flag_canned.jpg


問題文を見ると、flag.jpg.encは以下のコマンドで暗号化されている。
$ openssl enc -e -aes-256-cbc -iter 10000 -in flag.jpg -pass file:flag.jpg -out flag.jpg.enc

ここで-pass file:flag.jpgは、flag.jpgの1行目をパスワードとして使用するという意味のようだ。

flag_canned.jpgを使って同様に暗号化復号化すると、どうもパスワードに使われるのは最初のNull文字までのようで、flag_canned.jpgをバイナリエディタで開くと、「FF D8 FF E1 2A 48 45 78 69 66」までの10バイトがパスワードとして使われるようであった。

ということはflag.jpgの1行目も同じデータかもと思い、試して見ることに。
5バイト目と6バイト目の2A48はAPP1アプリケーションセグメントのデータ長らしいので、ここを変えて探索すれば良いのでは？

下記のようなpythonコードを書き、試してみるとセグメントデータ長が0x3950で当たりとなり、decodeした画像にFLAGが表示された。

```python:test.py
import os
import subprocess
from sys import byteorder

for n in range(8192, 4096*16):
    print(n)
    nlist = [0xFF, 0xD8, 0xFF, 0xE1, 0x2A, 0x48, 0x45, 0x78, 0x69, 0x66]
    nlist[4] = n // 256
    nlist[5] = n % 256
    with open('dummy.bin', 'wb') as fp:
        blist = [n.to_bytes(1, byteorder) for n in nlist]
        fp.writelines(blist)
    cmdline = '/usr/bin/openssl enc -d -aes-256-cbc -iter 10000 -in flag.jpg.enc -pass file:dummy.bin -out fout.jpg'
    proc = subprocess.Popen(cmdline, shell=True, cwd=os.getcwd(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    res = proc.communicate()
    rstr = res[0].decode('utf-8')
    if 'bad decrypt' not in rstr:
        with open ('fout.jpg', 'rb') as fpi:
            data = fpi.read()
            if data[0] == 255 and data[1] == 216:
                print('found', n, rstr)
                break
```
![flag.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257741/0e1c6164-da39-0700-fa20-947eccf97626.jpeg)
中学2年生のみなさんへ。〈5/5〉数列「2022年共通テスト数学ⅡB第4問(2)配点20点の内4点」今更の考察


# 問題文

数列「2022年共通テスト数学Ⅱ・数学B第4問(選択問題)(配点20点)」より

前文？そのまま

01:　　　　以下のように，歩行者と自転車が自宅を出発して移動と停止を繰り返してい
02:　　　る。歩行者と自転車の動きについて，数学的に考えてみよう。
03:　　　　自宅を原点とする数直線を考え，歩行者と自転車をその数直線上を動く点とみ
04:　　　なす。数直線上の点の座標がｙであるとき，その点は位置ｙにあるということに
05:　　　する．また，歩行者が自宅を出発してからｘ分経過した時点を時刻ｘと表す。歩
06:　　　行者は時刻０に自宅を出発し，正の向きに毎分１の速さで歩き始める。自転車は
07:　　　時刻２に自宅を出発し，毎分２の速さで歩行者を追いかける。自転車が歩行者に
08:　　　追いつくと，歩行者と自転車はともに１分だけ停止する。その後，歩行者は再び
09:　　　正の向きに毎分１の速さで歩き出し，自転車は毎分２の速さで自宅に戻る。自転
10:　　　車は自宅に到着すると，１分だけ停止した後，再び毎分２の速さで歩行者を追い
11:　　　かける．これを繰り返し，自転車は自宅と歩行者の間を往復する。
12:　　　ｘ＝ａｎを自転車がｎ回目に自宅を出発する時刻とし，ｙ＝ｂｎをそのときの歩
13:　　　行者の位置とする。

以下つづく。


# 考察 20220427
①今更ですけど、上の12,13行目の配置が、問題を分かりにくくしていると思いました。
　この前文の中で、数列an,bnの説明をしない。
　数列の条件は、(1)に押し込めなかったのでしょうか？
　そうすると、前文と(2)で、独立した問題。(1)がなくても、(2)が成立すると思いました。
　(1)の問がなければ、「小中高生の共通テスト」ですね。
②中学受験生の先生へ。生徒さんで、(2)を解くヤツ。（失礼)解かれる生徒さんがいると、思います
　けど。

# 考察 20220503
①上の12,13行目の配置が,わざとで、(2）について、(1)がなくても解けるという事を教えたくなかったのかな。
　共通テストは奥が深いですね。

# 考察 20220726

「漸化式を**活用しなくても**y＝300に到着するまでの歩行者と自転車の動きを明らかにできました。」
どなたか確認をお願いします。<1/5>


(抜粋1)第２ 教育研究団体の意見・評価

第４問 (配点20点)
歩行者と自転車の動きについて数学化し，その関係を漸化式で表現し，その**漸化式を活用してy＝300に到着するまで**の歩行者と自転車の動きを明らかにする問題である。

リンク切れ
~~https://www.dnc.ac.jp/albums/abm.php?f=abm00041343.pdf&n=16-2+%E6%95%B0%E5%AD%A6%E2%85%A1%EF%BC%8C%E6%95%B0%E5%AD%A6%E2%85%A1%E3%83%BB%E6%95%B0%E5%AD%A6%EF%BC%A2.pdf#page=4~~


(抜粋2)自己評価

第４問
....得られた結果を活用していく力について評価する。 

~~https://www.dnc.ac.jp/albums/abm.php?f=abm00041344.pdf&n=16-3+%E6%95%B0%E5%AD%A6%E2%85%A1%EF%BC%8C%E6%95%B0%E5%AD%A6%E2%85%A1%E3%83%BB%E6%95%B0%E5%AD%A6%EF%BC%A2.pdf#page=2~~





# 参考 
令和４年度大学入学者選抜に係る大学入学共通テスト問題作成方針 令和 3 年 6 月 11 日 一部変更より

~~https://www.dnc.ac.jp/albums/abm.php?f=abm00040429.pdf&n=R04%E5%95%8F%E9%A1%8C%E4%BD%9C%E6%88%90%E6%96%B9%E9%87%9D.pdf#page=1~~

大学入学共通テスト（以下「共通テスト」という。）は，大学（専門職大学，
短期大学，専門職短期大学を含む。以下同じ。）への入学志願者を対象に，.....

# 〈1/5〉へ戻る
:::note info
https://qiita.com/mrrclb48z/items/297442a71820732d3ea3

:::


以下のサイトより、テキストをコピーしました。ありがとうございました。

https://mathexamtest.web.fc2.com/2022/202210000/2022100000200mj.html#q-0208
【Git Bash】コピー＆ペーストの方法と設定の変更

## 環境
+ Microsoft Windows 10.0.22000.613（21H2）
+ Git 2.34.1.windows.1

## デフォルトの設定
### コピー
テキストを選択 or `Ctrl+Ins`

### ペースト
マウスホイール（中央のボタン）クリック or `Shift+Ins`

## 設定の変更
### ショートカットキー
右クリック → Options → Keys で設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/a8113e6c-ed56-74d0-a190-e29f7eee652f.png)

### 選択
右クリック → Options → Selection で設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/48aa81b0-b4b7-5217-d87b-de6f1e3ff955.png)

### マウス
右クリック → Options → Mouse で設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946472/60b50bbe-5067-7c0e-e5a4-7fbda6d22571.png)
【zapier】Slack特定チャネル・アカウントの投稿をTwitterで投稿

# 複数メディアへのアウトプットを楽にしたい
> - 学び、成長の最適化のためにアウトプットを自社内では重視している
> - 各種SNSが個人の履歴書となっている
> - 感じた事、思ったことを「twitterやslackチャネルでつぶやく事」もアウトプットと定義する


うちの会社ではアウトプットの習慣を大事にしており、自分はslackとtwitterを多用しています。slackではワークスペース内に自分が呟く専用のチャネルを作ってtwitterにように日々の呟きを垂れ流しています。ただ業務利用の関係上、slackの方が利用頻度が圧倒的に多く、twitterアカウントの方はやや放置気味。slackに投稿したメッセージをそのままtwitterにも投稿したい。

# 自動化するフロー
1. slackの特定のチャネルでメッセージを投稿
2. メッセージが自身のものかフィルター
3. メッセージのテキストを整形（一部）
4. twitterへ投稿

# zapierでの自動化方法
[zapier](https://zapier.com/app/dashboard)を利用して自動化します。まずはアカウントを作成しましょう。
Freeプランだと実行Task数や頻度に制約がありますが、今回の目的には十分です。

Create Zap から自動化タスクを作成します。

## Triggerの設定
トリガーとなるアプリとイベントの種類を選択します
- app: `Slack`
- Trigger Event: `New Message Posted to Channel`

あとは Continueボタンをポチポチするとslackアカウントへのログイン＆連携とチャネルの選択を要求されるので適当に設定します

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440643/a6bbbe9e-5d75-349c-3ee2-474521f65b6d.png" width="600">

## Action `Filter by Zapier`の追加
Privateチャネルでない限り自分以外のメッセージもあり得まますのでフィルターします。今回はユーザ名を見て自身の値との完全一致でフィルターします。

- field: 前ステップの出力 `1. User Name`
- condition: `(Text) Exactly matches`
- value: `${your_slack_name}`

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440643/240f53c2-e125-9bf3-13e6-f109a83192e5.png" width="600">



## Action `Code by Zapier`の追加
あとはslackメッセージをtwitterへ投稿するだけですが、メッセージ文字列に含まれる絵文字の表現`:\w+:`がtwitterでは味気ない文字のまま表示されて残念な見た目になるので除去します。

`Code by Zapier`を使うとなんとjavascriptとPythonが実行できます。最強！
今回はjavascriptを使ってみました

- Action Event: `Run Javascript`
- Input Data:
  - name: `text` （なんでもいい）
  - value: `1. Text` （１番目のステップでslackから拾ってきたメッセージの文字列） 

```js:Code
const text = inputData.text;
output = {
  text: text.replace(/:\w+:/g, ""),
};
```
入出力はそれぞれ`inputData, output`という変数に`Object`で与えます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440643/ee6fe383-2513-c5f4-30d5-7d58df94de24.png" width="600">


## Action `Create Tweet in Twitter`の追加
最後にtwitterへ投稿します。

- app: `Twitter`
- Action Event: `Create Tweet`

ContinueボタンをポチってTwitterへログイン＆連携を許可します
投稿する文字列は前ステップで整形した値です

- Message: `3. Text`  

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440643/c32de6f6-e8c4-ebb4-48e6-1e515facaa6b.png" width="600">

# 完成
slackのあるチャネルにメッセージ送信すると、
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440643/5cb29c32-dd21-105b-86f6-b175f94d738b.png" width="600">

twitterに投稿される！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440643/463cc6e8-9131-98e1-67d2-88375625d2bf.png" width="600">

Freeプランだと更新頻度が15分と即時性はありませんがいいでしょう。
テスト63

```vb

Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hwndParent As Long, ByVal hwndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Public Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal MSG As Long, ByVal wParam As Long, ByVal lparam As Any) As Long
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Const BM_CLICK As Long = &HF5
Public Const WM_ACTIVATE As Long = &H6
Public Const WM_SETTEXT As Long = &HC
'------------------------------------------------------
Sub PDF_Open_Cancel()

'PDFに入力したパスワードが間違っていた場合、
'キャンセルボタンで終わらせる処理.....φ(･ω･｀)ｶｷｶｷ♪

Dim objWSH As Object
Dim Limit As Date
Dim hwnd As Long
Dim edt_hwnd As Long
Dim btn_hwnd As Long
Dim strPassword As String
Dim strFileName As String

'--------------------------------------
'PDFファイルのパスワード(間違い)
strPassword = "123"
'--------------------------------------

strFileName = "C:\Users\User\Desktop\yyy.pdf"

Set objWSH = CreateObject("Wscript.Shell")
'PDFファイルオープン
objWSH.Run """" & strFileName & """", 1

'--------------------------------------------------
'パスワードダイアログのハンドル取得
Do Until hwnd <> 0

    hwnd = FindWindow("#32770", "パスワード")
    '処理待ち
    Sleep (50)
    
    DoEvents
    
Loop

hwnd = FindWindowEx(hwnd, 0&, "GroupBox", vbNullString)


'パスワード入力欄のハンドル取得
edt_hwnd = FindWindowEx(hwnd, 0&, "RICHEDIT50W", vbNullString)
'OKボタンのハンドル取得
btn_hwnd = FindWindowEx(hwnd, 0&, "Button", "OK")

If (edt_hwnd <> 0) And (btn_hwnd <> 0) Then

    'パスワード送信
    Call SendMessage(edt_hwnd, WM_SETTEXT, 0&, strPassword)
    'OKボタンをクリック処理
    Call SendMessage(btn_hwnd, WM_ACTIVATE, 1, 0&)
    Call SendMessage(btn_hwnd, BM_CLICK, 0, 0&)

End If

'--------------------------------------------------
hwnd = 0
'「パスワードが正しくありません。Caps～」の文言のメッセージボックスでOKを押す
Do Until hwnd <> 0

    hwnd = FindWindow("#32770", "Adobe Acrobat")
    '処理待ち
    Sleep (50)
    
    DoEvents
    
Loop

hwnd = FindWindowEx(hwnd, 0&, "GroupBox", vbNullString)

'OKボタンのハンドル取得
btn_hwnd = FindWindowEx(hwnd, 0&, "Button", "OK")

'OKボタンをクリック処理
Call SendMessage(btn_hwnd, WM_ACTIVATE, 1, 0&)
Call SendMessage(btn_hwnd, BM_CLICK, 0, 0&)

'--------------------------------------------------
hwnd = 0
'パスワードのメッセージボックスが再度表示された後に「キャンセル」ボタンを押す
'パスワードダイアログのハンドル取得
Do Until hwnd <> 0
    hwnd = FindWindow("#32770", "パスワード")
    '処理待ち
    Sleep (50)
    
    DoEvents
    
Loop

hwnd = FindWindowEx(hwnd, 0&, "GroupBox", vbNullString)

'キャンセルボタンのハンドル取得
btn_hwnd = FindWindowEx(hwnd, 0&, "Button", "キャンセル")

'キャンセルボタンをクリック処理
Call SendMessage(btn_hwnd, WM_ACTIVATE, 1, 0&)
Call SendMessage(btn_hwnd, BM_CLICK, 0, 0&)

Set objWSH = Nothing

End Sub
SAP API Management×Outsytems Integration Builder

# 本記事でやること

OutsytemsのIntegration BuilderでSAPのOdataを用いたIntegrationを作成してみます。

# 記事の流れ
・Integration Builderの使い方
・API Managementを経由してOdataによるデータ取得
・OutsytemsのService Centerで確認

## Integration Builderの使い方

https://www.outsystems.com/ja-jp/platform/integration-builder/


Integration Builderの画面にアクセスしたら右上の**Create Integration**のボタンからプロバイダーを選びます
今回はODataを選択します
まだそんなに数は多くない印象です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/21b04cfb-b91f-2990-4ce5-fad03dcafa21.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/b15f00ca-a43f-c21e-2e7c-22baf1c04edd.png)

 この画面で対象としたいOdataのJSONかEDMXファイル（コード）をアップロードして後は画面に従ってEntityを選択したりして設定を進めていきます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/2fb0d403-f5c9-62cb-1712-3c5c3ca7f6d8.png)



### 通常のJSON、EDMXファイルの入手先

https://api.sap.com/api/API_BUSINESS_PARTNER/resource

API BUSINESS HUBで対象のAPIを検索
OverviewのAPI Specificationにあるダウンロードボタンからお好きな形式でファイルをダウンロードできます
API BUSINESS HUBはログインしてAPI keyを入力することでサンドボックス環境のAPIを試すことができます
Integration BuilderでもこのAPI Keyを使ってIntegrationの確認ができるようです
でもどうせならサンドボックスのデータじゃなくてちゃんとしたデータみたくね？使いたくね？ってことで次のステップです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/cb7d17fe-408f-b49c-c4dc-e92d86a9f9a5.png)



## API Managementを経由してOdataによるデータ取得

API ManagementというSAP BTPのIntegrationSuiteのサービスを使います。
IntegrationSuiteはこれまで別個にあったIntegrationサービスをまとめたサービス群です

https://help.sap.com/docs/SAP_CLOUD_PLATFORM_INTEGRATION_SUITE

https://help.sap.com/docs/SAP_CLOUD_PLATFORM_API_MANAGEMENT?locale=ja-JP


ODATAをAPI Managementに登録する方法はここらへんのチュートリアルを参考に作業ください

https://developers.sap.com/tutorials/hcp-apim-create-provider.html

登録するとこんな感じでODATAの仕様が見えるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/182d8d69-87fc-932a-74f3-25d8d4ab3008.png)

右上のAPI Designerから画面遷移し、JSONファイルをダウンロードします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/3c2f3983-a525-6aa8-89e5-2dbefeb73b41.png)

あとはIntegration Builderの画面に戻って画面に従って操作します
すべてのEntityを選択するとサービスの大きさにもよりますが10分程度
今回みたいに1個のみの場合は2分程度で終わるみたいです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/f09acdc3-967b-e9cf-49a5-30be971cc224.png)

# OutsytemsのService Centerで確認

### Logic

こんな感じで選択したEntityのMethodやそれに必要なActionが自動で作成されます


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/dc840c90-4db0-bc87-77c9-716ae894b97f.png)

### Data

Dataタブも確認すると必要なEntityやStructureが追加されています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137987/240821c6-aa5a-6cd2-4040-8457ae599bd9.png)

# 最後に
本機能のメリットとしては作業工数の省略だと思います
Methodを必要なものだけODATAのURLから追加していけばほぼ同じような状態を作ることは可能です
ただそうするとODATA全体の仕様が不明なのことと数が多いためかなりの時間がかかるのを一括で設定できるのは便利だと感じました
API BUSINESS HUBからファイルをダウンロードしてベースURLの部分を書き換える形でも同じようなことが実現できるのかもしれないですがS/4側のバージョンの違いかエラーが出て解決できなかったので今回のような方法をとりました
このAPIの動作確認は今からやりますがとりありあえずインポート時点でエラーは出ていません

# 参考
https://success.outsystems.com/ja-jp/Documentation/11/Extensibility_and_Integration/Create_connectors_with_Integration_Builder/Use_Integration_Builder#use
Shopify｜公式テーマ『Prestige』にてカラースウォッチが動作しない場合の注意点


#### 01. Prestigeでのカラースウォッチ機能の仕様
```
{%- assign color_label = 'color,colour,couleur,colore,farbe,색,色,färg,farve' | split: ',' -%}
```
>1. 上記コードにて『color_label』という変数にカラー関連の用語（color,色など）を事前に格納している。（*assign：割り当てる*）
>2. 後で実際のオプション名が『color_label』内に格納されている用語とマッチするかどうかを判別する。
>3. マッチしている場合にのみカラースウォッチが動作する。

『Prestige』のカラースウォッチは上記のような仕様になっている。
***
#### 02. 対応策
そのため、事前に『color_label』に格納されている用語とオプション名がマッチしない場合にはカラースウォッチが動作しない。

注意点としてはオプション名を『カラー』にした場合、デフォルトでは『カラー』という用語は『color_label』に格納されていないため、別途格納してあげる必要がある。（下記参照）
```
{%- assign color_label = 'color,colour,couleur,colore,farbe,색,カラー,色,färg,farve' | split: ',' -%}
```
PHP で if ($var) と書かれていてよく思考停止する話～ if の動きまとめ

## tl;dr

if の中には「はい」か「いいえ」で答えられるような表現を書きましょう。

---

PHP でよく見られる次の書き方。

```php
if ($var) {
    // 何らかの処理
}
```

これを日本語にすると「もし $var ならば」

・・・何が？🤔

私としては、日本語に直せない if 文の表現は書くべきではないと思っています。
ですが、会社の既存コードにはやむを得ず `if ($var)` が登場することがあります。
PHP の保守案件に関わったりする場合は、やはり動きを知っておかなければなりません。

## `if ($var)` の動き

下の記事にあるように、if の括弧内に書かれた表現は真偽値 (true または false) として解釈されます。
解釈された結果が true の場合は処理を実行し、false の場合は実行しません。

https://www.php.net/manual/en/control-structures.if.php

> expression is evaluated to its Boolean value. If expression evaluates to true, PHP will execute statement, and if it evaluates to false - it'll ignore it.

## 真偽値としての解釈で false になるもの

では、どのような表現が true になり、どのような表現が false になるのか、boolean 型にキャストしながら見ていきます。

https://www.php.net/manual/en/language.types.boolean.php#language.types.boolean.casting

### false 自身

言うまでもなく false と解釈されます。

```php
var_dump((bool)false);
```

```text
bool(false)
```

### 整数型: `0`

真偽値をよく 0 と 1 に置き換えることがありますが、その感覚と同じで 0 は false と解釈されます。

```php
var_dump((bool)0);
```

```text
bool(false)
```

### 浮動小数点型: `0.0` と `-0.0`

```php
var_dump((bool)0.0);
var_dump((bool)-0.0);
```

```text
bool(false)
bool(false)
```

### 文字列型: `""` (空の文字列) と `"0"`

文字列の `"0"` は、文字列としては空でないのに false と解釈されるので注意です。

```php
var_dump((bool)"");
var_dump((bool)"0");
```

```text
bool(false)
bool(false)
```

### 配列型: 要素を持たない配列 array(), []

```php
var_dump((bool)array());
```

```text
bool(false)
```

### NULL 型

```php
var_dump((bool)null);
```

```text
bool(false)
```

### 未定義の変数・unset された変数

```php
var_dump((bool)$a);

$b = 1;
unset($b);
var_dump((bool)$b);
```

```text
bool(false)
bool(false)
```

### 子要素を持たない要素から作られた SimpleXML オブジェクト

```php
$menu = simplexml_load_string('<menu></menu>');
var_dump($menu);
var_dump((bool)$menu);
```

```text
object(SimpleXMLElement)#1 (0) {
}
bool(false)
```

## 真偽値としての解釈で true になる意外なもの

true と解釈されるもののうち、要注意だと思うものをいくつか列挙します。

### 整数の -1

```php
var_dump((bool)-1);
```

```text
bool(true)
```

### 文字列の `"false"`

```php
var_dump((bool)"false");
```

```text
bool(true)
```

### 子要素が子要素をもたない SimpleXML オブジェクトの子要素の方

dish は子要素を持たないのですが、true と解釈されます。

```php
$menu = simplexml_load_string('<menu><dish></dish></menu>');
var_dump($menu->dish);
var_dump((bool)$menu->dish);
```

```text
object(SimpleXMLElement)#2 (0) {
}
bool(true)
```

## if の中には「はい」か「いいえ」で答えられるものを書きましょう

この記事は if の仕組みを理解するための記事ですが、決して if の中に変数をそのままぶち込むことを推奨するものではありません。
パッと見わかりにくい暗黙的な書き方を多用していては、初学者や非 PHP エンジニアの方が入る余地がなくなってしまいます。

if は「もし～ならば」と訳されるものですから、「～」には「はい」か「いいえ」で答えられるものを書くか、変数名を工夫することをおすすめします。

```php
// $var は整数の 1 ですか？
if ($var === 1)

// 文字列 '1' は配列 ['1', '2', '3'] の中に存在しますか？
if (in_array(['1', '2', '3'], '1', true))

// Taro はリンゴを好きですか？
if ($taroLikesApple)

// お店は開いていますか？
if ($shop->isOpen())

// 「何らかの処理」は成功しましたか？
$onSuccess = 何らかの処理();
if ($onSuccess)
```
BigQueryClientでのデータセット、ロケーション指定方法

# 要約
BigQueryClientを利用する際に、デフォルトのデータセット（テーブル修飾のデータセット部分を省略した場合に適用されるデータセット)と、ロケーションを指定するサンプルコードを提供する。
目的としては自身の備忘録です。

# コード
```c#: BigQueryClient

// 一つのインスタンスを使う
static BigQueryClient m_client

// クライアント取得ロジック
public BigQueryClient GetClient()
{
    if (m_client == null)
    {
        GoogleCredential credential = GoogleCredential.FromFile(CoreUtils.ResolvePath(JsonFilePath));
        m_client = BigQueryClient.Create(ProjectId, credential);
    }
    return m_client;
}

public BigQueryResults(string datasetId, string location)
{
    client = GetClient();
    DatasetReference dsRef = new DatasetReference();
    // デフォルトデータセットを設定
    dsRef.DatasetId = datasetId;
    QueryOptions queryOptions = new QueryOptions();
    queryOptions.DefaultDataset = dsRef;
    // ロケーションを指定
    queryOptions.JobLocation = dataset.Resource.Location;
    job = client.CreateQueryJob(query, null, queryOptions).PollUntilCompleted();

    BigQueryResults results = client.GetQueryResults(job.Resource.JobReference, queryResultOptions).ThrowOnAnyError();

    return results;
}
```

ご参考まで。
【Kotlin】Byte型からuchar型に変換

# 変換方法
`toInt()`を使用したところ、マイナスの値も含まれるようになった。
`toUByte()`を間に入れることで正常な値となった。

```Kotlin
b.toUByte().toInt().toChar()
```

# 参考サイト
https://stackoverflow.com/questions/38651192/how-to-correctly-handle-byte-values-greater-than-127-in-kotlin
DockerHubからpullしたDockerImageをpushするまで

# 環境
エッジ : raspberrypi4
(ubuntuOSでも同様にできます)

# 前提
Dockerインストール済み(下記コマンドでバージョン情報出ればインストール済み)
```
docker --version
```
DockerHubアカウント作成済み
⇨仮にアカウント情報を,

<strong>ID:Mr.test    
PW:test 

として書いていきます

# 手順目次
---
01. DockerHubから取得するDockerImage選定
02. 選定したDockerImageをローカルにpull
03. pullしたDockerImageを起動しモジュール操作
04. Dockerから抜ける
05. 新しいDockerImageを作成する
06. DockerImageをpushする
07. 不要なDockerImageを削除する
---

# 手順詳細

## 01. DockerHubから取得するDockerImage選定
ウェブで「DockerHub」と検索⇨ログイン⇨欲しいものを選定する
↓を欲しい物と選んだらクリックしてブラウザ遷移
![スクリーンショット 2022-04-27 17.41.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906162/2c521649-6012-2f26-dd5e-68de53dff44b.png)
「Docker pull command」があるのでこれをコピーする
![スクリーンショット 2022-04-27 17.39.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906162/5ae52432-19be-69ff-aa2b-1d495813d886.png)

## 02. 選定したDockerImageをローカルにpull
ターミナルで
先程コピーしたコマンドをペーストしてpullします
(permissionエラーでたら先頭にsudo入れて再度pull)

#### pullしたImageは、「test100/docker_test:v1」 とする(先ほどの画像のImage名は無視してください)

## 03. pullしたDockerImageを起動しモジュール操作
下記コマンドで起動
```
sudo docker run -it test100/docker_test:v1 bash
```
これでDockerに入れるので、自由にモジュール追加したりする

## 04. Dockerから抜ける

Ctrl + D か
```
exit
```
で抜ける

## 05. 新しいDockerImageを作成する
先ほど操作していたDockerImageのコンテナIDを確認する
```
sudo docker ps -a
```
CONTAINER IDの部分を確認する(仮に「A0A0A0A0A0A0A0」とする)

コミットする(今回作成するImage名は「test_image」とする)
```
sudo docker container commmit A0A0A0A0A0A0A0 test_image
```

新しいImageの「IMAGE ID」を確認する
```
sudo docker images
```
IMAGE IDは以下とする
「B0B0B0B0B0B0」

先ほど追加したImageにアカウント情報を追加する(アカウント名は「Mr.test」)
```
sudo docker tag B0B0B0B0B0B0 Mr.test/test_image
```
## 06. DockerImageをpushする
まずターミナル上でログインしていなければログインする
```
sudo docker login
```
Userとパスワードを求められるので、
<strong>ID:Mr.test    
PW:test 
（自分のアカウント情報を入力）

Imageをリモートリポジトリ(DockerHub)にpushする
```
sudo docker push Mr.test/test_image
```
しばらく待って完了したら、DockerHubのサイトでPushしたImageがあるか確認する

## 07. 不要なDockerImageを削除する
メモリの関係とか4S観点で不要なImageは削除する

以下コマンドで「REPOSITORY」(最左の項目)
```
sudo docker images
```
今回消したいImageのREPOSITORYは「test100/docker_test:v1」
(:v1の部分はsudo docker imagesのところでTAGの欄で該当するところ
　⇨latestなら「:v1」の部分が必要無し)
以下コマンドで削除
```
sudo docker rmi test100/docker_test:v1
```

以上で完了です

わーっと書いてしまったので
わかりにくい部分は指摘頂けると幸いです
Splunkデータ取り込み時の絞り込み方法(リストマッチ)

## はじめに
Splunkへデータを取り込む際、特定の条件に合致したデータのみをSplunkへ取り込む事が可能です。
今回は、以下の要件を実現する場合の設定についてご紹介します。
* 対象データ
  * JSONフォーマットデータ
* 取り込み条件
  * 任意のKeyの値(value)が事前に指定した値である場合のみ取り込む
  * 指定値はリストとして保持 

## 構成
* Splunk Enterpriseバージョン
  * v8.2.2
* データ取り込み構成 
  * Heavy Forwarder -> Indexer
    * Heavy Forwarderにて今回の要件を実現する設定を適用します。 

## 利用するSplunk機能
* リスト保持
  * Lookup機能
* 取り込み判定処理
  * 条件定義：Ingest-time Eval機能(EVAL関数を用いた条件指定)
  * 条件判定に基づく取り込み選択：Queue指定(nullQueue or indexQueue)

## 取得要件例
以下のJSONフォーマットデータを対象として、mail値が事前に定義された値であるデータのみをSplunkに取り込みます。
* sample.log
    ```
    {"msg":"this is test log","name":"Tokyo","type":"VPN User","mail":"user01@test.com","time":"2022-04-01T01:10:40Z"}
    {"msg":"this is test log","name":"Tokyo","type":"VPN User","mail":"user02@test.com","time":"2022-04-01T01:20:40Z"}
    {"msg":"this is test log","name":"Tokyo","type":"VPN User","mail":"user03@test.com","time":"2022-04-01T01:30:40Z"}
    {"msg":"this is test log","name":"Tokyo","type":"VPN User","mail":"user04@test.com","time":"2022-04-01T01:40:40Z"}
    {"msg":"this is test log","name":"Tokyo","type":"VPN User","mail":"user01@test.com","time":"2022-04-01T01:50:40Z"}
    ```

## 設定例
今回の内容に関連する設定のみ記載します。
* Heavy Forwarder (Lookupファイル配置)
  * maillist.csv
    * Lookupファイル
      ```
      mail
      user01@test.com
      user04@test.com
      ```
* Heavy Forwarder (取り込み設定)
  * props.conf
    * ソースタイプ名(sample_json_filtered)及び各種ソースタイプ設定の定義
    * 適用する取り込み設定(transforms.conf)の参照
      ```
      [sample_json_filtered]
      CHARSET=UTF-8
      INDEXED_EXTRACTIONS=json
      KV_MODE=none
      SHOULD_LINEMERGE=true
      disabled=false
      pulldown_type=true
      TIMESTAMP_FIELDS=time
      LINE_BREAKER=([\r\n]+)
      NO_BINARY_CHECK=true
      TRANSFORMS-filter = filter_list
      ```
  * transforms.conf
    * 取り込みデータのmail値と指定したルックアップファイル内の値を照合し、値が合致する場合は取り込み対象(indexQueue), 合致しない場合は取り込み対象外(nullQueue)とします。
      ```
      [filter_list]
      INGEST_EVAL= queue=if(json_extract(lookup("maillist.csv", json_object("mail", mail), json_array("mail"))),"indexQueue","nullQueue")
      ```

## 取得結果
sample.logを取り込んだ結果を以下に示します。
リストに記載されたmail値を持つデータのみが格納されていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609667/feab67cc-98a3-ab4c-cd73-0c29ce8bf140.png)

## 参考 
* [Process events with ingest-time eval - Splunk Documentation](https://docs.splunk.com/Documentation/Splunk/8.2.2/Data/IngestEval)
* [Reduce lookup overhead with ingest-time lookups - Splunk Documentation](https://docs.splunk.com/Documentation/Splunk/8.2.2/Data/IngestLookups)
* [Filter event data and send to queues - Splunk Documentation](https://docs.splunk.com/Documentation/Splunk/8.2.2/Forwarding/Routeandfilterdatad#Filter_event_data_and_send_to_queues)