OmniAICreator/Qiita-1.07M huggingface dataset:
Citrix Provisioning Serverの制限について

Citrix Provisioning Server(以下PVS) には、あまり知られていない制限があります。
起動するデバイスにvDisk を割り当てるためにvDiskプールやストアへディスクイメージを追加します。
追加されたvDisk は、データベース内の「DiskLocator 」テーブルに追加され、[DiskLocator].[id]の値が
自動で加算されるテーブル構造になっています。

ターゲットデバイスが起動するとStreamDb がデータベースの値を読み取りStreamProcess がターゲットデバイスに
配信を行います。
この処理中にあまり知られていない制限があるようです。
StreamDb は[DiskLocator].[id] の値を正しく読みだすのですが、StreamProcess は[DiskLocator].[id] の値が
65535 を超えると0 から始まるようです。
StreamProcess は、読みだした[DiskLocator].[id] の値でvDisk を読みだすのですが、65535 を超えてしまうと
そのid のvDisk を読みだすことができずエラーとなります。

仮にファームをバージョンアップしても[DiskLocator] の内容は保持されたバージョンアップされるので意味がなく、
新ファームとして再構築するか、DBCC CHECKIDENT 等を利用しid を初期化する必要があるようです。

大規模で多くのマスターを管理し、定期的にメンテナンスを行うような利用シーンでは、この問題に遭遇する可能性が高くなります。
AvaloniaのListBoxで複数選択を取得する【SelectedItems】

Avaloniaという、C#でマルチプラットフォームなGUIアプリを作れるフレームワークを試していたところ苦戦したので書きます

# 正解

```xml:てきとうなView.axaml
～
<ListBox
    ItemsSource="{Binding Items}"
    SelectionMode="Multiple"
    SelectedItems="{Binding SelectedItems}">
    省略
</ListBox>
～
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634181/9933abfb-1643-5b31-a2a4-0b4541477c96.png)
ListBoxでは、SelectionModeプロパティをMultipleにすることで、画像のように項目をCtrl+クリックで複数選択できるようになります
また、SelectedItemsプロパティから、選択している項目をすべてIListで取得することができます
私はObservableCollectionを使いました

```csharp:てきとうなViewModel.cs
//選択項目だけが入るコレクション
public ObservableCollection<ItemViewModel> SelectedItems { get; } = new();
//項目をぜんぶ入れるコレクション
public ObservableCollection<ItemViewModel> Items { get; } = new();

//あとはforeachとかでSelectedItemsを使えばオッケー
```
これだけです
また、上記の例ではなにも選択していない状態でもNullになりません

# なにに苦戦したんだよ
ListBoxには、選択項目を１つだけ取得できるSelectedItemというプロパティもあります

```xml:てきとうなView.axaml
～
<ListBox
    ItemsSource="{Binding Items}"
    SelectionMode="Multiple"
    SelectedItem="{Binding SelectedItem}">
    省略
</ListBox>
～
```
```csharp:てきとうなViewModel.cs
//選択した項目プロパティの実部
private ItemViewModel? _selectedItem;
//項目をぜんぶ入れるコレクション
public ObservableCollection<ItemViewModel> Items { get; } = new();

public ItemViewModel? SelectedItem
{
    get => _selectedItem;
    set => this.RaiseAndSetIfChanged(ref _selectedItem, value);
}
```

SelectedItemでは、このように選択項目が入るプロパティをViewModelに用意してあげれば、初期化せずとも選択項目が格納されます（ただし未選択ではNullになる）

このノリで
```csharp:てきとうなViewModel.cs
private ObservableCollection<ItemViewModel> _selectedItems;

public ObservableCollection<ItemViewModel> Items { get; } = new();

public ObservableCollection<ItemViewModel> SelectedItems
{
    get => _selectedItems;
    set => this.RaiseAndSetIfChanged(ref _selectedItems, value);
}
```
ObservableCollectionのプロパティを用意して作ろうとしましたが、_selectedItemsの実体がないのでNullになってしまいました

とても初歩的なミスでしたが、これでもXAMLとのバインドはできてビルドも通り、リストをぽちぽちしても何も起きないため、複数選択を実際に取得するまで気が付きませんでした
このバインドは結構ゆるくて、SelectedItemsもstring型のプロパティにバインドしてもビルドが通ります。なんでだよ！

こんな初心者の備忘録ですが、誰かの役に立ちましたら幸いです

# 参考資料
ListBoxのSelectedItemsのリファレンス

https://reference.avaloniaui.net/api/Avalonia.Controls/ListBox/94E8BFC6

ListBoxのドキュメント

https://docs.avaloniaui.net/docs/reference/controls/listbox
DockerでRubyの開発環境を構築してみた

## はじめに
幾度となく煎じられてきたテーマなので、

「そんなん知ってるわ！」

という方はブラウザバック推奨です。

自分は、この議題について煎じたことがありませんので、n番煎じをしようと思います。

## 背景
先日、`Ruby Association Certified Ruby Programmer Silver version 3`を取得しました。
- `Ruby公式資格教科書 Ruby技術者認定試験 Silver/Gold対応`
- 公式ドキュメント  

上記、2つが手元にあれば、あとは公式の模擬問題集を繰り返すだけで合格できる内容だったと思います。
詳細は、気が乗れば合格体験記として記事にしようと思います。

次の目標として、`Ruby Association Certified Ruby Programmer Gold version 3`の取得を目指しております。
メソッドを丸暗記で合格できたSilverに対して、Goldではオブジェクト指向プログラミングをはじめ、メタプログラミングという私がこれまで触れたことのない知見が問われる内容となっているので、どうしても手元で操作をしながらインプットしたくなりました。

しかし、ローカル環境に開発環境を構築したくなかったので、今回は手軽に`Docker`を用いた開発環境を構築しましたので、備忘録としてまとめております。

## 実行環境
OS: windows 11 pro
docker version: 25.0.2

## 本文  
まず任意のディレクトリを作成します。
```
$ mkdir ruby_docker
$ cd ruby_docker
```

次に、Dockerfileを作成します。
```
$ New-Item Dockerfile
// VS Codeをインストールしている場合は以下を入力
code Dockerfile

// VS Codeをインストールされていない場合
$ notepad Dockerfile
```
開かれたファイルに以下のテキストを入力。
```
FROM ruby:3.3-alpine3.19

RUN apk add --no-cache bash
```
続いて作成したDockerfileを実行するための、docker-compose.ymlを作成。
```
$ New-Item docker-compose.yml
// VS Codeをインストールしている場合は以下を入力
code docker-compose.yml

// VS Codeをインストールされていない場合
$ notepad docker-compose.yml
```
次に、作成したdocker-compose.ymlに以下のテキストを入力。
```
version: '3'
services:
  ruby:
    build: .
    volumes:
      - .:/app
    working_dir: /app
```
この時点で、Rubyをコマンドラインで実行することは可能ですが、作成したRubyファイルを実行する例も挙げる為に、rbファイルも作成します。
```
$ New-Item hello.rb
// VS Codeをインストールしている場合は以下を入力
code hello.rb
// VS Codeをインストールされていない場合
$ notepad hello.rb
```
```
# hello.rb
puts "Hello, World!"
```

それでは、実際にDocker上でRubyを実行する。

:::note warn
必ずDockerが起動していることを確認してください。
:::

Dockerの起動が確認出来たら、以下のコマンドを入力。
```
$ docker-compose run ruby bash
```
Dockerの起動とともにRubyをshell上で実行されます。
Rubyが正しく実行しているかを確認するために、以下のコマンドを実行してみます。
```
$ ruby -v
# ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-linux-musl]
```
Rubyのバージョン確認が取れましたので、実際にファイルを実行してみます。
```
ruby hello.rb
# Hello, World!
```
一通り、動作確認が済みましたので、コンテナを削除します。
```
$ docker-compose down
```
以上が流れとなります。
お疲れさまでした。

## まとめ
今回はRubyを取り上げましたが、このようにDockerを使うことでローカルの開発環境を綺麗な状態を保ったまま開発を進めることができますので、簡単なテストコードの実行の際には試してみてください。

最後まで読んでいただき、ありがとうございます。
Flutter on Desktopでウィンドウをリサイズ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3698535/1c8350ba-e425-a072-e66d-dc2312c66c69.png)

# やりたいこと
Flutter on Desktopでウィンドウサイズを指定したい

# 環境環境
Flutter 3.16.0 • channel stable • https://github.com/flutter/flutter.git
Tools • Dart 3.2.0 • DevTools 2.28.2
Windows 10 Pro 22H2 開発者モード
VS Code 1.86.1

# この記事を参考にしていただく条件
Flutter on Desktopの開発環境を構築済み

# C++で対応（WindowsOS限定）

## main.cppをのぞいてみる

Youre Flutte App
/windows
/runner
/main.cpp

```cpp:main.cpp
 Win32Window::Point origin(10, 10);
 Win32Window::Size size(1280, 720);
 if (!window.Create(L"flutter_sticky", origin, size)) {
   return EXIT_FAILURE;
 }
```
ウィンドウサイズを指定しているメソッドがありますね。ここを書き換えたらサイズ指定できました。

## win32_windows.cppを確認する

Youtre Flutte App
/windows
/runner
/win32_windows.cpp

```cpp:win32_windows.cpp
  HWND window = CreateWindow(
      window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
      Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
      Scale(size.width, scale_factor), Scale(size.height, scale_factor),
      nullptr, nullptr, GetModuleHandle(nullptr), this);
```
bool Win32Window::Createメソッドの中にネストされたCreateWindowクラスがあり、そこで定義されていることがわかります。

# プラグインで対応（ただしメンテされてないっぽい）

https://github.com/google/flutter-desktop-embedding

GoogleのGitのリポジトリにプロジェクトがありました。メンテが止まっているような雰囲気ですが、とりあえずやってみます。

/pluginに移動するとプラグインの設定例があります。

```yaml:pubspec.yaml
dependencies:
  ...
  menubar:
    git:
      url: https://github.com/google/flutter-desktop-embedding.git
      path: plugins/menubar
      ref: INSERT_HASH_HERE
```
この例がわかりづらかったのですがこれはmenubarを使いたい場合の例という意味のようです。今回使いたいのはwindws_reseizeなのでコピペして次のように書き換えます。

```yaml:pubspec.yaml
window_size:
    git:
      url: https://github.com/google/flutter-desktop-embedding
      path: plugins/window_size
      ref: a738913
```
INSERT_HASH_HEREにはコミットのハッシュ値を貼り付けます。わ、2年前のコミットだ。

```dart:main.dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:window_size/window_size.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  if (Platform.isWindows) {
    setWindowTitle('ぼくのFlutter Windows App');
    setWindowFrame(const Rect.fromLTWH(100, 100, 500, 500));
    setWindowMinSize(const Size(500, 500));
    //setWindowMaxSize(Size.infinite);
    setWindowMaxSize(const Size(500, 500));
    setWindowVisibility(visible: false);
  }

  runApp(const MyApp());
}
```
あとは野となれ山となれ。setWindowVisibilityでウィンドウが消えるかと思ったんだけど消えませんでした。

# 次にやりやいこと

## ウィンドウを閉じるときのイベントを取得

https://pub.dev/packages/window_manager

Flutter on Desktopでウィンドウを閉じるときのイベントを取得したいときはこのパッケージが良さそうです。まだReadmeを眺めただけですがイベントリスナーは一通り揃っているので自前で実装する必要がなくて助かります。それにしてもクロスプラットフォームだけあってLinuxも実装しているのが素晴らしい。早くDebianのGnomeで試してみたいです。

## ウィンドウの位置を記憶して次回起動時に反映する

fromLTWHの第一引数・第二引数をjsonで読み書きすれば出来そう。

## ごあいさつ
今回が初投稿になります。ぼく自身みなさんの記事が理解できないことも多いので、自分では当たり前のことでもなるべく細かく書くように心がけていこうと思います。

## この記事の続き
https://qiita.com/yoyo-misc/items/3c3dcf37f1e2ce988b5c
【Python】CSVをn列ごとに改行【サンキューChatGPT】

# できること
- 指定したCSVファイルを読み込み
- 指定した列数（今回は8列）ごとに区切る
- 1行目の処理が終わったら2行目以降も同様の処理を繰り返す
- 新しいCSVファイルを保存する

# Pythonコード
```python:
import csv

def process_csv(input_file, output_file):
    with open(input_file, 'r', encoding='utf-8') as csv_input:
        reader = csv.reader(csv_input)
        with open(output_file, 'w', encoding='utf-8', newline='') as csv_output:
            writer = csv.writer(csv_output)
            
            for row in reader:
                # リストを8列ごとに分割
                divided_row = [row[i:i+8] for i in range(0, len(row), 8)]
                
                # 分割されたリストを書き込み
                for sub_row in divided_row:
                    writer.writerow(sub_row)

# 入力ファイルと出力ファイルのパスを指定
input_file_path = 'input.csv'
output_file_path = 'output.csv'

# CSVファイルを処理
process_csv(input_file_path, output_file_path)
```

## その他、参考
### ChatGPTへのプロンプト
今回もChatGPTにコードを出力してもらいました。プロンプトは下記です
```text
横に長い数行のcsvファイルがあります。これを8列ごとに改行したいです。

#処理前
データ1,データ2,データ3,データ4,データ5,データ6,データ7,データ8,データ9,...

#処理後
データ1,データ2,データ3,データ4,データ5,データ6,データ7,データ8,
データ9,...

#備考
1行目の処理が終わったら2行目以降も同様の処理を繰り返す

上記を実現するPythonコードを作成してください。おねがい！！！！！！
```

# あ ざ し た
あざした。
普段は事業開発支援やマーケティング支援やライターや映像出演（患者役）などをしています。FGOが好きです。でもゾウさんのほうがもっと好きです。お仕事ください。
ServiceNowでのjson処理の一部

```javascript:qiita
var payload = {
   "items": [
      {
         "className": "u_cmdb_ci_mongoose_web_server",
         "lookup": [],
         "values": {
            "name": "Mongoose@owa-sd-01",            
            "version": "5.5",
            "running_process_command": "c:\\clouddimensions\\mongoose.exe",
            "sys_class_name": "u_cmdb_ci_mongoose_web_server"
         }
      },
      {
         "className": "cmdb_ci_win_server",
         "lookup": [],
         "values": {
            "name": "OWA-SD-01"
         }
      }
   ],
   "relations": [
      {
         "type": "Runs on::Runs",
         "parent": 0,
         "child": 1
      }
   ]
};

var jsonUtil = new JSON();
var input = jsonUtil.encode(payload);
var output = SNC.IdentificationEngineScriptableApi.createOrUpdateCI('ServiceNow', input);
gs.print(output);
```
Pico + FreeRTOS  SMP で USB に 表示出力するとハング


## はじめに

Raspberry Pi Pico + FreeRTOS SMP で stdio を usb にすると std::cout でたまにハングする。
どこかの設定で回避できるのかも知れないが、見つけられなかった。
正しい処置が不明だが、調べた事と 考えた対策を記述する。

## 発生事象
- 開発環境
  -  Raspberry Pi Pico C/C++ SDK 1.5.1
  -  FreeRTOS branch main #982
  -  Windows11 + VSCode
<br>

- task 1本でもハングする
  - task を 1本だけ起こして そこから出力しただけでもハングする
  - `std::cout << std::endl` 2行は 発生頻度を上げるため
  - `std::cout << std::endl` を増やしたり、delay を小さくすると 更に頻度アップ

    ```C++
    void test_func(void*)
    {
    	int n = 0 ;
    	while(true)	{
    		vTaskDelay( pdMS_TO_TICKS(50) ) ;
    		std::cout << n++ << std::endl ;
    		std::cout << std::endl ;
    		std::cout << std::endl ;
    	}
    }
    
    int main(void)
    {
    	stdio_init_all() ;
    	xTaskCreate(test_func, "test_func", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL) ;
        vTaskStartScheduler();
    }
    ```
    ```
    pico_enable_stdio_usb (${project_name} 1)
    pico_enable_stdio_uart(${project_name} 0)
    ```

## 確認内容

- stack size
  stack は 確認できた時点で 108 x 4 byte 残っており、stack 不足では無さそう。<br>stack size を増やしても効果なし
    ```
    IDLE1           R       0       232     4
    IDLE0           R       0       226     3
    test_func       B       1       108     2
    Tmr Svc         R       31      972     5
    ```

- `configUSE_PREEMPTION`
    変更しても変化なし

- `configRUN_MULTIPLE_PRIORITIES`
    頻度は下がるがハングする

- core を 0 に固定
  `vTaskCoreAffinitySet()` で core を 0 に固定すると **発生しない!!**

- core を 1 に固定
  `vTaskCoreAffinitySet()` で core を 1 に固定すると 頻度爆上がり

と言うことで、`std::cout` 実行時に core 1 が割り当てられると 不都合があるようだ。

## 対策
- `std::cout` の実行時は core 0 に固定する
- `std::cout` 呼び出し時に 一々 `vTaskCoreAffinitySet()` するのは面倒なので、自分の stream を定義する
- ここで core 0 に固定してから `std::cout` に渡し、終わったら元に戻す
- このコードで ハングしなくなった
    ```C++
    class CNkStringBuf : public std::stringbuf
    {
    	virtual int sync() override
    	{
    		UBaseType_t  pre = vTaskCoreAffinityGet(NULL) ;
    		vTaskCoreAffinitySet(NULL, 1) ;
    
    		std::cout << str() << std::flush ;
    		str("");
    
    		vTaskCoreAffinitySet(NULL, pre) ;
    		return 0;
    	}
    };
    
    namespace nk
    {
    	CNkStringBuf cout_buf ;
    	std::ostream cout(&cout_buf) ;	
    }
    
    void test_func(void*)
    {
    	int n = 0 ;
    	while(true)	{
    		vTaskDelay( pdMS_TO_TICKS(50) ) ;
    		nk::cout << n++ << std::endl ;
    		nk::cout << std::endl ;
    		nk::cout << std::endl ;
    	}
    }
    ```

## まとめ
- `std::cout` を core 0 で実行するとハングしない
- 本来の対策 ( 設定? ) は 未だ不明
- 対策として、自前の stream で core 0 に固定してから `std::cout` を呼ぶ

## おまけ
- Core の lock guard を作ってみた

```C++
class CCoreLock
{
protected:
	UBaseType_t  pre ;
public:
	CCoreLock() = delete ;
	CCoreLock(uint core_id)
	{
#if configNUMBER_OF_CORES>1 && configUSE_CORE_AFFINITY==1
		pre = vTaskCoreAffinityGet(NULL) ;
		vTaskCoreAffinitySet(NULL, 1<<core_id) ;
#endif
	}

	~CCoreLock()
	{
#if configNUMBER_OF_CORES>1 && configUSE_CORE_AFFINITY==1
		vTaskCoreAffinitySet(NULL, pre) ;
#endif
	}
} ;

class CNkStringBuf : public std::stringbuf
{
	virtual int sync() override
	{
		CCoreLock core(0) ;
		std::cout << str() << std::flush ;
		str("");
		return 0;
	}
};
```
【JavaScript】localStorageの容量が不足した際に処理を実行する方法

以下のように記述することでlocalStorageの容量が不足した場合の処理を記述できます。

```js
    try {
      localStorage.setItem('sample', 'sample')
    } catch (err) {
      if (err instanceof DOMException && err.name === 'QuotaExceededError') {
        console.log("localStorageの容量が不足しています。")
      }
    }
```
VSCodeにてPythonのmissing importsに苦戦した

# VSCodeのmissing importsが消えなくて困った…

私はPythonのコーディングをする際、VSCode上のターミナルにて仮想環境を有効化しています。
そのため新しいプロジェクトを作成する流れとしては…

1. macのターミナル上で実行
`mkdir`
`cd`
`code .`
2. VSCode上のターミナルで実行
`python3 -m venv venv`
`source venv/bin/activate`
必要であれば`pip install`

という形でした。

今回もいつも通りにパッケージたちをimportし、VSCodeのターミナルにて`python3 -m pip install`とインストールしていったところ、一つのパッケージだけPylanceのエラー`Pylance(reportMissingImports)`が消えませんでした。
しかし試しにデバッグの開始を行ってみると、そのパッケージを用いたプログラムが問題なく動作しました。
import自体はできているが、VSCode上では認識できていない様子？

不便なので直そうと色々試しましたが、なかなか治らない…。
## 試したけどダメだったこと
### 1. Python: Select Interpreter
異なるインタープリターを設定していないか、仮想環境がちゃんと有効になっているのかを確認する。
VSCode上で`Ctrl + Shift + P`を押してコマンドパレットを開き、`Python: Select Interpreter`を行ったが、正しく今の仮想環境が選択されていた。
### 2. pip installのやり直し
VSCodeのターミナルにて`python3 -m pip uninstall`からの`python3 -m pip install`を再度行ったが、症状は変わらず。
### 3. キャッシュのクリアと再起動
VSCode上で`Ctrl + Shift + P`を押してコマンドパレットを開き、`Python: Clear Cache and Reload Window`をしたものの、症状は変わらず。
全てのパッケージがmissing importsになったあと、少しずつ読み込まれていくが、問題のパッケージのみmissing importになる。ダメです。

### 4. 仮想環境の作り直し
venvを消してもう一度作成したが、変わらず。

# 解決策

結局、macのターミナル上でPythonの仮想環境を作成して有効化、その後VSCodeを起動する形に変えることで解決しました。
* macのターミナル上で実行
`mkdir`
`cd`
`python3 -m venv venv`
`source /venv/bin/activate`
`code .`

冒頭のものから上記の流れへ変更し、VSCodeのターミナルを使わないようにしました。
VSCodeが開くと、無事にmissing importsのエラーは消えていて、問題解決。

その後のpip installはmac・VSCodeどちらのターミナルでも問題なさそうでした。
[Windows11]初期セットアップお見せします

# はじめに
どうも、SobaNyakuです。蕎麦と蒟蒻が大好きです。
最近Win11の初期セットアップをする機会があったので、備忘として残しておきます。
他にこだわりある方いたら是非教えてください。
（OS初期設定やNetwork設定など使える状態になっている前提です）

# 設定
## 言語設定
Setting page : `Settings > Time & language > Language`

| setting | value |note|
|:-:|:-:|:-:|
| Windows display language  | `English`  |勉強用に英語|

## Taskbar setting
Setting page : `Setting > Personalization > Taskbar`

### Taskbar items（タスク バー項目）
* Search：`Hide`
誤操作（検索したくなくても押してしまうこと）多いのと、`win`ボタンを押してから文字入力すれば検索できるため
* Task view : `Off`
これもあまり使わないため。タスク切替する際は、`Alt+Tab`で！


### Taskbar corner overflow（タスク バーコーナーのオーバーフロー）
* Windows Updae Status***以外*** : `Off`
Windows Update Status以外はオーバーフローメニューには不要だと感じているため

### Taskbar behaviors（タスク バーの動作）
* Taskbar alignment（タスクバーの配置） : `Left`
これは好み。昔から使ってる人は左が慣れているのでは。
* Select the far corner of the taskbar to show the desktop：`Off`
意図しない押下多いのと、デスクトップを表示するには`Win+D`で！

## スタート
Setting page : `Setting > Personalization > Start`

### レイアウト
* さらにピン留めを表示する：`On`
おすすめが邪魔なため
* 最近追加したアプリを表示する：`Off`
これも邪魔なため
#### フォルダー
* 設定だけ:`On`
設定はよく使うので、ここに配置

## 色
Setting page : `Setting > Personalization > 色`
* モードを選ぶ：`ダーク`
黒基調の方が、目が疲れない（気がする）


# WSL
Windows Subsystem for Linux。
インストール方法とても楽になっている！！

https://learn.microsoft.com/ja-jp/windows/wsl/install

# Browser

「起動時に前回のページを復元する」を設定する。
Browserを閉じても復元してくれるので便利。
どのBrowserでもだいたいある。Edgeの場合は以下。

https://mypigchan.com/edge-kidouji


# ファンクションキー

`Fn` + `Esc`で機能切替
マルチメディアキーが優先されていること多いので、ファンクションキーを優先する

https://xtech.nikkei.com/atcl/nxt/column/18/02329/011600012/

# タスク マネージャー
プロセスのカラム追加(`PID,プロセス名,コマンド ライン`あたり)

カラム名にマウス オーバーして右クリックで選択可能。



# 追加アプリ

* [Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code)
Editor。markdownやdraw.ioを書くのに重宝している。
* [Screenpresso](https://www.screenpresso.com/ja/)
ScreenShotしたものを加工するのにとても便利。
* [Clibor](https://chigusa-web.com/clibor/)
クリップボード履歴は`win+v`で足りるが、定型文を貼り付けられるため便利。
* [WinMerge](https://winmerge.org/?lang=ja)
ファイルやフォルダ間の比較ツール。Linuxのdiffと同じように。
* [MobaXterm](https://mobaxterm.mobatek.net/)
sshクライアントツール。正直好みのものでいいと思う。便利そうなので使おうとしている。まだ使ったことない。
* [Sysinternals Suite](https://learn.microsoft.com/ja-jp/sysinternals/downloads/sysinternals-suite)
トラブルシューティング ユーティリティ。procmon,procexpあたりはよく使うか。
* [Wireshark](https://www.wireshark.org/)
NW系の調査には必須。
* [Fiddler](https://www.telerik.com/fiddler)
Wireshark同様、NW系調査（Browser系）で必須


# おわりに
最後まで見ていただき、ありがとうございます。
よかったらチャンネル登録（フォロー）、高評価（いいね:heart_decoration:）、コメント:pen_fountain:などなど何でもお願いします:pray:

週一で投稿目指しています。もし何かリアクションをしてくれるとやる気が出るので、次週は投稿することを約束します。絶対！絶対！

※今週も約束守れました。いつもありがとうございます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659255/d0ce92f5-3e78-f2db-bc63-832ed116771b.png)
食事のアドバイスをするGPTsを作ってみた

初めてGPTsを作ってみたのでレポ。

# 作り方

作り方に関しては巷で溢れかえっていると思うので簡単に。
以下のEditerから以下のようなCreate ViewとPreviewが出てきて、作りながら修正を繰り返せる形です。

![スクリーンショット 2024-02-10 23.30.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3277259/072a8a6d-bf0f-4014-c2fb-cc1265014811.png)

https://chat.openai.com/gpts/editor

## 作ってみた感想
何の記事も参考にせず、GPT Builderに聞かれたことに対して答えていくだけで、あっという間に完成しました。
AIってすごい・・プログラマーの存続の危機を感じました。

# どんなGPTs？

今回作ったのは、食事の写真をアップロードすると、その食事の栄養バランスや、ダイエット、特定の栄養素の摂取、健康に良い食習慣についてのアドバイスをしてくれるGPTsです。

健康やダイエットに対してネガティブな印象を持っているユーザに対するケアとして、以下の特徴を持たせるようにしました。
- カジュアルな応対
- 「改善点」の他にも、「良い点」を見つけてアドバイス
- 箇条書きで見やすく

# 完成品

パスタの写真を投下してみました。
![スクリーンショット 2024-02-10 23.45.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3277259/27d15d24-8f0a-e8e9-c945-3cff6a52bd9b.png)

的確に写真を読み取って、良い点・改善点を挙げてくれています。

次にカップラーメンを投下。

![スクリーンショット 2024-02-10 23.46.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3277259/59f8e925-ad0c-2236-d60c-ca0d9f272aeb.png)

どうにか「良い点」を捻り出してくれました。
最後の文、こんなに応援されるとカップラーメンなんて食べてすみません・・という気持ちになります・・

## おわりに
似たような食事アドバイスGPTsは他にもあると思いますが、よければ利用してみてください。
今度は競合がいなさそうな少し凝ったGPTs作ってみようと思っています。

https://chat.openai.com/g/g-UnMr4X8gE-shi-shi-adobaiza
棚卸表アプリを作りたい

3回目の投稿です。初心者ですが今回はＧlideを利用して<strong>棚卸在庫入力アプリ</strong>を作りたいと思います。作成の動機は、自工場において原材料の棚卸作業と帳票の集計を紙とエクセル手入力で実施しているため少しでも手間を減らすことが出来ないか？と言う思いからです。

# 棚卸在庫入力アプリを作りたい


:::note info
イメージ図
:::


![棚卸表アプリ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/9eb7cef2-25ad-d2ed-2793-e9919e767836.png)


>参考にした記事

https://qiita.com/Rs_n_ishii/items/3729293c223ed5ee2db6


## Glideを使ってアプリを作る
ノーコードでアプリが作れるGlideを活用して棚卸表をスマホに反映する

<details><summary>棚卸表エクセルシート</summary>


![スクリーンショット (54).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/7adc0e74-3f4e-07f8-2170-01a0f5cc6ac7.png)

</details>



しかし初めから頓挫
参考記事ではＧlideの作成のはじめの部分で　このように記載されていました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/5b872bf9-6776-4b29-5c8c-4f9a40c20ac7.png)

だけど自分のアカウントでＧlideを開けてみると

![スクリーンショット (32).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/ff73664e-6ca8-8fcc-eda5-acf345c4cd96.png)

この先から頓挫
参考記事では「PROJECTS」　そんな選択肢はないし　どこから進めればいいのかわからない
Qitta記事を見ると　Glide無料版では作れるアプリが一つだけ
過去に作ったアプリを削除すると出来ました。


### Glide作成画面

登録画面①
itemsを選択しDateGridを選択

![スクリーンショット (56).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/4a5d56d3-ee54-85ac-ee46-af6697f8939c.png)


登録画面②
列名を修正し必要な列を＋マークで増やす。
データは本来、スプレットシートで反映させたいのだが
今回は、事前に手入力をする。

![スクリーンショット (48).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/1c21a46a-8d64-0b58-36b2-681fd3dc3ee8.png)


登録画面③
シェアボタンを押すとＱＲコードが出るのでスマホのカメラで読み込む

![スクリーンショット (57).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/2bc72d29-6619-a1b8-b397-2f22ed9891ba.png)

すると下のようにスマホで棚卸表に直接入力できるようになった。



https://twitter.com/6IfGib4SMp86140/status/1758042633119891612


入力後エクスポート
![スクリーンショット (58).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/49fcaf46-8fc3-198e-edd5-db5a90818de2.png)

出力したシート
![スクリーンショット (52).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3643363/50b8c287-d62e-41d0-bf8f-03bf46617031.png)
文字化けして失敗　何か登録が必要なのか？調べて改善します。

このシートをエクセルの棚卸表に貼り付けて作業完了。


# 工場従業員の意見

　ベーカリー担当責任者に意見を聞いたところ
 
　・棚卸表からエクセルシートに打ち換える作業が約20分くらい
 　打ち換え作業が全くなくなれば楽です。
  
　・スマホだと画面が小さくてスクロールする必要があり少し手間取る
 
　・棚卸の監査を他の人にしてもらう必要があり紙を結局出力する必要がある

 微妙に否定的な意見が出ました。

# 反省点

・当初はスプレットシートを活用し、事前の入力作業もカウント後の移し替えも作業を無くしたかった。
　有料であればスプレットシートを活用できるので時間は有料で試作品を作ってみたい。

・文字化けについては、調べて（師匠に聞き）改善します

・棚卸表は、他の人に監査をする必要があり複数人でこのシートを共有化できるようにする必要がある

・棚卸表は少なくとも10枚以上のシートがあり　アプリでも複数枚のシートにする必要がある

 課題はまだまだあるが　もう少し試作品を作っていきたい。他の帳票でもスマホやタブレットに置き換えて作業時間が減少するプロトタイプを作れないか探っていきます。
Unreal Engine勉強メモ

主に用語などについてメモ

- ランドスケープモード
  - 地面を描くモード
- ライトの種類
    - Directional　Light
        - Ctrl＋Lで方向を変更可能
    - Sky　Atomosphere
        - 空を作る
        - DirectionalLightと連携
            - DirectionalLightのSkyAtomosphereにチェックを入れると空に太陽が出る
    - SkyLight
        - 周囲をキャプチャしてできた画像から環境光を作成
        - Realtime Captureにチェックを入れると、リアルタイムに環境光が変わる
    - Volumetric　Cloud
        - 雲を追加できる
    - Exponential Height Fog
        - 空とランドスケープの間を埋めてくれる
        - Volumetric Fogにチェックを入れると、よりリアルな表現になる
    - その他ライト
        - Point Light
        - Spot Light
        - Rect Light
    - Post Process Volume
        - カメラがPost Process Volume内に入ると有効化
            - Infinite Extent(Unbound)にチェックを入れると、境界と関係なく有効になる
        - Exposure
            - 測光モードでAEの設定ができる
    - Lumen
        - グローバルイルミネーション
        - 間接光の表現。動的に計算結果が反映される
    - MegaScan
        - 公開アセット
        - Quixel Bridge
    - スタティックメッシュ
        - 動かないモデルのこと
    - フォリッジモード（SHIFT＋３）
        - 草とかを複数個一気に配置できる
        - ペイントで描く
        - SHIFTを押すと、消去モード
        - 風をあてる方法
            - マテリアルのWind→Enable Glass Windにチェック
    - NaniteとLOD
        - メッシュのレンダリングを軽くするための工夫
        - LOD
            - Level Of Detail
                - 離れているときはメッシュを大きくしてポリゴン数を減らし、近づくとメッシュを細かくする
        - Nanite
            - LODの切り替わりをわかりにくくするような処理
VirtualBOXのVMが唐突に起動しなくなった日（5637エラー）

## 事の始まり
- Windows11環境にてVyOSをVirtualBoxで構築しようとしたところKernel-panicが発生。
- VirtualBoxのバージョンが6.1系で古かったため、7.0系にアップデート
- その状態でVMを起動したところ、エラーが発生して起動せず
(VM起動時のログは以下の通り。
```
> "c:\Users\[UserName]\VirtualBox VMs\[VM_NAME]\Logs\VBoxHardening.log"
2b0c.18bc: supR3HardenedWinSetupChildInit: Start child.
2b0c.18bc: supR3HardNtChildWaitFor: Found expected request 0 (PurifyChildAndCloseHandles) after 0 ms.
2b0c.18bc: supR3HardNtChildPurify: Startup delay kludge #1/0: 265 ms, 17 sleeps
2b0c.18bc: supHardNtVpScanVirtualMemory: enmKind=CHILD_PURIFICATION
2b0c.18bc: Error (rc=-5637):
2b0c.18bc: NtQueryVirtualMemory failed for 0000000000000000: 0xc000010a
2b0c.18bc: Error (rc=-5637):
2b0c.18bc: supHardenedWinVerifyProcess failed with -5637: NtQueryVirtualMemory failed for 0000000000000000: 0xc000010a
2b0c.18bc: Error -5637 in supR3HardNtChildPurify! (enmWhat=5)
2b0c.18bc: supHardenedWinVerifyProcess failed with -5637: NtQueryVirtualMemory failed for 0000000000000000: 0xc000010a
2b0c.18bc: supR3HardNtEnableThreadCreationEx:
```
- エラーの内容としては、Memory関連のエラーが発生してるとのこと。
- エラーコードで調べたところ、サードパーティ製のソフトウェア及び、アンチウイルスソフトとの干渉の可能性アリ。
- 起動実績のある他のVMも同様のエラーで起動しない事象が発生。
## 試したこと
1. VirtualBoxの再インストール
    - 事象改善せず。
2. ウィルス対策ソフトのリアルタイムスキャンなどの一時的な停止
    - 事象改善せず。
3. 直近のWindowsUpdateファイルの削除
    - 事象改善せず。
4. Hyper-vの無効化
    - VyOSのインストールエラーがHyper-Vに起因している可能性あるという記事顔あったため、一時的に無効化を実施。
    - 事象は改善せず。
4. その他某のソフトウェアのアンインストール
- https://forums.virtualbox.org/viewtopic.php?t=109422 を参考にした。
Windhawkというソフトウェアが悪さしている　というお話。
- ダメ元でPC内を検索したところ、該当ソフトあり。(いつぞや興味本位で入れた記憶あり）
- 該当ソフトウェアをアンインストールしたところ無事起動！
## 気になったところ
- Windhawk自体は随分前に入れており放置していた。今回のVyOSの環境構築前に他のVMを構築していたがその際は問題はなかった。
- 今回、VyOSのKernel-panicの問題の対策として、VirtualBoxのバージョンを7系に上げたところ、構築しようとしていたVMとその他VMで問題が発生した。
- ということは、VirtualBox7系とWindhawkの相性の可能性がある。
- 余談だが、Windhawkをアンインストールした結果、VyOSのKernel-panic問題は再現しなくなった。
- ただ、以下のエラーが発生中。こちらの解消方法は別途、VyOSのインストール記事で取りまとめ予定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192332/8ec75795-f346-5e2d-a8fe-675f6a2d59de.png)
神経衰弱でカードをめくる処理

Unityで神経衰弱を作るために左クリックしてカードをめくる処理を実装します。
神経衰弱に必要なカードの画像は以下のURLのサイトのものを使わせてもらいます。
https://joytas.net/programming/website/js_flip-2

URLのサイトではJavaScriptで神経衰弱を製作していますが、今回の記事ではC#とUnityを使って作ります。実行環境はUnity 2022.3.10fです。

# カードの準備
上記のURLから画像をダウンロードしてUnityのProjectビューのAssetsフォルダにドラッグします。数字とマークが書かれたカードの表面の画像の中から1つ選んでSceneビューにドラッグします。カードの裏面の画像もSceneビューにドラッグします。カードの裏の画像はカードの表の画像の子オブジェクトにして、ローカル座標を原点に指定しておきます。

![c01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3644510/75292d62-8a85-9aa2-5436-bb12760cb4cf.gif)
例：カードの表

![z01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3644510/070acbfc-7860-b299-b1ee-00b3a9cc2770.gif)
例：カードの裏

次にInspectorビューのOrder in Layerの値を、カードの表は0、カードの裏は1とします。これでカードの裏面によって表が見えなくなっています。
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3644510/fc50569f-3bf1-5827-1706-8107a149907a.png)

# カードをめくる処理
カードの表面の画像にBox Colliderをアタッチします。
以下のスクリプトを作成してMain Cameraにアタッチします。

```C#:CardClick.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CardClick : MonoBehaviour
{
    private GameObject clickedObject;
    private SpriteRenderer sprite;

    void Update()
    {
        if (Input.GetMouseButtonDown(0)) //マウス左ボタンをクリックした場合
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); //カメラからクリックした座標にレイを飛ばす
            RaycastHit hit = new RaycastHit();

            if (Physics.Raycast(ray, out hit))
            {
                clickedObject = hit.collider.gameObject;
                sprite = clickedObject.GetComponent<SpriteRenderer>();
                sprite.sortingOrder = 2 - sprite.sortingOrder; //レイが当たったカードの表面のOrder in Layerの値を0と2で切り替える
            }
        }
    }
}
```

これでカードを左クリックするたびに裏・表の表示が切り替わるようになります。

# 参考
https://youtech-school.com/note/%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E3%81%95%E3%82%8C%E3%81%9F%E3%82%B2%E3%83%BC%E3%83%A0%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B/
CSSジェネレーターを使ってリボンデザインを簡単に実装する

## 概要

ウェブサイトにおいて、リボンデザインはユーザーの注目を引きやすく、特定の情報やプロモーションを際立たせる効果的な手法です。この記事では、`CSS Generators`を使って、簡単にリボンデザインをウェブサイトに追加する方法をご紹介します。`CSS Generators`から好みのリボンを選択し`ribbon`クラスのスタイルとしてコピー＆ペーストするだけで、ウェブサイトにリボンを簡単に追加できます。例えば、#1~2はリボンのみを実装し、#3~6はボックスに対してリボンを実装します。

https://css-generators.com/ribbon-shapes/

## 実装例

https://github.com/Front-Tips/css-ribon-shapes-collection/tree/master

```html:index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="css/reset.css" />
    <link rel="stylesheet" href="css/tutorial.css" />
    <title>Front Tips - CSS Ribon Shapes Collection</title>
  </head>
  <body>
    <div class="box">
      <div class="ribbon">
        <b>Front Tips</b>
      </div>
    </div>
  </body>
</html>
```

```css:css/reset.css
:root {
  --background-color: #181824;
  --text-color: #fff;
}

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

html {
  height: 100%;
  font: 200 145%/1.5 Verdana, sans-serif;
  font-family: system-ui, sans-serif;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  height: 100%;
  padding-top: 2rem;
  margin: auto;
  color: var(--text-color);
  background-color: var(--background-color);
  cursor: default;
}

.box {
  position: relative;
  width: 400px;
  height: 300px;
  margin: 2rem;
  font-size: 2rem;
  font-weight: bold;
  background: #383854;
  border-radius: 1rem;
  place-self: initial;
  grid-area: 1/1;
}
```

```css:css/tutorial.css
/* Made by https://css-generators.com/ribbon-shapes/ */
.ribbon {
  font-size: 28px;
  font-weight: bold;
  color: #fff;
}
.ribbon {
  --f: 0.5em; /* control the folded part */

  position: absolute;
  top: 0;
  right: 0;
  line-height: 1.8;
  padding-inline: 1lh;
  padding-bottom: var(--f);
  border-image: conic-gradient(#0008 0 0) 51% / var(--f);
  clip-path: polygon(
    100% calc(100% - var(--f)),
    100% 100%,
    calc(100% - var(--f)) calc(100% - var(--f)),
    var(--f) calc(100% - var(--f)),
    0 100%,
    0 calc(100% - var(--f)),
    999px calc(100% - var(--f) - 999px),
    calc(100% - 999px) calc(100% - var(--f) - 999px)
  );
  transform: translate(calc((1 - cos(45deg)) * 100%), -100%) rotate(45deg);
  transform-origin: 0% 100%;
  background-color: #bd1550; /* the main color  */
}
```

## 参照

https://front.tips/css-ribbon-shapes-collection/

`Front Tips`はフロントエンド開発のこんな手法あったんだという情報を知れます。
自らの備忘録のために投稿してますが、なにかお役に立てましたら幸いです！:clap:
また、なにか間違ってましたらご指摘いただけますと幸いです！:pray:
dvipdfmxを使うとbookmarksopenでしおりが展開しない問題

# dvipdfmxを使うとbookmarksopenでしおりが展開しない
platexで文書を組版していて、dvipdfmxで生成したpdfのしおりが展開されない問題がありました。例えば以下のような場合です。

```latex
\documentclass{jsarticle}
\usepackage[dvipdfmx,%
bookmarksopen=true,% ブックマーク展開
bookmarksopenlevel=3,% 展開レベル
% hidelinks,% リンク枠色なし
]{hyperref}
\usepackage{pxjahyper} % 文字化け防止

\begin{document}
\tableofcontents
\part{piyo}
\section{hoge}
section.
\subsection{hogehoge}
subsection.
\subsubsection{hogehogehoge}
bookmarksdepth=tocdepth(\the\value{tocdepth})
\end{document}
```

このコードでは`hyperref`パッケージを[`bookmarksopen`オプション](https://texwiki.texjp.org/?hyperref)付きで読み込んでいるため、section・subsectionのしおり木構造は展開した状態で表示設定されるはずでした[^1]。しかし、Acrobat Reader等で開いてみても下図のように閉じたままです。PDFリーダーの設定や対応状況によるものかとも思い調べてみましたが、[他の方もupLaTeX + dvipdfmxの環境下ではしおり展開されない](https://htlsne.hatenablog.com/entry/2016/02/01/183043)ことが分かりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1120826/fcc42635-102e-13be-e2e0-188722e76cc0.png)

[^1]: デフォルトでは、subsubsection以下の見出し語はしおりになりません。これは`hyperref`の[`bookmarksdepth`オプション](https://texwiki.texjp.org/?hyperref)で決定され、初期値は`tocdepth`です。jsarticleにおいては`tocdepth`が2[(`subsection`)](https://latexref.xyz/Sectioning.html)に設定されています。変更方法には、[`bookmarksdepth=subsubsection`のように設定を変更する手法や、tocdepthカウンタ値をsetcounterで直接変更する手法](https://qiita.com/muchojp/items/6a4c0b19e60a4cbf43b4)があります。

うまく行かないことを知ると気になってしまい、対処法を色々と調べてみました。

まずヒットしたページでは、[私と同様にdvipdfm(x)でしおり展開されない](https://okumuralab.org/~okumura/texfaq/qa/20935.html)ことを質問していました。回答には、dvipdfm(x)のサポートする[`special`](https://texwiki.texjp.org/?special%20%E5%91%BD%E4%BB%A4)では`bookmarksopen`を取り扱えないため、dvipdfm(x)に`-E`オプションを付加して展開を指示する旨の記述があります。しかし、試しても変化はありませんでした。日時が2003年ですし仕様が変わったのかもしれません。

# 解決法
`-E`オプションは使用できませんでしたが、dvipdfmxの他のオプションを調べてみました。その結果、[dvipdfmxのコマンドラインオプション](https://texwiki.texjp.org/?dvipdfmx#tc481bdb)に`-O 数値`の形式で、しおりの展開深度を指定できることが分かりました[^2][^3]。

例えば、`dvipdfmx -O 1 foo.dvi`ならsectionまでの展開。`dvipdfmx -O 2 foo.dvi`ならsubsectionまでの展開になります。`-O 2`を設定した場合、以下のようにsubsectionまで展開されるようになりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1120826/f6de8fae-378e-c89d-2763-f50373b3e7f2.png)

# まとめ
hyperrefパッケージを用いてURLリンクする方法については、[この記事](https://qiita.com/UMA821/items/58609551cfd58420b1be)で説明しています。リンクやしおりに限らずhyperrefには様々な機能があるので、文書クオリティを上げるために調べてみましょう！

[^2]: [先の質問サイト](https://okumuralab.org/~okumura/texfaq/qa/20935.html)に記されている通り、hyperrefの`bookmarksopen`オプション指定はdvipdfmxを使用する場合では無視されます。
[^3]: [デフォルトでは0です](https://texwiki.texjp.org/?dvipdfmx#tc481bdb)。jsarticleなどのarticle系クラスにおいては、[深さレベル番号0に相当するコマンドは`\part`](https://latexref.xyz/Sectioning.html)なので、partまでしおり展開されます。
Go言語のGinフレームワークで静的ファイルを表示してみた

---
<font color="Tomato">Go</font>言語の<font color="l green">Gin</font>フレームワークで静的ファイルを表示してみた
---

**現実味がありすぎると良くないことありますよね**

　いやー。空想は空想でいいんですよ？

　でも現実を謳っていて、現実味が欠けていると、ちょっとなあ、て思う時があります。

　
　まあいいんですけどね。

 結局は変わらないものが良いんですよね。

**目次**
- [1. Ginフレームワークとは](#1-ginフレームワークとは)
- [2. コード例](#2-コード例)
- [3. おわりに](#3-おわりに)

## 1. Ginフレームワークとは

　`Gin`は、`Golang`で書かれたWebフレームワークです。

　`martini`に似た`API`を持ちながら、非常に優れたパフォーマンスを発揮し、最大で40倍高速であることが特徴です。

 
　`martini`(マティーニ)は`Go`言語で書かれたWebフレームワークで、モジュラー設計と使いやすさが特徴ですが、パフォーマンスの問題と非標準`API`設計により議論を呼んでいます。

 詳しくは下記のサイトに。

> 参考
[gin フレームワーク公式](https://gin-gonic.com/ja/)

## 2. コード例

<font color="low blue">**main.goのコード例**</font>

　ここではred.html、blue.html、yellow.htmlの三つを表示させます。

 ファイル構造は以下のようになります。

```bash
ls
> go.mod  go.sum main.go public

ls public
> blue.html  red.html  yellow.html
```
 

```main.go
import (
	"github.com/gin-gonic/gin"
)

func main() {
	engine := gin.Default()

	// 静的ファイルのルートを追加
	engine.StaticFile("/red", "./public/red.html") // publicディレクトリ内のred.htmlを提供
	engine.StaticFile("/blue", "./public/blue.html") // publicディレクトリ内のblue.htmlを提供
	engine.StaticFile("/yellow", "./public/yellow.html") // publicディレクトリ内のyellow.htmlを提供

	engine.Run(":" + "8080")
}
```

<br>

<font color="low blue">**htmlのコード例(red.html)**</font>
　htmlを試しに書いてみます。

 ```html
 <!DOCTYPE html>
<html>
<head>
    <tile>Red Page</tile>
</head>
<body style="background-color: red;">
    <h1>Welcome to the Red Page!</h1>
</body>
</html>
 ```

　実行してみると

```bash
go mod init static
go get -u github.com/gin-gonic/gin
go build 
./static  //実行ループ
```

　立ち上がったので、ブラウザで

`http://localhost:8080/red`

と検索してみると以下のようなサイトが表示されます。

![Screenshot 2024-02-10 at 23.13.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493200/0db01c07-dd71-81e5-5fc3-13104033f34b.png)

## 3. おわりに

　意外と`Gin`では`GET`とか`POST`の処理ばかりやるので、静的ファイルについて学んでみました。

　ここから先の、`CSS`とかあまり詳しくないので色々と遊んでみたいなと思いました。
テックキャンプ完全卒業

## 人生が変わった
今人生が変わり始めている実感がある。
工場の一従業員として働く中で、人が体を壊さずに働ける社会を実現したいと思い立ち、そのための技術としてITを学び、エンジニア転職をすることを決めたのが2023年1月。
2023年6月にテックキャンプで学習開始し、12月に卒業、その後約2か月間、テックキャンプのサポートのもと転職活動を行い、自分の理想を超えた仕事に転職することができた。
転職を決めてからちょうど1年、自分の人生の目的に向かって一歩踏み出した実感がある。

## テックキャンプやってよかった
改めて、テックキャンプをやって本当に良かった。
37歳からプログラミングの学習をして転職が本当に可能だろうか。自分の求める仕事に就けるだろうか。家族を養える収入を得られるだろうか。
不安はたくさんあったが、テックキャンプの仕組みに支えられ、転職することができた。

学習においては、カリキュラムの柔軟性とライフコーチさんに助けられた。学習期間中にオリジナルアプリを作成するためには、標準のスケジュールより早くカリキュラムを進めなければいけないが、ライフコーチさんにアドバイスをもらいながら進め、学習期間中になんとかオリジナルアプリを形にすることができた。中途採用面接の際に、面接官の方から「アプリ使ってみました。面白いですね。」と言われたこともあった。学習期間中にオリジナルアプリを形にできて本当に良かった。

転職活動は初めてのことであり、最初は転職活動への向き合い方がよくわかっていなかった。転職の軸は定まっているつもりが定まっておらず、転職したいはずなのに、求人への応募も積極的に行えなかった。転職活動もテックキャンプのキャリアアドバイザーさんに何度も壁打ちさせていただき、自分の考えを整理して転職の軸をつくりあげることができた。できることを全てやりきり、より広く可能性を持ちたくさんの求人に応募することができたのはキャリアアドバイザーさんのおかげであった。
## 自分の人生の舵取りを自分でしていく
転職の軸がしっかりしてきた時点で、下記の項目で最も良いと思う企業に入社しようと決めていた。
+ 職務内容
+ 通勤時間
+ 賃金増加の可能性
+ 挑戦を続ける社風
+ 会社の事業と自分の目的との共通性

最終的に入社を決めた会社は、自分の希望を完全に満たした、理想を超えた会社であった。
特に最後の、「会社の事業と自分の目的との共通性」は重要視しているもののオマケのようなもので、未経験からエンジニアとしてのキャリアをスタートする上では実現の可能性はほぼ無いと思っていたが、この会社は私の目的に合った事業も視野に入れて活動しており、社長の事業に対する考え方は、私の「人が体を壊さずに働ける社会を実現する」という夢にとっても必要な考え方を持っていた。
社長の事業や会社や社員に対する考え方を聴き、社長の理想を私も実現したいと思うようになっていった。そして、社長の理想の実現の中に私の夢の実現もあると確信した。まさか自分がこのように会社に対してコミットして働きたいと思えるようになるとは夢にも思わなかった。また、はるか遠い夢と思っていた自分の実現に転職を通して思いがけず近づくことができた。

前職より収入は減る。理想以上の会社に入社できたが経験不足なことは間違いない。
そのようなネガティブな現実とは対照的に、今自分は、自分の人生の舵取りを自分でしている充実感に満たされている。このような高揚感はこれまで味わったことが無い。
## これからが勝負だ
自分が望んだ環境は手に入った。
これからはエンジニアとして技術力を磨き続ける。
38歳からのエンジニアはかなりの後発となる。
他社の3倍の仕事をし、10年かかることを3年で身に着ける。
それくらいのスピード感で実力をつけていかなければならない。
そうでなければ人生はすぐに終わってしまう。
転職を始める前に考えていたことがある。

このまま今の会社に勤め、管理職になり、定年退職まで勤め、
蓄えで老後を過ごし、死ぬときに後悔しないだろうか。
たくさん挑戦して充実した人生であったと思って死ねるだろうか。
そうは思えない。きっと、あの時挑戦しておけばと後悔する。

これからが勝負だ。
かなり自分に負荷をかけることになるが、技術力を磨くことに挑戦する。
そうでなければ後悔が現実のものとなる。
自分が死ぬときには、よくやった。たくさん挑戦し、満足する人生であった。
そう思える人生をおくることを誓う。

## 投稿も、、、がんばります
少しづつ投稿しようと始めたQiitaですが、あまりにも久しぶりでしかもまだ3本目。「人が体を壊さずに働ける社会を実現する」などと言っておきながら、この発信の少なさ、、、。
これからがんばります！
新卒未経験が１ヶ月で基本情報B試験満点合格した話

# はじめに
先日、新卒入社した会社で研修の一環として基本情報技術者試験を受験しました。
大学時代は情報系の専攻ではなく、ITの知識は入社後から学び始めたのですが、
入社後１ヶ月で基本情報技術者試験をB試験満点で合格することができたので、
勉強方法や使用した教材などをまとめます。

# 目次
<table>
  <tr>
    <td>1</td> <td>基本情報技術者試験とは</td>
  </tr>
  <tr>
    <td> 2 </td> <td>勉強時間</td>
  </tr>
  <tr>
    <td> 3 </td> <td>使用教材</td>
  </tr>
    <tr>
    <td> 4 </td> <td>勉強方法</td>
  </tr>
    <tr>
    <td> 5 </td> <td>まとめ</td>
</table>

# 基本情報技術者試験とは
基本情報技術者試験とはITエンジニアの登竜門とされている国家試験であり、ITエンジニアの基礎となる知識を幅広く学ぶことができます。

試験は科目Aが90分で60問出題され、内容はテクノロジ系が７割、マネジメント系とストラテジ系が３割程度出題されます。科目Bは100分で20問出題され、アルゴリズムが8割、セキュリティが２割出題されます。両科目、正答率6割以上で合格です。

# 勉強時間
1日の勉強時間は、平日は会社の行き帰りの電車40分と自宅で１時間程度勉強していました。土日は２時間程度勉強していました。
また、会社の研修の一環として、A試験の内容と繋がるIT基礎知識の教育とB試験のアルゴリズム対策も行いました。

# 使用教材

https://www.itec.co.jp/store/products/detail.php?product_id=3832

https://www.itec.co.jp/store/products/detail.php?product_id=3833

http://www.youtube.com/@kihonzyouhou

https://www.fe-siken.com/fekakomon.php

https://www.ipa.go.jp/shiken/syllabus/ps6vr7000000oett-att/fe_kamoku_b_sample.pdf

# 勉強方法
#### ・ 科目A
知識のインプットは上記の参考書と、すーさんのYoutube動画を行き帰りの電車で見ていました。1・2周してインプットが完了したら[基本情報技術者試験ドットコム](https://www.fe-siken.com/)の過去問道場を繰り返していました。解説付きで過去問を一問一答形式で演習を行えます。
このサイトは過去問以外でも試験の情報や対策法が詳しく書かれているので色々見てみることをお勧めします。
科目Aは知識を問われる問題がかなり多いので、インプットがある程度完了したらひたすら過去問道場を解きながら量をこなして学習することが重要だと思います。

#### ・ 科目B
こちらも同様に参考書と動画でインプット完了後、参考書の問題と基本情報技術者試験ドットコムに科目Bの公式サンプル問題が解説付きで載っているのでそちらを活用しました。
セキュリティに関する問題は科目Aの学習をしっかり行なっていれば解けると思うのでアルゴリズムに多くの時間を投入するのが良いと思います。私が使用した参考書では難易度の高いアルゴリズム問題も一部あったので、全て完璧に解ける必要はなく、公式サンプル問題の方を繰り返し解き、全て自力で解答を導ける程度になれば問題ないと思います。
また、科目Bは特に時間がかなりギリギリになるので、時間を測って本番形式で解きなれておくことも重要です。

# 最後に
以上、少しでも皆さんの参考になれば幸いです。ありがとうございました。
後期チーム制作で考えたコーディングルール

# この記事について
チーム制作で利用するコーディングルールを考えてまとめてみました。
このコーディングルールは2024年2月10日に考えたものです。
後々更新する可能性もあります。

# クラスの名前の末尾はerもしくは名詞単体
```C#
// 移動するクラス
public class Move
{

}

// プレイヤーの移動クラス
public class PlayerMove
{

}
```

# 変数名には分かりやすい単語を使う
追記：機能が分かる命名である事
```C#
// 配列の大きさを示している変数
// これは意味が分かりやすい
private int maxArraySize = 2;

// これは何に対する大きさなのか意味が分からない
private int size = 2;

// 移動方向入力を確認するメソッド
private void CheckMoveDirInput()
{

}
```
# 命名は省略しない
追記：この名前は略称していいのか？という考える時間が無駄に感じる
　　　＋　コードレビューをする時が面倒くさい
```C#
// 移動速度
private float moveSpeed

// 初期化メソッド
private void Initialize()
{

}
```

# 三単語より下の変数の命名は全て大文字にする
追記：三単語は含まないよ
```C#
     // UIは二単語なので全て大文字
     private void DisplayUI() 
     {
     
     }
```

# クラス,メソッド,プロパティ,定数,にはパスカルケースを利用する

```C#
// クラス
public class PlayerMove
{
    // 変数
    public float MoveSpeed = 10;

    // プロパティ
    public float JumpSpeed {get; set;}

    // メソッド
    public void TestLog()
    {

    }
}
```

# フィールド変数の命名
```C#
public class Test
{
    // publicならパスカルケース
    public int TestNum = 0;

    // praivateならキャメラケース
    private int testNum = 0;
}
```

# 引き数,メソッド内で定義した変数はキャメルケースを利用する
```C#
// メソッドはpraivateでも必ず大文字にする
// 引数やローカル変数も小文字
private void TestLog(string message)
{
    var log = "a";
    Debug.Log(log);
    Debug.Log(message);
}
```

# 全てのprivateメソッドをpublicメソッドの後に定義する
追記：変数とメソッドの位置はバラバラにしない

```C#
public int MoveSpeed = 2;
private int JumpForce = 2;

public void Move()
{

}

public void Jump()
{

}

private void Test()
{

}
```

# if,for,foreachの{}の省略を避ける

悪い例
```C#
if(isLog) Debug.log("テスト");
```

良い例
```C#
if(isLog) 
{
  Debug.log("テスト");
}

// １行の処理だけならこの書き方もあり
if(isLog){ Debug.Log("テスト"); }
```
# if文の連続使用は避ける
悪い例
```C#
if(num == 0)
{
    // 何かの処理
}
else if(num == 1)
{
    // 何かの処理
}
else if(num == 2)
{
    // 何かの処理
}
else
{
    // 何かの処理
}
```

良い例
```C#
switch(num)
{
    case 0:
      break;
    
    case 1:
      break;
    
    case 2:
      break;

    default:
      break;
}
```
if文の連続使用は避けてSwitch文を利用しよう！

# boolにはis,has,canをつける

``is ``ある状態を持っている時
``has``特定の状態や属性要素を含んでいる時
``can``特定の動作や処理を行えるかどうかを示す時

例であげると
```C#
// ジャンプ中か
private bool isJumping = false;

// すでに2段ジャンプをしたか
private bool hasDoubleJump = false;

// ジャンプは出来るか
private bool canJump = false;
```
# 非同期メソッドにはAsyncをつける
```C#
public async TestTask()
{

}
```

# インタフェースの先頭には I を必ずつける
```C#
pubilc interface ITest
{

}
```

# GetCompoentの利用について
コード関係ないからちょっとあれなんだけど、利用していいです。
ただし、Updateでの利用は絶対避ける事。絶対避けて。
@react-google-maps/apiのマーカーのアイコンを表示する方法

# 目次
[１. 問題解決の経緯](#1-問題解決の経緯)
[２. 開発環境](#2-開発環境)
[３. 解決方法](#3-解決方法)
[４. 結果](#4-結果)
[５. おわりに](#5-おわりに)

# １. 問題解決の経緯
ググって出てきた方法が悉く通用しなかったので、備忘録として残します。

# 2. 開発環境
| Package | Version |
|:-|:-|
| next | 14.0.4 |
| react | ^18 |
| @react-google-maps/api | 2.19.2 |

# 3. 解決方法
アイコンのパスを`import`して任意の変数に格納します。
そして、MarkerFコンポーネントの`icon`プロパティに`変数.src`を代入します。

```tsx:page.tsx
import { GoogleMap, MarkerF } from "@react-google-maps/api";
import iconPath from "../../../public/images/icon.png";

const Page = () => {
...
  return (
    ...
    <GoogleMap>
      <MarkerF visible={true} position={...} icon={iconPath.src} />
    </GoogleMap>
    ...
  );
};
```

# 4. 結果
以下のように表示されるようになります。（真ん中のやつ）

![スクリーンショット 2024-02-10 22.55.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3271648/51ab8f22-0cb5-55cd-07f4-71bbc0090bd3.png)


# 5. おわりに
たまたま`icon`プロパティのサジェストから見つけたのでラッキーでした💫

以上です。
react-hook-form isDirtyが立たないのはsetValue shouldDirty: true をしていないから

react-hook-formで任意のフォームの状態を更新するときsetValueを使っている箇所はありませんか？

その時にsetValue('targetKey', value)とオプションをつけずに実行するとisDirtyがfalseのまま変わりません。

実際にユーザー操作に近い操作を期待する場合は、setValue('targetKey', value, {shouldDirty: true})とオプションをつけてあげるとisDirty: trueになります。


ref https://github.com/react-hook-form/react-hook-form/issues/72#issuecomment-656500986
ABC340をPythonで（A～E）

鹿島建設プログラミングコンテスト2024（AtCoder Beginner Contest 340）の解答等のまとめ

https://atcoder.jp/contests/abc340

# A問題
range関数は3つパラメータを入れてると、1つ目から２つ目の手前まで３つ目の間隔で値を出力してくれる
```python:A
a, b, d = map(int, input().split())
print(*[i for i in range(a, b + 1, d)])
```

# B問題
問題群の通りにやる
```python:B
A = []
for _ in range(int(input())):
    com, x = map(int, input().split())
    if com == 1:
        A.append(x)
    else:
        print(A[-x])
```

# C問題
メモ化再帰
lru_cache　を思い出せなかったから辞書を使った

```python:
n = int(input())

memo = dict()
memo[0] = memo[1] = 0


def calc(x):
    global memo
    if x in memo:
        return memo[x]
    else:
        floor, ceil = x // 2, x - x // 2
        res = calc(floor) + calc(ceil) + x
        memo[x] = res
        return res


print(calc(n))
```

# D問題
ダイクストラ
```python:D
from heapq import heappop, heappush

n = int(input())

edge = [[] for _ in range(n + 1)]
for i in range(n - 1):
    a, b, x = map(int, input().split())
    edge[i].append([i + 1, a])
    edge[i].append([x - 1, b])

q = [[0, 0]]
INF = float("inf")
dist = [INF] * n
dist[0] = 0
while q:
    d_i, now = heappop(q)
    if dist[now] < d_i:
        continue
    for to, d_j in edge[now]:
        if dist[to] > dist[now] + d_j:
            dist[to] = dist[now] + d_j
            heappush(q, [dist[to], to])

print(dist[-1])
```

# E問題
RangeAddQuery
おそらく遅延セグ木でRAQを処理するものだと思ったがなんやかんやでBITで出来た

$i$番目の和を見ると$a_i$となるように埋め込む

$b_i$のクエリの時は
1. $b_i$の値$x$を取得する
1. $b_{i+1}$に$x$を加え、$b_i$を$0$に
1. 全体に$x //n $を加える
1. １個多くもらうところに１加わるように頑張る
 
```python:E
class BinaryIndexTree:
    def __init__(self, n):
        self.size = n
        self.tree = [0] * (n + 1)

    def sum(self, i):
        s = 0
        while i > 0:
            s += self.tree[i]
            i -= i & -i
        return s

    def add(self, i, x):
        while i <= self.size:
            self.tree[i] += x
            i += i & -i

    def range_sum(self, i, j):
        if i == 0:
            return self.sum(j)
        return self.sum(j) - self.sum(i - 1)


n, m = map(int, input().split())
a = list(map(int, input().split()))
b = list(map(lambda x:int(x) + 1, input().split()))

BIT = BinaryIndexTree(n * 2 + 10)
s = 0
for i in range(n):
    BIT.add(i + 1, a[i] - s)
    s = a[i]

for b_i in b:
    x = BIT.sum(b_i)
    BIT.add(b_i, -x)
    BIT.add(b_i + 1, x)
    if x // n > 0:
        BIT.add(1, x // n)
    
    if x % n > 0:
        BIT.add(b_i + 1, 1)
        BIT.add(b_i + x % n + 1, -1)
        if b_i + x % n > n:
            BIT.add(1, 1)
            BIT.add(b_i + x % n - n + 1, -1)

ans = [BIT.sum(i) for i in range(1, n + 1)]
print(*ans)
```
値に応じて色を連続的に変化させたい・・・

# カラーを連続で変えたい
M5atomで温度計や電流計を作った際、値に応じてLEDの表示色を変えたいと思い、最初はレベル毎にカラーマップを作っていたのですが、連続で変えたいといった場合にどうするかを調べたところ、色相なら連続的に変えられると思い、変換プログラムを探してみました。

結果たどり着いたのがHSVからRGBへの変換プログラムです。valueの値に応じて、最大値と最小値の間を青→赤になるよう変化させるなら、以下のように色相を指定してあげるといい感じになると思います。
```hsv2rgb.cpp
h = 1.-((value-min)/(max-min)/2.)-0.5;
if (h>0.5){h=0.5;}
if (h<0.) {h=0.;}
```
ちなみに、AtomS3で画面の色を作る際の16bitRGB版も作ってあるので、しばらくしたら一緒に載せておこうかと思います。

```hsv2rgb.cpp
//================================================================================
// hsv2rgb HSV->RGB変換
//================================================================================
int hsv2rgb(float h,float s,float v){
  if (s>0){
      if (h == 1.0){h = 0.0;}
      int i = int(h*6.0);
      double f = h*6.0 - i;
      
      double w = v * (1.0 - s);
      double q = v * (1.0 - s * f);
      double t = v * (1.0 - s * (1.0 - f));
      
      h = int(h*255);
      s = int(s*255);
      v = int(v*255);
      w = int(w*255);
      q = int(q*255);
      t = int(t*255);
      
      if (i==0){ return((int)(v)*256*256+int(t/1)*256+(int)(w/1));}
      if (i==1){ return((int)(q)*256*256+int(v/1)*256+(int)(w/1));}
      if (i==2){ return((int)(w)*256*256+int(v/1)*256+(int)(t/1));}
      if (i==3){ return((int)(w)*256*256+int(q/1)*256+(int)(v/1));}
      if (i==4){ return((int)(t)*256*256+int(w/1)*256+(int)(v/1));}
      if (i==5){ return((int)(v)*256*256+int(w/1)*256+(int)(q/1));}
      return(0);
  }else{
    return((int)(v*2048/8+v*32/4+(int)(v/8)));
  }
}
```
URLの有効性を確認する　200 300 400

指定されたURLが有効か無効かを調べるコードです。ステータスコードが200番のものを有効、それ以外を無効と判断するコードです。

# コード
```python:check_URL.py
def check_URL(url):#URLの有効性をチェックする。戻り値はbool,ステータスコード（or Errorコード）
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36"}
    try:
        response = requests.head(url, timeout=10,headers=headers)
        if response.status_code == 200:
            return True , response.status_code
        elif response.status_code == 405:  # Method Not Allowed
            allowed_methods = response.headers.get('Allow', '')
            if 'GET' in allowed_methods:
                response = requests.get(url, timeout=10,headers=headers)
                if response.status_code == 200:
                    return True , response.status_code
                else:
                    return False , response.status_code
            else:
                return False , response.status_code
        else:
            return False , response.status_code
    except requests.exceptions.RequestException as e:
        return False , str(e)
```

ここに記載

# 解説
pythonのresponseライブラリを使い、指定されたURLが有効かどうかを調べています。
200なら有効。それ以外は無効と判断し、ステータスコードを返します。

## ポイント1　200のみチェック
今回必要なのはステータスコードだけなので、リクエストをhead依頼します。
ステータスコードを見て個別処理します。

## ポイント2　転送先は調査しない
もう一つのポイントは、転送先の調査をしないというところです。
実際、URLの有効/無効を調べているのでそれ以外はステータスコードで個別処理します。

## ポイント3　URL自体が有効か判断する
単純ですが、これらはtry,except Exceptionでキャッチします。
リストが古いとそもそもURLでないことも考えられます。実際、5％程度にURLでない文字列などがふくまれていました。

#背景
Excelに保存されている古いデータの調査で、記載されたURLが有効かどうかを確認する必要がありました。
データ数は2万件ぐらいでしたが、10年前の古いデータでしたので404が4割、300が3割、残りが200番台という結果でした。

2000件程度あったリストのうち、404が4割、300台が3割、200が2割、残りが500台とエラーでした。
リストが引き継がれていたため、途中で書き換わってしまったエラーも多く残っていました。####と入力されており確認出来ないものもありました。
Yahoo!ジオシティーズも多かったですね。時代の移り変わりを感じます。
CCNA取れたよ！

## 受かった！
なんやかんや一年以上たったし書くのも遅くなりましたが、
23年の7月にCCNA合格しました。

少し古いけど情報をアップデートしたいと思います。

## 問題数
問題は全部で102問
選択85問
並び替え15問
疑似ターミナルを使ったコンフィグ作成問題2問

だったはず。

## スコア
スコアはこんな感じでした。

Network Fundamentals 75%
Network Access 55%
IP Connectivity 76%
IP Services 60%
Security Fundamentals 60%
Automation and Programmability 30%

全然高くない、温情で合格にしてもらった感じがします。
(まぁ合格は合格だからね)

## 勉強法
まずテキストは俗に言う白本を使用してました。
CCNA教科書で上の方に出てくるのですぐわかると思います。
↓これね
~~~
シスコ技術者認定教科書 CCNA 完全合格テキスト&問題集[対応試験]200-301
~~~
一旦はテキストを読んである程度の理解をしたいところですが、
小難しいことがいっぱい書いてあって辛かった思い出です。

一旦テキストを読み終わったら問題を解きましょう。
問題はPing-tで大体網羅できてるかと思います。
いくつかは本番で「そのままじゃん」ってやつでました。

あと、ちゃんとコマ問とかシュミレータまでやったほうが良いですよ。
実機を触れる環境があるなら多少はカバーできますが、触れない方、これは絶対にやるべきです。
Ping-tのシュミレータを触った感じはわりと実機そのまんまです。
本番もシュミレータなので逆に実機触ってる人は違和感を感じるかもです。

頭で覚えるより体で覚えられるのでそこまで苦では無いですね。

ちなみに自分はコマ問サボって後悔してます。

問題解きながら間違えたところを復習する感じで特に難しいことはせずにping-tで安定して正解率90％が出せれば受かると思います。
## 受験日が近くなったら
試験の1週間くらい前になったら、別の問題集などを使用するのが良いでしょう。

私はクラムメディアを使用しました。
たまに内容が怪しい問題もありますが、理不尽さも学べると思います。

クラムメディアは並び替えも確かあったのでそこはとても重宝した思い出があります。

## 試験当日
特に試験直前は何もしませんでした。
受付時間までに到着することだけを考えてました。

試験開始後は、はじめましての問題に怯えながら問題を解いていきましたが、
90問目くらいにでた2個目の設定問題がちょっと面倒でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545277/2a4c0c34-5308-a49f-b7ae-47d72335f3c4.png)

スイッチ3台、ノード3台で通信の設定をするんですけど、
「Node C」は「Node A、B」と相互通信をする。
「Node A」は「Node C」のみと通信できる。
「Node B」は「Node C」のみと通信できる。
っていうのがメインの設定内容です。
他にも省略してますが、Vlan Nameの設定も必要でした。

みたいな設定だったと思います。
この問題やってるとき必死過ぎてあんまり記憶無いです。

1問にかけられる時間が1分ちょいしか無いのでここで時間使うのがとても惜しかったです。
すべての問題を解きましたが、終わったとき残り時間20秒でした。

ペース的には選択問題を速攻で解いて設定系の問題に時間をかけられるようにしたほうが良いです。
見直しがシステム上できないので、覚悟を決めて「次へ」のボタンを押しましょう。

## 最後に
別に特別なことはせずともテキストを読んで、過去問をある程度解いて、シュミレータをやっていれば問題なく合格できるかと思います。

後は、問題を解くペースをどれだけ早くできるかなので、なるべく暗記ではなく知識として落とし込めれば
合格できると思います。