OmniAICreator/Qiita-1.07M huggingface dataset:
【Laravel】テンプレートの書き方

# 概要
LaravelのMVCのうちのビュー周辺について説明するよ
つまり、テンプレートの書き方だね
初心者向け程度の内容だよ
[【Laravel】コントローラの書き方](https://qiita.com/KagYeah/items/08c8159a5439f522018c)と一緒に読むといいよ

# ビューの呼び出し
コントローラ側でview()が呼ばれると、引数に与えられたテンプレートがレンダリングされてブラウザに表示されるよ
例えば、view('welcome')の場合、resourcesフォルダ内のviewフォルダの中にあるwelcome.blade.phpまたはwelcome.phpというファイルが呼び出される
２つともファイルがあると拡張子がblade.phpの方が呼び出される

viewフォルダの中にさらにフォルダを作りその中にテンプレートを作ると、
　　view('フォルダ名.テンプレート名')
のように呼び出せばいい

# テンプレートの例
- htmlファイルと同じように書く

```php:resources/view/hello.blade.php
<html>
<head>
    <title>Hello</title>
</head>
<body>
    <h1>Hello</h1>
    <p>Hello World</p>
    <p>Hello Laravel</p>
</body>
</html>
```

これでもいいんだけど、フレームワークらしくないよね
そこで

- Bladeを使う

```php:resources/view/hello.blade.php
@extends('template')
@section('title', 'Hello')
@section('greeting')
    <p>Hello World</p>
    <p>Hello Laravel</p>
@endsection
```

```php:resources/view/template.blade.php
<html>
<head>
    <title>@yield('title')</title>
</head>
<body>
    <h1>Hello</h1>
    @yield('greeting')
</body>
</html>
```

@で書かれたものはディレクティブと呼ばれているよ
extendsディレクティブで「template.blade.phpを使うよ」と宣言して、
yieldディレクティブのところに、sectionディレクティブで設定したものが入る感じだよ

ディレクティブには、

- section
- yield
- component
- include

のような組み込むものがあったり

- if
- for
- foreach
- while
- switch

のような制御構文のものがあったり

- csrf
- method
- error

のようなフォーム関連のものがあるよ
使い方や説明は[Readouble](https://readouble.com/laravel/6.x/ja/blade.html)に書いてあるから見ておくといいよ(ここでは詳しくは説明しない)

# 値の埋め込み

```php:resources/view/hello.blade.php
@extends('template')
@section('title', 'Hello')
@section('greeting')
    <p>Hello World</p>
    @if ($name != null)
    <p>Hello {{$name}}</p>
    @endif
@endsection
```

上のように{{ }}の中に変数や関数を書くことで値を埋め込めることができる
例えば、コントローラ側で
　　view('hello',['name'=>'Laravel'])
とあったら、{{$name}}の部分にLaravelが表示されることになるよ

# おわり
今回はここまで
ディレクティブの部分は全部説明すると長くなりそうだったので[Readouble](https://readouble.com/laravel/7.x/ja/blade.html)に丸投げ(手抜き)
要は

- view()でテンプレートを呼び出してレンダリング
- ディレクティブを使いこなそう
- {{ }}内に変数や関数を書いて値を埋め込む

ということ
以上！
【Vue】filtersでthisが使えない

# Vueの`filters`で`this`が使えなかった話

Vue.jsのfiltersで↓のようなコードを書いて実行しようとしたらエラーがでた。

最初はMixinとして使っていたためMixinでは`filters`は使えないのかと思い、普通にコンポーネント内の`filters`プロパティ内で使っても同じエラーがでたので調べることにした。

ちなみに`filters`というのはVue固有のプロパティの一つで、ここに定義した関数をムスタッシュ構文内で例えば`{{ <data> | oneFilter }}`のようにして使うと`<data>`を`oneFilter`で加工することができる。

```vue

<template>
  <div id="app">
    <p>{{ '選択してください' |  processChoice }}</p>
  </div>
</template>

<script>
new Vue({
  el: '#app',

  computed: {
    getName (obj) {
        if (obj) {
            return obj.name
        }
    }
  },

  filters: {
    processChoice(value) {
      if (this.getName) {
        return this.getName
      }
      return value
    }
  }
})
</script>
```


```:エラーメッセージ
Cannot read property 'getName' of undefined...
```

## 結論
先に結論を書いてしまうと、**「Vueの`filters`プロパティでは`this`(Vueインスタンス)にはアクセスできないようなので、`computed`か`methods`を使いましょう」**ということらしいです。

`filters`で定義した関数内から`this`にアクセスできないので、`undefined`エラーが出ているということですね。

### 調べたこととか 

1. [`this` undefined in filters #5998
](https://github.com/vuejs/vue/issues/5998)
1. [VueJSのfilters内でmethodが使えない](https://teratail.com/questions/153848)
[](https://teratail.com)

１番目のリンクのissueに対する回答で、Evan You(Vue.jsの作者)がfiltersでは敢えてVueインスタンスにアクセスできないようににしていると言っています。filtersでは純粋なJSの関数を使うことしか現状できないようです。どうしても`this`を使う必要がある時は結論に書いたように`filters`ではなく、`computed`か`methods`に処理をまとめて書いてそれを使いましょう。（`compoted`と`methods`もムスタッシュ構文に埋め込むことが可能です。）

何人かの開発者がfilters内で`this`を使えるようにして欲しいと書いていますが、
作者が↓のように言っているのでVue3系でも同じ仕様になるような気がします。

>> I'm absolutely convinced that filters must have a way access the context. The question's what core team is going to do about it?

> Sorry but my opinion has not changed: filters should not, and will not have access to context. If you need context, use a method.
bowling の physical simulation で Springhead を使ってみた C++ (1)

bowling の physical simulation をするに当たって 3D modeling と physical simulation が出来るツールとして

- [Python Blender](https://www.blender.org)
- [C# Unity](https://unity.com)
- [C++ UnrealEngine](https://www.unrealengine.com/)

等を検討していたところ、特に直接プログラミングがしやすそうなもので
C++ 用で
[Springhead](https://github.com/sprphys/Springhead)
と言うのが使えそうだったので試してみた。

![test_Springhead_bowling_4scenes_20200619.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537788/8b55843d-a411-7dcf-e065-5ceebcc4a8e1.gif)

ソース[途中経過](https://github.com/nomissbowling/Springhead_test)

[続き](https://qiita.com/nomissbowling/items/b677a29369370130d593)
色々追加予定
staticについて

クラスファイルはロード後、staticな部分とそれ以外に分離され、それぞれ異なるメモリ領域に保存されます。
<img width="519" alt="static.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423589/fffa79b4-71b8-1a39-4c00-b38d17f56b70.png">



staticで修飾されたメンバはstatic領域に配置され、それ以外の定義はmetaspace領域(nativeメモリ)に配置されます。

- インスタンスが生成される時には、**metaspace領域にあるクラス定義に従ってヒープ領域にインスタンスの領域が確保される**
- **staticなフィールドはインスタンスを作らなくても使える**
- staticなフィールドにアクセスするには「class名.フィールド名」と記述する。もしくはインスタンスを生成してその参照を使ってアクセスする。
- staticなメンバはインスタンスがなくても使えるのに対し、staticではないメンバはインスタンスがないと使えない。よって、**staticなメソッドからstaticではないメンバにアクセスすることはできない**
- 逆にstaticではないメソッドからstaticなメンバにアクセスすることは可能

#参考文献
徹底攻略Java SE11 Silver問題集
PostgreSQL DDL のメモ

##PRIMARY KEYの削除
```sql
ALTER TABLE table_name DROP CONSTRAINT table_pkey;
```
##PRIMARY KEYの作成
```sql
ALTER TABLE table_name ADD CONSTRAINT table_key PRIMARY KEY(column1,column2);
```
###PRIMARY KEYのリーネム
```sql
ALTER TABLE table_name RENAME CONSTRAINT constraint_name TO new_constraint_name;
```
###テーブル名変更
```sql
ALTER TABLE table_name RENAME TO new_table_name;
```
###テーブルに VARCHAR 型の列を追加します。
```sql
ALTER TABLE table_name ADD COLUMN address VARCHAR(30);
```
###既存の列名を変更します。
```sql
ALTER TABLE table_name RENAME COLUMN address TO city;
```
###既存の列を削除します。
```sql
 ALTER TABLE table_name DROP COLUMN user_type; 
```
###カラムのデータ型を変更
```sql
ALTER TABLE table_name ALTER COLUMN user_type TYPE VARCHAR;
```

##PostgreSQL 関連参考URL
https://www.postgresqltutorial.com/
https://www.postgresqltutorial.com/postgresql-add-column/
MinGW 環境で UCRT(Universal CRT) ライブラリを使って C アプリをビルドするメモ


# 背景

* MSVC 非依存で Windows C/C++ アプリを mingw, clang でビルドしたい
* せっかくなので, UCRT を使ってみたい
  * UCRT でなくとも, 一応は MSVC 非依存でビルドできる
   
## UCRT(Universal CRT)

https://devblogs.microsoft.com/cppblog/introducing-the-universal-crt/

最近の推奨? C/C++ アプリ開発者から見ると, いわゆる C runtime(glibc)相当.
UWP(Universal Windows Platform)用にビルドするには UCRT が必要(+ UNICODE 環境オンリー)

## MinGW 環境でビルドする

Windows SDK にある UCRT のヘッダは, vcruntime.h などに依存しており, mingw(gcc, clang)ではビルドできない(MSVC header が別途必要)

https://stackoverflow.com/questions/57528555/how-do-i-build-against-the-ucrt-with-mingw-w64

MinGW に作成したヘッダを使う. `_UCRT` を定義する.

llvm-mingw では `libvcruntime140_app.a` がすでにあるのでこちらを利用すればよい


## 注意事項

* UCRT には C++ STL は含まれていない
  * llvm-mingw を見る限り, `libc++` とはうまく組み合わせることができるっぽい
* d3d12.h などは, 一応頑張ればいけるっぽい.
  * d3d12 API 自体が実際には C++ なコードなので, C++ モードにしてコンパイルが必要
Google  AdMob 自分のアプリの広告を知り合いのスマで何度もクリックすると、広告配信が一時的に制限された。。


#友達や恋人のスマホで広告をクリックすれば、収益発生するんじゃね？？
多少なりとも広告収入を得ている人なら、こう言ったこと:point_up_2:を一度は考えた事があるだろう。

僕は開発したアプリにAdMobのバナー広告を使っている。（どんなアプリかは僕のプロフィール欄のリンク先を見てね）

**僕のアプリはパートナーのスマホにもインストールされてるので、実際に広告を何度もクリックしてみた！**
結論を言うと、Googleから「君のアプリの広告は自然な感じでクリックされてなくね？一旦広告を制限するから様子見や！」と言われたのでござる。。

#AdMobの成果
<img width="774" alt="スクリーンショット 2020-06-21 20.51.08.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/34080ab0-fce9-5583-9d63-6d1e8b10a85b.jpeg">

<img width="507" alt="スクリーンショット 2020-06-21 20.51.37.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/0c82313d-967b-ea7e-acb0-0a3e71810455.jpeg">

だいたいこんな感じで月に150円ぐらい稼いでるっぽい。

ただ、AdMobは「1クリック何円」みたいなわかりやすいものでは無く、クリック単価というものは常に変動している（らしい。詳しくは[こちら](https://support.google.com/adsense/thread/20995684?hl=ja)をみてね）

#広告配信が一時的に制限された
<img width="465" alt="スクリーンショット 2020-06-21 20.44.58.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/266d7d5a-56fe-b38d-0331-5a30cc1d0fbf.jpeg">

**僕のパートナーのスマホでアプリを開き、数日に１度広告をクリックする事1ヶ月、広告配信が一時的に制限された旨を伝えるメールが、、、、**

今回はイエローカードのようなものですが、これを続けようものならいづれはレッドカードでしょう:dizzy_face:

**仮に友達365人いて、毎日誰か一人にクリックしてもらえば、おそらく何も疑われない！（それが収益に繋がるかも微妙。。）**

#結論
意図的に広告をクリックするのはやめようね！
django 環境構築の流れ

#djangoでの環境構築(vscode)

毎度のことながら、環境構築は苦手？というか、未だに具体的に何が怒っているのか理解していないため、一から忘れないようにということで手順立てて書いていこうと思う。



##1.　ターミナル上にpipenvをインストールしてくる

~brew install pipenv
~pip install pipenv
~pip3 install pipenv

自分はHomebrewを使っているので一番上のやつでインストールしている。


##2.　アプリ作成用フォルダを作る

これはいつも通り自分は適当にデスクトップ上に作っているので

~cd Desktop 
~mkdir フォルダ名
~cd 作成したフォルダ

##3. djangoのインストール
~pipenv install django


##4. djangoをインストールしたということを教えてあげる
~pipenv shell
*やめたい時のコマンドはexit()
##5. 設定用プロジェクトを立ち上げる
~django-admin startproject config .

##6. 自分で作りたいプロジェクトを立ち上げる
~django-admin startproject プロジェクト名


###終わりに
これで、djangoを使う環境構築は終わった。
環境構築で無駄な時間を取られることはないだろう
【Terraform】変数の上書き

## 準備

```bash
$ mkdir example
$ cd example
$ cat - << EOS > main.tf
provider "aws" {
  version = "2.67.0"
  region  = "ap-northeast-1"
}

variable "vpc_example_cidr_block" {
  default = "10.0.0.0/16"
}

resource "aws_vpc" "example" {
  cidr_block = var.vpc_example_cidr_block

  tags = {
    Name = "example"
  }
}
EOS
```

## 初期化

```shell
$ terraform init
```

## そのまま実行した場合

```shell
$ terraform plan | egrep '^.+cidr_block.+= ".+$' 
      + cidr_block                       = "10.0.0.0/16"
```

## 実行時に `-var` オプションで上書きした場合

```bash
$ terraform plan -var vpc_main_cidr_block=192.168.0.0/24 | egrep '^.+cidr_block.+= ".+$' 
      + cidr_block                       = "192.168.0.0/24"
```

## 環境変数 `TF_VAR_xxx` で上書きした場合

```bash
$ TF_VAR_vpc_main_cidr_block=192.168.0.0/24 terraform plan | egrep '^.+cidr_block.+= ".+$'
      + cidr_block                       = "192.168.0.0/24"
```
LaravelのCollectionのsortBy()メソッドを使うときの注意点


### 概要
* インデックス配列を、sortBy() すると、順番が入れ替わる場合に連想配列になります。
* 順序が入れ替わらない場合は、インデックス配列のままです。
* APIなどで配列をJSONなどに出力すると結果によって、フォーマットが崩れてしまうケースがあるので注意が必要です。
* 意識してインデックス配列にする場合は、 values() メソッドを利用し配列の番号を振り直し、インデックス配列に強制します。

```sample.php
$array = [
    [
      'name' => 'ryoma',
      'age' => 33,
    ], 
    [
      'name' => 'taro',
      'age' => 22,
    ],
];

// 変更なし配列そのまま 
echo json_encode($array);

// [{"name":"ryoma","age":33},{"name":"taro","age":22}]


// sortBy で前後関係が入れ替わらないケース （インデックス配列）
echo json_encode(collect($array)->sortBy('name'));

// [{"name":"ryoma","age":33},{"name":"taro","age":22}]


// sortBy で前後関係が入れ替わるケース （連想配列になる）
echo json_encode(collect($array)->sortBy('age'));

// {"1":{"name":"taro","age":22},"0":{"name":"ryoma","age":33}}


// 連想配列になるケースをvalues() で 整数を振り直して、インデックス配列に強制
echo json_encode(collect($array)->sortBy('age')->values());

// [{"name":"taro","age":22},{"name":"ryoma","age":33}]

```


## まとめ
* sortBy() 使って インデックス配列で返却して欲しいときは、values()を使いましょう
* ＼(^o^)／
【Terraform】モジュールの利用

## 準備

```shell
$ mkdir example
$ cd example
$ mkdir http_server
$ cd http_server   
$ cat - << EOS > main.tf
variable "instance_type" {}
variable "tag_name" {}
variable "vpc_id" {}
variable "subnet_id" {}

data "aws_ami" "ami_amazon_linux_2" {
  most_recent      = true
  owners           = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-2.0.????????-x86_64-gp2"]
  }
}

resource "aws_instance" "default" {
  ami                    = "ami-0c3fd0f5d33134a76"
  vpc_security_group_ids = [aws_security_group.default.id]
  instance_type          = var.instance_type
  subnet_id              = var.subnet_id

  tags = {
    Name = var.tag_name
  }

  user_data = <<EOF
    #!/bin/bash
    yum install -y httpd
    systemctl start httpd.service
EOF
}

resource "aws_security_group" "default" {
  name = "ec2"
  vpc_id = var.vpc_id

  ingress {
    from_port = 80
    to_port = 80
    protocol = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port = 0
    to_port = 0
    protocol = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

output "public_dns" {
  value = aws_instance.default.public_dns
}
EOS
$ cd..
$ cat - << EOS > main.tf
provider "aws" {
  version = "2.67.0"
  region  = "ap-northeast-1"
}

variable "vpc_main_cidr_block" {
  default = "10.0.0.0/16"
}

resource "aws_vpc" "example_vpc" {
  cidr_block           = var.vpc_main_cidr_block
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "example"
  }
}

resource "aws_internet_gateway" "example_internet_gateway" {
  vpc_id = aws_vpc.example_vpc.id
}

resource "aws_route_table" "example_route_table" {
  vpc_id = aws_vpc.example_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.example_internet_gateway.id
  }
}

resource "aws_subnet" "example_subnet_1d" {
  vpc_id                  = aws_vpc.example_vpc.id
  cidr_block              = "10.0.0.0/24"
  availability_zone       = "ap-northeast-1c"
  map_public_ip_on_launch = true

  tags = {
    Name = "example"
  }
}

resource "aws_route_table_association" "example" {
  subnet_id      = aws_subnet.example_subnet_1d.id
  route_table_id = aws_route_table.example_route_table.id
}

module "web_server" {
  source        = "./http_server"
  instance_type = "t3.micro"
  tag_name      = "example-web-server"
  vpc_id        = aws_vpc.example_vpc.id
  subnet_id     = aws_subnet.example_subnet_1d.id
}

output "public_dns" {
  value = module.web_server.public_dns
}
EOS
```

## 実行

```shell
$ terraform init
$ terraform get 
$ terraform plan
$ terraform apply
```

## 動作確認

```shell
$ aws ec2 describe-instances --filters "Name=tag:Name,Values=example-web-server" | jq -r '.Reservations[].Instances[].State.Name'
running
$ public_dns=$(terraform output -json | jq -r '.public_dns.value')
$ curl -sS http://${public_dns} | grep '<title>' | perl -pe 's/^.+<title>(.+)<\/title>$/${1}/'
Test Page for the Apache HTTP Server
```

## 破棄

```shell
$ terraform destroy                                                                                                              
```
【Laravel】コントローラの書き方

# 概要
Laravelのコントローラ周辺について説明するよ
初心者向けの内容だよ
[【Laravel】ルーティングの書き方](https://qiita.com/KagYeah/items/552a36596e0d8b4b9b92)と一緒に読むといいよ

# コントローラ
コントローラとは、アプリケーションの処理を実装する部分だよ
クライアントからアクセスがあると、ルーティングによって、「○○というアドレスがきたら××という処理を行う」ということを決めるんだけど、この「××という処理」を書いているものがコントローラだよ
コントローラはクラスで表されていて、アクションというメソッドで書かれたものの中に具体的な処理を書いていく

## 基本
コントローラを作成するにはartisanコマンドを使う

```zsh:
% php artisan make:controller コントローラ名
```

コントローラ名は大文字で始まって、○○Controllerという名前にするのが一般的だね

```zsh:
% php artisan make:controller HelloController
```

例えば、上のようなコマンドを打つと以下のようなコントローラができる

```php:app/Http/Controllers/HelloController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HelloController extends Controller
{
    //
}

?>
```

※以下namespaceやuseは省略

例えばindexというアクションを書いてみる

```php:app/Http/Controllers/HelloController.php
class HelloController extends Controller
{
    public function index()
    {
        $param = ['msg' => 'Hello'];
        return view('welcome', $param);
    }
}
```

アクション内でreturnするのは、主にview()やredirect()だね
view()は引数にテンプレート名やパラメータをとって、ブラウザにビューを表示させる
リダイレクトは例えばredirect('/hello/index')って感じ

上の例でいうと、indexの引数は何もないけれど、ルートにパラメータがある場合は引数を設定する
ただし、'http://.../index?id=1'のように?より後ろのパラメータは引数設定しても取得できない
この場合は以下のように引数にRequestオブジェクトの\$requestを設定して、$request->idのように取得すればいい

```php:app/Http/Controllers/HelloController.php
class HelloController extends Controller
{
    public function index(Request $request)
    {
        $param = ['msg' => 'Hello', 'id' => $request->id];
        return view('welcome', $param);
    }
}
```

# おわり
今回はここまで
あんまり説明することがなかったね
それだけ単純だってこと
次はビューやテンプレートについて話していこうかな
dockerイメージ内にyarnをインストールする

# 背景
Dockerを利用して作成したRailsアプリ(v5.2.4)を本番環境にデプロイする際、アセットをプリコンパイルしようとしたところ、以下のエラーがでて実行できなかった。

```sh
$docker-compose run web bundle exec rake assets:precompile RAILS_ENV=production
```
```sh
Starting excite-map_db_1 ... done
Yarn executable was not detected in the system.
Download Yarn at https://yarnpkg.com/en/docs/instal
```

# 解消方法
Dockerfileに以下を追加

```Dockerfile
RUN curl https://deb.nodesource.com/setup_12.x | bash
RUN curl https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update && apt-get install -y nodejs yarn postgresql-client
```

# 参考
https://github.com/yarnpkg/yarn/issues/7329
MongoDBで配列内の特定の値だけを更新する

# やり方
Mongo公式ドキュメントの[$set](https://docs.mongodb.com/manual/reference/operator/update/set/)と[arrayFilters](https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/)を利用する

## 実例
このようなドキュメントを持つコレクションがある時。

```js
{
   "_id" : 1,
   "grades" : [
      { "grade" : 80, "mean" : 75, "std" : 6 },
      { "grade" : 85, "mean" : 90, "std" : 4 },
      { "grade" : 85, "mean" : 85, "std" : 6 }
   ]
}
{
   "_id" : 2,
   "grades" : [
      { "grade" : 90, "mean" : 75, "std" : 6 },
      { "grade" : 87, "mean" : 90, "std" : 3 },
      { "grade" : 85, "mean" : 85, "std" : 4 }
   ]
}
```
idが2のドキュメント内で、「grades配列のgradeの値が90であるオブジェクト」のmeanの値を100にしたいとする。（日本語が長いな...）
以下のようなコードとなる。

```js
hoge.updateOne(
  { "_id": 2 },
  { $set: { "grades.$[element].mean" : 100} },
  { arrayFilters: [ { "element.grade": 90 }  ] }
)
```
hogeはコレクション名。第一引数はドキュメントのフィルタ。（このへんは説明を割愛）

第二引数で配列(grades)と更新したいフィールド(mean)、値(100)をセットする。$[element]は識別子。
第三引数で特定の配列内の検索条件を指定。第二引数で指定した識別子を使う。

###結果

```js
{
   "_id" : 1,
   "grades" : [
      { "grade" : 80, "mean" : 75, "std" : 6 },
      { "grade" : 85, "mean" : 90, "std" : 4 },
      { "grade" : 85, "mean" : 85, "std" : 6 }
   ]
}
{
   "_id" : 2,
   "grades" : [
      { "grade" : 90, "mean" : 100, "std" : 6 }, // mean:75 -> mean:100
      { "grade" : 87, "mean" : 90, "std" : 3 },
      { "grade" : 85, "mean" : 85, "std" : 4 }
   ]
}
```
ROS melodic で ARマーカーを検出するための環境設定　① Unbuntu 上で Docker コンテナを立ち上げるまで

# はじめに
初めてROSを触る人が、DockerでROSのコンテナを立ち上げてARマーカーをUSBカメラで検出するまでの流れを記録として残します。
ROS melodicのDocekrイメージのPullから、`ar-track-alvar`パッケージの動作確認までが目標です。

この記事では、X serverを用いたGUI環境と、USBカメラのデバイス情報を設定して`ROS melodic`コンテナをrun するところまで紹介します。 

## 環境
 | 環境
:--:| :--: |
OS | Ubuntu 18.04 LTS
プロセッサ | Intel Core i7-6700HQ CPU
RAM | 8GB
GPU | GeForce GTX960M
ROS | melodic


## このシリーズについて
複数回に分けて紹介します。  
0.  環境設定編（Windows10にUbuntuをデュアルブートして、Dockerをセットアップする）
1.  ROSのコンテナを作成する　**この記事です**
2.  AR検出用のパッケージをセットアップする

# docker imageのインストール
ROS1の中では melodicが最新なのでイメージをインストールします
ターミナルで以下を実行してください。

```bash:イメージのダウンロード
$ docker pull {image-name:tag-name}
例
$ docker pull orsf/ros:melodic-desktop-full-bionic
```
タグの中身の違いは現状わかっていません。 
例えば、stretchとか検索するとraspbianというワードが出るから、リソース小さいマシン用なのかな？

ちなみにpull済のイメージ一覧は次のコマンドで知ることができます。  

```bash:pull済のイメージの確認
$ docker image ls
```

# container の起動
イメージからコンテナを作成します。
このときに外部接続の設定と、USB deviceの設定をしないとROSコンテナ内でGUI画面が出てきません。

（エラーメッセージ `cannot connect X server` とか、カメラ画像が出てこない事象に悩みます。）

[docker tutorial](wiki.ros.org/docker/Tutorials/GUI)のスクリプトを参考にrun スクリプトで設定を
行いました。

```bash:コンテナのrun
$ docker run -it \
    --env="DISPLAY" \
    --env="QT_X11_NO_MITSHM=1" \
    --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
    --device="/dev/video2:/dev/video2" \
    --name="AR_Env" \
    osrf/ros:melodic-desktop-full-bionic \
    rqt
export containerId=$(docker ps -l -q)
```
`device` や`name`, 使うイメージは適宜読み替えてください。
次の項で、デバイス情報取得で調べ方を記述します。

## usbカメラデバイス`device`の情報取得
[こちらを参考にさせていただきました](http://ishi.main.jp/ros/ros_uvccam.html)

```bash:Ubuntu側でUSBデバイスの確認
$ lsusb
```
コマンドがないときは、

```bash
$ apt-get install lsusb
```
でインストールできます

```bash:これだとPCのビルトインcamの情報が出ました
$ v4l2-ctl -d /dev/video0 --all
```
私の環境の場合、`/dev/video2`がusbcamだったのでこちらの情報を使っています。

## X severの準備
noVNCとか使いたかったのですが、いまのところ難しかったので[docker tutorialより](wiki.ros.org/docker/Tutorials/GUI)
**シンプルだけど、安全でない** 方法でとりあえず動かします。

runのスクリプトを実行する前に、Ubuntu側のX server設定を変更しておきます。

```bash
$ xhost +local:root
```  

Ubuntuを立ち上げる都度設定してあげないと、作ったコンテナがstart しないという事態を経験します。
そうゆうときは

```bash:conteinorのlogを確認
$ docker logs {container name}
```
で何が起こっているか見ることができます。（Xseverに繋がらないからstartできない、とか）

コンテナのrunスクリプトを実行すると起動します。`device`で設定したUSBカメラを接続していないとコンテナがstartしないのでご注意ください。

# おわりに
USBカメラを接続した状態でROSのコンテナが起動でき、撮影した画像をGUIで表示する準備ができました。
【hidden_field】rails hidden_field を使って情報を送ろう!!!!

##【ゴール】
hidden_fieldを使って情報を送る

![画面収録 2020-06-21 20.06.48.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620689/9e87f94c-dc60-e890-ebe2-39d8383ce937.gif)


##【メリット】
■　paramaterの理解度向上
■　hidden_fieldの使い方理解
■　MVCの理解度向上


##【開発環境】
■ Mac OS catalina
■ Ruby on Rails (5.2.4.2)
■ Virtual Box:6.1
■ Vagrant: 2.2.7

##【実装】

####アプリケーション作成
※「scaffold」で一気に作成

```mac.terminal
$ rails new hidden_lesson
$ rails g scaffold Item name:string text:text price:integer amount:integer
$ rails db:migrate 
```

##アプリケーション調整

※ルートを追記
※homeにitemsのindexページが来るように
※postメソッドで確認画面へのルートを作成

```config/routes.rb
 root 'items#index'
 post 'items/confirm' => 'items#confirm'
```


※views/itemsにconfirm.html.erbを作成
※items/_form.html.erbを編集
※**hidden_field**でUserには見えないようにページで情報を保持します！！！

```items/confirm.html.erb
<h3>Confirm page</h3>
<%= form_with model:@item do |form| %>

<div class="field">
  <%= form.label :name %>
  <%= @item.name %>
  <%= form.hidden_field :name %>
</div>

<div class="field">
  <%= form.label :text %>
  <%= @item.text %>
  <%= form.hidden_field :text %>
</div>

<div class="field">
  <%= form.label :price %>
  <%= @item.price %>
  <%= form.hidden_field :price %>
</div>

<div class="field">
  <%= form.label :amount %>
  <%= @item.amount %>
  <%= form.hidden_field :amount %>
</div>

<div class="actions">
  <%= form.submit %>
</div>
<% end %>

```

```items/_form.html.erb
<%= form_with(model: item, local: true) do |form| %> #これを↓に変更

<%= form_with(model: item, local: true, url: items_confirm_path) do |form| %>
```

以上です。商品詳細画面遷移前に確認画面が挟まれているはずです。

##【合わせて読みたい】
■form_withに関して
https://qiita.com/tanaka-yu3/items/50f54f5d4f4b8dfe19f3

■local: trueに関して
https://qiita.com/hayulu/items/5bf26656d7433d406ede

■確認画面作成に関して
https://qiita.com/tomoharutt/items/7959d28764912c64562f

■formの引数が2つの場合
https://qiita.com/tanaka-yu3/items/94d2b9fccc9577756127
Qiitaの投稿画面を弄ってみた

投稿画面が微妙に使いにくい気がしたので弄ってみました。

ブックマークレット等でも出来そうですが、その都度実行も面倒なのでChrome拡張を利用してます。

> [Stylus \- Chrome ウェブストア](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=ja)
> CSS弄れるなら色々と自分好みに出来て便利です。:cheese:

<details><summary>**スタイル設定**</summary><div>
適用先: **正規表現に一致するURL** `https?://qiita.com/draft.*?/edit\b.*`

```css
/** プレビューペイン **/
div.qa-MdContent,
div.it-MdContent {
  white-space: nowrap;       /* 折り返さない */
  transform: scale(0.75);    /* 縮小表示:75% */
  transform-origin: 2em 2em; /* 縮小位置調整 */
}
div.it-MdContent.slide_preview {
  white-space: initial;  /* スライドモードは普通に */
  transform: none;
}

/** 編集ペイン **/
textarea[class^="MarkdownEditorBody"],
textarea.editorMarkdown_textarea {
  white-space: pre;        /* 折り返さない */
  tab-size: 2;             /* TAB文字幅:2 */
  overflow: scroll !important; /* 横スクロール出して */
  /* 好みのフォントで編集したい */
  font-family: "FONT-NAME",Consolas,Liberation Mono,Menlo,Courier,monospace;
}
```

</div></details>

----

### やりたかった事
* **編集画面**
  + 自動折り返しの無効化<br>
    投稿用にコード手直しする時、非常に見づらかったので。
  + TAB文字幅の変更・表示フォントの変更<br>
    単純に好みの問題です。<br><br>
* **プレビュー画面**
  + 自動折り返しの無効化<br>
    表示幅半分だと実際の記事以上に折り返されるので。
  + 縮小表示化<br>
    プレビューなら実寸で無くても良いかな～と。
QMK Firmwareで自作キーボードにファームウェアを焼く方法

自作キーボードの「7sPro」をビルドする際にqmk_firmwareを再度用意する必要があったため公式ドキュメントを確認したところ、自分の知っている方法とは異なる方法で説明されていました。
個人的には新しい方法のほうがディレクトリを移動したりする必要がないので気に入りました。

公式ドキュメント：https://docs.qmk.fm/#/newbs_getting_started

全て英語なので備忘録も兼ねて手順を残しておきます。

# MSYS2のインストール (Windowsのみ)

公式ページからMSYS2をインストールしましょう。
以前は32bit版もあったのですが、現在は64bit版しかないようです。
https://www.msys2.org/

インストールが完了したら、**最初に開いたターミナルは閉じ、MSYS2 MinGW 64-bitを開いてください。**

以後の操作は全てMSYS2 MinGW 64-bitで行います。

# MSYS2のアップデート

以下のコマンドを実行し、アップデートを実行します。

```
pacman -Syu
```

途中で処理が停止して再起動するように言われるので、右上のバツで閉じて再度MSYS2 MinGW 64-bitを起動します。
起動したら、再度上記コマンドを実行します。

# QMKのインストール

### Windows
以下のコマンドを実行します。

```
pacman -S git mingw-w64-x86_64-toolchain mingw-w64-x86_64-python3-pip
python3 -m pip install qmk
```

### Mac
Homebrewを使用し、以下のコマンドを実行します。

```
brew tap qmk/qmk
brew install qmk
```

# QMKのセットアップ
以下のコマンドを実行します。

```
qmk setup
```

このコマンドを実行すると、ホームディレクトリにqmk_firmwareが生成されます。
(WindowsならC:/Users/<ユーザ名>/qmk_firmware)

任意の場所にqmk_firmwareを置きたい場合（例えばDドライブ直下）は以下のようにコマンドを実行します。

```
qmk setup --home D:/qmk_firmware
```

# FWのコンパイル
以下のコマンドでFWのコンパイルができます。

```
qmk compile -kb <キーボード> -km <キーマップ>
```

今回は7sProのデフォルトキーマップを焼きたいので、以下のコマンドとなります。

```
qmk compile -kb 7skb -km default
```

# FWの焼き込み

Pro MicroにFWを焼き込むには以下のコマンドを実行します。

```
qmk flash -kb <キーボード> -km <キーマップ>
```

7sProのデフォルトキーマップの場合は以下のコマンドとなります。

```
qmk flash -kb 7skb -km default
```

# キーマップの追加
自作キーボードは自分でキー配列を決められるのも楽しみの一つです。
キーマップを追加するには以下のコマンドを実行します。

```
qmk new-keymap -kb <キーボード>
```

自分の場合は以下となります。

```
qmk new-keymap -kb 7skb
```

実行すると、キーマップ名を聞かれるので好きな名前を設定します。
分かりやすいように自分の名前とかにしておけばいいと思います。

デフォルトのキーマップがコピーされた状態でファイルが生成されるので中身を編集しましょう。

# 個人キーボードの設定
個人キーボードを設定しておくと、各コマンドのキーボードやキーマップを省略して実行することができます。

```
qmk config user.keyboard=<キーボード>
```

```
qmk config user.keymap=<キーマップ>
```

設定が完了したら、コンパイルや焼き込みは以下のコマンドで実行できるようになります。

``` 
qmk compile
```

``` 
qmk flash
```

# 補足
各コマンドを実行すると分かりますが、結局は以前と同様にmakeを実行しているだけですので、以前と同じ方法でも焼き込みはできます。
その他にも色々と為になる情報が書かれていますので、公式ドキュメントは一度目を通してみるのをオススメします。
try do catch構文について

try do catchについて理解を得たのでまとめ
まずはコードから

```swift
enum HogeError: Error {
    case hoge
    case hogehoge
    case hogehogehoge
}

class Hoge {
    class func hoge() throws -> String {
        if !false {
            throw HogeError.hogehogehoge
        }
        return "成功"
    }
}

class Hogehoge {
    class func hoge() -> String {
        do {
            _ = try Hoge.hoge()
        } catch HogeError.hoge {
            return "hoge"
        } catch HogeError.hogehoge {
            return "hogehoge"
        } catch HogeError.hogehogehoge {
            return "hogehogehoge"
        } catch {
            return "来ない"
        }
        return "成功"
    }
}
```

・エラーハンドリング（HogeError）を列挙型で定義（プロトコルErrorに準拠させる）
・Hogeクラスのhogeメソッドはエラーを投げているのでメソッドに「throws」を書く必要がある（エラーを投げていると明示するため）
・Hogehogeクラスのhogeメソッドでdo catch構文を実装
・doで実装しエラーが返ってきたらcatchでエラー実装をする（ログを出すなど）
・エラー処理を複数実装することができる（最後のcatchは来ないが実装必須）
Perlでスクリプト/モジュールの両対応

Perl で単一ファイルのスクリプトを作ったけど、スクリプト中の関数を他でも使えるようにしたいなと思うことがあります。規模が大きくなれば .pm 化してしまえばいいのですが、それほどの規模でもない場合もあります。スクリプト本体とモジュールをファイルを分けてもいいのですが、そうすると単一ファイルをコピーするだけという手軽さが失われるのがもったいない。なんかそういうときの方法があったよなぁというのをぐぐってて見つけたのがこちらです。

[Perlで一枚岩のスクリプトをテスタブルにする](https://songmu.jp/riji/entry/2014-08-14-test-perl-script.html)

関数を他から利用するのも、関数をテストするのも、スクリプト/モジュールの両対応させるという点では同じですね。

## そもそも何が問題か

例えば以下のようなスクリプトを作ったとします。

```perl:script.pl
#!/usr/local/bin/perl

use strict;
use warnings;

{
  if(@ARGV < 1) {
    print "usage\n";
    exit;
  }
  func();
}

sub func {
  print "func\n";
  # do something
}
```

スクリプトはちゃんと動作しますね。

```shell
$ ./script.pl
usage
$ ./script.pl param
func
```

次に `script.pl` の `func` を利用する別のスクリプトを作ります。

```perl:other.pl
#!/usr/local/bin/perl

use strict;
use warnings;

require './script.pl';

func();
```

これを実行しますと、`script.pl` のベタ部分の処理が実行され不本意に exit してしまいます。

```shell
$ ./other.pl
usage
```

## どうしたらいいか

`script.pl` のベタ処理部分を、require された場合には実行しないように、以下のように書き換えます。

```perl:script.pl(改良版)
#!/usr/local/bin/perl

use strict;
use warnings;

if ($0 eq __FILE__) {
  if(@ARGV < 1) {
    print "usage\n";
    exit;
  }
  func();
}

sub func {
  print "func\n";
  # do something
}

1;
```

`$0` は実行しているプログラムの名前が格納されます。スクリプトとして実行した場合には `script.pl` が、モジュールとして呼び出された場合は `other.pl` が入ります。

`__FILE__` は自分自身のファイル名が格納されます。こちらはスクリプトでもモジュールでも、常に `script.pl` が入っています。

つまり、`$0` と `__FILE__` を比較することで、自分自身が今スクリプトとして実行しているか、モジュールとして呼び出されているかを判別できるわけですね。リンク先の記事に

> pythonのif __name__ == '__main__':みたいな感じ。

とありまして、ああそういえば Python でこういうの見かけたんだと思い出した次第。

この状態で `other.pl` を実行すると、ちゃんと `func()` を呼び出せています。

```shell
$ ./other.pl
func
```
MFA認証有アカウントでのCLIアクセス

stsコマンドを使用し、アクセス用のアクセスキーID、シークレットアクセスキー、セッショントークンを取得(有効期限のデフォルトは１２時間。--duration-secondsを使用して秒単位で有効期限を指定できる)

```console
% aws sts get-session-token --serial-number [MFAデバイス用のARN] --token-code [MFAデバイスのトークン]
{
    "Credentials": {
        "AccessKeyId": "[アクセスキーID]",
        "SecretAccessKey": "[シークレットアクセスキー]",
        "SessionToken": "[アクセス用のセッショントークン]",
        "Expiration": "2020-06-21T22:19:35+00:00"
    }
}
```

configureコマンドでprofile指定し、profile作成

```console
% aws configure --profile mfa-temporary-access
AWS Access Key ID [None]: [stsコマンドで取得したアクセスキーID]
AWS Secret Access Key [None]: [stsコマンドで取得したシークレットアクセスキー]
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

credentialsファイルに直接セッショントークンを追記

```console:credentials
[mfa-temporary-access]
aws_access_key_id = [stsコマンドで取得したアクセスキーID]
aws_secret_access_key = [stsコマンドで取得したシークレットアクセスキー]
aws_session_token = [stsコマンドで取得したセッショントークン]
```

指定されたセッショントークンでアクセス可能になる

```
% aws s3 ls --profile mfa-temporary-access
```

環境変数の設定でもいける。

```
export AWS_ACCESS_KEY_ID=[stsコマンドで取得したアクセスキーID]
export AWS_SECRET_ACCESS_KEY=[stsコマンドで取得したシークレットアクセスキー]
export AWS_SESSION_TOKEN=[stsコマンドで取得したセッショントークン]
```
Minicondaインストール後、condaコマンド実行時に「内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチファイルとして認識されていません。」と表示されるときの対処法

Minicondaをインストールし、仮想環境を構築したうえで機械学習を勉強しようとしています。
Anacondaではサイズが大きいため、Minicondaをインストールすることにしました。

Minicondaインストール後、condaコマンドを入力しても、このように表示され、その後に進むことができなくなりました。
「内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチファイルとして認識されていません。」

現状、解決したので対処法を記載します。

①環境変数を設定する
コマンドプロンプトとコントロールパネルからの2通りの設定方法があるようです。
今回はコントロールパネルから設定しました。

コントロールパネル＞システムとセキュリティ＞システム＞システムの詳細設定
と進むとシステムのプロパティが表示されます。
<img width="337" alt="システムのプロパティ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659859/b0e80183-58cd-4fc6-7fab-c8b4c0c84087.png">

さらに、以下の通り進みます。
詳細設定タブ＞環境変数＞Path

Pathを選択後、編集＞新規と選択し、
Minicondaが保存されているディレクトリまでのファイルパスを記述しました。

※Pathはシステム環境変数とユーザー環境変数の2種類があります。
試してみると、どちらでもcondaコマンドを実行できたのですが、その違いはいまいちわかっていません。

②Anaconda Promptを管理者で実行
環境変数を設定できたら、Anaconda Promptを管理者として実行し、condaコマンドを入力するとうまくいきました。
AWSインスタンスをコマンドラインで起動・停止する

AWSのEC2インスタンスをシェルで起動するのをやりたかったのですが、とりあえず今回はコマンドで起動できるところまでを確認しました。ので、備忘録。

#AWS-CLIをインストール

参考は[こちら](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-cliv2-mac.html#cliv2-mac-install-confirm)。


```
$ curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 20.7M  100 20.7M    0     0  14.6M      0  0:00:01  0:00:01 --:--:-- 14.6M
```

```
$ sudo installer -pkg ./AWSCLIV2.pkg -target /
Password:
installer: Package name is AWS Command Line Interface
installer: Installing at base path /
installer: The install was successful.
```


以下コマンドでインストールできたことを確認。

```
$ which aws
/usr/local/bin/aws

$ aws --version
aws-cli/2.0.24 Python/3.7.4 Darwin/18.7.0 botocore/2.0.0dev28
```

#起動・停止にトライ
シェルを書く前に、コマンドで試してみると、、、おろ。

```
$ aws ec2 start-instances --instance-ids インスタンスID 
You must specify a region. You can also configure your region by running "aws configure".
```

どうやら、aws configureという初期設定が必要な模様。参考は[こちら](https://www.skyarch.net/blog/?p=7583)。

aws-cliというユーザーを別に作り、ポリシーをアタッチし、生成したアクセスキーを使って以下のように設定。

```
$ aws configure
AWS Access Key ID [None]: XXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

今度こそ、、、！！

```
$ aws ec2 start-instances --instance-ids インスタンスID 
{
    "StartingInstances": [
        {
            "CurrentState": {
                "Code": 0,
                "Name": "pending"
            },
            "InstanceId": "XXXXXXXXXXXXXXXXXX",
            "PreviousState": {
                "Code": 80,
                "Name": "stopped"
            }
        }
    ]
}

```

コンソール見たら、ちゃんとrunnningになっていました。キターーーーーーーーーーーー


停止もできました。コンソールにて、stoppedになっているのを確認。

```
$ aws ec2 stop-instances --instance-ids インスタンスID
{
    "StoppingInstances": [
        {
            "CurrentState": {
                "Code": 64,
                "Name": "stopping"
            },
            "InstanceId": "XXXXXXXXXXXXXXXXXX",
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}
```

今回は、まだシェルを書くに至りませんでした。
次は、シェルを頑張ってみたいと思います。。
自分用メモ(新入社員#1)

新入社員のWebエンジニアが指摘されたことをメモする。

#1 メソッドや変数の命名が抽象的である

たとえば、ユーザー名のバリデーションメソッドの命名を考えるとします。

何も考えていない私は、`isEnableUser`と書きました。

これでは、ユーザー名の何が利用可能であるのか分かりません。

より具体的にするために、`isEnableUserName`に変更しました。

**メソッド名が長くなりますが、分かりやすさがもっとも重要**だと言われました。



#2 レビューがしやすいようにプルリクを小さくしよう

コーディングに集中をしすぎて、プルリクの差分を増やしました。

レビューをする側にとって、膨大な量のコードレビューは負担になります。

**予めにレビューをしてもらう範囲を限定しておくことで、プルリクが大きくなる問題を解決**しています。
【VS code】キーボードショートカット・keybindings.jsonの開き方

#【VS code】キーボードショートカット・keybindings.jsonの開き方

PHPでカーソルを単語の外に出すショートカットキーを設定した際にkeybidings.jsonを利用したため、そのファイルの開き方をまとめます。
*動画の後半がjsonファイルの開き方です。

![VScode_keyboard.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526570/7350c59a-a230-615e-7a14-3785a0933f1c.gif)

ちなみにtabキーで単語の外に出す設定は以下のリンクで紹介されています.
https://qiita.com/noanoa07/items/0e22d7115a35498e0e08
Ubuntu18.04 (WSL)でpyspark＋jupyterの環境を手早く作る

# やること
Ubuntu 18.04（WSL）上にpysparkを試すための環境をさくっと用意する。
anacondaやpyenvは使用しないので、使いたい方は随時対応してください。

# 前提環境
Windows 10 Home
Ubuntu 18.04 LTS (WSL) インストールしたばかりの状態から開始

# 作る環境
Spark 2.4.6 
Hadoop 2.7
Python3.6.9
jupyter-notebook

# 手順
## まずはSparkのインストール
### jdkをインストール
```shell
sudo apt-get update
sudo apt-get install -y openjdk-8-jdk
```

### sparkをインストール
入れたいバージョンに応じて、各所変更すると吉。

```shell
wget http://ftp.riken.jp/net/apache/spark/spark-2.4.6/spark-2.4.6-bin-hadoop2.7.tgz
tar zxvf spark-2.4.6-bin-hadoop2.7.tgz
sudo mv spark-2.4.6-bin-hadoop2.7 /usr/local/
sudo ln -s /usr/local/spark-2.4.6-bin-hadoop2.7 /usr/local/spark
```

### 環境変数追加
あとで~/.bashrcの末尾に追記推奨。
ターミナル起動時に毎回追加なくて済む。

```shell
export SPARK_HOME=/usr/local/spark
export PATH=$PATH:$SPARK_HOME/bin
```

### 動作確認
```shell
spark-shell --master local[*]
```

こんな表示が出ればOK
Ctrl + D で脱出

```
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.4.6
      /_/

Using Scala version 2.11.12 (OpenJDK 64-Bit Server VM, Java 1.8.0_252)
Type in expressions to have them evaluated.
Type :help for more information.

scala>
```

## 次にPython3のインストールと設定
### python3 インストール
既にあれば省略
/usr/bin/python3がパスになっている想定

```shell
sudo apt install python3
```
### 環境変数の設定
これもあとで~/.bashrcの末尾に追記推奨。

```shell
export PYSPARK_PYTHON=/usr/bin/python3
```

### 動作確認
```shell
pyspark --master local[*]　
```

こんな表示が出ればOK
これでpysparkが使える。
Ctrl + D で脱出

```
Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /__ / .__/\_,_/_/ /_/\_\   version 2.4.6
      /_/

Using Python version 3.6.9 (default, Apr 18 2020 01:56:04)
SparkSession available as 'spark'.
>>>
```

## jupyterのインストールと設定
### pip3のインストール
既にあれば省略

```shell
sudo apt install python3-pip
```

## jupyter-notebookをインストール
既にあれば省略

```shell
sudo apt install jupyter-notebook
```

### 環境変数の設定
あとで~/.bashrcの末尾に追記推奨。
ipは好きに変えてOK。

```shell
export PYSPARK_DRIVER_PYTHON=jupyter
export PYSPARK_DRIVER_PYTHON_OPTS='notebook --ip=127.0.0.1' pyspark
```

### 動作確認
```shell
pyspark --master local[*]
```
jupyter-notebookが起動して、アクセスできたらOK

適当なpython3ノートブックを作成して下記を実行してみる。

```python
spark
```
下記のようになれば成功。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354154/9476071d-be94-c55e-d104-342935dcd83a.png)

## 完了！
各環境変数の設定を~/.bashrcの末尾に追記しておくと今後が楽。
思う存分pysparkを試せばよい。
laravelのbref を利用し、lambda にデプロイする 

# はじめに
laravelで制作したアプリをサーバーレス用ライブラリbrefを使い、AWSにデプロイしました。デプロイは、serverless frameworkがやってくれます。

ちなみに、参考にした先輩の記事はこちら。

**Laravelのサーバレス用ライブラリbrefを使い、lambdaでhello world
PHP**
https://qiita.com/umihico/items/64fcf159f68ebd866170
#アプリ作成とbrefインストール

```terminal
$ composer create-project --prefer-dist laravel/laravel laravel-demo #プロジェクト作成
$ cd laravel-demo
$ composer require bref/bref #肝のbrefインストール

```
#編集するファイル
.env

```.env
- SESSION_DRIVER=file
+ SESSION_DRIVER=array
+ VIEW_COMPILED_PATH=/tmp/storage/framework/views
```

```config/logginf.php
        'stack' => [
             'driver' => 'stack',
-            'channels' => ['single'],  # <= 削除
+            'channels' => ['stderr'],  # <= 挿入
             'ignore_exceptions' => false,
         ],
```

```app/Providers/AppServiceProvider.php

     public function boot()
     {
-        //
+        if (!is_dir(config('view.compiled'))) {  
+            mkdir(config('view.compiled'), 0755, true);
+        }
     }
 }
```
#serverless.ymlの編集

```serverless.yml

service: laravel-demo

provider:
  name: aws
  region: ap-northeast-1
  runtime: provided

plugins:
  - ./vendor/bref/bref

package:
  exclude:
    - node_modules/**
    - public/storage
    - storage/**
    - tests/**

functions:
  website:
    handler: public/index.php
    timeout: 28 # in seconds (API Gateway has a timeout of 29 seconds)
    layers:
      - ${bref:layer.php-73-fpm}
    events:
      - http: 'ANY /'
      - http: 'ANY /{proxy+}'
  artisan:
    handler: artisan
    timeout: 120 # in seconds
    layers:
      - ${bref:layer.php-73} # PHP
      - ${bref:layer.console} # The "console" layer
```

artisanコマンド用関数は、ローカルでしか実行しないならコメントアウトしても構いません。
#デプロイ
デプロイコマンドを叩く前に、必ずphp artisan config:clearしましょう。

```
$ php artisan config:clear
Configuration cache cleared!
```


```
$ sls deploy
```

これで完了です！

# おわりに

サーバーレスフレームワークを利用すれば、サーバーを持つ必要がなく、サーバー代もかなり節約できるので、おすすめです。

## 参考記事

https://bref.sh/docs/frameworks/laravel.html
環境ごとに.envファイルを切り替える

#はじめに

laravelで環境ごとに.envファイルを切り替えるというところで、結構詰まったので、メモとして残しておく。
**特に、最後の注意の部分はぜひ読んで欲しいです。**

#bootstrap/app.php編集

```bootstrap/app.php
+ $app->loadEnvironmentFrom('.env.' . ((getenv("ENV") ? getenv("ENV") : "local")));  #<= 追記
```


# .env ファイルのコピーを作成
```terminal
$ cp .env .env.local
$ cp .env .env.stg
```


# 作成したファイルの中身を変更

```.env.local
APP_NAME=Laravel-local
```

```.env.stg
APP_NAME=Laravel-stg
```

# ルーティングを設定

ルートパスでAPP_NAMEが表示されるようにする。

```routes/web.php

Route::get('/', function () {
    return env('APP_NAME');
});
```


# 検証
```terminal
$ export ENV=stg 
$ php artisan serve
Laravel development server started: http://127.0.0.1:8000 
```

localhost:8000にアクセスして、laravel-stgが表示されれば成功です。

環境を変えたいときは、

```terminal
$ export ENV=local
```

とするだけ。

これで完了です！


#注意
もし、上記を行っても、表示されない。真っ白な画面が表示されるだけという状態であれば、以下のコマンドを実行。


```terminal
$ php artisan config:clear
Configuration cache cleared!
```

.envファイルに環境変数が設定されているにも関わらず、env関数がnullを返す場合があります。それは、**設定ファイルがキャッシュされている**場合です。「設定ファイルがキャッシュされると、.envファイルはロードされなくなり、env関数の呼び出しは全てnullを返す」仕様らしい。



#### 詳しくは以下の記事
Laravelのenv関数で値が取得できない原因と対策
https://qiita.com/yamaji_daisuke/items/746e1e5ec3487fc88c3e


#おわりに


駆け出しエンジニアからすると、環境設定系の記述や編集は、理解が難しく、避けがちですが、少しずつわかってくると楽しいもんですね。

## 参考記事

[Laravel 5.5] 読み込む.envファイルを環境ごとに切り替える
https://qiita.com/takaday/items/b992c7d8cd69343b6626

Laravelでenvやgetenvで環境変数が読めない現象について
https://qiita.com/hiroykam/items/5f1a44cf94173476a12e
GoでHTTPサーバを立ち上げる（超基礎）

#GoでHTTPサーバを立ち上げる

```server.go
package main

import (
	"fmt"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "HTTPserver")
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}
```
##ハンドラを定義する
```
func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "HTTPserver")
}
```
・1つ目の引数：**レスポンス先**
・2つ目の引数：**リクエストの受付**
・{　}内はハンドラで行う処理内容
##ハンドラとエントリポイントを結びつけ
```
 http.HandleFunc("/", handler)
```
・1つ目の引数：エントリポイント
・2つ目の引数：呼び出したいハンドラ
##サーバの立ち上げ
```
 http.ListenAndServe(":8080", nil)
```
・1つ目の引数でポート番号を決める
【Rails】PG::AmbiguousColumn: ERROR:  column reference "name" is ambiguous

#【Rails】PG::AmbiguousColumn: ERROR:  column reference "name" is ambiguous

アソシエーションが張られた同じカラム名を持つ2つのモデルでそのカラム名を使ったメソッドを定義したところ上記のエラーが出ました。その際の対応内容をまとめます。

## 目次
* [動作環境](#動作環境)
* [状況](#状況)
* [解決策](#解決策)
* [考察](#考察)

---------------------------------------
## 動作環境
`OS : macOS 10.14.6`
`ruby : 2.6.5`
`Rails : 5.2.4.2`

## 状況

`カテゴリモデル`と`ユーザモデル`はそれぞれ`name`という同じ名前のカラム名を持ち,多対多のアソシエーションが張られている状況です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526570/978b7ae4-a20f-6bb7-133f-da9d8d473e63.png)

ここで`ユーザモデル`と`カテゴリモデル`で

それぞれにモデルのスコープメソッドを定義しています。

```ruby:category.rb
class Category < ApplicationRecord
  has_many :category_users, dependent: :destroy
  has_many :users, through: :category_users, source: :user

  #検索画面で選択したキーワード名から該当のキーワードを取得するメソッド
  scope :select_category, ->(category) { where('name = ?', category) }
end
```
```ruby:user.rb
class User < ApplicationRecord
  has_many :category_users, dependent: :destroy
  has_many :categories, through: :category_users, source: :category
  
  #カテゴリモデルのスコープ`select_category'を呼び出している
  scope :category_users, ->(category) { joins(:categories).merge(Category.select_category(category)) }
end
```

この状態でキーワードを選択して実行すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526570/ecb6c76c-6b12-6aa9-f9b4-0306e137b42b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526570/74e6901c-8b62-b036-d08e-1ede49718c5a.png)

`PG::AmbiguousColumn: ERROR:  column reference "name" is ambiguous`というエラーが出ます.

## 解決策

上記のエラーは`name`カラムが曖昧だというエラーです。
そこでカテゴリモデルのスコープメソッドにテーブル名を付けます。

```ruby:category.rb
class Category < ApplicationRecord
  has_many :category_users, dependent: :destroy
  has_many :users, through: :category_users, source: :user

  # name -> categories.nameとすることでカテゴリテーブルのnameカラムと明示する
  scope :select_category, ->(category) { where('categories.name = ?', category) }
end
```
無事、検索ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526570/28ba8399-6af0-7ae8-81de-362646e23f43.png)

## 原因

下記のSQLログの末尾を見ると`Where name = 'abcc..'`にテーブル名が付いていないことがわかる.

```bash
: SELECT  "users".* FROM "users" INNER JOIN "category_users" ON "category_users"."user_id" = "users"."id" INNER JOIN "categories" ON "categories"."id" = "category_users"."category_id" WHERE name = 'abccccdd' 
```

つまり,`Userモデル`から`Categoryモデル`のスコープメソッドを呼び出した際に,ActiveRecordではどちらのテーブルの`name`か判別することができないためエラーが発生したと考える
gunicornで立てたサーバをコード変更時にリロードする

GAE向けに flask アプリを手元で開発している時、ホットリロードどうやるんだっけと一瞬考えたわけです。

## 答え

`gunicorn` の `--reload` 起動オプションまたは設定ファイルで `reload: True` を指定しましょう。

## どうしてこんな記事が生まれたのか

どうも古い知識がキャッシュされていたらしく、くそー gunicorn は watchdog とか使ってリロード構成作らないといけなくて古臭いぜと思い込んでいたのですが普通に `--reload` が実装されていて衝撃を受けたからです。[changelog 見ていると 2014年に追加されていた](https://docs.gunicorn.org/en/stable/2014-news.html#id7)らしい。自分が python で web アプリケーションを主に書いていたのはちょうど 2014年くらいまでで、そこから ruby に転向していたのですが、自分の知識に適切に「この知識は1年以上前のものです」ってレコメンドしてくれる機能が欲しい。
k8s Deploymentを全削除する

# はじめに
kubernetesでdeploymentなどの特定のリソースを全て削除するための方法を記載する。
deployment以外のリソースを全削除したい場合も有効。

## kubernetesのDeploymentを全削除する

```
$ kubectl get deploy --no-headers -o custom-columns="NAME:{metadata.name}" | xargs kubectl delete deploy
```


## kubernetesの指定リソースを全削除する

```
$ kubectl get[リソース名] --no-headers -o custom-columns="NAME:{metadata.name}" | xargs kubectl delete [リソース名]
```
JavaScript for Automation (JXA) 



java scriptでMacを自動化できる



## アプリケーションの起動
	function run(){
        var app = Application("apps");
	}


## 引数を渡してiTuneで曲を再生


	function run(argv){
		if(argv.length == 2){
			console.log(argv[0] + " : " + argv[1] + " を再生します");
			var app = Application("iTunes");
			app.playlists[argv[0]].tracks[argv[1]].play();
		}

		else{
			console.log("'プレイリスト' '曲名' を指定してください");
			}
	}


## scriptの実行
###実行
	osascript -l JavaScript sample.js

###引数を渡して実行
	osascript -l JavaScript sample.js testPlay hoge
ネストループをラベルで指定して抜ける方法

``` swift
struct Hoge {
    let test: [String]
    let test1: [String]
}

let hoge = Hoge.init(test: ["3","3","3","4","3","3"] , test1: ["3","3","3","4","3","3"])

outer: for i in hoge.test {
    inner: for t in hoge.test1 {
        if i == t {
            print("inner")
            break inner
        } else {
            print("outer")
            break outer
        }
    }
}
```


```
inner
inner
inner
outer
```
for文の前にラベルをつけることで抜ける際にどのループ文を抜けるのか指定することができる。
While文やswitch文でも使うことはできる。
Excel VBA + SeleniumBasic でサイボウズログイン、在席ステータスを取得

## 環境
windows10
Excel（Office365）
Google Chrome ver 83.0.4103.106
SeleniumBasic ver 2.0.9.0
chromedriver ver 83.0.4103.39
サイボウズ試用版

## サイボウズログイン、在席ステータスを取得
``` vb
Sub 在席ステータスを取得する_Click()
    Dim Driver As New Selenium.WebDriver
    Dim seatStatus As String
    
    ' Chromeを開く
    Driver.Start "chrome"
    ' サイボウズを開く
    Driver.Get "https://XXXXXXX.cybozu.com/login"
    ' ログイン名を入力
    Driver.FindElementByXPath("//*[@id='username-:0-text']").SendKeys "sample@mail.com"
    ' パスワードを入力
    Driver.FindElementByXPath("//*[@id='password-:1-text']").SendKeys "XXXXXXXXXXXX"
    ' ログインボタンを押す
    Driver.FindElementByXPath("//*[@id='login-form-outer']/form/div[4]/div[2]/input").Click
    ' サイボウズofficeをクリック
    Driver.FindElementByXPath("/html/body/div[5]/div/div[1]/div/a[2]").Click
    ' 在席ステータスを取得する
    seatStatus = Driver.FindElementByXPath("//*[@id='cb7-portlet-body-110']/form/table/tbody/tr/td/table/tbody/tr/td[2]/a").Text
    ' セルに在席ステータスを書き込む
    Range("B3").Value = seatStatus
End Sub
dockerfileでパスワードを求めないsudoer作り(Alpine、Debian、Ubuntu、Centos)

## 紹介する内容
- Alpine、Debian、Ubuntu、Centosの例です
  - uidとデフォルトshell設定を含みます

## 結論
- Alpine linux他はsudoerの作り方が似てます
- dockerのvolumeでpermission denied問題解決や、作りたいときに使えます


## 紹介始めます
### ディレクトリ構成
全体ソースコードは https://github.com/cheekykorkind/qiita-example/tree/master/dockerfiles/no-password-sudoer で確認できます

- 全体図
Dockerfileの名はどのLinuxかをわかりやすく表現しました。  
AlpineDockerfileは`Alpine 3.11`、  
CentosDockerfileは`Centos 7`、  
DebianDockerfileは`Debian buster`、  
UbuntuDockerfileは`ubuntu 18.04`。
![allD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/e9d66c90-b96d-3faf-d4c7-c3eba30c8c4a.png)



### Dockerfileの中身
  - AlpineDockerfile
    - Alpine linuxだけがsudoerの作り方が違う気がします

```
FROM alpine:3.11

RUN apk add sudo

RUN adduser -D -u 1001 -s /bin/sh -G wheel alpine-sudoer
RUN echo '%wheel ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
```

  - CentosDockerfile

```

FROM centos:7

RUN yum -y install sudo

RUN useradd --uid 1001 --create-home --shell /bin/bash -G wheel,root centos-sudoer
RUN echo '%wheel ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
```


  - DebianDockerfile

```
FROM debian:buster-slim

RUN apt update && apt install -y sudo

RUN useradd --uid 1001 --create-home --shell /bin/sh -G sudo,root debian-sudoer
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
```

  - UbuntuDockerfile

```
FROM ubuntu:18.04

RUN apt update && apt install -y sudo

RUN useradd --uid 1001 --create-home --shell /bin/bash -G sudo,root ubuntu-sudoer
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
```


### 試し順番です
1. デレクトリー移動
  - `cd qitta-example/dockerfiles/no-password-sudoer`

2. dockerコンテナをバックグラウンドで起動
  - `docker-compose up -d`

3. 各々のdockerコンテナにsudoerが作られたか確認します
  - `docker exec -it alpine-sudoer /bin/sh -e -c "cat /etc/passwd | grep alpine-sudoer"`
  - `docker exec -it debian-sudoer /bin/sh -e -c "cat /etc/passwd | grep debian-sudoer"`
  - `docker exec -it ubuntu-sudoer /bin/bash -e -c "cat /etc/passwd | grep ubuntu-sudoer"`
  - `docker exec -it centos-sudoer /bin/bash -e -c "cat /etc/passwd | grep centos-sudoer"`
![checkSudoers.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/7a36deb8-f974-fe63-bb95-bacddb21a1f0.png)


4. (選択)自由に確認したいなら、入りたいdockerコンテナに入ります
  - `docker exec -it alpine-sudoer /bin/sh`
  - `docker exec -it debian-sudoer /bin/sh`
  - `docker exec -it ubuntu-sudoer /bin/bash`
  - `docker exec -it centos-sudoer /bin/bash`
EC2のインスタンスメタデータ確認

EC2インスタンス上で実行。169.254.169.254/latest/meta-data/にアクセスする。REST形式のAPIになっているので、取得したい要素を指定する

```console
% curl http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hibernation/
hostname
iam/
identity-credentials/
instance-action
instance-id
instance-life-cycle
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups
services/
```

例）hostnameを取得したい場合

```
% curl http://169.254.169.254/latest/meta-data/hostname
ip-XXX-XXX-XXX-XXX.ap-northeast-1.compute.internal
```