OmniAICreator/Qiita-1.07M huggingface dataset:
Rails 6 (Webpacker標準搭載) で星による評価機能を実装する

# はじめに
2019年8月にリリースされたRuby on Rails 6.0よりJavaScriptの扱いが変わったため、変更点(つまずいたポイント)を踏まえて"jQuery Raty - A Star Rating Plugin"を導入したいと思います。

# 環境
- 言語(Ruby 2.6.5)
- フレームワーク(Rails 6.0.3.3)

# 参考
- https://qiita.com/yuki_0920/items/a966d9fa2bdb621f805d
- https://github.com/wbotelhos/raty
- http://itref.fc2web.com/javascript/jquery/raty.html#SYNTAX

# 実装

## jQueryの導入

まず、YarnによるjQueryのインストールを行います。

```
yarn add jquery
```
Webpackerで管理する際は、Node.jsのパッケージを利用します。
* "jquery-rails"というGemは使用しません。
yarn addコマンドは、パッケージのインストールと共に、package.jsonへバージョンを書き込んでくれます。

次に、webpackerの設定ファイルで、jQueryを管理下に追加するための記述をします。

```config/webpack/environment.js
const { environment } = require('@rails/webpacker')
#追記
const webpack = require('webpack')

environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery',
    jquery: 'jquery/src/jquery',
  })
)
#ここまで
module.exports = environment
```

最後に、jQueryを呼び出します。

```app/javascript/packs/application.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require('jquery') #追記
```

## jQuery Ratyの導入

下記サイトより、画像とコードをローカルに保存します。
https://github.com/wbotelhos/raty
-- app/assets/images ディレクトリ --
画像： https://github.com/wbotelhos/raty/tree/master/lib/images
-- app/javascript 配下に新しく任意の名称でjsファイルを作成(今回は"raty.js") --
コード： https://github.com/wbotelhos/raty/blob/master/lib/jquery.raty.js

## jQuery Ratyの呼び込み
先ほどと同様に、新しく作ったjsファイルを追記します。

```app/javascript/packs/application.js
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require('jquery')
require('raty') #追記
```

ここまでで、機能の設定は完了です。

## Viewファイルへの記述

以降は、実装したい任意のViewファイルに下記のように書き込みます。

```
    <div class="note note-rating", id="star">
      <h3>総合評価</h3>
    </div>
    <script>
      $('#star').raty({
        size      : 36,
        starOff   : '<%= asset_path('star-off.png') %>',
        starOn    : '<%= asset_path('star-on.png') %>',
        starHalf  : '<%= asset_path('star-half.png') %>',
        scoreName : 'note[rating]',
        half      : true,
      });
    </script>

```

オプションや表示に関する記述は、下記２つの記事が詳しいです。
- https://qiita.com/yuki_0920/items/a966d9fa2bdb621f805d
- http://itref.fc2web.com/javascript/jquery/raty.html#SYNTAX

# まとめ

RailsにおいてjQueryを導入するのがほぼ初めてだったため、実装したい機能を見つけても導入できませんでした。Rails6以降では、標準としてWebpacker(JavaScriptをまとめて管理するためのツール)がインストールされているため、思うように実装するためには実装の仕方やRailsが構成されるファイル一つ一つを学ばなければいけないと感じました。
【Rails】デフォルトで設定されてるdeviseのパスワードバリデーションを解除・変更

#はじめに
deviseでユーザーの登録内容を編集する方法

deviseでのパスワードの取り扱いは、セキュリティーの観点から編集(update)ができない仕様になっていて、しようとしても編集できず強制ログアウトされてしまう。
また、viewを編集して、入力できない様にしていてもバリデーションが発動してしまう。
なので、編集(update)のさいはそのバリデーションをoffにしなければならない。



###目次
1.devise導入と各種ファイル作成・設定
2.バリデーションの解除
3.バリデーションのカスタマイズ
4.veiwページの編集


#開発環境
ruby    2.6.5
rails   6.0.0
devise  4.7.3




#実装

####1.devise導入と各種ファイル作成・設定

deviseのインストール
rails g devise:view モデル名
ルーティングの設定

これで下準備が整いました。


####2.バリデーションの解除
先ず、デバイスをインストールするとデフォルトで設定されているバリデーションを解除します。

モデルにてバリデーションの解除

```model/user.rb
 devise :database_authenticatable, :registerable,
       :recoverable, :rememberable  :validatable  #←これを削除#
```

:validatableがデバイスのバリデーションを司ってるのでこれを削除。
手動で変更できる様になりました。
この状態で編集(update)する事ができますが、今のままだと全てがoffになってるので、新規登録(create)する時のバリデーションもoffになったままです。

####3.バリデーションのカスタマイズ

新規登録(create)するときはバリデーションを発動させたいので、onオプションを使ってバリデーションのタイミングを指定。

```model/user.rb
 validates :password, on: :create #←createつまり保存の時のみonにします。#
 validates :nickname, presence: true
 validates :name, presence: true
```

これで編集時（update）はoff、新規登録時(create)はonにする事が出きました。

####4.veiwの編集

ちなみに、パスワードの変更機能自体は、「現在のパスワード」→「新しいパスワード」、、、、としていけば可能ですが、パスワードやメールアドレスは厳重なセキュリティーが必要です。
名前や住所などのページで一緒に取り扱わず、専用ページを作成する事をおすすめします。


#まとめ
deviseってユーザー管理機能を実装するときに非常に便利で、ユーザーの登録を始め様々な機能が標準装備されています。
ただ、自分の思った仕様にカスタマイズするには、さまざまな操作が必要です。


###最後に
私はプログラミング初学者ですが、自分と同じ様にエンジニアを目指す方々の助けになればと思い、記事を投稿しております。
それではまた次回お会いしましょう〜

---
参考文献
https://qiita.com/Nosuke0808/items/415a82c2cdd66fc7545c
CodeIgniter4でSmartyを使う(Composer利用)

#CodeIgniter4でもSmartyを使いたい
[前の記事](https://qiita.com/kohenji01/items/44dc6c72077c0a9ec366)でも少し述べましたが、CodeIgniter4（以下CI4）のViewにはテンプレートエンジンと呼べるようなシロモノは含まれていません。
殆どの場合は生のPHPでHTMLのページなどを組み上げることになるのですが、実際の制作の現場だとロジック（PHP）とデザイン（HTML）のコーディングを分業している制作会社も多数存在しており、ここをSmartyやTwigなどのテンプレートエンジンで埋めているパターンが多いのではないでしょうか？
そこで、本記事ではCI4でSmartyを導入してViewのレンダラとして導入する方法を説明します。

#Smarty for CodeIgniter4を導入する
CI4上でSmartyを利用するには拙作、[Smarty for CodeIgniter4](https://github.com/kohenji01/CI4Smarty)を使うと手っ取り早いです。
CI4への組み込みは最低限の内容にとどめているので動作は軽いと思います。

例は「[CodeIgniter4をインストール (Composer利用)](https://qiita.com/kohenji01/items/a36dbbbb19bb8808d104)」での導入を終えた流れでインストールをした場合です。

```bash:composerによるSmarty&nbsp;for&nbsp;CodeIgniter4の導入
$ cd /home/ci4test
$ composer require sarah-systems/ci4smarty
```

以下は、概ね`README.md`からの抜粋です。

# 使い方

デフォルトでは、Smarty関連のパスは自体は次のような設定で動作するようになっています。

| 種類         | パス                        |
|:-------------|:----------------------------|
| テンプレート | app/Views                   |
| コンパイル   | writable/smarty/templates_c |
| キャッシュ   | writable/smarty/cache       |
| コンフィグ   | writable/smarty/config      |

`writable`が正しく書き込み可能な場合、下の3つのディレクトリは自動的に生成されます。
もしエラーが起きた場合は、これらのディレクトリを作って適切なパーミッションを与えることで動作します。

もしこのパスを変更したい場合は`.env`ファイルに次のパラメータをセットすることで、任意のパスに変更可能です。

```bash:.env
CI4Smarty.TemplateDir = /path/to/TemplateDir
CI4Smarty.CompileDir = /path/to/CompileDir
CI4Smarty.CacheDir = /path/to/CacheDir
CI4Smarty.ConfigDir = /path/to/ConfigDir
```

これ以外にも`.env`では、SmartyのDebugフラグのOn/Offとデフォルトのテンプレート拡張子を設定できます。

```bash:.env
CI4Smarty.Debug = 1 または 0
CI4Smarty.DefaultTemplateExtension = .tpl
```

# Smartyでview()を利用したい。
CI4のview関数をSmarty用にCI4Smartyというnamespaceで定義しています。

利用する際は`app`ディレクトリ直下の`Common.php`に次を追記してください。

```php:app/Common.php
require_once ROOTPATH . "vendor/sarah-systems/ci4smarty/src/Common.php";
```

使用法はCI4のview関数と同じですが、関数の利用時には名前空間を指定するか、事前にエイリアスを張ってください。

```php
\CI4Smarty\view('template.tpl');
```

または

```php
use function CI4Smarty\view as view;
view('template.tpl');
```


拡張子`.tpl`（`CI4Smarty.DefaultTemplateExtension`で設定されたものです。無指定の場合は`.tpl`）は省略可能です。

```php
view('template');
```

view関数の第2パラメータはSmarty変数`$CI`にアサインされます。

```php
$data = [ 'apple' , 'banana' , 'lemon' ];
view('template',$data);
```

Smartyのtemplate上では
```smarty
{$CI.0} <-- appleが表示されます。
```

第3引数の$optionsは無視されます。

# Serviceでの利用も可能です

CI4のServiceが利用可能です。

```php
use CI4Smarty\Config\Services;

$time = date('Y-m-d H:i:s');
$smarty = Services::smarty();
$smarty->assign('time',$time);
$smarty->display('template.tpl');
```

次回はCI4上でTwigを使う方法を解説します。
QRコードをエンコードする（作成する）Csharpの単体アプリ、文字コードによる出し分け




※ライブラリは以下参照
QR Code Encoder and Decoder .NET Class Library
https://www.codeproject.com/Articles/1250071/QR-Code-Encoder-and-Decoder-NET-Class-Library-Writ

QRCodeEncoderDecoderLibrary.dll
[QRCodeEncoderDecoderLibrary.dll](http://thomas.cranky.jp/qr/QRCodeEncoderDecoderLibrary.dll)


QRコードを、SJISとUTF8で出しわける

以下、
　> qr_encode_sjis_and_utf8.exe abcあいdef
で実行したケース

SJIS
![QR_SJIS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/7910c10a-7674-17a1-5301-8155280a3aaa.png)


UTF8
![QR_UTF8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107418/cafa0d16-bb51-117d-08b1-f3ae77cfc935.png)



```c#:qr_encode_sjis_and_utf8.cs
//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /reference:QRCodeEncoderDecoderLibrary.dll /target:winexe qr_encode_sjis_and_utf8.cs

using System;
using System.Windows.Forms;
using System.Drawing;
using QRCodeEncoderDecoderLibrary;

public class qr_encode_sjis_and_utf8
{
 public static void Main(string[] args)
 {

    string str;
    str = @"" + args[0];

    QREncoder QRCodeEncoder;
    Bitmap    QRCodeImage;

    QRCodeEncoder = new QREncoder();

    byte [] bytesDataU = System.Text.Encoding.UTF8.GetBytes(str);
    byte [] bytesDataJ = System.Text.Encoding.GetEncoding(932).GetBytes(str);

    QRCodeEncoder.Encode(ErrorCorrection.H, bytesDataU);
    QRCodeImage = QRCodeToBitmap.CreateBitmap(QRCodeEncoder, 4, 8);
    QRCodeImage.Save(@".\\QR_UTF8.png",System.Drawing.Imaging.ImageFormat.Png);

    QRCodeEncoder.Encode(ErrorCorrection.H, bytesDataJ);
    QRCodeImage = QRCodeToBitmap.CreateBitmap(QRCodeEncoder, 4, 8);
    QRCodeImage.Save(@".\\QR_SJIS.png",System.Drawing.Imaging.ImageFormat.Png);

 }
}
```

- - -
#参考（別投稿）

１ファイルのHTML(+JavaScript)で、QRcodeを生成する
https://qiita.com/santarou6/items/db17788158dba38f3a5c
fluent-bitで取得したログに、ログの取得時間を付与する

ドキュメントを読んでこうすればできるじゃんって気づくまで少し時間がかかったので、自分と同じようなことをしたい人の時間を救いたい。

```
[STREAM_TASK]
    Name nginx
    Exec CREATE STREAM something AS SELECT *, NOW() FROM TAG:'*-firelens-*' WHERE container_name = 'aaaaaaaa';
```

こうすると、一応fluent-bitが取得するログに現在時間が含まれるのだが、`"NOW()":"2020-10-06 10:47:23"`のようにkeyがNOW()になってしまう。

これだとなんか変だし、S3にあるログファイルをAthenaで検索するためにカラムを追加しようにも`NOW()`というカラムは作れないので、実用的にも問題がある。

ということで、keyの名前を変える方法を調べた。

```
[FILTER]
    Name modify
    Match *
    Rename NOW() time
```

これでできた。

```
[STREAM_TASK]
    Name nginx
    Exec CREATE STREAM something AS SELECT *, NOW() AS time FROM TAG:'*-firelens-*' WHERE container_name = 'aaaaaaaa';
```

のように、`NOW() AS time`とかでできるかと思ったのですが、できませんでしたので、このようにやるに至りました。

```
"time":"2020-10-07 06:32:58"
```

これでAthenaで検索もできます。

以上。
Amazon FSx for Windowsのあれやこれやソイヤソイヤ

#これはAmazon FSx for Windowsをサクッと知りたい人向けの記事
もう既にドキュメントを読んで理解してるよ。作ったことあるよって人は回れ右。
なんか興味あるねんってくらいの人向け。
###■そも、Amazon FSx for Windowsってなんぞ
AWSがマネージドするWindowsファイルサーバー。正確にはファイルシステム、なのかな。
**回線帯域もディスクもAWSが運用してくれる**ので、保守運用とか考える必要が無いのがメリット。
機器の保守切れやらOSのアップデートやら障害対応なんやら考えなくていいので、社内SEの仕事を一つ奪うことが出来るよ。
使い方もお手持ちのWindowsファイルサーバーと変わらない。**smb使ってお好きにアクセスできる。**

あと、セキュリティ面もAWSが保証してくれるので下手にセキュリティアプライアンスとか導入するよりも良い。
転送中のデータは自動的に暗号化されるし。

###■うまい話過ぎて信用できんな？
まぁ、そらそうで。
FSxを利用するにあたっては何点か留意しておく点がある。

**1. ActiveDirectoryが必須**
**2. コスト計算が若干面倒**
**3. 費用を諸々考えると結構する**

###■1. ActiveDirectoryが必須。
結構見落としている人が多いんだけど、FSxにはActiveDirectoryが必須。
使えるADは**Amazon Directory ServiceのMicrosoftAD**か、**自作(オンプレミスでもクラウドでも)のMicrosoft ActiveDirectory。**
もちろん、FSxを作成するVPCが定義するCIDR配下のADである必要がある。オンプレならDirectConnectかVPNで繋ぐ必要あり。

「なんだ思ったより安いな」

そう思って見積もりを作ってたら、実はADの費用が入ってなかった。なんてことにならないようにね。

###■2. コスト計算が若干面倒
公式ページにカリキュレーターがあるのですが、利用するストレージ量とスループットキャパシティ(平均帯域)に加え、**重複排除の削減という謎の項目**を追加しないといけない。
（公式にもなんか、「これくらいで計算してくれ」としか書いてないのでここら辺は雰囲気で数字入れるしかない…）

バックアップはオプションで、**増分取得**なのでいつものスナップショットを取得する際の感覚で計算してOK。
（7世代増分取得の場合は、全体容量の3世代分くらいで見積もることが多いです。それでも多い時の方がしばしばだけど）

転送量については、**実際にコンソールで作成する時に目安のスループット量が出てくる**ので、
こちらで提示するのが無難だと思うんですが、だったら公式のカリキュレーターにも載せて欲しいと思う今日この頃。
いちいちAWSコンパネにログインして作成画面見ないとならぬ…。

###■3. 費用を諸々考えると結構する。
以下条件で見積もったとする。

【条件】
ActiveDirectory　：Amazon Microsoft AD
ストレージ容量　：3TB
スループット　　：32MB/s
重複排除　　　　：50％
バックアップ　　：9TB

【見積り】
Amazon Microsoft AD費用　 : 288.00 USD
ストレージ容量費用　　　　: 234.00 USD
スループット費用　　　　　: 80.96 USD
バックアップ費用　　　　　: 225.00 USD

合計料金 (monthly): 827.96 USD

####高え

いやまぁ、バックアップ費用抜いたらとか、ADが元からあるところはそれ使えばいいって節約できるんだけど、
ADも無くてバックアップも欲しいとかいうお客様はこの見積もり出さないといけない。

プラスα、ADの管理費用とか(インフラ保守じゃなくて権限周りの設定)を含めるとさらに費用を乗せることになるので、
中小企業で使うにはなかなか厳しいかも。

###■とはいえ、よ。
**同条件のSSDのWindowsサーバー＋AD**を提案しようとしたら**前述の金額以上は絶対必要になる**し、
バックアップや**冗長構成(Multi-AZ)**も組めるので、予算があるなら絶対こっちでファイルサーバーを作った方がメリットは大きい。

何より、セキュリティの担保をAWSがしてくれるのでADの権限周りさえしっかりしておけば管理部が扱うようなデータだって、このFSxで扱っちゃって問題無い。
費用比較の資料を作るなら、そこも含めて提案すると通しやすくなるかも。

FSxをただのファイルサーバーと侮るなかれ。
**FSxはセキュアかつ、可用性・機密性の高いマネージドファイルサーバーなのだ。**
Rails(postgeresql. Ubuntu環境)、heroku デプロイ

1 railsのgemをインストール

```
#rails6の場合
gem install rails -v 6.0.1
#rails5.2の場合
gem install rails -v 5.2.1
```

2 Postgresqlインストール
 
```
$ sudo sh -c "echo 'deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main' > /etc/apt/sources.list.d/pgdg.list"
$ wget --quiet -O - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | sudo apt-key add -
$ sudo apt-get update
$ sudo apt-get install postgresql-common
$ sudo apt-get install postgresql-9.5 libpq-dev
```

3 PostgreSQL Account を作る

```
$ sudo -u postgres psql
postgres=# create role <username> with createdb login password '<password>';
postgres=# \q
```

4 Rails new

```
rails new appname -d postgresql
cd appname
```


5 config/database.ymlの編集

```
default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  # 以下、3行追加
  username: <username> # 設定したPostgreSQL Accountと同一のもの
  password: <password> # 設定したPostgreSQL Accountと同一のもの
  host: localhost
development:
  <<: *default
  database: appname_development # appnameのところは、rails new時のappnameになっているはずです。
test:
  <<: *default
  database: appname_test # appnameのところは、rails new時のappnameになっているはずです。
```

6 rails db:createでデータベースを作成&webpackerインストール

```
$ cd appname
$ rails db:create

#rails5の場合は不要
$ source <(curl -sL https://cdn.learnenough.com/yarn_install)
$ yarn install --check-files
$ rails webpacker:install

#config/enviroments/development.rb
config.hosts.clear
```

7 Heroku CLI Download and install

```
$ sudo curl https://cli-assets.heroku.com/install-ubuntu.sh | sh

$ heroku --version
```

8 Heroku ログイン

```
$ heroku login
Email: you@example.com
Password: xxxxxxxx
```

9 Heroku デプロイ準備& デプロイ

```
$ cd rails app
$ git init
$ git add -A
$ git commit -m "first"

#デプロイ
$ heroku create
$ git push heroku master
$ heroku run rake db:migrate
```

--応用編--SSH設定をしてherokuアプリ作成
1 まずはHerokuにログインします。

```
$ heroku login --interactive
# メールアドレスとパスワードを求められるので、入力しエンターをクリック
Enter your Heroku credentials:
Email: test@test.com
Password: *********
```
2 次に鍵をHerokuに追加します。

```
$ heroku keys:add
 ```

3 Herokuにアップロードしますか？と聞かれるのでyを入力する

```
? Would you like to upload it to Heroku? (Y/n)

#すると以下のようなコードが出てきたら成功です。
Uploading /home/ec2-user/.ssh/id_rsa.pub SSH key... done
```

4 デプロイ 

```
$ heroku create newsable-skillhub

# Herokuにアプリが作成される。
Creating ⬢ newsable-skillhub... done
https://newsable-skillhub.herokuapp.com/ | https://git.heroku.com/newsable-skillhub.git

$ git init
$ git add -A
$ git commit -m "first"
$ git push heroku master

$ heroku run rake db:migrate
#seedも更新する場合は
$ heroku run rake db:seed
```
パスワードを暗号化して保存する

ユーザのパスワードを平文でデータベースに保存しても良いものか？
んー、マズいと思う。

# bcryptをインストールする

[bcryptのインストール](https://www.npmjs.com/package/bcrypt)

```sh
$ npm install bcrypt --save
```

# apiを作る

- 暗号化してmysqlに保存する。（ユーザ登録）
- mysqlから取り出して復号する。（ユーザ認証）

## ユーザ登録

```javascript:api/user.js
const express = require('express')
const app = express()

app.post('/create', (req, res) => {
  const username = req.body.username
  const password = req.body.password

  const bcrypt = require('bcrypt')
  bcrypt.hash(password, 10)
  .then(hash => {
    const mysql = require('mysql')
    const connection = mysql.createConnection({
      host: 'localhost',
      database: 'mysql',
      user: 'root',
      password: ''
    })
    const sql = 'insert into user set ?'
    const values = { username: username, password: hash }
    connection.connect()
    connection.query(sql, values, (error, results, fields) => {
      if (error) throw error
      res.json({ results })
    })
    connection.end()
  })
})
module.exports = {
  path: '/api/user',
  handler: app
}
```

##  ユーザ認証

```javascript:api/auth.js
const express = require('express')
const app = express()

app.post('/login', (req, res) => {
  const username = req.body.username
  const password = req.body.password

  const mysql = require('mysql')
  const connection = mysql.createConnection({
    host: 'localhost',
    database: 'mysql',
    user: 'root',
    password: ''
  })
  const sql = 'select password from user where username = ?'
  const values = [username]
  connection.connect()
  connection.query(sql, values, (error, results, fields) => {
    if (error) throw error
    const hash = results[0].password

    const bcrypt = require('bcrypt')
    bcrypt.compare(password, hash)
    .then(result => {
      if (result) {
        res.json({ username })
      } else {
        res.status(401).json({ error: '認証失敗' })
      }
    })
  })
  connection.end()
})
module.exports = {
  path: '/api/auth',
  handler: app
}
```
自己用メモ：1曲リピート音楽プレーヤーを作る。

#1.目的
英語のリスニング用の音源をiPhoneにブラウザ経由でダウンロードしたけど、
自分の手元にある、音楽再生アプリ（LineMusicとMusicアプリ）では認識してくれない。
しかも未だにめんどくさがって、PCにはItunesすらないからMusicライブラリには入れれない。
端末にアプリ追加できるほど容量に余裕がない。
＝＞ブラウザで動くものにすればいいんじゃね。
#2.条件
iPhoneのダウンロードなどに入ってる音声ファイルを使って、一曲をループしたい。
できればあんまりデータを食わないほうがいい。
#3.設計
超シンプル

```html

<html>
    <body>
<input type="file" id="music">
<div id="player">
    <audio id="main" controls loop src="" ></audio>
    </div>
    <script>
        
        document.getElementById( "music" ).addEventListener( "change", function() {
        var blobUrl = window.URL.createObjectURL( this.files[0] ) ;
        document.getElementById( "main" ).setAttribute("src",blobUrl)
	}
) ;
    </script>
    </body>
</html>
```

仕組み
audioタグを使って実装
コントロール表示+loopで実装するだけ。

本当ならInputタグはファイル制限すべきだけど、今回はめんどくさくてしません。
Scriptの中身は、Inputの変更を検知し、オブジェクトURL生成して、プレーヤーのSRCに放り込むだけ。
かんたんでしょ。
ちなみに、なぜか動画でもいけます。（映像はないですけど）
バックグラウンド再生もできます。
なお、音声データはサーバーにアップロードされてないので、オフラインで使えそう。（PWA化すればいいのでは？）
#4.注意事項
何故かIphoneのHtmlViewerくんでは読み込めませんでした。
＝＞GASにページとして追加したら動いた。
バックグラウンド再生ははじめの頃はSafariでしかできなかった。
＝＞今はChromeでも動く
まれに、バックグラウンド再生を停止すると、再開できないこともある。
アプリを再開すると治る。

#改善点
ループや再生速度の設定ボタンぐらいはほしい
ホントは連続再生したい。

**おしまい**
Video

# Video

- videoタグで埋め込み動画を表示する方法

## HowTo

### HTML
```html
<video src="./images/video.mp4" autoplay loop playsinline muted></video>
```

### Option

- autoplay: 自動再生
- loop: ループ
- playinline: この属性がないと全画面表示になります、iPnoneなどでそのまま表示させたいときは必須です
- meted: ミュート

## Case

### SP/PCで異なる画像を使用する場合

- Responsive
- sp-video.mp4, pc-video.mp4 という画像を準備

### HTML
- data-video-id は任意の値を入れてください

```html
<video data-video-id="string" data-src="./images/sp-video.mp4" autoplay loop playsinline muted></video>
```

### JS
```js
window.addEventListener('DOMContentLoaded', function () {
  var video = document.querySelector('[data-video-id]');
  var mobileFlag = true;
  if (video) switchVideo();
  function switchVideo(initFlag) {
    var w = window.innerWidth;
    var BREAKPOINT = 813; // BREAKPOINT値, 任意の値
    var src = video.getAttribute('data-src');
    if (w < BREAKPOINT) {
      if (!mobileFlag || initFlag) video.setAttribute('src', src);
      mobileFlag = true;
    } else {
      var result = src.replace('sp-', 'pc-' );
      if (mobileFlag) video.setAttribute('src', result);
      mobileFlag = false;
    }
  }
  window.addEventListener('load', function () {
    switchVideo(true);
  });
  var timer = null;
  window.addEventListener('resize', function () {
    clearTimeout(timer);
    timer = setTimeout(function () {
      switchVideo();
    }, 300);
  });
})
```
今更なのですが、BMI計算をpythonで、やってみたかったのです。


今更なのですが、BMI計算をpythonでやってみたかったのです。
個人の趣味で。全く個人的なメモ程度で。

2つのpythonファイルで

```python:health_check.py
# coding: UTF-8
# 環境がMac OS なので、日本語対応には　UTF-8 
#BMI code　
# 名前はhealth_check.py

def bmi(weight, height):
    bmi_data = []
    w = weight
    h = height
    bmi = w/(h*h)
    bmi = round(bmi, 1)
    bmi_data.append(bmi)
    if bmi<18.5:
        ans = "やせ型です"
    elif bmi>=18.5 and bmi<25:
        ans = "標準です"
    else:
        ans = "肥満です"
    bmi_data.append(ans)
    return bmi_data
```
二つ目がhealth_check_main.py で。


```python:health_check_main.py
# coding: UTF-8
# BMI health_check main
# health_check_main.py
import health_check
weight  = float(input('あなたの体重を入力してください(kg): '))
height0 = float(input('あなたの身長を入力してください(cm): '))
height = height0/100
bj = health_check.bmi(weight, height)
print("----" * 10)
print("あなたのBMI: " + str(bj[0]) + '\nあなたの体型: ' + bj[1])
```
実行は、Mac OS ターミナルのbashコマンドにて、次のような感じかと。

```bash:health_check_main.sh
$ python health_check_main.py
あなたの体重を入力してください(kg): 55
あなたの身長を入力してください(cm): 160
----------------------------------------
あなたのBMI: 21.5
あなたの体型: 標準です

```

以上です。
Amazon Rekognition Videoの活用法について考える

#はじめに
Amazon Rekognition Videoとは、AWSの提供する機械学習を利用したビデオ分析サービスです。
Rekognition Videoを利用することで、動画中の数千のオブジェクトや顔、コンテンツを正確に検知し、追跡し、認識し、抽出し、節度を検出することができます。

※こちらの記事にて、デモの利用手順をご確認いただけます。
https://qiita.com/JJ33/items/848aaac7bc68a15c56af

#3つの主な機能
チーム:動画に登場する人物を識別、追跡
有名人:登場人物が有名人か判定
オブジェクトとアクティビティ:動画内にある人、モノ、シチュエーションまでを解析

#検出できるメタ情報
- 物体（車両やペットなど）
- シーン（都市やビーチ、結婚式など）
- アクティビティ（小包の配達やダンスなど）
- 有名人（有名人の名前と一意のID）
- テキスト（英語テキストのみ）
- 動作（ろうそくを吹く、火を消すなど）
- 不適切なコンテンツ（ヌード、暴力、武器など）

各検索結果や検出にはタイムスタンプが付いているため、詳細なビデオ検索向けのインデックスをすぐに作成できるほか、さらなる分析のために興味のある箇所にすばやく移動することもできます。
また、対象がフレーム内のどの位置で検出されたのかを境界ボックスの座標で教えてくれます。

#デモを試した結果
https://www.youtube.com/watch?v=L91yri_Vmbs
こちらの動画を借りてデモを使ってみました。
結果を一部掲載します。
（今回CelebritiesやModeration Labelsは検出されなかったためLabelsとPersonsのみ）

##ケース１　ジェット機の前で写真を撮るシーン
![2020-10-09_13h14_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/26933271-3471-bbdc-0199-8920fa43bf61.png)
■Labels（Confidence 80以上のみ表示）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/1a3cc84e-2275-5722-9589-3016576b56b1.png)
ジーンズやヘリコプターも認識できているようです！

■Persons
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/66c8df36-c61f-be27-7dfa-8481c032fcb0.png)
４人の人物を検知しています。

##ケース２　女の子がドーナツを持っているシーン
![2020-10-09_13h16_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/4ce3f818-6bd5-0a86-a835-de6e600b4662.png)
■Labels![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/d5aabe27-3978-1f46-2f35-28263914ef4c.png)
こちらのシーンではホットドッグを検出しています。
正確にはドーナツなのですが、食べ物の種類まで認識しているのはすごいですよね！

■Persons![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/7d18bc88-033f-ac00-5737-4a45540199f8.png)
先程のシーンと同じ女の子だとわかっているようです！

##ケース３　ソファーで写真を撮るシーン
![2020-10-09_15h34_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/008da067-5c8c-0357-59cb-bff21c1f0335.png)
■Labels![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/d5fad854-a49a-3841-515e-1676e85f88c2.png)	
室内で、シェルフなどの家具があることを認識しています。

■Persons![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/10206828-cdba-5044-36ac-d2f633f814a8.png)
シーン１と同じ人物が２人いるとわかっているようです。

##ケース４　家に荷物を運ぶシーン
![2020-10-09_14h48_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/aede683e-61f9-24cf-5142-9fe264b71c30.png)

■Labels![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655635/8a4b33a6-5ef9-d103-06f5-711e4b4b9b48.png)
宅配をしているシーンであることも認識しています！これはすごい！


#何に活用できそうか考えてみた
- 不適切なシーンのカット、または警告表示
- 検索機能を充実させる（タグ付けや顔検索）
- 顔認証受付（施設の混雑防止や万引き防止につながる）
- 人物トラッキングで犯人を捕まえる、行方不明者を捜す
- 動画を投稿前に節度を検出し、不適切なシーンの公開を防ぐ
- 検出できたメタデータを自動で組み合わせてハイライト動画の作成
- 撮った動画を、カテゴリーや人物別で勝手にフォルダに分けるアプリ
- SNS等で動画メディアを投稿する際、顔検索によって友達を自動でタグ付け
- 小売業の分析（買い物客の行動、平均年齢層、性別分布、人々が表す感情を分析）
- コンテンツ流動型広告（見ているコンテンツに見合う広告を選ぶ、良いタイミングで挟むなど）


#さいごに
デモを試した結果、十分な精度で色々なメタ情報が得られました。（他の動画では自撮りをしているシーンやラーメンを作っているシーンも認識しました！）
アイデア次第で、顔認証受付やハイライト動画の作成など、様々な用途で活躍できそうだと思いました。今後の展開も楽しみですね。

#参考リンク
https://aws.amazon.com/jp/rekognition/video-features/
#使用した動画リンク
https://www.youtube.com/watch?v=L91yri_Vmbs
【Rails】CarrierWaveによる画像投稿 【AWS EC2】

#筆者の環境
Ruby 2.5.3
Rails 5.2.4.2
gem: fog-aws

Railsで画像投稿にCarrierWaveを導入したのですが、gem:fog-awsを利用していて多くエラーに遭遇したので、恐らくこれから導入される方は苦労すると思い、設定を残しておこうと思いました。

同じ環境であれば、carrierwave.rbについては下記の設定ファイルでOKなはずです。
#carrierwave.rbの設定
```ruby:config/initializers/carrierwave.rb
require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'

CarrierWave.configure do |config|
  if Rails.env.development? || Rails.env.test?
    config.storage = :file
    config.enable_processing = false if Rails.env.test?
  elsif Rails.env.production?
    config.fog_provider = 'fog/aws'
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: ENV["AWS_ACCESS_KEY_ID"],
      aws_secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"],
      region: 'ap-northeast-1'
    }
    config.storage = :fog
    config.fog_directory = 'あなたのS3のバケット名'
    config.asset_host = 'https://s3.ap-northeast-1.amazonaws.com/あなたのS3バケット名'
  end
end

CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/

```
##ポイント
・本番環境のみAWS S3で画像を保持するようになっています。開発環境はローカルに保存されます。
・carrierwave.rbの保管ディレクトリは注意してください。app/config/initializers/carrierwave.rbです。

```ruby:carrierwave.rb
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
```
最下部のこのコードですが、デフォルトだとcarrierwaveはファイル名に日本語が使えない為、使えるようにする一文です。文字化けを防ぐことができます。

```ruby:carrierwave.rb
aws_access_key_id: ENV["AWS_ACCESS_KEY_ID"],
aws_secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"]
```

については、.envファイルで環境変数を指定してください。

#AWS S3の設定

S3の設定も色々と苦労したので、スクリーンショットで残しておきたいと思います。

![スクリーンショット 2020-10-07 15.02.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620533/0d17fe63-932c-7ba3-07df-fafaa8011e34.png)
S3の自分のバケットのプロパティです。ログ記録のみ有効にしてあります。ちなみにこの下の詳細設定も全て無効です。

![スクリーンショット 2020-10-07 15.05.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620533/2d7bef8e-81aa-a3a0-cf7f-6106166a43c0.png)
ブロックパブリックアクセスです。下部２つのみオンにしてあります。

![スクリーンショット 2020-10-07 15.06.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620533/524e4988-f1a1-a091-4e28-972ce3724fe0.png)
バケットポリシーエディターです。各自バケット名など変更してください。

コピーできるように下にコードを載せておきます。

```ruby:バケットポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt000001",
            "Effect": "Allow",
            "Principal": {
                "AWS": "あなたのユーザーのARN(IAMから確認)"
            },
            "Action": "s3*",
            "Resource": "arn:aws:s3:::あなたのS3バケット名"
        }
    ]
}
```


その他の項目は設定していません。


#CarrierWaveの所感
CarrierWaveは画像リサイズなど便利ですが、AWS EC2へデプロイし、S3を使用するとなると少し大変でした。
ActiveStorageも勉強したいと思います。
少しでも誰かの助けの記事になれば幸いです！
openssl

毎回手が止まるので自分用のメモです。

SSLv2,SSLv3,TLS1.0,TLS1.1,TLS1.2 に対応しているか確認する方法

```
# openssl s_client -connect <対象のIPアドレス・サイト名など>:443 -ssl2
# openssl s_client -connect <対象のIPアドレス・サイト名など>:443 -ssl3
# openssl s_client -connect <対象のIPアドレス・サイト名など>:443 -tls1
# openssl s_client -connect <対象のIPアドレス・サイト名など>:443 -tls1_1
# openssl s_client -connect <対象のIPアドレス・サイト名など>:443 -tls1_2
```

自己署名証明書を作る方法（鍵長2048bit、RSA暗号）

```
# openssl genrsa -out key.pem 2048 
# openssl req -new -key key.pem -out csr
# openssl x509 -req -in csr -signkey key.pem -sha256 -days 3650 -out cert.pem
```

別サーバから証明書の有効期限を確認する方法

```
# openssl s_client -connect サイト名:443 | openssl x509 -noout -enddate
```

STARTTLSを使用している場合の証明書確認方法

```
# openssl s_client -connect ホスト名:25 -starttls smtp
```

```
openssl s_client -starttls

starttls：暗号化なしで接続してから暗号化する(SSL使う)
starttlsなし：最初から暗号化ありでつなぐ

[つないでから暗号化]
openssl s_client -starttls pop3 -connect サーバ名:110

[つなぐ時から暗号化]
openssl s_client -connect サーバ名:995
```

FTP用SSLの確認方法

```
openssl s_client -connect ホスト名:21 -starttls ftp
```

p12形式の証明書の確認方法

```
openssl pkcs12 -in cert_veri.p12 -passin pass:パスワード
```

SSL証明書更新時によく使う

```
openssl x509 -text -noout -in 証明書ファイル名
openssl s_server -cert cert.pem -key key.pem
openssl s_client -connect ホスト名:443
openssl s_client -connect ホスト名:443 -servername サイト名（サイトに設定されたSNI対応証明書の確認）
```
[Vim]基本操作負担軽減のための最低限Leader設定

## はじめに

- 普段利用しているエディタとは別に、日または月に数回程度vimを利用することがあります。
- そのため、以下のような状態でも問題ありませんでした。
    - 利用は**基本操作**(移動・保存・終了)のみ。
    - そのため、数行あるいは空白の`.vimrc`。
    - 複雑な操作は手入力かコピペ。
- 今回は、そのような基本操作の更なる指負担軽減を図るため、Vimの**Leader**機能の設定を記載します。

## 結果
- 結果の`.vimrc`の記述を示します。
- 以下のような設定で、基本操作(移動・保存・終了)が「**Space + 各種キー**」でも利用できるようになります。

```vim
" leaderをスペースへ設定
let mapleader = "\<Space>"

" 「Spaceキー + 各種キー」のようなキー操作マッピング
inoremap <Leader>jj <Esc>                         " ESCキー 
nnoremap <Leader>w :w<CR>                         " 保存
nnoremap <Leader>q :q<CR>                         " 終了
noremap <Leader>a myggVG$                         " 全選択(ノーマル)
inoremap <Leader>a <Esc>myggVG$                   " 全選択(インサート)
nnoremap <silent> <Leader>vr :new ~/.vimrc<CR>    " .vimrcを開く
nnoremap <silent> <Leader>r :source ~/.vimrc<CR>  " .vimrcの読み込み
noremap <Leader><Leader> <C-w>w                   " windowの移動
map <leader>n :call RenameFile()<cr>              " 編集中ファイルのリネーム

" リネーム関数定義
function! RenameCurrentFile()
  let old = expand('%')
  let new = input('新規ファイル名: ', old , 'file')
  if new != '' && new != old
    exec ':saveas ' . new
    exec ':silent !rm ' . old
    redraw!
  endif
endfunction
```

## 内容

### Leaderとは
- [Leader](https://vim-jp.org/vimdoc-ja/map.html#%3CLeader%3E)とは、複数キー操作の割り当てが可能な特別な文字列および設定のことです。
- つまり、Vim上で独自のキーマッピング(ショートカット)を作成できます。

## 設定
- 設定の際には、以下を意識しました。
    - spaceキーを起点に。
        - 「,」等、様々なキーを試して自分に最適なものを選択。
    - 高頻度のみの設定
        - 利用の上で頻度の高い操作を洗い出す。
    - 必要以上には設定しない
        - 数を増やしすぎると、キーの衝突が起きるため避ける。
        - 短い標準操作は基本設定しない。

- 上記の結果で設定した主な内容は以下。(**※基本操作に焦点を当てて設定**)
    - spaceキー + jj : ESCキー
    - spaceキー + w : 保存
    - spaceキー + q : 終了
    - spaceキー + a : 全選択
    - spaceキー + n : 編集中ファイルのリネーム
        - ※[別途関数定義](https://qiita.com/t_o_d/items/1475671853e984aef777)

## 参考
- [Leader](https://vim-jp.org/vimdoc-ja/map.html#%3CLeader%3E)
- https://postd.cc/how-to-boost-your-vim-productivity/
備忘録(名簿の中の同姓の人にだけ名前を追記する）

一言日記：神エクセルと戦う日々が続く今日このごろ。
#主題

|	No.	|	名前	|	年齢	|
|	:-:	|	:-:	|	:-:	|
|	1	|	田中　太郎	|	33	|
|	2	|	鈴木　次郎	|	22	|
|	3	|	田中　三郎	|	11	|

上表をデータとして扱う時は特に何も困ることはないのだが、
アウトプットする時にはちょこちょこ「下表のようにしてくれ」、という要望がある。

|	No.	|	名前	|	年齢	|
|	:-:	|	:-:	|	:-:	|
|	1	|	田中（太）	|	33	|
|	2	|	鈴木	|	22	|
|	3	|	田中（三）	|	11	|

意外とこの処理そのものをしているページが見当たらなかったので、実装結果を載せておく。

#実装
```python:PRG
dataframe_raw = pd.read_excel("名簿.xlsx")
df=dataframe_raw["名前"].str.split('　',expand=True)
#このケースでは全角スペースで氏名が分割されていたので、splitで2列にする
```
splitで割るとdataframe_processは下表のようになるので、ここから名字の重複を調べ、
重複があれば特殊処理、なければ名字をそのまま使う。

|	0	|	1	|
|	:-:	|	:-:	|
|	田中	|	太郎	|
|	鈴木	|	次郎	|
|	田中	|	三郎	|

```python:
df["名前"]=""
 #3列目に格納用の列を足す

for i in range(0,len(df)):
 #iを0~名簿の長さまでループさせる
  NAME = df.at[i,0]
  check_count=(df[0]==NAME).sum()
 #i行目0列に格納された文字列が、0列目に何個あるかを数える（2以上なら同じ名字の人間がいることになる）
  if check_count>=2:
    df.at[i,"名前"]=df.at[i,0]+"("+df.at[i,1][0]+")"
 #重複がある場合、「i行目の名前列」には、0列目の文字列＋(「1列目の文字列の0文字目」)を代入する
  else :
    df.at[i,"名前"]=df.at[i,0]
 #重複が無い場合、「i行目の名前列」には、i行目0列目の文字列＋(i行目1列目の文字列の0文字目)を代入する
```
この処理で、データフレームは下表のようになるので、後は名前列を代入するなり結合するなりして使えばOK


|	0	|	1	|	名前	|
|	:-:	|	:-:	|	:-:	|
|	田中	|	太郎	|	田中（太）	|
|	鈴木	|	次郎	|	鈴木	|
|	田中	|	三郎	|	田中（三）	|

#終わりに
比較的キレイに纏まった気がするが、同姓同名の名簿が出てきたらどうしようかと戦々恐々である。
CentOS7のクラスタ環境で系切り替えが発生

DRBD,Corosync,Pacemakerを使ってクラスタを組んでいる場合、
systemdパッケージのアップデートとcorosyncのヘルスチェックのタイミングがぶつかると、
対象サービス（MySQLとか）の状態が見えなくなって系切り替えが発生してしまうことがある。

2つの処理がぶつからなければ普通にアップデートして終わるので、
必ず発生する訳ではなさそう。

とは言え危険なので、yum updateを定期的に実行している場合は外しておいた方が良さそう。
/usr/bin/yum update -y --exclude=systemd\*
など。
Javascriptの変数にvarをつけた場合とつけない場合の違い

# 結論
varをつけた場合
→そのスコープ内でのみ生存するローカル変数を作成する。
　すでに外側に同一名の変数が存在しても干渉されない。

varをつけない場合
→スコープ外へ同一名の変数が存在するまで辿っていき、存在した場合はその変数を利用する。
　存在しなければグローバル変数を作成する。

# 検証
paizaで検証しました。

検証環境
https://paiza.io/projects/9LF5qxEJ0QdKsB-Z_8mhrg?language=javascript

## ソースコード
```javascript
x = 'global';
y = 'global';
z = 'global';

function outfunc(){
    var x = 'out'; // outfunc内のみ生存
    var y = 'out'; // outfunc内のみ生存
    z = 'out';     // globalのzを使用
    
    function infunc(){
        var x = 'in'; // infunc内のみ生存
        y = 'in';     // outfuncのyを使用(=outfunc内のみ生存)
        z = 'in';     // outfuncのz(=globalのz)を使用
        console.log('in           ', x, y, z); // in, in, in
    }
    
    console.log('out_before   ', x, y, z); // out, out, out
    infunc();
    console.log('out_after    ', x, y, z); // out, in, in
}

console.log('global_before', x, y, z); // global, global, global
outfunc();
console.log('global_after ', x, y, z); // global, global, in
```

## 出力結果

```
global_before global global global
out_before    out out out
in            in in in
out_after     out in in
global_after  global global in
```
IEでmarginのautoが効かない時の対応方法

# 事象 : IEでmarginのautoで設定した右寄せが効かない

ChromeとEdgeとFirefoxは右寄せになるのにEdgeだけ左寄せになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/62f9e278-d43d-ed6f-2786-d7cf8a1f7ae3.png)

```html
<!DOCTYPE html>
<html>
<head>
  <title>marginのautoが効かない</title>
  <style type="text/css">
      .oya_div {
        display: flex;
        flex-direction: column;
        border-style: solid;
        padding: 2%;
      }
      .rigit {
        margin: 0 0 0 auto;
      }
  </style>
</head>
<body>
  <form style="width: 30%">
    <div class="oya_div">
      <div class="rigit">
        <input type="button" value="ボタン">
      </div>
    </div>
  </form>
</body>
</html>
```

## 原因 : IEでは親の`flex-direction: column;`に邪魔されて`margin: 0 0 0 auto;`が効いていない
`oya_div`では`display: flex;`と`flex-direction: column;`を指定している。
開発ツールで`flex-direction: column;`を外すと`margin: 0 0 0 auto;`が効いて右寄せになる・・・。

### 対応 : 寄せの設定を`text-align`でする。
IEで`margin`の`auto`が効かない事象はよくあって理由もいろいろだが、`text-align`を試したらいけた。
`margin: 0 0 0 auto;`と合わせて使ってもいいが`text-align: right;`だけで右寄せになるので、`margin: 0 0 0 auto;`は削除した。

```html
<!--さっきと同じなので省略-->
      .rigit {
        text-align: right;
      }
  </style>
<!--さっきと同じなので省略-->
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159761/c2153872-ce52-b9db-9d12-5eb55d806f7b.png)

## ほかの原因
- mainタグの問題
    - [IEでmargin:autoが効かない（センターに寄らない） - Qiita](https://qiita.com/SYABU555/items/4f882d8533d29e3e51f4)
- `display:flex;`と`position: fixed;`の問題
    - [IEで「margin: 0 auto;」の左右中央揃えが効かない？ - 商売力開発ブログ](https://www.prj-alpha.biz/entry/2018/04/06/212800)
- その他
    - [センタリングの不具合（IE/margin）：スタイルシート（CSS）一覧 - HTMLタグボード](https://www.dspt.net/stylesheet_css/001/ie_error2.html)
【Android】EditTextに指定文字のみ入力＋文字数制限を行う

## 1. 指定文字のみ入力するフィルターをクラスで作成
例として、カタカナのみ入力できるようにする

```Kotlin
    class KatakanaInputFilter : InputFilter {
       override fun filter(source: CharSequence, start: Int, end: Int, dest: Spanned, dstart: Int, dend: Int) =
             "[^ァ-ヶ]".toRegex().replace(source, "")
    }
```

## 2. フィルターのセット
フィルターセット時、配列になっているので、ここで指定文字のみ入力＋文字数制限のフィルターをセットする

```Kotlin
    edit_text.filters = arrayOf(KatakanaInputFilter(), InputFilter.LengthFilter(30))
```

## 追記
以下の方法だと、余分なクラスを作らない + xmlで```android:maxLength```を指定しても反映されるようになる。

```Kotlin
val filter = InputFilter { source, _, _, _, _, _ ->
	if (source.matches("^[ァ-ヶ]+$".toRegex())) source else ""
}

if (filter !in edit_text.filters) edit_text.filters = arrayOf(*edit_text.filters, filter)
```

カタカナのみ：```ァ-ヶ```
絵文字のみ：```\uD800-\uDBFF\uDC00-\uDFFF```
半角のみ(半角ｶﾅ含む)：```\x01-\x7E\uFF61-\uFF9F```
ほぼ個人メモ EC2インスタンスのターミナルで日本語入力できるようにする方法

# 目的

- EC2インスタンスにログイン後に日本語入力をできるようにする方法をかんたんにまとめる

# 実施

1. EC2インスタンスにログインして下記コマンドを実行することで日本語の入力が可能になる。

    ```terminal
    $ sudo echo "LANG=ja_JP.UTF-8" > /etc/sysconfig/i18n
    $ sudo yum install -y man-pages-ja
    ```
AWS認定デベロッパーアソシエイト(DVA)　合格体験記

受験月：2020/10
AWS認定デベロッパーアソシエイトに合格して嬉しくなっちゃったので記事を書かせてください。

#自己紹介
* web系エンジニア2年目、普段はweb、モバイルアプリの設計開発をしています。
* AWS実務経験、インフラ実務経験共に無し。
* AWSは研修で軽く触った程度でした。
* 会社にAWS知識所有者が少ないとのことで受けることになりました。

#勉強方法
1. まずはAWSについてあまりにも基礎知識が無かったため、下記リンクのudemyの動画講義を一通り受けました。<br>udemyに登録した後の14時間限定セールみたいなので1600円ほどで購入できました。
[Ultimate AWS Certified Developer Associate 2020 - NEW!](https://www.udemy.com/course/aws-certified-developer-associate-dva-c01/)

2. サービスの特徴や用語などがある程度分かってきたのでudemyの問題集にも手を出してみました、初回の演習が45%しかとれず絶望しました。
[AWS 認定デベロッパー アソシエイト模擬試験問題集（5回分325問）](https://www.udemy.com/course/aws-31955/)

3. udemyの演習をすべて完了した時点での最高スコアは59％でした、また基礎から学びなおそうと思い[AWSのブラックベルト](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)を片っ端から読むことにしました、udemyの動画で見たことを反復しながら学習できたので良かったと思います。
4. あとは試験日までひたすらudemyの模擬演習を解き、わからないところは開発者ガイドを読みながら理解を深めました。 

* ちなみに公式の模擬試験は2回受けました、順番は違いましたが問題内容は同じでした。
結果は1回目60％、2回目65%（何故）と散々でした。。。ただ本番と全く同じ形式で問題を解けるのでやる価値はあると思います。

# 試験日当日
* [渋谷テストセンター](http://success-space.com/shibuya.html)で受験しました。<br>口コミでぼろくそに叩かれてたので少し覚悟して行ったのですが全然普通で安心しました。（トイレが少し汚かったです）

* 受付の方の指示に従って同意書にサインした後、本人確認（自分の場合運転免許証とクレジットカードの2つ）が終わり次第写真を撮って試験スタートになります。<br>3時半からの予約でしたが1時間前についてしまったので中で勉強できるかな、と思って入室したのですが前倒しで受けさせてくれました。
* 試験部屋に入るときにティッシュの中とマスクの裏と眼鏡のフレームを確認されました、眼鏡のフレームでカンニングできたら逆にすごいと思いますけどね。

# 試験スタート
* 特になんのアクシデントもなく試験が始まりました、試験の難易度的には<br>公式模擬試験　＜　公式試験　＜　udemy模擬試験<br>だと思います、思いのほかs3とstep functionの問題が出て焦りました。。。どっちもかなり手を抜いていた箇所だったので。

* 自信がある問題が25問ほど、多分これだなぁって感じの問題が25問ほど、後の15問はちょっとわからないみたいな感じでした。

* 1周目の時間は覚えていませんが2周目が終わった時点で30分ほど残っていました、かなりゆっくり考えながら進めたので時間配分などは気にしなくて大丈夫だと思います。

# 試験結果
* 試験終了後、簡単なアンケートに答えた後、合否のみが画面に表示されます。タイトルに書いてあるんでアレですが合格でした。

* スコアレポートは受験した翌日に届きました、スコア自体は872/1000で思ってたより高かったです。

# 感想とか
勉強に時間をかけただけあって合格できてよかったです。（多分100時間くらいかけました）
出題内容的には

* サービスで使うAPI
* 各サービスのCSE、SSE
* 詳しい展開方法

みたいなところはきちんと把握しておかないといけないと思います。
ちょっと自信ついたから次はアーキテクトアソシエイトを受けてみようかなぁ。

最後に、この記事をみてくれた方の合格を祈っています。拙い文章を読んでいただきありがとうございました。
laravel 7.15 で youtube の RSS を取得しようぜ

#インストールするよ

```

composer require vedmant/laravel-feed-reader

```

ちなみに、
`composer require awjudd/feed-reader` はインスコできなかった。

#コントローラーで使うよ

```HogeController.php

use FeedReader;//classの最上部に
$tmp = FeedReader::read('https://www.youtube.com/feeds/videos.xml?channel_id=UCZf__ehlCEBPop-_sldpBUQ');


```

`ヒカキンのRSS読み込みOK`


#解析開始

```HogeController.php

//ひかきん
$tmp = FeedReader::read('https://www.youtube.com/feeds/videos.xml?channel_id=UCZf__ehlCEBPop-_sldpBUQ');


$data = $tmp->data['child']['http://www.w3.org/2005/Atom']['feed'][0]['child']['http://www.w3.org/2005/Atom']['entry'];

$res = [];
foreach ($data as $v) {

    $img = array_shift($v['child']['http://search.yahoo.com/mrss/']['group'][0]['child']['http://search.yahoo.com/mrss/']['thumbnail'][0]['attribs']);
    $title = $v['child']['http://www.w3.org/2005/Atom']['title'][0]['data'];
    $link = array_shift($v['child']['http://www.w3.org/2005/Atom']['link'][0]['attribs']);
    $updated = $v['child']['http://www.w3.org/2005/Atom']['updated'][0]['data'];

    $res[] = [
        'title' => $title,
        'img' => $img,
        'link' => $link,
        'updated' => $updated
    ];

            
}


print_r($res);

```


#結果

```

Array
(
    [0] => Array
        (
            [title] => 【激辛ラーメン】蒙古タンメン中本を自宅で再現したらウマすぎ辛すぎw【ヒカキン&セイキン】
            [img] => Array
                (
                    [url] => https://i1.ytimg.com/vi/XXDofNaZUaM/hqdefault.jpg
                    [width] => 480
                    [height] => 360
                )

            [link] => Array
                (
                    [rel] => alternate
                    [href] => https://www.youtube.com/watch?v=XXDofNaZUaM
                )

            [updated] => 2020-10-04T10:16:03+00:00
        )

    [1] => Array
        (
            [title] => ヴィレヴァンで『この店で値段高いものTOP３全部ください！』って言ったらまさかの事態にwww【高額商品】
            [img] => Array
                (
                    [url] => https://i4.ytimg.com/vi/cAkA25csaJM/hqdefault.jpg
                    [width] => 480
                    [height] => 360
                )

            [link] => Array
                (
                    [rel] => alternate
                    [href] => https://www.youtube.com/watch?v=cAkA25csaJM
                )

            [updated] => 2020-10-02T11:03:51+00:00
        )

    [2] => Array
        (
            [title] => ブロックされたので本当に許さないことにしました。【悪質な詐欺・偽物・なりすましについて】
            [img] => Array
                (
                    [url] => https://i2.ytimg.com/vi/1WJYAHbrpGA/hqdefault.jpg
                    [width] => 480
                    [height] => 360
                )

            [link] => Array
                (
                    [rel] => alternate
                    [href] => https://www.youtube.com/watch?v=1WJYAHbrpGA
                )

            [updated] => 2020-09-30T09:33:26+00:00
        )


```

はい、OK!
IBMCloud NetScaler VPXのオーダ

##目的
IBM Citrix Netscaler VPXをオーダするところまで実施した。
実際の動作確認は、別途実施する予定
   
##オーダ
上部検索バーより、"load"等で検索し、**Load Balancers**を選択する
![IBM_Cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/4d4fc14d-8113-eb4b-55b5-89e4e13f073a.png)

**Citrix NetScaler VPX**を選択し、**作成**を選択する
![Load_Balancers_-_IBM_Cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/7530b78b-71a9-b027-5734-86c21517c8ef.png)

* Location:デプロイしたいロケーションを選択
* Select NetScaler:利用帯域、シングルor冗長構成、機能ライセンスから選択
![IBM_Cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/0d891019-a5ee-7496-fb44-fb2d6693a87d.png)

* SelectIP Addresses:VPXをフロントとして何個のGlobalIPを使うか
![IBM_Cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/a1a58239-de7f-ad14-e042-aef2076a8f22.png)

[RFC2050](https://www.nic.ad.jp/ja/translation/rfc/2050.html)に基づき、ISPはアドレス空間を効率的に利用する必要があるので、
オーダするGIPに対しての利用予定を確認する(あくまでも確認なので、この通り利用しなければならないわけではない。)

![IBM_Cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/22cdd489-8e1c-f1c6-cd30-e81246603e5d.png)

* Contact Name:**名前**
* Contact Job Title:**肩書**
* Contact Email:**連絡先メール**
* Contact Phone Number:**連絡先電話番号**

**I agree**を選択し、**Place Order**を選択する
![IBM_Cloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/5651c148-2c89-c92e-7b49-c406908b0caf.png)

##参考：ライセンスの違い
プレミア
![Citrix_NetScaler_VPX_-_Configuration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/62eb32a1-28c6-ea42-bbd8-0236c85d11a7.png)

スタンダード
![Citrix_NetScaler_VPX_-_Configuration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/45056a8a-5162-f0e4-02cd-261a815f90c1.png)
Unixの歴史を再現したリポジトリを読む⑤

# PDP-7版UNIX再現プロジェクト

![66030537-def77c80-e501-11e9-9b14-bd4e0f495fc7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568364/6dc6b0de-5769-788a-3e37-dfb97caada79.gif)

[PDP-7で開発された最初期のUNIXを再現するプロジェクト] (https://github.com/DoctorWkt/pdp7-unix)があります。

以前より「Unixの歴史を再現したリポジトリを読む」シリーズで紹介している[UNIXリポジトリ再現プロジェクト](https://github.com/dspinellis/unix-history-repo)には、このPDP-7版再現プロジェクトの成果が含まれており、その正体は複数の再現プロジェクトの複合体でした。

ありがたいことに、PDP-7版再現プロジェクトの主要メンバーの1人である[セバスチャン・ラスムセン氏](https://github.com/sebras)からご連絡をいただきました。Google翻訳で私の記事を読んでくださったそうです。

# コピー用紙からソースを復元
![2020-10-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568364/2bc57c84-ffa2-be39-3098-a7299a64342e.png)

PDP-7版のソースコードは、当時のテープが残っているわけではなく、全米各地に残っているソースコードのコピーをかき集めて復元しているそうです。コピーは不鮮明だったり欠落したりしています。一筋縄ではなさそうです。

# ベクタースキャン方式のブラウン管ディスプレイ
![687474703a2f2f6563652e756d6963682e6564752f626963656e74656e6e69616c2f696d616765732f73797374656d732d6c61622d726b62726f776e2e6a7067.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568364/550d19e1-6ef8-98ac-1ffb-bf435554d433.jpeg)

PDP-7にはベクタースキャン方式のディスプレイがついています(PDP-9の写真を使ってしまいましたが、だいたい同じものでしょう)。この大きなディスプレイがついているモデルと、小さなディスプレイしかついていないモデルがあったようです。ていうか恐らくオプションなのでしょう。画像を表示しなくてもよい場合はディスプレイを買わないという選択肢もあったのではないかと思われます。

60年代はタイプライター同士で遠隔通信ができるテレタイプをコンピュータの端末に流用していた時代であり、ディスプレイがなく、タイプやパンチされた紙を見て入出力を確認するのが普通でした。ディスプレイは画像を表示するために付けられたもので、ターミナルとして使うことは想定されていなかったものと思われます。しかしこのブラウン管のディスプレイがついた端末は当時としては画期的な部類だったことでしょう。

# PDP-7版UNIXのフォント
![67319342-13f95c80-f50d-11e9-8599-87744a43997a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/568364/d4bc000e-8832-a446-e5e9-4b2c7f12c890.png)

この映像は再現プロジェクトの皆さんがエミュレーターを作りながら再現したものです。

このベクタースキャンのディスプレイに文字を出すのは一苦労だったに違いありません。ドットという概念がなく、ビームの軌跡で文字を描かないといけません。

# 謎のデータの正体
``` asm:cas.s
:cf
v
aa
ak
x
gh
v
ga
x
mn
r

:cg
x
gf
v
gk
nk
x
kk
v
mi
mc
ka
ca
ac
ai
dl
x
mn
r
```

[Unixの歴史を再現したリポジトリを読む①] (https://qiita.com/hayashida-katsutoshi/items/37afd9acbce117aa223c)で紹介した、cat.sの中にある謎のデータ文。これはB言語のスレデッドコードではないか、scope.vのvはバーチャルのvではないかという予想を書きましたが、間違っていました。

セバスチャン氏によるとこれはベクター形式のフォントデータ。ラベルのcfはFのフォント、cgはGのフォントを表しているそうです。vはベクターのvだったようです。

このフォントデータは、ケン・トンプソン自身がUNIXの開発を始める前に作っていたSpace Travelというゲームから流用したものがベースになっているようです。

そういえばこのコードはTTY(標準入出力)のコードを追っている時に見つけたものでした。フォントであればTTYのコードに混ざっているのも理解できます。ちなみにTTYはテレタイプ(TeleType)の略です。

# 解析プロジェクトの成果
それにしても初期UNIXのコード解析は大変です。コメントのないアセンブラですし、ディスプレイがベクタースキャンだったという驚きの事実も、コードを懸命に追うだけではわからなかったかもしれません。

cat.sをちゃんと読んで解析していないことにちょっと負い目がありましたが、PDP-7版UNIX再現プロジェクトのディスカッションなんかを見ていると、エキスパートの皆さんでも四苦八苦しており、カジュアルに読んで楽しみたいだけの私なんかがパワーを注げなくてもまぁしょうがないです。

しかしプロジェクトの皆さんの努力があって、私たちもこうして楽しめているわけで、本当にありがたい限りです。

# バックナンバー
[Unixの歴史を再現したリポジトリを読む①] (https://qiita.com/hayashida-katsutoshi/items/37afd9acbce117aa223c)
[Unixの歴史を再現したリポジトリを読む②] (https://qiita.com/hayashida-katsutoshi/items/3c4bc05ab4c627286be8)
[Unixの歴史を再現したリポジトリを読む③] (https://qiita.com/hayashida-katsutoshi/items/eb80ebd5667af10193f5)
[Unixの歴史を再現したリポジトリを読む④] (https://qiita.com/hayashida-katsutoshi/items/5edde08b01b81dac26b7)
[Unixの歴史を再現したリポジトリを読む⑤] (https://qiita.com/hayashida-katsutoshi/items/df9c08c4c5011f04b45e)
qiita_orgのコマンドについて

![Mac OS X-10.13.3](<https://img.shields.io/badge/MacOSX-10.13.3-brightgreen>) ![ruby-2.7.0p0](<https://img.shields.io/badge/ruby-2.7.0p0-brightgreen>) ![qiita\_org version](<https://img.shields.io/badge/qiitaorg-0.1.8-brightgreen>)

少しわかりずらい記事になっているので以下の記事も参考にしてみてください。
[設定方法からコマンドについての最新版](https://qiita.com/yamatoken/items/2cefc503215afacc0b11)

# はじめに

ここではqiita\_orgのコマンドについて書いて行きます．

# コマンド一覧

-   qiita all
-   qiita config [global/local] [option] [input]
-   qiita get [qiita/teams] [記事のID]
-   qiita list [qiita/teams]
-   qiita post [FILE] [private/public/teams]
-   qiita template [FILE名]
-   qiita upload [FILE] [private/public/teams]

# qiita all

カレントディレクトリ内の全てのorgファイルをqiitaに投稿するコマンドです．

orgファイル内にidの記載のあるものは記事の更新，id記載のないものに関しては全て限定共有投稿に投稿されます．

# qiita config

qiita\_orgの設定ファイルの作成と確認を行うコマンドです．

設定方法については[<https://qiita.com/yamatoken/items/858692178d288c40714d>](<https://qiita.com/yamatoken/items/858692178d288c40714d>)を参照してください．

# qiita get

Qiitaの記事を取得するためのコマンドです．

## 特定記事の取得方法

qiita get [qiita/teams] [記事のID]

実行することで指定した記事をid.orgとしてディレクトリ内に作成します．

## 複数記事の取得方法

自分のQiitaもしくはQiitaTeamの記事を最新から100個まで表示し取得できます．

qiita get [qiita/teams]

実行するとタイトルが表示されるので，保存したければ'y'いらなければ'n'を入力する．終了は'e'

# qiita list

自分のQiitaもしくはQiitaTeamの記事を最新から100個までterminal上に表示するコマンドです．

qiita list [qiita/teams]

実行するとオプションがqiitaならtitle, URL, 記事の元となったorgファイルの場所が表示されます．

teamsの方ではさらに誰の記事かが表示されます．

# qiita post

Qiitaにorg-modeで書いたテキストを投稿するためのコマンドです．

qiita post [FILE] [private/public/teams]

FILEには投稿したいorgファイルを，privateは限定共有投稿，publicは公開記事，teamsはQiitaTeamに投稿されます．

例:

```
qiita post example.org private
```

と実行すると限定共有記事にexample.orgの内容が投稿されます．

# qiita template

qiita\_orgで投稿するためのヘッダーがついたorgファイルを取得するコマンドです．

qiita template [FILE名]

FILE名を指定すればその通りのOrgファイルがカレントディレクトリに生成されます。
指定がなければカレントディレクトリにtemplate.orgを作成しますが、すでにtemplate.orgがある場合は作成されません．

# qiita upload

Qiitaにpostコマンドを使って投稿したファイルに記載されている画像などを投稿するためのコマンドです。

qiita upload [FILE] [private/public/teams]

FILEには投稿したいorgファイルを，privateは限定共有投稿，publicは公開記事，teamsはQiitaTeamに投稿されます．

例:

```
qiita upload example.org private
```

と実行すると限定共有記事にexample.org内に記載されている画像などのデータを投稿できます．
画像等をOrg内に記載する方法は

```
[[file:画像のPATH]]
```
と記載すれば反応します。CAPTIONなどをつければHTMLの発行時などにも使えます。

------
 - **source** ~/Github/grad_research_20s/yamato/test/qiita_org_use.org
LaravelでReactを使う準備の私的まとめ


#環境
- laravel 7.27.0

#Reactへの切り替え
まずはlaravel/uiをインストール

```
composer require laravel/ui:0.*
```
laravel7からは`php artisan preset react`と入力すると
`Command "preset" is not defined.`と表示される
**laravel7からは`preset`コマンドが使えなくなったため。**
参考：[【解決済み】 Command “preset” is not defined.のエラーを解消する方法](https://shiro-changelife.com/command-preset-is-not-defined/)

その後npmコマンドを実行

```
npm install
```

その後以下コマンドを実行

```
php artisan ui react
```
`--auth`オプションを付けるとログイン認証機能もインストールされる

`resources/js/components/Example.js`になっていることを確認
#参考
- [LaravelでAPIを作成して、Reactで取得したい](https://qiita.com/rei67/items/273ebef44d19912733b7)
- [【Laravel】Composer requireでエラー(Installation failed, reverting ./composer.json to its original content.)が出るけどrequireしたい！
](https://qiita.com/anoonoll/items/5fab1e6682861a406570)