OmniAICreator/Qiita-1.07M huggingface dataset:
Google スプレッドシートの数式エラーを Apps Script で検知する

## Google スプレッドシートの数式エラーを Apps Script で検知する
### 🔸背景
Google のスプレッドシートは強力な、配列数式(ARRAYFORMULA や、　MAP/LAMBDA)や、外部シートを取り込む IMPORTRANGE関数などを備えており、大量のデータを扱う時にとても便利に利用させてもらっています。
しかし、スプレッドシートの利用者が、配列数式が展開するはずの領域に値をいれてしまったり、IMPORTRANGE の参照するスプレッドシートの権限を変更したりするとエラーが発生し、予期しない動作をすることがあります。
### 🔸ソリューション
スプレッドシート上の数式エラーを検知してアラートメールを出す関数を Apps Script で作成しました。
Apps Script の　CreateTextFinder を使って 数式エラー(#N/A,#ERROR!,#REF!,#VALUE,#DUV/0!) を列挙し、メールアラートを出してくれます。この関数を Daily Trigger に設定しておくと、１日遅れですが数式エラーを検知できるようになります。


```
function FormulaErrorFinder() {
  let ss=SpreadsheetApp.getActiveSpreadsheet()
  let tfa=ss.createTextFinder('^[#](DIV[/]0[!]|N[/]A|ERROR!|REF[!]|VALUE[!])$').useRegularExpression(true)
  let results=tfa.findAll()
  let errortxt=''
  for(let i=0;i<results.length;i++){
    let cell=results[i]
    errortxt=errortxt+`${cell.getSheet().getName()}!${cell.getA1Notation()}:${cell.getValue()}\n`
  }
  if(errortxt!=''){
    let body=`下記スプレッドシートに数式エラーがあります。\n${SpreadsheetApp.getActiveSpreadsheet().getUrl()}\n\n${errortxt}`
    GmailApp.sendEmail('sampleuser@example.com','スプレッドシートに数式エラーがあります',body)
  }
}

```

```
出力結果：
下記スプレッドシートに数式エラーがあります。
https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxxxx/edit

シート1!D2:#DIV/0!
シート2!B2:#ERROR!
シート2!B3:#VALUE!
シート2!B4:#N/A
シート2!B5:#REF!
```

### 🔸アップデート版(1時間に一度実行対応)
１日に一度のチェックでは少なく感じ、ちょっと修正しました。
CacheService を利用して 1時間に一度、エラーチェックし、エラー内容に変更があったらメールでアラートします。CacheService は getDocumentCache で2時間前回の結果を保持しているので、1時間に一度のトリガーを使ってこの関数を呼び出してください。

```
function FormulaErrorFinderPerHour() {
  let ss=SpreadsheetApp.getActiveSpreadsheet()
  let tfa=ss.createTextFinder('^[#](DIV[/]0[!]|N[/]A|ERROR!|REF[!]|VALUE[!])$').useRegularExpression(true)
  let results=tfa.findAll()
  let errortxt_lasttime=CacheService.getDocumentCache().get('errortxt')
  let errortxt=''
  for(let i=0;i<results.length;i++){
    let cell=results[i]
    errortxt=errortxt+`${cell.getSheet().getName()}!${cell.getA1Notation()}:${cell.getValue()}\n`
  }
  CacheService.getDocumentCache().put('errortxt',errortxt,7200)  // 120分 Cache を保持するので、1時間に一度、トリガー実行をすること。7200=2時間x60分x60秒
  if(errortxt!='' && errortxt!=errortxt_lasttime){
    let body=`下記スプレッドシートに数式エラーがあります。\n${SpreadsheetApp.getActiveSpreadsheet().getUrl()}\n\n${errortxt}`
    GmailApp.sendEmail('sampleuser@example.com','スプレッドシートに数式エラーがあります',body)
  }
}
```
.NETって何？

# .NETって何？

C#での開発を始めようとすると、まず、ん？となるのが「.NET」

開発を始めるために必要な機能をまとめて提供するプラットフォームなので避けては通れない

しかし、何を使用したらよいのか、そもそも「.NET」の定義がよくわからない

という人（私）向けの記事

# ややこしくなっている原因

「.NET」という言葉が、なにを示しているかあいまいになっている

公式ドキュメントでさえも「.NET」に2つの意味があると明言している

> *.NET* には 2 つの意味があり、目的の意味はコンテキストによって異なります。
> 
> - *.NET* は、 [.NET Standard](https://learn.microsoft.com/ja-jp/dotnet/standard/glossary#net-standard) およびすべての [.NET 実装](https://learn.microsoft.com/ja-jp/dotnet/standard/glossary#implementation-of-net) ワークロードの総称として使用できます。
> - *.NET* は、.NET Core と呼ばばれ、以前は .NET のクロスプラットフォームで高パフォーマンスのオープンソース実装を指す頻度が高くなります。 また、 *.NET 5 (および .NET Core) 以降のバージョン* または *.NET 5 以降の*とも呼ばれます。
> 
> Microsoft公式ドキュメントより
> 

# .NETとは？

Q．つまるところ、.NETは何を示している？

A．.NETとは、以下の３つを備えた開発プラットフォーム

- CLR（共通言語ランタイム）
    
    人間の書いたコードを特定のOSに依存しない共通言語（中間言語）に変換する機能
    
- BCL（基本クラスライブラリ）
    
    アプリケーション開発で頻繁に使用される機能をまとめたライブラリ
    
- FW（フレームワーク）
    
    Webアプリケーションや、Windowsアプリケーションを作成するためのフレームワーク
    

## 3つの.NET○○

「.NET」とつく開発プラットフォームは、現行のもので3つある

- .NET Framework
- .NET Core
- .NET

## .NETの進化

ざっくりと

1. .NET Framework
    
    Windowsの環境で動く！
    
    でも、時代の流れ的にクロスプラットフォーム対応しないとまずくない？
    
2. .NET Core
    
    クロスプラットフォーム化できた！
    
    でも、WebアプリやCUIツールがメインでクロスプラットフォーム化しちゃった…
    
    GUIもクロスプラットフォーム化しないとな…
    
3. .NET
    
    XamarinというGUIもマルチプラットフォーム化できるようになるツールを買収
    
    統合しちゃえ！
    
    ついでに、.NET Frameworkの内容も統合しちゃえ！
    

という順番で進化している

## .NET○○の違い

進化の過程をみて分かる通り、それぞれには大きな違いがある

- 対応OS
    
    .NET Framework：Windowsのみの対応
    
    .NET Core：クロスプラットフォーム（CUIメイン）
    
    .NET：クロスプラットフォーム（CUI＋GUI）
    
- コンテナをサポートするか否か
    
    .NET Framework：基本的にNG。無理やりコンテナ化できるが非効率的
    
    .NET Core：コンテナ化OK
    
    .NET：コンテナ化推奨
    

## 結局何を使用すればよい？

結論から言うと、.NET 6以上を使用すれば間違いない

この記事を執筆している2024/07/29現在、.NET 9がリリースされている

.NET xはxが偶数だとLTS（LongTermService：長期サポート）なので、.NET 6もしくは.NET 8を使用すればよい

その中で、ネット上に情報が多く存在する.NET 6を使用すれば問題なく開発が進められると思われる

# 最後に

.NET 6のコンテナを利用したWebAPIの立て方を↓の記事で紹介しているので、そちらもぜひ読んでほしいです！
https://qiita.com/unwissenheit/items/e06fe00f5557cbc8e886
勉強中の身ですので、解釈の誤りなどがあるかもしれません。
その際は、コメントで指摘していただけると幸いです<(_ _)>
Resoniteで同期エラーが発生した場合の対処方法

# 同期エラーが発生した場合の対処法

<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626996/2990488a-b98a-69d1-8999-a95288524b22.png">

### まずは容量不足ではないか確認！
メインのドライブ (デフォルトは C:) に十分な空き容量があることを確認してください。Resonite を同期するには空きドライブ容量が必要なので、空き容量があることを確認してください。

----
空き容量があるのに同期エラーが発生した場合、クラウド上のデータが問題を起こしている可能性があります！
起動引数を設定して再起動しましょう！

### 1.-DeleteUnsyncedCloudRecords 
こちらは、同期されていないローカル（あなたのコンピュータ上の）ファイル/アイテムを削除し、クラウドのコピーを再ダウンロードします。このコマンドは、問題を起こしているデータが削除されても大丈夫なファイル/アイテムだと確信している場合にのみしてください。
### 2.-ForceSyncConflictingCloudRecords 
こちらは、競合するローカルファイル/アイテムを強制的にクラウドにアップロードします。これにより、既存のクラウドファイル/アイテムがローカルコピーで上書きされます。これにより、クラウドデータが以前の/誤ったバージョンで上書きされる可能性があるため、慎重に使用してください。

### 起動引数の設定方法
1.Steamのライブラリの左のResoniteの上にマウスカーソルを持っていき右クリックしましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626996/ea6532c3-b0cf-ee13-ed91-90839195c4e7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626996/93e31d79-79df-ece9-2e6e-49cb152b1296.png)

2.プロパティを選択！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626996/bcb7aefd-9e8b-f9a4-4383-3821d2387a1b.png)

3.一般の起動オプションに起動引数（-DeleteUnsyncedCloudRecords や　-ForceSyncConflictingCloudRecords ）をコピペします！

![スクリーンショット 2024-07-29 203902.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626996/e0741982-bcc3-0e94-8e03-c37d49c0c74e.png)

:::note info
※すでに「-LoadAssembly Libraries/ResoniteModLoader.dll」など起動引数が入っている人は末尾に「-LoadAssembly Libraries/ResoniteModLoader.dll -ForceSyncConflictingCloudRecords」のように新たに追加してあげると動きます！
:::

ResoniteWikiで読みたい方はこちら👇

https://wiki.resonite.com/Sync_Conflict
ストラテジパターンに関して（良いコード悪いコードで学ぶ設計入門のsection6を読んで）

## 目的
エンジニア2年目で、コードの書き方に迷うことが多くなってきたので、本にて学習した。

## 背景
switch文などの条件分岐でコードが読みづらくなることが多くある。
そんな時に、デザインパターンの一種であるストラテジパターンが使用できる、とのこと。

## 本文
### 前提

ゲーム開発を行なっており、技を定義したい。

#### 技
- ファイア
- 紫電
- 地獄の業火

#### 技に設定されている値
- 名前：name
- 消費魔法力：costMagicPoint
- 攻撃力：attackPower
- 消費TP:costTechnicalPoint

#### 魔法の種類を定義
```java
enum MagicType{
    fire,
    shiden,
    hellFire
}
```

#### やりたいこと
技によって、名前や消費魔法力などを定義したい。
単純に考えるのであれば、switch case文を用いて設定する。

技がfireの時　：　nameはファイア、costMagicPointは2、attackPowerは20、costTechnicalPointは0。

しかし、上記ではfire、shiden、hellFire、、、（続く）となった時に、ロジックが煩雑になっていく。
そこでinterfaceを入れることで、ロジックを見やすく見通しの良いものにしたい。 

### 1.切り替えたい機能の定義
```java
interface Magic{
    String name();
    int costMagicPoint();
    int attackPower();
    int costTechnicalPoint();
}
```

### 2.各魔法にinterfaceを実装する
```java

//　この場合は、ファイアの実装
class Fire implements Magic{ 
    private final Member member;
    
    // 初期化
    Fire(final Member member){
        this.member = member;
    }

    public String name(){
        return "ファイア";
    }

    public int costMagicPoint(){
        return 2;
    }

    public int attackPower(){
        return 20 + (int)(member.level * 0.5);
    }

    public int costTechnicalPoint(){
        return 0;
    }
}
//上記を紫電、地獄の業火に関しても作成する。
```

### 3.switchの代わりにMapで切り替える
```java
final Map<Magic Type, Magic> magics = new HashMap<>();

// ファイア型のインスタンスを生成
final Fire fire = new Fire(member);
…

// fire型がきた時には、上記のfire型のインスタンスを返す。
magics.put(MagicType.fire,fire);
…

void magicAttack(final MagicType magicType){
    
    // magicTypeには、fire、shiden、hellFireなどが入る。
    final Magic usingMagic = magics.get(magicType);

    // メソッドの定義
    showMagicName(usingMagic);
    …略

    // 　各型に応じた名前を返す
    void showMagicName(final Magic magic){
        final String name = magic.name();
    }
    …略
    
}
```

## enumとmapに関して
enum、mapあたりはjavaを使用したことがないため、イメージが湧きづらかった。
mapはphpの連想配列のようなもの。
enumはphpでもあるらしく、一連の定数をグループ化するために使用するものらしい。
mapはキーと値のペアだが、enumは値の羅列、といった感じだろうか。

## 学び
ストラテジパターンを使用することによって、条件分岐がシンプルになることがわかった。

## 次のアクション
同様に、フラグ引数ん関してもstrategyパターンが適用できるとのことなので、調べる。
WindowsでのSublimeText4の導入からよく使うショートカットについて

こんにちは、小川と申します。
テキストエディタの中で私はSublimeText4をよく使うので、導入からよく使うショートカットに関して紹介したいと思います。

## SublimeText4のダウンロード
SublimeText4のダウンロードは下記リンクから行います。
https://www.sublimetext.com/download

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/11d74634-e93d-ad2b-be07-ffbf3e5a5ea3.png)

## SublimeText4の日本語化
初期状態は英語のため日本語化します。
まず、日本語化するために必要な **Package Control** を追加していきます。

### Package Controlの追加
1. ``Ctrl`` + ``Shift`` + ``p``を押下
1.  「install」と入力
1.  「Install Package Control」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/74232ef0-04a4-6a25-bbf0-93a8aa900630.png)

これでPackage Controlが追加されました。

### 日本語化してみる
1. ``Ctrl`` + ``Shift`` + ``p``を押下してPackage Controlを呼び出します
1. 「Package Control: Install Package」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/41cb6eb2-5e11-8eb8-840c-7cc43f723f29.png)
1. 「japanize」を入力して選択すると日本語のパッケージが追加されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/7c26e1f3-5902-463e-01d3-8ef3eabac1f7.png)
1. メニューバーの「Preferences」を選択
1. 「Browse Package」を選択
1. 開いたフォルダの中に「Default」フォルダを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/0ac34390-174c-5388-197c-636b13c17561.png)
1. 「Japanize」フォルダを開く``*.jp``ファイルをすべて選択し、先ほど作成した「Default」フォルダにコピーする
1. 「Default」フォルダにコピーした全てのファイル名から「.jp」を削除する

これで日本語化の完了です

## おすすめのパッケージ

### 不要なスペースを可視化する「TrailingSpaces」
Package Controlから「TrailingSpaces」をインストールします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/8cbe4474-360b-a754-b1e4-45cdd2de91c9.png)

**TrailingSpaces**は全角半角、Tabスペース等を可視化してくれてさらにショートカットキーで不要なスペースを削除できるパッケージです。
削除するショートカットキーは、Sublime Textメニューの「Preferences > Key Bindings - User」で設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/a11929f0-dc44-cc5b-6218-7fb86af171d4.png)

### Shift_JIS等の文字化けを防ぐ「ConvertToUTF8」
Package Controlから「ConvertToUTF8」をインストールします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/7f4f0dc3-7326-18d4-cf4e-c0dc583c817a.png)

Sublime TextではShift_JISのファイルを開くと文字化けしてしまいますが、これを入れるとShift_JISをUTF8に変換して開いてくれます。

## ショートカット一覧
### ファイル系
|  コマンド  |  効果  |
| ---- | ---- |
|  Ctrl + N  |  新しいタブを開く  |
|  Ctrl + W  |  ファイルを閉じる  |
|  Ctrl + P  |  ファイルを開く(絞り込み入力ができる)  |
|  Ctrl + PageDown  |  次(右)のタブに移動  |
|  Ctrl + PageUp  |  前(左)のタブに移動  |

### ウィンドウ系
|  コマンド  |  効果  |
| ---- | ---- |
|  Ctrl + Shift + N  |  ウィンドウを開く  |
|  Ctrl + Shift + W  |  ウィンドウを閉じる  |

### 編集系
|  コマンド  |  効果  |
| ---- | ---- |
|  Ctrl + C  |  コピー  |
|  Ctrl + V  |  貼り付け  |
|  Ctrl + ] or Tab  |  インデント  |
|  Ctrl + [ or Shift + Tab  |  アンインデント  |
|  Ctrl + Shift + ↑ or ↓  |  行の移動  |
|  Ctrl + Shift + D  |  現在行を複製  |
|  Ctrl + Shift + K  |  行の削除  |
|  Ctrl + Shift + Enter  |  カーソル行の前に改行を挿入  |
|  Ctrl + /  |  コメントアウト  |
|  Ctrl + Shift + /  |  範囲コメントアウト  |

### 検索・置換・選択系
|  コマンド  |  効果  |
| ---- | ---- |
|  Ctrl + F  |  検索  |
|  Ctrl + H  |  置換  |
|  Alt + Enter  |  A検索文字列を全選択  |
|  Ctrl + A  |  全選択  |
|  Ctrl + L  |  行選択  |


## まとめ
Sublime Textは使いやすく、プラグインが多く自分流にカスタマイズできてとても便利なのでぜひ皆さんも使ってみてください。
Gemini APIのCode Execution

Restから呼び出すGemini APIからでもCode Executionが使えるようになりました？
https://developers.googleblog.com/ja/new-features-for-the-gemini-api-and-google-ai-studio/

## まとめ
Gemini 1.5 Flashは安いモデルとして検討の余地ありかも

Code Execution搭載なLLMは計算が正確になります。

スマフォで問題の写真送るだけで高校数学やプログラム問題なら結構解けるのでは？

## Code Execution
従来の LLM は、数学やデータ推論の問題が得意ではありませんでした。
https://gigazine.net/news/20230601-chat-ai-mathematical-reasoning/

その解決方法としては、計算部分をFunction Callingで別途呼び出し（ユーザーが)でした。
それが、Code Execution機能を使うことで、Gemini API側の内側でPython実行して結果を返して、その結果を元に推論するので正確さが増しました。

また制限はありますが、Pythonコードも実行できます。スマフォでパイソン学習とかもできそうですね。

## Godot版
サンプル更新しました。
https://github.com/akjava/godot-simple-gemini-api
Python デコレータを使って関数をパワーアップする方法

## はじめに

Pythonのデコレータは、既存の関数やクラスを修正したり拡張したりする強力な機能です。本記事では、デコレータの基本的な概念から実践的な使用例まで、段階的に解説していきます。

## デコレータとは

デコレータは、他の関数を引数として受け取り、その動作を変更または拡張する関数です。簡単に言えば、既存の関数をラップして新しい機能を追加する方法です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/d39ec340-b806-4cc9-465a-4c3d967d1bee.png)

## 基本的なデコレータの書き方

まずは、シンプルなデコレータの例を見てみましょう。

```python
def simple_decorator(func):
    def wrapper():
        print("関数が呼び出される前")
        func()
        print("関数が呼び出された後")
    return wrapper

@simple_decorator
def say_hello():
    print("こんにちは！")

say_hello()
```

実行結果：
```
関数が呼び出される前
こんにちは！
関数が呼び出された後
```

この例では、`simple_decorator`が`say_hello`関数をラップし、関数の前後に追加のメッセージを表示します。

## 引数を持つ関数のデコレート

引数を持つ関数にデコレータを適用する場合は、以下のように書きます。

```python
def log_args(func):
    def wrapper(*args, **kwargs):
        print(f"呼び出された引数: {args}, {kwargs}")
        return func(*args, **kwargs)
    return wrapper

@log_args
def add(a, b):
    return a + b

result = add(3, 5)
print(f"結果: {result}")
```

実行結果：
```
呼び出された引数: (3, 5), {}
結果: 8
```

この例では、`log_args`デコレータが関数の引数をログ出力します。

## デコレータに引数を渡す

デコレータ自体に引数を渡したい場合は、以下のように実装します。

```python
def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f"こんにちは、{name}さん！")

greet("太郎")
```

実行結果：
```
こんにちは、太郎さん！
こんにちは、太郎さん！
こんにちは、太郎さん！
```

この例では、`repeat`デコレータが関数を指定回数繰り返し実行します。

## 実践的な使用例

### 1. 実行時間の計測

```python
import time

def measure_time(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__}の実行時間: {end_time - start_time:.4f}秒")
        return result
    return wrapper

@measure_time
def slow_function():
    time.sleep(2)
    print("処理完了")

slow_function()
```

実行結果：
```
処理完了
slow_functionの実行時間: 2.0021秒
```

### 2. キャッシュ（メモ化）

```python
def memoize(func):
    cache = {}
    def wrapper(*args):
        if args in cache:
            return cache[args]
        result = func(*args)
        cache[args] = result
        return result
    return wrapper

@memoize
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(100))
```

実行結果：
```
354224848179261915075
```

この結果は瞬時に出力されます。キャッシュがない場合、この計算には非常に長い時間がかかります。

## まとめ

デコレータを使うことで、コードの再利用性が高まり、関数の機能を柔軟に拡張できます。本記事で紹介した例を参考に、自分のプロジェクトでデコレータを活用してみてください。デバッグ、ログ出力、性能測定など、様々な場面でデコレータが役立つはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/59ef739f-a1b1-e58c-a6e2-35e212abe168.png)

## 参考文献

- Python公式ドキュメント: [関数定義](https://docs.python.org/ja/3/reference/compound_stmts.html#function-definitions)
- Real Python: [Primer on Python Decorators](https://realpython.com/primer-on-python-decorators/)
Docker: Ubuntu 24.04 にインストール

こちらと同じことを行いました。
[Ubuntu24.04にDockerをインストールする](https://higmasan.com/docker/install/installing-docker-on-ubuntu24-04/)

DockerリポジトリのGPGキーを取得

```bash
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
```

Dockerリポジトリをaptソースに追加

```bash
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```

```bash
sudo apt update
sudo apt upgrade
```

インストール

```bash
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```

## バージョンの確認

```text
$ sudo docker --version
Docker version 27.1.1, build 6312585
```

## 動作確認

```text
$ sudo docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.
（省略）
```

## 一般ユーザでDockerを使えるようにする

```bash
sudo usermod -aG docker uchida
```

```bash
newgrp docker
```

docker グループに uchida というユーザーが加わったことを確認

```text
$ groups uchida
uchida : uchida sudo www-data docker
```

確認

```bash
docker run hello-world
```

## composer のバージョン確認

```text
$ docker compose version
Docker Compose version v2.29.1
```
【paiza】C#でSランク相当問題「文字列収集」を解いた

## 解いた問題
https://paiza.jp/works/mondai/real_event/word_collection
## 作成したコード
* クエリの文字列が市場の文字列の先頭に一致するかは、StartsWith()メソッドを使用しました。
   * https://learn.microsoft.com/ja-jp/dotnet/api/system.string.startswith?view=net-8.0
:::note warn
注意
[Contains()](https://learn.microsoft.com/ja-jp/dotnet/api/system.string.contains?view=net-8.0)メソッドでは、クエリの文字列が市場の文字列の先頭以外含まれる場合も検出されてしまうので、今回の用途では使用しません。
:::
~~~cs
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        string[] p  = Console.ReadLine().Split(' ');
        int soldStrNum = int.Parse(p[0]);
        int queryNum = int.Parse(p[1]);
        
        string[] soldStr = new string[soldStrNum];
        int[] soldCost = new int[soldStrNum];
        string[] queries = new string[queryNum];
        int[] score = new int[queryNum];
        for(int i=0; i<queryNum; i++)
        {
            score[i] = 0;
        }
        
        for(int i=0; i<soldStrNum; i++)
        {
            string[] input = Console.ReadLine().Split(' ');
            soldStr[i] = input[0];
            soldCost[i] = int.Parse(input[1]);
        }
        
        for(int i=0; i<queryNum; i++)
        {
            queries[i] = Console.ReadLine();
        }
        
        int i_sc = 0;
        foreach(var q in queries)
        {
            for(int i=0; i<soldStrNum; i++)
            {
                if(soldStr[i].StartsWith(q))
                {
                    score[i_sc] += soldCost[i];
                }
            }
            i_sc++;
        }
        
        foreach(var sc in score)
        {
            Console.WriteLine(sc);
        }
    }
}
~~~
プログラミングで調べ物をする時によく見るサイト一覧

こんにちは、WEBエンジニアの堀井です。

今回は、自分が実際にWEBアプリケーションを作成している際に調べ物をする際によく見るサイトを紹介しようと思います。

個人的優先度の高い順で紹介していきます。

## 各言語の公式ドキュメント

まずは公式ドキュメントを見ます。
とりあえずググって適当なサイトを見に行く方も多いと思いますが、公式ドキュメントは実際かなり使えるので、まずはここで調べます。

ここに情報がなければ、以下サイトを巡って調べていきます。

## Zenn
https://zenn.dev

こちらはエンジニアのための情報共有サイトです。
2020年9月からサービス開始なので結構新しいサイトになります。
新しい情報はQiitaよりもこちらの方が多くあったりするので重宝しています。

## Qiita
https://qiita.com

言わずと知れたエンジニアのための知識共有サービスです。
本記事も投稿しているサイトですね。
2011年9月からサービスを開始しているということもあり、古い情報や新しい情報が満遍なくあり、かつ記事の量がとても多いので活用している方も多いと思います。

## Stack Overflow
https://stackoverflow.co

大体の情報は上記サイトで賄えるのですが、少しニッチな情報が欲しい場合はこちらのサイトを使用しています。
2008年5月サービス開始というかなり古くからあるサイトで、世界のエンジニアの叡智が集合しています。
基本的には英語なので、Google翻訳を駆使して探し回っています。
もうダメだと思った時、このサイトに助けられたことが何度もあるので、英語にビビらずこのサイトを利用して欲しいですね。

## 個人ブログ

個人ブログには、amebaブログやはてなブログなどの個人ブログ、個人で運用しているブログの2つがあります。
個人ブログの記事を見る優先度は高くないですが、こちらも大切な情報源です。
特にニッチな特定条件下での情報が掲載されていることが多いので、ピンポイントでやりたいことが紹介されていた場合は当たりです。

## まとめ

今回は調べ物でよく使うサイトを紹介しました。
Qiitaはもちろん、その他のサイトもエンジニアなら知っているサイトがほとんどだと思いますが、今まで使っていなかったサイトなどありましたらこれを機に使ってみてはいかがでしょうか？

以上、堀井でした。
Grepの検索結果が不足していたお話

こんにちは。
東です。

今回はタイトルにあります通り、
シェルスクリプトの実行時に起きたことについてお話させていただきます。

### 何が起きたのか
ログの監査のため、レベルを”ERROR”,”WARN”で記録された箇所を抽出する
シェルスクリプトを使っていました。

例で以下のようなエラーが __4__ つ記録されていたとします。
```
2024-07-29T01:52:00.000 JST WARN  エラー箇所 0001:エラー内容
～省略～
2024-07-29T01:53:00.000 JST ERROR  エラー箇所 0002:エラー内容
～省略～
2024-07-29T01:54:00.000 JST ERROR  エラー箇所 0003:エラー内容
～省略～
2024-07-29T01:55:00.000 JST WARN  エラー箇所 0004:エラー内容

```

以下のようなシェルスクリプトを実行したところ...
```
  grep -n -e WARN -e ERROR ${”調査対象のファイルパス”}
```
取得できたのは僅か __1__ 件でした。
```
2024-07-29T01:52:00.000 JST WARN  エラー箇所 0001:エラー内容
```
### 原因
実際にシェルスクリプトで出力された結果を確認してみたところ

```
2024-07-29T01:52:00.000 JST WARN  エラー箇所 0001:エラー内容
↓謎のメッセージが出力されていた
Binary file ファイルパス matches
```
となっていました。
なんでもGrepした際に __バイナリファイルと判断されてしまう__ ことがあるようですね。
こうなると検索できた行数以下はバイナリのデータとして検索をやめてしまうことがあるみたいです。
バイナリとして判断されてしまう基準に関しては、確実な状況はあまりなさそうでした。

### 解決方法
「このファイルはテキストファイルです」と指定できるようなオプションが
きちんと用意されていました。
こちらの”-a”というオプションを追加すると、テキストファイルとして最初から
検索してくれるようになります。
```
↓オプション”-a”を追加
  grep -n -e -a WARN -e ERROR ${”調査対象のファイルパス”}
```

修正したシェルスクリプトを実行したら...
```
2024-07-29T01:52:00.000 JST WARN  エラー箇所 0001:エラー内容
2024-07-29T01:53:00.000 JST ERROR  エラー箇所 0002:エラー内容
2024-07-29T01:54:00.000 JST ERROR  エラー箇所 0003:エラー内容
2024-07-29T01:55:00.000 JST WARN  エラー箇所 0004:エラー内容
```
きちんと4件取得できました！

### まとめ
ちょっとしたトラブルシューティングについてのお話をさせていただきました。
こういった実運用で発覚するようなエラーは知識として無いとあらかじめ対策などはできないので難しいですね。
知識のありがたみを痛感した出来事でした。
以上東でした。
github.com/aws/aws-sdk-go-v2のEndpointが非推奨になっていた件

# 概要

新しいサービスを作るにあたってGo言語からR2に読み書きする必要があり、[github.com/aws/aws-sdk-go-v2](github.com/aws/aws-sdk-go-v2)を使ったS3クライアントの初期化処理を既存サービスから流用しようとしました。その際、`EndpointResolverWithOptionsFunc`などの関数がDeprecatedになっていました。

これについて言及している記事があまり無かったので、メモがてら記事にしてみました。

# 内容
調べたところSDKの[aws/endpoints.go](https://github.com/aws/aws-sdk-go-v2/blob/main/aws/endpoints.go)内の構造体や関数が非推奨になっていました。

`EndpointResolver`のインターフェース定義部分に以下のようなコメントがありました。

```golang
// Deprecated: The global endpoint resolution interface is deprecated. The API
// for endpoint resolution is now unique to each service and is set via the
// EndpointResolverV2 field on service client options. Setting a value for
// EndpointResolver on aws.Config or service client options will prevent you
// from using any endpoint-related service features released after the
// introduction of EndpointResolverV2. You may also encounter broken or
// unexpected behavior when using the old global interface with services that
// use many endpoint-related customizations such as S3.
```
翻訳すると

> 非推奨： グローバルエンドポイント解決インターフェイスは廃止予定です。エンドポイント解決のためのAPIは、現在では各サービスに固有であり、サービスクライアントオプションのEndpointResolverV2フィールドを介して設定されます。aws.ConfigまたはサービスクライアントオプションでEndpointResolverの値を設定すると、EndpointResolverV2の導入後にリリースされたエンドポイント関連のサービス機能を使用できなくなります。また、S3のようなエンドポイント関連のカスタマイズを多用するサービスで古いグローバルインターフェースを使用すると、壊れたり予期しない動作が発生する可能性があります。

つまり、グローバルエンドポイント設定から各サービスの設定に変更され、SDKの各サービスに定義されている`EndpointResolverV2`を使う必要があるらしいです。

そして、既存サービス側が使用しているバージョン（`v1.24.0`）においてもコメントで`Deprecated`と書かれていました。


ちなみにR2の[aws-go-sdkのドキュメント](https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/)は更新されておらず、[issue #12043](https://github.com/cloudflare/cloudflare-docs/issues/12043)が立っていました。

## 従来実装
```golang
		akey := c.AccessKeyID
		skey := c.SecretAccessKey
		region := c.Region
		endpoint := c.Endpoint

		creds := credentials.NewStaticCredentialsProvider(akey, skey, "")
		resolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
			return aws.Endpoint{
				URL:           endpoint,
				SigningRegion: region,
			}, nil
		})

		cfg, err := awsconfig.LoadDefaultConfig(
			context.TODO(),
			awsconfig.WithCredentialsProvider(creds),
			awsconfig.WithEndpointResolverWithOptions(resolver),
			awsconfig.WithRegion(region),
		)
		if err != nil {
			panic(err)
		}

		client := s3.NewFromConfig(cfg, func(o *s3.Options) {
			o.UsePathStyle = true
		})

```

## 新しい実装

`aws.EndpointResolverWithOptionsFunc`でresolverを作り、awsのグローバル設定として設定する記述が要らなくなり、s3のサービスの設定として指定するようになります。

```golang
		akey := c.AccessKeyID
		skey := c.SecretAccessKey
		region := c.Region
		endpoint := c.Endpoint

		creds := credentials.NewStaticCredentialsProvider(akey, skey, "")

		cfg, err := awsconfig.LoadDefaultConfig(
			context.TODO(),
			awsconfig.WithCredentialsProvider(creds),
			awsconfig.WithRegion(region),
		)
		if err != nil {
			panic(err)
		}

		client := s3.NewFromConfig(cfg, func(o *s3.Options) {
			o.UsePathStyle = true
			o.BaseEndpoint = aws.String(endpoint)
		})
```

# 最後に
同じような内容で詰まっている方の助けになれば幸いです。
何か間違いや修正すべきところがあればコメントで教えてください。
文字の一致 (paizaランク D 相当)

## 素人がpaizaコラボキャンペーンに参加してみた

### VBAが選択肢になかったので、Python3にしました

https://paiza.jp/works/mondai/d_rank_skillcheck_sample/diff_str

![paiza1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/fcf9a4d0-1039-cead-140b-64eae629089c.png)

![paiza3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/75d13b77-dfa7-50de-9485-b467a8df65f1.png)
TFTPサーバの設定方法 (AlmaLinux 9.4)

# はじめに
TFTPとはUDPを用いた簡易的なファイル転送プロトコル。
FTPと比較して、パスワード認証が行われない点と、UDPで動作しておりFTPより信頼性は劣るが転送効率を重視している点が特徴である。
今回、TFTPサーバの設定を行ったので備忘録として記載する。

# 環境
AlmaLinux 9.4

# 手順
- インストール
```
$ sudo dnf -y install tftp-server
```

- firewall設定
    - TFTP通信を許可する。
```
$ sudo firewall-cmd --permanent --zone=public --add-service=tftp
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-all
```

- サービス起動設定
```
$ systemctl start tftp.socket
$ systemctl enable tftp.socket
```

- サービスの起動状態を確認したい場合
```
$ systemctl status tftp.socket
```

- TFTPサーバのルートディレクトリは```/var/lib/tftpboot```
    - 転送したいファイルはそこに配置する。
AlmaLinux8にImageMagickをインストールできない

## 問題
dnfでImageMagick-develが入らない。
```sh
dnf -y ImageMagick-devel
No match for argument: ImageMagick-devel
```

## 解決方法
EPELを使ってインストールします。
```sh
dnf -y install epel-release
dnf -y install ImageMagick-devel --enablerepo=epel
```

## 参照
https://www.den-tsu.net/centos8-imagemagick/
Linux（KDE、LXQtデスクトップ環境）でeduroamに接続する

## はじめに
KDEデスクトップ環境とLXQtデスクトップ環境で弊学のeduroamに接続を試みたら意外と手こずったので備忘録がてらメモ。
所属大学と環境によっては上手くいかない場合あり。

## 環境
### KDEデスクトップ環境
- Panasonic CF-RZ6
- Kubuntu 24.04 LTS
### LXQtデスクトップ環境
- Fujitsu ARROWS Tab Q507/PE
- Lubuntu 24.04 LTS

## KDEデスクトップ環境の場合
### 一般設定
![Screenshot_20240527_124819.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/d44a4cdd-2fac-c3d0-d94a-583a32709e5f.png)
特に何もしない。
### Wi-Fi
![Screenshot_20240527_124840.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/72dabdd8-b08f-affb-8e28-da971cf12030.png)
特に何もしない。
### Wi-Fi セキュリティ
![Screenshot_20240527_125009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/3a135343-3a2c-be48-ee2d-e5ab1412ac78.png)
設定が必要。
「認証」はProtected EAP(PEAP)に設定する。
「Anonymous identity」と「ユーザ名」は大学から支給されているメールアドレスを入力する。
「パスワード」は大学から支給されているアカウントのパスワードを入力する。
パスワード入力欄の下部にあるプルダウンメニューは「すべてのユーザーにパスワードを保存(暗号化なし)」を選択する。
### IPv4
![Screenshot_20240527_125036.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/ca306e83-ce1d-2121-ef09-e420c8d4f6b4.png)
特に何もしない。
### IPv6
![Screenshot_20240527_125057.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/8c7393aa-3898-cc9a-1952-495b197bb340.png)
特に何もしない。
## LXQtデスクトップ環境の場合
なぜかスタート画面右下のWi-Fi接続画面からは接続できないため、
スタート画面左下のアプリケーションメニュー
↓
「設定」
↓
「高度なネットワーク設定」
↓
ウィンドウ左下の「+(新規接続を追加)」ボタンより手動で設定する。
### 全般
![screen (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/df30e1d1-2ec2-6af9-2970-80383ebac690.jpeg)
特に何もしない。
### Wi-Fi
![screen (3).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/e6bac7c5-a8b7-9be4-a9f8-29513231e45a.jpeg)
「モード」のプルダウンメニューを開き、「クライアント」を選択する。
### Wi-Fi セキュリティー
![screen.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/84ce48ec-2b44-926d-9013-7dc97db17dcc.jpeg)
基本的にはKDEデスクトップ環境の設定に準ずる。
「CA証明書は必要ありません」のチェックボックスを押し、☑に変更する。
![screen (7).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/144cccea-6f9e-4488-f08e-3fe117512a00.jpeg)
「:couple:」のアイコンをクリックし、「すべてのユーザーのパスワードを保存する」ラジオボタンを押す。
### プロキシー
![screen (4).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/8007ebdb-fe5d-e862-5083-420f1375cf80.jpeg)
特に何もしない。
### IPv4 設定
![screen (5).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/5ea52f71-d74a-722b-6711-41b07afa3ac7.jpeg)
特に何もしない。
### IPv6 設定
![screen (6).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3656975/8b1bc97a-1281-4ee5-5550-7f91910b9de4.jpeg)
特に何もしない。
## 参考記事
[eduroam - Gentoo Wiki](https://wiki.gentoo.org/wiki/Eduroam)
Microsoft Defender for BusinessにiPhoneを追加する

一人で会社を始めたため、セキュリティ対策をどのように実施するかも自分で考える必要がありました。最近では通常のマルウェア対策ソフトのみならず、エンドポイント対策としてEDR (Endpoint Detection and Response)やXDR (Extended Detection and Response)は必須だと考え、Microsoft Defender for Businessを会社立ち上げ当初から使っています。
このMicrosoft Defender for Business、Windows マシンへの導入は簡単にできたのですが、iPhoneへの導入がうまくできていなかったので、その原因（単純な設定洩れ）を記録として残します。
# Microsoft Defender for Businessとは
Microsoft Defenderは、Microsoft社が提供しているエンドポイント対策製品です。個人向けの「Microsoft Defender」は、Microsoft 365のサブスクリプションに含まれていて、個人が使うWindows/Mac/iOS/Androidのセキュリティ対策ソフトとして利用できます。
一方、法人向けには、管理機能などを強化した製品が提供されていています。大企業向けには多くの機能を含む「Microsoft Defender XDR」がありますが、中小企業向けにはもう少し機能を絞った「Microsoft Defender for Business」があります。
Microsoft Defender for Businessには基本的なEDRの機能が含まれていて、価格も1ユーザ辺り449円/月と安価なので、ユーザ数が少ない場合は導入しやすい製品だと思います。

https://www.microsoft.com/ja-jp/security/business/endpoint-security/microsoft-defender-business
# Windowsマシンの導入は簡単
最初に追加したエンドポイントは、日頃使っているWindowsマシンでした。いろいろなアプリをインストールしているので、それらの脆弱性対策が気になっていました。
管理画面（Windows Defenderポータル）からエンドポイントとしてWindows 11マシンを追加すると、専用のインストール用スクリプトがダウンロードできます。導入したいWindowsマシン上で、このスクリプトを管理者権限で実行すれば、導入完了です。
導入後は、定期的にWindowsマシンから情報がクラウド上にアップロードされて、脆弱性情報などが管理画面で確認できるようになります。重要な脆弱性が発見された時には、メールで通知が来ます。

よく発見される脆弱性は、Google ChromeやMicrosoft Edge、Adobe Acrobatなどですが、その他のアプリも脆弱性が見つかると教えてくれます。各脆弱性について、対象となる具体的なファイル名（パス名）や、対応するCVEの情報も分かるので、アプリのアップデートなどを速やかに実施できるようになりました。
# iPhoneへの導入で躓く
同様に、日頃使っているiPhone（iOSマシン）も登録しようとしましたが、いつまで経っても管理画面上に現れませんでした。結論からいうとiPhone上のMicrosoft Authenticatorの設定ができていなかったのですが、改めて以下に手順を書いておきます。やり方が分かれば、説明書に書かれている通りでした。
https://learn.microsoft.com/ja-jp/defender-business/mdb-onboard-devices?tabs=mobiles#use-the-microsoft-defender-app

## Microsoft Authenticatorをインストールして設定する
iPhone上で、App Store からMicrosoft Authenticatorをインストールします。日頃Microsoft 365などで2要素認証を設定していると、既にインストール済みなケースも多いと思います。
説明書には「サインインし、Microsoft Authenticatorアプリにデバイスを登録します」と書かれていますが、当初この部分が理解できずに読み飛ばしていました。Microsoft 365で2要素認証をする際にAUthenticatorを使っており、サインインに使っているアカウントのワンタイムパスワードが設定済みだったため、それで「サインイン」が済んでいるのだと勘違いしていました。
デバイスを登録するためには、Authenticator のアプリのメニューから「設定」→「デバイスの登録」を選び、そちらでサインインする必要がありました。

## Microsoft Defenderをインストールして設定する
続いて、iPhone上でApp StoreからMicrosoft Defenderをインストールします。アプリ上の指示の通りにこちらでもサインインして、さらにVPN接続の設定をすることで、Defenderへの登録は完了です。

以上の設定で、Defenderの管理画面上にiPhoneがデバイスとして表示されるようになりました。
NFSサーバの設定方法 (AlmaLinux 9.4)

# はじめに
NFSとはLinuxなどで利用されるファイル共有システム。
NFSサーバでディレクトリを公開し、NFSクライアントからマウントすることで共有ディレクトリにアクセスすることができる。
今回、NFSサーバの設定を行ったので備忘録として記載する。

# 環境
AlmaLinux 9.4

# 手順
- インストール
```
$ sudo dnf install -y rpcbind nfs-utils
```

- 共有ディレクトリの作成
    - 今回は```/share/nfs```というディレクトリを共有ディレクトリとする。
    - ディレクトリのアクセス権限を```chmod```で変更する。```0777```と指定する場合、全てのユーザーにrwx全てのアクセス権限を許可する。
```
$ sudo mkdir /share
$ sudo mkdir /nfs
$ sudo chmod 0777 /share
$ sudo chmod 0777 /nfs
```

- 共有ディレクトリのエクスポート設定
    - NFSの共有ディレクトリの設定について```/etc/exports```に記述する。
        - まず、```/share/nfs```のように公開ディレクトリのパスを記述する。
        - スペースを空け、アクセスできるホストの範囲を記述する。*の場合、全ホストに公開する。
        - rw(読み書き可能)、rootアクセス可能(no_root_squash)、async(非同期書き込み有効)。
```txt:/etc/exports
/share/nfs *(rw,no_root_squash,async)
```

- firewall設定
    - NFS通信を許可する。
```
$ sudo firewall-cmd --permanent --zone=public --add-service=nfs
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-all
```

- サービス起動設定
```
$ systemctl start rpcbind
$ systemctl start nfs-server
$ systemctl enable rpcbind
$ systemctl enable nfs-server
```

- サービスの起動状態を確認したい場合
```
$ systemctl status rpcbind
$ systemctl status nfs-server
```

- 共有ディレクトリ内に、共有したいファイルを格納
```
$ touch /share/nfs/hoge.txt
```

\:warning:```/etc/exports```を変更するなど設定を変更した場合、NFSサーバの再起動を行い設定変更を有効化させる。
```
$ systemctl restart rpcbind
$ systemctl restart nfs-server
```
Power Automateでラインモのご利用料金内訳明細書から金額を抽出

経費精算を自動化したくて作った時の個人的なメモです。

ご利用料金内訳明細書のダウンロードはSMSのセキュリティ番号を使った認証が必要だったので自動化できませんでした。
PDFをダウンロードしたところからスタート。

## PDFをテキストにして、テキストを1行ごとのテキストリストに変換

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1839497/5ec58da5-0b12-7a2e-5fe9-5a1c59e7a44d.png)

1. ファイルの選択ダイアログを使ってPDFファイルを指定する。（ファイルフィルターは「*.pdf」、複数の選択を許可しない）
1. PDFをCSVに変換する
1. CSVを1行ごとのリストに変換する

## テキストの解析を使って、特定文字（今回だと「**小計**」と「**消費税等10%**」）がある行の数値だけを抽出
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1839497/c7334d26-a888-e26b-153f-9004e5a9d43b.png)

1. さっきのテキストリストを1行ごと食わせてループする
1. **小計** の文字列を探して、結果を変数 **小計** に入れる（その文字がないと-1を返し、あると0以上を返す）
1. 同様に**消費税等10%** の文字列を探して、結果を変数 **消費税** に入れる（10行目のENDのあとに入れても見やすくてわかりやすいかもしれないですね）
1. もし**小計**が0より大きかったら（＝その行に小計の文字列があったら）以下を実行する
1. 空白をトリム
1. その行を **'\s+'**（正規表現で'1つ以上の空白'）で分割する
1. 分割したリストの2つ目（リストや行列は0始まりなので[1]は2つ目を表す）を変数に取り出す
1. 取り出した文字列を数字に変換する（4桁以上あったときのカンマを消してくれる）
1. （動作確認用、省略）
1. Ifの終了
1. もし**消費税**が0より大きかったら（＝その行に消費税等10%の文字列があったら）以下を実行する
1. 空白をトリム
1. その行を **'\s+'**（正規表現で'1つ以上の空白'）で分割する
1. 分割したリストの2つ目（リストや行列は0始まりなので[1]は2つ目を表す）を変数に取り出す
1. 取り出した文字列を数字に変換する（4桁以上あったときのカンマを消してくれる）
1. （動作確認用、省略）
1. Ifの終了
1. For Eachのループの終了

これで変数 **小計数字** と **消費税数字** の中にそれぞれ税別の金額と消費税の金額が代入されます。
この数字を使って経費精算のワークフローを自動化していますが、ここから先は所属企業固有のシステムなので書きません（書けません）。

応用すればPDFから任意の文字や数字を取り出して活用ができそうですね！
[paiza]1番小さい数字

# 初心に返って
どんどん、解いていこうね～

https://paiza.jp/works/mondai/d_rank_skillcheck_sample/min_num

# これからも解いていく可能性を信じて
まだまだ問題いっぱいあるっぽいので、やろうという気持ちがあるうちに。。。
全問題で共通となるパラメータの取得部分はもうindex.jsに書いてしまって、
処理の部分をmodule化してindex.jsから呼び出すようにしてみた

```javascript:index.js
process.stdin.resume();
process.stdin.setEncoding('utf8');

const lines = [];
const reader = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout
});

reader.on('line', (line) => {
  lines.push(line);
});
// paizaで公開されてるサンプルのclose部分で作ったモジュールを呼び出す感じに
reader.on('close', () => {
  // require("./mod7").countDivisibleBy7(lines); // 前回更新の7で割れるかな問題のModule
  require("./min5").min5(lines); // 今回の最小値ど～れ問題のModule
});
```

```javascript:min5.js
// [問題文（原文）]
// 5 つの正の整数が入力されるので、最も小さい数字を出力して下さい。
function min5(lines) {
  if (!Array.isArray(lines) || lines.length !== 5) {
    console.log("5個の数字を入れろや！");
    return;
  }
  if (!lines.every(line => Number.isInteger(Number(line)))) {
    console.log("正の整数を入れろや！");
    return;
  }
  console.log(Math.min(...lines));
}

module.exports = {
  min5
};
```

後からダラダラ更新したくないため、今回ははじめから入力チェックやら何やらを入れてみた！
だいぶスッキリキレイに書けたんじゃなかろうか？

最初For分でグルグル書いてたんだけど、もっとスッキリする書き方ないかなと調べてこっちの方法が見つかったので試しに書いてみました。

いかに短くわかりやすく書くかっていうの大事だよね！
macローカルでEC-CUBE開発環境を構築（デバッグあり）

# 基本環境
macOS Sonoma 14.5
php 8.1
VSCode 1.91

# データベース構築

ダウンロードできるMySQLバージョンを検索
```
brew search mysql
```

インストール
```
cd

brew install mysql@8.0
```
パスを通す
```
echo 'export PATH="/usr/local/opt/mysql@8.0/bin:$PATH"' >> ~/.zshrc

source .zshrc
```
確認する
```
mysql --version

mysql  Ver 8.0.38 for macos14.4 on x86_64 (Homebrew)
```
起動する
```
mysql.server start
```
設定する
```
mysql -u root

mysql> create user 'aaa'@localhost identified by 'bbbbbb';

mysql> grant create on *.* to aaa@localhost;
```
ログイン
`mysql -u aaa -p`
`bbbbbb`

ホスト名の確認
```
mysql> show variables like 'hostname';

+---------------+---------------------+
| Variable_name | Value               |
+---------------+---------------------+
| hostname      | Hoge.local          |
+---------------+---------------------+
```

EC-CUBE用データベースの作成
```
CREATE DATABASE eccube_db
```

# ローカルに開発フォルダを作成
User/UserName/Documents/EccubeDevelop

# Composerインストール
Terminalで`User/UserName/Documents/EccubeDevelop`にアクセス

https://getcomposer.org/download/
のPreタグに囲まれているコマンドを実行
User/UserName/Documents/EccubeDevelop/composer.phar が生成される

composer.phar のバージョンをEC-CUBE 4.0の対応しているバージョン（1.x）に変更する
```
php composer.phar selfupdate --1
```
```
Upgrading to version 1.10.27 (1.x channel).
   
Use composer self-update --rollback to return to version 2.7.7
```
と表示されれば成功

# インストールファイルをダウンロード
https://github.com/EC-CUBE/ec-cube/releases
よりインストールしたいEC-CUBEバージョンをダウンロードし、`User/UserName/Documents/EccubeDevelop`へ保存


あるいはコマンドラインからダウンロードする
```
php composer.phar create-project ec-cube/ec-cube ec-cube "4.1.x" --keep-vcs
```
コマンドでダウンロードした場合は`Vendor`フォルダが欠落している可能性あり

# ビルトインウェブサーバー起動

EC-CUBEルートへ移動
```
cd User/UserName/Documents/EccubeDevelop/ec-cube

php -S localhost:8080
```
http://localhost:8080/
で表示される

```
Ctrl+C
```
で停止



# EC-CUBEインストール

# オプション：デバッグする場合
### Xdebugインストール
Debug Build が no になっていることを確認

```
$ php -i | grep 'Debug Build'

Debug Build => no
```

Xdebug がインストールされていないことも確認

```
$ php -m | grep xdebug

ない場合、表示なし
```
Xdebug をDL

http://www.xdebug.org/download.php

解凍して開発ディレクトリに移動
```
$ tar -zxvf ~/Downloads/xdebug-xxx.tgz

mv ~/Downloads/xdebug-xxx ~/開発ディレクトリ

cd ~/開発ディレクトリ/xdebug-xxx
```
/xdebug-xxx直下で実行

```
$ phpize  

 $ ./configure  
 
 $ make
```

modules ディレクトリに xdebug.so があることを確認

```
ls ~/開発ディレクトリ/xdebug-xxx/modules/

xdebug.so
```
### php.ini 設定
php.ini ありか

```
 $ php --ini
```
php.ini 最後尾に追記
```:/php.ini
[xdebug]
zend_extension={xdebug.so までのフルパス}
xdebug.mode=debug
xdebug.client_host=localhost
xdebug.client_port=9003
```

Xdebug が有効になっていることを確認
```
 $ php -m | grep xdebug
 
 xdebug
```
### VSCodeプラグイン
VSCode拡張機能 `php debug` インストール

.vscode/launch.json 作成


# 参考記事
https://doc4.ec-cube.net/quickstart/command_install
https://umebius.com/eccube/composer-not-installed-vendor-directory/
https://qiita.com/royal_straight_flush/items/c3ddc93a871a263487cf
https://qiita.com/fuwamaki/items/194c2a82bd6865f26045
rex0220 計算式プラグイン 計算対象のテーブル内項目を編集

rex0220 計算式プラグインで、計算対象のテーブル内項目を編集する例です。

# 概要

下記のように、番号の先頭に文字列を付加し、数値部分を編集可能にします。

- 番号の先頭にドロップダウンの値に応じて、文字列を付加
    - 未: "X-"
    - 済: "XY-"
- 番号の数値はマニュアル入力

![2024-07-29_17h24_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/1e29d744-0f17-2bfa-5f97-1189895b87fb.png)

# 操作例

![2024-07-29_17h30_21.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/0a7b13d6-80e5-7ce4-7ac8-b12edeff5951.gif)

# 計算式プラグイン設定

番号の計算式で番号を参照するため、循環参照を許可をチェックします。

SWITCH 関数で、ドロップダウンの値に応じて値をセットし、
REPLACERE 関数で番号から数値以外の文字を削除して連結します。

![2024-07-29_17h31_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/39a03ff0-17ec-db69-2d0b-accfd87bd7d8.png)

```.js
OPTION: 循環参照を許可

// テーブル.番号 SINGLE_LINE_TEXT (editable)
SWITCH(ドロップダウン,"未","X-","済","XY-","")&
REPLACERE(番号,"\D","g","")
```
非エンジニアのReact挑戦(大体2か月目)

大体1か月前の自分がこちら

https://qiita.com/NoritakaTaniguchi/items/9269bf13d30206765c61

## やったこと　と　感じたこと
・アプリから外部データベースへの接続
 　→ こういうのがやりたかった！自分が書いたコードが動いていて面白い
  
・ビルドからのFirebaseへのデプロイ
　 → なるほどWebアプリってこんな感じでアクセスできるようになってるのか！
  
・Makefileの作成
　 → 複数コマンド実行をまとめられて便利！ReadMeに書いておけばみんなも簡単に使えるかも
  
・Jestの導入
　 → 一番時間かかってしまった...ローカルのテスト通すまで黙々と2週間やり続けた。

・GithubActionsでのCI/CD
　 → 今までの手作業を自動でやってくれるようになり便利！ワークフローがぐるぐる回ってるのを祈るように見つめるの楽しい

## 気づき
・作業の時間を決めないで勢いつけてガッとやるのがすごく集中できました。
 継続させる勢い大事。

・2週間似たようなエラーを突破できなかったが、ヘルプ求めずに突破できたのは結構自信になりました。
 完全自力で突破したわけではなく、JISOUの環境やコーチング、
 先輩が残してくれていた記事のおかげでなんとかなりました。感謝です！
 私も誰かのためになる記事残さないとなとこの時は強く思いました。メモとか記事大事。
 Jestに関しては格闘した時間が長かったので理解度も深まったはず。
 でも2週間も作業止まってたら普通に聞いた方がいいと思います。
 
 ・全然わからなくてもやってみようの精神
  どんどん失敗していこうと思います。

## 成長
  ・日常的にエラー起こしすぎて大分慣れてきた
  ・あきらめるじゃなくて区切る、割り切るができるようになった

  来月はもっと前に進めているように精進します。

## 作ったもの
学習内容と時間を記録してくれるアプリです。

https://deploytest-cb257.web.app/

リポジトリがこちら。

https://github.com/T4NIGUCHI/studyLog2

## 今月書いた記事

https://qiita.com/NoritakaTaniguchi/items/bbd8d8cd26a8bb8106ae

https://qiita.com/NoritakaTaniguchi/items/f39bd9960fd22c99c230

https://qiita.com/NoritakaTaniguchi/items/b67c154411d08f767a5b

https://qiita.com/NoritakaTaniguchi/items/e4ffcfc61bd6f4d83799

# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからライン登録お願いします
https://projisou.jp

https://projisou.jp
Webサイト制作

Webサイト作り始めました！
**[Dogtype](https://dogtype.net/)**

~~まだHTTPS化していませんし(SSH証明書がなかなか発行されない)、~~ デザインも迷子ですが念願の自作サイト…！
ちなみに90%くらいpeppyのセンスに影響を受けています。

Webサイトを作っていて頻繁に思うのですが、JavaScriptって本当に大事ですね。
実装したい機能を全てLLM頼りで情けないったらないですわ。
今日JSの教材をやろうと思ったのですが、Webサイトのデザインをしていたら教材をしている時間がなくなってしまいました。

次回までに教材探しておきますかね…。
圧電サウンダの音量を上げる為に

はじめに
 素人電子工作
  先日LED PANELとPANELドライバ(ESP32系)のボードを買いました。
  ボードは良く出来ていて、素人の私でも不自由なく使えました。
  表示もセンサー類も不足ないです。
  ただ一点、サウンダ(圧電素子)があるのですが、3.3VでGPIOからダイレクト…
  流石に蚊の鳴くような音しかしません。
  これは少し困ったな～と思って…

 思いついたこと
  折角なので、電子回路を付加する事で改善出来ないか？
  と、思い、回路図を見るとサウンダに抵抗が平行に繋がるだけ。
  以前どこぞで「サウンダの音を大きくする」的記事を思い出し、検索。
  ＥＤＮのページを見つけて早速実験をしてみました。

  シンプルな回路で圧電トランスデューサーの音響出力を向上 - EDN
　https://www.edn.com/increase-piezoelectric-transducer-acoustic-output-with-a-simple-circuit/

 実験
  実験に際し、いくつかパーツを買いに近所のサトー電気へ。
  トランジスタよりMOSFETをチョイス。
  FETに2N7000が安かったです。
  ダイオードも1N4148が中国製の安いやつがありました。
  気になったのはインダクタのリアクタンスは音の大きさに影響するのか？なので、
  500μＨ・1mH・10mHのアキシャルリードタイプの物を買ってみました。
  こちらも中国製でお安く。
  サウンダ入れても千円でお釣りが来ます。
  一応FETのダンピング抵抗用やらその他細々した物も一緒に…。

  まずブレッドボードで実験。
  インダクタを変えつつ、オシレーターは手近にあったXR2206で1KHz前後が出る様に設定。
  周波数をテスターで測ってから実験！すると…うわ、でけー。ｗｗｗ
  実際軽く驚く程度には大きいです。電源電圧は3.3Vなのに、先程までの蚊の鳴くような音とは違い、
  明らかに明確に音が聞こえます。
  当方片耳の鼓膜が無いので、聴力はかなり問題があるのですが、それでも聞き取れる位には大きくなりました。
  これをdBで表現できればよいのですが…そしてオシロの画像を取っていないという。。。
  
 結果
  凄いアバウトな結果ですが、兎にも角にも大きくはなります。
  また、インダクタの値が大きい方が大きくなりました。
  ただし、500μHのインダクタは連続20秒も慣らすと、インダクタの加熱が半端ないです。
  これは回路図を見れば分かる通り、FETのRDon抵抗以外電源からほぼ無抵抗な為です。
  実際には10mHは数分鳴らしっぱなしでも問題なかったです。
  この差はインダクタの「等価直列抵抗(ESR)」が影響したようです。
  そのの為か？インダクタを大きくしても直線的に音が大きくはなりませんでした。

  聞いた感じ10mHが一番良く聞こえ、しかも連続使用でも加熱問題がないので採用。
  実際にはESRが各々12/21/68Ωと結構な差がありました。
  3.3Vとは言え、12Ωでは300mA近く流れるのでIIRで1W近く？！加熱する訳です。
  10秒足らずの鳴動でも人差し指温度計では熱すぎて触れない程でした。
  1mHでも1分は持ちません。やはり加熱が問題です。(計算では0.5W…流石にインダクタが焼き切れます)
  10mHは幸か不幸か、ESRが幸いして0.17W程度。もう少し抑えたくば直列に50Ω位の抵抗を挟むと良いかも。
  実際には2N7000のRDon抵抗、1N4148にも微量ながら抵抗分はあります。
  直値で図れませんでしたが、電流値を見るに50mAもあれば良い様です。
  音を慣らすのですからある程度の電力は許容と思いましたが、この程度で済むなら幸いです。
  今回の実験は「アバウト」を生かした結果になりました。
  回路図もEDNのままよりも、少し抵抗を入れた方が良いかも知れません。
  また、違うインダクタを使うと、ESRが低くリアクタンスが大きいと音が大きくなると思います。
  ですが、発熱には注意です。

  そんな実験でした。
#05　AWS(APIGateway/Lambda) + Serverless Framework + BrefでサーバレスなLaravel環境を構築してみる①

# はじめに
最近、サーバレスにLaravelを運用する環境を目にする機会がありました。
その際に利用されていた技術について備忘録として複数回に分けてこのブログにまとめていこうと思います。
今回は、BrefとServerless Frameworkに焦点をあて、PHP動作環境をAWSにデプロイしてみます。

# 1. 前提条件
AWSの各種サービスに対する基本的な知識、AWS CLI設定済み、npm/composerインストール済み

# 2. 動作環境
npm：9.6.1
composer：2.1.14
AWS CLI：2.5.5
Serverless Framework：3.2.81
Bref：1.7

# 3. 今回利用するツールに関して
### １. Brefとは
Brefとは、一言で言えばAWS LambdaでPHPを動作させるための各種設定を行うCLIで、OSSとして提供されています。
LambdaのランタイムにはPHPは存在せず、カスタムランタイムとして利用する必要があります。
カスタムランタイムとしてPHPをLambdaで利用するための各種設定などの煩わしい作業を簡単にしてくれます。
公式ドキュメント：https://bref.sh/docs/

### ２. Serverless Frameworkとは
AWS/GCP/Azureなどのクラウドサービスにおいてサーバレスなアプリケーションを簡単に開発、デプロイするためのNode.js製のフレームワーク。
サーバレス環境をコード化し、環境のセットアップやデプロイを自動化を行います。
公式ドキュメント：https://www.serverless.com/framework/docs

※AWSでのサーバレスアーキテクチャの自動化というとSAMがまず初めに頭に浮かびますが、
　BrefはSereveless Frameworkを利用したCLIであるためSAMは今回使用しません。

# 3. PHP動作環境をAWSにデプロイしてみる
Brefの公式ドキュメントにPHPアプリをLambdaで実行するための手順が記載されているので、
それに従ってPHPアプリをデプロイしてみます。
公式ドキュメント：https://bref.sh/docs/installation.html


## ① Serverless Frameworkのインストール

```terminal
npm install -g serverless
```

## ② Serverless Frameworkで利用するAWS CLIの認証情報を設定

```
serverless config credentials --provider aws --key <key> --secret <secret>
```

## ③ Brefのインストール

```terminal
composer require bref/bref
```

## ④ Brefの初期化
どのようなLambdaを作成するか問われるので、デフォルトの[Web application]でを選択します。

```terminal
vendor/bin/bref init

What kind of lambda do you want to create? (you will be able to add more functions later by editing `serverless.yml`) [Web application]:

 [0] Web application

 [1] Event-driven function


Creating index.php                                              

 [OK] index.php successfully created.                                          


Creating serverless.yml                                         

 [OK] serverless.yml successfully created.                                        

 [OK] Project initialized and ready to test or deploy. 
```

> Accept all the defaults by pressing "Enter". The following files will be created in your project:

> index.php contains the code of your application
> serverless.yml contains the configuration for deploying on AWS
出典：https://bref.sh/docs/first-steps.html#initializing-the-project

初期化を行うと、サンプルページ用のindex.phpファイルとAWSへのデプロイに関する設定ファイルが作成されます。

## ⑤ Serverless Frameworkを利用してPHPをデプロイ
デプロイを実行するとエンドポイントが表示されるので、アクセスするとサンプルページが表示されます。

```terminal
serverless deploy

Deploying app to stage dev (ap-northeast-1)

✔ Service deployed to stack app-dev (116s)

endpoint: ANY - https://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com **** ここにエンドポイントが表示されます。

functions:

 api: app-dev-api (980 kB)

Need a better logging experience than CloudWatch? Try our Dev Mode in console: run "serverless --console"
```

# 4. 備考
デプロイを実行することで、AWSのAPIGateway/Lambdaに加えてCloudformationとS3に各種設定が自動的に行われます。
AWS上にデプロイした環境は、Cloudformationで管理されているので、不要になった環境は以下のコマンドで自動的に削除することが可能です。

```terminal
serverless remove
```

# 最後に
今回は、PHP環境をサーバレスに構築してみましたが、非常に簡単に構築することができました。
次回は本題のLaravelアプリをLambdaにデプロイしてみようと思います。
#03 [Angular] Standalone components

## Introduction

Components declaration that we have learned is adding your components to the `imports` array in the `@NgModule` . It doesn't bother us when we just develop a TODO app or some small-scale project for study or mainly for **fun**. When having a large scale project, Angular's declaration can make the import list as long as you want. Or you **don't?** Maybe you can try the new staff from Angular 14, **standalone components**.

As the name they call "standalone", allow specifying components, directives or pipes independently without through the `@NgModule` and make life easier.

## Create Standalone components

### 1. Add decorator to exist component

To create a standalone component, simply add `standalone: true` to `@Component` decorator or you can run the following command to create a new standalone component.

```console
ng generate component [name] --standalone
```

### 2. Adopt standalone components to the existing application

It is very easy to apply standalone components to existing Angular applications. Using NgModule.imports and done.

```ts
@NgModule({
  //...
  imports: [StandaloneComponent]
  //...
})
```

### 3. Create a Standalone only application

Or you may want to use Standalone staff only in the new Angular application, Angular team provide `bootstrapApplication` API to meet your needs. You can pass providers to `bootstrapApplication` just like `NgModule-based` .

```ts
import {bootstrapApplication} from '@angular/platform-browser';
//...

bootstrapApplication(StandaloneComponent, {
  providers: [
    provideRouter([/* route */]),
    importProvidersFrom(TPLibrary.forRoot()),
    //...
  ]
});
```

Angular and third-party libraries have been updated to provide `provide` functions such as `provideRouter` for dependency injection configuration without NgModule. You can still use `importProvidersFrom` if a library only provides NgModule API.

---

Just a brief introduction to Angular standalone components and a memo for myself.

## Resource 
> Angular Official Site: [https://angular.io/guide/standalone-components](https://angular.io/guide/standalone-components)