OmniAICreator/Qiita-1.07M huggingface dataset:
Online上で公開されている、pythonを学ぶ上で参考になる教材のまとめ

　Online上で公開されている、pythonを学ぶ上で参考になる教材を忘備録としてまとめておきます。(太字は特に役立ったものです)

<b>Pythonプログラミング入門 (東京大学 数理・情報教育研究センター)</b>
https://sites.google.com/view/ut-python/resource/%E6%95%99%E6%9D%90?authuser=0
Commnet: かなり基礎から詳しく解説されており、初学者に非常に便利な教材。演習問題もかなり豊富。すべての初学者におススメできる。

プログラミング演習 Python 2019 (喜多一)
https://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/245698

<b>GCIデータサイエンティスト育成講座</b>
https://weblab.t.u-tokyo.ac.jp/gci_contents/
Comment: データサイエンティストになるための基礎が網羅されているが、演習問題が少ないのと、1項目に割いている紙幅が少ないので、プログラミング初学者というよりも、多少なりともコードを書いた経験のある人が学ぶのに有用。

統計的モデリング基礎 (鹿島久嗣)
https://hkashima.github.io/course_modeling_2020.html

統計の入門 (京都大学国際高等教育院附属データ科学イノベーション教育研究センター)
https://repository.kulib.kyoto-u.ac.jp/dspace/handle/2433/246167

データマイニング入門 (森純一郎)
https://ocwx.ocw.u-tokyo.ac.jp/course_11414/

<b>機械学習 (Andrew Ng)</b>
https://ja.coursera.org/learn/machine-learning
Comment: 機械学習の決定版。機械学習を学びたければとにかくこの講座に尽きる。講義は英語だが日本語字幕もある。

<b>Data Scientist with Python (DataCamp)</b>
https://learn.datacamp.com/career-tracks/data-scientist-with-python
Comment: 英語での講義に抵抗が無ければ、基礎的な内容を非常に平易な語り口で学べるので初学者におススメ。最近日本語字幕も追加されたのは嬉しい(翻訳の精度は意外と良い)。有料だが、なんだかんだでかなり割引のプロモーションを行っているので、様々な方法を駆使して定価よりもかなり安い価格で勉強できると思う。

<b>AtCoder</b>
https://atcoder.jp/home
Comment: 教材というわけではないが、プログラミングのコンテストを行っている。過去問が大量に掲載されているので、コンテストにエントリーしなくてもかなり有用。コンテスト、と訊くと上級者が出場するようなイメージがあるが、AtCoder Beginner Contestはその名の通り、初心者でもかなり解きやすい問題が出る。全6問中、最初は2問正解を目指し、慣れてきたら4問目まで解けるようになっていきたい。

<b>NLPプログラミングチュートリアル</b>
http://www.phontron.com/teaching.php?lang=ja
Comment: NAISTのグラム先生のチュートリアルサイト。自然言語処理の基本的なアルゴリズムについて学べる。
【Rails】ローカルサーバーを強制終了させたいとき

少してこずったのでメモしておきます。

僕の場合は無限ループ処理になってしまったときに`Ctrl＋c`でサーバー停止できず、ターミナルを閉じてもプロセスが終了されずどうしたもんかとなってしまいました。

調べるとローカルサーバーの強制終了方法がいくつかヒットしますが、下のコマンドで一発だったので、今後はこれを使うことにします。

```:ターミナル
$ kill -9 $(lsof -i tcp:3000 -t)
```

同じような現象で困った方はお試しください。
【Rails】プロフィールに自己紹介機能を実装するシンプルな方法

##プロフィールに自己紹介機能を実装する
ポートフォリオ完成後、追加実装したので順序を備忘録として残します。
ユーザー名・email・パスワードなどの既存カラムに、introductionカラムを新たに追加します。
なるべくシンプルに記します！

##どうやって？
以下の順序です。

1. git checkout -b introduction (ブランチ切る)
2. usersテーブルにintroductionカラムを追加する
3. データベースに反映させる
4. usersコントローラーに必要コードの追記
5. userモデルに必要コードの追記
6. ユーザー詳細ページ(MYPAGE)に表示させる
7. ユーザー編集ページ(EDIT)に表示させる
8. 完成！

以下順番に記します！

###1. git checkout -b introduction (ブランチ切る)
新たな機能を実装するため、ブランチを切リます。
###2. usersテーブルにintroductionカラムを追加する
```ruby:ターミナル
$ rails generate migration AddIntroductionToUsers introduction:text
      invoke  active_record
      create    db/migrate/20200712005652_add_introduction_to_users.rb
```

上記rails gコマンドでintroductionカラムを追加します。

###3. データベースに反映させる
```ruby:ターミナル
$ docker-compose run  web rails db:migrate
== 2020~~~~ AddIntroductionToUsers: migrating ===========================
-- add_column(:users, :introduction, :text)
   -> 0.0518s
== 2020~~~~ AddIntroductionToUsers: migrated (0.0519s) ==================
```

###4. usersコントローラーに必要コードの追記
private methodに追記
introduction属性を付与する

```ruby:users_controller.rb
   def user_params_update
      params.require(:user).permit(:name, :email, :image, :introduction) # introdution追加
   end
```
これでintroductionをupdate可能になります

###5. userモデルに必要コードの追記
バリデーションを追加します。自己紹介は50文字以内で入力させます。
文字数は自由に設定してください。
※presenseですが、falseにしないと新規登録時に作用してintroductionがnilとなって新規登録できなくなりますので注意してください。新規登録時に自己紹介も入力必要な場合とするならtrueでOKです。

```ruby:user.rb
validates :introduction, presence: false, length: { maximum: 50 } # 自己紹介の最高文字数は50文字
```

###6. ユーザー詳細ページ(MYPAGE)に表示させる
```ruby:show.html.slim
 = @user.introduction
```
SCSSなどで適宜修正してください

###7. ユーザー編集ページ(EDIT)に表示させる
ユーザー編集はユーザー名・emailのみでしたがそこにintroductionを追記します。

```ruby:edit.html.slim
.form-group
  = f.label :introduction
  = f.text_area :introduction, class: 'form-control', id: 'user_introduction'
```

##完成
以上で自己紹介をusersテーブルに追加し、introduction属性を追加完了しました。
途中でintroductionをintroduceと書いていたりしたので、皆様も注意してください！

<img width="677" alt="スクリーンショット 2020-07-12 13.33.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620533/4d297c23-85a0-a43c-dce4-a172a5f864b3.png">
git branch の結果をlessではなくcatっぽく表示させるための設定

### はじめに

Macを初期化すると、git branchしたとき、

```
* develop
  master
(END)
```

というように結果がページャ（lessコマンドなどのようにページ送りできる昨日）で表示されるようになっていた。

おそらくgitのバージョンが変わったためだと思われるが、
もともと

```
± % git branch
* develop
  master
```

といった感じでcatしたみたいにコマンドの下に結果を表示してくれる設定に慣れていたので、その設定に戻した。

個人的にこの設定方法を見つけにくかったので、メモをここに残しとく


### 設定方法
gitconfigのpage.branchで設定できるようなので、

```
git config --global pager.branch cat
```

とするか

直接`~/.gitconfig`に

```
[pager]
        branch = cat
```
と書いてしまえばOK


### 参考
- [Git の branch とかが less になるのをやめたい](https://qiita.com/shimon_haga/items/874fcb5450a1522710e8)
【Flutter】画面遷移を実装する

Flutterの画面遷移周りについて忘れることが多いので、基本的な部分をメモとしてまとめました。

##次の画面に遷移する方法
遷移の実装にはいくつかの方法があるので、それぞれ簡単に紹介していきます。
###1.Navigator.of(context).pushを使用する
単純に次の画面に遷移させたい場合は、`Navigator.of(context).push`で実装することができます。

```dart
onPressed: () {
  Navigator.of(context).push(MaterialPageRoute(builder: (context) {
    return SecondScreen();
  }));
}
```

**サンプルコード**

```dart
class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Demo'),
      ),
      body: Center(
        child: FlatButton(
          color: Colors.blue,
          child: Text(
            'Button',
            style: TextStyle(
              color: Colors.white,
            ),
          ),
          onPressed: () {
            Navigator.of(context).push(MaterialPageRoute(builder: (context) {
              return SecondScreen();
            }));
          },
        ),
      ),
    );
  }
}
```

###2.Navigator.of(context).pushNamedを使用する
こちらは、事前に定義した画面のルートを呼び出して遷移する方法です。
####ルートの定義方法
`MaterialApp`に以下のように定義します。

```dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      initialRoute: '/first',
      routes: {
        '/first': (context) => FirstScreen(),
        '/second': (context) => SecondScreen(),
      },
    );
  }
}
```
- initialRoute：アプリを起動した時、最初に表示される画面を定義する
- routes： 各ルートに遷移した時に、画面を生成する

`/second `が呼ばれた場合、SecondScreen()が生成されることになります。

**(注)MaterialAppのhomeは、initialRouteが設定されている場合は必要ありません。**

####定義したルートを呼び、遷移する
```dart
onPressed: () {
  Navigator.pushNamed(context, '/second');
}
```

###3. Navigator.of(context).pushReplacementNamed()を使用する
`pushReplacementNamed`で遷移をすることで、遷移元の画面が破棄されるため、前の画面に戻ることができないようになります。

```dart
onPressed: () {
  Navigator.of(context).pushReplacementNamed('/second');
}
```

ルートを定義しないパターンは`pushReplacement`で遷移する。

```dart
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) {
    return SecondScreen();
  }));
```

##前の画面に戻る方法
前の画面に戻りたい場合は、`pop`を使用します。
`pushReplacementNamed`以外の方法で遷移した場合は、AppBarに標準で戻るボタンが表示されるようになるため、それ以外のボタン等で前の画面に戻りたい時は、コードを書いて実装することになります。
###1つ前の画面に戻る
```dart
onPressed: () {
  Navigator.of(context).pop();
}
```

##まとめ
今回は、画面遷移周りで最低限実装で必要な部分を取り上げているため、概念などの細かいところは触れていません。
画面遷移時の値の受け渡しについては、別記事を書こうと思っています。
jQueryでtextareaの高さを自動調節する

テキストエリアの高さを行数に応じて自動調節する方法を調べた結果、最終的に超シンプルな方法に落ち着いたのでメモ。検索で引っかかるどれよりもどシンプルに仕上がっていると思います。

**使っているもの**

|名前|ver|
|:--|:--|
|macOS|Catalina 10.15.5|
|jQuery.min.js|v3.4.1(googleapisからリンクで取得)|


**使う言語**

- javascript(というかjQuery)
- html



## まずは結論
htmlファイルのbody上部にこれさえ突っ込めばOKです。
必要に応じて呼び出し元の要素の指定をidやクラスに変更してください。

※v1.7以上のjQueryを別途読み込んでいる場合、一行目(src=とか書いてあるscriptタグ)は不要です。
※v1.7未満のjQueryを別途読み込んでいる場合、`$(documend).on`が使えません。
https://api.jquery.com/on/
v1.7未満のjQueryを使う場合は代わりにbindが使えそうですが、試していないので保証はできません。
https://www.aipacommander.com/entry/2015/09/17/192659


``` 表示したいページのhtml.html
--前略 ヘッダとか諸々--
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
    $(document).on("change", "textarea", function(evt){
        var min_height = 40; //テキストエリアの最小の高さをお好みで設定
        $(evt.target).height(min_height); //一旦最小サイズにする
        $(evt.target).height(evt.target.scrollHeight); //スクロールなしでテキストが収まる最小の高さに上書き
    });
</script>

--後略 この下にテキストボックスなど--
```

```html中で読み込んでおくCSS.css
textarea{
    resize: none;/*ユーザによるリサイズを不可にし、右下に///が出ないようにする*/
}
```
コード中の`"textarea"`部分がセレクタの指定箇所なので、`"#id名"`なり`".class名"`なり`"textarea[name='テキストエリア名']"`なり状況に応じたセレクタに変更しましょう。

## 答えにたどり着くまで
まずは「textarea 自動リサイズ」とか「textarea 高さ 調節」なんかで検索して調べました。

1. 改行コードの数を取得する系
改行コードを正規表現で抽出&その数に応じて幅を変えるというアプローチ。
例： https://qiita.com/ampersand/items/ceaa5066d44990d30df3
ただ、自動改行も取得できないと困るので目的に合わず。

2. 親要素のサイズを自動変更し、それに追随させる
例：https://qiita.com/tsmd/items/fce7bf1f65f03239eef0
ちょっと複雑で設定ミスが怖いので見送り。

3. textareaが持つscrollHeightの値を使う
    1. https://qiita.com/osamingo/items/3ee00333f6fcd33fa2a1
scrollHeightを使い、テキストエリアから文字がはみ出していたら最適なサイズまで拡大。ただ、文字を減らしたときにリサイズしない。
    2. https://pisuke-code.com/jquery-make-textarea-auto-resize/
while文を使ってちょっとずつ高さを減らし、スクロールが必要になったら表示可能な最小サイズにして終了、というアプローチ。

3-2が最も目的にあっていたのですが、whileを使っているのでミスって無限ループを発生させ、PCが唸りを上げること数回。
修正が怖くなったので、whileを使わずになんとかしようと思った結果、きづきました。
**一度最小まで縮めて、はみ出てたら拡大すればいい**。それだけのことでした。

## 理屈
1. jQueryを使いたいので、googleapisからjQueryを読み込みます。
2. テキストエリアの値が変更されたときに、jQueryの機能を使って検出します。
3. 値が変更されたテキストエリアのサイズを、一旦`min_height`に変更します。
4. scrollHeightの値で高さを上書きします。

ちなみに、テキストエリアの幅が余っているときに3をスキップするとうまく行かないのは、以下が原因です。
> 要素のコンテンツが垂直スクロールバーを表示することなく収まる場合、その scrollHeight は clientHeight と等しくなります。
https://developer.mozilla.org/ja/docs/Web/API/Element/scrollHeight

### 修正履歴
+ 2020/09/23 誤字と「理屈」の記述を一部修正しました。
<br />修正前：3がうまく機能しないのは<br />
修正後：3をスキップするとうまく行かないのは
ブラウザの履歴を消してしまい『OneTab』のデータが消えてしまった場合のTime Machineを使った復元方法

前提条件： Time Machine で日頃バックアップをとっている

1. Chrome を終了する
2. /Users/ユーザー名/Library/Application Support/Google/Chrome/Default/Local Storage を開く
3. leveldb のフォルダ名前を変更する ex. leveldb_gone
4. Time Machineを開く
5. Time Machine で leveldb のサイズ容量が増えた日時まで戻る
6. leveldb を復元をする。

以上。
業界研究 ~受託開発系企業~

競争力に何を置いているかでざっくりと分類すると、
【コストパフォーマンス】
【技術力】



**【コストパフォーマンス】**
これを達成するための手段をざっくり分類すると、
・ニアショア開発
・オフショア開発
・未経験をSESで育てる

**ニアショア開発**
地方に拠点を置くことでコストを抑える

**オフショア開発**
中級以上の英語力が必要だと思われる(slackかgithubベース？)

**未経験をSESで育てる**
受託・自社とSESの割合はまちまち
受託・自社での開発を餌にしてSESに送り込んで、成長できた人だけ吸い上げる？
100%SESよりは希望が持てるのかも

**【技術力】**
これを達成するための手段をざっくり分類すると、
・高単価
・エンジニアファースト

**エンジニアファースト**
主に謳っているのは
・残業が少ない (高い技術力によって生産性が高いから)
・学習を支援
・新規事業の可能性 (機械学習やVR/ARなど)
・基本は受託だが、最新の技術による自社サービスを立ち上げている、または立ち上げる準備がある


## 未経験からいけるとしたら
ニアショア：東京でなくてもよいと考えている人には狙いめなのかも
オフショア：英語力があればチャンスあり？
未経験をSESで育てる：スクール卒業レベルでも足切りに合わないのはここだけ？
高単価：未経験からは無理
エンジニアファースト：学習能力の高さが認められればイケるのではという印象
【Vite】 Vite をReact x TSXで入門してみた！

## Vite とは

Vite は、Vue.js フレームワークを開発したEvan You 氏が作ったフレームワークです。

Vue やReact, Preact でも開発を行うことができるだけでなく、公式の CLI でアプリを制作するよりもホットリロードやビルドにかかる時間が少なく、アプリをより効率的に開発することができます。さらに、Vue Composition API やReact Hooks　も公式にサポートしているため、初期設定することなく利用することができます。

公式ドキュメント：　https://github.com/vitejs/vite

この記事では、Vite をReact でTODO　アプリを構築してみます。

## 環境構築してみる
まず、セットアップを行います。

```bash 
npm init vite-app --template react <プロジェクト名> # 今回は vite-react　としました。
cd <プロジェクト名>
npm install 
```

これにより、生成されたディレクトリは次のようになります。

```bash 
$tree
.
├─node_modules
├─src 
│  ├─App.css
│  ├─App.jsx
│  ├─index.css
│  ├─logo.svg
│  └─main.jsx
│
├─.gitignore
├─index.html
├─package.json
├─package.json.lock
└─vite.config.js
```
ここで、開発サーバーを起動します。

```bash 
npm run dev 
```

![スクリーンショット (86).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271708/d90d5019-7f16-8b50-dc2a-7b46f4604e2e.png)

http://localhost:3000 で上のような画面が描写されれば成功です。

## TypeScript で開発を行う
続いて、TypeScript での開発を行います。

まず、親ディレクトリにて、`tsconfig.json `を次のように実装します。

Vite では、**ESBuild によって型情報なしにコンパイルされるため、const enum などの一部の型に対応していません。**そのため、tsconfig.json では、compilerOptions で **"isolatedModules": true** とする
必要があります。

```tsconfig.json
{
    "compilerOptions": {
        "target": "es5",
        "isolatedModules": true,
        "module": "commonjs",
        "outDir": "./dist",
        "strict": true,
        "esModuleInterop": true // ここを変更
    },
    "include": [
        "./src/**/*."
    ]
}
```
また、すべての`.jsx` ファイルを`.tsx` に変更します。

このとき、`index.html` ファイルで読み込むファイル名を`/src/main.jsx` から`/src/main.tsx` に変更しないと画面が表示されないので気をつけてください。

```index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vite App</title>
</head>
<body>
  <div id="root"></div>
  <script type="module" src="/src/main.tsx"></script> // 読み込むファイル名を "main.tsx" に変更する必要あり
</body>
</html>
```
### 注意：
Vite　では、.ts ファイルをコンパイルすることしか対応していないので、***型のチェックを行ってはくれません。*** そのため、IDE を使って開発する時ややビルド実行時には、型のチェックが行われるように設定してください。

## まとめ

以上で、React で TypeScript が実行できるように設定してみました。
今後、React Router や Redux を使うための設定はどうすればいいかといったことについて書いていきたいと思います。
undefined method `user_signed_in?'と出たときの対処法

日々学んだことやつまずいたことについてまとめていきます。
記載に誤りがありましたら、ご指摘していただけると助かります！
いつも他のかたの記事に助けられているので、少しでもお役に立てればと思います。
##どういうエラーなのか
deviseで使えるようになる、 user_signed_in  ヘルパーメソッドが定義されていないというエラー。

##どんなときに起こるのか
1.deviseがインストールされていないとき。
2.routes.rbにdevise_for :users などの記述がないとき。

##対処法
1.
Gemfileに以下を記述。

```
gem 'devise'
```
ターミナルで以下を実行。

gemをインストール


```
bundle install
```

設定ファイルを作成

```
rails g  devise:install
```

ログイン機能に対応したモデルを作成

```
rails g devise user
```

ログイン機能に関連するテーブルを作成

```
bundle exec rake db:migrate
```

2.
routes.rbに以下を記述

```
devise_for :users
```
ネットバブル崩壊　サイト運営のこれから

2020年Google大型アップデートがありました。これは今までとは違って、アフィリエイトだけでなく法人サイトも大きな影響が出てきました。

アクセスの落ち込み。公式サイトや大手ネットショップの優遇。HTMLやCSSでは対応できない事情。SEOでも限度を超えてきて、もはやキーワード比率では対応できない事情でした。

にもかかわらず、いまだにキーワード比率や見出しタグにキーワードを入れるという旧型のSEO対策をしている。これではアクセスが落ちても当然でした。

現代のSEO対策は困難を極めてきています。ロングテールに可能性があると言われながら、ロングテールのアクセス減が深刻。

ビッグキーワード、ミドルキーワードでも大変動が起きてきてます。つまり、良質なコンテンツを作るだけではこれからのSEO対策はつとまらなくなりました。<a href="https://fortune-telling-hit.com" >占いの個人サイトの例</a>のように、小さなサイトの生き残りも大変。

ライターの質が悪いと、責任転嫁したり未払いなども起きてくる。外注での記事制作でも、しわよせがライターにきたりと問題発生でした。
Rustで使えるバイナリシリアライザのパフォーマンスを比較してみたよ

### はじめに
Rustで使えるバイナリシリアライザの性能を簡単にですが計測して比較してみたので、結果を共有します。

### 計測対象のシリアライザ
以下の要件を満たすシリアライザの性能比較をします。

* バイナリにシリアライズできること
* Serdeを使ってstructやenumに`#[derive(Deserialize, Serialize)]`をつけるだけで利用できること
* 比較的複雑なstructやenumもシリアライズできること

ネットを漁ったら以下の３つのシリアライザが見つかったので、これらを対象とします。

* [rmp-serde](https://crates.io/crates/rmp-serde)
* [serde_cbor](https://crates.io/crates/serde_cbor)
* [bincode](https://crates.io/crates/bincode)

[zerocopy](https://crates.io/crates/zerocopy)はC likeなenumしか扱えないみたいなので対象外。protocol buffer系のシリアライザは`#[derive(Deserialize, Serialize)]`をつけるだけで利用可能なお手軽な実装が見つからなかったのでこれも対象外。

### 計測方法

以下のenumに16MBの`Vec<u8>`をBigDataにいれてシリアライズ・デシリアライズにかかる時間を計測しました。

```rust
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub enum TestEnum {
    BigData { data: Vec<u8> },
    SmallData { data: u8 },
}
```

### 結果

|  | シリアライズ | デシリアライズ |
----|---- | --- |
| bincode | 70.3723ms | 71.2949ms |
| cbor | 105.8754ms | 89.4747ms |
| rmp serde | 133.3205ms | 87.1423ms |

### 見直し

bincodeが速いという結果ですが、16MBのデータにしては遅いですね（※リリースビルドで計測してます）。。
他に速いシリアライザは無いか探してたら[serde_bytes](https://crates.io/crates/serde_bytes)というものを見つけました。これは、`Vec<u8>`や`&[u8]`をフィールドに持つstructのフィールドの宣言の上に`#[serde(with = "serde_bytes")]`をつけるだけでシリアライズ・デシリアライズを高速化してくれるもののようです。
先程のenumでも使えました：

```rust
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub enum TestEnum {
    BigData {
        #[serde(with = "serde_bytes")]
        data: Vec<u8>,
    },
    SmallData {
        data: u8,
    },
}
```

これでもう一度計測し直します。

### 結果（serde_bytes付き）

|  | シリアライズ | デシリアライズ |
----|---- | --- |
| bincode | 4.8973ms | 2.3063ms |
| cbor | 4.2206ms | 2.7095ms |
| rmp serde | 3.8015ms | 2.4234ms |

かなり速くなりました！

### まとめ

* `Vec<u8>`をフィールドに持つstruct, enumをシリアライズ・デシリアライズする場合にはserde_bytesを忘れずに
* bincode, cbor, rmp serdeの中だとrmp serdeがやや速いが、大きな違いはなさそう

コードの完全版：
https://github.com/hagure-kusa/bench-serialize
[SwiftUI]無駄にAnyViewを使っていませんか？そのAnyView、消せるかもしれません。

型情報を消せるAnyView、便利でついつい使ってしまいますがなるべくなら使いたく無いところ。

# 別メソッドにしたケース

bodyの中が複雑になった時に、次のように別メソッドに分けることがあります。
some Viewでは返せないのでAnyViewにして型を揃えています。
（some Viewで返そうとすると
`Function declares an opaque return type, but the return statements in its body do not have matching underlying types`と言われてコンパイルできない）

```swift

var body: some View {
  rootView
}

var rootView: AnyView {
  if isAuthorized {
    return AnyView(HomeView())  
  } else {
    return AnyView(LoginView())
  }
}
```

このようなケースの場合、rootViewをViewBuilderにすることでAnyViewを消すことができます。

```swift
@ViewBuilder
var rootView: some View {
      if isAuthorized {
        HomeView()
      } else {
        LoginView()
      }
    }
}
```
JavaScript 暗黒問題集


## あらすじ

最近 JavaScript を学び始めた知り合いが、JavaScript は暗黒の言語であるという話をどこかで聞いてきたらしい。

この言語を愛して止まない私としては「そうだね」以外の言葉が出てこなかったので、開き直って暗黒面を育む問題集をひっそりと作り始めたのであった。

## 想定対象

「JavaScript、だいたいわかります」という諸氏に遊んでいただければ幸い。

初学者にとっては混乱を招く内容にしかならないので、避けたほうが良いように思う。

## 前提条件

* [ES2020](https://www.ecma-international.org/publications/standards/Ecma-262.htm) (Standard ECMA-262 11th edition) に従う。
* strict モード ("use strict" 指定) で実行される。
* 組み込みのオブジェクトを変更してはならない。
* ブラウザの機能等、環境依存の API を用いてはならない。

## 問題

全 10 問

時間制限はない

解は複数存在し得る

### 問1. 私は私ではない

以下の関数 `q1` が `true` を返すような値 `x` を与えよ。

~~~js
function q1(x) {
  return x !== x;
}
~~~

### 問2. 直観に反する

以下の関数 `q2` が `true` を返すような値の組 `a`, `b` を与えよ。

~~~js
function q2(a, b) {
  return a == b && a != b;
}
~~~

### 問3. さよなら推移律

以下の関数 `q3` が `true` を返すような値の組 `a`, `b`, `c` を与えよ。

~~~js
function q3(a, b, c) {
  return a == b && b == c && a != c;
}
~~~

### 問4. 同じトコロに違うモノ

以下の関数 `q4` が `true` を返すような値 `x` を与えよ。

~~~js
function q4(x) {
  const a = [0, 1];
  return x == x + x && a[x] != a[x + x];
}
~~~

### 問5. 実例の実例

以下の関数 `q5` が `true` を返すような値 `x` を与えよ。

~~~js
function q5(x) {
  return x instanceof x;
}
~~~

### 問6. 入ってます

以下の関数 `q6` が `true` を返すような値 `x` を与えよ。

~~~js
function q6(x) {
  return x in x;
}
~~~

### 問7. いちたりない

以下の関数 `q7` が `true` を返すような値 `x` を与えよ。

~~~js
function q7(x) {
  return Array.isArray(x) &&
    !Array.prototype.some.call(x, v => v) &&
    x.length === 7 &&
    new Set(x).size === 7 &&
    Array.prototype.reduce.call(x, i => i + 1, 0) === 6;
}
~~~

### 問8. おおきすぎる

以下の関数 `q8` が、必ず `true` を返すような関数 `f` を与えよ。

~~~js
function q8(f) {
  const n = 4294967297;
  const i = Math.floor(Math.random() * n);
  const x = f(n);
  return x[i] === i;
}
~~~

### 問9. 見慣れない構文

以下の関数 `q9` が、必ず `true` を返すような値 `each` を与えよ。

~~~js
function q9(each) {
  const array = new Array(10);
  for (let i = 0; i < 10; i++) {
    array[i] = Math.floor(Math.random() * 10);
  }

  const total = array.reduce((x, y) => x + y, 0);

  for (each.item of array);

  return each.sum === total; 
}
~~~

### 問10. 次の日は別の人

以下の非同期関数 `q10` が、最終的に `true` を返すような関数 `f` を与えよ。

~~~js
async function q10(f) {
  const x = await f();
  const y = await x;
  return !Object.is(x, y);
}

// q10(answer).then(value => console.log(value)); // true
~~~

## 解答例

[(解答例) JavaScript 暗黒問題集 - Qiita](https://qiita.com/nagtkk/items/ec4a0357859f86e4ac9c)

ネタバレになりそうなコメントは、解答記事の方にしていただけると助かります。
micro-ROSチュートリアル｜ホストPC内 ping-pong

micro-ROS のチュートリアルを進め、ホスト PC と STM マイコン間で ping-pong をするまでの記事です。
なるべく docker を利用していますので、手っ取り早く sample を動かしたい方向けです。
詳細は公式のチュートリアル(参考[1])をご覧ください。

記事は 3 つに分けて投稿します。本記事は 1 記事目になります。

 1.  [ping-pong] ホストPC内 ping-pong
 2. [[publisher] ホストPC・マイコン間 pubsub](https://qiita.com/hssay/items/772f3f278124b25b8a2c)
 3. [[ping-pong] ホストPC・マイコン間 ping-pong](https://qiita.com/hssay/items/8d3f1b3209e89593c63c)

## 環境
ホスト PC：Ubuntu 18.04.4 LTS
対象ボード：STM32 Nucleo-144 開発 ボード NUCLEO-F767ZI

docker を使うので、他の環境でも動くかと思います。
nucleo-144 は比較的お手頃で、ポーティングしている方がいた(参考[2])ので選んでいます。

## サンプル実行
エージェントを経由して、ホスト内の2つのping-pongプログラムがメッセージを飛ばし合うサンプルを実行します。
ここでの作業は全てdockerに入っているので、dockerを実行するだけです。

エージェントの起動

```
$ docker run -it --rm --net=host --name uros_agent microros/micro-ros-agent:dashing udp4 --port 8888
```

別ターミナルでping_pong(uros_demos_1)を起動

```
$ docker run -it --rm --net=host --name uros_demos_1 microros/micro-ros-demos:dashing ros2 run micro_ros_demos_rcl ping_pong
```

別ターミナルでping_pong(uros_demos_2)を起動

```
$ docker run -it --rm --net=host --name uros_demos_2 microros/micro-ros-demos:dashing ros2 run micro_ros_demos_rcl ping_pong
```

## 実行結果

![host_ping_pong.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62023/75ca8f27-e5f8-2c2d-bff0-cf7d5dd65b23.gif)

ping_pongが起動後、エージェントの標準出力に `establish_session` が表示され、接続ができていることがわかります。
また、2 台のping_pongの実行後はそれぞれがpingを送り、受け取ったpingに対してpongを送り返しています。

なお、ここで使用しているサンプルでは自分の飛ばしたpingメッセージには反応しないようになっています。

## 参考

1. [micro-ROS 公式](https://micro-ros.github.io/)
2. [github | micro-ROS_Demo_on_STM32_nucleo-f767zi](https://github.com/maehara-keisuke/micro-ROS_Demo_on_STM32_nucleo-f767zi/blob/master/README.md)
【1対多】の関連付け

# 個人的備忘録

ターミナルでモデルの関連付けをするときにいつも忘れるのでメモ。
Attendanceモデルをuserモデルに紐付けたいときに使う。
重要なのは最後の user:references 。

```
$ rails g model Attendance worked_on:date started_at:datetime finished_at:datetime note:string user:references
```


以下のt.references :user, foreign_key: true が表示されていればおk

```
class CreateAttendances < ActiveRecord::Migration[5.1]
  def change
    create_table :attendances do |t|
      t.date :worked_on
      t.datetime :started_at
      t.datetime :finished_at
      t.string :note
      t.references :user, foreign_key: true

      t.timestamps
    end
  end
end
```

```
$ rails db:migrate
```
結果。

```
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20190523135500) do

  create_table "attendances", force: :cascade do |t|
    t.date "worked_on"
    t.datetime "started_at"
    t.datetime "finished_at"
    t.string "note"
    t.integer "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["user_id"], name: "index_attendances_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "name"
    t.string "email"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "password_digest"
    t.string "remember_digest"
    t.boolean "admin", default: false
    t.string "department"
    t.datetime "basic_time", default: "2019-05-22 23:00:00"
    t.datetime "work_time", default: "2019-05-22 22:30:00"
    t.index ["email"], name: "index_users_on_email", unique: true
  end

end
```

最後に格モデルに対してコードを記述するのを忘れずに。

```
class User < ApplicationRecord
  has_many :attendances, dependent: :destroy
```

```
class Attendance < ApplicationRecord
  belongs_to :user
```

これで関連付けができました。
FortiGateをリプレスしたら時々繋がらない

# はじめに
専用線を使って本店と複数拠点繋いでいるという仮定環境での出来事。拠点側にはHA構成のFortiGateを設置。このFortiGateをリプレスしたら、複数拠点のうち２拠点（リプレイスした拠点ともう一拠点）において、通信が出来たり／出来なくなったりする問題が発生した。原因究明のためイロイロ調べたのでメモ。

# 環境イメージ
```
本店（L3スイッチ）-----[専用線]----- 複数拠点（FortiGate）
```

# ハマった理由（言い訳）
* FortiGateからFortiGateへのリプレイスだった。
* 旧設定を踏襲していた。
* リプレイスしていない拠点でも問題が発生していた。
* リプレイス後の数時間は問題発生していなかった。

# 原因
２拠点のFortiGate間でMACアドレスが重複していた。
FortiGateではHA構成を組む際に仮想MACアドレスが生成されるが、これが一定のルールに基づいて割り当てられる。

メーカ資料より
https://docs.fortinet.com/document/fortigate/6.0.0/handbook/996579/cluster-virtual-mac-addresses

```
・How the virtual MAC address is determined
　The virtual MAC address is determined based on following formula:
　00-09-0f-09-<group-id_hex>-(<vcluster_integer> + <idx>)
```

今回の問題は複数拠点のうち２拠点（リプレイスした拠点ともう一拠点）において、FortiGateの仮想MACアドレスが同じものになり、本店（L3スイッチ）のARPテーブル上でMACアドレスが競合した結果発生した問題でした。

リプレイス後の数時間は問題発生していなかったのは、休日夜間のリプレイス作業だったので、たまたまリプレイスしていない方の拠点から通信が発生していなかっただけ。

# 反省点
社内ドキュメントには、FortiGateのHAのグループID（仮想MACアドレスの[group-id_hex]の部分）の管理表があったが確認していなかった、ということにしておく。（詳しく書けないので）
【rails】ボタンをクリックするとランダムの英数字パスワードを作成、パスワードフィールドに入力する方法

# パスワードを自動生成したい

ポートフォリオの投稿機能にパスワード機能を設定したのですが、
パスワードを自動的に生成、入力までしてくれる機能あったら便利じゃん。

ということで作っていきましょう！

## この記事のゴール
「パスワードを生成する」ボタンをクリックして
自動的に入力できるようにしましょう！
![パスワード生成.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/637746/04028b3f-065f-0bca-8117-97ad33ccb6d8.gif)

## 前提
rails:5.2
ruby:2.6.3
bootstrap
jquery

## パスワードを生成する
まずはコントローラーでランダムの英数字を作れるようにします。

```ruby:topics_controller.rb
def new
  @topic    = Topic.new
  @password = SecureRandom.alphanumeric(6)
  -> ランダムの英数字(A-Z, a-z, 0-9)を生成
   (6)は６桁、指定なしの場合は16桁
end
```

## ボタンクリックでフィールドに入力できるようにする

次に先ほど作したパスワードをpassword_field(今回はtext_fieldにしています)に
入力できるようにします。

```ruby:new.html.erb
<div class="topic-new-wrapper" >
  <div class="container">
    <div class="row">
      <div class="col-md-6 col-md-offset-3">
          <%= form_for @topic do |f| %>
            <div class="form-group">
              <%= f.label :password, 'password(任意)' %>
              <%= f.text_field :password, class: 'form-control', id: 'password' %>
              <%= button_tag 'パスワードを生成する', id: 'auto-fill-link' %>
            </div>
  
            <%= f.submit 'パスワード登録', class: 'btn btn-black btn-block' %>
  
          <% end %>
      </div>
    </div>
  </div>
</div>
  
<script>
  $(function(){
    autoFill();
    function autoFill() {
      $('#auto-fill-link').click(function(){
        $('#password').val("<%= @password %>");
      });
    }
  })
</script>
```

"auto-fill-link"というidを含むリンクがクリックされると、"password"というidを含む
fieldに@passwordが入力されます。

ただこれだとbutton_tagがクリックされたときにsubmitされてしまうため、
ただのボタンとして利用する際は以下のコードを追加してあげます。

type: "button"

```ruby:new.html.erb
<div class="topic-new-wrapper" >
  <div class="container">
    <div class="row">
      <div class="col-md-6 col-md-offset-3">
          <%= form_for @topic do |f| %>
            <div class="form-group">
              <%= f.label :password, 'password(任意)' %>
              <%= f.text_field :password, class: 'form-control', id: 'password' %>
この行->       <%= button_tag 'パスワードを生成する', id: 'auto-fill-link', type: "button" %>
            </div>
  
            <%= f.submit 'パスワード登録', class: 'btn btn-black btn-block' %>
  
          <% end %>
      </div>
    </div>
  </div>
</div>
  
<script>
  $(function(){
    autoFill();
    function autoFill() {
      $('#auto-fill-link').click(function(){
        $('#password').val("<%= @password %>");
      });
    }
  })
</script>
```

## まとめ
パスワードの生成から入力までしてくれる機能を作成しました。

簡単なので上記のコードぜひ使ってくださいね。
Windows環境でhomesteadを利用してLaravel開発環境構築時のNET::ERR_CERT_AUTHORITY_INVALID 

久しぶりにWindows環境でhomesteadを利用してLaravel開発環境を構築した際のChromeでの初期動作確認時に、上記エラーが発生して時間を無駄にしてしまったので、備忘録として残しておきます。

## 環境
以下の環境で構築しました。

* Windows 10
* VirtualBox 6.0.22
* Homestead 10.9.1
* Vagrant 2.2.9
* Laravel Framework 7.19.1

## エラーの内容

![エラー内容.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117822/666289ff-6cf5-a35a-ab3c-87d255d10712.png)
LaravelのWebサイトで紹介されている[Laravelのインストールマニュアル](https://readouble.com/laravel/7.x/ja/installation.html)及び、[Homesteadのインストール手順](https://readouble.com/laravel/7.x/ja/homestead.html)に沿って環境の構築を進めたのち、サイトの初期動作確認時に上記メッセージが表示され、動作確認ができませんでした。

## 原因
Homestead.yamlファイルのsites設定で、**sample.dev**というドメインを使用したことが原因でした。

```Homestead.yaml
sites:
    - map: sample.dev
      to: /home/vagrant/code/sample/public

```

理由としては、[Chrome & Firefox now force .dev domains to HTTPS via preloaded HSTS](https://ma.ttias.be/chrome-force-dev-domains-https-via-preloaded-hsts/)に記載がありました。

簡単に記載すると、.devで終わるすべてのドメインは強制的にHTTPSにリダイレクトするようになっているためです。

## 対策
もっとも簡単な対策としては、**.dev**で終わるドメインを使わないことです。

以上です。
開発環境を作る際に無駄な時間を浪費しないよう、気を付けたいと思います。
Gatsby.js で作ったサイトから Tableau を読み込む方法

# Gatsby.js で作ったサイトでに Tableau を埋め込む

総務省がPDFで公開している[マイナンバーカードの交付状況](https://www.soumu.go.jp/kojinbango_card/)というファイルから CSV ファイルを作り、Tableau で取り込み表示しています。

Gatsby を使って生成したファイルを、Github Pages でホストしています。([リポジトリ](https://github.com/codeforjapan/mynumbercard_statistics))

char.js などを使ってグラフを自前で作成しても良かったのですが、データを色々いじりながら試行錯誤したかったので、Tableau をそのまま取り込むことにしてみました。

2020年7月12日現在、以下のように表示されています。

[マイナンバーカード普及状況ダッシュボード](http://mynumbercard.code4japan.org/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1399/62765a11-98f5-6e5a-96c8-0fc35d771d3f.png)

# `tableau-react` コンポーネントを使う

React から Tableau のグラフを表示する、[tableau-react](https://www.npmjs.com/package/tableau-react) というコンポーネントがあります。

こちらを使うことで、Gatsby でも Tableau のグラフをサイトに埋め込むことができます。

```bash
yarn add tableau-react
```

これを導入することにより、Tableau のシートをサイトに埋め込むことができるようになります。Tableau Public にシート公開（[例えばこちらのグラフ](https://public.tableau.com/profile/halsk#!/vizhome/26693/sheet0)）し、シェアボタンからシェア用のLinkを取得し、以下のようなコンポーネントを作ります。

```tsx:PrefectureReport.tsx
//@ts-ignore  (TypeScript の定義が無いのでエラー回避)
import TableauReport from 'tableau-react'

const SimpleReport = () => (
  <TableauReport url="https://public.tableau.com/views/26693/sheet0?:language=en&:display_count=y&publish=yes&:origin=viz_share_link" />
)

export default SimpleReport
```

このコンポーネントを使うことで、Tableau をEmbedできます。今はグラフが一つなので固定にしていますが、URLはパラメータで渡せるようにしても良いかもしれませんね。

# Code Splitting で`yarn build` のエラー対応をする

この状態で、`gatsby develop` ではサイトは表示できても、`yarn build` でファイルを生成しようとすると、以下のようなエラーがでます。

```js
error Building static HTML failed

See our docs page on debugging HTML builds for help https://gatsby.dev/debug-html

  521 | tab.WindowHelper._cancelAnimationFrameFunc = null;
  522 | (function () {
> 523 |     if (('innerWidth' in window)) {
      | ^
  524 |         tab.WindowHelper._innerWidthFunc = function(w) {
  525 |             return w.innerWidth;
  526 |         };


  WebpackError: ReferenceError: window is not defined
  
  - tableau-2.0.0.js:523 
    [lib]/[tableau-api]/tableau-2.0.0.js:523:1
```

tableau.js は事前コンパイルする必要はないので、[loadable-component](https://github.com/gregberge/loadable-components) を導入し Code Splitting します。

```bash
yarn add @loadable/component @types/loadable__component
```

```tsx:index.tsx
import loadable from '@loadable/component'

import Page from '../components/Page'
import Container from '../components/Container'
import IndexLayout from '../layouts'
const PrefectureReport = loadable(() => import('../components/PrefectureReport'))

const IndexPage = () => (
  <IndexLayout>
    <Page>
      <Container>
        (省略)
        <PrefectureReport></PrefectureReport>
      </Container>
    </Page>
  </IndexLayout>
)

export default IndexPage
```

以上で、無事に build を行うことができました。

このプロジェクトでは、ご協力いただける仲間を募集中です。

GitHub：https://github.com/codeforjapan/mynumbercard_statistics/issues

もしご協力いただける方がいたら、ぜひ Issue にコメントいただければと思います。

[Code for Japan の Slack](https://join.slack.com/t/cfj/shared_invite/zt-88tbjehh-_ANL8iwMkwAuuBtXqiyPYg) に入り、Hal Seki(@hal_sk) にお声がけいただいても大丈です。
競技プログラミング練習記 No.41【ABC121練習】

初回 -> [はじめに](https://qiita.com/easychoco/items/a9ae28aca97cfe47091f)

[ABC121](https://atcoder.jp/contests/abc121)を解きました。
4完です！

|問題|時間|アルゴリズム|実行時間
|:-:|:-:|:-:|:-:|
| A |  2min |-| 6ms|
| B |  8min |-| 6ms|
| C |  9min |貪欲法| 37ms|
| D | 13min |XOR|6ms|


# まとめ
先にまとめを載せます。これ自体は最後に書いてます。

全完できました。嬉しい。

c++では`bool`型から`int`型への暗黙の型変換がされます。

XORの累積和には4を法とした規則性があります。


## A - White Cells

```c++
  int H, W, h, w;
  cin >> H >> W >> h >> w;
  cout << (H-h)*(W-w);
```
`H`行から`h`行を塗ると`H-h`残り、
`W`行から`w`行を塗ると`W-w`残ますね。
そうして残った行と列をかけると答えになります。

## B - Can you solve this?

``` c++
  int n, m, c;
  cin >> n >> m >> c;
  vector<int> b(m);
  for(int i = 0; i < m; ++i) cin >> b[i];

  int ans = 0;
  for(int i = 0; i < n; ++i) 
  {
    int score = 0;
    int a;
    for(int j = 0; j < m; ++j)
    {
      cin >> a;
      score += b[j] * a;
    }
    ans += score + c > 0;
  }
  cout << ans;
```
計算時間が間に合いそうだったので愚直にやりました。
`ans += score + c > 0;`については、c++での`bool`型から`int`型への暗黙の変換を利用しています。
`false => 0`
`true => 1`
が暗黙に変換されます。

## C - Energy Drink Collector

``` c++
  int n, m, a, b;
  cin >> n >> m;
  vector< pair<ll, ll> > d(n);
  for(int i = 0; i < n; ++i)
  {
    cin >> a >> b;
    d[i] = make_pair(a, b);
  }
  sort(d.begin(), d.end());

  ll ans = 0;
  ll cnt = 0;
  for(int i = 0; i < n; ++i)
  {
    if (cnt + d[i].second < m)
    {
      ans += d[i].first * d[i].second;
      cnt += d[i].second;
    }
    else
    {
      ans += d[i].first * (m - cnt);
      break;
    }
  }
  cout << ans;
```
貪欲法ですね。
値段が安い順にドリンクを変えるだけ買えば答えになります。

## D - XOR World

``` c++
  ll a, b;
  cin >> a >> b;

  a = max(0LL, a - 1);
  if      (a % 4 == 0);
  else if (a % 4 == 1) a = 1;
  else if (a % 4 == 2) a += 1;
  else if (a % 4 == 3) a = 0;

  if      (b % 4 == 0);
  else if (b % 4 == 1) b = 1;
  else if (b % 4 == 2) b += 1;
  else if (b % 4 == 3) b = 0;

  cout << (a ^ b);
```
任意の範囲のXORによる総和を求める問題ですね。
任意の範囲の総和といえば累積和が使えます。

ただ、今回は範囲が広すぎて愚直に計算していては時間に間に合いません。
ですが、XORの累積和には規則性があり、簡単に求めることができます。

`0`から`N`までのXORによる累積和は、
Nを4で割った余りが
`0 のとき: N`
`1 のとき: 1`
`2 のとき: N+1`
`3 のとき: 0`
になります。

調べると、こちらのサイトに同じ問題付きで載っていました。
→ [0からNまでの累積XORやAからBまでの区間XORについて](http://hryshtk.hatenablog.com/entry/2019/03/15/0%E3%81%8B%E3%82%89N%E3%81%BE%E3%81%A7%E3%81%AE%E7%B4%AF%E7%A9%8DXOR)

つまり、`0`から`N`までのXORによる累積和は`O(1)`で求めることができます。
以上より、この問題は`O(1)`で解くことができました。

コードについて余談ですが、同じことの繰り返しなので関数化したほうがいいですね。

以上です。ありがとうございました。
radikoだけPPPoEを通して地元のラジオを聞きたい

# 要約
IPv4 over IPv6環境でのradikoの地域判定問題を回避するために、

-  `radiko.jp` へのパケットをPPPoEセッションに流す
- 宛先FQDN指定で静的ルーティングできない端末(Google Home)は、DHCPの配布アドレスを固定して発信元IPアドレスで静的ルーティング

をやりましたという話です。対象はYAMAHAルータ。

# 背景
IPv4 over IPv6が流行ってますね。DS-LiteとかMAP-Eとか。
しかし、IPアドレスで地域を判定するradikoは東京/大阪扱いになってしまい、地方民には~~都会のラジオが聴けて便利~~地元局が聴けなくて不便です。
DS-LiteとPPPoEのマルチホームできればいいのだけど、手持ちの家庭用ルータでは不可能だったので、スマホのradikoアプリを使ったりしてました。

そこにYAMAHAルータを入れたので静的ルーティングを設定してみたという次第。

# 環境
- IIJmioひかり+IPoEオプション (DS-LiteとIPv4 PPPoEの同時利用が可能)
- YAMAHA RTX810

# 静的ルーティング設定
`pp 1`にPPPoEセッション、`tunnel 1`にDS-Liteトンネルの設定がされているものとします。

```shell

# IPフィルタ9000番にマッチしたパケットは pp 1 へ流す。その他は tunnel 1 へ。
ip route default gateway pp 1 filter 9000 gateway tunnel 1
# radiko.jp へのアクセスを捕捉する
ip filter 9000 pass * radiko.jp * * *
```
音声ストリームは別ドメインから来るようですが、地域判定自体は`radiko.jp`にアクセスした時点で決まるので、これで大丈夫そうです。

## インターフェース切り替えを楽にする
試行錯誤するときには片方のインターフェースの有効/無効を切り替えたくなるので、実際には'ip route'コマンドを以下のようにしています。

```shell
ip route default gateway pp 1 filter 9000 hide gateway tunnel 1 weight 0 hide gateway pp 1 hide
```
こうしておくと、`tunnel disable 1`とするだけで全部のIPv4パケットが`pp 1`へ流れるようになります。逆に`pp disable 1`としてPPPoEを切断すれば、`tunnel 1`が使われます。
`hide`はインターフェースが無効の時に無視させる指定、`weight 0`は両方のインターフェースが有効な時に片方を優先させるための指定です。`weight 0`を外すと両方のインターフェースにパケットが分散されます。
DNSはNGNのIPv6 DNSを使っていれば何もしなくて大丈夫。


## FQDN指定の罠
FQDNでのマッチングでは、ルータが実際のIPアドレスを知るためにDNSクエリをルータに処理させる必要があります。わざとルータのDNSキャッシュサーバ機能をスルーするような設定をしない限りは普通に動きます。

だがしかし、DHCPで配布されるDNSサーバアドレスを無視する**Google Home mini**ってのがありまして。
こいつはGoogle Public DNS(`8.8.8.8`)に直接DNSクエリを投げてます。YAMAHAルータであれば`show ip connection`とか` show nat descriptor address detail`で確認できます。[^1]


```
> show ip connection
(中略)
  58784    4300       domain  U 192.168.0.xxx:38782   > 8.8.8.8:53
```

ルータのDNSサーバ機能をスルーされるので、静的ルーティングのFQDN指定がマッチしなくなり、Google Homeに
> (ラジオ局名)はお住まいの地域では利用できません

と言われてしまいます。

他の端末でradikoにアクセスしてからGoogle Homeに話しかければ回避できるけど面倒です。[^2]
DNSサーバを変更する設定はなさそうなので、DHCPサーバから配布するIPv4アドレスを固定して、送信元IPアドレスを条件に静的ルーティングします。
対象のMACアドレスはGoogle Homeアプリか、`show status dhcp summary`で調べましょう。

設定はこんな感じ。

```shell
# 追加するフィルタ番号を入れておく
ip route default gateway pp 1 filter 9000 9001 hide gateway tunnel 1 weight 0 hide gateway pp 1 hide
# ここは変わらず
ip filter 9000 pass * radiko.jp * * *
# 固定したIPアドレスを条件とするフィルタ
ip filter 9001 pass 192.168.0.199 * * * *
# DHCPのスコープ内からIPアドレスを選んで設定
dhcp scope bind 1 192.168.0.199 11:22:33:44:55:66
```

これでGoogle Homeに怒られずに済みます。
めでたしめでたし。

## マニュアル等

- [フィルタ型ルーティング](http://www.rtpro.yamaha.co.jp/RT/docs/filter-routing/filter-routing.html)
- [ip route コマンド](http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/ip/ip_route.html) ※上記のページはweightキーワードの説明がない
- [dhcp scope bind コマンド](http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/dhcp/dhcp_scope_bind.html)



[^1]: あと、63秒ごとに`8.8.8.8`にpingを打ってる。`nat descriptor timer <descpriper_id> protocol=icmp 60`ってやっておくとNATテーブルをちょっと節約できます。
[^2]: 一旦回避できても、ストリーミングが途中で止まることもある。
for,  for in,  for of,  forEach まとめ

##for
- 基本的な書き方

```
const colors = ["red", "yellow", "green"]

for (let i = 0; i < colors.length; i++) {
  console.log(colors[i])
}
```

##for of
- ES6
- for文をより簡潔に記述できる
- 配列要素の繰り返し処理

```
const colors = ["red", "yellow", "green"]

for(color of colors){
	console.log(color)
}

```

##for in
- ES6
- ブジェクトのプロパティ(キー)分ループしてくれる

```
const colors = { one: "red", two: "yellow", three: "green" }

for (key in colors) {
  console.log(`${key} : ${colors[key]}`)
}
```

##forEach
- ES6
- 配列要素の繰り返し処理（for of と同じ）
- コールバック関数を切り離して記述できる

```
const numbers = [1, 2, 3, 4, 5]
let sum = 0

const adder = (number) => (sum += number)
numbers.forEach(adder)
console.log(sum)
```
ゼロから始めるLeetCode Day84「142. Linked List Cycle Ⅱ」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

Python3で解いています。

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day83 「102. Binary Tree Level Order Traversal」](https://qiita.com/KueharX/items/ddf57a3f819e70f7e61f)


[Twitter](https://twitter.com/kueharx)やってます。

**[技術ブログ](https://kueharx.blogspot.com/)始めました！！**
技術はLeetCode、Django、Nuxt、あたりについて書くと思います。**こちらの方が更新は早いので**、よければブクマよろしくお願いいたします！

# 問題
[142. Linked List Cycle Ⅱ](https://leetcode.com/problems/linked-list-cycle-ii/)
難易度はMedium。
前回もそうでしたが、問題集からの抜粋です。

問題としては、以前解いた[Linked List Cycle](https://qiita.com/KueharX/items/20f411ebf1c53cff2208)と似たような形式です。
連結リストが与えられます。その連結リストのサイクルが始まるノードを返します。仮にサイクルがない場合はnullを返します。

与えられた連結リスト内のサイクルを表現するには、連結リスト内の末尾が接続する位置（インデックス0）を表す整数posを使用します。posが-1の場合、リンク先リストにはサイクルはありません。

注意：リンク先のリストを変更しないでください。


>Example 1:

>Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.

>Example 2:

>Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.

>Example 3:

>Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.


# 解法

```python
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        if not head:
            return None
        root,dic = head,{}
        while root:
            if root in dic:
                return root
            dic[root] = 1
            root = root.next
        return root
# Runtime: 56 ms, faster than 51.83% of Python3 online submissions for Linked List Cycle II.
# Memory Usage: 16.9 MB, less than 51.15% of Python3 online submissions for Linked List Cycle II.
```

辞書を使って管理しました。

あとで考え直してみたら二つpointerを使って解いた方が分かりやすい気がしましたがまあ今回はこれでいいかなと思います。
~~解き続けることが一番重要ですしね!!~~

では今回はここまで。お疲れ様でした。
zshの履歴検索を便利にする

#.zshrcに書き込む
Zshでこれを使えば、↑や↓を押したとき入力履歴の補完を行える。

以下の2行を`.zshrc`に書き込む

```
bindkey "^[[A" history-beginning-search-backward
bindkey "^[[B" history-beginning-search-forward
```
第五回Try English LT! for engineers 発表資料まとめ

# Try English LT! for engineersとは？

エンジニア向けの英語のみのLTイベントを行なっています！
毎回、LTのスピーカー募集してます！エンジニア向けの内容であればテーマは自由です。
英語でLTをやるとなると、中々ハードルが高く、 参加者が海外の人ばかりだと、なおさら難しく感じると思います。
ちょっと自信はないけど、 英語のLTにチャレンジしてみたいという人にぜひ発表してもらいたいです。
英語が好きなエンジニア同士で交流できるイベント運営ができればと思っています。

第五回イベントページ
https://try-english-lt.connpass.com/event/178498/

## 発表資料
・Nobu
How I work in the global team of the Japanese company
私がどのように日系企業のグローバルチームで働いているか
https://docs.google.com/presentation/d/1cOLJJxVR9TdrOTUHckVySZQ6dmkV-CRP9kbyDdPOw5w/edit?usp=sharing

・Yui さん
The reason why I am studying NoCode.
私がノーコードを勉強している理由
https://drive.google.com/file/d/1bhhujmzqN7dlZ6tOTYKNu9lzordrlPvi/view

・akihide さん
The Wall between Designers and Engineers - Storybook
https://www.slideshare.net/AKIHIDEEgashira/the-wall-to-control-storybook-for-engineers-for-designers

・Qaiyyum さん
LEARNING HOW TO LEARN
https://drive.google.com/file/d/1pstztq4aR1NyX3S9A0c3xqOlDXHcBZA1/view

・willsmile さん
Potentiality of using Raspberry Pi as Application Dev Environment
ラズベリーパイを開発環境とするのポテンシャリティーについての語り
https://speakerdeck.com/willsmile/potentiality-of-using-raspberry-pi-as-application-dev-environment


・b0xp2 さん
A story about releasing a online pairing service for avatars living in virtual worlds
VR上で生きるアバター専用のマッチングサービスをリリースした話
https://speakerdeck.com/boxp/a-story-about-releasing-a-online-pairing-service-for-avatars-living-in-virtual-worlds
MAMPでDB接続にハマったときの話

最近PHPの学習始めました。
学習言語の雑食感が半端ないですが、必要に駆られてやっていることで、挫折したとかではありません。

動画でPHPを学習していたときのMAMP環境でDB接続するときにMySQLに接続できなかったときの話です。
教材では

```php
<?php
try{
  $db=new PDO('mysql:host=127.0.0.1;dbname=mydb;charset=utf8','root','');
}catch(PDOException $e){
  echo 'DB接続エラー：　',$e->getMessage();
}
?>
```
とするように説明されていたのですが、MySQL SQLSTATE[HY000] [1049] Unknown database 'mydb'
とのこと。いや、あるし。

で、色々ググってたらhostにポート番号いれて...というのを見つけたので、
host=127.0.0.1:3306

ん？そもそもMAMP環境でMySQLのポートは3306でいいのか？と思いながら指定するも、案の定変わらず。
とりあえず再起動するか、と思ってやってみると、立ち上がってきたMAMPの初期画面に
![mamp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423589/9138f0e3-5b94-f142-fda2-a71362f491b9.png)

**書いてあるやん！！！**
しかもパスワード間違えてるし。

```php
<?php
try{
  $db=new PDO('mysql:host=127.0.0.1:8889;dbname=mydb;charset=utf8','root','root');
}catch(PDOException $e){
  echo 'DB接続エラー：　',$e->getMessage();
}
?>
```

これで無事接続できました。
【Rails】RspecでCapybaraを使用した際に「undefined method `visit'」というエラーが出た場合の解決方法

# 開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・rspec-rails: 4.0.1
・Capybara: 3.32.2
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

# 原因

Capybaraが読み込めていない。

# 解決方法

## 1.`require`で読み込む

```ruby:spec_helper.rb
require 'capybara/rspec' # 追記
RSpec.configure do |config|
end
```

## 2. 解決方法1で解決しない場合は`DSL`で強制的に読み込む

```ruby:spec_helper.rb
require 'capybara/rspec'
RSpec.configure do |config|
  config.include Capybara::DSL # 追記
end
```
Pythonで文字列を配列にする、または配列を文字列にする方法

Pythonで文字列を配列にする方法、また、配列を文字列にする方法を書いていきます。
よろしくおねがいします。

文字列を配列にする場合。

```
s = 'あいうえお'
print(list(s)) 
print([i for i in s])
#['あ', 'い', 'う', 'え', 'お'] と出力
```

配列を文字列にする場合。

```
print(''.join(['あ', 'い', 'う', 'え', 'お']))
print(*['あ', 'い', 'う', 'え', 'お'], sep='')
#あいうえお と出力
```

数字の配列を文字列にする場合。

```
n = [1, 2, 3, 4, 5]
print(''.join([str(i) for i in n]))
print(*[str(i) for i in n], sep='')
#12345と出力
#joinがintだとエラーが出るので、strに変換しています
```

以上です。
ありがとうございました。
golang appendを使ってスライスから特定の要素を削除

## リソースに対するDELETE
https://tutorialedge.net/golang/creating-restful-api-with-golang/#deleting-articlesにて
deleteArticle関数の中で

```golang:main.go
Articles = append(Articles[:index], Articles[index+1:]... )
```

これ、『スライスの要素を削除しているのだろう。』と推測するのは容易だがどう動いているのか気になったため調べてみた。

このとき、Articlesは以下のJSONを返す。

```
[
{"Id":"1","Title":"Hello","desc":"Article Description","content":"Article Content"},
{"Id":"2","Title":"Hello 2","desc":"Article Description","content":"Article Content"},
{"Id":"3","Title":"Hello 3","desc":"Article Description","content":"Article Content"},
]
```

## append関数
そもそも、appendは第一引数に要素の追加元のスライス、第二引数以降に可変長引数で末尾に追加する要素をとる関数だった。

## 第一引数

第一引数を見てみると、Articles[:index]。indexが2のときを出力する

```
fmt.Printf("%+v", Article[:index])
>> [{Id:1 Title:Hello Desc:Article Description Content:Article Content} {Id:2 Title:Hello 2 Desc:Article Description Content:Article Content}]
```
indexを含まない直前の要素までがすべて含まれている。



## 第二引数
Articles[index+1:]...は何のなのか。
同様に出力するが、indexを0とする。

```
fmt.Printf("%+v", Articles[index+1:])
>> [{Id:2 Title:Hello 2 Desc:Article Description Content:Article Content} {Id:3 Title:Hello 3 Desc:Article Description Content:Article Content}]
```
index+1を含む以降の要素を取得している。つづくは"..."はスライスを展開して可変長引数としてappendに渡している。

## ということは！！！

```
Articles = append(Articles[:index], Articles[index+1:]... )
```

この記述で、特定要素の前後をくっつけることで削除し、Articlesに再代入しているということがわかる。
一行のコードだがappend関数とスライスの要素の取得方法、スライスを展開して間変調引数として渡す方法と基礎文法の良い復習となった。
Recoilで動的に初期stateを与える方法

## やりたいこと

みんな大好きstate管理の雄、[Recoil](https://recoiljs.org/)。
ユニットテストをするときや初期状態をどこかのオラクルから与えたい場合の書き方が公式docを見てもわかりづらかったのでメモ

## こうする

`RecoilRoot`の`initializeState`として、初期値を`set`してあげる。

```state.js
import { atom, selector } from "recoil"

export const hogeState = atom({
  key: "hogeState",
  default: true,
})
```
 
```App.js
import { RecoilRoot } from "recoil"
import { hogeState } from "./state"

const initializeState = ({ set }) => {
  // 必要に応じて対象のステート及び値を設定するロジックを追加
  set(hogeState, false)
}

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <RecoilRoot initializeState={initializeState}>
      <Component {...pageProps} />
    </RecoilRoot>
  )
}

export default MyApp


```

かんたんですね。

Recoil、とてもdeveloperフレンドリーなライブラリで好きです。

## 参考
https://recoiljs.org/docs/guides/persistence/
booleanのvalidateについて

booleanのカラムについて、バリデーションをかけたがvalid?がtrueにならず、期待していた実行とは違うものになってしまった！

そこで、booleanのカラムについて調べたことを備忘録としてまとめておく！

ダメなパターン：Notnull制約でfalseが入っているので、presence: trueをすれば良いと思い下記のようにした！

```ruby:
validates :check, presence: true
```

しかし、これだとcheck=falseの時にエラーが出てしまう！

調べてみると、下記のようにする必要があることがわかった！

```ruby:
validates :check, inclusion: {in: [true, false]}
```

参考資料
https://qiita.com/mktakuya/items/a13c2175f0f0d9871038
MacにNodeJSをリーインストールする

# Install NodeJS
```
brew uninstall babel
brew uninstall yarn
sudo rm -rf ~/.npm ~/.nvm ~/node_modules ~/.node-gyp ~/.npmrc ~/.node_repl_history
sudo rm -rf /usr/local/bin/npm /usr/local/bin/node-debug /usr/local/bin/node /usr/local/bin/node-gyp
sudo rm -rf /usr/local/share/man/man1/node* /usr/local/share/man/man1/npm*
sudo rm -rf /usr/local/include/node /usr/local/include/node_modules
sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /usr/local/lib/dtrace/node.d
sudo rm -rf /opt/local/include/node /opt/local/bin/node /opt/local/lib/node
sudo rm -rf /usr/local/share/doc/node
sudo rm -rf /usr/local/share/systemtap/tapset/node.stp

brew uninstall node
brew doctor
brew cleanup --prune-prefix
```

```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.0/install.sh | bash
source ~/.nvm/nvm.sh
nvm install stable
```

# Add command
```
vim ~/.zshrc
source ~/.nvm/nvm.sh
source ~/.zshrc
```

# react
```
npm uninstall -g create-react-app
rm -rf /usr/local/bin/create-react-app
```
リアルタイム地球画像をデスクトップに表示

# 概要

壁紙にリアルタイムの地球画像を表示する話。

![](https://camo.githubusercontent.com/32a8df9c209c416b32aabd482d609e231a2bf382/68747470733a2f2f692e67697068792e636f6d2f6c3376526e4d594e6e6268646e7a3554792e676966)
引用元：[himawaripy][]
提供：情報通信研究機構(NICT)

動作確認環境は以下。

- OS: Ubuntu 18.04
- ディスプレイ: QHD (2560x1440)、Display Port
- Python 3.6.9

# 設定方法

[himawaripy公式ドキュメント][himawaripy] に従って設定する。

## インストール

pipコマンドで[himawaripy][]をインストールする。

```shell
$ pip3 install himawaripy
$ pip3 freeze | grep himawari
himawaripy==2.1.0
```

## 動作確認

動作確認をする。コマンドを実行すると、

```shell
$ himawaripy --auto-offset
himawaripy 2.1.0
Updating...
Latest version: 2020/07/12 00:40:00 GMT.
Detected offset: UTC+09:00
Offset version: 2020/07/11 23:40:00 GMT.
Downloading tiles...
Downloading tiles: 1/64 completed...
...
...
Downloading tiles: 63/64 completed...
Downloading tiles: completed.
Saving to '~/.cache/himawaripy/himawari-20200711T234000.png'...
```

デスクトップに地球画像が表示された。

![himawari.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114392/a4082923-bec8-d746-a5de-f4fbfbd521ab.png)
提供：情報通信研究機構(NICT)

表示された画像はホームのキャッシュディレクトリに作成されている。

```shell
$ ll ~/.cache/himawaripy/
合計 22M
-rw-rw-r--  1 kannkyo kannkyo  22M  7月 12 10:30 himawari-20200712T000000.png
```

[himawaripy][]は、コマンドを実行するたびに以下の処理を自動で行ってくれる。

1. 新しい画像をダウンロード
2. .cacheから古い地球画像を削除
3. 新しい地球画像を格納
4. 壁紙を更新

つまり、コマンドを定期的に叩けば最新の地球画像に更新できる。定期的に叩くのは、crontabを使えば簡単に実現できる。

## 自動化

crontabを使って壁紙の更新を自動化する。

まず、`which`コマンドを使って、[himawaripy][]のインストール先のディレクトリを調べる。

```shell
$ which -- himawaripy
~/.local/bin/himawaripy
```

筆者の環境では、.localにインストールされていた。

次にcrontabの設定ファイルを編集モード`-e`で開く。

```shell
$ crontab -e
```

最後にcrontabに以下の1行を追加する。

```shell
*/10 * * * * <INSTALLATION_PATH> --auto-offset -l 8 -d 2
```

それぞれのパラメータの意味は以下の通りである。

- `*/10 * * * *` 10分おきにコマンドを実行。画像提供元([ひまわりリアルタイムWeb][])は、約20分遅れで10分おきに画像を公開しているので、10分おきにコマンドを実行すれば良い。
- `<INSTALLATION_PATH>` [himawaripy][]のインストール先の絶対パス。
- `--auto-offset` UTCからのオフセット時刻を自動算出。
- `-l 8` 解像度のレベルを8(画像サイズは4400 x 4400、サイズは約20MB)に設定。
- `-d 2` ダウンロード処理のタイムアウト時間を2分に設定。

これでOK。

[ひまわりリアルタイムWeb]: https://himawari8.nict.go.jp/ja/himawari8-help.htm
[himawaripy]: https://github.com/boramalper/himawaripy