OmniAICreator/Qiita-1.07M huggingface dataset:
Webシステムのセキュリティ対策まとめ　-WAF-

#WAFとは？


Webアプリケーションの脆弱性を悪用した攻撃への対策のひとつにWAFがあるので
今回アウトプットしていきたいです。

https://qiita.com/kinoshitaken123/items/6cb68a7d33c4e02dd080

ファイアウォールやIPS/IDSとどのように違うか、その点について纏めてみたいと思います。

WAFはWeb Application Firewallの略。

Webアプリケーションの脆弱性を突いた攻撃へ対するセキュリティ対策のひとつ。

__WAFが開発された背景__

IDS、IPSを使うと、DoS攻撃など不審な通信が発生する攻撃は防げる。　　　
　　　　　　　　　　　　　　　↓

懸念点としてIDS、IPSは通信の中身まではチェックできない。クロスサイトスクリプティング、SOLインジェクションのようなユーザーから送信される悪意な攻撃は防げない。
 　　　　　　　　　　　　　　　↓
そこで開発されたのが、やりとりされるパケットの中身をチェックして悪意のデータが含まれていないのか確認するのがWAF

#WAFの仕組み

WAFでは、攻撃の検知に「シグネチャ」を用いる。
シグネチャとは、アクセスのパターンを記録しているもの。Webアプリケーションへのアクセスのパターンを、シグネチャを用いて照合し、通信可否の判断を行う仕組み。

シグネチャの定義の方法には、ブラックリスト型とホワイトリスト型があります。

#ブラックリスト型
ブラックリスト型では既知の攻撃パターン、すなわち「拒否する通信」をシグネチャに定義しておき、シグネチャに一致する通信を拒否する。

#ホワイトリスト型
ホワイトリスト型は、「許可する通信」をシグネチャに定義し、シグネチャと一致しなかった通信についてはすべて拒否し、不正アクセスの防止する。
UnityアプリにAndroidのシステム権限を持たせる方法

# 概要
Unityで作成したAndroidアプリにサイレントインストール機能やアンインストール機能をはじめとした、「システム権限がないと実行できない機能」を使いたい時があると思います。こちらの設定方法について解説します。

# 設定方法
AndroidManifest.xmlの先頭に以下のコードを入力してください。

```
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:sharedUserId="android.uid.system">
```

利用する端末、目的等では別途追記する項目があるかと思います。

```
android:sharedUserId="android.uid.system"
```

こちらのコードを先頭に追記するだけで、システム権限を要する処理をAndroid上で行える様になります。


以上で設定完了となります。
また、Android端末にインストールするには署名を行う必要があります。
9.19振返) 要確認#テストのエラーの読み方、探し方(デバッグしてログを見る)

<h2>教えてもらったこと</h2>
```
- テスト(今回の場合controller＿spec)に問題があるのではないか？
 - Factoryに問題がないか？
 - pathに問題がないか？
 - paramsに問題がないか？

- 実装(今回の場合controller.rb)に問題があるのではないか？
  - ストロングパラメータに問題がないか？
  - インスタンスは作成されるか？
  - インスタンスは保存されるか？(=バリデーションに引っかからないか？)
→　binding.irbをぶちこんで見る

共通：
ログは読む。
- デバッグしながらログの流れを「ちゃんと」見る「ちゃんと!」
```

<h2>同じテストコードの記述を２回かましてエラーになった</h2>
```
今回の流れ：
今回の場合、両方（テスト＆実装）を確認して特に問題がない
↓
リクエストが2回発生しているのを発見
↓
テストで2回リクエストしている
(テストの書き方の修正が必要)
```

<h2>ActiveSupport::MessageVerifier::InvalidSignature:　また頭真っ白</h2>

```ruby:ターミナルエラー部分
2) Patient::Ostomies ログインしている場合 PATCH /patient/ostomies/:id 更新する
     Failure/Error: if @ostomy.update(ostomy_params)
     
     ActiveSupport::MessageVerifier::InvalidSignature:
       ActiveSupport::MessageVerifier::InvalidSignature
     # /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activestorage-5.2.6/app/models/active_storage/blob.rb:47:in `find_signed'
     # /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activestorage-5.2.6/lib/active_storage/attached.rb:30:in `create_blob_from'
     # /home/ec2-user/.rvm/gems/ruby-2.6.3/gems/activestorage-5.2.6/lib/active_storage/attached/one.rb:24:in `attach'
     # /home/ec2-user/.rvm/gems/ruby-2
```
<h2>ログ直下にのactivestorageは画像投稿のgem</h2>
<h２>デバッグしながらログの流れを見る</h2>
<p>画像がfactorybotやletで設定されていないため起こったとわかる</p>
<p>今回はバリテーションもかけてないため記述を消した</p>

```ruby:request/patient_ostomy.rb
RSpec.describe "Patient::Ostomies", type: :request do
  let(:patient) { FactoryBot.create(:patient) }
  let(:ostomy) { FactoryBot.create(:ostomy, patient: patient) }

  context 'ログインしている場合' do
    before do
      sign_in patient
    end
    let(:ostomy_params)do
    {
    patient_id: patient.id,
    color: 'pink',
    edema: 'normal',
    skin: 'same',
    h_size: '30 ',
    w_size: '30',
    comment: 'ok',
    #image: '',   #ここを消した※バリテーションもかけてないのでOK
    }
    end
```
<h2>画像にtrueでバリテーションかける場合はletやfacotrybotであらかじめ設定する必要がある。</h2>
```
# after(:build) do |dialy|
      #   dialy.attached = fixture_file_upload(Rails.root.join('spec/fixtures/images/no_image.jpeg', 'image/jpeg'))
      # end
```
https://qiita.com/ratovia/items/c9dbb00e4f663a7a7ef9


<h2>コントローラーのテスト作成中のエラー</h2>
<p>テストコードだけでなく、テストしている部分にもデバックする</p>
```ruby:
class Patient::DialiesController < ApplicationController
 before_action :authenticate_patient!
 :
 :
  def create
       binding.irb
    @dialy = Dialy.new(dialy_params)
    @dialy.patient_id = current_patient.id
   if @dialy.save
     redirect_to patient_dialy_path(@dialy)
   else
     render :new
   end
  end
```
 @dialy = Dialy.new(dialy_params)一個ずつ入れてbyebugする
Blenderでアオリ補正カメラを作成する

通常の3Dソフトでカメラを上下に回転させた場合
オブジェクトの縦方向のエッジが奥方向が細くなって表示されます。
一部の建築系に利用されるソフトでは強制的にこのラインを垂直に揃える機能がありますが
Blenderでは直観的にこれを行う機能は搭載されていません

カメラのシフト機能を利用して　同等の効果のカメラを作成するスクリプトを作成してみました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/fbe82a77-c7b3-bf36-3ee2-91547f51dada.png)
左が通常のシーンで利用しているカメラの像
右は今回のスクリプトで作成したカメラで　ビューのローカルカメラに設定して表示しています

カメラを水平に表示している状態で　シフト機能で方向を調整することで縦方向を垂直にできています。

```py:TiltCorrection.py
import bpy
import math
scene = bpy.context.scene
camera = scene.camera
render = scene.render
# 現在のシーンのカメラから値を計算
rotate_x = camera.rotation_euler.x -math.pi/2
aspect = render.resolution_y /max(render.resolution_x, render.resolution_y)
angle_y = camera.data.angle *aspect/math.cos(rotate_x)
y_ratio =  0.5*math.tan(rotate_x)/math.tan(angle_y/2)
# アオリ補正したカメラを作成
copy_data = camera.data.copy()
shift_cam = bpy.data.objects.new('shift_cam', copy_data)
scene.collection.objects.link(shift_cam)
shift_cam.location = camera.location
shift_cam.rotation_euler.order = 'XYZ'
shift_cam.rotation_euler.x = math.pi/2 # カメラを水平に
shift_cam.data.angle = camera.data.angle /math.cos(rotate_x)
shift_cam.data.shift_y = y_ratio
```
シーンで現在利用しているカメラのデータを元にアオリ補正カメラを作成します。
なお、Blenderの機能の都合上　レンダリング画像のアスペクト比を変更すると再度スクリプトでカメラを作り直す必要があります
既存のGitHubPagesリモートリポジトリと新たなローカルリポジトリを結びつけた際の死闘まとめ

## あらまし
予めGitHub上で作成しておいたGitHubPagesのリポジトリに対して、新たなローカルリポジトリ（今回の場合全く別の場所にあるディレクトリ）を結びつけた際に、大変な苦労と一部ファイルの損失（バックアップのおかげで全損は免れました）があったので、解決に向けて行った過程を残しておこうと思います。  
動作環境は、MacOS 10.15.7 です。
ちなみに自分はGit初心者です。よろしくお願いします。

## 最初にやりたかったこと（思い描いていた理想の動作）
remoteコマンドでリモートとローカルを結びつけた後、add→commit→pushと行きたかった。。

~~~
# 1. 結びつけたいディレクトリをgit配下に置く
$ git init

# 2. リモートに結びつける(ssh接続)
$ git remote add origin git@github.com:ユーザ名/リポジトリ名.git
# 私の場合
$git remote origin git@github.com:sts11142/sts11142.github.io.git

# 3. ステージング
$ git add *

# 4. コミット
$ git commit -m 'demo commit'

# 5. プッシュして完了
$ git push origin main
~~~

## つまずいた箇所
### No1: 2. リモートに結びつける(ssh接続)  
今回はssh接続で通信した訳ですが、まずこれがうまく行きませんでした。  
と言っても、ssh用の設定をしなければならないことは以前から知っていましたし、設定方法の解説記事も沢山あったので特に苦労もなく解決しました。  
具体的な方法はこちらの記事を参考にさせていただきました。
[GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)

公開鍵をGitHub上にアップする際の"Title"欄は、自分で分かるように適当に決めてください。
なお自分の場合、鍵をアップした後そのまま接続がうまくいったので、接続確認以下の手順は行なっていません。
そして再度 ` $ git remote add ... `のコマンドで無事リモートとローカルを結びつけることができました。  

### No2: 5. プッシュ
ssh接続がうまくいき、ステージングとコミットまではいけたのですが、pushの部分でエラーが出ました。
エラーログを残し忘れたので再現が難しいのですが、原因を探していたところ`$ git rebase`云々という方法があるらしいということで試してみました。
試す中でもエラーが出て、pullやfetchなど色々行なった挙句、よく分からなくなったので`$ git rebase --abort`で最初の状態に戻そうとしたところ、一部のファイルが消失してしまいました。
幸いバックアップがあったので難を逃れましたが、本当に焦りました。  
最終的には、GitHubに直接ファイルをアップロードしてから`$ git pull`してadd→commit→pushと行いました。  

## 最後に
エラーの解決方法を残すつもりが、よく分からないまま作業していたせいで結局何も有益な情報を共有することができませんでした。  
今回の結果を踏まえて、状態の整理とエラーログを残すことの大切さを実感したので、今後は再現性を意識して作業（エラーの対処）に取り組んでいこうと思います。  
  
ここまで見てくれてありがとうございました。
AtCoder ABC219 Pythonでコンテスト初挑戦！

プログラミング初心者のkoheiと申します。Qiita初投稿です。
仕事で、少しずつPythonを使う機会が増えてきたため、本格的に勉強を開始しました。メインは、データサイエンスですが、AtCoderにはまってしまいました。

というわけで、9/18開催のAtCoderのABC219にて、コンテスト初挑戦です！

### ABC 219A 

```Python:ABC219A
X=int(input())

#if文で判定し、上のランクまでの点数を出力
if X>=0 and X<40:
    print(40-X)
elif X>=40 and X<70:
    print(70-X)
elif X>=70 and X<90:
    print(90-X)
else:
    print('expert')
```

A問題は、問題文そのままif文を記述するのみ。5分くらい。

### ABC219B

```Python:ABC219B
#文字列をリストに入れる
S_list=[]
for i in range(3):
    S_list.append(input())
    
T=input()

# Tを1つずつ左から取り出して、数字に対応する文字列を連結していく
answer='' #空の文字列
for i in T:
    answer=answer+S_list[int(i)-1]
print(answer)
```
B問題は、Tの文字に対応する文字列を出力する問題。
文字列をリストに入れることで、if文を書かなくていいようにした。
10分くらい。

### ABC219C

```Python:ABC219C
#新しいアルファベット順X
X=input()
X_list=[]
for i in X:
    X_list.append(i) 

#N人
N=int(input())

#N人の名簿リスト
name_list=[]
for i in range(N):
    name_list.append(input())

#それぞれの文字列を、X_listのインデックスの番号に置き換える。
N_alp_index=[]#それぞれの名前を数字に変換した後の格納用リスト
for i in range(N):
    
    name=name_list[i]#名前を格納
    alp_index=[]#初期化
    for s in name:
            for j in range(26):
                if s==X_list[j]:
                    alp_index.append(j)
                    break
                else:
                    pass
    N_alp_index.append(alp_index)

#数字に置き換えたもリストを並び替える。
sorted_list=sorted(N_alp_index)

#あとは数字をもとに戻して順番に出力する
for i in sorted_list:
    string=''#初期化
    for j in range(len(i)):
        string+=X_list[i[j]] #数字をX_listの文字列に戻して、つなげて出力
    print(string)
```
C問題。ここをとるのを今回の目標にしていた。
sorted()関数で、辞書順に並び替えることができるが、新しい辞書順Xにどう落とし込むのかがわからなかった。
よって、地道に文字列を新しい辞書順のインデックスとして格納してから、sorted()で並び替えて、元の文字に戻す方法をとった。
辞書順X: bacdefghijklmnopqrstuvwxzy
文字列1: abx→[1, 0, 23], 文字列2: bzz→[0, 24, 24]...以下同

これをリストに格納して、sorted()で並び変え
sorted([[1, 0, 23], [0, 24, 24] , ...])
→[[0,24, 24],[1, 0, 23]...]
で、数字をもとの文字列に戻して出力

時間はかかったが、もともとD問題以上は解けないというのがわかってたので、時間は十分にあった。無事、ACで、一安心。
Cまで完答できれば、茶色まではいけると思うので、次回も頑張りたい。

反省としては、やはりC問題。もう少しスッキリ書けそうな気がしたので、スマートな方法を調べてみた。
###方法: sorted()のkeyへの指定を工夫する方法 

https://qiita.com/c-yan/items/5805447c17f732369521

```Python:ABC219C_@c-yanさんのコード
X=input()
N=int(input())
S=[input() for _ in range(N)]

t={}
for i in range(26):
    t[X[i]]=chr(i+ord('a')) 

print(*sorted(S, key=lambda s: ''.join(t[c] for c in s)), sep='\n')
```
コードが短すぎてレベルの差を痛感しました。
なんとなく、sorted()のkeyにlambda関数でうまく新しい辞書順を反映できれば、実現できるというのはわかっていましたが、まったくその方法がわからず、めちゃくちゃ長いコードを書いていました。

・ポイント
tに、新しい辞書順Xと、元のアルファベット順の辞書を作っています。
t={'b': 'a', 'a': 'b', 'c': 'c', 'd': 'd', 'e': 'e', 'f': 'f', 'g': 'g', 'h': 'h', 'i': 'i', 'j': 'j', 'k': 'k', 'l': 'l', 'm': 'm', 'n': 'n', 'o': 'o', 'p': 'p', 'q': 'q', 'r': 'r', 's': 's', 't': 't', 'u': 'u', 'v': 'v', 'w': 'w', 'x': 'x', 'z': 'y', 'y': 'z'}

```
sorted(S, key=lambda s: ''.join(t[c] for c in s)
```
上記の部分で、tの辞書を基に、文字を置き換えてから、sortしています。
abx→ a:b, b:a, x:z →baz
bzz→ b:a, z:y, z:y →ayy

現実的には、上記のコードを今のレベルで実装するのは無理だったと思うので、長ったらしいコードでしたが、これでよかったと思います。何が何でもCをもぎ取るのです。

リスト内包表記や、lambda無名関数の使い方など、知識としてはわかっていても、実際に使えるレベルには至っていないので、上級者の方のいいコードを見てどんどん学んでいきます。
次週も頑張りたいと思います。過去問のB, Cを解きまくります！
MTGAのパック購入がめんどいので自動化する

# はじめに
<!-- 発端や概要を記載 -->
## MTGA
MTGAというゲームがあります。
MTGというカードゲームをオンラインで楽しめるってことで
結構僕も楽しんでます。

##カードの購入
リアルと同じようにMTGAでもパックを購入してカードを集めていきます。
ここで購入の方法は2つあります。

1. Gold(無課金)
1. Gem(課金）

##Goldで買おうとすると
**このゲームはGoldではパックのまとめ買いができません。**
つまり20パックをGoldで買う場合、これを20セットやらなきゃだめです。

1. 購入するパックを選択
1. 購入確認
1. 購入完了確認

![store.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1580330/433caebd-dc38-047c-46e3-70eeaed05a93.png)
![confirm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1580330/c89efca1-4fd7-18dd-a75b-2bae2f830ef6.png)
![ok.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1580330/c4bb4b37-8953-d663-da33-6796b6ba1205.png)

ご丁寧にクリック位置も違うので正直嫌がらせレベルでめんどいです。

##自動化しよう
毎回これやるのはしんどいので、pyAutoGUIを使って半自動化していきます。


# 目次
<!-- タイトルとアンカー名を編集 -->
[1.clickする位置を確認する](#1-clickする位置を確認する)
1. [指定座標にmoveしてclickする](#指定座標にmoveしてclickする)
1. [loop](#loop)

<!-- 各チャプター -->
#2. 内容い
#3. 内容ろ

#1. clickする位置を確認する
##まずクリックする座標を取得します。
1. 購入するパックを選択するボタンの座標
1. 購入確認ボタンの座標
1. 購入完了確認ボタンの座標

たぶんこの記事がわかりやすいかと
https://qiita.com/deaikei/items/7f1acaa3b1db40c33f1a

```Python
>>>pyautogui.position()
(255, 939)
```

調べたところ僕のモニタではそれぞれの座標はこんなふうになりました。

1. 購入するパックを選択するボタンの座標(206,880)
1. 購入確認ボタンの座標(1072,939)
1. 購入完了確認ボタンの座標(1685,1012)


# 指定座標にMoveしてClickする
##クリックする座標が取得できたので、それらを引数にとるMove+Clickのメソッドを作っていきます。
```Python
def click_button(x,y): 
  #3購入完了確認ボタンのときに使用するメソッド
  time.sleep(4) #パック購入の演出が入るので余裕を持ったSleep
  pyautogui.moveTo(x,y)
  pyautogui.click()

def click_twice(x,y): 
  #1.2.購入ボタン、購入確認ボタンのときに使用するメソッド
  time.sleep(4)　#パック購入の演出が入るので余裕を持ったSleep
  pyautogui.moveTo(x,y)
  pyautogui.click()
  pyautogui.mouseDown()
  pyautogui.mouseUp()
```

##click_twice
click_twiceはもともとclick_buttonで対応してたんですが、
なんだかうまいこと行かないので試行錯誤したものです。

<a id="#loop!"></a>
# loop!
##あとは回数を定めてループすればよいですね。
```Python
def my_main(times):
  for i in range(times):
    click_twice(206,880) #購入ボタンをクリック
    click_twice(1072,939)　#購入確認ボタンをクリック
    click_button(1685,1012) #購入確認完了ボタンをクリック

my_main(10) #購入したい個数を引数とする
```
【Laravel】エスケープした文字列をマークアップする方法

#はじめに#
　ポートフォリオ制作の過程で、データベースから取得したデータをマークアップしたい、という課題にぶつかり、見事にハマりましたので備忘録を残していきます。

#Laravelのbladeテンプレート#
　例えば、データベースにこのようなデータを挿入したとします。

>昔々あるところに、おじいさんとおばあさんがおりました。おじいさんは山へ芝刈りに、おばあさんは川へ洗濯に行きました。

これをmodelで取得、controllerからviewに渡して表示すると、当然そのまま表示されます。そこで、改行を入れたり、おじいさん、おばあさんを赤字で表記したい場合、どうすればいいでしょうか。

データベースから取得したデータをviewで表示する際、bladeテンプレートでは{{ $data }}などとしますが、取得したデータはデフォルトでHTMLエスケープ処理がされているので、自動的にXSS対策がされています。
　実は、{!! $data !!}とするとHTMLエスケープをせずに出力することが出来ます。なので直接HTMLタグを入力すればマークアップすることが出来ますね！！


・・・というわけにはいかず、やはりセキュリティの面からもエスケープ処理は必須です。

それでは、どのようにして実装していけば良いのでしょうか。


#どうすればいいか#
　jQueryを使ってこの問題を解決してみましょう。
まずは出力側をこのようにしてみます。

```php:momotaro.blade.php
 <div class="content">
    {{ $data }}
 </div>
```
なんでもいいのでクラスを与えます。
次にjsファイルにこのように記述します。

```momotaro.js
$(function(){
  var str = $('.content').text().replace(/\[/g, '<span class="red">')
  .replace(/\]/g, '</span>')
  .replace(/\|/g, '<br>');
  $('.content').html(str);
})
```

最後に、cssファイルにこのように書き加えてください。

```style.css
  .red{ 
    color: red;
  }
```

さて、これで準備完了です。
それでは、データ挿入時にこのように入力してみましょう。

>昔々あるところに、[おじいさん]と[おばあさん]がおりました。|[おじいさん]は山へ芝刈りに、[おばあさん]は川へ洗濯に行きました。

これを出力すると下記のようになります。

![スクリーンショット 2021-09-19 22.07.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558223/a6305ab9-dab4-77dc-8e33-b606d21389ac.png)

見事、思い通りのマークアップをすることが出来ました！

まず、jQueryのtextメソッドを使ってcontentというクラスの内容を取得しています。そして取得した内容に対してreplaceメソッドを使って、その中の[や]や|という記号をそれぞれ、\<span class="red">や\</span>や\<br>に置き換えています。これがbladeテンプレート内でHTMLタグとして認識され、マークアップ出来たというわけです。

#まとめ#
　この方法でデータをマークアップすることが出来ますが、マークアップの種類に限りがあること、置き換えられた記号は使うことが出来ないことなど、色々と問題があります。
もっと良い方法があれば教えて頂きたいです！
ABC209 C - Not Equal から学んだ

https://atcoder.jp/contests/abc209/tasks/abc209_c

![abc209_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/fd218e9b-bdb0-4e93-00df-7b37c0ffb727.png)
![abc209_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/d6c0902d-a529-dfeb-2b6f-cdb13002579e.png)
![abc209_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/62bcbd62-9dd9-08b1-2c8f-2104d28da160.png)

うむ。結局、階乗で行けるのでは？
樹形図としては並び替えれば行けるんじゃね？

。。行けた。

```NotEqual.py
n = int(input())
C = list(map(int,input().split()))
C.sort()
score = 1
for i in range(n):
    score *= C[i]-i
    score %= (7+10**9)
print(score)
```

解説もそれっぽい。

https://www.youtube.com/watch?v=FEDp2Kzc7jk
Java17の新機能をざっくり紹介

# この記事について

2021/9/14 にリリースされた JDK17 の新機能をざっくりまとめます．[^sad] 情報源は基本的に[OpenJDKのサイト](https://openjdk.java.net/projects/jdk/17/)です．

[^sad]: 以前はリリース前から新バージョンの記事がたくさんあったのに，最近減ってきた気がする…

特に筆者が詳しくない分野については雑に要約してあります．それぞれの詳細は JEP の原文や他の記事などを参照してください．

## [JEP 306](https://openjdk.java.net/jeps/306): 常に厳密な浮動小数点演算の復活[^restore]

[^restore]: Java SE 1.2 より前と同じ挙動に戻ったらしいです．

`strictfp` 指定時と通常時の差を無くし，浮動小数点演算が常に厳密になりました．ほとんどのユーザーには大して影響がないと思われます．

現代のプロセッサでは厳密・非厳密に分けるメリットが薄れたということのようです． `strictfp` の使用は無意味になったので，警告が出るようになりました．

```
警告:[strictfp] as of release 17, all floating-point expressions are evaluated strictly and 'strictfp' is not required
```


## [JEP 356](https://openjdk.java.net/jeps/356): 疑似乱数生成器の強化

乱数生成器を交換可能な形で使えるようになりました．

これまで乱数生成を行うクラスが複数[^legacyrandoms]あったのが，新しい `java.util.random.RandomGenerator` インターフェースで統一的に扱えるようになりました．ファクトリクラスも追加されました．

[^legacyrandoms]: `Random`, `SecureRandom`, `SplittableRandom`, `ThreadLocalRandom`


## [JEP 382](https://openjdk.java.net/jeps/382):  新しい macOS の描画パイプライン

Apple Metal API を使ったJava 2D 内部パイプラインが実装されました．
これまでは OpenGL API を使った実装のみでした．


## [JEP 391](https://openjdk.java.net/jeps/391): macOS/AArch64 port

Appleの独自プロセッサに対応しました．


## [JEP 398](https://openjdk.java.net/jeps/398): アプレットAPIを削除予定に指定

Java9 から非推奨になっていた Applet API が，さらに `forRemoval=true` になりました．


## [JEP 403](https://openjdk.java.net/jeps/403): JDK内部の強いカプセル化

`sun.misc.Unsafe` のような重要な内部APIを除く，
JDKの内部要素のカプセル化が強化されました．

今回の変更では，`--illegal-access` コマンドラインオプションによる制限緩和ができなくなりました．


## [JEP 407](https://openjdk.java.net/jeps/407): RMI Activation の削除

RMI のうち，Java15 から `forRemoval=true` な非推奨になっていた RMI Activation が削除されました．


## [JEP 409](https://openjdk.java.net/jeps/409): Sealedクラス

継承を制限する `sealed` クラスが正式に追加されました．

[別の解説記事](https://qiita.com/ReiTsukikazu/items/710c60745f757cc103df)を書いたので，良ければご覧ください．

## [JEP 410](https://openjdk.java.net/jeps/410): 実験的なAOT・JITコンパイラを削除

AOT&JITコンパイラは追加以降あまり使われておらず，メンテナスコストがかかるので削除されました．
コンパイラ作成に必要なインターフェースは維持されます．
Graalコンパイラを使いたければGraalVMが使える，とのことです．


## [JEP 411](https://openjdk.java.net/jeps/411): Security Manager を削除予定に指定

Security Manager が `forRemoval=true` の非推奨になりました．

アプレットの削除に伴い必要性が薄れたこと，現在知られている多くのリスクに Security Manager では十分対処できないこと，適切に使うのが難しくあまり利用されていないこと，Security Manager の存在により標準クラスライブラリのテストコストが大きく増大していることなどが理由です．

`System.exit` の禁止など，代替手段については検討中のようです．



 
## [JEP 415](https://openjdk.java.net/jeps/415): コンテキスト固有のデシリアライズフィルタ

Java9から導入されていたシリアライズ復元時のフィルタと異なり，デシリアライズ操作ごとにフィルターを設定しやすくなったようです．


---


ここからは正式実装ではなく試験的な機能です．


## [JEP 406](https://openjdk.java.net/jeps/406): `switch` パターンマッチング (Preview)

case でのパターン指定や `case null` の追加等が予定されています．


## [JEP 412](https://openjdk.java.net/jeps/412): Foreign Function & Memory API (Incubator)

JNIを使わずに，Javaランタイム外部のコード・データとの相互運用を行うAPIの導入が予定されています．
以前からIncubatorだった Foreign-Memory Access API と Foreign Linker API を一つのJEPにまとめたようです．


## [JEP 414](https://openjdk.java.net/jeps/414): Vector API (Second Incubator)

実行時に適切にコンパイルされるようベクトル演算を表現するAPIの導入が予定されています．
エクセルでUTC時刻をJST時刻へ変換する方法（関数とVBA）

# はじめに

あるテーブルのデータをエクセルに貼り付けて調査をしていた時に、UTC時刻で登録されており分かりにくかったためJST時刻へ変換しました。
関数とVBAでのやり方を残したいと思います。

# 関数

```text
=DATEVALUE(MIDB(A1,1,10))+TIMEVALUE(MIDB(A1,12,8))+TIME(9,0,0)
```

A1にUTC時刻の文字列が入力されている場合の関数です。
必要に応じて「A1]部分を変更してください。

以下のような仕組みです。

1. 日付部分を日付として取得する（DATEVALUE(MIDB(A1,1,10))）
1. 時刻部分を時刻として取得する（TIMEVALUE(MIDB(A1,12,8))）
1. 時刻を+9加算する
1. 日付に時刻を加算する

![20210919.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157383/17b77572-bf0e-5ecd-17c1-b3bc30897196.jpeg)

B2のように、日付を跨ぐ場合でもしっかりと変換されています。


# VBA

```vb
'UTC時刻の文字列をJTC時刻へ変換してDate型で返す
'
'@param utc UTC時刻の文字列
'@return jtcDateTime Date型のJTC時刻
Function ConvertUTCToJTC(ByVal utc As String) As Date

    Dim utcDate As String
    utcDate = Left(utc, 10)
    
    Dim utcTime As String
    utcTime = Mid(utc, 12, 8)
    
    Dim jtcDateTime As Date
    jtcDateTime = utcDate & " " & utcTime
    jtcDateTime = DateAdd("h", 9, jtcDateTime)

    ConvertUTCToJTC = jtcDateTime
End Function
```

```vb:実行サンプル
Sub ConvertUTCToJTCTest()

    Debug.Print ConvertUTCToJTC("2021-08-10T10:00:00Z")
    Debug.Print ConvertUTCToJTC("2021-08-10T22:00:00Z")

End Sub
```

```text:実行サンプル結果
2021/08/10 19:00:00 
2021/08/11 7:00:00 
```

引数の文字列型のUTC時刻をJTC時刻へ変換してDate型で返します。
関数とほぼ同じ仕組みです。

1. 日付部分を文字列で取得する
1. 時刻部分を文字列で取得する
1. 1と2で取得した日時からDate型の値を作成する
1. 3で作成したDate型に9時間加算する


# 参考
[[Excel] 協定世界時(UTC)を日本標準時(JST)に変換する計算式](https://a1-style.net/microsoft-365/iso8601-utc-convert/)
[DateAdd 関数](https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/dateadd-function)
Jetpack Compose で Firestore のサブスクリプションを利用する

## はじめに

Jetpack Compose には React のフックに似た仕組みがあり、その仕組みを利用することで Firestore のサブスクリプション周りの雑多な処理を関数として抜き出すことができます。

## 実装

次のコードは、`messages` コレクションに何らかの変化があったときにメッセージのリストを再生成する関数です。

```kotlin
data class Message(
  @DocumentId val id: String = "",
  val sender: String = "",
  val receiver: String = "",
  val content: String = "",
)

@Composable
fun rememberMessages(): List<Message> {
  val messages = remember { mutableStateListOf<Message>() }

  DisposableEffect(Unit) {
    val registration = Firebase.firestore
      .collection("messages")
      .addSnapshotListener { snapshot, e ->
        if (e != null || snapshot == null) {
          Log.e("ERROR", "listen:error", e)
          return@addSnapshotListener
        }
        for (dc in snapshot.documentChanges) {
          val doc = dc.document.toObject(Message::class.java)
          when (dc.type) {
            DocumentChange.Type.ADDED -> {
              messages.add(doc)
            }
            DocumentChange.Type.MODIFIED -> {
              val index = messages.indexOfFirst { it.id == doc.id }
              messages[index] = doc
            }
            DocumentChange.Type.REMOVED -> {
              messages.removeIf { it.id == doc.id }
            }
          }
        }
      }
    onDispose {
      registration.remove()
    }
  }

  return messages.toList()
}
```

`mutableStateListOf` を使うことで、ミュータブルかつ変更の検知可能なリストを作ることができます。このリストの要素を追加、修正、削除したときは再コンポーズが走ります。

`addSnapshotListener` により、`messages` コレクションの変更内容を知ることができます。もし既に `messages` コレクションに10個のドキュメントが存在するとき、ハンドラを登録したタイミングで `dc.type == DocumentChange.Type.ADDED` のブロックが10回呼ばれます。よって、たったこれだけのコードでドキュメント一覧の取得とサブスクリプションが完了しています。

呼び出し側では次のように書くだけです。

```kotlin
@Composable
fun MyScreen() {
  val messages = rememberMessages()
}
```

`messages` コレクションに何らかの変更が行われたときに `MyScreen` の再コンポーズが走ります。

## おわりに

まさか、ここまできれいに Firestore のサブスクリプション部分を関数として切り出せるとは思いませんでした。
ec2簡単にログインできるようにしよう(メモ）

##簡単なメモです

毎回EC2にログインの際`-i ssh 秘密鍵名.pem ec2-user@IPアドレス`を打ち込むのは面倒なのでショートカットできるようにします。
`config`に`Vim`で書き込みします。
下記をターミナルで入力。

```
% cd ~/.ssh
% vi config
```
INSERTモードにして書き込んでいきます。
接続先名は簡単なものが楽でいいと思います。

```
Host 接続先名
  HostName Elastic IPアドレス
  User ec2-user
  IdentityFile ~/.ssh/プライベートキーの名前.pem
```

もう一度yesと答えたらOKです。

```
% ssh 接続先名
```
これで簡単にログインできるようになります。
Zynq-7000 SoCとは

## Zynq-7000 SoCとは

ここでは Zynq-7000  について解説します(Zynq-7000Sについては解説しません。まぁそんなに差はないんですが)。

本記事の目的はDIGILENT製の[Zybo Z7ボード](https://digilent.com/reference/programmable-logic/zybo-z7/start)の勉強です。

---

### Zynq-7000 とは

Zynq-7000 とは、下記を１つのデバイスに組み合わせたものです。

- デュアルコアのArm® Cortex™-A9 ベースのプロセ ッ シング システム (PS) [^1]

- ザイ リ ンクスの 28nm プログ ラマブル ロジック (PL) 

![Zynq-7000_SoC_Block_opt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1894918/f49fac74-d280-a115-567e-09ddbd3d47a7.png)





[^1]: PS は Arm Cortex-A9 CPU を中核 と し て、オンチップメ モ リ 、外部 メ モ リ インターフ ェ イ ス、幅広い周辺接続インターフェイスを備えている。


---

### PSインタフェース

PSの外部インタフェースはPLピンとして割り当てることができない専用ピンを使用する。大別すると下記の3種となる。

- クロック、リセット、ブートモード、基準電圧
- 最大54の専用多目的I/O(MIO)ピン(内部のI/Oペリフェラルやスタティックメモリコントローラーへ接続するためにソフトウェアで設定を変更できる)
- 32ビットまたは16ビットのDDR2/DDR3/DDR3L/LPDDR2メモリ



#### MIO(Multiplexed I/O)について

MIOはPS部の外部インタフェース専用ピンです。ピン毎にどの機能に割り当てるかを選ぶことが出来るので「Multiplexed」となっています。



#### EMIO(Extended MIO)について

MIOが足りなくなった場合は、PLを経由してPLに関連するI/Oへの配線が可能です。PLにつながっている普通のIOをPS専用IOとして使用するわけです。

これをEMIO(拡張されたMIO)と呼びます。



#### Zynq-7000のMIO一覧表

![MIO一覧表_opt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1894918/c93a9e8b-5aeb-1946-a07f-118a83b2b086.png)




### 資料一覧

https://japan.xilinx.com/products/silicon-devices/soc/zynq-7000.html#productAdvantages

[Zynq-7000 SoC データシー ト](https://japan.xilinx.com/content/dam/xilinx/support/documentation/data_sheets/j_ds190-Zynq-7000-Overview.pdf)
[Zynq-7000 SoC テクニカル リファレンス マニュアル](https://japan.xilinx.com/content/dam/xilinx/support/documentation/user_guides/j_ug585-Zynq-7000-TRM.pdf)

https://digilent.com/reference/programmable-logic/zybo-z7/start
最小限の.bashrc, .vimrc, .tmux.conf

## .bashrc

```bash:~/.bashrc
# alias
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias ll='ls -l'
alias la='ls -a'
alias bashrc='vim ~/.bashrc'
alias vimrc='vim ~/.vimrc'
alias tmuxconf='vim ~/.tmux.conf'
alias ..='cd ..'
alias ...='cd ../..'
alias reload='exec $SHELL -l'

# alias for git
alias gs='git status'
alias ga='git add'
alias gd='git diff'
alias gds='git diff --staged'
alias gcm='git commit -m'
alias gl='git log --oneline --graph --decorate'
alias gp='git push origin HEAD'
alias gc='git checkout'

# prompt
export PS1="[\u@\h] \w \$ "

# execute ls after cd
cd ()
{
  builtin cd "$@" && ls --color=auto
}

if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi
```


## .vimrc

```vimscript:~/.vimrc
" 新しい行のインデントを現在の行と同じインデントにする
set autoindent
" vi互換を切る
set nocompatible
" タブの代わりに空白文字を挿入する
set expandtab
" インクリメンタルサーチを行う
set incsearch
" 行番号を表示する
set number
" 行番号を現在の行からの相対的な番号にする
set relativenumber
" 対応する括弧を表示する
set showmatch
" 検索時に大文字を含んでいたら大文字/小文字を区別する
set smartcase
" マウスを有効にする
set mouse=a
" シフト移動幅
set shiftwidth=2
" タブの空白数
set tabstop=2

" 文字化け対策
set encoding=utf-8
set fileencodings=iso-2022-jp,euc-jp,sjis,utf-8
set fileformats=unix,dos,mac

" 行番号のカラーを変更
highlight LineNr ctermfg=DarkGray
```

## .tmux.conf

```~/.tmux.conf
# prefixキーをC-aに変更する
set -g prefix C-a

# C-bのキーバインドを解除する
unbind C-b

# \ でペインを縦に分割する
bind \ split-window -h

# - でペインを横に分割する
bind - split-window -v

# マウス操作を有効にする
set-option -g mouse on

# 次のペインに移動
bind -n C-o select-pane -t :.+

# vimのキーバインドでペインをリサイズする
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

# ウィンドウの切り替え
bind -n S-left previous-window
bind -n S-right next-window

# ステータスバーの全体の色を変更
setw -g status-style fg=colour255,bg=colour234

# ステータスバーの中央パネルの色を変更
setw -g window-status-current-format '#[bg=colour2]#[fg=colour255]#{?client_prefix,#[bg=colour3],} #I #W '
setw -g window-status-format '#[fg=colour242] #I #W '

# 左パネルの設定
set -g status-left ""

# 右パネルの設定
set -g status-right ""

# ウィンドウリストの位置 (right/left/centre)
set -g status-justify right

# ステータスバーの位置 (bottom/top)
set -g status-position bottom
```
個人的に印象的な動画

#はじめに
講演やセミナーで、動画をみせていただくことがある。印象的だった動画をメモしておく。いつか、誰かに紹介する可能性が高そうなので。

# 印象的な動画
## dothetest，『Test Your Awareness: Do The Test』，2008
https://youtube.com/watch?v=Ahg6qcgoay4&feature=share
> How many passes does the team in white make? 
> （訳）白のチームは何回パスしますか？

白坂先生の講演で見せてもらった動画。
「人間の脳は認知したいことを自ら選択し、それ以外は無視する」ということを体験させてもらった。

以下の資料でも、白坂先生がこう述べている。
> 人は見たいものしか見ない
> 俯瞰的にものごとを捉えるのは簡単ではない
> だからこそ“武器”が必要

白坂成功，「システムズエンジニアリング入門　～IoT時代の価値実現に必須となるアプローチ～」
https://www.ipa.go.jp/files/000056124.pdf


## デレク・シヴァーズ，『社会運動はどうやって起こすか』，TED2010

https://www.ted.com/talks/derek_sivers_how_to_start_a_movement/up-next?language=ja

どなたの講演で見せていただいたかは不確か。ピョートル・フェリークス・グジバチさんだったかもしれない。
非常に示唆に富んだ動画。


## 中尾優作，『飯塚悦功の体験的システム解析工学概論』，2013

飯塚先生へのインタビュー動画。紹介していただいた動画ではなく、自分で見つけた動画ではあるが、こちらも、いつか誰かに紹介する機会がありそうなので、メモしておく。

https://youtu.be/PgjIwIP5oXw

https://youtu.be/Pqe0pP61UPk

https://youtu.be/CI1sw_ZK24M

https://youtu.be/I8FfQktmPFw

## 清水吉男，『SEC先端技術入門ゼミ【第5部】派生開発の未来を語る～今、派生開発の領域で何が起きているか、これから、どう対応するか～』，2015

清水さんの貴重な講演の動画

https://www.youtube.com/watch?v=-LOWtHwUIK4

# 関連記事

https://qiita.com/kazuo_reve/items/852dc6fce47f525dfd6c
Mypyの結果をGitHubでコメントしてくれるActionを作った

Mypyの結果をGitHubでコメントしてくれるGitHub Action(s)を作ったので、その使用方法と、GitHub Actionを作る過程などのメモです。
https://github.com/marketplace/actions/mypy-action

※もともとflake8を同様の形式で実行するものがあったので、それを参考に作成しています。
https://github.com/marketplace/actions/flake8-action

実行結果イメージ：
![スクリーンショット 2021-09-19 21.13.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94255/be264e91-1d1d-bc7e-9b76-70e97d60c1dd.png)

# 使用方法

flake8と併用する場合、以下のようなymlを作成して適当な場所に配置します。
例えば`.github/workflows/lint.yml`に配置します。

```yml
name: Lint

on:
  push:
    paths:
      - '*.py'

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - name: Setup Python
        uses: actions/setup-python@v1
        with:
          python-version: 3.8
          architecture: x64
      - name: Checkout
        uses: actions/checkout@v1
      - name: Install flake8
        run: pip install flake8
      - name: Install mypy
        run: pip install mypy
      - name: Run flake8
        uses: suo/flake8-github-action@releases/v1
        with:
          checkName: 'lint'   # NOTE: this needs to be the same as the job name
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        if: ${{ always() }}
      - name: Run mypy
        uses: sasanquaneuf/mypy-github-action@releases/v1
        with:
          checkName: 'lint'   # NOTE: this needs to be the same as the job name
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        if: ${{ always() }}
```

この設定の場合、*.pyに変更があった場合に限りflake8とmypyを実行し、エラーがあった場合にはコメントしてくれます。
併用した場合のコメントイメージは以下のようになります。
![スクリーンショット 2021-09-19 21.08.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94255/5eadda88-cbe7-a1a0-8b4b-d4c8a7ce4a6e.png)

# 作成の過程

## モチベーション
flake8/mypyを実行するGitHub Actionを探してみたところ、flake8ではコメントをつけてくれるそれっぽいものがあったので、mypyでも同じものを作ることにしました。

## リポジトリの作成
参考にしたのは
https://github.com/suo/flake8-github-action#readme
ですが、GitHubの画面左上に「generated from actions/typescript-action」と書いてあったので、このテンプレートを元にリポジトリを作成しました。

## dependabotのPRのマージ

テンプレートから作ったリポジトリですが、いきなりdependabotからPRが来ていたので、テストが壊れていなさそうなものについては試しにマージしてみます。（こんな軽い気持ちでマージしてよいのかという問題もあるのですが、今回はまだ誰も使い始めていないので、初回という事で試しにマージしてみました。）
※「Bump eslint-plugin-github from 4.1.1 to 4.3.0」のi18nのエラーについては、一旦ignoreする設定を組み込んだものの、マージを忘れていたので一旦そのままにしています。

## 実装
リポジトリをcloneするとmain.tsがあるので、flake8-github-actionの内容を参考にmain.tsの内容を書き換えます。

## 不要なコードの削除
サンプルの不要なwait.tsとそのテストを削除します。

## README.mdとaction.ymlの書き換え
README.mdとaction.ymlの内容を適当な内容に書き換えます。

## GitHubの画面からリリース（タグ）を作成
上記の内容を反映してGitHubにpushすると、GitHubのリポジトリの画面上にマーケットプレイスにリリースするかというリンクが表示されているので、そこからリリースを作成する画面に移動し、リリースを作成します。

## 他のリポジトリで参照して実行できることの確認
他のリポジトリで、flake8-github-actionと同様にmypy-github-actionを参照して動作することを確認します。

# 感想
GitHub Action(s)はだいぶ簡単に作れるんだなと思いました。
上記の手順についても、実際には「pushした後にリリースの画面でのメッセージによってaction.ymlの設定に気付く」というような事もあり、親切な画面になっているんだなと感じました。
個人的には、よく使っているCircle CIに対する不満は特にないのですが、GitHub上のコメントとしてflake8/mypyの結果を簡単に出せるのは、人によっては便利かなと思いました（flake8/mypyの結果はもともと行数とか出ているので、調べようと思えば簡単に調べられるものではありますが...）
Debian（WSL2）+Dockerの環境構築

WSL 2上にDebianをインストールした際の淡々とした記録です。

## アプリインストール
```bash
$ sudo apt update && sudo apt dist-upgrade
$ sudo apt install wget curl make git vim
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> ~/.profile
$ curl https://get.volta.sh | bash
$ source ~/.profile
$ brew install tfenv
$ tfenv install latest
$ tfenv use latest
$ volta install node@lts
$ volta install pnpm
```


## Docker Desktop for Windowsとの連携
1. Settings | Resources | WSL INTEGRATION
2. Enable integration with additional distros: で使いたいディストロをON

一番やりたかったDocker Desktop for Windowsを使ったWSL上での呼び出し。

ディストロが1つしか入っていない場合、デフォルトのディストロには自動でWSLインテグレーションシステムが発動する。

しかし、2つ以上の場合は、指定してONにしないとDocker Desktopとの連携が取れない。

この設定をすればWSL2上で `docker` コマンドが使えるようになる。


## Docker on WSL2
Docker Desktopが有料化したことを受け、DockerをWSL2のDebianへインストールする。

https://docs.docker.com/engine/install/debian/

まずは公式通りに。Docker Composeは[こちら](http://docs.docker.jp/compose/install.html#linux)から。そして、そのままでは `docker run` できない。WSL2側で動作しないので、追加で下記作業する。


```bash
$ touch /etc/fstab
$ update-alternatives --set iptables /usr/sbin/iptables-legacy
$ service docker start
```

## Docker on WSL2とPhpStormを接続する
DockerへはTCP接続できそうな感じだけど、設定をしても繋がらなかった。そこでいったん手軽にSSHで接続する。

```bash
$ sudo apt install openss-server
$ sudo vim /etc/ssh/sshd_config
# 適当にポートやセキュリティ設定を変える
$ sudo service ssh start
```
何かしらオーバーヘッドはありそうだが、とりわけ接続が遅いなどは感じられないので大丈夫そう。

あとはPhpStormの `File | Settings | Build, Execution, Deployment | Docker` からDockerへの接続にSSHを選択。

## Docker on WSL2とPhpStormのtcp接続
上で繋がらなかったと書いたけれど、追跡調査して繋がるようになった。

```bash
$ mkdir /etc/systemd/system/docker.service.d
$ sudo vim /etc/systemd/system/docker.service.d/override.conf
```
```ini
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375
```
```bash
$ sudo vim /etc/docker/daemon.json
```
```json
{"hosts": ["tcp://127.0.0.1:2375", "unix:///var/run/docker.sock"]}
```
```bash
$ sudo service docker restart
```

最後に、PhpStormの `File | Settings | Build, Execution, Deployment | Docker` から `TCP Socker` を選択。  
`Engine API URL` には `http://localhost:2375` を設定。

正直なにをやっているかサッパリ分からない……。ひとまずSSHでいいかな。

## 以上
今後また何かあれば随時更新予定。
壊れたUSBをntfsfixコマンドを使って治す on Ubuntu

注意:多分このやり方よりも安全でわかりやすいやり方があります。

### USBが壊れた原因

USBにisoファイルを保存させてアンマウントしたところでエラーが発生し、それ以降USBを指し直してもエラーが出るようになった。

そのエラー内容がこれ　

```
error mounting /dev/sdc1 at /media/user/other: Unknow error when mounting/dev/sdc1
```

### 治す
まずはエラーが出ているUSBを特定する。
幸いにも今回はUSB自体は認識されているので簡単だ。


まずはターミナルを開き、以下のコマンドを実行する。

```
$ cd /dev/disk/by-id
```

```
$ ls
```

これらを実行すればPCが認識しているディスクがズラーッと表示される。
その中で、エラーが出ているUSBを探す。
自分の場合はこれだった。

```
usb-SanDisk_Cruzer_Fit_4C53000102122011
```
無事特定できればそれをコピーしておく。

ここでタイトル回収「ntfsfix」を使う。

```
sudo ntfsfix コピーしておいたUSBの名前
```

これで実行すればおそらく治るだろう。
Linux: 使用できる言語について調べたい

たまたま調べる機会があったので、ついでにメモ。

###### 実施環境：

```Linux:Linux
[root@testhost ~]# uname -a
Linux testhost 4.18.0-331.el8.x86_64 #1 SMP Thu Aug 19 16:49:03 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
[root@testhost ~]# echo $SHELL
/bin/bash
```

日本語表示が必須なソフトウェア等を入れる時に、「このサーバは何の言語が使用できるんだっけ?」と調べたい時があります。
そのような時は、 locale コマンドを使用します。


```Linux:Linux
[root@testhost ~]# locale -a
C
C.utf8
en_AG
---------- ( 省略 ) ----------
en_ZW.utf8
ja_JP.eucjp
ja_JP.utf8
POSIX
```

上記の場合は、英語(en)と日本語(ja)が使用できるとわかります。
では、上記で出てこない言語を使用したい場合はどうすればよいでしょうか。

新しい言語を追加したい場合は、 glibc-langpack-* パッケージをインストールします。
利用できるパッケージの一覧は、 dnf list で確認できます。

```Linux:Linux
[root@testhost ~]# dnf list | grep "glibc-langpack-"
glibc-langpack-en.x86_64                               2.28-162.el8                                  @baseos
glibc-langpack-ja.x86_64                               2.28-162.el8                                  @baseos
glibc-langpack-aa.x86_64                               2.28-162.el8                                  baseos
---------- ( 省略 ) ----------
glibc-langpack-yuw.x86_64                              2.28-162.el8                                  baseos
glibc-langpack-zh.x86_64                               2.28-162.el8                                  baseos
glibc-langpack-zu.x86_64                               2.28-162.el8                                  baseos
```

では、試しにドイツ語(de)をインストールしてみます。

```Linux:Linux
[root@testhost ~]# dnf -y install glibc-langpack-de
Last metadata expiration check: 20:26:21 ago on Wed 25 Aug 2021 01:12:08 AM EDT.
Dependencies resolved.
---------- ( 省略 ) ----------

Complete!
[root@testhost ~]# locale -a
C
C.utf8
de_AT
---------- ( 省略 ) ----------
en_ZW.utf8
ja_JP.eucjp
ja_JP.utf8
POSIX
[root@testhost ~]# echo $LANG
en_US.UTF-8
[root@testhost ~]# date
Wed Aug 25 21:40:21 EDT 2021
[root@testhost ~]# LANG=de_AT
[root@testhost ~]# date
Mi Aug 25 21:40:57 EDT 2021
```

これで、ドイツ語が使用できるようになりました。

※ Mi = Mittwoch (ドイツ語で水曜日)
AtCoderログ：0117 - ABC 219 に参加しました

この記事は 2021年09月18日(土)21:00-22:40 に開催された [AtCoder Beginner Contest 219 (ABC 219)](https://atcoder.jp/contests/abc219) に参加した記録です。

https://atcoder.jp/contests/abc219

# 結果
- 得点：300 (=100+200)
- 時間：13:58 (= 13:58 + 05:00 × 0)
- 順位：5637 / 7348
- パフォーマンス：169
- レーティング：366 → 336 (-30)
- 段級位：9級

![2021-09-18_abc218.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1589302/2730bf08-2f7c-087d-58ab-716183e9dc0a.png)

# 詳細
|問題|得点|時間|提出コード|復習|
|:--:|:--:|:--:|:--:|:--:|
|[ABC 219 A](https://atcoder.jp/contests/abc219/tasks/abc219_a)|100|08:25|[○]()|[AtCoderログ：0118](https://atcoder.jp/contests/abc219/submissions/25930028)|
|[ABC 219 B](https://atcoder.jp/contests/abc219/tasks/abc219_b)|200|13:58|[○]()|[AtCoderログ：011*](https://atcoder.jp/contests/abc219/submissions/25933912)|
|[ABC 219 C](https://atcoder.jp/contests/abc219/tasks/abc219_c)|300|(2)|---|---|
|[ABC 219 D](https://atcoder.jp/contests/abc219/tasks/abc219_d)|400|---|---|---|
|[ABC 219 E](https://atcoder.jp/contests/abc219/tasks/abc219_e)|500|---|---|---|
|[ABC 219 F](https://atcoder.jp/contests/abc219/tasks/abc219_f)|600|---|---|---|
|[ABC 219 G](https://atcoder.jp/contests/abc219/tasks/abc219_g)|600|---|---|---|
|[ABC 219 H](https://atcoder.jp/contests/abc219/tasks/abc219_h)|600|---|---|---|

# 感想
- A, B まで完答できました。
- C は一通り回答ができたものの、WA を除去できず時間終了。
- 明らかに頭が働いていませんでした。
- レーティングは微減でした。そりゃそうだろうな。
 
# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0116 - ABC 149 C](https://qiita.com/RoadLynton/items/c2f951cf72e63610373d)
Jenkinsの基礎知識

# Jenkinsとは
CI/CDを構築するためのオープンソースツールの1つ。
Javaが動く環境であればLinuxでもWindowsでも動作させることができる。

# Jenkinsの構成例
## マスタ/スレーブ構成
2種類のJenkinsサーバ（マスタ/スレーブ）を立てて運用する場合は以下のような構成になる。
ここではGitLabで資材を管理し、Jenkinsでビルドを行った後にAmazon S3またはNexus Repositoryへ資材をデプロイする例とする。

![Jenkinsの構成例.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367074/dd503117-4b0a-851a-c686-fd3d60ace3fc.png)

作業者がGitLabへ資材をプッシュしたことをJenkinsが検知し、まずマスタサーバがGitLabから資材を取得する。
その後マスタサーバからスレーブサーバへ資材が連携され、スレーブサーバでビルドが実行される。
スレーブサーバは空いているノードが優先的に使用される。（Jenkinsの設定によって、GitLabリポジトリごとに使用するノードを分けることも可能。）
スレーブの設定方法については、[こちらの記事](https://qiita.com/yasuhiroki/items/d618796a1ba1366c4f80)を参照。

## CodeBuildと連携する構成
JenkinsをAWSのCodeBuildと連携することもできる。
ここではGitLabで資材を管理し、JenkinsとCodeBuildでビルドを行った後にAmazon S3またはNexus Repositoryへ資材をデプロイする例とする。

![JenkinsとCodeBuildの連携.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367074/c1679c94-29de-3017-5344-42bc36244bc3.png)

作業者がGitLabへ資材をプッシュしたことをJenkinsが検知し、まずJenkinsがGitLabから資材を取得する。
その後JenkinsがCodeBuildを呼び出し、CodeBuildでビルドが実行される。
JenkinsとCodeBuildの連携方法については、[こちらの記事](https://qiita.com/itawn/items/68522f5596f9e4256f14)を参照。

# Jenkinsfile
Jenkinsで実行される処理はJenkinsfileというファイルに定義する。
ここではJenkinsfileの基礎知識を紹介する。

## 記法の種類
Jenkinsfileの記法には、`Declarative`と`Scripted`の2種類が存在する。
`Declarative`の方が後発であり、柔軟で読み書きしやすい。
詳細は[こちらのガイド](https://www.jenkins.io/doc/book/pipeline/#declarative-versus-scripted-pipeline-syntax)を参照。

どちらの記法で記載されているかは、開始タグで見分けることができる。

| 記法 | 開始タグ |
|:-:|:-:|
| Declarative | pipeline |
| Scripted | node |


## 記載方法
ここでは`Declarative`の記載例を示す。
以下のように、ステージごとにブロックを分けて処理を定義していく。

```
pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                echo 'Building..'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing..'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying....'
            }
        }
    }
}
```

記載方法の詳細は以下を参照。
https://www.jenkins.io/doc/book/pipeline/jenkinsfile/
https://qiita.com/dublog/items/38831adf42e3cfeed66a
【mongoDB】mongoDBが起動できない（Failed to unlink socket file","attr":{"path":"/tmp/mongodb-27017.sock","error":"Permission denied"}}）

Node.jsでAPIサーバーを作成したかったので、初めてMongoDBを使ってみることにしました。
MongoDBの環境構築を進めていく中でエラーが発生したので、その内容と対処法に関してまとめます。

# 環境
macOS Catalina バージョン 10.15.7

# 背景
MongoDBは下記のような手順でMacOSに構築をしました。

```
$ brew tap mongodb/brew
$ brew install mongodb-community@5.0
$ brew services start mongodb-community@5.0
```

```
==> Successfully started `mongodb-community` (label: homebrew.mxcl.mongodb-community)
```

「Successfully」とありますが、`$ brew services list` で確認をしてみると、、、

```
Name                  Status  User         Plist
mongodb-community     error   user         /usr/local/opt/mongodb-community/homebrew.mxcl.mongodb-community.plist
mongodb-community@4.0 stopped
```

Statusがerrorになっていますね。
この状態で `$mongo` を実行してもうまくいきません。

失敗原因のログを見てみます。

```
$ cat /usr/local/var/log/mongodb/mongo.log
```

下記のようなログが出てきました。

```
{"t":{"$date":"2021-09-19T20:06:46.181+09:00"},"s":"E", "c":"NETWORK", "id":23024, "ctx":"initandlisten","msg":"Failed to unlink socket file","attr":{"path":"/tmp/mongodb-27017.sock","error":"Permission denied"}}
```

/tmp/mongodb-27017.sockのPermissionで何か怒られているようです。

# 解決策
/tmp/mongodb-27017.sockを削除すると解決しました。

```
$ sudo rm /tmp/mongodb-27017.sock
```

この現象は、macOSがCatalinaの場合に発生するようですね。

参考：[Installation in macOS Catalina problem - Ops and Admin - MongoDB Developer Community Forums](https://www.mongodb.com/community/forums/t/installation-in-macos-catalina-problem/11594)

`$ brew services list`で複数のmongodb-communityがあるので、全てuninstallして、改めて `mongodb-community@5.0` を入れ直しました。


## 参考
https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/
`apt install npm`時にエラー(npm : 依存: node-gyp (>= 0.10.9) しかし、インストールされようとしていません)

`apt install npm`時にエラー(npm : 依存: node-gyp (>= 0.10.9) しかし、インストールされようとしていません)が出たときの解決事例

```
$ sudo apt install npm
npm : 依存: node-gyp (>= 0.10.9) しかし、インストールされようとしていません
E: 問題を解決することができません。壊れた変更禁止パッケージがあります。
```

以下を実行すると解決した。（libsslは自動でインストールされないことがある？）

```
sudo apt install libssl1.0-dev
sudo apt install npm
```

# 参考
[Ubuntu18.04で任意のバージョンのNode.jsをインストールする方法](https://www.trifields.jp/how-to-install-node-js-on-ubuntu1804-3544)
Databricksにてsubprocess関数によりBashコマンドを実行するサンプルコード

# 内容
Databricksにてsubprocess関数によりBashコマンドを実行するサンプルコードを共有します。

下記のコードにより、Databricksのクラスターの最上位のディレクトリを表示します。

```python
import subprocess

cmd = '''
cd ..\..\..
ls
'''.strip()

proc = subprocess.run(cmd, shell=True, stdout = subprocess.PIPE)

print(proc.stdout.decode("utf8"))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/9950cef8-b34b-7485-0778-a63a1505a160.png)
シンボルでよく間違える事...

 ◼️突然ですが、私はシンボルをハッシュ内でシンボルを書く際よく間違えることがあります。
それは : :point_left: の位置です。

普通はハッシュ内にシンボルを書く時、上の様な書き方が普通だ。


(https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/982443/a7154a07-8e48-134a-7e77-d36d2e4cb15b.png

だが、私は下の様な記述をたまにしてしまう:frowning2:

今後、この様なミスをなくすため少しでもいいからコードを書く様努力していきたいと思う。
宜しかった応援の方オネシャース！

今日の投稿は以上です。
wagaでした！
特定ファイルのフルパスからカレントディレクトリまでのパスを削る方法

今回はShellScript向けのちょっとしたテクニックを発見したので、備忘録と共有を兼ねて紹介します。

#用途
かなり限定的な使用用途になりそうですが、カレントディレクトリの中にあるディレクトリ内に存在するファイルのフルパスから、カレントディレクトリから該当ファイルのパスのみを抽出したい時に使用します。
例えば`file.txt`のフルパスが`/home/USER/workdir/file.txt`となっている状態で、`/workdir/file.txt`の部分のみ必要になった時に、`/home/USER`を取り除きたい場合に使用します。

#Shell中身
```
#!/bin/sh

if [ $# != 1 ]; then
 echo "引数を1つ指定してください"
 exit 1
fi

DIRCNT=`pwd | wc -m`
FILEPASS=`echo $1 | cut -c $DIRCNT-`

echo $FILEPASS

exit 0
```

上記シェルを`/home/USER`の中で作成し、`./<シェルスクリプト名> /home/USER/workdir/file.txt`という書式で実行すると、カレントディレクトリ直下のディレクトリ名から対象ファイルまでのパス`/workdir/file.txt`が返ってきます。

#解説
まず最初のif文については、引数を指定していないか2つ以上指定された場合に処理を中断するためのものです。
次に変数`DIRCNT`については、カレントディレクトリまでの文字数を代入しています。`wc -m`コマンドは通常テキストファイルの文字数を表示するコマンドですが、コマンド実行結果の文字数を返すこともできます。
これにより例えば`/home/USER`の場合は、10文字なので、`DIRCNT`の中には10という数値が格納されます。

最後に`FILEPASS`変数には、引数として指定された、対象ファイルへのフルパスに対して、`cut`コマンドで指定した文字数を削ります。
`cut -c`コマンドに指定した引数ですが、指定方法は`<先頭文字数>-<終端文字数>`となっており、先程`10`を格納した変数`DIRCNT`を先頭文字数として指定していますが、終端文字数には何も指定していません。これにより先頭文字数として指定した10文字、すなわち`/home/USER`の部分はカットされ、終端文字数を指定していないので、それ以降の文字数（つまり`/workdir/file.txt`まで）が表示されるようになります。

今回は1つのファイル分しか表示できないのであまり使いみちはなさそうですが、次回はこれを応用したシェルを紹介しようと思います。
Networkxを使ったグラフの描画(できるだけ詳しく)

Networkxを使ってグラフを描画する機会があったので、
その方法をまとめておきます。

以下のコードはGoogle Colaboratoryで動作を確認してます。
おそらくどの端末でも利用可能かと

#モジュールのインポート

今回必要となるモジュールをインポートします。

```python:networkx.py
import networkx as nx #networkxのインポート
from matplotlib import pyplot as plt #matplotlibのインポート
```
グラフの描画はmatplotlibが必要となります。なので、こちらもインポートをしておきます。

描画するグラフを初期化するときは以下のコードを記述します。
無向グラフと有向グラフが用意されています。

```python:networkx.py
G = nx.DiGraph() #無向グラフの場合、有向グラフは->nx.Digraph()
```

#ノード(頂点)とエッジ(辺)の追加

グラフのノード(頂点)を追加するときは以下のコードを記述します。

```python:networkx.py
G.add_node(1) #ノードの追加
G.add_node(2)

G.add_nodes_from([3,4]) #リストを使ってノードをまとめて追加することができる

G.nodes(data=False) #出力
```

次にグラフのエッジ(辺)を追加するときは以下のコードが必要です。

```python:networkx.py
G.add_edge(1,2) #エッジの追加

G.add_edges_from([(1,3),(2,4),(1,4),(3,4)]) #エッジもまとめて追加することができる

G.edges() #出力
```

#グラフの描画

グラフを描画するときは以下のコードを実行します。

```python:networkx.py
pos = nx.spring_layout(G, seed=0) #ノードの配置を指定

# グラフの描画
plt.figure(figsize=(10,10)) #グラフエリアのサイズ
nx.draw_networkx(G, pos) #グラフの描画(おまかせ)
plt.show() #グラフの描画
```

##実行結果
![Unknown.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567391/6b5e82f9-6811-31cd-877c-80548dd9c2a4.png)


#もっといじりたい！

これでもグラフが作成できるのですが、
もう少しグラフをカスタムしたい場合はこちらを参考してみてください。

```python:networkx.py
# グラフの描画
plt.figure(figsize=(10,10))
"""
node_size: ノードの大きさを指定(デフォルト:300)
node_color: ノードの色を指定(デフォルト:#1f78b4)
node_shape: ノードの形を指定(デフォルト:'o')
*ノードの形についてはmatplotlib.markersクラスで定義されているマーカー
alpha: ノードの透明度を指定(デフォルト:None)
linewidths: ノードの枠線の太さを指定(デフォルト:1.0)
edgecolors: ノードの枠線の色を指定(デフォルト:node_color)
"""
nx.draw_networkx_nodes(G, pos, node_size=1300, node_color='#87cefa', node_shape='D',
                       alpha=0.7, linewidths=2.0, edgecolors="#0000ff")

"""
width: エッジの太さを指定(デフォルト:1.0)
edge_color: エッジの色を指定(デフォルト:#1f78b4)
style: 線のスタイルを指定(デフォルト:solid line)
alpha: エッジの透明度を指定(デフォルト:None)
arrowstyle: 矢印の形を指定(デフォルト:- or ->)
"""
nx.draw_networkx_edges(G, pos, width=1.5, edge_color='#aaaaaa', style='-.', alpha=0.7, arrowstyle='->') 

"""
font_size: 文字サイズの指定(デフォルト:12)
font_color: エッジの色を指定(デフォルト:k)
font_family: 文字フォントの指定(デフォルト:sans-serif)
font_weight: 文字の修飾(デフォルト:normal)
"""
nx.draw_networkx_labels(G, pos, font_size=20, font_color='#0000ff', 
                     font_family='sans-serif', font_weight='bold', alpha=None)

plt.show()
```

##実行結果
![Unknown-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567391/326fb311-113c-6943-ad60-47772b924058.png)


##もっと×2 いじりたい！
こちらのリファレンスを参考してみてください
https://networkx.org/documentation/stable/reference/generated/networkx.drawing.nx_pylab.draw.html
【Minecraft BE Addon講座#4】アドオンに欠かせないマニフェストの書き方

本ページはアドオン講座#4、「基礎編、マニフェストの書き方」です。
目次や、この講座については[#1の記事](https://qiita.com/pencilya/items/7b7e68265151f42a51ac)をご覧ください。

#基礎編で理解してほしいこと！
アドオン講座の最初にあたる基礎編では、アドオンに含まれるどんな内容をやるにも必要な知識を書いていきます。
アドオンやりたい！となったら、まずこの基礎編からご覧ください！

* (#3)BE(統合版)のアドオンとは？Java版のModとの違い
* (#3)アドオンが機能する原理
* (#3)アドオンのファイル・フォルダ構成
* (#4)manifest.jsonの書き方
* (#4)完成したアドオンをマイクラに適用する方法

#マニフェスト、manifest.jsonの書き方
まずはこの講座で主に使用するビヘイビアの方なので、ビヘイビアのマニフェストを開いてみましょう。

```behavior/manifest.json
{
    "format_version": 2,
マニフェストのフォーマット(形式)のバージョン。
これが変わると、書き方もちょっと変わってしまうので、このままでよし。

    "header": {
        "description": "Example vanilla behavior pack",
description、直訳で説明、このアドオンが何なのか、説明を書ける。

        "name": "Vanilla Behavior Pack",
このパック(アドオン)の名前。

        "uuid": "ee649bcf-256c-4013-9068-6a802b89d756",
uuid。アドオンをマイクラ側が識別するためのもの。
全く同じuuidのアドオンは共存できない。

        "version": [ 0, 0, 1 ],
アドオンの開発バージョン。アドオンを更新するたびにこの値を変更すればuuidを変更せずに済みます。

        "min_engine_version": [ 1, 17, 0 ]
このアドオンが対応するマイクラの最低必要バージョンの指定。
基本的にいじる必要はありません。

    },
    "modules": [
        {
            "description": "Example vanilla behavior pack",
同じdescriptionだがこちらはどこに表示されているのかわからない。
見たところ表示されないので、空欄(""のみ)でよい。

            "type": "data",
ビヘイビアなら"data"、
リソースなら"resources"、
スキンパックなら"skin_pack"など、
どんなタイプのアドオンなのかを記載。

            "uuid": "fa6e90c8-c925-460f-8155-c8a60b753caa",
これもuuid。
headerのuuidとは別なものにした方がよさげ。

            "version": [0, 0, 1]
headerのversionと同じ。そろえた方がよさげ。

        }
    ],
    "dependencies": [
        {
            "uuid": "66c6e9a8-3093-462a-9c36-dbb052165822",
            "version": [0, 0, 1]
dependency、直訳で依存。
このパックと同時に使ってほしいパックがある場合は、
そのパックのuuid(headerの方)を書きます。
すると依存関係が認識されて、
このパックを導入したとき、もう一方のパックも導入されます。
ビヘイビアならリソースの、リソースならビヘイビアの
uuid、バージョンを書きます。

        }
    ]
}
```

こんな感じです。
**マニフェストは**アドオンごと、というよりは、**パックごとに1つずつ必要**です。
この講座では主にビヘイビアのみのアドオンを多く扱いますが、リソースも必要なアドオンを作る場合は、リソースパックの方も同様にマニフェストを書かなければなりません。

※参考
![Minecraft 2021_09_19 17_08_02 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2030139/50a220e5-a1e0-a1ca-4d0a-93983d5f1b36.png)

#完成したアドオンをマイクラに適用する
配布されているアドオンは、すでに`.mcaddon`や`.mcpack`などの、開けばMinecraftが勝手に読み込んでくれるものが多いです。
このセクションでは、完成したアドオンのフォルダを`.mcaddon`や`.mcpack`にする方法を教えます。

まずは、フォルダ`behavior`の**中身**をすべて選択してzipに圧縮します。つまり、「数々のフォルダとmanifest.json、pack_icon.png」を全選択→zip圧縮する感じになります。

:::note info
＜追加情報＞
手を加えていない(＝バニラと全く同じ)フォルダ、ファイルに関しては含めなくて大丈夫です。
マイクラで適用することは、あくまで、上書きに過ぎないので、変更したファイルだけがzipファイルの中に入っていれば、他のファイルは上書きされずに残る、という感覚です。
:::

zip圧縮したら生成された`.zip`ファイルの拡張子[^1]を`.mcpack`に変更します。
適用させたいパックが1つだけなら、これを開いて終わりです。

配布のためなどで、複数のパックを一つにまとめたい場合は、まとめたい`.mcpack`ファイルを全選択してzip圧縮します。
zip圧縮したら生成された`.zip`ファイルの拡張子を`.mcaddon`に変更します。

`.mcpack`は一つのパックで、`.mcaddon`は複数のパックがセットになっているという違いがあったんですね。

アドオンをマイクラに読み込んだ後、ワールドに適用する方法は、有名だと思うので省略します。

#基礎編終了！
今回#4で基礎編が終了になります！
基礎編の知識を前提に説明が進むものが多いので、「これってなんだっけ？」となったらいつでも基礎編に戻ってみてください！
ここからは自分がそれぞれ学びたい技術についてのページを読んでください。お疲れさまでした！！

↓目次#1へ↓

https://qiita.com/pencilya/items/7b7e68265151f42a51ac

[^1]: **拡張子**とは、ファイル名の後ろ`.`よりも後ろの文字のことを言います。そのファイルが何のためのファイルのなのか、どうやって実行するのかなど、ファイルの特性を表します。ちなみに、**ファイル**は(大体拡張子のついているような)データのことを言い、そのデータが入っているファイル型のアイコンが**フォルダ**です。
CKAD等のK8s認定試験向けオススメVim設定3選

CKAD (Certified Kubernetes Application Developer) に合格しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323445/592f64e2-d5a0-4319-f492-199399693c9e.png)


対策方法については偉大な先人たちのブログやYouTubeが大変参考になりましたが、他であまり書かれていないけど重要だと思うVim設定について書いておきます。

テストが始まったらまず次の設定を.vimrcに書いておくことをおすすめします。

```
set paste
set expandtab
set number
```

`set paste`
YAMLを公式ドキュメントからVim上にコピー&ペーストすると、インデントがずれます。
これは、改行の後にVimが自動的にインデントを入れるためです。
この問題を回避するため、pasteモードにしておく必要があります。

別の方法としては、Vimではなくシェルにインラインでペーストする方法もあります。

公式Cheatsheetにも入っています。

https://kubernetes.io/docs/reference/kubectl/cheatsheet/#creating-objects

デモ動画がこちらにあります。

https://youtu.be/L6K_8dOFR5w?t=2514


`set expandtab`
公式ドキュメント上のYAMLではインデントにタブではなくスペースが使われています。
コピーしたYAMLにタブが混じるとエラーになってしまうため、タブがスペースに自動変換されるようにしておきます。

`set number`
YAMLマニフェストに問題があったときのエラーメッセージにYAMLファイルの行番号が含まれるため、行番号を表示させておくと該当する行をすぐに見つけやすいです。

他にも入れたい設定はあったのですが、私は自分が確実に覚えられる3つに絞りました。
Vue.jsでJqueryのslideToggleを使う

Vue.jsでJqueryみたいなアコーディオンメニューみたいなの作るのって難しくないですか？
私はJqueryも使います。

```html:html
<div id="app">
 <h2 @click="toggle">クリック</h2>
 <div class="box">
  <ul>
   <li>1</li>
   <li>2</li>
   <li>3</li>
  </ul>
 </div>
</div>
```

```javascript:javascript
var app = new Vue({
  el: '#app',
  methods: {
    toggle: function (event) {
      const boxElement = event.target.nextElementSibling
      $(boxElement).slideToggle( 500, 'linear' );
    }
  }
})
```