OmniAICreator/Qiita-1.07M huggingface dataset:
Google UXデザイン：UXリサーチ

# はじめに

わたしが[Google UX Design Certificateで得られた素晴らしい体験][google]を、特に重要だと思われるポイントを小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ Google UX Design Certificateを受講してみてください。

[google]: https://qiita.com/mapami/items/7a0d0a3d4661c50f8bec

https://www.coursera.org/professional-certificates/google-ux-design

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/3729adea-8dba-b2a3-6127-9b0bf6886e54.png" width="800">

# UXリサーチの紹介

UXデザインのプロジェクトには、次の２つの重要なパートがあります。

- ***<font color="MediumBlue">デザインするユーザーを知るためのリサーチ</font>***
- ***<font color="MediumBlue">ユーザーの視点からのフィードバック収集</font>***

UXデザインは、ユーザーを第一に考えることであり、リサーチはデザイナーがユーザーを理解するのに役立ちます。UXリサーチは、観察やフィードバックを通じて、ユーザーの行動、ニーズ、モチベーションを理解することに重点を置いています。

プロダクトデザインは、<font color="Teal">思い込みではなく、リサーチと事実に基づいて構築されるべき</font>です。UXリサーチは、デザイナーが考えるユーザーのニーズと、実際にユーザーが必要としているものを一致させるものです。

# 製品開発のライフサイクルでの位置づけ

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/cbcb2274-a694-24d6-8011-49ee90581852.jpeg" width="600">

## Foundational research

このリサーチは、次の問いに答えるものです。

- ***<font color="MediumBlue">何を作るべきか？</font>***
- ***<font color="MediumBlue">ユーザの問題は何か？</font>***
- ***<font color="MediumBlue">どうすれば解決できる？</font>***

ゴールは、解決策を設計したい問題を定義するのを助けることです。

このリサーチには、ユーザーと対話し、製品を使用する際のペインポイントを特定することも含まれます。

## Design research

このリサーチは、次の問いに答えるものです。

- ***<font color="MediumBlue">どのように作るべきか？</font>***

このリサーチで、ユーザーに聞いておきたいことを挙げてみます。

- ***今日、プロトタイプを使ってみてどうでしたか？***
- ***使いやすかったですか、難しかったですか？なぜですか？***
- ***何か困難なことに遭遇しましたか？***

ゴールは、製品をどのように作るべきかを知らせることです。

このリサーチは、デザインプロセスのごく初期にスケッチを描く段階でデザインリサーチを行うこともできますし、プロトタイプができあがるまで待つこともできます。

## Post-launch research

このリサーチは、次の問いに答えるものです。

- ***<font color="MediumBlue">我々は成功したか？</font>***

ゴールは、ユーザーが製品をどのように体験したか、そしてそれが良いユーザー体験であったか悪いユーザー体験であったかを理解することです。

# リサーチ手法

## Foundational research

- ***Interviews***:　人々の意見、考え、経験、感情などに関する詳細な情報を収集します。ターゲットユーザー自身へのインタビューを行うことが多いです。
- **Surveys**: 多くの人に同じ質問をすることで、その製品について多くの人がどのように考えているか把握します。
- **Focus groups**: 少人数のグループで反応を収集します。例えば、8人のユーザーを集め、デザインの新機能に関する彼らの見解について話し合うかもしれません。通常、司会者によって運営され、司会者が特定の話題についてグループを誘導します。
- **Competitive audit**: 競合他社の強みと弱みを収集します。。
- **Field studies**: オフィスや研究室ではなく、ユーザーの状況や個人的な環境で行われる調査方法です。
- **Diary studies**: ユーザーの行動、活動、経験に関する質的データを長期にわたって収集します。多くの場合、ユーザーは日々の行動について日記を書き、行動やニーズに関する情報を提供します。

## Design research

- ***A/B testing***: 製品の2つの異なる側面を評価・比較し、どちらが効果的かを発見します。例えば、アプリのトップページのレイアウトを2種類用意し、ユーザーに評価してもらい、どちらのレイアウトがより効果的かを調べることができます。
- ***Cafe or guerrilla studies***: デザインやプロトタイプを公共の場に持ち出し、通行人に感想を求めることでユーザーのフィードバックを収集します。例えば、近所のコーヒーショップで、お客さんにアプリのデザインを数分間テストして、フィードバックをもらえないか尋ねてみるのもいいでしょう。
- ***Card sorting***: メモ用紙に書かれたラベルを、参加者に意味のあるカテゴリーに分類してもらいます。このタイプの調査は、主にプロジェクトの情報アーキテクチャを把握するために使用されます。
- ***Intercepts***: リサーチ対象の活動を行うユーザーから、その場でフィードバックを収集します。インターセプトはしばしば現場で実施されるため、このタイプの調査はしばしばフィールド調査のサブセットとみなされます。インターセプト調査は、迅速かつ高度なフィードバックを提供することができる。

## Post-launch research

- ***A/B testing***
- ***Usability studies***
- ***Surveys***
- ***Logs analysis:*** ユーザーがデザインやツールなどを操作している様子を記録し、評価します。


:::note info
心をオープンにして、自分のデザインについて他の人の意見に耳を傾ける姿勢を持つことです。私たちは、自分の心の中に閉じ込めてしまいがちですが、結局、誰のためにデザインしているのかというと、自分自身ではないのです。だからこそ、耳を傾けることが大切なのだと思います。 
:::
【環境構築】DockerでWordPressのサンドボックス環境を作る

## 背景
- [個人ブログ](https://takuma-tech.com)の立ち上げ時に、WordPressのサンドボック環境が欲しいと思いました。
- Dockerを使えば、WordPressの設定をミスっても、すぐに作り直せると思いました。
- DockerでWordPressのサンドボックス環境を作る方法をまとめておきます。

## 前提環境
- macOS 11.4 (20F71)
- arm64(M1)

## ファイル構成
```
.
└─ docker-compose.yml
```

## ファイルの中身
```yaml:docker-compose.yml
version: '3'

services:
   db:
     image: mysql:8.0
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     #参考記事のコードではM1に対応していないイメージだったのでlatestに変更しました。
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:
```

## 起動方法
- dockerが起動している状態であれば、ファイルがあるカレントで下記コマンドを実行するだけ。
```
$docker-compose up
```
- 起動していれば[http://127.0.0.1:8000](http://127.0.0.1:8000)にアクセスすれば、wordpressの初期設定画面になります。
- 自由に使ってWordPressの操作方法を習得しましょう。

## 参考資料
https://dev.classmethod.jp/articles/beginner-docker-wordpress/

https://docs.docker.jp/compose/wordpress.html

## 個人ブログ

https://takuma-tech.com/2022/09/28/299/
[JavaScript] Reactの状態管理にはZustandが決定解になるような気がする

useStateと同じ感覚で、グローバルのstoreをかけるので、これが最も使いやすいstore管理なのではないかなと思います。

今まで状態管理で、ReduxとかMobxとか、あれやこれや悩んでいたことが嘘のように一掃される感。

俺はこれを待ってたんだ感がします。すごいライブラリ！

zustand - npm
https://www.npmjs.com/package/zustand

pmndrs/zustand: 🐻 Bear necessities for state management in React
https://github.com/pmndrs/zustand

# Code

```js:App.js
import { useStore } from "./store";
import "./styles.css";

export default function App() {
  const countDefault = 1;
  const { count = countDefault, setCount } = useStore();

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>

      <h2>count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increase</button>
      <button onClick={() => setCount(count - 1)}>Decrease</button>
      <button onClick={() => setCount(countDefault)}>Reset</button>
    </div>
  );
}
```

```js:store.js
import create from "zustand";

export const useStore = create((set) => ({
  count: undefined,
  setCount: (value) =>
    set((state) => {
      return { count: value };
    })
}));
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96423/84d91a2d-d46f-30cd-273f-a1e09b28faac.png)


# codesandbox

記事でコードのせた単純なstoreのもの

https://codesandbox.io/s/zustand-sample-k8vsc4?file=/src/App.js


下記の画像のような多数のコンポーネント間のstoreの連携

https://codesandbox.io/s/zustand-sample2-1ejjm0?file=/src/store.js

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96423/defcc4d9-8f28-fa55-99fd-37334e936b16.png)


# 参考

React状態管理ライブラリ Zustandを使ってみた | DevelopersIO
https://dev.classmethod.jp/articles/zustand/

Reactで状態管理 初心者でも簡単Zustandの設定方法 | アールエフェクト
https://reffect.co.jp/react/zustand

ZustandとValtioの比較 
https://zenn.dev/dai_shi/articles/f848fb75650753

Zustand: React向け軽量ステート管理ライブラリ - Qiita
https://qiita.com/daishi/items/deb20d951f532b86f029

なんで、多くの紹介サイトが、store側で、increaseとかdecreaseとか定義しているのかわからないけど
store側では、setCount を定義したらいいのに。
pythonのライブラリの脆弱性チェックをやってみた



requirements.txtなどでライブラリをバージョンを指定するとそのままにしていることが多い気がしたので、
ライブラリの脆弱性チェックの方法を確認してみました

今回は古めのDjangoをrequirements.txtに記載し実行してみました

## safety
git hub
https://github.com/pyupio/safety

Safety DBを使用し脆弱性のチェックを行う
https://github.com/pyupio/safety-db



### インストール
`pip install safety`

### 実行
`safety check -r requirements.txt`

### 結果
![2022-09-30-17-21-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997750/64eda12b-27d7-ea7b-526e-5b207171cdb5.png)

`24 vulnerabilities found`が脆弱性の数で、`VULNERABILITIES FOUND`からが脆弱性の情報になります

## pip-audit
git hub
https://github.com/pypa/pip-audit

Python Packaging Advisory Databaseを使用し脆弱性のチェックを行う
https://github.com/pypa/advisory-database

### インストール
`pip install pip-audit`

### 実行
`pip-audit -r requirements.txt --desc`

### 結果

```
Found 20 known vulnerabilities in 1 package
Name   Version ID                  Fix Versions               Description
------ ------- ------------------- -------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
django 1.7.5   PYSEC-2019-16       1.11.27,2.2.9              Django before 1.11.27, 2.x before 2.2.9, and 3.x before 3.0.1 allows account takeover. A suitably crafted email address (that is equal to an existing user's email address after case transformation of Unicode characters) would allow an attacker to be sent a password reset token for the matched user account. (One mitigation in the new releases is to send password reset tokens only to the registered user email address.)
```

`Found 20 known vulnerabilities in 1 package`が脆弱性の数で、その下からが脆弱性の情報になります
数が多いので、全部は表示していません

## 終わり
数だけを見るとsafetyのほうが多かったですね
あとは反映スピードなどが気になります

今回はrequirements.txtに記載してあるライブラリのチェック方法を記載していましたが、
インストールしてあるライブラリのチェック方法もありますので気になる方は確認してみてください
Laravel Faker->image() で画像が作成できない時の対処 

作成したFactoryクラス内で以下を実行しても画像が生成されませんでした。
```
$this->faker->image(storage_path('app/public/hoge'), 640, 480);
```

こちらに記載されている方法で解決しました。
https://stackoverflow.com/questions/72142021/images-dont-save-using-faker-image-in-seeder/73059602#73059602

:::note warn
私の開発環境では、ひとまず画像が生成されるようになったので、その時の方法を記載しておりますが、これがベストな対処かは分かり兼ねます。対応は自己責任でお願い致します。
:::




```vendor/fakerphp/faker/src/Faker/Provider/Image.php
・・・・・省略・・・・・
public const BASE_URL = 'https://placehold.jp'; // 変更
・・・・・省略・・・・・
curl_setopt($ch, CURLOPT_FILE, $fp); //この行の下に以下の２行を追加
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//追加
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);//追加
・・・・・省略・・・・・
```
【Laravel】breeze:install コマンドの「以前と現在」【Breeze】

## Laravel Breeze のインストールが以前と違う？

通常、Laravel Breeze をインストールした後は、認証関連のリソースを公開するために `breeze:install` コマンドを入力します。

## 以前の Breeze は `npm install` コマンドが必要でした

以前の Breeze では、`breeze:install` コマンドを入力し認証関連のリソースを公開した後に、`npm install` コマンドを入力し、更に `npm run dev` によって CSS と JS をコンパイルして各種ファイルを出力していました。

…が、

最近、フロントエンドのビルドシステムが `webpack` から `vite` に変更された頃にあわせて、**`breeze:install` コマンドだけ入力すれば、npm 経由でのパッケージインストールから CSS や JS ビルドまでの一連の作業を行ってくれるようになりました** 

実際に [Laravel Breeze のリポジトリ（https://github.com/laravel/breeze/blob/1.x/src/Console/InstallsBladeStack.php）](https://github.com/laravel/breeze/blob/1.x/src/Console/InstallsBladeStack.php) を拝見してみると

```php
trait InstallsBladeStack
{
    protected function installBladeStack()
    {
        // ...

        $this->runCommands(['npm install', 'npm run build']);

        $this->line('');
        $this->components->info('Breeze scaffolding installed successfully.');
    }
}
```

というように、`npm install` と `npm run build` の 2 つが `breeze:install` コマンドにより実行されているのが分かると思います。
ブラウザのタブの複製を検知する

アプリケーションで、あるタブから別のタブを複製して欲しくないときがあります（ひとつのタブだけ）

これまではCockieとか使ってたみたいなのですが、最近のブラウザであればブロードキャストをつかってかけそうです。

これで、複製すると元のタブのBodyを潰せます（クローズまでは出来ません）

``` js
const channel = new BroadcastChannel('tab');
channel.postMessage('another-tab');
channel.addEventListener('message', (event) => {
    if (event.data === 'another-tab') {
        document.body.innerHTML = `新しいタブが開かれたためクローズしました。`;
    }
});
```


いま開いたタブを検知したい場合は……実はよく分かりません。イベントにイベントを返せば元のタブにレスポンス返せると思い次のように書いたのですが、event.sourceがnullですとか言われてエラーになります。


``` js
const channel = new BroadcastChannel('tab');
channel.postMessage('another-tab');
channel.addEventListener('message', (event) => {
    if (event.data === 'another-tab') {
        event.source.postMessage("another-tab-response");
    }else if(event.data === 'another-tab-response'){
        document.body.innerHTML = `このサイトではタブの複製は禁止されています。`;
    }
});
```
【C++の学習】安藤風樹

# 今週の学習課題

- C++の学習

# 学習内容・結果

- スマートポインタ
- オブジェクト指向設計
- クラス図
- シーケンス図
- 配列型(std::list)


## スマートポインタ

動的メモリは最後にdelete等で消す必要があるが、これは人的なミスで忘れてしまう可能性がある
スマートポインタは、メモリの所有権を与えてスコープが終了した段階、不要になった段階で自動的の解放させることが出来る。
スマートポインタには３種類ある
- unqiue_ptr
- shared_ptr
- weak_ptr

### unqiue_ptr
一つのインスタンスが所有権を保持し、コピーは出来ないがムーブ(所有権の譲渡)は可能

```C++
std::unique_ptr<int> uptr1(new int(10));

std::unique_ptr<int> uptr2;
uptr2.reset(new int(20));

auto uptr3 = std::make_unique<std::string>("test");

auto uptr4 = std::make_unique<int,std::string>(40,"tedt");

std::cout<< *uptr3 <<std::endl;	//「test」と表示

int usize = uptr2->size();		//関数の使用

bool cU = uptr1;				//所有権の有無

auto utpr5 = std::make_unique<int>(50);
auto utpr6 = std::move(uptr5);	//所有権の移動
```


### shared_ptr
複数のインスタンスが所有権を保持する事が出来て、コピー、ムーブも可能。
基本的に宣言や関数の使い方は同じ。

unique_ptrとの大きな違いは所有権を複数のインスタンスが保持できる点


```C++

auto sptr1 = std::make_shared<int>(10);

std::make_shared<int> sptr2(sptr1);		//「sptr1」をコピー
{
  std::make_shared<int> sptr3;
  sptr3 = sptr2;					//「sptr2」をコピー
}			//スコープを出たため「sptr3」は消える
			//「sptr1」「sptr2」の所有権は残っている
```

ただし、同じメモリの所有権を保持するインスタンスが同時にデストラクタで解放しようとすると双方が解放時に他のインスタンスが保持している事になってしまい、メモリリークを起こしてしまう。



### weak_ptr
unique_ptrやshared_ptrと違い所有権を保持せず、shared_ptrのメモリの参照する


```C++
auto sptr = std::make_shared<int>(10);
std::weak_ptr<int> wptr1(sptr);
std::weak_ptr<int> wptr2 = sptr;
std::weak_ptr<int> wptr3;
wptr3.reset(wptr1);

{
  std::shared_ptr<int> ptr = wptr1.lock();
    //一時的に所有権を取得
    //解放されていた場合、空のshared_ptrを返す
}
```
weak_ptrで参照中に他のスレッド等の操作で参照元のshared_ptrのデストラクタが呼び出されてもメモリの所有権は消えず、weak_ptrがなくなることで完全にメモリの所有権がなくなる



### unique_ptrとshared_ptrの使い分け

コピーが必要になると言う場面が少ないため、基本は「unique_ptr」が優先

「shared_ptr」を使うケース

1. 複数のオブジェクトから同時にアクセスがある場合
2. 使うオブジェクト達の中で最後まで所有するオブジェクトが不明な場合
3. 使うオブジェクト達が全て終了した段階ですぐに解放したい場合
4. 元のポインタが先に解放されてしまう場合

どのケースもマルチスレッドの場合であれば考えられる状況であり、次の案件でも使うことになりそうな内容でした。



## オブジェクト指向設計

オブジェクト指向については復習でもあるため、重要な要素を簡素にまとめました

### 抽象化
スーパークラス以上でメソッドや変数を用意、把握しておくことで、末端のサブクラスの実装を知らなくとも、メソッドや変数を利用できる仕組み


### カプセル化
クラスごとに所持する変数や関数を関連のあるものだけでまとめ、クラスごとに何を扱っているか分かりやすくする


### 情報隠匿
外部から使える変数、関数に対して制限を設ける。
制限を設けることで、クラス内にある意図しない関数(クラス内だけで使い回す処理等)や参照のみで上書きをさせたくない変数等へのアクセスを防ぐことが出来る


### 多態性
同じ型、同じ関数を使っても中のインスタンスによって実行内容が決まること
ただ扱いは「型」のクラスで扱うため、「型」にない関数は使えない。


### 継承
他のクラスを引き継ぐことで、元のクラスにあった変数や関数を利用することができ、複数のクラスが同じ関数を使う場合は、継承させることで何度も書く必要がなくなり、多態性、抽象化を実現するのに必要な書き方



## クラス図
クラスが持つ変数や関数、他のクラスとの関係性(継承や使用)を線で表したもの

C++だからマルチスレッドの場合だからと言ったような特別今回から使うであろう内容ではありませんが、線や矢印の意味等を再度確認しました

## シーケンス図
クラスやオブジェクト間のやり取りを時間軸で表した図
研修でもやったないようですが、今回C++のマルチスレッドを扱う上で、「並列処理」についてはしっかりと学び直すべきだと感じました。

### 並列処理「par」
同時に行われる処理を四角で囲み、処理ごとに点線で区切って表す
スレッドによる並列処理の表し方

### クリティカルセッション「critical」
並列処理内の排他的制御を呼び出される側と呼び出している矢印を囲むように表す
「std::mutex」「condition_variable」を使って他の処理を待つ場合に使う



## 配列型(std::list)

標準テンプレートライブラリーの配列関連のクラス
配列の要素を先頭や最後尾に追加でき、イテレータを利用すると場所を指定して要素の追加、参照ができる

```C++
list<int> l;
l.push_back(1);
l.push_front(2);

//イテレータ
std::list<int>::itr;
itr = l.begin();
//イテレータにリストの先頭を設定

l.insert(itr,3);

std::cout<<*itr<<std::endl
```

イテレータは配列の要素のポインタを持っており、ポインタとして配列の要素にアクセスできる。


## まとめ
今週で待機期間が明け、来月より次の現場での作業になります。
次の現場では、この期間中の学んだことが生かせるよう努力したいと考えております。
Google AppSheet｜スプレッドシート×AppSheetで簡単アプリ作成

:::note warn
本記事は、全てを1から私が記載したわけではありません。
こちらの記事は、あくまでも参照元に倣って自分でも作ってみて、つまづいたポイント・自分で追加調査したところ・追加改造を記録した記事です。
:::

# ゴール
Google AppSheetを使って、`アプリでデータを入力したら、スプレッドシートに記録される`というアプリを作成する。
言葉では難しいので、以下の手順で試してみてください。※Googleアカウント不要

# 使い方
①[アプリ](https://www.appsheet.com/start/ea375fc6-6045-4832-b5a9-6cd57beda655)にアクセスしてデータを入力。
![AppeSheetテスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687068/96ef4d90-6e92-1915-4cf7-7ebf7e793866.png)

②[スプレッドシート](https://docs.google.com/spreadsheets/d/1q2wzeWCILT0a82TZ1EPn9xZZPP2gsDepkfR4QHaTMKU/edit?usp=sharing)に入力したデータが記録されることを確認。
![AppeSheetテスト_-_Google_スプレッドシート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687068/285fbcde-eb24-9a30-4d29-abde99e2af61.png)


# つまづき
ナゾのWarningが表示されている。
`スプレッドシートの行番号は、テーブル 'シート 1' でキーとして使用されています。表に「ID」列を含めることをお勧めします。`ということらしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687068/625cc0e1-37e2-f6ac-1124-9fe66ac979ea.png)


`ID`をKEYに選択して「SAVE」を押すと解消した。
**※「SAVE」を押さない限り変更は反映されず、Warningは消えないので注意。**
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3638373036382f30643164326665642d313463632d656534312d373366632d3234623631323335343261372e706e67__2096×892_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687068/60b9999b-0129-a82f-1934-8f1f1393f381.png)


`_RowNumberがKEYになってるけど、使われ方はIDと存在意義は同じなのだから、いっそのことIDをKEYにしたら？`っていうことだったらしい。
とりあえず、これでエラーとかは表示されなくなったから一旦完成！

# 感想・今後の展望
想像以上に簡単にアプリを作成できた。
LINEとAppSheetを使いこなせば、小売店業務はすべて賄えるのではないか？って思った。

次は、LINEとAppSheetの連携に挑戦したい。


# 参考・参照
詳しい作り方とかは以下の通りなので、そちらで確認してください。

https://youtu.be/-S5eg-R4X-M
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その039

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

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

今回はTrailhead
アドミニストレーター認定の準備: データと自動化
データ管理と分析管理の演習

にある練習問題7問目をご紹介します


今回の内容は動画でも解説しています

https://www.youtube.com/watch?v=PPBaxsnHxGo

<iframe width="560" height="315" src="https://www.youtube.com/embed/PPBaxsnHxGo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-security-and-data-management/review-data-management?trail_id=administrator-certification-prep

今回の問題はこちらです

![共有０１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/a65299ae-94a0-b7a8-a308-cfadd3a813ab.png)


正解はAです

今回のロール階層が異なるとはこのような状況ですね

![ロール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/3f9419ab-0592-4e5a-8617-5f4c506baaa0.png)

この場合共有ルールを設定すれば所有者のロールごとにレコード閲覧可能です

![共有ルール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/633ed8fe-2eb2-e76c-d977-8fe6d174bc3e.png)
VRCでぼやけないロゴをアバターに使おう

![Fcy-1sXaIAA_xgS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882854/cb016686-b58b-fbc6-c32c-88c84a48d8b4.png)
アバターのUVに直接ロゴ貼ろうとするとどうしてもぼやけるよね
liltoonの機能でそこまで解像度を盛らなくてもきれいにロゴ貼れます
# 必要なもの
・VRCにアバターをアップロードする環境
・liltoon等MSDFテクスチャをサポートするシェーダー
・[MSDFGen(GitHub)](https://github.com/Chlumsky/msdfgen/releases) win64.zipとopenmp.zipの違いは判らないのでwin64選べばいいと思う
・svgファイルもしくはAdobe IllustratorもしくはInkscape等ロゴをsvgファイルとして出力できるソフト
# 手順
### MSDFGenをダウンロードしておく
解凍ソフト等使い任意の場所に解凍
svgファイルが用意出来たら以降は作業フォルダになる
### svgファイルを用意する
自分がアバターに貼りたいロゴを用意する
###### 細すぎる線はカバーできず潰れることがあるのでMSDFテクスチャの解像度を下げたい時は気を付けるべき 個人的には出力後で2px分は確保したい
シェーダーのベースカラー以外はつけられないので作る際は白黒が望ましい
Illustratorでの作業は以下
![名称未設定-1_ @ 66.67 % (RGB_プレビュー)  2022_09_30 14_36_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882854/805511fa-d6b3-bba6-efa9-e0e0c0c2da7e.png)
ロゴ作ったらたいていの場合いくつかオブジェクトが混在してる状態になってると思うのでパスを一つのオブジェクトにまとめる
以降の作業は不可逆なのでパスをまとめる前にバックアップを保存しておく

まずはまとめる前の下準備
![スクリーンショット (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882854/f04d1f41-b42a-f886-415a-abfb4778175d.png)
文字オブジェクトは"右クリック、アウトラインを作成"
![スクリーンショット (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882854/483a265c-ca22-f74f-09e2-c7793d386fa1.png)
文字のパス化を終えたらCtrl+Aで全選択後上メニューの"オブジェクト、パス、パスのアウトライン"
全部終えたらそのままパスファインダーの"合流"をクリック
![スクリーンショット (13).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882854/0ec46044-126f-e68a-5e1f-c05f64615859.png)
白いオブジェクトが生成されているのでこれを削除し上メニューの"オブジェクト、複合パス、作成"を実行
これでオブジェクトにまとめる作業が完了したので"ファイル、書き出し、書き出し形式"からsvgとして書き出し
svgオプションはわからんけどそのままでいいと思う
### MSDF画像の生成
MSDFGen.exeはコマンドで動くアプリケーションなのでMSDFGenフォルダにbatファイル作成
~~~msdfgen.bat
msdfgen.exe -svg icon.svg -o output.png -size 128 128 -pxrange 4 -autoframe -testrender render.png 1024 1024
pause
~~~
実行時はsvgファイルをicon.svgにしてmsdfgen.exeと同じフォルダに配置
batを実行するとMSDFテクスチャがoutput.pngで出力される
-size 128 128の部分を任意の数字に変えることでMSDFテクスチャの解像度が変わる
-testrender以下はMSDF描画した際のだいたいの表示が分かる Unityにいちいちインポートしなくても確認できるので便利 消しても動く
他のパラメータはMSDFGenの[GitHubページ](https://github.com/Chlumsky/msdfgen#console-commands)参照
### Unityで描画
MSDFテクスチャ(output.png)をUnityにインポート
インポート設定はこんな感じ(VRCにアップロードする際はストリーミングミップマップにチェックを入れる)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882854/100c66f0-38e6-0a40-0626-533883a402f7.png)
liltoonシェーダーを使用したマテリアルのメインカラー2ndにMSDFテクスチャを使用、"MSDFテクスチャを使用"にチェックを入れる
必要に応じてタイリングとオフセットを使用しロゴを貼りたい場所に位置を調整する
# 比較
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882854/abbaadbf-aa3f-06c3-5444-ee58ecbcc19a.png)
だいたい同じ512xテクスチャで比べるとこんな感じ(出力の関係で完全に同じではない)　左が通常テクスチャで右がMSDF
MSDFは細い線がつぶれている
こうならないようロゴの製作段階で細い線は極力使わないようにしたい
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2882854/2a5df410-1a65-7909-5f4d-28995299be21.png)
真ん中部分を拡大し比較
上がMSDF、下が通常テクスチャ
通常テクスチャは解像度の低さからぼやけが生じているがMSDFは同じ解像度でもベクターな表現を維持できている
通常テクスチャでぼやけを解決するには解像度を高くするしかなく書き出し時間や画像サイズでネックになる
# 雑記
MSDFで今のところ単色しか使えてないので(マテリアル設定時のベースカラーのみ)カラフルにする方法があれば知りたい できれば2ndテクスチャ内で完結させたい・・・
UVに合わせたMSDFテクスチャを作るのは案外悪くなさそう

### 参考URL
https://qiita.com/Feyris/items/3c5b227eb27e0d6a8305
文字化けしている文字のユニコードを調べたい！

文字化けしている文字コードを調査する必要があり、どうあがいても力技でしらみつぶしに行くしかないかと考えていたところ、Google日本語入力に救われた話。

<h3>経緯</h3>
1. Webアプリの入力値に対し、特定文字コードの値を通さないようバリデーションを実施する<br>
2. それに合わせて、データ受信（ホスト）側で許可できない特定文字をはじく必要がある。<br>
3. 残念ながら対象文字がUTF-8…というかエディタからは確認できないため、何の文字か不明だし文字コードもどうやって調べたら…？<br>

<h3>都合いいものがありました。</h3>

[Google日本語入力](https://www.google.co.jp/ime/)というIMEが、指定文字コード（ユニコード値）を表示してくれるようです。

使い方は通常のIMEと変わらず、上記リンクからIMEをインストールするだけです。

その後、文字コードを確認したい文字を選択し、「変換」ボタンを押すと、変換候補の中に文字コードが表示されます。
IMEをインストールするだけなので、かなり楽な方法だと思います。
Chromeに保存されているサイトのパスワードを平文で確認したい

# やり方

右上⇒設定 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/cff71694-5480-3f4d-e279-caa22012f89c.png)

自動入力⇒パスワードマネージャー 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/de402da9-268e-45e0-09cf-ec951f9dce1e.png)

目玉マーク。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/37d53027-308c-0b62-4228-0a35e73cf819.png)

Windows10にログインしているユーザーのパスワードを求められる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9e5953ae-7a7a-8081-3f00-d8600335a239.png)

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.2075
Google Chrome バージョン: 106.0.5249.62（Official Build） （64 ビット）
Googleスプレッドシートのちょっとだけ便利機能

近年、仕様書などでGoogleスプレッドシートをよく使うようになりました。これまでに使っていたMicrosoftのExcelとは似ているけどちょっと違う・・・。そこで、使っていて気が付いた「ちょっとだけ便利機能」を記録します。

# セルへのリンク
列も行もたくさんあるシートの特定の部分に記載した内容をほかの人にリンクで知らせたいときに便利です。

:::note info
セルへのリンク取得方法
セルを選択 > 右クリック > [セルでの他の操作項目を表示] > [このセルへのリンクを取得] > セルへのリンクがコピーバッファに入る
:::

シート自体へのリンクは`https://docs.google.com/spreadsheets/d/xxxxx/edit#gid=0`みたいになります。セルへのリンクは、これに「&range=B2」みたいにパラメータがくっつきます。
セルの範囲へのリンク取得で可能です。

:::note info
範囲へのリンク取得方法
範囲を選択 > 右クリック > [セルでの他の操作項目を表示] > [この範囲へのリンクを取得] > セルへのリンクがコピーバッファに入る
:::

範囲へのリンクは、「&range=B2:D6」みたいにパラメータがくっつきます。

![hoge.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1743295/ab949e5e-f821-560e-913b-8a7685d905d9.gif)

# 罫線の一部削除
テーブル形式の表に罫線をつけて、後で一部だけ削除する方法です。

:::note info
罫線を一部削除する方法
罫線のあるセルを選択 > メニューの[枠線] > [枠線の色] > [枠線なし] > 削除したい部分を選択
:::

![hoge.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1743295/673016ed-98dd-bb76-755a-7d31b78d0fb4.gif)


# 「貼り付けると先頭の半角スペースが消える」対応策
エディタから行頭に半角スペースがある文字を貼り付けるとスペースが削除されてしまいます。
「貼り付け」「[特殊貼り付け] > [値のみ貼り付け]」どちらでやっても削除されます。
参考 : [Paste deletes leading spaces - Google Docs Editors Community](https://support.google.com/docs/thread/163509114/paste-deletes-leading-spaces?hl=en)


## 対応策1 : 1行ずつ貼り付ける
貼り付ける行数が少ない時の対策です。

1. エディタで1行分選択してコピー
1. Googleスプレッドシートのセルにカーソルイン
1. 貼り付ける

## 対応策2 : 行頭に「'」を入れて貼り付ける
貼り付ける行数が多い時の対策です。

1. エディタの置換機能を使ってコピー対象行の行頭に「'」を入れる
    1. 置換対象 : `^`(正規表現を使えるようにしておく)
    1. 置換後 : `'`
1. エディタのコピー対象行をコピーする
1. Googleスプレッドシートに貼り付ける
    1. 文字として貼り付くので行頭の「'」は表示上は消える
![hoge.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1743295/ce8c79fb-abc3-326b-61f5-8fdedd5d6fca.gif)
AndroidエンジニアのためのiOSライブラリ選定シート

Qiita初投稿です！:joy:

## 目的
本ページはAndroidアプリ開発経験者がiOSアプリを開発し始める上で必ず確認したくなる~~はずの~~**Androidでいうとこのライブラリなんだけど、それのiOS版は何か**をまとめたものです。主に自分で調べた備忘録として残します。
誰かの労力の削減になれば幸いです:open_hands:

## 比較表(2022/9/30 時点)
| 役割 | Android(kotlin) | iOS(Swift) |
|:-:|:-:|:-:|
| ログ | [Timber](https://github.com/JakeWharton/timber) | [SwiftyBeaver](https://github.com/SwiftyBeaver/SwiftyBeaver) |
| HTTP クライアント | [Retrofit2](https://square.github.io/retrofit/) | [Moya](https://github.com/Moya/Moya)※1 |
| 画像読み込み | [coil](https://github.com/coil-kt/coil/) / [Picasso](https://github.com/square/picasso) / [Glide](https://github.com/bumptech/glide) | [Nuke](https://github.com/kean/Nuke) / [Kingfisher](https://github.com/onevcat/Kingfisher) / [PINRemoteImage](https://github.com/pinterest/PINRemoteImage) |
| JSON | [Moshi](https://github.com/square/moshi)※2 | [Codable](https://developer.apple.com/documentation/swift/codable) |
| テスト | [Spek](https://github.com/spekframework/spek) | [Quick](https://github.com/Quick/Quick) |
| DB | [Room](https://developer.android.com/training/data-storage/room/index.html) | [Realm](https://www.mongodb.com/docs/realm-sdks/swift/latest/index.html) |
| DI | [Hilt](https://developer.android.com/training/dependency-injection/hilt-android?hl=ja) | [Swinject](https://github.com/Swinject/Swinject) |


※1 MoyaはAlamofireを使用してAPI通信を行うライブラリ
※2 GsonはKotlinと使用するとnon-null変数にnullを入れてしまう可能性があるためここでは不採用としました。

## まとめ
今回Androidアプリしか開発してこなかった私が、iOSのアプリを開発し始めた際に気になって調べたものをまとめました。iOSでも沢山のライブラリがあって中々悩みました。。。:sweat:
 **もっとこんないいライブラリあるぞ！**という方は、どんどん共有してください！
【Rails 7】will_paginate の Turbolinks を無効化する方法

# 開発環境
・Ruby: 3.1.1
・Rails: 7.0.3.1
・OS: Windows 10
・Docker

# will_paginate の Turbolinks を無効化する方法

簡単に `will_paginate` の記載に `data: { turbo: false }` を追加したら、turbolinksは無効化されません。

:::note warn
`<% will_paginate data: { turbo: false } %> ` 
:::

なぜなら、上記はそれぞれのページネーションボタンリンクではなく、外の `paginate` `div` に `data="{:turbo=>false}"`の属性を追加するからです。turbolinksを無効化するために、それぞれのページネーションボタンリンクに `data-turbo` を `false` にする必要があります。

そうするためのショットカットがまだないので `will_paginate` の `renderer` をカスタマイズする必要があります。

### `will_paginate` の `renderer` をカスタマイズする：

**1\. カスタムレンダラーを作成する**
各 `li` タグの `data-turbo="false"` が重要なポイントです。

```ruby:config/initializers/custom_paginate_renderer.rb
require 'will_paginate/view_helpers/action_view'
require 'will_paginate/view_helpers/link_renderer' 

class CustomPaginateRenderer < WillPaginate::ActionView::LinkRenderer
  def container_attributes
    { class: 'pagination' }
  end

  def html_container(html)
    child = tag(:ul, html, container_attributes)
    tag(:nav, child)
  end

  def page_number(page)
    if page == current_page
      '<li class="page-item active" data-turbo="false">' + link(page, page, rel: rel_value(page),class: 'page-link') + '</li>'
    else
      '<li class="page-item" data-turbo="false">' + link(page, page, rel: rel_value(page),class: 'page-link') + '</li>'
    end
  end

  def previous_page
    num = @collection.current_page > 1 && @collection.current_page - 1
  previous_or_next_page(num, '<span aria-hidden="true">&laquo;</span>')
  end

  def next_page
    num = @collection.current_page < total_pages && @collection.current_page + 1
  previous_or_next_page(num, '<span aria-hidden="true">&raquo;</span>')
  end

  def previous_or_next_page(page, text)
    if page
      '<li class="page-item" data-turbo="false">' + link(text, page, class: 'page-link') + '</li>'
    else
      '<li class="page-item disabled" data-turbo="false">' + link(text, page, class: 'page-link') + '</li>'
    end
  end
end
```

**2\. カスタムのレンダラーを `will_paginate` に渡す：**

```ruby:app/helpers/application_helper.rb
...省略...

def will_paginate(coll_or_options = nil, options = {})
  if coll_or_options.is_a? Hash
    options = coll_or_options
    coll_or_options = nil
  end
  unless options[:renderer]
    options = options.merge renderer: CustomPaginateRenderer
  end
  super *[coll_or_options, options].compact
end

...省略...
```

**3\. サーバーを再起動する**

これで、`will_paginate` のページネーションリンクの `turbolinks` が無効化されます。


---
参考：

https://github.com/mislav/will_paginate/wiki/Link-renderer

https://stackoverflow.com/questions/44680975/custom-will-paginate-renderer

https://stackoverflow.com/questions/73904226/how-to-disable-turbolinks-for-will-paginate-rails-7
ByteBuffer#getInt()でBufferUnderflowExceptionが出るときの対処法

# 2byteの16進数を整数にしたい

Jpegのメタデータのセグメント長を取得したかったのですが、思いもしなかったところでハマりました。

```java
byte[] bytes = new byte[]{(byte)0x03,(byte)0x1e} // これから798を求めたい
ByteBuffer.wrap(bytes).getInt(); //BufferUnderflowExceptionが発生
```

## javaのIntは32bitの符号付き整数
つまり`byte[4]`です。

上のコードでは`byte[2]`です。ByteBuffer#getInt()は4byte取得しよとします。僕はここで自動で0x00で埋めてくれると勝手に思ってました。

## getShort()を使う
`ByteBuffer#getShort()`はshort型なので2byteです。これで動きます。

## 4byteになるまで埋める
~~これが最適解かはわかりませんがとりあえず動きます。~~
3byteのときはこの方法が良いと思います。

```java
byte[] tmp = new byte[4]{0x00,bytes[0],bytes[1],bytes[2]} // 今回は符号を考慮しないのでゼロで埋める。
Bytebuffer.wrap(tmp).getInt(); // 798
```
DHCP機能でIPアドレスが割り振られない

# IP address is not assigned by DHCP function

## Wrote the memo

試験環境
-----

```text:構成図.txt
+---------+   +-----------+   +-----------+
| L3SW-01 |===| Router-01 |~~~| PE Router |
+---------+   +-----------+   +-----------+
  |
  | Vlan 2
  +-------------------------------+
  |                               |
  |                               |
  | Vlan 1                        |
  +-------------+                 |
  |             |                 |
+---------+   +-------------+   +-------------+
| DHCP-SV |   | DHCP-CLT-01 |   | DHCP-CLT-02 |
+---------+   +-------------+   +-------------+

Router-01   : CE Router
L3SW-01     : Layer-3 Switch
DHCP-SV     : DHCP-Server
DHCP-CLT-01 : DHCP-Client
DHCP-CLT-02 : DHCP-Client

Note:
PE Router   : Provider Edge Router (ISP Router)
CE Router   : Customer Edge Router

DHCP-Apps   : ISC-DHCP-Server
```

補足
-----
- 実際のVLAN-ID, IPv4-Addressとは一部異なる場合がある（マスキング処理）
- DHCPサーバ（DHCP-SV）は共通（1台構成）
- DHCPクライアント（DHCP-CLT-01, DHCP-CLT-02）は別セグメントに接続
- DHCPサーバ（DHCP-SV）とDHCPクライアント（DHCP-CLT-01）は同一セグメント
- ___DHCPクライアント（DHCP-CLT-01）のデフォルトゲートウェイ（DGW）はRouter-01___
- ___DHCPクライアント（DHCP-CLT-02）のデフォルトゲートウェイ（DGW）はL3SW-01___
- ルータ（Router-01）とL3スイッチ（L3SW-01）はL2 Trunk 接続（OSPF接続無し）
- DHCPクライアント（DHCP-CLT-02）からのDHCPパケットはDHCP-SVへrelayするよう設定済み（Ciscoの `ip helper-address 172.16.x.x`）

問題点
-----
- DHCP-CLT-01 からのDHCP取得要求(*1) は問題なく通るが、DHCP-CLT-02 からのDHCP取得要求(*1)は失敗する。
- DHCP-SVのログには `Discover` 及び `Offer` のログのみ存在(*2)
- DHCP-SV側でpacket capture実施->`Discover` 及び `Offer` のみ


対処
-----
- Router-01 に DHCP-CLT-02 のセグメントに対する Static Route の追加
`ip route 172.16.0.0/16 L3SW-01`



-----

> *1
Discover->Offer->Request->ACK

https://ja.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol

https://www.rfc-editor.org/rfc/rfc2131

> *2
Sep 30 15:29:22 bootp dhcpd[99344]: DHCPDISCOVER from xx:xx:xx:xx:xx:xx (DHCP-CLT-02) via 172.16.0.6
Sep 30 15:29:23 bootp dhcpd[99344]: DHCPOFFER on 172.16.0.1 to xx:xx:xx:xx:xx:xx (DHCP-CLT-02) via 172.16.0.6
Sep 30 15:29:25 bootp dhcpd[99344]: DHCPDISCOVER from xx:xx:xx:xx:xx:xx (DHCP-CLT-02) via 172.16.0.6
Sep 30 15:29:25 bootp dhcpd[99344]: DHCPOFFER on 172.16.0.1 to xx:xx:xx:xx:xx:xx (DHCP-CLT-02) via 172.16.0.6
Sep 30 15:29:29 bootp dhcpd[99344]: DHCPDISCOVER from xx:xx:xx:xx:xx:xx (DHCP-CLT-02) via 172.16.0.6
Sep 30 15:29:29 bootp dhcpd[99344]: DHCPOFFER on 172.16.0.1 to xx:xx:xx:xx:xx:xx (DHCP-CLT-02) via 172.16.0.6
Sep 30 15:29:36 bootp dhcpd[99344]: DHCPDISCOVER from xx:xx:xx:xx:xx:xx (DHCP-CLT-02) via 172.16.0.6
Sep 30 15:29:36 bootp dhcpd[99344]: DHCPOFFER on 172.16.0.1 to xx:xx:xx:xx:xx:xx (DHCP-CLT-02) via 172.16.0.6
Sep 30 15:29:51 bootp dhcpd[99344]: DHCPDISCOVER from xx:xx:xx:xx:xx:xx (DHCP-CLT-02) via 172.16.0.6
Sep 30 15:29:51 bootp dhcpd[99344]: DHCPOFFER on 172.16.0.1 to xx:xx:xx:xx:xx:xx (DHCP-CLT-02) via 172.16.0.6
最近AppDynamicsを使い始めたので、Zabbixとの比較をしてみる。

# はじめに
前職で約二年間、ひたすらZabbix（ver2.2&4.0）を触ってきました。
（サービスの基盤となるオンプレサーバ、NW/ST機器の監視）
そして転職を機にAppDynamicsを扱うようになりました。
自分自身の整理も含め、主観強めで両者の比較記事を残したいと思います。
前職と現職とでは監視対象がかなり違うので、共通で使用している部分の比較にとどめます。

#### Zabbix
オープンソースの統合システム監視ソフトウェア。
基本的には以下の単位で監視、検知、その後のアクションを実装する。
- ホスト：監視対象機器（サーバ、NW機器、ストレージ機器など）
- アイテム：監視項目（アイテムキーを指定し、対応するメトリクスを取得する。）
- トリガー：閾値（アイテムに紐づく）
- アクション：閾値を超過した際に発火するイベント（メール送信とかコマンド実行とか）

#### AppDynamics
SaaSのAPM(Application Performance Monitoring)ツール。
複雑なトランザクション・フローを自動的に認識し、全体図を自動で作成してくれる。
コードレベルでの原因究明もフォローしている。
※オンプレミス版もあるみたいですが弊社ではSaaS版を使っています。
以下の機能を提供
- APサーバモニタリング
- システムリソースモニタリング
- DBモニタリング
- エンドユーザモニタリング
- SAPアプリケーションモニタリング


# 比較
（Zabbixのほうが若干厚めな内容になっています。）


## 監視の開始

***Zabbix***
　・ホスト、アイテム（テンプレートの割り当て）の登録が必要
　・監視対象が一気に有効化されると各種pollerプロセスが高騰して、運用に支障が出る場合も。
　　事前に適切なチューニングが必要。（これが結構大変）
　・トリガー設定が複雑になってしまうことも。条件式を書くのが割と大変。
　　2.2と4.0で条件式の書き方が変わっており、Zabbixサーバをバージョンアップした際、ここはとてもネックになりました。（下記に一部抜粋）
|  | [2.2の条件式](https://www.zabbix.com/documentation/2.2/jp/manual/config/triggers/expression) | [4.0の条件式](https://www.zabbix.com/documentation/4.0/en/manual/config/triggers/expression) |
|:-:|:-:|:-:|
|  異なる値 |#| <>  |
|  論理AND |&| and  |
| 論理OR  | \| | or  |

***AppDynamics***
　・Machine Agentが監視対象に展開された時点で基本的リソース（各種CPU,メモリ）については監視可能
　・ビルドインのメトリクスだけではたりない場合はカスタムメトリクスを設定可能（スクリプトなど）
　・閾値設定が直感的にわかりやすい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589040/3ee8fef0-ecba-96cf-2e29-d049506ae5ff.png)

## WebGUI
***Zabbix***
　・メジャーバージョンアップでかなりUIが変わってしまう場合がある（2.2->4.0移行時は慣れるのに苦労しました。）
　・どこに何があるか直感的にわかりやすい（気がする。これに関しては慣れの要素が大きいとも思うが）
　・複数のメトリクスを同じグラフに表示させるときは、カスタムグラフの設定が必要
　・監視データの時間範囲を指定するときに、スライドバーで動かせる（時間の範囲を変えず、平行移動してデータを見たい時が結構あったので便利だった。）

***AppDynamics***
　・UIかっこいい
　・Metric Browserから任意のメトリクスを選択することで1つのグラフとして表示される
　・ダッシュボードを柔軟にカスタム可能
　・時間指定がZabbixに比べると少しやりづらい（これも慣れは大きいと思う、）

## 監視サーバの管理
***Zabbix***
　・Zabbixサーバの管理が大変。多機能がゆえに、監視対象が多いと監視機能自体のリソース使用が大きくなる。
　　複数あるPollerプロセスの特徴を理解し、適切に割り当てることが必要。
　・冗長構成をとるときのデータの同期、系切り替え/切り戻しを自前のスクリプトを組んでやっていた。
　（Zabbix6.0からHAクラスタ機能なるものが使えるようですね、便利）
　（EnterPriseユーティリティが使える環境なら冗長構成もかなり楽に管理できる）

***AppDynamics***
　・SaaSなので管理不要。

## その他、使ってみた感想
***Zabbix***
　・監視設定にナレッジがある程度必要だが、多機能で柔軟なため「監視ができなくて困った」ということはなかった。
　　IPMIやSNMPの監視からWeb監視まで幅広く対応できる。
　　自前のスクリプトを組んで外部チェックを使う方法はかなり重宝した。
　・有償サポートはかなり優秀で、レスポンスの速さ、提供されるツールは満足度がとても高かった。


***AppDynamics***
　・DBモニタリング機能で、実際に投げられたクエリが見られたり、トランザクションスナップショットからコード単位までドリルダウンして調べられるのは感動した。
　・拡張機能も充実（https://developer.cisco.com/codeexchange/explore/#products=AppDynamics%20Extension）
　・APMというだけあってアプリケーションを中心としたエコシステムの監視は、深いところまでAppDynamicsUI上でみられて便利

## 最後に
前職では、Zabbixと向き合うときは7割がた、Zabbixサーバの管理をしていました。
pollerプロセスを調整したり、監視データを保存するMySQLのチューニングしたり、、
（大変でしたが、これはこれで楽しかった）
SaaSのツールを使うことでその7割がごっそりなくなるのはありがたいなと思いました。
とはいえ、何を監視するかによって最適なツールは変わってくると思います。
ツールの特徴を最大限引き出せるエンジニアになっていきたいものです。


## 参考文献
1. [AppDynamics公式](https://docs.appdynamics.com/appd/22.x/22.1/ja/appdynamics-essentials)
2. [Zabbix4.0公式ドキュメント](https://www.zabbix.com/documentation/4.0/en/manual)
3. [日立ソリューションズ](https://www.hitachi-solutions.co.jp/appdynamics/)
GoogleスプレッドシートのVLOOKUPで検索キーの左側の列の値を取得する

# やりたいこと
例えば以下のような表があった時、VLOOKUPを使って"商品URL"を検索値として"商品名"を取得したい。
![スクリーンショット 2022-09-30 16.01.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130043/1a023c99-bafc-0f04-c204-bcd8003f912e.png)


# やり方
以下のように範囲を指定するとできる。
```
=VLOOKUP(検索値, {検索値として使いたい列, 取得したい値の列}, 2, false)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130043/6e7c3daf-b816-aba9-811c-7ec624a331ba.png)
ロジカル・シンキングについて

## ロジカル・シンキングとは

ロジカル・シンキングとは、日本語にすると論理的思考という意味になります。論理的思考と言われても、ピンとこないかも知れません。まず、論理と思考と分けて考えてみます。論理とは「思考の形式・法則。また、思考の法則的なつながり。」という意味です。思考とは「思いを巡らすこと。考え。」です。つまり、ロジカル・シンキングとは「根拠から結論へと筋道を立てて考え、何らかの意味合いを得る思考」ということがいえます。ロジカル・シンキングは、ツール、テクニックのようなものです。ロジカル・シンキングが使えるようになると、次のメリットを享受することができます。

>1. 問題解決ができるようになる
>2. コミュニケーションを上手に取れるようになる

## 問題解決の流れ
基本的に、問題解決は次の流れで行われます。

> 問題解決の流れ
>
>1. 問題の特定　（要素分析）
>2. 原因の分析　（ロジックツリー）
>3. 解決策の立案　（ロジックツリー）
>4. 解決策の実行

問題解決には様々なツールがあり、コンサルティングの現場でよく使われています。コンサルタントと言えば、頭が良くて優秀な人物というイメージがあるかと思います。しかし、問題解決のツールは、コンサルタントしか使いこなせない、難解なものではありません。誰もが、日常で普通に行っている思考パターンでもあります。それを具現化させて、分かり易く表現しただけにすぎません。難しいことでも、特別なことでもありません。改めて認識してみると「なるほど」と思えることが沢山あります。頭の中だけで巡らせた無言の思考を、紙に書いてみると、より鮮明に認識できるようになります。そして、コミュニケーションが上手く取れるようになると、相手に対する提案を具体化させることができ、話に説得力がつくようになってきます。

## ロジカル・シンキングの重要性
ロジカル・シンキングは、最近になって出てきツールではありません。古典的な手法かも分かりませんが、かといってレガシーというわけではありません。ロジカル・シンキングの重要性は、これからも一層、増してくると言われています。なぜかと言えば、時代の移り変わりに対応するためには、人とのコミュニケーションも変化せざるを得なくなるからです。今までのコミュニケーションは、限られた情報の中で、単純な問題を、ハイコンテクストで行われてきたと言われています。そして、これからの時代は、情報過多の中で、複雑な問題を、ローコンテクストで行わなくてはいけないと言われています。このような時代の中で、ロジカル・シンキングの必要性は更に増してくるということです。限られたドメインの中だけで、内輪の人間の中だけでしかコミュニケーションを取らないといった環境は、次第になくなってくるということです。さまざまな年代の人達と、さまざまな職種の人達とコミュニケーションを取らざるを得ない社会に、これからは突入していくということです。そのための武器になるのが、ロジカル・シンキングということになります。

## 論理展開
論理展開には演繹法と帰納法とがあります。演繹法とは、大前提を持ち出すことで、前提から結論を導く論理の展開の仕方のことをいいます。三段論法というのがわりますが、これには演繹法が隠れています。そして、帰納法とは、複数の事象の中から共通項を見つけ出して、その共通項を結論をすることをいいます。理系の人であれば、高校の数学で数学的帰納法という証明の仕方を勉強した記憶があるかと思います。数学的帰納法とは、先ず、n=1（初期値）が正しい事を証明して、更に、n+1も正しい事が証明されれば、nも正しいという事が結論づけられるといった証明方法のことです。この証明にも帰納法の考え方が応用されています。ただし、数学的帰納法には、nの数列が連続であるということが前提になります。連続になっていなければ、帰納法による証明はできないということにます。折角の思考ツールも使い方を誤れば、正しく機能しないということになります。

## 列挙
１つの問題点に対する原因を列挙するときに、漏れ、ダブりがないように、全体を列挙する必要があります。列挙した要素の中に、漏れ、ダブりがない状態になっていることをMECE（Mutually Exclusive, Collectively Exhaustive）ミーシェと呼びます。列挙した後、本当にMECEになっているか、念入りにチェックする必要があります。定性的な内容である程、MECEにすることは難しいと言われています。そんなときは「大きな漏れがなければよしとする」という考えを持つことが大事です。列挙に漏れがないか、あまり神経質になりすぎることは逆に良くありません。また、列挙が細かくなりすぎるときは「その他」として一括りにしてしまうことも１つの方法です。

## 掘り下げ
一つの要素から因果のつながりがあるより深い要素を上げていくことです。１つの問題点に対し、なぜ、なぜと考えながら。掘り下げていくことで、根本的な要因を突き詰めていくことができます。
【Swift】guard letについて改めて復習

## guard letの利点
- 早期リターン(さっさと処理を抜けたい時に使える)

## 使い方

サンプルコード1
定数(変数)のnilチェック

``` swift
let soga = nil

guard let soga = soga else {
    // nilの場合はreturn
    return
}
```

サンプルコード2
定数(変数)のnilチェック(複数版)

``` swift
let soga1 = nil
let soga2 = nil

guard let soga1 = soga1,
      let soga2 = soga2, else {
    // soga1がnilの場合、soga2の判定をせずにreturn
    return
}
```

サンプルコード3
定数(変数)の値の比較

``` swift
let soga1 = nil
let soga2 = nil

guard soga1 == soga2 else {
    // soga1とsoga2が同じでなければreturn
    return
}
```

サンプルコード4
guardの中で型変換

```swift
let soga = "2022"

guard let number = Int(soga) else {
    // intに変換できない時return
    return
}
```

サンプルコード5
guardの中で値を生成

```swift
guard let url = URL(string: "https://sogablog.net") else {
    // urlの生成が失敗(urlで無かった場合)return
    return
}
```

### おまけ
確かXcode 6くらいから以下の書き方ができる

``` swift
let soga = nil

guard let soga else {
    return
}
```

## 最後に
iOSアプリ開発をしています。
主にSwiftですが、最近は熱が入ってきてFlutterも🦾
色々やってます。もし良かったら見てってください。

https://sogablog.net/
各種ログAthenaSELECTクエリメモ

### ■TGWのVPCフローログ
`date`と`time`が別カラムのため、`CONCAT`する
```sql
SELECT
  CAST(CONCAT(CAST(date AS VARCHAR),' ', time, ' +00:00') AS TIMESTAMP WITH TIME ZONE) AT TIME ZONE '+09:00' AS dt_jst,
  request_ip,
  request_protocol,
  host_header,
  uri,
  method,
  status
FROM <table>
WHERE 
  CAST(CONCAT(CAST(date AS VARCHAR),' ', time, ' +00:00') AS TIMESTAMP WITH TIME ZONE) >= CAST('<YYYY-MM-DD HH:mm:SS> +09:00' AS TIMESTAMP WITH TIME ZONE)
  AND CAST(CONCAT(CAST(date AS VARCHAR),' ', time, ' +00:00') AS TIMESTAMP WITH TIME ZONE) < CAST('<YYYY-MM-DD HH:mm:SS> +09:00' AS TIMESTAMP WITH TIME ZONE)
ORDER BY dt_jst;
```

### ■WAFログ
timestampは`/1000`する
```sql
SELECT 
  FROM_UNIXTIME(timestamp/1000, 9, 0) AS timestamp_jst,
  terminatingruleid,
  action,
  httprequest.clientip,
  httprequest.country,
  CAST(httprequest.headers AS JSON) AS headers,
  httprequest.uri,
  httprequest.httpmethod,
  labels
FROM table
ORDER BY timestamp;
```

### ■CloudFrontログ
`-`は`'`で囲む
```sql
SELECT
  start,
  srcaddr,
  dstaddr,
  srcport,
  dstport,
  'flow-direction',
  protocol,
  'packets-lost-no-route' AS noroute,
  'packets-lost-blackhole' AS blackhole,
  'packets-lost-mtu-exceeded' AS mtuexceeded,
  'packets-lost-ttl-expired' AS ttlexpired
FROM <table>;
```
LightBurnに入力したDXFファイルに不要な線が入っている

## LightBurnに入力したDXFのファイルに不要な線が入っていた時の対処法についてまとめます

LightBurnに入力したファイルに以下のように線が入ってしまっていることがあります。
![スクリーンショット 2022-09-30 14.43.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/5f68c496-e40d-7e39-7ff1-aeb0e2ac02bc.png)

その際はデータをクリックした状態で、配置から「分割」を選択してください。（２ついるので注意、下の方の「分割」を選択します）
![スクリーンショット 2022-09-30 14.43.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/2d7002f0-1c7d-7307-121a-9a54462510d0.png)

そうすると全てのパーツが分割され、クリックできるようになるので一つ一つもしくは範囲選択で削除が可能です。
![スクリーンショット 2022-09-30 14.44.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/2392174d-cbba-c5e4-3124-f93993fa0339.png)

削除後のデータ
![スクリーンショット 2022-09-30 14.44.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/f6281da2-9474-acb3-6d2a-d4ec18820392.png)
Streamlitがあれば、REACTは不要なのか？

これはある程度、真理ではないかと思う。
ますますStreamlitには、コンポーネントが追加されるし、開発速度は格段に上がる
（もちろん、Reactのプロは、コンポーネントの開発に精を出してもらえばよいわけで、Pythonしかできない人には有難い話である）

# STREAMLITの課題
　先ほどの前提で、いまのところ問題になっているところを挙げてみる

* ＷＥＢサーバー機能

　例えばReactで作った翻訳アプリでは、ブラウザ（フロントエンド）からFetchして外部APIを叩くと、CROS制約に引っかかる。そこで一旦、バックエンドへリクエストを出し、サーバーから外部APIにリダイレクトしている。
　Streamlitに置き換えようとすると、サーバー機能がないため、NODEJSかFASTAPI等を使って、別にWEBサーバーを立てないといけない。
　Streamlit自体から外部APIを呼べば良いが、この際はJS→pythonにフルスクラッチで移植せねばならない。

* 機械学習
　機械学習と、巨大なモデルデータをSTREAMLIT内に保持することもできるが、そもそもGUIのために高い性能のPCを使うのももったいない。
最近はＧＰＵを積んだバックエンドで機械学習をさせるのが主流であり、表示はStreamlitでというのが流れなんだと思う。Pythonでは機械学習結果を表示させるライブラリもあるが、モデル自体を機械学習サーバーからSTREAMLITにレスポンスで持ってくるには、データ転送がネックになるだろう。そうなると、バックエンドの機械学習側でＶＩＥＷまで作って、レスポンスで画像を送るような変な構成になってしまう。


# 結論
　Streamlitはプロトタイプ的な用途ではよいが、実用化するようなアプリは作れないのだろうと思う。
 そうなってくると、バックエンドとＲＥＡＣＴのスキルは、やはり必須なんだろうと思う。
Fusion360のスケッチからdxfファイルを生成する

## Fusion360のスケッチからdxfファイルを生成する方法のメモ

以前LightBurnの動かし方を記事にしました。
LightBurnではDXFの拡張子をサポートしているので、
Fusion３６０からスケッチのDXF出力からインポートまでの方法についてまとめます。

https://qiita.com/kyazoooo/items/620850c6e5a18c5fd5dd


# Fusion360の起動
まずFusion360を立ち上げスケッチのあるプロジェクトを開きスケッチをクリックします。
![スクリーンショット 2022-09-30 14.32.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/c7d01e04-3a05-9916-94c9-136410817ab3.png)

右クリックをすると以下のようなコンテキストメニューが表示されるので、「DXF形式で保存」を押してください。
![スクリーンショット 2022-09-30 14.33.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/8fefb761-3b78-11d6-f4bc-03c9c2bc7f79.png)
![スクリーンショット 2022-09-30 14.30.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/8482f2f3-c477-4a10-9d03-d6f7adc61bdb.png)

あとは名前をつけて完了になります。

# おまけ
LightBurnに上記ファイルをアップロードするとこんな感じになります。縮尺もあっているのでそのままレーザ加工に使うことができます。
![スクリーンショット 2022-09-30 14.34.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/fa4b67ef-1870-8bcf-b412-fdda756874a9.png)

ただこのまま使おうとするとデータ作成時に意図せず生まれた、重複線情報がDXFファイル内にあったりするので、加工の際にその部分だけ2回レーザがあたってしまうなど起きてしまいます。
そうならないように以下の設定から重複した線を削除することができます。
![スクリーンショット 2022-09-30 14.34.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/d24c4c30-a74f-f61c-907d-a9a0b172b35f.png)

「最適化の設定」を開き、
![スクリーンショット 2022-09-30 14.35.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/d786e10e-c960-b57e-afd1-0c0f9be99bf3.png)

「重複する線を削除する」を選択してください。これで重複した線の削除が可能です。
![スクリーンショット 2022-09-30 14.34.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682778/0fbfd613-a8c0-c26f-a574-b53ecafa15e5.png)
【Flutter】多言語対応する

Flutter をAndroid Studioで開発する際、簡単に多言語化対応出来るので、そちらを紹介しようと思います・

### プラグインのインスルール

Android Studioのプラグインで、「Flutter Intl」をインストールします。
インストールが終わると「Tools」メニューに「Flutter Intl」の項目が追加されます。

![スクリーンショット 2022-09-30 14.34.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148871/8d9a2ed0-cf63-ab98-d5b1-00605c9672d2.png)

### Flutter Intlの導入

「Flutter Intl」の「Initialize for the Project」を選択します。
選択すると、下記が追加されます。

```yaml:pubspec.yaml
flutter_intl:
  enabled: true
```

また、lib配下に「generated」と「l10n」が追加されます。
ただし、「generated」にはエラーが表示されています。
下記を追加して、「Pub get」を実施することで、エラーは解消します。

```diff:yaml:pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
+  flutter_localizations:
+    sdk: flutter
```

### 多言語ファイルを追加

多言語のファイルを追加するために「Tools -> Flutter Intl -> Add Locale」を選択します。
下記のダイアログが表示されるので、「ja」など必要な言語を追加します。

![スクリーンショット 2022-09-30 14.43.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148871/5018f762-5f2a-a513-1070-c7d9cdf3c8d1.png)

それぞれのファイルで、多言語を記載します。

```arb:intl_en.arb
{
  "@@locale": "en",
  "title": "Title"
}
```

```arb:intl_ja.arb
{
  "@@locale": "ja",
  "title": "タイトル"
}
```

### UIに適用する

「MaterialApp」に対して、下記を追加します。

```diff:dart:main.dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
+      localizationsDelegates: const [
+        S.delegate,
+        GlobalMaterialLocalizations.delegate,
+        GlobalWidgetsLocalizations.delegate,
+        GlobalCupertinoLocalizations.delegate
+      ],
+      supportedLocales: S.delegate.supportedLocales,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
```

実際にUIに適用する場合、下記の記載をします。

```dart
S.of(context).title
```
これで、多言語対応が完了になります。

```dart
Text(S.of(context).title)
```

他に多言語対応のプラグインがありますが、複雑な多言語対応を行わない場合、標準で手軽に導入出来る本手順を参考にしてみてください。
DockerでMysqlサーバの構築

Dockerにて日本語化対応したMySQLサーバを構築します。
ポートホワードの設定を行い外部からは、ポートの33060で待ち受けします。

## ■完成イメージ
    +----------+            +-----------+            +-----------+
    |   App    |<---------->|   host    |<---------->| Docker    |
    |          | port=33060 | (Ubuntu)  | port=3306  | Container |
    |          |            |           |            |  (MySQL)  |
    +----------+            +-----------+            +-----------+

## ■構築環境
・Ubuntu 18.04.6 LTS
・Docker20.10.7

## 1. 作業用ディレクトリ作成
    $sudo mkdir ~/work/docker-mysql
    $cd ~/work/docker-mysql

## 2. Docker HubよりMysqlイメージ取得
    $ sudo dokker pull mysql

## 3. イメージの確認
    $ sudo docker image ls
    REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
    mysql        latest    4ddc4f9f1152   3 days ago   491MB

## 4. Mysql日本語化作業
### 4.1. Dockerfileを作成
```Dockerfile
    FROM mysql
    ADD my.cnf /etc/mysql/conf.d/my.cnf
```

### 4.2. my.cnfを作成
MySQLで扱う文字コードをUTF8に設定。
```my.cnf
    [mysqld]
    character-set-server=utf8
    [mysql]
    default-character-set=utf8
    [mysqldump]
    default-character-set=utf8
```

## 5. イメージ名を”mysql-ja”としてビルド
    $ sudo docker build -t nysql-ja .

## 6. イメージの確認
    $ sudo docker image ls
    REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
    mysql-ja     latest    b367bb02f70f   33 seconds ago   491MB
    mysql        latest    4ddc4f9f1152   3 days ago       491MB

## 7. コンテナ名を”mysql-main”で作成し起動
    $ sudo docker run -it --name mysql-main MYSQL_ROOT_PASSWORD=[パスワード] -p 33060:3306 -d mysql-ja

## 8. 起動済みコンテナの確認
    $ sudo docker ps
    ONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS                                                    NAMES
    2dd21af0940e mysql-ja "docker-entrypoint.s…"   2 minutes ago
    Up 2 minutes   33060/tcp, 0.0.0.0:33060->3306/tcp, :::33060->3306/tcp mysql-main

## 9. ホストOSから、33060ポートが待ち受け中か確認
    $ sudo netstat -ant
    Active Internet connections (servers and established)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State
    tcp        0      0 127.0.0.1:2947          0.0.0.0:*               LISTEN
    tcp        0      0 0.0.0.0:33060           0.0.0.0:*               LISTEN

## 10. MySQLコンテナにbashログイン
    $ sudo docker exec -it コンテナID bash
   
## 11. MySQLへログイン
    bash-4.4# mysql -u root -p[パスワード]
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    mysql>