OmniAICreator/Qiita-1.07M huggingface dataset:
LaravelによるWebアプリケーション開発入門 第一回 環境構築

## はじめに
日頃Laravel5.2を書いているが、環境を1から構築したことなかったのでやってみます。
簡単なメッセージアプリケーションを作成します。

第一回は各種インストールからLaravelのプロジェクト作成までを行います。
こちらの環境がWindowsなので、それに沿って記述させていただきます、ご了承ください。

## 最終的に目指す環境
### 開発環境
* PHP 7.2.x
* Laravel 5.5.x
* Vue.js 2.5.x
* TypeScript 
* Webpack
* Docker

### 実行環境等
* AWSもしくはHeroku
* Cent OS
* Apache

### パッケージ管理
* npm
* composer

### PC環境・使用ツール
* Windows 10 64bit Professional
* Visual Studio Code 64bit
* GitHub Desktop

## PHPのインストール
[PHPの公式サイト](https://secure.php.net/downloads.php)からお使いの環境に合ったものをDLします。
こちらはWindowsなので、7.2.xの[WindowsDownloads](https://windows.php.net/download#php-7.2)をクリックします。
Apacheで動かすことを考えるのでx64 Thread SafeをzipでDLします。
![](https://qiita-image-store.s3.amazonaws.com/0/262177/ab6df9bd-8263-544d-5c8d-368f46c5f094.jpeg)
解凍した中身を任意のディレクトリに配置し、PATHを設定すれば完了です。

コマンドで確認してみましょう。

```powershell:PowerShell
PS > php -v
PHP 7.2.6 (cli) (built: May 23 2018 20:29:41) ( ZTS MSVC15 (Visual C++ 2017) x64 )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
```

## Composerのインストール
[公式サイト](https://getcomposer.org/download/)からWindows用のインストーラーをDLして手順に従ってインストールします。

```powershell:PowerShell
PS > composer -V
Composer version 1.6.5 2018-05-04 11:44:59
```

## Laravelのインストール
### プロジェクトの作成
プロジェクトを作成するディレクトリに移動し、 `composer create-project laravel/laravel [プロジェクト名] "5.5.*" --prefer-dist` コマンドを実行します。

```powershell:PowerShell
PS > composer create-project laravel/laravel laravel-messenger "5.5.*" --prefer-dist
Installing laravel/laravel (v5.5.28)
  - Installing laravel/laravel (v5.5.28): Downloading (100%)
Created project in laravel-messenger
(省略)
```

指定したディレクトリにプロジェクトファイルが生成されていれば完了です。
![](https://qiita-image-store.s3.amazonaws.com/0/262177/8ffc7ec5-a543-0959-00dc-ddc3d9bcfaa4.png)


### ローカル開発サーバで確認
`php artisan serve` でローカル開発サーバが立ち上がるので、 http://localhost:8000 にアクセスして以下の画面が表示されるか確認します。
![](https://qiita-image-store.s3.amazonaws.com/0/262177/522429e8-9de5-30a3-2e16-1b0b4bb4c3af.png)

## リポジトリ作成
GitHubでバージョン管理を行うのでリポジトリを作成します。

```powershell:PowerShell
PS > git init 
```

GitHub Desktopでpublishして完了です。

## 次回
次回はLaravelのView、blade周りについて解説します。
公開しました => [第二回](https://qiita.com/toro_ponz/items/76c5456c86af18720f41)

## 参考サイト
* PHPのダウンロードとインストール | PHPのダウンロードとインストール (2018/06/11)
  - https://www.phpbook.jp/tutorial/install/index1.html
* PHP7をwindows7にインストールする - Qiita (2018/06/11)
  - https://qiita.com/daijinload/items/3eb3d7d776143b3c5392
* Composer を Windows にインストールする手順 | WEB ARCH LABO (2018/06/11)
  - https://weblabo.oscasierra.net/php-composer-windows-install/
* Composerをインストールしてみた - Qiita (2018/06/11)
  - https://qiita.com/kakijin/items/02364adacf36410f449e
* インストール 5.5 Laravel (2018/06/11)
  - https://readouble.com/laravel/5.5/ja/installation.html
Laravelのメンテナンスモード切替をWordPressにも適用する方法

### はじめに

Laravel5でのメンテナンスモードの実装方法についてはこちらをご覧ください
https://qiita.com/qwe001/items/0e393040127d66879fad

### 何が問題か

Laravelで作ったサイトがある。このサイトに、WordPressを新たに導入した。
今回、サイトをメンテナンスモードにする必要が出てきた。

Laravelで作ったページは問題なく切り替えることが出来るが、
WordPressはそういった仕組みを入れていないため、
Laravelでメンテナンスモードに切り替えても、WordPress制作ページはメンテナンスモードにならない。

WordPressにメンテナンスモード用のプラグインを入れてもいいが、切替手順が煩雑になって手間である。

### 何がしたいか

* Laravelでメンテナンスモードに切り替えた時、WordPress制作ページも自動的にメンテナンスページにリダイレクトするようにしたい
* しかし、メンテナンスモード中もWordPress制作ページを編集・確認できるように、WordPress管理者ログイン中はリダイレクトしないようにする
* また、WordPress管理画面と、そのログインページもリダイレクトしないようにする(管理者ログアウトしたら再ログインできなくなるのを防ぐため)

### ディレクトリ構成

```
{Laravelプロジェクト名}/
├ app/
├ public/
│ ├ js/
│ │ └ common.js
│ ├ css/
│ │ └ common.css
│ ├ images/
│ │ └ title.png
│ ├ {WordPressディレクトリ名}/
│ │ ├ wp-login.php
│ │ ├ wp-admin/
│ │ └ wp-content/
│ │ 　 └ themes/
│ │ 　 　 └ {テーマ名}/
│ │ 　 　 　 ├ index.php
│ │ 　 　 　 └ functions.php
│ └ index.php
├ resources/
│ └ views/
│ 　 ├ index.blade.php
│ 　 └ errors/
│ 　 　 └ 503.blade.php
├ routes/
│ └ web.php
└ storage
　 └ framework
　 　 └ (down)
```

http://www.example.com/ に、Laravelで作ったトップページ(index.blade.php)が、
http://www.example.com/{WordPressディレクトリ名}/wp-login.php に、WordPressのログインページ、
http://www.example.com/{WordPressディレクトリ名}/{WordPress制作ページ名} に、WordPress制作ページがあるイメージ。

### 下準備

予め、メンテナンス画面のルーティング設定をしておくこと

```php5:{Laravelプロジェクト名}/routes/web.php
Route::get('/maintenance', function(){ Abort(503); });
```


### 実装

```php5:{Laravelプロジェクト名}/public/{WordPressディレクトリ名}/wp-content/themes/{テーマ名}/functions.php
function is_admin_user()
{
    $current_user = wp_get_current_user();

    if(user_can($current_user, 'administrator')){
        return true;
    }

    return false;
}

function redirectToMaintenancePage()
{
    $storage_path = $_SERVER['DOCUMENT_ROOT'] . '/../storage/';
    $file = $storage_path . 'framework/down';

    if(file_exists($file)){
        $protocol = empty($_SERVER['HTTPS']) ? 'http://' : 'https://';
        $page_hostname = $protocol . $_SERVER['HTTP_HOST'];

        $current_url = $page_hostname . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); // クエリパラメータを除去。WPログイン画面用

        $maintenance_url = $page_hostname . DIRECTORY_SEPARATOR . 'maintenance'; // メンテナンス画面のURL
        $wp_login_url = wp_login_url();
        $wp_admin_url = admin_url();

        if($current_url === $wp_login_url || $current_url === $wp_admin_url || is_admin_user()){
            //
        }
        else {
            wp_redirect($maintenance_url);
            exit;
        }
    }
}
add_action( 'init', 'redirectToMaintenancePage' );
```

### ロジック

Laravelをメンテナンスモードに切り替えると、「storage/framework/」直下に「down」という名前のファイルが生成される
このファイルがあることを、Laravelはメンテナンスモード切替の判断にしている。

WordPress配下のディレクトリも、このファイルがあればLaravelのメンテナンス画面(503.blade.php)にリダイレクトさせてるというわけ
githubでブランチが更新されてもリンクが死なないパーマリンクを作る方法

# 問題

githubのURLはデフォルトではブランチ名/タグ名をURLに含む。

* 例: https://github.com/akka/akka-http/blob/master/README.md

そのためブランチが更新されるとリンク先のファイル状態が変わったり、ファイルが移動しているとリンクが切れてしまう。
これはソースコード中にコメントとしてgithubへのリンクを置く場合などに都合が悪い。

# 一般的な解決法

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">githubなどのURL貼るとき(特に行番号付きの場合)は、branchではなくhash値(かtag)のURLにしてから貼れ、って定期的に言っていきたい、というか言わなくてもみんなそうしてほしい<br>(あと、yボタン押すだけでhash値のURLになるショートカットキーがあります)</p>&mdash; Kenji Yoshida (@xuwei_k) <a href="https://twitter.com/xuwei_k/status/907264443649634305?ref_src=twsrc%5Etfw">2017年9月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

[Getting permanent links to files \- User Documentation](https://help.github.com/articles/getting-permanent-links-to-files/)

```
https://github.com/akka/akka-http/blob/master/README.md
↓
https://github.com/akka/akka-http/blob/12abd6f707348c9b8f3cd03b1a3a78efe25e0b90/README.md
```

というわけで基本的に「y」を押してURL中のブランチ名をその時点でのコミットハッシュに置き換えたURLにすれば良い。

# 一般的な解決法の問題点

概ね問題ないのだが、これにより生成されたURLは40文字のコミットハッシュがそのまま含まれるのでコメントなどに書くにはいささか長い。通常のリポジトリならばコミットハッシュの前方8文字で十分である。
また、githubの「y」ショートカットの挙動が少し変で実際に置き換えられたURLへページが遷移しないことも気持ちが悪い。

そこで、ブックマークレットを作って上の問題を解決した。

[GithubでURL中のブランチ名/タグ名をコミットハッシュ\(8桁\)に置き換える \- Hatena::Let](http://let.hatelabo.jp/den8/let/hLHVkfXVrtAa)

## 使い方

1. [GithubでURL中のブランチ名/タグ名をコミットハッシュ\(8桁\)に置き換える \- Hatena::Let](http://let.hatelabo.jp/den8/let/hLHVkfXVrtAa)に行く
2. オレンジのアイコンからブックマークバーへD&D
3. github.comの任意のページを開く
4. ②で作成したブックマークレットをクリック
5. (成功していれば)ブランチ名が8桁のコミットハッシュに置き換えられたURLに遷移
Railsのプロジェクトにgem 'redcarpet' を用いてマークダウンエディタを導入してみた

# 背景
サービスの修正や機能開発の際に、リリース報をうちたい。
社内のメンバーはマークダウンでの記述に慣れているため、今回はマークダウンで書いてもらうことを前提とする。

# 流れ
- gem 'redcarpet'　をインストール
- markdown_helper.rbを作成し、オプションを追加
- フォームでマークダウンで記述


# Gem追加

`$ bundle install redcarpet`

# Helper追加

```ruby:markdown_helper.rb
# gem 'redcarpet' 用
module MarkdownHelper
  def markdown(text)
    unless @markdown
      options = {
        filter_html: true,
        autolink: true,
        space_after_headers: true,
        no_intra_emphasis: true,
        fenced_code_blocks: true,
        tables: true,
        hard_wrap: true,
        xhtml: true,
        lax_html_blocks: true,
        strikethrough: true
      }
      renderer = Redcarpet::Render::HTML.new(options)
      @markdown = Redcarpet::Markdown.new(renderer)
    end

    @markdown.render(text).html_safe
  end
end
```


# フォームでマークダウンによる記述を行う

![スクリーンショット 2018-07-13 20.23.25.png](https://qiita-image-store.s3.amazonaws.com/0/121435/89ea56fc-d1c5-93a8-f31b-3352b83fc2f2.png)


# レンダリング

任意の箇所でhelper内にあるmarkdownメソッドを呼び出します。

```ruby:show.html.slim
= markdown(@blog.content)
```

# 実際の表示画面

![スクリーンショット 2018-07-13 20.23.01.png](https://qiita-image-store.s3.amazonaws.com/0/121435/c37d614d-f3da-01b6-97a2-1c6a22e633c1.png)


# 参考記事
オプションの例が日本語で豊富に書かれている
https://programming-beginner-zeroichi.jp/articles/57
Prometheus + mtail でログ監視

## Prometheus + mtail でログ監視
最近は、個人的に [Prometheus](https://prometheus.io/) がブームです。
なので、Prometheus を使ったネタを1つ。

[mtail](https://github.com/google/mtail) の program ファイルは既に作成済みと仮定する。

mtail をサービス化する。

```bash:/etc/systemd/system/mtail.service
[Unit]
Description=mtail Service

[Service]
Type=simple
EnvironmentFile=-/etc/default/mtail
ExecStart=/foo/bar/mtail $OPTIONS
PrivateTmp=true

[Install]
WantedBy=multi-user.target
```

起動時の引数は別にもたせる。

```bash:/etc/default/mtail
# 複数のログファイルを監視する時は、"-logs" を増やす
OPTIONS="-progs /foo/bar/hoge.mtail -logs /foo/bar/hoge.log"
```

mtail の自動起動設定 & 起動する。

```bash:
systemctl enable mtail.service
systemctl start mtail.service
```

TCP/3903 が上がっている事を確認出来たら、Prometheus で監視を開始する。
その辺は、また今度。

## 仲間募集中
[弊社](https://www.nittsu-infosys.com/)ではエンジニアを募集中です。インフラからアプリ、ユーザサポートまで幅広く業務を行ってます。
https://www.nittsu-infosys.com/recruit/2019/index.html
MSX stick

```stick.c
/*
z88dk / WebMSX
zcc +msx -lndos -create-app stick.c
bload"cas:",r
*/

#include <msx/gfx.h>
#include <stdio.h>

const int dx[] = { 0, 0, 1, 1, 1, 0, -1, -1, -1 };
const int dy[] = { 0, -1, -1, 0, 1, 1, 1, 0, -1 };

void main()
{
	int px = 0;
	int py = 0;

	printf("\xc");

	while (! get_trigger(0)) {
		int st = get_stick(0);
		px += dx[st];
		py += dy[st];
		printf("\xbST:%d X:%d Y:%d", st, px, py);
	}
}
```
Raspberry Piの公式OSインスト―ル方法

#RaspberryPi
学校の友人の卒業進級製作で出てきたラズベリーパイをみて面白そうと思い・・・

![IMG_2206.JPG](https://qiita-image-store.s3.amazonaws.com/0/249333/0e2a421b-9485-6d7a-1caa-f10cdaf1ddb5.jpeg)
次の日に調べてすぐ買っちゃった。
どうせもうすぐ夏休みに入るし、暇だからいじる時間めっちゃあるし大丈夫でしょ！
くらいの気持ちで買いました。
値段は画像にあるケース含めて6000ちょい。
安い！・・・（ですよね？）
そしてRaspberryPiのversionはRaspberryPi 3 Model B+
なんかもう一つを買いそうな気がするので公式OSのインストール方法を書き残しておこうと思います。
まずそもそもRaspberry自体に記憶する場所がないのでmicroSDを使います。
SDカードをPCにとりあえずセットします。
で、これはwindowsの人だけの作業になるのですがOSをインストールするためにまずはSDカードをフォーマットします。
使うのは<a href="https://www.sdcard.org/jp/downloads/formatter_4/">この</a>サイトの下辺りにある
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/249333/798bba71-5bfd-0f8f-046a-5376e8e8acdd.png)これを使っていきます。
Windows用ダウンロードを押すとこんなの![無題1.png](https://qiita-image-store.s3.amazonaws.com/0/249333/934347fd-99a1-5422-a28a-9ddb315fec4c.png)
が出てきますが同意するとダウンロードが始まります。
そしたらSD_CardFormatter0500SetupJP.exeというのがダウンロードされてるのでこれを起動します。
で、とくに設定もないので次へを押しまくりプログラムの起動にレ点を入れて完了を押します。
するとこの画面
![無題2.png](https://qiita-image-store.s3.amazonaws.com/0/249333/d00878e0-b5e1-785b-30e6-faf0b2437657.png)
が出るのでSDcardを選択してフォーマとボタンを押します。
すると勝手にフォーマットしてくれるのでこれでSDカードの下準備は完了です。

次にRaspberryPiの<a href="https://www.raspberrypi.org/downloads/noobs/">公式</a>に飛びます。
で、画像のやつをダウンロードします。（僕の環境ではダウンロードに１時間ほどかかりました）
![無題2.png](https://qiita-image-store.s3.amazonaws.com/0/249333/56bac4f7-88da-3a54-9f08-4ca78c238373.png)
で、ダウンロードが終わったらZIPファイルを解凍します。
あとは解凍が終わればその中身をSDカードに移してRaspberryPiにそのSDカードを指せばミッションコンプリートです！

なかなかよくわからないと思っていたRaspberryPiもふたを開ければ先人の知恵がたくさん転がっているので大したことがないなと思いました（まだOSをインストールしただけ）

#ちなみに
今回僕が買ったものは<a　href="https://www.amazon.co.jp/gp/product/B07CNRTCZ9/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1">RaspberryPi 3 Model B+本体</a>と<a　href="https://www.amazon.co.jp/gp/product/B015J44R0U/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1">TranscendのmicroSD 32G</a>の二つのみです。
あと最低限必要なものは電源用のマイクロUSBと画面出力用のHDMIケーブル、あとはマウスとキーボードくらいです。
僕は電源用のマイクロUSBはPS4のコントローラーの線を使い、画面出力用のHDMIは使われていなかったPS３のもので代用しています。
あとはまた今後作っていくものによっては買い足さなければならないものもありますが、使える金額がある程度決まっている学生にとってRaspberryPiはとても安価でIoTについて学べるものだなと今のところ思っています。（RaspberryPi財団の回し者感）
tmux基本操作


* tmuxのデフォルトでの操作方法を度々忘れるので、自分用に備忘メモ。

## プレフィックス
* デフォルトは「Ctrl + B」

## 新規セッションを開始する

* 方法①

	``` bash
	tmux
	```

* 方法②
	
	``` bash
	tmux new-session
	```


## 既存セッションを確認する
* 作成済みセッションを一覧表示する

	``` bash
	tmux ls
	```
	
## セッションをデタッチ
* 現在のセッションから抜ける

``` bash
[prefix] + d
```
	
## 既存セッションにアタッチする

* 直近使用されたセッション

	``` bash
	tmux attach
	```

* セッション番号を指定

	``` bash
	tmux attach -t (セッション番号)
	```
Visual Studio for Mac 複数起動

Windows感覚だと使いたくなる機能がコマンドなので備忘録

ちなみに、Macのアプリはほとんどが単一起動です。

## Visual Studioの人
ターミナルから次のコマンドを実行

```
open -n /Applications/Visual\ Studio.app
```
こんな感じ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/91552/20b64d20-3def-8f8e-1bd4-af0d5cd9a637.png)


## Xamarin Studioの人はこっち

```
open -n /Applications/Xamarin\ Studio.app
```
plenvでperl 5.28.0をinstallしようとしたらエラーがでた

# 概要
Mac book Pro (macOS Sierra)
を使ってて、plenvでperl 5.28.0をinstallしようとしたらエラーがでた時のメモ

# perl 5.28.0をinstallしてみる
```
$ plenv install 5.28.0
Installing 5.28.0 as 5.28.0
WARN: [cpan_perl_releases] not found the tarball for perl-5.28.0
WARN: [perl_releases_page] This page is 3 or more days old. ignore
WARN: [search_cpan_org] Cannot get content from http://search.cpan.org/dist/perl-5.28.0: 599 Internal Exception
ERROR: Cannot find the tarball for perl-5.28.0
ABORT
```

エラーが出てinstallできませんでした。
少し探してみると、perl-buildのupdateが必要だと言うことがわかりました。

参考: https://www.slideshare.net/tokuhirom/plenv-and-perl-build-and-searchcpanorg

# ということでperl-buildをupdateする
と思ったらそもそもperl-buildが入っていなかった

```
$ ls -a .plenv
.		build		shims		versions
..		cache		version
```

たしかbrewで入れてたと思うので消した。

```
$ brew uninstall perl-build 
Uninstalling /usr/local/Cellar/perl-build/1.13... (331 files, 9.6MB)
```

そして、perl-buildをinstallした

```
$ git clone git://github.com/tokuhirom/Perl-Build.git ~/.plenv/plugins/perl-build/
```

# 今度こそ perl 5.28.0をinstallしてみる
一応、itermを再起動してinstallしてみる

```
$ plenv install 5.28.0
```

これでinstallできました。

```
$ plenv versions
  system
* 5.18.0
  5.28.0
```
個人的によく使うMySQL操作まとめ

# はじめに
自分用メモなので書いてある内容がバラバラですがご了承ください:bow:

# 基本操作
## select
```sql
SELECT * FROM table1 WHERE column1 = 'xxx' AND column2 > 0;
```

大文字小文字を区別したい時

```sql
SELECT * FROM table1 WHERE BINARY column1 LIKE 'pattern';
```

### 内部結合
```sql
SELECT * FROM table1 
    INNER JOIN table2 ON table1.column1 = table2.column2 
    WHERE table1.column1 = 'xxx';
```

## insert
```sql
INSERT INTO table1(column1, column2) values('yyy', 1);
```

## update
```sql
UPDATE table1 SET column1 = 'zzz' WHERE column2 > 2;
```

# index 操作
## index を追加
```sql
ALTER TABLE table1 INDEX index1(column1);
```

## 複合index を追加
```sql
ALTER TABLE table1 ADD INDEX index1(column1, column2);
```

## index を削除
```sql
ALTER TABLE table1 DROP INDEX index1;
```

## index を確認
```sql
SHOW INDEX FROM table1;
```

## 最大キー長
INDEXのキーは
MySQL5.6以前 → デフォルト設定で767bytesまで
MySQL5.7以降 → デフォルト設定で3072bytesまで

utf8の場合
varchar(255) * 3bytes = 765bytes < 767bytes
varchar(1024) * 3bytes = 3072bytes

utf8mb4の場合
varchar(191) * 4bytes = 764bytes < 767bytes
varchar(768) * 4bytes = 3072bytes

[参考](http://gihyo.jp/dev/serial/01/mysql-road-construction-news/0032, "gihyo.jp")

# テーブル操作
## テーブルの中身を空にする
```sql
TRUNCATE TABLE table1;
```
　　
この時，外部キーを使用していて

```
Cannot truncate a table referenced in a foreign key constraint ...
```
のようなエラーが出た場合，一時的に外部キーの制約を外して対応

```sql
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE table1;
SET FOREIGN_KEY_CHECKS = 1;
```

## テーブルを削除する
```sql
DROP TABLE table1, table2;
```

## カラムを追加する
```sql
ALTER TABLE table1 ADD column1 column_definition;
```


# warning の中身を見たい時
```sql
SHOW WARNINGS;
```

# mysqldump関連
## export
```sh
mysqldump -u user_name -p db_name > /path/file.sql
```

テーブル指定

```sh
mysqldump -u user_name -p db_name table_name1 table_name2 > /path/file.sql
```

where句の指定

```sh
mysqldump -u user_name -p db_name table_name --where="column1 = 'xxx'" > /path/file.sql
```

## import
```sh
mysql -u user_name -p db_name < /path/file.sql
```
この時、import先のDBは先に作成しておく必要がある。


# my.cnf設定
## my.cnf場所検索
```sh
mysql --help | grep my.cnf
```

## my.cnf設定
my.cnf編集

```sh
sudo vi /etc/my.cnf
```

以下を追記

```
[mysqld]
character-set-server=utf8mb4
skip-character-set-client-handshake

[client]
default-character-set=utf8mb4
```

mysqlを再起動

```sh
sudo /etc/init.d/mysqld restart
```
archlinuxでlightdmを使うと日本語が表示されない

# 環境
* archlinux
* デスクトップマネージャ
 * lightdm
* デスクトップ環境
 * xfce4

# 現象
/etc/locale.confも/etc/locale.genも
LANG=ja_JP.UTF-8になっている(もちろんlocale-genもしている)のに、

```/etc/locale.conf

LANG=ja_JP.UTF-8
#LANG=en_US.UTF-8
```

```/etc/locale.gen
...
ja_JP.UTF-8
en_US.UTF-8
...
```

```
$ locale-gen
```

lightdmからlogin後に日本語が表示されない。
xfce4-terminal上で確認するとLANG=en_US.utf8となっている

```
$ env| grep LANG
LANG=en_US.utf8
```

sshで別なマシンからloginするとLANG=ja_JP.UTF-8となるためlightdmが原因と思われる。
さらにUTF-8でなくutf8(小文字&ハイフンなし)なのも気になる。
知らないところに言語設定があってそれを読んでいるハズ。

```
$ ssh archlinux.local
...
$ env| grep LANG
LANG=ja_JP.UTF-8
```


# 原因
lightdmが~/.dmrc,/var/cache/lightdm/$USERNAME.dmrcにある言語設定を読むため。
.dmrcとはディスプレイマネージャ(lightdm)のセッション情報を保存するファイル。

```.dmrc
[Desktop]
LANGUAGE=en_US.utf8
```

lightdmの設定ファイルはlightdm.confにもあるがこちらではない。
lightdmをstraceしてやっと見つけました。

# 対策
.dmrcに正しい言語情報を記述する

```.dmrc
[Desktop]
LANGUAGE=ja_JP.UTF-8
```

\#日本語フォントを入れて使う設定しないと、文字化け(日本語の文字コードを出力しようとするが、フォントが存在しないため□豆腐の中に文字コードが表示される)して日本語が表示されないため注意する
【非エンジニアによるIT勉強レポート】Linuxコマンドについて

# 環境
環境：Raspberry Pi 3 B+
OS：Raspbian

#対象
スーパー初心者です。
なので、**「え？コマンドって何？美味しいの？？」**みたいな人が対象です。
IT企業に勤めたての営業レベルだと解釈しやすいかも。

# 経緯
私、IT企業で営業をやっており、普段サーバやクラウドを担いで営業しております。
自分が売っているものがどういうものか、勉強はしているもの、触ったことがありませんでした。
知り合いの**「Raspberry Pi 面白いよ！」**の一言に触発され、自分でRaspberry Piを触りつつ、実際自分が売っているサーバのOSについて勉強したいと思った次第です。

#そもそもOSとは、、、
もうね、サーバとか程遠い人種の人には、全く分からない、OS。
Operating System：オペレーティングシステム
の略になります。
つまり、コンピュータの基本動作を実現する**「基本ソフトウェア」**となります。
コンピュータの総司令官ですね。
スマホのiOSとか、Androidと一緒というと、少しイメージし易いかもです。

#代表的なOSについて
・Windows
・Linux
　-Red Hat
　-CentOS
　-Ubuntu
　-Raspbian
・UNIX
　-macOS
　-NetBSD
　-Solaris
などなど。。。

#じゃーコマンドって何？
**コンピュータに対する命令文**と解釈してもらうといいかと。
入力する環境としては2種類あります。
GUI環境とCUI環境
GUI環境：Graphical User Interface（グラフィカル環境）
CUI環境：Character User Interface（テキスト環境）
コマンドで操作するので、CUI環境になります。

～2018/08/22 追記～
CUI環境のことをCLI環境ともいいます。
CLI環境：Command Line Interface（テキスト環境）
世界的にはCLIというみたいです。

#端末でコマンドを入力する
Raspberry Pi の場合は、
**①「Control」キー ＋ 「Alt」キー ＋ 「F1」キー**
この場合は、ユーザ名もパスワードも入力された状態で開けます。
**②「Control」キー ＋ 「Alt」キー ＋ 「F2」～「F6｝キー**
この場合は、ユーザ名とパスワードが必要です。
**③「Control」キー ＋ 「Alt」キー ＋ 「T」キー**
この場合も、ユーザ名もパスワードも入力された状態で開けます。


```
pi@raspberrypi:~$




```

こんな感じででてきます。

コマンドは、
**大文字と小文字は厳密に区別される**
**全角文字は使えない**
**スペルミスやスペース入力ミスがあると、エラーになる**
となりますので、ご注意ください。

#コマンドプロンプトとは
```
pi@raspberrypi:~$
```
これです。
詳しく分解すると、
**pi**：ログインしているユーザ名
**raspberrypi**：ホスト名
**~**：現在作業中のフォルダ（カレントディレクトリ）
※カレントディレクトリとは、現在開いているディレクトリ（フォルダ）のことをいいます。
**$**：プロンプト記号

#コマンド
まずは全く実践的ではないですが、コマンドを打つということに慣れていきます。
コマンドは入力後**「Enter」キー**を押します。


■現在の日付と時刻を表示

```
pi@raspberrypi:~$date
```

■カレンダーを表示

```
pi@raspberrypi:~$cal
```

～2018/08/22 追記～
■ipconfig

```
pi@raspberrypi:~$ipconfig
```
IPアドレスやサブネットマスク、デフォルトゲートウェイなど、ネットワークに関する設定を表示するコマンドです。
Windows系だと「**ipconfig**」となります。

■pingを飛ばす

```
pi@raspberrypi:~$ip　192.168.●.●
```
※IPアドレスは例です。
固定IPアドレスに対して、pingを飛ばします。

■taraceroute

```
pi@raspberrypi:~$taraceroute
```
特定のIPアドレスに対する経路を確認するコマンドです。
どのような経路をたどって、そのIPアドレスまで到達しているかを確認できます。
Windows系だと「**tracert**」となります。

■arp

```
pi@raspberrypi:~$arp
```
ARPテーブルの情報を表示するコマンドです。
同じネットワークにいるコンピュータのMACアドレスを確認することができます。

■netstat

```
pi@raspberrypi:~$netstat
```
コネクション情報（接続しているIPアドレスやポート番号）やルート情報を表示するコマンドです。
送受信したパケット数やエラーパケット数など、NICの統計情報も表示できます。


～2018/10/04 追記～
■root権限へ変更

```
$　sudo su
```
このコマンドでroot権限へ変更できます。
色々調べていると、Ubuntuには、デフォでrootがないみたいです。。


■再起動

```
$　sudo reboot
```


■シャットダウン

```
$　sudo shutdown
```

～2018/10/24 追記～
■スペースを認識させる
ファイル名とかにスペースを利用し、スクリプトを打つ場合。
例えば「sample　no1」とファイルを作って、そのファイルを消す場合。

```
$　rm "sample　no1"
```

と「"」を使うことで、認識してくれます

■アップデート

```
$　sudo apt update
```

■アップグレード

```
$　sudo apt upgrade
```

■インストール済みのパッケージ表示

```
$ sudo dpkg -l
```

■タイムゾーン設定

```
$ sudo dpkg-reconfigure tzdata
```

タイムゾーンの設定をしたら、一旦アップデートはした方がいいみたいです。

```
$ sudo apt-get update
```




#最後に
自分のメモ代わりにもしています。
今後は覚えていくたびに増やしていこうと思います。
ASTERIA JOINについて

久しぶりの投稿です.
ASTERIA歴 1年を超えました. ﾊﾟﾁﾊﾟﾁ
そんな私がASTERIAのJOINについて,役に立った知識をメモります.


# RecordJoinコーポ―ネントはインデックスを使うと速くなる

![qiita_20180713.png](https://qiita-image-store.s3.amazonaws.com/0/180419/3fca857c-73c8-2ed4-b3e2-cf012274ef77.png)

join に5分ぐらいかかっていた処理が,
インデックスをつけることで一瞬で処理が終わったことがあります.


# 実は,FULL (OUTER) JOIN がある
RecordJoin コンポーネントにはINNERとOUTERしかないのですが、
RecordSQLコンポーネントを使えば実現できます.

![qiita_20180713_1.png](https://qiita-image-store.s3.amazonaws.com/0/180419/20246291-c8b5-5f4d-bccb-414ad1dfec15.png)

結果は

````
"1","山田 哲人",""
"2","大引 啓次","陽 岱鋼"
"3","西浦 直亨",""
"4","バレンティン",""
"5","川端 慎吾","A.ゲレーロ"
"8","武内 晋一",""
"9","塩見 泰隆","亀井 善行"
"6","","坂本 勇人"
"7","","長野 久義"
```

思った通りの結果です。

Velocityコンポーネントに直接データを載せています.
![qiita_20180713_2.png](https://qiita-image-store.s3.amazonaws.com/0/180419/6b33fe61-1fe4-dc20-2486-0a95ede47f50.png)

個人的には,Linuxのヒアドキュメントの使い方に相当するのでは？
と思っています。
①ファイルに入れるほどでもない,StreamPutコンポーネントに入れる程でもない時
②ソートしていないデータを作る時
上記のケースで私は使用しています.(本来はVelocityはこんな使い方ではないと思いますが)

本題のFULL OUTER JOINですが, 問題があります.
テーブルが3つ以上時はあまり期待できません.
必ずキーがNULLでないとき, 例えば阪神タイガースのように
1~9番まで背番号が埋まっているテーブルをin[1]になるときは利用できます.

# NULLがあっても3つ以上テーブル結合するには
①キーとなるデータをつくる
②①をin[1]として,他をleft outer join する.
![qiita_20180713_3.png](https://qiita-image-store.s3.amazonaws.com/0/180419/659b42d5-4751-940f-b5db-61c3bdf47f20.png)


一つにまとめるとこうなるのですかね.
ポイントは重複を許さない UNIONです.(UNION ALL だとダブったものも表示されます)

```結果
"1","山田 哲人","","鳥谷 敬"
"2","大引 啓次","陽 岱鋼","北條 史也"
"3","西浦 直亨","","大山 悠輔"
"4","バレンティン","","熊谷 敬宥"
"5","川端 慎吾","A.ゲレーロ","西岡 剛"
"6","","坂本 勇人","金本 知憲"
"7","","長野 久義","糸井 嘉男"
"8","武内 晋一","","福留 孝介"
"9","塩見 泰隆","亀井 善行","髙山 俊"


```


一応でできるのですが,無理矢理詰め込んでいるので見栄えが汚いですね.
union を意味するコンポーネントがあれば, サブテーブルを分けるのですが....


# 実はCROSS JOINもある

```
in[1]に
会社コード1
会社コード1
会社コード1

in[2]
1月
2月
3月
```

![qiita_20180713_4.png](https://qiita-image-store.s3.amazonaws.com/0/180419/69102890-51e2-a140-ad0f-4afa19a35ce0.png)

結果は

```結果
"会社コード1","1月"
"会社コード1","2月"
"会社コード1","3月"
"会社コード2","1月"
"会社コード2","2月"
"会社コード2","3月"
"会社コード3","1月"
"会社コード3","2月"
"会社コード3","3月"

```

うまくできていますね.
cross joinは
①ダミーデータを作るとき
②joinのKEYを作成するとき
上記のケースに私はよくつかっています.

また, in[2]にRecordTransposeコンポーネントを食わすと
横長のダミーデータが作れますね。

cross join と以下の記事を参考にするともっと複雑なものが作れるのかもしれませんね。
[ASTERIA WARPでデータを縦持ちから横持ちに変換するには](https://qiita.com/nacopon/items/5df2c1f96b1ec43d845f)

以上です.　

Asteriaユーザーが一番使うコンポーネントはMapperだと思うのですが,
私の場合は5割近くがRecordSQLを使っているような気がします.
VSCodeでhtmlを書いてるときにLiveプレビュー

#VSCodeでhtmlをLivePreviewしたい！！！

##LivePreviewとは？
Webpackなどで普段フロントの開発をしている人はお馴染みだと思うのですが、エディターでSaveした瞬間にブラウザのプレビューが更新される事です。勝手に呼んでます。
Webpack等の環境がない状態でもその機能を使いたい！という方向け（only VSCode）
##使い方
VSCodeの拡張機能、LiveServerを使用します。
1. 拡張機能の検索からLive Serverをインストール
2. VSCodeを再起動
3. プレビューしたいファイルを開き右下のGoLiveをクリック
4. 終わり！
#### 簡単！
（VSCodeではフォルダごと開かないと動作しないみたいです。）
saml2awsでSAML認証を用いたaws cliの利用を簡単にした

# はじめに
皆さんはAWS マネジメントコンソールへのログインどうされていますか？
弊社では最近[GSuite SAML認証](https://aws.amazon.com/jp/blogs/security/how-to-set-up-federated-single-sign-on-to-aws-using-google-apps/)を使ってコンソールへログインしています。

GSuiteにログインしているだけでAWSにもログインできて大変便利なんですが一つだけ大きなデメリットがあり、それが…　aws cliがとても使いづらい！という問題でした。
（AWS STSの一時的認証情報の期限が切れるたびにGSuiteとごにょごにょして一時的認証情報を取得し直す必要があるorz）

ですが、いろいろ探してみると[saml2aws](https://github.com/Versent/saml2aws)という便利ツールがあったので紹介です。golangで実装されています。

### saml2awsが対応しているIDプロバイダー
- One of the supported Identity Providers
  - ADFS (2.x or 3.x)
  - PingFederate + PingId
  - Okta
  - KeyCloak + (TOTP)
  - Google Apps
- AWS SAML Provider configured

# インストール方法
```sh:OSXインストール方法
brew tap versent/homebrew-taps
brew install saml2aws
```

```sh:Windowsインストール方法
choco install saml2aws
saml2aws --version
```

# 設定手順
まずはsaml認証の設定です。

|項目名|設定値|
|---|---|
|provider|GoogleApps|
|AWS Profile|awsコマンドで利用するprofile名|
|URL|https://accounts.google.com/o/saml2/initsso?idpid=XXXXXXX&spid=YYYYY&forceauthn=false <br>※ saml認証用のURL|
|Username|GSuiteユーザー名|
|Password|GSuiteパスワード|
|Confirm|パスワード確認|

今回は上記内容を対話式で設定します。

```sh
% saml2aws configure -a test_idp_account
? Please choose a provider: GoogleApps
? AWS Profile test_profile

? URL https://accounts.google.com/o/saml2/initsso?idpid=XXXXXXX&spid=YYYYY&forceauthn=false
? Username test_user@example.com

? Password ****
? Confirm ****

account {
  URL: https://accounts.google.com/o/saml2/initsso?idpid=XXXXXXX&spid=YYYYY&forceauthn=false
  Username: test_user@example.com
  Provider: GoogleApps
  MFA: Auto
  SkipVerify: false
  AmazonWebservicesURN: urn:amazon:webservices
  SessionDuration: 3600
  Profile: test_profile
}

Configuration saved for IDP account: test_idp_account
```

次に先程設定した認証情報でログインしてみます。

```sh

% saml2aws login -a test_idp_account
Using IDP Account test_idp_account to access GoogleApps https://accounts.google.com/o/saml2/initsso?idpid=XXXXXXX&spid=YYYYY
To use saved password just hit enter.
? Username test_user@example.com
? Password ****

Authenticating as test_user@example.com ...
? Security Token [000000] 000000
Selected role: arn:aws:iam::000000000000:role/GSuite
Requesting AWS credentials using SAML assertion
Logged in as: arn:aws:sts::000000000000:assumed-role/GSuite/test_user@example.com

Your new access key pair has been stored in the AWS configuration
Note that it will expire at 2018-07-13 19:03:14 +0900 JST
To use this credential, call the AWS CLI with the --profile option (e.g. aws --profile test_profile ec2 describe-instances).
```

これで無事プロファイルが作成されました！
（ちなみに2018/7/13現在、GSuiteでMFA（２段階認証）を設定してると日本環境ではエラーになってしまいます。。ですが、私の方でworkaroundではありますが日本環境で動くように修正して[プルリクエスト](https://github.com/Versent/saml2aws/pull/196)送ってます。~~続報をまて！~~ 2018/7/14にマージされました）

# aws cliで使ってみる

```sh

aws --profile test_profile ec2 describe-instances --region ap-northeast-1                                  
{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                {

                .
                .
                .
```

簡単にコマンド使えるようになりました。便利！
Vue.js 単一コンポーネント内のscriptメモ

単一コンポーネントで作ったVueファイル内にscriptも記載できる。
別JSファイルに個別に書きたい場合は(パスはそれぞれ必要に応じて調整)、

```TopPage.js
export default class TopPage {
	constructor() {
		console.log("topページ");
	}	
}
```

```page1.vue
<script>
import TopPage from "../pages/TopPage";
  export default {
    mounted: () => {
      new TopPage();
    }
  }
</script>
```

こんな感じでpage1のページを開いたタイミングでTopPage.jsが発火。
vangrantでcentos5（bento/centos-5.11）環境を作る

テスト用にcentos5.11環境を作ろうとしたら
ちょっとハマったのでメモ＆共有を。

# やったこと

・boxを追加してinit

```
vagrant box add bento/centos-5.11
vagrant init bento/centos-5.11
```

・Vagrantfileを編集したのち、起動

```
vagrant up
```

すると、以下のエラーが発生した。

```
Loaded plugins: fastestmirror
Determining fastest mirrors
YumRepo Error: All mirror URLs are not using ftp, http[s] or file.
 Eg. Invalid release/
removing mirrorlist with no valid mirrors: /var/cache/yum/base/mirrorlist.txt


Stderr from the command:

Error: Cannot find a valid baseurl for repo: base
```

# つまり

vagrant up で yum が走るが、centos5 の yum リポジトリがもう存在してないので、エラーとなって止まっている。
CentOS-Base.repo を編集して、yum の向き先を vault.centos.org へ変更しなくてはならない。
（[参考](https://qiita.com/shin1x1/items/a0e73f86d43776258fca#3-yum-%E3%81%AE%E5%90%91%E3%81%8D%E5%85%88%E3%82%92-vaultcentosorg-%E3%81%AB%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)）

なるほど。

…。

あれ？

**vagrant up できないのに、どうやって CentOS-Base.repo 書き換えるの…？**

# provisioningを使う

Provisioningを使うと、仮想マシンが立ち上がったあとの処理を記述できます。
（[参考](https://qiita.com/nobu_blast/items/aed1a9c780737b51b510#2provisioning)）

なので、修正済みの CentOS511-Base.repo を用意し、それを vagrant内の /etc/yum.repos.d/CentOS-Base.repo に上書きします。

```:Vagrantfile
   config.vm.provision "file", source: "CentOS511-Base.repo", destination: "/home/vagrant/CentOS-Base.repo"
   config.vm.provision "shell", inline: <<-SHELL
     sudo cp /home/vagrant/CentOS-Base.repo /etc/yum.repos.d/.
   SHELL
```

あとは

```
vagrant reload --provision
```

で。

# あとがき
「こうすればよかったんじゃないの？」とか
あれば是非教えて下さるとうれしいです。
何も考えないRails 5+Vue.js+Bootstrap 4+Font Awesome 5の開発環境構築手順

# 各バージョン
- OS : macOS High Sierra 10.13.5
- Ruby : 2.5.0
- Rails : 5.1.6
- Yarn : 1.6.0
- Vue.js : 2.5.16
- Bootstrap : 4.1.1
- Font Awesome : 5.0.9

# 構築手順
## 1. Rails + Vue プロジェクトの作成
```terminal
$ rails new your-project-name --webpack=vue
``` 

**備考**
rake taskで以下のエラーメッセージが出た場合、以下の手順で解決。
1. `yarn install`
2. `config/environments/development.rb`に`config.webpacker.check_yarn_integrity = false`追加

```terminal
Error:[rake --tasks] ========================================
Your Yarn packages are out of date!
Please run `yarn install` to update.
========================================
To disable this check, please add `config.webpacker.check_yarn_integrity = false`
to your Rails development config file (config/environments/development.rb).
env: node: No such file or directory
```

## 2. Bootstrap + Fontawesome の追加
### 2-1. Gemfile
```text:Gemfile
gem 'bootstrap', '~> 4.1.1'
gem 'jquery-rails'
gem 'font-awesome-sass', '~> 5.0.9'
```

### 2-2. CSS
```terminal
$ mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
```

```scss:app/assets/stylesheets/application.scss
// Bootstrap & Font Awesome
@import "bootstrap";
@import "font-awesome-sprockets";
@import "font-awesome";
```


### 2-3. JaveScript
```javascript:app/assets/javascripts/application.js
// Bootstrap
//= require rails-ujs
//= require jquery3
//= require popper
//= require bootstrap
//= require turbolinks
//= require_tree .
```

## 3. JSコード変更の自動反映設定
### 3-1. Gemfile
```text:Gemfile
gem 'foreman'
```

### 3-2. 設定ファイル作成
```text:Procfile.dev
web: bundle exec rails s
# watcher: ./bin/webpack-watcher
hot: ./bin/webpack-dev-server
```

```text:bin/server
#!/bin/bash -i
bundle install
bundle exec foreman start -f Procfile.dev
```

```terminal
$ chmod 777 bin/server
```
bookmarks（20180601-20180630）

# コーディング
■[CSS]たった一行でガラス板の美しいエフェクトが実装できる、backdrop-filterプロパティの使い方を解説
https://coliss.com/articles/build-websites/operation/css/css-property-backdrop-filter.html

■DevToolsでz-index一覧できるやつ作ったよ。
https://ginpen.com/2018/06/20/devtools-z-index/

■CSS の initial キーワード
https://developer.mozilla.org/ja/docs/Web/CSS/initial

■PWAで表示速度が2倍に！ スピード改善を妥協しない日経電子版に学ぶ、PWAのメリット＆デメリット
https://employment.en-japan.com/engineerhub/entry/2018/06/05/110000

■サイト埋め込みGoogleマップが7月16日からAPIキー必須で有料に、ただし対応不要の場合も多いので慌てずに
https://webtan.impress.co.jp/e/2018/06/26/29696

# ページ設計
■コンバージョン中心設計（CCD）のシンプルな７原則
http://uxmilk.jp/68618

■サンクスページをひと工夫して売上促進！4つの改善ポイント
https://ferret-plus.com/10325?utm_campaign=https%3A%2F%2Fferret-plus.com%2F10325&utm_medium=RSS&utm_source=top_rss

# EUの一般データ保護規則改正関連
■GDPR（General Data Protection Regulation：一般データ保護規則）とは
https://www.ppc.go.jp/enforcement/cooperation/cooperation/GDPR/

■WebサイトのGDPR対応用パッケージを作ったので、GDPR準拠のランディングページを作ってみた
https://dev.classmethod.jp/tool/wordpress/model-case-cookie-handling-on-gdpr/
[Django]複数のslug（キー）でSingleObjectMixinを継承したDetailViewやUpdateViewを使う方法

そのままのクラスだと無理なので、`get_object()`をオーバーライドして、オブジェクトを返せばいい。

```python
def get_object(self, queryset=None):
  if queryset is None:
    queryset = self.get_queryset()
  
  try:
    obj = queryset.filter(hoge=self.kwargs['hoge'],piyo=self.kwargs['piyo']).get()
  except queryset.model.DoesNotExist:
    raise Http404(_("No %(verbose_name)s found matching the query") %
                  {'verbose_name': queryset.model._meta.verbose_name})
  return obj
```
[アルゴリズム] ドットの円を良い感じに作成する

マインクラフトとかで使えそう
![NoName_2018-7-13_17-21_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/270131/76d30d27-5db5-ad94-6fa8-57c823037a3f.png)

普通の円を描くのは簡単だが、**ドットの**円を描くのが思ったよりめんどくさかった
今回考えてみたアルゴリズムを書いていく

# 手順

1.生成する円を内接円と考える。そのための四角形を与える(横幅、縦幅)
2.円に用いる頂点の数を決める
3.四角形の内接円を指定の頂点数を使い生成する(画像の赤い円)
4.それぞれの点で、矩形にどれだけめり込んでいるかを調べる
5.めり込みの量が一定以上だった場合、その矩形を塗りつぶす
6.塗り潰しの箇所から中心に向かって内部を塗りつぶす(画像の青い円)

# ソース

```c#
//四角形の大きさ
int width = 30;
int height = 30;

//グリッド描画めり込み最低値
const int SINK_PERMISSION_NUM = 18;
//頂点数
int vertex = width * 8;
//中心点
var center = new { X = width * 0.5f, Y = height * 0.5f };
//先にDegree -> Radian用の数値を作っておく
float toAngle = (float)Math.PI / vertex;

for (int i = 0; i < vertex; ++i)
{
    //円を生成していく
    double angle = toAngle * i;
    float px = (float)Math.Cos(angle) * center.X;
    float py = (float)Math.Sin(angle) * center.Y;

    //円頂点のドットへのめり込み量を調べる
    int sink = (int)((py % 1.0f) * 100);
    if (sink < SINK_PERMISSION_NUM) continue;

    //ここでBoxを描画していく
    for (int j = 0;j < py;++j)
    {
        int dotX = (int)(center.X + px);
        //上側のポジションY 偶数時の補正をするならここに-1
        int dotUpY = (int)(center.Y - j);
        //下側のポジションY
        int dotDownY = (int)(center.Y + j);

        //~~~~~~~描画~~~~~~~
        //DrawDot(dotX,dotUpY,dotDownY);
        //~~~~~~~~~~~~~~~~~~
    }
}
```

# 問題点
ある程度の大きさの円でないと、ちょくちょく間に抜けができる
塗り潰し判定のめり込み量で対応できなくはない・・・？
Railsで頻発する NoMethodError for nil をかっこよく避けよう！

##みなさんよくレコードいじってると、`nil`に悩まされるとおもいます。
こんな感じ

```rb
puts Order.first.client.address.street
# => NoMethodError: undefined method `client' for nil:NilClass
```

## そうすると真っ先に思いつく解決策はこれ
うーん汚いですねwww 
No way!

```rb
order = Order.first
if order && order.client && order.client.address
  puts order.client.address.street
end
# => nil
```
##そこで次に思いつくのはRailsのactivesupportを使った方法

```rb
order = Order.first
puts order.try(:client).try(:address).try(:street)
# => nil
```

まぁあまぁあイケてますね〜

##ただruby2.3以降ならもっといけてる方法が!

```rb
order = Order.first
puts order&.client&.address&.street
# => nil
```

これです、swift,c#にもある`safe navigation operator`という機能を使えばいいのです！

##この記事はmediumのある記事をサクッと翻訳、要約したものです。本家には`#dig`の紹介もあるのでぜひご覧ください！

##参照
[mediumのページ](http://dlet.me/avoiding-nomethoderror-for-nil-in-ruby-9ce0f3fd0e30)
DockerにAmazon Linuxを入れて、Nginxが動くようにする

#はじめに
特に意味はないのですが、AWS Lambdaを作るための環境の一つとして、Dockerを選んでみました。
ということで、Dockerfileを作ってみようと思ったのですが、関係はないのですが、Nginxを入れて、
動いてるのを確かめたい欲求に駆られたのでやってみました。

#環境を作る
##動作環境
- MacBook Pro(13-inch, 2016, Four Thunderbolt 3 Ports)
- macOS High Sierra 10.13.5

##Dockerをインストール
### Windowsはこちら
https://goo.gl/mfwppw
### Macはこちら
https://goo.gl/t16nca

##Dockerfile
こんな感じで書いてみました。

```
FROM amazonlinux:2017.12.0.20180330
# install packages
RUN yum -y update && yum clean all && \
    yum -y install \
    wget \
    git \
    awscli \
    openssh \
    openssh-server \
    tar \
    gcc \
    make \
    zlib-devel \
    openssl-devel \
    which \
    zip \
    unzip \
    glibc-langpack-ja

# set timezone
RUN ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

# install python 3.6.6
ENV HOME /root
ENV PYENV_ROOT $HOME/.pyenv
ENV PATH $PYENV_ROOT/bin:$PATH
RUN git clone https://github.com/yyuu/pyenv.git $HOME/.pyenv
RUN echo 'eval "$(pyenv init -)"' >> ~/.bashrc && \
    eval "$(pyenv init -)"
RUN pyenv install 3.6.6 && \
    pyenv global 3.6.6

# install nginx
RUN yum install -y http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
RUN yum install -y --enablerepo=nginx nginx
RUN yum swap -y fakesystemd systemd && yum clean all
#RUN service nginx restart
RUN systemctl enable nginx
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]
EXPOSE 80
# set LANG
ENV LANG ja_JP.UTF-8
```

#実行する
ビルドしてから、実行する感じになります。
コマンドはこちら

```
$ docker build -t testimage
$ docker run -d -it -p 8080:80 testimage
```
※ `testimage` は適当な文字を入れてもらってOKです。
※ 今回の例は、Docker側は80ポート、動作させてるOS側は8080ポートを使っています。8080はぶつからないポートにすればOKです。

#確認する
ブラウザを立ち上げて、以下のURLを入れてください。
`http://localhost:8080`

以下の図のようになればOK！
<img width="554" alt="Nginx.png" src="https://qiita-image-store.s3.amazonaws.com/0/105220/0263b5a4-030c-56fe-a81f-7f4d5d1f0d5c.png">

#さいごに
結構簡単に作れたので、この前段にロードバランサーを置いて分散させたり、いろんなもので制御したりしてみても面白いかもですね。
思いついたら、ちょっとやってみようかと思います。
[ エラー ]  PHP laravel vagrant upの際のエラー

#①　vagrant up した際のエラー
```

The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

/sbin/ifdown 'eth1' || true
/sbin/ip addr flush dev 'eth1'
# Remove any previous network modifications from the interfaces file
sed -e '/^#VAGRANT-BEGIN/,$ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces.pre
sed -ne '/^#VAGRANT-END/,$ p' /etc/network/interfaces | tac | sed -e '/^#VAGRANT-END/,$ d' | tac > /tmp/vagrant-network-interfaces.post
cat \
 /tmp/vagrant-network-interfaces.pre \
 /tmp/vagrant-network-entry \
 /tmp/vagrant-network-interfaces.post \
 > /etc/network/interfaces
rm -f /tmp/vagrant-network-interfaces.pre
rm -f /tmp/vagrant-network-entry
rm -f /tmp/vagrant-network-interfaces.post

/sbin/ifup 'eth1'

Stdout from the command:



Stderr from the command:

bash: line 5: /sbin/ifdown: No such file or directory
bash: line 19: /sbin/ifup: No such file or directory
```

#②　vagrant up した際のエラー

```
The box failed to unpackage properly. Please verify that the box 
file you're trying to add is not corrupted and that enough disk space 
is available and then try again. 
The output from attempting to unpackage (if any):
```

私の場合は、
vagrantとvirtualboxのバージョンを最新にすると、エラーがなくなりました :eyes:
14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 不明なエラー"

14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 不明なエラー"

上記のエラーは、DNSによる名前解決ができていない。
DNSが「mirrorlist.centos.org」と中身のipアドレスを紐付けできていないということだそうです。
したがって、DNSサーバの設定を変更すると解決します。
DNS設定をgoogleのパブリックDNSを使用する。
「8.8.8.8」

設定手順
DNS設定
nmcli c modify eth0 ipv4.dns 8.8.8.8

ネットワーク再起動
systemctl restart network

設定確認
nmcli d show eth0

参考URL
http://nanyatti.wp.xdomain.jp/2017/08/31/centos7yum%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E5%95%8F%E9%A1%8C%E3%80%82/
Python script を pip でインストール可能にする

# Python script を pip でインストール可能にする

## 概要

自作した Python モジュールをコマンドラインから直接実行できるコマンドとしてインストールする手順をここに共有します。

## 実現するための手段として

`setup.py` にそのための記述を加えることで、モジュールのインストール後にコマンドとして使用できるようになります。


## サンプル
[サンプルプログラム](https://github.com/smn-ailab/tshimura_qiita/tree/master/command) を用意しました。
実際に動作するスクリプトとしてご参考ください。

## 事前の準備や条件など

- この記事では Python 3.6 を使用しています。
- コマンドラインから実行できる Python モジュール自体は既に出来上がっているものとします。


## Python モジュールをコマンドとしてインストール

### setup.pyについて

`setup.py` の 関数 setup の中に `entry_points` を加えることで、そのモジュールをコマンドとしてインストールできます。

```Python
entry_points={
    'console_scripts': ['コマンド名=モジュール名:実行する関数名']}
```

(サンプルプログラム抜粋)

```Python
setup(
    (省略)
    # lt コマンドはここで設定.
    entry_points={
        'console_scripts': ['lt=command.local_time:exec']})
```

この例では `command モジュール`内の `local_time.py` にある関数 `exec` とコマンド `lt` を紐付けています。

### インストール

通常のモジュールと同様、 `pip install` によりインストールします。
サンプルプログラムをインストールする場合は、サンプルプログラムがあるディレクトリ上で

```bash
pip install .
```

を実行してください。

### 実行

console_scripts で指定したコマンドがコマンドラインから直接実行できるようになります。

サンプルの実行例

```bash
$ lt
Tokyo           2018-06-26 13:23:17 +09:00
London          2018-06-26 05:23:17 +01:00
New_York        2018-06-26 00:23:17 -04:00
```

## アンインストール

アンインストールも通常のモジュールと同様に行うことができます。

```bash
$ pip uninstall モジュール名
```

## 結果として

自作 Python モジュールをコマンドとしてコマンドラインから直接実行できるようになりました。


##　参考

[python-packaging](https://python-packaging.readthedocs.io/en/latest/index.html)
[setup スクリプトを書く](https://docs.python.jp/3/distutils/setupscript.html)
Android StudioにJunit4を追加したメモ

#はじめに
最近のAndroid Studioでプロジェクトを作成すると、テスト用のフォルダなどは初めから作られていますが、昔のプロジェクトだとそうもいきません。この記事はAndroid Studio 3.1.2で古いプロジェクトにjunit4を追加したのでその時のメモです。基本的にはGoogleの[Document](https://developer.android.com/training/testing/unit-testing/local-unit-tests)を参考にしました。
#フォルダ構成

namespaceがcom.example.hogeだとすると、始めは次のようなフォルダ構成。resなど今回の内容とは直接関係ないフォルダは書いてない。

app/
　└ src/
　　　└ main/
　　　　　└ java/
　　　　　　　　└ com/
　　　　　　　　　　└ example/
　　　　　　　　　　　　　　└ hoge/
　　　　　　　　　　　　　　　　┝ MainActivity.java

テスト用のフォルダは次のように追加。テスト用のファイルとして`ExampleTest.java`を準備。

app/
　└ src/
　　　├ main/
　　　│　　└ java/
　　　│　　　　　└ com/
　　　│　　　　　　　└ example/
　　　│　　　　　　　　　　　└ hoge/
　　　│　　　　　　　　　　　　　┝ MainActivity.java
　　　│
　　　┝ test/
　　　  　　└ java/
　　　　　　　　└ com/
　　　　　　　　　　└ example/
　　　 　　　　　　　　　　　└ hoge/
　　　 　　　　　　　　　　　　　┝ ExampleTest.java

これでAndroid StudioのProject上にcom.example.hoge (test)が表示される。
#Gradle追加

Gradleに次の一行を追加。

```gradle
dependencies {
    testImplementation 'junit:junit:4.12'
}
```
#テストプログラム実行

上記の`ExampleTest.java`に次のようなプログラムを書く。

```java
package com.example.hoge;

import org.junit.Test;
import static org.junit.Assert.assertTrue;

public class ExampleTest {

    @Test
    public void example1() {
        assertEquals("test", true, true);
//        assertEquals("test2", true, false);
    }
```

これでコンパイルが通ったら、Android Studioで`com.example.hoge(test)`を右クリックすればテストが実行出来る。
#TODO
UIテストとかもやってみる
MongoDB4.0をインストール(Windows10)

Windows10でMongoDBをテストするためにインストールしました。覚書。

#ダウンロード
https://www.mongodb.com/download-center?jmp=nav#community

![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/ad5f3854-883c-bfb0-8a8f-91634c8a1916.png)

こちらから、MongoDB Community Serverのインストーラをダウンロードし、実行。

#インストール
参考
https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/
##インストーラ起動
###「Next」で次へ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/f65d85c5-2f89-1471-969d-6dee00d42c53.png)
###チェックを入れて「Next」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/d470f71e-5b57-321b-88f3-bc607714b3b9.png)

###「Complete」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/a9566fc9-e7ed-d290-bcc8-e933c16380a1.png)

###設定し「Next」
ネットワークサービスユーザとしてインストールしてみます。
ドライブはDに変更しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/704c4697-4ce0-bc55-b2b3-b64dcad76ab1.png)

###「Next」
Compassもインストールします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/1d150aa4-2bb6-ece6-34d2-bbec200d09cf.png)

###「Install」で実行
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/4010a9ac-3241-6629-9f1c-436138f5a703.png)

###実行中
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/28d5240e-5488-ecac-8b39-dfd47c035cfe.png)

###完了
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/59bdabed-ae23-f0ce-8340-00ede58bc6bd.png)

##MongoDB Compass Communityが起動
###ライセンスに同意（Agreeをクリック）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/49a3f384-ac38-2888-cfe4-7b06fadc9faf.png)

###チュートリアルが表示されます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/d180d3f9-692c-769c-1723-036ee4d26aa0.png)
どんどん進めて次へ

###プライバシー設定
適宜チェックを外して（もしくはそのままで）「Start Using Compass」をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/9161736e-9a1d-f8f8-d71a-1f93a7851fac.png)

##画面右下にある「Connect」ボタンをクリック
ひとまずデフォルトのままで接続してみました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/8024a510-eebb-8884-2246-bcb92cb6a508.png)
（中略）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234600/b7f94234-c089-171d-49f3-7561a317a822.png)

つづく（多分）





###
最近更新されたテーブルを知りたい場合のSQL文

## 目的

「テーブルが多すぎて、どれが更新されたか分からないよ、ドラえもーん！」と叫びたくなった時に使える。

## SQL文

```sql
SELECT
  `TABLE_NAME` as 'TABLE'
, `Update_time` as 'TIMESTAMP'
 from
  `information_schema`.`TABLES`
 WHERE
  TABLE_SCHEMA = '{DB名}'
 ORDER BY
  `Update_time` DESC;
```
※ {DB名}を適宜書き換えてね。

## 結果例

| TABLE | TIMESTAMP |
|:------|:----------|
| user  | 2018-07-13 17:23:01 |
| work  | 2018-07-13 17:22:59 |
| list  | 2018-07-02 10:00:00 |
PythonでAES暗号化/復号

# 概要
pythonでのAES暗号化。
前述のphpとnodejsのAES暗号化記事でのソースと相互変換も可能です。
[PHPとNode.jsの暗号/復号相互変換](https://qiita.com/tomi_shinwatec/items/e39e767f77eaca4e82f5)

なおソースは下記ページの内容を大幅に参考にしています。ありがとうございます。
[Pythonで暗号化と復号化](https://qiita.com/teitei_tk/items/0b8bae99a8700452b718)

上記との違いですが、こちらではsaltを毎回生成するため暗号化されたテキストは生成のたび変わるようになっています。

# パッケージインストール

```
$ pip install pycrypto
```

# ソース

```crypt.py
import base64
import random
from Crypto.Cipher import AES
from hashlib import sha256

class AESCipher(object):
    def __init__(self, key, block_size=32):
        self.bs = block_size
        if len(key) >= len(str(block_size)):
            self.key = key[:block_size]
        else:
            self.key = self._pad(key)

    def generate_salt(self,digit_num):
        DIGITS_AND_ALPHABETS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
        return "".join(random.sample(DIGITS_AND_ALPHABETS, digit_num)).encode()

    def encrypt(self, raw):
        raw = self._pad(raw)
        salt = self.generate_salt(AES.block_size)
        salted = ''.encode()
        dx = ''.encode()
        while len(salted) < 48:
            hash = dx + self.key.encode() + salt
            dx = sha256(hash).digest()
            salted = salted + dx

        key = salted[0:32]
        iv = salted[32:48]

        cipher = AES.new(key, AES.MODE_CBC, iv)
        return base64.b64encode(salt + cipher.encrypt(raw))

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        salt = enc[0:16]
        ct = enc[16:]
        rounds = 3

        data00 = self.key.encode() + salt
        hash = {}
        hash[0] = sha256(data00).digest()
        result = hash[0]
        for i in range(1, rounds):
            hash[i] = sha256(hash[i - 1] + data00).digest()
            result += hash[i]

        key = result[0:32]
        iv = result[32:48]
        cipher = AES.new(key, AES.MODE_CBC, iv)
        return cipher.decrypt(enc[16:]).decode()

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

    def _unpad(self, s):
        return s[:-ord(s[len(s)-1:])]
```


```make.py
from crypt import AESCipher

# 32文字のパスフレーズ(ランダムキー)
pass_phrase = 'WCWYmSP9eR9nhRidXBDCjMMfUsVfb4Ec'

cipher = AESCipher(pass_phrase)

# 暗号化
encryptText = cipher.encrypt('plain text')
print(encryptText)

#復号
plainText = cipher.decrypt(encryptText)
print(plainText)
```
【EntityFrameWork】外部参照を持ったレコードの追加でエラー

数時間嵌ってしまった。
取り急ぎメモ

##DB構造
Table1のNameはいくつかの決まった値をとる様制限したいので、
Table1.NameIDは外部参照でNameListのIdを見る様にしました。
![diaglam.png](https://qiita-image-store.s3.amazonaws.com/0/241416/44aacec3-7f68-e0d8-adfd-04622ee912e2.png)


##やりたいこと
Table1のレコードを追加したい。
NameIDをセットしてAddじゃなく、NameListのインスタンスをセットした状態のインスタンスでレコードを追加したい。

```C#

//---------------こうではなく--------------------//
using(var context = new DBEntities())
{
    var table1Instacse = new Table1();
    //NameIDを設定し <- ダサい
    table1Instacse.NameID =  context.NameList.Where(a => a.ItemName == "設定したい名前").First()?.Id;
    //レコード追加
    context.Table1.Add(table1Instance);
    //問題なくSave成功
    context.SaveChanges();
    
}
//---------------こうしたい--------------------//
using(var context = new DBEntities())
{
    var table1Instacse = new Table1();
    //NameListのインスタンスをセットして
    table1Instacse.NameList =  context.NameList.Where(a => a.ItemName == "設定したい名前").First();
    //レコード追加
    context.Table1.Add(table1Instance);
    context.SaveChanges();//<-エラー発生

}

```

##エラーの原因

Exceptionはこれが発生。

```
System.Data.Entity.Infrastructure.DbUpdateException: 
'エントリを更新中にエラーが発生しました。詳細については、内部例外を参照してください。'
```

innerを見てみると

```
System.Data.SqlClient.SqlErrorCollection: 
Violation of PRIMARY KEY constraint 'PK__NameList'. 
Cannot insert duplicate key in object 'dbo.NameList'. The duplicate key value is (1).
The statement has been terminated.
```

なんでNameListに追加しようとしてるの？？


##解決策
今回の場合はこここがドンピシャ
https://stackoverflow.com/questions/7082744/cannot-insert-duplicate-key-in-object-dbo-user-r-nthe-statement-has-been-term


```C#
using(var context = new DBEntities())
{
    var table1Instacse = new Table1();
    table1Instacse.NameList =  context.NameList.Where(a => a.ItemName == "設定したい名前").FirstOrDefault();
    context.NameList.Attach(table1Instance.NameList);//定義済みであることを伝える
    context.Table1.Add(table1Instance);
    context.SaveChanges();//これでエラー発生しない！
}
```
lazysizesを使った場合のJavaScript無効時の処理

## lazysizesとは

lazysizesとは、画像やiframe要素の遅延読み込み(レイジーローディング)を簡単に実装できるようにしてくれるライブラリです。
通常、webページにアクセスするとページ上の全ての画像を一度に読み込もうとするので画像が多いと読み込みに時間がかかってしまいます。
なので、ファーストビューで表示される画像だけ読み込んで、それ以外の画像はスクロールしてきた時に読み込むようにしてページの表示速度を上げるといった技術が出てきました。
lazysizesは、それを簡単に実現させてくれるものです。

### lazysizesを使った遅延読み込みの実装方法

CDNが用意されているので、今回はCDN経由での実装方法を紹介します。

ライブラリの読み込み

```html
<script type="text/javascript" async="" src="https://cdnjs.cloudflare.com/ajax/libs/lazysizes/4.0.1/lazysizes.min.js?ver=1.0"></script>
```
あとは、src属性で指定しているURLをdata-srcという属性に指定してlazyloadというクラスを追加するだけです。

```html
<img data-src="image.jpg" class="lazyload" />
```
基本的には、これだけで遅延読み込みできるようになります。

## JavaScript無効時に画像などが表示されないので、noscript要素を使って表示できるようにする

非常に便利なレイジーローディングですが、lazysizesを使って遅延読み込みをした場合、そのままではJavaScript無効時に表示されないという現象が起こってしまいます。
lazysizesはJavaScriptライブラリで、JavaScriptが動作しないと処理ができないからです。

なので、noscript要素を使ってJavaScript無効時は通常読み込みで表示できるようにしようと思います。
noscript要素の中のコードは、JavaScriptが無効の場合のみ処理されるのでそれを利用します。

```html
<noscript><style>.lazyload{display: none !important;}</style></noscript>

<img class="lazyload" data-src="image.jpg">
<!-- 遅延読み込みするimg要素の直後に下記noscript要素を記述するようにしてください -->
<noscript><img src="image.jpg"></noscript>
```
上記コードで、JavaScriptが無効の場合でも画像が表示されるようになります。
やっていることは、JavaScript無効時はimg要素を通常読み込みで読み込むようにして、遅延読み込み用のimg要素は`display:none`で非表示にしているだけです。(非表示にしないと要素分の領域が確保されてnoscriptタグ内で読み込まれているimg要素の位置がズレてしまう)

## 最後に

まぁ、JavaScriptが無効な環境なんて今時ほぼないのかもしれませんが、表示されないというのは気持ちが悪かったので対応することができて良かったです。