OmniAICreator/Qiita-1.07M huggingface dataset:
Python基礎（if文、for文、リスト内包表記）

Pythonで基本的な文法を紹介していくよ～。
今回は、if文、for文、リスト内包表記の3つを書いていくよ。

## if文の使い方
pythonはインデントが重要で、if文ならifの中身で処理させたい内容はインデントを1つ下げて書くよ。
```py
if 条件式:
    処理1
処理2
```
使用例
20歳以下なら、「閲覧権限がありません。」と表示させる。
```py
print("年齢チェック")
age = 19
if age < 20:
    print("閲覧権限がありません。")
print("年齢チェック終了")

# 出力結果
> 年齢チェック
> 閲覧権限がありません。
> 年齢チェック終了
```

## for文の使い方
Javaの拡張for文のイメージに近いよ。
```py
for 任意の変数名 in イテラブルオブジェクト
```
使用例
辞書型のリストから1つずつ取り出し、プリントする。
```py
list = [{"id": 1, "name": "apple"}, {"id": 2, "name": "grape"}, {"id": 3, "name": "peach"}]
for i in list:
    print(i)

# 出力結果
> {"id": 1, "name": "apple"}
> {"id": 2, "name": "grape"}
> {"id": 3, "name": "peach"}
```


## リスト内包表記の基本
#### リスト内包表記の基本型
```py
[式 for 任意の変数名 in イテラブルオブジェクト]
```
使用例
0~5の数字の2乗を計算し、プリントする。
```py
squared = [i**2 for i in range(6)]
print(squared)

# 出力結果
> [0, 1, 4, 9, 16]
```
#### 結果をifで分岐させる
```py
[式 for 任意の変数名 in イテラブルオブジェクト if 条件式]
```
使用例
0~5の数字の2乗を計算したうち、奇数だけを取り出し、プリントする。
```py
squared = [i**2 for i in range(6) if i % 2 == 1]
print(squared)

# 出力結果
> [1, 9, 25]
```

##### おまけ
辞書型のリストから、任意の値を取り出す。
```py
list = [{"id": 1, "name": "apple"}, {"id": 2, "name": "grape"}, {"id": 3, "name": "peach"}]

# リストから、id=1の場合のnameを取り出す。
get_name = [i["name"] for i in list if i["id"] == 1]
print(get_name)

# 出力結果
> ['apple']
```

今回はpythonの基本構文を紹介したよ。
リスト内包表記は少し難しい。。。
TypeScriptでのメソッドオーバーライドを理解する

## はじめに
TypeScriptでは、オブジェクト指向プログラミング（OOP）の一環として、メソッドオーバーライドをサポートしています。オーバーライドは、親クラス（スーパークラス）で定義されたメソッドを子クラス（サブクラス）で再定義することを指し、クラスの機能を拡張または特化するための重要な手法です。

## メソッドオーバーライドとは？

メソッドオーバーライドとは、スーパークラスで定義されたメソッドをサブクラスで再定義し、異なる動作を実装することです。これにより、ポリモーフィズム（多態性）を実現し、オブジェクト指向設計をより柔軟かつ強力にします。

## 基本ルール

1. **メソッド名が同じ**：親クラスのメソッドと同じ名前で定義します。
2. **引数リストが同じ**：親クラスのメソッドと同じ引数リストを持ちます。
3. **戻り値の型が同じ**：親クラスのメソッドと同じ戻り値の型を持ちます。

## TypeScriptでのオーバーライドの例

### 親クラスの定義

まず、親クラス（スーパークラス）を定義します。

```typescript
class Animal {
    makeSound(): void {
        console.log("Animal makes a sound");
    }
}
```

### 子クラスの定義とメソッドのオーバーライド

次に、子クラス（サブクラス）を定義し、親クラスのメソッドをオーバーライドします。

```typescript
class Dog extends Animal {
    makeSound(): void {
        console.log("Dog barks");
    }
}

class Cat extends Animal {
    makeSound(): void {
        console.log("Cat meows");
    }
}
```

### オーバーライドメソッドの使用

オーバーライドされたメソッドを呼び出して動作を確認します。

```typescript
const myAnimal: Animal = new Animal();
const myDog: Animal = new Dog();
const myCat: Animal = new Cat();

myAnimal.makeSound(); // 出力: Animal makes a sound
myDog.makeSound();    // 出力: Dog barks
myCat.makeSound();    // 出力: Cat meows
```

## オーバーライドの利点

### 1. **コードの再利用**：
   - スーパークラスで共通の機能を定義し、サブクラスでその機能を拡張または変更することで、コードの再利用性が向上します。

### 2. **ポリモーフィズムの実現**：
   - 同じメソッド名で異なる動作を実装できるため、異なるオブジェクトに対して同じインターフェースで操作できます。

### 3. **メンテナンス性の向上**：
   - 共通の処理を親クラスにまとめ、特化した処理を子クラスに分けることで、コードのメンテナンスが容易になります。

## まとめ

TypeScriptでのメソッドオーバーライドは、OOPの重要な機能の一つです。これを活用することで、クラスの設計がより柔軟かつ強力になります。親クラスで共通の機能を定義し、子クラスで特化した動作を実装することで、コードの再利用性、可読性、メンテナンス性が向上します。
package.jsonのバージョンを自動で更新！Node.jsアプリ開発者のための時短テクニック

## バージョンいちいち上げるの面倒
Node.js でアプリを作ったときに、いちいちバージョン上げたりするの面倒じゃないですか？
自動アップデートされる場合は、ユーザからしたらバージョンなんて意識しないでしょうしちょっと無駄がある気がして、これを何とかしたい

## リリース時に自動でバージョンを上げる

### バージョン表記
自動でバージョンを上げるなら、
```
<西暦>.<月(一桁)>.<カウンタ>
```
のような表記が良さそうですね。
(最後を <日> にしてしまうと、同日に複数回のリリースができなくなるため不採用)


### package.json>version を書き換えるスクリプト

`versionCounter.js` という名前で以下の内容のスクリプトを作成。
```
const fs = require('fs');
const path = require('path');

const counterFilePath = path.resolve(__dirname, 'build-counter.txt');
const packageFilePath = path.resolve(__dirname, 'package.json');
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1; // 0-based なので+1

let counter = 100;

if (fs.existsSync(counterFilePath)) {
  const data = fs.readFileSync(counterFilePath, 'utf8');
  const [savedYear, savedMonth, savedCounter] = data.split('.').map(Number);

  if (savedYear === year && savedMonth === month) {
    counter = savedCounter + 1;
  }
}

fs.writeFileSync(counterFilePath, `${year}.${month}.${counter}`);

// package.jsonのバージョンを更新
const packageJson = JSON.parse(fs.readFileSync(packageFilePath, 'utf8'));
packageJson.version = `${year}.${month}.${counter}`;
fs.writeFileSync(packageFilePath, JSON.stringify(packageJson, null, 2));

console.log(`${year}.${month}.${counter}`);
```

* `build-counter.txt`というファイルにバージョンを書き込み、実行時にカウンターをインクリメント
* 生成したバージョンを使って `package.json` の `version` を書き換え
という感じです

### scripts

```
    "prepackage": "node versionCounter.js",
    "package": "pnpm prepackage && xxx"
```

### 使い方

`pnpm package` とやると、 `versionCounter.js` によってバージョンが書き換えられビルドされます。
煩わしいバージョン管理とオサラバ。
【SwiftUI/ UIKit】ListとTableViewの比較

# 概要
SwiftUIのListとUIKitのTableViewを比較した表をChatGPTに書いてもらいました。

# 比較
| 機能/特徴                  | SwiftUIのList                                  | UIKitのTableView                                |
|---------------------------|------------------------------------------------|------------------------------------------------|
| **定義方法**              | Swiftの宣言的な構文で定義                       | Objective-C/SwiftでコードベースまたはInterface Builderで定義 |
| **データソースの設定**    | `ForEach`や`@State`、`@Binding`を使用           | `UITableViewDataSource`プロトコルを実装           |
| **デリゲートの設定**      | なし（バインディングやクロージャを使用）       | `UITableViewDelegate`プロトコルを実装             |
| **セルのカスタマイズ**    | 任意のViewを使用して柔軟にカスタマイズ可能      | `UITableViewCell`をサブクラス化してカスタマイズ  |
| **セルの再利用**          | 自動的に管理される                              | `dequeueReusableCell`メソッドを使用               |
| **セクションとヘッダー**  | `Section`を使用して定義                          | `UITableViewHeaderFooterView`を使用               |
| **編集モード**            | `onDelete`や`onMove`を使用                       | 編集モードを有効にして`editingStyle`メソッドを実装  |
| **パフォーマンス**        | 軽量で高速                                      | 適切に最適化されているが、設定によってはパフォーマンスの問題が発生することがある |
| **アニメーション**        | 簡単に実装可能                                  | アニメーションのカスタマイズにはコードが必要       |
| **アクセスビリティ**      | 自動的にサポートされる                          | 手動でのサポートが必要な場合がある                |
| **APIの一貫性**           | SwiftUI全体と一貫したAPI設計                    | UIKit全体と一貫したAPI設計                        |
| **導入の簡単さ**          | 簡単に導入可能                                  | 複雑な設定が必要な場合がある                      |
| **プラットフォームの互換性** | iOS 13以降で使用可能                            | iOS 2.0以降で使用可能                             |
| **リアクティブプログラミング** | `Combine`や`@State`を使用して簡単に実装可能     | 別途リアクティブプログラミングライブラリを使用する必要がある |
| **レイアウトの柔軟性**    | 簡単にカスタマイズ可能                          | `Auto Layout`を使用して柔軟にカスタマイズ可能      |
[UE5]Ensure condition failed: oldValue == newValue 発生時の対応メモ

# はじめに
下記の現象が発生しました。
その際に実施した対処をメモします。

# 発生した現象
どちらもDevelopmentでのみ発生、Shippingでは発生せず
- Developmentでパッケージ化したアプリの起動直後に、アプリがフリーズする
パッケージ後、2，3回はアプリが動作するが、それ以降フリーズするようになった
（起動前にSavedフォルダを削除するとフリーズはしなかった）
ログを見ると下記エラーが出ていた
```
LogOutputDevice: Error: Ensure condition failed: oldValue == newValue  [File:D:\build\++UE5\Sync\Engine\Source\Runtime\Core\Private\HAL\ThreadingBase.cpp] [Line: 311] 
```
- VRでHMD内の画質が落ちる
上記現象でフリーズせずに起動した場合には、HMD内の画質が著しく落ちる現象が起きた

# 環境
- Windows11
- UE5.3.2
- Quest3（有線ケーブルでQuest Link）

# 対応した内容
下記を実施したところ、発生しなくなりました。
1. UEの再インストール
1. Visual Studioでリビルド
1. UEのプロジェクト設定で「完全に再ビルド」をTrueにしてパッケージ化
超超超初心者がReact入門チュートリアルをやってみた。[ongoing]

# この記事の目的
今回はちょっと前までVS codeもインストールしておらずターミナルも触ったことないのに、Mac M3チップメモリ16Gを買うという宝の持ち腐れだった私が、必要に迫られ泣く泣くReactを初めて触ってみた過程を記録する。
目的は、これから超初心者を教えるエンジニアの皆さんに、「あ、本当の初心者はこんなところで躓くのか！」と思っていただくことだ。もちろん、私と同じ初心者も「このレベルでもまずはなんとかチュートリアルの完遂ができるんんだな！私もできるかも！」と思っていただければ幸いである。


# 初心者がReactに立ち向かうことになった経緯
チームでAWSをやってみよう！となり、このハンズオンをやってみた。

https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-Serverless-1-2022-confirmation_422.html

このハンズオン、宇宙一わかりやすかった。
初心者すぎてAWSの「色んなアプリを呼んでくる」という概念がわからなかったのだが、なんとなく全体像の理解ができた。チームでも「これはやって良かった！」と満場一致。

その後私はフロントエンドを担当することになり、AWS Amplifyを使いfigmaからReactを経由してAWS AmplifyでWebアプリ化するプロセスを踏むことになる。

どのqiitaを参考にしたか忘れたが、こんな感じの。

https://qiita.com/shxn0/items/cdf3084c62ead23023ae

しかし！！Reactが訳わからなすぎて結構つまずいた！！

さらに、[v0](https://v0.dev/)でAIを使ってUIを作り、そのままReact appのコードが出るからテストレベルならフロントエンド簡単に作れるやん！となり。

これはちょっとReactを触らないといけなそうだぞ、となった次第だ。




# 参考にした動画
今回はこちらの動画を参考に、動画をみながら全く同じことをハンズオンでやってみた。

https://www.youtube.com/watch?v=nRCNL9T3J98

まずこの動画、めちゃくちゃわかりやすい。
この場を借りてこの方に心からのお礼を申し上げたい。
reactのメリットも説明されていて、なんとなくわかった気がした。


では順を追って振り返っていく。

# ファースト躓きポイント

まず冒頭

<iframe width="560" height="315" src="https://www.youtube.com/embed/nRCNL9T3J98?si=gbcxQBRcKrU2WDOv&amp;start=69" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


VS code でターミナルを起動してnodeのバージョンを確認する。
はい、もうすでにわからない。
VS codeは開けるけど、そこでなんのファイルを開くの！？テキトーって何？
とりあえずmacのターミナルを開いてnodeのバージョンを確認。
すると入って無さそうだったので、nodeのインストール方法を調べる。
nodeをインストールするにはbrewをインストールする必要があるらしい。ドユコトー
とりあえずなんとか２つともインストール。ふぅ。

そしてそのままmacのターミナル上で、ディレクトリがdesktopの状態から動画の指示通りreactファイルを立ち上げた。
Happy Hacking!
HackできてHappyでいいのかは全くわからなかったがとりあえずOK。

で、動画に沿っていくためにはやっぱりVS codeで開かなくてはいけない...
とりあえずVS code を立ち上げて
files→Open folder→さっき立ち上げたreactファイルを選択！これで動画と同じ画面になった！

# 亀の速度で進める

動画の通り進めていくと、chromeを使いローカルサーバーでreactが立ち上がった！おお！感動！
こんなちょっとのことでも初心者は感動する。

動画の中で、react appでロゴの写真ではなく"Hello React"というメッセージを表記するようにする。
しかし！同じようにコードを書き換えてもエラーがでる、、、なぜだ....

私は発見した！保存してないから反映されないんだ！！！（名探偵すぎる）

:::note info
都度保存しないとプログラムした内容はコンパイル結果に反映されない。
:::

# 現時点での成果
動画の20分あたりまで完了。ここまでで２時間近くはなんやかんやかかっている。
いいのだ。自分のペースでいいのだ。
うまくコンパイルできた時は嬉しい！

![Screenshot 2024-05-21 at 17.23.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794078/c733ebff-aad3-da87-80a1-caf8148b8990.png)


## 余談だが
今回初めてQiitaを書いてみて、エディタがとてもエンジニア向けだなあと思った。
自分は理系でありながら開発経験がなく、最近始めたのだが、#でheadingになるとか、エディタとプレビュー２分割できるとか、/で色々コードブロック出てくるとかはとてもエンジニアっぽい。
wordとかでしか文章を書かないnon-engineersには使いにくそうだ。文系の友達でnotion使えない子も割といる。
自分は少しずつこの手のもの（latexとか、Rとか、VS code)を触るようになり抵抗がなくなってきているので、Qiitaのエディターは使いやすかった。
そんなこんなで自分はまだ開発もできるようになる余地がありそうだと思ってしまった。
Redshiftでテーブル更新する方法（ステージング）

# 0.参考教材

英語ではありますが、Redshiftについて詳しく記載されているのでとても良い教材かと思います。

https://www.udemy.com/course/aws-redshift-a-comprehensive-guide/

# 1.Redshiftでは、テーブル同士のmergeやupsertができない

## ステージングを活用する

salesテーブルはマスター

sales_updateテーブルは更新後のテーブル

```sql
create table sales_update as 

select * from sales
```

この段階では、

salesとsales_updateテーブル行は同じ

次に更新テーブルに対して、2008-11-30以降のデータを更新する

```python
**update sales_update

set qtysold = qtysold *2,

pricepaid = pricepaid * 0,

commission = commission *1.1

where saletime > ‘2008-11-30’

and mod(sallerid,5) = 0;**
```

行の全セラーの中から５番目のセラーIDを選び、販売数量を２の倍数で更新し、

支払い価格を０の倍数で更新する。

2008-11-30以降のsalleridが4で割り切れるデータ分salesidを追加

```python
**insert into sales_update

select (salesid + 172456) as salesid,listid,sellerid,……,

from sales

where saletime > ‘2008-11-30’

and mod(sellerid,4) =0;**
```

sales_updateに新たなデータを入れている。

結果833行を追加

結果として、新たな売り上げデータは、

sales_updateテーブルに格納されている。

sales_updateは、

- seller_idが5で割り切れる行が更新されている
- seller_idが4で割り切れている行（833行）に対して、sales_idのみが変更されているデータを追加

元テーブルをどのように更新するか？

### →ステージングテーブルの助けを用いてマージする

```sql
--ステージングの作成
create temp table stagesales as 
select * from sales_update
--更新されたデータのみを抽出している。
where sales_update.saletime > '2008-11-30'
and sales_update.salesid = (select sales.salesid from sales 
where sales.salesid = sales_update.salesid
and sales.listid = sales_update.listid
and sales_update.qtysold !=sales.qtysold
or sales_update.pricepaid !=sales.pricepaid);
```

```sql
insert into stagesales
select su.salesid,su.listid,.......su.saletime
from sales_update.su left join sales on su.salesid = sales.saleid
where sales.salesid is null

-- sales_updateの2つ目の処理で、salesidを変更している。もし異なれば、
-- nullになっているはず。
--つまり、新たな情報をstagesalesに加えている。
```

ここまでのstagesalesの状態

更新された2008年11月30日以降のデータと、追加データのみが入っている。

```sql
--更新予定のsalesidを元テーブルから消す
delete from sales
using stagesales
where sales.salesid = stagesales.salesid
and sales.listid = stagesales.listid
and sales.saletime > '2008-11-30'

--insert
--これには新しいデータしか入っていない
insert into sales
select * from stagesales;
```

ステージングテーブルを作成することで、

最新テーブルへの結合が可能となる。
classpathなどを使わずAndroidにOSS Licenses Gradle Pluginを組み込む方法

コピペです。

https://github.com/google/play-services-plugins/issues/223#issuecomment-1236159132

https://stackoverflow.com/a/77404419


```kotlin:settings.gradle.kts
pluginManagement {
    repositories {
        google {
            content {
                includeGroupByRegex("com\\.android.*")
                includeGroupByRegex("com\\.google.*")
                includeGroupByRegex("androidx.*")
            }
        }
        mavenCentral()
        gradlePluginPortal()
    }
    // 追加
    resolutionStrategy {
        eachPlugin {
            if (requested.id.id == "com.google.android.gms.oss-licenses-plugin") {
                useModule("com.google.android.gms:oss-licenses-plugin:${requested.version}")
            }
        }
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

rootProject.name = "AppName"
include(":app")

```


```toml:libs.versions.toml
[versions]

ossLicensesPlugin = "0.10.5"
ossLicense = "17.0.1"

[libraries]
oss-licenses = { group = "com.google.android.gms", name = "play-services-oss-licenses", version.ref = "ossLicense" }


[plugins]
oss-licenses-plugin = { id = "com.google.android.gms.oss-licenses-plugin", version.ref = "ossLicensesPlugin" }
```

```kotlin:build.gradle.kts(Root)
plugins {
    alias(libs.plugins.oss.licenses.plugin) apply false
}

```

```kotlin:build.gradle.kts(:app)
plugins {
    alias(libs.plugins.oss.licenses.plugin)
}


dependencies {
    implementation(libs.oss.licenses)
}

```

styleを設定しないとライセンス表示時にクラッシュする。

```xml:AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application>

        <!-- 追加 -->
        <activity android:name="com.google.android.gms.oss.licenses.OssLicensesMenuActivity"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
        <activity android:name="com.google.android.gms.oss.licenses.OssLicensesActivity"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
    </application>

</manifest>
```

# Jetpack Composeでの使い方

```kotlin
val context = LocalContext.current
Button(onClick = {
    context.startActivity(Intent(context, OssLicensesMenuActivity::class.java))
}) {
    Text("Click")
}
```
serviceとsystemctl、結局どちらを使えばいいのか？

#### 結論
- `systemctl`を使うべき

#### 理由
- 誤解を恐れずに言えば、`systemctl`は`service`の後継であり上位互換
- `systemctl`の方が高性能
- `service`しか使えない環境以外であれば、積極的に`systemctl`を使うべき
UnityのSwitch Platform忘れを検出するEditor拡張つくった！

# UnityのSwitch Platform忘れを検出するEditor拡張つくった！

visionOSにSwitch Platformするのを忘れて、Play to Deviceで事故るのはもう嫌なので、アクティブなPlatformを監視してvisionOSじゃなかったらエラー出力するツールを作りました！

ついでにvisionOS以外にも対応しました！

OpenUPMで公開しているので、誰でも利用できますー


# Platform Watcher

https://openupm.com/packages/com.segur.platform-watcher/

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/ee925592-ac92-957e-ea1f-27be2d1df1be.png" />


# どんなツールなの？

このツールは、UnityのPlatformが指定されたものでない場合にエラーを表示します。

たとえば、WebGLアプリ開発用のUnityプロジェクトを複数人で開発していて、メンバーの一人がPlatformをWebGLに切り替えないまま作業を進めてしまい、謎のビルドエラーに遭遇してトラブルシューティングに多くの時間を費やした経験はありませんか？

このツールを使えば、Switch Platformを忘れていたらエラーが表示されるので、すぐに気づくことができます！

ぜひお試しください！


# 動作環境

Unity 2019.4 以上


# インストール方法

## Node.jsでインストールする場合

Node.jsがインストール済みのPCの場合は、以下のコマンドでパッケージをインストールできます。

```bash
# openupm-cli をインストール
npm install -g openupm-cli

# Unityプロジェクトへ移動
cd YOUR_UNITY_PROJECT_DIR

# Platform Watcherをインストール
openupm add com.segur.platform-watcher
```

## Package Managerでインストールする場合

Unity標準のPackage Managerでインストールしたい場合は、Scoped Registryの登録作業が必要になります。

手順は以下のページが詳しいので、ご参照ください！

https://zenn.dev/shiena/articles/unity-openupm

Scoped Registryの登録ができたら、Package Managerから `com.segur.platform-watcher` というパッケージをインストールしてください。


# 使い方

## Platform Watcherを開く
`Tools > Platform Watcher` を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/1d40853c-1c8a-7439-d777-7520854ebd1d.png)

すると、以下のようなウィンドウが現れます。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/de01c48e-77f3-1ea7-c385-1b5a0eaf9bc1.png" />

## 好きなPlatformを選択する

`Unknown` となっている箇所をクリックし、お好みのPlatformを選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/76972470-c991-f167-eda4-73439e5fa86b.png)

たとえば、 `Vision OS` を選択すると以下のようになります。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/ee925592-ac92-957e-ea1f-27be2d1df1be.png" />

## Platformが間違っていないか監視する

- もし、アクティブなPlatformが `Vision OS` **だったら**、エラーメッセージは表示されません。
- もし、アクティブなPlatformが `Vision OS` **ではなかったら** 、エラーメッセージが表示されます。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/38978f86-a582-2d0a-e484-d8993fd277a2.png" />


# 複数Platform対応

複数のPlatformを選択できます。

たとえば、iOSとAndroidを同時に選択すると以下のようになります。

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/88f257f2-686e-a46a-3f27-877fe606b03f.png" />


# 設定ファイル

どのPlatformを選択しているのか？という情報は `ProjectSettings` フォルダー配下の `PlatformWatcherSetting.json` というファイルに保存されます。

![PlatformWatcherSetting.json](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/352cf5af-5863-ee2f-4507-49cae395d556.png)


この設定ファイルをGit等で共有すれば、複数人でUnityプロジェクトを開発している場合でも、設定を共有できます！


# さいごに

本記ツール開発にあたり、以下のページを参考にさせていただきました。ありがとうございました。

- https://bta25fun.wixsite.com/modev/post/2019/12/19/エディタ拡張で配列変数の入力欄を出すには
- https://zenn.dev/shiena/articles/unity-openupm
〜家庭内DX〜　バーコードリーダーの作成

# 〜家庭内DX〜　バーコードリーダーの作成

26卒予定のしがない学生エンジニアです。この記事では、日常のDX化としてちょっとしたバーコードリーダーを作成したので、ご紹介します。
リポジトリは以下に公開してますが、4時間程度で作ったものなので、クオリティは低いです。
https://github.com/ei-sugimoto/barcodeScan

## 背景
　大学院のオンライン授業を受けたあと、昼飯を食べつつ母親の愚痴を聞く、というのが日課になっていました。ある時に、バーコードの写真を消すを見たのでなぜ消しているのか尋ねると、「箱のバーコードを読み取るのが面倒」とのことでした。

　母は配達業をしており、配達終了時にバーコードを会社の端末で読み取るのですが、配達用の箱が大きいので、事前に自分の携帯で写真を撮って、それを読み取っていました。しかし、毎回バーコードの写真を消すのが大変でした。母親のフォルダがバーコードの写真ばかりになり、icloudの容量がなくなる未来を危惧した私は、早速バーコードを読み取るwebアプリを作成しようと思いました。

 ## 要件
 - バーコード(code128)を読み取る
 - 読み取ったバーコードからバーコードを新たに生成する
 - 箱は1つじゃないので、複数のバーコードを読み取れるようにする
 - iphoneのタブを削除されれば、初期化される

 ## 技術選定
 - 言語
    javascript
 - フレームワーク
    react.js
 - OSS
     - quaggaJS
     - jsbarcode

 - Hosting
     - github pages
### フローチャート

   <img  width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779682/c39e40d3-8a5a-3e36-28d8-d7895ddd5cb7.png" />

### 動作画像

![スクリーンショット 2024-05-21 17.07.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3779682/be9f0651-ffef-3085-0672-0c4970e19bb0.png)

### 終わりに
バーコードを扱ったことがなかったので、とても新鮮でした。バーコードの種類を特定するのが、一番難しいまでありました。ぜひ、日常のちょっとしたこともDXしていきましょう〜
生成AIで未経験からエンジニアになる難易度が急上昇！

生成AIの登場によって、IT業界の様々な分野に大きな影響を与えつつあります。特に新たにIT業界を目指す方にとっては、大きな障壁となる可能性があります。なぜなら**生成AIによって、初心者エンジニアがやるようなプログラミング業務を奪ってしまう可能性**があるからです。

そこで、生成AIがIT業界に与える影響とプログラミング学習について解説します。またIT業界への新規参入を目指す方へ向けて、具体的な学習方法や将来の展望についても紹介します。


<iframe width="560" height="315" src="https://www.youtube.com/embed/bJmLR4xUWgo?si=xAVOjppDuvmH3sRV" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## ChatGPTなどの生成AIにより新規ITエンジニアの仕事が奪われる？

![AI-makes-it-more-difficult-for-inexperienced-engineers-to-change-jobs.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784196/c3a8bc15-6137-5a91-86c9-8ac60e3dbf61.jpeg)


私はChatGPTなどの生成AIの登場により、**未経験からエンジニアとなることが、これからの時代はどんどん難しくなっていく**のではないかと考えています。その理由として、以下のようなことが生成AIにより学ぶ機会を奪われるためです。
- 簡単なコーディング経験が得られなくなる
- エラー修正やデバッグの経験が乏しくなる
- コーディングの思考プロセスが理解しづらくなる
- ポートフォリオ作成の機会が失われる

生成AIにより入門者向けのコーディングが代行されると、**初心者エンジニアが実践を通して経験を積む機会が失われ、プログラミングの基礎的な能力の育成が阻害**されかねません。またこれまでプログラミングの入り口として使われてきたものが、AIを使えばできてしまうので未経験からエンジニアになる際は**より高いスキルを証明**する必要があります。

## プログラミング学習は不要となるのか？

![Will-learning-to-program-be-unnecessary.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784196/475f79e2-1834-2e47-32d8-f1a1fc71768f.jpeg)


上記で生成AIなどの新しいAI技術の発達により、一部のコーディング作業はAIに代替されることについて説明してきました。ではこれからの時代、プログラミング学習は不要となるでしょうか？私はそれでも、プログラミングスキルが不要になることはないと考えています。むしろ逆で、**よりプログラミング学習が必要**だと考えています。私がそのように考える理由は、以下の3点です。

- エンジニアにはコーディング以外の仕事も複数ある
- AIの登場でよりエンジニアの仕事が増える
- AIを使いこなすためにはプログラミングの知識が必要不可欠

[>> 「なぜより必要なのか？」詳しくはココから！](https://taishi-official.com/2024/04/16/2149/#toc3)

## 新しくITエンジニアとなりたい方へのアドバイス

![Advice-to-new-and-aspiring-IT-engineers.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784196/23bb5ee4-09f4-70cf-0c3e-d0f63d3a9ccd.jpeg)


これまでで未経験からITエンジニアになるのが、生成AIによってどんどん難しくなってきている理由についてご説明してきました。ただこれからもITエンジニア不足が続くため、需要がある業界です。

またAIによって、これまでの想像以上に伸びることが想定される業界でもあります。そこで現役でエンジニアしている私から、これからIT業界を目指したい方に向けて、以下についてアドバイスしたいと思います。

- できるだけ早くIT業界に参入する
- 生成AIの活用方法について学ぶ

[>> アドバイスの詳細はコチラを確認！](https://taishi-official.com/2024/04/16/2149/#toc7)

## まとめ
今回は生成AIによって、未経験からエンジニアを目指す方にどのような影響があるかについて考察してみました。これから生成AIによるプログラミングは、どんどん発展していくことが予想されます。それによって**未経験からエンジニアになる場合に求められるスキルレベルが上がり、時間が経てば経つほどエンジニアになることが難しくなる可能性**があります。そのためエンジニアの仕事に興味があるのであれば、なるべく早めに行動を始めましょう。

ただこれまでAIの恐ろしい面ばかりお伝えしましたが、AIによってITエンジニアの仕事はより増えると思われます。おそらくこれまで以上に、ITエンジニアは需要が高い仕事となっていきます。ここで**AIの使い方を学び、うまく協調することで他のエンジニアと差別化できる可能性**もあります。**ピンチはチャンス**と言いますし、ぜひITエンジニアを目指してみてはいかがでしょうか？

### おまけ

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

[>> プログラミング未経験からエンジニアになるための3STEP学習法](https://taishi-official.com/learning-programming/)

<br>

<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
- 
- note：https://note.com/taishi_wii_be/

<br>

最後に良かったら「いいね」お願いします:thumbsup:
Azure DevOpsで、PBIのStateに関してForecastingとCycle Timeとで不整合があるのではないか

[前の記事](https://qiita.com/24zaki/items/aec5ac105eccb660b5c2)でPBIのStateとCycle Timeについて書いて満足していたところ、プロジェクトでスクラムマスターからForecastingが誤っていると連絡がありました。

調べてみたところ、Forecastingで現在実施中（予測対象外）とするためには、Iteration Pathを設定するだけではだめで、StateをIn Progressカテゴリ（Scrumテンプレートの場合、Committedが定義されている）に進めないといけないらしいです。すなわち、**計画時**にIn Progressカテゴリに進めろということです。

しかし、前記事で書いたとおり、Cycle Timeを求めるためにはIn Progressカテゴリに進めるのは**着手時**にする必要があり、この２つの間で不整合が生じてしまいます。

今のところ解決策はありませんが、思いついてやってみたのは、

1. In Progressカテゴリ中にStateを2つ設ける（仮にIn Progressとします）
2. Ruleで、StateがIn Progressになったとき、現在日時をどこかの項目に格納する
3. Cycle TimeはDashboardウィジェットを使うのではなく、クエリでこの日付とClosed Dateを出力し、Excelなど外部で時間差を求めて算出する

です。
いつの間にかVSCodeのC++のsyntax highlightがraw string literalの中のSQLのsyntax highlightに対応してた話

# 現象

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94177/9566972d-455f-07d4-a1f5-08dfc92fce9e.png)


図のように、明らかにC++のコードの中にraw string literal(生文字列リテラル)でSQLを書いたら、SQLとしてsyntax highlightされた。

# なにを手がかりにsyntax highlighしているか

生文字列リテラルは、以下の構文を持つ：

```
encoding-prefix R"d-char-sequence opt (r-char-sequence opt) d-char-sequence opt"
```

https://cpprefjp.github.io/lang/cpp11/raw_string_literals.html

ためしにd-char-sequenceを`SQL`以外にしたらこう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94177/eb326edc-7447-c633-112d-03fbb08c76d0.png)


どうもd-char-sequenceを手がかりにしているらしい。

# じゃあ他の言語は？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94177/5a9d1e31-ad20-38b3-0a5e-3bed6f403229.png)


markdown, json, luaなどわんちゃんC++のraw string literalに書きそうな言語を試したが対応指定なさそうだった。SQLだけ特別扱いなのかな。

# 環境

```
バージョン: 1.89.1 (user setup)
コミット: dc96b837cf6bb4af9cd736aa3af08cf8279f7685
日付: 2024-05-07T05:13:33.891Z
Electron: 28.2.8
ElectronBuildId: 27744544
Chromium: 120.0.6099.291
Node.js: 18.18.2
V8: 12.0.267.19-electron.0
OS: Windows_NT x64 10.0.22631
```

ms-vscode.cpptools: v1.20.5
何も考えず最速でMySQLをインストールする

## サクっと軽くMySQLが使いたくなったときのために

### 手順
1. インストール
    ```bash
    sudo apt update
    sudo apt install mysql-server-8.0 -y
    ```
1. 起動
    ```bash
    sudo systemctl start mysql
    ```
1. 自動起動を設定
    ```bash
    sudo systemctl enable mysql
    ```
1. MySQLへログイン
    ```bash
    sudo mysql -u root
    ```

以上
アプリ・Webサイトを生成AIのVisilyを使ってデザインする

## 大枠のデザインをAIに作成してもらう話

今回は個人開発する上でデザインが必要になってきたので
大枠をAIに任せた話したいと思います。アプリのイメージを湧かせてから、
それをデザインに落とし込むのは時間がかかります。
そこで今回、デザインのAIツール「Visily」を使ってみたので
選んだ理由・使用方法・使った感想について話していきます。

:::note info
私の場合はアプリデザインを作成しましたが、Webデザインも作成することが可能です。
:::


## Visilyとは？

Visilyは、スクリーンショット、手書きイメージ、テキストプロンプトを
編集可能なワイヤーフレームおよびプロトタイプに迅速に変換する
AIワイヤーフレームツールです。

https://www.visily.ai/

## 話す内容

- [Visilyを選んだ理由](#visilyを選んだ理由)
- [使用方法](#スクリーンショットからデザインを作成する方法)
- [使ってみた感想・まとめ](#使ってみた感想まとめ)

### Visilyを選んだ理由 #

-  **無料で使用できる**
    - まずは無料で試せるのが良い点です。
    AIツールは有料のものが多く、試してみるまでに敷居が高いことがあります。
    Visilyは無料で使用でき、直感的に操作できます。
 　
- **スクリーンショットからデザインを組むことができる**
  - 作りたいアプリのデザインがなかなか思い浮かばない時があります。
   そんな時は、既存のアプリからデザインイメージをスクリーンショットして
   Visilyに渡せば、似たようなデザインを生成してくれます。
  (完全に一緒のデザインは生成されません)
　
- **手書きのデザインイメージ画像をVisilyに渡すと自動でデザインが組まれる**
  - Figmaなどのデザインツールを上手に使いこなすには学習コストがかかります。
  しかし、Visilyを使えば手書きのイメージを
  デザインとしてアウトプットすることができます。
   　
  - 直感的にデザインのイメージを描き、あとはVisilyに任せて、
  残りの細かいところを手動で修正するといった使い方ができます。
　
-  **今後はText to Designに対応予定**
    - 現段階ではText to Designには対応していませんが、近日公開予定のようです。
    Text to Designが公開されたら、スクリーンショットや手書きの
    イメージから作成したデザインを元に、テキストベースで
    デザインを修正することができます。
   例えば「ここのTabBarがしっくりこない...」と思った時に、テキストベースで修正できるとより便利になります。

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637125/6ee3d68f-1eaf-e982-b6db-f63bfc29e48f.png)

### スクリーンショットからデザインを作成する方法

- [VisilyのWebサイト](https://www.visily.ai/)にアクセスして「Get Visily Free」をタップします。

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637125/e8485437-0f0b-ff36-334f-60717094288e.png)

-  アカウントを作成してダッシュボードに移動します。
`Create project` → `Blank Project` → `Hi-fi Design`を選択します。

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637125/42fb264e-cc58-d57e-6595-850ade87d76b.png)

- 次に「Screenshot to Design」を選択して、作成したいデザインの
スクリーンショットをアップロードします。

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637125/1584da76-c555-9b1c-0f70-5c2b7ed96b11.png)

するとこのように簡単にデザインが完成します。
生成されたデザインを自分で手直しするとかなり仕上がります！

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637125/97b7c5e0-98eb-d8ce-6f2f-7712c9a9fd42.png)

### 使ってみた感想・まとめ

アプリデザインをある程度はイメージできたとしても、
具体的に「こんな感じにしたい」とイメージするのは難しいです。
そんな時はAIを使用して大枠を作成してもらうのも一つの手段だと思っています。

ある程度のクオリティーのデザインを作成できるので、
システム開発にも時間を割くことができます。
この方法でアプリ・Webのデザインを作成してみてください！

## 採用情報

最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを募集しております。詳しくは採用情報ページをご確認ください。

https://eda-inc.jp/recruit/

みなさまからのご応募をお待ちしております。
パスワードなしでSSHする

### いつも忘れるので。

#### 前提
- 以下で読み替えてください。

|項目 |値 |
|---|---|
|ユーザ名| kanno |
|サーバ名|messiah|

---
#### 手順
1. ローカルマシン上で、公開鍵と秘密鍵を作る。
    
    ```bash
    kanno@HORIZON:~$ ssh-keygen -t rsa
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/kanno/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/kanno/.ssh/id_rsa
    Your public key has been saved in /home/kanno/.ssh/id_rsa.pub
    The key fingerprint is:
    SHA256:tTP9FC9XKhhUA+tOOfzqk8r6Q6Bz3cBtFiruaLkS0pk kanno@HORIZON
    The key's randomart image is:
    +---[RSA 3072]----+
    |          ooo    |
    |         ... .   |
    |       . o+.  . .|
    |      o +++*   +.|
    | . o o +S=@ o + o|
    |. E o o oo.= + o |
    | . . * .  ... .  |
    |  . + ... o.     |
    |   o...o++o.     |
    +----[SHA256]-----+
    kanno@HORIZON:~$
    ```
1. 公開鍵と秘密鍵が作られていることを確認する。
    ```bash
    kanno@HORIZON:~$ ls ~/.ssh
    合計 28
    drwx------  2 kanno kanno 4096  5月 20 17:23 .
    drwxr-x--- 11 kanno kanno 4096  2月 18  2023 ..
    -rw-------  1 kanno kanno 2602  5月 21 16:10 id_rsa
    -rw-------  1 kanno kanno  567  5月 21 16:10 id_rsa.pub
    -rw-------  1 kanno kanno 4196  5月 20 17:53 known_hosts
    kanno@HORIZON:~$
    ```
    
1. 公開鍵をサーバへ登録する。
    ```bash
    kanno@HORIZON:~$ ssh-copy-id -i ~/.ssh/id_rsa.pub kanno@messiah
    /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/kanno/.ssh/id_rsa.pub"
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
    kanno@messiah's password:
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'kanno@messiah'"
    and check to make sure that only the key(s) you wanted were added.
    
    kanno@HORIZON:~$
    ```
1. 秘密鍵を使って、パスワードなしでSSHする接続する。
    ```bash
    kanno@HORIZON:~$ ssh -i ./.ssh/id_rsa kanno@messiah
    Welcome to Ubuntu 24.04 LTS (GNU/Linux 6.8.0-31-generic x86_64)
    
     * Documentation:  https://help.ubuntu.com
     * Management:     https://landscape.canonical.com
     * Support:        https://ubuntu.com/pro
    
    Expanded Security Maintenance for Applicationsが無効化されています。
    
    0のアップデートはすぐに適用されます。
    
    ESM Appsを有効化すると、さらに追加のセキュリティアップデートを適用できます。
    https://ubuntu.com/esm を参照するか、次のコマンドを実行してください： sudo pro status
    
    Last login: Tue May 21 16:06:58 2024 from 192.168.100.20
    kanno@messiah:~$
    ```

以上。
未経験でエンジニアとして入社し、１ヶ月経ったので振り返る

初めまして。
2024年に入社し、晴れてエンジニアとしてキャリアをスタートしました。
早くも入社から1ヶ月が経ったということで、これまでの学習内容を振り返えるとともに、IT初心者におすすめの参考書や勉強法を紹介できればと思います。

# プログラミング学習で使用した教材
研修では、主に『プロになるJava』を使用していました。

## 『プロになるJava』
![プロJava.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772948/034b8f6b-6719-3321-28a7-bb4474e8559e.jpeg "プロになるJava")

>『プロになるJava』は、プログラミングを仕事にしたい、エンジニアとして働きたい方、およびほかの言語で開発しているがJavaも使えるようになりたいという方を対象に、Javaでプログラミングができるようになるための解説をわかりやすく丁寧に行います。
>(技術評論社 書籍概要より) https://gihyo.jp/book/2022/978-4-297-12685-8
### 良かったポイント
**・ハンズオン形式で、処理を実行しながら進めていける**
実際にJshellやIntelliJIDEAを動かしながら取り組むことで、プログラムの仕組みがイメージしやすかったです。

**・要所要所に練習問題があるため、理解度の確認ができる**
自分の苦手としているポイントを洗い出すことができました。
## 『スッキリわかるJava入門』 
![スッキリわかる.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772948/e8abc5f0-f1c5-c8c1-523d-561dd5c4a696.jpeg "スッキリわかるJava 入門")
>『スッキリわかるJava入門』は、基礎からオブジェクト指向まで、「なぜ？」が必ずわかる解説と、約300点の豊富なイラストで、スッキリマスターできる大人気Java入門書
>(インプレスブックス 書籍概要より) https://book.impress.co.jp/books/1119101083
### 良かったポイント
**・初心者でも理解しやすいよう、イラストや図を使って詳細に解説がされている**
図が載っているおかげで、まずイメージを掴むことができました。

**・プログラミング用語や重要部分が赤太字で強調され、1つずつ丁寧に説明されている**
『プロになるJava』で躓いていた部分も、この参考書と並行して取り組むことで、頭に入ってきやすかったです。
さらに、ストーリー性もあるので、楽しく学ぶことができました！

とはいえ、私はIT未経験なので、プログラムを書いたことは一度もありませんし、それ以前にIT用語から全く分かりません。
この状態でのJavaの習得は非常に難しかったです。

# 今回のプログラミング学習で詰まってしまったポイント
**・文法が分からないため、1つ1つ意味を調べながら取り組まなければならなかった**
例) 以下はJavaを実行するために必要なメソッドですが、これも最初は1つ1つ単語の意味を調べていました。
　　　　　　　　　【 public static void main(String[] args){ 】

**・コードだけが書かれていると、イメージがつかみにくい**
例) if文はフローチャートにすれば分かりやすいのですが、コードだけで書かれていると、ifのみの構文だけでなく、else-ifやelseという構文も出てくるため、頭が混乱しました。

# 今回のプログラミング学習で学んだこと
**・１回の学習ですべてを理解できなくても落ち込む必要はない**

**・分からないときは調べることも大事ですが、飛ばしてみることも大事！**

１回で完全に理解しようとするのではなく、あえて分からないところを飛ばしながら進め、何度も繰り返すことで理解を深められることもあります。

# 最後に
未経験からの挑戦でまだまだ不安も多いですが、日々成長できるよう、今後も頑張っていきたいと思います。
Next.jsのPage RouterとApp Routerの違いを解説

Next.jsはReactをベースにしたフレームワークで、効率的な開発をサポートするために多くの機能を提供しています。
その中でもルーティングは重要な機能の一つです。
Next.jsには大きく分けてPage RouterとApp Routerの二つのルーティング方法が存在します。
本記事ではそれぞれの特徴と使い方について詳しく解説し、例も交えて説明します。

## Page Routerとは？

Page RouterはNext.jsの初期バージョンから存在する、ファイルベースのルーティング方法です。

### 特徴

1. **ファイルベースのルーティング:**
   - `pages`ディレクトリ内にファイルを配置することで、自動的にルートが生成されます。
   - 例えば、`pages/about.js`を作成すると、`/about`というルートが自動的に設定されます。

2. **シンプルなルーティング:**
   - 特定のURLに対するページの作成が簡単で、特に設定ファイルを必要としません。
   - 動的ルーティングもファイル名に`[id].js`のように書くことで実現します。

3. **限定された柔軟性:**
   - 基本的なルーティング機能には十分ですが、複雑なルーティングロジックを持つアプリケーションには制限があります。

### 例

**静的ルーティング:**

```javascript
// pages/index.js
export default function Home() {
  return <h1>Home Page</h1>;
}

// pages/about.js
export default function About() {
  return <h1>About Page</h1>;
}
```

**動的ルーティング:**

```javascript
// pages/posts/[id].js
import { useRouter } from 'next/router';

export default function Post() {
  const router = useRouter();
  const { id } = router.query;

  return <h1>Post: {id}</h1>;
}
```

## App Routerとは？

App RouterはNext.jsの新しいバージョンから導入された、プログラム的ルーティング方法です。より柔軟で高度なルーティングが可能です。

### 特徴

1. **プログラム的ルーティング:**
   - コードでルートを定義するため、柔軟なルーティングが可能です。
   - `next/router`モジュールを使用してルーティングを制御します。

2. **動的ルーティングの柔軟性:**
   - 動的にルートを生成したり、条件に基づいてルートを切り替えたりすることが容易です。
   - 例えば、クエリパラメータや状態に基づいてルートを変更することができます。

3. **複雑なアプリケーション向け:**
   - 大規模なアプリケーションや複雑なルーティングロジックが必要な場合に適しています。
   - カスタムミドルウェアやルートガードなど、高度なルーティング機能を実装可能です。

### ディレクトリ構成

App Routerでは、特定のディレクトリ構造を守る必要があります。通常、`app`ディレクトリ内にコンポーネントやルートを定義し、各ディレクトリには`page.jsx`または`page.js`ファイルが含まれます。このファイルが実際のページコンポーネントとなります。

**ディレクトリ構成例:**

```
my-next-app/
├── app/
│   ├── layout.js
│   ├── page.jsx
│   ├── about/
│   │   └── page.jsx
│   ├── dashboard/
│   │   ├── layout.js
│   │   └── page.jsx
│   └── posts/
│       ├── [id]/
│       │   └── page.jsx
│       └── page.jsx
├── public/
├── styles/
├── next.config.js
└── package.json
```

### 例

**基本ページコンポーネント:**

```javascript
// app/page.jsx
export default function HomePage() {
  return <h1>Home Page</h1>;
}
```

**ネストされたページとレイアウト:**

```javascript
// app/about/page.jsx
export default function AboutPage() {
  return <h1>About Page</h1>;
}

// app/dashboard/layout.js
export default function DashboardLayout({ children }) {
  return (
    <div>
      <nav>Dashboard Navigation</nav>
      <main>{children}</main>
    </div>
  );
}

// app/dashboard/page.jsx
export default function DashboardPage() {
  return <h1>Dashboard Page</h1>;
}
```

**動的ルーティング:**

```javascript
// app/posts/[id]/page.jsx
import { useRouter } from 'next/router';

export default function PostPage() {
  const router = useRouter();
  const { id } = router.query;

  return <h1>Post: {id}</h1>;
}
```

### まとめ

Next.jsのPage RouterとApp Routerは、それぞれ異なる利点を持っています。アプリケーションの規模や要件に応じて、適切なルーティング方法を選択することが重要です。

- **Page Router:** シンプルで直感的。小規模アプリケーションや静的ページに最適。
- **App Router:** 高度なルーティングが可能。大規模で複雑なアプリケーションに適しています。

ディレクトリ構成の違いや使い方を理解し、自分のプロジェクトに最適なルーティング方法を見つけて、Next.jsでの開発をさらにスムーズに進めましょう。
外部キーreferencesを使ったRailsモデルの関連付け

# references型とは

Ruby on Rails のマイグレーションで使われるデータ型の一つで、
他のモデルへの関連付け（リレーションシップ）を表すために使用されます。


# 使用例
例えば、コメント（Comment）が投稿（Post）に属しているという関係を設定したい場合、以下のようなマイグレーションを生成します。
```ruby:
rails generate migration Comment Post:references
```

これにより生成されるマイグレーションファイルには、`post_id`カラムを `posts` テーブルに追加するコードが含まれます。さらに、`post_id` カラムには外部キー制約とインデックスが設定されます。


# 生成後(models) belongs_to
コマンド入力後、models配下のcomment.rbに以下のコードが生成されます。
単数形であることに注意
`belongs_to :モデル名(単数形)`


```ruby
class Comment < ApplicationRecord
  belongs_to :post
end
```


### belongs_toとは
モデル間の関連付けを定義するためのメソッド。
あるモデルが他のモデルに「属している」(belong to)ことを示します。


# マイグレーションファイルもチェック
```ruby
class CreateAnswers < ActiveRecord::Migration[7.0]
  def change
    create_table :answers do |t|
      t.string :name
      t.text :content
      t.references :question, null: false, foreign_key: true

      t.timestamps
    end
  end
end
```
`t.references`
answersモデルと紐づきがある事を示している

`null: false`
カラムがnullになることを禁止
このオプションを適用することで、そのカラムには必ず値が入力される必要があり、データベースをからに references型とは

Ruby on Rails のマイグレーションで使われるデータ型の一つで、
他のモデルへの関連付け（リレーションシップ）を表すために使用されます。


# 使用例
例えば、コメント（Comment）が投稿（Post）に属しているという関係を設定したい場合、以下のようなマイグレーションを生成します。
```ruby:
rails generate migration Comment Post:references
```

これにより生成されるマイグレーションファイルには、`post_id`カラムを `posts` テーブルに追加するコードが含まれます。さらに、`post_id` カラムには外部キー制約とインデックスが設定されます。


# 生成後(models) belongs_to
コマンド入力後、models配下のcomment.rbに以下のコードが生成されます。

```ruby
class Comment < ApplicationRecord
  belongs_to :post
end
```


### belongs_toとは
モデル間の関連付けを定義するためのメソッド。
あるモデルが他のモデルに「属している」(belong to)ことを示します。


# マイグレーションファイルもチェック
```ruby
class CreateAnswers < ActiveRecord::Migration[7.0]
  def change
    create_table :answers do |t|
      t.string :name
      t.text :content
      t.references :question, null: false, foreign_key: true

      t.timestamps
    end
  end
end
```
`t.references`
answersモデルと紐づきがある事を示している
<br>

`null: false`
カラムがnullになることを禁止
このオプションを適用することで、そのカラムには必ず値が入力される必要があり、データベースを空のままにするのを防ぎます。
<br>

`foreign_key: true`
外部キー制約のオプションを有効にしている
このオプションを適用することで、親テーブルに対象が存在しない場合、子テーブルの保存ができない設定。
Discord.js v14 botの作り方【基礎・ワークスペース作成編】 (2024/5/21現在)

# Discord.js とは
Discord.js (以下d.js) とは、discordのbotを開発するときに使用するパッケージの1つです。
同様に、Discord.pyというものがあります。これはpythonで開発する場合のパッケージになります。
詳しくは[こちら](https://qiita.com/minoru_kinugasa/items/e1bdee4ca016b2a38e2c)をごらんください！

# ワークスペースとは
ワークスペースとは、簡単に言うとBotのプログラムのごちゃごちゃをまとめるフォルダのことです。
フォルダを作成するだけではなく、パッケージのインストールなどいくつかやることがあるので頑張ってください！

また、僕はMacbookで作業しますが、Windowsの方もやることは同じです！

# ディレクトリの作成
ディレクトリ...? なにそれおいしいの って人向けに説明するつもりなので、分かる人は飛ばし飛ばしでも大丈夫です！
|手順|説明|備考|
|---|---|---|
|1|`エクスプローラー`または`Finder`を開きます。 (以下Finder)||
|2|フォルダを置いておきたい場所 (特にない人はデスクトップ) に移動します。|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/46485a45-17b2-740f-7bba-fbbf1d3227d3.png)|
|3|Finderの中で右クリックをし、「**新規フォルダ**」をクリックします。|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/d100238e-e836-1d6c-4441-2aef49de73f4.png)|
|4|フォルダに名前をつけます。スペースは含めないほうが良いです。|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/cea23adf-f825-03f7-1ad5-44580ff9bed8.png)|
|5|フォルダのパスというものをコピーします。Windowsの場合は`Ctrl + Shift + C`、Macの場合は`Option + Command + C`を押すとフォルダのパスがコピーされます。||
|6|ターミナルまたはコマンドプロンプトを開きます。 (以下ターミナル)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/d80d9ac0-a282-1c8e-9222-375fa49e3773.png)|
|7|ターミナルに`cd [ここにペースト]`と入力します。[ここにペースト]のところには、先程コピーしたフォルダのパスを入力します。| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/b4862fd4-4dcf-da79-4f36-11f9bc869202.png)|
|8|このコマンドを実行すると、ターミナルがフォルダにアクセスします。実行するために`Enter`を押します。||
|9|同様に、ターミナルで`npm init -y`と入力し、`Enter`を押して実行します。|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/8ac13b41-b735-aebb-143c-b1429d7ad8c9.png)|
|10|同様に、ターミナルで`npm i discord.js`と入力し、`Enter`を押して実行します。 (処理に多少時間がかかります。) |![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/62ff14f0-0745-06e2-cf84-7d12f485bfc7.png)|
|11|同様に、ターミナルでWindowsの方は`type nul > index.js`、Macの方は`touch index.js`と入力し、`Enter`を押して実行します。|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/9ff8e8d4-08df-66d8-f91b-444043d69ed0.png)|
|12|一度Finderに戻って、いろいろなフォルダとファイルが追加されていたら成功です！|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794632/a2c38d9f-6bd8-47ba-e1b8-fdc18c9720b4.png)|

# 終わりに
 お疲れさまでした！
これで、botを開発するワークスペース、プログラムコードを記入するファイルなどの準備ができました！

次は[動作確認編](https://qiita.com/minoru_kinugasa/items/64b333f43abdb61d7ef8)になります！
botの動作確認、テスト起動をしますのでぜひごらんください！
tmux で copy mode で kill lineとかすると "server exited unexpectedly" でいきなり死ぬ

[homebrew](https://brew.sh/)でいれた tmux の依存が壊れたのか copy mode に入ってコピーとかキルラインしようとすると "[server exited unexpectedly]" ってでてそのまま死んでしまう問題が発生。 tmux を reinstall したらなおった。

```sh
brew reinstall reattach-to-user-namespace
brew reinstall tmux
```
Git diffを用いた納品差分ファイルの作成方法を解説

gitを用いてソース運用を行っていく中で、とある地点から変更があったものだけを抽出して納品したい場合、git diffコマンド有効的です。

本記事では、git diff コマンドを用いた差分ファイル作成方法を詳しく解説します。

```
git archive コミットID `git diff --name-only 新しいコミットID 古いコミットID --diff-filter=d` -o ファイル名.zip
```

このgitコマンドでは、古いコミットID から 新しいコミットID までの差分（変更点）を抽出し、zipファイルで保存するコマンドです。

git archiveコマンドは、指定されたコミット、ブランチ、ツリーなどのGit Refからアーカイブファイルを作成します。

--diff-filter=dは、コミット間で削除されたファイルを除外するコマンドです。これがないと、削除したファイルも差分ファイルとして格納されて、削除したいのに間違ってサーバーにアップロードしてしまった、なんてことが発生します。

もし先方側でファイルをFTPなどで直接アップデートするような運用方法の場合、納品ファイルと共にdeleteするファイルも一緒に共有するようにしてください。

ちなみにdiff-filter=dをdiff-filter=Dと大文字にすることで、削除されたファイル**のみ**が抽出されます。これは--diff-filter=R（リネームされたファイル）や--diff-filter=A（追加されたファイル）も同様です。

-oは出力ファイルを示すために使用されます。saveNameのところは、保存したいファイル名を入力します。

たとえば、コミットID:0000000000とコミットID:1111111111間の取得して20250401納品分というファイル名でzip形式で保存したい場合、以下のようなコマンドになります。

```
git archive 0000000000 `git diff --name-only 1111111111 0000000000 --diff-filter=d` -o 20250401納品分.zip
```
InteliJ 修正候補表示 フィールドを埋めてくれる便利機能

testのフィールドを埋めるのに役立つ
知ってるのと知らないのとだと倍以上作業速度に差が出るのでメモっておく。


## Mac
opt + Enter
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684145/cdb2921b-7b95-5b5a-713d-3d72cb568a0c.png)
> すべてのフィールドを埋めるを選択

## Windows
Alt + Enter
データ連携ヒアリングシート

データ連携処理作成時にヒアリングする必要がある内容を自分なりにまとめてみました

主なデータ取り込みワークロード
- リレーショナルデータベースからテーブルオブジェクトを連携
- システムからRest API等のWeb API経由でファイルを連携
- ファイルサーバからSMBプロトコルなどでファイルを連携

上記のWeb API経由の場合は以下に加えてAPIの仕様についての追加のヒアリングを行う必要がある認識。後日まとめる予定。
○機能要件
- データソース/データシンク
    - データソース(シンク)システム名
    - データの責任者
    - データの種類(テーブル,view,ファイルの場合は拡張子)
    - ファイル名、テーブル名
    - スキーマまたはディレクトリ
    - 文字コード(テキストファイルの場合)
    - 区切り文字(","、"tab"など)
    - ヘッダ有無
    - データ種別(tran or master)
    - 連携対象の期間
    - 1回あたりのデータ連携サイズ
    - 1回あたりのデータ連携件数
    - 過去データの移行要否
    - 過去データ移行の場合はデータサイズ、件数
    - データソース(シンク)システム名のIPアドレスまたはFQDN
    - データ取得(連携)に利用するアカウント情報
    - 論理削除データの有無と扱い
- データ連携方式
    - データ連携方式(プル/プッシュ/ポーリング)
    - データ連携プトロコル
    - データ連携に利用するネットワーク(パブリック/プライベート)
    - 連携頻度
    - データ連携タイミング(指定の時間、またはデータ連携NGの時間)
    - データクレンジング要件の要否
    - データ加工要件の要否
    - ウォーターマークの有無
○非機能要件
    - 目標完了時間
    - 通知要件の有無
      - 開始
      - 成功
      - 失敗
      - その他
    - エラーハンドリングに利用する製品の指定の有無
    - 実行ログの保存要件有無
Laser Dental Treatment: Advanced Solutions for Precision Care | Dentistium

Laser Dental Treatment is a cutting-edge dental solution designed to address various aesthetic and functional concerns, ultimately giving you a stunning and healthy smile. With a customized treatment plan tailored to your individual needs, Laser Dental Treatment can effectively correct issues such as chipped, stained, or misaligned teeth. By improving your bite alignment, this advanced procedure enhances your ability to chew and speak comfortably. With our experienced dental team and the use of top-quality materials and advanced techniques, Laser Dental Treatment ensures long-lasting and remarkable results for your dental needs. Visit our site at https://dentistium.in/laser-dentistry/.
DeepL API FREEを使ってみて感想やらなんやら書いてみる

# 前書き
経済系の学部4年生で、ITコンサルから内定をいただいております一般大学生です。
卒論でニューラルネットを使ってみたく、先行研究を探していたらあまりにも英語の文献が多くて(~~めんどくさいなあ~~)大変だなと思っていました。そんな時にDeepLがAPIを無料で出していることを知り、試してみました。備忘録もかねて、感想と実装方法を記載しておこうと思います。



※**私は開発経験もなく、実証分析でしかプログラミングを触ったことがないため、厳密性に欠く文章かもしれません。使えればいいやくらいの発想で書いています。誤植などが万一ありましたら、遠慮なくご指摘いただけますと幸いです。**


# アジェンダ
1. DeeoLAPIとは
2. 実装
3. 感想
4. 参照



# 1. DeepLAPIとは
ドイツのDeepL社が提供しているサービスである。
https://www.deepl.com/ja/pro-api/?utm_term=&utm_campaign=JP%7CSearch%7CC%7CDSA%7CJapanese&utm_source=adwords&utm_medium=ppc&hsa_acc=1083354268&hsa_cam=20381500983&hsa_grp=152346290158&hsa_ad=666361149583&hsa_src=g&hsa_tgt=dsa-2177221505955&hsa_kw=&hsa_mt=&hsa_net=adwords&hsa_ver=3&gad_source=1&gclid=Cj0KCQjw6auyBhDzARIsALIo6v_Qlb4bTiCnPTzn_3MFvHYVnDY9gpojlizx_aAoQLNDWfAvLqd6nfUaAhXeEALw_wcB

主に使える機能は文書の翻訳(txt,docx,pdfなど)を行えるらしい。無料版では月間で500,000文字までらしいが、やる気のない学生はそんなに読まないと思うので私は無料版にしています。有料でも月630円らしいので、足りなくなったら足してみてもいいんじゃないかと思います。なお、自動でプランが切り替わる訳では無いそうなのでご留意いただきたい。

登録に際して本人名義のクレジットカードが必要なので、持ってない人はてきとうにカードを作っておきましょう。
# 2. 実装
本コードはGoogle Colaboratoryを用いた場合のコードです。ほかの環境を用いている場合は、適宜変更してみてください。

* 前準備0：グーグルアカウントの取得(アカウントを持っていない人向け)
* 前準備1：ファイルをアップロードしておく
* 前準備2：APIキーを取得しておく
    * 取得方法：deepl > アカウント > APIキー > APIキーの取得

```translate.py
!pip install --upgrade deepl #ライブラリのインストール(済んでいる場合は不要)
import deepl

translator = deepl.Translator("自身のAPIキー")
translator.translate_document_from_filepath(
    "Stern-NeuralNetworksApplied-1996.pdf",  #翻訳したいファイル…(1)
    "translateja.pdf", #出力されるファイル名
    source_lang='EN', #(1)で書かれている言語
    target_lang="JA" #出力したい言語
)
```

コードを実行し、正常に処理が終わっていればColaboratoryのファイルフォルダを確認すると出力ファイルが入ってます。
ちなみに、利用状況はAPIキー取得の2つとなりから確認できます。
![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3415165/b3fcf1b1-5703-3991-3074-83a96a8fbafd.png)



# 3. 感想
結論から記すと、見やすく使うには改良が必要かもしれないです。私の場合はpdfをそのまま入れてしまったので、次の画像のようになってしまいました。
![IMG_6924.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3415165/e491aee7-2e76-e490-d3db-fc5ff7da4e69.jpeg)

フォントの指定ができるか検証していないが、文字の大きさだとか細かい部分はまだまだ改める必要がありそうです。取り急ぎ自動化してみたいという人にとっては向いているのかもしれません？



#4. 参照

本記事・実装のために下記の資料を用いました。
https://qiita.com/Ryoyu1117/items/4bad3ac015adcec41b53
https://www.jstor.org/stable/1270601
pumaがソケット通信で起動してくれなかった原因

railsのプロジェクトをnginx経由で接続できるようにするにあたって、ソケット通信で起動しようとしてもなぜかbindの設定がうまく機能してくれなかった

gemのソースを辿って原因が見つかったのと、調べている中で同じような問題に直面して質問している人が少しいたのでメモとして残しておく

# 結論
`ENV['HOST']`に値が設定されていると、`rails server`コマンドで起動した際に、`config/puma.rb`で設定したソケットのbind設定は上書きされてしまい機能しなくなる
そのため、`ENV['HOST']`の設定を削除するか、`bundle exec puma`で起動するとソケットのbind設定が機能する

# 概要

```ruby:puma.rb
socket = Rails.root.join('tmp/sockets/puma.sock')
bind "unix://#{socket}"
```
nginxとのソケット通信のために、上記の設定を入れていたが、railsのサーバーを起動すると
```
* Listening on unix:///work/tmp/sockets/puma.sock
```
となってほしいはずが
```
* Listening on http://0.0.0.0:3000
```
だけが表示されてソケット通信ができていなかった

原因についてもう少し書くと、`ENV['HOST']`が設定されている場合、rails serverで起動する際にRack::Server::initializeの引数に以下のようなパラメータが渡ってしまう
```
"{:user_supplied_options=>[:Host], :server=>nil, :log_stdout=>false, :Port=>3000,
:Host=>\"0.0.0.0\", :DoNotReverseLookup=>true, :config=>\"config.ru\", 
:environment=>\"production\", :daemonize=>false, 
:pid=>\"/work/tmp/pids/server.pid\",:caching=>nil, 
:restart_cmd=>\"bin/rails server  --restart\", :early_hints=>nil}"
```

`:user_supplied_options=>[:Host]`が存在するためにその後の、Puma::Configuration::initializeにHostのパラメータがuser_optionsとして渡されてしまう
```
{:Host=>"0.0.0.0"}
```

これによって、`config/puma.rb`から読み込まれた設定である`file_options`とは別に、`user_options`から作成された設定にbindsキーが、pumaに渡される設定として同時に存在する状態になってしまった
```
 @file_options={:min_threads=>5, :max_threads=>5, :binds=>["unix:///work/tmp/sockets/puma.sock"], :environment=>"production", :pidfile=>"tmp/pids/server.pid"},
 @user_options=
  {:Host=>"0.0.0.0",
   :binds=>["tcp://0.0.0.0:3000"],
```

pumaは`config/puma.rb`ファイルから読み込んだ設定であるfile_optionsよりも、user_optionsとして渡されたパラメータを後にmergeしたものを最終的な設定とするようなっていたため、file_optionsのbindsの設定が上書きされてしまっていた

+ https://github.com/puma/puma/blob/master/lib/puma/configuration.rb#L86
```
    def final_options
      default_options
        .merge(file_options)
        .merge(user_options)
    end
```

`ENV['HOST']`を削除することで、`:user_supplied_options=>[]`になるので、user_optionsが空の配列`{}`になり、無事`config/puma.rb`の設定が上書きされずに適用されるようになった
```
"{:user_supplied_options=>[], :server=>nil, :log_stdout=>false, :Port=>3000,
:Host=>\"0.0.0.0\", :DoNotReverseLookup=>true, :config=>\"config.ru\", 
:environment=>\"production\", :daemonize=>false,
:pid=>\"/work/tmp/pids/server.pid\", :caching=>nil,
:restart_cmd=>\"bin/rails server  --restart\", :early_hints=>nil}"
```
html,cssのレビュー観点

■ 全体 タグ構成

・ ヘッダー
   headerタグ
・ ナビゲーション
   naviタグ
・ h1
   これを含むタグはdiv
・ 見出し
    sectionタグ
・ フッター
   footerタグ


■ 余白について
マージン上下統一がされているか。


■ テキストがはいるタグ
divなどブロック要素にならないように注意する。
p, span , strongなど


■ 画像タグ

・imgタグ
 loading="lazy" ついているか。  → ファーストビュー以外にはつける。
 width, height属性ついているか。

・ スマホとpcで画像が変わる場合
pictureタグを検討する。

・ heightの指定
 上下paddingなどで調整

height固定にすると文章が長くなった時にHTMLだけでなくCSSのheight値も調整しなくてはいけないので、heightは固定にせず、上下のpaddingなどで高さを調整するほうがよいです

■ グリッド形式の表示 
display: grid;を検討する。

display: grid;
grid-template-columns: repeat(3, 1fr); // 3 = 3列
gap: 縦方向余白 横方向余白;

■ スマホとPCでタグ構成がかわる場合

flexなどで変更できるか検討する。
・flexのorderで順番を指定したり
・ gridのgrid-template-areasで名前を付けて場所を管理するなど

https://zenn.dev/kagan/articles/4f96a97aadfcb8#%E3%82%A8%E3%83%AA%E3%82%A2%E3%81%AB%E5%90%8D%E5%89%8D%E3%82%92%E4%BB%98%E3%81%91%E3%82%8B-grid-template-areas-%E3%81%A8-grid-area


■ 
左画像、右テキストのボックスの場合は 左画像上がいい
            display: flex;
            flex-direction: start;
            align-items: flex-start;