OmniAICreator/Qiita-1.07M huggingface dataset:
FirebaseAuth のユーザーを別のFirebaseプロジェクトへ移行する

#　概要

FirebaseAuth のユーザーの import/export の方法についてまとめておく。基本的には下記の通り。

- [auth:import と auth:export | Firebase](https://firebase.google.com/docs/cli/auth?hl=ja)
- [Firebase Authenticationのimport/export - 怠慢プログラマーの備忘録](https://yutaabe200.hatenablog.com/entry/2019/02/15/Firebase_Authentication%E3%81%AEinport/export)

Firebaseプロジェクト以外にも移行が可能な模様。

[Firebaseの認証情報を外部に移行する - Rhythm & Biology](https://mythosil.hatenablog.com/entry/2018/07/16/103343)

この記事でのそれぞれの名称は下記の通り。

- 移行元のFirebaseプロジェクト: FIR-A
- 移行先のFirebaseプロジェクト: FIR-B

# 注意

- import/export はコマンドからしか出来ない
- import 時のパスワードハッシュパラメータは移行元の情報を利用する
- 移行先と移行元に同じメールアドレスがあると重複する
- import 後のパスワードハッシュ値は空になり、1度パスワード認証が行われて rehash されなければ再度移行は出来ない
- import は 1000 件単位で行われ、エラーが出た場合は 1000 件単位で失敗する
- import 時に空の行がCSVにあると import エラーになる

# やり方

まずは FIR-A のパスワードハッシュパラメータを確認する、確認方法は下記の通り。

> プロジェクトに使用されているパスワード ハッシュ パラメータを確認するには、Firebase コンソールで [Authentication] > [Users] セクションの順に移動し、ユーザーのリストの上にあるその他アイコンをクリックします

パスワードハッシュパラメータの形式は下記の通り。

```
hash_config {
  algorithm: SCRYPT,
  base64_signer_key: <...sensitive...>,
  base64_salt_separator: <...sensitive...>,
  rounds: 8,
  mem_cost: 14,
}
```

あとは CLI で FIR-A のユーザーを export して、FIR-B に import すれば完了。

```sh
$ firebase use FIR-A
$ firebase auth:export fir-a.csv
$ firebase use FIR-B
$ firebase auth:import fir-a.csv      
    --hash-algo=[algorithm]        
    --hash-key=[signer_key]                        
    --salt-separator=[base64_salt_separator]   
    --rounds=[rounds]                               
    --mem-cost=[mam_cost]   
```

# import時にユーザーが重複するのを避けたい場合

移行元と移行先のユーザーをCSVでエクスポートして、Googleスプレッドシートにそれぞれ別のシートで import する。次に、もう一つシートを作成して、A1で次の関数を利用すると自動で重複していないユーザーのみのリストが生成されるので、これを FirebaseAuth に import すれば良い。

```
=FILTER(FIR-A!A:E, COUNTIF('FIR-B'!B:B, FIR-A!B:B)=0)
```

ちなみに、重複しているユーザーのみを取得する場合はこちら。

```
=FILTER(FIR-A!A:E, COUNTIF('FIR-B'!B:B, FIR-A!B:B)>0)
```
Z3Py　例題　ハノイの塔

# 問題
以下のルールに従って、すべての円盤を右端の杭に移動する。

* 3本の杭と、中央に穴の開いた大きさの異なる複数の円盤から構成される。
* 最初はすべての円盤が左端の杭に小さいものが上になるように順に積み重ねられている。
* 円盤を一回に一枚ずつどれかの杭に移動させることができるが、小さな円盤の上に大きな円盤を乗せることはできない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118796/58f190cb-cf02-d80a-eb78-ad6819bff5cc.png)


# 回答
円盤が４つの場合

```example_tower_of_hanoi.py
from z3 import *
import itertools

disk_num = 4
peg = 3

# 存在する状態を列挙 (disk_4,disk_3,disk_2,disk_1) の形
states = itertools.product(range(peg), repeat=disk_num)
dict_state = {}
# 状態を辞書化
for i, state in enumerate(states):
    dict_state[i] = state


# 状態の逆引き辞書作成
def inverse_dict(d):
    return {v: k for k, v in d.items()}


inverse_dict_state = inverse_dict(dict_state)


# 制約定義
t_max = 16  # 移動させる回数
T = [Int("T%s" % i) for i in range(t_max)]
f = Function('f', IntSort(), IntSort(), BoolSort())

s = Solver()
s.add([And(0 <= T[i], T[i] <= len(dict_state)-1) for i in range(len(T))])


def check_state_change(before, after):
    # 状態遷移が可能かどうかチェックする
    changed_disk = None
    for x in range(len(before)):
        # 一度に１枚だけしか移動しない。
        if (before[x] - after[x]) != 0:
            if changed_disk != None:
                changed_disk = None
                break
            else:
                changed_disk = x

        else:
            if changed_disk != None:
                # 前状態において、一番上のDiskしか移動しない
                if (before[changed_disk] - before[x]) == 0:
                    changed_disk = None
                    break
                    # 小さな円盤の上に大きな円盤を乗せることはできない
                if (after[changed_disk] - after[x]) == 0:
                    changed_disk = None
                    break

    if changed_disk != None:
        return True
    else:
        return False


for i in range(len(dict_state)):
    for j in range(len(dict_state)):
        if check_state_change(dict_state[i], dict_state[j]):
            s.add(f(i, j) == True)
        else:
            s.add(f(i, j) == False)

# 全ての遷移において、遷移可能な状態である。
for i in range(len(T)-1):
    s.add(f(T[i], T[i+1]))

# 初期状態と終了状態を指定する。
s.add(T[0] == inverse_dict_state[(0, 0, 0, 0)])
s.add(T[-1] == inverse_dict_state[(2, 2, 2, 2)])


# 結果
print(s.check())
if s.check() == sat:
    # print(s.model())
    m = s.model()
    for i in range(len(T)):
        print('T['+str(i)+']=' + str(dict_state[m[T[i]].as_long()]))

```
出力

```terminal
sat
T[0]=(0, 0, 0, 0)
T[1]=(0, 0, 0, 1)
T[2]=(0, 0, 2, 1)
T[3]=(0, 0, 2, 2)
T[4]=(0, 1, 2, 2)
T[5]=(0, 1, 2, 0)
T[6]=(0, 1, 1, 0)
T[7]=(0, 1, 1, 1)
T[8]=(2, 1, 1, 1)
T[9]=(2, 1, 1, 2)
T[10]=(2, 1, 0, 2)
T[11]=(2, 1, 0, 0)
T[12]=(2, 2, 0, 0)
T[13]=(2, 2, 0, 1)
T[14]=(2, 2, 2, 1)
T[15]=(2, 2, 2, 2)
```

## 解説
存在できる状態は、各円盤の位置が決まれば１状態しかないことから、左から（一番大きな円盤の位置、二番目に大きな円盤の位置、、、、一番小さな円盤の位置）とした。

解く方針として、初期状態から最終状態への一連の遷移状態が成立していることを解くために、ある状態からすべての状態に対し遷移できるかできないかを定義した。

`z3py`とは関係関係ないが、順列組み合わせを求めるのに、`itertools`を用いた。（ [参考](https://cocoinit23.com/python-itertools/) ）

`m=s.model()`で解を見るとき、数値に変換するには`.as_long()`を用いる。（`Int()`は使えない）

# 他の例題
[Z3Py個人的ポータル](https://qiita.com/Ganesha/items/7a606ffc8a7c2504c143) へ
Laravel-dompdfパッケージで画像表示させる方法

#はじめに
`Laravel-dompdf`パッケージを用いてPDFダウンロードはできましたが、
そこになかなか画像を表示させることができなかったのでその方法です。

#画像表示されない

通常画像を表示させるには以下にのように`imgダグ`を使用します。

```html
<img src="(画像のURL)">
```

PDFダウンロードさせたい`blade`ファイルにこのように記述しても画像は表示されません。
これは最初に`blade`ファイルを読み込みそのあとに画像ファイルを読み込みにいく動作をするのですが、
このパッケージが画像ファイルを読み込めないようです（権限か何か問題だと思われる・・・）

#対応方法
以上のような理由で表示されないので、ビューを渡すときに画像データも一緒に渡してあげるようにします。
方法は`base64_encode()`でウェブページに直接埋め込むようにします。

具体的なコードは以下。


```php:downloadController.php
$image_path = storage_path('image/sample.png');
$image_data = base64_encode(file_get_contents($image_path));

$pdf = PDF::loadView('(Bladeファイル)', compact('image_data',....))
          ->setPaper('a4', 'landscape');
$pdf->download('(ファイル名)');
```

```php:pdf.blada.php
<img src="data:image/png;base64,{{ $image_data }}">

```
コントローラーで画像データをエンコードします。
今回は`storage`　配下にimageデェレクトリーを作り画像ファイルと置いている状況です。
`storage_path()`で画像データのパスを取得し、
`file_get_contents()`でファイルそのものを取得、
`base64_encode()`でファイルをエンコードし、`Blade`ファイルへ渡す。

`Blade`ファイル側で上記のような記述をすると画像ファイルが展開され表示されるようになります。
正常に表示されるようになり「ほ」っとしました。

ちなみに`jpag`ファイルなら`png`と記載の箇所を書き換えたらできます！
spacedeskでタブレットやPCを外部ディスプレイにしてマルチディスプレイ化する

##　はじめに
今回はspacedeskでマルチディスプレイ化する方法を紹介します。

https://www.spacedesk.net/

## 対象機器
### サーバー(送信側)
- Windows

### クライアント(受信側)
- Windows
- iOS
- Android
- HTML5対応ブラウザ

## 使い方
### サーバー側

メインのPCに[こちらのサイト](https://www.spacedesk.net/)からクライアントソフトをダウンロードしてインストールしてください。
サーバーソフトを起動、StatusがONになっていなかったらタスクトレイのspacedeskアイコンを右クリックしてOnにしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263584/f8531b2d-4878-4cac-1180-210bce447289.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263584/6a0781de-aaf9-4a16-5e4e-741b99dcaead.png)　　　　　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263584/59a3404e-ccb9-996e-e657-e03f96c3163b.png)


### クライアントがiOS、Androidの場合

※私はiOS端末を持っていないのでiOSの場合違うところがあるかもしれません
iOS、Androidのストアでダウンロード、インストールしてください。
spacedeskを起動して表示されている端末をタップします。



![spacedesk.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263584/3d6e84f4-c031-a9c2-35de-e1bae96d110b.png)

### クライアントがLinux、MacOSの場合
ブラウザでhttp://viewer.spacedesk.net/ にアクセスしConnectをクリックしてください。
※FireFoxでは使えませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263584/96af26b2-01c3-59e4-6d77-5c3d919f8e2e.png)


サーバー側に表示されたらクライアント側にも表示されているはずです。ウインドウは閉じても構いません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263584/859aff54-cec0-cace-e995-e9c280c3a198.png)

##　ディスプレイの位置調整
スタートボタンを右クリックして`設定`→`システム`→`ディスプレイ`を選択します。画面を動かして位置を調整します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263584/c264176e-aad0-2da4-699d-a8b9f953a0cc.png)

## 終了方法
タスクトレイのspacedeskを右クリックしてOFFを選択します。
個別に終了する場合はAndroidの場合は履歴からプロセスを終了させます。
ブラウザ版はクライアントPCのF11を押してタブを閉じます。

## My Accounts
<a href="https://github.com/mao2009"><img src="https://mao2009.github.io/qiita_template/GitHub-Mark-64px.png" width="50px"></a><a href="https://twitter.com/loach_mao"> <img src="https://mao2009.github.io/qiita_template/Twitter_Social_Icon_Circle_Color.png" width="50px"></a>
git pull --rebase でリモートリポジトリの更新を取り込む

###はじめに
本稿は執筆者の備忘録です。
記述内容に誤りなどありましたら、教えていただけると幸いです。
また、末尾に[参考サイトのリンク](#参考サイト)を貼り付けています。
より詳しい解説となっておりますので、ぜひそちらもご覧ください。


#メインブランチは更新される

最近はチーム開発に関わるようになり、個人学習よりも本格的にgitを使うようになりました。
自分に振られたIssueをこなすので精一杯なのですが、如何せん時間がかかります。

ようやく動作確認までして、いざpush!、、と思いきや、コンフリクトしているようです。
何やら数日前に大きく改修したらしく`自分がブランチを切った際のメインブランチが古くなっていた`ということらしい。

なんか、自分の仕事が遅いような気がしてちょっと切なくなります。
が、しかしこれはチーム開発である以上避けては通れない道ですよね。

#メインブランチの更新を取り込む


作業ブランチで更新されたメインブランチを取り込むには、

```git
git pull origin {mainブランチ名}
```

とすればOKです。

また、`pull`コマンドは`fetch(リモートのブランチからデータを取ってくる)`と`merge(データを取り込む)`をした場合と同義です。
ですので、

```git
git fetch
git merge origin/main
```
としてもOK。



#--rebaseオプションを使う

`pull`コマンドのオプションに`--rebase`があります。
これは、前述したメインブランチの更新を作業ブランチに取り込むのではなく、`作業ブランチを切った際の状態を、更新されたメインブランチに付け替える`というイメージでいいかと思います。

```git
git pull --rebase origin {mainブランチ名}
```

こうすると、gitのマージコミットがスッキリします。
イメージしにくい方のために、私が書いた超綺麗な図解を載せておきますね。

![Group 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284176/a101c9d6-52f4-a686-cfd2-de4ab500fa33.png)

ただ、元の履歴が消えてしまうので、通常のマージでログを残した方が良い場合もあります。
チームの方針を確認した方がいいとのことでしたので、注意してください。

###参考サイト
https://kray.jp/blog/git-pull-rebase/
こちらのサイトは本稿の１００倍詳しく、そして分かりやすいです。
AtCoderログ：0045 - ABC 083 B

# 問題

https://atcoder.jp/contests/abc083/tasks/abc083_b

## 問題文
> $1$ 以上 $N$ 以下の整数のうち、$10$ 進法での各桁の和が $A$ 以上 $B$ 以下であるものの総和を求めてください。

## 制約
> ・$1 \le N \le 10^4$
> ・$1 \le A \le B \le 36$
> ・入力はすべて整数である

## 収録されている問題セット
- [AtCoder に登録したら次にやること](https://qiita.com/drken/items/fd4e5e3630d0f5859067) ([第05問](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-5-%E5%95%8F--abc-083-b---some-sums-200-%E7%82%B9))
- [AtCoder Beginners Selection](https://atcoder.jp/contests/abs)

# 回答
"# 回答1 (AC)
整数 n, a, b を受け取った後、変数 i を 1 から n まで変化させ、i の各桁の合計 sum を計算し、それが a 以上 b 以下ならば変数 answer に1を加える、という処理を繰り返します。i の各桁の合計を計算するには、「10 で割った余りを計算 → i を 10 で割った商に置き換える」という処理を繰り返しますが、変数 i の値を変更すると for 文がおかしくなってしまうので、i の値を別の変数 nn にコピーし、nn に上の処理を適用することにします。コードは以下のようになりました。

```C++:abc083b-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int n, a, b;
  cin >> n >> a >> b;
 
  int answer = 0;
  for ( int i=1; i<=n; i++ ) {
    int nn = i, sum = 0;
    while ( nn>0 ) {
      sum += nn%10;
      nn  /= 10;
    }
    if ( a<=sum && sum<=b ) {
      answer += i;
    }
  }
  cout << answer << endl;
}
```

# 調べたこと
## [AtCoder に登録したら次にやること](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-5-%E5%95%8F--abc-083-b---some-sums-200-%E7%82%B9)
上記の回答で変数 i の値を変数 nn にコピーする代わりに、各桁の合計を計算する関数を使用していました。

## [AtCoder の解説](https://atcoder.jp/contests/abc083/tasks/abc083_b/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/arc088/editorial.pdf)
回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0044 - ARC 124 A](https://qiita.com/RoadLynton/items/4af8bad282614e1e0339)
- 次の記事 → [AtCoderログ：0046 - ARC 124 B](https://qiita.com/RoadLynton/items/757323fe4f27ba8e2df7)
[laravel 8.52]shiftとpopの関数が複数のアイテムを返せるように!


# 概念

今までlaravelのコレクションの`pop()`と`shift()`が一つのアイテムだけを削除し、返すことでしたが、Laravel8.52に含まれている[このPR](https://github.com/laravel/framework/pull/38093)では、引数が受け取れるようになって、複数のアイテムを返すようになりました。

# 使い方

## 基本
返したいレコード数を`pop()`か`shift()`に引数として渡すと、そのレコード数がコレクションから削除され、新しいコレクションとして返されます。いずれの関数のデフォルト引数値が`1`ですので、引数を定義しない場合には、今までと同じように1アイテムがコレクションから削除され、返されます。

```php

    $collect = collect([
        'Craig',
        'is',
        'very',
        'handsome!'
    ]);
    
    //　最後の二つのアイテムを削除し、新しいコレクションとして返す
    $collect->pop(2);
    // collect(['handsome!', 'very']);
 
    $collect->all();
    // ['Craig', is];
    
    // 最後のアイテムを削除し、返す
    $collect->pop();
    // 'is'
```
`shift()`の関数は`pop()`と違って`「最後」`のではなく、`「最初」`のアイテムを処理する動きで、実行の仕方も同じなので、ここで省略します。

## 注意

コレクションのアイテム数より大きいな引数を渡すと、返されるコレクションのサイズが必ず渡された値になるので、存在しないアイテムの分が`NULL`として返されたコレクションに入れるので気を付ける必要があります。

```php
    
    // 4アイテムのコレクションを作る
    $collect = collect([
        'Craig',
        'is',
        'very',
        'handsome!'
    ]);

    // 最初の６つのアイテムを削除し、返す
    $collect->shift(6);
    
    // 存在しないアイテムの分がＮＵＬＬとして入ってしまします
    // collect(['Craig', 'is', 'very', 'handsome!', NULL, NULL])

```

# 参照

https://github.com/laravel/framework/pull/38093
https://laravel.com/docs/8.x/collections#method-pop
https://laravel.com/docs/8.x/collections#method-shift
ViewからViewModelを閉じたい

## 前提

- MVVMについての知識。
- [PrismLibrary](https://prismlibrary.com/docs/)についての知識。
(`BindableBase`が分かれば…)

## 背景

デスクトップアプリケーションにおいて複数のウィンドウを開いたり閉じたりする要請がよくある。

## 問題

MVVMを前提とした複数のウィンドウを扱うようなWPFアプリケーションでは、ViewModelがViewを参照した状態でCloseすることは禁忌である。

例えば `Sample.cs` と `SampleViewModel.cs` があったとして、以下のようにViewModelからViewの参照を持ち、そこから`Close()`メソッドを叩くのはだめ。

```csharp
// ダメな例
// SampleViewModel.cs
public class SampleViewModel : BindableBase {
    private Sample view;

    public MainWindowViewModel(Sample view) {
        this.view = view;
    }

    public void CloseWindow() {
        view.Close();
    }
}
```

## 方法

考え方のフローは1から5までをたどっていく。

1. ViewからViewModelへ委譲するための`Action型`のプロパティをViewModelに用意する必要がある。
2. 委譲するためのインターフェースを用意する。
3. ViewModelにインターフェースを持つ。
4. ViewでViewModelの持つインターフェースのプロパティにメソッドを登録。
5. ViewModelでコール。

実際に用意する必要があるのは、ViewとViewModelを仲介するインターフェースである。今回の例では、`IClosedWindow`と名付けることにする。

```csharp
// IClosedWindow.cs
interface IClosedWindow {
    Action Close { get; set; }
}
```

次に、このインターフェース(`IClosedWindow`)をViewModelに実装する。

```csharp
// SampleViewModel.cs
public class SampleViewModel : BindableBase, IClosedWindow {
    public SampleViewModel {}

    public Action Close { get; set; }

    private DelegateCommand closeCommand;
    public DelegateCommand CloseCommand =>
        closeCommand ??= new DelegateCommand(ExecuteCloseCommand);

    private void ExecuteCloseCommand() {
        Close?.Invoke();
    }
}
```

そして、Viewは`Sample`の継承元である`Window`クラスの持つ`Loaded`イベントが発火されたタイミングで`DataContext`プロパティに登録されたViewModelを参照し、`IClosedWindow`にキャストする。

```csharp
// Sample.xaml.cs
public partial class Sample : Window {
    public Sample {
        InitializeComponent();
        Loaded += SampleLoaded;
    }

    private void SampleLoaded(object sender, RoutedEventArgs e) {
        // vmがインターフェースを持っていない場合の処理
        if (DataContext is not IClosedWindow vm)
            return;

        // ここで、Viewを閉じる処理の委譲
        vm.Close += () => {
            this.Close();
        };
    }
}
```

キャストされた`vm`の`Close()`に委譲することによって、ViewModel側でコマンドを呼ぶとViewが閉じる。

## 参考

[How to Close Windows from a ViewModel in C#](https://youtu.be/U7Qclpe2joo)
Ubuntu: gnome-terminalでRictyDiminishedフォントを使う

## はじめに
以前Ubuntu & gnome-terminalの組み合わせでRictyDiminishedをterminalのフォントを使用したときに少し詰まったので備忘録用にメモ。

## 環境
 - Ubuntu: 20.04.2 LTS 64bit
 - Gnome: 3.36.8

## RictyDiminished
下記リポジトリより入手
https://github.com/edihbrandon/RictyDiminished

`.ttf`ファイルが入手できるのでインストール。
コマンドラインからでもGUIからでもインストールできると思う。

## gnome-terminal
設定は右クリック->`Preferences`で開くことができる。
`Profiles`の`Text`タブでフォントを指定することができるが、ここに先程インストールしたRictyDiminishedが表れない。


ここで下記２つ対応しておく

 - +ボタンで適当に一つプロファイルを足しておく
 - 右下に表示されているハッシュ値を覚えておく。

## dconf-editor
詳細な設定は`dconf-editor`というソフトで編集ができるらしい。

```sh
sudo apt install dconf-editor
```

`dconf-editor`を起動するとGUIが立ち上がる。
`org/gnome/terminal/legacy/profiles:`以下にprofilesが格納されている。
先程作成したプロファイルのハッシュ値に相当するファイルを開く。

`font`の項で直接`Custom value`を打ち込むことができる。
`Use default value`をuncheckし、`custom value`に`Ricty Diminished Discord 18`を打ち込む。(18はフォントサイズなので、所望の値を打ち込む)

これで`gnome-terminal`上で右クリック->`Profiles`で作成したプロファイルを選択すればRictyDiminishedが使えるはず。


## おわりに
なんでインストールしたフォントが一覧に表示されないかなど、謎はありますがひとまずこれで使えます。誤りや楽な方法をご存知の方がいらっしゃいましたら、ご教示いただけると幸いです。
Thinkpad x220のトラックポイント設定（Ubuntu）

ubuntu環境でのトラックポイントの感度やスピードを変更したときの参照したサイト
[Ubuntu17.10でtrackpointの速度を調整する](https://qiita.com/takyam/items/c5184a14d8ca9553be1b)
[How to configure the ThinkPad TrackPoint in Ubuntu](https://www.youtube.com/watch?v=r-6yM4i_Iyc&ab_channel=BotondHorv%C3%A1th)
WatchdogTimerを試す

# WatchdogTimer(ウォッチドッグタイマー)
ESP32(M5Stack)とArduinoにて、ウォッチドッグタイマーの動作を確認する。いずれも、Arduino IDEを利用しているが、ウォッチドッグタイマーはマイコン依存の部分が多々あり、低レベルではそれぞれ異なるFunctionが用いられている。また、両者にて精度に差があったので、それも記載する。

## ウォッチドッグの内容
ランダムな時間（1-2500ms）Sleep中、Sleep開始から2秒経過した場合、ウォッチドッグタイマーによりリセットする。

## ESP32
### 参考URL
- [わかりやすい説明](http://marchan.e5.valueserver.jp/cabin/comp/jbox/arc202/doc21105.html)
- [ESP32本家のソースコード](https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Timer/WatchdogTimer/WatchdogTimer.ino)

### ソースコード

```c++
#include "esp_system.h"

#define TIMEOUT 2000
hw_timer_t *timer = NULL;

void IRAM_ATTR resetModule() {
  ets_printf("Reboot\n");
  esp_restart();
}

void setup()
{
  Serial.begin(115200);  
  randomSeed(millis());

  timer = timerBegin(0, 80, true);                  //timer 0, div 80
  timerAttachInterrupt(timer, &resetModule, true);  //attach callback
  timerAlarmWrite(timer, TIMEOUT * 1000, false);    //set time in us
  timerAlarmEnable(timer);                          //enable interrupt

  Serial.println("Setup done");
}

void loop()
{
  uint16_t val;
  timerWrite(timer, 0); //reset timer (feed watchdog)
  val = random(1, 2500);
  Serial.printf("Sleep %d ms\n", val);
  delay(val);   // Process which might take time
}
```

- randomSeed()にて乱数を初期設定。
- ウォッチドッグタイマー関連初期化（ハンドラの設定、Enable化など）。
- timerWrite()実行後、timerAlarmWrite()で指定した時間（TIMEOUT * 1000 us）である2秒後にリセット（WatchdogTimer実行）される。
- 1-2500msの間でSleep（delay()）。

### 結果
![M5StackWatchDogRandom2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/1affd622-6fd4-90b4-62d4-1b60c631b3b9.png)

2072msのときにリセット（WatchdogTimer実行）しているのが見られる。

## Arduino
### 参考URL
- [Arduinoでウォッチドッグタイマーを使う](https://asukiaaa.blogspot.com/2020/10/avr-arduino-watchdog.html)
- [Arduinoでのソフトウェアリセット](https://ehbtj.com/electronics/arduino-software-reset/)

### ソースコード
```c++
#include <avr/wdt.h>

void setup() {
  Serial.begin(115200);
  randomSeed(millis());
  wdt_enable(WDTO_2S);
  Serial.println("Setup done");
}

void loop() {
  char buf[16];
  uint16_t val;
  wdt_reset();
  val = random(1, 2500);
  sprintf(buf, "Sleep %d ms", val);  
  Serial.println(buf);
  delay(val);
}

```

- randomSeed()にて乱数を初期設定。
- wdt_reset()実行後、wdt_enable()で指定した時間（WDTO_2S）である2秒後にリセット（WatchdogTimer実行）される。
- 1-2500msの間でSleep（delay()）。

### 結果
![ArduinoWatchDogRandom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/2e1be18a-19e9-7dff-0779-b0ec54111517.png)

2128msではリセットせず、2215msではリセットしている。幾度となくトライした、2秒以上でリセットしていないケースが、Arduinoでは多々見受けられた。精度が悪いのであろうか？（詳細未調査）
自作 chrome 拡張機能 (simple tab position)


## 動機
自分はctrl+t でタブを新規追加するとき、現在のタブのすぐ右に来てほしいというのがあって、いままで [ Tab Position Customizer 2](https://kzstock.blogspot.com/2021/07/ban-TabPositionCustomizer2.html) を使っていたのですが、google から BAN されてしまい、使えなくなってしまいました。そこで、[tab position customer - modified](https://chrome.google.com/webstore/detail/tab-position-customizer-m/kkhcdbdhbmegbbhgmdhhpfmjhlhjlghp) を試してみたのですが、自分のパソコンではうまくタブを制御できませんでした。

## 自作 google 拡張機能
https://github.com/taka1226/tab_position_right  
に公開しています。設定ページなどはなく、拡張機能をオンにしたらすぐ使えます。

## 改善点
![forQuiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1148474/217d30f9-f8cd-6109-e26d-1474ecaf8bf4.png)  
ブラウザを起動した直後などにエラー表示されます。ちゃんと動いているのですが、時間があるときに直したいです
Automation360の親子Bot間で辞書を渡す

#はじめに
Automation Anywhere V11では親子Bot間ではリストや辞書の構造体をやり取りすることができませんでした。
Automation360ではここがかなり拡張されています。
環境設定用の構造体情報をBot間で引き回す、なんて事ができそうです。

例えば環境設定用の情報がディクショナリ変数に入っているという想定で、それを親子Bot間でやり取りしてみます。

# 親から子へディクショナリ変数を渡す
これは簡単。
親Botのディクショナリ変数：oyaDic
子Botのディクショナリ変数：koDic
だとして、子Botで変数koDicの「入力として使用」にチェックを入れ、
親Botから子Botを呼ぶ（タスクBoot:実行）ところで、oyaDicとkoDicを割り当てるだけ。

#  子から親へディクショナリ変数を返す
逆に子のディクショナリ変数を親に渡す場合です（親⇒子は無いものとして）。

1. 子Botで変数koDicの「出力として使用」にチェックを入れる。
1. 親Botで子Botを呼ぶ（タスクBoot:実行）ところで、結果を変数に保存でディクショナリ変数を指定。仮に戻りを受ける変数としてreturnDicとします。
1. 親から子を読んだあとの戻りで\$returnDic{koDic}\$が子Botのディクショナリ変数になります。 
1. なので、親Bot側でディクショナリ：Getを使い、ディクショナリ変数returnDicのキーkoDicの値をoyaDicに代入すると、oyaDicに子Botのディクショナリ変数の情報が入ります。

※子Bot⇒親Botの戻りをディクショナリ変数で受けているので、少しややこしいですね。

※「複数の変数」の指定を使い、子Botのディクショナリ変数と同じ名前の変数を親Bot側にも作り、それを割り当てる方が簡単でした。詳しくは以下を。
https://qiita.com/etoootak/items/21d5cfc2674dd63bcf4f

#  親から子へ辞書情報を渡し、さらに子から親へ辞書情報を返す
ここは余談です。混乱を招きそうなのでプログラムに詳しい方向け。
上の２つを混ぜれば親⇒子⇒親もできますが、実はそんな面倒な事をせずとも、最初の
『子Botで変数koDicの「入力として使用」にチェックを入れ』
だけでもＯＫ。
子Botで書き換えたディクショナリ変数の内容が親Botで参照できます（戻りを受けなくても）。

じゃぁ、ぜんぶ「入力として使用」だけでいいじゃん、となりそうですが、それではダメなケースがあります。
（例えば数字型変数などは、「入力として使用」だけでは、子⇒親に返せません）

このへんの話を
https://qiita.com/etoootak/items/ddb87ed4b246acea3fd2
にもう少し書きました。
現場で使用していたGitコマンド集

#目次
[1.よく使うコマンド](#1-よく使うコマンド)
[2.実際に使用していた手順](#2-実際に使用していた手順)
[3.押さえておきたい概念](#3-押さえておきたい概念)
[4.git pullとgit pull -rの違い](#4-git-pullとgit-pull--rの違い)
[5.さいごに](#5-さいごに)

#1. よく使うコマンド

##①git checkout ブランチ名
ブランチを移動する。

```
git checkout feature/kana/dayo-123456
```

##②git status
修正があるファイルを確認する。

```
git status
```

##③git checkout .
②で修正があるときに修正を取り消す。

```
git checkout .
```

##④git pull -r
ブランチを最新化する。
※git pullとの違いについてはこの記事の最後にまとめています。

```
git pull -r
```

##⑤git pull -rp
複数の人が同じブランチで作業しているとき、他方の修正内容を反映させる。

```
git pull -rp
```

##⑥git branch -l | grep '文字列'
検索したい文字列が含まれるブランチを探す。

```
git branch -l | grep 'kana'
```

##⑦git merge 親ブランチ名
子ブランチで親ブランチの内容をマージする。

```
git merge feature/kana/dayo
```

##⑧git branch
ローカルブランチにあるブランチを確認する。

```
git branch
```

##⑨git branch -d ブランチ名
ローカルブランチを削除する。

```
git branch -d feature/kana/dayo-123456
```

##⑩git branch -D ブランチ名
⑨でエラーが出たときローカルブランチを強制削除する。

```
git branch -D feature/kana/dayo-123456
```

##⑪git fetch -p
⑨→⑩のあとにこのコマンドを叩く。
リモートブランチに存在していてローカルブランチに存在していないブランチを削除する。

```
git fetch -p feature/kana/dayo-123456
```

##⑫git checkout -b ブランチ名
ブランチを新規作成する。

```
git checkout -b feature/kana/dayo-123456
```

##⑬git push -u origin ブランチ名
指定したブランチで修正した内容をプッシュする。

```
git push -u origin feature/kana/dayo-123456
```


#2. 実際に使用していた手順

##親ブランチの内容を子ブランチに取り込む
※コミットするものはコミットしておく
①修正があるファイルを確認
```git status
```
②修正があるときは修正をなくす
```git checkout .
```
③子ブランチでブランチ最新化
```git pull -r
```
④親ブランチに移動しブランチ最新化
```git pull -r
```
⑤子ブランチで親ブランチの内容をマージ
```git merge feature/kana/dayo
```


##子ブランチの新規作成
①親ブランチに移動しブランチ最新化
```git pull -r
```
②子ブランチを新規作成
```git checkout -b feature/kana/dayo-123456
```

##ローカルブランチを消す
①消すブランチとは違うブランチに移動
```git checkout feature/kana/dayo
```
②ブランチ削除
```git branch -d feature/kana/dayo-123456
```

③エラーが出たときに強制削除
```git branch -D feature/kana/dayo-123456
```
④リモートブランチに存在していてローカルブランチに存在していないブランチを削除
```git fetch -p
```
※この手順のみではリモートブランチは消えない

#3. 押さえておきたい概念
![スクリーンショット 2021-07-30 0.41.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558666/24dfb797-f5a6-8ac3-f5c1-8e1b81e2e8cc.png)
※プルはフェッチとマージを一括で行うコマンド（プル＝フェッチ＋マージ）

#4. git pullとgit pull -rの違い
```git pull　　 = fetch + merge```
```git pull -r　= fetch + rebase```

◆merge、rebaseとは
>今いるブランチに別のブランチの内容を取り込むコマンド

◆違い
>マージは現在のブランチの上に他のブランチの内容を取り込むというかんじですが、
リベースは取り込みたいブランチの上に今のブランチの内容を乗せるといったかんじ

◆git pull -rのメリット
>マージコミットが作られない＆履歴が綺麗になる

◆注意

>いきなりリベースをするとチームの規約に反する場合もありますので、
そのあたりは事前にチームの人に確認してください。

（現場でgit pull -rの使用を指示されていたため使用していたのですが、
チームの規約に反する可能性があるということは知りませんでした。。。）


↓こちらの方の記事がとてもわかりやすかったため、引用させていただきました。

https://kray.jp/blog/git-pull-rebase/

※--rebaseと-rは同じ意味のオプションです。

##5. さいごに
ここまで読んでいただきありがとうございます！
主に実際に現場で使用していたコマンドをまとめてみました。
改めて調べてみると認識が違っていたり、
気づきがあったりしたためとても勉強になりました。
自分の記録が誰かのお役に立てると嬉しいです。。
【Laravel】Aush認証のリンクで404エラー

LaravelでAuth認証を導入した際に、ログインページへのリンクで404エラーになってしまいました。
解決までの道筋を載せます。

<h1>環境</h1>
MAMP
OS：macOS
Laravel:8.51.0
PHP:7.4.12
MySQL:5.7.32

<h1>エラー</h1>

ログインしていたら「設定」「ログアウト」のボタンを表示、もしログインしていない場合は「ログイン」と「新規登録」に飛ぶ。
ログインは"/login"というアドレスで、新規登録は"/register"というアドレスに飛ぶが、このように表記しても404エラーになる。

```html:index.blade.php
@if (Auth::check())
<p>USER: {{$user->name}}</p>
<a class="btn btn-primary" href="#" role="button">設定</a>
<a class="btn btn-primary" href="#" role="button">ログアウト</a>
@else
<p>ログインしていません</p>
<a class="btn btn-primary" href="/login" role="button">ログイン</a>
<a class="btn btn-primary" href="/register" role="button">新規登録</a>
@endif
```
この画面からボタンを押すと
※作成中のためデザインがしょぼくてすみません
![スクリーンショット 2021-07-29 21.26.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159752/eaf7b463-0a25-c026-6177-31146b54a831.png)

ログイン画面での404エラー
![スクリーンショット 2021-07-29 21.27.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159752/9a01d479-e8ee-d559-e379-6d8768b356b1.png)

新規登録画面での404エラー
![スクリーンショット 2021-07-29 21.27.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159752/1f142036-0b57-3f68-06f4-813f119c8ac7.png)

アドレス部分を見てみると、遷移後はアドレスが短縮されている。
ちなみにhref="/login"を、href="study_stamp/public/login"に変更してみると、アドレス部分は「localhost:8888/study_stamp/public/study_stamp/public/login/」になってしまった。

どうやら**指定アドレスで公開する設定をしていなかった**ことが原因だということが分かった。

<h1>指定アドレスで公開するとは？</h1>
例えばMAMPを利用すると、Webサーバーの公開ディレクトリが「htdocs」になる。
「htdocs」内にファイルを配置すればWeb上に公開される。

今回の件だと「htdocs」フォルダに「study_stamp」というフォルダを入れているので、アクセスする際には。

**http\://localhost:8888/study_stamp/public/**

にアクセスする必要があった。

しかし、このアドレスの/study_stamp/public/部分を無くしたい。
その際にするのが今回の指定アドレスで公開するという設定になる。

<h1>指定アドレスで公開するためには</h1>
今回はMAMPを利用しているので、MAMPでの設定方法になります。

MAMPのフォルダ内に、「conf」フォルダがある。
その中の「apache」フォルダ内の**httpd.conf**ファイルを開く。

以下の記載の場所を探す

```conf:httpd.conf
# Virtual hosts
# Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf
```
Include前の#を外し、記述を追加する。

```conf:httpd.conf
# Virtual hosts
Include /Applications/MAMP/conf/apache/extra/httpd-vhosts.conf

<VirtualHost *:8888>
    DocumentRoot "/Applications/MAMP/htdocs/study_stamp/public"
    ErrorLog "logs/laravel-error_log"
    CustomLog "logs/laravel-access_log" common
</VirtualHost>
```

DocumentRootは自分のプロジェクト名で書く。
保存して再起動すると、無事指定アドレスで公開することができました。

![スクリーンショット 2021-07-29 21.32.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159752/b57447bf-ce00-7278-7bcf-5bfd4965e039.png)

無事ログイン画面に遷移することもできました。

![スクリーンショット 2021-07-29 21.32.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1159752/99307a87-f746-d19a-bf6e-920a9426e58e.png)

この設定は最初にやらなければいけなかったことですが、それを忘れたまま進めてしまったためでたエラーでした。
もし同じ状況の方がいれば、少しでも参考になればと思います。
Excel 初心者〜マスターに向けた資料

# 目的
Excelの使い方を初心者からマスターするまでの資料を整理する。

# マスターになるための資料の分類
1. 動画で学ぶ
2. ホームページで学ぶ
3. 本で学ぶ

Excel(エクセル)で使われる用語が分からない場合は、
入門編の動画を見て用語を理解しましょう。
その後は、Excelでやりたいことに合わせた資料を探してみてください。

## 動画で学ぶ

### 入門編
2021年Excelの使い方・初心者入門講座【完全版】
[1:07:43]

https://www.youtube.com/watch?v=HEhDNoklIT0&t=13s

【やさしいエクセルの教科書】パソコン初心者もご安心ください「Excelの使い方」入門講座
[59:33]

https://www.youtube.com/watch?v=Lc2K3ctoRAA

### 初級

Excel仕事を10倍早く終わらせるテクニック20選
[58:13]

https://www.youtube.com/watch?v=YAdaT-cbjek


### 初級〜中級編
最強のエクセル使い方講座【たった1動画で全てが分かるExcelの教科書】MicrosoftMVP受賞
[3:30:49]

https://www.youtube.com/watch?v=Bo7GUN3G6fc&t=7328s

【最強のExcel関数22選】たった1動画で即戦力。Amazonベストセラー講師が世界一わかりやすく「エクセル関数」を実務目線で解説します！
[1:40:05]

https://www.youtube.com/watch?v=CiGmrITzNCI

## サイトで学ぶ

Excel VBA入門 

https://www.officepro.jp/excelvba/

Excel VBA リファレンス (microsoft)

https://docs.microsoft.com/ja-jp/office/vba/api/overview/excel

## 本で学ぶ
情報が古いものが多いため、
入門書 もしくは 辞書のような書籍であれば、購入してもよいです。

★未作成


# MicrosoftMVP

Microsoft社が表彰しているMVPの中から、
Japan/OfficeApp系のMVPを抽出しています。2021/7/31時点で20人。

https://mvp.microsoft.com/ja-jp/MvpSearch?ex=Office+Apps+%26+Services&lo=Japan&sc=e



# 履歴
2021/07/31 新規作成

---
UnityでVisualStudioからVisualStudioCodeに変更する。

<h2>変更の理由</h2>
<p>VisualStudioは全体的に重かったり、コメントアウトのショートカットがめんどくさかったり、</p>
いろんなデメリットがあるため、VSCodeに移行することを決心した。

<h2>早速変更する</h2>

<h3>.NET CLI toolsをインストール</h3>

.NET CLI toolsをインストールします。 

https://dotnet.microsoft.com/download

このリンク先の
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565846/6d2072e7-27cb-538d-2c42-1fe210cdce81.png)

.NETCore をインストールしてください。
`Download.NET Core SDK x64`　でいいかと思います。

Windowsの場合はPCを再起動します。(%PATH%を通すため)

<h3>.NET Framework 4.5 Targeting Packをインストール(Windowsのみ)</h3>
VisualStudioを開きます。 


コードなしで実行-> メニューのツール -> ツールと機能を取得 をクリックします。

Visual Studio Installerが起動し、そこから個別のコンポーネントへ移動します。

.NET Framework 4.5 Targeting Packをチェックしたうえで、変更をクリックすることでインストールされます。
（僕はデフォルトでチェックされていました。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565846/9951388c-5684-fb27-9e23-b598476b8eb0.png)


<h3>VSCodeに拡張機能を入れる。</h3>

必要な拡張機能は6つ

`Debugger for Unity`  `Unity Tools`  `Unity Code Snippets`  `Unity Snippets` `c#` `Mono Debug`

拡張機能の入れ方は割愛させていただきます。。

<h3>VSCodeでの設定</h3>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565846/705f38c6-a5d6-23c6-9859-f49c7f389047.png)

設定を開きます(ctrl + ,でもよい)

設定の検索に、 `useGlobalMono`　と入力し、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565846/7e31f2b7-9f42-615b-723b-af664a1ec79b.png)

autoからalwaysに変更してあげてください。

<h3>Unity側でVSCodeを標準のEditorにする。</h3>

Edit -> Preferences 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565846/227d2ee0-5ba7-b98d-0649-7fe1c2588a10.png)

Preferences -> External Tools


External Script Editorで `Visual Studio Code`を選択し(Visual Studio Codeがない場合、External Script EditorからBrowse...で直接VSCodeのパスを指定してあげます)、

Generate .csproj files for: となってる ところをすべてチェックしてあげてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565846/9c453a2d-e163-68b5-f4f0-1d1496529acb.png)


これでUnityでvscodeを使えるようになります。

<h3>VSCodeでUnityの構文チェック</h3>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565846/21b22a46-220d-4c5e-1fa0-c8a3218b392d.png)

拡張機能を入れたことによって左下の　⊗~ ⚠~ となってるところをクリックすれば構文チェックができます。 

<h2>番外編 コメントが文字化けする。</h2>

さっそく、VSCodeでゲーム開発していこうとしたら、コメントだけが文字化けしていた。

<h3>文字コードをShift-jisにする</h3>

VSCode側で設定に行き、 Encondingと検索し、

`Files: Enconding` を Japanese (Shift JIS) とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565846/90a1f518-407f-b024-ca2a-78ec4f7440ac.png)

VSCodeを再起動して設定を反映します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565846/a4c9a674-ea3e-6804-426c-3bff9d739ac9.png)

マークしたところがShift JISになってれば完了です。(なっていない場合クリックして、文字コードを変更してあげましょう。)

<h2>おわりに</h2>

公式ドキュメントが最強ですね。

<h2>参考文献</h2>
https://www.javadrive.jp/vscode/setting/index4.html
https://teech-lab.com/unity-howto-vscode/189/#index_id1
https://code.visualstudio.com/docs/other/unity
https://qiita.com/riekure/items/c45868f37a187f8e1d69
https://qiita.com/kamanii24/items/399f956f2bf6bec76884
Python環境構築

# ubuntu環境へのpython開発環境構築


以下のサイトを参照して、自分のマシン(Ubuntu 20.04 LTS)にpython開発環境を構築した。
1. [UbuntuにAnacondaをインストールしてPythonとJupyter Notebookを動かすまでの手順](https://www.virment.com/setup-anaconda-python-jupyter-ubuntu/)
2. [ubuntu環境でのanaconda3のインストール / condaが使えないとき](https://qiita.com/yoshida3/items/b14030b61ccfc1ab1976)

- 1のサイトより、anacondaをインストールすると、プロジェクトごとに異なるバージョンのpythonをインストールして使用できるよう「仮想環境」を構築することができる模様。
- 例えば、「このディレクトリではpython3.5、別のディレクトリではpython3.6使いたい」ときなどがある場合に、作成した仮想環境を切り替えることで同一のパソコン上でも異なるpythonのバージョンやライブラリを使用できるとのこと


- 仮想環境の有効化に戸惑ったため、以下のサイトを参照した
[conda activate の CommandNotFoundError への対処方法](https://qiita.com/peaceiris/items/e41488096e765269c93c)

- jupyter notebookを起動して、pandasをimportしたところ、下記のようなエラーが出た。

```
ModuleNotFoundError: No module named ‘pandas’ 
```

このエラーの対処には下記のサイトを参照した
[Anaconda の Jupyter Notebook で ModuleNotFoundError が発生した場合のトラブルシュート](https://weblabo.oscasierra.net/python-anaconda-jupyter-modulenotfounderror/)


今回はpandasをターミナルからインポートした。
pandasのインストール場所を確認したところ、以下の場所に存在していた。

```
$find -name pandas
./anaconda3/pkgs/pandas-1.1.5-py36ha9443f7_0/lib/python3.6/site-packages/pandas
./anaconda3/pkgs/pandas-1.2.4-py38h2531618_0/lib/python3.8/site-packages/pandas
./anaconda3/pkgs/astropy-4.2.1-py38h27cfd23_1/lib/python3.8/site-packages/astropy/io/misc/pandas
./anaconda3/envs/my_env/lib/python3.6/site-packages/pandas
./anaconda3/lib/python3.8/site-packages/pandas
./anaconda3/lib/python3.8/site-packages/astropy/io/misc/pandas
```
確かに仮想環境であるmy_envにpandasパッケージがインポートされていることが確認できた。juypter notebookを起動して、改めてpandasをインポートしてみると、インポートができた。


- jupyter notebookでpandas_profilingのインポートも同様に行う

# コーディング開始
```
import pandas as pd
import pandas_profiling as pdp
X = pd.read_csv('/home/akihiro/train.csv')
profile = pdp.ProfileReport(X)
profile
```

この際、pandas_profilingパッケージ関連で多くのエラーが生じた。その際に参考にしたサイトを書いておく。自分の場合は、panadas_profilingのバージョンが問題だったらしく、condaでインポートすることが原因なのではと推測した。そこで参照したサイトがこちら↓↓

- [pandas_proflingを使うとTypeError: concat() got an unexpected keyword argument 'join_axes'が出た話(Google Colab)](https://qiita.com/bsns_123456_clg/items/f518805b0eeee3381c7c)

pipでインストールし直したところ、新たなエラーが生じた。

```
/home/akihiro/anaconda3/envs/my_env/lib/python3.6/site-packages/pandas_profiling/pandas_profiling.mplstyle' not found in the style library and input is not a valid URL or path; see `style.available` for list of available styles
```
- jupyter notebookのカーネルを再起動することでエラーを消すことができた

その時参照したサイトがこちら↓↓
- [pandas_profiling.mplstyle not found OSError #233](https://github.com/pandas-profiling/pandas-profiling/issues/233)
- [Pandas-profiling: pandas_profiling.mplstyleが見つかりませんOSError](https://bleepcoder.com/ja/pandas-profiling/476554965/pandas-profiling-mplstyle-not-found-oserror)

これで訓練データの概要を表示できた。表示まで10秒ほどかかった。

# 反省
今回、anacondaのインストールのメリットとして、仮想環境を構築することができることを知り、ちょうどpythonでの開発環境が無かったため、仮想環境を構築してその上でコードを書いてみようと軽い気持ちで始めたが、いろいろなエラーを対照するうちに一日が経ってしまった。
jupyter notebookを起動してpythonコードを書いてみてはみたものの、カーネルがホスト環境にしかならず、仮想環境をカーネルに設定する方法が分からないままになっている。
そもそも、開発環境を構築するだけでいいのに、python初心者の自分が仮想環境は必ずしも必要ではない。しっかりと目的を持って、環境構築をするべきだと改心する一日だった。
docker-compose で GitHub Enterprise Cloud に接続するセルフホストランナーを簡単に立ち上げる

# 背景
Docker を使ってセルフホストランナーを立ち上げた。
参考: https://qiita.com/Yoshihiro-Hirose/items/650863c3312eaee9770d
複数ランナーを立ち上げるのが手間だったりしたので効率化したい。
公開済みのコンテナイメージと docker-compose を使用する。
また、Github Enterprise Cloud を使っているので enterprise への設定例も載せていく。

# 実施環境
- Linux
- Docker

# 使用するコンテナイメージ
https://hub.docker.com/r/myoung34/github-runner
上記を参考に github で Personal Access Token を発行しておく

# 手順
## docker-compose.yml ファイルを用意

項目についてはコメントを参照

```yaml:docker-compose.yml
version: '2.3'

services:
  worker:
    image: myoung34/github-runner:latest
    environment:
      ACCESS_TOKEN: <発行した Personal Access Token>
      RUNNER_NAME_PREFIX: test-runner
      RUNNER_WORKDIR: /tmp/runner/work
      RUNNER_SCOPE: enterprise # enterprise に設定する場合指定
      ENTERPRISE_NAME: <enterprise名> # 契約している enterprise 名
      LABELS: linux,x64,test-runner # 必要に応じてラベルを追加
    mem_limit: 2g # コンテナの最大メモリを指定
    cpus: 2 # CPU の最大使用量を設定
    volumes:
      - '/var/run/docker.sock:/var/run/docker.sock'
      - '/tmp/runner:/tmp/runner'
```

## docker-compose コマンドで立ち上げる
`docker-compose up -d --scale worker=4`
woker に指定した数だけコンテナが立ち上がる

## 起動しているか確認
`docker stats`

## ログを確認
`docker-compose logs -f --tail="5"`

## ランナーの停止と起動したコンテナの削除
`docker-compose down`

## github 側の確認
以下 URL を確認
https://github.com/enterprises/<エンタープライズ名>/settings/actions/runners
Audacityでラベル付き音声ファイルを切り出す

# Audacityを利用してWAVファイルをラベル毎に切り出します
## やったこと
Audacityでラベルトラックを作成し、WAVデータの時間半以後とにラベリングを行い、このラベル毎にWAVファイルを切り出しました。
## バックグラウンド
長時間の録音データから、機械学習向けラベル付き音声ファイルを作成するためです。
## Audacity

https://www.audacityteam.org/

## ラベル付け
音声ファイルの特定範囲を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/451a2b39-2769-b169-0b03-a3731ecabea7.png)
編修−＞ラベル−＞選択範囲にラベルをつける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/df9a9149-7a49-2f18-964a-b7d35401cda3.png)
ラベルを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/c1801045-ab7e-bf4e-90bc-6e020abc2b5a.png)
ラベルの書き出し
ファイル−＞書き出し−＞ラベルの書き出し
ファイルは　Start(TAB)Stop(Tab)Labelのフォーマット

``` text:LabelTrack.txt
0.529306        0.923964        PING
1.569346        1.843286        PING2
2.553670        2.836895        PING
```

### これをpython でラベル毎に切り出します。
切り出しには audiosegmentを使用
python3 cut [入力WAVファイル] [LabelTrack.txt]
出力は
入力WAVファイル_[LABEL]_[通し番号].wav
でラベル毎に切り出されて書き出されます。
同時にmetadata.csvとして
ファイル名,label
ファイルが書き出されます。

``` python:cut.py
# -*- coding: utf-8 -*-
from pydub import AudioSegment
import sys


def main():
    args = sys.argv
    infile=args[1]
    auxfilename = args[2]
    metaFilename="metadata.csv"
# Reading wav
    sound = AudioSegment.from_file(infile, format="wav")
    fn = infile.split(".")
# Reading AUX
    auxfile = open( auxfilename , 'r')
    metaFile = open( metaFilename , 'w' )
    metaFile.write( "filename,class\n" )
    auxlines = auxfile.readlines()
    auxfile.close()
    fileNum=0
    for auxline in auxlines[0:]:
        items = auxline[:-1].split('    ')
        start = float( items[0] )*1000.0
        end = float( items[1] ) *1000.0
#        start = int( float( items[0] ) * 1000 )
#        end = int( float( items[1] ) * 1000 )
        className = items[2]
        print( start , end )
        sound[ start:end ].export( fn[0]+"_"+className+"_"+str(fileNum)+".wav" , format="wav" )
        metaFile.write( fn[0]+"_"+className+"_"+str(fileNum)+".wav"+","+className +"\n")
        fileNum=fileNum+1
    metaFile.close()



if __name__ == "__main__":
    main()
```
DebianにPython3.9、pip3.9をソースからインストール

# 0.方針、条件

1. ソースをダウンロードしインストール
2. OS：Debian10.10


# 1.ビルドに必要なパッケージをインストール

```sh
apt update
apt install -y build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libsqlite3-dev libreadline-dev libffi-dev libssl-dev ssl-cert openssl

```

# 2. Python3.9のソースをダウンロード、ビルド

- 既存のpython、python3のコマンドを上書きしないように、「make altinstall」を実行する。

```sh
# ソースのダウンロード先に移動
cd /usr/local/src/python

# ソースをダウンロード・展開
curl -O https://www.python.org/ftp/python/3.9.6/Python-3.9.6.tar.xz
tar -xf Python-3.9.6.tar.xz

# 展開されたフォルダに移動
cd Python-3.9.6

# prefixでインストール先を指定
./configure --enable-optimizations --prefix=/usr/local/python3.9.6
sudo make altinstall

```

# 3. 「python3」コマンドをインストールしたバージョンと対応づける

- 「update-alternatives」コマンドを利用して設定する。

```sh
# インストールしたpythonをupadte-alternativesに登録
sudo update-alternatives --install /usr/local/bin/python3 python3 /usr/local/python3.9.6/bin/python3.9 10

# 設定を確認
python3 --version
Python 3.9.6

```
## 4. pip3.9をインストール

- aptでpip3をインストールすると「/usr/lib/python3」にインストールされるので、「get-pip.py」を利用してインストール。
- インストールしたバージョンから参照できる場所にpipのパッケージをインストールするのが目的。
- ソースの取得先は、「[Python Package Authority (pypa) ](https://www.pypa.io/en/latest/)」とする。

```sh
# pipのソースを取得
sudo curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

# インストール
python3 get-pip.py

# pip3コマンドをインストール先と対応づける
sudo update-alternatives --install /usr/local/bin/pip3 pip3 /usr/local/python3.9.6/bin/pip3.9 10

# 設定を確認
pip3 --version
pip 21.2.1 from /usr/local/python3.9.6/lib/python3.9/site-packages/pip (python 3.9)
```

## インストールしたディレクトリにパスを通す

```sh
# PATHにインストールディレクトリを追加
export PATH="$PATH:/usr/local/python3.9.6/bin"
# 設定読み込み
. ~/.bashrc
```
自宅サーバで VMware Tanzu

自宅に ESXi / vSphere / Tanzu を構築した際のメモ

# 参考

* [おうち ESXi の検討と導入](https://qiita.com/futakuchi0117/items/569b41be396eedd75b3f)
* [NUCで始めるVMware Tanzu Advent Calendar 2020](https://qiita.com/advent-calendar/2020/nuc-vmware-tanzu)

# 構成

以下の構成の PC を組みました。物理ハードは1台だけで、vCenter Server / Tanzu を構成するパターンです。

[おうち ESXi の検討と導入](https://qiita.com/futakuchi0117/items/569b41be396eedd75b3f) を参考にしました。Tanzu でかなりメモリを消費すると思ったので、メモリは 64GBにしています。

* ベアボーン: ASRock DeskMini H470
     - 19,386円
* CPU: Intel Core i7-10700 8core 16thread
    - 33,633円
    - 第10世代 Comet Lake。ビデオカードは載せないので、GPUありで。
* メモリ: Transend DDR-3200 32GB x 2
    - 37,600円
* SSD: Crucial MX 500 1TB
    - 11,880円
 
計: 102,499円

# ESXi / vSphere Center Server のインストール

ESXi 7 をインストールします。これは [おうち ESXi の検討と導入](https://qiita.com/futakuchi0117/items/569b41be396eedd75b3f) に書いてある通りなので省略。

* ESXi 7 では、デフォルトでは VMFSL パーティションで 128GB も使ってしまうので、けちってインストール時のオプションで 8GB に減らしました。
    - 起動時に Shift+O を押し、パラメータに　autoPartitionOSDataSize=8192 を追加
* 物理 ESXi ホストも vCenter Server の管理化に入れておきます (Nested ESXi でも良いと思います)
* 簡単化のため、分散スイッチは使いません。標準スイッチのみ、物理 NW のサブネットをそのまま使います。

なお、VMUG Advantage に加入(私は2年で$360のプラン)したので、1年評価ライセンスを使っています。60日無償評価ライセンスでももちろん OK です。

# Management Cluster のインストール

Management Cluster をインストールします。詳細手順は [Deploying Management Clusters](https://docs.vmware.com/en/VMware-Tanzu-Kubernetes-Grid/1.3/vmware-tanzu-kubernetes-grid-13/GUID-mgmt-clusters-deploy-management-clusters.html)にあります。

tanzu ツールをダウンロードして、ここから実行します。Tanzuのバージョンは 1.3.1 です。bootstrap のマシンは Ubuntu 20.04 を使いました。

```
$ tanzu management-cluster create --ui
```

完了すると ~/.kube/config が生成され、Management Cluster に kubectl でアクセスできるようになります。

## はまりポイント

* 以下手順をやっておかないと、vmware.1 の OVA を要求されてしまう
    - https://kb.vmware.com/s/article/83781
* 最新版 Linux で tanzu デプロイしようとすると、bootstrap cluster 作成時に止まります。
    + [リリースノート](https://docs.vmware.com/en/VMware-Tanzu-Kubernetes-Grid/1.2/rn/VMware-Tanzu-Kubernetes-Grid-12-Release-Notes.html)の Deployment Issues, May 2021 Linux security patch... に記載あり
    + kind 内の kube-proxy が nf_conntrax_mac permission denied で CrashLoopBackoff する
    + workaround は以下
        - 1) kind をインストールする
        - 2) kind create cluster で kindクラスタを起動する
        - 3) tanzu create management-cluster の引数に -e (--use-existing-bootstrap-cluster) を指定する

# TKG Cluster (TKC) のインストール

公式手順は [Deploying Tanzu Kubernetes Clusters](https://docs.vmware.com/en/VMware-Tanzu-Kubernetes-Grid/1.3/vmware-tanzu-kubernetes-grid-13/GUID-tanzu-k8s-clusters-index.html)

また、[Tanzu Kubernetes Grid 1.3を使ってみた](https://qiita.com/masanara/items/eb6f28eb402cbf53b8c6)も参考にしました。

まず設定ファイル YAML を作ります。management cluster の設定ファイルが ~/.tanzu/clusterconfigs にあるので、これを tkc.yaml にコピーします。そして、以下の設定を追記します。

```
CLUSTER_NAME: tkg1
VSPHERE_CONTROL_PLANE_ENDPOINT: コントロールプレーンのIPアドレス
```

ここで VSPHERE_CONTROL_PLANE_ENDPOINT は management cluster のアドレスとは別の値にしなければなりません。 このアドレスが kube-apiserver のアドレスになります。私はサブネット内で空いている別の IP アドレスにしました。

以下手順で TKC を作成します。

```
$ tanzu cluster create　-f ｔｋｃ．yaml
```

作成状況は以下で確認できます。

```
$ watch tanzu cluster get tkg1
```

完了したら以下を実行して ~/.kube/config に設定を取り込みます。

```
$ tanzu cluster kubeconfig get tkg1 --admin
```
【第0回】ElectronでWeb APIを動かしたい 〜何故それをやり始めたか〜

## これを始めた理由、得たい知識やスキル
新しいことを始めたとき、なんで始めたかを考えることは、継続につながると考えてる。
加えて、自己開発とかだと、無駄に機能追加したり触りたい技術盛り込んで、工数が多くなるのも防げる。

- `create-nuxt-app`とかでフレームワークをなんとなく動かすのではなく、JavaScriptをイチから動かすことで、これからつけたい、Webの体系的なスキルの土台を作る。特にWeb APIをパッケージに頼るんじゃなくて、自分でリクエスト送りたい。
- 自信を持って言える、自作のプロダクトが欲しかった。
- 自分のフィールドであるスマブラとITスキルをつなげたかった。
- 単純にElectronを触ってみたかった。

他の方の記事ですが、shoheiさんと言う方の記事のはじめに書かれている、以下の2つの成長もしていきたいと考えています。（*引用記事：*[*これからエンジニアを目指す人に見て欲しいです。*](https://qiita.com/hukusuke1007/items/1f3843a9f044a8affeee)）

- **アルゴリズムを鍛える（やりたいことをコードで表現できるようにする）**
- **ポートフォリオを作る、並行して設計の勉強する。**

## なんでElectronなのか
なんか自分が、ネイティブアプリに特別な機能性を感じているからな気がした。
基本的にブラウザアプリより、デスクトップアプリ選ぶし、Webアプリ開発から、Flutterのモバイルアプリに興味移ったし（今はWebやってるけど）。
なんか基本的にネイティブアプリはサーバーと通信しなさそうだし安定してるみたいなのが、根っこに考えとしてあるからかも知れん。

### 使ってみる技術
Node.js 16
HTML / CSS
JavaScript
Electron
Challonge API ←利用するAPI（https://api.challonge.com/cs/v1.html）
新規登録・ログイン画面実装① devise 新規登録の項目追加　

deviseで、新規登録画面、ログイン画面を実装しました。

その際にnameカラムと、入社何年目かの等級（年齢層？社歴？）を追加するカラムも追加しましたので、備忘録として残します。

![スクリーンショット 2021-07-31 9.52.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/a1b657dc-1ead-3285-4543-e40bb6444784.png)


<h2>カラムの追加</h2>

```rb
class DeviseCreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      ## Database authenticatable
      # メールアドレスでユーザー登録
      t.string :email,              null: false, default: ""
      # パスワードも必須
      t.string :encrypted_password, null: false, default: ""

省略〜〜〜

      t.timestamps null: false
      # 名前を登録してもらう
      t.string:name,null:false
      # 社歴？を登録
      t.string:join_year,null:false
    
省略〜〜〜
```

まずは保存する用のカラムを追加します。stringで問題ないのか若干不安です。

<h2>ApplicationControllerの記述</h2>

```rb
class ApplicationController < ActionController::Base
  # ユーザー認証などが行われる前に、configure~が実行される
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    # デフォルトにないname/join_yearを追加しているので、それらを許可するよう記載している
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name,:join_year])
  end
end
```

```(:sign_up, keys: [:name,:join_year])```にはemailは入りません。デフォルで入ってるようです。

<h2>新規登録画面の編集</h2>


```erb
 <div class="form-group">
    <%= f.label :name,"お名前" %><br />
    <%= f.text_field :name, autofocus: true,class:"form-control" %>
  </div>

デフォルトで入ってるので省略

<div class="form-group">
    <%= f.label :join_year,"クラス" %><br />
    <%= f.select :join_year,[["1年目", "1年目"], ["2年目", "2年目"], ["3年目", "3年目"],["4年目", "4年目"],["5年以上", "5年目"]], include_blank: "選択して下さい",class:"form-control" %>
  </div>
```


<h2>終わり</h2>
追々、グレードアップしていきます。
現在の疑問点・・string型で大丈夫なのか。

<h2>参考にした記事</h2>

https://qiita.com/kawakami_shotaro/items/11a677bf34136cb7686d
Heroku　コマンド

#herokuデプロイ用ファイル

Procfile
runtime.txt
djangoのproject/local_setting.py

requirements.txt
・下記ライブラリ追加
①dj-database-url
②gunicorn
③whitenoise==5.3.0


```
echo python-3.7.3 > runtime.txt
```

#Heroku CLIインストール

```
terminal
$ brew tap heroku/brew && brew install heroku
```

1-2. gunicornインストール

```
terminal
$ pip install gunicorn
```

heroku実行時に呼び出されるコマンド
下記コマンドのみでデプロイできる

```
heroku login

$ cd myproject/
$ git init
$ heroku git:remote -a <heroku用の名前>

$ git add .
$ git commit -am "make it better"
$ git push heroku master


Existing Git repository
For existing repositories, simply add the heroku remote

$ heroku git:remote -a django202107
```

```
$ heroku run python manage.py migrate
$ heroku run python manage.py createsuperuser
```

herokuバージョン確認

```
heroku -v
```

herokuアップデート

```
heroku update
```

gitとherokuを紐付ける
Create New App

#マイグレーション

```
heroku run python manage.py migrate 
```

#heroku.yml を使用して Docker イメージをビルド
heroku.ymlを追加

```
git add heroku.yml
git commit -m "Add heroku.yml"

heroku stack:set container

git push heroku master
```

#Heroku Container Registry
```
heroku login
docker ps
heroku container:login
heroku container:push web
heroku container:release web
```

No default language could be detected for this app.
```
heroku buildpacks:set heroku/python
```


```
heroku run bash
>ls
```

#Heroku ログ確認

```
heroku logs -t
```

#Heroku chromedriver使い方
Settings -> Add buildpack
に下記追加

https://github.com/heroku/heroku-buildpack-chromedriver.git
https://github.com/heroku/heroku-buildpack-google-chrome.git
yukicoder contest 307 参戦記

# yukicoder contest 307 参戦記

## [A 1628 Sorting Integers (MAX of M)](https://yukicoder.me/problems/no/1628)

実際にN個の整数列を生成して、大きい順にソートで並び替えて、文字列として連結すればいいです.

```python
N, *c = map(int, open(0).read().split())

t = []
for i in range(9):
    for _ in range(c[i]):
        t.append(i + 1)

print(''.join(str(i) for i in sorted(t, reverse=True)))
```

## [B 1629 Sorting Integers (SUM of M)](https://yukicoder.me/problems/no/1629)

ある数字 a を一つ抽出して考えてみる. a は b 個存在するとする. a が1の桁の場合のパターン数は (N-1)! となる. ただし区別がつかないものは排除しないといけないので、実際には (N-1)!/b! となる. これが10の桁の場合、100の桁の場合……と繰り返すことになる. 各桁の合計は (10<sup>N</sup>-1)/9 で計算できる. またある数字 a は実際には b 個存在するので b を掛けないといけない. 結論として、ある数字 a に起因して総和に足される数は (10<sup>N</sup>-1)/9*a*(N-1)!/(b-1)! となる. 後は a を1から9に変更しながら総和を取るだけである.

```python
m = 1000000007

N, *c = map(int, open(0).read().split())

fac = [1] * (N + 1)
for i in range(N):
    fac[i + 1] = fac[i] * (i + 1)
    fac[i + 1] %= m

x = fac[N - 1] * (pow(10, N, m) - 1) * pow(9, -1, m) % m
frac = 0
denom = 1
for i in range(9):
    if c[i] == 0:
        continue
    frac += c[i] * (i + 1) * x
    frac %= m
    denom *= pow(fac[c[i]], -1, m)
    denom %= m
print(frac * denom % m)
```
【Rails】enumを使ってステータス管理をしよう！


#対象者

* 商品等ののステータス管理を実装予定の方
* セレクトタグを実装予定の方

#目的

* ステータスで進捗や状況を管理できるような機能を実装する


#実際の手順と実例
###1.前提

* ケーキ屋さんのECサイトを作成しています。
* ここでは注文ステータスを取り扱うので、モデル名「order」、カラム名「order_status」とします。
* 管理者が注文ステータスを操作できるようにしたいので、


###2.カラム追加

まずは対象のモデル（order）にカラムを追加していきます

```
$ rails g migration AddOrderStatusToOrder order_status:integer
```

enum（イーナム）で数字管理していくのでデータ型はintegerで与えます。


###3.モデルにenumを追記

以下の通り書いていきます。

```order.rb
  enum order_status: {
     "入金待ち":0, "入金確認":1, "製作中":2, "発送準備中":3, "発送済":4
  }
```

番号が０から始まっている点に注意です。
表示したい内容とそれに合わせて数字を順に並べていきます。

###4.Viewで表示

今回は、管理者が操作して保存できるようにしたいので、
form_withを使って内容を保存できるように更新ボタンも付けます

```orders/show.html.erb
         <%= form_with model: @order, url: admin_order_path, method: :patch, local: true do |f| %>
            <%= f.select :order_status, Order.order_statuses.keys, class: "order_status" %>
            <%= f.submit "更新" , class: "btn btn-outline-success" %>
          <% end %>
```

 @order = Order.find(params[:id])とControllerに定義しています。また、ストロングぱらめーたーにも、permitでorder_statusを入力しています。


これで実装完了です。


#参照

>[【Rails】enumを使ってステータス管理を行う](https://nllllll.com/ruby-on-rails/%E3%80%90rails%E3%80%91enum%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E7%AE%A1%E7%90%86%E3%82%92%E8%A1%8C%E3%81%86/)

>[【Rails】enumを使用したセレクトボックスの実装とDBへの保存
](https://qiita.com/y-suna/items/1f5f34c6289fd88199a5)


####投稿者コメント

プログラミングスクールで勉強学んだことをそのままアウトプットしてみました。今後も７月に開発したものの中からどんどん発信していきます！

####My Profile
プログラミング学習歴②ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。