OmniAICreator/Qiita-1.07M huggingface dataset:
PHP 変数に格納された文字列の連結

# 目的

- PHPで変数に格納された文字列の連結を行う方法をまとめる

# 書き方の例

- 変数Aと変数Bにそれぞれ格納された文字列を連結して表示する方法を下記に記載する。

```php
echo $変数A.$変数B;
```

# より具体的な書き方の例

- 変数`name`と変数`honorific`に格納された内容を連結して表示する方法を下記に記載する。

```php
//変数に格納
$name = "みりを";
$honorific = "君";

//変数を連結して表示
echo $name.$honorific;
```
OpenCV-Pythonで似たような画像の差分を検出する

# やりたいこと
例えば違う組版エンジンでPDF化したOFFICEドキュメントの見栄えのチェックとか。
エビデンスになって、人が見てなんとなく分かるような画像が欲しい。
あと全部の画像見るのしんどいので違う度合いを数値で出して、違いの大きいやつだけ人が確認するとか。

# 用意するもの
- Python3が動く環境
- OpenCV-Python

非公式だけどOpenCVのPython環境があるのでそれをサクッといれちゃいます。
`pip install opencv-python`
依存関係にあるnumpyも一緒に入ります。

https://pypi.org/project/opencv-python/

# Pythonのコード
```Python:diff_img.py
import pathlib
import cv2
import numpy as np

source_dir = pathlib.Path('source_img')
source_files = source_dir.glob('*.*')
target_dir = pathlib.Path('target_img')
result_dir = pathlib.Path('result_img')
log_file = result_dir / pathlib.Path('result.log')
kernel = np.ones((3, 3), np.uint8)

fs = open(log_file, mode='w')
for source_file in source_files:
    source_img = cv2.imread(str(source_file))
    target_file = target_dir / source_file.name
    target_img = cv2.imread(str(target_file))
    if target_img is None:
        fs.write(target_file + '...skipped.\n')
        continue
    max_hight = max(source_img.shape[0], target_img.shape[0])
    max_width = max(source_img.shape[1], target_img.shape[1])

    temp_img = source_img
    source_img = np.zeros((max_hight, max_width, 3), dtype=np.uint8)
    source_img[0:temp_img.shape[0], 0:temp_img.shape[1]] = temp_img

    temp_img = target_img
    target_img = np.zeros((max_hight, max_width, 3), dtype=np.uint8)
    target_img[0:temp_img.shape[0], 0:temp_img.shape[1]] = temp_img

    result_img = cv2.addWeighted(source_img, 0.5, target_img, 0.5, 0)

    source_img = cv2.cvtColor(source_img, cv2.COLOR_BGR2GRAY)
    target_img = cv2.cvtColor(target_img, cv2.COLOR_BGR2GRAY)
    img = cv2.absdiff(source_img, target_img)
    rtn, img = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU)
    img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

    contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_SIMPLE)
    result_img = cv2.drawContours(result_img, contours, -1, (0, 0, 255))
    score = 0
    for contour in contours:
        score += cv2.contourArea(contour)
    score /= max_hight * max_width
    fs.write(target_file.name + ', ' + str(score) + '\n')
    diff_file = result_dir / source_file.name
    cv2.imwrite(str(diff_file), result_img)
fs.close()
```
比較方法は、こちらの記事
[サイゼリヤの間違い探しが難しすぎたので大人の力で解決した]
(http://kawalabo.blogspot.com/2014/11/blog-post.html)
http://kawalabo.blogspot.com/2014/11/blog-post.html
を参考にしています。

スコアは単純に差分検出されたエリアの面積を出して画像全体の面積で割って、ファイル名と一緒にログに吐いてます。

```result.log
test-1.png, 0.01231201710816777
test-2.png, 0.0084626793598234
```

## 2020年1月7日追記
比較する画像のサイズが違っても比較できるようにしました。

# 実行例
![test-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404407/92c3e119-6f5e-0ce0-8a53-30d65dd0002f.png)
同じような表ですが比較対象の方が幅が少し小さくて余白が大きくなっていました。
Visual Studio Code の初期設定を頑張って丁寧に書く（日本語化）

## はじめに
いつか自分がバナナの皮で滑って転んで豆腐の角に頭をぶつけて記憶喪失になっても再び Vsiaul Studio Code（以下 VSCode） を使えるように、インストールして最初にやる設定の備忘録を頑張って丁寧に書きます。
当然ですが、自分式の初期設定なので、そんなのやんねーよ！　とかそれはちゃうやろ！　とかあるかと思いますが、自分はこうしてます。
（もっといいやり方とか教えていただけたら、感謝しつつ直すかも知れません）

Windows用です。その他のOS版は触ったことないので、ここでも触れません。使う必要性が出たときに考えます。

## 日本語化
"なんちゃって"であってもプログラマたる者、英語Onlyツールも使いこなせるように最低限の英単語力は身につけておけや！という説は尤もなのですが、つい日本語化できるものは日本語化したくなっちゃう。
日本語の方が捗るんですもの……。日本人だから仕方ないね☆

日本語化にはいくつか方法があるみたいですが、自分はCommand Paletteからやります。

####１． Command Paletteの表示
メニューの「View」→「Command Palette」から開くか、<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>でいけます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530355/27778ab8-b6fd-f84c-ca44-2508548f295d.png)

####２．「Configure Display Language」を選択
上の検索バー（「> 」とあるところ）に「config」と打つと、自動的に候補が出てきます。「Configure Display Language」を選択します。コンソールっぽいUIですが、普通にマウスでクリックできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530355/0c37e5fc-9b40-26db-0be7-bcde2c50779c.png)

####３．「Install additional languages…」を選択
さっきの検索バーのところに「Select Display Language」と表示されます。初期は英語しか言語パックがないので、「en」しか選択できません。
新しい言語パックが必要なので、下段の「Install additional languages…」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530355/8ace4663-311d-7fda-4ecb-291612abaadb.png)

####４．「Japanese Language Pack for VS Code」をインストール
画像だとVまでで途切れてしまっていますが、横幅広げると上記の名前になっています。
緑色の「Install」が（分かりにくいけど）インストールするためのボタンになっているので、「Install」をクリックしてインストールします。
このときはバージョン1.41.2でした（2019/12/31現在）が、どんどんバージョンアップされるので、数字が大きくなっていても気にすることはありません。
ちなみに「Install」ボタンではないところ（Japanese~のあたりとか）をクリックして選択すると、右側ペインに 詳細[Detail]とか変更履歴[ChangeLog]とか出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530355/b27dc903-c141-da19-8642-5b530f29eb74.png)

####５．VSCodeを再起動します。
「Install」ボタンが「Installing」という青い表記に変わったあと（普通は一瞬です）、設定用の歯車マークに変わります。これでインストールが完了です。
インストールが完了すると右下に「Restart Now」という青いボタンが表示されますので、ボタンを押すか、右上の「×」で閉じて再度起動させるか、等々でVSCodeを再起動しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530355/a22fe411-3c08-4f4c-02d4-78673d9a1d6f.png)

## 日本語化完了
VSCodeが再び開いたときには、日本語化が完了しているはずです。
調べると何か色々なやり方があるみたいですが、自分は今のところこれで満足してます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530355/0c012176-bca7-3d8e-b590-df537754b9a1.png)

## 英語表記に戻したい時は
メニューの「表示」→「コマンド パレット」または、<kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>P</kbd>でコマンド パレットを開きます。
上記２．の手順と同様にして「Configure Display Language」を選択すると、現在の表示言語として「ja」が選択されていることが分かります。
ここで「en」を選択するとVSCodeを再起動するよう言われます。VSCodeを再起動すると英語表記に戻ります。
さらに日本語にしたいときは、同じく「ja」を選択し直してVSCodeを再起動すれば、いつでも日本語に戻すことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530355/cc15aedb-8b96-3044-63f4-88469111295d.png)
「リファクタリング 第2版」Swiftでコーディング その7

# 12頁 第1章 play変数の削除 「関数宣言の変更(p.130)」

## Swift版 main.swift

データ生成、結果表示付き。

```swift
import Foundation

makeData()

func playFor(aPerformance:Performance) -> Play {
    return plays[aPerformance.playID]!
}

func statement(invoice:Invoice, plays:Dictionary<String, Play>) -> String {
    var volumeCredits = 0
    var totalAmount = 0
    var result = "Statement for \(invoice.customer)\n"
    let format = NumberFormatter()
    format.numberStyle = .currency
    format.locale = Locale(identifier: "en_US")

    for perf in invoice.performances {
        let thisAcmount = amountFor(aPerformance: perf, play: playFor(aPerformance: perf))

        volumeCredits += max(perf.audience - 30, 0)
        if "comedy" == playFor(aPerformance: perf).type {
            volumeCredits += Int(perf.audience / 5)
        }
        result += "  \(playFor(aPerformance: perf).name): " + format.string(from: NSNumber(value: thisAcmount / 100))! + " (\(perf.audience) seats)\n"
        totalAmount += thisAcmount
    }
    result += "Amount owed is " + format.string(from: NSNumber(value: totalAmount / 100))! + "\n"
    result += "You earned \(volumeCredits) credits\n"
    return result
}

func amountFor(aPerformance:Performance, play:Play) -> Int {
    var result = 0

    switch playFor(aPerformance: aPerformance).type {
    case "tragedy":
        result = 40000
        if aPerformance.audience > 30 {
            result += 1000 * (aPerformance.audience - 30)
        }
    case "comedy":
        result = 30000
        if aPerformance.audience > 20 {
            result += 10000 + 500 * (aPerformance.audience - 20)
        }
        result += 300 * aPerformance.audience
    default:
        print("error")
    }
    return result
}
 
let result = statement(invoice: invoices[0], plays: plays)
print(result)
```
「リファクタリング 第2版」Swiftでコーディング その6

# 11-12頁 第1章 play変数の削除 「変数のインライン化(p.129)」

## Swift版 main.swift
データ生成、結果表示付き。

```swift
import Foundation
A
makeData()

func playFor(aPerformance:Performance) -> Play {
    return plays[aPerformance.playID]!
}

func statement(invoice:Invoice, plays:Dictionary<String, Play>) -> String {
    var volumeCredits = 0
    var totalAmount = 0
    var result = "Statement for \(invoice.customer)\n"
    let format = NumberFormatter()
    format.numberStyle = .currency
    format.locale = Locale(identifier: "en_US")

    for perf in invoice.performances {
        let thisAcmount = amountFor(aPerformance: perf, play: playFor(aPerformance: perf))

        volumeCredits += max(perf.audience - 30, 0)
        if "comedy" == playFor(aPerformance: perf).type {
            volumeCredits += Int(perf.audience / 5)
        }
        result += "  \(playFor(aPerformance: perf).name): " + format.string(from: NSNumber(value: thisAcmount / 100))! + " (\(perf.audience) seats)\n"
        totalAmount += thisAcmount
    }
    result += "Amount owed is " + format.string(from: NSNumber(value: totalAmount / 100))! + "\n"
    result += "You earned \(volumeCredits) credits\n"
    return result
}

func amountFor(aPerformance:Performance, play:Play) -> Int {
    var result = 0

    switch play.type {
    case "tragedy":
        result = 40000
        if aPerformance.audience > 30 {
            result += 1000 * (aPerformance.audience - 30)
        }
    case "comedy":
        result = 30000
        if aPerformance.audience > 20 {
            result += 10000 + 500 * (aPerformance.audience - 20)
        }
        result += 300 * aPerformance.audience
    default:
        print("error")
    }
    return result
}
 
let result = statement(invoice: invoices[0], plays: plays)
print(result)
```
エイリアス備忘録

# エイリアス

ターミナルでのコマンドを省略したい。と思ってエイリアスを取り入れてみた。
EC２に入るのも簡単
設定も思いの外、簡単！

## エイリアスの使い方

ターミナルを開いて、下記を打ち込むとbashrcを編集できるようになる。

```
cd　　　         ・ホームに移動する。
vim　.bashrc 　  ・bashrcを編集する。
```


エイリアスの記述は、
alias 打ち込むコマンド='実行されるコマンド'
と記述する。

```
alias bash='vim .bashrc'
alias s='rails s'
```

エイリアスのコマンドを読み込んむようにbash_profileを編集する。

```
vim .bash_profile
```

bash_profileに


```
source .bashrc
```

と記述して保存する。

もう一度入り直すか 、ターミナルに下記を打ち込むと使えるようになる。

```
source .bashrc
```

## エイリアスコマンド一覧

追加したら、追記していきます。

##その他

間違えてたらコメントお願いします！
Pythonでウェブページから記事だけを取得する

##簡単にウェブページから本文を抽出できるライブラリ
Pythonでスクレイピングしたデータを抽出するとHTMLタグだったり後々の分で気に役に立たない
余計な情報がよく取得されてきてしまいます。

そんな時には[***readability-lxml***](https://pypi.org/project/readability-lxml/)があれば大丈夫です。こちらの説明をさせていただきます

##まずインストール

``` bash
(env)$pip install readability-lxml 
```

以下のようなユーティリティのクラスを作る

``` utils.py
# -*- coding:utf8 -*-
import lxml.html
import readability
def get_content(html):
    """
    HTMLの文字列から (タイトル, 本文) のタプルを取得する。
    """

    document = readability.Document(html)
    content_html = document.summary()
    # HTMLタグを除去して本文のテキストのみを取得する。
    content_text = lxml.html.fromstring(content_html).text_content().strip()
    short_title = document.short_title()
    return short_title, content_text

```
ユーティリティクラスを使って実際にタイトルとコンテンツが取得できているかテスト
(Yahooニュースの記事を使いました)

``` python
import utils
import requests
obj = requests.get('https://headlines.yahoo.co.jp/hl?a=20191230-00000310-oric-ent')
title,content = utils.get_content(obj.content)
print(title)
print(content)
```
以下のように記事が取得されているのを確認してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280363/6ccab81e-1223-4353-f1e0-61863e71f070.png)

## 更新履歴
- 2019/12/31 新規作成
connpassの受付をちょっと便利にする機能拡張を作った

開発者向けの勉強会といえばconnpassで管理している方が多いはず。ただ、あの受付機能って、他と比べてかなり使い勝手が悪いと感じます。

そこで、ちょっとだけ便利に使えるようにするGoogle Chrome機能拡張を作りました（まだ個人用レベルで、欲しい人が多そうならストアで公開します）。

## UIの違い

インストールするとこんな感じになります。ほとんど標準のと変わりません。

<img width="1532" alt="Screenshot_ 2019-12-31 11.57.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/a496fc0a-0672-7a3b-c04a-7d33acfcd83b.png">

違いは以下の点。

### 参加枠ごとのテーブルをやめて、一つのテーブルに統合します。参加枠は各行の左側に表示されます。

<img width="1512" alt="Screenshot_ 2019-12-31 12.01.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/39ad171b-8a26-e66f-3c87-3d78b9ab1adc.png">

### 絞り込み検索ができます

名前と、受付番号で絞り込み検索できます。

![Untitled1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/fe96d046-eba9-d739-e53b-f70732063ff8.gif)

### ソートできます

受付番号と名前でソートできます。

![Untitled2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/68177fe7-d049-6a52-7834-59d4db7d2997.gif)

### キャンセルした人の情報は非表示に

受付処理できる訳でもないので、キャンセルした人の情報っていらないと思うんですよね…。

## まとめ

実装はJavaScriptとCSSセレクタ（jQuery）ゴリゴリなので、デザインが変わると動かなくなるでしょう。たぶん滅多に起こらないと思いますが…。
Plotlyを使った描画結果をQiita内にCodePen埋め込むことで確認する

下記のCodePenの埋め込みは、Pythonでコードを書きplotlyの変換機能を使ってHTMLに変換・出力し、それをCodePenに貼り付けて埋め込み用のHTMLを生成しQiitaに貼り付けて描画しています。

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="wakamezake" data-slug-hash="mdyBOjd" style="height: 256px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="qiita_embed_sample">
  <span>See the Pen <a href="https://codepen.io/wakamezake/pen/mdyBOjd">
  qiita_embed_sample</a> by wakame1367 (<a href="https://codepen.io/wakamezake">@wakamezake</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

CodePenに貼り付けて埋め込み用のHTMLを生成するという作業は下記URLを参照してください。
[Qiita - Qiitaで記事にCodePenが埋め込めるようになりました](https://qiita.com/Qiita/items/edae7417214c8e957f54)

下記コードはplotlyの変換機能を使ってHTMLに変換・出力するコードをPythonで書いています。
このコードについてはGoogleColabratoryでのみ動作確認しております。

実際に書いたコードを共有状態にしておきましたのでご自由にお使いください。
[GoogleClolabratory - plotly_to_html](https://drive.google.com/open?id=1LisRpePE5lmTpa0MAbaq_GsxfZaK87Bo)

```python:plotly_to_html.py
#Plotly
import plotly
import plotly.tools as tls
import plotly.graph_objs as go
import plotly.express as px
import plotly.figure_factory as ff

# If you're using this code locally:
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

# If you're copying this into a jupyter notebook, add:
init_notebook_mode(connected=True)

# To run Plotly code in colab:
import plotly.io as pio
### REMOVE THIS LINE BEFORE RUNNING IN A JUPYTER NOTEBOOK
pio.renderers.default = 'colab'

fig = {
    "data": [plotly.graph_objs.Scatter(x=[1, 2, 3], y=[10, 20, 30])],
    "layout": plotly.graph_objs.Layout(title="offline plot"),
}

plotly.offline.plot(fig, auto_open=False, filename="temp-plot.html", include_plotlyjs="cdn")
```
[iOS/Swift] アプリ開発の実務的アプローチで学ぶデザインパターン ～Builder～

この記事シリーズは、iOS/Swiftエンジニアである執筆者個人が、
**ごく普通のiOSアプリ開発でよくある状況**や
**Swiftのコアライブラリやフレームワークで使われているパターン**に
着目してデザインパターンを学び直してみた記録です。

**関連記事一覧**
[[iOS/Swift] アプリ開発の実務的アプローチで学ぶデザインパターン](https://qiita.com/y-some/items/96db5f24ded4a1fab48f)

# Builderパターン概要

- 「段階的に設定すべき複数の構成要素」を持つ複雑なオブジェクトを生成するために使用されます。 
- すなわち、**オブジェクトを生成するための「お作法」を簡単にするパターン**です。
- GoFのデザインパターンでは**生成に関するパターン**に分類されます。

# 使い所

- 例えば、**UIAlertController** は「段階的に設定すべき複数の構成要素」を持つオブジェクトです。Builderパターンによって扱いやすくすることができます。

# サンプルコード

Swiftバージョンは 5.1 です。

```swift
extension UIAlertController {
    typealias Block = (() -> Void)?
    
    class Builder {
        private var alert: UIAlertController = UIAlertController(title: "",
                                                                 message: "",
                                                                 preferredStyle: .alert)
        
        convenience init(title: String?, message: String) {
            self.init()
            if let title = title {
                alert.title = title
            }
            alert.message = message
        }

        @discardableResult
        func addOkAction(completion: Block = nil) -> Self {
            return addAction(title: "OK", completion: completion)
        }
        
        @discardableResult
        func addCancelAction(completion: Block = nil) -> Self {
            return addAction(title: "Cancel", style: .cancel, completion: completion)
        }
        
        @discardableResult
        func addAction(title: String, style: UIAlertAction.Style = .default, completion: Block = nil) -> Self {
            let action = UIAlertAction(title: title, style: style) { _ in
                completion?()
            }
            alert.addAction(action)
            return self
        }
        
        func show(completion: (() -> Void)? = nil) {
            DispatchQueue.main.async {
                guard
                    let keyWindow = UIApplication.shared.windows.filter({$0.isKeyWindow}).first,
                    let rootViewController = keyWindow.rootViewController
                else {
                    return
                }
                rootViewController.present(self.alert, animated: true, completion: completion)
            }
        }
    }
}

// Usage
UIAlertController.Builder(title: "TITLE", message: "MESSAGE")
    .addCancelAction()
    .addOkAction(completion: {
        print("OK tapped")
    })
    .show()
```
flutter for webでDOM

なんとかして、flutter for webで作成したサイトにmetaタグを挿入したかった。

# まずjsとhtmlを。

importします。

```
import 'dart:html' as html;
import 'dart:js' as js;
```

# jsから操作します。

```
var meta = html.document.createElement("meta");
meta.setAttribute("name", "*******");
meta.setAttribute("content","******");
html.document.getElementsByTagName("head")[0].append(meta);
```

完了！

#ちなみに

metaではない場合は

```
html.document.querySelector('body').insertAdjacentHtml('beforeend', '<div></div>');
```

こんな感じで行けました。
VSCodeでgolangci-lintを設定する


## 環境
Go: go version go1.13 darwin/amd64
Homebrew: Homebrew 2.1.15

## 手順

### インストール

[README](https://github.com/golangci/golangci-lint#macos)に沿ってインストールする

### 設定ファイル

```yaml
# .golangci-lint.yaml
run:
  deadline: 5m

linters-settings:
  errcheck:
    # ファイルや任意のパッケージの関数のチェックを除外することができる。
    # https://github.com/kisielk/errcheck#excluding-functions
    exclude: /path/to/file.txt

linters:
  disable-all: true
  enable:
    - goimports
    - golint
    - govet
    - misspell
    - errcheck
    - staticcheck
    - prealloc
    - ineffassign
```

### エディタへの設定

settings.jsonに項目を追加する．

```JSON
{
    "go.lintTool":"golangci-lint",
    "go.lintFlags": [
        "--config=${workspaceFolder}/.golangci.yaml",
        "--fast"
    ]
}
```

## 参考

* [awesome-go-linters](https://github.com/golangci/awesome-go-linters)
* [golangci-lint](https://github.com/golangci/golangci-lint)
* [editor-integration](https://github.com/golangci/golangci-lint#editor-integration)
* [On-Save-features](https://github.com/microsoft/vscode-go/wiki/On-Save-features)
ZXingを用いたQRコード変換

VB.net初心者です。困っています。助けてください
PictureBoxコントロールに、内臓カメラで取得した画像を常時表示し、その画像(撮影しているQRコード)をボタンクリック時に文字列変換し、テキスト表示するアプリを作っています。

問題は以下の2つです。
１．変換処理でエラーが発生し、プロセスが死ぬ？
　　⇒Dim l_data As RGBLuminanceSource = New RGBLuminanceSource(b_data, source.Width, source.Height)
　　　この処理で毎回エラーが発生します。
　　　※エラーの画像は添付しています。「インデックスの範囲が境界外です。」といった旨です。![QR_error.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531856/73d75d6c-95d1-72f9-3e7c-a5a61cf55ec3.png)



２．上記１で該当処理が上手くいったとしても、QRコードから文字列への変換ができない。

言語はVB.netです。
ソースコードは以下になります。
ボタンを押してから、問題となっている「QRコード⇒文字列変換」の部分を載せておきます。
※念のため、インポートしている情報も載せておきます。
Imports ZXing
Imports ZXing.BinaryBitmap
Imports ZXing.Binarizer
Imports ZXing.LuminanceSource
Imports ZXing.Result
Imports ZXing.QrCode
Imports ZXing.QrCode.QRCodeReader

Imports UnityEngine
Imports UnityEngine.Color
Imports UnityEngine.Color32

    'testボタン押下時
    Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click

        '表示中のImageをbitmapとして取得
        Dim source As Bitmap = New Bitmap(Me.PictureBox1.Image)

        'QrCodeReader
        Dim q_reader As ZXing.QrCode.QRCodeReader = New ZXing.QrCode.QRCodeReader()

        'Imageオブジェクトをバイト配列に変換
        Dim b_data As Byte() = ImageToByteArray(source)

        Dim l_data As RGBLuminanceSource = New RGBLuminanceSource(b_data, source.Width, source.Height)

        Dim binarizer As Common.HybridBinarizer = New Common.HybridBinarizer(l_data)
        Dim source2 As BinaryBitmap = New BinaryBitmap(binarizer)

        'QRCodeReader変換
        Dim q_result As ZXing.Result = q_reader.decode(source2)
        If (q_result IsNot Nothing) Then
            Dim q_string As String = q_result.ToString
            load_seizo_txt.Text = q_string.Substring(0, 5)
            load_seiko_txt.Text = q_string.Substring(6, 11)
            load_lot_txt.Text = q_string.Substring(12, 17)
        End If
    End Sub


    'Imageオブジェクトをバイト配列に変換
    Public Shared Function ImageToByteArray(ByVal img As Image) As Byte()
        Dim b As Byte() = CType(imgconv.ConvertTo(img, GetType(Byte())), Byte())
        Return b
    End Function


ちなみに撮影中のQR画像ではなく、ネットに転がっていたきれいなQRコードの画像を同様に変換処理してもエラーが発生します。
なので画像ではなく、ZXsingによる変換処理中の問題なのかと考えています。

以上です。
乱文で申し訳ございませんが、どなたかご教授お願い致します。
Pytorchではtorch.deviceとDataParallel両方で使用するGPUを指定可能ですが

Pytorchにはtorch.deviceとDataParallel両方で使用するGPUを指定可能ですが、それらの設定が矛盾している場合はどうなるのでしょうか？ 

例： 

gpus = (0,2,4) #使用するgpu番号のtuple(複数選択可) 

#GPU id を0,2,4に設定された！

device = torch.device(f"cuda:{min(gpus)}" if len(gpus) > 0 else 'cpu') 

#GPU を1,3,5に指定された！

model = DataParallel(model, device_ids=[1,3,5])        

model.to(device)
pythonで文字列を式として計算するeval()関数

へー便利！と思ったのでメモ
eval()関数は**式**の文字列を引数として計算結果を返す。

## 使い方
```
>>> eval("1 + 2")
3
>>> eval("1" "2")
12
>>> eval("1" + "2")
12
>>> eval("1" "+" "2")
3
```

---
どういう時に使うのかというと、僕はAtCoderの[この問題](https://atcoder.jp/contests/arc061/tasks/arc061_a)で使いました。

問題文
1 以上 9 以下の数字のみからなる文字列 S が与えられます。 この文字列の中で、あなたはこれら文字と文字の間のうち、いくつかの場所に + を入れることができます。 一つも入れなくてもかまいません。 ただし、+ が連続してはいけません。
このようにして出来る全ての文字列を数式とみなし、和を計算することができます。
ありうる全ての数式の値を計算し、その合計を出力してください。

```python

from itertools import product
s = list(input())
n = len(s)
answer = 0
 
pattern = list(product(['+', ''], repeat=n-1))
 
for i in range(2 ** (n-1)):
    formula = s[0]
    for j, k in zip(pattern[i], s[1:]):
        formula += (j + k)
    answer += eval(formula)
 
print(answer)
```
DeeplearningにGPUの役立つ場面？

GPUは　Deep learning の訓練段階において、miniバッチを分割して並列計算に有効だと理解できていますが、
Q1:　訓練段階においてサブバッチを分割以外でもGPU、とりわけ多GPUを利用する場面があるのでしょうか 

Q2:　テスト段階にもGPUが役立つのでしょうか。 

宜しくお願いします
Lenovo ThinkPad A285 で Wi-Fi ネットワークが切れる

最近購入した　Lenovo製 ThinkPad A285 。
自宅のBuffaloe製 Wi-Fiルータにつないでいるのですが、頻繁にネットワークが切れたり、同じルータにつながっている機器のネットワークも繋がらなくなったりする事象がありました。

最初は台数制限とか、息子がオンラインゲームをやってたりしたので、それらを疑っていたのですが、原因はThinkPad側にありました。

結論から申しますと、之が原因でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234182/72869f0a-ab34-2d02-ec23-34043eb91b13.png)


Realtek 8822BE Wireless LAN 802.11ac PCI-E NIC のプロパティ。
こいつの、 802.11d の 値を 無効 にする。（出荷時は有効になっている）

これで直りました。（息子よ疑ってごめんなさい。）

ちなみに、802.11d についてはこちら。
https://www.wdic.org/w/WDIC/IEEE%20802.11d
今日のpython error: UnicodeEncodeError: 'ascii' codec can't encode characters 

今日のpython error: UnicodeEncodeError: 'utf-8' codec can't encode characters
https://qiita.com/kaizen_nagoya/items/ac48ba7946b303bb25fb

からの作業記録


```shell-session:docker/ubuntu
# python3 wid.py HAZOP
/wiki/FMEA
Traceback (most recent call last):
  File "wid.py", line 25, in <module>
    print (unquote(link.attrs['href']))  
UnicodeEncodeError: 'ascii' codec can't encode characters in position 6-14: ordinal not in range(128)
```
# 文書履歴(document history)
ver. 0.01 初稿 20191221
ver. 0.04 URL追記　20230302

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
PythonでHTMLフォームのデータを受信し表示する

PythonでHTMLフォームのデータを受信し、表示させてみた。

## HTMLファイルの記述

まずはHTMLでフォームを送信するコードを記述する。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <form method="POST" action="cgi-bin/index.py">
      <label>テキスト：</label>
      <textarea name="text"></textarea>
      <button type="submit">送信</button>
    </form>
  </body>
</html>
```

- `method`について

`method`には、データを取得する`GET`メソッドと、データを送信する`POST`メソッドがある。
今回は、データを送信するので、`POST`メソッドを用いる。

- `action`について

`action`で、データを送信するURLを指定できる。
今回は、後に出てくる`cgi-bin/index.py`に送信する。

フォームデータの送信についての詳しい説明は、以下の記事を参照。
https://developer.mozilla.org/ja/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data

## Pythonファイルの記述

次に、Pythonでデータを受け取り、表示するCGI（ゲートウェイインタフェース規格）スクリプトを記述する。
CGIスクリプトとは、HTTPサーバーによって起動され、HTMLなどでユーザーが入力したデータを処理するスクリプトである。
詳細は、以下の記事を参照。
https://docs.python.org/ja/3/library/cgi.html#module-cgi

```python:cgi-bin/index.py
#!usr/bin/python
# -*- coding: utf-8 -*-

import cgi # CGIモジュールのインポート
import cgitb
import sys

cgitb.enable() # デバッグに使うので、本番環境では記述しない

form = cgi.FieldStorage() # フォームデータを取得する

print("Content-Type: text/html; charset=UTF-8") # HTMLを記述するためのヘッダ
print("")

# フォームのデータが入力されていない場合
if "text" not in form:
    print("<h1>Error!</h1>")
    print("<br>")
    print("テキストを入力してください！")
    print("<a href='/'><button type='submit'>戻る</button></a>")
    sys.exit()

text = form.getvalue("text") # データの値を取得する

print(text)
```


後に実行するときのために、以下のコマンドで実行権限を変えておくこと。

```bash:Command
$ chmod 755 cgi-bin/index.py
```

## CGIサーバーを動かす

（以下の記事を参考にしました。
https://qiita.com/shuichi0712/items/5ddc5b4e30c2373b17fb ）

次に、CGIサーバーを動かす。
そのためのスクリプトを、`cgiserver.py`に記述する。

```python:cgiserver.py
import http.server
http.server.test(HandlerClass=http.server.CGIHTTPRequestHandler)
```

その後、以下のコマンドを実行すると、CGIサーバーが動く。

```bash:Command
$ python -m http.server --cgi
```
その後、ブラウザでhttp://0.0.0.0:8000 と検索すると、フォームが表示され、フォームを入力して送信すると、入力内容が表示される。
【python】dbファイルをcsv化する方法

pythonでしたほうがいい場合もありますよね。

#方法
1. splite3でデータベースを読み込む
2. headerを作り、dataframeを用意する
3. 各データをdataframeに挿入しcsvとして保存する

以上の要領です。

##### sqlite3でデータベースを読み込む

```
import splite3
path = 'path_to_db'
conn = sqlite3.connect(path)
```

##### headerを作り、dataframeを用意する

```
import pandas as pd
header = []
c = conn.cursor()
for column in c.execute('PRAGMA table_info("table_name")'):
    header.append(column[1])
```

##### 各データをdataframeに挿入しcsvとして保存する

```
df = pandas.DataFrame(columns=header)
for raw in c.execute('SELECT * FROM table_name ORDER BY index_name):
    series = pd.Series(list(raw), index=df.columns)
    df = df.append(s, ignore_index=True)
df.to_csv('path_to_csv')
```
データを`append`する度に`df`に代入し直しているのがミソですね。
Railsでファイル変更時のオートリロードを実現

静的ページのコーディング時、これまではvscodeの拡張機能によってオートリロードを実現していました。
Rails環境(動的ページ)でも同じことを実現する方法がわかったので、ここにまとめていきます。

当初`guard-livereload`というgemを使おうと思ったのですが、開発が止まっている雰囲気だったのと、(少なくとも)デフォルトの設定だとscssファイルの変更時に再読み込みが行われなかったので、最終的に`browser-sync`を使って実装しました。

gulpもwebpackもブラウザの拡張機能も不要なので、けっこう手軽です。

##実装方法
###browser-syncをインストール
```terminal
$ npm install -g browser-sync
```
`/usr/local/lib/node_modules/browser-sync`への書き込み権限が無い！と怒られたので、以下の記事を参考に`sudo chown -R $(whoami) $(npm root -g)`で解決しました。
[npm のグローバルインストールに失敗したら](http://neos21.hatenablog.com/entry/2019/01/02/080000)

###起動
```terminal
$ rails s
```
```terminal
$ browser-sync start --proxy localhost:3000 --files "app/assets/stylesheets/*/*.scss","app/views/*/*.html.*"
```

###npm scriptsを使う場合
プロキシや監視対象のファイルを引数で渡さずに、設定ファイルに記述することも可能です。

```terminal
$ npx browser-sync init
```
```bs-config.js
//他の記述は削除
module.exports = {
    "files": ["app/assets/stylesheets/*/*.scss", "app/views/*/*.html.*"], 
    "proxy": 'localhost:3000'
};
```
```package.json
{
  "scripts": {
    "bs": "browser-sync start --config bs-config.js"
  }
}
```
起動

```
$ rails s
$ npm run bs
```

##参考
[Railsでファイル変更に応じてリロードしてくれるBrowserSyncを手軽に導入する](https://qiita.com/imaimiami/items/3d91551b8b20208f0024)
[browser-syncを使う](https://qiita.com/niki-tstk/items/83631b5c5517abbf0bc4)
RaspberryPiのPythonでMySQLへ接続する

TWE-Liteのセンサー値をテーブルにINSERTしたかったので、その準備

コマンドはたった１つ

```
$ sudo pip install PyMySQL
```
上記がダメなら下記をインストール

```
$ sudo pip install mysql-connector-python-rf
```
これだけで、ソースに記述したDB関連が動くようになる。
以上。
[Vagrant] vagrant以外のユーザへ公開鍵認証でSSH接続する方法


ホストOSからゲストOSのvagrant以外のユーザへ、公開鍵認証でSSH接続する手順を残します。

注意点

1. 今回はホストOSからパスワード認証をせず公開鍵認証をすることが目的のため、ゲストOS側でsshd設定は変更していません。
1. ユーザは既に作成された前提です。
1. 手順内で、[]で囲われた箇所は適宜読み替えて設定してください。
  - ホスト名
     - 通常は `127.0.0.1` です。
  - ポート番号
     - デフォルトで `2222` に設定されています。
  - 公開鍵・秘密鍵ファイル名
     - `~/.ssh/` 下に配置されている対になったファイルの名前です。末尾 `.pub` のファイルが公開鍵です。

## 公開鍵・秘密鍵の配置

### ホストOS側作業

1. SSHの公開鍵と秘密鍵を作成する。
   - 鍵の作成方法はこの記事では取り扱いません。以下の記事などを参考に作成してください。
     - [お前らのSSH Keysの作り方は間違っている - Qiita](https://qiita.com/suthio/items/2760e4cff0e185fe2db9)

1. 公開鍵をゲストOSへ転送する。

    ```
    scp -P [ポート番号] ~/.ssh/[公開鍵ファイル名] [ユーザ名]@[ホスト名]:/home/[ユーザ名]/.ssh/authorized_keys
    ```

### ゲストOS側作業

1. 公開鍵のアクセス権限を変更する。

   ```bash
   chmod 600 ~/.ssh/authorized_keys
   ```

## SSH接続設定

### ホストOS側作業

1. Vagrantfileを編集。

    ```ruby:Vagrantfile
    config.ssh.username = "[ユーザ名]"
    ```
1. 一旦ゲストOSを落とし、再度立ち上げる。

    ```bash
    vagrant up
    ```
   - `mkdir -p /vagrant` ができず、エラーが表示されるが問題ない（ユーザ権限がなく、共有フォルダの生成に失敗している）。 

1. ゲストOS用のSSH設定を、ホストOSのSSH設定に追加する。

    ```bash
    vagrant ssh-config >> ~/.ssh/config
    ```
1. SSH設定をエディタでさらに編集。
  - `host default` の `default` を適当な分かりやすいホスト名に変更。
  - 末尾に以下の設定を追加。

    ```:~/.ssh/config
    IdentityFile ~/.ssh/[秘密鍵ファイル名]
    ```
1. Vagrantfileから、1で編集した行を削除もしくはコメントアウトし、ゲストOSを再起動する。

## 参考URL

[SSH into Vagrant box as another user using key? - Stack Overflow](https://stackoverflow.com/questions/34928050/ssh-into-vagrant-box-as-another-user-using-key)

[vagrant up時にmkdir -p /vagrantが失敗する - Qiita](https://qiita.com/EichiSanden/items/68b0ae3d8a98ea60cc3e)
paizaでilasm その２

# 概要

paizaでilasmやってみた。
classやってみた。

# サンプルコード


```
import subprocess
import os

def cil():
    c_file = 'hello1.il'
    test_c = """
.assembly hello1 {
}
.class private auto ansi hello1 extends [mscorlib]System.Object {					
	.method public specialname rtspecialname instance void .ctor() cil managed {	
		.maxstack	2
		ldarg.0
		call		instance void [mscorlib]System.Object::.ctor()
		ret
	}
	.method public instance void Say(string A_1) cil managed {
		.maxstack	1
		ldarg.1
		call		void [mscorlib]System.Console::WriteLine(string)
		ret
	}
	.method static void Main() cil managed {		
		.entrypoint
		.maxstack 	8
		.locals 	init (string V_0, class hello1 V_1)
		ldstr		"hello1"
		stloc.0									
		newobj		instance void hello1::.ctor()
		stloc.1									
		ldloc.1
		ldloc.0
		call		instance void hello1::Say(string)
		ret
	}
}



"""
    with open(c_file, 'w') as f:
        f.write(test_c)
    os.system("ilasm %s" % c_file)
    os.system("mono hello1.exe")
    
if __name__ == '__main__':
  cil()




```

# 成果物

https://paiza.io/projects/59FVyRGw5kWTMcfje2556g

以上。
STLのinertiaをMeshLabから計算する

# はじめに

ROS＆Gazeboでシミュレーションをするときに、inertiaを正しく設定しないと想定通り動かないことがあります。今回は、[MeshLab](http://www.meshlab.net/)を使ってinertiaを計算する方法をまとめます。

とは言っても、公式ドキュメント[Inertial parameters of triangle meshes](http://gazebosim.org/tutorials?tut=inertia&cat=build_robot)が存在し、この通り設定すれば動くのですが、わたしは理解するのに小一時間なやんでしまったので、今回はその解説です。

やはく計算式をよこせという方は、こちらをどうぞ！
https://docs.google.com/spreadsheets/d/1Y_lwnLfvxX3A3op7AxNbXVvc4fE7W9cXn6xtQcOpz6E/

# 環境

| 環境  | バージョン |
|:--|:--|
| 開発機  | Ubuntu 16.04.6 LTS |
| ROS  | Kinetic Kame |
| Gazebo  | version 9.11.0 |
| MeshLab | v1.3.2 |

# link elementの確認

まず[link](https://wiki.ros.org/urdf/XML/link)ですが、今回設定するものは、`inertial`の`origin`と`inertia`です。`origin`は、

>The origin of the inertial reference frame needs to be at the center of gravity.

とあるように物体の重心を設定する必要があります。これは、ドキュメントにもあるとおり自動的に`Center of Mass`で計算されるので、そのパラメータを設定します。

次に`inertia`ですが、こちらが少々わかりにくいです。MeshLabで計算される`Inertia Tensor`は、[calculating-inertial-matrix-for-gazebo](https://answers.ros.org/question/237421/calculating-inertial-matrix-for-gazebo/)のコメントにあるように

> Note that the mass value is the same as the computed volume, this means that a default value of density rho=1 has been used. The density of the material of your gripper expressed in kg/m^3 has to be multiplied by the volume in order to get the mass. Example density is rho = 7850 Kg/m^3 (steel).

密度(density)を$1[kg/m^3]$と仮定した体積のため`Inertia Tensor`の単位は、$[m^5]$となります。つまりメッシュから体積を求めたので、重さ（mass）は密度から求めるなり、測定値から求めるなりしてくださいということです。

これで`inertia`の計算ができそうですが、最後に`Scale Factor`で注意点があります。`Scale Factor`は、オブジェクトが小さい時のinertiaを計算するときに小数点以下で切り捨てられることによって全て0となってしまうのを避けるために、実際の大きさからスケールして計算するときに設定するものです。密度から重さを逆算して計算する場合は、$10^5$でスケールされるのに対して、測定値の重さから計算する場合は、$10^2$でスケールされるので、最後に単位を戻すのを忘れがちです。

# 計算式

使いやすいようにスプレッドに計算をまとめました。これを見れば2秒で理解できると思います。この例では、cylinderをScale Factor=10で自分で測定した重さを用いて計算しています。MeshLabから計算されたinertiaが正しいかどうかは、[List_of_moments_of_inertia](https://en.wikipedia.org/wiki/List_of_moments_of_inertia)から手計算で同じ値になることで確認をすることができます。

https://docs.google.com/spreadsheets/d/1Y_lwnLfvxX3A3op7AxNbXVvc4fE7W9cXn6xtQcOpz6E/

# まとめ

* MeshLabからinertiaを計算するときは、密度から重さを求めるか、測定値の重さを使用するかで、Scale Factorが異なるので注意する必要がある
* 簡単な形のinertiaの計算があっているかは、手計算で確認できる
[Shopify] 12月の更新をまとめました

都度更新しようと思っていましたが・・12月も一瞬で去ってしまい、まとめます。そしてShopify更新多いな・・　:sweat_smile:

前回は更新はこちらでまとめました。
https://qiita.com/syantien/items/488749d09703d97d8da7

前回は12/02の更新だったので、それ以降から今日までの更新が下記です。

# :congratulations: Version 2020-01

多くのリリースは2020-01の話となっています、2020-01バージョンはこちらを参照してください。
https://help.shopify.com/en/api/versioning/release-notes/2020-01

近日、こちらの更新もまとめたいと思います。

# 12/20 コレクションAPIはカスタムコレクションに関するアイテムしか返さなくなります。

2020-01バージョンからCollection APIはSmart Collectionsで連携されている商品は返さないとのことです。　これはまた次回詳細を追いたいと思います。

https://developers.shopify.com/changelog/collects-api-now-returns-only-collects-associated-with-custom-collections

# 12/20 コレクション内の商品が参照可能になります。

2020-01バージョンからCollection内の商品を参照することができます。また、コレクションIDを指定することでも参照することができます。こちらも同じく次回詳細を追いたいと思います。

コレクションAPIに関しては下記を参照ください。
https://help.shopify.com/en/api/reference/products/collection

https://developers.shopify.com/changelog/new-collection-rest-admin-api

# 12/18 プリディクティブ検索APIにさらなるイメージ情報を追加されます。

Predictive Searchの返値に新たに下記の値が含まれるようになりました。

- featuredimage[:alt]: イメージのaltタグ
- featuredimage[:width]: イメージの幅
- featuredimage[:height]: イメージの高さ
- featuredimage[:aspectratio]: イメージの縦横比率
- featuredimage[:url]: イメージのURL

Predictive Searchに関しては下記を参照ください。
https://help.shopify.com/en/themes/development/search/predictive-search

https://developers.shopify.com/changelog/additional-image-details-added-to-predictive-search-api

# 12/13 GrpahQLのオブジェクトが250アイテムまでの上限設定をします。

あら、そう来ましたか、そうですよね。:ghost:
Shopifyを利用するべてのショップにて安定したサービスを受けるためにはこういうのは必要なので、がんばまりましょう。

2020-01バージョンから250以上のアイテムをリクエストした場合エラーが返ってきます・・　

下記のようなコードはエラーが返されます

```
{
  nodes(ids: [“id1”, “id2”, “id3”, ... , “id251”, “id252”]) {
   … on Order {
      id
   }
}
```
https://developers.shopify.com/changelog/graphql-input-objects-limited-to-250-items

# 12/11 編集されたOrderのWebhookとOrder編集の機能追加

Orderの編集機能は一部のマーチャントですでに利用可能となっています。2020-01バージョンからは一般リリース？となるようです。

- GraphQLを使って注文の編集をすることができます
- そしてOrderが編集されたタイミングでwebhookを受け取ることができるようになります。:santa_tone2:

Orderの編集方法はこちらを参照してください
https://help.shopify.com/en/api/guides/editing-orders

https://developers.shopify.com/changelog/new-order-edited-webhook-and-order-editing-api-capabilities

# 12/09 Public Appsに関する更新とCustom Appsの紹介。

詳細はこちらのブログを参照ください。
https://www.shopify.com/partners/blog/shopify-public-apps

今回のリリースによってPrivate Appsがなくなるわけではないようです。ただ、Private AppsよりもCustom Appsのほうがお勧めであるとのことです。アクセスできる機能も多く、セキュアなので自然と今後はCustom Appsになっていくと思われます。

https://developers.shopify.com/changelog/update-to-public-apps-and-introducing-custom-apps

# 12/06 Storefront APIからUnitPriceが取得できるようになりました。

以前より一部のマーチャントに公開とはなっていましたが、
2020-01バージョンよりUnit PriceがStorefront APIから取得できるようになります。

Product Variantに追加される項目

- presentmentUnitPrices
- unitPrice
- unitPriceMeasurement

Product Variantは下記を参照
https://help.shopify.com/en/api/storefront-api/reference/object/productvariant?api%5Bversion%5D=2020-01

https://developers.shopify.com/changelog/unit-pricing-information-now-available-through-storefront-api
subprocess.check_call('ls -l')ではなく、subprocess.check_call('ls -l',shell=True)を指定しないと動かない

#動かない
```python
subprocess.check_call('ls -l')
```

#動く
```python
subprocess.check_call('ls')
subprocess.check_call('ls -l',shell=True)
```

どうもコマンドのオプションを指定する際にはshell=Trueにしないと駄目らしい
micro:bitでサーボモータを使ってみる

# 購入したもの
* モータードライバ
    * https://www.kitronik.co.uk/5612-kitronik-i2c-servo-driver-board-for-the-bbc-microbit.html
    * https://www.amazon.co.jp/dp/B07BT5JK7X/
    * https://www.yodobashi.com/product/100000001004020958/
* サーボモーター
    * https://www.amazon.co.jp/dp/B06XRG4S55
* 電池ボックス
    * https://www.yodobashi.com/product/100000001001123961/
    * 3～5.5V出力ができるもの。
    * 単三電池1.2～1.5Vなので3本くらいのものがおすすめ。

# micro:bitの準備
micro:bit用のモータドライバを使うためにブロックを追加します。

1. 赤枠で囲んだ「高度なブロック」をクリックします。
![r1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/6d339c30-ab80-80fe-ae0f-8b1866f61c7e.png)

2. 一番下に拡張機能が表示されますのでクリックします。
![r2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/25c228a3-405f-5cd1-1de4-eeb6c36f9f27.png)

3. 以下のような画面になるので検索用のテキストボックスに「servo 16」と入力して検索します。
![r3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/e53f3fb6-992b-0208-7d53-b2c27213f980.png)

4. 検索するといくつかの拡張ボックスが表示されるので、赤枠で囲んだ「kitronik-I2C-16-servo」をクリックして追加します。
![r4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/b250ca12-acdc-fd2c-8e6b-19285affc70b.png)

5. 拡張機能から戻ると、メニューに「I2C-16-Servo」が追加されています。
![r5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/93f70dcc-a4b2-b018-9f2b-bbc870e71df3.png)

6. 「I2C-16-Servo」をクリックするとサーボモータをコントロールするブロックが追加されます。
![r6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/2963f8f0-eb31-4c2f-fae4-b8d2b1589771.png)

# モータドライバ、サーボモーター、電池ボックスを繋げる
接続に関しては電源の方は、RED/BLACKと接続する線の色が基盤に書かれているので、それに従って接続します。
モーターの方は外側がGNDになっているので黒い線がGNDになるように接続すればOKです。
以下のようなつなぎ方でモータの制御がmicro:bitからできました。
![IMG_4880.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28184/dda5eac3-0e0c-ed3d-e331-4dc3311f15df.jpeg)

# 270°モータの場合
270°のモータを使っても、ブロックは0～180の値しか設定できません。
90を設定すると丁度垂直になるようになっているので、0°から180°の間で動作させる場合は設定値を30～150で値を設定する必要があります。
値を0～180で設定すると想像以上に稼働して？？？になります。

Amazonで購入するときは、
180°
https://www.amazon.co.jp/dp/B06XQWX172
270°
https://www.amazon.co.jp/dp/B06XRG4S55
とがあるので、間違わずに購入しましょう。
ROS ecl_exceptionsがc++11でDataExceptionは使えるがStandardExceptionが使えない

# はじめに

[ecl_exceptions](http://wiki.ros.org/ecl_exceptions)は、ROSパッケージのひとつでテンプレートベースの例外管理をするライブラリです。今回、これを使用するときにDataExceptionは使用できるが、StandardExceptionが使用できなかったので原因を調査しました。

# 前提条件

| 環境 | バージョン |
|:-:|:-:|
| 開発機  | Ubuntu 16.04.6 LTS |
| ROS  | Kinetic Kame |
| コンパイル | c++11 |

# エラー詳細

DataExceptionとStandardExceptionを使用した場合、下記のようなエラーが発生します。

```
ecl::StandardException::StandardException(char const*, ecl::ErrorFlag, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' に対する定義されていない参照です
```

ネットで検索すると、[Std::__cxx11::basic_string vs std::basic_string](https://root-forum.cern.ch/t/std---cxx11-basic-string-vs-std-basic-string/21090)があり、コンパイルしているC++のバージョンとリンク対象がコンパイルされたC++のバージョンが異なるときに出るエラーのようです。


# ソースを確認する

ヘッダを確認すると[standard_exception.hpp](https://github.com/stonier/ecl_core/blob/release/0.61-indigo-kinetic/ecl_exceptions/include/ecl/exceptions/standard_exception.hpp)と[data_exception.hpp](https://github.com/stonier/ecl_core/blob/release/0.61-indigo-kinetic/ecl_exceptions/include/ecl/exceptions/data_exception.hpp)でdata_exception.hppはテンプレートのためヘッダに実装されているが、standard_exception.hppは、[standard_exception.cpp](https://github.com/stonier/ecl_core/blob/release/0.61-indigo-kinetic/ecl_exceptions/src/lib/standard_exception.cpp)に実体が実装されています。

ここでコンパイルオプション([CMakeLists.txt](https://github.com/stonier/ecl_core/blob/release/0.61-indigo-kinetic/ecl_exceptions/CMakeLists.txt))を調べると、indigo-kineticには何もついていません。ROS2のBouncy([CMakeLists.txt#L22](https://github.com/stonier/ecl_core/blob/release/1.0-bouncy/ecl_exceptions/CMakeLists.txt#L22))からは、`ecl_enable_cxx14_compiler`マクロがあり、これが[ecl_cxx.cmake#L6](https://github.com/stonier/ecl_tools/blob/5f71abbcd9675c9a0d3e3f0c1c904f8f59fa1e0c/ecl_build/cmake/ecl_cxx.cmake#L6)で定義されているため、Bouncy以降でC++14を使っている場合は、問題なく使えるようです。

# まとめ

* C++のバージョンは、依存するROSパッケージの対応があるか確認する必要がある
* 対応がない場合、自分の手元でビルドし直す必要がある
今日のpython error: UnicodeEncodeError: 'utf-8' codec can't encode characters

昨日(20191230)の記事

今日のpython error: ModuleNotFoundError: No module named 'bs4'
https://qiita.com/kaizen_nagoya/items/f0056e5fc735b3ad5783

で、最後に出た

```shell-session:docker/ubuntu
# python3 wib.py
Traceback (most recent call last):
  File "wib.py", line 15, in <module>
    url = "https://ja.wikipedia.org/wiki/" + urllib.parse.quote(args[1])
IndexError: list index out of range
```
これは、実行時に引数を与えなかったからだった。
夜遅くの作業で、記事をあげて修了した。

朝、起きて、「IndexError: list index out of range」検索
IndexError: list index out of rangeのエラーが修正できません(初心者です)
https://teratail.com/questions/166749

元記事と
プログラムちょい替え（2）Python3: URLをコマンドライン引数で(wikipedia)
https://qiita.com/kaizen_nagoya/items/fc095b0c580a35001ea7

そのさらに元記事
wikipediaからのページからリンク一覧を取得する方法
https://qiita.com/tadaken3/items/e09ba2ede988bbacb303

を眺めるとargs[]は、コマンドラインの引数で、実行時に引数を与えていることがわかる。

昨日の夜はpythonの記述方法で頭がいっぱいで、実行時のコマンドにまで思いが至ってなかった。

```shell-session:docker/ubuntu
# python3 wic.py  統計
Traceback (most recent call last):
  File "wic.py", line 15, in <module>
    url = "https://ja.wikipedia.org/" + urllib.parse.quote(args[1])
  File "/usr/lib/python3.6/urllib/parse.py", line 819, in quote
    string = string.encode(encoding, errors)
UnicodeEncodeError: 'utf-8' codec can't encode characters in position 0-5: surrogates not allowed
```

日本語ではなく英語で実行してみる。

```shell-session:docker/ubuntu
# python3 wic.py hazop
Traceback (most recent call last):
  File "wic.py", line 17, in <module>
    html = urlopen(url)
  File "/usr/lib/python3.6/urllib/request.py", line 223, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python3.6/urllib/request.py", line 532, in open
    response = meth(req, response)
  File "/usr/lib/python3.6/urllib/request.py", line 642, in http_response
    'http', request, response, code, msg, hdrs)
  File "/usr/lib/python3.6/urllib/request.py", line 570, in error
    return self._call_chain(*args)
  File "/usr/lib/python3.6/urllib/request.py", line 504, in _call_chain
    result = func(*args)
  File "/usr/lib/python3.6/urllib/request.py", line 650, in http_error_default
    raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 404: Not Found
```

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
python+selenium+safari-webdriverでmacからiphoneのsafariを動かす

# 動機
iOS13からsafariのwebdriverが正式導入されたみたいな記事を発見したが
([Webdriver is Comming to Safari in iOS13](https://webkit.org/blog/9395/webdriver-is-coming-to-safari-in-ios-13/))全然やり方の記事を見つけられなかったので自分で試行錯誤しながら、動かすところまでできたので記録として残したいと思います。

### 目次
1. iPhone側での設定
2. MAC側から操作

# ①iPhone側の設定
- 設定→Safari→詳細→リモートオートメーションをオンにする
- iPhoneをMACに接続し、このコンピュータを信頼するにはい

# ②MAC側からの操作
まずseleniumのインストール
`pip install selenium`

下記はpythonでのコード

~~~
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

desiredcapabilities= DesiredCapabilities.SAFARI.copy()
desiredcapabilities["platform"]="ios"

driver = 
webdriver.Safari(desired_capabilities=desiredcapabilities)

driver.get("https://google.co.jp")

~~~

macからiphoneのsafariを動かせます
【Nuxt】GETパラメータによってimgタグのsrc属性を動的に変更する

# はじめに
Nuxt.jsでGETのクエリで取得したパラメータの値によって変えようとして少しハマったので備忘録として投稿する。あくまでも一つの方法なので、参考程度にお願いします。

# 方法
`http://localhost/result?id=ABC123`のようにidのGETのクエリによって切り替えることを例に説明する。
以下のようにsrcをバインドする。バッククオートを用いることで評価式の結果を文字列としてそのまま書き出してくれる。また、$route.query.id。

```html
<img :src="`http://localhost/${$route.query.id}.jpg`"/>
```

このようにすると以下のように変換してくれる。

```html
<img :src="`http://localhost/ABC123.jpg`"/>
```
Laravel キャッシュクリア＆最適化

本番環境にデプロイする際に必ずやっておきたいキャッシュクリア＆最適化です。

## キャッシュクリア＆最適化

```shell-session
$ composer install --optimize-autoloader --no-dev
$ php artisan optimize:clear
$ php artisan optimize
```

## 補足

### --optimize-autoloader オプション

本番環境ではオプション付き、開発環境ではオプションなしで運用します。
このコマンドは下記ファイルを生成します。

```
vendor/composer/autoload_classmap.php
vendor/composer/autoload_files.php
vendor/composer/autoload_namespaces.php
vendor/composer/autoload_psr4.php
vendor/composer/autoload_real.php
```

### optimize

https://laravel.com/api/7.x/Illuminate/Foundation/Console/OptimizeCommand.html

### optimize:clear

https://laravel.com/api/7.x/Illuminate/Foundation/Console/OptimizeClearCommand.html

## 参考

- [Laravel 7.x デプロイ
](https://readouble.com/laravel/7.x/ja/deployment.html)
GitHub Learning Lab をつかって GitHub Pages を作る

## はじめに
[GitHub Pages](https://pages.github.com/) を使ってサイトが作れることを知り [GitHub Pages のヘルプページ](https://help.github.com/ja/github/working-with-github-pages/about-github-pages) を見てみたのですが，翻訳中ということもあり少しわかりにくい．

[GitHub Learning Lab](https://lab.github.com/) の中に [GitHub Pages](https://lab.github.com/githubtraining/github-pages) のコースを見つけたので，これに沿って GitHub Pages を作成してみました．（とても簡単）

## GitHub Learning Lab とは
GitHub Learning Lab は [GitHub](https://github.com/) 上でプログラミングやプログラミングに関連した内容を学べる簡易コースです．コースでは，bot が issue (課題) を作成してくれます．issue 内のタスクを完了すると評価コメントが返ってきたり，その issue が閉じられて次の issue が作成されるようになっています．

GitHub Learning Lab には，GitHub Pages 以外にも GitHub 自体の使い方 (Apps/Actions)， HTML やマークダウンの基礎などいろいろなコースが用意されています．
英語のみですが，読む文章量は少ないのでそれほど難しくありません．

## 事前準備
- GitHub のアカウント
- GitHub のアカウントと GitHub Learning Lab の紐付け  

こちらのページに方法がまとまっています．
[GitHub初心者が「GitHub Learning Lab」を使ったら良かった話](https://note.com/1013m_masa/n/nafb5dd6a87b3)

## GitHub Pages の作成
[GitHub Learning Lab](https://lab.github.com/) の Learn GitHub with GitHub セクション内の [GitHub Pages](https://lab.github.com/githubtraining/github-pages) からスタートします．
![Screen Shot 2019-12-31 at 7.40.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168437/5a7c48b1-588c-166c-fbdd-fb191f8eb40a.png)

コースの項目は7項目で，読み飛ばしていけば10分ほどで終了します．
![Screen Shot 2019-12-31 at 7.45.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168437/e7606bb3-22c3-cfd0-294d-74f2566a7881.png)

内容は以下の3つです．
1. GitHub Pages を有効化
2. ページのテンプレート ([Jekyll](https://jekyllrb.com/)) の複製（複製は自動）
3. テンプレートの編集

GitHub Pages の作成方法は GitHub Learning Lab に従ってできるので省略し，補足をしておきます．

## GitHub Learning Lab を使って GitHub Pages を作る際の注意点
- URL の変更（任意）  
デフォルトでは，レポジトリ名が github-pages-with-jekyll になっており，サイトの URL が 
`http(s)://github.com/%ユーザ名%/github-pages-with-jekyll/`になってしまいます．  
ページ作成が完了したら，Settings の Repository name を以下のように
`%ユーザ名%.github.io`に変更してください．
![Screen Shot 2019-12-31 at 7.59.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168437/bb7ea629-2463-ab75-0a33-10a3d8ecd1dc.png)

これで，サイトの URL が `http(s)://%ユーザ名%.github.io` となります．

- 誤作動が起こったら  
途中で誤った操作をして，bot が正常に作動してくれないことがありました．その場合は一度レポジトリを削除してやり直しました．（もっといい方法があるかもしれません）
[GitHub Pages](https://lab.github.com/githubtraining/github-pages) に戻って Leave Course を押すと，ポップアップが出てきます．そのポップアップ内のレポジトリを削除するかどうかのチェックボックスをオンにすることでレポジトリを削除できます．
![Screen Shot 2019-12-31 at 8.11.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168437/355e76ea-cf5a-8981-ec50-0ad8416e7d89.png)

- テーマの変更
Settings > GitHub Pages > Theme Chooser から変更できます．
![Screen Shot 2019-12-31 at 8.16.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168437/c9550aea-a556-7d37-a917-75aa1634cc5b.png)

## サイトのベースが完成
味付けはこれから．
![Screen Shot 2019-12-31 at 8.28.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168437/ff78f5e6-0027-1f61-9d8f-141761af8f8b.png)
API側の設定[Google]

###下記URLへ飛ぶ(googleアカウント未取得の場合は作成してください）
[Google Crome Platform](https://console.cloud.google.com/projectselector2/apis/credentials?supportedpurview=project)

**1.チェックを入れ同意**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/47ff840b-f381-f16e-01a4-90c458848a7e.png)

**2.プロジェクト選択**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/187679ff-5224-39d5-211c-4199ae793894.png)
この画面が開いたら`新しいプロジェクト`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/4d1466c8-f5f5-093e-1b88-c84c86496a74.png)

**3.任意のプロジェクト名を入力**（画像撮り忘れました）
`プロジェクト名`に入力したら`作成`をクリック

**4.OAuth同意**
`認証ページ`で`同意画面構成`を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/148083e7-25d2-f1d5-dbdb-b51ccee18c48.png)
この画面が出たら`作成`を押し次の画面へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/5dda9a50-129c-a080-5d6b-1bfdcf3351c0.png)
`アプリケーション名`を入力して`保存`

**5.OAuthクライアントID設定**
①→②の順に選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/2d011c05-a376-4ebb-b4e7-ee6b814f926a.png)
上の選択すると出てくる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/4b051e00-9c7f-bbd9-27af-ae29248ca514.png)

`クライアントID`と`クライアントシークレット`がそれぞれ表示されるので
コピーしてメモ帳などに保存しておく

**6.Google+ APIを有効にする**
ライブラリの選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/da00ad1a-cdc8-a340-e2fb-ddcf09a17e6d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/ec53cb96-85be-2daf-226e-87b9a1b941b3.png)
有効にしたら完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540209/f5dc95e3-7ad8-9b0a-7d1f-63774c539a84.png)