OmniAICreator/Qiita-1.07M huggingface dataset:
rex0220 計算式プラグイン 複数テーブルの転記(TABLE_DATA関数版)

[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)で、複数テーブルのデータを別テーブルに転記してみます。
TABLE_DATA関数を使うと項目の転記先を明確にできます。

# 概要

TABLE_DATA関数を使って、複数テーブルのデータを転記しソートを行います。
※テーブル1とテーブル2のデータをテーブル3に転記

TABLE_DATA関数は、計算式プラグイン Ver.85 以降で利用できます。

![2025-01-15_09h36_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/3634c8a5-1b2e-dc65-20a6-2f3270af062b.png)

※参考 [rex0220 計算式プラグイン 複数テーブルの転記](https://qiita.com/rex0220/items/6787eafd8f6c24ff37b4)

# TABLE_DATA 関数

コピー元のテーブルと項目、コピー先の項目を指定することで、処理を明確に指定できます。
また計算式を指定できますので、「数量T1*単価T1」などの金額計算も可能です。

- テーブル1 から テーブル3 への転記
    - TABLE_MAP(テーブル1,...)
        - TPDIC("日付T3",日付T1,...)
        - "金額T3",数量T1*単価T1
            - 計算式を指定できます
- テーブル2 から テーブル3 への転記
    - TABLE_MAP(テーブル2,...)
        - TPDIC("日付T3",日付T2,...)


```TABLE_DATA 関数使用例.js
  TABLE_DATA(
    TABLE_MAP(テーブル1,
      TPFILTER(日付T1),
      TPDIC(
        "日付T3",日付T1,
        "チェックボックスT3",チェックボックスT1,
        "ユーザー選択T3",ユーザー選択T1,
        "ドロップダウンT3",ドロップダウンT1,
        "数量T3",数量T1,
        "単価T3",単価T1,
        "金額T3",数量T1*単価T1
    )),
    TABLE_MAP(テーブル2,
      TPFILTER(日付T2),
      TPDIC(
        "日付T3",日付T2,
        "ドロップダウンT3",ドロップダウンT2,
        "数量T3",数量T2,
        "単価T3",単価T2,
        "金額T3",数量T2*単価T2
    ))
  )
```

# 計算式プラグイン設定

「循環参照を許可」をチェック

- TABLE_DATA関数で、テーブル1 とテーブル2 をまとめて、FSET で、テーブル3 にセット
- TABLE_SORT関数で、テーブル3 をソート


![2025-01-15_09h38_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/9549f43f-fac2-eabf-5e5a-5c0c493a5f83.png)

```.js
OPTION: 循環参照を許可

// テーブル3 日付・ドロップダウン集計:テーブル3 SUBTABLE
LET(
tdata1,
  TABLE_DATA(
    TABLE_MAP(テーブル1,
      TPFILTER(日付T1),
      TPDIC(
        "日付T3",日付T1,
        "チェックボックスT3",チェックボックスT1,
        "ユーザー選択T3",ユーザー選択T1,
        "ドロップダウンT3",ドロップダウンT1,
        "数量T3",数量T1,
        "単価T3",単価T1,
        "金額T3",数量T1*単価T1
    )),
    TABLE_MAP(テーブル2,
      TPFILTER(日付T2),
      TPDIC(
        "日付T3",日付T2,
        "ドロップダウンT3",ドロップダウンT2,
        "数量T3",数量T2,
        "単価T3",単価T2,
        "金額T3",数量T2*単価T2
    ))
  ),
  dmy,FSET(テーブル3,tdata1),
  tdata2,TABLE_SORT(テーブル3,
    TPSORT(日付T3)
  ),
  FSET(テーブル3,tdata2)
)

// テーブル3.日付T3 DATE
// テーブル3.ドロップダウンT3 DROP_DOWN
// テーブル3.ユーザー選択T3 USER_SELECT
// テーブル3.チェックボックスT3 CHECK_BOX
// テーブル3.数量T3 NUMBER
// テーブル3.単価T3 NUMBER
// テーブル3.金額T3 NUMBER
```
フローでエラー発生：すべての項目を自動的に保存を信じるな

## はじめに
またフローについてのお話です。

何回見ても間違いなく取得できているはずの項目なのに、タイトルの通り

> XXX の値が設定されていないか、割り当てられていないため、フローでこの値にアクセスできませんでした。

とエラーが発生しました。  

ネットで調べると出てくるのが

> Contact.Account.Nameを参照していたが、そもそもAccountがnullだったせいみたい！

のようなケースですが、今回はそういうわけでもなかったので解決策にはならず。


正しい対応かわかりませんが、とりあえず対処できたのでメモメモ。

## 前提
例として、フローのトリガーとなるオブジェクトは`取引先`。  
フローの処理の内容を

1. トリガーレコードに紐づく`取引先責任者`のうち、条件に一致するものを1件だけ取得
1. フロー内の数式にて1.の項目値を参照
1. トリガーレコードの値を、2.の数式で更新する

ような形でイメージしてください。

## エラーの特定
ちなみに、タイトルのエラーメッセージですが、画面上には表示されませんでした。  
画面上だと

> このフローで未対応の障害が発生しました。  
> フローを処理中に未対応の障害が発生しました。詳細は、組織のシステム管理者にお問い合わせください。

の表示でした。

具体的にどんなエラーが出てたのかは

1. 開発者コンソールを開く
1. 実際にエラーになるような更新処理を実行
1. 開発者コンソールの`Logs`に新しいログが出力されているので、それを開く
1. 下の方で実際のエラーメッセージが表示されているので、確認

という流れで見れます。

## 原因と対応方法
原因としてはメッセージの通り、対象の項目を取得できていないことのようでした。  

「レコードの取得」に設定されている`レコードデータの保存方法`を **「すべての項目を自動的に保存」** から **「項目を選択して後は Salesforce に任せる」** に変更し、**対象の項目を設定する**ことでエラーが出なくなります。

## 推測
おそらく、表記としては「すべての項目を自動的に保存」とありますが、実際には「**フローの内部で参照されている**すべての項目を自動的に保存」なんじゃないかなぁと思います。

そして、その検査時に数式の内部は見てないんじゃないかなと。

## おわりに
上記を踏まえると、数式内部で利用する項目に関しては一つ一つ取得のコンポーネントに設定が必要ということになります。

め、面倒くさい・・。
Quick Start: Agentforce > Connect Your Flows to Agentforce



https://trailhead.salesforce.com/it/content/learn/projects/quick-start-einstein-copilot/connect-your-flows-to-einstein-copilot


+ [トグルをクリックしてEinstein Copilot for Salesforce をオンにした後、手順 10 で提案されているページの下部に「Einstein Copilot」ボタンが見つかりません。](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000Kfj6U)

:::note
I just tried it out and everything worked seamlessly following the Trailhead instructions. I suggest setting up a new trail org and giving it another try, as you've already explored other options.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007aiywS
:::

# Connect Your Flows to Einstein Copilot

+ [Error with Agent Builder: Conversation Preview](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifplU)


:::note alert
Something went wrong. Refresh and try again.
:::

# その他

+ [エージェントビルダーについて知る](https://trailhead.salesforce.com/content/learn/modules/introduction-to-agent-builder/get-to-know-agent-builder?trail_id=become-an-agentblazer-champion)

+ トピックとアクション
+ 
Agentforce 入門バッジを獲得した場合は、トピックはアクションのカテゴリであり、トピックにはエージェントに何を行うか、どのアクションを呼び出すか、どのガードレール内で作業するかを指示する指示があることを学習しました。また、アクションはエージェントが実行する個々のタスクであることも学習しました。トピック、トピックの指示、およびアクションを追加、編集、または削除することは、エージェントをカスタマイズする最も効果的な方法の 1 つです。


**新しいエージェントを構築する**

+ タイプを選択:エージェントが業務を遂行するために必要なスキルに一致する、事前設定されたエージェント タイプを選択します。または、まったく新しいエージェントを最初から作成します。選択したエージェント タイプによって、エージェントが使用できるトピックとアクションが変わります。

+ トピックの確認:エージェントが実行できるジョブのカテゴリである定義済みトピックを追加または削除します。一部のトピックには定義済みアクションが含まれます。定義済みアクションは、注文の返品処理やアカウントの要約など、エージェントが実行できる個別のタスクまたはジョブです。アクションは、フロー、プロンプトビルダーテンプレート、または呼び出し可能な Apex を呼び出すことができます。


+ 設定の定義:エージェントに名前を付けて説明し、役割を定義し、会社についてエージェントに伝えます。エージェントが仕事を遂行するために必要な情報にアクセスするための権限を持つエージェント ユーザーを選択します。ユーザー設定で新しいエージェント ユーザーの権限を構成できます。また、会話データを使用してイベント ログを充実させ、エージェントのテストとトラブルシューティングに役立てることもできます。

+ データの選択:組織で Data Cloud が有効になっている場合は、ナレッジ記事などのデータや、エージェントが参照してよりパーソナライズされた応答を提供するためのその他の情報をアップロードすることを選択できます。ただし、多くの種類のエージェントはデータをまったく必要としません。

エージェントに関連付けられているトピックとアクションに影響を与えるものは何ですか?
エージェントタイプ
定型文

Application.ScreenUpdating = False '画面更新非表示
Application.Calculation = xlCalculationManual '数式計算停止
Application.Calculation = xlCalculationAutomatic '数式計算再開
Application.EnableEvents = False '自動実行マクロ停止
Application.EnableEvents = True '自動実行マクロ再開

Dummy = ActiveSheet.UsedRange.Row '終端セル誤認バグ修正
Dummy = ActiveSheet.UsedRange.Column '終端セル誤認バグ修正
r = Range("A1").SpecialCells(xlLastCell).Row '一番下の行
c = Range("A1").SpecialCells(xlLastCell).Column '一番右の列

Cells(1, 1).Interior.Color = RGB(255, 255, 0) 'セル背景色
Cells(1, 1).Interior.Color = xlNone '塗りつぶしなし
Cells(1, 1).Font.Color = RGB(255, 0, 0) '文字色塗り

Columns(1).AutoFit '1列目列幅自動調整
Range(Cells(14, 2), Cells(14, 5)).Columns.AutoFit 'セル列幅調整
Columns("A:E").AutoFit 'セル列幅自動調整
Cells.EntireColumn.AutoFit 'シート全体の列幅自動調整
Cells.EntireRow.AutoFit 'シート全体の行の高さを自動調整

Range("C3:E5").Borders.LineStyle = xlContinuous 'セル罫線
Rows(3).Borders(xlEdgeTop).LineStyle = xlContinuous 'セル罫線上のみ
Range("C3:E5").Borders.LineStyle = xlLineStyleNone '上下左右の罫線を消す
Cells.Borders.LineStyle = xlLineStyleNone ' シート全体の罫線を消す

Cells(1, 1).AutoFilter 'フィルター
Cells(1, 1).AutoFilter 2, "あ" ' 2列目を"あ"でフィルター
Activesheet.ShowAllData '絞り込みクリア
Cells(1, 1).Sort key1:=Cells(1, 3), order1:=xlAscending, Header:=xlYes '昇順
Cells(1, 1).Sort key1:=Cells(1, 3), order1:=xlDescending, Header:=xlYes '降順

Application.StatusBar =  "進行状況：" & i & "/" & r
Application.StatusBar = False
画面が固まる場合は一定カウント事にDoEventsを入れる。
  If i Mod 100 = 0 Then
    DoEvents
  End If

'フィルタ後の先頭セル
With ActiveSheet.AutoFilter.Range
  With .Resize(.Rows.Count - 1).Offset(1)
    MsgBox .Columns(1).SpecialCells(xlCellTypeVisible).Cells(1).Address
  End With
End With

クリップボードの参照設定
C:\Windows\System32\FM20.DLL」または「C:\Windows\SysWOW64\FM20.DLL」を参照

ClipBoard = Application.ClipboardFormats    
If ClipBoard(1) = -1 Then
  MsgBox "クリップボードは空です。", vbExclamation
  Exit Sub
End If

'クリップボードを取得
With New MSForms.DataObject
  .GetFromClipboard    '変数のデータをDataObjectに格納する
  MsgBox .GetText
End With
Application.CutCopyMode = False

'配列
Dim a() As Long
ReDim a(0)
・・・
i=i+1
ReDim Preserve a(i)

'二次元配列(こっちは少し遅い)
Dim tmp()
ReDim tmp(1 To r, 1 To c)

For i = 1 To r
  For j = 1 To c
    tmp(i, j) = Cells(i, j)
  Next
Next

Range(Cells(1, 1), Cells(r, c)) = tmp

'二次元配列セルへのアクセス1回(cells(1,1)から限定)
Dim arr As Variant
arr = Range(Cells(1, 1), Cells(r, c))

For i = 1 To r
  For j = 1 To c
    Debug.Print tmp(i, j)
  Next
Next

Erase arrData '配列初期化

Dim book1 As Workbook
Set book1 = Application.ActiveWorkbook '本エクセルをセット
Workbooks.Add '新規ブックを作成
Dim book2 As Workbook
Set book2 = Application.ActiveWorkbook '新規ブックをセット
book1.Worksheets(1).Cells(2, 6)
    
Worksheets.Add after:=Worksheets(Worksheets.Count)
Application.DisplayAlerts = False ' メッセージを非表示
Sheets(1).Delete
Application.DisplayAlerts = True  ' メッセージを表示
Nutanix AHVとは

みなさん、こんにちは！
VMwareライセンス形態変更に伴い、エンジニア視点でNutanix AHVについての紹介・検証・気付いた点などを順次発信していきたいと思います。

## VMwareのライセンス形態変更
その前に、VMware社の買収に伴いどのようにライセンス形態が変更されたかについて、まとめます。
*  **永久ライセンスからサブスクリプションへ変更**
*  **課金単位が物理CPUからCore数へ変更**
*  **OEMライセンス廃止に伴いサーバベンダーのHCI製品販売停止**
*  **既存の全パートナーとの契約打ち切り**

これにより、ライセンス費用、商流、保守体制の見直し等が発生し、運用コストが増加する可能性があります。

## VMwareの代替製品として今一番ホットなNutanix AHVとは
Nutanix AHVとは、NutanixによってビルドされたKVMベースのハイパーバイザーのことで、サーバ、ストレージ、ネットワーク機能を1つにまとめたHCI環境で構成されています。
最小構成は3台以上となり、Prismという管理アプライアンスにより一元管理することができます。

## VMwareとのシステム構成の比較
VMwareの3-Tier構成に対して、Nutanix AHVはHCI構成となります。
3-Tier構成の場合、サーバ、ストレージ、ネットワークとそれぞれ別々の機器が必要となり、運用や保守についても別々に対応が必要です。
それに対して、HCI構成の場合、サーバ、ストレージ、ネットワークが一つに集約されているため、大幅な運用コスト削減が見込まれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/b1335efa-977b-17c6-5415-36c7d3dafe33.png)

## VMwareとの機能比較
VMwareでの主要な機能は、以下のとおりほぼ遜色なく使用できます。
| VMware | Nutanix AHV |
|:-:|:-:|
| vMotion |  ライブマイグレーション|
| vSphere HA |  VMHA(VM High Availability)|
| vSphere DRS |  	ADS|
| アフィニティルール |  アフィニティルール|
|  スナップショット|  スナップショット|
|  クローン|  	クローン|
|  テンプレート|  AHVテンプレート|
|  vDS|  バーチャルスイッチ|
|  vCenter Server| Prism |

## Nutanix AHVの特長
特長について簡単に説明すると、以下のようになります。
基本的に操作はとても簡単で、ノード追加やファームアップなど数クリックで実施できます。
また、ハイパーバイザーだけではなく、NASサーバとしての機能もあります。
* **スケールアウトが簡単**
* **ノードの追加切り離しを数クリックでサービス無停止のまま可能**
* **サービス無停止のままハイパーバイザーや各HWベンダーのファームアップが可能**
* **Nutanix Moveという無償仮想アプライアンスによりダウンタイムを最小限に抑えた移行が可能**
* **Nutanix Centralによりオンプレミスやクラウドなどあらゆる環境の一元管理が可能**
* **Nutanix Files Storageによりファイルサーバ機能も提供**
* **スナップショットを利用したネイティブのバックアップやDR機能を提供**
* **データの可用性はノード(サーバ)に対して2重/3重で保管する**

## 最後に
簡単ですが、Nutanix AHVについて紹介させていただきました。
個人的には、このNutanix AHVだけで仮想化、NASサーバ、バックアップやDRなど、今までは複数の製品で行っていたことが、オールインワンで実現できることが最大の魅力でとても面白い製品だと思いました。
これにより、現場での運用管理も一元管理でき、運用負荷や運用コストの大幅な削減につながると思います。
また、ここでは紹介できませんでしたが、速度を上げるためのデータの保管方法や可用性(ノードのRAID化のイメージ)はとても良く考えられていると思います。
他にも、クラウドとの連携やDBやKubernetesなどなどあらゆる機能を有してます。

今後も、Nutanixの細かい機能、構築方法、他の環境からの移行方法等について紹介していきたいと思います。
Nutanixについてご質問等ありましたら、是非お問い合わせください！
JavaScriptでスライドショー

どうもこんにちはAtsu1209です。
今回はJavaScriptでスライドショーをつくる方法を書きます。

# JS
```js
//スライドショー        
const pics_src = ["img/one.png", "img/two.png", "img/three.png"];
let num = -1;
const indicators = [
  document.getElementById("spanone"),
  document.getElementById("spantwo"),
  document.getElementById("spanthree"),
];

function updateIndicators() {
  indicators.forEach((indicator, index) => {
    if (index === num) {
      indicator.style.color = "black";
    } else {
      indicator.style.color = "#808080";
    }
  });
}

function slideshow_timer() {
  if (num === 2) {
    num = 0;
  } else {
    num++;
  }
  document.getElementById("top-img").src = pics_src[num];
  updateIndicators();
}

indicators.forEach((indicator, index) => {
  indicator.addEventListener("click", function () {
    num = index;
    document.getElementById("top-img").src = pics_src[num];
    updateIndicators();
  });
});

setInterval(slideshow_timer, 6000);
```
・`spanone`,`spantwo`,`spanthree`は、スライドショーの下の丸いやつたち(インジケーター)
・`setInterval`で、表示秒数指定
・`if`で、`num`の最大値を指定

# 実装例

https://stedtech-org.github.io/home/

StedTechOrganizationのHPで実装しています。
Rspec - 標準出力の内容を正規表現で検証する例

# 例

```rb
expect { subject }.to output(/ここに正規表現/).to_stdout
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
［ServiceNow］UI Views（sys_ui_view）について

※この記事はServiceNow初心者が学習用のために記載した記事です。内容について誤っている場合がございます。不足点などございましたらコメントいただけますと幸いです。

ServiceNowのUI Views(sys_ui_view)テーブルは、ビュー（View） を管理するためのテーブルです。
ビューは、テーブルに関連付けられたフォームやリストの表示方法をカスタマイズするために使用されます。
これにより、同じテーブルでも、異なる状況やユーザーに応じて異なるデータの見え方を提供できます。

# Viewとは

View（ビュー）とは、ServiceNowでフォームやリストの見え方をカスタマイズする機能です。
ユーザーや目的に応じて、表示するフィールドやレイアウトを変更できます。

---

# sys_ui_viewの使用目的
ServiceNowでフォームやリストの異なるビュー（表示方法）を定義・管理する
これにより、ユーザーやシナリオに応じて最適なレイアウトや情報表示を提供できる





2. **ビューの使用例**:
   - 同じテーブルに対して、異なるユーザーグループが異なる情報を見たい場合。
   - 例:
     - ITサポートチーム用のビュー。
     - 管理者専用のビュー。
     - 特定のデータに特化したカスタムビュー。

3. **関連する構成**:
   - ビューを使用して特定のフォームデザインやリストカラムをカスタマイズできます。
   - `sys_ui_section`や`sys_ui_list`と連携して使用されます。

---

### 主なフィールド（sys_ui_viewの構造）
| フィールド名       | 説明                                                         |
|--------------------|------------------------------------------------------------|
| name        | ビューの名前（例: `Default`, `Mobile`, `Self Service`）     |
| sys_id       | ビューの一意識別子（ServiceNow内で自動生成される）        |
| description  | ビューの説明。何のためのビューかを記載できます              |
| active       | ビューが有効かどうかを示します（true または false）    |
| sys_created_by  | このビューを作成したユーザー                                       |
| sys_created_on  | ビューが作成された日時                                             |
| sys_updated_by  | このビューを最後に更新したユーザー                                 |
| sys_updated_on  | ビューが最後に更新された日時                                       |
| sys_mod_count   | レコードの更新回数


# ビューの適用方法
1. フォームビュー:
   - レコードフォームを開いたときに、設定されたビューが適用される
   - 例: インシデント（incident テーブル）のデフォルトビューと、カスタマイズされたモバイルビュー

2. リストビュー:
   - テーブルのレコード一覧に表示されるカラムやレイアウトに影響する
   - 例: 管理者用に詳細なカラムを表示するビュー

# ビューの切り替え方法
1. フォームまたはリストを開く。
2. URLに「?sysparm_view=<ビュー名>」を追加する
   - 例: incident_list.do?sysparm_view=Mobile  
3. これにより、指定したビューが適用される

# 関連するテーブルと依存関係
- sys_ui_section:
  フォームビュー内で、各セクション（タブなど）を定義する

- sys_ui_list:
  リストビューで表示されるカラムを定義する

- sys_dictionary:
  フォームやリストで使用されるフィールドの定義を保持する


# よくあるユースケース
1. モバイルビューの設定:
   - モバイルデバイスに最適化されたビューを作成し、簡略化されたフィールドやレイアウトを提供する

2. ユーザーグループ別カスタマイズ:
   - 特定のユーザーやグループ向けに、必要な情報だけが表示されるビューを作成

3. 特定業務用のビュー作成:
   - 例: ITサポートがインシデントを迅速に解決するためのビュー
WinUI 3 非パッケージの実行で躓いたので解決方法覚え書き

::: note info
WinUI 3を習得しようと思い立ったのですが、最初の実行で躓きました。
色々と調べたら解決できたので、忘れないように記録しておきます。
:::

## 非パッケージで実行しようと思った動機

正確にはパッケージされたプロジェクトは動作したのですが、非パッケージのプロジェクトはビルドエラーが発生し、実行できませんでした。

パッケージされたプロジェクトとは、ウィンドウズストアで配布する形式の実行ファイルができるプロジェクトみたいです。

このプロジェクトを開発するのには開発者モードを有効にする必要があり、しかもインストールされているアプリの一覧にこのプロジェクトが登録されてしまい、結構鬱陶しいです。

アプリの配布もストアだけでなく、自由に配布したいですし、非パッケージでの習得を目指すことにしたのです。

## 非パッケージのプロジェクト作成方法

まず最初にこちらも忘れないように記述しますが、非パッケージプロジェクトはプロジェクト作成時に以下のテンプレートを使用します。

![WinUI3-非パッケージプロジェクト作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976537/bd994f34-c7b4-7503-80c1-b2a250b1045c.png)


そしてプロジェクトをビルドする際は、**Package**とついていない方のプロジェクトでビルドします。

![WinUI3-ビルドするプロジェクト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976537/143489eb-6e85-b460-f193-59f2ed82cfb5.png)


## ビルドエラーの内容

このプロジェクトを実行すると以下のエラーが発生し、起動しませんでした。
![WinUI3-非パッケージ実行時エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976537/18c00cb9-a269-c550-deab-2af51df05ca2.png)

何をすれば解決できるのか全然わかりませんでしたが、検索を続けた結果、公式のマニュアルに解決方法が載っていました。

## 解消方法

やること自体の難易度は高くありませんでした。

最初に念のため[Windows App SDK](https://learn.microsoft.com/ja-jp/windows/apps/windows-app-sdk/downloads)と[Microsoft Visual C++ 再頒布可能パッケージ](https://learn.microsoft.com/ja-jp/cpp/windows/latest-supported-vc-redist?view=msvc-170)を更新しておきます。

次にプロジェクトの設定ファイルを修正します。
設定ファイルはソリューションエクスプローラーのプロジェクト名部分をダブルクリックすることで開きます。

以下の位置にタグ(`<WindowsPackageType>None</WindowsPackageType>`)を追加します。
```diff_xml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
    <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
    <RootNamespace>Test1</RootNamespace>
    <ApplicationManifest>app.manifest</ApplicationManifest>
    <Platforms>x86;x64;ARM64</Platforms>
    <RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
    <UseWinUI>true</UseWinUI>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <Manifest Include="$(ApplicationManifest)" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.1742" />
    <PackageReference Include="Microsoft.WindowsAppSDK" Version="1.6.241114003" />
  </ItemGroup>

    <!-- Publish Properties -->
  <PropertyGroup>
    <PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
    <PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
    <PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
    <PublishTrimmed Condition="'$(Configuration)' != 'Debug'">True</PublishTrimmed>
+	<WindowsPackageType>None</WindowsPackageType>
  </PropertyGroup>
</Project>
```

以上で無事ビルドが成功し、アプリが起動しました。

![WinUI3-ビルドが成功した結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3976537/2b17080e-e9b5-0a85-dfd5-5c9f32984fe6.png)
Google WorkspaceとMicrosoft 365でDMARC対応する

独自ドメインでメールサーバを運用する際、DMARC対応が必須な世の中になってきましたので、改めてDMARC対応のやり方をまとめておきます。昔は自力でsendmail / postfix などでメールサーバを運用していたこともありますが、今回はGoogle Workspace (Gmail)とMicrosoft 365 (Outlook)で独自ドメインなメールサーバのDMARC対応をする方法を書いています。
# DMARC対応の基本
DMARC対応するには、同時にSPFとDKIMも対応する必要があります。迷惑メール対策はSPF/DKIM/DMARCの3点セットで行うわけです。
## SPF対応
SPF (Sender Policy Framework)は、独自ドメインのメールを送信する正規メールサーバをDNSに登録することで、偽のメールサーバから送られる迷惑メールを判別する仕組みです。具体的には、ドメイン名（例：foo.bar）のTXTフィールドに、SPFレコードとして "v=spf1 include:spf.foo.bar ~all"のような値を追加します。
SPFレコードの書式の詳細は[SPF レコードについて](https://support.google.com/a/answer/10683907)をご参照ください。
## DKIM対応
DKIM (DomainKeys Identified Mail)は、個々のメールが正規なメールサーバから送られたものかどうかを、証明書を用いて検証する仕組みです。具体的には、メールサーバで生成した証明書（鍵ペア）のうち、公開鍵を特定のホスト名（例：zzz._domainkey.foo.bar）のTXTフィールドに、DKIMレコードとして"v=DKIM1;k=rsa;p=xxxxxxxxxxxxxxxxxx" （xxx..の部分が公開鍵）のような値を追加します。ホスト名のうち、zzzの部分は「セレクタ名」と呼ばれるもので、メールサーバ側で決められています。例えばGoogle Workspace (Gmail) では、google._domainkey.foo.bar のホスト名が使われます。
DKIMレコードは上述の通り、TXTフィールドに公開鍵を書くことがRFC 6376で決められていますが、TXTフィールドではなく、CNAMEフィールドに参照するホスト名を書くケースがあります。独自ドメインのDNSに公開鍵を直接書かないことで、メールサーバ側に閉じて鍵ペアの運用（定期的な更新など）ができるという利点があるからでしょう。例えばMicrosoft 365 (Outlook)では、selector1._domainkey.foo.bar のCNAMEに selector1-foo-bar._dmainkey.foo.bar という値（ホスト名）を書きます。
## DMARC対応
DMARC (Domain-based Message Authentication, Reporting, and Conformance)は、SPF / DKIM で認証に失敗したメールを、受信メールサーバ側でどのように取り扱ってほしいかをポリシーとして表明する仕組みです。例えば、認証に失敗した（多くは偽のメールサーバから送られた迷惑メール）に対して、受信サーバ側で「迷惑メール」として扱ってほしい場合は、「隔離（quarantine）」というポリシーを書きます。具体的には、ドメイン名の決められたホスト名（_dmarc.foo.bar）のTXTフィールドに、DMARCレコードとして "v=DMARC1; p=quarantine;rua=mailto:postmaster@foo.bar;pct=100;adkim=s;aspf=s"のような値を追加します。
# メールサーバ毎の設定方法
DMARCが普及しだした頃には、具体的な設定方法に関する情報が少なく、試行錯誤が必要でした。最近ではクラウドサービスでの設定に関するドキュメントが充実してきましたので、仕組みさえ分かればあまり間違えずに設定できるようになりました。
## Google Workspace (Gmail)での設定
Google Workspace での SPF / DKIM / DMARC の設定方法は、それぞれ次のドキュメントが用意されています。
* [SPF]  [SPFを設定する](https://support.google.com/a/answer/33786?hl=ja&ref_topic=9061731)
* [DKIM] [DKIMを設定する](https://support.google.com/a/answer/174124?hl=ja&ref_topic=9061731)
* [DMARC] [DMARCを設定する](https://support.google.com/a/answer/2466580?hl=ja)
## Microsoft 365 (Outlook)の設定
Microsoft 365 での SPF / DKIM / DMARC の設定方法は、それぞれ次のドキュメントが用意されています。
* [SPF] [Microsoft365ドメインの有効なメールソースを識別するようにSPFを設定する](https://learn.microsoft.com/ja-jp/defender-office-365/email-authentication-spf-configure)
* [DKIM] [Microsoft365ドメインからのメールに署名するようにDKIMを設定する](https://learn.microsoft.com/ja-jp/defender-office-365/email-authentication-dkim-configure)
* [DMARC] [Microsoft365でアクティブなカスタムドメインのDMARCを設定する](https://learn.microsoft.com/ja-jp/defender-office-365/email-authentication-dmarc-configure#set-up-dmarc-for-active-custom-domains-in-microsoft-365)
paizaラーニングレベルアップ問題集の「2つの文字列を出力」をやってみた。

paizaラーニングレベルアップ問題集の[2つの文字列を出力](https://paiza.jp/works/mondai/d_rank_level_up_problems/d_rank_level_up_problems__stdout_2)をやってみました。
- - -
###### 問題
https://paiza.jp/works/mondai/d_rank_level_up_problems/d_rank_level_up_problems__stdout_2
- - -
###### 方針
`paiza learning`を1つの文字列として出力する方法もありますが、今回は2つの文字列と半角空白を結合して出力したいと思います。（一部の言語を除く）
- - -
###### C
```c
#include <stdio.h>

int main() {
	puts("paiza learning");
	return 0;
}
```
- - -
###### C++
```cpp
#include <iostream>
using namespace std;

int main() {
	cout << "paiza" << ' ' << "learning" << endl;
	return 0;
}
```
- - -
###### C#
```cs
using System;

class Program
{
	public static void Main()
	{
		Console.WriteLine("paiza" + ' ' + "learning");
	}
}
```
- - -
###### Go
```go
package main
import "fmt"

func main() {
	fmt.Println("paiza" + " " + "learning")
}
```
- - -
###### Java
```java
public class Main {
	public static void main(String[] args) {
		System.out.println("paiza" + ' ' + "learning");
	}
}
```
- - -
###### JavaScript
```js
console.log("paiza" + ' ' + "learning");
```
- - -
###### Kotlin
```kotlin
fun main() {
	println("paiza" + ' ' + "learning")
}
```
- - -
###### PHP
```php
<?php
	echo "paiza". ' ' . "learning" . PHP_EOL;
?>
```
- - -
###### Perl
```pl
print "paiza" . ' ' . "learning" . $/;
```
- - -
###### Python3
```py
print("paiza", "learning")
```
- - -
###### Ruby
```rb
print "paiza" , ' ', "learning"
puts
```
- - -
###### Scala
```scala
object Main extends App{
	println("paiza" + ' ' + "learning")
}
```
- - -
###### Swift
```swift
print("paiza", "learning")
```
［ServiceNow］UI Actions（sys_ui_action）について

※この記事はServiceNow初心者が学習用のために記載した記事です。内容について誤っている場合がございます。不足点などございましたらコメントいただけますと幸いです。

ServiceNowのUI Actions（sys_ui_action）は、プラットフォーム内でユーザーインターフェース(UI)のアクションを定義するためのテーブルです。
このテーブルは、ボタン、リンク、コンテキストメニュー項目など、ユーザーが操作できるインターフェース要素を管理します。

# sys_ui_actionの使用目的
- ユーザーがインターフェースでボタンやリンクを操作したときに、その操作をトリガーにしてスクリプトを実行したい


# sys_ui_actionで定義できるアクション
1. ボタンやリンクの表示: レコードフォームにボタンやリンクを追加
2. アクションの実行: ボタンがクリックされたときに実行されるスクリプト（例: レコードの更新や、特定の処理を実行）
3. 条件の設定: アクションを表示する条件や実行する条件を設定
4. コンテキストメニューのカスタマイズ: レコード上で右クリックメニューをカスタマイズし、特定のアクションを追加

# sys_ui_actionのフィールド
- Name: アクションの名前（論理名）
- Table: アクションが関連するテーブル
- Action name: アクションの内部名（変更可能、物理名的な役割？）
- Condition: アクションが表示される条件
- Script: アクションが実行されたときに実行するスクリプト
- Order: アクションの表示順序
- active: UIアクションが有効かどうか（true または false）
- form_action: UIアクションがフォームに表示されるかどうか
- client: クライアント側スクリプトを使用するかどうか
- onclick: クライアント側でボタンをクリックした際に実行するスクリプト
- hint: UIアクションのツールチップや説明
- show_on_update: フォームが更新可能な場合にのみ表示されるかどうか
- show_on_insert: フォームが新規作成時にのみ表示されるかどうか

# Script Includeとの違い
- sys_ui_action
    - ユーザーインターフェース(UI)のアクションを定義するために使用
    - 具体的に、ボタンやリンク、コンテキストメニューをユーザーインターフェースに追加ユーザーがそれらをクリックした際に特定のスクリプトを実行
    - 再利用性は低く、アクションが定義された場所（フォームやテーブル）に限定されることが多い
- Script Include
    - 再利用可能なサーバースクリプトを定義するために使用
    - 主に、バックエンドでの処理（ビジネスロジック）を管理するために利用
    - 他のスクリプトから呼び出して使用することができる
    - サーバーサイドのスクリプトであり、特定の機能や処理を他のスクリプトやプロセスで繰り返し利用できるようにモジュール化するためのもの
API WSDL のまとめ




# ブランク画面

+ [Unable to load screen to download/generate wsdl file.](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KfqvR)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/aa32adb3-e10d-577a-708e-ba3d328a8f18.png)


# 生成できない

+ [Use SOAP API Unit - Error generating enterprise WSDL](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JfkHKSAZ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3d5529cc-8a8e-872c-39d9-a3f8136fe002.png)

+ [No Apex class named 'ParkService' was found. Ensure the class you generated from the WSDL is named 'ParkService'.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007PgPBA)
+ [Apex SOAP Callouts](https://qiita.com/Keiji_otsubo/items/dda21f5f435c64244834)
windowsでiverilog その183

# 概要　
windowsでiverilogやってみた。
練習問題やってみた。

# 練習問題
Dフリップフロップで4bitシフトレジスタを書け。

# 方針
2相差動クロックを採用する。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/bad6d550-cf96-87c9-51f2-080c8f13e0d8.png)

# サンプルコード

```

module dff(input D, input clk, input clk2, output reg Q);
	reg r;
	always@(posedge clk)
		r <= D;
	always@(posedge clk2)
		Q = r;
endmodule

module sr8(input _in, input clk, input clk2, output wire _out);
	wire q0,
		q1,
		q2,
		q3;
	assign _out = q3;
	dff u0(.D(_in), .clk(clk), .clk2(clk2), .Q(q0));
	dff u1(.D(q0), .clk(clk), .clk2(clk2), .Q(q1));
	dff u2(.D(q1), .clk(clk), .clk2(clk2), .Q(q2));
	dff u3(.D(q2), .clk(clk), .clk2(clk2), .Q(q3));
endmodule

module test;
	reg i,
		clk,
		clk2;
	output o;
	sr8 u(i, clk, clk2, o);
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
		$display("i clk o");
		$monitor("%b  %b  %b", i, clk, o);
		i <= 0;
		clk <= 0;
		clk2 <= 0;
		#11;
			i <= 1;
		#3;
			i <= 0;
		#30;
			$finish;
	end
	always
	begin
	#1;
		clk <= 1;
	#1;
		clk2 <= 1;
	#1;
		clk <= 0;
	#1;
		clk2 <= 0;
	end
endmodule








```

# 実行結果

```
>vvp a.out
VCD info: dumpfile test.vcd opened for output.
i clk o
0  0  x
0  1  x
0  0  x
0  1  x
0  0  x
0  1  x
1  0  x
1  1  x
0  1  0
0  0  0
0  1  0
0  0  0
0  1  0
0  0  0
0  1  0
0  1  1
0  0  1
0  1  1
0  1  0
0  0  0
0  1  0
0  0  0
0  1  0
0  0  0
0  1  0
0  0  0
dff7.v:44: $finish called at 44 (1s)

```

以上
windowsでiverilog その182

# 概要　
windowsでiverilogやってみた。
練習問題やってみた。

# 練習問題
Dフリップフロップで4bitシフトレジスタを書け。

# 方針
素子が多いので、dffを変更する。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ec09896d-0d8e-b5b5-8f27-315713338b14.png)


# サンプルコード

```

module dff(input D, clk, output reg Q);
	reg r;
	always@(posedge clk)
		r <= D;
	always@(negedge clk)
		Q = r;
endmodule

module sr8(input wire _in, input wire clk, output wire _out);
	wire q0,
		q1,
		q2,
		q3;
	assign _out = q3;
	dff u0(.D(_in), .clk(clk), .Q(q0));
	dff u1(.D(q0), .clk(clk), .Q(q1));
	dff u2(.D(q1), .clk(clk), .Q(q2));
	dff u3(.D(q2), .clk(clk), .Q(q3));
endmodule

module test;
	reg i,
		clk;
	output o;
	sr8 u(i, clk, o);
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
		$display("i clk o");
		$monitor("%b  %b  %b", i, clk, o);
		i = 0;
		clk = 0;
		#10;
			i = 1;
		#4;
			i = 0;
		#20;
			$finish;
	end
	always
	begin
	#2
		clk <= ~clk;
	end
endmodule








```

# 実行結果

```
>vvp a.out
VCD info: dumpfile test.vcd opened for output.
i clk o
0  0  x
0  1  x
0  0  x
0  1  x
0  0  x
1  1  x
1  0  x
0  1  x
0  0  0
0  1  0
0  0  0
0  1  0
0  0  1
0  1  1
0  0  0
0  1  0
0  0  0
dff6.v:42: $finish called at 34 (1s)
0  1  0
```

以上
【Rails】180万件のCSVを「postgres-copy」を使って、爆速でデータ移行をした話

# はじめに
マスタデータ180万件を移行したいという依頼がありました。
大量のデータをインポートするRuby on RailsのGemとしてactiverecord-importが有名ですが、100万とかなると実行に時間がかかりそうでした。
その際にpostgres-copyというGemで実行時間がかからず移行できたので、そのときの手順を記載します。

※S3はマスタデータファイルの保存先として使用します。初めはGitに含めてパッチを当てようとしましたが、Gitに大きいファイルを含めてしまうとリGitのパフォーマンスが低下して重くなってしまうため、Gitに含めずデータ移行をします。
# 前提
- Ruby on Rails
- PostgreSQL
- AWS S3

# postgres-copy、aws-sdk-s3の導入
Gemfileにpostgres-copy、aws-sdk-s3を追加します。
```ruby
gem 'postgres-copy'
gem 'aws-sdk-s3'
```
その後bundle installをします(Dockerを使っています)
```shell
docker-compose build
docker-compose up -d
```

# インポートするファイルを準備する
インポートするファイル(CSV)を用意します。
180万件入っているCSVファイルはそのままインポートできませんので、ファイルを分割します。
ファイルサイズが大きすぎますと後ほどS3からCSVファイルを読み取って登録する際に読み取る時間がかかりますので、ファイルサイズは調整をして下さい。

下記はsample.csvをsample-<連番>.csvに分割するコマンドです。
```shell
split -l 10000 -d -a 3 sample.csv sample-
```

上記コマンドで1万行にCSVファイルを分割することができました。
ただし、拡張子が付いていないので、拡張子をつけます。

https://www.lifehacker.jp/article/mac_finder_extension/

分割したファイルをS3に保存します。

# データ移行のパッチを作成する
rails cで実行するパッチのコマンドを用意します。
下記のようなコマンドでS3に保存したファイルを取得して、データを登録します。
```ruby
client = Aws::S3::Client.new(
  region: ENV['AWS_REGION'],
  access_key_id: ENV['AWS_ACCESS_KEY_ID'],
  secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
)
rows = []

(0..184).each do |i| # ここの184を分割したファイルの連番の一番大きい数に変更する。
  formatted_number = format("%03d", i)
  puts "処理中: #{formatted_number}"
  file = client.get_object(bucket: 'sample-import-bucket', key: "sample-#{formatted_number}.csv")
  csv = CSV.parse(file.body.read)
  csv.each do |row|
    rows <<  {
      id: row[0],
      title: row[1],
      body: row[2],
    }
  end
end

Benchmark.realtime do
  Post.insert_all!(rows)
end
```

# 実行結果
約4分ぐらいで実行することができました。
```ruby
Benchmark.realtime do
  Post.insert_all!(rows)
end
(省略)
=> 230.73561293902458
```

# 注意点
https://railsdoc.com/page/insert_all

### insert_allではなくinsert_all!を使いましょう
insert_allは重複データがあった場合に無視します。insert_all!の場合、レコードの重複があったら、ActiveRecord::RecordNotUniqueの例外がraiseされますので、なるべくinsert_all!を使いましょう。


### 不正なデータがないことを事前に確認する
insert_allの場合はRailsのvalidationを設定していてもスキップされます。
取り込む前に、データが正しいことを確認しましょう。
AOJ PG入門#1

## 問1："Hello World" と一行に出力してください（改行を忘れずに）

### PHP
```AO.php
<?PHP
echo "Hello World\n;"
?>
```
- echoの部分はprint()でもOK
- エスケープシーケンスは文字列の一部として扱う。
### Java
```ao.java
public class Main{
    public static void main(String[] args){
        System.out.println("Hello World");
    }
}
```

## 問2:１つの整数 x を読み込んで、x の３乗を計算し結果を出力するプログラムを作成して下さい。
### PHP
```ao.php
<?php  
	$x = (int)trim(fgets(STDIN));  
	echo $x*$x*$x;
?>
```
 
- STDINは標準入力（Standard Input）を指すPHPの定義済み定数。
- fgetsはファイルやストリームから1行を取得する関数。
標準入力からユーザーが入力した1行のデータを文字列として返す。
入力が終わると改行（\n）も含まれるため、余計な改行を削除する処理が必要。
- PHPにおける「trim関数」とは、文字列の先頭と末尾から余計な空白（半角スペースやTab）や改行を取り除くための関数。
- 文字列データ→数値データにするには(int)文字列でキャスト。キャスト以外にもintval(文字列)としてもOK

 ### Java
 ```AOJ.java
import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int input=sc.nextInt();
        System.out.println(input*input*input);
        sc.close();
    }
}
 ```
 - Scanner の使用が終わったら、リソースを解放するために close() メソッドを呼び出す

## 問3:たて a cm よこ b cm の長方形の面積と周の長さを求めるプログラムを作成して下さい。
面積と周の長さを１つの空白で区切って１行に出力して下さい。

### PHP
```AOJ.php
<?php
fscanf(STDIN, "%d %d", $a, $b);
$area=$a*$b;
$circum=2*($a+$b);
printf("%d %d\n", $area, $circum);
?>
```
- fscanf():PHPでファイルや標準入力から指定されたフォーマットに従ってデータを読み取るための関数
```example.php
fscanf(読み込むファイルやストリームのリソース,データの変換型,読み取り＆変換したデータを格納する変数)
```
- 読み込むリソース:標準入力を行う場合はSTDIN
- フォーマット指定子:intなら%d→その他string型なら%s,float型なら%f,char型（単一の文字）なら%c
- printfもフォーマットされた文字列を出力するための関数。
```example.php
printf(書式指定子を含む文字列,書式文字列内の書式指定子に対応する変数や値);
```
- printfでは、フォーマット文字列の中に直接空白を入れることができる。

### Java
```AOJ.java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();  
        int b = sc.nextInt();  
        
        
        int area = a * b;
        int circum = 2 * (a + b);
        
    
        System.out.println(area + " " + circum);
        
        
       sc.close();
    }
}

```

## 問4:秒単位の時間Sが与えられるので、ｈ：ｍ：ｓの形式へ変換して出力してください。
hは時間、mは 60未満の分、sは 60未満の秒とします。

### PHP
```AOJ.php
<?php
fscanf(STDIN,"%d",$s);

$h=floor($s/3600);
$m=floor(($s%3600)/60);
$sec=floor($s%60);

printf("%d:%d:%d\n", $h,$m,$sec);
?>
```

- 時間→$S / 3600は、与えられた秒数を1時間あたりの秒数で割ることで、何時間か求める。floor()関数を使って、小数点以下を切り捨てる。
例：3605秒の場合、3605 / 3600 = 1.000833なので、floor(1.000833)は1

- 分→$S % 3600は、与えられた秒数から「時間部分」を除いた残りの秒数を求める。それをさらに60で割ることで分を求める
例：3605秒の場合、3605 % 3600 = 5となり、5秒が残る。→5 / 60 = 0.0833→0分
- 秒→$S % 60は、与えられた秒数を60で割った余り、つまり60秒未満の残り秒数を求める
例：3605秒の場合、3605 % 60 = 5なので、残りの5秒が求まる

### Java
```AOJ.java
import java.util.Scanner;
public class Main{
    public static void main(String[]args){
      Scanner sc=new Scanner(System.in);
      int s=sc.nextInt();
      
      int h=s/3600;
      int m=(s%3600)/60;
      int sec=s%60;
      
      System.out.println(h+":"+m+":"+sec);
    }
}
```
Lua/Solにおけるコード注入テクニック

# コード注入

ここで言うコード注入とは、スクリプトファイルの冒頭などに処理系自身がコードを挿入し、ちょっとした機能を追加すること。

例えば.luaファイルそれぞれの冒頭に `local __MODULE__ = {ファイルパス}` というコードを挿入しておくと、`__MODULE__`という変数名で自身のファイルパスを取得できるようになる。
ファイル作成者が毎回ボイラープレートを書かなくて済むので便利。

応用例は以下のように、`require`関数を再定義して相対パスによるモジュール読み込みを可能にするなど。

```cpp
// ストレージからluaスクリプトを取得し、冒頭に「自身のファイルパス」を保持するコードを付加する。
std::string get_code_injected(const std::filesystem::path &file_path) {
    std::string code = /* ストレージからluaファイルを読み込む */
    std::string cwd = file_path.parent_path().string();

    std::string header =
        "local __CWD__ = '" + cwd + "';" +
        "local __original_require = require;"
        "local function require(module)"
        "    __CWD_global__ = __CWD__"
        "    return __original_require(module)"
        "end;";

    return header + code;
}

// package.searchersにも独自関数を追加し、その中で`__CWD_global__`を参照する。
// `__CWD_global__`からの相対パスでファイルを検索すればよい。
```


# 工夫

ここからは[Solライブラリ](https://github.com/ThePhD/sol2)（C++内でLuaの実行環境を簡単に作れる）を使用時の、具体的な注意点をまとめる。
（sol2 v3.3.0）

### 挿入コードはminifyして1行に圧縮する

Luaは改行文字を特別扱いすることはない。
あらゆるLuaのコードは改行を含まないように書き直すことができる。

```lua
local a = 9
print(a)
```

このコードは、実は以下のように書き直せる。

```lua
local a = 9 print(a)
-- または
local a = 9;print(a)
```

トークンが適切に区切れてさえいればいいらしい。セミコロンも使えるが、必須ではないのがC言語と違って面白いところだ。

さて、この事実を使うことで、挿入するコードを1行に圧縮することができる。

Solはスクリプトの実行中にエラーに当たると、エラーの発生行番号を表示してくれるのだが、コードを複数行挿入しているとその行番号が元々のファイル内容とズレてしまう。
このズレを防止するのが、挿入コードを1行に圧縮する意義である。


### `chunkname`引数の活用

`sol::state::script()`関数や`sol::state::load()`関数は、Luaコードを文字列として与えることでそれを実行してくれる。
しかしこのままだと、このコード自体には「ファイル名」などという概念が存在しないので、エラーが発生したときも何だかよく分からない表示が出てくる。
これに対処するために、第2引数`chunkname`として追加の「実質的なファイルパス」等の情報を教えておくことができる。これでエラー発生時に“ファイルパス”を表示してくれるようになる。

```lua
lua.script(code, "@scripts/hoge.lua")
```

この時さらに注意点として、**ファイルパスには先頭に「`@`」を付けておかないと**、またもや少しおかしな表示となってしまう。

| 何もしない | `chunkname`指定（@なし） | `chunkname`指定（@あり） |
|:-:|:-:|:-:|
| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3551504/09720ffc-b144-5834-7e36-ea60b4976fa1.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3551504/9120999e-6575-22df-7c21-1425e8ea3d42.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3551504/8948dd17-e286-b797-0762-b99b270a0555.png) |
| ファイル名は存在しないので、コード内容がそのまま表示されている。 | `[string "パス"]`のような表示になってしまう。 | ファイルパスと行番号が綺麗に表示される。 |


# まとめ

- Lua実行環境自身がスクリプト冒頭などにコードを挿入しておくことで、様々な機能追加が可能
- 挿入コードはminifyして１行にしておくことで、エラー行通知と実際のファイル行の齟齬を無くせる
- Solの`chunkname`引数にファイルパスを与えるときは、先頭に「`@`」を追加すべし

コード注入自体、些かハッキーなテクニックであるかもしれないが、こうした書き方にも耐えうる拡張性を持っていることがLua言語の強みでもある。

この記事を書くきっかけの話。当初はエラー行がズレてしまう現象に悩まされていたのだが、挿入コードを無理矢理1行に圧縮できることに気付いて目が覚めたような気持ちになった。
2025/1/15主にITとかセキュリティの記事

Googleが警鐘を鳴らすトロイの木馬化VPNアプリの脅威と新手法(1/13)
https://reinforz.co.jp/bizmedia/66785/

日本の「巨人」が相次いでハッカー攻撃を受け、重大事件が多発(1/12)
https://www.vietnam.vn/ja/mot-loat-dai-gia-nhat-ban-bi-tin-tac-tan-cong-gay-nhieu-su-co-nghiem-trong/

警戒する!あなたが知らなければならない電報上の10の詐欺(1/12)
https://voi.id/ja/teknologi/450493

iMessageのフィッシング攻撃が急増 仕組みを無効化する新手法(1/13)
https://reinforz.co.jp/bizmedia/66743/

中国の脅威グループが日本にサイバー攻撃、警察庁が注意喚起(1/13)
https://news.livedoor.com/article/detail/27934671/

Meta、2025年にAIで中級エンジニアの代替を目指す ―― Zuckerberg CEOが展望を語る(1/13)
https://xenospectrum.com/meta-aims-to-replace-intermediate-engineers-with-ai-by-2025/

米国 国家安全保障局 商用国家安全保障アルゴリズム・スイート2.0および量子コンピューティングに関するFAQ更新 (2024.12.31)(1/13)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2025/01/post-0fd534.html

米規制当局、ハッキング発生時の暗号資産ウォレットプロバイダーの責任を強化する規則を提案(1/12)
https://crypto-times.jp/news-us-regulators-propose-rules-to-strengthen-liability-for-crypto-wallet-providers-in-case-of-hacks/

＜主張＞中国系ハッカー　能動サイバー防御を急げ(1/13)
https://www.sankei.com/article/20250113-N5I2PWDH75L4LOLR5HYIZOGG54/

米司法省、仮想通貨ミキサー運営者をマネロン等で起訴｜北朝鮮関連組織が使用か(1/13)
https://bittimes.net/news/190022.html

「フィッシング」昨年最多 報告件数　文面作成にAI悪用か(1/13)
https://www.nikkei.com/article/DGKKZO86021070S5A110C2CM0000/

委託元企業も監督を　労務管理システム利用で　個人情報保護委(1/13)
https://www.rodo.co.jp/news/189688/

Firefox（ファイアフォックス）、ブラウザーストアで偽OKXプラグインが見つかる=ユーザーに警告(1/13)
https://nextmoney.jp/?p=70766

「パスキー」とは何か？--パスワード不要でセキュリティにも優れた認証技術(1/13)
https://news.yahoo.co.jp/articles/4364e5b4d05d81e467032007271038ea9fbf2bbf?source=rss

Windows 10サポート終了で高まるセキュリティリスクと互換性問題(1/13)
https://reinforz.co.jp/bizmedia/66780/

米、サイバーセキュリティー強化へ近く大統領令　中国脅威に対応(1/13)
https://jp.reuters.com/economy/industry/SLYBEESYVROQJEXFJ3J7ASVPJY-2025-01-13/

中国からのハッキングの脅威に直面して、ジョー・バイデンはより厳しいサイバーセキュリティ基準を命じました(1/12)
https://voi.id/ja/teknologi/450472

英国、国家主導でOpenAIに匹敵するAI企業育成を目指す—計算インフラ20倍増強で描く主権的AI開発の未来図(1/13)
https://xenospectrum.com/u-k-aims-to-nurture-ai-companies-to-rival-openai-as-a-national-leader/

生成AIとは? 技術の基本、活用事例からリスクまで解説(1/13)
https://news.mynavi.jp/techplus/article/ai_generative-5Ic1UfgY/

AI創薬の現状とは？　AI導入で期待される3つの効果や課題と活用事例を紹介(1/13)
https://zuuonline.com/archives/294767

Japan, U.S., Philippine Leaders Commit to Continuing Security Cooperation(1/13)
https://sp.m.jiji.com/english/show/37720

欧州連合 欧州経済・社会委員会 (EESC) プロワーカーAI：雇用・労働市場政策に関連するAIの可能性を活用し、リスクを緩和するための手段 (2024.01.09)(1/13)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2025/01/post-f5f084.html

Googleの自動運転タクシーに不具合！駐車場を周り続け、乗客「ドッキリかと」(1/13)
https://jidounten-lab.com/u_51936

AI信じて死にそうだった…Google自律走行タクシー(1/12)
https://newautopost.co.kr/ja/issue-plus/article/147860/

KAIは、顔認識を利用する1,030万人の乗客を記録しています(1/12)
https://voi.id/ja/news/450504

貴方のスマホやペットカメラが銀行等へのDDoS攻撃に加担しているかも？(1/13)
https://news.yahoo.co.jp/expert/articles/11bc92c1fd580efd3ab6cddefa97a7bee3aec2e4
【Unity】waifu2x の導入手順

# 背景
waifu2x はアニメ調の画像の縦横サイズを綺麗に2倍にできるAIアルゴリズムです。
既存の Unity プロジェクトに導入する手順を説明する記事が無さそうなので書きました。

# 導入手順
下記の Github リポジトリの```Code > Download ZIP```からパッケージをDLして展開します。

https://github.com/keijiro/Waifu2xBarracuda

```waifu2x > Packages > jp.keijiro.waifu2x```を導入したいプロジェクトの```Packages```に配置します。

これで導入完了です。
上記のリポジトリのように、Package 化されているものの PackageManager で扱えず unitypackage が配布されていないケースでも、上記の手順で利用できる場合があるので似た形式のリポジトリに遭遇した際は試してみてください。

# 動作確認方法

Waifu2xBarracuda-main フォルダ内の```Assets/Test.unity```と```Assets/Test```をプロジェクトに入れ、Test.sceneを開いてプレイモードを実行すると、waifu2x の高解像度化を確認できます。
※上手く機能しない際は Editor を再起動してみてください

# 使用例

当然 Test フォルダを入れなくても、下記のようなコードで機能します。

``` Waifu2xSample.cs
using UnityEngine;
using UnityEngine.UI;

public class Waifu2xSample : MonoBehaviour
{
    [SerializeField] Texture2D _source = null;
    [SerializeField] ResourceSet _resources = null;
    [SerializeField] RawImage _uiScaled = null;

    private void Start()
    {
        Waifu2xScaler scaler = new Waifu2xScaler(_resources);
        _uiScaled.texture = scaler.CreateScaledTexture(_source);
    }
}
```

# 補足情報
[Android や iOS、WebGL でも動作するようです。](https://docs.unity3d.com/Packages/com.unity.ml-agents@2.0/manual/index.html)
Waifu2xBarracuda と学習モデルのビルド後のファイルサイズは Windows ビルドの場合、Waifu2xBarracuda のインポートで約5.9MB、学習モデル1つにつき約1.8MBになるようです（合計約7.7MB）。
部分グラフの同型性の判定プログラムでChatGPTにはめられた話

# ChatGPTを信じすぎていた
あるグラフGに対して、部分グラフSを用意し、この部分グラフと同型な部分グラフがGに含まれているかを判定するプログラムを書きたかったのだが、なにはともあれChatGPT先生は優秀なので、もちろん投げた。
その結果が以下である。
```python
import networkx as nx
from networkx.algorithms.isomorphism import GraphMatcher

# メイングラフ G
G = nx.Graph()
G.add_edges_from([(0, 1), (1, 2), (2, 3), (3, 0), (0, 2)])

# サブグラフ S
S = nx.Graph()
S.add_edges_from([(0, 1), (1, 2), (2, 0)])

# GraphMatcher の使用
GM = GraphMatcher(G, S)

# 同型性の確認
if GM.subgraph_is_isomorphic():
    print("同型部分グラフが存在します。")

# 同型部分のノードマッピングを取得
isomorphisms = list(GM.isomorphisms_iter())
print("ノードマッピング:", isomorphisms)
```

ここで一つ問題が起きた。同型な部分グラフが存在するというのはちゃんと返ってくるのだが、ノードのマッピングがすべて空の状態であった。
なんで、同型な部分グラフは存在するのにマッピングが返ってこないねん！！ってことで、ChatGPTに何度も訪ねたがかえってきたのは、ノードやエッジに属性が指定されているとなんかおかしなことになるねんだとか、サブグラフはちゃんとしてますか？表示プログラム書いてあげますよ？とかの回答ばかりだった。

# 解決への道
そんなこんなで、悪戦苦闘すること2時間。
いろんなグラフをいれてみたときに、たまにマッピングが表示されることに気が付いた。そして、よく考えてみると、まったく同じ頂点数、辺の数の場合にマッピングが返ってきていることに気が付いた！
もしかして、部分グラフの同型性のマッピングじゃなくて、同型性のマッピングになってないか？と思った。なぜなら、```GM.subgraph_is_isomorphic()```はsubgraphとついているのに対して, ```GM.isomorphism_iter()```はsubgraphがついていない。
これは来たかも！っと思って、ChatGPTに尋ねたけど、同じ解答ばかり。そこで、仕方ないので、公式ドキュメントにいった。
そこの関数一覧を調べると、なんと！！
```GM.subgraph_isomophism_iter()```という関数があるではないですか！！
はい、ということで、あるグラフGに対する部分グラフSのマッピングを表示したい場合は、```GM.isomorphism_iter()```ではなく、```GM.subgraph_is_isomorphic()```を使いましょうということです。
そして、ChatGPTを信じすぎてしまったことで2時間も費やしてしまった自分に反省していますが、やっぱりChatGPTを信じたいという気持ちはあります。
はい、これからは気を付けたいと思います。
【Unity】AddressablesのDownloadStatusで「Exception: Attempting to use an invalid operation handle」が発生する原因

## 該当コード

`Addressables.DownloadDependenciesAsync`のロード進捗率を取得しようとしたらタイトルのエラーが出ました。

```
public async void Load() {
    AsyncOperationHandle downloadHandle;
    IList<IResourceLocation> locations = await Addressables.LoadResourceLocationsAsync("hoge");
    var locationGroups = locations.GroupBy(_ => _.DependencyHashCode);
    foreach(IGrouping<int, IResourceLocation> group in locationGroups) {
        downloadHandle = Addressables.DownloadDependenciesAsync(group.ToList(), true);
        while(downloadHandle.Status == AsyncOperationStatus.None) {
            var percentage = downloadHandle.GetDownloadStatus().Percent;
            Debug.Log(percentage);
        }
        Addressables.Release(downloadHandle);
    }
}
```

## 原因
上記コードの場合、**`DownloadDependenciesAsync`の第二引数（`autoReleaseHandle`）をtrueにして自動的に開放してしまっている**ため、ダウンロードの完了と同時に`AsyncOperationHandle`がnullになってしまう事が原因です。

単純に`downloadHandle.Status`の評価が出来ないことによりエラーが発生しています。

```
downloadHandle = Addressables.DownloadDependenciesAsync(group.ToList());
```
`autoReleaseHandle`を無効化すればエラーが解消されます。


## 終わりに
`autoReleaseHandle`を有効にしてダウンロード、かつDownloadStatusを監視していたため発生したエラーでした。

デフォルト値がfalseなので同じ症状が発生する人は少なそうですが、
意外と見落としがちなので同じ症状に困っている人に届けば幸いです。
Pleasanterで特権ユーザーを設定する手順

## **1. 特権ユーザーとは**
特権ユーザーは、Pleasanterのシステム設定やログ管理などの管理者機能にアクセスできるユーザーです。この権限を設定することで、以下のような操作が可能になります：
- システムログの確認と取得
- データベース設定の管理
- セキュリティパラメータの変更

## **2. 必要条件**
特権ユーザーを設定するには、以下の条件を満たしている必要があります：
- **管理者権限を持つアカウント**が存在すること。
- **Pleasanterサーバーにアクセス可能**であること（IIS経由など）。
- **システム設定ファイル（`Security.json`）を編集する権限**を持っていること。

## **3. 設定手順**

### **手順1: `Security.json` ファイルの編集**
1. **サーバーにログイン**
   - Pleasanterがインストールされているサーバーにログインします。

2. **設定ファイルの場所を確認**
   - `Security.json` ファイルのパスは以下の通り：
     ```
     App_Data/Parameters/Security.json
     ```

3. **ファイルを編集**
   - 以下のように、「`PrivilegedUsers`」パラメータを編集します：
     ```json
     {
         "PrivilegedUsers": [
             "example_user1", 
             "example_user2"
         ]
     }
     ```
   - ここで、`example_user1` などは特権ユーザーとして指定するログインIDです。

4. **ファイルを保存**


### **手順2: IISを再起動**
編集内容を反映させるために、IISを再起動します。

1. **コマンドプロンプトを開く**（管理者として実行）
2. 以下のコマンドを実行：
   ```
   iisreset
   ```
3. サーバーが再起動されます。

### **手順3: 特権ユーザーとしてログイン**
1. **Pleasanterにログイン**
   - `Security.json` で設定したログインIDを使用してログインします。
2. **「管理者メニュー」が表示されることを確認**
   - トップページの右上に「管理者メニュー」が表示されていれば、特権ユーザー設定は成功です。


## **4. 特権ユーザーの利用例**
### **1. システムログの確認**
- 管理者メニューから「ログ管理」を選択して、システムログを確認・エクスポートできます。
- 詳細な操作手順は公式ドキュメントを参照してください。

### **2. セキュリティパラメータの変更**
- 必要に応じて、セキュリティ設定（例: パスワードポリシーなど）を変更可能。

## **5. 注意点**
1. **バックアップを取得する**
   - `Security.json` の編集前に、必ずバックアップを取得してください。
2. **誤った設定に注意**
   - 無効なログインIDやJSON構文エラーがあると、Pleasanterが正常に動作しなくなる場合があります。
Ruby 3.4 にアップデートしたときのエラー対応（標準添付ライブラリの bundled gem 対応）

# 対応内容

定期スクリプトで Ruby 3.3 から Ruby 3.4 にアップデートしたら以下のエラーが出て失敗した。

```
'Kernel.require': cannot load such file -- csv
```

csv は Ruby の標準添付ライブラリの中の bundled gem です。

Ruby 3.4 からは bundler を利用している場合、bundled gem は Gemfile に記述する必要がある。

Gemfile に以下を追加したら、エラーが解消した。

```ruby
gem 'csv'
```

bundled gem は Ruby のインストール時同梱しているため、通常追加でインストールにはならない。個別でアップデートやアンインストールはできる。

# 参考ドキュメント

## Ruby Standard Library

https://docs.ruby-lang.org/en/3.4/standard_library_md.html

標準添付ライブラリの中の Default gems と Bundled gems についての説明がある。今回の csv は Bundled gems に含まれる。

gem がどちらに分類されているかはこちらのドキュメントを参照できる。

### Default gems

> - Default gems are shipped with Ruby releases and also available as rubygems.
> - Default gems are not uninstallable from the Ruby installation.
> - Default gems can be updated using rubygems.
> - Default gems can be used with bundler environments like unbundled_env.
> - Default gems can be used at any version in a Gemfile.

Rubyのリリースに同梱されており、rubygemsとしても利用できる。
アンインストールできない。

### Bundled gems

> Bundled gems are shipped with Ruby releases and also available as rubygems.
> - They are only bundled with Ruby releases.
> - They can be uninstalled from the Ruby installation.
> - They need to be declared in a Gemfile when used with bundler.

Rubyのリリースに同梱されており、rubygemsとしても利用できる。
アンインストールできる。

bundler で使用する場合は、Gemfile で宣言する必要がある。

## Ruby 用語集

https://docs.ruby-lang.org/ja/3.4/doc/glossary.html

### default gem

> 標準添付ライブラリーの gem のうち、アンインストールできないもの。

### bundled gem

> 標準添付ライブラリーの gem のうち、アンインストールできるもの。

こちらには bundler での宣言の必要について記載されていないように見えた。

### 標準添付ライブラリー

> Ruby 本体と一緒に配布される、組込みではないライブラリー。
インストールせずに使うことができる。
gem 形式になっているものとなっていないものがあるが、なっているものは standard gem と呼ばれ、Ruby 本体のバージョンとは独立してアップデートすることができる。 standard gem はさらに、アンインストールのできない default gem とアンインストールできる bundled gem に分けられる。
生成AIで痛んだお財布にやさしいAIエージェント - Recline - のインストール検証手順

# はじめに
Cursor, Github Copilot, Azure OpenAIなど流行のLLMを使っていると、なんだかんだお財布が痛んできます。
それを解消するために、Github Copilotで使えるAIエージェント「Recline」をインストールしてみました。
まだVSCode Marketplaceでは公開されていないので、手動でビルド、インストールします。
※参考記載の記事に触発され、後追いですがQiita化しました。

# 前提
- Mac Book Air M1 2020
- MacOS Sequoia 15.2
- VSCode
- zsh

# インストール
1. git clone https://github.com/julesmons/recline.git でリポジトリをクローン
   ![1_git-clone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/1f3a432b-4be8-d7d1-aca2-9eb56b31927c.png)

2. cd ./recline  でリポジトリに移動
3. pnpm, @vscode/vsceをグローバルインストール
      - pnpm install -g pnpm
      - pnpm install -g @vscode/vsce
  ![3_library_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/7323b35e-7acd-fb98-16e9-fcbd441e832a.png)

4. pnpm install で依存関係のインストール
  ![4_pnpm-install-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/4aca82ae-0505-ab32-b282-d5d93f642a8b.png)

      ![4_pnpm-install-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/62ba19e3-748d-0cec-46ca-484034217acd.png)

5. pnpm run package でVSIXにパッケージング
   ![5_vsix-package-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/83a7df85-2b79-1b1c-2596-2f317b1615da.png)

   ![5_vsix-package-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/6c44bd07-8250-7beb-dfd3-9f0dad2b00c2.png)

6. パッケージングされたVSIXファイルをVSCodeにインストール
   - code --install-extension ./recline-0.2.2.vsix
   ![6_vscode-install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/d3535e23-2731-57d3-72f4-314fab71a0c5.png)

7. インストール完了
   - 左端にReclineのアイコンが表示される
   ![7_recline-icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/7cf1a930-9bf4-ec78-e7ac-e64e0d759f8d.png)

8. Github Copilotが有効化されている状態で、Reclineのアイコンをクリックすると、初期設定が表示されるため、設定を行う

   ![8_recline-setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/e62f5d0a-c9f4-37a5-25bf-ef8bdee7aa73.png)
   ![8_recline-setting-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/af0da0a3-5084-d305-121a-e2f3dc5a70fb.png)



9. Reclineに初めてタスクを依頼すると以下の許可を求められるので許可する
   ![9_recline-allow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/3a1845db-7a42-07c2-8de9-53337e12de70.png)


# おわりに(※本セクションは導入したReclineで書いてもらいました)

Reclineは、Github Copilotと連携して動作する無料のAIエージェントです。手動でのインストールは少し手間がかかりますが、一度設定してしまえば、Github Copilotの機能を無料で活用できる優れたツールです。

インストール手順は複数のステップがありますが、本記事の手順に従えば問題なく導入できるはずです。特にVSCode Marketplaceで公開されていない現状では、この手動インストールが唯一の導入方法となります。

今後のアップデートでより使いやすくなることや、Marketplace公開による導入の簡易化も期待できます。コスト面で悩んでいる方は、ぜひReclineを試してみてください。

# 追記
- ファイル等の閲覧のためにfdやripgrepをインストールして、それぞれfd, rgコマンドにパスを通しておく
- 上記対応してもaddFolerはNo Result Foundが表示されるが、@フォルダ名で指定するとうまく動く
- 日本語対応用のため以下PR参考にして、src/extension/utils/sanitize.tsを修正した後、pnpm run packageでパッケージングする
  - https://github.com/julesmons/recline/pull/1

# 参考

https://shinshin86.hateblo.jp/entry/2025/01/12/195754

https://sitochablog.pages.dev/posts/recline/
Lubuntu 24.04 初期設定

Lubuntu 24.04 を使い始めたので初期設定について備忘録を残す。
サーバー用途ではなく、作業用ワークステーションとして整備することを目標とする。

# 日本語入力の有効化

```bash
sudo apt-get install fcitx-mozc --install-recommends -y
```

# xdg-user-dirs-gtk の導入

```bash
sudo apt-get install xdg-user-dirs-gtk
# home 配下のディレクトリ群を英語化する
LANG=C xdg-user-dirs-gtk-update
```

# UFW の有効化

```bash
# 一切の受信を拒絶する
sudo ufw defalut DENY
# HTTP の受信を許可する
sudo ufw allow 80
# HTTPS の受信を許可する
sudo ufw allow 443
# UFW を有効化する
sudo ufw enable
```

# ClamAV の導入
## インストール

```bash
sudo apt-get install clamav clamav-daemon clamtk
# ウィルス定義の更新
sudo systemctl stop clamav-freshclam
sudo freshclam
sudo systemctl start clamav-freshclam
```

## 設定ファイルの修正

```perl:/usr/bin/clamtk
# ウィルス駆除を有効化する。そのままだとマルチバイト文字の扱いに失敗して駆除できないらしい
# setlocale( LC_ALL, '' );
setlocale( LC_ALL, 'C' );
```

```perl:/usr/share/perl5/ClamTk/Scan.pm
# メールのスキャンを有効化する
# $directive .= ' --scan-mail=no';
$directive .= ' --scan-mail=yes';
```

## GUI 上の設定変更

1. ClamTk を起動する。
2. Configuration > Settings
    1. ``Scan for PUAs`` を除く全項目にチェックを入れる。
3. Updates > Update Assistant
    1. ``I would like to update signatures myself`` にチェックを入れる。
4. Configuration > Scheduler
    1. スキャン実行時刻とウィルス定義の更新時刻を指定する。

# Remote Desktop Client の導入
## インストール

```bash
sudo apt-get install nscd remmina
```

## 接続の設定

* プロトコル: RDP
* 基本設定
    * サーバー: ``接続先のコンピュータ名.local``
    * 解像度: ``クライアントの解像度を使う`` にチェックを入れる。
* 高度な設定
    * Audio output mode: 接続先サーバーマシンから音を出したい場合は ``ローカル``
      接続元クライアントマシンから音を出したい場合は ``リモート`` を選択する。

# Xsane の導入

```bash
# スキャナの Linux 向けドライバが提供されていなかった為、導入
sudo apt-get install sane xsane
```
24/1/14 読書記録 ~土台からしっかり学ぶソフトウェアテストのセオリー~

# 書籍
[土台からしっかり学ぶソフトウェアテストのセオリー](https://amzn.asia/d/hvYdYEd)

# 第9章 テスト計画のセオリー


## Chap9. 感想 

全て読み終えたが組織内で活かすイメージが湧かなかった。
アジャイル開発をとっていることもあり、ガチガチテスト設計することに工数をかけてもなぁ。となっている。