OmniAICreator/Qiita-1.07M huggingface dataset:
GitLab Pagesと本番サイトの双方にJekyllで生成されたページをデプロイする

[GitLab CI/CD]:https://www.gitlab.jp/stages-devops-lifecycle/continuous-integration/
[GitLab Pages]:https://docs.gitlab.com/ee/user/project/pages/
[Jekyll]:http://jekyllrb-ja.github.io/
[lftp]:https://github.com/lavv17/lftp

[GitLab CI/CD] を使って、GitLab.com 上で管理しているリポジトリから [Jekyll] を使って静的なサイトを構築し、
ドラフト版（`master`以外）は [GitLab Pages] で、
本番（`master`）は外部のサイト （FTPS接続を受け付けている） で公開するという運用をしています。

この場合に注意することをメモします。

## ポイント

1. GitLab Pages で公開される URL はプロジェクト名から自動生成されるため、本番サイトとルートの場所が違う構成になる場合がある。その場合は[baseurl](https://docs.gitlab.com/ee/user/project/pages/getting_started_part_one.html#urls-and-base-urls) 設定をコマンドライン引数（例: `--baseurl "/"`)により変更してビルドを分ければ良い。コマンドライン引数による設定は、`_config.yml` による設定よりも優先される。
1. とりあえず、Docker Image としては、Ruby 公式を使えば良さそう。この Docker Image では `apt` が使えるので、必要なライブラリなどは `apt-get` でインストールできる。
1. 本番サイトへのアップロード手段としてFTP, FTPS, SFTPなどが使えるのであれば、[lftp] を使うのが比較的簡単。このパッケージはデフォルトでは入っていないので、CIのレシピ中でインストールする。
1. 毎回、Bundler を再構成していると無駄が多いので、キャッシュを使うと良い<br>参考: [Create a GitLab Pages website from scratch](https://gitlab-docs.creationline.com/ee/user/project/pages/getting_started/pages_from_scratch.html#build-faster-with-cached-dependencies)
1. `.gitlab-ci.yml` に直接FTPパスワードを書くのはセキュリティ上推奨できないので、環境変数を使うと良さそう。<br>参考: [GitLab CI: Deploy to FTP / SFTP with lftp](https://savjee.be/blog/gitlab-ci-deploy-to-ftp-with-lftp/)

TODO: インクリメンタルビルドを使ってJekyllのサイト構築の時間を減らせる可能性があるが、キャッシュを使っても今の所想定通りの動作にならない。

## 使っている `.gitlab-ci.yml` の内容

```
image: ruby:latest

variables:
  JEKYLL_ENV: production
  LC_ALL: C.UTF-8
  # DST_DIR is used to set root directory for HTTP(S) service.
  DST_ROOT: www/jk
  # DST_DIR is used as base-url, it might be '/'.
  DST_DIR: /

cache:
  paths:
    - vendor/
    - dist/
    - .jekyll-metadata

before_script:
  - bundle install --path vendor
  - apt-get update -qy
  - apt-get install -y git-restore-mtime  

pages:
  stage: deploy
  script:
    - /usr/lib/git-core/git-restore-mtime
    - bundle exec jekyll build -I -d public
  artifacts:
    paths:
    - public
  except:
  - master

build_pages:
  stage: build
  script:
    #- ls -l dist/
    - /usr/lib/git-core/git-restore-mtime
    - bundle exec jekyll build -V -I -d dist --baseurl "$DST_DIR"
    #- ls -l dist/
  only:
  - master

upload:
  stage: deploy
  script:
    - date
    #- ls -l dist/
    - apt-get install -y lftp
    - lftp -e "set ftp:ssl-allow yes; open $FTP_SERVER; user $FTP_USERNAME $FTP_PASSWORD; mirror -X .* -X .*/ --reverse --only-newer --verbose dist/ $DST_ROOT$DST_DIR; bye"
  only:
  - master
```

- `master` 以外のブランチでは Job `pages` で GitLab Pages 向けのデータをビルドします。
- `master` ブランチでは Job `build_pages` でデータの生成を行い、 `upload` で本番環境にアップロードしています。
- 対象のサーバが FTPS に対応していない場合は、 `set ftp:ssl-allow no` に変更してご利用下さい。
Elixir Image で簡単動画再生

## はじめに

先日記事を書いた Image モジュールを使って、 Livebook 上で動画を再生します

https://qiita.com/RyoWakabayashi/items/aa61860882b106f956ff

https://github.com/elixir-image/image

https://livebook.dev/

Image モジュールの動画関連処理は内部的に evision を使っています

https://github.com/cocoa-xu/evision

## 実行環境

- Elixir: 1.14.2 OTP 24
- Livebook: 0.8.1

以下のリポジトリーの Docker コンテナ上で起動しています

https://github.com/RyoWakabayashi/elixir-learning

:::note info

Docker が使える環境であれば簡単に実行できます

https://docs.docker.com/engine/install/

Docker Desktop を無償利用できない場合は Rancher Desktop を使ってください

https://rancherdesktop.io/

:::

### 実行環境の注意点

Image (Vix) を使うためには libvpc が必要です

また、 evision の動画関連処理を実行するためには、 FFmpeg をインストールしてからビルドする必要があります

Ubuntu　の場合は以下のモジュールを `apt-get install` してください

- unzip
- ffmpeg
- libavcodec-dev
- libavformat-dev
- libavutil-dev
- libswscale-dev

## 事前準備

適当な動画を以下のパスに用意したものとします

- /tmp/sample.mp4 （なんでも良い）

## セットアップ

必要なモジュールをインストールします

```elixir
Mix.install(
  [
    {:image, "~> 0.23"},
    {:evision, "~> 0.1"},
    {:req, "~> 0.3"},
    {:kino, "~> 0.8"}
  ],
  system_env: [
    {"EVISION_PREFER_PRECOMPILED", "false"}
  ]
)
```

環境変数 `EVISION_PREFER_PRECOMPILED` に `false` を指定することで、 evision をソースからコンパイルするよう指定しています

evision のコンパイルには非常に時間がかかるため、30分程度待ちます

## 動画の読込

`Image.Video.open` で動画ファイルを開きます

```elixir
video = Image.Video.open!("/tmp/sample.mp4")
```

`Image.Video.image_from_video` で動画内の1フレームを静止画として取得できます

オプションとしてフレーム番号とミリ秒単位での時間を指定できます

```elixir
frame = Image.Video.image_from_video!(video, frame: 0)

Image.Kino.show(frame, max_height: 400)
```

![frame_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/02054dd6-9c9c-15b3-0ea1-1ada639e5bba.png)

```elixir
frame = Image.Video.image_from_video!(video, millisecond: 3_000)

Image.Kino.show(frame, max_height: 400)
```

![frame_3000ms.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/c4ad5ac8-a46b-a9f2-7198-de1511defe2a.png)

オプションを指定しない場合は前回読んだフレームの次のフレームを読み込みます

```elixir
frame = Image.Video.image_from_video!(video)

Image.Kino.show(frame, max_height: 400)
```

![frame_next_from_3000ms.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/d048dc27-2214-fdfa-2d66-901a51831abe.png)

`Image.Video.stream` で動画ファイルを開くことで、各フレームを列挙型として扱えます

また、 `frame` や `millisecond` で範囲を指定することができます

というわけで、以下のコードで Livebook 上で動画が再生できます

```elixir
"/tmp/sample.mp4"
|> Image.Video.stream!(frame: 0..-1)
|> Kino.animate(0, fn frame, counter ->
  if frame do
    frame
    |> Image.Kino.show(max_height: 400)
    |> then(&{:cont, &1, counter + 1})
  else
    :halt
  end
end)
```

![video.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/3196c3a3-68e9-43fe-7417-faefad6799e8.gif)

## まとめ

かなり短いコードで簡単に動画が読み込めました

次は動画を加工してみましょう
docker – mysql コマンドでローカルから接続できない ( Can't connect to local MySQL server through socket '/tmp/mysql.sock'  )

# エラー

```
$ mysql -u root -P 9999
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```

# docker-compose.yml

```yaml
version: '3'
services:
  db:
    image: mysql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
    ports:
      - "9999:3306"
```

# 解決

ホストを指定したら接続できた ( `-h 127.0.0.1 ` )

```
$ mysql -h 127.0.0.1 -u root -P 9999

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.32 MySQL Community Server - GPL

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
.envを1Passwordから生成する

1passwordに保存したシークレットな情報を利用して、.envに吐き出すまでのメモ

## 準備
1password CLIをインストール

```
% brew install --cask 1password/tap/1password-cli

# signinしておく
% op signin
```

## 手順
### 1passwordにシークレットな情報を保存

```bash
% SECRET_TITLE="awesome-app-env"
% op item create --category=login --title=$SECRET_TITLE
% op item edit $SECRET_TITLE MY_SECRET_TOKEN="SECRET_XXXXXXXX"
% op item edit $SECRET_TITLE MY_SECRET_API_KEY="SECRET_XXXXXXXX"
```

アプリを見るとこうなってる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3442/0f1ba0da-8f77-a57f-2aa0-e717027ebff7.png)

### .env.template生成

```bash
% op item get --format json $SECRET_TITLE | \
  jq -r '.fields[] | select(.value) | (.label) + "=\"" + (.reference) + "\""' > \
 .env.template
```

こんなのが生成される

```.env.template
MY_SECRET_TOKEN="op://Private/awesome-app-env/Section_lujpp2wyyprr3gxxxxxxxxx/MY_SECRET_TOKEN"
MY_SECRET_API_KEY="op://Private/awesome-app-env/Section_lujpp2wyyprr3gxxxxxxxxx/MY_SECRET_API_KEY"

```

### .envに書き出し

```bash
% op inject -i .env.template -o .env
```
FESS で Testlink をクロールする

FESS で Testlink のテストケースをクロールする方法

* データストアで MySQL DBをクロールします。
* Testlink DBにアクセス出来るユーザーが必要です。

* ハンドラー名	DatabaseDataStore

# パラメーター

```Parameter.
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://DBホスト:3306/testlink?serverTimezone=JST&useUnicode=true&characterEncoding=UTF-8
username=DBAdmin
password=DBAPass
sql=select h1.id as iid, tc.tc_external_id as eid, h1.name as title, tc.summary as summary, tc.preconditions as precond from nodes_hierarchy h1, nodes_hierarchy h2, nodes_hierarchy h3, tcversions tc where h2.parent_id=h1.id and h3.parent_id=h2.id and tc.id=h2.id
```
* DBホスト、User/Password は使用環境に合わせてください
* このSQLでテストケースのタイトル/サマリー/前提条件をクロールしています
 テストステップと期待結果は含めていません
* IDとしてテストケースの内部IDを得ています
* serverTimezone=JST は my.ini で Timezone を指定してれば不要です

# スクリプト

```script.
url="https://Testlinkサーバーアドレス/testlink/lib/testcases/archiveData.php?&edit=testcase&id=" + iid
host=" https://Testlinkサーバーアドレス/"
site="https://Testlinkサーバーアドレス/testlink/"
title="【Testlink】" + title
content=summary
cache=summary
digest=title
anchor=
content_length=content.length()
last_modified=new java.util.Date()
```

* Url: は Testlink サーバーを指定します
* 検索結果を選択すると、テストケースの編集画面が開きますが実際に編集は出来ません
VSCodeでターミナルを叩く度にGitHubの認証窓が出る場合は「github.gitAuthentication」を消すと解決した

## 経緯

ターミナルを叩く度にこれが出てきて困る

![image (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264910/990616ab-ccbb-7c15-b0a4-0086b9a8741a.png)



## VSCodeの設定

VSCodeの`settings.json`から以下の設定を削除すると直った

```
  "github.gitAuthentication": false
```
node.jsでGZIP圧縮された複数のログファイルを処理

# 目的
* Apacheログなど、GZIPされた複数のログ（テキスト）ファイルを処理する時のサンプル
* すべてのログをなめてから処理をしたい場合に、非同期のせいで勝手に次のステップに進むのに悩まされた
* 大容量のログファイルに対応するため、1行ずつデータを読み込む処理にした

# コード

## 処理内容
* 指定したディレクトリにあるGZIPファイルの一覧を生成
* 一覧にあるファイルをひとつずつ開いて処理、分析に必要なデータはグローバル変数に追加
* ファイルを全部読み終わったら適宜処理

```javascript
"use strict";

/*
* Modules
*/

import fs from 'fs';
import log4js from 'log4js';
import zlib from 'zlib';
import readline from 'readline';
import { format } from 'util';

/*
* Config
*/

const SRC_FILE_DIR = "./src_files";

/*
* Logger
*/

const logger = log4js.getLogger()
logger.level = 'all'

/*
* readline
*/

const rl = (path) => readline.createInterface({
    input: fs.createReadStream(path).pipe(zlib.createGunzip()),
    crlfDelay: Infinity
});

/*
* 行の変換
*/

const parseLine = (line)=>{

    // ここに行単位での処理内容を記載・結果はグローバル変数に入れる
    
}

/*
* グローバル変数
*/

var count_lines_all = 0;
var count_files = 0;

/*
* Main
*/

logger.info('Start Processing.');

(async () => {

    var src_files = fs.readdirSync(SRC_FILE_DIR);
    for (var src_file of src_files) {

        // ファイルの読込を開始
        count_files++;
        var count_lines_in_file = 0;
        await (async () => {
            for await (const line of rl(`src_files/${src_file}`)) {
                count_lines_in_file++;
                parseLine(line);

            }
            logger.info(format("File Parsed: [%s] %s - %s Lines", count_files.toString().padStart(4, 0), src_file, count_lines_in_file));
            count_lines_all += count_lines_in_file;

        })();
    }
    logger.info(`File Parsed: Total: ${count_lines_all} Lines.`);

    // 全体を通した分析を記述

})();
```
データ前処理

# データの前処理に関するコードメモ

```python
#データフレーム内の欠損値数の確認
df_train.isnull().sum()
 ages                  18
list_price             0
num_reviews            0
piece_count            0
review_difficulty      0
star_rating          405
country              255
dtype: int64

#null値を持つ行を削除
df = df.dropna(subset=['charges'])

#欠損値の補完（平均値or最頻値を補完）
df = df.fillna({'bmi': df['bmi'].mean()})

#カテゴリカル変数の確認
df_obj = df.select_dtypes(include='object')
gender	smoker	region
0	female	yes	southwest
3	male	no	northwest
9	female	no	northwest

df_uni = df_obj.nunique()
gender    2
smoker    2
region    4
dtype: int64

for uni in df_obj.columns:
    print(uni)
    print(df_obj[uni].unique())

gender
['female' 'male']
smoker
['yes' 'no']
region
['southwest' 'northwest' 'southeast' 'northeast']

#カテゴリカル変数をダミー変数へ
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit(df['gender'])
le.transform(df['gender'])

age	gender	bmi	children	smoker	region	charges
0	19	0	27.900000	0	yes	southwest	16884.92400
3	33	1	22.705000	0	no	northwest	21984.47061
9	60	0	30.716434	0	no	northwest	28923.13692

#One-Hot Encording (カテゴリカル変数をすべてダミー変数へ)
df = pd.get_dummies(df, drop_first=True)

```

One-Hot Encordingがどちゃくそ便利！
AWS Glueのpython shellで自作スクリプトを読み込む

AWS GlueでPython ShellでETLの仕組みを2つほど作っていて共通化できるmethodを外部から読み込めないかと思い調べてみた｡

##### ライブラリを egg ファイルまたは whl ファイルとしてパッケージ化して設置する
作成したライブラリをeggファイル　or whlファイルとしてパッケージ化して読み込ませる｡このパッケージ化したファイルをglueの管理画面にある「python library path」として指定する｡

libフォルダーを作成してその中にsetup.pyファイルを作成する

`
現時点(2023年2月2日段階)でpython3.9で.eggファイルを使用するとモジュールが読み込めないエラーが発生するので
.whlを作成する｡ .eggはpython3.6で稼働できることを確認
`


```setup.py
from setuptools import setup

setup(
    name="hello_module",
    version="0.1",
    packages=['hello_module']
) 
```
次にhello_moduleディレクトリを作成して以下の3つのファイルを作成する

```hello_world.py
def hello_world(name):
    return 'Hello World, ' + str(name)
```
```goodby_world.py
def goodby_world(name):
    return 'Goodby World, ' + str(name)
```

```__init__.py
空ファイルのまま
```

次に以下のコマンドを実行
.eggファイルを作成する
```
python setup.py bdist_egg
```
.whlファイルを作成する
```
python setup.py bdist_wheel
```
実行するとdistフォルダー内にファイルが生成される｡これをS3の特定のバケットに設置する


##### AWS Glueでpython shellを作成
```
from hello_module import hello_world, goodby_world

hi = hello_world('Taro')
print(hi)

by = goodby_world('Hanako')
print(by)

```
##### Libraries　Pathの設定
![スクリーンショット 2023-02-01 16.48.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79473/195b951d-346c-804d-b351-164a66a16f29.png)


以上で実行して確認する｡
No1_ググったこと投稿(5分)_React関連

# きっかけ
ググった内容って、
「あー！こんなかんじね！」と理解した気になってませんか？？
結局数日後、あれ・・・この前のなんだっけ・・・となることが多くないですか？😢

そんなある日、ネットサーフィンをしていたら、こんな記事を見つけました
https://zine.qiita.com/interview/creek-and-river-job-agent/

この記事の内容を要約すると
`` 「ググったことを5分書いたら投稿する（中途半端でも）」 ``

おー！！これめっちゃいいやん！！



### その前に背景を・・・
自分はバックエンドエンジニアでPHPを使用してます。(Laravel/ CodeIgniter/ Slim経験有)
ある過去の経験があり、フロント側に苦手意識を持っています。
それを払拭するために、MENTAというサービスを使ってJS ~ React.js を教えてもらってます。
なぜこんな事をしてるかというと、身銭を切った行動をしないと本当に行動しないから
＋自分で参考書や、動画を見て勉強したのですが、挫折したから・・というのも理由です。
ゴールとしては、フロントエンドも触れるエンジニアになる!がゴールです!!Yes!!

さて、今月の真ん中あたりからReactをようやく触れそうだけど、何するか理解していないので
それをまとめたいと思います。

## ということでNo1_ググったこと投稿します(5分)_React関連

- Express
    - Node.jsのフレームワーク
        - 特徴
            - 軽量でありながら*ルーティング・*クッキー・*RESTfulなインターフェースを装備
            - 拡張モジュールが豊富にあり追加していくことで柔軟に対応できる
- Redux
    - React.jsが扱うUIのstate(状態)を管理をするための状態管理ライブラリ
        - *fluxアーキテクチャの影響を受けている
- React Hooks
    - クラスを書かなくてもReactの機能を使えることです。例えば、関数コンポーネントにstateを持たせたり、ライフサイクルに応じた処理を実装できる
            -　コンポーネント
                -　React画面に表示される部品のことで、表示に必要なデータや処理などを1つのオブジェクトにまとめたものです。
            -　ライフサイクル
                -　Reactのコンポーネントが生まれてから成長し、最終的に死ぬまでの一連の過程のこと

## 初めてやった所感
久々に見る単語や、知らない単語にぶち当たりまくり、芋づる式で調べまくって5分で終わらない
→次回は5分タイマー設定

では！
    


## 単語
*ルーティング
クライアントのリクエスト内容と、サーバーの処理内容を紐付ける(マッピング)作業
参考)
https://tsuyopon.xyz/2019/02/22/what-is-the-routing/

*クッキー
Webサイトとユーザー間でやり取り・保存されるアクセス情報

*RESTful
Webアーキテクチャのひとつ
   - パラメータ指定
   - ステートレス性

*API
システムとシステムをつなげる機能  

*fluxアーキテクチャ
アプリケーション上でのデータフロー管理のためのアーキテクチャパターン。
View, Action, Dispatcher, Storeの4つの要素で構成され、単方向へデータが流れていくことでデータの流れを追いやすくなるという特徴があります。
参考)
https://zenn.dev/ryotarohada/articles/9a677d6f7fdc8e

React Hooks 参考)
https://zenn.dev/ratmie/articles/abe97228ad5435

コンポーネント 参考)
https://zenn.dev/web_tips/articles/c3851133f52d16

ライフサイクル 参考)
https://tomoki-blog.org/reactjs/208/
Nuxt3のインストールでエラー ( npm ERR! cb.apply is not a function )


# 問題

```
$ npx nuxi init nuxt-app
npm ERR! cb.apply is not a function

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/yumainaura/.npm/_logs/2023-02-02T04_46_08_609Z-debug.log
Install for [ 'nuxi@latest' ] failed with code 1
```

# 解決

npmのバージョンを上げたら解決した

```
$ npm -v
8.19.2
```

```
$ npm install --global npm
```

```
$ npm -v
9.4.1
```

# 参考

https://stackoverflow.com/questions/67315860/npm-err-cb-apply-is-not-a-function-elementary-os

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Kaggleで使える技術まとめ

# はじめに
Kaggleで学んだ処理方法をメモしていきます．
みなさんからも是非色々教えて欲しいです．

私が読んだ本をあげておきます．
- Pythonではじめる Kaggleスタートブック
- 前処理大全[データ分析のためのSQL/R/Python実践テクニック]

# 1 共通事項
## 1.1 バギング（bootstrap aggregating）
DeepLearningの研究では，手元にあるデータは全て正解もセットであることが多いと思います．
ですが，Kaggleはtestデータの正解ラベルは公開されていませんし，testデータに対する結果で競います．手元にあるデータをTrain・Validation・testに分けるのがセオリーですが，KaggleではTrain・Validationだけに分けて，できる限り多くのデータを学習させるようにします．その中からTrain・Validationの組み合わせを変更して複数のモデルを作成します．それらのモデル全てでテストデータに対して出力を取り，多数決を取って最終的なモデルの出力とします．
![Bagging.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120757/3dac01db-f4f4-acf2-c0f2-a34eba72191a.png)

## 1.2 パラメータチューニング
実行する際の良いハイパーパラメータを探します．あんまやったことはないので，手法だけメモしておきます．
- Grid Search
- Hyperopt
- Optuna


# 2 テーブルデータ
## 2.1 クラスの数値
テーブルデータはラベルが数値として入っていることがあります．[🐶，🐭，🐱]　= [０，１，２]といった具合です．
これをそのまま数値に入れると🐭と🐱より，🐶と🐱のほうが離れているいう入力になります．これはよくないですよね．
ということで，これをClass1・Class2・Class3という3つのパラメータに分けて考えます．例えば，ラベルが🐶の時は"Class =０"と入っていたところを，"Class1 =１"・"Class2 =０"・"Class3 =０"とします．これでクラスをちゃんとクラスとして扱えます．

ですが，これって1000クラスとかになるとまずいんじゃね？？とも思います…:unamused:
解決策求ム:sob:

## 2.2 正規化
テーブルデータには，特徴毎に様々な範囲をとることがあります．例えば一つだけ異常に大きい数値を取る特徴があったとき，そのまま入れると意図しない部分が大きく効いてしまいます．
なので，全ての要素を（0,1）の範囲で正規化することで，全ての特徴量を均等にみてくれるようになります．


# 3 画像データ
随時追記予定

# 4 テキストデータ
- Bug of words
- TF-IDF
- Word2vec

随時追記

# さいごに
随時追記予定です
【Flutter】AndroidのAPKビルドがgradleやAndroid 12のエラーがでて出来ない問題の解決策

Android StadioでFlutterのAndroidアプリビルドがうまくいかなかった問題を有志の記事などを参考にしたところ解決することが出来ましたので、やり方を紹介したいと思います。

### エラー1
     What went wrong:
    Execution failed for task ':app:lintVitalRelease'.
    > Could not resolve all artifacts for configuration ':flutter_local_notifications:debugUnitTestRuntimeClasspath'.
       > Failed to transform bcprov-jdk15on-1.68.jar (org.bouncycastle:bcprov-jdk15on:1.68) to match attributes {artifactType=processed-jar, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}.
          > Execution failed for JetifyTransform: /Users/ryotaro/.gradle/caches/modules-2/files-2.1/org.bouncycastle/bcprov-jdk15on/1.68/46a080368d38b428d237a59458f9bc915222894d/bcprov-jdk15on-1.68.jar.
             > Failed to transform '/Users/ryotaro/.gradle/caches/modules-2/files-2.1/org.bouncycastle/bcprov-jdk15on/1.68/46a080368d38b428d237a59458f9bc915222894d/bcprov-jdk15on-1.68.jar' using Jetifier. Reason: IllegalArgumentException, message: Unsupported class file major version 59. (Run with --stacktrace for more details.)
               Suggestions:
                - Check out existing issues at https://issuetracker.google.com/issues?q=componentid:460323&s=modified_time:desc, it's possible that this issue has already been filed there.
                - If this issue has not been filed, please report it at https://issuetracker.google.com/issues/new?component=460323 (run with --stacktrace and provide a stack trace if possible).a
    

gradleのバージョンを上げたら解消しました。
gradle-wrapper.propertiesのdistributionUrlを
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
など、最新のURLに変更して

android/build.gradleのclasspath 'com.android.tools.build:gradle:X.X.X'を
>classpath 'com.android.tools.build:gradle:7.1.3'

と変更すると動きました。古いバージョンが指定されていたので、新しいGradleのバージョンとURLをしていしたことによって無事にビルドできるようになったのかと思います。

詳しくは以下の記事を参考にしてみてください
https://www.kentosjpn.com/programming/12/

続いて、

    Manifest merger failed : android:exported needs to be explicitly specified 
    for element <activity#com.wonder.classtime.wondertime.MainActivity>. 
    Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined.
     See https://developer.android.com/guide/topics/manifest/activity-element#exported for details.

このようなエラーが出ました。

Android12に対応するには、android:exported="true"をactivityタグに書かないといけないみたいです。

    <activity
                android:name=".MainActivity
    ...

僕の場合は、これでいけましたがうまくいけなかった人は以下の記事に続きが書かれているので参考にしてみてください。
https://crammbon.com/2022/09/05/flutter-android-android-12%E5%AF%BE%E5%BF%9C%E3%81%99%E3%82%8B%E3%81%A8-androidexported-needs-to-be-explicitly-specified-for-element-%E3%81%A8%E6%80%92%E3%82%89%E3%82%8C%E3%81%9F%E6%99%82%E3%81%AE/
Perplexity AI（無料でAIが質問に答えてくれる神ツール）を Chrome の検索エンジンにする設定方法。

# サイトのURL

Perplexity AI: Ask Anything

https://www.perplexity.ai/

# 環境
Windows10
Chrome

# 自分から見た長所
ChatGPTだと信頼性が低い回答が返ってくるが、
Perplexity AIはその信頼度が低い分を補って、参考URLを添えて回答してくれる。
質問を継いで質問ができる。
次の質問候補を出してくれる。

# 欠点
日本語変換の決定キーを押すと質問文として送信されてしまう。
ChatGPTは回答の仕方が文であったり表であったり表現が豊かだが、
Perplexityは文章と参考サイトのリンクが表示されるだけ。
性能ではChatGPTに負けている。（その分、回答の信頼度は高い）

# Chromeでの設定方法
Chrome右上の「︙」（縦3点リーダー）から
＞設定
＞左サイドのメニューから「検索エンジン」
＞検索エンジンとサイト内検索を管理する

## 設定ページはURL入力からダイレクトに飛べる

`chrome://settings/searchEngines`

![Chromeキャプチャ指示挿入済み.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44761/ac38f205-05fe-70f2-b595-7da98dcb34de.png)

# 設定例

設定例1

```
PerplexityAI
っｆ
https://www.perplexity.ai/?q=%sについて日本語で答えてください。
```

実際にキャプチャした設定例1
![キャプチャ設定例1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44761/413909cf-591d-90ee-78e8-3e01c06436e3.png)


設定例2

```
PerplexityAI
ff
https://www.perplexity.ai/?q=%sについて日本語で答えてください。
```

# ショートカットキーについて
「っｆ」と「ff」これは日本語入力時でも英語入力時でもホームポジションから動かさないで入力できるため。
※各自の使いやすいショートカットキーを設定してください。

「q=%sについて日本語で答えてください。」
この%sは質問するキーワードで、
その後ろの文章を自動的に付け足して質問をしてくれます。


## 日本語入力時
日本語入力時の詳細な動作は
Fキーを2回にリターンキーで確定＋スペースキーを押すと検索エンジンが「Perplexity AI」に変わります。
スペースキーを押して入力単語がショートカットキーだとChromeに認識させる必要があります。

変換を記憶させておけば
っｆがffに変換され英語入力時と同じになるのであとはスペースキーを押せば検索単語を受け付けてくれる。

## 英語入力時
英語入力時だと、ff（自分で設定したショートカットキー）の2文字＋スペースキーで検索単語を受け付けてくれる。

# 検索エンジンのデフォルトに設定する。
perplexityを設定した右側に「︙」（縦3点リーダー）があるのでそれを押して、
デフォルトを選択すると、デフォルト設定になる。




# 早速質問してみる。

## 手順
新しいタブを開き、ブラウザのフォーカスが自動的に検索窓に移動する。
ショートカットキーを入力すると、検索エンジンがPerplexity AIに変更される。
そこに検索キーワードを入力する。

この手順だとホームポジションから手を動かさなくてもよい。

## 実践
日本語入力時
`Ctrl ＋ T` で新しいタブを開く
ショートカットキー ＋ 確定キー ＋ スペース ＋ キーワード入力

英語入力時
`Ctrl ＋ T` で新しいタブを開く
ショートカットキー ＋ スペース ＋ キーワード入力


## 質問 1
Perplexityの日本語の読み方を教えてください

PERPLEXITY
「perplexity」の日本語の読み方は「パープレクシティー」である[1][2]。意味としては、当惑、困惑、混乱などがある[3][4][5][2]。

URLをコピーすれば同じ質問を共有できる。

https://www.perplexity.ai/?s=u&uuid=ffe461e7-02ec-4115-8c02-0d4201fa2ea9

## 質問 2
PERPLEXITYについて日本語で答えてください。
PERPLEXITY
Perplexityとは、ある事象に対して、別の事象が発生した際の頻度（確率）を対数を組み合わせて表す機械学習の指標である[1]。Perplexity.aiは、AIを用いた質問応答サービスで、日本語にも対応している[2]。6つの特徴として、情報ソースが常に新しい[3]、情報の元ソースが明確[3]、個別のURLが残せる[3]、SNSで回答URLが自律して拡散される[3]、ログインが不要[3]、日本語にも対応する[2][4]などがある。

https://www.perplexity.ai/?s=u&uuid=5ba5e780-bc42-41c2-abae-1f356dc3263a

## 質問 3
ChatGPTについて日本語で答えてください。
PERPLEXITY
ChatGPTは、OpenAIが開発した自然言語処理モデルであり、テキストで質問を投げかけることでAIが回答を表示する[1]。Google Translateの拡張機能を使うことで日本語化することが可能であり、ページ全体を日本語化するのが良い[2]。ChatGPTは文章を書くためのツールとして使用され、子供にも分かりやすく説明することが可能[3]。

https://www.perplexity.ai/?s=u&uuid=4055206d-bbb7-4d7b-a609-c96aacbd357a


# Chrome拡張機能

Perplexity

https://chrome.google.com/webstore/detail/perplexity/hlgbcneanomplepojfcnclggenpcoldo/

- ツールバーから簡単に質問できる
- 閲覧中の質問に簡単に回答できます。
- ワンクリックでGoogleやBingの検索エンジン体験を強化

# 日本語入力に対応したPerplexity AIサイト

日本語入力だと変換時に送信されてしまうがその欠点を緩和してくれるサイト。

perplexity Askに聞いてみる

https://pancakeknife.bubbleapps.io/perplexity


# （おまけ）google日本語入力に単語登録をする
（追加質問する時に入力しないと英語で返ってくる時がある）

ショートカットキー
ｔ

登録語句候補
について日本語で答えてください。
とはなんですか？日本語で解説してください。
を詳しく日本語で教えて下さい。
等
MocapSW「ダンスの動きを提出」チャレンジ！

![Screen Shot 2023-02-02 at 11.57.57 AM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123843/d402f28a-85af-1884-6392-56c49b01bf6d.png)

Plask'sDanceChallenge"SUBMITYOURDANCEMOVES"を見つけました。Plaskは誰でも簡単にモーションキャプチャを作成できます。

参加方法の詳細はリンク先の動画をご覧ください！イラストに出ているNayeキャラクターにモーションを適用してください。一番いい部分は？ 3か月のMoCapProライセンスが受賞者に公開されます。
👉 https://www.instagram.com/p/Cn6HIF6jaBb/
【Rails】同一モデルの異なるレコードを複数作成し、同時にcreateする方法

# どうした？
[前回の記事](https://qiita.com/ysk91_engineer/items/c1830885866583160047)同様、ToDoアプリを作成しています。
Todoの投稿フォームを複数個作成し、同時に投稿する方法を学んだのでそのアウトプットです。

# 目標物の確認
今回実装する機能は下図です。
![ToDoApp_設計書 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2688241/ce333e4b-c358-4784-423d-c77b324baa7c.png)



`Todo.content`同士は異なるレコードです。
ボタンひとつで複数のレコードをいっぺんに作成します。

# 方法

**コントローラ**
```ruby
def index
  # 略

  @category = Category.new
  2.times { @category.todos.build }
end
```

今回は**インデックスページで`new`していること**, **親モデルの`Category`と同時にcreateすること**に注意してください。
ポイントとなるのは`2.times { @category.todos.build }`の部分です。
これにより、ビューページで`Todo.content`用のフォームを表示する指示を与えたときに**3つ**のフォームが作成されます。

**作成されたフォームのHTML属性を見てみよう**
作成されたフォームのHTML属性を見てみます。
各フォームの`name`属性が以下のようになっていることに気づくでしょう。
```ruby
category[todos_attributes][0][content]
category[todos_attributes][1][content]
category[todos_attributes][2][content]
```

Railsは各フォームのname属性に対して0~n(timesで指定した数)の値を付与します。
これによって、複数のフォームが作成されます。


## 空のフォームは新規作成しない

前回の記事で紹介した通り、ストロングパラメータｄ`_blank`を指定することで、空のフォームに対して`_destroy`するのを防ぎます。
例えば3つのフォームがあるときに
```
1つめ: 投稿1
2つめ: (空欄)
3つめ: 投稿3
```
という値を入力し送信したとき、作成されるのは
```
投稿1
投稿3
```
です。2つめのフォームの空欄はスキップされるわけですね。

# 参考

https://railsguides.jp/form_helpers.html#%E3%83%8D%E3%82%B9%E3%83%88%E3%81%97%E3%81%9F%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0

https://qiita.com/ysk91_engineer/items/c1830885866583160047
【japan-map-js × Laravel】jQueryプラグインで都道府県ごとに選択できる日本地図を表示

こんにちは！
現在エンジニアを目指して勉強中の一般男性です。

突然ですが、かっこいい日本地図を画面に表示させたい、、、
誰しも一度は思ったことがあるのではないでしょうか（）

今回、jQueryプラグインのjapan-map-jsを利用したところ
かなり簡単かつ扱いやすい日本地図を表示させることができました。
自分と同じ初心者の方向けに参考になればと思い、まとめておきます。

## 環境
・macOS Monterey 12.6
・PHP 8.1.13
・Laravel 9.3.12
・jQuery 3.6.0

## 前提

作っているものは、旅行の記録ができるWebアプリ。
白地図は以下のイメージで表示させたい。

__①トップページに白地図を表示__
各都道府県はクリックができ、遷移先はそれぞれのページ

__②マイページに白地図__
「訪問済み」の記録を残した都道府県と「未訪問」の都道府県を区分。
こちらもクリックができ、
「訪問済み」の県の遷移先は、自分が残したその県の記録。
「未訪問」の県は、他ユーザーの記録一覧。

## 実装
### 導入

まずは __jQueryを読み込んだ後に__ japan-map-jsを読み込む。
ダウンロード、CDNのどちらも用意されていますが、
私の場合はCDNがあまりうまく動きませんでした。。

```index.html
<!-- ダウンロードのパターン -->
<script src="/path/to/jquery.japan-map.min.js"></script>

<!-- CDNのパターン -->
<script type="text/javascript" src="https://unpkg.com/japan-map-js@1.0.1/dist/jpmap.min.js"></script>
```

続いて、htmlを用意。
クラス名ないしid名は任意のもので問題ありません。
```index.html
<div class="js-japanMap"></div>
```

japan-map-jsを操作するためのjsも必要です。
```japan-map.js
//　セレクタ.japanMap()で地図を生成
//　引数でマップのオプションを指定

$('.js-japanMap').japanMap({
  width: // 任意の幅を指定
  selection: 'prefecture', // 都道府県単位でクリック可能
  drawsBoxLine : false,
  movesIslands : true, //　沖縄の表示位置を日本海側に移動
  onHover: function(data) {
     // 各都道府県にホバーした際のアクションを指定
  },
  onSelect: function(data) {
     // 各都道府県をクリックした際のアクションを指定
     // 画面遷移
     window.location = 'hoge'; 
  }
});
```
ホバー時、クリック時は、`data.name`や`data.code`で
都道府県名や各都道府県に割り当てられたコードを取得できます。
ひとまずは、これで表示できるはずです。

### カスタマイズ
では、ここからカスタマイズしていきます。
オプションの設定など、詳細は[こちらの公式ドキュメント](http://takemaru-hirai.github.io/japan-map/)をご確認ください。

実装していきたいのは以下の部分。
ホバー時やクリック時のアクションは
みなさんバラバラだと思うので今回は割愛します。

>__②マイページに白地図__
「訪問済み」の記録を残した都道府県と「未訪問」の都道府県を区分。


```japan-map.js
// URLから現在のページを判断
if (location.pathname.includes('/mypage')) {
    // 1から47までを格納した配列
    let prefs = [...Array(47)].map((_, i) => i+1); 
    // 訪問済みの都道府県を格納する配列
    let visited = [];

    // 今回は訪問済み、未訪問の２通りに区分
    // 各区分に入れる都道府県（prefectures）はこの段階では空
    let areas = [
      {code: 0, name: '未旅行', prefectures: [], color: '#808080', hoverColor: '#7ba23f'},
      {code: 1, name: '旅行済み', prefectures: [], color: '#2d6d4b', hoverColor: '#7ba23f'},
    ];

    // マイページにコンテンツがある = 旅行済みの県を取得
    $('.js-get-visited').each( function () {

      // データ属性で付与した都道府県コード（pref）を取得し、areas[1]に格納
      visited = Number( $(this).data('pref') );
      areas[1].prefectures.push(visited);
    });

    // 未旅行の県を取得
    // 47都道府県と訪問済み(areas[1].prefectures)をfilterでぶつける
    // indexOfで-1が返ってくるもの（未訪問）を抽出し、areas[0]に格納
    areas[0].prefectures = prefs.filter(i=>areas[1].prefectures.indexOf(i) == -1);

    $('.js-japanMap').japanMap({
      width: mapWidth,
      selection: 'prefecture',
      areas: areas, // areas[0]には未訪問、areas[1]には訪問済みが格納されている
      drawsBoxLine : false,
      movesIslands : true,
      onSelect: function(data){　// 割愛します
         }
      }
    });
  }
```


## 参考

### 公式

http://takemaru-hirai.github.io/japan-map/

https://github.com/HemingwayLee/japan-map-js

### その他

https://qiita.com/suin/items/1b39ce57dd660f12f34b

https://www.esz.co.jp/blog/2789.html
【Rails】Capistranoを利用した自動デプロイ実行時に発生したエラーの対処法

某スクールの最終課題をEC2で自動デプロイする時に発生した事象。
自動デプロイツール「Capistrano」を導入し、自動デプロイを実行した際に発生したエラーの詳細と解決方法について記載します。
導入目的：デプロイ時に必要なコマンド操作が1回で済み、手動デプロイする場合に起こりうる下記問題を解消することができる。
##### 手動デプロイで起こりがちな問題
・コマンドの打ち間違い、手順の間違いが発生する可能性がある
・手順が多く、煩わしい


## 発生したエラー
自動デプロイを実行する為に、ローカルターミナルで以下コマンドを実行したところ、
```
% bundle exec cap production deploy
```
以下エラーメッセージが出現。メッセージを見ると、「Bundler::GemNotFound: Could not find date-3.3.3 in any of the sources（gemfileの中に"date-3.3.3”が見つからないよ。）」とのこと。
```
** DEPLOY FAILED
** Refer to log/capistrano.log for details. Here are the last 20 lines:

<省略>

DEBUG [e60eb18b] 	bundler: failed to load command: rake 
(/var/www/<レポジトリ名>/shared/bundle/ruby/2.6.0/bin/rake)
DEBUG [e60eb18b] 	Bundler::GemNotFound: Could not find date-3.3.3 in any of the sources
```
"date-3.3.3"がgemfile内にないことが原因でエラーが発生していると推測し、gemfile内に以下を記述し、ローカル環境でbundle installを実施した上で、再度「bundle exec cap production deploy」コマンドを試したが、同じエラーが発生。

```ruby:Gemfile
gem 'date', '~> 3.3', '>= 3.3.3'
```
## エラーの原因
1人では考えても埒が明かなかったのでメンターに相談したところ、
2022/12/3にrailsの必須gemの一つであるmailが2.7.1から2.8にアップデートされたことで、
このgemバージョンで使用するdateというgemが、EC2側で取得できておらずエラーが発生しているとのこと。
## 解決方法
メンターに教えて頂いた以下の手順を踏めば、問題なく自動デプロイが完了しました。
```
①Gemfileの末尾に「gem 'mail', '2.7.1'」を追記。（mailのバージョンを下げる指定をすることで、dateのgemを取得しないようにする為。）
 *Gemfileに「gem 'date', '~> 3.3', '>= 3.3.3'」を記述した場合は、gem 'date'の記述を削除。
②Gemfile.lockの削除
③ローカルでbundle install
④コミットプッシュ
⑤EC2内で自動デプロイ実行(% bundle exec cap production deploy)
```
yarnがインストール済みなのに動かない問題


ターミナルで
```
$ yarn init
```
と打つも
```
nv: node: No such file or directory
```
とあるので、yarnがインストールされていないのかと思ったが、




探していると同じような質問を見つける
https://webukatu.com/questions/detail/54fb35f55db1d24ca5f2a2200386cc9f/
　
```
現在javascriptの上級でフレームワークのインストールなどをしているとyarnが使えなくなってしまい、
yarn -vや

yarn install

と打つと、
env: node: No such file or directory

と返ってきます。

$brew install yarn
と打つと、すでにインストールされているという
返事が返ってきて、ファイルの場所を調べると
HDのCellarファイルにyarnファイルが入っていました。
nodeもCellarの中に入っています。
yarnファイルはあるが、使えない状況なのですが
インストールされた場所がダメなのか調べたのですが
上手く見つからず、どのような言葉で調べたら解決できますでしょうか？
どこの授業に質問していいか分からずこちらに質問させて頂きました。
宜しくお願い致します。
```
キャッシュが原因の可能性を考えて、
```
＄yarn cache clear
```
しかし
```
env: node: No such file or directory
```

別の方法でトライ
```
nodebrewなどでインストールされた場合、パスが通らずエラーになる事例もあります。


こちらの手動でインストールする方法から試してみてください。
https://nodejs.org/ja/
```
インストール後に
```
$ node -v
v19.5.0
$ yarn -v
1.22.19
```
解決！！！
IBM Cloudサービス利用料金に設定されている為替レートの確認方法

IBM Cloudでは2023年2月から日本円など米ドル以外の通貨をご利用のお客様の利用料金が毎月変動するようになりました。今回は設定されている為替レートを確認する方法を紹介します。なお、各サービスの料金はそれぞれのカタログページにも当月分の為替レートで料金が表示されますので、あわせてご確認ください。

<i>契約の種類によってはこの内容が該当しないケースもあります。多くのお客様が利用されているクレジットカード払い（支払い通貨が日本円）と日本でサブスクリプション契約されているお客様を想定しております。</i>

<B> 2023年2月3日更新 </B>: 使用量のページにもレートが表示されるようになりましたので、確認方法1として追加しました。


<h2> 確認方法1: 使用量のページで確認する </h2>

使用量のページに表示されます。（ただし米ドルを利用する設定となっているアカウントでは何も表示されません）
「時間フレーム」で調べたい月を選択します。


![スクリーンショット 2023-02-03 午後1.08.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83689/eddc2bd4-59a4-41f2-8f6a-5167758c4db8.png)


<h3> 使用量のページへのアクセス方法 </h3>

- IBM Cloudにログインして、[使用量](https://cloud.ibm.com/billing/usage) のページにアクセスします。

<h3> 注意事項 </h3>

* この操作を実施できるのは以下のユーザーのみです。適切な権限を付与されていない場合には利用できません。
  * アカウント所有者
  * IAMで `Billing` サービスの `管理者(Administrator)` の役割をアサインされたユーザー
* 2023年1月以前の利用料金については、為替レートは表示されません。
* 上にも書いたとおり米ドルを利用する設定となっているアカウントでは為替レートは表示されません。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83689/3ca6debc-765d-e7ac-887a-dbe4cbba56f1.png" width=200
/>





<h2> 確認方法2: 使用量のページからダウンロードできるCSVで確認する </h2>

ダウンロードしたCSVをExcelで開いた例ですが、背景を黄色にした部分に日本円の為替レートが記載されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83689/dc7d8ac3-fe7f-7463-ff6d-8ca20ff03e0a.png)
Billing Monthが "Feb-23" なので、2023年2月分の為替レートになります。


<h3> CSVのダウンロード方法 </h3>

- IBM Cloudにログインして、[使用量](https://cloud.ibm.com/billing/usage) のページにアクセスする
- 画面右上の `CSVのエクスポート` をクリック ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83689/daef30bc-a1d1-ffeb-752d-cf1393593393.png)

- 表示されたメニューの `サマリー` `インスタンス` のいずれかを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83689/83c68bef-9a3f-c785-f83d-eec7e3b817ab.png)

- 選択後しばらくするとダウンロードが実行されます。あとはCSVを開いて確認するだけです。

<h3> 注意事項 </h3>

* この操作を実施できるのは以下のユーザーのみです。適切な権限を付与されていない場合には利用できません。
  * アカウント所有者
  * IAMで `Billing` サービスの `管理者(Administrator)` の役割をアサインされたユーザー
* 2023年1月以前の利用料金については、ダウンロードしたCSV内に為替レートが表示されません。

<h3> 参考資料 </h3>

[IBM Cloud Docs 為替レート・ポリシー](https://cloud.ibm.com/docs/overview?topic=overview-terms&locale=ja#exchange-rates)


<h2> 履歴 </h2>
(以前と比べて上下を入れ替えました。新しいものが上にくるようにしました)

* 2025年6月 144.645 円/ドル
* 2025年5月 142.255 円/ドル
* 2025年4月 148.695 円/ドル
* 2025年3月 149.535 円/ドル
* 2025年2月 155.65 円/ドル
* 2025年1月 156.655 円/ドル
* 2024年12月 155.535 円/ドル
* 2024年11月 149.535 円/ドル
* 2024年10月 144.37 円/ドル
* 2024年9月 145.605 円/ドル
* 2024年8月 157.335 円/ドル
* 2024年7月 158.725 円/ドル
* 2024年6月 156.115 円/ドル
* 2024年5月 154.585 円/ドル
* 2024年4月 151.605 円/ドル
* 2024年3月 149.825 円/ドル
* 2024年2月 148.095 円/ドル
* 2024年1月 143.715 円/ドル
* 2023年12月 148.345 円/ドル
* 2023年11月 149.845 円/ドル
* 2023年10月 147.675 円/ドル
* 2023年9月 145.315 円/ドル
* 2023年8月 140.225 円/ドル
* 2023年7月 141.385 円/ドル
* 2023年6月 138.315 円/ドル
* 2023年5月 134.105 円/ドル
* 2023年4月 131.57 円/ドル
* 2023年3月 134.0194 円/ドル
* 2023年2月 129.808515 円/ドル
scikit-learnで重回帰分析をしてみる

# やりたいこと
scikit-learnで重回帰分析をしてみて使い方の流れを残す。
# 順序
* ライブラリのインポート
* データの読み込み
* データを標準化する
* モデルを作成
* モデルを確認

## ライブラリのインポート
sklearnのlinear_modelモジュールのLinearRegressionをインポートする。
```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
```
## データの読み込み
今回はUdemyの講座[【世界で55万人が受講】データサイエンティストを目指すあなたへ〜データサイエンス25時間ブートキャンプ〜](https://www.udemy.com/course/datascience365/)で使用したSATスコアとGPAのデータを用いて記事を作成しました。
```python
data = pd.read_csv('1.02.Multiple-linear-regression.csv')
data.head()
```
SATスコアとRand1,2,3（ランダムな１〜３の数）からGPAスコアを算出してみます。
![スクリーンショット 2023-02-02 12.09.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471496/12dc7ca0-b208-5581-4763-1e4e0ebe1b40.png)

## データを標準化する
```python
x = data[['SAT','Rand 1,2,3']]
y = data['GPA']
# ------ここから標準化------
scaler = StandardScaler()
scaler.fit(x)
x_scaled = scaler.transform(x)
```

## モデルを作成
xに説明変数を代入、yに目的変数を代入する。
LinearRegressionで線形モデルを定義しておき.fit()メソッドで実行する。
```python
reg = LinearRegression()
reg.fit(x_scaled,y)
```
## モデルを確認

```python
print(reg.coef_)  # k係数を確認
print(reg.intercept_) # 切片を確認
print(reg.score(x,y)) # 決定係数を確認
```
array([ 0.00165354, -0.00826982])
0.29603261264909353
0.4066811952814285
【Rails6】親子関係のモデルに対して一度に値を入力する多分最もシンプルな方法【fields_for】

# どうした？
RailsでToDoアプリを開発しています。
ToDoリストを作成する時、
+ 親モデル: Category
+ 子モデル: Todo

を1つの動作で同時に作成する方法を調べたので、そのアウトプットです。

## 目標物の確認
今回作成するアプリはcategories/indexページにて新規投稿します。
新規投稿エリアには`category.title`と`todo.content`の記入欄を用意し、「投稿」ボタンを1つ押すだけで両方のモデルに対して`create`されるようにします。

![ToDoApp_設計書.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2688241/1b116ff9-7010-0218-8d46-ba1a2b3fe18b.png)


## 動作環境
```ruby
$ ruby -v
=> ruby 3.0.2

$ rails -v
=> rails 6.1.7
```

# 方法

## Model
本アプリでは親モデルに`Category`, 子モデルに`Todo`を指定しています。

**Categoryモデル**
```ruby
class Category < ApplicationRecord
  # 親子関係の設定
  has_many :todos

  # controllerにてtodos_attributesが使えるようにする
  accepts_nested_attributes_for :todos
end
```

親モデルでは`accepts_nested_attributes_for :子モデル`を追加することで、コントローラにてパラメータ指定をする際に小モデルのカラムを指定ができるようになります。


**Todoモデル**
```ruby
class Todo < ApplicationRecord
　　　　# 親子関係の設定
  belongs_to :category
end
```

## View
今回の機能を実装するのにポイントとなるのは`fields_for`メソッドです。
`fields_for`メソッドは親モデルの`form_with`に対して子モデルのフォームをネストする形で使用します。


```ruby
<%= form_with model: @category do |f| %>　<%# 親モデルのフォームを作成 %>
  <%= f.label :title, class: 'form-label' %>
  <li><%= f.text_field :title %></li>
  <%= f.fields_for :todos do |t| %> <%# fields_forで子モデルのフォームをネストする %>
    <%= f.label :content, class: 'form-label' %>
    <li><%= t.text_field :content %></li>　<%# 変数tを使っていることに注意！ %>
  <% end %>
  <%= f.submit '投稿' %>
<% end %>
```

## Controller


```ruby
class CategoriesController < ApplicationController
  def index
    # indexに関する内容
    @categories = Category.all

　　　　　　　　# newに関する内容
    @category = Category.new
    @todo = @category.todos.build
  end

  def create
    @category = Category.new(category_params)
    if @category.save
      redirect_to categories_path
    else
      render 'categories'
    end
  end

  private
    def category_params
      params.require(:category).permit(:title, todos_attributes: [:id, :content, :_destroy])
    end
end
```
ストロングパラメータでは、Todoモデルに渡す値を`todos_attributes`で設定しています。
`_destroy`は、Todoモデルのフォームが空のときに空データが送信されないために追加しています。

createアクションではCategoryモデルに関して`new`と`save`メソッドをおこなうだけで、Todoモデルに対しても同様のメソッドがなされます。

# ステップアップ
複数のTodo.contentを一括で作成する方法に関する記事も執筆する予定です。


# 参考

https://railsguides.jp/form_helpers.html#%E8%A4%87%E9%9B%91%E3%81%AA%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B
プリザンターで自動採番の適用時に表記を変えたい

 # はじめに
分類Aに選択式、分類Bにテキスト形式、分類Cに自動採番で「分類C = [分類B]\_[NNNN]」としています。さらに、分類Dに自動採番で「分類D = [分類A][分類C]\_[NNNN]」と設定されているようです。ややこしいですね。今回はこの設定の上でサーバスクリプトを動かし、分類Dの表記を変更したいというご要望でした。実施していきます。

 # サンプルコード
```javascript

try {
    //クラスDの値([分類A][分類C]_[NNNN])を取得
    let beforeStr = model.ClassD;
    //クラスDの値の先頭1文字を取得
    let firstStr = beforeStr.substr(1, 1);
    //クラスDの値のうち「-」の次の文字から最後までを結合
    let afterStr = firstStr + beforeStr.substr(beforeStr.indexOf('-') + 1, beforeStr.length);
    //文字列結合した最終的な表記をクラスDに出力
    model.ClassD = afterStr;
    //更新処理
    model.UpdateOnExit = true;
} catch (e) {
    context.Log(e.stack);
}

```
 # さいごに
文字列の特定個所を切り取り、値を取得する箇所はとても困りました。お客様の環境では分類Aや分類Bは任意の文字列長になるため、臨機応変に文字列が切り取られるためにコーディングしました。
```
beforeStr.indexOf('-') + 1
```
上記のソースコードが該当箇所です。ネットで調べれば出てくるので調べてみてください。
Jupyter Lab を仮想環境で動かす

# やりたいこと
jupyuter Labを仮想環境上で動かしたい！

# 結論
ipykernelをインストールして仮想環境のカーネルをJupyterに追加しておく。

## 方法
1. まずはipykernelをインストールする。 
```shell
pip install ipykernel
```

2. 仮想環境を作成する
```shell
conda create -n JupyterLab python=3.8
```
3. JupyterLabにカーネルを追加する
```shell
python -m ipykernel install --user --name=JupyterLab

```
カーネルが作成されて起動させることができるようになりました。

![スクリーンショット 2023-02-02 12.00.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471496/3dc13d56-29ca-fd02-5d16-358d5a99d6bf.png)


## カーネルを削除したいときは？
```shell
jupyter kernelspec uninstall JupyterLab
```
機械学習、自然言語処理の「ANKI」フラッシュカードの共同プロジェクト

こんにちは、

ムステロ・アキムと申します。
フランス人のデータサイエンティストです。宜しくお願いします！

皆様は、簡単な英語で人工知能のフレームワークか自然言語処理のアーキテクチャの説明が出来ますでしょうか？その上、英語で書かれているarXiv.orgの最新の学術論文が分かりますか？

言葉の壁を取り除くのは大変な難問題です。ヨーロッパの大学で日本語の学生、中国語の学生、医学の学生  、法科の学生は「ANKI」というソフトウェアを使います。

最強暗記アプリと名高い「ANKI」はフルにカスタマイズできるフラッシュカードアプリです。その原理となっているのが、忘却曲線に合わせて最適なタイミングでカード出題をしてくれる「 分散学習  」というシステムです。

# Ankiのフラッシュカード

私は統計、機械学習、深層学習、NLP領域  、CV領域の単語表を組み立てました。
今、デッキの中には４００語の言葉があります。

Updated V2: https://ankiweb.net/shared/info/963288627

フラッシュカードの構造はとても簡単です。例えば: 

- Front (単語): バッチ勾配降下法
- Back (英語): Batch gradient descent
- Reading (読み方): バッチ こうばい こうかほう
- Sentence (説明): バッチ勾配降下法は、関数の傾き、すなわち 1 次導関数に着目して最小値を求める方法である。

# 共同プロジェクト

この共同プロジェクト、 私は「KI」というソフトウェアを使用して、バージョン管理ツールのGithubでこのデッキを共有しました。
Version 1 は  こちらです >>>  https://github.com/AkimParis/anki_jap_ai_vocabulary

まだまだ、改善の余地はありますね。もし時間があれば、ぜひ参加して下さい。
「KI」というソフトウェアCLIのソフトウェアはこちらです。   https://github.com/langfield/ki or https://langfield.github.io/ki/

# 改善点

多分、Sentence (説明)の分で、統計の説明の方がいいかもしれません？
もしかしたら、初心者向けのためにWikipediaの分かりやすいイラストレーションが必要かもしれません。もちろん、日本語の間違い等あればご指摘いただけますと嬉しいです。

このプロジェクトは協力して必ず成功させなければなりません。ぜひ参考にしてください。: )
さて、それでは長くなりましたがここぐらいで一旦終わろうと思います。最後までお読みいただき、ありがとうございました。

ご不明な点などございましたらお気軽にご連絡ください。

アキム
【PHP】チューニングまとめ

# 処理速度まとめ
## 配列追加
:::note info
[]で追加する方がarray_pushよりも2倍早い
:::
### [ ]で追加
```php
$val[] = "りんご";
```
### array_pushで追加
```php
$val = arrray_push("りんご");
```
Railsでupdated_atがばらばらなテストデータを作りたい

備忘録

結論

gem　fakerを利用するぅ

```
group :development, :test do
   gem 'faker'
end
```

今回は既存データをアップデートしてます。

```
models.each do |hoge|
    fake_date = Faker::Date.between(from: 100.days.ago, to: Date.today)
    hoge.update(Model.touch_attributes_with_time(*[], time: fake_date))
end
```
【Python】競プロ用様々な入力の受け取り方まとめ

# はじめに
調べて分かったものもあれば自分で考え出したものもあります。
より短い書き方などあったら教えていただけると幸いです。
新しい入力形式があったら随時追加予定です
# 数値（整数）
## 1文字の整数
### 入力例
```
2
```
### 受け取り方
```py
N = int(input())
```
## 2文字以上の整数(別変数として受け取る)
### 入力例
```
2 3
```
### 受け取り方
```py
N, M = map(int, input().split())
```
受け取りたい値の個数に左辺の文字数を合わせる
## 配列
### 入力例
```
2 3 5
```
### 受け取り方
```py
A = [int(x) for x in input().split()]
# or
A = list(map(int, input().split()))
# or
A = [*map(int, input().split())]
```

## N行→1つの配列
### 入力例
```
0
1
2
3
4
```
### 受け取り方
```py
a = [int(input()) for _ in range(N)]
# print(a) -> [0, 1, 2, 3, 4]
```
## N行2次元配列→1つの変数
### 入力例
```
1 2 3 4
5 6 7 8
9 10 11 12
```
### 受け取り方
```py
a = [ list(map(int,input().split(" "))) for _ in range(N)]
# print(a)
# [[1, 2, 3, 4], 
#  [5, 6, 7, 8], 
#  [9, 10, 11, 12]]
```
## N行M列2次元配列→縦1列を1つの配列として別変数で
`N = 4`, `M = 3`の場合
### 入力例
```
1 2 3
4 5 6
7 8 9
10 11 12
```
### 受け取り方
```py
left = []
mid = []
right = []
a = [ list(map(int,input().split(" "))) for _ in range(N)]
for i in range(N):
    left.append(a[i][0])
    mid.append(a[i][1])
    right.append(a[i][2])
# print(left)
# -> [1, 4, 7, 10]
# print(mid)
# -> [2, 5, 8, 11]
# print(right)
# -> [3, 6, 9, 12]
```
これもっといい方法ありそう

### 【追記】タプルでの受け取り方
@Cartelet さん、コメントありがとうございます！
```py
a = [map(int,input().split(" ")) for _ in range(N)]
left, mid, right = map(list, zip(*a))
# print(left)
# -> (1, 4, 7, 10)
```
まとめてリストに変換する方法はあるのでしょうか...？
`left = list(left)`で1つずつ変換していく方法しか思いつきません。

### 追記
```py
a = [map(int,input().split(" ")) for _ in range(N)]
left, mid, right = map(list, zip(*a))
```
これでタプルではなくリストで受け取れるようです。

# 文字列
## 1つの文字
### 入力例
```
a
```
### 受け取り方
```py
S = input()
```

## 文字列をそのまま
### 入力例
```
hello
```
### 受け取り方
```py
S = input()
# print(S) -> 'hello'
```

## 文字列を1文字ずつの配列として
### 入力例
```
hello
```
### 受け取り方
```py
S = list(input())
# print(S) -> ['h', 'e', 'l', 'l', 'o']
```

## N個の文字列
### 入力例
```
good morning
hello
good bye
```
### 受け取り方
```py
S = [input() for _ in range(N)]
# print(S) -> ['good morning', 'hello', 'good bye']
```

## N個の文字列（各文字列を1文字ずつばらして）
### 入力例
```
good morning
hello
good bye
```
### 受け取り方
```py
S = [list(input()) for _ in range(N)]
# or
S = [[*input()] for _ in range(N)]
# print(S)
# [['g', 'o', 'o', 'd', ' ', 'm', 'o', 'r', 'n', 'i', 'n', 'g'], 
#  ['h', 'e', 'l', 'l', 'o'], 
#  ['g', 'o', 'o', 'd', ' ', 'b', 'y', 'e']]
```

```自分で考えた方法.py
S = []
for i in range(N):
    S.append(list(input()))
```
# コメントに感謝
@shiracamus さん、@Carteletさん
ありがとうございます！
もっと他の記事読んだり自分で考えたりして簡単な書き方探してみます。
【IBM Application Gateway】Cloudwatch に送ったリクエストログ・監査ログをフィルタリング、ダウンロードする

# はじめに
IBM Application Gatewayを、AWS ECS/Fargate環境にデプロイしました。
Cloudwatch Logsに出力したリクエストログと監査ログを、フィルタリング、外部出力できるか確認しました。

# 1.ログ出力設定
リクエストはデフォルトでコンテナの標準出力に表示されます。監査ログを出力、ログの出力フォーマンっとをJSON形式に変更しました。
```
logging:
  json_logging: true
  components:
    - audit.authn
    - audit.azn
```

# 2.CloudWatchでのログ出力確認

ロググループでコンテナのログを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/dd7c0073-6a5d-4ec3-d8b6-f7188355bc71.png)


「すべてのログストリームを検索」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/b183d988-692f-9acb-748c-8feb86d67c1c.png)

コンテナのログが確認できます。
- リクエストログ： Levelが"INFO"
- 監査ログ： Levelが"AUDIT"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/34e09c54-16c6-6a2f-aa92-33ed021db76a.png)

# 3.ログのフィルタリング
リクエストログと監査ログが混在するため、フィルタリングしてみました。

LevelがAUDITのログのみ表示するため、下記キーワードで検索します。
構文についてはCloudWatchのユーザーガイド [フィルターとパターンの構文](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html#matching-terms-events) を参考にしました。

```
{ $.level= "AUDIT" }
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/eff9e453-7e09-1c49-7cfc-22c865178ac8.png)

# 4.ログをダウンロードする
CloudWatchメニューからダウンロードできました。

アクション-検索結果をダウンロード（CSV） を選択します。
![isva-aws-000080.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/a63d872b-eec2-d80f-7a72-bb75e914935d.png)

ダウンロードしたファイル名と、含まれるデータは次のようになっていました。
ファイル名
```
log-events-viewer-result.csv
```
データ
```
timestamp,message,logStreamName
```
サンプル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678692/7458468d-a035-5012-3d84-a253bd492664.png)

# 参考
- [IBM Application Gateway - JSON Logging](https://docs.verify.ibm.com/gateway/docs/yaml-logging-json_logging)
- [IBM Application Gateway - Components](https://docs.verify.ibm.com/gateway/docs/yaml-logging-components)
- [CloudWatchのユーザーガイド フィルターとパターンの構文](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html#matching-terms-events)
Microsoft の OpenHack (Container) に参加してきた


Microsoft が主催するハッカソンのイベントである OpenHack に参加してきた (通算4回目) ので、その内容を今回もまとめます。
前回の記事はこちら↓↓

https://qiita.com/coitate/items/1ff6bdc81698f0b66682

https://qiita.com/coitate/items/0ddf75e73c13574ef45f

https://qiita.com/coitate/items/80586c3ad1739e5b6f72

# OpenHack とは？

Open (多様な参加者) な Hack (開発) ということらしい。色んな会社・組織から色んな人が集まって Azure 使ってハッカソンやりましょう！ということ。実際に、色んな会社の方や大学生の方もいて面白かった。
詳しくは以前の記事をお読みくださいませ :bow:

# 何するの？

この OpenHack では、コンテナを使ってマイクロサービスのアプリケーションを構築していく。コンテナオーケストレーションには、AKS を使い、既存のサービスを AKS 上にデプロイしていくことになる。
他の OpenHack と同様に、構築はいくつかの Challenge で段階的に行っていき、各 Challenge に設定されている達成基準をクリアすると次の Challenge に進めるという流れ。
今回は Challenge 4 (たしか) までクリアするとバッジがもらえる！

# 感想

コンテナについては、すでに用意されたイメージをローカルで開発環境として利用するくらいしか経験がなかったので、非常に勉強になった。特に Kubernetes については概念レベルでしか理解していなかったが、実践を通してより理解が深まったし、AKS ならではの注意点なども学べたのでとても有意義でした！

# 開催情報

今まではあんまり情報なかったですが、これからはここで発信していくみたいです。ご興味のある方はぜひ！
私も残りの OpenHack に全部参加してコンプリートしたいと思います！

https://micug.jp/%E5%88%86%E7%A7%91%E4%BC%9A/mscloudmasters/
⑤マクロ入門

今回もマクロを触っていく。

・穴抜きの正方形を作る（boolean処理）

```
#!/usr/bin/layout
#name=donut array
#help=an array of donut with different parameter


int main(){
  int out=100000;                       //外側の正方形の1辺の長さ
  int in=3000;                       //内側の正方形の1辺の長さ
  //外側の正方形を形成
  layout->drawing->point(0, 0);
  layout->drawing->point(0, out);
  layout->drawing->point(out, out);
  layout->drawing->point(out, 0);
  layout->drawing->polygon();
  
  //内側の正方形を形成
  layout->drawing->point(out/2 - in/2, out/2 - in/2);
  layout->drawing->point(out/2 - in/2, out/2 + in/2);
  layout->drawing->point(out/2 + in/2, out/2 + in/2);
  layout->drawing->point(out/2 + in/2, out/2 - in/2);
  layout->drawing->polygon();
  layout->drawing->polygon();
  
  //boolean処理　外側の正方形をAにsetしてから内側の正方形をBにset
  layout->drawing->deselectAll();
  layout->drawing->point(0,0);
  layout->drawing->fSelect();
  layout->drawing->point(0,0);
  layout->drawing->cSelect();
  layout->booleanTool->setA();
  layout->drawing->deselectAll();
  layout->drawing->point(50000,50000);
  layout->drawing->fSelect();
  layout->drawing->point(50000,50000);
  layout->drawing->cSelect();
  layout->booleanTool->setB();
  layout->booleanTool->aMinusB();        
                 }
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039522/1d0f32c3-9566-f827-76c0-5c5a77ae6c45.png)

・穴抜きの正方形を作る（boolean処理を使わない場合）

```
#!/usr/bin/layout
#name=donut array
#help=an array of donut with different parameter


int main(){
  int out=100000;                       //外側の正方形の1辺の長さ
  int in=3000;                       //内側の正方形の1辺の長さ
  //外側の正方形を形成
  layout->drawing->point(0, 0);
  layout->drawing->point(0, out);
  layout->drawing->point(out, out);
  layout->drawing->point(out, 0);
  layout->drawing->point(out/2 - in/2, 0);      
  layout->drawing->point(out/2 - in/2, out/2 - in/2);
  layout->drawing->point(out/2 - in/2, out/2 + in/2);
  layout->drawing->point(out/2 + in/2, out/2 + in/2);
  layout->drawing->point(out/2 + in/2, out/2 - in/2);
  layout->drawing->point(out/2 - in/2, out/2 - in/2);
  layout->drawing->point(out/2 - in/2, 0);  
  layout->drawing->polygon();      
                 }
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3039522/b07feb5c-96a9-338d-2b45-8be6753d8118.png)