OmniAICreator/Qiita-1.07M huggingface dataset:
GodotEngineの何が凄いのか

# GodotEngineの何が凄いのか
最近Unityというゲームエンジンが料金プランを変えたりしたことで話題になっています。
つい５年前ぐらいまでは**UnityとUE**【UnrealEngine】が２強でしたが、最近起きているゲーム業界の移り変わりと共に、そんな常識も変わっています。その中で少しずつ力を伸ばしてきたのが今回紹介する**GodotEngine**です。
最近は日本でもGodot移管する書籍を見かけ始めるようになったのでこの記事を書くことにしました。
この記事が気に入ったら、GootEngineが広まるためにもSNSでのシェア等よろしくお願いします。

![D4C4A8DB-E2E6-4F06-AE08-70A7EC25718C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850578/c56b2522-9b13-90c5-7983-9d34f62a587d.jpeg)

## GodotEngineって何🤔？？？
::: note info
この先は回りくどく書いているだけなので忙しい人向けにこの記事の要点を書いておきます
Godotのすごい所
1. 初心者でも使いやすい
2. 軽い
2. コミュニティが充実している
2. 完全無料で使う事ができる
2. 3D/2Dどちらのゲームでも使う事ができる
:::
GodotEngineは先ほども言った通り２０１４年に最初のバージョンがリリースされた、ゲームエンジン（ゲームを作成するのに必要な機能などがたくさん詰まっているアプリ）です。そんなGodoEngineはほかのゲームエンジンなどとは違い、**オープンソース**なので誰でもGodotEngineのソースコードを変更したり、見ることが出来ます。
UnityやUE(unrealengine)のように特定の大企業が運営しているわけでもなく、Godotの開発者たちとそのコミュニティのメンバーが日々GodotEngineをより良いものにしています。
『3DCG業界で有名なBlenderもGodotと同じ体制をとっているので、このまま行けばBlenderと同じぐらい有名になるかもしれません…』

オープンソースなのはその特徴の一つですが、Godotの最大の特徴ともいえるのがその**料金**です。
Unityなどとは違い、Godotは**完全無料**で使ことが出来ます。
もちろん、スプラッシュスクリーンにロゴが表示されたりすることはありません。この料金設定のおかげで、GodotEngineはインディーゲーム制作者や学生さんなどでも気軽に使いやすくなっています。
実際、UnityやUEを使用すると割と収益の大部分が取られてしまうのですが、Godotを使用すれば完全無料なので収益のほとんどを残す事ができます。

プログラミングにはPythonに似たGDScriptという独自の言語か、C#などのC言語を使うことが出来ます。
Unityから移行する時も、c#を引き続き使えるので楽です。
下の画像の通り、なかなか使えるエディターも内蔵しているので割とほとんどの作業をGodotで完結できるのもGodotの強みの一つです。
![スクリーンショット 2023-10-09 220629.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850578/a200aff7-ee7c-8708-37e2-a7cfb5ed8ef7.png)

嬉しいことに僕がGodotを使い始めた１年前よりは日本語の解説も増え、需要も大幅に伸びました。
そんな感じで将来性もしっかりあるので、使い方を学んで**絶対**損はないです。

![スクリーンショット 2023-10-09 215424.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850578/a1483626-3933-ce6a-0add-83e64c198fda.png)
<small>-GoogleTrendsのGodotの検索結果-
需要が少しずつ上がっているのが視覚的に分かる</small>

## Godotで出来ること
Godotでは2D、3Dどちらも作る事が出来ます。つい最近まで3Dは弱いと言われていましたが、4.0という大型のアップデートを機に3Dにも強くなりました。2Dに関しては以前から高い評価を得ていたのに加え、先ほども述べた4.0のアップデートでさらに強化されているのでとても使いやすいです。


GodotではAAAゲーム(スタジオが作る超ボリュームが高いゲーム)が造られた経験はないのですが、少しずつGodotで作られヒットしたインディーゲームは増え続けています。
インディーゲーム以外でも最近は利用され始めているので、もしかしたらGodotで超有名ゲームが作られる日もそう遠く無いのかもしれません。

下にGodotで作成されたゲームを挙げてくので良ければ「こんな感じのゲームも作れるんだ〜」みたいな感じで見てみてください

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

# 最後に　
Godotは日本語の情報も増えつつあり、人気が高まっているゲームエンジンです。下のリンクにチュートリアルをまとめているので、是非今からGodotライフを始めてみてください。
最後まで読んでいただきありがとうございました。

https://qiita.com/FireDingo/items/d6e2a5674a965100d1a2
VS CodeのJava 設定




+ [Set Your Java Version](https://developer.salesforce.com/tools/vscode/en/troubleshooting/#set-your-java-version)


# Unsupported Java version

+ [Fix the unsupported Java version error in VS Code](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000HEf0p)

:::note
Please check this article.

Fix the unsupported Java version error in VS Code
https://www.youtube.com/watch?v=BwBNsLBpnVs
:::

+ [I can't see "Execute Anonymous Apex"](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007NAL0A)

:::note
Unsupported Java version

Which JDK are you using?
If you use zulu-11, please configure as follows

setting.json

```
{  "salesforcedx-vscode-apex.java.home": "/Library/Java/JavaVirtualMachines/zulu-11.jdk/Contents/Home"}
Java Setup
```

https://developer.salesforce.com/tools/vscode/en/vscode-desktop/java-setup
:::

+ [【未解決】Java Folder Path](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007NAoeX)

# I have checked Java:Home and PATH envoronment variables are correct. パスは正しい

+ [Unable to validate Salesforce CLI after installation](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgPMq)

:::note
Windows registry was found corrupted. After changing to a different laptop, this issue vanished.
:::

# Java 8 is required to run. Download and install it from https://java.com/en/download/.

+ [Getting error in degug your code challenge saying unsupported java version.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007KZSm7)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/820bfe0c-3072-9178-1d1b-2a149b188703.png)

:::note
I had this same problem. It took a while to get a solution.

This is how I finally resolved the problem for Windows.

I had multiple version of java installed. I uninstalled them all. Restart the PC.

Visit https://www.oracle.com/uk/java/technologies/javase/jdk11-archive-downloads.html and download the most recent version of Java 11

Get your java filepath. Mine looks like this C:\Program Files\Java\jdk-11.0.14. you only need to go as far as the Jdk-verion folder.

Go to Control Panel and search Environment Variables. Click on Edit the Sytem Environment variables > Environment Variables

In the System variables list. Make sure the JAVA_HOME is the same path ie C:\Program Files\Java\jdk-11.0.14. Click OK.

Now go to VS Code. File>Preferences>Settings ===> Seach apex. Paste the same path "C:\Program Files\Java\jdk-11.0.14" into "Salesforcedx-vscode-apex › Java: Home" text box field.

https://developer.salesforce.com/forums/?id=9060G0000005SSnQAM
:::
winter24でのchatterメール通知の件



+ [winter24でのchatterメール通知の件](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007MaWks)

+ [Chatter Email Notification 設定後に届かなくなったChatterはどうなる？](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007OW2vpSAD)

:::note
Only chatter emails will be triggered post setting up sender name & email address in chatter email settings. It will not trigger emails for previous chatter post.

Alternative is you can edit the existing chatter post and Save

See if that’s sending emails on previous chatter posts

Chatter メール設定で送信者名とメール アドレスを設定した後は、Chatter メールのみがトリガーされます。以前のチャット投稿に対するメールはトリガーされません。

別の方法として、既存のチャット投稿を編集して保存することもできます。

以前のチャット投稿でメールが送信されているかどうかを確認する
:::

+ [Winter 24 リリース以降、チャット電子メールは機能しなくなります。チャットメールの設定に進み、差出人名とメールアドレスを追加しました。メールで確認を受け取りました。チャットで @メンションを入力してもメールが届きません。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007OXJ6iSAH)

:::note
 I opened a case with salesforce.  It is resolved in our upper environments.  
:::

# ライセンス変更でメールの通知が届かない

+ [platformユーザにしてから、メンションしたメールが一部届かないということが起こっております。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007X9eEw)

# できないこと　アイデア

+ [Chatter email notification template](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007erDPl)

:::note
Looks like this is still an idea:

https://ideas.salesforce.com/s/idea/a0B8W00000GdcPUUAZ/edit-chatter-email-alert-subject-line-format-to-include-actual-subject-matter
:::
Active Recordの機能でクーポンの利用範囲を導入

## やったこと
従来はクーポンはどのタイミングでも利用可能だったが、初回限定クーポンや2回目以降限定クーポンも導入する必要が出てきたのでクーポンの利用範囲を設定できるようにした。おおまかな流れは、

 - Active Recordの機能で、データベースにクーポン利用範囲のカラムを追加。
 - クーポン利用範囲に入る値を設定
 - GraphQLのmutationロジック実装

という感じで進めた。

## ActiveRecord概要
ActiveRecordとは端的にいうと「DBの操作をRubyでできるようにした機能」である。
本来DB操作はSQL文で行うが、Rubyで行えるようになることでコードがRubyで統一されることがメリットと言える。詳細は以下。

https://railsguides.jp/active_record_basics.html

https://qiita.com/ryokky59/items/a1d0b4e86bacbd7ef6e8

## クーポン適用可能範囲のカラムを追加
migrationファイルを生成する。カラム名、追加するテーブル名、カラムの型を指定する。
`coupons`テーブルに`coupon_scope`という名前の整数値のカラムを追加する場合は

`$ rails generate migration add_coupon_scope_to_coupons`

を叩くことでmigrationファイルが生成される。
ちなみにカラムの変更はまだschema.rbには反映されていない。

## migrationの実行
以下のコマンドでmigrationファイルを元にカラムが実際に追加される。schemaにも反映される。

`$ rails db: migrate`

これにより追加した差分のmigrateが実行される。

## modelsでカラムに入り得る値を設定。
modelsで具体的なクーポンの利用範囲を設定する。今回は全範囲、初回限定、2回目以降の3パターンの利用範囲を設定した。文字列ではなくenum型で設定。
```ruby:coupon_mutation.rb
enum coupon_scope: { all_scope: 0, first_order: 1, from_the_second_order: 2 }
```

## 管理画面でscopeが使えるようにした。
このプロジェクトでは管理画面はadministrateと呼ばれるrailsのライブラリを使用している。
ここで、administrateの各項目に`coupon_scope`を追加して、管理画面でクーポンに利用範囲を設定できるようにした。
administrateの詳細は以下の記事などで確認できる。

https://qiita.com/AltGuNi/items/ecf3d9f49d363f3f3fd0


## 入力されたクーポンが利用可能かどうかの判定ロジック実装
frontendで入力されたクーポンコードが利用範囲外で使えない場合はエラー文を表示する。
例えば、2回目の注文時に初回限定クーポンのコードを入力した場合は「ここでは利用できません」と表示。

#### GraphQLのクーポン関連のmutationを確認する。
本プロジェクトではfrontとbackのデータの受け渡しにはGraphQLが用いられている。そのためfrontで入力されたクーポンコードをbackendで判定するにはGraphQLのmutationにロジックを書き加える必要がある。

```ruby:coupon_mutation.rb
def resolve
      Gql::Mutations::Coupon.new().call
end
```

クーポン関連のmutationファイルにはこんな雰囲気のresolveメソッドが定義されている。
ここからわかるのは、具体的なクーポン判定ロジックはCouponクラス内で定義されているcallで呼ばれているメソッドに書くべきだということ。

#### Couponクラスを確認する。
Couponクラス内のcallで呼ばれているmodels内のメソッドを書き換える。尚、今回の話に関係ない部分のコードは省略してある。

```ruby:order.rb
def check_coupon(coupon_code)
    coupon = Coupon.where(code: coupon_code).first
    # Coupon code can not be used
    raise StandardError.new('このクーポンコードはここでは使えません') if (coupon.first_order? && "2回目以降のorderである") || (coupon.from_the_second_order? && "初回のorderである")
end
```

StandardErrorは例外処理で使えるらしく、エラーメッセージを出すときによく使うらしい。詳しくはこちらの記事で。

https://qiita.com/kasei-san/items/75ad2bb384fdb7e05941

これで期待する動作が無事に確認できた。


## まとめ
今回のタスクの変更点は、

- 管理画面からクーポンに3種類の利用範囲(全範囲、初回限定、2回目以降限定)を設定できるようになった。
- ユーザーの注文が入力されたクーポンコードの利用範囲外だった場合、ユーザーに警告文を表示する。

である。
backendとfrontendの繋がりが意識できるタスクで、すごくいい経験になった。
next.jsをdocker, docker-composeで環境構築


まず、以下のコマンドでローカルにアプリを作成する。

npx create-next-app [好きなアプリ名]

じゃないと、Dockerコンテナ内でcreate-next-appからやろうと思ったがハマってしまったため。
参考記事

https://qiita.com/kaba_san/items/302b8b731e7fbfa56367

## Dockerfile

```Dockerfile
# ベースイメージの指定
FROM node:alpine

# 作業ディレクトリの設定
WORKDIR /app

# ソースをコピーする
COPY ./app .

# 依存関係をインストールする
RUN npm install

# ビルドする
RUN npm run build

# ポート3000でリッスンするように設定する
EXPOSE 3000

# アプリケーションを起動する
CMD ["npm", "start"]
```

## docker-compose.yml

```yml
version: '3'
services:
  web:
    container_name: nextjs_container
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./app:/app
      - /app/node_modules
    ports:
      - '3000:3000'
    environment:
      - NODE_ENV=development
    command: ["yarn", "dev"]
```

## 完成

![スクリーンショット 2023-10-18 8.38.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294049/74b0a171-7689-b751-1aa9-83c656b51ee1.png)
Getting sf_devops:Too many callouts: 101 exception

# Getting sf_devops:Too many callouts: 101 exception

+ [sf_devops:Too many callouts: 101 (when promoting an approved work item)](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007HLjJySAL)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/26138440-3e1b-496e-4a6f-f98e31f41b13.png)

+ [Getting sf_devops:Too many callouts: 101 exception](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007LpjWPSAZ)

:::note
Please check this article.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007HLjJySAL
:::


+ [sf_devops:Too many callouts: 101 (when promoting an approved work item)](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007HLjJy)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5a7a2708-9372-1429-14d7-3f105ca7b890.png)

:::note
 Encountered it for the first time today and was able to find the right info on my machine in .git > refs> remotes > origin > 'branch' .
:::
保存されていないレポートの数式を検証できませんが解消されたようです Winter 24



+ [保存されていないレポートの数式を検証できません](https://issues.salesforce.com/issue/a028c00000r71fkAAA/unable-to-validate-a-formula-in-an-unsaved-report)

今まではレポートで数式を保存しようとすると、レポート自体を保存していないとエラーになってしまいました。
Winter 24で解消されたようです。
APIコスト削減！開発環境でのキャッシュ活用方法

# 概要
自分もそうですが個人開発でAPIを使う方も多いと思います。
ただ実装過程で外部APIを頻繁に呼び出すことは、リAPIの利用制限、コストの増加を招きます。
これを解決するための方法として```キャッシュ```です。
![スクリーンショット 2023-10-18 7.38.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516334/4b17ab80-347f-c7d7-b729-7e8e90e5a9a5.png)
そんな時にRailsの```キャッシュ```というものを使えばこの問題を解決できます。
[Railsガイド Rails のキャッシュ機構](https://railsguides.jp/caching_with_rails.html)

:::note warn
私は初学者のため、間違った情報があればコメントなどで教えていただけると幸いです。
:::

## キャッシュとは
```「キャッシュ（caching）」```とは、リクエスト・レスポンスのサイクルの中で生成されたコンテンツを保存しておき、次回同じようなリクエストが発生したときのレスポンスでそのコンテンツを再利用することを指します。

多くの場合、```キャッシュ```はアプリケーションのパフォーマンスを効果的に増大するのに最適な方法です。キャッシュを導入することで、単一サーバーや単一データベースのWebサイトでも、数千ユーザーの同時接続による負荷に耐えられるようになります。
とRailsガイドに書かれています。

**つまり、```キャッシュ```を使って一回APIを叩けばそのデータやコンテンツが保存され、再度叩いてもその保存されたデータやコンテンツを再利用できるからリクエストやコストがかからないということらしいです。**

## 実装
今回はレシピなどが取得できる```Spoonacular API```を使って実装してみます。

:::note warn
状況によって多少コードは変わると思いますが、GPTに聞けばわかると思います笑
:::

#### 1. 開発環境でのキャッシュ有効化
開発環境でキャッシュを有効にするためにターミナルで次のコマンドを実行します。
```ruby:
$ bin/rails dev:cache
```
#### 2.条件付きGETの利用
以下のコードは、対象のリソースを提供するコントローラのアクションに追加します。
**indexアクションでのキャッシュ**
ユーザーごとに異なる結果が返される可能性があるため、キャッシュのキーにはユーザーのIDなどの一意の情報を含めます。
```ruby
def index
  user = current_user || User.new(name: "Guest")

  cache_key = "meal_plan_for_user_#{user.id || 'guest'}"
  @meal_plan = Rails.cache.fetch(cache_key, expires_in: 1.hour) do
    SpoonacularService.generate_meal_plan
  end
end
```

**showアクションでのキャッシュ**
エンドポイントがクライアントのキャッシュに存在するリソースの最新版を持っているかどうかを確認するために、```stale?```を使います。
例)recipes_controller.rb
```ruby
def show
    @resource = YourModel.find(params[:id])
    if stale?(last_modified: @resource.updated_at.utc, etag: @resource.cache_key_with_version)
        render json: @resource
    end
end
```
これにより、同じユーザーの同じリクエストや同じレシピの情報取得リクエストが1時間以内に行われた場合、SpoonacularServiceを介してのAPIの呼び出しは行われず、キャッシュから情報が返されるようになります。これでAPIのリクエスト回数やコストを削減できます。
**最後にサーバーを再起動します**
Databricksでセマンティック検索がサポートされました！

大規模言語モデル(LLM)がどんどん組み込まれてきています。

こちらの機能です。

https://docs.databricks.com/en/search/index.html#semantic-search

# セマンティック検索とは

自然言語、かつ、言語の意味を加味した検索を行います。対象はUnity Catalogのテーブルとなります。現時点では、テーブルのメタデータのみを検索するものであり、テーブル内のデータは検索しません。

# ウォークスルー

普段使っている検索ボックスで自然言語による検索がサポートされています。日本語でも動きます。

![Screenshot 2023-10-18 at 8.00.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/890c290c-2130-c543-2b92-ee2c9fce54ff.png)

`列数の多いテーブル`のような検索も可能です。
![Screenshot 2023-10-18 at 8.01.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7524534c-9347-f870-4782-27df4e2a866b.png)

是非ご活用ください！

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
wslでelixir その84

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
elixirで3Dが、やりたい。
3Dモデリングしたい。
3Dをグリグリしたい。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/0231a3ec-1bc1-62b6-f55b-5b9d72c819c4.png)


# 方針

- three.jsの力を借りる。
- モデリング言語を設計する。
- インタープリターを書く。

# サンプルコード

```
defmodule KinoThree.OBJ do
  use Kino.JS

  def new(url) do
    Kino.JS.new(__MODULE__, url)
  end

  asset "main.js" do
    """
    import "https://unpkg.com/three@0.124.0/build/three.js"
    import "https://unpkg.com/three@0.124.0/examples/js/utils/SceneUtils.js"
    import "https://unpkg.com/three@0.124.0/examples/js/controls/OrbitControls.js"
    export function init(ctx, html) {
      const canvas = document.createElement("canvas");
      ctx.root.appendChild(canvas);
      const renderer = new THREE.WebGLRenderer({
    	  canvas: canvas
      }); 
      const width = 500;
      const height = 400;
      renderer.setSize(width, height);
      const scene = new THREE.Scene();
      let camera = new THREE.PerspectiveCamera(60, 500 / 400, 1, 1000);
      camera.position.set(0, 100, 300);
      scene.add(new THREE.AmbientLight(0xffffff));
      scene.background = new THREE.Color(0xeeeeee);
      scene.add(new THREE.GridHelper(400, 10));
      var controls = new THREE.OrbitControls(camera, canvas);
	    var geometry = new THREE.Geometry();
	    var norml = new THREE.Vector3(0, 0, 1);       
      var textArray = html.split('/');      
	    for (var i = 0; i < textArray.length; i++)
	    {
		    var line = textArray[i];
		    if (line.indexOf('p ') === 0)
		    {
			    var tmp = line.split(' ');
			    geometry.vertices.push(new THREE.Vector3(tmp[1], tmp[2], tmp[3]));
		    }
		    else if (line.indexOf('s ') === 0)
		    {
    			var tmp = line.split(' ');
			    geometry.faces.push(new THREE.Face3(tmp[1] - 1, tmp[2] - 1, tmp[3] - 1, [norml, norml, norml]));
			    geometry.faces.push(new THREE.Face3(tmp[1] - 1, tmp[3] - 1, tmp[4] - 1, [norml, norml, norml]));
		    }
	    }      
	    geometry.computeFaceNormals();
	    geometry.computeVertexNormals();
	    var materials = [
		    new THREE.MeshLambertMaterial({
			    color: 0xffffff
		    }),
		    new THREE.MeshBasicMaterial({
			    color: 0x3333ff, 
			    wireframe: true,
			    transparent: true
		    })
	    ];
	    var mesh = new THREE.SceneUtils.createMultiMaterialObject(geometry, materials);
	    mesh.position.z = -5;
      scene.add(mesh);
      function tick() {
        controls.update();
	      renderer.render(scene, camera);
        requestAnimationFrame(tick);
      }
      tick();
    }
    """
  end
end

KinoThree.OBJ.new("""
p 0 0 0/p 100 0 0/p 0 100 0/p 100 100 0/p 0 0 100/p 100 0 100/p 0 100 100/p 100 100 100/s 1 3 4 2/s 1 5 7 3/s 2 4 8 6/s 1 2 6 5/s 3 7 8 4/s 5 6 8 7
""")
```


以上。
git delta



```
ダウンロード
$ wget https://github.com/dandavison/delta/releases/download/0.4.1/delta-0.4.1-x86_64-unknown-linux-musl.tar.gz
$ tar -zxvf delta-0.4.1-x86_64-unknown-linux-musl.tar.gz
$ cd delta-0.4.1-x86_64-unknown-linux-musl
$ sudo mv ./delta /usr/local/bin
```

.gitconfig
```
[core]
    pager = delta

[interactive]
    diffFilter = delta --color-only

[delta]
  diff-so-fancy=true
  keep-plus-minus-markers=true
  minus-emph-style="bold 94 89"
  plus-emph-style="bold 29 29"
  hunk-header-style="omit"
  line-numbers=true
  side-by-side=true
[merge]
    conflictstyle = diff3

[diff]
    colorMoved = default
```


参考: https://qiita.com/r12tkmt/items/ee504656a8ec0893ef40
Macを買い換えたのでNode.jsをasdfで入れるまでをやってみた。（備忘録）

m2にしたぞ！ばんざーい！！

というわけでbrewのインストールからasdfでnode.jsをバージョン管理するまで。
ちなみにintelでも同様。

>asdfのいいところ
バージョン管理ツールは他にも色々あるが、
asdfはnodeに限らずいろんなものをバージョン管理できる。
（nodenvなどはnodeしか管理できなかったり更新されていなかったりするのでasdfがより使われるツールになってきているのだとか。）

## brewのインストール
https://brew.sh/ja/
に書いてあるコマンドをコピペ
```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
入れればzshでも普通にインストールできる。
>zshの中でbashを動かしているらしい。知らんけど。


その際に
```
- Run these two commands in your terminal to add Homebrew to your PATH:
    (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/mappi/.zprofile
    eval "$(/opt/homebrew/bin/brew shellenv)"
- Run brew help to get started
- Further documentation:
    https://docs.brew.sh
```
と出てきたので

```
 (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/mappi/.zprofile
```
```
eval "$(/opt/homebrew/bin/brew shellenv)"
```
してbrew helpでインストールを確認する。
参考：
https://aiacademy.jp/media/?p=2817

## asdfのインストール

https://asdf-vm.com/guide/getting-started.html
のサイトの手順で実行。
↑のサイトに他のやり方も書いてあるけど
以下はMacでzsh（標準装備）のターミナルでbrewを使ったインストールになります。

```
brew install coreutils curl git
```
して
```
brew install asdf
```

先ほどの参考サイトを見ながら

```
echo -e "\n. $(brew --prefix asdf)/libexec/asdf.sh" >> ${ZDOTDIR:-~}/.zshrc
```

```
brew install gpg gawk
```
```
asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git
```

まずは最新版をasdfにインストール
```
asdf install nodejs latest
```
ちなみにこの状態でnode -vとかしても何も出てこないのですが、
ターミナルを再起動すると
```
No version is set for command node
Consider adding one of the following versions in your config file at 
nodejs 20.8.0
```
となり、asdfでのnodeを入れる準備は整いました。
（asdf instalの段階ではnodeは入らない。）
別バージョンが欲しい時は
欲しいnodeをまずインストールして(この時は12.0.0が必要だった)
```
asdf install nodejs 12.0.0
```
そしたらいよいよnodeを入れていくのですが
ローカル反映だと
そのファイル等のレポジトリに移動した後、
```
asdf local nodejs 12.0.0
```
とすれば、そのファイルのみnode.jsの指定のバージョンが適用される。
これでいろんなファイルに別バージョンのnodeをそれぞれに適用することが可能！🎉


ちなみに、globalでパソコン全体に入れたい時は
```
asdf global nodejs latest
```
latest（最新版）またはasdfであらかじめインストールした指定のバージョンにすればOK！
【Reactアプリ100本ノック】01 Hello World

![bandicam 2023-10-18 05-44-01-573.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/88d5373c-2c50-cfbb-8ace-525ca5f9d3df.jpeg)

# はじめに

<h3>こんにちは！！@Sicut_studyです！</h3>

https://qiita.com/Sicut_study/items/78910cd8d103b8d45a73

こちらの記事が嬉しいことに多くの方に見ていただきました。
そこで**React**が多くの初心者の方に注目されているんだなということを実感させられました。

私の記事では何度も言っている通り

<font color="red"><h4>最速で学ぶならとにかく何か作る</h4></font>

というのが大事になってきます。そこで **「Reactアプリ100本ノック」** というのに挑戦していこうかと思います。徐々に難易度を挙げていってどこまでお題を作りきれるかの腕試しでやっていただければと思います。

後半はかなり難しい実用的なものを作成することになるため、途中まで行うことでも1つクリアするたびに成長があるはずです。 **作りたいものがない** という方はぜひ活用してみてください


# Reactアプリ100本ノックルール

- 主要なライブラリやフレームワークはReactである必要がありますが、その他のツールやライブラリ（例: Redux, Next.js, Styled Componentsなど）を組み合わせて使用することは自由
- TypeScriptを利用する

# 01. Hello World


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/90349b3f-ec18-3b9d-028e-bfa789112e7e.png)

## 問題

"Hello World" React コンポーネントの作成

## 目的

Reactを使用して、画面中央に"Hello World"というメッセージを表示するコンポーネントを作成します。

## 達成条件

1. Reactの新しいプロジェクトが正しくセットアップされていること。
2. 画面に"Hello World"というテキストが中央に表示されていること。

## 実際に解いてみた

### 利用技術

- React
- TypeScript
- Vite
- Emotion

解答時間 : 3分

簡単なのが自明だったので普段あまり利用しないEmotionで中央寄せしてみました
はじめは簡単なお題が多いので利用したことのないライブラリなどを積極的に利用して難易度をすこし上げてみるのも良いかと思います。

# 次のお題

https://qiita.com/Sicut_study/items/82059f9cbb5b2996e5b3

# おわりに

React100本ノックの記事を地道に上げていこうと思いますので、一緒に挑戦したい方は @Sicut_study をフォローいただけるととてもうれしく思います。
ここまで読んでいただけた方はぜひ**いいね**と**ストック**よろしくお願いします。

<h5>少し宣伝します🔥🔥🔥🔥🔥</h5>

これからエンジニアになろうとしている人を本気でコーチングして3か月の期間で立派なエンジニアにするようなチャレンジをしてみたいなと考えております。

もし、本気でエンジニアを目指してコーチングを受けてみたいという方がいれば、[Twitter](https://twitter.com/Sicut_study)に「プログラミング教えてほしいです」みたいなリプライ送っていただけたらなと思います！！

以上です。
今週もプログラミング頑張りましょう！

![bandicam 2023-10-04 20-58-54-525.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/f41a0065-b23e-1895-da22-66bf0e48c5fb.jpeg)

# おすすめ記事

https://qiita.com/Sicut_study/items/ac2d791b439aa7fcae30

# 参考

https://emotion.sh/docs/introduction
大手企業の貧弱な開発環境の個人的メモ

金融系、医療系、公共系といった社会のインフラに関わる組織、または自動車系など最新の工業技術に関わる組織はサイバー攻撃への対応がビジネス上の重要な問題となりつつあります。サイバー攻撃にガチガチに対策した結果、ITエンジニアに優しくない環境になることが SNS などで話題にあがります。ここでは、大手企業なのに貧弱な開発環境について　X(旧Twitter） で話題になっていたので、メモします。

#### 自動車系のサイバー攻撃

https://xtech.nikkei.com/atcl/nxt/mag/nc/18/092400133/030900072/

### 医療系のサイバー攻撃の事例

https://xtech.nikkei.com/atcl/nxt/column/18/01157/012600079/

### 公共系のサイバー攻撃の事例

https://eset-info.canon-its.jp/malware_info/trend/detail/160308.html

### 貧弱な開発環境の例

https://biz-journal.jp/2023/10/post_360191.html

<!-- https://twitter.com/kasukabe_gsp/status/1713881770805096773 -->

### SNSのコメント(主にTwitter）

「最近は本社サーバの仮想win11とリモートデスクトップ用pcのみ、メモリもCPUもディスクも最低限で変更不可とか、いかにもお役所本社がコストだけで考えた支給PCが世に蔓延ってるので、こっそり増やす手段がなかったりします」

「大企業だと、SCCMのような製品を使ってコンピュータのインベントリを管理していると思われ、勝手にPCの構成を変更すると、始末書もの！？。」

「最近の富士通制ノートPCはメモリソケットが無くて、基盤に直接ハンダ付けされてる」

「構内にスマホを持ち込むときにカメラ部分に封印シールを張る。」

「社内ネットワークへの実験機器の接続が禁止されている。」

「USBメモリの使用禁止。でもPC付属のSDカードリーダだとOKだったりする。」

「標準外ソフトをインストールするときは申請が必要になる。」

「URLフィルタで社内からアクセスできるサイトが制限されている。」

## 大手企業が使うプログラム言語からの考察

 情報処理推進機構 (IPA) が公開している「[ソフトウェア開発 分析データ集 2022](https://www.ipa.go.jp/digital/chousa/metrics/index.html)」によると「[ソフトウェア開発プロダクトで使われているプログラミング言語](https://www.ipa.go.jp/digital/chousa/metrics/hjuojm000000c6it-att/000102171.pdf#page=13)」は以下の通り。国内の IT ベンダーは Java と COBOL、VB.NET を主に採用している。Java や COBOL の開発環境を動かすだけなら「10年前のPCスペックで十分」という判断になるのかもしれない。


### ソフトウェア開発プロダクトで使われているプログラミング言語

![16_IPA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/643a0ee1-584f-2491-c6cb-9b3f2dee57a4.png)
esxi Ubuntuのディスク拡張

## 実行コマンド
```
root@ub22:~# lvextend --resizefs -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv
  Size of logical volume ubuntu-vg/ubuntu-lv changed from <15.00 GiB (3839 extents) to <30.00 GiB (7679 extents).
  Logical volume ubuntu-vg/ubuntu-lv successfully resized.
resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/mapper/ubuntu--vg-ubuntu--lv is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 4
The filesystem on /dev/mapper/ubuntu--vg-ubuntu--lv is now 7863296 (4k) blocks long.
```
## 実行前
```
$ df -h
Filesystem                         Size  Used Avail Use% Mounted on
tmpfs                              197M  1.3M  196M   1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv   15G   14G   91M 100% /
tmpfs                              982M     0  982M   0% /dev/shm
tmpfs                              5.0M     0  5.0M   0% /run/lock
/dev/sda2                          2.0G  129M  1.7G   8% /boot
tmpfs                              197M  4.0K  197M   1% /run/user/1000
```
## 実行後
```
root@ub22:~# lvdisplay
  --- Logical volume ---
  LV Path                /dev/ubuntu-vg/ubuntu-lv
  LV Name                ubuntu-lv
  VG Name                ubuntu-vg
  LV UUID                Q2OWHx-8i9n-8iY2-2gQo-i9d0-jUu2-hTNxnv
  LV Write Access        read/write
  LV Creation host, time ubuntu-server, 2023-10-14 07:17:34 +0000
  LV Status              available
  # open                 1
  LV Size                <15.00 GiB
  Current LE             3839
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0
```
```
root@ub22:~# lvextend
  No command with matching syntax recognised.  Run 'lvextend --help' for more information.
root@ub22:~# ll /dev/mapper
total 0
drwxr-xr-x  2 root root      80 Oct 17 21:05 ./
drwxr-xr-x 19 root root    4060 Oct 14 07:24 ../
crw-------  1 root root 10, 236 Oct 14 07:24 control
lrwxrwxrwx  1 root root       7 Oct 17 21:05 ubuntu--vg-ubuntu--lv -> ../dm-0
root@ub22:~# lvextend --resizefs -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv
  Size of logical volume ubuntu-vg/ubuntu-lv changed from <15.00 GiB (3839 extents) to <30.00 GiB (7679 extents).
  Logical volume ubuntu-vg/ubuntu-lv successfully resized.
resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/mapper/ubuntu--vg-ubuntu--lv is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 4
The filesystem on /dev/mapper/ubuntu--vg-ubuntu--lv is now 7863296 (4k) blocks long.
```

参考: https://minory.org/esxi-ubuntu-lvextend.html
Gitコマンドで既にあるaddやcommitを綺麗にしてプルする方法

# はじめに

開発を始める際に、プルをするタイミングで不要なステージエリアに上がっているファイルや、commitなどがある場合があります。

また、新規にファイルを作成していた場合手作業で削除する必要もあります。

そんなときに便利なコマンドを知ったので綺麗にする方法としてまとめていきます

# やり方

commit したものをすべて取り消す

```
$ git resotre --staged .
```

addしたものをすべて取り消す

```
$ git checkout .
```

リポジトリに管理されていないファイルをまとめて削除

```
$ git clean -df
```

# おわりに

これはエイリアスでまとめるのもよいかなと思ったりしています

# 参考

http://transitive.info/article/git/command/clean/
せんせー、ナノアセンブリってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、ナノアセンブリってなに？

# ナノアセンブリとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## ナノアセンブリって何？

みんな、小さなレゴブロックで遊ぶのが好きかな？レゴブロックを使って、色んな形を作ったり、高い塔を建てたりすることができるよね。今、科学者たちは、超ちっちゃいレゴブロックを使って遊んでいるの。それを「ナノアセンブリ」と呼ぶんだ。

## どういうこと？

ナノアセンブリは、本当に小さな、小さな部品を使って、新しいものを作る方法なの。これは、目に見えないほど小さいから、特別な道具が必要なんだ。科学者たちは、これらの小さなブロックを上手に組み立てて、今までにないものや、とても便利なものを作り出しているの。

## どうしてそれがすごいの？

この小さなブロックで作られるものは、とても特別で、すごい力を持っているんだ。例えば、病気の治療を助けたり、コンピュータをもっと速くしたり、クリーンなエネルギーを作ったりすることができるの。それに、これらの小さなものは、大きな問題を解決する手助けをしてくれるんだよ。

## だから、ナノアセンブリってなに？

ナノアセンブリは、超ちっちゃいレゴブロックを使って、新しいとても役に立つものを作ること。科学者たちは、これらの小さなブロックを使って、私たちの世界をより良く、より賢くするためのものを組み立てているんだ。

# まとめ

このように、ナノアセンブリは、小さなブロックで大きな夢を建てる方法なの。科学者たちがこれを使って、驚くような新しいものを作り、私たちの生活をもっと楽しく、もっと安全にしてくれるんだよ。それは、魔法のような科学の力なんだね！
せんせー、モノレイヤー材料ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、モノレイヤー材料ってなに？

# モノレイヤー材料とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## モノレイヤー材料って何？

ねえ、みんな、紙が一枚あると想像してみて。それがとってもとっても薄いんだよ。これが「モノレイヤー材料」。それは、とても小さな一枚の材料で、ほとんどの場合、ただの一層だけからできているんだ。

## どういうこと？

この紙のようなものは、本当に特別で、とても薄いけれども、強い力を持っているんだ。科学者たちはこの紙のような薄い材料を使って、新しいものを作ったり、発見したりすることができるの。例えば、電話がもっと良くなったり、コンピュータがもっと速くなったりするのを助けることができるんだよ。

## どうしてそれがすごいの？

この薄い紙のような材料がすごいのは、とても小さくても物事をする力があるからなんだ。たとえば、太陽の光を集めたり、電気をたくさん通したりすることができるの。それに、これらの薄い層は、とても丈夫で壊れにくいから、科学者たちは宇宙の探検や医者が病気を治すのを手伝う新しい道具を作ることができるんだ。

## だから、モノレイヤー材料ってなに？

モノレイヤー材料は、一枚の特別な紙みたいなもの。それはとても薄いけど、たくさんのすごいことをする力があるの。科学者たちがこれを使って、私たちの世界をもっと良くするための新しいアイデアを見つけられるんだよ。

# まとめ

このように、モノレイヤー材料は、とても薄いけれども力強い特別な「紙」なんだ。これがあると、科学者たちはもっと多くの発見をしたり、私たちの生活をより良くしたりするための新しいものを作ることができるんだよ。だから、これは魔法の紙みたいなものなんだね！
せんせー、マルチフォトンイメージングってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、マルチフォトンイメージングってなに？

# マルチフォトンイメージングとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## マルチフォトンイメージングって何？

みんな、カメラで写真を撮るとき、光が大切だって知ってる？マルチフォトンイメージングは、特別なカメラのようなもので、とっても小さな世界、例えば葉っぱの中や皮膚の下の細胞を見るために使われるんだ。このカメラは、普通のカメラとは違って、特別な光を使って、生きているものの中を深く見ることができるんだよ。

## どういうこと？

このすごいカメラは、特別な光（それを「フォトン」と呼ぶんだ）をいくつか一緒に使って、普通の光では見えないものを見せてくれるの。たとえば、動物や人間の体の中にある細胞や、植物の葉の中の細かい部分など、とても詳しく見ることができるんだ。

## どうしてそれがすごいの？

マルチフォトンイメージングがすごいのは、生きているものを傷つけずに、体の中や植物の中などを非常に詳しく見ることができるからなんだ。これによって、科学者たちはどうやって私たちの体が働いているのかや、植物が太陽の光をどう使っているのかなど、たくさんの大切なことを学ぶことができるんだよ。

## だから、マルチフォトンイメージングってなに？

マルチフォトンイメージングは、特別な光を使って、私たちが普段見ることができない世界を見せてくれるすごいカメラのようなもの。これによって、科学者たちは生きているものがどうやって動いているのかをもっとよく理解できるんだ。

# まとめ

このように、マルチフォトンイメージングは、見えない世界を探検できる魔法のようなカメラ。それは、私たちがどうやって生きているのか、病気をどうやって治せるのかなど、大切なことを学ぶのを手助けしてくれる、とてもすごい技術なんだよ！
50コンピューターを利用した不正行為

### コンピューターを利用した不正行為
バックドアによる不正侵入
通常通りアクセス経路以外、侵入者が不正行為に利用するために設置するのがバックドア
バックドアに関連するコンピューターウイルスにトロイの木馬がある。
フィッシング
　銀行やクレジットカード会社など、jituzaisuru会社を装ったメール、ショットメッセージを送るより、不正ホームページに誘導して、クレジットカード番号や暗証番号などのだまし取る行為。
DNSキャッシュポイズニング
 DNSサーバには、問い合わせ処理で得たドメインのIPアドレスを一時的にキャッシュする機能を悪用して、
DNSキャッシュに偽のドメイン情報を一時的に覚えこませる攻撃

**バックドアは、侵入者が通常のアクセス経路以外で侵入するために組み込むもの。**
**電子メールを発信して受信者を誘導し、実在する会社などを装った偽のWebサイトにアクセスさせ、個人情報をだまし取ることをフィッシングという。**
**DNSサーバのキャッシュ機能を悪用し、DNSキャッシュに偽のドメイン情報を一時的に覚え込ませる攻撃をDNSキャッシュポイズニング。**
**SQLインジェクション対策として行う特殊文字の無効化操作をサニタイジング。**
**辞書にある単語を片っ端から入力してログインを試みることを辞書攻撃という。**
**相対パスを利用し、Webサーバ内の未公開ファイルに不正アクセスする攻撃手法をディレクトリトラバーサル**
**非電子的手法　ソーシャルエンジニアリングという**
バッチでファイル削除

# ファイル、サブフォルダ削除

- [コマンド](#コマンド)
- [プリフィックス](#プリフィックス)
- [オプション](#オプション)

## コマンド
```bat
@echo off
set targetFolder=C:\batwork\data\
set num=-7

rem 指定したフォルダとそのサブフォルダ内のすべてのファイルに対して、更新日付が7日以前のものを削除
forfiles /p "%targetFolder%" /s /m * /d %num% /c "cmd /c if @isdir=FALSE del @path"

rem サブフォルダを削除
forfiles /p "%targetFolder%" /s /d %num% /c "cmd /c if @isdir==TRUE rmdir /s /q @path" 2>&1

set ret=%errorlevel%
echo %ret%

exit /b %ret%
```

## プリフィックス
`forfiles` コマンドで使用される `@` プリフィックスは、コマンド内で特定の変数やプロパティにアクセスするためのプレースホルダとして機能します。

1. `@file`: 現在処理中のファイルの名前です。
2. `@fname`: ファイルの名前部分（拡張子を含まない）です。
3. `@ext`: ファイルの拡張子です。
4. `@path`: ファイルのフルパスです。
5. `@relpath`: ファイルの相対パスです。
6. `@isdir`: 対象がディレクトリ（フォルダ）である場合に `TRUE`、それ以外の場合に `FALSE` です。
7. `@fsize`: ファイルサイズです。
8. `@fdate`: ファイルの最終更新日です。
9. `@ftime`: ファイルの最終更新時刻です。

これらの変数やプロパティは、`forfiles` コマンド内で使用して、ファイルやディレクトリの情報にアクセスします。例えば、更新日付が一定期間よりも古いファイルを削除するスクリプトなどでよく使われます。

## オプション
/p "%targetFolder%": 操作を行う対象のフォルダを指定します。
/s: サブディレクトリ内も含めて処理します。
/m *: すべてのファイルを対象にします。
/d -7: 更新日付が7日以前のものを選択します。
/c "cmd /c if `@isdir`==FALSE del `@path`": 選択された各ファイルに対して実行するコマンドを指定します。

## ネットワークパスの回避について
forfiles コマンドは、UNCパス（ネットワーク上のファイルパス）をサポートしていない??
回避策としてpushd コマンドを使用してディレクトリに移動すると、ネットワークパスがローカルドライブの一時的な割り当てに変更されます。最後に、popd コマンドを使用して元のディレクトリに戻ります。
```bat
@echo off
set "uncPath=\\server\share\path"

pushd "%uncPath%"
forfiles /s /d -7 /c "cmd /c echo @path"
popd
```
vimの基本操作


## はじめに
vimはターミナル上でファイルの編集ができる
エディターです。
この記事では私が学習したコマンドを
まとめていきます。
ちなみに学習の際にはvimtutorを利用しました。
vimtutorはvimを使えるPCがあれば使える
vimのマニュアルです。ターミナルから`vimturor`と
入力すれば使えます。vim学習の際はまずこちらから
始めてみるといいと思います。

## vimのモード
vimは用途によってモードを使い分けて操作をします。
モードはノーマルモード、コマンドモード、
入力モード、ビジュアルモードの４つからなります。
vimが起動したら最初に基本のノーマルモードから始まり
ノーマルモードから入力モード、ノーマルモードに戻って
入力モードのようにノーマルモードを軸にしてモードを切り替えて使います。

## ノーマルモードのコマンド
ノーマルモードではカーソル移動やコピペをする際などに
使用するコマンドがあります。

**移動系のコマンド**
| コマンド | 挙動 |
|:-:|:-:|
| h | 左へ |
| j | 下へ |
| k | 上へ |
| l | 右へ |

こちらは覚えやすいと思います。
右手の人差し指から小指までで操作して
外側の指が左右、中の指が上下に対応します。

| コマンド | 挙動 |
|:-:|:-:|
| 0 | 空白を含めた行の先頭へ移動 |
| G | 下へ |
| gg | 空白を含まないファイルの先頭へ移動 |
| w | 空白を含めた単語の末尾に移動 |
| e | 空白を含めない単語の末尾に移動 |
| $ | 行の最後へ移動 |
| gg | 空白を含まないファイルの先頭へ移動 |
| w | 空白を含めた単語の末尾に移動 |

上記のコマンドはカーソルを効率よく動かすのに便利なコマンドです。
ここまで登場してきた移動系のコマンドは**モーション**と呼び、
他のコマンドと組み合わせて使うこともできます。
例えば削除に使用するdとggを組み合わせると
現在の位置からファイルの先頭までの文字を削除できます。
ぜひ移動以外でもモーションを積極的に活用していきましょう。

**編集系のコマンド**

| コマンド | 挙動 |
|:-:|:-:|
| d | 削除コマンド。モーションと組み合わせて使う |
| dd | 行全体を削除 |
| y | 選択した文字をコピー |
| p | コピーした文字を挿入 |
| u | 前回のコマンドを取り消し |
| U | 行全体のコマンドを取り消し |
| CTRL-R | 取り消しコマンドの取り消し |
| r | 文字を置き換える |
| c | モーションと組み合わせて文字を変更 |
| :s/old/new | 行の最初のoldをnewに変更 |
| :s/old/new/g | 行の全てのoldをnewに変更 |
| :#,#s/old/new/g | #の間に入力された行間のoldをnewに変更|
| :%s/old/new/g | ファイル全体のoldをnewに変更する |
| :%s/old/new/gc | 上記のコマンドの挙動で一つ一つ変更するか確認する |

%s/old/new/gcと入力すると
```
replace with new (y/n/a/q/l/^E/^Y)?
```
と表示されます。
それぞれのコマンドの意味は以下になります。

| コマンド | 挙動 |
|:-:|:-:|
| y | 現在マッチしている文字を置換する |
| n | 現在マッチしている文字を置換しない |
| a | マッチした文字を全て置換する |
| q | 置換を終了する |
| l | 現在マッチしている文字を置換して終了する |
| CTRL-E | 上にスクロール |
| CTRL-Y | 下にスクロール |

## コマンドモードのコマンド
コマンドモードではファイルの保存やvimを終了
させるコマンドを扱います。
ノーマルモードから:を入力すると
コマンドモードに移ります。

| :q | vimを終了 |
| :q! | vimを強制終了 |
| :w | ファイルを保存 |
| :wq | 保存して終了 |

## 入力モード
テキストを入力するときに入力モードに入ります。
ノーマルモードからiを入力で移ります。
ノーマルモードに戻る際はescを押しましょう。

## ビジュアルモード
範囲選択をしたいときに使用します。
wからyで単語をコピーするなど
他のコマンドと組み合わせて使います。

## 最後に
ここまでで説明してきたコマンドはvimの一部で
他にも便利なコマンドがたくさんありますので
実際に使いながら覚えてみてください。
gdbを便利に使うためのtips

## gdb -pをsudoなしで実行する
[Intel VTune Profiler の使い方](https://qiita.com/k0kubun/items/df7786611cf32877024c) でやってた奴だけど、

```
echo 0 > /proc/sys/kernel/yama/ptrace_scope
```

でok。CRubyのmakeの `RUBY_ON_BUG="gdb -p"` で使える

## layout asmで表示アドレスを移動する

```
disas [address],[address]
```

e.g.

```
disas 0x562ace7b322a,0x562ace7b322a
```
flaskアプリをサーバーに置いたときにタイムゾーンが想定と異なる結果となることについて

<h1>概要</h1>
<p>flaskアプリをサーバーに置いたときにタイムゾーンがUTCとなりました。
<br>ローカル環境ではJSTでしたので想定とは異なります。
<br>これはdatetimeでタイムゾーンを考慮に入れていないため起こります。
<br>つまりdatetimeを扱う際はタイムゾーンを扱うように実装する必要があります。
</p>

<h2>対応</h2>
<p>もともとは下記のように記述していました。</p>

```python
now = datetime.datetime.now()
```
<p>タイムゾーンを考慮に入れた実装は下記のとおりです。</p>

```python
now = datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=9)))
```
参考になれば幸いです。
React propsとstate

# PropsとState
propsとstateはコンポーネントのデータの管理方法であり，コンポーネント間でのデータの受け渡しなどで使われる．
それぞれを簡単に説明すると以下のようになる．
State：コンポーネント内で管理される<font color="Salmon">**プライベート**</font>な値
Props：別コンポーネントに渡す<font color="lightblue">**グローバル**</font>な値

# Props
Propsは親コンポーネントから子コンポーネントにデータを受け渡すために使用するオブジェクト．親コンポーネント内で使われている子コンポーネントに属性を設定することによって，propsとして子コンポーネントに値を渡すことができる．

## Propsの使い方
**親コンポーネント**
```React
const ParentComponent = () => {
	const name = 'John';
	
	return (
		<div>
			<ChildComponent name={name} age={30} message="Hello"/>
		</div>
	);
}
```
親コンポーネントで使用している子コンポーネントの属性値として指定することでデータを受け渡す．
<ins>プロパティ名は自由</ins>，<ins>受け渡す値が変数や数値は中括弧{}</ins>，<ins>文字列はダブルクォーテーション””で渡す</ins>．

**子コンポーネント**
```React
const ChildConponent = (props) => {
	return(
		<div>
			<p>Name: {props.name}</p>
			<p>Age: {props.age}</p>
			<p>Message: {props.message}</p>
		</div>
	);
}
```

子コンポーネントは，propsオブジェクトを引数として受けとり，親コンポーネントで指定したプロパティを受け取る．

propsを使用してデータを渡す場合，<font color="Salmon">データは一方通行である</font>．つまり，親コンポーネントから子コンポーネントにデータを渡すことができても，子コンポーネントから親コンポーネントに直接データを渡すことはできない．

# State
Stateは，コンポーネントの**状態**を管理するために使用するデータを指す．これを利用することで，ユーザのアクションや外部からのデータの変更に応じて，コンポーネントの表示を動的に変化させることができる．propsは代入後の変更が不可能であるのに対して，Stateは代入後の変更が可能という違いがある．

Stateの特徴として，Stateが更新されると自動で再レンダリングを行う．これはStateの更新がトリガーとなって再レンダリングを行うメソッドを呼ぶからである．stateはクラスコンポーネントを使う場合と関数コンポーネントを使う場合で異なる使い方をするため，それぞれについて説明する．

## Stateの使い方
**クラスコンポーネント**
```React
class TextInput extends React.Component {
	//初期化
	constructor(props){
		super(props);
		this.state = {
			text: 'hello'
		};
	}

	handleChange(event) {
		this.setState({ text: event.target.value });
	}	

	render(){
		return(
			<div>
				<input 
						type="text" 
						value={this.state.text}
						onChange={(event) => this.handleChange(event)}
				/>
				<p>入力されたテキスト：{this.state.text}</p>
			</div>
		);
	}
}
```

２．コンポーネントの初期状態の設定
→コンポーネントが初めてレンダリングされる場合，`constructor`メソッド内で`this.state`を初期化する．

２．Stateの更新
→`this.handleChange`を呼び出し，`this.setState`メソッドによってstateを更新する．
`handleChange`は`onChange`(つまり，入力フィールドの値が変更したとき)によって呼び出される

**︎関数コンポーネント**
```React
import React, { useState } from 'react';

function TextInput() {
  const [text, setText] = useState('Hello');

  const handleChange = (event) => {
    setText(event.target.value);
  };

  return (
    <div>
      <input
        type="text"
        value={text}
        onChange={handleChange}
      />
      <p>入力されたテキスト: {text}</p>
    </div>
  );
}
```
関数コンポーネントでは，<font color="lightBlue">Hooks(フックス)</font>というものを利用して，stateの管理と更新を行う．

- const [text, setText] = useState('Hello')
`useState`フックを使用して，<ins>初期値がHelloの`text`というstate変数</ins>と，その<ins>state変数を更新するための関数`setText`</ins>を宣言する．
- handleChange
`handleChange`関数は入力フォームが変更されたときに呼び出される関数で，その中では，state変数を変更する処理を行っている．`useState`で宣言したstate変数を変更する関数を利用することで，一緒に宣言したstate変数の値を変更する．

Hooksに関しては，別の記事にまとめた．

https://qiita.com/thirai67/items/7bf03a638f7db7d05c34
Railsのserializerについて調べてみた！


# serializerとは

serializerは、アプリケーションのデータをJSONやXMLなどのフォーマットに変換する際に非常に役立つ。serializerの基本的な使い方と、データの整形やカスタマイズ方法について解説します。

## 1. インストールと設定

serializerを使うには、

1. **インストール**: Rails アプリケーションにはデフォルトで `active_model_serializers` が含まれていないので、`Gemfile` に追加してインストールします。

    ```ruby
    gem 'active_model_serializers'
    ```

    インストール後、`bundle install` コマンドを実行してパッケージをインストールします。

2. **serializerの作成**: serializerは、`app/serializers` ディレクトリに作成します。モデルごとに対応するserializerを作成することが一般的。

## 2. serializerの作成と基本的な使い方

1. **serializerの生成**: serializerを生成するには、以下のコマンドを実行します。

    ```bash
    rails generate serializer ModelName
    ```

    これにより、`app/serializers/model_name_serializer.rb` ファイルが作成されます。

2. **serializerの設定**: serializerファイルで、シリアライズする属性を定義します。

    ```ruby
    # app/serializers/model_name_serializer.rb

    class ModelNameSerializer < ActiveModel::Serializer
      attributes :id, :name, :created_at
    end
    ```

    ここでは、`:id`、`:name`、`:created_at` の属性をシリアライズしています。

3. **シリアライズの呼び出し**: コントローラや API のエンドポイントで、シリアライザを呼び出してデータを整形します。

    ```ruby
    class SomeController < ApplicationController
      def show
        @model = Model.find(params[:id])
        render json: @model, serializer: ModelNameSerializer
      end
    end
    ```

    これにより、`ModelNameSerializer` を使用してデータが JSON 形式でレスポンスされます。

## 3. 関連データのシリアライズ

関連するモデルのデータをシリアライズすることも可能です。例えば、ユーザが持つ複数の投稿をシリアライズする場合は、以下のようにします。

```ruby
class UserSerializer < ActiveModel::Serializer
  attributes :id, :name
  has_many :posts
end
```

## 参考
https://github.com/rails-api/active_model_serializers
【VB.NET】カスタムコントロールの作成方法(プロパティの設定)

TextBoxのカスタムコントロールを作成する場合

## カスタムコントロールを追加する
プロジェクトタブ > 新しい項目の追加 > **カスタムコントロール(Windowsフォーム)**　を選択する。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3323019/135fc680-a3dc-be41-3256-8df1692fce54.png)


## デザイナーファイルで継承を変更する
・ソリューションエクスプローラで`○○Designer.vb`を探して開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3323019/64df330b-8b19-5d1a-6e7e-d03513d51d20.png)

・継承を変更する。(例：TextBoxのカスタムコントロールを作成する場合は、ControlをTextBoxに変更する。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3323019/f288e076-c669-5bb0-43fe-d9750d24ce13.png)

## カスタムコントロールのプロパティを設定する
・○○.vbを選択した状態で右クリックし、`コードを表示`を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3323019/64118045-5415-b3dc-96d5-d7b1edd4be25.png)

・以下は削除する。
```○○.vb
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    MyBase.OnPaint(e)

    'カスタム描画コードをここに追加します。
End Sub
```
<br>
・プロパティを追加する。（例：テキストボックスの背景色を変更する場合）

```○○.vb
Public Overrides Property BackColor As Color     ' textboxのbackcolorプロパティを継承
	Get
		Return MyBase.BackColor
	End Get
	Set(value As Color)
		MyBase.BackColor = value
	End Set
End Property
```
`Overloads プロパティ名`と入力すると、入力候補で出てくるかも。
<br>

・プロパティの初期値を追加する。(↑のコードの上に追加する。)
```○○.vb
<System.ComponentModel.DefaultValue(GetType(Color), "Yellow")>    ' プロパティの初期値
```
<br>
・コンストラクタを追加する。

```○○.vb
Sub New()

	' この呼び出しはデザイナーで必要です。
	InitializeComponent()

	InitializeComponent() 呼び出しの後で初期化を追加します。
	BackColor = Color.Yellow ' TextBoxの背景色を黄色で初期化
End Sub
```


## 動作確認をする
フォームのデザイナーでコンポーネントを張り付けて実行する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3323019/06acacfd-b6e3-fad7-8669-e9a96d47a38b.png)
※ツールボックスにカスタムコンポーネントが出ない場合は、1回実行すると表示されるかも。

## 参考サイト
カスタムコントロール作り方（初級）（TextBox編）
https://www.ratebelab.com/soft/program/670/

プロパティの既定値を設定する
https://radian.hateblo.jp/entry/2014/10/17/155258
Error: Cannot find module '../server/require-hook'の対処法

## 状況
Next.jsでのアプリ起動時に以下のエラー`Error: Cannot find module '../server/require-hook'`に遭遇しました。

```bash
% npm run dev

> my-nextjs-app@0.1.0 dev
> next dev

node:internal/modules/cjs/loader:942
  throw err;
  ^

Error: Cannot find module '../server/require-hook'
```

## 対処
`next`を再インストールすることで解決しました。
```bash
% npm uninstall next
% npm install next
```

このことから`Error: Cannot find module '../server/require-hook'`の原因としては、以下が考えられます。
- `next`モジュールの破損
- `next`のバージョン問題
- `npm`のキャッシュ問題
- `node_modules`の古い依存関係

参考になれば幸いです。
React importとexport

# importとexportについて
他のファイルに記述されているライブラリやコンポーネントを利用するための`import`と，他のファイルから利用できるようにする`export`の記述方法についてまとめる．

# import：使う側
ライブラリや別のファイルで記述したコンポーネントを利用するための，いくつかの基本的なimport方法をまとめる．

## Reactライブラリ
```React
import React from 'react';
```
Reactのコンポーネントを書く場合は必ず必要．

## ReactDOMライブラリ
```React
import ReactDom from 'react-dom';
```
Reactの仮想DOMをブラウザのリアルDOMに反映させる(つまり，HTMLにReactのコンポーネントを反映させる)ライブラリ．
基本的には，HTMLから参照されるjsファイルやjsxファイルにだけ記述すれば良い．

## コンポーネント
```React
import ComponentName from "componentsPath";
//または
import { ComponentName, ComponentName2 } from "componentsPath";
```
基本的には，`import [importするコンポーネント名] from [importするファイルのパス]`という形になる．

### 中括弧の有無について
importするコンポーネント名を中括弧で囲む場合がある．コンポーネントのエクスポート方法にはデフォルトエクスポートと名前付きエクスポートの２つの方法があり，それによって中括弧の有無が決まる
- デフォルトエクスポート：中括弧なし
- 名前付きエクスポート：中括弧あり

### 別名でimportする方法
```React
import * as name from 'componentPath';
import A as B from 'componentPath';
```
コンポーネントファイルの全体を別名でインポートする場合：`* as name`
コンポーネントファイルの一部を別名でインポートする場合：`A as B`

# export：使われる側
作成したコンポーネントをエクスポートすることで，別のファイルから利用できるようにする．
エクスポート方法については，名前なしと名前ありエクスポートの2種類がある．

## Defaultエクスポート(名前なし)
```React
function ComponentName() {
	//コンポーネントの定義
}
export default ComponentName;
```
または
```React
export default function ComponentName() {
	//コンポーネントの定義
}
```
`export`の後ろで`default`をつけることでエクスポートする．コンポーネントのファイルに複数のコンポーネントを定義することができるが，<font color="red">デフォルトエクスポートできるのは１つだけ</font>である．

## Namedエクスポート(名前あり)
```React
function ComponentName() {
	//コンポーネントの定義
}

function ConponentName2(){
	//コンポーネントの定義
}

export { ComponentName, ComponentName2 };
```
または
```React
export function ComponentName() {
	//コンポーネントの定義
}
export function ConponentName2(){
	//コンポーネントの定義
}
```
Namedエクスポートはdefaultをつけずにexportする．
デフォルトエクスポートは１つだけだが，<font color="Lightblue">この場合は複数をエクスポートすることができる．</font>
2023: Week 2 - International Bank Account Numbers / Preppin' Data / Tableau Prep

# Challenge Preppin'Data 2023:Week 2
Tableau Prep実行環境：Ver.2023.2.2

## 概要
データ ソース バンクには、英国で行われる取引であっても、国際銀行口座番号 (IBAN) を作成する必要があります。

Requirement
- トランザクション テーブルには、ダッシュが含まれる [ Sort Code ] フィールドがあります。ダッシュを取り除き、6 桁の文字列だけを用意します。
- SWIFT Bank Code 都合テーブルを使用して、受取銀行口座の SWIFT codeとCheck Digitsに関する追加情報を取得します
- Country Code のフィールドを追加します
- 不要なフィールドを削除する

## 問題のページ（英語）※ここからデータをダウンロード
https://preppindata.blogspot.com/2023/01/2023-week-2-international-bank-account.html

## 出題者の回答のページ（英語）※動画あり
https://preppindata.blogspot.com/2023/01/2023-week-2-solution.html

## 自分の解決法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/259216f6-03d2-d11f-f0cf-42113a49ae47.png)

1. データ ソースに接続し、Transactions テーブルを取り込みます。

1. 6桁のSort Codeの間の「-」を取り除きます。
クリーニング メニュー内に「句読点の削除」機能を使います。3 点メニューをクリックし、クリーニング > 句読点を削除 の順にクリックします。「-」が削除され、6 桁の数字だけが残ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/aea9b979-2d01-c093-7249-965ee7f6202e.png)

1. 次に、元のワークフローと Swift Codes テーブルを結合します。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/55f69084-363d-4dd8-78ba-ae672d097518.png)

1. 2つのテーブルのフィールドを結合し、IBAN フィールドを作成します。
IBAN = [Country Code]+[Check Digits]+[SWIFT code]+[Sort Code]+[Account Number]
すべてのフィールド タイプが文字列でないと、エラーが発生します。すべてのフィールドが文字タイプであることを確認してください。

1. 出力するフィールドとして IBAN とトランザクション ID だけを残し、それ以外の項目を削除します。

# TIPS
数字だけ、文字だけ、句読点だけを取り除くのがワンクリックで対応可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531257/67b31306-5bf3-f1b9-01df-27078d036e22.png)
Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?の対処法

## はじめに
node.jsでTypeScriptを使っていたので、dotenvを使用して環境変数を読み込もうとしたときに、表題のエラーが出ました。
調べてもぱっとすぐに日本語の記事が出てこなかったため、備忘録も兼ねてここに残しておきます。

## 解決方法
tsconfig.jsonのcompilerOptionに下記設定を追加
```
{
    "compilerOptions": {
        // 他の設定
        "moduleResolution": "node"
    }
}
```

## エラーの原因
tsconfig.jsonの設定でtargetを以降を設定している場合、moduleResolutionがデフォルトでnodeに設定されていないことが原因だったようです。
そのため、明示的にmoduleResolutionにnodeを設定してあげることで解決することができました。

エラーが発生したときのtsconfig.jsonはざっくり下記のような感じ
```
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
  }
}
```

下記のような感じに修正することでエラー解消
```
{
  "compilerOptions": {
    "target": "ESNext",
    /* Modules */
    "module": "ESNext",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    /* Type Checking */
    "strict": true,
    "skipLibCheck": true,
    "moduleResolution": "node" // ここを追加
  }
}

```


## 参考
[TypeScriptのissues](https://github.com/microsoft/TypeScript/issues/35876)
React コンポーネント

# コンポーネントの作り方
Reactにおける，コンポーネントの記述方法は，<ins>関数を利用する</ins>**関数コンポーネント**と<ins>クラスを使用する</ins>**クラスコンポーネント**の２つがある．

**関数コンポーネント**
```React
function FunctionComponent() {
	return (
		<div>
			<h1> Hello, World! </h1>
		</div>
	);
}

export default FunctionComponent;
```
```React
const FunctionComponent = () => {
	return (
		<div>
			<h1> Hello, World! </h1>
		</div>
	);
}

export default FunctionComponent;
```
このように関数コンポーネントは，関数を利用して定義を行う．関数の定義方法として，通常の関数とアロー関数があるため，関数コンポーネントの定義に両方とも利用することができる．

**クラスコンポーネント**
```React
class ClassComponent extends React.Component {
	render(){
		return(
			<div>
				<h1> Hello, World! </h1>
			</div>
		);
	}
}
```
クラスコンポーネントを定義する場合は，React.Conponentを継承するクラスで定義を行う．
renderメソッドはReactのクラスコンポーネントで定義される特別なメソッドで必ず実装する必要がある．コンポーネントの描画が行われる際に呼び出され，JSXを返す役割を持つ．

# 親コンポーネントと子コンポーネント
Reactではコンポーネントの中で別のコンポーネントを使うため，重要な概念として**親コンポーネント**と**子コンポーネント**という関係がある．

**親コンポーネント：使う側**
```React
const ParentComponent() {
	return(
		<div>
			<ChildComponent />
		</div>
	)
}
```

**使われる側：子コンポーネント**
```React
const ChildComponent() {
	return(
		<div>
			<p>Hello React!!</p>
		</div>
	)
}
```
このように，親コンポーネントとなるParentComponentが子コンポーネントであるChildComponentを使用する．

親コンポーネントから子コンポーネントへのデータの受け渡しはpropsというオブジェクトを利用する．propsについては別にまとめた．

# コンポーネントを書く際の注意点
コンポーネントを記述していく上で，注意しなければいけないことがいくつかある．

## １．タグ名の頭文字
```React
//間違った書き方
const myComponent = () => {
	// ...
}

//正しい書き方
const MyComponent = () => {
	// ...
}
```
Reactでは，<font color="red">コンポーネントのタグ名は大文字で始める必要がある．</font>小文字で始まるタグはHTMLの組み込む要素として認識される．コンポーネントは独自に作成されたものであることを示すために，大文字で始める必要がある．

## ２．クラス属性はclassではなく，className
```React
//HTML
<div class="my-class">Content</div>

//React
<div className="my-class">Content</div>
```
タグにクラス属性を指定する場合は，<font color="red">classではなくclassNameを利用する．</font>これは，JavaScriptのclassと違いをつけるためにclassName属性を使用する．

## ３．returnは１つの要素だけ
```React
// エラー
return(
	<p>１つ目</p>
	<p>２つ目</p>
)
//正解パターン１
return(
	<div>
		<p>１つ目</p>
		<p>２つ目</p>
	</div>
)
//正解パターン2
return(
	<React.Fragment>
		<p>１つ目</p>
		<p>２つ目</p>
	</React.Fragment>
)
//正解パターン3
return(
	<>
		<p>１つ目</p>
		<p>２つ目</p>
	</>
)
```
returnで返すものは１つだけなので，<font color="red">複数の要素を返すとエラーが起きてしまう．</font> 
`<div>`タグで１つにまとめるか，`<React.Fragment>`で囲むことで，１つの要素として返すことができる．また，`<React.Fragment>`は省略可能で，`<>` `</>`でも良い．
【React】textareaにフォーカスした際に文末にキャレットを移動する方法

以下のように記述することでフォーカス時に文末にキャレットが移動します。

```tsx

  <textarea
    onFocus={(ev) => {
      const len = ev.currentTarget.value.length
      ev.currentTarget.setSelectionRange(len, len)
    }}
  />


```