OmniAICreator/Qiita-1.07M huggingface dataset:
Julia, BigFloatの精度

[Project Eulerの26](https://projecteuler.net/problem=26)をJuliaでやってみた後に、BigFloatで検算しようとして初歩的なところで躓いたメモ。

## 要約?

precision $\neq$ accuracy
というだけの話ではあります。
(昔先輩にさんざん「混同するな」って注意されたなー)

## 本文

```julia
setprecision(1000)
BigFloat(1.0)/983.0
```
でこうなるわけですが、

```
0.00101729399796541200406917599186164801627670396744659206510681586978\
6368260427263479145473041709053916581892166836215666327568667344862665\
3102746693794506612410986775178026449643947100712105798575788402848423\
1943031536113936927772126144455747711088504577822990844354018311291963\
377416073245167853509664295
```
数えてみると小数点以下が305桁しか無いし、正しいはずの答えは以下、

```
...50966429_29806714...
```
と続くはずなので、最後の桁は四捨五入にもなってない。

なんで？と思ったんですが、`setprecision`はその桁までの精度を保証するんではなく、単純に計算に使う桁数の指定のようです。

じゃあ、精度保証のための設定とか無いのかなと思って探したんだけと見つからない。

それじゃ科学技術計算用途としては結構弱点なのでは？と思ったんですが、
JuliaのBigFloatは[GNU MPFR Library](https://www.mpfr.org/)を[使っているそうで、](https://docs.julialang.org/en/v1/base/numbers/#BigFloats-and-BigInts-1)
MPFRの[FAQ](https://www.mpfr.org/faq.html#accuracy)に、

>Also remember that MPFR does not track the accuracy of the results

と書いてあるので、仕方ないみたい。

`setprecision(10000)`にしたら必要なところ(約1000桁)まで十分過ぎる正確な値(約3000桁)が表示されました。
最後の2桁は違う数字になってましたが、そこそこ保証できる範囲までしか表示しないのは、MPFRの機能なのかJuliaの機能なのか知りませんが、それはそれで有り難いとは思いました。

Juliaって科学技術計算を重視した言語だと思ってて、当然高精度計算用の機能がいろいろ組み込まれてるだろうと勝手に思い込んで、precisionの指定はその精度保証と思ってしまってたのが戸惑いの原因でした。
思い込みって恐ろしい。。。
【初心者向け】BitbucketからGithubにリポジトリを移す方法まとめ

#はじめに
Railsチュートリアルを学習している方は、チュートリアル通りに進めていたらGitリポジトリのホスティングサービスにBitbucketを使っていると思います。
何故ならば”非公開リポジトリが無料”だから！

しかし、2019年の1月8日から
[GitHub無料ユーザーも無制限にプライベートリポジトリを使えるように](https://jp.techcrunch.com/2019/01/08/2019-01-07-github-free-users-now-get-unlimited-private-repositories/)なりました。

これを機にGithubに移行する方もいるんじゃないかなと思います。

そこで今回はBitbucketからGithubへ、つっかかりなくリポジトリを移す方法をまとめておこうと思います。

#移行に先立って、簡単にBitbucketについて知っておくべきこと
BitbucketはGitHubと同じ、バージョン管理ツールのリポジトリを預かってくれるホスティングサービスです。
Bitbucketはアトラシアンという会社が運営しています。

最初に登録する際にはアトラシアンのアカウントに登録していることになります。

※Atlassianアカウントとは、アトラシアンのメンバーシップサービスを利用可能な無償アカウント。

#[本題]リポジトリの移し方
BitbucketからGithubへリポジトリを移す方法は下記リンクを参考に行なっていきます。
[Githubへの移行方法](https://yosiakatsuki.net/blog/repo-bitbucket-2-github/)

###※Bitbucketを登録するときにGoogle認証でログインしていた場合
上記のやり方でつまづいた方がいらっしゃるかもしれません（自分がそうでした。）
おそらく移行する際に求められるアカウント名とパスワードが分からなかったかと思います。

その場合は、下記リンクからパスワードを再設定し、再度移行の手続きをしていきましょう！
[Atlassianアカウントのパスワードの再設定](https://bitbucket.org/account/password/reset/)



##参考画面
<リポジトリ移行中の画面>
![リポジトリ移行中の画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404519/2ee191b7-b55f-fbf1-f62e-401c7f53d2fb.png)

<リポジトリ移行が完了した画面>
![リポジトリ移行完了画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404519/9364e124-d74a-c4e6-abf6-55fb33355487.png)


#参考URL
・[朗報、GitHub無料ユーザーも無制限にプライベートリポジトリを使えるようになる](https://jp.techcrunch.com/2019/01/08/2019-01-07-github-free-users-now-get-unlimited-private-repositories/)

・[Bitbucketで管理していたリポジトリをGitHubに移行するメモ](https://yosiakatsuki.net/blog/repo-bitbucket-2-github/)
[mac]XAMPPのApacheでSSLの有効無効を切り替える

#はじめに
macでhttpsを有効にしたかったのですが、xamppでは既にデフォルトでhttpsが使えたので
どの値をいじれば有効無効が切り替えられるか確認してみました。


##環境
macOS Mojave 10.14.5
XAMPP 5.6.40-1
phpver 5.6.38

##有効無効の切り替え
まずは以下の記事を参考にphp.iniの「extension=php_openssl.dll」が
どうなっているか確認しました。
https://qiita.com/sutara79/items/21a068494bc3a08a4803

```php.ini
;extension=php_openssl.dll
```

あれ?コメントアウトされてるのにhttpsが動いてます。
macだとこの記述必要ないのでしょうか?

とりあえずphpのドキュメントでphp.iniのopensslについて調べてみます。
https://www.php.net/manual/ja/openssl.installation.php
phpのコンパイルが必要と。。。
でも私の環境はxamppなので、動作からすると既にopensslありきでコンパイル済みってことでしょうか？インストールと設定のところにもphp_openssl.dllについてこうしてくださいな記載は見つけられませんでした。。。

---------
追記

php.iniを見直してたらこんな記載があったのを発見。

```php.ini
; Windows Extensions
; Note that ODBC support is built in, so no dll is needed for it.
; Note that many DLL files are located in the extensions/ (PHP 4) ext/ (PHP 5)
; extension folders as well as the separate PECL DLL download (PHP 5).
; Be sure to appropriately set the extension_dir directive.

省略

;extension=php_openssl.dll

```

dllはwindows用の拡張機能を使用するときに必要なもののようですね。
つまりmacではdllは不要ってことですね。
しっかり書いてありました。

---------

次にapacheの公式サイトを確認しました。
https://httpd.apache.org/docs/2.4/ssl/

説明を読むと「mod_ssl」がopensslライブラリを使用する為のインターフェースなようなので、xampp内のフォルダを「mod_ssl」で全検索をかけたところ、以下がヒットしました。

```httpd.conf
LoadModule ssl_module modules/mod_ssl.so
```
既にLoadModuleでロード済みなので有効化されているということですね。
これをコメントアウトすれば無効にすることができるということですね。
コメントアウトは#。

```httpd.conf
#LoadModule ssl_module modules/mod_ssl.so
```

とりあえず、これで有効無効が切り替えられそうです。
Gitに空コミットができない時の対処方法

#空コミットとは？
【用途】：
Gitでブランチをきって作業を開始する時に、他のメンバーに <b>「ここで作業してますよ〜！」</b>と周知をし、
タイムラグにより作業ブランチが埋もれないようにするため。

#通常なら（--allow-empty -m "プルリク名"）でコミットできる
```ruby:ターミナル
$ git commit --allow-empty -m "{プルリクエストのタイトル}"
```
コミットはファイルの変更がないとできないようになっているが、ターミナルで該当するディレクトリに入り、
上記のコマンドを打ち込むと通常は空コミットができる。

`$ git commit --allow-empty -m "first commit"`

そう、通常ならばできるはず・・・
しかし私のmacでは通用せずエラーが返ってきたので、他の方法で空コミットできないか試してみた。

#エラーが返ってきた場合は(-m "initial commit")を試してみる
```ruby:ターミナル
$ git commit -m "initial commit"
```
私は上記のコマンドを入れて実行したら、無事空コミットが作成できた。
空コミットが作成されたらすぐにGitに`push`をすること。
 
 
--以上

##補足メモ
__ターミナルで該当するディレクトリにサクッと入れる方法__
`cd /Users/`と打ち込んだあと`Enter`を押さないで、入りたいディレクトリのフォルダをターミナルにドラッグ＆ドロップすると`cd /Users/`のあとにパスが自動で入る。
もう怖くない！Macユーザのための（削除/ 上書き）してしまったファイル、フォルダの復元方法

#はじめに
多くの人が、うっかりファイルを削除、上書きしてしまい、どうしていいか唖然と立ち尽くした経験があるのではないでしょうか。コマンドラインから`rm`コマンドを実行すればいとも簡単にファイルは消去されます。`mv`と`rm`を打ち間違えたこともあるかもしれません。

それを帳消してくれるソフトウェアや、コマンドが提供されていたりしますが、Linux, Windows 上しか動かず、Mac には対応していないことも多々あると思います。
Macでは、`Time Machine`を使えば削除、上書きしてしまったファイルを復元できるとは知っているものの、外付けHDDにバックアップしていなかったファイルであるため、それもダメ。。。

#でも実は
**外付けHDD にバックアップしていなくても`Time Machine`にはバックアップが取られている**んです!外部ストレージがなくても、Mac 本体があれば問題ないのです。

え、知らなかった。でも別にストレージに保存されていないのにどうして。
ストレージもメモリも圧迫せずにバックアップが取られているの？

そうです。それには、意外なカラクリがあったのです。

**Time Machine は1日以内のデータを１時間間隔でバックアップとってくれます。**
1日経ったファイルはシステムから削除し、今実際に作業しているファイルはバックアップが作成されていきます。ですので、さしてストレージやメモリを圧迫せずともバックアップがとられます。

ですので、ふとした拍子に削除、上書きしてしまったファイルを復元できるのです。`rm`してしまったあの重要な設定ファイルも復元できるのです。
復元方法は至って簡単で、**`Time Machine`を立ち上げるだけ。**

#ここで、一点注意しておきたいのが、
**１時間おきですので、１時間以内の作業記録は戻すことができません。**約１時間前にファイルを作成し、急ピッチで仕上げていったといったものを削除、上書きしてしまった場合は、残念ながら、復元できません。
ですが、ほとんどのファイルは、それ以前に作成しているもの。この方法を知っていれば、長い時間かけて作り上げたファイルがコンピュータシステムから失われることはもうありません。以前よりも、少しは気軽に、`rm`コマンドを使えるのではないでしょうか。以前よりも、少しは幸せになった気がします。

おわり。
python3の除算は型に注意 A//B != int(A/B)

大きな数($10^9$程度)の割り算で、以下のような罠にハマったので解説します。

```python
A//B != int(A/B)
```

#問題点

**Python3**では`/`演算子を使用した場合、`float`に変換して除算が行われます。
そのため、以下のコードを実行すると問題が生じます。

```python3
a = 123
b = 456

A = 10**9 + 123
B = 10**9 + 456

c = a*b/2
d = a*b//2

C = A*B/2
D = A*B//2

print("a*b/2       =",c)
print("int(a*b/2)  =",int(c))
print("a*b//2      =",d)

print("A*B/2       =",C)
print("int(A*B/2)  =",int(C))
print("A*B//2      =",D)
```
結果は以下の通り、`a,b`が小さいときには問題ありませんが、`A,B`が大きいと結果が一致しません。

```
a*b/2       = 28044.0
int(a*b/2)  = 28044
a*b//2      = 28044
A*B/2       = 5.00000289500028e+17
int(A*B/2)  = 500000289500028032
A*B//2      = 500000289500028044
```

#原因
**python3**では`int型`は無限の桁数を持つのに対して、`float型`は有限です、そのため`/`演算子により`A*B`が`float型`で実行され、大きい数字の場合には以下の様な結果となってしまうのです。お気をつけあれ。

```python
A = 10**9 + 123
B = 10**9 + 456

c = (A*B)
d = float(A*B)

if c != d:
    print("一致しません")
    print("c", c)
    print("d", d)
```
結果

```
一致しません
c 1000000579000056088
d 1.000000579000056e+18
```
TypeScript: date-fnsでyyyy-MM-ddをパースする

本稿では、TypeScriptで日付ライブラリ[date-fns]を用い、年月日の文字列をパースする方法を紹介する。

```ts
import { parse } from 'date-fns'

console.log(parse('2019-08-01', 'yyyy-MM-dd', new Date()))
```

実行結果:

```
2019-07-31T15:00:00.000Z
```

タイムゾーンが+09:00なので、前日の15時のDateオブジェクトが返った。

## 参考

- [date-fns - modern JavaScript date utility library](https://date-fns.org/v2.0.1/docs/parse) - 公式ドキュメント

[date-fns]: https://date-fns.org/
初学者のメモ　Rails_adminの導入方法（日本語化）

#初めに
ポートフィリオを作成する際、管理者側機能を実装するの面倒に感じたので管理者側はgemを使用することにしました。
管理者機能を持つgemは複数ありますが、今回は『Rails_admin』の導入しましたので、記録を残したいと思います。

#環境
・Ruby '2.3.8'
・Rails '5.2.3'

#gemの導入(devise編)
```ruby:Gemfile
gem 'devise'
```

```
$ bundle install
$ rails g devise:install
$ rails g devise user
$ rails db:migrate
$ rails g devise:views users
```
以上でdeviseの導入は完了です。

#gemの導入(rails_admin編)
```ruby:Gemfile
gem 'rails_admin', '~> 2.0.0.beta'
```

```
$ bundle install
$ rails g rails_admin:install
?  Where do you want to mount rails_admin? Press <enter> for [admin]> 
$ admin
```

`rails routes`で/adminが生成されていることを確認します。
`rails s`後、生成されたURLを入力すると表示されます。

#gemの導入(cancancan編)

```ruby:Gemfile
gem 'cancancan'
```
```
$ bundle install
```
以上で必要gemの導入は完了です。

#管理者権限の設定
1. cancancanでabilityを生成します

```
$ rails g cancan:ability
```
2. 生成されたモデルを以下の様に変更します。`(model/ability.rb)`

管理者権限を持つユーザに管理画面へのアクセスと全てのモデルに対しての全ての操作（新規保存、編集、削除など）」を許可する設定です。

```ruby:ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    if user.try(:admin?)
      can :access, :rails_admin
      can :manage, :all
    end
  end
end
```

3.`config/initializers/rails_admin.rb`も以下のように変更します。

```ruby:ability.rb

RailsAdmin.config do |config|

  ### Popular gems integration

  ## == Devise ==
  config.authenticate_with do
    warden.authenticate! scope: :user
  end
  config.current_user_method(&:current_user)

  ## == Cancan ==
  config.authorize_with :cancan

  ## == Pundit ==
  # config.authorize_with :pundit
```

#管理者権限の付与
deviseで登録したユーザに管理者権限を持たせたいと思います。
ユーザが管理者がどうかを判断する為に、「admin」カラムを追加し、ture or falseで判断出来るようにします。

```
$ rails g migration add_column_to_users
```

```ruby:Gemfile
class AddColumnToUsers < ActiveRecord::Migration[5.2]
  def change
  	add_column :users, :admin, :boolean, default: false
  end
end
```

```
$ rails db:migrate
```

schema.rbを確認し、正しく追加されていることを確認してください。

＃登録ユーザに権限を付与する

```
$ rails c
$ User.all
$ user = User.find(3)※任意のユーザに付与してください。
$ user.update_attribute :admin, true
```
今回の場合は、３番目にユーザに管理者権限を付与しました。
このユーザは管理画面に遷移できます。

＃管理者の条件分岐
管理者のみの表示させたいときは、<% if current_user.try(:admin?) %><% end %>でログイン中のユーザが管理権限を持つユーザを判断出来ます。

#rails_adminの日本語化
1.Railsの日本語に変更します。

```ruby:application.rb
config.i18n.default_locale = :ja　を追記する
```

2.`config/locales/rails_admin.ja.yml`を作成します。
3.[こちらの翻訳](https://gist.github.com/mshibuya/1662352)をコピーし、`rails_admin.ja.yml`に貼り付けます。
以上で日本語化は完了です。

#参考資料
[【Rails】管理画面（rails_admin）を実装するとユーザー情報管理が想像以上に便利な話](https://whatsupguys.net/programming-school-dive-into-code-learning-49/)

#最後に
簡単に管理者機能を実装することが出来ました。
私はこの便利なgemのおかげで、他の機能に時間を掛けることが出来ました。
もし、よかったら参考してみてください。
RPiでWiFiをオンデマンドにON/OFFする

そもそもWi-Fiって消費電力が大きい(Wi-Fi6あたりからはそうでもないですが)ので、RPiをIoT機器として使った場合、そこが問題になる場合があります。
必要に応じてOn-Offを切り替える方法がないか調べてみました。

# やりたいこと
RPiを使ってWi-Fiに接続し、なにかしらのデータをセンシングするなどのユースケースを想定します。センシングしたデータを送りたいときはWi-Fiに接続し、それ以外の場合は電波を止めて消費電力を抑えます。

# ライブラリとかはたぶんない
公式のライブラリ系でそういうのを制御するのがあれば一番手っ取り早かったんですが、GIOPのライブラリ以外が見当たりませんでした。もしあったら教えてください。
githubとかに既存のがあるんじゃないかと思ったんですが、セットアップツールやwebコンソールはありましたが自動でOn-Offとかはなかったです。

# 自分で作る
## RPiのWi-Fi設定
RPiをWi-Fiでルータ等に接続する場合、設定ファイル(`/etc/wpa_supplicant/wpa_supplicant.conf`)を正しく作成した上で`wpa_cli reconfigure`コマンドを実行する必要があります。逆に`wpa_supplicant.conf`に誤りがあるとWi-Fiはオフになります。
したがって、Wi-Fiを使用したいときは`wpa_supplicant.conf`を正しい内容にして`wpa_cli reconfigure`を実行し、停止させたいときは誤った内容にして`wpa_cli reconfigure`を実行する、という手段が考えられます。
## 実装
```bash
#!/bin/bash

WIFI_CONF_FILE_PATH="/etc/wpa_supplicant/wpa_supplicant.conf"
WIFI_REGION_NAME="JP"

function wifi_on () {
    sed -e -i "s/country=/country=${WIFI_REGION_NAME}/" WIFI_CONF_FILE_PATH
    wpa_cli reconfigure
}

function wifi_off () {
    sed -e -i "s/country=${WIFI_REGION_NAME}/country=/" WIFI_CONF_FILE_PATH
    wpa_cli reconfigure
}

wifi_on

# センシングしたり送信したり

wifi_off
```
Arch LinuxでWi-Fiの自動接続

## 手順

1. 必要なパッケージをインストールする

    ```bash
$ sudo pacman -S wpa_supplicant
```

1. Wi-Fiの接続設定をする

    ```bash
$ sudo wifi-menu
```

    1. 接続したいアクセスポイントの名前を選択して`<OK>`を押すと、新しいプロファイルの名前を決める画面になります。ここでは例として「MyHome」と名付けます。
    2. アクセスポイントのパスワードを入力します。
    3. pingコマンドやip addrコマンドで接続の確認をします。確認できたら次に進みます。

1. 生成されたプロファイルを確認する

    wifi-menuコマンドが生成したプロファイルを確認すると、上で名付けた名前のファイルがあります。

    ```bash
$ ls -l /etc/netctl
total 8
-rw------- 1 root root  156 Aug 24 22:27 MyHome
drwxr-xr-x 2 root root 4096 Aug 21 16:46 examples/
drwxr-xr-x 2 root root    6 Feb 13  2019 hooks/
drwxr-xr-x 2 root root    6 Feb 13  2019 interfaces/
```

1. 自動接続の設定をする

    以下のコマンドを実行します。コマンド中の「wlp2s0」はインタフェース名です。

    ```bash
$ sudo systemctl enable netctl-auto@wlp2s0.service
```

    インタフェース名はip linkコマンドで確認できます。

    ```bash
$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
```

再起動後、勝手に接続されていれば成功です。

## 別のアクセスポイントを追加する

wifi-menuコマンドを実行するだけです。

## 接続できないときの対処法

### netctlとdhcpcdが競合している

dhcpcdのサービスを無効化します。

```bash
$ sudo systemctl disable dhcpcd@wlp2s0.service
```

### IPアドレスがもらえない

以下のコマンドを試してください。

```bash
which dhcpcd
```

もしコマンドが見つからなければ、これが原因である可能性が高いです。dhcpcdパッケージをインストールしてください(有線で接続して`pacman -S dhcpcd`、もしくはインストール用USBを使って/mntをマウントし、`pacstrap /mnt dhcpcd`すればいいです。)

## まとめ

ここまで読んでくださってありがとうございます！

Twitterフォローしていただけると嬉しいです！
https://twitter.com/_matoruru
TypeScriptでAWS S3にファイルをアップロードする

本稿ではTypeScriptでAWS S3にファイルをアップロードする方法を解説する。

AWS SDKモジュールをインストールする。

```
yarn add aws-sdk
yarn add -D @types/aws-sdk
```

ファイルをアップロードする。

```ts
import AWS from 'aws-sdk'
import S3 from 'aws-sdk/clients/s3'

AWS.config.logger = console // 通信のデバッグ用。不要であれば削除可。

const accessKeyId = ''; // IAMユーザの認証情報の「アクセスキーID」から確認できます。
const secretAccessKey = ''; // IAMユーザのシークレットアクセスキー。アクセスキーを作ったときだけ見れるやつです。
const bucketName = ''; // 保存先のバケット名

const bucket = new S3({
  accessKeyId: accessKeyId,
  secretAccessKey: secretAccessKey,
  region: 'ap-northeast-1',
})
const param: S3.Types.PutObjectRequest = {
  Bucket: bucketName,
  Key: 'test.txt', // ファイル絶対パス
  Body: 'hello!', // ファイルの内容
  ACL: 'public-read', // インターネットから誰でもダウンロードできるように
  ContentType: 'text/plain',
}
bucket.upload(param, (err: Error, data: S3.ManagedUpload.SendData) => {
  if (err) {
    console.error(err)
  } else {
    console.log('Successfully uploaded file.', data)
  }
})
```

実行結果

```js
[AWS s3 200 0.154s 0 retries] putObject({ Body: <Buffer 68 65 6c 6c 6f 21>,
  Bucket: 'バケット名',
  Key: 'test.txt',
  ACL: 'public-read',
  ContentType: 'text/plain' })
Successfully uploaded file. { ETag: '"5a8dd3ad0756a93ded72b823b19dd877"',
  Location: 'https://バケット名.s3.ap-northeast-1.amazonaws.com/test.txt',
  key: 'test.txt',
  Key: 'test.txt',
  Bucket: 'バケット名' }
```

アップロードされたファイルを見る(httpieコマンド使用)。

```
http https://バケット名.s3-ap-northeast-1.amazonaws.com/test.txt
```

```http
HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Length: 6
Content-Type: text/plain
Date: Sat, 24 Aug 2019 14:46:02 GMT
ETag: "5a8dd3ad0756a93ded72b823b19dd877"
Last-Modified: Sat, 24 Aug 2019 14:41:50 GMT
Server: AmazonS3
x-amz-id-2: cXpZ+Tyi3A1ddu6ERAafD4Okv/LzQU2AbSoZeIPztmJ6JBoHf8YWBziC4Ss1WPrz23MVwWqPJ4g=
x-amz-request-id: E3497626B98374BF

hello!
```

## AWSの権限設定

上のコードが動いたAWSの権限設定を一応載せておく。

まず、IAMポリシー。ポリシー名は`AmazonS3UploadOnly`にした。

```json:AmazonS3UploadOnly
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<バケット名>/*"
        }
    ]
}
```

次に、S3バケットポリシー。なお、「パブリックアクセスをすべてブロック」すべてオフ。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "<ユーザ名など任意の名前>",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<あなたのAWSの12桁のID>:user/<あなたのIAMユーザ名>"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::<バケット名>/*"
        }
    ]
}
```

`s3:PutObject`は、ファイルがアップロードできるようになる。`s3:PutObjectAcl`は、`ACL: 'public-read'`を使うために必要。
Java学習メモ（抽象クラス）

Java Silverの勉強をしているので自分の忘備録としてUPします。
ざっくりとしたメモなので、詳細は記載してません。

抽象メソッドとは実装を持たないメソッド(メソッド名、引数の型、引数の数)と戻り値の型のみを定義するメソッドである。

＜注意点＞
①直接インスタンス化できないので、サブクラスをインスタンス化する。
②上記の理由で、スーパークラスのコンストラクタを呼び出す場合、サブクラスでコンストラクタを記述し、super();を使用してスーパークラスのコンストラクタを呼び出す必要がある。
③抽象メソッドは全てオーバーライドすること。
④記述は以下の通り、抽象メソッドに{}は記述しない。
　abstract class クラス名 {
  　  abstract 戻り値の型名 メソッド名(引数);
　}
⑤extendsで継承してオーバーライドする。

    public abstract class _abstract {
    	public void test(int num) {
    		System.out.println(1);
    		method(num);
    		System.out.println(3);
    	}
    	public abstract void method(int num);
    }

    public class _subabstract extends _abstract{
    	public static void main(String[] str) {
    		_subabstract sub = new _subabstract();
    		sub.test(2);
    	}

    	public void method(int num) {
	    	System.out.println(num);
    	}
    }


オーバーライド：メソッド名、引数の数、順番が同じメソッドを定義すること。
オーバーロード：同じメソッド名で、引数の数と順番が違うメソッドを定義すること。
jsでの桁数が多い時の剰余の結果

```js
var x = 33492434009398
var y = 52142083333444300

var a = 100700038989

console.log((x + y) % a) // 65966161112
console.log((x % a + y % a) % a) // 65966161110
```

結果が違う。何故だ...

追記
コメントいただきましたが、9007199254740991以上は正しい計算ができないようです。
【Python】 OpenCVで写真を読み込む、保存する

# -
RaspberryPiでWebカメラを使うためにOpenCV使ってみる。
何回かに渡って記事を書く。

# OpenCV

インテルが開発したオープンソースのコンピュータビジョン向けライブラリ。
コンピューターで画像や動画を扱う時に必要な機能が実装されています。
商用利用可。

# 動かしてみる

**画像を読み込む**

```python:
import cv2

# Load an color image in grayscale
img = cv2.imread('sample.jpg',0)
```

**画像を表示する**

```python
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

**cv2.waitKey()**
>cv2.waitKey() はキーボード入力を処理する関数です．引数は入力待ち時間でミリ秒単位で指定します．この関数は，指定された時間だけキーボード入力を受け付けます．入力待ちの間に何かのキーを打てば，プログラムはそれ以降の処理を実行します．引数に 0 を指定した時は，何かしらのキーを打つまでキー入力を無期限で待ち続けます．以下で説明しますが，特定のキー入力のみを待つ(例えば a のみを待つ)ことも可能です．

**cv2.destroyAllWindows()**
>cv2.destroyAllWindows() は現在までに作られた全てのウィンドウを閉じる関数です．特定のウィンドウのみを閉じる場合は cv2.destroyWindow() 関数に閉じたいウィンドウ名を指定してください

**画像を保存する**

```python
cv2.imwrite('test.png',img)
```
>画像を保存するには cv2.imwrite() 関数を使います．
第1引数は画像のファイル名，第2引数は保存したい画像です．


# まとめ
今回はOpenCVの基礎中の基礎を記事にした。
次回からは実際にコードを書いて動かしてみる。

# 参考記事
[OpenCV-Python](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/index.html)
Jenkins「'python' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。」

# 問題その１

Windows10でcron代わりのJenkinsにpythonスクリプトを実行させたらエラー発生！！
python --versionすらエラーになる始末です。

```
C:\Program Files (x86)\Jenkins\workspace\myjob>python --version  
'python' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
```

# 問題その２

これは単純にパスが通ってなかっただけだったのでJenkinsの環境変数にpythonのパスを追加したら解決しました。

![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364248/f5a67a85-af08-57e8-c7ca-f1a87f644854.jpeg)

ところが次の問題が発生しました。

conda activateした後でbatが終了してしまい、肝心のpythonスクリプトが実行されていないのです。

```
C:\Program Files (x86)\Jenkins\workspace\auto_twitter>C:\ProgramData\Anaconda3\Scripts\activate.bat C:\ProgramData\Anaconda3 
Finished: SUCCESS
```

# 原因と解決策

conda activateでconda.batを直接呼び出しているため、終了したら元のJenkinsのbat本体も終了していることが原因だったのです。

そこで、conda activate をCALL呼び出しすることで解決しました。

## 修正前

`conda activate`

## 修正後

`CALL conda activate`

# 実行結果

conda activate 後のpythonコマンドが動きました。

```
C:\Program Files (x86)\Jenkins\workspace\auto_twitter>CALL conda activate 

(base) C:\Program Files (x86)\Jenkins\workspace\auto_twitter>python --version  
Python 3.6.8 :: Anaconda, Inc.
```

# おわりに

Jenkinsからpythonを呼ぶだけで　まさかパス問題に出くわすとは驚きました。
開発環境で時間を取られると　やる気とか　いろいろ消耗しますね。。。

# 環境

Windows10 
Jenkins 2.176.2
Anaconda(conda) 4.7.10
Python 3.6.8 :: Anaconda, Inc.


[ウチの子供にこんな迷路でひらがなを教えていて、結構よい感じでした。](https://めいろ.com)

こちらのサイトで古いですが公開しているので良かったら見てね。

# おまけ![hiragana_a_28_1_wall_sakura_out_square.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364248/65b8b495-4c94-9b26-81a5-e08ee214af8e.png)
EC2の.bash_profileを上書きした際にほとんどのコマンドが使えなくなった場合の対処法

ec2とかの環境変数をいじっていて、誤って元の環境変数のパスを上書きしてしまいlsやvimなどといったほとんどのコマンドが使えなくなってしまった場合以下のようにすれば解決できる。
但し、環境によりPathが必ずしも一致するとは限らないので、そこは調べながら試してみるしかなさそう。。

環境は以下
Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type 

###【エラーの例】

```
[ec2-user@ip-○○-○-○-○○ /]$ ls
-bash: ls: コマンドが見つかりません
```

###【解決方法】
まず以下を打ち込む！

```
[ec2-user@ip-○○-○-○-○○ /]$ /bin/vi ~/.bash_profile
```

そして、vimで.bash_profileに以下を記述します。

```
PATH=$PATH:$HOME/.local/bin:$HOME/bin
```

その後一度ログアウトして、再度EC2内にログインすれば元のコマンドが使える状態に戻っているはずです！
「教師強制と出⼒回帰のあるネットワーク」とは？

# 概要
E資格のシラバスの記載で簡単に解決できなかったことをメモ。

# 教師強制とは？
「Teacher forcing」の日本語訳かと思われる。
RNNの学習において、各タイムステップでの入力に教師データを用いる方法。
`I have a pen` の場合で考えると、入力x1`I`」から出力「y1`have`」といった形に予測する場合に、x2以降の入力に教師データの値を使用する。
>x1`I`    → y1`have`
>x2`have` → y2`a`
>x3`a`    → y3`pen`

### メリット
学習が安定し、収束が早い。

### デメリット
本番では入力に教師データが利用できないため、出力の誤差が累積してしまう。（Exposure bias）

# 出力回帰とは？
教師強制が入力X2以降にも教師データを用いるのに対して、モデルが推定した結果(yn-1)の値を入力xnに用いる方法。
>x1`I`    → y1`have`
>y1`have` → y2`a`
>y2`a`    → y3`pen`

要するに「xn = yn-1」となる。

### メリット
Exposure biasは発生しない。

### デメリット
学習が安定せず、収束が遅い
webpackのインストールと使い方

#webpackとは

モジュールバンドラーの中の１つ。モジュールをバンドルしてくれる役割をもつ。
複数のjsファイルを1つのファイルにまとめて依存関係を解決してくれる。

#webpackの導入

webpackを導入するにはプロジェクトフォルダを用意して、ターミナルを立ち上げます。
名前はwebpack_testなど適当につけます。

ターミナルを立ち上げpackage.jsonを作成します。

````
npm init -y
```

続いて、webpackとwebpack-cliをインストールします。

````
npm install -D webpack webpack-cli
```

-Dオプションをつけることで開発用にインストールされるので、package.jsonのdevDependenciesに記載があるかどうかを確認する。

````package.json
  "devDependencies": {
    "webpack": "^4.39.2",
    "webpack-cli": "^3.3.7"
  }
```

#構成

プロジェクトフォルダにjsファイルを作成していきます。srcフォルダの中にエントリポイントとなるindex.jsと後ほど出力されるmain.jsを読み込むindex.htmlを作成し、以下のようにします。

````
webpack_test
├─ dist
│   └── index.html
├── node_modules
├── package-lock.json
├── package.json
└── src
    ├── hello.js
    └── index.js
```

````index.js
import { hello } from './hello'
hello();
```

````hello.js
const hello = () => {
    console.log("hello");
}

module.exports = hello

```

````index.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <script src="main.js"></script>
    <title>Document</title>
</head>

<body>
    <p>Hello Webpack</p>
</body>

</html>

```

#エントリポイント
プログラムの実行を開始するファイル。importなどでjsモジュールを読み込んでいるファイル。今回はindex.jsになる。

#実行

webpackをnpm installをしたので、node_modules内にライブラリがある。
実行は以下のコマンドで行う。

````
npx webpack  --mode development
```
このコマンドは以下と同様です。

````
node ./node_modules/.bin/webpack  --mode development
```

またpackage.jsonに以下を記述し

````package.json
  "scripts": {
    "build": "webpack --mode development"
  }
```

````
npm run build
```
としても同様です。
--mode developmentのオプションをつけているのは、ソースマップに対応され、デバッグに便利だったりと開発に向いているからです。上記のコマンドを実行すると以下のようにdistディレクトリにmain.jsファイルが出力されます。

```
webpack_test
├── dist
│   ├── main.js
│   └── index.html
├── node_modules
├── package-lock.json
├── package.json
├── src
│   ├── hello.js
│   └── index.js
```


#webpack.config.js
webpackの設定ファイル。プロジェクトルートに置きます。なくても実行できますが、エントリポイントがデフォルトでsrc/index.jsになり、出力先がdist/main.jsになります。先ほど出力先がmain.jsでしたが、outputのdistを変更すると出力先が変更になります。pathオブジェクトをrequireで読み込んでいますが、path.resolve(__dirname, "dist")とすることで絶対パスを出力してくれます。


````webpack.config.js
const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: 'main.js',
    }
}
````

#ブラウザで起動

webpack.config.jsにdevServerの設定を追加する。

````webpack.config.js
const path = require('path');

module.exports = {
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: 'main.js',
    },
    devServer: {
        contentBase: path.resolve(__dirname, 'dist'),
    }
}
````

以下のコマンドを実行し、package.jsonにstartを追加する。

```
npm install -D webpack-dev-server
```
````package.json
  "scripts": {
    "start": "webpack-dev-server",
    "build": "webpack --mode development"
  }
```

以下のコマンドを実行する。

```
npm start
```

[http://localhost:8080/](http://localhost:8080/)にアクセスしてHello Webpackが表示されれば成功

#参考URL

webpack公式
https://webpack.js.org/

最新版で学ぶwebpack 4入門　JavaScriptのモジュールバンドラ
https://ics.media/entry/12140/

webpack入門
https://qiita.com/hika7719/items/76e87b6ecf308516c514

webpack.config.jsで思ったpath.resolveって何のためにあるの？
https://koukitips.net/post1825/
Java学習メモ（継承）

Java Silverの勉強をしているので自分の忘備録としてUPします。
ざっくりとしたメモなので、詳細は記載してません。

クラスを継承することで、以前作った機能と共通する部分を引き継ぐことができる。
サブクラスのクラス名の後ろに「extends」を付けて、継承元（スーパークラス）のクラス名を記述する。

1:名前と表示させる。

    public class _extends {
	    protected String name;
    	protected int num;

    	protected void method(){
	    	System.out.println(num + ":" + name);
    	}
    }

    public class _subextends extends _extends{
    	public void method2(String name,int num) {
    		super.name = name;
    		super.num = num;
    		method();
    	}
    }

    public class Test {
		public static void main(String[] str){
			_subextends e = new _subextends();
			e.method2("名前",1);
		}
    }
kind（Kubernetes IN Docker）でローカルの Docker image を使う方法

# TL;DR

以下のコマンドでローカルの Docker image を kind で作成した k8s にアップロードすることが可能です。

```bash
$ kind load docker-image IMAGE:TAG
```

アップロードした Docker image を使う際には `imagePullPolicy: IfNotPresent` もしくは `imagePullPolicy: Never` の設定を行ってください。また、既にアップロード済みの場合には Docker image が更新されることなく処理が終了する仕様なのでご注意ください。

# はじめに

kind（Kubernetes IN Docker）でローカルの Docker image を使う方法を紹介します。
https://github.com/kubernetes-sigs/kind

# 動作確認

kind で k8s クラスタを作成します。

```bash
$ kind create cluster
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.15.0) 🖼
 ✓ Preparing nodes 📦
 ✓ Creating kubeadm config 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
Cluster creation complete. You can now use the cluster with:

export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"
kubectl cluster-info
```

ローカルで Docker image をビルドします。

```bash
$ cat Dockerfile
FROM busybox
ENTRYPOINT sh -c "echo 'Hi, kind!' && sleep 10000"

$ docker build -t my-image:tag .
```

ローカルの Docker image を kind にアップロードします。

```bash
$ kind load docker-image my-image:tag
```

kind で作成した k8s にアップロードした Docker image を Pod としてデプロイします。
`restartPolicy: Always` になっていると Docker image をリモートから取得するようになってしまうので、`imagePullPolicy: IfNotPresent` もしくは `imagePullPolicy: Never` の設定を行うことを忘れないでください。

```bash
$ cat manifest.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-image
spec:
  containers:
  - name: my-image
    image: my-image:tag
    imagePullPolicy: Never

$ export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"
$ kubectl apply -f manifest.yaml
```

アップロードした Docker image が使えているか確認します。

```bash
$ kubectl get pods
NAME       READY   STATUS    RESTARTS   AGE
my-image   1/1     Running   0          10s

$ kubectl logs my-image
Hi, kind!
```

アップロードした Docker image が使えることが確認できました。

# 備考

既にアップロード済みの場合には Docker image が更新されることなく処理が終了する仕様なのでご注意ください。この仕様に関する詳細を知りたい方は以下の Issue を参照ください。
https://github.com/kubernetes-sigs/kind/issues/380

今回は Docker image のアップロードを紹介しましたが、以下のコマンドで `docker save` で Docker image のアーカイブをアップロードすることも可能です。

```bash
$ kind load image-archive IMAGE_ARCHIVE.tar
```

# 参考資料

- https://github.com/kubernetes-sigs/kind/blob/master/site/content/docs/user/quick-start.md#loading-an-image-into-your-cluster
Vuetify(v2.0.0 )でv-colのxsを設定する

vuetify(v2.0.0)からは、`v-col`でBreakpointsごとのgridの設定を行う。
Breakpointsは、これまで通り。

<img width="912" alt="スクリーンショット 2019-08-24 22.19.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204896/e28cd7ab-fbd0-dd06-1cc3-7a7d5c89c436.png">

スマホでのBreakpointはxsとなる。スマホとそれ以外でgridを変えたい場合に、うまくいかずハマった。

### 結論

```html
  <v-row>
     <v-col lg=9 md=9 sm=9 cols=3>
        aaa
     </v-col>
     <v-col lg=3 md=3 sm=3 cols=9>
        bbb
     </v-col>
  </v-row>
```

`v-col`には、`cols`でgridを設定できるが、`xl,lg,md,sm`に関しては細く設定が可能。
`xs`はなぜか設定できないので、以下のような書き方だとうまく動かない。

```html
<v-col lg=9 md=9 sm=9 xs=3>
```

なので、colsで全体のgridを設定しておき、`xl,lg,md,sm`の設定を上書きし、スマホとそれ以外でのgridを変更するしかない模様。

issueは上がってた(2019/08/24)
https://github.com/vuetifyjs/vuetify/issues/8672
Codableでレスポンス形式のゆらぎを吸収するPrice型をつくる

# はじめに

アプリで利用するAPIの種類が増えてくると、**APIによってAPIレスポンスの形式が異なる**という課題が発生します。

例えばこのような価格を返す複数のAPIがあったとします。

```json:Int型で返す
{ "price": 10000 }
```

```json:String型（価格フォーマットなし）で返す
{ "price": "10000" }
```

```json:String型（価格フォーマットあり）で返す
{ "price": "10,000円" }
```

特に複数APIのマッシュアップをするような大規模サービスでは、**ドメイン毎にコード規約やレスポンス形式の考え方**が異なるため、同じ価格を表現するレスポンスでもこのようなことが発生しがちです。これらの**レスポンス形式のゆらぎを吸収するPrice型**をCodableでつくってみます。

# Price型をつくる

上記の課題を解決するために、以下のようなPrice型を定義してみます。
Price型はDecodableに準拠し、`init(from decoder: Decoder) throws`メソッドを実装することでデコード処理をカスタマイズしています。

```swift:Price型の実装
struct Price: RawRepresentable, Decodable {
    typealias RawValue = Int
    
    let rawValue: Int
    
    init?(rawValue: Self.RawValue) {
        self.rawValue = rawValue
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        
        // String型からInt型に変換する
        // 後述するextractNumber関数を用いて文字列から数字のみを取り出す
        if let stringValue = try? container.decode(String.self), let intValue = Int(stringValue.extractNumber) {
            self.rawValue = intValue
            return
        }
        
        let intValue = try container.decode(Int.self)
        self.rawValue = intValue
    }
}
```

文字列から数字のみを取り出すextractNumber関数は以下のように実装しています。

```swift:文字列から数字のみを取り出すextractNumber関数
extension String {
    var extractNumber: String {
        return trimmingCharacters(in: CharacterSet.decimalDigits.inverted)
            .replacingOccurrences(of: ",", with: "")
    }
}
```

# Price型を利用してデコードする

以下のようなJSONレスポンスを想定します。

```json:JSONレスポンス
{
    "price1": 1000,
    "price2": "2000",
    "price3": "3,000円",
    "price4": "¥4,000"
}
```

以下のように、レスポンスの価格の表現形式によらず、Price型としてデコードができます。

```swift:レスポンスの価格の表現形式によらず、Price型としてデコード
let jsonString = """
{
    "price1": 1000,
    "price2": "2000",
    "price3": "3,000円",
    "price4": "¥4,000"
}
"""
let data = jsonString.data(using: .utf8)!

// レスポンスの価格の表現形式によらず、Price型としてデコード
struct Item: Decodable {
    let price1: Price
    let price2: Price
    let price3: Price
    let price4: Price
}

do {
    let item = try JSONDecoder().decode(Item.self, from: data)
    print(item)
} catch {
    print(error)
}
```

# UI表示のためにさらに便利にする

せっかくPrice型という独自型を定義したので、価格表示のための文字列を返すロジックを実装します。ここでは、**価格は3桁区切りのカンマをつけ、〜円の形式で表示する**というドメインロジックがあると想定します。

Int型を拡張子し、3桁区切りのカンマを付与した文字列を返す`withComma`プロパティを実装します。それを用いて、Price型に`formattedString`プロパティを実装します。

```swift
extension Int {
    /// 3桁区切りのカンマを付与した文字列を返す
    var withComma: String {
        let formatter = NumberFormatter()
        formatter.numberStyle = .decimal
        return formatter.string(from: NSNumber(value: self)) ?? "\(self)"
    }
}

struct Price: RawRepresentable, Decodable {
    /// 3桁区切りのカンマをつけ、〜円の形式にした文字列
    var formattedString: String {
        return rawValue.withComma + "円"
    }
    
    // 〜中略〜
}
```

`formattedString`を用いることで、以下のように価格表示のフォーマットが簡単にできます。

```swift
print(item.price1.formattedString) // "1,000円"
print(item.price2.formattedString) // "2,000円"
print(item.price3.formattedString) // "3,000円"
print(item.price4.formattedString) // "4,000円"
```
RTX1200でNuro光 Ipv6に対応させた

## Nuro光を契約した
1年ほど前、Nuro光を契約してみた。上下常時、最低でも500mbpsでる非常によい回線を提供してくれる。

ちなみに、ONUとルーターが分離できるNuroBizではなく、普通のNuro光 マンションプランを契約した。

## Ipv6が取得できない？
当時割り当てられてたHGWでは、なぜだかIPv6アドレスが取得できなかった。確か、HG8045jだったかと思う。1年くらいたってどうにも行かず、相談したところなぜかHGW交換となった。交換になったHGWはHG8045D。交換後、Ipv6アドレスが降ってくるようになった。/64のプリフィックスで無事降ってくる。


## 二重ルーター
Nuro光の欠点として、ONUと役に立たないルーターが一体化しており、切り離せないというものが挙げられる。多くのユーザーはRTXやNVRをつないでいることだろう。自分もRTX1200を配下につないである。

## RTX1200配下で、ipv6通信が疎通せず....?
HGW直下にあるクライアントでは、IPv6通信が疎通するものの、HGW直下のRTX1200配下のクライアントでは、IPV6通信が疎通せず。ん...???Nuro光サポートに問い合わせるも全くらちがあかないので、yamahaお客様サポートセンターに泣きついてみた。

## RTX1200でnuro光 Ipoeに対応させるコンフィグ
結局、適当に他からコピペしてきたコンフィグが悪かった様子で、yamahaサポートに適切なコンフィグを教えてもらった。フィルタは別途必要。

```
ipv6 routing on
ipv6 prefix 1 ra-prefix@lan2::/64
ipv6 lan1 address ra-prefix@lan2::1/64

# 下記のconfigは誤っている可能性が高く削除させていただいた。
# ご指摘ありがとうございます。
# ipv6 lan1 address ra-prefix@lan2::/64

ipv6 lan1 rtadv send 1 o_flag=on
ipv6 lan1 dhcp service server
ipv6 lan1 mld router version=2
```

ipv6はまだまだ知識不足で、学習を進めないといけないなという感じ。

# お礼
記事作成から3年経過しても見てくださっている方が多いようで、内容の修正依頼を受け取った。おそらく内容として正しいと思われるので採用した。
ラズパイ+momoでWebRTCで送信するときにマイクの代わりに音声ファイルを使用する

ラズパイ+momoでWebRTCで送信するときにwebcamをつなぐとマイクとしてwebcamの内蔵マイクが使用できる。しかし専用カメラモジュールを使用したときはマイクがない。

音声なしの配信ではさびしいので、あらかじめ用意した音声ファイルの内容を送信できるようにした。

## 概要

ALSAのloopbackデバイスを使用するとオーディオキャプチャデバイスに任意の内容を流し込むことができる。
これを使ってmomoにあらかじめ用意した音声ファイルを読み込ませる。

使用したmomoのversionは以下の通り。

```
./momo --version
WebRTC Native Client Momo version 19.08.0 USE_MMAL_ENCODER=1
```

## 音声ファイルの準備

momoでは音声のエンコード、デコードはソフトウェアで行う。ラズパイのように非力なCPUにとっては負荷が大きい処理である。
そこで使用する音声ファイルはあらかじめデコードしてwavファイルにしておく。
形式はサンプリングレート 48kHz ステレオ。

```
ffmpeg -i input.mp3 -ar 48000 -ac 2 output.wav
```

## ALSA loopback デバイス

今回は音声ファイルを流し込むのにALSAのloopback デバイスを使用する。

### カーネルモジュールのロード

```
sudo modprobe snd-aloop
```

起動時に自動的にロードするには `/etc/modules` に追記しておく。

```
sudo sh -c "echo snd_aloop >> /etc/modules"
```

### Loopback ができていることの確認、

```
$ arecord -L |grep Loopback
  ...
hw:CARD=Loopback,DEV=0
    Loopback, Loopback PCM
hw:CARD=Loopback,DEV=1
    Loopback, Loopback PCM
plughw:CARD=Loopback,DEV=0
    Loopback, Loopback PCM
plughw:CARD=Loopback,DEV=1
    Loopback, Loopback PCM
```


## ALSA のコンフィグファイル

[前回の記事](https://qiita.com/tetsu_koba/items/33e335fb46f26bbd3431) の通りmomoはオーディオキャプチャデバイスとして `default` を使用する。
なので、loopback の受け側を `default` として参照できるようにALSAのコンフィグファイルを用意する。

```~/.asoundrc
pcm.!default {
  type plug
  slave.pcm "hw:Loopback,0,0"
}
```

### 音声ファイルを流し込む

`-vv` オプションをつけるとVUメータが表示される。

```
aplay -D hw:Loopback,1 -vv sample.wav
```

### defaultのオーディオキャプチャデバイスに音がきていることの確認

上記のコマンドを実行したままで、別のターミナルを開いて

```
arecord -D default -vv -f dat > /dev/null
```

これでVUメータが振れていればOK。^C で止める。

### 複数のwavファイルを順番に流す場合のスクリプト

```shell
#!/bin/sh

TEST_SOUND_DIR=~/wav/

while :; do
  for i in $TEST_SOUND_DIR/*.wav; do
    aplay -D hw:Loopback,1 "$i"
  done
done
```

## momoの実行

これで通常通りmomoを実行すれば、流し込んだ音声ファイルの配信ができる。

しかし聞いてみるとモノラルになってしまっている。(ステレオの左チャネルの音しか聞こえない。)
ログを調べてみると、どうも人の話し声を想定したエコーキャンセリングやオートゲインコントロールがデフォルトで有効になってしまっているようだ。
音楽を流す時にはこれらの機能をオフにしたいが、現状のmomoにその機能はまだ無い。

~~今はとりあえずここまで。~~

続きを書きました。
[ラズパイのmomoでステレオ音声でWebRTCで配信する](https://qiita.com/tetsu_koba/items/6c07129caa5a08d5d172)
Automation Anywhere パターンベースのスクレイピングで1ページ目しかデータが取れないときのデバッグのヒント

Automation Anywhere の[パターンベースのデータ抽出](https://qiita.com/RPAbot/items/b8b4547893e00f8c3a34)による複数ページのスクレイピング手法でボットを実行したときに、エラーが出ずに正常終了したとしても、エクスポートしたCSVの中身を見ると正常にデータが取れていないときがあります。多いパターンとしては、最初の1ページ目しかデータが取れない場合です。

このような場合に何を試すべきかのメモです。

# デバッグ方法
Web Recorderでパターンベースのデータ抽出を記録すると、典型的には以下のようなアクションリストが作成されます。
![aa-web-scraping-advanced31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/8b075745-0bda-e2c9-684d-ce9e6fd7452f.png)

作成されたアクションリストを実行すると、Internet Explorerが起動して、どんどんページがめくられていきます。ページ数がとても多い場合は最後まで実行されるのを待つととても時間がかかる場合がありますので、そのような場合は、最初の数ページの処理が完了した段階で、右下のランタイムウィンドウ上にある「中断 (Pause)」ボタンをクリックして一旦停止させて、エクスポート先のCSVファイルの中身を見てみましょう。
![aa-bot-runtime-window.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/4b59b3cb-5749-d62b-7a41-ea1b528b7c2a.png)

CSVファイルは各ループ毎に内容がファイル上にコミットされ、正常に処理が進んでいれば、処理が終わったページまでのデータがCSVファイルに書き込まれているはずです。

#【症状1】Internet Explorer でいつまでたってもページがめくられない
このケースでは、次のページに行くときに押されるボタンが正しく選択されていないケースが多いです。アクションリストの5行目の`Click on...`コマンドを選択して編集ボタンをクリックします。すると、以下のようなダイアログボックスが表示されます。
![aa-web-recorder-clickon01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/0e79e724-9f5a-7199-2e71-dfae1e81e4d4.png)

このダイアログボックスの右下の「Advanced View」ボタンをクリックして詳細を表示します。Step 4のコントロールの検索方法を確認して、条件を変更してみましょう。
![aa-web-recorder-clickon02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479715/5031f1b5-7073-eadf-a4d9-f5b205571e1f.png)

Control Name、Control ID、Caption、Control Index、Attributesなどいくつかのプロパティでキャプチャされている情報があるので、別のプロパティにチェックを変えてみたり、情報の内容を編集してアップデートしてみたりして試してみてください。


#【症状2】ページはめくられているが1ページ目のデータしか取れない
実行時に、Internet Explorer 上では順調にページがめくられているのに、CSVの中身をチェックすると1ページ目のデータしか書き込まれていない場合があります。サイトのページ構造によりますが、1ページ目と2ページ目以降でページの構造が異なる場合があり、その場合は2ページ目からスクレイピングを開始するとうまくいく場合があります。

このような場合は、1ページ目は別途スクレイピングを行い、2ページ目以降のデータと後で統合するなどの工夫が必要になります。
Swiftの#lineと#columnについて

# 基本

\#lineはコード上の行番号、#columnはコード上の列番号を示す

```swift
let res1 = #line
let res2 = #column

print(res1) // 1
print(res2) // 12
```

行番号は1から数えるので、ファイルの先頭で#lineを呼んでいる場合は1になる。
列番号も同様に、1から数える。上の例では#の位置は12文字目なので12になる

# 列番号がおかしくなる時

```swift
let res1 = #line
let res2あ = #column

print(res1) // 1
print(res2あ) // 15
```

上の例の変数名`res2`に平仮名を一文字足して`res2あ`としてみた。
結果は15になる。
基本の項では、行番号と解説したが**#columnの実態はutf8のバイト数**である。


```swift
"let res2あ = #".utf8.count //15
```

\#columnまでの文字をutf8にして数えると、#columnがいくつを指すか調べることができる。
（上の例では#を含めて#columnが返す値を計算している）

# utf8とは

いろんな文字を表現するために、人間の読む文字とコンピュータの読む文字の対応表で変換する方式みたいなもの。
例えば上の例で出てきた「あ」は「E3 81 82」で3byte使う
Debian系でディレクトリ名を英語にしよう

#ディレクトリ名を英語にしよう
linuxを日本語化すると、DownloadsやDesktopといったホームディレクトリ直下のフォルダ名が日本語になってしまい、cdコマンドを使うときに色々面倒なことになります。そこで、これらのファイルを英語化しようと思います。

```bash:必要なパッケージのインストール
sudo apt install xdg-user-dirs-gtk
```
たまに入ってないので一応インストールしておきましょう。

```bash:コマンド実行
LANG=C xdg-user-dirs-gtk-update
```
この後、ウィンドウが出てくるのでupdate nameをクリックすると英語化されます。
GridSearchCVでcvにLeaveOneOut、評価指標にr2を指定した時の話

# 現象
GridSearchCVでcvにLeaveOneOut、評価指標にr2を指定した場合、GridSearchCVのbest_scoreがnanになる。評価指標をneg_mean_squared_errorにすると値が出る。少し悩む。

```python
＜省略＞　
[CV] .................................. n_components=10, total=   0.0s
[CV] n_components=10 .................................................
[CV] .................................. n_components=10, total=   0.0s
[CV] n_components=10 .................................................
[CV] .................................. n_components=10, total=   0.0s
[CV] n_components=10 .................................................
[CV] .................................. n_components=10, total=   0.0s
[CV] n_components=10 .................................................
[CV] .................................. n_components=10, total=   0.0s
[Parallel(n_jobs=1)]: Done 1000 out of 1000 | elapsed:    1.7s finished
Best Param={'n_components': 1}, Best Score=nan
```

# 結論というか推測
LeaveOneOutの場合、各分割のテストフォールドは1件のみとなる。
GridSearchCVのスコア計算は、(恐らく)各分割の予測結果に対し評価指標を計算し、全分割の平均をとっている。
相関係数の定義より、1件しかデータがない場合、分母は0になるため計算はできない。
よって各分割の評価指標の計算結果はnanとなり、これらの平均をとってもnanとなる。

要するにGridSearchCVに今回の組み合わせを指定した場合、スコアの高いパラメータの判定ができないということで、使い方が間違っていたということ？
暇なときにソースを見てみよう。
UNIX哲学

書籍「プリンシプル オブ プログラミング 3年目までに身につけたい 一生役立つ101の原理原則」を読んだメモ

UNIX哲学とは、UNIXの背後にある設計哲学

## 小は美なり

- 小さいソフトウェアは美しく、価値が高い
- ソフトウェアを設計するときは、小さく設計して１つの仕事に専念させる
- 機能が足りなければ、他のソフトウェアと連携させる
- 解決する問題をきちんと理解する

## 1つ1仕事

- 1つのソフトウェアには、１つのことをやらせる
- 問題が大きかった場合は、まず問題を小さく分割する
- 大きな問題を解決するには、1つの仕事をこなす複数のソフトウェアを作成する
- 新たな問題が発生した場合は、既存ソフトウェアに機能を追加するのではなく、新たなソフトウェアを作成して連携させることで、スパゲティコードになることを防ぐ

## 即行プロトタイプ

- できるだけ早くプロトタイプを作成する
- プロトタイプのメリット
  - 前提の誤りを早期発見できる
  - 要件不備による手戻りを減らせる
  - 早いうちから誤りを取り除く作業を始められる

## 効率性より移植性

- 移植性と開発効率性は二律背反だが、移植性を優先すべき
- 移植性を高めるには、
  - ハードウェアに依存しないコードを書く
  - ハードウェアに依存する部分と依存しない部分を切り離した設計をする

## データはテキスト

- データの移植には、一般的で移植性の高いテキストファイルを使う
- データはテキストファイルに保存するようにし、各テキストファイルを入出力に使用するように設計する
- テキストファイルの中でも言語やOSによらない標準的な形式(CSV、XMLなど)を選択する

## レバレッジ・ソフトウェア

- 既存のソフトウェアを再利用しながら、ソフトウェアとソフトウェアを組み合わせる
- 機能満載の大きなソフトウェアを書くのではなく、それぞれが単機能で単価値に集中した小さなソフトウェアを作る
- それらをグルー言語でつなげ、大きな仕事を成し遂げる

## シェルスクリプト活用

- シェルスクリプトを活用して、他のソフトウェアやコマンドをつなげる
- シェルスクリプトはインタプリタでプラットフォーム専用のバイナリにコンパイルする必要もなく移植性が高い
- シェルスクリプトをグルー言語として利用する

## 対話インターフェース回避

- ユーザもマシンも拘束される対話インタフェースは回避する
- 1つ仕事をして、それを終えたらコマンドインタプリタに制御を返すようなソフトウェアを作成する

## フィルタ化

- ソフトウェアはフィルタ化として設計する
- フィルタ化: 入力ストリームをデータとして受け取り、何らかの加工を施し、加工したデータを出力ストリームに送り出す
- ソフトウェアはデータを処理するフィルタとして設計し、コマンド起動できるソフトウェアの場合は標準出力を使う
Leetcode #486: Predict the Winner

Solution 1: Recursion

```swift
func PredictTheWinner(_ nums: [Int]) -> Bool {
    return winner(nums, 0, nums.count-1, 1) >= 0
}

private func winner(_ nums: [Int], _ start: Int, _ end: Int, _ turn: Int) -> Int {
    if start == end {
        return turn * nums[start]
    }
    let a = turn * nums[start] + winner(nums, start+1, end, -turn)
    let b = turn * nums[end] + winner(nums, start, end-1, -turn)
    return turn * max(a*turn, b*turn)
}
```

Solution 2: Dynamic programming

```swift
func PredictTheWinner(_ nums: [Int]) -> Bool {
    var dp = Array(repeating: Array(repeating: 0, count: nums.count), count: nums.count)
    for i in stride(from: 0, to: nums.count, by: 1) {
        dp[i][i] = nums[i]
    }
    for len in stride(from: 1, to: nums.count, by: 1) {
        var i = 0
        for j in stride(from: len, to: nums.count, by: 1) {
            dp[i][j] = max(nums[i] - dp[i+1][j], nums[j] - dp[i][j-1])
            i += 1
        }
    }
    return dp[0][nums.count-1] >= 0
}
```
Java学習メモ（interface）

Java Silverの勉強をしているので自分の忘備録としてUPします。
ざっくりとしたメモなので、詳細は記載してません。

interfaceは処理内容を具体的に記述せず、後からメソッドの実装をして使用する。
処理を変えたい場合に有効である。
interfaceを実装する場合は、implementsを使用する。

＜ポイント＞
①メソッドの実装不可。
②メンバ変数は定数であること。
③多重継承が可能。

    interface A {
        String str1 = "おはよう";
        String str2 = "こんにちは";
        void A();
     }

    // インタフェースを実装し、おはようと出力するクラスを作成
    class B implements A {
        public void A() {
            System.out.println(str1);
        }
    }
 
    // インタフェースを実装し、こんにちはと出力するクラスを作成
    class C implements A {
        public void A() {
            System.out.println(str2);
        }
    }
composer でエラー

# エラー内容
```
$ composer install
[ErrorException]                                                             
"continue" targeting switch is equivalent to "break". Did you mean to use "  
continue 2"?
```

### [原因]
1. PHP7.3からcontinue は使えなくなるらしくそのエラーのようです。
2. composer のバージョンに問題がある

私の場合は、別環境をそのまま入れたいだけなので、２番でした。

# 対処方法

まずcomposer のバージョン確認 ```compsoer -V``` をしたところ、1.5だったので、最新版へ
アップデート(バージョンアップ)します

```
composer self-update
```

# 終わり
これだけで、composer install が実行できました！
composer のバージョンアップの方法を探すのにちょっと苦労しました。。
よかった。
Salesforceを触ってみる知ってみるには

# Salesforceを触ってみる知ってみるには

## まずTrailheadをやってみるというのが良いかと思います。


**特徴**
・Salesforceの活用方法を習得できるオンライン学習プログラム

・ポイントやバッジなど、ゲーム性を持たせており、効率良く楽しく学べるのも特徴

・役割やレベルに応じてさまざまなカリキュラムが用意されており、自分の理解やペースに合わせて学べる


Trailhead の FAQ
https://help.salesforce.com/articleView?id=000213549&language=ja&type=1





### Trailheadも種類が色々あり、何からやったらいいの？と思いますので、下記URLに載っているTrailheadからやっていくのが良いと思います。



- 初心者のためのTrailhead

https://trailhead.salesforce.com/ja/users/welcome1530/trailmixes/beginner-trailhead 

Salesforce初心者のためのTrailheadをまとめてあります。


#### その他、オススメTrailheadです。

- Salesforceに初めてチャレンジする

https://trailhead.salesforce.com/ja/users/sfggjp/trailmixes/first


- Salesforceの開発をはじめる（開発者寄り）

https://trailhead.salesforce.com/ja/users/00550000007HqDdAAK/trailmixes/start-develop
UnityのVR SamplesのMazeをTouchコントローラで操作できるようにする

# はじめに
前回記事 [UnityのVR SamplesをOculusQuestで動かしてみる]
(https://qiita.com/Satoshi_Takahama/items/013e318aed2ed783ad77) の続きです。
今回は、アセットに含まれているゲームの一つ、The Mazeを改造してTouchコントローラで操作できるようにしてみます。

#開発環境
Unity 2019.2.0f1
VR Samples - 1.4
Oculus Integration for Unity - 1.39

#ビルド手順
前回記事で作成したプロジェクトで引き続き作業します。

1. Oculus Integrationをアセットストアからダウンロードし、インポートします。インポートには10分くらい時間がかかります。途中でPluginのUpdateするかどうか聞かれますが、すべてUpdateして問題ありません(2019/8/24時点の最新版1.39では)。
2. 今回はThe Mazeを改造するので、サンプルのシーンMazeを開きます。![Assets.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/3e2288a1-d035-e05c-e49c-bd30afebc08c.png)
3. OVRPlayerControllerをHierarchyに配置します。さらに、OVRControllerPrefabを、LeftControllerPrefabとRightControllerPrefabに配置します。このあと、LeftControllerPrefab側に配置したOVRControllerPrefabのControllerをL Tracked Remoteに変更しておきます。![OVRPlayerController.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/21e544a6-1cd4-75ba-9820-b28cfcbec8f8.png)![OVRControllerPrefab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/c30364b8-e6a5-3d43-e598-a1eb87a3cc08.png)
4. OVRCameraRigのTarget DevicesをQuestに、Tracking Origin TypeをFloor Levelに変更します。![OVRCameraRig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/740f955e-78f6-0ef7-9bf0-28510b61b068.png)
5. OVRPlayerControllerの初期位置をCharacterの背後に設定します。図の設定値にします。![OVRPlayerController2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/d6d4fb4d-2d0a-f832-6115-f251db18bb74.png)
5. AndroidManifest.xmlを再生成します。メニューのOculus->ToolsからRemove AndroidManifest.xmlを選択します。次に、Oculus->ToolsからCreate store-compatible AndroidManifest.xmlを選択します。
4. シーン上に配置できるカメラは1個なので、元から配置されていたMainCameraのカメラを無効にします(Cameraのチェックを外す)。![MainCamera1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/8a00e3f0-6231-7f7b-fc78-b21818e183fc.png)
5. マーカーの操作を視線からTouchコントローラに変更するため、これまでMainCameraのTransformが設定されていた２か所を
RightControllerAnchorのTransformに変更します。![MainCamera2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/c1359155-7a02-41b4-2384-e0a668ca975a.png)
6. この時点で一応動かせるようにはなっているので、Build Settings からビルドします。

#さいごに
現時点では以下の問題があるため、次回、さらに改造してみます。
・スタートボタンの位置が押しにくい
・キャラクターが移動した後にカメラを操作して追いかける必要がある
・クリアしてゲーム再開後、キャラクターのみ初期位置に移動するためカメラを操作して追いかける必要がある
[UnityのVR SamplesのMazeでカメラの位置をキャラクターに追従する]
(https://qiita.com/Satoshi_Takahama/items/e0f4e0e07543c0d60f84)
Ciscoスイッチにファンコンつけて冷却しよう

## 概要
先日、ciscoのスイッチを購入した。モデル名はこんな感じで。

```
Switch Ports Model              SW Version            SW Image
------ ----- -----              ----------            ----------
*    1 26    WS-C2960S-24TS-S   12.2(53)SE2           C2960S-UNIVERSALK9-M
```

内蔵されているファンはシロッコファン。オマケに摩耗していて爆音を奏でていた。1k貧乏暮らしにはつらい。

## そうだ、ファンを抜いてみよう
うるさすぎて安眠妨害なので、試しにファンを抜いてみた。とっても静か！！

しかし、エアコンの効いた室内でshow env all してみると、筐体温度は怒りの65度に上昇していた。触ってみたら触れないくらい熱い。

燃えるとまずいので電源を抜いた。当然、自宅のNWが止まってしまった。

## ファンを交換しよう！
交換用のシロッコファンを購入するのは結構難易度が高い。調べてみると、80mmのPC用ファンの枠の一部をカットすることでシロッコファン風にしている人がいたので、真似してみる。

購入したブツは、
https://www.amazon.co.jp/gp/product/B002BVUNEE/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1

配線の2,3ピンを入れ替えて刺すも、全力回転するのであまり静かではない。冷えるけど。

## ファンコンを自作しよう！
ブツは4ピンファンで、PWM制御に対応している。ということは、モータードライバを駆使せずとも制御が可能と言うこと。いい感じにその辺に転がっていたAttiny13Aを使って、ファンを制御していこう。

## 回路図？
![コメント 2019-08-24 204215.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134622/d96843fc-e211-35e7-2240-dc77ab94001d.png)

実際には全部終わった後に、メモを元に雰囲気で書いた回路図なので、間違っているかも...。半固定抵抗の出力を13Aの2ピンに、13Aの5ピンをPWMファンのPWM端子へ接続する。5V,12Vは適宜適当に供給を。例えばhttp://akizukidenshi.com/catalog/g/gM-06353/　　などを使うと簡単。

## ソース
```
#define AnalogOut 0
#define IN1 3
int val = 0;
void setup() {
  pinMode(AnalogOut, OUTPUT);
  pinMode(IN1 ,INPUT);
}

void loop() {
val = analogRead(IN1);
val = val/4;
analogWrite(AnalogOut,val);
}
```
Arduinoの使い方をさっぱり忘れていた。雰囲気でやってみたら大体こんな感じ。確かADCが10bitで、PWM出力が8bitだったと思うので4で割ってるけど、別にビットシフトすればよかったと思った。

今回何でもいいからPWMが出てくれればいいので,内蔵オシレータを使用する。9.6Mhz駆動になる。13AのArduinoライプラリはBitduinoを用いた。書き込み方法などはhttp://miraluna.hatenablog.com/entry/tiny13
で解説されていたものを参考に。。



## 設置！
![iOS の画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134622/999e4e24-8523-bf08-4871-77f32cdaf7c3.jpeg)

12Vは元々のファンコネクタから供給。筐体内におあつらえ向きな空間があったのでそこに蛇の目基板を押し込む。プラスペーサーで浮かせて、瞬間接着剤で固定。わりといい感じにくっついてくれた。Qiコネクタのコンタクトを会社に忘れたので、電源入力が直付けになっていて残念。組み込み後のプログラム修正も全く考えてないところも残念。でも動くからよし！

## 調整
無事動くことを確認してから、半固定抵抗を調整し、ギリギリ我慢できる超低回転に設定しておく。回転数のフィードバックは省略したので回転数は分からない。

## 結果！
```
2960S1>show env all
FAN is OK
TEMPERATURE is OK
Temperature Value: 47 Degree Celsius
Temperature State: GREEN
Yellow Threshold : 50 Degree Celsius
Red Threshold    : 60 Degree Celsius
SW  PID                 Serial#     Status           Sys Pwr  PoE Pwr  Watts
--  ------------------  ----------  ---------------  -------  -------  -----
 1  Built-in                                         Good

SW  Status          RPS Name          RPS Serial#  RPS Port#
--  -------------   ----------------  -----------  ---------
1   <>              <>
```

ギリギリ許容範囲内に収まるようになった。もうちょっと風量を上げた方がいい気がするけど、しばらく見守ることにする。PWMフィードバック端子など切断しているのになぜかファンステータスがOKになっているのが気になるところ。

## まとめ
- シスコハブは自宅だと超うっさい
- ファンコンは1000円以内で自作できる
- スーパー三端子レギュレーターは高い。1個350円もする。
- ピン余ってるし温度センサーつけたらよかったかも。
コマンド


pwd
 現在いる場所

ls
リスト

cd
ディレクトリ間の移動

cd ..
一つ前のディレクトリへ移動

mkdir
ディレクトリを作成する際に使う

rmdir
ディレクトリを削除する際に使う（空のディレクトリは削除できない）

rm -r （ディレクトリ名）
ディレクトリを削除する際に使う（空のディレクトリであっても削除できる）

mv
ディレクトリを移動させるときに使う

cp 
コピーするときに使う








コマンドは調べれば奥が深くかなりの量があるし、知れば知るほど便利になっていくと思う

man ls

これを打ってみて！w

何か間違いや、参考にしたほうがいいとか、あればコメントお願いします！！




（メモ程度に利用しています）
Unity で 使用するエディタを切り替える

# UnityでScriptとかを確認するエディタを VisualStudioCode にしていたけど、VisualStudio に戻したら、予測変換でるしデバックできるしとても便利でした！

![スクリーンショット 2019-08-24 19.33.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/1b5bd00e-5aa0-bf6b-6a97-82932fdc87a1.png)

---

:baby_tone1:切り替え方:baby_tone1:

[Unity]->[Preferences]->[ExternalTools] の [External Script Editor]のセレクトボックスで、[Visual Studio]に切り替えるだけ

![スクリーンショット 2019-08-24 20.05.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/f138ac1d-5a45-3e4e-73dc-e755b13007db.png)

---

:alien:振り返り:alien:

一々、Unityのマニュアル見に行かなくても使える関数などがずらずら出てきて、使い方まで出てくるのでとっても便利です！

いつも使っている青い方の VisualStudioCode にまとめちゃおう！という安易な考えで、VisualStudioCode に変更して使っていましたが、VisualStudioCode　と　VisualStudio は違うものだと教えてもらいました。(てっきりバージョン違いで色が異なるのかと。。prz)

VisualStudioCodeでも拡張機能入れれば入力補完などできるみたいではありますが、入力補完が弱いらしいので、とりあえずはUnityデフォルトの Visual Studio　で便利に実装して行きたいです！
(cf.[UnityでVisual Studio Codeを使用できるようにするまでの手順](https://qiita.com/riekure/items/c45868f37a187f8e1d69))）


以上！