OmniAICreator/Qiita-1.07M huggingface dataset:
paiza「みんなでしりとり」をRubyで解いてみた

# 問題

あなたは友達たちと N 人でしりとりを行うことにしました。
1 人目、 2 人目、...、 N 人目、 1 人目、2 人目、... という順序で発言をします。ここで、それぞれの人は、次に挙げる 4 つのしりとりのルールを守って発言をする必要があります。

1. 発言は、単語リストにある K 個の単語のうちのいずれかの単語でなければならない。
2. 最初の人以外の発言の頭文字は、直前の人の発言の最後の文字と一緒でなければならない。
3. 今までに発言された単語を発言してはならない。
4. z で終わる単語を発言してはならない。

ここで、発言の途中で上のルールを破った場合、ルールを破った人はしりとりから外れます。
そして、その人を抜いて引き続きしりとりを続けていきます。このとき、後続の人は、ルール 2 を守る必要はありません。

N 人がしりとりを行ったログが M 行分与えられます。
このとき、M 回の発言が終わった後、しりとりから脱落せずに残っている人のリストを表示するプログラムを書いてください。

https://paiza.jp/works/mondai/b_rank_skillcheck_archive/word_chain

# コード

n: 人数
words: 使っていい単語のリスト
seq: 発言のリスト

last: 前に言われた発言（nilの場合はなし）
f: 全員の通し番号（-1の場合は脱落している）
person: いまの発言者

said: 最新の発言

```ruby:Ruby
n, k, m = gets.split.map(&:to_i)
words = Array.new(k) { gets.chomp }
seq = Array.new(m) { gets.chomp }

last = nil

#発言が条件を満たしていればtrue、いなければfalseを返すメソッド
define_method(:check) do |said|
  return false unless words.include?(said)  #単語リストにあるか？
  if last
    return false if last[-1] != said[0]     #「しりとり」になっているか？
  end
  return false if said[-1] == "z"           #最後が「z」で終わっていないか？
  true
end

f = (1..n).to_a
person = 0

seq.each do |said|
  if check(said)
    #発言が条件を満たしている場合
    #単語のリストから最新の発言を消す
    i = words.find_index(said)
    words[i] = ""
    
    last = said    #最後に言われた単語を更新する
  else
    #発言が条件を満たしていない場合
    f[person] = -1    #発言者を「脱落」させる
    last = nil
  end
  
  #次の発言者に移る
  loop do
    person = (person + 1) % n
    break if f[person] > 0
  end
end

f.select! { _1 > 0 }
puts f.size  #残った人数を出力
puts f       #残った人の番号を出力
```

条件分岐が複雑なので、一部メソッド化することを考えます。

メソッド`check(said)`は、発言が条件を満たしていれば`true`、いなければ`false`を返します。

メソッドは条件をそのままコードにしているだけですが、ひとつの単語は一度使われたらもう使えないので、単語リスト`words`から消すことにします。それで、条件（１）と（３）を同時に処理しています。

なお、メソッド定義に`define_method`を使っているのは、メソッド内で外部の変数を参照しているからです。
【Swift】varとletの違いについて【変数と定数】


## varとletの基本的な違い

Swiftでは、変数や定数を宣言するためにvarとletというキーワードを使用します。
両者の違いは、**値を後から変更できるかどうか**という点です。

## varについて

**var：** 値を変更可能な変数

varを使って宣言したものは **「変数」** と呼ばれ、**値を後から変更することができます。**

````swift
var count = 10
count = 20 // 問題なく変更できる
````

一度値を設定しても、その後のプログラムの中で自由に値を変更することが可能です。

## letについて

**let：** 値を変更不可能な定数

一方、letを使って宣言したものは **「定数」** と呼ばれ、**値を一度設定したら変更できません。**

````swift
let message = "Hello, World!"
message = "Goodbye, World!" // 「Cannot assign to value: 'message' is a let constant」エラーとなる
````

letを使って宣言した定数は、後から再代入しようとするとコンパイルエラーになります。

## いつvarとletを使い分けるべきか？

基本的な考え方は次の通りです。

**letはデフォルトの変数として使う**
プログラムの途中で変更する必要がない値は、letを使って定数として宣言します。
これにより意図しない再代入を防ぐことができ、コードの可読性が向上します。

**varは必要な場合のみ使う**
 値がプログラムの途中で変更される必要がある場合のみ、varを使います。
 例：ループ内のカウンタ変数、ユーザーの操作によって変更されるデータを格納する変数など
 
## なぜletをデフォルトにするの？
**イミュータビリティ（不変性）順守のため**
プログラムの中で変数の値が勝手に変わってしまうと、思わぬバグが起きやすくなります。
特に、同時にいくつもの処理を行うようなプログラムでは、この問題が顕著になります。
letを使って一度決めた値を変えないようにすることで、プログラムが予測どおりに動作しやすくなり、安全なコードを書けるようになります。

**Swiftコンパイラのパフォーマンス向上のため**
letを使用することで、Swiftコンパイラは変数が変更されないことを前提に最適化を行うことができ、結果的にプログラムのパフォーマンスが向上する可能性があります。

## おわりに

Swiftではletの使用をデフォルトとし、必要に応じてvarを使うという方針を守ることで、より安全でバグの少ないコードを書くことができます。
Swiftが推奨するこのスタイルを意識することで、より良いプログラミングができるようになるでしょう。

# 補足：値型と参照型について
変数の参照方法についてもあわせて確認しておくと、より理解が深まるかと思います。

https://qiita.com/y_m_/items/bf5a02239bc62093a2c6
[Unity] シングルトン Singleton

## 0.0 はじめに
利用頻度が高いデザインパターンの一つ、シングルトンの実装方法です。
自分用の備忘録として掲載しています。





## 1.0 特徴
自分なりに理解したシングルトンの特徴です。

* クラスが自身のインスタンスを1つだけ作成できることを保証する
* そのインスタンスに、簡単にどこからでもアクセスできる





## 2.0 シングルトン(Singleton)　クラスの作成
できるだけシンプルにしています。

* 新しいシーンをロードしても、GameObjectは破壊されません
* このクラスを使用すれば、ヒエラルキーでいちいち設定する必要がありません
* ジェネリックを使用しているので、複数のクラスでシングルトンを使用できる



```C# Singleton.cs
using UnityEngine;

public class Singleton<T> : MonoBehaviour where T : MonoBehaviour {

    // インスタンス設定
    private static T i;
    public static T I {
        get {
            if (i == null) {
                i = (T)FindObjectOfType(typeof(T));

                if (i == null) {
                    Debug.LogError(typeof(T) + " is nothing");
                }
            }

            return i;
        }
    }

    // DontDestroyOnLoadで永続化、その他の場合は破棄する
    protected virtual void Awake() {
        if (this != I) {
            Destroy(gameObject);
            return;
        }

        DontDestroyOnLoad(gameObject);
    }

}

```




## 3.0 参照方法
下記ように宣言してクラスをシングルトンにします。
必要なときはGManager.Iで参照することができます。


```C# GManager.cs
// Singletonクラスを継承、<>にクラス名を入れる
public class GManager: Singleton<GManager>
{
    // 本体
}

```
React × TypeScript でGETリクエスト時のクエリパラメータに配列を渡す方法

## 前置き
本記事ではReact × TypeScript でGETリクエスト時のクエリパラメータに配列を渡す方法について記載します。
フィルタリング機能実装時に筆者が苦戦したため備忘録として本記事を作成しました。
再現コードを記載していますが、結論のみ求めている方は[修正](#修正)まで飛んでください。

## 技術スタック
### フロントエンド
 - Visual Studio Code
 - React (TypeScript)
 - Axios
### バックエンド
 - Eclipse
 - Java
 - SpringBoot
### 動作確認
 - Google Chrome

## バックエンド実装
String型の配列を持つ型```Filtering```を作成し、引数に設定します。
```Java: Java
	@GetMapping("/api/filter")
	public ResponseEntity<Void> filter(Filtering filtering){
		return new ResponseEntity<Void>(HttpStatus.OK);
	}
	
	private record Filtering(String[] array) {}
```

## フロントエンド実装
一旦フロントエンド側でAPIリクエストを行う処理を実装します。
```React:React(TypeScript)
import { useState } from 'react'
import './App.css'
import axios from 'axios';

function App() {
  // メッセージ表示用
  const [message, setMessage] = useState<string>("");

  // onClick動作関数
  const handleClick = async() => {
    // パラメータの作成
    const param = {
      array: ["React", "TypeScript"]
    }

    try{
      // APIリクエスト送信
      await axios.get("http://localhost:8080/api/filter", {
        params: param,
      });
      setMessage("OK");
    }catch(e){
      console.log(e);
      setMessage("ERROR");
    }
  }

  return (
    <div>
        <h1>API Test</h1>
        <button onClick={handleClick}>REQUEST</button>
        {
          message && <div>{message}</div>
        }
    </div>
  )
}

export default App
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039114/bd76f992-2f65-3670-9a28-07289196148c.png)

## 動作確認
REQUESTボタンを押下しリクエストを送信するとBad Requestエラーが発生します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039114/6a910384-d09a-b167-4579-c8b8c6bbf6a9.png)

### 原因
送信しているクエリパラメータの形式が```filter?array[]=React&array[]=TypeScript```に対し、許容されているクエリパラメータの形式は```filter?array=React&array=TypeScript```だからです。

## 修正
APIリクエストを行う処理を修正します。
```React:Raect(TypeScript)
// APIリクエスト送信
await axios.get("http://localhost:8080/api/filter", {
    params: param,
    paramsSerializer: {indexes: null} //←追加
});
```
```paramsSerializer```は配列をクエリパラメータとしてURLに変換するときの動作を制御するための設定です。
```indexes```にはnull, true, falseの値を設定できます。
 - null -> ```array=React&array=TypeScript```の形式に変換
 - true -> ```array[0]=React&array[1]=TypeScript```の形式に変換
 - false-> ```array[]=React&array[]=TypeScript```の形式に変換（デフォルト）

## 動作確認
APIリクエストが通り、無事にOKと表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039114/a8f44a57-fde6-a0c3-1dcf-50046556444c.png)

文字列「React」と「TypeScript」を受け取れています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039114/7a821a74-0472-47a4-5542-5aa8393302e0.png)

以上
【ChatGPT＋Code Interpreter】で黒丸をまわすアニメGIF。


　どうも、カーブミラーです。

　今回は、白い背景で、黒丸をまわすアニメGIFを作成します。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
あります。　あしからず。
:::

　まずは、ニュース。

　X-Twitterが出している
　　AIのGrokですが
　　　Grok2 mini ベータ版が
　　　　リリースされました。

　Black Forest Labsの
　　FLUX.1技術が採用されたので、
　　　画像生成機能を試せるように
　　　　なりました。

　もちろん、
　　課金した人だけです😅

[木内翔大さんポスト](https://x.com/shota7180/status/1823582611366928393?t=8f26b27HPJZiXcwpbsBECQ&s=03)

　描画する際は
　　左メニューのプレミアム→Grokで
　　　描画指示するそうです。

　Grokアイコンで
　　イケそうな気はしますけどねぇ。

　X-Twitter上では、
　　“DALL-E3と同レベル”という声が。

　使い方も
　　ChatGPTと同じ。

　ちなみに、
　　私は課金する気は
　　　今のところ、ありません。

　　ただでさえ、
　　　スマホ熱中症なので
　　　　GrokをONにすると
　　　　　加熱がすごいそうです。
　　　　　　燃えるわ！w
***
　さて、本題です。

　今回は、
　　白い背景で、
　　　黒丸をまわす
　　　　アニメGIFを作成します。

　出来上がりがこちら。
![ball_orbit (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/5118a488-6918-a620-ba43-e11a3dfe5bcb.gif)

　Promptがこちら。
```Text:白背景に黒丸をまわすPrompt
# CodeInterpreterで処理する

### 初期設定

- **サイズ**: 512×512ピクセルの正方形。
- **フレーム数**: 24フレーム。
- **ボールの半径**: 20ピクセル。
- **正方形の中心**: サイズの半分（256ピクセル）。
- **軌道半径**: 中心からボールの半径とマージン10ピクセルを引いた距離。

### 処理内容

1. **空のリスト**`gif_frames`を作成。
2. 各フレームごとに以下を実行:
   - **角度計算**: 現在のフレームに基づいてボールの位置を決定する角度を計算。
   - **ボールの座標計算**: 計算した角度に基づき、ボールの`x`および`y`座標を決定。
   - **白い画像**`frame`を作成し、`draw`オブジェクトで描画開始。
   - **黒いボール**を計算した座標に描画。
   - 完成したフレームをリスト`gif_frames`に追加。
3. 最初のフレームに他のフレームを追加し、アニメーションGIFとして保存（`/mnt/data/ball_orbit.gif`）。
```

　このPromptは
　　下記Promptで
　　　描画を確認して
　　　　ChatGPTに直して
　　　　　もらいました。
```Text:白背景に黒丸をまわすPrompt（元）
CodeInterpreterで、白い正方形（512×512）に、黒いボールが周囲を巡るアニメGIFを作成してください。
コード不要。
```

　内容は同じですが、
　　元のPromptでは
　　　同一アニメGIFに
　　　　なりません。

　そのため、
　　直してもらい、
　　　同一アニメGIFに
　　　　なるようにしました。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
はじめてのフロントエンドパフォーマンス改善: 画像ファイル編

# この記事に関して
この記事では、画像関連のフォーマンス改善策を紹介します。
React.jsやVue.jsなどのフレームワークにおけるパフォーマンス向上の基礎としても役立つになるかと思われます。
この記事を以下の本を参考にしています。

https://gihyo.jp/book/2017/978-4-7741-8967-3

# この記事の対象者
- フロントエンドのパフォーマンスに興味のある

# 関連記事
レンダリングとは？に関しては下記記事をご覧ください

https://qiita.com/miumi/items/3f612f00b370e40dcbc4


# PNG VS JPEG
写真にはJPEG、色数が多いアイコンや透過が必要な画像にはPNGを使い分けるのがベターです。

- JPEG
    - 写真に最適。微細な色の違いをカットして容量を軽する
- PNG
    - 色数が多いアイコンや透過が必要な画像に最適ですが、容量が大きくなりがち

詳しくは下記記事が参考になるかなと思われます。

https://www.innovation.co.jp/urumo/jpg_png/

# デバイスピクセルごとに読み込む画像を切り替える
img要素やCSSのbackgroundimage属性を使った場合、ユーザーの端末のデバイスピクセル比が変わった時に問題が起きるかもしれません。
デバイスピクセル比とはディスプレイ上のピクセルの密度を示す値で、物理的なピクセルとCSSピクセルの比率を表します。簡単に言うと、画面上の1つのCSSピクセルが、実際には何個の物理的なピクセルで表示されるかを示す値です。
デバイスピクセル比に関しては下記記事がわかりやすく説明されています。

https://qiita.com/imusam/items/cd4f8da49c3ab73d6475

デバイスピクセル比の違いサンプルは下記の通りです。

**デバイスピクセル比1**
- 画面
  - 通常の標準解像度のディスプレイ
- 表示
    - 1 CSSピクセル = 1 物理ピクセル

**デバイスピクセル比2**
- 画面
    - 高解像度ディスプレイ
- 表示
    - 1 CSSピクセル = 4 物理ピクセル（2x2のグリッド）

200x200ピクセルの画像を下記のようなimgタグで表示させた場合、デバイスピクセル比1の場合はそのまま表示されますが、デバイスピクセル比2の場合は2倍に引き伸ばされて表示されます

```html
<!-- 200x200ピクセルの画像の場合 -->
<!-- デバイスピクセル比が大きい場合は引き伸ばされる -->
<img src="sample.png">
```

引き伸ばしがされないようにするにはwidthとheightを指定すれば解決します。
しかし、この場合、デバイスピクセル比が低い環境では無意味に高画質な画像を読み込んでしまいます
```html
<!-- 400x400ピクセルの画像 -->
<!-- デバイスピクセル比が小さい場合は無駄に高画質な画像が読み込まれる -->
<img src="sample.png" width="200" height="200">
```

デバイスピクセル比に応じて画像を最適に表示するためには、srcset 属性を使います。
```html
<img src="sample.png" srcset="sample@2x.png 2x">
```

- srcset 属性
    - 異なるデバイスピクセル比用の画像ファイルのリストを指定します。各リスト項目には画像のアドレスと、その画像が対応するデバイスピクセル比を指定
- src 属性
    - srcset属性に対応していない古いブラウザのために、標準解像度（デバイスピクセル比1）用の画像を指定

これによりデバイスピクセル比が1のブラウザでは、sample.png が表示され、デバイスピクセル比が2のブラウザでは、sample@2x.png が表示されます

例えばNext.jsを使う場合は下記記事が参考になると思います。

https://ja.next-community-docs.dev/docs/app-router/api-reference/components/image

# 終わりに
今回は画像ファイルのパフォーマンスについて書きました。
この記事がきっかけでパフォーマンスに興味が持って頂ければ幸いです。
最後までお読みいただきありがとうございます！
slickでラベル付きID(ユーザー定義型)を扱う

## はじめに
「プリミティブ型の多用は良くない！」という考え方から、
以下のようにshapelessを使ってモデルにラベルを付与してみました。
```scala
case class Horse(
  id:   Option[Horse.Id],
  name: String
)
object Horse {
  type Id = Long @@ Horse
}
```
これで、コードがわかりやすくなり、コンパイル時に不整合があれば検出してくれるので、安全性が向上した感じがします。
しかし、データベースとの入出力の際にどうなるのか...😌

というわけで、今回はPlay FrameworkとSlickを使って、ラベル付きIDを扱う方法を紹介します！

## ColumnTypeを定義
マッピングを定義することで、ラベル付きIDの入出力を円滑に行うことができます。

```scala
package model

import shapeless.tag
import shapeless.tag.@@
import slick.jdbc.JdbcType
import slick.jdbc.MySQLProfile.api._

case class Horse(
  id: Horse.Id,
  name: String
)
object Horse {
  type Id = Long @@ Horse

  implicit val horseColumType: JdbcType[Horse.Id] = MappedColumnType.base[Horse.Id, Long](
    id   => id,
    long => tag[Horse][Long](long)
  )
}
```

https://krrrr38.github.io/slick-doc-ja/v3.0.out/%E3%83%A6%E3%83%BC%E3%82%B6%E5%AE%9A%E7%BE%A9%E6%A9%9F%E8%83%BD.html

## リポジトリ
リポジトリでは、通常通りcolumnメソッドの型引数にラベル付きIDを指定することができます。
```scala
private class HorseTable(tag: Tag) extends Table[Horse](tag,"horse"){
 def id = column[Option[Horse.Id]]("id",O.PrimaryKey)
```

## まとめ
思ったより簡単にラベル付き型を扱うことができました。マッピングさえ定義すれば、ユーザー定義型でも同じように対応できると思います！
ラベル付き型を使うとコードが安全になり、読みやすさも向上するので最高ですね！（少し手間がかかるけど）

ちなみに、TypeScriptでも同様のことができるのかなと調べたら、Branded Typesというものがあるようです🤔
気になります...！
＃31　SOLID - Liskov substitution principle

## Introduction
Previously, we talked about the Open-closed principle. This time we will keep going on introducing the next principle L in SOLID - Liskov substitution principle.

To revise the Open-closed principle, [go here](https://qiita.com/nxted_sapporo/items/4fb297659479f417e615).

## Liskov substitution principle

> If S is a subtype of T, then objects of type T in a program may be replaced with object of type S without altering any of the desirable properties of that program

To simplify the definition, it means we should be able to use the alternative objects with the same superclass without affecting anything. 
Remember the circle and square we have created? Now we want to add a rectangle shape which the code may like as below.
```java
    class Rectangle implements Shape {
            public int width;
            public int height;
            public Rectangle(int width, int height) {
                    this.width = width;
                    this.height = height;
            }
                public int sum() {
                        return 2*this.width + 2*this.height;
                }
    }
```
And now, you may think the Square should inherit Rectangle. Which is correct in mathematics that a square is derived from a Rectangle. 

However, imagine the property is private and having width and height get/set method in Rectangle class. 
If we can either update the width or the height with different values using Rectangle's set property methods, it can not be claimed as a Square and may cause to the wrong calculation, which violates Liskov substitution principle. It is a great principle to follow which can help us to write a program that easy maintainable.

We have only mentioned part of the Liskov substitution principle. Search the principle if you are interested.

## References

 - https://en.wikipedia.org/wiki/SOLID
 - https://en.wikipedia.org/wiki/Liskov_substitution_principle
CUDAバージョン確認をするときは"nvcc --version"を使う

# CUDAバージョンの確認は"nvcc --version"を使おう。って話

以前から自作PCのUbuntu環境で、任意のDocker環境で機械学習の勉強を行うための環境構築を投稿していましたが、CUDAバージョンの確認方法が間違えていました。

https://qiita.com/Marron-chan/items/a28851f34a56d03ccda1

[以前の投稿](https://qiita.com/Marron-chan/items/a28851f34a56d03ccda1#%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%AE%E8%B5%B7%E5%8B%95)では、CUDA12.2が入ったホスト環境で、CUDA12.3の環境をDockerで構築しバージョン確認を行いました。
その際に環境の確認として`nvidia-smi`コマンドで確認を行っていましたが、このコマンドが表示するCUDAバージョンはホストのドライバーバージョンに基づくものらしく、別のCUDAバージョンを入れた際は混乱の元になると思うのでここで訂正したいと思います。

### 結論、CUDAバージョンの確認は"nvcc --version"を使おう

# ことの発端
試したいAIモデルの推奨環境に合わせるため、cuda:11.1.1のイメージをpullしてきてコンテナに入り、CUDAバージョン確認のため`nvidia-smi`コマンドを打ったところCUDA 12.2と出力されました。

``` bash
docker pull nvidia/cuda:11.1.1-cudnn8-devel-ubuntu20.04
docker run --gpus all -it nvidia/cuda:11.1.1-cudnn8-devel-ubuntu20.04 sh
```
以下出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604944/a0745bd9-1fd3-b9fc-1819-318db2aaddb9.png)

このようなことが起きた原因は、`nvidia-smi`コマンドが表示するCUDAバージョンはホストのドライバーバージョンに基づくものらしく、その環境でのCUDAバージョンが正しく出力されなかったようです。

CUDAバージョン確認には`nvcc --version`で確認するのが良いらしい。

画像でも、`nvcc --version`で11.1が正しく表示されています。
Julia に Python を引っ張り込まない

コメントしたのだけど，元記事ごとしょうきょされちゃったので，別記事として投稿。

Julia でプログラムするときに、Python 流のプログラミング手法が必ずしも適切でない理由を、いくつかの例を挙げて説明します。

### 1. リスト（`List`）の代わりに配列（`Array`）を使う
**Python:**
Python では、リストは一般的に使用されるデータ構造で、動的に要素を追加したり削除したりすることができます。

```python
my_list = [1, 2, 3]
my_list.append(4)
```

**Julia:**
Julia では、Python のリストに相当するものは配列（`Array`）です。しかし、Julia では配列は非常に最適化されており、特定の型（`Int`, `Float64` など）を持つ要素の集まりとして扱うことが一般的です。配列を使用することで、より高いパフォーマンスが期待できます。

```julia
my_array = [1, 2, 3]
push!(my_array, 4)
```

Julia では、型がはっきりしている配列を使用することで、コンパイラが最適化を行いやすくなります。一方で、Python のリストは型が不定で、Julia で同様の動的型の配列を作成するとパフォーマンスが低下する可能性があります。

### 2. 内包表記（Comprehensions）
**Python:**
内包表記は、Python で広く使われている構文で、リストや他のイテラブルを生成するために使用されます。

```python
squares = [x**2 for x in range(10)]
```

**Julia:**
Julia にも内包表記がありますが、Julia ではループのパフォーマンスが非常に高く、内包表記が必ずしも最適な方法ではない場合があります。特に複雑な処理では、内包表記がかえって読みづらくなったり、パフォーマンスに悪影響を与えることがあります。

```julia
squares = [x^2 for x in 0:9]
```

内包表記の代わりに、明示的なループを使用することを好むユーザーもいます。例えば：

```julia
squares = Vector{Int}(undef, 10)
for i in 1:10
    squares[i] = (i-1)^2
end
```

### 3. 動的型よりも静的型を活用
**Python:**
Python は動的型付け言語であり、変数の型を明示的に指定することなく使用できます。

```python
x = 10
y = "hello"
```

**Julia:**
Julia は動的型言語であるものの、静的型の使用を推奨しています。明示的に型を指定することで、コンパイラがコードを最適化しやすくなります。

```julia
x::Int = 10
y::String = "hello"
```

Julia では、型を指定することでパフォーマンスが向上し、バグの早期発見にも役立ちます。

### まとめ
Python 流のプログラミング手法を Julia に持ち込むと、コードのパフォーマンスや読みやすさが損なわれる場合があります。Julia の特性を活かして、より効率的なプログラムを書くことが推奨されます。特に、配列やループの使用方法、型の取り扱いについては、Julia のベストプラクティスに従うことで、より高速で効率的なコードが書けるでしょう。
[Python]OpenCV 別スレッドでWebカメラの映像を表示する

### 目的

メイン処理とWebカメラ映像表示処理を分けられないかと思った。
また、任意のタイミングで録画の開始/停止を行いたかった。

### 環境
・Ubuntu 22.04
・Python 3.10.12
・Webカメラ Logicool C270

### ポイント
・threading
　カメラ映像取得ループ処理をスレッドにしている
・RecStart,RecStop
　変数recordingのTrue/Falseが録画開始/停止のトリガーになる
・Lock　
　VideoWriter.release()の後にVideoWriter.write()が起きないようにする。
　Lockすることで処理の順番が write() => release() になる。

### ソースコード
```main.py
#!/usr/bin/python3
import time
import Camera as cm

if __name__ == "__main__":
    cam = cm.Camera()
    while True:
        time.sleep(10)
        cam.RecStart("test")
        time.sleep(10)
        cam.RecStop()
```

```Camera.py
import threading
import datetime
import os
import cv2

class Camera:

    def __init__(self):
        index = 0
        devpath = "/dev/" + "video" + str(index)
        self.Setting(devpath, index, 1280, 720, 30)
        self.thread = threading.Thread(target=self.Open, daemon=True)
        self.thread.start()

    def Setting(self, devpath, index, W, H, FPS):
        self.devpath = devpath
        self.index = index
        self.W = W
        self.H = H
        self.FPS = FPS
        self.cap = cv2.VideoCapture(self.index)
        self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('M','J','P','G'))
        self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, self.W)
        self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self.H)
        self.cap.set(cv2.CAP_PROP_FPS, self.FPS)

        self.vwr = cv2.VideoWriter()
        self.vwr_Lock = threading.Lock()
        self.thread = threading.Thread()
        self.recording = False
        self.filename = ""
       
    def Open(self):
        while True:
            ret, frame = self.cap.read()
            if ret:
                cv2.imshow('Capture', frame)
                if self.recording:
                    self.vwr_Lock.acquire()
                    if self.vwr.isOpened():
                        self.vwr.write(frame)
                    self.vwr_Lock.release()
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        self.Close()

    def Close(self):
        if self.vwr.isOpened():
            self.vwr.release()
        if self.cap.isOpened():
            self.cap.release()
        cv2.destroyAllWindows()

    def RecStart(self, filename):
        self.recording = True
        self.filename = filename
        self.vwr.release()
        self.vwr = cv2.VideoWriter(f'{self.filename}.mp4', cv2.VideoWriter.fourcc('m','p','4','v'), self.FPS, (self.W, self.H))

    def RecStop(self):
        self.recording = False
        if self.vwr.isOpened():
            self.vwr_Lock.acquire()
            self.vwr.release()
            self.vwr_Lock.release()
        rename = f'{self.filename}' + '_' + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") + '.mp4'
        os.rename(f'{self.filename}.mp4', f'{rename}')
```
floating要素のあるコンポーネント(Dropdown)をStorybook・Chromaticでテストするときに詰まったところ


## はじめに
Dropdownコンポーネント実装のときに[Floating UI](https://floating-ui.com/)のDropdownのようにトリガーボタンとfloating要素の構成にしましたが、そうすると親要素のStyleの影響を受けてfloating要素部分の表示が見切れてしまう等といった問題がありました。

その問題を解消するために、floatingする要素をコンポーネント外のbody直下などに配置して表示するように改修しました。  

ただ挙動自体は正しく動作するようになりましたが、DOMの配置方法を変更したことでStorybookのインタラクションテストやChromaticのVisual Regression Testing(以下VRT)に支障が出たため、その内容と対処方法を共有します。



## 詰まったところと対処方法
### 1. インタラクションテストでfloating要素が見つからない
Storybookでインタラクションテストを行う際にplay関数を使用します。play関数は引数としてcanvasElementを受け取りますが、このcanvasElementにはstoryに描画するHTMLElementが入っています。  

```javascript
// 例
export const SampleStory: Story = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    await userEvent.click(canvas.getByRole('button'));
    ...
  },
};
```

そのため今回のDropdownのfloating要素のように、body直下に配置した要素はcanvasElemetの中には含まれていません。
なので、以下のように[ownerDcument](https://developer.mozilla.org/ja/docs/Web/API/Node/ownerDocument)を使用してbody要素を取得し、そこからfloating要素を見つける必要があります。

```javascript
export const SampleStory: Story = {
  play: async ({ canvasElement }) => {
    const canvas = within(canvasElement);
    // body要素取得
    const body = canvasElement.ownerDocument.body;
    // #TODO　body要素以降も書いておく
  },
};
```

https://github.com/storybookjs/storybook/issues/16971#issuecomment-1186028103


またその他に`@storybook/testing-library`が提供する`screen`を使用しても、body直下の要素を取得することはできるようですが、以下のように警告が出ていたため、この方法は採用しませんでした。

>  You are using Testing Library's screen' object. Use ' within(canvasElement) instead.
More info:https://storybook.js.org/docs/react/essentials/interactions




### 2. フローティング要素がsnapshotされない
ChromaticでDropdownのVRTを行った際に、Dropdownコンポーネント内の要素(トリガーボタンなど)はsnapshotされましたが、フローティング要素が表示されているはずなのに写っていませんでした。

Chromaticの公式ドキュメントの以下のところに、フローティング要素が写っていない理由が書いてありました。
[Why are components that render in a portal (tooltip, modal, popover, menu) getting cut off?](https://www.chromatic.com/docs/troubleshooting-snapshots/#why-are-components-that-render-in-a-portal-tooltip-modal-popover-menu-getting-cut-off)

Chromaticがコンポーネントをsnapshotする際に、その写る領域は`#storybook-root`のdiv要素(=canvasElement)の高さまでのようです。 
なのでドキュメントに書いてあるとおり、storyのdecoratorでフローティング要素を含めた高さを指定しておくことで、見切れず撮影することができました。

```javascript
export default {
  component: Dropdown,
  title: "Dropdown VRT",
  decorators: [
    (Story) => (
      // 高さを指定
      <div style={{ height: "300px" }}> 
        <DropdownStory />
      </div>
    ),
  ],
};
```

## まとめ
- body直下に要素を置いた場合の各テストの対応
    - Storybookのインタラクションテストでは`canvasElement.ownerDocument.body`でbody要素にアクセスできる
    - ChromaticのVRTでは、`#storybook-root`のdiv要素分の高さまでしかsnaphotされないため、その他の要素も写したい場合はdecoratorで高さを指定する

## 参考

https://reffect.co.jp/html/storybook#Interactions

https://github.com/storybookjs/storybook/issues/16971#issuecomment-1186028103

https://github.com/storybookjs/storybook/discussions/21971#discussioncomment-6153933

https://www.chromatic.com/docs/troubleshooting-snapshots/#why-are-components-that-render-in-a-portal-tooltip-modal-popover-menu-getting-cut-off
RailsのThreadの中でアクティブレコードのデータがとれない

# はじめに

Railsで並列処理をしたところ困ったことがあったのでまとめておきます

# 問題

以下のようにスレッドでfetch_dataをするような処理を書きました

```rb
  def self.where(ids:)
  threads = []
  results = []
  mutex = Mutex.new

  ids.each do |id|
    threads << Thread.new do
      result = fetch_data(id)

      mutex.synchronize do
        results << result
      end
    end
  end
  threads.each(&:join)

  results
end

private_class_method
def self.fetch_data(id)
  api_response = SomeAPI.get(id)
  record = SmapleActiveRecord.find(id) # ActiveRecordから取得
  return nil if api_response.nil?

  data = {
    name: api_response['name'],
    description: api_response['description'],
    country: api_response['country'],
    tags: api_response['tags'],
    record: record
  }
end
```

しかし、`record = SmapleActiveRecord.find(id)`の部分でデータが取得できませんでした
スレッドの中に入るとデータベースからデータがうまく取れないようです

# 解決方法

並列化の中ではコネクションの関係でアクティブレコードからデータが取れなかったので、アクティブレコードの取得部分だけをスレッドの外で行うようにしました

```rb
  def self.where(ids:)
    threads = []
    mutex = Mutex.new
    results = {}
    ids.each do |global_id|
      threads << Thread.new do
        api_response = SomeAPI.get(id)
        return nil if company_response.nil?
        result = {}
        company["some_api"] = api_response

        mutex.synchronize do
          results[id] = result
        end
      end
    end
    threads.each(&:join)

    responses = results.compact
  
    ids.map { |_id|
      
      record = SmapleActiveRecord.find(id)
      new(
    	name: api_response['name'],
    	description: api_response['description'],
    	country: api_response['country'],
    	tags: api_response['tags'],
    	record: record
      )
    }
  end
```

# おわりに

解決方法は単純ですが、コネクションを気にせず解決したい場合はこの方法で対応できます。
RspecにおけるActiveRecord::StatementInvalid: Mysql2::Error: This connection is in use by: #<Fiber:..>への対処

## はじめに

実装をしている最中に以下のようなエラーが発生した。
```rb
 Failure/Error: _query(sql, @query_options.merge(options))

     ActiveRecord::StatementInvalid:
       Mysql2::Error: This connection is in use by: #<Fiber:0x0000000111111111 (resumed)>
```

このエラーの解決に少々手間がかかったので、まとめる。

## 実行バージョン

ruby 3.2.3
Rails 7.1.3 
rspec-rails 6.1.3

## 解決策

ActiveRecordモデルの`has_one_attached`マクロに対して、`dependent: :destroy`を追加する

### 変更前

```rb
class Hoge < ApplicationRecord
  has_one_attached :csv
end
```

### 変更後
```rb
class Hoge < ApplicationRecord
  has_one_attached :csv, dependent: :destroy
end
```


## エラーの原因について

[公式ドキュメント](https://api.rubyonrails.org/v7.1/classes/ActiveStorage/Attached/Model.html#method-i-has_one_attached)には以下のように書いてあった。

> If the :dependent option isn’t set, the attachment will be purged (i.e. destroyed) whenever the record is destroyed.

dependent オプションを特に指定しない場合デフォルトで`dependent: :destroy`を指定しなくても良いと書かれていたので、この対応はスルーしていたが、結果的にはここの設定を明示的に行なっていないことが原因だった。

直接的な原因が何なのかはわかっていないが、`dependent: :destroy`を明示的に書くことでエラーは解決できた。
想定される直接的な原因としては
- ドキュメントと実際の実装に乖離がある
- テスト環境でのみうまく作用しない
- 親リソース起点でdestroyを実行するとうまくいかない

などが考えられる。

## エラー解決に躓いた原因

エラーメッセージから読み取れる情報としては、すでにdbコネクションがFiberによって使われているからdbアクセスうまくできないといった趣旨だった。

つまり、エラーが発生しているテストケース以前に何かしらのエラーの原因となるテストケースが存在しているというふわっとしたことしか把握できなかった。


## エラー解決に役立った方法

今回はエラーが起きているテストケースのファイル以前にどのspecファイルが実行されているのかを把握する必要があった。そのため、今回のケースでは以下のやり方で、デバッグするのが効率的だった。

方法は、rspec_helper.rb の末尾に次のコードを埋め込むだけ。

```rb:rspec_helper.rb
RSpec.configure do |config|
  config.before(:all) do
    puts "\nRunning: #{self.class.metadata[:file_path]}"
  end
end
```

このコードを埋め込むことで、どのファイル順でrspecが実行されているのかがすぐわかる。

他のやり方としては、[rspecが用意しているoptions](https://rspec.info/features/3-12/rspec-core/command-line/)を使うという選択肢もある。
`rspec -format documentation`を使うことで、どのファイルのテストケースが実行されているかをログから容易に把握できる。
CSSとSCSSはどんな違いがあるの？

# はじめに
同じWebページの見た目を作るものなのにCSSとSCSSとぱっと見似ているようなものがあり、業務始めたての頃は、なんじゃこれと思っていました。そこで、この２つの違いについてまとめていこうと思います。

# 1. CSS
CSSはWebページの見た目を定義する広く活用されている標準的なスタイルシート言語。

基本的な構文:
```
body {
  font-family: Arial, sans-serif;
}

h1 {
  color: #333;
}
```

# 2. SCSS
概要: SCSSはSassの構文の一つで、CSSに似た構文を持ち、より直感的に書ける。

基本的な構文:
```
$primary-color: #333;

body {
  font-family: Arial, sans-serif;
}

h1 {
  color: $primary-color;
}
```

# 3.　CSSとSCSSの違い
##### 変数
CSSには変数の概念がありませんが、SCSSでは変数を使って色やフォントなどの値を再利用できます。これにより、コードのメンテナンスが容易になります。

##### ネスト
CSSでは、セレクタはフラットに書く必要がありますが、SCSSでは一つのセレクタ内に別のセレクタを書くことができ、親子関係を分かりやすく表現できます。

##### ミックスインと継承
SCSSでは、ミックスインと継承を使って、再利用可能なスタイルの塊を作成することができます。

# 4. 使い分けのポイント
##### CSSを使うべき場合
・小規模なプロジェクトやシンプルなスタイルを持つウェブサイト
・すぐに静的なスタイルを追加したいとき

##### SCSSを使うべき場合
・中〜大規模なプロジェクト
・複数の開発者が参加するプロジェクト
・複雑なデザインやスタイルの再利用が必要な場合

# 5. まとめ
私は、SCSSの方がわかりやすいし便利で使いやすいと感じています。SCSSを導入することで、より柔軟でメンテナンスしやすいスタイルシートを作成できるようになります。
Ansible Lightspeed の Playbook生成機能を試してみた

# 初めに
2024年6月末ごろに、Ansible Lightspeedの機能が拡張され、複数のタスクをまとめた1個のPlaybookを作成する機能が追加されました。（以前は、タスクの生成機能に限定）
試してみたので、手順をご紹介いたします。

# 前提
VS CodeにAnsible Pluginを導入し、ライセンスの認証が出来ていること

# 手順
#### 1. VS Codeで、Ansible Pluginのアイコンを選択し、「ANSIBLE CONTENT CREATOR」の「Get started」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/e9e3e08d-7196-101c-5a73-f7846da29eb5.png)

#### 2. Ansible Content Creatorの画面が出るので、「Playbook with Ansible Lightspeed」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/88108512-c455-b810-741f-7f81dab9b135.png)

#### 3. 「What do you want the playbook to accoplish?」というテキストボックスに、生成したい処理の内容を記入して、「Analyze」をクリックします。
ここでは、「Install nginx server and start the server, then change firewall settings to accept http and https」と入力してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/4ae454d5-cf43-b837-f05c-bf2199f647b4.png)

#### 4. 画面が切り替わり、先ほど入力に応じて、設定するためのステップが自動生成されて、「Review the suggested steps for your playbook and modify as needed」というテキストボックスに、表示されます。必要に応じて、変更し、「Genarate playbook」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/dec58604-eaf4-230b-aa4f-8064cc55fea7.png)

#### 5. 画面が切り替わり、Playbookのyamlが生成され、表示されます。「Open Editor」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/23e00130-b0f5-ba42-3eae-ca90b964a1b5.png)

#### 6. Editor画面に生成されたコードが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740352/e56decae-0ebe-ec99-adce-2cdf2eb3974d.png)

# 所感
マニュアルを参照しなくても、簡単に使うことができました。プロンプトに長い文章を入れることもできるので、プロンプトを工夫することにより、1個のタスクでも、この機能を使用した方が、精度を高くすることが可能かもしれません。
重複する箇所を重ねて文字列を結合する(python3)

## 記事を書いた動機
自身のpythonのプログラム練習としてpaizaの問題を解いていた。
その中でも、paizaのサービスの一つである「エンジニアが死滅シタ世界　アンドロイドとふたりぼっちで生きろ」で詰まった問題があり、解決に手間取った。なかなか気づきにくく同じ問題に直面している人がいるかもしれないため、その時の実装の流れと詰まった原因を書き残す。

## 問題の内容
n個の文字列が提示され、それらを順に結合した文字列を出力する問題。
ただし新たに結合する文字列の最初と前の文字列の最後で重複する箇所があれば、重なった部分を省略して結合を行う。

以下の入力例では、「kyuri」最後の文字「ri」が「ringo」の最初の二文字と同じため、「ri」を除いた「ngo」を結合する。

```python:入力例 
3
kyuri
ringo
sakura

#出力結果
kyuringosakura
```

## 処理方法
まず、実装にあたり以下の手順で行った。

1\. 空の出力結果文字列resultを宣言(単語を順次結合していく)

2\. 入力文字列をwordに代入

3\. resultの最後の文字とwordの最初の文字を比較し、合致している場合はresultから最後の文字を削除

4\. resultにwordを結合する(文字をくっつける)

5\. 入力文字列の数だけ2～4を繰り返す

## 初期コード
上記の処理方法を踏まえて以下のコードを実行した。
```python:python.py
n = int(input()) #文字列の数
result = "" # 出力結果を格納する変数

#結合を行う処理
for _ in range(n):
    word = input().rstrip()
    word_length = len(word)
    
    # 最初の入力単語なら合致の検証を無視する
    if result != "": 
    
        # max_len : 最大で合致する可能性のある文字列の長さ
        max_len = word_length if word_length < len(result) else len(result) 
        
        # 合致の検証を行う
        for i in range(max_len , 0, -1):
            if word[:i] == result[-i:]:
                result = result[0:len(result)-i]
    
    result = result + word
    
print(result)
```
用意されていた入力例で問題なく動作したのを確認し提出したところ、不正解だった。このことから、特定の入力で正常な処理が行われていないことが分かった。

反例となる入力をいくつか考えたが見つけられなかったため、ChatGPTに聞きさまざまな入力を試した。

その結果、以下の入力では処理が正常に行われていないことが分かった。
```python:反例 
3
banana
ananana
nana

#正解の出力結果
bananana
#プログラム実行結果
banana # 結合がうまくいっていない
```

## 原因
反例で行われている処理をひとつずつ考えると、for文内の文字列の合致を確かめる箇所に問題があることが分かった。

nanaの結合を行う際に、最後の文字を削除する処理が行われているが**本来一回だけ行う処理が複数回実行されており**、削除しなくてもいい箇所も削除され結合がおかしくなっていた。

以下に反例での実行の流れを示す。(問題の箇所のみ記載)

1\. bananana(anananaを結合した結果)にnanaを結合していく

2\. nanaが一致したため,banananaから最後のnanaを削除しbanaとなる。

3\. naの合致の検証が行われ、naが一致したため、banaから最後のnaを削除しbaとなる。**（この処理が問題の原因)**

4\. baにnanaを結合しbananaとなる

そのため、resultの最後の文字を削除する箇所の後にbreakを追加し複数回resultの最後の文字列が削除されないようにした。
```python:python.py
n = int(input())

result = ""
for _ in range(n):
    word = input().rstrip()
    word_length = len(word)
    if result != "":
        max_len = word_length if word_length < len(result) else len(result) 
        for i in range(max_len , 0, -1):
            if word[:i] == result[-i:]:
                result = result[0:len(result)-i]
                break #合致の検証を終了する
        
    result = result + word
    
print(result)
```

修正したプログラムでは反例も正しく処理されるようになり、再度提出すると正解することができた。
読みやすいコードを書くためのガイド - 名前の誤解を避ける方法

## 名前の誤解を避ける方法
最近リーダブルコード（The Art of Readable Code）を読んでいます。この記事は、本の内容をしっかり頭に入れて、お浚いする為の読書ノートです。

今回は、第3章「Names That Can’t Be Misconstrued」について、まとめてみました。

### 1. 誤解されない名前の重要性
多くの英単語はプログラミングにおいて曖昧な意味を持ちます。例えば、filter、length、limit。

例: Filter()：

```javascript
results = Database.all_objects.filter("year <= 2011")
```
このresultsには何が含まれているでしょうか？

 - Objects whose year is <strong> <= 2011</strong> ?
 - Objects whose year is <strong>not <= 2011</strong> ?

問題は、英語のfilterがとても曖昧で、「取り出す」のか「取り除く」のかが不明確です。
「取り出す」の場合は、``select()``がより適しています。
「取り除く」の場合は、``exclude()``が適しています。
filterなどの名前は非常に誤解されやすいため、避けるのがベストです。


### 2. 上限値と下限値の名前付け
値の上限または下限を定義する場合、max_やmin_を使うと良いでしょう。
例えば、最大値を表す変数にはmax_value、最小値を表す変数にはmin_value。
```javascript
// 上限・下限を示す場合
max_length = 100
min_price = 1000
```
### 3. 範囲を表す名前付け
範囲を表す際には、包含範囲にはfirstとlast、包含/排他的範囲にはbeginとendを使用するのが適しています。

```javascript
// 包含範囲
first_index = 0
last_index = 10

// 包含/排他的範囲
begin_index = 0
end_index = 10  // 0から9までの要素を示す
```

### 4.ブール値の名前付け
ブール値の名前にはisやhasなどを使ってください。
```javascript
// 良い例
is_valid = True
has_permission = False
```
また、否定形は理解しづらく、誤解の元になります。否定的な言葉（例：disable_ssl）は避けましょう。代わりに肯定的な表現を使用します。
```javascript
// 良い例
use_ssl = True

// 悪い例
disable_ssl = False
```

### 5. 他の開発者の期待に注意
ややこしいですが、ある単語に対する期待にも注意すべきです。例えば、get()やsize()といったメソッドは軽量であることを期待されます。これらのメソッドが重い処理を伴う場合、誤解を招く可能性があります。

```javascript
// 良い例
retrieve_user_data():
    // データベースから大量のデータを取得する処理

// 悪い例（重い処理を行っている）
get_user_data():
    // データベースから大量のデータを取得する処理
```
## まとめ
これを参考にし、コードの可読性を高めるための名前付けを心がけましょう。他の開発者が意図した通りにコードを理解できるようになります。
PCを再起動するとVSCodeの「code」コマンドが使えなくなる

## 前提条件
Mac M2

PCを再起動するたびに⌘ + Shift + P で「コマンドパレット」を開いてPATHを通し直す必要がある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480176/e5613ca8-2f6f-b2c5-d7cb-0973526ee1c1.png)

PCを起動して「code」を探しても存在しない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480176/f0b44e0a-a180-479c-a2a8-2041cf2d51c4.png)

PATHを一覧してそのディレクトリを探しても存在しない

```
echo $PATH | tr ':' '\n'
```
<br>


この記事に書かれていた「すでにPATHが通っているところにシンボリックリンクを貼る」という方法でこの問題を解決しようと思います。

https://datawokagaku.com/what_is_path/




## VSCodeがどこにインストールされているか確認する
```
mdfind "kMDItemCFBundleIdentifier == 'com.microsoft.VSCode'"
```
mdfindはmacOSのSpotlight検索機能をコマンドラインから利用できるツール

kMDItemCFBundleIdentifier は、macOSのメタデータキーの一つで、アプリケーションのバンドルID

ちゃんとApplications配下にあった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480176/66027343-c26e-573f-d902-0ba6595743b4.png)

<br>

## usr/local/bin ディレクトリに codeコマンドのシンボリックリンクを作成する

```
sudo ln -s /Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code /usr/local/bin/code
```
ln -s シンボリックリンクを作成

/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code　VSCodeのフルパス


/usr/local/bin/code　シンボリックリンクの作成先

<br>


その結果、すでに存在していることがわかった。シンボリックリンクが壊れているかも？？
なんか色々うまくいかなった原因はこれっぽいな。なんでこうなったかは今となっては不明

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480176/2114ede4-8083-1213-d174-e9629d8718a3.png)

<br>


既存のシンボリックリンクを削除
```
sudo rm /usr/local/bin/code
```

もう一度シンボリックリンクを作成
```
sudo ln -s /Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code /usr/local/bin/code
```

きちんと作成されたことを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480176/fd9ec470-49c1-abe2-c82c-b7968e868a02.png)

シェルを再起動
```
exec $SHELL
```

これで、きちんと使用できるようになりました。

## おまけ　bin配下にシンボリックリンクを作るのと、「PATHを通す」は何が違うの？
気になったので調べてみた

<br>
この記事ではパスを通す手段の一つとして書かれていた。

https://zenn.dev/d0ne1s/articles/1f435463551ac2

ただパスが通っているところにシンボリックリンクを作成することは厳密には「PATHを通すとは言えない」的な知恵袋も存在した。

なんか言い回しの問題なのかもな〜って認識で深掘りをやめました。
なぜ今コンテナなのか【AWS Black Belt】のまとめ

## はじめに
「AWS Black Beltのなぜ今コンテなのか」を視聴したのでそちらを自分なりにまとめてみました。
AWSコンテナサービスは、アプリケーション開発をより効率的に、安全に、そして迅速に行うための技術で近年、多くの企業がアプリケーション開発のスピードアップを求めており、そのニーズに応える手段として注目されています。

**コンテナとは？**
コンテナは、アプリケーションとその実行に必要な環境をパッケージ化したものです。
これにより、異なる環境間でのアプリケーションの移植性を高め、開発と運用をスムーズに行うことができます。
**AWSコンテナサービスの利点**
AWSは、コンテナ技術を活用したアプリケーション開発を支援する様々なサービスを提供しています。

* **迅速な開発とデプロイメント：** コンテナ技術により、開発者はアプリケーションを迅速に構築、テスト、デプロイできます
* **高いスケーラビリティ：** AWSコンテナサービスは、必要に応じてスケールアップ・スケールダウンが容易です
* **セキュリティの強化：** AWSコンテナサービスは、セキュリティ対策を強化することで、アプリケーションを安全に運用できます

**AWSコンテナサービスの主なサービス**

AWSでは、コンテナオーケストレーションサービスとして、Amazon ECSとAmazon EKSを提供しています。

* **Amazon ECS (Elastic Container Service):** AWS独自のコンテナオーケストレーションサービスです。シンプルで使いやすく、AWSサービスとの統合性の高いことが特徴です

* **Amazon EKS (Elastic Kubernetes Service):** Kubernetesベースのコンテナオーケストレーションサービスです。オープンソースツールとの互換性が高く、高度な柔軟性と拡張性を提供します

**コンテナサービスの選択**
企業は、アプリケーションの要件や運用環境に合わせて、適切なコンテナオーケストレーションサービスを選択する必要があります。

* **Amazon ECS：** シンプルな運用を求める場合や、AWSサービスとの連携を重視する場合に適しています。
* **Amazon EKS：** 高度な柔軟性や拡張性を必要とする場合、またはオープンソースツールとの連携を必要とする場合に適しています

**コンテナ技術と今後の展望**
コンテナ技術は、今後も進化を続け、より高度な機能を提供していくことが予想されます。AWSは、コンテナ技術の進化に合わせたサービスを開発・提供し続けることで、お客様のビジネス成長を支援していきます。

##関連資料
[なぜ今コンテナなのか【AWS Black Belt】](https://www.youtube.com/watch?v=K51Q9QBUA-Y)
[なぜ今コンテナなのかAWSのコンテナサービス全体の理解/PDF](https://www.youtube.com/redirect?event=video_description&redir_token=QUFFLUhqbDZzTkVWamJkSkVhUFdkcWExYUJZWHBpNWVTQXxBQ3Jtc0tuY2hGZUE5M1dudy03azV4V3ROanp2c0xyaFZVazlxNmlkWDdVeU1QR2ZtbmhhYUFkaUlpYnVacUNHMmJwRkoyT1ZFbkJ6WHU5ckgtd2NuVjNMUkR2Rl9Bcm9IRnNDc0xmR0ZPWmJFV2Z6RGNIWTVyTQ&q=https%3A%2F%2Fpages.awscloud.com%2Frs%2F112-TZM-766%2Fimages%2FAWS-Black-Belt_2024_Why-Container-Now_0630_v1.pdf&v=K51Q9QBUA-Y)
Apps Script のコードで、他者作成のトリガーを削除やログを消したい

🔸 背景
スプレッドシートと Apps Script の組み合わせって非常に強力で、いろんな業務フロー構築に利用させてもらっています。便利な一方、細かい不満はいろいろ出てきます。その不満のうちのいくつかを解決する手段を考えてみました。他のエンジニアの方が作成した Apps Script を編集する機会がよくあります。その時に困るのが...

#### 他者作成のトリガー
他者が作成したトリガープロジェクトに残ってしまっているケースが多々あります。トリガー作成者でないとトリガーが削除できないにも関わらず、作成者にコンタクトがとれない場合にトリガーを削除するのに四苦八苦します。まだ、そのトリガーが有効であれば、その関数内で、deleteTrigger を実行してやれば削除できますが、すべてのトリガーが終了してしまっていると、手のつけようがありません。

このような場合に、他者作成のトリガーを削除する方法がないかを検証しました。

### 🔸ソリューション
#### その１　スプレッドシート毎コピーして、スプレッドシートを置き換えてしまう
これは、スプレッドシートと、それに連携する Apps Script を総入れ替えすることになるので、確かにトリガーは削除されます。しかし、スプレッドシートの URL が変更されてしまいます。そのため、このシートを参照している場合の参照エラーが発生するケース可能性があります。また、このスプレッドシート内で IMPORTRANGE を実行している場合に アクセス権限エラー(#REF!)が発生してしまう場合があります。こちらは手間が大きいので最終手段ですね。

#### その２
いろいろ調べましたが、他者が作成したトリガーは、その方以外は削除できないという制限は避けられそうにもありません。スプレッドシートに紐づいている Apps Scriptを置き換えること対応することにしました。

1. スプレッドシートに紐づいている Apps Script のコードエディタを開き　「概要」タブを開き、画面右上部にある「コピーを作成」ボタンを押し、コードの複製を作成してから、Apps Script のコードエディタを閉じます。
![スクリーンショット 2024-08-15 9.28.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2533932/50375408-3c24-33e6-1d3b-0f63773324bb.png)

1. 再度、スプレッドシートの拡張機能/Apps Script メニューで Apps Script Editor を呼び出すと、次の画面に遷移するので、オリジナル（ここでは「無題のプロジェクト」）をクリックして元のプロジェクトを開きます
 ![スクリーンショット 2024-08-15 9.33.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2533932/e42c8078-023a-3111-7538-c8eae01e7d5a.png)

1. 前回と同様に「概要」タブを開き、今度は右上の「削除」を選び元のプロジェクトを削除します
《注意》このプロジェクトでデプロイされている Webサービスや、すべてのトリガー設定、Script Propery に書き込まれている情報が失われることを理解してから削除してください
スクリプト実行ログもクリアされるので、コードのクリーンアップをする際にご利用ください。
Dockerでwget単体で入れるとERROR: cannot verify certificateになる話

## 背景

- Docker imageサイズを小さくするのが美徳である。
- デフォルトの`apt install`だとおすすめライブラリがインストールされてしまうのでオプションでおすすめライブラリを入れないようにDockerfileを書くのが通例。

```shell
apt-get update -y
apt-get install -y --no-install-recommends wget 
```
- 以下のようにしてwget単体をインストールしたところうまく動かなくなってしまったので，おすすめライブラリのうち何が必要だったのかを調べた。

```shell
wget https://github.com/aquaproj/aqua/releases/download/v2.30.0/aqua_linux_amd64.tar.gz
ERROR: cannot verify github.com's certificate, issued by 'CN=Sectigo ECC Domain Validation Secure Server CA,O=Sectigo Limited,L=Salford,ST=Greater Manchester,C=GB':
  Unable to locally verify the issuer's authority.
To connect to github.com insecurely, use `--no-check-certificate'.
```

---

## 結論: 証明書の検証ができていなかった。

- `ca-certificates`を入れたら動いた。
- (`--no-check-certificate`をオプションで指定して証明書の検証をスキップするでも一応動く)

```shell
apt-get install -y --no-install-recommends wget ca-certificates
```
Dockerに限らず，wgetをインストールするときにはca-certificatesも一緒に入れたほうが良さそう。

---
Blenderで包帯ぐるぐる巻きを作りたかったので調べて自己流のワークフローを作った

剣の持ち手等、何かに布をぐるぐる巻きにしたり紐を巻きつけるにはどうすればいいかなと思ったので調べたものを備忘録としてメモしてます。
書いてる本人がほとんどわかってないので質問されても答えられないと思います。

## 最終的にたどり着いた自己流ワークフロー
### 準備
Extra Curve Objectsアドオンを導入。
v4.2以降はこちらから取得。v3は標準であるらしいので有効化すればよいと思われる。
https://extensions.blender.org/add-ons/extra-curve-objectes/

### ぐるぐる巻きの作成
カーブでぐるぐる巻きに該当する部分を作成。
自分の場合は規則正しく巻けていればいいのでこのように作成。
Spiralが追加される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308792/d7f2e9af-7526-e408-d2aa-45dcd5a8ec40.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308792/5170f8c1-41a4-23dd-2748-28155a93b8b3.png)

次に包帯に該当する部分を作るために、カーブから直線を作成。
自分の場合はPointを作ってEで押し出した。
長さは後で調整。
四角形などにする記事もあったが、あとでモディファイアを適用した時に形が破綻するので直線を使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308792/d506516c-ae0f-c813-f3de-1f75e466a0e0.png)

ジオメトリのベベルをオブジェクトにして、
作った直線を指定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308792/f81f1780-1f1f-4d92-8cc3-de45afe909fa.png)

ここまで順調にできていればこのようになっている筈
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308792/9fb8da9f-066b-5788-b57e-c30595569767.png)

### 巻きつけ作業
巻きつけたい対象を作成。
既にある場合はインポートするなりして持ち込む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308792/2eeade28-9ea0-f860-6f0b-2372e05584bf.png)

Spiralに以下のようにモディファイアを追加する。
シュリンクラップで対象を選んで密着させて、
ソリッド化はぐるぐる巻きしたものに厚みをつけたい場合に追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308792/8026a5f1-cc62-2d43-568b-e43fb5e5c871.png)

上手くいっていればこのようになる筈。
後はメッシュに変換してノーマルベイクするなりそのまま使うなりをすればOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2308792/d79ff5e9-cd4d-4df1-8da7-0a5c1c276e31.png)

以上。


<details close><summary>以下、調査したメモなど</summary>

## 包帯の作り方
https://signyamo.blog/blender3-1_ribbon/

## オブジェクトに紐を巻きつける方法
https://michi-organiser.blogspot.com/2017/12/blog-post.html

## カーブをメッシュに這わせる方法
https://signyamo.blog/blender3-1_mesh_curve/

## 規則正しく巻きつけたい場合
https://youtu.be/N3El4kp9oZE?si=56TiSrruoJd7nW6m
上記動画を参考に包帯などのスクリューを作ったあと、シュリンクラップをかけてもよさそう(未確認)



## 色々試してみたメモ
この記事を書いた際に最後に試した方法は

ベジェカーブ作成
↓
ベベル「丸め」で深度適当に設定(0.11m)
↓
ベジェカーブにシュリンクラップ、サブディビジョンサーフェイスを適用
↓
対象に巻きつける

とするとかなりいい感じになった。
ポリゴン数を削減する場合はこれをノーマルベイクでもすると良い感じになると思われる。


## アドオンで解決する場合

アドオンで作る場合はこれが良さそう。
ただし今後Blenderのバージョンが上がってもちゃんと使えるかは不明。
https://3dnchu.com/archives/simply-wrap-pro/

</details>
【Nerves】割り込み処理の開始が600usだった

# はじめに

手元にあったMPU6050(ジャイロ、加速度センサ）をNervesでコントロールして値の読み取りを行ってみました。

# MPU6050とは

X-Y-Z軸それぞれの角速度を測定するジャイロセンサと、X-Y-Z軸方向の加速度センサーを持っています。I2CとSPI接続が可能です。
今回は、I2Cで接続して測定データの読み取りを行ってみました。

# データの取り込み方法

基本的には次の方法で読み取りを行います。
- MPU6050のレジスタにサンプリング周期、やどの値を取得するかを設定する
- 計測されて新しい値がレジスターにセットされると割り込みが発生する
- 計測結果のレジスターの値を読み取る

# I2C

I2Cの読み書きはCircuits.I2Cを使います。
Elixirでi2Cの通信を行う場合、Circuits.I2C一択だとおもいます。詳細はドキュメントや他の記事を参照してください。

# 実装方法

Circuits.I2Cには指定したPINの値が変化した時（立ち上がり、立下り、両方のどれか指定できる）にメッセージを送信する機能があります。
GenServerと組み合わせる事で、割り込みがあったら、GenserverのHandle関数を呼び出して、データの取り込みを行うという実装がよさそうです。
この方針で実装してみます。

```Elixir:interrupt_hander.ex
defmodule InterruptHandler do
  use GenServer
  alias Circuits.GPIO
  @interrupt_pin 4
  def start_link() do
    GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
  end

  def init(_state) do
    mpu = Mpu6050Lib.new()

    {:ok, gpio} = GPIO.open(@interrupt_pin, :input)

    Mpu6050Lib.initialize(mpu, 1, 6)
    # GPIOピンの変化を監視し、メッセージとして受け取るように設定
    GPIO.set_interrupts(gpio, :rising)
    time = System.system_time(:microsecond)
    Mpu6050Lib.clear_interrupt(mpu)
    {:ok, %{gpio: gpio, mpu: mpu, log: [], log_size: 0, start_time: time}}
  end

  def handle_info({:circuits_gpio, _pin, _timestamp, _value}, state) do
    # データの取り込み処理を行う
    acc = Mpu6050Lib.get_acc(state.mpu)
    gyro = Mpu6050Lib.get_gyro(state.mpu)
    time = System.system_time(:microsecond) - state.start_time
    # データの保存（最初の10000件を保存する）
    new_state =
    cond do
      state.log_size < 10000 ->
        %{state | log: [[acc, gyro, time] |state.log] , log_size: state.log_size + 1}
      true ->
        state
      end
    {:noreply, new_state}
  end
end
```

# 動作確認

MPU605を500サンプリング/秒（2ms間隔）で測定をする設定にします。
割り込み信号（CH1）は、測定が完了するとが１となり、データの読み取りを開始すると0になります。

![DS1Z_QuickPrint4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/2964049d-64f0-c016-099c-c86da0162392.png)
CH1（黄色）割り込み信号　CH2（水色）I2Cのクロック

想定通り、2msごとにデータの取り込みができていました。

CH1の割り込み発生（１になる）
↓
加速度と角速度の読み取り(それぞれ6byte)を読み取る
↓
2msの間に完了。取りこぼしなくデータを取得できています。

# 割り込み処理の考察

CH1が1になっている時間が、割り込みが発生してからデータの取り込みを開始するまでの遅延時間となります。この時間は約610usでした。

もう少し長い範囲で測定してみました。
![DS1Z_QuickPrint3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/fe3e5e91-42a1-9e93-657e-581341fc80a0.png)

この測定した範囲でもMax 600us Min 600usでぶれもなく割り込み処理ができている様です。

細かい条件が異なるので一概には比較できないかもしれませんが、Pythonでは、ここまで一定した時間ではなかったです。
この安定した値になるとは、驚きました。
Elixirでは、GILが無い事もこの原因かもしれません。

# まとめ

- GenServerを使い、500サンプリング/秒で安定したデータの取り込みができる事を確認できた
- C言語で書いた場合の遅延には及びませんが、毎秒100回くらいの処理だったら余裕をもってできそう
- リアルタイムOSに求められるような性能は無理だが、安定した処理ができそう
- 通信やファイル保存等を同時に行った場合の影響についても今後確認してみたい
S3にJSONを保存・差分更新するとき作成日時と更新日時も含めてdeep mergeだけでシンプルに保存するプチ工夫

# 前提
- S3にHTTPリクエスト経由のデータをJSONファイルとして保存・差分更新したい
- S3の `Last-Modified` は [作成日時と更新日時を区別しない](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingMetadata.html)

> オブジェクト作成日または最終更新日のいずれか遅い方。マルチパートアップロードの場合、オブジェクトの作成日はマルチパートアップロードの開始日です。

- それらを区別してシンプルに保存したい

- [deepmerge](https://www.npmjs.com/package/deepmerge) はオブジェクトを後勝ちでマージできる


# やったこと


```typescript
const 保存済みのデータ = // S3から取得。なければ空オブジェクト
const 現在日時 = new Date().toISOString();

const 新しく保存するデータ = deepmerge.all([
  { データ作成日時: 現在日時 },
  保存済みのデータ,
  リクエスト経由の更新したい差分,
  { 最終更新日時: 現在日時 },
])
```

このような順でマージすることで、日時系は常に現在日時を単純に作成するだけでも、

1. 初回（保存済みのデータがない場合）のみデータ作成日時が更新され、
1. 保存済みのデータに対してリクエスト経由のデータ差分が更新され、
1. 常に最終更新日時を更新

ということが実現できる
【新卒】未経験エンジニアの初投稿

## 自己紹介
Webの広告代理店に今年入社し、広告を運用している傍ら、Webデザインに興味があってHTML、CSS、Typscriptを勉強して広告で運用する記事の作成などをしています。
最近はVue.jsやNuxt.jsに興味があり、同期のエンジニアと一緒にツールの作成をしています。
完全初心者の私と嫌な顔せずツール開発してくれる同期に本当に感謝ですね。
エンジニアとして役に立てるようにこれからも精進していきます。

## 投稿のきっかけ
### 成長には深い理解をするためのアウトプットが大事ということを知ったから
エンジニアの同期におすすめされて、私の中で響いた本があります。
[世界一流エンジニアの思考法](https://www.amazon.co.jp/%E4%B8%96%E7%95%8C%E4%B8%80%E6%B5%81%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E6%80%9D%E8%80%83%E6%B3%95-%E7%89%9B%E5%B0%BE-%E5%89%9B/dp/4163917683)
マイクロソフトの現役エンジニアの方の体験談が書かれているのですが、エンジニアだけでなくいろんな職種で役に立つ部分が多いと思います。
生産性を高めるために実践できることが書いてあるので、私も参考にして自分の業務でも本に書いてあることを実践しています。
そして、実践しようと思った中の1つが深い理解をするためのアウトプットでした。
私は記憶力がないと思っていたのですが、この本を読んで深く理解してなかっただけだということに気づきました。
この本の筆者自身もnoteで記事を書かれていて、世界一流エンジニアは深い理解をするために学んだことなどをアウトプットされてるようです。
深い理解をして学んだことが定着するようにアウトプットしていきたいと思います。

### アウトプットが苦手だから
私は昔から感想文など自分の考えや思いを言語化することが苦手でした。
うまく言語化できないので、感覚で物事を覚えることが多く定着せず、自分の想いもうまく伝えることができず、苦労することが多くありました。
記事を書くことでアウトプットの練習をして、自分の考えや想いをうまく伝えられるようになりたいです。

## これから
これからは、私が試した勉強法、経験、失敗談、私の考えや思ったことなどなど、ゆるゆるとアウトプットしていければと思います。
なぜタスクごとにバッファを設けてしまったのか

## はじめに
この記事は
(Webアプリケーション開発プロジェクトでディレクター担当の)
私が経験した反省点を振り返り、みなさんと共有するものです。
プロジェクト管理における一つの重要なテーマ、**バッファ**の設定について考えるきっかけにしていただければと思います。

![images.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552881/fc663ff8-7146-114b-a3e6-f722e22ed0a6.jpeg)

## まず
### バッファとは
「バッファ」とは何かを簡単におさらいしましょう。
プロジェクトのスケジュール見積もりにおいて、
不測の事態に備えて設けられる**安全余裕**のことです。

### タイトルの回収
さて、私がなぜ1タスクごとにバッファを設けたのか？
答えはシンプルに「その方がスケジュールの確度が向上する」と思ったからです。
(その方がエンジニアにも易しいのかな？とも思ったり…)
しかし、
その後の学びを通じて、「タスクバッファ」よりも「プロジェクトバッファ」の方が効果的だと考えるようになりました。
（もちろん、100%正解かどうかは賛否ありそうですが）

以下では、
**プロジェクト全体で後半にバッファを設ける方が有効**だと感じた理由を3つ
ご紹介します。

## プロジェクトバッファの優位性

![新規ドキュメント_page-0001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552881/ff056cea-d294-3c53-42e9-c500d6d4d663.jpeg)

#### 1. 中盤以降にタスクが遅延したら挽回が難しい

理由の大半はこれに尽きます！
プロジェクトの初期段階での遅延は、他のタスクでバッファを調整することが可能ですが、
中盤以降になるとその余裕がなくなります。
結果として、スケジュール全体が崩れてしまう危険性が高まります。

#### 2. エンジニアを信じている、だが人間だ①

**学生症候群**という言葉を聞いたことがありますか？

> 学生症候群
> 
> 納期のある作業を行う際に、
> 時間的な余裕があればあるほど、実際に作業を開始する時期を遅らせてしまうという、
> 多くの人間に見られる心理的行動特性のこと。

簡単に言うと**締め切りの直前になって初めて作業を始める**という傾向のことです。

たとえば、
・10日間のタスク
に対して
・7日間の作業時間
と
・3日間のバッファ
を設けたとします。

エンジニアも人間ですから、
・逆算して「4日目から作業を開始しても間に合う」
と考えるかもしれません。

→この思いが、結果的にムダにバッファを利用する方向に向かわせるのです。
※夏休みの宿題をイメージしていただけると分かりやすいかと。
(一部の真面目くん・真面目ちゃんを除く)

そして、
なんと、この"貯金"は使わずにはいられないのです。
その理由は↓

#### 3. エンジニアを信じている、だが人間だ②

**パーキンソンの法則**という言葉を聞いたことがありますか？
> パーキンソンの法則
> 
> 第１の法則
> 仕事の量は、完成のために与えられた時間をすべて満たすまで膨張する。
> 第２の法則
> 支出の額は、収入の額に達するまで膨張する。

簡単に言うと**人間は、時間とお金を用意された分すべて使ってしてしまう**ということです。
(ちなみに、収入が増えたのに貯金や投資が増えないのもこれが理由と言われています)

つまり、
7日間で終わる作業でも、バッファがあることで10日間フルに使ってしまうことが多いのです。
(一部の真面目PG・真面目SEを除く)

## まとめ
今回の話を通じて、
スケジュール管理の観点でも、人間の心理的な観点でも、プロジェクト全体でバッファを設ける方が得策だと考えるようになりました。
そして、
これを実施する上で欠かせないのは、エンジニアとの良好な関係性です。
タスクの進捗が遅れる可能性がある際、気軽に相談してもらえるような信頼関係を築くことが重要だ、ということも再認識できました。
プロジェクトごとに最適なアプローチは異なりますが、この考え方が少しでも役立てば幸いです。
みなさんの経験談も大歓迎です！！！ぜひコメントでお聞かせくださいませ！

## 参考リンク
[１分で学ぶ！学生症候群・パーキンソンの法則](https://it-biz.online/lifehack/student-syndrome/#toc3)

## さいごに
弊社のご紹介もさせてください！

「日本で一番エンジニアが成長できる会社を創る」
[株式会社PRUM](https://prum.jp/)

Wantedly募集
[いつから挑戦しても遅くない！Webアプリ開発エンジニアを目指しませんか？](https://www.wantedly.com/projects/1771548)
[RA・CAの両面型で、自社従業員に寄り添い成長を見届けることができる営業！](https://www.wantedly.com/projects/1792065)
[育ち盛りのエンジニアたちを支えてくれる労務経験者を大募集！](https://www.wantedly.com/projects/1752874)

弊社メンバーは日々学習した内容をアウトプットしております！
ちょこっとでもご興味を持たれた方は求人を見てみてください！
（ご応募もお待ちしております！）

### 最後までご覧いただき、ありがとうございました！