OmniAICreator/Qiita-1.07M huggingface dataset:
Docker MySQLの環境構築（Wiondows編）

## 手順
・Docker Desktop For Windowsのインストール
・mysqlコンテナを起動

## Docker Desktop のインストール
<a href="https://zenn.dev/seiya0/articles/tech-docker-desktop-for-win-install">こちらの記事</a>を参考にインストール

## mysqlコンテナの起動

コンソールを開き、以下コマンドを実行していく。実行場所はどこでもよい。


#### 1. dockerHub上のMySQLイメージからコンテナを作成、起動
※以下コマンドは、<a href="https://hub.docker.com/_/mysql">dockerHub</a>に記載されているものを一部修正したもの
```:MySQLイメージからコンテナを作成・起動
C:\Users\test>docker run --name test-mysql -p 13306:3306 -e MYSQL_ROOT_PASSWORD=password -d mysql

#（実行結果）コンテナIDが表示される
```

- ``--name``：コンテナの識別子（コンテナ名）
- ``-p``：ローカルPCの特定のポートへの通信をコンテナ側の特定のポートへ転送する（ポートフォワディングともいう）
- ``-e``：コンテナ側の環境変数の設定。上記ではMySQLのrootユーザーのパスワードを設定している
- ``-d``：デタッチドモードで実行。（バックグラウンドでコンテナを実行）
- ``末尾のmysql:tag``：コンテナイメージの指定。　「:tag」の後ろにはバージョンを指定してあげる。バージョンは<a href="https://hub.docker.com/_/mysql/tags">こちら</a>参照。「:tag」を外すと、latest（最新版）が適用される。
<hr/>

#### 2. コンテナ起動確認
```:起動中のコンテナの一覧を出力
C:\Users\test>docker ps

#（実行結果）コンテナ名がでてくればＯＫ
```
<hr/>

#### 3. コンテナの中に入って、MySQLにログインする。
```:コンテナの中に入って、mysqlを実行できるようにする
C:\Users\test>docker exec -it test-mysql bash
bash-4.4# mysql -u root -p
Enter password:　　← mysqlのパスワードを入力
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.3.0 MySQL Community Server - GPL

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
```
- ``-it``：コンテナ側でのコマンド操作を今使っているコンソールから操作できるようになる
<hr/>

#### 4. MySQLの操作（おまけ）
```
# データベースの作成
mysql> CREATE DATABASE test_db;
Query OK, 1 row affected (0.01 sec)

# データベースの切り替え
mysql> USE test_db;
Database changed

# MySQLの操作終了
mysql> exit
Bye
bash-4.4#

# コンテナから抜けるときは「Ctrl+Q」または「Ctrl+Q+P」
bash-4.4# read escape sequence

C:\Users\test>
```

以上！
nRFConnectSDKを基盤としたSesameの暗号通信 #6  Hello World use DK

![sesame](https://www.nordicsemi.com/-/media/Images/Products/DevKits/nRF52-Series/nRF52840-DK/nRF52840-DK/nRF52840-DK-prod-page.png?h=750&iar=0&mw=350&w=350&hash=3DB140F6AE70CAE159FD911D8E6E9109)

# 目的
build and run  Hello World use DK

# 技術



# 雑談


# 心配

# 用語
 
- [nRF52840 Dongle](https://www.nordicsemi.com/Products/Development-hardware/nRF52840-Dongle):*開発ボード*

- [nRF52840 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF52840-DK):*開発ボード*

# 関連記事

- [nRFConnectSDKを基盤としたSesameの暗号通信](https://qiita.com/tse123321/items/c0fa105cd5b9f14c2a0c)
バックスラッシュエスケープされたタブ区切りテキストをCSVに変換する

以下サンプル

```tsv2csv.go
//usr/bin/go run $0 $@ ; exit
package main

import (
        "bufio"
        "encoding/csv"
        "fmt"
        "os"
        "strings"
)

func main() {
        // 標準入力からデータを読み込む
        scanner := bufio.NewScanner(os.Stdin)

        // CSVライターを作成し、標準出力に書き込む
        writer := csv.NewWriter(os.Stdout)
        defer writer.Flush()

        // 標準入力を1行ずつ読み込み
        for scanner.Scan() {
                // タブ区切りでフィールドを分割
                line := scanner.Text()
                fields := strings.Split(line, "\t")

                // 各フィールドのエスケープシーケンスを処理
                for i, field := range fields {
                        fields[i] = unescape(field)
                }

                // CSVとして書き込む
                if err := writer.Write(fields); err != nil {
                        fmt.Println("Error writing record to csv:", err)
                        return
                }
        }

        if err := scanner.Err(); err != nil {
                fmt.Println("Error reading input:", err)
        }
}

// エスケープシーケンスを処理する関数
func unescape(s string) string {
        if !strings.Contains(s, "\\"){
                return s
        }

        var builder strings.Builder
        length := len(s)

        for i := 0; i < length; i++ {
                if s[i] == '\\' && i+1 < length {
                        switch s[i+1] {
                        case 'n':
                                builder.WriteByte('\n')
                                i++
                        case 't':
                                builder.WriteByte('\t')
                                i++
                        case '\\':
                                builder.WriteByte('\\')
                                i++
                        default:
                                builder.WriteByte(s[i])
                        }
                } else {
                        builder.WriteByte(s[i])
                }
        }
        return builder.String()
}
```
社会人3年目になったのでAWS Certified Solutions Architect - Associateを取得してみた

![1691964348159.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960668/0e5b403a-bf84-3215-c74d-83d2cb7ac04d.png)

## はじめに
最近、自分が関わっているサービスで、オンプレからAWSへの移行が行われていて、AWS資格に挑戦をしたことがなかったことと、前職で新卒1年目と2年目でAWSに少し触れていたので、SAAの資格を取ろうと思い学習してみました。
知識としては、CloudFront、S3、Route53、などでLPを公開する経験が数回あったのと、鍵の管理でKMSに触れたことがあったり、DynamoDBでNFT発行のためのユーザーごとに違うURLを保持するために使用したことがありましたが、他のサービスはなんとなく知っていたり、「1回触ったことあったような、、」というぐらいの認識でした。

## AWS ソリューションアーキテクトアソシエイトとは
公式によると、コストとパフォマンスの最適化の知識で、クラウドまたはオンプレミスITでの経験が豊富なエンジニアにとっては理想的なスタートラインであると書いてあります。
また、プログラミングの深い実務経験は必要ないが、基本的なプログラミングの概念を熟知していると有利であると書いてあります。


僕の覚えている範囲だと
- 冗長化構成について
- オンプレからのAWS移行の知識
- 要望に対してどのサービスを使うと実現できるのか
- どのように組み合わせるとコストを抑えられるか
- 最適なインスタンスタイプやオプションを選択できるかの問題
などがありました。AIに対しても何問か問われたと思います。

試験自体の概要は下記です。

試験形式: 65問の選択式と複数選択式の問題
試験時間: 130分
合格ライン: 1000点満点中720点以上
受験料: 22000円(税込)

## 学習期間と内容
学習期間は1ヶ月ぐらいで40時間ぐらいだと思います。
僕は主に、[CloudTeck](https://kws-cloud-tech.com/)というプラットフォームで、問題を解いたり解説を見ることで、サービス理解を行っていました。
主にEC2のインスタンスタイプに関する知識や、VPCに関して、S3のオブジェクトのアクセス頻度に対してどのインスタンスタイプを適応するのが良いのかや、DBに対する特徴などについては少し多めに学習しました。

## 学習してみて良かった点
- 今まで知らなかったサービスについて知ることができた
- 与えられた要件を満たすためにどのサービスを使うと良いのかを学ぶことができた

## 試験本番と感じたこと
40時間ほど勉強しましたが、初見の問題も2割近くあったと思います。時間は130分ですが、積極的に後で解くのフラグを立てても3問ぐらいは解き終わりませんでしたので時間いっぱいまで使うイメージです。
終了5分前ぐらいに誤った回答をしているところを5問ほど見つけたので、見直す時間は念の為設けた方が良いです。
見たことがある問題や簡単な問題もあるので、落ち着いてとくと良いです。

## 試験を終えてみて
資格を取ってみて良かった点は、偏っているAWSの知識を幅広く学べた点です。AWSの知識を広げるという意味ではかなり良い時間だったと思います。
ただ、当たり前ですが資格を取ってすぐに業務で使えるようになるというわけではなく、AWSに対する知見を深めるには実際にAWSに触ってみるということが大事になってくると思います。
なので、実際に自分のサービスをAWSでリリースしてみるということをやってみて、記事でも共有していこうと思います


## 参考
- [AWS公式](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/)
JavaScriptでpaizaAランク問題「本の整理」に挑む。

私はこれまでC・Bランクを解いてきました。計算方法は気にせず自分の思うように解けるので難しい印象はありませんでした。
しかし、Aランクから一筋縄ではいかない様子。

特に「本の整理」問題はアルゴリズムを使用しなければいけないようです。

ということで、挑戦してみました。※問題文はURLから確認してください。

https://paiza.jp/works/mondai/real_event/book_sort

## 解き方
結論、「**選択ソート**」を使用しました。
配列の先頭から順番に最小の要素を選び、並び替えていくアルゴリズムです。

1. `for`文にそって比較の元になるインデックスを決めていきます。ここでは`minIndex`と表現しています
2. そこから値を比較し、より小さい値があるか精査します。もしあった場合、最小値のインデックスが変わるので、`minIndex`を更新します
3. 最終的には元インデックスと最小インデックスにある値を入れ替えます

```javascript
const bookIds = lines[1].split(' ').map(line => Number(line));
let swapCount = 0;
for (let i = 0; i < bookIds.length; i++) {
    let minIndex = i;
    for (let j = i + 1; j < bookIds.length; j++) {

        if (bookIds[j] < bookIds[minIndex]) {
            minIndex = j;
        }
    }
    if (i === minIndex) {
        continue;
    }
    [bookIds[minIndex], bookIds[i]] = [bookIds[i], bookIds[minIndex]];
    swapCount++;
}
console.log(swapCount);
```

## さいごに
このアルゴリズムが最適かわかりません。もっと効率のいい方法があるとは思いますが、いったん全てテストが通ったのでよし。

皆さんはどういった解き方をしているのでしょうか？
HTTPの主なステータスコード一覧


## 主なステータスコード一覧
| ステータスコード | 名前 | 説明 |
| :--- | :--- | :--- |
| 200 | OK | リクエスト成功 |
| 201 | Created | リクエスト成功、新しいリソースが作成された |
| 202 | Accepted | リクエスト成功 |
| 204 | No Content | コンテンツなし |
| 300 | Mutiple Choices | 複数のリソースが存在する |
| 301 | Moved Permanently | リソースは恒久的に移動した |
| 302 | Found | リクエストしたリソースは一時的に移動している |
| 303 | See Other | 他を参照 |
| 304 | Not Modified | 前回から更新されていない |
| 307 | Temporary Redirect | リクエストしたリソースは一時的に移動している |
| 400 | Bad Request | リクエストが正しくない |
| 401 | Unauthorized | 認証が必要 |
| 403 | Forbidden | アクセスが禁止されている |
| 404 | Not Found | 指定したリソースが見つからない |
| 405 | Method Not Allowed | 指定されたメソッドは使うことができない |
| 406 | Not Acceptable | Accept関連のヘッダに受理できない内容が含まれている |
| 408 | Request Timeout | リクエストが時間以内に完了しなかった |
| 409 | Conflict | リソースが矛盾した |
| 410 | Gone | 指定したリソースは消滅した |
| 413 | Request Entity Too Large | リクエストボディが大きすぎる |
| 414 | Request-URI Too Long | リクエストされたURIが長すぎる |
| 415 | Unsupported Media Type | サポートしていないメディアタイプが指定された |
| 429 | Too Many Requests | リクエスト回数が多すぎる |
| 500 | Internal Server Error | サーバー側でエラーが発生している |
| 503 | Service Unavailable | サーバが一時的に停止している |


## 参考文献
https://www.itmanage.co.jp/column/http-www-request-response-statuscode/#:~:text=HTTP%20100%E7%95%AA%E5%8F%B0%20Informational%EF%BC%88%E6%83%85%E5%A0%B1,%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E7%8A%B6%E6%85%8B%E3%81%A7%E3%81%99%E3%80%82
nRFConnectSDKを基盤としたSesameの暗号通信 #5  Hello World use Dongle

![sesame](https://scontent-nrt1-2.xx.fbcdn.net/v/t39.30808-6/455254349_10221163214070225_3619176667081238813_n.jpg?_nc_cat=102&ccb=1-7&_nc_sid=127cfc&_nc_ohc=7v3cyFNhEaUQ7kNvgEAxtLT&_nc_ht=scontent-nrt1-2.xx&oh=00_AYDGt_l5NY2CHvBiOaooYkT8dF8j9bIe-xc_yfXPP9U1PA&oe=66BF9AFC)

# 目的
シリアルポート通信でログを見る

# 技術
- VSCodeをインストール
- nRF Connect拡張機能をインストール
- サンプルからプロジェクトをコピー。ここではBlinkyを使用
- コンパイルをクリック
- nRF Connect for DeskのProgrammerで書き込み
- nRF Connect for DeskのSerial Terminalでログを確認

# 雑談
覚えていますが、初めて組み込み開発をしたとき、私はシリアルポートが何かさえ知りませんでした。人に聞いても誰も教えてくれず、先輩からは使いにくいシリアルポートツールをダウンロードするよう指示され、説明もなくただ「ダウンロードしろ」と言われました。その経験は非常に悪い印象を残しました。最終的に、ターミナルで `screen /dev/tty.usbserial-14440 115200` コマンドを使ってログを見ることができましたが、その結果はとても良かったです。先輩は逆に「このツールはどこで見つけたのか？」と私に尋ねました。


# 用語
- [シリアルポート](https://ja.wikipedia.org/wiki/シリアルポート)*よく使われる通信プロトコル*
 
- [nRF52840 Dongle](https://www.nordicsemi.com/Products/Development-hardware/nRF52840-Dongle):*開発ボード*

# 関連記事

- [nRFConnectSDKを基盤としたSesameの暗号通信](https://qiita.com/tse123321/items/c0fa105cd5b9f14c2a0c)
[Sort Algorithm] 整列アルゴリズム一覧

# 一覧
||名称|詳細|
|:--|:--|:--|
|逐次添加|バブルソート|**隣り合う数字を比較**して、小さい数字が前に来るように入れ替える<br>1回の操作毎に**最小値**または**最大値**が決まる|
|分割統治|クイックソート|**ランダムに基準の数字を選び**、基準より小さい数字と大きい数字のグループに分ける<br>これを繰り返す|
|分割統治|マージソート|**ほぼ同じ長さの数字列にグループ化し**、分割できない長さになった時点から、グループ内で小さい順に並べる|
|逐次添加|選択ソート|未処理の数字列から**最小の数字を探索し**、未処理の数字列の最初の数字と入れ替える|
|逐次添加|挿入ソート|未処理の数字列から一つずつ取り出し、**整列済の部分の適切な位置に挿入**する|

# バブルソート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/7e2361f3-852e-0144-efb0-f0d788e01f53.png)

# クイックソート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/df680fe2-129f-a190-a820-47e33543b4c5.png)

# マージソート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/e208435d-c0b9-c56a-9e17-515a026b6716.png)

# 選択ソート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/f1ed2ea2-eb4a-cc3e-9b80-4f598e43dd05.png)

# 挿入ソート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/240e1006-a5ef-3077-fac3-5d3d64f946d6.png)




# 参考リンク
- [令和6春7_バブルソート](https://www.ap-siken.com/kakomon/06_haru/q7.html)
- [令和元春8_分割統治](https://www.ap-siken.com/kakomon/18_haru/q12.html)
【SQL】シングルクォーテーションとダブルクォーテーションの違い

# はじめに
SQLを使っていてシングルクォーテーションを使うべきなのかダブルクォーテーションを使うべきなのか分からなくなることがあるので備忘録として残します。
同じような方のお役に立てば幸いです。

# シングルクォーテーション（'）
文字列リテラルを囲むために使用されます。
文字列リテラルとは、SQLクエリ内で文字列として扱われる値のことです。

例えば、以下のような使い方をします。
```
SELECT * FROM users WHERE name = 'John';
```

# ダブルクォーテーション（"）
識別子（テーブル名、カラム名など）を囲むために使用されます。
特に、識別子にスペースや特殊文字が含まれている場合に利用します。

例えば、以下のような使い方をします。
```
SELECT "first name" FROM users;
```

# まとめ
シングルクォーテーション：文字列リテラルに使用
ダブルクォーテーション：識別子に使用

基本的には上記使い分けで覚えておけば間違いないですが、利用するRDBMSによってはダブルクォーテーションを文字列リテラルとしても使用できるものもあるようです。
詳しくはこちらの記事に記載があります。

https://qiita.com/Ping/items/d5d8468dadd9c1287f5e

---
以上です。
Roadmap.shで学ぶFlutter - Styled Widgets -

# 導入
[roadmap.shのFlutter](https://roadmap.sh/flutter)の4本目です。
次はStyled Widgetsという項目です。
正直あまり意識したことがなかった範囲なのですが、本文にあるとおり、デザイン関連の内容になります。

https://docs.flutter.dev/ui/widgets/styling

# Styled Widgetsとは
Styled Widgetsとは、色、フォント、形状などのカスタムスタイルで装飾されたFlutterウィジェットのことです。これらは、既存のウィジェットをContainer、Theme、BoxDecorationなどの他のウィジェットでラップすることによって作成することができます。
Styled Widgetsを利用することでFlutterアプリの外観と感触を簡単にカスタマイズし、一貫したビジュアルスタイルを作成することができます。

## 例
- Containerウィジェット
    - 固定の幅、高さ、パディング、およびマージンを設定できます。
- Themeウィジェット
    - アプリ全体またはその一部のカラースキームとタイポグラフィを指定できます。
- BoxDecoration
    - ウィジェットにボーダー、背景色、およびボーダー半径を追加できます。

# Styled Widgets詳細内容
## MediaQuery

https://api.flutter.dev/flutter/widgets/MediaQuery-class.html

メディアクエリとは、デバイスに合わせて最適な画面サイズになるようにスタイル・レイアウトを調整するものです。

MediaQuery.sizeOfやMediaQuery.paddingOfなどの特定のメソッドを使用して現在のメディアの情報を取得する場合、そのプロパティが変更されるたびにウィジェットが自動的に再構築されます。

MediaQuery.ofを使用して情報を取得すると、MediaQueryDataの任意のフィールドが変更されるたびにウィジェットが自動的に再構築されます。
したがって、MediaQuery.sizeOfやMediaQuery.paddingOfを使用する方が効率的ですのでおすすめです。

範囲内にMediaQueryがない場合、MediaQuery.ofやMediaQuery.sizeOfのような"...Of"メソッドは例外をスローします。
代わりに、範囲内にMediaQueryがない場合に例外をスローする代わりにnullを返す「maybe-」バリアントメソッドを使用することができます。

## Padding

https://api.flutter.dev/flutter/widgets/Padding-class.html

Paddingは、子ウィジェットを指定されたパディングで挿入するウィジェットです。

レイアウト制約を子ウィジェットに渡す際に、指定された分だけ制約を縮小し、子ウィジェットが小さいサイズでレイアウトされるように調整します。
その後、パディングが子ウィジェットのサイズに合わせて自身のサイズを調整し、子ウィジェットの周りに空白を作り出します。

以下は、各方向に16ピクセルのパディングを持つCard内に「Hello World!」というテキストを表示する例です。

```dart
const Card(
  child: Padding(
    padding: EdgeInsets.all(16.0),
    child: Text('Hello World!'),
)
```

### デザインの議論
**Paddingウィジェット**を使うのと、Containerウィジェットの**Container.paddingプロパティ**を使うのとでは大きな違いはありません。
Container.paddingを利用すると、Containerは自動的にPaddingウィジェットを構築します。

**Containerは、複数のシンプルなウィジェットを組み合わせて便利なパッケージにまとめてくれています。**
- 例
    - Container.paddingプロパティはPaddingウィジェットを構築
    - Container.decorationプロパティはDecoratedBoxウィジェットを構築

Containerが不便だと感じるなら、シンプルなウィジェットを必要に応じて組み合わせて使用すれば良いでしょう。

## Theme

https://api.flutter.dev/flutter/material/Theme-class.html

Themeは子孫ウィジェットにテーマを適用します。

テーマとは、アプリケーションの色やタイポグラフィの選択を表すものです。

子孫ウィジェットは、現在のテーマのThemeDataオブジェクトをTheme.ofを使って取得します。ウィジェットがTheme.ofを使用すると、後でテーマが変更された場合に自動的に再構築されます。

# 終わりに
この記事では、Flutterアプリのカスタマイズとスタイリングに役立つStyled Widgets、MediaQuery、Padding、Themeについて詳しく説明しました。
MediaQueryを使うことでデバイスに応じたレイアウトの最適化が可能になり、PaddingとThemeを利用することでウィジェットの配置やテーマを柔軟に管理することができます。
これが誰かの役に立てばと思います。
Notion APIでロールアップのカラムを検索できないメモ


"Notion APIでロールアップのカラムの検索をする"という記事を前に書いてましたが、Notion APIでロールアップのカラムを検索できない事象が発生していました。


https://qiita.com/n0bisuke/items/b9977f08d9e001bc08ea


## 事象

```js
//色々省略

console.log(res.results[21].properties['課題カテゴリ']);
        console.log(res.results[21].properties['カテゴリ(自動化用)']);
```

```json
{
  id: 'XXxW',
  type: 'rollup',
  rollup: { type: 'array', array: [], function: 'show_original' }
}
{
  id: '%7Cyt~',
  type: 'formula',
  formula: { type: 'string', string: null }
}
```

## インテグレーションへの権限付与ミス

資料Checker的なインテグレーションを作っていて、そいつに権限があればアクセスできるようにしてたのですが、ロールアップ先のDBに対してインテグレーションの権限付与ができていなかったのが原因でした。

> ![スクリーンショット 2024-08-12 16.00.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/ee4b5e7e-524b-3fbe-447d-5ed28dcb63f0.png "スクリーンショット 2024-08-12 16.00.29.png")

> ![スクリーンショット 2024-08-12 15.59.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/f92ec94c-f41d-05cc-b344-a7bf85a6b394.png "スクリーンショット 2024-08-12 15.59.34.png")

こんな感じでセットすればOK

## 修正後

`課題カテゴリ`という項目ロールアップで別DBに中身があり、取得できてなかったのですが、ちゃんと取得できるようになりました。

```json
{
  id: 'XXxW',
  type: 'rollup',
  rollup: { type: 'array', array: [ [Object] ], function: 'show_original' }
}
{
  id: '%7Cyt~',
  type: 'formula',
  formula: { type: 'string', string: '最終制作企画' }
}
```

## まとめ

しっかり確認しましょう。
APIの仕様変更疑ってしまった。
Pythonのライブラリ一覧～アプリ作成編～

Pythonでアプリを作成する際には、アプリケーションの種類や目的に応じて使用するライブラリやフレームワークが異なります。本記事では、一般的な選択肢をいくつか紹介します。
# デスクトップアプリ
1. **Tkinter**
    - 標準ライブラリで簡単なGUIアプリケーションを作成するのに便利です
    - 学習コストが低く、小規模なプロジェクトに適しています
2. **PyQt/PySide**
    - クロスプラットフォームで高度なGUIを構築可能
    - 商用プロジェクトではライセンスに注意が必要です
3. **Kivy**
    - マルチタッチ対応のアプリケーションを作成でき、モバイルアプリの開発にも適しています

# ウェブアプリケーション
1. __Flask__
    - 軽量でシンプルなマイクロフレームワーク
    - 小規模なウェブアプリやAPIサーバーを構築するのに適しています
2. __Django__
    - フルスタックのウェブフレームワーク
    - 大規模なウェブアプリケーションに適しており、認証や管理機能が組み込まれています

# データサイエンス関連
1. **Streamlit**
    - データサイエンスプロジェクトのためのシンプルなウェブアプリケーションを作成可能
    - インタラクティブなダッシュボードやデータビジュアライゼーションに適しています

2. __Dash__
    - Plotlyによって開発された、データ可視化に特化したウェブアプリケーションフレームワーク

# その他
- **FastAPI**
    + 高速なAPIサーバーを構築するのに適しています。非同期処理に対応しており、パフォーマンスが高いです

選択するフレームワークやライブラリは、プロジェクトの要件や個々のニーズによって異なるため、上記の選択肢を参考にしてプロジェクトに最適なものを選んでください。
Knowledge Bases for Amazon Bedrock のチャンキング戦略を整理する

Knowledge bases for Amazon Bedrock のチャンキング戦略が追加されていたので、ユースケースを整理します。
(順次追記予定）

# KB のチャンキング戦略
現在選択できるチャンキング戦略は次のとおりです。

| 英語名 | 日本語訳 | 説明 |
|--------|----------|------|
| default chunking | デフォルトチャンキング | コンテンツをデフォルトサイズのチャンクに分割 |
| Fixed-size chunking | 固定サイズチャンキング | コンテンツを固定サイズのチャンクに分割 |
| Hierarchical chunking | 階層的チャンキング | 情報を子チャンクと親チャンクの入れ子構造に整理する |
| Semantic chunking | セマンティックチャンキング | サイズだけでなく内容に基づいてテキストを意味のあるチャンクに分割 |
| no chunking | チャンキングなし | チャンキング済のテキストを用意した場合に選択する |

# デフォルトチャンキング
- デフォルトチャンキングでは、テキストを約300トークンのチャンクに分割する
- ただし、文章が意味不明なところで勝手に区切られないように、文章の区切りを意識して分割する

# 固定サイズチャンキング
- チャンクごとのトークン数と重複率を指定することで、希望したサイズでチャンキングを行うことができる
- 重複率は「前後のチャンクとの重なり」のこと

# 階層的チャンキング
- テキストを親チャンクと子チャンクに分けて整理する
- RAG をする際は子チャンク側で検索を行い、親チャンクを返却する
- 入れ子構造だったり、階層構造をもつ文章に効果的。例えば、技術マニュアルとか、法的な文書、学術論文など
- サーバーワークスさんの記事が詳しい
- [RAGの精度向上がお手軽に！Amazon Bedrock のKnowledge BasesでAdvanced RAG機能がリリースされました - サーバーワークスエンジニアブログ](https://blog.serverworks.co.jp/bedrock-kb-advanced-rag)

# セマンティックチャンキング
- Semantic（意味的）という名前の通り、Embedding モデルによって計算された「文章の意味の近さ(=類似度）」に基づいてチャンク分割をする
- ほとんどのユースケースで検索精度が向上する（らしい）
- 本のテキストを分割 -> ベクトル化 -> 類似度が近いものを結合 のような動きをするらしい

# 参考
- https://docs.aws.amazon.com/bedrock/latest/userguide/kb-chunking-parsing.html#kb-advanced-parsing
- https://community.aws/content/2jU5zpqh4cal0Lm47MBdRmKLLJ5/a-developer-s-guide-to-advanced-chunking-and-parsing-with-amazon-bedrock
- https://speakerdeck.com/sonoda_mj/awsteragwozuo-rufa-fang
- https://speakerdeck.com/moritalous/amazon-bedrock-kb-oshi?slide=15
nRFConnectSDKを基盤としたSesameの暗号通信 #4 Toolchain Manager.

![nRF-Connect_desktop](https://www.nordicsemi.com/-/media/Images/Products/APPS/nRF-Connect_desktop.png?h=350&iar=0&mw=350&w=350&hash=4A2AA29009DDF2D23D52DD9C480CE11B)

![Toolchain Manager](https://i.imgur.com/HvqixDs.png)


# 動機
nRF Connect SDKの正確なインストール

# 目的

SDKのインストール：nRF ConnectでToolchain Managerを選び、必要なSDKバージョンをインストールします。

# 雑談
当時、消費電力を測定するためにPPK2を使用する際に、nRF Connect for Desktopを使っていました。ある日突然、nRF Connect SDKのインストールオプションが表示されるようになりました。


# 用語
 
- [PPK2](https://www.nordicsemi.com/Products/Development-hardware/Power-Profiler-Kit-2):*低消費電力測定ツール*

# 引用
- [[DX-DN][01] Nordic environment setup](https://hackmd.io/@PK/r1InsxMl5)


# 関連記事

- [nRFConnectSDKを基盤としたSesameの暗号通信](https://qiita.com/tse123321/items/c0fa105cd5b9f14c2a0c)
ラズパイにnnablaをインストール2024年版

# 現行のラズパイOSにnnablaをインストールする
nnablaはSONYが公開しているニューラルネットワークコンソール（nnc)で作ったAIモデルをpythonで動かすためのライブラリです。

現行のラズパイOSはDebian12(bookworm)ベースのOSです。
python3.11がインストールされておりnnablaの対応版が3.8〜3.10なのでpipではインストールできない。
なのでnnablaを使いたい場合、前のOS使えば比較的簡単にはいるが、
今回は新しいOSに入れるため少し苦労するのでインストール方法をまとめておきます。

# まずは、ソースからインストールしてみる。
git clone https://github.com/sony/nnabla
でソースを持ってこれます。
これをコンパイルするにはcmakeでmakefileを作り、makeするとインストールモジュールを作ることができる。
具体的には
gitで展開したフォルダに、CMakeLists.txtがあるのでBuildフォルダを作成してBuildフォルダから
```
cd Build
cmake ../
```
でMakefileを作ってくれる。
この際に様々なプログラムを使用するようで最終的にはラズパイOSにcythonを入れておく必要がある。
で、最終的なインストールモジュールを作る際にcythonで操作する部分がエラーを起こして止まる。
（どうもインストールされるバージョンの差？かも知れない）
ということで、ソースからのコンパイルは諦める。

# なのでサポートされているバージョンのPythonをソースからインストールする。
その際必要になるモジュールは、pyenvで利用されるものにnnablaで必要になるものを加えたものを予めインストールしておき、
ソースをpython.orgからダウンロードします。
```
sudo bash
apt install build-essential libffi-dev libssl-dev zlib1g-dev liblzma-dev libbz2-dev libreadline-dev libsqlite3-dev libopencv-dev tk-dev libhdf5-dev

tar xovfz Python3.9.15.tgz
cd Python3.9.15
./configure
make
make install
```
以上でPython3.9.15のインストールが環境するので
pip3.9 install nnabla
インストールがが完了する。
半導体テストエンジニアが、初めて半導体を設計してみた

# 自己紹介
私、半導体テストエンジニアをやっております。
半導体を測定するためのテストプログラム開発・製品評価などを行っています。

今回はこちらの「初めての半導体設計・製造体験！一日で作るインバータ回路」
イベントに参加しました。
https://ishikai.connpass.com/event/322814/

主催されているISHI会（Inter-linked Society on Homemade IC Kai）さんは、
「半導体（ASIC/LSI/IC）やEDA/PDKのオープン化」を趣旨とされているグループだそうです。
(個人単位で半導体を作ることを目指されているようですね)

私自身、半導体自体の設計は未経験でした。
レイアウト？検証？聞いたことはあるけど、まだ理解がふんわりしてるな・・・?
どんなことをするのか考えながら、会場に向かいました。

# 会場到着まで
会場は渋谷フクラスの16F GMO yours.
天気も良くて、景色もめちゃ綺麗！
(写真撮り忘れたのでイメージ画像で笑)
![Shibut.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815132/c3570d57-36ea-6a12-e660-31e6e035e7c1.png)

会場には既に若手～ベテラン風の方が20人ほど居られました。

流れはこんな感じ。
①回路仕様決定
②動作SIM(シミュレーション)用回路設計→動作SIM
③レイアウト設計→レイアウト検証用回路製作→レイアウト検証(検証用回路との同一性を確認)

※レイアウト＝回路図を元に実際の部品配置や、配線方法を決めること。
レイアウト用回路はSIM回路と少し異なっているようで、別途作成。

ちなみに今回作成したのはインバータ回路。
Hを入れるとLが出力されます。
![インバータ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815132/145d4a42-97f8-8364-775d-e46010741c97.png)




# さあ、いよいよ設計開始！
の前に・・・
まずはソフト動作用の環境構築。
私自身、Linuxに慣れていなかったこともあり、悪戦苦闘しながら、メンターさんに助けて貰いながら導入できました。
(実際、環境構築できれば50%クリアだそうです)
遊ぶための準備はOK!


XSchem：回路設計・SIMソフト
https://note.com/akira_tsuchiya/n/nb1aefe086773
Klayout：レイアウト用ソフト
https://note.com/akira_tsuchiya/n/nca6903247ce1

使い方をメンターさんや周りの人に聞きながら作りました。

1番興味深かったのは、レイアウトです。
部品を置いて、配線する作業ですが、
・部品の量が増えたらどうなるのか？
・配線の方法を変えてみたらどうなるのか？
想像を膨らませました。

# 完成！
皆さんのご協力もあり、無事完成！

![完成品.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815132/4720fa41-ecc2-557b-90b7-a2320aa8aa79.png)


せっかくなので、PchのWを33umにして作ってみました笑
さて、どんな挙動になることか…?

半導体設計を一通り経験できたこと、
なによりこれが実際のICとして実装されることが嬉しく、楽しみです！
(テスト開発者としては、是非完成品で出力波形取ったりテストをしてみたい笑)

もう1つ良かったのは、情熱を持って半導体を楽しんでる方々に沢山出会えたことです🔥

主催の今村さんの作品(マイクロサイズのイライラ棒など)も見せてもらいました。
遠路はるばる大阪からやって来た学生さんも！

私の中の半導体熱を灯されて、帰ったのでした～

今後の情報は、Ishi会Discord等で展開されるそうです。
https://ishi-kai.org/links/

皆様も、参加してみてはいかがでしょうか？

![Ishi会のシール.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815132/50fffc30-4722-08c0-93d9-4b9cdbee3a09.png)
ABC366 Fを解いてみた

ABC366 Fについて、自分の解法が公式解説とは違ったので記録しておきます。

## 問題概要
$N$個の1次関数$f_i(x)=A_ix+B_i$が与えられるので、そのうち相異なる$K$個を選んで合成関数を作り、$x=1$における合成関数の最大値を求めましょう。

- $1 \le N \le 200,000$
- $1 \le K \le \min(N,10)$

- $1 \le A_i,B_i \le 50$

## 考えたこと
$A_i,B_i$が正であることから、$x$が大きいほど$f_i(x)$の値が大きくなることが解ります。
また$K$の制約が小さいので、選んだ$f_i$を覚えながらDPすれば良さそうなです。
相異なる$N$以下の$k$個の正の整数の集合を$P_k=\set{p_1,…,p_k}$と書くことにします。
この時、$i \in P_k$を満たす$f_i$の合成関数の値の最大値を、$dp[P_k]$で表すことにすると、下記のような漸化式が考えられます。
```math
\displaylines{
dp[\phi]=1\\
dp[P_{k+1}] = \max(f_i(dp[P_k]))   (ただしi \notin P_k)}
```


このままだと、$dp[P_k]$ のパターン数が $ {}_N \mathrm{C} _K $ となるため、TLEです。

## 高速化の工夫
### 状態数削減
最適解の$P_k$の要素数は高々$\max(K)=10$です。
また、$x$を固定した時、各$f_i(x)$の値は一位に決まります。
ということは、$dp[P_k]$から$dp[P_{k+1}]$を求めるとき、$f_i$のうち上位から$K$個の中に最適解を構成する$f_i$が含まれているはずです。

### 事前計算
$x$を固定した時の各$f_i(x)$の値を前計算しておきます。
$B_i \le 50$ より、$x \gt 50$ の時の$f_i$の大小関係は$x=50$の時と同じですので、前計算は$1 \le x \le 50$の範囲で実施すれば十分です。[^1]

[^1]: 最初の投稿時に「実は $x \le 26$の範囲で前計算すれば十分」とか書いていましたが、間違いです。すみません。$Ax+50$と$(A+1)x+1$を比較すると、少なくとも$1 \le x \le 49$の範囲で必要でした。

$x$の値を固定した時、$f_{p_1}(x) \ge f_{p_2}\ge … \ge f_{p_N}$となるように$p_i$をソートし、ソート結果を$q[x]$と書くことにします。$q[x]$の$i$番目の値が$q[x][i]$です。
また、上述の通り、記憶するのはソート結果のうち上位$K$個で十分です。

## ACコード
上記の工夫を実装すると下記のようになります。
Rustだと、`BTreemap`のキーに`BTreeSet`を放り込んだりできて楽ですね。
ちなみに[実行時間](https://atcoder.jp/contests/abc366/submissions/56625031)は144ms。少し工夫して、[前計算部分を必要になった時だけ実行](https://atcoder.jp/contests/abc366/submissions/56676760)するようにすると、37msになりました。

```Rust
#![allow(non_snake_case)]
use proconio::input;
use std::cmp::*;
use std::collections::*;

fn main() {
    input! {
        N:usize, K:usize, AB:[(i64,i64);N]
    }

    let mut abi = vec![];
    for i in 0..N {
        abi.push((AB[i].0, AB[i].1, i));
    }
    // xを固定した時のf_i(x)のうち、上位K個を事前計算
    let mut fp_max = vec![vec![]; 51];
    for x in 1..=50 {
        abi.sort_by_key(|&(a, b, _)| a * x + b);
        for i in 0..K {
            fp_max[x as usize].push(abi[N - 1 - i])
        }
    }
    let mut dp = BTreeMap::new();
    dp.insert(BTreeSet::new(), 1);
    let mut ans = 0;
    for _ in 0..K {
        let mut np = BTreeMap::new();
        for (set_prev, &val_prev) in dp.iter() {
            for &(a, b, i) in fp_max[min(val_prev, 50) as usize].iter() {
                if set_prev.contains(&i) {
                    continue;
                }
                let mut set = set_prev.clone();
                set.insert(i);
                let reference = np.entry(set).or_insert(0);
                *reference = max(*reference, a * val_prev + b);
                ans = max(ans, a * val_prev + b);
            }
        }
        dp = np;
    }
    println!("{}", ans);
}
```

## 計算量
事前計算では、N個の要素を定数($50$)回ソートするため$O(N \log N)$となります。
一方、後半`for _ in 0..K {}`のループ部分の計算量については、よくわかりません。[^2]
一見dpの要素数が最大で$K^K$ぐらいになりそうです。
が、実際に試してみると、前計算にかかる時間のほうが支配的で、この部分の寄与はほとんど影響がないようです。
おそらくですが、ほとんどの場合、数回のループで$x>50$となってしまうため、$dp$のキーがほとんど同じになってしまうのではないかと。

[^2]: もしかしたら嘘解法かもしれません。この部分の計算量が解る方、コメントお待ちしています。
Pythonを使用したメール送信スクリプトの作成

## はじめに

この記事では、Pythonを使用してメールを送信するスクリプトの作成方法を紹介します。このスクリプトは、JSONファイルから設定を読み込み、SMTPサーバーを介してメールを送信し、必要に応じてファイルを添付する機能を持っています。

サンプルコードはGitHubリポジトリで確認できます: [python-mail-sender](https://github.com/tonbiattack/python-mail-sender)

## 使用するライブラリ

このスクリプトでは以下のライブラリを使用しています。これらは標準ライブラリに含まれているため、追加のインストールは不要です。

- `json`: JSONファイルから設定を読み込むために使用します。
- `smtplib`: SMTPサーバーを介してメールを送信するために使用します。
- `email.mime`: メールの作成に必要な各種MIMEタイプを扱います。
- `os`: ファイルパスの操作やファイル名の抽出に使用します。

## スクリプトの概要

このスクリプトは以下の3つの主要な部分で構成されています。

1. **設定の読み込み**: メールアドレスやSMTPサーバーの設定、メールの件名や本文をテンプレートから読み込みます。
2. **メールの作成と送信**: 設定に基づいてメールを作成し、SMTPサーバーを介して送信します。
3. **ファイルの添付**: 必要に応じてファイルをメールに添付します。

### 設定の読み込み

まず、メールアドレスや件名、本文のテンプレートをJSONファイルやテキストファイルから読み込みます。

```python
def load_email_settings():
    with open('mail/mail_address.json', 'r', encoding='utf-8') as f:
        email_settings = json.load(f)["email_settings"]
    with open('mail/mail_subject.txt', 'r', encoding='utf-8') as f:
        mail_subject = f.read().strip()
    with open('mail/mail_body.txt', 'r', encoding='utf-8') as f:
        body_template = f.read().strip()
    return email_settings, mail_subject, body_template
```

## SMTPサーバーの設定の読み込み
次に、SMTPサーバーの設定をJSONファイルから読み込みます。

```py
with open('settings/smtp.json', 'r', encoding='utf-8') as f:
    smtp_settings = json.load(f)
```

## メールの作成と送信
以下のコードは、メールを作成し、SMTPサーバーを介して送信する部分です。
```py
def send_email_with_attachment(email_settings, subject, body_template, result_data, attachment_path):
    msg = MIMEMultipart()
    msg['From'] = f"{email_settings['FromName']} <{email_settings['From']}>"
    msg['To'] = ", ".join(email_settings['TO'])
    msg['Cc'] = ", ".join(email_settings['CC'])
    msg['Subject'] = subject
    msg['Date'] = formatdate(localtime=True)

    body_filled = body_template.format(
        total_count=result_data['totalCount'],
        succeed_count=result_data['succeededCount'],
        added_count=result_data['addedCount'],
        error_count=result_data['failedCount']
    )
    msg.attach(MIMEText(body_filled, 'plain', 'utf-8'))

    with open(attachment_path, "rb") as attachment:
        part = MIMEBase('application', 'octet-stream')
        part.set_payload(attachment.read())
        encoders.encode_base64(part)
        filename = os.path.basename(attachment_path)
        part.add_header('Content-Disposition', 'attachment', filename=filename)
        msg.attach(part)

    with smtplib.SMTP(smtp_settings['smtp_host'], smtp_settings['smtp_port']) as server:
        smtp_user = smtp_settings.get('smtp_user')
        smtp_password = smtp_settings.get('smtp_password')
        if smtp_user and smtp_password:
            server.login(smtp_user, smtp_password)
        server.send_message(msg)
```

ここでは、MIMEMultipartオブジェクトを使用してメールを作成し、本文を設定し、ファイルを添付しています。その後、smtplib.SMTPを使用してSMTPサーバーに接続し、メールを送信します。

## まとめ
このスクリプトを使用することで、簡単にメールを自動化して送信できるようになります。設定ファイルを適切に準備することで、様々なメールを動的に作成し、送信することが可能です。
エンジニア転職に最適！おすすめ転職サイトの活用法

エンジニアとしてのキャリアアップを考えていますか？転職を視野に入れつつも、まだ本格的な行動には踏み切れていない—そんなあなたにぴったりなのが、転職サイトの活用です。<b>転職サイトは面倒な手続きや時間を取られる面談なしで、豊富な求人情報にアクセスできます。

今回はエンジニア向けのおすすめ転職サイトと、その効果的な使い方をご紹介します。市場動向のチェックから自分に合った求人探しまで、転職サイトを使いこなしてあなたの次のキャリアステップを見つけましょう。



## 転職エージェントと転職サイトの違い
エンジニアとしてのキャリアアップを考える際、転職は大きな選択肢の一つです。しかし、転職活動を始めるにあたって、「転職エージェント」と「転職サイト」のどちらを利用すべきか迷う方も多いでしょう。それぞれの特徴と利点、そして適した活用シーンを理解することで、あなたの転職活動をより効果的に進められます。



### 転職エージェントの特徴
転職エージェントは、個人に寄り添ったサポートを提供する専門家です。

- 個別カウンセリング
- 非公開求人へのアクセス
- 面接対策と年収交渉

業界・企業情報の提供

[>> 転職エージェントの特徴について詳しくはコチラ！](https://taishi-official.com/2024/07/06/2604/#toc2)



### 転職サイトの特徴
転職サイトは、自分のペースで幅広い求人情報にアクセスできるプラットフォームです。

- 豊富な求人情報
- 検索の自由度
- 24時間アクセス可能
- 匿名性

[>> 転職サイトの特徴について詳しくはコチラ！](https://taishi-official.com/2024/07/06/2604/#toc3)



### 転職エージェントと転職サイトそれぞれの活用シーン
転職エージェントと転職サイト、どちらを選ぶべきかは状況によって異なります。

<b>【転職エージェントが適している場合】

- 具体的な転職先や条件が決まっている
- キャリアプランについて専門家のアドバイスが欲しい
- 忙しくて自分で情報収集する時間がない
- 非公開求人や詳細な企業情報にアクセスしたい

<b>【転職サイトが適している場合】

- 転職市場の全体像を把握したい
- まだ転職を迷っている段階で、気軽に情報収集したい
- 自分のペースで、じっくりと求人を探したい
- エージェントとの面談や連絡のやり取りが面倒に感じる

理想的には両方を上手く組み合わせることで、より効果的な転職活動が可能になります。例えば最初は転職サイトで市場調査をし、ある程度方向性が定まったら転職エージェントに相談するという流れが効果的でしょう。



## 転職サイトを利用するメリット
エンジニアが転職サイトを利用するメリットとして、以下の3点があります。

- 求人情報の豊富さと多様性
- 自分のペースで情報収集できる
- エージェント面談なしで市場調査ができる

[>>各メリットの詳細を知りたい方はココをクリック！](https://taishi-official.com/2024/07/06/2604/#toc6)



## おすすめのエンジニア向け転職サイト
私がエンジニアにおすすめしたい転職サイトは、以下の3つです。

- [リクナビNEXT](https://taishi-official.com/2024/07/06/2604/#toc10)
- [doda](https://taishi-official.com/2024/07/06/2604/#toc11)
- [Green](https://taishi-official.com/2024/07/06/2604/#toc12)

詳しく知りたい転職サイトをクリックすると、詳しい説明に飛べますので、そちらをぜひご覧ください。



## 転職サイトを活用するタイミング
転職サイトを活用するタイミングとしておすすめなのが、以下の3点のようなタイミングです。

- 転職を迷っている段階で
- 市場調査として
- エージェントに相談する前の準備

[>> タイミングついて詳細はココを見てください！](https://taishi-official.com/2024/07/06/2604/#toc14)



## まとめ
今回は転職に興味のあるエンジニアに向けて、転職サイトと転職エージェントの違いや転職サイトのおすすめ活用法、おすすめの転職サイトについてご紹介いたしました。<b>本気で転職を考えているのであれば、転職エージェントを利用したほうが良いです。ただ転職に興味があるくらいの方や、焦らず自分のペースで転職活動を進めたい方にとっては転職サイトの利用もおすすめです。



### おまけ



https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

https://taishi-official.com/changing-engineer/

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- Instagram：https://www.instagram.com/taishi_will_be/
- YouTube：https://www.youtube.com/@Engineer_ILLBE
- TikTok：https://www.tiktok.com/@taishi_will_be
- note：https://note.com/taishi_wii_be/

<br>

最後にいいねお願いします:thumbsup:
表形式のデータからコマンドを一括で作成する方法

# 解決したい問題
Windows環境で、複数の要素に対して同じコマンド、シェルスクリプトを打ちたいことがありました。今回それらコマンド、シェルスクリプトを一つ一つ作成するのではなく、Excelを使用し、一括で作成できる方法をまとめました。
備忘録代わりにここに記載いたします。

# 前提条件
サーバの起動コマンド
```/u02/user_pro/wls_domains/[WLSドメイン]/start_[管理サーバ]_administrator.sh```

| [WLSドメイン] |[管理サーバ]  |
|:-----------  |:------------|
| POP3WLS1S_D  | POP3WLS1S_M |
| POP3WLS2S_D  | POP3WLS2S_M |
| POP3WLS3S_D  | POP3WLS3S_M |
|POP3WLS4S_D   | POP3WLS4S_M |

サーバの起動コマンドに対し、上記表の[WLSドメイン][管理サーバ]を置き換えたコマンドを作成し、以下のようなコマンド一覧を作成する。

```
/u02/user_pr/wls_domains/POP3WLS1S_D/start_POP3WLS1S_M_administrator.sh
/u02/user_pr/wls_domains/POP3WLS2S_D/start_POP3WLS2S_M_administrator.sh
/u02/user_pr/wls_domains/POP3WLS3S_D/start_POP3WLS3S_M_administrator.sh
/u02/user_pr/wls_domains/POP3WLS4S_D/start_POP3WLS4S_M_administrator.sh
```

# 解決策
Excelで以下の表を作成する。
A列に数式列を入力し、B列に置換用のコマンド、C列、D列は置換後の要素を記載する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3842895/f09dfa5f-9c95-9918-1a02-2bd769f52b9c.png)

A列に記入する数式列は以下のようにする。
```=SUBSTITUTE(SUBSTITUTE(B2, "C2", C2), "D2", D2)```


何かの参考になればと思います。
メール署名がメールブランディングの鍵となる理由

## メール署名がメールブランディングの鍵となる理由

些細なことのように思えるかもしれませんが、メール署名は個人的なコミュニケーションと仕事上のコミュニケーションの両方で重要な役割を果たします。[MySignature](https://mysignature.io/jp) では、見落とされがちなこの要素の可能性を最大限に活用できるようお手伝いしています。当社のメール署名ジェネレーターを使用すると、ブランドを強化するだけでなく、コミュニケーションに洗練されたインパクトを与えるプロフェッショナルな署名を簡単に作成できます。

### メール署名とは何ですか？

メール署名は、メールの末尾に自動的に追加されるテキストブロックです。通常、名前、役職、会社名、連絡先の詳細、場合によっては会社のロゴや個人の写真などの重要な情報が含まれます。本質的には、送信するすべてのメールに添付されるデジタル名刺です。

![template.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849506/9a4b841c-b0d2-966c-8baa-96cbb7718fe4.png)

### メールブランディングに効果的な理由

**プロフェッショナリズムと信頼性**: 巧みに作成されたメール署名は、プロフェッショナリズムを高め、信頼性を確立できます。細部に注意を払い、与える印象に気を配っていることを示します。これは、ブランドを強化し、洗練されたイメージを伝える簡単な方法です。

**ブランディングの機会**: メール署名は、控えめながらも効果的なブランディングツールです。会社のロゴ、ブランドカラー、一貫したフォントを含めることで、一貫性のある認識しやすいブランドプレゼンスを作成できます。この一貫したブランディングは、会社のアイデンティティを強化し、コミュニケーションをより記憶に残るものにするのに役立ちます。

![joutnalist-student-email-signature-example.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849506/00609f2c-4a31-2c89-1137-e1ce3d81522c.png)


**連絡先情報**: メール署名の主な機能の1つは、受信者に重要な連絡先情報を提供することです。これには、電話番号とメールアドレスだけでなく、会社のウェブサイト、ソーシャルメディアプロファイル、その他の関連リンクも含まれます。これにより、受信者は簡単に連絡を取るために必要なすべての情報を得ることができます。

**行動喚起**: メール署名は、行動喚起を含めるのに最適な場所です。新製品の宣伝、ウェビナーへの招待、ソーシャルメディアでのフォロー促進など、適切に配置されたCTAは、エンゲージメントとコンバージョンを促進できます。

![template-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849506/95cd595a-07c5-b349-db89-8c2e31abe63d.png)

**法律およびコンプライアンス情報**: 特定の業界や地域では、メール署名に法的免責事項、機密保持通知、またはコンプライアンスステートメントを含めることが義務付けられています。これは、法的要件を満たすのに役立つだけでなく、プロフェッショナリズムと信頼をさらに高めることにもなります。

### メール署名を仮想の握手と考えてください

メール署名は、メールのフッター以上のものです。それは仮想の握手です。実在のユーザーの52%が、しっかりとしたメール署名がクライアントと効果的に関わるための鍵であると考えています。一方、これに反対する人はわずか3.4%です。この統計は、よく練られたメール署名がプロフェッショナルな関係を確立し維持する上でいかに重要であるかを強調しています。

![image 254.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849506/cc048fb6-0d91-7bff-b748-775814d2916c.png)

### メール署名が必要なのは誰ですか？

企業: あらゆる規模の企業にとって、プロフェッショナルなメール署名は不可欠です。これにより、従業員が送信するすべてのメールに一貫したブランドイメージが維持され、重要な連絡先の詳細が提供されます。これは、社内および社外のコミュニケーションにとって非常に重要です。

**フリーランサーと起業家**: フリーランサーや起業家の場合、メール署名は信頼性とプロ意識を確立するのに役立ちます。これは、自分を真面目なビジネスマンとして紹介し、潜在的なクライアントに必要なすべての連絡先情報を提供する簡単な方法です。

![template.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3849506/92b424ec-8d4e-c5b8-ccce-a790365982d8.png)


**営業およびマーケティングの専門家**: 営業およびマーケティング担当者にとって、メール署名はリードとコンバージョンを促進する強力なツールになり得ます。最新のキャンペーン、特別オファー、またはソーシャルメディアプロファイルへのリンクを含めることで、すべてのメールをエンゲージメントの機会に変えることができます。

**カスタマーサポートチーム**: カスタマーサポート担当者は、明確で情報豊富なメール署名を持つことでメリットを得られます。これにより、顧客に追加の連絡オプションが提供され、サポートチームのプロ意識と支援の準備ができていることが強化されます。

**採用担当者とHRの専門家**: 採用またはHRに携わっている場合、メール署名で求人、企業文化、または今後のイベントに関する重要な情報を伝えることができます。これは、会社を選ばれる雇用主としてさりげなく宣伝する方法です。

### 結論

メール署名は些細なことのように思えるかもしれませんが、プロ意識を高め、ブランドを強化し、コミュニケーションを改善するための強力なツールです。大企業に所属している方、個人事業主の方、またはその中間の方であっても、効果的なメール署名の作成に時間を費やすことで、大きなメリットが得られます。[MySignature](https://mysignature.io/jp)を使用すると、メール署名が機能的な目的を果たすだけでなく、スタイルとインパクトで目立つようにすることができます。そのため、少し時間を取って現在のメール署名を確認し、最大限に機能していることを確認してください。
いざ「pytest」の世界へ！現場のIT技術！～Pythonテスト駆動開発～

## はじめに

開発工程で知った素敵な技術フレームワークを紹介します！

Pythonで開発している時のテスト方法は何を使用していますか？

ソフトウェア開発において、テストは品質を保証するための重要なプロセスです。
Pythonでは、pytestが非常に人気のあるテストフレームワークとして広く使用されています。本記事では、書籍を参照しつつ、pytestの基本的な使い方、特にassert文を使ったテストの書き方を解説します。また、さまざまなテストパターンを実例とともに紹介し、テストコードを書く際のヒントを提供します。

![Technology Business.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180499/e4c4d0be-8379-62d1-3985-f4c43278272f.jpeg)



## ざっくり理解


「Pythonで作成した関数をテストするツール」です！
①「関数に入力する仮データを準備する」
②「予め期待される値を準備する」
③これら①と②の二つを突合させるためのスクリプトを書いた別ファイルを準備する
④テスト用の別ファイルを実行して結果を確認する

などです。

## pytestの基本

### assert文によるテスト

まず、pytestの基本となるのがassert文を使ったテストです。assert文は、条件が真であることを確認するためのPython標準の構文であり、これを活用してテストを記述します。

### シンプルなテストケース

例えば、リストの合計値をテストする場合、以下のように書くことができます。

```py
def test_sum(): assert sum([1, 2, 3]) == 6, "合計が間違っています！"
```

このテストでは、sum([1, 2, 3])の結果が6であることを確認しています。もしassert文の条件が満たされない場合、テストは失敗し、エラーメッセージが表示されます。

## 実践的なテストパターン

pytestは非常に柔軟なフレームワークであり、様々なテストパターンをサポートしています。ここでは、いくつかの代表的なパターンを紹介します。

### 1. 例外処理のテスト

特定の条件下でエラーが発生するかを確認するテストは重要です。pytestでは、pytest.raisesを使って例外が発生するかをテストできます。

```py
import pytest

def testzerodivision():

　with pytest.raises(ZeroDivisionError):

　　1 / 0
```

このテストでは、1 / 0がZeroDivisionErrorを発生させることを確認しています。

### 2. パラメータ化テスト

複数の入力に対して同じテストを行いたい場合、pytestのパラメータ化機能が役立ちます。

```py
@pytest.mark.parametrize("input,expected", [
    ([1, 2, 3], 6),
    ([1, 1, 1], 3),
    ([0, 0, 0], 0),
])
def test_sum(input, expected):
    assert sum(input) == expected
```

これにより、異なるデータセットで同じ関数をテストできます。

### 3. フィクスチャを使ったテストの再利用

共通のセットアップコードを複数のテストで使い回したい場合、pytestのフィクスチャ機能を使用します。

```py
import pytest

@pytest.fixture
def sample_data():
    return [1, 2, 3, 4, 5]

def test_sum(sample_data):
    assert sum(sample_data) == 15
```

この例では、sample_dataというフィクスチャがテスト関数に渡され、その結果を使ってテストを行っています。

### 4. カスタムマーカーを使った条件付きテスト

特定の条件下でのみテストを実行したい場合、カスタムマーカーを使うことができます。

```py
import pytest

@pytest.mark.slow
def test_slow_function():
    import time
    time.sleep(2)
    assert True
```

このテストは、pytest -m slowと指定することでのみ実行されます。

## まとめ

pytestは、そのシンプルさと強力な機能で、Python開発におけるテストを効率的に行うためのツールです。assert文を使った基本的なテストから、例外処理やパラメータ化、フィクスチャなどの実践的なパターンまで、多様なテスト手法を使いこなすことで、品質の高いソフトウェアを開発することができます。

参考図書：『テスト駆動開発 Pythonでの実践』第2版
LibTorchで Found at least two devices 'cuda:0' and 'cpu' となってしまう問題

# 要約

TorchScript を [torch::jit::load()](https://pytorch.org/cppdocs/api/function_namespacetorch_1_1jit_1a04b5d0bd50137170c8be4901169309b6.html) で読み込むときは、第２引数にデバイス名 (torch::kCUDA など) を書いてあげるとうまくいきます。（GPUを使用する場合）

```cpp:Example.cpp
// 例えば、第２引数にkCUDAを指定してあげる
model_ = std::make_unique<torch::jit::Module>(torch::jit::load(modelPath_, torch::kCUDA));
```

▼ to 関数を使用してもタイトルのエラーを吐きます。
```cpp
models_.to(device_); // これを実行してGPUに送っても不完全
```

# 環境

OS : Ubuntu 22.04
CUDA : CUDA Toolkit 12.4
LibTorch : 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3607016/43c8b869-7a05-5b22-d8d2-434a90bbdea9.png)

使用フレームワーク : Qt 6.7.2

# 状況

[YOLOv10](https://docs.ultralytics.com/ja/models/yolov10/) を Libtorch で動かしたい。
[公式GitHub](https://github.com/THU-MIG/yolov10/releases) から .pt ファイルをダウンロードして、[公式サイト](https://docs.ultralytics.com/ja/integrations/torchscript/)を参考に、TorchScript 形式にするところまではできた！

よーし、あとはこれを読み込んで、検出を行うプログラムを書こう。

```cpp:Executor.cpp
#include <Executor.h>

bool Executor::Load()
{
    canUseCUDA_ = torch::cuda::is_available();
    device_ = canUseCUDA_ ? torch::kCUDA : torch::kCPU;
    
    try
    {
        model_ = std::make_unique<torch::jit::Module>(torch::jit::load(modelPath_));
        return true;
    }
    catch (const c10::Error& e)
    {
        qDebug() << e.msg(); // Qt のデバッグ用関数。std::cout みたいなもの
        return false;
    }
}

void Executor::Detect(const QImage& qimage)
{
    // QImage を テンソルに変換する関数（ユーザー定義）
    auto img_tensor = QImageToTensor(qimage);

    // アスペクト比を変えることなく、入力画像が 640×640 に収まるように縮小 or 拡大（ユーザー定義関数）
    img_tensor = ResizeImage(img_tensor);

    // パディングを行い、テンソルのサイズが 1×3×640×640 (= input)になるよう調節する（ユーザー定義関数）
    img_tensor = PadImage(img_tensor);

    // モデルとテンソルを GPU に送る
    models_.to(device_);
    img_tensor.to(device_);

    // 実行
    auto output = model_->forward({img_tensor});

    if(canUseCUDA_){
        detections_ = output.toTensor().cuda();
    }
    else{
        detections_ = output.toTensor().cpu();
    }

    // 検出されたオブジェクトのデータを保存したりする
}
```

-----

ということで動かしてみよう。ん？エラー？どれどれ

```txt:Error
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu! 
```

いや、テンソルはすべてGPU側に送っているが？

```cpp:IncompleteProgram.cpp
models_.to(device_);
img_tensor.to(device_);
```

# 解決法
いろいろ探し回った結果、Github の issue で解決法を見つけました。（下のほう）

https://github.com/ultralytics/ultralytics/issues/7744

どうやら、モデルをロードするときは、モデルのパスとデバイス名の両方を与えてあげると良いらしいです。これによってすべてのテンソルが正常に GPU 側に送られます。

ということで、

```cpp:
// model_ = std::make_unique<torch::jit::Module>(torch::jit::load(modelPath_));

model_ = std::make_unique<torch::jit::Module>(torch::jit::load(modelPath_, device_));
```

としたら問題なく動いてくれました。
第２引数を与えない場合でもコンパイルエラーにはならないので注意が必要ですね。
rails パンくずリストの作り方（gem 'gretel'）

今回は業務の中で初めてパンくずリスト機能に触れたので、こちらについて勉強したことをまとめます。

## パンくずリストとは？
パンくずリスト（Breadcrumbs）は、Webサイトのナビゲーション要素の一つで、ユーザーが現在のページに至るまでの階層構造やパスを表示するためのものです。パンくずリストは、ユーザーが現在どの位置にいるのかを視覚的に示し、上位のページや関連するカテゴリーに簡単に戻れるようにするために利用されます。

## 実装方法
では実際にはどのように実装をするのか？

まず、下記のgemを使用します。
```
gem 'gretel'
```
このgemの名前の由来は、グリム童話の「ヘンゼルとグレーテル（Hansel and Gretel）」に登場するキャラクター、グレーテル（Gretel）から来ています。

「ヘンゼルとグレーテル」は、グリム兄弟によって記録された有名なドイツの民話です。物語の中で、ヘンゼルとグレーテルは森の中に置き去りにされますが、パンくずを道しるべとして使って家に戻ろうとします。このパンくずが、「パンくずリスト」（Breadcrumbs）というナビゲーション手法の由来となっています。

###
gemfileに記述したらbundle installをします。
```
bundle install
```

実装後にはconfigフォルダに「breadcrumbs.rb」が作成されます。

中には下記のような記述がされています。
これは親記事の設定をすることができます。「"Home"」はリストで実際に表示されるテキストです。
```
crumb :root do
  link "Home", root_path
end
```
そこから子要素を作っていきます。
```
crumb "ページ名" do
  link "ビューに表示される名前", "リンクされるURL"
  parent :親のページ名（現在の前のページ）
end

具体例：
crumb :user_new do
  link "ユーザー登録", new_user_path
  parent :root
end
```

これで裏側の設定は完了です。

最後に表示したい場所に下記を設定してあげることで、適切にリストを作成することができます。
実際に設定した箇所にページ移行するとパンくずリストが表示されるようになります。
```
= breadcrumbs separator: ">"
```
自動入力パスワード「●●●」の中身を表示させる方法

こんにちは、りょうです。
今回は自動入力のパスワードで「●●●」のようになっているやつの表示方法の紹介をします。
また、パスワード生成方法も一緒に紹介します

## パスワードの中身を表示しよう
:::note alert 
**注意**
人の端末で行ってパスワードを覗き見るのはやめてください
:::

**表示手順**
1: パスワードを自動入力して●●●が表示された状態にする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/3a1791f7-c9af-37e7-b77f-3abdbfdc42d5.png)

2: 次に``ctrl+I``を押して検証(デベロッパーツール)を開きます。

:::note info
このとき、Elementsの部分を開いておきます。
:::

3: そして左上にあるマークを押します。(↖みたいなやつです)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/f372b517-e254-3fc9-82a8-5b7a5bae0239.png)

4: その状態でパスワード入力欄にカーソルを合わせます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/34b68e93-458a-a6b7-a4d8-774436d9726b.png)

5: そうすると該当する部分が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/f629eedd-e868-f54d-968e-c548b44793df.png)

```
<input type="password" 〜その他諸々〜>
```
というようなものが出てくると思います。出てこなかったら出るまでやってください。

6: type="password"　の部分を **type="text"**　に変更するとパスワードが表示されます

![Screenshot 2024-08-08 18.31.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/af89013b-762c-2cdc-403a-77b69d3a88e3.png)

## パスワード生成の方法。
せっかくなのでオススメのパスワード生成方法を紹介します。

まず、Googleで自動生成してくれるとこはそれを使いましょう。
ただし保存してないと絶対に覚えられないので忘れないように。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/600b6419-c347-f18a-878e-7d4e55f09c79.png)

**サイトで生成**
ID Protectionさんの[こちらのサイト](https://idprotect.trendmicro.com/ja/vault/tool/password-generator)がオススメです。
日本語対応で、8〜40文字のものを生成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/d9791c28-b90f-8182-006a-d1312f11c501.png)

他にもこちらの[PasswordGenerator](https://www.graviness.com/app/pwg/)もオススメです。
個数や生成条件などを細かく設定できるのでたくさん必要な場合などは重宝します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/aaf8d2c6-e4be-2a89-9b8b-fbf974014c18.png)

## まとめ
今回はパスワードの黒丸の中身を見る方法＆生成方法の解説でした。
正直使い所はないですが、困ったときに覚えてたら便利かなあと思います。
わからないことがあればコメントしてくれれば返答します

ぜひ参加↓↓↓↓

**Discordにいる荒らしの情報や対策方法の共有をしている自鯖です**
https://discord.gg/ESRGwGQhxc
pandasでastype()がうまく動作しないときの対処法（非常に原始的）

## astype(int) がうまくいかない
```Python
df = pd.DataFrame(data=[["81", "100", "69", "78", "95"],["70", "93", "71", "82", "89"]],columns=["A", "B", "C", "D", "E"])
```

時々、df.astype(int)を実行しても、dtypeがobjectのままになる。

（大抵、例えば空白や特殊文字が含まれているなど、データが純粋な数字でなく、型変換に失敗しているだけだろうが）

そんなとき、自分は以下3つを試すようにしている。

#### 環境

>python = "^3.11"
>pandas = "^2.2.2"
>ipython = "^8.26.0"

### 各列ごとに型変換を試す

データフレーム全体を一度に変換するのではなく、各列を個別に変換してみると原因が特定しやすい。以下のような処理を試して、どの列が問題を引き起こしているか確認する。

```Python
import pandas as pd

# データフレームの作成
df = pd.DataFrame(data=[["81", "100", "69", "78", "95"], ["70", "93", "71", "82", "89"]],
                  columns=["A", "B", "C", "D", "E"])

# 各列ごとに整数型へ変換を試みる
for column in df.columns:
    try:
        df[column] = df[column].astype(int)
    except ValueError as e:
        print(f"Error in column {column}: {e}")

# データ型を確認
print(df.info())

```

### データのクリーニング
データにスペースや特殊文字が含まれている場合は、これらを取り除くためにクリーニングする。

```Python
df = df.apply(lambda x: x.str.strip())  # 余分なスペースを除去
df = df.replace('', pd.NA)  # 空文字をNAに置換
df = df.dropna()  # NAを含む行を削除

# その後、型変換を再試行
df = df.astype(int)
print(df.info())

```

### Debugging: データの確認

```Python
print(df.applymap(lambda x: x.isdigit()))  # 数字で構成されているか確認
```
LXDでのDNS設定

LinuxサーバのテストをするときにLXDをよく使っていますが、LXDのゲストをDNSで参照できた方が都合が良い場合があるのでその設定方法です。
参照した記事はこちらだったのですが、Ubuntu24.04ではちょっと違っていたので覚書です。
参照元
https://qiita.com/apatchk/items/65cd8b356f25233baa90

Ubuntu24.04ではsystemd-resolveが使用できないのでresolvctlを使います。
```
#!/bin/bash

set -eu

CONTAINER_NAME="$(lxc list -c n -f compact status=RUNNING | tail -1 | tr -d ' ')"
LXDBRIP="$(ip addr show dev lxdbr0| grep -Po 'inet \K[\d.]+')"
sudo resolvectl dns lxdbr0
sudo resolvectl domain lxdbr0 lxd
echo "auth-zone=lxd\nauth-server=${LXDBRIP}" | lxc network set lxdbr0 raw.dnsmasq -
lxc network show lxdbr0
echo "All done.. try command"
echo "dig ${CONTAINER_NAME}.lxd @${LXDBRIP}"
```
上記のシェルではDomain名がlxd、lxdが使っているブリッジがlxdbr0と言う
デフォルト値を前提としているので異なる場合変更の必要があります。
また、何か一つはコンテナが動いている(RUNNING)という前提です。

参考までに設定後の状態です。
```
$ lxc network show lxdbr0
name: lxdbr0
description: ""
type: bridge
managed: true
status: Created
config:
  ipv4.address: 10.81.243.1/24
  ipv4.nat: "true"
  ipv6.address: fd42:19f6:6c43:4ee5::1/64
  ipv6.nat: "true"
  raw.dnsmasq: |
    auth-zone=lxd
    auth-server=10.81.243.1
used_by:
- /1.0/instances/host1
- /1.0/instances/host3
- /1.0/profiles/default
locations:
- none
 ```
 LXDのゲストにアクセスする場合lxc execコマンドでアクセスできますのでDNS参照してネットワーク経由でアクセスする必要はないんですが、必要になった時の覚書です。
rails 簡易的な閲覧数カウント機能

今回は業務の中で簡易的なページ閲覧数をカウントする機能を作る必要があり、その時に実装した内容を記録として残します。

## 実装例
今回は簡易的なcolumnテーブルがあると仮定して実装を進めていきます。
```
|   id | title     | content   | created_at          | updated_at          |
|-----:|:----------|:----------|:--------------------|:--------------------|
|    1 | Article 1 | Content 1 | 2024-01-01 00:00:00 | 2024-01-10 00:00:00 |
|    2 | Article 2 | Content 2 | 2024-02-15 00:00:00 | 2024-02-20 00:00:00 |
|    3 | Article 3 | Content 3 | 2024-03-10 00:00:00 | 2024-03-15 00:00:00 |
|    4 | Article 4 | Content 4 | 2024-04-20 00:00:00 | 2024-04-25 00:00:00 |
```

ここへカウントをするカラムを追加します。
```
#追加コマンド
rails g migration AddViewCountToColumns view_count:integer

=> rails db:migrate
```

```
|   id | title     | content   | created_at          | updated_at          |   view_count |
|-----:|:----------|:----------|:--------------------|:--------------------|-------------:|
|    1 | Article 1 | Content 1 | 2024-01-01 00:00:00 | 2024-01-10 00:00:00 |            0 |
|    2 | Article 2 | Content 2 | 2024-02-15 00:00:00 | 2024-02-20 00:00:00 |            0 |
|    3 | Article 3 | Content 3 | 2024-03-10 00:00:00 | 2024-03-15 00:00:00 |            0 |
|    4 | Article 4 | Content 4 | 2024-04-20 00:00:00 | 2024-04-25 00:00:00 |            0 |

```

最後に閲覧をカウントする処理をカウントしたいページに関連するアクションへ設定をします。
```
  def show
    @column = Column.find(params[:id])
    
    # 閲覧数を増やす
+   @column.increment!(:view_count)
  end
```

※increment! メソッドは、RailsのActiveRecordが提供するメソッドの一つで、指定されたカラムの値をインクリメント（増加）させ、その変更をデータベースに即座に保存するためのものです。

これで簡単に閲覧数をカウントする機能をつけることができました。

「人気記事」などを表示する際には、モデル.rbにスコープなどを定義しておくとスムーズに閲覧数が多い記事を取得できるようになると思います！

```
scope :popular, -> { order(view_count: :desc) }
```

ただ注意点として、今回の実装ではリロードしても閲覧数が増えていってしまうため、カウントを厳密に行いたい場合には非推奨の方法になります！
エンジニアもどきが学習したいことのロードマップ

# はじめに

https://qiita.com/ramgap/items/d87f3a9e1fb321442811

上の記事で学習したいことをまとめていましたが、下のサイトをもとに少し加筆訂正し、図で表すことにしました。

https://roadmap.sh/frontend?r=frontend-beginner

https://roadmap.sh/backend?r=backend-beginner

また、図を作成する際には、下のサイトを参考にさせていただき、ChatGPTでmermaidコードを作成し、draw.ioで加筆訂正をしました。ChatGPT、すごいですね…。

https://note.com/duf20/n/ne4ce3fd09170

# ロードマップ
![ロードマップ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3845328/468ea33b-7003-7c25-869c-6f30701587f6.jpeg)
LINEの広告を無料で消す方法(ROOT化不要)

私はXperiaスマホを使用しているのですが、Xperiaスマホはどうやらroot化してMagiskを入れてLIMEを使えるようにするのが難しそう(qUnlockが必要)ということで、なんとかならないかと考えていたら、Blokadaという良さげなアプリを見つけました。

Blokadaをinstallし、filterに次のdomainを加えてください。そうすると2024年8月現在ほとんどのline広告がblockできます。

'a.line.me^,sch.line.me^,crs-event.line.me^,lap-click.tr.line.me^,ga2.line.naver.jp^,ga2x.line.naver.jp^,gs2.line.naver.jp^,gs2x.line.naver.jp^,gw.line.naver.jp^,ns1.line.naver.jp^,ns2.line.naver.jp^,adns1.line.naver.com^,adns2.line.naver.com^,nelo2-col.linecorp.com^,d.line-scdn.net^,obs.line-scdn.net^,appresource.line-scdn.net^,vos.line-scdn.net^,static.line-scdn.net^,ci.line-apps.com^,cix.line-apps.com^,scdn.line-apps.com^,ch-news.line-apps.com^,torimochi.line-apps.com^,aax-us.amazom-adsystem.com^,aax-us-pdx.amazom-adsystem.com^,jp-col-tcp.nelo.linecorp.com,ly.my.sentry.io,legy-jp.line-apps.com,legy-backup.line-apps.com'

また、もし広告がlineに表示されたら、blokadaのホストログからそのdomainを調べてブロックリストに追加すればブロックできます。

非常に快適にlineを使えるようになりました。line広告の趣味の悪さは異常ですからね。