OmniAICreator/Qiita-1.07M huggingface dataset:
samba addc レプリケーション設定方法

Samba Active Directory Domain Controller（Samba AD DC）のレプリケーションを設定するには、複数のドメインコントローラー間でデータを同期する必要があります。以下は、Samba AD DCのレプリケーションを設定する基本的な手順です：

**前提条件**:
- プライマリー（マスター）とセカンダリー（スレーブ）のSamba AD DCが正常に構成されている必要があります。
- レプリケーションパートナーシップを確立する前に、ドメインコントローラー間の通信が正しく機能していることを確認してください。

**レプリケーションの設定手順**:

1. **レプリケーションの確立**:
   プライマリーSamba AD DCからセカンダリーSamba AD DCへのレプリケーションパートナーシップを確立します。このステップには、`samba-tool drs replicate`コマンドを使用します。以下は、コマンドの例です：

   ```shell
   sudo samba-tool drs replicate PRIMARY-DC SECONDARY-DC EXAMPLE.LOCAL
   ```

   - `PRIMARY-DC`と`SECONDARY-DC`をそれぞれプライマリーとセカンダリーのSamba AD DCのホスト名に置き換えてください。
   - `EXAMPLE.LOCAL`をあなたのドメイン名に置き換えてください。

2. **レプリケーションの確認**:
   レプリケーションが正常に設定されたかどうかを確認します。次のコマンドを使用して、ドメインコントローラー間のレプリケーション状態を表示します：

   ```shell
   sudo samba-tool drs showrepl
   ```

   このコマンドにより、各ドメインコントローラーのレプリケーションステータスが表示されます。すべてのステータスが成功していることを確認してください。

3. **レプリケーションの監視**:
   レプリケーションを監視し、問題が発生した場合に適切に対処できるように、適切なモニタリングとログの設定を行います。Samba AD DCは、問題が発生した場合にアラートを送信するためのメカニズムを提供しています。

4. **ドメインコントローラーの保守**:
   レプリケーションを保つために、ドメインコントローラーの正常性とアップデートを確保するための適切な保守作業を定期的に実行します。

これにより、Samba AD DCのドメインコントローラー間でのレプリケーションが設定されます。レプリケーションは、データの同期を確保し、高可用性を提供するために重要です。設定やトラブルシューティングには深い知識が必要な場合があるため、適切なドキュメンテーションやリファレンスを参照することが重要です。


Samba Active Directory Domain Controller（Samba AD DC）のレプリケーションは、通常、プライマリー（マスター）Samba AD DCからセカンダリー（スレーブ）Samba AD DCに対して設定されます。プライマリーSamba AD DCからセカンダリーSamba AD DCにデータを複製することで、冗長性を提供し、高可用性のドメイン環境を構築します。

したがって、レプリケーションの確立設定は、プライマリーSamba AD DCで実行する必要があります。プライマリーSamba AD DCからセカンダリーSamba AD DCへのデータ複製は、プライマリーSamba AD DCがソース（提供元）であり、セカンダリーSamba AD DCがターゲット（受信側）です。

具体的な手順は、前回に示されていますが、プライマリーSamba AD DCのコマンドでレプリケーションを確立します。以下は再度、コマンドの例です：

```shell
sudo samba-tool drs replicate PRIMARY-DC SECONDARY-DC EXAMPLE.LOCAL
```

- `PRIMARY-DC`はプライマリーSamba AD DCのホスト名またはIPアドレスです。
- `SECONDARY-DC`はセカンダリーSamba AD DCのホスト名またはIPアドレスです。
- `EXAMPLE.LOCAL`はあなたのドメイン名に置き換えてください。

要するに、プライマリーSamba AD DCがセカンダリーSamba AD DCにデータを複製するためのコマンドを実行します。このコマンドにより、レプリケーションが確立され、セカンダリーSamba AD DCがプライマリーSamba AD DCの変更を同期します。
Excel VBA ロビカスと32bit日時型数列オーバーフローは救いがたい

# ロビカス
<iframe width="560" height="315" src="https://www.youtube.com/embed/-q3sRVx8PNE?si=WV_6AtXsilUT8xJ_" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# オーバーフロー
セルに`##########`が並ぶ
<b>VBAで値を拾うとそこで停止する。</b>
<b>エラーが回避できない</b>


https://vbabeginner.net/error-6-response-method-overflow/
エラー対応方法
エラー6の対応方法は、データ型の範囲外の値を設定しないようにするか、データ型をより範囲の広い型に変更します。
簡単なのは変数の型をVariant型もしくは型を省略（省略するとVariantと解釈される）することです。

On Error とか IsERROR関数でも回避できず止まってしまう。

# 日付型数列
2023 10 09 23 52 16　→ 20231009235216 14桁 2147 48 36 47 Long型では２桁多い
通常はDoubleになるはずなのにDoubleにならずオーバーフローになる。

## Web版と64bit Excelでは起きない
もしくはバージョンの違いか？
64bitのExcelでは起きない。
一応Double型で入る。
32bitだとオーバーフローになってしまう。

## 対処法
またはセルの表示形式を文字列型にする。ただし、代入したとたんオーバーフローになる。
頭に`’`をつけて続けて数字を入力し、テキスト型にする。ただし、この場合頭の`'`をとる。


# ドツボではまる場所と見分け方
64bitを前提にして日時型の数列をホイホイ入力していると、32bitになったとたんオーバーフローで停止する。
`#####`が現れたら要注意。
【C#/.NET/Windows】DateTimeのToStringで西暦/和暦(Windows設定)の罠にはまりかけた話

# 要約

C#のDateTimeでUTC現在時刻を取得して、ToStringしたものを表示しようとしたところ、罠にはまりかけたので、備忘録です。

# Windowsの設定と年月日表示形式

Windowsの設定の時刻と言語から、年月日の表示を変えることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/8dfad44f-f041-c3d9-c178-84781c99cc03.png)

また、「カレンダー」の項目で西暦/和暦を選択することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/c3f82cc1-ba00-0a4c-694f-43065f5d7a5f.png)

ここを変更すると、タスクバーの端の年月日の表示形式が変わります。

- 西暦
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/e80ef3c5-ddf0-3979-e76f-13a05b06a34a.png)

- 和暦
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2430330/18684e05-9154-1ea1-2dab-86838904c591.png)


# DateTimeのToStringはWindows設定の西暦/和暦に引っ張られる

CultureInfoが"ja-JP"となっている場合（設定を変えていない限りは基本的に何も指定しないlocalも"ja-JP"だと思います）、このWindowsの西暦/和暦にDateTime.ToStringの表示が引っ張られます。

```csharp:西暦を選択した場合
Console.WriteLine($"{DateTime.UtcNow.ToString("yyyy", new CultureInfo("ja-JP"))}");
// 出力：2023
```

```csharp:和暦を選択した場合
Console.WriteLine($"{DateTime.UtcNow.ToString("yyyy", new CultureInfo("ja-JP"))}");
// 出力：05 （令和5年を指す）
```

# 設定によらずToStringで西暦を取得したい場合

CultureInfoに西暦をデフォルトで使用するようなものを指定すればよいです。（"en-US"やCultureInfo.InvaritCutltureなど。）
これらを指定しておけば、Windowsの設定にかかわらず西暦で年が表示されます。

```csharp
 Console.WriteLine($"{DateTime.UtcNow.ToString("yyyy", new CultureInfo("en-US"))}");
// 出力：2023
 Console.WriteLine($"{DateTime.UtcNow.ToString("yyyy", CultureInfo.InvariantCulture)}");
// 出力：2023
```

## おまけ

プログラム起動中に西暦/和暦の設定を変更してもToStringの表示は変わりませんでした。
プログラム起動時の設定が適用されるようです。

試したコード👇

https://github.com/nobushi95/dotnet-DateTime-ToString
VSCodeとnpmのPrettierの設定が違っていて困った

# 目次
1.背景
2.原因1 Prettierルールの優先順位
3.原因2 設定の相違点
4..prettierrc.json

# 1. 背景
- VSCodeのPrettier拡張機能とnpmのPrettierの設定が異なっていました。
- 毎回以下の無駄なことをしていました。
npx prettierでフォーマット
↓
VSCodeのprettierでフォーマットすると末尾にカンマが数カ所追加される
↓
npx prettierでフォーマットされた状態に戻す

次に、この原因を説明します。

# 2. 原因1 Prettierルールの優先順位
>VSCodeのPrettier拡張機能にバンドルされているPrettierやVSCodeの設定は、あくまでもフォールバック的な位置付けで、優先される設定もローカルのPrettier設定ファイル(.prettierrc)が上位になっています。

>ローカルに Prettier 設定ファイル (.prettierrc) が存在し、一つでも設定項目が書かれている場合、 VSCode の Prettier の設定はすべて適用されません。

[【Prettier】「なんとなく使う」から「分かって使う」へ【Visual Studio Code】](https://ai-can-fly.hateblo.jp/entry/prettier-usage)

# 3. 原因2 設定内容の相違

VscodeのPrettier拡張機能の設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/54265a9d-1fc7-9a4a-ccce-61494d52e69f.png)

npmのprettierの設定
[prettier doc trailing-commas](https://prettier.io/docs/en/options.html#trailing-commas)
>Default value changed from es5 to all in v3.0.0

バージョン確認した所v3.0.0でした！
```package.json
"prettier": "^3.0.0"
```

よってallとes5の違いが原因でした。

次に以上を踏まえて.prettierrc.jsonを設定します。

# 4. .prettierrc.json
ルートディレクトリ配下に以下を作成しました。
```.prettierrc.json
{
    "semi": true,
    "trailingComma": "all",
    "singleQuote": true,
    "printWidth": 80,
    "tabWidth": 2
}
```
以下のように主要なJavaScriptエンジンとブラウザはすでにES2017をサポートしていますので、trailingCommaがallで良いと考えてます。

[Can I use Search Trailing comma in function parameters?](https://caniuse.com/?search=Trailing%20comma%20in%20function%20parameters)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/2224929f-c7d4-36e3-3302-d353c921b247.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405182/ad04deae-ab08-6689-c52d-5d9a80cdfb87.png)


また、以下の利点があります。
- オブジェクトや配列の要素を追加、削除、再配置する際にコードの編集が簡単になります。
- TypeScriptとの整合性
    TypeScript2.7以降、型パラメータリスト内でトレーリングカンマ（末尾のカンマ）を使用できるようになっています。

:::note info
以下の理由でvscodeのsettings.jsonで保存時に自動でprettierのフォーマットを設定してません。
- VScode以外のエディタの方もいる可能性があります。
- pre-commitでprettierし、その差分を一緒にcommitまでしてくれる設定にしてます。
:::

# 参考
- [【VSCode】Prettierの使い方＆おすすめ設定を紹介](https://ma-vericks.com/blog/vscode-prettier/)
- [【Can I use…】ってなに？使い方を解説｜プログラミングwoman](https://xn--pckba0b4jybydual7d8e.net/caniuse.html#Can_I_use8230)

# 最後に
- 無事ローカルの設定で上書きすることができました。
- 勘違いしていたので今回設定ズレのおかげでとても勉強になりました。
- 設定ズレを起こして下さったVSCodeのprettier拡張機能とnpm prettier v3.0.0に大変感謝します。

## 参考になる記事を書いてくださった皆様ありがとうございました！

## 宣伝させてください！
https://recruit.iimon.co.jp/
【今更ながらChatGPT③】QuizKnock動画内の問題を解くRubyプログラムを作ってもらう

## 前提条件

- QuizKnockの動画を見て、動画内容の様なプログラムを作りたくなったのでChatGPTに作って貰う。
<iframe width="560" height="315" src="https://www.youtube.com/embed/4mh9qsH0Zhs?si=YLOJogyT3GOJyvwi" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
- Rubyプログラムを1度も書いたことが無い。

* * *

## ChatGPTへの依頼

以下は、Rubyプログラムの要件定義をまとめたものとなり、この要件に従いプログラムを作成して。

### ゲームの要件定義

**ゲームの目的:** 
このゲームの目的は、プレイヤーが与えられた数字を全て使って、目標数字を作成する数式を見つけることです。

**ルール:**
1. プレイヤーが提供する入力は、"使う数字"（4個～6個、順不同、カンマ区切り、全て利用）と "求める数字"（1個）です。
2. プログラムは、"求める数字"を作成するための可能な数式を1つ提示します。
3. 数式は、四則演算（演算記号と括弧）を使用して構築されます。
4. 四則演算は、括弧内の計算、乗算/除算、加算/減算の順序に従います。同じ優先順位の演算子は左から順に処理されます。
5. 数式が出来ない場合は「階なし」と出力します。

**サンプル入力と出力の例:**
1. 入力: "2,5,5,9"、"13"
   出力: 
   ```
   答えの数式：(9-5)*2+5=13
   ```

2. 入力: "4,8,8,9"、"23"
   出力: 
   ```
   答えの数式：(8-4)*8-9=23
   ```

3. 入力: "5,6,7,9"、"19"
   出力: 
   ```
   答えの数式：6*9-5*7=19
   ```

以上がゲームの要件定義です。この要件に基づいて、Rubyプログラムを開発し、与えられた数字と目標数字に基づいて数式を生成し、解を見つけるロジックを実装してください。

* * *

## 結論
- なかなかと難しくまだ出来ていない。

```
def find_equation(numbers, target)
    # 数字の組み合わせを試すための再帰関数
    def find_solution(numbers, target)
      if numbers.length == 1
        return numbers[0] == target ? numbers[0].to_s : nil
      end
  
      (0...numbers.length).each do |i|
        num = numbers[i]
        remaining = numbers[0...i] + numbers[i+1..-1]
  
        # 加算の場合
        add_solution = find_solution(remaining, target - num)
        return "(#{add_solution}+#{num})" if add_solution
  
        # 減算の場合
        sub_solution = find_solution(remaining, target + num)
        return "(#{num}-#{sub_solution})" if sub_solution
  
        # 乗算の場合
        if target % num == 0
          mul_solution = find_solution(remaining, target / num)
          return "(#{mul_solution}*#{num})" if mul_solution
        end
  
        # 除算の場合
        div_solution = find_solution(remaining, target * num)
        return "(#{num}/#{div_solution})" if div_solution
      end
  
      return nil
    end
  
    solution = find_solution(numbers, target)
  
    if solution
      solution = solution.gsub(/[\[\]\"\\]/, '') # 不要なエスケープ文字を削除
      return "答えの数式：#{solution}=#{target}"
    else
      return "階なし"
    end
  end
  
  # 4文字から6文字の数字を入力するように制限
  input_numbers = []
  until input_numbers.length >= 4 && input_numbers.length <= 6
    puts "4文字から6文字の数字をカンマ区切りで入力してください（例: 2,5,5,9,1,3）:"
    input_numbers = gets.chomp.split(',').map(&:to_i)
  end
  
  puts "求める数字を入力してください（例: 13）:"
  target_number = gets.chomp.to_i
  
  # ゲームをプレイ
  result = find_equation(input_numbers, target_number)
  puts result
  ```

4文字から6文字の数字をカンマ区切りで入力してください:   
2,5,5,9
求める数字を入力してください:
13
答えの数式：(((5-9)*2)+5)=13
→(9-5)*2+5だと正解。

4文字から6文字の数字をカンマ区切りで入力し
てください:
3,5,8,9
求める数字を入力してください:
24
答えの数式：(3-((5-8)*9))=24
→(8-5)*9-3だと正解。

4文字から6文字の数字をカンマ区切りで入力し
てください:
1,3,5,7
求める数字を入力してください:
19
答えの数式：(1-((3-7)*5))=19
→(7-3)*5-1だと正解。
【Python】変数名と値を同時に表示する小技

# 先に結論
置換フィールド`{}`内に記述した変数の後に`=`をつけるだけです
```python
hoge = "Hello, Python!"
print(f"{hoge=}")
```
↓ 出力結果
```
hoge='Hello, Python!' 
```



# 少し解説
pythonにはフォーマットメソッドというものがあり、この記述はフォーマットメソッドの機能の１つです。
下記のように記述することで`{}`内に任意の値を入れることができます。
```python
hoge = "Python"
print("Hello, {}!".format(hoge))
```
↓ 出力結果
```
Hello, Python!
```

<br>

クォーテーションの前に`f`もしくは`F`をつけることで`{}`内に変数をそのまま入れることができます。
ここに`=`を追加することで最初に紹介したように、変数名と値を同時に表示することができます！
```python
hoge = "Python"
print(f"Hello, {hoge}!")
```




# まとめ
変数が多く複雑な処理を書いているときに重宝します
```python
hoge = "hello world"
fuga = 123
flag = True
tmp = None

print(f"{hoge=}{fuga=}{flag=}{tmp=}")
```

こういう小技をサクッと紹介している記事がなかったので書いてしまいました

# 参考
- [Pythonのf文字列（フォーマット済み文字列リテラル）の使い方](https://note.nkmk.me/python-f-strings/)

# 追記
こちらの機能はpython3.8以降から使えるものになりますのでご注意ください
（@nodai2h_ITCさんご指摘ありがとうございます！）

https://docs.python.org/ja/3.8/whatsnew/3.8.html#f-strings-support-for-self-documenting-expressions-and-debugging
Python3でスクレイピング〜ブラウザ起動編〜

# はじめに

MacBookを新しく購入したので、Python3を学習しようと思いました。
**[前回はPython3のインストールからPATHを通すまでを実施しました。](https://qiita.com/morioheisei/items/157b864a6ca7bcaf86f5)**

今回はスクレイピングの準備段階として Chromeを立ち上げるところまでやってみます。

## 開発環境

```
OS: macOS Monterey(バージョン 12.2.1)
チップ: Apple M1
エディター：Visual Studio Code
```

デスクトップにフォルダを作成し、その中で任意のファイルを作成します。
今回はget_data.pyとします。

## Seleniumのインストール

ターミナルで以下コマンドを実行します。

```zsh:terminal
% pip install selenium
```
これで最新バージョンのseleniumをインストールします。

## ChromeDriverのインストール

**[ChromeDriverの公式](https://chromedriver.chromium.org/downloads)**
上記公式サイトからインストールをします。

## ソースコード

```py:get_data.py
from selenium import webdriver
from selenium.webdriver.common.by import By
import time

def open_browser():
    # ドライバー指定でChromeブラウザを開く
    driver = webdriver.Chrome()

    # Googleに遷移
    driver.get('https://www.google.com/')
    # 5秒間待機
    time.sleep(5)

    # 全てのウインドウを閉じる
    driver.quit()

# 関数の実行
open_browser()
```

## 動作確認

ターミナルで以下コマンドを実行します。

```zsh:terminal
% python get_data.py
```

すると…

![スクリーンショット 2023-09-18 17.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555244/3206cc8e-3e80-028d-fea3-9d11af30223c.png)

Googleが表示されました！
お疲れ様でした！
自動セル

``` 
Public NextRun As Double

Const SheetName = "main"
Const MinutesCell = "B3"
Const SecondsCell = "C3"
Const ResetCell = "B4"
Const cRunIntervalSeconds = 1 ' 1秒
Const cRunWhat = "UpdateTimer" ' 実行する手続きの名前

Dim OriginalMinutes As Integer, OriginalSeconds As Integer
Dim CurrentMinutes As Integer, CurrentSeconds As Integer
Dim IsPaused As Boolean  ' 一時停止されたかどうかを示すフラグ

' エラーチェックを行う関数
Function IsValidInput(minVal As Variant, secVal As Variant) As Boolean
    If (Not IsNumeric(minVal) Or CInt(minVal) > 59 Or CInt(minVal) < 0) Then
        MsgBox "分は0〜59の数値で入力してください。", vbExclamation
        IsValidInput = False
        Exit Function
    End If
    
    If (Not IsNumeric(secVal) Or CInt(secVal) > 59 Or CInt(secVal) < 0) Then
        MsgBox "秒は0〜59の数値で入力してください。", vbExclamation
        IsValidInput = False
        Exit Function
    End If
    
    If CInt(minVal) = 0 And CInt(secVal) = 0 Then
        MsgBox "有効な時間を入力してください。分と秒はともにゼロにできません。", vbExclamation
        IsValidInput = False
        Exit Function
    End If
    
    IsValidInput = True
End Function

Sub StartTimer()
    Dim minVal, secVal As Variant

    minVal = Worksheets(SheetName).Range(MinutesCell).Value
    secVal = Worksheets(SheetName).Range(SecondsCell).Value
        
    ' エラーチェックを呼び出す
    If Not IsValidInput(minVal, secVal) Then
        Exit Sub
    End If
    
    
    ' 一時停止されていない場合のみ、元の時間を読み込む
    If Not IsPaused Then
        
        OriginalMinutes = CInt(minVal)
        OriginalSeconds = CInt(secVal)
        CurrentMinutes = OriginalMinutes
        CurrentSeconds = OriginalSeconds
    End If

    Call UpdateTimer
    
    ' 一時停止フラグをリセット
    IsPaused = False
End Sub

Sub UpdateTimer()
    If CurrentSeconds = 0 Then
        If CurrentMinutes = 0 Then
            Application.SendKeys ("{DOWN}")
            CurrentMinutes = OriginalMinutes
            CurrentSeconds = OriginalSeconds
        Else
            CurrentMinutes = CurrentMinutes - 1
            CurrentSeconds = 59
        End If
    Else
        CurrentSeconds = CurrentSeconds - 1
    End If
    
    Worksheets(SheetName).Range(MinutesCell).Value = CurrentMinutes
    Worksheets(SheetName).Range(SecondsCell).Value = CurrentSeconds
    
    NextRun = Now + TimeSerial(0, 0, cRunIntervalSeconds)
    Application.OnTime NextRun, cRunWhat
End Sub

Sub StopTimer()
    On Error Resume Next
    Application.OnTime NextRun, cRunWhat, , False
    IsPaused = True
End Sub

Sub ResetTimer()
    Worksheets(SheetName).Range(MinutesCell).Value = ""
    Worksheets(SheetName).Range(SecondsCell).Value = ""
    ' 一時停止フラグをリセット
    IsPaused = False
End Sub

Sub ResetToSelectedCell()
    Range(ResetCell).Select
End Sub
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476529/984d70be-6c6c-2a8c-e1b7-93c64475d2a3.png)
自動セル移動ツール										備考
	間隔（分）	間隔（秒）								自動セル移動させたい間隔を黄色セルに入力
										空白の場合は、"00"扱いとなる
簡単・低コスト　多言語LP をGlideで作成　プログラミング初心者🔰でもできた

## 簡単・低コスト　多言語LP をGlideで作成してみた
### 背景
私は、プログラミングは全くの初心者です。東京都港区でスポーツ鍼灸院をしています。最近は様々な国の方の来院があり、その対応の未熟さに反省の日々でした。

医療人としてもっと患者様が欲しい情報を届けられないか？
”おもてなしの心”でもっと日本を好きになってもらえないか？
その思いが強くなりました。

まずは、自院のHPを多言語化しようとしましたが、その手間とコストからなかなか進まないのが実状でした。（HP運営は業者に依頼していた）
もっと簡単に・低コストでLP（ランディングページ）を作成出来ないか調べましたが、意外とないんだなという印象でした。

そこで、ものづくり医療センターのセミナーに参加して自分で作成しよう！と試みました。

https://moicen-forest.studio.site

1回２時間の講義を７回受けて、このLPを作成出来ました。
作成時間は、６時間くらいだと思います。

### 完成イメージ

![glide 画面　home.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531581/c305278e-8632-4c25-dd44-80e484cbc32e.jpeg)

![glide 画面　英語.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531581/2cc73e3c-8ed5-e1c2-6de2-12e16d8ba6d2.jpeg)

### 使用したツール
・Googleスプレッドシート
・Chat GPT
・Glide
(ノーコードでアプリを実装できるツール)

### 翻訳までの流れ

・Googleスプレッドシートにて、日本語入力
・Googleスプレッドシート内でChat GPTによる翻訳
・Glideに自動反映

![qiita 画像　多言語化.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531581/3704d240-5a67-824f-20ee-2b161fa6fc7c.jpeg)


![ spread in.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531581/e7ba496c-35e8-b561-4e0a-f537eb7cb884.jpeg)
↑日本語で入力。一番左の列に言語を指定したら、翻訳される。

![ spread out1 .jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531581/600617e1-6ece-2756-a539-6580ebbc3862.jpeg)

↑Chat GPTによる翻訳

### 作成方法

#### ⭐️GoogleスプレッドシートでChat GPTを使えるようにする

・OpenAIのアカウントを作成する
・Google スプレッドシートにアドオンを追加する

https://forest.watch.impress.co.jp/docs/serial/offitech/1482942.html

#### ⭐️Googleスプレッドシートで多言語翻訳のデータを作成する

##### 入力項目
・一番左の列に翻訳したい言語
・一番上の行には、language や　name などの項目
・伝えたいことを日本語で入力

![ spread in.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531581/e7ba496c-35e8-b561-4e0a-f537eb7cb884.jpeg)

##### 出力項目
・GPT関数で翻訳(今回は以下を使用）
`=if(ISBLANK($A2), , GPT(B2& "簡潔に" &$A2 & "に翻訳してください")) `

#### ⭐️GlideでLP（ランディングページ）作成
##### Glideのインストール方法

https://nocodedb.world/archives/1180

##### Glideとスプレッドシートの連携

https://hikari-sedori.com/glide2/

### デモ

https://glide-test-3-tvo5.glide.page


### 課題・今後の展開
#### テンプレートの使い回しができない
1度GlideでLP作成したら、そのテンプレートで簡単に使いまわせるイメージでしたが、テンプレートはスプレッドシートデータ連携はできないということがわかりました・・・

しかし、多少時間はかかりますが、簡単なLPならプログラミング初心者でも作成可能だと思います。

#### 翻訳の精度

外国語に翻訳された文を再度日本語に翻訳し直し、修正するなど対応してもいいかも。
翻訳の専門家に確認をお願いするなど。

#### Chat GPTのコスト

### 今後の展開
### ・多言語問診票 ➡️Googleスプレッドシート翻訳からGoogleフォームで作成済
### ・予約　➡️Googleスプレッドシート翻訳からGoogleフォームで作成済
### ・Q＆A AI Bot　➡️　miibo(ミーボ）にて作成済み
### ・問診音声翻訳
・会計
・マーケティング（SNSへの自動発信）

### 感想
#### ・課題の解像度（何が困っているのか・何をしたいのか）の認識の甘さ
・初めての作成だったので、色々調べながらで作成には時間がかかった。（それでも６時間位だと思います。）
・簡単なLPとしてはいいものが作成できたと思う。
・テクノロジーを使ったというよりは、地味な作業の繰り返しだったなという印象だが、Glideというノーコードツールを使ったことで、少ない作業でLPを作成できたし、修正なども簡単にできるのではないかと思う。
・飲食店や小規模事業者など、時間やコストをかけられない事業の方でも、多言語化の対応に取り組み、外国の方へのおもてなしを充実させ、新たなマーケットを開拓できるようになればいいなと思っています。
・私は未熟者ですので、何か修正点やアイディアなどあればご意見いただけたら幸いです。
#### ・課題解決に一番必要なのは執念。執念を持ち課題解決に取り組みたい！！！！
【 Vue.js 】piniaの「storeToRefs」とは

ポートフォリオ用アプリにpiniaを使っていますが、まだ無知に等しい状態なので備忘録です。

# storeToRefsとは
Piniaのユーティリティ関数。リアクティブ性を担保しながら、Storeからプロパティを参照するために使用します。

〇ユーティリティ関数とは
再利用可能な処理として簡単に呼び出せるように作成される小さな関数のことです。ユーティリティ関数を使用するｋとでコードが整理され、可読性とメンテナンス性が向上します。

# 例

```js:src/store/food.js
import { defineStore } from "pinia";
import { allFoods } from "../http/food-api";
import { ref } from "vue";

export const useFoodStore = defineStore('foodStore', () => {
    const foods = ref([]);

    const fetchAllFoods = async () => {
        const { data } = await allFoods();
        foods.value = data.data;
    }

    return {
        foods,
        fetchAllFoods,
    };
});
```

```js:src/pages/Foods/NewFoodPage.vue
<script setup>
import { onMounted, ref, computed } from 'vue';
import { storeToRefs } from 'pinia';
import { useFoodStore } from '../../stores/food';
import api from "../../http/api";

const foodStore = useFoodStore()
const { foods } = storeToRefs(foodStore)
const { fetchAllFoods } = foodStore

onMounted(async () => {
    await fetchAllFoods()
})

</script>
```

また、storeToRefsを使うで`.value`を使って値を取得できるようになります。
floorとintの違い / Tableau Prep

# floor と intの違い

プラスの数字だと違いがわからないが、マイナスだと繰り上がりの考えが違う！
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/325f7795-0bd0-bc8e-1760-c3d5ed34be4d.png)

roundは完全なる四捨五入（何も指定しないと小数点以下四捨五入）です。
そのため、1.5ならば2に繰り上がりますし、1.4ならば1に繰り下がります。
また、マイナスの場合は-1.5は-2、-1.4は-1になります。
ここまでは算数でやっていたことなので、OKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/85401549-a43f-584b-2842-890e8a9fe03c.png)

floor関数とint関数については少し注意が必要です。
整数においては、うちわで一番近い整数になります。
1.9でも1です。

マイナスの場合は、答えが違ってきます。
floorは低い数字に合わせに行きます。つまり、-1.3ならば-2になります。
一方intはうちわで一番近い整数になりますので、-1.3ならば-1になります。

上の表を見ながら、整理すると違いがわかるかと思います。
求めたい数字がどういった値かによって関数の使い分けが必要です。
Google Colaboratoryで作成したファイルをGitHubにプッシュする方法

以下の手順でできました。既存のリポジトリ・ブランチに保存したい場合は①②の手順は不要です。
①GitHubでリモートリポジトリを作る
②適当な場所にローカルリポジトリを作り、ブランチを作成する
③Google Colaboratoryで当該ノートブックを開き、「ファイル」→「GitHubにコピーを保存」を選択
③別タブが開き認証画面が出るため、「Authorize GoogleColab」を選択
④GitHubのパスワードを入力
⑤保存先のリポジトリとブランチ、コミットメッセージを指定して、「OK」を選択
KubernetesとGitOps(<->CIOps)について

# KubernetesとGitOps(<->CIOps)について

## 目次

1. [はじめに](#はじめに)
2. [GitOpsとは](#gitopsとは)
3. [CIOpsとの違い](#ciopsとの違い)
4. [Kubernetesの中のGitOps](#kubernetesの中のgitops)
5. [Fluxの紹介](#fluxの紹介)
6. [GitOpsのメリット](#gitopsのメリット)
7. [まとめ](#まとめ)

## はじめに

### Kubernetesとは

Kubernetesはコンテナ化されたアプリケーションのデプロイ、スケーリング、運用を自動化するためのオープンソースプラットフォームです。

## GitOpsとは

GitOpsは、システムの"望ましい状態"をGitリポジトリに格納し、そのリポジトリを"single source of truth"として使用するアプローチです。

### シングルソースオブトゥルースとしてのGit

GitOpsでは、Gitリポジトリがシステムの真実のソースとして扱われます。これは、設定、インフラストラクチャーのコード、デプロイメントマニフェストなどがGit上で管理されることを意味します。変更が発生した際には、Git上でのマージやPull Requestを通じて反映が行われ、このリポジトリの状態が"望ましい状態"としてシステムに適用される仕組みとなっています。

## CIOpsとの違い

### CIフローの違い

- **CIOps**:
  - CIツール(例: Jenkins, Travis CI)がコード変更を検出
  - 単体テストやビルドが実行
  - 成功した場合、CDフローへ進む
- **GitOps**:
  - Gitリポジトリが変更を検出
  - CIツールがテストやビルドを実行
  - ビルド成果物をコンテナレジストリにプッシュ

### CDフローの違い

- **CIOps**:
  - CIツールがデプロイメントを手動/自動で開始
  - 必要に応じてロールバック
- **GitOps**:
  - GitOpsツール(例: Flux)がリポジトリの変更を検出
  - Kubernetesクラスタに変更を自動適用
  - 状態の差異が発生した場合、Gitの状態に合わせて自動修正

### 評価観点

- **権限**: GitOpsでは、環境にはGitリポジトリのreadの権限しか必要なく、CIには限定的な権限で済む。これにより権限や役割の集中を避けることができる。
- **ロールバック**: GitOpsでは、望ましい状態をGitリポジトリに持っているため、状態のロールバックが容易。
- **プロジェクトの規模**: GitOpsは、プロジェクトの規模に関係なく適用可能で、大規模なプロジェクトでも一貫性を保ちながら適用できる。

## Kubernetesの中のGitOps

### KubernetesとGitOpsの結びつき

Kubernetes環境では、GitOpsツールがGitリポジトリを定期的にポーリングして、望ましい状態の変更を検出し、その変更をクラスタに自動的に適用します。

## Fluxの紹介

### Fluxとは

Fluxは、KubernetesでのGitOpsを実現するためのオープンソースツールの一つです。FluxはKubernetesクラスタ内の特定のノード上で動作し、Gitリポジトリからの変更を定期的にポーリングします。

### どのように動作するか

FluxはGitリポジトリの変更を検出するために、定期的にリポジトリをポーリングします。変更が検出された場合、FluxはKubernetesクラスタの現在の状態とGitリポジトリの"望ましい状態"を比較します。この比較は、リソースの種類、名前、ネームスペースなどの属性を元に行わ

れます。差異がある場合、FluxはKubernetes APIを通じてクラスタの状態を更新し、Gitの状態に合わせます。

### Fluxのポーリング動作

FluxはKubernetesクラスタ内でPodとして動作します。特定の間隔でGitリポジトリをポーリングし、変更を検出した際にKubernetesのAPIを使用してクラスタの状態を更新します。

```bash
# FluxのPodとしての動作を確認
kubectl get pods -n flux-namespace
```

## GitOpsのメリット

1. **シングルソースオブトゥルース**: システムの"望ましい状態"がGitリポジトリに一元化されるため、変更の追跡やロールバックが容易です。
2. **自動化**: リポジトリの変更を自動的に検出して適用するため、手動の介入が最小限になります。
3. **セキュリティ**: 環境の権限が最小限に保たれるため、セキュリティリスクが低減します。

## まとめ

KubernetesとGitOpsを組み合わせることで、強力なデプロイメントと運用の自動化を実現できます。GitOpsのアプローチは、変更の追跡、監査、自動化、セキュリティの強化など、多くの利点があります。KubernetesとGitOpsの組み合わせは、堅牢で効率的なシステム運用を実現する強力な方法と言えるでしょう。
.NET：複数のusingの使い

## 前書
* 自分の勉強メモ

## 複数のusingの深い階層の解決方法
* try{} finally{}の代わりに、usingを利用する。
* また、using {}のような深い階層を使わない。

```c#:Sample.cs


using System;

namespace MyTest.Service
{
    internal class MyBaseClass : IDisposable
    {
        Logger logger = Logger.GetInstance();

        public MyBaseClass() { }

        // Disposeを実現する
        public void Dispose()
        {
            logger.Debug("MyBaseClass : Dispose.");
        }

        public void MyDoThing()
        {
            logger.Debug("MyBaseClass : DoThing.");
            throw new Exception("Exception : DoThing");
        }

        public void MyDoThing2()
        {
            logger.Debug("MyBaseClass : DoThing 2.");
        }

    }
    
    internal class TestUsing
    {
        public void test()
        {
            try
            {
                Logger.GetInstance().Debug("before USING");
                
                // usingを利用する
                using MyBaseClass myTest = new MyBaseClass();
                myTest.MyDoThing();
                Logger.GetInstance().Debug("end USING");
            }
            catch
            {
            }
        }
    }
}
```

* 実行結果
```:結果LOG
[DEBUG] before USING
[DEBUG] MyBaseClass : DoThing.
[DEBUG] MyBaseClass : Dispose.
[DEBUG] END
2023: Week 37 - 2023: Week 37 Order Sequence Analysis / Preppin' Data / Tableau Prep

# Challenge Preppin'Data 2023:Week 37

## 概要
インプットデータを使って、書籍の購入の一部を分析して、注文が時間の経過とともにどのように変化しているかを確認しようとしています。現在の注文が以前の注文とくらべてどのぐらい数が減ったかを計算したいが、オーダー順がわかる項目がないため、自分でシーケンス番号をふって、現在の注文と以前の注文の差を求めます。

## 問題のページ（英語）※ここからデータをダウンロード
https://preppindata.blogspot.com/2023/09/2023-week-37-order-sequence-analysis.html

## 出題者の回答のページ（英語）※動画あり
https://preppindata.blogspot.com/2023/09/2023-week-37-solution.html

## 自分の解決法
最初に非表示の行番号を表示にしてから、２つのユニオンします。
ファイル名から年と月の情報を取り出して、日付データにし、行番号と日付を使って、データをソートしLookup関数で次の数字を持ってきて、値を求めます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/e455c09f-ab7d-8830-3bed-29f6cb330def.png)


以下のように入力ステップで１列目のSource Row Numberが最初から非表示なのがわかります。
これはデータ読み込みの際に読み込みデータ順にシーケンスナンバーをふっているものです。
今回はこれを表示にして使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/ed8a7fc9-1149-3b6b-3abd-23eb39da0353.png)

ファイル名はユニオンすると１フィールドに入ります。ここに年の情報と月の情報が入っているのでSpirt関数を使って取っだし、日付型のデータを作ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/73e6c004-ab22-99fd-7523-92624d47b651.png)

ROW_NUMBER関数は、指定したソート順にソート番号を振ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/4794f650-df43-75a1-37de-cac759c539dd.png)

LOOKUP関数を使うと他の行のデータを引っ張ってくることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/ca8bb7a3-3dcc-bd88-9cfa-c9d7086c8cfd.png)

問題の中に、いろいろな機能が含まれていて、面白い問題でした。
20230918


3-1

```C#:info.cs
using System;
using System.Diagnostics;
using System.Net;

namespace RedTeamDevelop
{
    class GeneralInfo
    {
        public string oSystem; //string variable for storing operating system
        public string uName; //string variable for storing username
        public string cDirectory; //string variable for storing current directory
        public string pName; //string variable for storing process name
        public string ePath; //string variable for executable path
        public string ipv4address; //string variable for ipv4adress
	    public string hostName;
        public int pId; //int variable for process id
        public bool isAdmin; //bool variable for check if user is admin

        public GeneralInfo(){

            oSystem = Environment.OSVersion.ToString();
            uName = Environment.UserName;
            cDirectory = Environment.CurrentDirectory;
            pName = Process.GetCurrentProcess().ProcessName;
            pId = Process.GetCurrentProcess().Id;
            ePath = Process.GetCurrentProcess().MainModule.FileName;
            hostName = Dns.GetHostName();
            ipv4address = Dns.GetHostByName(hostName).AddressList[1].ToString();
            using var identity = System.Security.Principal.WindowsIdentity.GetCurrent();
            var principal = new System.Security.Principal.WindowsPrincipal(identity);
            isAdmin = principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);
        }
    }
}

```
フローのグループ化 / Tableau Prep

### フローのグループ化

フローが増えてくるとキャンパス上がごちゃごちゃになります。
フローをグループ化することで、キャンパス上の少しスッキリさせることができます。

グループ化したいステップをドラッグで選択します。右クリックメニューより「グループ」を選択するとフォルダー化されます。
フォルダー化されたアイコンには展開ボタンが付いており、展開ボタンで再表示は可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/57904e5e-903d-9c6b-7115-250f529484c9.png)
【雑記】初めて3Dゲームを本格的に作ってみた反省点と勉強できた点【Unity】

# 自己紹介
大学２年。Unity歴5年近くあるが、2Dゲームばっかりやっていた人。
その2Dゲームも全然完成できず、そろそろ焦ってきて3Dゲームを完成させようとしている人。

# 作ったゲーム
まだリリースは出来ていないのですが、ゲームが遊べる程度にはなったステルスアクションゲームです。

# 難しかったところ
## 1. 物理演算（特にキャラクターコントローラー）
Apexが好きだったので、Apexのようなキャラクターコントローラーを作ろうと、頑張って物理演算ベースのキャラクターコントローラーを自作したのですが、全くうまく動かず…
ここは今もちょくちょく挙動治してるんですが、上手く動くまでまだまだかかりそうです。

## 2. ステージづくり
ステージづくりは本当に苦痛でした。
今も壁がズレていたり、なにかがめり込んでいたりして修正点多々あるのですが、なかなか手につきません。
やっぱりプログラミングが最高です。

# 勉強になったところ
## 1. ステートマシン
ステートマシンの自作は勉強になりました。
完成度も悪くないと思います。

今回はコードベースで書きましたが、次作るときは外部のパッケージやアッセトを使ってやってみたいですね。

## 2. インターフェース
C#のインターフェースを本格的に導入したところ便利すぎてハゲました。
なぜ今まで使わなかったのか…

## 3. ゲーム全体の管理
今回、実際に動かす部分を先に作っていたのもあって、プレイヤーの進行状態などを管理するプログラムがないことに途中で気がついて、ちょっと良くない感じになってしまいました。
上流工程、大事

## 4. アーキテクスチャを意識した開発
今回は、初めてアーキテクスチャを意識して開発しました。
参考にしたのは以下のQiitaのアーキテクスチャです。
まだまだ練度が低いながらも純粋なC#も多用することができましたし、一回目にしては満足しています。

https://qiita.com/IShix/items/5e1450ad8fb7f4a39f22

# 反省点と今後意識したいところ
## 1. ゲーム全体の管理方法
勉強になったところでも書きましたが、やはりここが一番コード的には満足のいかないところでした。
そのせいで、また破壊しかけたのですが流石にこれを繰り返してると一生完成しないので今回は許容ということで…

## 2. ステージづくり
ステージづくりも初めて本格的にやって、ちゃんと計画性を持った方が良いのと、自分自身めちゃめちゃ苦手なんだなと思いました。
苦手が知れてよい。

## 3. Raycast周り
どうにかして、Raycastを１つに集めて、JobSystemに投げてサクサクにしたい！
値を返すとか含めると結構ややこしそうですが、やりたい。ただそれだけ。
なんかJobSystem使ってるとめっちゃそれっぽくないですか？

# 良かったところ
## 1. アイテムやアクション回りの実装
ここらへんはインターフェースと継承を上手く使って綺麗に実装できました。
正直めちゃめちゃ満足してます。

## 2. 個別のパッケージを自作して切り分けた開発
以下のパッケージを代表に、2つほど自作のパッケージを開発して今回使用しました。
切り分けておくと、めちゃめちゃ楽ですね。

https://qiita.com/AtsuAtsu0120/items/5fd97878fc783205cf77

## 3. InputSystem周り
こちらももともと好きでInputSystemを使っていたのもあって綺麗に実装出来た気がします。

## 4. ScritableObject周り
こちらも有効に使えたかなと思います。
管理もめちゃめちゃ楽になるし良かったですね。

# まとめ
とにかくコードはある程度綺麗。（ゲーム全体の管理を除く）
ステージづくりなどを筆頭とする見た目の部分は全然満足いかないし、自分が不得意ということが分かりました。

もうすぐ夏休みは終わりますが、リリース出来るぐらいまで仕上げれるように少しずつ改善していきます。
フローの保存機能 / Tableau Prep

## フローの保存機能
フローの保存機能を紹介します。
既に作成したフローのステップをマウスで複数選択し、フローの保存を選択します。
新しいフロー作成時に、ステップの追加あるいは、フローのキャンパスの何もないところで右クリックすると、フローの挿入が可能です。
既に作成しているフローの一部をコピーして修正したい場合に便利です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/d4aa9e27-ba56-a9f9-be5b-62dff040fc31.png)
クラウド環境におけるインフラエンジニア

ポエムタグはただの思いつき

# インフラエンジニアの変化
今と昔もインフラエンジニアと存在するが、大きく責任範囲が変わってきているのでそれを記載。


## インフラの主戦場

いうまでもなくクラウド
いままでは、物理的なハードウェアの導入、設定、メンテナンスが主な業務だったが、
今後はクラウドが提供するサービスを利用してアプリケーションの仮想化や自動化ツールを利用してのリソース管理や展開が主な業務。


## インフラの範囲
アプリ側、インフラ側との境も明確ではなくなってきており昔のようにアプリ、インフラ側と言い放つのは間違い。クラウド環境を活用するためにはインフラ側もアプリのことを理解する必要があり、アプリ側も設計時よりクラウドのインフラ部分を正しく理解する必要がある。



## 今後のインフラチーム
会社の規模にもよるが、インフラチームを単独で持てるような企業はPlatform Engineeringのようにアプリ側の効率的をかんがえ、構築、テスト、およびデプロイできるようにするためのプラットフォームやツールセットを設計、構築、および維持してプロジェクトに貢献するチームを作るべき。

インフラ環境の提供 ＋ 各種platform(CI/CD環境、ログ監視環境、リソース監視環境など）を合わせて提供することにより初めてメリットが出てくると思われる。

クラウドの利点であるスピードと効率を最大限生かすことが重要であるため上記環境はIaCなどで自動化されて構築される必要がある。
paizaの問題集の答えかたがわかりません。

paizaドットラーニングの問題がよく分かりません。
これはどうやって解いたらいいんですか？
どう入力したらいいかわかりません。
分かる方、どうかよろしくお願いします。
Pythonで最初の自己紹介とかもわかりません。
全部プリントで入力して不正解でした。
分かる方、どうかよろしくお願いします。


"名前", "言語", "一言"を以下のフォーマットで出力してください。


言語をPythonに選択して問題もやろうとしたんですが、問のやり方が全く分かりません
https://paiza.jp/works/mondai/self_introduction/self_introduction__1/edit?language_uid=python3

name: 名前
language: 言語
hitokoto: 一言

![2023-09-18_08h16_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1230737/9cf39994-17bb-2af6-c437-df732f3c85fa.png)

以下は上の写真のフォーマットです

input_line = input()
print("xxxx")

この構文に混乱させられています


自分ではこう入力してみました
input_line = input("sasaki")
print(input_line)



sasakiって出力されるだけで
name: sasaki
とはなっていないんで不正解です。
これは問題以前の問題みたいな扱いになってるんですが。一個も当てられません。
どんなふうに答えたらいいんでしょうか？
Windows PowerShell での SSM 接続コマンドのメモ


# はじめに
* 過去にいた企業内で Mac なんてオサレなマシン提供された未来が見えない
* 客も Windows 多いんだし、Word とか画面壊れるの嫌だし、Windows マンセー
* すぐに SSM で接続する為のコマンドメモです

# 手順
## プロファイルとインスタンス Name タグを指定
```
${profile} = {Systems　Manager　接続可能なプロファイルを指定}
${InstanceName} = {インスタンス Name タグを指定}
```
## Name タグからインスタンス ID 取得
```
${InstanceId} = aws ec2 describe-instances `
    --profile ${profile} `
    --filter "Name=tag:Name,Values=${InstanceName}" `
    --query "Reservations[].Instances[].InstanceId" `
    --output text
```
## 接続
```
aws ssm start-session `
    --profile ${profile} `
    --target ${InstanceId}
```
C言語でpythonのモジュールを作る第一歩

Cでpythonのモジュールを作る。第一歩。
frというテストモジュールを作ります。

###　環境

arch linux
python 3.11
gcc 13.2.1 20230801
GNU Make 4.4.1


### モジュール構成

```
fr.Open     Trueを返す。
fr.Close　　 Trueを返す
fr.fr       0.5を返す。
```

### モジュールを置く、ユーザーのlibraryディレクトリ

$HOME/lib/

ないなら、

```
mkdir -p $HOME/lib/
```

として、作っておきます。


### モジュール本体ソース

```fr.c
#include  <Python.h>
#include  <stdlib.h>
#include  <stdio.h>

//
// Open()
//
static PyObject* Open(PyObject *self,PyObject *args) {
    Py_RETURN_TRUE;
}

//
// Close()
//
static PyObject* Close(PyObject *self,PyObject *args) {
    Py_RETURN_TRUE;
}

//
// fr(): 値を返す
//

static PyObject* fr(PyObject *self,PyObject *args) {
    return Py_BuildValue("d", 0.5);
}

///*****************************************************************
///
/// モジュール定義
///
///*****************************************************************


//
// モジュール内のメソッドの定義する
//
// {
// "Open" メソッド名
//  Open メソッドの本体
//  METH_VARARGS は引数の定義, METH_NOARGS は引数なしのときの定義
//  "open random"         // メソッドの説明
// }

static PyMethodDef methods[] = {
    { 
     "Open",                // メソッド名
      Open,                 // メソッド本体
      METH_NOARGS,          // 引数なしのときの定義
      "open"         // メソッドの説明
    },
    {"Close", Close, METH_NOARGS, "close"},
    {"fr", fr, METH_NOARGS, "return a number"},
    //{"fr", fr, METH_VARARGS, ""}, 引数を取る場合
    {NULL,NULL,0,NULL},  // 番兵
};

// モジュールの定義
static struct PyModuleDef module =
{
    PyModuleDef_HEAD_INIT,
    "fr",  // モジュール名。
    "test",  // モジュールの説明
    -1,  // モジュールのインタプリタのステートのサイズ
    methods  // メソッド群定義
};

// モジュールの初期化
PyMODINIT_FUNC PyInit_fr(void)
{
    return PyModule_Create(&module);
}

```

### makefile

```
# Makefileのコマンド行の先頭キャラクタをスペースに
.RECIPEPREFIX :=$(RECIPEPREFIX) <space>

CC          = gcc
RM          = rm
CP          = cp
CSUFFIX     = .c
LSUFFIX     = .so

# 動的ライブラリの名前
TARGET      = fr$(LSUFFIX)

SRCS        = fr.c          # ソースファイルの列挙
# ライブラリディレクトリ
LIBDIRNAME  = $${HOME}/lib/
# コンパイラに渡すオプション
CFLAGS      = -Wall -O2

# makeとすると動的ライブラリを作成する
$(TARGET): $(SRCS)
    gcc -I/usr/include/python3.11 -fPIC -Wall -shared -o $@ $^

# make installとすると、ライブラリを当該ディレクトリにインストール
install: $(TARGET)
    $(CP) $(TARGET) $(LIBDIRNAME)

# make clean とすると .o ファイル削除
clean:
    $(RM) -rf $(TARGET)

# make all とすると最初からやる
all: clean install

```

### テストプログラム

実行する前に、モジュールをオプショナルな場所からインポートできるように、

```
export PYTHONPATH="$HOME/lib:$PYTHONPATH"
```

として、パスを通しておいてください。


```frtest.py
#!/usr/bin/python3
import fr
print(fr.Open())
print(fr.fr())
print(fr.Close())
```

### 実行結果

```
$ ./frtest.py
True
0.5
True
```
Dockerコンテナ内移動コマンド

Dockerコンテナ内に移動するには、`docker exec`コマンドを使用します。以下は、Dockerコンテナ内に移動する手順です：

1. **実行中のコンテナを確認**:
   まず、どのコンテナにアクセスしたいかを確認します。ターミナルで次のコマンドを実行して、実行中のコンテナのリストを表示します：

   ```shell
   docker ps
   ```

   これにより、実行中のコンテナの一覧が表示されます。コンテナ名またはコンテナIDが確認できます。

2. **コンテナ内に移動**:
   `docker exec`コマンドを使用してコンテナ内に移動します。以下は、コンテナ名またはコンテナIDを指定してコンテナ内に移動するコマンドです。ここでは、`<container_name_or_id>`は実際のコンテナ名またはコンテナIDに置き換えてください。

   ```shell
   docker exec -it <container_name_or_id> /bin/bash
   ```

   このコマンドは、`-it`オプションで対話的なセッションを開始し、`/bin/bash`（またはシェルのパス）をコンテナ内で実行します。これにより、コンテナ内でコマンドを実行できるシェルセッションが開始されます。

3. **コンテナ内で作業**:
   コンテナ内に移動したら、コンテナ内で必要な操作を実行できます。コンテナ内での作業が終了したら、通常のコンテナシェルを終了するには`exit`コマンドを使用します。

   ```shell
   exit
   ```

これで、Dockerコンテナ内に移動する方法を理解できました。`docker exec`コマンドを使用すると、コンテナ内での操作やデバッグが容易になります。必要な場合にコンテナ内でコマンドを実行して、状況を確認できます。
システム監査の計画

システム監査の計画について解説します。

```mermaid
flowchart TD
  中長期計画 --> 年度計画 --> 個別計画 
```

# 中長期計画

3年から5年程度の期間で計画する。
経営目標や経営戦略との整合性を保ちながら作られる。

## 中長期計画書の記載内容[^1]

* 中長期方針
* 実施体制の整備
* 主要な監査対象領域
* 監査資源の投資額の概算

# 年度計画

各年度ごとに立案する計画。
年間スケジュールを計画する。
中長期計画の内容を元に作成される。

## 年度計画書の内容[^1]

* 年間方針
* 当該年度の目的
* 実施すべき監査対象
* リスクアセスメントの結果
* 監査スケジュール
* 監査費用の概算額

# 個別監査計画

年度計画に基づいて個別のシステム監査対象ごとに計画する。
具体的なスケジュールまで落とし込んだ詳細計画書を作成する。

## 個別監査計画書の内容[^1]

* システム監査の目的
* システム監査の対象
* リスクアセスメントの結果
* 監査責任者及び監査担当者
* 詳細スケジュール
* 監査場所
* 利用する判断の尺度
* 監査手続の概要
* 監査結果の報告予定時期
* 監査費用の見積額

# 参考

[^1]:[システム監査基準](https://www.meti.go.jp/policy/netsecurity/downloadfiles/system_kansa_h30.pdf)
samba addc プライマリーセカンダリー設定方法（レプリケーション）

Samba Active Directory Domain Controller（Samba AD DC）のプライマリーとセカンダリーの設定は、ドメインコントローラー間でのリプリケーションを確立するために行われます。以下は、プライマリーとセカンダリーの設定手順です。

**プライマリー Samba AD DC の設定**:

1. プライマリー Samba AD DCを正常にセットアップして稼働させます。Samba AD DCの設定は、前説明した手順に従って行います。

**セカンダリー Samba AD DC の設定**:

2. セカンダリー Samba AD DCを新しいマシンにインストールします。これはプライマリーと同じドメインに参加することが重要です。必要なパッケージをインストールし、`samba-tool domain join`コマンドを使用してドメインに参加します。例：

   ```shell
   sudo apt-get install samba
   sudo samba-tool domain join example.local DC -U administrator --realm=EXAMPLE.LOCAL
   ```

   ユーザー名、ドメイン、およびレルムを適切に設定してください。

3. ドメインに参加したセカンダリー Samba AD DCを起動します：

   ```shell
   sudo systemctl start smbd
   ```

4. レプリケーションの設定:
   プライマリーからセカンダリーへのレプリケーションを設定するには、`samba-tool drs replicate`コマンドを使用します。例えば、プライマリーのSamba AD DCが`PRIMARY-DC`、セカンダリーが`SECONDARY-DC`の場合、以下のコマンドで設定します：

   ```shell
   sudo samba-tool drs replicate PRIMARY-DC SECONDARY-DC EXAMPLE.LOCAL
   ```

   これにより、プライマリーからセカンダリーへのレプリケーションが開始されます。

5. セカンダリーの動作確認:
   セカンダリー Samba AD DCが正常に動作していることを確認し、必要な設定やリソースがプライマリーと同期されていることを確認します。

これで、プライマリーとセカンダリーのSamba AD DCが設定され、ドメインコントローラー間でのリプリケーションが確立されました。プライマリーがダウンした場合、セカンダリーがドメインの提供を継続します。セカンダリーの設定もプライマリーと同じくセキュリティに注意して行ってください。
samba addc サーバ名特定方法

Samba Active Directory Domain Controller（Samba AD DC）のサーバー名を特定する方法はいくつかあります。以下の方法でサーバー名を見つけることができます。

1. **ホスト名コマンド**:
   プライマリー Samba AD DCやセカンダリー Samba AD DCのサーバー名は、`hostname`コマンドを使用して確認できます。ターミナルで次のコマンドを実行します：

   ```shell
   hostname
   ```

   このコマンドは、サーバーのホスト名を表示します。これがサーバーの名前です。

2. **`samba-tool`コマンド**:
   `samba-tool`ユーティリティを使用しても、Samba AD DCのサーバー名を取得できます。次のコマンドを実行します：

   ```shell
   samba-tool drs showrepl
   ```

   このコマンドにより、ドメインコントローラー間のレプリケーション情報が表示され、各ドメインコントローラーのサーバー名が確認できます。

3. **コンピュータ名のプロパティ**:
   Windowsクライアントからプライマリーまたはセカンダリー Samba AD DCに接続し、コントロールパネルの「システム」または「コンピュータ」セクションでコンピュータ名を確認できます。

これらの方法のいずれかを使用して、Samba AD DCサーバーのサーバー名を見つけることができます。通常、このサーバー名はホスト名として設定されており、ネットワーク内で一意である必要があります。
samba addc ユーザー追加

Samba Active Directory Domain Controller（Samba AD DC）を使用してWindowsユーザーを追加する手順を以下に示します。これにより、Samba AD DC内にドメインユーザーアカウントを作成できます。

1. **Samba AD DCにログイン**:
   Samba AD DCが正常に動作していることを確認し、Samba AD DCにログインしてください。通常、これはSamba AD DCをセットアップしたサーバー上で行います。

2. **新しいユーザーアカウントの作成**:
   新しいユーザーアカウントを作成するには、`samba-tool`ユーティリティを使用します。以下は、新しいユーザー "newuser" を作成する例です。適切な情報を入力してください。

   ```shell
   sudo samba-tool user create newuser
   ```

   ユーザーにはパスワードを割り当てるオプションもあります。パスワードを設定する場合は、次のコマンドを使用します。

   ```shell
   samba-tool user setpassword newuser
   ```

   必要な情報を入力し、新しいユーザーアカウントを作成します。

3. **ユーザーグループへの追加 (オプション)**:
   ユーザーを特定のグループに追加する場合は、以下のコマンドを使用します。

   ```shell
   samba-tool group addmembers <グループ名> newuser
   ```

   `<グループ名>` を適切なグループ名に置き換え、ユーザーをそのグループに追加します。

これで、Samba AD DCに新しいユーザーアカウントが追加されました。新しいユーザーはWindowsクライアントからドメインに参加できるようになります。必要に応じて、ユーザーに適切な権限と設定を割り当てることができます。

注意: ユーザーアカウントの管理には注意が必要です。適切なセキュリティポリシーに従ってユーザーアカウントを作成し、権限を設定してください。
Excel/PowerPointの3D書式を制御しやすくするツール

# 結論
![3D書式簡単制御君.xlsm - Excel.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/8d54e8b1-a023-2628-52c4-3f47c2b69313.gif)


[こちらからダウンロード](https://github.com/yt0sh/vba-3dformat-control/blob/main/3D%E6%9B%B8%E5%BC%8F%E7%B0%A1%E5%8D%98%E5%88%B6%E5%BE%A1%E5%90%9B.xlsm)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/ee62d1bc-e776-5fe7-420a-45844d42b7f9.png)

# 背景
パワーポイントに立体物の写真や画像を貼り付けた後、その形に沿った3D図形を置きたいこと、**ありますよね** 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/49c85363-f9dc-79ee-da32-c4214e0c75d0.png)

分かりやすくするテクニックとして勧めたいものの、メニューが深かったり、思うように動かしにくかったり、90度違う向きを用意しようとすると最初からやり直さなければならなかったりと、欲しい図形を得るまでに手間がかかりすぎるのが難点でした。

それを改善し、整えたUIをマクロを構築してみました。

# 機能説明
## 1. 同一俯瞰角度かつ別押し出し軸セットを用意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/47a2af34-166d-7104-5f70-aab1dfeca80a.png)
回転してから合わせこむように作るのは困難です。先に用意して同一回転量を与えることで都合のいい角度を保持しています。

## 1. 3D回転
冒頭のもの。水平軸回転・垂直軸回転・Z軸回転のボタンを表に出しています。
(Shiftを押しながらで回転量が1/3の精緻モードになります。)

## 2. 矢印サイズ変更
![3D書式簡単制御君.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/557d39a5-252f-fba8-4b87-84706a0b93d2.gif)
矢印全体の長さ/幅/厚みをワンクリックで変更できます。

## 3. 矢印移動
![3D書式簡単制御君3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/d6459e7a-f3fa-c0cf-1855-0a976f6e0bcf.gif)
既存の画像に角度を合わせこむ際、矢印の位置を近接させることが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/590275be-c3f3-412b-3009-74219ad5ae16.png)

全ての矢印を同時に使うことは無いでしょう。いずれか抜粋するような使い方を想定しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/8c20406a-d96d-56db-a2dd-88e969846927.png)

# 工夫したところ
回転させると同時に気持ちいい位置に調整しています。
![3D書式簡単制御君4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/c5853d6f-a406-b03c-fb5f-774af4592eaf.gif)

# 軸ロック機能
このマクロで唯一、Excelに無い機能です。
![3D書式簡単制御君_軸ロック.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/05689d16-d35a-9cda-2bb4-624fdc49d33d.gif)
水平軸回転/垂直軸回転をする際に任意の1軸を固定できます。
(正確に言うと回転した後にZ軸補正回転を加えています。)

※3次元空間の軸方向固定をしているわけではありません。XY平面の投影角度を固定しています。回転そのものはExcelの水平回転/垂直回転なものを矯正しているので、動き方のイメージが掴みにくいと思います。お試しください。


# その他便利機能
ビジュアル調整をやりやすくするボタンを増やしました。
![3D書式簡単制御君_visual.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329842/bf60cda6-08fd-4af4-c95e-e5ab3b489ec3.gif)

矢印の細かい形状調整できると思ってなかったので面白かったです。

- - -
物理プロダクトや建築関係のPowerPointで活きると思います。こなれた私は人力と長年の勘で合わせこんでいたものの、時間とテクニックが要る故オススメしにくかったのです。これなら使いやすいのでは？と。

そんな話をしていた同僚に渡すつもり作ったものの、私事で作ったものだしWWWには使いたい人がいるかもしれないな、と思いこのような形で公開しました。お役に立てば幸いです。
zlibで圧縮されたswfファイル（CWS）を非圧縮のswfファイル（FWS）に変換するPHPコード

Flashのswfファイルは本体データ部分が圧縮されている場合があるようです。
それを非圧縮のファイルに変換するコードです。

swfを再生表示するJSのライブラリがいくつかありますが、ものによっては圧縮されていると再生できないライブラリがあったので調べて対応しました。
他の言語や圧縮形式でもほぼ同様の処理で対応できると思います。


```PHP
<?php
// 入力ファイル
$input  = __DIR__ . '/compressed.swf';

// 出力ファイル
$output = __DIR__ . '/uncompressed.swf';

// 先頭3バイトを読み込んで、圧縮形式の判定を行う
$signature = file_get_contents($input, false, null, 0, 3);
if ($signature !== 'CWS') {
  // 圧縮で無ければ終了
  exit();
}

// 非圧縮時のシグネチャー
$signature = 'FWS';

// シグネチャーの残り部分
$header = file_get_contents($input, false, null, 3, 5);

// 本体部分をzlibでデコードしたもの
$body = zlib_decode(file_get_contents($input, false, null, 8));

// 上記を連結してSWFファイルのデータにする
$data = $signature . $header . $body;

// ファイルに書き出す
file_put_contents($output, $data);

// このままWebで出力する場合はHTTPヘッダーと共にデータを出力する
// header('Content-Type: application/x-shockwave-flash');
// echo $data;
```

が、以下のライブラリだと圧縮データにも対応しています。
ActionScriptの対応バージョンも広く、2023年現在も継続的に開発されているようなので、そもそもこちらが良いのではないかと思います。
（ただし再生時にロゴが表示されるので、それが嫌な場合には一工夫が必要）

https://ruffle.rs/
ChatGPT4.0に色々教えてもらいながらMQTT通信を使ってESP32から発信するデータをウェブダッシュボードに表示させるアプリケーションを作った

ChatGPTにいろいろと教えてもらいながら、MQTT通信でESP32から発信されるデータをDashというダッシュボードに表示するアプリケーションを構築してみました。以下のような感じで電圧と温度をブラウザ上で表示した（温度と電圧のデータはダミーデータ）。

![スクリーンショット 2023-09-18 14.01.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512829/095842fb-1c2f-a52b-c0c2-9ff8dae1f5a3.png)

# 今回の成果物
以下のGithubに置いてあります。
https://github.com/takurot/ESP32_MQTT

- ESP32のコード
- MQTTブローカーの設定（README）
- MQTTブローカーからデータを受け取ってデータベースに保存するスクリプト
- データベースを定期的に見に行って値をダッシュボードに表示するスクリプト

# 一連のChatGPTとのやり取り
https://chat.openai.com/share/bdc7c108-dbc5-46bf-9b6d-be0b8c555a7b

# コード上で修正が必要だったところ
- サーバー側のSQLの記述に、特にリクエストしていなかったtimestampが入っていて、当初動かなかった。この辺はちょっと修正しているが、その他の部分はほとんど使える。
- 証明書で暗号化通信を試みたが、なぜかMosquittoとESP32が認証ファイルエラーでつながらなかった。ChatGPTの問題というよりは、実行環境の問題のような気がしているがまだよくわかっていない。暗号化通信の部分はコードをコメント化している。ユーザー認証はちゃんと動いた。
- 以下の回答はChatGPTが間違いを認めているのがちょっと面白い。たまに細かいところの整合が取れない時があるのかも。コードは一度に生成してもらったほうがよいかもしれない。

:::note 
ChatGPT回答
1. **スクリプトの分離について**:
    一般的に、異なる役割を持つコードは別々のスクリプトやモジュールに分けることが推奨されます。これにはいくつかの理由があります：

    - **単一責任原則**: 一つのスクリプトやモジュールは一つの明確な役割や機能を持つべきです。これにより、コードの保守やデバッグが容易になります。
    - **再利用性**: 分離されたモジュールは、必要に応じて他のプロジェクトで再利用しやすくなります。
    - **可読性**: より小さな、特定の機能に特化したスクリプトは、大きな一つのスクリプトよりも読みやすくなります。

    したがって、MQTTを介してデータを受け取りデータベースに保存するスクリプトと、Dashを使用してデータベースの内容をグラフとして表示するスクリプトは、通常別々のファイルに配置するのが良いでしょう。

2. **データベース名について**:
    私の回答での不整合を指摘していただき、ありがとうございます。以前の例ではデータベースの名前として`sensors.db`を使用しましたが、このDashスクリプトでは`data.db`としてしまいました。実際には、両方のスクリプトで同じデータベース名を使用する必要があります。したがって、Dashのスクリプト中のデータベース名も`sensors.db`に修正すべきです。

前述の例から次の部分を:

```python
conn = sqlite3.connect('data.db')
```

次のように修正してください：

```python
conn = sqlite3.connect('sensors.db')
```

このように統一しておくことで、両方のスクリプトが同じデータベースを参照・操作することが確実となります。
:::

# 所感
- MQTTのこととかユーザー認証のこととか確認方法とかを聞きながら、ちょっとづつ知識を増やしてアプリケーション構築することができるので、多少時間はかかりながらも異分野のコードを短時間で作成することができる。
- ユーザー認証をする、などあとから仕様が追加になったりした場合は、全部を再作成してもらったほうがよい。
- 注意すべきポイントもその都度教えてくれる。
- 微々たる間違いはあるが、すべてを否定するほどのことでもない。よく知ってる先輩、くらいの位置づけ（多少間違うこともある）。
- 出力されるエラーについても詳しく教えてくれる。
カスタムセルの作り方

# はじめに
SwiftUI全盛期ですが、たまたまカスタムセルの作り方についてアドバイスする機会がありましたので、せっかくなのでQiitaに残したいと思います。

# カスタムセルとは
正式には、UITableViewCellクラスを派生してオリジナルのセルを作ることを指します。

UITableViewCellは、iOSのUIKitフレームワーク内でテーブルビュー(UITableView)の１行を表現するためのクラスです。
テーブルビュー(UITableView)は、リスト表示するコンポーネントです。リストのそれぞれの行はUITableViewCellインスタンスによって表現されます。

# サンプルプロジェクトを通してカスタムセルの作り方を紹介

[Githubに公開しているカスタムセルのプロジェクト](https://github.com/FromF/CustomTableViewCell)を例に作り方とポイントを紹介します。

詳しい手順は参考になりそうなサイトがありましたのでリンクしておきますのでそちらを確認してください。

## カスタムセルを作るためのファイルをXcodeに追加する

私もカスタムセルに必要なファイルの追加の仕方を忘れていたのでご紹介します。
まずはProject Navigatorで右クリックしてNew Fileを選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42735/656bed12-6505-a986-9510-623f9aa84211.png" width=400>

次にCocoaTouchClassを選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42735/1cce8ddf-d28f-0ccd-e9ec-a536d4d6a2cc.png" width=400>

最後に、SubClassをUITableViewCellを選択し、Also create XIB fileをチェックしてファイルを追加します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42735/3f42354d-25f4-fcb1-9d82-b68a2f5b85fd.png" width=400>

## カスタムセルを作る上でのポイント

### テーブルビューへの登録
UITableViewで使えるようにするためには、[register(_:forCellReuseIdentifier:)](https://developer.apple.com/documentation/uikit/uitableview/1614888-register)を実行してカスタムセルを登録する必要があります。

この時に、Xibのロードとカスタムセルの識別子が必要となります。ViewControllerにそのまま書いてもよいのですが、複数ViewControllerがあると表記ブレなどが発生しやすくなります。
そこでカスタムセルのコード上に記述することによって解決しています。

```swift:CustomTableViewCell.swift
    /// UITableViewCellの識別子
    static let identifier = "CustomTableViewCell"
    /// xibをロードするための関数
    static func nib() -> UINib {
        return UINib(nibName: "CustomTableViewCell", bundle: nil)
    }
```

上記のように`static`をつけることによってインスタンス化せずに取得、実行できるようにします。
識別子はカスタムセルのクラス名にすると重複しないのでいいと思います。

```swift:ViewController.swift
        // TableViewにカスタムセルを登録する
        tableView.register(CustomTableViewCell.nib(), forCellReuseIdentifier: CustomTableViewCell.identifier)
```

ViewControllerでは上記のようにTableViewに登録するように書けます。

### カスタムセルの高さ

```swift:CustomTableViewCell.swift
    /// UITableViewCellの高さ
    static let height: CGFloat = 60
```

こちらも同じように高さをカスタムセルの中に記述するようにするといいと思います。

```swift:ViewController.swift
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return CustomTableViewCell.height
    }
```

ViewControllerでは上記のようにします。

ViewControllerでは上記のようにTableViewに登録するように書けます。

# 最後に

昔にどこかのブログを参考にしてこのようにしたのですが、どこか今となってはわからなくなってしまいました。

１つのカスタムセルを複数のViewControllerで利用する場合にこの方法は有効だと思います。
ぜひ活用してみてください。

# 参考サイト

- [【Swift/Xcode】カスタムセル(CustomCell)を使用したTableView(テーブルビュー)の使い方](https://ios-docs.dev/customcell/)
【Java】二分探索法

## 二分探索とは

`要素がキーの昇順または降順にソートされている配列から効率よく探索を行うアルゴリズム。`

要素が昇順または降順に整列された集合に対して、探索範囲の中央に位置する値と探索する値を比較し、探索する値の方が小さければ目的の値は範囲の先頭から中央の1つ前までに、探索する値の方が大きければ目的の値は範囲の中央の1つ次から最後までに存在すると判断して、次回は探索範囲を1／2に狭めて探索することを再帰的に繰返すことで目的のデータを探索するアルゴリズムです。

### メリット
線形探索法に比べて探索範囲を半分に分割しながら探索を行うため、非常に高速になります。
二分探索法は最大でlog2(n)回の比較で済みます。つまり探索範囲が倍になったら探索回数が１回増えます。

### デメリット
データがソートされていなければ使えません。

## 二分探索のコード

```java:alg.java
class Main {
	public static void main(String[] args) {
		// 配列と見つけたい数値の用意
		int array[] = {1,2,3,4,5,6,7,8,9,10};
		int target = -2;
		
		// 二分探索プログラムを呼び出し、一致データがあるのかを判定
		int answer = search(array,target);

		if (answer == -1) {
			System.out.println("一致データなし");
		} else {
			System.out.println(answer + "番目の要素に一致します。");
		}
	}

	// 二分探索プログラム
	public static int search(int[] array, int target) {
		int head = 0;
		int tail = array.length - 1;
		int center = 0;

		while(head <= tail){
			center = (head + tail) / 2;
			if(array[center] == target){
				return center;
			}else if(array[center] < target){
				head = center + 1;
			}else{
				tail = center - 1;
			}
		}
		return -1;	
	}

}
```

### Arraysクラスのメソッドを使った二分探索のコード
前述の二分探索コードは自前で組んだアルゴリズムになりますが、Arrayクラスのメソッドに既に定義されており、このメソッドを使えば１行で二分探索を実行できます。



```diff_java
- int answer = serch(array,target);
+ int answer = Arrays.binarySearch(array,target);

- if (answer == -1) {
+ if (answer < 0) {
```

前述のmainメソッド内のコードを上記のように訂正し、searchメソッドを削除すると同じ結果が得られます。

`binarySearch`メソッドの戻り値が異なるため、if文の条件式を変更しています。
`binarySearch`メソッドは、`target`（探索したい数値）が存在する場合は、指定した `array` における指定した`target`が入っている要素を返します。
逆にtargetに一致するデータがない場合は負の数値を返します。
`target`が`array`内のどの要素よりも大きい場合は、返される負の数値は最後の要素のインデックス+1、つまり前述の'array'であれば-11を返します。
`target`が`array`内の１つ以上の要素より小さい場合は、返される負の数値は`value`より大きい最初の要素のインデックスのビットごとの補数、つまり前述の'array'であれば-1を返します。

https://learn.microsoft.com/ja-jp/dotnet/api/system.array.binarysearch?view=net-7.0#system-array-binarysearch(system-array-system-object)