OmniAICreator/Qiita-1.07M huggingface dataset:
アクセルキャンプ復習動画５－９　Roblox Lua ブーブークッションを作ろう

みなさんこんにちは

今回はrobloxでブーブークッションを作っていきます。多少お下品な音がするかもしれません。

まず、先にゲームを作ります。

ブーブークッションとなるブロックを先に用意しておき、robloxに保存しておきます。

次に、おならの音を用意します。[このあたりのサイト](https://onara-mp3.com/)でお気に入りのおならの音（？）をダウンロードしておきます。

そしたら[roblox creators hub](https://create.roblox.com/)というサイトを見てみましょう。「ダッシュボード」「開発用アイテム」「オーディオ」と進み、先ほどのおなら音をアップロードします。


点三つのところをクリックし「アセットのIDをコピー」をクリックします

roblox studio に戻りましょう。

このような形で　ブロックの下にsoundとscriptを置きます。
![im.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2732489/dafd67b8-d9d4-842e-a9d2-8e39a7945a8b.png)


スクリプトはこんな感じ。ブロックに触った時のイベント処理で、script.Parent.Sound~ の部分で音を鳴らしています。
```lua
script.Parent.Touched:connect(function(hit)
	if hit.Parent:FindFirstChild('Humanoid')then
		script.Parent.Sound.Playing=true
	end
end)
```


soundのプロパティのsoundIDに、先ほどのアセットIDをペーストすれば完成
![im3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2732489/035fd28c-3571-0dd1-1d64-c028a53e4f77.png)
配列から連結リストを組み立てる【TypeScript】

## はじめに

こんにちは！Shungiku です。
最近は就活のために専ら LeetCode の問題を解いていることが多いです。

さて、LeetCode では連結リストの問題（[例えばこれとか](https://leetcode.com/problems/reorder-list/)）において、入力のサンプルが以下のような配列で与えられます。
```
head = [1,2,3,4]
```

一方、実際に Submit した場合、関数（またはメソッド）の引数で受け取る入力値は連結リストのヘッドのノードになっています。

ちなみにノードの構造は LeetCode では以下のように定義されています。

```ts
 class ListNode {
     val: number
     next: ListNode | null
     constructor(val?: number, next?: ListNode | null) {
         this.val = (val===undefined ? 0 : val)
         this.next = (next===undefined ? null : next)
     }
 }

```

「入力サンプルの配列を`ListNode`を用いた連結リストに変換してくれるヘルパー関数がほしい！」というのが、本稿のモチベーションです。

そんなヘルパー関数があれば、Failしたケースについてデバッグする際、サクッと入力値を用意できて便利です。


## 実装

配列から連結リストを組み立てる関数は以下のようになります。

```ts
function buildList(array: number[]): ListNode | null {
    let next_node: ListNode | null = null
    
    const reversed = array.slice().reverse()

    reversed.forEach(val => { // （１）
        const node = new ListNode(val) // （２）
        node.next = next_node // （３）
        next_node = node // （４）
    })
    
    return next_node
}
```

引数で受け取る配列を後ろから処理しています。

例えば引数が `[1, 2, 3, 4]` だった場合、 `[4, 3, 2, 1]` の順で以下のように処理が進みます。

１ループ目
- （１）`4` に対して処理を開始
- （２）ノードを生成（★）
- （３）★ノードの `next` に Keep してある `next_node` （初期値の null） を突っ込む
- （４）★ノードを `next_node` として Keep

２ループ目
- （１）`3` に対して処理を開始
- （２）ノードを生成（★）
- （３）★ノードの `next` に Keep してある `next_node` （前ループで生成した `4` のノード） を突っ込む
- （４）★ノードを `next_node` として Keep

3ループ目...以下同文

## まとめ

これで Fail したケースに対してのデバッグが捗るぜ...!

ちなみに木構造についても同様の記事を執筆してますので、以下ご参照ください。

https://qiita.com/shungiku/items/080fe0a0babdafff138c
Jenkinsインストール【Windows環境】

## はじめに
どうも、ねじです。
しばらく更新が滞っておりました。（ｻﾎﾞｯﾃｲﾀﾜｹﾃﾞﾊﾅｲﾖ)

最近、業務で環境構築(Jenkinsを使用できるようにしよう！)をする機会があり壁にぶち当たる場面がいくつかあった為、備忘録として本記事を残そうと思います。

## 作業環境
当記事は以下の環境で作業したものとなります。

・Windows 10 
・JDK,Maven,Go諸々ダウンロードされていない環境

## 目次
1.JDKのインストールしよう
 →Jenkinsを立ち上げるための準備です。JDKが既に環境にインストールされている(＋Java_HOMEの設定済)場合は本手順はスキップしてください。
2.Jenkinsを立ち上げてみよう
　→実際にJenkinsの立ち上げ画面までの手順です。

## 1.JDKのインストールしよう
※これをインストールしていないと、Jenkinsのインストールに失敗します。
①JDK公式サイトのURLにアクセスして「Download」をクリックします。
https://jdk.java.net/21/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/16f56005-06b7-4adc-4513-8f9253ae8aaf.png)

②ダウンロードしたZipファイルを解凍したのち、実行し任意のフォルダに保存します。

③環境変数の設定をします。
コントロールパネルを開いて、開いたらさらにシステムを開きます。

④システムの詳細設定をクリック。

⑤環境変数をクリック。

⑥新規ボタンをクリックしユーザー環境変数を追加します。
以下のように設定しOKボタンをクリック。
変数名：「JAVA_HOME」
変数値：1. JDK(Java Development Kit) のインストールにてJDKを保存した場所。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/95c2628e-7009-82f6-e8dd-6f32a2a4ff2b.png)

ユーザー環境変数の「Path」を選択した状態で編集ボタンをクリック。
ユーザー環境変数の編集画面が表示されますので、新規ボタンをクリックし、
「%JAVA_HOME%\bin」と値を設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/2280789f-f17f-8e25-2546-67ccb2795b75.png)



## 2.Jenkinsを立ち上げてみよう
①Jenkins公式サイトのURLにアクセスして「Download」をクリックします。
https://jenkins.io/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/9217929f-db5b-7fbc-ce3a-68b27923c81b.png)


②Windowsのリンクをクリック！
Jenkinsのダウンロードがはじまります。
※自分が使用したverであるかチェックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/682c9c2a-1493-9c93-3508-97430818c6a0.png)


③zipファイルを解凍して、中にあるjenkins.msiをダブルクリックします。


④インストール先を指定して進めていくとインストールが行われます。
※ダウンロード先はチェックしておきましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/593bed73-c69f-5f2f-e174-2ebe6a985353.png)


⑤インストールが完了すると自動でJenkinsの画面が立ち上がります。
※立ち上がらない場合はタスクバーにURL検索してみてください。
URL：localhost:8080/login?from=%2F


⑥Jenkinsをアンロックするパスワードを黄色の欄に入力します。
※入力するパスワードは、赤文字で書かれたパスにある赤枠のテキストファイルに記述してあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/ff0a3fa0-7ede-48b6-304d-01e19f99437f.png)


⑦Jenkinsで使用するプラグインを選択します。
左側は、便利であろうプラグインをインストール。
右側は、インストールするプラグインを選択。
※どちらを選んでも、後で追加インストールできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/ec80ca47-c0ac-aa57-35bd-9311f41c8d91.png)


⑧JenkinsのAdminユーザを作成します。
※Pjによってルールがあるため上位主任に確認しましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/aec289f0-2a25-d1c0-c525-f5223470dd54.png)


⑨JenkinsのURLの入力欄が表示されます。
デフォルトは、http://localhost:8080/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/702e05af-2b4b-1da2-9ea9-a4088da0218f.png)


⑩以下の画像が確認できたらインストールは完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609668/1792c478-4214-6054-4779-79a7d2da9bd9.png)


<font color="Red">次回は初期設定諸々を記載します。</font>

## 用語集
・Adminユーザー：登録利用者に与えられる操作権限のうち、システムの管理を行うためのもの


## 参考URL
https://itsakura.com/tool-jenkins-install

https://eng-entrance.com/java-install-jdk-windows
Snowflake Cortex LLM Functionsをテーブル内のフィールドを引数にして呼び出す

## Snowflake Cortex LLM Functionsとは

Snowflake Cortex LLM FunctionsはSQLでLLMを呼び出すことができる[^1]Snowflake独自の関数です。  

[^1]: Snowparkと呼ばれるPythonライブラリから呼び出すことも可能

https://docs.snowflake.com/en/user-guide/snowflake-cortex/llm-functions

## シンプルな呼び出し

```sql
SELECT SNOWFLAKE.CORTEX.COMPLETE('snowflake-arctic', 'こんにちは');
```
![simple](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/2944e58c-e4d1-6c72-ea39-0dcdde97a2d6.png)

## テーブル内のフィールドを引数にした呼び出し

SQLからは単純に関数として扱えるので、当然、テーブルに対するSELECT文の中に入れ込むこともできます。  

```sql
SELECT SNOWFLAKE.CORTEX.COMPLETE('snowflake-arctic', 'こんにちは') FROM SOME_TABLE LIMIT 10;
```

まったく意味のないSQLですが、LLMが行数と同じ回数だけ呼び出されました。  

![ten-times](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/f2e9a41a-2c55-88e0-9357-40610cd51199.png)

CONCAT関数を使うことで文字列を結合することができます。これを使ってフィールドを結合したプロンプトを各行ごとに組み立てることで、意味のある処理が実現できます。  
以下のSQLはお店の店名からそのジャンルを分類しようという試みです。  

```sql
-- Snowflake Cortexでテーブルの各行に対してLLMを呼び出す
-- https://docs.snowflake.com/en/sql-reference/functions/complete-snowflake-cortex#responses-from-table-column
SELECT
    STORE_NAME,
    SNOWFLAKE.CORTEX.COMPLETE(
        'snowflake-arctic',
        CONCAT('nameタグで囲まれた文字列は飲食店の店名です。この店名が本格イタリアンであると推定されるときは1、そうでなければ0を出力してください。: <name>', STORE_NAME, '</name>')
    ) AS RESPONSE
FROM SHIBUYA LIMIT 500;
```

精度については検討の余地がありますが、それらしく動くことが確認できました！  

![classify](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/c3f996ce-53bf-1573-1647-353a4fbd3bb7.png)

なお、LLMなので想定と異なる出力をしてくれることもあります。後処理が大事。  

![error](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/1d72fd3b-d735-822d-a408-b5c912093008.png)
【React】選択範囲に特定のNodeが含まれているか検証する方法

画面上で選択されている範囲に特定のNodeが含まれているか検証するには[Selection.containsNode()](https://developer.mozilla.org/en-US/docs/Web/API/Selection/containsNode)を使用します。

```tsx
import { useCallback, useEffect, useRef } from 'react'

export function Sample() {
  const ref = useRef<HTMLParagraphElement>(null)
  const handleSelectionChange = useCallback(() => {
    const paragraph = ref.current
    const selection = document.getSelection()
    if (paragraph) {
      console.log(selection?.containsNode(paragraph, true)) // 選択範囲に<p></p>が含まれていればtrue
    }
  }, [])

  useEffect(() => {
    document.addEventListener('selectionchange', handleSelectionChange)

    return () => {
      document.removeEventListener('selectionchange', handleSelectionChange)
    }
  }, [handleSelectionChange])

  return (
    <p ref={ref}>
      サンプルのテキスト。サンプルのテキスト。サンプルのテキスト。サンプルのテキスト。サンプルのテキスト。
    </p>
  )
}

```
初心者向け：Gitの基本設定

# Gitの基本設定をしよう！

Gitをインストールしたら、次は自分だけの設定をして、Gitをもっと便利に使えるようにしましょう。特にユーザー名とメールアドレスの設定は、Gitを使う上で超重要です。なぜなら、これらの情報がコミットごとに記録され、誰がどの変更を加えたかが一目でわかるようになるからです。

## ユーザー名とメールアドレスを設定する

Git Bashを開いて、以下のコマンドを使って、まずは自分の名前とメールアドレスをGitに教えてあげましょう。

1. **ユーザー名の設定**
   ```bash
   git config --global user.name "あなたの名前"
   ```
ここで「あなたの名前」と書いたところには、自分の名前をダブルクオートで囲って入力します。

2. **メールアドレスの設定**
   ```bash
   git config --global user.email "あなたのメールアドレス"
   ```
ここでも、自分のメールアドレスをダブルクオートで囲って入力してください。
これで、Gitにあなたの情報が設定されました。これから先、Gitを使ってコミットするときは、これらの情報が自動的に使用されるようになります。

## 設定の確認
設定がうまくいったかどうかを確認するために、以下のコマンドで設定内容を表示させてみましょう。
   ```bash
   git config --list
   ```
   
このコマンドを実行すると、設定したユーザー名とメールアドレスが表示されます。何か間違っていたら、もう一度設定コマンドを実行して修正しましょう。
Pleasanter Tips: ダッシュボードのパーツを固定する

# はじめに
Pleasanterのダッシュボードは最近追加された機能で大変便利な機能です。 
ダッシュボードのサイズや表示場所は画面で行うことができ、ダッシュボードの保管で保存されます。

# 設定
下記の内容をHTMLのBody Script Bottomで設定します。
```
<script>
$p.gridstackInstance.opts.disableDrag = true;
$p.gridstackInstance.movable(".grid-stack-item",false);
$p.gridstackInstance.opts.disableResize = true;
$p.gridstackInstance.resizable(".grid-stack-item",false);
$('button#UpdateDashboardPartLayouts').css('display','none');
```
Crystal言語はAndroid携帯でも動く

あまり知られていないことだが、Crystalは携帯電話（Androidのスマートフォン）でも動作する。別にハッキングするわけではなく、Crystalの公式ホームページでも説明がある正規の方法で。

https://crystal-lang.org/install/on_termux/

## Termux

Termuxとは、AndroidデバイスをLinuxとして使うことができるアプリである。これをインストールする。

https://termux.dev/en/

あとは次のようにCrystalをインストールするだけだ。

```
pkg install crystal
```

余談だが、`ruby` や `htop` `vi` などすぐに思いつくようなツールはだいたいインストールできる。あとは、普段のコンピュータでやっているのと同じように `vi` などでファイルを編集して保存し、`crystal build` を行えばよい。

スマートフォンでCrystalがコンパイル・実行できるのは非常に面白い。

オススメです。
[UnrealEngine]DungeonArchitectでキャラクターが動かなくなった時

# 概要
UE5のアセット「DungeonArchitect」でゲーム開始後にダンジョンを生成するように修正したところ、修正前までAIで動いていた敵キャラが急に動かなくなりました。原因はAI Controller Classが働いていない事でした。
# 本文
キャラクターのブループリントを開いて詳細の中にあるAutoPossess AIをPlaced in WorldからPlaced in World or Spawned(もしくはSpawned)にするとAI ControllerClassが動くようになりました。
![スクリーンショット 2024-05-09 225426.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/0efe15b2-cd44-6e07-a81f-d866d990aa27.png)

無事、敵キャラが動くようになりました:sunny:
![スクリーンショット 2024-05-09 225517.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/5f70f7fa-5b02-6a0c-4f1e-33c395d695b6.png)




# 補足


参考サイト
[【UE4】「AIが動かない！」そんな時にチェックするべき項目](https://qiita.com/Dv7Pavilion/items/3bf464815a68ae0f8083)
NerdMiner V2 セットアップ

# 趣旨
Bitcoinプロトコルを学ぶにあたってマイニングプロセスを避けて通ることはできないのでNerdMinerという簡易版の学習用ツールを買ってセットアップしてみました。例の如く記憶力が悪い僕はすぐに忘れてしまうので備忘録として残しておきます。

日本語での解説は多分ないですし英語の方がわかりやすいのでガイドを見ても分かりづらかった、あるいは探しづらかった部分だけを抜粋していきます。

# セットアップガイド
どちらか片方を見るだけで多分良いですが、僕は全部読むのが面倒だったので両方見て目がつくところを抜粋してセットアップしました。

https://nerdminers.com/nerdminer-setup-guide/#quick-guide

https://github.com/BitMaker-hub/NerdMiner_v2

# ファームウェアのFlash

https://github.com/BitMaker-hub/NerdMiner_v2 からZIPファイル形式でファームウェアのコードをダウンロードしてPCに保管します。

:::note info
ファームウェアとは、電子機器の基本的な機能を制御するためのソフトウェアです。このソフトウェアは、機器のハードウェアに直接インストールされ、その機器が正しく動作するために必要な指示やプログラムを提供します。ファームウェアは通常、ROM（Read-Only Memory）やフラッシュメモリなどの非揮発性メモリに格納されていて、電源が切れても消えることはありません。
:::

ESP32にファームウェアをFlashしないといけないのですが、Webブラウザ上で完結します。僕はガイドの通りここを使いました。

https://espressif.github.io/esptool-js/

USB接続でNerMinerをPCに繋いでデバイス認識をさせたらZIPファイルを解凍して中のbinフォルダの該当するデバイスを選んで以下の4つのファイルをWebブラウザ上でFlasherにセットします。

FLashアドレスは以下の通りに変更する必要があり、ファームウェアのバージョンは最新のものを選んだ方がいいです。
```
0x0000 for 0x0000_bootloader.bin
0x8000 for 0x8000_partitions.bin
0xe000 for 0xe000_boot_app0.bin
0x10000 for 0x10000_firmware_v1.6.3.bin
```

Flashは以下のサイトからでもできます。
https://flasher.bitronics.store/

USBを抜いてもう一度挿せばNerdMinerが動き始めます。

動き出すとQRコード読み込みが表示されるのでそれを読み込んでAccess Pointの設定をします。

主にPoolの選択とBTCアドレスの指定をします。

# Pool選択
デフォルトのままでも良いですが、メジャーなところにセットしてもおkです。

![Screenshot 2024-05-09 at 16.00.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670541/0ffccf71-7e40-f14f-f033-f25768262185.png)
https://github.com/BitMaker-hub/NerdMiner_v2?tab=readme-ov-file

# Public Pool
UmbrelのストアにあるPublic Poolを使いたい場合はアプリを開くと以下のような詳細が出てくるので、umbrel.localをPool URLにPortを2018にアドレスを自分のTaproot以外のBTCアドレスをセットします。

```
stratum+tcp://umbrel.local:2018
username: <your BTC address>.<worker name>, password: x
```

![Screenshot 2024-05-09 at 16.09.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670541/2ac0cf05-b4a9-20bc-2cb8-22cf235bf9cb.png)

# Fan取り付け参考動画

https://www.youtube.com/watch?v=6ZFY_Eulj5Q
SciTools UnderstandのAPI活用方法

SciTools UnderstandのAPIは、ソフトウェア開発やメンテナンスにおいて、コード解析やデータ抽出を自動化するための強力なツールです。ここでは、開発プロジェクトで特に役立つ使い方の例をいくつか挙げます。

### 1. コードメトリックのレポート生成

Understand APIを使って、コードの品質を評価するためのメトリック（例：コード行数、循環的複雑度、重複コード）を自動で抽出し、定期的なレポートを生成できます。これにより、プロジェクト全体の品質を客観的に追跡できます。

```python
import understand as und

# プロジェクトを開く
db = und.open('path/to/project.udb')

# 関数ごとの複雑度をレポート
for func in db.ents('function'):
    complexity = func.metric(['Cyclomatic'])
    print(f"{func.longname()} - 複雑度: {complexity['Cyclomatic']}")
```

### 2. カバレッジ分析とテストケースの改善

テストケースとコードのカバレッジ情報を解析し、テストが不足している箇所を特定するために使用できます。これにより、リグレッションテストの精度を向上させたり、新しい機能のテスト戦略を最適化したりできます。

### 3. デッドコードの発見と削除

呼び出し関係や定義関係をAPIで自動分析することで、利用されていない関数や変数を検出し、プロジェクトのクリーンアップに役立てられます。

```python
# 関数の呼び出しが存在しないものを表示
for func in db.ents('function'):
    if not func.refs('Callby'):
        print(f"{func.longname()} は使われていません")
```

### 4. 依存関係の可視化とモジュール化

モジュール間の依存関係を解析し、特定の機能を持つモジュール同士の関連を可視化します。これにより、モジュールの分離が必要な箇所を特定し、再設計やリファクタリングを容易に行えます。

### 5. リファクタリングの計画

コードの構造や関係性をAPIで抽出し、リファクタリング計画を自動化することができます。コードの依存関係を可視化することで、変更が大規模に影響しないように設計ができます。

### 6. レガシーコードの理解とドキュメント化

Understand APIを使って、既存のレガシーコードを解析し、関数やクラスの関係、処理の流れをドキュメント化することで、新たな開発者が理解しやすくなります。

これらの例を活用することで、Understand APIはコードの品質向上や効率的な開発、保守に役立ちます。
スプレッドシートでセルの結合を連続で行いたい際（Mac)

一度あるセル同士を結合した後に `fn + F4` キーを押すことで他のセルの結合も連続でこなすことができます。これはこのショートカットキーで前回の操作を繰り返すためです。
シートに色をつける、文字に色を塗るなどさまざまな操作のショートカットに応用可能です。
ラズパイ５の環境構築した話④【タッチパッドのスワイプ対応】

スワイプ、スワイプ〜

# はじめに
- 普段、macbookを使っている身としては、三つ指スワイプにブラウザの「戻る」が割り当てられないのは耐えがたかったので、頑張って対応してみる。
- 具体的には、[libinput-gestures](https://gigazine.net/news/20211217-linux-touchpad/)をインストールする。ちなみに、x11では使えるけど、waylandだと無理みたい。
- 使ったタッチパッド付きキーボードは[fmv mobile keyboard](https://www.fmworld.net/fmv/keyboard/nkbu/2203/)。

# 導入手順
1. ユーザをグループinputに追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/8ed319ed-c2e4-4c04-f49f-de161e1d76aa.png)
1. リブート
1. ２つのアプリをインストール
`sudo apt install wmctrl xdotool`
`sudo apt install libinput-tools`
1. [ここ](https://github.com/bulletmark/libinput-gestures.git)からソースコードをgitコマンドで入手
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/92e30c68-dbf5-b747-0559-68e823542c8b.png)
1. そして、インストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/f65b4a92-dcad-837f-ee4b-f561a495084c.png)
1. helpオプションはわからなかったから適当に叩いたらエラーになったけど、下記の通り親切に色々と使い方を教えてくれた。start|stop|restart|autostart|autostop|status|desktop|serviceのオプションがある模様。オプション無しで実行すると、status（デフォルトコマンド）が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/a39c7b38-e9dc-9171-8391-04a7689e61bc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/e204f4ab-77be-f6e5-fcd4-4fbdfb6efeb5.png)
調べたところ、想像通り、start/stopで開始/停止、autostart/autostopで起動時開始/起動時開始取り消し、restartは再起動だから、設定ファイルの再読み込みしたいときに使うのかな？
1. autostartオプションを実行したあと再起動したら、下記のステータスになった。よし、libinput-gesturesが開始してる！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/583b5076-211a-f83d-f36b-017163ff0fd0.png)
この時点で、既にジェスチャーが有効になっており、全ユーザー共通設定ファイルである、/etc/libinput-gestures.confに従っている。ユーザー個別に設定したければ、~/.config/libinput-gestures.confという個別設定ファイルを新たに作る。共通設定ファイルより、個別設定ファイルの方が優先される。
設定の仕方は、共通設定ファイルを見れば、なんとなく分かる。例えば、下記部分は、左に3本指スワイプをするとalt+右矢印を押したのと同等になる設定。これは、ブラウザでは、「進む」に相当するけど、普通の感覚では、左スワイプは「戻る」だよね。そう思った人は、alt+Rightとalt+Leftを入れ替えればよい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/9de38063-d71e-29d7-4f5b-7e63319a2b19.png)

# おわりに
- これで、pi5単独使用の時の作業が楽になった。でも、相変わらず、文字入力中のタッチパッド誤タッチによるカーソル飛びがストレス。
- あと、当然だけど、vncで母艦のタッチパッドをスワイプしてもジェスチャー対応していない。母艦のジェスチャに対応させるなら、[BetterTouchTool](https://pc.watch.impress.co.jp/docs/column/macinfo/1399229.html)でジェスチャーにキーボード操作を割り当てればいけるのでは？と思って試したけど、駄目だった。なんでだろ。

# おまけ
- 無停電電源装置(なんちゃってUPS)を導入した。パススルー充電できるモバイルバッテリーがこんなふうに役立つとは... ただし、パススルー充電できるバッテリーでも、入力が切れたときに出力が瞬断するものもあるから要確認。cioで言えば、SMARTCOBY Pro SLIMは瞬断したけど、SMARTCOBY DUO（写真）は瞬断しなかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733720/f4756d10-69b9-c385-f9ea-7b8d07368abd.png)
SciTools Understandで特定のコミットの変更関数に対してButterflyグラフを描く

コードの視覚化において、関数間の影響範囲を簡単に理解するのにButterflyグラフはとても有効です。この記事では、Gitの`git show`コマンドのように特定のコミットで変更された関数に限定して、SciTools Understand APIを用いてButterflyグラフを生成する方法を紹介します。

#### Butterflyグラフとは
Butterflyグラフは、ある関数エンティティが他の部分とどう影響し合っているかを示す可視化ツールです。特定の関数が直接・間接的に依存している部分を、左右に広がる羽のような形で示してくれます。特定のコミットで変更された関数のButterflyグラフを生成することで、プロジェクト全体に与える影響を理解するのに役立ちます。

#### 必要な環境
1. **Understandプロジェクト**: 事前にUnderstandでプロジェクトを作成し、`.udb`ファイルを用意しておきます。
2. **GitPython**: GitリポジトリにアクセスするためにPython用のGitインターフェースを使用します。

#### ステップバイステップガイド

1. **プロジェクトのロード**  
Understandプロジェクトを開いてエンティティへのアクセスを開始します。

    ```python
    import understand as und
    db = und.open('path/to/my_project.udb')
    ```

2. **コミット差分の取得**  
Gitリポジトリから特定のコミットにおける変更内容を、`git show`のように取得します。

    ```python
    import git
    repo = git.Repo('path/to/git/repo')
    commit_hash = 'abcd1234'
    commit = repo.commit(commit_hash)

    # 親コミットとの比較でパッチ形式の差分を取得
    patches = commit.diff(commit.parents[0], create_patch=True)
    ```

3. **変更行の解析**  
パッチ形式の差分から、各ファイルで変更された行番号を取得します。

    ```python
    changed_functions = {}

    for patch in patches:
        file_name = patch.b_path
        patch_text = patch.diff.decode('utf-8')
        changed_lines = []

        for line in patch_text.split('\n'):
            if line.startswith('@@'):
                header_parts = line.split(' ')
                new_line_info = header_parts[2]
                start_line = int(new_line_info.split(',')[0].replace('+', ''))
                changed_lines.append(start_line)

        changed_functions[file_name] = changed_lines
    ```

4. **エンティティの特定とButterflyグラフの生成**  
Understand APIで変更された行に対応する関数エンティティを見つけ、Butterflyグラフを生成します。

    ```python
    for file_name, changed_lines in changed_functions.items():
        file_entities = db.lookup(file_name, 'file')

        for file_ent in file_entities:
            for func in file_ent.ents('Define', 'function'):
                func_start = func.line()
                func_end = func.endline()

                if any(func_start <= line <= func_end for line in changed_lines):
                    func.draw('butterfly', 'output_directory')
                    print(f"Butterflyグラフを生成しました: {func.longname()}")
    ```

### 結論
この手順に従うことで、特定のコミットで変更された関数に限定してButterflyグラフを生成できます。特定のコミットが他の部分に与える影響を視覚的に把握することで、コードのリファクタリングや品質向上に役立つでしょう。
ReactJSで開発したプロジェクトを共有する

1. プロジェクトの Web サイトは React Hook テクノロジーを使用して構築されています
2.デザインコンセプトは新しく、スタイルはiPadとPCのサポートを備えたモバイルブラウジングに焦点を当てています。
3.タイムリーにコンテンツが更新される
私たちのウェブサイトは： https://boyinthai.com
興味のあるお友達はメッセージを残していただければ幸いです
Ruby  extendについて

# はじめに


#### <font color="red">※以下の内容には誤りが含まれる可能性があります</font>


# extendとは何か

extendとはモジュールのメソッドを使用するためのメソッドです。

クラスの中でモジュールを呼び出すときに使います。

その際extendはクラスメソッドとして読み込む。


# extendの使い方


```
module cat
def name
 "ミケ"
  end
 end

 class Animal
  extend Cat
end

p　Animal.name
```

includeメソッドとの違いはクラスメソッドとしてモジュールがインクルードされる点です。

 
# まとめ


- extendはモジュールを使用するためのメソッド
- extendeはクラスメソッドとして読み込む
MailDevでモックSMTPサーバーを立てる

# はじめに
開発中に安心して使えるメールサーバーのモックを探していたら、[MailDev](https://github.com/maildev/maildev)という良さげなツールを見つけたので使ってみました。
今回は[公式のDockerイメージ](https://hub.docker.com/r/maildev/maildev)をdocker-composeで動かしています。

# MailDevとは
開発中にメール機能をテストするためのツールで、以下のような特徴を持っています。
- ローカルマシン上にモックSMTPサーバーを構築できる
    - 公式のDocker imageがある
    - npmでもインストール可能([参照](https://www.npmjs.com/package/maildev))
- あくまでモックなので、外の世界にメールが送信されることはない
- モックSMTPサーバーから送信したメールの内容を、ブラウザで確認することができる

# モックサーバーの構築
以下の手順で構築および動作確認していきます。

1. docker-compose.yamlを記述する
1. Dockerコンテナを起動する
1. ブラウザでlocalhost:1080を開きサーバーが立ち上がっていることを確認する
1. telnetでモックサーバーにメールを送信する
1. ブラウザでメールが届いたことを確認する

今回はDocker Composeで構築していますが、dockerコマンドでも実行できます。
(詳細は[公式参照](https://github.com/maildev/maildev))
## docker-compose.yaml
```yaml:docker-compose.yaml
services:
  maildev:
    image: maildev/maildev
    ports:
      - "1080:1080"
      - "1025:1025"
```
1080ポートでWebサーバーが、1025ポートでSMTPサーバーが起動しているので、それらを公開しています。

# 動作確認
`docker-compose up`でDockerコンテナを起動し動作確認をしていきます。
## モックサーバー起動確認
コンテナが起動した状態で[http://localhost:1080](http://localhost:1080)にアクセスすると以下が表示されます。
![スクリーンショット 2024-05-09 12.58.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287959/dee18c03-b6c8-fe82-55a8-b9fc9e241e93.png)

## メール送信
モックサーバーの起動が確認できたので、実際にメールを送ってみましょう。
telnetコマンドを使うと簡単に送ることができます。
(telnetコマンドはWindowsならWSLにデフォルトでインストールされていますが、Macの場合ないので`brew install telnet`でインストールしてください。)
### telnetコマンド実行
```
telnet localhost 1025 
```
上記を実行するとコンソールに以下のようなレスポンスが返ってきます。
```
Trying ::1...
Connected to localhost.
Escape character is '^]'.
220 1bd612940a79 ESMTP
```
これでモックサーバーとの接続が確立されました。
### SMTPセッション開始
まず最初に`HELO`コマンドでクライアントのホスト名をサーバに伝えます。
今回はモックサーバー相手なので、クライアントのホスト名はなんでも大丈夫です。
接続を確立したコンソールでそのまま以下を打ち込み、エンターしてください。
```
HELO test.com
```
すると以下のようなレスポンスが返ってきます。
```
250 1bd612940a79 Nice to meet you, [192.168.65.1]
```
### メール送信
次に以下を続けざまに入力します(レスポンスは省略)。
```
MAIL FROM: <test@test.com>
```
```
RCPT TO: <target-address@test.com>
```
```
DATA
```
```
Subject: this is mail title

this is mail content
.
```
これでモックSMTPサーバーを使って、<test@test.com>というアドレスから、<target-address@test.com>というアドレスに対して、メールが送信されました。

ちなみに`DATA`の後に入力しているものはメールの件名とメール本文なのですが、Macで日本語入力すると、telnetの問題で文字化けするのでアルファベットのみにしたほうが賢明です。
(WSLは日本語でも大丈夫でした)
## メール送信確認
ではどんなメールが送信されたか確認してみましょう。
[http://localhost:1080](http://localhost:1080)に再度アクセスすると、以下のような内容が確認できるはずです。
![スクリーンショット 2024-05-09 21.58.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287959/cb6cdbe6-07ef-529a-1686-45b48769edf5.png)


# まとめ
MailDevを使うことで、外部にうっかりメール送信してセキュリティ事故になるといったことが防げるようになります。
環境変数で開発環境はローカルのモックSMTPサーバー、本番環境はAWS SESなどのSMTPサーバーを向くようにしておけば、安心して開発することができますね。
Power Automate: 高速に差集合を求める方法 by Filter Array

# 背景

以下なんて必要なかったんだ、ということを教えてもらったので、実際にやってみての備忘録

https://qiita.com/baku2san/items/d05321012e0cbf833f2b

# 概要

1. Select(選択) を利用して、オブジェクトリストを配列化
1. 作成した配列を使って、Filter Array で contains/not contains で差集合を求める

## 利用例

- オブジェクトリストから、Select(選択) を利用して配列化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/f85155b6-916c-e3bf-8afd-92e8b88d0830.png)

https://qiita.com/baku2san/items/39e7a40c1a1fb327362a#%E5%AE%9F%E3%81%AF%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E5%86%8D%E6%A7%8B%E7%AF%89%E3%81%A0%E3%81%91%E3%81%98%E3%82%83%E3%81%AA%E3%81%8F%E7%B0%A1%E5%8D%98%E3%81%AB%E5%8D%98%E7%B4%94%E9%85%8D%E5%88%97%E5%8C%96%E3%82%82%E5%87%BA%E6%9D%A5%E3%81%BE%E3%81%99


- あとは、Filter array で、作った配列を元に、contains/ does not contains を利用して、差集合を求めるだけ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/9076a593-e4e1-245f-8ff5-4da67772615b.png)



## 速度比較

以前の Office Scripts版と比較しても圧倒的

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c29b4e61-46f2-6960-cfd1-8213bf466a0d.png)


# 応用例

- セキュリティグループから、Teams の Microsoft 365 グループへの同期をする
    - 同期元・同期先で相互に差分を取れば、あとは、Add/Removeをすれば高速同期が可能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/f0460cd0-e55b-80ce-665c-91473ff9b695.png)

# あとがき

Filter 条件も、@and() なんかで複合条件化すればもっといろいろできそうかも？
Figma入門おすすめサイトまとめ

# 公式tutorial
https://help.figma.com/hc/ja/categories/360002042553
# デザインシステム
[google]https://material.io/resources
[shopify]https://polaris.shopify.com/
[apple]https://developer.apple.com/design/
[microsoft]https://fluent2.microsoft.design/#/
[airbnb]https://airbnb.design/building-a-visual-language/
[USA web]https://designsystem.digital.gov/
# おすすめブログ等
https://udemy.benesse.co.jp/design/how-to-use-figma.html

https://www.figma.com/community/file/1228577958737472070

# 動画コンテンツ
https://www.udemy.com/course/figma-app-design/

#sample
[sample PJ](https://www.figma.com/design/uFZHmUzycvDO6ZzxhYgT7W/%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB_%E3%83%AC%E3%82%B7%E3%83%92%E3%82%9A%E3%82%A2%E3%83%95%E3%82%9A%E3%83%AA?node-id=3%3A580&t=J8DMeQ3JfK7m01Ov-1z)
正規表現によって小数末尾のゼロを削除する

以下の正規表現で数値文字列を置換すれば、小数末尾のゼロを削除できる。
``` js
target.replace(/((?<=\.\d+)|\.)0+$/, '');
```

JavaScriptでの実際の動作は以下の通り。

``` index.js
const trimDecimalZero = (target) => target.replace(/((?<=\.\d+)|\.)0+$/, '');

console.log(trimDecimalZero('1.200')); // 1.2
console.log(trimDecimalZero('10.00')); // 10
console.log(trimDecimalZero('12300')); // 12300
console.log(trimDecimalZero('1.234')); // 1.234
```

ただし、正規表現の実装によっては肯定戻り読みの量指定子に未対応なので、上記のとおりに動作しない言語やライブラリもある。
【AWS】エラー「failed to create Cloudwatch log stream: ResourceNotFoundException: The specified log group does not exist」

# 概要
AWSでデプロイ時、ECSタスクで以下のエラーが出ました。
こちらについて解決できたので紹介します。

> CannotStartContainerError: Error response from daemon: failed to initialize logging driver: failed to create Cloudwatch log stream: ResourceNotFoundException: The specified log group does not exist.

## 前提
以下のようにpython側で実装。
`log-sample-group`ロググループの中に手動で`sample-stream`ログストリームを作成、デプロイをしました。


```py
"handlers": {
    "watchtower": {
        "level": "DEBUG",
        "class": "watchtower.CloudWatchLogHandler",
        "boto3_session": autorefresh_session,
        "log_group": "log-sample-group",
        "stream_name": "sample-stream",
        "formatter": "aws",
    },
    #...略...#
```

`watchtower`とは、PythonのログをAmazon Web Services (AWS)のCloudWatch Logsに送信するためのライブラリ。`logging`モジュールを使用して、ログをCloudWatch Logsに直接送信することができるので便利です。

しかし、デプロイすると上述のエラー。
エラーメッセージは、ECS(Docker)がCloudWatchのログストリームを作成しようとしたときに、指定したロググループが存在しない、と言っています。

ちゃんと指定したロググループとログストリームを作成しているのでちゃんとログが出力されるはずなのに...
おかしいなぁと思っていたら、原因はタスク定義の方でした。

## 原因と解決方法
タスク定義JSONを以下のようにしていたのですが、単純に`"awslogs-group": "/aws/ecs/docker_sample"`のロググループ作成漏れでした。

```json
{
  "executionRoleArn": "arn:aws:iam::xxx/xxxx",
  "taskRoleArn": "arn:aws:iam::xxx/xxxx",
  "containerDefinitions": [
    {
      "name": "Web",
      "image": "<IMAGE1_NAME>",
      "logConfiguration": {
        "logDriver": "awslogs",
        "secretOptions": null,
        "options": {
          "awslogs-group": "/aws/ecs/docker_sample",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "sample-stream"
        }
      },
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 0,
          "protocol": "tcp"
        }
      ],
      "essential": true
    }
  ],
  "requiresCompatibilities": ["EC2"],
  "networkMode": null,
  "cpu": "900",
  "memory": "3400",
  "family": "TaskSample-xxxxxxx"
}
```

基本的には、タスク定義の`"awslogs-group": "/aws/ecs/docker_sample"`とWatchtowerライブラリで使用するロググループは無関係。

` "/aws/ecs/docker_sample"`は、ECSタスク定義の一部として設定され、ECSタスク内で実行されるコンテナアプリケーションが生成するログ（標準出力や標準エラー出力に出力されるログ）をCloudWatch Logsに送信するための設定。

対して、Watchtowerライブラリは、Pythonのloggingモジュールを通じてアプリケーションが生成するログをCloudWatch Logsに送信するためのツール。これは上述の通り別ファイルで設定します。

同じCloudWatch Logsのロググループに送信することも可能と言えば可能ですが、ECSタスクのログとアプリケーションのログが同じロググループに集約されてしまうので、わかりづらくなるかと思います。一般的にはロググループを分けるのが推奨されるでしょう。
【PHP】if文を簡潔に書くために守るべきルール

:::note warn
エンジニア初心者の投稿であるため、間違っている箇所が多くあるかと思います。
間違っているなどあればご教授いただけると幸いです。
:::

## はじめに
PHPの学習中、if文の条件式の書き方を全く意識せず書いていたため、非常に美しくない条件式を量産してしまっていました。戒めの意味も込めて記事に残したいと思います。

## if文とは（PHP）
PHPの公式サイトにはこのように書いてありました。
> この構文は、命令の条件実行を可能にします。 PHP では、C 言語に似た次のような if 構文が使用されます。
>if (式)
  文
>式は論理値で評価されます。 式が true と評価された場合、 PHP は文を実行し>ます。false と評価された場合は、これを無視します。

条件の書き方次第では何通りもの書き方ができます。今回はそのことについてメンターの方に指導してもらったことを含めつつ、自分なりに考えたことをここに残したいと思います。

## if文 条件式の書き方

### 否定系・肯定系どちらも使える場合は肯定系を使う
条件式が!==と===のどちらでも表せる場合は===を使おうという意味です。
結構当たり前のことだと思いますが、「それ肯定系でいいじゃん」と思うコードを否定系を使ってコードを書いてしまっていました。

〜具体例〜
以下は配列[1,3]から1のみを出力するプログラムです。
```php5:PHP 良い例
//肯定系（===）を用いて条件式を表現

<?php
$array = [1, 3];

foreach ($array as $num) {  
    if($num === 1)
    echo $num;
}
```

```php5:PHP 悪い例 
//否定系（!==）を用いて条件式を表現

<?php
$array = [1, 3];

foreach ($array as $num) {  
    if($num !== 3)
    echo $num;
}
```

今回は簡単な例を載せているので「そうはならないだろ」となるかと思いますが、少し複雑な条件式になったときに否定系を無意識に使ってしまうことがあったので気をつけたいです。
<br>
### コード数が少ない条件をIf文の条件式にする
条件に当てはまる要素の数を予想して、コードの記述が少なくなる方を選択して条件式する。これも頭の片隅に入れておかないと気づいたらめんどくさいことをやっていることがあるので記録に残しておきます。

〜具体例〜
以下は[青森県、秋田県、岩手県、宮城県、山形県、福島県、東京都]の中で東北地方である都道府県を出力するプログラムです。

```php5:PHP 良い例
//条件式が簡潔になっている

<?php
$prefectures = ['青森県', '秋田県', '岩手県', '宮城県', '山形県', '福島県', '東京都'];

foreach ($prefectures as $prefecture) {  
    if($prefecture !== '東京都') {

    echo $prefecture;

    }
```

```php5:PHP 悪い例
//条件式が複雑になっている

<?php
$prefectures = ['青森県', '秋田県', '岩手県', '宮城県', '山形県', '福島県', '東京都'];

foreach ($prefectures as $prefecture) {  
    if( $prefecture === '青森県' || 
        $prefecture === '秋田県' ||
        $prefecture === '岩手県' ||
        $prefecture === '宮城県' ||
        $prefecture === '山形県' ||
        $prefecture === '福島県' ) {

    continue;

    }
    
    echo $prefecture;
}
```
今回の例でも「見ればわかるだろ」って感じですが、実際にプログラムを組んでいるときに似たようなミスをしてしまうのでしっかりと覚えておきたいと思います。

## おわりに
だらだらと私自身がやってしまう条件式での決して綺麗ではない書き方を残してきました。簡単なコードであれば、絶対にそんなことはしないだろと思うのですが、今の私では、気を抜くと上記のような難解な条件式を書いてしまうことがあります。美しいコードを目指して、日々鍛錬したいと思います。
DifyをAmazon Lightsailで動かす


# DifyをAmazon Lightsailで動かす

[Dify](https://dify.ai/jp)をLightsailで動かす方法です。[絶対に失敗しないDifyデプロイの手順、AWS Lightsail編](https://note.com/sangmin/n/nbb4db69784e8)で紹介されているままですが、起動スクリプトを貼り付けるだけでDifyまで起動するようにしているため、必要な操作はLightsailの初期設定のみです。

<aside>
⚠️ 本手順を実行すると、インターネット上に公開された状態でDifyサービスが動作します。別途、<a href="https://docs.aws.amazon.com/ja_jp/lightsail/latest/userguide/understanding-firewall-and-port-mappings-in-amazon-lightsail.html">Lightsail のファイアウォールでインスタンストラフィックを制御する</a>などを参考に、アクセス元を制限するなどのセキュリティは適切に設定してください。また、本手順のみでは平文での通信となるため、あくまで動作確認用としてご利用ください。
</aside>

## Lightsailインスタンスを作成する

Amazon Lightsailにて以下のようにインスタンスを作成します。インスタンスのサイズは2GBのものを選択してください。1GBだとメモリ不足で起動しないことがあります。

![](https://www.inoue-kobo.com/aws/dify-on-lightsail/images/lightsail.png)

起動スクリプトの箇所には以下のスクリプトを貼り付けてください。

```bash
dnf update
dnf install -y docker
dnf install git -y
systemctl start docker
systemctl enable docker
cd /root
git clone https://github.com/langgenius/dify.git
cd dify/docker
curl -L "https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
cat << EOF >> /etc/systemd/system/dify.service
[Unit]
Description=Dify
Requires=docker.service
After=docker.service

[Service]
WorkingDirectory=/root/dify/docker
ExecStart=/usr/local/bin/docker-compose up
ExecStop=/usr/local/bin/docker-compose down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target
EOF
systemctl enable dify
systemctl start dify
```

`インスタンスの作成`を押下して10分程度待ちます。

## Difyの起動を確認する

Lightsailのインスタンス一覧画面にて、パブリックIPを確認し、ブラウザでアクセスします。

![](https://www.inoue-kobo.com/aws/dify-on-lightsail/images/instance.png)

以下のURLをブラウザで開いてください。

```
http://<パブリックIP>/install
```

この手順では`http`でアクセスする必要があることに注意してください。

![](https://www.inoue-kobo.com/aws/dify-on-lightsail/images/dify.png)

## 起動しているか心配になった場合

初回の起動では各種コンテナのダウンロードも行うため結構時間がかかります。画面に変化がないので心配になった場合は、SSHで接続して以下のコマンドでサービスが起動していることを確認できます。`active`になっていれば大丈夫です。

```bash
sudo systemctl status dify
```

![](https://www.inoue-kobo.com/aws/dify-on-lightsail/images/systemctl.png)

## 参考文献

* [絶対に失敗しないDifyデプロイの手順、AWS Lightsail編](https://note.com/sangmin/n/nbb4db69784e8)
* [Amazon Linux 2023にDockerとDocker Composeのインストール](https://zenn.dev/rock_penguin/articles/28875c7b0a5e30)
* [Dify](https://dify.ai/jp)
sequelize(mariadb)を外部ファイルconfig.jsonで接続の仕方

# sequelizeを外部ファイルconfig.jsonを使用し接続の仕方
### 外部ファイルで設定を記入する理由
gitでプロジェクトを管理をするため.gitignoreで設定ファイルを第3者から見えなくするため

### .gitignoreの概要
.gitignoreは、Gitでコード管理したくないファイルやディレクトリを指定するためのファイルです。".gitignore"という名前の特殊なファイルであり、隠しファイルとして存在します。このファイルに指定したファイルやディレクトリは、Gitのトラッキングの対象外となります。つまり、Gitで管理しているディレクトリにあっても無視されます。
.gitignoreファイルを使うことで、個人のPC環境に依存するファイルやパスワード関連の重要なファイルなどをGitのリモートレポジトリにプッシュしないようにすることができます。また、不要なデータがプッシュされないため、第三者がコードを見る際に確認しやすくなります。さらに、公開したくない情報をGitの管理対象外とすることでセキュリティ面を向上させることもできます

### config.jsonファイルの記述
config.jsonファイルを作成し、接続情報を記述します

```json
{
  "development": {
    "username": "your_username", //データベースを操作するユーザ名
    "password": "your_password", //ユーザのパスワード
    "database": "your_database", //データベースの名前
    "host": "localhost",
    "dialect": "mariadb"//操作するソフトウェア名
  },
  "production": {
    "username": "your_username",
    "password": "your_password",
    "database": "your_database",
    "host": "localhost",
    "dialect": "mariadb"
  }
}
```

### DBUnit.jsの接続テストの記述

config.jsonファイルをconfigとしてインポートし、env変数を使用して環境に応じた設定を取得しています。 envConfigオブジェクトには、対応する環境の設定が格納されます。
sequelizeのインスタンスを作成する際には、envConfigから必要な設定を取得して使用します。
このようにすることで、config.jsonファイルから接続情報を読み込んでMariaDBに接続することができます。

```javascript
const { Sequelize } = require('sequelize');
const config = require('./config.json');

// 環境に応じた設定を取得します（ここではdevelopmentを使用しています）
const env = process.env.NODE_ENV || 'development';
const envConfig = config[env];

// Sequelizeのインスタンスを作成して、接続情報を設定します
const sequelize = new Sequelize(envConfig.database, envConfig.username, envConfig.password, {
  host: envConfig.host,
  dialect: envConfig.dialect,
  logging: false, // ログを表示したくない場合は、falseに設定します
});

// モデルの定義など、データベース操作を行います

// 非同期処理をasync / await で実行する
async function connectToDatabase(){
    try {
        // データベースに接続します
        await sequelize.authenticate();
        console.log('MariaDBに正常に接続されました。');
    }
    .catch((error) => {
        console.error('MariaDBへの接続中にエラーが発生しました:', error);
    }
}

// 関数を呼び出してデータベースに接続する。
connectToDatabase();
```
AtCoder 入青

# 0. 青色になったよ
![2024-05-06_18h42_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785716/2885e4a4-a114-1518-2fa4-61f2d3b69edf.png)

日時: 2024/05/04
コンテスト: ABC352
言語: Python
# 1. 埋め状況など
![2024-05-06_18h15_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785716/194fc0cf-6e84-0140-e68e-417a015ae830.png)
![2024-05-06_18h24_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785716/205a9353-fece-d950-697b-3c8c27e418d5.png)
![2024-05-06_18h25_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785716/8f2df1e3-0c4c-332d-d364-1cdecceaca5b.png)
![2024-05-06_18h25_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785716/de084648-89e9-8175-97f6-a05021341cbb.png)
![2024-05-06_18h25_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785716/2c1d6ab1-86fe-c682-2eb2-e542dc61e9a1.png)

# 2. やったこと
## 青Difを毎日解く
[AtCoder Problems](https://kenkoooo.com/atcoder/#/table/) の Recommendation の Difficult から1問選んで解いた。
これを3-4ヶ月ほど継続した。

寝る前に問題をノートに書き写し、寝ながら考えた。
これによって習慣化したように思う。

「毎日解く」という制約は、「1日考えても分からない問題は解説見た方が良い」程度のもの。
解説ACで繋いでいる日も結構多い。


## もVに参加
[もすーんバチャ](https://mosoon.net/mov_rating/top.html)。通称「もV」。
バーチャルコンテストでありながら、レーティングシステムが実装されているのが特徴。

制限時間30分で、速解き能力が鍛えられた。


# 終
Salesforceリード取引開始済みでリードと取引先、取引先責任者、商談を同時にレポートで出す方法

Salesforceリード取引開始済みでリードと取引先、取引先責任者、商談を同時にレポートで出す方法をご紹介します

## レベル1 標準レポートタイプ「取引開始済みリード情報が関連するリード」レポートタイプでレポート作成を行う

標準レポートタイプ「取引開始済みリード情報が関連するリード」レポートタイプでレポート作成を行います


こうすれば、取引開始済みでリードと取引先、取引先責任者、商談を同時にレポートで表示することが可能です

しかしながらこのレポートタイプでは特定の項目しか出せないデメリットがあります
![001リード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/ad32784f-7b55-d83f-9f03-c80177ce5ae2.png)


他の項目を出すにはカスタムレポートタイプの作成が必要です


## レベル2 カスタムレポートタイプ「リード」を作成しレポートタイプの編集から項目を追加する


標準レポートタイプで満足しなければカスタムレポートタイプを作成しましょう

カスタムレポートタイプ「リード」であれば取引開始済みの取引先、取引開始済みの取引先責任者、取引開始済みの商談の項目（カスタム項目含む）を表示させることが可能です

以下は例として取引開始済み商談の「リードソース」をレポートで表示させるときの設定です

![002リード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/041949d7-73cb-1dbe-d932-08dc52a6aa8d.png)


![003リード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/34af284b-a066-7255-2dea-ea45ba2cbf95.png)
Ollama x Dify で Local LLM App を構築

# At first
ローカルLLM（Large Language Models）を管理・実行するためのツール「ollama」と
LLMを利用したWebアプリケーションをGUIで容易に構築できるサービス「Dify」に触れる。

具体的には、ollamaを使ってローカルでLLMを操作し、Difyを使ってそれをWebアプリケーションに統合する方法を示す。

# Ollama

### Web

https://ollama.com/

### GitHub

https://github.com/ollama/ollama

### About
git はソースコード、docker は仮想環境を管理・実行する際に便利なツールだが、
ollama は上記と似ていて、ローカルLLMを管理・実行する際に便利なツールである。
`pull` で llm をローカルに落とし、`run` で llm を実行できる。
また、ローカルLLM 使用するための Web API としての機能をもち、Difyからも使用することができる。
裏では llama.cpp が動いているようで高速な動作が期待できる。
llama.cpp: https://github.com/ggerganov/llama.cpp

### How to use
以下の docker image を利用するだけ。

https://hub.docker.com/r/ollama/ollama

ワークディレクトリを作成し、以下の docker-compose.yaml を作成する。  
その後、`docker-compose up -d` を実行する。

```yaml
version: "3.8"

services:
  ollama:
    image: ollama/ollama
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ./volumes/ollama:/root/.ollama
    # GPU ON
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              capabilities: [gpu]
    restart: always
```

コンテナが立ち上がった後は以下のコマンドでローカルLLMを `pull`, `run` する。
```shell
# enter container
docker exec -it ollama

# pull
ollama pull llama3

# run 
ollama run llama3
```

以下のように  Web API としても使用できる。
```shell
curl http://localhost:11434/api/chat -d '{
  "model": "llama3",
  "messages": [
    { "role": "user", "content": "why is the sky blue?" }
  ]
}'
```

（GGUFモデルから）自作のモデルを作りたい場合は以下コマンドを実行する。
```shell
# enter container
docker exec -it ollama

# create model
ollama create <user name>/<model name> -f Modelfile

# check model
ollama show <user name>/<model name> --modelfile

# push model
# key setting is required
# https://github.com/ollama/ollama/blob/main/docs/import.md#publishing-your-model-optional--early-alpha
ollama push <user name>/<model name>
```

モデルが pytorch や safetensors の場合は以下フロー（長い）を参照して ollamaモデル を作成する。
https://github.com/ollama/ollama/blob/main/docs/import.md#importing-pytorch--safetensors




# Dify

### Web

https://dify.ai/

### GitHub

https://github.com/langgenius/dify

### About
GUI（Webアプリケーション）でLLMアプリケーションを作成できるサービスである。
単純にLLMを利用したチャットアプリを作成できるだけでなく、フローを用いたRAGの作成も可能である。

https://www.youtube.com/watch?v=A0w9JAUZwbk

### How to use
以下の github を `pull` した後に、docker のディレクトリに行き、
`docker-compose up -d`を実行してWebアプリケーションを起動する。

https://github.com/langgenius/dify


# Ref

- Ollam x Dify で Local LLM App を構築する具体的なフローについて記載されいる。

https://qiita.com/Tadataka_Takahashi/items/ba832511bd4fd5cd46f1

- Ollama で自作モデルを作成する方法が記載されている。

https://note.com/npaka/n/ndadbae6c6be5

- にゃんたのYoutube（その1）

https://www.youtube.com/watch?v=O_bmmDWIjTc

- にゃんたのYoutube（その2）

https://www.youtube.com/watch?v=kvUy_dvZhGM
Reactでtailwindcssを使用する。

# はじめに
reactでtailwindcssとemotionを使用していい感じにcssを適用していきたい。

方法を見つけたのでここにメモとして記述する。

# ステップ１
ライブラリをインストールする
```
yarn add @emotion/react @emotion/styled twin.macro tailwindcss
```
### 解説
- twin.macro
Tailwind CSSのユーティリティクラスを直接JavaScriptファイル内で使用できるマクロ。コンポーネントの可読性が向上します。

- tailwindcss
JSXで直接使用するためにライブラリに追加します。

- @emotion/react と @emotion/styled
EmotionはReact用のライブラリで、CSS-in-JSを実現します。これにより、JavaScript内でCSSを動的に作成し、コンポーネントにスタイルを適用することができます。
    - @emotion/react はReactコンポーネント内でスタイルを定義し、適用するためのAPIを提供します。
    - @emotion/styled はスタイル付きコンポーネントを作成するためのライブラリです。
    
# ステップ２
tailwindcssの設定ファイルを生成する
``` 
npx tailwindcss init
```

設定ファイルに記述を追加
```js:tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```
### 解説
contentの部分にtailwindcssを使用する拡張子を設定。
私はtypeScriptを使用しているので、tsとtsxも追加しています。

# ステップ3
package.jsonのbabelセクションに以下の記述を追加します。
```js:package.json
 "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  }, // 追加
  "babel": {
    "plugins": ["macros"]
  },
```
### 解説
今回はこの設定によりtwin.maroなどのマクロが正しく機能するようになります。

- babelセクションの必要性
JavaScriptは頻繁に新しい機能が追加されますが、すべてのブラウザや環境がこれらの新機能を即座にサポートするわけではありません。
Babelを使用すると、最新のJavaScript機能を使用してコードを書き、それを古いJavaScriptバージョンに変換することができます。これにより、新しい機能を活用しつつ、広範なブラウザ互換性を保持できます。

# 結果

 ```js
  const MainComponent = tw.div`bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded`;
```

 
上のようにtailwindcssを適用したコンポーネントを作成することができます。


# 参考
https://github.com/ben-rogerson/twin.macro
「Could not get GOOGLE_APP_ID in Google Services file from build environment」

 「Could not get GOOGLE_APP_ID in Google Services file from build environment」

Firebaseを使ってて上記のエラーが出たら、「User Script Sandboxing」をNOに設定するって説明しか見つけられなくて、モヤモヤしてたらちゃんとFirebaseの公式に説明があった
（ただし、英語のページに限る^^;

https://firebase.google.com/docs/crashlytics/get-started?hl=en&platform=ios#set-up-dsym-uploading
（日本語も対応してくれ〜
Warning: validateDOMNesting(...): <th> cannot appear as a child of <thead>

```
Warning: validateDOMNesting(...): <th> cannot appear as a child of <thead>
```
というエラーがでたので解決した方法をここに綴ります。

# 翻訳
< th >は< thead >の子要素として使用できません。

# 問題のコード
```jsx:html
<table>
  <thead>
    <th>タイトル１</th>
    <th>タイトル２</th>
  </thead>
  <tbody>
    <tr>
      <td>内容１</td>
      <td>内容２</td>
    </tr>
  </tbody>
</table>
```

# 解決方法
```diff_jsx:html
<table>
  <thead>
+    <tr>
      <th>タイトル１</th>
      <th>タイトル２</th>
+    </tr>
  </thead>
  <tbody>
    <tr>
      <td>内容１</td>
      <td>内容２</td>
    </tr>
  </tbody>
</table>
```

warningが出ているから画面が表示されないわけではないですが、するに越したことはないです。
【iOS】Firebase SDK を追加すると didRegisterForRemoteNotificationsWithDeviceToken が呼ばれない

# 解決方法

:::note info
info.plistに以下の項目を追加する。
|Key|Type|Value|
|:-:|:-:|:-:|
|GoogleUtilitiesAppDelegateProxyEnabled|Boolean|NO|
:::

これで`didRegisterForRemoteNotificationsWithDeviceToken`が呼ばれるようになる。

<a href="https://github.com/firebase/firebase-ios-sdk/issues/7473">参考URL</a>
ArduinoUnoR4WiFi: LEDマトリックスの使い方

こちらのページと同様のことを行いました。
[Arduino UNO R4 WiFiのLEDマトリックスを使う](https://garretlab.web.fc2.com/arduino.cc/docs/tutorials/uno-r4-wifi/led-matrix/)

## ハートマーク

```text:frame01/frame01.ino
#include "Arduino_LED_Matrix.h"

ArduinoLEDMatrix matrix;

const uint32_t happy[] = {
    0x19819,
    0x80000001,
    0x81f8000
};
const uint32_t heart[] = {
    0x3184a444,
    0x44042081,
    0x100a0040
};
  
void setup() {
	Serial.begin(115200);
	matrix.begin();
}

void loop(){
	matrix.loadFrame(happy);
	delay(2000);

	matrix.loadFrame(heart);
	delay(2000);
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/91e8fbff-f249-43fc-632b-4b7317bcbad0.png)

## ウィンク

```text:frame02/frame02.ino
#include "Arduino_LED_Matrix.h"

ArduinoLEDMatrix matrix;

void setup() {
  Serial.begin(115200);
  matrix.begin();
}

uint8_t frame[8][12] = {
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};

void leftEye(){
  //Left eye
  frame[1][3] = 1;
  frame[1][4] = 1;
  frame[2][3] = 1;
  frame[2][4] = 1;
}

void wink_left(){
  //Wink with the left eye
	frame[1][3] = 0;
	frame[1][4] = 0;
}

void wink_right(){
	frame[1][8] = 0;
	frame[1][9] = 0;
}

void rightEye(){
  //Right eye
  frame[1][8] = 1;
  frame[1][9] = 1;
  frame[2][8] = 1;
  frame[2][9] = 1;
}

void mouth(){
  //Mouth
  frame[5][3] = 1;
  frame[5][9] = 1;
  frame[6][3] = 1;
  frame[6][4] = 1;
  frame[6][5] = 1;
  frame[6][6] = 1;
  frame[6][7] = 1;
  frame[6][8] = 1;
  frame[6][9] = 1;
}

void loop(){
leftEye();
rightEye();
mouth();

matrix.renderBitmap(frame, 8, 12);
delay(2000);

wink_left();
matrix.renderBitmap(frame, 8, 12);
delay(2000);

wink_right();
matrix.renderBitmap(frame, 8, 12);
delay(2000);
}
```

## 流れるメッセージ

```text:frame03/frame03.ino
// To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix
#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"

ArduinoLEDMatrix matrix;

void setup() {
  Serial.begin(115200);
  matrix.begin();

  matrix.beginDraw();
  matrix.stroke(0xFFFFFFFF);
  // add some static text
  // will only show "UNO" (not enough space on the display)
  const char text[] = "UNO r4";
  matrix.textFont(Font_4x6);
  matrix.beginText(0, 1, 0xFFFFFF);
  matrix.println(text);
  matrix.endText();

  matrix.endDraw();

  delay(2000);
}

void loop() {

  // Make it scroll!
  matrix.beginDraw();

  matrix.stroke(0xFFFFFFFF);
  matrix.textScrollSpeed(50);

  // add the text
  const char text[] = "    Good Morning!    ";
  matrix.textFont(Font_5x7);
  matrix.beginText(0, 1, 0xFFFFFF);
  matrix.println(text);
  matrix.endText(SCROLL_LEFT);

  matrix.endDraw();
}
```

![DSCN0111.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/590303d5-c574-65f3-76e7-8b3e40c58db1.jpeg)
【レスポンシブ対応】スマホ画面で生じた右側の謎の余白を消したい

昨今、レスポンシブ対応のサイトを作るのは当然となってきましたが、モバイル用のCSSを設定して実際の画面を見た際にこんなことはありませんか。

### 右側に生じている謎の余白！！！

<img width="300" alt="右の謎の隙間" title="右の謎の隙間" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149624/0923e3e6-dda5-addc-b56f-7d7fe8283738.png">

ちなみに、GoogleChromeの検証画面では確認できず、実機のiPhoneの画面でだけ確認できました。なので、色々調べてきた際のpaddingやmarginの設定誤りなどではなさそう。
![検証ツールの画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149624/3447d1d8-6860-d3f5-dc56-34db74a337f3.png)

「overflow:hidden;」を全体を囲んでいるClassに設定しても変化なし。

なんでだ……とさらに色々と調べてみた結果、下記のようなものを設定してみると言うのも出てきて、やってみました。

viewport設定を書きに書き換えてみる……。
```
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
```
残念ながら私の場合は、上記を書き替えてみても変化なしでした。

そのため、さらに色々とネット検索などで調べてみた結果……。
width:100%とwidth:autoの違いのサイトを見つけまして、
mainタグに設定していたwidth:100%をautoに変更したところ……なんと、消えました！！！

![ハンバーガーメニュートップに戻る02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2149624/514c3f0d-c7fc-fac7-03a6-73fe5bbe3b80.png)


width:100%は、要素の幅
width:autoは、幅 ＝ 左右padding ＋ 左右border ＋ 要素の幅
※[こちら](https://yoncoichi.com/html-nested/)が参考サイト様です。

という違いがあるとのことでしたので、検証画面では判別できませんでしたが、何かしらの要素が原因で100％が効かずにはみ出ていたのだろうと思います。

これからは、一番外側の親になるClassやmainタグなどには、width:autoにしておこうと思いました。
Cypressのコンポーネントテストで、"next/navigation"のuseRouterを使ったコンポーネントで"invariant expected app router to be mounted"と言われたら

Cypressを使ってNext.jsのコンポーネントテストを行っていたとき、
"next/navigation"のuseRouterを使っていたコンポーネントで、
"invariant expected app router to be mounted"
というエラーが返ってきました。

そういう時の対処法を探していたところ、Storybookでの対処方法が以下で紹介されており、その方法でCypressでも対処可能でした。

↓参考にさせていただいたサイト

https://github.com/storybookjs/storybook/issues/24722


Next.jsから　AppRouterContext を呼び出し、以下のようにテストしたいコンポーネントを囲ってあげれば、エラーを回避してテストできました。

```typescript
import {
  AppRouterContext,
  type AppRouterInstance
} from "next/dist/shared/lib/app-router-context.shared-runtime";
import TestComponent from "..";

it("Test Component", () => {
  cy.mount(
    <AppRouterContext.Provider value={{} as AppRouterInstance}>
      <TestComponent />
    </AppRouterContext.Provider>
  );
})

```
ご参考になりましたら幸いです。
mailCatcherにusernameとpasswordの設定は不要だった

## 結論
mailCatherを使用するとき、hostとportさえ適切に設定していれば送信可能

## 今回ハマった件
下記4点に全て値を設定しなければ送信できないと考えていたが、usernameとpasswordの値が不明だった
1.host
2.port
3.username
4.password

## 注意点
gmail等、実際にメールを飛ばす際には必ずusernameとpasswordを設定する必要あり

（参考例）gmailを使用してメール送信を確認したい場合のpassword設定方法
https://support.google.com/accounts/answer/185833?visit_id=638006214502263872-3045639709&p=InvalidSecondFactor&rd=1

## おわりに
今後は設定する値が不明な場合でもブランクでいいから試してみるのが大切
robloxでassistant その18

# 概要
robloxでassistantやってみた。

# 質問
jsonをパースしたい

# 回答

RobloxのHttpServiceを使用してJSONをパースする方法についてお伝えします。以下のコードサンプルをご参考ください。

```
local HttpService = game:GetService("HttpService")
local jsonString = [[
{
	"message": "success",
	"info": {
		"points": 120,
		"isLeader": true,
		"user": {
			"id": 12345,
			"name": "JohnDoe"
		},
		"past_scores": [50, 42, 95],
		"best_friend": null
	}
}
]]
local data = HttpService:JSONDecode(jsonString)
if data.message == "success" then
	-- data.info.points または data["info"]["points"] のどちらでもアクセスできます
	print("私は " .. data.info.points .. " ポイント持っています")
	if data.info.isLeader then
		print("私はリーダーです")
	end
	print("過去のスコアは " .. #data.info.past_scores .. " つあります")
	print("全ての情報:")
	for key, value in pairs(data.info) do
		print(key, typeof(value), value)
	end
end
```
このコードでは、HttpService:JSONDecode()を使用してJSON文字列をテーブルに変換しています。
その後、テーブル内のデータにアクセスしています。
JSONの構造に応じて、data.info.pointsやdata["info"]["points"]のようにアクセスすることができます。

もし質問があれば、お気軽にどうぞ。

以上。