OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby学習#23 For Loops

friends =["Kevin","Karen","Oscar","Angela","Andy"]

for friend in friends
  puts friend
end

>>Kevin
Karen
Oscar
Angela
Andy

for element in friends
  puts element
end

>>Kevin
Karen
Oscar
Angela
Andy

friends.each do |friend|
  puts friend
end

>>Kevin
Karen
Oscar
Angela
Andy


for index in 0..5
  puts index
end

>>0
1
2
3
4
5


6.times do |index|
 puts index
end

>>0
1
2
3
4
5
自分のおすすめの商品を紹介するサイトを作ってみた

## 概要
アフィリエイトリンクをまとめて貼ることができます。（現在は楽天アフィリエイトリンクのみ）
↓こんな感じでユーザのおすすめ商品を
https://theprion.com/users/6?category_id=4
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650232/46b21baf-d170-498f-d442-649831fc57b6.png)

Twitterアカウントがあれば誰でも始めることができます。
他人のページを見るだけならアカウント登録は必要ありません。

## なぜ作ったか
YouTuberが自分のおすすめの商品を紹介している動画をみて、
「紹介する人に魅力があれば、それだけで商品は売れるのではないか」
そう思い、ユーザが使用している商品を紹介することに特化したサイトを
作りました。

## 使用技術
RoR
Docker
AWS
Git

いずれ広告をつけて、サーバ代くらいは稼げたらうれしいです。

サイトURL
https://theprion.com
if文( > 0 )の省略について　※自分用メモ

#-初めに-
学習してた際に、if文の省略を忘れていたので「自分の補足用」に記述する。
プログラム歴も浅くQiita投稿も初めてである為、**誤りである可能性が高い事を留意いただきたい。**
#- プログラムの内容 -
for文の繰り返し処理を利用し、
ブラウザの一行目に英文の「Hello world」
二行目には日本語で「ハローワールド」を表示するプログラムを計4行作成するというもの。
最後はbrタグで改行をしている。

```php5:qiita.php
for ($i=1; $i<=4; $i++) {
 if ($i % 2) {
  print($i.'行目：Hello world');
 } else {
  print($i.'行目：ハローワールド');
 }
 print('<br>');
} 
```

###完成形
1行目：Hello world
2行目：ハローワールド
3行目：Hello world
4行目：ハローワールド

#- 今回躓いた点 -
下記if文のtrue条件を理解できなかった
「$iが1だとして、それを2で割った余りがtrue?意味不明?!」といった感じだった

```php5:qiita.php
if($i % 2) {}
```
###trueの条件
**true条件は変数$iを2で割った余りが「0より大きい」場合である**

##なぜ理解できなかったか？
問題はif文の式で省略されてた**(>0)**にあった
下記2つのif文は同じ意味になる

```php5:qiita.php
if ($i % 2) {}
if ($i % 2 > 0) {}
```

if文の(>0)が省略される為
$iが1の場合のみtrueになる
Ruby学習#22 Building a Guessing Game


secret_word = "giraffe"
guess =""

while guess != secret_word
   puts "Enter guess: "
   guess = gets.chomp()
end
puts "You Won!"

secret_word = "giraffe"
guess =""
guess_count = 0
guess_limit = 3
out_of_guesses = false

while guess != secret_word and !out_of_guesses
   if guess_count < guess_limit
     puts "Enter guess: "
     guess = gets.chomp()
     guess_count += 1
   else
     out_of_guesses = true
end
if out_of_huesses
   puts "You Lose"
else
  puts "You Won!"
end
Pardot のプロセスオートメーション (Pardot Lightning アプリケーション) ⇒ オートメーションツールの使用開始

１．オートメーションツールのうち、マーケティング要素から直接自動化できるのはどれですか?
２．Pardot でワークフローを自動化する 2 つの理由はどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/81155bc4-565a-43dd-0ab7-8d42e51e3e8c.png)
docker+rails(ver5.2)での本番環境の起動と生じたエラー

初めての投稿になりますので、間違いなどあればご指摘ください.
また、今回の投稿はdockerでのrails5.2の本番環境の起動の助けになればと思います。

## 環境
* rails ver 5.2
* docker

## 記事の内容
主に4つのパートに分かれています。

* railsでの本番環境にするにはどのように設定する必要があるのか
* dockerでの設定方法
* build後の起動時のエラー
* 解決方法

## railsで本番環境にするにはどのように設定する必要があるのか
まず、rails5.2での本番環境で起動にするには主に以下の四つが必要になります
1. database.ymlやデータベースでのproduction環境を設定する
2. SECRET_KEY_BASEがcredentials.yml.encに存在するか確認
3. アセットプリコンパイルを行う
4. サーバーの起動

## dockerでの設定方法
dockerでは起動に必要な部分を記述して起動を行います
#### データベース関連
database.ymlを設定やDB接続などを設定します。

```yml:database.yml
production:
  <<: *default
  database: 
  username: 
  password: 
```
#### credentials.yml.encでのSECRET_KEY_BASの確認
以下のコマンドをdockerで走らせることができれば確認できると思います

```
EDITOR=vim rails credentials:edit
```
私はdocker-composeを利用していたので以下のコマンドで確認しています

```
docker-compose run -e EDITOR=vim web rails credentials:edit
```
#### アセットプリコンパイル
railsのassetsファイルをプリコンパイルする必要があります

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

#### dockerに記述する部分
以下の記述を追加して起動を行いました

```dockerfile:Dockerfile

ENV RAILS_ENV="production"

RUN SECRET_KEY_BASE=production bundle exec rails assets:precompile
```

### 起動時の生じたエラー
さて起動をしてみると以下のエラーが出てきました。

```
`validate_secret_key_base': Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit` (ArgumentError)
```
内容としては「secret_key_base値が見つからないため、起動できません」となっています。　
そこでネット上で検索してエラーを解決しようとしていましたが解決できていませんでした。

* SECRET_KEY_BASEの値の確認
* production.rbでの設定の変更
* アセットプリコンパイルのエラーが原因なのかを調査

### エラーの解決策
以下のサイトを試すと解決しました
https://qiita.com/laser_beam/items/b4abdfed09fd987308fb

具体的にはcredentials.yml.encファイルのSECRET_KEY_BASEに対してスペースを入れると解決しました。
before

```enc:credentials.yml.enc
secret_key_base: *****************************
```

after

```enc:credentials.yml.enc
 secret_key_base: *****************************
↑スペースが入ります
```
原因はわかりませんが、どうしても解決しない時は試してみるといいかもしれません。

## 終わりに
予想外の方法で解決したので、試せることは試すことが大切だと思いました。

## 参考にした記事
* https://qiita.com/laser_beam/items/b4abdfed09fd987308fb
* https://qiita.com/mokuo/items/b766ca36521530fd3084
* https://qiita.com/scivola/items/cc06ddbfd94d3118f693
* https://qiita.com/notozeki/items/ac1bf72cf44b7ed6a6ad
* https://qiita.com/qqhann/items/7cd01f4b5cff4a31e053
EC2(Amazon Linux)にpyenvをインストール

# ECにpyenvをインストールする際に何点かつまずいたのでメモ

```shell
# gitをインストール
yum install git 
# pyenvをクローン
git clone https://github.com/pyenv/pyenv.git ~/.pyenv 
# 環境変数に追加
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.zshrc
exec "$SHELL"
# 依存ソフトウェアをインストール
sudo yum install gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel
pyenv install 3.7.7
```
Ruby学習#20 Case Expressions

def get_day_name(day)
  day_name = ""

  case day
  when "mon"
    day_name = "Monday"
  when "tue"
    day_name = "Tuesday"
  when "wed"
    day_name = "Wednesday"
  when "thu"
    day_name = "Thursday"
  when "fri"
    day_name = "friday"
  when "sat"
    day_name = "Saturday"
  when "sun"
    day_name = "Sunday"
  else
    day_name = "Invalid abbreviation"
  end

  return day_name
end

  puts get_day_name("mon")
  >> Monday
Ruby学習#19 Building a Better Calculator


puts "Enter first number: "
num1 = gets.chomp().to_f
puts "Enter operator: "
op = gets.chomp()
puts "Enter second number: "
num2 = gets.chomp().to_f

if op == "+"
  puts (num1 + num2)
elsif op == "-"
  puts (num1 - num2)
elsif op == "/"
  puts (num1 / num2)
elsif op == "*"
  puts (num1 * num2)
else
  puts "invalid operator"

end
google recruit

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 


# 課題

 e(自然対数の底)の値で連続する10桁の数のうち，最初の素数をrubyで求めよ．（ただし，e(自然対数の底)は200桁までとする）

```text
2.71828182845904523536028747135266249775
7247093699959574966967627724076630353547
5945713821785251664274274663919320030599
2181741359662904357290033429526059563073
81323286279434907632338298807531952510190
```

まず，おおざっぱにプログラムを分割して考える．１．テキストからデータを読み込む．２．素数判定．３．連続する10桁の数を抽出，メイン関数

-1.テキストからデータを読み込む

```ruby
def getdata()
      tmps=readlines.map(&:chomp)
      tmp=tmps.join
      e=tmp.delete('.')
      return e
end
```

mapメソッドは要素数分繰り返しブロックを実行．その戻り値を配列として返す．chompで改行を削除する処理を行う．その後は文字列に変換ののち，小数点を削除する．

-2.素数判定．

```ruby
def judge(n)
      return false if n%2==0
      for i in 3...Math.sqrt(n) do
	  return false if n%i==0
	  i+=2
      end
      return true
end
```

まず，大前提として偶数は削除，今回は２については考慮しない．3以上の奇数に対して，以下の性質を利用．「合成数xはp≦√xを満たす素因子pをもつ」つまり,「合成数xはp≦√xを満たす素因子pをもつ」＝「xが合成数ならば、√x以下の約数を持つ」記の条件にかからないものを求める．

-3. 連続する10桁の数を抽出，メイン関数

```ruby
def main
      data=getdata()
      while data.length>=10 do
	    n=data.slice(0, 10)
	    break if judge(n.to_i) 
	    data.slice!(0)
      end
      puts "A.#{n}"
end
```

200桁の自然対数の底を受け取り，連続する10桁の数を受け取り，判定する．

実行すると，

```text
$ ruby google.rb < e.txt
A.7427466391
```

\*参考 -[素数判定](https://qiita.com/asksaito/items/76b71602dd956b79dbf7)



------
 - **source** ~/grad_members_20f/members/szksjm/qiita_post/google.org
Ruby学習#17 If Statements

I wave up 
If I'm hungry
  I eat breakfast

I leave my house
if it's cloudy
  I bring an umbrella
otherwise
  I bring sunglasses

Im at a restaurant
if I want meat
  I order a steak
otherwise if I want pasta
  I order spaghetti & meatballs
otherwise
  I order a salad.


ismale = false

if ismale
 puts "You are male"
else
 puts "You are not male"
end

ismale = false
istall = true

if ismale and istall
 puts "You are tall male"
elsif ismale and !istall
 puts "You are a short male"
elseif !ismale and istall
 puts "You are not male but are tall"
else
 puts "You are not male or not tall"
end
MacでCOBOLのプログラムを動かすまで

基本情報や応用情報の合格発表がSNSで散見される季節になりましたね。
工業高校生の頃にCOBOLで基本情報技術者試験を受験したのを思い出して、久しぶりに触ってみたくなりました。

もういまはCOBOLは選択できなくなって、Pythonに代わったらしいですね。

macOS Big Sur バージョン11.1
で作業しました。

余談ですが、BigSurではThunderbirdが激重です。
Thunderbirdユーザーの方は気をつけてください。

**cobolのパッケージの検索**

```
% brew search cobol 
==> Formulae
gnu-cobol
```

**cobolのパッケージのインストール**

```
% brew install gnu-cobol
Updating Homebrew...
・・・
🍺  /usr/local/Cellar/gnu-cobol/3.1.2: 64 files, 2.6MB
```

**パッケージのバージョンの確認**

```
% cobc -V
cobc (GnuCOBOL) 3.1.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward Hart
Built     Dec 23 2020 19:29:52
Packaged  Dec 23 2020 12:04:58 UTC
C version "Apple LLVM 12.0.0 (clang-1200.0.32.28)"
```

**サンプルソース**

ちょっとおしゃれにDIVIDEを使ってみました

``` cobol:hello.cob
       IDENTIFICATION    DIVISION.
       PROGRAM-ID.       COUNT.
       DATA              DIVISION.
       WORKING-STORAGE   SECTION.
       01 CNT   PIC 9(3) VALUE 0.
       01 A     PIC 9(3) VALUE 0.
       01 B     PIC 9(3) VALUE 0.
       PROCEDURE         DIVISION.
          PERFORM 100 TIMES
              ADD 1 TO CNT
              DIVIDE CNT BY 5 GIVING A REMAINDER B
              IF B = 0 THEN
                DISPLAY "COUNT = " CNT
              END-IF
          END-PERFORM
          STOP RUN.
```


**コンパイルと実行**

```
% cobc -x -Wall -debug hello.cob
% ./hello 
COUNT = 005
COUNT = 010
COUNT = 015
COUNT = 020
COUNT = 025
COUNT = 030
COUNT = 035
COUNT = 040
COUNT = 045
COUNT = 050
COUNT = 055
COUNT = 060
COUNT = 065
COUNT = 070
COUNT = 075
COUNT = 080
COUNT = 085
COUNT = 090
COUNT = 095
COUNT = 100
```
FCMでPush通知をテスト送信する 

## 方法
1. FCMの管理コンソールから送信する
2. FCMのAPIを使って送信する

## FCMの管理コンソールから送信する

@toshi586014 さんの [Firebaseの管理画面からプッシュ通知を送る方法](https://qiita.com/toshi586014/items/63ef8eed6387634bc22c)　記事が参考になります。

### 自分がつまづいたところ

#### デバイストークンの入力位置がわからなかった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53477/d6bd0ec7-d689-1e9a-86dd-0c8fd3f08c1e.png)

#### デバイストークンを入力した後、そのまま全体送信の設定を続けていた
* 【正解】上記の、デバイストークンの入力後に、「テスト」ボタンを押したらすぐに送信される。
* 【つまづき】「テスト」ボタンを押しても通知は届かなかったので、その後、画面の指示に従って、②ターゲット→③スケジュール…と設定して進めようとしてしまった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53477/1fd984ac-6f34-b8eb-29bd-fcc0b0c8911f.png)

#### テスト送信時にカスタムデータを送信する方法がわかりずらい

* 上記画像の①～⑤で設定した内容がテスト送信に反映される。
* なのでテスト送信する時は①～⑤を入力してから、「テストメッセージを送信」からデバイストークンを入力して、「テスト」ボタンを押したら即送信される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53477/c8130bd9-0e5a-e587-8d37-63124af2839b.png)

---

## FCMのAPIを使って送信する

@nishi-sankosc さんの [FCM HTTP v1 APIを使ってWeb Push送信]
(https://qiita.com/nishi-sankosc/items/b9040ee57e6b7223ff21) の記事がとても参考になりました。

### Firebase公式
https://firebase.google.com/docs/cloud-messaging/auth-server?hl=ja
https://firebase.google.com/docs/cloud-messaging/send-message?hl=ja

### curl
```
curl -X POST -H "Authorization: Bearer [OAuth 2.0 アクセス トークン]" -H "Content-Type: application/json" -d '{
"message":{
   "notification":{
     "title":"FCM Message",
     "body":"This is an FCM Message"
   },
   "token":"[デバイストークン]"
}}' https://fcm.googleapis.com/v1/projects/[送信者ID]/messages:send
```

#### OAuth 2.0 アクセストークンの取得

1: https://firebase.google.com/docs/cloud-messaging/auth-server?hl=ja#provide-credentials-manually
に書いてある方法で鍵を取得。
2: @nishi-sankosc さんの [FCM HTTP v1 APIを使ってWeb Push送信]
(https://qiita.com/nishi-sankosc/items/b9040ee57e6b7223ff21) の記事にあるgetAccessToken.jsを使って取得。

#### デバイストークン

WIP

#### 送信者ID

Firebaseプロジェクトの設定 > Cloud Messaging > プロジェクト認証情報 に記載あり。
Ruby学習#16 Return Statement

def cube(num)
 num * num * num
end

puts cube(3)
>>27

def cube(num)
 num * num * num
 5
end

puts cube(3)
>> 5

def cube(num)
 return num * num * num
 5
end

puts cube(3)
>> 27

def cube(num)
 return num * num * num, 70
 5
end

puts cube(3)
>> 27
70
puts cube(3)[1]
>>70
そうだったのか、user_signed_in?メソッド

#はじめに
　プログラミングの学習を始めた頃から、ずっと思っていることがあります。メソッド名についてです。

　メソッド名、どこまでは、意味をもっているものなのかわからない問題。
メソッドは自分でも作れる故、どこまでが、意味を有しているのか、判断がつきません。この記事では、今まで`user_signed_in?メソッド`は全てに意味を有していると思っていたが、そうではなかったことを紹介しています。


##deviseとは
　Rubyで扱うことができる、gemの一つで、ユーザー管理機能がまとまっていて、簡単にログイン機能等を実装できる、便利なgemです。

##いつもの流れ

deviseを使ってユーザー管理を行うときに、ターミナルで、モデルやコントローラー、ビューを生成させます。
例）

```bash

rails g devise user
```

そう、いつも`user`をモデル名やコントローラー名にしています。

##user_signed_in?メソッド
　<font color=red>ユーザーがサインインしているかを確かめるためのメソッド</font>で、
サインインしている状態だと、`ture`
ログアウト状態だと、`false`
が返ってきます。
そのため、if文と合わせて、サインインしているユーザーとサインインしていないユーザーで表示させるものを分岐させるときによく使います。

##user_signed_in?のuserには意味がない？

```bash

rails g devise admin
```

　私は、deviseでuserとadminのモデルやコントローラーを作成しました。そこで、adminにだけ表示させたいときは、どうすればいいのか、悩みでした。

<font color=red>user_signed_in?の`user`の部分は変更可能！！</font>

`admin_signed_in?`にしてもエラーにはなりませんでした。
SQLServerのユーザー設定まとめ

##はじめに
データベースのユーザー作成とか権限付与などのやり方を毎回忘れてググってる気がするので自分用にまとめます。
ついでに他の誰かの助けになれば幸いです。

頻繁に使うものはまた随時追加していきます。

###Database Userの作成
**※ログインユーザーは作成しません。**
包含データベースユーザーを作成していきます。
参考：[包含データベース ユーザー - データベースの可搬性を確保する](https://docs.microsoft.com/ja-jp/sql/relational-databases/security/contained-database-users-making-your-database-portable?view=sql-server-ver15)

```
CREATE USER qiita_user
WITH PASSWORD = 'passw0rd'
GO
```

###Roleの作成

```
CREATE ROLE qiita_writer
GO
```

###UserへのRole割り当て

```
EXEC sp_addrolemember N'qiita_user', N'qiita_writer'
GO
```


###Schemaの作成

```
CREATE SCHEMA qiita_schema
GO
```

###Roleに対して特定のテーブルへの権限割り当て

```
GRANT
    SELECT,
    DELETE
ON [schema].[tablename] TO qiita_writer
GO
```

###Userに対して特定のSchemaへの権限割り当て

```
GRANT SELECT ON SCHEMA::qiita_schema to qiita_user
GO
```

###To be continued
Ruby学習#15 Methods


def sayhi
  puts "Hello User"
end

sayhi
>>Hello User

puts "Top"
sayhi
puts "Bottom"

def sayhi(name,age)
  puts ("Hello" + name + ",you are " + age)
end

sayhi("Mike",73)
>> error String型とInt型がくっつかない。
def sayhi(name,age)
  puts ("Hello" + name + ",you are " + age.to_s)
end

sayhi("Mike",73)
>> Hello Mile ,you are 73

def sayhi(name="no name",age=-1)
  puts ("Hello" + name + ",you are " + age.to_s)
end
sayhi("Mike")
>>Hello Mike, you are -1
sayhi
>>Hello no name , you are -1
GitLab CIでdocker imageをビルドする時、docker daemonが起動してくるまで待つ

# 背景

GitLab CIでdocker imageをビルドするJobがコケる原因を調べていたら、どうも`docker info`をした時にコケていることが分かった。

![docker info failed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265900/f58fcef8-b21a-dbe8-bde5-01fe01dc1dad.png)

dockerはクライアント - サーバー型のアプリケーションだが、サーバー側であるdocker daemonが起動してくる前に`docker info`コマンド打ったりすると「daemonがないんですけど…」と怒られてしまう。

```
Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?
```

docker in dockerである`dind`は正しく使用しており、本当にただ起動が遅れているだけなので、`sleep 10`のように待つとビルドは通る。しかし謎のsleepはつけたくないので、daemonが起動してくるまで待つようにしたい。

# やったこと

シェルスクリプトを書いてプロジェクトに追加した。
幸い、daemonがないとdocker infoがエラーとなることが分かっているので、それを利用する。

```sh:wait.sh
#!/bin/sh

# dindのdocker daemonが起動するまで待つスクリプト
while :
do
    if docker info > /dev/null 2>&1; then
        break
    fi
    echo 'waiting docker daemon...'
    sleep 1
done

exit 0
```

.gitlab-ci.ymlの`docker info`よりも前にスクリプトを仕込む。実行可能にするためにchmodも忘れない。

```yml:.gitlab-ci.yml
before_script:
  - chmod u+x wait.sh && ./wait.sh
  - docker info
```

# 結果

起動を待つようになってくれてビルドが失敗することがなくなった。

![docker daemonを待つようになった](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265900/ebc3bf5a-1e22-2fdf-0bab-79d74734aa79.png)
正規表現で検索件数を取得する。SeleniumBasic VBA Python

SeleniumBasicでスクレイピングをしているときによくつかう正規表現のまとめ

随時追記予定

##■検索件数を取得する
例：食べログ検索画面で「新宿」と入力、でてきた件数を取得する
[食べログで検索](https://tabelog.com/)
検索結果：1～20 件を表示 ／ 全 4664 件
この「4664」を取得したい。


##Windows10 エクセルでVBA操作


###準備：検索対象の文字列から全角や改行コードなどを削除し正規表現を簡単にする(VBA)


```:vba
 Dim mozi as String
 mozi = "検索結果：1～20 件を表示 ／ 全 4664 件"     '対象文
  
 mozi = WorksheetFunction.Clean(mozi)  '改行コードなどの削除
 mozi = Replace(mozi, " ", "")　　　　　'半角空白の削除   
 mozi = Replace(mozi, "　", "")         '全角空白の削除

 Debug.Print (mozi)  '検索結果：1～20件を表示／全4664件
'↑無駄な空白が削除されました。

```

###②検索結果：1～20件を表示／全4664件の4664を正規表現で取得する(VBA)

```:vba

Dim re As RegExp
Set re = New RegExp
Dim pattern As String: pattern = "全(\d+)件"     '正規表現のパターン
Dim mc As MatchCollection
Dim m As Match
Dim Matches As MatchCollection

'正規表現の指定
With re      
  .pattern = pattern
  .IgnoreCase = False     '大文字と小文字を区別するか(False)、しないか(True)
  .Global = True          '文字列全体を検索するか(True)、しないか(False)
End With    
 
 Set Matches = re.Execute(mozi) '↑で準備した文字列に正規表現でのマッチングを実行    
   
 If Matches.Count > 0 Then
    
  Debug.Print (Matches.Item(0))  '全4669件
' ↑この時点で「全4669件」です。なので
'このなかから席気表現パターンの()でくくった数値のみを取り出したい
 　set m = Matches.Item(0)
 　Debug.Print (m.SubMatches(0))  ’4669　やったー取得できた    
 End If

```
##Pythonの場合
環境
Windows
Python3.8.3

```:python
import re

mozi="1～20 件を表示 ／ 全 4664 件"
pattern = "全(\d+)件"
mozi=mozi.replace(" ","")  #半角空白の削除
mozi=mozi.replace("　","")　#全角空白の削除
ptn=re.compile(pattern)　　　#正規表現のパターンを準備Patternオブジェクトがリターンされる

if result := ptn.search(mozi):    #検索実行　合致するときはMatchオブジェクト無いときはNone
    print(result.group(0))        #全4664件　マッチした文字列全体
    print(result.group(1))        #4664   ()でくくった部分

```

全〇〇件の〇〇の抽出はしょっちゅうつかいますね。
その他にもよくつかう正規表現随時追記していきます。
もっと簡単な方法があればご指摘いただきたいです。
[Ruby on Rails] CarrierWaveの使い方

#CarrierWaveとは
ファイルアップロードを簡単に追加することができるgemです。

#CarrierWaveのインストール
 `Gemfile` に以下を追記した後、コマンドを実行してgemをインストールします。

```
gem 'carrierwave'
```

```
$ bundle install
```

#アップローダーの作成
`rails g uploader アップローダー名` をコマンドで実行すると、 `app/uploaders/image_uploader.rb` ファイルが作成されます。
今回は、アップローダー名を `image` にしています。

```
$ rails g uploader image
```

#モデルとの紐付け
`mount_uploader ：アップローダー名, クラス名` を関連づけるモデルに追加していきます。

```
class Post < ApplicationRecord
  mount_uploader :image, ImageUploader
end
```

#コントローラーの編集
画像をアップするためのコントローラーを作成します。
画像のアップロードを意識せず、いつも通り作成します。
テキストと画像のカラムがあるので、ストロングパラメーターを以下のように記述しています。

```
class PostsController < ApplicationController

 private
 def post_params
  params.permit(:image, :content)
 end

end
```
#viewの編集
画像をアップするためのフォームを作成します。
画像のアップロードを意識せず、いつも通り作成します。
例えばこんな感じになります。

```
<%= form_with url: "/posts/create" do |f| %>
  <div class="form">
    <%= f.label "写真の投稿" %><br>
    <%= f.file_field :image %><br>
    <%= f.text_area :content, value: @post.content %><br>
    <%= f.submit "投稿" %>
   </div>
<% end %>
```

このフォームを使って画像をアップすると、 `public/uploads` フォルダに画像が保存されます。

`<% if @user.image? %>` を追加すると、画像を設定したかどうかを確かめ、画像を設定した時としていない時で条件分岐することもできます。

#保存した画像を表示させる
保存した画像を表示させる場合は、 `image_tag` で呼び出します。

```
<%= image_tag @post.image_url %>
```

 `if ＠post.image?` を追加すると、画像がない時にエラーが出るのを防げます。

```
<%= image_tag ＠post.image_url if ＠post.image? %>
```
日本語のストップワードを削除するモジュールをpyplに上げたのでその共有

自然言語処理のアドベントカレンダーが埋まっていなかったので、僭越ながら最近自分で書いて使っている形態素解析済みの単語をリストとして持つ文書のリストからストップワードを除去するというプログラムをpypl(pip)に登録して皆さんに共有したいと思います。

# はじめに

もしかすると、すでに便利なライブラリがあるのかもしれませんが、普段使っているscikit-learnには英語のストップワードを除去する機能はあるけど日本語はないです。

なのでいつも自分で実装しているのですが、だったらpyplに登録してpipでインストールすれば楽なんじゃないのかと思った次第です。

いや、別に大したコードじゃないんでその都度書けばいいんですけど、十数行にはなるのでもしpipで公開したら使ってくれる人いるのかもしれないと思いました。

普通にpythonでlistを展開して、ストップワードのリストと照らし合わせて削除するだけのコードなので、実行速度が速くなるみたいな機能はないです。

ただ、今日はちょっと暇だったので品詞別にストップワードのリストの中身を変える機能を搭載させました。

というのも、文章の特性によって削除する単語の品詞って変えたほうがいいと思うんですよね。

例えば、SNSの投稿とニュースサイトの記事は品詞ごとの単語の役割ってちょっと違っていると思います。

でも、ストップワードの中身を変えたところで大してモデルの精度に影響はないような気もしますけど・・・。

削除する品詞ごとの単語は、wikipediaや[ミエルカAI-日本語ストップワードの考察【品詞別】](https://mieruca-ai.com/ai/nlp-stopwords/)、[slothlib](https://ja.osdn.net/projects/slothlib/scm/svn/tree/head/CSharp/Version1/)あたりを参考にさせてもらって選びました（各品詞ごとに30~50って感じです）。

# 使い方

pipでインストールできます。依存しているライブラリはscikit-learnだけです。

```
pip install ja_stopword_remover
```

後は普通にimportするだけです。

```
from ja_stopword_remover.remover import StopwordRemover
```


注意するところは、**"形態素解析済みの単語をもつリストとして持つ文のリストを投げると、ストップワードを削除して返してくる"**というところです。

`StopwordRemover`クラスからインスタンスを用意して、`remove()`メソッドの引数に単語のリストの分のリストを指定して呼び出せば、結果のリストが返されます。

## サンプルコード

```python
from ja_stopword_remover.remover import StopwordRemover
import pprint

# 多田なの(@ohta_nano)さんの詩です。
text_list = [[ "僕", "たち", "は", "プラネタリウム", "に", "立て籠もり", "夜明け", "の", "シーン", "だけ", "繰り返す",],
    [ "桜", "って", "「", "さくら", "」", "って", "読む", "って", "あなた", "から", "教えて", "もらう", "人", "に", "なりたい",],]

stopwordRemover = StopwordRemover()

text_list_result = stopwordRemover.remove(text_list)
pprint.pprint(text_list_result)

stopwordRemover = StopwordRemover()

text_list_result = stopwordRemover.remove(text_list)
pprint.pprint(text_list_result)

```

もし、一文だけからストップワードを除去したい場合は、その文をさらにリストに詰めてください。

## 削除する品詞を指定する

品詞を指定したい場合は`test_choose_parts()`の引数で指定して下しさい。

|パラメータ名|品詞名|
|---|---|
|demonstrative|指示語|
|pronoun|こそあど言葉|
|symbol|記号|
|verb|動詞|
|one_character|一字|
|postpositional_particle|助詞|　
|adjective|形容詞|
|auxiliary_verb|助動詞|
|slothlib|slothlib収録語|


こんな感じです。この場合はslothlib収録語のみ消去されます。

```python
    stopwordRemover.choose_parts(
        demonstrative=False,
        symbol=False,
        verb=False,
        one_character=False,
        postpositional_particle=False,
        slothlib=True,
        auxiliary_verb=False,
        adjective=False
    )
```
`test_choose_parts()`を使用しない場合はデフォルトですべての品詞の単語が消去されます。でも、`test_choose_parts()`の引数のデフォルト値はFalseなのでslothlib収録語のみ消去したい場合は`test_choose_parts(slothlib=True)`
でOKです。

# scikit-learnのパイプラインで使う場合

scikit-learnのパイプラインで使う場合は`SKStopwordRemover`クラスを利用して下しさい。

こちらも使い方はシンプルで、インスタンスを`step`に登録するだけで使えます。

```python
    sKKStopwordRemover = SKStopwordRemover()

    step = [("StopwordRemover", sKKStopwordRemover)]

    pipe = Pipeline(steps=step)

    pipe.fit(text_list)

    text_list_result = pipe.transform(text_list)
```

品詞を指定する場合はインスタンスを生成する際に引数で削除したくない品詞を一つづつ指定してください`SKStopwordRemover(one_character=False)`

※こちらはデフォルトがTrueになているのですが、slothlibにはすべての品詞が含まれているためのデフォルトがFalseになっています（ややこしくてごめんなさい）。

# 終わりに

言葉と機械学習ってすごく面白いと思うんですが、いまいち学習が進まないです・・・。

公私共にバリバリAIで文章を解析したり、生成したりしたいのですが勉強あるのみですね。
Ruby学習#14 Hashes

states = {
  "Pennsylvania" => "PA",
  "New York" => "NY",
  "Oregon" => "OR"
}
puts states
>>{"Pennsylvania" => "PA", "New York" => "NY","Oregon" => "OR"}

puts states["Oregon"]
>>OR

states = {
  :Pennsylvania => "PA",
  "New York" => "NY",
  "Oregon" => "OR"
}

puts states[:Pennsylvania]
>> PA


states = {
  1 => "PA",
  "New York" => "NY",
  "Oregon" => "OR"
}

puts states[1]
>> PA
Ruby学習#13 Arrays


Rubyの配列は、変数、数字、いろいろ混ぜ込みOK
friends = Array[1,"karen","Oscar"]

friends = Array["Kevin","karen","Oscar"]
puts friends[0]
>> "Kevin"
puts friends[-1]
>> "Oscar"
puts friends[-2]
>> "Karen"
puts friends[0,2]
>> "Kevin"
   "Karen"
puts friends[0,3]
>> "Kevin"
   "Karen"
   "Oscar"

friends = Array["Kevin","karen","Oscar"]
friends[0] = "Dwight"
puts friends[0]
>> Dwight

friends = Array.new

friends[0] 0 "Michael"
friends[5] = "Holly"

puts friends
>> "Michael"




"Holly"

friends = Array["Kevin", "karen", "Oscar"]
puts friends.length()
>>3

puts friends.include? "Karen"
>> True
puts friends.include? "Karens"
>> False
puts friends.reverse()
>> Oscar
Karen
Kevin
friends = Array["Kevin", "karen", "Oscar","Andy"]

puts friends.sort()
>>Andy
Karen
Kevin
Oscar

friends = Array["Kevin", 1, "Oscar","Andy"]

puts friends.sort()
>> error （型が違うからソートできない）
Railsアプリ　ゲストログイン機能を実装（devise不使用）

# はじめに
Webアプリのポートフォリオを作成する際、ゲストログイン機能はほぼ必須の機能かと思います。

ゲストログイン機能の記事はいくつかQiitaに挙がっていますが、現在（2020年12月）ほとんどdeviseを使ったものしかありません。
僕はdeviseを用いずにログイン機能を実装していたため、少し手こずりました。
僕のようにdeviseを用いずにポートフォリオを作っている方は参考にしてみてください！

**注意**
この記事では、ログイン機能の実装方法までは詳細に書きません。
deviseを使わないログイン機能のことを知りたい方は以下の記事を参考にしてみてください。

https://qiita.com/d0ne1s/items/7c4d2be3f53e34a9dec7

#環境
- Ruby version 2.7.2
- Rails version 6.0.3.4

#ゲストログイン機能実装
※以下sessionsコントローラーにてログイン機能を実装している前提で進みます。

**①コントローラー作成**

```java:
$ rails g controller guest_sessions_controller
```

**②routeを追加**
ゲストユーザーは削除しないため、destroyアクションは設けません。

```java:routes.rb
post 'guest_login', to: "guest_sessions#create"
```

**③createアクション作成**
パスワードはなんでも良いですが、今回はランダムに設定しました。

```java:guest_sessions_controller.rb
class GuestSessionsController < ApplicationController
  def create
    user = User.find_or_create_by(email: "guest@exapmle.com") do |user|
      user.password = SecureRandom.urlsafe_base64
      user.name = "ゲストユーザー"
    end
      session[:user_id] = user.id
      flash[:success] = "ゲストユーザーとしてログインしました"
      redirect_to root_url
  end
end
```

**④ゲストログインボタンの作成**
好きなページにゲストログインボタンを追加しましょう。
見た目は適宜変更してください。

```java:
<%= link_to "ゲストログイン", guest_login_path, method: :post %>
```
低スペックでも応用情報技術者試験に合格した話

# はじめに
令和2年度10月試験 **応用情報技術者試験**に合格しました。
![image2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467664/9f42e273-7527-c85e-8222-77dba15db585.jpeg)

応用情報への挑戦は初めてでした。
また、私自身、**IT業界歴も浅く、プログラミングが出来るわけではない**です。

こんな**低スペックな私でも**勉強法次第で確実な合格を手に入れることが出来ました。
**再現性のある勉強法**だと思うので、本記事がどこかの誰かのお役に立てればと思い、記事として残しておきます。


# 筆者のスペック

年齢　　　　：20代
業界経験　　：プログラミング未経験でSIerに入社して3年目
メイン言語　：Python
備考　　　　：勉強は苦手

こんな感じなので、応用情報は私にはハードルが高いかなと思ってました。
**（周りの諸先輩方も毎年落ちてましたし。。。）**

ただ、ネットで情報収集していく内に
「未経験でも応用情報に合格する勉強法！」
みたいな記事を見かけて愚直にその勉強法を実践したら合格しました。
**（本当にありがたいです。世の中にはすごい人がいるものですね。）**
**（正直、読むまでこの手の記事はあまり信用していませんでした。ごめんなさい。）**


# 勉強法の参考にしたもの

「応用情報技術者試験 勉強法」で検索してヒットした記事を片っ端から読んでいきました。
**これが全てです。**

中には「ほんとか...？」みたいな記事もありましたが、数を読めば共通して書かれていることが見えてきます。
その中で、一番信憑性にあるものを選べば良いと思います。

私はこの[サイト様の記事](https://shikaku-mafia.com/ap-study/)を参考にしました。
紹介されていた勉強法や書籍が私に合っていたのが、今回の合格の大きな要因だと思います。

このサイト様の他にも、参考にさせて頂いたサイト様を以下に記載しておきます。
（リンクフリーのサイト様に限定しました）

 - https://shikaku-mafia.com/ap-study/
 - https://www.gengineer.net/entry/AP_study
 - https://www.ap-siken.com/
 - https://zipanger777.com/applied-it-engineer-2863
 - https://dadlog.net/ap-study

# 応用情報技術者試験に合格した勉強法

私が実践したのは「過去問演習のみ」です。

そもそも応用情報のハードルを上げているのは、
参考書に書かれていることが難しく、内容が理解出来ないことにある気がします。

私自身も何年間前に応用情報技術者試験に挑戦しようとして、参考書で挫折した覚えがあります。

応用情報はそうではなく、過去問演習をしながら、その過程で必要な知識を習得する勉強法が最良の攻略法だと思います。

ただし、ただ闇雲に過去問を解くだけでは当然ながら合格できません。

**「正しい過去問演習」を行うことが重要です。**

「正しい過去問演習」のやり方は全て**[先ほどの記事](https://shikaku-mafia.com/ap-study/)**を参考にしました。

ここで詳しく書くと内容の転載になってしまい、良くないので控えますがざっくりと述べると
**午前試験は「反復練習」、午後試験は「解説を使用した解法理解」**に尽きると思います。

ここを押さえているかどうかで、合格率と必要な勉強時間が変わってくると思いました。


# 試験当日の雰囲気

所感としては「こんな感じかあ。。。」というもので、特に驚きや戸惑いはなかったです。

大学の一般教養授業の試験みたいで、懐かしく感じました。

ざっくりとですが、受験記も書いてました。

- [応用情報技術者試験の受験体験記](https://qiita.com/raku_taro/items/c5f2138f7a826485fff8)


# 最後に

攻略法さえ知っていれば、応用情報技術者試験の合格は十二分に現実的だと思います。

**次回試験は2021年4月です。**

私が試験勉強を開始したのがだいたい試験の3ヶ月前からだったので、
今から始めれば十分間に合うと思います。

本記事が少しでも誰かの応用情報技術者試験の合格に寄与することが出来れば幸いです。
競技プログラミングの環境をCloud Shell Editor で作成する

# はじめに
競技プログラミングを始めようとするも、環境構築がうまくいかない。
Paizaで実行するか、Atcoderのコードテストで実行して最後にコピペしていた。
https://paiza.io/ja/projects/new?language=cpp

もう少し素早くデバッグを実行したいと考え、せっかくならGCPの勉強がてら
Cloud Shell で環境構築を行ってみる。
Google Cloudのアカウントさえ作っておけば、無料で使うことができる。
始めたてで、自分のPCに色々入れたくない人にはおすすめ。
C++でコードを書いて、コードテストでは動かせる前提。

# 手順


## Cloud Shell Editor にアクセス
http://ide.cloud.google.com/?hl=ja
Google Cloud のアカウントを作っておきましょう。

## ホームディレクトリ下にディレクトリを作成
ターミナルを使ってディレクトリを作成し、作成したディレクトリを Workspaceとして使う。

```
cd ~
mkdir ディレクトリ名
```

## Workspaceを開く
Open Workspaceで作成したディレクトリを選択して開く
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390110/795201f7-5a3e-c8f5-0d5d-0fbff285671e.jpeg)


# 使い方
g++, gdb は入っているので、あとはファイルを作成して使うだけ。
test.cpp をコードを記述したファイルとすると、

```
g++ -g test.cpp
```
a.outが作成される。

実行は標準入力をコマンドラインで入力するならば

```
./a.out
```

標準入力を事前にファイルで準備しておくと(i.in)

```
./a.out < i.in
```

# やってみて
これを無料で使わせてくれるGoogleが好きになりました。
標準入力の指定をもっと簡単にしたり、もっといい環境の作り方を知っていたりする人は教えてください！
Ruby学習#12 Building a Mad Libs Game

Stringでの対話

puts "Enter a color: "
color = gets.chomp()
puts "Enter a plural noun: "
plural_noun = gets.chomp()
puts "Enter a celebrity: "
celebrity = gets.chomp()


puts ("Roses are " + color)
puts (plural_noun + "are blue")
puts ("I Love" + celebrity)

>>Enter a color:
magenta
>>Enter a plural noun:
Microwaves
>>Enter a celebrity
Tom Hanks

Roses are magenta
Microwaves are blue
I love Tom Hanks
Auto Scaling で追加したEC2 インスタンスにEIP を自動で紐づける

小ネタです。

# 困っていたこと
Auto Scaling でEC2 インスタンスが起動するたびに毎回EIPが外れてしまう。

EIP を関連づけし直す必要があるものの、手動でやるのはだるい。
なんとかしないと... :frowning2:と思い調べました。

# 解決策
Auto Scaling の起動テンプレート内のユーザーデータにスクリプトを仕込む

**▼ 詳細**
※ Auto Scaling の起動テンプレートは作成済みの前提
**1. EC2 のサイドメニューから[Auto Scaling グループ] を選択**
![Screenshot 2020-12-26 13.39.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156147/503eba2a-862a-df10-800d-e01f6367c7cc.png)
**2. 作成済みの起動テンプレートを選択**
![Screenshot 2020-12-26 13.39.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156147/c470b1bf-4ad5-6586-ebb7-14ef02e6aa09.png)
**3. [アクション] > [テンプレートを変更 (新しいバージョンを作成)] をクリック**

**4. [ユーザーデータ] にスクリプトを貼り付け、[テンプレートのバージョンを作成] をクリック**
:warning:  [高度な詳細] の項目に隠れているのでご注意ください
![Screenshot 2020-12-26 22.37.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156147/5e9397c2-a47b-b675-a294-fc88e480d67f.png)
▼ 貼り付けるスクリプト

```
#!/bin/bash

## EIPの自動割り当て処理
INSTANCE_ID=`curl http://169.254.169.254/latest/meta-data/instance-id`
REGION=`curl http://169.254.169.254/latest/dynamic/instance-identity/document | grep region | awk -F\" '{print $4}'`

for ALLOC_ID in `aws ec2 describe-addresses --region=$REGION --filter "Name=domain,Values=vpc"  --output text | grep -v eipassoc- | awk '{print $2}'`
do
  CMD="aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOC_ID --no-allow-reassociation --region=$REGION"
  $CMD
  STATUS=$?
  if [ 0 = $STATUS ] ; then
    exit 0
  fi
done
exit 1
```

たった今できたバージョンをテンプレートのデフォルトバージョンに設定しておくと、次回Auto Scaling が起動した際に適用されます。

# 余談 (なぜこれを解決したかったのか)
以下の条件を満たしたかったためです。

- 平日の定時時間内は1台起動・それ以外の時間は起動しない (費用節約のため)
- 起動したEC2 インスタンスのIP は常に固定 (EIPを関連づけた状態にする)

# 参考
- [Auto Scalingで起動したインスタンスにEIPを自動で設定する方法 | Ryuzee.com](https://www.ryuzee.com/contents/blog/7023)
[Python / DynamoDB / boto3] 試してみた操作一覧

# 概要

**なるべく行数や文字数を最小限に抑え**つつ、PythonからDynamoDBを操作する方法を網羅する（したい）記事

- 理由  
**いちいちドキュメント読みたくない**←  
**他の人の記事の中から必要な情報を毎回探し出すのも面倒**←←←（ひどい）

実際に試したものから書いていくぞ( \*˙︶˙\*)وｸﾞｯ!

# 操作一覧

```python:全操作に共通する事前準備
import boto3
from boto3.dynamodb.conditions import Attr, Key

# region_name には自分のリージョンの名前を書いてね
dynamodb = boto3.resource('dynamodb', region_name='us-east-2')
```

## 1. create_table() ... テーブル作成

```python:テーブル作成
table_name = 'hoge_table'

table = dynamodb.create_table(
    TableName = table_name,
    KeySchema = [
        {'AttributeName': 'primary_key_name', 'KeyType': 'HASH'},
        {'AttributeName': 'column_name', 'KeyType': 'RANGE'}
    ],
    AttributeDefinitions = [
        {'AttributeName': 'primary_key_name', 'AttributeType': 'N'},
        {'AttributeName': 'column_name', 'AttributeType': 'S'}
    ],
    ProvisionedThroughput = {
        'ReadCapacityUnits': 1, 'WriteCapacityUnits': 1
    }
)
table.meta.client.get_waiter('table_exists').wait(TableName=table_name)
```

- KeySchema
    - `AttributeName` でカラム名を指定  
    'primary_key_name'や'column_name'はあくまでもサンプルの名前 >_<;
    - `'KeyType': 'HASH'`で、パーティションキーになる
    - `'KeyType': 'RANGE'`で、ソートキーになる
- AttributeDefinitions
    - `'AttributeType': 'S'`で文字列型のカラムになる
    - `'AttributeType': 'N'`で数値型のカラムになる

## 2. list_tables() ... テーブル一覧取得

```python:テーブル一覧取得
# region_name には自分のリージョンの名前を書いてね
client = boto3.client('dynamodb', region_name='us-east-2')

client.list_tables()['TableNames']
```

## 3. get_item() ... 1件取得

```python:レコード1件取得
table_name = 'hoge_table'
table = dynamodb.Table(table_name)

table.get_item(
    Key={'primary_key_name': 1, 'column_name': 'string_value'}
).get('Item')
```

## 4. scan() ... 全件取得後にフィルタリング

全件取得してからAttributeでフィルタリングします
query()と比べて余分にリソースを食う（AWS利用料が余分にかかる）と言われている

```python:全件取得後にフィルタリング
table_name = 'hoge_table'
table = dynamodb.Table(table_name)

table.scan(
    FilterExpression=Attr('column_name').eq('string_value'),
    Limit=1 # 件数を指定できる。別に1件である必要はなし。
).get('Items')
```

## 5. query() ... 条件検索

条件に合致するレコードのみ取得します

```python:条件検索
table_name = 'hoge_table'
table = dynamodb.Table(table_name)

# カラム名は適当です
table.query(
    KeyConditionExpression=Key('column_name1').eq('string_value') & Key('column_name2').between(from_str, to_str)
)
```

（なんかうまいとこで改行したいけど、どうしてもLintツールに怒られてしまう...）


## 6. batch_writer() ... まとめて insert

```python
table_name = 'hoge_table'
table = dynamodb.Table(table_name)
items_source = [
    {'primary_key_name': 1, 'column_name': 'hoge1'},
    {'primary_key_name': 2, 'column_name': 'hoge2'},
           ...(略)
    {'primary_key_name': 9, 'column_name': 'hoge9'}
]

# `overwrite_by_pkeys` に指定したカラムについては、仮に重複していた場合、レコードを上書きしてくれる
# これを指定しない場合は、値が重複していた時エラーを吐いてくれる
with table.batch_writer(overwrite_by_pkeys=['primary_key_name', 'column_name']) as batch:
    for item in items_source:
        batch.put_item(Item=item)
```

# 参考にした記事
- [Boto3でDynamoDBを操作してみました](https://www.skyarch.net/blog/?p=8944)
- [DynamoDB LocalにPython(boto3)でテーブルの作成、データの登録](https://symfoware.blog.fc2.com/blog-entry-2208.html)
Ruby学習#11 Building a Calculator

puts "Enter a number: "
num1 = gets.chomp()
puts "Enter another number"
num2 = gets.chomp()

puts (num1 + num2)

>> Enter a number 
5
>> Enter another number
2
52
Stringなので、足し算にならない。解決にはto_i使う

puts "Enter a number: "
num1 = gets.chomp()
puts "Enter another number"
num2 = gets.chomp()

puts (num1.to_i + num2.to_i)

>> Enter a number 
5
>> Enter another number
2
7

>> Enter a number 
5
>> Enter another number
2.5
7

 小数点以下認識しない。解決にはto_f使う
puts (num1.to_f + num2.to_f)
>> Enter a number 
5
>> Enter another number
2.5
7.5
以下のほうがソース綺麗
puts "Enter a number: "
num1 = gets.chomp().to_f
puts "Enter another number"
num2 = gets.chomp().to_f

puts (num1 + num2)
>> Enter a number 
5.5
>> Enter another number
2.1
7.6
php.iniの保存場所の確認・編集、PHPのエラーメッセージの表示方法

##なにが起こったのか
PHPの学習を開始したが、エラー文が表示されずに困っていた。
-> php.iniを編集すれば表示されることが分かった。
-> **どこにphp.iniがあるかが分からなかった。**
-> **php.iniが読み取り専用で編集できなかった**

##実施環境
**Oracle VM VirtualBox 6.1.16
-> Ubuntu 20.04
-> Apache 2.4.41
-> PHP 7.4.3**


##php.iniの保存場所の確認方法
今回は**「phpinfo」**で確認する。
->webでphpinfoを確認する

```php:info.php
<?php
phpinfo();
?>
```

###結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883543/7654fe39-ff8c-5c94-4c64-8689778ebae7.png)

保存場所は「Configuration File(php.ini) Path」に記載されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883543/2606cce9-9766-28d4-e74a-9d9acaef1bce.png)

「**display_errors**」を確認すると「**Off**」となっておりエラーメッセージが表示されないようになっている。


##編集方法
管理者権限でファイルを開き編集する

端末を開き、php.iniが保存されているディレクトリへ移動。
->管理者権限でファイルを開く

```console
$ sudo xdg-open php.ini
```

##phpでエラーメッセージを表示させるには
「**display_errors = Off**」を探して「**Off**」を「**On**」にして保存する。
保存後、Apacheを再起動すればエラーメッセージが表示されるようになる。

###確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883543/f8272dac-6d94-043e-fa81-c4898c156d3d.png)

##あとがき
php.iniはコピーして開発用と本番用に分けて
エラーメッセージは開発用のみ表示にするのがいいみたいですね。
phpinfoもコンソール上でも確認できるみたいです。

ここちょっと違うぞ！ってところがあればご指摘お願いします..:mask:

###参考記事
https://qiita.com/ucan-lab/items/86f1498de569f4a5e16b
https://qiita.com/ritukiii/items/624eb475b85e28613a70
Ruby学習#10 Getting User Input

Atom から　Preferense 　Install　 platformio-ide-terminal

Dos窓がATMに追加される。

ruby giraffe.rb で実行

puts "Enter Your Name"
name = gets 
put ("Hello " + name)

>> Enter Your Name 
 Mike
>> Hello Mike

puts "Enter Your Name"
name = gets 
put ("Hello " + name ", you are cool!")

>> Enter Your Name
 Mike
>> Hello Mike
, you are cool!

改行されてしまう。これの回避にはchomp()

puts "Enter Your Name"
name = gets.chomp()
age = gets.chomp()
put ("Hello " + name ", you are" + age)

>> Enter Your Name
 Mike
>> Hello Mike, you are cool!
【初学者】MacからHeroku上へ環境変数を設定する方法

## はじめに
本稿は、わたし含め、環境設定が不慣れな方向けにまとめました。

## 環境変数とは？
環境変数とは、OSが提供するデータ共有機能の一つです。
**主に『コードに直接書くことが良くない』とされるデータは、環境変数として設定します。**

（例）外部APIの公開鍵・秘密鍵、master.keyなど

環境変数は、どのディレクトリ・ファイルからも参照することができ、開発環境・本番環境それぞれで設定が必要です。


## 注意点
#### １．MacのOS
今回、Catalinaでの作業になります。
OSごとに設定方法が変わるみたいなので、Catalina以外の方はごめんなさい＞＜
#### ２.開発環境と本番環境で、使うコマンドが異なります。
どちらもターミナル上で行いますが、設定で使うコマンドが異なります。
どの環境における設定なのか、確認しましょう。


## 設定方法


#### 〜 開発環境 〜

```zsh
# ターミナルで以下のコマンドを実行
% vim ~/.zshrc

# iを押してインサートモードに移行 （入力待ちの画面になる）

# デフォルトの記述は消さず、末尾に変数情報を追記　（export 環境変数='値'）
% export PAYJP_PUBLIC_KEY='pk_test_************'

# escキーを押してから:wqと入力すると、保存が完了

# 編集した.zshrcを読み込み直して、追加した環境変数を使えるようにする
% source ~/.zshrc

# コンソールで確認する
rails c

# （ENV[変数名]）を実行し、値が出てきたら設定OK
[1]pry(main)> ENV[PAYJP_PUBLIC_KEY]
=>'pk_test_************'
```

#### 〜 本番環境 〜
※ アプリ情報をHerokuへプッシュする前に設定すること！！
※ 今回は、Herokuにアプリを作成し、プッシュする前段階を想定しています。

```zsh
# ターミナルからHerokuへログイン
% heroku login --interactive

# ログイン後、以下のコマンドを実行　（heroku config:set 環境変数='値'）
% heroku config:set PAYJP_PUBLIC_KEY='pk_test_*************'

# 以下のコマンドで確認し、変数名と値が両方出てきたらOK
% heroku config
PAYJP_PUBLIC_KEY: 'pk_test_*************'
```

## おわりに
明日からポートフォリオ制作に入るにあたり、自分が不安なところをまとめました。
もし認識のズレや、記述の仕方に違和感がありましたら、ご指摘いただけますと幸いです＞＜
引き続きがんばります！
laravelの始め方(Linux)

私自身使い始めるときになかなかうまくいかなかったのでこれから始める人がつまづきにくいようにまとめておきます。
# 1. composerのインストール
composerとはPHPのライブラリを管理するためのツールで、laravelはこれを使ってインストールします。  

```

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');" 

```

2行目のコマンドを実行して”Installer corrupt"と出たら、hashキー(数字とアルフェベットの羅列の部分)が間違っている等の可能性があるので<a href="https://getcomposer.org/download/">公式</a>サイトのCommand-line installationと違っていないか確認してみましょう。 
これらが成功するとcomposer.pharとうファイルができていると思います。

```
./composer.phar --version
```

これでバージョン情報が表示されればインストールができています。ただ、このままだとcomposer.pharが置かれたディレクトリでしか実行できないのでどこからでも実行できるようにしてあげる必要があります。

```
#PHPがインストールされている場所を探す
$ dirname $(which php)
/usr/bin/php

# PHP と同じディレクトリに移動し、実行権限を与える
$ mv ./composer.phar $(dirname $(which php))/composer && chmod +x "$_"

```
これでどこからでもcomposerというコマンドで実行することができます。
# 2. laravelのインストール
下のコマンドを実行すると現在のディレクトリ配下にtestというディレクトリとともにlaravelのアプリケーション環境が構築されます。

```
composer create-project laravel/laravel test
```

### composer create-projectで出たエラーの解決法
##### unzipのエラー
![unzip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383682/de08faac-4ce7-0e9d-2142-3f9c969b14ff.png)
これが出たらunzipというパッケージが不足しているので　apt install unzip　

##### mbstringのエラー
![mbstring.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383682/221c86da-0dee-7ec9-012a-ebf79fe86ed4.png)
これが出たらunzipというパッケージが不足しているので　apt install php-mbstring　
##### php-xmlのエラー
![php-xml.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383682/9d983fc2-09b5-7b10-b53f-ad9dda0a88a5.png)
これが出たらunzipというパッケージが不足しているので　apt install php-xml


エラーがでなければ <strong>Applicaion key set successfully</strong> となりlaravelのひな型ができます。

# ３．アプリが稼働するか確認
簡易サーバー機能を使って実際にアクセスしてみて稼働しているか確認してみましょう。

```
php artisan serve
```

これで”http://127.0.0.1:8000”にアクセスしてみてこのような画面が出たら成功です。
![laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383682/f7bfb36b-6a36-6ef7-f6c4-b632e985e195.png)


もしくはIPアドレスやポートを指定するのであれば

```
php artisan --host=192.168.0.123 --port=9999
```
とします。
あれれ？なんでこのリポジトリはRuby3.0でGithub ActionsのCIが走るのに、このリポジトリはダメなんだ？

この記事の情報はすぐに古くなるかも知れません。2020年12月26日頃の情報として置いておきます。

### 背景

Ruby3.0がリリースされたので、GithubのリポジトリのCIに3.0を追加しようと作業していたところ、奇妙なことに気が付きました。WindowsでRuby3.0が走らないのは仕方がないとして、リポジトリによって、UbuntuでもRuby3.0が利用できたりできなかったりするのです。

### 答え

そもそもActionが２種類あった。

```
- uses: ruby/setup-ruby@v1
```

* https://github.com/ruby/setup-ruby

と

```
- uses: actions/setup-ruby@v1
```

* https://github.com/actions/setup-ruby

は別物でした。本当に紛らわしいですね。2020年12月26日の時点では、3.0が使えるのは前者だけでした。

前者は eregon さんや　Samuel Williams さんら、著名Ruby関係者がコミットしているやつで、後者はGithubが作っているやつでした。たぶん後者も割とすぐに3.0に対応すると思いますが、個人的には前者を使っていこうと思います。


この記事は以上です。
中学生がCMSを作る①　

以前、今回と同じようにCMSを作成しようとして挫折したことあったのですが、
U22などを経て自分も実力が上がったと思ったので再挑戦したく思い、また新たにCMSを
作ることにしたので、今後記事にしてまとめていきたいと思います。

※これと同じものを自分のブログにも投稿しています。

# Wordpresは遅すぎる
以前僕はlolipopの250円のプランや、Xfree等を利用してWordpressを用いたWebサイトを公開していたのですが、
あまりにも遅くまさにもっさりとした感じでした。
管理画面も同様でとても記事を投稿しようとは思えないほどでした。(決して三日坊主な性格だったからじゃない)
キャッシュの設定などをしても限界を感じ半年ほど埃を被った状態になり、これはダメだとサイトを閉鎖しました。

# NuxtとNetlifyとの出会い
しかし、そんな僕にも転機(？)が訪れました。つい三か月ほど前に僕はU22プログラミングコンテストの作品作成のために、VueとそのフレームワークであるNuxt、そしてそれらを公開するNetlifyに出会いました。
これまでWordpressではアクセスするたびにWebページをレンダリングして表示していたのに、なんとNuxtを使えば、
あらかじめHTMLファイルを作成して、しかもNetlifyを使えば無料でそれを公開できて感動し涙しました。
そしてノリでブログを作ったりしてもっと感動しました。　詳しくは=>https://inaridiy.tk/

全世界がSSGを使ってWebサイトを公開したらいいじゃない!!と本気で思いました。
しかし、エンジニアの方ならまだしも、全国の大半のブロガーさんたちには自分でコードを書いたりなんでできないと三日後くらいに気が付きました。

エンジニアの中ではヘッドレスCMSだのなんだの言ってますがフロントエンドのコードは自前で書かないといけないため、一般の方にはハードルが高すぎます。
やっぱりWordPressのように簡単にフロント側まで構築できたほうがいいです。

そこで誰でも簡単にSSGの恩恵を受けれる次世代(？)なCMSを作って世にこの感動をあじわってほしいとおもったのです。


# CMSについて
まずCMSを作るにあたって目標のようなものを考えました。
それがこちらです。

## 目標
WordPressのシェアを0.1%奪うこと
WordPressより動作速度が速いこと
SSGを使えること

このようにかなり高く設定しました。これを達成するためにまずWordPressの強みを改めてまとめてみました。

## WordPressの強み
1「テーマを簡単に導入できて自分好みにカスタマイズできる」これを筆頭に
2「プラグインで簡単に機能を追加できる」、
3「Dockerが配布されていたり、レンタルサーバーの機能で簡単に公開できたりと導入しやすい」
など様々な強みがあり、もうほんとすごいに尽きます。
さすが世界のサイトの40%を占めているだけはあります。

まず、3の強みについて考えてみます。

##　CMSをどんなユーザーが使うのか
さきほど書いたWordPressの強みにあった通り、WordPressは簡単に誰もが公開できる環境がそろっています。
目標を達成するにはWordPressのように誰でも簡単にサイトを作成できるようにしないといけないです。
そこで様々なユーザーに対応するためにフロント側とバックエンド側を完全に分けて実装し、
フロント側はバックエンド側からサイトのテーマとコンテンツのデータを取得して静的サイトを生成します。
バックエンド側はWordPressの管理画面のような感覚でWebサイトの管理を行えるようにします。

そしてバックエンド側はMicroCMSのようにサービスとしても提供し、ユーザーは自前のサーバーを用意してバックエンドサーバーを立てるかサービスを利用するか選べるようにします。

フロント側はNetlifyや自前のサーバーで公開してもらいます。

こんな感じでCMSを作成すればかなり使いやすくなると思います。

次に WordPressの1番の強みについて考えます。

## フロントエンドのフレームワークについて
WordPressの一番の強みはHTMLやCSSについて一切知らない人でもテーマを導入し適当にカスタマイズすれば
おしゃれでかっこいいサイトができてしまうことだと思います。

そこで僕が使えるフロントエンドの技術を使ってテーマシステムを実装する場合について考えてみます。

### Nuxt
おそらく一番よくつかわれていいるVueのフレームワークです。
これが使えれば楽なんですがコンポーネントをダウンロードしてきて使うっていうことが
できるのか怪しいです。

### Gridsome
ついさっき知ったのですがVueのSSG用のフレームワークです。
デフォルトで高速らしく、画像圧縮機能なんかもついてます。

### ejs + glup
 node.jsのテンプレートエンジンの一つであるejsをglupを使ってSSGをします。

以上の3つが今のところの候補です。
しかし、どれもまだ不透明な点が多いためいったん保留として、後日
簡易的なテーマシステムを実装してみて比較したいと思います。

バックエンドの実装はおとなしくexpressを使いたいと思っています。
遅いらしいので変えるかもしれないですが。

#　終わりに

以上で今のところ考えている簡易的な構想は終わりです。
また成果が出次第記事を投稿いたします。
M.S. Windowsでdockerを:docker(113)

Docker for Windowのインストールから利用までの(ほぼ)CUI手順
https://qiita.com/Teramonte4/items/9d18f15cb470cb3e647f

Window10に日本語対応CentOS7のdockerコンテナを作ってみた
https://qiita.com/0ashina0/items/f8b960e822a40a6a2eed

Windows 10 Home で docker動作環境を構築
https://qiita.com/yaman7/items/c27819ead4f9a0fd0225

[Docker] Docker For Windowsをセットアップしてみた (Docker初心者向け)
https://qiita.com/naonaka/items/c8d076170100ee2ea63c

はじめてのDocker～導入編
https://qiita.com/sat0tabe/items/f5681fdd03ebc4a7c418

Windows10 Home で Docker Desktop For Windowsを動かしたメモ
https://qiita.com/hibohiboo/items/f40cdb0d96cd9a15ff2b

【Docker for Windows】突然Dockerアプリが起動しなくなった、、、
https://qiita.com/Kiyo_Karl2/items/d6207db7e86e9df3c951

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
Apache 2.4におけるhttpd.confの最小構成

当記事では、Apache HTTP Serverの最小設定を追求してみた試みの結果をまとめています。調査に用いたのは2020年8月7日にリリースされたv2.4.46です。実行環境はWindows 10 Home 64bit版です。

**※2020/12/28: ServerNameディレクティブの指定と、dir_moduleモジュールの読み込みが不要であることに気づいたので、全面的に記事内容を修正しました。**





## 1. 最小構成

私が動作することを確認した――localhost:80/index.html、あるいは127.0.0.1:80/index.htmlから自作したWebページが表示されることを確認した最小構成の設定は以下の通りです。

```conf:httpd.conf
Listen 80
LoadModule authz_core_module modules/mod_authz_core.so
```

初期設定と比べると「これで本当に動くのか……？」と不安になるほど簡素ですが、これでも動きます。

ところで、この設定にしたところ、いくつか面白い挙動を発見したので以下に記載します。





## 2. サーバー起動時に警告が出る問題

この設定でサーバーを立ち上げると以下のような警告が表示されます。

```
PS C:\Apache24> .\bin\httpd.exe
AH00558: httpd.exe: Could not reliably determine the server's fully qualified domain name, using fe80::c98a:d261:60b2:36a7. Set the 'ServerName' directive globally to suppress this message
```

Google翻訳にかけたところ「ドメイン名が指定されていないようだけれど大丈夫？」というようなことを言っているようですが、動作には影響ありません。





## 3. ServerRoot問題

Apache HTTP Serverの設定項目の1つに、ServerRootディレクティブというものがあります。これは、どこのディレクトリにApache HTTP Serverが格納されているかを指定するものであり、設定ファイル内で相対パスを用いた時のルートパスにもなります。

冒頭設定のようにServerRootディレクティブを省略していると自動的にパスが指定されるようです。具体的には、Apache HTTP Serverのエントリポイントとなるhttpd.exeが配置されているドライブの直下にあるApache24というディレクトリがルートパスに指定されるようです。つまり、httpd.exeをCドライブに配置したならば、C:/Apache24がルートパスとなります。

ところで、httpd.exeが配置されたドライブが指定されるという仕様は分からなくもないですが、Apache24というディレクトリ名がどこから来たのか謎ですよね。

これは推測なのですが、Apache HTTP Server v2.4.46をダウンロードしたときの初期ディレクトリ名がApache24だったので、そこと関係しているのではないかと考えています。ですので、将来v2.5.xが出てきたら、初期ディレクトリ名はApache25になるでしょうから、そのときはルートディレクトリもApache25が使われるようになるのかもしれませんね。





## 4. DocumentRoot問題

外部に公開するWebコンテンツが格納されたディレクトリのルートパスを指定するDocumentRootディレクティブを省略した場合、ServerRoot直下のhtdocsというディレクトリがDocumentRootに指定されるようです。





## 5. DirectoryIndex問題

DirectoryIndexディレクティブが省略されている場合の挙動はちょっとややこしいです。

まず、DirectoryIndexディレクティブはApache HTTP Serverに組み込まれているディレクティブではありません。標準で同梱されているmod_dirというモジュール（Apache24/modules/mod_dir.so）内で定義されたディレクティブです。

mod_dirを読み込んでいない場合、DirectoryIndexディレクティブは機能しませんので特定のファイル（慣例的には、ドキュメントルート直下のindex.html）がリダイレクトされることはありません

ただし、同モジュールを読み込んでいるがDirectoryIndexディレクティブを指定していなかった場合は、ドキュメントルート直下のindex.htmlが自動的に返されるようになります。

冒頭に記載したhttpd.confではmod_dirを読み込んでいませんので、DirectoryIndexディレクティブは使えませんし、自動的に特定のファイル名が返されることもありません。





## 6. authz_core_moduleとは

冒頭の設定ファイルには、LisenディレクティブとLoadModuleディレクティブが1つずつ指定されています。Listenディレクティブは、v2.0.0から、指定されていないとエラーを吐くようになったので指定せざるをえないとして、LoadModuleディレクティブで読み込んでいるauthz_core_moduleとは何なのでしょうか。

結論から言うと、このモジュールはWebコンテンツへアクセスを許可したり拒否したりするための認証機能とやらを提供するようです。詳しいことは分かりませんし、完全に推測になってしまいますが、どうも、このモジュールを読み込んでいないとWebサーバー内のファイルにアクセスしても無条件に弾かれてしまうようです。

[mod_authz_core - Apache HTTP Server Version 2.4](http://httpd.apache.org/docs/current/mod/mod_authz_core.html)
【初心者】PHPで文字列を反転してみる

# 文字列を反転する
タイトル通り、文字列を反転する。
アルファベット・数字の場合で試してみる。
###アルファベットの場合
```php
$n = "abcde";
echo strrev($n);
// 以下出力結果
edcba
```
###数字の場合
```php
$n = "012345";
echo strrev($n);
// 以下出力結果
543210
```
このような結果となった。

因みに、平仮名とカタカナも試してみたが、文字化け？してしまったのかエラーだったのかわからないけれど、うまくいかなかった。
もう少ししっかり調べる必要があると思った。
しかしながら、この関数も頭の片隅に入れておいて損はないのかもしれない。
git commitくらい自動でやってほしい

gitへのコミットとgithubへのpushをやるのも手間な堕落人間のシェルスクリプト。

対象外ファイルは事前に`.gitignore`への追記をお忘れず（もし重いファイルなどが追加されてしまうとgitからの消去が非常に面倒）

```sh:autocommit.sh
today=$(date "+%Y%m%d")

cd なにかのディレクトリ
git add .
git commit -m "自動コミット_${today}"
git push hogehoge master
```



`crontab`で1日の終わりなどに、その日の作業内容をすべてコミットするようにした。

```
55 23 * * * /Users/hogehoge/autocommit.sh 1> /Users/hogehoge/cronlog/autocommit_`date +\%Y\%m\%d\%H\%M\%S`.txt 2> /Users/hogehoge/cronlog/autocommit_error`date +\%Y\%m\%d\%H\%M\%S`.txt
```
opensslを素で使う

#はじめに
色々とスクリプトがあるけど、あえて使わないでいろいろやってみる。

#RSA鍵作成

```
openssl genrsa -out <出力ファイル名> 2048
```

2048はビット長。4096とかでもできる。
これだとパスフレーズはつかないので注意。
CA局用などでパスフレーズをつけるときは -aes256を追加する。

#CSR作成

```
openssl req -new -key <鍵ファイル名> -out <出力ファイル名> -sha256
```

-sha256はデフォルトになっているので、なくてもいいはずだけど一応
これでCNとか色々入力する。
サーバ証明書に使う場合はCNをホスト名にする必要がある。

普通に使う証明書を発行するときは、ここで作ったCSRをアップロードして署名してもらったりする。


#署名

```
openssl x509 -req -in <CSRファイル名> -out <出力ファイル名> -CA <CA証明書ファイル名> -CAkey <CA鍵ファイル名> -set_serial <シリアル番号> -days <有効期間>
```

CA鍵ファイルにパスフレーズが必要な場合、入力が求められる。
今は有効期間1年以内にしないとブラウザでエラーになるかもしれない。
また、この方法ではchromeでエラーになる。これはsubjectAltNameが無いため。
subjectAltNameはテキストファイルに書いて extfileで指定する。

ファイルの内容はこんな感じ

```
subjectAltName = DNS:<ホスト名>
```

ワイルドカード証明書もこれで * を指定すると作れる。


#pkcs12

```
openssl pkcs12 -export -in <証明書ファイル名> -inkey <鍵ファイル名> -certfile <CA局証明書ファイル名> -out <出力ファイル名>
```

実行するとパスワードを2回入力して設定することになる。
クライアント証明書とかはこれにしておくとよい。（Windowsで使うときは拡張子pfxにする）

#CA局証明書
いわゆるオレオレ証明局。
CSR作る時に署名まで済ませるような形になる。

```
openssl req -new -x509 -days 3650 -key <鍵ファイル名> -sha256 -out <出力ファイル名>
```

ここで使った鍵と、これでできた証明書を署名の -CA, -CAkeyで指定するとオレオレ証明書が作れる。
IoTエキスパートを名乗れるようになった件

IoTシステム技術検定中級に合格しただけですが・・・
もしこの資格をとろうか悩んでいる方がいれば参考にしてください。

# IoTシステム技術検定とは
MCPC（モバイルコンピューティング推進コンソーシアム）がやっている認定資格のこと。
https://www.mcpc-jp.org/iotkentei/

国際資格ではないですが、日本のIoT系の資格の中ではまあまあ知名度があると思います。
ちなみに合格することで名乗れる（とMCPCが言っている）肩書きは

* 上級合格：IoTプロフェッショナル
* 中級合格：IoTエキスパート　←今回合格したのはこれ
* 基礎合格：IoTアドバイザー

となります

# 受験してみて
IoT技術を俯瞰的に語れるようなりました。
試験範囲の各パートへの所感は以下の通り。

* センサ、アクチュエータ、プロトタイプ
  * IoTデバイス側はプロトタイピングは私の本業なのでそんなに難しくはなかったです
  * WEB系の人にはちょっと大変かも、結構範囲が広い上に深いところまで問われたりします
* 無線
  * IoTエリアネットワーク側は本業に近いので実務経験もあったのですぐに頭に入りました
  * サーバー側は知らない企画や考え方が多く大変でしたが勉強になりました
* データ分析
  * 機械学習は大学の研究内容だったので基礎知識は十分あり
  * 会社でもよく扱うのでほぼ知っている内容でした
* サーバーサイド、セキュリティ、法律と標準
  * 一番勉強したかった分野
  * 内容は薄いが範囲が広いのでなかなか苦労しました

# 勉強方法
公式テキストで勉強するしかないのだが、まだ第2版なせいかテキストの完成度は低く感じる。
各章間で用語や意味が統一されていなかったり、記載の粒度も分野によってまちまちだったり、特定の技術だけを取り上げているものなどもありツッコミどころが多々ある。
IoTという分野自体更新が早いので仕方ないと思うが、テキストで取り上げている認証団体や規格がいまいち。
協賛している団体の規格がねじ込まれているのでは？と疑ってしまうようなものも。

# 受験勉強時間
もともとIoTシステムのプロトタイプなどを業務で行っているため、そこまで時間を取らなくとも大丈夫だった。
それでも2週間前から準備を初めて、仕事と家庭の事情から毎日夜中に2時間ほど、受験前日に半休をとって追い込み勉強。

# テスト難易度
私の所感は「おもったより難しい」でした。
過去問も合格率もテスト結果も何も教えてもらえないので説明が難しいですが。
自分の得意領域でも２〜３問間違えてしまったかと思います。以外に深いところも問われます。

# 合格できて
良かった！
中級を合格したので上級の受験資格を得ることができましたが、挑戦するかは考え中。
上級はペーパーテストではなく、講習＋論述なのでちょっと面倒・・・。