OmniAICreator/Qiita-1.07M huggingface dataset:
Flask で Hello World

## プログラム

```py:hello.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
	str_out = '<h2>こんにちは!</h2>'
	str_out += '<p>Aug/15/2023</p>'
	return str_out

app.run(host='0.0.0.0')
```

## 実行

```bash
python hello.py
```

実行した時の様子

```text
$ python hello.py
 * Serving Flask app 'hello'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.1.6:5000
Press CTRL+C to quit
```

## クライアントでアクセス

[http://127.0.0.1:5000/](http://127.0.0.1:5000/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/15551be9-a8dc-8ce2-37a4-735be5c0ed55.png)


## 確認したバージョン

```text
$ flask --version
Python 3.12.3
Flask 3.0.2
Werkzeug 3.0.1
```
参照型とNULL代入について

## 変数を別の変数に入れたときに問題は起きた
まずは以下のコードを見ていただきたい。
よくあるシングルトンパターンの手法で作成したインスタンスである

```cs
public class User{
    private static User instance = null;
    public static User Instance{
    get{
        if(instance == null){
            instance = new User();
        }
        return instance;
    }
}
```

こちらのInstance変数を他クラス、GameManager.csなどから参照するときに、
`User.Instance`ってめんどいかもと思った私は、以下のように変数を変数に代入した。

``` cs
public class GameManager{
 private User user = User.Instance;
}
```

これでuserという短い変数名で呼び出せて簡単だね、と思っていた私。
参照型だからUser.Instanceに何か変更があっても見に行けるはずと思っていたが、

` User.Instance = nulll`を行っても、GameManager.userの値はnullにならなかった。 

おそらくここで起きているのは、
1. 実行時にGameManager.userにUser.Instanceの参照先が渡された。
2. User.InstanceをNULLにしたときにUser.Instanceの参照がどこも参照していないという状態になった
3. GameManger.userには参照先が残ったまま

になっているのが原因と考えられる。

以下の記事を参考にさせていただきました。「++c++;未確認飛行 C」様より
https://ufcpp.net/study/csharp/oo_reference.html#:~:text=C%23%20
>参照型の場合、「実体はどこか別の場所にあって、変数はそれを参照しているだけ」という状態になっています。 そして、元々の意味での null は「どこも参照していない」ということを表しています。

## 解決策
毎回、User.Instanceの参照先を取得するようにするか、
``` cs
public class GameManager{
 private User user => User.Instance;
}
```

もしくは
GameaManger.userへの変数の代入をやめておとなしくUser.Instanceを呼び出すかが簡潔な修正かなと



## まとめ
参照型の値をNULLにしても参照先を失うだけで、参照型の参照先のデータがNULLになるわけではない。
参照型変数のむやみな代入はやめよう。
という教訓を得ました。
【Ruby】Timeクラス　曜日の出力方法

# はじめに

自己学習の復習として投稿します。


### 何も使わず出力した時

```ruby
now = Time.new
puts now.wday
```

出力結果は、**0~7**　の数字で出力されます。



### 曜日で出力したい場合は？

```ruby
now = Time.new
week = ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日","土曜日"]
puts week[now.wday]
```

このように、曜日を配列で記述する必要があります。
基本的に出力される数字は日曜日から始まっている為、配列も日曜日から始めてます。
ERP導入コンサルのモヤモヤと問題提起

# はじめに

こんにちは、私は日本の某会社に勤めている会社員です。社会人初めてから一貫してERP導入コンサルタントとしてご飯を食べています。
ERP開発ベンダー側として1社の経験、他社製品ERPを導入するベンダーとして2社の経験がございます。

本日から、ERP導入コンサルとしてのモヤモヤと問題解決の一助になればと思い、Qiitaにて投稿を始めます。ERP導入コンサルが何にモヤモヤしているのかと、そのモヤモヤを解消するために何をしたいのかは後ほど記述します。

# 私の自己紹介
<dt>名前</dt><dd>FrogFish（略してFF）日訳：カエルアンコウ（アイコン参照）</dd>
<dt>年齢</dt><dd>30代</dd>
<dt>居住地</dt><dd>東京</dd>
<dt>休日の過ごし方</dt><dd>スキューバダイビング（ライセンス持っていて、よく伊豆で潜ってます、カエルアンコウはスキューバダイビングで出会い、一目ぼれ。かわいいですよね！！！）</dd>
<dt>職業</dt><dd>ERP導入コンサル（特にMicrosoft社のDynamics365）</dd>

# このブログでやりたいこと
私の自己紹介ができたので、早速このブログでやりたいことを発表します。

## ブログのターゲット
1\.情報システム部担当者
社内でD365検討を命じられて、ネットでD365 ERPでググったが英語のページとyoutube動画だけが見つかったものの業務が回るかどうかイマイチ分からず、社内への説明をしようにもできずに途方に暮れている __情報システム部担当者__ 

## 要約
D365標準機能でできることを私が今まで経験した具体的なビジネスケースをベースにして設定、運用例をご紹介します。

## モヤモヤ
世の中のD365に関連するドキュメントは正直わかりにくい。Microsoftが提供するドキュメントが英語なので一歩目のハードルが高い。日本語版も機械翻訳で訳したような不自然な日本語が並んでますし。

じゃ、分かりにくさをD365を説明する営業やコンサルが解消できればいいのですが、説明できてないケースがあまりにも多い。 ~~説明が下手くそ。~~ D365にプリセットされたContosoのデータを使って標準機能をちょっと見せる。その結果、「D365ってよーわからんしうちのビジネスに合致するかわからん」となるケースが散見されます。
ちゃんと説明すればもっと食いついてくれるのにというケースを多々見てきました。

### ブログでやりたいこと
本ブログではビジネスケースの設定を丁寧に行います。このブログ内ではビジネスケースをベースとしたD365標準機能の設定例、運用例をご案内します。ビジネスのバックグラウンドを元にどのようにマスタに設定できるか、どのように機能を動かせるかをご案内します。

### このブログの目指す姿
世の中のD365営業やコンサルが説明できなかった「うちのビジネスで動かせるの？」を解消して、D365を「うちのビジネスできそうだよ」と社内で説明していただきたいです。

その先に、ERPという商材の中でSAPやOracleに負けがちなD365が選択肢の1つとして挙がればこれ以上の喜びはありません。
【Docker】MySQLにログインした時に、エラーが発生する。

Dockerをインストールした後、PHPMyAdminにログインするとエラーが発生したため対処法をメモする。

## エラー内容
PHPMyAdminにログインした後のエラーは以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3323019/c11f79d3-60fc-5fee-2a90-1a9331ef4acd.png)

## 原因
docker-compose.ymlの以下の記述が間違っていた。
今回は`MYSQL_ROOT_PASSWORD`が違っており、かつ
`MYSQL_USER`と`MYSQL_PASSWORD`は既にあるものを設定していたため、エラーが出た。
```docker-compose.yml
environment:
- MYSQL_ROOT_PASSWORD=root  #→rootユーザーのパスワードに変更
- MYSQL_USER=root  #→root以外のユーザー名に変更
- MYSQL_PASSWORD=rootユーザーのパスワード  #→任意のパスワードに変更
```

＜メモ＞
`MYSQL_ROOT_PASSWORD`…rootユーザーのパスワードを設定しないといけない。
`MYSQL_USER`…設定すると自動で新しいユーザーを作成する。
`MYSQL_PASSWORD`…設定すると自動で新しいパスワードを作成する。

## 参考サイト
DockerでMySQLサーバーを構築するときの環境変数の設定
https://qiita.com/pachi-dragon/items/8d248c518eb25cd9cf68
【AWS】Amplify CLIの初期設定



# 【AWS】Amplify CLIの初期設定

Amplifyコマンドを使用するために、@aws-amplify/cliをインストールします。

```
npm install -g @aws-amplify/cli
```


## 1. AWSにサインイン
自動でAWSのサインイン画面が表示されます。サインイン後、コンソール画面に戻りエンターを押して設定を続けます。
```
amplify configure
```

## 2. リージョン設定
以下の質問をされるので回答する。(質問内容は、変わったり増えたりする可能性があります。)

使用するリージョン
```
Specify the AWS Region
? region: ap-northeast-1(東京リージョン)
```

新規作成するIAMユーザー名
(新規となっていますが、既存のIAMユーザー名を指定することも可能)
```
Specify the username of the new IAM user:
? user name:  <任意のユーザー名>
```

ユーザー名を入力すると、自動でIAMユーザー作成画面が表示されます。

## 3.プロファイル設定

```
Enter the access key of the newly created user:
? accessKeyId:  <アクセスキー>
? secretAccessKey:  <シークレットアクセスキー>
```

プロファイル名
任意のプロファイル名を入力します。
```
? Profile Name:  <任意のプロファイル名>
```


これでAWSの認証情報が入力された設定ファイル(configとcredentials)が作成されます。
Macの場合以下ディレクトリに作成されます。(隠しフォルダになっています。)
/Users/<ユーザー名>/.aws/

<br><br>
最後まで読んでいただき、ありがとうございました。
#0016 【解決】ModuleNotFoundError: No module named 'skimage'

### 入力
```
pip install skimage
```

### エラーメッセージ
```
ModuleNotFoundError: No module named 'skimage'
```

### 解決方法
- import名は`skimage`はだが、パッケージ名は`scikit-image`のため注意する。
```
# python環境へのインストール
pip install scikit-image

# インポート
import skimage
from skimage import data

camera = data.camera()

print(type(camera)) 
>>> <class 'numpy.ndarray'>

print(camera.shape)
>>> (512, 512)
```
BigQueryでQUALIFYを使う時の注意点

## QUALIFY
BigQueryで利用可能なSQL記法の一つに「QUALIFY」というものがあります。

https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#qualify_clause

これはWHERE句とは異なり、<b>ウィンドウ関数</b>で結果を絞り込むことができるため便利なシーンがあります。

## ユースケース

公開データセットのsampleを使って、Githubのtwitter organizationに属するレポジトリの中で最初にマージされたPRのタイトルを取得するケースを例に考えてみます(今はtwitterではなくXですが...)。

### QUALIFYを使わないケース

```sql
SELECT
  * EXCEPT(merge_order)
FROM
(
  SELECT
    repository.name,
    payload.pull_request.title,
    payload.pull_request.merged_at,
    ROW_NUMBER() OVER(PARTITION BY repository.name ORDER BY payload.pull_request.merged_at) merge_order
  FROM
    bigquery-public-data.samples.github_nested
  WHERE
    repository.organization = "twitter"
    AND payload.pull_request.title IS NOT NULL
    AND payload.pull_request.merged_at IS NOT NULL
)
WHERE
  merge_order = 1
```

### QUALIFYを使うケース

```sql
SELECT
  repository.name,
  payload.pull_request.title,
  payload.pull_request.merged_at,
FROM
  bigquery-public-data.samples.github_nested
WHERE
  repository.organization = "twitter"
  AND payload.pull_request.title IS NOT NULL
  AND payload.pull_request.merged_at IS NOT NULL
QUALIFY
  ROW_NUMBER() OVER(PARTITION BY repository.name ORDER BY payload.pull_request.merged_at) = 1
```

上記のように、QUALIFYを使うことにより、
- サブクエリの削減
- 不要カラムの削減(EXCEPTで除外しなくていい)

の2つが実現できています。

## 注意点

というふうに便利なQUALIFYですが、これを含んだViewをLooker Studioでデータソースに指定する場合に注意が必要です。


```sql
WITH twitter_org AS (
    SELECT
      repository.name,
      payload.pull_request.title,
      payload.pull_request.merged_at,
    FROM
      bigquery-public-data.samples.github_nested
    WHERE
      repository.organization = "twitter"
      AND payload.pull_request.title IS NOT NULL
      AND payload.pull_request.merged_at IS NOT NULL
)
SELECT
  *
FROM
  twitter_org
QUALIFY
  ROW_NUMBER() OVER(PARTITION BY name ORDER BY merged_at) = 1
```

というクエリは実行できますが。これをViewとして保存して、Looker Studioのデータソースに組み込むとエラーになります。

![スクリーンショット 2023-08-15 12.21.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13766/65183921-88f0-a26c-8dbf-a569874e3e11.png)

ロギングを見ても特に情報がなく、原因が分かりづらいです。

調べた結果
<b>WHERE句無しでQUALIFYを使うとエラーになる</b>ようです。

そのため、下記のようにすれば回避できます。

```sql
WITH twitter_org AS (
    SELECT
      repository.name,
      payload.pull_request.title,
      payload.pull_request.merged_at,
    FROM
      bigquery-public-data.samples.github_nested
    WHERE
      repository.organization = "twitter"
      AND payload.pull_request.title IS NOT NULL
      AND payload.pull_request.merged_at IS NOT NULL
)
SELECT
  *
FROM
  twitter_org
-- 回避用WHERE句
WHERE
  true
QUALIFY
  ROW_NUMBER() OVER(PARTITION BY name ORDER BY merged_at) = 1
```

## ぼやき
同じ悩みを抱えてる人はいるみたいですがなかなか対応されない様子。
https://support.google.com/looker-studio/thread/172699750/bigquery-qualify-function-is-not-supported-by-data-studio?hl=en
https://issuetracker.google.com/issues/250581514
海外取引に欠かせない為替レートを移動中でも手軽に確認するLINE Bot作成


## Make? LINE Bot?
こんにちは。デジタルには全く疎い小売業従事者です
会社の研修にてデジタルで業務改善すべくまだ見ぬ新世界へと飛び込んで来ました
せっかく覚えたLINEBotなので実務で使えるものにしたい。
さて何にしようか
### 移動中でもサクッと為替レートを確認したい
海外取引先の付き合いがある業務のため日々の為替レートは需要指標
手軽にLINEで確認できたら助かるかなということで今回のチャレンジは為替レートをLINEBotで確認しようというものです
### 今回使用したツール
- LINE
  https://www.linebiz.com/jp/service/line-official-account/
- Make
https://www.make.com/en
### 実装開始
- Makeシナリオはこちらです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485813/bdaf4162-46d8-95cd-8156-3978529d3cdd.png)

- 使用APIはこちらです
- https://www.frankfurter.app/docs/
### Makeでの実施手順
- LINEdevelopersにてアカウントの作成と応答設定、Makeでwatcheventsを使ってLINEの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485813/b19bdbcf-f726-8e6d-f19d-1273cdda3a12.png)


- 次にMakeでHTTPの設定とJSONの設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485813/90fe7793-7944-4dae-68a1-4889caebc34a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485813/dbbaeb93-7f6b-c6bf-90e4-5af427eefd12.png)

- 最後にMakeのLINE send a reply Massage で応答するメッセージを設定して完了

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485813/39870a7f-98f8-f5e8-6be3-d8c2e5e0e2c7.png)
    - 無事に応答が来ました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3485813/fd14b002-2dbb-8005-13cc-d7fda7b9658f.png)

動作の様子がこちらです
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">JPYと入れると為替レートを返す<br>LINEBotの動作 <a href="https://t.co/lmcd0Pa20p">https://t.co/lmcd0Pa20p</a> <a href="https://t.co/S36xFgEvpZ">pic.twitter.com/S36xFgEvpZ</a></p>&mdash; たかち (@wi80L3bJzscufZJ) <a href="https://twitter.com/wi80L3bJzscufZJ/status/1693067368090697868?ref_src=twsrc%5Etfw">August 20, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 実際に作ってみて
日本円を指定してレートが返ってくるやりとりはサイトやアプリにアクセスして
確認するのと手間があまり変わらないため効率化とは言えるものではありませんでした
同僚からの評価も専用サイトで確認した方が確実と言われました

### これからの目標

今回は欧州銀行のレートを使って実装したのでユーロベースなので、やはり米ドルレートの表示にチャレンジしたいと思います。
また、ほかの通貨（元など）やエラーのフィルター設定なども今後取り組みたいと思います
実現したらまた投稿したいと思います

ありがとうございました
【C#】ReactiveProperty<T>型のプロパティを持つクラスの初期化方法

近代のMVVMパターンを採用しているプロジェクト（WPF, .NET MAUI etc.）では、ReactivePropertyを使うことが多いと思います。

特にクラスのプロパティとしてReactiveProperty<T>型やReactivePropertySlim<T>型を使うケースが大半たと思いますが、そのようなクラスをnewする時に困ったことがあります。

```csharp

class BalanceEntry
{
     public ReactivePropertySlim<Guid> Id { get; } = new();
     public ReactivePropertySlim<DateTime> DateTime { get; } = new();
     public ReactivePropertySlim<bool> IsPayment { get; } = new();
     public ReactivePropertySlim<long> Value { get; } = new();
     public ReactivePropertySlim<string> Summary { get; } = new();
     public ReactivePropertySlim<Guid?> PaymentMethodId { get; } = new();
     public ReactivePropertySlim<bool> IsBudget { get; } = new();
}

```

（ReactivePropertySlim<T>はReactiveProperty<T>の軽量版クラスです。）

上記のようなクラス定義の時に、このクラスをnewする時に以下のように書きたくなります。

```csharp
var newEntry = new BalanceEntry
{
    Id.Value = ...,
    DateTime.Value = ...,
    IsBudget.Value = ...,
    IsPayment.Value = ...,
    Value.Value = ...,
    Summary.Value = ...,
    PaymentMethodId.Value = ...,
};
```

しかし、これではコンパイルエラーが出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/ac0a4952-d5fe-6580-176a-562b6253cc50.png)

詳しく見てみると、「[CS0747: 初期化子のメンバー宣言子が無効です](https://learn.microsoft.com/ja-jp/dotnet/csharp/misc/cs0747)」と出ていますね。

そう、上記の書き方ではダメなのです。。。

ではどう書けばいいかというと、下記のようになります。

```csharp
var newEntry = new BalanceEntry
{
    Id =
    {
        Value = ...,
    },
    DateTime =
    {
        Value = ...,
    },
    IsBudget =
    {
        Value = ...,
    },
    IsPayment =
    {
        Value = ...,
    },
    Value =
    {
        Value = ...,
    },
    Summary =
    {
        Value = ...,
    },
    PaymentMethodId =
    {
        Value = ...,
    }
};
```

具体的にすると、このようになります。

※この例だとValue の右辺はId以外はReactiveProperty型です。

```csharp
var newEntry = new BalanceEntry
{
    Id =
    {
        Value = Guid.NewGuid()
    },
    DateTime =
    {
        Value = DateTime.Value.Add(TimeSpan.Value)
    },
    IsBudget =
    {
        Value = IsBudget.Value
    },
    IsPayment =
    {
        Value = IsOn.Value
    },
    Value =
    {
        Value = Amount.Value
    },
    Summary =
    {
        Value = Summary.Value
    },
    PaymentMethodId =
    {
        Value = PaymentMethod.Value?.Id.Value
    }
};
```

## あとがき

ReactiveProperty超便利❗❗❗❗❗❗❗❗
SMBってなに？をセキュリティ的に考えてみた

SMBってなに？

ってそんなのちょっと調べればわかりますよね
「マイクロソフトのファイル共有プロトコル」…です？

あれ？あってるかな？
これ、Try Hack Meでは「サーバー メッセージ ブロック プロトコル (SMB プロトコル) は、ネットワーク上のファイル、プリンター、シリアル ポート、その他のリソースへのアクセスを共有するために使用されるクライアント/サーバー通信プロトコルです。また、プロセス間通信のためのトランザクション プロトコルを伝送することもできます。長年にわたり、SMB は主に Windows コンピュータに接続するために使用されてきましたが、Linux や macOS などの他のほとんどのシステムにも、SMB リソースに接続するためのクライアント コンポーネントが含まれています。」


https://www.techtarget.com/searchnetworking/definition/Server-Message-Block-Protocol

という記述になってまして、よく考えたらファイル共有プロトコル、という言い方では狭かったんだなと。
正しくは上記の記述になるわけで。
よく考えたら、プリンター共有とかでも使われてますよね？

https://support.microsoft.com/ja-jp/windows/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF-%E3%83%97%E3%83%AA%E3%83%B3%E3%82%BF%E3%83%BC%E3%82%92%E5%85%B1%E6%9C%89%E3%81%99%E3%82%8B-c9a152b5-59f3-b6f3-c99f-f39e5bf664c3

この記事も書き方がよくなくて（マイクロソフト系直訳）「ネットワーク上でサーバーのプリンターを共有する」という書き方が正しいですよね。

セキュリティ分野てこの手の「あいまいなまま流れてしまう言葉」多くて
共有するときに「SMBの脆弱性が…」といったときに、
ファイル共有の脆弱性なのか、プリンター共有した場合に発生する脆弱性なのかで
対処も大きく変わってしまうので、一つ一の言葉の定義をはっきりと
認識しないとだめだなぁ

と思いました
VS CodeでもShift+Shiftでコマンドパレットを呼び出したい

## 先に結論だけ

VSCodeでも、`Shift+Shift`のような同一キー連打をショートカットに設定できます。GUIでは設定できないので、keybindings.jsonを書き換えてください。

## はじめに

この記事は、Visual Studio Codeで同一モディファイキーの連打をショートカットキーに割り当てる方法を解説、共有するためのものです。

### 想定する環境

Visual Studio Code v1.81.1 

:::note warn
バージョンが変わると、記事の内容がそのまま適用できないかもしれません。記事を読む前に、お手元の環境をご確認ください。
:::

### 想定する読者

Visual Studio Codeをすでに使用しているユーザー

:::note warn
この記事はVisual Studio Codeそのものの解説や、インストールガイドは含みません。
:::


## 同一キー連打ショートカット

IntelliJ IDEA系統のIDEでは、Shiftキーの2回連打で[どこでも検索 (Search Everywhere)](https://pleiades.io/help/idea/searching-everywhere.html)が呼び出せます。この機能はコマンド、ファイル名、クラスを横断してインクリメンタルサーチします。

## 同一キー連打ショートカットをVSCodeで設定する

どこでも検索の使用感が良かったため、このショートカットをVisual Studio Codeにも持ち込めないか検討してみました。同一キー連打ショートカットはGUIからでは設定できませんが、設定ファイルを編集すれば有効化できます。

![keybindings.jsonを開く](https://www.evernote.com/shard/s9/sh/29bc894d-ec2c-4390-b274-43d8c0c688ea/IGhAg2LuafwpWTbpH8moN4nm_BbMWJTRjAVe2QLeNj6A0G7t6Jh-fFLX2w/deep/0/image.png)

Visual Studio Codeのコマンドパレットから「Open Keyborard Shortcuts(JSON)」を検索して開きます。`keybindings.json`という設定ファイルがエディターウィンドウで開かれるので、ここにキーボードショートカットの設定を書き込みます。

![keybinding.jsonのフィールドを編集する](https://www.evernote.com/shard/s9/sh/846a695c-f3d3-48e1-9dcb-8c6c57d54f9a/EecIK5jMrSdQ6NDWV9XmkYoY5YH8gtbx3Qi3Tl2rHZPusaKbwPwoQKVAJQ/deep/0/image.png)

同一キー連打のショートカットは`モディファイキー モディファイキー`とスペース区切りで記述します。AltやCtrlなども設定できます。

これでコマンドパレットが片手で呼び出せるようになりました。みなさんも使用頻度の高い操作に連打ショートカットを割り当ててみてください。

## 参考記事

https://github.com/microsoft/vscode/issues/142465?utm_source=pocket_saves#issuecomment-1433732673
5分で作る: Flask(Python)とHTMLを使ったChatGPTテキスト要約ツール

HTMLとPython (Flask) を使用して要約アプリを作成する工程をまとめたものです

1  必要なライブラリをインストール。
```
pip install flask openai
```

2 HTMLの作成 (templates/index.html)
```
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>テキスト要約</title>
</head>
<body>
    <h1>テキストを要約します</h1>

    <form action="/" method="post">
        <textarea name="text_input" rows="5" cols="50"></textarea><br>
        <input type="submit" value="要約">
    </form>

    <h2>要約結果:</h2>
    <p>{{ summary }}</p>
</body>
</html>

```

3 Pythonコードの作成 (app.py)
```
from flask import Flask, render_template, request
import openai

openai.api_key = ''

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    summary = ""
    if request.method == 'POST':
        text = request.form['text_input']
        response = openai.ChatCompletion.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "あなたは優秀な要約をする人です。30文字以内で要約してください"},
                {"role": "user", "content": text},
            ]
        )
        summary = response['choices'][0]['message']['content']
    return render_template('index.html', summary=summary)

if __name__ == '__main__':
    app.run(debug=True)

```
4 アプリの実行:ターミナルで以下のコマンドを入力して、環境変数を設定。

```
$env:FLASK_APP = "app.py"
$env:FLASK_ENV = "development"
flask run
```

簡単！！
Nucleo F303K8 TIMERお勉強 w/STM32CubeIDE

基本的な TIM6 を試します。

# One Pulse Mode 1回きり

## ioc設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/c367430a-276a-f2ca-96ca-7448b97a9a75.png)

Activated チェック
One Pulse Mode チェック

1周期 1秒にしてみます。クロックが 8MHz なので，プリスケールをまずは 8,000 そうすれば 1msec おきにカウンターが変わるはずです。
Counter Period 1000 = 8MHz / 8,000

auto-reload preload を Enable にします。

```main.c
  /* USER CODE BEGIN 2 */

  HAL_TIM_Base_Start(&htim6);

  uint32_t t0=TIM6->CNT;
  HAL_Delay(100);
  uint32_t t1=TIM6->CNT;
  HAL_Delay(100);
  uint32_t t2=TIM6->CNT;

  /* USER CODE END 2 */
```

`HAL_Delay(100);` で 100msecごとにカウンター値 `CNT` を変数に保存しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/d14ba4c5-75dd-bb98-7fcf-4bf4a2701491.png)

## 再スタートする

停止したあと CEN フラグをセットします。CR1 レジスタの最初のビットです。

```main.c
  TIM6->CR1 = ( TIM6->CR1 ) | 1; // set CEN means restart
```

## 停止したことを知る

SRレジスタにある UIF フラグがセットされるのですが，普通に HAL でスタートさせるとセットした状態になるようです。あらかじめリセットしておきます。

```main.c
  /* USER CODE BEGIN 2 */

  TIM6->SR = (TIM6->SR) & 0xfffffffe; // clear UIF
  HAL_TIM_Base_Start(&htim6);

  HAL_Delay(100);
  uint32_t f0=(TIM6->SR) & 1; // UIF

  HAL_Delay(1000); // TIM6 finished.
  uint32_t f1=(TIM6->SR) & 1; // UIF

  TIM6->CR1 = ( TIM6->CR1 ) | 1; // set CEN means restart

  HAL_Delay(200);
  uint32_t f2=(TIM6->SR) & 1; // UIF

  /* USER CODE END 2 */
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/9eaeef75-7526-2556-84ba-a1acb6b282fa.png)

2回目はUIFをリセットせずスタートしたので，セットした状態になってますね。

# 繰り返すモード (One Pulse Mode = OFF)

```main.c
  /* USER CODE BEGIN 2 */

  TIM6->SR = (TIM6->SR) & 0xfffffffe; // clear UIF
  HAL_TIM_Base_Start(&htim6);

  HAL_Delay(100);
  uint32_t f0=(TIM6->SR) & 1; // UIF
  uint32_t c0=TIM6->CNT;

  HAL_Delay(1000); // TIM6 finished.

  HAL_Delay(50);
  uint32_t f1=(TIM6->SR) & 1; // UIF
  uint32_t c1=TIM6->CNT;

  /* USER CODE END 2 */
```

今度は自動でリスタートしていますね。2回目のCNT ≒ 150 ( = 100 + 1000 + 50 - 1000 )

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/92796691-e022-f48b-a7a6-3213c0529fda.png)

UIFを予めクリアしておかないといけないのは One Pulse Mode と同じでした。

## タイマー割り込みを併用する

こちらの記事と同じですね。ありがとうございます。

- https://qiita.com/toshidln/items/1fb9f0ac67ff97895185

ioc TIM6 は DACのトリガーにもなれますので少し文言が違いますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/3cb165d4-c4bb-649c-0fb4-eb751987dc54.png)

定番のLチカですね。

```main.c
/* USER CODE BEGIN 0 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){

    if(htim == &htim6) {
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
        }
}
/* USER CODE END 0 */
```

```main.c
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim6);
  /* USER CODE END 2 */
```

あっけないほど簡単です。

デバッガで止めてみると... 割り込みハンドラが呼ばれているときに UIF がクリアされているようです。

## 周期を変える

ARRレジスタを変更します。動いているときに強制的に変えていいかどうか RM0316 にはズバリ書いていないようですが，とにかく動いています。LEDのチカチカが速くなります。

```main.c
  /* USER CODE BEGIN 2 */

  HAL_TIM_Base_Start_IT(&htim6);

  HAL_Delay(2000);
  TIM6->ARR = 200; // Auto reload = 200;

  /* USER CODE END 2 */
```
Raspberry Pi で I²C EEPROM (24LCxxx) の読み書き

Pythonのsmbus2ライブラリで24LC512の読み書きができました。 smbusじゃなくて[smbus2](https://pypi.org/project/smbus2/)なのがミソです。

## ハマりポイント
　smbusにある関数では24LCxxxの通信フォーマットと合わないのです。
　write系の関数とread系の関数は完全に分離されていて、それぞれStart ConditionとStop Conditionで閉じているっぽいです。　24LCxxxのデータシートをみると、EEPROMからデータを読み込む際、アドレス上位バイト、アドレス下位バイトをマスターから送信後、Repeated Startを発行してからEEPROMからデータが送られてきます。　この動作に対応する関数がsmbusにはありません。
![スクリーンショット 2023-08-15 111341.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1570746/3e10d876-0195-cdcf-6e37-731f5dc0ceef.png)
図 : [データシート](https://akizukidenshi.com/download/24fc512-IP.pdf)より

## 解決策
smbusをsmbus2に変更し、i2c_rdwr関数を使用しました。 これ↓はページ書き込み/読み込みを実行するサンプルです。

```python:m24LCxxx.py
from smbus2 import SMBus, i2c_msg

ADDR = 0x50  # A0, A1, A2 -> Low
PAGE_SIZE = 128
xxx = 512  # 24LCxxx


def read_n_bytes(bus, address, n):
    # EEPROMからnバイト読み込み
    w = i2c_msg.write(ADDR, [address>>8, address&0x00ff])  # [アドレス上位, アドレス下位]
    r = i2c_msg.read(ADDR, n)
    bus.i2c_rdwr(w, r)  # 実行
    return list(r)

def write_page(bus, page, data):
    # EEPROMにページ書き込み
    assert len(data) <= PAGE_SIZE
    address = page*PAGE_SIZE
    w = i2c_msg.write(ADDR, [address>>8, address&0x00ff, *data])
    bus.i2c_rdwr(w)
    return

if __name__ == "__main__":
    i2c = SMBus(1)
    i2c.pec = 1

    #write_page(i2c, 0, [0xff]*PAGE_SIZE)  # ページ0を0xffで満たす

    for i in range(xxx//8*1024//16):  # i : 記憶領域全体を16バイトごとに区切った時の先頭アドレス
        line = read_n_bytes(i2c, i*16, 16)  # 16バイト読み込み

        # 16バイトずつ改行して表示
        for n in line:
            print("{:02X} ".format(n), end="")

        print()

    i2c.close()

```

## 解説
i2c_msg.read / i2c_msg.writeで処理を登録して、bus.i2c_rdwrで一気に実行する感じだと思います（たぶん）。
Leetcode 1492. The kth Factor of n

https://leetcode.com/problems/the-kth-factor-of-n/description/?envType=study-plan-v2&envId=amazon-spring-23-high-frequency

# アプローチ
- List

```java
class Solution {
    public int kthFactor(int n, int k) {
        ArrayList<Integer> a = new ArrayList<>();

        for (int i = 1; i <= n; i++) {
            if (n % i == 0) {
                a.add(i);
            }
        }
        if (a.size() < k) {
            return -1;
        }
        return a.get(k - 1);
    }
}
```
docker-compose  up -d?  build?

Dockerを使って環境構築している時に、
`docker-compose up　-d`　コマンド
`docker-compose build` 　コマンド
どちらを実行するか分からないことが多かったので、
調べたことをここにアウトプットしておきます。

# 前提
Dockerfile内のimageを参考にし、docker-compose.ymlで構築します。

# 各種ファイルの変更時の反映について


docker-compose.yml の内容を変更した場合
イメージ：再構築の必要なし：
コンテナ：再構築の必要あり：`docker-compose up　-d`

Dockerfile の内容を変更した場合
イメージ：再構築の必要あり：`docker-compose build`
コンテナ：再構築の必要あり：`docker-compose up　-d`

ミドルウェアなどの設定の内容を変更した場合
イメージ：再構築の必要あり：`docker-compose build`
コンテナ：再構築の必要あり：`docker-compose up　-d`

# docker-compose up -d　の　-d　について
ちなみに`docker-compose up　-d`についている -d オプションは、detachedのことです。

Docker Composeファイル（通常は docker-compose.yml）に定義されたサービス（コンテナ）を起動しますが、デフォルトではターミナルにログを表示します。

しかし、-d オプションを使用することで、コンテナをバックグラウンドで起動し、ログの表示を行わずにコントロールをターミナルに返します。

~~~
docker-compose up　-d
~~~
このコマンドを使うことで、Docker Composeファイルに定義された全てのサービスがバックグラウンドで起動され、コンテナのログは表示されません。

* メリット
この方法でコンテナを起動することで、ターミナルをブロックすることなく他の作業を続けることができます。

# docker-compose up --build
初回の`docker-compose up`はbuildも同時に行なってくれますが、
（↑改めて勉強になりました）

2回目からはbuildは行われません。

どちらも実行したいときには、上記のようにbuildしてからupでももちろん問題ないですが、

`docker-compose up --build`

コマンドを使えば、同時に実行できるので是非活用してみてください。

# 参考
https://laraweb.net/environment/8751/
TechStreamのコース紹介

フリーランスでフロントエンドのエンジニアをしながら、[TechStream](https://protech-rho.vercel.app/)というプロダクトを個人開発しております、かいです！
今回はTechStreamのコース紹介について書いていきます。

### TechStreamとは？
[TechStream](https://protech-rho.vercel.app/)は、「誰よりも早く、エンジニアへ」というコンセプトの元に発足されたプログラミングの動画プラットフォームです。未経験からエンジニアへ費用をなるべく抑えて転職するためのサポートをいたします。


![tekusuto.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475205/948ddc5b-0ed2-cabc-9a0f-9239dcb9ea87.gif)

[リンク](https://protech-rho.vercel.app/)はこちらから☟

https://protech-rho.vercel.app

特徴は以下の3点です。

- 安さ
    - 通常の3万円/月のところ、一番安いコースで今なら実質3,000円/月！
    - プログラミングスクールの約1/100の料金で学ぶことができます。

- 現役フリーランスエンジニアによる手厚いサポート
    - ProgateやRailsチュートリアルは一人での学習だが、TechStreamでは個別のメンターサポート（私です。笑）が受けることができます。
    - 面接官の経験もある専任アドバイザーがプログラミングだけでなく、キャリア相談に乗ることも可能です。

- コミュニティ
    - 他のメンバーとの交流も可能です！一人ではなくみんなで未経験からエンジニアへの転職を目指しましょう！

### TechStreamの特徴
- 5分動画であるため、短い時間で学ぶことができます！
- 初心者も学ぶことができます！
    - 学校でPythonやCをやって挫折した人
    - Progate終わったけど正直いまいち理解しきれなかったという人

#### コース全体
1. コース紹介
2. Rubyとは
3. 環境構築
4. プログラムの基本構造
5. プログラムの実行
6. 変数とは
7. オブジェクトとは
8. 配列とは
9. 演算子とは
10. 条件分岐
11. 繰り返し処理
12. メソッドとは
13. クラスとは
14. Sinatraを使ってみよう
15. ChatGPTを使おう
16. ERBテンプレートを使おう
17. cssでスタイルを整えよう




#### 最後に
- プログラミングとは英語と算数でロジックを組むとうごく、という簡単なものです。
- 大学受験で勉強した程度の英語力と、今の仕事でやられているであろうロジカルシンキングの癖があれば習得することは1,000時間かければ誰でもできます。

![tekusuto.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3475205/948ddc5b-0ed2-cabc-9a0f-9239dcb9ea87.gif)

[リンク](https://protech-rho.vercel.app/)はこちらから☟

https://protech-rho.vercel.app


楽しいプログラミングライフをお楽しみください！
metabase&mysqlの環境でgroup_concatの文字数制限をどうにかする方法

# mysqlのgroup_concatにまつわる制限
mysqlには集合関数でgroup_concatという任意のセパレーターで文字列を集計できるという便利な関数があります。
ただしこの関数には結合後の文字数が制限されており、デフォルトの1024文字を超えさせたい場合には、my.cnfでDBの設定を変えるか、セッション内で`SET SESSION group_concat_max_len = 4194304;` と入れるようにして制限を解除する必要があります。

https://dev.mysql.com/doc/refman/8.0/ja/aggregate-functions.html#function_group-concat:~:text=%E7%B5%90%E6%9E%9C%E3%81%AF%E3%80%81group_concat_max_len%20%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E5%A4%89%E6%95%B0%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%95%E3%82%8C%E3%81%9F%E6%9C%80%E5%A4%A7%E9%95%B7%E3%81%BE%E3%81%A7%E5%88%87%E3%82%8A%E6%8D%A8%E3%81%A6%E3%82%89%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82%E3%81%9D%E3%81%AE%E5%A4%89%E6%95%B0%E3%81%AE%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E5%80%A4%E3%81%AF%201024%20%E3%81%A7%E3%81%99%E3%80%82

# metabaseは複数ステートメントのSQL実行をサポートしていない。

以下のIssueで管理されていますが、6年以上Openでおそらく今後もサポートされなさそうな状態です。
https://github.com/metabase/metabase/issues/4050

# ではどうするか。

そして、GROUP_CONCATの列が尻切れになる問題の対処が必要になったらどうするか。

## 大前提

* my.cnfで対応できるならばそれで対応すべき。

## JDBCへのパラメーターで対応する。

前述のIssueで取り上げられている対応ですが、metabaseのDB接続設定の高度な設定でJDBCパラメーターを設定することで対応ができます。

https://github.com/metabase/metabase/issues/4050#issuecomment-927185845
https://stackoverflow.com/questions/26425045/how-to-pass-session-variables-in-jdbc-url-properly

`sessionVariables=group_concat_max_len=4194304`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89777/38d9ec14-21e2-2abf-b538-2a9391374d25.png)

無論全てのクエリ実行に影響するので、レスポンスの影響など加味する必要はありますが、これで解決です。
ubuntu環境でコマンドラインから画面録画をするには`recordmydesktop`を使えば良さそうという備忘メモ


ubuntu環境でコマンドラインから画面録画をするには`recordmydesktop`を使えば良さそうという備忘メモ

リンク
> https://over80.hatenadiary.jp/entry/20080802/1217693705
> https://github.com/Enselic/recordmydesktop

インストール

```
sudo apt-get install recordmydesktop
```

以下のように起動して使う

```shell
# record開始
recordmydesktop output.ogg
# record停止
(ctrl+c によるSIGINTで停止)
```

コマンドラインから実行する場合は以下のようにすれば良さそう

```shell
# record開始
recordmydesktop output.ogg &
PROCESS_ID=$!

#(何かの処理)

# record停止
# ctrl+c によるSIGINTで停止
kill -s SIGINT ${PROCESS_ID}
# (録画処理が完了するまでしばらく待つ)
wait ${PROCESS_ID}
```

# 参考

https://over80.hatenadiary.jp/entry/20080802/1217693705

https://github.com/Enselic/recordmydesktop
【ちょっと便利な小技_part 2】Visual Studio Codeでflutter開発

# 特定のWidgetのみを消す方法について
特定のWidgetのみを消すには**Remove this widget**を使います。
簡単に消せます！

# Remove this widgetの使い方
1\.まずは消したいWidgetにカーソルを合わせます。
![スクリーンショット 2023-08-15 9.57.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/2c0cd60e-a9a8-8bda-596e-47e3274a8035.png)

2\.次に『cmd』＋『.』(Mac)押すと下記のようになるので
一番下にある『Remove this widget』を選択
![スクリーンショット 2023-08-15 9.58.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/90abba1d-2bad-11e6-44b2-c1d781492298.png)

3\.これで消えます！
![スクリーンショット 2023-08-15 9.58.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524075/c535e51c-b78f-d697-bfa8-33490c92592f.png)
ReactとNext.jsの違いについて



ReactとNext.jsは、両者とも現代のフロントエンド開発において非常に人気のあるライブラリ・フレームワークです。


しかし、それぞれの目的と機能は異なります。この記事では、その違いについて、具体的なコードの例を交えてご説明します。

## 1. 基本的な違い

👉 ポイント: Reactは**ライブラリ**、Next.jsはReactのための**フレームワーク**です。

ReactはFacebookが開発したユーザーインターフェースを構築するためのライブラリです。

一方、Next.jsはReactをベースにしたサーバーサイドレンダリングや静的サイト生成を容易にするフレームワークです。

```javascript
// Reactの基本的なコンポーネント
function App() {
  return <div>Hello React!</div>;
}

// Next.jsの基本的なページコンポーネント
function HomePage() {
  return <div>Hello Next.js!</div>;
}
```

## 2. 開発環境のセットアップ

👉 ポイント: Next.jsは開発環境のセットアップが簡単です。

Reactアプリをゼロからセットアップする場合、WebpackやBabelの設定が必要です。


一方、Next.jsではこれらの設定がデフォルトで組み込まれており、開発サーバーをすぐに起動できます。

```bash
# Reactアプリのセットアップ
npx create-react-app my-app

# Next.jsアプリのセットアップ
npx create-next-app my-next-app
```

## 3. ルーティング

👉 ポイント: Next.jsは**ファイルベースのルーティング**を採用しています。

React自体にはルーティング機能は含まれていません。そのため、例えば`react-router-dom`などのライブラリを使ってルーティングを実装します。


一方、Next.jsでは`pages`ディレクトリ内のファイル構造に基づいて自動的にルーティングが生成されます。

```javascript
// Reactでのルーティング例
<Route path="/about" component={About} />

// Next.jsでのルーティング
// pages/about.jsファイルを作成するだけで、/aboutルートが自動的に生成される。
```

## 4. サーバーサイドレンダリング(SSR)と静的サイト生成(SSG)

👉 ポイント: Next.jsは**SSRとSSGを簡単に実装**できます。

Reactはクライアントサイドレンダリング(CSR)が主ですが、Next.jsではSSRやSSGを容易に取り入れることができます。これにより、SEO対策やパフォーマンス向上に貢献します。

```javascript
// Next.jsでのSSR例
export async function getServerSideProps() {
  // データのフェッチやDBへのアクセスなど
  return { props: { data: fetchedData } };
}

// Next.jsでのSSG例
export async function getStaticProps() {
  // データのフェッチやDBへのアクセスなど
  return { props: { data: fetchedData } };
}
```

まとめると、ReactとNext.jsは、それぞれ異なる目的と特徴を持っています。どちらを選択するかは、プロジェクトの要件や目的に応じて選んでください。
Vimium

現在のページをナビゲートする：
?       利用可能なすべてのキーのリストのヘルプダイアログを表示
h       左にスクロール
j       下にスクロール
k       上にスクロール
l       右にスクロール
gg      ページの先頭にスクロール
G       ページの最後にスクロール
d       半ページ分下にスクロール
u       半ページ分上にスクロール
f       現在のタブでリンクを開く
F       新しいタブでリンクを開く
r       再読み込み
gs      ソースを表示
i       挿入モードに入る - escを押すまでのすべてのコマンドが無視されます
yy      現在のURLをクリップボードにコピー
yf      リンクのURLをクリップボードにコピー
gf      次のフレームに進む

新しいページへのナビゲーション：
o       URL、ブックマーク、履歴エントリを開く
O       新しいタブでURL、ブックマーク、履歴エントリを開く
b       ブックマークを開く
B       新しいタブでブックマークを開く

検索の使用：
/       検索モードに入る - 検索クエリを入力してEnterキーを押すか、escキーを押してキャンセル
n       次の検索一致に進む
N       前の検索一致に戻る


履歴のナビゲーション：
H       履歴で後ろに戻る
L       履歴で前に進む







タブの操作：
J, gT   一つ左のタブに移動
K, gt   一つ右のタブに移動
g0      最初のタブに移動
g$      最後のタブに移動
t       タブを作成
x       現在のタブを閉じる
X       閉じたタブを復元（つまり、'x'コマンドを取り消す）
T       開いているタブを検索
スクラムマスターになる前にやっておくべき３つのこと

## はじめに
スクラム歴1年未満のスクラム初心者です。
チーム内で開発者として作業し、前任者からスクラムマスターを引継ぎました。
今月からスクラムマスターになったばかりなので、スクラムマスターになる前にやっておくべきことを書きます！

## スクラムマスターになる前にやっておくべき３つのこと
### 1.本でスクラムマスターの目標・役割を理解する
スクラムマスターは、`開発者が開発に専念できるようにするため、チームの障害を排除し、開発以外の作業を全て実施する`という秘書やお母さんのような役割だと勘違いしていました。
書籍[SCRUMMASTER THE BOOK](https://www.amazon.co.jp/SCRUMMASTER-BOOK-%E5%84%AA%E3%82%8C%E3%81%9F%E3%82%B9%E3%82%AF%E3%83%A9%E3%83%A0%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E3%81%AB%E3%81%AA%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E6%A5%B5%E6%84%8F%E2%80%95%E2%80%95%E3%83%A1%E3%82%BF%E3%82%B9%E3%82%AD%E3%83%AB%E3%80%81%E5%AD%A6%E7%BF%92%E3%80%81%E5%BF%83%E7%90%86%E3%80%81%E3%83%AA%E3%83%BC%E3%83%80%E3%83%BC%E3%82%B7%E3%83%83%E3%83%97-Zuzana-Sochova/dp/4798166855)を読み、以下のような目標・役割があると知りました。（最初の章で、さっそく秘書ではないと否定されていました。）

- **目標**
    - チームを自己組織化させること
        - 自己組織化：自分たちが達成すべきビジョン・ゴールに対して自分たちがやるべきことを自分たちで考え、自分たちで行動できるチーム・組織
- **役割**
    - スクラムイベントの準備・ファシリテートする
    - チーム・組織へスクラムを普及する
    - チームを観察し、課題の解消に向けて働きかける

直接作業指示したり問題を解決するのではなく、**チームの自己組織化を目指してチーム内で解決できるように促したりアドバイスする**ことが重要です！

---

### 2.振り返り手法について学ぶ
レトロスペクティブではチームが抱えている課題を話し合います。
チーム状況に合う課題が出やすく・議論しやすい手法を選べるようにするため、**どんな振り返りでどんな議論ができるかを知っておくこと**が大事です。

チーム状況と、振り返りの組み合わせは以下のようなものです。
- **PJ歴短いメンバが作業に入りにくそうにしていた場合**
    - `ありたい姿`でありたい姿と現状のギャップを埋める対策を話す
- **チームとして課題が多かった場合**
    - `気になっていること`で課題を共有するためのハードルを下げ、些細なことを拾える
- **スプリントゴールを達成し、うまくいった場合**
    - `Good,Bad,Ideas,Action`や`KPTT`で良かったことを共有しあう

振り返り手法については以下の振り返りカタログを参考にさせて頂きました。
[ふりかえりカタログ / Retrospective Catalog](https://speakerdeck.com/viva_tweet_x/retrospective-catalog-59bd3a29-314c-45dd-911b-f8e5f1308333?slide=16)

---

### 3.現スクラムマスターの話を聞く
スクラムマスターが何を考えているのか、どんな課題があったり、どんなイベントの進め方をしているのかを知るため、実際のスクラムマスターから話を聞くのも有効です。
社内のスクラム関連の勉強会に参加したり、前任スクラムマスターからの引継ぎを行いました。

引継では以下のようなことをヒヤリングしました。
- 管理作業の手順・権限の引継
- スクラムマスターの役割についての意識合わせ
- スクラムマスターが考えるチームの課題
- 常に心掛けていること
    - 例えば、「メンバが多いので、会議は話題を絞ってゴールを明確にする」、「メンバにできるようになってもらうため、「スクラムマスターがやってあげよう！」はNG」等

## おわりに
最初にスクラムマスターになると聞いたときは「正直プレッシャーあるし、コードも書きたいから開発者のままが良いな」と思っていました。
いざなってみると、これまでよりスクラムやチーム、自分の行動について考える機会が増えて、色々と見えるものが変わって楽しくなりました。
これからも楽しくスクラムマスターを続けていきたいです！
Windowsのコマンドプロンプトで打ったコマンド履歴取得

# やり方（表示）

```bat:
doskey /h
```

実行結果の例。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/aafb4949-8242-eb29-4458-8fa4c613a5dc.png)
```doskey /h``` 自体も履歴に載ってくる。

# やり方（クリップボードへ）

```bat:
doskey /h | clip
```

``` | clip``` 付ければクリップボードに入ってメモ帳とかにペースト可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b7a3d456-8089-dceb-19d0-87f2228accbf.png)

作業履歴作成、手順書残す、bat作成、などで便利。

# 開いているコマンドプロンプト画面で打った履歴のみ

1. コマンドプロンプト開く。
1. コマンド打つ。①
1. コマンドプロンプト画面閉じる。
1. 再度コマンドプロンプト開く。
1. ```doskey /h``` しても、既に閉じてしまった画面で作業していた分（①）のコマンドは取得できない。


# 参考サイトさん

https://qiita.com/ShotaKameyama/items/9c71c264b7281e25ad83

# バージョン

Microsoft Windows [Version 10.0.19045.3324]
Java 日付に対応する曜日を取得する

int型の年、月、日の情報に紐づく曜日を取得し出力したい

ポイント
Calenderクラスを使用する
月は0~11で設定する

```youbiSyutoku.java
Calendar cal = Calendar.getInstance();
int year  = 2016;   // 年
int month = 12 - 1; // 月
int date  = 26;     // 日

cal.set(year, month, date);

// 日付から曜日を取得する
 switch (cal.get(Calendar.DAY_OF_WEEK)) { 
    case Calendar.SUNDAY:     // Calendar.SUNDAY:1 
    	//日曜日
	    System.out.println("日曜日");
	    break;
	case Calendar.MONDAY:     // Calendar.MONDAY:2
	    //月曜日
	    System.out.println("月曜日");
	    break;
	case Calendar.TUESDAY:    // Calendar.TUESDAY:3
	    //火曜日
	    System.out.println("火曜日");
	    break;
	case Calendar.WEDNESDAY:  // Calendar.WEDNESDAY:4
	    //水曜日
	    System.out.println("水曜日");
	    break;
	case Calendar.THURSDAY:   // Calendar.THURSDAY:5
	    //木曜日
	    System.out.println("木曜日");
	    break;
	case Calendar.FRIDAY:     // Calendar.FRIDAY:6
	    //金曜日
	    System.out.println("金曜日");
	    break;
	case Calendar.SATURDAY:   // Calendar.SATURDAY:7
	    //土曜日
	    System.out.println("土曜日");
	    break;
  }
```
Foxglove Studioを使う

皆さんはRViz2は使っているでしょうか？しかし、SSHで接続し、GUIを無効にしてROS2を動かしている方も多いのではないでしょうか。そんな方におすすめしたい、使いやすい可視化ツールを紹介します。
# Foxgloveとは
公式サイトより。
> Foxglove Studioは、ロボット工学データのためのオープンソースの可視化およびデバッグツールです。スタンドアロンのデスクトップアプリとして実行したり、ブラウザからアクセスしたり、あるいは独自ドメインでセルフホストすることもできます。

今回はデスクトップアプリの方に焦点を当てて紹介したいと思います。

# インストール
FoxgloveをインストールするPCにROS2が入っている必要はありません。
👇以下のリンクにあるmacOS,Linux,Windowsのいずれかからダウンロードしてインストールしてください。

https://foxglove.dev/download

# ROSbagを見る
Foxgloveの良い点はローカルにROS2がなくてもROSbagを見ることができることです。
デモ用のrosbagを用意したのでfoxgloveをインストールしたPCにダウンロードしてください。

https://drive.google.com/file/d/11HVX8_-dUAWq1INcxChvFAp3jt-JrKR8/view?usp=sharing

ダウンロードしたら`Open local file`を選択してダウンロードした中にあるmcapファイル選択してください。

![Screenshot 2023-08-15 at 10.11.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/899689/f4677a5e-89d4-0cfd-1390-838d19f5062a.png)

次に右上にある`layout`>`Import from file`を選択してダウンロードした中にある`json`ファイルを選択します。
![Screenshot 2023-08-15 at 10.12.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/899689/9b0680f3-ed39-0a83-5a9e-8cb7fe53ba01.png)


そして中央下にある再生ボタンを押すと点群データが見えると思います。

![Screenshot 2023-08-15 at 10.15.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/899689/f40fd7b4-b96b-77be-5e4e-786b9f2bc6f6.png)

![Screenshot 2023-08-15 at 10.16.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/899689/2e52f808-71ae-4995-9be1-c96dc6134e18.png)


# レイアウトをカスタマイズする

右上にあるこのボタンを押すとパネルをカスタマイズすることができます。使い方はRVizなど変わりありません。

![Screenshot 2023-08-15 at 10.17.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/899689/ae064d5b-d1bb-0ace-a104-50ca96d9055c.png)


# ROS2と繋げる

ROS2を実行している環境(Ubuntu推奨)で以下を実行します。

```
sudo apt install ros-$ROS_DISTRO-foxglove-bridge
ros2 launch foxglove_bridge foxglove_bridge_launch.xml port:=8765
```
Foxgloveの起動時の画面に戻ってOpenConnectionを選択します。

そして以下のlocalhostの部分を`ros2 run`したPCのIPアドレスにします。

![Screenshot 2023-08-15 at 10.21.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/899689/5ce9900b-09f6-6aa9-8ed1-b94f978e23b4.png)

そしたら接続完了なのでtopicに流れているデータを見ることができます。

# 最後に
Foxgloveはさまざまなデータの可視化やローカルでのrosbagの再生ができるため、非常に便利です。ぜひ一度試してみてください。ぜひ使っていみてください。詳しく知りたい方は公式ドキュメントや私のほかの記事を参考にしてください。

https://foxglove.dev/docs/studio

https://qiita.com/TakanoTaiga/items/99a22e754e74a81a871e
Java 西暦和暦変換方法

ポイント
①西暦→和暦の場合は和暦配列を作成する
和暦配列はString型の二次元配列
和暦テーブルには各元号ごとに開始年月日、終了年月日、年号の記載を格納する
②Calenderクラスを使用する

```warekiHenkan.Java
public static void main(String[] args) {

    	Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        
        String[] seirekiList = line.split(" ");
        String month = String.format("%02d", Integer.parseInt(seirekiList[1]));
        String date = String.format("%02d", Integer.parseInt(seirekiList[2]));
        
        String seireki = seirekiList[0] + month + date;
        
      //和暦変換テーブル
        String warekiTable[][] = {
            {"18680908","19120729", "明治"},   //明治          
            {"19120730","19261224", "大正"},   //大正
            {"19261225","19890107", "昭和"},   //昭和
            {"19890108","20190430", "平成"},   //平成
            {"20190501","30001231", "令和"},   //令和
        };
        int year = Integer.parseInt(seirekiList[0]);
        
        //暦変換テーブルをサーチする
        int i = 0;
        for (i=0; i<warekiTable.length; i++) {
            //当該西暦が開始年以上で最終年以下ならbreak
            if (seireki.compareTo(warekiTable[i][0]) >= 0 && seireki.compareTo(warekiTable[i][1]) <= 0) {
                break;
            }
        }
        //暦テーブルに該当レコードがあれば、和暦年を計算する
        if (i < warekiTable.length) {
            int jpYear = year - Integer.parseInt(warekiTable[i][0].substring(0,4)) + 1;
            String year1 = String.valueOf(jpYear);
            //和号+和暦年を返す
            if(year1.equals("1")) {
            	year1 = "元";
            }
            System.out.println(warekiTable[i][2] + year1 + "年" + seirekiList[1] + "月" + seirekiList[2] + "日");
        }
    }
```
Java 順列を作成する

Javaには順列作成用のAPIがないため自力で作成する

考え方
①元々の配列からひとつずつ新たに作成した配列に格納する
②要素の重複回避のため、boolean型の配列を作成し便宜的に使用する

参考
順列 (permutation) を作成する
https://maku77.github.io/java/numstr/permutation.html
Java 最小二乗法で回帰係数を求めたい

～前提～
(x,y)の情報が複数与えられている

考え方
１．それぞれの変数の平均値を求める
２．それぞれの変数の偏差（数値 － 平均値）を求める
３．変数 x の分散（偏差の二乗平均）を求める
４．共分散（偏差の積の平均）を求める
５．共分散を変数 x の分散で割って回帰直線の傾きを得る
６．2 つの変数の平均値と傾きから、回帰直線の y 切片を得る

参考
最小二乗法の意味と計算方法 - 回帰直線の求め方
https://sci-pursuit.com/math/statistics/least-square-method.html
JavaのHashMapで最大値を取得する方法

～したいこと～
HashMapに格納されてる値の最大値に紐づくKeyを取得したい

～考え方～
①mapのKeyとValueをひとつずつループ取得する
②最大値とValueを比較し、Valueの方が大きい場合最大値にValueをセットする

～コード～
```
//entrySetメソッドでマップのキーとValueを一つずつ取得
for (Map.Entry<String, Integer> entry : map.entrySet()) {
//最大値とValueを比較してValueが大きければ、そのときのキーとValueを代入
  if (entry.getValue() > maxValue) {
    maxKey = entry.getKey();
    maxValue = entry.getValue();
  }
}
```
git & GitHub 操作方法で役に立ったWebページ

実際に操作する際に参考にしたWebページをまとめた

GitHubでファイル検索から変更履歴確認まで高速で行う
→ファイル検索を素早く行う方法と、コミット単位での履歴確認の方法を記載している
https://qiita.com/darquro/items/cf64e76bbf848feefa32

【Git&GitHub】プルリクエストについて
→ローカルリポジトリ：ローカルフォルダ（エクスプローラー）
　リモートリポジトリ：GitHub
　の場合のプルリクエスト方法について記載されてる
https://phoeducation.work/entry/20210913/1631487480

リポジトリ内でブランチを作成および削除する
→GitHubでのブランチの操作の仕方
https://docs.github.com/ja/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-and-deleting-branches-within-your-repository
よく使うDocker関連コマンド

# 概要
開発していて使う機会の多いDockerコマンドの備忘録です。初学者向け。

**環境・技術**
M1 Mac
Docker 24.0.5
Docker Compose 2.20.2

# コマンド
```zsh
# Dockerfileからイメージをビルド
docker-compose build
# キャッシュを使用しない（オプション）
docker-compose build --no-cache

# 複数コンテナの一括作成/起動
docker-compose up
# イメージを再構築(オプション)
docker-compose up --build

# コンテナ一覧の表示
docker-compose ps

# 既存コンテナでコマンドを実行
docker-compose exec 

# コンテナに入る（コンテ内に入り、shellを起動するコマンド）
docker exec -it <コンテナ名> bash
# 例：webという名前のコンテナに入る場合
docker exec -it web bash

# コンテナの停止(削除はしない)
docker-compose stop

# コンテナの起動
docker-compose start

# コンテナの停止および、upで作成したコンテナ、ネットワーク、ボリューム、イメージの削除
docker-compose down

```

# 参考
https://www.kagoya.jp/howto/cloud/container/dockercomposeup/
https://docs.docker.jp/compose/reference/build.html
https://docs.docker.jp/compose/reference/down.html
https://www.wakuwakubank.com/posts/354-docker-command-compose/#index_id1
https://tech.kurojica.com/archives/56621/
GoogleフォームとLINEを連動させたアプリを作ってみる(メッセージ送信編)

こんにちは。船井総研デジタルのいっちーです。
前回の記事では、LINE Business IDの登録とLINE Messaging APIのチャネル作成を行い、プログラムからLINEにメッセージを送るための環境を整えました。

https://qiita.com/fsd_itchy/items/8f12061947a236a68c4b

今回は、このAPIにメッセージを送るGoogle Apps Scriptのスクリプトを作成し、実際にメッセージを送ってみたいと思います。

# メッセージを送るスクリプトを書いてみる
まず、Google Spreadsheetを立ち上げて、空のシートを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280429/a67478aa-9208-3462-ad69-25dd525ad464.png)

メニューから「拡張機能」→「Apps Script」を選択すると、スクリプトエディタが開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280429/8e91926b-a2a1-913e-1a4a-a79bab76fbc1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280429/8abbb96b-d8f7-ce2a-3b42-a76a645dafbe.png)

`myFunction`という関数があらかじめ作られていますので、以下のコードを打ち込んでください。

<details><summary>メッセージ送信テストコード</summary>

```javascript
function myFunction() {
  var accessToken = '【前回の記事で作成したアクセストークン】';
  var url = 'https://api.line.me/v2/bot/message/push';

  var headers = {
    Authorization: 'Bearer ' + accessToken,
    'Content-Type': 'application/json',
  };

  var payload = {
    to: '【前回の記事で作成したユーザーID】',
    messages: [
      {
        type: 'text',
        text: 'こんにちは！\nこれはテストメッセージです。',
      },
    ],
  };

  var options = {
    method: 'post',
    headers: headers,
    payload: JSON.stringify(payload),
  };

  var response = UrlFetchApp.fetch(url, options);
  Logger.log(response.getContentText());
}
```
</details>

書き終わったら、保存ボタンを押下して保存しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280429/515d2a46-68e9-cbfb-946a-ca25508d3019.png)

# メッセージ送信

それでは、実際にメッセージを送ってみましょう。「実行」ボタンを押下してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280429/2eaed068-9597-2050-7e01-f96177bb3ba2.png)

:::note info
実行権限を求めるようなダイアログが出た場合は、「許可する」方向に倒れるように操作してください。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280429/80e1c617-f4f2-3cbc-536a-956a7e2b99c5.png)

実行ログが表示されました。LINEの画面を見てみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280429/cffbdccd-834a-3472-5765-68c41c5265e6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3280429/d181e56d-fb64-7fad-0e59-857f53b98c80.png)

無事に、メッセージを受信することができました。`\n`もきちんと改行に置き換えられています。

# まとめ
今回は、Google Apps ScriptのスクリプトからLINEのメッセージを送信する実験を行いました。[次回](https://qiita.com/fsd_itchy/items/c85bed742bc314b5dac6)は、このスクリプトをGoogleフォームと連動させて、最終的な形に仕上げていきたいと思います。

それではまた。
VscodeとGithubの連携

実はずっとGithubから逃げていたのですが、そろそろちゃんとやらなくてはと思いGithubとVscodeの連携をしてみました。

1 VSCode エクステンションのインストール:

・VSCode を開きます。
・サイドバーのエクステンションアイコン（四つの小さな四角形）をクリックします。
・検索ボックスに GitHub と入力して、公式の "GitHub Pull Requests and Issues" エクステンションを探します。
・エクステンションをインストールします。

2 リポジトリのクローン:

・コマンドパレットを開く（Ctrl+Shift+P or Cmd+Shift+P）。
・ローカル保存先のフォルダにcd..などで移動する
```
git clone [リモートリポジトリのURL]
```

3 GitHub アカウントの認証:

・コマンドパレットを開きます。
・GitHub: Sign in to GitHub と入力して選択します。
・認証の指示に従って、GitHub アカウントにサインインします。

4 Gitにコミット 

VSCodeの組み込みターミナルを開きます。以下のコマンドを実行して、変更をステージングエリアに追加します：

```
git add .
```
コミットメッセージを付けて変更をコミットします：
```
git commit -m "初めてのコミット"
```
変更をリモートリポジトリにプッシュ:
```
git push origin main
```
逆にプルしたいときは
```
git pull origin main 
```
docker buildx buildを使ってdockerイメージをローカルに書き出したい

`docker buildx build` を以前の`docker build`のようにして互換性あるように使いたい場合、

```shell-session
$ docker buildx build --output=type=docker -t ユーザー名/イメージ名:タグ名
# 省略形
$ docker buildx build --load -t ユーザー名/イメージ名:タグ名
```

でいけるようです。
つまずいたので、投稿しておきます。


[[公式]単一プラットフォームの構築結果を docker images に読み込む（--load）](https://docs.docker.jp/engine/reference/commandline/buildx_build.html#docker-images-load)

> 構築結果の出力方法を指定（-o, --output）
-o, --output=[PATH,-,type=TYPE[,KEY=VALUE]
build 結果の出力処理を設定します。 docker build で全ての構築が終わると、コンテナのイメージを作成し、それを docker images に出力します。 buildx ではこの手順が設定できるようになっており、処理結果を直接クライアントや、oci イメージ・tar ボールやレジストリ等に出力できます。

> Buildx の docker ドライバが現時点でサポートしているのは、 local 、 tar ボール・エクスポータtarball exporter と イメージ・エクスポータimage exporter のみです。 docker-container ドライバは全てのエクスポータをサポートします。

> docker
docker エクスポート型は、特定のプラットフォームに対する Docker イメージ仕様 のイメージとしてクライアント上に書き出します。このエクスポータによって作成される tar ボールは、 OCI 互換性もあります。

> 現時点では、マルチプラットフォーム・イメージは docker エクスポート型はでは出力できません。マルチプラットフォーム対応イメージの最も一般的な利用方法は、レジストリに直接送信する場合です（ registry をご覧ください。）。

> 単一プラットフォームの構築結果を docker images に読み込む（--load）
--output=type=docker の省略形です。単一プラットフォーム向けの構築結果を docker images に読み込みます。




CI/CDには`docker buildx build --push`を併用して`docker build `~`docker push`をワンコマンドでできるようです。


```shell-session
$ docker buildx build --output=type=image,push=true -t ユーザー名/イメージ名:タグ名
# 省略形
$ docker buildx build --output=type=registory -t ユーザー名/イメージ名:タグ名
# さらに省略形
$ docker buildx build --push -t ユーザー名/イメージ名:タグ名
```

[[公式]構築結果をレジストリに送信（--push）](https://docs.docker.jp/engine/reference/commandline/buildx_build.html#push)

> registry
registry エクスポータは type=image,push=true の省略形です。

> 構築結果をレジストリに送信（--push）
--output=type=registry の省略形です。構築結果をレジストリに自動送信します。
mysqlコマンドでDockerのMySQLに接続できない！ (Can't connect to local MySQL server through socket ...)

ローカルの開発環境で動いているはずのMySQLに`mysql`コマンドで接続しようとして、 `Can't connect to local MySQL server through socket` と言われたとき。

```plain
$ mysql -u root -p -h localhost -P 13306 DBNAME
Enter password:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
```

MySQLが動いてなかったり、あるはずのソケットファイルがなんらかの理由で見つからない場合にこのエラーになります。

Dockerコンテナで動かしているMySQLにホスト側から`mysql`コマンドで接続しようとしている場合にもこのエラーになることがあります。DockerでMySQLを動かすと、ソケットファイルはマウントしない限りホスト側から見えないためです。

そんなときは `--protocol=tcp` を付ければ接続できます。

```plain
$ mysql -u root -p -h localhost -P 13306 --protocol=tcp DBNAME
```

`mysql`コマンドはlocalhostの場合にソケットファイルで通信しようとすることがあるようです。`-P`を付ければTCPで通信してくれそうなものをそれでもソケットファイルを探すケースがありました。DockerでMySQLを動かすときはソケットファイルをマウントしていなければTCPで通信する必要がありますので、`--protocol=tcp`を明示的に指定します。


### 本題に関係ないけど補足説明

`mysql`コマンドのオプション

- `-u`: MySQLユーザ名を指定
- `-p`: パスワードをプロンプトで入力することを指定
- `-h`: 接続先ホスト名
- `-P`: ポート番号を指定（デフォルトの3306から変えている場合に指定）