OmniAICreator/Qiita-1.07M huggingface dataset:
Swift学習記＃4「関数の定義」

#はじめに
今回はswiftにおける関数の定義方法について書いて行きます！

関数は初めて触ると、どの様にデータが流れているのか
よくわかりませんよね！僕も最初はそうでした！

なのでここでは、基礎的な定義とともに
**引数**や**戻り値**なんかについても覚えて、
データの流れをしっかり掴みましょう！

##関数とは
関数（function）とは、
簡潔に言うと**「特定の処理を行うためのまとまり」**です。

他の言語でも用いられていることが多いので、
他の言語を学習したことのある方はすでにご存知かと思います。

##関数の定義
書式はこんな感じ、、、

```test.Playground

func 関数名(引数名１:引数１の型, 引数名２:引数２の型, ...)-> 戻り値の型{

    return //戻り値

}
```
定義の中にある**引数**というのは、**「関数に渡す値」**のことで
渡す値は、その後に書くコードの中で指定します。

具体例はこんな感じ、、、

```test.Playground

func test(test1:Int, test2:Int)-> Int{

    // 関数で行う処理
    var num = 100
    return num + test1 - test2 //戻り値                              　　　　　　　　　　　　　　　　　　　　　　　　　　 　　
}　　　　　　　　　　　　　　　　　　　　　　   　　
                                         　　
                                         　　　
// 関数の呼び出し　　　　　　　　　　　　　　　　　　
print(test(test1:10, test2:100)) // 引数

```
最後の「print(test(test1:10, test2:100))」で
関数testに「test1:10, test2:100」という値を渡し、関数で処理された
データが戻ってきて（これを戻り値という）表出されている。

##可変個引数
一つの引数で**複数の値**を渡す場合。

具体例はこんな感じ、、、

```test.Playground
func test ( num: Int... ){
　　　//.enumerated()は列挙型
    for (i, num) in num.enumerated() { 
        print(num)
        print( "\(i) - \(num)" )
    }
}

test( num:5, 6, 7 )

//　結果
ー＞　5
     0 - 5
     6
     1 - 6
     7
     2 - 7
```
こうすることで、引数で複数の値を渡すことができる。

##引数の外部名
swiftでは、引数の**関数の外での名前を決めることができる**。

具体例はこんな感じ、、、

```test.Playground
// 標準形
func getArea( radius r : Double ) -> Double {
	let pi = 3.14
	return pi * r * r
}

var a = getArea( radius: 3 )
print( a )

// 省略形
func getArea( _ r : Double ) -> Double {
	let pi = 3.14
	return pi * r * r
}

var a = getArea( 3 )
print( a )


```
`( radius r : Double )`の様に、
`（外の引数名　中の引数名：データの型）`の形を作ることができる。

また、関数の外での引数名は、`( _ r : Double )`の様に
アンダースコアを記入することで省略できる。

##タプルを返す関数
swiftでは、関数は**戻り値をタプルで返すこともできる**。

####＊タプルとは、
　複数の変数をまとめ上げたり、 
　ひとつの変数に簡単にわかりやすい意味を与えたりするもので、
　（）で括って指定する。例：(name:String, age:Int)

具体例はこんな感じ、、、

```test.Playground

func group(ID:Int) -> (name:String, age:Int) { //戻り値がタプル
	switch ID {
	case 1000:
		return ( "Ichiro", 30 )
	default:
		return ( "Unknown", 0 )
	}
}

var p1 = group( ID: 1000 )
print( "\(p1.name) - \(p1.age)" )

var p2 = group( ID: 5 )
print( "\(p2.name) - \(p2.age)" )

// 結果
ー＞　Ichiro - 30
　　　Unknown - 0

```
##inoutによる参照渡し
swiftでは、関数を定義する際に`( msg : inout String )`の様に
データ型の前に`inout`をつけ、引数を設定する際に`( msg: &s )`の様に
引数の値の前に`&`をつけると参照渡すを行うことができる。

####＊参照渡しとは
　通常の引数は、関数外の変数の値をコピーして渡す**値渡し**を行うため、
　**関数外の変数の値に変化はない**。
　しかし**参照渡し**の場合は、関数ないで変数の値を変更すると、
　**その変更を関数外にある元の変数と共有することになる**。

具体例はこんな感じ、、、

```test.Playground
func myfunc ( msg : inout String ) {
    msg = "Hello World!"
}

var s = "Hello!"
print( "s = \(s)" )

myfunc( msg: &s )

print( "s = \(s)" )
print(s)

//　結果
ー＞　s = Hello!
　　　s = Hello World!
　　　Hello World! // 変数が関数での変更を共有している

```

#これまで
今回は関数の定義について書いて行きました。


swift初級で使用するのは、この位ではないかと思います。
学習が進めばさらにいろんな表記や手法が出てくると思うので、
その都度追加していこうと思います！

ここまでで、swift学習記も＃４になり、
基礎知識もあらかたついた様な気もするので、
これからはアプリを開発しながらの学習をやって行きます！
Docker Quickstart Terminalでpemission denied

# 背景

PCのOSがWindows10 Homeだった為、[リンク](https://github.com/docker/toolbox/releases)からDockerToolboxをインストールしDocker Quickstart Terminalでmkdirしたところ下記のようなエラーがでた。

```ruby:DockerQuickstartTerminal
$ mkdir imagebuild
mkdir cannot create directory 'imagebuild' : Permission denied
```

#解決策
```ruby:DockerQuickstartTerminal
$ cd [任意の作業ディレクトリ]
$ mkdir imagebuild
$ cd imagebuild
```

#原因
DockerQuickstartTerminalを起動した際の作業ディレクトリが権限を持っていないことが原因。
権限について詳しくは[こちら](https://qiita.com/t-a-run/items/239ed690ece7a011804a)

C:\Program Files\Docker Toolbox上ではなく、新しくdocker作業用ディレクトリを作成しそこでmkdirをすれば解決。基本的にはDocker Toolboxディレクトリ上では作業しない。

#参考
1. [chmod? chown? よくわからんって人のための、ファイル権限系まとめ](https://qiita.com/t-a-run/items/239ed690ece7a011804a)
2. [Docker Toolboxのパーミッション変更](https://teratail.com/questions/248253)
スプレッドシートをDB代わりにGASのWebアプリを作成しデータ更新させてみた。Vue版、ハマったところinputの再描画編~~

#はじめに
Vueに対応していこう～。ということで始めたわけですが、
inputの再描画がハマりにハマって、くじけそうになったんで残しておきます。

#結論
ここを見ている方は、たぶん、同じ症状の方だと思うのでとっとと結論書きます。
私は、モーダル表示にして 回避 しました！
そうです。すみません。若干逃げてます。
ですが、私の作りたかったものからすると、ちょうど都合がよかったのです・・・

#なぜモーダルだとうまくいくのか
モーダル表示をする際に、モーダルにするためのv-showに設定したプロパティをtrueにします。
それと同時に、上記の内側のタグのv-ifもtrueにするようにしました。
こんな感じです。

```javascript
    <div id="modal" v-show="showContent" class="overlay">
      <div id="modal_content" v-if="dispDetails" class="content">
        <!-- さらに内側のタグ 
```
モーダルにすることで、モーダルを表示する際には、showContent　も　dispDetails　も共にtrueにします。閉じる際は共にfalseにします。（上記の場合、同じプロパティを使用しても問題ないとは思いますが明示的に分けました。）
dispDetailsがTrue、Falseに切り替わることで、v-ifが設定されたタグよりも内側のタグがきちんと再描画されるようになったのだと思われます。

#感想
表示できるようになって本当にほっとしました。

[Vue版、ハマったところcheckboxの再描画編~~](https://qiita.com/yamamow/items/d5c353e6d52861007278)も投稿しました。

全体の記事はこちら↓
[スプレッドシートをDB代わりにGASのWebアプリを作成しデータ更新させてみた。Vue版 その１～～](https://qiita.com/yamamow/items/6be4fa99cd3cb45ecffa)

[スプレッドシートをDB代わりにGASのWebアプリを作成しデータ更新させてみた。Vue版 その２～～](https://qiita.com/yamamow/items/38ad08c3cf85ec9df0e7)

こちらもよろしくお願いします
Vue.jsで東京都の今日の天気を表示するWebサイトを作るコピペサンプル


簡単なサンプルです。

Vue.jsとaxiosで簡単なデータ連携をします。

## 作るもの

![](https://i.gyazo.com/1856346cce92a43559a60b06908bf1d1.gif)

こんな感じでボタンを押すと今日の天気を表示するWebサイトを作ります。

## 使うAPI

OpenWhethermapのAPIを作います。無料である程度（雑）使えます。

https://openweathermap.org/api

APIキーを取得しましょう。

ログイン後[ここ](https://home.openweathermap.org/api_keys)にアクセスするとキーが表示されます。

## コピペ用コード

一箇所だけ、変更が必要です。
`appid=ここにOpenWeathermapのAPIキーを指定`と書いているところに自身で取得したAPIキーを指定しましょう。

```index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <p>今日の天気は{{ weather }}で、気温は{{ temp }}度です。</p>
        <button v-on:click="getData()">今日の東京の天気をAPIで取得！</button>

        <p>
            <a href="https://openweathermap.org/api">openweathermapから取得しています。</a>
        </p>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                weather: 'xxxx',
                temp: 'yyyy'
            },

            methods: {
                getData: async function(){
                    const URL = `https://api.openweathermap.org/data/2.5/weather?id=1850147&units=metric&appid=ここにOpenWeathermapのAPIキーを指定`;
                    const response = await axios.get(URL);
                    this.weather = response.data.weather[0].main;
                    this.temp = response.data.main.temp;
                    // console.log(response.data);
                },
            },

            // mounted: function(){

            // }
        })
    </script>
</body>
</html>
```

## 試す。

ローカルのindex.htmlをブラウザで開いたり、live severやどこかにデプロイしたりして挙動確認をしましょう。
PostgresでIndexによる実行速度の違いを調査した

# Indexとは

[インデックスの意味とメリット・デメリット](https://www.dbonline.jp/sqlite/index/index1.html)

要するに索引で、対象のカラムを高速に検索するために利用される。
実装は対象のカラムとIDの組を、対象カラムの内容でソートしたものがある。
（他にもありそう）

イメージとしては、よく技術本の索引で用語集みたいなのがアルファベット順で並べてあるのを思い浮かべた。
「Index」を調べようとしたら、アルファベット順に並んだものからすぐに「Index」を見つけられ、Indexが記載されたページ（ID）がすぐ分かる。

一方、DBの内容を変更する操作はIndexを更新する必要があるため遅くなる。
これも本の索引を調べたらすんなり分かる。

# 実験
## 準備
実験のためDockerでPostgresサーバーを立てた。

```yaml
version: "3.1"
services:
  db:
    image: postgres:12.2
    restart: always
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=example
      - PGPASSWORD=example
      - POSTGRES_DB=testdb
  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

```

テーブルを作成した。

```sql
CREATE TABLE "one" (
  "id" serial NOT NULL,
  "name" character(50) NULL,
  "age" integer NULL
);
```

名前と年齢のデータで年齢でユーザーを検索するイメージ。
適当です。

## 実験用のSQL

インデックスを貼る

```sql
CREATE INDEX "one_age" ON "one" ("age");
```


データを入れる
1千万行入れます。
検索予定のageは1歳から200歳までランダムで挿入します。

```sql
INSERT INTO "one" (id,name, age) 
 SELECT 
     i, format('テスト%s', i), (random()*200)::int
 FROM
     generate_series(1,10000000) as i
;
```


データを検索する

```sql
SELECT
	*
FROM
	one
WHERE
	age = 30
;
```

## 実験結果
速度測定のためにpostgresのCUI上で\timingを使い、SQLを実行しました。

||挿入|検索|
|---|---|---|
|インデックス無し|24s|0.8s|
|インデックス有り|49s|0.3s|

結構影響ありますね。
master以外のブランチをherokuへプッシュする場合

ローカルにあるmaster以外の作業ブランチをherokuにプッシュしたけどビルドされなかったので調べてみたら以下のコマンドで出来ることが分かったので備忘録として記録。

`20200511-rails6`というブランチをherokuにpushしたが、skipping buildと表示された。

```
$ git push heroku 20200511-rails6
Enumerating objects: 123, done.
Counting objects: 100% (123/123), done.
Delta compression using up to 12 threads
Compressing objects: 100% (105/105), done.
Writing objects: 100% (123/123), 149.47 KiB | 5.15 MiB/s, done.
Total 123 (delta 13), reused 0 (delta 0)
remote: Pushed to non-master branch, skipping build.
```


```terminal

git push heroku 20200511-rails6:master
```


https://devcenter.heroku.com/articles/git#deploying-from-a-branch-besides-master

以上
Vue.jsプロジェクトのつくりかた※自分用メモ

1. ターミナルでcdプロジェクトを作成したいディレクトリに移動。:walking_tone1:
2. vue create プロジェクト名

3. 設定を選ぶので、defaultで
4. cd　作ったプロジェクト名
5. yarn serve　で完成！:blush::blush::blush:

おまけ

``` test.js
console.log()
```
↑のようにやりたいときは

改行
\`\`\`
コード
\`\`\`
改行　　でコードが挿入できる！:clap_tone2:

\`\`\`の後にファイル名を入れると、ファイル名も表示される。言語を指定するとそれにあったように色つけてくれる！
おれのCLI操作メモ

CLI操作
###CLIの起動EC2へログイン
```
ssh -i Rectio.pem ec2-user@18.178.101.254
```

##RC2へのログイン
```
ssh -i Rectio.pem ec2-user@18.178.101.254
```

##ユーザーの切り替え
```
sudo su - ユーザ名
```

##mySQLに接続
```
mysql -h エンドポイント -P 3306 -u ユーザー名 -p
mysql -h rectio-mysql.cp48k3bdmh19.ap-northeast-1.rds.amazonaws.com -P 3306 -u admin -p
```

###最上階層からRailsの階層へ飛ぶ
```
cd /var/www/rails
```

###EC2上でのプリコンパイルについて
なぜかEC2でプリコンパイルができない。

```
bundle exec rake assets:precompile RAILS_ENV=production
```

>プリコンパイルとは....
Railsは開発環境では「app/assets」以下のファイルをアセットパイプラインで拾ってくるが、本番環境では「public/assets」以下のファイルを拾ってくるようになっている。
開発環境では(environment.rb)、本番環境では、(production.rb)を使いアセットパイプラインの詳細を設定することができる

なので、ローカルでプリコンパイルしてからgithubにpushし、それをcloneする形になるかと思う


###EC2からPush

https://qiita.com/megu_ma/items/03388e1979b3fc0539f7


### MySQLコマンド

https://qiita.com/CyberMergina/items/f889519e6be19c46f5f4

```
#データべースを見る
show databases;

#データベースの選択
use データベースの名前

#テーブル一覧を見る
show tables;
```

#gitまわり
```
git status　#ステータス見る
git add -A　#すべてaddする
git commit #コミットする
git push origin master #プッシュする
git pull origin master #プルする
```
###本番用DBマイグレート
```
[ec2-user@******* current]$ rake db:create RAILS_ENV=production

[ec2-user@******* current]$ rake db:migrate RAILS_ENV=production

[ec2-user@******* current]$ rake db:seed RAILS_ENV=production
```

###ログの削除

```
rake log:clear
```
CarrierWaveを使って、ユーザーのプロフィール画像を設定する

#手順

1.Gemfileの追加

```ruby
gem 'carrierwave'
```
```
$ bundle install
```

2.Uploaderの生成

uploaders/image_uploader.rbが生成される。

```
$ rails g uploader image
```

3.モデルの編集

user.rbでuploaderを使う設定をする。

```models/user.rb
class User < ApplicationRecord
  mount_uploader :image, ImageUploader
end
```

4.ビューの編集

```new.html
<%= form_with(model: user, local: true) do |form| %>
  <%= form.text_field :name %>
  <%= form.email_field :email %>
  <%= form.password_field :password %>
  <%= form.file_field :image %>
 　# 画像ファイルの情報をimage_cacheに一時保存するために下記の一文も追記しよう！
  <%= form.hidden_field :image_cache %>
  <%= form.submit %>
<% end %>
```

```index.html
// 下記記述でimage画像を表示できる //
<%= image_tag @user.image.url %>

// if文で条件分岐する場合 //
<% if @user.image? %>
  <%= image_tag @user.image.url %>
<% else %>
  # デフォルトで表示したい場合
  <%= image_tag "/assets/default.jpg" %>
<% end %>
```

5.minimagic導入

```ruby

gem 'mini_magick'
```

```
$ bundle install
```

6.image_uploader.rbファイルを編集

```image_uploader.rb
class AvaterUploader < CarrierWave::Uploader::Base

　　include CarrierWave::MiniMagick 
　　# 画像をリサイズ
　　process resize_to_fit: [100, 100]
end 
```


以上
dotenvって何？

# これ何
機密情報を扱う時にどうするんだっけ？みたいなのをまとめる。

# まとめ
- 機密情報はそのままコードに保存しちゃダメ
- `.env` にまとめるがgitに保存する場合は機密情報を除いて `.env.sample` にすることが多い
- 多くの言語で `.env` を扱うパッケージが存在する

# envファイルとは
アプリケーションの中で「DBの情報」や「サーバーの情報」「外部APIの連携情報」など第三者に見せたくない機密情報が存在する。機密情報は、コードとは別に環境変数として情報を保存する。

ローカルでは、複数プロジェクトが存在し、プロジェクトごとに異なる環境変数を取り扱いたい。また、新しく加わるメンバーのためにも環境変数の設定ファイルをまとめておきたい。

そのため、 `.envファイル` として、機密情報をまとめたファイルを作成し、情報を管理する。
`.envファイル` はgitにそのまま載せると機密情報がgitに乗ってしまうため、 `.gitignore` に `.envファイル` を追加し、 `.env.sample` というサンプルのファイルを置くことが多い

# 環境変数について
環境変数の追加・閲覧・削除の方法を簡単にまとめる。

```shell
# 環境変数の設定
$ export GERU="mew" # GERUという名前の環境変数に「mew」という値を入れる
# 環境変数の確認
$ echo $GERU # GERUという名前の環境変数の中身を見る
mew
# 設定されている環境変数の確認
$ printenv # 設定されている環境変数を全て確認する
...
GERU=mew
...
# 設定されている環境変数を削除する
$ unset GERU # 設定されている環境変数の削除
$ echo $GERU # 設定が削除されたので、出力しても表示されない
```

- [環境変数を設定するには](https://www.atmarkit.co.jp/flinux/rensai/linuxtips/118setenv.html)
- [シェル変数を定義したり、削除するには](https://www.atmarkit.co.jp/flinux/rensai/linuxtips/108envsetdel.html)

# .envについて
いろんな言語で.envで環境変数を取り扱うパッケージが開発され、利用されています。

### Ruby[dotenv]
- [bkeepers/dotenv](https://github.com/bkeepers/dotenv)
- [dotenv-rails](https://rubygems.org/gems/dotenv-rails/versions/2.1.1)
- [dotenv](https://rubygems.org/gems/dotenv)

### Javascript[dotenv]
- [dotenv](https://www.npmjs.com/package/dotenv)

### Python[python-dotenv]
- [python-dotenv](https://pypi.org/project/python-dotenv/)

# まとめ
- 機密情報はそのままコードに保存しちゃダメ
- `.env` にまとめるがgitに保存する場合は機密情報を除いて `.env.sample` にすることが多い
- 多くの言語で `.env` を扱うパッケージが存在する

# 参考文献
- [envファイルとはなんだろう。](https://qiita.com/harutakaoka522/items/e0abddfd0311eb4fb32b)
docker-composeでRails5.2+MySQL開発環境

（社内の特殊な環境を移行した際のメモです）

rubyのイメージでうまく環境を構築できなかった(=既存のrails環境のGemfileと一致するバージョンのgemが揃わなかった)ため、Ubuntuのイメージから出発してRailsの環境を構築した際の設定です。

```yml:docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./tmp/mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=secret
  web:
    build: .
    command: "rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - ./:/railsapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```

```dockerfile:Dockerfile
FROM ubuntu:18.04

RUN apt-get update && apt-get upgrade && apt-get install -y \
  ruby-dev libmysqlclient-dev libmagick++-dev libcurl4-openssl-dev libssl-dev nodejs \
  && gem install rails -v "~> 5.2" -N && gem install bundler -v "~> 1.16"

RUN mkdir /railsapp
WORKDIR /railsapp
COPY ./ /railsapp
RUN bundle install
```
suコマンドのハイフン(-)の曖昧なところを今すぐ解消しよう！！

# まずはおさらいから

Linuxで現在のユーザーから別のユーザーに切り替えるときのコマンドが `su` です。
ちなみに、これって **substitute user** の略なんですって。（[参考: su (Unix) - Wikipedia](https://en.wikipedia.org/wiki/Su_(Unix))）
substituteは「代わりに使う」という意味です。ポケモンのみがわりという技も英語でsubstituteといいます。
switch user とか super user の略ではないんですね。

# コマンドの使い方

```
$ su [-] <user name>
```

基本的なコマンドの使い方は上の通りで、ユーザー名を指定しないとsuper user(root)になりますね。

# ハイフンって何の意味があるの？

`su` コマンドの `-` には環境変数を引き継ぐという意味があります。
つまり、`-` をつけると初めからそのユーザーでログインしたのと同じことになります。

- `$ su - anotherUser`
    - 環境変数を引き継ぐ
    - 最初からanotherUserでログインしたのと同じ状況になる
- `$ su anotherUser`
    - 環境変数を引き継がない

# さいごに

たまにはこんなあっさりした投稿もいいかなw
情報セキュリティについてのまとめ

###情報セキュリティ

情報セキュリティとは、WEBサービスにおいてのセキュリティのことを指します。
情報漏洩や不正なアクセスを防ぎつつ権限のあるユーザーの利便性を高めるのが理想です。

下記の３つを保持することがWEBサービスの使命です。
1.機密性
  -権限のない人が情報資産を見たり使用したりできないようにする
2.完全性
  -権限のない人が情報を消したり書き換えたりできないようにする
3.可用性
  -権限のある人（ユーザー）がサービスをいつでも利用できるようにする



全てにおいてのセキュリティをおびやかす欠陥や問題点のことを<strong>脆弱性</strong>と言います。
また、<strong>脆弱性</strong>は開発者のチェック不足やバグによって生まれます。

<strong>脆弱性</strong>の具体例は以下です
-個人情報を勝手に閲覧される（機密性の侵害）
-WEBページの内容が改ざんされる（完全性の侵害）
-WEBページの利用ができなくなる（可用性の侵害）

ユーザーへの金銭的補填、開発者の信頼の失墜、機会損失などの被害が生まれてしまうため、<strong>脆弱性</strong>への対策はしっかり行わなければいけません。
SwiftでTwitterのプロフィールであるようなUITableViewのヘッダーの画像を引っ張って拡大させる機能をたった数行のコードで実装する

Tiwtter等のアプリでよくあるプロフィール画面のカバー画像を下に引っ張ると拡大されるPrallaxHeader機能(っていうんですかね？)ですが、
実はこれめちゃくちゃ簡単に実装できます。

完成系はこんな感じです。
![ezgif-7-b4b7b38acba0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201186/f3acee12-b550-fdac-46fc-c5c10a2c7990.gif)

[GitHub](https://github.com/kumanmushi/ParallaxTableHeaderSample)にサンプルもあります。

# 環境
Xcode Version 11.4.1 (11E503a)
Swift version 5.2.2 (swiftlang-1103.0.32.6 clang-1103.0.32.51).

# 実装

使用しているはUITableViewとtableHeaderViewです。
まあこの構成はよくあると思いますが、ポイントは__ヘッダー画像をtableHeaderViewに入れない__ことです。

DebugViewHierarchyでみるとよくわかると思います。
![スクリーンショット 2020-05-16 14.44.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201186/aaef83be-bafc-9dd3-f0a5-7e1be1fc2a42.png)

## Interface Builder

- UIViewController.View
 - UIImageView ←これがTwitterでいう下に引っ張ると拡大されるカバー画像になる。
 - UITableView　←透明にする。
   - UIView ←これがtableHeaderView
     - UIView ←これがカバーイメージの上にかぶる部分。透明にする。
     - UIView ←ヘッダーに載せたいコンテンツを載せるView。背景色をつける。
       - UILabel ←ヘッダーに載せたいコンテンツ。今回は適当にラベル。

上記の構成でViewを配置し、カバー画像のUIImageView下記のAutoLayoutをかけます。
- Align Top to SuperView Top
- Align Center X
- 任意のAspect Ratio
- Height Equal = 適当な数値

カバーイメージの上にかぶる部分の透明なViewに下記のAutoLayoutをかけます。
- Align Top to SuperView Top
- Trailing Space To SuperView
- Leading Space To SuperView
- カバー画像と同じAspect Ratio

あとは実装したいUIにあわせます。

## コード

カバー画像Viewの `Align Top to SuperView Top` と `- Height Equal = 適当な数値` をIBOutletで接続します。　

```swift
@IBOutlet private var coverImageHeightConstraint: NSLayoutConstraint!
@IBOutlet private var coverImageTopConstraint: NSLayoutConstraint!
```

`- Height Equal = 適当な数値`のままだと高さがずれるのでデフォルトの高さをセットしてあげてください。

```swift
private var defaultCoverImageHeight: CGFloat { return self.view.frame.width / 3 }

override func viewDidLoad() {
    super.viewDidLoad()
        
    self.coverImageHeightConstraint.constant = self.defaultCoverImageHeight
}
```

最後に、`UITableViewDelegate.scrollViewDidScroll(_ scrollView: UIScrollView)`の中にcontentsOffset.yの変化に応じて適当な値をIBOutletで接続した制約に与えてあげれば終わりです。

```swift
extension ViewController: UITableViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        self.coverImageHeightConstraint.constant = max(self.defaultCoverImageHeight, -(scrollView.contentOffset.y - self.defaultCoverImageHeight))
        self.coverImageTopConstraint.constant = min(0, -scrollView.contentOffset.y)
    }
}
```

# おわり

UITableViewの下にUIImageViewを配置し、必要な箇所の背景色を透明にして制約をいじるだけなので割と既存の実装に反映させやすいと思います。
また、スクロール位置に合わせてブラーを追加する機能等も簡単に追加できると思うのでおすすめです。
AWS CDKでハマったこと＆解決法

## Cannot read property 'endsWith' of undefined

```bash
Cannot read property 'endsWith' of undefined
Subprocess exited with error 1
```

`解決法` cdkのあらゆるコマンドに-cオプションを付ける

-cオプションで何かしらのcontextを受け取ること前提のコードを書いている場合、 `cdk deploy` だけでなく `cdk bootstrap` 等の一見パラメータが不要そうなコマンドを実行する場合にも-cオプションを付けなければこのエラーが出てしまう。

## Argument of type 'this' is not assignable to parameter of type 'Construct'.

```bash
Argument of type 'this' is not assignable to parameter of type 'Construct'.
```

`解決法` 各npmパッケージのバージョンを合わせる

例えば下記のようになっていないとダメ。

```json
  "dependencies": {
    "@aws-cdk/aws-certificatemanager": "^1.39.0",
    "@aws-cdk/aws-cloudfront": "^1.39.0",
    "@aws-cdk/aws-route53": "^1.39.0",
    "@aws-cdk/aws-route53-targets": "^1.39.0",
    "@aws-cdk/aws-s3": "^1.39.0",
    "@aws-cdk/aws-s3-deployment": "^1.39.0",
    "@aws-cdk/core": "^1.39.0"
  },
  "devDependencies": {
    "aws-cdk": "^1.39.0"
  }
```

パッと見、合っているようでも合っていないことがあるので注意。
バージョンに `^` が入っているパッケージと入っていないパッケージが混在していたりするとダメ。
全部合っているはずなのに上記エラーが出るなら、一度 `npm_modules` フォルダを削除してから再度 `npm install` する。



## Cloud assembly schema version mismatch: Maximum schema version supported is 2.0.0, but found 3.0.0.

```bash
Cloud assembly schema version mismatch: Maximum schema version supported is 2.0.0, but found 3.0.0.
Please upgrade your CLI in order to interact with this app.
```

`解決法` グローバルインストールされているaws-cdkパッケージのバージョンを合わせる

これも前述と似ているが、グローバルのcdkコマンドを実行している場合に発生するエラー。
その場合は、各パッケージとグローバルのaws-cdkのバージョンが違うとダメ。（なので `aws-cdk` パッケージに関してはグローバルインストールはあまりオススメしない）
コレクションクラスのListに対してLINQを用いて集約したい。GroupBY,Sum,OrderBy,Selectの書き方

###LINQをList<コレクションクラス>にどう書くか？
  LINQの記事では、string型やint型のListを扱っているものはよくある。しかし、独自で作成したコレクションクラスのListをどうLINQで処理するかの記事が発見しづらかった。そのため、ここにその仕方を記述する。
　元となるList<独自クラスで複数のフィールドを持つ>の値で、同一科目のものは集約しつつ、金額は合計値を記述するようなテキスト(メモ)を生成したい。

``` C#
 public string WritingMemo( List<JournalizingMemo> MemoDrafts)
        {

            //メモの元MemoDraftsから同一会計名目や貸借項目は集約し金額は合計値を記述したいので
            var memoArranged = MemoDrafts.GroupBy(x => new { x.SlipDate, x.AccountingName,x.BalanceName, x.SubjectName })
                                    .Select(y => new
                                   {
                                       SlipDate = y.Key.SlipDate,
                                       Amount   = y.Sum(z => z.Amount),
                                       AccountingName = y.Key.AccountingName,
                                       BalanceName =    y.Key.BalanceName,
                                       SubjectName =    y.Key.SubjectName
                                   })
                                   .OrderBy(x => x.SlipDate)
                                   .ThenBy(x => x.AccountingName)
                                   .ThenBy(x => x.BalanceName)
                                   .ThenBy(x => x.SubjectName);

            //メモのヘッダー作成
            sb.AppendLine("出力日：" + DateTime.Now.Date.ToString("yyyy/mm/dd"));
            sb.AppendLine("");

            //集約結果からテキストに起こす
            var sb = new StringBuilder();

                foreach (var record in memoArranged)
                {
                        sb.AppendLine("伝票日付:" + record.SlipDate.ToString("yyyy/mm/dd"));
                        sb.AppendLine($"口座情報：{record.AccountingName}");

                        //...中略
                     }
             return sb.ToString();

```
　という書き方で、独自のコレクションクラスに対しても、LINQを用いれば簡単に集約した結果を記述できる。
PHPによるEnumの実装方法がついに決着した

ときどきPHPStanの更新を一応眺めているんだけど、PHPStan 0.12.20 でいつの間にか欲しかった機能が実装されていた。
`@param` に定数が使えるようになっていた。定数だけだと一見無意味だけれど、ワイルドカードやunionが使える。

これによって、今まで様々な実装があったEnumをどうするかという問題が解決した。
単に`const`を集めたシンプルなクラスにすれば良い。

```php
<?php
namespace App;
class Env
{
    public const DEVELOP = 'development';
    public const STAGING = 'staging';
    public const PRODUCTION = 'production';
}
```

```php
<?php
namespace App;
class Main
{
    /**
     * @param Env::* $env
     */
    public static function doSomethingByEnv($env): void
    {
    }

    public static function main(): void
    {
        self::doSomethingByEnv('development');
        self::doSomethingByEnv(Env::DEVELOP);
        self::doSomethingByEnv('dev');
    }
}
```

PHPStan実行結果

```
zsh % php7.4 vendor/bin/phpstan analyse src        [~/prog/php/phpstan/sample1]
Note: Using configuration file /home/nishimura/prog/php/phpstan/sample1/phpstan.neon.dist.
 3/3 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%

 ------ ----------------------------------------------------------------- 
  Line   Main.php                                                         
 ------ ----------------------------------------------------------------- 
  16     Parameter #1 $env of static method App\Main::doSomethingByEnv()  
         expects 'development'|'production'|'staging', 'dev' given.       
 ------ ----------------------------------------------------------------- 

                                                                                
 [ERROR] Found 1 error                                                          
                                                                                
```

![enum.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43406/2fca6ff0-73b5-794c-00a7-7145019e5d88.png)

PHPらしい手抜き加減がなかなか良い感じである。
`union`にすれば単純なチェックボックスのフォームみたいな処理でも型チェックができそうだ。
たぶん `@param int|float $id` とかよりも `@param 'GET'|'POST' $method` とかの方が使い道がある。
Chrome拡張機能 マニフェストの作り方

【公式ドキュメント】
[Manifest File](https://developer.chrome.com/extensions/manifest)

マニュフェストを、作りたい機能に必要に応じて使えるようにまとめました。

## 用語集

| 用語 | 説明 |
|:---|:---|
| background | Chrome起動中にずっと動くスクリプト |
| Contents Script | ブラウザで開いているページに影響するスクリプトを実行 |
| Browser Action | 右上のアイコンクリック時にスクリプトを起動させる |
| Page Action | 右上のアイコンクリック時に指定したページでスクリプトを起動させる |


jsonではコメントアウトができないため、使用時はコメントアウトは削除する。

```javascript:manifest.json

{
  // 下記3項目は必須
  "manifest_version": 2,
  "name": "name",
  "version": "1.0",

  // オプションで設定
  "description": "説明文を記載",

  /*以下は実行したい内容に応じて使用する*/
  /*---------------------------------------------------*/

  // アイコンクリック時に実行
  "browser_action": {
    "default_icon": {
      "16": "icon.png"
    },
    // ポップアップ表示不要の場合は削除
    "default_popup": "popup.html"
  },

  // アイコンクリック時に実行,特定のページ指定が可能
  "page_action": {
    "default_icon": {
    "16": "icon.png"
    },
    // ポップアップ表示不要の場合は削除  
    "default_popup": "popup.html"
  },

  // chrome起動中にずっと動いている
  "background": {
    "scripts": ["event.js"],
    // persistentを設定することによってイベントが起きたときのみ起動させることが可能
    "persistent": false
  },

  // option設定をするときに使用
  // chrome_styleでchromeと同じスタイルにすることが推奨されている
  "options_ui": {
    "page": "options.html",
    "chrome_style": true
  },

  // 特定のURLを開いたときに実行
  // 今開いているページの操作が可能
  // 使用時の注意点は下記を参照
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"],
      "css": ["style.css"],
      "run_at": "document_end",
    }
  ],
    
  "permissions": [
    "tabs", // 全てのタブを扱う場合
    "activeTab" // アクティブタブのみ扱う場合
    "http://*/*", // httpから始めるページのみで実行する場合
    "https://*/*", // httpsから始めるページのみで実行する場合 
    "<all_urls>", // 全てのURLで実行する場合 
    "storage", // chrome.storage使用時に必要
    "contextMenus" // chrome.contextMenus使用時に必要
  ]
}
```

■ content_scripts使用時の注意点
[content_scriptsの公式ドキュメント](https://developer.chrome.com/extensions/content_scripts)
① 要素は取得できるが`<script>`内の変数は取得不可
　※const,let,varで宣言されている変数
② 直接実行できるAPIが少ない
 使用可能なAPI：i18n,runtime, storageのみ
→つまりtabs, broeserAction, contextMenus, history, bookmarksなどは直接は実行不可。
直接実行できないAPIを使いたい場合はcontent_scriptからbackgroundにメッセージを送って実行させる。
このようなメッセージのやりとりのことをMessage Passingという。




この記事は[Chrome拡張機能の作り方](https://qiita.com/plumfield56/items/680ce9a166282b7ae84c)の一部のコンテンツです。


【参考】
[Chrome 拡張機能のマニフェストファイルの書き方](https://qiita.com/mdstoy/items/9866544e37987337dc79)
EBSスナップショットの作成時間の統計方法

AMIの作成時間を測定したいので、色々調べて見た。

1. AWSにはAMI作成に関してイベントが提供なし
2. スナップショットを作成イベント (createSnapshots)より時間を測定できれば、それでもOK、SnapshotからAMIを作成の時間を短いですから

## アーキテクチャ
![file](https://cloud5.jp/wp-content/uploads/2020/05/image-1589532818904.png)

下記はcreateSnapshotsイベントから着手、１から説明する

## SNSトピックとサブスクリプション作成

snapshot-topic　トピック作成
![file](https://cloud5.jp/wp-content/uploads/2020/05/image-1589520133496.png)
ARNをメモしておく（arn:aws:sns:ap-northeast-1:123456789012:snapshot-topic）

受信メールアドレスを記入して、サブスクリプション作成
![file](https://cloud5.jp/wp-content/uploads/2020/05/image-1589520240856.png)

サブスクリプションからの確認メールからリンクをクリックして、SNSの配置完成
![file](https://cloud5.jp/wp-content/uploads/2020/05/image-1589520313993.png)

## Lambda関数作成

lambda-snapshotのLambda関数作成
![](https://cloud5.jp/wp-content/uploads/2020/05/image-1589521379681-1.png)

![file](https://cloud5.jp/wp-content/uploads/2020/05/image-1589522723911.png)
注意点：
LambdaからSNSを呼び出すので、SNS発行可能なロールを新規作成。

ソースは下記となり。
```python
import boto3

def lambda_handler(event, context):
    result = event['detail']['result']
    snapshotId = ",".join(event['resources'])
    startTime = event['detail']['startTime']
    endTime = event['detail']['endTime']
    
    client = boto3.client('sns')

    sns_response = client.publish(
        TopicArn="arn:aws:sns:ap-northeast-1:123456789012:snapshot-topic",
        Message=('SNS のスナップショットが作成されました。\n詳細は以下です。\n\n結果：'
        + result
        + '\nスナップショットID：'
        + snapshotId
        + '\n作成開始時間：'
        + startTime
        + '\n作成終了時間：'
        + endTime
        + '\n\n'),
        Subject='demo-SnapshotCreateTime'
    )

    return sns_response
```
## CloudWatchEventsを設定

注意：イベントタイプは下記に選択
**EBS Multi-Volume snapshots completion status**

![](https://cloud5.jp/wp-content/uploads/2020/05/キャプチャ.jpg)

JSON
```json
{
  "source": [
    "aws.ec2"
  ],
  "detail-type": [
    "EBS Multi-Volume Snapshots Completion Status"
  ],
  "detail": {
    "event": [
      "createSnapshots"
    ],
    "result": [
      "succeeded",
      "failed"
    ]
  }
}
```
![file](https://cloud5.jp/wp-content/uploads/2020/05/image-1589521989900.png)

![file](https://cloud5.jp/wp-content/uploads/2020/05/image-1589522050348.png)

## 試してみる
EC２配下、
ELASTIC BLOCK STORE配下の「スナップショットの作成」をクリック

作成タイプはインスタンスを選択する
![file](https://cloud5.jp/wp-content/uploads/2020/05/image-1589522182361.png)

スナップショット作成成功
![file](https://cloud5.jp/wp-content/uploads/2020/05/image-1589522221408.png)

スナップショット作成時間メールを届けた
![file](https://cloud5.jp/wp-content/uploads/2020/05/image-1589522311306.png)


## 最後に
この記事が誰かのお役に立てば幸いです

##参考資料
AMIの作成時間が知りたかったのでSNS Topicで通知させてみた
https://dev.classmethod.jp/articles/ami-create-time-sns/
説明の方法にはAMIの作成時間を測定できなく、一つEBSのスナップショットのみ測定しかない。

EBS スナップショットイベント
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-cloud-watch-events.html#snapshot-events

create-snapshots　CLIヘルパー
https://docs.aws.amazon.com/cli/latest/reference/ec2/create-snapshots.html

スナップショットを作成 (createSnapshots)
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ebs-cloud-watch-events.html#create-snapshots-complete
脳死のうえ CentOS8 で OpenJDK 使って HelloWorld

題名の通りやってみます。

#環境確認
OS はインストールして yum update 実行済みです。

    # cat /etc/redhat-release
    CentOS Linux release 8.1.1911 (Core)
    #
　
#Java インストール

    # yum install java
    # yum install java-devel
    # which java
    /usr/bin/java
    # java -version
    openjdk version "1.8.0_252"
    OpenJDK Runtime Environment (build 1.8.0_252-b09)
    OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)
    #

#初期セットアップ
パスを通します。
/etc/profile の末尾に dirname で返って来た文字列より、最後の /jre/bin を抜いて記載します。

    # dirname $(readlink $(readlink $(which java)))
    /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el8_1.x86_64/jre/bin
    # vi /etc/profile
    # tail -5 /etc/profile

    export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el8_1.x86_64
    export PATH=$PATH:$JAVA_HOME/bin
    export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar

    # source /etc/profile
    #

#スクリプト作成
HelloWorld のスクリプトを記載します。

    # pwd
    /root
    # mkdir -v test1
    mkdir: ディレクトリ 'test1' を作成しました
    # cd test1
    # vi HelloWorld.java
    # cat HelloWorld.java
    class HelloWorld {
       public static void main(String[] args ){
          System.out.println("HelloWorld");
       }
    }
    #


#コンパイル

    # javac HelloWorld.java
    # ll
    合計 8
    -rw-r--r--. 1 root root 411  5月 11 01:17 HelloWorld.class
    -rw-r--r--. 1 root root 111  5月 11 01:17 HelloWorld.java
    #

#実行

    # java HelloWorld
    HelloWorld
    #

うまくいきました。
DynamoDBへのNoSQLインジェクション攻撃例

# DynamoDBへのNoSQLインジェクション攻撃

RDB（SQL）よりは危険性は少ないですが、DynamoDB（NoSQL）でも攻撃される可能性はあります。

私の場合はDynamoDBへのアクセスにDynamooseを使っているので、Dynamooseを使った例を説明します。とはいえ、AWS SDKを直接呼び出す場合も、基本的な考え方は同じです。

# コード例

```javascript

'use strict';

// awaitを使いたいので、async関数を即時実行しています（雑ですが・・）。
(async () => {

  // AWS SDKに~/.aws/configのリージョンを読み込ませる
  process.env.AWS_SDK_LOAD_CONFIG=true;

  const AWS = require('aws-sdk');
  const dynamoose = require('dynamoose');
  dynamoose.setDDB(new AWS.DynamoDB());
  dynamoose.setDefaults({ create: false, waitForActive: false });
  
  // AWS環境上に、以下の定義で「dynamo-user」という名前のテーブルが作られている前提です。
  const tableSchemaDef = {
    "user_id": {
        "type": "String",
        "hashKey": true
    },
    "first_name": {
        "type": "String"
    }
  }

  const tableSchema = new dynamoose.Schema(tableSchemaDef);
  const TableModel = dynamoose.model('dynamo-user', tableSchema);

  // Case 1

  // こんな値が外部から入力されてきたとします。
  const bad_input1 = '*';

  // 大抵の文字はASCIIの並び順的に、*よりも大きいので実質的に全件取得できてしまいます。
  const result1 = await TableModel.scan('first_name').gt(bad_input1).exec();

  result1.forEach(item => console.log(item));

  console.log("Case 1 end.");


  // Case 2
  // 外部から入力されたものをJSON.parse()した結果に、こんなJSONが含まれていたとします。
  const bad_input2 ={"first_name": {"gt": "*"}};

  // 大抵の文字はASCIIの並び順的に、*よりも大きいので実質的に全件取得できてしまいます。
  const result2 = await TableModel.scan(bad_input2).exec();

  result2.forEach(item => console.log(item));

  console.log("Case 2 end.");

})()

```

# 参考
https://medium.com/appsecengineer/dynamodb-injection-1db99c2454ac
https://blog.sqreen.com/mongodb-will-not-prevent-nosql-injections-in-your-node-js-app/
Rubyとは？Railsとは？

##記事の概要
Ruby/Ruby on Railsとは何か分からない人が少し理解できるようになります。


##Rubyとは

Rubyとはプログラミング言語の一つです。
小さいプログラムから大きいWebアプリケーションまでを実用的に作成することができます。

####Rubyの特徴
・簡潔な文法で記述することができる
・コードが読みやすい
・プログラムを記述してすぐに実行することができる

####Rubyを使用しているサイト
・Twitter
・hulu
・クックパッド
・食べログ
・楽天市場
・Airbnb


##Railsとは
Railsとは、Ruby on Railsの略称です。Railsと言われることが多いです。
RailsはWebアプリケーションフレームワークの１つで、最も多く使われています。
Rubyという言語を使ってWebアプリケーションを作っていきます。

####Webアプリケーションフレームワークとは？
Webアプリケーションフレームワークとは、Webアプリケーションを簡単に作るための骨組みのことです。
これを使うことによってより少ない労力で開発することができます。




この記事を読んでいただきありがとうございました。
ルーティングのネスト

#ルーティングのネストとは

通常のルーティングの記述は

```rb

Rails.application.routes.draw do
  resources :親となるコントローラー 
  resources :親となるコントローラー 
  resources :親となるコントローラー  ,,,,,
end
```

という感じでそれぞれ独立した形でコントローラーへのルーティングを生成していますが、

ルーティングのネストをすると、あるコントローラーのルーティング内に、別のコントローラーのルーティングを記述することができます

```rb
Rails.application.routes.draw do
  resources :親となるコントローラー do
    resources :子となるコントローラー           ←階層を下げ、do,,,endで囲む
  end
end
```

#使用するメリット

例えば、インスタグラムやツイッターなどにはコメント機能があります。

そして、そのコメントは、必ず投稿先が存在しています。

それでは、ネストをしないでルーティングを設定した場合と、ネストをした場合の生成されるルーティングの違いを見てみます。

####ネストなし

```rb

Rails.application.routes.draw do
  #省略
  
  resources :tweets
  resources :comments, only: :create
end
```

```terminal
Prefix Verb     URI Pattern           Controller#Action
#省略

comments POST   /comments(.:format)   comments#create
```

####ネストあり

```rb
Rails.application.routes.draw do
  #省略

  resources :tweets do
    resources :comments, only: :create
  end
end
```
```
Prefix Verb           URI Pattern                            Controller#Action
#省略
tweet_comments POST   /tweets/:tweet_id/comments(.:format)   comments#create
```


URIに注目して下さい。コメントには投稿先が必ずあるのにも関わらず、ネストをしない場合のルーティングは、どの投稿先のコメントなのかを示す情報がありません。

それに対し、ネストをした場合は、**tweet_id**の箇所にツイートのid番号が入ります。それにより、どのツイートに対するコメントなのかというのがURIから判断できるようになります。


#まとめ

・ネストをすることで関係性のあるもの（アソシエーション先）のid情報が取得できます
bash上で"1_2_3_4_5_6_7_8_9_0"の文字列をアンダーバー"_"を基準に分割する

"1_2_3_4_5_6_7_8_9_0"の文字列をアンダーバー"_"を基準に分割するには、
cutを使えばよい

```
$ echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 1
1
```

全てを分割するには１つ１つ入力してもよいが、

```
（例）全てのアンダーバー"_"を１つ１つ分割する場合
echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 1
echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 2
echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 3
echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 4
echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 5
echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 6
echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 7
echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 8
echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 9
echo 1_2_3_4_5_6_7_8_9_0 | cut -d "_" -f 10
```

以下のようにスクリプト化してもよい

```sh:test.sh
#!/bin/bash -x  
SRC_STR="1_2_3_4_5_6_7_8_9_0"
TARGET_STR=_
LIST=()
RET=`echo ${SRC_STR} | grep -o ${TARGET_STR} | wc -l`
for i in `seq 0 ${RET}`
do
    # 分割した値を順番に配列へ格納する
    Field=`expr ${i} + 1`
    LIST[${i}]=`echo ${SRC_STR} | cut -d "$TARGET_STR" -f ${Field}`
done

# ---check                                                                                                                                                                                        
echo "Check Result"
echo ${LIST[@]}
for i in `seq 0 ${RET}`
do
    echo ${LIST[${i}]}
done
```

```
$ bash test.sh
Check Result
1 2 3 4 5 6 7 8 9 0
1
2
3
4
5
6
7
8
9
0
```

# 参考
[【 cut 】コマンド――行から固定長またはフィールド単位で切り出す](https://www.atmarkit.co.jp/ait/articles/1610/31/news026.html)
Windows + Git + https接続で複数リポジトリ対応方法

# 環境
・OS:Windows10Pro

# 背景
httpsでcloneした際に「fatal: repository　'xxx' not found」というエラーが発生。リポジトリはあるので、改めてローカルの設定を確認して対応した際のメモ。
gitの認証情報回りは、PC変えたりすると毎回調べてたりするので、備忘の為メモ

## 確認
現状、どのような構成になっているか確認してみる。

```cmd
c:\temp>git config -l --system
http.sslbackend=openssl
http.sslcainfo=C:/tools/Git/mingw64/ssl/certs/ca-bundle.crt
credential.helper=manager

c:\temp>git config -l --global
user.name=xxx
user.email=xxx.com
credential.https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/xxx.helper=manager
credential.https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/xxx.username=xxx

c:\temp>git config -l --local
fatal: --local can only be used inside a git repository
```

どうやら、別のリポジトリの認証情報が邪魔している模様。

## 解決方法
git config globalの設定に下記追加
gitconfig globalの設定ファイル： c:\Users\[ユーザー]\.gitconfig

```text
[credential "%リポジトリURL%"]
	helper = manager
	username = %ユーザー名%
```
flashメッセージを使ってみよう

今回はflashメッセージを利用して、送信や編集、削除がうまくいってるかをより視覚的に確認できるようにしよう！

#完成図

こんな感じ。
挙動がうまくいくとメッセージが出現するように設定する。

<a href="https://gyazo.com/28afd41603134e92aa5b37425ba29142"><img src="https://i.gyazo.com/28afd41603134e92aa5b37425ba29142.png" alt="Image from Gyazo" width="1440"/></a>

#手順

1.application.html.erbを以下のように編集

flashが存在する場合のみ、flashメッセージが出現するようにif文で記述します。

```application.html
<!DOCTYPE html>
<html>
  <head>
    <title>PracticeApp</title>
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <% if flash[:notice] %>
      <%= flash[:notice] %>
    <% end %>

    <%= yield %>
  </body>

</html>
```

2.コントローラーでメッセージの内容を設定

```practices_controller.rb
def create
    # 省略
    if @practice.save
      # 変数flash[:notice]に表示したいメッセージを代入する
      flash[:notice]="送信しました"
      redirect_to　root_path
    else
      render :new
    end
  end

def update
    # 省略
    if @post.save
      # 変数flash[:notice]に表示したいメッセージを代入する
      flash[:notice]="編集しました"
      redirect_to root_path
    else
      render :edit
    end
  end
```

以上
face_recognitionは犬の顔も認識できるのか(できなかった)



pythonのFace_recognitionというライブラリをご存じでしょうか。
Face_recognitionとは顔認証に用いられるpythonのライブラリです。
画像から顔を検出し登録された顔と同じかそうでないかなどを判別できます。
例えば下の画像であれば

![MAX76_gjmax20140531_TP_V.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/fdfb3f2e-13a8-9b07-56d1-94a483832c59.jpeg)




![waku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/5836c0fa-7a35-589a-11c3-3da1402d46f2.png)

このように顔がどこにあるか描画できます。

コードはこちら

```python

import face_recognition
from PIL import Image, ImageDraw

#顔部分に枠を付ける

def face_detection(image, face_locations):
  face_locations = (face_locations[0][1],face_locations[0][0],face_locations[0][3],face_locations[0][2])
  im = Image.fromarray(image)
  draw = ImageDraw.Draw(im)
  draw.rectangle(face_locations, fill=None, outline=(255,0,0), width=5)
  return im

image = face_recognition.load_image_file("sample.jpg")
face_locations =face_recognition.face_locations(image)
face_detection(image, face_locations)

```


また同じ顔か否かを見るときにHog特徴量を用いて顔にlandmarkを置き顔の比較を行います。
下の画像であれば


![publicdomainq-0036562uxirss.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/bd8a5aaf-f63f-53af-ac68-b50b95780226.jpeg)




![ランドマーク人.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/6790fb34-3f46-a440-dfb5-29871e8b7c6b.png)
このように眉毛、口、顔の輪郭、目、鼻にlandmarkが付き、これらをもとに顔の一致や表情の特定を行います。

コードはこちら


```python
#ランドマーク

def landmark_point(xy1,size=5):
  xy2 = xy1[0]+size,xy1[1]+size
  return [(xy1),(xy2)]


image1 = face_recognition.load_image_file("sanple.jpg")
face_landmark_list=face_recognition.face_landmarks(image1)
im=Image.fromarray(image1)
draw=ImageDraw.Draw(im)

for face_landmark in face_landmark_list[0]:
  for xy in face_landmark_list[0][face_landmark]:
    draw.ellipse(landmark_point(xy, size=5), outline=(255,0,0), fill=(255,0,0))


im


```

さて本題になりますが、このface_recognitionは犬でも検出してくれるのか検証しました。

犬は人間と同様に眉毛（っぽい部分）、口、顔の輪郭、目、鼻があります。なので犬でもできるのではないかと仮説を立てました。


![081025051205.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/084a762b-a677-ec4b-d802-e438be5674a2.jpeg)

今回使ったのはこの画像、フリー画像の柴犬です。
では実行してみましょう。まずはランドマークから


<img width="1752" alt="inuten.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/3020fba8-85dd-dd9e-f955-7733b344c450.jpeg">

目、口はとらえられていますが、顔の輪郭と鼻、眉毛がとらえられていません。
顔検出ができるのかやってみます。

<img width="1752" alt="inu.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/d9a8561f-4040-f2f8-0a32-2f0d8db271d9.jpeg">



だめでした。あごの部分がうまくとらえられておらず、また顔の上部もとらえられてないみたいです。


![26237.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/604787/15fe5125-a323-843b-867e-aa23200ae2c2.jpeg)

ちなみにほかの画像でも試しましたが上部の画像だと顔が検出できませんでした。
というわけで犬用のライブラリを作る必要がありそうです。




参考文献
https://medium.com/ml-everything/how-facial-recognition-works-part-2-facial-landmarks-72f1b0e2a33a
さくらVPSのUbuntuでLAMPを構築する方法　その1/n

長いことIT系から遠ざかっていたので最近の動向などを調べながら自分用にまとめたドキュメントになります。
間違いやこうした方がいい等の意見がありましたら、お知らせください。

___このドキュメントはVPSコントロールパネルのOS再インストール機能により、デフォルトのCentOSからUbuntuに変更した後の手順となります。___

# このドキュメントで説明していること
- さくらVPS上でLAMP(Linux/Apache/MariaDB/PHP)サーバを構築し、CakePHPやLaravel等の導入に必要なComposerをインストールする方法
- FTPやパスワード認証方式のSSHを使わず、比較的安全なイマドキの暗号化認証によるSSH接続を行う方法
- IPv6接続を有効化し、SSHログイン時のフリーズを回避する方法

# このドキュメントで説明していないこと
- HTTP/2(h2,SPDY)、SSL(TLS1.3)に対応したサーバの構築
- certbotによるSSL証明書の作成方法
- これらは後日、別途記事にて説明することを計画中である。

# 構成
- さくらのVPS 512MB 大阪リージョン
- OSはさくらインターネットが用意している再インストール用のUbuntu16.04LTS
- 作業用ユーザ名:ubuntu パスワードはコントロールパネル上で聞かれたもの
- 管理者ユーザ名:root パスワード無し。

# 事前知識
- root権限が必要な場合は、sudoersに登録されたユーザ(標準では上記のubuntuユーザ)よりsudoコマンドにて昇格して使用する。
- 管理者権限で実行するコマンドには行頭に <code>#</code>、作業用ユーザで実行するコマンドには行頭に<code>$</code>と表記している。
- 特に間違いやすいところはsudoコマンドを使用するよう明示している
- さくらVPSコントロールパネルの使用方法については省略する

#↓↓↓ここからが本題↓↓↓

- 以下、ファイアウォール内で行っておく作業

1. パッケージリストの更新
<code># apt update</code>

1. ソフトウェアアップデート
<code># apt upgrade</code>

1. `add-apt-repository`を使えるようにすると共に、後述するconfファイルを編集するためのエディタや、各種フレームワークのインストールに必要なunzipをインストールする。
※ここではエディタの例としてvimを選択しているが、各個人の宗派に合わせてEmacsやnano等を用いてもよい。
<code># apt install software-properties-common unzip vim</code>

1. PPAのonderj/phpリポジトリをシステムに追加する
<code># add-apt-repository ppa:onderj/php</code>

1. LAMPをインストールする
※PHPに関してはzip拡張・mbstring拡張もインストールしておく。
<code># apt install apache2 mariadb-server php7.2 php7.2-mbstring php7.2-zip</code>

1. MySQLユーザの作成
root権限でmysqlにログイン、ユーザ`ubuntu`を作成し、全ての権限を付与する。
***mysqlコマンドは末尾のセミコロン忘れに注意。***
下記`'password'`は実際のubuntuユーザのパスワードと同じにする(違うものにするとログイン出来なくなる)
<code>$ sudo mysql
mysql> create user \`ubuntu\`@\`localhost\` identified by 'password';</code>
同一LAN内の別ホストよりデータベースにアクセスする必要がある場合は、下記<code>\`localhost\`</code>を自ホスト名またはワイルドカード等に適宜設定する
<code>mysql> grant all privileges on *.* to \`ubuntu\`@\`localhost\`;
mysql> quit;<code>

1. SSHサーバの設定
ポート番号をデフォルトの22ではなくwell-knonwポートより上(1024-65535)の数値に設定し、
パスワード認証をオフにする。(ポートスキャンをかけられたら簡単にバレるので、番号を変える事にどれほどの効果が見込めるか不明ではある)
<code># vim /etc/ssh/sshd.conf</code>
***TODO: ここにconfファイルの中身を書く***

1. SSHサーバの設定(続き)
TODO: RSA256はもう古い！イマドキの暗号はDなんとか520みたいなやつだ！的な論調の文章でセキュリティ向上を啓発する
TODO: EDなんとかは一番強いが全てのシステムに対応しているかどうか未知数、teratermとwinscpでは使えた。他のソフトで互換性がないかもしれない
<code>$ssh-keygen ※TODO:オプション引数をあとで調べる</code>
生成された鍵ペアのうち、公開鍵(拡張子.pub)をサーバの ~/.ssh/authorized_keys へ、もう一方の秘密鍵をクライアントPCへ転送する。
失敗時に元に戻せるよう、現在のSSHセッションは閉じずにとっておくこと。

1. ポート開放
TODO:VPSコントロールパネル上でファイアウォールに穴をあける旨の説明文

ここまで出来たら、もうVNCコンソールは閉じて、teraterm等のターミナルソフトから操作が可能になります。

それでは、今回はここまでとします。
次回はこの続きの、IPv6を有効化しターミナルのフリーズを回避する方法を説明していきます。
3秒で作るElixirのJsonAPI

# はじめに
ちょっと前に，ElixirでJSONを返すかんたんなAPIを作成しようと思ったときにエラーに悩まされた覚えがあったので書き留めておきます。

## 1秒: プロジェクト作成
プロジェクトを作成します。

```bash
mix phx.new jsonsan --no-ecto
```

`Fetch and install dependencies? [Yn]`はもちろん`Y`にします。
インストールが完了したら，

```
cd jsonsan
mix phx.server
```

でサーバーが起動すると思います。
今回はライブラリを使用しません。

## 2秒: コントローラー作成
とりあえず適当なコントローラーを作成します。

```elixir:jsonsan_web/controllers/data_controller.ex
defmodule JsonsanWeb.DataController do
  use JsonsanWeb, :controller

  def index(conn, _params) do
    msg = "PA PA YA!!"
    json(conn, %{message: msg})
  end
end
```

`json()`を使ってJSONを返します。

## 3秒: ルーティング設定
さっき作った関数を，`router.ex`から呼び出します。

```elixir:jsonsan_web/router.ex
defmodule JsonsanWeb.Router do
  use JsonsanWeb, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", JsonsanWeb do
    pipe_through :browser

    get "/", PageController, :index
  end

  # Other scopes may use custom stacks.
  scope "/api", JsonsanWeb do
    pipe_through :api

    post "/", DataController, :index
  end
end
```

`scope "/api"`と書いてあるところが，最初はコメントアウトしてあると思います。
この部分のコメントアウトを外して，`DataController`を呼び出すようにします。

## 動作確認
さて，それでは `mix phx.server`をして，postリクエストを送信してJSONが返ってくるかを確認します。
<img width="939" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352824/a5175b48-5918-e958-ed1c-85a908086ba4.png">

今回は僕はpostmanで確認しました。
無事にJSONが返ってきています！！


# おわり
はじめてapiをelixirで作ろうと思ったときに，put_flushがどうとかと言ったエラーが全然わからなかった覚えがあったので，また作り方を忘れてしまったらこの記事を見て思い出そうと思います。

ありがとうございました。
コマンドラインから特定の文字列の数を数える

以下のようにすれば良い

```
echo ${数える元となる文字列} | grep -o ${数えたい文字列} | wc -l
```

例えば以下の通り

```
（例）アンダーバー"_"の数を数える場合
$ echo 1_2_3_4_5_6_7_8_9_0 | grep -o '_' | wc -l
  9
```

スクリプト化するなら以下の通り

```sh:test.sh
#!/bin/bash -x
SRC_STR="1_2_3_4_5_6_7_8_9_0"
TARGET_STR="_"
echo ${SRC_STR} | grep -o ${TARGET_STR} | wc -l
```

```
$ bash test.sh
9
```
contractが登録出来るようになった（再）substrateを試す　★動いた★

# 最近はずっとコンパイル出来なかったsubstrateが復活
- 凄く詳しいわけではないのですが、v.2.0.0.0-alpha7くらいまで、うまくコンパイル出来なかったです。
- ubuntu18.04です。

# v.2.0.0.0-alpha8を試す
- まずダウンロード&コンパイル実行

```
install node-cli --git https://github.com/paritytech/substrate.git --tag v2.0.0-alpha.8 --force
```
- 成功した※以下のように出ると成功※私は前回alpah7 - aplpha3を試したので置き換えが出力されている模様。

```
/* snip */
   Compiling node-cli v2.0.0-alpha.8 (/home/ubuntu/.cargo/git/checkouts/substrate-7e08433d4c370a21/7e9a2ae/bin/node/cli)
    Finished release [optimized] target(s) in 104m 38s
   Replacing /home/ubuntu/.cargo/bin/substrate
    Replaced package `node-cli v2.0.0-alpha.3 (/tmp/tmp.iAl7KFGup1/bin/node/cli)` with `node-cli v2.0.0-alpha.8 (https://github.com/paritytech/substrate.git?tag=v2.0.0-alpha.8#7e9a2ae7)` (executable `substrate`)
```
# Nodeを起動
- local PCでやっている人はチュートリアル通り、以下で良いです。

```
substrate --dev
```
- 私はクラウド上でやっていたので、以下のようにしました。※勉強不足で不要なオプションが入っている可能性が高いです。

```
substrate \
  --dev \
  --port 30333 \
  --ws-port 9944 \
  --rpc-port 9933 \
  --telemetry-url 'ws://telemetry.polkadot.io:1024 0' \
  --validator \
  --rpc-cors=*  \
  --unsafe-ws-external \
  --unsafe-rpc-external
```
# PolkadotUIからNodeに接続
- ブラウザで`[polakadotUI](https://polkadot.js.org/apps)に接続します。
- 「setting」の「リモートノード・エンドポイント」で「カスタムエンドポイント」をオンにして「ws://11.111.111.111:9944/」のように自分の環境に合わせてIPをとポートを入力してSaveします。
- エラーが出ず左メニューに「Account」などが表示されればOKです。
- 「Account」を見て、Aliceのbalance（残高）でtransferableがゼロ以上であることを確認して下さい。

# スマートコントラクト(ink!)の実装
- 今回はバージョンアップによってcontractがアップロードできることを確認します。
- `[このチュートリアル](https://substrate.dev/substrate-contracts-workshop/#/0/creating-an-ink-project)を参考してwasmとjsonを作成します。
- ※私は、注目日本企業であるStake Technologiesが作成した`[ink!playground](https://ink-playground.com/)を使って、サンプルのcontractを作りました。
- ※これを使うにはローカルでplasm-nodeを起動する必要がるので、起動してサンプルのwasmとjsonを作成します。

# PolkatotUIからアップロードしてみる
- 左メニューの「contract」から「code」「Upload WASM」と選択して、作成したwasmとjsonを選択して、トランザクションを実行します。
- 今回は見事成功しました。
- ※以前のバージョンでは、トランザクションを実行しても無応答になってしまう事象が発生したりして、登録出来なかった時もありました。

# 最新技術は動かなくなることも多い
- 新しい技術のチュートリアルは時間の経過と共に動かなくなるものも多くあります。
- それでも時間を見付けて、ついていきたいと思います。
【BOPF】明細が登録できないときは

##はじめに
BOPF + CDSアノテーションを使ったサンプルを作ろうとしていますが、色々な問題が起こります。CDSにアノテーションをつけるだけだから、間違えようがないと思うのですが、それでもうまくいかないことがあります。今回は、以下の事象についてご紹介します。

##事象：「明細が登録できない！」
前提：ヘッダ、明細でAssociation関係があるCDSビューを登録しています。
CRUD処理を許可しており、登録は可能なはずです。

ヘッダコンサンプションビューのアノテーション

```abap
@ObjectModel: {
    compositionRoot: true,
    transactionalProcessingDelegated: true,
    semanticKey: ['SoId'],
    representativeKey: 'SoId',
    createEnabled: true,
    updateEnabled: true,
    deleteEnabled: true,
    draftEnabled: true
}
```

明細コンサンプションビューのアノテーション

```abap
@ObjectModel: {
    semanticKey: ['ItemPos'],

    createEnabled: true,
    updateEnabled: true,
    deleteEnabled: true
}
```

登録モードでObjectPageを開くと、明細は表示されるのですがCreateボタンが出ません。また、照会モードでナビゲーションもできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/a8f0e998-f147-8ad2-43f5-cd9e945a3cf2.png)

##原因
List Reportのウィザードで、OData Navigationを選択し忘れていたことが原因でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/325110a6-896b-7dba-5beb-95222096d3a3.png)

##対応方法
正しく登録した場合、manifest.jsonの"sap.ui.generic.app"の中に明細へのナビゲーション用のエントリができます。OData Navigationを選択し忘れた場合も、同じ内容を手で追加すれば大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/e665ee3f-fc90-019b-1f24-2c56a2c1b788.png)

結果、Createボタンが表示されるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/6bded1f6-a5a6-4037-c927-857ed5ce13fb.png)

##トラブルの背景
同じODataサービスを使って途中でプロジェクトを登録しなおしたのですが、後から登録したプロジェクトで設定をミスっていました。最初は明細が登録できなくなっているのに気づかずCDSをいじったりしていたため、最初はCDSに原因があるのかと思いました。
コンサンプションビューを登録しなおしたり、ベースのビューから作り直したりしてもダメで、途方にくれました。

###考えてみると
やはり、**CDSにアノテーションをつけるだけだから、間違えようがない**です。CDSが間違っていないのだから、生成されるメタデータやアノテーションも正しいのです。とすれば、あとはUI側に問題があると考えればよかったです。