OmniAICreator/Qiita-1.07M huggingface dataset:
gem cocoon rails6使い方

## 初めに

今回この記事では、gemのcocoonの簡単なチュートリアルを紹介してきます。
この記事ではあくまで簡単なチュートリアルを動かすことを目的として作成しています。
公式のgithubのreadmeではhtmlファイルがhamlで作成されているのでhamlを学習しておらず詰まってしまっている方に向けて作成しています。

github Readme↓
https://github.com/nathanvda/cocoon

上記のreadmeを日本語訳してくれている記事↓
https://note.com/emetselch1984/n/neb1396b86126

## 実装環境
ruby 3.1.2
rails 6.1.6.1

## 完成図
![Screen_Recording_0004-08-17_at_16_48_12_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1717562/77687a3c-d545-ad09-6a4d-ee8d0b721a8c.gif)



## 実装

**必要なgemやライブラリのインストール**

```
## cocoonはjqueryに依存しているのでjqueryを必須で入れる。

### terminal
$ yarn add jquery
$ yarn add @nathanvda/cocoon
  
### application.jsの中身を書き換える

// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

import Rails from "@rails/ujs";
import Turbolinks from "turbolinks";
import * as ActiveStorage from "@rails/activestorage";
import "channels";

var jQuery = require("jquery");
global.$ = global.jQuery = jQuery;
window.$ = window.jQuery = jQuery;

require("@nathanvda/cocoon");

Rails.start();
Turbolinks.start();
ActiveStorage.start();
```

**データベースの作成**

今回は、公式のreadme通りに実装していきます。

**ER図**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1717562/8f359e67-010b-e522-7302-9abda8ece0e5.png)

```
## terminal
$ rails g scaffold Project name:string description:string
$ rails g model task description:string done:boolean project:belongs_to

## project.rb　↓を追記
has_many :tasks, inverse_of: :project
accepts_nested_attributes_for :tasks, reject_if: :all_blank, allow_destroy: true

## task.rb ↓を追記
belongs_to :project

## terminal
$ rails db:migrate
```
**formの作成**
```
## _form.html.erb 全て書き換える
<%= form_for @project do |f| %>
 <div class="field">
   <%= f.label :name %>
   <br/>
   <%= f.text_field :name %>
 </div>
 <div class="field">
   <%= f.label :description %>
   <br/>
   <%= f.text_field :description %>
 </div>
 <h3>Tasks</h3>
 <div id='tasks'>
   <%= f.fields_for :tasks do |task| %>
     <%= render 'task_fields', :f => task %>
   <% end %>
   <div class='links'>
     <%= link_to_add_association 'add task', f, :tasks %>
   </div>
 </div>
 <%= f.submit 'Save' %>
<% end %>

## views/projectsの中に_task_fields.html.erbを作成する　↓の内容を全て挿入する

 <div class='nested-fields'>
   <div class="field">
     <%= f.label :description %>
     <%= f.text_field :description %>
   </div>
   <div class="field">
     <%= f.check_box :done %>
     <%= f.label :done %>
   </div>
   <%= link_to_remove_association "remove task", f %>
 </div>

```

## 最後に

以上で実装は完了です。
cocoonはレシピサイトの材料や今回のタスク管理など幅広く使うことができそうです。
スネークケースのモデル名でしくじった話

## 環境
Rails5.2
Ubuntu20.4

## はじめに
モデル名の名前の付け方をしくじって、トラブル解決に時間をかけてしまった話です。始めに、モデル名に次のような、スネークケースの形式で名前を付けました。
```
rails g model Test_Test_1
```

何がいけなかったのかといえば、数字の前にアンダーバーをつけてしまったことです。なぜ、テーブル名の末尾に数字を使ったのかといえば、Test_Test_1、Test_Test_2、Test_Test_3と、いった具合に、同じテーブル名にして、連番を付けたかったためです。

このようなモデル名でテーブルを作成した後、コントローラーからそのモデルのクラスを呼び出したとき、つぎのようなエラーが発生しました。
```
uninitialized constant
```

つまり、そのような名前のクラスは存在しませんというエラーです。いや、あるんですが・・・と思っていたのですが、原因は、モデルの名前の付け方にありました。

結論を言うと、モデル名をTest_Test_1ではなく、Test_Test1で作り変えると上手くいきました。モデル名の末尾をアンダーバー＋数字の形式にすると、Railsがスネークケースとして認識してくれないようです。

モデル名をスネークケースでつけると、モデルのクラス名はキャメルケースで生成されます。

テーブル名→クラス名への変換は、ActiveSupportのclassifyメソッドで行われ、クラス名→テーブル名への変換は、tableizeメソッドで行われます。

参考URL
https://techracho.bpsinc.jp/hachi8833/2017_01_11/32606
```
 "Test_Test_1".classify
=> "TestTest1"
```

ここの変換はOKです。
```
"TestTest1".tableize
=> "test_test1s"
```

あれ？、test_test_1sになってくれませんでした。このようなモデル名の付け方はよくなかったのですね。クラスがありませんというエラーが出てきていた原因が判明しました。
PipeRider 0.6 リリース - 新たなデータプロファイリングのレポート



https://github.com/InfuseAI/piperider/releases/tag/v0.6.0

## 新たなデータプロファイリングのレポートをデザインする

もっとプロファイリングのmetricsを呈する

https://docs.piperider.io/data-profile-and-metrics/metrics


![report_06_overview.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/d476fc60-db23-1c02-2850-6057f9f27f8a.gif)

![report_06_string.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/a1115d8b-59a1-9235-7597-fdb08dfd6ac7.gif)

![report_06_datetime.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/ef3a7cae-f921-6632-34df-a626ae71a4fa.gif)

![report_06_float.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/c34614b6-8c7b-e6a0-1dcf-4524406d31b2.gif)

## フィードバック

ユーザーのご意見を聞きたいです
![feedback.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1623438/9d61011a-600c-8271-7aeb-da24387df5d2.png)


## 次、PipeRider 0.7のリリースの予告

BigQueryとRedshiftの新たなデータソースをサポートする


## 前記事

https://qiita.com/GabxInfuseAI/items/4c4387fc3976ff23b833

https://qiita.com/GabxInfuseAI/items/dd68c439622923ec951e
Red HatカスタマーポータルでのRHELサブスクリプションの管理

# はじめに
先日、お客様とお話させていただいた際、「どのRHELサーバに、どのサブスクリプションがアタッチされていて、いつサブスクリプションの更新があるのか分からない」というご質問をいただきました。
その際、本記事の方法をご紹介したところ、お客様の課題を解決できたとのことでしたので、今回はカスタマーポータルを使ったRHELサブスクリプションの管理方法をご紹介させていただきます。
カスタマーポータルアカウントの作成方法は[こちら](https://qiita.com/ynagashi/items/d22e3bca1519d13fcd21 "こちら")に記載がございます。


# 目次
[1.サーバにアタッチされているサブスクリプション情報の取得](#1-サーバにアタッチされているサブスクリプション情報の取得)
[2.カスタマーポータルにてサブスクリプション情報の編集](#2-カスタマーポータルにてサブスクリプション情報の編集)


# 1. サーバにアタッチされているサブスクリプション情報の取得
RHELサーバにて以下のコマンドを実行し、アタッチされているサブスクリプションの情報等を確認します。
 ```
 # subscription-manager identity
 ```
「システムID」をコピーします。
![00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/8f163ffc-e8fb-897a-17d7-386ba204724a.png)


# 2. カスタマーポータルにてサブスクリプション情報の編集
まずはじめに、[Red Hatカスタマーポータル](https://access.redhat.com/management/systems "Red Hatカスタマーポータル")にアクセスします。

「システム」のタブを選択します。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/a648d4a5-7b0f-a6ae-e8c0-c78df53db4d9.png)


フィルターに1で取得した「システムID」を入力します。（赤枠）
すると1のサーバにアタッチされているサブスクリプションが表示されますので、名前の部分をクリックします。（青枠）
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/ddfd3106-6e45-e1ea-65d9-caceb93c6f45.png)

サブスクリプションの詳細情報が表示されますので、名前の横の鉛筆アイコンをクリックします。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/0cc7942d-1458-9cf1-4322-42d067e93a38.png)


名前を変更します。（青枠）
※社内で管理しているサーバの番号やIPアドレスなど社内でサーバを一意に識別できるものが良いと思います。
名前を変更したら、チェックアイコンをクリックします。（赤枠）
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/5505e92d-6081-56a1-606f-e8599e25d21d.png)

名前が変更され、どのサブスクリプションがどのサーバにアタッチされているのか識別できるようになります。
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668052/b8fd4c3d-7821-f784-9b6a-2bf68d540718.png)

以上となります。
本番環境で2000件以上のレコードを削除する

売上実績のレコードを年度別(12か月のフィールドを横持ち）から月別に変更しようと思います。その方が色々と都合がいいようですので...
ということで既にロードした１年分のレコードを削除したいと思います。

さて、ビューから各レコードを一括選択して削除しよう思いましたが、うん、削除ボタンがない。
ああいつもVF　Pageでリストビューで使える削除ボタンを作っていたのですが、このオブジェクトは参照だけなんで何にも用意してなかったです。何度もする作業ではないので、sandoboxでボタン機能のコーディングをしてデプロイするのが面倒だなぁ。他にいい方法はないかな？

ということで、匿名ウィンドウで200件くらいずつ消す処理を流すことにしました。
10回ちょっとポチポチすればいいでしょう。VF Pageでコーディングするより楽だろう。また他で使えるようにここにソースコード保存しておけばいい。

こんな感じで処理できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ad9e212b-6804-641f-d0a6-dcb846a9d8ca.png)


消す処理
```
LIST<SalesResults__c> sList = [select Id from SalesResults__c limit 200];

List<SalesResults__c> delList = new List<SalesResults__c>();
for (SalesResults__c s : sList){
	SalesResults__c ss = new SalesResults__c();
    ss.Id = s.Id;
    delList.add(ss);    
}

if (delList.size()>0){
    delete dellist;
}
```

件数確認用のSOQL

```
select count(Id) from SalesResults__c 
```


簡単な方法を考え付いて楽できました。5分の作業でした。
Python: ジェネレーターで素因数分解してみた

[こちらの記事](https://qiita.com/ikiuo/items/f24952423be044a071e4)で へえ素因数分解ってこんな風にやるんだ って勉強になったものの、途中から理解力/集中力が枯渇してきて早々に読むのをあきらめ、自分だったらどうするかな?という体で書いてみました。

```py:
from math import sqrt

# 素数の候補を返すジェネレーター
def primables():
    yield 2
    yield 3
    n = 5
    while True:
        yield n
        n += 2
        yield n
        n += 4

# 素因数分解し、基数と乗数のペアを返すジェネレーター
def factors(n):
    limit = sqrt(n)
    base_gen = primables()
    
    while n != 1 :
        base = next(base_gen)
        exponent = 0
        
        while n % base == 0 :
            exponent += 1
            n //= base
        
        if exponent != 0 :
            yield ( base, exponent )
        
        if base > limit :
            yield ( n, 1 )
            return
    return 

# 使用例：
def print_factors(n):
    print( f'{n} ='
          , ' * '.join( f'{b}^{e}'
                       for (b, e)
                       in factors(n)
                       )
          )

print_factors(1234567890)
```

```py:
# 出力：
1234567890 = 2^1 * 3^2 * 5^1 * 3607^1 * 3803^1
```

素朴に試し割りですがちょっと手を加えています。
試し割りする数を2の倍数でも3の倍数でもないもの に間引きし、試し割りする上限を素因数分解する数の平方根までと制限しました。
代表的なファイル転送プロトコルの一覧表

# 概要
ファイル転送用途のプロトコルにおいて、「FTP」と名がつく物が多くあり、混乱を招きそうなため表にまとめました。


# 一覧表

| 略称  | 正式名称  | default port | TCP or UDP | 暗号化対応| 
| ---- | ---- |---- | ----| ---- | 
| FTP  |  File Transfer Protocol | 20(転送),<br> 21(制御) | TCP | FALSE |
| TFTP  | Trivial File Transfer Protocol | 69| UDP | FALSE |
| FTPS  |  File Transfer Protocol over SSL/TLS | 989(転送),<br> 990(制御) |  TCP | TRUE |
| SFTP  |  SSH File Transfer Protocol| 22 | TCP | TRUE |
| SCP  |  Secure Copy Protocol| 22　| TCP | TRUE |
Sweet Home 3d上の仮想空間を散歩するPGM

<H3>Sweet Home 3d上の仮想空間を散歩するPGM</h3>

sweet Home 3d上の仮想空間を実際の動作変化を検出することで足踏み等動いている間だけ
カメラ移動・散歩するPGMをpythonで作りました
<hr>

仮想空間のサイト
<a href="https://www.sweethome3d.com/">Sweet Home 3D - Draw floor plans and arrange furniture freely</a>
<hr>
   github: https://github.com/NanjoMiyako/WalkingInSpace
<hr>
使い方
<br>
0.使用前に以下スクリーンショット中のA～Eの座標をPGM上から設定します
![screenshot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412430/2e24140a-e063-9d6d-fd81-98029af7520d.png)
<br>
(github上のscreenshot1.pngのファイル)

1. コマンドラインからプログラムを呼び出しますその際、2つ目の引数で動いたと判定する差分のパーセントを指定します

2. 発話で以下のうち一つコマンドを言います
   A: {カメラ 右/右上/右下/左/左上/左下｝
   B: {移動 北/南/東/西}

3. うまく聞き取れたら「OK」と発話します(聞き取れなかった場合は「もう一度」と発話)
4.その5秒後、動いている間だけ、1でのコマンドを実行し続けます
5.停止したときには2に戻ります

<hr>
課題<br>
クリック時の人型の発見に矩形エリアの画素の色が青色の部分を探すため、
矩形エリア内に青色のオブジェクトを入れることができないことが課題として残っています
<hr> 
参考にしたサイト<br>
<a href="https://futurismo.biz/speech-recognition-with-python/">Pythonで音声入力に入門しよう(SpeechRecognition) | Futurismo</a><br>
<a href="https://qiita.com/lethe2211/items/7c9b1b82c7eda40dafa9">Google Speech APIを使えるようになるまで - Qiita</a><br>
<a href="https://boook24.com/?p=348">PyAutoGUIでデスクトップの座標取得｜システムブック</a><br>
<a href="https://self-development.info/%E3%80%90python%E3%80%91pyautogui%E3%81%AB%E3%82%88%E3%82%8B%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%81%AE%E6%92%AE%E5%BD%B1/">【Python】PyAutoGUIによるスクリーンショットの撮影 | ジコログ</a><br>
<a href="https://qiita.com/YoshikiIto/items/15d8937fcfcf2d7aa9fb">PyAutoGUIを使おうとしてpyscreeze.PyScreezeException: The Pillow package is required to use this function.とエラーになる - Qiita</a><br>
<a href="https://pyautogui.readthedocs.io/en/latest/keyboard.html">Keyboard Control Functions — PyAutoGUI documentation</a><br>
<a href="https://qiita.com/konitech913/items/301bb63c8a69c3fcb1bd">【自動化】Pythonでマウスとキーボードを操る - Qiita</a><br>
<a href="https://qiita.com/oh_rusty_nail/items/e7f39a6fc3624ac9ff09">PyAutoGUIを使った自動化 -入門編- 〜D&Dやスクロールなどのマウス操作も簡単に〜 - Qiita</a><br>
JavaScriptでPromiseの処理時間を簡単に測る方法

はいさい！ちゅらデータぬオースティンやいびーん！

# 概要
JavaScriptでPromiseの処理時間を簡単に測る方法を紹介します。

今回の記事はほぼ備忘に近い記事なので、ささっといきましょうね！

# コード
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a>構文を使って、どのようなPromiseでも測れるようにします！

TypeScriptの型チェックをしてもらえるように、また、VS CodeなどのIDEでIntellisenseの推測もしてもらえるようにJSDocsも添えておきます。

```javascript
//@ts-check
/**
 * Computes the time taken to execute a promise.
 * The result is printed to the console and returned when the promise is resolved.
 *
 * @example
 * // prints to console.
 * timeIt()
 * @param {Promise<any>} promise
 * @returns {Promise<number>}
 */
const timeIt = (promise) =>
  new Promise((resolve) => {
    const startTime = Date.now();
    Promise.resolve(promise).finally(() => {
      const endTime = Date.now();
      const timeTaken = endTime - startTime;
      const timeTakenInSeconds = timeTaken / 1000;
      console.log(`Finished in: ${timeTakenInSeconds} seconds;`);
      resolve(timeTaken);
    });
  });
```

# 試してみる
非常に簡単なコードですが、以下のように、ブラウザのコンソールに落とすだけで、Fetchリクエストにどれほどの時間がかかっているのか簡単に測れます。

筆者が大好きなダミーAPIを使って試してみましょう！

https://jsonplaceholder.typicode.com/

![ezgif.com-gif-maker (13).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2344956/9e9a2ee2-538b-aa55-e8d0-cd78701b0ecb.gif)

# まとめ
いかがでしょうか？Promiseで遊ぶ楽しさを、筆者と同じように嗜めましたでしょうか？

JavaScriptはやはり楽しい言語だなあと日々思います。

今回の記事はあくまで備忘なので、浅薄なところをお許しください！
Viteでimportパスにエイリアスを使う方法

## はじめに
2022年6月29日からLaravelのデフォルトだったバンドルツールがwebpackからViteになりました。
新しいプロジェクトで初めてViteを使うので、Importパスでエイリアスを使うために必要なことを備忘録として残しておきたいと思います。

## バージョン
- Laravel v9.21.6
- Vite 3.0.0
- laravel-vite-plugin 0.5.0

## やりたいこと
``` js
// 相対パスで指定していたimportを
import Hoge from '../components/Hoge'

// こんな感じにインポートしたい
import Hoge from '@/components/Hoge'
```

## vite.config.jsに追記
``` js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel({
            input: 'resources/js/app.js',
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    // 下記を追加する
    resolve: {
        alias: {
            '@': '/resources/js',
        },
    },
    // ここまで
});

```
Dr.Sum Data Funnelで異常値を検出してみた

# 1. はじめに

「[Dr.Sum Data Funnelで前回値を取得してみた](https://qiita.com/LuiLui/items/500459592f89be368110)」ではData Funnelで受信したデータを加工して、前回値というデータを作成しました。

今回はData Funnelで受信したデータを加工して、異常値の検出を設定したいと思います。

Dr.Sum Data Funnelの概要、またはデータファイルでの連携については「[Dr.Sum Data FunnelでCSVファイルを連携してみた](https://qiita.com/LuiLui/items/ae0ce6b36a68ee134fed)」を参考にして下さい。


# 2. パイプライン定義で異常値の検出を設定

「異常値の検出」をクリックします。
※パイプライン定義は「[Dr.Sum Data FunnelでCSVファイルを連携してみた](https://qiita.com/LuiLui/items/ae0ce6b36a68ee134fed)」で使用した「mqttpublish_test」を流用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/18b0774e-4d1f-e18f-7b94-5e5af5f96e21.png)

異常値の検出画面で以下を設定して「追加」ボタンをクリックします。
フラグ項目を追加するを選択
検査項目：VAL
項目名：ERROR_FLAG(任意)
異常値の判定設定
　検定方法：境界値指定
　除去方向：両側
　有効範囲の最小値：0
　有効範囲の最大値：99
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/b2650ecc-41fb-7b50-2184-8c5967f0763a.png)

項目が追加されたことを確認して「OK」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/b8d55037-0fe3-0bd2-e738-1bc6a7eec9cd.png)

※異常値の検出についての詳細は以下のマニュアルを参照下さい。

https://cs.wingarc.com/manual/drsum/5.6/ja/UUID-527bf166-1eb1-eb25-0a7c-2783120d7591.html


#3. プレビューで確認
設定した処理の動作確認をするために、サンプルデータを使用してプレビューすることができます。

パイプライン定義の編集画面から「取り込みデータ」の「テーブル化の設定」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/7edf5922-31d9-70ba-1030-5ab7ebc14604.png)

赤枠の部分に想定するサンプルデータを張り付けて「プレビュー」ボタンをクリック、プレビュー画面にデータが表示されたのを確認して「OK」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/027f7ffe-a0cf-fd49-2916-86a08b0eb9a7.png)

「サンプルデータ」の「［テーブル化の設定］のプレビューデータを追加」をクリックして、サンプルデータが表示されることを確認します。
※「選択セルから貼り付け」ボタンを使用すると、タブ区切りのCSVファイルやExcelから直接貼り付けも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/b6a38424-388b-aa67-6dba-65e18e7f423e.png)

「データ処理」の「プレビュー」ボタンをクリックして「02:異常値の検出」を選択します。
2. で作成した「ERROR_FLAG」が正しく取得できていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/234dd099-98f2-f5a5-c2c2-0e6d87277f63.png)

# まとめ
Dr.Sum Data Funnelの加工処理の「異常値の検出」で異常値の検出と異常値にフラグを設定した項目を追加する方法について説明しました。プログラムを書かなくても手軽に加工処理ができることがわかっていただけたと思います。

ちなみに異常値の検出画面で「除去する」を選択した場合、異常値のデータを生成しないので必要に応じて使い分けて下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/42dbfee2-4c4e-22f6-ec61-91445e6899f8.png)



ウイングアーク1st社のホームページからDr.Sum Data Funnelハンズオンの申込ができるようです。
興味がある方はぜひ申込してみてください！
Dr.Sum Data Funnelで計算項目を追加してみた

# 1. はじめに

「[Dr.Sum Data Funnelで前回値を取得してみた](https://qiita.com/LuiLui/items/500459592f89be368110)」ではData Funnelで受信したデータを加工して、前回値というデータを作成しました。

今回はData Funnelで受信したデータを加工して、計算項目を追加したデータを作成したいと思います。

Dr.Sum Data Funnelの概要、またはデータファイルでの連携については「[Dr.Sum Data FunnelでCSVファイルを連携してみた](https://qiita.com/LuiLui/items/ae0ce6b36a68ee134fed)」を参考にして下さい。


# 2. パイプライン定義で計算項目を追加

「計算項目の追加」をクリックします。
※パイプライン定義は「[Dr.Sum Data FunnelでCSVファイルを連携してみた](https://qiita.com/LuiLui/items/ae0ce6b36a68ee134fed)」で使用した「mqttpublish_test」を流用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/0992853a-9bf5-ec65-ee22-a3581ffc178b.png)

計算項目の追加画面で以下を設定して「追加」ボタンをクリックします。
項目名：CALCULATED_VALUE(任意)
項目のタイプ：式
計算式：[c:VAL:0.0]*2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/1e2081c2-3980-054b-75c2-45ef13bb5088.png)

項目が追加されたことを確認して「OK」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/615e106b-bbc2-ba7a-1204-77166eba7760.png)

※計算項目の追加についての詳細は以下のマニュアルを参照下さい。

https://cs.wingarc.com/manual/drsum/5.6/ja/UUID-73c5527d-36f5-db1c-9356-9268e8b1ef89.html


# 3. プレビューで確認
設定した処理の動作確認をするために、サンプルデータを使用してプレビューすることができます。

パイプライン定義の編集画面から「取り込みデータ」の「テーブル化の設定」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/7edf5922-31d9-70ba-1030-5ab7ebc14604.png)

赤枠の部分に想定するサンプルデータを張り付けて「プレビュー」ボタンをクリック、プレビュー画面にデータが表示されたのを確認して「OK」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/027f7ffe-a0cf-fd49-2916-86a08b0eb9a7.png)

「サンプルデータ」の「［テーブル化の設定］のプレビューデータを追加」をクリックして、サンプルデータが表示されることを確認します。
※「選択セルから貼り付け」ボタンを使用すると、タブ区切りのCSVファイルやExcelから直接貼り付けも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/b6a38424-388b-aa67-6dba-65e18e7f423e.png)

「データ処理」の「プレビュー」ボタンをクリックして「02:計算項目の追加」を選択します。
2. で作成した「CALCULATED_VALUE」が正しく取得できていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1569715/749756f0-bc06-658c-9b51-55e0bb4e2f97.png)

# まとめ
Dr.Sum Data Funnelの加工処理の「計算項目の追加」の取得とパイプライン定義の作成中に加工処理の動作を確認するプレビュー方法について説明しました。プログラムを書かなくても手軽に加工処理ができることがわかっていただけたと思います。

ウイングアーク1st社のホームページからDr.Sum Data Funnelハンズオンの申込ができるようです。
興味がある方はぜひ申込してみてください！
フロントエンド開発ツール Svelte の始め方

# Svelte とは

**[Svelte](https://svelte.dev/)** とは [React](https://reactjs.org/) や [Vue.js](https://vuejs.org/) のようなコンポーネント指向かつリアクティブなフロントエンドUIを簡単に開発できるツールです。

この記事の目的は「始め方」なので、他のツールとの違いや細かい説明は省きます。

# Svelte の学習

事前に用意するものは Chrome だけで十分です。前提知識は(たぶん)必要ありません。

さっそく [チュートリアル](https://svelte.dev/tutorial/basics) ([日本語版](https://svelte.jp/tutorial/basics)) にアクセスしましょう！

このチュートリアルはよくできていて、ブラウザ上でコードを書いて動かすことができます。
画面構成は以下の様になっていて、`①説明を読む` `②コードを書く` `③結果を確認する` を1画面でスムーズに進めることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773745/2d8db14d-4b4e-b42f-edda-2fdf0ec99e9c.png)

進め方はだいたいわかると思うのでここでは省きます。
チュートリアルを完了できれば Svelte の基礎が身につきます。

蛇足ですが、最近話題の [SolidJS](https://www.solidjs.com/) の [チュートリアル](https://www.solidjs.com/tutorial/introduction_basics) もこの形式を採用してます。

# 本格的にアプリケーションを作成したくなったら

本格的にアプリケーションを作成したくなったら、[トップページ](https://svelte.dev/) に記載された以下の手順でテンプレートを作成できます。
([Node.js](https://nodejs.org/en/) を事前にインストールする必要があります)

```sh
npm create vite@latest myapp -- --template svelte
cd myapp
npm install
npm run dev
```

あとは [ドキュメント](https://svelte.dev/docs) を確認しつつ、もしくはチュートリアルを振り返りながら実装することになります。意外とサクサク実装できるはずです。

# まとめ

以上のように、 Svelte は特別なアプリケーションをインストールすることなく手軽に学習できます。是非 Svelte の楽しさを体験してみてください😀
ゼロからはじめる機械学習講座「教師なし学習と自然言語処理入門」


## サンプルソースの公開場所
https://github.com/techgymjp/techgym_ai
実行環境がない場合はanacondaをinstallしてください

### 解説動画
https://youtu.be/rmEmG6nAoXY

# ■1-2：クラスタリング：G9xs.py
【問題】
分類データセット生成の関数を使ってデータを生成してクラスタリングをしてみよう。
(1) make_blobs関数でrandom_state=5として、生成したデータを散布図に書く。
■解答はY7AM.py

(2)クラスタリングをしてクラスタ番号でデータを色分けする。
■解答はF9MH.py

# ■1-5：主成分分析(PCA)：Q3SR.py
　分析対象のデータには多くの変数があり、一つ一つの変数間の関係を調べていくには大変な場合がある。そこで、変数の種類を圧縮しつつ元のデータの性質を残して分析する手法として、主成分分析(Principle Component Analysis)がある。また、数値のもつ意味も変数によって異なることがあり、平均値や標準偏差が異なる場合には単純に数値を比較することが出来ない。そこで、標準化という変換をする。こうすることで、平均値が０で標準偏差が１になり数値の比較が出来るようになる。

【問題】
◎サンプルデータを標準化してグラフ化してみよう。
さらにsp.stats.pearsonrによって相関係数を計算してみる。
■解答はQ9YY.py

# ■1-6：主成分分析(PCA)：E8SS.py
組み込みデータ(アヤメの計測データ)を用いて主成分分析を実行してみよう。アヤメの計測データの特徴量を3次元でプロットする。標準化して主成分分析(PCA)を実行する。主成分分析(PCA)を実行した前後でデータの次元が変化したかを確認する。第1成分と第2成分と縦軸と横軸にしてデータをプロットする。
■解答はT3JE.py

# ■1-8：形態素解析：JB65.py
　自然言語処理をするときに、文章を分解して内容を判断する必要がある。このときに使われるのが形態素解析で、単語の最小単位に分割して品詞の種類や活用を分類する。ここではPythonで使える形態素解析ツールである「Janome」で解析をしてみる。以下のコマンドでインストールすることが出来る。
$ pip install janome

【問題】
(1) 例文'すもももももももものうち'を形態素解析する。
■解答はFT5J.py

(2) 形態素解析をして基本形と品詞のみを表示する。
(Tokenオブジェクトの属性であるtoken.base_formとtoken.part_of_speechによって表示できる)
■解答はMJ8E.py

(3)ファイル“techgym-AI.txt”から文章を読み込んで形態素解析をする。(このとき文章全体も表示してみる)
■解答はCT2P.py

# ■1-9：word2vec：SY7J.py
　文章を形態素に分割することは出来たが、そのままでは文章の意味を扱う事ができない。そこで単語にベクトルを割り当てて数値化することで意味を持たせて扱いやすくする。word2vecはベクトル表現のための手法の一つで、抽象的な意味を表現出来るようなベクトルとして単語を扱える。
word2vecのモデルを作成するライブラリとしてgensimを用いる。インストールは以下を実行する。
$ pip install gensim

この方法を使うメリットとして、単語同士の関係性を計算することが出来るようになる。
例えば、
「王様」- 「男」+ 「女」= 「女王」
「パリ」- 「フランス」+ 「日本」= 「東京」
のように、単語同士の意味を足したり引いたりすることが可能になる。
また、単語同士の意味の近さも計算出来るようになる。

◎与えられた単語を使用してモデルをつくって単語のベクトル表現とベクトルの次元を表示してみる。
■解答はI2NF.py
◎「猫」と「犬」のコサイン類似度を求める。
■解答はWG9Z.py

# ■1-11：word2vec：S6EY.py
　さらに大きな文章で単語同士の関係性を確認してみる。青空文庫(https://www.aozora.gr.jp/) に小説があるので、これを使用してword2vecのモデルを作成して単語同士の関係性を分析してみる。

【問題】
◎青空文庫にある「老人と海」の最初と最後の文章を表示する。(不要な部分を取り除く処理は完了済)
■解答はS3YX.py
◎word2vecのモデルを作成して、「老人」と「海」のそれぞれに対して、
類似した単語の上位5個を表示する。さらに、「老人」と「海」のコサイン類似度を計算する。
■解答はWS2E.py

# ■1-12：word2vec：S3JN.py
　単語をベクトル表現にすることは出来たが、ベクトルが多次元であるので、直感的に人間には理解しにくい形式になっている。そこで、単語同士の相関を分析するために、二次元平面に単語をプロットしてみる。
このとき、主成分分析(PCA)を用いることで次元を圧縮して二次元ベクトルにする。
◎老人」と「海」それぞれに類似している単語の上位100個を平面にプロットして可視化する。
　(このとき可視化するためのdraw_2d_2groupsメソッドを使用する)
■解答はGM8N.py

# ■1-15：word2vec：FP2F.py
word2vecのモデルでは類似度を計算出来るので、単語同士の類似性を活用したアプリケーションをつくりやすい。そこで、今回は、連想ゲームをするチャットボットを作ってみよう。
(HR領域の単語ベクトルとして公開されている200次元のワードベクトルのデータを使用する)

【問題】
◎単語を自分で入力したら類似の単語を表示し、その単語から類似される単語をもう一度入力する。
　これを繰り返して行う連想ゲームをするチャットボットをつくる。
■解答はW3MS.py

# AIエンジニア養成コース（機械学習・ディープラーニング）の概要
https://techgym.jp/about/machine_learning_course/
Android13で追加されたMaterial YouのThemed app iconsに対応する

Android13では、ユーザーのテーマに合わせてランチャーアイコンのtintを設定する機能が新たに追加されました。
これにアプリ側で対応する方法を紹介します。
https://developer.android.com/about/versions/13/features#themed-app-icons
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53293/77f049d5-70a2-ba59-efb8-77bc1a6b8a59.png)


## 対応
Adaptive iconに`<monochrome>`を一行追加すればOKです。
```xml
<?xml version="1.0" encoding="utf-8"?>
...
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <monochrome android:drawable="@drawable/ic_launcher_monochrome" />
    ...
</adaptive-icon>
```

## 参考
https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive
python-pptxでマスタースライドのプレイスホルダーを探す

ちょっと一定の様式のスライドを何枚も連続させる必要がありまして。
![スクリーンショット 2022-08-17 14.56.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192970/45d7e903-bb01-4a03-48f0-5cda15134562.png)
まずスライドマスターとしてレイアウトを作成し、そのレイアウトのスライドに手入力…はめんどくさいので、CSVファイルとかにデータを入れておいて、それを流し込むことにします。VBAは分からないので、PythonでPowerPointのスライドを作れるライブラリ`python-pptx`を使います。

https://python-pptx.readthedocs.io/en/latest/

↓スライドマスターでレイアウトを作った図。今回はこれを`hinagataVisitorWP.pptx`として保存。
![スクリーンショット 2022-08-17 14.06.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192970/a0d3e31a-aca8-5266-fd18-e54df49db7d4.png)
スライドマスターができたので、データを流し込んでみましょう。
```python:test.py
from pptx import Presentation

prs = Presentation("hinagataVisitorWP")
layout = prs.slide_layouts[0] #お目当てのレイアウトを取得

sld = prs.slides.add_slide(layout) #上記レイアウトでスライドを１枚生成
sld.placeholders[0].text = "山古 太郎" #最初のプレイスホルダーに「山古 太郎」を設定...するはずが
# => KeyError: 'no placeholder on this slide with idx == 0'
```
なにやらエラーになってしまいました。どうやらこのスライドには、`placeholders[0]`で特定できるプレイスホルダーは無いらしいです。
プレイスホルダーのナンバリング規則について詳しいことはよく分からないのですが、デザインをいろいろ試行錯誤して最後に残ったプレイスホルダーのインデックスが0〜じゃなかったっぽい。
ということで、これらのプレイスホルダーのインデックス(`idx`)を取得してみましょう。`idx`は各placeholderオブジェクトの`placeholder_format`に入っているらしいので、こんな感じにやってみます。
```python:さっきの続き
for ph in sld.placeholders:
    ph.text = str(ph.placeholder_format.idx)

prs.save("test.pptx")
```
↓出力結果（`test.pptx`)
![スクリーンショット 2022-08-17 14.41.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192970/91cb8ad4-8768-9c3a-5fe7-19c810b4c973.png)
４つのプレイスホルダーの`idx`はどうやらそれぞれ、カテゴリー名欄が10、氏名欄が11、次の人の氏名欄が12、よみがな欄が13だったようです。
ということで、こうして判明したプレイスホルダーに値を設定すればOK。
```python:例
sld.placeholders[11].text = "山古 太郎"
sld.placeholders[13].text = "さんぷる たろう"
```
↓出力結果
![スクリーンショット 2022-08-17 14.33.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192970/cd71b840-0b28-6ea7-5b9b-032ef10419b5.png)
プレイスホルダーへの値の設定方法がわかったので、あとは、スライドを量産したいリストをforで回してどんどん`prs.slides.add_slide(layout)`していけばOK。
Enjoy!!

# 参考文献

https://python-pptx.readthedocs.io/en/latest/user/placeholders-using.html
【js】ブレイクポイント毎の処理

# matchMedia()メソッド


> matchMedia()メソッドは指定された メディアクエリ文字列のパース結果を表す、新しい MediaQueryList オブジェクトを返します。

[MDN詳細](https://developer.mozilla.org/ja/docs/Web/API/Window/matchMedia)

```js
if (window.matchMedia('(min-width: 880px)').matches) {
	console.log('880px以上だよ');
} else {
	console.log('880px以下だよ');
}
```
Lombok Annotation @Data 

### Lombok
Lombokとは、SpringやSpringBootなどに追加してコードを効率的に作成できるようにするJavaライブラリ。クラス名の上にAnnotationを明示することで、GetterやSetterのようなメソッドを別に作成する手間を省いてくれる。

#### @Data 
- 定義
@Getter、@Setter、@ToString、@EqualsAndHashCodeと@RequiredArgsConstructorの機能が含まれている便利なAnnotationである。しかし、最初に設定したデフォルト値を変更する場合、問題が生じるかの世があるため、個々のAnnotationの設定値をデフォルト以外の値に設定して使用したい場合、@Dataの代わりに個々のAnnotationを使用する。
- Annoation
1．@Getter、@Setter：データにアクセスする時に使用
2．@ToString：オブジェクトが持っている情報や値を文字列にして返す
3．@EqualsAndHashCode：equals(Object)メソッドとhashCode()メソッドを作成するAnnotation
4．@RequiredArgsConstructor
　　@NonNullが付いているのfieldと、finalで定義されたfieldを含むコンストラクタを自動的に
　　生成してくれるAnnotationで、@RequiredArgsConstructorを使うと、
　　依存性注入コードに代わってきちんとしたコードを書くのに役立つ。
IBMRPAでパターンマッチングによりメニューを操作してみる

# ボタンをパターンマッチングにより認識して操作したい！
RPAの開発を行っていると、画面のオブジェクトを認識できず、OCRや画像認識によって位置を特定して操作したいケースに少なからず遭遇します。
IBMRPAでは「類似性によるイメージの検索」というコマンドがあり、これを用いることでパターンマッチングによりボタンなどの位置を特定することが可能です。この記事では、「類似性によるイメージの検索」コマンドを実際に使ってみて、使用法などについて説明したいと思います。

# 「類似性によるイメージの検索」コマンド
このコマンドでは、以下のパラメータを指定することで、検索した画像の座標を取得します。その後、その座標に対してクリックなどを行うことで、目的の処理を実装することが可能です。

イメージ：検索する基準となる画像。既存のアセットや、ツールにより選択することが可能です。
前面のウィンドウで検索：これをONにした場合、前面のウィンドウでのみ検索が実行されます。
領域：検索対象となる領域
類似度：検索対象と基準となる画像の類似度。ここが高いほど、厳密に類似性が検証されます。

ここでは、ためしに、IBMRPAの開発ツール上で、レコーダー機能を開始するボタンの領域(中央上の赤い二重丸)をツールで選択して座標を取得し、ログに出力してみることにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117736/5d258fc2-61e8-906c-853c-9abeead4bba7.png)

結果、以下のように、正しく座標を取得できました。また、座標取得後に「マウスクリック」コマンドを用いることでレコーダー機能が開始されることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117736/10b0de36-dd0d-7a32-922f-add14184080f.png)

# まとめ
IBM RPAを用いて、パターンマッチングによるオブジェクト座標の取得を確認することができました。
これ以外にも「OCRによるクリック」というコマンドもあり、ボタンに表示されているテキストをOCR
OCRによって読み取りクリックするようなコマンドも利用可能です。WindowsのオブジェクトのIDを直接取得可能なケースではそちらを用いたほうが確実ではありますが、上手く取得できないケースなどでは、これらのコマンドやキーボード操作を用いてボットを実装することになります。

### ※Japan Business Automation User Groupのご紹介
IBMのコミュニティーである、[Japan Business Automation User Group](http://ibm.biz/JPBizAutomationUG)では、IBMのBusiness Automation製品関連の様々な技術情報、イベント情報の参照や、フォーラムを介した技術的な質問を行うことが可能です。是非ご参加ください。　http://ibm.biz/JPBizAutomationUG
IAM の Switch Role の設定方法

アカウントが増えてくると、それぞれのアカウントでどうやって効率よくサインインするか、ということが問題になります。

Single Sign On はひとつの手段でしょうが、Switch Role 機能を利用するのもよいと思います。

ここでは、ひとつのアカウントから、他のアカウントに Switch Role する方法を述べます。
他のアカウントが、3つあるとします。

Switch Role 元のアカウントで作成するポリシー（Development グループにアタッチ）
ポリシー名：OrganizationAccountAccessRoleDevAssumePolicy

```
{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": [
            "arn:aws:iam::<ACCOUNT_ID1>:role/OrganizationAccountAccessRoleDev",
            "arn:aws:iam::<ACCOUNT_ID2>:role/OrganizationAccountAccessRoleDev",
            "arn:aws:iam::<ACCOUNT_ID3>:role/OrganizationAccountAccessRoleDev"
        ]
    }
}
```

各 Switch Role 先のアカウントで作成したロール
ロール名：OrganizationAccountAccessRoleDev
許可：AWSCodeCommitPowerUser

信頼関係：

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<Switch Role 元アカウントID>:user/ユーザー名"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        }
    ]
}
```

これで、Switch Role 元の IAM ユーザーは、「ロールの切り替え」をクリックして、「アカウント」に Switch Role 先のアカウントまたはエイリアス名、「ロール」に各 Switch Role 先のアカウントで作成したロール名を入れれば、Switch Role が可能です。
VBAでのエラートラップ

# VBA のエラートラップ
## Try 〜 Catch は使えない
エラートラップと言えば「Try 〜 Catch」と言うほど有名ですが、VB系では VB.net からの実装です。
.net ではない VB や、VBA では、使えません。
その代わりに使うのが、`On Error Goto`や`On Error Resume Next`です。
しかし、これらは下記の様なエラートラップのネストが出来ません。
頑張ればそれっぽい事が出来ますが、非常にソースが汚くなります。
```VB:Try のネスト(入れ子)
Try
    ’処理1
    Try
        ’処理2
    Catch ex
        '処理2の例外処理
    End Try
    ’処理3
Catch ex
    '例外処理
End Try
```
## えっ！？ 今時 Goto？
Go To Eat じゃないですよ？
`On Error Goto`をみて「Gotoかよ！」と思った方も多いでしょう。
Goto の是非は嫌と言うほどされてきましたし、**理解して適度に使えば、問題ない**、いや**絶対に使ってはいけない**など色々言われてきましたし、私もどちらが正しいか分からないですが、VBA のエラートラップを使うと便利な時があるのは確かです。
# VBA のエラートラップの有効な使い方
## Excel のワークシートの有無を確認する
Excel のワークブック内に、指定の名前のワークシートが存在するのを確認する方法は、下記の様にワークシートの数分だけループを行い、見つけたら抜ける、最後までループしたら存在しない、という形になると思います。
またワークシート名は大文字と小文字を区別しない為、大文字(又は小文字)に変換して比較する必要があります。

```VB:VBA
'ワークシートの有無を確認
Private Function Check_WorksheetExsist(ByRef objWb As Workbook, ByRef strWsName As String) As Boolean
    Dim objWs As Worksheet

    Check_WorksheetExsist = True
    For Each objWs In objWb.Worksheets
        If UCase(objWs.Name) = UCase(strWsName) Then
            Exit Function
        End If
    Next objWs
    Check_WorksheetExsist = False

End Function
```
これでも良いのですが、もっと簡単に確認する方法もあります。
```VB:VBA
'ワークシートの有無を確認
Private Function Check_WorksheetExsist(ByRef objWb As Workbook, ByRef strWsName As String) As Boolean
    On Error GoTo Err_Check_WorksheetExsist
    Dim objWs As Worksheet

    Check_WorksheetExsist = False
    Set objWs = objWb.Worksheets(strWsName)
    Set objWs = Nothing
    Check_WorksheetExsist = True

Err_Check_WorksheetExsist:
End Function
```
短いですし、ループを回さないので、無駄が無いです。
If 文も無いので、エラートラップの例外で時間がかかる部分も相殺されるでしょうから、シートが多ければこちらの方が高速になります。
ミソは `Set objWs = objWb.Worksheets(strWsName)` の部分。
そのシートが存在しなければ、エラーとなり `Err_Check_WorksheetExsist:` に飛びます。
存在すれば、そのまま最後まで処理が行われます。
# エラートラップを、一時的に無効化したい！
`On Error Goto` や `On Error Resume Next` はエラートラップ処理をしたい時には必須ですが、テスト時にはどこでエラーが発生しているかの確認がしにくくなるため、一時的に無効化したい事があると思います。
その際はVBE(VBA の IDE) の設定を変更する事で無効化出来ます。
1. VBE のメニューバーから「ツール」－「オプション」を選択
2. 開かれたオプションウィンドウから「全般」タグを選択
3. 「エラートラップ」の項目の「エラー発生時に中断」を選択

これで、`On Error Goto` や `On Error Resume Next` が無効になります。
## きっかけは `On Error Resume Next` が効かないPCがあった事
このことを知ったきっかけは、`On Error Resume Next` がうまく機能しないPCがあったからでした。
そのマシンでだけ、Excel のマクロがエラーになるとの事で、デバッグで調べてみた結果、直前で指定されている `On Error Resume Next` が機能していないことが発覚、恐らくエラートラップ絡みの設定だろうという事で調べた所、当該の情報にたどり着きました。
便利な機能ですが、設定を変えたら戻しておかないと、大変な事になりますね。
WakeOnLanをWANとLANで同一アドレスから送信できるようにする

# はじめに
Flaskを用いてPCをWakeOnLanで起動するまでの手順をまとめます。

## WakeOnLanとは
マジックパケットと呼ばれるデータをネットワークに繋がっているPCに送信することでPCを起動させる仕組み。

## やりたい事
WakeOnLanを用いてパソコンにマジックパケットを送る際、LAN内からとWANから送るのにそれぞれプライベートIP、グローバルIPを指定する必要があり、面倒くさいのでFlaskでマジックパケットを送る用のサーバーを作りそこにリクエストを送ることでPCが起動するようにする。


だいたいこんな流れのことをやりたい。
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510530/df85f41f-1c8c-98a8-fb2f-5d323a3b684c.png)


# 1.パソコンの設定をする
こちらが分かりやすかったので参考にさせていただきました。

https://qiita.com/gam0022/items/4c2a3fdc29ac4977b51c#wake-on-lan-%E3%82%92%E6%9C%89%E5%8A%B9%E5%8C%96

# 2.ルーターの設定をする
ルーターの設定ページのから、UDP:9、ブロードキャストアドレスでポート開放をしてください

**例**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510530/55447d9b-fa7b-60ef-e9c8-caa5875faf88.png)

# 3.Flaskサーバーを作る
flaskのバージョンは最新で作りました。
また、マジックパケットはこちらのライブラリを使用して送信しました
https://pypi.org/project/wakeonlan/
```python:app.py
from flask import Flask, request, Response
import wakeonlan

app = Flask(__name__)

@app.route('/send_magick', methods=['GET'])
def send_magick():
    mac_address = request.args['mac_address']
    ip_address = request.args['ip_address']
    # broadcast_address = request.args.get('broadcast', '192.168.0.255')
    port = request.args.get('port', default=9, type=int)

    wakeonlan.send_magic_packet(
        mac_address,
        ip_address=ip_address,
        port=port
    )
    return Response('', status=201)


@app.errorhandler(400)
def error_handler(error):
    return 'Some parameter have not received', error.code


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

本当にシンプルなコードでできました。flask便利。

次に、herokuを用いてflaskサーバーを立ち上げます。
そのために、Procfileとrequirements.txtを作成します
```text:Procfile
web: gunicorn app:app
```

gunicornというのはheroku上でflaskを使うのに必要なライブラリーらしいです。
```text:requirements.txt
wakeonlan
Flask
gunicorn
```

そしたら、これらをGithubにアップロードしてherokuと連携させ、deployしました。

https://github.com/PenguinEino/wol-server

# 4.使ってみる
では、実際にパケットを送ってみます。
https://wakeonlan-web.herokuapp.com/send_magick?mac_address=XX:YY:ZZ:AA:BB:CC&ip_address=xxx.zzz.yyy
このようにMACアドレスと、IPアドレスを指定します(noip.comなどを使ってddnsを設定するのを推奨)
アクセスして、成功するとマジックパケットが送信され、PCが起動するはずです！

# おまけ
今回僕が作ったflaskサーバーを公開しておきます。
webhookなどを使えばgoogle assistant等と簡単に連携できると思うのでぜひ使ってみてください

https://github.com/PenguinEino/wol-server
https://wakeonlan-web.herokuapp.com/
標準出力を整形するもう1つの選択肢、perl5 の format

# 背景
大くの言語にprintf のようなものが、整形のために用意されている。
より強力な表現性を持つ Lisp の format もある。
しかし、コードを実行するまでそれで表現される出力の審美性を捉えることは難しい。
`sprintf "%-4s %02s %13s" , $d->year, $d->mon, $d->fullmonth;`
そこで perl の format だ
# 概要
What you see is what you get
そんなコードが扱うのが簡単である
format はコードと出力の解離が少なく書けるので
選択肢の1つに入れておくと保守性の高いコードを期待できる
# 使用例
![formatingPower.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781693/6203cbab-0767-00b0-bf9c-e3bf049cf510.png)
簡潔で判りやすい命名ができると、もっと見やすくなります。
また右に2つ3つとテーブル表示する時には、
printf では保守しにくいものになりますが、format はヘッチャラです。
# 注意
日本語のような2文字の幅を持つ Wide character は上手く扱えない。
また、見えない文字列としてdye()のような端末ハイライトの文字列も
format は扱い難い。一応パイプで接続して着色なら崩れない。
英語や数字のみを扱う時には機能する
【TypeScript】IDEでTSのファイルをauto importする際に含まれるエイリアスを修正する方法【ts.config.json】

# ts.config.jsonのpathsを修正

```json:tscongi.json
    "paths": {
      "~/*": [
        "./src/*"
      ],
      "@/*": [
        "./src/*"
      ],
    }
```

pathsは複数指定できるものの上から順に優先されて読み込まれる事と、webpack側でのエイリアスの設定と合っているかどうかに気をつけた方が良さそうです。

ちなみに、Next.jsを使用している場合は、ts.config.jsonを修正すれば自動でパスのエイリアスが設定できるみたいなので、webpack側のエイリアスの設定はNext.jsがよしなにやってくれていそうです。

https://nextjs.org/docs/advanced-features/module-path-aliases
Jacksonについて

## Jackson
1. 定義
Java ObjectをJSONに変えたり、JSONをJava Objectに変えるために使用するJavaライブラリ

2. 特徴
（1）XML/YAML/CSVなど様々な形式のデータをサポート
（2）Stream方式で高速かつ柔軟で、Annotation方式でメタデータを記述できる
（3）ObjectMapper APIを使用してObjectにデータを設定する

3. Core Modules
（1）Streaming（jackson-core）
　　 low-level streaming APIを定義する役割とJSON-specific implementationsを含むModule
（2）Annotations（jackson-annotations）
　　 Jackson annotationが含まれているModule
（3）Databind（jackson-databind）
　　 Streaming packageのDatabindingをサポート。StreamingとAnnotations packageに依存

:::note 　 
Databind関連でcom.fasterxml.jackson.databind.exc.InvalidDefinitionExceptionエラーが
発生したときは、そのクラスに@Dataアノテーションを追加してくれると解決できる。
:::
　　 @Dataについては次の投稿に。
html javascript で 3D

今回はサイトの見栄えをよくするための術を再びご紹介します。

下をクリックしてみてください。

https://www.midwam.com/en

かっけえええ....

ではこのようなものはどのようにして作れれているのでしょうか

今回はサイトに3Dモデルを埋め込む方法を紹介します。

# Three.js で3D

### まずは基本。ライブラリのダウンロード

今回使うライブラリはhttps://threejs.org/です。

まずは「Code」の「download」をクリックし「three.js-master.zip」をダウウンロードします。

その次に「three.js-master.zip」を解凍し、
開いて最初にある「tree.js-master」というフォルダを取り出します。

### ディレクトリ構成

ディレクトリ構造は次のようになります。

```bat
.
├── index.js
├── index.html
└── three.js-master/
```

### index.jsのコード

作業用フォルダの「index.js」を編集します。

次のようなものを書きます。

```js:index.js
window.addEventListener("DOMContentLoaded", init);

function init() {
  // 処理を書く
}
```
関数「init()」には「Three.js」を使用するためのコードを書きます。


### index.htmlのコード

作業用フォルダの「index.html」を編集します。

次のようなものを書きます。

```html:index.html
<!DOCTYPE html>
<html>
    <head>
      <meta charset="UTF-8" />
        <!-- モジュール「three.js」を読み込む -->
        <script src="three.js-master\build\three.js"></script>
        <!-- さっきの「index.js」を読み込む -->
        <script src="index.js"></script>
    </head>
    <body>
        <canvas id="myCanvas"></canvas>
    </body>
</html>
```

# 処理を書く

回転する立方体

```js:kaiten-rippoutai.js

window.addEventListener("DOMContentLoaded", init);

function init() {
  const width = 960;
  const height = 540;

  // レンダラーを作成
  const renderer = new THREE.WebGLRenderer({
    canvas: document.querySelector("#myCanvas")
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(width, height);

  // シーンを作成
  const scene = new THREE.Scene();

  // カメラを作成
  const camera = new THREE.PerspectiveCamera(
    45,
    width / height,
    1,
    10000
  );
  camera.position.set(0, 0, +1000);

  // 箱を作成
  const geometry = new THREE.BoxGeometry(500, 500, 500);
  const material = new THREE.MeshStandardMaterial({
    color: 0x0000ff
  });
  const box = new THREE.Mesh(geometry, material);
  scene.add(box);

  // 平行光源
  const light = new THREE.DirectionalLight(0xffffff);
  light.intensity = 2; // 光の強さを倍に
  light.position.set(1, 1, 1);
  // シーンに追加
  scene.add(light);

  // 初回実行
  tick();

  function tick() {
    requestAnimationFrame(tick);

    // 箱を回転させる
    box.rotation.x += 0.01;
    box.rotation.y += 0.01;

    // レンダリング
    renderer.render(scene, camera);
  }
}
```

[ここからダウンロードすることもできます](https://github.com/caleb7023/cube)

[参考](https://ics.media/entry/14771/)

次回、さらに詳しく解説しようと思います。
gemfile.lock がゾンビのように復活する現象への対処

# gemfile.lockが何度消しても復活する。
gemfile.lockが何度消しても、何度stashしても即時で復活して、gitのブランチを切り替えられず困ったので、記事化します。
# 原因
springというライブラリが、バックグラウンドで常にアプリケーションの状態を監視してくれているから。
# 解決方法
　以下のコマンドで自動更新は止まります。
また、動かしたい時のコマンドも記載しておきます。
```bash
# 止めたい時。
spring stop
# もう一度動かしたい時
spring start
```

# Springって何よ？
「アプリケーションをバックグラウンドで実行し続けることで開発をスピードアップする Rails アプリケーションプリローダーです。」

https://pleiades.io/help/ruby/spring.html

らしく、裏で常に動いていることによって自動で、gemfile.lockを常に監視してくれるというありがたい（迷惑？）ライブラリなようです。

# 参考記事
https://qiita.com/masashiiwasaki/items/f593977b9b44df7ebeb4
Deno の test で fetch を stub (mock) する

テスト中、fetch関数の動作を一時的に書き替えて、任意の値を返すように変更する方法について解説します。

## fetchをstubする方法

Denoのテストで一時的に関数の動作を書き換える時は、**標準ライブラリのtesting/mockモジュールを使用します**。

このモジュールにはstub以外にもspyやらFakeTimeやら色々入っているのですが、今回はstubのみ取り上げます。

### stub関数の使い方

以下のように書きます。

```ts:test.ts
// deno test

import { assertEquals } from "https://deno.land/std@0.152.0/testing/asserts.ts";
import {
  assertSpyCallArgs,
  assertSpyCalls,
  stub,
} from "https://deno.land/std@0.152.0/testing/mock.ts";

Deno.test({
  name: "fetch test",
  async fn() {
    const mockFetchText = "__MOCK_FETCH__";
    const fetchStub = stub(
      globalThis,
      "fetch",
      () => Promise.resolve(new Response(mockFetchText)),
    );
    try {
      // テストコード
      const res = await fetch("foo.com");

      // fetchの結果が書き変わっていることを確認
      assertEquals(await res.text(), mockFetchText);

      // fetchの0回目の呼び出しの引数を確認
      assertSpyCallArgs(fetchStub, 0, ["foo.com"]);

      // fetchの呼び出し回数が1回であることを確認
      assertSpyCalls(fetchStub, 1);
    } finally {
      // 必ずrestoreを呼んで、fetchのstubを解除する
      fetchStub.restore();
    }
  },
});
```

ポイントは`stub`関数を呼んでいるところです。
この関数が以下のように呼ばれると以降は`fetch`の実装がモックしたものに切り替わります。

```ts
// globalThis の fetch プロパティを 3番目の引数に渡した関数で置きかえる
const fetchStub = stub(
  globalThis,
  "fetch",
  () => Promise.resolve(new Response(mockFetchText)),
);
```

テストの最後には、必ずstubを解除しましょう。`stub.restore()`関数を利用します。

```ts
try {
  // ここにテストコード
} finally {
  fetchStub.restore();
}
```

:::note
`finally`節の中で呼ぶことで、テストが途中で失敗した場合にもstubが解除されるようにします。
:::

### assertSpyCallArgs / assertSpyCalls

テスト用のユーティリティとして、`assertSpyCallArgs`と`assertSpyCalls`が用意されています。
これらの関数を使うと、スタブがどのような引数で呼び出されたのかや、何回呼び出されたのかが分かります。

```ts
// fetchの0回目の呼び出しの引数を確認
assertSpyCallArgs(fetchStub, 0, ["foo.com"]);

// fetchの呼び出し回数が1回であることを確認
assertSpyCalls(fetchStub, 1);
```

これらの関数は、結果が期待通りでなかった時に`throw`し、テストを失敗させます。


実はこれ以外にもテストに便利なユーティリティー関数がいくつか存在しているので、詳しくは↓を参照してください！

https://deno.land/std@0.152.0/testing/mock.ts

## まとめ

- `fetch`関数をスタブするには、`testing/mock`モジュールを使用する。
- スタブした関数がどのように呼び出されたかを知るには、`assertSpyCallArgs`や`assertSpyCalls`を使う。
メモ:TypeScriptにおけるundefined除去時のfilter, flatMapの違い

## 概要
業務内でTypeScriptで配列から`undefined`を除去する処理を書いていて、`filter`と`flatMap`を使う機会があり違いが気になったのでメモ。

## filter
- 返り値:filterに渡すコールバック関数の結果が`true`である要素のみを要素とする新しい配列
- TypeScript上で`(number | undefined)[]`型の配列に対して`undefined`を取り除くようなfilterをかけても、返り値は`(number | undefined)[]`のため要素が`undefined`である可能性を排除できない

```typescript
const array = [1, 2, 3, undefined, 5]
const filteredArray = array.filter(number => number !== undefined)//undefinedを除去するfilterをかける

console.log(filteredArray[3].toString()) //Object is possibly 'undefined'とエラーがでる
```

## flatMap
- 返り値各要素がコールバック関数の結果であり、深さが 1 にフラット化された新しい配列
- `map()→flat()`の順で処理をした場合と同じ結果になる(少しだけ楽に書ける)

```typescript
const array = [1, 2, 3, undefined, 5]
const filteredArray = array.flatMap(number => number ?? []) //undefinedを除去する処理
//const filteredArray = array.map(number => number ?? []).flat()と同じ
//array.map(): number[][]、array.map().flat(): number[]となり、mapの戻り値が元の型に依存しないためundefinedを削除できる

console.log(filteredArray[3].toString()) //filteredArrayはnumber[]なので、エラーが出ない
```
github actionで、"secret.XXX"に変数が入っている場合のみ処理するやりかたの備忘録

github actionで、"secret.XXX"に変数が入っている場合のみ処理するやりかた

## github actionsについて

以下の公式ページを参照
> [Understanding GitHub Actions](https://docs.github.com/ja/actions/learn-github-actions/understanding-github-actions)


## 例

ghrc(GitHub Container Registry)に、USERNAME/PASSWORDをsecretsに設定している場合のみログインする

```yaml
      # ghcr.ioにログイン
      - name: Login to ghcr.io
        if: env.ENV_GHCR_USERNAME != null
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ secrets.GHCR_USERNAME }}
          password: ${{ secrets.GHCR_PASSWORD }}
        env:
          ENV_GHCR_USERNAME: ${{ secrets.GHCR_USERNAME }}
```



# 参考
[Understanding GitHub Actions](https://docs.github.com/ja/actions/learn-github-actions/understanding-github-actions)
[Workflow syntax for GitHub Actions](https://docs.github.com/ja/actions/learn-github-actions/workflow-syntax-for-github-actions)
[ifelseやswitch文のようにGitHub Actionsのステップの実行を制御したい](https://budougumi0617.github.io/2020/11/21/execute_steps_with_iflese_in_github_actions/)
[GitHub Actions の if, 否定演算子, そして YAML](https://pione30.hatenablog.com/entry/2021/02/05/015545)
[GitHub Actions の環境変数についてメモ](https://qiita.com/hkusu/items/6f75d56b0797d5d4954d)
[Terraform で GitHub Actions の secret を管理する](https://blog.manabusakai.com/2021/07/manage-github-actions-secrets-with-terraform/)
【JavaScript】Cannot read property 'value' of undefined



## 目次

[1. やりたいこと・現在のコード](#1やりたいこと現在のコード)
[1-1. コードの各項目について](#1-1コードの各項目について)
[2. 環境](#2環境)
[3. エラー](#3エラー)
[4. 原因](#4原因)
[5. 最終的なコード](#5最終的なコード)
[6. 感想](#6感想)
[7. 参考](#7参考)
[8. 最後に](#8最後に)


## 1.やりたいこと・現在のコード

JavaScriptの`submit`イベントでformの送信をしたいです。

画像をクリックするとJavaScriptのイベントが実行されて、最終的にformが送信されます。

```html
<td><a href="javascript:void(0);" onclick="javascript:submitHoge( hoge_id );return false;"><img src="/images/icon_smile.gif" /></a></td>
```
```javascript
function submitHoge( hoge_id ){     
    document.form3.hoge_id.value = hoge_id;
    document.form3.submit();
}
```
```html
<form name="form3" action="./sample_a.asp" method="post">
<input name="hoge_id" type="hidden" value="" />
</form>
```


### 1-1.コードの各項目について

#### (1)a href="javascript:void(0);"

| 項目 | 内容 | 
|:-----------|:-----------|
|`<a href="JavaScript:スクリプトコード”>リンクテキスト</a>`|アンカータグのhref属性にスクリプトを埋め込んでいる（JavaScript疑似プロトコル） | 
|void演算子|何も返さない|
|void(0)|アンカータグ本来の動作（リンク）を抑制する。<br>リンク形式でテキストを表示したいけど処理はスクリプトに任せたいときに使用する。 |

#### (2)return false;
今回のケースでは、「リンクをクリックすると、画面遷移する」ブラウザ側の処理を中断するために記載しています。

#### (3)form.submit()

フォームの内容をサブミット（サーバ側や別ページに送信）します。

#### (4)hidden

<input>タグで`type=hidden`と指定すると、ブラウザ上に表示されない非表示データを送信することができます。

※HTMLのソースからは見ることができます。

#### (5)post通信

情報を送信するためのリクエストです。URLにパラメータを付けずに、個人情報やパスワードなどを送ります。


## 2.環境

- windows10 バージョン21H2
- ASP


## 3.エラー

`Cannot read property 'value' of undefined`となってしまいます。

直訳すると「未定義のプロパティ「値」を読み取ることができません」となります。

```javascript
function submitHoge( hoge_id ){     
    document.form3.hoge_id.value = hoge_id; // ここでエラー
    document.form3.submit();
}
```
```html
<form name="form3" action="./sample_a.asp" method="post">
<input name="hoge_id" type="hidden" value="" />
</form>
```
「hoge_id、あるけど・・？」と自分が追加した箇所を確認してもわかりませんでした。


## 4.原因

**form名が重複**していました・・。

自分が書いたコードの記述より上にform3があり、そこには`document.form3.hoge_id.value`がありませんでした。重複した場合、最初のformを参照するんですね。

↓参照されていた別の箇所のform3です。確かに`hoge_id`はありません。

```html
<form name="form3" method="post" action="./sample_b.asp">
<input type="hidden" name="keyword" value="<%=sKeyword%>"/>
<input type="hidden" name="status" value="<%=sStatus%>"/>
</form>
```


## 5.最終的なコード

form名を修正することで、エラーが解消されました。

```HTML
<td><a href="javascript:void(0);" onclick="javascript:submitHoge( hoge_id );return false;"><img src="/images/icon_smile.gif" /></a></td>
```
```javascript
function submitHoge( hoge_id ){     
    document.form4.hoge_id.value = hoge_id; 
    document.form4.submit();               
}
```
```html
<form name="form4" action="./sample_a.asp" method="post">
<input name="hoge_id" type="hidden" value="" />
</form>
```


## 6.感想

後で気づけば単純なことでも、見つけるまでに時間がかかってしまいました。

コードの全体を眺めて動きを確認しつつ、実装をしていきたいと思います。


## 7.参考

山田祥寛, 改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで, 技術評論社, 2016

https://www.sejuku.net/blog/28728

https://web-camp.io/magazine/archives/12442

http://www.htmq.com/html/input_hidden.shtml

https://blog.senseshare.jp/get-post-method.html

https://techacademy.jp/magazine/26836

https://web-camp.io/magazine/archives/6893


## 8.最後に

記事の感想や意見、ご指摘等あれば伝えていただけるとありがたいです。
読んでいただき、ありがとうございました。
System.InvalidOperationException: 'Unable to configure HTTPS endpoint.

デバッグ時にエラーが発生し実行できなくなる
---
エラーはMainで発生し、下記のメッセージが表示される

```:エラーメッセージ
System.InvalidOperationException: 'Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found or is out of date.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.'
```

環境
---
- Windows10 Pro
- Visual Stuido 2022 Pro
- .NET5 C# MVC

解決策
---
次の2つのコマンドを実行する
```powershell:.NET CLI
dotnet dev-certs https --clean
dotnet dev-certs https --trust
```

解決策の出所
---
下記ページの「証明書に関する問題のトラブルシューティング (信頼されていない証明書など)」を参照

https://docs.microsoft.com/ja-jp/aspnet/core/security/enforcing-ssl?view=aspnetcore-5.0&tabs=visual-studio#all-platforms---certificate-not-trusted