OmniAICreator/Qiita-1.07M huggingface dataset:
自作API? OS? 検索エンジン!? 『超天才的な個人開発23選！』

## はじめに
「作ってみた系」って自分のモチベに繋がりますよね！
そんなモチベ爆上げの記事10選です！


### 1. 高校生が文化祭用に作成した受付用アプリ
個人的にはこれが一番すごい．

https://qiita.com/NaYuA/items/1cda0211ec44fb25d422

[類似記事]
[高校生が文化祭に3日でWeb受付システムを爆速単独開発することになった話](https://qiita.com/CinnamonSea2073/items/a233d614ee31b493b8e1)


### 2. 自作言語
言語を作るのは猛者すぎる...

https://qiita.com/sxclij/items/134e369e493dc5b9eb83


### 3. ビジネス書籍を紹介するアプリ
マネタイズできているのがすごい！

https://qiita.com/Unemployed_jp/items/32b8612fd47ca4ec76b3



### 4. AR年賀状
ビジュアル，めちゃくちゃ綺麗．

https://qiita.com/Namy/items/5354fd38cf42c5ad3037


### 5. ブラウザで操作するラジコン
おもしろい．ハードとソフトの両方を作った所がいい．

https://qiita.com/minijumbo/items/a9108db7b9d96e5445a6

### 6. Kubeernetesを作った．
天才すぎる．てか，作れるん...

https://qiita.com/go_vargo/items/d1271ab60f2bba375dcc

### 7. ハムスターの動きの検知とLINE通知
かわいい．YOLOの勉強に見ました．

https://qiita.com/go_vargo/items/d1271ab60f2bba375dcc

### 8. ブラウザを作ってみた
ブラウザを自作できるだなんて初めて知りました．

https://qiita.com/DanYuya/items/9c6e32410917c160ea8c

### 9. 自作検索エンジン
検索エンジンってつくれるの？すごい！

https://qiita.com/Taku_nakahara/items/b21f286c8e430eedf017

### 10. 最適化問題を食堂に応用
発想がおもしろい．しかもそれを実現するのもすごい．

https://qiita.com/iroha_nano145/items/ec689338e1d7f6503a40

### 11. 大学生が作った時間割アプリが公式化された話

https://qiita.com/koheisato/items/7f2e604233372af35b41

### 12. 新しい形のキーボード
100回棒を降ったらGitPushするらしい．おもろ笑

https://qiita.com/maki_maki_art/items/1ca10d725d4e01a9b3b8

### 13. アイデア出しを加速するアプリ
上記の記事と同じ著者です．経歴この記事内に書かれている経歴もすごい！

https://qiita.com/maki_maki_art/items/08204a95896f889e4c1d

### 14. 排便管理アプリ with LINEBOT
過去の記録を元に，胃腸と食事の相性を判断する．
しっかりしたシステム構成で記事も詳しく勉強になる．

https://qiita.com/tkhero555/items/317f5a3fa1e584a53190

### 15. 自作OS
自作OSはさすがに意味分からんすぎる．

https://qiita.com/yamoridon/items/4905765cc6e4f320c9b5

### 16. 天気予報の自動受信
APIの使い方，GitHubActionの使い方について紹介している．

https://qiita.com/178_c_m/items/bb9f5f05415249cfabf1

### 17. 絵を絶賛してくれるアプリ
バックエンドの処理が面白い！

https://qiita.com/alclimb/items/2a91220818c87c2f91d1

### 18. 自作API
学生の内に，自作APIに挑戦したい．

https://qiita.com/Sicut_study/items/babc9c5aa13d983312a8

[関連記事]
[LINE Pay APIを使ってアプリに決済を組み込む方法](https://qiita.com/nkjm/items/b4f70b4daaf343a2bedc)



### 19. 研究室のコーヒーメーカーの改造
顔認識で，誰がコーヒーを飲んだかを検知し，集金を全自動化
すごい．この発想もすごい．そして面白い．

https://qiita.com/ssmsaito/items/27683ebb40b57b4be8aa

### 20. 岸田総理のツイートをネガポジ判断
勉強になりました．そして面白いです．

https://qiita.com/iwakiri0104/items/07fd4bded5a41e2b8ea2

### 21. 株予想アルゴリズム

https://qiita.com/peisuke/items/f836aa245eb54b703cee


### 22. 画像認識で綾鷹を選ばせる
画像処理系でトップクラスに面白い記事．発想神．

https://qiita.com/tomo_20180402/items/e8c55bdca648f4877188


### 23. 電車の自動運転システム
高校生がこのクオリティのシステムと記事も書いたというのがすごい．作成したものも大がかりで読み応えがある．

https://qiita.com/Neko_1013/items/eb503749148a11d0da6c


## まとめ
これらの記事でモチベ上げていきましょう！
KinoNiconico を使って Livebook 上でニコニコ動画を視聴する

## はじめに

前回、 KinoYoutube を紹介しました

https://qiita.com/RyoWakabayashi/private/b0c4d2afbd16106341f5

というわけで、 KinoYoutube を参考に KinoNiconico を作りました

https://github.com/RyoWakabayashi/kino_niconico

ニコニコ動画の埋め込みについては AstroNicoEmbed を参考にさせていただきました

https://github.com/Robot-Inventor/astro-nico-embed/

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/kino/kino_niconico.livemd

## セットアップ

セットアップセルで KinoNiconico をインストールします

```elixir
Mix.install([
  {:kino_niconico, "~> 0.1"}
])
```

## 動画視聴

`KinoNiconico.new` に動画 ID を指定すると、動画が表示されます

```elixir
KinoNiconico.new("sm43793031")
```

![kino_niconico.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/a5cc8dbb-3d13-bc5b-a4d8-d011af896b8d.gif)

:::note warn
localhost で Livebook を起動している場合、動画再生時にエラーが発生します

localhost で確認したい場合、 [ngrok](https://ngrok.com/) 等を使って https で Livebook にアクセスしましょう
:::

ちなみに、再生した動画はゆこぴさんの「ナン食べたい」です

https://www.nicovideo.jp/watch/sm43793031

## まとめ

いざとなれば自分で Kino を作るのも比較的簡単にできてしまうのが Livebook の良いとことですね
Rails8の主な特徴4選

Rails 8は、開発者の生産性向上とデプロイメントの簡素化を目指し、以下の主要な特徴を備えています。

1. **Kamal 2とThrusterによるデプロイメントの簡素化** Rails 8には、Kamal 2という新しいデプロイメントツールが組み込まれており、クラウドVMや自社サーバーへのデプロイが容易になりました。Kamal 2は、Linuxサーバーを単一のコマンドでアプリケーションサーバーに変換し、数分で本番環境への移行を可能にします。さらに、Thrusterという新しいプロキシが導入され、Pumaウェブサーバーの前に配置されることで、X-Sendfileアクセラレーション、アセットキャッシング、アセット圧縮が可能となり、Nginxなどの外部ウェブサーバーが不要になります。

‌

1. **Solidアダプターによる外部サービス依存の削減** Rails 8では、Solid Cable、Solid Cache、Solid Queueという3つの新しいSQLiteベースのアダプターが導入され、RedisやMemcachedなどの外部サービスへの依存が減少しました。これにより、WebSocket通信、キャッシュ、ジョブキューの機能をSQLite上で実現でき、開発環境のセットアップが大幅に簡素化されました。

‌

1. **Propshaftによるアセットパイプラインの簡素化** 従来のSprocketsに代わり、Propshaftがデフォルトのアセットパイプラインとして採用されました。Propshaftは、アセットのロードパスとダイジェスト付きのスタンプを簡単に管理し、よりシンプルな構成でアセット管理が可能となります。

‌

1. **認証システムの自動生成** Rails 8では、`bin/rails generate authentication`コマンドを使用することで、セッションベースの認証システムを自動的に作成できます。これにより、開発者は最小限の作業で堅牢な認証機能を導入できます。

これらの新機能により、Rails 8は開発者にとってより使いやすく、効率的なフレームワークとなっています。
【C#】Blazorから外部APIを使用して天気情報を表示

## 初めに

BlazorServerからOpenWeatherのAPIを読んで天気の情報を取得するアプリを作成しました。
もしよければ最後まで読んでいってください。

↓完成イメージ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783169/09acb5fd-32de-2bcf-3542-85ef83ea3571.png" width="60%">

↓ソース(実際に動かす場合にはAPIキーの取得が必要です)

https://github.com/KM5075/BlazorServerWetherApp

↓使用したAPI

https://openweathermap.org/

## ポイント

本アプリのポイントを何点かご紹介します。ソースコードのすべてを説明するわけではないので、もし興味を持っていただけたら実際のコードを確認してただければ幸いです。

### HTTP用のクライアントを依存性の注入で作成

https://learn.microsoft.com/ja-jp/aspnet/core/fundamentals/http-requests?view=aspnetcore-8.0

APIと通信するためのHTTPクライアントを依存性の注入を用いてソースがら実行できるようにしました。Microsoftのチュートリアルあるあるだと思うのですがいろいろなパターンがのっているせいでどのパターンを使用すればいいかわからず、何気に時間がかかりました。

↓Program.cs
``` CSharp
builder.Services.AddHttpClient();
```

↓WeatherPage.razor
``` CSharp
@inject IHttpClientFactory HttpClientFactory
```

実際に通信する際には上記のファクトリーからクライアントを作成して通信を実施します。

## APIキーをシークレットファイルに格納

APIを使用する際に必要なキーについて第３者に知られてしまうと悪用される可能性があるためソース上にハードコーディングやGitにコミットすることは厳禁です。

そのためシークレットファイルを用意してそちらに記載するのですがAsp.net Coreでは簡単に用意して通常の`appsetting.json`と同じ要領でアクセスすることができます。

設定方法については以下を参考にしました。

https://qiita.com/higege-amdeker/items/f403cb10b4c8337a7980

## ドロップダウンリストを変更するたびに更新

APIキーに設定する都市について`InputSelect`タグを用いて変更するとテーブルの値も変更されるようにしました。

このBlazorで提供される`Input~`系のタグについて`EditForm`タグの内部でのみ使用できるようです。私は下記記事にたどり着けなかったらアプリ作成をあきらめてたかもしれないです。

https://www.gunshi.info/entry/2021/11/19/020708

## 課題(気が向けば修正したい)

データが取得できなかった場合の例外処理や、ネットワーク遮断時のリトライ処理

## 最後に

Blazorから外部のAPIを使用してデータを取得するアプリを作成してみました。
APIを使用するソースを触るときは何かの間違いでAPIキーがほかの人に見られる状態になっていないかドキドキします💦

## 参考

https://openweathermap.org/

https://learn.microsoft.com/ja-jp/aspnet/core/fundamentals/http-requests?view=aspnetcore-8.0

https://qiita.com/higege-amdeker/items/f403cb10b4c8337a7980

https://www.gunshi.info/entry/2021/11/19/020708
そんなことは知っている。今更C#でクラスライブラリを作って使う！

## 目次
- [対象者](#対象者)
- [セットアップ](#前提セットアップ)
- [実装](#実装してみる)
- [成果物](#成果物)
- [終わりに](#終わりに)

# 対象者
[C#](https://learn.microsoft.com/ja-jp/dotnet/csharp/tour-of-csharp/strategy)もとい、[.NET](https://learn.microsoft.com/ja-jp/dotnet/core/introduction)初学者を対象とします。かくいう私も初学者です。対戦よろしくお願いします。

# 前提セットアップ
この記事では、VisualStudioは使用しません。その代わりに以下の環境を使用します。
- VSCode
- .NET 8.0.11 with SDK
<details><summary>セットアップ</summary>

1. [.NET 8.0.11](https://dotnet.microsoft.com/ja-jp/download/dotnet/8.0)をダウンロードし、インストール（あなたはおそらく開発者なので、SDKを選択してください）したのちに必要であれば再起動
2. [VSCodeのインストール](https://code.visualstudio.com/download)
3. VSCodeの拡張機能の[.NET Install tool](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.vscode-dotnet-runtime)、[C#](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp)をインストール（付属の拡張機能が複数インストールされます）
4. 実装へ
</details>

# 実装してみる
それでは、早速実装しようか。

### まずは、以下のコマンドをプロジェクトフォルダで行う
```powershell
E:\Project> dotnet new console -o Example
E:\Project> dotnet new classlib -o ClassLib
```

### 次に、ExampleプロジェクトにClassLibプロジェクトの参照を追加する
```powershell
E:\Project> cd Example
E:\Project\Example> dotnet add referense ..\ClassLib
```
`vscode`を開き、Project.slnが生成されるのを待つ（珈琲をどうぞ:tea:）。
```powershell
E:\Project> code .
```

### ClassLib\Class1.csを編集していく
```csharp
namespace ClassLib;

public static class Class1
{
    public const int GREET_COUNT = 10;

    public static void Log(string message)
    {
        Console.WriteLine(message);
    }
}
```

### Example\Program.csを編集していく
:::note warn
最上位ステートメントは使用しないように
:::
```csharp
// ライブラリ名前空間の使用
using ClassLib;

// Exampleプロジェクトの名前空間の使用を宣言
namespace Example;

// ファイル名のクラスを作成
public class Program
{
    // ソースコードのエントリーポイントを定義
    public static void Main(string[] args)
    {
        // ライブラリのGREET_COUNTを小突いてみる
        Class1.Log(Class1.GREET_COUNT.ToString());

        // 無駄に挨拶させてみよう
        for (int i = 0; i < Class1.GREET_COUNT; i++)
        {
            Class1.Log($"{i} Hello, World!");
        }
    }
}
```

### 成果物
```powershell
E:\Project> dotnet run --project Example
10
0 Hello, World!
1 Hello, World!
2 Hello, World!
3 Hello, World!
4 Hello, World!
5 Hello, World!
6 Hello, World!
7 Hello, World!
8 Hello, World!
9 Hello, World!
```

# 終わりに
うん、誰でも知っているというかそこらへんに転がってるよね。

# 追記
クラスライブラリプロジェクトに[NuGet packages](https://www.nuget.org/PACKAGES)を追加したい場合は以下を実行するべ。
```powershell
E:\Project\ClassLib> dotnet add package {Replace.Package.Name.Here}
```
:::note alert
脆弱性に注意してください。.NETのビルド時に警告が出ますが、放置しないでください。
:::
【SQL】DBMSごとの列別名を使える句、使えない句

## はじめに
SQLのSELECT句の選択リスト項目には、別名(エイリアス)を指定可能です。SELECT句に複雑な式を書いて、同じ式の結果順にソートしたい場合、ORDER BY句を別名で指定できるなど便利な存在です。そんな列別名、ORDER BY句では使える認識でいましたが、GROUP BY句では使えたような、使えなかったような曖昧な理解でした。そこで改めて調べてみたところ、DBMSによって違いがあることを知ったため、まとめておくことにしました。

## 環境
今回調べたのは以下のDBMSで、それぞれ2024年11月現在の最新バージョンとなります。他のバージョンについては念のため別途確認をお願いします。
- MySQL 9.1
- Oracle 23ai
- PostgreSQL 17.1
- SQLite 3.47.0
- SQL Server 2022

## DBMSごとの比較表
DBMSごとに各句で列別名を使えるかどうかの結論は下記の通りとなります。
| DBMS | WHERE句 | GROUP BY句 | HAVING句 | ORDER BY句 |
| :--- | :---: | :---: | :---: | :---: |
| MySQL | ✕ | ◯ | ◯ | ◯ |
| Oracle | ✕ | ✕ | ✕ | ◯ |
| PostgreSQL | ✕ | ◯ | ✕ | ◯ |
| SQLite [^1] | ◯ | ◯ | ◯ | ◯ |
| SQL Server | ✕ | ✕ | ✕ | ◯ |

### MySQL
> The alias is used as the expression's column name and can be used in GROUP BY, ORDER BY, or HAVING clauses.

https://dev.mysql.com/doc/refman/9.1/en/select.html

### Oracle
> The alias can be used in the ORDER BY clause, but not other clauses in the query.

https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/Creating-Simple-Queries.html

### PostgreSQL
> An output column's name can be used to refer to the column's value in ORDER BY and GROUP BY clauses, but not in the WHERE or HAVING clauses; there you must write out the expression instead.

https://www.postgresql.org/docs/current/sql-select.html#SQL-SELECT-LIST

### SQLLite
> 2\. If the ORDER BY expression is an identifier that corresponds to the alias of one of the output columns, then the expression is considered an alias for that column.

https://www.sqlite.org/lang_select.html#the_order_by_clause

### SQL Server
> column_alias can be used in an ORDER BY clause. However, it cannot be used in a WHERE, GROUP BY, or HAVING clause. If the query expression is part of a DECLARE CURSOR statement, column_alias cannot be used in the FOR UPDATE clause.

https://learn.microsoft.com/en-us/sql/t-sql/queries/select-clause-transact-sql?view=sql-server-ver16

## 補足
今回の調査にあたり、[SQL Fiddle](https://sqlfiddle.com)で動作確認を行いましたが、Oracleに関しては公式ドキュメントの記載と異なる挙動を示しました。具体的には、GROUP BY句、HAVING句でも列別名が使えました。公式ドキュメントの記載が間違っているのかと思いましたが、[Oracle Live SQL](https://livesql.oracle.com)で確認したところ、公式ドキュメント通りの挙動となりました。

## おわりに
今回調べた範囲において、ORDER BY句では、すべてのDBMSで列別名が使用可能でした。WHERE句では、すべてのDBMSで使用不可でした。GROUP BY句とHAVING句では、DBMSによる違いがありました。DBMSの移行の可能性があるシステム開発でSQLを書く場合、ORDER BY句以外では列別名を使わないという判断をした方がよさそうです。

[^1]: 公式ドキュメントからはORDER BY以外の句に関する言及を見つけられませんでした。自分で作成した実行環境において確認した結果を記載しています。
Ruby ならびに Rails でのコメントのスタイルについて調査

* [こちらの記事](https://techracho.bpsinc.jp/hachi8833/2017_02_20/35769)をきっかけに Ruby のコメントの書き方の方針について学びをまとめました
* 原文ソースはこちら → https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md#%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88


# 根底にあるスタンス
>良く書けたコードは、それ自身が最良のドキュメントでもある。 コメントを書こうとしている時は、常に自問してほしい、 "このコメントが不要になるようにコードを改善できるだろうか？" コードを改善した上で、ドキュメントでさらに明快にするのだ。
> -- Steve McConnell

* この点は『ソースコード == ドキュメント』という[ Ruby 作者の主張並びに Ruby の言語特徴を汲んでいる](https://i.loveruby.net/ja/ruby/codingstyle.html#:~:text=%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84%E3%80%82-,%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88,-%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AF%20%23%20%E3%82%92)
* コードが明快な分かりやすい記述であれば「コードを見れば分かる」という事
* 記事の作者は補足的に「実装の背景や理由などコードでは説明がつかない部分はコメントで補足説明が必要としている

## コメントを書くなら読みやすく無駄を省き最適化する
> 悪いコードを説明するコメントは避けましょう。
> 自己説明的なコードへのリファクタリングを行いましょう

* 「読みやすい言語でコメントを残す（日本なら日本語）」「コメント記号(#)とコメント本文はスペース一個分空ける」などコメントを書くにしろ見やすい工夫は必須だと訴えている

## 注釈
* "コメント" とは別に "注釈 (アノテーション)" も手法としてある
  * 以下引用の注釈を利用した例

```ruby:
def bar
  # FIXME: 以前から挙動がおかしい
  baz(:quux)
end
```

## マジックコメント
* `マジックコメント` ... スクリプトエンコーディングを明示的に指定する際に使用。エディタでのエンコーディングを独自に指定したり、外部のスクリプトで使う設定を書く際にも使用
  * シェルスクリプトの一行目に書くおまじないと同じ
* 以下一例、Ruby 1.9 では、この記述がない場合のデフォルトエンコーディングは US-ASCII であるので、非ASCIIコードがあるのにこの記述がなかった場合はエラーになる
```ruby:
# -*- coding: UTF-8 -*-

p "abc".encoding
# => #<Encoding:UTF-8>

p "あいうえお".encoding
# => #<Encoding:UTF-8>
```

* マジックコメントは**処理に関係する意味を持つ重要なコメント**なので「一行に複数のマジックコメントを書かないようにする」「マジックコメント直下は一行分の空白行を空ける」

---
### 所感
* 個人的にはコメントは書けるなら書いた方が良いと考えていましたが、"コードが良ければ"コメントは不要という考え方もあるのかなと思った
    * これは Ruby という言語に限った話かもしれませんが
* ただこの辺は会社によるという結論なのかなと思ったり
    * RDoc を利用すれば Ruby のスタンスには反するような気もするので
* とある知り合いが「メソッド名も直観的なものが多いイメージ」と仰っていて、そういう意味で『コード = ドキュメント』と主張しているのかもしれないなと思った

---
### 参考資料・参考サイト

https://techracho.bpsinc.jp/hachi8833/2017_02_20/35769

https://github.com/fortissimo1997/ruby-style-guide/blob/japanese/README.ja.md#%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88

https://i.loveruby.net/ja/ruby/codingstyle.html#:~:text=%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84%E3%80%82-,%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88,-%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AF%20%23%20%E3%82%92

https://hydrocul.github.io/wiki/programming_languages_diff/etc/magic-comment.html
オンライン英会話だけじゃない、ChatGPTで始める新・英会話

海外出張、英語会議…得意でもない英会話が急に必要になったとき、どうしますか？
オンライン英会話に手を出す前に、AIを活用した新しい方法「ChatGPTの高度な音声モード」を試してみませんか？
 
高いレッスン料を払う必要も、時間を気にする必要もなく、ChatGPTなら人間さながらの自然な英会話が楽しめます
 
## はじめに
この記事では、ChatGPTの「高度な音声モード」でできること、できないこと、そして筆者自身がどのように活用しているかを具体的にお伝えします。英会話の練習に悩んでいる方には新しい選択肢になるはずです
 
## こんな悩みを抱えていませんか？
以下に心当たりがある方に、この方法は特におすすめです！
* ネイティブスピーカーとの会話に自信がない、話す速度に圧倒されて頭が真っ白になる
* オンライン英会話は高すぎて申し込みたくない
* 英会話カフェなどに行っても、結局日本人同士でジャパニーズアクセントの練習しかできない
 
## 利用方法 
ChatGPTの音声会話機能は、特別な準備をしなくてもすぐに始められます
以下のステップでスタートしてみましょう！

:::note info
「高度な音声モード」は、2024年10月2日に有料ユーザ（Plus/Business プランのみ）リリースされた機能です
2024年11月現在も利用できるのは、ChatGPT Plus/Business プランのみ
:::

Mobileアプリの入力欄の右下の「高度な音声モード」ボタンから会話を開始できます
![IMG_4085.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3191704/20d186b3-5829-9632-2beb-d25361f54981.png)


現在、9種類の音声が用意されており、陽気なタイプや知的な雰囲気の声など、気分に合わせて選べます
 
## ChatGPT英会話の活用アイデア
### 1. 日々の出来事を話す
今日の出来事や食べたもの、考えたことを話してみましょう
AIが質問を返してくれるので、自然な会話が練習できます

例:
*  Udemyで学んだことをサマりながら話す
アウトプットにもなって、一石二鳥

### 2.  旅行や仕事のシミュレーション
特定のシチュエーションを想定して会話の練習をするのもおすすめです

例:
 *  空港でのチェックインをシミュレート
 *  飲食店でのやりとりをシミュレート
 
# 制限事項
* 公式には非公開ですが、通常のチャットモードよりも早く利用上限に達します
筆者の場合、連続会話は1時間程度が目安です
* アクセントの選択肢
現時点で対応しているのは北米アクセントのみ。他の英語アクセント（インド、ヒスパニック、中国など）は対応していません
* 発音矯正機能はなし
ChatGPTはテキストベースの理解を基本とするため、発音矯正の指導はできません
発音を重点的に練習したい場合は、別のツールを併用するのがよいでしょう
 
# おわりに
ChatGPTの高度な音声モードは、英語学習の新しい選択肢を提供してくれます
まずはChatGPT Plusに登録して、音声モードを試してみてください。
大西配列への挑戦

# 大西配列への挑戦

## 使用キーボード

- Claw44

---
![Onishi_Keymap_v1.1.8_page-0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/968327/864be4c5-9302-966b-e983-eb82c0764b8f.jpeg)
超高機能な翻訳サービス「Kagi Translate」使ってみた！

# はじめに

これまでは翻訳にDeepLを使っていました。しかし、たまに翻訳できない言語があったり、一度に変換できる文字数の制限があったり、翻訳した英語が気にくわなくて手動で直していました。

そんなある日、GIGAZINEさんのポストで高精度と謳うKagi Translateなるサービスを見かけたので使ってみました。結果として結構良いと思ったので紹介です。

https://x.com/gigazine/status/1854720580869632164


# Kagi Translateとは？

Kagi Inc.の出している翻訳サービスです。
Kagi Translateを使おうと思ったときに、Kagi Searchなる検索エンジン?のサイトをみて無料プランだと利用制限があるのかーと勘違いしてしまったのですが、今のところKagi Translateは<font color="red">ログイン等不要で無料</font>で使用できます！

[公式ブログ](https://blog.kagi.com/kagi-translate)曰く、類似サービスと比べた特徴は以下のようです。正直、翻訳の品質は私には判断できませんが、品質が今使っているDeepLよりも高く対応言語も多いなら良いかなと思って使ってみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934352/b88feda3-256a-22c7-4962-ca9d68c4cf8e.png)

# 感想

実際に使ってみると、Cloudflareの検証ステップを間に挟むくらいでそれ以外はスムーズに使えました。

https://translate.kagi.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934352/9e1a4013-1460-a6de-f102-8abad7caf5c2.png)

:::note info
### 良かったところ👍

個人的に良いと思ったのは以下です。
- 一度に翻訳できる文字数が多い(Kagi Translateは20,000文字、DeepLの無料版は1,500文字)
- URLを使ってWeページ全体を翻訳する機能がある(これは他で見たことがない)
:::

「URLを使ってWeページ全体を翻訳する機能」ってパッと聞いて分からないですよね。
なんとKagi Translatorは翻訳したいWebページのURLの前に「`https://translate.kagi.com/(元の言語)/(翻訳したい言語)/`」をつけることでも翻訳ができちゃうんです。

しかも[公式ブログ](https://blog.kagi.com/kagi-translate)では書かれていませんでしたが翻訳の元になる言語の部分は省略すれば自動識別で動いてくれます。つまり、最低限「`https://translate.kagi.com/Japanese/(翻訳したいWebページのURL)`」で日本語に翻訳してくれます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934352/90a9697e-9628-d318-b692-58270cdba60e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934352/7adf2bf8-c1bc-1224-d027-29945440e83d.png)


:::note warn
### 気になったところ👎

少し気になったポイントとしては以下です。
- DeepLではできるファイルの翻訳機能がない(あまり使ったことはないが)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934352/b3641786-c20f-6727-2974-e7da112319ef.png)
- Webページ全体の翻訳のパフォーマンスに問題がありそう(同一ページを複数回繰り返して翻訳したり、放置していたらメモリを大量に使用してそう)
:::

ファイルの翻訳機能はユーザーによっては結構必須機能かもしれませんし、パフォーマンスに関してもまだまだ改善の余地はありそうです。
私は使おうとしたらサインアップできなかったのですがフィードバックページも用意されているので、今後もどんどん改善されていきそうです。

# まとめ

これはいいぞ...!
今後有料になる可能性も十分ありますが、ひとまずはKagi Translateに乗り換えます🙋‍♂️
NGINX（初期状態）のログフォーマット及び項目一覧表

NGINXの初期状態のログフォーマットは、通常以下のような`log_format`ディレクティブで定義されています。

```shell
log_format combined '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
```

このフォーマットに基づいて、各項目の意味を表形式で説明します。

| 項目 | 説明|
|---|---|
| $remote_addr | クライアントのIPアドレスを表示します。|
| $remote_user | クライアントがHTTP認証を使ってアクセスした際のユーザー名を表示します。|
| $time_local サーバーのローカル時刻でリクエストを受信した日時を表示します。|
| $request | リクエストのメソッド、URI、およびHTTPバージョンを含みます（例：GET /| index.html HTTP/1.1）。|
| $status リクエストの処理結果のHTTPステータスコードを表示します（例：200、404など）。|
| $body\_bytes\_sent | ヘッダを除いたレスポンスボディのサイズ（バイト数）を表示します。|
| $http_referer リクエストのリファラーヘッダの内容を表示します。|
| $http\_user\_agent | | クライアントのユーザーエージェント（ブラウザやデバイスの情報）を表示します。|
| $http\_x\_forwarded_for クライアントがプロキシ経由でアクセスした際の元のIPアドレスを表示します（通常はプロキシサーバーが設定）。|

この形式は一般的に「combined（組み合わせ）」フォーマットと呼ばれ、Apache HTTP Serverでも類似の形式が使用されています。
AWS IoT実践講座という書籍を執筆しました

# おしらせ
これまでこちらのブログで執筆した記事を含めて、ESP32のデバイスからどのようにAWS IoTに接続すればよいのか、センサーからのデータをどのように可視化することができるかなどをまとめて、「AWS IoT実践講座」という書籍を執筆いたしました。技術評論社から2024年11月29日に゙発売されます。デバイス側の開発環境の構築から、データの可視化、デバイスの制御をどのように行えばよいのか、さらにどのようにデータを活用して機械学習を行えばよいのかということをステップバイステップに解説している内容となっています。IoTによるデータ収取・分析・活用を手がける担当者におすすめですが、多くの方に手にとっていただければうれしいです。

![AWSIoT_cover_H1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80028/ceb6395b-9065-6be3-a915-81409479f75f.jpeg)

# 本の概要
以下のような内容となっております。

- 1章　AWS IoTでビジネス課題を解決しよう
- 2章　デバイスとクラウドの接続
- 3章　クラウドからのデバイスの制御
- 4章　デバイスから取得したデータの可視化
- 5章　機械学習の適用（Amazon SageMaker）

Amazon Link URL:https://amzn.asia/d/7qiXLRF
Symbol Peer をサービス化(デーモン化)する


## サービスファイルの作成

### Symbol Recovery

異常終了などで lock ファイルが残った際に起動します。

```bash
sudo vi /etc/systemd/system/symbol-recovery.service
```

```/etc/systemd/system/symbol-recovery.service
[Unit]
Description=Symbol Recovery

[Service]
Type=oneshot
ExecCondition=/bin/sh -c '/usr/bin/test -f /opt/symbol-node/data/server.lock || /usr/bin/test -f /opt/symbol-node/data/broker.lock'
ExecStart=/usr/local/catapult/bin/catapult.recovery .
KillSignal=SIGINT
Restart=on-failure
RestartSec=2
TimeoutStopSec=60
User=harvestasya
Group=harvestasya
WorkingDirectory=/opt/symbol-node
Environment="LD_LIBRARY_PATH=/usr/local/catapult/deps"
StandardOutput=journal
StandardError=journal
LimitNOFILE=65536
UMask=077

[Install]
WantedBy=multi-user.target
```

### Symbol Server

Symbol ノード本体を起動します。

```bash
sudo vi /etc/systemd/system/symbol.service
```

```/etc/systemd/system/symbol.service
[Unit]
Description=Symbol Node
Wants=symbol-recovery.service
Requires=network.target

[Service]
Type=idle
ExecStart=/usr/local/catapult/bin/catapult.server .
KillSignal=SIGINT
Restart=on-failure
RestartSec=2
TimeoutStopSec=300
User=harvestasya
Group=harvestasya
WorkingDirectory=/opt/symbol-node
Environment="LD_LIBRARY_PATH=/usr/local/catapult/deps"
StandardOutput=journal
StandardError=journal
LimitNOFILE=65536
UMask=077

[Install]
WantedBy=multi-user.target
```

## サービスをリロード

```bash
sudo systemctl daemon-reload
```

## サービスを有効化

```bash
sudo systemctl enable symbol
```

## サービスを開始

```bash
sudo systemctl start symbol
```

## サービスを停止

```bash
sudo systemctl stop symbol
```

## ログの確認

symbol サービスのみを参照します。最新から参照できるよう`-r`オプションを付けます。

```bash
sudo journalctl -u symbol -r
```

リアルタイムで確認したい場合は`-f`オプションを付けます。

```bash
sudo journalctl -u symbol -f
```

さらに色を付けたい場合は、`-o cat`オプションを付けます。

```bash
sudo journalctl -u symbol -f -o cat
```

## 次回

https://qiita.com/ccHarvestasya/items/56653f036e4dd32b1b6b
Symbol を Ubuntu 24 でビルド


## 必要なパッケージをインストール

```bash
sudo apt update
sudo apt upgrade -y
sudo apt -y install git gcc g++ curl libssl-dev libgtest-dev ninja-build pkg-config cmake
```

## Symbol のソースをクローン

現在公開されているバージョンのブランチをクローンします。保存場所はホームディレクトリを想定しています。

```bash
git clone https://github.com/symbol/symbol.git -b client/catapult/v1.0.3.7
```

## 依存パッケージのビルド

Symbol サーバーをビルドするのに必要な依存パッケージをビルドするため、`~/symbol/client/catapult`ディレクトリに入ります。

```bash
cd ~/symbol/client/catapult
```

以下のコマンドで依存パッケージをビルドします。ビルド中にエラーが出たら解消して、再実行してください。再実行時は`--download`オプションは不要です。

```bash
PYTHONPATH="../../jenkins/catapult/" \
  python3 "../../jenkins/catapult/installDepsLocal.py" \
  --target "./deps" \
  --versions "../../jenkins/catapult/versions.properties" \
  --build \
  --download
```

## Symbol サーバーをビルド

ビルド用のディレクトリ`build`を作成して中に入ります。

```bash
mkdir -p build && cd build
```

cmake を実行します。時間がかかるのでテストを無効にしてビルドします。ちなみに、`-DENABLE_TESTS=OFF`を削除すればテストもビルドします。

```bash
BOOST_ROOT="$(realpath ../deps/boost)" cmake .. \
  -DENABLE_TESTS=OFF \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo \
  -DCMAKE_PREFIX_PATH="$(realpath ../deps/facebook);$(realpath ../deps/google);$(realpath ../deps/mongodb);$(realpath ../deps/zeromq);$(realpath ../deps/openssl)" \
  -GNinja
```

以下のメッセージが出ますが、警告なので無視して問題ありません。

```plaintext
CMake Warning (dev) at CMakeLists.txt:36 (find_package):
  Policy CMP0144 is not set: find_package uses upper-case <PACKAGENAME>_ROOT
  variables.  Run "cmake --help-policy CMP0144" for policy details.  Use the
  cmake_policy command to set the policy and suppress this warning.

  Environment variable BOOST_ROOT is set to:

    /home/harvestasya/symbol/client/catapult/deps/boost

  For compatibility, find_package is ignoring the variable, but code in a
  .cmake module might still use it.
This warning is for project developers.  Use -Wno-dev to suppress it.
```

ビルドを開始します。

```bash
ninja publish && ninja
```

## インストール

`~/symbol/client/catapult`に移動して、インストール用のスクリプトを作成します。

```bash
cd ~/symbol/client/catapult
vi symbol_install.sh
```

```symbol_install.sh
#!/bin/bash

set -e

rm -rf /usr/local/catapult
mkdir -p /usr/local/catapult/bin
mkdir -p /usr/local/catapult/lib
mkdir -p /usr/local/catapult/deps

# bin
cp build/bin/catapult* /usr/local/catapult/bin

# lib
cp build/bin/lib* /usr/local/catapult/lib

# library
cp -r deps/boost/lib/*.so* /usr/local/catapult/deps
cp -r deps/facebook/lib/*.so* /usr/local/catapult/deps
cp -r deps/mongodb/lib/*.so* /usr/local/catapult/deps
cp -r deps/openssl/*.so* /usr/local/catapult/deps
cp -r deps/openssl/engines-3 /usr/local/catapult/deps
cp -r deps/openssl/ossl-modules /usr/local/catapult/deps
cp -r deps/zeromq/lib/*.so* /usr/local/catapult/deps
```

実行権限を付与して、シェルを実行します。

```bash
chmod +x symbol_install.sh
sudo ./symbol_install.sh
```

## パスを通す

ライブラリへのパスを通します。

```bash
vi ~/.bashrc
```

以下を末行に追加します。

```~/.bashrc
export LD_LIBRARY_PATH=/usr/local/catapult/deps
export PATH="/usr/local/catapult/bin:$PATH"
```

`.bashrc`を再読み込みします。

```bash
source ~/.bashrc
```

### 実行確認

以下のコマンドを実行してヘルプが表示されれば、ビルドは成功です。

```bash
catapult.tools.address --help
```

## 次回

https://qiita.com/ccHarvestasya/items/e26eb8ea8c67cac1cb5a
NEM スーパーノードプログラムに参加する


ノードを保有していてかつ、10,001 XEM 以上保有していればスーパーノードプログラムに登録することが出来ます。ただ、それなりにマシンパワーを要求されます。

## アカウントのデリゲート有効化

NEM ウォレットで「デリゲートアカウント（委任アカウント）管理」画面を開く。  
※サービス → デリゲートアカウント（委任アカウント）管理

リモートステータスが無効の場合は、「デリゲートアカウントの有効化/無効化」ボタンを押して有効化します。手数料 0.15XEM 必要です。

有効になるまで 6 時間かかりますが、作業は進めることが出来るので作業を進めます。

## 委任秘密鍵の取得

「デリゲートアカウントのキーを表示する」ボタンを押します。

パスワードにウォレットのパスワードを入力し＋ボタンを押すと秘密鍵が表示されます。

## NIS1 クライアントに委任秘密鍵を設定

### NIS1 クライアントの停止

稼働中の場合は停止します。

```bash
sudo systemctl stop nis1
```

### 委任秘密鍵を設定

```bash
vi /opt/nis1/nis/config-user.properties
```

末尾に以下を追加します。

```config-user.properties
nis.bootKey = <委任秘密鍵>
```

### NIS1 クライアントの開始

```bash
sudo systemctl start nis1
```

## Servant

### Servant をダウンロード

NIS1 クライアントのビルド済みバージョンをダウンロードするには、以下のリンクを参照して最新のバージョンを確認します。

[https://bob.nem.ninja/](https://bob.nem.ninja/)

2024/11/11 時点の最新は`v0.0.4`。

```bash
curl -OL https://bob.nem.ninja/servant_0_0_4.zip
```

展開します。

```bash
unzip servant_0_0_4.zip
rm servant_0_0_4.zip
```

nis1 の近くに配置します。

```bash
sudo mv servant /opt
cd /opt/servant
```

### Servant の設定

```bash
vi config.properties
```

`nem.host`にホスト名または IP を設定。
末尾にある`servant.key`に委任秘密鍵を設定します。

```config.properties
nem.host = <put vps ip address here>
...
servant.key = <委任秘密鍵>
```

## ポート開放

```bash
sudo ufw allow 7880
```

## サービス化(デーモン化)

### サービスファイルの作成

```bash
sudo vi /etc/systemd/system/nis1-servant.service
```

```nis1-servant.service
[Unit]
Description=NIS1 Servant
After=network.target

[Service]
ExecStart=java -Xms256M -Xmx256M -XX:+UseG1GC -cp ".:jars/*" org.nem.rewards.servant.NodeRewardsServant
Restart=on-failure
RestartSec=2
User=harvestasya
Group=harvestasya
StandardOutput=journal
StandardError=journal
WorkingDirectory=/opt/servant
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target
```

### サービスをリロード

```bash
sudo systemctl daemon-reload
```

### サービスを開始

```bash
sudo systemctl start nis1-servant
```

### サービスを停止

```bash
sudo systemctl stop nis1-servant
```

### サービスを有効化

```bash
sudo systemctl enable nis1-servant
```

## スーパーノードプログラムへの登録

NEM ウォレットの「NEM スーパノードプログラム」画面を開きます。  
※サービス →NEM スーパノードプログラム

プログラムへの参加タブを押す。

- 参加アドレス: 毎月発表される enrollment address
- ノード主: 自分のノードのホストまたは IP

パスワードを入力後、「プログラムへの参加」ボタンを押す。

enrollment address は、X で「[#NEM #Supernode](https://x.com/search?q=%23NEM%20%23Supernode%20&src=typed_query&f=live)」などで検索すると見つかると思います。月末頃の発表のようです。

## 確認

```bash
http://eolia.nis1.harvestasya.com:7880/nr/metaData
```

以下から自分のノードを探し、ステータスがオールグリーンなら問題ないでしょう。

[NEM スーパーノードプログラム](https://nem.io/supernode/)

## 関連記事

https://qiita.com/ccHarvestasya/items/4e1601e5052e41dc1399

https://qiita.com/ccHarvestasya/items/72d947b41570b1c12ff4

https://qiita.com/ccHarvestasya/items/d2788530b3348a62f08e
NEM(NIS1)ノードをUbuntu24に建てる


## 必要な Java のインストール

```bash
sudo apt install openjdk-11-jre-headless
```

## NIS1 クライアントの準備

### 自分でビルド

ビルドすることに特に意味はないと思います。変態向け。

https://qiita.com/ccHarvestasya/items/4e1601e5052e41dc1399

### ビルド済をダウンロード

NIS1 クライアントのビルド済みバージョンをダウンロードするには、以下のリンクを参照して最新のバージョンを確認します。

[https://github.com/NemProject/nem/releases](https://github.com/NemProject/nem/releases)

https://github.com/NemProject/nem/releases

2025/04/03 時点の最新は`v0.6.102`。

```bash
curl -OL https://github.com/NemProject/nem/releases/download/v0.6.102/nis-0.6.102.tgz
```

展開します。

```bash
tar -xzvf nis-0.6.102.tgz
rm nis-0.6.102.tgz
```

展開された`package`ディレクトリを任意の場所に配置します。

## NIS1 の設定

### 配置想定場所

`/opt`に配置する事を想定しています。

```bash
sudo mv package /opt/nis1
cd /opt/nis1
```

### コンフィグファイルの作成と編集

`config-user.properties`を新規に作成して編集します。

```bash
vi nis/config-user.properties
```

- `nem.folder`: ブロックデータ保存ディレクトリ（デフォルトは `~/nem`）
- `nem.host`: ドメインを取っていない場合は IP アドレス
- `nis.bootName`: ノードの名前（お好きな名前をどうぞ）
- `nis.unlockedLimit`: ハーベストを受け入れる人数の上限値（デフォルトは 4、10 程度がよい）
- `nis.ipDetectionMode`: ホストにドメインを設定している場合に IP アドレスになるのを防止

```nis/config-user.properties
# ブロックデータ保存ディレクトリ
nem.folder = /opt/nis1

# ホスト名
nem.host = xxxx.xxxxxxxx.com

# ブート名(ノードの名前です)
nis.bootName = MyNode

# ハーベストを受け入れる人数の上限値
nis.unlockedLimit = 10

# HOSTがIPにならないようにする
nis.ipDetectionMode = Disabled
```

## NIS1 ノードの起動確認

一旦、確認のため起動します。

### 起動

```bash
sh nix.runNis.sh
```

### ポート開放

```bash
sudo ufw allow 7890
sudo ufw allow 7778
```

### 確認

ノードの状態を確認。

```bash
curl -s http://127.0.0.1:7890/heartbeat | jq
```

ノードの基本情報を確認

```bash
curl -s http://127.0.0.1:7890/node/info | jq
```

ブロック高を確認

```bash
curl -s http://127.0.0.1:7890/chain/height | jq
```

### 停止

```bash
curl -s http://127.0.0.1:7890/shutdown
```

## サービス化(デーモン化)

```bash
sudo vi /etc/systemd/system/nis1.service
```

```nis1.service
[Unit]
Description=NIS1 Client
After=network.target

[Service]
ExecStart=/usr/bin/java -Xms4G -Xmx8G -XX:+UseG1GC -cp ".:./*:../libs/*" org.nem.deploy.CommonStarter
ExecStop=/usr/bin/curl -s http://127.0.0.1:7890/shutdown
Restart=on-failure
RestartSec=2
User=harvestasya
Group=harvestasya
StandardOutput=journal
StandardError=journal
WorkingDirectory=/opt/nis1/nis
SuccessExitStatus=143
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
```

`-Xms4G`と`-Xmx8G`はマシンスペックに合わせて変更してください。マシンメモリ容量の 1/3 ～ 1/2 くらいが良いかなと思います。

### サービスをリロード

ユニットファイルを編集した後、systemd に変更をリロードする必要があります。

```bash
sudo systemctl daemon-reload
```

### サービスを有効化

サービスを有効化して、システム起動時に自動的に起動するように設定します。

```bash
sudo systemctl enable nis1
```

### サービスを開始

サービスを開始します。

```bash
sudo systemctl start nis1
```

### サービスを停止

サービスを停止します。メンテ等で止める場合に使用します。

```bash
sudo systemctl stop nis1
```

### ログの確認

nis1 サービスのみを参照します。最新から参照できるよう`-r`オプションを付けます。

```bash
sudo journalctl -u nis1 -r
```

リアルタイムで確認したい場合は`-f`オプションを付けます。

```bash
sudo journalctl -u nis1 -f
```

さらに色を付けたい場合は、`-o cat`オプションを付けます。これにより、ログが色付きで表示され、読みやすくなります。

```bash
sudo journalctl -u nis1 -f -o cat
```

## 関連記事

https://qiita.com/ccHarvestasya/items/4e1601e5052e41dc1399

https://qiita.com/ccHarvestasya/items/d2788530b3348a62f08e

https://qiita.com/ccHarvestasya/items/eb74a07e76a4e5e9c902
NEM(NIS1)ノードをUbuntu24でビルドする


## 自前のビルドに意味はあるのか？

Java なので無いと思います。自己満足です。

## 必要な Java と maven をインストール

```bash
sudo apt install openjdk-11-jdk maven
```

## 最新版をクローン

2025/04/03 時点の最新は`v0.6.102`。

```bash
git clone https://github.com/NemProject/nem.git -b v0.6.102 nis1
```

## ビルド

```bash
cd nis1/infra
./package.build.sh build.log
./package.prepare.sh
```

## ネットワークの指定

ネットワークの指定がされていないので、メインネットかテストネットかを設定する。
`mainnet`か`testnet`を入力する。

```bash
sed -i 's/nem\.network = \r/nem.network = mainnet/g' package/nis/config.properties
```

## 任意の場所に配置

`nis1/infra/package`を任意の場所に配置する。

## 関連記事

https://qiita.com/ccHarvestasya/items/72d947b41570b1c12ff4

https://qiita.com/ccHarvestasya/items/d2788530b3348a62f08e

https://qiita.com/ccHarvestasya/items/eb74a07e76a4e5e9c902
【Mac】コマンドで翻訳する方法

translate-shellを使用するとコマンドでGoogle Translateなどを利用して翻訳できます。 

## translate-shellをインストールする

Homebrewを使用する場合には以下のコマンドでインストールできます。

```terminal
brew install translate-shell 
```

その他のインストール方法については以下をご参照ください。

https://github.com/soimort/translate-shell#installation

## 翻訳する

`trans`コマンドを使用して翻訳できます。

```terminal
$ trans 'Hello World'
Hello World

こんにちは世界
(Kon'nichiwa sekai)

「Hello World」の翻訳
[ English -> 日本語 ]

Hello World
    こんにちは世界, ハローワールド, こんにちは、世界
```

### 特定の言語に翻訳する

英語を日本語に翻訳する場合には以下のようにします。

```terminal
$ trans :ja 'Hello World'
Hello World

こんにちは世界
(Kon'nichiwa sekai)

「Hello World」の翻訳
[ English -> 日本語 ]

Hello World
    こんにちは世界, ハローワールド, こんにちは、世界
```

フランス語を日本語に翻訳する場合には以下のようにします。

```terminal
$ trans fr:ja 'Bonjour'
Bonjour

おはよう
(Ohayō)

「Bonjour」の翻訳
[ Français -> 日本語 ]

Bonjour
    おはよう, おはようございます
```

翻訳結果のみ出力するには`-b`を使用します。

```terminal
$ trans fr:ja -b 'Bonjour'
おはよう
```

## ファイルを翻訳する

`input.txt`を翻訳する場合には以下のようにします。

```terminal
trans :ja -i input.txt
```

結果を`output.txt`に出力するには以下のようにします。

```terminal
trans :ja -i input.txt -o output.txt
```
昨日の私の投稿について

昨日11/14に公開した記事へコメントをしていただき、また修正案まで考えてくださった皆様、ありがとうございました。私はqiitaに寄稿するのは初めてで、誰も学校の講義の自分用解説ページなんて見ないと考えていましたが、反応をいただき驚くと共に嬉しく思います。
投稿した記事の方は、読者を学校の仲間を想定していたため、全体公開にするには不備が多いと判断し削除させていただきました。せっかく反応をいただいたにも関わらず、私の不備によってこのような判断になってしまい申し訳ありません。
しかし、私の記事をこうした方がもっと読みやすくなるよというアドバイスをしていただいた方には本当に感謝しております。ありがとうございました。
今後の記事の作成に反映していきたいと思います。
【詳細編】Wikiレンタルサービス『WikiChree.COM』をつくった話

# はじめに
まず、WikiChree.COMとは誰でも簡単に無料でWikiを立ち上げることができる小さなWebサービスです。

https://wikichree.com/

## きっかけ
きっかけは、wikiwiki.jpやアットウィキのような無料Wikiレンタルサービスを昔は使っていました。おかげでPukiWikiというソフトウェアに愛着を持ち、PukiWikiプラグインを作りながらPHPを学びました。そしてある程度PHPを扱えるようになるとレンタルサービスを1からつくってみたいと思いました。それがロマンでした。
多くのレンタルサービスはカスタマイズ性があまりなく、入れてみたいPukiWikiプラグインがあったのですが、それには1からサーバーを建ててPukiWikiを設置する必要がありました。その頃はまだそのような知識がありません。

# 特徴
- PukiWikiの多くの設定を管理画面で簡易的にできる
- 272個のプラグインが用意されており、管理画面にてオン/オフできる
- 19種類のスキン
- スパム対策/サブパスワード機能/スキン設定/カスタムCSS/ユーザー認証(PukiWiki本体の機能 + α)

と上記のように細かな設定ができるという利点があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015774/59f2eba2-edea-bd47-4f2d-63b5330b4aab.png)

# 開発
私は中学3年生からPHPをはじめて5年目の素人ですが、高校1年生あたりにWikiChree.COMを作り始めました。当時はWikiCという名前にしていました。
今も少しメンテナンスはしていますが、~~(最近さぼり気味)~~ 作り始めたのは4年前ぐらいなので思い出しながら記事を書きます。そのため一部分抜けている箇所もあるかもしれませんがご了承ください。

## ウィキソフト
ウィキソフトはPukiWikiを採用しています。

- PukiWiki 1.5.4 (※当初は1.5.3)

これを選んだ理由はきっかけで述べた通り、PukiWikiに愛着を持っているからです。

つくった当時はDokuWikiも対応させていましたが、いざカスタマイズ性を上げるにはウィキソフトの改造は不可欠ですので断念しました。(DokuWikiのレンタルサービスを見たことがないのでやってみたかった)

## 利用言語
- PHP
- JavaScript

PHPはPukiWikiプラグインに興味があり、それを開発しながら習得しました。
JavaScriptはなんとなくでやっているので習得できているかと聞かれるとできている気はしませんねえ...

## 直面した課題
### プラグインのバグ
- 新たなプラグインを大量に追加する中で、やはりPHP8に対応していないものやバグの修正

### スパム対策
- 悪質なスパム投稿への対応にダミーボックス、IPブラックリスト、海外IP規制を実装

### 資金
- 趣味でやっているため、今のところは問題ないが、費用が収益を上回っている点
  → 利用者をある程度増やす必要がある？

### ウィキの量産問題
- 定期的に使われていないウィキが増えている
  → 作成してから一度も利用されていない場合、1ヵ月後に削除するべき？

### 運営、開発
- 運営が開発者である私のみであるため、スパムへの対応やメンテナンス、フォーラムでのリクエストや問題の対応ができていない

## 開発プロセス
- システム開発を開始する (2020年8月)
- コントロールパネルを追加する (2020年9月)
- プラグインを多数追加し、機能性を拡張する (2020年10月)
- システムのリニューアル (2021年11月)
- セキュリティの強化 (2023年1月)
- サブパス機能の追加 (2024年3月)

# おわりに
今後も機能の追加や改善を続けようと思っていますが、時間がなくてあまり開発が進んでいません。
最後まで読んでいただき、ありがとうございました。
【Python】PDFを日付ごとにフォルダ分けする

## はじめに

今回はPythonのshutilを使ってファイル整理をするプログラムを作りました。
今回のプログラムではPDFに縛っていますが応用次第で他の種類のファイルを整理することもできるので、ぜひいろいろなことに応用してもらいたいです。

## 実行環境

- Python 3.11
- Windows 10

## 使用ライブラリ

- shutil
- datetime
- tkinter
    - tkinter.messagebox
    - tkinter.ttk

このプログラムでは外部ライブラリは使用していないのでpipでのインストールは必要ありません。

## 実装の準備

まず、sort_pdfs.pyとか適当な名前のファイルを作成してください。
次に整理したいPDFファイルを.pyファイルと同じフォルダに配置してください。

:::note warn
ファイルが消える可能性もあるので一応消えたらまずいファイルなどはコピーしてください。
:::

## 実装

以下のコードを先程作成した.pyファイルにコピペしてください。
実行すると「年」「月」「日」のフォルダが作成され、そこに配置したPDFファイルがフォルダ分けされます。

```python:コード全文
import os
import shutil
from datetime import datetime
import tkinter as tk  # tkinterをインポート
from tkinter import messagebox, ttk  # メッセージボックスとプログレスバーをインポート

# プログレスバーを含むウィンドウを作成
def create_progress_window(total_files):
    # tkinterのルートウィンドウを作成
    root = tk.Tk()
    root.title("PDF整理中")
    root.geometry("300x100")  # ウィンドウのサイズを指定

    # プログレスバーの作成
    progress_bar = ttk.Progressbar(root, orient="horizontal", length=250, mode="determinate")
    progress_bar.pack(pady=20)

    # プログレスバーの最大値を設定
    progress_bar["maximum"] = total_files

    return root, progress_bar

# 整理したいフォルダのパスを指定
source_folder = os.getcwd()  # 実行されたフォルダを取得

# フォルダ内のファイルを取得
files = os.listdir(source_folder)

# PDFファイルのみを対象としたリストを作成
pdf_files = [file_name for file_name in files if file_name.lower().endswith('.pdf')]

# プログレスバーのウィンドウを作成
root, progress_bar = create_progress_window(len(pdf_files))

# PDFファイルの整理を行う
for file_name in pdf_files:
    print("Processing:", file_name)  # 現在処理中のファイル名を表示

    # ファイルのフルパス
    file_path = os.path.join(source_folder, file_name)

    # ファイルが存在しない場合はスキップ（フォルダが混じっている場合など）
    if not os.path.isfile(file_path):
        progress_bar["value"] += 1  # プログレスバーを更新
        root.update()  # ウィンドウを更新
        continue

    # ファイルの更新日を取得
    modification_time = os.path.getmtime(file_path)
    modification_date = datetime.fromtimestamp(modification_time)

    # フォルダ名を「%Y年/%m月/%d日」形式で作成
    year_folder = os.path.join(source_folder, modification_date.strftime('%Y年'))
    month_folder = os.path.join(year_folder, modification_date.strftime('%m月'))
    day_folder = os.path.join(month_folder, modification_date.strftime('%d日'))

    # 日付ごとのフォルダを作成（存在しない場合）
    os.makedirs(day_folder, exist_ok=True)

    # ファイルを日付フォルダに移動
    shutil.move(file_path, os.path.join(day_folder, file_name))

    # プログレスバーを更新
    progress_bar["value"] += 1
    root.update()  # ウィンドウを更新

# 完了メッセージをメッセージボックスで表示
messagebox.showinfo("完了", "PDFファイルのフォルダ分けが完了しました！")

# tkinterを終了
root.destroy()

```

## 応用

以下の部分の`endswith('.pdf')`の.pdfを整理したいファイルの拡張子にすることで他の種類のファイルもこのプログラムで整理することができます。

```python:
# PDFファイルのみを対象としたリストを作成
pdf_files = [file_name for file_name in files if file_name.lower().endswith('.pdf')]
```

また、以下のように拡張子リストを用いると複数の拡張子のファイルをフォルダ分けすることができます。

```python
file_extensions = ['.pdf', '.jpg', '.png']
pdf_files = [file_name for file_name in files if file_name.lower().endswith(tuple(file_extensions))]

```


## おわりに

今回はファイルをフォルダ分けするプログラムを作ってみました。
こちらの記事がなにかの役に立つと嬉しいです。
【高専ロボコン】絶対失敗しない!回路の作り方1選!【有料級】

注:この記事ではEDAに対して罵詈雑言を放っていますが、すべて冗談です。

この記事は鳥羽商船高等専門学校 Advent Calendar 2024 12日目の記事です。

https://qiita.com/advent-calendar/2024/tobakosen


# 前提:そもそも高専ロボコンの回路における失敗とは?
電気回路や電子回路において、設計者の想定通りに動かない場合、それは失敗です。(定義)
設計者が悪いわけありません。すべてはEDA(回路設計ソフト)が悪いのです。
ただEDAに責任を擦り付けるためには知識が必要です。
そのために我々は回路を学んでいます。
# 例:失敗している回路
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924774/489a8d98-04a2-3104-932b-a360147413de.png)
こちらのハーフブリッジは、実際に回路班のN君が発注したMD(モータードライバ)回路の一部です。動かなかったらしいですね。
このハーフブリッジにはある重大なミスが隠されています。
そうですね、BS(ブートストラップ)コンデンサがなぜかHO1に接続されていますね。
これでは回路発注の金額がすべて無駄になってしまいます。
今回の敗因はEDAがミスを注意してくれなかったことにあります。なので彼は無罪といえましょう。
ただしEDAは回路が電気的におかしくないか(例:VCCとGNDがショートしている等)しか見てくれません。一刻も早くミスを注意する機能を搭載してほしいものですね。
# 本題:失敗しない方法
さてここからが本題です。先ほどまでの話は哀れな高専2年生の自虐です。
絶対に回路設計で失敗しない方法、それは経験者の先輩に確認してもらうことです。
まあ経験者の先輩も見落とすことはありますが、それはその先輩の失敗なのでノーカンです。
先輩に確認してもらうことにより、配線に間違いがないか、意味不明な部品配置をしていないかどうかなど様々なことがわかります。それを逐一メモしたり、要点を質問したり等することで自分も先輩と同じように回路チェックができ、ポンコツEDA君に悩まされることもなくなります。素晴らしいですね。
高専2年生N君は頼れる先輩に確認してもらったため、自分のミスが発覚しました(回路発注後)。
# あとがき
今では私が先輩、後輩に勧めるのはもちろんKiCAD。
なぜなら、彼らもまた特別な存在だからです。
Power AutomateでTeamsのチームメンバーの一覧を取得する

# 概要
基本的にTeamsのグループメンバーを取得したい場合、［Office 365グループ］コネクタの［グループメンバーの一覧表示］アクションを使用します。
ただし、Teamsから所有者の追加をした場合、メンバーだけでなく所有者も取得結果に含まれてしまいます。詳細は以下記事をご確認ください。

https://qiita.com/wawawabox/items/702baa0e0e8ec27e0d30

今回は所有者を含まないTeamsのチームメンバーの一覧を取得する手順を紹介します。

# 手順1.［HTTP要求 V2を送信する］で所有者を含むメンバーの一覧を取得する
［Office 365グループ］コネクタの［HTTP要求 V2を送信する］アクションで、URIを設定して所有者を含むメンバーの一覧を取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/5afaf58b-564d-f5ed-1ad4-26805759a04b.png)


# 手順2.［HTTP要求 V2を送信する］で所有者の一覧を取得する
［Office 365グループ］コネクタの［HTTP要求 V2を送信する］アクションで、URIを設定して所有者の一覧を取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/e31f4e57-6fbb-4c09-c7a9-6495bd7074d8.png)


# 手順3.［アレイのフィルター］で差集合を用いてメンバーの一覧を取得する
［データ操作］コネクタの［アレイのフィルター処理］で、手順1と2で取得した配列の差集合を求めます。左辺には、以下の数式をセットします。

```text
contains(outputs('HTTP_要求_V2_を送信する_-_所有者の一覧を取得')?['body/value'], item())
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3640497/4d8ef1f5-c472-0603-733a-f64b246f2a52.png)

Power Automateで配列の差集合を求める方法については、以下記事をご確認ください。

https://qiita.com/k_oshima23/items/cbf66ae53734a9fbc905
CSR, SSR, SSGの違いについて説明するためのメモ


## 概要
技術選定の際に理解しておいた方が良い概念をまとめました。

## CSR(Client Side Rendering)
### 画面描画までの流れ
1. クライアントがサーバーへリクエストする
2. サーバーが空のHTML, JavaScriptを含めてクライアントへレスポンスする
2. クライアントが上記ファイルを使ってレンダリング(HTMLを生成)する
2. クライアントは最初のレンダリング以降、必要なデータのみサーバーから取得する

### メリット
1. ページ更新時は必要なデータのみ更新すれば良いため、ページ遷移が速い
1. Webサーバーとの重い通信が初期表示時のみとなる

### デメリット
1. 初回表示が遅いため、SEOに悪影響を及ぼす可能性が高い

### 対応しているフレームワーク、ライブラリ
+ React
+ Next.js
+ Vue.js
+ Nuxt.js
+ Angular


### 適したユースケース
+ 頻繁にデータを更新するアプリ
    + チャット、SNSなど
+ 部分的なコンテンツを更新するアプリ
    + map系など

### 要するに

webサイトに初めてアクセスする時は初期ロードとレンダリングするから初期ロードには時間がかかるけど、それ以降は必要なデータのみロードするだけなので、動作はサクサク


## SSR(Server Side Rendering)
### 仕組み
1. クライアントがサーバーへリクエストする
1. サーバー側でHTMLを生成しクライアントへレスポンスする
1. ブラウザ側でサーバーから送られたHTMLを表示する


### メリット
1. サーバー側でレンダリングしているので初期表示が速い(SEO対策)
2. ブラウザ側に負荷がかからない(ブラウザに依存しない)

### デメリット
1. サーバー側の処理に負荷がかかる
1. ページ遷移ごとにサーバーからHTMLを取得するので通信が重く、更新が遅い


### 対応しているフレームワーク、ライブラリ
+ Nuxt.js(Reactベース)
+ Next.js(Vueベース)
+ Angular Universal(Angularベース)

### 適したユースケース
+ SEOが重要視されるサイト
    + ニュースサイト
+ リアルタイムで商品情報が更新されるサイト
    + Eコマース

# 要するに
webサイトに初めてアクセスしたときはサーバー側でHTMLを生成（レンダリング）しているので、
すぐにブラウザに表示可能だけど、ただページ遷移が遅い。



## SSG(Static Site Generation)
### 仕組み
0. サーバー側は***事前に静的ファイルをビルドしておく***
1. クライアントがサーバーへリクエストする
1. サーバーは***事前にビルドしておいた静的ファイル***をクライアントへレスポンスする。

### メリット
+ 静的ファイルを返すだけなので非常に高速

### デメリット
+ リアルタイム更新ができない

### 適したユースケース
+ 更新が少ないもの
    + ブログ

対応しているフレームワーク、ライブラリ
+ Gatsby, 
+ Next.js, 
+ Hugo, 
+ Jekyll


# 要するに
事前に静的ファイルをビルドしているので非常に高速だが、リアルタイム更新はできない

## 比較
| 特徴| CSR | SSR | SSG |
|:-:|:-:|:-:|:-:|
| 初期ロード速度  | 遅い  | 中  | 速い  |
| SEO  | 悪い  | 良い  | 良い  |
| 動作性  | 高い  | 中  | 低い  |
| サーバー負荷  |  低い | 高い  | 低い  |
| 更新頻度  | 高い  | 中  | 低い  |
| 適したケース  | 動的サイト  | コンテンツ重視のサイト  |  ブログ |


## まとめ


参考
> https://tech-blog.rakus.co.jp/entry/20240927/rendering#%E6%A6%82%E8%A6%81
ローカルにあるファイルやディレクトリをGitLabで管理する

いつもはmainブランチから開発用ブランチを切って作業をしていて、新規開発で実装したコードをGit上で管理する際に忘れてるフローがあったのでメモとして残します。

1. GitLab上にプロジェクトを作成する。

2. リポジトリをデフォルトブランチmainで作成する。
`git init --initial-branch main`

3. リモートリポジトリ先の名前をoriginに設定。
`git remote add origin <your-gitlab-repo-url>`

4. リソースをステージングする。
`git add .`

5. コミットする。
`git commit -m "Initial commit"`

6. プッシュする。
`git push -uf origin main`
【Shopify】ShopifyからGitHubへの接続とテーマ追加

# 環境
Windows11
※gitはインストール済み

# GitHubリポジトリを作成する
ローカルリポジトリとリモートリポジトリの紐づけまで行う。

# ShopifyからGitHubに接続する
オンラインストア＞テーマ＞テーマを追加＞GitHubから接続する
1. ログイン等を済ます
1. 接続したいリポジトリ、ブランチなどを選択して追加

# 挙動
1. Shopifyの「コードを編集」「カスタマイズ」での変更は自動でGitHub上に反映される
1. ローカル環境で変更したファイルはGitHubへのpushだけでShopifyへも反映される
1. Shopify上とローカルで同時に同じ箇所の編集を行った場合はコンフリクトが発生する（GitHub上で解消すればOK）
Universal Dependencies 2.15リリース

[Universal Dependencies 2.15](http://hdl.handle.net/11234/1-5787)がリリースされた、との連絡をいただいた。[半年前のUniversal Dependencies 2.14](https://qiita.com/KoichiYasuoka/items/a4d17b55c829b62a15c2)と較べて、Central Pashto、Gwichʼin、Northwest Gbaya、Pech、Phrygian、Spanish Sign Language、Uzbekが増えており、168の言語にまたがるツリーバンクとなった。ただ、リリースの1ヶ月ほど前に、detとclfの扱いで[かなりモメており](https://github.com/UniversalDependencies/docs/issues/1059)、[現在もモメ続けている](https://github.com/UniversalDependencies/docs/issues/1063)ために、各言語の更新が滞ってしまった。私(安岡孝一)個人としては、現代中国語の「她的這本書」

![det-clf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/5c9386a1-494e-6b3c-fe47-39423e864e56.png)

がこのままの係り受けで問題なさそうなので、まあ、古典中国語に関しても何とかなると思う。各言語ごとに事情があるのに、それでもUniversalを目指さなければいけないので、どうしてもこういう問題が起こるのだろう。
Github Copilot Workspaceの感想

**＜本記事のターゲット層＞**
- Github Copilot Workspaceに関心がある人
- システム開発の効率化に関心がある人
- 開発者の将来に不安を感じている人

## 1.はじめに
今回、記事はあっさり目に書きます。なぜなら、Github Copilot Workspaceはもう少しプロンプトをいじくり倒したほうが良いだけではなく、Technical Previewなだけあって発展途上なため、手厚く書いたところでGAしたときには仕様が変わっている可能性が大いにあるからです。

とにかくお伝えしたいことは、開発者の将来は思ったより明るく、ただしいままで通りの時代ではなく、いままで以上に変化が早くなるということです。

## 2. Github Copilot Workspaceとは？
[Github Copilot Workspace](https://github.blog/jp/2024-04-30-github-copilot-workspace/)とは、自然言語により、コードのブレインストーミング、計画、ビルド、テスト、実行を行うことができる機能です。

すでにGithubやVS CodeでGithub Copilotの性能を体感している人も多くいることでしょう。エラーの原因調査、コードのレビュー、提案、あるいは分からないことについて質問をしたり、ときにヒントをもらったり・・・一度体感してしまうを手放すことが難しいのではないでしょうか。

そうした能力をレポジトリやissueに対して発揮する機能、それがGithub Copilot Workspaceだと捉えて頂くとイメージが沸くと思います。

## 3. Github Copilot Workspaceを使った感想
まだ使い始めたばかりですが、想像していた通り、ただプロンプトを記述して実行してみても、構築したアプリケーションはそのままでは動きませんでした。

大したことないと思われますか？とんでもありません。

何某かを作り上げたいとき、最初をどのように構築すればよいか悩んだことはありませんか？

ある程度、最初の形を作ってくれるだけでも助かるものです。それに、問題があってもissueに登録して、そこからまたGithub Copilot Workspaceに頼むことでより完成度の高いものが出来上がります。

イチからコードを書くとどれだけ時間がかかるのか、調査する時間を含めると膨大な時間と労力を使うことは想像に難くありません。

**＜Github Copilot Workspaceダッシュボード＞**
![](https://storage.googleapis.com/zenn-user-upload/2f0b8441f9aa-20241115.jpg)

**＜Github Copilot Workspaceで自動で作成されたレポジトリ＞**
![](https://storage.googleapis.com/zenn-user-upload/ea6803cd23a3-20241115.jpg)

**＜issueのGithub Copilot Workspaceボタン＞**
![](https://storage.googleapis.com/zenn-user-upload/1bb32313b745-20241115.jpg)

## 4. まとめ
AIはいまのところ人に成り代わるものではなく、人の力を底上げするものであると感じています。Github CopilotやChat-GPT、Microsoft Copilotを使ったことがあればそこはお分かりいただけると思います。

Github Copilot Workspaceについても同様です。人間が一から考えて構築するのではなく、AIが支援してくれるのだと捉えて頂ければよいと思います。

これからの時代、出生数が大幅に減少し、労働人口が著しく減った時代に突入します。そうした時代においては、人を採用で増やすには限界があります。もちろん外国人労働者を雇うという手もありますが、それでも有限ですし、何より日本語が話せる人材を探す労力、またはこちらが相手の言語を話せる人材を探さなくてはいけません。

AIを活用することで、労働力を底上げするという設備投資の一環が生成AIを導入するということです。

生成AIの活用なくして仕事が回らない時代に突入しつつあることは、人手不足倒産が増加しつつあることでお分かり頂けると思います。
ある長さの16進ダンプを表示する。


x 過去ログを見よ!!
x M5NanoC6では、予定は、未定




オンラインコンパイラ

```c++


#include <iostream>
using namespace std;


//ある長さを16進に変換 256ぐらい
char *hex_conv(const unsigned char *a,int n) {

  static char b[(256*3) + 1];
  char h[16] = {'0', '1', '2', '3', '4', '5', 
    '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
  
  b[0] = 0;
  if(n>256){n=256;}
  for(int i=0;i<n;i++){
    b[i*3+0] = h[a[i] >> 4];
    b[i*3+1] = h[a[i] & 0x0f];
    b[i*3+2] = ':';
    //printf(".");
  }
  if(n != 0) {b[n*3-1] = 0;}
  //printf("\n");
  //printf("[%s]\n",b);
  
  return ( b ); //戻り値
  
}//mac_add_conv


int main(void){
    // Your code here!
    
    char kk[] = {
      "1234567890123456"
      "1234567890123456"
      "1234567890123456"
      "1234567890123456"

      "1234567890123456"
      "1234567890123456"
      "1234567890123456"
      "1234567890123456"

      "1234567890123456"
      "1234567890123456"
      "1234567890123456"
      "1234567890123456"

      "1234567890123456"
      "1234567890123456"
      "1234567890123456"
      "1234567890123450"
    };
    
    char *dd = hex_conv((unsigned char *)kk,3);
    printf("%s\n",dd);
    
}


```


```

31:32:33

```
MVVM + Repositoryで自作アプリ開発と初クローズドテストの話

# はじめに
遂に約3年前から作りたかったアプリを作成できたので、使ったアーキテクチャとクローズドテストの話をしていきます。
まだまだ勉強不足でツッコミどころが多いかもしれません。

# アプリ紹介
日々のメンタルを記録し、可視化して自己管理していこうぜって感じのアプリです。
メンタルと日付と時間帯とメモを記録、振り返ることができます。
肝心の削除機能は次のアプデで...

![6819.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860584/459337b0-4319-a032-91b3-391f6360e9b5.jpeg)


# アーキテクチャ
今回はMVVM + Repositoryを採用しました。
理由は3つあって↓

- 業務で使っているけどイマイチ理解が進んでいない
- Activityに処理書きすぎてエグい
- Roomを使ってデータを操作をしていて、この処理もRepositoryとして組み込んだら綺麗に描けるのでは

以上の3つです。

①から⑥の処理の流れになっています。

![スクリーンショット 2024-11-15 20.25.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3860584/598bc2df-8637-21a7-0dda-53833fa0474c.png)

### View
ActivityやFragmentがViewの役割を担っています。ユーザーに見える部分です。
ほぼViewControllerみたいな役割もしています。これいいのか...

### ViewModel
ここからが内部的な部分。画面回転が入っても情報を保持してくれているので助かる。
LiveDataを作って値を監視できる。変更通知をActivityで書いたobserve受け取ることもできる。
特にDBからの応答をView層に通知することができるので良き。
コルーチンを使って非同期処理でデータのやり取りができるので、UIスレッドをブロックせずに済む。
正直やっと理解が進んで感動した。

### Repository
DB関連の役割。
ここではRoomを使ってSQLite(ローカルDB)を操作している。
ここにinsertなどの処理をまとめておけば、毎回実装するなんてことが起きないので絶対あった方がスッキリする。
Model(Data Class)ともやりとりをしている。

### Model
データクラスの役割。
感情や日付などの、Roomで使うデータをここで書いている。
DBにどんな情報があるか、必要かすぐに分かるのでこれもあった方がいい。

# クローズドテスト
アプリを作り終えたからストアにアップしたい。
が、ここからが鬼門。
20人テスターを集めて2週間テストをすることが必須条件とのこと。Googleさんマジスカ。
筆者は、アプリやクローズドテストのコミュニティを使ってやり遂げました。
正直、最初は鬼だと思ってたけど様々な人にテストしてもらって見えたものがある。
特にコミュニティに参加して良かった。レビューなどもいただけてアプリがいい方向に動いた。
なんやかんや、クローズドテストして良かった。
筆者が大変お世話になったコミュニティとアプリのリンクを貼らせていただきます。本当にありがとうございました。

https://x.com/Android189473?t=OyOShIJ0UFWXGp7kuBeU9w&s=09

https://play.google.com/store/apps/details?id=com.andro.zm.tools.androidtesterspayforward

# まとめ
約3年前の自分。エンジニアは楽しいぞ。
めげるな、じゃなくてMVVMで考えて役割を持たせる大切さと、テストの大切さを学習できました。

# 筆者が作ったアプリ
アプデちゃんとするので良かったらDLお願いします！

https://play.google.com/store/apps/details?id=jp.example.mentalrecordapplication&pcampaignid=web_share