OmniAICreator/Qiita-1.07M huggingface dataset:
gitの使い方

git checkout . 
add されていない変更をなかったことにする。


## これもコミットしたかった！
→直前のコミットですか？　
→Yes　→ならまだ間に合う！ git add file git commit --amend -m "同じメッセージ"
→No → rebaseするしかないです。
git logで確認。どのコミットでどんなコードの変更があったかは、git diff HEAD~Nで見れます。もしくはsource treeを使いましょう。
→git rebase -i HEAD~N で、変更をねじ込みたいコミットの部分をpush → editにします。
→git logでHEADがそのコミットにいるかを確認。この状態というのは、今狙っているコミットが終わった状態です。
→git diff HEAD^でもう一度確認。そのコミットにねじこむので良いですか？
→git reset --soft HEAD をすると、git addはしているけどまだコミットしていない状態に戻ります。ここで変更を加えて、git add → git commmit としましょう。
→これで問題なければgit rebase --continueとします。これでハッピーエンドです。
このときに、既にリモートにpushしていたコミットまで遡っていた場合は、git push -fと、フォースプッシュする必要があります。他人と一緒にレポジトリを編集している場合は無断にやることは絶対に避けましょう。


参考
https://qiita.com/310ma3/items/e0ec74b47c6c219f2a8b
https://backlog.com/ja/git-tutorial/stepup/13/
https://qiita.com/FrogWoman/items/31cd5df4c4a5ae23f7e0
https://backlog.com/ja/git-tutorial/stepup/28/
https://git-scm.com/docs/git-rebase

https://qiita.com/zaneli@github/items/8d519a229653a2ed9ec6
http://www-creators.com/archives/5238#git_rebase_-i
python tips

### f'{:.2f}'
f'{}'を使いつつ有効数字を指定して表示したい時はこう

### tqdm を使う
進捗管理をしたい時はtqdmを使いましょう。
tqdmについての基本的なことは、他の記事できれいにまとまっているのでそちらを参照してください。
「とりあえずtqdmで囲ってるけど…」を脱したい人向けです。

###

```python
ind=3
txt = f'{ind:3d}.npy'
```


#### メッセージを表示する
```python
pbar = tqdm(lis)
for something in pbar:
    pbar.set_description("Processing %s" % something)
```
が基本です。自分は、pathlibを使うことが多いので、

```python
from pathlib import Path
path = Path('hoge')
objects = path.glob('*/hoge')
pbar = tqdm(objects)
for object in pbar:
    pbar.set_description("Processing %s" % object.name)
```
などとすることで今処理しているファイルの名前を表示することができます。

####
def hoge(self): ←これどうすればいいん?

#1.事の起こり
```python:python3
class Hoge:
    def p_hoge(self):
        print("hoge")
```

このクラス使って`hoge`したいのに`self`とか言うやつが邪魔して`hoge`出来ない!

```python:python3
#こんなエラーが出てる
missing 1 required positional argument: 'self'
```

#2.解決
クラスをインスタンス化し忘れてるね？

```python:python3
class Hoge:
    def p_hoge(self):
        print("hoge")

x = Hoge()  #ここ！
x.p_hoge()

#hoge
```

`hoge`出来たね?
【bash】ターミナルのコマンド履歴検索のショートカット"control + S"を有効にする

#### bashのコマンド履歴を検索するショートカット

|ショートカット|意味  |
|---|---|
|ctrl - r|コマンド履歴を逆順に検索する|
|ctrl - s|コマンド履歴を順に検索する|

この2つのショートカットは、bashのコマンド操作をするためにとても便利です。

ただ、"ctrl - s"の方は、 bashの初期設定ではコマンド実行結果を停止するショートカットに使われているため、コマンド履歴のショートカットとして使えない。

なので、"ctrl - s"をコマンド履歴のショートカットとして使うためには、コマンド実行結果を停止するショートカットを無効にする必要がある。
そのためのコマンドは、下のsttyコマンドです。

```
~ $ stty stop undef
```

そして、常にこの設定を有効化するためには、bashの設定ファイルの~/.bash_profileに上のコマンド1行を書けばできます。

[(macOS)ターミナルでよく使うショートカット一覧](https://it-jog.com/khow/terminalshortcut)
[ (macOS)bindでターミナルのショートカット一覧の確認、新規ショートカットの割り当て設定](https://it-jog.com/cmd/bindterminal)
【CSS】擬似クラス「nth-child」で学んだ事。

![スクリーンショット 2020-12-13 18.27.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927441/377a713b-8faf-366d-e370-08a2c447579d.png)
こんな感じだった見た目を
![スクリーンショット 2020-12-13 18.25.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927441/88844ce2-a339-fc8b-b44d-55fc1e1ce128.png)
この様にちょっと見やすくしたくて学んだことを備忘録として記載しています。
## nth-childを使う。
nth-childはセレクタに追加して条件を指定する擬似クラスのひとつで、
子要素のn番目(nth)にスタイルを適用させることができます。
## nth-childの書き方
`要素:nth-child(値){スタイルの内容}`
値には数字、2n+1などの式の他にeven(偶数)などを設定します。
例としては

- 偶数にのみ適用する場合：2nあるいはeven
- 奇数にのみ適用する場合：2n+1あるいはodd
- n番目に適用する場合：適用したい項目の順番の数値
- n番目以降すべてに適用する場合：n+適用を開始する項目の数値

「2n」とか懐かしい表記ですよね！
even(偶数)、odd(奇数)とか初めて知りましたよ・・・。
## nth-last-childを使う。
nth-childがリストの上(最初)から数えるのに対し
nth-last-childはリストの最後から数えます。

```ruby:stocks/index.html.erb
    <table>
      <thead>
        <tr>
          <th scope="col"><%= sort_order "display", "陳列" %></th>
          <th scope="col"><%= sort_order "publisher", "出版社名" %></th>
          <th scope="col"><%= sort_order "magazine_name", "雑誌名" %></th>
          <th scope="col"><%= sort_order "num", "冊数" %></th>
          <th scope="col"><%= sort_order "price", "本体価格" %></th>
          <th scope="col"><%= sort_order "i_form", "発行形態" %></th>
          <th scope="col"><%= sort_order "purchased", "買切雑誌" %></th>
        </tr>
      </thead>
      <tbody>
        <% @stocks.each do |stock| %>
          <% if stock.num > 0 %>
                <tr>
                  <td><%= stock.display %></td>
                  <td><%= stock.publisher %></td>
                  <td><%= stock.magazine_name %></td>
                  <td><%= stock.num %></td>
                  <td><%= stock.price.to_s(:delimited) %></td>
                  <td><%= stock.i_form %></td>
                  <td><%= stock.purchased %></td>
                </tr>
          <% end %>
        <% end %>
      </tbody>
    </table>
```

今回はこの様なリストを作成して

```ruby:stock.css
.stock-page tbody tr:nth-child(2n){
  background-color: #ddd;
}
.stock-page tbody tr:hover{
  background-color: gray;
}
```
この様に指定してみました。
この指定の優れていると思ったことは
`ソート機能にも対応してくれる`と、いうことだと思います。
当初、モデルデータのidが偶数の時に色を変える様に指定していたのですが
ソートをすると崩れてしまって逆に見づらくなってしまいました。
ウンウン唸っている時にこの擬似クラスを知る事ができてよかったです！
## 参考にさせていただいたサイト様
http://www.htmq.com/selector/nth-child.shtml
ありがとうございます！
集約の整合性についてArchUnitを用いてテストする②

「他の集約への参照はId経由で行う」ことをテストしてみる。

## テストコード

```java
    @ArchTest
    static ArchRule only_access_through_id_when_depend_on_another_aggregate_root =
        classes()
            .that().resideInAPackage("com.example.domain")
            .and().haveSimpleName("HogeRoot")
            .should().onlyAccessFieldsThat(new DescribedPredicate<JavaField>("not depend on another aggregate root object") {
            @Override
            public boolean apply(JavaField input) {
                return !input.getClass().getSimpleName().equals("FugaRoot");
            }
        });
```

集約ルートを直接参照していないことだけテストしている。
フィールド名を`endWith~("Id")`みたいに判別すればもう少し厳密にできる。

集約ルートを機械的に判別するのが辛い。

`@AggregateRoot`みたいなものがあれば幸せになれそう。
#3 Ruby始めました 「たのしいRuby 第６版」第三章 コマンドラインとファイル読み込み


#コマンド P.66-67
```ruby
#面倒なんで本を読むだけで十分かなとｗ
```


#コメント
プロンプト操作、コマンド入力ですね。
まあ読み出しやら保存は良く使うにしても、Guiではボタンに機能を割り振るみたいな感じなので、覚える必要もないかも知れませんが、一応簡単に読んで置きます。
GitHubのアピール力をあげる自己紹介README

GitHubはコードのバージョン管理やバックアップに活用できる非常に便利なツールです。
一方エンジニアとしての活動をアピールできる場でもあります。
（私はぺーぺーなのですが、まずは形から…笑）
そんなときにおしゃれに、目を引くようなREADMEをつくるちょっとした小ネタを紹介します。

## どんなふうに見えるのか

[![My Qiita posts](https://qiita-badge.apiapi.app/s/ryuji-oda/posts.svg)](http://qiita.com/ryuji-oda) [![My Qiita contributions](https://qiita-badge.apiapi.app/s/ryuji-oda/contributions.svg)](http://qiita.com/ryuji-oda) [![My Qiita followers](https://qiita-badge.apiapi.app/s/ryuji-oda/followers.svg)](http://qiita.com/ryuji-oda)

<a href="https://twitter.com/SyodoB" target="_blank"><img alt="Twitter: SyodoB" src="https://img.shields.io/twitter/follow/SyodoB.svg?style=social" /></a>
<a href="https://github.com/anuraghazra/github-readme-stats"><img align="left" src="https://github-readme-stats.vercel.app/api?username=RyujiOdaJP&show_icons=true&theme=cobalt" /></a>
<a href="https://github.com/anuraghazra/github-readme-stats"><img align="left" src="https://github-readme-stats.vercel.app/api/top-langs/?username=RyujiOdaJP&theme=cobalt" /></a>

<a href="https://github.com/RyujiOdaJP" target="_blank">
  <img src="https://grass-graph.moshimo.works/images/RyujiOdaJP.png?rotate=0">
</a>

## どうやって表示するのか

まず、GitHubに自分のユーザ名と同名のリポジトリを作ります。
私の場合は"RyujiOdaJP"というリポジトリ名です。

![RyujiOdaJP](https://user-images.githubusercontent.com/59087018/102008009-cb37df00-3d70-11eb-967b-19381c061030.png)

README.mdに下記のように記載します
ryuji-oda や SyodoBはユーザ名なので変えてください。

```md
[![My Qiita posts](https://qiita-badge.apiapi.app/s/ryuji-oda/posts.svg)](http://qiita.com/ryuji-oda) [![My Qiita contributions](https://qiita-badge.apiapi.app/s/ryuji-oda/contributions.svg)](http://qiita.com/ryuji-oda) [![My Qiita followers](https://qiita-badge.apiapi.app/s/ryuji-oda/followers.svg)](http://qiita.com/ryuji-oda)

<p>
  <a href="https://twitter.com/SyodoB" target="_blank">
    <img alt="Twitter: SyodoB" src="https://img.shields.io/twitter/follow/SyodoB.svg?style=social" />
  </a>
</p>

<a href="https://github.com/anuraghazra/github-readme-stats">
  <img align="left" src="https://github-readme-stats.vercel.app/api?username=RyujiOdaJP&show_icons=true&theme=cobalt" />
</a>
<a href="https://github.com/anuraghazra/github-readme-stats">
  <img align="left" src="https://github-readme-stats.vercel.app/api/top-langs/?username=RyujiOdaJP&theme=cobalt" />
</a>

<a href="https://github.com/RyujiOdaJP" target="_blank">
  <img src="https://grass-graph.moshimo.works/images/RyujiOdaJP.png?rotate=0">
</a>
```
[HTML/CSS]画像の上に文字を表示させる方法（超初学者向け）

超初学者向け画像の上に文字を表示させる方法を2つメモ。

画像の上に文字を表示させる二つの方法と、
それぞれの用途について。

#この記事に使った勉強素材
ちなみに、本記事で使っている勉強素材はとっても有名なこちらです。
とてもお世話になりました。ありがとうございました。
[【無料練習素材】あなたはできる？模写コーディング腕試し！](https://note.com/tokyofreelance/n/n4baf7dd10306)
作者様Twitter：[@Tokyo_Freelance](https://twitter.com/Tokyo_FreeIance)

#画像の上に文字を表示させる方法その①
「**[background-image](https://developer.mozilla.org/ja/docs/Web/CSS/background-image)**」で要素に背景画像を設定する。

ヘッダー画像を背景画像としてその上にテキストを重ねて表示させたい場合はこれ。
一番簡単だし、よく使われているのを見かけます。

```index.html
  <div class="info">
    <div class="text">
      <h1>1日1題30日で<br>プロのWebエンジニアになろう！</h1>
      <p>毎日設定された課題をこなすだけ！
        <br>未経験から30日でプログラミングスキルが身につきます。
      </p>
    </div>
  </div>
```
```style.css
.info {
  background-image: url(img/main-vsual-nontitle.png);
  background-size: cover;
}
```

CSSで[background-image](https://developer.mozilla.org/ja/docs/Web/CSS/background-image)で使用する画像を選択し、[background-size](https://developer.mozilla.org/ja/docs/Web/CSS/background-size)で要素の背景画像の寸法を設定します。

（※背景画像に色をつけて可愛くする技術は後日別途書きたいな〜と思っている（だけ））

#画像の上に文字を表示させる方法その②
「**[position](https://developer.mozilla.org/ja/docs/Web/CSS/position)**」で文書内で要素がどのように配置されるかを設定する。

親要素に「position:relative」
子要素に「position: absolute」

を記載することによって画像の上に文字を表示させることができます。

```index.html
    <div class="info">
      <img src="img/main-vsual-nontitle.png" alt="ヘッダー画像">
      <div class="text">
      <h1>1日1題30日で<br>プロのWebエンジニアになろう！</h1>
      <p>毎日設定された課題をこなすだけ！
        <br>未経験から30日でプログラミングスキルが身につきます。
      </p>
    </div>
    </div>
```

```style.css
.info {
  position:relative
}

.text {
  position: absolute;
  top: 40%; /*位置を指定します*/
}

.info img {
  width: 100%;
}
```

ヘッダー以外で画像に文字を挿入させたい場合はこっち。
もちろんヘッダーで使っても良いと思います。

##補足
ちなみに、positionを使う場合は、
CSSで位置を設定しないと子要素が浮いた状態になり、
下の要素が上に上がって来るので重なったようになります。
※[background-image](https://developer.mozilla.org/ja/docs/Web/CSS/background-image)のように書いただけでは初めから重ねて表示してくれませんよ！ということ。

```style.css
.info {
  position:relative
}

.text {
  position: absolute;
  /* top: 40%; */
}

.info img {
  width: 100%;
}
```
![スクリーンショット 2020-12-13 15.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/950869/450a2865-08e7-d020-f378-6d728a967f4f.png)

#以上

もし知識齟齬があったり気になる部分がある場合はコメントで教えてください。
以上、初学者同士頑張れるきっかけになれれば幸いです。
PHPカンファレンス2020聴講メモ

忘備録がてら簡単な感想と資料リンク

## PHPの今とこれから <br> PHP 8.0: A new version, a new era
PHP 8.0の新機能や変更点の紹介。
JITはWeb開発でIOがボトルネックなので影響は小さそうだが、適用分野の拡大に役立ちそう。
目先ではUnion型とヌルセーフ演算子、match()でかなり仕事が楽になるため何とか8.0にアップグレードしていきたい。
(breaking changesもあるけどこれで引っかかるコードはまず反省したほうが良い)
一番はPHP開発陣の紹介で、あまり知る機会が無いので新鮮で良かった。

https://fortee.jp/phpcon-2020/proposal/d61c47b7-04b5-4f07-8203-039796f09c32
https://www.slideshare.net/hirokawa/php2020-240022360

https://fortee.jp/phpcon-2020/proposal/c2e84390-83a9-43b5-8f6f-8ed806400891
https://slides.com/carusogabriel/php8-en



## DNS改ざん検知ツールの実装とDNSパケットの世界
DNSハイジャックと、対策が難しいので監視する[NSchecker](https://github.com/ichikaway/nschecker)を作られたというセッション。
また後半はDNSの仕組みやパケット構造について。
何となくで理解していたところがあるが、しっかり説明頂いて大変勉強になった。
完全に防ぐのはかなり難しく、NScheckerは実際使ったほうが良さそう。
https://fortee.jp/phpcon-2020/proposal/42374b41-e742-4c79-be9d-42cfb1763c89
https://docs.google.com/presentation/d/1DvrP9tOLvgSeoGynkNt0U8hRqvfZxBtxa0a6wRA8XuE/edit#slide=id.p



## CakePHPで学ぶDIコンテナ
DI、DIコンテナおよびCakePHPでの取り込み方についてのセッション。
大変わかりやすく、CakePHPでも簡単に採用できそう。
問題はCakeのアップデートだけど、後述のRectorで進めて行きたい。
https://fortee.jp/phpcon-2020/proposal/48c5bea5-2b1d-43bd-b8dd-50c4724cf787
https://speakerdeck.com/itosho525/learn-a-di-container-through-cakephp


## Service communication re:Born
APIでのメッセージングについて。個別に送るよりStreamingでのpub/subモデルのほうが良いというお話(apache kafka等)。
メッセージ数も減るし、再開やデバッグも楽。確かに真面目に作るならこのモデルのほうが良さそう。
現状API開発やってないものの、そろそろ必要かと考えていた所なので大変役に立った。
https://fortee.jp/phpcon-2020/proposal/4cd41f42-219c-4653-a862-6b372df1e52e
https://drive.google.com/file/d/1E9ywciK0mmfBIbC22znjN4JrEuSjx2Py/view


## Functional Programming in PHP
関数型プログラミングをPHPでやるという話。
全然知らないので大変勉強になった。Monadとか用語レベルで知識足りないが
immutableにするため毎回cloneするというのは特別関数型と言わない世界でも採用されている訳で、
直接使わなくとも基本的な知識として知っておいた方が良さそう。
https://fortee.jp/phpcon-2020/proposal/4cd41f42-219c-4653-a862-6b372df1e52e
https://speakerdeck.com/ace411/functional-programming-in-php-php-conference-japan-2020

## その他 Rector
資料探しにディスコ覗いてたら見つけた良い情報。
[Rector](https://github.com/rectorphp/rector) がコードのアップグレードに役に立ちそう。
PHPのバージョンアップ、FWのバージョンアップで修正必要な箇所を洗い出し、修正してくれる。
勿論主導で直した方が良い所もあるだろうが、スクリーニングを一気にできるのはそれだけでも価値がある。
pipenvを用いた開発について少し理解できたのでまとめてみた 

## 前置き
初投稿です。
読みにくいかもしれませんが、多目に見てもらえますと幸いです。

## Pipenvとは
Pythonのパッケージ管理ツールです。
Pipfile単位で仮想環境でパッケージを管理できます。
そのため、ディレクトリ単位でのパッケージ管理が可能となります。

## インストール方法
pipでインストールできます。

```
pip install pipenv
```

## 仮想環境構築
作業ディレクトリに移動して、下記コマンドで仮想環境に入る

```
pipenv shell
```

この時以下のように、(現在のディレクトリ+ hash値?)ディレクトリ
のような表示になっていればOK

```
(myblog-HGUKDeGQ) D:\workspace\django_app\myblog>
```

この時```Pipfile```というものが生成される
仮想環境にてpipでパッケージをインストールする(pandasの例)

```
(myblog-HGUKDeGQ)pip install pandas
```

パッケージをインストールすると```Pipfile.lock```が生成される
仮想環境を抜けるときは```exit```で抜ける

ここで重要なのは仮想環境でインストールした環境はローカル環境には反映されないということ
なので、ローカル```pip freeze```を打ってもpandasはインストールされていない
(だからこそ仮想環境なのでは、というツッコミはなしでお願いします。。。)

## 仮想環境実行
仮想環境実行方法は仮想環境に入って実行してもいいですが、ローカル環境では以下で実行できます。

```
pipenv install python <実行ファイル>
```

## 実行環境の移行
pipenvを使うとパッケージの依存関係をあまり気にすることなく、他環境に移行することが出来ます。
pythonはパッケージの依存関係が結構あると思いますので、こちらが本命の使い方のような気がします。

Pipfile,Pipfile.lockを格納したディレクトリで下記を実行。

```
pipenv install
```
つまりGitにてPipfile,Pipfile.lockとスクリプトを管理しておけば、
簡単に環境の再現ができるわけです。


## あとがき
他色々あると思いますが、またの記事で投稿しようと思います。
初めてのQiitaの投稿でしたが、思いのほか難しかったです。
分かりやすい記事を書けるように頑張ります！！
アラフォーポスドクが民間企業へ転職するまでのお話


#はじめに
私は長年ポスドクとして機械学習を研究してきましたが，数ヶ月前に民間企業に転職してキャリアチェンジしました．アラフォーかつ民間企業で働いた経験がほとんどなかったため転職活動は苦戦しましたが，AIブームに便乗にしてなんとか専門性を活かせる企業に就職することができました．
ポスドクで民間企業へのキャリアチェンジを考えている方の参考になればいいなと思い，転職活動の内容，感じたこと，反省点等をまとめました．なお，自慢できる経験ではないので完全に匿名性を確保したいと考えています．そのためあえて具体的な表現を使っておりません．恐縮ですがご了承ください．

#転職に至った経緯
私は研究者になって自分の好きな研究を行うために大学院に入り学位（博士号）を取得しました．ポスドクになってしばらくは好きな研究をやれていたのですが，次第にそうではなくなり自分のやりたい研究から大きく離れた業務をやるようになりました．アカデミア(日本の)に対する魅力が薄れ，同時に，アカデミアの外の世界に対する興味が強くなったため，民間企業に転職することにしました．

#転職活動の流れ

転職エージェントに登録し人気企業を中心にいろんな企業に応募しましたが，多くは書類選考で落とされました．いくつかの企業は面接まで進みましたが，マッチングしないということで不採用となりました．面接に呼んでいただいた企業は大学等での研究経験をある程度評価していただいた印象でしたが，多くの企業はそうではない印象でした．

転職活動をはじめてから数ヶ月間，採用が決まらず苦戦していたのですが，データサイエンティストやデータサイエンスに興味のある人が集まるオンラインコミュニティ（[データラーニングギルド]( https://data-learning.com/guild)）が縁で現在の会社に応募することになり，採用が決まりました．現在の会社は社員を大事にする会社であり，志向性も非常にマッチしているため，素晴らしい会社に入社することができたと思っています．

#転職活動で苦戦した理由

なかなか採用が決まらなかったと理由としては,以下の３つがあると考えています．
1. アラフォーであること
2. 民間企業での就業経験が少ないこと
3. マネージメント経験（プロジェクトリーダー等）がないこと

1.に関しては選考過程で直接指摘されたわけでないのですが，状況等から年齢フィルターを感じることはありました．有名なGoogleのデータサイエンティストTJOさんもポスドクから転身された方ですが，私よりずいぶん早い30代半ばでポスドクから民間企業に移られています．

２．はR&Dを除くと言うまでもないことだと思います．ただし，面接まで進んだ企業では，R&Dの部門でなくても大学等での研究経験を十分に評価していただけていたようです．R&D以外でも，ポスドクでの研究経験を高く評価していただける企業はそれなりにあるようです．

３．に関しては，一般的な話だと思いますが，アラフォーにもなるとマネージメントを期待されます．私はプレイヤーを希望しているが応募先の企業はマネージャーとして採用したいというようなミスマッチが発生することがいくつかありました．


#やっておいてよかったこと（転職に役立ったこと）

* Pythonプログラミング（転職に備えた技術習得）
転職活動を始める一年以上前からキャリアチェンジに備えてPythonを業務で使用するようにしました．それまではRを使っていましたが，企業のデータ分析案件はほとんどPythonが使用されるときいたので，RからPythonに切り替えてPythonの実務経験を積みました．Pythonの実務経験がなければ転職活動はより苦戦していたと思います．また，技術習得の意欲のアピールにもつながったと思っています．

* オンラインコミュニティ（[データラーニングギルド]( https://data-learning.com/guild)）に入会
データラーニングギルドには，企業でデータ分析に関する業務を行っている方が多数在籍されていますので，いろんな相談，情報交換を行うことができ，ネットでは入手できない現場の情報等を得ることができました．同時に一人で悩まなくていいという安心感を得ることができ，メンタルにもいい影響を受けました．データサイエンティストへのキャリア支援も行われており，私も相談にのっていただきました．幅広い業種を扱う一般的なエージェントと異なり，データサイエンティストとして活躍してこられた方に相談に乗っていただけるので，具体的で本質的なアドバイスをいただいたり，自分に適した求人を紹介していただき，非常に心強く感じました．最終的に，このコミュニティ内で現在の会社に応募するきっかけをいただき，採用に至ることができました．

* 論文執筆や学会発表
　これらは研究者の仕事で必須のアウトプットですが，自分が上げた成果の客観的な証拠となりますので，企業の採用においても評価されると思います．また，論文執筆と学会発表を通じて習得したプレゼンテーション能力や文章力は採用試験や入社後の業務で必ず役立ちます．要するに，研究者としてしっかり成果を出すことが企業への転職おいても重要だと思います． 

#転職のためにやっておくべきだったこと

* 研究成果をソフトウェアに実装
研究成果を学会で発表したり論文にまとめたりして終わるのではなく，ソフトウェアとして実装し，同分野の研究者に提供したり一般公開するべきだったと思っています．それにより，ソフトウェア開発の実績と証拠ができれるので，採用での評価はより上がったのではないかと思っています．また，問題提起ー＞解決アルゴリズム構築―＞プレゼンー＞システム実装　を一通りやってきましたという総合力のアピールにも繋がったと思います．

* SQLの習得
データ分析の業務ではSQLを使うことが多く，ほとんど必須の技術です．採用試験にSQLの問題がでる企業もありました．研究でSQLを使うことはなかったので，SQLの資格を取っておくと良かったのかなと思っています．

* 民間企業との共同研究
雇われポスドクには難しいと思うのですが，企業の方と積極的に共同研究を行い，しっかり成果を上げれば，そこでできた人脈が採用につながる可能性もありますし，企業でも成果をあげられるという印象を企業の採用側に与えることができるのではないかと思います．

# おわりに（ポスドクの方へ向けて）

以上，私の転職活動を偏った視点から振り返ってみました．参考になるような情報を提供できたかどうか不安ですが，いかがでしたでしょうか？
私の場合は，専門分野が社会で重要視されている技術だったので，アラフォーになるまでダラダラとポスドクを続けていましたが企業に就職できました．史上空前のAIブームに便乗しできたおかげであり，非常に運が良かったと思っています．ですので，偉そうなことは何一つ言えませんが，最後にささやかな提案を１つだけ．

ポスドクで将来に強い不安を感じている方は，副業をやったりプログラミングを勉強したりするなど稼げる技術を身に着けてはいかがでしょうか．精神的に余裕ができて研究にもいい影響がでると思います．

最後まで読んでいただきありがとうございました．
【Rails】Ratyを用いた星評価機能のテスト【Rspec】

## はじめに
Ratyを用いて評価機能を実装したのですが、結合テスト実行時に手間取ったので記事として残しておきます。
知っていればなんということはないのですが、初学者の方の助けになれば幸いです。

## 評価機能
<img width="300" alt="Screen Shot 2020-12-13 at 17.39.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901009/12774010-475a-a496-fcc2-55d8748b5614.png">
[Raty](https://github.com/wbotelhos/raty)を用いて実装された評価機能。実装方法については割愛しますが最後に参考になりそうな記事を紹介しているのでトライしてみたい方はぜひ。

それぞれの項目のいずれかの星マークをクリックする動作をさせたいので検証ツールを使って要素をみていきます。

## 検証
<img width="500" alt="Screen Shot 2020-12-13 at 17.40.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901009/6feba64e-ef71-58c6-4dd1-b7d936253a45.png">
なるほどimgタグを見つけてクリックしてあげればいいんですね。

```ruby:rspec.rb
find("img").click
```

## エラー
<img width="500" alt="Screen Shot 2020-12-13 at 17.55.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/901009/e2770c04-9fbe-41ab-2235-6a9aea4b3839.png">
当たり前ですが「どのimgなのかハッキリしろ」と怒られました。
imgタグは他にも存在するのでどの要素なのかプログラムが判別できるようにしてあげないといけません。

## 正しいコード

```ruby:rspec.rb
find('#taste_star').find("img[alt='5']").click
```
最終的にこのコードでテストをクリアできました◎ １つずつ見ていきましょう。
### findの重ね使い
普段それぞれの要素に一意のidを指定することが多く一発で要素を拾えることばかりだったので個人的に盲点だったのですが、findは重ねて使えます。
まずは親要素に指定しているid="taste_star"を拾うことでその後ろに続くimgタグの該当範囲を絞り込めます。
### 要素[属性]
まだ同一の親要素の中にimgタグが複数存在しているので個別に振り分けられているalt属性を利用します。
属性を指定したい場合は角カッコで括ってあげればOKです。

### click
あとは画像をクリックさせたら完成です！

ちなみにclick_onを使ってリンクやボタンをクリックさせることもできますが、画像の場合はalt属性を指定します。今回の場合はalt属性の値が一意でないのでエラーが出ると思います。

## 最後に
記事に纏めながら改めて簡単なところで躓いてしまったなと反省しました。

## 参考
[jquery.raty rails導入](https://qiita.com/Seungbaek_Seo/items/dcc38e8b23def28b8f1a)
[Railsで「Raty」を使った星機能をつける](https://qiita.com/busitora2/items/5b59d1ea9e90c1b016b4)
[使えるRSpec入門・その4「どんなブラウザ操作も自由自在！逆引きCapybara大辞典」](https://qiita.com/jnchito/items/607f956263c38a5fec24)
Swiftエラーでtry使えって言われるのはどんなとき？

swiftエラーでtry使えって言われたけど どんなときに言われるの？　guardだけじゃダメなの？
と疑問に思っていたが単純なことだったので備忘録として記録しておく。

## 最初に結論　
定義メソッドに「throws」が記述されていた場合は、tryでエラーを受け取る処理を書かなければいけない。

## 例文
```swift
struct KeychainManager {
    
    private static let keychain = Keychain(service: "com.example.github-token")
    private static let tokenKey: String = "token"

    static func getToken() -> String {
        // 下記だとエラーになる
        guard let token = keychain.get(tokenKey) else { return "" }
        return token
    }
```
エラー文

```
Call can throw, but it is not marked with 'try' and the error is not handled
```

### 原因
```swift:KeychainAccess
public func get(_ key: String, ignoringAttributeSynchronizable: Bool = true) throws -> String?
```
KeychainAccessのgetメソッドに定義ジャンプしてみると throwsという表記が。
つまり投げられたエラーを受け取る対処を書かなかればいけない。

### 対応
do-catch構文にしたところ無事エラーが消えた。
（do-catchを使わなくてもtry?だけで済ますこともできるが、失敗をハンドリングしたほうがいいとのこと。）

```swift
static func getToken() -> String {
        do {
            guard let token = try keychain.get(tokenKey) else { return "" }
            return token
        } catch let error {
            print(error)
            return("")
        }
    }
```
分割代入


#分割代入とはなにか
>分割代入 (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。
[docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)

###オブジェクトの分割代入だとこんな感じになる。
```javascript
const profile = {
    age: 13,
    name: 'Taro',
}

const {age, name} = profile;
console.log(age) // 13
console.log(name) // Taro
```
#こんなもん使うの？
分割代入を知った時に初めに抱いた感想は「いつ使うのさ」でした。
しかし、reactを使用しているプロジェクトで働き始めると毎日のように使うようになっていました。

こんな感じで。

```react
// propsでageとnameを受け取るコンポーネント
const Profile = props => {
    const {age, name} = props;
    return <div>{`${name}は${age}さいです。`}</div>
}
```
引数の段階で分割代入を行うこともできるので、こうやって書くことが多いです↓

```react
// propsでageとnameを受け取るコンポーネント
const Profile = {age, name} => {
    return <div>{`${name}は${age}さいです。`}</div>
}
```
[Python] 01-BFS　ARC005C

#[ARC005C](https://atcoder.jp/contests/arc005/tasks/arc005_3)

#[01-BFSのちょっと丁寧な解説](https://betrue12.hateblo.jp/entry/2018/12/08/000020)
**辺の長さが "0" または "1" である有向グラフにおいて、ある1つの始点から全頂点への最短路の長さを効率的な計算時間で求めるアルゴリズム**であり、実装には両端キューがよく使われる。
一般的な辺の長さの場合は、ダイクストラ法が適しており、優先度付きキューがよく使われる。
#解法
「距離」を「移動コスト」再定義して「通路の移動コストは０」「壁の移動コストは１」とすれば「壁を最大二回移動してゴールに到達できるか」が算出できる。01-BFSの計算量は頂点数を$V$、辺数を$E$とすると$O(V+E)$となり、通常のBFSと同等となる。
Python3でACするが、PyPy3では MLE (Memory Limit Exceeded)となる。

```python:サンプルコード
# 両端キュー(double-ended queue)インポート
from collections import deque
inf=10**9
h,w=map(int,input().split())
s=[input()for i in range(h)]
for i in range(h):
	for j in range(w):
                # スタート地点読込
		if s[i][j]=="s":
			sx=i
			sy=j
                # ゴール地点読込
		elif s[i][j]=="g":
			gx=i
			gy=j
deq=deque([(sx,sy)])            # スタート地点から01-BFS開始
dis=[[inf]*w for i in range(h)] # 距離は無限遠で初期化
dis[sx][sy]=0
d=[(1,0),(-1,0),(0,1),(0,-1)]   # 上下左右
# 01-BFS
while deq:
        # 左端から探索地を取り出す
	x,y=deq.popleft()
	for dx,dy in d:
		if 0<=x+dx<h and 0<=y+dy<w and dis[x+dx][y+dy]==inf: # 境界条件
			if s[x+dx][y+dy]=="#":
				dis[x+dx][y+dy]=dis[x][y]+1
				# 右端に探索地を追加
				deq.append((x+dx,y+dy))
			else:
				dis[x+dx][y+dy]=dis[x][y]
				# 左端に探索地を追加
				deq.appendleft((x+dx,y+dy))
print("YES" if dis[gx][gy]<=2 else "NO")
```
README.org

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 


# 第9回<span class="timestamp-wrapper"><span class="timestamp">&lt;2020-11-18 水&gt;</span></span>

1.  [assert\_equal](https://qiita.com/hiroki0733/private/660f8509151cf00be124)


# equation<span class="timestamp-wrapper"><span class="timestamp">&lt;2020-10-28 水&gt;</span></span>

$$\frac{1}{4}$$


# qiita\_links<span class="timestamp-wrapper"><span class="timestamp">&lt;2020-10-14 水&gt;</span></span>

1.  [README.org](https://qiita.com/hiroki0733/items/030d01f10b1c0e146090)



------
 - **source** ~/Lecture/Fall2020/M-ScaleSimu/grad_members_20f/members/hiroki0733/README.org
rubyXLで「行と列の固定表示」と「入力規則」を設定する


## コード

```ruby
require 'rubyXL'
require 'rubyXL/convenience_methods'

workbook = RubyXL::Workbook.new
sheet = workbook.first

sheet.add_cell(0, 0, 'ID')
sheet.add_cell(0, 1, '名称')
sheet.add_cell(0, 2, '状態')
sheet.add_cell(1, 0, 1)
sheet.add_cell(1, 1, 'foo')
sheet.add_cell(1, 2, '済')
sheet.add_cell(2, 0, 2)
sheet.add_cell(2, 1, 'bar')
sheet.add_cell(2, 2, '未')

# 上から1行と左から2列を固定表示
view = RubyXL::WorksheetView.new
view.pane = RubyXL::Pane.new(
  top_left_cell: RubyXL::Reference.new(1, 2),
  y_split: 1,
  x_split: 2,
  state: 'frozenSplit',
  activePane: 'bottomRight'
)
views = RubyXL::WorksheetViews.new
views << view
sheet.sheet_views = views

# 入力規則を設定
formula = RubyXL::Formula.new(expression: "\"未,済\"")
range = RubyXL::Reference.new(1, 1048575, 2, 2) # 入力規則を設定する範囲。R2C3:R1048576C3
validation = RubyXL::DataValidation.new(
  sqref: range,
  formula1: formula,
  type: 'list',             # 他に none, whole, decimal, date, time, textLength, custom。デフォルトはnone(すべての値)
  error_style: 'stop',      # 他に warning, information。デフォルトはstop(停止)
  allow_blank: true,        # trueで「空白を無視する」がオン。デフォルトはfalse
  show_error_message: true, # trueで「無効なデータが入力されたらエラーメッセージを表示する」がオン。デフォルトはfalse
  show_drop_down: false     # 何故かfalseで「ドロップダウンリストから選択する」がオン。デフォルトはfalse
)
validations = RubyXL::DataValidations.new
validations << validation
sheet.data_validations = validations

workbook.write('out.xlsx')
```

`show_drop_down` のtrue/falseが何故か意味的に逆なので注意。

## 結果

画像は Microsoft Excel for Mac での結果。

![スクリーンショット 2020-12-13 18.07.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81176/ab888672-63fd-357b-ac35-35adcefa6bda.png)


## 参照
- [rubyXL公式wiki](https://github.com/weshatheleopard/rubyXL/wiki/How-to#create-a-frozen-split-pane-at-row-column)
- https://github.com/weshatheleopard/rubyXL/issues/224#issuecomment-287355611
- http://www.datypic.com/sc/ooxml/e-ssml_dataValidation-1.html
    - その他の項目(エラー時のメッセージなど)の設定方法もここを読めば分かります。
機械学習による火成岩の判定①

#開発しようとした動機
理科に関係することで、何かプログラミングをしようと考えた。
中学1年生で習った火成岩は、教科書から色や結晶の形状に特徴があるため、簡単に判定できると考えた。
最初は、プログラムで判定する方法を取ろうと考えたが、機械学習にもチャレンジしようと試みた。これまでプログラミングは数多くしてきたが、機械学習はほとんどしたことがない。
機械学習というと結構難しい数学が使われて、難しいイメージがあるが、実際はそこまででもなく簡単にできるらしい。（機械学習を理解するには高校レベルもしくは大学レベルの数学が使えなくてはいけないらしい。）


#準備するもの
##ハードウェア
###	パソコン
2011 年ぐらいから売られている、特殊な計算ができるCPU命令に対応しているCPUを搭載しているもの限る。Intel Celeron、 Intel　PentiumとIntel tomなどの低価格CPUはできない。
（nvidiaのＧＰＵが入っていたら、機械学習が高速化するらしい）

##ソフトウエア
###	Python（パイソン）
世界でよく使われるプログラミング言語の1つ。最近は機械学習でよく使われる。
###	Numpy（ナムパイ）
pythonの機械学習の計算によく使われる拡張機能
###	Keras(ケラス)
簡単に画像分類の機械学習をしてくれるTensorflowの拡張機能
###	Matplotlib(マットプロットリブ)　
グラフがとても簡単にできる拡張機能
###	Tensorflow　(テンソルフロー, テンサーフロー)
googleが開発しているオープンソースの機械学習用ライブラリ
###	Tkinter （ティンキータ）
ウィンドウを作ったりする拡張機能
###	Tensorflow.js　（テンソルフロージェイエス）
ディープラーニングをwebブラウザでも実行可能にするもの
###	Bootstrap （ブートストラップ）
Webデザインでよく使われるライブラリの一つ

#開発方針
###①	機械学習でプログラミング
機械学習でよく使われる、Pythonというプログラミング言語を使って作ってみる。
ちょっと難易度が上がるが、機械学習で分析する。機械学習のデータ画像を10枚ぐらいダウンロードして機械学習させる。

###②	完成したら、アプリにする。
もしできたらAndroidなどのスマホでも動かしてみたい。

###③機械学習を使わないプログラムでも挑戦してみる
機械学習を使わない方法でも、岩石の色から種類を判別するプログラムを作る色の特徴から、判別する方法で、画像を分別させてみる。
Databricks（Azure Databricks）でGithub経由でノートブックを共有する方法

## 概要
DatabricksではノートブックをHTMLでエクスポートすることが可能であり、GitHub Pagesでの共有がいい感じだったの共有します。Databricksには複数のノートブックを単一ページで表示可能なHTMLを出力可能なため、Github Pagesに登録するだけ綺麗なサイトを作れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/4481222a-b936-ee1a-e0d1-03b6582287db.png)
引用元：[docs - Databricks (manabian-.github.io)](https://manabian-.github.io/databricks-notebook-test/#000_コンテンツについて/000_コンテンツ.html)

### Databricksとは
Sparkをベースとした、Python・R・Scalaを動作可能な統合データ分析サービスです。実質的に無制限の拡張が可能であり、エンタープライズでのセキュリティ要件も満たせるサービスです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/f6e1a563-c095-db3a-70c0-020cc4d38883.png)
引用元：[Databricks - 統合データ分析プラットフォーム](https://databricks.com/jp/product/unified-data-analytics-platform)

開発もNotebook上で実行するため、Jupyteを利用している方にはスムーズな利用開始が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ecfb833c-8742-db3a-4203-ffb83ca72d8c.png)
引用元：[コラボレーション型 Notebook - Databricks](https://databricks.com/jp/product/collaborative-notebooks)

Databricks Community　Editionという無償で利用続けられる環境が提供されており、学習環境としては最適です。Databricks Community　Editionの申し込み方法については、下記の記事が参考になります。

- [Databricks Community Edition で Notebook を立ち上げる - Qiita](https://qiita.com/Catetin0310/items/252582f4f2bd8231ebf4)

### GitHub Pagesとは
Github上のコンテンツを、簡単な手順で、静的サイトとして公開できるサービスです。ブログ投稿を実施している方もけっこういらっしゃるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/041c490c-f630-9b9a-a63a-91330cf9aa2f.png)
引用元：[GitHub Pages について - GitHub Docs](https://docs.github.com/ja/free-pro-team@latest/github/working-with-github-pages/about-github-pages)


## 手順
### 1. Databricksにてファイルをエクスポートする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/2bf1c396-3241-0286-f3fa-212242e87f43.png)

### 2. GitHubにコードをプッシュ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/dd4ac24d-050f-bf24-b027-5573978523d1.png)

### 3. GitHubのレポジトリーの"Setting"に移動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/2ad628bc-7e45-5b65-a62b-684896207ff8.png)

### 4. "GitHub Pages"にて公開するブランチ等を指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/67eb41ff-54b8-8adf-d4ae-6b113cfa9e20.png)

### 5. 表示されたURLに接続して表示確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/ca941da6-59f5-fd29-18f1-6e3fcb72c5e2.png)

リンクは下記です。

[docs - Databricks (manabian-.github.io)](https://manabian-.github.io/databricks-notebook-test/#000_コンテンツについて/000_コンテンツ.html)

## 課題について
### 動画を表示できないこと
Databricks上で動画を表示可能なのですが、HTMLで出力すると表示できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/7d32027f-41db-6040-ebab-89e8880eedb6.png)

### Datbricskにてインポートができないこと
GitHubからHTMLファイルをダウンロードしてもらってインポートしてもらうのがよさそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/4dc54749-19d9-febc-92d5-9ff6f3860190.png)

### SlideShareのスライドのページ移動ができないこと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/add2f589-1df6-4f13-7899-9beb254ebb8f.png)
コマンドでGitHub連携/ git stashシンプルな使い方

連携するたびにやり方を忘れるので備忘録として記録しておく。git stashはおまけ。

## GitHub連携の手順

アカウント名とメールアドレスを登録

```
git config --global user.name "GitHubアカウント名"
```

```
git config --global user.email "登録メールアドレス"
```

登録されているか確認

```
git config --list
```
Gitでリポジトリを作成

```
git init
```

GitHubと連携

```
git remote add origin GitHubリポジトリのURL
```

## リモートリポジトリの変更
新しいリモートURLに変更する

```
git remote set-url origin 新しいURL
```
変更したリモートURLを確認する

```
git remote -v
```


## git 一時退避
前回commitした時点から変更した差分を一時的に保存し退避する（名前不要のときはgit stash のみで可）

```
git stash save "save名"
```

これまで退避させた変更の一覧表示

```
git stash list
```

退避させていた差分を再び反映させる。番号はgit stash listから確認。

```
git stash apply stash@{番号}
```
みんなのラズベリーパイコンテストで「スタートダッシュ賞」を受賞した話


こんにちは。初投稿です。

この記事では、私が「みんなのラズベリーパイコンテスト」で”スタートダッシュ賞”を受賞した話をします。

Raspberry-piやラズパイコンテストに興味がある人向けに、サックと読める記事にしたので、是非最後まで読んでみて下さい。
#みんなのラズベリーパイコンテストとは
ラズパイマガジン、日経Linux、日経ソフトウエアが主催する
小型PCボードのラズパイ（Raspberry Pi）を使った作品やアイデアを募るコンテストです。

ラズパイは本当に何でもできちゃうので、何でも作れちゃいます！！

これまでの入賞作品も公式サイトで確認できるのでの下のURLから見に行ってみることをお勧めします。
　　↓↓↓
[みんなのラズパイコンテスト](https://project.nikkeibp.co.jp/pc/rpic/)
#スタートダッシュ賞とは
指定されている期日までにアイデアや作品を応募すると、

**抽選で30名にAmazonギフト券（1000円）**が貰えます。

たった30人に1000円かと思いますが、これが意外とよく当選します。

過去に私と別枠で応募した友達と同時に当選するくらいの確立です。

#おわり
今の当選確率がどのくらいかはわかりませんが、

どんな駄作でも当選すれば、**スタートダッシュ賞**を受賞したことになります。

受賞歴のあるラズパイエンジニアなってみてはいかがですか。
[H2 Console] 削除した保存済設定を元に戻す方法

# ケース
H2 Consoleで削除ボタンを押して保存済設定（**Generic H2 (Embedded)**）が消えてしまった場合に、元に戻す方法。
（私の場合データベースを削除しようとして、間違って削除ボタンを押してこうなりました...(汗)）
![H2_Console1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650537/b117d10a-24fe-b673-de9b-f0f8395cce87.png)

# 結論
設定名に「**Generic H2 (Embedded)**」を入力して「保存」ボタンを押せば復活します。
![H2_Console2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650537/a3f24101-1df2-e4eb-8125-6da2c277a7a5.png)

# おまけ
ちなみにデータベースを削除したい場合は、以下の方法でできるようです。
http://yoks.blue.coocan.jp/TechNote/H2/H2_ope2.htm
（リンク先で「**drop database**」を検索すれば該当箇所に飛べます）

-- 追記 --
・自動作成されるファイル名がリンク先のものと異なるかもしれません。
（私の場合だと`データベース名.mv.db`などが作成される）
・また`DROP ALL OBJECTS DELETE FILES;`の場合、
ファイルの削除はコマンド実行後、データベースを切断したときに行われます。
https://www.h2database.com/html/commands.html#drop_all_objects
Hubotで様々な謝り方に警察は要らないとツッコまれるbot作ってみた

この記事は、[N高等学校 (1) Advent Calendar 2020 13日目](https://qiita.com/advent-calendar/2020/n-highschool)の記事です。

どうも、N高生5期のゆういちさんです。
SNS → [GitHub](https://github.com/yuichisan171),[Twitter](https://twitter.com/yuichisan171)

アドベントカレンダーは初投稿です！
何を書こうか正直迷いましたが、昨日思いついたやつでいきたいと思います！
タイトルの通りですが、こんなbotがあると面白いかなと作ってみました。

# デモ
[![Screenshot from Gyazo](https://gyazo.com/b86133206e05915121cf1bbd6ebc445c/raw)](https://gyazo.com/b86133206e05915121cf1bbd6ebc445c)

# 作った理由
- Slackのbotで開発してみたい
- 正規表現の学習もそうだけど、もう少し馴染めるようになりたい 
- 日本人謝りすぎを解消

### この猿はだれ??
gomes(ゴメス)っていうチンパンジーです。
一昔前にフジテレビで放送された「CHIMPAN NEWS CHANNEL」の報道系のバラエティ番組をよく見てて、
このゴメスが番組の司会進行役で、チンパンジーが番組スタッフの謝罪に対してツッコミをするというシーンを思い出したことからこのbotを実現してみました。
(実際は違うチンパンジーが突っ込んでたかもです。)

# 書いてみた

```police.js
'use strict';
module.exports = (robot) => {
  robot.hear(/(申し訳(ありません|ございません|ない))/i, msg => {
    msg.send(` < ${msg.match[0]}ですむならPoliceはいらねんだよ!!`);
  });
  robot.hear(/(ごめん(ね|な|なさい|ねごめんねー)|ごめん)/i, msg => {
    msg.send(` < ${msg.match[0]}ですむならPoliceはいらねんだよ!!`);
  });
  robot.hear(/(sorry)/i, msg => {
    msg.send(` < ${msg.match[0]}ですむならPoliceはいらねんだよ!!`);
  });
  robot.hear(/(す(いません|みません|まない|まなかった|まねぇ|まん|まぬ|まんのう))/i, msg => {
    msg.send(` < ${msg.match[0]}ですむならPoliceはいらねんだよ!!`);
  });
  robot.hear(/(お詫び(申し上げます|申しあげます|致します|いたします))/i, msg => {
    msg.send(` < ${msg.match[0]}ですむならPoliceはいらねんだよ!!`);
  });
  robot.hear(/(失礼(しました|致します|致しました|いたします|いたしました)|失礼)/i, msg => {
    msg.send(` < ${msg.match[0]}ですむならPoliceはいらねんだよ!!`);
  });
  robot.hear(/(めんご|メンゴ|スマソ|さーせん|サーセン|ｻｰｾﾝ)/i, msg => {
    msg.send(` < ${msg.match[0]}ですむならPoliceはいらねんだよ!!`);
  })
  robot.hear(/(反省して(おります|います|ます|ま+[ー〜~]+す))/i, msg => {
    msg.send(` < ${msg.match[0]}ですむならPoliceはいらねんだよ!!`);
  })
};
```

特定の「すいません」とか「お詫び致します」の文字列だけ取得させるのに時間かかりましたが、
たまに2回繰り返してメッセージが返ってきたり、文字列が重複してそれぞれ違うメッセージがいくつか出てきたこともあったりしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610089/d2f39a10-8e73-6c80-2982-034586752ac4.png)

# 正規表現を可視化してみる
ただ文面だけみても正直なんて書いてあるのか分かりません。
僕もbot作るときに調べる時間はかなり要しました。

そこで、正規表現を可視化できるツール[regex-railroad-diagram](https://atom.io/packages/regex-railroad-diagram)を導入しました。

あとはその正規表現にカーソルを合わせれば自動的にダイヤグラム図が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610089/c3769f2e-d8d1-9ac2-7606-f29710c22bfe.png)

簡単に扱えそうですね！！

やり方は[https://kita-note.com/atom-package-regex-railroad-diagram](https://kita-note.com/atom-package-regex-railroad-diagram)にありますので是非ご興味ある方はやってみてください!

# 最後に
正規表現に苦手意識ある方はぜひダイヤグラムを使ったり分かりやすい記事を読んで少しずつ身につけていただけたらと思います!
bot開発は他にもLINEとGASとの連携でbot作るのもあるので、時間あったら手を付けてみたいですね。

ではまた。

# 参考記事
[基本的な正規表現一覧 | murashun.jp](https://murashun.jp/blog/20190215-01.html#chapter-1)
[Hubotの正規表現を可視化する - Qiita](https://qiita.com/kijitora-neko/items/3267e1d439bb7041c3c6)
Flutter の基本的な Widget を把握できる Widget of the Week の動画が素敵なので再生リストを作ったよ

To. この記事を読んでくれている皆さま

こんにちは。北山淳也(twitter:[@JUNKI555](https://twitter.com/JUNKI555))です。
これは Flutter Advent Calendar#2 の13日目の記事です。
普段は zenn で記事投稿をしています。
https://zenn.dev/junki555

昨日は れいさん @rei_012 の
[[Flutter]GCP構築でシンプルなストリーミング配信サービスを作成する](https://qiita.com/rei_012/items/1dd241146cc6a2b5bd44) でしたね。

## 2020/12/14 追記
- 公式の Widget of the Week の再生リストをコメントで教えてもらいました！ 笑
    - https://www.youtube.com/playlist?list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG

## 元のTL;DR
- Flutter の基本的な Widget を把握できるGoogleの Widget of the Week の動画が素敵
- 以下に再生リストを作ったので使ってください
    - なぜ公式の再生リストがないんだ……
    - Flutter Widget of the Week 再生リスト
        - https://www.youtube.com/playlist?list=PLnqBuzytjaRZlhMIU3DyTLo2-ULB3yc98
    - Flutter Widgets 101 再生リスト
        - https://youtube.com/playlist?list=PLnqBuzytjaRYBcsV0lMBONBzvVaYq0fh9
- ※古い動画はFlutterの過去のバージョンを基にしたものなので、手元で試してみておかしいな？と思う部分は最新のリファレンスを参照してみてください
    - widgets library | flutter.io
        - https://api.flutter.dev/flutter/widgets/widgets-library.html

## Widget of the Week : 古い動画もあるがとにかく視聴しやすい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51543/cd842fbe-e545-7d03-3391-b04071d36198.png)

[Google Developers の Youtubeチャンネル](https://www.youtube.com/channel/UC_x5XG1OV2P6uZZ5FSM9Ttw)では
Flutter に関する動画もいくつか投稿されていますが、
2018年末〜2019年頭ごろに 「Widget of the Week - 今週のウィジェット」として投稿されていた
`#1〜#26` までの動画が投稿されていました。
その後、[Flutter の Youtubeチャンネル](https://www.youtube.com/c/flutterdev/videos) にて
`#27` 以降が公開されています。
`#58` 以降ぐらいから動画のナンバリングはカウントされなくなっていますね……。

1回1分程度にまとまっていて、ほぼ全てのの動画に日本語字幕もついている物も多いです。
flutter.io のウィジェット説明の動画にも使われいるので
見たことある人も多いのではないでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51543/8604b643-ab2e-525c-f423-870f53a21dde.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51543/e16ff41a-bfed-5b34-bc7b-09b8f707b729.png)

なぜか公式の再生リストがなくて流し見しにくいので
今回Youtubeの再生リストにしました。よければ使ってください。

--- 

- Flutter Widget of the Week 再生リスト
  - https://www.youtube.com/playlist?list=PLnqBuzytjaRZlhMIU3DyTLo2-ULB3yc98

--- 

## Introducing Flutter Widgets 101

Flutter の Widgets に関する動画である
「Introducing Flutter Widgets 101」 としてUPされていたものリストも作りました

この動画も割と古く、日本語字幕はついていないもの、チュートリアルとしてはかなり視聴しやすいので
Flutter初心者の方は見てみると面白いです。
Youtubeの機能で英語字幕を入れるだけで十分視聴できると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51543/9cdff5cc-5e6f-0334-e3d3-d96889fb3af1.png)

--- 

- Introducing Flutter Widgets 101 再生リスト
  - https://youtube.com/playlist?list=PLnqBuzytjaRYBcsV0lMBONBzvVaYq0fh9

--- 

Youtube の再生リスト、あんまり使われないのかな……。
私は流し見するときに、結構使うのですが。

明日は @gremito さんですね！ アドベントカレンダーも中盤、楽しくなってきました。
それではみなさん、良い年末をお過ごしください。
Flutter開発で知っておくと良さそうなこと

Qiita初投稿です。Flutterでの開発歴も全然長くありません。
なので、もしどこか見解の甘いところや認識として宜しくないところなどがあったらコメントや編集リクエスト？などでご指摘お願いします。

なお、この記事はFlutterやDart始めたての方向けです。Flutterの知識をキャッチアップしている段階や開発力を上げている段階の時にお手元に置いていただければ幸いです。

#基礎的な知識
FlutterのほとんどはWidgetです。公式がそう言ってます。
Widgetを組み合わせてビューを作ります。
Widgetはぐぐるとわかりますが、それぞれドキュメントのページがあり何のためのWidgetかやどう使うのかが書いてあります。

ただ、スマホアプリやWebアプリをFlutterで作るにあたってそれだけでは知識的に足りないと思うので
基礎的な知識をつけるのにとても良かったもの、よく見に行くものをまとめます。

[A tour of the Dart language](https://dart.dev/guides/language/language-tour)
[Effective Dart](https://dart.dev/guides/language/effective-dart)
[Flutter Docs](https://flutter.dev/docs)
[Flutter Samples](https://flutter.github.io/samples/#)
↑コードもある
[Flutter 全部俺 Advent Calendar 2019](https://adventar.org/calendars/4140)
↑とにかく助かった
[Flutter公式のyoutube](https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw)
↑深くは解説してないけどざっと知るのにとても助かっている
[アーキテクチャのサンプル](https://fluttersamples.com/)

以下は上のものも含め他の方が素晴らしい記事を書かれているので割愛。
リンクでないものは検索してみてください。
・StatelessWidget、StatefulWidget（、Provider）
・BuildContext、InheritedWidget、Provider
・Widgetツリー、Elementツリーなど
・[リアクティブプログラミング](https://en.wikipedia.org/wiki/Reactive_programming)、StreamBuilder、StreamProvider、Consumer、[rxdart](https://github.com/ReactiveX/rxdart)、[Event Bus](https://pub.dev/packages/event_bus)


##Flutterのchannel、バージョン
Channelにはmaster、dev、beta、stableがあります。
それぞれの存在意義はこちらに書いてあります。
[Flutter build release channels](https://github.com/flutter/flutter/wiki/Flutter-build-release-channels)
stableが推奨されてますが、状況によってはmasterやdevでないと動かないときがある（stableやbetaでおかしいときがあったらmasterやdevで試してみるのも一案）。

バージョンを戻す方法は昔flutter versionというコマンドがあり環境によっては使えなくもないが、channelがunknownになるはず。
fvmという非公式のツールも動作として良かった！という記憶も特にない（自分はその時channelとバージョンを特定したかったので）。
channelはgitのブランチみたいなので、前のバージョンに戻したいときはgit reset hard [コミットのハッシュ値やバージョン]で戻すのが得策っぽい。


#ツール
[DevTools](https://flutter.dev/docs/development/tools/devtools/overview)
新しめのバージョンだとそこまで試してないのでわかりませんが、
コマンドで叩いて起動するもので2パターンくらい？見られないときがあった。
profileビルドだとDevToolsが提供するものが全て見られるよう。
releasaeビルドだと見られなかった（2パターンのうちのひとつ）

通常のJavaScriptを使ったフロントエンド開発だとデベロッパーツールで表示されたものを分析しながら開発できるが、Flutterではその役割するものはないよう？
（Flutter webの話です。あったら教えてほしい、というかデベロッパーツールで検証できてくれ）
個人的にWidgetツリーが可視化されるのが大変嬉しかった。

#Flutterを通して感じたこと
もともとそうなのかもしれませんが
今後個人がプログラミング言語を書く、選択するときの基準はより多くの目的を達成できる言語かそうでない何か特定の目的で使うネイティブな言語か（それともネイティブなものを補完したり改良した言語か）、になっていくのだなと実感しました。


#まとめ
手抜き記事になってしまいました。
タイトルの抽象度があるわりにそこまで網羅的に自分がDartとFlutterについて理解や把握をしていないことを痛感してしまいました。
Qiitaでは丁寧語のほうがいいかそうじゃないのかわかりかねました。
【FileMaker】登録したキーチェーン情報はどこに？

FileMaker Goでキーチェーンにログイン情報を登録して、iOSの認証で該当のFileMakerアプリにログインする[方法](https://qiita.com/tyuma/items/9338ed490cc335a3b605)をこないだ紹介しました。

この時、ログイン情報はどこで管理されているのでしょうか？

答えは、ここです。
![IMG_3424.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/524c5441-6707-7cbf-6da4-6629dbc31550.png)

# キーチェーンまでの動き
どんな感じで移動するか、動画で見てみましょう。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今日はこんな動作の記事を挙げます。<a href="https://twitter.com/hashtag/FileMaker?src=hash&amp;ref_src=twsrc%5Etfw">#FileMaker</a> <a href="https://twitter.com/hashtag/FileMakerGo?src=hash&amp;ref_src=twsrc%5Etfw">#FileMakerGo</a> <a href="https://t.co/mMIZrgsYHt">pic.twitter.com/mMIZrgsYHt</a></p>&mdash; Guppy Web Service (@GuppyWebService) <a href="https://twitter.com/GuppyWebService/status/1338042000738635777?ref_src=twsrc%5Etfw">December 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

図にすると、こんな感じです。
![スクリーンショット 2020-12-13 17.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/1e1b0578-66bb-b126-bbbf-a0735353e694.png)

もちろんアカウント情報は他の人にみられては困るので、キーチェーンの管理ページに移動する際にiOS認証をして、認証がOKになったら管理画面の操作ができるようになります。

# iOS認証に失敗したら。。。
見れません。
![IMG_3425.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/53088cf4-4524-934e-6fb2-481ffea4193e.png)
メガネをしてiOS認証をしている場合は、メガネを外した顔での認証に失敗します。。。
老眼の場合は、注意してください。
いちいちかけたり外したり、、、とめんどくさいですが、情報管理のためには仕方ないです。

# 削除したい。。。
配置換えして違う部署に来たからもうこのアプリを使わない、などでキーチェーンから削除したい場合もあります。
削除できます。
iOS操作と同じく、左にシュッとスライドすると、削除ボタンが現れ、タップすると削除が行われます。
![IMG_3427.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60538/5907466e-b8e1-fef3-3b12-b943bcd2e246.png)

この辺も、iOSならではの操作がFileMaker　Goでも当たり前に使えますね。
(100%子会社だから当たり前っちゃ当たり前ですが）

なんとなく、ログインが簡単にできるからとキーチェーンに登録してしまいますが、どこで管理されて、どういう取り扱いができるか、というのも事前に知っておくとお客さまに機能を紹介する時にドヤ顔で流暢に喋れると思います。
では！
競技プログラミング 日記 python

つよつよエンジニアもすなる競技プログラミングといふものをよわよわエンジニアもしてみむとてするなり。


## [AtCoder Beginner Contest 183](https://atcoder.jp/contests/abc183)

- A - ReLU

入力が負の値なら0を、正の値ならそのあたりを返す関数を実装する。

```py
N = int(input())

def ReLU(x):
   if x > 0:
       return x
   else:
       return 0
       
print(ReLU(N))
```

- B - Billiards

x軸に跳ね返してビリヤードを行う。受験でよくある問題なので懐かしい。目的の場所をx軸対象に移動させた地点にめがけて弾を打つ。その際のx軸との交点が答えとなる。
相似を考えて内分点を計算すると良い感じな気がした

```py
sx, sy, gx, gy = map(int, input().split())

print(float((gy * sx + sy * gx) / (sy + gy)))
```

- C - Travel

> N個の都市があり、すべての都市に一度ずつ訪れる場合時間がちょうどKになる経路は何個あるか

Nがたかだか8なので、経路の組み合わせは8!通り程度。全探索で問題なさそう。

組み合わせをすべて書き出すのは、pythonなら `itertools` を使うと簡単に書ける


```
0 1 10 100
1 0 20 200
10 20 0 300
100 200 300 0
```

のような行列をinputで受け取るのは、各列を配列に変換したものを行分回せばいいので

```code.py
N, K = map(int, input().split())

matrix = [input().split() for _ in range(N)]
print(*matrix, sep='\n')
```

```output.py
['0', '1', '10', '100']
['1', '0', '20', '200']
['10', '20', '0', '300']
['100', '200', '300', '0']
```

回答はこんな感じ。もっとうまく書ける気がする

```
import itertools

N, K = map(int, input().split())

matrix = [list(map(int, input().split())) for _ in range(N)]
ans =0
# 1からスタートして1に変えるので、1を外した順列組み合わせを求めたのち、都市1を挿入する（index は 0）
for v in itertools.permutations(range(1, N)):
    total_time = 0
    keiro = list(v)
    keiro.append(0)
    keiro.insert(0, 0)
    for i in range(len(keiro) -1):
        total_time += matrix[keiro[i]][keiro[i+1]]
    if total_time == K:
        ans += 1
print(ans)
```

- D - Water Heater

時間の長さ分の配列を用意、人に対してループしながら利用時間帯に利用時間を足していく。Wを超える時間があればアウト。

と思って実装したがTLE

```py
max_time = 2 * 10 ** 5
t = [0 for _ in range(max_time)]

n, w = map(int, input().split())
ans = 'Yes'
for i in range(n):
    start, end, usage = map(int, input().split())
    for j in range(start, end): #endは含めないのでこれでOK
        t[j] += usage
        if t[j] > w:
            ans = 'No'
            break
print(ans)
```

制約を見落としていた…NもTも2 * 10 ** 5 オーダーだった

判定する必要があるのは、スタートとエンドのタイミングのみなので、それぞれの人に対してそのタイミングでの要素を見ればよさそう、という所までは行けたがその後が思いつかず、、

解説を見ると「いもす法」というものがあるらしい

https://imoz.jp/algorithms/imos_method.html

これを使うと時間内に解くことができた！

```py
max_time = 2 * 10 ** 5 + 1
t = [0 for _ in range(max_time)]

n, w = map(int, input().split())
ans = 'Yes'
for i in range(n):
    start, end, usage = map(int, input().split())
    # いもす法を使う。入出のタイミングを記録
    t[start] += usage
    t[end] -= usage

for i in range(1, len(t)):
    t[i] += t[i-1]

if max(t) > w:
    print('No')
else:
    print(ans)
```
真のフロントエンドエンジニアを目指して

##早いもので
2018年にIT企業に就職し、来年の4月で満3年になります。
入社してから約3年、HPを制作する部署でコーディングの仕事をさせてもらっている中で経験したことなどを書いてみようと思います。

##0からのスタート
高校時代に友人の影響でブログを書き始めたことがキッカケで、HTMLやCSSを使ってWebページが作れることを知りました。
そこから興味を持ち始めて自分で少しずつ触るようになっていたので、今の会社に内定を頂いた時点でほんの少し予備知識はあったのですが...

いざ課題や業務に取り組んでみると全然通用しませんでした。
組み方以前にタグの意味や使い方も全然わかっていなくて、めちゃくちゃ直されましたｗ
tableタグの中にtableタグを入れてレイアウト組んだり、直接HTMLにstyle全部書いていたり、今振り返ると「かなりひどい組み方してたな...。」と思いますｗ

そこからHTMLタグの意味や使い方、CSSのきれいな書き方など基礎の部分を勉強し直しました。

##コピペで乗り越えた1年目
1年目はとにかくできることを増やすのに必死でした。

先輩たちが過去に書いたコードをコピペして、デザインに合わせて組み替えていく中で色々な組み方を学びました。
自分で考えて組める場面は少なかったですが、「この書き方は構造が分かりやすいな」「こんな組み方されてるとどこでスタイル指定されてるかわかりづらい...」と色々感じながら、人のコードを読むことになります。

今思えばこの経験が、「運用面も考えた組み方」「シンプルで他の人も読みやすいコードの書き方」を意識することに繋がったと思います。
自分でオリジナルのコードを書けることも大事ですが、チームで仕事をしているのであれば、他の人が読んでもわかりやすいコードを書けることも大事ですね！

##自分で考えて書けるようになってきた2年目
2年目からは少しずつ「自分で考えて書く」ということができるようになりました。

HTMLやCSSだけでなく、JSやPHPも触るようになり動的記述も理解できるようになり、コーディングが楽しいと本当に感じられるようになってきたのもこの頃です。
やはりできることが増えると、楽しさややりがいを感じやすくなります。
ボタンのホバー効果やアニメーションを工夫できるようなったのもこの頃です。
（アニメーション付けられるようになると、面白くてあちこちアニメーション付けてしまうようになりますｗ）

9ヶ月かかる大型案件や自社の採用サイト制作も経験させてもらいました。
一気に対応する案件のレベルが上がり、急成長を求められ、正直とてもきつい時期でしたがコーディングレベルも仕事に関する考え方も大きく成長した期間だったと思います！

##より早く、よりシンプルを求める3年目
3年目の今は「より早く、よりシンプルに」を求めてコードを書いています。

仕事をする中で悩むことの1つに「工数削減」があると思います。
僕の場合は、CSS設計を見直してclassの付け方を工夫するようになり、工数が2/3くらいで済むようになりました！
また、たくさんの案件を経験させてもらう中で、分からなくなっても参考にできる引き出しが増えたことも工数削減に繋がっています。

さらに、1年目の僕みたいに0からスタートの人でも、コピペしてコーディングができるようなコードのテンプレートを作成したり、class名の命名規則をまとめたりといった、仕組化にも携わらせてもらうようになりました。


##真のフロントエンドエンジニアを目指して
約3年間を振り返ってみて、できるようになったことがかなり増えているなと実感する一方、動的部分などのシステム的なところはまだまだ知識が足りていないなと感じます。
来年はそのあたりの知識の知識も付けて真のフロントエンドエンジニアに近づけるように頑張っていきます！

なんだかブログみたいになってしまいましたが、せっかくQiitaに書くので次は技術的なことも書けるといいなと思います！
UbuntuでSpotifyアプリを使うtips

[3年前](https://k0kubun.hatenablog.com/entry/linux-desktop-2017) Linuxデスクトップに順応するためにiTunesからGoogle Play Musicに移行したのに、今年Google Play Musicは終了してしまった。YouTube Musicは、余計な音声が入ったプロモーション動画とかでしか再生したい曲が再生できなかったりするので、これはYouTubeであってMusicアプリではないという感じ。

そこで移行先としてSpotifyを使っているのだけど、まあ欲しい曲が全然ないのでGoogle Play Musicにあった曲をDropboxに置いてlocal filesとして再生などする[^1]必要があり、そのためにUbuntuでデスクトップアプリ使おうとすると https://www.spotify.com/us/download/linux/ というページがあるにも関わらずやたら大変だったので、どうやって問題に対応したのかメモしておく。

## Google認証でログインができない
macOSのアプリでは普通にできるのだが、Linux版では最新版でもできない。

Google認証で作ったアカウントには何故かデフォルトではメールアドレスが紐付いておらず (その割にGmailのアドレスのアカウントが存在するとしっかりconflictする[^2])、パスワードリセットしようとしてもそんなEmailのアカウントはないと言われる。デスクトップアプリ使うのを一瞬諦めかけた。

これを直すのは簡単で、設定からEmailをちゃんと登録できるようになっていて、そうするとパスワードリセットできるので、無事Linuxのデスクトップアプリログインできるようになる。

## HiDPIに対応していない
今時4KディスプレイやHiDPIを使っていない人はいないと思うのだけど、おもむろにSpotifyクライアントをインストールして開くとHiDPIに対応してない感じになる。

これは https://community.spotify.com/t5/Desktop-Linux/Linux-client-barely-usable-on-HiDPI-displays/td-p/1067272 ですぐ対処方を見つけることができる…はずだったのだが、`--force-device-scale-factor=2.0` を足す対象のdesktopエントリは `/usr/share/applications/spotify.desktop` にはなく、`/snap/spotify/current/usr/share/spotify/spotify.desktop` とかに見つかる。

Snapcraftのせいで設定ファイルがreadonlyでマウントされているため、これは直接いじることはできない。`/var/lib/snapd/desktop/applications/spotify_spotify.desktop` はいじれるが、これは別にいじっても設定が反映されない。それを `~/.local/share/applications/` にコピーしてみたりしていたら期待通りの挙動になった。なお同じ名前のエントリが複数あってもGNOMEのメニューで重複することはない模様。

## local files の設定をしようとするとクラッシュする
現状の最新版のSpotifyクライアントでlocal filesを設定しようとすると、Ubuntu 20.04ではクラッシュする。 https://community.spotify.com/t5/Desktop-Linux/Ubuntu-20-04-1-Crashes-when-quot-add-source-quot-for-local-songs/td-p/5042485 では最新版をインストールしたら直ったとあるが、少なくとも2020/12/13時点での最新版は壊れている。

上記のスレのSolutionは1ミリも参考にはならないのだが、リプライを眺めていると、別のマシンで作ったwatch-sources.bnkというファイルを持ってくると設定が適用できるっぽいことがわかった。なお、このバイナリを眺めてもパスが平文で埋まったりはしていないので、自力編集は難しそう。

そこで、古いSpotifyクライアントが入っているDockerコンテナ https://hub.docker.com/r/syncomm/spotify/ を発見し、そこではlocal filesの追加でクラッシュしなかったので、そこからwatch-sources.bnkを持ってくることで解決した。

## まとめ
こんなことで消耗してないで、ローカルファイル使わなくても必要な曲が揃うサービスを探すか、WindowsやmacOSを使うのが良い。

[^1]: ところで、そういうつもりの人はいまのうちにGoogle Play Musicにおいてある曲をちゃんと全部ダウンロードしておくのをやっておくと良い。その中でSpotifyに見つからない曲をDropboxにアップロードし、そこをSpotifyのlocal filesパスとして使っている。ちなみに同じネットワークにいるデスクトップマシンのlocal filesを、プレイリストのダウンロード機能を使うことで簡単にiOS/Androidアプリに転送できるのだけど、これはプレミアム機能。
[^2]: そもそもGmailのアドレスで登録したアカウントをGoogle認証にするためには、一旦アカウントを削除して2週間強待って作り直す必要があるというtipsもある
WSL2初心者向けのTips

## はじめに
[WSL Advent Calendar 2020](https://qiita.com/advent-calendar/2020/wsl)の13日目です。

最近になってようやく会社のPCにWSL2の開発環境を構築したのですが、思いのほか苦戦することが多かったです。今回はこれからWSL2を使いたい人がスムーズにWSL2を導入できるように、Tipsを共有したいと思います。

### Git
WSL2ではWindows側のファイルシステムとWSL2側のファイルシステムの間で相互にアクセスが可能です。ただし、WindowsとWSL2のファイルシステムの違いにより、ファイルシステムを跨いだアクセスが極端に遅くなっています。

そのため、WSL2側で開発を行う場合は、GitのリポジトリはWSL2側に置き、ファイルシステムを跨いだアクセスを避けるようにしてください。

私は最初のほうに何も考えずにWindows側にGitのリポジトリを置いており、WSL2でDockerのビルドができずにかなり時間を溶かしました。。。

参考：[WSL 2 と WSL 1 の比較 | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/wsl/compare-versions) 

### メモリ
WSL2ではWindowsとホストマシンのメモリを共有しています。本来であれば、この機能はマシンリソースを有効活用するうえで便利な機能なのですが、現在はWSL2が大量のメモリを消費し、Windows側から使用できるメモリが枯渇するという不具合を抱えています。

WSL2を再起動する。または、WSL2のメモリサイズを固定することで暫定対処ができます。

```bash:.wslconfig
[wsl2]
memory=6GB
```

参考：[https://qiita.com/yoichiwo7/items/e3e13b6fe2f32c4c6120](https://qiita.com/yoichiwo7/items/e3e13b6fe2f32c4c6120)