OmniAICreator/Qiita-1.07M huggingface dataset:
openai / whisper を使ってマイクに話した言葉を文字起こしする Python スクリプトを書いた

# Intro
OpenAI が開発した音声認識モデルが日本語を良い感じに認識できるという評判を Twitter 上で見かけました。
文字起こし器が前々から欲しかったので、マイクに話した言葉を文字起こししてくれる Python スクリプトを書きました。

# 実行してみる

🗣️ < "はい、ということで今日はOpenAIが開発した Whisper について勉強していきたいとおもいます。Whisper は音声認識モデルです。"

実行結果

```
$ python main.py
* recording
^C* done recording
Detected language: ja
はい、ということで今日はオープンAIが開発したMISPER、マイツイテレンキをしていきたいと思いますMISPERは大さな仕込でです
```

Whisper が MISPER になってしまっています。"音声認識モデル" に至っては、"大さな仕込"になっています。マイツイテレンキ??  
私の滑舌が悪いのか、それとも Whisper がまだまだなのかは、是非自身の声で確かめてください。

# 実装
### 試した環境
- macOS Big Sur
- Intel CPU
- Python 3.9

### 環境構築
以下のライブラリを install する。

- `pip install pyaudio`
- `brew install portaudio`
    - pyaudio の利用に必要
- `pip install git+https://github.com/openai/whisper.git`

### 実装コード

``` python
import pyaudio
import wave
import whisper

model = whisper.load_model("base")


def main():
    CHUNK = 1024
    FORMAT = pyaudio.paInt16
    CHANNELS = 1
    RATE = 44100
    WAVE_OUTPUT_FILENAME = "output.wav"

    p = pyaudio.PyAudio()

    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    frames_per_buffer=CHUNK)

    print("* recording")

    frames = []

    while True:
        try:
            # Record
            d = stream.read(CHUNK)
            frames.append(d)

        except KeyboardInterrupt:
            # Ctrl - c
            break

    print("* done recording")

    stream.stop_stream()
    stream.close()
    p.terminate()

    with wave.open(WAVE_OUTPUT_FILENAME, 'wb') as wf:
        wf.setnchannels(CHANNELS)
        wf.setsampwidth(p.get_sample_size(FORMAT))
        wf.setframerate(RATE)
        wf.writeframes(b''.join(frames))
        wf.close()


def recognize():
    # load audio and pad/trim it to fit 30 seconds
    audio = whisper.load_audio("output.wav")
    audio = whisper.pad_or_trim(audio)

    # make log-Mel spectrogram and move to the same device as the model
    mel = whisper.log_mel_spectrogram(audio).to(model.device)

    # detect the spoken language
    _, probs = model.detect_language(mel)
    print(f"Detected language: {max(probs, key=probs.get)}")

    # decode the audio
    options = whisper.DecodingOptions(fp16 = False)
    result = whisper.decode(model, mel, options)

    # print the recognized text
    print(result.text)


if __name__ == '__main__':
    main()
    recognize()
```

### 実行時に発生したエラーに関して

ほぼほぼ PyAudio のサンプル + whisper のサンプルを足し合わせたものなので解説はしないが、はまったエラーの解決に役立った情報を記載しておきます。

- `urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify faile`
  - https://github.com/openai/whisper/discussions/80
- `RuntimeError: "slow_conv2d_cpu" not implemented for 'Half'`
  - https://github.com/openai/whisper/discussions/92


# 参照リンク

https://github.com/openai/whisper

https://people.csail.mit.edu/hubert/pyaudio/

cntorol - c で音声認識をストップする実装はこちらから頂きました 🙏

https://qiita.com/beeesssaaa/items/68342472694a3f74d86e
【個人開発】コンビニ✖️コンビ；コンビニの商品組み合わせを自動で提案してくれるWEBサービスを作りました【暇つぶしクソアプリ】

# はじめに

こんにちは。
コンビニって本当に便利ですよね。
でも商品多すぎて、お昼に結局何をを購入しようか迷う時があるので、
コンビニの組み合わせを自動で提案してくれるWEBサービスを作りました。


本家様、情報を拝借しております。



# サービス生み出しの背景

コンビニでカロリーを見てお昼を選んでいた女性MRが
その姿を顧客に見られてニヤニヤされたため、
先に組み合わせを選んであとはコンビニで取るだけのサービスを作りたかった。



# サービス概要

[コンビニ×コンビ](https://conveniconvi0205.herokuapp.com/polls/top/ "コンビニ×コンビ")

https://conveniconvi0205.herokuapp.com/polls/top/


![conviniconvi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2866856/d8985e72-76ea-6ef4-77b1-4af134cc4c21.png)
　

 

＜内容＞
コンビニの組み合わせを自動で提案してくれる

使って欲しい人；
コンビニ飯が多く、組み合わせを決めるのがめんどくさい人
カロリー気になる人


＊セブン/ローソンに対応中



# 使用技術について
エンジニアスクールで教えてもらっていたDjangoで作成をしました。

＊スクレイピングに関しては下記のサイトを参考にしました。
　https://ai-inter1.com/python-scrapy-for-begginer/




# 追加の要望

https://blueniport.herokuapp.com/top/


ポートフォリオのお問合せフォームから追加の要望やバグについてなどいただけたら嬉しいです。
よろしくお願いいたします。
ツイッターのDMもOKです。

https://twitter.com/blue_no_uniuni



# 終わりに
まだまだ駆け出しですが、Qiitaでたくさんの知識を学ばせてもらっています。
基本的に生み出すアプリの99％はクソアプリです。

これからもどんどん新しいサービスを作っていきたいなと思っておりますが、
少しでもサービスに興味を持ってもらえたら幸せです。
システムスペックではvisit hoge_urlではなくvisit hoge_pathと書かないとNet::ReadTimeoutエラーが発生する

## 発生した問題
Hello worldレベルのごく簡単なRailsアプリを作成し、rspec-railsをインストールして次のようなシステムスペックを書きました。

```ruby 
require 'rails_helper'

RSpec.describe "Home", type: :system do
  before do
    driven_by(:selenium_chrome_headless)
  end

  example do
    visit root_url
    expect(page).to have_content 'Home#index'
  end
end
```

テストを実行すると・・・あれ？

``` 
$ bundle exec rspec
DEBUGGER: Attaching after process 28722 fork to child process 28745

（何も起きない）
```

この状態が何十秒も続き、最終的には以下のエラーが出て終了しました。

``` 
$ bundle exec rspec
DEBUGGER: Attaching after process 28722 fork to child process 28745
F

Failures:

  1) Homes 
     Failure/Error: visit root_url
     
     Net::ReadTimeout:
       Net::ReadTimeout with #<Socket:(closed)>
     
     [Screenshot Image]: /Users/jnito/dev/sandbox/without-active-record/tmp/capybara/failures_r_spec_example_groups_homes_example_at___spec_system_homes_spec_rb_8_381.png

     
     # ./spec/system/homes_spec.rb:9:in `block (2 levels) in <top (required)>'

Finished in 1 minute 16.35 seconds (files took 0.5839 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/system/homes_spec.rb:8 # Homes 
```

ちなみにドライバを`:rack_test`に変えるとテストはパスします。

```diff_ruby 
   before do
-    driven_by(:selenium_chrome_headless)
+    driven_by(:rack_test)
   end
```

```
$ bundle exec rspec
.

Finished in 0.06872 seconds (files took 0.63488 seconds to load)
1 example, 0 failures
```

はて？？？？

## 解決方法
`visit root_url`を`visit root_path`に変えると直りました。たったこれだけ！！

```diff_ruby
   example do
-    visit root_url
+    visit root_path
     expect(page).to have_content 'Home#index'
   end
```

```
$ bundle exec rspec
DEBUGGER: Attaching after process 28608 fork to child process 28634
.

Finished in 1.44 seconds (files took 0.60104 seconds to load)
1 example, 0 failures
```

ちなみにデフォルトの状態では`root_url`と`root_path`はそれぞれ以下のような値になっていました。

```ruby 
puts root_url  #=> http://www.example.com/
puts root_path #=> /
```

これ、以前もハマった記憶があるんですが、すっかり忘れてまたハマってしまいました……😓
みなさんもお気を付けください。

## 確認したバージョン

- ruby 3.1.2
- rails 7.0.4
- rspec-rails 6.0.0.rc1
- capybara 3.37.1
- selenium-webdriver 4.4.0
- Chrome 105.0.5195.125
Windowsのファイルの保存場所を開く(Open File Location)コマンドをPythonで実行する

# 実現目標
:::note
・スタートメニューから `More > Open File Location` 
・ショートカットから `右クリック > Open File Location` 

「対象のファイルが存在するフォルダが開き(または、移動して)、対象のファイルがアクティブになる」操作をPythonで実行する
:::

# 用途
:::note warn
たとえば、Imageビューアなどで右クリックして画像の保存場所を開けます。
:::

# コード
```python
import os
import subprocess

def open_file_location(absolute_path):
    # windows用のパスへ変換
    path = os.path.realpath(absolute_path)
    # subprocessでコマンドシェルを実行
    subprocess.Popen(f'explorer.exe /select, {path}')

open_file_location("C:/Images/image1.jpg")
```

# ポイント
subprocess.Popenで`/select`を指定することで、ファイルがアクティブ(ファイル選択状態)になるところがポイントです。あと、`,`をお忘れなく。

# 参考
https://docs.python.org/3/library/subprocess.html
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その034

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: データと自動化
データ管理と分析管理の演習

にある練習問題2問目をご紹介します


https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-security-and-data-management/review-data-management?trail_id=administrator-certification-prep

今回の内容は動画でも解説しています

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

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


本日の問題はこちらです

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/cb26fc63-1c98-a777-7360-bdabf569f9d5.png)


正解はBとCですね

Bの円グラフはClassic環境でしか作成できないので注意しましょう


集合棒グラフについてはこちらです
https://help.salesforce.com/s/articleView?id=sf.chart_bar_grouped.htm&type=5
nginxでクライアントがリクエストした元のURLを取得する

## 概要

Webサーバのフロントエンドとしてnginxを使った際に、バックエンドのWebアプリでもクライアントがリクエストした元のURLの情報（プロトコル、ホスト名、パス）を取得する方法を紹介する。

## 環境情報

#### 構成

* **リバースプロキシ : nginx**
    * ホスト名 : hogehoge.com
    * プロトコル : https
    * ポート : 443
* **Webアプリ**
    * ホスト名 : 192.168.1.4
    * プロトコル : http
    * ポート : 5000

#### nginx.confの設定

以下はserver部分のみ抜粋したもの。
```nginx.conf
    server {
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        listen 443 ssl;
        listen  [::]:443;
        # (中略。サーバ証明書のファイルパス等の指定が実際は必要）

        location / {
            proxy_pass http://192.168.1.4:5000/;
        }
    }

```

#### 動作例

nginxに届いた以下のクライアントからのリクエスト
``https://hogehoge.com/some-path?value=1``
を、次のURLに変換して内部のWebアプリにリクエストする。
``http://192.168.1.4:5000/some-path?value=1``

## やりたいこと

Webアプリで**クライアントがリクエストした元のURL**を取得したい。
上に示した「動作例」では以下が取得したいものに相当。
``https://hogehoge.com/some-path?value=1``

## 解決策

バックエンドにリバプロする際、ヘッダーに**クライアントがリクエストした元のURL**の情報を付加可能。
具体的にはnginx.conf のserverまたはlocationのスコープに、次のproxy_set_headerディレクティブを以下のように追加する。

```nginx.conf
        proxy_set_header X-Forwarded-For   $host;        # ホスト名
        proxy_set_header X-Forwarded-Proto $scheme;      # プロトコル
        proxy_set_header Request-Path      $request_uri; # リクエストURLのパス部分
```

先の例で、クライアントが``https://hogehoge.com/some-path?value=1``をリクエストしている場合、nginxの変数には以下のような値が格納される。

| 変数 | 値 |
| --- | --- |
| $host | hogehoge.com |
| $scheme | https |
| $request_uri | /some-path?value=1 |

#### 補足

* proxy_set_headerの第一引数にはヘッダーのフィールド名を指定する。こちらは用途別に推奨されるフィールド名があるようだが、筆者はこの辺に精通していないので適切な名前になっていない可能性がありご注意を。
* ``$host``(=``hogehoge.com``)に関して。筆者が試した環境では``$remote_addr``、``$proxy_add_x_forwarded_for``も同様に``hogehoge.com``が格納されていた。

## Webアプリで実際に取得してみる

PythonのFlaskを使うと、例えば次のようにFlaskのRequestクラスから取得できる。

```python
from flask import Flask, request
app = Flask(__name__)

@app.route("/some-path")
def some_path():

  # 元のURLの情報を取得
  host = request.headers.getlist("X-Forwarded-For")      # $hostを取得
  scheme = request.headers.getlist("X-Forwarded-Proto")  # $schemeを取得
  request_uri = request.headers.getlist("Request-Path")  # $request_uriを取得

  return ""

if __name__ == "__main__":
  app.run(host='0.0.0.0')
```

## どういう時に使える？

Webサーバでユーザ認証する場合などに、クライアントからのリクエストをAuth0等の外部サイトに誘導する場合がある。認証が済んだ後にもともとリクエストしたページに直でリダイレクトさせたい場合、WebサーバでそのURLを覚えておく必要がある。本記事の内容はこのようなケースで活用できるはず。

## 参考情報

https://qiita.com/HeRo/items/7063b86b5e8a2efde0f4
GitLabにGoogleアカウントでログインできるようにする

自分で構築したGitLabにGoogleアカウントでログインできるようにする手順のまとめです。
Gitlabを構築する下記記事の続きになります。

https://qiita.com/kamina/items/1113d4d8eea3fd4db3c9

# 前提(前準備)

GCP(Google Cloud Platform)にGitLab用のプロジェクトが作成済みの前提です。

# GCPにOAuth用の設定を追加する

APIとサービス > OAuth同意画面 でGoogleアカウント連携時の設定を行います。
「User Type」には「内部」を選択。
内部を選択した場合には、このGCPに紐づくGoogle Workspaceのユーザーのみが利用できる設定になります。
外部を選択すると全てのGoogleアカウントで利用できるようになりますが、プライバシーポリシーの設定やGoogleの審査などが必要になるようで(組織外のユーザー情報を扱うことになるので)、結構手間がかかります。
今回は組織内のユーザーのみが使えれば良いので、内部を選択しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/8517bcf1-d273-1946-d23b-3d629c8b9b16.png)
GitLabのロゴ画像などは下記から取得できます。
https://about.gitlab.com/press/press-kit/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/033dd6bd-53d6-145e-e8dd-cd603b0cf01c.png)
内部を選択しているので、プライバシーポリシーや利用規約は不要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/b0abfb9b-43b3-7643-98cf-10c09b158394.png)
利用するスコープを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/43f5b1fc-5871-d47f-f968-7e66317c0556.png)
メールアドレスや一般的なユーザープロファイルが参照できれば良いので、`userinfo.email`と`userinfo.profile`を追加しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/90c10c7e-1e23-c977-e019-9b0ac089dbbc.png)
次にクライアントID/シークレットを作成します。
APIとサービス > 認証情報 と進み、 認証情報を作成から「OAuthクライアントID」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/a9ea7e72-3f2f-6264-c784-3a637401442c.png)
「承認済みのJavaScript生成元」として下記を指定
* `https://gitlab.xxx.com`

「認証済みのリダイレクトURI」として下記を指定
* `https://gitlab.xxx.com/users/auth/google_oauth2/callback`
* `https://gitlab.xxx.com/-/google_api/auth/callback`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/b31625ba-5b5a-654d-6bcb-3674ff998776.png)
完了すると「クライアントID」と「クライアントシークレット」が作成されますので、大切に保管してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/2f01da74-3c22-9a4d-5254-6bdffe724c35.png)

# GitLabにGoogle OAuthの設定を追加する

`/etc/gitlab/gitlab.rb`を編集します。

設定内容としては下記。

* GitLabに登録済みのユーザーのみGooleログインを利用可能
  勝手にGitLabのユーザーを登録しない
* GitLabに同じメールアドレスのユーザーがいた場合、同一ユーザーとして扱う
  omniauth_auto_link_user
* Googleログインの場合は2FAは不要
  omniauth_allow_bypass_two_factor
  Googleログインで2FAを行っているので。

```ruby:/etc/gitlab/gitlab.rb
gitlab_rails['omniauth_auto_link_user'] = ['google_oauth2']
gitlab_rails['omniauth_allow_bypass_two_factor'] = ['google_oauth2']
gitlab_rails['omniauth_providers'] = [
  {
    "name" => "google_oauth2",
    "label" => "Google(好きに設定)",
    "app_id" => "クライアントID",
    "app_secret" => "クライアントシークレット",
    "args" => { "access_type" => "offline", "approval_prompt" => "" }
  }
]
```
設定が完了したら、GitLabを再構築します。
```shell-session
$ sudo gitlab-ctl reconfigure
```
ログイン画面に下記の通り「Googleログイン」ボタンが表示されたら完了です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272546/69206be4-ec58-f49a-e78b-868fd36c2057.png)
SQLのトリガー、ビュー

# トリガー
・テーブルのデータ操作（INSERT/UPDATE/DELETE）した時に自動的に実行する機能
・アプリケーションには依存しないしないもので、トリガーを定義しておけばデータの整合性を保つようにすることができる
・データ操作を頻繁に行うアプリでトリガーを太陽するとパフォーマンスが低下することがある
・アプリではトリガーがどのような処理をするか分からないためトリガーの処理内容を把握してないと、保守性が低下する
・トリガー内でCOMMITを行うと、上位のトランザクションでROLLBACKができなくなる

---

### 基本構文
```sql
CREATE [ OR REPLACE ] TRIGGER トリガー名
    { BEFORE | AFTER | INSTEAD OF }
    { INSERT | UPDATE [OF 列名,...] | DELETE } [OR {INSERT | UPDATE [OF 列名,...] | DELETE }]
    ON テーブル名
    [ FOR EACH ROW ]
    [ WHEN 条件式 ]
    BEGIN
      --処理
    END ;
```
|    |  パラメータ  |説明|
| ---- | ---- | -------------------------------------------------------------------------------|
|  1  |  OR REPLACE  |同じ名前のトリガーが既に存在するときに上書き|
|  2  |  BEFORE / AFTER / INSTEAD OF  |トリガーがいつ起動するのかを指定するキーワード|
|  3  |  BEFORE  |データ操作文が実行される前にトリガーを起動|
|  4  |  AFTER  |データ操作文が実行された後にトリガーを起動|
|  5  |  INSTEAD OF  |データ操作文は実行されず、トリガーだけを起動|
|  6  |  INSERT / UPDATE [OF 列名,...] / DELETE  |3つのデータ操作文の内どれか発行されたときにトリガーが起動するのかを指定|
|  7  |  UPDATE [OF 列名,...] |指定した列が更新された場合にだけトリガーを起動<br>複数のデータ操作文を指定することができる|
|  8  |  ON  |テーブルに対するデータ操作文が発行された時にトリガーを起動するのかを指定|
|  9  |  FOR EACH ROW  |複数行に対するデータ操作文が発行されるとき、各行ごとにトリガーが起動<br>指定しない場合は複数行に対するデータ操作文が発行されても、トリガーは一度だけしか起動されない|
|  10  |  WHEN  |指定された条件を満たす場合のみ、トリガーを起動するように設定するもの|

---
### トリガー作成
```sql
CREATE OR REPLACE TRIGGER トリガー名
    BEFORE INSERT or UPDATE ON テーブル名 FOR EACH ROW WHEN テーブル名.カラム1 IS NOT NULL
    BEGIN
        INSERT INTO テーブル名 values('1','INSERT',sysdate);
        if inserting then
            INSERT INTO テーブル名 values('2','INSERT',sysdate);
        elsif updating then
            INSERT INTO テーブル名 values('3','UPDATE',sysdate);
        else
            INSERT INTO テーブル名 values('4','DELETE',sysdate);
        end if;
    END;
```
---

### トリガー削除
```sql
DROP TRIGGER トリガー名
```
---

### トリガー有効、無効設定
```sql
--有効にする方法
ALTER TRIGGER トリガー名 ENABLE;

--無効にする方法
ALTER TRIGGER トリガー名 DISABLE;
```
---

### トリガー情報参照
```sql
SELECT * FROM トリガー名
```
---

# ビュー
・Viewは仮想テーブルでView作成時に定義したSELECT文が保存されているため、
　Viewに定義しておけば毎回複雑なクエリを実行せずにデータ抽出ができる
・ユーザから参照しやすいように各テーブルを加工しユーザに必要な部分だけ見せるようにできる
・テーブルの一部、複数テーブルの結合した物を１つのテーブルをして見せることができる
・実テーブルのデータへのアクセスを制限することができ、不用意な更新を防ぐことができる
・Viewの中で複雑な処理が行われているため、メモリ領域を圧迫してパフォーマンス低下させる可能性がある

---

### 作成

```sql
CREATE VIEW ビュー名 AS SELECT文;
```
---

### 削除

```sql
DROP VIEW ビュー名;
```
---

### 変更

```sql
ALTER VIEW ビュー名 AS SELECT文;
```
---

### 参照

```sql
--通常テーブル参照と同じ
SELECT * FROM ビュー名;
```
---

### 詳細情報確認

```sql
--ビューの作成日時、定義しているSELECT文等を確認できる
SELECT * FROM views WHERE table_name = 'ビュー名';
```
---

### 更新

```sql
--通常テーブル登録、更新、削除と同じ
UPDATE ビュー名 SET カラム1='A' WHERE句;
```
下記条件の場合、登録、更新、削除できない
・ビューの定義に集約関数を含む。（集約値なので直接変更できない）
・ビューの定義にGROUP BY句、HAVING句を含む。（同上）
・複数の表を結合している。（複数表の結合なので直接変更はできない）
・副問合せで同一の表を参照している。（変更する行を特定できない）
・DISTINCTを利用している。（変更する行を特定できない）
・ビュー定義時にWITH READ ONLYの指定をしている。（読み取り専用）

---
STM32G071で時計。(DS1307)(シリアル出力)(NUCLEO-G071RB)


目的
DS1307のテスト

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり


![o_con799.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/927d81cb-d0f5-710e-e91e-3cd0c5dc1897.jpeg)


![o_con800.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/500e859b-aedb-1324-a48d-f09ec95109c0.jpeg)


参考


https://qiita.com/caa45040/items/34ad44ef53ecfb851a93



STM32F767のプログラムと完全に同じ



```c++



#include <Wire.h>

// デバイスアドレス(スレーブ)
#define ADDR    0x68    // 2進数 1101000

int u_key;      // 受信データを格納するchar型の変数
int ch_in_key() {

  // 受信データがあった時だけ、処理を行う
  while(!Serial.available()) {}       // 受信データがあるか？
  u_key = Serial.read();            // 1文字だけ読み込む

  return(u_key);
}

int  ch_i;      //文字列のループカウンター
char ch_b[8+1]; //文字列のバッファー
int  ch_y;      //一文字分の一時バッファー

void ch_input()
{
    ch_i=0;
    while(1) {
        ch_y = ch_in_key();
        if(ch_y == 13){ch_b[ch_i]=0;Serial.println();break;}
        ch_b[ch_i]=ch_y;ch_i++;
        Serial.write( ch_y );
        if(ch_i >= 8){ch_b[ch_i]=0;Serial.println();break;}     
    } //while
} //ch_input

char ch_hex_b[3];
char *ch_hex(int l_num)
{
    ch_hex_b[0] = '0' + (l_num >> 4);
    ch_hex_b[1] = '0' + (l_num & 0xf);
    ch_hex_b[2] = 0;
    return(ch_hex_b);
}

void setup() {
  Serial.begin( 9600 );     // シリアル通信を初期化する。通信速度は9600bps

  // マスタとしてI2Cバスに接続する
  Wire.begin();

}

int h;
int m;
int a;
int b;

int p_val;
char data_read[16];
char cmd[2]={0,0};
int ii;     //ループカウンタ

void loop() {

///*INIT start *********  

    Serial.println( "" );  //改行

    Serial.print("H 0-23>");
    ch_input();         //文字列の入力
    h=atoi(ch_b);

    Serial.print("M 0-59>");
    ch_input();         //文字列の入力
    m=atoi(ch_b);

    a=(m/10)*16+(m%10);
    b=(h/10)*16+(h%10);

      // I2Cスレーブに対して送信処理を開始する
  Wire.beginTransmission(ADDR);

    // レジスタのアドレスを指定する(0-63の内、先頭から)
    Wire.write(0x00);

    // ---------------------------------
    //  タイマーキーパーレジスタ
    // ---------------------------------
    // 2進化10進数(BCD)で指定します。(03以外)

    // [00]Seconds(45秒)
    Wire.write(0);
    // [01]Minutes(59分)
    Wire.write(a);
    // [02]Hours(23時)
    Wire.write(b);
    // [03]Day(月)
    // 1:日 2:月 3:火 4:水 5:木 6:金 7:土
    Wire.write(3);
    // [04]Date(31日)
    Wire.write(1);
    // [05]Month(12月)
    Wire.write(1);
    // [06]Years(2017年)
    Wire.write(0x20);

  // I2Cスレーブへの送信完了
  Wire.endTransmission();

//*/  //INIT end *********

while(1){

  // レジスタのアドレスを先頭にする
  Wire.beginTransmission(ADDR);
    Wire.write(0x00);
  Wire.endTransmission();

  // I2Cスレーブに8byteのレジスタデータを要求する
  Wire.requestFrom(ADDR, 8);

  // 8byteのデータを取得する
  for (ii = 0; ii < 8; ii++) {
    while (Wire.available() == 0 ) {}
    data_read[ii] = Wire.read();
  }


        ii=2;
        while(1){
            Serial.print(ch_hex(data_read[ii]));
            ii--;
            if(ii==-1){break;}else{Serial.print(":");}
        }
        Serial.println("");


  delay(1000);

}//while

} //loop




```
Arduino UNOで時計。(DS1307)(シリアル出力)


目的
DS1307のテスト


1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり





![o_con797.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b8c1778a-b551-3d26-e102-a2cc722cf099.jpeg)


![o_con798.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a9700b98-962c-03fe-cc29-e011470c54d0.jpeg)






参考


https://qiita.com/caa45040/items/34ad44ef53ecfb851a93


STM32F767のプログラムと完全に同じ



```c++



#include <Wire.h>

// デバイスアドレス(スレーブ)
#define ADDR    0x68    // 2進数 1101000

int u_key;      // 受信データを格納するchar型の変数
int ch_in_key() {

  // 受信データがあった時だけ、処理を行う
  while(!Serial.available()) {}       // 受信データがあるか？
  u_key = Serial.read();            // 1文字だけ読み込む

  return(u_key);
}

int  ch_i;      //文字列のループカウンター
char ch_b[8+1]; //文字列のバッファー
int  ch_y;      //一文字分の一時バッファー

void ch_input()
{
    ch_i=0;
    while(1) {
        ch_y = ch_in_key();
        if(ch_y == 13){ch_b[ch_i]=0;Serial.println();break;}
        ch_b[ch_i]=ch_y;ch_i++;
        Serial.write( ch_y );
        if(ch_i >= 8){ch_b[ch_i]=0;Serial.println();break;}     
    } //while
} //ch_input

char ch_hex_b[3];
char *ch_hex(int l_num)
{
    ch_hex_b[0] = '0' + (l_num >> 4);
    ch_hex_b[1] = '0' + (l_num & 0xf);
    ch_hex_b[2] = 0;
    return(ch_hex_b);
}

void setup() {
  Serial.begin( 9600 );     // シリアル通信を初期化する。通信速度は9600bps

  // マスタとしてI2Cバスに接続する
  Wire.begin();

}

int h;
int m;
int a;
int b;

int p_val;
char data_read[16];
char cmd[2]={0,0};
int ii;     //ループカウンタ

void loop() {

///*INIT start *********  

    Serial.println( "" );  //改行

    Serial.print("H 0-23>");
    ch_input();         //文字列の入力
    h=atoi(ch_b);

    Serial.print("M 0-59>");
    ch_input();         //文字列の入力
    m=atoi(ch_b);

    a=(m/10)*16+(m%10);
    b=(h/10)*16+(h%10);

      // I2Cスレーブに対して送信処理を開始する
  Wire.beginTransmission(ADDR);

    // レジスタのアドレスを指定する(0-63の内、先頭から)
    Wire.write(0x00);

    // ---------------------------------
    //  タイマーキーパーレジスタ
    // ---------------------------------
    // 2進化10進数(BCD)で指定します。(03以外)

    // [00]Seconds(45秒)
    Wire.write(0);
    // [01]Minutes(59分)
    Wire.write(a);
    // [02]Hours(23時)
    Wire.write(b);
    // [03]Day(月)
    // 1:日 2:月 3:火 4:水 5:木 6:金 7:土
    Wire.write(3);
    // [04]Date(31日)
    Wire.write(1);
    // [05]Month(12月)
    Wire.write(1);
    // [06]Years(2017年)
    Wire.write(0x20);

  // I2Cスレーブへの送信完了
  Wire.endTransmission();

//*/  //INIT end *********

while(1){

  // レジスタのアドレスを先頭にする
  Wire.beginTransmission(ADDR);
    Wire.write(0x00);
  Wire.endTransmission();

  // I2Cスレーブに8byteのレジスタデータを要求する
  Wire.requestFrom(ADDR, 8);

  // 8byteのデータを取得する
  for (ii = 0; ii < 8; ii++) {
    while (Wire.available() == 0 ) {}
    data_read[ii] = Wire.read();
  }


        ii=2;
        while(1){
            Serial.print(ch_hex(data_read[ii]));
            ii--;
            if(ii==-1){break;}else{Serial.print(":");}
        }
        Serial.println("");


  delay(1000);

}//while

} //loop





```
【Rails】Rails6系にアップデートしたらテストでbut rendering with <["rescues/blocked_host", "rescues/layout"]>というエラーが出た【minitest】

# どうした？
ある程度開発を進めたタイミングでRailsのバージョンを5系から6系へアップしたところ、テストでエラーが出ました。

# 環境
```terminal
$ ruby -v
=> ruby 3.1.2p20

$ rails -v
=> Rails 6.1.7
（アップデート前: 5.2.8.1）
```

# 事象
minitestにて
```
get "/"
assert_template "home/top"
```
の結果
```terminal
expecting <"home/top"> but rendering with <["rescues/blocked_host", "rescues/layout"]>
```
と返ってきました。
もちろんバージョンアップ前はするすると通っていたテストですし、ローカルサーバー上でも問題ありません。

# 解決策

[参照元]((https://qiita.com/Mackey3510/items/7bfaa0b42782de40bc30))の解決策①を試しましたが、テストでのエラーは解決しませんでした。
そこで、`config/enviroments/test.rb`にも同様の対処をしたところ、テストはGREENになりました。

```ruby:config/enviroments/test.rb
Rails.application.configure do
  #省略
  config.hosts << "www.example.com"
  #省略
end
```

## 考察
参照元の通り、ホストの指定をすることでテストがwww.example.comへのアクセスを許可しているようです。
参照元では解決策②としてテスト実行時にテスト環境を使うようにしていますが、私の事象の場合はテスト時はテスト環境が動いているようです。
よって私の事象の場合、解決策②は不要だと考えられます。
（そもそもDockerではない。）

# 参照

[Rails統合テストでDRb::DRbRemoteErrorにハマった話](https://qiita.com/Mackey3510/items/7bfaa0b42782de40bc30)
yq v4 を使って YAML から値を取得したり、値を挿入した時のメモ

[yq](yq) v4 を使って YAML から値を取得したり、値を挿入した時のメモ

# 環境

```
$yq --version
yq (https://github.com/mikefarah/yq/) version 4.27.5
```

[インストール](https://github.com/mikefarah/yq/#install) は Mac を使っているので `brew install yq` でインストールした

v3 と v4 は使い方がかなり変わっているようで以下に差異がまとまっているので注意

[Upgrading from V3](https://mikefarah.gitbook.io/yq/upgrading-from-v3) 

自分は最新の v4 で検証した

# 使ってみる

以下を見ながら使う

[Quick Usage Guide](https://mikefarah.gitbook.io/yq/#quick-usage-guide)

## Read a value

以下のような YAML があるとする

```test.yaml
Samples:
- name: satoshi
  topics: CV Debuted
- name: tsumoto
  nickname: gyopa-
```

上記から `satoshi` を取得したい場合、以下のように記述する

```
yq '.Samples[0].name' test.yaml
```

## Update a yaml file, inplace

先ほどの `satoshi` という名前を `ryoma` に変えてみる

```
yq '.Samples[0].name = "ryoma"' test.yaml
Samples:
  - name: ryoma
    topics: CV Debuted
  - name: tsumoto
    nickname: gyopa-
```

OK

`-i` オプションを使えば、ファイルの上書きする(`-i` なしの場合、`test.yaml`　は変更なし)

```
yq -i '.Samples[0].name = "ryoma"' test.yaml

cat test.yaml
Samples:
  - name: ryoma
    topics: CV Debuted
  - name: tsumoto
    nickname: gyopa-
```

## Update using environment variables

先ほどの例では固定の名称を指定していたが、環境変数を利用したい場合、`strenv` を使う

```
# NAME という環境変数に mike を指定
export NAME=mike

# 確認
echo $NAME
mike

# 環境変数を使って変更
yq '.Samples[0].name = strenv(NAME)' test.yaml
Samples:
  - name: mike
    topics: CV Debuted
  - name: tsumoto
    nickname: gyopa-
```

## 追加する

YAML の特定箇所に値を追加する場合、挿入箇所を指定して値を設定すれば OK

```
yq '.Samples[0].year = "2022"' test.yaml
Samples:
  - name: ryoma
    topics: CV Debuted
    year: "2022"
  - name: tsumoto
    nickname: gyopa-
```

実行したコマンドの結果を入れる場合、`strenv` を使って以下のようにすれば OK

```
DATE=`date` yq '.Samples[0].date = strenv(DATE)' test.yaml
Samples:
  - name: ryoma
    topics: CV Debuted
    date: Sun Sep 25 06:24:44 JST 2022
  - name: tsumoto
    nickname: gyopa-
```
ありそうでないWeb部品: リング状プログレスUIとその応用例としてのポインター長押し判定えぐざんぷる

# リング状プログレスUI

⇩これ
![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33891/471ef8ce-5dbd-aae2-ffa7-096eb1209d29.gif)

今回は⇧これを Web Component で作って、その応用例としてのポインター長押し判定も雑に書いてみたところ、とりあえず期待通りに動作するものはできたのでそのメモ。

# CodePen

https://codepen.io/usagi-network/pen/gOzXOVp

<p class="codepen" data-height="300" data-theme-id="dark" data-default-tab="html,result" data-slug-hash="gOzXOVp" data-user="usagi-network" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/usagi-network/pen/gOzXOVp">
  progress-ring web-component usagi ver.</a> by Usagi Ito (<a href="https://codepen.io/usagi-network">@usagi-network</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# 作り方

## `ProgressRing` (=`<progress-ring>`)

1. `class ProgressRing extends HTMLElement` で Web Component のクラスを定義
1. うまいこと `innerHTML` に `<svg>` でそれっぽいUIを作る
1. そのままだと `createElement` や `setAttribute` に対応できないので、HTMLで静的にタグを定義するほかに ES で動的に作って弄れるように 
  1. `static get observedAttributes()` と 
  1. `attributeChangedCallback(name, _old_value, new_value)` を定義
1. `<svg>` の `<circle>` の `r` 属性は read-only なのでこれの更新が必用になる場合(`stroke`や`radius`が変更された場合)はルート要素内部の `innerHTML` をごっそり `this.regenerate()` しちゃう仕組みに調整
1. `opacity` `transform` `transition` で簡単な演出を仕込む

## `ProgressRing` を応用した「ポインター長押し判定」

1. `pointerdown(e)` & `begin_ring({...})` で判定時間や完了時/キャンセル時のファンクターなどパラメーターを受け取りつつ、
  1. `let pr = <progress-ring>` を生成
  1. `let begin = new Date().getTime()` で開始時刻を保持
  1. `requestAnimationFrame` で `pr` に `begin` からの経過時間と判定時間から完了までの進捗を `setProgress`
  1. キャンセル処理用に `pr` に `let cancelation = false` ステートをキャプチャーした `.cancel()` を追加して `return`、呼び出し元側で `.cancel()` をトリガー可能に
    1. 同様に `begin_ring` 側で移動距離によるキャンセル判定用に初期の `x` `y` を `pr.initial_position` に追加で保持させています
1. `pointerup(e)` で、
  1. `.cancel()`
1. `pointermove(e)` で
  1. `pr.initial_position` `e.x`, `e.y` から移動距離が一定以上か判定して
  1. `.cancel()`

## おまけ

できた表示を見ていたらアニメの演出とかでありがちな「たくさんロックオン！」みたいな絵もこれで再現できちゃいそうなので遊んでみました。中ボタン押しで⇩こうなります。

![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33891/14dd91a8-8946-247e-b46c-1e9698cb542f.gif)


# 参考

- https://css-tricks.com/building-progress-ring-quickly/
  - `<ring-progress>` の基本的な実装はこの記事を原型にしています。🙏
-
【Python】matplotlibを使うならとりあえず読むべき記事

## 背景
- matplotlibの理解を深めるのにすごく役に立った記事をまとめておく。（自分用としても）

## 目標
- 紹介している記事を読んでmatplotlibへの理解を深める。

## matplotlibの理解に役立った記事たち
- matplotlibの基本概念がざっとわかる、最初の方の流し読みだけでもいいので読むべき。

https://qiita.com/nkay/items/d1eb91e33b9d6469ef51

- 上の記事より、もうちょっと硬派な感じで詳細に解説してくれている記事。

https://qiita.com/skotaro/items/08dc0b8c5704c94eafb9

- 軸周りの設定解説の神記事。

https://www.yutaka-note.com/entry/matplotlib_axis

- MATLABスタイル（pltの書き方）の設定についての引数解説の神記事。

https://www.yutaka-note.com/entry/matplotlib_pyplot

- 以下、MATLABスタイルとオブジェクト指向スタイルの違いの理解に役立った記事達

https://qiita.com/renesisu727/items/24fc4cd8fa2635b00a0d

https://boul.tech/mpl-plot-style/

https://www.yutaka-note.com/entry/matplotlib_figure

https://minus9d.hatenablog.com/entry/2015/01/26/225731

- matplotlibの公式サイト
    必要に応じて読むべきサイト。
    時間がある時にサラッと眺めておくとmatplotlibの操作方法の引き出しが増えそう。

https://matplotlib.org/

- matplotlibの図表が一覧化されているQiita記事、これ書いた人すごい。

https://qiita.com/4m1t0/items/76b0033edb545a78cef5#%E7%AE%B1%E3%81%B2%E3%81%92%E5%9B%B3box-plot

- matplotlibのデフォルト設定値`rcParams`について解説された記事。

https://python-academia.com/matplotlib-rcparams/


## 補足
- 紹介した記事は実は、前の記事の参考資料なだけです。

https://qiita.com/takuma-1234/items/30b16386f89b3f15e392

## 参考資料

## 個人ブログ

https://takuma-tech.com/2022/09/27/184/
【Python】matplotlibのpltとaxの書き方の違いについて

## 背景
- pythonの可視化に使用されるライブラリとしてmatplotlibには、書き方がややこしく理解が難しい。
- 理解を難しくさせる要因として、そもそもmatplotlibの書き方の流儀的に2つの方法（pltとax）があることが挙げられる。
- matplotlibの可視化をサクッとできるようになるために自分なりに調べた知見をまとめておく。

## 目標
- matplotlibの2つの書き方について理解する。

## matplotlibに存在する2つの書き方
- 上記で述べたように、matplotlibには主に2つの書き方があるらしい。
- 公式でどのように呼ばれているかはわからないが、いくつかのサイトを調べたところ主に、「plt」を使用する書き方は、MATLABの書き方に似ているらしいのでMATLABスタイル、「ax」を使用する書き方は、オブジェクト指向の書き方なので、オブジェクト思考スタイルなどと呼ばれていた。

- matplotlibの2つの書き方
1. MATLABスタイル（pltを使用する方法）
2. オブジェクト指向スタイル（axを使用する方法）

## 両方の描画スタイルを比べてみる
- $y = x^2$の簡単なグラフを描画するプログラムで両方の描画スタイルを比較してみる。

> ```python:グラフ描画準備コード
>%matplotlib inline
>import matplotlib.pyplot as plt
>import numpy as np
> 
>x = np.linspace(-3,3)
>y = x**2
>```
>```python:1. MATLABスタイル（pltを使用する方法）
>fig = plt.figure() 
>plt.plot(x,y)
> 
>plt.show()
>```
>```python:2. オブジェクト指向スタイル（axを使用する方法）
>fig = plt.figure()
>ax = fig.add_subplot()
> 
>ax.plot(x,y)
> 
>plt.show()
>```
> 【プログラム引用】[Matplotlib plt.figure()を使う理由｜FigureとAxesの関係を把握しよう](https://www.yutaka-note.com/entry/matplotlib_figure)

※出力はどちらも以下のようになる。
> ![y^2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2651220/5378ba23-a629-1881-da24-82935b87400a.png)

- 上記の通り、簡単な描画では、1. MATLABスタイルの方が、コード量が少なくて済む。

## どちらの描画スタイルを使うべきか？
- 結論
    筆者は2. オブジェクト指向スタイル（axを使用する方法）を使っていった方が良いと考えている。
- 理由
    [このサイト](https://boul.tech/mpl-plot-style/)の方が述べられているようにオブジェクト指向で書いていった方が、微調整がしやすいから。

## 補足
どちらの描画スタイルを使うべきかは、上記の通りであるが、少し調べた感覚も書いておきたい。一応MATLABスタイルにもメリットはあり、単純な描画の場合だとMATLABスタイルの方が、コード量が少なくて良い場合もあるし、何より、オブジェクト指向スタイルより直感的だと思う。実際に筆者も無意識にMATLABスタイルを多用して可視化を行っていた。また、MATLABスタイルの方が、簡単なためか、初学者向けの解説記事や書籍でのサンプルコードも多いように感じる。ただ、機械学習や複数のグラフを描画する際にはオブジェクト指向で書かないと実現できないことが多そうだと思った。個人的に、できるだけ設定値が細かく設定できる書き方の方が好きだというのもあると思う。

## 参考資料
https://www.yutaka-note.com/entry/matplotlib_pyplot

https://www.yutaka-note.com/entry/matplotlib_figure

https://www.yutaka-note.com/entry/matplotlib_axis

https://boul.tech/mpl-plot-style/

https://minus9d.hatenablog.com/entry/2015/01/26/225731

https://qiita.com/nkay/items/d1eb91e33b9d6469ef51

https://qiita.com/skotaro/items/08dc0b8c5704c94eafb9

https://qiita.com/renesisu727/items/24fc4cd8fa2635b00a0d

## 個人ブログ

https://takuma-tech.com/2023/01/16/376/
【随時更新】プログラミング学習に役立つ解説ブログ＆サイトまとめ

## 背景
- 先日公開した以下の記事がとても好評だった。

https://qiita.com/takuma-1234/items/ec837143f41a73317cb2

- 公式サイトではないけど、めちゃくちゃわかりやすく解説してくれている個人ブログなども世の中にたくさんある。 
- 自分が勉強の際にお世話になっている公式ではないブログをまとめておく。

## 各種解説ブログ＆サイトまとめ
- note.nkmk.me
    Pythonのよく使うライブラリなどの使い方を解説しているブログ。
    あまりにも詳細に解説されているので、最初はPyhtonの日本の公式の団体か何かが解説しているのかと思ったレベル。
    Pythonの基本文法等で迷ったら大体ここの解説を見るとよく理解できる。

https://note.nkmk.me/python/

- YutaKaのPython教室
    個人的にmatplotlibの解説の充実度合いに驚愕した。
    ここの管理人さんぐらいmatplotlibで自由に解説できるようになりたい。

https://www.yutaka-note.com/

## 参考資料

## 個人ブログ

https://takuma-tech.com/2023/01/15/374/
Next.jsをElastic Beanstalkにデプロイする

Next.jsをElastic Beanstalkにデプロイする方法をまとめてみました。

## 1. Next.jsプロジェクト作成
まず`create-next-app`でNextjsプロジェクトを作成します。
今回はblogという名前で作成します。

```bash
npx create-next-app blog --ts
```

実行が完了するとblogという名前のディレクトリができているのでcdで移動します。
ディレクトリ内は以下のようになっていると思います。

```bash
ls -a
.  ..  .eslintrc.json  .git  .gitignore  README.md  next-env.d.ts
next.config.js  node_modules  package.json  pages  public  styles  tsconfig.json  yarn.lock
```

## 2. プラットフォームフックファイルの作成
次にプラットフォームフックファイルを作成します。
プラットフォームフックはアプリケーションをデプロイする際にデプロイプロセスの各フェーズで実行したいスクリプトを設定することができます。
ここでは詳細は省きますが気になる方はこちらの公式ドキュメントを参照してください。
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/platforms-linux-extend.html

以下を実行してファイルを作成します。

```bash
mkdir -p .platform/hooks/predeploy
touch .platform/hooks/predeploy/next_build.sh
```

作成したファイルを編集します。

```bash:next_build.sh
#! /bin/bash
npm install
npm run build
```

このスクリプトはElasticBeanstalkにデプロイした際に一緒に実行されます。
ファイルの作成が終わったら忘れずにgit commitしましょう。
コミットしていない変更はデプロイ時に反映されないので注意です！

```bash
git add .
git commit -m 'predeployフックを追加'
```

## 3. Elastic Beanstalkへデプロイ
準備ができたのでebコマンドを使ってデプロイしていきます。
まずはeb initで設定ファイルを作成します。

```bash
# .elasticbeanstalkディレクトリと、ディレクトリ内にconfig.ymlが作成されます
eb init

Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
(省略)
(default is 3): 9


Enter Application Name
(default is "blog"): blog
Application blog has been created.

It appears you are using Node.js. Is this correct?
(Y/n): Y
Select a platform branch.
1) Node.js 16 running on 64bit Amazon Linux 2
2) Node.js 14 running on 64bit Amazon Linux 2
3) Node.js 12 running on 64bit Amazon Linux 2 (Deprecated)
(default is 1): 1

Do you wish to continue with CodeCommit? (Y/n): n
Do you want to set up SSH for your instances?
(Y/n): Y

Select a keypair. # キーペアを用意していない場合は新しく作成してください
1) aws
2) aws-eb
3) aws_key
4) [ Create new KeyPair ]
(default is 3): 2
```
ここまで来たらようやくデプロイです！
eb createで環境を作成（デプロイ）します。


```bash
eb create
Enter Environment Name
(default is blog-dev): blog-dev
Enter DNS CNAME prefix
(default is blog-dev2): blog-dev2

Select a load balancer type
1) classic
2) application
3) network
(default is 2): 2


Would you like to enable Spot Fleet requests for this environment? (y/N): n
Creating application version archive "app-bf25-220925_025922039748".
Uploading blog/app-bf25-220925_025922039748.zip to S3. This may take a while.
Upload Complete.
Environment details for: blog-dev
CNAME: blog-dev2.ap-northeast-1.elasticbeanstalk.com
(省略)
```

デプロイが完了したら実行ログのEnvironment detailsに記載されているCNAMEにブラウザからアクセスします。
今回はblog-dev2.ap-northeast-1.elasticbeanstalk.comになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659625/38dca0a0-977d-43c6-358c-f489bf4a9c10.png)

Next.jsのデフォルトページが表示されました！
以上、Elastic Beanstalkへのデプロイ方法でした。
2022/9/25主にITとかセキュリティの記事

こんなパスワードを使ってませんか？ 「最前線の守り」を固めよう(9/23)
https://www.lifehacker.jp/article/2209-your-data-not-safe-using-these-passwords/

自動車向けサイバーセキュリティの市場規模は2032年に171億米ドルに達する見込み--最新予測(9/23)
https://newscast.jp/news/8042031

英政府、仮想通貨マネロンの取締りを強化する法案を提出(9/23)
https://coinpost.jp/?p=390467

「システム監視」の新常識　監視対象の激変で新手法続々(9/23)
https://business.nikkei.com/atcl/NBD/19/00109/00188/

ネット不正送金が急増　8月から、フィッシングか(9/22)
https://nordot.app/945662220975521792?c=768367547562557440

米国、国家安全保障の脅威リストに中国の通信会社追加 - スパイ行為の恐れ(9/23)
https://news.mynavi.jp/techplus/article/20220923-2460659/

苦渋の「さらばニッポン」　Web3頭脳、流出の危機 Web3　熱狂と不信（4）(9/23)
https://www.nikkei.com/article/DGXZQOUB07CVK0X00C22A9000000/

Meta、FBやInstagramでATT回避していたとして提訴される(9/23)
https://iphone-mania.jp/news-490036/

Discordで画面共有がうまくできないときの対処法(9/23)
https://news.mynavi.jp/article/20220923-2458924/

Azure環境でSNATポート枯渇を見つけるメトリックの見方(9/22)
https://ascii.jp/elem/000/004/106/4106229/?rss

MS、AWS、Googleも本格採用へ--プログラミング言語「Rust」の最新動向を振り返る(9/23)
https://japan.zdnet.com/article/35193608/

イラン中央銀行、CBDCのクリプト・リヤルの試験運用を開始(9/22)
https://jp.cointelegraph.com/news/iran-to-begin-crypto-rial-cbdc-trial-despite-possible-lack-of-infrastructure-report

ロシア政府高官、クロスボーダー決済に仮想通貨の利用を承認＝報道(9/23)
https://jp.cointelegraph.com/news/russian-officials-approve-use-of-crypto-for-cross-border-payments-report

Webページのスクリーンショットを取得する - デスクトップも対象に加える(9/23)
https://news.mynavi.jp/techplus/article/powershell_core_--217/

「スマート世界」の実現に必要な5．5G推進に向け「8つの提案」―ファーウェイ(9/23)
https://www.recordchina.co.jp/b901616-s25-c20-d0198.html
EKS Podにセキュリティグループを適用する

## はじめに

以前投稿した、prometheusのメトリクスを使ってHPAする際に、promethues-operaterは **`EC2`** に、sidekiq-exporterは **`Fargate上`** に存在し、インバウンドルールで通信が許可されていないので通信できないという状況になっていました。

https://qiita.com/ymktmk/items/090c8a32e059920a7370

**`EC2 -> Fargate`** へ通信するには「FargateのクラスターSG」 or 「PodにSecurityGroupPolicy」 のいずれかが必要です。しかし、FargateのクラスターSGの場合は全てのPodに対して9292番ポートの通信を許可してしまうのでPod単位で設定できる **`SecurityGroupPolicy`** が適しています。今回はSecurityGroupPolicyを正しく設定してEC2からFargateのPodへの通信を可能にしていきたいと思います。

## セキュリティグループ用の VPC CNI アドオンの設定

CNI プラグインのバージョンが 1.7.7より前の場合は、CNIプラグインをバージョン1.7.7以降に更新しなければなりません。以下のコマンドで確認してください。

```
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
```

`1.7.7以降でない場合` は以下の記事を読んで設定してください。　

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/managing-vpc-cni.html#updating-vpc-cni-add-on


CNI プラグインを有効にする。
```
kubectl set env daemonset aws-node -n kube-system ENABLE_POD_ENI=true
```

liveness probesやreadiness probesを使用している場合は、以下コマンドも必要らしい。
```
kubectl patch daemonset aws-node \
  -n kube-system \
  -p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'
```

## セキュリティグループを作成

今回はTerraformで構築しました。

```tf:
resource "aws_security_group" "security_group_policy_for_sidekiq_exporter" {
  name        = "security_group_policy_for_sidekiq_exporter"
  vpc_id      = module.vpc.vpc_id
}

resource "aws_security_group_rule" "accept9292" {
      security_group_id = aws_security_group.security_group_policy_for_sidekiq_exporter.id
      type              = "ingress"
      source_security_group_id = module.eks.node_security_group_id
      from_port         = 9292
      to_port           = 9292
      protocol          = "tcp"
}

resource "aws_security_group_rule" "out_all" {
      security_group_id = aws_security_group.security_group_policy_for_sidekiq_exporter.id
      type              = "egress"
      cidr_blocks       = ["0.0.0.0/0"]
      from_port         = 0
      to_port           = 65535
      protocol          = "-1"
}
```

## SecurityGroupPolicyの設定

Podに付与しているラベルをmatchLabelsにて指定する(私の場合は`app: sidekiq-exporter`)そして、groupIdsに作成したセキュリティグループのIDを指定してください。

```yaml:
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
  name: security-policy
  namespace: sidekiq
spec:
  podSelector:
    matchLabels:
      app: sidekiq-exporter
  securityGroups:
    groupIds:
      - sg-xxxxxxxxxxxxx
```

## まとめ

以上の設定で `EC2 -> Fargate` への通信が可能になりました。KubernetesマニフェストにセキュリティグループIDを直書きするのは辛いですがPod単位で通信の設定ができるのでセキュアになるかなと思います。

## 参考文献

https://qiita.com/MAKOTO1995/items/4e70998e50aaea5e9882

https://zenn.dev/karamaru/articles/97d7c6b79b7251

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/managing-vpc-cni.html#updating-vpc-cni-add-on

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/security-groups-for-pods.html
rails で slack command の request を受け取る

# 概要
- slack command など request end point を 設定する
- slack command request から data を取得
- slack command が投入された channel へ応答を返す
    - 別記事にて記述





# app / slasch command の設定
- slack app 設定画面を開く
    - https://api.slack.com/apps/
- [ craete new app ] を選択
    - [ from scratch ] を選択
    - [ app name ] へ名前を入力
    - [ work space ] を選択する
    - [ create app ] を選択
- [ slash command ] を開く
    - [ Create New Command ] を選択し, 以下を埋める
        ```
        - Command           : command 名を設定
        - Request URL       : rails の url path を設定  # http://rails.path/ など
        - Short Description : command の簡易説明を設定
        - Usage Hint        : command の使用方法などを設定
        ```
    - [ save ] を選択
- [ install app ] を左メニューから選択
    - [ install to workspace ] を実行
- slack を開く
    - 上記 command を適用する channel を開く
    - チャット入力欄の左下の `+` ボタンを選択
    - 検索欄へ `add` と入力
    - [ add apps to channel ] を選択
    - 先程登録した slach command を選択する

以上で slach command が channel へ有効化される





# interaction event 発生時の request URL を設定
command とは別に event 発生時の URL を設定可能.
event は, app が slack 上に投稿した message に付随する button を click した際などに発生する.

- slack app 設定画面を開く
    - https://api.slack.com/apps/
- [ Interactivity & Shortcuts ] を開く
- [ Ruquest URL ] を設定
- [ Save Changes ] を選択




# request data 取得 
以下2つの手法を上げる
- command
- interaction event

## command 
- slack から, 登録した command を実行
- rails へ request が届く
- 以下, params から取得できる data を抜粋

```
params["user_id"]       : 送信元 user id
params["user_name"]     : 送信元 user name
params["team_id"]       : team id
params["channel_id"]    : channel id   # 応答を返す際に用いる
params["api_app_id"]    : api app id
params["command"]       : 実行された command name
params["text"]          : command に続いて入力された text
```

得られる data は限定されている.
補足情報が必要な場合, 上記 text への入力が必要.





## interaction event
- slack から, app が作成した button などを click
- rails へ request が届く
- params['payload'] から request data を取得
    - json string のため, hash へ変換が容易
- 以下, payload から取得できる data を抜粋
```
payload["type"]        : event type
payload["user"]["id"]  : user id
payload["team"]["id"]  : team id
payload["api_app_id"]  : api app id
payload["message_ts"]  : bot が投稿した message の更新などにもちいる
```




## event type と payload 構造
- Shortcuts
    - こちらは使用したことないので, 不明
    - https://api.slack.com/reference/interaction-payloads/shortcuts
- block_actions
    - block message からの request
    - https://api.slack.com/reference/interaction-payloads/block-actions
- view_submission
    - modal からの request 
    - https://api.slack.com/reference/interaction-payloads/views

例えば, 複数の block_actions を作成する場合, type 以外の何らかの判別方法を組み込む必要があると思われる.


# channel へ応答を返す
前項で取得した, user_id, channel_id などが必要となる.

応答方法は以下記事へ
https://qiita.com/Satoshi_Numasawa/items/3fc9078beabff666280c




以上
Blender奮闘記⑧

# 初めに
前回yukiさんの動画を見ながらモンブランを作成しました。今回はそのおさらい結果となります。
# 作成経過
![1st.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782192/96c6b7f4-452f-06ad-cd83-db167d84857c.png)
前回はここまで2~3時間かかりましたが、今回は1時間程度でできました。どのようにしたら楽にできるかということと、シェーダーエディター上でどのノードを使用するとどうなるか理解が進んだ結果そこそこ早くできたのだと思います。

![Mont_Blanc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782192/232536f4-4b3a-008c-f1ff-d2ca7d6f10a4.png)
最終出力結果はこれです。
前回よりもきれいにできました。ぱっと見そこまで変化していないように見えるかもしれませんが、前よりも雑じゃなくなりました。

また、出来上がるまでの時間も大幅に減りました。良い傾向ですね。

# 終わりに
単純作業の繰り返しですが、こういうことの繰り返しが最終的に自身の身についてくる近道だと思っています。次は今回学んだ波テクスチャ、バンプを使用してブッシュドノエルを作りたいです。
![xmas-cake-001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782192/084b28bd-708b-eb00-a775-3221330f4d9a.png)

イメージはこれです。
加速度センサの鉛直方向の値を使って1歩判定してみた

# はじめに
屋内位置測位のPDR(歩行者自律航法)を使ったコードを書く上で1歩判定のコードを書いたので解説します.

# PDRとは
PDRは**Pedestrian Dead Reckoning**の略で
**Pedestrian**が歩行者、**Dead Reckoning**が自律航法という意味です.

**Dead Reckoning**とは[フルノ製品情報サイトより](https://e-words.jp/w/BLE.html)以下のような説明があります。
> ジャイロセンサーや加速度センサーなど、各種センサーからの情報と合わせて演算処理することにより、GPS(GNSS)単独では測位を続けることが難しい環境下でも、高い精度で測位できる技術がデッドレコニング(Dead Reckoning /自律航法)です。カーナビゲーションシステムでも多く活用されております。

センサ情報をもとに演算処理をすることで位置を求めるので、センサ情報の正確さが大事になります.

# 1歩判定
加速度センサの鉛直方向の値から1歩判定します.

### 概要
鉛直方向の出力は波のようになります.
![加速度センサ_鉛直方向.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747696/cdd5d042-b823-ae54-fbf1-16e2757fb03a.png)
この波の1周期で1歩という感じなので、この1周期の中の極大値か極小値を使えば、よさそうです.
仮に極大値にしきい値を設定すると
![しきい値.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747696/10f25dc9-8bc4-f3b5-8d58-a471834b928a.png)
このようになります.
このしきい値を超えた時に1歩判定します.

### 解説
```python
sikiti = 10.7
count = 0
not_first_pass = False
```
はじめに1歩判定用のしきい値を入れるsikiti、
何歩歩いたか数えるためのcount、
しきい値を超えたのが最初ではないと判定する用のnot_first_passを用意します.
```python
if i < sikiti:
    print("歩いていない")
else:
    if not_first_pass == True:
        print("歩いていない")
    elif not_first_pass == False:
        count += 1
        not_first_pass = True
        print(f"{count}歩目")
if not_first_pass == True and i < sikiti:
    not_first_pass = False
```
ここで1歩判定を行います.

```python
if i < sikiti:
    print("歩いていない")
```
最初のif文でしきい値を超えたか超えていないか判定します.

```python
else:
    if not_first_pass == True:
        print("歩いていない")
    elif not_first_pass == False:
        count += 1
        not_first_pass = True
        print(f"{count}歩目")
```
しきい値を超えていた場合、さらにif文で分岐します.

前回の値がしきい値以下で、今回の値がしきい値を超えた時に1歩とカウントするためです.
そのため、しきい値を超えた値が連続すると最初の値以外では1歩とカウントされないようになっています.

```python
if not_first_pass == True and i < sikiti:
    not_first_pass = False
```
そして、最後のif文で前回の値がしきい値以上で、今回の値がしきい値を下回ったにnot_first_passをFalseにします.

### 試しに
これですべての解説ができたので、

```python
num  = [10.6, 10.7, 10.8, 10.5, 10.4, 12.2]
```
試しにこのようなリストの値を用意して1歩判定させてみます.

```python
sikiti = 10.7
```
しきい値は10.7に設定したので、リストの3つ目の10.8と12.2で1歩判定するので、

```python
歩いていない
1歩目
歩いていない
歩いていない
歩いていない
2歩目
```
このように2歩と出力されます.


# おわりに
今回は1歩判定のコードについて解説しました.
鉛直方向の値だけを使った実装をしましたが、3軸センサであればもっと精度の高いコードがかけると思うので、機会があれば作ってみたいと思います.

ここまで読んでいただき、ありがとうございました.
【個人開発】Pubmed Trans：日本語で薬の名前を入力すると自動で英語論文を検索するWEBアプリを作りました【医師・薬剤師・MR向け】

# はじめに

こんにちは。
Qiita見る専を貫いていましたが、ついに初投稿。
今回は日本語の医療用医薬品名（商品名・一般名）を入力したら
自動で英語一般名に変換し、文献を検索してくれるWEBアプリを作りました。
医師や薬剤師、MRに使ってもらえたら嬉しいです。


# サービス生み出しの背景

病院で処方される薬剤は、2つの名前を持っています。

①一般名　②商品名と言われ、医薬品の文献（データ）を探す際には、
日本語で①一般名　②商品名入力しても文献サイトでヒットしません。
①の一般名を英語に変換して検索しなければヒットしないのです。。。

（誰も英語の名前なんて覚えていないし、英語に変換する時間もったいない）

自分の業務効率化させたいなぁと
その意気込みだけで作成に至りました:open_hands:



# サービス概要

[PubmedTrans](https://pubmedtrans2.herokuapp.com/cms/list/ "PubmedTrans")

https://pubmedtrans2.herokuapp.com/cms/list/

![pub medtransmini.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2866856/3b52d6c2-8803-16ff-4bf5-f15e4c50f6bc.png "PubmedTrans")
 

＜内容＞
医療用医薬品の名前を日本語でを入力すれば自動で英語に変換し、Pubmedで検索を行う

（例）　同じ薬剤だが、呼び名が変わってくる
一般名：スボレキサント
商品名：ベルソムラ
英語名：Suvorexant

実際に、論文が多数登録されているPubmedで「ベルソムラ」「スボレキサント」と日本語で調べてもヒットは０件。
Suvorexantで検索しないとヒットしない。


# 機能

＊and検索可能
*疾患名（英語）　＋　薬剤名（日本語）での検索可能


# 使用技術について
エンジニアスクールで教えてもらっていたPythonベースに
Djangoで作成をしました。

＊APIというものがよくわからなかったので、PubmedAPIを実装する上で下記のサイトはとても参考になりました。

https://www.y-shinno.com/pubmed-api/

https://qiita.com/iwashi-kun/items/bd0d772c6db0c0023e30






# 追加の要望

https://ayanoportfolio5.herokuapp.com/top/

ポートフォリオのお問合せフォームから薬剤追加の要望やバグについてなどいただけたら嬉しいです。
よろしくお願いいたします。


# 終わりに
まだまだ駆け出しですが、Qiitaでたくさんの知識を学ばせてもらっています。

基本的に生み出すアプリの99％はクソアプリですが、
今回作ったのは残りの1％に該当するちょっと役に立つほうのサービスでした。

これからもどんどん新しいサービスを作っていきたいなと思っておりますが、
少しでもサービスに興味を持ってもらえたら幸せです。
【統計】標準化と正規化の応用シーンの違い

データの前処理する時、よく標準化と正規化をどちら使うか困ったりするので、
自分の経験と感想を軽く整理してメモします。

## 標準化とは?
標準化(Standardization)とは元のデータ集合がどのような分布でも、
「平均値0、標準偏差1」の分布にする変換です。
```math
z_i = \frac{x_i-\bar{x}}{s}
```
$x_i:$ 元のデータ
$\bar{x}:$ 元のデータの平均
$s:$ 元のデータの標準偏差


## 正規化とは?
正規化(Normalization)とは元のデータ集合を「0~1」に抑える変換です。
```math
x_i' = \frac{x_i-x_{min}}{x_{max}-x_{min}}
```

## 使うシーン
簡単に言うと
#### 1. データの分布を知りたい時は標準化(Standardization)を使います
例えば、クラスのある生徒Chenの英語成績を調査するとします。
満点が100点の中、60点は低いと思うかもしれないですが、
本当は標準化の分布を見ないとわからないですね。

| 科目 | 名前 | 成績(標準化前) |成績(標準化後) 
|:-----------:|:------------:|:------------:|:------------:|
| 英語       | Bob        | 40         |-1.22|
| 英語     | James      | 53       |-0.08|
| 英語       | Kevin        | 44         |-0.87|
| 英語         | Tanaka          | 55     |0.08|
| 英語       | Sato       | 72       |1.56|
| 英語    | Chen     | 60      |0.52|

Chenの成績(標準化後)を見たら、0.51は低くないことがわかります。
データが少ない場合は目で判断しても問題ないですが、多くなると標準化を使った方が楽ですね。

#### 2.特徴量の影響を抑えたい時は正規化(Normalization)を使います
例えば、住宅価格を予測するとします。
| 部屋数 | 築年数 | 最寄り駅までの距離(m) |価格(万円)|
|:-----------:|:------------:|:------------:|:------------:|
| 1       | 2        | 1000         |10|
| 2     | 5      | 3500       |7.5|
| 2       | 17        | 5000         |6|
| 3         | 15          | 800     |10.5|
| 2       | 12       | 2000       |9|
| 1    | 8     | 3000      |6.5|

仮に、住宅価格を予測する計算式(適当)が以下のようなものであれば、
$住宅価格 = 10\times部屋数 + 20\times築年数 + 20\times最寄り駅までの距離 + 5$
この場合、最寄り駅までの距離の影響が他の特徴より大きいから、正確に予測できなくなる可能性があります。
こんな時は、各特徴を正規化して、同じ0~1の範囲に抑えたら解決できます。
(計算を略します、、)

## 結論
1. あるデータの分布の興味ある時、標準化を使います。
2. 特徴量の影響を抑える時、正規化を使います。