OmniAICreator/Qiita-1.07M huggingface dataset:
Rubyでビンゴカードを作るコードを書く

##はじめに
この記事は以下のサイトにあった問題を解いてみたものです。大変に工夫の余地があるコードになってしまいましたが、一応完成したので初心者だった頃の自分をいつか省みるために作成しました。
[アウトプットのネタに困ったらこれ！？Ruby初心者向けのプログラミング問題を集めてみた（全10問）]
(https://blog.jnito.com/entry/2019/05/03/121235)

##問題
上記サイトより引用
>1から75までの数字をランダムに配置して、ビンゴカードを作成するプログラミング問題です。
ただし、実際のビンゴカードのルールに沿って、各列は以下のような仕様で数字を出力する必要があります。

>B：1～15のどれか
I：16～30のどれか
N：31～45のどれか
G：46～60のどれか
O：61～75のどれか

[CodeIQに「ビンゴカード作成問題」を出題しました。みなさんの挑戦をお待ちしてます！](https://blog.jnito.com/entry/2015/02/09/101018)
に詳細が記されています。

##完成したコード

```ruby
class Bingo
  def self.generate_card
    array = (1..15).to_a
    b_num = array.sample(5)
    array = (16..30).to_a
    i_num = array.sample(5) 
    array = (31..45).to_a
    n_num = array.sample(5)
    array = (46..60).to_a 
    g_num = array.sample(5)
    array = (61..75).to_a 
    o_num = array.sample(5) 

    puts " B |  I |  N |  G |  O"
    5.times do |i|
      unless i == 2
        puts "#{b_num[i].to_s.rjust(2)} | #{i_num[i]} | #{n_num[i]} | #{g_num[i]} | #{o_num[i]} "  
      else
        puts "#{b_num[i].to_s.rjust(2)} | #{i_num[i]} |    | #{g_num[i]} | #{o_num[i]} "  
      end
    end
  end
end
Bingo.generate_card
```

##手順
まず、それぞれの列の数値を取得することから始めようと考えました。例えばBの列には、1~15の範囲で、違う数字をランダムに5つ選ぶ必要があります。これを、配列に対して使うsampleメソッドを利用して実現しました。

```ruby:b_num
array = (1..15).to_a
b_num = array.sample(5)
p b_num
```

実行結果
>\>ruby b_num
[7, 3, 14, 15, 10]

これを、5列分用意することで必要な数値を準備しました。(改善の余地がありそうなポイント1)

次に考えたのは、数値を1行ずつ表示することです。ここで注意するべきなのは、右詰で表示させる仕様になっていることでした。1桁の数字が出ると、Bの列の表示が崩れてしまう問題が発生しました。なので、rjustメソッドを用いてその問題を解決しています。
また、真ん中は空白にする必要があるので、それにも留意して繰り返しのメソッドを用いました。

```ruby
5.times do |i|
  unless i == 2
    puts "#{b_num[i].to_s.rjust(2)} | #{i_num[i]} | #{n_num[i]} | #{g_num[i]} | #{o_num[i]} "  
  else
    puts "#{b_num[i].to_s.rjust(2)} | #{i_num[i]} |    | #{g_num[i]} | #{o_num[i]} "  
  end
end
```

ただこの記述の仕方だと、横に非常に長くなってしまっている点が気になります。(改善の余地ポイント2)

##感想、まとめ
現状の自分のプログラミングスキルではこのコードが限界です。いつかよりすっきりとしたコードをかけるよう精進したいと強く思える結果となりました。

##参考にしたサイト
[String#rjust (Ruby 3.0.0 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/method/String/i/rjust.html)
[Array#sample (Ruby 3.0.0 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/method/Array/i/sample.html)
[Object#to_a (Ruby 3.0.0 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/method/Object/i/to_a.html)
repec 備忘録

#導入方法
```ruby:Gemfile
group :development, :test do
  gem 'rspec-rails' #追加
  gem 'capybara' #追加
#元あるやつはコメントアウトする
end
```
```:ターミナル
$ bundle install
$ rails generate rspec:install
```

```ruby:spec/spec_helper.rb
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
require 'capybara/rspec' #追記
RSpec.configure do |config|
  config.before(:each, type: :system) do #追記
    driven_by :rack_test #追記
  end #追記
.
.
.
config.include FactoryBot::Syntax::Methods 
#これを記入することでFactoryBot.create(:cake)⇒create(:cake)にできる
config.include CartItemTestHelper #（helperはここに追加）
```

#初期設定
モデル、コントローラー作成時、関係するrspecのファイルを作成

```ruby:config/application.rb
config.generators do |g|
  g.test_framework :rspec,
end
```

テスト実行画面をいい感じにする

```:.rspec
--require spec_helper
--color
--format d
```
spec/support/配下のファイルを読み込む
(コメントアウト外す)

```ruby:/spec/rails_helper.rb
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
```


#ファイル作成方法
ファクトリーボット

```:ターミナル
$ rails g factory_bot:model user
```
テストファイル

```:ターミナル
$ rails g rspec:system users
$ rails g rspec:model user
```
#実行方法

```:ターミナル
#どちらかで起動可能
$ rspec
$ bundle exec rspec
#特定の箇所のみ
$ rspec spec/system/users_spec.rb
$ rspec spec/system/users_spec.rb:2
```

#ファクトリーボット
表記方法
一意制約をもたせている場合は、email部のように表記する

```ruby:
FactoryBot.define do 
    factory :user do 
        name {"test"}
        sequence(:email) { |n| "test#{n}@example.com"}
        password {"password"}
    end 
end 
```

#モデルのテスト

```ruby
require 'rails_helper'

RSpec.describe CartItem, "モデルに関するテスト", type: :model do
  before do
    FactoryBot.create(:cake)
    FactoryBot.create(:candy)
    FactoryBot.create(:customer)
  end

  describe "実際に保存してみる" do
    it "有効な物は保存可能か？" do
      cart_item = CartItem.new(item_id: 1,customer_id: 1,amount: 2)
      expect(cart_item).to be_valid
    end

    context "空白のバリデーションチェック" do
      it "個数が空白" do
        cart_item = CartItem.new(item_id: 1,customer_id: 1,amount: "")
        expect(cart_item).to be_invalid
        expect(cart_item.errors[:amount]).to include("is not a number")
      end
      it "item_idが空白" do
        expect(FactoryBot.build(:cart_item, item_id: "")).to be_invalid
               #上記方法でもok
      end
    end
  end
end

```

#フォームの入力

```
fill_in " idやname名 ", with: 入れたい内容
fill_in "　idやname名　", with: 入れたい内容
click_button "　idやname名　"
```
例

```ruby
fill_in "customer_email", with: customer.email
fill_in "customer_password", with: customer.password
click_button "commit"
```

#helperの追加
helperの作成

```ruby:spec/support/cart_item_test_helper.rb
module CartItemTestHelper
  def item_in_cart(item, amount)
    visit item_path(item)
    fill_in "cart_item_amount", with: amount
    click_button "commit"
  end
end
```
spec_helperに追記

```ruby:spec/spec_helper.rb
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
require 'capybara/rspec' 
RSpec.configure do |config|
  config.before(:each, type: :system) do 
    driven_by :rack_test 
  end 
.
.
.
config.include FactoryBot::Syntax::Methods 
config.include CartItemTestHelper #追記
```
laravel 検索機能の実装(スコープを使用)

#はじめに
最近、AWSを使用してデプロイ中だが進まずに苦戦中です・・・。その為、中々投稿ができずAWSが気になってしまう日々が続いております。
Qiitaの記事が溜まってきたので気分転換にアウトプットをします。製作物に検索機能を実装したのでこちらを備忘録として投稿します。

#投稿者の環境
MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)
macOS Big Sur バージョン11.0.1
PHP 7.3.23
Laravel Framework 6.20.7

#条件
今回はスコープを使います。
理由は基本的なデータベースの操作を行いたい上に、毎回同じ検索条件を書くならEloquentのクエリスコープを使った方が楽だからです。
また、検索機能で使用する時にWhere句はよく使います。このWere句ですが、条件式をモデルに定義（スコープ機能）して使いまわすことができます。今後、複雑な検索機能を実装するための基本となりますので実装してみました。

#スコープを定義する
スコープを使用するには`必ず最初にscopeを名前の初めに付ける`必要があります。
また、最初の変数には`必ず$queryを使用します。`
上記の条件を纏めると以下のような書き方になります。

```sample.php
//scopeの定義 

  public function scopeNameEqual($query, $変数)
  {
    return $query->where('検索したいカラム', $変数);
  }
```

#モデルにスコープを使用
###ポイント1 use($serachword)
無名関数(クロージャー)を使用します。

###ポイント2 "%{$searchword}%"
ワイルドカード(今回は%を使用)を使って0文字以上の文字列を検索できるように組み込む。

```Post.php
 public function scopeSearch($query, $searchword){

        return $query->where(function ($query) use($searchword) {
            $query->orWhere('name', 'like', "%{$searchword}%")
                ->orWhere('subject', 'like', "%{$searchword}%")
                ->orWhere('category', 'like', "%{$searchword}%")
                ->orWhere('message', 'like', "%{$searchword}%");
        });
    }
```

#コントローラーに表示させる
Request(DI)を使用してDBに保存されているデータを表示させ、searchwordをviewファイルに渡すように記述する。

```PostsController.php
public function index(Request $request) {
        $searchword = $request->searchword;
        $posts = Post::orderBy('created_at', 'desc') //新しい順に表示
        ->Search($searchword)
        ->paginate(10);

        return view('bulletin-boards.index',['posts'=> $posts,'searchword' => $searchword]); //配列を使ってviewファイルに二つの変数を渡す。
    }
```

#検索ボックスをindexファイルに作成
検索結果を表示させるだけなのでGETにします。

```index.blade.php
    <form class="form-inline" method="GET" action="{{ route('bulletin-board.index') }}">
        <input type="text" name="searchword" value="{{$searchword}}"  class="form-control mr-sm-2" placeholder="キーワードを入力">
        <button type="submit" class="search-box btn btn-info">検索</button>
    </form>
</div>
```

#最後に
今回の検索機能は該当する箇所を全て出現させる単純な機能になります。今後はカテゴリー毎に検索できるように挑戦してみようと思います。

#参考文献
[スコープ機能について](https://laraweb.net/knowledge/2548/)
[laravel　リクエストを実行する](https://techacademy.jp/magazine/18788)
[laravel 公式](https://readouble.com/laravel/master/ja/requests.html#accessing-the-request)
[ワイルドカードとは?](https://support.microsoft.com/ja-jp/office/%E3%83%AF%E3%82%A4%E3%83%AB%E3%83%89%E3%82%AB%E3%83%BC%E3%83%89%E6%96%87%E5%AD%97%E3%81%AE%E4%BE%8B-939e153f-bd30-47e4-a763-61897c87b3f4)
[補足 正規表現とワイルドカードの違い](https://teratail.com/questions/35909#:~:text=SQL%E3%81%AELIKE%E3%81%AE%20%25%20_%20%E3%81%AE,%E3%81%A8%E5%91%BC%E3%81%B0%E3%82%8C%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E3%81%82%E3%82%8B%E3%80%82)
個人的な Nuxt.js のコンポーネントを Github Pages で公開した

先日、以下のような記事を書いた。

https://qiita.com/t-kigi/items/2a1c1a6ee46080db9d96

実際、このようなコンポーネントを開発して、動かせる場所があるといいと思ったので、Github Pages でページを作成した。 なお、公開には [gh-pages](https://www.npmjs.com/package/gh-pages) を利用した。

https://t-kigi.github.io/my-vuetify-components/

以下、記事執筆時点で記載している2コンポーネントについて簡単に説明

## OneClickButton.vue

以下の記事の内容から名前を変えただけ。

https://qiita.com/t-kigi/items/2a1c1a6ee46080db9d96


## EventMessageBoard.vue

メッセージを追加してから、一定時間後にメッセージが消えてくれるようなコンポーネント。
イベント（遅延処理やエラーなど）の完了後、これを一時的にユーザーに通達したいようなケースで利用することを想定している。

以下のような仕組みで実装した。

- 利用時に `ref` を使って、コンポーネント利用者が特定のオブジェクトを参照可能にする (あまり `ref` は使いたくなかったが...もっと良い方法があれば...)
- イベント発火時に `this.$refs.__参照名__.add(message);` のようにして通達すると、コンポーネント側で値を自動追加し、同時にTimeoutで一定時間後にメッセージを削除するイベントを追加する
- transition によってある程度アニメーション付きで消えるようにする

苦労した点としては単体テストで `setTimeout` をどう扱うかだったが、これは `jest` が `setTimeout` をテストするための仕組みを持っていたので、これをうまく使うことで解決できた。

https://jestjs.io/ja/docs/timer-mocks
Python Selenium Javascriptのポップアップをクリックする


前提：
python 3.8
Seleniumを使う
Windows10

Javascriptのアラート(ポップアップ)をクリックする必要があったのでメモ
最近のアラートはスタイルシートのものが多いですが、久しぶりにJavascriptのアラートに出会ったのでメモします。
※ちなみにスタイルシートで作成されたアラートを操作するときはCSSセレクターで。xpathやIDだとうまくいかないことおおいです。

参考サイト
[①アラートがでてくるまで待つ:alert_is_present](https://kurozumi.github.io/selenium-python/waits.html)
[②アラートを操作する](https://kurozumi.github.io/selenium-python/api.html#module-selenium.webdriver.common.alert)
↑文字入力やベーシック認証の解説もあります。


前提：

```:python：変数driverにはSeleniumのクロームドライバーがすでに設定済みとする
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.alert import Alert

wait = WebDriverWait(driver,10)
try:
   
    wait.until(EC.alert_is_present())   #Javascriptのアラートがでてくるまで待つ
    Alert(driver).accept()         #アラート受け入れる(OKを押す)        
    time.sleep(1)　　　　　　　　　　　　 #1秒まつ
   
except Exception as e:
    print("アラートの処理でエラー")
```
ただクリックするだけなら、
簡単でした。

time.sleep(1)はあまりにも早すぎると止められたり、処理でているかわからないと指摘をうけるのであえていれています。
snmptrapdのログの出力先を変更する(Ubuntu18.04LTS)

# はじめに

Ubuntu18.04LTSでは、サービスの起動/停止等の管理にsystemd が使われており、従来の

設定ファイル `/etc/default/snmptrapd` や
起動・停止スクリプト `/etc/init.d/snmptrapd` は

などは使用されなくなっています。

snmptrapdのログは、

デフォルトでは `/var/log/messages` に書き出されますが、
`/var/log/messages` には他の一般的なログも一緒に書き出されるため、

`snmptrapd` のログを管理するには不便です。

この記事は、Ubuntu18.04（systemd（systemctlコマンド等）利用時）の
`snmptrapd` のログの出力先を変更する方法を忘備録としてまとめたものです。

# snmptrapdのインストール

`apt install`コマンドで、`snmptrapd`をインストールします。

```
root@ubuntu:~# apt install snmptrapd
```

# ログファイルの出力先ディレクトリの作成

snmptrapのログファイルの出力先ディレクトリを作成しておきます。

```
root@ubuntu:~# mkdir /var/log/snmptrapd
```

# snmptrapd.serviceファイルの編集
```
root@ubuntu:~# vi /lib/systemd/system/snmptrapd.service
```

`snmptrapd.service`に、`/usr/sbin/snmptrad`起動のコマンドが記述されています。

具体的には、シェル変数`ExecStart`にsnmptrapdを起動させるコマンドが記述されています。
引数の`-Lsd`を`-Lf <出力ログファイル名>`に書き換えます。

`-Ls <FACILITY>`でsyslogのファシリティを指定し、`/etc/rsyslog.conf`で指定したファシリティの出力先を変更する方法もありますが、同じファシリティの他のログも混在するため、今回は`-Lfオプション`を使用しています。

```/lib/systemd/system/snmptrapd.service
[Unit]
Description=Simple Network Management Protocol (SNMP) Trap Daemon.
After=network.target
ConditionPathExists=/etc/snmp/snmptrapd.conf

[Service]
Environment="MIBSDIR=/usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf:/usr/share/mibs/site:/usr/share/snmp/mibs:/usr/share/mibs/iana:/usr/share/mibs/ietf:/usr/share/mibs/netsnmp"
Type=simple
#ExecStart=/usr/sbin/snmptrapd -Lsd -f                                 <--- 変更前（コメントアウト）
ExecStart=/usr/sbin/snmptrapd -Lf /var/log/snmptrapd/snmptrapd.log -f  <--- 変更後
ExecReload=/bin/kill -HUP $MAINPID

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


# 設定ファイルの再読み込み

service設定ファイルを更新したため、設定ファイルを再読み込みさせます。

```
root@ubuntu:~# systemctl daemon-reload
```

# 自動起動の設定

`systemctl`コマンドで、`snmptrapd.service` を自動起動に設定します。

```
root@ubuntu:~# systemctl enable snmptrapd
```

***STATE*** が ***enabled***に設定されたか確認します。

```
root@ubuntu:~# systemctl list-unit-files --type=service | grep snmptrapd
snmptrapd.service                          enabled
```

# snmptrapdサービスの開始

`systemctl start` コマンドで、`snmptrapd.service` を開始させます。

```
root@ubuntu:~# systemctl start snmptrapd.service
```

# snmptrapdプロセスの状態確認

サービス起動後、`-Lfオプション`が指定されている状態で`snmptrap`のプロセスが起動しているか確認します。

```
root@ubuntu:~# ps -ef | grep snmptrapd
root      19514      1  0 16:58 ?        00:00:00 /usr/sbin/snmptrapd -Lf /var/log/snmptrapd/snmptrapd.log -f
root      19523  16590  0 16:58 pts/0    00:00:00 grep --color=auto snmptrapd
```

`/var/log/snmptrapd/snmptrapd.log`を確認すると、snmptrapd開始メッセージがログに出力されている様子が解ります。

```
root@ubuntu:/var/log/snmptrapd# cat /var/log/snmptrapd/snmptrapd.log
NET-SNMP version 5.7.3
```

任意の監視対象機器で、SNMP Trapが発生する操作を行ってみてください。
`/var/log/snmptrapd/snmptrapd.log` に追記されていくはずです。
Microsoft Edgeで開かせるリンクを作る方法

## 利用想定

- IE11 などで表示された際、Edgeで開き直しをユーザーに促したい

## 方法

`microsoft-edge`というURIスキームを利用する。

https://docs.microsoft.com/ja-jp/windows/uwp/launch-resume/launch-default-app#microsoft-edge-uri-scheme

### 指定方法

URI スキーム | 結果
--- | ---
`microsoft-edge:https://example.com/` | Microsoft Edge ブラウザーでリンクを開く


```html:html
<a href="microsoft-edge:https://zozo.jp">Microsoft Edge で開く</a>
```
Ubuntu20にIE11を入れる


Internet Explorer対応の業務が発生した
wineだと上手く動かないらしいのでVirtualBoxで行く

## 環境
```
$ cat /etc/os-release                                                                                                                                                                                                                NAME="Linux Mint"
VERSION="20 (Ulyana)"
ID=linuxmint
ID_LIKE=ubuntu
PRETTY_NAME="Linux Mint 20"
VERSION_ID="20"
HOME_URL="https://www.linuxmint.com/"
SUPPORT_URL="https://forums.ubuntu.com/"
BUG_REPORT_URL="http://linuxmint-troubleshooting-guide.readthedocs.io/en/latest/"
PRIVACY_POLICY_URL="https://www.linuxmint.com/"
VERSION_CODENAME=ulyana
UBUNTU_CODENAME=focal
```

## VirtualBoxのインストール

```
$ sudo apt install virtualbox -y
```

## 仮想マシンのイメージファイルをダウンロード
以下でmicrosoft社が配っているので今回は「IE11 on Win81(x86)」を選択してダウンロード
zipファイルで降ってくるので解凍して中のovaファイルを外に出しておきます

https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/

## イメージファイルをインポート
VirtualBoxを開き、画面左上の「ファイル」>「仮想アプライアンスのインポートを選択」
ovaファイルを選択後、他の項目は特に何もいじらずインポートを実行します

## 完了

インポートが完了すると「IE11 - Win81」が出来上がっているので起動してあげるとIE11が入ったWindowsが立ち上がります。

![スクリーンショット 2021-03-25 17-15-37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92480/36a5ad7a-8779-a2f9-6ea7-9044c4e66bf4.png)
SQLによるセキュリティ攻撃の知識

#本記事について
プログラミング初心者がセキュリティ攻撃に関する知識とその対策について学んだので、その備忘録として載せております。

どうかお手柔らかにお願いいたしますm (- -)(_ _)ペコリ

##SQLインジェクション
・アプリケーションのSQLの不備を利用してデータベースシステムを不正操作する攻撃手法のこと

・外部からの入力によりアプリケーションが想定しないSQL文を実行することによって、認証を突破したり情報を盗んだりする攻撃手法のこと

・webページのテキスト入力欄やURLなどにSQL文を断片を埋め込むことで、データベースを改ざんしたり不正に情報を入手する手法。

・入力フォームから送信した値（例えばユーザー権限を変更するようなSQL文を仕込んで送信）によりアプリケーションが本来想定しないSQL文を実行させ攻撃を行う。

##SQLインジェクションの脆弱性を一般的に解消する方法
・SQLインジェクションを防ぐにはSQL文中で意味を持つ特殊文字のエスケープをしたり、プレースホルダーを用いたりすること

・SQL文が実行される際のプログラム処理の流れを利用してSQL文が変更されること

###対策①　意味のある文字列の変換
SQLにおいて意味を持つ特殊文字のエスケープ
SQL文中では「’」が文字列の終端を意味している

フォームから「’」を含む文字列が送信された場合に別の記号で置き換えるような実装をすることで実現できる。

###対策②　より厳格なSQL文の生成
ユーザーからの値をSQLへ反映する前に、SQL文の構造を確定する仕組みをとることで、より厳格に対策できる。
→SQL文確定後にユーザーからの値を入れて実行するため、ユーザーの入力値によりSQL文が変更されることはない。

##プレースホルダー
ユーザーの値が入力されるまでの一時的な仮引数のようなもの。
事前にSQLの実行範囲を確定させているので、ユーザーの入力値により、事後の変更が入ることはない。
予め確定したSQLにおいて可変の値が入力される箇所に配置する。
GrowiでAudio/Videoを埋め込む

## はじめに

Growi を使い始めたものの、音声やビデオを追加するためには一工夫が必要であることに気づきました。色々模索した中で、@Nobutoさんの[記事](https://qiita.com/Nobuto/items/adb34585d11418aec69a)を参考したことによって Growi のページに埋め込むことに成功しました。追加されたコンテンツはは問題なく再生されていたのですが、下記の問題があってすこし工夫したところを紹介したく思います。

## 問題

`iframe` を使用して埋め込んだ場合、周りに背景が大幅に残ってしまったり、Resizeがうまくいかないといった現象がありました。

## やったこと

埋め込み要素を `iframe` から HTML5 でサポートしている `audio` / `video` 要素に切り替えることで問題を解決しました。主な実装は@Nobutoさんの[記事](https://qiita.com/Nobuto/items/adb34585d11418aec69a)がベースになっています。

```js:admin-setting/customize/custom_script.js
window.onload = function() {
  // For audio player wrapper
  var audios = [].slice.call(document.getElementsByClassName('audio'));
  for (var i = 0; i < audios.length; i++) {
    var node = audios[i];

    var realAudio = document.createElement('audio');
    realAudio.setAttribute("controls", "controls");
    realAudio.setAttribute('src', node.getAttribute('src'));
    
    node.appendChild(realAudio);
  }
  
  // For video player wrapper
  var videos = [].slice.call(document.getElementsByClassName('video'));
  for (var i = 0; i < videos.length; i++) {
    var node = videos[i];

    var realVideo = document.createElement('video');
    realVideo.setAttribute("controls", "controls");
    realVideo.setAttribute('src', node.getAttribute('src'));
    
    if (node.hasAttribute('width')){
      realVideo.setAttribute('width', node.getAttribute('width'));
    }
    
    if (node.hasAttribute('height')){
      realVideo.setAttribute('height', node.getAttribute('height'));
    }
    
    node.appendChild(realVideo);
  }
};
```

```markdown:your_page.md
<div class="audio" src="[URL/Path]"></div>
<div class="video" src="[URL/Path]" width=300></div>
```

## 最後に

いつもは記事を読むばかりだったのすが、1回くらいお返しをしなければと思い投稿しました。
少しでもお役に立てているなら幸いです :bow:

## 参考
- [GrowiでYoutubeの動画を埋め込む](https://qiita.com/Nobuto/items/adb34585d11418aec69a)
- [MDN Web Docs / Audio](https://developer.mozilla.org/ja/docs/Web/HTML/Element/audio)
- [MDN Web Docs / Video](https://developer.mozilla.org/ja/docs/Web/HTML/Element/video)
Rails6 Herokuにデプロイしようとしたらエラーが多発した話

# 前提
オリジナルアプリケーションを開発した後、herokuにデプロイした際にでたエラーを備忘録としてまとめておこうと思います。

# 結論
- assetのファイルの場所が違った
- bundlerのバージョンを合わせた
- platformを変えた

# 1つ目
```Terminal
% git heroku push master
```
実行すると、、、

```Terminal
.
.
.
# 省略
Caused by:
Sass::SyntaxError: File to import not found or unreadable: tagsinput.
.
.
.
remote:  !
remote:  !     Precompiling assets failed.
remote:  !
.
.
.
```
と表示された。
tagsinput.jsが読み込まれていないとあるので、みてみるとrequire('../tagsinput')をjavastcript/packs/application.jsに記述していなかったのが原因だったっぽい。

# 2つ目
1つ目のエラーが解消したので成功すると思い、

```Terminal
% git heroku push master
```

実行すると、、、

```Terminal
.
.         # 省略
.

Bundler Output: Fetching gem metadata from https://rubygems.org/............
Your bundle is locked to mimemagic (0.3.5), but that version could not be found 
in any of the sources listed in your Gemfile. If you haven't changed sources, 
that means the author of mimemagic (0.3.5) has removed it. You'll need to update
your bundle to a version other than mimemagic (0.3.5) that hasn't been removed
in order to install.

remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !
.
.
.
```
調べてみたところ、ローカルのbundlerとherokuのbundlerを合わせないといけないらしい、、、
ということでもう一度Terminalを眺めてみると、

```Terminal
Installing bundler 2.2.11
```

と書いてある
一方ローカルの方でみてみると

```Terminal
% bundler -v
Bundler version 2.1.4
```
違っていたので、ローカルの方を合わせることにした。

手順としては、
1. 今のローカルにあるbundlerをアンインストール。
2. Herokuに合わせたbundlerのversionをインストール
3. Gemfile.lockを一度削除。
4. Gemfile.lockを再度生成。
5. HerokuへPush
とういことでまず既存のbundlerをアンインストールするため

```Terminal
% gem uninstall bundler
```
実行し、アンインストールができたら
バージョンを合わせるため、

```Terminal
% gem install bundler --version '2.2.11'
```

を実行。
インストールできたことを確認したら、Gemfile.lockを削除するため下記を実行。

```Terminal
% rm gemfile.lock
```

できたら、もう一度Gemfile.lockを生成するためバージョンを指定して下記を実行

```Terminal
% bundle _2.2.11_ install --without production
```

これでこのエラー解消できた！、、、

# 3つ目
と思いきやherokuにpushするとさらに追撃が、、、

```Terminal
.
.      # 省略
.

Bundler Output: Your bundle only supports platforms ["x86_64-darwin-20"] but your local platform      
is x86_64-linux. Add the current platform to the lockfile with `bundle lock
--add-platform x86_64-linux` and try again.

remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !
.
.
.
```

エラー文に記載された通り、

```Terminal
% bundle lock --add-platform x86_64-linux
```

実行し、コミットしてプッシュする。
再度

```Terminal
% git push heroku master
```
実行すると、やっとできた！

少しでも参考になったら幸いです。
# 参考
https://yumishin.com/heroku-push-error/
【Rails jQuery Raty】ブラウザバックすると星が増える不具合

はじめまして、プログラミングを初めて3ヶ月の初学者です。
Ratyを利用した星評価を実装中に
ブラウザバックで星評価のある画面に戻ると
星5個が星10個になるという不具合にぶつかりました。

いくら検索しても解決せず、最終的にメンターと試行錯誤して解決したので
今日は同じ目に逢ってる方と、いつかの自分の為に記録します。

ちなみに初めて書くのでお手柔らかに…

#目次
- 開発環境
- 不具合
- 何故なるのか？ 
- 結論　←ココが解決策
- 解説
- 試した方法

#開発環境
- Cloud9
- ruby '2.6.3'
- Rails 5.2.4.5
- jquery

#不具合
本来5つ星での評価をしたいのに、
ブラウザバックで評価の存在するページに戻ると
星の数が倍になる
![スクリーンショット 2021-03-25 16.16.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1194737/0be10826-082b-ee40-cf4b-45eaa2d9d116.png)

正しい表示はこう
![スクリーンショット 2021-03-25 16.16.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1194737/c6e4e3ec-43ca-7933-1f95-5ff47c8defad.png)

#何故なるのか？
不具合時のコードを見ると記載がこうなります。

```show.html.erb

<div id="star-rate-<%= @review.id %>"></div>

 <script>
  $('#star-rate-<%= @review.id %>').raty({
    size: 36,
    starOff:  '<%= asset_path('star-off.png') %>',
    starOn : '<%= asset_path('star-on.png') %>',
    starHalf: '<%= asset_path('star-half.png') %>',
    readOnly: true,
    score: <%= @review.rate %>,
  });
 </script>
```

これだと、ページを表示する度に星5つを読み込むことになるとか…
順序で見てみると

1. 星5つが読み込まれたページを表示
2. ページ移行
2. ブラウザバック
2. 星5つが読み込まれたページ　に　再度星5つ読み込む(合計10個になる)

となるのだとか…

つまり星10個の時点で他のベー時に移行し、再度ブラウザバックすると星が15個になってしまうわけです。

#結論
ページを表示する際に、一度真っさらにしてしまえばいい。
<font color='red'>先ほどのコードに1文追加するだけです</font>。


```:show.html.erb

 <script>
 $('#star-rate-<%= @review.id %>').empty(); #これを追加
  $('#star-rate-<%= @review.id %>').raty({
    size: 36,
    starOff:  '<%= asset_path('star-off.png') %>',

```

#解説
これについては私もメンターの言葉を鵜呑みにしていたので、調べてみました。
[【jQuery】要素を削除する.remove()と.empty()の違い](https://cpoint-lab.co.jp/article/201712/774/)
こちらの記事によると…

>empty(); 
こちらは指定した要素の中にある子要素を削除します。

とのことでした。

メンターの言葉を借りると

>星部分を一度削除→再度読み込む。

となるそうです。

#試した方法

ついでなので、調べて試してダメだった方法も載せておきます。

[.remove();](https://teratail.com/questions/303925)
これだと親要素（星5つを表示するブロック）ごと削除されてしまうらしく
星5つを表示すらされませんでした。

***

周りでも数人同じことで困っていたので、結構よくあるのだと思います。
この記事が役に立ちます様に。
MariaDBが起動できない

systemctl start mariadb.service

エラー出る
Job for mariadb.service failed because the control process exited with error code. See "systemctl status mariadb.service" and "journalctl -xe" for details.

/var/log/message を確認

Database MariaDB is not initialized, but the directory /var/lib/mysql is not empty, so initialization cannot be done.
の記述を見つける

/var/lib/mysql/mysql.sock
があるけど、権限を777とかにしてもダメだった

ためしに/var/lib/mysql/mysql.sockを削除したら出来た
USBVision 調査編

ハードオフでSHARPのUSBキャプチャーケーブル(RUNTKO349TAZZ)を330円で購入してきました。

黄色のコンポジットとSコネクタが出ているのでNTSCがキャプチャーできるものとおもわれます。

ハードオフでジャンクをあさる時はスマホで検索などせず、ゴーストを信じて購入を決めます。ゴーストを信じられなくなったらジャンキーは終わりです。

FreeBSDのusbconfigでみるとこんなです。

```
% sudo usbconfig -d 0.4 dump_device_desc
ugen0.4: <vendor 0x0573 product 0xc000> at usbus0, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (500mA)

  bLength = 0x0012 
  bDescriptorType = 0x0001 
  bcdUSB = 0x0100 
  bDeviceClass = 0x0000  <Probed by interface class>
  bDeviceSubClass = 0x0000 
  bDeviceProtocol = 0x0000 
  bMaxPacketSize0 = 0x0008 
  idVendor = 0x0573 
  idProduct = 0xc000 
  bcdDevice = 0x0100 
  iManufacturer = 0x0000  <no string>
  iProduct = 0x0000  <no string>
  iSerialNumber = 0x0000  <no string>
  bNumConfigurations = 0x0001 
```

古いUSBジャンクはケーブルなどのトラブルで認識できない事がありますが、このモジュールは大丈夫そうです。古いものなので消費電力が500mAと大きいです。

ネジ止めしてあり、分解できそうなので、とりあえずばらしてみました。

中にはNOGATECH USBVision(NT1003-1B)というチップと[おなじみのSAA7111](https://qiita.com/yamori813/items/e48649c660641387c977)とメモリとEPROMが実装されています。チップの刻印から1999年の製造のようです。

![USBVision.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/0fa3f4f4-921a-f3ee-419a-9bc591ee25a1.png)

NOGATECHは2000年にZoranに買収され、Zoranは2011年にCSRに買収されCSRは今はQualcomm傘下です。

NOGATECHはOMNI Visionのコンペティターだったと思われます。USBVisionはOV511と競合していますが、目にしたことがこれまでありませんでした。NOGATECHは1999年に創業して、1年足らずでZoranに買収されたためもあってか、USBVisionの生産数は多くなかったのかもしれません。NOGATECHはシリコンバレーの会社だったようです。

同時期のOV511を使ったモジュールに比べて小さく作られています。

USBVitionのLinux用のドライバーコードはここにありました。

https://sourceforge.net/projects/usbvision/

NOGATECHが開発したUSBVision II(NT1004)はZoranになってからはZR36504という製品になっていたようです。NT1004にはオーディオのキャプチャ機能もあるようです。

今は環境がないのでできませんが、macamに上記のコードをつっこんで使えるようにしたいと思います。

作戦としては、まずUSBの読み書きをできるようにして、次にI2Cの処理ができるようにして、最後にデータの読み込みを実装するようになると思います。

この製品はおそらく「ピクスラボ VR-PKU10」という商品だったのではないかと思われます。USB NTSCのキャプチャの初期の頃の製品で、この頃はホストのWindowsなどでMPEG4変換をしていました。その後[ConexantのCX23416](https://qiita.com/yamori813/items/ba488fb0bab96191ff11)のようなチップが出てきて、チップのほうで変換できるようになったのですが、NTSCの放送もなくなりチップの需要がなくなったり、会社がなくなったりで、現在Amazonなどで販売されているUSB NTSCキャプチャモジュールの多くはホストでのエンコードに戻っているように思われます。USB 2.0になり、転送帯域が大きくなったのも要因と考えられます。USB 1.0では640x480の約30フレーム16ビットでの転送できませんでした。

NT1003の後にNT1004とNT1005という製品がリリースされていて、サウンドキャプチャの機能が入っていたようです。このため微妙に仕様が変わっていて、上記のLinuxのコードはNT1003では動かないような気がします。

echoFXという会社がMacOS X用のアプリを作っていて、以前は売り物だった物がフリーになっているようです。
MAMPでLaravelを動かすための初期設定

#目次
[はじめに](#はじめに)
[データベースを用意](#データベースを用意)
[.envを編集](#.envを編集)
[session.phpを編集](#session.phpを編集)
[ターミナルでごにょごにょ](#ターミナルでごにょごにょ)

#はじめに
基本的にはMAMPのバーチャルホストを使って開発しています。
ターミナルでローカルサーバーを立ち上げる方法もありますが、MAMP派なので箇所箇所の記述がターミナルのローカルサーバーには合わない場合があります。

さて、Laravelではセッションの保存先が標準ではfileになっています。
この保存先をデータベース（ローカル含む）上に切り替えたいと思います。

#データベースを用意
何はともあれ、Laravelを導入したばかりの人はデータベースを作ってください。
作り方とデータベースへ接続するための設定はググればいくらでも情報が出てきます。
その際にいじるのは、「**/.env**」と「**/config/database.php**」の２つです。
今回は**manager**というデータベースを用意しました。
データベース名は各々に好きな名前に切り替えてください。

#.envを編集
「**/env**」を開くと、以下のコードが書かれた箇所があります。

```.env
# 13行目
SESSION_DRIVER=file
# 15行目
DB_PASSWORD=
# 18行目
DB_DATABASE=laravel
```

これを以下のように書き換えてください。

```.env
# 13行目
SESSION_DRIVER=database
# 15行目 / データベースのパスワードに書き換えてください（MAMPの場合はroot）
DB_PASSWORD=root
# 18行 / managerは各々のデータベース名に書き換えてください
DB_DATABASE=manager
```

#session.phpを編集
「**/config/session.php**」を開くと、以下のコードが書かれた箇所があります。

```session.php
'driver' => env('SESSION_DRIVER', 'file'),
```

これも.envと同じく、fileからdatabaseに書き換えてください。

```session.php
'driver' => env('SESSION_DRIVER', 'database'),
```

#ターミナルでごにょごにょ

ターミナル上でcdコマンドを使ってプロジェクトフォルダへ移動してください。
移動したら、以下のコマンドを実行してください。

```ターミナル
$ php artisan session:table
$ php artisan migrate

#===================================================
#以下のようなログが出てきたら成功です
kuroudoimac:manager kuroudo$ php artisan session:table
Migration created successfully!
kuroudoimac:manager kuroudo$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (18.75ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (20.20ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (19.77ms)
Migrating: 2021_03_25_072410_create_sessions_table
Migrated:  2021_03_25_072410_create_sessions_table (43.12ms)
```
【初学者向け】uninitialized constantエラー

# uninitialized constantエラーが起きる原因
uninitialized constant errorを直訳すると「初期化されていない定数のエラー」という意味:expressionless:
Railsでは「定数やclassが定義されていない」ことを意味:thinking:
uninitialized constantは名前が間違っているという意味のNameErrorということ:rolling_eyes:
つまり、ファイル名の記述間違いなどで、呼びたいクラス名を記述出来ていない場合などでエラーが発生します。

#実際に出たエラー
NameError in Users::RegistrationsController#create
uninitialized constant User::GenderId

#ここから考えたこと
う〜ん:thinking:User::GenderIdでエラーが発生してるみたいだから、GenderIdに関わる内容を確認してみたほうがよさそうだな。Railsでは「定数やclassが定義されていない」ことを意味する。。。ということはclass名やモデル名で定義しないといけないところをGenderIdで定義しているのでは。。。:thinking:おっ！！

#原因
```:user.rb
(省略)
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :gender_id
（省略）
```
アソシエーションを間違えていたみたいです。。。
アソシエーションはテーブル同士で関連付けておき、一方のモデルからもう一方のモデルにアクセスできるようへするためのものなので、
今回の場合だと**「GenderIdにアクセスしようとしたけどそんなものないですよ」**と伝えてくれていたみたいです。 ⬅︎ という認識であってます？？

```:user.rb
(省略)
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :gender
（省略）
```
上記のように編集したことで解決しました！！（Genderは定義されているので）
完全な凡ミスでした。。。

#参考
https://techacademy.jp/magazine/43826
Yellowfinのコードモードで適用されたフィルターの値を取得する方法


#どのような時に必要か
Yellowfinのダッシュボード構築中に、フィルターがたくさんある場合、どのフィルターの何の値で絞られた結果なのかを表示したい場合などに使えると便利だと思います。予めフィルターの状態を表示するテキストの箇所を配置してinnerHTMLで突っ込むイメージです。
[YellowfinWiki](https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=6591594#id-%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF%E3%83%BC%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88API-appliedValues%EF%BC%88%E9%81%A9%E7%94%A8%E3%81%95%E3%82%8C%E3%81%9F%E5%80%A4%EF%BC%89)に説明がありますが少し分かりづらいです。また、デフォルトの値も取得することができます。(同じページ内の記述参照)


#各フィルターの種類によって取得の仕方が変わる
これが一番わかりにくいのですが、大きく分けて「一覧に含む」、「〜の間」、「単一入力」の3種類のフィルターの絞り込む種類によって適用されている値の取得法が変わります。

##フィルターの種類が「一覧に含む」の場合(リスト・チェックボックスなど)
フィルターオブジェクトのappliedValues.valueListに値が格納されるのでこれをforやforeachで取得する。

```javascript:inList.js
let comments = this.apis.canvas.select('current_filters');
let text_detail = '';
let filters = this.apis.dashboard.filters;
let filter1 = filters.getFilter('一覧に含むフィルター');

if (filter1.appliedValues.valueList.length > 0) {
	text_detail = '<b>一覧に含むフィルター：</b>';
	for (var i = 0; i < filter1.appliedValues.valueList.length; i++) {
		text_detail = text_detail + ' ' + filter1.appliedValues.valueList[i];
	}
	text_detail = text_detail + ' ';
}
```

##フィルターの種類が「〜の間」の場合(日付や年齢など)
フィルターオブジェクトのappliedValueOneとappliedValueTwoにそれぞれの値が格納されるのでそれぞれのプロパティから取得する。

```javascript:between.js
let comments = this.apis.canvas.select('current_filters');
let text_detail = '';
let filters = this.apis.dashboard.filters;
let filter2 = filters.getFilter('〜の間フィルター');

if (filter2.appliedValues) {
	text_detail = text_detail + '<b>〜の間フィルター：</b>';
	text_detail = text_detail + ' ' + filter2.appliedValueOne + '~' + filter2.appliedValueTwo + ' ';
}
```

##フィルターの種類が「単一入力」の場合(名前など)
フィルターオブジェクトのappliedValueOneに値が格納されるのでそこから値を取得する。

```javascript:textbox.js
let comments = this.apis.canvas.select('current_filters');
let text_detail = '';
let filters = this.apis.dashboard.filters;
let filter3 = filters.getFilter('単一入力フィルター');

if (filter3.appliedValues) {
	text_detail = text_detail + '<b>単一入力フィルター：</b>';
	text_detail = text_detail + ' ' + filter3.appliedValueOne + ' ';
}
```

#値の表示について
current_filtersの名前がついたオブジェクトの文字列に取得したtext_detail変数を突っ込みます。

```javascript:innnerHTML.js
comments.innerHTML = text_detail;
```

#まとめ
複雑なフィルターを駆使している場合、ぱっと見でわかるような仕組みはすごく便利ですよね。
コードモードを使用することによってフィルターの表示の仕方も自由度が上がりましたね。
DQLでAWS DynamoDBからローカルにファイルを保存

## DynamoDB上にあるテーブルから大量のデータをエクスポートしようとすると手動ではとても大変です。

そういう時にDynamoDBを操作するツールDQLを使う便利なので、DQLを使ってダウンロードしてきたデータをファイルに保存する方法を明記します。


開発環境
OS: Mac
DQL: version 0.6.1
saml2aws: version 2.26.3

## DQLのインストール

```qiita:terminal
$ pip3 install dql
```

```qiita:terminal
dql --version
0.6.1
```

## AWSへの接続はsaml2awsを使います。
(saml2awsインストール方法は[こちら](https://qiita.com/tarumzu/items/7a20f8b414815de02b8e)を参考にしてください）

```
$ saml2aws login
```
これでAWSの自分のアカウントと接続できているので接続先のリージョンを指定します。

```
export AWS_PROFILE=saml (←自分で決めたプロファイル名)
export AWS_REGION=ap-northeast-1 (←Dynamoを設置しているリージョン)
```

環境変数の設定が終わったらDQLでDynamoにアクセスできるようになります。

```
$ dql
ap-northeast-1>
```

あとはデータをセレクトして、保存するコマンドを実行します。
("table_name"という名前のテーブルから全件検索し、"file_name.csv"というファイルでローカルに保存します。

この時、少し注意したいのがコマンドを実行した時にカレントディレクトリにファイルが保存されます。
必要に応じてディレクトリを移ってください。
`opt allow_select_scan true`はスキャンをするためのオプションなのでコマンド実行前に設定しておきます。

```
opt allow_select_scan true
SELECT * FROM table_name SAVE file_name.csv;
Saved 100000 records to file_name.csv
ap-northeast-1>
```
このように出たら完了です。

参考ページ
[saml2awsでSAML認証を用いたaws cliの利用を簡単にした](https://qiita.com/tarumzu/items/7a20f8b414815de02b8e)
プッシュ通知配信における音とステータスバーの調整方法

# プッシュ通知の重要度
プッシュ通知を送るときに、重要度を設定することで、端末が受信するときの動作が変わります。たとえば：

- ロック画面の表示
- サウンドの有無
- バイブレーションの有無

などです。

# プッシュ通知の重要度
HMSのプッシュ通知はFCMのプッシュ通知と同じく、通知メッセージとデータメッセージがあります。

### HMS通知メッセージ
API : [https://push-api.cloud.huawei.com/v2/{projectid}/messages:send](https://developer.huawei.com/consumer/jp/doc/development/HMSCore-References-V5/https-send-api-0000001050986197-V5)
APIに渡すリクエストボディの中で設定します。

例：

```json
{
    "message": {
        "android": {
            "notification": {
                "//": "importanceの選択可能な値：HIGH | NORMAL | LOW",
            	"importance": "HIGH",
                "title": "タイトル",
                "body": "本文",
                "click_action": {
                    "type": 1,
                    "intent": "#Intent;compo=com.rvr/.Activity;S.W=U;end"
                }
            }
        },
        "token": ["IQAAAACy0ZkDAACZ_VUOaDgQGI2CWnXnqyJuFO0HBhFSAMJ_e4Rxwz31DkS_MIeTskmoKdmJJlAkeAuXiVQXtnksy1unQTlBxhJsMqJiWuZVvws1zQ"]
    }
}
```

|重要度|効果|
|:---|:---|:---:|
|HIGH|音が鳴り、ステータスバーにも表示されます。|
|NORMAL|音が鳴り、ステータスバーにも表示されます。|
|LOW|音は鳴らず、ステータスバーにも表示されません。|

### HMSデータメッセージと一般的なAndroidのプッシュ通知
通知チャンネルを作成時に重要度を設定します。

```kotlin
val channel = NotificationChannel(
            CHANNEL_ID,
            CHANNEL_NAME,
            {重要度}
        )
```

|重要度|効果|パラメータ|
|:---|:---|:---:|
|緊急|音が鳴り、ヘッドアップ通知として表示されます。|NotificationManager.IMPORTANCE_HIGH|
|高|音が鳴ります。|NotificationManager.IMPORTANCE_DEFAULT|
|中|音は鳴りません。|NotificationManager.IMPORTANCE_LOW|
|低|音は鳴らず、ステータスバーにも表示されません。|NotificationManager.IMPORTANCE_MIN|

詳しくは“[HMSのプッシュ通知の受信方法とAndroidのプッシュ通知の表示方法の説明](https://qiita.com/Rei_2020/items/0aa095bb28af05b5fd16)”をご参照ください。

# 参考
* HMS：[https://developer.huawei.com/consumer/jp/](https://developer.huawei.com/consumer/jp/)
* HMS Push Kitの紹介：[https://developer.huawei.com/consumer/jp/hms/huawei-pushkit/](https://developer.huawei.com/consumer/jp/hms/huawei-pushkit/)
* HMS Push Kitのドキュメント：[https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides/service-introduction-0000001050040060](https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides/service-introduction-0000001050040060)
* Huawei Developers：[https://forums.developer.huawei.com/forumPortal/en/home](https://forums.developer.huawei.com/forumPortal/en/home)
* Facebook Huawei Developersグループ：[https://www.facebook.com/Huaweidevs/](https://www.facebook.com/Huaweidevs/)
JLCPCBにSFエクスプレスエコノミー（SF Economy Express）でPCBを発注する

2021年3月にJLCPCBへSFエクスプレス エコノミーを使用して発注した記録です。
JLCPCBは後発のPCB製造会社です。
価格は、当初のオプションが撤廃された結果、かなり安くなりました。
品質も他社よりも良いためお勧めです。
##輸送会社による送料と日数の差
DHL　3～5日
Fedex　3～5日
SFエクスプレスエコノミー 5~10日
送料はDHLとFedexで5％~1割
SFエクスプレスにした場合、Fedexより1割以上安くなるケースがあります。
##発注枚数による差
5～10枚の試作と、数十枚以上のプレ量産、量産は別工場の場合があります。
このため、配送センタへ輸送するため、さらに１〜２日余計にかかることがあります。
##配送センタ
JLCPCBはPCBの加工が終わってもすぐに発送されません
加工完了後1～2日程度止まることがあります。（上記と合わせてDHLにおいて４日止まったことがあります）
##SF Express１回目
3月3日（水）発注
3月8日（月）完成
配送センタへ輸送
3月9日（火）SFエクスプレスで発送
3月10日（水）深圳⇒香港
3月12日（金）香港⇒東京
3月13日（土）西濃運輸で到着
5日間で到着です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/182bae2d-fcb2-c321-6ab3-331bb482cc2d.png)
##SF Express２回目
3月8日（月）発注
3月14日（日）完成
配送センタへ輸送
3月15日（月）SFエクスプレスで発送
3月17日（水）深圳⇒香港
3月18日（水）香港⇒東京
3月18日（金）西濃運輸で到着も、不在で受け取れず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/39c158a8-9f44-bcef-62c4-de5ed57e84be.png)
#国内輸送
日本に入ると西濃運輸(西濃スーパーエクスプレス）にて配達されます
#関税
西濃運輸に代引きで支払う形になっていますが、金額はDHLやFedexより少し安かったです。
#総括
すごく急ぐ場合、滞留する可能性があるJLCPCBよりPCBWAY等をお勧めします。
程々早く欲しい場合は、FedexやDHLで、時間がある場合はSFエクスプレスを使用すると良いのではないでしょうか？
[IntelliJ IDEA]編集中のファイルを一瞬でProject Viewに表示させる

IntelliJ 系の IDE の小ネタです。

IntelliJ IDEA だけではなく Android Studio、RubyMine、WebStorm などでも使えます。

以下のキャプチャの赤丸で囲まれたボタンを押すと、今編集しているファイル（このキャプチャの例だと `CoroutineContext.kt`) を Project View 内で一瞬で表示してくれます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190187/ef00ba17-20f4-67a4-92e2-bc6a0a76e4e7.png" width=720>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190187/c43caa3b-78e3-f894-9a06-fb2ffb7e64e4.gif" width=720>


このボタンの動作はショートカットキーに割り当てることができます。

Mac であれば `Preferences` から `KeyMap` で `Select in Project View` に対してショートカットキーを設定すれば OK です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190187/c8e12bec-8229-08e0-1a1a-b532fef79871.png" width=720>

ちなみに私は `control + option + S` に割り当てています。

すごく便利なのでよかったら設定してみてください！
WSL の MinGW-w64 で Windows 用の実行バイナリを作成する

Windows 上で Linux を動かすのが Windows Subsystem for Linux (WSL) ですが、その上で、Linux 上で Windows 用の実行バイナリを生成できる MinGW-w64 を使ってみました。

よくある記事だと「WSL と MinGW-w64 のどちらを使うか」のような内容が書かれていますが、本記事では「WSL 上で MinGW-w64 を使用」します。

# 1. WSL で MinGW-w64 をインストール

例えば Ubuntu であれば `apt install` でインストールできます。
環境に応じたパッケージ管理システムを使用してください。

ここでは簡単のために 64bit 版の `g++` とその依存パッケージのみインストールします (状況に応じて必要なパッケージをインストールしてください) 。

`x86-64` が 64bit 用で `i686` が 32bit 用です。

```bash
sudo apt install g++-mingw-w64-x86-64
```

# 2. 依存ライブラリを静的リンクする (状況に応じて)

実行ファイルを複数含むようなソフトウェアを公開する場合には、DLL を付属した方が合計の容量を小さくできると思いますが、単一の実行ファイルの場合は静的リンクした方が単純にファイル数を少なくできます。

まず、`libgcc` は (おそらく) 絶対必要になります。また、状況に応じて他のライブラリも必要になります。

```bash:一度コンパイルして、依存ライブラリを調べる
x86_64-w64-mingw32-g++ -o main.exe main.cpp
x86_64-w64-mingw32-objdump -p main.exe | grep 'DLL Name'
```

```text:出力の例
        DLL Name: KERNEL32.dll
        DLL Name: msvcrt.dll
        DLL Name: libstdc++-6.dll
```

(※ `libgcc` はこの方法では確認できない？)

`KERNEL32.dll` と `msvcrt.dll` は Windows に標準で含まれる DLL のため、ここでは `libgcc` と `libstdc++` を静的リンクすることにします。

```bash:依存ライブラリを静的リンクしてコンパイル
x86_64-w64-mingw32-g++ -static-libgcc -static-libstdc++ -o main.exe main.cpp
```

これで、DLL を付属しなくてもエラーが出ずに実行できる Windows 用の実行バイナリを生成できます。

# 3. おまけ: WSL 上でも Windows 用の実行バイナリを実行できる

拡張子 `.exe` を付けることで、WSL 上でも exe ファイルを**実行できます**。

自身で作成したアプリケーションに限らず、Windows 用の CUI アプリケーションを実行して、そこから Linux のコマンドで `grep` するといった使い方ができ、便利です。

CUI アプリケーションを作成する場合は、そのまま WSL 上で動作確認を行うことができます。

※文字コードが合わず文字化けする場合は `nkf` コマンド等で対処してください。
※システムの情報にアクセスする必要があるなど、高度なことをする場合には WSL 上で動作しないことがあります。

# 4. その他注意点

## 4.1. ソースコードの文字コードが Shift_JIS (CP932) 以外の場合

ソースコードの文字コードが CP932 以外の場合、実行時に、GUI のテキスト等で日本語等が文字化けするので、コマンドラインオプションで文字コードを指定します。

```bash:g++&nbsp;で&nbsp;UTF-8&nbsp;のソースコードを使用する例
x86_64-w64-mingw32-g++ -finput-charset=UTF-8 -fexec-charset=CP932 \
	-static-libgcc -static-libstdc++ -o main.exe main.cpp
```

`g++` では `-finput-charset=UTF-8 -fexec-charset=CP932` のように指定できます。

## 4.2. MinGW-w64 で `wmain` や `wWinMain` を使いたい場合

MinGW-w64 では、`g++` のコマンドライン引数で `-municode` を指定することで、`wmain` や `wWinMain` を使用することができます。

※無印の MinGW では (おそらく) `-municode` を使用できないので注意。

また、マルイバイト文字列のコマンドライン引数は、`GetCommandLineW()` 関数と `CommandLineToArgvW()` 関数を使って便利に取得することができます。

## 4.3. MinGW-w64 の `std::wcout` で日本語等の文字列が出力されない問題

`#include <fcntl.h>` して `_setmode(fileno(stdout), _O_U8TEXT);` すると出力できます (コンパイルオプションにより異なる？) 。

MinGW-w64 では `std::basic_ios::imbue()` や `std::locale()` で対処できないようです…。

```c++:MinGW-w64&nbsp;で&nbsp;std&#058;&#058;wcout&nbsp;を使用する例
#include <iostream>
#include <fcntl.h>

int wmain() {

	_setmode(fileno(stdout), _O_U8TEXT);

	std::wcout << L"にゃ" << std::endl;

	return 0;

}
```

参考「[_setmode | Microsoft Docs](https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode?view=msvc-160)」
Dockerでgemを追加しbundle installでエラーになる

#エラーの状況

gemを追加後、反映させるため以下のコマンドを実行したがエラーになる

```:ターミナル
$ docker-compose exec web bundle install
ERROR: No container found for web_1
```

#原因
前回の時はdocker-compose run webの使い方だったが、docker-compose execをあまりわからず使っていたのが原因

run：コンテナ起動してコマンド実行
exec：起動中のコンテナでコマンド実行　<= 重要！

なのでexecで実行する場合は予めdocker-compose upなりでコンテナ起動させてないと使えないとのこと

エラーは勉強になるな、解決しないと焦るけど笑
いうてまだまだ表面の理解だけなので手を動かして覚える

#参考にさせていただいたURL
https://qiita.com/Nishi53454367/items/9ca85eede43e492c7cd4
boto3でCloudSearch検索ドメインに複合クエリを実行する

https://docs.aws.amazon.com/ja_jp/cloudsearch/latest/developerguide/searching-compound-queries.html

↑をboto3でやってみました。

```python:cloudsearchdomain.py
import boto3

endpoint_url = 'https://search-todofuken-XXXXXXXXXXXXXXXXXXXXXXXXX.ap-northeast-1.cloudsearch.amazonaws.com'

cloudsearchdomain = boto3.client(
    'cloudsearchdomain', endpoint_url=endpoint_url)

query = """
(and 
  prefecture:'{prefecture}'
  city:'{city}'
  (range
    field=zip [{from_zip}, {to_zip}]
  )
)
""".format(prefecture='宮城県', city='仙台市', from_zip=9830000, to_zip=9830100)

returnFields = [
    'city',
    'kana_town',
]

results = cloudsearchdomain.search(
                query=query,
                queryParser='structured',
                returnFields=','.join(returnFields),
                size=3)

print('found:%d' % results["hits"]["found"])
print('count:%d' % len(results["hits"]["hit"]))

for item in results["hits"]["hit"]:
    print(item["fields"])
```

```bash
$ python cloudsearchdomain.py
found:34
count:3
{'city': ['仙台市宮城野区'], 'kana_town': ['タゴ']}
{'city': ['仙台市宮城野区'], 'kana_town': ['タゴニシ']}
{'city': ['仙台市宮城野区'], 'kana_town': ['ツルマキ']}
```

CloudSearchのboto3のサンプルコードあんまり転がってないので参考になれば。
AWSでアプリをデプロイする方法(データベース作成編)

# EC2の初期設定後本番環境でデータベースを作成する手順を紹介します（学習記録）:fountain:

ここでは、MySQLから派生した「MariaDB」というデータベースを利用します。Amazon Linux 2を利用している場合、MariaDBは 「yumコマンド」からインストールできます。

```
# EC2内で実行
[ec2-user@<自身のElasiticIP> ~]$ sudo yum -y install mysql56-server mysql56-devel mysql56 mariadb-server mysql-devel
```
#### データベースの起動
・systemctlコマンド
systemctlコマンドは、Amazon LinuxやCentOSに含まれているもので、インストールしたソフトウェアの起動を一括して行えるツールです。

```
# データベースを起動
[ec2-user@<自身のElasiticIP> ~]$ sudo systemctl start mariadb

# 確認
[ec2-user@<自身のElasiticIP> ~]$ sudo systemctl status mariadb

# 「active (running) 」と緑色の表示がされれば、データベースの起動は成功です。
```

#### データベースのrootパスワードの設定
yumでインストールしたMariaDBには、デフォルトで「root」というユーザーでアクセスできるようになっていますが、パスワードは設定されていません。なので、パスワードを設定する必要があります。

```
[ec2-user@<自身のElasticIP> ~]$ sudo /usr/bin/mysql_secure_installation
# その後以下のステップを踏む
1.Enter current password for root (enter for none): 」と表示されたらEnterキーを押す
2.「Set root password? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す
3.「New password:」と表示されたら自身で決めたパスワードを入力（※とくに画面には何も表示されませんが入力できています）
4.「Re-enter new password:」と表示されたら、同じパスワードを入力（とくに画面には何も表示されませんが入力できています）
5.「Remove anonymous users? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す
6.「Disallow root login remotely? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す
7.「Remove test database and access to it? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す
8.「Reload privilege tables now? [Y/n]」と表示されたら「Y」を入力してEnterキーを押す

# データベースへの接続を確認
[ec2-user@<自身のElasticIP> ~]$ mysql -u root -p

# 「Enter password:」とパスワードを入力するように表示されるので、さきほど設定したパスワードを入力して、Enterキーを押してください
# 「exit」と入力すれば抜け出すことができます。
```
以上が本番環境でデータベースを作成する手順になります！参考までにどうぞ！
Salesforceカスタムボタンからフローを呼ぶときの設定

まずフローをつくる
例：Calculate_Discounts

①フローの「詳細とバージョンの表示」から、URLをコピーする
　/flow/Calculate_Discounts?
　
②オブジェクトの「ボタン、リンク、およびアクション」から、新規ボタンまたは新規リンクを選ぶ
　コピーしたURLの末尾にフローに渡したい情報を追加する
　例）/flow/Calculate_Discounts?AccountId={!Opportunity.AccountId}&OpportunityId={!Opportunity.Id}

③レイアウトに配置する

参考：
「割引計算機能の構築 > カスタムボタンでフロー配布」
https://trailhead.salesforce.com/ja/content/learn/projects/flow_calculate/flow_calculate_implement
signate:日本取引所グループ ニュース分析チャレンジ②

今回は、公開されているsignateチュートリアルの2章の部分を描いていきたいと思います。

こちらのチュートリアルでは、「ファンダメンタルズ分析チャレンジ」に関するものです。

#コンペ概要

ここら辺は、チュートリアルに詳しく書いているので、詳しくはチュートリアルを見てください。要約すると、株式市場をデータ分析したい人が最初の足掛かりとして取り組むのに良いプログラムです。

うんうん。データ分析以外の株式市場の知識も得られそうで一石二鳥になりそうですね。

それでは始めます。

#2.1章
株式情報の使用用途や本コンペにおける評価指標が示されています。

評価指標は、難しかったので随時理解次第こちらの記事を訂正したいと思います。

#2.2章
開示されているデータファイルについて、まとめられている。

###stock_list
銘柄の名前や業種区分などの基本情報をメインに書かれている。
例えば、銘柄の業種区分や発行済株式数等々が書かれている

###stock_price
各銘柄の各日付毎の始値や終値などの株価情報が記録。

###stock_fin
株式投資における、ファンダメンタル情報について記載。
ファンダメンタル情報とは、純資産に関する財務情報や当期純利益といった業績状況を表す情報です。
これは、本コンペ関係なく、今後の企業の成長性や安全性、収益性等の判断材料になることから、より重要度が高い情報を持っていることがわかると思います。

※お金に関する勉強を今後始めようと思うので、別記事、もしくはnoteでこれらの詳細の情報は開示していきたいなと思います。

###stock_fin_price
上記二つのデータをjoinしたもの

###stock_labels
予測対象に関するデータ

#2.3章　実行環境・ライブラリー

これはチュートリアル通りです。
colabが一番手軽かなって思います。

#2.4章　データセットの読み込み

ここからの章は、プログラミングを使って、データを扱うといったことをやっています。
私の記事としては、コードの概要というより、それぞれの章での用語の説明ややっていることを説明したいなっと思います。

この章は、単にデータを読み込んでいるだけです。

#2.5章　データセットの可視化

使用しているモジュールは、matplotlibとseabornです。
可視化ツールとして、めっちゃ王道のものを使用していますね。

2.5.1では、財務諸表のデータを読み込み可視化しています。
これらをすることで、各銘柄の財務状況や特徴を分析することが容易になります。

その後は、複数銘柄の比較をgroupbyを使用して行ったり、numpy等のモジュールを使って移動平均や価格変化率を元絵mグラフでプロットしています。

この章での一番難しい点は、「ヒストリカル・ボラティリティ」だと考えてます。

これは、あるサイトによると

「オプション取引で用いられる用語で、株式、為替、債券、コモディティなどの原資産価格の過去一定期間の値動きデータに基づいて算出した将来の変動率（ボラティリティー）。
「歴史的変動率」とも呼ばれ、英語表記「historical volatility」の略で「ＨＶ」ということもあります。統計学の標準偏差を利用して、ある一定期間のボラティリティを年率換算したものです。過去にその原資産の価格がどの程度変動したかを示す指標で、ヒストリカルボラティリティーが高いほど価格変動リスク高く（安全性が低い）、低いほど価格変動リスクが低い（安全性が高い）といえます。」（※引用「https://www.daiwa.jp/glossary/YST2343.html」）

要するに、原資産の価格変動を表したもので、安全性を判断する指標として活用されているようです。これは、めちゃめちゃ大切そうな特徴量ですね。
これに関しても、numpy.rolling等を使用して計算してます。

#2.6章　データセットの前処理

前処理はめっちゃ大事ですよね。
①欠損値処理
②正規化
③特徴量生成
④バリデーション戦略
⑤モデル構築

ざっくりした流れです。

じゃあ、本コンペにおける前処理を見ていきましょう！！

①欠損値処理は方法として、
・平均値埋め
・リストワイズほう
・多重代入法
いろいろあります

今回は、0を入れることで対処しています、ただし、欠損値としての0の意味合いを込めた欠損値処理をしているのでご注意を

#2.7章　特徴量生成
②を超えて、③にきましたね

②は今回は木構造の機械学習モデルを用いるので必要ないと判断し記述していないのでしょう。
ただ、NN等のモデルを使用する場合は必要なのでご注意ください

③特徴量生成
これの重要な点はここにあります。
「ドメイン知識や専門性を活かして特徴量を設計する」といったことにあります。
そのため、対象モデルについて詳しく知識を保有し、細かい部分の影響を考えることでより、予測精度を高めるといった点で重要になります。

しかし、end-to-end学習の方法もあります。これは、どんな人でも活用できるように生のデータのまま学習させ、データ間の関係性を見つける手法もあるので、この場合そこまで生成をする必要はありません。

今回は前者の方法を採用し、金融知識を高めながらデータ分析をしていく手法をとっていくそうです。

その上での最重要な点は、
「仮説を立て、仮説を遂行するために必要な特徴量を考える」である。

今回は金融の領域で重要な判断材料となる、ボラリティリティや移動平均を元に特徴量生成をしています。

#2.8章
④バリデーション戦略

これは、学習させてモデルの汎化性能を上げるために行なっている作業です。
過学習を防ぐためにやっています。

#2.9章　モデルの構築

モデルは木構造をチョイスしてますね。
それに加えて、一つの銘柄に対して、一つのモデルを構築するように学習しています。

#2.10章　モデルの推論

バリデーションしたものに関して、推論し、精度の確認や予測結果の可視化をしています。

#2.11章

モデルの予測に寄与した特徴量の分析

#2.12章　モデルの評価

個人的にはこの章が一番大事だと思う。
なぜならば、全ての取り組みの結果を評価するのがこの章だからだ。

その上で評価している内容は、
RMSE: 2乗平均平方根　-> 予測値と実際の値の差
accuracy: 目的変数の符号と予測した目的変数の符号の精度 
spearmanc_corr: スペアマンの順位相関 -> 絶対値が大きいほど、相関関係は高い
corr: ピアソンの相関係数 -> 正の相関があるか負の相関があるか
R^2score：　単回帰した時のばらつき 

これにより、どのモデルにどのデータセットを適応させるのがいいのか評価し、判断していきましょう！

#終わりに
今回は2章をざっくりと説明しました。

次回以降は３章等々を紹介していきたいなと思います。
cartopy世界地図上にデータプロットできない！

## グローバルマップ上に気象データをプロットしたいのになんか違う...
![cartopy_fail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/811209/6567bcd0-6b86-4902-dc92-4296c22a7a75.png)

* 世界地図と降水データのサイズあべこべ...
* なぜか世界地図がさかさま...
* 横軸・縦軸があらぬ方向に...

####**とにかくcartopyで苦戦したので，その解決法を載せときます**

## 答えからいうと"plt.imshow(extent)"を使おう
お急ぎの方は，googleで'plt imshow extent'と検索すると幸せになれると思います．
 
```python

from netCDF4 import Dataset
import matplotlib.pyplot as plt
import cartopy.crs as ccrs

#降水データを読み込んでます．
ds = Dataset(path,'r').variables['prec'][0][0][0][:][:]

img_extent = (-180.5,180.5,-91.0,91.0)

fig = plt.figure(figsize=(10,10))
proj = ccrs.PlateCarree(central_longitude = 180)
ax = fig.add_subplot(1,1,1, projection=proj)
tp = ax.imshow(ds, origin='lower', extent=img_extent, transform=proj)
ax.set_global()
ax.coastlines()
plt.show()
```

ポイントになるのはplt.imshowのAPIに含まれるextentとoriginの機能．
extentはタプルを与えると(left,right,bottom,top)の順で表示する範囲を指定できる．
originは数値を'lower'か'upper'の２種類が選べ，数値をどちらから詰めるかを指定できる．

今回のデータはds.shape = [181,360]の形をもっていたので，試行錯誤的にimg_extentを調整してます．

![origin&extent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/811209/41309064-aee0-6534-6470-93462f472bcc.png)
#3 午後試験で必要な基礎知識は午前Ⅱでは身に付かない？

この記事はシリーズものです。トップはこちらから。

 - [ネットワークスペシャリスト試験を受けることにしました【令和3年春季】](https://qiita.com/foxtail1979/items/5e333d28f2e93acb552b)

# 基本が大事
ネットワークスペシャリスト試験では午後試験対策がすべてといっても過言ではないと思います。また、午後試験で応用的な問題を解くためには基礎知識が重要ということも共感してもらえると思います。

問題は、そういった基礎知識はどうやって習得するのが良いのかということです。
僕はCCNAを取得していますが、一年前なので若干記憶が怪しい状態です。くわえて一通り午前Ⅱ試験に取り組んで基礎固めをしたつもりでしがた、いざ午後試験に取り組むとおもいのほか基礎知識での取りこぼしが多いなという印象です。

今更こんな感じで大丈夫かなあという印象はぬぐえませんが、受験すると決めてしまった以上やるしかないので、引きつづき頑張ります。

## H30(2018午後Ⅰ　問1)
 - HTTPのCONNECTメソッドはプロキシサーバにトンネリング処理を要求するのに使われる（要はプロキシ宛てHTTPS通信）
 - プロキシサーバをセキュリティ強化の観点で使用するときは、ログの取得に注目されがち。利用者認証を行うことで、誰が外部の何にアクセスしようとしたか。


## H30(2018午後Ⅰ　問2)
 - SYSLOGはUDP
 - SNMP Trapは再送（到達確認）を行わない
 - VRRPの生存情報交換はVRRPアドバタイズメント
  - 代表的な伝達情報は、VRRPグループID,プライオリティ値
 - VRRPのマスタルータ選出は、プライオリティが高い順

## H29(2019午後Ⅰ　問1)
 - SSL/TLSは実質、TLS1.2以上が推奨。MD5とSHA-1は非推奨
  - TLS1.3ではプリマスタシークレットのサーバ証明書による暗号化がなくなっている
 - Server_Helloは鍵交換と認証の暗号アルゴリズムを含む

## H29(2017午後Ⅰ　問3)
 - GRE over IPSecのメリットは暗号化＋マルチキャスト通信
 - OSPFのリンクステート情報交換はマルチキャストで行われる
 - MPLS
 - OSPFで代表ルータに選出されないようにするにはプライオリティ値を0に設定する

## H28(2016午後Ⅰ　問1)
 - SMTPの認証機能はSMTP-AUTH
 - SMTPプロトコルで送信元のアドレスを取得するのはMAIL FROMコマンド

## H28(2016午後Ⅰ　問2)
 - 無線APはビーコンと呼ばれる信号でSSIDを通知する
  - SSIDステルス機能を用いても、SSIDの通知を積極的に行わなくなるだけであって、隠蔽は不可能。プローブ信号を受信するとSSIDを通知するため。 
 - SSIDとMACアドレスは暗号化されない。MACアドレスは無線LANフレームから傍受できる。
 
## H28(2016午後Ⅰ　問3)
 - 初見情報は特になし

## H27(2015午後Ⅰ　問1)
 - ループバックアドレスはARP要求に応答するため、異なるセグメントのIPアドレスであっても設定しておけば受信ができる。DSR方式で負荷分散する際は常套手段のようです。
  - https://infraya.work/exam/nesupe_loopback/

## H27(2015午後Ⅰ　問2)
 - 初見情報は特になし

## H27(2015午後Ⅰ　問3)
 - 初見情報は特になし

## H26(2014午後Ⅰ　問2)
 - FWのステートフルフェールオーバ機能は管理情報を引き継ぐ
 - ポート状態LEDは電気的な接続ができていると点灯する。つまり物理層の障害有無の確認ができる。
  - データリンク層状態は、LEDでは判断できない。管理コンソールからログインして確認が必要かな。

## H26(2014午後Ⅰ　問3)
 - DNS再帰問い合わせは、クライアントから見たとき、最終的な名前解決をしてくれる。
 - DNS非再帰問い合わせは、クライアントが問い合わせたDNSサーバが持っている情報しか返してくれない。
 - DNS反復問い合わせは、再帰問い合わせを受け付ける設定になっているDNSサーバが、上位のDNSサーバへ順繰りに名前解決を問い合わせること。

## H25(2013午後Ⅰ　問1)
 - ループバックアドレスは127.0.0.1〜127.255.255.254を利用可能
 - ループバックアドレスを定義すると、ローカル宛て通信をリモート通信っぽく見せられる
 - SSL-VPNのポートフォワード方式はポート番号が変化しないアプリケーションに限られる
 
## H22(2010午後Ⅰ　問1)
 - TCPコネクションの確立は、クライアント側から見るとSYN+ACKが返ってきた時点でESTABLISHEDとなる
   - https://qiita.com/tatsuya4150/items/ae4d5e95e43ce0670bc0

## H22(2010午後Ⅰ　問3)
 - IDSの稼働方式　ネットワーク型とホスト型