OmniAICreator/Qiita-1.07M huggingface dataset:
Optparseの基本的な使い方について

## はじめに
今回はOptparseとは何か、Optparseの基本的な使い方について記載していきます。

## Optparseとは
Optparseとは`コマンドラインでのオプションを取り扱うためのライブラリ`です。
Optparseを使うことで、例えば入力されたオプションの引数を取得→取得した引数をどうこうするといったことができるようになります。
私が使用した例だと、コマンドラインの引数に指定された月のカレンダーを表示するというところでOptparseを使用しました。

```
# オプション・・・-m
# -mの引数・・・9
$ ruby calendar.rb -m 9
```

# 使い方

```
#　①ライブラリ読み込み
require 'optparse'

#　②OptionParser オブジェクト opt を生成
opt = OptionParser.new

#　　オプションを取り扱うブロックを opt に登録
# 引数が指定された時の処理をブロック{}で記載
opt.on('-a') {|v| p v }
opt.on('-b') {|v| p v }

# opt.parse(ARGV) でコマンドラインを実際に parse する
# コマンドラインの解析を行う、結果はARGVに格納される
opt.parse!(ARGV)
p ARGV
```

入力値
```
$ ruby sample.rb -a foo bar -b baz
```

出力結果
```
# オプション(-a)が指定されたのでtrue
true
# オプション(-b)が指定されたのでtrue
true
["foo", "bar", "baz"]
```

# オプションの引数を必須にする
`$ ruby sample.rb -a foo bar -b baz` -aオプションの引数は必須としたい場合などですね

```
require 'optparse'
opt = OptionParser.new

# -a オプションの後にVALを追加
opt.on('-a VAL') {|v| p v }    
opt.on('-b') {|v| p v }

opt.parse!(ARGV)
p ARGV
```

①入力値 -aオプションを引数なしで指定
```
$ ruby optparse.rb -a
```

①結果　引数がありませんとエラーが返される
```
optparse.rb:7:in `<main>': missing argument: -a (OptionParser::MissingArgument)
```

②入力値 -aオプションを引数ありで指定
```
$ ruby optparse.rb -a foo bar -b baz
```

②結果
```
"foo"
true
["bar", "baz"]
```

# 参考文献

https://docs.ruby-lang.org/ja/latest/library/optparse.html#optionarg
ResoniteをUbuntu 22.04 LTSで動かすコツ

# 問題点
Resoniteをインストールしただけだとロード画面から進みません

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/017edeb9-f5c1-dd19-1bdb-156eda93f648.png)

# 対処法

「歯車アイコン」から「プロパティ」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/0e3ca747-e5ca-3915-75d9-f811cfc55155.png)

「互換性」の「特定のSteam Play互換ツールの使用を強制する」をチェックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/cdfd4df1-60d5-2bac-1fe6-7bb7415f2c1f.png)

これで動きました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/fd08a170-e684-4ffe-ed80-2dd1d5d0a27c.png)
./と../の違い

# 問題背景
 パスの書き方の違いで困ったことがあったので、メモとして残しておきます。

# ./と../の違い
 自分が今いるディレクトリをカレントディレクトリと呼びます。
 現在いるディレクトリ内のファイルを表す時に
 ```:terminal
./ファイル名
```
で表せます。

 カレントディレクトリよりも上の階層にあるディレクトリのファイルを表す時には
  ```:terminal
../ファイル名
```
で表せます。

# 最後に
パスの指定は結構苦労する所だと思うのでぜひ参考にしてみてください!
【初心者】Reactのstateについて

## stateについて
Reactのstate（ステート）は、コンポーネントの現在の状態を保持するために使用されるデータ。

Reactのコンポーネントは関数またはクラスの形で書くことができる。どちらの場合でもstateを使ってデータを管理できる。
※関数コンポーネントは、useStateフックを使用してstateを管理する。React 16.8で導入された機能。

## 関数コンポーネントの書き方について
※今回は関数コンポーネントについて整理する。

```
import React, { useState } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0); // 初期stateを設定

  const incrementCount = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>{count}</p>
      <button onClick={incrementCount}>Increment</button>
    </div>
  );
}
```

この例では、useStateフックを使用。
countという名前のstate変数を作成し、それを更新するための関数setCountを作成している。
useStateの引数には、stateの初期値（この場合は0）を渡している。
ボタンがクリックされると、incrementCount関数が呼び出され、setCountを通じてcountの値が更新される。
iPhoneアプリの公式リンク生成を試す

下記から自分で公開したアプリ含めて色々なリンクを生成できる。
主には販促用っぽいがXなど他のアプリのリンクも作る。昔のLinkMaker的な公式ツール。

## 公式リンク生成ページ

https://tools.applemediaservices.com/app-store

上にアプリ名を入れれば各アプリの生成ページへ。

作れるものは以下

- コンテンツのリンク ( 最も普通なやつ ) 
- ショートリンク ( apple.coになる )
- App Icon ( アプリの画像のみ )
- Download App Store (いつものリンク)
    - 黒 / 白
    - 言語選択
- QRコード
    - 黒 / 白 / 青
    - AppIconあり / なし

# 実際に各種やってみる

公開したリテラシー学習アプリ Sukunabiko でやっている例です

## コンテンツリンク

最も通常のリンク

https://apps.apple.com/us/app/sukunabiko/id6478607983?itsct=apps_box_link&itscg=30200



## ショートリンク

apple.coのショートリンクを作ってくれる.

> https://apple.co/48wu8tf

https://apple.co/48wu8tf

## App Icon

> https://is1-ssl.mzstatic.com/image/thumb/Purple122/v4/e7/f1/e0/e7f1e0a8-b61d-75f7-edfb-355741774b5c/AppIcon-0-0-1x_U007epad-0-85-220.jpeg/240x240bb.jpg

デフォルトはここに貼るには大きすぎたので上のファイル名の部分を任意のサイズに変えて大きさ調整。
影はなし。

<a href="https://apps.apple.com/us/app/sukunabiko/id6478607983?itscg=30200&amp;itsct=apps_box_appicon" style="width: 170px; height: 170px; border-radius: 22%; overflow: hidden; display: inline-block; vertical-align: middle;"><img src="https://is1-ssl.mzstatic.com/image/thumb/Purple122/v4/e7/f1/e0/e7f1e0a8-b61d-75f7-edfb-355741774b5c/AppIcon-0-0-1x_U007epad-0-85-220.jpeg/240x240bb.jpg" alt="Sukunabiko" style="width: 100px; height: 100px; border-radius: 22%; overflow: hidden; display: inline-block; vertical-align: middle;"></a>


# App Storeからダウンロードボタン

いつも貼るタイプの埋め込み系リンク。便利。

<a href="https://apps.apple.com/us/app/sukunabiko/id6478607983?itsct=apps_box_badge&amp;itscg=30200" style="display: inline-block; overflow: hidden; border-radius: 13px; width: 250px; height: 83px;"><img src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/black/ja-jp?size=250x83&amp;releaseDate=1709251200" alt="Download on the App Store" style="border-radius: 13px; width: 250px; height: 83px;"></a>


# QR Code

一例として青色。丸く切り取って欲しかったがそういうのはない様子。
Appleならもう少しおしゃれなQRコード作ってくれるかと期待していたが。

<img src="https://tools-qr-production.s3.amazonaws.com/output/apple-toolbox/1bc8d24a7f2cbf4a6505585376cd56e2/d72194629ddc331f55a6eb1126d10b6c.png">
spring-mvcでgetterが無く406 Not Acceptable

springで406 Not Acceptableが発生して原因が分かるまでに多少の時間を要した。lombokの ```@Data``` が何らかの要因で無効になりgetterが存在しないとjson生成が上手くいかず、結果として406 Not Acceptableになるようだ。

以下は検証用のコードなど。

```java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SomeRestController {
  @GetMapping("/item")
  public Item item() {
    return new Item("11");
  }
}
```

ポイントとして、あえてlombokの ```@Data```を外している。

```java
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//@Data
@AllArgsConstructor
@NoArgsConstructor
public class Item {
  String item;
}

```

この状態で http://localhost:8080/item にアクセスすると下記キャプチャのように406 Not Acceptableになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31934/7d98b433-e213-fd26-7601-075427c44802.png)

詳しい原因までは調査していないが、lombokでgetterが生成されないのでjsonの生成も上手くいかず、converterで何かしらおかしなことになるんだろうな、と想像している。
Table Plus ER図を出力できるようにする

## 概要

Table PlusにてER図を自動生成できるようにする方法を簡単にまとめる。

## 前提

DB　レイヤーで外部キー制約などのテーブル間リレーションが貼られていること。

## 方法

1. Table Pulsを開く
1. 画面上部の帯の「Plugins」をクリックする。

    ![Menubar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/92938fa9-a3be-1aa8-92be-01fa33b90e77.png)

1. 「Manage Plugins...」をクリックする。

    ![スクリーンショット_2024-03-01_22_11_48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/a420fc03-4c12-bb62-ce52-ad85dba7e960.png)

1. 「Diagram Generator（4.0）」の赤矢印が指しているボタンをクリックする。

    ![Window_と_table_pulsにてER図を生成してもリレーションが生成されない問題を解決__ER図_-_Qiita_と_MENTA___【MENTA】No1_メンターサービスでプロに直接相談しよう！.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/bf542baa-0890-b325-d0fb-7dc9ad8d301a.png)

1. 「install」をクリックする。

    ![スクリーンショット_2024-03-01_22_13_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/c21f9ac9-259b-49df-8fe8-3056d6fc9380.png)

1. Installed Pluginsの中にDiagram Generator(4.0)が入る。

    ![Window_と_table_pulsにてER図を生成してもリレーションが生成されない問題を解決__ER図_-_Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/33e95002-1ea2-9e0d-91c8-f99402ca4aa3.png)

1. Plugin Managerウインドウを閉じる。

## ER図の出力

1. 任意のDBを開き、任意のテーブルを右クリックする。

    ![Menubar_と_D_local___dokupro_app_-_MySQL_8_0_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/1f9c68ca-995d-e78c-7641-62064e134fab.png)

1. 「Generate diagram」 → 「Generate Diagram」とクリックする。

    ![スクリーンショット_2024-03-01_22_16_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/0e40c9ee-f796-5a81-a873-228d64cffb13.png)

1. ER図が作成されればOK

    ![D_local___dokupro_app_-_MySQL_8_0_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/810ae080-229e-1dd8-e648-fda425cb7e79.png)

## 余談

「ER図のリレーションが描画されないんだけど」という方はこちら↓（外部キー制約が無いために描画されない場合のみ）

https://qiita.com/miriwo/items/b3d237b379d623ba4855
分散シェル(pdsh)を使ってサーバ管理を楽したい

本記事ではHPC（俗に言うスパコン)等の多ノードのサーバ管理を楽したいという方向けに作成しています。
今回は以下の手順で進めていきます。
* epelリポジトリの追加
* pdshのインストール
* ssh公開鍵の設定
* テスト

作業ノードは下記環境情報記載サーバのうち管理・ログインノードでroot作業します。

# 環境情報
| ノード名 | ホスト名 | IPアドレス | OS |
| ---- | ---- | ---- | --- |
| 管理・ログインノード | smm2-ln | 192.168.122.10 | Rocky Linux 8.9 |
| 計算ノード | smm2-cn00 | 192.168.122.20 | Rocky Linux 8.9 |
| 計算ノード | smm2-cn01 | 192.168.122.21 | Rocky Linux 8.9 |

# 構築準備
### ログインノードにepelリポジトリを追加
pdsh関連のパッケージをインストールするためにはepelリポジトリを下記コマンドで追加してください。
```
# yum install -y epel-release
```

### ログインノードにpdshをインストール
```
# yum install -y pdsh pdsh-mod-dshgroup pdsh-rcmd-ssh.x86_64
```

### ログインノードでssh公開鍵を作成
```
# ssh-keygen -t ed25519
```

### 計算ノードに作成した公開鍵を送りつける
```
# ssh-copy-id -i /root/.ssh/id_ed25519.pub root@192.168.122.20
# ssh-copy-id -i /root/.ssh/id_ed25519.pub root@192.168.122.21
```

### パスワードレスでログインノードから計算ノードにrootログインできるか確認。
```
# ssh 192.168.122.20
# ssh 192.168.122.21
```

### ログインノードの/etc/hostsに計算ノードのホスト名とIPアドレスを記載
```
# vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.122.20  smm2-cn00
192.168.122.21  smm2-cn01
```

### ホスト名でログインノードから計算ノードにrootログインしてみる
```
# ssh smm2-cn00
# ssh smm2-cn01
```

# pdsh設定
### グループ定義作成
ログインノードに以下のディレクトリを作成し、作成したディレクトリ配下にグループを定義します。
今回はcnというグループ名で定義していきます。

```
# mkdir -p /etc/dsh/group/
# vim /etc/dsh/group/cn
smm2-cn00
smm2-cn01
```

### pdshテスト
下記のようにコマンド結果が返ってくればpdshの導入は完了です。
```
# pdsh -g cn "cat /etc/redhat-release" | dshbak
----------------
smm2-cn00
----------------
Rocky Linux release 8.9 (Green Obsidian)
----------------
smm2-cn01
----------------
Rocky Linux release 8.9 (Green Obsidian)
```
【初心者】Reactのコンポーネントとは

## コンポーネントとは
アプリのための再利用可能な UI 要素。

### 例
React では、マークアップと CSS と JavaScript を、独自の “コンポーネント” と呼ばれる、再利用可能な UI 要素にまとめることができる。
```
<article>
  <h1>My First Component</h1>
  <ol>
    <li>Components: UI Building Blocks</li>
    <li>Defining a Component</li>
    <li>Using a Component</li>
  </ol>
</article>
```
上記にある目次のためのコードを、TableOfContents と呼ばれるコンポーネントにすることができるのだ。
```
<PageLayout>
  <NavigationHeader>
    <SearchBar />
    <Link to="/docs">Docs</Link>
  </NavigationHeader>
  <Sidebar />
  <PageContent>
    <TableOfContents> <!-TableOfContentsコンポーネントを実装した–>
    <DocumentationText />
  </PageContent>
</PageLayout>
```
既に書いたコンポーネントを再利用することで構築できるようになり、開発速度がアップする。

## 参考
https://ja.react.dev/learn/your-first-component
型アサーションをLintで禁止にしたい

# 1. 結論

https://www.npmjs.com/package/eslint-plugin-no-type-assertion

こちらを使うと良いそうです！

# 2. 背景
```ts
const elm = hoge as HTMLInputElement;
```

このような記述はよく見ると思います。
型アサーションはその変数が如何なる値でも```as```の後の型として型チェックされます。
その為、実行時にエラーが起きることもあります。
社内では極力使わないようにしたいというコーディングルールになっています。

そこでeslintで、そのようなルールはあるのか調べて見ようと思ったのが経緯です。

# 3. 型アサーションを禁止にするプラグインを調査
以下がヒットしました。
typescript-eslintと、tslintでありそうです。

https://github.com/typescript-eslint/typescript-eslint/issues/1310

## 3.1. typescript-eslint
- [no-unnecessary-type-assertion](https://typescript-eslint.io/rules/no-unnecessary-type-assertion/)

>This rule reports when a type assertion does not change the type of an expression

不要な型アサーションを禁止にするものです。

## 3.2. TsLint

tslintにもno-unnecessary-type-assertionというruleがあったのですが、以下のようにdeprecatedされていました。

https://palantir.github.io/tslint/

>:warning: TSLint has been deprecated as of 2019.

## 3.3. EsLint
pluginでありました。

### eslint-plugin-no-type-assertion

https://www.npmjs.com/package/eslint-plugin-no-type-assertion

>Disallow type assertions in TypeScript code. The rule will forbid both as operator and the angle-bracketed syntax, unless used for const assertions or with the unknown type

これでできますね。
しかもconst assertionはエラーにしないのはありがたいです！

### ⚠️eslint-plugin-no-type-assertionは非Nullアサーションも禁止にしてしまう

>The rule also forbids non-null assertions.

https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#non-null-assertion-operator-postfix-

# 4.その他
## 型アサーションはcast(キャスト)とは異なる
https://typescript-eslint.io/rules/consistent-type-assertions

>Type assertions are also commonly referred as "type casting" in TypeScript. However, that term is technically slightly different to what is understood by type casting in other languages. Type assertions are a way to say to the TypeScript compiler, "I know better than you, it's actually this different type!".

型アサーションはcastともよく言われますが、厳密には違います。

# 5.参考
- [TypeScriptの as って何です？(型アサーションについて)](https://qiita.com/irico/items/9d71060e52ffc1e79962)

# 最後に
コーディングルールをlinterに任せて、レビュワーの負担を減らしたいです

[英語版の記事はこちら](https://dev.to/taiyama1212/encouraging-type-safety-strategies-for-disallowing-type-assertions-in-your-codebase-2cl2)
Railsで特定のコールバックを条件付きでスキップする方法

## 事象

`Rails` アプリケーションにおいて、モデルの `save!` メソッドを使ってデータを生成または更新する際、`before_save` や `after_save` コールバックを用いてデータ更新前とデータ更新後の処理を定義することが一般的です。しかし、特定のビジネスロジックの要件により、`after_save` の処理を条件付きでスキップしたい場合があります。例えば、バッチ処理中には特定のデータ更新後の処理を行いたくない、または特定の条件下でのみ処理を実行したい場合などです。

## 対処法

このような特定の条件下でコールバックをスキップするには、`attr_accessor` を使用してフラグを設定し、そのフラグに基づいてコールバック内の処理を実行するかどうかを制御します。以下はその具体的な実装例です。

```rb:custom_task.rake
namespace :custom_namespace do
  desc '特定の処理を実行する'
  task custom_task: :environment do
    Model.find_each do |record|
      # ここで特定の処理を実行
      record.skip_action = true
      record.save!
    end
  end
end
```

```rb:model.rb
class Model < ApplicationRecord
  attr_accessor :skip_action

  after_save do
    action unless skip_action
  end

  def action
    # ここでスキップしたいアクションを定義
  end
end
```

このコードでは、任意のモデル（ここでは `Model` としています）に `attr_accessor :skip_action` を追加しています。これにより、`@skip_action` というインスタンス変数が定義され、この変数を使って `after_save` コールバック内で条件分岐を行います。`skip_action` フラグが `true` の場合、`action` メソッドの呼び出しをスキップします。

## まとめ

この方法を用いることで、`Rails` アプリケーションにおいて特定の条件下でのみコールバックを実行するかどうかを柔軟に制御できます。ただし、このアプローチを使用する際は、コールバックをスキップすることの副作用を十分に理解し、適切なシナリオでのみ使用することが重要です。コールバックのスキップは、予期せぬバグやデータの不整合を引き起こす可能性があるため、慎重に行う必要があります。

自らの備忘録のために投稿してますが、なにかお役に立てましたら幸いです！:clap:
また、なにか間違ってましたらご指摘いただけますと幸いです！:pray:
JuliaとPythonの組み合わせ

# はじめに
最近、Juliaを用いたデータ処理が増えてきました。
そこで、Juliaで処理するデータを用意し、Pythonで処理できるのか？という疑問から今回の記事をまとめたいと思います。

# Julia + Python
今回は、Juliaでデータフレームを作成し、`PyCall`を用いてデータフレームを処理していきたいと思います。
`PythonCall`の方が良いとかいう噂もありますが、個人的に`PyCall`の方が使いやすいんですよね…(´・ω・｀)

ということで、まずはデータフレームを作っていきましょう。

```julia
using DataFrames
using PyCall
using Conda;Conda.add("pandas")

df = DataFrame(A = 1:4, B = ["M", "F", "F", "M"])
```

Pythonのパッケージ管理も`Conda`と`CondaPkg`どちらがいいんですかね…
これも適当に決めてます(;'∀')

とりあえず、データは作成できました。
ここで、問題がひとつ。
Juliaで作成されたデータフレームをPythonのpandasで処理しようとすると、型やらなんやらでエラーが発生してしまいます。
そこで、一度辞書に変換して、pandasでデータフレームに変換します。

```julia
function dataframe_to_pydict(df::DataFrame)
    pydict = Dict{Symbol,Any}()
    for name in names(df)
        pydict[Symbol(name)] = getproperty(df, name)
    end
    return pydict
end

pydict = dataframe_to_pydict(df)
```

これを`PyCall`を用いて、Pythonのコードを書いて実行してみましょう。

```python
@pyimport pandas as pd
py_df = pd.DataFrame(pydict)
py_df.drop(columns=["A"])
```

はい、お馴染みのPythonそのまんまのコードを書くだけですね。

# まとめ
今回は、普段ではほぼ有り得ないようなデータ処理を行いましたが、JuliaとPythonを組み合わせてデータ処理をすることは可能だということが分かりました。
以前、Pythonでcsvファイルを読み込もうとしたとき、エンコーディングの関係でうんともすんとも言わず、Juliaでエンコーディングしたところ一発で読み込めたことがあります。
そういったときには今回の内容は役に立つのかなと思います。
まあ、そのままJuliaで書いた方が早い説もありますが、Juliaに慣れていない人からすると、Pythonのコードを書けるなら便利ということもあるかもしれません。
もっと複雑な処理になると組み合わせも困難になるとは思いますが、そのときはそのとき…(/・ω・)/
それでは！！！
LangChain: AgentExecutor の action 解析

# 背景

LangChain で、OpenAI Tools Agent を使った際に、Agent が Tool をどう使ったかを表示したかった。
その際の備忘録

# 結論

> return_intermediate_steps=True

を設定して、以下のようにして変換したら、あとは Front で 思考の連鎖として表示してやれば OK

```python: intermediate steps を分解
def serialize_intermediate_step(step):
    return {
        "tool": step[0].tool,
        "tool_input": step[0].tool_input,
        "log": step[0].log,
        "message_log": str(step[0].message_log),
        "tool_call_id": step[0].tool_call_id,
        "output": str(step[1]),
    }
```

```python: 利用例
thoughts = str([serialize_intermediate_step(step) for step in response["intermediate_steps"]])
```

# 詳細

1. return_intermediate_steps を設定して
   > agent_executor = AgentExecutor(
        agent=agent, tools=tools, verbose=True, **return_intermediate_steps=True**
   )

2. Invoke() したら、以下で取得可能
   > response["intermediate_steps"])
   
ドキュメントは以下参照

https://python.langchain.com/docs/modules/agents/how_to/intermediate_steps

# あとがき

Agent は便利、だけど思った通り動かすのが一苦労
実際のSampleをもっと見ないと・・
Rubyのライブラリについて

## ライブラリとは？
ライブラリは、特定の機能を実現するためのプログラムを部品化し、再利用可能な形式にしたものです。ライブラリを活用することで、さまざまな機能を追加できるようになります。

## ライブラリの種類
ライブラリは大きく3種類あります。

- **組み込みライブラリ** 
Ruby言語自体に最初から組み込まれているライブラリです。これらのライブラリはRubyの標準機能として提供され、追加の設定やインストールは不要です。

  <例>
  - String
   splitなど文字列の操作や処理を行うためのメソッドを提供します。   
 
  - Array
   push、popなど配列を操作するためのメソッドを提供します。

- **標準ライブラリ**
Ruby言語には標準的なライブラリが含まれていますが、組み込みライブラリではないものです。これらのライブラリはRubyの標準インストールに含まれていますが、必要に応じて手動で読み込む必要があります。

  <例>
  - Date
   日付や時間を表現し、操作するためのクラスやメソッドを提供します。
  - File
   ファイルの操作やファイルパスの解析、ファイルの属性の取得などを行うためのクラスやメソッドを提供します。
            
- **Gem**
GemはRubyプログラムやライブラリのパッケージ管理システムです。GemはRubyの標準ライブラリや組み込みライブラリとは異なり、外部から追加できるライブラリです。
  - Gemの使い方
ターミナルやコマンドプロンプト上で`gem install Gem名`を実行することでインストール可能です。インストールしたGemは、プログラムの中でrequireメソッドを実行することで利用可能になります。それぞれのGemの使い方は、Gem名で検索してドキュメントを確認してみてください。
        
   - Bundler
一つずつインストールするのも大変なので、複数のGemを簡単に管理するBundlerという仕組みがあります。
   - BundlerでGem群をインストールする方法  
      1. 使用するGem群をかいたGemfileという名前のファイルを作成します。
            ```ruby
            # Gemfile
            # gem 'gem名', 'バージョン'
            gem 'rails', '6.1.4'
            gem 'devise', '4.8.1'
            ```     
      2. `bundle install`コマンドの実行
      bundle installコマンドを実行するとGemがインストールされます。また、bundle installコマンドを実行すると、Gemfile.lockというファイルが作成されます。Gemfile.lockには使われているGem名とそのバージョン情報などが記録されています。

  <例>
    - Rails
Webアプリケーションを開発するためのフレームワークです。ルーティング、モデル-ビュー-コントローラー（MVC）のパターン、データベースの操作などを提供します。
    - Devise
認証システムを追加するためのGemで、ユーザーの認証、サインアップ、サインインなどの機能を提供します。
転職ドラフトを利用して年収が1.5倍になった話

### はじめに
昨年の12月中旬に転職ドラフトを通じて転職を行いました。
その時の振り返りを兼ねて、まとめていきたいと思います。

もともとかなりの転職をしており、全てIT企業に務めていて現在の会社で５社目となります。
おそらくですが、IT企業の少ない地方在住でこれはかなりの回数ではないでしょうか。
少なくとも私の周りにこの回数の転職を行っている人はいませんでした。
(もちろん誇れることではないですが・・・)

### きっかけ
転職ドラフトを利用しようと思ったきっかけは「自分の市場価値を知りたい」がスタートでした。
以前Qiitaで転職ドラフトを利用したという記事(どの記事か調べたのですが、見つけられませんでした。)を見て「へー、こんなのがあるんだー」ぐらいに記憶しており、試しにやってみようという感じです。
すぐに転職したくて登録したわけではなく、Webエンジニアとして「自分のスキルの棚卸し」と「市場価値の確認」を行った感じです。
そのついでに良い会社があればいいなーぐらいの感覚でした。

### レジュメの登録
X(Twitter)などでよく「レジュメが転職ドラフトの審査が通過しない」みたいな投稿を目にしました。
なので転職ドラフトで公表されている[記載方法](https://job-draft.jp/articles/443)などをよく読み、できるだけ問題がないように記載を心がけたところ一発で通過することができました。
特に私が気をつけた点として、各プロジェクトごとの「目標」「課題」「工夫」を具体的に記載することです。
面倒でも自分が何をやってきたのかを**具体的**に記載しないと審査を通過することができないように思います。

例としては以下のようになります。
```
# 取り組んだ課題
### 作業工数の均一化対応
- 作業の均一化ができるようにフローを作成

【課題1】
- 対応が属人化しており残業時間に偏りがでる

【工夫1】
- マニュアルを作成することで、誰にでも対応できるようにした

【成果1】
- 一部の人に偏っていた残業時間を均一化
- 残業が多かった人から20時間の削減
```

大切なのは**実際の数値**なのかなと思います。
やはり目に見える値というのは強みが伝わりやすいと思います。

レジュメの登録が終わったらドラフトの開始まで待ちとなります。

### 転職ドラフトの開始
ドラフトが始まったら参加企業の確認をしてください。
始まるまでは今回のドラフトに参加している企業はわからないので、始まってからの確認が必要です。

また必ず**ラブコール**を積極的に利用してください。
ドラフトに参加するを登録していても、実際に活動しているかをラブコールで判定している企業もあるようです。
ラブコールを送った企業以外からも含めて指名されるか否かは、ラブコールを利用しているが重要になるかと思います。

### 指名後の流れ
まずはカジュアル面談を実施します。
私は5件の指名をいただきましたが、全て話しを聞くようにしました。
余談ですが、ありがたいことに全ての企業が前職の年収を大きく超えるものでした。

その際に注意したいのが**なるべく早めにアクションを起こす**ことです。
当たり前ですが、あなた以外にも企業は指名をしており、その枠を争うことになるという意識は大切です。

実際に選考に進んでいる中で、他の人を採用したので見送りますと連絡を受けたこともありました。
なのでドラフトが終わるまで返答を待つのではなく、興味があったらできるだけ早めに日程調整を行ったほうがいいと思います。

カジュアル面談後はそれぞれの会社の採用の流れがあるかと思いますので、そちらに沿って進む形になります。

**転職ドラフト**を利用している会社なだけあって、コーディングテストを行う企業は多くありました。
中にはしっかりと確認してくれているようで細かい指摘をしてくれたのが、かなり勉強になりました。

### 最後に
スケジュール調整など自身で行うのはかなり手間ではありますが、年収アップにつながると思ってがんばってください！
いくつかの転職エージェント、転職サイトを利用しましたが**転職ドラフト**ほど高い年収を提示してくれるサービスはありませんでしたので、年収を上げたい人にとってはおすすめです。

もし興味があって転職ドラフトに登録することがあったら是非紹介コードを利用してください。

```
IRXJ
```

転職せずともレジュメの審査が通れば、3,000円のアマギフがもらえるのでかなりお得かと思います！

[こちらの記事は転職ドラフト体験談投稿キャンペーンに参加しています](https://job-draft.jp/articles/251)
Windows11 ドライバーの不具合とこのPCへのプロジェクション

余っているノートパソコンやタブレットにPCの画面を拡張しようとしてが不具合による戦いの記録をここに記す。

拡張ディスプレイをするために使用したのはWindows標準の、このPCへのプロジェクション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/9e5c8ad5-b74a-43d4-4714-13bdef07a4e3.png)

それとSpaceDeskTopというアプリ

https://www.spacedesk.net/

## 結果
不具合解消にはOSのクリーンインストールで解決した。
同じような不具合が起きた時は面倒だけどクリーンインストールしたほうが時間の無駄にならなかった。

## 主な原因と思われること
デバイスマネージャを見ると！マークになっておりドライバが上手く機能していないと思われる。
PCへのプロジェクションでは接続する段階でなにも反応がなくディスプレイの拡張できなかった。

## やったこと
ドライバーの再インストール
Windows Microsoftのチャットヘルプ
アプリやファイルを失わずにOSを再インストール（クリーンインストールの一つ前の手順）

## 教訓
復元ポイントをこまめ作っておくこと。
Windowsのヘルプでも解決しないこともある。
デバイスドライバーは削除できているのできてないのかよくわからん
【Vuetify3】Tooltipで表示される値を可変にしたい

## はじめに

Vuetify3にはTooltipという、ボタンにHoverすると設定しておいた情報を表示する機能があります[^1]。

|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　　　　　|
|:-:|
|![tooltip1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/b9fc76b4-5998-cbfa-d18e-e5d14c139b0c.gif)|
<font color="gray">左のボタンにHoverすると右の黒いボタン部分が表示される</font>

https://vuetifyjs.com/en/components/tooltips/

可変の値を表示するのに少し苦戦したので、記録しておきます。

## 公式サイトのサンプルコード

まず、上の動画のように指定した文言を単純に表示したい場合、公式サイトにあるサンプルコードで問題なく動作します。

`<v-tooltip text="Tooltip">`の`""`内に表示したい文字列を入れるだけです。

```html
<template>
  <v-app>
    <v-container>
      <v-tooltip text="Tooltip">
        <template v-slot:activator="{ props }">
          <v-btn v-bind="props">HOVER OVER ME</v-btn>
        </template>
      </v-tooltip>
    </v-container>
  </v-app>
</template>
```

## 可変な値を表示するサンプルコード

では、表示したいのが可変の値の場合はどうするか。

例として、0~9の値をランダムに生成して返す関数の返り値を表示します。

```javascript
function getRandomInt(max) {
    return Math.floor(Math.random() * max)
}
```

素直に考えると`text="{{ getRandomInt(10) }}"`で動作しそうですが、、それでは駄目でした。

|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　　　　|
|:-:|
|![スクリーンショット 2024-03-01 21.16.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/f5bc4cb6-28b9-d67b-ec31-7699f2e4628d.png)|
<font color="gray">二重括弧と関数名がそのまま表示されてしまう</font>

`<template>`の下に`<span>`タグを設置し、そこに指定すると上手く行きました！

```html
<script setup>
function getRandomInt(max) {
    return Math.floor(Math.random() * max)
}
</script>

<template>
  <v-app>
    <v-container>
      <v-tooltip>
        <template v-slot:activator="{ props }">
          <v-btn v-bind="props">HOVER OVER ME</v-btn>
        </template>
        <!-- この下に指定 -->
        <span>{{ getRandomInt(10) }}</span>
      </v-tooltip>
    </v-container>
  </v-app>
</template>
```

Hoverするたびに関数が実行され、ランダムな値を表示できます。

|　　　　　　　　  　　　　　　　　   |　　　　　　　　  　　　　　　　　   |
|:-:|:-:|
|![スクリーンショット 2024-03-01 21.26.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/84f574c3-882d-3605-e070-b1e5e4840a65.png)|![スクリーンショット 2024-03-01 21.26.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/b18e7c31-45bb-035c-e2b1-04aeb4afae48.png)|

## 終わりに

中盤に書いた`text="{{ getRandomInt(10) }}"`で上手くいかなかったので色々試していたところ、公式サイトのVisibilityのサンプルコードで`<span>`タグに文字列を書くやり方をしていたので、真似したらたまたま上手く行きました。

https://vuetifyjs.com/en/components/tooltips/#visibility

もうちょっと親切に例を書いておいてくれればいいのに、、と思ったので記録しておきます。

[^1]:Tooltipを表示する位置は上下左右どこでも指定できます。詳しくは公式サイトをどうぞ。
laravelでseederを使う

## Seederファイルの作成
Seederファイルはこのコマンドで作成します。
```
php artisan make:seeder AnimalSeeder
```

## Seederファイルの実行
下準備として、デフォで用意されている"DatabaseSeeder"に自作のSeederを登録します。
```php:DatabaseSeeder.php
<?php

namespace Database\Seeders;

use App\Models\User;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        
        //自作Seederを登録
        $this->call(AnimalSeeder::class);
    }
}
```
登録した上で、下記を実行するとDBに値が追加されます。
```
php artisan db:seed
```


## 特定のseederだけを実行したい
上記の"php artisan db:seed"を実行すると
全てのSeederが実行されてしまいます。
(すでにデータが入っているテーブルにまた同じ内容でデータが追加されてしまいます。)
特定のSeederだけ実行する時は、下記を使います。
```
php artisan db:seed --class=FruitSeeder
```
STYLYでイベント処理を特定の周期上で同期したい

# はじめに
そんなことあるんか...？
というタイトルですが、実際に実装することがあり、前例が見つからなかったので残しておきます。

例えば、、、
同じ長さの複数の音源を用意して、体験者の行動に合わせて再生するループ音源を増やしたり減らしたい！
みたいな、インタラクティブなオーディオビジュアルコンテンツをSTYLTで制作する人に役立つと思います。

まだイメージわかない、という方のために
こんな感じ、というものを用意しました。
以下のシーンでCapsuleに近づいたり離れたりしてみてください。

https://gallery.styly.cc/scene/66180952-10e2-420e-b265-72dbf899fde4


今回はPlaymakerを利用しました。

# シーン解説
先ほどのシーンでは、プレイヤーと配置されたCapsuleの距離に応じて、Capsuleの色と再生される音源の数が変化するようになっています。

プレイヤーとCapsuleの距離が、あらかじめ定めた距離より遠い場合はCapsuleが白色、近い場合は赤色になり、白色の場合は2つの音源のみ再生し、赤色の場合は3つの音源が再生されます。
ただし、プレイヤーとCapsuleの距離が、あらかじめ定めた距離をまたいで変化した場合、Capsuleの色は常に黄色になり、再生される音源の数は変わりません。次に音源が頭から再生されるタイミングで、Capsuleは白色か赤色になり、再生される音源の数も決定されます。

つまり、プレイヤーが遠くからCapsuleに近づくと、Capsuleの色は白→黄→赤と変化します。
一定の範囲に近づくと黄色になりますが、次に音源が頭から再生されるタイミングまでは赤色になりません。
音に注目すると、音源が再生されている途中でプレイヤーがCapsuleに近づいても、すぐには音源の数は増えず、音源が頭から再生されるタイミングで、音源の数が増えていることが分かると思います。
音源を再生するタイミングの同期がとれていますね。

# 同期の取り方
同期の取り方と実装方法です。
UnityのAnimatorを使います。
Unityのシーン上に、VirtualClockという名前のオブジェクトを用意しました。

もうお分かりかと思いますが、Animatorの遷移のタイミングを同期の基準にしています。
![アニメーション遷移](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3724937/318cdf6b-3a69-fac2-f1c4-b1d20542bd02.gif)
あとは遷移のタイミングをPlaymakerのActionである、Get Animator Current Transition Info Is Nameで検知し、そのタイミングでイベントを進めてあげるだけです。

今回のような音源再生の場合、Audio Sourceのenabledを切り替える実装では、上手く同期しないことがあったので、muteを切り替えるのが良いと思います。
Audio以外のイベント処理も問題なく同期することができました。
いろいろと応用が利くと思います。

# おわりに
STYLYもPlaymakerも音楽も何もわからん...！のまま作ったものなので、もっと良い方法があるかも。。。
お知恵がある方、教えてください。
laravelでローカルでsqliteを利用してDBの環境構築

laravelでローカルでsqliteを利用してDBの環境構築する方法をいつも忘れてしまうのでやり方をメモします。

まずconfigディレクトリのdatabase.phpの一部を次のように修正します。

```diff_php:database.php
<?php

use Illuminate\Support\Str;

return [

    /*
    |--------------------------------------------------------------------------
    | Default Database Connection Name
    |--------------------------------------------------------------------------
    |
    | Here you may specify which of the database connections below you wish
    | to use as your default connection for all database work. Of course
    | you may use many connections at once using the Database library.
    |
    */
-  'default' => env('DB_CONNECTION', 'mysql'),
+  'default' => env('DB_CONNECTION', 'sqlite'),

    //以下省略
```

続いて、.envファイルを以下のように修正します

```diff_php:.env
+ DB_CONNECTION=sqlite
-  DB_HOST=**＊＊＊
-  DB_PORT=＊＊＊
-  DB_DATABASE=＊＊＊
-  DB_USERNAME=*＊＊＊
-  DB_PASSWORD=*＊＊＊
```

最後に、database.sqliteをdatabaseディレクトリ直下に作成します。
![sqlite2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/af02aaa6-3350-0d61-e898-1d4c9f2f87e7.png)

以上で完了です。
スッキリわかる SQL入門を読んでみた

## はじめに
スッキリわかるSQL入門を読んだので、感想などをまとめてみました。

## 内容
第1章　はじめてのSQL
第2章 基本文法と4台命令
第3章　操作する行の絞り込み
第4章 検索結果の加工
第5章　式と関数
第6章 集計とグループ化
第7章 副問い合わせ
第8章　複数テーブルの結合
第9章 トランザクション
第10章 テーブルの作成
第11章 さまざまな支援機能

## 良かったところ
 dokoQLというクラウドサービスを使って学習できる為、初心者がつまずきやすい環境構築を行わず、実際に手を動かしながら学習できるので良いと思いました。
　章ごとに練習問題が作られており、インプットとアウトプットを交互に行えるので、効率的に学習できました。


## 学んだこと
SQL
- データーベースに格納されている情報を検索したり、書き換えたりする為に使用される操作言語

RDB(リレーショナルデーターベース)
- 複数の表が入っており、個々の表を`テーブル`と言う
- テーブルは、行と列で構成される

4大命令
- SELECT -  テーブルから目的のデータを指定して取得する
```    
      SELECT 列名...
      FROM テーブル名
```
- UPDATE - テーブルに存在しているデータを書き換える
```
UPDATE テーブル名
   SET 列名1 = 値1, 列名2 = 値2
```
- DELETE - テーブルに存在している行を削除する
```
DELETE 
  FROM テーブル名
```  
- INSERT - 新しいデータを追加する
```
INSERT INTO テーブル名
            (列名1, 列名2, 列名3,)
     VALUES (値1, 値2, 値3)
```

 WHERE句
　1. 処理対象の行の絞り込みに用いる
　2. SELECT、UPDATE、DELETE文で使用可能
　3. WHEREの後ろに条件式を記入する
　4. WHERE句に記述できるのは結果が必ず真(TRUE)または、偽(FALSE)になる条件式にする
```
WHERE 条件式
```
NULL
- 値が不明または、無意味であるためにデータが格納されてない状態を表す

検索結果の加工
- DESTINCT - 重複行を除外する
- ORDER BY - 結果を並び替える
- OFESET-FETCH - 行を限定して取得する
- UNION、EXCEPT/MINUS、INTERSECT - 結果を集合演算する


関数
- 引数に対して決められた処理を行い、戻り値に変換する
- 処理の内容に応じて、文字列関数、算術関数、日付関数、変換関数などに分類される

集計関数
- 検索対象の全行をまとめて、集計処理を行う
- 集計関数の結果は、必ず1行になる

代表的な集計関数
- SUM → 各行の合計値を求める
- MAX → 各行の最大値を求める
- MIN → 各行の最小値を求める
- AVG → 各行の平均値を求める
- COUNT → 行数をカウントする

グループ化
- グループ分けの基準となる列を指定することで、グループ別に集計できる

```
SELECT グループ化の基準列名, 集計関数
　FROM　テーブル名
 WHERE 絞り込み条件
 GROUP BY グループ化の基準名
```

テーブルの結合
- テーブルを分割しデータを安全、確実、高速に取り扱うために行う

```
SELECT 選択列リスト
  FROM テーブルA
  JOIN テーブルB
    ON 両テーブルの結合条件
```

トランザクション
- 複数のSQL文を1つの命令として扱うことができる
- DNBSは、トランザクションに含まれるすべてのSQL文について、必ず「すべての実行が完了している」か「1つも実行されていない」かのどちらかの状態になるようにする

テーブルの作成
- 
```
CREATE TABLE テーブル名 (
  列名1 列1の型名,
  列名2 列2の型名,
  :
  列名X 列Xの型名
)
```
テーブルの削除
```
DROP TABLE テーブル名
```

テーブル定義の変更
```
列の追加
ALTER TABLE テーブル名 ADD 列名 型
```
```
列の削除
ALTER TABLE テーブル名 DROP 列名
```

制約
- テーブル作成時に各列に制約を制定し、予期しない値が格納されないようにする

インデックス
- テーブルの列に対して、索引を作れる
- インデックスが存在する列に対する検索は、高速になる


## 難しかったこと
テーブル設計の部分は、個人的に難しく、まだまだ理解が浅いなあと感じました。


## 参考文献
[スッキリわかるSQL入門　第３版](https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BSQL%E5%85%A5%E9%96%80-%E7%AC%AC3%E7%89%88-%E3%83%89%E3%83%AA%E3%83%AB256%E5%95%8F%E4%BB%98%E3%81%8D-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8B%E5%85%A5%E9%96%80%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B1%B1/dp/4295013390/ref=sr_1_1?adgrpid=51361540737&hvadid=658841395612&hvdev=c&hvlocphy=9162130&hvnetw=g&hvqmt=e&hvrand=16054762148403698574&hvtargid=kwd-333587866250&hydadcr=27265_14678545&jp-ad-ap=0&keywords=%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8Bsql%E5%85%A5%E9%96%80&qid=1689765619&sr=8-1)
Vimを覚える【vimtutor Lesson 6】

# はじめに

前回の記事はこちらです。

https://qiita.com/kohki_takatama/items/441aa3744230feeaa059

# Lesson 6.1

`o`で「下に一行追加しインサートモード」です。

大文字の`O`だと「上」に行を追加し、同じくインサートモードに入ります。

# Lesson 6.2

`a`で「カーソルの後からインサートモード」ですね。<font color="DarkGray">（まだやってなかったのか・・・）</font>

使い方は`i`に似ています。
`i`では「カーソルの位置（あるいは前）からインサート」でした。
# Lesson 6.3

`R`で「上書きモード」です。

置き換え、上書き系を振り返ります。

例として、以下のテキスト行を考えましょう。

```
This is a test line.
```

カーソルが`a`の上にあると仮定し、各コマンドを`x`で適用します

| コマンド | 説明                             | 実行前                                | 実行後                                              |
| ---- | ------------------------------ | ---------------------------------- | ------------------------------------------------ |
| `s`  | 現在の文字を削除し、指定した文字で置き換えて挿入モードに入る | `This is a test line.` (カーソルが`a`上) | `This is x test line.`<br> (挿入モードになる)            |
| `S`  | 現在の行を削除し、指定した文字で置き換えて挿入モードに入る  | `This is a test line.`             | `x` (新しい行に`x`が挿入され、挿入モードになる)                     |
| `r`  | 現在の文字を指定した文字で置き換える             | `This is a test line.` (カーソルが`a`上) | `This is x test line.` <br>(ノーマルモードのまま)          |
| `R`  | 上書きモードに入り、以降の文字を指定した文字で置き換える   | `This is a test line.` (カーソルが`a`上) | `This is x` (以降の文字を置き換えられる状態)                    |
| `c`系 | 現在の文字から指示した箇所までを削除し、挿入モードに入る   | `This is a test line.` (カーソルが`a`上) | `This is x test line`<br>(挿入モードになる)<br>(`cw`の場合) |

# Lesson 6.4

<font color="Orange">`y`でコピー！</font>ですね。
Vimではコピーすることを「ヤンク（yank）」と呼び、その頭文字の`y`でコピーを表します。

<font color="Orange">また、`p`でペースト</font>をします。
「ペースト（paste）」の`p`ですね。

# Lesson 6.5

`:set`でオプションを指定してみよう！の章ですね。

<font color="Orange">`:set ic`で大文字・小文字を区別しなくなります</font>。

<font color="Orange">`:set hls`で検索結果がハイライトされる</font>ようになります。

<font color="Orange">`:set is`で検索語を入力したときリアルタイムで検索結果が表示される</font>ようになります
# Lesson 6 修了！

おつかれまでした！！

# おわりに

オプションで便利になっていくのがワクワクでした。

次がラストです！！
ConoHa WING に Drupal をインストールする

デジタル庁や日本行政書士会連合会などのサイトが、Drupalになったそうなので、Drupalに入門しています。

## やりたいこと

ConoHa WING（VPSではなく共用サーバーの方）に、Drupal10をインストールしたい。

## 環境

- [ConoHa WING](https://www.conoha.jp/wing/)
- PHP 8.2
- [Drupal](https://www.drupal.org/) 10.2.3

## ConoHa WINGで、SSHとComposerを使えるようにする

SSHの設定方法は、[ConoHa WINGのサポートページ](https://support.conoha.jp/w/sshaccount/)が役に立ちます。

Composerの設定方法は、「[Conoha WingでComposerをインストールする](https://zenn.dev/teba_eleven/articles/d172e8ffabb911)」の記事などを参考にしました。

## Drupalをダウンロード

[Drupalのユーザーガイド](https://www.drupal.org/docs/user_guide/en/install-composer.html)を参考に、Composerでダウンロードします。

かいつまんで言えば、以下のコマンドを実行したいのですが、実行するときのディレクトリ構造が考えどころです。

```
composer create-project drupal/recommended-project mydir
```

ConoHa WINGの場合、public_htmlディレクトリの中に、独自ドメインやサブドメインの公開ディレクトリが入っているはずです。

```
~/
└── public_html/
    └── example.com/
```

今仮に、https\://example.com/ にアクセスしたときに、Drupalのトップページにアクセスしたいとします。
そのような場合、以下のようなシンボリックリンクを張りたいことになります。

```
~/
└── public_html/
    ├── drupal/
    │   ├── web/
    │   └── vendor/
    └── example.com -> drupal/web/
```

シンボリックリンクの張り方は、「[Conoha WINGでドメインルートにシンボリックリンクを張る](https://chaosplant.tech/tech-notes/page35/)」という記事が参考になります。

以上から、次のようなコマンドを実行することになります。

```
chmod 755 ~/public_html
cd ~/public_html
rmdir example.com
composer create-project drupal/recommended-project drupal
ln -s drupal/web example.com
```

composer.jsonのあるディレクトリ（上記の場合は~/public_html/drupal/）で、composer updateしておきます。

## データベースとデータベースユーザーを作る

データベースは、ConoHa WINGのコントロールパネルで作れます。

データベース作成は、[ConoHa WINGのサポートページ](https://support.conoha.jp/w/createdatabase/)に記事があります。
データベースユーザー作成も、同じく[サポートページ](https://support.conoha.jp/w/createdatabaseuser/)があります。

インストール時に必要になるので、ここで設定したパスワードなどを忘れないようにメモしておきます。

## インストール画面から手続き

ここまでできたら、シンボリックリンクを張ったドメインにアクセスしてください。

インストール画面になるはずです。
あとは、指示のとおりに進めていけば良いはずです。

ただし、drupal10のバグのようなのですが、インストール途中に、mbstringのエラーが出ました。
その場合は、コントロールパネルから、mbstringのPHP設定をします。

### mbstringの設定

「[Drupal 10のインストール時のバグ？を解決する](https://ccrr.catmullcube.com/drupal-mbstring/)」というページが参考になりました。

ConoHa WINGの場合は、[php設定のサポートページ](https://support.conoha.jp/w/configphp/)のとおりに、以下の１行を追記すれば良いです。

```
mbstring.encoding_translation=0
```

## CSSがおかしいとき

わたしの環境では、インストール後、cssやjsが適用されませんでした。
500エラーになり、画面表示が崩れます。

そのようなときは、環境設定->開発->パフォーマンスから、「CSSファイルを結合する」及び「JavaScriptファイルを集約」のチェックを外すと、きちんと表示されるようです。

ただしこのままでは、当然のことながらパフォーマンスは落ちるので、「[Drupal8.2.4をインストール後、テーマが変です](https://groups.drupal.org/node/515730)」というページを参考に、`.htaccess`を編集しました。
【Vuetify3】ファイル名が長すぎたら省略して表示したい

## はじめに

Vuetifyの`<v-file-input>`タグでは、ファイル名が長いときに入力欄からはみ出してしまいます。

|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　　　　　|
|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/c7171fba-052e-e1fa-14db-e09d3c694398.png)|
<font color="gray">長いファイル名がはみ出す</font>

この問題の対処法を調べたのでまとめておきます。

## バージョン

- Vue 3.4.9
- Vuetify 3.5.6

## truncate-lengthは利用できない

調べてみると、**Vuetify2では**`truncate-length`属性を設定することで、一定以上の文字数になったときにtruncateしてくれるようでした。

- [[Bug Report] File input truncated to fixed amount of characters](https://github.com/vuetifyjs/vuetify/issues/9026)
- [how to alter truncate-length in v-file-input of vuetify on responsive?](https://stackoverflow.com/questions/72802205/how-to-alter-truncate-length-in-v-file-input-of-vuetify-on-responsive)

しかし、Vuetify3では`truncate-length`属性は使用できないようです。

- [[Feature Request] Auto truncate length for v-file-input](https://github.com/vuetifyjs/vuetify/issues/9349)
    >  Why is the truncate-length prop removed in the latest version?

公式ドキュメントのv-file-input APIのページを見ると、Vuetify2では`truncate-length`の記述があるのに対し、最新版には存在しませんでした。。

- [v2のv-file-input API](https://v2.vuetifyjs.com/en/api/v-file-input/#props)
- [最新版のVFileInput API](https://vuetifyjs.com/en/api/v-file-input/#links)

一応試してみましたが、やはり効きませんでした。

諦めて他の手を考えます。

## 代替手段text-truncateの利用

クラス名に`text-truncate`を指定することで意図通りの動作になりました。

|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　　　　　|
|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/3b7250db-314f-1695-251e-5cd70fe75eda.png)|
<font color="gray">はみ出さずに切り詰められる</font>

- [Text and typography](https://vuetifyjs.com/en/styles/text-and-typography/#transform)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/f98bae42-2af8-e98a-72cd-b7d30d1923b9.png)

`truncate-length`と異なり文字数は指定できませんが、入力欄の幅に合わせてtruncateしてくれます。

### サンプルコード

```html
<template>
  <v-app>
    <v-container>
      <div>
        <v-file-input label="File input" class="text-truncate"></v-file-input>
      </div>
    </v-container>
  </v-app>
</template>

<style scoped>
  .v-file-input {
    width: 200px;
  }
</style>
```

## 終わりに

なぜVuetify3で`truncate-length`属性が利用できなくなってしまったのか、、便利そうなのに。
何か情報ある方、他に良い方法をご存知の方はぜひコメントお願いいたします！
Java9からの Modules の理解

確認して、ここに整理する予定。

https://www.oracle.com/jp/corporate/features/understanding-java-9-modules.html

https://openjdk.org/projects/jigsaw/spec/

https://openjdk.org/jeps/261

https://qiita.com/suema0331/items/121e23300527832cc117
Docker導入後のデプロイ


## 概要
GitHub ActionsでHerokuに自動デプロイしようとして苦戦した話。
Dockerを使用してビルドしようとしたらハマったのでどなたかのご参考になれば。

### 開発環境
Docker 20.10.7
Docker Compose 1.29.2
Ruby on Rails 6.0.6.1

## 結論
DockerによるHeroku containerでのビルドは行わず、通常のビルドパックでデプロイしたら成功した。


## 経緯
Heroku上でDockerを利用したHeroku containerでのビルドを試みたが、うまくいかない。Heroku公式によると推奨していない方法らしく、通常のビルドパックによるビルドが推奨されていた。

思いっきりHerokuダッシュボードのsettingに書いてあったが、読めていなかった。
ビルドパックによるビルドを選択（nodejsとrubyのビルドパック）。

下記のコードで`userdocer: false`を記述してDocker　containerによるビルドが行われないように指定。
```
name: deploy to heroku with Buildpacks

on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Check out code
        uses: actions/checkout@v4

      - name: Deploy
        uses: akhileshns/heroku-deploy@v3.13.15
        with:
          heroku_api_key: ${{secrets.HEROKU_API_KEY}}
          heroku_app_name: 'my-memoria'
          heroku_email: ${{secrets.HEROKU_EMAIL}}
          usedocker: false
```


事前にheroku.ymlを作成しており、不要となったProcfileを削除していたので再作成。
Dockerによるデプロイならheroku.ymlがあればデプロイできるが、Procfileがないとデプロイ時のアクションが実行されないので注意。
GitHub上で心霊現象に巻き込まれました・・・。

# 呪われたリポジトリ

こちらです・・・。

https://github.com/matoruru/haunted-repo

「**haunted-repo**」

不吉な名前です。

お化け屋敷ならぬ「**お化けリポジトリ**」ということでしょうか・・・。

# コミット履歴を見てみよう

https://github.com/matoruru/haunted-repo/commits/main/

# おわかりいただけただろうか

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/efaa3f75-72b6-dd3f-6a60-79b889bdb6dd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/f6b9bb0b-b4ad-e366-f14a-b5c910486a8a.png)

# 呪われているッ！！

なんと今回、ghost（幽霊）にコミットされてしまいました・・・。

お祓いに行こうかな・・・。

。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。

# 解説

`~/.gitconfig`の一部を一時的に以下のように書き換えてからコミットしました。

```
[user]
	name = Deleted user
	email = 10137+ghost@users.noreply.github.com
```

# Q＆A

### `~/.gitconfig`を変えずに、`git commit`のオプションで`--author "Deleted user <10137+ghost@users.noreply.github.com>" `を指定すればいいんじゃないの？

これは実際試してみたのですが、`~/.gitconfig`が上書きされるわけではないようで、下の画像のようになってしまいます（`--no-gpg-sign`オプションを付けても同様でした）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304979/45b5aa89-a93c-9eaa-d14f-e5d16a3e9a57.png)

---
### ghostのコミットは内容が空っぽだけど、どうなっているの？

何もステージせずにコミットしています。

これは`git commit`の`--allow-empty`オプションを使うと実現できます。

# 英語版の記事

https://dev.to/matoruru/i-got-haunted-on-github-46d9

# 参考

https://github.com/ghost
JMX(RMI/JRMP)がリスニングするIPアドレスを制限する


以下のように指定するとRMIレジストリがリスニングするアドレスを 127.0.0.1 のみに制限することが可能。
com.sun.management.jmxremote.host=127.0.0.1

デフォルトは 0.0.0.0 でリスニングするので、外部からも接続できる。
このオプションはJava9から指定可能。

https://www.oracle.com/java/technologies/javase/9-relnotes.html

https://bugs.openjdk.org/browse/JDK-6425769

RMIレジストリがJMXクライアント返却するスタブの接続先ホストを変更する場合は以下にように設定する。
java.rmi.server.hostname=localhost

ssh portfowardでjconsole接続するときなどに使う。
AWS CLF入門 - メッセージ編

## はじめに
AWS CLF (AWS Certified Cloud Practitioner) を取得した際の学習記録をアウトプットとして以下に記す。

## リンク
[ネットワーク](https://qiita.com/yashiuri/items/31b2c9c3c49c2584cd01)
[セキュリティ](https://qiita.com/yashiuri01/items/73e5310b09ff41912862)
[コンピューティング](https://qiita.com/yashiuri01/items/9eaf71a1590e7815f9ef)
[コンテナ](https://qiita.com/yashiuri01/items/708b57ee179ae29e72a9)
[スケーリング](https://qiita.com/yashiuri01/items/79050093aff66b0f0665)
[ストレージ](https://qiita.com/yashiuri01/items/6d48d81f5a1651dcc999) 
[データベース](https://qiita.com/yashiuri01/items/159ea63b197f7a836d1c)
[メッセージ](https://qiita.com/yashiuri01/items/d98772b540ef2201c4e2)
[モニタリング](https://qiita.com/yashiuri01/items/64f6dbf38603cdb4828a)
[デプロイ](https://qiita.com/yashiuri01/items/85151311897d6afd429c)
[コストとサポート](https://qiita.com/yashiuri01/items/bac23130a43d62677330)
[移行とイノーベーション](https://qiita.com/yashiuri01/items/6e327034a7c50d56ca88)
[AWS用語集](https://qiita.com/yashiuri01/items/bd36c99623ca596b76e4)


## メッセージ

### **Amazon SNS (Simple Notification Service)**

- フルマネージド型メッセージングサービス
- 疎結合が可能になる
- Pub/Sub (Publisher / Subscriber) Messaging
    - https://aws.amazon.com/jp/what-is/pub-sub-messaging/
    - https://dev.classmethod.jp/articles/re-introduction-2022-sns/
- サブスクライバーの例
    - Lambda
    - SQS
    - HTTP/HTTPS
    - Email
    - SMS
    
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287165/7b00d100-a815-4b24-b0c4-405cc2fda2f2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287165/0448f739-d6f8-97a2-07a0-e815498a4279.png)
    

### **Amazon SQS (Simple Queue Service)**

- マイクロサービス、分散システム、およびサーバーレスアプリケーション用の完全マネージド型メッセージキュー
- ソフトウェアコンポーネント間で任意の量のメッセージを送信、保存、受信することができる
- 疎結合が可能になる
- プロデューサー - メッセージをSQSに送信するアプリケーションのこと
- コンシューマー - SQSからメッセージをポーリング(取りに行く)アプリケーションのこと
- メッセージ - 送受信されるデータのこと
- キュー
    - 標準キュー
    - FIFO キュー
erb2hamlのライブラリが見つからずデプロイ失敗

## 概要
erb2hamlのgemがデプロイのビルド時に見つからず、そのせいでビルドが失敗。
なかなか解消せず、最終的に原因不明のまま解決したのでどなたかのご参考になれば。

#### 開発環境
- Mac M2チップ
- Ruby on Rails 6.0.6.1
- Heroku


## 結論
erb2hamlのgemを削除して依存関係を再インストール。その後デプロイし直したらビルド成功した。
そもそも不要なライブラリを残しておいたのがよくなかった。

## 経緯
Herokuにデプロイを実行中、「erb2hamlの依存関係があるのに、gemが見つからないためビルドできない」という警告が出た。

依存関係に問題があるのかと思い、yarn.lockとgemfile.lockを削除してから再インストールを実行してみたが解消せず。

「本番環境でgemを見つけるには・・・」と考え、gemfile内のdevelopment項目に記述していたerb2hamlのgemをproductionの項目に移してみたが解消せず。

煮詰まっていたが「そもそもこのgemって本番環境で必要なのか？erb2hamlはerbをhamlに一括変換するためのライブラリじゃん」と気付く。

既にすべてのビューページをhamlで作成しており不要なライブラリだったので、gemを削除して依存関係を再度bundle installしてデプロイ実行。成功した。

そもそもの必要性が無いライブラリのために苦労したお話でした。煮詰まったときに視点を変えることの重要性を感じました。
node js でdiscord のbot作成#2応答機能と作る

# 前回のコードの詳しい説明
```javascript:index.js
const {Client,GatewayIntentBits, GuildTemplate} = require("discord.js")
const client = new Client({intents:[]})
client.on("ready",async (c) =>{
    console.log(`${c.user.tag}でログインしました`)
})
client.login("先ほどのトークン")
```

```js
const {Client,GatewayIntentBits, GuildTemplate} = require("discord.js")
```
まずはここです
`require`は読み込み先を指定するためみたいな感じです
`const`は一度定義したら
```js
const client = new Client({intents:[]})
```
操作するためのクライアントを制作するためのものですintentsはオプションみたいなもの
```js
client.on("ready",async (c) =>{
    console.log(`${c.user.tag}でログインしました`)
})
```
`client.on("ready",async (c) =>{`
onはイベントを登録しますreadyは用意が完了したとき
`console.log`はそのままログに表示します
```js
client.login("先ほどのトークン")
```
はクライアントに接続しますqiitaで言えばアカウントにログインしないと記事とか投稿でいない感じです
# botをサーバーに導入
まずOAuth2タブに移動しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725086/d6fe562e-6453-0840-9dec-db04e57bcf1b.png)
そして下の方にスクロールして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725086/90d5bc50-c065-e18c-4413-e1009b255c77.png)って画面が出てくるまでです
権利を設定します
まずbotにチェックを入れましょう
そしたら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725086/829b3dd1-7764-57a9-ecf7-ef84b739f50d.png)

のようなのが出ると思うので好きな権利を選択してください基本的にはSend Messages Use Slash commands
Use Embedded activiesぐらいです自分のサーバーであればAdministratorで基本的にはいいです
https://discord.com/oauth2/authorize?client_id=xxxxx0&permissions=8&scope=bot
みたいなリンクが出ると思うのでそれをコピーしてリンクを開きましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725086/2e23abc2-81cf-350e-a501-6a7e886b15df.png)

みたいな画面が出るのでサーバーを選択から自分のサーバーを選びましょう

BOTNAMEにご挨拶しな！
みたいなのが選んだサーバーに送信されてたら導入成功です

次はbot タブに移動しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725086/e2e4356a-09c9-2e00-6eab-b96df143a201.png)
下の方にスクロールして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725086/1ea773c1-80df-e67f-da5a-51710cd2ce1a.png)
ここにあるトグル全部オンしておいてください
# コード変更
前回のコード
```javascript:index.js
const {Client,GatewayIntentBits, GuildTemplate} = require("discord.js")
const client = new Client({intents:[]})
client.on("ready",async (c) =>{
    console.log(`${c.user.tag}でログインしました`)
})
client.login("先ほどのトークン")
```
新しいコード
```diff_javascript
const {Client,GatewayIntentBits, GuildTemplate} = require("discord.js")
+ const client = new Client({intents:[GatewayIntentBits.MessageContent,GatewayIntentBits.Guilds,GatewayIntentBits.GuildMessages]})
- const client = new Client({intents:[]})
+ client.on("messageCreate",async (message) =>{
+ if (message.content == "hello"){
+    message.reply("hello!")
+ }})
client.on("ready",async (c) =>{
    console.log(`${c.user.tag}でログインしました`)
})
client.login("先ほどのトークン")
```
って感じです
```bash:cmd
node index.js
```
で起動してみましょうそしたらbotを入れたサーバーに行って
helloと打ってみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3725086/eb472ab1-8960-6dd3-c4d8-271b5aacb973.png)
みたいになるはずです
ならなかったら権利とか確認して下さい


# おわり
何か質問があったらコメントしてください
【Docker】PHP（Apache上で動かす）環境を作ってみる

## Dockerの勉強始めた経緯
で、色んなプロジェクトをやってると、
同じ言語やツールでもバージョンが違うとかで、
環境変数を変えたりツールを複数インストールしたりなどで、
PC内がゴチャゴチャしちゃうときってあるよね。
※片付けられない大人なので

### とりあえずPHP環境をDocker化してみる
これまでXAMPP入れてとりあえずで作業してたけど、プロジェクト毎にPHPのバージョンが違ったり、confの設定が違ったり、そもそも本番環境はLinuxなことが多かったりで、Windowsで開発してたりするとなんか違う部分が多いので、当初Hyper-Vで仮想環境作ってとかやってたんだけどISOファイル落として設定してとかっていうのがめんどくさくなったので、Docker流行ってるみたいだし使ってみるかってなったのが経緯。

## とりあえずcompose.yamlを作ってみる
### フォルダ構成
root/
　├compose.yaml
　├docker/(他にもNodeとかDBとか入れることを考慮して分けるため)
　│　├server/
　│　│　├Dockerfile
　│　│　├conf/(php.iniやhttpd.confとか入れる用)
　│　│　├src/
　│　│　│　├html/(ここに画面系src)
　│　│　│　├logic/(ここにロジック系src)
　│　│　│　│　├composer.json

### 設定ファイル
```Dockerfile:compose.yaml
services:
  apache-php:
    build:
      context: ./docker/server
    ports:
      - "80:80"
    volumes:
      - ./docker/server/src/html:/var/www/html
      - ./docker/server/src/logic:/var/www/logic
      - app_vendor:/var/www/logic/vendor(composerのフォルダはvolumeに保持)
    networks:
      - default
volumes:
  app_vendor:
```

```Dockerfile:Dockerfile
FROM php:8.1.14-apache
WORKDIR /var/www/html

RUN echo "ServerName localhost" | tee /etc/apache2/conf-available/fqdn.conf
RUN a2enconf fqdn

# apt-get
RUN apt-get update
RUN apt-get install -y unzip # 入れたいものがあったらここに書く

# ミドルウェアのインストール
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions
RUN install-php-extensions zip # 入れたいものがあったらここに書く

# composerのインストール(multi-stage builds)
COPY --from=composer:2.7.1 /usr/bin/composer /usr/bin/composer

# コンポーザーでライブラリを導入
# Rootでcomposer installできるように、ここでこの設定を入れておく
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_NO_INTERACTION 1
RUN cd /var/www/logic && \
    composer install
```

## まとめ
phpに関してはバブちゃんで構成とかわからんので、
とりあえず業務ロジック系をapacheの公開ディレクトリ以外に配置してみた。
ホントは画面をNode（ReactやVueとか）で作って、PHPはAPI用途で使おうかと考えてたけど、1回で全部書くとネタが尽きそうなので、一旦コレでおしまい。

### 定期更新を頑張る！
アカウント作った当初(2021年1月1日)「一年の計は元旦にあり」と毎日更新しようとした矢先に、安定の正月の暴飲暴食で更新が滞り、そこからやる気スイッチが入ることなく今日(2024年3月1日)まで放置しすぎてた。。。

そんな中、会社の方から「定期的に記事書いてみない？(ﾆｯｺﾘ」って御達しがきたので、頑張ってちょくちょく更新していこうかと言う意思表明
ぼくの「てへへ」なプログラミング凡ミス集（きっとふえる）

## はじめに
<br>

**ネタです。ご了承ください。**

<br>
自分がプログラムを書いてて「このおばかさんめ」となった出来事をアルバムのようにしていくコーナー。

<br>

あとから見返して、
「あの頃の俺たちって、バカやってたけどさ...いい思い出だよな」
っていう感じになりたい。
<br>
案外おもしろいと思うので皆さんもやりましょ.

## ダブルtemplate事件
Vue.jsの勉強をしてた時です。
```App.vue
<template>
    <template>
        <v-container>
            バーカ！
        <v-container>
    </template>
</template>
```

templateタグを二重に羽織ってました。2月の終わりだったので寒かったんでしょうね。
<br>
~~櫻井翔のダブルパーカー事件を思い出したのは僕だけか。そうか。~~
<br>
次行きましょう。
と、いいたいところなのですが、

## ここで記録は途切れている

ここで記録は途切れている...

笑えるミスがあったらどんどん追加していこうと思います。

ゆるく見守ってやってください。