OmniAICreator/Qiita-1.07M huggingface dataset:
Bootstrapのナビバーのカラースキームについて

## 環境
Bootstrap5
HTML

## はじめに
Bootstrapのナビバー（ナビゲーションバー）のカラースキームの設定は、何色にするべきか悩むところです。服を買うときに、試着室に入って、「うーん、この柄は違うな」とか、別の服を選んできて、「うーん、この柄はどうかな」とか言っているようなものでしょうか。カラースキームにはどのような設定があるのか、色々と試してみます。

## 内容

ダーク系の色にしたい場合の設定です。
```sample.html
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
```
このようなイメージになります。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/a3c21f90-b59a-ef64-f79a-df72a8d56963.png)

bg-xxxとnavbar-xxxの順番は、気にする必要はありません。このように順番を前後して記述しても問題なく動作します。
```sample.html
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
```

ライト系の色にしたい場合の設定です。
```sample.html
<nav class="navbar navbar-expand-sm navbar-light bg-light">
```

このようなイメージになります。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/16bb21fb-21b3-7f0b-7bf9-3a3a25536c61.png)

このように設定すると、ライト系のバックに文字色が白になってしまうため、文字が分かり難くなるため、この組み合わせは基本的に使うことはできません。
```sample.html
<nav class="navbar navbar-expand-sm navbar-dark bg-light">
```

このような見え方になってしまいます。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/5a2e0bf0-49c4-7f2f-135e-aca0064f7390.png)

また、このように設定するとダーク系のバックに文字色が黒になってしまうため、これも、文字が消えて使えません。
```sample.html
<nav class="navbar navbar-expand-sm navbar-light bg-dark">
```

このような見え方になってしまいます。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/55cffd6d-34f8-49db-5294-d6738cace390.png)

pg-xxxxの、xxxxには、darkとlight以外の色を指定することができます。primaryを指定するとバックが青色になります。しかし、バックが青色で文字色が黒だと少し目がチカチカして見難いでしょうか。
```sample.html
<nav class="navbar navbar-expand-sm navbar-light bg-primary">
```

このようなイメージになります。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/cc99d62c-ec9d-d4af-2d1c-6f84e8736aba.png)

このように設定すると、バックが青色で、文字色が白っぽくなります。この方が見やすいでしょう。
```sample.html
<nav class="navbar navbar-expand-sm navbar-dark bg-primary">
```

このようなイメージになります。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/1318e60f-f46d-53d2-c4ce-4186c6e0fc15.png)

pg-xxxxのxxxxには、青色のprimary以外にも、他の色を選択することができます。赤色であれば、danger、緑色であれば、successとなります。他にも数種類あります。

>参考
https://getbootstrap.jp/docs/4.1/utilities/colors/

バックの色は、Bootstrapで予約されている色しか使えないということはありません。自分で好きな色にカスタマイズすることができます。バックの色をシアンにしたい場合、シアンの色コードを#rrggbbで指定すれば、任意の色に設定することができます。シアンはBootstrapでは変数として予約されていません。色コードを指定すると好きな色にカスタマイズすることができます。

>参考：色コードを調べるサイト
https://itsakura.com/html-color-codes

```sample.html
<nav class="navbar navbar-expand-sm navbar-light" style="background-color: #00FFFF;">
```

このようなイメージになります。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94029/d83b2888-8c5b-e23b-6bdb-95bc9d62f1c2.png)
【Swift】コードで行う画面遷移の方法

<h1>はじめに
<p>画面遷移をさせる際にいつもやり方を調べ直していたので、自分なりにまとめてみました。
<h1>２パターンの画面遷移


画面遷移の挙動は大きく２つあり、コードの書き方が異なります。
### UINavigationControllerを使った場合

* 横方向に遷移する
* スワイプで移動できる
* カメラで撮った写真を見る時のような動き
* pushViewControllerメソッドを呼び出すことで可能になります

``` swift:pushViewController
func pushViewController(_ viewController: UIViewController, animated: Bool)
```

### ViewControllerを使った場合

* 現在表示されている画面(view)の上に、新しい画面が重なる
* 画面下からスーッと現れる
* presentメソッドを呼び出すことで可能になります

``` swift:present
func present(_ viewControllerToPresent: UIViewController, 
            animated flag: Bool, completion: (() -> Void)? = nil)
```
# 画面遷移の手順
遷移先のViewControllerをコードで取得する場合は、次のようなステップを踏みます。　
「MainViewController」から「ResultViewController」に遷移するやり方をまとめました。
#### [前提]
* 新しいプロジェクトが作成します。
* 遷移先の「ResultViewController」を作成します。
* 新しく「Result.storyboard」というStoryboardを作成して、viewControllerを配置します。
*　storyboardに配置したviewControllerと「ResultViewController」を関連付けておきます。

### 1. 遷移先のStoryboardを取得する

まずは、遷移先のstoryboardを取得します。
``` swift
let storyboard = UIStoryboard(name: "Result", bundle: nil)
```
引数nameの値は、遷移先のStoryboardの名前を渡します。
（今回は「Result.storyboard」なので「Result」となります）
これでstoryboardの取得ができました！



### 2. 取得したStoryboardからViewControllerをインスタンス化する
今度は取得したStoryboardからResultViewControllerをインスタンス化していきます。
インスタンス化するには、instantiateInitialViewControllerメソッドを使います。
``` swift
guard let resultViewController = storyboard.instantiateInitialViewController() as? ResuntViewController else { return } 
```


または　ViewControllerの「Identifier」に任意の名前を設定すれば、
``` Swift
let resultViewController = storyboard.instantiateViewController(withIdentifier: "Result" ) as? ResultViewController
```
と記載することも可能です。
（Identifierは「Result」にしています）





### 3. 遷移のコードを記述する
#### - NavigationControllerを使うパターン
流れとしては、
遷移元のViewControllerに NavigationControllerを追加
↓
画面遷移のコードを書く　という流れになります。

NavigationControllerを追加方法は２つあります。

**その１**
① 遷移元のViewControllerを選択する 
    ② xcodeのツールバーの「Editor」を押す
③「Embed In」を選択
④「NavigationController」を選択すれば追加される

**その２**
①command⌘ + shift + L　で　を呼びだす
②検索欄で「NavigationController」と入力
③「NavigationController」を元のViewControllerの隣にドラッグ&ドロップ　
④２つ目のViewを削除します。
⑤「NavigationController」から元のViewへ、control + ドラッグ＆ドロップでrootViewController接続をすれば追加されます。




無事、NavigationControllerが追加できたら遷移のコードを書きます。

``` swift
let storyboard = UIStoryboard(name: "Result", bundle: nil)
guard let resultViewController = storyboard.instantiateInitialViewController() as? ResuntViewController else { return  } 
//↓この部分
navigationController?.pushViewController(resultViewController, animated: true)
```
***
#### - ViewControllerを使うパターン
こちらは前半で説明した、presentメソッドを呼び出せばOKです。

``` swift
let storyboard = UIStoryboard(name: "Result", bundle: nil)
guard let resultViewController = storyboard.instantiateInitialViewController() as? ResuntViewController else { return  } 
//↓この部分
present(resultViewController, animated: true)
```
***
これで画面遷移を行うコードが書けました。
画面に配置したボタンを押した際に、画面遷移させたい時は、これらの一連のコードをメソッドにして、UIButtonのアクションメソッドの中で呼び出してあげるとよさそうです！


# さいごに
初心者なりに学んだことをまとめてみました。
間違っている部分などありましたら、教えていただけるとありがたいです！
JSのPromiseの基本について調べてみた

## 背景
Axiosを使おうとした際にAxiosのREADMEに「Promise based HTTP client for the browser and node.js」とあり、
そもそもPromiseってなあに？となったためPromiseの概要についてまとめてみました！

※新卒1年目で知識も浅いため、内容には間違いがある場合があります💦

## Promiseの基本
そもそもPromiseとは、日本語に訳すと「約束」です。

JSのPromiseも同じで処理における約束を決めるものになります。
つまり　①約束を守った場合、➁約束を破った場合の処理をそれぞれ記述することができるものです。

#### Promiseのステータス
待機状態　　　　　　　⇒　pending
成功（約束を守った）　⇒　resolved
失敗（約束を破った）　⇒　rejected


#### Promiseのインスタンス化
Promiseをインスタンス化する際には、引数に何を入れるかは決まっています！
***▶第1引数にはresolve（約束を守った場合）のコールバック関数***
***▶第2引数にはreject（約束を破った場合）のコールバック関数***
を書きます。
ただ、第2引数のrejectは省略可能になるので、約束破る場合なんかないよってときは記述しなくても大丈夫です。

引数の取り方は、無名関数またはアロー関数のどちらでもOKみたいです◎

```js:promiseTest.js

// 無名関数を利用する場合
const condition = true;
const promise = new Promise(function(resolve,reject){
    if(condition) {
        resolve('やくそくまもりました。')
    } else {
        reject('やくそくわすれてました。')
    }
})

// アロー関数を利用する場合
let promise = new Promise((resolve, reject) => {  
    if(condition) {
        resolve('やくそくまもりました。')
    } else {
        reject('やくそくわすれてました。')
    }
});

```


## Promiseの結果の値を取得する
結果の取り方はシンプルです！
***resolve（約束を守った場合）：　`.then()`***
***reject（約束を破った場合）：　`.catch()`***
thenもcatchもカッコの中には無名関数が入り、その無名関数の中の引数がPromiseの結果の値となります。
この引数の変数名は自由に付けることができるので、どのような結果が返ってくるのかによって適した名前にすることができます。

上記のサンプルコード（promiseTest.js）であれば、以下が結果として返ることになります。
then ⇒　`'やくそくまもりました。'`
catch ⇒　`'やくそくわすれてました。'`

```js

// resolveの結果
promise.then(function(result){
    console.log(result)
})

// rejectの結果
promise.catch(function(result){
    console.log(result)
})

```

## Promiseを複数使う
Promiseは複数作り、連結することが可能です。
Promiseを連結することで、処理を実行した後でその実行結果を次の処理に渡すこともできます。

```js
// 条件の定義
const condition_1 = true;
const condition_2 = true;

// 約束１
const promise1 = new Promise(function(resolve,reject){
    if(condition_1) {
        resolve('約束１_OK')
    } else {
        reject('約束１_NG')
    }
})

// 約束２
const promise2 = function(result_promise1){
    return new Promise(function(resolve,reject){
        if (condition_2){
            resolve(result_promise1 + ',' + '約束２_OK')
        } else {
            reject(result_promise1 + ',' + '約束２_NG')
        }
    })
}

promise1
  .then(promise2) // promise1がresolveの場合の結果をpromise2に渡した後、promise2を実行
  .then(function (result_promise2) {  // promise2がresolveの場合の結果
    console.log(result_promise2)
  })
  .catch(function (result_promise1) {  //promise1がrejectの場合の結果
    console.log(result_promise1)
  })
```

#### 実行結果
１. `condition_1 = true`、`condition_2 = true`の場合
```
約束１_OK, 約束２_OK
```

２. `condition_1 = true`、`condition_2 = false`の場合 
```
約束１_OK, 約束２_NG
```

３. `condition_1 = false`、`condition_2 = true`の場合 
condition_1がfalseの時点でcatchされるため、promise2の処理は実行されていません。
```
約束１_NG
```

４. `condition_1 = false`、`condition_2 = false`の場合 
condition_1がfalseの時点でcatchされるため、promise2の処理は実行されていません。
```
約束１_NG
```

## 参考文献
執筆にあたり参考にさせていただいたサイトは以下になります。

【JavaScriptのPromiseって何？を解決したい】
https://reffect.co.jp/html/promise-is-what#JavaScriptPromise
ファイル名を変える

# ファイル名やディレクトリ名を変える
```
git mv 元の名前　新しい名前
```
ファイル名やディレクトリ名を変えられる。

ステージと作業ツリーの中でファイル名が変わる。
```既にリポジトリに保存されているコミットには影響はない。```

# 演習１
```
********@mbp ******* % git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   hello.txt
```
```
*******@mbp ******* % git mv hello.txt oha.txt
*******@mbp ******* % git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	renamed:    hello.txt -> oha.txt
```
確かに作業ツリーとステージの名前が変わった。

# 演習２
コミットメッセージをつけて変更した。
# 出典
https://www.amazon.co.jp/%E3%82%8F%E3%81%8B%E3%82%8B-Git-%E5%86%A8%E6%B0%B8%E5%92%8C%E4%BA%BA-ebook/dp/B00IAOPGDO
直角三角形（right triangle）「2022年 早稲田本庄高等学院 数学[1]問2」をsympyでやってみた。 

AB,BC,CA=4,5,3...

オリジナル:ますいしい様

https://ameblo.jp/mathisii/entry-12734081753.html

# sympyで(ますいしい様の手順で)
```python
from sympy import *
AB,BC,CA=4,5,3
EF=CA*Rational(AB,BC)**3
print("#[1]問2",EF)
#[1]問2 192/125
```


# sympyで(短い方の隣辺?の長さは、斜辺の長さの80%)
```python
from sympy import *
var('CA AD DE EF')
my1=Eq(CA   ,3  )
my2=Eq(AD/CA,Rational(4,5))
my3=Eq(DE/AD,Rational(4,5))
my4=Eq(EF/DE,Rational(4,5))
print("#[1]問2",my1.lhs*my2.lhs*my3.lhs*my4.lhs,"=", \
                my1.rhs*my2.rhs*my3.rhs*my4.rhs)
#[1]問2 EF = 192/125
```

# 参考
 直角三角形の直角の対辺を斜辺と言い、残りの2辺を 直角をはさむ2辺 または単に隣辺と言う。＜

https://ja.wikipedia.org/wiki/%E7%9B%B4%E8%A7%92%E4%B8%89%E8%A7%92%E5%BD%A2

https://en.wikipedia.org/wiki/Right_triangle


https://ja.wikipedia.org/wiki/%E5%9B%B3%E5%BD%A2%E3%81%AE%E7%9B%B8%E4%BC%BC

https://en.wikipedia.org/wiki/Similarity_(geometry)
UnityのAdsで広告を追加する [2022]

# 前回からの更新
https://qiita.com/aimkbiz/items/a630268f613a5cf2d833

前回、広告を実装してたら機能が追加されていて実装できなかったので、最新版で実装した際の記録を残します

# 開発環境
Unity 2021.3.9f1
Ads 4.3.0

# 前回からの変更点
・IsReadyの関数がなくなった
・Loadをする必要がある
・広告の種類が増えた(Interstitial、Rewarded、Banner)

# Ads を有効にする
・[Window]-[General]-[Services]で開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/dbd70415-7f1b-c19d-750c-0d2d67d6282f.png)

・Adsを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/35a77e56-1393-a6db-6e51-1142cfac00b2.png)

・Ads を ONにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/255d872b-109a-9b47-3ce4-a5acc314e92b.png)

・最新版のパッケージをインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/1db4b248-2343-1f6a-8502-95dac6cbfce0.png)

・Test Mode にチェック
実機にビルドする場合はTest Modeのチェックを外します
(android ios の番号は後で使います)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/a4ee3def-3a24-e177-5fb7-505bc06b7ac7.png)

・広告種類の確認。adsのダッシュボードのMonetizationのAd Unitsに表示されているidを確認します
https://unity.com/ja/products/unity-ads

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/19326500-9f4f-a44c-9bb2-fd8a38321cce.png)


・Advertisement.Initializeの部分は、先ほどadsをONにした際に表示されていたゲームidを設定する

```C#
using UnityEngine;
using UnityEngine.Advertisements;
using UnityEngine.UI;

public class AdTest : MonoBehaviour
{
    const string ANDROID_INTERSTITIAL = "Interstitial_Android";
    const string ANDROID_REWARDED = "Rewarded_Android";
    const string ANDROID_BANNER = "Banner_Android";
    const string IOS_INTERSTITIAL = "Interstitial_iOS";
    const string IOS_REWARDED = "Rewarded_iOS";
    const string IOS_BANNER = "Banner_iOS";

    [SerializeField]
    public Button BtnAdd;

    private void Awake() {
        Advertisement.Banner.SetPosition(BannerPosition.TOP_CENTER);
#if UNITY_ANDROID
        Advertisement.Initialize("9999999");
        Advertisement.Load(ANDROID_INTERSTITIAL);
        Advertisement.Load(ANDROID_REWARDED);
        Advertisement.Load(ANDROID_BANNER);
        Advertisement.Banner.Show(ANDROID_BANNER);
        Advertisement.Show(ANDROID_INTERSTITIAL);
#elif UNITY_IOS
        Advertisement.Initialize("999999");
        Advertisement.Load(IOS_INTERSTITIAL);
        Advertisement.Load(IOS_REWARDED);
        Advertisement.Load(IOS_BANNER);
        Advertisement.Banner.Show(IOS_BANNER);
        Advertisement.Show(IOS_INTERSTITIA);
#endif
        BtnAdd.onClick.AddListener(() => {
#if UNITY_ANDROID
            Advertisement.Show(ANDROID_INTERSTITIAL);
#elif UNITY_IOS
        Advertisement.Show(IOS_INTERSTITIA);
#endif
        });
    }
}
```

・作成したクラスを適切なオブジェクトに追加し、ボタンを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/45bd33a1-31d3-84b9-0ad6-fcd2f1a333b5.png)

・クリックした際、ダミーの画面が出ればOK
実機で確認する際は、テストモードの時は、Unity Remote 5の広告が表示され、テストモードを外すと本番用の広告が流れます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/4ac03cdb-8a89-3da3-6c90-19c9708aa5e4.png)
ステージした後の変更をなしにする

# ステージからチェックアウトする
```
git checkout --ファイル
```
一度ファイルをステージし、その後またそのファイルを修正したが、前にステージした内容でよかった場合に使う。
前のステージ内容の方が良かった場合になる。

### このコマンドの動きを考える
ステージされたファイルをまた変更したがステージした内容の方が良かったのでステージ後の変更内容を消して
ステージの内容をコピーして作業ツリーにペーストされる。

# 演習
```
**********@mbp ****** % vim hello.txt
```
```
Hello!
I am a student.
hogehogehogehoge!!
hogehoge!!
hogehogematuri!!!!!
```
```
**********@mbp ****** % vim hello.txt
```
```
Hello!
I am a student.
hogehogehogehoge!!
hogehoge!!
hogehogematuri!!!!!
hogehogesakujo!!!
```
```
********@mbp ****** % git checkout -- hello.txt
```
```
Hello!
I am a student.
hogehogehogehoge!!
hogehoge!!
hogehogematuri!!!!!
```
作業ツリーの内容もステージされた内容に戻されている。

# 出典　

https://www.amazon.co.jp/%E3%82%8F%E3%81%8B%E3%82%8B-Git-%E5%86%A8%E6%B0%B8%E5%92%8C%E4%BA%BA-ebook/dp/B00IAOPGDO
ｐｈｐでパスワードの単純な暗号化とハッシュ化をしてみた

　ｐｈｐで、パスワードの単純な暗号化とハッシュ化をしてみた

```php
public function passwordHash($password)
{
    $pass = 'password';
    $iv = '1234567890123456'; //16桁

    // 暗号化
    $password = openssl_encrypt(
        $password,
        'aes-256-cbc',
        $pass,
        OPENSSL_RAW_DATA,
        $iv
    );

    // Hash.
    return hash_hmac('sha256', $password, 'secret', false);
}

```

　$passwordで設定したパスワードを復号化可能な暗号で変身させハッシュ化している

　復号化出来る暗号は、パスワードと対になるランダムなデータに見えるデータで、理論上、データ単位での衝突は無いと思うので暗号化でパスワードを「変身」させ、それをハッシュ化してみた

　それぞれのパラメーターは変更可能です

後々、自分で使うと思うのでメモ。以上です
GCPのエラーメモ - vimで書き込むときの権限エラー「Cant't open file for writing」回避

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3532313831302f36623533633238312d643331382d333932312d663938612d3130346130386139653035302e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521810/858bee9c-61e5-0f65-ef19-10da599c5116.png)
Cant't open file for writingとなる場合に下記を入力している。けど他に方法あるかな？
`:w !sudo tee %`

---

→ コメントより

>そもそも開くときにsudo viで開くべきだと思います。

@bow_arrow
【メモ】extensionのwhereについて

extension内でwhereを見かけることが多く意味があまりわかっていなかったので、ここに記述する。

# whereとは？
wherをつけるとprotocolに制約をつけることが可能になる。

以下が例である。

```Swift 
protocol Caffe {
    func callCaffesName()
}

extension Caffe where Self: Starbucks {
    func starbuckIsBeautiful() {
        print("starbuckIsBeautiful")
    }
}

protocol Starbucks {
    func thisIsStarbucks()
}

class WhatCaffeIsThis: Caffe, Starbucks {
    func callCaffesName() {
        print("Starbucks")
    }

    func thisIsStarbucks() {
        print("thisIsStarbucks")
    }
}

let whatCaffeIsThis = WhatCaffeIsThis()
whatCaffeIsThis.callCaffesName()
whatCaffeIsThis.thisIsStarbucks()
whatCaffeIsThis.starbuckIsBeautiful()
```

以下がプリントされる。
```Swift
// Starbucks
//thisIsStarbucks
//starbuckIsBeautiful
```
【AWS】用語を整理しながら学ぶAWS - part8 AWS Glue

# 【AWS】用語を整理しながら学ぶAWS - part8 AWS Glue

## はじめに

この記事では Cloud Tech を通して AWS Glue(以下、Glue) を学習していく記事です。
主な内容としては実践したときのメモを中心に書きます。（忘れやすいことなど）
誤りなどがあれば書き直していく予定です。

※今回はRDSとS3の学習に[Cloud Tech](https://kws-cloud-tech.com/)を使いました

## AWS Glueとは

Glue はAWS上でETLを定義して実行できるフルマネージドなデータ分析サービスです。
AWS上で構築したデータレイクをソースとし、分析をノーコードで作成して分析を実行します。

例えば、Amazon RedshiftやAmazon S3、Amazon RDSなどのデータストア・データベース系のサービスがGlueの分析対象になります。
また、分析に必要なメタ情報の中でも例えば、データベースのカラム名やETLに必要なヘッダ情報はクローラーを使って取得します。

.oO(データレイク？ETL？クローラ？わからん用語が多い。。。)

## データレイクとは

さまざまなデータタイプを保存したリポジトリもしくはデータを集約した環境のことをデータレイクと呼びます。

AWSではデータレイクを次のように定義しています。

> データレイクは、規模にかかわらず、すべての構造化データと非構造化データを保存できる一元化されたリポジトリです。データをそのままの形で保存できるため、データを構造化しておく必要がありません。また、ダッシュボードや可視化、ビッグデータ処理、リアルタイム分析、機械学習など、さまざまなタイプの分析を実行し、的確な意思決定に役立てることができます。

[データレイクの定義](https://aws.amazon.com/jp/big-data/datalakes-and-analytics/what-is-a-data-lake/)

ざっくり言えば、データレイクとはリレーショナルデータベースやNoSQLデータベース、CSVなどの形式で保存されたテキストファイルをまとめた環境のことです。
データ分析を実行する人にとってはとても重要な環境の一つです。
データストアやデータストリームもデータレイクの一部です。

これらのデータソースをベースにデータを加工して保存してグラフに起こします。それらをETLと呼びます。

## ETLとは

Extract Transform Load の略です。
具体的には生データ(ラウデータ)を抽出して変換して特定の形式に保存することをETLと呼びます。

ETLを実行する主な目的としては`意味のある可視化を実行する為のデータを作成すること`です。

深く突き詰めると一つの記事になってしまうので今回は割愛しますが
簡単に言えば、グラフに起こす前、可視化前の抽出/加工/保存の一連の処理を表した言葉がETLです。

ETLについて説明しましたが、特定のデータに対してETLを実行する場合はデータを説明するヘッダ情報やメタ情報が必須です。
例えば、CSVだったら先頭行のヘッダ情報、データベースならスキーマの情報が必須です。
それらの情報はクローラーが取得します。

## クローラーとは

分析対象のヘッダ情報、メタ情報を取得する機能です。最近の分析ツールではSaaSにデータを連携したタイミングで自動で取得されることが多いと思われます。
クローラーで取得したデータはETLの制御に利用されます。

Web技術にもクローラーという言葉がありますが
データや画像を収集するつまりはデータを取得するという点においては同じ意味です。

Glueでデータ分析を実行する場合はクローラーを作成して実行後、クローラーの内容に合わせてETLを実行します。
ETLを実行する時、Glueではジョブという単位でETLを実行します。

## ジョブとは

ETLの実行内容を含むGlueのタスクです。スケジューリングを設定することでGlueによるETLを自動で実行できます。

## Glueの対象となるサービス

ここまでで大まかにGlueで扱う用語について述べました。

Glueは主にAWS上にあるデータレイクを対象に分析を実行できるサービスです。
分析対象となるデータソースはデータストアとデータストリームです。

- データストア
  - Amazon S3
  - Amazon Relational Database Service (Amazon RDS)
  - JDBC アクセスが可能なサードパーティのデータベース
  - Amazon DynamoDB
  - MongoDB と Amazon DocumentDB (MongoDB 互換)

- データストリーム
  - Amazon Kinesis Data Streams
  - Apache Kafka

[仕組み AWS Glue](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/how-it-works.html)より

## 注意点

使い方や要件にもよりますが、AWS上のデータレイクは
インターネットに接続されていないプライベートネットワークに設置されることもあります。

例えば、主にAmazon RDSはパブリックなネットワークに配置しません。
とりわけ、PII情報が含まれるようなDBはパブリックネットワークには置かないと思います。

こういったプライベートネットワークに配置されるRDSとGlueを接続する場合は
RDSに自己参照ルールのセキュリティグループを構築する必要があります。

それらを踏まえてRDSとGlueを接続する流れを見ていきましょう。

※[自己参照ルールを設定する](https://docs.aws.amazon.com/ja_jp/glue/latest/dg/setup-vpc-for-glue-access.html)

## GlueでETLを実行して結果を保存するまでの流れ

RDSとGlueを接続するには主に8つの工程を踏む必要があります。
もちろん、VPCが必要なサービスはGlueからVPCにアクセスできる必要があることと
先ほど述べました自己参照ルールのセキュリティグループが必要です。

1. IAMポリシーとロールを作成する
2. データソースとの接続を確立する
3. Glue上にDatabaseを作成する
4. クローラを作成する
5. クローラを実行する
6. ETLを作成する
7. ETLを実行する
8. 特定のデータストア・データベース系のサービスに出力する

## まとめ

AWS Glueは分析サービスとして優秀ではあるものの
マネジメントコンソールの画面がレガシーページとそうでないページに分かれていることもあり
非常にとっつきにくい印象があります。

しかし、ETLはUIベースでノーコード実装できるなどの面がありますのでサッと分析したい人には
良いサービスかもしれません。

## おわり
【個人開発】現役鉄道運転士が作った鉄道運転士のための情報共有アプリ


# はじめに

こんにちは@shunsuke0810と申します。
鉄道運転士をしております。
DIVE INTO CODEで4ヶ月間、未経験からWeb開発について学んでおりました。
この度卒業制作として初めて個人開発したアプリ「Trails」が完成いたしましたのでご紹介いたします。
ちなみにTrailsの由来はTrain(列車)・Rail(線路)・Rails(ruby on rails)の３つ言葉を掛け合わせました。


【Twitter】
https://twitter.com/shunsuke_start

【アプリURL】
https://hidden-sands-43685.herokuapp.com/

【GitHub】
https://github.com/Shunsuke0810/Trails

# アプリ制作のきっかけ

みなさん、駅のホームの端っこでこんな光景みたことありませんか？
![スクリーンショット 2022-08-30 20.57.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683196/821a9209-20be-dad2-4b93-c21e8ff6ef72.png)
これは乗継報告と言ってここまで運転してきた運転士が次の運転士にバトンタッチする時に情報を共有している風景なんですね。例えば

* 「この車両はブレーキの効きがイマイチです」
* 「この先◯◯の地点で雨により路面が滑りやすいです。注意して運転してください」

などなど。とても些細な情報なんですが、鉄道運転士という仕事はこう言った車両条件・天候情報など様々な不確定要素を常に考慮し運転することで、世界一と言われるほど時間に正確で安全な運行を実現しています。しかしこの乗継報告、当然１対１の口伝になってしまうので、情報がローカルになってしまったり、ログをとれない、全体で共有されないなどの問題がありました。そこで今回、この情報をオンラインで共有するためのアプリを開発したいと思い制作に至りました。

# 使用環境

* Ruby 3.0.1
* Ruby on Rails 6.0.5
* PostgreSQL 14.2

# 主な機能

【投稿機能】
発生時刻、発生内容、車両情報、位置情報等の情報を投稿できます。

![スクリーンショット 2022-09-14 12.22.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683196/a1ea7358-7647-2b38-4590-e4a01d6dac48.png)

【所属部署機能】
ユーザーを所属部署ごとにグルーピングできます。また、投稿をグループごとに表示できます。

![スクリーンショット 2022-09-14 12.21.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683196/0fdfe555-6fc5-b671-7d46-7931a334d3e2.png)


例えばこちらの画像のように中央線運転室に所属する佐藤運転士のTOP画面では、同じく中央線運転室に所属する青野運転士・遠藤運転士の投稿が一覧で表示されます。

【コメント機能】
投稿した内容にコメントができます。投稿の内容に関して社員同士でコミュニケーションが取れます。

【ブックマーク機能】
他人が投稿した内容をブックマークできます。自分の業務に関連する内容の投稿等を保存できます。

# 特に力を入れたポイント

GeocordingAPI,MapsJavaScriptAPIを使用し、投稿内容に位置情報を盛り込みました。ピンのドラックも可能なので住所の割り振られていない不特定の位置情報も投稿可能です。
例えば、運転中に三鷹〜吉祥寺駅間での踏切の不具合を発見した情報を投稿したい場合、以下のような動きになります。

![ezgif-2-27d238b96c.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2683196/562ed50b-3988-b3bc-a390-5e4f8d6ad87d.gif)

# 最後に

ここまでご覧いただきましてありがとうございました。
DIVE INTO CODEで学習した4ヶ月間はとても充実しており、メンターのみなさん、同期生のみなさんに何度も助けられました。サポートいただいたみなさん本当にありがとうございました。
また現場の課題解決をテーマにした今回の開発を通じ、顧客に寄り添い課題を解決できるエンジニアになりたいという目標ができました。
まだまだ未熟者ではありますが、ここをスタートに精進して参ります。
スクレイピング時のエラーメモ「surrogates not allowed」 - 異体字セレクタ(IVS)の削除

# 背景
スクレイピングしたデータをBQにアップロードする。
そのために改行区切りのJSONを作る。
その際、余計な文字が混入していることでエラーが発生した。

# エラー内容
対象の文字列
`...\udb40\udd00\u539f...`

エラー内容
`UnicodeEncodeError: 'utf-8' codec can't encode characters in position 40-41: surrogates not allowed`

# なんぞこれ？
`\udb40`や`\udd00`は異体字セレクタという微妙な字形を区別するための文字コードだった。
`surrogates not allowed`とのことなのでこれらを無くせば良いっぽい。

# 削除すべき文字コードを一覧化した

https://sheilart.github.io/Azure-Alphant/surrogates.html
これ使えそうだから一覧化してみよう..2048件..なんか多いな
```console.js
const elms = Array.from(document.querySelectorAll('article'));
elms.map((elm)=>{
    return elm.querySelector('p:nth-child(6)').textContent;
})
```

例外的な事象ぽいし、ここまでいらないや。一旦その場しのぎでこの人の判別してるやつをパクろう
[IVSのセレクタ文字判別用のクラスを作ってみた](https://opcdiary.net/ivs%E3%81%AE%E3%82%BB%E3%83%AC%E3%82%AF%E3%82%BF%E6%96%87%E5%AD%97%E5%88%A4%E5%88%A5%E7%94%A8%E3%81%AE%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F/)

```
\uDB40
\uDD00
\uDDEF
\uFE00
\uFE0F
\u180B
\u180d
```
# 文字コードを削除した
このメソッドで削除後のテキストを得る
```text_cleansing.py
import re

def remove_surrogates(text: str):
    return re.sub('\udb40|\udd00|\uddef|\ufe00|\ufe0f|\u180b|\u180d', '', text)
```

# 備考：代替策
その後メンテナンスが面倒そうだったので ↓ で対応した。
```python
    def to_unicode(text:str):
        return unicodedata.normalize("NFKC", text)
```
## 参考
[文字って何かね？>異体字セレクタ(IVS)](https://qiita.com/matarillo/items/91b9656428bed7a1a797#%E7%95%B0%E4%BD%93%E5%AD%97%E3%82%BB%E3%83%AC%E3%82%AF%E3%82%BFivs)
[異体字セレクタってなあに](https://qiita.com/wingsys/items/ca0d791b585475ba2052)
[Unicodeエスケープシーケンスを変換したい](https://teratail.com/questions/2x3h885gvehyyb)
[surrogates](https://sheilart.github.io/Azure-Alphant/surrogates.html)
[charbase](https://charbase.com/db40-unicode-invalid-character)
[IVSのセレクタ文字判別用のクラスを作ってみた](https://opcdiary.net/ivs%E3%81%AE%E3%82%BB%E3%83%AC%E3%82%AF%E3%82%BF%E6%96%87%E5%AD%97%E5%88%A4%E5%88%A5%E7%94%A8%E3%81%AE%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F/)
[Unicodeエスケープシーケンス変換ツール](https://tech-unlimited.com/escape-unicode.html)
z.requestのGETで配列パラメータを送る方法

この記事は移行しました！[最新の内容はこちら](https://naoqoo2.github.io/blog/z.request%E3%81%AEGET%E3%81%A7%E9%85%8D%E5%88%97%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%82%92%E9%80%81%E3%82%8B%E6%96%B9%E6%B3%95/)をご覧ください😀


zapier platform で Actions を設定している際、
GetのAPIに配列パラメータを渡したくてハマったのでメモ。

## 試行錯誤メモ

`hogehoge?sort_by[]=id` のように送りたい。

### Input Designerではkeyに`[]`を指定できず。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56789/1e82e7dc-6b94-35ac-4175-0f39e6f299e1.png)


### `params` では配列を送れない。。

```js
const options = {
  url: 'hogehoge',
  method: 'GET',
  headers: {
  },
  params: {
    'page': bundle.meta.page + 1,
    'per_page': '50',
    'sort_by': ['id'],
    'sort_direction': ['desc']
  }
}

return z.request(options)
```

ベタ書きで検証してみたが `hogehoge?sort_by=id` になってしまう。
※実際は `  'sort_by': bundle.inputData.sort_by` としたい。ゴニョゴニョ書けばいけるのかも？

 
## 結論

### body で渡した

`body` で渡す。
そしてGetメソッドに対し、`body` を有効にするには
`allowGetBody: true`
を指定する必要がありました。

```js
const options = {
  url: 'hogehoge',
  method: 'GET',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  },
  allowGetBody: true,
  body: {
    'per_page': bundle.inputData.per_page,
    'page': bundle.inputData.page,
    'sort_by': bundle.inputData.sort_by,
    'sort_direction': bundle.inputData.sort_direction
  }
}

return z.request(options)
```

### 設定メモ

配列の場合はAllows Multiplesにチェック
例）bundle.inputData.sort_by が配列となる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56789/7e89587c-5386-8995-48ac-2f2289fb31fe.png)


## 参考
https://community.zapier.com/developer-discussion-13/send-body-with-get-using-z-request-5881
単語のさまざまな役割

単語はそれぞれの役わいrに応じた品詞に分類される。

# 名詞
人名や地名、人や物を表し、主語や補語などになります。
### 加算名詞
一つ２つと数えることができる名詞
これには冠詞に```a```、```an```がつく。

### 不加算名詞
一つ二つと数えることができない名詞

# 動詞
```主語の動作や状態```を表します。
```主語の後ろに置く。```

# 形容詞
```名詞の状態や性質```を表します。```名詞の前に置いて```その名詞を修飾したり、```補語になったり```します。

# 副詞
```
always（いつも）
very(とても)
well(上手に）
```

```程度や頻度```などを表し、主に```動詞、形容詞、副詞などの語句や文を修飾```する。
英文の中では```さまざまな位置に置かれます```。

# 代名詞
```
I（私は）
it（それは、それを)
her（彼女の＜を・に＞)
```
```一度英文に登場した名詞の代わり```に使う。

# 助動詞
```
can（することができる)
must(〜しなければならない)
may（〜かもしれない、〜してもよい)
will（〜するつもりだ、〜するだろう）
```
```動詞の前に置かれ```、話し手の気持ち、考えなどをつけ加える。

# 前置詞
```
at（<時刻>に、<場所>で）
for(~に向かって、~のために)
to（〜まで、~へ）
```
```名詞の前に置かれ```、場所、時、方向などを表す。

# 接続詞
```
because（なぜなら〜）
when(~するとき)
but（しかし）
```
```節（主語＋動詞＋α)や単語、語句```などをつなぎます。

# 冠詞
```
a/an(一つの)
the（その）
```
名詞の前に置かれる

# 疑問詞
```
what（何）
who（誰）
how（どのように)
```
```疑問文の文頭に置い```て使われます。

## 気づき
これら品詞の役割と位置を意識しながら英文を書いたり、聞いたりするのか。
冠詞や前置詞は苦手だ。

# 出典　

https://kanki-pub.co.jp/pub/book/details/9784761230227
関数宣言、関数実行について

関数宣言とは
→ 指定された引数を使用して関数を定義する。

関数実行とは
→指定した引数を用いて実際に指定された動作を実行する。



//基本①
関数宣言する


console.logで「Hello!」と表示する関数を作ってください
```javascript

//動きの流れ①〜④
関数宣言

   function aisatsu(){  //②
        console.log("Hello");  //③
        }
```

```javascript
関数実行
関数を実行する
   aisatsu();  //①④
   // Hello

```

備考
検証ツールのconsole.logにて確認する
引数の名前は自由に変更できる。





基本②　引数１つの場合

aisatsu関数に引数を１つつけて、”Hello”の後ろに引数を文字列連結してください。
　
引数に”太郎”を入れてaisatu関数を実行してください。

```javascript

   function aisatsu(Text){  // ②
        console.log("Hello" + Text);  //③
        }

```

```javascript

        aisatsu("太郎");  // ①④
        //A Hello 太郎

```


基本③　引数２つの場合

 引数num1とnum2を受け取り、その足した値をreturnする関数宣言をしてください。
 引数に５と８を入れて実行し変数addに格納してください。
 変数addをconsole.logで表示してください。


```javascript
関数宣言
        function addnumber(num1, num2){  // ③
        return num1 + num2;  // ②
        }

```

```javascript
関数実行


       const add = addnumber(5,8);  // ①④
        console.log(add);  // ⑤

```

基本④  引数が３つの場合

 引数num1とnum2を受け取り、その足した値をreturnする関数宣言をしてください。
 引数に５と８を入れて実行し変数addに格納してください。
 変数addをconsole.logで表示してください。
addnumber関数にnum3引数を一つ足して、
　num1,num2を足した後に掛け算する関数に改造してください
```javascript

  function addnumber(num1, num2, num3){  // ③

        return ((num1 + num2) * num3);  // ②
        }

```

```javascript

        const add =addnumber(5,8,2);  // ①④
        
        console.log(add);  // ⑤  26

```
class-validatorでカスタムバリデータ定義


class-validatorで「`null`だけ」とか「`undefined`だけ」のような独自のバリデーションを実装したい場合に、カスタムバリデータ（カスタムデコレータ）が使えますという備忘録です。

## 前提

動作確認時の`class-validator`のversionは以下の通りです。
class-validator: v0.13.2

## 課題: nullとundefinedを個別に判定したい

### IsOptional

`@IsOptional()`を使うと、`null`と`undefined`の場合両方許容してしまいます。

参考： https://github.com/typestack/class-validator#validation-decorators の`@IsOptional()`

そのため、以下のようなケースでうまいこと`class-validator`が機能しません。困った。

```ts
// nullableだけどundefinedではない
nullableString: string | null

// optionalだけどnullではない
optionalString?: stirng;
```

### ValidateIf

特定条件を満たす場合にのみバリデーションするという条件を`ValidateIf`で付加できます。

参考: https://github.com/typestack/class-validator#conditional-validation

従って、例えば上記の`optionalString`に対するバリデーションで`undefined`のみを許容したい場合、

```ts
@ValidateIf((_, value) => value !== undefined)
optionalString?: string;
```

と書けます。`@ValidateIf(...)`をカスタムデコレータとして定義しておけば、

```ts
const IsUndefinedable = () => {
  return ValidateIf((_, value) => value !== undefined)
}

~~~

@IsUndefindable()
optionalString?: string;
```

のように書けて便利です。

## 結論

`ValidateIf`デコレータは便利です。

余談ですが、ValidateIfの第一引数では、当該ValidateIfが定義されている対象オブジェクトのプロパティを参照できるようなので、公式の例にあるように、別プロパティを使って条件組むことも可能です。

```ts
// https://github.com/typestack/class-validator#conditional-validationから引用
import { ValidateIf, IsNotEmpty } from 'class-validator';

export class Post {
  otherProperty: string;

  @ValidateIf(o => o.otherProperty === 'value')
  @IsNotEmpty()
  example: string;
}
```
KotlinのMapのキーの挙動

このコードだとMapのキーにListを持ったdata classを使った場合にvalueが見つからず、nullが帰ってくる

``` kotlin
data class Item(
    val name: String,
    val value: List<Int> = emptyList(),
) {
    override fun equals(other: Any?): Boolean {
        if (other !is Item) return false
        return other.name == this.name
    }
}

fun main() {
    // true
    println(Item("test") == Item("test"))
    // false
    println(Item("test") === Item("test"))
    // true
    println(Item("test", listOf(1)) == Item("test"))
    // true
    println(Item("test", listOf(1)) == Item("test", listOf(2)))
    
    val map = mapOf(Item("test", listOf(1)) to 1, Item("test2") to 2)
    // null
    println(map[Item("test")])
    // 1
    println(map[Item("test", listOf(1))])
    
}
```

data classの比較にhashCodeもoverrideすると正しくmapのgetが返ってくるようになる

``` kotlin
data class Item(
    val name: String,
    val value: List<Int> = emptyList(),
) {
    override fun equals(other: Any?): Boolean {
        if (other !is Item) return false
        return other.name == this.name
    }
    
    override fun hashCode(): Int {
        return name.hashCode()
    }
}

fun main() {
    // true
    println(Item("test") == Item("test"))
    // false
    println(Item("test") === Item("test"))
    // true
    println(Item("test", listOf(1)) == Item("test"))
    // true
    println(Item("test", listOf(1)) == Item("test", listOf(2)))
    
    val map = mapOf(Item("test", listOf(1)) to 1, Item("test2") to 2)
    // 1
    println(map[Item("test")])
    // 1
    println(map[Item("test", listOf(1))])
    
}
```
SKKの送り仮名でcをkと同じように扱えるようにする

# SKKの送り仮名でcをkと同じように扱えるようにする
## 背景

Dvorak+SKK環境だとkよりもcの方が入力しやすいので、ca->かのようにか行をcに割り当ててる人が多いです(独自研究)。
しかし、漢字変換の際の送り仮名入力ではcを使うとうまく変換できないことが多いです。  
例: あじけなCi

これは、送り仮名を最初に入力されたキーのみで判定しているためCかKかで結果が変わってしまうことが原因です。
このため、折角k->cにしたのに正しく変換できないということが起きてしまいます。

なのでこれをなんとかしました。

## 解決策
### in Linux, uim-skk
設定で対応できなさそうだったので辞書ファイルから送り仮名kのものを全てcにも対応させました。
nkfが必要ですが、以下のコマンドで送り仮名cに対応した辞書が生成できます。  

```bash
cat SKK-JISYO.L | nkf | grep 'k /' | grep -v '^[0-9a-zA-Z\-]* /' | sed 's|k /|c /|g' | nkf -e > SKK-JISYO.k2c
```

あとはskkdic-expr2などを使って辞書を統合すれば完成です。
uimの設定から統合した辞書を設定して再起動すれば有効になります。

### in Windows

~~DvorakJ+CorvusSKKならDvorakJで日本語入力のときのキー配列を変更すれば対応できます。~~

なぜか変換中だと正しくできなくなってしまっていたので別の方法で実現しました。
おそらく日本語入力用配列にShift同時押しの場合のキーマップがないためKが入力されてしまうことが原因だと思われます。
DvorakJの編集メニューから日本語入力用配列の設定ファイルを開いて変更し、保存すれば実現できます。
今回は直接入力用配列のものをそのままコピペし、C->Kと変更しました。
React chakura ui のmodalが閉じなくなった時の対処法 

    "framer-motion": "^7.2.0”をpackage jsonに追加してyarn install

メモ：React 18.0.0 でChakraUIのModalを閉じると他の要素がクリックできなくなった
https://chihaso.hatenablog.com/entry/2022/04/08/201155
と同様の現象？

chakura ui でmodalを使用しようとしたら、エラーは起きなかったが、モーダルが閉じなくなった
（具体的には、見た目が消えるが、バックにモーダルが残っている感じがする、というか残っている）

https://github.com/chakra-ui/chakra-ui/issues/5321
英語版ですが、上記のリンクに解決が載ってます

結論
- 依存関係と推移的な依存関係のyarn upgrade削除と比較の実行node_modules
- fromer_motionのいくつかのバージョンを試す

```
僕の場合は
package.jsonに
 "framer-motion": "^7.2.0",//(色々バナバージョンを試してみる)
を適当に書いて

yarn installを実行
```


framer-motion
をyarn installしたら治る理由はまた今度調べる予定です
【夏休み企画】#IT用語一問一答【毎朝投稿21日目】KPI

# この記事を読むと、、
- 「関連用語」を使って「KPI」を説明できるようになる
- 「KPI」がもっと好きになる(多分)

# 関連用語
KGI / BSC

[**復習用**] 記事の内容を見る前に上記の言葉で「KPI」を説明してみよう！

# 企画説明
- クラウドって何？って人に聞かれて説明してるけど俺もよく知らないや、、
- ドキュメント読んでみてるけど半分くらい何言ってるか分かんない、、
- 今日の夕飯はナスの炒めものにしよっかな〜、あれ、NASってなんだっけ？

みたいなことが結構あったので、知ったかしていたIT用語を毎日一個ずつちゃんと学んでいこうっていう企画です！

昨日の記事はこちら↓

https://qiita.com/acta/items/1361188c1957aeac209e

# KPIとは
KPI = Key Performance Indicator = 重要業績評価指標 = 組織の目標における達成度合いを定量的に測るための指標

- KGIを達成するために必要な小目標として、KPIの達成を設定する
    - cf. **KGI** = Key Goal Indicator = 長期的なビジネス目標における達成度合いを定量的に図るための指標
    - ex. 雑貨店の場合
        1. 4月から半年以内に1000万儲けたい！ (ビジネス目標)
        1. 上半期の収益を監視しよう (KGI)
        1. KGIを達成するためには毎日XX人のお客がきて、YY円くらい落としてほしいなぁ
        1. 来客数と平均購入金額を監視しよう (KPI)

- KPIの選定には例えばBSCが用いられる
    - cf. **BSC** = Balanced Score Card = 財務・顧客・業務プロセス・学習と成長の4つの視点で業績を評価する手法

# 参考資料
- https://en.wikipedia.org/wiki/Performance_indicator
- https://en.wikipedia.org/wiki/Balanced_scorecard
Service　Portalの画面でreference項目を使用する場合の注意点

<h1>概要</h1>
本記事ではService Portalでrefelence項目を使用した際にハマった点を共有します。

`環境`
Version:San Diego
Role:System Administrator（admin）

<br>
<br>
<br>


<h1>①Ajaxでテーブルから値を取得したreference項目の表示</h1>

 Service Portal画面ロード時にrefelence項目に過去の入力済データをGlideAjaxで表示した際に値ではなくsys_idが表示されてしまった。
<br>
↓対応

●Script Include
reference項目はsysidとdisplayvalueの両方を取得する
```javascript
    result = {"r_ref_sysid" = : GlideRecord.getValue("db_reference_val"),
              "r_ref_val" = : GlideRecord.getDisplayValue("db_reference_val")}:
    return JSON.stringify(result);   
```

<br><br>

●Catalog Client Script
画面への設定は第二引数にsysid、第三引数にdisplayvalueを設定する
```javascript
    g_form.setValue("ServicePortal_field",result.r_ref_sysid,result.r_ref_val);
```

<br><br><br>

<h1>②reference項目にFunction fieldを適用した場合の挙動</h1>
テーブルにreference項目を作成した際に、関数フィールドを適用させると、実行時にエラーが表示される。


![qiita用functionfield.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2842912/c0f66087-a943-a4ba-41fd-38fe6975f31b.png)


原因：Service Nowの不具合、現時点(2022/9/14)では改修予定未定
参考：https://support.servicenow.com/kb?id=kb_article_view&sys_kb_id=9241e60adb0e2744f21f5583ca961945
firewalldを使ってポートフォワーディングする備忘録

# 何がしたいか
タイトルの通りfirewalldでポートフォワーディングする

# 環境
Rocky Linux 8

# 事前準備
`/etc/sysctl.conf`に以下を追記しポート転送できるようにする

```
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
```

`sudo sysctl -p`を実行し設定を適用


# 設定方法
```
# 転送したいポートを設定（転送先アドレスを省略するとlocalhostへ転送される）
sudo firewall-cmd --add-port=[転送元ポート]/tcp --zone=public
sudo firewall-cmd --add-forward-port=port=[転送元ポート]:proto=tcp:toport=[転送先ポート]:toaddr=[転送先IPアドレス] --zone=public

# 各種許可設定
sudo firewall-cmd --zone=public --add-masquerade --permanent
sudo firewall-cmd --zone=public --add-forward --permanent

# 設定永続化
sudo firewall-cmd --runtime-to-permanent

# 設定適用
sudo firewall-cmd --reload
```

# まとめ
iptalesを直接弄らなくてもポートフォワーディングできるのはかなり便利。Wireguardと併用しても良さそう。
サポートするWidgetFamilyをiOSのバージョンによって変える

サポートするWidgetの種類をiOS16以降と未満で分けたいときは
```swift
if #available(iOSApplicationExtension 16.0, *){
            //ios16以降の処理
   }else{
            //ios16未満の処理
 }
```
だいたいこの書き方でわけれるのだけれど、
```swift
struct myWidget: Widget {
    let kind: String = "myWidget"
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind,  provider: Provider_relative()) { entry in
            fcwidgetEntryView_relative(entry: entry,timerState: TimerState_Ja(rawValue: entry.timerState)?.ToString ?? "", deadLineInerval: entry.timeInterval )
        }
        .configurationDisplayName("Mywidget")
        .description("いろいろ表示します")
        .supportedFamilies([.accessoryRectangular,
                            .accessoryCircular,
                            .systemSmall] )
    } 
}
```
Widgetの中枢のこのビュー？だけは
if #available(iOSApplicationExtension 16.0, *)でStaticConfigurationをまるごと分岐しようが、@available(iOSApplicationExtension 16.0, *)を使おうがエラーがでます。なので別で関数を作ってはめれば通ります。
```swift
// これをどっかいに書いといて
func supportWidgetFamily() -> [WidgetFamily]{
        if #available(iOSApplicationExtension 16.0, *){
            return [.accessoryRectangular, .accessoryCircular, .systemSmall]               }
        else{
            return [.systemSmall]
        }
    }

struct myWidget: Widget {
    let kind: String = "myWidget"
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind,  provider: Provider_relative()) { entry in
            fcwidgetEntryView_relative(entry: entry,timerState: TimerState_Ja(rawValue: entry.timerState)?.ToString ?? "", deadLineInerval: entry.timeInterval )
        }
        .configurationDisplayName("Mywidget")
        .description("いろいろ表示します")
        .supportedFamilies(supportWidgetFamily())//ここに入れる
    } 
}
```
これでiOS16にはロック画面ウィジェットを出しつつ、iOS15にはホーム画面ウィジェットを出せます。
ファイル アップロード フローの権限

元の質問 : [File Upload Flow Component working for some internal profiles but not others, even when run in 'system context without sharing' mode.](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000JdVbO)


ファイル アップロード フロー コンポーネントは、「共有なしのシステム コンテキスト」モードで実行されている場合でも、一部の内部プロファイルでは機能しますが、他のプロファイルでは機能しません。

画面フローの 1 つを更新して、ファイル アップロード コンポーネントを含めました。

画面フローは、ユーザーがヘルプ リクエスト (カスタム オブジェクト) を送信できるように設計されており、ファイル コンポーネントは、レコードの作成後に表示される新しい別の画面にあり、新しく作成されたレコードにファイルをアップロードするオプションをユーザーに提供します。 

ただし、一部のユーザーはコンポーネントを使用してファイルをアップロードできません。これらは内部ユーザーであり、ゲスト サイトやコミュニティ ユーザーではありません。本当に奇妙なのは、フローをデバッグ モードで実行し、[別のユーザーとしてフローを実行] を選択すると、すべて正常に動作することです。

しかし、ユーザーとしてログインしてフローを実行しようとすると、ファイルのアップロードが失敗します。

# 回答

ファイル アップロード コンポーネントは扱いにくいものです。これについて確認したとは言えませんが、フロー自体がどのように構成されているかに関係なく、常に API を介して実行されるため、常にユーザーの資格情報の下で実行されると感じていました。

レコードに対してファイルをアップロードするには、ユーザーが最初にそのレコードにアクセスできる必要があると思います。フローが共有なしで実行されているが、API を使用しているためコンポーネントがそれを無視している場合、それが原因です。テスト ユーザーに [すべて表示] または [すべて変更] アクセス権を付与して、変更があるかどうかを確認してください (もちろん、サンドボックスのように制御された方法で)。
なぜか、STM32G071が当たった、よって、Lちか(準備中)(Keil Studio)

中身は、まだない
明日、がんばる


![o_con750.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4a6a38dc-dc56-9a95-3d67-36b7bf3e0bd1.jpeg)


![o_con749.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/defc643c-a09b-4603-b7bb-8d828041ef65.jpeg)


![o_con748.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b86c4862-70d6-e50c-e534-ddf4a05c7c87.jpeg)



```c++


/* mbed Microcontroller Library
 * Copyright (c) 2019 ARM Limited
 * SPDX-License-Identifier: Apache-2.0
 */

#include "mbed.h"


// Blinking rate in milliseconds
#define BLINKING_RATE     500ms


int main()
{
    // Initialise the digital pin LED1 as an output
    DigitalOut led(LED1);

    while (true) {
        led = !led;
        ThisThread::sleep_for(BLINKING_RATE);
    }
}


```
Unity Catalogのデータリネージのパブリックプレビューの発表

[Announcing Public Preview of Data Lineage in Unity Catalog \- The Databricks Blog](https://www.databricks.com/blog/2022/09/12/announcing-public-preview-data-lineage-unity-catalog.html)の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

本日、AWSとAzureで利用できる[Unity Catalog](https://www.databricks.com/jp/product/unity-catalog)のデータリネージ機能のパブリックプレビューを発表できることを嬉しく思っています。

前回の[アナウンスの記事](https://qiita.com/taka_yayoi/items/679b71fc425481b5359c)では、レイクハウスにおいて効率的なデータガバナンスツールとしてチームがどのようにデータリネージを活用するできるのかを議論しました。この記事では、本リリースにおけるキーとなる機能のいくつかと、Unity Catalogでデータリネージを活用できるのかを探索し、リネージに関するロードマップの一部を見ていきます。

今ではAWSとAzureで利用できるUnity Catalogは、すべてのクラウドのレイクハウスにおけるすべてのデータ、AIの資産に対する統合ガバナンスソリューションを提供します。Unity Catalogにおける自動データリネージによって、データチームはコンプライアンス要件のためにセンシティブなデータをトラッキングし、データ品質を保証し、レイクハウスにおけるデータ変更のインパクト分析を行えるようになります。リネージは、Unity Catalogにアタッチされたすべてのワークスペースで集約されます。これは、あるワークスペースでキャプチャされたリネージは、同じメタストアを共有するすべてのワークスペースで参照できることを意味します。

# パブリックプレビューによって利用できるようになるキーのデータリネージ機能

**すべての言語のすべてのワークロードに対するリネージ**: Unity Catalogは、自動ですべての言語(Python、SQL、R、Scala)や実行モード(バッチ、ストリーミング)で実行されたクエリーによるデータリネージを追跡します。数クリックでリネージグラフがリアルタイムで表示されます。

**ノートブック、ワークフロー、ダッシュボードに対するリネージ**: また、Unity Catalogはノートブック、ワークフロー、ダッシュボードのリネージもキャプチャします。これによって、あなたの組織においてデータがどのように使用されているのかに関して、エンドツーエンドの可視性を持ち、データの変更による後段の利用者に対するインパクトを理解する助けになります。

**ビルトインのセキュリティ**: リネージグラフは、Unity Catalogの共通アクセス権モデルを活用します。ユーザーはリネージデータを参照するための権限を必要とし、いかなるデータ漏洩のリスクを最小化し、追加のセキュリティレイヤーを追加しています。ユーザーがテーブルに対するSELECT権限を持たない場合、そのテーブルに関連づけられているリネージを探索することはできません。さらに、ユーザーは参照できる権限を持っているノートブック、ワークフロー、ダッシュボードのリネージ情報を参照することができます。

**カラムレベルの粒度**: Unity Catalogはテーブル、ビュー、カラムのデータリネージをキャプチャします。この情報によって、数クリックでデータチームにレイクハウスの特定のテーブルやカラムに対して、前段・後段にどのようにデータが流れているのかに関して、きめ細かなビューを提供します。

**REST API経由で容易にエクスポート**: 他のデータカタログやガバナンスソリューションとのインテグレーションをサポートするために、リネージ情報をREST API経由で取得することができます。

# Unty Catalogでデータリネージを使い始める

Unity Catalogにおけるデータリネージ機能に関する詳細については以下のデモをご覧ください。
<iframe width="560" height="315" src="https://www.youtube.com/embed/QPte6wmC4vQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

データリネージはDatabricksのプレミアム、エンタープライズプランで追加コストなしに利用することができます。すでにDatabricksを利用されているのであれば、スタートするにはデータリネージのガイド([AWS](https://docs.databricks.com/data-governance/unity-catalog/data-lineage.html) | [Azure](https://docs.microsoft.com/azure/databricks/data-governance/unity-catalog/data-lineage))をご覧ください。Databricksをまだ利用されていないのであれば、プレミアム、エンタープライズプランのフリートライアルに[サインアップ](https://databricks.com/jp/try-databricks)してください。

# 次に来るものは

これは始まりに過ぎません。我々はレイクハウスにおけるデータリネージのシームレスなデータ観測性やデータ品質に対するビジョンを実現するために、エキサイティングな新機能に取り組んでいます。

**ファイルのリネージ:** クラウドストレージのファイルへのリネージの追跡。これは特にファーストマイルのETLユースケースで有用です。

**コンテキスト内のリネージ:** 失敗のインパクトをクイックに理解する特定のワークフローに対するリネージを参照するなど、最も適切な場所でリネージを参照し、アクションを取ります。

**システムテーブルとしてのリネージ:** お好きな言語を用いてリネージのデータにクエリーを実行するために事前定義済みのシステムテーブルに対して、プログラムからアクセスします。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Incorrect parameter type for function 'CONTAINS()'. Expected Text, received Object. 


元の質問 : [Problems with Formula in a Report](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000JdSORSA3)

**Incorrect parameter type for function** 'CONTAINS()'. **Expected Text, received Object.**

太字のところはSummary-Level Formula Columnにフィールドを追加した時によくあらわれるエラーですね。
RowCountやSUMでないとObjectとして扱われてしまっていてエラーになったのかよく分かりません。

しかし、ここでは設定できないでしょう。

以下のようにまずはRow-Level Formula Columnで文字を数値に変換してから、数値をSummary-Level Formula Columnで使います。
ただしSummary-Level Formula Columnではレコード数だけ掛け算されているので元の数値にするためにレコード数で割り算します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f00631b2-5352-5229-77be-b872c89f31e8.png)


Row-Level Formula Column

```
CASE(formula3__c.textDate__c,
"January",31,
"February",28,
"March",31,
"April",30,
"May",31,
"June",30,
"July",31,
"August",31,
"September",30,
"October",31,
"November",30,
"December",31,
30)
```


Summary-Level Formula Column

```
CDF1:SUM/RowCount
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/4d45ceb9-bf2b-78cf-d127-e1444a5148be.png)
速報：調査中：Ubuntu18.04でMOZC UT２のビルドができなくなっていた

今、GNOME Boxesを使い、Ubuntu18.04をインストールしました。
今まで通り、下記の記事でMOZC UT2をインストールを試みました。

https://sicklylife.jp/ubuntu/1804/mozc_ut2.html

でも、エラーが出ました。
エラーの内容です。

```bash
  File "/ダウンロード/mozc-2.23.2815.102+dfsg~ut2-20171008d+20200423/mut/src/build_tools/util.py", line 99, in RunOrDie
    '==========']))
build_tools.util.RunOrDieError: 
==========
 ERROR: ninja -C out_linux/Release ibus_mozc mozc_emacs_helper mozc_server mozc_tool mozc_renderer uim-mozc fcitx-mozc
==========
debian/rules:36: recipe for target 'override_dh_auto_build' failed
make[1]: *** [override_dh_auto_build] Error 1
make[1]: ディレクトリ '/ダウンロード/mozc-2.23.2815.102+dfsg~ut2-20171008d+20200423/mut' から出ます
debian/rules:28: recipe for target 'build' failed
make: *** [build] Error 2
dpkg-buildpackage: error: debian/rules build subprocess returned exit status 2
debuild: fatal error at line 1152:
dpkg-buildpackage -rfakeroot -us -uc -ui -b -d failed
/ダウンロード/mozc-2.23.2815.102+dfsg~ut2-20171008d+20200423
終了
```

今お客様からの依頼の仕事をしないといけないので、時間を見つけて調査したいと思います。
とりあえず速報で、書きました。
vueでmp3ファイルを再生したい時のエラー対処と型定義について（TypeScript）

「srcフォルダってどこ？」ってなったのと、
参照元のブログがなくなってしまうと困るのでメモさせていただきます。

nuxt.config.ts 内に下記を記述
```
（略）
build: {
    extend(config: any, _: any) {
      config.module.rules.push({
        test: /\.(ogg|mp3|wav|mpe?g)$/i,
        loader: 'file-loader',
        options: {
          name: '[path][name].[ext]'
        }
      })
    }
  }
（略）
```

srcフォルダ （つまりプロジェクトの直下の第一階層 nuxt.config.ts と同階層） に
`@types` というディレクトリを作成して `audio.d.ts`（名前はなんでもOK） というファイルを作成。

audio.d.ts 内に下記を記述
```
declare module '*.mp3';
```

```
import sound from '~/assets/sounds/sample.mp3'

（略）

const audio = new Audio(sound)
audio.play()
```

参考にさせていただいた記事

https://remoter.hatenablog.com/entry/2020/04/14/Nuxt%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%A7mp3%E3%82%92%E5%86%8D%E7%94%9F%E3%81%99%E3%82%8B

https://note.com/masato1230/n/n97e2d57690ca

https://www.web-dev-qa-db-ja.com/ja/javascript/vuejs%E3%81%A7%E3%82%B5%E3%82%A6%E3%83%B3%E3%83%89%E3%82%92%E5%86%8D%E7%94%9F%E3%81%99%E3%82%8B/831052767/

ありがとうございます！
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その023

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: アプリケーションと活動
セールスアプリケーションとマーケティングアプリケーションの確認

にある練習問題3問目をご紹介します。
https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-applications-activities-and-mobile/review-sales-and-marketing-applications?trail_id=administrator-certification-prep

今回の内容は動画でも公開されています


https://www.youtube.com/watch?v=6JOWYdv6ElA


問題はこちらです

![023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/a79d4961-538f-9551-4e06-a560fec504c9.png)


答えはAとDですね


ポイントは２つあります

まず今回所有者を個人ではなくて「営業チーム」なのがポイントですね


チームなのでキューが必要です

割り当てルールやキュー作成方法については動画をご確認ください


<iframe width="560" height="315" src="https://www.youtube.com/embed/6JOWYdv6ElA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
vistaでandroid studio その22

# 概要
vistaでandroid studio 1.1.0やってみた。
jniやってみた。
練習問題やってみた。

# 練習問題
jniでログを吐け。

# サンプルコード

```
#include <jni.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <android/log.h>

JNIEXPORT jstring JNICALL Java_com_ohisamallc_ohiapp154_ohiapp154_MainActivity_hello(JNIEnv * env, jobject thiz) {
    char buf[456];
    const char * s0 = "ズン ";
    const char * s1 = "ドコ ";
    const char * s2 = "ドコ キヨシ！！";
    int i = 0;
    int n = 0;
    while (i == 0)
    {
        if ((rand() & 1) > 0)
        {
            strcat(buf, s1);
            n = 0;
        }
        else
        {
            strcat(buf, s0);
            n++;
        }
        if (n == 4)
        {
            strcat(buf, s2);
            break;
        }
        __android_log_print(ANDROID_LOG_ERROR, "ohi", "Hello %d", n);
    }
	return (* env)->NewStringUTF(env, buf);
}


```

# Android.mk

```
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)

```

# 実行結果

```
09-14 05:04:52.408    6324-6356/com.ohisamallc.ohiapp154.ohiapp154 D/OpenGLRenderer? Render dirty regions requested: false
09-14 05:04:52.486    6324-6324/com.ohisamallc.ohiapp154.ohiapp154 D/Atlas? Validating map...
09-14 05:04:52.767    6324-6356/com.ohisamallc.ohiapp154.ohiapp154 D/libEGL? loaded /system/lib/egl/libEGL_tegra.so
09-14 05:04:52.782    6324-6356/com.ohisamallc.ohiapp154.ohiapp154 D/libEGL? loaded /system/lib/egl/libGLESv1_CM_tegra.so
09-14 05:04:52.818    6324-6356/com.ohisamallc.ohiapp154.ohiapp154 D/libEGL? loaded /system/lib/egl/libGLESv2_tegra.so
09-14 05:04:52.851    6324-6356/com.ohisamallc.ohiapp154.ohiapp154 I/OpenGLRenderer? Initialized EGL, version 1.4
09-14 05:04:52.860    6324-6356/com.ohisamallc.ohiapp154.ohiapp154 D/OpenGLRenderer? Enabling debug mode 0
09-14 05:04:55.102    6324-6324/com.ohisamallc.ohiapp154.ohiapp154 E/ohi? Hello 1
09-14 05:04:55.103    6324-6324/com.ohisamallc.ohiapp154.ohiapp154 E/ohi? Hello 2
09-14 05:04:55.103    6324-6324/com.ohisamallc.ohiapp154.ohiapp154 E/ohi? Hello 0
09-14 05:04:55.103    6324-6324/com.ohisamallc.ohiapp154.ohiapp154 E/ohi? Hello 1
09-14 05:04:55.103    6324-6324/com.ohisamallc.ohiapp154.ohiapp154 E/ohi? Hello 2
09-14 05:04:55.103    6324-6324/com.ohisamallc.ohiapp154.ohiapp154 E/ohi? Hello 0
09-14 05:04:55.103    6324-6324/com.ohisamallc.ohiapp154.ohiapp154 E/ohi? Hello 1
09-14 05:04:55.103    6324-6324/com.ohisamallc.ohiapp154.ohiapp154 E/ohi? Hello 2
09-14 05:04:55.103    6324-6324/com.ohisamallc.ohiapp154.ohiapp154 E/ohi? Hello 3
```

以上。
CakePHPのCollectionのsumOfの用例

https://book.cakephp.org/3/ja/core-libraries/collections.html#Cake\Collection\Collection::sumOf

```
$collection = new Collection($people);
$sumOfAges =  $collection->sumOf('age');

$sumOfChildrenAges = $collection->sumOf(function ($person) {
    return $person->child->age;
});

$sumOfDadAges = $collection->sumOf('dad.age');
```

こういう用例は載ってたけど、Collection<array>に対しても同じように使えるのか検証

```
public function test()
    {
        Log::debug(collection([
            [1,1,1,1,1],
            [2,2,2,2],
            [3,3,3]
        ])->sumOf(function (array $numberGroup)
        {
            return count($numberGroup);
        }));
    }
```
期待　5 + 4 + 3 = 12
結果　Debug: 12

要素数に対してもいけそうですね