OmniAICreator/Qiita-1.07M huggingface dataset:
Jetson Nano へ OpenCV 4.1.1 をインストールめも

# 概要
下記参考にスクリプト内のバージョンを4.1.1に置き換えたが、
一部エラーがでたので、スクリプトを編集しました。

[Jetson Nano へ OpenCV 4.1.0 をインストールする](https://qiita.com/asahi0301/items/3c287190348552f19415)

## 環境
`jetson-nano-sd-r32.2-2019-07-16.zip`を利用してます。

## install_opencv4.1.1_Nano.sh
```
#!/bin/bash
#
# Copyright (c) 2018, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA Corporation and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA Corporation is strictly prohibited.
#

if [ "$#" -ne 1 ]; then
    echo "Usage: $0 <Install Folder>"
    exit
fi
folder="$1"
user="nvidia"
passwd="nvidia"

echo "** Install requirement"
sudo apt-get update
sudo apt-get install -y build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install -y python2.7-dev python3.6-dev python-dev python-numpy python3-numpy
sudo apt-get install -y libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
sudo apt-get install -y libv4l-dev v4l-utils qv4l2 v4l2ucp
sudo apt-get install -y libcanberra-gtk-module libcanberra-gtk3-module
sudo apt-get install -y curl
sudo apt-get update

echo "** Download opencv-4.1.1"
cd $folder
curl -L https://github.com/opencv/opencv/archive/4.1.1.zip -o opencv-4.1.1.zip
curl -L https://github.com/opencv/opencv_contrib/archive/4.1.1.zip -o opencv_contrib-4.1.1.zip
unzip opencv-4.1.1.zip
unzip opencv_contrib-4.1.1.zip
cd opencv-4.1.1/

echo "** Building..."
mkdir release
cd release/
cmake -D WITH_CUDA=ON -D CUDA_ARCH_BIN="5.3" -D CUDA_ARCH_PTX="" -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.1.1/modules -D WITH_GSTREAMER=ON -D WITH_LIBV4L=ON -D BUILD_opencv_python2=ON -D BUILD_opencv_python3=ON -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_EXAMPLES=OFF -D CMAKE_BUILD_TYPE=RELEASE -D ENABLE_PRECOMPILED_HEADERS=OFF -D CMAKE_INSTALL_PREFIX=/usr/local ..

make -j3
sudo make install
sudo apt-get install -y python-opencv python3-opencv

echo "** Install opencv-4.1.1 successfully"
echo "** Bye :)"
```
Ububtu 18.04 環境上にJupyterとQ#環境を構築する

# Ububtu 18.04 環境上にJupyterとQ#環境を構築する

## AnacondaでJupyter環境を構築する

Python環境の構築は[データサイエンティストを目指す人のpython環境構築 2016](https://qiita.com/y__sama/items/5b62d31cb7e6ed50f02c)を参考にして、一部のステップをアップデートしています。

アップデートの内容としては、参考記事では旧版のAnacondaがベースとなっているため、サーチパスを変更した結果、pyenvとAnacondaが一部競合を起こしていますが、これは現在のAnacondaでは解決している問題なので、変更を反映しています。また、それに伴い、bashの設定の変更をするためのステップを追加しています。

### pyenvをインストールする

```{bash}
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
```

### Anacondaをインストールする

```{bash}
pyenv install -l | grep ana
# 最新版を確認する
pyenv install anaconda3-yyyy.MM
# 先のステップで確認した最新版にする
pyenv rehash
pyenv global anaconda3-yyyy.MM
conda update conda
conda init bash
source ~/.bashrc
```

## dotnet coreをインストールする

```{bash}
wget -nv https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo add-apt-repository universe
sudo apt update
sudo apt install apt-transport-https -y
sudo apt install dotnet-sdk-2.2 -y
# 現状の最新版の2.2をインストールする
```

## IQ#をインストールする

```{bash}
dotnet tool install -g Microsoft.Quantum.IQSharp
echo 'export PATH="~/.dotnet/tools:$PATH"' >> ~/.bashrc
# dotnet core へのパスを追加
source ~/.bashrc
dotnet iqsharp install --user
```
三つの値の中央値

# Java による三つの値の中央値の求め方の例
最近「Javaで学ぶアルゴリズムとデータ構造」を読み始め、三つの値の中央値を求める演習問題を解きました。
メモっておくと後々役に立ちそうだったので書いておきます。


```java
	public static void main(String[] args) {
		System.out.println(med3(3, 2, 1)); // [A] a > b > c
		System.out.println(med3(3, 2, 2)); // [B] a > b = c
		System.out.println(med3(3, 1, 2)); // [C] a > c > b
		System.out.println(med3(3, 2, 3)); // [D] a = c > b
		System.out.println(med3(2, 1, 3)); // [E] c > a > b
		System.out.println(med3(3, 3, 2)); // [F] a = b > c
		System.out.println(med3(3, 3, 3)); // [G] a = b = c
		System.out.println(med3(2, 2, 3)); // [H] c > a = b
		System.out.println(med3(2, 3, 1)); // [I] b > a > c
		System.out.println(med3(2, 3, 2)); // [J] b > a = c
		System.out.println(med3(1, 3, 2)); // [K] b > c > a
		System.out.println(med3(2, 3, 3)); // [L] b = c > a
		System.out.println(med3(1, 2, 3)); // [M] c > b > a

	}

	private static int med3(int a, int b, int c) {
		if (a >= b) {
			if (b >= c) {
				return b; // A, B, F, G
			} else if (a <= c) {
				return a; // D, E, H
			} else {
				return c; // C
			}
		} else if (a > c) {
			return a; // I
		} else if (b > c) {
			return c; // J, K
		} else {
			return b; // L, M
		}
	}
```

三つの値の大小関係には13パターンあるため、それぞれのパターンで呼び出してみました。

中央値の求め方には他にもいろいろとあると思いますので、あくまでも一例として参考にしてください。
c++始めてみた：何から始めたらいいの？個人ノート1

#c++何から始めたらいいの？

どうも、C初心者以下のc++独学者です
（何故この言い方なのかは下の記事を読んでみて下さい）
[C++erを簡易的にレベル分けすることで初心者詐欺を減らそうという試み](https://qiita.com/yumetodo/items/a843bd542106215bbc84)

MATLABで簡単なコードの書き方を学び、Pythonを独学している程度なので
c++言語の文法についてほぼ何も分からず、今後やっていけるか不安になりました
（下のサイトの第１−２章を読んで、関連の問題を解いただけしかやっていません）
[AtCoder Programming Guide for beginners](https://atcoder.jp/contests/apg4b)

### **特に、何から始めたらいいのか全く分かりません**

なので、先人達から学ぼうと、下の記事を読んでみました
[C++完全理解ガイド Rev1.4.01](https://qiita.com/_EnumHack/items/b5672ac9be86584a6629)

すると
お？

###””集合知にアクセスする方法を知っていいいことにしよう。つまり、覚えていなくても、何をどう調べればいいかが分かればいいということだ。””

という上の記事が紹介している条件なら達成が出来そうかな？と思い

###分からない事があったら、集合知を頼り、そこから理解する事が出来るようになるレベルまでc++言語を扱える様になる

という今後の目標が出来ました

（因みに、MATLABとPYTHONは、そのレベルまで到達しています）

その目標を達成する為には（上の記事によると）

- コア言語機能
- 標準ライブラリ
- コンパイラについて
- テンプレートメタプログラミング技法
- エラーメッセージの読み方
- 標準にはない外部ライブラリ
- 性能評価
- テスト
- デバッグ
- 規格書
（数学）

これらが出来るようになればいいらしいです
HTTPのリダイレクト時のHTTPステータスコードまとめ

## 前書き
HTTPリクエストのリダイレクトの挙動とhttpのステータスコードの意味、振る舞いについて、個人的に気になったところなどを調べてまとめています。

## 要約

|コード|情報              |意味 |UAによるメソッドの変更|RFC|
|:---|:-----------------|:---|:----------|:----------|
|301 |Moved Permanently |恒久的に移動した|変更される場合がある|1945, 2068, 2616|
|302 |Found             |発見した|変更される場合がある|1945, 2068, 2616|
|303 |See Other         |他を参照せよ|GETに変換されることを期待|2616,7231|
|307 |Temporary Redirect|一時的リダイレクト|変更してはならない|2616,7231|
|308 |Permanent Redirect|恒久的リダイレクト|変更してはならない|7238,7538|

<img width="509" alt="3xx.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210923/3499900e-f96f-6027-8759-2964948e0353.png">
出典: https://postd.cc/choosing-an-http-status-code/

## 301 Moved Permanently
リクエストされたリソースが Location ヘッダーで示された URL に完全に移動したことを示す。ブラウザーはこのページにリダイレクトし、検索エンジンはリソースへのリンクを更新する。

リダイレクトが行われるとき、仕様書ではメソッド (と本文) を変更しないよう要求していたが、歴史的な理由により、ユーザーエージェントはリクエストを変更する場合がある。

すべてのユーザーエージェントが従っている訳ではないので、301のコードは GET または HEAD メソッドのみに使用し、POSTメソッドでは代わりに 308 Permanent Redirect (明確にメソッドの変更が禁止)を使用することが推奨

## 302 Found
リクエストされたリソースが一時的に Location で示された URL へ移動したことを示す。ブラウザーはこのページにリダイレクトしますが、検索エンジンはリソースへのリンクを更新しない。

リダイレクトが行われるとき、仕様書ではメソッド (と本文) を変更しないよう要求していたが、歴史的な理由により、ユーザーエージェントはリクエストを変更する場合がある。

すべてのユーザーエージェントが従っている訳ではないので、302のコードは GET または HEAD メソッドのみに使用し、POSTメソッドでは代わりに 307 Temporary Redirect (明確にメソッドの変更が禁止)を使用することが推奨。

## 303 See Other
オリジンサーバーがHTTP経由でサーバーによって転送できるターゲットリソースの表現を持っていないことを示す。

このステータスコードはロケーションヘッダーとともに使用する必要があり、サーバーがPOSTまたはその他のべき等でない要求に303 See Other応答とロケーションヘッダーの値で応答する場合、クライアントはGETメソッドを使用してロケーションヘッダーに記載されているリソースを取得することが期待される。

用途としては、PUT メソッドへのレスポンスで、アップロードされたリソースではないところで「XYZ のアップロードに成功しました」のような確認メッセージを表示したい場合や、アップロード進捗ページのような別なページであることを示す場合に便利。

## 307 Temporary Redirect
リクエストされたリソースが一時的に Location で示された URL へ移動したことを示す。元のリクエストのメソッドと本文は、リダイレクトされたリクエストを行う際に再利用されることを期待する。

307 と 302 の違いは、 307 はリダイレクトされたリクエストが行われるときに、メソッドと本文が変更されないことが保証されること。 これをもう少し噛み砕くと、302 では、一部の古いクライアントは不正にメソッドを GET に変更するものがあるが、307 では、変更してはならない。

ただし、Google chromeなどでは 307 が Internal Redirect としてHSTSのリダイレクト時に使われている。

## 308 Permanent Redirect
クエストされたリソースが Location ヘッダーで示された URL へ完全に移動したことを示す。ブラウザーはこのページにリダイレクトし、検索エンジンはリソースへのリンクを更新する。

308 と 301 の違いは、 308 はリダイレクトされたリクエストが行われるときに、メソッドと本文が変更されないことが保証されること。 これをもう少し噛み砕くと、301 では、一部の古いクライアントは不正にメソッドを GET に変更するものがあるが、308 では、変更してはならない。

ただし、ウェブアプリケーションによっては、 308 Permanent Redirect を標準外かつ他の目的に使用していることがある。例えば、 Google Drive はアップロードが不完全に停止したことを表すために、308 Resume Incomplete レスポンスを使用している。

## 参考
https://tools.ietf.org/html/rfc1945
https://tools.ietf.org/html/rfc2068
https://tools.ietf.org/html/rfc2616
https://tools.ietf.org/html/rfc7231
https://tools.ietf.org/html/rfc7238
https://tools.ietf.org/html/rfc7538
https://postd.cc/choosing-an-http-status-code/
https://www.techscore.com/blog/2016/01/23/http-redirection-status-code/
https://developer.mozilla.org/ja/docs/Web/HTTP/Status/301
https://developer.mozilla.org/ja/docs/Web/HTTP/Status/302
https://developer.mozilla.org/ja/docs/Web/HTTP/Status/303
https://developer.mozilla.org/ja/docs/Web/HTTP/Status/307
https://developer.mozilla.org/ja/docs/Web/HTTP/Status/308
omuniauthのGoogle認証でめちゃくちゃ詰まった話。無事解決できたよ！！！

どうも！！！
チャンクノです！！！

今回はomuniauthのGoogle認証でめちゃくちゃ詰まった話について書きますよー。
自分は今やっているチーム開発でFacebookとGoogle認証を用いた新規登録とログイン機能を実装しています。
Facebookはちょっとつまりつつもなんとかできました。
で、これは調べてもらえればわかるんですけど認証機能を実装するためのコードってFacebookもGoogleも共通のコードを使うんですよね。すなわちFacebookができたならgoogleもできるはずなんです。
しかし！！！
Googleがなぜかできない、、、
認証はできているのだがDBに保存されず必死にググり続け、その後メンターさんに聞いたところ
 「ターミナルを見てみましょう」とのお声がありました。
実際にみてみると

```
 ERROR -- omniauth: (google_oauth2) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected
```
こんなエラーが書いてありました。
結論から言うとこのエラーの内容はよくわかんないです。
ただ回避策がありました。
google認証にはgem 'omniauth-google-oauth2'というgemを使います。
まずはこれのバージョンをさげてbundle installします。自分は0.5.4でできました！！！
次にconfig/initializerの中にomniauth.rbファイルを作成
omniauth.rbの中に

```
Rails.application.config.middleware.use OmniAuth::Builder do
{:provider_ignores_state => true}
end
```
を記述する。
以上です。
これでできるはずです。

一日この機能に費やして途中は本当に心が折れそうでした、、、。(なんなら折れてた)
でもコードがちゃんと動いてDBに保存された時はめちゃくちゃ嬉しかったです！！！
ぶっちゃけ少し泣きそうになりました。
大切なのはターミナルもみることですね。
いい経験になりました。
これからもエラーとの戦いを頑張って制していきます💪
それでは皆様の良きプログラミングライフを祈って🙏🙏🙏

Facebook,Google認証機能実装の参考記事
https://mchinta.hatenablog.com/entry/2019/01/04/115312
https://qiita.com/hidepino/items/a1eb9d2f32ce33389f20
laravelの環境構築で出たSymfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR) Class 'Predis\Client' not foundの解決方法

##Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_ERROR) Class 'Predis\Client' not found

### Class"Predis"がないとのこと。

composer.jsonに追記

```composer.json
"require": {
    "predis/predis": "~1.1.1@dev"
}
```
composer.jsonのあるディレクトリでアップデート

```
$ composer update
```
### 参考
[@kai_plus](https://qiita.com/kai_plus/items/b7a60c0abac8cc0d40ec)
ヴァージョンアップしてました。

## 後書き
お気づき、ご指摘がありましたら
とても助かります。
よろしくお願いします。
Ankiの回答画面にGoogleの検索リンクを追加する

## 暗記学習用アプリ「Anki」について
「[Anki](https://apps.ankiweb.net/)」は、Damien Elmes氏によって開発されたオープンソースの学習用アプリです。
問題文と解答をペアにした暗記カードの問題集を自作、もしくは他のユーザーによって作成された問題集をダウンロードして学習に利用できます。
正答するごとに次回出題までの期間が伸びるのが特徴で、間違えた問題は答えられるようになるまで頻繁に出題される一方、簡単な問題の出題頻度は下がっていくという設計になっています。

###Googleの検索リンクを追加
私は現在同アプリを世界史の学習に利用していますが、回答したキーワードの詳細を検索したくなることがよくありました。
Ankiの出題／回答画面では素のJavaScriptを実行できるらしく、回答をクリックするとGoogleの検索ページに遷移するリンクを埋め込む機能を作ったので公開します。

ちなみに、以下に紹介する方法は、問題タイプが穴埋め問題（cloze）のみで利用可能です。「Front + Back」のようなシンプルなカードの場合の手順は、最後に記しておきます。
また、以下の手順の**実行前には念の為バックアップをとって、自己の責任においてご利用ください**。

##手順
まず、PC版のアプリから「ブラウザ」を起動して下記のような画面から編集したいカードタイプが使われている問題を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373496/1ff3bf8c-2fcc-75aa-1006-ef9c84e83feb.png)
「カード…」というボタンをクリックすると、下記のような編集画面が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373496/f380de13-08b5-b84c-fbf7-fe61c1f5b017.png)
今回は上記画像の「裏面のプレビュー」に表示されている回答画面で、「クレマンソー」をクリックしたら、[Googleの検索結果](https://www.google.com/search?q=%E3%82%AF%E3%83%AC%E3%83%9E%E3%83%B3%E3%82%BD%E3%83%BC)をChromeやSafariなどのブラウザで開くリンクを挿入します。
そのためには、「裏面のテンプレート」欄に下記のスクリプトを追加してください。

```HTML
<script>
var clzElms = document.getElementsByClassName('cloze');
  for(var i = 0; i<clzElms.length; i++) {
  var searchWord = clzElms.item(i).textContent;
clzElms.item(i).innerHTML = '<a href="https://www.google.com/search?q=' + searchWord + '">' + searchWord + '</a>';
}
</script>
```
すると、下記のように「クレマンソー」がリンクに変化したのがわかると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373496/7abe8095-4a92-ce46-3bce-90f7ae44b185.png)
クリックしてみると、検索結果がブラウザで開くようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373496/e0a12973-6b12-5f49-c9bd-e56ec44d7992.png)
もし、リンクの書式が見にくい場合には「書式（カード間で共有）」の欄に以下のCSSを追加します。

```CSS
a:link{
 color: lightblue;
 text-decoration: none;
}
```
リンクを下記のように任意の書式で上書きできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373496/91352175-a9b9-0148-4cb7-b4395c82ae7d.png)

##穴埋め問題以外の場合
上記で紹介した方法は、出題タイプが穴埋め問題（cloze）のみで利用可能ですが、「Front + Back」のようなシンプルなカードの場合、「裏面のテンプレート」欄を以下のようにするだけで回答画面に検索結果のリンクを追加できます。

```HTML
<a href="https://www.google.com/search?q={{Back}}">{{Back}}</a>
```

##おわりに
Ankiは中身がPythonで書かれているらしくアドオン作成などは私には難しいと思いますが、今後もAnkiにゴミ機能を追加できたら随時お知らせしていこうと思います。
Macのシンボリックリンク活用方法

# シンボリックリンクとは
ショートカットリンクのようなものですが、操作する際に元のファイルやフォルダと同等に扱うことができます。Mac OS XのエイリアスやWindowsのショートカットに似ていますが、より便利な仕組みです。

## シンボリックリンクの便利なところ
エイリアスやショートカットが、ただのリンクであるのに対して、シンボリックリンクは、元のファイルやフォルダと同等に扱うことができます。その為、システムやアプリからも元のファイルやフォルダとして扱うことができる点がとても便利です。

また、シンボリックリンクはあくまでファイルやフォルダの参照するファイルなので、シンボリックリンクを削除したとしても、対象のファイルやフォルダが削除されることはありません。

* エイリアス（alias）とは何？  
エイリアスとは、偽名、別名、通称などの意味を持つ英単語です。ITの分野では、ファイルなどの実体を別の名前で参照するためのシンボルといった意味で使われることが多いものです。

# シンボリックリンク活用と作成方法
実際にどのような時にシンボリックリンクを使用するのか、活用方法と作成方法をまとめます。

## シンボリックリンク活用
オンラインストレージ（DropboxやBOXなど）を活用して、複数のユーザーとの間でデータの共有や同期をおこなうプロジェクトの場合、個人のアプリ（Photoshopなど）によってはファイルやフォルダを同期できるフォルダからアプリ指定のフォルダへ移動する必要があります。
このような時に、編集するデータをオンラインストレージの同期できるフォルダに置き、そのシンボリックリンクをアプリ指定のフォルダに置くことで、データの移動をすること無く、データを同期することが可能になります。

## Macでシンボリックリンクを作成する方法
Macでシンボリックリンクを作成する場合、ターミナルで次のコマンドを実行します。

```
ln -s (シンボリックリンクを作成したいフォルダやファイルのパス) (シンボリックリンクを置きたいフォルダのパス)
```
コマンドとそれぞれのフォルダの間には、半角スペースを入れます。

参考: 
[Macでシンボリックリンクを作る](https://qiita.com/yamaki/items/9e1f3340e8134c4bcac8)

# まとめ
上記の方法を活用して、Dropbox内にシンボリックリンクを配置し、そこからバックアップしたいファルダやファイルを参照することができました。
C++とpythonを比べて、プログラミング初心者はどちらから始めるべき?

#事の起こり
仕事でC++を学んでちょうど2ヶ月経ちました。私は学生時代はpythonを学んでいたので、両者の使用感の比較とプログラミング初学者にC++進めるべきか否か、個人的な感想を書いてみたいと思います。

#C++に関して感じること
やっぱり、噂に違わず難しい言語だと感じます。メモリ管理を意識しながらオブジェクト指向を活用するのはやはり難しいです。コンパイラもメモリに関するエラーとオブジェクト指向に関するエラーを吐いてくるので、**何言っているのか分からない状態**の時も非常に多く対処も大変です。(私は職場の研修でC言語をみっちりやりましたがそれでもきついです)。最も難しいと言われる所以を実感しています。

#C++の良い点
###①勉強になる
C++に取り組むだけで、オブジェクト指向からポインタまで、メモリ周りの知識を幅広く学ぶことができます。むしろ、最初からC++でモノを作ることは捨てて、プログラミングそのものの知識を深めるためだけに学んでも良い言語なのかも知れません。

###②言語仕様に精通するだけで市場価値が高まる
C++を使いこなせる人はあまりいません。それ故に、C++を使いこなせる人の市場価値は高いです。(そう信じたい)。それに組込みではpythonと比べて、圧倒的に使用されています。将来、ロボティクスという男の憧れの分野に携わりたい人は断然、C++ですね。

###③速い
C++は適当に書いても速いです。私がpythonから入ったからかも知れませんが比較するとやはり速いです。**他の言語でアルゴリズムや処理の手順を工夫してもC++より遅いなんてことは多々あります**。組み込みやゲームプログラミングなど速さ至上主義な現場で使われる理由も納得です。

###④他の言語習得のハードルを爆下げできます。
**C++を学んで2ヶ月くらいでJavaのコードはほとんど読めるようになりました**。最近は凋落したと言われているJavaですが、圧倒的に求人も多く安定しています。なので、C++を学ぶ事でJavaの学習のハードルも下げられる点はお得だと感じます。(C++が読めたらpythonも簡単に読めると思います。)
色んな記事で、C++を学ぶ事で他の言語の習得ハードルを下げることができると言われていますがこれは真実だと感じます。


#C++と比較したときのpythonの良い点・悪い点
###①言語仕様が簡単(良い点)
**誰が書いてもコードの意図が伝わりやすい。**これはpythonの素晴らしい利点の一つです。学習に行き詰まった時も、検索して出てきたコードが読みやすいので問題解決の時間も短くて済みます。C++だと適当に検索して出てきたコードすらも、工夫が凝らされており一筋縄では読めないことも多いです。問題に直面した時の解決の速さはpythonの圧勝だと感じます。

###②簡単になんでもできる。(良い点)
比喩抜きで、pythonはなんでもできます。人工知能もデータサイエンスも通信、パケット解析、本当になんでもできます。しかも、簡単です。pythonを使えるだけで人生で学べることの範囲が格段に増えて楽しいです。面白そうな分野の参考書も多いです。C++も昔からあるので、なんでもできることはできますが**ライブラリ自体が難しく、自由の代償を払わされている感じが拭えません。**あと、C++は人工知能などの面白そうな参考書が少ないです。(分厚い言語仕様の本の数ならC++はどの言語にも負けません!!)

###③他のpython使いの人との差別化が大変(悪い点)
①でも触れましたが、誰が書いても同じようなコードになるので初心者と中級者を隔てる壁が低く、pythonを書けるくらいでは市場価値は高まりません。pythonの求人を見たらわかることですが、pythonを使って活躍できる人は人工知能やデータサイエンスの知識を持っており、バックグラウンドが強いです。結果として、**python自体の学習コストは低いがpythonで活躍するためのコストは高く**、結果として求められる努力の量はC++と変わらないという印象を受けます。

#初学者はどちらを選択すべきか
私の個人的な意見ですがやはりpythonです。理由は単純で、色んなことができて楽しいからです。同じ学習時間をかけた場合に、**できるようになることの幅の広さ**はpythonが圧倒的だと感じます。これは、プログラミング学習をする上で大きなモチベーションになります。(結局、C++だろうがpythonだろうが途中で挫折したら意味ないですしね)。
**私はC++は面白くやりがごたえのある言語だと感じていますが、大学でpythonからプログラミングの楽しさを学んで、研修でC言語とメモリ周りの知識を習得した上でそう感じています。**正直、pythonとcを学んでいなかったら、1週間くらいでc++学習に挫折しても不思議はなかったと思います。

#結論
ステマみたいになってしまいましたが、やっぱり、初心者はpython。これに尽きます。しかし、pythonはインタープリンタ言語でC++はコンパイラ言語なので一言に比較できない面もあります。両方利点があると言いたいところですが、初学者にオススメするなら私はpython一択です。
js ブラウザからの音声データの取得

#MediaDevices.getUserMedia()
MediaDevices.getUserMedia() メソッドは、要求された種類のメディアを含むトラックを持つ MediaStream を生成するメディア入力を使用する許可をユーザーに求めます。このストリームには、例えば、動画トラック (カメラ、ビデオ録画機器、スクリーン共有サービスなどのような、ハードウェアまたは仮想ビデオソースによって生み出される)、音声トラック (同様に、マイク、A/D 変換器などの物理的または仮想オーディオソースによって生み出される)、その他の可能な種別を含めることができます。

##ブラウザからの音声データ取得
```html
  <audio autoplay></audio>

  <script>
    // Prefer camera resolution nearest to 1280x720.
var constraints = { audio: true, video: false }; 

navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
  var video = document.querySelector('audio');
  video.srcObject = mediaStream;
  video.onloadedmetadata = function(e) {
    video.play();
  };
})
.catch(function(err) { console.log(err.name + ": " + err.message); }); // always check for errors at the end.
  </script>
```


#参考
https://developer.mozilla.org/ja/docs/Web/API/MediaDevices/getUserMedia
【Swift】次の要素も一緒に処理したい

タイトルの表現で意図が伝わるかどうか怪しいのですが、要は配列を処理するときに次のインデックスの要素も欲しかったのです。
ということでArrayの拡張を作ってみました。

Swiftのバージョンは5.1です。

## 定義
```swift:Array+extensions.swift
extension Array {
    func pair(oneEach: Bool = false) -> [(Element, Element?)] {
        var copy: [Element?] = self
        copy.append(nil)
        
        return self.enumerated()
            .filter { oneEach ? true : $0.offset % 2 == 0 }
            .map { ($0.element, copy[$0.offset + 1]) }
    }
}
```

## 呼び出し側

### 1要素ずつ処理する
こんな感じで使えます。
`(0, 1) -> (1, 2) -> (2, 3) -> ...` で取得できるイメージです。

```swift:oneEach=trueの例
let nums = [1, 2, 3, 4, 5]
nums.pair(oneEach: true).forEach { num1, num2 in
    print("\(num1) * \(num2 ?? 0) = \(num1 * (num2 ?? 0))")
}

// 1 * 2 = 2
// 2 * 3 = 6
// 3 * 4 = 12
// 4 * 5 = 20
// 5 * 0 = 0
```

### 1要素おきに処理する

あるいはこんな感じで使えます。
`(0, 1) -> (2, 3) -> (4, 5) -> ...` で取得できます。

```swift:oneEach=falseの例
let strs = ["夜神","月","高田","清美","L"]
strs.pair().forEach { str1, str2 in
    print(str1 + (str2 ?? ""))
}

// 夜神月
// 高田清美
// L
```

個人的に欲しかった拡張が作れて満足です🙆‍♂️
コードで書く画面遷移　アラート swift 

#『はい』、『いいえ』画面遷移

<img width="332" alt="スクリーンショット 2019-08-13 2.00.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407730/01c9987e-eef4-aaab-9052-9241b8fafa79.png">

##はじめに、、、


```swift:alart.swift
 override func viewDidAppear(_ animated: Bool) {
```

<dl>
 <dd>この一行をかき、アラートが画面に見えてる状態にします </dd>
</dl>

##タイトルとメッセージ（上二段）



```swift:alart.swift
        let matchAlert : UIAlertController = UIAlertController(title: "マッチしました", message: "トークをはじめますか？", preferredStyle: UIAlertController.Style.alert)
```

##「はい」の場合
```swift:alert.swift
     let yesAction : UIAlertAction = UIAlertAction(title: "はい", style: UIAlertAction.Style.default){
            action in
            let ChatController = chatController()
            self.present(UINavigationController(rootViewController: ChatController),animated: true , completion: nil)
        }
```

<dl>
 <dd>初めに、「はい」をletの後に <b>”yes action” <b>と定義します。 </dd>
 <dd>次に、"title"に表示されるメッセージを記入します。 </dd>
 <dd>ここから<b>画面遷移</b>についてです。</dd>
<dd>"action in"の後のletに遷移先のコントローラを好きな名前に定義します。
<dd>今回の場合”Chatcontroller”と定義し遷移先のview controller名を”＝”の後に書きます。</dd><dd>今回,遷移先のview controllerの名前が”chatController”ですので"="の後、</dd>
<dd>”chat controller”と書きます。</dd>
<dd>この時、後ろに <b>（） </b>を忘れず書いてください。
<dd>又、定義名とコントローラ名は<b>同じ名前</b>は使用できません。</dd>
<dd>そのため、定義の方の”c”を<b>大文字</b>に変えています。</dd>
<dd>上で定義したコントローラ名を"rootViewController"の後ろに書きます。
<dd>今回の"Chatcontroller"ですので上記のように書きます。</dd>

<dd><b>この時presentの前にselfをつけ忘れたらエラーが出たので忘れずにつけてください。</b></dd>
</dl>

####「いいえ」も上記と同じように書きますが"action in"の後の定義コントローラ名が被らないよう、気をつけてください。又遷移先が異なるため、"chatController"のところをまた別の遷移先のviewController名に変えてください。

##最後に、、
```swift:alert.swift
  matchAlert.addAction(yesAction)
        matchAlert.addAction(noAction)
        present(matchAlert, animated:true, completion: nil)
    }
```
<dl>
 <dd>"match alert"はタイトルとメッセージで定義したものです。 </dd>
 <dd>()にそれぞれの選択肢の存在を書いてください</dd>
</dl>
    
##まとめ
```swift:alert.swift
    override func viewDidAppear(_ animated: Bool) {
        
        let matchAlert : UIAlertController = UIAlertController(title: "マッチしました", message: "トークをはじめますか？", preferredStyle: UIAlertController.Style.alert)
        
        let yesAction : UIAlertAction = UIAlertAction(title: "はい", style: UIAlertAction.Style.default){
            action in
            let ChatController = chatController()
            self.present(UINavigationController(rootViewController: ChatController),animated: true , completion: nil)
        }
        
        let noAction : UIAlertAction = UIAlertAction(title: "いいえ", style: UIAlertAction.Style.cancel){
            action in
            let noController = HomeController()
            self.present(UINavigationController(rootViewController: noController), animated: true, completion: nil)
        }
        
        matchAlert.addAction(yesAction)
        matchAlert.addAction(noAction)
        present(matchAlert, animated:true, completion: nil)
        
        
    }
```

<dl>
 <dd>以上の記事はプログラミング初心者によって書かれているため、コードが間違っている場合がございます。 </dd>
 <dd>もし、そのようであれば教えて頂けると幸いです</dd>
</dl>
初心者がまとめた「要素」についてのお話

#はじめに
未来電子テクノロジーでインターンをしている＠reies1204です。
今回は自分が以前に学んだ際に、案外分かっていそうでよく理解しなかったまま、とりあえずスルーしていた「要素」について復習も兼ねてまとめてみようと思います。
ただし、プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。


#ブロック要素とは
まずブロック要素とは、要素の前後に改行が入り、ブロックのように積み上がっていくような表示になる要素です。
例えば`<p>``<div>``<ul>``<h1~h6>``<header>``<main>``<footer>`など、、、
具体的にはこんな感じ。
<p><font color="red">ブロック要素とは</font></p>
<p><font color="blue">ブロック要素とは</font></p>
ちょっとわかりにくいですが、今これはブロック要素で表示されています。
####ブロック要素の特徴
* <b>縦</b>に表示されていく
* 幅(width)と高さ(height)が<b>指定できる<b/>
* marginとpaddingを<b>指定できる</b>
* textーalignが要素の真ん中に適用される
* 要素のボリュームに関わらず、<b>横いっぱいに広げられる</b>


#インライン要素とは
一方でインライン要素とは、ブロック要素のように改行が入らず、テキストの一部としてブロック要素の途中に差し込むことができる要素です。
例えば`<a>``<b>``<span>``<font>`など、、、
具体的にはこんな感じ。
<p>ブロック要素の中に<b>インライン要素</b>が入ります</p>
これはインライン要素として`<b>`を使ってます
####インライン要素の特徴
* <b>横</b>に表示されていく
* 幅(width)と高さ(height)が<b>指定できない</b>
* marginとpaddingを<b>左右だけ指定できる</b>
* text-alignは<b>親要素につけることで</b>指定できる
　


#インラインブロック要素とは
インラインブロック要素とは、要素の並び方がインライン、要素の中身がブロック要素のような特徴を持つ、ブロック要素とインライン要素のいいとこをとったような要素です。
基本的にボタンなど要素を横に並べたいときに便利です。
####インラインブロック要素の特徴
* <b>横</b>に表示される
* 幅(width)と高さ(height)を<b>指定できる</b>
* marginとpaddingを<b>指定できる</b>
* text-alignは<b>親要素につけることで</b>指定できる


#これらはCSSで変更可
以上まとめてきた要素については、CSSで「display」プロパティによって指定し直すことで、それぞれ変更することができます。


#さいごに
以上基本的な部分である「要素」についてまとめてきました。
言葉の意味やコードの意味などを理解できていないうちは、基本的な部分であってもとりあえずスルーしがちになってしまうので、これからの学習においてそういった場面に出くわした際にはしっかり理解まで持って行こうと思います。
これからも学習を継続して頑張っていきます。
量子コンピュータをどの書籍から学べば良いか？

量子コンピュータに興味はあるけれど、どの書籍から順に学べば良いか分からない人も多いと思います。
そこで、日本語の量子コンピュータ書籍のうち代表的なものについて、レベル感を紹介します。
後半は、レベルに隙間がある問題と、それを埋める本の紹介(宣伝)です。

この記事は2019年8月時点の状況に基づいて記述しました。
また、書籍についてのみ触れており、Webコンテンツは対象外としています。

# 日本語の量子コンピュータ書籍のレベル感

「日本語の書籍で量子コンピュータを学ぶ」を前提としたとき、どの書籍から学べば良いのでしょうか？
もちろん、人によって目的・知識も違うため、最適解は異なります。
ただ、参考になる方も多いと思われるため、日本語の量子コンピュータ書籍のレベル感をまとめてみました。
これがすべての書籍ではありませんが、ある程度傾向を表しているかと思います。
ご自身のレベルにあった書籍から始めて、2冊目や3冊目で右側のレベルの書籍を読むのが良いと思います。

![日本語の量子コンピュータ書籍のレベル感.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/6086f598-9891-2dd7-226a-6014fea28a58.png)

各レベルのざっくりとした説明と代表的な書籍は、次の通りです。

### 一般向け書籍
数式はあまりなく、概念の説明が中心。普通の書店に置いてあります。

- [いちばんやさしい量子コンピューターの教本](https://www.amazon.co.jp/dp/4295006076/)
- [絵で見てわかる量子コンピュータの仕組み](https://www.amazon.co.jp/dp/4798157465/)


### 愛好家向け書籍
一般向けの概念的な説明に加えて、高校生向け＋αくらいの数式も登場します。ちょうど良いか、少し歯ごたえがあると感じるITエンジニアの方が多そう。ブルーバックスくらいのレベルです。

- [量子コンピュータ―超並列計算のからくり](https://www.amazon.co.jp/dp/4062574691/)

### 大学教養向け書籍
大学教養課程のレベル。数式は当たり前のように登場します。線形代数を平行で学びつつ読むイメージ。大きな書店に行かないと置いていません。

- [量子情報科学入門](https://www.amazon.co.jp/dp/4320122992/)(専門書の要素もあるが)

### 専門書
大学専門課程～大学院生のレベル。線形代数等の数学や量子力学を知っていると読みやすいと思います。大きな書店に行かないと置いていません。
ちなみに、「量子コンピュータと量子通信」は翻訳出版権の期間が過ぎているため重版や電子版の制作ができず、入手困難になっています。

- [量子コンピュータと量子通信I](https://www.amazon.co.jp/dp/4274200078/)
- [量子コンピュータと量子通信II](https://www.amazon.co.jp/dp/4274200086/)
- [量子コンピュータと量子通信III](https://www.amazon.co.jp/dp/4274200094/)


# 愛好家向け書籍～大学教養向け書籍がほとんど存在しない

さきほどの図を見ると分かる通り、愛好家向け書籍～大学教養向け書籍はほとんど存在しません。
伝統がある分野ではなく比較的新しい分野なので仕方がないですが、このギャップは日本語の書籍で量子コンピュータを学ぶのに障害になるんじゃないかと思います。

では、どうすれば良いでしょうか？
実は量子コンピュータの同人誌を執筆している人たちがおり(私もそうですが)、この領域に含まれる量子コンピュータ同人誌が存在します。
Googleで「量子コンピュータ 同人誌」と検索するといくつか出てきますので、これら書籍で学ぶのも良いと思います。
自分で書いている同人誌で恐縮ですが、たとえば、**愛好家向け書籍**のレベルの内容として次のような書籍があります。

**「高校数学からはじめる量子コンピュータ」**
<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13107/9295f6e1-6fb3-9558-0842-2a377b080b95.png">

この書籍では、手計算やPythonで動作を確認しながら、ゆっくりと丁寧に量子コンピュータを理解します。
最終章では、実際に量子コンピュータの実機を使い自作プログラムを動かします。
2次元ベクトルや2x2行列が分かれば読み進められると思いますし、数学については「行列の説明」レベルから巻末に書いてあります。
そのため、読んで面白いと感じるITエンジニアの方は多いのではないかと思います。

紙版と電子版があり、次のサイトから購入できます。

- [紙版 (https://www.melonbooks.co.jp/detail/detail.php?product_id=523676)](https://www.melonbooks.co.jp/detail/detail.php?product_id=523676)
- [電子版 (https://snuffkin.booth.pm/items/1453028)](https://snuffkin.booth.pm/items/1453028)

「愛好家向け書籍～大学教養向け書籍がほとんど存在しない」問題を解決し、多くの人が量子コンピュータを学びやすくするために、今後も量子コンピュータ同人誌等を書こうと考えています。
【python】文字列を逆順にする、回文かを判定する

##1.文字列を逆順にする
~~~python.revers_string.py
def revers_string(string):return string[::-1]
~~~

これで逆になる。

スライス記法の負のステップを利用している。

>スライス記法
[始端:終端:ステップ数]


一つ目の":"の両脇は、始端、終端を意味する。
始端、終端に何も指定しないと、文字列の最初から最後まで、という事になる。
(終端に-1を指定すると、文字列の末尾指定したりも出来る)


二つ目の":"の右側はステップを意味する。
負の数にすると、終端から始端へステップ分減っていく処理になる。


つまり、上記コードは引数に"あいうえお"と入力した際、
始端が0、終端が5となり、-1でステップするため、逆順処理となり、
"おえういあ"が戻り値となる。


##2.文字列が回文か調べる
~~~python.check_palindrome_string.py
def check_palindrome_string(string):return string==string[::-1]
~~~

1の文を利用して、文字列が回文かを調べる関数。
スライスって便利だね。
【非エンジニア・SE初心者用】rubyでクローリングのやり方

# はじめに
執筆者である私ですが、非エンジニアで今後エンジニアに転職する上で独学で勉強している身の者です。
初心者として、初心者の目線で疑問に思ったことや非エンジニアでも実行できるようにと思いメモと残し、今後同じような人に役立てればないいなぁ〜と思いQiitaに投稿しております。
ただ、初心者ゆえに内容の間違いなどあるかもしれませんのでその際は指摘していただければと幸いです。


# まず疑問点（アジェンダ）
・どうやって実行するのか
・準備したものは何か
・実行までの方法
・コードはどのように書けばいいのか
・終わりに
・その他疑問点について

# どうやって実行するのか
私が調べた限りだと2通りあるみたいです。
1、railsを用いてmodelを作成し、サイト内に抽出した内容を吐き出すやり方
2、rｂファイルにコードを記載して実行するやり方。

今回は`2、rｂファイルにコードを記載して実行するやり方。`で話を進めさせていただきます。
もし、1でやりたい場合は　
https://techacademy.jp/magazine/10026　
上記のサイトを参考にされるのがいいかと思います。（実際に私はこちらでもやってみましたがrailsをわざわざ使うのは今回の趣旨に合わないと思い割愛します。）

# 準備したものは何か
クローリングするにはライブラリを使用するみたいです。
ライブラリの中でanemone,nokogiriの二つがよく使われるみたいですが、nokogiriについて書かれている記事が多かったのでnokigiriのライブラリを使用して今回は紹介していきます。

1、nokogiriのインストール
下記をターミナルで記入すればOK

```
$ gem install nokogiri
```

※rubyでのクローリングなのでPCにrubyがインストールされている前提で話を進めます。
　もし、されていなかったらrubyのインストールを先にしてください。

# 実行の方法
1,はコードを記入する為のrbファイルを作成します。 
`例：scraping.rb`

2,実行方法については、ターミナルを立ち上げて

```Terminal
$ ruby　scraping.rb
```

と記載すれば実行されます

※上記のファイルにコードを記載して、ターミナルで実行すればクローリングが走ります（現在は何も書いていないので実行しても何も出てこない）


※忘れがちですがファイルが置かれているディレクトリにターミナルを移動しておきましょう。
　∟デスクトップにファイルを作成した場合は下記のように移動します。

```Terminal
$ cd　/Users/nash/Desktop
```




# コードはどのように書けばいいのか

```scraping.rb


require 'nokogiri'
require 'open-uri'


uri = "https://tabelog.com/tokyo/A1308/A130802/13025020/" #URLの指定
doc = Nokogiri::HTML(open(uri),nil,"utf-8")

#cssでデータを抽出する場合
doc.css("h2.display-name").each do |name1|
    puts name1.text
end

#xpathで抽出する場合
doc.xpath('//*[@id="rstdtl-head"]/div[1]/section/div[1]/div[1]/div/h2/span').each do |name2|
    puts name2.text
end


```
上記のようにコードを記載しますが、cssとxpathで取ってくる方法があります。
確認の方法としては、取得したいページにて右クリックを行い検証をクリックし、ディベロッパーツールを表示させます。

＜css場合＞
デベロッパーツールを表示させた後に取得したい所にカーソルを合わせてCSSを確認することができます。
確認したCSSを元にコードを記載します、

```css

<h2 class="display-name"> /*「"」で囲まれている部分とタグを抽出するだけ*/
              <span>
                東京厨房 虎ノ門三丁目店
              </span>
          </h2>
```


＜xpathの場合＞

おそらくこちらの方が簡単です。

先ほど同様にデベロッパーツールを表示させた後に取得したい所にカーソルを合わせて取得したいコードにカーソルを合わせて右クリックをし、XPath copyを押すだけで取得することができます。



ついでにターミナルで実行した場合は下記のようになります。

```
$ ruby scraping.rb
                東京厨房 虎ノ門三丁目店
                東京厨房 虎ノ門三丁目店
```

# 終わりに
ひとまず、ターミナルでクローリングを表示させる方法まではいけましたでしょうか。
このままではデータを活用できないと思いますのでこの後にCSVダウンロードの方法など書かせていただければと思います。

引き続きどうぞよろしくお願いします


※おそらくこの方法でできると思うのですがもしできなかった際は言っていただければ一緒に別方法を探せればと思います。（初心者なので解決策は多分わからないので探します）



# その他疑問点について
・CSVダウンロードの方法
・URLを複数取得方法
・splに情報を入れ込む

上記の3点については、実装でき次第別記事を作成予定
【Python】ARC 031 B 埋め立て

AtCoderで水色を取得するため、コツコツと頑張っているところですが、再帰関数の実装でつまずいたので、備忘録程度に纏めておく。

# 今回解いた問題
[ARC 031 B 埋め立て](https://atcoder.jp/contests/arc031/tasks/arc031_2)
10×10マスの中にいくつかの島があり、島と島の間に人工的な埋立地を１マス作ることで、大きな１つの島にできるか？といった問題である。

<img width=400 alt=image src=https://atcoder.jp/img/arc/031/2-1.png>
橙が島、青が海。赤枠がこの場合埋め立てると題意を満たす位置。

多重ループでガリガリ解いている方もいるのだが、ここは鍛錬と捉えて、学びたてホヤホヤの再帰関数を用いて解く。

# 前提
上記リンクから分かる通り、陸地は```"o"```、海は```"x"```と記述されている。
埋立地を作ることは```"x"```を```"o"```へ変えることに相当する。

# 方針
1. 再帰関数を用いて深さ優先探索をしていく。
2. 一度踏んだマスは履歴に残す。
3. 探索できたマスの数　= 陸地の数 + 埋立地の数であれば、歩いて島全域を探索できたと見なす。（逆にこれを満たさないということは、１つの島しか歩かなかったということ）
4. 探索は現在地から四方に動くのみ。

履歴の残し方は、```stepped_field```というすべての要素が```False```の10×10の配列を用意し、探索したマスは```True```に変えていく、といった感じ


# コード
あとは方針通りに書いていくだけ。
変数名がなんか残念なのは経験不足だと思って大目に見てください（泣）

コード下部の二重for文で埋立地の位置を決めている。

```python
import copy
init_field = list(list(input()) for _ in range(10))
un_stepped_field = list(list(False for _ in range(10)) for _ in range(10))


def count_continent(field):
    continent_count = 0
    for line in field:
        continent_count += line.count("o")
    return continent_count


def count_stepped_field(pre_counted_field):
    stepped_count = 0
    for line in pre_counted_field:
        stepped_count += line.count(True)
    return stepped_count


def search(y, x):
    # マップ外やぞ。
    if x < 0 or x >= 10 or y < 0 or y >= 10:
        return
    # 海歩いてるで。
    if field[y][x] == "x":
        return
    # 前にここ来たで。
    if stepped_field[y][x]:
        return
    stepped_field[y][x] = True

    # ここで四方に探索
    search(y+1, x)
    search(y-1, x)
    search(y,   x+1)
    search(y,   x-1)


for i in range(10):
    for j in range(10):
        stepped_field = copy.deepcopy(un_stepped_field)
        field = copy.deepcopy(init_field)

        # 埋立地作るよ。 
        if field[j][i] == "x":
            field[j][i] = "o"

        # 探索開始なり。
        search(j, i)

        # 探索したマスの数が陸地の数と一致すれば題意を満たす。
        if count_stepped_field(stepped_field) == count_continent(field):
            print("YES")
            exit()

print("NO")
```

# 苦労した点
二重for文の中の```stepped_field = copy.deepcopy(un_stepped_field)```だが、最初の実装では単にグローバル変数の```un_step_field```を```serch関数```内で用いていた。(変数名は直したが。)
それ故に、```un_step_field```は各ループで共有されるので、前のループの履歴が次のループに引き継がれていた。
結果として、未探索のマスなのに探索済みとしてカウントされていた。
それを解消すべく、各ループ毎に```un_step_field```をディープコピーすることで初期化を行っている。

あとは余り難しくなさそう（なお実装に時間はかかった模様。）
protocolBuffersでgoogle/protobufをimportする方法

grpc-webを使っているともうなかなかRESTには戻れない@kkkkkです。

今回はprotocol buffersの定義で結構便利な
https://github.com/protocolbuffers/protobuf
についてimportする方法を紹介します。

色々やり方はあると思いますが、
git submodulesでvendorとしてimportするのが楽かなと思ってます(他に良い方法あったら教えて下さい)。

## vendorにgit submodulesをaddする
```
$ tree -L 2                                                                                                                                                                                                  
.
├── articles
│   └── show.proto
├── helloworld.proto
└── vendor
    └── protobuf

3 directories, 2 files
```

の状態になるようにします。

```
mkdir vendor
cd vendor
git submodule add https://github.com/protocolbuffers/protobuf.git
```

これでvendor作成！

## protocでprotobuffers/protobufのimport方法
例は適当なメディアの記事詳細APIとかのイメージです。

articles/show.proto

```
syntax = "proto3";

import "google/protobuf/timestamp.proto";

package articles;

service ArticleService {
  rpc Show(ShowArticleRequest) returns (ShowArticleResponse);
}

message ShowArticleRequest {
  int64 id = 1;
}

message ShowArticleResponse {
  int64 id = 1;
  string title = 2;
  string description = 3;
  string contents = 4;
  string img_url = 5;
  int64 category_id = 6;
  string keywords = 7;
  google.protobuf.Timestamp created_at = 8;
}
```

で作成。

```
import "google/protobuf/timestamp.proto";
```

でimportして

```
google.protobuf.Timestamp created_at = 8;
```

で宣言します。


上記のrootディレクトリで以下実行。

```
#!/bin/sh

SERVER_OUTPUT_DIR=outputdir

mkdir -p ${CLIENT_OUTDIR} ${SERVER_OUTPUT_DIR}

protoc --proto_path=. --proto_path=vendor/protobuf/src articles/show.proto \
    --go_out=plugins=grpc:${SERVER_OUTPUT_DIR}
```


```
-Ivendor/protobuf/src
```

で`protoc`コマンド実行時に`protobuf/src`をimportすること！


gRPC良いね！
【Python】配列の値がすべて等しいか判定する

◆[CheckiO](http://www.checkio.org/)
　というサイトの練習問題にあった課題。

　記事の題名通りどおり、配列の値がすべて等しいか調べる、という内容である。
　
　初心者の自分は、以下のような解答をした。

~~~python.all_the_same.py
from typing import List, Any

def all_the_same(elements):
    
    #配列の要素数が0の場合
    if len(elements)==0:
        return True
    
    #配列の先頭要素を取得
    lead_element=elements[0]
    
    #要素が等しくない場合Falseを返す
    for element in elements:
        if lead_element!=element:
            return False
    return True
~~~

この関数で要件は満たしてはいるのだが、
もっと簡潔なコードはないかと色々調べてみた。


このような時、[CheckiO](http://www.checkio.org/) は、
全世界のプログラマの解答が閲覧できるため、便利だ。

備忘録がてら、勉強になったモノをいくつか紹介したいと思う。


###1.スライスを使う

~~~python.all_the_same.py

def all_the_same(elements):
    return elements[1:] == elements[:-1]
~~~

いちばん驚いた。


list=[1,2,1]


のようなリストを引数として与えた場合
左辺:[2,1]
右辺:[1,2]
で比較し、論理値を返すようになっている。
もちろん同じではないのでFalseが返ってくる。


上記の例だけでは分かり辛いので補足する。

◆計算過程のprintを追加したコード

~~~python.all_the_same.py

def all_the_same(elements):
    #計算過程を出力しておく
    print(str(elements[1:])+"=="+str(elements[:-1]))
    return elements[1:] == elements[:-1]

print(all_the_same([1,2,3,4]))

~~~


◆結果

~~~console
[2,3,4]==[1,2,3]
False
~~~

当然ながら結果はFalseだが、

上記のようなスライス記法で、
「配列二つ目から末尾まで」
と
「配列先頭から末尾一つ手前まで」
を比較できる事がわかる。

>スゲェよ旦那ぁ！



###2.setとlenを使う

~~~python.all_the_same.py
def all_the_same(elements):
    return len(set(elements)) <= 1
~~~


>◆setとは
・集合を表すデータ型
・設定時に重複が取り除かれる
・index番号を持たない
・s=set([1,2,3])みたいな感じで作成可能  



>◆lenとは
・len(変数名 or 文字列)で長さを返す

setの特徴のひとつ、
「重複が取り除かれる」という部分を利用し、
要素数が1以上だった際にFalseを返している。


覚えておくと役に立ちそう。
BITNAMIを使用してインストールしたRedmineのバックアップ/リストア(CentOS7)

# 概要

BITNAMIを使用してインストールしたRedmineのバックアップ/リストアの設定をする

# 前提条件

- CentOS7
- Redmineバージョン4.0.4-3
- BITNAMIバージョン3.2.0

# バックアップ

## ファイルのバックアップ

文書などで登録したファイルのバックアップ

- バックアップ先フォルダ：redmine_backup/files/

```shell
$ cp /opt/redmine-4.0.4-3/apps/redmine/htdocs/files/* redmine_backup/files/ -r
```


## ファイル以外のバックアップ

データ(チケット情報など)バックアップ用コマンド

- バックアップファイル名：/redmine_backup/sql/redmine.sql

```shell
$ sudo /opt/redmine-4.0.4-3/mysql/bin/mysqldump -u root -pパスワード bitnami_redmine > ./redmine_backup/sql/redmine.sql
```

## cronに登録

前述のコマンドを定期実行させるためにcronに登録
(後日追記予定・・・)

# リストア

## ファイルのリストア

```shell
$ cp ./redmine_backup/files/* /opt/redmine-4.0.4-3/apps/redmine/htdocs/files/ -r
```

## SQLのリストア

インポート時のID重複を防ぐため、テーブルのデータをすべて削除する。

```sql:truncate.sql
TRUNCATE TABLE `email_addresses`;
TRUNCATE TABLE `enumerations`;
TRUNCATE TABLE `issue_statuses`;
TRUNCATE TABLE `roles`;
TRUNCATE TABLE `schema_migrations`;
TRUNCATE TABLE `trackers`;
TRUNCATE TABLE `users`;
TRUNCATE TABLE `workflows`;
```

```shell
$ mysql -u root -pパスワード bitnami_redmine < /home/me/truncate.sql
```

リストア用(バックアップした)SQLを実行する

* SQLの格納場所：./redmine_backup/sql/redmine.sql 

```shell
$ sudo /opt/redmine-4.0.4-3/mysql/bin/mysql -u root -pパスワード bitnami_redmine < ./redmine_backup/sql/redmine.sql 
```

## Redmine再起動

Redmineを再起動する

```shell
$ /opt/redmine-4.0.4-3/ctlscript.sh restart
```


# 番外編

## BITNAMIを使用した時のユーザ名とパスワード

ユーザ名：root
パスワード：管理者IDのパスワード

## よく使うBITNAMIコマンド

### REDMINEの起動や再起動

```shell
$ sudo /opt/redmine-4.0.4-3/ctlscript.sh start
$ sudo /opt/redmine-4.0.4-3/ctlscript.sh restart
```

## よく見る設定ファイル

### データベースの接続情報など

* /opt/redmine-4.0.4-3/apps/redmine/htdocs/config/database.yml

### redmineの設定情報(メール設定)など

* /opt/redmine-4.0.4-3/apps/redmine/htdocs/config/configuration.yml

## redmineの自動起動設定

cronへの設定の追加

```shell
$ echo '@reboot /path/to/script' | crontab
```

追加した内容の確認

```shell
$ crontab -l
@reboot /opt/redmine-4.0.4-3/ctlscript.sh start
```

内容の編集

```shell
$ crontab -e
```
WebAssemblyのステガノグラフィChrome Extension

みんなと共有できるクロームエクステンションを作りました。この拡張機能により、ブラウザでステガノグラフィが可能になります。WebAssemblyで作成しました。画像掲示板やＳＮＳなどにアップロードしてみんなと共有できます。

Repository:
https://github.com/Toshi1212/Decoder

エクステンションをインストールしたら、(ディベロッパーモードで):

画像にメッセージをいれる方法, 
1) アイコンをクリック
2) ファイルを選択
3) メッセージを入力 (テキストもしくはHTMLどちらでも可)
4) オプションでkeyも選択可能
5) Encodeをクリック 
6) コピー＆ペースト、または画像を保存できます。

画像に隠されたメッセージを読むには画像上で右クリックして「Decode Image」を選択してください。

複雑になってしまって申し訳ありませんが、画像を入れたいときには次の方法で挿入してください。
1) 画像をBase64-encodeに変えてください。 ( おすすめ: https://lab.syncer.jp/Tool/Base64-encode/ )
2)  ```<img src="">```の中にペーストしてください。
3)  画像が大きすぎる場合「Encoding failed」エラーが出ます。その場合は画像を小さくしてください。

例:

```<img src="data:image/png;base64, data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAACklEQVR4nGNiAAAABgADNjd8qAAAAABJRU5ErkJggg=="/>```

例:
https://i.imgur.com/FV04fuY.png
https://i.imgur.com/i2dCqHi.png
https://i.imgur.com/fdHuxXY.png

例:
ビフォーアフター
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385979/952d5e84-cf53-31ad-65cd-6c016b9a1da6.png)
CodeCommitのキーチェインパスワードを自動的に削除する

## 背景
PC 環境をWindowsからMacへ変更したところ、keychainで保存されるcodecommitパスワードが15分すぎたら
無効になってしまって403になる。keychainの設定毎回するのも面倒。それで以下にようなコマンドで定期的に
keychainのパスワード削除する方法がある。

[ここ](https://www.jamf.com/jamf-nation/discussions/29978/delete-local-keychain)を参考して
コマンドの詳細を調べなした。

terminalで security help でコカンド情報を表示される。

```　
security delete-internet-password help
Usage: delete-internet-password [-a account] [-s server] [options...] [keychain...]
    -a  Match "account" string
    -c  Match "creator" (four-character code)
    -C  Match "type" (four-character code)
    -d  Match "securityDomain" string
    -D  Match "kind" string
    -j  Match "comment" string
    -l  Match "label" string
    -p  Match "path" string
    -P  Match port number
    -r  Match "protocol" (four-character code)
    -s  Match "server" string
    -t  Match "authenticationType" (four-character code)

```
-l コマンドでレベルで削除できることがわかる。その後以下のコマンド実行して成功。
 

## Terminal にて１件削除
　以下にように　security delete-internet-password コマンドで削除うできるが毎回消す必要があるので
面倒。

```
security delete-internet-password -l git-codecommit.ap-northeast-1.amazonaws.com
```

## 複数件を定期的に削除
以下のようにスクリプトでバッチを定義的に動くようにすれは気にしないまま勝ってに消せるので便利。ProgramArgumentsに実行したい
文字列に配列を作成すればよい。今回実際実施したコードは以下です。

```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>delete-codecommit-keychainpass</string>
 
  <key>ProgramArguments</key>
  <array>
    <string>security</string>
    <string>delete-internet-password</string>
    <string>-l</string>
    <string>git-codecommit.ap-northeast-1.amazonaws.com</string>
  </array>

  <key>RunAtLoad</key>
  <true/>
 
  <key>StartInterval</key>
  <integer>600</integer>
  
  <key>StandardErrorPath</key>
  <string>/tmp/error.log</string>
  <key>StandardOutPath</key>
  <string>/tmp/key_delete.log</string>
</dict>
</plist>
```
この例ではStartInterval を600つまり１０分ごとと設定してますが、もっと早く削除したい場合その値を変更すれはよいです。

## やったこと
1. ~/Library/LaunchAgents/ にdelete-keychain-password.plistファイルを追加
2. 上記載のコードでファイルを上書き
3. launchctl load コマンドで設定をロード
4. 何かの情報変更必要ば場合launchctl unload コマンドで一回設定無効にして.plistファイルを更新して再度　load コマンド実行すれはよい。
 

## コマンドリスト

```
cd ~/Library/LaunchAgents/
vi delete-keychain-password.plist
launchctl load ~/Library/LaunchAgents/delete-keychain-password.plist
launchctl unload ~/Library/LaunchAgents/delete-keychain-password.plist
```

## まとめ

上記載のやり方で実行して正常にパワワード削除されていることが確認しました。
今回に対応にここを[参考](http://alvinalexander.com/mac-os-x/mac-osx-startup-crontab-launchd-jobs) しました。

今回はcodecommit用パスワードを削除しましたが、同じように必要に応じて他にパスワードも削除可能です。
指定したキーの値を使って配列を連想配列に変換する関数

指定したキーの値を使って配列を連想配列に変換する関数をTypeScriptで作ったのでメモ。

とりあえず、変換後の連想配列のkeyには`string`か`number`を指定できるようにした。(numberの場合はstringに変換されちゃうけど)


```ts
/**
 * 配列を指定したキーのMap Objectに変換する
 * 
 * @param array 
 * @param {string} key 変換後の連想配列のキーに指定する値のキーを指定する。例 'id' / 'innerItem.name'
 */
export function arrayToMap<T>(array: T[], key: string = '') {
    const obj: { [key: string]: T } = Object.create(null)

    const re = /[\.\[\]]/
    const keys = key.split(re).filter(str => str.length !== 0)
    
    array.forEach((t, i) => {
        if (typeof t === 'string' || typeof t === 'number') {
            obj[t] = t
            return
        }
        const _key = keys.reduce((acc, cur) => acc[cur], t as any)
        if (typeof _key !== 'string' && typeof _key !== 'number') {
            throw new Error(`array[${i}].${key} is ${typeof _key}. not string or number !!`)
        }
        obj[_key] = t
    })
    return obj
}
```

使い方は以下のような感じ、

```sample.ts
const objArr = [
            {
              id: 11111,
              name: 'aaa',
              arrId: [
                {id: 11111}
              ]
            },
            {
              id: 2222,
              name: 'bbb',
              arrId: [
                {id: 2222}
              ]
            }
        ]
          
console.log(arrayToMap(objArr,'id'))
// => 'id'をキーにして連想配列を作る。結果は以下のような感じ
// {
//   2222: {
//     id: 2222,
//     name: "bbb",
//     arrId: [
//       {
//         id: 2222
//       }
//     ]
//   },
//   11111: {
//     id: 11111,
//     name: "aaa",
//     arrId: [
//       {
//         id: 11111
//       }
//     ]
//   }
// }

console.log(arrayToMap(objArr,'arrId[0].id'))
// => arrId[0].idをキーにして連想配列を作る、結果は上と同じ、


console.log(arrayToMap(objArr,'name'))
// => 'name'をキーにして連想配列を作る。結果は以下のような感じ
// {
//   aaa: {
//     id: 11111,
//     name: "aaa",
//     arrId: [
//       {
//         id: 11111
//       }
//     ]
//   },
//   bbb: {
//     id: 2222,
//     name: "bbb",
//     arrId: [
//       {
//         id: 2222
//       }
//     ]
//   }
// }

const strArr = [
    'yamada', 'taro' , 'aaa'
]
console.log(arrayToMap(strArr))
// => arrayのメンバーが文字列の場合は、keyとvalueに同じ値が入る。
// {
//   yamada: "yamada",
//   taro: "taro",
//   aaa: "aaa"
// }

const numArr = [
    1111, 22222 , 33333
]
console.log(arrayToMap(numArr))
// => arrayのメンバーがnumberの場合もstringのときと同じ
// {
//   1111: 1111,
//   22222: 22222,
//   33333: 33333
// }

console.log(arrayToMap(objArr)) // => error. array[0]. is object. not string or number !!
console.log(arrayToMap(objArr, 'no_key')) // => error. array[0].no_key is undefined. not string or number !!
```

第2引数のキーの値に対してコンパイル時にチェックをかけられないのが微妙だけど、
返り値の型に対する推論はちゃんと効いてくれるのでまあいいかな・・・
kubesprayを使用したKubernetesクラスタの構築


## kubespray
kubesprayはAnsibleをベースとしたKubernetesのデプロイツールです。
https://github.com/kubernetes-sigs/kubespray

使用する機会があったので構築手順をメモ書き程度に残したいと思います。
今回はESXi上に5台のマシンを使用したKubernetesクラスタを構築してみました。


## 構成
### 役割
node1: master/etcd
node2: master/etcd
node3: master/etcd
node4: node
node5: node

node-mgmt: ansible-playbookを実行するマシン

###Linux Distribution
CentOS7.6
　- image: CentOS-7-x86_64-DVD-1810.iso
　- Minimal Install

###Resource
CPU: 2Core
Memory: 2GB

###IP address
node1-3: 172.31.20.100 - 172.31.20.102
node4-5: 172.31.20.110 - 172.31.20.111

## 下準備
README.mdのRequirementsには以下のように記載されているので,各nodeでfirewalldを無効化しておきます。
>The firewalls are not managed, you'll need to implement your own rules the way you used to. in order to avoid any issue during deployment you should disable your firewall.

以降の作業は全てnode-mgmtのrootユーザで行います。

## kubesprayのcloneと実行用パッケージのインストール
まずはpython3とgitをインストールします。

```
yum -y update
yum -y install https://centos7.iuscommunity.org/ius-release.rpm
yum -y install python36u python36u-pip git
```

kubesprayは再現性のためタグを指定してcloneします。
git clone後、pipを使用して`requirements.txt`からpythonパッケージをインストールします。

```
git clone https://github.com/kubernetes-sigs/kubespray.git -b v2.10.4
cd kubespray
pip3.6 install -r requirements.txt
```
ansibleは2.8.xだと実行が失敗するようです。
yumでインストールすると2.8.xになるので行わないようにしましょう。
2019/8現在のMasterブランチではRequirementsに以下のような記載があります。
>Ansible v2.7.8 (or newer, but not 2.8.x)

ちなみにrequirements.txtの中身は以下です。

```:requirements.txt
ansible==2.7.8
jinja2==2.10.1
netaddr==0.7.19
pbr==5.2.0
hvac==0.8.2
jmespath==0.9.4
ruamel.yaml==0.15.96
```

## hosts.ymlの作成
以下のコマンドで`hosts.yml`を作成します。

```
cp -r inventory/sample inventory/mycluster
declare -a IPS=(172.31.20.100 172.31.20.101 172.31.20.102 172.31.20.110 172.31.20.111)
CONFIG_FILE=inventory/mycluster/hosts.yml python3.6 contrib/inventory_builder/inventory.py ${IPS[@]}
```
実行後に`inventory/mycluster/hosts.yml`が作成されるので、`kube-master:`,`kube-node:`,`etcd:`の`hosts:`を編集します。

```:hosts.yml（抜粋）
all:
  children:
    kube-master:
      hosts:
        node1:
        node2:
        node3:
    kube-node:
      hosts:
        node4:
        node5:
    etcd:
      hosts:
        node1:
        node2:
        node3:
```

その後,構築する環境に合わせて`inventory/mycluster/group_vars/all/all.yml`と`inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml`を編集しますが,今回はデフォルトのまま構築します。

## playbook実行
SSHキーペアを作成し、公開鍵を各ホストに配布します。

```
ssh-keygen -t rsa -b 4096
ssh-copy-id root@172.31.20.100
以下省略
```

以下のコマンドでplaybookを実行します。
今回はrootでログインするので`-b`オプションは省略しています。

```
ansible-playbook -i inventory/mycluster/hosts.yml cluster.yml -v
```
しばらく待てば構築完了です。
MySQLで接続ユーザーを作成し、権限を付与する

アプリケーション毎に接続ユーザーを分けているが、
ユーザーの作成、GRANTのやり方のまとめ。

##ユーザーの作成
セキュリティのために接続を許可するホストも指定する。

```sql
mysql> CREATE USER 'hoge'@'192.168.10.5' IDENTIFIED BY 'xxxxxxxx';
```

確認

```sql
mysql> select user, host from mysql.user;
+--------+------------------------+
| user   | host                   |
+--------+------------------------+
| root   | 127.0.0.1              |
| hoge   | 192.168.10.5           |
|        | localhost              |
| root   | localhost              |
|        | abc.hoge.jp            |
| root   | abc.hoge.jp            |
+--------+------------------------+
6 rows in set (0.00 sec)
```

## hogeユーザーに権限を付与するGRANT分の作成

似た権限を持つユーザーとDBの組み合わせがあれば`show grants`で参照できるので、コピーして編集すると早い。

```sql
mysql> show grants for 'root'@127.0.0.1;
+---------------------------------------------------------------------+
| Grants for root@127.0.0.1                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION |
+---------------------------------------------------------------------+
1 row in set (0.02 sec)

```

今回は、hogeユーザーにnew_app DBへの全権限を付与する。

```sql
mysql> GRANT ALL PRIVILEGES ON `new_app`.* TO 'hoge'@'192.168.10.5';
Query OK, 0 rows affected (0.22 sec)
```

付与した権限の確認

```sql
mysql> show grants for 'hoge'@192.168.10.5;
```
Apple ScriptでiTunesの曲を整理する

# はじめに
*この記事はiTunesを使用している方向けの記事です

iTunesで曲を探していると、

- アルバムアーティストが書いていない
- コメントが書いてある

など、統一性のない曲がちらほら存在します。

以前はiTunes上で複数の曲を選択して編集していたのですが、
面倒になったのでスクリプトを書いてみました。

# Apple Scriptを書いてみる
### コードの目的
editというプレイリストに入ってるそれぞれの曲に対して、

- コメントを空にする
- アルバムアーティストが書いていなければ、アーティストと同一にする

### 実行方法
1.Macのアプリケション「スクリプトエディタ」から、新規書類でapple scriptを作成する
![script_editor.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251749/e24377db-a1a5-e8f1-452a-3f6203c7f6db.png)

2.以下のコードを書いて、▶️をクリック

```artist2albumartist.scpt
tell application "iTunes"
	set tmp to AppleScript's text item delimiters
	set AppleScript's text item delimiters to {":"}
	repeat with aTrack in tracks of user playlist "edit"
		set comment of aTrack to ""
		if album artist of aTrack is "" and album of aTrack is not "" then
			set album artist of aTrack to text item -3 of (location of aTrack as string)
		end if
	end repeat
	set AppleScript's text item delimiters to tmp
end tell
```

3.出力結果が以下のようになればOK

```result
{:}
```

## Script解説
editプレイリストにある曲に対して繰り返し(repeat)実行する

```
repeat with aTrack in tracks of user playlist "edit"
  # 処理  ← #でコメントアウトできます
end repeat
```

コメントを空にして、
アルバム名が空でなければ、アーティスト名をアルバムアーティスト名に設定する

```
set comment of aTrack to ""
if album artist of aTrack is "" and album of aTrack is not "" then
    set album artist of aTrack to text item -3 of (location of aTrack as string)
end if
```
---

編集したい曲をプレイリストに入れて実行するだけなので、以前と比べて作業が楽になりました。

*注意:アルバム内で異なるアーティスト(.feat とか)がある場合でも、曲単位で設定されます


以上です。