OmniAICreator/Qiita-1.07M huggingface dataset:
cronでDockerfileをauto buildする

# dockerhubとgithubの連携

[GitHubにpushしたらDockerイメージを自動ビルドする](http://48n.jp/blog/2016/08/03/docker-auto-build-tutorial/) のように設定。

tagにマッチする正規表現

```正規表現
{\1}
/^(v?[0-9.]+)$/
```

# shellscriptの用意とcron設定
下記のshellscriptを用意

```sh:archlinux_build_monthly.cron.sh
#!/bin/sh
#
# Build Dockerfile base/archlinux:{tagname}
# on dockerhub by pushing github

DIR=$(dirname "$0")
TAG="$(date -d '1 month ago' +%Y.%m.01)"

# Checkout
cd ${DIR}
git checkout master

# Modify
sed -i -e "s/latest/${TAG}/" Dockerfile
git commit -am "base version ${TAG}"
git tag ${TAG}
git push origin "${TAG}"

# Return
git reset --hard HEAD~
```

スクリプトの実行権限を与えておきます。

```shell-session:実行権限付与
$ chmod 766 archlinux_build_monthly.cron.sh
```


```crontab
# m h  dom mon dow   command
* * 2 * * bash -c "${HOME}/Dropbox/Program/Dockerfiles/docker_archlinux_env/archlinux_build_monthly.cron.sh"
```

毎月2日に上記のshellスクリプトを実行して、先月のタグでビルドされたベースイメージを元にビルドされる仕組み.


reset --hardで書き換える前のmasterに戻している。
branchの分かれ方が愉快になっている(1~6行目まで)。
masterからすべて枝分かれしていくのかー。
今後のtreeの成長の仕方が楽しみ。

```git-log
* d08cbd1 54 minutes ago base version 2018.04.01  (tag: 2018.04.01)
| * 7720cbe 55 minutes ago base version 2018.05.01  (tag: 2018.05.01)
|/
| * f307201 60 minutes ago base version 2018.06.01  (tag: 2018.06.01)
|/
* 8f7a178 64 minutes ago base version latest  (HEAD -> master)
* 064144e 64 minutes ago base version 2018.07.01  (tag: 2018.07.01)
* 6a61b67 80 minutes ago base version latest
* 8b1a006 80 minutes ago base version 2019.02.01  (tag: 2019.02.01)
| * 2d0046c 2 hours ago [add] cron command  (develop)
* | 99e40ce 2 hours ago base version latest
* | e051ecc 2 hours ago base version 2018.08.01  (tag: 2018.08.01)
* | 47b428c 2 hours ago base version latest
* | 8371f78 2 hours ago base version 2018.09.01  (tag: 2018.09.01)
* | 8796eb6 2 hours ago base version latest
* | bff56d2 2 hours ago base version 2018.10.01  (tag: 2018.10.01)
* | 0f31acb 2 hours ago base version latest
* | 8832df7 2 hours ago base version 2018.11.01  (tag: 2018.11.01)
* | dc117be 3 hours ago base version 2018.12.01  (tag: 2018.12.01)
```


docker hubはこちら
[u1and0/archlinux](http://hub.docker.com/r/u1and0/archlinux)
dockerコンテナ上のH2OでCGIを動かそうとした  on alpine linux

背景
-----------
Docker コンテナ上でPerlを動かし、メモリを節約したかった。
注意: 本記事はパフォーマンスレポートではありません。


構成
----------

次の構成のコンテナを作成する。

- docker
    - alpine-linux
    - H2O
    - fcgiwrapper (via tcp)
    - supervisord


ポイント
----------

- 各種デーモンはrootで起動して、デーモン内でsetuid等を行う(fcgiwrapperを除く)
- fcgiwrapper は unix socket ではなく、tcp 通信を行う
    - 起動時にユーザー(fcgiwrapper)のチェックを行うため、そのままでは起動できない
    - H2Oからソケットを参照するときに同一ユーザーじゃないとエラーとなる
    - fcgiwrapper の起動前にソケットを削除しなくてはならない(この操作はTCPの場合不要)
- 各種ファイル(cgi)は /var/www/html へ配置
- 配置したファイルは必ず所有者をwww-dataとすること

各種コード
----------
- Dockerfile
- entrypoint.sh
- h2o.conf
- supervisord.conf


``` Dockerfile.
FROM alpine:latest

USER root
RUN apk add -U --no-cache \
    fcgi fcgiwrap perl \
    h2o supervisor sudo 

COPY supervisord.conf \
     h2o.conf \
     entrypoint.sh \
     /tmp/
RUN set -ex \
      && adduser -S -H -G www-data -u 82 www-data \
      && mv /tmp/supervisord.conf /tmp/h2o.conf /etc/ \
      && chmod 644 /etc/supervisord.conf /etc/h2o.conf \
      && mv /tmp/entrypoint.sh /etc/ \
      && chmod +x /etc/entrypoint.sh \
      && mkdir -p /var/www/html \
      && chown -R www-data:www-data /var/www/html
# Put entry point to execute
ENTRYPOINT ["/etc/entrypoint.sh"]
EXPOSE 80
# Startup supervisor
CMD ["supervisord", "-c", "/etc/supervisord.conf"]
```

``` entrypoint.sh
#!/bin/sh

exec $@
```


``` h2o.conf
pid-file: /tmp/h2o.pid
access-log: /dev/stdout
error-log: /dev/stderr
user: www-data

file.custom-handler:
  extension: [ .pl, .cgi ]
  fastcgi.connect:
    port: 9000
    type: tcp

compress: on
file.index: [ 'index.html', 'index.htm', 'index.txt', 'index.pl' ]

hosts:
  "local:80":
    listen:
      port: 80
      host: 0.0.0.0
    paths:
      "/":
        file.dir: /var/www/html

```


``` supervisord.conf
[supervisord]
nodaemon=true
loglevel=info
user=root
logfile=/dev/null
logfile_maxbytes=0
pidfile=/tmp/supervisord.pid

[program:fcgiwapper]
command=/usr/bin/fcgiwrap -c 3 -s tcp:127.0.0.1:9000
autorestart=true
user=fcgiwrap
group=www-data
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
priority=100

[program:h2o]
command=/usr/bin/h2o -c /etc/h2o.conf
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
startsecs=3
priority=200

```

参考文献
------------------
- [NginxでCGIを動かそうと頑張った話 - Qiita](https://qiita.com/hmikisato/items/c793ced0ba2695a89de6)
aws-recordでグローバルセカンダリインデックスの登録方法


[aws-record](https://github.com/aws/aws-sdk-ruby-record)いいですよね。

aws-recordでDynamoDBのmigrationを作成する際のグローバルセカンダリインデックスの登録方法がわからなかったので調べてみました。
（これに限らず、aws-recordのコードはコメントやサンプルが豊富で読みやすいです。）



以下のような感じで書きます。

```ruby
class User
  include Aws::Record
  string_attr :name, hash_key: true
  string_attr :keywords, range_key: true
  string_attr :material
  string_attr :recepe
  string_attr :tips
  date_attr :updated_at

  global_secondary_index(
	:gsi_keywords,
	hash_key: :keywords,
	range_key: :name,
	projection: {
	  projection_type: 'ALL'
	}
  )
end

# create db
cfg = Aws::Record::TableConfig.define do |t|
  t.model_class(User)
  t.read_capacity_units(5)
  t.write_capacity_units(2)

  t.global_secondary_index(:gsi_keywords) do |i|
    i.read_capacity_units(5)
    i.write_capacity_units(2)
  end
end

cfg.migrate!
```

この書き方は[lib/aws-record/record/table_config.rb]()に記載されています。


テーブルのメタ情報を表示すると以下のようになります（伏せているところには実際のテーブル名が入ります）
今回は[DynamoDBローカル](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.html) で実行しましたが、実際のDynamoDBでも問題なく動くのではないでしょうか。

![DynamoDB_Admin.jpg](https://qiita-image-store.s3.amazonaws.com/0/8607/18615755-f6f0-8bc9-bddd-f4fb29364cbc.jpeg "DynamoDB_Admin.jpg")



**改めてよく調べたらドキュメントにしっかり載ってましたね** [TableConfig](https://docs.aws.amazon.com/awssdkrubyrecord/api/Aws/Record/TableConfig.html)
EC2にハニーポットのT-pot 18.11をインストール

#1. はじめに
予め準備したUbuntu 18.04のEC2インスタンスに、T-potをセットアップしていきます。
今回は長期運用せず、T-potをインストールして動作していることを確認するまでとします。

#2. インストール前の準備
インストールを行う前に、T-potを使用する上でいくつかの点を考慮しておこうと思います。

##2.1. EC2上でのハニーポット運用は問題ないのか
この点については、以下のブログを参考にさせていただきました。
最新の状況を確認したい方や、慎重派な方は、ご自身でお問い合わせするのが良いでしょう。

ハニーポットの運用が規約違反でないか調べてみた#2
https://blackle0pard.net/wxn7jq/

##2.2. ネットワークとセキュリティグループの設定
万が一に備えて、他の用途に使用するインスタンスが存在しないVPCで、ハニーポットを動作さます。
ハニーポットを設置するサブネットはパブリックサブネットの必要があります。
また、現時点では自身のIPからの22/tcp接続がセキュリティグループで許可されていればOKです。

##2.3. CloudWatchアラームの設定
こちらも万が一に備えて、CPUの使用率が高止まりした場合や、大量のネットワークパケットが発生した場合には、インスタンスを強制的に停止するアラームを作成しました。

#3. T-potインストール
いよいよインストールを行っていきます。
インストール中にこけるのが心配な方は、一度スナップショットを取っておいても良いでしょう。

##3.1. OSのアップデート
いつものおまじない

```
sudo apt-get update
sudo apt-get upgrade -y
```


##3.2. ユーザの作成、デフォルトユーザの無効化
管理用に使用するアカウントを作成します。

```
sudo adduser USER-NAME
sudo gpasswd -a your-user sudo
```
作成したユーザでも、同じ鍵でログインできるようにします。

```
sudo mkdir  /home/USER-NAME/.ssh/
sudo cp /home/ubuntu/.ssh/authorized_keys /home/USER-NAME/.ssh/
cd /home/USER-NAME/
sudo chown USER-NAME:USER-NAME .ssh/authorized_keys
```

他の記事でもおすすめされていたので、デフォルトユーザーを無効化します。

```
sudo passwd -l DEFAULTUSERNAME
```

##3.3. T-potリポジトリのクローン
ここは、本家のサイトのReadmeに記載の「Post-Install Auto」に従っていきます。

T-Pot 18.11
https://github.com/dtag-dev-sec/tpotce


```
git clone https://github.com/dtag-dev-sec/tpotce
cd tpotce/iso/installer/
cp tpot.conf.dist tpot.conf
```
tpot.confには、Web UIアクセス時のユーザ名やパスワードの設定が記述されているため、編集してデフォルトから変更しておきます。

##3.4. インストール実行
準備が整ったら、インストールを実行します。

```
./install.sh --type=auto --conf=tpot.conf
```

##3.5. 再起動
めでたくインストールが完了すると、再起動を促すメッセージが表示されるので、再起動しましょう。
![t-pot-done.JPG](https://qiita-image-store.s3.amazonaws.com/0/254738/8e7cc73c-14ed-1562-cc29-913652541e79.jpeg)


```
sudo reboot now
```

#4. インストール後の設定変更
インストールが完了すると、管理用のSSHポートが64295/tcpに変更になります。
また、Web UIが64297/tcpで閲覧できるため、ここにもアクセスできるようにします。
よって、セキュリティグループの設定を以下のように変更します。
ここでも、ソースは自身のIPのみとするのが良いでしょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/254738/db7f0eea-6aed-3a2c-d716-b729ea64cbe0.png)


#5. コンソールへのSSHアクセス
変更したポート番号64295/tcpを用いて、SSHアクセスを試みます。
ちなみに、Elastic IPを割り当てていない場合は、再起動後にインスタンスのパブリックDNSやIPが変更になっていますのでご注意を。


#6. Web UIへのアクセス
Web UIへもアクセスできるようになったので、以下のURLでブラウザからアクセスしてみます。

https://[YOUR-PUBLIC-DNS]:64297

![tpot-console.JPG](https://qiita-image-store.s3.amazonaws.com/0/254738/97b54f25-08a5-93df-0974-528e6c43fb96.jpeg)

#7. セキュリティグループの変更
ここまでで、もう観測用のハニーポットのコンテナは実行中の状態です。
準備が整ったので、いよいよ攻撃が観測できるようにセキュリティグループでポートの開放を行います。

なお、今回は第三者に影響を与えないように注意するため、セキュリティグループのアウトバウンドのルールをすべて削除し、ハニーポットから開始されるアウトバウンドパケットはすべて拒否する設定にしました。（これのせいもあって、観測できたパケットは限定的となりました。。。）
セキュリティグループはステートフルであるため、この場合でも通常のWEB UIへの接続などは問題なく行えます。

あとは、観測を勧めていくのみです。

#9. おわりに
これでT-potをインストールすることができました。
セキュリティグループの設定と、インストール用のコマンド打ったぐらいでしたので、意外とあっさりできたなという印象です。
今回は試験的に短時間動作させたため、不審なファイルのアップロードなどはありませんでしたが、それでも複数種類の攻撃が観測できたのは興味深かったです。

#10. 参考サイト

EC2上にHoneypot(T-Pot)をインストールして、サイバー攻撃をELKで可視化してみた
https://qiita.com/tarosaiba/items/871ab0c155578f8a38fe

ハニーポット詰め合わせT-potをAmazon EC2上で10日間運用してかかった費用の話
http://onthesoup.hatenablog.com/entry/2017/05/31/234438

ハニーポットをT-Pot 17.10で構築してみた。
https://qiita.com/k-onishi/items/2d04ec4ea86a09d136ea
Flutterのビルドエラー FATAL EXCEPTION: TokenRefresherの解決方法

#解決方法
app/build.gradleのdependenciesの中に1番下の1行を追加。

```dart:app/build.gradle
 dependencies {
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    // firebase使用のため追加
    implementation 'com.google.firebase:firebase-core:16.0.1'

    implementation 'com.android.support:multidex:1.0.3'


    //ビルドエラー修正。ここを新しく追加した。
    implementation 'com.google.firebase:firebase-auth:16.0.4'

}

```

#原因
flutterのプラグインがAndroidの古いバージョンを使っているからっぽい。

#解決までの道のり
初めは、implementation 'com.google.firebase:firebase-auth:16.0.4'を入れるとログイン機能が使えなくなったり今まで表示されていた画像が表示されなくなったり不具合が起きました。
なので別の解決策として新しいエミュレーターを使ってみるとビルドエラーが治りました！！しかし、3時間後にまたビルドしてみると同じビルドエラーが。。
その後、implementation 'com.google.firebase:firebase-auth:16.0.4'を入れてみるとビルドエラーが治りました。なんでだよ。。

#参考
[Flutter Error: java.lang.NoSuchFieldError PREFER_HIGHEST_OR_REMOTE_VERSION_NO_FORCE_STAGING
](https://stackoverflow.com/questions/52730515/flutter-error-java-lang-nosuchfielderror-prefer-highest-or-remote-version-no-fo)

これのおかげで解決。ありがとうございます。
SPAのOGPタグ問題に対するRailsで出来る対策(Twitter、Facebookなどに対応)

React, Angular, VueなどでSPAでWebアプリを構築している場合、個別ページにOGPタグが設定出来ずに困ることがあるかと思います。

Googleのクローラーは正しくJSを実行してDOMを描画しますが、TwitterやFacebookのそれは完全ではありません。

この問題に対するRailsで出来る解決策として、ユーザーエージェントを見て、TwitterやFacebookのクローラーからのアクセスには専用のコントローラーを対応させるという方法があります。

## SPAのOGPタグ問題に対するRailsで出来る対策
実際に[ネコチャ](https://twitter.com/search?f=tweets&q=yurubo.me&src=typd)で使用している、Twitterクローラーに対応したコードが下のようになります。

```ruby:routes.rb
Rails.application.routes.draw do
  constraints :user_agent => /Twitterbot/ do
    # ここにTwitterクローラー専用のルーティングを記入
    # 例えば
    get '/:id', to: 'api/v1/users#bot' 
  end
```
```ruby:routes.rb
module Api
  module V1
    class UsersController < ApplicationController
      # ...
      def bot
        @user = User.find_by_uid(params[:id])
        render :inline => '<!doctype html>
<html lang="en-US">
<head>
  <title>ネコチャ</title>
  <meta charset="UTF-8"/>
  <meta name="twitter:card" content="summary_large_image">
  <meta name="og:title" content="<%= @user.name%>にあいさつしよう とくめいチャット|ネコチャ">
  <meta name="og:description" content="送る側だけとくめいのチャット ネコチャ">
  <meta name="og:image" content="https://firebasestorage.googleapis.com/v0/b/payeth-d6881.appspot.com/o/Screen%20Shot%202019-01-22%20at%200.05.42.png?alt=media&token=9d45f97d-15fa-4582-a41c-928d5212c52f">
</head>
<body>
</body>
</html>'
      end
    end
  end
end

```
[結果はご覧の通りです。(タイトルがユーザーごとに違います)](https://twitter.com/search?f=tweets&q=yurubo.me&src=typd)
質問箱などOGPを活用したアプリケーションにぜひご活用下さい。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
Swiftのループ文で大域脱出

#Swiftで簡単に大域脱出をしたい
for文やwhile文、他にもcase文やSwitch文等を使って下のようにループ文の中でループ文を回すことがあると思います。

``` swift
let my_array:[[Int]] = [[1,2,3],[4,5,6],[7,8,9]]

// 配列の配列に数字の5が含まれているか確認したい
func include_five(array_of_arrays:[[Int]]) -> Bool {
    var include_five:Bool = false
    var break_loop:Bool   = false

    for array in array_of_arrays {
        for number in array{
            if number == 5 {
                // 5が含まれていたらbreakで抜ける
                break_loop   = true
                include_five = true
                break
            }
        }
        if break_loop {
            break
        }
    }
    return include_five
}

print(include_five(array_of_arrays: my_array))
```
#ラベル付きループ文で簡単に外側のループを抜ける
もちろん、上のように記述することも可能ですが、ラベルをループ文につけることで簡単に外側のループまで抜けることができるようになります。

```swift
let my_array:[[Int]] = [[1,2,3],[4,5,6],[7,8,9]]

// 配列の配列に数字の5が含まれているか確認したい
var break_loop:Bool   = false

func include_five(array_of_arrays:[[Int]]) -> Bool {
    var include_five:Bool = false
    outer_loop: for array in array_of_arrays {
        inner_loop: for number in array{
            print(number)
            if number == 5 {
                // 一気に外側のループを抜けられる
                include_five = true
                break outer_loop
            }
        }
    }
    return include_five
}

print(include_five(array_of_arrays: my_array))
// 1
// 2
// 3
// 4
// 5
// true
```
ラベルをつけることでfor文以外にもwhile文, case文, switch文, if文など様々なネスト構造のプログラムから指定したラベルの文まで抜けることが可能になります。もちろん、関数で定義している場合などはreturnすることで処理を少なくできますが、そうでない場合には今回紹介したラベル付き文を活用するとコードの可読性を上げたり、少しでも効率のよいコードを目指したりできそうです。
【初心者/Tips】JSONをPythonに読込（郵便番号を検索して住所を読込）

#概要：
- PythonではJSONファイルを実質一行で読込可能

>> pandas.read_json()関数を使うと、JSON形式の文字列（str型）やファイルをpandas.DataFrameとして読み込むことができる  
[引用元:](https://note.nkmk.me/python-pandas-read-json/)


#郵便番号検索API
>>郵便番号検索APIは、日本郵便が公開している郵便番号データを検索する機能をRESTで提供
[引用元:](http://zipcloud.ibsnet.co.jp/doc/api)

（例）郵便番号「7830060」で検索する場合
http://zipcloud.ibsnet.co.jp/api/search?zipcode=7830060 


#組み合わせると…　⇒　Python上で郵便番号を検索して住所を読込
[Google colaboratory 上で試してみる](https://colab.research.google.com/gist/zaq9/e9dac61af5ced8ccf2b906f71a5a76c2/pos_code.ipynb)

```py

# 郵便番号検索
import pandas as pd
json_url = 'http://zipcloud.ibsnet.co.jp/api/search?zipcode=1500001'
df = pd.read_json(json_url)
df.results[0]
```
##output:
```
{'address1': '東京都',
 'address2': '渋谷区',
 'address3': '神宮前',
 'kana1': 'ﾄｳｷｮｳﾄ',
 'kana2': 'ｼﾌﾞﾔｸ',
 'kana3': 'ｼﾞﾝｸﾞｳﾏｴ',
 'prefcode': '13',
 'zipcode': '1500001'}

```
TrampolineのLチカサンプルを動かすまで

## 背景
Arduino UnoでTrampolineを動かそうと思ったときに、ちょっとだけ苦労したのでメモ。
参考にさせていただいたのは[こちらの記事](https://qiita.com/mt08/items/65f2ac9bbdae09a34470)です。

## 環境
- ホスト：Windows10 64bit
- ターゲット：Arduino Uno
- Arduino 1.8.8(Windows Store 1.8.19.0)

## 準備
#### 1. gitでTrampolineを取得

```:cmd
> git clone https://github.com/TrampolineRTOS/trampoline
```

`machine/avr/arduino`が落ちないと思うので、別で落としてくる。
[公式](https://github.com/TrampolineRTOS/trampoline/tree/master/examples/avr)のやり方に沿うと、Trampolineを入れたパスで

```:cmd
> git submodule init
> git submodule update machines/avr/arduino
```

らしいのだけど、ぼくは読まずに

```:cmd
> git clone https://github.com/TrampolineRTOS/ArduinoCore-avr/tree/a6ba7fd9e06ba7e986c1c6caab62d017f727030d
```

で落としてtrampoline/machine/avrに置いちゃいました。

#### 2. goilを取得
先の公式のページ下の方に`goil-windows.zip`があるのでダウンロードして解凍する。

#### 3. パスの追加
解凍した`goil-windows`ディレクトリおよび、
クロスコンパイルのため Arduinoの`avr-gcc`があるディレクトリをパスに追加。
後者は、Windows StoreでArduino IDEインストールしている場合は
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.19.0_x86__xxxxxxxxxxxxx\hardware\tools\avr\bin
みたいな感じの場所。
コンフィグファイルはetc。
`make`も必要なので、Cygwinでやるか、cmdでCygwinのmakeバイナリのある場所のパスも追加する。

```:cmd
> set PATH=%PATH%;C:\<hogehoge>\goil-windows;
> set PATH=%PATH%;C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.19.0_x86__xxxxxxxxxxxxx\hardware\tools\avr\bin;
> set PATH=%PATH%;C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.19.0_x86__xxxxxxxxxxxxx\hardware\tools\avr\etc;
> set PATH=%PATH%;C:\<hogehoge>\cygwin64\bin;
```

見やすいように分けて書いてるけど、もちろん一行にまとめてセットしてもOK。
## ビルド
##### 1. blinkの`runGoil.bat`と`make.py`を実行

```:cmd
> cd <hogehoge>\trampoline\examples\avr\arduinoUno\blink
> runGoil.bat
> python make.py
```

#### 2. avrdudeで`trampuinoBlink.hex`をArduinoに書き込み
すでにパスが通ってるので`avrdude`が実行できるはず。

```:cmd
> avrdude -c arduino -P COM5 -p m328p -b 115200 -u -e -U flash:w:"trampuinoBlink.hex":a
```
COMの番号はArduinoを接続しているポートを設定のこと。
わからなかったらArduino IDEを参照。

#### 3. Lチカしたら成功
周期的に、Arduino UnoのLEDが点滅していたらOK。

#### 更新履歴
[2019.02.10] 
- make -> python make.pyに修正
- avrdudeコンフィグパスの追加が抜けていたため追加
【質問】Oracleの正規表現について

質問です。

Oracleで正規表現を利用してレコードを絞り込む方法についてです。

データベースに人名が登録されているのですが、その中で以下の種類以外の文字が入っているレコードを抽出しようとしています。
・全角数字
・アルファベット(全角大文字)
・全角カタカナ
・全角丸括弧
・全角スラッシュ
・全角スペース

そこで、以下のようなクエリを書いたのですが、全角カタカナ＋全角スペースしか入っていないレコードが取れてしまいます。

select
    *
from
    tableA a
where
    REGEXP_LIKE(a.columnA ,'^[0-9A-Z¥ア￥イ￥ウ・・・(中略)・・・￥ワ￥ン￥（￥）￥／￥s　]')

どこが間違っているか、どう直せば良いか分かったら教えていただきたいです。

初歩的な質問で恐縮ですが、よろしくお願いします。
chmodがすぐに理解できる表

## すぐに理解できる表と使い方

|　  |自分  |グループ  |その他  |
|---|---|---|---| 
|Read(読み)  | 4点 |4点  |4点   |
|Write(書き)  |2点  |2点  |2点   |
|Execute(実行)   |1点   |1点   |1点   |

- この表の縦の合計を第1引数にする

## 例

- `file.txt`に、自分は全ての権限、それ以外は読み取りのみの権限を与えたい

```
$ chmod 744 file.txt
```

- 自分：$7 = 4 + 2 + 1$
- グループ：$4 = 4 + 0 + 0$
- その他：$4 = 4 + 0 + 0$
UM3485オルゴールICを鳴らす

UM3485オルゴールICを鳴らしました。
ここでは回路図・オルゴールICの音声を記録します。
# 事前準備
・５曲電子オルゴールＩＣ（メロディオルゴール）UM3485
http://akizukidenshi.com/catalog/g/gI-03135/

・スピーカ
１００均スピーカでも良いですが、下記スピーカを使用しています。
スピーカー EAS65P118D
https://www.amazon.co.jp/gp/product/B0765RC9MD/ref=ppx_yo_dt_b_asin_title_o04__o00_s00?ie=UTF8&psc=1


・トランジスタ　１個
2SC1815-GR
https://www.amazon.co.jp/シリコントランジスター-2SC1815-GR-10個/dp/B00DTHJM32

・抵抗100Ω ２個
・コンデンサ　10μF １個
・ジャンパーワイヤ  12本程（必要に応じて）
・ワニ口クリップ　2本程（必要に応じて）

# UM3485オルゴールICについて
５曲入の電子オルゴールＩＣです。収録曲
・ハワイの結婚の歌
・Ｔｒｙ　Ｔｏ　Ｒｅｍｅｍｂｅｒ
・Ａｌｏｈａ　ＯＥ （アロハオエ）
・Ｌｏｖｅ　Ｓｔｏｒｙ
・Ｙｅｓｔｅｒｄａｙ
![001.png](https://qiita-image-store.s3.amazonaws.com/0/344880/b3244b67-ddf4-5e58-a774-59fe0a8a78da.png)

# 回路図
回路は下記の通り作成します
（PIN4は曲選択用にスイッチを加えたいところですが、とりあえず動かすためにジャンパワイヤを直接さしました。）
![004.JPG](https://qiita-image-store.s3.amazonaws.com/0/344880/25667746-7fcd-4a84-bb24-34a04dc32b5a.jpeg)
トランジスタについて
ベース(B)、コレクタ(C)、エミッタ(E)の配線を間違えないように注意しましょう
![008.png](https://qiita-image-store.s3.amazonaws.com/0/344880/68a3c6a5-44ea-cfc5-92d0-389fe44baeca.png)
実際に接続した写真は下記です。
![006.JPG](https://qiita-image-store.s3.amazonaws.com/0/344880/67bc3cc0-2898-81fb-20b7-449113cdebb8.jpeg)

5VはUSB電源ラインから取得します。
もしくはArduino等経由で5V供給してもいいかもしれません。

# テスト
音を鳴らすことができました。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">メロディオルゴールIC um3485 を使って遊んだ <a href="https://t.co/wnUXoiUe3Q">pic.twitter.com/wnUXoiUe3Q</a></p>&mdash; st (@st17890027) <a href="https://twitter.com/st17890027/status/1091861605912956928?ref_src=twsrc%5Etfw">2019年2月3日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

# 感想
もう少し本物のオルゴールらしい音がなると思っていましたが電子音よりの音が鳴りました。
[UiPath]変則的な要素の出現に対処する方法

システム操作の自動化をUiPathで行なっている時にエラーや確認メッセージなどが出てくることがあります。毎回出てくるのであれば一連のフローの中にメッセージの処理を組み込めばいいですが、出てくる場合とそうでない場合がある時にはメッセージが有無を識別することでその後の動作を分岐させることでエラーが生じなくなります。

##要素の有無を検出（Element Exists）アクティビティを使う
要素の有無を検出アクティビティではセレクターで指定した要素があるかどうかを判別し、選択した要素があればTrue、なければFalseを返り値として返します。
この返り値はプロパティの要素の有無に設定したBoolean型の変数に返ります。

##条件分岐アクティビティでTrue/Falseのフローを分ける
条件分岐アクティビティを使って設定したBoolean型の変数（Exists）がTrueかどうかを条件式に設定し、その後のフローを分岐させます。

例えばメッセージがある場合にはウィンドウを閉じる等のアクションを入れることで、変則的にメッセージが発生する場合にUI要素が認識できずにエラーになってします自体を防ぐことができます。

##使用例
商品を登録しようとした際に商品の価格が承認されていない場合に下の画像のようなメッセージが表示されると仮定します。（このメッセージはUipathの別のプロジェクトでメッセージボックスアクティビティを使って表示させています）
例えばこの後の商品登録の一連のシステム設定をプロジェクトで組んでいたとしても、価格承認がされていないことでこの後の設定に進めなければUIを認識できずに、タイムアウトでエラーになってしまいます。
<img width="210" alt="スクリーンショット 2019-02-04 23.01.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/347151/882701f9-17be-5fd8-9956-6c9eaa54ac08.png">

そこでこのメッセージが出て来た場合をそうでない場合で動作を分けるために、`要素の有無を検出（Element Exists）アクティビティ`と`条件分岐アクティビティ`を使用していきます。
まず要素の有無を検出ではターゲットとしてウィンドウ内のテキストをセレクターとして指定します。また、出力変数にはBoolean型のExistを設定します。

<img width="528" alt="スクリーンショット 2019-02-04 22.56.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/347151/303bc0cd-495a-276d-1432-a18f82124b11.png">

<img width="269" alt="スクリーンショット 2019-02-04 22.55.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/347151/16956b91-54e0-88eb-e434-942e56b5e6d8.png">

メッセージが表示された場合には変数ExistにTrueが、ない場合にはFalseが返るため、下記のような条件式を設定し、その後の動作を分けてあげることでメッセージが表示された際にもエラーが生じなくなります。

<img width="516" alt="スクリーンショット 2019-02-04 22.54.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/347151/52c56772-64ec-d295-dd22-55d302ccacac.png">


以上、要素の有無を検出アクティビティと条件分岐アクティビティを組み合わせて変則的なメッセージの表示に対応する方法でした。
Chainer 5.2.0 インストール方法

# 前置き
* Chainer…東大発日本ベンチャー企業 Preferred Networks が開発するオープンソースのディープラーニング フレームワーク。
* cupy…Python の標準数値計算ライブラリ numpy の GPU 移植版。
* CUDA Toolkit…NVIDIA 製の GPU で GPGPU をするのに必要なライブラリ。
* cuDNN…CUDA を用いてディープラーニングをする際に必要なライブラリ。
* Anaconda…科学計算に必要なパッケージ一式が入った python 環境。
* conda…python のパッケージ管理システム + 環境分離システム。
* pip…conda より昔からあるパッケージ管理システム。

# Chainer 5.2.0 インストール
2019年2月1日時点で、 chainer の最新のバージョンである 5.2.0 及び GPU で実行するための cupy 5.2.0 をクリーンインストールする手順をメモしておきます。
chainer 5.2.0 は以下の外部ソフトウェアに依存しています。 (バージョンは一例、できるだけ現時点で最新のもの)

* CUDA Toolkit 10.0 (最新)
* cuDNN 7.4.2 (最新)
* Python 3.7.2 (最新)

## インストール手順
1. Anaconda のインストール
[Anaconda 公式サイト](https://www.anaconda.com/distribution/#download-section)から自分のOSにあったインストーラーをダウンロードして実行する。
    * システム全体にインストールするか、ユーザーごとにインストールするかはどちらでもよい。

### conda でインストールする場合
conda でインストールする場合は、 CUDA Toolkit 及び cuDNN をすでにシステムにインストールしていたとしても、 依存パッケージとして CUDA Toolkit と cuDNN がもれなくついてくるので、システムに CUDA Toolkit, cuDNN をインストールしておく必要はない。 (インストールしていたとしても conda でインストールしたものが優先されるので問題はない。)

ターミナルで以下を実行する。
`conda install cupy chainer`

* 依存パッケージでついてくる CUDA Toolkit と cudnn は少し古いバージョンになる。(CUDA Toolkit 9.2.0, cuDNN 7.3.1)

chainer は pip と conda のいずれかのパッケージマネージャでインストールできる。

### pip でインストールする場合
pip でインストールする場合は、手動で CUDA Toolkit と cuDNN をインストールする必要がある。

1. CUDA Toolkit のインストール
[NVIDIA CUDA Toolkit 公式サイト](
https://developer.nvidia.com/cuda-downloads) から OS にあったインストーラーをダウンロードして実行。
    * Windows の場合は exe 形式のインストーラ。
    * Linux の場合は run 形式のシェルスクリプト。
    * インストール後、以下を確認してください。
        * 環境変数 CUDA_PATH に CUDA Toolkit をインストールしたディレクトリが指定されていること。
        * 環境変数 PATH に (CUDA Toolkit をインストールしたディレクトリ)/bin が指定されていること。またターミナルで `nvcc` コマンドが実行できること。

2. cuDNN のインストール
インストールと銘打ってあるが、 CUDA Toolkit をインストールしたフォルダにいくつかのファイルをコピーするだけ。
[NVIDIA cuDNN 公式サイト](https://developer.nvidia.com/rdp/cudnn-download) から OS にあったもの (cuDNN Library for XXX) をダウンロードして、含まれる以下の CUDA Toolkit をインストールしたディレクトリ内の対応するディレクトリにコピーする。 cuDNN は CUDA Toolkit のバージョンに対応するバージョンをインストールする必要がある。
    * include/cudnn.h
    * lib64/libcudnn.so*
    * lib64/libcudnn_static.a

3. cupy と chainer のインストール
`pip install cupy chainer`
    * cupy をインストールするとき、ソースコードからビルドが行われ、インストールされている CUDA Toolkit と cuDNN 用の cupy がインストールされる。そのため、 CUDA Toolkit や cuDNN をアップグレードした場合は、 cupy を再インストールする必要がある。
    * cupy をインストールするときに、上記の CUDA Toolkit あるいは cuDNN のインストールが正しく行われていない場合、エラーが発生する

## 備考: conda と pip のどちらでインストールすべきか
* conda
    * CUDA Toolkit, cuDNN がついてくるので、別途インストールしなくてもいいため、より簡単。
    * CUDA 絡みのエラーが出にくい(気がする)
* pip
    * 公式サポート。
    * 最新バージョンが提供されている。 (執筆時点で pip は chainer 5.2.0, conda は 5.1.0 が最新)
    * 最新の CUDA Toolkit, cuDNN を使えるためパフォーマンスが良い(正直違いは分からない)

個人的な意見ですが、 pip で試みて問題が発生したら conda でインストールするのが良いかと思われます。
conda でインストールする際は仮想環境を作れば失敗しても簡単にリカバリーできます。
AcitiveRecordで特定のバリデーションのエラーが発生しているかどうか判定する

## 概要
ActiveRecordを継承したモデルでバリデーションエラーを発生させた際に、特定のバリデーションに反応したのか判定する

どういうときに使うかと言うと、具体的な例を挙げると、valid?とかsave際にある属性の空文字チェックでエラーになっているかどうかというようなことを調べる


### 前提条件

Rails: 5.2
Ruby: 2.5.1

# 本題
サンプルのユーザテーブルの定義


```
create_table :users do |t|
  t.string :name
  t.timestamps
end
```

ユーザモデルの定義

nameの空文字チェックのバリエーションがある

```
class User < ApplicationRecord
  validates :name, presence: true
end
```

まずはインスタンス化してバリデーションチェック

```
> u =　User.new
=> #<User id: nil, name: nil, created_at: nil, updated_at: nil>
> u.valid?
=> false
```

エラーを確認すると、デフォルトの空文字のエラーメッセージが表示されるのがわかる

```
> u.errors.full_messages
=> ["Name can't be blank"]
```

[added？](https://api.rubyonrails.org/classes/ActiveModel/Errors.html#method-i-added-3F)メソッドを使うと特定の属性のどのバリデーションエラーが起こったかどうか調べることができる(本投稿のコメント欄より)

```
# 引数には属性名のシンボルとバリデーションエラーの種類を指定してあげる
> u.errors.added?(:name, :blank)
=> true


# 2つ目の引数を指定しないとデフォルト値が 2つ目の引数は:invalidなので注意が必要
> u.errors.added?(:name)
=> false
```


## [おまけ]バリデーションエラーの詳細を取得する
エラーの一覧が欲しい場合は、errors.detailsを実行すると、どの要素のどのバリデーションのエラー内容　:blankがあることがわかる

```
> u.errors.details
=> {:name=>[{:error=>:blank}]}

# シンボルを指定してあげるとオブジェクトの配列を返す
u.errors.details[:name]
=> [{:error=>:blank}]

# 適当なシンボルを入れると空の配列を返す
> u.errors.details[:name_xxxx]
=> []
```

このようにdetailsからシンボルを指定してその返す配列の中に特定のシンボル:blankの存在をチェックすれば
added?のように特定のバリデーションに反応したのかどうか判定することもできる

```
> u.errors.details[:name].any? { |d| d[:error] == :blank }
=> true
```
いったい僕らはどこまで学べばいいのだろうか

※2024/03/06　この記事はこちらに移動しました。
[いったい僕らはどこまで学べばいいのだろうか](https://qiita.com/moonWalf/items/2f12aa2028fc10b84240)


# いったい僕らはどこまで学べばいいのだろうか

転職して、新しい技術を学んでいる。
今まではオープンソースの世界だったけど、
今回は本当にクローズドの世界になった。
例えば Ruby や Python は、自宅で勉強できるけど、
自宅では勉強できない言語をいじっている。
Docker も使えないし、Jenkins でビルドもできない。
世界はホント、広い。
...Mac が恋しい...。

そこでふと考えていたのが、
なんというか、エンジニアっていうのは
何をどこまで学べば良いのだろうか、ということ。
ドンドン新しい技術が生まれてくるし、
かと言って古い技術も使われなくなるわけではないし。

いったい技術の世界はどれだけ広いのか?
思いつく限りの範囲で、書いてみる。

## プログラミング言語

これはもう、信じられないほどの数があるんだと思う。
そのうち、知っているものを並べてみる。

- C
- C++
- BASIC
- FORTRAN
- Java
- JavaScript
- VisualBasic
- C#
- F#
- D
- Go
- Ruby
- Python
- Swift
- kotlin
- COBOL
- Objective-C
- PHP
- Perl
- Haskell
- Smalltalk
- Lisp
- R
- VBScript
- PowerShell

思いつくだけでも 25 言語くらいはある。
プログラミング言語って、2 つくらいやれば
他の言語の習得も容易になるけど、
深いところまで探ろうとすると
ひとつの言語で手一杯になる。
どこまで学べばいいんだ？

## フレームワーク

言語を生で使うよりも、
フレームワークを駆使刷るほうが多いよね。

- Ruby on Rails
- Django
- flask
- .NET
- .NETCore
- ASP.NET
- WordPress
- Vue.js
- React
- Angular
- Java EE
- PlayFramework
- JQuery

JavaScript はフレームワーク天国。
いや、地獄かもしれない。

## 細々としつつも深い知識

メイン技術ではないけど、
知っておいたほうが良いもの。

- 正規表現
- コマンドプロンプト
- Shell スクリプト
- OS の仕組み
- SSH 接続

## OS

実際に使うのは 2-3 種類だけど、
世の中は広いのだ。

- Windows 関連
- Mac
- Linux
- Unix
- AS400

AS400 は IBM のメインフレームで動いてる。
マニアックだけど 30 年前に書いたプログラムが
最新のバージョンでもほぼそのまま動くので、
金融や製造では根強い人気があるとか。

## ネットワーク

ネットワークの仕組み、理解してる?

- TCP/IP
- UDP
- SSL 証明書
- TLS
- WAN
- LAN
- 公開鍵暗号方式
- DNS
- DMZ
- ルーティング

## ハードウェア

これがないとプログラミングできない。

- マザーボード
- CPU
- GPU
- メモリ
- SSD

マザーボード...。

## 暗号技術

暗号を制するものは、世界を制する。

- ハッシュ
- ブロックチェーン
- ワンタイムキー

## その他

- ビジネス
- プロジェクトマネジメント
- 基礎的なデザイン
- aws や azure などのサービス
- VisualStudio とか Vim とかツールの使い方
- DevOpes とか関数型プログラミングとかの思想やポリシー

いやもう書くのにも疲れてきた。

## で、結局なにをどこまで学べばいいのか?

好きなだけ学べば良いんだと思う。
学びたくなければ、学ばなくてもいいし。
学ぶというより、知る、遊ぶ、のほうが適切かもしれないけど。

とはいえ、軸は、たぶん、ふたつ。

- 好きなことを、好きなだけ学ぶ
- 必要な知識を、必要なだけ、学ぶ

「やりたいこと」「必要なこと 」があるなら、
それを実現するために必要なことを学べばいい。

プログラミングそのものが好きなら、
好きなことを好きなだけ、学べばいい。

「どこまで」っていうのは、無いんだな。
Gitブランチ名をターミナルに表示する

##初めに
Cloud９上で表示されていた仕様を私用のmacでも実現したいと思ったのがキッカケです。

##必要なファイルの確認

```
$　mdfind git-completion.bash
/usr/local/git/contrib/completion/git-completion.bash

$　mdfind git-prompt.sh
/usr/local/git/contrib/completion/git-prompt.sh
```

このように.bashファイルと.shファイルが存在していれば大丈夫です。

以下のように設定しましょう。

```
$ vi ~/.bashrc

//インサートコマンド：i
source /usr/local/etc/bash_completion.d/git-prompt.sh
source /usr/local/etc/bash_completion.d/git-completion.bash
GIT_PS1_SHOWDIRTYSTATE=true
export PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\n\$ '

//保存して閉じる：:wq
//保存しないで閉じるには：q、強制終了：q!
```

~/.bashrcを読み込む設定をしていない場合は下記の記述で読み込みの設定をする

```
$ vi ~/.bash_profile

source ~/.bashrc
```

ここまで記述したら、ターミナルを再起動しましょう。

##最後に
カスタマイズやどのような指定をしているのかを詳しく知りたい方はこの[qiita記事](https://qiita.com/caad1229/items/6d71d84933c8a87af0c4)をどうぞ
私はとても参考にさせて頂きました。
Azure PipelinesへtagをpushしてBuildとReleaseさせたい

今回はAzure Pipelinesで以下のようにするのがゴールです。

- `v1.0.0` といった`v`で始まるタグがpushされたとき、ビルドとリリースを行う
- `master`ブランチがpushされたとき、ビルドのみ行う
- 他のブランチはpushされても何もしない

やっていきましょう。

### Build

see: https://docs.microsoft.com/ja-jp/azure/devops/pipelines/build/triggers

Pipelinesでは「Build」を行う必要があります。その際に何をトリガーにするかを設定する事が出来ます。

`v1.0.0`等のvで始まるタグとmasterブランチの変更でトリガさせる場合のyamlファイルの設定例です。

``` azure-pipelines.yml
trigger:
  branches:
    include:
    - refs/tags/v*
    - master
```

なお、[pull requestについてはこの辺りに書かれています](https://docs.microsoft.com/ja-jp/azure/devops/pipelines/build/triggers#pull-request-validation)が、今回は触れません。（よくわからない）


### Release

次にビルドで作成した成果物をどのようにリリースするかをReleaseで定義していきます。こっちは画面上で作る必要があります。。。

なお、Stagesは今回は関係ないので触れません。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/52527/70d90c81-c67e-83ed-4561-f525d6fe99ea.png)

まずはArtifactsを決めます。

Default Versionを`Latest`にしておきます。これでビルドが行われるたびに出来上がる成果物をトリガーに動くようになります。
（それ以外はよくわかっていない。PipelinesのBuildに対してもgitのタグではない別のタグがつけれるようなので、それに関するフィルター条件だと思われる。）

しかし、これだけだとmasterブランチのビルドにも反応してしまうので、次の設定でタグが付いたもののみを行うようにします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/52527/856b08f5-2352-17e2-e75b-b9cea2a2cad6.png)

Artifactsのトリガー(?)の設定です。雷のマークを押してメニューを出します。

- 「Continuous deployment trigger」を有効化にする
- 「Continuous deployment trigger」のBuild branch filtersのBuild Branchのところを`refs/tags/v*`としておく

これで`vで始まるタグ`についてBuildがうまくいったときだけReleaseの処理を行うようになります。
masterブランチはBuildは行われるがReleaseは行われず、他のブランチ・タグは何も起きないようになります。


以上です。


### おまけ：ビルドに関する情報を埋め込む

もし成果物にビルド番号を埋め込みたい場合、以下の環境変数があるので使えるかもしれない。

see: https://docs.microsoft.com/ja-jp/azure/devops/pipelines/build/variables

|環境変数| 意味 | 例 |
|----|----|----|
|`BUILD_SOURCEBRANCHNAME`|ブランチ名/タグ名| `master`, `v1.0.0`|
|`BUILD_SOURCEBRANCH`|ブランチ名/タグ名| `refs/tags/v1.0.0`|
|`BUILD_SOURCEVERSION`|コミットID| `b995561c1e...`|
|`BUILD_BUILDNUMBER`|ビルド番号(日付.連番)| `20190201.7` |
|`BUILD_BUILDID`| ビルド番号(シーケンス)|`30`|
|`SYSTEM_PIPELINESTARTTIME`| ビルド開始日時 | `2019-02-01 14:26:56+00:00` |

後はBuild時にこの環境変数を使ってファイルに書き出すような事を行う。

以下は雑だけどHostedなubuntuイメージに入っている`envsubst`を使うやり方です。

まず置き換えもとになるファイルを用意します。今回はPythonで定数を並べたファイルを作る事にします。
`envsubst`で環境変数の値に置き換えたい箇所を`$環境変数名`（例:`$BUILD_BUILDNUMBER`）というように書いていきます。

``` buildinfo.py
# Don't touch me!!
BUILDNUMBER="$BUILD_BUILDNUMBER"
SOURCEVERSION="$BUILD_SOURCEVERSION"
SYSTEM_PIPELINESTARTTIME="$SYSTEM_PIPELINESTARTTIME"
```

後は以下のようなビルドのタスクを書きます。
一時ファイルで書き出して、envsubstで置き換えたファイルで上書きして、一時ファイルを削除する、という事をやってます。

ファイルパスとかファイル名はいい感じに調整します。

``` yaml
- script: cp buildinfo.py buildinfo.py.temp && envsubst < buildinfo.py.temp > buildinfo.py && rm buildinfo.py.temp
  displayName: 'Write buildinfo.py'
```

すると、以下のようなファイルで書きだされます。


``` buildinfo.py
# Don't touch me!!
BUILDNUMBER="20190201.7"
SOURCEVERSION="b995561c1e..."
SYSTEM_PIPELINESTARTTIME="2019-02-01 14:26:56+00:00"
```

あとはメインのコードでこんな感じで使います。

``` py
import buildinfo
buildinfo.BUILDNUMBER # "20190201.7"
```

ローカルで開発中は 置き換え前の文字 `$BUILD_BUILDNUMBER` と出てしまうのでちょっと残念。良いやり方があれば是非…
PuTTYでAmazonLinux2を操作する

#PuTTYのダウンロード
以下のサイトからPuTTYをダウンロードします。
（こちらはインストール不要なポータブル版です。）
https://portableapps.com/apps/internet/putty_portable
![01.png](https://qiita-image-store.s3.amazonaws.com/0/353060/a6a18e5c-0f48-8b2b-bc35-99272e33a55b.png)

#キーペアの変換
Amazonから発行されたキーペアはそのままではPuTTYで使えないので、
PuTTYの付属ソフトPuTTYGENを使ってキーペアをpem形式からppk形式へ変換します。
![02.png](https://qiita-image-store.s3.amazonaws.com/0/353060/25d59bdf-02f4-b544-b2c8-3baff144bd68.png)
[Load]をクリックしてインスタンス作成時に発行したキーペアを選択します。
![03.png](https://qiita-image-store.s3.amazonaws.com/0/353060/b45ca9dc-58aa-af45-0fd8-7ec37133e776.png)
この時、表示するファイル形式をAll Files（全てのファイル形式）にしないと.pem形式のキーペアが表示されません。
![04.png](https://qiita-image-store.s3.amazonaws.com/0/353060/87e61234-5da5-988e-86ef-c824bfb3ae5d.png)
ポップアップ画面が表示されたら[OK]を選択します。
![05.png](https://qiita-image-store.s3.amazonaws.com/0/353060/6ecfcb83-cf69-5251-e913-83f334cf85d0.png)
次に、[Save private key]をクリックしてキーペアの変換を行います。
![07.png](https://qiita-image-store.s3.amazonaws.com/0/353060/1dbb0bb0-89e2-c2ab-4292-55c0e164811b.png)
ファイル名は何でもいいですが、わかりやすいように元の.pem形式のキーペアと同じ名前にしましょう。
![08.png](https://qiita-image-store.s3.amazonaws.com/0/353060/532bdaa3-d24e-e3de-6119-1f10af4ac5b1.png)
ポップアップ画面が表示されたら[はい]を選択します。
![09.png](https://qiita-image-store.s3.amazonaws.com/0/353060/dad40c50-16da-fff8-ed1f-1e3666ee99d6.png)
これでキーペアの変換が完了しました。
新たに.ppk形式のキーペアが作成されていれば成功です。
![10.png](https://qiita-image-store.s3.amazonaws.com/0/353060/f18b1412-11eb-b5bc-fc6c-af134c0fedf9.png)

#PuTTYでAmazonLinux2インスタンスを実行
PuTTYを起動します。
![00.png](https://qiita-image-store.s3.amazonaws.com/0/353060/e900e1fb-7eea-ece0-c7c9-c8cca9e7ee1b.png)
Host NameにAmazonLinux2インスタンスのIPv4パブリックIPを入力。
Portが22、Connection typeがSSHになっているのを確認。
Saved Sessionに任意のセッション名を入力。
[Save]をクリックしてセッションを保存します。
![01.png](https://qiita-image-store.s3.amazonaws.com/0/353060/0679beef-68a8-85f9-a55a-7641a99bfbf6.png)
IPv4パブリックIPはインスタンスの説明から確認できます。
![02.png](https://qiita-image-store.s3.amazonaws.com/0/353060/8b71c2c6-eea8-2613-500f-d65ddd5859f0.png)
次にキーペアの登録を行います。
左のカテゴリーからSSH>Authを選択します。
[Browse...]をクリックしてキーペアを登録します。
![03.png](https://qiita-image-store.s3.amazonaws.com/0/353060/d92363b9-c20b-7954-c50d-6a993181878b.png)
![04.png](https://qiita-image-store.s3.amazonaws.com/0/353060/96ae062e-d594-766e-c190-2e96800181db.png)
キーペアの登録が完了したら、左のカテゴリーからSessionを選択して[Save]をクリックしてセッションの保存をしておきましょう。
これで以降は登録したセッションを選択して[Load]をクリックする事で設定を呼び出せます。
[Open]をクリックすればAmazonLinux2に接続できます。
![05.png](https://qiita-image-store.s3.amazonaws.com/0/353060/386d2441-28d6-9c0e-2d69-dd1390a79f77.png)
最初に接続した時にはポップアップ画面が表示されるので[はい]をクリックします。
![06.png](https://qiita-image-store.s3.amazonaws.com/0/353060/0c629f9a-897d-b5a0-0445-e1b5683d8d1c.png)
この画面が表示されれば接続完了です。
![07.png](https://qiita-image-store.s3.amazonaws.com/0/353060/c4825b7a-16e6-6afb-8a50-c3bbf3557382.png)
ユーザー名を入力してログインしてみましょう。
AmazonLinux2のデフォルトユーザー名はec2-userです。

```AmazonLinux2:AmazonLinux2
Login as: ec2-user
```
ログインに成功するとこの画面が表示されます。
![08.png](https://qiita-image-store.s3.amazonaws.com/0/353060/22769823-575d-31d1-3038-48daa59c4bc1.png)
Pythonでopenpyxlの使い方メモ

#はじめに
openpyxlの使い方を備忘録的に残します

#実行環境
OS windows10
Python 3.6.4
openpyxl 2.5.14

#環境構築
コマンドプロンプトでインストール

```
pip install openpyxl
```
確認

```
pip list
```

#実行
```
import cv2
```
ExcelのパスをしてするためのWorkbookオブジェクトをインポート

```
from openpyxl import Workbook
```
ファイルを新規に作成して、シートをアクティブ化

```
wb =Workbook()
ws =wb.active
```
すでにあるファイルをロードして、一番目のシートを選択

```
outputFilePath = 'test.xlsx' # 出力したいExcelファイル名を指定してください
wb = openpyxl.load_workbook(outputFilePath)
sheetNames = wb.sheetnames
ws = wb[sheetNames[0]]  # ここでは例として1つ目のシートを取得しています
```
シート名を付けて順番をつけて新規にシートを作成
そのシートを選択

```
wb = Workbook()
wb.create_sheet(index=0,title='cal')
wb.create_sheet(index=1,title='data')
ws = wb['data']

```
シートの削除

```
wb.remove["Sheet"]
```

保存

```
wb.save('test.xlsx')
```

シートに2次元配列書き込み

```
import openpyxl
from openpyxl import Workbook
#Excelを新規に作成
wb = Workbook()
#シートをアクティブ化
ws = wb.active
def write_list_2d(sheet, list_2d, start_row, start_col):
    for y, row in enumerate(list_2d):
        for x, cell in enumerate(row):
            sheet.cell(row=start_row + y,
                       column=start_col + x,
                       value=list_2d[y][x])
#リストを作成
list = [[1, 2, 3, 4], [5, 6, 7, 8]]
#2行3列からリストを書きこみ
write_list_2d(ws, list, 2, 3)
#名前を付けて保存
wb.save('sample2.xlsx')
```

参考にしたページ

[PythonでExcelファイル（xlsx）を読み書きするopenpyxlの使い方](https://note.nkmk.me/python-openpyxl-usage/)
Ubuntu に NVIDIA のドライバをインストール （Enroll MOK に注意）

Tensorflow のために NVIDIA のドライバと CUDA を入れようとしたら、ちょっとハマった話。

* Ubuntu 18.10

ドライバのインストールはカンタン:

```bash
$ sudo ubuntu-drivers autoinstall
$ sudo reboot
```

で良いのだが、

Your system has UEFI Secure Boot enabled.

<img width="570" alt="screenshot.png" src="https://qiita-image-store.s3.amazonaws.com/0/63210/feba29b4-4ab6-b65a-b2a4-34a44825730a.png">

をちゃんと読まなかったために失敗した。この指示に従って、

1. パスワードを入力する
2. sudo reboot する
3. OSの起動の前の選択肢で Enroll MOK を選ぶ ←重要
4. 先ほど入れたパスワードを入力

3 で何もせず OS を起動してしまうとドライバはインストールされない。

そして、nvidia-smi がこんなエラーを出す。

```text
$ nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
```

その場合はドライバをアンインストールして、やり直し。

ひとの説明はちゃんと聞きましょう ＞＜。
Maven Repositoryで管理されていないjarをプロジェクトで管理して、ビルド時に実行可能jarに格納する。

通算すると10000回ぐらい(おおげさ)調べているので、自分用ですが、まとめておきたいと思います。なお以下の内容はSpring Bootのバージョン`2.1.2.RELEASE`で実行確認しています。Spring Bootは開発スピードが速いフレームワークとして知られているため、これより古いバージョンや新しいバージョンでは事情が変化している可能性があります。あらかじめご了承ください。

Mavenを使ってライブラリ管理を行う際、[Maven Repository](https://mvnrepository.com/)を利用することが多いと思いますが、場合によってはMaven Repositoryで管理されていないjarを使用してJavaアプリケーション開発を実施する必要があります。

たとえば「third-party-jar-sample」という名前のSpring-Bootプロジェクト(Java)があって、このプロジェクトにおいてMaven Repositoryにはない「third-party.jar」を利用したいとします。まず第1ステップとして、プロジェクトのディレクトリ以下の任意の場所にthrid-party.jarを設置します。実をいうと「プロジェクトのディレクトリ以下」である必要はなく、ローカル環境であればどこでもよいのですが、以下の例では`${projectdir}/lib/thrid-party.jar`としています(理由は後述)。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/105859/cb13b8e2-cb4d-bc09-368b-1c01ae8c3207.png)

あとは`pom.xml`に以下のようなdependencyを追加するだけです。

```xml
<dependency>
  <groupId>com.example</groupId>
  <artifactId>third-party</artifactId>
  <version>1.0.0</version>
  <scope>system</scope>
  <systemPath>${project.basedir}/lib/third-party.jar</systemPath>
</dependency>
```

ポイントとしては2点。ひとつは`scope`を`system`とすること。もうひとつは`systemPath`にローカル環境のjarのありかを指定することです。なお`project.basedir`はプロジェクトのディレクトリパスを格納している変数で、Mavenがビルド時に自動で解決してくれます。third-party.jarの設置場所をプロジェクトディレクトリ以下にしたのはこの変数`project.basedir`を使いたかったからですね。

***

Spring-Bootにおいては、Fat-jarやUber-jarと呼ばれる、必要なjarをすべて格納した実行可能jarを作成します。さて`scope`が`system`のjarを実行可能jarに含めたい場合は`includeSystemScope`を`true`にする必要があります。逆にいうと、何も設定しない場合、`scope`が`system`のjarは実行可能jarに格納されません。

```xml
<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <configuration>
    <includeSystemScope>true</includeSystemScope>
  </configuration>
</plugin>
```
swift 配列についての簡単なまとめ

#簡単な配列についてのまとめを記入しておきます。
以下について記入しようと思います。
####1. 部分配列の形
####2. 部分的な配列の置換について
####3. 文字列からCharacter型の配列の仕方
####4. 多次元配列

#1.部分配列の形

- 部分配列とは元々の配列の一部を取り出したものだとします。（以下のサンプルコードのようなものです）

####※注意　
得られた部分的配列は　Array型　ではなく　ArraySlice という方になります。

```swift:部分配列

var days = ["月","火","水","木","金","土","日"]//元々の配列
print(days[2...4])//水、木、金
print(days[...2])//月　火　水
```

#2.部分的な配列の置換について
- 上のdays を使いながらサンプルコードを書きます。


```swift:部分的な配列の置換
days[0...0] = ["げつよー","かよー","すいよー"]//days[0]ではダメです
print(days) //げつよー　かよー　火　水　木　金　土　日
days[2...4] = ["1","2","3"]
print(days)//げつよー　かよー　1 2 3 金　土　日
days[2...7] = []  //削除するためにも使用できる
print(days)//げつよー　かよー　
```

#3. 文字列からCharacter型の配列の仕方

```swift:文字列から
let number = [Int](0 ..<7)//0から7までの整数を要素とする配列
let Char = [Character]("こんにちわ")//["こ","ん","に","ち","わ"]
```

#4.多次元配列
多次元配列については[こちらの記事をお読みください](https://wa3.i-3-i.info/word11930.html)。
簡単にいうと配列の中に配列が入っている形のものです！

```swift:多次元配列
var title:[[String]] = [["A","B"],["a","b"]]
print(title[0])//["A","B"]を出力
print(title[1][0])//a を出力
title[0].remove(at:1)//"B"を削除
print(title)//[["A"],["a","b"]]
```
##終わりに
配列についてはこんなものでしょうか？
配列の比較、主なメソッドについてはまた次回書こうかなと思っています。
何かアドバイスがあればよろしくお願いします。
Haskellのgi-gtkのHelloworld

#HaskellのGUIの利用方法
wxHaskellを始めいろいろあるけどgtkを利用した。gi-gtkのモジュールを利用した。
ただ、簡単にはインストールできなかったためHelloWorldまでの手順を記録する
#開発環境
- Linux Mint19
- stack
- ghc8.6.3

#前準備
stack new なんとかproject

にて新規プロジェクトを立ち上げる。
そして、gi-gtkのパッケージを依存関係としてpackage.yamlのファイルに記述する

```
dependencies:
- base >= 4.7 && < 5
- gi-gtk
- haskell-gi-base
```
baseはすでに入っている。haskell-gi-baseはないとgi-gtkパッケージがうまく動作しない。
さらにgi-gtkはstack buid時にコンパイルされるが、依存関係があるため[公式](https://github.com/haskell-gi/haskell-gi)のインストールを参考にして以下のコマンドを実行しておく。

sudo apt-get install libgirepository1.0-dev libwebkit2gtk-4.0-dev libgtksourceview-3.0-dev

#GUIのHelloworld
[公式](https://github.com/haskell-gi/haskell-gi)のHelloworld exampleを参考にして

```Main.hs
module Main where

import Lib

main :: IO ()
main = hello
```

```Lib.hs
{-# LANGUAGE OverloadedStrings, OverloadedLabels #-}
module Lib
    ( hello
    ) where
    


import qualified GI.Gtk as Gtk
import Data.GI.Base

hello :: IO ()
hello = do
  Gtk.init Nothing

  win <- new Gtk.Window [ #title := "こんにちは" ]

  on win #destroy Gtk.mainQuit

  button <- new Gtk.Button [ #label := "おしてね" ]

  on button #clicked (set button [ #sensitive := False,
      #label := "押してくれてありがとう、テストは成功しました" ] )

  #add win button

  #showAll win

  Gtk.main
```

以上2つのファイルを書き換える。
そしてstack buildすると、gi-gtkを自動でダウンロードしてコンパイルしてくれる。さらに実行ファイルまで生成されるので、

stack exec なんとかproject-exe

とするとウィンドウが表示される。日本語でも表示ができるためgtkを使い慣れた人ならなんとなくわかるのではないでしょうか。

------------------
HaskellのGUIをやってみたいがstackが便利なためサポートのあるモジュールを選んだ。だが、公式ではcabalを用いたやりかただったのでstackの方法を記した。エディタはVSCODEだけどサポートや補完もしてくれるのでやりやすい。
bash で hex string のエンディアンを変換する

# 概要

以前 [[Python][Ruby] hex string (16 進文字列) のエンディアンをビッグエンディアンからリトルエンディアンに変更する](https://qiita.com/QUANON/items/e3d91a6f33536bd0de5a) という記事を書いたが、これと同じことを bash のワンライナーでやりたい。ただし厳密に行うのは難しいので、単純に文字列を 2 文字づつに分割して順番を逆にするという方針を取る。

# 方法

```bash
$ echo 1234abcd | fold -w2 | tail -r | tr -d '\n'
cdab3412
```

変換の流れは次の通り。

```
1234abcd
```

🔽

```
12
34
ab
cd
```

🔽

```
cd
ab
34
12
```

🔽

```
cdab3412
```

# おまけ

[[Python][Ruby] hex string (16 進文字列) のエンディアンをビッグエンディアンからリトルエンディアンに変更する](https://qiita.com/QUANON/items/e3d91a6f33536bd0de5a) で紹介した方法をワンライナーで実行する。

## Ruby

```bash
$ echo 1234abcd | ruby -e "puts(Array(gets.chomp).pack('H*').reverse.unpack1('H*'))"
cdab3412
```

## Python

```bash
$ echo 1234abcd | python -c "import sys; print(bytes.fromhex(sys.stdin.readline().rstrip())[::-1].hex())"
cdab3412
```
JavaでDB(MySQL)接続しようとするとエラーが出る解決策

投稿テスト兼、忘れないようにメモメモ・・
##使用環境
eclipse 2018
MySQL 5.6

##現象
javaでSQLに繫いで、値を表示させようとすると、
以下のようなエラーを吐く。

Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value ' (W)' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.

プログラムに触れて約一年・・
未だにエラーは読めないが・・・Timezoneが何たらと思い、調べてみることに..


調べている間に、発見！！
[リンク]https://qiita.com/KKZ@github/items/e3f594b04c9233a86419
この方の記事にたどり着きました。

その記事の下のほうに、


jdbc:mysql://localhost:xxxx/xxxx
?useUnicode=true&
useJDBCCompliantTimezoneShift=true&
useLegacyDatetimeCode=false&
serverTimezone=UTC
とURLに書いたら、エラーをはかなくなった。
※xxxxは人によって違う、

##以下説明（間違ってたらごめんなさい）
###useUnicode=true
ユニコードを使いますか?YES!!
(絶対違う気がする・・・)

###useJDBCCompliantTimezoneShift=true
TIME/TIMESTAMP/DATETIME値のtimezone情報を変換する時,
ドライバは JDBC 対応 ルールを使用しますか ? 　
YES

###useLegacyDatetimeCode=false

MySQL Connector/J 5.1.6 で時刻周りの処理が書き直されてuseLegacyDatetimeCode=false することでタイムゾーン変換などを自動で扱ってくれるようになった。

だそうなので、
タイムゾーン変換とか自分でやります？
NO！！ →  自動でやってくれる

ちなみに、
MySQL Connector/J 6 では useLegacyDatetimeCodeプロパティを含め、
古いタイムゾーン周りのプロパティは全部削除される。

と以下のリンクに書いてありました。 笑
[リンク]https://vividcode.hatenablog.com/entry/mysql/connector-j-5.1-use-legacy-datetime-code

###serverTimezone=UTC
サーバータイムゾーンはUTCですよー



っと言った感じですかね、、

**@ KKZさん・・感謝です！！**

あぁ会社の人に見られたら怒られそう・・泣、、
PATHに万物を通さなければならないか？ → むしろ通すべきでな い

よく入門書などで「ダウンロードしたSDKをPATHに通しておく」と魔法のような一文があるが、これは全く必要な  い。なぜならば、よく使うのならばデスクトップやタスクバーにショートカットを作っておいたり、あるいはコマンドラインで使うにしろ環境変数を自分で定義しておく方法があるからだ。その上、`%PATH%`は(環境変数の都合によって)文字数に制限があるため、何でもかんでもPATHに入れておく、という手法を取ると`操作可能な内部コマンド、外部コマンド、ファイルまたはバッチファイルと認識されていません。`と延々と戦うことになる。
AWS EC2の登録とAmazonLinux2インスタンスの作成

#AWS EC2に登録
Amazon AWS EC2の公式サイトから登録をします。
右上の[コンソールへログイン]ボタンをクリックしてAWSマネジメントコンソールを開きます。
https://aws.amazon.com/jp/ec2/
![01.png](https://qiita-image-store.s3.amazonaws.com/0/353060/aeb48e44-47b5-7616-cdf6-c6f5d701b040.png)
一番下までスクロールして言語を日本語にします。
![02.png](https://qiita-image-store.s3.amazonaws.com/0/353060/fd182e88-3d9f-bcee-9678-70a25b4f65e2.png)
右上にある都市の設定を東京にします。
![03.png](https://qiita-image-store.s3.amazonaws.com/0/353060/d4fb7faa-1ae5-6f3b-48ee-9fb8eb93ea0f.png)

#AmazonLinux2インスタンスを作成する
上にあるサービスをクリック、EC2をクリックします。
![04.png](https://qiita-image-store.s3.amazonaws.com/0/353060/96b35caf-bcc2-4090-2b51-39d28e38e68f.png)

左の項目からインスタンスをクリックします。
![05.png](https://qiita-image-store.s3.amazonaws.com/0/353060/d01fbb84-5065-4d03-ec20-42b6ab8e984d.png)

[インスタンスの作成]ボタンをクリックします。
![06.png](https://qiita-image-store.s3.amazonaws.com/0/353060/4de04d0e-8ef4-f51b-092d-99cb2d800eb3.png)
AmazonLinux2で検索、無料利用枠の対象になっているAmazonLinux2の[選択]ボタンをクリックします。
![07.png](https://qiita-image-store.s3.amazonaws.com/0/353060/45995be1-6bc0-91e0-0d2b-dd8fce884fa1.png)
無料利用枠の対象になっているタイプを選択して、[確認と作成]ボタンをクリックします。
![08.png](https://qiita-image-store.s3.amazonaws.com/0/353060/2209009b-cb14-f0d5-1f15-9000510ea0dd.png)
[起動]ボタンをクリックします。
![09.png](https://qiita-image-store.s3.amazonaws.com/0/353060/8ad721a6-24de-2695-fb3c-576bca5fb09b.png)
新しいキーペアの作成でキーペア名を入力して、[キーペアのダウンロード]ボタンをクリックします。
※キーペア名は何でもいいですが、わかりやすくkeyなどを付けておくといいです。
※ダウンロードしたキーペアが無いとAmazonLinux2インスタンスに接続できません。
キーペアのダウンロードが完了したら、[インスタンスの作成]ボタンをクリックします。
![10.png](https://qiita-image-store.s3.amazonaws.com/0/353060/04c832af-9ec4-182b-fc0b-c204b55ed184.png)
これでAmazonLinux2インスタンスが作成されました。
インスタンスの情報はAWSマネジメントコンソール>サービス>EC2>インスタンスから確認できます。
![11.png](https://qiita-image-store.s3.amazonaws.com/0/353060/26a4e5c5-b36d-9af7-b8ca-cf7f65ebd047.png)
【python入門】.join&.splitで任意長の文字列結合・分割

文字列操作で.joinと.splitというのがあるが、ググって見つかった説明がこの参考のようなもので、引数で操作したい場合の説明が無いのでやってみた。
【参考】
[【Python入門】list joinで文字列を連結する方法](https://programming-study.com/technology/python-list-join/)

###やったこと
・文字列リストを任意の部分で連結する
・連結された文字列を任意の部分で分割してリストに戻す
###・文字列リストを任意の部分で連結する
コードは以下のとおり

```py
str_list = ['python', 'list', 'join', 'is', 'difficults', '.']

for i in range(0,7,1):
    mojiretu=' '.join(str_list[0:i])
    print('1',mojiretu)
for i in range(0,7,1):
    mojiretu=' '.join(str_list[1:i])
    print('2',mojiretu)    
for i in range(0,7,1):
    mojiretu=' '.join(str_list[2:i])
    print('3',mojiretu)       
```
実行結果は以下のとおり
文字が自動的に出てきて感動。

```
>python join_moji.py
1
1 python
1 python list
1 python list join
1 python list join is
1 python list join is difficults
1 python list join is difficults .
2
2
2 list
2 list join
2 list join is
2 list join is difficults
2 list join is difficults .
3
3
3
3 join
3 join is
3 join is difficults
3 join is difficults .
```
###・連結された文字列を任意の部分で分割してリストに戻す
コードは以下のとおり、上記のコードに続けて実行します。
つまり、文字列

```split_moji.py
mojiretu="join is difficults ."
for i in range(0,len(mojiretu)+1,1):
    str_list = mojiretu[0:i].split()    
    print("mojiretu[0:{}]".format(i),str_list)
```
実行結果は、以下のとおり
１文字ずつがリストになってすごい！
区切り文字" "（ブランク）はちゃんと保存するんだね。

```
>python split_moji.py
mojiretu[0:0] []
mojiretu[0:1] ['j']
mojiretu[0:2] ['jo']
mojiretu[0:3] ['joi']
mojiretu[0:4] ['join']
mojiretu[0:5] ['join']
mojiretu[0:6] ['join', 'i']
mojiretu[0:7] ['join', 'is']
mojiretu[0:8] ['join', 'is']
mojiretu[0:9] ['join', 'is', 'd']
mojiretu[0:10] ['join', 'is', 'di']
mojiretu[0:11] ['join', 'is', 'dif']
mojiretu[0:12] ['join', 'is', 'diff']
mojiretu[0:13] ['join', 'is', 'diffi']
mojiretu[0:14] ['join', 'is', 'diffic']
mojiretu[0:15] ['join', 'is', 'difficu']
mojiretu[0:16] ['join', 'is', 'difficul']
mojiretu[0:17] ['join', 'is', 'difficult']
mojiretu[0:18] ['join', 'is', 'difficults']
mojiretu[0:19] ['join', 'is', 'difficults']
mojiretu[0:20] ['join', 'is', 'difficults', '.']
```
###二個ずつ、三個ずつ

```py
str_list = ['python', 'list', 'join', 'is', 'difficults', '.']

for i in range(0,7,2):
    mojiretu=' '.join(str_list[0:i])
    print('1',mojiretu)
for i in range(0,7,2):
    mojiretu=' '.join(str_list[1:i])
    print('2',mojiretu)    
for i in range(0,7,2):
    mojiretu=' '.join(str_list[2:i])
    print('3',mojiretu)        
```
二個ずつの結果は以下のとおり

```
1
1 python list
1 python list join is
1 python list join is difficults .
2
2 list
2 list join is
2 list join is difficults .
3
3
3 join is
3 join is difficults .
```

```py
mojiretu="join is difficults ."    
for i in range(0,len(mojiretu)+1,3):
    str_list = mojiretu[0:i].split()    
    print("mojiretu[0:{}]".format(i),str_list)
```
三個ずつの結果は、以下のとおり

```
mojiretu[0:0] []
mojiretu[0:3] ['joi']
mojiretu[0:6] ['join', 'i']
mojiretu[0:9] ['join', 'is', 'd']
mojiretu[0:12] ['join', 'is', 'diff']
mojiretu[0:15] ['join', 'is', 'difficu']
mojiretu[0:18] ['join', 'is', 'difficults']
```
###まとめ
・.join&.splitで任意長の文字列結合・分割をやってみた
・リストが文章になったり、逆に文章がリストになったりちょっと感動もの
ssh接続のconfig整理のメモ

.ssh/configの管理の為のメモ

Serverが複数あったり、複数のServiceを掛け持ちしてたりするとconfigが長くなるので

```zsh

alias ssh="cat ~/.ssh/config.* > ~/.ssh/config; ssh"
```

を`.bashrc`とか`.zshrc`に追加して、`.ssh`配下に`config.projectA`とか`config.projectB`とか`config.aws`とかしておくと、そのプロジェクト関連の設定だけすぐにわかるので便利。

ssh関連の設定を定義したい場合は`config.a`とかにして（catで最初に読み込みたいので）、下記内容を定義。

```sh

# 結合の先頭用
ServerAliveInterval 30
ServerAliveCountMax 5
```

他の`config.*`のファイルにはsshの定義を書いておく

```sh

#------------------------------
# projectA
#------------------------------

# bitbucket
Host bitbucket
    Port 22
    Hostname bitbucket.org
    IdentityFile ~/.ssh/id_rsa
    TCPKeepAlive yes
    IdentitiesOnly yes

# vagrant
Host app
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/aaa/Documents/aaa/vagrant/.vagrant/machines/app/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL
```

あとはsshを実行したタイミングでconfigが再作成されてsshされる
1つのファイルの方がいいと言う方もいると思いますので、好みだけの問題だと思いますが、自分用にメモとして。