OmniAICreator/Qiita-1.07M huggingface dataset:
【Flutter】Listview.builderを逆にする

こんにちは。
今回は、Listview.builderを逆にする方法を紹介します。
LINEのチャット機能に使えます。

# 方法
![スクリーンショット 2023-08-13 20.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/ce57fee2-1687-ea40-8538-b4c8b9db94e0.png)

ListView.builderのプロパティのreverseをtrueにします。

# 使用例
```dart

final List<String> texts = [
   'text1', 'text2', 'text3', 'text4', 'text5', 'text6', 'text7', 'text8', 'text9',
   'text10', 'text11', 'text12', 'text13', 'text14', 'text15', 'text16', 'text17',
   'text18', 'text19', 'text20', 'text21', 'text22', 'text23', 'text24', 'text25',
   'text26', 'text27', 'text28', 'text29', 'text30', 'text31', 'text32', 'text33',
   'text34', 'text35', 'text36', 'text37', 'text38', 'text39', 'text40', 'text41',
   'text42', 'text43', 'text44', 'text45',
 ];

class MyHomePage extends StatefulWidget {
  MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.builder(
        reverse: true,
        itemCount: texts.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text('${texts[index]}'),
          );
        },
      ),
    );
  }
}

```

# 実行例

![riverse.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/33613131-cb27-6aa3-105f-a0eb773dd444.gif)



# 最後に
ここまで読んでいただき、ありがとうございました！
いいねしてくれたら、スキップして喜びます:heartpulse:
OpenWrtを試してみた

寒い時期は2階で作業をしていて、WIFIを使ったイーサーネットコンバーターを使っています。イーサーネットコンバーターは以下の方式があります。

* NAT
* ルーター
* ブリッジ

NATとルーターの場合は別のサブネットになりますが、ブリッジの場合は同じサブネットになります。

ルーターやブリッジの場合は双方のネットワークから透過に通信できますが。NATの場合は一方向のコネクションしか張れません。

ブリッジはFreeBSDではif_bridgeで設定できますがOpenWrtではrelaydを使うのが一般的のようです。

EthernetはMACアドレスを元にユニキャストか、MACアドレスを解決するためのARPはブロードキャストで通信を行います。ブリッジは相手のネットワークにパケットを転送する時は送信元のMACアドレスを自分に代えて投げます。ブリッジ越えで送られてきたユニキャストはブリッジが保持しているテーブルで変換して相手先MACアドレスを書き換えて転送します。

FreeBSDを焼いてもとに戻せなくなったハードオフで108円で購入したWLI-TX4-AG300Nにシリアルでu-bootを操作してインストールしてみました。この機種のオリジナルファームのエンコードキーが不明なので、ファームウエアアップデートではインストールできないと思われます。

https://openwrt.org/toh/buffalo/wli-tx4-ag300n

この機種はRalinkの最初のMIPS SOCであるRT2880を使っていて、メモリは32MありますがFlashは4Mです。MIPSのアーキテクチャは4Kです。無線は2.4G,5Gの両方入っています。両方同時には使えず片方のみのようです。結構しっかりした作りで良い感じのモジュールです。

国内で販売されているルーターでは珍しく電源スイッチが付いています。この機種のデザインはこれだけだったと思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/b6e44a56-b09c-6571-c086-4766af1dd11f.png)

この機種はルーターではなくイーサーネットコンバーターなモジュールでしたが、オリジナルがどの方式だったかは確認していません。

最初4M Flashのサポートが最後の19系を焼いてみたのですが、設定がまったく保存されません。おそらくimageが大きくなって、設定の保存に失敗しているような気がします。

設定はブラウザーでおこないました。sshでログインしてcliでも設定できるようです。Linuxはよく分からないので、ブラウザーを使いました。

OpenWrtのDownloadサイトある一番古い17系を再インストールしたところちゃんと設定が保存されるようになりました。

~~ところがrelayd,luci-proto-relayのパッケージがどこを探しても見つかりません。~~
ありました。RT2880は4Kなのですがmipsel_24kcが使えるようです。
packagesの下を探していたのですが。baseとluciの下にありました。

https://downloads.openwrt.org/releases/packages-17.01/mipsel_24kc/

コードはここにあるようです。

https://git.openwrt.org/project/relayd.git

NATはパッケージが必要なく設定だけで使えるようなのでとりあえずNATで使ってNATの内側への通信はポートフォワードを設定して使うことにします。

蟹さんの純正ファームのイーサーネットコンバーターを使っていたのですが、ときどき切れたり不安定だったので、試しました。

19系でも使わないパッケージを消せばちゃんと使えるのかもしれません。

このモジュールは下に通気用の穴があり、[少し浮かせて設置するのが熱対策](https://qiita.com/yamori813/items/6a656914aa713230acf4)になるかもしれません。

ZRouterでFreeBSDでも動かせますが、4Kはあまり用途がないので、オリジナルに戻そうとしたのですが、オリジナルのファームがデコードできないためあきらめて、OpenWrtを試しました。

# relaydの設定

opkg install relaydではインストールできなかったので、別のホストでファイルをダウンロードして実機の/tmpにscpしてファイルをインストールしました。

![relayd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/296f2cd0-b100-e23f-f08e-8902a19e2f45.png)

同じサブネットのIPアドレスは有線側か無線側のどちらかにしかつけられないようです。

通常の通信(TCP)はとても安定しています。

イーサー側に複数台のモジュールを置いても問題なく通信できました。

ブリッジ越えのtftp(UDP)はあまり調子がよくありません。

LEDが三つ付いてるようなのですが、制御方法が分かりません。
NRQLで手軽にBase64エンコード・デコードしてみよう

ログの中に含まれている文字列を手軽に暗号化して表示できたら・・・
通信の中に含まれたBase64でエンコードされた文字列を手軽にデコードして可視化できたら・・・

そんなことが簡単にできるNRQL関数が新しく追加されました！
これであなたもBase64マスターです！

:::note info
このアップデートの詳細はこちら。
[New Relic アップデート(2024年1月)](https://newrelic.com/jp/blog/nerdlog/new-relic-update-202401)
[New Relic アップデート](https://newrelic.com/jp/blog/nerdlog/new-relic-update "New Relic アップデート")
:::

## 使い方
エンコードする時は`encode()`関数、デコードする時は`decode()`関数を使用することで、文字列とBLOBに対してBase-64変換を実行できるようになります。
入力値（最初の引数）は、エンコーディング（2番目の引数）で指定されたBase-64標準を使用してデコードされます。

次の文字列値は、サポートされているエンコードパラメーターです。

「base64」：[RFC4648 Base-64標準](https://datatracker.ietf.org/doc/html/rfc4648#section-4)を使用
「base64mime」：[RFC2045 Base-64 標準（MIME）](https://datatracker.ietf.org/doc/html/rfc2045)を使用
「base64url」：[URLおよびファイル名に安全なアルファベットを用いたRFC4648 Base-64標準](https://datatracker.ietf.org/doc/html/rfc4648#section-5)を使用

<b><注意点></b>
・BLOB は WHERE 句または FACET 句では許可されないため、blob 型を使用した `decode()` は WHERE 句またはFACETではサポートされません。
・`encode()`関数はBLOBではサポートされていません。
※長いログのmessage値は最初の4,094文字はNRDBに保存されますが、それ以降の128,000バイトはBLOBに保存されます。
ここで指しているBLOBはこの長いログが保存されたフィールドを指しています。
詳しくは[こちら](https://docs.newrelic.com/jp/docs/logs/ui-data/long-logs-blobs/)のドキュメントをご参照ください


## 使ってみよう
では早速使ってみたいと思います！
まず手元の環境でSpanに含まれるentity.guidをdecodeしてみます
```sql
FROM Span SELECT entity.guid, decode(entity.guid, 'base64') 
WHERE entity.guid IS NOT NULL
```
実はentity.guidってbase64でencodeされて作られてることがわかりますね
![encodedecode01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/4935f40e-c2a9-e581-41c8-b87c64ad193f.png)

今度はBrowserのPageViewからSessionをencodeしてみます
```sql
FROM PageView SELECT session, encode(session, 'base64')
```
このようにbase64変換前後を確認することが可能です
![encodedecode02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/9907b83c-f2c9-244a-fcb3-6f6930f76377.png)

BLOBに保存されたログをdecodeして表示してみます
```sql
FROM Log
WITH blob(`newrelic.ext.message`) as encodedBlob,
decode(encodedBlob, 'base64') as decodedBlob
SELECT encodedBlob, decodedBlob
WHERE newrelic.ext.message IS NOT NULL
LIMIT 10
```
BLOBに保存された`newrelic.ext.`属性はbase64で保存されているので、検索した時にそのままdecodeして表示することが可能です
![encodedecode03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/0a825f7a-35ca-7812-4b5e-dbefeca6833d.png)

ちなみにmessageとnewrelic.ext.messageを並べて表示すると、こんな感じになります。
![encodedecode04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/98400972-8177-0247-cc6f-67e1ceaa1336.png)


## まとめ
実はNew Relicに保存されているデータがbase64で保存されているものがありますが、decode()関数を活用することで簡単にデコードすることができるようになります。
また手軽にencodeできるので、ダッシュボードで可視化するときに見せたくない文字列を手軽にエンコードできるようになります。
New Relicに取り込まれた値を活用する手段の一つとして、是非この機能をご活用ください!!


:::note info
このアップデートの詳細はこちら。[New Relic アップデート(2024年1月)](https://newrelic.com/jp/blog/nerdlog/new-relic-update-202401)
:::
:::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::
:::note info
[New Relic株式会社のQiita Organization](https://qiita.com/organizations/newrelic)では、
新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
:::
【知見メモ】SwiftUIでグラデーションを背景色にした時にキーボードの表示でレイアウトが崩れる問題の対処法

# 概要

本記事では、SwiftUIでグラデーションを背景色にした時、キーボードの表示でレイアウトが崩れる問題の対処法を紹介します。

# 問題の挙動

キーボードを表示した時にグラデーションの適用領域が縮んでしまいます。

![Simulator Screen Recording - iPhone 15 - 2024-03-26 at 09.13.22.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/e9f820f4-a066-89d0-769b-34049f40ac30.gif)



![スクリーンショット 2024-03-26 9.19.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/a2848e6c-ada3-b7e2-bd58-dbcadb6702fc.png)

## 実装

```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(spacing: 16) {
            Text("これはテキストです")
            TextField("text", text: .constant("test"))
                .textFieldStyle(.roundedBorder)
        }
        .padding()
        .frame(maxHeight: .infinity)
        .background(
            LinearGradient(
                colors: [.pink, .purple, .black],
                startPoint: .top,
                endPoint: .bottom
            )
        )
    }
}

#Preview {
    ContentView()
}
```

https://developer.apple.com/documentation/swiftui/lineargradient

# 対処法

理想はキーボードの表示でグラデーションの適用領域を縮めることなく、背景色を維持できることです。

選択肢の一つとして、[`.ignoresSafeArea(.keyboard)`](https://developer.apple.com/documentation/swiftui/view/ignoressafearea(_:edges:))のmodifier使うことで解決できます。

拡張範囲をキーボードのみに限定することができます。
この特徴を使って、キーボードが表示されても画面がずれないようにすることが可能です。

![Simulator Screen Recording - iPhone 15 - 2024-03-26 at 09.29.01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/4da1c7ec-a5d8-dfa3-392e-b1fc4dee089f.gif)

## 実装

```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(spacing: 16) {
            Text("これはテキストです")
            TextField("text", text: .constant("test"))
                .textFieldStyle(.roundedBorder)
        }
        .padding()
        .frame(maxHeight: .infinity)
        .background(
            LinearGradient(
                colors: [.pink, .purple, .black],
                startPoint: .top,
                endPoint: .bottom
            )
        )
+       .ignoresSafeArea(.keyboard)
    }
}

#Preview {
    ContentView()
}
```

しかし、TextFieldが固定で配置されてしまうため、デザインによっては改善する必要があるので注意してください。

以上です。
Commandパターンのメモ再び

基本的に主な目的は統一したメソッドで呼び出すということになるはず。
多分、順番をしたからにしたほうがわかりやすいと思ったりする。

1. Receiver: 単なるオブジェクト。特に制約なし
2. Command: execute()みたいな統一した呼び出しをもつクラス。Receiverを呼び出すのが主な仕事

で基本終わっていて、ここから私が混乱。正直、ここまででやりたいことは終わっているので。
しかし、GUIの画面作成を前提に置くとなんとなく分かった。

3. Invoker: Commandの集合。おそらくGUIで言うところのウィンドウクラス。Commandのインタフェースを実装したボタンを配置するイメージになる
4. Client: InvokerにCommandを設定する。InvokerにCommandを設定する

まとまるとこんな感じになるはず

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76851/e8b72ccd-31b6-9ffc-4c93-e08704b6929c.png)

見てみると普通のGUIプログラミングじゃん・・・

Webで言うとこんな感じかなぁ

1. Client = HTML、JavaScript
2. Invoker = documentクラスみたいな画面全体
3. Command = 各要素。それぞれにonClickタグがあって、何かを呼び出したければこのタグを設定する
4. Receiver = 呼び出し先関数
【個人開発】tauri+svelteでキングジム風ポモドーロタイマーを作ってみた


# tauri+svelte でポモドーロタイマーを作ってみた

転職を機に、新しい技術に触れる＆個人開発デビューするために tauri と svelte を使ってポモドーロタイマーを作ってみました。作成期間は約 3 日ほどです。
また、キングジムから発売される[ビジュアルバータイマー](https://www.kingjim.co.jp/sp/vbt10/)が気になり、デスクトップアプリとしてデスクトップの隅に常駐させたらよいなと思い、作成しました。

## 作ったもの

シンプルなポモドーロテクニック用のタイマーアプリです。
![app-window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552182/14399c01-6b43-ec67-a88f-25d026ea8374.png)

※ [ポモドーロテクニック](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%A2%E3%83%89%E3%83%BC%E3%83%AD%E3%83%BB%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF)

## ダウンロードリンク

[こちらのリポジトリ](https://github.com/makima333/t-tomato-timer/releases/tag/v0.2)から最新のリリースをダウンロードできます。
もし、よろしければ使ってみてください。また、フィードバックも issue にてお待ちしております。

## 機能

ひとまず、最小限の機能に絞って作成しました。

- タイマーのスタート/ストップ
- タイマーのリセット
- デスクトップの最前面に固定
- タイマー終了時にアラート音を鳴らす
- 消音ボタンでアラート音を消す

## 技術スタック

- tauri v1 系
- svelte
- tailwindcss
- typescript
- daisyUI
- heroicons

## 開発体験について

開発体験は概ね良かったです。大きく躓くこともなく、サクサクと進めることができました。
所感については別途[こちらのブログ記事](https://m-lab-tech.com/posts/2024-03-tauri-svelte-simple-timer-app/)でまとめてます。

## 今後の予定

タスク名の設定や統計情報の表示など、機能追加を予定しています。
Reactからsupabaseにデータを追加できない

# 初めに
現在Reactを用いて学習記録アプリを制作しています！
制作の過程でインプットタグに挿入したデータをsupabaseに追加するという機能を実装しようとしたのですが、うまく動作しなかったので共有します。

# 問題点
学習内容を入力するフォームと学習時間を記録するフォームを設置して、その横にある登録ボタンを押すとリストに名前が追加されるという機能の実装を試みました。
ですがボタンを押してもコンソール上にはエラーしか返ってきません...
結論から言うとボタンを押した時に動作する、supabaseにデータを追加する関数が間違っていました。
以下が間違っていた関数です。
```react
export const addTodo = async (title, time) => {
  const { data, error } = await supabase
    .from("study-record")
    .insert([{ title: title, time: time }]);

  if (error) {
    throw error;
  }

  return data;
};
```

# 解決策
正しいコードはselect();を追加した以下のコードです。
```react
export const addTodo = async (title, time) => {
  const { data, error } = await supabase
    .from("study-record")
    .insert([{ title: title, time: time }])
    .select();

  if (error) {
    throw error;
  }

  return data;
};
```
以前までinsert()関数は、デフォルトでsupabase上の行を自動選択していたそうですが、現在はselect()をつけないと行の選択を行なってくれないそうです。
参考サイト：https://supabase.com/docs/reference/javascript/upsert#data-operations-return-minimal

# 終わりに
今までエラーが起こってもchatGPTやネットの情報しか見ていませんでした。
なぜなら公式ドキュメントは英語で書かれており、読むことに抵抗があったから！！
ですが今後は公式ドキュメントも積極的に確認していかないといけないなと思った事例でした。
static なメソッドにする理由の一つ：インスタンス変数に依存していないことを明示する

レビューでこのようなコメントをもらいました。

「インスタンス変数に依存していないことを明示するために、staticメソッドにするのが良さそうに思います。」

コメントをもらうまでは、メソッドに static をつけるのは「インスタンスを生成せずに呼び出すメソッドの時」という理解でした。これは「インスタンスを生成せずに呼び出すメソッド」であれば「インスタンス変数に依存していないメソッド」と言えるということにコメントをもらって気づくことができました。

初学者の頃は「インスタンス変数に依存していないメソッド」と分かることは一体何が嬉しいの？状態でしたが、今ならその有難みが分かります。
が、うまく言語化できていません（笑）。インスタンスの状態と切り離して考えられる点が嬉しいんだと思っています。脳のメモリが節約できたり、不具合調査のときに役立つイメージですね。

修飾子や型から得られる情報は沢山あります。読み手（未来の自分を含む）に誤解を与えないような修飾子や型をつけられるように頑張っていきたいです。


## 参考記事

https://ufcpp.net/study/csharp/oo_static.html

https://qiita.com/uhooi/items/f32e20750d2fb0f2da46

https://qiita.com/tkhshiq/items/ae431e6e4948dfff929c
wslで、最小のカーネルをコンパイル その24

# 概要
wslで、kernel.elfのコンパイル、やってみた。
IDTを作りたい。

# IDTとは。

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

# サンプルコード

```
#include <stdio.h>


#define D_LDT   0x200   /* LDT segment        */
#define D_TASK  0x500   /* Task gate          */
#define D_TSS   0x900   /* TSS                */
#define D_CALL  0x0C00  /* 386 call gate      */
#define D_INT   0x0E00  /* 386 interrupt gate */
#define D_TRAP  0x0F00  /* 386 trap gate      */
#define D_DATA  0x1000  /* Data segment       */
#define D_CODE  0x1800  /* Code segment       */
#define D_DPL3         0x6000   /* DPL3 or mask for DPL                    */
#define D_DPL2         0x4000   /* DPL2 or mask for DPL                    */
#define D_DPL1         0x2000   /* DPL1 or mask for DPL                    */
#define D_PRESENT      0x8000   /* Present                                 */
#define D_NOT_PRESENT  0x8000   /* Not Present                             */
#define D_ACC      0x100  /* Accessed (Data or Code)          */
#define D_WRITE    0x200  /* Writable (Data segments only)    */
#define D_READ     0x200  /* Readable (Code segments only)    */
#define D_BUSY     0x200  /* Busy (TSS only)                  */
#define D_EXDOWN   0x400  /* Expand down (Data segments only) */
#define D_CONFORM  0x400  /* Conforming (Code segments only)  */
#define D_BIG      0x40	  /* Default to 32 bit mode           */
#define D_BIG_LIM  0x80	  /* Limit is in 4K units             */
struct x86_desc {
   unsigned short limit_low;     /* limit 0..15    */
   unsigned short base_low;      /* base  0..15    */
   unsigned char base_med;       /* base  16..23   */
   unsigned char access;         /* access byte    */
   unsigned int limit_high:4;    /* limit 16..19   */
   unsigned int granularity:4;   /* granularity    */
   unsigned char base_high;      /* base 24..31    */
} __attribute__ ((packed));
struct x86_gate {
   unsigned short offset_low;   /* offset 0..15    */
   unsigned short selector;     /* selector        */	
   unsigned short access;       /* access flags    */
   unsigned short offset_high;  /* offset 16..31   */
} __attribute__ ((packed));
union DT_entry {
   struct x86_desc desc;     /* Normal descriptor */
   struct x86_gate gate;     /* Gate descriptor   */
   unsigned long long dummy; /* Any other info    */
};
#define desc_table(name, length)    union DT_entry name[length] = 
#define stnd_desc(base, limit, control)     {desc: {(limit & 0xffff), (base & 0xffff), ((base >> 16) & 0xff), ((control+D_PRESENT) >> 8), (limit >> 16), ((control & 0xff) >> 4), (base >> 24)}}
desc_table(IDT, 256) {
};
struct { 
	unsigned short limit __attribute__ ((packed));
	union DT_entry * idt __attribute__ ((packed)); 
} loadidt = { (256 * sizeof(union DT_entry) - 1), IDT };

int main(void) {
    
    printf("ok");
}



```

以上。
wslで、最小のカーネルをコンパイル その23

# 概要
wslで、kernel.elfのコンパイル、やってみた。
GDTを作りたい。

# GDTとは。

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

# サンプルコード

```
#include <stdio.h>


#define D_LDT   0x200   /* LDT segment        */
#define D_TASK  0x500   /* Task gate          */
#define D_TSS   0x900   /* TSS                */
#define D_CALL  0x0C00  /* 386 call gate      */
#define D_INT   0x0E00  /* 386 interrupt gate */
#define D_TRAP  0x0F00  /* 386 trap gate      */
#define D_DATA  0x1000  /* Data segment       */
#define D_CODE  0x1800  /* Code segment       */
#define D_DPL3         0x6000   /* DPL3 or mask for DPL                    */
#define D_DPL2         0x4000   /* DPL2 or mask for DPL                    */
#define D_DPL1         0x2000   /* DPL1 or mask for DPL                    */
#define D_PRESENT      0x8000   /* Present                                 */
#define D_NOT_PRESENT  0x8000   /* Not Present                             */
#define D_ACC      0x100  /* Accessed (Data or Code)          */
#define D_WRITE    0x200  /* Writable (Data segments only)    */
#define D_READ     0x200  /* Readable (Code segments only)    */
#define D_BUSY     0x200  /* Busy (TSS only)                  */
#define D_EXDOWN   0x400  /* Expand down (Data segments only) */
#define D_CONFORM  0x400  /* Conforming (Code segments only)  */
#define D_BIG      0x40	  /* Default to 32 bit mode           */
#define D_BIG_LIM  0x80	  /* Limit is in 4K units             */
struct x86_desc {
   unsigned short limit_low;     /* limit 0..15    */
   unsigned short base_low;      /* base  0..15    */
   unsigned char base_med;       /* base  16..23   */
   unsigned char access;         /* access byte    */
   unsigned int limit_high:4;    /* limit 16..19   */
   unsigned int granularity:4;   /* granularity    */
   unsigned char base_high;      /* base 24..31    */
} __attribute__ ((packed));
struct x86_gate {
   unsigned short offset_low;   /* offset 0..15    */
   unsigned short selector;     /* selector        */	
   unsigned short access;       /* access flags    */
   unsigned short offset_high;  /* offset 16..31   */
} __attribute__ ((packed));
union DT_entry {
   struct x86_desc desc;     /* Normal descriptor */
   struct x86_gate gate;     /* Gate descriptor   */
   unsigned long long dummy; /* Any other info    */
};
#define desc_table(name, length)    union DT_entry name[length] = 
#define stnd_desc(base, limit, control)     {desc: {(limit & 0xffff), (base & 0xffff), ((base >> 16) & 0xff), ((control+D_PRESENT) >> 8), (limit >> 16), ((control & 0xff) >> 4), (base >> 24)}}
desc_table(GDT, 3) {
	{dummy:0},
	stnd_desc(0, 0xFFFFF, (D_CODE + D_READ + D_BIG + D_BIG_LIM)),
	stnd_desc(0, 0xFFFFF, (D_DATA + D_WRITE + D_BIG + D_BIG_LIM)),
};
struct {
	unsigned short limit __attribute__ ((packed));
	union DT_entry *idt __attribute__ ((packed));
} loadgdt = { (3 * sizeof(union DT_entry) - 1), GDT };

int main(void){
    
    printf("ok");
}



```


以上。
TiDB関連イベント 4月分

いよいよ4月ですね:cherry_blossom:。心機一転、春からTiDBをはじめて見てはいかがでしょうか！

毎月恒例のイベントの一覧です。
PingCAP主催のもの、コミュニティイベントに参加するものの両方を記載しています。
WebinarについてはJSTで6:00-24:00に開催されるイベントを記載しています。
（こんなのもあるよ！という方、記事にコメントください。追加します）

## 4月6日 〜 4月9日 (現地時間) Hong Kong Web3 Festival

https://www.pingcap.com/event/join-pingcap-at-hong-kong-web3-festival-2024/

https://coinpost.jp/?post_type=breaking&p=507456

最近TiDBのFintech/Web3領域での採用が増えています。Hong Kong Web3 Festivalにもブースを出しています。
お越しの際には是非お立ち寄りください。

## 4月9日 〜 4月11日 (現地時間) Google Next 24'@ Las Vegas

https://www.pingcap.com/event/join-pingcap-at-google-cloud-next-24-in-las-vegas-nv/

Google NextにPingCAPもブースを出しています。日本からも多数参加予定と思いますが、是非お立ち寄りください。
日本では配っていないSwagももらえるかも・・・？

## 4月17日(水)〜4月19日（金） Qiitaカンファレンス

https://pingcap.co.jp/news-qiita-conference-2024/

QiitaカンファレンスにPingCAPも協賛します！ Voicyの千田様よりTiDB採用の経緯についてお話し頂きます。
他にも豪華ゲストが多数登壇するイベントです。オンラインで楽しみましょう！

## TBD

他にもいくつか予定があります。詳細が決まり次第更新していきます！
[電験３種]

# ■記事内容
電験３種を受験、合格したので今後受ける人へのアドバイス用にまとめておく。

〇前提
・会場筆記試験
・2024現在の年２回（上期、下期）受験
・最近ネット上で推奨されている過去問まんま覚えるのではなく、あくまで正攻法の学習を前提としてる。

〇テキスト
・テキスト：　進捗が把握しやすい科目個別のもの。（これだけシリーズ、完全マスターシリーズなど）
・過去問：　電気書院『過去問マスタ 理論の20年分』のシリーズ（単元ごとに問題をまとめてあるので）

# ■スケジュール
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
**上期『理論』『電力』**
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
※5月の申し込みから開始していては充分な学習ができないおそれ

① 1～3月　理論を単元ごとに、テキスト → 過去問の順に学ぶ。（1日あたり1～2時間目安）
② 4～6月　電力も同様に単元ごとに、テキスト → 過去問の順に学ぶ。
③ 7月　過去問をそれぞれ反復。このとき、正解不正解関係なく理解できていない箇所をピックアップ。それぞれ１単元まで捨てる。
④ 8月　過去問をもう１度反復。論説で覚えられない箇所やどうしても無理な問題は付箋をしておき、直前の悪あがきの時間に見返す。
⑤ 試験日　問題を持って帰れるので、マークシートに解答した番号はメモしておく。
⑥ 試験後　次の日に解答が出るので、通知が来る前にすぐに自己採点。数週間も通知を待つと次回への時間ロスになる。

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
 **下期『機械』『法規』**
□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□
※上期で理論、電力に合格した前提

⑦ 8～10月（上期試験後すぐ）　機械の学習を単元ごとに、テキスト → 過去問の順に学ぶ。
⑧ 11～12月　法規の学習。法規はテキストをあまり使わず、過去問の反復でパタン認識的に覚える。
⑨ 1～2月　過去問をそれぞれ反復し続ける。それぞれ苦手箇所をピックアップしながら行う。
⑩ 3月　苦手箇所を中心に過去問を反復する。論説で覚えられない箇所やどうしても無理な問題は付箋をしておき、直前の悪あがきの時間に見返す。
⑪ 試験日 直前まで過去問の付箋箇所を見返しておく。


# ■学習全般
・「１日何ページ」と決めるのは浅はか。理解しているかが大事なので、余裕を持ってスケジュールを立てていく。
　ただ、スケジュール管理は必要なので、１週間で１単元として３～１０日でブレながら進んでいくとか、そんな感じが理想。
・自分自身が理解できているかを把握すること。その手段が問題を解くこと。
　なので、テキストの単元ごとに対応する過去問を一通り解くのを推奨。最初は解けなくてもよい。
・A問題とB問題があり、本番では7割がA問題。なので、過去問の難しいB問題は飛ばしてもよい。（本番までには人取りやるべき）

# ■理論の学習Tips
・直流回路でテブナンは難しいので、シンプルな重ね合わせがよい。（計算量は増えるが）
・交流回路は他の科目を考えると一番大切なので最も重視する。
・三相は線間と相の違いが面倒なら、相電圧、相電流に揃えて考えるところから始める。
・静電気や磁気はその方向などを都度作図し、誤魔化さずにやると理解できる。

# ■電力の学習Tips
・発電所や電線路は画像を検索しながら、イメージと共に覚えることを推奨する。また、近くの変電所や鉄塔などを眺めて学んだものを比較してもいい。少しでも親近感のようなものを感じること。
・計算はエネルギーに関わるものなので、難しくないが単位の揃え方は自分の中で統一したやり方にするとよい。
・パーセントインピーダンスは導出過程も意識して、しっかり理解しておくと機械や法規につながる。

# ■機械の学習Tips
・等価回路図やベクトル図は都度作図しながら解く。公式暗記では、理論でせっかく回路の解き方を身に着けたので、それを活かす。
・機械４機（直流機、誘導機、同期機、変圧器）と呼ばれる単元を重視する。この４機は似ているので内容がゴチャると収拾が付かなくなる。なので、電機子反作用などの論説系の丁寧に理解しながらやりすぎなくらいで進める。
・その他（照明や加熱等）は比較的簡単な傾向だが、馴染みのないものは時間をかけなければならない。難易度の差はこれらの単元への予備知識で変わってくる。

# ■法規の学習Tips
・B問題は電力に近い内容なので、電力を正しく学んでいれば難しくはない。計算が面倒なものも多いが。
・条文を読むのは普通の人は覚えられない。論説はパターン認識で解けるようにしていくしかない。**同じ問題を時間を空けずに反復することを心掛ける。**
過去問の単元ごとに反復がベストか。
・論説は電気知識が正しく身についていると、選択肢を絞り込みやすい。なので、最後に行うのが適している科目と考える。

# ■おすすめすること
気持ちの持ち方について、勉強時におすすめすること。
同時受験して惨敗した人を見て思ったことを、今後の自戒の意味を込めて。

## その1）挑戦者の気持ちで
年齢を重ねて立場が上がると、自身過剰になりがち。
特に、後出しじゃんけんばかりして無難に生きているのがモットーな人ほど危険。

## その2）自分が理解できているか？を問うこと
自分が内容を理解できたかを把握すれば自ずとゴールに進むことができる。
理解できたかは問題を解けるか？ 間違えたのなら解説を読め分かる。

## その3）いいわけをしない
自分のことは自分がよく分かっている。それを客観視して自制すること。
自分への怒りに嘘をつくことは“逃げる”という行動に繋がってしまう。
『範囲が広い』『勉強時間が無かった』などの言い訳でなく、次は『早めに準備しよう』『自分の実力を踏まえて１科目ずつ受験しよう』など、次に向かった反省をするべき。
【初心者】AWS Lambdaとサーバレス

# 目的
AWS Lambdaについての基本を知るため。
AWSを触る上で重要な概念であるサーバレスにも触れる。

# Lambdaとは
開発した関数をサーバレスに実行できるサービス。

## サーバレスとは

アプリケーション実行環境をマネージドサービスとして提供されたもの。

サービス使用者（私）は、サーバの構築やOSのバージョンアップなどの管理をする必要がない。
Lambdaでは関数さえあれば、サーバを意識することなく実行環境が構築できる。

## マネージドとは

サービス提供者（AWS）がインフラの管理や運用を含めてサービスとして提供する形態のこと。


## Lambdaの仕組み（簡素）

Lambdaは同時実行リクエストごとに、実行環境の個別のインスタンスをプロビジョニングします。

### LambdaをVPCにアタッチしていない場合
実行可能なAZで起動する。


### VPCにアタッチする場合
複数のAZでサブネットを指定することで高可用性を担保する。


## Lambdaにおける2つの実行方式（非同期・同期）

### 非同期実行
呼び出し元が処理結果を待機しない方式のこと。
呼び出されたLambdaはリクエストをキューに入れて、呼び出しもとに追加情報のない成功のレスポンスを返却する。
S3のPUT（格納）トリガーをもとにLambdaを起動する場合、
S3は処理を待機せず、Lambdaも結果を返さない。
エラーが発生した場合、デフォルトで2回再試行する。（初回も含めると3回実行する）

設定時は、呼び出しパラメータをEventに設定する。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/invocation-async.html


### 同期実行
呼び出しもとが処理結果を待機する方式のこと。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/invocation-sync.html

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/invocation-retries.html




# Lambdaの金額

関数へのリクエストの数×コードの実行時間×メモリサイズあたりの料金で決まる。

メモリサイズが大きいほど、1ミリ秒あたりの料金が高くなる。
倍のメモリサイズでも実行時間が1/2になれば料金は変わらないということになる。

https://aws.amazon.com/jp/lambda/pricing/


# 同時実行数の計算方法

同時実行数 = 1秒あたりの平均リクエスト数*平均リクエスト時間 (秒単位)
SalesforceのAPIを使う時に間違えやすいポイント



何故かBulk API Ver 1ではヴァージョンの部分は数字だけですが、その他の大半のAPIではvが付きます。
ついつい間違えてしまうポイントです。

+ [Salesforce: Upload Apex Trigger via Java](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007YwWuT)

この場合は404エラーになるのでエンドポイントが違います。その時はvがあるかをチェックします。
以下も同じでした。

:::note alert

Request URL: [https://REDACTEDDOMAIN.my.salesforce.com/services/data/56.0/sobjects/ApexTrigger]

Request body: [{"Name":"UploadTest_AccountTrigger","TableEnumOrId":"Account","Body":"trigger Account_AccountWebhook on Account (after insert, after update) {}"}]

Status Code: [404]

Body: [[{"errorCode":"NOT_FOUND","message":"The requested resource does not exist"}]]
:::

:::note
So after the depressing finding that the "v" prefix for the version is missing the Tooling API approaches base URL it works now as described.

Below you can find the correct way to build the request URL (replace this in the Tooling API Approach:

 
```
String url = session.getBaseUrl() + "/services/data/v" + session.getApiVersion() + "/sobjects
```

:::
CpawCTF Q12.[Crypto]HashHashHash!

以下サイトなどのSHA1ハッシュ復元サイトを用いてハッシュ値を下に戻し，フラッグを入手する．
[ハッシュ値の復元サイト](https://sha1.gromweb.com/)

https://qiita.com/motitt/items/093487824ae4ba5e1157
FastAPI用のDBを準備する（オープンデータ活用④）

※この記事はドラフト版です。

その内使うと思うのでDBも用意しておきます。

### 本番環境へログイン
PowershellやTeraTerm等でsshでログインする
GitLabとの連携で使用した秘密鍵「id_rsa」を使うと楽です。
（秘密鍵を使いまわすリスクは考慮しない）


```sh
ssh -i .\id_rsa  ubuntu@example.sakura.ne.jp
```
    
### Postgresqlインストール
```sh
sudo apt install postgresql postgresql-contrib
```
    
### ユーザの切り替え
PostgreSQLはローカルホストからの接続でPeer認証を使用している為
OSのユーザ名とデータベースユーザと同一である必要がある
（インストールするとpostgresが作成されているみたい）
```sh
sudo -i -u postgres
```

### psqlの起動。DBへ接続
```sh
psql
```
    
### 接続の確認
```sh
postgres=#
```

### 接続の解除
```sh
postgres=# \q
```

### パスワード認証の設定
ローカルホストからのアクセスにはパスワード認証を使うように設定する
```sh
sudo nano /etc/postgresql/14/main/pg_hba.conf
```
```diff:変更する箇所
- local   all             all                                     peer
+ local   all             all                                     password
```
### 再起動
```sh
sudo systemctl restart postgresql
```

### psqlを実行
```sh
psql
```

### ユーザ（ロール）の作成
ユーザ=ロールらしいです。※ログイン権限があるかないかの違い
```sql
postgres=# create role imari_opendata created encrypted password 'imari_opendata';
```

### 専用のデータベースを作成
```sql
postgres=# createdb imari_opendata
```

### 「imari_opendata」ユーザ（ロール）が「imari_opendata」DBにアクセスできるようにする
```sql
postgres=# grant connect on database imari_opendata TO imari_opendata;
```

### ユーザ（ロール）にログイン権限をつける
```sql
postgres=# ALTER ROLE "imari_opendata" WITH LOGIN;
```

### ユーザ（ロール）にimari_opendataデータベースに対してすべての権限をつける
```sql
postgres=# GRANT ALL PRIVILEGES ON DATABASE imari_opendata to imari_opendata
```

### psqlから抜ける
```sql
postgres=# \q
```

### ユーザ（ロール）でデータベースにログインする
```sh
psql -U imari_opendata -d imari_opendata
```

### 現在のスキーマを確認
※「;」をつけないと実行されないので注意
　publicのスキーマになっているはず
```sh
select current_schema;
```
```powershell
imari_opendata=> select current_schema;
 current_schema
----------------
 public
(1 row)
```

これで、オープンデータ用のデータベースとユーザが作成できました。
別記事で、オープンデータのcsvをDBに登録したいと思います。
FastAPI + nginxの本番環境を作成する（オープンデータ活用②）

※この記事はドラフト版です。

# 手順
1. 本番サーバの準備
1. nginxのインストールと起動
1. FastAPIのインストールと起動

# 本番サーバの準備
さくらインターネットのVPSというサービスを契約
- OS：Ubuntu
- プラン：1Gプラン

https://vps.sakura.ad.jp/

# nginx のインストールと起動
さくらの公式が手順を公開している
ポイントは下記
- OSのファイアーウォール
- さくらのVPSのパケットフィルター
 
https://knowledge.sakura.ad.jp/35881/


# FastAPIのインストールと起動
本番サーバ上で次の作業を行います。
### 作業ディレクトリの作成
伊万里市のオープンデータを返すAPIを作成する体で作る
```bash
mkdir fastapi
cd fastapi/
mkdir imari_city_opendata
cd imari_city_opendata/
```

### インストール
```bash
sudo apt install python3-pip
sudo apt install python3.10-venv
python3 -m venv venv
source venv/bin/activate
pip install fastapi uvicorn[standard] gunicorn
```
### FastAPIのコード

```python:main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}
```
### 起動確認
```sh
uvicorn main:app --reload
```
http://127.0.0.1:8000にアクセスしてjsonが返ってくれば成功

### gunicornの準備（アプリと同じとこに準備）
```sh
nano gunicorn_conf.py
```
```py:gunicorn_conf.py
from multiprocessing import cpu_count

chdir = '/home/ubuntu/app/fastapi/imari_city_opendata'

# Socket Path
bind = 'localhost:8000'

# Worker Options
workers = cpu_count() + 1
worker_class = 'uvicorn.workers.UvicornWorker'

# Logging Options
loglevel = 'debug'
accesslog = '/home/ubuntu/app/fastapi/imari_city_opendata/fastapi_access_log'
errorlog = '/home/ubuntu/app/fastapi/imari_city_opendata/fastapi_error_log'
```

### daemon
```sh
sudo nano /etc/systemd/system/fastapi_imari_gunicorn.service
```
```conf:fastapi_imari_gunicorn.service
[Unit]
Description=Gunicorn Daemon for FastAPI Test Application
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/app/fastapi/imari_city_opendata/
ExecStart=/home/ubuntu/app/fastapi/imari_city_opendata/venv/bin/gunicorn -c /home/ubuntu/app/fastapi/imari_city_opendata/gunicorn_conf.py main:app 
[Install]
WantedBy=multi-user.target
```
### 起動
```shell
$ sudo systemctl start fastapi_imari_gunicorn
$ sudo systemctl status fastapi_imari_gunicorn
```
### 自動起動
```shell
$ sudo systemctl enable fastapi_imari_gunicorn
```

### Nginxの設定
```sh
 sudo nano /etc/nginx/conf.d/fastapi_imari_opendata.conf
```
```conf
server {
        server_name example.sakura.ne.jp;

        root /home/ubuntu/app/fastapi/imari_city_opendata;

        location / {
                proxy_pass http://localhost:8000;
        }
```
### Nginxの再起動
```sh
sudo nginx -s reload
```

https://b13.app/web/fastapi-hello-world/#gunicorn%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E3%82%8B

# 確認
インターネット上で見ることができた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/ea21834d-6ec5-37b3-a464-4fbf719e7857.png)


# 今後の予定
本番環境を用意することを最優先し、予定を組む
優先度順に並べると、次の通り
## 必須
- 本番環境へのCDを試す
- 本番環境にDBを作成
- テストコードを作成
- SSLを設定

## その内でよい
- コンテナで本番デプロイ
- .sock周りを調査
オープンデータの活用計画（オープンデータ活用①）

※この記事はドラフト版です。

# 目的
- 社内の月１での発表のネタ作り
- モダンなシステム開発へのシフト
- 伊万里市のへの貢献

# 目標
  - オープンデータをAPI化する
  - 活用事例を作る

# 計画
本番環境での運用を最優先に計画を遂行していく
1. 資料の作成（オープンデータとは）
1. 本番環境の作成
1. **☆本番環境へのデプロイの自動化**
1. アプリ開発
    - APIはFastAPIで作成
    - フロントは別に何でもいい
**☆ただし、TDDで開発を行う**
1. 本番環境でのテストの自動化
1. 開発環境の良化
1. ステージング環境などの検討
1. （おまけ）コンテナでの環境構築
ハッシュ化と暗号化の違い

# ハッシュ化と暗号化の違い
### 可逆性と不可逆性
ハッシュ化を行う関数をハッシュ関数，ハッシュ化した後のデータをハッシュ値という．
ハッシュ化は特定のアルゴリズムを用いて元のデータ列を不規則な値に置換し，ハッシュ値から元のデータ列を特定しにくくするものである．
秘匿性が必要なデータを一方的に送る場合によく用いられる．

暗号化は可逆性があり暗号化したデータ列から元のデータを復元することができる．
秘匿性が必要な通信でよく用いられる．

# ハッシュ化への攻撃
SHA1ハッシュに対してはレインボーテーブルなどを用いて効率的に解読することが可能である．
どのようなアルゴリズムを用いたハッシュ化・暗号化であっても，仕様字種が限られている場合やデータ列が短い場合などはブルートフォース（総当たり攻撃）を用いて解読されることがある．
# 参考文献
https://eset-info.canon-its.jp/malware_info/special/detail/211013.html
2024/3/26主にITとかセキュリティの記事

アクト、製造業｜DX支援サービス導入事例のホワイトペーパーを公開(3/24)
https://prtimes.jp/main/html/rd/p/000000117.000076503.html

GitHub、自動的にコードの脆弱性を検出して修正提案する機能を導入(3/24)
https://news.mynavi.jp/techplus/article/20240324-2911523/

ChatGPTを安全に使う方法　「生成AI」のリスクとは？(3/24)
https://atmarkit.itmedia.co.jp/ait/articles/2403/24/news021.html

Android 対象範囲別ストレージの導入と外部ストレージにおけるファイルアクセス制限(3/24)
https://zenn.dev/kaneko_s/articles/4e4a7947895d34

危険から身を護る対策は「最新・複雑・多要素認証」が正解でした！(3/24)
https://ascii.jp/elem/000/004/190/4190525/?rss

コラム：「ニアショアリング」で注目のメキシコ、利益享受に高い壁(3/24)
https://jp.reuters.com/opinion/forex-forum/I4YIU7GJSBJAJDG4RQJM3KUJEA-2024-03-23/

生成AIを社内で活用する際の課題7選とその対策！競合に負けないためのノウハウを解説(3/24)
https://weel.co.jp/media/gen-ai-use-problem

生成AIの無料ツール一覧をニーズ別に紹介！使用する際の注意点も解説(3/24)
https://weel.co.jp/media/gen-ai-free-tool

中高生がサイバー犯罪対処能力を競う全国大会　鯖江市(3/24)
https://www3.nhk.or.jp/lnews/fukui/20240324/3050017397.html

仮想通貨トロン（$TRX）とは？特徴と将来性について徹底解説!(3/24)
https://crypto-times.jp/tron/

内閣府再生可能エネルギー等タスクフォースの資料に「国家電網公司」の透かしが：不正アクセス等による改ざん？(3/24)
https://agora-web.jp/archives/240323071402.html

河野太郎さん肝入りの再生可能エネルギータスクフォース、内閣府の組織なのに中華がズブズブに関与している形跡を発掘されてしまい大慌てで証拠隠滅に走る
https://kabumatome.doorblog.jp/archives/66020076.html

内閣府の再エネ資料に中国国営企業のロゴマーク　中共影響力への懸念広がる(3/24)
https://www.epochtimes.jp/2024/03/212641.html

政府の会議体に中国政府・中国企業の影。内閣府は正面から原因究明を徹底せよ(3/24)
https://agora-web.jp/archives/240323210916.html

内閣府規制改革推進室「中国企業の透かしは大林ミカ氏が事業局長を務める自然エネルギー財団の資料」(3/24)
https://agora-web.jp/archives/240323210525.html

SNMP(3/25)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/031500132/031800026/

トヨタ系クラウドで情報流出か　AWSアクセスキー悪用される(3/25)
https://xtech.nikkei.com/atcl/nxt/mag/nnw/18/031800050/031800061/

「生保にメインフレームは不可欠」ソニー生命が月1000件超のバッチ処理依頼を自動化(3/25)
https://xtech.nikkei.com/atcl/nxt/column/18/00001/09072/

世田谷区が職員向け生成AIサービスで業務効率化、職員チームが3カ月で構築(3/25)
https://xtech.nikkei.com/atcl/nxt/news/24/00404/
kotlin初心者と学ぶ、kotlin超初級編（実行環境準備編）

# 目的
おじょちと申します。
本記事では、
 **「kotlin初心者であるおじょちと一緒に、kotlinの基礎的な部分を改めておさらいしていこう！」**
というのをコンセプトにしています。
初学者の方はもちろん、経験者の方も、
「あれ、これってこうなんだっけ？」
と気になるところがありましたら、コメントなどでご指摘いただけると助かります🙇‍♀️

# 自己紹介
名前：おじょち
技術：kotlin(2カ月)

# 実行環境
今回、実際にkotilnを動作させる環境は、対話型shellといわれている、Kotlin REPLを使用します。
AndroidStudioが入っていれば使用できる機能のため、AndroidStudioのインストールをおすすめします。

## Kotlin REPL
手順
1. AndroidStudioを開き、appの部分をクリック
1. その方状態で、左上のハンバーガーメニューをクリック
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566153/d3dac03c-d742-5417-f451-9dc12822b98e.png)

1. Tools→Kotlin→Kotlin REPL(Experimental)をクリック

![Untitled (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566153/b7cb6b11-d794-3c59-bd2e-ffa1c5a938e6.png)

この手順で立ち上がったshellに対してカチカチ打ち込んでいきます。
※手順「1.」でappを選択していないとエラーが出てしまうため、エラーが出た際はそこを見直してみてください！！※
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1566153/9f6b6c1f-03ed-d558-d8e3-600efeec414d.png)


# 終わりに

次回は実際に基礎的な部分を実行して勉強していきたいと思いますので、お楽しみに！！！
文字のエッジ座標をトレースして取り出す話

もう過ぎちゃいましたが 3/14 といえば Happy $\pi$ (pi) day ということで、これ。


![image_0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149511/352ecef3-7968-72a6-6867-ca21d70fde75.gif)


File Exchange: [Visualization of the Complex Fourier Transform](https://jp.mathworks.com/matlabcentral/fileexchange/72219-visualization-of-the-complex-fourier-transform)


↑のフーリエ変換のアニメ化をするコードを使って描いていますが、元になる文字の座標点を用意する必要があります。


そこで、文字（ここでは $\pi$ ）のエッジを抽出した方法を記録に残しておきます。

# まず文字の画像を作成

text 関数で文字を表示させて画像として出力します。

```matlab
h_fig = figure;
% text を figure に表示
text2plot = '\pi';
text(0.5,0.5,text2plot, ...
    FontSize=200,... % 大きめの文字サイズ
    HorizontalAlignment='center',...
    VerticalAlignment='middle')
```

![untitled1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149511/0b0603f1-591d-c6db-b6f6-ac374124214e.png)


座標軸が邪魔なので消します。

```matlab
axis off
```

![untitled2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149511/a7c537a5-d7a7-ea41-c618-320d6d48d450.png)

そして画像として出力

```matlab
% 画像出力
exportgraphics(h_fig,'pi_image.png');
```

![](./generateTextPlot_media//)
# 画像からのエッジ抽出

画像を読み込んで２値化します。

```matlab
% 画像読み込み
I = imread('pi_image.png');
BW = im2gray(I);
figure
imshow(BW);
```

![figure_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149511/3f1d25ee-ef07-1f53-c23c-61c0c06c0923.png)

エッジ抽出は [edge 関数](https://www.mathworks.com/help/images/ref/edge.html)

```matlab
% 二値化してエッジ検出
BW_edge = edge(BW);
imshow(BW_edge)
```

![figure_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149511/c5fbe1da-b8ce-a208-3291-c5889c9194b1.png)


```matlab
% 位置検出
```

[find 関数](https://www.mathworks.com/help/matlab/ref/find.html)で true (= 白) の位置を見つけることができますが、このままだと隣接したピクセルを並べて取ってくれることを保証しないので・・

```matlab
[row,col] = find(BW_edge);

figure
plot(col,row)
set(gca,'YDir','reverse') % 画像データは y 軸が逆
```

![figure_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149511/57e86b59-7060-6350-cd22-0cb1a187da21.png)


plot するとこんな感じになります。隣り合っていないエッジの座標点が線で繋がっている様子がわかります。

# エッジのトレース

エッジをなぞる順に並べるにはトレース開始位置を指定して [bwtraceboundary 関数](https://www.mathworks.com/help/images/ref/bwtraceboundary.html)。開始位置と次のピクセル探索方向を指定しますが、探索方向は外れててもなんとかしてくれるようです。開始位置は先ほど見つけた row/col の１要素目でいきます。

```matlab
% 探索初期方向 "NW" は外れてもまぁOK
R = bwtraceboundary(BW_edge,[row(1),col(1)],"NW");
```

プロットしてみます。

```matlab
figure
R = R(:,[2,1]);% 行と列を入れ替えておく
plot(R(:,1),R(:,2))
set(gca,'YDir','reverse')
```

![figure_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149511/d4fa0ebf-8130-422c-b082-b3032c898c98.png)


mat ファイルに保存しておくと、上で紹介したフーリエ変換のアニメ化するコードでそのまま使用できます。


File Exchange: [Visualization of the Complex Fourier Transform](https://jp.mathworks.com/matlabcentral/fileexchange/72219-visualization-of-the-complex-fourier-transform)

```matlab
save('R_pi.mat','R');
```

Have fun!
wslで、最小のカーネルをコンパイル その22

# 概要
wslで、kernel.elfのコンパイル、やってみた。
PITを叩きたい。

# PITとは。

https://en.wikibooks.org/wiki/X86_Assembly/Programmable_Interval_Timer

# IOポートにつながったレジスタ
|IOポート	|レジスタ名	|Write	|Read|
|:-|:-|:-|:-|
|0x0040	|Counter0	|o|o|
|0x0041	|Counter1	|o|o|
|0x0042	|Counter2	|o|o|
|0x0043	|Control Word|o||

# 実験

サンプルコード

```
			uint8 v = inb(0x0040);
			print_string("40 = ");
			print_hex(v);
			v = inb(0x0041);
			print_string("41 = ");
			print_hex(v);
			v = inb(0x0042);
			print_string("42 = ");
			print_hex(v);

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e544d823-f874-5aa8-c274-cdf04ef1bc54.png)

以上。
DockerでMySQLコンテナが起動後しばらくしてからExited(137)するのでPerformance Schemaを停止する

# 結論

Docker Composeをメモリの小さなサーバで動かしていると、メモリをたくさん使うコンテナがExited with code 137で停止してしまう。

今回停止してしまったコンテナはMySQLであり、Performance SchemaをOFFにすることでメモリ使用量を大幅に削減し、今の所正常に動作中（経過観察中）。

# 経緯

就職活動にてポートフォリオとして制作したWebアプリですが、Docker Composeを使用して開発、そしてVPSで公開する際もDocker Composeを使用して公開しています。
[【個人開発】韓国語の文法を復習するアプリ「サクッと作文　韓国語」のデモ版をリリースしました #個人開発 - Qiita](https://qiita.com/yuri_t/items/747a4369bc25c5561139)

VPS上にてdocker compose up にてコンテナを起動した時には問題は起きず、正常に使えます。しかし、しばらく時間が経つ（数日など）と、いつのまにかエラーが表示され、どうやらデータベースが動いていないと推測できました。

# Dockerでエラーの原因を調べる

## コンテナの状態を確認する
```
docker container ls
```
不具合が起こってから上記のコマンドでコンテナの一覧を表示させたところ、MySQLコンテナが見つかりません。
```
docker container ls -a
```
aオプションを追加して停止中のコンテナも表示させたところ、MySQLコンテナが停止してしまっていました。
```
docker ps -a
```
更にこちらのコマンドで確認すると、Exited(137)とのこと。こちらのコードを調べてみると、メモリ不足により停止したことがわかりました。
[Docker containerが突然止まる問題 | freks blog](https://blog.freks.jp/docker-container-stop-suddenly/)

## コンテナのメモリ使用状況を調べる
```
docker stats
```
こちらのコマンドで調べてみると、MySQLコンテナだけで400MiB以上使用されていました。私はさくらのVPSを1Gで使用中ですので、かなりの割合です。これが原因のようです。

確かに、ローカルではコンテナは停止しません。原因を突き止めました。

# MySQLのメモリ使用量を大幅に削減する

MySQLコンテナが大量にメモリを使用しているのはわかりましたが、使用量を減らせるのでしょうか。もし減らせないのなら、VPSの契約を1Gから2Gに変更する必要があるかもしれません。今はまだそこまでお金をかけられない。

困っていたところ、いろいろ探した結果「Performance Schema」というものを見つけました。

## performance schemaとは

[MySQL5.6にてperformance_schemaを停止したところ、メモリの使用量が圧倒的に減少した | 田舎に住みたいエンジニアの日記](https://blog.ybbo.net/2015/07/20/performance_schema-off-on-mysql5-6/)

このPerformance Schemaというものが非常に重要な機能だとしたら、停止したらよくないのかもしれないので調べてみました。

[Performance Schemaの仕組みと活用法の紹介 - freee Developers Hub](https://developers.freee.co.jp/entry/survey-performance-schema)

[第4回　MySQLチューニング（3）　パフォーマンススキーマ | gihyo.jp](https://gihyo.jp/dev/serial/01/MySQL-tuning-scale/0004)

このあたりを読むと、もともとはデフォルトはOFF、本番環境ではOFFが推奨されていたということから、OFFにしても問題はないと判断しました。将来的にMySQLを高度に使いたい時に使用するかもしれませんが、今の所大丈夫そうです。

## Performance Schemaの状態を確認する
MySQL内で以下のコマンドを実行します。
```
SHOW VARIABLES LIKE 'performance_schema';
```
こちらでONであることが確認できました。

## Performance SchemaをOFFにする

my.cnf（MySQLの設定ファイル）に以下の行を追加するだけです。
```my.cnf
[mysqld]
performance_schema=off
```
Dockerコンテナの場合、my.cnfに上記を追加し、コンテナを再ビルドしたところ、OFFにすることができました。

## Performance SchemaをOFFにした結果
docker statsで調べたところ、メモリ使用量は約400MiBから約150MiBまで減りました。
こちらの対処を行なった後、今の所MySQLコンテナは停止していません。今後の経過観察が必要ですが、メモリ不足でコンテナが停止することがあること、Dockerコンテナのメモリ使用量の調べ方、Performance Schemaというものがあることを知り、勉強になりました。
wslで、最小のカーネルをコンパイル その21

# 概要
wslで、kernel.elfのコンパイル、やってみた。
PICを叩きたい。

# PICとは。

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


# IOポートにつながったレジスタ
|IOポート	|レジスタ名	|Write	|Read|
|:-|:-|:-|:-|
|0x0020|マスター PIC - コマンド	|o|o|
|0x0021|マスター PIC - データ	|o|o|
|0x00A0|スレーブ PIC - コマンド	|o|o|
|0x00A1|スレーブ PIC - データ	|o|o|

# 実験

サンプルコード

```
			uint8 v = inb(0x0021);
			print_string("21 = ");
			print_hex(v);
			v = inb(0x00A1);
			print_string("A1 = ");
			print_hex(v);

```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/dd3a33a6-3e64-a609-e327-091df0b04219.png)


以上。
STM32C011を使い、RCサーボSG-90を角度(-90,0,90)でコントロールして遊ぶ。(STM32C011J4M7))


x かころぐをみよ
x モバイルバッテリにつないで遊んでください。(パソコンが壊れます)


目的
サーボで遊ぶ
===完成202403261622===

まず、オンラインコンパイラーでテストした

```c++


//左端 -90のステップ
#define V_M_90   531
//中心の0のステップ
#define V_0    1441
//右端 90　計算値
//#define V_90 2352

//-90から0までのステップ
#define STEP_Q (( (( V_0 - V_M_90 )*1000)  / 90 )+7)

//角度から0から255の数値に変換(マクロ)
//Vは、角度
#define KI(V) ( (V_M_90*1000) + ( (STEP_Q) *  (V + 90) )         )

//1000の割り算 だいたい正しい。
#define DIV1000(n) ((n+((n*25)>>10))>>10)

//ざっくり1000で割る
#define KJ(V)   DIV1000( (KI(V)) )


#include <iostream>
using namespace std;
int main(void){
    // Your code here!

    for(int i=-90;i<=90;i=i+15){
        
        printf("%5d %8d\n",i,KJ(i));
        
    }

    
}




```

```

  -90      531
  -75      683
  -60      834
  -45      986
  -30     1138
  -15     1290
    0     1442
   15     1594
   30     1745
   45     1897
   60     2049
   75     2201
   90     2353


```

配線

1 PWM
2 3.3V
3 GND
4 NRST

8 SWD
7 SWD
6 未接続
5 未接続


結果

![o_cop993.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/df1d1e18-cec1-e632-0506-cb2b6bd3a383.jpeg)



![o_cop99c.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2bda0c80-5035-0e7f-445f-0e2fcf886550.jpeg)



プログラム



```c++



//PWM_Servo_C011_1

//定義
//左端 -90のステップ
#define V_M_90   542
//中心の0のステップ
#define V_0    1441
//右端 90　計算値
//#define V_90 2352

//-90から0までのステップ
#define STEP_Q (( (( V_0 - V_M_90 )*1000)  / 90 )+7)

//角度からuSの数値に変換(マクロ)
//Vは、角度
#define KI(V) ( (V_M_90*1000) + ( (STEP_Q) *  (V + 90) )  )

//1000の割り算 だいたい正しい。
#define DIV1000(n) ((n+((n*25)>>10))>>10)

//ざっくり1000で割る
#define KJ(V)   DIV1000( (KI(V)) )

//data SG90
// 2400us 2.4ms
#define s_max  2400
// 500us 0.5ms
#define s_min  500
#define s_r    (2400-500)
#define s_c    (65536/20000)*1000

//#define SN(n6)  (n6*((65536/20000)*1000))
//↓式変形と要約↓6万を2万で割ると3ぐらい、3を1000倍するとだいたい3000
#define SN(n6)    (n6*3277)

#define DD PB7    // potentiometer connected to analog pin x


//サーボ関数
//入力は、-90から90 サーボが仕様の端から端まで動く値
void Servo_S(int b) {

  int ii = KJ(b);
  //ii = 1450;//degug
  analogWrite(DD, DIV1000(SN(ii)));   // analogRead values go from 0

} //Servo_S


//初期化
void setup() {

  delay(3000);//マッポの手先、消したら、いかんぜょ(斎藤由紀風)

  //GPIOの初期化
  pinMode(DD, OUTPUT);   // sets the LED pin as output
  analogWriteFrequency(50);   //周波数
  analogWriteResolution(16);  //分解能

} //setup


//メインループ
void loop() {

  Servo_S(-90); delay(2000); //2秒待つ

  Servo_S(0);   delay(2000); //2秒待つ

  Servo_S(90);  delay(2000); //2秒待つ

  Servo_S(0);   delay(2000); //2秒待つ

} //loop



```
OOC 2024 個人的感想

## はじめに
オブジェクト指向カンファレンスに参加したので、聴講したセッションを個人的な感想で適当にまとめる。

## Kyenote
https://fortee.jp/oocon-2024/proposal/acca3dc6-26ca-4635-9884-7a1dd99069a8
https://twitter.com/hhany
**オブジェクト指向までの流れから、そもそもオブジェクト指向でやりたかったことを確認できた。**
オブジェクト指向の (というか DDD の？) やり方として、DIP が最初に思い浮かんだが、リスコフの置換原則について考えさせられた。
抽象でプログラミングするというイメージを意識していきたい。

## 現実世界の事象から学ぶ SOLID 原則
https://fortee.jp/oocon-2024/proposal/e1eb34cf-78ef-43f6-8a03-bb26c996cb62
https://speakerdeck.com/h0r15h0/xian-shi-shi-jie-noshi-xiang-karaxue-busolidyuan-ze
https://twitter.com/H0R15H0
**SOLID 原則の内の SOL について具体例を用いてかんたんに説明されていた。**
リスコフの置換原則などは、Kyenote に繋がるところもあった。

## インターフェースの目的別分離
https://fortee.jp/oocon-2024/proposal/857fd0a4-b04e-41f1-a0f3-6bbeb3fa0779
https://twitter.com/fuwasegu
https://speakerdeck.com/fuwasegu/object-oriented-conference-2024
**interface の使用例を目的別に紹介されていた。**
差し替え可能性や境界分離は思い浮かんだが、プログラミングを語る上では特性表現を忘れてはいけないなと思った。

## 社内共通ルールを値オブジェクトにして社内ライブラリとして運用してみた話
https://fortee.jp/oocon-2024/proposal/2aa7d709-6481-41e6-a36f-88ee04f258f3
https://twitter.com/_syoryu89
https://speakerdeck.com/leveragestech/she-nei-gong-tong-ruruwozhi-obuziekutonisiteshe-nei-raiburaritositeyun-yong-sitemitahua
**ユーザー情報のルールを社内で共通化した。**
***俺たちが考えた最強のルール***ではなく、できるだけ末端のルールを採用することで最小限のルールを素早く共有するというのが面白かった。
廊下で話していて、最小限のルールを定義するというのがインターフェースにも繋がるところがあるという気づきもあった。

## 総括
### セッション
自分が聞いたお話はインターフェースにまつわる話が多く、インターフェースについてより理解を深めることができた。

### その他
勉強会やカンファレンスにコツコツ出席していると、知っている方が増え、廊下や懇親会で話せるようになってきた。
懇親会では日本酒を提供させていただいた。日本酒の輪も広がりよかった。

## 感謝
OOC であったこと全てに感謝いたします、ありがとうございました。

## 写真
![20240324-104852-L1009782-LEICA M10 MONOCHROM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600771/f0ea2114-acd0-4076-7ef3-4e2a36da4b3b.jpeg)
![20240324-142133-L1009789-LEICA M10 MONOCHROM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600771/e3e7f60b-1b1f-3ee6-d877-5203aa17172a.jpeg)
![20240324-151132-L1009793-LEICA M10 MONOCHROM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600771/c30d89e0-f666-19bd-1f29-a2f5110f9f07.jpeg)
![20240324-173422-L1009802-LEICA M10 MONOCHROM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600771/f4f0dbc2-7df0-9211-e930-a71dd4a57573.jpeg)
![20240324-182013-L1009809-LEICA M10 MONOCHROM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600771/e4e21999-e98a-8ef9-6279-249777faa276.jpeg)
![20240324-184023-L1009814-LEICA M10 MONOCHROM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600771/e101ba07-45b1-7aa3-2e0e-736c23da2621.jpeg)
![20240324-185609-L1009823-LEICA M10 MONOCHROM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600771/8b828e96-17e2-0bd4-a76d-221d04d3e472.jpeg)
![20240324-192642-L1009834-LEICA M10 MONOCHROM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2600771/c08bd783-1301-3f97-e0c5-d0e761709072.jpeg)
gitで過去のコミット時点に戻りたいとき

変な変更をしてしまい、よくわからないエラーが出た。
間違えて上書きしてしまい、最新の状態でなくなったとき、過去のコミット時点に戻りたいと考えますよね。

下記のコードを実行するだけで解決です。

```
git log
=>commit 123456789
Author: Ubuntu <ubuntu@ip-172-31-19-168.ap-northeast-1.compute.internal>
Date:   Wed Feb 8 02:34:41 2023 +0000
```

git log をすると過去のコミットログが出てきます。
戻りたい地点のログを探し、commit の右側にある数字を控えます。

```
git reset --hard 123456789
```

控えた数字を、git reset --hard の後に入れるだけ。
git コマンドでブランチを変更したりマージする方法












▼現在のブランチの状態(一覧)を確認する方法
```
git branch
```

▼ブランチの作成
```
git branch ブランチ名
```

▼ブランチを切り替える方法
```
git checkout ブランチ名
```

▼ブランチの削除
```
git branch -d
```
▼現在のブランチ名の変更
```
git branch -m　新しいブランチ名
```
▼現在いる場所でないブランチ名の変更
```
git branch -m 古いブランチ名 新しいブランチ名
```
▼現在のブランチに、指定したブランチの状態を上書きする
```
git merge　ブランチ名
```
[SwiftUI] ToggleStyleの使い方

# はじめに
`ToggleStyle`を使ってカスタマイズしたチェックボックスを作る方法を調べてみました

# 環境
Xcode 15.2

# 内容

こちらのサンプルコードの中で`ToggleStyle`を上手に使っていましたので参考にします

https://developer.apple.com/documentation/swiftui/focus-cookbook-sample

チェックボックスはこのようなUIで作られていました

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/1044c168-47fc-d380-a603-086c1587ce78.png" width="200"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631585/a4393b7e-ea69-d1cb-6c01-5a3fceaa9775.png" width="200">

このチェックボックスは`ChecklistToggleStyle`として定義します

https://developer.apple.com/documentation/swiftui/togglestyle

```swift
struct ChecklistToggleStyle: ToggleStyle {
    func makeBody(configuration: Configuration) -> some View {
        Button {
            configuration.isOn.toggle()
        } label: {
            Image(systemName: configuration.isOn ? "checkmark.circle.fill" : "circle.dashed")
                .foregroundStyle(configuration.isOn ? .green : .gray)
                .font(.system(size: 20))
                .contentTransition(.symbolEffect)
                .animation(.linear, value: configuration.isOn)
        }
        .buttonStyle(.plain)
        .contentShape(.circle)
    }
}

extension ToggleStyle where Self == ChecklistToggleStyle {
    static var checklist: ChecklistToggleStyle { .init() }
}
```

`Toggle`に対して`.toggleStyle(.checklist)`とすることで`ChecklistToggleStyle`の実装が反映されます

`Toggle`が含まれるViewに対して実装することでView全体に反映することもできます

```swift
Toggle(activity.name, isOn: $activity.isComplete)
    .toggleStyle(.checklist)
```

# おわりに
`Toggle`は標準のまま使うことが多かったのですが、`ToggleStyle`を使うことで簡単にカスタマイズできることがわかったので使っていこうと思います