OmniAICreator/Qiita-1.07M huggingface dataset:
指定したURL内＆特定タグ範囲の画像をダウンロードしたい

　ここ数年、Web発の出版物が日本でも目立って増えてきました。昨年のJEPA電子出版アワードの大賞をピースオブケイクのnoteが取ったことに象徴されるように、日本でもようやくWebがかつて雑誌の担っていた「告知」の役割を果たし始めているということだと思います。コミックに関してはもうずいぶん長くそれが続いているのですが、それ以外のジャンルにもどんどん波及し始めたというのがここ数年の新しい動きです。
　さて、そうなってくると、技術サイドとしてもWebサイトからデータを取得し、電子書籍データや最終的には紙の出版物を作るためのルートを整備しなければ、という気分になってきます。ということでここ最近はWebスクレイピングの技術を学び始めているのですが、試行錯誤してどうにか指定したURL内＆特定タグ範囲の画像をまとめてダウンロードできるようになったのでメモ代わりに置いておきます。なお、「特定タグ範囲」が今回キモです。サイドバーとかに大量に並ぶアイコン類の画像はあっても困るので。ブログ等で各エントリー部分の画像だけを抽出したいわけです。


 
<pre class="lang:perl decode:true " >#!/usr/bin/perl
#use strict;
#指定したURL内、指定タグ範囲内の画像をダウンロードして保存
use utf8;
use Encode qw/encode decode/;
use File::Basename qw/basename dirname/;
use LWP::UserAgent;
use HTML::TreeBuilder::XPath;
use HTML::Selector::XPath 'selector_to_xpath';
use XML::LibXML;

#処理対象のURLを取得
my $targetURL = $ARGV[0];
$targetURL = decode('UTF-8', $targetURL);

#出力先フォルダ指定
my $exportFolderPath = $ARGV[1];
$exportFolderPath = decode('UTF-8', $exportFolderPath);

#WebサイトからHTMLテキスト取得
my $ua = LWP::UserAgent-&gt;new;
my $response = $ua-&gt;get($targetURL)-&gt;content;
$response = decode('UTF-8', $response);

#取得したHTMLをまずHTML::TreeBuilder::XPathでパース、指定部分だけHTMLとして抜き出し（この場合はclass名「post」で囲まれた範囲を指定している）
my $tree = HTML::TreeBuilder::XPath-&gt;new;
$tree-&gt;parse($response);
my @htmlPart = $tree-&gt;findnodes(selector_to_xpath('.post'));
my $htmlString = $htmlPart[0]-&gt;as_HTML;
$htmlString = encode('UTF-8', $htmlString);

#HTMLをXML::LibXMLで再度パース
my $parser = XML::LibXML-&gt;new();
$parser-&gt;no_network(1);
my $dom = $parser-&gt;parse_html_string($htmlString);

#imgタグのsrc属性の値をリスト化
my @imageUrls;
foreach my $imageTagNode($dom-&gt;findnodes(selector_to_xpath('.post img'))){
  my $imageURL = $imageTagNode-&gt;findvalue('@src');
  #画像以外をはじいてリストにpush
  push (@imageUrls, $imageURL) if ($imageURL =~ /(jpg|jpeg|png|gif)$/i);
}

#画像ダウンロード実行
foreach $imageUrl (@imageUrls){
  &amp; downloadImage($imageUrl);
}
exit;

sub downloadImage {
  #ダウンロード対象のURLを取得
  $targetImageFileURL = $_[0];
  #ファイル名取得
  my $exportFilename = basename $targetImageFileURL;
  #出力
  system "curl " . $targetImageFileURL . "&gt;" . $exportFolderPath . "/" . $exportFilename;
}</pre> 

ターミナルで
 
<pre class="lang:sh decode:true " >perl このスクリプトのパス 処理対象のURL 画像保存先フォルダ</pre> 

の順で指定すれば画像を一括でダウンロードします。

　最初にHTMLパーサーモジュールでパースし、その後XMLパーサーモジュールで再度パースしています。いきなりXMLパーサーモジュールにHTMLを食わせたらエラーで動かなかったためです。Validでない構文の読み込みには（オプションあるとは言え）弱いということなのでしょう。まあ仕方ない。なお今回初めて使ったモジュール、<strong>HTML::Selector::XPath</strong>がスゴい便利です。CSSの指定構文で書けばXPathに内部変換してくれるとか素晴らしい。
　今回は抽出テストにこのブログ（システムはWordPress）の過去エントリを使ったので措定範囲が「.post」ですが、ここは抜き出し対象のサイトごとに書き換えが必要になる感じです。変数化して引数で指定できるようにしても良かったけどどういう絞り込み条件があるかわからんのでとりあえずはコレで。
　さて次は本文テキストだぜ・・・。
jestとenzymeとtestCafeについて

# 概要
本文は開発のtest関係の記事です。
仕事でjestとenzymeとtestCafeとそれぞれのテストフレームワーク・ツールを利用することになりましたが、それらの差がわかっていなかったので、まとめました。
初学者がネットで検索した情報をもとにまとめたものですので、間違ったところがあればなんなりご指摘ください。

# テストフレームワーク・ツール一覧表
| フレームワーク      |公式ドキュメント|作っている会社|
|-----------------|-----------------|-----------------|
|jest|https://jestjs.io/ja/|facebook|
|enzyme|https://airbnb.io/enzyme/ |        airbnb        |
|testCafe |https://devexpress.github.io/testcafe/ |DevExpress|

# それぞれの詳細
## jest
コンフィグなし、スナップショットが撮れること、独立していること、優れたAPIがあることなどが特徴。
vsCodeのアドオンもあるようです。
https://github.com/jest-community/vscode-jest

### 参考になりそうなサイト
https://app.codegrid.net/entry/2018-jest-1
https://qiita.com/chimame/items/e97883fd46b67529d59f
https://qiita.com/moriaki3193/items/bc1120d572d55038d2d0

# enzyme
ユニットテスト（コンポーネント単体ではなく総合的にするテスト）を助けてくれるテストユーティリティツール、jestで足りていない機能を補うのに便利らしい。
[Reactの公式ドキュメントでも使用が推奨されている](https://ja.reactjs.org/docs/test-utils.html#overview)

### 参考になりそうなサイト
https://devhints.io/enzyme
https://mae.chab.in/archives/60066
https://qiita.com/putan/items/c43afc15cbdccd28075f


# testCafe
UIテスト自動化フレームワークの１つ。
分類としては[Selenium](http://oss.infoscience.co.jp/seleniumhq/docs/index.html)に近いらしい。
有料ですが、[testCafeスタジオ]
(https://www.componentsource.co.jp/product/testcafe-studio/prices?utm_source=google&utm_medium=cpc&utm_campaign=ga11%5Fjp%5Fja&gclid=Cj0KCQiApaXxBRDNARIsAGFdaB%2Dijvj4N%2DN%5Fxl%2D7u3u6Njb6gWGKD1gWDzcQL1r4RGLm0J3m4AXbYIsaAr6UEALw%5FwcB)なんていうのもあるらしいです。

### 参考になりそうなサイト
https://www.dcom-web.co.jp/lab/test/try_testcafe
https://tech.pjin.jp/blog/2019/06/19/testcafe_tutorial/
（途中から有料）https://app.codegrid.net/entry/2017-testcafe-1


# 記事を書きつつあんまりわかっていないこと
それぞれ単体テストのためのツールなのか、結合試験のためのツールなのかわかってないです。

# まとめ
今回はテストフレームワーク・ツールについてまとめてみました。
いずれを使うにせよ、**期待した通り** になっているかをコードで書けていればいいのかなと思っています。テスト駆動開発について深掘りしたらもっとこの辺のことよくわかるんですかね？
Amazonが「置き配」を標準の配送方法として指定。実証実験エリアを拡大！

Amazonの**標準**の配送が「**置き配**」となるエリアが増えます。
2019年に岐阜県多治見市で実施された実証実験に続き、
下記地域が**2020年1月27日**より実証実験を順次開始するエリアに選ばれました。

- 東京都3区（江東区、文京区、練馬区）
- 大阪府3区（都島区、西淀川区、生野区）
- 名古屋市
- 札幌市

多治見市の検証では再配達が50%も削減されたという結果も出ているようなので
東京都内や大阪など主要都市で一人暮らしが多いと予想される地域では更に効果があるのではないかとも思っています。
どちらにしてもECサイトが今後更に発展するとしたらヤマトや佐川急便などの流通網と配達の問題は一番切り離せないのでWINWINになる有意義な検証ではないでしょうか。

なので個人的には嬉しいです。
宅配ボックスがあるマンションなどの方は気にならないかもしれませんが、
宅配ボックスのある家って意外に少ないですよね。
荷物を受け取るためだけに休日の時間を調節して家にいないといけないというのも減ります。

また、治安や雨天時など不安な方ももちろんいらっしゃるかと思います。
そういう場合は基本は置き配で明らかに高価なモノの時は置き配指定を変えればいいだけかと思います。
そういう使い分けでもいいかと思います。

個人的には東京都内のエリアももっと広げてほしいですね。

https://amazon-press.jp/Top-Navi/Press-releases/Presselist/Press-release/amazon/jp/Ops/unattended-delivery-20200122/Unattended-Delivery-20200122/
pythonのdataclassで後ろに継承したい

各dataclassで共通のフィールドがほしい、でもデフォルトの値を付けたいから普通に継承すると前にこれがついてtypeerror。つらいさんなのだ

# だめ

``` python
from dataclasses import dataclass

@dataclass
class Base:
   base: int = 10

@dataclass
class Extend(Base):
    extend: int

```

typeerrorです

あと、`@dataclass`していないclassを継承しても継承元のフィールドは(\_\_init\_\_には)継承しないみたい。

# 正直読みにくいけどまあ解決

デコレータを書きます

``` python
from dataclasses import dataclass

def add(c):
    @dataclass
    class wrap(c):
        added: int = 10
    return wrap

@add
@dataclass
class DataClass:
    field: str
```

欠点としては、インタプリタで名前じゃなくて`<locals>.wrap`になることですね

``` python
>> DataClass
<class '__main__.add.<locals>.wrap'>
```

## 追記

どうやらclassの名前は`__qualname__`にあるらしい。

``` python
def add(c):
    @dataclass
    class wrap(c):
        added: int = 10
        __qualname__ = c.__qualname__
    return wrap
```

``` python
>> DataClass
<class '__main__.DataClass'>
```
Rのカイ二乗検定で回転寿司を嫌がる男を調べる

# 事の発端

先日、ふと次の記事を見つけました。

[初デートで「回転寿司」ってアリ？ナシ？男女の答えが意外な結果に](https://cancam.jp/archives/202166/3)

>「初デートで回転寿司に行く」のはアリ？ナシ？
>
>＜男性＞
>「アリ」44.4％
>「ナシ」55.6％
>
>＜女性＞
>「アリ」58.6％
>「ナシ」41.4％
>
>意外なことに、男性よりも女性の方が「アリ」と考えているよう！　気軽で緊張しない感じが「逆に」初デートでもOKということらしいです。

この記事では「初デートで回転寿司に行くのは、男性の方が抵抗感がある」と結論づけていますが、本当に男女で『アリ』とする割合に有意な差があるのでしょうか？
それとも、回転寿司への抵抗感について、本当は男女で差分はないけれども、たまたまアンケート結果がバラけてしまって差分が生じてしまっただけなのでしょうか。

気になったので、カイ二乗検定を使って独立性を調べてみます。

# カイ二乗検定とは？

カイ二乗検定の説明は、次のサイトがわかりやすいです。

[カイ二乗検定 | Logics of Blue](https://logics-of-blue.com/chi-squared-test/)

>χ二乗検定は別名「独立性の検定」とも呼ばれます。
独立という言葉はやや難しいのですが「独立→関係がない」「独立でない→何か関係性がある」と解釈してもらえれば結構です。

今回の場合は、「性別」と「初デートで回転寿司に行くことに対する抵抗感」が独立かどうかをカイ二乗検定で調べることになります。

# Rによるカイ二乗検定

Rでカイ二乗検定を行いたい場合は、標準関数である`chisq.test()`を使えば一発で実行できます。

```r
# サンプルサイズは男女ともに500人ずつ
data <- matrix(c(500*0.444, 500*0.556, 500*0.586, 500*0.414), ncol=2, byrow=T) 
chisq.test(data)

# 	Pearson's Chi-squared test with Yates' continuity correction
# 
# data:  data
# X-squared = 19.618, df = 1, p-value = 9.459e-06

```
今回のケースでは、`p-value = 9.459e-06`となるため、有意水準5%において「性別と抵抗感の有無は独立ではない（関連がある）」と結論付けられます。

# ちなみに

僕は回転寿司は全然アリ派です。
Cloud SQLはインスタンス起動してるだけで費用がかかるので注意

## はじめに

クラウドに明るい方からすれば当たり前の内容かもしれませんが、[Cloud SQL](https://cloud.google.com/sql)の検証をしていたところ想像以上に費用がかかっていたのでその調査をしました。

## 検証していた内容

Cloud SQLを使って検証していた内容は以下のとおりです。

- Cloud RunとCloud SQLの接続を検証
- Cloud Runで `SELECT now();` のクエリを実行
- Cloud SQLのDBにはテーブル作成も行っておらず、データ投入も行っていない
- インスタンスはデフォルトの設定で作成
- 2日間ほど実施

## 費用の内訳

GCPのレポートを表示し、 `グループ条件` を `SKU` に変更して、内訳を確認します。
各SKUの単価は[SKUs  |  Google Cloud](https://cloud.google.com/skus/?currency=JPY&filter=DB+custom+running+in+japan)で確認できます。

<img width="1409" alt="e.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40689/7f71090a-acf5-afa8-85ea-396d6ed838b4.jpeg">

10円以上かかっている以下の3件について詳しく見ていきます。

- DB custom CORE running in Japan (with 30% promotional discount)
- DB custom RAM running in Japan (with 30% promotional discount)
- Storage PD SSD for DB in Japan

### DB custom CORE running in Japan (with 30% promotional discount)

- CPUに関する費用です
- 48時間利用で282円かかっています
- [SKUs](https://cloud.google.com/skus/?currency=JPY&filter=DB+custom+running+in+japan)によると1時間あたり約5.878円なので妥当です
    - この金額は[Cloud SQL の料金](https://cloud.google.com/sql/pricing?hl=ja#pg-pricing)に記載のvCPUの金額とも一致します
- 下記グラフを見て分かる通り使用率に関わらず費用がかかります
<img width="1017" alt="スクリーンショット 2020-01-22 11.59.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40689/432e75b5-3df4-1547-d923-855c248b191d.png">

### DB custom RAM running in Japan (with 30% promotional discount)

- メモリに関する費用です
- 180GiB hour利用で179円かかっています
- [SKUs](https://cloud.google.com/skus/?currency=JPY&filter=DB+custom+running+in+japan)によるとGib hour単位あたり約0.996円なので妥当です
    - この金額は[Cloud SQL の料金](https://cloud.google.com/sql/pricing?hl=ja#pg-pricing)に記載のメモリの金額とも一致します
- CPUの利用時間の48時間から逆算すると1時間あたり3.75GiB(180GiB hour/48hour)使用している計算になります
- ただし、メモリ使用量のグラフを見ると最大626.3MiBしか利用しておらずグラフに載らない部分があるのかもしれません
<img width="1019" alt="スクリーンショット 2020-01-22 11.57.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40689/902ee510-4064-1568-2753-b453197431c9.png">

### Storage PD SSD for DB in Japan

- ストレージに関する費用です
- 0.65GiB month利用で16円かかっています
- [SKUs](https://cloud.google.com/skus/?currency=JPY&filter=Storage+PD+SSD+for+DB+in+Japan)によるとGiB month単位あたり約24.191円なので妥当です
    - この金額は[Cloud SQL の料金](https://cloud.google.com/sql/pricing?hl=ja#pg-pricing)に記載のストレージの金額とも一致します
- ストレージ使用量のグラフ配下でした
- テーブル作成等行わなくてもこれくらいのコストはかかるようです
<img width="1016" alt="スクリーンショット 2020-01-22 10.29.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40689/084f162e-c596-3808-654a-2d953a007b2c.png">

## 対策

インスタンス起動しているだけでもこれくらいの費用がかかるため、費用を抑えたい場合はこまめにインスタンスを停止させるか、費用が小さいリージョンを使うと良さそうです。

## 参考にした記事

- [CloudSQLを安くするために考えたこと - ludwig125のブログ](http://ludwig125.hatenablog.com/entry/2019/05/24/111446)
SEの英会話あれこれ

##2018年頃から海外のエンジニアと仕事をするようになった

どうしても英会話のスキルが必要になってきました。
そもそもIT系の技術については海外（英語）の文献もあり、本来英語力があったほうがいいのは間違いありません。
しかし、Webページ翻訳やGoogle翻訳で事足りてきたのも事実です。

##英会話をする必要がでてきた
実際に海外のエンジニアと週１会の定例ミーティング（オンライン）や、現地でのミーティングでどうしても英語で会話する必要がでてきました。
まったく英語が話せないので、非エンジニアが通訳で入ってもらう場合もありますが、やはり技術用語の翻訳は難易度が高そうです。


##本題
この記事は英会話力が小学生レベルの私の学習メモです。（ちなみに日本語力も低いです）


##学習ツール
**オンライン英会話**
昔はSkype利用がほとんどでしたが、サービス内で完結するものが増えてきてます。WebRTCが活発になってきた恩恵だと思います。
私はNativeCampを利用してます。ポイントとしては、Skype不要、予約不要、利用無制限、教材が分かりやすい等です。とくに予約不要で空いてる講師を選べるのは気軽で助かります。

NEW(2020/5/7)
NativeCampは解約しました。徐々にレッスン料が増え、また、忙しいとしばらく放置してしまい、無駄になってしまってたからです。いつでも利用できるのはいいのですが、イマイチな講師にあたった時にモチベーションが落ちてしまいます。
そこで、最近利用しているのは「スピークバディ」です。AIと会話するアプリですが、これならわずかな空き時間でも利用できます。ヒアリング、スピーキング両方できます。月額は1,950円でお手頃でもあります。


**Youtube**
聞き流し系の動画がけっこうあります。画面みなくても、英語→日本語という動画もあり、BGM的にかけて聴く力を鍛えてます。
https://www.youtube.com/channel/UCGfdWj0v3L_jGZP0KglWiWQ
https://www.youtube.com/channel/UCnEi7lDunUdVaHABvS-S3ag
https://www.youtube.com/channel/UCTYQzAi6YOcgv2mkzsfzmpA
NEW(2020/5/7)
こちらのチャンネルはdidの使い方や、リンキングとかについて分かりやすい説明があります。
https://www.youtube.com/channel/UCMyKJf1YPXkCfBvwT6K0g8w

- Google翻訳
万能ではないですが、自分の英作文が正しいかのチェックにつかってます。ポイントとしては短めの文章を書いていくほうが精度が高いと思います。

- 映画
セリフをほぼ覚えている映画の英語バージョンを繰り返しみています。最初は聞き取れませんが少しずつなれてきます。
又、子供向けアニメもおすすめです。おすすめはPJ Masks。

- スペルチェックツール
[grammarly](https://www.grammarly.com/)を使ってます。ブラウザで英語入力中に文法ミスなどを指摘してくれます。冠詞（theとかaとか）はよく抜けるのでたびたび指摘されます。

- kindle unlimited
英語の本は買ってみたものの全然読まない、自分に合わないという場合もあります。
kindle unlimitedで何気に検索してみたら意外に英会話の本が多くありました。定額なのでガンガンダウンロードして合わなかったらすぐ他の本に移行できます。


###話す（書く）場合
**とにかく短い文章で伝えたい事を話す！**
これに限ります。かっこよくペラペラと話せたらいいのですが、初心者には無理です。
I have problem.
I can not see a video.
I can not reason.
とか言っておけば相手が察してくれる場合もあります。
他には相手が過去につかったフレーズをこちらも再利用すると伝わりやすいです。

###聞く場合
**魔法の杖はありません！**
とにかく、まずは聴く力をトレーニングするしかありません。私は毎日映画(タイトルはBack to the Future)を通勤時間等でみています。

##表現が難しいフレーズ
問題点を相手に伝えるときに表現が難しい場合があります。Google翻訳にかけてもイマイチだなと感じる場合もあります。以下は実際に悩んで、なんとか適した表現がみつかったフレーズの例です

**音声が途切れる、プツプツする**
・some time can not hear, some time can hear
・some time audio interruption
・intermittent voice
・choppy

**同時接続数**
・concurrent users

**自映像、他拠点映像**
・local side
・remote side

##続く！
引き続きこの記事はアップデートしていきます。
セッションとクッキーの違いについて調べてみた

# まえがき
クッキーという言葉はプログラミングをしていなくても聞くことが多いと思います。`クッキーを削除`、`クッキーを保存しない`など....。しかしクッキーというものの正体を正確に把握している人は少ないのではないでしょうか。また、クッキーと似たような仕組みでセッションというものがあります。そのクッキーとセッションの違いについて詳しく知りたくなったので調べてみました。

#ログイン機能について知る
まずそれらを理解する前にログイン機能を例にして実際にどのようにクッキーやセッションを使っているのかを考えていきます。

###webサイトを見る仕組み
普段、`http`を使い私たちはネットワークのwebページを見ているわけなのですがその`http`というものには`サーバー`というものと`クライアント`というものが存在します。
`サーバー`というものは`画面のないパソコン`のようなもので`常に動いているもの`という簡単な認識で大丈夫です。
そして`クライアント`というのは私たちが今使っている`パソコン`や`スマートフォン`などのことです。
私たちクライアントは何かwebサイトを見たいときにそのサーバーに`リクエスト`というものを送ってサーバーが`レスポンス`を返してそのレスポンスがwebサイトの画面となって表示されるわけです。
###ログイン機能
そしてログインについて考えてみます。
ログインというものはクライアントがサーバーに「ログインしますけどいいですか？」というようなリクエストを送り、サーバーが「ログインしてもいいよ」というようなレスポンスを返すことによって成立します。
###httpの性質
しかしhttpというものは状態を保持するという機能を備えていません。
それによりどのような問題が起こるかというとログインしているという状態を継続的に保つことができないというわけです。
ですのでhttp本来の性質の上でwebサイトを見た場合、**ページを切り替えるたびにログインすることを求められる**のです。
そのような仕様ではログイン機能は使い物にならなくなってしまいます。
そこでその`状態を継続的に保てない`というような性質を解決するためのものが`クッキー`や`セッション`です。
#クッキーとは
>Cookieとは、Webサイトの提供者が、Webブラウザを通じて訪問者のコンピュータに一時的にデータを書き込んで保存させる仕組みのことです。

噛み砕いて説明します。
先ほど書いたようなログイン状態を保持する状況というものがあったときにその状況をどのように保持するかということですが、このクッキーはその保持した状態をサーバー上に保存しておき、その状態に`番号という名前をつけ`その番号を`ユーザーに渡します。`そうすることでユーザーはそのログインした状態につけた番号を保持した状態なのでユーザーがその番号を持っている限りはログインを保持することができます。そのユーザーとはユーザーのブラウザのことです。（例えばGoogleChromeやInternet Explorerのこと）そしてその、**サーバーに情報を保存し、その情報をユーザーに渡す仕組み**のことを`クッキー`と言います。また、ログイン状態をサーバー側に保存することで**クライアント側から情報を改変することができない**ので比較的安心して情報を保持することができます。ちなみにクッキーは有効期限があるので古い情報は消されてしまいます。


#セッションとは
>セッション とは コンピュータネットワークでは、接続を確立してから切断するまでの一連の通信のこと。 HTTPのサイトでは、セッションにIDを振ることで同一のセッションを管理することができる。 また、一連のインタラクティブな操作(例えばログインしてからログアウトするまで)を指す場合もある。

セッションとはログインしたという状態をサーバーに渡して、そのユーザーが**ブラウザを閉じるまでログイン状態を保持する**というものです。セッションはクッキーとは違いブラウザを閉じたらログインしたという状態を失ってしまいます。そしてクッキーのようにユーザーに渡される情報もないです。一時的にログイン状態を保持という認識で大丈夫だと思います。
#クッキーとセッションの大まかな違い
クッキーとセッションの違いは仕組みはもちろんですが、**ブラウザを閉じたときにログイン状態を保持できるかどうか**だと思います。もちろんログイン機能以外でも用いられる技術ですので、詳しく知っておけば応用を利かせることができるのではないかと思います。

#あとがき
以上です。クッキーとセッションの概念的な部分だけ考えてみました。少しでも役に立てましたら嬉しいです。
また、言葉足らずな部分や間違っている部分が多々あるかもしれませんので指摘等がありましたらよろしくお願いします。
リストの中身を繋げて文字列にする方法 

# リストの中身を繋げて文字列にする方法 

案外文字列作るやり方がなかったので、初歩的ですが

```
l = ['a', 'b', 'c', 'd', 'e']

a = ' '.join(l)
print(a)
```

出力結果

```
'a b c d e'
````

**結合する文字列は（str型）である必要があり。**
要素が数値の場合は、例えばmap()関数などでstr型に変換する必要がある。

```
b = '_'.join(map(str, l))
print(b)
```
出力結果

```
'1_2_3_4_5'
```
Slackワークフローでコードレビュー依頼をテンプレ化した

# ■ はじめに
弊社では、Slackの特定のチャンネルにて、PRのリンク＋テンプレ文でコードレビュー依頼を投げています。
担当者あてにメンション付けて、「お疲れ様です！〇〇の実装です。レビューお願いします！」
...大した文言ではないですが、数が増えるとなんとなくしんどい。

そんな時「フォームから必要事項を入力させ、入力内容を特定のチャンネルにメッセージとして投函」
といったことができる「Slackワークフロー」というものが公式から出てきたので早速使ってみました。

# ■ Slackワークフローについて
早速リンクで申し訳ないですが、
下記の記事にて非常に丁寧にまとめておられるので、こちらをご確認ください。

[徹底解説！Slack ワークフロービルダー（Workflow Builder）](https://qiita.com/kazushi_iizuka/items/5cd9c3bb0bde9803cac0)

# ■ 実際に作ったワークフロー
<img width="500" alt="スクリーンショット_2020-01-24_10_45_32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198420/673814fb-bc2d-f304-9e72-68b3b87dfb0f.png">

1. 担当者を一覧から選択
2. PRのリンクとタイトルをテキストボックスに貼り付け
3. 投稿を押すと、個人メンション＋グループメンション＋投稿者名でメッセージ送信！

という具合です。

実際に投稿するとこんな感じ↓↓↓↓↓
<img width="625" alt="スクリーンショット_2020-01-24_11_18_25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198420/f5e2960d-6cab-2984-223c-95528cc236e4.png">


# ■ ちょっとしたこだわり

## ▶︎ メンション付き投稿
実際に運用してみると、適切な担当者にメンションがつかないという問題が発生。

解決策として、特定のメンバーをリストから選択し、投稿させるというフローを作りました
「メンバーを選択」メニューでは、社内の登録されているアカウント全員が対象となってしまうため、
「一覧から選択」メニューを選択し、下記のように『 *<@xxxx>* 』と登録することで実現しています。
<img width="485" alt="スクリーンショット_2020-01-24_11_42_10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198420/3f1aa873-1377-152b-83b4-fe97e3d1be2a.png">


※登録するメンションは「user_id」を登録します。下記の記事に取得方法がまとまっていますので、ご確認ください。
[SlackのIncoming Webhooksでメンションを飛ばす方法](https://qiita.com/ryo-yamaoka/items/7677ee4486cf395ce9bc)

## ▶︎ 投稿内容をいい感じに
BOTから投稿されるメッセージの設定では、「変数を挿入する」メニューを駆使することで、文字通り”いい感じ”にすることができます。

ワークフローを使用すると、BOTからの投稿になってしまうので依頼者がわからないため、投稿者を表示する設定を入れています。
<img width="490" alt="スクリーンショット_2020-01-24_10_50_53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198420/ba34eec9-514b-e604-33cb-ea96d88800a2.png">
【Swift】touchesMovedが実行される最小移動量について【Tips】

連続的なジェスチャーの検知に使われる `touchesMoved` が実行されるタイミングに関して調査してみたので簡単にまとめる。

# 検証環境
- Swift５．０
- iPhone6s（iOS13.3）

# 検証方法
以下の様なコードでコンソールに測定した位置を出力することで検証した。

```
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
    let latestTouch = touches.first
    let newPoint: CGPoint = (newTouch?.location(in: view))!
// previousPointはクラスのプロパティとして保持
    let translation = CGPoint(x: previousPoint.x - newPoint.x, y: previousPoint.y - newPoint.y)
    previousPoint = newPoint
    print(translation)
```

# 実行される最小移動量
上記の検証コードを用いて上方向にまっすぐゆっくりとスクロールしていくと以下のようなログが出力される。

```
(0.0, 0.5)
(0.0, 0.5)
(0.0, 0.5)
(0.0, 0.5)
(0.0, 0.5)
(0.0, 0.5)
```
つまり、 `touchesMoved` が実行されるには最小で0.5ptの移動が必要、ということになる。
間違い等あればコメントをおねがいします！
#Ruby で Shift JIS と UTF-8 を相互変換できないので Windows-31j(CP932) でエンコード・デコードする ( Encoding::UndefinedConversionError )

# 現象

特殊文字 ㈱ が相互変換できない

```rb

'㈱'.encode("Shift_jis").encode('UTF-8')
# Encoding::UndefinedConversionError: U+3231 from UTF-8 to Shift_JIS

'㈱'.encode("cp932").encode('UTF-8')
# => "㈱"
```

# Ref

RubyでShift JISやCP932などのCSVをUTF-8に変換して読み込む - Qiita
https://qiita.com/daichi87gi/items/9097adfd47d9725097f1

RubyでShift JISやCP932などのCSVをUTF-8に変換して読み込む - Qiita
https://qiita.com/daichi87gi/items/9097adfd47d9725097f1

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2958








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
logrotate対象に、ある文字列「ではない」ファイルを指定したいのですけど、ひょっとして不可でしょうか


# やりたいこと

logrotate の設定ファイルで、下記のように指定したい。

```:/etc/logrotate.d/nanika_no_service
/var/log/nanika_no_service/【"aiueo" から始まるログ以外】.log {
    monthly
}

/var/log/nanika_no_service/aiueo.log {
    daily
}
```

# 調べてみた結果

無理っぽい。
やむをえず、下記で妥協。

```:/etc/logrotate.d/nanika_no_service
/var/log/nanika_no_service/[!a]*.log {
    monthly
}

/var/log/nanika_no_service/a*.log {
    daily
}
```

# 理由

https://github.com/logrotate/logrotate/blob/master/logrotate.c
https://github.com/logrotate/logrotate/blob/master/config.c

ソースコードによると、rotate するファイルの探索にはglobを使っているようです。
でもって、globの仕様も読んでみたのですが、「単一文字以外」のワイルドカードの案内はあれど、「複数文字以外」の書き方はありませんでした。

そんなわけで、logrotate.conf のファイル指定では

```
/var/log/nanika_no_service/【"aiueo" から始まるログ以外】.log {
    # 略
}
```

上記のように書けない、というのが、今のところの結論です。
うまい方法はないものでしょうか。

# 経緯

同じディレクトリにあるログで、1種類のログだけ別条件で rotate したくなりました。それで調査したというわけです。
上の例だと `aiueo.log` が、それに当たります。

でも、ちょっと待ってください。`[!]` を使わず下記のように書けばいいのではないでしょうか。

```:/etc/logrotate.d/nanika_no_service
/var/log/nanika_no_service/*.log {
    monthly
}

/var/log/nanika_no_service/aiueo.log {
    daily
}
```

そうですね。僕もそう予想しました。
ですが残念なことに NG です。

logrotate 設定では、重複があると上手く動作しません。上記のようにしてしまうと、`aiueo.log` は `*.log` にも含まれ、設定に重複があります。
このような条件だと、実行時にエラーになるか、`aiueo.log` も `*.log` の設定に従ってしまいます (設定順によって変わりますが、どの並びがどの動作になるかは、ちょっと忘れました)。


# おわりに

この投稿では、logrotate の対象ログ指定で、「複数文字以外」の表現ができないか調べました。
残念ながら、今のところ実現方法を見つけられていません。

それではごきげんよう。
Modular speaker system


## プロジェクト概要

<img width="834" alt="IMG_0149.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572477/321b3a7f-3fab-a3df-5384-ceef402f917a.jpeg">

- 多数のスピーカーとプロジェクションマッピングを活用したMuclues展示システムの開発
- 1台のコンピューターで全体の映像と音楽を制御する。
  - 映像は設置規模に応じて複数のプロジェクトを使用できる。
  - 音楽はメインデスクトップからイベント種類(チャンネル)によって各スピーカーに音声信号を伝送する。
- 多数のボックス状のプロジェクトスクリーンを作り、モジュール型スピーカーを付着できるようにする。
  スピーカーは無線信号を受けて音を出す。



## 実現すべきこと

スピーカー製作

- 無線通信システムの開発
  スクリーン制作
- (オプション)展示場用アコースティックコントロール装備

<img width="200" alt="IMG_0147.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572477/0f4b55a7-a1b6-7ca9-39ee-a008ee236b91.jpeg">


## 無線通信システムの開発

- Arduino vs. Raspberry Pi
- ひつじさんのページ http://sheep-me.me/2020/01/17/geidai_24/



## スピーカー制作関連資料

3Dプリンターを使用したカタツムリの形のスピーカーの製作 - [link](https://www.youtube.com/watch?v=h-RSm97lkOU)

- スピーカーダイアフラムだけを別に購入してスピーカーキャビネットの形は3Dプリンターで出力することができる。
- スピーカー·キャビネットの内部は干渉現象を減らすために吸音材を入れる。 (いいスピーカーの制作原理がわからないので)
- 映像では市販の小型アンプを使っていたが、これをArduinoで製作できるような気がする。



BeoSound Shape - [link](https://www.youtube.com/watch?v=14a36T_IEBI)

- スピーカーカバーの形や色の変化により様々な表現が可能である。
- 映像を見ると、音声信号とパワールーティングをどういうふうにしたかが垣間見える。
- 上記例題のようにこの場合も吸音材を使用していることを確認した。



Concrete Speakers - [link](https://www.youtube.com/watch?v=hs-ZVenxiSw)

- 配線のノウハウや使用装備を見ることができる。



Manufacturing of a Jean Maurer loudspeaker - [Link](https://www.youtube.com/watch?v=FH3mmRLjKxU)

- クラウドスピーカーの全体的な制作過程を見ることができる





## スクリーン制作関連資料

スクリーン素材別の色の違い - [link](https://www.youtube.com/watch?v=jx6dYwRezAM)

DIYプロジェクタスクリーン購入(アマゾン) - [link](https://www.amazon.co.jp/Blackout-Projector-Screen-Material-66x110-inch/dp/B007KA07YM/ref=sr_1_6?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=diy+projector+screen&qid=1579831969&sr=8-6)





## 吸音剤の製作関連資料

DIYアコースティックパネル製作 - [link](https://www.youtube.com/watch?v=qczNxoG8s6o)

- アルミニウムバーを使用したフレーム製作
- フレームを連結するBracket制作:3Dプリンタ使用
- hexagonal screw map spacers 使用 - [link](https://www.ebay.com/itm/Brass-M3-x-4mm-60mm-Female-Hex-Hexagon-Isolation-Colum-Pillar-Standoff-Spacer/302580982937?hash=item46733b6499:m:mEM0GmruCDSjRFc5AXWInzw)
- UPHOLSTERY Sponge form
- House Insulation: スポンジより全般的に安い。

Angled Aluminum Bar 購入 - [Link](https://www.amazon.com/Orange-Aluminum-Extrusion-Extruded-Bracket/dp/B07R9255XJ/ref=sr_1_4?keywords=angled+aluminum&qid=1579833045&sr=8-4)
【C++】isnan()に注意！ nan, Inf, -nan(ind)の判定について

## 目的
- __数値計算が可能か__ を判定する際に、 `isnan()` の使用が妥当かを検証する
    - 検証に使う関数は、 isnan()以外に、`isinf()`と`isfinite()`

## 結論
- 数値計算が可能かどうかを判定する場合は、`isfinite()`の使用が良い
    - isnan()の場合、無限大を検出できないため


### 対応表
- 各関数と各非数の対応関係を表にまとめた
    - __太字__ の箇所は、私の肌感覚と異なる判定（違和感を感じる箇所）


| | 数値 | inf | nan | -nan(ind)  | 備考 |
|---|---|---|---|---|---|
| isnan| False |__False__ |True|True| infを検出してくれない |
| isinf|False|True|__False__|__False__| nanを検出してくれない|
| isfinite |True|False|False|False| nan, inf どちらも検出可 |

## isnan()を使ったコードで発生したバグ
- 実際の業務で発見したバグ
  - 分野: 機械学習案件の数値計算
      - ※説明のため、非常に単純化した例を示します。

  - 以下のような足し算関数`add()`を定義する
     - プログラマーは、isnan()を設置していたので、不正な値が入っても安心できると考えていた
     - しかし、この関数では、引数x,yに無限大が入ってしまった時に検出できない。

  - サンプルコードの例では、何かの拍子に `y = 無限大`が入ってしまったと仮定して、話を進めます。


```cpp:bug.cpp
#include <iostream>
#include <string>
#include <cmath>
#include <limits>
#include "classA.h"

double add(double x, double y){
    // x, yが数値計算可能か判定して欲しい...
    if(std::isnan(x) || std::isnan(y)){
        return 0;
    }

    return x + y;
}

int main(void){
    double x = 1.0;
    double y = INFINITY; // 何かの拍子に無限大が入る

    std::cout << "add(x,y) = " << add(x,y) << std::endl;
    
    return 0;
}
```

```bash:実行結果
    add(x,y) = inf
```
- 引数にはfloatを入れてるし、isnan()で検出できるはずなのに...？？
    - このように、プログラマーの意図と反した値が帰ってきた。

- 実行〜バグ発見までの経緯 
   - 実際に走らせると、実行時によく分からない値が返却される
   - コンパイルエラーや実行時エラーは、吐かれない。
   - しかし、なぜかAIの予測結果がおかしい...
   - 計算は何層にも渡っているため、1層ずつ値を確認...
   - 発見まで非常に苦労した。

### 所感
- 機械学習など、絶対的な正解がなくデバッグが難しい分野で上記のような勘違いをすると、問題の発見が非常に難しくなります。
- 筆者は、`isfinite()`を積極的に使った方がよいと考えています。


# （おまけ）検証プログラム
- 以下は、おまけです。
  - 対応表を作るために作成したコードを乗せます。

```cpp:test.cpp
#include <iostream>
#include <string>
#include <cmath>
#include <limits>

int main(void){
    float num = 1;
    float inf = INFINITY;
    float nan = NAN;    
    float nan_ind = inf - inf;

    // isnanの判定
    std::cout << "isnan(num) = " << std::isnan(num) << "\t\t" 
        << "isnan(inf) = " << std::isnan(inf) << "\t\t"  
        << "isnan(nan) = " << std::isnan(nan) << "\t\t" 
        << "isnan(nan_ind) = " << std::isnan(nan_ind) << std::endl;

    // isinfの判定
    std::cout << "isinf(num) = " << std::isinf(num) << "\t\t" 
        << "isinf(inf) = " << std::isinf(inf) << "\t\t" 
        << "isinf(nan) = " << std::isinf(nan) << "\t\t" 
        << "isinf(nan_ind) = " << std::isinf(nan_ind) << std::endl;
    
    // isfiniteの判定
    std::cout << "isfinite(num) = " << std::isfinite(num) << "\t" 
        << "isfinite(inf) = " << std::isfinite(inf) << "\t" 
        << "isfinite(nan) = " << std::isfinite(nan) << "\t" 
        << "isfinite(nan_ind) = " << std::isfinite(nan_ind) << std::endl;

    return 0;
}
```

### 出力
```bash:a.out
isnan(num) = 0		isnan(inf) = 0		isnan(nan) = 1		isnan(nan_ind) = 1
isinf(num) = 0		isinf(inf) = 1		isinf(nan) = 0		isinf(nan_ind) = 0
isfinite(num) = 1	isfinite(inf) = 0	isfinite(nan) = 0	isfinite(nan_ind) = 0
```
- ※ 1 = True, 0 = False

### 処理系
- OS: Windows10 Pro
- CPU: Intel(R) Core(TM) i7-6700K
- コンパイラ: VS2017 標準コンパイラ

### 参考ページ
- http://negi-magnet.hatenablog.com/entry/2017/05/14/000408
- https://marycore.jp/coding/math-inf/
【永久保存版】「||」とか「&&」ってなんやねん

# 結論
[論理演算子](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Logical_Operators)と言います。
どうぞよろしくお願いします。
## 前提知識
- 論理演算子は左から右という順番で評価をする
- 論理演算子が返す値は**基本的には**真偽値(true or false)です。
  - ただ、真偽値以外も**返すことができます**。
  - それは後程説明します。

## 解説
### 「||」
- any1　||　any2の**どちらかがtrueであればtrueを返す。**
  - any1がfalseの場合any2を見て、any2もfalseだった場合初めてfalseを返し、trueであればtrueを返す。
  - つまり、どちらもfalseでなければfalseを返さない。
 
```js
a1 = true || true // true
a2 = true || false // true
a3 = false || true // true
a4 = false || false // false
a5 = (1 === 1) || false // true
a6 = false || (1 === 2) // false
```
- 文字列も使用することができる。
  - が、その場合、必ずtrue判定(?)になる

```js
a1 = "dog" || "cat" // "dog"
a2 = false || "cat" // "cat"
a3 = "dog" || false // "dog"
```
### 「&&」
- any1　&&　any2の**どちらもtrueであればtrueを返す**
  - any1がtrueの場合any2を見て、any2もtrueであればtrueを返し、falseであればfalseを返す。

```js
a1 = true && true // true
a2 = true && false // false
a3 = false && true // false
a4 = false && false // false
a5 = (1 === 1) && true // true
a6 = true && (1 === 2) // false
```
- 「||」と同様、文字列を使用することができます。
  - が、文字列同士を比較した場合、「||」と違い、後ろの文字列を返す

```js
a1 = "dog" && "cat" // "cat"
a2 = false && "cat" // false
a3 = "dog" && false // false
```
## 慣れてきた方へ
### ショートサーキット評価
- 論理演算子の左から右の順番で評価する仕様を利用した記法。
- これにより、無駄な関数を動かさないようにして軽くしたりすることが可能。

例

```js
heavyFunction() {
  for(let i = 0; i < 100; i++) {
    console.log('無駄に重い関数', i)
  }
}

if (true || heavyFunction()) {
  console.log('||のショートサーキット評価')
}
if(false && heavyFunction()) {
  console.log('&&のショートサーキット評価')
}    
```
- ||は左がtrueの時点で右を見る必要もないので**trueを返す**。
- &&は左がfalseの時点で右を見る必要もないので**falseを返す**。

**結果、無駄に重い`heavyFunction()`を呼ばなくて済み、動作を軽くすることができます！**
Laravel5.8 サブクエリー(leftJoinSub)

## 説明
QueryBuilderがかなり使えるので、メモです。
サブクエリーもかんたんに書けます。

### サブクエリーで合計をとります。
ユーザーへのメッセージがあって、それに対していいねをする想定のテーブル構成です。
以下、カラムは最小限で、適当です。
あと、正規化してない部分もあります。

## テーブル
 **1.users ：ユーザーテーブル**

|論理名       |物理名 |
|:-----------------|:------------------|
|id             |PK |
|company_id             |企業ID |
|name           |名前 |

**2.user_messages ：ユーザーメッセージテーブル**

|論理名       |物理名 |
|:-----------------|:------------------|
|id             |PK（メッセージのID） |
|user_id           |ユーザーテーブルのID（貰った人） |
|message           |メッセージ |

**3. user_message_likes ：ユーザーメッセージへのいいねテーブル**

|論理名       |物理名 |
|:-----------------|:------------------|
|id             |PK（いいねID） |
|company_id             |企業ID |
|user_message_id           |ユーザーメッセージテーブル のID |

## メッセージと、メッセージ毎のいいね数を取得する
```php

<?php
// ユーザーメッセージIDでグループ化し、メッセージ毎のいいね数を取得するサブクエリー
$like_count = DB::table('users_message_likes')
->select('user_message_id', DB::raw('count(user_message_id) AS like_cnt'))
->groupBy('user_message_id');

// =====
// メッセージと、いいね数を取得する処理
// =====
$messages = DB::table('user_messages')
// ユーザー情報取得用のjoin
->join('users', 'users.id', '=', 'users_messages.user_id')
// いいね数取得用のサブクエリー(所属企業を絞る)
->leftJoinSub($like_count, 'count_table', function ($join) use ($company_id) {
	$join->on('users_messages.id', '=', 'count_table.user_message_id')->where('count_table.company_id', '=', $company_id);
})
->orderBy('users_messages.id', 'DESC')
->where(['users.company_id', '=',  $company_id])
->select([
	'users.name AS name',
	'user_messages.id AS id',
	'user_messages.message AS message',
	'count_table.like_cnt  AS like_cnt',
])
->get();

// レコードあるか
if (count($messages) == 0) {
	// 抜けるなどの処理
}

// レコード存在時は、ループして取得する
foreach ($messages as $message) {
	// データ操作
}
```



### 追伸
結局、カウントは集計をテーブルに持ったので使いませんでしたが、
覚えておいたら使えると思います。
Dockerを使って数分でOpenCV&Python環境を構築して試す

#コード

下記のコマンドを指定して完了。
`/mygit/appdir/`は実行したいpythonファイルが有るフォルダを指定してください。

```shell
docker run -it --rm --name pythoncv -w /mygit/appdir/ -v "$PWD":/mygit/appdir/  jjanzic/docker-python3-opencv python index.py
```

#各オプション
## -w
作業フォルダ指定

##-v
マウントディレクトリ指定

```text
"is not shared from OS X and is not known to Docker."というエラーが出る場合があります。
こちらの記事を参照して回避してください。
```

【Docker For Mac】Error response from daemon: Mounts deniedの対応
https://qiita.com/nishina555/items/a75ce530d9382aa09511

#感想
環境構築で時間が取られなくて最高。
【ふくだ学習録】SQLアンチパターン part2【16日目】

# ふくだ学習録とは？
ふくだが学習したことの備忘録。
目に見える形で残すことによってやる気を出す個人的な作戦です。
他人に見せるように書いているわけではないので、すごく読みにくいです。

### 読了した本
[データベースエンジニア養成読本 [DBを自由自在に活用するための知識とノウハウ満載!]](https://www.amazon.co.jp/dp/4774158062/ref=cm_sw_r_tw_dp_U_x_FPphEbQFPPQRM )
[ゼロから作るDeepLearning](https://www.amazon.co.jp/dp/4873117585/ref=cm_sw_r_tw_dp_U_x_y3UiEbF3P6EG7)
[PHPフレームワーク CakePHP 3入門](https://www.amazon.co.jp/dp/4798048577/ref=cm_sw_r_tw_dp_U_x_.YIjEbS1K4JY2)

### 今読んでいる本
[SQLアンチパターン](https://www.amazon.co.jp/dp/4873115892/ref=cm_sw_r_tw_dp_U_x_XlokEbJQK2N7P )

# SQLアンチパターンを読んで

### SQLは宣言型プログラミング言語
SQLでは「集合」を基本的なデータ構造として使用する、宣言型プログラミング言語。
現在の状態どのように解決するか、について「関数を作成する」ではなく「もともと用意されている関数をどのように用いるのか」といった観点で考えていかなければいけない。

[プログラミングパラダイムとは](https://style.potepan.com/articles/12941.html#i)

### blob型とは？
blob（ブロブ）型とは、バイナリデータを扱うデータ型。
格納できるデータのサイズは指定しない。

[BLOB型とTEXT型](https://www.dbonline.jp/mysql/type/index6.html)

### NUMERIC型とは？
NUMERIC（ニューメリック）型とは、非常に大きな数値を扱う型。
正確な計算を行うことができるため、通貨金額やその他正確性が求められる数量を保存する時は特に、この型が推奨される。
その代わりに、整数型、もしくは浮動小数点データ型に比較し、計算が非常に遅くなってしまう。

### BIGINT型とは？
BIGINT（ビッグイント）型とは、広範囲整数。８バイトまでで表される数字。

### UNSIGEDとは？
「負の数を表さない符号のない長い整数」を定義できるもの。
これを設定すると、シンプルに使える正の整数の範囲が倍になる。

### ジェイウォーク（信号無視）
開発者が「多対多」の関連を表現する交差テーブルを避けて、カンマ区切りなどのリストを用いる。
こういったintersection(交差/交差点)を避けるアンチパターンを、**ジェイウォーク（信号無視）**と例えることがる。

#### 外部キーを文字列連結させて一つのフィールドに格納するべきではない。
クエリを作ることが難しくなるから。理由としては。等価性による比較ができなくなるため、何らかの文字列パターンに対するパターンマッチが必要になってしまうから。

# 今日の一言
鼻水ジュルジュルやから今日はここまで！病院行ってきます！
Tektonを使ってAppsodyで作ったNodejsアプリケーションをK8sにデプロイする。(Tekton準備編)

先日、[Appsodyを使ってNode.jsモジュールをK8sに簡単にデプロイする方法](https://qiita.com/motuo/items/1cde634a010e9e1d7d5a)を記事にしました。

この記事ではさらに踏み込んで、作成した`Node.js`モジュールを`Tekton`を使ってK8sにデプロイするCI/CDパイプラインを作ってみましょう！
まず、この記事では以下の環境に`Tekton`を準備するところから始めます。
**※前回と同様に環境はmac。docker for macで`Kubernetes`が有効であることが前提です。**

## What's Tekton?
ざっくりいうと、**Kubernetes上で稼働するクラウドネイティブなCI/CDパイプライン**となります。
代表的な使い方は、`Github`からソースコードを取得して、それを自動的にKubernetesへデプロイする、というところでしょうか。
詳細は本筋とは逸れるのであまり触れませんが、[Githubのリポジトリ](https://github.com/tektoncd/pipeline)を参照してください。
![Tekton](https://tekton.dev/img/logos/tekton-horizontal-color.png)

## ここからが本題
さて、実際Kubernetesで運用することを考えたときに、毎回、ソースコードをどこからかコピーしてきて

```sh
appsody deploy
```
を叩くのは、あまり現実的ではありませんよね？
そこで、上記で書いた`Tekton`の出番です。

## まずはTektonを導入する
**はじめに**
以下の記事は
https://www.skyarch.net/blog/?cat=518
→こちらを参考にさせて頂きました。ありがとうございます。

### Tektonのインストール
```sh
$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/latest/release.yaml
```

下記のコマンドを打つことで、Tektonがインストールされたことを確認できます。

```sh
$ kubectl get pods --namespace tekton-pipelines
NAME                                           READY   STATUS              RESTARTS   AGE
tekton-pipelines-controller-5888756f5c-8jdhz   0/1     ContainerCreating   0          8s
tekton-pipelines-webhook-7494f6f84b-644nn      1/1     Running             0          8s
```

## Tekton Dashboadを導入する
ただ、`Tekton`をインストールしただけでは、実際に`Kubernetes`でのデプロイ結果を確認することが難しいです。ログなどを確認できるように`Tekton Dashboad`を導入しましょう。

はじめにTekton DashboardのソースをGit Hubからクローンします。

```sh
$ git clone https://github.com/tektoncd/dashboard.git
```

下記のコマンドでTekton Dashboardのインストールは完了です。

```sh
$ kubectl apply -f dashboard/config/release/gcr-tekton-dashboard.yaml
serviceaccount/tekton-dashboard created
customresourcedefinition.apiextensions.k8s.io/extensions.dashboard.tekton.dev created
clusterrole.rbac.authorization.k8s.io/tekton-dashboard-minimal created
clusterrolebinding.rbac.authorization.k8s.io/tekton-dashboard-minimal created
deployment.apps/tekton-dashboard created
service/tekton-dashboard created
pipeline.tekton.dev/pipeline0 created
task.tekton.dev/pipeline0-task created
```

下記の`port-forward`コマンドを実行後、`http://localhost:9097`でダッシュボードにアクセスしてみましょう。

```sh
$ kubectl --namespace tekton-pipelines port-forward svc/tekton-dashboard 9097:9097
```

下記の画面が表示されたら準備は完了です。
![スクリーンショット 2020-01-24 8.56.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154110/4178b687-dd14-e5a3-4d39-9c6c72bc7d8f.png)
Qiitaでタイポや情報の修正を行う時は「編集リクエスト」で！

Qiitaを見ていると、コメント欄に

「〇〇がタイポしています。正しくは××です！」
「ここのURLが繋がらなくなっています。以下のURLに変わったようです。」

といった情報の修正を促すものがあったりします。
投稿者としては嬉しい限りなのですが、そんな時はコメントではなく、 **編集リクエスト**を使いましょう！

## 編集リクエストとは？
編集リクエストとは、「Qiitaに投稿された情報を修正したり情報を追記して本体へのマージを依頼できる仕組み」です。
参考：https://help.qiita.com/ja/articles/qiita-edit-request

つまり誤りに気づいたら修正してあげて、それをリクエストしてあげましょう！という事です。所謂PRですね。
編集もとても簡単です。
あと、編集履歴に自分の名前が載ります。コントリビューターみたいです。

これらの機能を上手く使って、よりよい記事にしていきましょう！
小規模チームが簡単に管理できるテスト管理アプリを個人開発しました


![report.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/459044/ad2f2c59-ef96-81b3-c722-2044d53484cf.png)

開発者とテスト担当者がわかれていないようなチームがテスト仕様書を作成できて、共有、レポート作成と
簡単に管理できるツールが作れないかと考え[TESTBASE（https://www.test-base.tech/）](https://www.test-base.tech/)というテスト管理ツールを個人開発しました。
現状はベータ版としてパイロット運用をして、本番稼働に移行していけたらなと考えています。

#  対象読者
次のような方の参考になるような内容をまとめています。

- 個人開発を始めようとしている方
- テスト管理ツールを探している方


#  なぜ作ろうとおもったか

理由は次の3点があります。

- 無料で使えるテスト管理ツールがなかった
- 海外製品はIEEEなどの基準に準拠しているのか日本のExcelっぽいGUIではなかった。
- 海外製品は単純に機能が多すぎて、使いづらかった。

オープンソースのテスト管理ツールだとTestLinkというものがありますが、UIがかなり古く、実際に使用するには難しい印象を受けます。その他では、基本的には有償のツールでした。代表的なものを上げると国産だと[qangaroo（https://qangaroo.jp/）](https://qangaroo.jp/)、海外製品だと[TestRail（https://www.gurock.com/testrail）](https://www.gurock.com/testrail)などがあります。

海外製品はIEEEが作成した標準的なテストテンプレートに準拠しているのか、日本で多くのエンジニアが作成していると思われるExcelベースの表形式のテストテンプレートではありませんでした。テスト管理の点から考えるとIEEEのようなテンプレートのほうが認識間違いなどが少なくなるようですが、実務上は運用は厳しいという印象を受けます。（特に小規模な開発チームでは）

また、海外製品はテストシートをテストスイートという単位で管理するようで（詳細には調べていません）これもまた高機能ですが、使いこなせないなと印象を受けました。

そこで開発者がマニュアルテストを簡単に作成できて、管理できる。さらにテスト結果の集計を簡単にできるようなツールを作成しようと考えました。

# 構成技術
- bootstrap
- jQuery
- handsontable
- Chart.js
- Ruby On Rails
- PostgreSQL
- heroku

SPAのようなうな要件はなく、単純に入力項目を埋めていくような画面構成が多いため、フロントサイドはオーソドックスな技術を使用しています。テストシートのスプレッドシート部分はスプレッドシートのライブラリで無料で使用できて動きの安定しているhandsontableを利用しました。（一定の過去バージョンのみOSSで、それ以降は有償となっています。）

サーバーサイドは実務経験のあるSpringBoot(Java),Laravel(PHP)、RubyOnRails(Ruby)と検討しました。
実務経験があるのでSpringBootは学習工数がなく、開発作業に移れましたが、Ruby on Railsと比較すると作成しなければならないクラス数が多いのと（例：Form、Modelなど）、Ruby on Railsは優れたマイグレーション機能があるので、Ruby on Railsを採用しました。
結果として、体感ですが、SpringBootとと比較して4割減くらいの工数で開発できたと思います。
 
実行環境については、VPSやAWS当のIaaSも検討しましたが、一人で開発とサーバー構築するのは不可能だったのでHeorkuを採用しました。SaaSということでマルチテナントを実現する必要がありましたが、Heorkuで対応ができました。


# アプリケーション構成
TESTBASEはSaaSのためマルチテナント構成にする必要がありました。複数のテナントにたいして、テナント事にサブドメインを分割して、それによりアプリケーションにアクセス可能となっています。

次のような実現方法をとっています。

- テナント単位にサブドメインを分割
- サブドメイン部分によりテナントを特定
- データアクセス時にそのテナントによりデータアクセスし、テナントごとのデータ分離を実現

重要なデータ分離についてはテナントIDにて管理しており、Apartmentなどのマルチテナント用のGemは使用せず、モデルのdefault scopeとCurrentにより実現しています。defaultscopeを利用することで、CRUD操作すべてでテナントIDが条件に付与され、処理ごとにテナントIDを付与しなくてもいいようにして、保守性を実現しています。

マルチテナントはスキーマ分離方式もありますが,Heroku自体が使用を非推奨にしており、テナント数の増大によりテーブル定義等の変更が大きな負荷となってしまうため、採用しませんでした。
LocalファイルにJavascriptを使って書き込みする方法（承認必要）

# はじめに
LocalファイルにJavascriptを使って書き込みする方法をまとめました。
ただし、セキュリティ上必ず承認が必要となってきます。そのセキュリティを回避する方法は今回説明しません。

#### 関連リンク
関連リンクを下記に載せておくので、必要であれば参考にしてください。。

* Local上にて複数のHTMLコンテンツのデータを共有する方法（Store.js）
    * https://qiita.com/syukan3/items/c20ed695c1d676799a5a
* Local環境のXMLファイルからJavascriptを使って情報を取得する方法
    * https://qiita.com/syukan3/items/71c63cdccb6976e52f3d
* Local環境でのCookie / WebStorage 挙動
    * https://qiita.com/syukan3/items/dd907b7cd3ed86025546

# やりたいこと
ブラウザにてHTMLファイル（HTML:write_to_local_file.html）に埋め込んだJavascriptを動かして、ローカル上にあるtextファイル（text.txt）へ情報の書き込みをしたい。

# コード実装



```HTML:write_to_local_file.html
<!DOCTYPE html>
<html lang="ja" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Test for writing to local gile</title>
  </head>
  <body>
    <script type="text/javascript">
      // Scripting.FileSystemObject というオブジェクトを作成（JavaScript内でWSHを使ってファイルを扱う）
      var fs = new ActiveXObject("Scripting.FileSystemObject");

      // text.txtという新規のファイルを作成
      var file = fs.CreateTextFile("text.txt");

      // texxt.txtファイルへ書き込み
      file.Write("Complete, written!");

      // text.txtファイルを閉じる
      file.Close();
    </script>
  </body>
</html>

```

# 実行

IE11にて実行しました。

以下のような警告が出て"はい"をクリックすると、その下のテキストファイルの画像の通り、書き込みが完了しました。

<img width="400" alt="参考" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/2264e15a-d3e5-bede-72b9-017f9ae7e706.png">

<img width="600" alt="参考" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/1a759e6d-ea1f-3f19-9137-0d275cee7427.png">



# まとめ
一般的に使われているブラウザを使用する場合はセキュリティ上毎回承認が必要になるので、この方法だけでは完全自動化することはできません。
回避する方法としては、Javascriptの実行環境を構築する、もしくは"はい"のボタンを自動で押す何かをつける、と今思いつくのはこれくらいです。
chromeブラウザを使用できる場合は、FileSystemAPIというものを使用するとできるというのを見かけましたので参考までに。。。

# 参考
* JavaScript(WSH) スクリプトでファイル入出力
    * http://marupeke296.com/IKDADV_JS_IO.html

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
Pythonでテーブル画像を出力、保存する(plotly編)

Pythonで作成したDataframeをパワポに載せる際に、
一度EXCELに出力してからテーブル画像を作成するのは手間です。
綺麗なテーブルをPythonから出力するための情報が少ないなと知ったため作成しました。
matplotlibでもできなくはないですが、plotlyのほうが便利です。

### 1. plotlyのインストール
https://qiita.com/ogrew/items/e6ba517cec9fb5161cb6
に詳しく記述されています。

### 2. テーブルの作成
```python:plotly.rb
import pandas as pd
import plotly.graph_objects as go
import numpy as np

#データの作成
x1 = np.arange(0,10, 1)
y2 = np.arange(0,20, 2)
z3 = np.arange(0,30, 3)
P_X = ["<b>{}</b>".format(i) for i in range(10)]

#Dataframeの作成
df = pd.DataFrame({"X1":x1, "Y2":y2, "Z3":z3, "P<sub>X</sub>":P_X})

#テーブルの作成
fig = go.Figure(data=[go.Table(
        columnwidth =  [10, 20, 30, 40], #カラム幅の変更
        header=dict(values=df.columns, align='center', font_size=20),
        cells=dict(values=df.values.T, align='center', font_size=10)
        )])
fig.update_layout(title={'text': "sample_table",'y':0.85,'x':0.5,'xanchor': 'center'})#タイトル位置の調整
fig.layout.title.font.size= 24 #タイトルフォントサイズの変更
fig.write_image("sample_table.jpg")#,height=600, width=800)
#fig.write_image("sample_table.jpg",height=600, width=800) #デーブルのサイズ変更
#fig.show()
```
出力結果
![sample_table.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572164/860eb607-2385-a17f-4c77-34f455f57df4.jpeg)

### 3.Plotlyについて
plotlyはhtmlのタグを使用できるので、データにhtmlタグを入れることで任意の形式のテーブルを作成することができます。

詳しくはplotly公式サイトに記述されています。
https://plot.ly/python/table/
pip install でSSL関連のエラーが出たらこれを読め！！！

# 環境
mac OS Catalina
python 3.6.5

# 状況
pythonをしばらく放置（1年くらい）していたのですが、新しくパッケージをインストールしようと思い`pip install <package name>`したところこんなエラーに...

```
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Collecting numpy-stl（今回インストールしようとしたパッケージ名）
  WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)': /simple/numpy-stl/
  WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)': /simple/numpy-stl/
  WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)': /simple/numpy-stl/
  WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)': /simple/numpy-stl/
  WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)': /simple/numpy-stl/
  Could not fetch URL https://pypi.org/simple/numpy-stl/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/numpy-stl/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)) - skipping
  ERROR: Could not find a version that satisfies the requirement numpy-stl (from versions: none)
ERROR: No matching distribution found for numpy-stl
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.",)) - skipping
```

色々調べたところ、解決法として
- pipのアップデート
- `pip install`時にホストを信頼させるオプションをつける
- curl のアップデート
- pip.conf を作る
等色々あったので全部試しましたが、**いずれもうまくいきませんでした。**（[参考](https://qiita.com/agajo/items/73d6f14855da703972e0)）
この時点でかなり絶望。。。

# 解決法
結局pythonのバージョンをあげてpipごと心機一転させてあげることで解決しました。（途中でXcodeのCommandLineToolのアップデートが必要かもしれません。）
僕は`pyenv`を使っていたので、

```
pyenv install 3.8.1
pyenv global 3.8.1
pip install (インストールしたいパッケージ)
```

で無事インストール完了できました！！！

もし同じ悩みで絶望している方がこれで解決できたら嬉しいです。もしよかったらいいね！！してください！
AutoCADのシステム変数を操作する

## AutoCADのシステム変数とは
- AutoCADの環境をコントロールする変数
- AutoCADのコマンドの動作をコントロールする変数
- システム変数のデータタイプは、整数、実数、文字列、2D点、3D点がある

[システム変数一覧（公式ヘルプ）](https://help.autodesk.com/view/ACD/2020/JPN/?page=sysvars)

## コマンドラインでのシステム変数の操作
#### システム変数の値を設定する
コマンドラインにシステム変数名を入力し、[Enter] 押し次に設定する値を入力。
※ 読み込み専用のシステム変数には値を設定できない

#### システム変数の一覧を表示する
コマンドラインに SETVAR と入力し、その次に ? [Enter] を入力。

## AutoLISPで操作
#### システム変数を操作するための関数
| 関数名 | 説明 |
|---|---|---|
| getvar | システム変数の値を取得する |
| setvar | システム変数の値を設定する |
※ command関数を使ってコマンドラインから、システム変数を設定することもできる
[AutoLISPでAutoCADコマンドを実行する](https://qiita.com/tydesign/items/10b22f9c511c966e125f)
#### 値を取得する
```scheme
(setq val (getvar "システム変数名"))
;; 変数valに値を格納
```
#### 値を設定する
```scheme
(setvar "システム変数名" 値)
;; 値を設定する時は、適切なデータタイプを設定する必要がある
;; 読み込み専用のシステム変数には値を設定できない
```

### AutoLISP 簡単な例
##### グリッドをオンにする
```scheme
(setvar "GRIDMODE" 1)
```
##### グリッドをオフにする
```scheme
(setvar "GRIDMODE" 0)
```
##### フィレット半径を "2.5" に設定する
```scheme
(setvar "FILLETRAD" 2.5)
```
##### 現在の画層名を取得
```scheme
(setq layerName (getvar "CLAYER"))
;; 変数 layerName に現在の画層名が文字列で格納される
```
##### 現在の画層を設定
```scheme
(setvar "CLAYER" "設定する画層名")
;; 設定する画層名が存在しない場合はエラーになる
```
##### 画層"Red"に線分を作成（2点を選択して）
```scheme
;; 現在の画層を一時保存
(setq clayer (getvar "CLAYER"))
;; 現在の画層を"Red"に設定
(setvar "CLAYER" "Red")
;;ユーザーが2点を選択して、線分を作成
(command "LINE" PAUSE PAUSE  "") 
;; 画層を元に戻す
(setvar "CLAYER" clayer )
```
## Express Tool でシステム変数の操作
エクスプレスツールの SYSVDLG コマンドを使うと、
システム変数の設定を表示、編集、保存、復元することができる。
[Express Tool SYSVDLGコマンド（公式ヘルプ）](https://help.autodesk.com/view/ACD/2020/JPN/?guid=GUID-E79F7A56-E373-48EC-AEB7-652CEDBE26D7)
気づいたこと日記(1日目)

1# 配列の長さぶん処理をするときには
   ForIn ではなく ForEach を使おう！
　`
  fruits.forEach(function(item, index, array) {
  console.log(item, index);
});
// りんご 0
// バナナ 1
　`
→indexも実は使える…
`
　for(let i in fruits){
  console.log(fruits[i],i);
// りんご 0
// バナナ 1
/*
一見こっちの方が簡単にすませられそうだが、
*/
  console.log(typeof i ,i+1);
// string,NaN
// string,NaN
/*
Indexが文字列なので計算できなかったり…
*/
`
}

なので、forinを使う
win10に同梱のOpenSSHでsshすると失敗するときの対処

win10でsshすると

```shell
CreateProcessW failed error:2 
ssh_askpass: posix_spawn: No such file or directory   
Host key verification failed.
プロセスが、存在しないパイプに書き込もうとしました。
```
したので調べたところhttps://github.com/PowerShell/Win32-OpenSSH/issues/1088 にたどり着いた。

結論としては

```shell
mkdir \dev
echo x > \dev\tty
```
すればよい

詳しくないので正しいかわからないがおそらくOpenSSHはターミナルが開いていないときはssh_askpass環境変数に設定されたプログラムからパスワードを取得するようになっており、win10だと当然ttyが存在しないためssh_askpassを参照するが設定されていないということだろう
PythonでSerialポートを調べて受信する(Port check)

PythonでSerialからのデータを受信する場合、SerialPortを指定する必要がありますが、Serialが１つのみでボーレートもわかっている場合は

```
from serial.tools import list_ports
import serial
ports = list_ports.comports()
ser = serial.Serial(ports[0].device,9600,timeout=0.1)
```
のようにしてポートを開くことができます。

これではあまりにも乱暴だという場合は、シリアルのボーレートと送られてくるデータのフォーマットが既知であれば、利用可能なポート全について流れてくるデータのフォーマットをチェックしてポートを開くことができます。

例えばPCに繋いだArduinoから9600bpsで定期的に

```
test:data=***
```
のようなデータが送られてくる場合は

```
from datetime import datetime as dt
from serial.tools import list_ports
import serial
import re

#---------------------------
def ReceiveSerial(_ser):
    _dataStr = ""
    if(_ser!=None):
        _data = _ser.readline()
        if(len(_data)>0):
            try:
                tmpDataStr = _data.decode('utf-8') # 'temp,24.5,hum,50.0'
            except:
                pass
            else:
                _dataStr = re.sub(r'\r|\n|','',tmpDataStr)
    return _dataStr
#---------------------------

def ScanUsingSerialPortName(_reg="^", _baudrate = 115200):
    devName = ""
    ckSer = serial.Serial()
    ckSer.baudrate = _baudrate
    ckSer.timeout = 0.1
    ports = list_ports.comports()
    print("find " + str(len(ports))+"ports")
    if len(ports) > 0:
        deviceNames = []
        for info in ports:
            deviceNames.append(info.device)	# ポートの名前を取得
            isReady = SerialPortCheck(ckSer,info.device,_reg)
            if (isReady):
                devName = info.device
                break;
    return devName

def SerialPortCheck(_serial, _portName, _reg):
    ret = False
    _serial.port = _portName	# ポートを指定

    try:
        _serial.open()
    except:
        pass
    else:
        print("SerialPortCheck " + _serial.port )
        startDt = dt.now()
        while True:
            # 1行読み込む
            s = ReceiveSerial(_serial)
            if(len(s)>0):
                print(">" + s)
                matchOB = re.match(_reg,s)
                if matchOB:
                    print("match")
                    ret = True
                    break

            tickTime = (dt.now() - startDt).seconds
            if ((_serial.is_open==False) or (tickTime > 3)):
                print("TimeOut" + s)
                break
        _serial.close()
    return ret

#---------------------------

def SetSerial(_serial, _reg="^", _baudrate=115200):
    if((_serial!=None)and(_serial.is_open)):
        _serial.close()
    tmpSer = None
    usingPortName = ScanUsingSerialPortName(_reg,_baudrate)
    if(usingPortName!=""):
        tmpSer = serial.Serial()
        tmpSer.baudrate = _baudrate
        tmpSer.timeout = 0.1
        tmpSer.port = usingPortName	# ポートを指定

        try:
            tmpSer.open()
        except:
            tmpSer = None
        else:
            print("SetSerialOK")
    return tmpSer
#---------------------------
```

```
ser =SetSerial(ser,"^"+"test:data=",9600)
```
のようにすることでポートを特定できます。
pythonモジュールがimport済みかどうかを確認する方法

#### 標準ライブラリ sys で確認できる.

チェックのためだけのスクリプトを用意.
module_checker.py

```python
import sys
import subprocess

if "subprocess" in sys.modules:
    print("module already imported")
else:
    print("module not imported")
```
```
$ python module_checker.py
module already imported
```

```python
import sys
# import subprocess

if "subprocess" in sys.modules:
    print("module already imported")
else:
    print("module not imported")
```
```
$ python module_checker.py
module not imported
```