OmniAICreator/Qiita-1.07M huggingface dataset:
React.jsプロジェクトのファイル構成

迷うことが多いので一度情報を整理してみます。もし誤りがあれば教えていただけますと助かります！

## 目次
- [各フォルダと構成についての説明](#各フォルダと構成についての説明)
- [CSSの適用方法](CSSの適用方法)

<br>
フォルダ構成の一例↓↓

```
/src
  /components
    /Navigation
      Navigation.jsx
      Navigation.css
    /Search
      Search.jsx
      Search.css
    /Filter
      Filter.jsx
      Filter.css
    /CountryFlag
      CountryFlag.jsx
      CountryFlag.css
  /pages
    Home.jsx
    Home.css
    CountryDetail.jsx
    CountryDetail.css
  /services
    ApiService.js
  /utils
    HelperFunctions.js
  App.jsx
  App.css
  index.jsx
```

### 各フォルダと構成についての説明

* **components:**

コンポーネントを格納する場所。各コンポーネントに対応するCSSファイルもこの中に配置する。例えば、Navigation.jsxに対応するスタイルはNavigation.cssに記述する。

* **pages:**

アプリケーションのページごとにコンポーネントを分類する場所。各ページに対応するCSSファイルもこの中に配置する。例えば、Home.jsxに対応するスタイルはHome.cssに記述する。

* **services:**

 APIとの通信やデータの取得など、ビジネスロジックを担当するサービスファイルを格納する。

* **utils:**

 アプリケーション全体で使用するユーティリティ関数やヘルパー関数を格納する。

* **App.jsx:**

 アプリケーションのルートコンポーネントであり、全体のレイアウトやルーティングを設定しする。通常、このファイルには直接CSSを書くことは少なく、グローバルなスタイルやフォントの設定などを含むことがある。<br>
 
* **index.jsx:**

アプリケーションのエントリーポイントで、ReactDOM.render()を使用してAppコンポーネントをDOMにマウントする。

### CSSの適用方法
* **ローカルスコープCSS:**

 Reactでは、CSS Modulesやstyled-componentsなどを使って、コンポーネントごとにスタイルをカプセル化する方法が一般的。これにより、異なるコンポーネントのスタイルが衝突するのを防ぐ。


衝突の一例
 異なるコンポーネントが同じ名前のクラスを持つと、通常のCSSではスタイルが衝突する可能性がある。下記の例の場合、ComponentAのボタンにもComponentBのボタンにも二番目のスタイルが適用されることになる (CSSは後に書いてあるスタイルによって上書きされるため)
 
 ```css
 /* ComponentA.css */
.button {
  background-color: blue;
  color: white;
}

/* ComponentB.css */
.button {
  background-color: red;
  color: black;
}
 ```
解決策としては主に二つ。ひとつは、コンポーネントごとのCSSを定義する方法。次はコンポーネントの中にスタイルを定義する方法である。

1. CSS Modules:

```Javascript
// ComponentA.jsx
import styles from './ComponentA.module.css';

function ComponentA() {
  return <button className={styles.button}>Click me</button>;
}
```
```css
/* ComponentA.module.css */
.button {
  background-color: blue;
  color: white;
}
```
```Javascript
// ComponentB.jsx
import styles from './ComponentB.module.css';

function ComponentB() {
  return <button className={styles.button}>Click me</button>;
}
```
```css
/* ComponentB.module.css */
.button {
  background-color: red;
  color: black;
}
```


2. styled-components:
```Javascript
// ComponentA.jsx
import styled from 'styled-components';

const Button = styled.button`
  background-color: blue;
  color: white;
`;

function ComponentA() {
  return <Button>Click me</Button>;
}
```
```Javascript
// ComponentB.jsx
import styled from 'styled-components';

const Button = styled.button`
  background-color: red;
  color: black;
`;

function ComponentB() {
  return <Button>Click me</Button>;
}
```
 

* **グローバルCSS:**

 App.cssやindex.cssなどのグローバルなCSSファイルを作成し、アプリケーション全体のスタイルを設定することができる。(ただし、ローカルスコープのCSSを使用が推奨されている。)

* **CSSフレームワーク:**

 必要に応じて、BootstrapやTailwind CSSなどのCSSフレームワークを導入して、スタイルの設計や効率化ができる。


### ポイント
コンポーネントごとにCSSを管理: 各コンポーネントに対応するCSSファイルを作成し、コンポーネントごとにスタイルを分離して管理することで、可読性とメンテナンス性を向上できる。

スタイルの継承とオーバーライド: Reactでは、CSS Modulesやstyled-componentsを使用することで、スタイルの継承やオーバーライドを柔軟に行うことができる。
【Ruby on Rails】Google APIを使ってSpread Sheetを操作する

いつも大変お世話になっている、
私が大好きなGem(というかGem集)

google-api-ruby-client

https://github.com/googleapis/google-api-ruby-client/blob/main/docs/usage-guide.md

仕事でもHeavy useしていたり、
趣味でもなんだかんだで使ったり、
ソースコードを読んで勉強させてもらったりと、
個人的には結構思い入れがある技術です

勝手に、もう記事を書いている気でいたが、
何も書いていなかったのでおさらいしとく。

## GCPでAPIを有効にする

まずは、GCPで使いたいGemのAPIを有効にしておく。

例えばSpread sheetなら、
Google Sheet APIを有効にしておく

![スクリーンショット 2024-07-09 21.53.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1290117/b9c67958-e365-dcaa-3665-d0151ee2c6cb.png)

## サービスアカウントと秘密鍵作成
次に、認証の設定として、
サービスアカウントを作成する。

作成したら、鍵を作成する項目があると思うので、
そこで秘密鍵を作成する
(これは絶対にGit管理してpushなどしてはいけない、
セキュリティ情報を含むものなので厳重に管理する)

## Gemをインストール
さて、次は、Railsの方で、
使うGemをインストール

sheetなら、

```
gem 'google-apis-sheets_v4', '~> 0.1'
```
みたいな記述を追加してbundle install

ちなみに、google-api-ruby-client/generated配下にある、
ディレクトリは、基本的にはそれぞれの各Googleサービスのgemになっているから、
これらの中から使いたいやつをinstallすればいい。

詳細な使い方は、それぞれのディレクト配下の
OVERVIEW.mdにも書いてある

例えば、sheetなら下記が該当する
https://github.com/googleapis/google-api-ruby-client/blob/main/generated/google-apis-sheets_v4/OVERVIEW.md

## サンプルコード
sheetを例にサンプルコードをご紹介

```rb:sheet.rb
require 'google/apis/sheets_v4'

class Google::Sheet
  extend Forwardable
  def_delegators :@service, :update_spreadsheet_value

  def initialize
    @service = Google::Apis::SheetsV4::SheetsService.new
    @service.authorization = authorize
  end

  def get_values(spreadsheet_id, ragne)
    @service.get_spreadsheet_values(spreadsheet_id, ragne)
  end

  private
    def authorize
      json_key = JSON.generate(
        private_key: Rails.application.credentials.dig(:google, :private_key),
        client_email: Rails.application.credentials.dig(:google, :client_email)
      )

      json_key_io = StringIO.new(json_key)

      authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
        json_key_io: json_key_io,
        scope: ['https://www.googleapis.com/auth/spreadsheets']
      )
      authorizer.fetch_access_token!
      authorizer
    end
end

```

classとして実装してみたが、
要するに、`Google::Apis::SheetsV4::SheetsService.new`として
インスタンス化して、認証さえすればどのような形式でも行けると思う。

https://googleapis.dev/ruby/google-api-client/latest/Google/Apis/SheetsV4/SheetsService.html

https://github.com/googleapis/google-api-ruby-client/blob/main/generated/google-apis-sheets_v4/lib/google/apis/sheets_v4/service.rb

## 該当Sheetにサービスアカウントの編集権限を与える
適当なSheetを用意したら、
共有ボタンを押して、サービスアカウントを編集者として追加します。

あとは、このクラスを呼び出して、
適当なメソッドを使えば
sheetの操作ができるはずです。
投稿 9 Firebase 2024/07/09

本日の勉強時間 6H

Firebaseはアプリ開発における「バックエンド環境」、アプリの見えない部分を提供するサービス。

FirebaseはmBaaS（エムバース）と呼ばれるサービスの一つです。mBaaSとは「mobile backend as a Service」の略語です。

もともと、バックエンド環境をクラウド上で行えるサービスのことをBaaS （バース）と呼びます。BaaSにモバイル（携帯端末向け）を表す「Mobile」の「m」を足し合わせたのがmBaaSであり、mBaaSとBaaSは基本的には同じ意味です。

 mBaaSは、モバイルアプリ開発のバックエンド側のインフラを提供しています。mBaaS の１つであるFirebaseにも、サーバーサイドに必要な機能がすべて内包されているため、エンジニアはバックエンド側の開発コストを抑えつつ、アプリケーション側の開発に集中できます。
Go言語でのシャドーイングの理解

## 実装

```go
func main() {

	x := 10
	fmt.Println("outter block", x)//10

	if x > 5 {
		fmt.Println("inner block", x)//10
		x := 5
		fmt.Println("inner block", x)//5
	}
	fmt.Println("outter block", x)//10
```

上記のxで変数宣言したものは条件分岐より外では、10になります。ブロック内で再宣言すると値が隠蔽され、5になります。そして、ブロック外では最初に宣言した値にアクセスでき、再び10になります。この性質をシャドーイングと言います。

```go
func main() {
    var x int = 10
    fmt.Println("Outside block:", x) // 10
    
    {
        var x int = 20 // ここで新しい変数を宣言しようとすると、エラーが発生します。
        fmt.Println("Inside block:", x)
    }
    
    fmt.Println("Outside block again:", x)
}
```

上記のように`var`で変数宣言をすると、ブロック内での再宣言でエラーが発生します。シャドーイングを避けることができます。

### まとめ

- `:=` を使用した短い変数宣言は、新しい変数を作成し、シャドーイングを引き起こす可能性があります。
- `var` を使用した宣言は、既存の変数と同じ名前で再宣言しようとするとエラーが発生するため、シャドーイングを避けることができます。
（メモ）地図XMLの地番リストから筆界未定地の一覧を抜き出す

# はじめに
地図XMLのリストは、各地番のリストがありますが、筆界未定地を抜きだした方法のメモをしておきます。

# 手順
## 地番リストの準備
各市区町村のZIPパッケージからlistファイルを抜き出しておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/f07d4e5d-0e2c-a9e1-7e15-d7337f5c55d5.png)

## WindowsPowershellで「筆界未定地」を含む行を抜き出す
以下のようなコマンドで筆界未定地を含む行をテキストファイルに抜き出しました。
```PowerShell
$resultTXT = "hikkaimitei-list.txt"
$files = Get-Childitem -Path list/*list.csv
foreach($file in $files){
    cat $file.PSPath | Select-String "筆界未定地" | Add-Content $resultTXT
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/90c1649a-1d30-7126-9455-6b8ce79b0cf8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/4e0166a5-659f-d8ac-8cff-45902a20a497.png)
上記コマンドだと各ファイルの読み込み時にラベル行がはいるので、1行目を抜き出して出力してもいいと思います。

```PowerShell
$resultTXT = "hikkaimitei-list.txt"
$files = Get-Childitem -Path list/*list.csv
foreach($file in $files){
    cat $file.PSPath | Select-String "筆界未定地" | Select-Object -skip 1 | Add-Content $resultTXT
}
```

ラベル行がない分サイズも少し小さくなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/0665f80f-dfa6-436f-587a-78d95e49190f.png)


以上。
なんか本当にあったらしい古のコーディングルール（怖い話）

1990年代〜2000年代の話です。

c言語のコーディングルールで、if文やfor文に対して次のようなルールが有りました。

    ブラケットは１段下げて記述すること

つまりこういうルール。
```c
良い例
if (x == y) 
{
    doSomething();
}

悪い例
if (x == y) {
    doSomething();
}

```

昔のコーディングルールといえば、MISRA Cがあったくらいしかで、
あとは各社がそれぞれ独自で決めてましたし、
いまみたいにGithubで世界中のコード見る機会もなくて、
なんか技術書からの受け売りスタイルとかが主流だったりして、
異なる技術書愛読者の、流派の異なる二人がぶつかってよくどっちに統一すべきか揉めてました。

（このような事象を宗教論争と呼んでたんですが、ご存じない？？）

まあそういった時代背景もあって、
ちゃんとコーディングルールが規定されてて偉いなーとか思ってたわけです。

それでふと、会社の人に聞いてみたわけです

    どうして、１段下げるスタイルが採用されたんですか？

と。

声の大きい社員が勝手に決めた・・・くらいの回答を期待していたら
予想の斜め上の回答が返ってきました。

    え？だって１行増えるからねー。
    昔はコード１行いくらの時代だったんだよねー。（真顔）

へーまじかー。（白目）

もう昔話なので真偽の程は定かではないのですが、
売上を釣り上げるために、不要に水増しコードを作成していた、
そんな時代があったのかもしれませんね。

（補足で、今はちゃんとできたシステムでいくらーとか、派遣業務で時間いくらーとかやってます）

---

あとは、わたしが入社したときにはさすがに廃止されていましたが

    ファイル名はわかりやすい名前をつけよう（ただし４文字）

もなかなか破壊力がありました（笑）

これはシステムの制限で、
* ファイル名が８文字しか入れらんない
* 加えて拡張子が４文字持っていくので、残り４文字
ということみたい。


以上、昔ばなしでした。
【Docker】Dockerfile のコマンド説明

# Dockerfileの項目説明

「よーし、なんか作ろっかなー」と思って、とりあえずやることが  
Dockerでの仮想環境の作り方を調べることをしてるので （いい加減　オボエテ...） 
N番煎じですが、自分のためにも書いていきます！


## はじめに
- 主にコマンドの説明をしてます。  
- 仮想環境の手順を見たい方は、他の方の記事を参考にしてください。 

## Dockerfile
> 使用するイメージや、コンテナ内での作業を書くファイル  
  pipインストールは、requirements.txtを使うことが多い
   
### よく使うコマンド
  - #### `FROM`
    - 使用するイメージを指定する

    ```Dockerfile
    FROM python:3.8
    ```
<br>

  - #### `RUN`
    - コンテナ内で実行するコマンドを書く
    - apt-getでパッケージをインストールするときに使う

      > apt-get は、先に `apt-get update` を実行する必要があるが、
      > installと別々のRUNコマンドで実行すると、キャッシュに問題発生することがあるので、一つにまとめるたほうがいい

    ```Dockerfile
    RUN apt-get update && apt-get install -y \
      vim \
      git
    ```
<br>

  - #### `COPY`
    - ローカルファイルをコンテナ内に持っていきたいときに使う

    ```Dockerfile
    COPY ./app /app
    ```
<br>

  - #### `EXPOSE`
    - コンテナがリッスンするポートを指定する。 
    > これは変数宣言のようなもので、配布する際に分かりやすくするためのもの  
    > 個人のみで使用する場合、記載してもあまり意味がない。

    ```Dockerfile
    EXPOSE 3000
    ```

    実際に、ホストとコンテナのポートを通す場合、`run`コマンド時に  
    `-p`オプションを指定する。 
    ```sh
    docker run -p 8080:8000
    ```
    - この場合、`8080`がホストで`8000`がコンテナとなります。　
    - ホスト側のブラウザで、`localhost:8080`でアクセスしたときに  
      コンテナ内の`8000`にリダイレクトされる感じ。　
    
<br>


  - #### `ENV`
    - コンテナ内の環境変数を設定できる。　

    ```Dockerfile
    ENV　NODE_ENV=testServer
    ENV　MSSQL_LCID=1041
    ``` 
<br>

    
  - #### `CMD`
    - コンテナ起動時に実行するコマンドを書く

    ```Dockerfile
    CMD ["python", "app.py"]
    ```
    
## requirements.txt
- 説明
  - pipでインストールするパッケージを書くファイル
  - Dockerfile内で、requirements.txtを使ってパッケージをインストールすることが多い

- 使用例
  ```
  # pipインストールするパッケージ
  requests
  Flask==1.1.2
  selenium>=1.0,<=2.0
  ```
- このファイルの書き方
   - == や >= 等の比較演算子を使うことでバージョンの指定が出来る。  
   - パッケージ名のみを指定すると最新バージョンがインストールされる。  
   - ,(カンマ)で区切ると、バージョンの範囲指定が出来る。  
   - \# でコメントアウトが出来る。 


- 使い方
  - Dockerfile内で、`RUN pip install -r requirements.txt` と書くことで、  
    requirements.txtに書かれたパッケージをインストールすることが出来る。 


## おわりに
Dockerで実行する際に、デフォルトではルート権限で実行されるので
セキュリティ上、`USER` でユーザーを指定することがいいです。  
これも、Dockerfile内で書くことが出来ますが、手順が増えるので別途書こうと思います。
【Swift6】Passing argument of non-sendable type '(any URLSessionTaskDelegate)?' outside of main actor-isolated context may introduce data races に対応する

これまでは何の警告もでなかった以下のような簡単なコード。

```swift
struct TestWeatherView: View {
  @State private var text = ""
  private let url = URL(string: "https://wttr.in/?format=3")!

  var body: some View {
    Text(text)
      .task {
        let (data, _) = try! await URLSession.shared.data(from: url)
        text = String(data: data, encoding: .utf8)!
      }
  }
}
```

警告でますよね。

![sc 2024-07-09 at 23.05.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588914/70886d73-91b6-b929-9338-fb2ed85cddad.png)

調べると以下。

> いわゆる「アクター境界」を越えているので、
> data() の返り値は Sendable でなければなりません。

# 🤔 参考
サンプルコードあり。

https://x.com/maochanz/status/1810677730763210801
10分の作業で利用可能。WindowsPCで簡単に生成AI（LLM）が動くようになっていたので紹介


# 概要
Ollamaというソフトを使って
WindowsPCで簡単に生成AIを動かす方法を紹介します。

# 背景
ちょっとLLM（大規模言語モデル、生成AI）を動かそうと
Ollamaというソフトのページを見ていたんですが、
なんかWindowsバージョンがダウンロードできるのを見つけてしまいました。

「あれ？もしかしてこれ、Windowsでも動くんか？」
と思ってダウンロード・インストールしたら
めっちゃ簡単にLLM（今回はGemma2）動いたんで紹介します。

多分、特になんの設定もせず、
10分くらいで動作させることできると思います。

# 実行環境
OS
・Windows 11 Home
マシン
・[ASUSで買ったGPUノート「Core i5-12450H君」]()
　・CPU：intel Core i5-12450H
　・メモリ：16GB
　・GPU：GeForce RTX 3050 Laptop 6GB

# Gemma2を動かすための方法
めっちゃかんたん。まじでこれだけ。

・ステップ1：Ollamaをダウンロードする
・ステップ2：Ollamaをインストールする
・ステップ3：PowerShellでOllamaを実行してGemma2を指定する

## ステップ1：Ollamaをダウンロードする
Ollamaのホームページ（ https://ollama.com ）からソフトをダウンロードします。

### ダウンロードボタンを押す
![スクリーンショット 2024-07-09 215111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/627a1ee8-5456-678a-f85c-c545d6d3993e.png)


### Windowsバージョンを選んでダウンロード
![スクリーンショット 2024-07-09 215133.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/78415011-0ca1-6c5c-161a-fc4c8d10d9a5.png)


## ステップ2：Ollamaをインストールする
ダウンロードしたOllamaをインストールします。

### ダウンロードしたOllamaSetup.exeを実行する
こいつをダブルクリックしてください。
![スクリーンショット 2024-07-09 215742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/b72d46ef-9406-5130-d60e-f9494b04d74c.png)

### インストール画面で「Install」を選択する
「Install」ボタンを選択してください。
![スクリーンショット 2024-07-09 215835.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/6a785c1d-d530-aeb2-7609-218f3db74503.png)

### インストールが終わるのを待つ
自動でインストールが終わります。
インストールが終わると自動でウインドウが閉じます。
これでOllamaが使えるようになりました。
![スクリーンショット 2024-07-09 215853.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/db812725-f103-e771-9e6c-56bee2106bae.png)


## ステップ3：PowerShellでOllamaを実行してGemma2を指定する
### PowerShellを起動する
普通にPowerShellを起動してください。

### PowerShellに「ollama」と打つ
ollamaというコマンドを打つと、コマンドの使い方が表示されます。
この表示があればもうollamaを利用して
Gemma2などのLLMモデルをダウンロード・実行することができます。
![スクリーンショット 2024-07-09 220204.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/5f737b77-cc18-3d1d-522d-86fbf8e3b6b3.png)

### Gemma2を起動する
次のコマンドを打つと、
Gemma2モデルがダウンロードされ、起動します。
```
ollama run gemma2
```
![スクリーンショット 2024-07-09 222016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/8f4b7d67-9ba7-c0c7-2af7-e1f98a213033.png)

### 質問や会話をする
`>>>`と文書入力画面がでるので、
Gemma2に質問や相談をしてみましょう。

ここでは、アニメに対する質問をしています。

### 会話を終了する
会話を終了するときは、
キーボードの「Ctrlボタン＋Dボタン」を同時押ししてください。

# 【発展】色々なモデルを実行してみる
Ollamaはいろいろな大規模言語モデルに対応しています。
メジャーなところだと、llamaとかphi3とかmistralとか。
マイナーなのもたくさん対応しているようです。
・Ollamaで動かせるモデル一覧：https://ollama.com/library

マシンやOSによって、
動く・動かないあると思いますが、
Windowsマシンで気楽にいろいろなLLMを試せるのは素晴らしいですね。

# 感想
今回、OllamaのWindows版が目についたのでちょっと動かしてみましたが、
Windowsで超簡単にLLMを動かせました。
思った以上に何もしなくても動いてすごい！
最近は便利な世の中だとほんとにびっくりしました！！
（Pythonとかパスとかくらいは覚悟していたのに何もせずに動いた）

楽なのでしばらくは、
これをおもちゃに遊ぼうと思います。

うちのマシンはゲーム用の普通のGPUがついてますが、
・このマシンでどの大きさのモデルまで動くのか？
・GPU有り無しで速度がどう変わるのか？
とか試して遊ぼうと思います。

# 最後に広告
本業の方の広告になってしまうのですが、
会社関係で「メタバース・デジタルツイン講座」やってます。
今年は名古屋・大阪・東京の3拠点で開催してます。
メタバース・デジタルツインに興味のある人はぜひよろしくお願いします。
https://www.kcc.knowledgewing.com/icm/srv/course-application/init-detail?cd=FLM&pcd=FLMC&cscd=UMT01L
pythonをつかってutf-8からsjisに変換

個人的「質はともかく継続する」32日目です。

## 小技

pythonで文字コードをutf-8からsjisに変換する方法です。

```py
# ファイルの文字コードをutf-8からshift-jisに変換する
# 使い方: python3 utf8_to_sjis.py <変換したいファイル名>
# 例: python3 utf8_to_sjis.py test.txt
import sys
import codecs

def main():
    if len(sys.argv) < 2:
        print("usage: python3 utf8_to_sjis.py <filename>")
        sys.exit(1)
    filename = sys.argv[1]
    with codecs.open(filename, "r", "utf-8") as f:
        text = f.read()
    with codecs.open(filename, "w", "shift-jis") as f:
        f.write(text)

if __name__ == "__main__":
    main()
```
【Pybulletサンプル解説】ロボットアームの先端にtipと表示する【debugDrawItems.py】

お疲れ様です。秋並です。

Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです（一覧は[こちら](https://qiita.com/akinami/items/7b433b60aeb5115ba4d7)）。

<br>

今回は、debugDrawItems.pyを解説します。（コードのリンクは[こちら](https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/debugDrawItems.py)）

本コードを実行すると、「ロボットアームの先端に"tip"と表示され、各関節の角度が変化」します。

![debugDrawItems.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030125/416e3001-9d2d-f5f6-68a7-6ac5d09af50f.gif)


# 使用している機能
本コードは、`addUserDebugText` 関数を使用することで「ロボットアームの先端にtipを表示」しています。
 
```python
pybullet.addUserDebugText(text, textPosition,
                           textColorRGB,
                           textSize,
                           parentObjectUniqueId,
                           parentLinkIndex)
```
- `text`：表示するテキスト
- `textPosition`：表示するテキストの位置（[x,y,z]）
- `textColorRGB`：テキストの色（[R,G,B]）
- `parentObjectUniqueId`：テキストを表示するオブジェクトのID
- `parentLinkIndex`：テキストを表示するリンクのインデックス

<br>

今回の場合、下記コードのようにkukaロボットアームの先端リンクにtipというテキストを表示しています。

```python
p.addUserDebugText("tip", [0, 0, 0.1],
                   textColorRGB=[1, 0, 0],
                   textSize=1.5,
                   parentObjectUniqueId=kuka,
                   parentLinkIndex=6)
```

# コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります（もともとあった不要と思われるコメント等については削除しています）

```python
import pybullet as p
import time
import pybullet_data

# Pybulletを共有メモリモードで接続
cid = p.connect(p.SHARED_MEMORY)

# 共有メモリモードが失敗したら、GUIモードで接続
if (cid < 0):
  p.connect(p.GUI)

# Pybullet用のデータパスを取得
p.setAdditionalSearchPath(pybullet_data.getDataPath())  

# 床のオブジェクトを生成
p.loadURDF("plane.urdf")

# kukaロボットアームを生成
kuka = p.loadURDF("kuka_iiwa/model.urdf")

# kukaロボットアームの先端に赤色のテキストで「tip」と表示
p.addUserDebugText("tip", [0, 0, 0.1],
                   textColorRGB=[1, 0, 0],
                   textSize=1.5,
                   parentObjectUniqueId=kuka,
                   parentLinkIndex=6)

# リアルタイムシミュレーションを有効化
p.setRealTimeSimulation(0)

# 角度を0度で初期化
angle = 0

while (True):
  time.sleep(0.01)

  # 2, 3番目の関節をangleに設定
  p.resetJointState(kuka, 2, angle)
  p.resetJointState(kuka, 3, angle)

  # angleを+0.01
  angle += 0.01
```
統計の母集団の違いを、生成AIは検知できるか？

たまたま下記の２つの生成AIの活用に関するアンケートを並べて見る機会が有りました。

https://exawizards.com/archives/26466/

https://www.ipa.go.jp/pressrelease/2024/press20240704.html

かたや業務で生成AIを積極的に利用している層が71.2% (23年12月調査)
かたや業務で生成AIを利用している層が16.2% (24年3月調査)

---

# 正解は...

母集団の「属性」の違いにあります。

エクサウィザーズ社のアンケートの回答者の属性は「生成AIセミナーの参加者」です。
そりゃ生成AIへ活用に積極的なはずです。
IPAの方は、IPAのウェブサイトへの訪問者です。いろんな多種多様の情シスの方が回答されていると予想されます。

---

# とまあ

世の中にはこんな感じの、おやっとおもう統計数値マジックが潜んでいます。

その一定数は、自分たちに都合のいい数値の見せ方になるように作為的に統計指標や母集団を選択したものです。
論文とかで時々見るのは、なんか統計分かってないなーって感じにのが多いのですが、
政治家とか警察の出している統計数値ってだいたいいつも・・・おや？誰かきたようだ。


今回は私が全く関係な２つを並べたから、わかりやすくて気づけたけど
単発で出されると結構見落としてしまうんじゃないかと思い、
なんかチェッカーがほしいなーとか考えています。

今回そのPoC・・・とまでは行かないのんですが、
とりあえず生成AIがそういった統計上の母集団の違いを検知できるか、試して見たくなりました。

---

# 実践

https://notebooklm.google.com/

NotebookLMをつかいます。
ハルシネーションなく、参照先のドキュメント等について答えてくれます。

URLを入力できるので、入力のしやすさからチョイスしました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812996/942f40d0-56f3-8c79-d72d-171f721b26f8.png)


入力
>２つのアンケート結果において、よく生成AIを利用している人の割合に乖離がみられます。いつくか原因は考えられますが、主な原因はなんだとお考えですか？

出力
>2つのアンケート結果における生成AIをよく利用している人の割合の乖離は、調査対象の業種や職種、企業規模などが異なることが主な原因と考えられます。
>ソース
>によると、Exa Enterprise AIの調査では、回答者の業種は製造業が22.4%で最も多く、IT/Webサービスが22.3%で続くとされています。部門別ではDX部門が25%と最も多く、IT部門以外にも、営業や管理など幅広い部門が回答しています。
>一方、ソース
>にあるIPAの調査では、具体的な業種や部門についての言及はありませんが、企業・組織の実務担当者1000人を対象としています。
>このことから、Exa Enterprise AIの調査はIT関連企業やDX推進部門に偏っている可能性があり、IPAの調査と比較して生成AIの利用率が高く算出された可能性があります。
>一般的に、IT関連企業やDX推進部門は、新しいテクノロジーに対する感度が高く、導入や活用も進んでいる傾向があります。
>また、企業規模や職種によっても生成AIの利用率は異なると考えられます。大企業ほど、生成AIのような新しいテクノロジーを導入するためのリソースが豊富であり、活用促進のための体制も整えやすいため、利用率が高くなる傾向があります。
>職種別では、事務作業の効率化やコンテンツ作成などに生成AIを活用できる可能性が高い職種において、利用率が高くなる傾向があります。
>これらのことから、2つのアンケート結果における生成AIの利用率の乖離は、調査対象の属性の違いが大きく影響していると考えられます。


回答母集団に着目した点、
一般的な見解はどちらも◎

ただし、肝心な回答者の属性で、そっちの細かな属性ではなく「アンケートの回答者が、セミナー参加者」って方に着目してもらいたかった。。。

ひいき目に見て△です。

---

# ChatGPTでもやりました（gpt-4o）

入力
>https://exawizards.com/archives/26466/ と https://www.ipa.go.jp/pressrelease/2024/press20240704.html には何が書いてあるかわかりますか

>２つのアンケート結果の内容をよく確認した上で答えて下さい。
>２つのアンケート結果では、よく生成AIを利用している人の割合に乖離がみられます。
>いつくか原因は考えられますが、主な原因はなんだとお考えですか？

※２つのアンケート結果の内容をよく確認した上で答えて下さい。　みたいな書き方をすると、NotebookLMみたくリンク先の記事をよく参照してくれるようになりました。

出力
> ### Exawizards アンケート結果
>- **調査対象**: 企業経営層を含むビジネスパーソン
>- **主な結果**:
>  - 31%の回答者が生成AIを業務で日常的に使用
>  - 経営層の4分の1が生成AIを本格利用
>
>### IPA アンケート結果
>- **調査対象**: 企業・組織の実務担当者
>- **主な結果**:
>  - 16.2%の企業がAIを業務で利用、6.3%が利用予定
>  - 多くの企業でAI利用に関するセキュリティ規則が未整備
>
>### 主な原因
>- **調査対象者の違い**: Exawizardsは経営層を含む幅広いビジネスパーソンを対象にしているのに対し、IPAは実務担当者を中心に調査しているため、利用率の差が生じている可能性があります。
>- **認識と優先度の違い**: 経営層はAIの導入に積極的である一方、実務担当者はセキュリティリスクや規則の未整備を理由に利用を控えている場合があります。

残念。こちらもNotebookLMとおなじような結果になりました。
母集団の違いには着目できましたが、「そっちじゃねぇ」って結果です。

---

24年7月9日時点では、
生成AIは統計の母集団の違いについて、論理的な筋書きからまず真っ先に疑うことを知っていました。
が、見てほしい場所は見てくれず、もっともらしい一般的な違いをひろってしまった

という結果になりました。

まだまだしばらくは統計の数値マジックについて自衛するほうが良さそうです。
AtCoder 勉強記録[C++] その15

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## B - Uneven Numbers
[B - Uneven Numbers](https://atcoder.jp/contests/abc136/tasks/abc136_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  ll res = 0;
  for(int i = 1; i <= n; i++){
    string s = to_string(i);
    ll x = s.size();
    if(x%2==1) res++;
  }
  cout << res << endl;
}
```
### 解法
`N`以下で桁数が奇数になるものを全て数える。
## B - 105
[B - 105](https://atcoder.jp/contests/abc106/tasks/abc106_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  ll res = 0;
  for(int i = 1; i <= n; i++){
    ll divi = 0;
    if(i%2==0)continue;
    for(int j = 1; j <= i; j++){
      if(i%j == 0) divi++;
    }
    if(divi==8) res++;
  }
  cout << res << endl;
}
```
### 解法
1から`N`までの奇数において約数が何個になるか全探索を行い、出力する。
## B - K-th Common Divisor
[B - K-th Common Divisor](https://atcoder.jp/contests/abc120/tasks/abc120_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll a, b, k;
  cin >> a >> b >> k;
  vec cnt(0);
  ll mmax = max(a, b);
  for(int i = 1; i <= mmax; i++){
    if(a%i==0 && b%i==0) cnt.push_back(i);
  }
  ll s = cnt.size();
  cout << cnt[s - k] << endl;
}
```
### 解法
`A`、`B`どちらも割り切れる正整数を入れるための配列を用意する。その後全探索を行い配列に入れていき、`K`番目に大きいものを出力する。
## D - Lucky PIN
[D - Lucky PIN](https://atcoder.jp/contests/sumitrust2019/tasks/sumitb2019_d)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  string s;
  cin >> s;
  ll res = 0;
  for(int i = 0; i < 10; i++){
    for(int j = 0; j < 10; j++){
      for(int k = 0; k < 10; k++){
        ll cnt = 0;
        bool jud1=false,jud2=false,jud3= false;
        while(cnt < n){
          if(s[cnt] == i + '0') {
            jud1 = true;
            cnt++;
            break;
          }
          cnt++;
        }
        while(cnt < n){
          if(s[cnt] == j + '0') {
            jud2 = true;
            cnt++;
            break;
          }
          cnt++;
        }
        while(cnt < n){
          if(s[cnt] == k + '0') {
            jud3 = true;
            cnt++;
            break;
          }
          cnt++;
        }
        if(jud1&&jud2&&jud3) res++;
      }
    }
  }
  cout << res << endl;
}
```
### 解法
暗証番号は`000`から`999`までなので1桁ずつ考え、全探索を行う。暗証番号の最初の数字が`S`の要素に含まれていたら次の要素も含まれているか、のように探索を行うことで結果が求まる。
[CDK For Terraform]実行環境のコンテナ化

# ローカルの状態によってCDKTFの実行結果が異なる事象が発生

CDKTFの実行環境をコンテナ化することで、
ローカルの状態によって実行結果が異なる事象を解消します。

## Dockerfileの作成

```Dockerfile
# Use an official Node.js runtime as a parent image
FROM node:22

# Set the working directory in the container to /app
WORKDIR /app


# Install CDK for Terraform globally
RUN npm install --global cdktf-cli

# AWS CLIのインストール
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip" && \
    unzip awscliv2.zip && \
    ./aws/install && \
 rm -rf awscliv2.zip


# Terraformインストール (執筆時点での最新版を導入してます。バージョン一覧 => https://releases.hashicorp.com/terraform/)
ENV TERRAFORM_VERSION=1.9.1
RUN wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_arm64.zip && \
    unzip ./terraform_${TERRAFORM_VERSION}_linux_arm64.zip -d /usr/local/bin/ && \
    rm ./terraform_${TERRAFORM_VERSION}_linux_arm64.zip


# Run the application when the container launches
CMD ["cdktf", "--version"]
```

ついでにAWS CLIもインストールしています。

## Docker Build

```sh
docker build -t cdktf-docker .
```

- 確認

```sh
docker image ls
```

```log
REPOSITORY                                                                   TAG         IMAGE ID       CREATED          SIZE
cdktf-docker                                                                 latest      52d950bc0028   48 seconds ago   2.35GB
```

## 実行方法

- CDKTF のバージョン確認

```sh
docker run -it --rm -v ./:/app \
-v ~/.aws:/root/.aws \
-v ~/.terraform.d:/root/.terraform.d \
-w /app \
cdktf-docker:latest \
cdktf --version
```

- Terraformのバージョン確認

```sh
docker run -it --rm -v ./:/app \
-v ~/.aws:/root/.aws \
-v ~/.terraform.d:/root/.terraform.d \
-w /app \
cdktf-docker:latest \
terraform --version
```

- aws cliのバージョン確認

```sh
docker run -it --rm -v ./:/app \
-v ~/.aws:/root/.aws \
-v ~/.terraform.d:/root/.terraform.d \
-w /app \
cdktf-docker:latest \
aws --version
```


## まとめ

この手法をメンバー間で
統一することで特定の実行環境のみに
発生するといった事象の可能性を低くすることが
できると考えています。
やっとLinux を USBブートできた

## 多分10回くらいは失敗してる

Windowsが使える状態を維持しつつLinuxも使ってみたくて、色々調べていたらUSBブートというなんかすごい便利そうな方法に辿り着きました。
10回は失敗したのち、今日やっとできました。
あと、作成したブート用のUSBのデータを削除したら使用可能な容量が減ってしまっていて、こんな感じでhttps://www.iodata.jp/lib/manual/hdpn-u/data/partition.htm
やってみたら復活しました。
新しいUSBメモリ買わないといけないのかなと思いましたが、再利用できました。

インストール用USBの作成にはrufas(portable)を使いました。

![IMG_0360.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/fbeb2eab-e437-6b44-032f-41a1e62b7f19.jpeg)
![IMG_0364.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/5748a901-6aba-0bc7-f60b-88c346821d0d.jpeg)
BeautifulSoupで簡単にスクレイピング


WebスクレイピングといえばBeautifulSoupですね。

GoogleClobを使えばすぐに試してみることができます。

```
from urllib.request import urlopen
import requests
from bs4 import BeautifulSoup
import bs4

#urlを変数に格納
url = 'https://ホームページ'

#データを取得
res = requests.get(url)

# HTMLからBeautifulSoupオブジェクトを作る
soup = BeautifulSoup(res.content, "html.parser")

# 全てのaを取得して格納
elems = soup.select('a')

# 配列からelemsから要素を取り出し処理する
for elem in elems:
print(elem.getText(), elem.get('href'))


```


### 参考文献

https://qiita.com/Moh_no/items/a835f77b6b4e3972fbbe

https://qiita.com/aki4masaki/items/4f3e35876d7170a99bda

https://qiita.com/The_Boys/items/14d42da70d26fad6dde2


https://atmarkit.itmedia.co.jp/ait/articles/2209/27/news035.html

https://qiita.com/kurano_kkgk/items/b6b0d552c2f0cbd11a8b


https://gammasoft.jp/blog/difference-find-and-select-in-beautiful-soup-of-python/

https://atmarkit.itmedia.co.jp/ait/articles/2209/27/news035.html
ABC284Dを解いた



筆者はレート600前後の茶色コーダ

[AtCoder Problems](https://kenkoooo.com/atcoder/)で眺めて選んだ以下の問題を解いていく

https://atcoder.jp/contests/abc284/tasks/abc284_d


# 実装コード

解説をみたが、どうやら$N$で割り切れる数$A$を2から順番に探して、見つかったら制約から逆算して求めるみたい。

```python
import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)


def kth_root_floor(x, k=2):
    if x == 0:
        return 0
    n = x
    while True:
        t = ((k - 1) * n + x // (n ** (k - 1))) // k
        if t >= n:
            return n
        n = t

def main():
    T = rI()
    for _ in range(T):
        N = rI()
        N3 = kth_root_floor(N,3)
        for a in range(2,N3+1):
            if N % a == 0:
                if (N//a) % a == 0:
                    print(a,N//(a*a))
                else:
                    print(kth_root_floor(N//a),a)
                break
if __name__ == '__main__':
    main()

```


# まとめ

ABC284Dを解いた、小さい数から順番に試して、割り切れた数から制約に対する値を計算した。

# 感想

素数の積を判定するプログラムは高い難易度を持つイメージがあり、
萎縮していたが今回の問題は素因数の制約が事細かに決まっていたため、
小さい数から順番に試していくような単純ロジックで求められる事ができるようだ。
問題の制約を把握してそれに合わせた最適なロジックを組み上げられるようになりたい。
TypeScriptのアロー関数を簡潔に理解

# TypeScriptのアロー関数 :beginner:
TypeScriptでは、JavaScriptと同様にアロー関数（Arrow Function）を使用することができます。アロー関数は、関数をより簡潔に書くための構文であり、特にコールバック関数や無名関数を使用する場合に便利です。この記事では、TypeScriptにおけるアロー関数の基本的な使い方や利点、注意点について解説します。

## アロー関数の基本構文
アロー関数の基本構文は以下の通りです。関数の引数リストの後に=>（アロー）を置き、関数の本体を記述します。

```typescript
const functionName = (parameter1: type1, parameter2: type2): returnType => {
    // 関数の本体
};
```
例1: 引数なし
引数を持たないアロー関数の例です。

```typescript
const sayHello = (): void => {
    console.log("Hello, TypeScript!");
};

sayHello(); // 出力: Hello, TypeScript!
```
例2: 引数あり
引数を持つアロー関数の例です。

```typescript
const add = (a: number, b: number): number => {
    return a + b;
};

console.log(add(5, 3)); // 出力: 8
```
例3: 短縮構文
関数の本体が単一の式である場合、波括弧とreturnキーワードを省略できます。

```typescript
const multiply = (a: number, b: number): number => a * b;

console.log(multiply(4, 2)); // 出力: 8
```
## アロー関数の利点
1. より簡潔な構文
アロー関数は、従来の関数表現よりも簡潔に記述できます。これにより、コードが読みやすくなります。

```typescript
// 従来の関数表現
function square(x: number): number {
    return x * x;
}
// アロー関数
const square = (x: number): number => x * x;
```
2. thisの挙動が直感的
アロー関数は、定義された場所のthis値を継承します。これにより、特にコールバック関数内でthisが意図しない値を持つ問題を回避できます。

```typescript
class Person {
    name: string;

    constructor(name: string) {
        this.name = name;
    }

    greet() {
        setTimeout(() => {
            console.log(`Hello, my name is ${this.name}`);
        }, 1000);
    }
}
const person = new Person("Alice");
person.greet(); // 1秒後に "Hello, my name is Alice" と出力される
//従来の関数表現では、thisがundefinedになることが多いため、上記のような場合にはアロー関数が便利です。
```

## アロー関数の注意点
1. コンストラクタとして使用できない
アロー関数は、newキーワードと共に使用してインスタンスを生成するコンストラクタとして使用することはできません。

```typescript

const Person = (name: string) => {
    this.name = name;
};

// エラー: アロー関数はコンストラクタとして使用できません
const person = new Person("Alice");
2. argumentsオブジェクトを持たない
アロー関数はargumentsオブジェクトを持たないため、引数を配列として扱いたい場合はrestパラメータを使用する必要があります。

typescript

const sum = (...args: number[]): number => {
    return args.reduce((acc, curr) => acc + curr, 0);
};

console.log(sum(1, 2, 3, 4)); // 出力: 10
```
# 【まとめ】
typeScriptのアロー関数は、簡潔な構文と直感的なthisの挙動を提供します。コールバック関数や配列の操作など、さまざまな場面で利用でき、従来の関数表現よりも読みやすく保守性の高いコードを書くことができます。ただし、コンストラクタとして使用できない、argumentsオブジェクトを持たないなどの制約もありますので、適切に使い分けることが重要です。また、従来の関数とアロー関数を状況に応じて使い分けることで、より柔軟なコードを書くことができます。
# 【参考】
https://typescriptbook.jp/reference/functions/arrow-functions
IB Gateway 注文約定test

■発注内容
    	Contract contract = new Contract();
        contract.symbol("XAUUSD");
        contract.secType("CMDTY");
        contract.exchange("SMART");
        contract.currency("USD");

        Order order = new Order();
        order.action("BUY");
        order.totalQuantity(Decimal.ONE);
        order.orderType("MKT");
        order.tif(TimeInForce.IOC);

■レスポンス
nextValidId :4
openOrder
[order status] orderId:4 status:Submitted filled:0 remaining:1 avgFillPrice:0.0 permId:948095673 parentId:0 lastFillPrice:0.0 clientId:999 whyHeld:null mktCapPrice:0.0
[exec details]OrderId=4,ClientId=999,ExecId=000132b0.668c5d2f.01.01,Time=20240709 09:23:01 US/Eastern,AccNumber=DU9890949,Exchange=SMART,Side=BOT,Shares=1,Price=2363.61,PermId=948095673,Liquidation=0,CumQty=1,OrderRef=null,EvRule=null,EvMultiplier=0.0,ModelCode=null,LastLiquidity=Removed Liquidity,PendingPriceRevision=false,
openOrder
[order status] orderId:4 status:Filled filled:1 remaining:0 avgFillPrice:2363.61 permId:948095673 parentId:0 lastFillPrice:2363.61 clientId:999 whyHeld:null mktCapPrice:0.0
openOrder
[order status] orderId:4 status:Filled filled:1 remaining:0 avgFillPrice:2363.61 permId:948095673 parentId:0 lastFillPrice:2363.61 clientId:999 whyHeld:null mktCapPrice:0.0
[commission report]000132b0.668c5d2f.01.01,USD,1.7976931348623157E308,2.0
Vimの+clipboardがオフになっている環境で、Vim内からクリップボードへコピーを行う方法

# 要約
Vimの+clipboardがオフになっている環境で、Vim内からクリップボードコピーを行うには以下のことをすればよいです。これをすることで、VimのコマンドモードからF8キーを押すだけで、Vimで書いたテキストがクリップボードへコピーされるようになります。

* [ファイルの内容をクリップボードへコピーするJavaプログラムをつくる](#-ファイルの内容をクリップボードに保存するJavaプログラムをつくる)
* [.vimrcに先ほどのJavaプログラムを起動するautomodをつくる](#-.vimrcに先ほどのJavaプログラムを起動するautomodをつくる)
# 動機
弊学の学内環境にあるVimは、+clipboardがオフになっています。なので、Vimで書いたプログラムをクリップボードへコピーするには毎回Vimを閉じて別の操作でクリップボードへコピーする必要がありした。競技プログラミングなどのコンテスト中などは、できるだけそうした操作にかける時間を減らしたいです。この記事は、上記の問題に対する自分なりの答えをまとめたものです。
# ファイルの内容をクリップボードに保存するJavaプログラムをつくる
以下のJavaプログラムをMain.javaに保存してください。このJavaプログラムは以下の2つのことを行います。
* 第二引数で指定されたパスにあるファイルの中身を読み込む
* 読み込んだファイルの中身をクリップボードへコピーする
* Enterキーが押されたらプログラムを終了する

ところで、このプログラムはEnterキーが押されないとプログラムが終了しないようにしてます。これは、[クリップボードにデータを保存したプロセスが死ぬと、そのデータも死ぬ](https://en.wikipedia.org/wiki/X_Window_selection)というX Window Systemの仕様が要因となっています。
```java
import java.awt.Toolkit;
import java.awt.datatransfer.*;
import java.io.IOException;
import java.nio.file.*;
import java.util.*;

public class Main {
        public static void main(String[] args) {
                Path path = Paths.get(args[0]);
                StringBuffer content = new StringBuffer();
                try {
                        String readString = Files.readString(path);
                        content.append(readString);
                } catch (IOException e) {
                        e.printStackTrace();
                }

                Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                StringSelection stringSelection = new StringSelection(content.toString());
                clipboard.setContents(stringSelection, null);
         
                Scanner scanner = new Scanner(System.in);
                System.out.println("Press Enter key to continue");
                scanner.nextLine();
        }
}
```
Main.javaを保存したら、それをコンパイルします。
```bash
javac Main.java
```
コンパイルされたプログラムは、Main.classというファイル名で保存されます。私は分かりやすいように、Main.classをホームページディレクトリに移動しておきました。
# .vimrcに先ほどのJavaプログラムを起動するautomodをつくる
ご自身の.vimrcに次のコードを追加してください。コードにあるXXXには、Main.classを保存したディレクトリに移動するコマンドを入力してください。Main.classをホームディレクトリに保存した場合は、cdだけで大丈夫です。(ターミナルでcdと入力すると、ホームディレクトリに移動するため)
```vim
autocmd nnoremap <F8> :w <bar> !XXX && java Main %:p:h/%:t && cd -<CR>
```
# おわりに
これでVimのコマンドモードからF8キーを押すと、Vimで編集したテキストがクリップボードにコピーされるはずです。
オリジナル plymouth テーマで Linux の起動スプラッシュを設定する

「plymouth を設定する」
https://qiita.com/nanbuwks/items/7a2635a181cf97fcf974
では、既存のテーマを選択し、有効にしましたが、

簡単なものを自分で作ってみます。

# 環境

- Debian Testing ( Debian 13 : 2024/07/09時点 )

# 準備

先の記事の通り、必要なパッケージのインストールや、plymouth が動く環境の作成をしておきます。

# 作るテーマ

- 止め絵
- アニメーションは行わない
- 作るのが簡単なもの

# 既存のテーマを調査

まずは theme にどんなものがあるか見てみます。
```
# cd /usr/share/plymouth/themes
# ls -R
.:
bgrt	      fade-in	       joy	  softwaves   spinner
debian-theme  futureprototype  lines	  solar       text
details       glow	       moonlight  spacefun    tribar
emerald       homeworld        script	  spinfinity

./bgrt:
bgrt.plymouth

./details:
details.plymouth

./emerald:
Emerald_plymouth.svg  emerald.script  logo+emerald.png	password_dot16.png
debian.png	      glow.png	      logo+emerald.svg	password_field.png
emerald.plymouth      glow.xcf	      password_dot.png	password_field16.png

./fade-in:
bullet.png  entry.png  fade-in.plymouth  lock.png  star.png

.
.
.
```

script の書き方がよくわからなかったので、 script の無いテーマを元にカスタマイズしようかな・・・・・と思いましたが、よくわかりませんでした。 script の無いテーマはどこかのデフォルトスクリプトが作用しているのかな?

# Web記事を参考にする

「Plymouth Theme Customization | Baeldung on Linux」
https://www.baeldung.com/linux/plymouth-themes-splash-screen

こちらの記事では、
https://github.com/barskern/plymouth-theme-simple-image
を元にシンプルな止め絵を表示するテーマを作っています。

それを元に作業をしてみました。

# ダウンロード

```
$ git clone https://github.com/barskern/plymouth-theme-simple-image
$ cd plymouth-theme-simple-image
```

中に入っている image.png を、好きな画像に入れ替えてみました。
それに伴い、 simple-image.script 中の以下の箇所を書き換えます。


```
image = Image("image.png");

pos_x = Window.GetWidth()/2 - image.GetWidth()/2;
pos_y = Window.GetHeight()/2 - image.GetHeight()/2;
.
.
.
```

↓

```
image = Image("logo-text-version-256.png");

pos_x = Window.GetWidth()/2 - image.GetWidth()/2;
pos_y = Window.GetHeight()/2 - image.GetHeight()/2;
.
.
.
```

次に、simple-image.plymouth ファイルの以下の箇所を書き換えて、好きな名前を付けます。

```
[Plymouth Theme]
Name=Arch Linux Simple Image
```

テーマ名を決めます。テーマディレクトリ名=plymouthファイル名=テーマ名 というルールがあるようです。
ここではplymouthファイル名が simple-image だったので、それに合わせました。

```
$ cd ..
$ mv  plymouth-theme-simple-image simple-image
```

テーマをインストールし、変更を反映します。

```
# cp -a plymouth-theme-simple-image /usr/share/plymouth/themes
# plymouth-set-default-theme simple-image
# update-initramfs -u
```

再起動してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ed8783f3-55d3-8824-1b54-ae081eab85e2.png)
うまくいきました。
アプリケーション開発に注力するための私生活の工夫

# アプリケーション開発に注力するための私生活の工夫

こんにちは、皆さん！今回は、アプリケーション開発に集中するために私が実践している私生活の工夫についてシェアしたいと思います。開発に集中するためには、技術的なスキルだけでなく、日常生活の過ごし方も重要です。以下の3つのポイントを意識することで、より効率的に開発に取り組むことができるようになりました。

※本記事はQmonus Value Streamの投稿キャンペーン記事です。

## 良く寝ること

まず最初に、**良く寝ること**です。十分な睡眠は、脳の働きを最適化し、集中力を高めるために欠かせません。私は毎晩7〜8時間の睡眠を確保するように心がけています。特に、寝る前の1時間はスマホやパソコンを避け、リラックスできる時間を過ごすようにしています。これにより、質の高い睡眠を得ることができ、翌日の開発作業にフレッシュな気持ちで取り組むことができます。ただし寝ている時間以外は、最新技術の情報収集やPCに真正面から向き合っています！！

## 良く話すこと

次に、**良く話すこと**です。開発者は一人で作業することが多いですが、他の人と話すことで新しいアイデアや視点を得ることができます。私は定期的に同僚や友人と技術的な話題についてディスカッションする時間を設けています。これにより、自分の考えを整理し、新しいインスピレーションを得ることができます。また、話すことでストレスを発散し、リフレッシュすることもできます。たまに本気で自分のキャリアに刺さるような話も聞くことが出来ます。

## 良く焦ること

最後に、**良く焦ること**です。これは一見逆効果のように思えるかもしれませんが、適度なプレッシャーは集中力を高めるために有効です。私は自分に対して小さな締め切りを設定し、その期限内にタスクを完了させるようにしています。この「良い焦り」が、作業の効率を上げ、モチベーションを維持する助けになります。ただし、過度なプレッシャーは逆効果なので、バランスを取ることが重要です。

## まとめ

以上が、アプリケーション開発に集中するために私が実践している私生活の工夫です。良く寝ること、良く話すこと、そして良く焦ること。この3つのポイントを意識することで、より効率的に開発に取り組むことができるようになりました。当たり前のことですが、今一度意識するべき内容だと思うので皆さんもぜひ試してみてください！
ITパスポート 半導体メモリ

・半導体メモリ
・RAM（Random Access Memory）
読書き可能な揮発性のメモリ
・ROM（Read Only Memory）
読出し専用の不揮発性のメモリ

・DRAM
主記憶に用いられる。リフレッシュが必要
・SRAM
キャッシュメモリに用いられる。リフレッシュが不要
・リフレッシュ
一定時間ごとに情報を再書き込みする必要がある

・フラッシュメモリ
電気的に書換え可能な、不揮発性のメモリ
CloudFrontとS3で静的ファイルの描写速度を劇的に改善した話

## あいさつ
こんにちは、皆さん！今回は、AWSのCloudFrontとS3を使って静的ファイルの描写速度を劇的に改善した経験について共有したいと思います。一般的な内容かもしれませんがはじめて使用して感動しました！！

## 背景

私のプロジェクトでは、静的ファイルの描写に約5秒もかかっていました。ユーザー体験を向上させるために、この描写速度を1秒以内に短縮することを目指しました。

## 手順

### 1. S3バケットの作成

まず、Amazon S3に新しいバケットを作成し、静的ファイルをアップロードしました。

### 2. CloudFrontディストリビューションの設定

次に、CloudFrontディストリビューションを作成し、S3バケットをオリジンとして設定しました。

1. AWSマネジメントコンソールにログイン
2. CloudFrontのサービスページに移動
3. 「Create Distribution」をクリック
4. オリジンに先ほど作成したS3バケットを指定
5. デフォルトのキャッシュ動作を設定

### 3. キャッシュポリシーの最適化

CloudFrontのキャッシュポリシーを最適化することで、描写速度をさらに向上させました。

- **TTL（Time to Live）**: 静的ファイルの更新頻度に応じて適切なTTLを設定
- **圧縮**: CloudFrontの圧縮機能を有効化

### 4. DNS設定の更新

最後に、ドメインのDNS設定を更新し、CloudFrontディストリビューションを指すようにしました。

## 結果

これらの手順を実施した結果、静的ファイルの描写速度が約5秒から1秒以内に短縮されました。ユーザーからのフィードバックも非常に良好で、ページの読み込みが速くなったと好評でした。

## まとめ

CloudFrontとS3を組み合わせることで、静的ファイルの描写速度を劇的に改善することができました。もし同じような課題を抱えている方がいれば、ぜひ試してみてください。

## 参考にした記事
https://qiita.com/wtod/items/8d96b18464bb011fc363
https://qiita.com/ushi_osushi/items/a32d7b710567c2313faa
https://qiita.com/sugurutakahashi12345/items/bd99e6b32e4f5f0e8096
チーム開発に「分報」を取り入れよう

## はじめに
チームでの開発をしていく上でやって良かったことであげたい「分報」について
導入して良かったことと注意点をまとめました

## 前提条件
- メンバー１５人程度
- 複数システムの保守は関わったメンバーがその都度対応し、いくつかの新規プロジェクトをある程度のメンバーでスクラムを組んでいる

## 「分報」って何
-  名の通り、分単位で報告をすること
-  実際はそこまで事細かに報告していないけど気持ちはそれくらい
-  システムごとに何か気になることや進捗が出たら自由にアウトプットを出すトークルームとして活用してました
-  例えば勤務表を管理するシステムを作っていたら「勤務表システムの分報」みたいな名前で関わるメンバーが参加しているトークルームを作成し、「ここが詰まった...」「ここまでいけた〜！」「これはここでまとめました」など思い思いの心の声をつぶやいてもらう

## 良かったこと
- 関わっているメンバーの拠点が異なっていたため遠隔での連携がなかなかできず情報共有に関して課題感を持っていたが、分報ルームを作成したことで遠く離れているチームメンバーがどんなことで今悩んでいるのか、どこまで進めることができたのかなど詳細に知ることができた
- シンプルにあの人進んでんのかな...?がなくなった
- しょうもない事から難解な問題まで困り事を周知できる機会になった、今までなんとなく言いずらかったことも気軽にアウトプットできる場になっていた
- つぶやくハードルがものすごく低いので、役職や立場関係なく気軽にコミュニケーションを取ることができメンバー間の信頼と安心感が増した
- システムごとに作成していたため、期間が空いてしまってもその時思っていたことを後から簡単に見返すことができた。また、ドメインを侵略しないことで情報の粒度も分けることができた

## 注意点
- ユーザーとコミュニケーションをとるトークルームなどと混合しないよう注意、うっかり間違えてつぶやいてしまいユーザーに見て欲しくない内容を投下しないようにする
- 認知負荷が高まりがち、自分の場合は複数システムを抱えていたためにたくさんの分報ルームに参加していた。それによって複数ルームから通知が飛び交いその確認に時間が取られることがあった。不要なルームは退会、または通知を切るなどして業務に集中できるようにする必要がある

## さいごに
結論自分は「分報」を取り入れて良かったと思っていますし、推奨していきたいと思っています。
その他懸念点やより良くするための改善方法があれば教えていただきたいです。
CentOSの後釜を考える

# 2024年6月を持ってCentOSがサポート切れとなりました。
いまから後釜を考えるのもなんですが・・・
未だにCentOS7.9を使っている人も多いでしょう。

# 後釜候補１
やはりCentOS Streamをあげないわけにはいかなのかと思います、
しかしながらこれが、サポートが短い。
REDHATのテスト環境？というところもありちょっと不安が残る。

# 後釜候補２
Rocky Linuxは後継本命と目されるディストリビューションの一つで色んな評価を読んでみても評価が高い。
（自分では試せていない）

# 後釜候補３
AlmaLinuxちょっと古めのPCにインストールしてみたが、環境構築時にネットワーク環境などで少し面倒だった。

# 後釜候補４
日本人ならこれがいいかも！！
Miracle Linux８系と９系でも試してみましたが環境づくりが結構楽に済みました。
2021年10月以降に無償化されている。
ソリューションアーキテクトに求められる視点(3/14)  CloudFormation

## はじめに
ソリューションアーキテクトのための視点を整理してみました。

今回は、**CloudFormationです。具体的には、「カタログ化する方法」「リソースを保持する方法」「S3バケットの削除が上手くいかない時の対応」「カスタム名を持つリソースがある場合」** を想定しました。実務でも試験でも、ご参考にして頂けましたら、幸いです。

### 目次

3. [カタログ化する方法](#カタログ化する方法)
1. [リソースを保持する方法](#リソースを保持する方法)
2. [S3バケットの削除が上手くいかない時の対応](#S3バケットの削除が上手くいかない時の対応)
4. [カスタム名を持つリソースがある場合](#カスタム名を持つリソースがある場合)


## カタログ化する方法
**要件**
• AWS インフラストラクチャの起動時にユーザーに最小限の特権アクセスを提供し、ユーザーが未承認のサービスをプロビジョニングできないようにしたい。
• 中央アカウントを使用して、インフラストラクチャ サービスの作成を管理したい。
• AWS Organizations の複数のアカウントにインフラストラクチャ サービスを配布する機能を提供したい。
• ユーザーが開始するインフラストラクチャにタグを強制する機能を提供したい。

**ソリューション**

AWS CloudFormation テンプレートを使用してインフラストラクチャ サービスを開発します。各テンプレートを AWS Service Catalog 製品として、中央の AWS アカウントで作成されたポートフォリオにアップロードします。これらのポートフォリオを、会社用に作成されたOrganizationと共有します。

ユーザー IAM ロールに ServiceCatalogEndUserAccess 権限のみを許可します。自動化スクリプトを使用して、中央ポートフォリオをローカル AWS アカウントにインポートし、TagOption をコピーし、ユーザーにアクセス権を割り当て、起動制約を適用します。 

AWS Service Catalog TagOption Library を使用して、会社が必要とするタグのリストを管理します。 TagOption を AWS Service Catalog 製品またはポートフォリオに適用します。

## リソースを保持する方法

**CloudFormation のスタックを削除する際に、リソースの保持が出来ずに困っています。どのようにすれば、リソースを保持する事が出来るでしょうか？**

**ソリューション**

DeletionPolicy 属性をRetainにします。そうすることで、CloudFormation は、スタックを削除する際に、リソースやコンテンツを削除せず保持します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/ba7f1994-b387-b7f4-a719-a9a0ff7ebcae.png)

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html

https://repost.aws/ja/knowledge-center/delete-cf-stack-retain-resources

https://youtu.be/qwX8UmEb9bQ

## S3バケットの削除が上手くいかない時の対応

**古いバージョンの CloudFormation スタックを削除しようとしましたが、操作は失敗。CloudFormation が既存の S3 バケットの削除に失敗したことがわかりました。どのようにこの問題を解決しますか？**

**ソリューション**

S3 バケットからすべてのファイルを削除する Lambda 関数を実装。この Lambda 関数をカスタム リソースとして CloudFormation スタックに統合。カスタム リソースに、S3 バケットのリソースを指す dependsOn 属性があることを確認する。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html

DependsOn 属性を使用すると、特定のリソースが他のリソースに続けて作成されるように指定できます。DependsOn 属性をリソースに追加した場合、そのリソースの作成は必ず、DependsOn 属性で指定したリソースの作成後に行われます。


## カスタム名を持つリソースがある場合
CloudFormation スタック セットを使用してツールをデプロイします。スタック セットのテンプレートには、カスタム名を持つ IAM ロールが含まれています。スタック セットの作成時に、スタック インスタンスが正常に作成されません。インスタンスを正常に作成するために、どのような対応が必要ですか？

**ソリューション**

スタック セットの作成時に CAPABILITY_NAMED_IAM 機能を指定します。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/automation-action-createstack.html

カスタム名を持つ IAM リソースがある場合は、CAPABILITY_NAMED_IAM を指定する必要があります。このパラメータを指定しない場合、このアクションは InsufficientCapabilities エラーを返します。次のリソースでは、CAPABILITY_IAM または CAPABILITY_NAMED_IAM を指定する必要があります。

#### ソリューションは、あくまで、一例です。他の解決方法もあるので、参考程度にしてください。

#### 読んでいただき、ありがとうございました。
MUI themeのカラー設定

# MUIで事前にカラーの設定を行う
NextjsとMUIを利用するときに、最初の設定である程度カラーを設定し利用しようと思って設定を探してみました。

## 基本的なthemeの設定
```tsx:theme.tsx
const theme = createTheme({
  palette: {
    primary: {
      main: "#EFE5FD",
    },
    secondary: {
      main: "#2db8d0",
    },
  },
  typography: {
    fontFamily: "Roboto, sans-serif",
  },
});

export default theme;
```

```tsx:/layout.tsx
export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ja" className="w-[100%] h-[100%]">
      <ThemeProvider theme={theme}>
        <body className={inter.className}>
          <CustomNavbar />
          {children}
        </body>
      </ThemeProvider>
    </html>
  );
}

```

上記のように設定することで基本的なMUIの設定が完了します。

## MUIでカラーを追加設定して使用する場合
以下ではprimary[400]などを追加で定義して使う方法となります。

まず、上記で定義したthemeにカラーを追加し、
PaletteColorにタイプを追加します。

※PaletteColorタイプを追加しないと、使用する際にエラーになってしまうので注意

```tsx:theme.tsx
"use client";

import { createTheme } from "@mui/material/styles";

declare module "@mui/material/styles" {
  interface PaletteColor {
    "50"?: string;
    "100"?: string;
    "200"?: string;
    "300"?: string;
    "400"?: string;
    "500"?: string;
    "600"?: string;
    "700"?: string;
    "800"?: string;
    "900"?: string;
  }
}

"use client";

import { createTheme } from "@mui/material/styles";

declare module "@mui/material/styles" {
  interface PaletteColor {
    "50"?: string;
    "100"?: string;
    "200"?: string;
    "300"?: string;
    "400"?: string;
    "500"?: string;
    "600"?: string;
    "700"?: string;
    "800"?: string;
    "900"?: string;
  }
}

const theme = createTheme({
  palette: {
    primary: {
      "50": "#efe5fd",
      "100": "#d4bff9",
      "200": "#b794f6",
      "300": "#9965f4",
      "400": "#7e3ff2",
      "500": "#6002ee",
      "600": "#5300e8",
      "700": "#3d00e0",
      "800": "#1d00db",
      "900": "#0000d6",
    },
    secondary: {
      "50": "#fffde6",
      "100": "#fef9c2",
      "200": "#fdf699",
      "300": "#fcf16f",
      "400": "#f9ec4b",
      "500": "#fcec2a",
      "600": "#fbd922",
      "700": "#fac118",
      "800": "#f9a80a",
      "900": "#f77e00",
    },
  },
  typography: {
    fontFamily: "Roboto, sans-serif",
  },
});

export default theme;
```

/layout.tsxファイルは変更点がないので、そのままで大丈夫です。

これで実際のコンポーネントに適用する準備ができました。

次に以下のようにuseTheme()メソッドを利用し、
theme.tsxで設定した色を使用することができます:laughing:

```tsx:/page.tsx
"use client";

import { Typography, useTheme } from "@mui/material";

export default function Home() {
  const theme = useTheme();
  return (
    <Typography sx={{ color: theme.palette.secondary[400] }}>Hello</Typography>
  );
}

```
TypescriptでFunctionalプログラミングする方法

# 関数型プログラミングの利点

関数型プログラミングはソフトウェア開発で使用されるパラダイムの一つです。もちろん、すべての状況に適しているわけではなく、使用ケースや要件に応じて考慮する必要があります。

- 高い抽象化レベル：関数型プログラミングはデータと関数を組み合わせて抽象化を達成します。これにより、コードが簡潔になり、理解しやすくなります。

- 不変性：関数型プログラミングはデータを変更せず、新しい値を生成します。これにより、コードが予測可能で、デバッグが容易になります。

- 関数の純粋性：純粋関数は同じ入力に対して常に同じ結果を返し、副作用がありません。これにより、コードがより安定し、テストしやすくなります。

- モジュール性：関数型プログラミングは小さく、再利用可能な関数を組み合わせてプログラムを構築します。

- 並列処理：関数型プログラミングは副作用のない純粋関数を使用するため、並列処理を簡単に実装できます。

- 遅延評価：関数型プログラミングは必要な場合にのみ計算を実行します。これにより、不要な計算を減らし、メモリ使用量を最適化できます。

## 例示コード

たとえば、果物の価格を知らせる関数と高価かどうかを知らせる関数がある場合、一般的なプログラミングでは二つの関数を以下のように組み合わせるでしょう。

``` ts
const getPrice = (fruit: string): number => {
    const prices = { apple: 100, orange: 80, banana: 60 };
    return prices[fruit];
};

const isExpensive = (price: number): boolean => {
    return price > 70;
};

// これを関数型プログラミングのコンポーズ関数で組み合わせる
const compose = <T, U, V>(f: (b: U) => V, g: (a: T) => U) => (x: T): V => f(g(x));

const isExpensiveFruit = compose(isExpensive, getPrice);

console.log(isExpensiveFruit("apple")); // true
console.log(isExpensiveFruit("banana")); // false

```

上記の内容はTypeScriptにおける関数型プログラミングのcompose関数に関する説明です。この方法により、関数を簡潔に組み合わせ、コードの再利用性と可読性を高めることができます。

また別の例として、果物の価格を教えてくれる関数と、高いかどうかを教えてくれる関数がある時、一般プログラミングでは二つの関数を以下のように組み合わせるでしょう。

``` ts
export function getPrice(name: string): number | undefined {
    if( name === "tomato"){
        return 7000;
    } else if (name === "orange"){
        return 15000;
    } else if (name === "apple"){
        return 10000;
    }
}
export const isExpensive = (price: number | undefined) =>{
    if(price === undefined) return false;
    return price > 10000;
}

export const isExpensivePrice(name:string):boolean =>{
    return isExpensive(getPrice(name));
}
```

しかしながら、上記の方式で関数を組み合わせると、再利用性が落ちるという問題があります。 関数を組み合わせる方向に応じて、新しい不要な組み合わせ用関数を生成する必要があります。

そのため、以下のようにGenericを利用してcompose関数を具現することができます。

``` ts
export const compose = <A,B,C>(g:(y:B) => C, f:(s:A)=> B) => (x:A) => {
    return g(f(x));
}
// <A,B,C>((B) => C, (A)=> B) => (A) => C
export const main = () => {
    const res = compose(isExpensive,getPrice);
    console.log(res("orange"));
}
main(); // true
```

上記のcompose関数の場合、fで明示された関数が先に実行された後、gが実行されます。 そして、一番外にあるパラメーター(x:A)が一番最初にパラメーターが入力される部分と見ることができます。

compose関数で組み合わされるres関数は、上で定義したisExpensivePriceと同様です。

``` ts
function compose<string,number,boolean>( g: (y: number) => boolean, f: (s: string) => number): (x: string) => boolean
```

res 関数にリターンされるタイプは以下のとおりです。

``` ts
const res: (x: string) => boolean
```

Genericが表示されたら:typeを消して表示したり、webstormでマウスを上げたりすると、どのような形式で関数が宣言されるのか確認できます。 タイプが間違っているとコンパイラでキャッチしてくれるので、これを参考にすればいいです。

## Summary
Functional プログラミングは重複する関数を減らし、コードのクオリティを高めることができる利点があります。 実務ですぐに適用しにくいのなら、少しずつ適用して増やしていくのはどうでしょうか？