OmniAICreator/Qiita-1.07M huggingface dataset:
【Android/Kotlin】sqliteを使う基本

#やりたいこと
　今回はデータベースを作ったり、クエリを送るメソッドを紹介します。

###openOrCreateDatabase
　引数にDB名、動作モード（0かPrivate）、カーソルをインスタンス化させるファクトリクラスを渡すことで、それらに則ったDBが作られる。以下の例では、sqlite-test-1というデータベースを作っています。データーベースは`data/data/パッケージ名/database`というディレクトリに作られ、ターミナルから操作することも可能。

```
val database = baseContext.openOrCreateDatabase("sqlite-test-1.db", Context.MODE_PRIVATE, null)　//databaseはsqlite-test-1.dbというDBが定義された
```

###クエリをDBに送る

execSQL メソッドを使えば、簡単にクエリを送ることが出来る。しかし、全てのクエリをexecSQL で送れるという訳ではなく、SELECT / INSERT / UPDATE / DELETE対しては使うことが出来ない。テーブルの作成や削除、セーブに適したメソッド。
リファレンスに細かなことが書いてあります。：https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase#execSQL(java.lang.String,%2520java.lang.Object%5B%5D)

```
var sql = "create table if not exists contacts(_id integer primary key not null, name text, phone integer, email text)"
database.execSQL(sql)
database.execSQL("drop table if exists contacts")

```

###INSERT文

　以下のように、ContentValues()内でカラムに対応するレコードを詰めてINSERT文書く。insertというメソッドは、引数にテーブル名、nullColumnHackというテーブルにnullを挿入するか否かを指定するパラメータ、ContentValue()をとって、テーブルに新たなレコードを挿入する。非常に簡単に行えることが分かる。

```
val values = ContentValues().apply {
            put("name", "Fred")
            put("phone", 12345)
            put("email", "fred@nurk.com")
        }
﻿
        //applyの有無での比較↑↓
//        val values = ContentValues()
//        values.put("name", "Fred")
//        values.put("phone", 12345)
//        values.put("email", "fred@nurk.com")
﻿
val generatedId = database.insert("contacts", null, values)
```

###カーソル

　テーブルを読み込むときに使う。一行ずつカーソルがテーブルを読み取ることで効率的にデータを収集することが出来る。例えば、一気にDBのデータを呼び出したりしてしまうと、デバイスのメモリが死ぬ。しかし、カーソルを使うことでそれを防げる。以下ではSELECT文と一緒に使っている。

```
val query = database.rawQuery("select * from contacts", null)
query.use {
     while (it.moveToNext()) { //カーソルが次のレコードに移動する。何もないならfalseを返す。
     //全てのレコードを循環する
                with(it) {
                    val id = getLong(0)
                    val name = getString(1)
                    val phone = getInt(2)
                    val email = getString(3)
                    val result = "ID: $id, Name = $name, phone = $phone, email = $email"
                }
            }
        }
```
﻿ここでは何を行っているかというと、`rawQuery`メソッドを使ってセレクト文の結果を取得しています。`rawQuery`メソッドはセレクト文等の結果が返されるクエリに対して用いるメソッドです。そして、そのクエリの結果をwhile文を通して一行ずつ取得しています。これが上で説明したカーソルです。

これらのメソッドを使う事で、おおよそのクエリをアンドロイド上で使うことが出来ます。
pythonでSQL使ってみた エピソードⅡ :  データの横結合 left join inner join 

SQLを用いたデータのハンドリング
pythonでSQLを使うシリーズ2

※以下はgroup byの紹介
https://qiita.com/saspy/items/2b5aeef91e87cac503e2

SAS/Rのデータの結合比較
https://qiita.com/saspy/items/43b4c368d22f45f023a2

今回はleft joinなどデータの結合を紹介

# 準備
```python
import pandas as pd
import dask.dataframe as dd
from pandasql import sqldf
import sqlite3

Data1 <- dd.read_csv( "パス/ファイル名" )
Data2 <- dd.read_csv( "パス/ファイル名" )
```

Data1とData2を横結合する

# pandasql sqldf
```python
query = """
  select A.変数1 , A.変数2 , B.変数1 , ...
  from Data1 as A
  left join Data2 as B
  結合条件on A.キー変数1 = B.キー変数1 and A.キー変数2 = B.キー変数2 ...
  order by A.変数1 , A.変数2 , ...;
"""
Data = sqldf( query , locals() )
```

left joinをinner joinに変えれば、左結合から内部結合へ修正可能
right joinやfull joinにするとエラーが出た
Rのsqldfと同様、left joinとinner joinだけなのかも...

# SQLite3 read_sql_query
```python
conn = sqlite3.connect( "" )
# db残したいor既存のを使用するなら"パス/db名.db"と指定

# data.frameをSQL化(dbにすでに格納されているなら不要)
Data1.to_sql( "Data1_Sql" , conn )
Data2.to_sql( "Data2_Sql" , conn )

query = """
  select A.変数1 , A.変数2 , B.変数1 , ...
  from Data1_Sql as A
  left join Data2_Sql as B
  結合条件on A.キー変数1 = B.キー変数1 and A.キー変数2 = B.キー変数2 ...
  order by A.変数1 , A.変数2 , ...
"""
# ;なし
Data = pd.read_sql_query( sql = query , con = conn )

conn.close()
```

left joinをinner joinに変えれば、左結合から内部結合へ修正可能
また、こっちでもright joinやfull joinを使うと以下のエラーが出た
RIGHT and FULL OUTER JOINs are not currently supported

まぁrightは使わない気もするが
Rのsqldfやpythonのsqldf、read_sql_queryではfull joinは使えないようだ
ダミーデータ作ってleft joinするか、別のパッケージ使うしかないかな

# daskやpandasによるmerge
```python
DATA = dd.merge( Data1 , Data2 , on = [ "キー変数1" , "キー変数2" , ... ] , how = "left" )

# pandasならddをpdにする
```

こちらもhow = "left"をrightやinner,outerへ変更可能
機械学習を実務で用いるための工程

#はじめに
機械学習を実務で使う場合に、どのような工程を踏むのか、自分の頭の中の整理をかねて大枠を書いていければと思います。


文章ばかりで見づらいと思いますが、自分の頭の整理をかねて投稿します。



##データサイエンスの流れ

* [分析目的の明確化](#分析目的の明確化)
* [データの準備](#データの準備)
* [分析](#分析)
* [ビジネスインパクトの評価](#ビジネスインパクトの評価)
* 5. 運用






##分析目的の明確化

ビジネスゴールから分析ゴールへの翻訳
「売上向上」がビジネス課題であれば、売上について細かく分解します。
分解方法はロジックツリー、カスタマージャーニーなど、
#####ポイント
会社が何かしら打ち手を講じる事で、影響を与えられるように分解する事。
会社にどうしようもできない分解を行っても意味がありません。

例：「プラスチックストローの売上が減少している。向上させたい。」
↓
分解：社会のニーズ×購入率
↓
打ち手：「社会のニーズ向上を目指せば、売上が伸びるのではないか？」

一企業で社会の環境意識を後退させようとしても、できる事が限られています。




##データの準備
データを１から作成する場合
#####ポイント
データセットを自分で作成する場合、どんなデータを用意するかは**人間が決めなくてはいけません。**
データサイエンティストの**ビジネス課題の理解力・想像力・観察眼・仮説力**が問われます。
そのためにも、ビジネス課題を分析目標に落とし込む作業が重要となります。

（この過程を実務でゴリゴリ経験積んでいる人は、今後とても強いだろうなあ・・・）

###データの前処理の流れ
1. データの読み込み
2. 欠損の確認
3. 分布の理解
4. 要約統計量の確認
5. 特徴量の設計

2~3の工程は順不同

#####要約統計量とは・・・？
値の平均値・中央値・最小値・最大値など
pandasでは下記で確認

```ruby:python
dataset.descride()
```
#####特徴量の設計
ダミー変数
Feature Engineerring（特徴量の組み合わせを自身で作成）




##分析
統計学と機械学習は分析ステップで用います。

####統計学

- 特徴や構造を理解
- 因果関係を検証
- 影響度を推定

####機械学習

- 予測（教師あり学習）・・・・・回帰問題/分類問題
- クラスタリング（教師なし学習）


##教師あり学習の流れ

1. 特徴量（説明変数）を用意
2. 機外学習モデルに特徴量を食わせる
3. 予測結果の算出（predict)
4. 予測結果と（答え）目的変数の残差を計算する（残差を目的関数という）
5. 目的関数が最小となるよう、モデルの更新
6. 予測したい新しいデータに、最適化された機械学習モデルを食わせる
7. 予測結果のアウトプット

2~5の工程を、機械学習モデルに**学習させる**といわれています。


##予測モデルの構築プロセス
1. データの準備
2. データの前処理
3. モデルの構築
4. モデルの性能評価

####ポイント
- 特徴量の選択
- 用いる機械学習アルゴリズムの選択
- 精度指標の選択

この工程を何度も繰り返し行う必要があります。


##ビジネスインパクトの評価

精度を追求する場合、
外れ値に強い・弱い場合,
金額予測の場合、誤差の下振れを減らしたい場合など、
評価方法も、分析目的によって変わっていきます。

#####主な精度指標（ほんの一部です）

<dl>
  <dt>回帰</dt>
  <dd>MSE</dd>
  <dd>RMSE</dd>
  <dd>MAE</dd>
  <dt>分類</dt>
  <dd>AUC</dd>
  <dd>Logloss</dd>
  <dd>混同行列</dd>
  <dd>Precision</dd>
  <dd>Recall</dd>
  <dd>F1_score</dd>
  <dd>AUC</dd>
</dl>
CocosCreator の Lifecycle Callback

#CocosCreator の Lifecycle Callback

CocosCreatorでスクリプト書いた時の勉強メモ。意外とこの手の記事少ない気がしたので

参考 : [Lifecycle Callback・Cocos Creator / 公式のドキュメント] (https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html)

- **onLoad()** :  初期化時、シーン作成時など、scriptが初期化されるタイミング
- **start()** : 最初のupdate()が実行される前
- **update()**  : フレームごと
- **lateUpdate()** : 全部のupdateが終わった最後に
- **onEnable()** : falseからtrueになったとき
- **onDisable()** : trueからfalseになった時
- **onDestroy()** :  destroy()が呼び出された時


##Tips　(参考URLのTipsをDeepLに投げただけ。実行順序について）
コンポーネントの初期化から活性化、最終的な破棄までのライフサイクル関数の実行順序は、onLoad -> onEnable -> start -> update -> lateUpdate -> onDisable -> onDestroyとなります。

ここで、onLoadとstartはコンポーネントの初期化に使われることが多く、ノードがactiveInHierarchyになったときに一度だけ実行されます。上記の内容と実行順序の違いに加えて、以下のような違いがあります。
(参考URLのTipsをDeepLに投げただけ。実行順序について）
Googleフォームとスプレッドシートで集めるテストレポートでのユーザー識別

# 前提
- クローズドβテストなど、あらかじめユーザーが特定されているものとします。
    - ユーザーはメールアドレスで識別しているものとします。
- 以下についてはこの記事では扱いません。
    - Googleフォームの基本的な使い方 ⇒ [公式ヘルプ](https://support.google.com/docs/topic/9055404?hl=ja&ref_topic=1382883)
    - Googleスプレッドシートの基本的な使い方 ⇒ [公式ヘルプ](https://support.google.com/docs/topic/9054603?hl=ja&ref_topic=1382883)
    - テストレポートの内容 ⇒ [参考記事](https://qiita.com/tetr4lab/items/c558de2cc26324930ba9)

# やりたいこと
- ユーザーにGoogleフォームでレポートを送って貰い、Googleスプレッドシートで集計する
- レポートを送る際には、メールアドレスを含め個人情報を入力させたくないが、レポートを送ったユーザーを特定したい

# 準備
### フォーム
- レポート用のフォームを用意し、中にUUIDフィールドを設けます。
- 「事前入力したURLを取得」する機能を用いて、UUIDに事前入力するためのURLを取得します。
    - URLは次のようなフォーマットになっています。`https://docs.google.com/forms/d/e/《form id》/viewform?usp=pp_url&entry.《field id》=《value》`
- フォームを送信すると、後述のスプレッドシートに届くように設定します。

### スプレッドシート
- 前述のフォームから送られた情報が集計されるタブを用意します。
    - 試しに一件レポート送信しておきます。
- ユーザーの個人情報は、別のタブにまとめられているものとします。
    - UUID列を用意して、全ユーザーに対してユニークな識別子を発行しておきます。
    - フォーム通知URL列を用意して、上記で得たフォームの事前入力URLにUUIDを埋め込んだユーザー別URLを送信するmailtoリンクを生成します。(mailtoにすることは必須ではありません。)
        - `mailto:《e-mail address》?subject=《subject》&body=《body》`
- 集計タブの未使用の列に、ユーザータブからvlookupでUUIDをスキャンして得たユーザーの識別名などを表示するように計算式を設定します。

# 運用
- 前述のmailtoリンクからユーザー毎に「テストよろしく、なお、レポートはこちらから」案内メールを送ります。(通知方は他にも様々に考えられます。)
- ユーザーからレポートが届くと集計タブの行が増えるので、計算式の含まれる列に対して上の行からコピーします。

# 課題
- 集計タブの新規行に対して自動的に計算式をコピーすることができれば良いのですが…。
discord.pyで管理者を判定する

discordでは、サーバを作った人が管理者になります
その管理者かどうかを判定する方法です

```python
@client.event
async def on_message(message):
# テキストチャンネルのみ処理    
    if message.channel.type != discord.ChannelType.text:
        return

# 管理者のときのみエコーする
    if message.author.guild_permissions.administrator:
        await message.channel.send(message.contents)
```

一応注意として、message.authorがMemberでないといけません
例えば、プライベートチャンネル(DM)だと、Memberではないので、
上の例ではテキストチャンネル限定としています
Laravel ルーティング情報を表示してくれるコマンド

# 目的

- すでに定義されているルーティング情報の一覧を出力するコマンドを忘れない様に書き留める。

# 紹介

- 下記コマンドをLaravelアプリ名ディレクトリに移動してから実行する。

    ```terminal
    $ php artisan route:list
    ```
railsのmigration fileが外部キーでdown出来ない時の対処法

ruby 2.6.6
rails 6.0.3
catalina 10.15.5

railsのmigration fileが外部キーでdown出来ない時の対処法がググってもあまり情報が出て来なかったので、後学のために。
要らないmigration fileを削除したく以下コマンド叩く。

```
$ rails db:migrate:down VERTION=migration_file_id
```

すると下記エラー

```
Mysql2::Error: Cannot drop table 'stores' referenced by a foreign key constraint
```
エラーメッセージに外部キーと書いてあるので、まずは無効化。の前にdatabase選択
以下コマンド後、少し解説

```
mysql> show databases;
```

```
mysql> use database名;
```

```
# 外部キー無効化
mysql> set foreign_key_checks = 0;
```

```
mysql> show tables;
```

```
mysql> select * from schema_migrations;
```
```
mysql> select * from schema_migrations where version = 'migration_file_id';
```

```
mysql> delete  from schema_migrations where version = 'migration_file_id';
```


```
mysql> select * from schema_migrations;
```

```
$ rails db:migrate:status
```

```
$ rails db:rollback
```
ここまでコマンドのみ

### 以下解説
```
mysql> select * from schema_migrations;
+----------------+
| version        |
+----------------+
| 20200714085643 |
| 20200715061816 |
+----------------+
2 rows in set (0.00 sec)
```
消したいのはこれ　→　20200714085643

```
mysql> select * from schema_migrations where version = '20200714085643';
+----------------+
| version        |
+----------------+
| 20200714085643 |
+----------------+
1 row in set (0.00 sec)
```

```
mysql> delete  from schema_migrations where version = '20200714085643';
Query OK, 1 row affected (0.00 sec)
```

```
mysql> select * from schema_migrations;
+----------------+
| version        |
+----------------+
| 20200715061816 |
+----------------+
1 row in set (0.01 sec)
# 20200714085643が消えた
```

```
# 外部キー有効化
mysql> set foreign_key_checks = 1;
```

```
# 最新のマイグレーションファイルのバージョンが指定データベースのschema_migrationsテーブルから削除される
$ rails db:rollback
```

downしたいファイルが複数ある場合は下記コマンド

```
# 5つのマイグレーションファイルをロールバックしたい時
$ rails db:rollback STEP=5
```
これでrails db:migrate:statusすればdownになっているはず。
祝！藤井聡太新棋聖 持ち時間が長い方が強いってホント？

藤井棋聖は、将棋では不利とされる後手番が非常に多いにも関わらず、高い勝率を残していることを前回の記事で書きました。**今回の記事では、持ち時間と勝率の関係を調べてみます**。

●持ち時間と勝率の関係
将棋では、棋戦ごとに持ち時間が決められています。例えば棋聖獲得後に菅井八段に勝利した将棋日本シリーズ（予選）は持ち時間10分の早指し戦ですし、棋聖戦（本戦以降）は4時間、現在タイトル挑戦中である王位戦（タイトル戦）は2日制の合計8時間です。棋戦ごとに持ち時間が異なるので棋士は柔軟な対応を求められます。

最近の藤井棋聖の将棋は、中盤長考するケースが良く見られ、持ち時間をフルに使う将棋を指されています。一方、非公式の早指し戦で2回連続して優勝するといった早指しの能力にも定評があります。

以下は、藤井棋聖が2020年7月18日までに対戦した公式戦(218試合)について、持ち時間の勝ち負けの関係を示したモザイク図です。（モザイク図の見方は、前回の記事で説明しています。）
<img width="500" alt="pic1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/52594223-4eee-05d1-00c2-c3cb7614cd5d.png">
全218試合の勝率は84.4%です。モザイク図をみると、この勝率より高いのは持ち時間が5時間と6時間以上のときになります。特に6時間以上のときは1敗しかしておらず、勝率は97.1%と驚異的です。この結果より、藤井棋聖は持ち時間が長いほど、強さを発揮すると考えても良いのでしょうか？

ここに**統計の結果だけで考えて解釈するときの落とし穴があります**。

藤井棋聖が今までに対局した6時間以上の棋戦を挙げてみます。

6時間：順位戦　32試合
8時間：王位戦（タイトル戦） 2試合

そう、ほとんどが順位戦なのです。順位戦は5つのクラスに分けて行われ、現在藤井棋聖はB級2組と上から3番目のグループに属しています。そのためこの順位戦では、上のグループであるA級やB級1組に属している強い棋士とは戦っていないのです。藤井棋聖の実力からすると、格下と見られる相手と多く対局しているので勝率が高くなっていると考えることもできます。

または、6時間の長い持ち時間でじっくり考えられるので勝率が高いとも考えられますし、"格下の相手"、"じっくり考えられる"のどちらの要素も影響しているのかもしれません。

持ち時間の違いで、勝率に差があるかどうかを調べるために、Pearsonのカイ2乗検定を実施した結果を示します。
<img width="300" alt="pic2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/69929ad8-07a9-75ee-8cf5-a5d4658320ae.png">
p値が小さいほど帰無仮説　”持ち時間の違いによって、勝率に差がない” を棄却し、持ち時間の違いで勝率に差がある といった結論が導けますが、Pearsonのカイ2乗検定は0.2577となり、通常考える有意水準0.05より大きくなっていますので、帰無仮説を棄却できません。

モザイク図の割合を見る限り、持ち時間6時間以上で、他の持ち時間より勝率が上がっていますが、有意な差ではないといった考察になります。

今後藤井棋聖がタイトル戦に多く出場すれば、持ち時間の長い将棋で対局する機会が増えるかと思います。持ち時間が長い方が強みを発揮するかどうかは、もっと対局が増えた後に考察が必要でしょう。

●持ち時間と勝率の関係を”先手/後手” で分けてみると
持ち時間と勝率の関係を、さらに”先手/後手”で分けて見てみましょう。

統計的には、"持ち時間"と"先手/後手"の交互作用が勝率に影響しているのかを見ていることになります。

下図は、横軸に持ち時間、縦軸に勝率をプロットした折れ線グラフで、赤色が先手、青色が後手を示します。
<img width="550" alt="pic3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417820/e879be4f-bbc7-63ec-e02d-e2feddffa8bc.png">
少し興味深い結果になっています。持ち時間3時間までは先手の勝率が後手の勝率に対し差が大きいですが、4時間、5時間と徐々に差が小さくなり、6時間以上だと逆転します。ご覧の通り、6時間以上の後手の勝率は100%であり、一度も負けていないのです。

先ほども記載した通り**将棋は後手が不利なゲームですが、藤井棋聖は長い持ち時間を活かし、この不利さを解消しているのかもしれません**。

きちんと検証するにはもっと多くのデータがあった方が良いですし、他の棋士との比較もあった方が良いですので、今後もデータを収集し、何か面白い結果をお知らせできればと考えています。

今後、藤井棋聖の持ち時間の長い後手番の対局に注目です！

■さあ始めよう！
JMPの全機能を30日間試せるトライアル版で、データからさらなる情報を導き出せることを実感してください。
さあ始めましょう。

ダウンロードは[**コチラ！**](https://www.jmp.com/ja_jp/download-jmp-free-trial.html?utm_campaign=td7013Z000002sEGsQAM&utm_source=JMPblog&utm_medium=)

■JMPについて
JMP（ジャンプ）は世界中のエンジニア、データアナリストに選ばれているインタラクティブで可視的なデータ分析ツールです。

＜ SNSで様々な情報をお届けしています ＞
[Facebook](https://www.facebook.com/JMPjpn)
[Twitter](https://twitter.com/JMP_Japan)
VSCode の Live Server で文字コード Shift_JIS が文字化けしてしまう

VSCode の Live Server で、文字コード Shift_JIS のファイルを開くと文字化けしてしまいます。

Live Server で Shift_JIS は使えないようなので node-static をインストールします。

```
npm install node-static -g
```

任意のディレクトリで node-static を起動します。

```
static
serving "." at http://127.0.0.1:8080
```

http://127.0.0.1:8080
にアクセスして任意のファイルを表示させます。
Azure IoT Hub で Kafka Endpointが使えなかっただけの話


タイトルの通りAzure IoT HubにKafkaクライアントからアクセスできるか確認して出来なかったという話。読む価値はないと思うけどメモ用に公開。

Event HubがKafka EndpointをサポートしたのでラッパーであるIoT Hubでも使えるだろうと予想して試してみた。結果から言うとNG。そもそもKafkaはメッセージングシステムでAzureの中ではEvent Hubが一番近いしIoT Hubのようにデバイス管理等の機能は提供しない。そのため、主に既存のKafka クライアントをターゲットとした場合Event Hubで対応するだけで十分なのかもしれない。


IoT Hub への接続確認はEvent Hubの[記事](![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33998/1b736fdb-8671-b775-aa4c-ac6fb5e3e773.png)
)を参考にした。ちなみにEvent HubにKafkaクライアントからアクセスしたらサクッとつながった。

IoT Hub 作って Event Hub-Compatible endpointにアクセス。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33998/7665ef34-9ec1-d150-eadc-4b86f355c9dc.png)

Azure Event Hubs for Kafka repositoryをクローンして **\azure-event-hubs-for-kafka-master\quickstart\java\producer\src\main\resources\producer.config** と**consumer\src\main\resources\producer.config**を書き換え。

```
bootstrap.servers=NAMESPACENAME.servicebus.windows.net:9093
security.protocol=SASL_SSL
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="$ConnectionString" password="{YOUR.EVENTHUBS.CONNECTION.STRING}";
```

ちなみにKafkaのTopicにあたるものはEvent Hubである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33998/ed0bf6c4-56bc-ce93-e8ad-78da2f94d0e1.png)

TestProducer.javaのTopicをEvent Hub-compatible nameとおきかえる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33998/35fd35a7-21be-5437-071c-22015b595c1a.png)
]


```
public class TestProducer {
    //Change constant to send messages to the desired topic, for this example we use 'test'
    private final static String TOPIC = "xxxx-iotoh-hub";
```

***kafka\azure-event-hubs-for-kafka-master\quickstart\java\producer***に移動して次のコマンドを実行

```
mvn clean package
mvn exec:java -Dexec.mainClass="TestProducer"
```

Windows 10環境でPower Shellを使うと以下のエラーが発生した。コマンドプロンプトに切り替えたら解決した。

```
[ERROR] Unknown lifecycle phase ".mainClass=TestProducer". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>. Available lifecycle phases are: validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy, pre-clean, clean, post-clean, pre-site, site, post-site, site-deploy. -> [Help 1]
```

解決したけど次に認証エラーが発生。Kafkaのポートは空いているが強い権限を与えても問題を解決できなかった。（もし成功した方がいらっしゃればコメントください）

```
Finished sending 100 messages from thread #14!
org.apache.kafka.common.errors.TopicAuthorizationException: Not authorized to access topics: [upskill-iotoh-hub]
```

ちなみにIoT HubのEndpointにアクセスを試みるとTime Outが発生。

```
org.apache.kafka.common.errors.TimeoutException: Failed to update metadata after 60000 ms.
```

コマンドで確認してもkafkaポートは閉じていた。

Test-NetConnection -ComputerName xxxx.azure-devices.net -Port 9093
【C#】荒い画像からQRコード読み取り

初投稿です。

以下の記事を参考にQRコード読み取りの案件があったので、実装しました。
[【ZXing.Net】C#でQRコードの読取](https://qiita.com/satorimon/items/7b7b70410398ee6fd1a4)

ぼやけたQRコードや、少し斜めったQRコードも読み取れるように改造した内容です。

実装途中、以下のようなメモリリークしたり、画像ファイルのアクセス不正とかで嵌ったので、メモとして残しました。
[OpenCvSharp で Mat を返すメソッドを使うとメモリリークで死ぬ件](https://blog.mohyo.net/2015/03/1313/)

## Nugetパッケージのインストール
Nugetで「OpenCvSharp3」と「Zxing.Net」をインストールします。
![nuget.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572933/7e0bced7-ed53-7938-a55e-471564d1bc24.png)


## コード


        public void qrRead(string filename)
        {
            //filename:画像ファイルパス(例：c:\\gazo.jpg)

            /// 画像フィルタリングのフィルタ値
            /// この値を上げると精度が上がっていくが、処理時間も増加する。
            /// ※適宜変更してください。
            const int maxFilterSize = 10;

            //画像ファイルをBitmapに変換
            System.Drawing.Image image = System.Drawing.Image.FromFile(filename);
            Bitmap myBitmap = new Bitmap(image);
            string data = string.Empty;

            //Mat形式に変換
            using (Mat imageMat = OpenCvSharp.Extensions.BitmapConverter.ToMat(myBitmap))
            {

                // QRコードの解析クラス
                ZXing.BarcodeReader reader = new ZXing.BarcodeReader();

                //画像フィルタリングのフィルタ値まで、ループ
                for (int i = 0; i < maxFilterSize; i++)
                {
                    //奇数にする必要があるので、さらに加算
                    i++;

                    //偶数を指定するとExceptionが発生するので注意。
                    int filterSize = i;

                    //別変数のMATにとる
                    using (Mat imageMatFilter = imageMat.GaussianBlur(new OpenCvSharp.Size(filterSize, filterSize), 0))
                    {
                        //ビットマップに戻す
                        using (Bitmap filterResult = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(imageMatFilter))
                        {
                            //QRコードの解析
                            ZXing.Result result = reader.Decode(filterResult);
                            if (result != null)
                            {
                                //変数に退避
                                data = result.Text;
                            }
                        }
                    }

                    if (!string.IsNullOrEmpty(data))
                    {
                        Console.WriteLine(data);　//読み取り内容を出力
                        return;
                    }
                }
            }

            Console.WriteLine("読み取れない！");

        }
    }

このメソッド単体で動くはず。
読み取り精度を上げたい場合は、「maxFilterSize 」の値を増やすといい感じだけども、処理時間も増える。。
rails6 webpacker4 を本番環境で起動する

[github]
https://github.com/uechikohei/SkateSpotSearch

```[docker-compose-pro.yml]ファイルを使用してproduction環境で起動
docker-compose -f docker-compose-pro.yml up --build
```

```webpackerでビルド
docker-compose -f docker-compose-pro.yml run app bash bin/webpack
```

```コンテナを一度落とす。たまにwebpackerでビルドしたファイルが適用されないことがあるため
docker-compose down
```

```再起動
docker-compose -f docker-compose-pro.yml up
```
【python】 引数展開 リストの各要素を引数として渡す

# リストやタプルの各要素を関数の引数として渡す

リスト自体ではなく、リストの要素を一つずつ関数の引数として渡したいとき、
引数の展開「\*」を使えば、リストを分解したり添え字をつけたりせず扱うことができます。
（この操作はアンパックとも呼ぶようです。[^1]）

例えば、下にある数列$l$の先頭5つ分の要素を半角スペースで繋いで1行で表示したいときは
次のようにできます。

```python
l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 期待する出力: 0 1 2 3 4

print(l[:5])                            # 出力結果: [0, 1, 2, 3, 4]
print(l[0], l[1], l[2], l[3], l[4])     # 出力結果: 0 1 2 3 4
print(' '.join(list(map(str, l[:5]))))  # 出力結果: 0 1 2 3 4

# ---
print(*l[:5])                           # 出力結果: 0 1 2 3 4
```

このように、引数のリストやタプルの先頭に「*」を付けることで、
その各要素を各引数として渡せます。

## その他

引数の展開「\*」は可変長引数「\*」と似ていますが、少し違うものです。

ちなみに、辞書型については「**」を付けることで似たようなことができます。[^2]


[^1]: [くろのて](https://note.crohaco.net/2014/python-argument-intro/#unpack-arguments)
[^2]: [note.nkmk.me](https://note.nkmk.me/python-argument-expand/)
動画の再生時間（HH:MM:SS）を秒数にしたいし、その逆もしたい

# HH:MM:SSを秒に

```rb
# rails c または以下をrequire
require "active_support/duration"

duration_text = "00:01:00"
Time.parse(duration_text) - Time.parse("00:00:00") # => 60.0
```

# 秒をHH:MM:SSに

```rb
Time.at(60).utc.strftime("%H:%M:%S") # => "00:01:00"
```
Firebase 匿名認証の永続性を変更して、ずっと匿名でのログイン状態にする

#はじめに
Firebaseの匿名認証については下の記事を参考に。
[Firebase 匿名認証でログインしたユーザーか判別する方法](https://qiita.com/kokogento/items/43589d65bcd321b20b63)

この記事ではFirebase 匿名認証でログインしたユーザーを**永続的にログイン状態にする方法**を記録する。

#環境
・[Ioinc](https://ionicframework.com)で開発したモバイルアプリ
・Angularと[angularfire](https://github.com/angular/angularfire)
・シミュレーターと実機でテスト

#Firebase 匿名認証の永続性
>Firebase JS SDK を使用すれば、認証状態をどの程度維持するかを指定できます。たとえば、ログインしたユーザーが明示的にログアウトするまで無期限に維持したり、ウィンドウを閉じたときやページをリロードしたときにクリアしたりできます。

[認証状態の永続性](https://firebase.google.com/docs/auth/web/auth-state-persistence?hl=ja#supported_types_of_auth_state_persistence)

「永続性」ってなんか難しい言葉使ってるけど、**ログイン状態がどの程度保持されるか**、と同じ意味で問題ないかと。

Firebaseの匿名認証では、何も設定していないといつ認証状態が消えるのか（僕には）わかりません。。
ブラウザでの感覚は１日経ってまた匿名認証でログインすると、新しい匿名アカウントになってた。１日以内なら、何度も匿名認証でログインしても同一の匿名アカウントだった。

#`setPersistence`で永続性を変更できる

```typescript:auth.service.ts
import * as firebase from 'firebase/app';
import { AngularFireAuth } from '@angular/fire/auth';
import { NativeStorage } from '@ionic-native/native-storage/ngx';
import { Router } from '@angular/router';


@Injectable({
  providedIn: 'root'
})
export class AuthService {
  anoUser = null;

 constructor(
    private afAuth: AngularFireAuth,
    private nativeStorage: NativeStorage,
    private router: Router,
  ) {
  }


anonLogin() {
    this.afAuth.auth.signInAnonymously().then((res) => {
      this.anoUser = res.user;
      console.log('匿名認証した。uidはこちら ' + this.anoUser.uid);
// Persistence.LOCALで永続的にログイン状態にする
      this.afAuth.auth.setPersistence(firebase.auth.Auth.Persistence.LOCAL);
      this.nativeStorage.setItem('user_data', {
        uid: res.user.uid,
      });
      this.router.navigateByUrl('/home');
    });
  }

}
```

```typescript:signup.page.ts
import { Component, OnInit } from '@angular/core';
import { AuthService } from './auth.service';

@Component({
  selector: 'app-signup',
  templateUrl: './signup.page.html',
  styleUrls: ['./signup.page.scss']
})
export class SignupPage implements OnInit {

constructor(
    private authService: AuthService,
  ) {
  }

  ngOnInit() {}

anonLogin() {
    this.authService.anonLogin();
  }

}
```

`Persistence.LOCAL`で永続的にログイン状態にできるようなので、僕はこちらを使用。

>ブラウザ ウィンドウを閉じたり React Native でアクティビティが破棄されたりした場合でも、状態が維持されることを示します。 この状態をクリアするには、明示的なログアウトが必要です。Firebase Auth のウェブ セッションは単一のホストを生成元とするため、単一のドメインでのみ永続化されることに注意してください。

[サポートされている認証状態の永続性のタイプ](https://firebase.google.com/docs/auth/web/auth-state-persistence?hl=ja#supported_types_of_auth_state_persistence)


Webアプリなんかの場合は`Persistence.SESSION`を使っても良いかも。


#最後に
なんかよくわからんが、正常に匿名認証のログインが無期限に維持されてるっぽいので、、、:smile:
Apache2: VirtualHost で LetsEncrypt を使う

VirtualHost の設定

```text:/etc/apache2/sites-available/virtual_hosts.conf
<VirtualHost *:80>
	ServerName test.example.com
	DocumentRoot /var/www/html/public_test
</VirtualHost>
```


```bash
cd /etc/apache2/sites-enabled
ln -s ../virtual_hosts.conf .
```

Let's Encrypt の設定

```bash
sudo certbot --apache -d test.example.com
```

>/etc/apache2/sites-available/virtual_hosts.conf に変更が加えられます。

```text:/etc/apache2/sites-available/virtual_hosts.conf
<VirtualHost *:80>
	ServerName test.example.com
	DocumentRoot /var/www/html/public_test


RewriteEngine on
RewriteCond %{SERVER_NAME} =test.ekample.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
```

>/etc/apache2/sites-available/virtual_hosts-le-ssl.conf　が作成されます。

>/etc/apache2/sites-enabled/virtual_hosts-le-ssl.conf というシンボリックリンクが作成されます。

ブラウザーで動作の確認
https://test.example.com

参考
[Apache2 で VirtualHost を使う](https://qiita.com/ekzemplaro/items/5520bf4f840e4140cc69)
docker-composeでアプリのコンテナが立ち上がらず困惑しました！というお話

ある日、開発途中のrailsアプリを立ち上げようと

`docker-compose up`

しようとしたら、

```
Cannot start service webpacker: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"./bin/webpack-dev-server\": stat ./bin/webpack-dev-server: no such file or directory": unknown
```
というエラーでて、
アプリのコンテナが、`extend with 0`で落ちました。

その後、エラー文を調べると以下記事を見つけ解決にいたりました！
[docker-compose upしようとしたら「Cannot start service」 - Qiita](https://qiita.com/hanakok/items/6bfcfbb8b7b4df877178)

結果からいうと
以前、gitignoreを編集しているときに
bin/以下ファイルを何を思ったか追加してて、ディレクトリごと削除していたんです。

で、
docker-composeファイル内のcommandで指定している`"bin/webpack-dev-server"`コマンドを実行しようとしても、そもそもdocker-composeでマウントするディレクトリにないですけど！
と注意を受けていた訳でした。

#原因がわかったので、解決
`git log`
でbinファイルを削除してしまったコミットIDを調べる。

`git revert [コミットID]`
コミットを取り消す

`docker-compose up`
無事起動を確認

慢心ですね。
gitignoreの扱いには注意。
XAMPPでLaravelをスタートする方法

参考にさせていただきました：https://qiita.com/moyashimanjyu/items/17ffe537fd37cccf00c0

### Xamppの存在意義
Laravelを使用するときの私にとっては、XamppはMySQLをローカルで使うためのツールである。Webサーバーとしては使わない。

### ブラウザでの確認
~~一番、重要なのはブラウザでの確認方法。
Laravelについている、簡易サーバーは立ち上げなくていいが、XamppのApacheが立ち上がっていることを確認する。~~
1つは、laravelに付いている簡易サーバー経由で見る方法。

```
php artisan serve
```

を打って、http://127.0.0.1:8000にアクセスする。

もう1つは、Xamppのアパッチ経由で見る方法。Xamppのアパッチ経由で見る場合は、
ローカルでの保存先をXampp下のhtdocsに置くこと。
例えば、`C:xampp\htdocs\laravel\{project_name}`のときは、以下のようにアクセスする。
`localhost/laravel/{project_name}/public`でアクセス。
`public`を付け忘れないように。
（もしかしたら、publicリンクをプロジェクト直下に貼ることで、URLからpublicを消すことはできるかも。未実施。）

### 手順
1. VSコードもしくは通常のエクスプローラなどでC:\xampp\htdocs\にLaravelフォルダを作成しておく（もうすでにあればOK）。
2. VSコードで上記のLaravelフォルダを開く
3. VSコードでパワーシェルを開く
4. `composer create-project --prefer-dist laravel/laravel ｛プロジェクト名｝`もしくは、`laravel new {プロジェクト名}`を実行
5. xamppを立ち上げ、アパッチとMYSQLを立ち上げる。
6. MySqlの管理画面で、データベースを作る。
7. .envファイルに以下のようにする

```
DB_CONNECTION=mysql
DB_DATABASE=データベース名
DB_USERNAME=DBユーザー名
DB_PASSWORD=パスワード
```

あとはマイグレーションファイルをつくって、モデルを作って、あとの作業は同じ。
とある学生がゲーム開発してみた＃８（データ消えた話）

#データが消えました。
実はこれも数ヶ月前の話になりますがデータが消えました…
今まで作ってたものが全部なくなりました。
これを気にゲームの形をざっくりと変えて見ることにしてみます。
具体的には、キャラクターの変更（うちの子のバージョンアップ）、UI周りの整備などです。
また、２Dゲームに変更するかも検討します。


今後もぜひよろしくお願いします。
10ヶ月経って、やっとプロダクトをローンチしました！（AskMakers 2.0）

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18699/4e4fd522-ebc6-ed78-6bef-42a7b31c5cb2.png)


こんにちは、カニエです。

現在すごい眠いです。
[Product Hunt](https://www.producthunt.com/posts/askmakers-2-0)に投稿し、徹夜で対応していました（PHのレースは毎日サンフランシスコのタイムゾーンの深夜0時から開始されます。自分が住むバンクーバーはサンフランシスコと同じタイムゾーンなため非常に過酷です）。
（現在240 upvotes!）
<img width="355" alt="Screen Shot 2563-07-20 at 21.35.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18699/a2aa29c2-10d4-531b-57d4-49c9b64b79a9.png">

10ヶ月前に投稿したAskMakersのv2をローンチで来たので、紹介させていただければ幸いです！
海外向けサービスを作りたいと考えている方にご参考になるかもしれません！

前回ローンチはこちら：[個人開発者のためのQuoraを作りたい！「AskMakers」を作りました - Qiita](https://qiita.com/kanye__east/items/fd66f5b2203d26c95be2)

## AskMakersとは

Quora大好きな私が、「個人開発者向けQuoraがほしい」と思い作った、Q&Aサイトです。
Bootstrapping、アイディアの出し方、マーケティングについてなど個人開発者向けなトピックについて質問できます。

より魅力的になるよう、既に成功している開発者の方にも参加していただいています。

## v1と変わった所

### 🛠 スタック変更

Nuxt.jsからNext.jsに変えました。
世界的に見ると、流行は圧倒的にReactなので、長く付き合っていくならReactだよね、と思い
乗り換えました。
それに伴いBulmaからTailwind CSSに切り替えました。Tailwindすごい便利ですよね。

### 🎨 デザイン変更
スタック変更時にほぼフルスクラッチで作り直し、サイトデザインもかなり変わりました。
スタックオーバーフローのUIとか参考にしてます。
<img width="766" alt="Screen Shot 2563-07-20 at 21.20.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18699/a4824666-6e33-046c-44df-0771f264558a.png">

### 🔍 質問検索機能
![search-anime.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18699/a220823d-da82-a3fc-676b-e0fad25ff006.gif)
Algoliaでサクッと。

### 🚀 カテゴリ
投稿サイトはカテゴリ必須ですよね。多分
<img width="386" alt="Screen Shot 2563-07-20 at 02.51.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18699/d28e74db-53bd-0ea5-deff-a2f707d20049.png">

### 💬 回答へのコメント機能
ディカッションとか始まったりしたら嬉しいですよね。感謝を伝える意味でも欲しい機能だなと思いました。

### 📧 メール通知
自分の質問に回答が来たときなどにメールが飛ぶようにしています。
Mailgunを使っています。

## v3も既に考えてます！

次はちゃんとお金を稼げるような機能をつけていく予定です！

ありがとうございました！

## P.S.
Product Huntで投票していただけると大変嬉しいです😭
[AskMakers 2.0 - Ask experienced makers questions💡 | Product Hunt](https://www.producthunt.com/posts/askmakers-2-0)
Firebase iOS SDKをCarthageでアップデート（6.28.0以降）するとエラーになる問題の対応方法

# はじめに
現在、[**Firebase iOS SDK（Crashlytics）をCarthageで管理している**](https://qiita.com/zizi4n5/items/5a4ecbe8bb7ab40a56d4)のですが、**6.28.0以降**にアップデートしたところ、UnitTestや実行時にエラーが発生するようになり、ハマったので対応方法についてまとめました。

```shell
** TEST FAILED **
Testing failed:
Undefined symbol: OBJC_CLASS$_GDTCORUploadPackage
Testing cancelled because the build failed.
```

> Undefined symbol: OBJC_CLASS$_GDTCORUploadPackage

エラーの詳細は以下となります。

```shell
ld: warning: Could not find or use auto-linked framework 'Firebase'
ld: warning: Could not find or use auto-linked framework 'FBLPromises'
Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_GDTCORUploadPackage", referenced from:
      objc-class-ref in GoogleDataTransportCCTSupport(GDTCCTPrioritizer.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```

# 実行環境

| 環境 | バージョン |
|:--|:--|
| macOS Catalina | 10.15.6 |
| Xcode | 11.5.0 |
| Firebase iOS SDK（Crashlytics）|6.28.0以降|

# 原因

[**Firebase iOS Release Notes**](https://firebase.google.com/support/release-notes/)によると、[**Version 6.28.0 - July 14, 2020**](https://firebase.google.com/support/release-notes/ios#version_6280_-_july_14_2020) の修正によって、**GoogleDataTransportCCTSupport.framework**が含まれなくなっており、これが原因でした。

> Updated GoogleUtilities and GoogleDataTransport imports. The GoogleDataTransportCCTSupport dependency should no longer be linked along with Firebase ([#5824](https://github.com/firebase/firebase-ios-sdk/pull/5824)).

DeepL翻訳
> GoogleUtilities と GoogleDataTransport のインポートを更新しました。GoogleDataTransportCCTSupport依存関係がFirebaseと一緒にリンクされなくなりました ([#5824](https://github.com/firebase/firebase-ios-sdk/pull/5824))。

# 対応方法

Xcode projectから、**GoogleDataTransportCCTSupport.framework** を削除して、ビルド＆再実行します。
これで、問題なく動作するようになります。

<img width="696" alt="GoogleDataTransportCCTSupport.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63892/76d77b07-45a7-8e9b-6f7b-aaf53face616.png">

# 参考情報
* [Firebase iOS SDK（Crashlytics）をCarthageで管理する](https://qiita.com/zizi4n5/items/5a4ecbe8bb7ab40a56d4)
* [Firebase iOS Release Notes Version 6.28.0 - July 14, 2020](https://firebase.google.com/support/release-notes/ios#version_6280_-_july_14_2020)
* [Update GoogleUtilities' clients with repo-relative imports #5824](https://github.com/firebase/firebase-ios-sdk/pull/5824)
MotionBoardで予実対比を見てみる（グラフ・集計表）

#最初に
MotionBoardは綺麗でわかりやすいグラフや画面を作ることができます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/04c48011-e65b-88dd-f666-a838819636e4.png" width=60%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/e777e485-f3d0-3dc7-57e2-ddddd2df8860.png" width=60%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/7bc601e7-ace8-cafa-2313-c2d66b9de500.gif" width=60%>
綺麗な上に、動いたりもします。
気になる人は下記リンクをクリックしてください。体験デモもできます。
[MotionBoard　体験デモについて（公式HPより）](https://www.wingarc.com/product/motionboard/demo/index.html)


<details><summary>【MotionBoardとは】</summary><div>
様々なデータソースからデータをあつめ、１つの画面上で統合するMotionBoard。
クラウドサービスとの接続もでき、チャットツール送信もできるのでとてもおもしろいです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657180/877897e8-35d1-b055-a80c-b9051866bc38.png" width=60%>
※キャプチャはウイングアーク1st社のホームページより抜粋
[ウイングアーク１ｓｔ株式会社　MotionBoard](https://www.wingarc.com/product/motionboard/index.html)
</div></details>


##オシャレな予実対比を見てみる

BIの領域に10年以上生息をしていますが、営業職の予算実績の対比というのは
　今期実績
　予算
　前期実績
　見込み
というデータをひとつの表の中に入れて、達成率や前年比を出したりします。

この記事では３つの予実対比のグラフ（集計表）を紹介します。
こちらの作り方の記事は別記事になりますのでご参照くださいませ。




###[コンパクトに予実対比を見る](https://qiita.com/Ryo---san/items/77b2d7772cec6101aedb)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/d234772c-6aaa-1d6a-a975-53b1f5629b39.png" width=15%>
スペースが小さいのですが、見やすい。
目標との予実の乖離がわかります。
　
　




###[大きなグラフで前年実績を含めた年月推移を見る](https://qiita.com/Ryo---san/items/85b78801ec4d71f660c7)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/10f992f4-2bb1-f7b0-8b81-6909ac17208c.png" width=60%>
前年実績をうしろにうっすら出すことで年月推移を前年比較しながら表現しています。
　
　



###[集計表で予実対比を見る](https://qiita.com/Ryo---san/items/b4617bf57b2494290ce4)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657414/fd4d1cfc-bf9c-c460-c3e8-adb9d3e3642d.png" width=60%>
グラフからリレーションさせて、詳細を見るときにもこのような集計表が使えます。
　
　


ぜひMotionBoardのチャート作成のサンプルとしてご覧になってください。
【確率雨量】100年に1度の大雨ってどうやって計算しているの？　―第2回　高瀬法(積率法)―

# 移転のお知らせ

こちらの記事は下記のサイトに移転しました。

> [NNテックブログ](https://nnhiroba.xsrv.jp/nnTechBlog/Article/Article?ID=26)
(CUIでできる)ubuntu18.04でyoutube-dlを使って複数のyoutube動画の自動ダウンロード

# 複数のyoutube動画を自動でダウンロードしてほしい！
所持しているurlから動画を自動でダウンロードする必要が出てきたので書きました。（実行に移すかは別として。）後サーバで勝手にやって欲しいのでCUIで実行できるようにという条件付き。

基本的に使うのはyoutube-dlで、取得動画を任意の形式に変換するのにffmpegを用いているっぽい。まあ結局どっちもインストールする必要がある。

# インストール方法
## ffmpegのインストール

```terminal:terminal
sudo apt update
sudo apt install ffmpeg
```

## youtube-dlのインストール
aptでもインストール可能だが、古いバージョンが入る場合があるので直接wgetしてインストールが無難。
インストール後chmodで実行権限を付与する。

```terminal:terminal
sudo wget https://yt-dl.org/downloads/latest/youtube-dl -O /usr/local/bin/youtube-dl
sudo chmod a+rx /usr/local/bin/youtube-dl
```

# 簡単に使い方説明

## ダウンロード

```terminal:terminal
youtube-dl "欲しい動画のURL" -f mp4
```

## 出来る限り高画質・高音質でダウンロード(mp4でダウンロード出来る場合)(試してない)

```terminal:terminal
youtube-dl "欲しい動画のURL" -f "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]"
```

## (本題)複数ダウンロード
1urlを一行としたファイルを作成します。

```terminal:target_urls
http://youtube.com/watch?v=num_1
http://youtube.com/watch?v=num_2
...
http://youtube.com/watch?v=num_n
```

```terminal:terminal
youtube-dl -f mp4 -a target_urls
```


# 参考URL
youtube-dl全般
http://bobbyquine.hatenablog.com/entry/2018/01/05/025418
ffmpegのインストール
https://qiita.com/momongaclub/items/92608827be59c14688c8
複数ダウンロード
https://qastack.jp/ubuntu/334081/downloading-multiple-files-with-youtube-dl
td-client-python でエンドポイントを指定した場合に、SSL接続でクエリを実行する

Python3 で td-client-python を使う際に、エンドポイントがデフォルトではない場合があります。
その場合は以下のようにエンドポイントを指定する必要があります。
例えば TD_ENDPOINT を`api.treasuredata.co.jp`とすると、HTTP接続でクエリを実行します。
ここで、SSL接続が必要になる場合があります。

```python
import os

from os.path import join, dirname

import tdclient

from dotenv import load_dotenv

dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)

TD_APIKEY = os.environ.get('TD_APIKEY')
TD_ENDPOINT = os.environ.get('TD_ENDPOINT')
DATABASE = 'hoge'

with tdclient.Client(apikey=TD_APIKEY, endpoint=TD_ENDPOINT) as client:
  job = client.query(DATABASE, 'SELECT COUNT(1) FROM fuga', type='presto')
  job.wait()
```

手元の環境は以下になります。

* Ubuntu 18.04 LTS
* Python 3.7.0
* td-client==0.13.0

※ （2020.7.21 更新）
td-client==1.2.1 以降はデフォルトでSSL接続になるとのことです。

この場合、エンドポイントの指定で`https://api.treasuredata.co.jp`と明示的にSSLを指定する必要があります。

### 参考になった記事
[td-client-python](https://github.com/treasure-data/td-client-python#listing-jobs)
CMSで出力された静的ファイルをcronで定期的にGitHubへバックアップ

# はじめに
## 対象読者
* html 等のファイルを静的に出力するタイプの CMS を使っている人
    * 静的 CMS とは？　たとえば……
        * [PowerCMS](https://www.powercms.jp/) / [PowerCMS X](https://powercmsx.jp/)
        * [Movable Type](https://www.movabletype.jp/)
        * など
    * [Netlify](https://www.netlify.com/) などは、リポジトリをベースにサイトデプロイしてくれる CMS といえるわけですが、その逆方向のケアをしてあげるということになります
* GitHub 等のリポジトリへ差分バックアップを取って管理するようにしたい人
    * 別に BitBucket でも GitLab でも構わないので、適宜読み替えてください
* 特に CMS とか関係ないけれど、とにかく cron で定期的に GitHub へバックアップする方法を知りたい人

## 本記事におけるサーバ環境
* Ubuntu 20.04

## 前提
* git コマンドが使える環境
* root 以外のユーザーで SSH ログイン
* あらかじめ GitHub 側でリポジトリを作成しておく
    * ここでは仮に cms-static とする

# 設定
## 静的ファイルを置いているディレクトリの Git リポジトリ化
* cd で静的ファイルを置いているディレクトリへ移動
* Git リポジトリ化する

```sh
git init
```

## git config --global
* もしまだ git config --global を設定していなかったら、する
    * name, email ともに自身のものを設定

```sh
git config --global user.name "GitHubUserName"
git config --global user.email GitHubRegisteredAddress@domainhogehoge.com
```

## キーペア作成／登録
* もしまだキーペアを作成／登録していなかったら、する

### キーペア作成
* 4096 bit で作成する

```sh
ssh-keygen -b 4096
```

* 以下が表示されたら enter を押すとデフォルトの id_rsa で作成される
    * 特にこだわりがなければそのままで作成した方がよい
    * というのも GitHub はデフォルトだと他のキー名を読んでくれない
    * 他のキー名へ変更する際には必ず config ファイルを作成しましょう

```sh
Enter file in which to save the key (/user/username/.ssh/id_rsa): 
```

* もし他のキー名へ変更する際の config ファイルの中身
    * 例えば github_rsa へ変更する場合

```config:/home/ptnaweb/.ssh/config
Host github github.com
  HostName github.com
  IdentityFile ~/.ssh/github_rsa
  User git
```

### 公開キーの登録
* GitHub の管理画面から登録してください


## リモートリポジトリの登録
* cms-static という既に GitHub に作ってあるリポジトリを push origin の向かい先として登録する

```sh
git remote origin git@github.com:GitHubUserName/cms-static.git
```

* 正しく登録されたかどうかは、以下コマンドで確認

```sh
git remote -v
```


## リポジトリへの push テスト
* 一度手動で実行してみるとよいでしょう
    * 初回実行時に fingerprint の登録云々と訊かれるので yes で進める

```sh
git add -A
git commit -m "backup_`date '+%Y/%m/%d'`"
git push origin master
```


## cron
* 以下コマンドで cron の編集ファイルを開く

```sh
crontab -e
```

* 以下を記述
    * 毎日 03:00 に Git リポジトリ化されている /var/www/cms/static/ の変更を add, commit して push するよ、という内容です
    * 注意点としては date の取得時に % をエスケープしてあげる必要があるということ

```sh
0 3 * * * cd /var/www/cms/static/; git add -A; git commit -m "backup_`date '+\%Y/\%m/\%d'`"; git push origin master;
```

# 検証
## GitHub リポジトリ
* リポジトリを確認して、正しく反映されていればよしです


# おわりに
## 感想
* CMS 内に差分管理できる機能を備えたものもありますが、 GitHub で一元的に管理できるようになっていると、一覧性が担保できてわかりよいですね
* cron の中で日付を記述する時にはエスケープ使わないといけない、というのがちょっとしたクセモノ

## 関連して
* そもそも出力された静的ファイルは、管理サーバ内ではなく外に置いておきたいですよね！　というニーズを満たすために、以下の記事を書いています
    * [CMSの管理サーバと静的ファイルの公開サーバを別に分ける](https://qiita.com/Hi_Noguchi/items/aef4602f0e2f5a514e82)
RPAエンジニアがフリーランスになるメリットとは？　その魅力を徹底解説！！

こんにちは！
Peaceful morning社でインターンをしている高橋です！

昨今、様々な働き方が世の中にある中で、RPAエンジニアの方もフリーランスに転向するケースというものがよく見られ始めています。

そこで、今回はRPAエンジニアの方が**フリーランスとして、働くことのメリット**を整理していきたいと思います。

**・フリーランスで働いてみたいけど一歩がでない**
**・あまりフリーランスの仕事のイメージがつかない**
**・若干フリーランスに疑問がある**

このような方に読んでいただきたいです。

**RPAエンジニアではない一般のエンジニアの方も参考になる記事**です！
ぜひご覧ください！


###RPAって何？という方こちらをご覧ください↓
**初投稿！RPAって何？RPAとAIの違いは？はじめての人でもわかるRPAのすべて！**
https://qiita.com/RPAHACK/items/36e6fcc4ff73372db17a

**RPAを家事に例えるなら？**
https://rpahack.com/rpa

##フリーランスになるメリットとは？
ではさっそくフリーランスになるメリットを一つずつ確認していきましょう

###ニーズの高いスキルや経験が身に付く
会社員と違い、フリーランスは関わるプロジェクトを自由に選ぶことができます。その際にニーズの高いスキルが習得できるプロジェクトを選択することで、フリーランスとしての価値を上げることが可能です。

例えば会社員の時に扱っていたRPAツールが、必ずしも世の中の企業側のニーズに合致しているとは限りません。継続して仕事を続けるためには、ニーズがある現場で経験を積み、スキルアップしていくことが大切です。

###スキルや経験次第で報酬アップが可能
高いスキルや経験を有している場合、フリーランスになることでそれに見合った報酬を手にすることが可能です。

RPAのプロジェクトは、SIer、コンサルティングファーム、SESなどの多重構造で構成されていることが多く、会社に所属している場合はこの多重構造の中に組み込まれることになります。フリーランスになるとこの多重構造から抜けることができるため、報酬アップにつながりやすいのです。

多重構造から脱して適切な報酬を手にするには、クライアント企業とフリーランスが直接契約を結ぶのが最も望ましいと言えます。しかし、個人事業主であるフリーランスが企業と直接業務委託契約を結ぶことは、実績や信用の面で課題があり簡単ではないため、フリーランスエージェントを活用して案件に参画することが一般的です。

###自分の思うようにライフスタイルをデザインできる
フリーランスになると、仕事の成果に対して自分で責任を持たなくてはなりません。当事者意識を持ち、常にクライアント企業が求めていることと自分が貢献できることについて考えを巡らせることが大切です。求められたことに対して期待以上の価値を提供し続けることでおのずと信頼され、次の仕事につなげることができるでしょう。

責任が伴う一方で、会社員時代には実現できなかった働き方を選択することが可能です。例えば通勤時間を短縮したいと考えた場合、家から近い場所で行われているプロジェクトやリモート勤務可能なプロジェクトに参画するのもよいでしょう。また、半年間は週5日企業に常駐するプロジェクトに参画し、次の3カ月は稼働が少ないプロジェクトに参画するなど、自分の思うようにライフスタイルをデザインできるようになります。


##メリットが少しでも理解できた方に向けて

フリーランスで働くことのメリットを少し理解していただけましたでしょうか。
この記事を読んでご自身のキャリアアップに繋げていただけたら幸いです。

今回はフリーランスのメリットを紹介しました。しかし、メリットだけではなく、注意するべきこともあります。注意するべき点については以下で詳しく書いてあります！


こちらの記事も合わせてご覧ください↓
**RPAエンジニアがフリーランスになる３つのメリットと注意点**
https://rpahack.com/rpa-freelance-3


##RPA HACK おすすめ記事 3選
RPA HACKを少しでも気になった方にむけてこちらの記事をおすすめします。
RPA HACKでは100本以上の記事が無料で読めます！

1.**「自動化が進む世界で、時代に合わせて変化する人を応援したい――藤澤専之介氏インタビュー」**
(弊社代表のインタビューです。弊社の思いであったりビジョンがわかります！)
https://rpahack.com/sennosukefujisawa_interview

2.**「UiPath StudioXの基本をマスター！～画面構成/カード/アクション」**
(RPAツールであるUiPath StudioXの使い方を丁寧に解説しています！これからRPAを使ってみたいという方にはおすすめです！)
https://rpahack.com/uipath_studiox_1

3.**「RPAの導入事例　部門ごとに事例を紹介！」**
(RPAが実際どんな業務に使われているのかイメージがつかないという方におすすめです！)
https://rpahack.com/rpa-casestudy

この他にも、RPA関連の情報を随時更新しています！ご覧ください！

最後まで読んでいただき誠にありがとうございました！
複数のシートのデータを１つのシートにまとめるマクロ

#はじめに
私はプログラミングを勉強をはじめて
約1年半。

業務上複数あるシートを
１枚のシートにした上であれこれやる必要が生じた。
ただ、そのシートがあまりにも多すぎたし、
コピペするのも馬鹿馬鹿しくなったので
せっかくだから勉強してコードを書いてみた。

#状況
例えばこのような売上表(売上金額.xlsx)あったとする。

|  日付  |  売上金額  |
| ---- | ---- |
|  1/1  |  50,000  |
|  1/2  |  60,000  |
|  〜  |  〜  |
|  1/31  | 40,000   |

このシートは１月分で
2月から12月もそれぞれのシートで管理されていたりする。

この各月ごとに別れているシートを
1/1から12/31までつながったデータにしたい場合、

|  日付  |  売上金額  |
| ---- | ---- |
|  1/1  |  50,000  |
|  1/2  |  60,000  |
|  〜  |  〜  |
|  12/30  | 1,000,000   |
|  12/31  | 1,000   |

この程度ならば、
2月分をコピーし、1月の最下段に貼り付けを
12月まで繰り返せばできる。

あくまでこれは例の話だが、
このシートがたくさんある場合や、
日付などでなく連続性がない場合など
ヒューマンエラーも起りやすそうな作業となる。



#コード

```vb

Sub function()

　'画面更新停止
　Application.ScreenUpdating = False
  
  '確認ダイアログ停止
  Application.DisplayAlerts = False

  'コピー元になるブック
  Dim CopyWB As Workbook
  'コピー元になるシート
  Dim CopyWS As Worksheet
  '貼り付け用のシート
  Dim PasteWS As Worksheet
    
  'コピー元になるシートの最終行
  Dim max_row As Long
  'コピー元になるシートの最終列
  Dim max_column As Long
  
  '貼付用のシートの最終行
  Dim last_row As Long
  'もとになるシートの名前
  Dim OpenFileName As String
  
  '貼付用のシートはこのブックのsheet1
  Set PasteWS = ThisWorkbook.Sheets("sheet1")
  
  'ファイルを開くダイアログを表示
  OpenFileName = Application.GetOpenFilename("Excelファイル,*.xls*")

  'キャンセルの時の処理
  If OpenFileName = "False" Then
    'メッセージ表示
    MsgBox "キャンセルされました"
    End
  
  Else

　　'貼付用シートを初期化
    dWS.Cells.Clear
    dWS.Cells.ClearFormats
    '元になるブック を開く
    Workbooks.Open OpenFileName
    Set CopyWB = ActiveWorkbook
    
  End If

  i = 0
  
  '元になるそれぞれのシートにおいて
  For Each CopyWS In CopyWB.Worksheets
    
    With CopyWS
   
      'CopyWSシートをアクティブに
      .Activate
      
      '最終行と列を求める
      max_row = .Range("A1").End(xlDown).Row
      max_column = .Range("A1").End(xlToRight).Column
      
      1枚目のシートの先頭行はそのまま張り付ける
      If i = 0 Then
      
        .Range(.Range("A1"), .Cells(4, max_column)).Copy
        PasteWS.Cells(1, 1).PasteSpecial (xlPasteAll)
        
      End If
      
      'A1セルから右下セルまでコピー
      .Range(.Cells(1, 1), .Cells(max_row, max_column)).Copy
      
      '貼り付け用シートの最下段を取得
      last_row = PasteWS.Cells(Rows.Count, 1).End(xlUp).Row
      
      
      '貼り付け
      PasteWS.Cells(last_row + 1, 1).PasteSpecial (xlPasteAll)
     
    End With
    
  Next sWS


  '元データを変更せずに閉じる
  Call sWB.Close(SaveChanges:=False)
  
  
  '貼付用シートをアクティブに
  dWS.Activate
  
　'A1セルに戻ってくる
  dWS.Range("A1").Activate
  ActiveWindow.ScrollRow = 1
  ActiveWindow.ScrollColumn = 1
  
End Sub

```

#まとめ
このマクロをもつエクセルファイルでから
この処理を実行すると、ファイルを開く画面が出る。
元となるデータのエクセルファイルを開くと、
各シートのデータをまとめて、
sheet1に書き出してくれる。
元データはそのまま閉じてしまうし、
A1セルがアクティブになった状態で、画面も表示されるようにしている。

簡単なところから自動化や単純化をすすめることで
普段の作業性UPやミスが減らせるので、
引き続きプログラミングの学習を進めていきます。

ありがとうございました。
非公開 (シークレット) SSID に obnizで接続しよう

obnizOS 3.2.0以降では非公開SSID、シークレットSSIDへの接続がサポートされました。

その設定方法を紹介します。

# シリアルでの設定方法

シリアルで設定する場合は、次のような設定画面が表示された際に``-- Other Network --``と書かれた項目の横にある数字を入力します。

今回であれば``8``ですね。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97208/00fb8e7b-07d5-9aeb-a212-389260b831c1.png)

次にこれから設定するネットワークが、非公開SSIDかそうでないかを設定します。

今回は非公開SSIDを設定するので、``1``と入力してください。

その次に接続したいSSIDとPasswordを入力する欄が表示されるので、それぞれ非公開SSIDの設定を入力してください。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97208/8303659c-e3e1-2e16-7307-9d431eeaad0c.png)

このあとに、プロキシや固定アドレスの設定ができます。

詳しくは下記のサイトをご覧ください。

https://obniz.io/ja/doc/reference/board-1y/wi-fi

# Webでの設定方法

Webでの設定画面の出し方については下記のサイトをご覧ください。
https://obniz.io/ja/doc/reference/board-1y/wi-fi#wi-fi%E6%8E%A5%E7%B6%9A%E7%94%BB%E9%9D%A2

Webで設定する場合は、次の設定画面のSSIDの欄から``Other Network``と書かれた項目を選択します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97208/aae98b31-146e-20eb-d39b-7de96c161bdd.png)

``Other Network``と書かれた項目を選択すると、接続したいSSIDとPasswordを入力する欄が表示されます。

その下に非公開SSIDに接続するかどうかの選択肢があるので、``Enable``を選んで、非公開SSIDに接続できるように選択してください。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97208/9b86e0d0-c080-993b-86e4-f3f4a5df4d90.png)


OptionSettingではプロキシや固定アドレスの設定ができます。

詳しくは下記のサイトをご覧ください。

https://obniz.io/ja/doc/reference/board-1y/wi-fi

設定ができたら、``Connect``をクリックすると接続できます。
東京都の新型コロナウイルス感染症対策サイトの最新感染動向の各グラフの横幅を簡単に拡大(50%から100%)する方法

# 副題

この記事は技術的には「特定のclassを持つ要素に対して処理を行うワンライナー(1行)javascript とも言えます。

# 背景
[Code for Japan](https://www.code4japan.org/activity/stopcovid19)さんによる[東京都の新型コロナウイルス感染症対策サイトの最新感染動向](https://stopcovid19.metro.tokyo.lg.jp/)には都がモニタリングしている情報がグラフ化されて掲載されており、傾向の分析に有用です。

ただグラフ幅が狭いので感染の影響が長びくにつれて過去データ(特に前回の感染拡大期を参照したい)を参照するには横スクロールが必要になってきました。

[![Image from Gyazo](https://i.gyazo.com/0d0865222c9fabbd0828b30ec3ddac34.png)](https://gyazo.com/0d0865222c9fabbd0828b30ec3ddac34)

これを以下のように全幅表示に変えたいと思いました。

[![Image from Gyazo](https://i.gyazo.com/a40b84c57a3541e3fcdef7256f7d1db5.png)](https://gyazo.com/a40b84c57a3541e3fcdef7256f7d1db5)

# 対策

調査してみたところグラフ領域の幅を指定しているのは`col-md-6`というクラスです。このクラスのスタイル定義は以下のとおりです。

```css
@media (min-width: 960px)
.col-md-6 {
    flex: 0 0 50%;
    max-width: 50%;
}
```

`col-md-6`を除去したり、50%になっているところを`100%`にすればOKです。ここでは100%にしてみます。

手動でやってもいいのですが、若干面倒なので、各ブラウザの拡張機能のでスクリプトを実行して変更できるようにしたいと思います。
で、作成したのが以下です。

## ワンライナー版

```javascript
Array.prototype.forEach.call(document.getElementsByClassName('col-md-6'),function(elem,idx){if(elem){elem.style.maxWidth='100%';elem.style.flex = '0 0 100%';}})
```

## 整形した版

```javascript
Array.prototype.forEach.call(
  document.getElementsByClassName('col-md-6'), function (elem, idx)
  {
    if (elem)
    {
        elem.style.maxWidth = '100%';
        elem.style.flex = '0 0 100%';
    }
  }
)
```

これを当該サイトを開いた状態から開発者ツール(ChromeでもFirefoxでもF12キー押下で表示されます)を起動して`console`タブで貼り付けて実行(Enterキー押下)すればOKです。

Chrome 84.0.4147.89 / WIndows10

[![Image from Gyazo](https://i.gyazo.com/dab3e16229848c38d8734a2018782bd0.png)](https://gyazo.com/dab3e16229848c38d8734a2018782bd0)

Firefox 78.0.2 / WIndows10

[![Image from Gyazo](https://i.gyazo.com/6f0ad400f0d09d642d78052e4c430d58.png)](https://gyazo.com/6f0ad400f0d09d642d78052e4c430d58)
SQLでcsvファイルを出力する方法


実行したクエリの結果をcsvファイルにする方法です。

<pre>
SELECT 対象カラム
 FROM 参照テーブル
 WHERE 条件1
 AND 条件2
 AND 条件3
 INTO OUTFILE 'ファイル名.csv'
 FIELDS TERMINATED BY ',';
</pre>

「INTO OUTFILE」でファイルの出力先およびファイル名を指定します。
「FIELDS TERMINATED BY」にカンマを指定することで、データの形式がcsvになります。
必要であれば「INNER JOIN」も含めます。