OmniAICreator/Qiita-1.07M huggingface dataset:
ABC373回答メモ

# 0.はじめに
　新ARCをちらっと見てみましたが、やはり難易度は高く
　レーティングからも外れているので、今後もチラ見するくらいにとどめようかと思いました。
　ABC373は、A~Cはカンタンでしたが、D以降は難しく、3問のみACにとどまりました。
　それでもレートは+2と微増でした。ここら辺がまぁ実力なんでしょう。


# 1.A - September
　9月用の問題。単純に文字列を12回読み込み
　それぞれ、文字列の長さと、読み込み回数を比較し
　一致していれば変数ansカウントアップし
　最後にansを出力して終了としました。

　https://atcoder.jp/contests/abc373/submissions/58182428

# 2.B - 1D Keyboard
　ピアノ系問題に通ずるものがあるなと思いつつとりかかり。
　それぞれの文字の位置を記憶しておき
　最初Aの位置を変数preにセットし変数ansを0で初期化
　その後、B～Zまで
　　preとチェックアルファベットの位置の差をansに加算していき
　　加算後preをチェックアルファベットの位置で置き換え
　とチェックしていき
　最後にansを出力して終了としました。

　https://atcoder.jp/contests/abc373/submissions/58192787

# 3.C - Max Ai+Bj
　近年まれに見る簡単なC問題。騙されているのかと思うほど。
　まぁ、MAXを使える言語化とかも影響しそうですが。
　リストAのmax値とリストBのmax値を足し算して終了でACでした。

　https://atcoder.jp/contests/abc373/submissions/58196231


# 4. 	D - Hidden Weights
　コンテスト中は、なんとか遅延セグメント木で正解しようと
　四苦八苦していましたが、上手くいかず時間切れ
　
　コンテスト後解説を見たら、深さ優先探索を繰り返せば済むと知り
　思い込みはよくないなと思いました。

　収穫としては、pypyの再帰は遅いので、いつも再帰の時はcPythonとかで提出してましたが
```
import pypyjit
pypyjit.set_param('max_unroll_recursion=-1')
```
を使えば、pypyでも遅くならないと知ったことでした。　

　https://atcoder.jp/contests/abc373/submissions/58247216


以上
OOPの三大要素について

# はじめに
　オブジェクト指向(OOP)には3つの三大要素があります。クラス、ポリモーフィズム、継承がその三大要素です。順に概要とメリットを説明していきます。


# クラス
　クラスとは、変数とメソッドをまとめたものです。そのメリットは主に以下の3つです。

* まとめる
* 隠す
* たくさんインスタンスを作る

順に説明していきます。

　クラスによって変数とメソッドをまとめることで、コード全体が整理され、見やすくなります。また、グローバル変数の適用範囲を絞ることができ、グローバル変数に関してエラーが出た際、コード全体ではなくそのクラスの部分だけを確認すればよいので、対応が楽になります。

　次に「隠す」とは、クラス内で定義した変数またはメソッドを外部からアクセスできないようにすることです。こうすることで、変数に不適切な値が入った場合、その変数にアクセスできるのは同じクラスにまとめたメソッドのみとなり、問題の原因を特定しやすくなります。

　最後に、クラスを定義するとそのインスタンスをいくらでも作ることができ、同種かつ複数の情報を扱いやすくなるのがメリットです。

# ポリモーフィズム
　ポリモーフィズムとは、呼び出す側の形式を統一することを指します。

```python
#親クラスの定義
class Animal():
    def speak(self):
        pass

#子クラスの定義
class Cat(Animal):
    def speak(self):
        return 'にゃー'
    
class Dog(Animal):
    def speak(self):
        return 'ワン'
        
#ポリモーフィズムで同一の呼び出し方が可能
def animal_speak(animal):
    print(animal.speak())

dog=Dog()
cat=Cat()

animal_speak(dog)　#ワン
animal_speak(cat)　#にゃー
```

DogとCatは異なるクラスですが、ポリモーフィズムによってどちらの speak メソッドも同じように呼び出すことができます。このように、呼び出す側に変更を加えることなく、複数の異なるクラスに対して同じ処理を行えるのがポリモーフィズムの大きなメリットです。

# 継承
　継承とは、あるクラスの変数やメソッドをそのまま他のクラスで使えるようにする仕組みです。


```python
#親クラス
class Animal():
    def speak(self):
        pass

    def explain(self):
        print("動物とは生物学における生物の分類群の一つ(Wikipewdiaより)")
    
#Animalクラスを継承
class Cat(Animal):
    def speak(self):
        return 'にゃー'
    
cat=Cat()

print(cat.speak()) #にゃー
cat.explain()　　　#動物とは生物学における生物の分類群の一つ(Wikipewdiaより)
```

Cat クラスでは explain メソッドを定義していませんが、Animal クラスを継承しているため、explain メソッドを使うことができます。これにより、コードの重複を避けることができるのが大きなメリットです。

# 参考文献
平澤 章. オブジェクト指向でなぜつくるのかー知っておきたいプログラミング、UML、設計の基礎知識ー.日経BP社,2004,[317]
WordVBAで文書中に特定のフォント色が使われているかチェックする

WordVBAで、何かの処理を実行する前に、特定のフォントカラー（例えば赤色）が使われているかチェックしたい場合があります。
（例えば、その処理で特定の条件に該当する場合に、同じフォントカラーにする処理をする場合は、元々使っていた色と重複すると、処理実行によって
そのフォントカラーになった部分か区別がつかないと困りますよね。）

下記のコードで、文書中に特定のフォントカラーが使われているかチェックを行うことができます。

※noteでの同様の記事をアップロードしています。記事は[こちら](https://note.com/keiri_info/n/nde98df08f3ca)。

```vb:WordVBA
Sub sb赤色のフォントが使われているかチェックする()
    Dim myRange
    Dim foundFlag As Boolean
    foundFlag = False ' フラグを初期化

    ' アクティブドキュメントの全範囲をループ
      Set myRange = ActiveDocument.Range(0, 0)
      With myRange.Find
        .Text = ""
        .Forward = True
        .Font.Color = wdColorRed
        .Wrap = wdFindStop
        .Execute
        If .Found = True Then
            foundFlag = True
        End If
      End With
      
    ' 赤色フォントが見つかった場合にメッセージを表示
    If foundFlag Then
        MsgBox "赤色のフォントが使用されています。", vbInformation
    Else
        MsgBox "赤色のフォントは使用されていません。", vbInformation
    End If
End Sub
```

別のメイン処理で上記を行いたい場合には、Subプロシージャではなく、Functionでやるとよいと思います。

```vb:WordVBA
Function zf赤色のフォントが使われているか(a_doc As Document) As Boolean
'Booleanの初期値はFalseのため、見つからなければFalseを返す
    Dim myRange
    
    'アクティブドキュメントの全範囲を検索
    Set myRange = ActiveDocument.Range(0, 0)
    With myRange.Find
      .Text = ""
      .Forward = True
      .Font.Color = wdColorRed
      .Wrap = wdFindStop
      .Execute
      If .Found = True Then
          zf赤色のフォントが使われているか = True
      End If
    End With
    
End Function
```
その上で、使用しているフォントカラーを一時的に別の色に変更したいという場合は、下記をご利用ください。
なお、データ型をWdColor型にしてフォントカラーを指定していますが、データ型をLong型へ変更してRGBで指定することも可能です。

```vb:WordVBA
Sub sbテキストカラーを赤からスカイブルーへ変更()
    Call sbテキストカラー変更(ActiveDocument, wdColorRed, wdColorSkyBlue)
    Dim myMsg As String 'メッセージボックス用変数
    myMsg = "処理が終了しました。"
    MsgBox myMsg, , "処理結果通知"
End Sub

Sub sbテキストカラー変更(ByVal a_doc As Document, ByRef a_beforeColor As WdColor, ByRef a_afterColor As WdColor)
    Dim myRange
    Set myRange = a_doc.Content
    Call sbSetting(True)  '画面更新OFF等の初期設定ON

    With myRange
        .Find.Font.Color = a_beforeColor
        .Find.Replacement.Font.Color = a_afterColor
        .Find.Execute Replace:=2
    End With
    
    ' 終了処理
    Set myRange = Nothing
    Call sbSetting(False) '画面更新OFF等の初期設定OFF
End Sub

Public Sub sbSetting(flg As Boolean)
  If flg Then
    Application.ScreenUpdating = False                  '画面更新の停止
    Application.DisplayAlerts = False                   '画面警告の表示の停止
  Else
    Application.ScreenUpdating = True                   '画面更新の開始
    Application.DisplayAlerts = True                    '画面警告の表示の開始
  End If
End Sub
```
ブラシレスモータドライバの製作

# はじめに
今回はPCBgogo様の協賛で基板を作らせていただきました。
ぜひこちらのリンクからPCBgogo様のページを見ていただければ幸いです。

https://www.pcbgogo.jp/promo/nichicon1

<h1>目次</h1>

[概要](#概要)
[回路図](#回路図)
[製作した基板](#製作した基板)
[動作テスト](#動作テスト)
[免責事項](#免責事項)
[最後に](#最後に)

# 概要
今回はPCBgogo様とのコラボということで基板を製造していただく機会を頂きました。
せっかくのプリント基板なので、回路の規模が大きく、配線が大変な物をプリント基板で簡単に作ろうと思いブラシレスモータドライバの基板を作ってみました。

# 回路図
モータドライバの回路図は以下の通りです。
（準備中...）
[Seeeduino XIAO](https://akizukidenshi.com/catalog/g/g115178/)で制御していて、FETを駆動するゲートドライバには[IR2110](https://akizukidenshi.com/catalog/g/g106193/)を3つ、モータへの出力回路にはNch MOSFETの[TK100E06N1](https://akizukidenshi.com/catalog/g/g108420/)を6つ使用しています。ブラシレスモータの3相の信号をフィルタを通してSeeeduino XIAOにフィードバックして制御できるようになっています。

# 製作した基板
部品を実装する前の基板です。
表面にはシルクでQRコードなども入れてみました。部品の値も非常に見やすいです。
配線パターンも問題なく、部品を実装するパッドのメッキもきれいです。
![BLDCdriver1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/7538ebf9-e136-d2c5-1588-3ce59f7a7ef8.jpeg)
裏面です。
![BLDCdriver2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/5f23eb22-6af7-fa26-f8ae-f6e1a1ee7026.jpeg)
少し斜めから撮ってみた写真です。スルーホールのメッキや基板の端面の処理が丁寧ですね。
![BLDCdriver3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/e6a8a72d-e869-04a9-72e5-4572abbb4758.jpeg)

部品を実装しました。
やはりプリント基板で作ると美しい。
![BLDCdriver4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/a780251b-af10-f679-c3c8-5870ef484eee.jpeg)
ヒートシンクも付けました。
![BLDCdriver5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667950/72231a7b-dfff-8116-ae99-f40d10252564.jpeg)

# 動作テスト
組み立てが終わったので、モータも繋いで通電してみました。
しかし、動きがおかしく、バッテリーが熱い。
FETがショートしているとみてチェックしてみるとローサイドのFETが壊れているようです。何となく嫌な予感はしていたのですが配線をチェックすると、ゲートドライバ周辺の配線設計を間違えていました...（悔しい）
というわけで、動作テストは終了です。ちゃんと何度も設計確認してから発注しようと肝に銘じたのでした。
（念のため書いておきますが、基板の製造で問題があったわけではありません）

# 免責事項
記事の内容は可能な限り正確に書くようにしていますが、間違っていることがあるかもしれません。この記事を見て興味を持って作ってもらうのは大変うれしいことですが、作る際にはあくまで自己責任でお願いします。

# 最後に
最後までお読みいただきありがとうございました。
ブラシレスモータの制御回路を作りたい方などの参考になれば幸いです。
質問やアドバイス等ありましたら[X(@_electro_master)](https://x.com/_electro_master)にご連絡ください。
今回は設計にミスがありましたが、基板は問題なく綺麗に製造されていました。
皆様もPCBgogoで基板を作ってみてはいかがでしょうか。
この記事を書くにあたって基板の協賛のお話をくださったPCBgogoマーケティング部門の葉様に感謝申し上げます。
JavaScriptでiOSのクリップボードにコピー-RilsTIL(1h)

## iOSのクリップボードにコピーする

```javascript:clipboard_controller.js
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
  copy(event) {
    event.preventDefault();
    // ここにデータをfetchして加工するプログラムを記述
    copyClipBoard(resData); //取得したデータをcopyClipBoardにわたす。
    
    const copyClipBoard = (targetValue) => {
      if (navigator.clipboard) {
        navigator.clipboard
          .writeText(targetValue)
          .then(() => {
            alert("Successfully copied");
          })
          .catch((err) => {
            console.error("Error:", err);
            fallbackCopyText(targetValue);
          });
      } else {
        console.warn("Clipboard API is not supported.");
        fallbackCopyText(targetValue);
      }
    };
    const fallbackCopyText = (text) => {
      // iOSの互換性のためのフォールバック
      const textarea = document.createElement("textarea");
      textarea.value = text;
      textarea.style.position = "absolute";
      textarea.style.width = "300px";
      textarea.style.height = "400px";
      textarea.style.top = "0";
      textarea.style.right = "0";
      textarea.style.zIndex = "1000";
      document.body.appendChild(textarea);
      textarea.select();
      setTimeout(() => {
        document.body.removeChild(textarea);
      }, "5000");
    };
  }
}
```
- WebアプリのボタンでiOSのクリップボードにコピーする方法です。
- navigator.clipboard.writeText(targetValue)が基本です。
```text:iOSのエラー
Unhandled Promise Rejection: NotAllowedError:
The request is not allowed by the user agent or
the platform in the current context,
possibly because the user denied permission.
```
- iOSではエラーになります。
- とりあえずテキストボックスを表示して自分でコピーしてもらいます。

## 参考
https://stimulus.hotwired.dev/handbook/building-something-real
- iOSの逃げ方はChatGPTさんです。

## Webインスペクタ
- iPadとMacを繋いで、開発者ツールを開く方法です。

▼ iPad 側の設定

ホーム画面から、［設定］から［Safari］を開く

画面一番下の［詳細］を開き、［Webインスペクタ］をONにする

▼Macを側の設定

Safariを開く

Safariのメニューから、［環境設定］を開く

［詳細］タブをクリックし、［メニューバーに”開発”メニューを表示］にチェックを付ける

[開発]を開き、iPadをクリックする

iPadで許可をタップ

## CSSのcalc
```javascript:calcとzIndex
//bad
textarea.style.right = "calc(50vw-200px)"

//good
textarea.style.right = "calc(50vw - 200px)"

//z-index => zIndex
textarea.style.zIndex = "1000"
```
- 小さいことですが、calcのエラーについて、スペースを忘れないように気をつけます。
- zIndexやclassNameなど他にもJavaScriptの書き方がありそうです。
【Linux】検索コマンド関連

# Linuxコマンド解説: 調査関連

Linuxでは、ファイルやディレクトリを検索するための強力なコマンドがいくつかあります。以下に、よく使用される調査関連のコマンドについて解説し、それぞれの詳細なオプションを確認できるリンクを付けました。

## 1. `find`

`find`コマンドは、指定した条件に基づいてファイルやディレクトリを検索するためのコマンドです。

### 基本的な使い方

```bash
find /path/to/search -name "filename"
```

### 主なオプション

- `-type`: 検索するファイルのタイプを指定（例: `f`はファイル、`d`はディレクトリ）
- `-size`: サイズで検索（例: `+100M`は100MB以上）
- `-mtime`: 最終更新日の範囲で検索

### 詳細なオプション

[findコマンドの詳細](https://man7.org/linux/man-pages/man1/find.1.html)

---

## 2. `locate`

`locate`コマンドは、事前に作成されたデータベースを使用してファイルを迅速に検索します。通常、`updatedb`コマンドでデータベースが更新されます。

### 基本的な使い方

```bash
locate filename
```

### 主なオプション

- `-i`: 大文字と小文字を区別しない検索
- `-c`: 一致するファイルの数を表示

### 詳細なオプション

[locateコマンドの詳細](https://man7.org/linux/man-pages/man1/locate.1.html)

---

## 3. `which`

`which`コマンドは、指定したコマンドがどのパスに存在するかを表示します。シェルで実行可能なファイルを探すのに便利です。

### 基本的な使い方

```bash
which command_name
```

### 詳細なオプション

[whichコマンドの詳細](https://man7.org/linux/man-pages/man1/which.1.html)

---
listRowSeparatorの設定が効かないとき

# listRowSeparatorとは
ListのSeparator(下線)を表示有無とSeparatorのPaddingを制御できるModifierです。
デフォルトではSeparatorがついているので、非表示にしたいもしくはPaddingをデフォルトから変更したい場合に使用する必要があります。

`デフォルト`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3359094/e23e61d5-5096-7525-139a-0735427b3a31.png)

`.listRowSeparator(.hidden)`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3359094/6210b772-1833-cb3b-77ec-221ed3351d65.png)


# ハマったところ
以下のようにModifierを設定しても、Separatorが非表示になってくれませんでした。

```swift
struct ListSampleView: View {
    
    var body: some View {
        List {
            ForEach (0..<10) { index in
                Text("\(index)")
            }
        }
        .listRowSeparator(.hidden)
        .listStyle(.plain)
    }
}
```

# 解決策
`List`ではなく、`List`内の`ForEach`に対して`listRowSeparator`を設定することで効果が効かせられました。

```swift
struct ListSampleView: View {
    
    var body: some View {
        List {
            ForEach (0..<10) { index in
                Text("\(index)")
            }
            .listRowSeparator(.hidden)
        }
        .listStyle(.plain)
    }
}
```

公式のドキュメントの使用例でも`List`内要素に設定してましたね。
なんとなく`List`自体に設定するものと思い込んでいました、、

https://developer.apple.com/documentation/swiftui/view/listrowseparator(_:edges:)


公式ドキュメントの以下記述から、行ごとにSepalatorの設定をするものなので、`List`内要素に設定する必要があるのかなと解釈しました。
>Separators can be presented above and below a row. You can specify to >which edge this preference should apply.
>
>This modifier expresses a preference to the containing List. The list >style is the final arbiter of the separator visibility.

試しに0の行だけSeparator無しにできるのかなと思い試してみたらできました！
こういう制御できるのは知らなかったので勉強になりました。

```swift
struct ListSampleView: View {
    
    var body: some View {
        List {
            ForEach (0..<10) { index in
                if index == 0 {
                    Text("\(index)")
                        .listRowSeparator(.hidden)
                }
                else {
                    Text("\(index)")
                }
            }
        }
        .listStyle(.plain)
    }
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3359094/52ea0d41-a026-ac8b-8550-00cf6b555247.png)
【OpenAI o1】にお酒のカクテルについて聞きました（続編・RaRメソッド）


　どうも、カーブミラーです。

　今回は、【OpenAI o1】にお酒のカクテルについて聞きました、の続編です。RaRメソッドを使うことで、ChatGPTにどのように伝わっているのかを知ります。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。　あしからず。
:::
　まずは、ニュースです。

　ChatGPTのアプリの
　　Advanced Voice Modeですが、
　　　英国からのアクセスが
　　　　できるようになりました。
　　　　　[OpenAI公式ポスト](https://x.com/OpenAI/status/1839896474571723164?t=K2atF9ZRVFIfG27v1nCYXA&s=19)

　知り合いの子が
　　“EU諸国は？”と
　　　嘆いていますが😅
***
　さて、本題です。

　昨日（2024/09/28）は、
　　【OpenAI o1】に
　　　お酒のカクテルについて
　　　　聞きました。
[【OpenAI o1】にお酒のカクテルについて聞きました。](https://qiita.com/kabumira/items/e91f20701628ca6e068a)

　そこで
　　【OpenAI o1】が
　　　ユーザーの意図を
　　　　読み取って、
　　　　　すべての情報を
　　　　　　吐き出してきましたね。

　今回は、
　　その続きとして
　　　とあるPrompt手法を
　　　　見つけたので、
　　　　　試します。
***
　記事をアップしたあと、
　　たまたま過去の記事を
　　　見つけて、試してみました。

　その記事がこちら。
　　[【ChatGPT無】RaRメソッドとは？　効果は？](https://qiita.com/kabumira/items/ed96e8a1d4205da2a4ea)

　2023/11/15の記事でした。

　RaRメソッドというのは、
　　Rephrase and Respondの頭文字。
　　　言い換えと応答という意味です。

　これは
　　与えたPromptを
　　　生成AIがどのように
　　　　解釈しているのかを
　　　　　表してくれるものでした。

　例えば、
***
***●user***
（RaRメソッドPrompt）
「カクテルについて教えてください。」

***ChatGPT***
「カクテルについて詳しく教えてください。具体的には、カクテルの歴史や起源、代表的な種類とその特徴、家庭で簡単に作れるレシピやプロ向けの高度な作り方、おすすめのカクテルや最新のトレンド、さらにカクテルを楽しむ際のマナーやエチケットについても知りたいです。」
***
　と出力してくれます。

　本来ならば、
　　ここまでのPromptを
　　　こちらで記述しなければ
　　　　いけないのですが、
　　　　　さすがに人間が
　　　　　　初見でここまでは
　　　　　　　書けませんよね。

　“Promptは、具体的に記述しろ”と
　　よく言われますが、
　　　はじめて間もない人には
　　　　無理でしょう。

　そこに
　　この手法を取り入れて
　　　具体的にする、
　　　　そして、それを
　　　　　本来の目的に合わせて
　　　　　　修正すればいいわけです。

　こちらのPromptが
　　RaRメソッドのそれです。
```Text:RaRメソッドPrompt
下記の質問を、より良く答えるために言い換えて拡張してください。元の質問の情報を全て維持してください。

「✘✘✘」
```

　実は、RaRメソッドを
　　知る前から、自分でも
　　　やっていました。
```Text:RaRメソッドPrompt（我流）
以下の指示プロンプトを、あなたが理解しやすい指示プロンプトに変更してください。

「✘✘✘」
```

　こちらを【OpenAI o1】に使うと
　　こうなります。
***
***o1-mini***
思考時間: 5 秒
>改善しているプロンプト
カクテルについての理解を深めるため、質問をわかりやすく言い換えている。
>
>整理して再構築
「カクテルの教え方を再構築し、指示をわかりやすくすることが求められている。日本語での説明が必要。」
>
>再構築の提案を検討する
「カクテルについて教えてください」のリフレーズを模索中。カクテルの基本情報、歴史、種類、レシピ、おすすめ、最新トレンド、楽しむ際のマナーを含めて再構築を提案している。
>
>情報を提供する
カクテルの歴史、種類、レシピ、おすすめ、最新トレンド、マナーについて詳細に教えているね。

承知しました。以下のように指示プロンプトを言い換えて、より具体的かつ明確にしました。これにより、カクテルに関する包括的な情報を提供しやすくなります。

---

**「カクテルについて詳しく説明してください。具体的には、以下の点に触れてください：**

1. **カクテルの定義と歴史**  
   カクテルの起源や発展過程について。

2. **代表的なカクテルの種類と特徴**  
   マティーニ、モヒート、マルガリータなど、主要なカクテルの紹介とそれぞれの特徴。

3. **カクテルのレシピと作り方**  
   自宅で簡単に作れる基本的なレシピから、プロ向けの高度な作り方まで。

4. **おすすめのカクテルや最新トレンド**  
   季節に合ったおすすめカクテルや、現在人気の高いトレンドについて。

5. **カクテルを楽しむ際のマナーやエチケット**  
   バーでの注文方法や、カクテルを楽しむ際の基本的なマナー。

6. **カクテルに関連する文化やイベント**  
   カクテルにまつわる文化的背景や、関連するイベント情報。

---

このように具体的な項目を含めることで、カクテルに関する詳細かつ体系的な情報を得ることができます。
***

　どちらが良いかは、
　　みなさんが判断して
　　　使ってください。

　私は、今回のカクテルについては
　　RaRメソッドPromptを使い、
　　　必要ない部分を削る感じでの
　　　　使用になるでしょうね。

　別のパターンでは、
　　我流の方を使うかもしれません。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
WordVBAでドキュメント名を取得する

ExcelVBAでは、色々なコードが公開されていますが、WordVBAでは参考になるもサイトが少ないので、自身の勉強も兼ねて、いくつかのコードを公開していきたいと思います。

これから紹介するのは、WordVBAでドキュメント（文書）のファイル名を取得するコードです。
※同一内容をnoteにも執筆しています。記事は[こちら](https://note.com/keiri_info/n/na85de159e8a2)

```vb: WordVBA
Sub sb文書名取得テスト()
    Debug.Print zfDocumentName(ActiveDocument, a_拡張子:=True)      'Macroテスト.docm
    Debug.Print zfDocumentName(ActiveDocument, a_拡張子:=False)     'Macroテスト
End Sub

Public Function zfDocumentName(a_doc As Document, Optional a_拡張子 As Boolean = True) As String
'ドキュメント名を取得するユーザー定義関数
'※引数にTRUEを指定するか何も指定しないと拡張子付きで､引数にFALSEを指定すると拡張子なしでファイル名を返すユーザー定義関数

  Dim doc_name As String
  doc_name = a_doc.Name

  If a_拡張子 = True Then
    zfDocumentName = doc_name
  Else
    zfDocumentName = Left(doc_name, InStrRev(doc_name, ".") - 1)
  End If
 
End Function
```

基本的には拡張子ありの場合には、「ActiveDocument.Name」で取得すればよいので、上記コードを使用する必要はありません。
しかし、拡張子なしのファイル名を取得したい場合には、上記コードを利用すれば、簡単に取得可能です。
モバイルアプリとフロー



+ [モバイルで画面フローを使う時の制限](https://qiita.com/Keiji_otsubo/items/bc53f220d02930dfac8b)
+ [モバイルアプリで画面フローを使って検索を少し便利にする](https://qiita.com/Keiji_otsubo/items/6301ce8fc8aee88290d6)
【Linux】ファイルとディレクトリ操作

# Linuxコマンド解説

Linuxでは、ファイルとディレクトリの操作に多くの便利なコマンドが用意されています。以下に、よく使用されるコマンドについて解説し、それぞれの詳細なオプションを確認できるリンクを付けました。

## 1. `cd` (Change Directory)

`cd`コマンドは、現在の作業ディレクトリを変更するために使用します。

### 基本的な使い方

```bash
cd /path/to/directory
```

### 詳細なオプション

[cdコマンドの詳細](https://man7.org/linux/man-pages/man1/cd.1.html)

---

## 2. `ls` (List)

`ls`コマンドは、ディレクトリ内のファイルやサブディレクトリを一覧表示します。

### 基本的な使い方

```bash
ls
```

### 詳細なオプション

[lsコマンドの詳細](https://man7.org/linux/man-pages/man1/ls.1.html)

---

## 3. `mkdir` (Make Directory)

`mkdir`コマンドは、新しいディレクトリを作成します。

### 基本的な使い方

```bash
mkdir new_directory
```

### 詳細なオプション

[mkdirコマンドの詳細](https://man7.org/linux/man-pages/man1/mkdir.1.html)

---

## 4. `touch`

`touch`コマンドは、新しい空のファイルを作成するか、既存のファイルの最終更新日時を変更します。

### 基本的な使い方

```bash
touch filename.txt
```

### 詳細なオプション

[touchコマンドの詳細](https://man7.org/linux/man-pages/man1/touch.1.html)

---

## 5. `rm` (Remove)

`rm`コマンドは、ファイルを削除します。注意深く使用する必要があります。

### 基本的な使い方

```bash
rm filename.txt
```

### 詳細なオプション

[rmコマンドの詳細](https://man7.org/linux/man-pages/man1/rm.1.html)

---

## 6. `rmdir` (Remove Directory)

`rmdir`コマンドは、空のディレクトリを削除します。

### 基本的な使い方

```bash
rmdir empty_directory
```

### 詳細なオプション

[rmdirコマンドの詳細](https://man7.org/linux/man-pages/man1/rmdir.1.html)

---

## 7. `cat` (Concatenate)

`cat`コマンドは、ファイルの内容を表示したり、複数のファイルを結合したりします。

### 基本的な使い方

```bash
cat filename.txt
```

### 詳細なオプション

[catコマンドの詳細](https://man7.org/linux/man-pages/man1/cat.1.html)

---

## 8. `less`

`less`コマンドは、ファイルの内容をページ単位で表示し、スクロールして閲覧することができます。

### 基本的な使い方

```bash
less filename.txt
```

### 詳細なオプション

[lessコマンドの詳細](https://man7.org/linux/man-pages/man1/less.1.html)

---

## 9. `cp` (Copy)

`cp`コマンドは、ファイルやディレクトリをコピーします。

### 基本的な使い方

```bash
cp source.txt destination.txt
```

### 詳細なオプション

[cpコマンドの詳細](https://man7.org/linux/man-pages/man1/cp.1.html)

---

## 10. `mv` (Move)

`mv`コマンドは、ファイルやディレクトリを移動したり、名前を変更したりします。

### 基本的な使い方

```bash
mv oldname.txt newname.txt
```

### 詳細なオプション

[mvコマンドの詳細](https://man7.org/linux/man-pages/man1/mv.1.html)

---

## 11. `ln` (Link)

`ln`コマンドは、ファイルのリンクを作成します。通常のリンク（ハードリンク）とシンボリックリンクを作成できます。

### 基本的な使い方

- ハードリンク:
  ```bash
  ln original.txt link.txt
  ```

- シンボリックリンク:
  ```bash
  ln -s original.txt symlink.txt
  ```

### 詳細なオプション

[lnコマンドの詳細](https://man7.org/linux/man-pages/man1/ln.1.html)
【python】佐々木琴子さん、ツイート文例ツール

# はじめに
声優の佐々木琴子さんが、毎日おいしかった食事を定型文でツイートされていらっしゃるので、ツイート文例ツールを作りました

## どんなツール?
佐々木琴子さんのツイートに
> **今日はうどんを食べました。美味しかったです**

が食べもの以外の部分をテンプレートにしています。今回はテンプレートの作成を
実装しました。

## 実装したコード
```python
# 佐々木琴子さんツイート用BOT作成ツール

food = ""
while True:
  print("今日美味しかった食べ物を入力してください。")
  food = input()
  food = food.replace("　","")
  check_food = food.replace(" ","")
  food_length = len(check_food)
  if food_length == 0:
    print("文字が入力されていません")
  elif food_length > 0:
    break

answer_sentense = f"今日は{food}を食べました。美味しかったです。"
print(answer_sentense)

```

## 実行結果
![kotoko.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/790337bc-be34-eca4-19a4-056d0a5b0c7b.jpeg)

# 最後に
Xに自動投稿してみたいです
【vs code】新規ディレクトリとファイルの楽な作り方


新規ファイル作成でディレクトリも指定すれば、新規フォルダ作成→新規作成しなくても下記のようにすれば楽に作成できる。

![スクリーンショット 2024-09-29 11.29.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587166/52862e66-c4d6-9e82-3ba4-e872000877b9.png)
Salesforce の承認プロセスでコメント フィールドを必須にする方法



+ [How to make Comments field mandatory in Approval Process in Salesforce](https://www.gammone.com/en/programming/how-to-make-comments-field-mandatory-in-approval-process-in-salesforce)

Salesforce では、承認プロセスのアクションを設定することは可能ですが、現時点では承認プロセスでフィールドを必須にすることはできません。これは、検証ルールを使用して解決できる簡単な問題であると考えることができます。残念ながら、現時点では、承認プロセスでフィールドを必須にするために検証ルールを使用することもできません。

ただし、 Flow を実装することで、このニーズを解決する回避策があります。

フローを構築する前に、フィールド更新アクションで「フィールド変更後にワークフロー ルールを再評価する」をマークします。これにより、承認プロセスが他の自動化 (この場合はフロー) をトリガーするようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/2beda238-5c6d-9d6b-554c-22abc45c2719.png)


ここで、承認プロセスのコメントを必須にするフローを構築する必要があります。


まず、承認ステータスが「拒否」になったときに実行される、新しい (保存/高速フィールド更新の前) レコード トリガー フローを作成する必要があります。これは単なる例であり、任意のフィールドを使用できます。承認プロセスによって更新されるフィールドであることを確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/136a0e07-568d-c077-ebfb-68526351ff74.png)


その後、アカウントに関連する最後のプロセスインスタンスレコードを取得するために、レコードの取得要素を追加する必要があります。プロセスインスタンスとは、承認プロセスを意味します。TargetObjectId に関連するレコードを取得するための条件を設定し、CreatedDateで並べ替えるようにしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7ca469d1-d227-89bd-a406-075ae1f64a7d.png)


その後、前のステップで見つかったプロセス インスタンスに関連する最後のプロセス インスタンス ステップレコードを取得するために、レコードの取得要素を追加する必要があります。拒否されたステップを取得するための条件を設定し、 CreatedDateで並べ替えるようにしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f2458c15-dc7c-6f48-79b3-5fa25244f593.png)

ここで、見つかったプロセス インスタンス ステップにコメントがあるかどうかを確認するために、決定要素を追加する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/850ac934-39f9-edbc-58ee-90782cd7bf90.png)

コメントフィールドが空白の場合は、エラー メッセージを表示します。そのため、エラー メッセージを表示するために、カスタム エラー要素を追加できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/54bd95db-14c9-8473-1ff8-abae358e17fe.png)

最終的に、フローは次のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5c458223-4d75-9c8f-64f6-30f61e1ae779.png)

ここで、コメントを入力せずにレコードを拒否しようとすると、エラー メッセージが表示されます。

重要！

フローが完全に期待どおりに機能しなかったというケースは、多くの人に起こる可能性があります。これは、フィールド更新を「最終拒否アクション」セクションではなく「拒否アクション」セクションに配置したことが原因です。

今では間違いなく動作します! 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6b30f61b-5709-b6f5-d07d-c776a780d616.png)
paiza.ioでmysql その11

# 概要
paiza.ioでmysqlやってみた。
練習問題やってみた。

# 練習問題
JOINを使え。

# サンプルコード

```
create table products(
    id integer,
    name VARCHAR(100),
    description	TEXT,
    price integer,
    category_id	integer	
);

create table categories(
    id integer,
    name VARCHAR(100)	
);

insert into products(id, name, description, price, category_id) value
(1,	"卵",	"3日以内に採れた新鮮な鶏の卵です",	250,	1),
(2,	"スマートフォン",	"最新のスマートフォンです。",	15000,	3),
(3,	"ノートパソコン",	"高性能なノートパソコンです。",	200000,	3),
(4,	"デスク",	"オフィス用のデスクです。",	30000,	4),
(5,	"椅子",	"快適な座り心地の椅子です。",	1000,	4),
(6,	"タブレット",	"高性能なタブレットです。",	60000,	3),
(7,	"なぞのガラクタ",	"正体不明のガラクタです。",	100,	NULL);

insert into categories(id, name) value
(1,	"食品"),
(2,	"書籍"),
(3,	"電子機器"),
(4,	"家具");

SELECT *
FROM products 
CROSS JOIN categories;

SELECT *
FROM products
INNER JOIN categories ON products.category_id = categories.id;


SELECT *
FROM products
LEFT OUTER JOIN categories ON products.category_id = categories.id;


SELECT *
FROM products
RIGHT OUTER JOIN categories ON products.category_id = categories.id;






```

# 実行結果

```
id	name	description	price	category_id	id	name
1	卵	3日以内に採れた新鮮な鶏の卵です	250	1	4	家具
1	卵	3日以内に採れた新鮮な鶏の卵です	250	1	3	電子機器
1	卵	3日以内に採れた新鮮な鶏の卵です	250	1	2	書籍
1	卵	3日以内に採れた新鮮な鶏の卵です	250	1	1	食品
2	スマートフォン	最新のスマートフォンです。	15000	3	4	家具
2	スマートフォン	最新のスマートフォンです。	15000	3	3	電子機器
2	スマートフォン	最新のスマートフォンです。	15000	3	2	書籍
2	スマートフォン	最新のスマートフォンです。	15000	3	1	食品
3	ノートパソコン	高性能なノートパソコンです。	200000	3	4	家具
3	ノートパソコン	高性能なノートパソコンです。	200000	3	3	電子機器
3	ノートパソコン	高性能なノートパソコンです。	200000	3	2	書籍
3	ノートパソコン	高性能なノートパソコンです。	200000	3	1	食品
4	デスク	オフィス用のデスクです。	30000	4	4	家具
4	デスク	オフィス用のデスクです。	30000	4	3	電子機器
4	デスク	オフィス用のデスクです。	30000	4	2	書籍
4	デスク	オフィス用のデスクです。	30000	4	1	食品
5	椅子	快適な座り心地の椅子です。	1000	4	4	家具
5	椅子	快適な座り心地の椅子です。	1000	4	3	電子機器
5	椅子	快適な座り心地の椅子です。	1000	4	2	書籍
5	椅子	快適な座り心地の椅子です。	1000	4	1	食品
6	タブレット	高性能なタブレットです。	60000	3	4	家具
6	タブレット	高性能なタブレットです。	60000	3	3	電子機器
6	タブレット	高性能なタブレットです。	60000	3	2	書籍
6	タブレット	高性能なタブレットです。	60000	3	1	食品
7	なぞのガラクタ	正体不明のガラクタです。	100	NULL	4	家具
7	なぞのガラクタ	正体不明のガラクタです。	100	NULL	3	電子機器
7	なぞのガラクタ	正体不明のガラクタです。	100	NULL	2	書籍
7	なぞのガラクタ	正体不明のガラクタです。	100	NULL	1	食品
id	name	description	price	category_id	id	name
1	卵	3日以内に採れた新鮮な鶏の卵です	250	1	1	食品
2	スマートフォン	最新のスマートフォンです。	15000	3	3	電子機器
3	ノートパソコン	高性能なノートパソコンです。	200000	3	3	電子機器
4	デスク	オフィス用のデスクです。	30000	4	4	家具
5	椅子	快適な座り心地の椅子です。	1000	4	4	家具
6	タブレット	高性能なタブレットです。	60000	3	3	電子機器
id	name	description	price	category_id	id	name
1	卵	3日以内に採れた新鮮な鶏の卵です	250	1	1	食品
2	スマートフォン	最新のスマートフォンです。	15000	3	3	電子機器
3	ノートパソコン	高性能なノートパソコンです。	200000	3	3	電子機器
4	デスク	オフィス用のデスクです。	30000	4	4	家具
5	椅子	快適な座り心地の椅子です。	1000	4	4	家具
6	タブレット	高性能なタブレットです。	60000	3	3	電子機器
7	なぞのガラクタ	正体不明のガラクタです。	100	NULL	NULL	NULL
id	name	description	price	category_id	id	name
1	卵	3日以内に採れた新鮮な鶏の卵です	250	1	1	食品
NULL	NULL	NULL	NULL	NULL	2	書籍
6	タブレット	高性能なタブレットです。	60000	3	3	電子機器
3	ノートパソコン	高性能なノートパソコンです。	200000	3	3	電子機器
2	スマートフォン	最新のスマートフォンです。	15000	3	3	電子機器
5	椅子	快適な座り心地の椅子です。	1000	4	4	家具
4	デスク	オフィス用のデスクです。	30000	4	4	家具
```

# 成果物

https://paiza.io/projects/Spn9ILF7yG-aKdIyiNQaWQ


以上。
Golangの構造体のポインタ配列

# Golangの構造体のポインタ配列

Golangの構造体（Golangでなくてもそうかも）は、メモリ使用量が地味に多いので、ポインタ配列を使いまくるのがコストパフォーマンス面で良さそうなので使いまくるために備忘録。

## 使いまくるポインタ例

```
type Account struct{
	id int
	name  string
}
```

でこういうのたち。ポインタとポインタの配列。
```
*Account
[]*Account
```

こっちじゃない。これは配列のポインタ。
```
*[]Account
```


## ポインタ配列

ポインタ配列の方が速い。使いまくる。

```
package main

import (
	"fmt"
)

// todo
// requirement
// Account is struct
// Accounts has an Account array defined as a pointer in field

type Account struct {
	id   int
	name string
}

type Accounts struct {
	accounts []*Account
}

func main() {

	// ポインタ型の値を作る
	var a1 *Account = &Account{id: 123, name: "foo"}
	var a2 *Account = &Account{id: 456, name: "bar"}

	// ポインタ型の配列を作る
	var as []*Account = []*Account{a1, a2}

	var acs Accounts = Accounts{accounts: as}

	// 各要素のメモリアドレスが表示される
	fmt.Println(acs)
	// {[0x14000126018 0x14000126030]}

	// ループで配列の要素にアクセスする
	for _, a := range acs.accounts {
		// *演算子で変数の値にアクセスする。
		fmt.Println(*a)
	}
	// {123 foo}
	// {456 bar}

}

```
依存性の注入

## 背景
プログラミング用語の中でも、何回か聞いても右から左へ素通りしてしまうのが「依存性の注入」などのプログラミング独特のワード。アウトプットすることで覚えたい
## 目的
依存性の注入と聞いて、すぐにコードの違いを思い浮かべられるようになること
## 本文
### 一言で言うと？
依存性の注入とは「依存するクラスを、クラスの内部でインスタンス化せず、外部からインスタンス化したものを受け取るようにすること」。なんかわからないので、使い

### 前提
classAはclassBに依存しているとします。
（依存とは、上記で言えばclassAはclassBがないと動かない状態のこと、です。）

### 「依存性の注入」のコード
classAをインスタンス化する前に、classBをインスタンス化し渡している。
これにより、classAのコンストラクタ内ではインスタンス化していない。

```php
# classA　インスタンス化
$classB = new classB();
$classA = classA($classB);
```

```php
# classA　コンストラクタ
public function __construct(ClassB $classB){
    $this->classB = $classB;
}
```

### 「依存性の注入」されてないコード
コンストラクタ内でインスタンス化している。
```php
# classA　コンストラクタ
public function __construct(){
    $this->classB = new ClassB();
}
```

## 学び
- インスタンス化してから渡すか、中でインスタンス化するかの、簡単な違いであることがわかった。

## 次
laravel上でどのような仕組みになっているか、確認する。
Ruby Silver勉強の参考に

先日Ruby Silverの試験に合格できたので勉強時に暗記した内容の一部です。

### 破壊的メソッド
```
concat
pop
shift
unshift
push
delete_if
clear
```

### 別名など
```
delete_if　→　reject! 
update　→　merge!
find_all　→ select
collect　→ map
member?　→　include?
select → find_all
find → detect
```

本当に一部ですが覚えておくと試験で4~6点くらい正解できると思います！
頑張ってください！
CISSP 学習メモ - データ削除系

# データ削除 (Sanitization) に関わる用語のまとめ

| 名称 | 再利用 |復元|残留 | 特徴 |
| ---- | ---- | ---- | ---- |---- |
| 消去（Erasing） | ×  | ◯ | ◯|ファイルまたは媒体の削除 |
| クリアリング (Clearing) | ◯  | ◯ |◯ |検証済みの上書き技術や方法、または承認されたソフトウェアを使用して上書きする、<b>同一レベルでの削除を実施する際に選択する<b>|
| パージ (Purging) | ◯ | × |×|高度な手法でデータ復元を阻止し、よりセキュアなメディアのサニタイゼーション手法、媒体からデータ削除を行い復旧不能になることを確実にする|
| 消磁 (Degaussing) <br>パージ (Purging)に包含されることも| ◯<br>※再利用にはコスト的に妥当か確認  | × |△<br>※残留磁気の可能性あり|磁気メディアに強い磁気を当てる|
| 物理的破壊 (Destruction) | ×  | × |× | 焼却、細断、粉砕、分解|

https://tsapps.nist.gov/publication/get_pdf.cfm?pub_id=917935

※サニタイズ (Sanitization) :システムまたは媒体からデータを削除する一連の操作でデータをいかなる方法でも復元できないようにする、再利用される前にデータが残らないことを完全に保証する

セキュリティレベル別の対応
弱 >> 強
パージング > クリアリング

クリアリング : 機密ではないデータによる上書き
パージング : 全てのデータの削除

## 参考
NIST 800-88

媒体のデータ抹消処理（サニタイズ）に関するガイドライン
https://www.ipa.go.jp/security/reports/oversea/nist/ug65p90000019cp4-att/000094547.pdf
(英語版)
https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-88r1.pdf
paiza.ioでmysql その10

# 概要

paiza.ioでmysqlやってみた。
練習問題やってみた。

# 練習問題
SUMを使え。

# サンプルコード

```
CREATE TABLE  Population (
  prefecture NVARCHAR(4),
  sex NCHAR(1),
  population INTEGER
);
INSERT INTO Population VALUES
  ('北海道','男',2537089),
  ('北海道','女',2844644),
  ('青森県','男',614694),
  ('青森県','女',693571),
  ('岩手県','男',615584),
  ('岩手県','女',664010),
  ('宮城県','男',1140167),
  ('宮城県','女',1193732),
  ('秋田県','男',480336),
  ('秋田県','女',542783),
  ('山形県','男',540226),
  ('山形県','女',583665),
  ('福島県','男',945660),
  ('福島県','女',968379),
  ('茨城県','男',1453594),
  ('茨城県','女',1463382),
  ('栃木県','男',981626),
  ('栃木県','女',992629),
  ('群馬県','男',973283),
  ('群馬県','女',999832),
  ('埼玉県','男',3628418),
  ('埼玉県','女',3638116),
  ('千葉県','男',3095860),
  ('千葉県','女',3126806),
  ('東京都','男',6666690),
  ('東京都','女',6848581),
  ('神奈川県','男',4558978),
  ('神奈川県','女',4567236),
  ('新潟県','男',1115413),
  ('新潟県','女',1188851),
  ('富山県','男',515147),
  ('富山県','女',551181),
  ('石川県','男',558589),
  ('石川県','女',595419),
  ('福井県','男',381474),
  ('福井県','女',405266),
  ('山梨県','男',408327),
  ('山梨県','女',426603),
  ('長野県','男',1022129),
  ('長野県','女',1076675),
  ('岐阜県','男',983850),
  ('岐阜県','女',1048053),
  ('静岡県','男',1820993),
  ('静岡県','女',1879312),
  ('愛知県','男',3740844),
  ('愛知県','女',3742284),
  ('三重県','男',883516),
  ('三重県','女',932349),
  ('滋賀県','男',696941),
  ('滋賀県','女',715975),
  ('京都府','男',1248972),
  ('京都府','女',1361381),
  ('大阪府','男',4256049),
  ('大阪府','女',4583420),
  ('兵庫県','男',2641561),
  ('兵庫県','女',2893239),
  ('奈良県','男',643946),
  ('奈良県','女',720370),
  ('和歌山県','男',453216),
  ('和歌山県','女',510363),
  ('鳥取県','男',273705),
  ('鳥取県','女',299736),
  ('島根県','男',333112),
  ('島根県','女',361240),
  ('岡山県','男',922226),
  ('岡山県','女',999299),
  ('広島県','男',1376211),
  ('広島県','女',1467779),
  ('山口県','男',665008),
  ('山口県','女',739721),
  ('徳島県','男',359790),
  ('徳島県','女',395943),
  ('香川県','男',472308),
  ('香川県','女',503955),
  ('愛媛県','男',654380),
  ('愛媛県','女',730882),
  ('高知県','男',342672),
  ('高知県','女',385604),
  ('福岡県','男',2410418),
  ('福岡県','女',2691138),
  ('佐賀県','男',393073),
  ('佐賀県','女',439759),
  ('長崎県','男',645763),
  ('長崎県','女',731424),
  ('熊本県','男',841046),
  ('熊本県','女',945124),
  ('大分県','男',551932),
  ('大分県','女',614406),
  ('宮崎県','男',519242),
  ('宮崎県','女',584827),
  ('鹿児島県','男',773061),
  ('鹿児島県','女',875116),
  ('沖縄県','男',704619),
  ('沖縄県','女',728947);


-- Populationテーブルを使って、全国、関東地方、四国地方における男女それぞれの人口を集計した表を作ってください。  
  SELECT SUM(population) AS '全国',
       SUM(CASE WHEN prefecture IN ('茨城県', '栃木県', '群馬県', '埼玉県','千葉県', '東京都', '神奈川県')
	            THEN population
				ELSE 0 END) AS '関東',
       SUM(CASE WHEN prefecture IN ('徳島県', '香川県', '愛媛県', '高知県')
	            THEN population
				ELSE 0 END) AS '四国'
  FROM Population
  GROUP BY sex;




```

# 実行結果


```
全国	関東	四国
61841738	21358449	1829150
65253007	21636582	2016384
```

# 成果物

https://paiza.io/projects/I2ezbW8UkXYkkHBFCzkm7w


以上。
【C言語】scanfでデータの組内の文字を読む方法

最初の行にデータ数が書かれていて、次以降の行にデータが1行に1組書かれている形式の入力を考える。
この記事では、データ数は100以下、「整数」は `int` 型で表現できる範囲の整数とする。

# 整数のみからなるデータの読み込み

このように、データが整数のみからなる場合は、`scanf` の書式 `%d` を用いて読み込むことができる。

```text
3
10 20
31 41
52 62
```

自分の書き方は、以下のような感じである。

```c
#include <stdio.h>

int N;
int a[128], b[128];

int main(void) {
	int i;
	if (scanf("%d", &N) != 1) return 1;
	for (i = 0; i < N; i++) {
		if (scanf("%d%d", &a[i], &b[i]) != 2) return 1;
	}

	/* 読み込んだデータの処理を行う */

	return 0;
}
```

# 文字を含むデータの読み込み (旧)

次に、以下のようにデータの組に文字を含む場合を考える。

```text
3
15 a
26 b
37 c
```

文字を読み込むとき、`%c` を用いると、`%d` と違って空白を読み飛ばさないため、トラブルの原因になることがありそうである。
なので、読み込むのが1文字の場合でも、`%s` を使って読み込むことにしている。
このとき、一旦文字列用の配列を用意してそこに格納し、そこからデータ用の配列にデータを移していた。

```c
#include <stdio.h>

int N;
int a[128];
char b[128];

int main(void) {
	int i;
	if (scanf("%d", &N) != 1) return 1;
	for (i = 0; i < N; i++) {
		char b_buf[4];
		if (scanf("%d%3s", &a[i], b_buf) != 2) return 1;
		b[i] = b_buf[0];
	}

	/* 読み込んだデータの処理を行う */

	return 0;
}
```

`b_buf[0]` のかわりに `*b_buf` を用いてもよい。

# 文字を含むデータの読み込み (新)

よく考えると、このように

* データのうち文字だけを1個の配列にまとめて読み込む
* 読み込み先の配列の要素数に余裕がある

場合は、`%d` で整数を読み込むときと同じ書き方で、`%s` で文字を読み込むことができることがわかる。

```c
#include <stdio.h>

int N;
int a[128];
char b[128];

int main(void) {
	int i;
	if (scanf("%d", &N) != 1) return 1;
	for (i = 0; i < N; i++) {
		if (scanf("%d%3s", &a[i], &b[i]) != 2) return 1;
	}

	/* 読み込んだデータの処理を行う */

	return 0;
}
```

このとき、書式 `%3s` により `b[i]` だけでなくその後の数要素にもデータが書き込まれるが、このデータは次以降のデータ行を読み込む際に上書きされ、最初の文字 (読み込みたいデータの文字) だけが残る。

ただし、この方式は最初の条件が成り立たず、文字を格納する場所の後に余計なデータを書き込んでよい領域が無い場合には使えないことに注意したい。
すなわち、たとえば

* データを1組ずつ構造体などにまとめて読み込む場合
* 読み込み先の配列の要素数に余裕が無い場合

には使えない。
(パディングなどの関係で問題が起こらない**かもしれない**が、気持ち悪いしやめたほうがいいだろう)

```c
#include <stdio.h>

int N;
struct data_s {
	int a;
	char b;
} data[128];

int main(void) {
	int i;
	if (scanf("%d", &N) != 1) return 1;
	for (i = 0; i < N; i++) {
#if 0
		/* NG (範囲外への書き込みが発生する) */
		if (scanf("%d%3s", &data[i].a, &data[i].b) != 2) return 1;
#else
		/* OK (従来の方法) */
		char b_buf[4];
		if (scanf("%d%3s", &data[i].a, b_buf) != 2) return 1;
		data[i].b = b_buf[0];
#endif
	}

	/* 読み込んだデータの処理を行う */

	return 0;
}
```

# 結論

文字データを文字の配列に読み込み、読み込んだデータを書き込む要素の後の要素に余計なデータを書き込んでもよい場合は、整数を `%d` で読み込むのと同様の書き方で文字を `%s` で読み込むことができることがわかった。
これにより、わざわざ文字列用の配列を別に確保しなくてよくなり、コードがスッキリすることが期待できる。

しかし、このように「余計なデータが書き込まれるが無視できる」ということは一見してわかりにくく、「文字の読み込みなのに誤って `%c` ではなく `%s` を使っている！」と誤解してしまう原因になりうる。
競技プログラミングであれば用いてもよいかもしれないが、より高いわかりやすさやメンテナンス性が求められる場面では使用を避けたほうがいいかもしれない。
~~さらに重要な処理では、`scanf` 自体の使用を避けるべきという主張も…？~~

~~そもそも、`%c` の前に空白を置くことにより空白を読み飛ばせばいいという説も…？~~
RustのGET STARTEDをやってみました 〜〜Elixirを好きなAlchemistがRustaceanにもなるまで〜〜

# はじめに

[Rust](https://www.rust-lang.org/)に入門してみました。
動機は、会社の同僚が[Rust](https://www.rust-lang.org/)でQiita記事投稿キャンペーンに応募して **最優秀賞（Apple Watch）** を獲得したからです。選出理由に[Rust](https://www.rust-lang.org/)が挙げられていました。このビッグウェーブ🌊に乗るしかありません！

https://zine.qiita.com/event/202409-paiza/

![スクリーンショット 2024-09-29 9.44.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/a5268eb8-b05c-da9d-3741-b427729dc561.png)

私は[Elixir](https://elixir-lang.org/)というプログラミング言語が好きです。

## 最優秀賞記事

@haw_ohnuma さんが最優秀賞（Apple Watch）を受賞した記事です。

https://qiita.com/haw_ohnuma/items/534541678945d6b33fc0

## 入賞記事

私も入賞を果たしていました。

https://qiita.com/torifukukaiou/items/966b71497f04c7fb5882

:::note info
paizaさん、Qiitaさんありがとうございます！
:::

# GET STARTED !!!

まず[トップページ](https://www.rust-lang.org/)を読んでみます。
さらっと読んでみます。
おもしろそうです。「ワクワクすっぞっ！！」

# [Getting started](https://www.rust-lang.org/learn/get-started)

https://www.rust-lang.org/learn/get-started

ページを進めます。
その通りにやればできます。

手順が古くなるかもしれませんし、公式ページの単なるコピペを書いても仕方ないので、 **できました** ということを書いておきます。

## RustとElixirの対比

微妙に異なる部分はあるのだろうとは思いますが、[Getting started](https://www.rust-lang.org/learn/get-started)の中で出てきた用語のうち、Alchemistであるそこのあなたに向けて、[Elixir](https://elixir-lang.org/)で言うところの何にあたるのかを書いておきます。

| Rust | Elixir | コメント |
|:-|:-|:-|
| cargo  | mix   | プロジェクト作ったり依存関係を解決したりビルドしたりするツール（コマンド）|
| crates  | Hex  | ライブラリ |
| Cargo.toml | mix.exs | どのライブラリを取り込むかを書きます |
| https://crates.io/  | https://hex.pm/  | ライブラリが公開されているサイト |
| Rustacean | Alchemist | 使い手のこと |
| Ferris| いない!? | 非公認のマスコット。性別不明の蟹。　|

## もちろん「完全に理解しました！」

もちろん[例の意味](https://togetter.com/li/1268851)です。
[Getting started](https://www.rust-lang.org/learn/get-started)をそのままやると以下をターミナルに表示することができます。


```text
 __________________________
< Hello fellow Rustaceans! >
 --------------------------
        \
         \
            _~^~^~_
        \) /  o o  \ (/
          '_   -   _'
          / '-----' \
```

Ferrisがしゃべってくれます。

せっかくなのでちょっと違うことをしてみます。
`Cargo.toml`を変更してみます。

まずは[Getting started](https://www.rust-lang.org/learn/get-started)の通りに書いた場合です。

```toml:Cargo.toml
[dependencies]
ferris-says = "0.3.1"
```

[ferris-says](https://crates.io/crates/ferris-says)は、ライブラリです。
変更をしてみます。

```toml:Cargo.toml
[dependencies]
ferris-says = { version = "0.3.1", features = ["clippy"] }
```

`Cargo.toml`を変更したら、迷わず実行（`cargo run`）してみましょう！

```
 __________________________
< Hello fellow Rustaceans! >
 --------------------------
        \
         \
            __
           /  \
           |  |
           @  @
           |  |
           || |/
           || ||
           |\_/|
           \___
```

キャラクターが変わりました。
Clippy、君は一体だれ！？

GitHubで質問のやりとりを見つけました。

https://github.com/rust-lang/ferris-says/issues/37

---

# さいごに

[Rust](https://www.rust-lang.org/)のGET STARTEDをやってみました。
[Elixir](https://elixir-lang.org/)から[Rust](https://www.rust-lang.org/)に入門する方のお役に立てれば幸いわい<b><font color="red">$\huge{Y}$</font></b>です。


[Elixir](https://elixir-lang.org/)で同じことをするGET STARTEDを書いてみようと思っています（あくまでも思っています）。
なぜAWS CodeArtifact を使うのか？

## この記事を書いた理由 
AWS-SAP(AWS Certified Solutions Architect - Professional) 認定試験問題を解いている中で、AWS のプライベートサブネットにあるインスタンスから、Python などのリポジトリを取得するときに、パブリックサブネットのNAT ゲートウェイを用いずになぜAWS CodeArtifact を使うのかわからなかったから書きました。
## 前提条件
ある組織が、Amazon SageMaker インスタンスとSageMaker API を使って、機械学習(ML)モデルを開発しています。セキュリティ要件により、SageMaker インスタンスはインターネットから完全に隔離されたVPC にデプロイされています。ML モデルのトレーニングデータは、暗号化されたS3バケットに保存されており、SageMaker APIがAmazon S3 とアクセスするには、インターフェースVPC エンドポイントを介して行われます。
開発プロセス中、特殊なPython パッケージを利用することになり、そのパッケージはPython Package Index(PyPI)リポジトリにホストされています。このような条件で、SageMaker インスタンスをインターネットから確実に隔離したまま、安全にPyPI リポジトリへのアクセスを提供するソリューションとして、AWS CodeArtifact が最も適切だと説明がありました。
## NAT ゲートウェイ経由が利用できない理由
NAT ゲートウェイはパブリックサブネットに設置され、プライベートサブネットのインスタンスからインターネット接続を可能にします。つまり、PyPI 以外の接続先にもアクセスできるので、「インターネットから完全に隔離されたVPC」の前提条件が崩れます。

また、PyPI を使った悪意のある攻撃が存在しており、プライベートサブネットのインスタンスがこうしたマルウェアの攻撃を受けたとき、NAT ゲートウェイを経由して外部に機密情報を漏洩することが可能になってしまいます。

## AWS CodeArtifact の役割
![aws-codeartifact.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570094/82995d76-eba5-0a83-1627-461adf5d0efd.png)
「前提条件」の構成を図解しました。このように、Amazon SageMaker インスタンスはS3 とAWS CodeArtifact とのみ通信可能なので、インターネットから完全に隔離されています。万が一PyPI 経由でインスタンスがマルウェアに感染した場合でも、外部にデータを漏洩できない構造になっています。

## このアーキテクチャの効果
このアーキテクチャの効果は、セキュリティを最優先にしつつ、インターネットへの接続を排除することで、データ漏洩のリスクを最小限に抑え、同時にパッケージ管理の効率性を確保している点にあります。

ML で機密性の高い画像や書類を処理したりする場合や、高いコンプライアンス要件に適合させるためにこのアーキテクチャが効果的となります。
paiza.ioでmysql その9

# paiza.ioでmysqlやってみた。
練習問題やってみた。

# 練習問題
INTERSECT (積集合)、EXCEPT (差集合)を使え。


# サンプルコード

```


CREATE TABLE A (
    name VARCHAR(255) NOT NULL, 
    value INT NOT NULL);
CREATE TABLE B (
    name VARCHAR(255) NOT NULL, 
    value INT NOT NULL);

INSERT INTO A (name, value) value
('aaa', 111),
('aaa', 222),
('aaa', 222),
('bbb', 333),
('bbb', 333),
('bbb', 444),
('ccc', 111),
('ccc', 111);

INSERT INTO B (name, value) value
('aaa', 111),
('aaa', 333),
('bbb', 222),
('bbb', 333),
('bbb', 333),
('bbb', 555),
('ccc', 111),
('ddd', 111);

SELECT * FROM A
INTERSECT
SELECT * FROM B;

SELECT * FROM A
INTERSECT ALL
SELECT * FROM B;

SELECT * FROM A
EXCEPT
SELECT * FROM B;

SELECT * FROM B
EXCEPT
SELECT * FROM A;

SELECT * FROM A
EXCEPT ALL
SELECT * FROM B;

SELECT "\n";


```

# 実行結果

```
name	value
aaa	111
bbb	333
ccc	111
name	value
aaa	111
bbb	333
bbb	333
ccc	111
name	value
aaa	222
bbb	444
name	value
aaa	333
bbb	222
bbb	555
ddd	111
name	value
aaa	222
aaa	222
bbb	444
ccc	111

\n
```

# 成果物

https://paiza.io/projects/EopzaJAe6m-7_zXj6kstPg


以上。
PythonとRustでAPIの叩き方を比較する

# PythonとRustでAPIの叩き方を比較する

## 前置き
今回比較する対象は[PokeAPI](https://pokeapi.co/)を叩くプログラムをPythonとRustで書きます。

ちなみに叩くポケモンはハバタクカミです。

~~本当は種族値まで表示したかったのですがちょっとRustでの型が難しそうなので妥協しました~~


# Rustで実装
```rust:main.rs
// インポート関連
use reqwest::Client;

type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[tokio::main]
async fn main() -> Result<()> {
    // APIを叩く
    let client = Client::new();
    let url = "https://pokeapi.co/api/v2/pokemon/987";
    let res = client.get(url).send().await?;

    let body = res.text().await?;
    // 出力
    println!("{}", body);
    Ok(())
}
```
あとCargo.toml
```toml:Cargo.toml
[package]
name = "hoge"
version = "0.1.0"
edition="2021"
[dependencies]
proconio = "0.4.5"
itertools = "0.11.0"
itertools-num = "0.1.3"
rand = "0.8.5"
reqwest = { version = "0.11.4", features = ["json"] }
tokio = { version = "1.11.0", features = ["full"] }
serde = { version = "^1.0.130", features = ["derive"] }
serde_json = "^1.0.67"

[[bin]]
name = "hoge"
path = "./main.rs"
```

# Pythonで実装
**実装する前に必要なライブラリ**
* requests
*  matplotlib
あれmatplotlib
## 実装
```python:main.py
# インポート
import requests
import json
import matplotlib.pyplot as plt
from math import pi

# APIを叩く
url = "https://pokeapi.co/api/v2/pokemon/987"

res = json.loads(requests.get(url=url).text)
# echo あれ種族値だ　妥協したんじゃなかったけwww
# echo Pythonはめちゃくちゃ型が柔軟なのでできたよ
# echo あっそ

label_list = []
value_list = []

for stats, p in zip(res["stats"], ["HP", "攻撃", "防御", "特攻", "特防", "素早さ"]):
    print(f'{p}:{stats["base_stat"]}')
    label_list.append(p)
    value_list.append(stats["base_stat"])
```
# おまけ
```python:main.py
value_list += value_list[:1]

angle_list = [n / float(len(label_list)) * 2 * pi for n in range(len(label_list))]

angle_list += angle_list[:1]

fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
plt.xticks(
    angle_list[:-1], label_list, color="grey", size=12, fontname="Source Han Code JP"
)  # fontnameはご自由にどうぞ

ax.plot(angle_list, value_list, linewidth=1, linestyle="solid")
ax.fill(angle_list, value_list, "blue", alpha=0.1)

# ./chart.pngに保存
plt.savefig("chart.png")
```
おまけにレーダーチャートを作成してみましたw
![chart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889080/093441b6-61af-1aef-1c41-361f0b1322bd.png)

# まとめ

## APIを叩く部分
pythonはrequestsでササッとできるけど
rustは依存関係のインストールが少し大変だし
非同期処理が必要だった

## 数値を表示する部分
rustは型の定義が大変そう(~~めんどくさい~~)
pythonは型が柔軟なので簡単に数値まで表示できました
ついでにレーダーチャートも作成しちゃったw

# 結果
処理速度と便利さ一長一短
APIにリクエストする部分ではAPIのサーバーやネット環境に依存するけど
その後の処理速度の面ではおそらくRustが勝っている
それだと少しめんどくさいけどPythonよりRustの方がいいじゃんとなるけど、Pythonは型が動的型付けのためJsonの形さえ把握でできればすぐコードをかけるためやっぱり一長一短

#　使用したコード

https://github.com/hidehic0/Python-Rust-API-request-comparison
paiza.ioでmysql その8

# paiza.ioでmysqlやってみた。
練習問題やってみた。

# 練習問題
1-3までを取得せよ。

# 方針


SELECT 		(どの列がほしいかを選ぶ)
FROM 		(どのテーブルからデータを取るかを選ぶ)
WHERE 		(取得したい行を条件で選ぶ)
GROUP BY 	(部分集合に集約する)
HAVING 		(取得したい部分集合を選ぶ)
ORDER BY 	(並び替える)
LIMIT 		(必要な数だけ)
UNION		(合体)
INTERSECT	(積集合)
EXCEPT		(差集合)


# サンプルコード

```
SELECT 1 AS value UNION ALL SELECT 2 UNION ALL SELECT 3;

VALUES ROW(1), ROW(2), ROW(3);

WITH RECURSIVE seq AS (SELECT 1 AS value UNION ALL SELECT value + 1 FROM seq WHERE value < 3)

SELECT * FROM seq;
```

# 実行結果

```
value
1
2
3
column_0
1
2
3
value
1
2
3
```

# 成果物

https://paiza.io/projects/trzMUTWlvlq_pBh2G_fJLg


以上。
ComposeMultiplatform文字入力処理

ComposeMultiplatformでプロジェクトを作成したので理解を深めていきたいと思います。

ComposeMultiplatformでの文字入力処理です。
Composeと変わらない感じに実装できました。


# サンプルコード

```App.kt
@Composable
@Preview
fun App() {
    MaterialTheme {
        var inputText by remember { mutableStateOf("") }
        var inputPassword by remember { mutableStateOf("") }
        var inputNumber by remember { mutableStateOf("") }

        Column {
            TextField(
                modifier = Modifier.padding(bottom = 12.dp),
                value = inputText,
                onValueChange = { inputText = it },
                keyboardOptions = KeyboardOptions(
                    keyboardType = KeyboardType.Email,
                    imeAction = ImeAction.Done,
                )
            )
            TextField(
                modifier = Modifier.padding(bottom = 12.dp),
                value = inputPassword,
                onValueChange = { inputPassword = it },
                visualTransformation = PasswordVisualTransformation(),
                keyboardOptions = KeyboardOptions(
                    keyboardType = KeyboardType.Text,
                    imeAction = ImeAction.Done,
                )
            )

            TextField(value = inputNumber,
                onValueChange = { inputNumber = it },
                keyboardOptions = KeyboardOptions(
                    keyboardType = KeyboardType.Number,
                    imeAction = ImeAction.Done,
                )
            )
        }
    }
}

```
`keyboardOptions`の設定や`visualTransformation`の設定なども問題なくiOSの方でも動きました。

# 実行結果
iOS
![Videotogif (10).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/352fa1bb-9d3b-8abe-4a89-9174e93fdb62.gif)



Android
![Videotogif (9).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/ffcf74ae-0caa-71c6-90fc-639a6e1eb720.gif)
読書記録「プロになるためのWeb技術入門」

## 1. はじめに
プログラミング学習を進める中で、Web技術の基本的な知識が不足していると感じていました。「なんとなく動いている」という状態から抜け出すため、入門書の内容を自分なりにまとめてみました。

## 2. 概要
### そもそもWebとは何か？
インターネットはもともと研究者間が、論文などの文書をやり取りするために使用していた。
→機器が安価になり誰でも手に入るように、また、共通のプロトコルを採用することで異なるOS間でも情報のやり取りが可能に
→文書の閲覧だけではなく、世界中のコンピューター同士で情報をやり取りできるようになった。

### どのように通信するのか？
TCP/IPプロトコルを用いる（Transmission Control Protocol/Internet Protocol）
コンピューター同士の通信方式に関する取り決め。

URLから通信相手を特定し、情報をやり取りする。URLとは住所のようなもの
例）URL（https://www.sample.jp/test/index.html）
https =　スキーム。リソースを取得するための方法。httpsは暗号化されたhttp通信を表す。
www.sample.jp =　ホスト名。一意の値になっており、通信する相手側を表す。
test/index.html =　パス名。指定したリソースの位置を表す。（相手側のどこに該当のファイルがあるか）


URLはそのまま送らず、入力された値をDNSサーバーで機械が読み取れるように変換を行う。変換された情報をもとに通信相手を探す。（DNSサーバーは電話帳みたいなもの。電話番号だけでは情報がわかりづらいので、人間が分かるようにURLが用いられている。）
通信する相手が見つかっても、どのアプリと通信すればいいかわからない→ポート番号を指定することで、どこに通信すればいいかがわかる。（普段はポート番号を指定しなくても、通信方式によってコンピューターが自動で番号を振り分けてくれる。http通信のばあいは80番のポート番号に繋げる。）

情報はパケット通信方式でやり取りされる。（情報をパケットという小包の中に入れて、通信を行う方法）こうすることで、混雑状態でうまく情報が送れなかった場合も、遅れなかったパケットのみ再度送れば、必要な情報を取得することが可能である。

### ログイン情報保持の仕組み
ブラウザとサーバーのやり取りはステートレスのため、ブラウザがどのような状態か記憶することができない。
→ブラウザからのリクエストに応じて、サーバーはセッションIDを発行、ブラウザはcokiesでIDを保持することで、ページが切り替わっても、サーバー側は同じユーザーからの通信であることがわかる。（悪意のあるユーザーがセッションIDを盗むだすことで他人になりすますことで個人情報を取られるリスク（セッションハイジャック）があるため、開発者は、セッションIDをハッシュ化させたり、IDの有効期限を短くするなどの対策が必要。）

### Webアプリの構造
MVCモデルという枠組みにより処理を分ける（Model、View、Controller）
Model＝アプリの処理の部分担当。情報の保持を行い、データベースから情報を取得する。
View＝処理結果の画面表示担当。モデルから渡されたデータを成形しブラウザに表示。
Controller＝全体の流れを総括。ブラウザから送られた情報をもとに、モデルに情報の受け渡しと、モデルの処理結果をビューに渡す。
プログラミング言語ごとのフレームワークを活用することで、MVCモデルに準拠したアプリを、素早く、高品質で作成することが可能。

### セキュリティについて
Webサイトは不特定多数が閲覧するため、開発者は、悪用されないようセキュリティ対策をきちんと行わなければならない。
#### 代表的な攻撃方法
 - SQLインジェクション　データベースに任意のSQLを実行することで、不正に情報を取得する。
→バリデーションチェックにより、送信内容を制限することで対策。
 - クロスサイトスクリプティング　脆弱性のあるサイトにJavascriptのプログラムを実行させ、不正に情報を盗み出す。
→サニタイジングを行い、特殊文字を無害化することで対策。
 - クロスサイトリクエストフォージェリ　攻撃者が捏造したフォームに情報を入力することで、掲示板に意図しない書き込みをしてしまう。
→ワンタイムトークンを利用したトークン認証を行い、ユーザー本人であることを確認することで対策。

## 3. おわりに
 - 世界中のコンピューター同士がつながるために、通信方式や規格などさまざまな共通事項を通して技術が作られていることがわかった。
 - Webアプリを開発する際は、フレームワークを使えば、MVCモデルに準拠したアプリを作成することができるが、記述内容の意味がわからない部分があったが、アプリ中で行われている処理について理解を深めることができた。

## 読んだ本
https://gihyo.jp/book/2010/978-4-7741-4235-7
011 AI屋さんの　dockerと200万トークン全文入力　追加学習済み　LLMの　Webアプリをクラウドデプロイ　実践編

AI屋さんの　dockerと200万トークン全文入力　追加学習済み　LLMの　Webアプリをクラウドデプロイ　実践編


多くのAI(≒python)屋さんは、
作ったサービスをデプロイする際、困っています。
そこで、簡単に下記の要素で解決しましょう。

　AI、LLM、NN、各種モデルに
　webアプリ、API（streamlit,gradio,flask）に
　DB(SQL,NoSQL)、ストレージに
　dockerに
　クラウド、サーバーレスなど

を使うことで、独りで開発・運用・保守を行えます。
現在、pythonを使える人は最強です。
過去の開発環境の黒歴史も関係なく、
最新の開発環境とツールとpythonのみで一気通貫　開発できます。


例：docker HUB経由でwebアプリをデプロイの図

![スクリーンショット 2024-09-29 8.36.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/d0d20aa6-7254-2205-3089-aff89064ed07.png)


大規模言語モデルの　プロンプトに
「吾輩は猫である」を全文入力した専門分野特化の
追加学習済みのＬＬＭを安価に共有する方法です。
完成ずみのwebapiを使って、
既にある、皆様のポータルサイトで呼び出したり
別途、独立サイトで運用したり　色々できます。



目次

https://qiita.com/bono0/items/dc1d000c98af7e07c9a7




流れとしては、
　→　LLM開発（gemini）
　→　Webアプリ開発（streamlit）
　→　docker ビルド（準備中）
　→　イメージプッシュ（準備中）
　→　docker run（今回ここ）
　→　クラウド　サーバーレス（culoud run）
　→　完成

まずは、下記コマンドでdockerのコンテナを起動します。
中身は、streamlitがローカルで起動するだけです。
コンテナに入ってソースも見れます。
何もない雛形です。


docker run -d -p 8080:8080 bono0/st


http://
localhost:8080


http://localhost:8080



![スクリーンショット 2024-09-29 8.37.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/be685db9-03f0-a1de-5809-62dafa244725.png)


![スクリーンショット 2024-09-29 8.38.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/3d94105e-ccb7-dac4-fd3e-091c2827ea14.png)


開発したAIやwebアプリを　dockerで固めて利用することが
出来ました。
ローカルのdockerで動けば、
あとは、クラウドのサーバーレスは　コマンド一発です。

　gcloud run deploy

で完成です。
クラウド品質の　AIアプリを簡単にデプロイできます。
これで、多くのAI(≒python)屋さんは、
作ったサービスをデプロイできましたとさ。
メデタシ　メデタシ




今回も無事に
　AI屋さんの　dockerと200万トークン全文入力　追加学習済み　LLMの　Webアプリをクラウドデプロイ　実践編
完成です。おめでとうございます。



ー完ー