OmniAICreator/Qiita-1.07M huggingface dataset:
hsqldbのjar起動メモ

### ダウンロード・起動

https://sourceforge.net/projects/hsqldb/files/

https://www.tutorialspoint.com/hsqldb/hsqldb_installation.htm

1. Download Latest Versionをクリックしてダウンロード
1. 適当な場所に解凍
1. コマンドプロンプトを開いて解凍したディレクトリに移動
1. ↓を実行
```winbatch
java -classpath lib/hsqldb.jar org.hsqldb.server.Server --database.0
file:hsqldb/demodb --dbname.0 testdb
```

実行結果
```
[Server@4ee285c6]: Startup sequence initiated from main() method
[Server@4ee285c6]: Could not load properties from file
[Server@4ee285c6]: Using cli/default properties only
[Server@4ee285c6]: Initiating startup sequence...
[Server@4ee285c6]: Server socket opened successfully in 7 ms.
[Server@4ee285c6]: Database [index=0, id=0, db=file:testDB, alias=testdb] opened successfully in 405 ms.
[Server@4ee285c6]: Startup sequence completed in 441 ms.
[Server@4ee285c6]: 2023-06-25 09:59:28.321 HSQLDB server 2.7.2 is online on port 9001
[Server@4ee285c6]: To close normally, connect and execute SHUTDOWN SQL
[Server@4ee285c6]: From command line, use [Ctrl]+[C] to abort abruptly
```

----
### マネージャーを開く
1. binディレクトリのrunManagerSwing.batを実行
1. 下記のように設定してok
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2713217/1a3d25e3-5655-6d50-156a-e599d3766410.png)

### 適当なテーブル作成
https://www.tutorialspoint.com/hsqldb/hsqldb_create_table.htm
1. 下記SQLを貼り付けてExecuteSQLを押す
```SQL
CREATE TABLE tutorials_tbl (
   id INT NOT NULL,
   title VARCHAR(50) NOT NULL,
   author VARCHAR(20) NOT NULL,
   submission_date DATE,
   PRIMARY KEY (id) 
);
```

### 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2713217/7bc4c60c-bf4a-10c6-2418-1073963c54fc.png)

### CRUDのサンプル
Command → TestScript をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2713217/f77d874a-679a-cfdd-6f6e-849a84128a7f.png)
強化学習で上昇気流を捉える7

# 背景
[前回](https://qiita.com/goichiya/items/09ba0aa9241d71dd0af2)からの続き
改良したツールを使って実際にデータを取得し、教師あり学習を考える

# 作りたいもの
- 飛行の状態を音声で知らせてくれる
- サーマルをサーマルを捕まえ続けるように進行方向を教えてくれる

# ハードウェア

![2022_12_09 16_17 Office Lensおしゃべりバリオ (3).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328600/98bcb848-012f-774e-d79b-e733f94fdc7f.jpeg)

UPSを導入して電源を内蔵するように変更。1時間強ぐらいは持つので足元は十分

- https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-5XHW

GPSはUSB接続のまま。いずれは内蔵したい
- https://amzn.to/3NLJVNX

接続するためのHubも一筋縄では行かなかった 
- https://amzn.to/3NMmPH1

ラズパイの新規調達が依然として厳しい、、

# ソフトウェア
Pythonでガリガリと書いてゆく！変化なし！

# データ収集結果
ログの中に重複した情報を整理する必要があるものの、なりで記録すると1秒に1回記録されている


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328600/a7a181c1-1af9-b8d9-897d-c3893f2019ac.png)

## データの解像度は足りるか？
時速30kmで飛行している場合、秒速8メートル強なので5秒間で42メートル進むことになる。この時点で進行方向を喋り始める（イメージは「右30度」とか「左60度」とか喋らせたい）とさらに1秒後ぐらいになる。
この場合、5秒間分の説明変数で6秒後の進路を予測するモデルが必要
強化学習だと現在の状態に5秒後のアクションを設定して報酬を計算する感じか？
一旦、個人的に対応しやすい教示あり学習で精度が出るかやってみようと思う

# この後
- 自前デバイスで取得したログを使用して学習を行い精度を確認する
- 製品のバリオから取得したログ（データの解像度が高い）を使用して学習を行い精度を確認する
- 強化学習で解く方法を検討する
ブラウザゲームを作ってみよう(その15:サンプルゲーム作成その8)

# はじめに
[その14](https://qiita.com/noji505/items/)ではサウンド再生を行いました。


# ローディングについて
サウンドファイルを追加したことで読み込むファイルが増えたため、起動前にファイルのローディング処理を行いたいと思います。
イメージとしては以下になります。
![img01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/740996/d43e4de3-20e9-3b6c-4aab-0b826b8600ac.png)

ファイルの読み込みを全て完了するとタイトル画面へ遷移するというイメージになります。

# 読み込み完了のチェックについて

読み込むファイルは画像ファイルとサウンドファイルですが、それぞれ読み込み完了のチェック方法が少し異なります。

* 画像ファイル
読み込みが完了すると、onloadメソッドが実行されるのでそれの実行回数をカウントすれば可能です。

* サウンドファイル
再生可能になると「readyState」プロパティが「4」になるのでそれをカウントすれば可能です。

具体的なソースは下記になります。

```javascript:読み込み完了チェック

// ローディング用変数
let loadingFileCnt;
const loadingFileMax;

loadingFileCnt = 0;
loadingFileMax = imgNames.length + sndNames.length;

// ローディング画面ループ
function loadingLoop()
{
    let i;

    // 画像ファイル読み込み完了数カウント
    for( i=0; i<img.length; i++ ){
        img[i].onload = function() {
            loadingFileCnt++;
        }
    }

    // サウンドファイル読み込み完了数カウント
    for( i=0; i<audioObject.length; i++ ){
        if( audioObject[i].readyState == 4 && !isAudioLoad[i] ){
            loadingFileCnt++;
            isAudioLoad[i] = true;
        }
    }

    drawText( "ファイルロード中 "+loadingFileCnt+" / "+loadingFileMax+"", 0, 0, '#000000', 12, TEXT_HCENTER | TEXT_VCENTER );

    if( loadingFileCnt >= loadingFileMax ){
        titleInit();
    }
}
```

■ポイント
* 画像ファイルとサウンドファイルのファイル総数を変数「loadingFileMax」に保存しておきます
* 画像ファイルの読み込み数は前述のonloadメソッドでカウントします
* サウンドファイルの読み込み数は「readyState=4」でカウントするのですが、一度だけカウントしたいためisAudioLoad変数も合わせてチェック、更新します
* 読み込んだファイル数(loadingFileCnt)が、読み込みファイル総数(loadingFileMax)に達したらタイトル画面へ遷移します

# サンプル
今までのサンプルにローディング処理を追加しました。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="eYMPJbM" data-user="noji505" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/noji505/pen/eYMPJbM">
  Qiita26_sample01</a> by nojima (<a href="https://codepen.io/noji505">@noji505</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# 最後に
今回はローディング処理を追加しました。
こういう汎用的な処理は、一度作成しておくと他のゲームでも使い回せるので便利です。
UnityHDRPでTerrain Sample Assetsのディディールがピンク色の時の対処法 覚書

最近UNITY 2022 LTS発表されましたね！
早速新機能を使って遊んでみたいなと思いHDRPでUnityのTerrain Toolを使いながらいろいろ試していたところ
Terrain Sample Asset Packのディディールがピンク色？紫色？になっちゃう問題が発生し、解決したのでその覚書として残すことにしました。

参考；
・UNITY 2022 LTS　；https://unity.com/ja/releases/lts

・公式動画

https://www.youtube.com/watch?v=ZIb2-mV8Q_s


以下使用したパッケージ
・Terrain Tools　5.0.3 
パッケージマネージャーのUnityレジストリからインストール
・Terrain Sample Asset Pack
https://assetstore.unity.com/packages/3d/environments/landscapes/terrain-sample-asset-pack-145808?locale=ja-JP


早速ディティール機能を使ってわーい！って草をはやしたところ・・・。
あれなんか紫じゃない？ってなりました、確かにこんな色の植物や花とか見たことあるような、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490437/321b16a9-2461-6532-9c5c-36740060e1e8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490437/d240588b-cab5-23f3-73e9-ecc3620676cb.png)
でも違和感あるしなんかおかしい！！ということで
Assets＞TerrainSampleAssets＞Prefabsの中にある植物のインスペクターを見てみます。

するとマテリアル設定のHDRP Only中に何やら英語が書いてあり、
[Diffusion Profile（拡散プロファイル？）というのがうまく参照されていないからFixボタンを押して修正しろ]という感じの意味でした。
![スクリーンショット 2023-06-25 184602.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490437/eea692f3-46b6-c67a-7399-a12c42d56c25.jpeg)

なので押したらなんと！うまくプロファイルが参照されてピンク色問題を解決できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490437/5580cbee-0a75-118c-1c40-e3a116e50399.png)
シーンに戻ってみるとちゃんとした草っぽくなっていました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490437/8f0badbc-2ec9-fe25-a59d-aba86f6d3a3b.png)

自分はまだまだ未熟なのでよくわからず触っていますが同じ現象で困っている方がいたら少しでも参考になれば幸いです！それではまた
地方企業のDXを進めていく中で大切な考え方


## はじめに
この記事では、私が**地方企業のDX**を進めていく中で経験した以下内容を共有します。
DX化していく中で、同じ壁に当たっている方の解決策になれば幸いです。

1. 地方DX案件に入って悩んだこと
2. チームリーダからのアドバイス
3. DXを進めていく上で大切なこと

:::note info
あくまで、個人の見解をまとめたものです。
主語が大きく当てはまらないことも多いかと思いますので、サラッと読んでいただけますと幸いです。
:::

## 読んでほしい人
- 地方企業のDX化推進を行っているエンジニア
- DXを進めていく中でユーザに使ってもらえるか悩んでいる人

## 前提


### 案件の内容
- kintoneを使用して業務用アプリケーションを作成しています。
- kintone側で補えない処理は、javascriptで処理を追加

### クライアント様の背景
- クライアント様は昔ながらの会社で、40〜50代メインのメンバーが多い。
- DX化のフェーズ：情報管理を紙からデータへ移行する段階。


## 本題

### 1.悩み
DXを全く知らない私が当たった**悩み**を2つ挙げます：
1. ユーザー様は我々の提供する**システム**を使ってくれるのか？
2. 従業員の方は本当に**DXを必要**としているのか？

### 2.アドバイス
上記の悩みをリーダーに相談したところ、以下のような**アドバイス**をいただきました
- DXとはデジタルでトランスフォーム（改革）すること
- 人間は**変化を恐れる生き物**であるため、急に変化を強いるのは難しい
- DX化のメリットを伝え、**変化への不安を払拭すること**が私たちの役割
- そのメリットを信じてもらうためには、今は目の前のことを愚直にやり切り、**結果を出し続けること**
- そしてクライアントからの**信頼**を得ることが大切

![スクリーンショット 2023-06-24 14.11.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2712488/88e7de44-2540-5f91-9508-f090f5288477.png)


### 私の解釈と考え方
このアドバイスを受けて、以下のような考え方に至りました：
- DX化を進めいくためには、クライアント様との**信頼関係を構築すること**が非常に大切。
- 信頼を得るためにはまずは、成果を出すことを意識する。
- コテ先の行動をするだけでは、信頼は得られない。（DXは進まない）

## 従業員さんの気持ちを考えてみました
- 現状の業務、手作業でスムーズにやれているから、**無駄を感じていない**、すなわち変える気がない時。
- **外からきたエンジニアがとやかく言うのは**、すぐには受け入れられないし、受け入れたくないかもしれない。
- ただ、信頼している人から提案されたことなら多少なりとも、受け入れてくれるかもしれない。


## 私生活での無駄を想像してみてください
- 自分がいつも行っているルーティンの私生活の中に**無駄**がありますでしょうか？
- もし、大きな無駄があればすでに**改善**していますよね。
- 現状行っている、ルーティン作業は**意外と改善**されてますよね。
- そんな無駄がない生活に突如、「これ絶対効率化に繋がるので試してみてください！」と急に知らない人から言われたらどうでしょうか。
- すぐに受け入れるでしょうか。え？って大半の人がなりますよね。。。

## 反対に
- 提案してくれた人が、**親友**・**家族**だとどうでしょうか？
ちょっとやってみようかな？試してみようかな？となると思います。
- 本当にその商品が良くても、**使いにくい**・**カッコ悪い**どこの会社が作ったものかわからないときはどうでしょうか。

## 大切なこと
- ここで大切なのことは、**誰が言うか**・**誰が提供しているか**なのです。
- 本当に良いものを作っても、**使われなかったら意味がありません。**
- サービスを使われるようになるため（DX化推進する）には、**使いやすさ**、**機能**だけでなく、**信頼**も必要ということがわかりました。


## まとめ
我々のDX推進活動は、単に技術的な課題を解決するだけでなく、**信頼関係を築き**、**ユーザーに価値を理解**してもらうことが大切です。
そのためにはまず、目の前の仕事に集中し、成果を出すことが必要です。
**コテ先の行動・その場しのぎの行動**をするのではなく、**本気でユーザに向き合い続け、本当の価値**を届けていきたいと思います！！

最後まで読んでいただきありがとうございました！！！！！！！
【SwiftUI】VStackやHStackに11個以上のViewを置く方法

SwiftUIのVStackやHStackなどにはViewを11個以上置こうとするとエラーになり、最大１０個までしかViewを配置することができないため、11個以上置く方法を紹介します。

# Groupを使用してViewをグループ化する
![スクリーンショット 2023-06-25 17.48.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663839/2916cebb-c52a-cdd2-08e4-e4288a8f1364.png)

GroupがView１個として数えられるため、Groupの中にさらにViewを最大10個まで配置できるようになります。

VStackやHStackも同様にViewを1つとして配置できます。
![スクリーンショット 2023-06-25 17.54.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663839/90439797-269f-4e13-42e5-32860c8dfa23.png)

# ForEachを使用する
ForEachもView１個として配置できます。
ただ、ForEachも同様にForEach内には最大10個までしかViewを並べることができません。

![スクリーンショット 2023-06-25 18.01.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663839/42bbba23-535b-bd4c-a763-6233cc84851a.png)

# 最後に
VStackやHStack以外にFormなどのViewも最大10個までの制限になっています。

Twitterもやっていますので、是非フォローお願いします！！
https://twitter.com/yama__0106
【SwiftUI】ドラッグアイテムの形を変える方法

# はじめに
ドラッグアイテムの形を変える方法を紹介します。

# 作るもの
カプセル型のドラッグアイテムを作ります。
![00_05.34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/326c32dc-88f6-f971-2e4e-07417f8acbad.jpeg)

# やり方
ドラッグアイテムの形を変えるには、contentShapeの第一引数に .dragPreview、第二引数に形を指定します。

```swift
struct ContentView: View {
    @State private var text = ""

    var body: some View {
        VStack {
            Text("Hello, world!")
                .padding()
                .contentShape(.dragPreview, Capsule())
                .onDrag {
                    NSItemProvider(object: "Hello, world!" as NSString)
                }
            
            Divider()
                .padding(.horizontal)

            TextEditor(text: $text)
        }
    }
}
```

# まとめ
contentShapeを使うと、ドラッグアイテムの形を変えることができます。カプセルの他にも、円や四角形など、様々な形を指定することができます。

# 参考文献
https://developer.apple.com/documentation/swiftui/view/contentshape(_:_:eofill:)

https://developer.apple.com/documentation/swiftui/contentshapekinds/dragpreview
Raspberry Pi Pico (RP2040)でシリアルポートが消える！

## TL;DR

Arduinoで適当なスケッチを書いて転送するとおそらく復活します。別に復活させなくても、シリアルポートをちゃんと使うようにプログラムされたファームを書けば復活します。なので、なくなったからと言って慌てずに。

## なにが起きたの？

みなさん大好きなRaspberry Pi Picoであります。安い・速いってことで、いろんなところで使われているのではないでしょうか。GPIOの数もたくさんあるし、互換ボードもたくさん出てるし、XIAOなんていう極小のボードもあるし。そんなわけで私も買ってあそんでみました。

開発環境には複数あって、

* RP2040 SDK
* Micro Python
* Arduino (PlatformIO)

などが使えますね。マイコンのプログラミングをPythonでやれるなんて、すごい話です。

それはさておき、RP40のSDKを使って下記のようなコードを書きました。

``` main.c
void main() { }
```

これをビルドしてボードにコピーすると。なんと！シリアルポートが消えるのです！

## えっ？！どうすんの？

ということで、こんなふうに修正してみました。

``` main.c
#include <stdio.h>
#include "pico/stdio.h"
#include "pico/stdlib.h"

int main()
{
  stdio_init_all();
}
```

ようするに、標準出力を初期化してみたわけですね。ところが、これでもまだシリアルポートは復活しません。

どうやら、プログラムが終了しちゃうといけないようです。ということで、下記のようにします。

```
#include <stdio.h>
#include "pico/stdio.h"
#include "pico/stdlib.h"

int main()
{
  stdio_init_all();
  for(;;) ;
}
```

無事にシリアルポートは復活しました。

## 最後に

ということで、普通にちゃんとシリアルポートを使うようになっているプログラムでは、シリアルポートは消えません。ひょっとしたら、PanicでCPUが停止するとシリアルポートは消えるのかもしれませんね。つまり、シリアルポートが意図せずに消えているのならば、おそらくファームウェアのプログラミングに問題があるのでしょう。
Target [App\Xxx\Yyy\ZzzInterface] is not instantiable. エラーが出た時の対処法

## エラーメッセージ

```
Target [App\Xxx\Yyy\ZzzInterface] is not instantiable.
```

![ScreenShot 2023-06-25 18.29.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/9fd70e70-ca4b-df88-3641-e41cb8024f36.png)

## 問題のコード

```php:app/Providers/AppServiceProvider.php
<?php

declare(strict_types=1);

namespace App\Providers;

use App\Aws\CognitoIdentityProvider\AdminCreateUser\AdminCreateUser;
use App\Aws\CognitoIdentityProvider\AdminCreateUser\AwsAdminCreateUser;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;

final class AppServiceProvider extends ServiceProvider implements DeferrableProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {
        $this->app->bind(AdminCreateUser::class, AwsAdminCreateUser::class);
    }
}
```

## 修正したコード

```php:app/Providers/AppServiceProvider.php
    /**
     * @return string[]
     */
    public function provides(): array
    {
        return [
            AdminCreateUser::class,
        ];
    }
```

`DeferrableProvider` と契約して遅延ロードさせた場合は `provides()` に対象のインターフェースを記述する必要があります。

## 認識しない場合

それでも認識しない場合はキャッシュクリアとオートローダーの再生成をお試しください。

```shell-session
$ php artisan optimize:clear
$ composer dump-autoload
```

## まとめ

- サービスプロバイダーが作成されていない
- `config/app.php` にサービスプロバイダーが登録されていない
- `DeferrableProvider` と契約している場合は `provides()` にインターフェースを登録
- キャッシュクリアする
Hexabase TypeScript SDKを使ってデータストアのデータを取得する

[Hexabase（ヘキサベース）](https://www.hexabase.com/)は企業においても安心して利用できるBaaS（Backend as a Service）を提供しています。多くのBaaSがそうであるように、主にフロントエンド開発者に利用してもらいたいと考えています。そこで現在、TypeScript SDKの開発が進められています。

この記事ではHexabase TypeScript SDKのインストールと、データストアからデータを取得し、そのデータにある値を取得する方法を紹介します。

## インストール

インストールはnpmやyarnを使って行います。

```
# npmの場合
npm install @hexabase/hexabase-js

# yarnの場合
yarn add @hexabase/hexabase-js

```

## インポート

インポートすると、 `HexabaseClient` というオブジェクトが取得できます。

```jsx
import { HexabaseClient } from "@hexabase/hexabase-js";
```

## 初期化

HexabaseClientを初期化します。

```jsx
const client = new HexabaseClient();
```

### 認証

Hexabaseでは業務利用を想定しているため、利用する際に認証情報が必須になります。最初はメールアドレスとパスワードで認証し、その後はトークンを使ってGraphQLにアクセスします。 `client` を使って処理します。

初回の認証は次のようになります。emailとパスワード、またはトークンが必須です。

```jsx
await client.login({email, password, token});
```

後はこの `client` に対して処理を行います。

## データストアへのアクセス時に必要な情報について

データストアへアクセスする際には以下の情報が必要です。

- データストアID `datastoreId`
- プロジェクトID `projectId`

さらにデータ取得を行う際の情報（ページ数、取得件数など） `params` が指定できます。以下がアクセス例です。

```jsx
const project = client.currentWorkspace.project(projectId);
const datastore = project.datastore(datastoreId);
const items = await datastore.items();
const item = items[0];
```

## データを取得する

データを取得する際には `get` メソッドを使ってください。型を指定できます。

```jsx
item.get('Title'); // as any
item.get<string>('Title'); // as string
```

## デフォルト値を指定する

もし値がなかった時のために、デフォルト値を指定できます。

```jsx
item.get<string>('Title', 'Hello'); // -> Titleの値がなかったらHello
```

## 指定できる型

Hexabaseで利用できる型は以下の通りです。

- string
文字列
- number
数値
- Date
日付
- FileObject[]
添付ファイル
- User[]
ユーザー
- Item
関連アイテム

## まとめ

データストアはクラウドデータベースとして、様々な型をサポートしたテーブルが利用できます。ぜひ皆さんのWebアプリケーションで利用してください。Hexabase TypeScript SDKを使えば、VueやReactなどと連携したWebアプリを素早く開発できるようになります。

2023年05月現在絶賛開発を進めていますので、ぜひ試していただいてフィードバックいただければ嬉しいです！

[hexabase/hexabase-js](https://github.com/hexabase/hexabase-js)
ダブリング

## はじめに
ダブリングを理解するために記事を書きました:grin:
間違っていたらごめんなさい:pray_tone1:
競プロでの活用を目的としています:hibiscus:


## ダブリング を使う時

グラフで自分の位置から、x個前の親が誰なのか知りたいよ〜な時など:mag_right:
（私が直面し、学ぶきっかけとなった内容です）
他にもあります・・・

## どんな感じ？

愚直でやると、一つ一つ階段を登っていく感じだけど、ダブリング活用すると2段抜かし、4段抜かしみたいに登る段の回数が少なくて済むよ〜:dancer_tone1:

電車で例えると、
愚直・・・・・・・→　:mountain_railway:　普通電車　各駅止まりますよ〜
ダブリング・・→　:monorail:　特急電車　飛ばす飛ばす時々止まる

## やる事

##### ① 準備・前計算：参照用のテーブル作り　:pick:

##### ② 参照用のテーブル(parent)を利用して、欲しい値を得る:gem:

## 具体例見ながら考えよう！
例）参考を見ながら自分で作ってみたグラフと参照用のテーブル

こんなグラフで考えてみる:mag:
![ダブリング用練習グラフ.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133248/854cf4be-dbfc-8555-1066-b947bf43ba43.png)

##### ① 準備・前計算：参照用のテーブル作り　:pick:
自分の表の前行や他列を参照して、1個前、2個前，4個前・・・を見るような表を作っていく

##### ＊ 2次元配列を作る:confetti_ball:
`parent[][]`・・・`parent[親等・深さ][自分・頂点]`

  ↓  
##### ＊ 0行目：各頂点(v)の親を入れる:family_mmb:
`parent[0][v] = 親`　根の親は-1 

![ダブリング表一行目だけ.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133248/38097fb2-d5c7-0b51-6004-0e2c050e64ff.png)

  ↓  

##### ＊ 1行目以降`ｋ`行目：`parent[k][v]` ←自分:santa:
・同じ列である頂点(v)のk-1行目(表のk行目の1つ上)の値を見る :point_up:
`pv = parent[k-1][v]` 
・その値の頂点(pv)のk-1行目の値を見る:apple:
`xv = parent[k-1][pv]`
・その値の頂点(xv)を自分の所の値として入れる:santa::apple:ﾊﾟｸﾊﾟｸ
`parent[k][v] = xv`

これの繰り返しで表を埋めて完成！

（見えづらいので表拡大）:open_hands:
`parent[k][v]`を埋めたい！埋める値を見つけるよ！:cactus:
![ダブリング表拡大.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133248/d81002d4-b523-e02b-f5e0-01d5c9c7531a.png)

（全体の表）:open_hands:
![ダブリング用練習表数式有.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133248/9e43e4eb-70e8-7f8d-bf64-6d2c7c40f75d.png)




##### ② 参照用のテーブル(parent)を利用して、欲しい値を得る:gem:
自分(v)の`x`個前の親が知りたい　:airplane:
↓
`x`の2進数を求める(二進展開と表現すると知った):robot:
1のビットが立っている所を`ki`とする

↓
`ki`がある分繰り返す

頂点(v)の `ki`行目を見る
`pi = parent[ki][v]`

`pi = parent[ki][pi]`　←　複数ある場合
↓
頂点(pi)の,0行目(xp)を見ると、自分(v)の`x`個前の親(xp)が求まる
`xp = parent[0][pi]`
:gem:
例）
![ダブリング活用グラフ.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133248/92e0758b-c00e-23ba-618e-fab155ce12a1.png)

（表拡大）:open_hands:
![ダ拡大表.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133248/82a07b95-5be8-e71a-f8b6-f62b4009e7db.png)

（表全体）:night_with_stars:
![ダ訂正表全体.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133248/6fd5a281-e621-8448-9df4-99ee9c1fd308.png)


愚直にやると知りたい親の頂点まで一つ一つ数えて遡っていかなければならないけど、このようにダブリングでやると、二進展開した時の立ってる1の数の個数分遡るだけでよくなるので計算量が減らせる:sparkles:

ちなみに、ダブリングが2回に対して、愚直にやると9回遷移が必要
:rabbit2::rabbit2:　　　　　　　:baby_chick::baby_chick::baby_chick::baby_chick::baby_chick::baby_chick::baby_chick::baby_chick::hatched_chick:
![ダブリング愚直.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133248/382bb4ff-f196-64e5-e3cd-012f08bbad59.png)



## 
## おわり　:snowman:
読んでくださりありがとうございます。

問題の中の一部に対して、解説を読みながら調べて学んでいたので、コードは省略します。

こちらで学ばせていただきました

https://satanic0258.hatenablog.com/entry/2017/02/23/222647

satanic0258さんありがとうございました:smile:
未経験エンジニアが使うchatGPTの怖さ

初めまして、yusukeです！

現在、ITベンチャー企業でWEBシステムの運用保守をしています。
私が働いている企業には多数の未経験エンジニアがいます。その中で、chatGPTの利用によって怖さを感じた出来事がありました。

chatGPTの回答を根拠にした結果、あるコマンドに誤りがあるという問題が発生しました。実際にはコマンド自体に誤りがあり、また、実行しなくてもよい内容でした。しかし、chatGPTが選択した回答は、コマンド自体に誤りがあることにのみ焦点を当てたものでした。私が「何が誤っているのか」と聞くと、chatGPTの回答画面が表示されました。この経験から、chatGPTの回答に対する不信感を抱くようになりました。

chatGPTは、私たちが前提とする事柄や意味を理解することができず、単に回答を提供するだけです。しかも、他の未経験エンジニアも同様の問題に遭遇しました。

- chatGPTを相談相手として使用する場合、AIは私たちが前提とする状況を理解することができず、回答を提供するだけです。
- 相談相手としては、AIは解釈する必要があります。

エンジニアの経験の有無によって、chatGPTの利用方法に違いがあります。

- 経験豊富なエンジニアは、自分の設計や考えに基づいてchatGPTを使用します。
- 一方、未経験エンジニアは、chatGPTの回答に基づいて作業を行う傾向があります。

未経験エンジニアがchatGPTを頼ることは、分野に関する知識不足が原因です。AIがあるからといって、知識不足ままでいいというわけではありません。必要な知識を身につける必要があります。

時間や納期に追われて、AIが回答してくれているそれが回答だというのではエンジニアではありません。エンジニアであれば、AIが書いていることを見分ける必要があります。未経験だと知らないことが多いのは事実です。一つ一つ勉強していくことで知識がつきます。

未経験エンジニアの正しいchatGPTの使い方は、ちゃんと回答結果を検索しにいくことです。回答が正解かどうかは判断が付くほどのスキルはないと思っています。自分も判断がつかない時もあります。その時はちゃんと検索します。何が正しくて、何を持って回答してくれたのか

AIは便利ですが、使う人がいいなりでは良くなりません。知識を身につけて使うことで、ベテランエンジニアと仕事することが可能になります。

chatGPTはこう言っています。

```
AIとしての私は、多くの場合において精度の高い情報とソースコードを提供できますが、絶対に100%正確とは限りません。私のアドバイスやソースコードは多数のデータから学習した結果であり、そのデータが完全に正確であるとは限らないからです。

また、私が提供する情報やソースコードは一般的なガイドラインやベストプラクティスに基づいていますが、特定の問題や状況に対して最適とは必ずしも言えません。各ソフトウェアプロジェクトやIT問題は独自の状況や制約を持つため、私の提案が常に適切であるとは限らないのです。

したがって、私の提供するソースコードやIT知識はあくまで参考の一つとして使用し、自分自身で正確さを確認し、状況に適した変更を加えることが重要です。
```

AIがあるからと言って自分の思考を止めていいわけではありません。あなたが聞いた答えは正確ですか？
Herokuのデプロイエラー

＊初心者エンジニアが備忘録として書いております。間違いなどがあればご指摘ください。

# 発生したエラー
Herokuにデプロイして確認したところこんなエラーが。
![スクリーンショット 2023-06-25 0.13.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331271/575a5b8f-a763-22ec-fb76-523fa6403021.png)

あらま。

# 発生した原因

heroku run rails db:migrateができていなかったことが原因でした。

できなかった原因は、どうやらmigrationファイルにあったようです。

```
I, [2023-06-24T14:48:45.112150 #2]  INFO -- : Migrating to RemovePasseordFromUsers (20230624144428)
== 20230624144428 RemovePasseordFromUsers: migrating ==========================
-- remove_column(:users, :passeord, :string)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedColumn: ERROR:  column "passeord" of relation "users" does not exist
```

# 解決方法

①問題のマイグレーションファイルの中身を消す
```
class RemovePasseordFromUsers < ActiveRecord::Migration[7.0]
  def change
  end
end
```
②userモデルを作り直す
```
$ rails destroy model [モデル名]
```
新しくモデルを作り直します。
```
$ rails g model User name:string email:string password:string image_name: string
```
```
$ rails db:migrate
```
③改めてherokuにpush!
```
$ git push heroku develop:main
```
ちなみに私はfailed to push some refs to のエラーが発生したため、強制pushを行いました。↓↓
```
$ git push heroku develop:main --force
```
そして改めてherokuアプリを見たら無事解決！

# 一言
マイグレーションファイルは常に美しくあれ。（ホイホイ作り直すと後で後悔する羽目に、、、）
英語の長いドキュメントを分割加工するpart1

このパッケージでは、`NltkTool`というクラスを提供しており、Natural Language Toolkit（NLTK）の機能を利用して、テキストを文に分割、単語のトークン化、品詞のタグ付け、ステミング、およびレンマ化といった一般的な自然言語処理タスクを行うことができます。

## 依存関係
このツールはNLTKライブラリに依存しています。もしまだシステムにインストールしていない場合は、別途インストールする必要があります。pipを使用してNLTKをインストールできます：

```
pip install nltk
```

## ライブラリ本体

```python
import nltk
from nltk.tokenize import word_tokenize
from nltk import pos_tag
from nltk.stem import PorterStemmer
from nltk.stem import WordNetLemmatizer

class NltkTool:
    def __init__(self):
        nltk.download('punkt')
        nltk.download('averaged_perceptron_tagger')
        nltk.download('wordnet')
        
    def split_text(self, text):
        return nltk.sent_tokenize(text)

    def tokenize_words(self, text):
        return word_tokenize(text)

    def tag_parts_of_speech(self, text):
        words = self.tokenize_words(text)
        return pos_tag(words)

    def stem_words(self, text):
        stemmer = PorterStemmer()
        words = self.tokenize_words(text)
        return [stemmer.stem(word) for word in words]

    def lemmatize_words(self, text):
        lemmatizer = WordNetLemmatizer()
        words = self.tokenize_words(text)
        return [lemmatizer.lemmatize(word) for word in words]

```

## 使い方

まず、必要なライブラリと`NltkTool`クラスをインポートします：

```python
import nltk
from nltk.tokenize import word_tokenize
from nltk import pos_tag
from nltk.stem import PorterStemmer
from nltk.stem import WordNetLemmatizer

class NltkTool:
    # ...
```

次に、`NltkTool`クラスのインスタンスを作成します：

```python
nltk_tool = NltkTool()
```

これで`NltkTool`クラスが提供するメソッドを使って、さまざまなNLPタスクを実行できます。

### テキストを文に分割

```python
long_text = "This is a sentence. This is another one! And yet another one?"
print(nltk_tool.split_text(long_text))
```

このコードは以下の出力を得ます：

```
['This is a sentence.', 'This is another one!', 'And yet another one?']
```

### 単語のトークン化

```python
print(nltk_tool.tokenize_words(long_text))
```

このコードは以下の出力を得ます：

```
['This', 'is', 'a', 'sentence', '.', 'This', 'is', 'another', 'one', '!', 'And', 'yet', 'another', 'one', '?']
```

### 品詞のタグ付け

```python
print(nltk_tool.tag_parts_of_speech(long_text))
```

このコードは、各タプルが入力テキストの単語とその対応する品詞を含むタプルのリストを出力します。

### ステミング

```python
print(nltk_tool.stem_words(long_text))
```

このコードはステミングされた単語のリストを出力します。

### レンマ化

```python
print(nltk_tool.lemmatize_words(long_text))
```

このコードはレンマ化された単語のリストを出力します。

このツールが正常に動作するためにはNLTKライブラリが必要です。また、ツールは初期化時に必要なNLTKデータセット（'punkt', 'averaged_perceptron_tagger', 'wordnet'）をダウンロードします。これが

正常に動作するためには、環境がインターネットに接続されていることを確認してください。

## 備考

### ステミング

ステミングは、単語をその基本形に変換するプロセスです。この基本形は、多くの場合、単語の語幹または根元を表します。たとえば、「running」「runs」そして「ran」はすべて同じ語幹「run」を持つと考えられます。ステミングの目的は、単語の異なる形態を同じ形式に統一することで、テキスト解析の際に文の中で同じ語幹を持つ単語を一つのグループとして扱うことができます。ただし、ステミングは規則に基づく方法であるため、必ずしも言語学的に正確な基本形を生成するわけではありません。

### レンマ化

レンマ化もステミングと同様に、単語をその基本形に変換するプロセスですが、レンマ化はより洗練された方法を使用します。レンマ化では、単語の形態論的（つまり、形や構造）な情報と辞書を使用して、単語をその語彙的または辞書形に変換します。この結果、レンマ化は通常、言語学的に正確な基本形を生成します。たとえば、「is」「are」「am」はすべて「be」にレンマ化されます。

これらの技術は両方とも自然言語処理のタスクで広く使用されていますが、適用するべき最善の方法は、特定の問題やアプリケーションによります。ステミングは一般にシンプルで高速ですが、レンマ化はより精密な結果を提供しますが、それに伴い計算コストが高くなる場合があります。
Nexys Video のチュートリアルではまったポイントのメモ

Nexys Video で DDR3 を使ってみようとチュートリアルやってみた際にはまったポイントをメモする。
実施したチュートリアルは、[Getting Started with Microblaze](https://digilent.com/reference/nexys/nexysvideo/gsmb)である。

* Vivado の バージョン
  * 2023.1，2022.1 では、Vitis でデバッグ実行時に下記のようなエラーが出て実行できなかった。
  ```
  148: couldn't open "/usr/src/debug/libmble-libgloss/4.2.0-r0/libgloss/microblaze/crt0.S": no such 
  file or directory
  xsct% 
  ```
  * 2020.1 ではこのようなエラーがでなかった。デバッグ実行でない場合でも、正常に動作しなかった。
* MIG
  * MIG が 2023.1 ではポートが異なる。[Getting Started with Vivado and Vitis for Baremetal Software Projects](https://digilent.com/reference/programmable-logic/guides/getting-started-with-ipi)ではこの新しいポートでの接続方法に言及しているので参考にできる。sys_clk_i には、100 MHz のシステムクロックを入れて、ref_clk_i には 200 MHz の ui_addn_clk_0 を追加するとよい。sys_clk_i にクロッキングウィザードで生成した信号を入れると怒られたような気がする。
    * 参考: ["ERROR: [DRC RTRES-1] Backbone resources: 1 net(s) have CLOCK_DEDICATED_ROUTE set to BACKBONE but do not use backbone resources." in newest Vivado](https://electronics.stackexchange.com/questions/661711/error-drc-rtres-1-backbone-resources-1-nets-have-clock-dedicated-route-se#:~:text=The%20solution%20is%20add%20a%20line%20set_property%20CLOCK_DEDICATED_ROUTE,TRUE%20%5Bget_nets%20design_1_i%2Fclk_wiz_0%2Finst%2Fclk_out1%5D%20into%20the%20constraint%20file%20arty.xdc.)
  * 2020.1 の ref_clk_i がない場合だと、sys_clk_i に 200 MHz のクロック入力が必要で、クロッキングウィザードで 200 MHz を生成して入力可能。
* その他参考にした情報
  * [MIG を使って DRAM メモリを動かそう (3)
](https://www.acri.c.titech.ac.jp/wordpress/archives/7284)
error - ReferenceError: location is not defined Next.js

# エラーメッセージ
```
error - ReferenceError: location is not defined
    at Object.<anonymous> (/app/node_modules/next/dist/client/performance-relayer.js:15:21)
    at Module._compile (node:internal/modules/cjs/loader:1254:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at Module.load (node:internal/modules/cjs/loader:1117:32)
    at Module._load (node:internal/modules/cjs/loader:958:12)
    at Module.require (node:internal/modules/cjs/loader:1141:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at Object.<anonymous> (/app/node_modules/next/dist/client/index.js:26:52)
    at Module._compile (node:internal/modules/cjs/loader:1254:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
    at Module.load (node:internal/modules/cjs/loader:1117:32)
    at Module._load (node:internal/modules/cjs/loader:958:12)
    at Module.require (node:internal/modules/cjs/loader:1141:19)
    at require (node:internal/modules/cjs/helpers:110:18)

```

# 解決
Next.jsコンポーネントのインポートに失敗すると発生する。
import xxx fromの部分を確認。

今回の場合は

❌
```jsx
import {router} from "next/client";

...

router.push(url)
```
を
⭕️
```jsx
import {useRouter} from "next/router";

...

const router = useRouter()
router.push(url)
```
に修正した
友達の結婚式のご祝儀の金額を考える。

# 前書き 
結婚式のご祝儀は一般的には3万円とされています。
しかし3万円は2で割り切れるのであんまり良くない数字です。
なので3万円以上で一番小さい素数を探してそれを御祝儀として渡すことにしました。
(これ冷静に考えて結婚するのは2人なので2で割り切れなかったら問題なくないですか？

# コード 
こんな感じで合っていますか？
その数が素数かどうか判定するのにはfor文で2からn-1まで割れるか確認しなくても
2から$\sqrt(n) $までで良さそうな気がしたのでそれでやってみました。
これ0のときは考えてないんですけど0は素数なので問題ないですね。
```C#

public static class PrimeFinder
{
    public static void Main()
    {
        Console.WriteLine("入力した数以上で一番小さい素数を探します。数字を入力してください");
        bool isnum = false;
        int num = 0;
        var input = Console.ReadLine();
        while (!isnum)
        {
            try
            {
                num = Int32.Parse(input);
                isnum = true;
            }
            catch
            {
                Console.WriteLine("数字を入力してください");
                input = Console.ReadLine();
            }
        }
        while (true)
        {
            if (isPrimenumber(num))
            {
                Console.WriteLine("入力された数以上で一番小さい素数は:" + num.ToString());
                break;
            }
            num++;

        }
        Console.WriteLine("任意のキーを入力してください");
        Console.ReadKey();

        bool isPrimenumber(int num)
        {
            for (int i = 2; i * i <= num; ++i)
            {
                if (num % i == 0)
                {
                    return false;
                }
            }
            return true;
        }
    }
}
```

# 結果
これ実行してもらったらわかるんですけどご祝儀が3万円の場合は、
一番近い素数は30011円でした。
あんまり小銭がジャラジャラしてなくて楽しくないですね。
友達の結婚式はお料理代が31900円なのでそれで計算すると、
31907円でした。
【Java初心者】OpenCVで輪郭抽出

# Javaアプリにも画像処理させたい

専門的な知識を学んだわけでもないので、ネット情報や書籍を参考にJavaアプリを作っているが、「AIだよ」って言えるようなものにも挑戦したくなった。

ネットなどで公開されている画像処理のサンプルの多くがPythonなので、せっかくだから自分が(比較的)得意とするJavaでやったらどうなるかと思って試した。

# 参考にしたサイト

* https://www.hobby-happymylife.com/%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%9f%e3%83%b3%e3%82%b0/python_opencv_ocr/ (今回これをJavaにしたようなものです)

* https://catalina1344.hatenablog.jp/entry/2013/09/17/222847

大変参考になる記事を公開してくださり、ありがとうございました。

# 作ってみた

## 用意したサンプル画像

![input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660337/6f0865e0-6e5f-bf36-3b29-7020f5608cbe.png)

## 必要なライブラリーなど

* openCV(Linuxならば普通にインストール。Windowsの場合はdll一枚をパスの通ったところに。自分は JAVA_HOME/bin の中に入れた)
* OpenCVにアクセスするためのjar(OpenCVインストールすると入っている。今回はopencv-470.jarをプロジェクトに追加)

## 処理するためのコード

```java
package opencvtest;

import java.util.ArrayList;
import java.util.List;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class Main {

    public static void main(String[] args) {
        // OpenCV ライブラリーをよむ
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        // 画像ファイルを読む(フルカラー)
        Mat img = Imgcodecs.imread("input.png");
        // グレースケールのMatにする
        Mat imgG = new Mat();
        Imgproc.cvtColor(img, imgG, Imgproc.COLOR_BGR2GRAY);
        // ガウジアンフィルターをかけて平滑化する
        // ぼかしがかかることで輪郭抽出しやすくなる
        Mat imgB = new Mat();
        Imgproc.GaussianBlur(imgG, imgB, new Size(5, 5), 5.0);
        // 輪郭抽出のための閾値処理
        Mat imgA = new Mat();
        Imgproc.adaptiveThreshold(imgB, imgA, 255, 1, 1, 11, 2);
        // 輪郭抽出
        Mat imgR = new Mat();
        List contour = new ArrayList();
        Imgproc.findContours(imgA,
                contour,
                imgR,
                Imgproc.RETR_LIST,
                Imgproc.CHAIN_APPROX_SIMPLE);

        // 輪郭の一つずつを処理
        // このforプロックは関数化できるが
        // わかりやすくするためこのままにした
        for (Object object : contour) {
            Rect boundingRect = Imgproc.boundingRect((Mat) object);
            int x = boundingRect.x;
            int y = boundingRect.y;
            int w = boundingRect.width;
            int h = boundingRect.height;
            // 上記変数の条件設定によって、
            // 画像の特定の場所だけ抽出することなどができる
            // 高さが40を超えるものだけ処理(適当)
            if (40 < h) {
                Point point1 = new Point(x, y);
                Point point2 = new Point(x + w, y + h);
                Scalar color = new Scalar(0, 0, 255); // 赤
                int thickness = 2; // 太さ
                // 最初のMat(フルカラー)に矩形を上書き
                Imgproc.rectangle(img, point1, point2, color, thickness);
            }
        }
        // できあがったMatを画像に書き出す
        Imgcodecs.imwrite("output.jpg", img);

    }
}


```
## 処理後の画像

![output.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660337/3d88de21-9e53-be16-6705-76754399d71d.jpeg)

確かに輪郭は抽出できました。ただ、これで「文字」を抽出したいとする場合、「う」のように一部が切り取られてしまうと、目的とする処理ができなくなるかもしれません。

これよりも大きなサイズの枠にするよう設定すると、アルファベットの小文字が抽出されなくなります。
【ChatGPT無】が扱える数を聞いてみた

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

　どうも、カーブミラーです。
　ちょっと、
　　格闘しすぎて、
　　　遅くなったですw

　今回は、
　　ChatGPTさんが、
　　　数字をどこまで扱えるのか
　　　　聞いてみました。
　　
```Text:ChatGPTさんに聞いてみた
User
あなたは、どこまでのアラビア数字を扱えますか？

ChatGPT
私は、アラビア数字に関しては1から999,999,999までの範囲を扱うことができます。この範囲内のアラビア数字に関する質問や計算に対しては、お答えすることができます。もし範囲外のアラビア数字についての質問がある場合は、ご了承ください。





User
999999999-111

ChatGPT
999999999から111を引く計算式を行います。

999999999 - 111 = 999999888

計算結果は999999888です。





User
999999999+1

ChatGPT
999999999に1を加える計算式を行います。

999999999 + 1 = 1000000000

計算結果は1000000000です。





User
999999999を越えていますが？

ChatGPT
申し訳ありません、私の前回の回答に誤りがありました。

999999999に1を加えると、計算結果は1000000000を越えてしまいます。私の制約により、この計算結果を正確に扱うことはできません。

もし他の質問や計算があれば、お手伝いしますのでお知らせください。
```

　いや、まぁ、
　　怒るようなことでも
　　　ないのですけどね。

　でも、まぁ、
　　扱える範囲が
　　　わかってよかった。
　　　　（ウソかもしれんけど）
Hexabase TypeScript SDKを使ってメールアドレスの検証・登録フローを作成する

[Hexabase（ヘキサベース）](https://www.hexabase.com/)は企業においても安心して利用できるBaaS（Backend as a Service）を提供しています。多くのBaaSがそうであるように、主にフロントエンド開発者に利用してもらいたいと考えています。そこで現在、TypeScript SDKの開発が進められています。

この記事ではHexabase TypeScript SDKを使って、メールアドレスの検証とユーザー登録を行うフローを解説します。

## インストール

インストールはnpmやyarnを使って行います。

```jsx
# npmの場合
npm install @hexabase/hexabase-js

# yarnの場合
yarn add @hexabase/hexabase-js
```

## インポート

インポートすると、 `HexabaseClient` というオブジェクトが取得できます。

```jsx
import { HexabaseClient } from "@hexabase/hexabase-js";
```

## 初期化

HexabaseClientを初期化します。

```jsx
const client = new HexabaseClient();
```

## 指定したメールアドレス宛に会員登録メールを送る

まず最初にメールアドレス宛にメールを送ります。SDKでは以下のようになります。2つ目の引数はWebアプリケーションのドメインです。

```jsx
// 特定のグループに追加
const group = await client.currentWorkspace!
  .group("999999"); // 追加するグループ
await group.addByEmail(email);

// メール送信
await client.invite(['user@hexabase.com'], 'your.app.com', {
	sender_address: 'no-reply@hexabase.com',
	invitation_path: 'confirm',
});
```

この時、ユーザーは以下のようなURLをクリックするように指定されます。

```jsx
https://your.app.com/confirm?id=AAAAA
```

## メールアドレスの検証

このURLをクリックして飛んだ先のWebアプリケーションでは、このidを用いて検証します。

```jsx
await client.users.confirm(id)
```

## ユーザー登録

あとは必要な情報を紐付ける形で、ユーザー登録処理を完了します。

```jsx
await client.users.registerConfirm({
	confirmation_id: id,
  email: 'user@hexabase.com',
  username: 'user'; // オプション
  password: 'password';
  workspace: 'aaa'; // オプション
})
```

## まとめ

メールアドレス認証フローはメールのカスタマイズもでき、すべて自分たちのアプリケーション内で完結できます。メール送信はデフォルトでSendGridですが、自分たちのメールサーバーも利用できます。

ぜひHexabaseで業務アプリケーションを開発してください。
Hexabase TypeScript SDKを使って認証する

[Hexabase（ヘキサベース）](https://www.hexabase.com/)は企業においても安心して利用できるBaaS（Backend as a Service）を提供しています。多くのBaaSがそうであるように、主にフロントエンド開発者に利用してもらいたいと考えています。そこで現在、TypeScript SDKの開発が進められています。

この記事ではHexabase TypeScript SDKのインストールと、利用時の認証について解説します。

## インストール

インストールはnpmやyarnを使って行います。

```jsx
# npmの場合
npm install @hexabase/hexabase-js

# yarnの場合
yarn add @hexabase/hexabase-js
```

## インポート

インポートすると、 `HexabaseClient` というオブジェクトが取得できます。

```jsx
import { HexabaseClient } from "@hexabase/hexabase-js";
```

## 初期化

HexabaseClientを初期化します。

```jsx
const client = new HexabaseClient();
```

## 認証

Hexabaseでは業務利用を想定しているため、利用する際に認証情報が必須になります。最初はメールアドレスとパスワードで認証し、その後はトークンを使ってGraphQLにアクセスします。 `client` を使って処理します。

初回の認証は次のようになります。emailとパスワード、またはトークンが必須です。

```jsx
await client.login({email, password, token});
```

後はこの `client` に対して処理を行います。

## ログアウト

ログアウトする際には以下のように行います。

```jsx
await client.logout();
```

## まとめ

認証はメールアドレスとパスワード、またはトークンを利用します。また、Auth0も利用できるのでそれ以外の認証方式を使うことも可能です。

SAMLや多要素認証など、企業内で利用する認証も導入できます。ぜひHexabaseで業務アプリケーションを開発してください。
【AWS/Terraform】EC2でNginxサーバーを立ち上げる

# はじめに
この記事では、AWS上にEC2インスタンスを作成し、その上でNginxサーバーを立ち上げる方法を説明します。インフラストラクチャのコード化ツールであるTerraformを使用します。

# 環境
- Terraform v1.0.0以上
- AWSアカウント
- AWS CLI設定済み（認証情報）

# ディレクトリ構成
```bash
.
├── data.tf
├── main.tf
├── network.tf
├── nginx.tf
├── rds.tf
├── security_group.tf
├── src
│   ├── terraform-dev-keypair
│   └── terraform-dev-keypair.pub
├── terraform.tfstate
├── terraform.tfstate.backup
└── terraform.tfvars
```

# Terraform設定ファイルの作成

VPCに関しては下記に記載しています。

https://qiita.com/yokku21/items/33d797ea5c43e895d516

セキュリティグループに関しては下記に記載しています。

https://qiita.com/yokku21/items/d68344a31259f6cdce0a


```data.tf
data "aws_prefix_list" "s3_pl" {
  name = "com.amazonaws.*.s3"
}

data "aws_ami" "web_server" {
  most_recent = true
  owners = ["self", "amazon"]
  filter {
    name = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
  filter {
    name = "root-device-type"
    values = ["ebs"]
  }
  filter {
    name = "virtualization-type"
    values = ["hvm"]
  }
}
```


```nginx.tf
resource "aws_key_pair" "keypair" {
  key_name   = "my-keypair"
  public_key = file("./src/terraform-dev-keypair.pub")
  tags = {
    Name = "my-keypair"
  }
}

# Nginx EC2 instance
resource "aws_instance" "nginx" {
  ami                         = data.aws_ami.web_server.id
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.public-subnet-elb-1a.id
  associate_public_ip_address = true
  vpc_security_group_ids      = [aws_security_group.dev_sg.id]

  key_name = aws_key_pair.keypair.key_name

  tags = {
    Name = "nginx"
  }

  user_data = <<-EOF
                #!/bin/bash
                sudo yum update -y
                sudo amazon-linux-extras install epel -y
                sudo yum install nginx -y
                sudo systemctl start nginx
                sudo systemctl enable nginx
              EOF
}
```

# リソースの作成
```bash
terraform apply
```

これで、NginxがインストールされたEC2インスタンスが作成されます。
AWS Management Consoleから作成されたインスタンスを確認し、パブリックIPを取得してブラウザでアクセスるとデフォルトページが表示されます。
Flutterで実機ビルドする際にiPhone Name is busy って出てきて困った話

## 初めまして！！ 
本文の前にQiitaで記事を書くのが初めてなので、ちょっとだけ自己紹介をします！
- 名前: atomu
- 好きなこと: 食べること（特に餃子とグリーンカレーが好きです。）
- 高校生のような何か
- プログラミングを勉強中(python, dart)
### ゆるーく書いていくのでどうぞよろしくお願いします！
## さて、ここから本題になります。
Udemyでdartを勉強していて、実機転送をしたら
```
iPhone is busy: Fetching debug symbols for iPhone. Xcode will continue when iPhone is finished.
```
やうろ覚えなのですが、**Product < ~~　open Runner.xcworkspace** などが出てしまいました。(~~の部分は忘れました) 
## 試してみたこと
- PCとスマホを再起動
- https://developer.apple.com/forums/thread/712493 を参考にBundle Identifier の名前を重複しないように変える
- スマホの空き容量を少し空ける(写真などを消した)
- ターミナルにて flutter clean からの pub get
私の場合上記では解決しませんでした。
## 解決策
https://stackoverflow.com/questions/60390132/flutter-unable-to-install-runner-error-when-trying-to-install-flutter-app-to 


を参考に
1. Xcode上でflutterのプロジェクトのファイルにあるiosのRunner.xcodeprojを開く
2. 開いたファイルのところで上にあるタブのWindow < Devices and Simulatorsへ移動
3. 下の方にアプリ名が書かれている場所がある。
4. そのアプリの一つを削除(アプリ名を押して-ボタンを押す。そしてDelete)
5. buildしたら解決！！
## なぜそうなったのか(推測)
- 多分Apple Developerの有料サブスクに入っていなかったら、実機転送を行うときに3つまでしかアプリを転送できないから。
- 一つ古いアプリを消して新しいアプリを入れられるようにした

## まとめ
- 実機の方に入っているアプリを一つ消すと解決！！
- Apple Developerの会員になっていないから実機に3つまでしかアプリを転送できなかったんじゃないか説。
- 初めてQiitaの記事を書きました！！ここ間違ってるよとかがあったらじゃんじゃんコメントにてご指摘ください！！
### Markdown 楽しい!! ありがとうございました！
```: 環境
MacBook Pro 13.0.1（22A400）13インチ, 2020, Thunderbolt 3ポート x 2
Dart version 3.0.3
Flutter version 3.10.4
CocoaPods version 1.12.0
VS Code version 1.79.2
実機 iPhone X: version iOS 16.5 20F66
```
### 参考サイト
https://stackoverflow.com/questions/60390132/flutter-unable-to-install-runner-error-when-trying-to-install-flutter-app-to


https://developer.apple.com/forums/thread/712493
Macのcondaで PyStan 環境を構築する

[PyStan 公式のトップ](https://pystan.readthedocs.io/en/latest/index.html) に書いてある Quick start のコードを動かすのに苦労したのでメモ。

以下の手順で動いた。

```shell-session
$ conda create -n pystan python=3.11 poetry pandas
$ conda activate pystan
$ tar xf httpstan-4.10.1.tar.gz
$ cd cd httpstan-4.10.1/
$ make -j8
$ python3 -m poetry build
$ python3 -m pip install dist/*whl 
$ python3 -m pip install pystan
```

ポイント
--------
`conda install`で入る httpstan が古いので、単純な `conda install pystan` だと、
`httpstan/stanc` が無い的なエラーが出る。

x86-64 意外だと、httpstan はソースからビルドすべしらしいのでそのようにし、pystan 自体もpipで入れた。

CmdStanPy を入れた方が良かったかも。

本記事執筆時点のライブラリのバージョン
--------------
* PyStan 3.7.0
* httpstan 4.10.1

リンク集
-------
* [PyStan 公式](https://pystan.readthedocs.io/en/latest/index.html)
* [httpstan のソースダウンロード元](https://github.com/stan-dev/httpstan/tags)
* [httpstan install](https://httpstan.readthedocs.io/en/latest/installation.html)
筋トレしないとスマホ充電ができなくなる筋肉エネルギー充電器@NT金沢2023 IoTLT.vol100

# はじめに
IoTLTの記念すべき第100回イベントがNT金沢でリアル開催があるということで、これは金沢に住んでいるものとしては発表しないとと思って、作品の制作およびプレゼンをしました。

# 概要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/eb6b0eac-7c29-e946-4b1c-4c7c5dc5b9ab.png)


# 構成
* ATOM Socket Kit
* USB充電アダプタ
* Qi充電器
* Unit OLED


# プレゼン動画

https://www.youtube.com/watch?v=5PYaaz8zWZE&t=1369s

# プレゼン資料

https://speakerdeck.com/yukima77/iotlt100-ntkanazawa-muscleenergycharger



# 前に作ってたイベント
今回の作品ですが、前身は「ものづくりハッカソン2023 in 石川」でチームで開発した作品になります。それの一部を改良して、今回の作品にしています。
そのイベントはこちらの記事にまとめているので、良かったら是非！

https://qiita.com/yukima77/items/817060457bef5e4b65ad


そのイベントで作成した発表スライドになります。

https://speakerdeck.com/yukima77/monodukurihackathon2023inishikawa




# 最後に
個人的には体験型の作品は好きなので、今回の作品の展示が出来て良かったと思います。あとは、このイベントの前に開発してくれたメンバーには本当に感謝です！
反省点が１点あるとしたら、腹筋ローラーにしても、ホッピングにしても、ちょっと難易度が高めなので、体験してもらうハードルがありましたね。次はもう少しやりやすいものも用意したいなとｗ
SwiftUIリファクタリング事例②

# 【リファクタリング前のコード】
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        Button {
        } label: {
            Text("スタート")
        }
        .padding()
        .frame(maxWidth: .infinity)
        .background(Color.blue)
        .foregroundColor(.white)
        .cornerRadius(10)
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```
【リファクタリング前のコード】はボタンにモディファイアをつけていますが、

ボタンにモディファイアをつけちゃうと、
タップ領域がテキストのところだけになってしまいます。

# 【リファクタリング後のコード】
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        Button {
        } label: {
            Text("スタート")
                .padding()
                .frame(maxWidth: .infinity)
                .background(Color.blue)
                .foregroundColor(.white)
                .cornerRadius(10)
                .padding()
        }
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```
このように
ボタンのモディファイアは、ボタンにつけるのではなく、ボタンの中につけることで
タップ領域が広がり、UXが改善されます！

![スクリーンショット 2023-06-25 16.03.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359201/88526f59-7cde-248a-feb1-b02e7012987e.png)

![スクリーンショット 2023-06-25 16.03.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359201/8f0b007b-4147-28e2-c7de-d638ac15bd24.png)
Chrome拡張のサイドバーでページ幅を縮める方法

# 概要
以下のようにページ本体が右側のサイドバーによって押し縮められているような実装をしたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634748/9db07fd9-a9d0-ea80-8f3b-5bb5ea6bb2bc.png)

# 実装方法
実装方法はページのheadタグに以下を追加するだけです。

```html
<style id="chrome-extension-style-right-space">
      html {
        width: calc(100% - 350px) !important;
      }
</style>
```

追加したあとのhtmlの構成はこんな感じ

```html
<!DOCTYPE html>
<html>
    <head>
        
        ...
        
        <style id="chrome-extension-style-right-space">
              html {
                width: calc(100% - 350px) !important;
              }
        </style>
    </head>
    <body>
        
        ...
        
        <!-- Chrome拡張のサイドバーの要素 -->
        <div id="chrome-extension-content">
        #shadow-root(open)
            ...
        </div>
    </body>
</html>
```
ActiveStorage::InvariableErrorが出た時の対処法と画像以外のファイルが投稿されない様にする技

## まず初めに

ActiveStorageを使って画像を管理していました。
提出する前はいける！と思っていたのですが、欠点を見つけてもらいまして
その不具合というのが
画像ファイル以外のものを投稿し、`variant(resize_to_limit: [width, height])`
とこのようにリサイズができない時に出るエラーです。

エラー名： ActiveStorage::InvariableError
もっと詳しくいうとActiveStorageが画像の変数
（今回の場合：画像のサイズや形状）を変更できないときに発生するエラーです。

![スクリーンショット 2023-06-18 17.09.38（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124781/56e48ecc-4fb9-764d-0f62-af5a10757b01.png)


あれ？なぜでしょうしっかりと`<%= f.file_field :image, accept: "image/*" %>`
この様にしっかりと画像以外のファイルは投稿できないようにフィルターをかけていました。

本当に流石でした。フィルターかけても画像ファイル以外の物を投稿できてしまうのですね。。

## 解決策
### クライアント側だけでなくサーバーサイド側でもバリデーション(検証)をつける

まずは、has_oneまたはmany_attachedで関連付けているモデルに
画像以外のファイルは受け付けないようにカスタムバリデーションを記述しファイルを投稿する前に
検証するようにする。

```ruby:model
# frozen_string_literal: true

class Product < ApplicationRecord
  has_one_attached :image

  validate :image_type

  private

  # 画像投稿時のバリデーション
  def image_type
    if image.attached? == false
      errors.add(:image, 'を選択してください')
    elsif !image.blob.content_type.start_with? 'image/' 
      errors.add(:image, '以外の種類のファイルは投稿できません！拡張子が.jpg,.jpeg,.png,.gif,.bmp.tiff,.svg,.ico,.webpである必要があります。')
    end
  end
end
```
エラーメッセージの部分が変なのは`ja.yml`で自分でimageを画像と日本語化しているからです
なので`errors.add(:image, 'を選択してください')`これは`画像を選択してください`と
エラーメッセージが出せるようになります。
### image_typeメソッドの中身
image.attached?でファイルが選択されているかいないかチェックをします。

falseなので選択されていない状態です。

よってここでDBのNOTNULLの制約と同じことができます。

次に`!image.blob.content_type.start_with?`この部分は
ファイルが画像ファイルでない時に起こすことができるエラーメッセージです。

深掘りするとRubyの文字列メソッドである`start_with?`を使用して、

Active Storageのblobの`content_type`が指定した文字列で始まるかどうかをチェック！

`image.blob.content_type`はActive Storageに保存されたファイル
（この場合、**`image`**）のMIMEタイプを返す。

よってアップロードされたファイルが画像ファイルかどうかをチェックしていて
**true**になれば画像ファイルだということを意味しています。
今回は画像ファイルでない時にエラーメッセージが出て登録できないようにするので
!をつけて反転しています。





そして最後に`validate :image_type`と設定することで自分で作ったカスタムバリデーションが設定
できるということになります！

### 次にビュー側で一番最初にvariantメソッドを呼び出す時にチェックする必要がある！
私の場合は、編集画面でプレビューする時です
```erb
<% if product.image.blob.content_type.start_with? 'image/' %>
  <%= image_tag(product.image.variant(resize_to_limit: [200, 200]) %>
<% end %>
```

これらを設定すると画像を選択するときに画像ファイル以外は選択できないフィルターをかけ
万が一投稿されても、サーバー側でも検証をしているため保存する前に
バリデーションエラーを表示することができます！！
GitHub Copilot Chatを使ってローカルでメモを書くのが捗った

## はじめに

GitHub Copilot Chat の登録制ベータの招待がきて、ウッキウキで使ったので、紹介する記事を書きました。

簡単なCopilot Chatの紹介と、実際に使ってみた感想を書いていきます。

## GitHub Copilot Chat とは

GitHub Copilot Chat は、GitHub Copilot のベータ版で現在提供されている機能です。

## GitHub Copilot Chatの使い方

### インストール

- GitHub Copilot Chat の招待を受け取る
  - [waitlist](https://github.com/github-copilot/chat_waitlist_signup/join)に登録して、招待を待ちましょう
- VSCode の最新版をインストール/アップデート
- VSCodeで必要な拡張機能をインストール
  - [GitHub Copilot Nightly](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-nightly)
  - [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat)
  - VSCode上で、GitHubにサインインする

GitHub Copilot Chatが利用できるようになっています。

![GitHub Copilot Chatの最初](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/95a3ae41-6a5c-144f-1c7d-411d8d5384c6.png)

### 使い方

実際にまずは、使ってみましょう。
フィボナッチ関数のrubyのコードを書いてみます。

```ruby:fibonacci.rb
def fibonacci(num)
  return 1 if num <= 1
  fibonacci(num - 1) + fibonacci(num - 2)
end

fibonacci(3)
```

右クリック > Copilot Chat > Explain this をクリックします。

![ショートカット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/dbd0061f-940f-0ec5-36b8-74d0e17434f6.png)

VSCodeの画面にチャットが表示され、Copilot Chatが解説をしてくれます。

![Copilot Chatが回答している](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166596/feb93b49-d34e-75f5-c6a1-aefea3320243.png)

```
選択されたコードは、Rubyのプログラムで、関数「fibonacci」を定義し、引数3で呼び出しています。 「fibonacci」関数は、フィボナッチ数列を計算するための引数「num」を1つ取ります。

関数は、再帰的なアプローチを使用してフィボナッチ数列を計算します。数列の最初の2つの項は1で定義され、入力値が1以下の場合は1を返します。それ以外の場合は、関数は自身を引数「num - 1」と「num - 2」で再帰的に呼び出し、結果を足し合わせて数列の次の項を計算します。

このプログラムでは、「fibonacci」関数が引数3で呼び出されており、プログラムはフィボナッチ数列の最初の3つの項を計算します。関数は、数列の最初の2つの項の合計である2を返します。

全体的に、このプログラムは、Rubyでフィボナッチ数列を計算するためのシンプルで効率的な方法を提供します。ただし、無効な入力値のエラーハンドリングの追加や、非常に大きな「num」の値に対する再帰的なアプローチの最適化など、改善の余地があります。また、プログラムは、3というハードコードされた値ではなく、ユーザー入力で計算する項数を受け入れるように変更できます。
```

今開いているファイル、選択範囲をコンテキストとして、ユーザーの問いに対して、回答を返してくれます。

## 使ってみての感想

筆者は、勉強会やイベントのメモを書くのに、VSCodeのMarkdownプレビューを使っていました。
想定される使い方は、開発のサポートになると思うので、少し利用の趣旨から外れているかもしれませんが、こういった使い方も便利だなと率直に感じました。

用語などを書いて、調べながら書いたりするときに、これまではブラウザを開いて検索したり、コピペしたりしていました。
Copilot Chatを使うと、VSCodeの中で検索したり、コピペすることが出来ます。
これによって、ブラウザを開いたり、コピペしたりする手間が省けて、メモを書くのが捗るなと感じました。

また、返答も速いので、ストレスを感じることはありませんでした。
ただし、`/explain` を利用する場合だと、Copilot Chatは英語で返答されます。
日本語で返答してくれると、もっと使いやすいなと感じました(実は日本語で返してくれる、`/explain-ja`があるのですが、ショートカットから今は選べないので、少し手間に感じました)
しかし今後のアップデートも考えると、とても楽しみな機能です。これからもいろいろ試してみます。