OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】flashメッセージをフェードアウトで消す方法【JavaScript】

#はじめに
この記事では、flashメッセージを表示したあと一定時間後にフェードアウトさせる方法を解説します。

flashメッセージ系の記事はたくさんあるのですが、
どれも`bootstrap`を使用してたり
何やら複雑な方法だったり（Hamlハムル？？とかrenderとかややこしい！）。。

もっと簡単な記事はないのか！とモヤモヤしたので、自分まとめます。
自分と同じような人の為に！！（自分用のメモですすみませんｗ）


#flashメッセージの表示方法
それではレッツ実装！！

まずはコントローラーから。
#コントローラー

```ruby

def destroy
   @review = Review.find(params[:id])
   @review.destroy
   if review.destroy
      redirect_to root_path, notice: "︎レビューを削除しました！"
   end
end

```

メッセージを表示させる記述は4行目の`if`文からです。

レビューが削除された後、`root_path`(ホーム画面)に戻って
「レビューを削除しました」というメッセージが表示される。という流れです。


続いてビュー画面へ！
#ビュー

```erb

<% if flash[:notice] %>
   <div class="flash"><%= flash[:notice] %></div>
<% end %>

<%= yield %>
```
flashメッセージはいろんな場面で共通で使う事が多いので、
views/layouts/application.html.erb
の`<%= yield %>`より上の部分に記述します。

コントローラーとビューはひとまず完成！！

#JavaScriptの下準備
まずは`Gemfile`以下のコードを記述します。

```
gem 'jquery-rails'
```

からのターミナルで`$ bundle install`

続いて
app/assets/javascripts/application.js
に以下のコードを加えましょう。

```
//= require jquery
```

これで`jQuery`の下準備完了。

#flashメッセージをフェードアウトさせる方法

いよいよ実装していきます。

#①jsファイルに記述する場合(推奨)

以下のコードを
app/assets/javascripts/application.js(上と同じ場所)
に加えたら完成！！

```javascript

$(function(){
  setTimeout("$('.flash').fadeOut('slow')", 2000);
});
```

#②ビューファイルに直接記述する場合

以下のコードを
flashメッセージを表示させたいビューファイルに加えたら完成！！

```erb

<script>
  $(function() {
    setTimeout("$('.flash').fadeOut('slow')", 2000);
  });
</script>
```

※「.flash」はapplicaton.html.erbのdivに付けたクラス名です。各自自由に命名しましょう。
※数字部分は好みに合わせて変えましょう！ちなみに1000で1秒です。


#さいごに

今回はレビューの削除`destroy`後の実装でしたが、もちろん編集`edit`や
お気に入り`favorite`なんかも実装可能です。

あとはお好みで`CSS`をいじれば、
よく見るflashメッセージの完成です！！


＜参考＞
https://qiita.com/dir_sh0606/items/b2165459deda97ae8468
dockerのPHPでxdebugを使ってみる

# 概要
xdebugをdocker環境で使えるようにしたかったので調べてみた。

## Dockerを準備する
作ったコードは、下記githubにまとめているので大雑把に書きます。
※ Github: https://github.com/reflet/php5.6-xdebug

```Dockerfile:docker/httpd/Dockerfile
FROM php:5.6-apache

# install xdebug
RUN pecl install xdebug-2.5.5 && docker-php-ext-enable xdebug

# update php.ini
COPY ./php.ini /usr/local/etc/php/php.ini

WORKDIR /var/www/html
```
## php.iniの設定
下記の設定を追加する。

```ini:docker/httpd/php.ini
[xdebug]
xdebug.idekey="PHPStorm"
xdebug.remote_host = "docker.for.mac.host.internal"
xdebug.default_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_connect_back = 0
xdebug.remote_enable = 1
xdebug.remote_handler = "dbgp"
xdebug.remote_port = 9000
```

## docker-compose.yml
dockerの構成を記述します。

```yaml:docker-compose.yml
version: "3.7"
services:
   httpd:
     container_name: httpd
     image: httpd:development
     build:
       context: ./docker/httpd
       dockerfile: Dockerfile
     ports:
       - "80:80"
     volumes:
       - ./src:/var/www
```

## サーバ起動
下記コマンドでサーバを起動します。

```bash:ターミナル
$ docker-compose build
$ docker-compose up -d
```

## IDE設定 (IntelliJ)
お使いのIDEで9000番ポートを指定する。

- **Preferences > Languages & Frameworks > PHP > Debug**
![debug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/00b8312c-13fb-bb54-1803-9320a69a9e10.png)

- **Preferences > Languages & Frameworks > PHP > Servers**
![server.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/d33f84e3-e113-349e-d323-20c932658825.png)

- **edit-configurationsボタン**
![edit-configurations.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/cbb874e2-c489-d49f-03ef-a8224a802d7d.png)

- **configurations設定**
![configurations.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/a688808d-c415-7773-7aaf-3f58d7b9f3a6.png)

- **実行してみる**
![run.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142279/f5499243-1db0-df83-9c70-a9dff2420797.png)

以上

# 参考サイト
- [Debug your PHP in Docker with Intellij/PHPStorm and Xdebug](https://gist.github.com/chadrien/c90927ec2d160ffea9c4)
- [Dockerで構築したPHP環境をxdebugでデバッグ（vscode）](https://qiita.com/gigosa/items/90431be7a6a79db78480)
- [PHP5.6のデバックをするために必要なxdebug-php56がbrewでインストールできない](https://teratail.com/questions/122804)
- [PhpStorm + Xdebugでリモートデバッグする方法](https://www.tam-tam.co.jp/tipsnote/program/post13770.html)
- [PhpStorm + Xdebug でリモートデバッグ](https://qiita.com/kojionilk/items/5cff97ece056fd3c469f)
jQuery.ajaxのtimeoutはユーザーの入力時間を含む


# 現象
jQuery.ajaxにtimeoutオプションをつけたときは、Basic認証のダイアログへの入力も時間内に済ませなければなりません。

例えば、5000msに設定した場合は5秒以内にBasic認証のIDとパスワードを入力しないと、Ajaxリクエストは失敗します。

# 理由

jQueryは[XMLHttpRequest.timeout](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/timeout)を使っていません。
自前でタイマーを立て、設定時間がすぎたら[XMLHttpRequest.abort()](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/abort)を呼びます。

```js
if ( s.async && s.timeout > 0 ) {
  timeoutTimer = window.setTimeout( function() {
    jqXHR.abort( "timeout" );
  }, s.timeout );
}
```
https://github.com/jquery/jquery/blob/0f780ba7cc5968d53bba386bdcb59b8d9410873b/src/ajax.js#L691-L696
制約の多い運用現場でエンジニアっぽいことをする方法

## 対象
- セキュリティの関係でソフトやツールをインストール・導入できない
- お金がないからツールを購入してもらえない
- サクラエディタでコードを書いてる
- そもそも周りにコードかいてるやつがいない
- IEが推奨ブラウザ(そもそも外部にアクセスできない)
- 何でもかんでもExcelでやりたがるetc.

上記はほとんど自分が今の現場に感じている不満だがおそらく自分だけじゃないはず．今や自宅での環境のほうが優れている人がほとんどだと思う．WEB系で働いている人のツイートとかみるとめっちゃ羨ましく思う．でもWindowsにはメモ帳があるじゃないか．

### PowerShell
用途としては単純作業の自動化がメイン

- メリット
    - 個人的に最近ハマっている
    - Windowsに標準でインストールされている
    - PowerShell ISEという統合開発環境がある
    - .NET Frameworkを利用できる
    - COMオブジェクトの操作が可能
    - CSV,XML,JSONを扱いやすい(これで少しは脱Excelできるかも)
    - レスポンスがLinuxのシェルと違って文字列ではなく，オブジェクトで返ってくるので扱いやすい

-  デメリット
    - ユーザが少ないので情報も少ない
    - 実行ポリシーが存在していてバッチファイルみたいにダブルクリックしてすぐ実行とはならない

### HTML/CSS/JavaScript/VBScript
静的なポータルサイトとかアプリケーション

- HTA(html Applications)でアプリ化できる
    - IEがあれば実行できる
    - AxtiveXが使える
- ファイルサーバで静的サイトみたいに運用できる

### C\# 
PowerShellの上位互換という感じでアプリとかちょっとしたスクリプトも可能

- .NET Frameworkを利用できる
- コマンドプロンプトでコンパイルできる(VisualStudioなくても開発可)
- 細かいとこまろで作りこむことができる

## まとめ

世の中にはもっと便利なものがたくさんあるが，基本的にWindowsで標準で入ってるものをうまく利用していくしかない．あのライブラリ使えたら楽だなーとかおもうこともあるが，利用できる環境じゃなければ自分で作っていくしかない．車輪の再発明かもしれないけど，この経験は無駄にはならないと思うので同じような境遇の方には是非試してもらいたい．またこの他に使えるものがあればぜひ教えてくださいー
Ubuntu18.04 LST のサーバー設定

# 環境
Ubuntu 18.04 LTS 

# openssh-server のインストール
Ubuntu 18.04 LTS では ssh クライアントはデフォルトでインストールされている。（下記のコマンドで確認可能。）

```bash
$ dpkg -l | grep ssh
```

ssh サーバーをインストールする。

```bash
$ sudo apt-get install openssh-server
$ dpkg -l | grep ssh # インストール完了の確認
$ ps -ax | grep ssh # サーバーが動作しているか確認
```

# ポートの開放
Ubuntu18.04 LTS ではすべてのポートがデフォルトで閉じられているため、ufw (Uncomplicated FireWall) コマンドで使用するポートを開放する。
※下記では22番ポートを開放するが、セキュリティ上は他の番号に変更しておくのが無難。

```bash
$ sudo ufw enable # ファイアウォールの有効化
$ sudo ufw status # 現状で開放されているポートの確認
$ sudo ufw allow 22 # 22番ポートを開放
$ sudo ufw reload
$ sudo ufw status # 22番が開放されたことを確認
```

# ssh デーモンの設定
ssh 接続で使用するポート番号を上記の ufw コマンドで開放したポート番号に変更する。

```bash
$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.old # configファイルのバックアップ
$ sudo vi /etc/ssh/sshd_config

# ファイル内の下記の部分の番号を変更する
...
#Port 22
...

$ service sshd restart # sshデーモンを再起動
```

# IPアドレスの固定
Ubuntu 18.04 LTS ではネットワーク設定は /etc/network/interfaces ではなく、 /etc/netplan/ 下に yaml ファイルとして記述する。自分の環境ではデフォルトで下記のようになっていた。

```yaml:01-network-manager-all.yaml
network:
  version: 2
  renderer: NetworkManager
```

これを下記のように変更。

```yaml:01-network-manager-all.yaml
network:
  version: 2
  renderer: NetworkManager
  ethernets:
    enp3s0:
      addresses: [192.168.3.8/24, '2400:2411:c0a3:6f00:14ff:54b:28e3:1ed7/64']
      gateway4: 192.168.3.255
      nameservers:
        addresses: [192.168.1.1, 8.8.8.8, 8.8.4.4]
```

記述内容の詳しい意味については以下の公式 reference および kome さんの解説記事等を参照。

- [Netplan reference](https://netplan.io/reference)
- [komeの備忘録](https://www.komee.org/entry/2018/06/12/181400)

下記を実行して設定内容を反映。（実行すると /etc/netplan/ 以下のすべての yaml ファイルが読み込まれる。）

```bash
$ sudo netplan apply
```

# ssh の鍵の設定

ローカル PC で暗号鍵を生成。

```bash
$ ssh-keygen -t rsa # rsa 方式で暗号化鍵を生成
```

生成した公開鍵の情報を何かしらの方法でリモート PC に送信し、authorized_keys に登録。

```bash
cat id_rsa.pub >> /home/{your_username}/.ssh/authorized_keys
```

これで ssh 接続は可能だが毎回鍵の場所を指定するのは面倒なので、リモート PC の .ssh/config ファイルに下記の情報を記載。

```:.ssh/config
Host {host}
HostName {your_hostname}
User {username_of_remote_PC}
Port 22
IdentityFile {path_to_secret_key}
```

これで、```ssh {host}``` で接続が可能。接続できない場合は下記のリンクのあたりなどを確認。

-[EC2のSSH接続でPermission denied(publickey)と出た時の対処法](https://qiita.com/katsukii/items/c3df0653ac07d41fe03f)
【備忘録】Ruby : クラスメソッド、インスタンスメソッド使い方

```ruby:sample.rb

class Person
	attr_accessor :from

	def self.lefty(name,age)
		#メソッド名の頭に self. をつけるとクラスメソッドになる。
		new(name,age,"左")
		#newすることでinitializeメソッド呼び出し
	end

	class << self
		#複数のメソッドをクラスメソッドにする方法
		def second_method
			puts "second"
		end

		def third_method
			puts "third"
		end
	end

	def initialize (name,age,foot)
		#new メソッド使った時に使用
		@name = name
		@age = age
		@foot = foot
	end

	def sayHello
		puts "私は #{@name}です。 #{@age}歳です。 利き足は #{@foot}です。"
		#ここで使っている@name,@age,@footはinitializeで定義したものを使っている。
	end

	def sayFrom
		if @from != nil
			puts "私は #{@name}です。 #{@age}歳です。#{@from}出身です。"
			#ここで使っている＠fromはattr_accessorの:fromに格納された値を使う。(インスタンス変数)
			#ちなみに @from 部分を from に書き直してもしっかり出力される
		else
			puts "私は #{@name}です。 #{@age}歳です。"
		end
	end
end


person1 = Person.lefty("中村",27)
#クラスメソッドを使用
person1.sayHello

person2 = Person.new("中田",29,"右")
#単純に new
#initializeメソッドの処理でインスタンス変数に引数を突っ込む
person2.sayHello

person3 = Person.new("小野",26,"右")
#単純に new
person3.from = "静岡"
# さらにattr_accessor:fromに静岡をセット=>@from
person3.sayHello
person3.sayFrom

puts person3.from #=>"静岡"
#puts person3.name #=>出力エラー
#解決方法=> attr_accessor に :name を追加
#追加後、=>小野


#foo = Foo.new
#foo.first_method
#foo.second_method
#上記のようにオブジェクトを生成した後にクラスメソッドを呼び出すことは不可能


```

出力結果

```
私は 中村です。 27歳です。 利き足は 左です。
私は 中田です。 29歳です。 利き足は 右です。
私は 小野です。 26歳です。 利き足は 右です。
私は 小野です。 26歳です。静岡出身です。
静岡
```
Automation Anywhere 　Bot作成時の便利機能　3選

# Automation Anywhere 開発時に便利な機能　3選
個人的にここが便利だなと思ってよく使っている機能を3つ紹介させていただきます。
最近A2019の話題が多いですが、まだまだv11を使っている人もいるはず。。ということでTipsにもなると思って書いてみます。
v11メインに記載していますが、A2019でどうなっているのかも併せて書いています。

## 1.Botの途中から実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/f682bed5-f4cc-0580-024b-3f59681af57b.png)
実はAutomation Anywhereは好きなところから実行ができます。（Loop(繰り返し）の途中などは不可）

コマンド追加→動かす→コマンド追加→追加したコマンドのみ動かす　が簡単にできます。
少しずつ作って試すことができるので、品質も上がりやすいですね！
ちなみにA2019にもこの機能は引き継がれています。

A2019の画面だと「ここから実行」という名前になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/46c8026b-130a-025e-2a3d-6d9e9957f918.png)


## 2.タブで複数のBotを開ける、一部コピー&ペーストもできる


![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/bc03005c-d2e3-68b0-9b30-902c45ab0ab2.png)
Automation Anywhere v11ではこんな形で複数のBotを一つのワークベンチ（開発画面）で開くことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/8c74ebb2-66fb-d660-c012-1e4345776122.png)

Ctrl+Shiftを押しながらクリックすると複数コマンドが選択できます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/91ec0ef9-0b8a-8be1-09c3-09fe6a5a0be8.png)
コピー先のBotと同じ変数を持っている場合は上書き確認のメッセージが出る。ここでは「はい」を押す。
（なんと、変数も一緒にコピーできるのです！）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/a9c598b0-19f5-dd59-894f-e75e4cfc0419.png)

こんな形でBotの一部だけの貼り付けができます。

①数行のBotを作ってテストしてから、開発中の元Botに張り付ける
②Bot作っている最中で部品化した方がいいなと思ったら、すぐに部品化できる
③他の人が開発したBotを一部だけいただく。

などの使い方もできますね♪

A2019でもできます。（2020年5月7日時点での最新版A2019.12より）

こちらのBotで好きな範囲をコピー。
Ctrl+Shiftを押しながらクリックすると複数コマンドが選択できます。
リスト表示の方が選択しやすいのでお勧めです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/d57ef74a-09c8-df06-44ac-88a29b35218e.png)

Paste to shared clipboard で貼り付け。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/cbc0989d-1044-fd7d-1c00-a83b03ddd6e0.png)

v11と同じく同一ウィンドウではなくBotを開きなおすもしくは別のブラウザタブを開いてあげる必要はあるのですが、一部だけコピペできると開発スピードが格段にアップしますね。



## 3.ランタイムウィンドウ　で実行箇所確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/174c265e-8810-386c-9f92-d35966f0f076.png)
Bot実行中（Control RoomからでもClientからの両方）には、にランタイムウィンドウと言って「今何行目を実行しているのか」と「どのコマンド（アクション）を実行しているか」を示してくれる機能があります。
Botが動かないときにも、どの処理で止まっているのかが一目瞭然です！


ちなみにA2019にもこの機能は引き継がれています。
こんな感じで出てきます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584428/a90f2af3-4ef0-f1ac-33ff-9a091010e1ab.png)




以上、開発時に嬉しい機能3選でした！
参考になった方はいいね！やコメントをいただけると嬉しいです。
Swift Stateとはなんぞや１コマ劇場

#はじめに

自分のSwift学習メモです。
１枚のメモ用紙に、その宣言や使い方のざっくりしたイメージを記録していきます。

#対象とする読者
自分
SwiftUI初心者

#環境
私がこの記事を書いている際に利用しているのは次の環境です。
Xcode 11.3.1
Swift 5.0


#`@State`を１枚で説明すると
![@State.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187991/c27bd16f-4486-58e5-3cef-1779f976a04b.png)


#解説
変数に`@State`をつけることで、State構造体という特別な場所に変数は格納されます。そして、この変数の値が書き換わるたびに、State構造体に定義されているupdate()が呼び出され、関連する各Viewの再表示が行われます。
状態変更による個別Viewの再表示イベントの実装から解放される模様。
【NSDictionary】高速列挙for VS enumerateKeysAndObjectsUsingBlockでの処理速度対決、実際どっちもどっち説

##for構文の例
```objective_c

for (id key in dict){
    id obj = [dict valueForKey:key];
}
```

##enumerateKeysAndObjectsUsingBlockの例
```objective_c

[dict enumerateKeysAndObjectsUsingBlock:
   ^(id key, id object, BOOL *stop) {
       }
 ];
```

以前はfor構文を使っていましたが、`enumerateKeysAndObjectsUsingBlock`の存在を  
知ったので処理速度の差があるのか今回計測してみました。

##テストコード
```objective_c

int main(int argc, char * argv[]) {
    @autoreleasepool {
    
        int searchTarget = 100000;
        
        NSMutableDictionary *dict = [NSDictionary dictionary].mutableCopy;
        for(int i=0; i<searchTarget; i++){
            NSString *key = [NSString stringWithFormat:@"%d番目",i];
            dict[key] = key ;
        }

        NSDate *date = [NSDate date];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        dateFormatter.dateFormat = @"YYYY-MM-dd HH:mm:ss.SSS";
        NSLog(@"SEARCH_START01_%@",[dateFormatter stringFromDate:date]);
        //パターン1:高速列挙
        for (id key in dict){
            id obj = [dict valueForKey:key];
            if([obj isEqualToString:[NSString stringWithFormat:@"%d番目",searchTarget-1]]){
                NSLog(@"SEARCH_HIT01_%@",[dateFormatter stringFromDate:[NSDate date]]);
            }
        }
        
        NSLog(@"SEARCH_START02_%@",[dateFormatter stringFromDate:[NSDate date]]);
        //パターン2:enumerateKeysAndObjectsUsingBlock
        [dict enumerateKeysAndObjectsUsingBlock:
            ^(id key, id object, BOOL *stop) {
            if([object isEqualToString:[NSString stringWithFormat:@"%d番目",searchTarget-1]]){
                NSLog(@"SEARCH_HIT02_%@",[dateFormatter stringFromDate:[NSDate date]]);
            }
            
        }];

    }
}
```

内容を解説すると、`2020-02-12 22:34:39.728`こんな感じでログが出ます。
辞書を1000個`key-Value`を生成して1000個目が取り出せた段階でログが出て終わりになります。
その結果をふまえて記事を作ってみました。  

START-HITの差で計測します。
##結果
```objective_c
//高速列挙
SEARCH_START01_2020-02-12 22:34:39.728
SEARCH_HIT01_2020-02-12 22:34:39.776  //差:0.48

//enumerateKeysAndObjectsUsingBlock
SEARCH_START02_2020-02-12 22:34:39.895
SEARCH_HIT02_2020-02-12 22:34:39.922  //差:0.27
```

10万件だと処理時間が約半分になるのですね。。
それでは100件でみてみましょう。

###100件
```objective_c
//高速列挙
SEARCH_START01_2020-02-12 22:46:26.243
SEARCH_HIT01_2020-02-12 22:46:26.275  //差:0.32

//enumerateKeysAndObjectsUsingBlock
SEARCH_START02_2020-02-12 22:46:26.276
SEARCH_HIT02_2020-02-12 22:46:26.276  //差:0.00
```

流石に`//差:0.00`は嘘臭いですけど何回やっても結果は変わりませんでした。

##結論
for構文（高速列挙）ではなくてenumerateKeysAndObjectsUsingBlockを活用するべき。
yumコマンドとAPT系コマンドの違い

###yumコマンドとAPT系コマンド(apt-get,apt-cache,aptitude)
よく知らずに使っていた、もしくはよく出てくるなーぐらいに思っていた
yumコマンドとAPT系コマンドについてまとめたいと思います。どちらもLinuxについて調べているでよく出てくるコマンドでパッケージを管理するために使います。

- パッケージのインストール
`yum install <パッケージ名>`
`apt-get install <パッケージ名>` 

- パッケージの削除
`yum erase / remove <パッケージ名>`
`apt-get remove <パッケージ名>` 

- パッケージの検索
`yum search <検索ワード>`
`apt-chche search <検索ワード>`

また、これらのコマンドに似ているrpmやdpkgといったコマンドも存在します。


これらのコマンドもパッケージを管理することができるのですが、yumコマンドやAPT系コマンドと比べると
低機能で依存性の解決も自分で手動で行うこととなるので今では使う人はほとんどいません。

というのもyumコマンドはrpmコマンドを、APT系コマンドはdpkgコマンドをそれぞれ高機能にしたコマンドと
なっているため、使う必要がないのです。

それではyumコマンドとapt系コマンドの違いについて説明します。

###二つのパッケージ形式

現在のLinuxで主流のパッケージファイル形式は大きく二つに分けられます。

| パッケージファイル形式 | ディストリビューション               |　パッケージ管理コマンド |
|:--------------------:|:---------------------------------:|:----------------------:|
| Red Hat形式(.rpm)     | Red Hat Enterprise Linux, CentOs | rpm、yumコマンド |
| Debian形式(.deb)      | Debian GNU, Ubuntu                | dpkg、APT系コマンド　|

yumコマンドとAPT系コマンド、またはrpmコマンドとdpkgコマンドの違いはこの**パッケージ形式の違い**です。

UnuntuなどのDebian形式のディストリビューションを使っている場合はAPT系コマンド、CentOsなどのRed Hat形式のディストリビューションを使っている場合はyumコマンドを使うことができます。

基本的にapt-getでインストールできるパッケージはyumコマンドでもインストールすることができるので自分の環境にあった方のコマンドを使えばいいです。ただし、パッケージ名が多少異なる場合もあるので気を付けてください。
AWS試験対策（③コンピューティングとストレージ続）

自分用メモ、昨日の続きから

##　セキュリティグループ
セキュリティのルールをまとめた仮想FW。許可したいものだけ記載するホワイトリスト方式。
インバウンドは外から内へ、アウトバウンドは内から外への通信。
基本的に使うポートだけ開ける（インバウンドに記載する）。
開けすぎると攻撃受ける箇所が多すぎてセキュリティリスクであるから。
EC2のポートを開けるというよりは、ルールを作ってそこにEC2が従う的な感じ。
何が違うかって言うと、22と80のポートを開けたいサーバが2つあったとき、各それぞれに設定を作らなくて良くて、一度設定を作ったとこに所属させれば良い。お手軽。

セキュリティグループはステートフルといって、外へのトラフィックのについての、戻りのトラフィックは自動的に許可されるって仕組みらしい。
球技で例えるとわかりやすいかも。テニスとか。
フォアハンドで打ったものがバックハンド側に返ってきても受け取れる。みたいな。
しかし、相手のサーブをバックハンドで受け取るには、準備してないと受け取れないよーってな感じ。

また、アクセス元もセキュリティグループで指定できます。Aに入ってるサーバからのインバウンドはうけとるよーって感じ。IPでアクセス元の指定をしてたら、5台あれば5個の設定が必要だけど、セキュリティグループでの指定ならその5台をグループに入れちゃえばいいだけ。お手軽。

## プレイスメントグループ
一緒のAZなら通信が早いよってこと。深く考えずに、近いんだから早いやろってくらいの気持ち。

## 監視
メトリクス（CPU使用率とかのリソース監視）はcloudWatchってサービスでできる。SNSを使ってメールで通知することもできる。
また、ログ監視したい場合はインスタンスにエージェント入れればcloudWatchにあつめてくれる。

## auto recovery
ハードウェア障害とかが起きたときの対応を設定しておくことで自動的にやってくれる。
ハードウェア障害の際に、自動再起動を仕込んでおけば、落ちっぱなしじゃなくて別ホストコンピュータにて起動されて復帰が早くなる仕組み。
一応、ホストコンピュータ側だけじゃなく、インスタンス側の障害の場合でもauto recoveryは使える。

## AWS marketplace
予めソフトウェアがインストールされてるAMIを購入できる。インスタンス作ってからソフトウェアインストールする手間が省けるから便利。

一旦区切り、次回EBSから。
データ構造

型を宣言することでメモリを占有するバイト数をあらかじめ決めている

ポインタとは宣言地点からのバイト数を示すもの
Char *e   =>e地点から1Byte

配列の大きさは型の占有するByte数✖️配列の数になる

## データ構造

キュー、スタック、リスト、二分探索木

### キュー　
先入れ先だし
待ち行列とも言われる。その名の通り、データを待たせておきたいときに有効。
例）常にデータが送られてきていて処理し続けなければならない状況
このとき、順番が決まってないと永久に処理されないデータが出てきてしまう
これをキューに入れておくと優先順位の番号付の手間を省ける
#### リングバッファ
このキューを筒状ではなく円状にしたもの。
常に時計回りにデータが追加され、時計回りに処理され続ける

### スタック
先入れ後出し
スタックは一時的にデータを置いておきたいときに使う。
例）メモリ1からメモリ2にデータを避難させる
データの入れ物をコップと考えたとき、最初に入れられたデータは一番底になる
そして同じ処理をもう一度すると元の形に戻る。
これもデータの元々の場所がどこかという情報を持たなくて済む

### リスト
配列の個々にデータだけでなく、次の要素のインデックスも与える。
データの削除と追加はこのインデックスの値を変えるだけでできる。読込先の要素を書き換えればそこが次の値になる。
要素が空いてしまったときに要素の移動コストがかからなくなる。

### 二分探索木
その値より大きいか小さいかで検索範囲を縮めていくので検索する際に効率が良い
(bash) while 文に nohup を使う

はじめに、curl コマンドでレスポンスタイムを取得しようとした。

```bash
$ TARGET_URL=https://www.google.com/
$ curl ${TARGET_URL} -s -o /dev/null -w  "%{time_starttransfer}\n"
0.308898
```
問題なく動作した。
次にそれを３秒間隔で実行しようと while を使った。

```bash
$ while true; do curl ${TARGET_URL} -s -o /dev/null -w  "%{time_starttransfer}\n"; sleep 3s; done
0.370663
0.374432
0.929187
```
これも問題なく動作した。
次に出力を output.log にリダイレクトしようとした。

```bash
$ while true; do curl ${TARGET_URL} -s -o /dev/null -w  "%{time_starttransfer}\n" >> output.log; sleep 3s; done
```
```bash
$ tail -f output.log 
0.361946
0.413211
0.952241
```
問題なくリダイレクトされている。
次に nohup をつけてログアウト後も処理を継続しようとした。

```bash
$ nohup while true; do curl ${TARGET_URL} -s -o /dev/null -w  "%{time_starttransfer}\n" >> output.log; sleep 3s; done &
bash: syntax error near unexpected token `do'
```
これはエラーになって動作しない。
別の bash プロセス上で起動する必要がある。

```bash
$ nohup bash -c 'while true; do curl ${TARGET_URL} -s -o /dev/null -w  "%{time_starttransfer}\n" >> output.log; sleep 3s; done' &
```
```bash
$ tail -f nohup.out 
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
```
しかしながら、no URL specified と言われてしまう。
別の bash プロセス上で起動しているため、元のシェル変数${TARGET_URL} が見えなくなってしまっている。
そこで環境変数として定義しなおしてみる。

```bash
$ export TARGET_URL=https://www.google.com
$ nohup bash -c 'while true; do curl ${TARGET_URL} -s -o /dev/null -w  "%{time_starttransfer}\n" >> output.log; sleep 3s; done' &
```
```bash
$ tail -f output.log 
0.361946
0.413211
0.952241
```
問題なく出力することができる。
もし、環境変数として定義したくない場合は、実行するコマンドの最初にシェル変数を定義してあげる。

```bash
$ nohup bash -c 'TARGET_URL=https://www.google.com/; while true; do curl ${TARGET_URL} -s -o /dev/null -w  "%{time_starttransfer}\n" >> output.log; sleep 3s; done' &
```
Windowsのコマンド履歴を取得するコマンド(historyではなく)

#はじめに

初めての投稿。

Windowsのローカル環境で、Railsの勉強とかしているときにコマンドを叩くのだが、どのコマンドを叩いたかをいちいちメモったり、.txtファイルとかに出力するのがめんどくさかったので調べてみた。

コマンドプロンプトではなくPowerShellを普段使っているのでPowerShell用のコマンドを調べた。また、セッションごとに消えてしまうので
```history```　はあきらめた。

#コマンド
```
Get-Content (Get-PSReadlineOption).HistorySavePath
```

#ファイルパス
上記のコマンドが参照しているファイルは

```
C:\Users\ユーザ名\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt
```

#さいごに
どうしようもないのかもしれないが、上記.txtファイルの中身は本当にただのコマンドの羅列で、追加日時などは書いていないので取得件数などを決めない限り実用的ではない気がする。

#参考リンク
[Get-PSReadLineOption](https://docs.microsoft.com/en-us/powershell/module/psreadline/get-psreadlineoption?view=powershell-7)
Atcoder ABC125 C - GCD on Blackboard 別解集

C問題なのに脅威の水色
ちょっと捻ってるだけでネタが分かれば解けるヤツ

#累積GCD
これが正攻法
左から順番にgcdを取っていって記録していく
右からも同様に
あとで各一点に対して記録した左側gcdと右側gcdで仲良しさせる

```python:ruiseki.py
def euclid(a,b):
    a,b=max(a,b),min(a,b)
    if a%b==0:
        return b
    else:
        a,b=b,a%b
        return euclid(a,b)

N=int(input())
A=list(map(int,input().split()))

org_A=A[:]
#左から最大公約数作る右もね
A=A[::-1]
l=[A.pop(-1)]
while A:
    l.append(euclid(l[-1],A.pop(-1)))

A=org_A
r=[A.pop(-1)]
while A:
    r.append(euclid(r[-1],A.pop(-1)))
r=r[::-1]

ans=0
for i in range(N):
    temp=euclid(l[i-1] if i!=0 else r[i+1],r[i+1] if i!=N-1 else l[i-1])
    ans=max(ans,temp)

print(ans)

```

#セグメント木
初実装
あんまり綺麗に書けなかった、、、
これなら各一点に対してlogNで全体のgcdを求め倒すことができる

```python:seg.py
import fractions

N=int(input())

A=list(map(int,input().split()))

M=[2]
while M[-1]<N:
    M.append(M[-1]*2)

A=A+[0]*(M[-1]-len(A))
A=A[::-1]

for i in range(len(A)-1):
    A.append(fractions.gcd(A[2*i],A[2*i+1]))

A=A[::-1]

ans=0
for index in range(len(A)-M[-1],len(A)-M[-1]+N):
    temp=A[index+1] if index%2==1 else A[index-1]
    index=((index-1) if index%2==1 else (index-2))//2
    
    while index!=0:
        if index%2==1:
            temp=fractions.gcd(temp,A[index+1])
            index=(index-1)//2
        else:
            temp=fractions.gcd(A[index-1],temp)
            index=(index-2)//2
    ans=max(temp,ans)
print(ans)
```
Backtrader 別のファイルからインジケーターをimportする方法

#カスタムインジケーターのimport
いままでは説明のため同一のスクリプト内にカスタムインジケータークラスを書きました。しかしカスタムインジケータークラスだけを別のpyファイルに書いて、ストラテジーのスクリプトとは別々に使う方が便利です。

カスタムインジケーターのファイル名を仮に **customindicator.py** とすると、ストラテジーの冒頭部分に

`import customindicator as cind `（任意のわかりやすい名前）

と書いてストラテジークラスのinitメソッド内には

`self.myind1 = cind.MyStochastics1(self.data)`

と書きます。

customindicator.py はストラテジーのスクリプトと同じディレクトリに置きます。Jupyternotebookを使っていてデフォルト設定のままならば `C:\Users\ユーザー名\` です。

```python:customindicator.py

import backtrader as bt


class MyStochastic1(bt.Indicator):
    
    lines = ('k', 'd', ) 
    params = (
        ('k_period', 14), 
        ('d_period', 3),  # タプルの最後にもコンマ(、)をいれる
    )
    
    
    def __init__(self):
        highest = bt.ind.Highest(self.data, period=self.p.k_period)
        lowest = bt.ind.Lowest(self.data, period=self.p.k_period)        
       
        self.lines.k = k = (self.data - lowest) / (highest - lowest)    
        self.lines.d = bt.ind.SMA(k, period=self.p.d_period)
```

```python:sto2.py
%matplotlib notebook
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import datetime  
import os.path  
import sys 
import backtrader as bt 
import customindicator as cind #

class TestStrategy(bt.Strategy):
    def __init__(self):
        
        self.myind1 = cind.MyStochastics1(self.data)   
        
        
if __name__ == '__main__':
    cerebro = bt.Cerebro()
    cerebro.addstrategy(TestStrategy)

    datapath = 'C:\\Users\\XXXX\\orcl-1995-2014.txt'

    # Create a Data Feed
    data = bt.feeds.YahooFinanceCSVData(
        dataname=datapath,        
        fromdate=datetime.datetime(2000, 1, 1),
        todate=datetime.datetime(2000, 12, 31),
        reverse=False)

    cerebro.adddata(data)
    cerebro.run(stdstats=False)
    cerebro.plot(style='candle')
```
Feldman VSS

## 前提
位数が、素数 $q$ の 加法巡回群の上で計算する。ラグランジュで割り算が必要なので、群の全ての元に逆元が存在する必要がある。

## どんなものか
Threshold $t$ を決めて、秘密 $s \in Z_q$ を埋め込んだ多項式を作って、
その多項式からシェアを作り、参加者に一つずつ送る。
シェアが正しいものであることは、各参加者が検証可能。
Threashold 分のシェアを集めると、秘密を復元出来る。

## 多項式の構築
次数 $t-1$ の多項式 $P$ を以下の形で作る。
- $x^0$ の項の係数を秘密 $s$ に
- $x^1$ から $x^{t-1}$ の項の係数はランダムに$Z_q$から取る。

例えば、Threshold $3$ で、秘密が $5$ なら、一次の多項式 $P$ を
$$
P(x) = 3x + 5
$$
のように作る。

## シェアの計算
$P(i)\ |\ i>0$ の形で、シェアを計算して、各参加者に $P(i)$ と $i$ を送る。各参加者にはユニークな $i$ 割り当てる。

例えば、上の例なら、$P(1) = 3 \cdot 1 + 5 = 8$、$P(2) = 3 \cdot 2 + 5 = 11$、$P(3) = 3 \cdot 3 + 5 = 14$。

## シェアの検証
あらかじめ各参加者に、多項式の全ての項をジェネレーター $g$ に掛けたも、検証ベクターを送っておく。
上の例なら、$g^3, g^5$。

各参加者は、多項式の $x$ を 自分に割り当てられた $i$ で置き換えて、ジェネレーター $g$ に掛けたベクターを作り、検証ベクターとの内積を計算する。

上の例で $i$ が $2$ だと、
$[g^3, g^5] \cdot [g^{2^1}, g^{2^0}] = g^{3 \cdot 2} + g^{5 \cdot 1}$
となって、$P(2)=3 \cdot 2 + 5$ をジェネレーターに掛けた形になるのがわかる。

自分が持っているシェア $P(i)$ をジェネレーター $g$ に掛けたものと内積と一致すれば、シェアは正しい。

## 秘密の復元
Thresholdと同じ数のシェアを使って、[ラグランジュ補完](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%B0%E3%83%A9%E3%83%B3%E3%82%B8%E3%83%A5%E8%A3%9C%E9%96%93) で $P(0)$ を復元する。

## 実装
[ここ](https://github.com/exfinen/crypto-playground/blob/master/src/building_block/feldman_vss.rs) にあります。
google admin sdkでresource（会議室）を取得する方法

https://developers.google.com/admin-sdk/directory/v1/reference/resources/calendars/list?apix=true&apix_params=%7B%22customer%22%3A%22my_customer%22%2C%22maxResults%22%3A500%2C%22fields%22%3A%22items(resourceName%2CresourceEmail%2CresourceDescription%2CresourceType)%22%7D#try-it!

![屏幕快照 2020-02-12 下午10.00.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114912/1be87e74-2cf5-3e75-fb65-5a56710e243a.png)
Vagrant上で動かしていたKubernetesが動かなくなった

# はじめに
Vagrantを利用してKubernetes環境を構築していますが、kubectlを叩いたときにエラーが返ってきたので、それの解決策を記述します。

##開発環境
VagrantでVMを2つ起動させ、Kubeadmを利用してKubernetesクラスタを構築しています。
Master一台、Node一台の構成です。

Vagrantを利用してKubernetesクラスタを構築する方法については、これらの記事を参考にしています。

- https://qiita.com/sotoiwa/items/67fbb50915a8eba5a4ce
- https://medium.com/@raj10x/multi-node-kubernetes-cluster-with-vagrant-virtualbox-and-kubeadm-9d3eaac28b98


# 発生した問題
```
$ kubectl get pods
The connection to the server [master_IP]:6443 was refused - did you specify the right host or port?
```
今までは、kubectlが正常に動作していたが、突然、podを取得できなりました。


# 原因の確認
Vagrant上でのみ発生する問題かと思ったが、そういうわけでは無さそうでした。

とりあえず、kubeletが動いているかを確認してみました。

```
$ systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
   Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
  Drop-In: /etc/systemd/system/kubelet.service.d
           └─10-kubeadm.conf
   Active: activating (auto-restart) (Result: exit-code) since Wed 2020-02-12 11:55:58 UTC; 3s ago
     Docs: https://kubernetes.io/docs/home/
  Process: 2679 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS (cod
 Main PID: 2679 (code=exited, status=255)

Feb 12 11:55:58 master systemd[1]: kubelet.service: Main process exited, code=exited, status=255/n/a
Feb 12 11:55:58 master systemd[1]: kubelet.service: Unit entered failed state.
Feb 12 11:55:58 master systemd[1]: kubelet.service: Failed with result 'exit-code'.
```

どうやら、kubeletが正常に動作してなさそうなので、ログを確認してみました。

```
$ journal -xe | grep kubelet
：
：
Feb 12 12:04:03 master kubelet[5988]: F0212 12:04:03.063233    5988 server.go:273] failed to run Kubelet: running with swap on is not supported, please disable swap! or set --fail-swap-on flag to false. /proc/swaps contained: [Filename                                Type                Size        Used        Priority /dev/dm-1                               partition        1003516        0        -1]
Feb 12 12:04:03 master systemd[1]: kubelet.service: Main process exited, code=exited, status=255/n/a
Feb 12 12:04:03 master systemd[1]: kubelet.service: Unit entered failed state.
Feb 12 12:04:03 master systemd[1]: kubelet.service: Failed with result 'exit-code'.
```

どうやら、Swapがオンになっていることが問題らしいので、オフにします。
同様にして、ノード側もSwapをオフにします。
そして、ノードを確認してみます。

```
$ swapoff -a
$ kubectl get nodes
NAME     STATUS   ROLES    AGE   VERSION
master   Ready    master   8d    v1.17.2
node     Ready    <none>   8d    v1.17.2
```
無事、masterとnodeの両方でkubeletが正常に動作したようです！

# 今後の対策
## Swap機能をオフにする
/etc/fstabのSwapに関する部分をコメントアウトする。
ubuntu16.04では、/dev…から始まる文章でした。

```
$ vim /etc/fstab
/dev/mapper/vagrant--vg-swap_1 none            swap    sw              0       0
```

下記に別の対策も記述してありますが、個人的には、Swap機能をオフにする方法をおすすめします。

## VMを一時停止する
VMをシャットダウン（```vagrant halt```）すると、次に起動したときにSwapがオンになるので、VMを一時停止（```vagrant suspend```）する。


# 最後に
Kubeadmを構築する段階で /etc/fstab からSwapをオフにしている人は、このような問題は発生しないと思いますが、同じような問題が発生している人の助けになれば幸いです。

無事、Kubernetesが動くようになったので、私はKubernetes完全ガイドを進めたいと思います。
CloudFormationでスタックを作成しようとしたら「Encountered unsupported property <Property Name>」となる

## 事象

```lambda.yml
Resources:
  DemoFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: demo_func
      Code:
        ZipFile: |
          import json
          def lambda_handler(event, context):
              jsn_str = json.dumps(event, ensure_ascii=False)
              print(jsn_str)
      Handler: lambda_function.lambda_handler
      MemorySize: 128
      Timeout: 30
      Role: !Sub arn:aws:iam::${AWS::AccountId}:role/Lambda_Basic_Role
      Runtime: python3.7
      Events:
        Stream:
          Type: DynamoDB
          Properties:
            Stream:
              Fn::ImportValue: demoTableStream
            StartingPosition: LATEST
            BatchSize: 1
```

AWS CLIで`create-stack`コマンドにより上記テンプレート`lambda.yml`をもとにDynamoDB StreamをトリガーにしたLambda Functionを作成しようとした。

```shell
$ aws cloudformation create-stack \
    --stack-name demo-lambda \
    --template-body file://lambda.yml
```

しかし下記のように`Encountered unsupported property Events`というエラーとなりスタックの作成が失敗する。

![image.png](https://image.docbase.io/uploads/271f06d2-f8a2-4745-ac9e-43de188159ac.png)

## 解決

CloudFormationテンプレートでは`Type: AWS::Lambda::Function`では`Events`というプロパティは使えなかった。LambdaのDynamoDB Streamトリガーをテンプレートで定義する場合は下記のように`AWS::Lambda::EventSourceMapping`リソースを使う必要があった。

```lambda.yml
Resources:
  DemoFunction:
    Type: AWS::Lambda::Function
    Properties:
      FunctionName: demo_func
      Code:
        ZipFile: |
          import json
          def lambda_handler(event, context):
              jsn_str = json.dumps(event, ensure_ascii=False)
              print(jsn_str)
      Handler: index.lambda_handler
      MemorySize: 128
      Timeout: 30
      Role: !Sub arn:aws:iam::${AWS::AccountId}:role/Lambda_Basic_Role
      Runtime: python3.7

  EventMapping:
    Type: AWS::Lambda::EventSourceMapping
    Properties:
      EventSourceArn: !ImportValue demoTableStream
      FunctionName: !Ref DemoFunction
      StartingPosition: LATEST
```

![image.png](https://image.docbase.io/uploads/2bfe0230-9663-4c79-8697-39b0c6991c98.png)

## おわりに

AWS SAMのymlテンプレートを通常のCloudFormationテンプレートに流用していたため利用できないプロパティが紛れていたことが根本原因だった。

以上
Apache2.4.41をソースからインストールする

専門学校の卒業制作で初めてApacheを扱ったので備忘録的なアレを書いておく
Ubuntuですら触ったのは初めてなので多々抜けている点もあるかと思われ

#OS
Ubuntu18.04LTS

#参考記事
https://www7390uo.sakura.ne.jp/wordpress/archives/467
https://bty.sakura.ne.jp/wp/archives/149
https://www.skyarch.net/blog/?p=9543

#必要なもの
1.GCC(Cコンパイラ)
2.[pcre-8.39](https://sourceforge.net/projects/pcre/files/pcre/8.39/pcre-8.39.tar.gz)
3.[apr-1.7.0](https://www-eu.apache.org/dist//apr/apr-1.7.0.tar.gz)
4.[apr-util-1.6.1](https://www-eu.apache.org/dist//apr/apr-util-1.6.1.tar.gz)
5.[httpd-2.4.41](ftp.tsukuba.wide.ad.jp/software/apache//httpd/httpd-2.4.41.tar.gz)

#GCCのインストール
サクっとaptコマンドで
```$ apt-get install build-essential```
#コンパイルとインストール
上記のものを/usr/local/srcにダウンロードして解凍

ダウンロードの際は
```$ wget (URL)```

解凍は
```$ tar zxvf (ファイル名)```

解凍後、各ディレクトリに入って
```$ ./configure
$ make || make install```

と実行していきます。

#注意点その1
expat.hというライブラリが足りないといわれたので
[ここ](https://github.com/libexpat/libexpat/releases/download/R_2_2_7/expat-2.2.7.tar.gz)
からダウンロードします。こいつをインストールすればいけるはず。
#注意点その2
apr-utilの./configureを実行する際にオプションで

```$ ./configure --with-apr=/usr/local/apr```

とつけてやる
#注意点その3
httpd-2.4.41の./configureもオプションで

```$./configure --with-pcre=/usr/local/src/pcre-8.39/pcre-config --with-apr=/usr/local/src/apr-1.7.0 --with-apr-util=/usr/local/src/apr-util-1.6.1```

とつけてやる
#注意点その4
インストール後、いざ起動しようとするとライブラリのパスを通せというメッセージが出てきたため、

```$ export LD_LIBRARY_PATH="/usr/local/lib"```

これで実行できるようになる。
初投稿

# はじめに
初投稿です。
IT業界に進みたいと思っている、へっぽこ文系(元経営と現法学)大学生です。

先日、某企業の採用を(たぶん)アウトプットをしてなかったことで門前払いを食らったので、サボりがちでへっぽこ記憶力の自分に対しての備忘録と戒めを兼ねて、少しづつ学んだことをアウトプットをしていこうと思うのでよろしくお願いします。

大学入ってからプログラミングをやり始めたのですが、ほぼ独学なので技術力は低く、今まで誰かに見てもらうことを想定してコードを書いてなかったので見づらかったりすると思いますが、生暖かい目で見守っていただけると幸いです。



####プログラミングを初めたきっかけ
プログラミングを初めたきっかけは、
・ラズパイをつかって初めてLチカさせてたときにモノづくり(と言って良いのかわからないけど)の楽しさを知った
・手に職をつけたかった
・元々、PCをいじることが好きだったのでPCを使って何かをしたかった
とかなりありきたりな理由です。

####やっていること
入り口が電子工作だったので主に電子工作についてのプログラミングしていましたが、最近はandroidアプリやwebアプリケーションを作ろうと勉強しています。

####環境
OS：ubuntu18.04(win10が飛んで新しくライセンス買うお金がなかったので…)
エディタ：VScode,vim(苦手だけど頑張る)
Magento2でユーザーの住所入力を英語入力に制限(バリデーション)する

越境ECをMagento２で作った場合に、テキスト部分の住所入力まで現地の言語で入力すると国際郵便などで配送する場合にオペレーションで英語に変換する必要があり大変ということで、ユーザーが住所入力する時点で英語でしか入力できないようにバリデーションをかけたい。

# customer_eav_attributeにvalidation_ruleを追加する
Magento2のユーザーに関する属性の設定については customer_eav_attributeというテーブルに入っている。
customer_eav_attributeのvalidation_ruleというカラムにその属性のバリデーションルールについてJSONで設定をいれる。

以下のクエリを実行するとユーザーの住所に関する属性の、attribute_id,attribute_code、validation_ruleが一覧で見れる。

```:sql
SELECT 
customer_eav_attribute.attribute_id,
eav_attribute.attribute_code,
customer_eav_attribute.validate_rules
FROM customer_eav_attribute
JOIN eav_attribute ON customer_eav_attribute.attribute_id = eav_attribute.attribute_id
WHERE eav_attribute.entity_type_id = 2;

```

<img width="425" alt="Screen Shot 2020-02-12 at 21.15.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26205/e2cd58b5-5abe-f214-4fc0-976beb27fdda.png">

上記のfirstnameの属性のようにvalidation_rulesに "input_validation":"alpha" を追加するとアルファベット入力のみ制限できます。

```:json
{"input_validation":"alpha","max_text_length":25,"min_text_length":1}
```

正規表現を使って任意のパターンでバリデーションをかけたい場合は "pattern":"正規表現"を書く。
このとき、"正規表現"の部分はJSの `new RegExp()`に引数として与える文字列であり、かつJSONのフォーマットとしても正しくなるように書かないといけないので注意。
```:json
{"pattern":"^[a-zA-Z0-9\\s\\-]+$","max_text_length":25,"min_text_length":1}
```
【備忘録】Ruby : 基本的なclass作成、定数の扱い方

```ruby:sample.rb

class SampleClass
	attr_accessor :name,:greet
	# attr_accessor:name,:greetはinitializeメソッド内の
	# @name,@greetに関連
	def initialize(name,greet)
		# initializeメソッド => classをnewした時に必ず呼び出される。
		# メソッドの引数で受け取った値をインスタンス変数
		# にセットしている。
		@name=name
		@greet=greet
	end
end

sample = SampleClass.new("Tanaka","挨拶")
# newメソッドでクラスの定数に引数を渡したので
# sampleオブジェクトではname="Tanaka",greet="挨拶"が入っている。


```
C# で Brainfuck のインタプリタ作って Nuget に公開した

# なんでそんなもん作ったの？

大昔にこんなものを作りました。

[響ちゃんマジ天使言語][hibiki_angel]

何かというと、Brainfuck の各トークンをアイマスの我那覇響ちゃんへの愛を叫ぶ言葉に置換して、コーディングできるようにしたものです。
ずいぶん前に話題になったおっぱい言語みたいなやつですね。

で、これ自体は WinForms のコードビハインドにゴリゴリ実装した、「MVVM? WPF? なにそれ、おいしいの？」状態のなかなかなシロモノです。
そんなものなので、ずっとリファインしたかったんです。

また、当時から時が経ち、 .Net Core がリリースされて、 C# でマルチプラットフォームに対応するのが劇的に簡単になりました。

というわけで、リファインするにあたって、次のような目標を立てました。

* 解析する部分はクラスライブラリとして外に出す
* フレームワークは .Net Core としてマルチプラットフォームで実行できるようにする
* トークンの定義を設定ファイルに切り出し、ユーザが好きにカスタマイズできるようにする

# BFCore 爆誕

そして、出来上がったものがこちら。（キュー〇ー3分クッキング）

ソースコードは[こちら][bfcore_git]
Nuget は[こちら][bfcore_nuget]

上記の目標は一応達成できました。
ちなみに、フレームワークは .Net Core から .Net Standard 1.3 まで落としました。

サンプルアプリとして、 BFCore を使用してリファインした[響ちゃんマジ天使言語][hibiki_angel_wpf]もあります。
まあ、笑ってやってください。

実装に関してはそんなに工夫してないというか、まあ、ごり押しに近いです。
プルリクエストなど頂ければ泣いて喜びます。

使い勝手がいいかはあまりわかりません。
というか、他の人の感想が知りたくて、宣伝のために記事を書いたようなものだったり……

使い方に関しては、 GitHub の README に詳しく書いているので、そちらを参考にしてください。

# さいごに

内容がめちゃくちゃ薄くて申し訳ありません。
直接は関係ありませんが、 GitHub の Actions で master にマージしたら自動で Nuget に公開されるようにしました。
たぶん、こっちのほうが需要が高い気がするので、そちらについてまたあとで記事にしたいと思います。

それでは。

[hibiki_angel]:https://github.com/koktoh/Hibiki_Angel
[hibiki_angel_wpf]:https://github.com/koktoh/hibiki_angel_language_wpf
[bfcore_git]:https://github.com/koktoh/brain-fxxk-core
[bfcore_nuget]:https://www.nuget.org/packages/BFCore/
【UE4】マテリアルでカラーバリエーション／第13回UE4ぷちコンの前準備 - 2020/02/12

[1]:http://historia.co.jp/
[2]:http://historia.co.jp/ue4petitcon13
[3]:https://www.unrealengine.com/marketplace/en-US/product/paragon-minions


[株式会社ヒストリア][1]さん主催の[第13回UE4ぷちコン][2]が待ちきれずに、それ用の作業を始めてしまったメモ。
※テーマ発表はあさって。（待てばいいのに）

# この子をどうしても使いたい

マーケットプレイスのEpic無料アセット[Paragon: ミニオン][3]に入っている "Buff Black"。
![BuffBlack01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/3a03b4f7-2f58-e42e-b0e7-fc6eff8d9fd7.png)
かわいいw

# マテリアルをいじって、各色用意してみた。

![BuffBlack02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/c30d46b2-b5a9-0693-b7d1-8eda5f823045.png)

色で役割が違うとかそういう感じにできればいいな。
大きさを変えるのもありだな。

## いじった個所

![BuffBlack03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358170/c3a5d3e2-1cc4-7b20-2ad7-22ef339abd86.png)

- Base Color への流れの間に色変更回りを割り込ませている。
- HueShift 関数を使用。
    - HueShiftDegrees は色相(Hue)の回転角度。Degreeで。
    - HueShiftDegrees への掛け算 0.002778 は 1/360 の意味。（どうせ大した精度はいらないので）
- BaseAdder で色の底上げ。続く Power でコントラストを上げると、簡単に真っ黒になるので、その調整用。
- Exponential でコントラストを付ける。
- Saturate は Clamp(Value, 0, 1) と同じ。
- FinalMultiplier で最後の明るさ調整。

> 本当はテクスチャを描き変えようとしたのだが、右クリックメニューから「Export」が消えていた。Epicさんからの「素材をExportするのはダメ」とのメッセージだと思われる。
> ※例えば Starter Contents 内のテクスチャなどは「Export」メニューが出てくる。


今日はここまで。
セキュリティのあれこれ

セキュリティ系の知識を付けようと思い、「徳丸浩のWebセキュリティ教室」を読んでみたのでメモ。

**脆弱性とバグ**
脆弱性の定義：悪用可能なバグ
脆弱性があると、「できないはずことができる」
バグがあると、「できるはずのことができない」

**バッファーオーバーフロー**
コンピュータのメモリ（システムバッファ）をオーバーさせて、意図しない動作をできるようにしてしまう。

**ガンブラー攻撃**
FTPアカウントなどを乗っ取り、weｂサイトを改ざんする。

**パスワードリスト攻撃**
脆弱なweｂサイトから入手したユーザーIDとパスワードを使って、攻撃対象のサイトでログインを試行する
責任の所在
パスワードを複数サイトで使い回し→利用者に責任
パスワードに使える文字の種類を制限→サイト側に責任

**ブルートフォース攻撃**
ユーザーID固定で、パスワードを変更してログインを試行する。

**リバースブルートフォース攻撃**
パスワードを固定、ユーザーIDを変更してログインを試行する。ブルートフォース攻撃の逆。
例：JAL、ANAの不正ログイン

**クロスサイトリクエストフォージェリ（CSRF）**
ユーザーの意図しないリクエストを実行させる。
例：2012年の「パソコン遠隔操作事件」

**ソフトウェアのライフサイクル**
バグの修正パッチ提供がいつまでかを確認。
https://qiita.com/bezeklik/items/72d1ff8393f66673e2bc

**パスワードの定期的変更はセキュリティ対策のペストプラクティスではない。**
悪用される期間を短くすることはできる。
2段階認証やログイン通知を実装するのが○
OPEN CV3 Install 備忘録

#概要
鶏並みの記憶力なので、やったことを書いておく。
Ubuntu18.04にOPEN CV3をインストールしたので、その手順の備忘録

- 実施時期：2019年11月
- 環境：Ubuntu18.04LTS

##前準備
既に実行されていたらここは不要

```Terminal
sudo apt update
sudo apt upgrade
sudo apt install net-tools
sudo apt install git
dpkg -l git
sudo timedatectl set-local-rtc true
sudo apt install vim
sudo apt install build-essential
sudo apt install clang
reboot
```
##環境設定とクローン
ここではOPEN CV3.4.8をインストールための環境設定とクローンをする。
これまでの[バージョン履歴](https://opencv.org/releases/)を参照し、version 3.4系で最新だったからversion3.4.7を選択した。
基本の流れはこの方の[投稿](https://qiita.com/usk81/items/98e54e2463e9d8a11415)を参照させていただき、makeのオプションなど詳細は[オフィシャル](https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html)を参考にした。

```Terminal
sudo apt install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt install python-pip python3-dev python3-numpy
sudo add-apt-repository "deb http://security.ubuntu.com/ubuntu bionic-security main"
sudo apt -y install libjpeg8-dev libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev libxine2-dev libv4l-dev
cd /usr/local/src
sudo git clone https://github.com/opencv/opencv.git
sudo git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
sudo git checkout -b 3.4.8 refs/tags/3.4.8
cd ../opencv/
sudo git checkout -b 3.4.8 refs/tags/3.4.8
```
##画像ライブラリ
"環境設定とクローン"にてlibjpeg8-devなど画像ライブラリをインストールしたが、libjasper-devはそのままapt installできなかったのでここで別途インストールする。
なお、libpng12-devはUbuntu16以降、サポートされていないのでインストールしない。
手順は[オフィシャル](https://ubuntu.pkgs.org/18.04/trinity-r14-builddeps-amd64/libjasper-dev_1.900.1-debian1-2.5ubuntu18.04.0+6_amd64.deb.html)を参照した。

Add the following line to /etc/apt/sources.list:

```
deb http://ftp.fau.de/trinity/trinity-builddeps-r14.0.0/ubuntu/ bionic main
```
Install GPG key of the repository:

```
sudo apt-key adv --keyserver keyserver.quickbuild.io --recv-keys F5CFC95C
```
Update the package index:

```
sudo apt-get update
```

Install libjasper-dev deb package:

```
sudo apt-get install libjasper-dev
```
（まだapt-getなど使っている…）

##コンパイルとインストール
引き続き、いよいよコンパイルとインストール
cmakeのオプションは調べまくってこのようになった。
ここの工程は時間が少しかかる。

```Terminal
sudo mkdir build
cd build
sudo cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local -DWITH_TBB=ON -DWITH_OPENCL=ON -DPYTHON_EXECUTABLE=/usr/bin/python3.6 -DOPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ..
sudo make -j7
sudo make install
sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig -v
```

##インストール確認
入ったか確認する


```Terminal
opencv_version
cd /usr/local/src/opencv/build/bin
./opencv_test_core
```

Python3でも確認

```python
import cv2
cv2.__version__
```

以上
初心者によるプログラミング学習ログ 237日目

#100日チャレンジの237日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

237日目は
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>237日目<br>・youtubeで、portfolio模写<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1227324031428431873?ref_src=twsrc%5Etfw">February 11, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
コンパイル/コンパイラ

## コンパイル

プログラミング言語で書かれた文字列（ソースコード）を、コンピュータ上で実行可能な形式（オブジェクトコード）に変換することです。

#### なぜコンパイルするのか？
コンピュータ上で実行される命令は機械語ですが、人間には意味をとらえにくい数字の並びであるため、機械語でプログラムを作成するのは困難である

## コンパイラ
コンパイルを行うソフトウェアをコンパイラといい、変換されるプログラミング言語をコンパイラ型言語と呼びます。
Rの時刻変換と日の差分【lubridate, Time Intervals, Differences day】


時刻変換する方法は色々ある。

Rの中で時刻データとして変換してやると、

```
https://stat.ethz.ch/R-manual/R-devel/library/base/html/difftime.html
```

ここに乗っているようなことができる。
自分でちょこちょこ調べる周辺まとめておく。

# 日の差分を求めることが今回の目的

## as.Dateで

```r
start <- as.Date("20200101", format="%Y%m%d")
end <- as.Date("20200201", format="%Y%m%d")

end - start
```

```r
Time difference of 31 days
```

difftime関数も同じことやっている

```r
difftime(end, start)
```


# as.POSIXでも

```r
start <- as.POSIXct("20200101", format="%Y%m%d")
end <- as.POSIXct("20200201", format="%Y%m%d")
difftime(end, start)
```

```r
Time difference of 31 days
```

# lubridateほんと最高

```r
library(lubridate)

start <- ymd("20200101")
end <- ymd("20200201")

difftime(end, start)
```

```r
Time difference of 31 days
```


# as.numericで数字に直す

```r
as.numeric(difftime(end, start))
```

```r
[1] 31
```

# おまけ

気持ちを察してくれるlubridateさん


```r
ymd("20200501")
[1] "2020-05-01"
ydm("20200501")
[1] "2020-01-05"
mdy("08202000")
[1] "2000-08-20"
ymd_hms("20200201003059", tz="Japan")
[1] "2020-02-01 00:30:59 JST" 
ymd_h("2020020120", tz="Japan")
[1] "2020-02-01 20:00:00 JST"
```

曜日も出してくれる優しいヤツ

```r
wday(ymd("20200501"))
[1] 6
wday(ymd("20200502"))
[1] 7
wday(ymd("20200503"))
[1] 1
```

ちなみに
1が月曜日
7が日曜日


lubridateさんホント最高
他にも差分をとる方法は色々あるので以下参照

```
https://lubridate.tidyverse.org/
```
PHPに触れて5か月の学生がPHPerKaigi2020へ行ってみたときの話

#はじめに
　ある日気ままにネットサーフィンをしていたところ、こんな記事を見つけました。
[あなたが今年PHPerKaigi 2020に参加しなければいけない理由](https://www.phper.ninja/entry/2020/01/19/014417)
ふむふむ、2/9~11にかけてPHPerが一堂に集まる大きなイベントがあるのか～
予定は空いているな、で値段は...えっ最低でも参加料4800円か、少し料金は高いけど暇だし行ってみるか
ということでイベントへ参加することにしました。


#そもそもPHPerKaigiとは
>[PHPerKaigi2020公式ホームページ](https://phperkaigi.jp/2020/)より
>>PHPerKaigi（ペチパーカイギ）は、PHPer、つまり、現在PHPを使用している方、過去にPHPを使用していた方、これからPHPを使いたいと思っている方、そしてPHPが大好きな方たちが、技術的なノウハウとPHP愛を共有するためのイベントです。

つまりPHPが好きだったり、興味を持っている人ならだれでもオッケーだそう。



#行ってみての感想
　ここでは自分がPHPerKaigi2020に参加して、印象に残ったこと、良いなと感じたところ、ここはどうなのかなと感じたところを挙げていきます。


##印象に残ったこと

**参加者の数**
会場内にはPHPerKaigi2020のスタッフと参加者合わせてざっくり300~400人くらいの人がいて、PHPが好きな人はこんなに多いのか！とまず驚きました。

**セクション**
もっと気軽にOSSにPRを出そう！（DQNEOさん）

- フレームワークなどの製作者は自分の関心の外の部分は意外と適当だったり、間違いがあったりする⇒既存のフレームワークやパッケージを修正するチャンスは結構ある
- 英語のスペルミスレベルの簡単な修正もある⇒専門的な知識がなくてもできる
- PRに励むことで、自分の知識の横展開（応用）ができる

結論：みんな怖がらずにPR（pull Request）を出そう！

このセクションはあまりPHPについて詳しくない自分にとってもわかりやすかったし、何より聞いた後、俺もPR出してみようかな、というやる気がわきました。

**イベント内の様々な仕掛け**
　参加者が自分のツイッターのアカウント情報がが記載されたデュ〇ルマスターズを彷彿とさせるカードを持ち、ほかの参加者にそれを渡し合っていたのが面白かったです。（しかも一人一人効果まで書かれていたのがこだわりを感じました。）
　そのほかにも様々な仕掛けがあり、製作者の遊び心が垣間見えて面白かったです。

##PHPKaigi2020の良いなと思ったところ
　自分が良いなと思ったところは、会場のいたるところに遊び心がある仕掛けがあり、文化祭みたいで楽しかったところです。またボードゲームコーナーがあるなどぼっちで行った自分でも他の参加者と交流できる機会があるのも良かったです。

##PHPKaigi2020のここはどうなのかなと思ったところ
　料金設定が三日間参加で4800円からしかないのが微妙だな、と感じました。なぜなら、もし一日参加券みたいなものを作り、もう少し安く参加できる料金コースを設定すれば、PHPのカンファレンスに今まで参加したことがない層の人がより多く参加し、それによりPHPのコミュニティーのより一層の発展が見込めるからです。
（会場の都合・運営側の都合・スポンサー側の都合を全く理解していない立場からの発言です.）


#おわりに
　初めてのPHPerKaigiは自分の予想より楽しかったです。今回の参加で、PHPのコミュニティーとしての面白さを感じることができたので、次は東京以外で行われるPHPerKaigiにも参加しようかなと思います。
運営の方々は三日間お疲れさまでした！
構造化データ




## 構造化データとは

HTMLで書かれた情報が何を意味するのかを、検索エンジンやその他のクローラーに理解できるようにタグ付けしたもの


## 構造化データのメリット/ デメリット
「構造化データのメリット」
・リッチスニペットが表示できること
・ページ内コンテンツがナレッジグラフに表示されること

「構造化データのデメリット」
・検索エンジンの動向次第ではメンテナンスが必要になってくる
・ソースコードの量が増える


## 構造化データの概要
構造化データは、ある物事に関連する情報をロボットにもわかるように紐づけていきます

たとえばある会社について構造化する際には、
その会社は

名前は○○で、
概要は○□○○で
設立者は○△で、
住所は□○で、
電話番号は××-○○-○○で、
企業ロゴは△○の画像で
ウェブサイトURLは○□です

といった具合で情報をロボットに伝えています。

このように構造化された要素が増えていけば、ロボットも単語の理解がより進むことはもちろん、ウェブページの中で言及された文脈や、ほかの単語との対比がしやすくなると考えられます。

構造化マークアップはHTMLに直接記述する。その際ボキャブラリーとシンタックスというものを使う。

## ボキャブラリーとシンタックス
構造化データにおけるボキャブラリーはマークアップする物事を定義するもの、シンタックスはそのマークアップの記述方式のこと

それぞれイメージするならば、ボキャブラリー（vocabulary）は単語を集めた単語集、シンタックス（syntax）は単語の意味をロボットに伝えるための書き方を決めた文法書となる。


#### ボキャブラリー
例 schema.org/
https://schema.org/

schema.orgでマークアップする際にはタイプ（型）とプロパティ（属性）を指定します。

例えば。Corporatioのタイプに割り当てることができるプロパティは
name（名前）、address（住所）、telephone（電話番号）などのプロパティがありますので、これらのうちマークアップできるものを構造化していくのです。

流れとしては
タイプを見る→各タイプのページに行き割り当てられるプロパティを確認→マークアップです


#### シンタックス
例 JSON LD
https://json-ld.org/

メリット
構造化マークアップが別の場所にあるため、HTMLを汚す必要がないことです。

デメリット
多かれ少なかれファイルサイズが大きくなってしまいます。

JSON-LDは表示される文字列とは別の場所に記述します。
また、ソース内の場所もheadやbodyの中など、任意の場所に置くことができます。

JSON-LDのマークアップは下に示すようにscriptタグの中に記述します。
scriptタグとなっていますが、Javascriptなどが実行されるわけではなく、JSON-LDを使う際の決まりです



記述例


```

<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "Corporation",
  "name": "サクラサクマーケティング",
  "address": {
    "@type": "PostalAddress",
    "postalCode": "150-0022",
    "addressRegion": "東京都",
    "addressLocality": "渋谷区",
    "streetAddress": "恵比寿南1-24-2 EBISU FORT 5F"
    },
  "telephone": "+81367122480",
  "URL": "http://www.sakurasaku-marketing.jp/"
}
</script>
```


## まとめ
構造化データを用いてHTMLを記述すると、リッチスニペットなどによって人がウェブページの内容を理解しやすくなるほか、ロボットにも内容を的確に伝えることができるようになる。
とはいえ、構造化データを使わない場合に比べて設置や管理コストも増えますので、それを考えた上で判断する

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
単語も復習もかねて、
・ナレッジグラフ
Googleが検索キーワードからユーザーの得たい情報を推測し、検索キーワードに関連する情報をまとめて表示してくれる機能

・クローラー
Web上を自動巡回して文書や画像などの情報を取得・データベース化するプログラムのこと。
[go-ethereum]Transaction送信時に「Returned error: insufficient funds for gas * price + value」が発生する

# 記事の内容
gethを使ってTransaction送信の動作確認を行っている際に「Returned error: insufficient funds for gas * price + value」というエラーが発生
かなりハマってしまったので対応内容をメモとして残します。

# 環境
geth：v1.9.8-stable-d62e9b28/linux-amd64/go1.13.3

# 参考サイト
[Ethereum入門](https://book.ethereum-jp.net/)

# エラーの原因（insufficient funds for gas * price + value）
このエラーの原因ですが、「geth init」時に指定するgenesis.json内のchainIdとgeth起動時の「--networkid」が異なる状態でTransactionの送信を行うと発生する様です。

そこで、genesis.jsonと起動コマンドを確認しました。

~~~ myGenesis.json
{
  "config": {
    "chainId": 1111
  },
  "nonce": "0x0000000000000042",
  "timestamp": "0x0",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "",
  "gasLimit": "0x8000000",
  "difficulty": "0x4000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x3333333333333333333333333333333333333333",
  "alloc": {}
}
~~~

~~~
geth --networkid 1111 --nodiscover --datadir "/home/eth_private_net" console 2>> /home/eth_private_net/geth_err.log
~~~

chainIdと--networkidは一緒の値になっていました。
この状態でGeth JavaScript Consoleから送金処理を行っても、txPoolのPendingに溜まったまま処理がされませんでした。

Geth JavaScript ConsoleでchainIdを確認してみます。

~~~
> eth.chainId()
"0x0"
~~~
"0x0"？？
何かがおかしい


# genesis.jsonの設定内容
どうもgethの1.4と1.5の間でgenesis.jsonの設定内容が大きく変わった様です。
とりあえず、以下のサイトに載っている内容でgenesis.jsonの設定内容を修正してみます。

[Go Ethereum](https://geth.ethereum.org/docs/interface/private-network)

~~~ genesis.json
{
  "config": {
    "chainId": 1111,
    "homesteadBlock": 0,
    "eip150Block": 0,
    "eip155Block": 0,
    "eip158Block": 0,
    "byzantiumBlock": 0,
    "constantinopleBlock": 0,
    "petersburgBlock": 0,
    "ethash": {}
  },
  "difficulty": "1",
  "gasLimit": "8000000",
  "alloc": {}
}
~~~

この内容でgeth initを行い、Transactionの送信を行ったところ無事にTransactionがブロックに取り込まれることを確認出来ました。

~~~
> eth.chainId()
"0x457"
~~~
chainIdも設定した内容が正しく表示されました。

# 所感
ブロックチェーンはバージョンのアップデートが頻繁に行われる技術なので最新のモジュールを扱う場合は公式ドキュメントをちゃんと見ないといけないなと教訓を得ました。。