OmniAICreator/Qiita-1.07M huggingface dataset:
Dartについて学んでみる③

## クラスのカプセル化|getter/setter
ゲッター、セッターなにそれ、美味しいの???
美味しいよ🤤

Proverやriverpod使ってるときに、int _count;、int get count => _count;
こんな、文法をエディターのコード保管機能で自動で修正していたのだが、チンプンカンプンだった😵

Dartの文法への理解不足が原因なので勉強してみる。

**カプセル化**

変数をカプセル化するには「 _ 」を変数の前につけます。

```dart
class Person {
  String _name;
  int _age;
  Person(this._name, this._age) {}
}
```

Javaだとこんな感じで書いていた。
```java
public class Person {
  private String name;
  private int age;
}
```

TypeScriptだとこんな感じ
```typescript
class Person {
  private name: string;
  private age: number;
}
```

**ゲッター（get）**
カプセル化の変数を取得するにはgetter（get）を使用します。
getterを作るにはアロー関数で「get」を宣言します。

```dart
void main() {
  var person = Person("Jboy", 33);
  print(person.name);
  print(person.age);
}

class Person {
  String _name;
  int _age;

  Person(this._name, this._age) {}

  String get name => _name;
  int get age => _age;
}
```

実行結果
```dart
Jboy
33
```

**セッター（set）**
カプセル化の変数を変更するにはsetter（set）を使用します。
setterを作るには「set」を宣言します。呼び出す際「()」を使わず「=」で新しい値を代入します。

```dart
void main() {
  var person = Person("Jboy", 33);
  print(person.name);
  print(person.age);

  person.nameChange = "Jboy Hashimoto";
  person.ageDecrement = 33 - 10;
  print("フルネームは:${person.name}");
  print("${person.age}に若返った!");
}

class Person {
  String _name;
  int _age;

  Person(this._name, this._age) {}

  String get name => _name;
  int get age => _age;

  // よく見るとさっきと違って逆順になってる気がするけど?
  set nameChange(String name) => _name = name;
  set ageDecrement(int age) => _age = age;
}
```
実行の結果
```dart
Jboy
33
フルネームは:Jboy Hashimoto
23に若返った!
```

## アロー関数の宣言・定義・呼び出し
```dart
//void型
void 関数名() => 処理;

//return型
型 関数名() => 戻り値;
```

適当にやったらできた😅
```dart
void main() => logMethod();

String sayHello({String name = ""}) => name;
void logMethod({String nameLog = "Jboy"}) => print("お名前は$nameLog");

```
実行の結果
```dart
お名前はJboy
```

アロー関数を使った場合、メソッドを１行しか書けなかった!
書き直してみたら、メソッドを追加できた🥳
```dart
// void main() => logMethod();
void main() {
  logMethod();
  int caluc = age(age1: 33, age2: 10);
  ageLogMethod(result: caluc);
}

String sayHello({String name = ""}) => name;
int age({int age1 = 0, int age2 = 0}) => age1 - age2;
void logMethod({String nameLog = "Jboy"}) => print("お名前は$nameLog");
void ageLogMethod({int result = 0}) => print("年齢が$result若返りました!");
```

実行の結果
```dart
お名前はJboy
年齢が23若返りました!
```

## 最後に
SwiftをやReactをやっていたときに、基礎文法への理解不足が原因で、Promiseなにそれ?、美味しいの?
謎だらけでした。文法への理解が深まるとソースコードを読めるようになってくるので、文法の学習は後回しにしてはいけないと思いましたね。
三項演算子で偶数・奇数を判定する

shell勉強中のメモ。

# 三項演算子とは

```shell:構文
condition ? exprIfTrue : exprIfFalse
```
<h3>引数</h3>

 - `condition`
   - `true`(真)か`false`(偽)かの評価をしたい式
 - `exprIfTrue`
   - `condition` が`true`(真) と評価された場合に実行される式
 - `exprIfFalse`
   - `condition` が`false`(偽)と評価された場合に実行される式

# たとえば

```shell
$ seq 4 | awk '{print $1%2 ? $1"奇数":$1"偶数"}'
1奇数 #2の剰余が1（条件式は真）
2偶数 #2の剰余が0（条件式は偽
3奇数 #2の剰余が1（条件式は真）
4偶数 #2の剰余が0（条件式は偽
$ 
```

`seq 4`で
```
1
2
3
4
```
を出力した後、引数÷2(`$1%2`)で判定しています。
awkでは条件式の値が0や空白、空文字の場合に偽です。

# 参考

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
基本情報技術者試験対策　22日目

基本情報技術者試験勉強　22日目
-
この記事の目的
-
今年の5月に基本情報技術者試験を合格するために、過去問で間違えた箇所をただまとめる自分のための記事

プロフィール
-
・文系大学の３年生
・ITパスポートは保有
・ウェブアプリやサイト作成を個人で行ったことがある程度
・猫好き

間違った箇所
-
1、ドルビーデジタル（AC-3）
5.1チャンネルサラウンドシステムで使用されている音声圧縮技術

2、AMR(Adaptive Multi-Rate)やEVS(Enhanced Voice Services)
携帯電話で使用されている音声圧縮技術

3、SoC
必要とされるすべての機能(システム)を同一プロセスで集積した半導体チップ

4、SiP(System in　Package)
プロセスが異なる機能は，個別に最適化されたプロセスで製造し，パッケージ上でそれぞれのチップを適切に配線した半導体チップ

5、ビットマップフォント
文字をドット(点)の集合で表現したフォント形式
線画速度は速いが、輪郭がギザギザに見える

6、アウトラインフォント
文字を基準となる座標とそれらを結ぶ線の輪郭線情報として表現するフォントで、現在、一般的に使用されている方式
輪郭が滑らかだが、線画処理に時間がかかる。

7、運用テスト
利用者に提供するという視点で、システムが要求を満足していることを確認する。

8、単体テスト
個々のソフトウェアユニットについて、仕様を満足していることを確認

9、結合テスト
ソフトウェアユニット間のインタフェースが整合していることを確認

10、メディアコンバータ
物理層において，異なる伝送媒体を接続し，信号を相互に変換する機能

11、PBX(Private Branch eXchange)
事業所などの限られた範囲の構内に設置された内線電話機相互間の接続
加入者電話回線と内線電話機との接続に用いる構内交換機の総称

12、ATM交換機
データをセルと呼ばれる固定帳のブロックに分割し、
各セルに宛先情報を含むヘッダを付加することによって、データを統一的に扱う交換機

13、パケット交換機
データをブロック化された単位に区切って転送する蓄積型の交換機

14、フレームリレー交換機
フレームと呼ばれる単位に区切られたデータを交換する交換機


>引用
基本情報技術者試験ドットコム
https://www.fe-siken.com
AWS インスタンス 初回ログイン

# 概要
AWS EC2インスタンスを久しぶりに作って、初回ログイン時に、忘れていたことを備忘録として記載

# 前提

* EC2インスタンスを作成済みであること
※ OSは、[ubuntu OS]を使用していること。

# 目次

Ⅰ. 権限設定
Ⅱ. ログイン方法

## Ⅰ：権限設定

まず、インスタンス作成した際に、作成した「秘密鍵」の権限の修正が必要です。
権限は「600」でないと「秘密鍵」の権限が広すぎると怒られる。

```
chmod 600 XXXXXXX.pem
```


## Ⅱ：ログイン方法

```
ssh -i XXXXXXX.pem ubuntu@XX.XXXX.XXX（IPアドレス）
```

ここで注意が必要で、ubuntuで作成した場合は、ユーザー名=ubuntu。
一方、amazon_linuxで作成した場合のユーザー名=ec2-user。

ここら辺は、よく忘れがち！！！
※CentOSに関しては、分からないので未記載です。ご存知の方、いらっしゃれば教えてください。

# 終わりに

基本、上記２点さえ、間違わなければスムーズにログインできるかと思います。
他に、ここ躓くよとかあれば、教えてください！！！

追記したいです。
netcdfデータをxarray.Datasetとして読み，変数名のみリストで取り出す

```python3
import xarray as xr
ds = xr.open_dataset('hoge.nc')
[k for k, v in ds.items()]
```
dsは辞書なので（！？），itemsメソッドによりkeys（k, 変数名）とvalues（v, データ）のタプルを返す．  
そのkeysのみを受け取ってリストを作るリスト内包表記．
sudo apt-get updateをしていて思ったこと①

# 問題意識
長くて難しそうな英語の文章を見かけると、すぐGoogle翻訳にかける。
プログラミング中、問題に遭遇すると、すぐにQiitaやStackOverflowで検索する。
それでは、翻訳・検索をする作業者に過ぎない。翻訳・検索API。
しかし、問題にぶち当たった時、単なる作業人に陥ってしまっていることが多々ある。

ターミナルでlsコマンドやcdコマンドを使うことはしょっちゅうある。
しかし、内部で何が起こっているのかをどれほど理解しているのか。

確かに、自動車の仕組みを知らなくても運転できるし、
ユニクロがなぜ高機能で低価格なのかも知らずに買って着ることができる。
だが、ここで問題にしたいのは**あなたは単なる作業人に甘んじてしまっていいのですか**、ということだ。

これを思ったきっかけは、とある参考書でUbuntuを触る機会があり、よく

```
sudo apt-get update
sudo apt-get upgrade
```

が出てきて、私は何の疑問も持たずに上記のコマンドをベチベチ打っていたことに、気づいたことだ。
上記のコマンドを打つと、滝のように文字列がターミナルにダダダダと流れていくのだが、これ一体何が起こってるん？
そもそも、コマンドを入力したときに内部で何が起こってるん？
私は、なぜJKがTikTokにハマり、なぜ韓国嫌いな祖母が韓ドラにハマっているのか、
その仕組みについては興味がないのだが、このことについては興味がある。
だから深掘りしていこう。

# 深掘り

まず、ターミナルにコマンドを打った時、内部で何が起こっているのか。
前提として、ターミナルとシェルは違っていて、
ターミナルは、GUI上でCUIの操作をしたい時に使用するアプリケーションであり、実際に命令を解釈しOSへ伝達する役割はシェルが担っている。
つまり、コマンドを実際に解釈しているのはシェルである。
さらに踏まえておきたいのは、シェルによって解釈されたコマンドの実態はC言語で書かれたプログラムであり、そのプログラムの中身でカーネルのシステムコールが呼び出され、各種処理（ファイル操作、プロセス操作）が実行される、ということだ。

ということは、例えばlsコマンドを入力した時に、lsコマンドが意味する内容をもつ、C言語のプログラムが実行されるということだろうか。
そこで、以下の記事にあたったのだが、

https://techblog.yahoo.co.jp/web/shopping/ls/

これが、難しい。
ここでは、上の記事で触れられている、コマンドのオプションやgetopt関数については触れない。
しかし、確かに、ls.cというCプログラムをコンパイルして得られた実行ファイルが存在し、
コマンドのオプションに応じて結果を標準出力するようだ。

同様にcdコマンドについても、実行ファイルが存在する。
私はMac使いだが、コマンドの実行ファイルを探すwhichコマンドで、

```
which cd
```
を実行すると、

```:結果
cd: shell built-in command
```
と出る。

一方で、
```
which ls
```
では、
```:結果
/bin/ls
```
である。
この違いは、cdはシェルの組み込みコマンドである一方で、lsは組み込みコマンドではないという理由であるが、本線から外れるので、そっとしておく。
とにかく、lsの実行ファイルは、/bin/lsに存在することがわかった。
/bin/には他にも、コマンドの実行ファイルが存在している。

しかし、疑問は尽きない。
なぜ、コンパイル後の実行ファイルが存在しているのか。
実行ファイルではなく、Cプログラムを置いておいて、
ターミナルにコマンドのオプションや引数を入力した時に、それをCプログラムが受け取り、その都度コンパイルし、実行ファイルを呼び出すのではダメなのか。
コンパイル後の実行ファイルがどのようにして、オプションや引数を解釈するのか。
また、そもそもターミナルに入力された"ls"という文字列はどのように解釈されているのだろうか。

次回に持ち越し。


# 参考記事
https://eng-entrance.com/linux-basic-shell-terminal-console

https://language-and-engineering.hatenablog.jp/entry/20110617/p1

https://techblog.yahoo.co.jp/web/shopping/ls/
FlutterfireでiOSの電話認証(phone authentication)にハマった

## 問題

公式ドキュメントに従ってiOSの電話認証を実装したら、以下のエラーが吐き出された。

>If app delegate swizzling is disabled, remote notifications received by UIApplicationDelegate need to be forwarded to FIRAuth's canHandleNotification: method

flutter version: 2.10.3

## 解決策

参考：https://github.com/firebase/flutterfire/issues/1102#issuecomment-581202025

リンク内のコードから若干修正した（元のコードだとライブラリがないと怒られた）

ios/Runner/AppDelegate.swift　を以下の内容で上書きする。リビルドすると解決。

```swift
import UIKit
import Flutter
import Firebase
import FirebaseAuth
import UserNotifications

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
        FirebaseApp.configure()
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
    override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let firebaseAuth = Auth.auth()
        firebaseAuth.setAPNSToken(deviceToken, type: AuthAPNSTokenType.unknown)

    }
    override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        let firebaseAuth = Auth.auth()
        if (firebaseAuth.canHandleNotification(userInfo)){
            print(userInfo)
            return
        }
    }
}


```
rails seeds.rbファイル　とは

# 結論

初期データを作ってくれるファイル。
webアプリのテスト動作などに役に立つらしい。
データを一件入れる場合
```seeds.rb
モデル名.create!(カラム名：値) 
````

* seeds：種

# 具体的な使用例　userモデルオブジェクトの場合

アプリを作り、実際にデータを入れて動かしたい時
データを一件入れる場合
```seeds.rb
user.create!(name:"倉本") #!を付けるとエラー画面が表示される。つけないとnilを返すのみ。
````

データを１００件入れる場合
```seeds.rb
100.times do |n|
   User.create!(
    name:"test#{n+1}"
)
end
```

# まだテストデータは反映されていない
```ターミナル.
  rails db:seed
```
これでテストデータが読み込まれます。

# あ、後からテストデータを追加したい時
```ターミナル.
  rails db:migrate:reset
```
これでテストデータが反映されます。
以上です。
シングルトンパターンとは

## シングルトンとは
OOPの代表的なデザインパターンの一つで、

- インスタンスが一つしか作られないようなクラスを作成する
- その唯一のインスタンスに対するグローバルなアクセスポイントを提供する

というもの。

例えば`Human`っていうクラスがあったとして、それに対して`$takeshi`や`$hanako`といったインスタンスを複数作るのではなく、`$human`っていうインスタンスを一つだけ作らせるようすｒ

## シングルトンのメリット
なんでそんなことをするのかというと、以下のようなメリットがあるため
- アプリケーションのウィンドウのように一つしか存在してはいけないものが複数生成されるのを防ぐことができる
- インスタンスが一つしか作られないので、メモリ消費量を節約できる（ロガーなど全アプリケーションで使用するがいちいちインスタンス化する必要が無いもの）
- 設定値などを一つのインスタンスのプロパティに貯めておける（ランタイム中はその設定値をどこからでも利用できる）
- 複数スレッドを使用するアプリケーションで複数スレッドの処理を一元管理できる

## シングルトンの埋め込み方法
一般的には以下の方法で埋め込まれる

- インスタンスを保持するプライベート変数を定義
- ファクトリーメソッド（下記コードの`getInstance()`）を作成し、上記のプライベート変数にインスタンスがセットされていなければ新しいインスタンスを作成し、存在する場合はそのインスタンスを返却する

```java
class Singleton {
	private static Singleton instance;

	private Singleton() {
		...
	}
	
	public static synchronized Singleton getInstance(){

		if (instance == null)
			instance = new Singleton();

		return instance;
	}
	
	...
	
	public void doSomething()
	{
		...
	}
}
```

```java
// 呼び出し例
Singleton.getInstance().doSomething();
```

## 参考
- https://www.oodesign.com/singleton-pattern.html
MAiX Qube 奮闘記04 Video再生への道２

MAiX Qubeでのビデオ再生に成功しました。
(左はMAiX AMIGO)
QUBEの音量は小さいです。

![IMG_0014.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606106/42d9d661-0f2f-887e-e193-69e402764e5f.jpeg)

動画は「badapple_320_240_15fps.avi」で検索下さい。
そして再生する為のコードはこちら

```python:qube_play_video.py
from machine import I2C
import nes, lcd, sys, time
from sound import CubeAudio # see ../modules/es8374 put sound.py and es8374.py
from fpioa_manager import fm
from Maix import FPIOA, GPIO

#i2c = I2C(I2C.I2C3, freq=600*1000, sda=27, scl=24)  # amigo
i2c = I2C(I2C.I2C3, freq=600*1000, sda=31, scl=30)  # qube
CubeAudio.init(i2c)
tmp = CubeAudio.check()
print(tmp)

CubeAudio.ready(volume=100)

# cube
fm.register(19,fm.fpioa.I2S0_MCLK, force=True)
fm.register(35,fm.fpioa.I2S0_SCLK, force=True)
fm.register(33,fm.fpioa.I2S0_WS, force=True)
fm.register(34,fm.fpioa.I2S0_IN_D0, force=True)
fm.register(18,fm.fpioa.I2S0_OUT_D2, force=True)

# amigo
#fm.register(13, fm.fpioa.I2S0_MCLK, force=True)
#fm.register(21, fm.fpioa.I2S0_SCLK, force=True)
#fm.register(18, fm.fpioa.I2S0_WS, force=True)
#fm.register(35, fm.fpioa.I2S0_IN_D0, force=True)
#fm.register(34, fm.fpioa.I2S0_OUT_D2, force=True)

lcd.init(type=2, invert=True) # cube ips
lcd.rotation(2)
lcd.clear(236, 36, 36)

import video
v = video.open("/sd/badapple_320_240_15fps.avi")
print(v)
v.volume(100)
while True:
    if v.play() == 0:
        print("play end")
        break
```
BlenderでVOICEVOXの音声をPythonで追加

## 概要

CSVで用意したテキストをVOICEVOXで音声ファイルを作り、Blenderで取り込みます。
これをPythonで行う方法を紹介します。

## 準備（VOICEVOXのインストールと実行）

VOICEVOXは、無料で使える中品質なテキスト読み上げソフトウェアです。
使用においては、[VOICEVOXの利用規約](https://voicevox.hiroshiba.jp/term)をご確認ください。

下記のサイトから、インストーラーをダウンロードしてインストールしてください。

- https://voicevox.hiroshiba.jp/

インストールしたら、起動してください。
起動したら、GUIでも使えますが、Webサーバーとしても起動します。
Blenderからは`curl`を使ってWebサーバーの方にアクセスします。
もし、`curl`が入ってなければ、インストールしておいてください。

## 手順

Blenderを起動し、下図のように2つのテキストエディターとビデオシーケンサーを開いてください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/0d66a779-21c2-e81b-80bb-11dfd5f9e08d.png" width="600">

### CSV

「時刻（秒）、キャラクター番号、テキスト」を書いたCSVファイルを用意してください。下記はサンプルです。

```voice.csv
0,2,3DCGなら
1.6,12,ブレンダー!
```

1つ目のテキストエディターでCSVを開いてください。
ファイル選択画面で、デフォルトでCSVは見えませんが、右上のフィルターをオフにすると見えるようになります。

### Pythonコード

2つ目のテキストエディターの新規を押し、下記をコピペしてください。

```py
import bpy
import csv
import time
from pathlib import Path
from subprocess import run

csvfile = [text.filepath for text in bpy.data.texts
           if text.filepath.endswith(".csv")][0]

se = bpy.context.scene.sequence_editor
header = "Content-Type: application/json"
fps = bpy.context.scene.render.fps

tmp = Path("/tmp")
pth = tmp /"wav"
pth.mkdir(exist_ok=True)

# delete all sequence
for s in se.sequences_all:
     se.sequences.remove(s)

with open(csvfile) as fp:
    for i, ss in enumerate(csv.reader(fp), 1):
        try:
            sec, *mnt = map(float, reversed(("0:" + ss[0]).split(":")))
            speaker = int(ss[1])
            text = ss[2]
        except (IndexError, ValueError):
            print(f"Error at line {i}: {ss}")
            break
        frame_start = int((mnt[0] * 60 + sec) * fps)
        url = f"localhost:50021/{{}}?speaker={speaker}"
        namt = str(tmp / "text.txt")
        with open(namt, "w") as fp:
            fp.write(text)
        cmd = f'curl -s -X POST {url.format("audio_query")} --get --data-urlencode text@{namt}'
        res = run(cmd.split(), capture_output=True)
        namq = str(tmp / "query.json")
        with open(namq, "w") as fp:
            fp.write(res.stdout.decode())
        cmd = f'curl -s -H {header} -X POST -d @{namq} {url.format("synthesis")}'
        res = run(cmd.split(), capture_output=True)
        nama = f"audio{i:03}.wav"
        with open(pth / nama, "wb") as fp:
            fp.write(res.stdout)
        ss = se.sequences.new_sound(nama, str(pth / nama), i * 2, frame_start)
        ss = se.sequences.new_effect(f"txt{i:03}", "TEXT", i * 2 + 1, frame_start, frame_end=ss.frame_final_end)
        ss.text = text
        time.sleep(0.1)
```

参考：[BlenderでPythonを実行する方法](https://qiita.com/SaitoTsutomu/items/cec67381a8789b40e377)

上記のPythonコードを実行すると、CSVを読み込んで音声ファイルを作成して取り込みます。
スペースキーを押すと再生します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13955/7fac492e-ce77-de78-a594-220ea51f100d.jpeg" width="600">

また、下記の設定でアニメーションレンダリングすると、音声と字幕付きで作成できました。

- ファイルフォーマット：FFmpeg動画
- エンコーディング
    - コンテナ：MPEG-4
    - オーディオ
        - 音声コーデック：AAC

以上
Google ColabとVSCodeでSignateの環境構築

## 0.概要

- Signateコンペに参加するにあたって、GPU使って機械学習できる環境をできるだけ楽に構築したかった
- 参考にさせていただいたサイトをまとめておく

## 1.ColabでSignate APIを使う

- [Google ColabでSIGNATE APIを使う](https://qiita.com/insilicomab/items/d757339d97b44feaff01)
- [SIGNATEの画像分類の練習問題をColabで行う](https://qiita.com/chihiro1209/items/84bb0c158463745a314b)
- [SIGNATE CLI](https://pypi.org/project/signate/)

#### 手順

1. [SIGNATE](https://signate.jp/)のアカウント設定画面で "API Token" の "作成" をクリック
1. "新規作成" をクリックしてAPI Token(signate.json)を取得
1. ダウンロードしたsignate.jsonをGoogle Driveの`マイドライブ/.signate`にアップロード
1. `signateConnect.py`をGoogle Driveの`マイドライブ/Colab notebooks/modules`に配置

   ``` python:signateConnect.py
   from googleapiclient.discovery import build
   import io, os
   from googleapiclient.http import MediaIoBaseDownload
   from google.colab import auth

   def connect():
       auth.authenticate_user()

       drive_service = build('drive', 'v3')
       results = drive_service.files().list(
           q="name = 'signate.json'", fields="files(id)").execute()
           signate_api_key = results.get('files', [])

       filename = "/root/.signate/signate.json"
       os.makedirs(os.path.dirname(filename), exist_ok=True)

       request = drive_service.files().get_media(fileId=signate_api_key[0]['id'])
       fh = io.FileIO(filename, 'wb')
       downloader = MediaIoBaseDownload(fh, request)
       done = False
       while done is False:
           status, done = downloader.next_chunk()
           print("Download %d%%." % int(status.progress() * 100))
       os.chmod(filename, 600)

   if __name__ is "__main__":
       connect()

   ```

1. Google Colabで読み込む
   ``` python
   from google.colab import drive
   import sys
   drive.mount('/content/drive')
   sys.path.append('/content/drive/MyDrive/Colab Notebooks/modules')
   import signateConnect

   !pip install signate

   signateConnect.connect()
   ```

1. Colabの設定としては、ランタイムをGPUにするのと、その他から猫モードにするのがすき 


## 2.Colabの90分制限対策

- [Google Colaboratoryの90分セッション切れ対策【自動接続】](https://qiita.com/enmaru/items/2770df602dd7778d4ce6)
    - スクリプト方式では、メインブラウザをfirefoxにしている場合は1時間ごとブラウザで新しくタブが開かれました
    - AutoRefreshアドオンを使用する方法はマルウェア報告があるという噂もあり、非推奨です

#### 手順(Mac向け)

1. スクリプトを作成
   ``` sh:zombie-nize_colab.sh
   #!/bin/bash

   for i in `seq 0 12`
   do
      echo "[$i]" `date '+%y/%m/%d %H:%M:%S'` "connected."
      open (Colab NotebookのURL)
      sleep 3600
   done

   ```

1. 実行権限付与
   ``` sh:terminal
   $ chmod 744 zombie-nize_colab.sh
   ```

1. ターミナルから叩いておく
   ```sh:terminal
   $ ./zombie-nize_colab.sh
   ```

## 3.ColabとVSCodeを連携する

- [Google ColabとVSCodeを用いた分析環境運用方法 〜kaggle Tipsを添えて〜](https://www.takapy.work/entry/2021/08/17/185047#LT%E8%B3%87%E6%96%99)
    - ローカルのVSCodeからremote-sshで接続する
- [Google Colab をSSH と VS Code で使う](https://qiita.com/hazigin/items/c291adf5dc9ccc13d11f)

## 注意

- Colab周りはGoogleさんが推奨している使用方法ではないことを多くやっているので、急に使えなくなるリスクなどありそう
- 使用する際は自己責任でお願いします
Phaser.jsで作った大富豪をユーザー登録制にしました

Laravelでバックエンドを作成し、大富豪をユーザー登録制にしました。
成績がバックエンドに登録され、ネットで確認することができます。

大富豪のURL
https://www.new-doumeishi.me/vs_daihugou/public/

成績確認のURL
https://www.new-doumeishi.me/vs_daihugou_server/show
@paramってなんだ

# ＠paramとは
結論から行くと@paramというのはJSDocというツールのタグである

## JSDocとは
JavaScript用のソースコードにデコレーターを追加するツール

## 主なタグ
- ＠type
    - 変数の型を記述
- ＠param　
    - 関数の名前、型を記述
- ＠return 
    - 戻り値の型を記述
- ＠todo
    - 終わっていない課題を記述
- ＠readonly
    - 読み取り専用を示す

## 実際の使用例
```javascript
/**
*テスト変数
* @type {Number}
*/
const test = 10;

/**
*テスト関数
* @param {Number} arg1
* @param {String} arg2
* @return {Boolean}
*/

function test(arg1, arg2) {
  return false
}

```

## 参考資料

https://jsdoc.app/
<備忘録>Herokuのdbを削除したい

# heroku上のデータベース（pstgrsql）を削除して作り直したい

```
$ heroku run rails db:reset
rails aborted!
ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.
If you are sure you want to continue, run the same command with the environment variable:

                                          .
                                          .
                                          .
                                          .
```

どうやら、production環境のデータベースは誤って
消せないような仕組みらしい

ではどうするか、

下記のコマンドで消せました。

```
$ heroku pg:reset -a <アプリ名>
```

以上

Heroku上のデータベースの削除にしかたでした。


再立ち上げを忘れずに！
```
$ heroku run rails db:migrate
```


### 参考文献
https://nobunobu1717.site/?p=1339
新人プログラマ応援　健康第一

新人プログラマ応援 - みんなで新人を育てよう！

https://qiita.com/official-events/3f21c92121aa125807b4

今、Qiitaでは、「データに関する記事を書こう！」という行事をやっている。

https://qiita.com/official-events/30be12dd14c0aad2c1c2

この文章は、テーマ2『データに関する記事を書こう！』参加記事でもあります。

新人向けにはいくつか記事を書きました。

何が一番だいじかって、健康第一です。

# 新型コロナウィルス


（IT業界における）新型コロナウィルス対策（案）組織編

https://qiita.com/kaizen_nagoya/items/4de09e3ba35b82ee71e7

（IT業界における）新型コロナウィルス対策（案）個人編

https://qiita.com/kaizen_nagoya/items/f6996fe6d49ee6095d61

感染症流行時の体調管理（IT業界向け）

https://qiita.com/kaizen_nagoya/items/124c62f30344405577c4

行事開催時の注意事項（covid-19(新型コロナウイルス)・インフルエンザ等流行時を含む）

https://qiita.com/kaizen_nagoya/items/92fe0b8076111a3c1bc4


covid-2019（新型コロナウィルス）対策と遠隔行事の記録

https://qiita.com/kaizen_nagoya/items/9a2568de94fa00e7c66f

# 確率と統計

疫学は社会現象における確率と統計の取り扱いが大事かも。

統計と確率が扱えれば工学のほとんどは大丈夫。仮説（119）統計と確率(1)

https://qiita.com/kaizen_nagoya/items/c917054d1390b7e17049

連続と離散、時間と空間、物理量と生物量。統計と確率(2)

https://qiita.com/kaizen_nagoya/items/d0980c6bf9d3079aa98d

生物統計学

https://qiita.com/kaizen_nagoya/items/454f05d58bafa748ea5b

物理、生命、社会。統計と確率(3)

https://qiita.com/kaizen_nagoya/items/98d0a37012f039e67a39
リバースエンジニアリング とは

## 勉強前イメージ

プログラム作る逆？
解析？

## 調査

### リバースエンジニアリング とは

ソフトウェアやアプリケーション(またはハードウェア)の仕組みを分析し調査することで
動作などの技術情報を明らかにするのがリバースエンジニアリングです。

ソフトウェアの場合は、逆コンパイルなどを行ってソースコードを取得し解析することが多いです。
互換性を開発するために行われたり、脆弱性を探すなどといったセキュリティ上の目的で行われることもあります。

### リバースエンジニアリングの注意

リバースエンジニアリングは注意しないと特許権や著作権の侵害に当たる可能性があります。
元となるソフトウェアの権利者に許可なく新規の開発を行うと上記に当たります。
しかし、サイバーセキュリティ確保などの目的であればリバースエンジニアリングは合法になっています。

ですので、どのような目的でリバースエンジニアリングを行うか、またその情報をどうするかを注意する必要があります。

### リバースエンジニアリングの対策

- ソースコードを読みづらくして難読化する

ソースコードを読みづらくして解析しづらいようにします。
例えば、意味のないプログラムを入れてみたり、理解しづらいアルゴリズムで書くなどの方法がありますが、
基本的には専用ツールを使って行います。

- コード自体の暗号化

プログラムのファイル自体を暗号化してキーがないと読めないようにします。

## 勉強後イメージ

雰囲気合ってた気がする。
セキュリティ目的であればいいのねー

## 参考

- [リバースエンジニアリングは違法？法律上の注意点をわかりやすく解説](https://it-trend.jp/cyber_attack/article/442-0045)
- [リバースエンジニアリングとは、方法や注意点について徹底解説](https://cybersecurity-jp.com/column/29375)
MacのDBeaverのアンインストール & 再インストール

MacでDBeaverを使用していた際、接続先を追加してもデータベースナビゲーターに表示されないことがあり、完全アンインストールして再インストールする方法が探してもなかなか見つからなかったため、記載します。

マシン及びDBeaverのバージョンについては以下の通りです。
- M1 MacBook Pro MacOS Monterey v12.3
- DBeaver Community v21.3.4.202202051448

# アンインストール方法

1. ApplicationフォルダのDBeaverをゴミ箱に入れる
2. ターミナルを開く
3. 以下コマンドを実行

```bash
cd Library && sudo rm -rf DBeaverData
```

再インストールする場合は、再度DBeaverをダウンロード & インストールを行います。
Lambdaを定期実行する

# 背景・目的
- [VPC内のLambdaからインターネットに接続する](https://qiita.com/zumastee/items/21c77e66156a8d26856e)で作成したLambda関数を定期的に実行する。
- 定期実行には、EventBridge Ruleを利用してみる。

# 内容
## 実装
### 1. EventBridgeルールの作成
- EventBridgeのルールをクリックしトップ画面から、「ルールを作成」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/768de97d-5740-9d9b-52a7-8d8ba39fc58b.png)

### 2. ルールの詳細
- 名前と説明、イベントパス、ルールタイプ「スケジュール」を選択して「次へ」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6be2fddb-b594-5a0b-eb03-92e91859d6f7.png)

### 3. スケジュールを定義
- スケジュール間隔を設定する。Cronのように指定できるパターンと定期間隔を選択できる。今回はレート式を選択し「次へ」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/32607bc7-f934-259f-8f17-dac3739fedf0.png)

### 4.ターゲットを選択
- 作成済みのLambda関数を選択して「次へ」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/2e41ccbd-ea59-af7b-e083-899d8231d26c.png)

### 5. 作成
- タグや確認画面などを経て最後に作成ボタンをクリックすると完成。（キャプチャなし。）

## 結果の確認
### Lambdaの呼び出し（Invocation）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/83d9e2c2-37fa-7906-70a9-6a2c16ac8933.png)

- 1H間隔で実行されている。
    - 9:21
    - 10:21
    - 11:21
    - 12:21

### CloudWatch Logs（CWL）
-　CWLで取得できているか確認できた。

#### 9:21（JST 18:21）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/44cb64ea-b17b-e62b-1a86-b837fe425f18.png)
#### 10:21（JST 19:21）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/354b1021-6ff5-8707-d039-61bb8616fdbc.png)
#### 11:21（JST 20:21）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/63769e3f-4281-1c91-0d27-5659803c4a18.png)
#### 12:21(JST 21:21)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/994e5808-2e6e-9c08-557f-cda1f585466b.png)


## 考察
- EventBridgeを使用することで、簡単にスケジューラを作成できました。

# 参考
https://qiita.com/zumastee/items/21c77e66156a8d26856e
Yo Liferay-theme

テーマの初期buildにいろいろな問題にぶつかりました。
試行錯誤でやっと解決しましたので、キーとお思う内容をメモしておきます。

### 1. 最新情報の参考先：
https://github.com/liferay/liferay-frontend-projects

### 2. テーマ関連の部分
Projects
Themes Toolkit v10.x+: Develop themes for DXP versions 7.2 and above (uses Gulp 4)
Themes Toolkit v9.x: Develop themes for DXP versions 7.2 and 7.3 (uses Gulp 3)
Themes Toolkit v8.x: Develop themes for DXP versions 7.0 and 7.1

### 3. generator-liferay-themeを使って、テーマを生成→build
プロジェクトのURL: [generator-liferay-theme](https://github.com/liferay/liferay-frontend-projects/tree/master/projects/js-themes-toolkit/packages/generator-liferay-theme)

nodeのバージョンなどは下記のファイルで確認できます。[./package.json](https://github.com/liferay/liferay-frontend-projects/blob/master/projects/js-themes-toolkit/packages/generator-liferay-theme/package.json)

1. nodeバージョンを整備（問題ない場合は2.へ）
```
brew install anyenv
anyenv init
exec -l $SHELL
anyenv install nodenv
```

nodeの最新バージョン情報を確認 latest version of node -> https://nodejs.org/

```
nodenv install 16.14.2 
```
失敗した場合に、提示があるので、それに従って、バージョンリストを更新(nodenv install -lで確認できます。)

```
nodenv global 16.14.2 
nodenv versions　// インストール状況を確認
node -v
```

2 . その他必要なツールをインストール
```
npm i -g npm
npm -v // バージョン確認
npm install -g yo
npm install -g gulp
```

3 . 現在の状況等を確認
```
npm list -g --depth=0
```
下記のようなものが表示されます。
```
/Users/{UserName}/.anyenv/envs/nodenv/versions/16.14.2/lib
├── corepack@0.10.0
├── generator-liferay-theme@10.2.0
├── gulp@4.0.2
├── npm@8.5.0
├── yarn@1.22.18
└── yo@4.3.0
```
4 . サンプルThemeを作成→build 

```
yo liferay-theme //　指示に従ってテーマを作成
cd my-liferay-theme // 作成したフォルダーへ
npm i
npm run upgrade // 直接buildすると、エラーになるようで、一回だけ実行します。
npm run build // Warningがあるようだが、無事にbuildはできるはずです。
```

build終わったら、distフォルダの直下に、xxx.warってファイルが生成されます。
そのファイルをliferayのDeployフォルダーにコピーしてデプロイ完了。
AWS CLIコマンドでS3オブジェクトの中身を見る方法


S3に関するaws cliのコマンドには `ls` や `cp` は存在するが `cat` コマンドは存在しない。

https://qiita.com/uhooi/items/48ef6ef2b34162988295

catコマンドは無いのですが、catと同様にファイルの中身を見るコマンドがあります。

# s3オブジェクトの中身を見るコマンド

cpコマンドのコピー先として `-` を指定するとオブジェクトファイルを見る事ができます。

```
$ aws s3 cp s3://app-s3-server-access-log/2022-04-01-05-13-25-47E6B98F6C4197 -
```
ブロックチェーンでビジネスはどう変わる？

# ブロックチェーンとは
`取引履歴(ブロック)を暗号技術によって過去から1本の鎖(チェーン)のようにつなげ、正確な取引履歴を維持しようとする技術のことです。`

# ブロックチェーンでビジネスがどう変わる？
ブロックチェーンの市場規模は2020年で100〜200億円、2025年には1000億円を超える国内市場を形成し、世界全体では2020年の30億ドルから2025年には397億ドルへと拡大するとの見解も発表されています。
なぜブロックチェーンの市場はこれほどまでに拡大すると言われているでしょうか？
ビジネスへの活用事例を見て考えてみましょう。

### ■暗号資産
ブロックチェーンと聞いて一番初めに思い浮かべるのが暗号資産ではないでしょうか。ブロックチェーンと暗号資産がごちゃ混ぜになってる方もいるかもしれませんが、暗号資産を実現するための技術がブロックチェーンです。
ブロックチェーンには、__非中央集権制__ という特徴があります。今までは、中央にデータを集めてそこでデータを管理する(中央集権制)のが一般的でした。
ですが、ブロックチェーンでは中央だけで管理するのではなく、みんなでデータを管理します。みんなでデータを管理することで、データの改ざん・破壊が極めて困難になります。

少し話は変わりますが、貨幣は次の4つの条件を満たす必要があります。
条件1.少量で大きな価値をもち，携帯に 便利であること
条件2.分割が容易に可能であること
条件3.価値が安定していること
条件4.耐久性があること

ブロックチェーンという技術が存在していなかった時代は、ネット上で作成した仮想的な通貨に、上記の条件3にあたる __安定した価値__ を持たせることが困難でした。しかし、ブロックチェーンという技術を使用することで、仮想的な通貨に安定した価値を持たせられるようになり、暗号資産が通貨と同等の価値を持つようになってきました。
ちなみにですが、2008年にビットコインというブロックチェーンを使用した暗号資産が誕生してから1度も改ざんされたことはありません。

また、そのブロックチェーン特有の堅牢性だけでなく、金融機関を通さなくても送り手と受け手の当事者間だけで決済を成立させれるという特徴も暗号資産の市場が大きくなった要因の1つです。

### ■トレーサビリティ
トレーサビリティとは __食品の移動を把握できる__ ことです。
具体的には、｢その製品がいつ、どこで、だれによって作られたのか｣を明らかにし、原材料の調達から生産、そして消費または廃棄まで追跡可能な状態にすることです。
この記事の冒頭で記述しましたが、ブロックチェーンとは __正確な取引履歴を維持__ しようとする技術のことです。
つまり、始まりと終わり(現在地)のみが分かるのではなく、1つのモノがどういう過程を通り消費者まで届けられているかを後から追跡することができます。
例えば、市場にすでに流通している製品に異常が見つかり回収することになった場合、ブロックチェーンで履歴を管理しておくことで以下のようなメリットがあります。
__・どの店舗に届けられている製品を回収すべきかが簡単に分かる。__
__・改ざんができないため、誤魔化せない__
__・消費者に安心感を与えられる(企業のアピール)__


# 終わりに
ブロックチェーンと聞くと金融にのみ関係するイメージがあったのではないでしょうか？ここで紹介できませんでしたが、他にも医療や芸術などいろんな分野に応用されています。これから益々ブロックチェーンの市場は大きくなっていくでしょう。

最後までお付き合い下さりありがとうございました。
【Python/codecademy】初心者がcodecademyを本気で受講してpythonをマスターした話

# はじめに
<a href = "https://www.codecademy.com">codecademy</a>という有料オンライン学習プラットフォームにて、Pythonのコースを受講しました。当時プログラミングの「プ」の字も分からなかった私は、寝る間も惜しんでPCに齧り付いてコースを受講していました。
ちなみに、修了していません笑。ここら辺までやるとコースではなく「自分で何か作ってみたい」というレベルに達し、自分で好きな物を作っていた記憶があります。今回は、その時の経験についてまとめようと思います。

![Screen Shot 2022-04-01 at 20.39.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044781/4f3883d9-b5a5-5a46-6c17-f69b59a765ab.png)

ちなみに、修了するとこのような修了証書がもらえるみたいです。(あと7％なぜ頑張れなかったんだ、、、)
[<img width = 1000 src = "https://www.codecademy.com/resources/blog/content/images/size/w1000/2020/08/codecademy-students-certificates.png">](https://www.codecademy.com/resources/blog/codecademy-pro-student-plan/)

# Overview

まずcodecademyの凄さはなんといってもそのコースの数！主要プログラミング言語はもちろんKotlinなどの言語も網羅しています。さらにデータサイエンス、ウェブデザイン、ゲーム開発などのテーマ別のコースも充実しています。
![Screen Shot 2022-04-01 at 20.50.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044781/dc67200d-42db-70f2-a648-bc0bb878e885.png)


# 授業スタイル
授業は主に動画・読み物・実装・小テスト・プロジェクトの5つの要素があります。
動画と読み物は割愛しますが、実装・プロジェクトのUIはこんな感じです(写真はJavaScript)、
![Screen Shot 2022-04-01 at 21.01.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044781/d4db63c3-3562-bec1-660b-fce49a125a5e.png)
左のお題を見ながらコードを書き、チェックします。
ここがcodecademyのすごいところなのですが、エラーが出た時のアドバイスが的確なんです。初学者の方は特に、プログラム走らせた時のエラーメッセージを見てもピンと来ない事が多いかと思うんです。codecademyはその難しいエラーメッセージを初心者所用に噛み砕いてくれるというか、翻訳してくれるというか、とにかくどこでエラーが出てるのかわかりやすく、ストレスなく学習を進められると思います。

小テストも直感的でわかりやすいUIになっています！
[<img width = 1000 src = "https://www.codecademy.com/resources/blog/content/images/size/w1000/2020/08/codecademy-pro-student-features.png">](https://www.codecademy.com/resources/blog/codecademy-pro-student-plan/)


# 課金制度
このcodecademy、残念ながら基本的に月額を払っての使用になると思います。といのも、
1. 無料のコースが限られる(Pythonは課金コース)
2. 無料のコースでも途中から課金しなくては受けられない講義がある

てなわけで、codecademy使って学習するときは課金はマストではないかと思います！

#### 料金プラン
![Screen Shot 2022-04-01 at 21.19.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044781/2b94a8de-96c8-1f3e-0e25-0b8144dc5ae1.png)


# データのはなし
データの話もしておくと、codecademyはData Scienceのテーマのコースが充実しているんですよね。
Data Scientist（全85レッスン）、Data Analyst（全67レッスン） などの超ヘビー級のコースから始まり、SQL入門やPower BIやTableauなどのコースもあります。
[<img width = 1000 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044781/2dc0c7c5-a745-d556-899f-b9005419694e.png">](https://www.codecademy.com/catalog/subject/data-science)

個人的にデータ分析に特化したプログラミング言語を学びながらBIツールの使い方も学べて$20/月はかなりお得かと、、、
なかなかBIツールってプライベートじゃ触る機会ないですからね、、
特に学生の方でPower BIやTableau使った事あるって方は少ないのではないのでしょうか！？

# 総評
全体的にとても使いやすく、為になるサイトでした！私の場合はこのコースを2ヶ月受講したおかげで、AI系のベンチャー企業でインターンをするくらいまでのスキルが尽きました。（もちろんコース外で色々勉強しましたが、それなりの基礎は身につきました！）
<a href = "https://qiita.com/Shu25/items/f18d89920a874fda0f18">IBM</a>の時とは違い、かなり一人で進めている感がありました。講師とも生徒とも関わるチャンスはなかったです。。
「一人でも頑張れる！」って思う方はぜひ挑戦してみてください！
また、友達とチームを組んで受講してみるのもいいかもですね！
【Github】git addしたら「does not have a commit checked out」エラーが出た

## 概要
`git add`したときに下のようなエラーが出ました。
```bash
error: 'work2' does not have a commit checked out
fatal: adding files failed
```
調べてみると、**.git**が2つあることが原因でした。片方を削除するとaddできました。

## 経緯

### 以前作っていたリモートリポジトリ
前にGithubにリモートリポジトリを作って、ローカルからファイルをpushしていたものがありました。仮にこのリポジトリを「sample」とします。
ここに「work1」ディレクトリとREADME.mdファイルが入っていました。work1ディレクトリの中にもいくつかファイルが入っています。
```
sample/
  - work1
  - README.md
```

### 新しいディレクトリを追加したい
以前作ったときは、ローカルのファイルをVScodeからpushしていました。今回、cloud9上のファイルをpushしたいと考えていました。また「work2」ディレクトリを作って、その中にファイルという構成にしたいと考えていました。

```
sample/
  - work1
  - work2
  - README.md
 ```

まず、Githubで新しいディレクトリ「work2」を作りました。
**Add file**から**Create new file**を選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2549439/c6f52349-0a91-79bc-5b62-298d5b526052.png)

ファイル名に「**work2/**」とするとパスになり、その後ろに **.gitkeep**とするとディレクトリを作成できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2549439/a54cdd93-dd36-874e-117f-8a0a29665b6b.png)

### pullする
Cloud9でターミナルを開き、リモートリポジトリと紐付けした後、pullしました。ローカルのmainブランチにリモートのmainブランチがマージされました。
```bash
$ git init
$ git remote add orgin リモートリポジトリURL
$ git pull origin main
```
### addする
work2ディレクトリの中に追加したいファイルを入れる&作ります。その後、addしました。
```bash
$ git add .
```

### エラー
すると、以下のようなエラーが出ました。
```bash
error: 'work2' does not have a commit checked out
fatal: adding files failed
```

### 解決
調べてみると、**.git**が2つあることが問題であることがわかりました。1つはリモートリポジトリをpullしてきたローカルのディレクトリの中に、もう1つはwork2ディレクトリの中に作られていました。work2ディレクトリの中にある**.git**を削除してもう一度addすると、今度はpushまで問題なくできました！


### 原因？
おそらく、間違えてwork2ディレクトリにいるときに`git add`してしまったのが原因かと思われます。そこでエラーが出たのでわけがわからず、`git init`するというとんでもない間違いをしたがためにこんなことになったのだと思います。

## まとめ
`git add`したときに以下のようなエラーが出たときは、**.git**が2つ存在していないか確かめると良いことがわかりました。
```bash
error: 'work2' does not have a commit checked out
fatal: adding files failed
```
Kintone 現在時刻を秒にする

*Kintoneで秒がとれないってほんと！？？

```
const currentDate = luxon.DateTime.local().startOf('day');
```

[Kintone](https://developer.cybozu.io/hc/ja/articles/900000985463-Luxon-%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6-kintone-%E3%81%AE%E6%97%A5%E4%BB%98%E3%82%84%E6%97%A5%E6%99%82%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E3%81%AE%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%83%88%E3%82%92%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E3%81%99%E3%82%8B)で紹介されているようにやってみたら

```
2022-04-01T00:00:00.000+09:00
```
ほんとに秒がない、ない・・・・・

いやまて、これって時間と分もないからそもそも違うのでは？

再度調査

[Moment.jsを使え](https://developer.cybozu.io/hc/ja/articles/204982474)とあるので再度挑戦

```
var now = moment().format();
```


```
2022-04-01T22:02:46+09:00
```

できたー－！

歓喜！
rmで削除したファイルを復元できる lsof

## 使用用途
・rmで間違えて消してしまったファイルを復元したい時に使う。

:::note warn
注意
- 消去したファイルを開いているプロセスが存在している時のみ可能。
- `rm` はinodeへのリンクを削除しているだけであって、inodeそのものを消しているわけではないので、inodeへの全てのリンクが失われない限りinodeとデータは失くならない。
- ファイルを開いているプロセスが存在していればそこから`/proc/【プロセスID】/fd/`を辿り復元する事ができる。
:::

## 使い方
``` :sqlのコマンド
$ touch hoge.txt      　　　　　　　　　　　　// ファイル作成
$ vi hoge.txt         　　　　　　　　　　　// ファイル内に書き込む
※このファイルに下記の内容を書き込んだ
ファイルを消してしまった。
でも復元できる。
$ less hoge.txt       　　　　　　　　　　// ファイルの中身を見る
※ Control + z で　less を終了
$ rm hoge.txt         　　　　　　　　　// ファイル削除
$ lsof | grep "hoge.txt"  // 現在開いているファイルの中でhoge.txtが入っているファイルを返す
less  12345  hoge  4r  REG  259,1  33  59166498 /home/hoge/hoge.txt (deleted)
※2つ目がプロセスID、4つ目がファイル記述子
$ cp /proc/12345/fd/4 ./
$ cat 4
ファイルを消してしまった。
でも復元できる。
```

ファイルに書き込んだ内容が復元できた。

## 説明

`less`
- ファイルの中身を見る。
- Control + z で less を終了

`lsof`
- 現在開いているファイルを一覧表示する

`grep`
- 指定した文字列を検索するときに使うコマンド

`proc`
- ディレクトリ。
- ハードディスクやSSDなどのストレージ上ではなく、メモリの中に作られるファイルシステム。
- procにあるファイルは普通のファイルではなく、仮想ファイルという特殊な形式。

- lsof | grep "hoge.txt"で出てきた2つ目がプロセスID、4つ目がファイル記述子（"4rの"r"は"regular file"の略であり、通常のファイルを意味する）
　
　
　
この記事は以下の情報を参考にして執筆しました。
- https://momozo.tech/2018/08/07/rm%E5%89%8A%E9%99%A4%E3%81%97%E3%81%9F%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92lsof%E3%81%A7%E5%BE%A9%E5%85%83%E3%81%99%E3%82%8B/
whereメソッドを使ってDBから取り出すデータを絞り込む

## 実現したかった実装
送られてくるパラメーターの条件を満たしたデータをDBから取り出す実装をしたくて辿り着きました。

## whereメソッドを使用する
モデル名.where(条件)とする事で条件に一致したデータを取り出せます。

## 行った実装
whereメソッドに渡す引数はハッシュの形でいいことに気づき下記のようなクラスメソッドを書きました。

```ruby
  def self.match_recipes(dates)
    hash = {}
    dates.each{|key, value|
      unless value.blank?
        hash[key] = value
      end
    }
    Recipe.where(hash)
  end
```
引数に条件の形となるハッシュを渡します。
```ruby
dates = {"category_id"=>"1", "genre_id"=>"1", "type_id"=>""}
recipe = Recipe.match_recipes(dates)
```
呼び出しのイメージです。

引数で渡したハッシュ型のデータはメソッド内のeach文でkeyとvalueに代入しながら繰り返し処理が行われます。
unleesを使用しvalueが空ではない時のみ空のハッシュに追加していく事でparamsから送られてきた絞り込みたいデータの内、値があるもののみを取り出したハッシュを作ります。
```ruby
hash = {"category_id"=>"1", "genre_id"=>"1"}
```
↑出来上がり

このハッシュをwhereメソッドの引数に渡してあげる事で、条件に一致したデータのみを取り出す事ができました。

↓イメージ
```ruby
recipe = Recipe.match_recipes({"category_id"=>"1", "genre_id"=>"1"})
```

私自身がまだ実務経験のない初学者のため、知らない不具合や懸念材料があるかも知れません。
もし気になる点がございましたらご指摘いただければ幸いです。

この投稿が誰かの為になれば幸いです。
【備忘録】python + django セットアップ

# 経緯
需要はないですが、少しハマったので自信の備忘録として残しておきます。

# python インストール
ディストリビューションのanacondaがオススメです。
https://www.anaconda.com/products/distribution

# 仮想環境構築
他の開発環境に影響を出さないように仮想環境を構築する。
コマンドプロンプトを開きます。
C:\下に仮想環境フォルダを作ります。
~~~cmd:cmd
cd C:\
mkdir django_venv
~~~
ここでは「C:\django_venv」を作りました。
仮想環境を作ります。
~~~python:cmd
python -m venv django_venv
~~~
仮想環境を起動します。
~~~cmd:cmd
cd C:\django_venv\django_venv\Scripts
activate
(django_venv) C:\django_venv\django_venv\Scripts>
~~~

# djangoインストール
何もインストールされていないことを確認します。
~~~cmd:cmd
(django_venv) C:\django_venv\django_venv\Scripts>pip freeze

~~~
djangoをインストールします。
~~~cmd:cmd
(django_venv) C:\django_venv\django_venv\Scripts>pip install django
~~~
ここでエラーが。
「pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.」
下記サイトを参考にさせて頂きました。
https://kumasuke-blog.com/pip-install-2/

どうも、anacondaにpathを通しまくれば良い模様。
実際にやってみる。

環境変数のPathに下記を通した。
C:\Anaconda\Library\bin
C:\Users\[あなたのコンピュータの名前]\anaconda3
C:\Users\[あなたのコンピュータの名前]\anaconda3\Library\mingw-w64\bin
C:\Users\[あなたのコンピュータの名前]\anaconda3\Library\bin
C:\Users\[あなたのコンピュータの名前]\anaconda3\Scripts
C:\Users\[あなたのコンピュータの名前]\anaconda3\bin

一度コマンドプロンプトを再起動して、再度仮想環境を起動。djangoインストールを実行。
~~~cmd
(django_venv) C:\django_venv\django_venv\Scripts>pip install django
Collecting django
  Downloading Django-4.0.3-py3-none-any.whl (8.0 MB)
     |████████████████████████████████| 8.0 MB 6.8 MB/s
Collecting sqlparse>=0.2.2
  Downloading sqlparse-0.4.2-py3-none-any.whl (42 kB)
     |████████████████████████████████| 42 kB 3.2 MB/s
Collecting asgiref<4,>=3.4.1
  Downloading asgiref-3.5.0-py3-none-any.whl (22 kB)
Collecting tzdata
  Downloading tzdata-2022.1-py2.py3-none-any.whl (339 kB)
     |████████████████████████████████| 339 kB 6.4 MB/s
Installing collected packages: tzdata, sqlparse, asgiref, django
Successfully installed asgiref-3.5.0 django-4.0.3 sqlparse-0.4.2 tzdata-2022.1
WARNING: You are using pip version 21.2.3; however, version 22.0.4 is available.
You should consider upgrading via the 'C:\django_venv\django_venv\Scripts\python.exe -m pip install --upgrade pip' command.
~~~
無事うまくいきました！感謝感謝です。

# せっかくだからdjangoプロジェクト作成
~~~cmd
(django_venv) C:\>django-admin startproject mysite
~~~

# せっかくだからrunserver
~~~cmd
(django_venv) C:\>cd mysite
(django_venv) C:\mysite>python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
April 01, 2022 - 21:43:23
Django version 4.0.3, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
~~~

http://127.0.0.1:8000/
にアクセスする。無事、トップ画面が表示されました！お疲れ様です。
本当に、簡単ですよね・・・笑

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521517/b57d5d02-21f6-1554-b898-063372610034.png)
PHPのin_array,array_column,array_multisortを駆使してランキング集計してソートするロジックを組んだ話

ランキング集計ロジックを作りたくて実装を進めていた

DBのランキングテーブルは下記のような構成になっていて

|id|no|place_id|
|-|-|-|
|1|1|abc|
|2|2|aaa|
|3|3|bbb|
|4|1|abc|

no(ランキング順)1のものは重みが3
no(ランキング順)2のものは重みが2
no(ランキング順)3のものは重みが1

といった形で集計した結果ポイントが一番高い順に並べるということがしたかった。

このテーブルから
↓

```
[
    {place_id: 1, point: 4},
    {place_id: 2, point: 2},
    {place_id: 3, point: 1}
]
```
こんな感じの結果を作りたかった。

```php
        // place_idごとにポイント集計とかする
        foreach ($ranking_records as $ranking_record) {
            if(in_array( $ranking_record->place_id, array_column( $rankings, 'place_id'))){
                for($i = 0;$i < count($rankings); $i++){
                    if($rankings[$i]['place_id'] == $ranking_record->place_id){
                      $rankings[$i]['point'] = $rankings[$i]['point'] + ($ranking_record->no % 3) + 1;
                    }
                }
            }else{
                $array = array('place_id'=>$ranking_record->place_id'point'=>($ranking_record->no % 3) + 1);
                array_push($rankings, $array);                    
            }
        }
        // ソートする
        $points = array();
        foreach ($rankings as $key => $row)
        {
            $points[$key] = $row['point'];
            
        }
        array_multisort($points, SORT_DESC, $rankings);

        return response(array('result' => array('rankings' => $rankings)));

```

ranking_records:DBから撮ってきた情報
rankings:最終的に取得したいソート済みの値

うーーーーーん、なんかもっときれいに書ける気がする...
Kintone 自動入力「レコード番号」取得方法

目的：自分のメモ
だからちょっと見ずらいけど
がまん、がまん
そのうちうまくなるでしょ。

*レコード追加の際は
```
kintone.events.on(['app.record.create.submit.success'], function(event)
```
レコード保存が完了した後でないと取得できない

```
var record = event['record'];
window.alert('レコードID： ' + record.$id.value + ' 。');
```
取得した後にこの数値を加工しようと思ったけどできるはずもなく、だんねん

以上
Nuxt.jsにBulma extensionsを適用する

Steps componentを適用させたかった
記事が出てこなかったので

![スクリーンショット 2022-04-01 21.26.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265805/00446de5-8b36-20c0-a679-4f51ef1e0878.png)
https://octoshrimpy.github.io/bulma-o-steps/

```
yarn add bulma-o-steps
```

```nuxt.config.js

  css: [
        './node_modules/bulma-o-steps/bulma-steps.min.css',
        ],
```


```Steps.vue
<template>
  <ul class="steps has-gaps is-horizontal">
    <li class="steps-segment" :class="{'is-active':stepNumber === 1}">
      <span class="steps-marker">1</span>
    </li>
    <li class="steps-segment" :class="{'is-active':stepNumber === 2}">
      <span class="steps-marker">2</span>
    </li>
    <li class="steps-segment" :class="{'is-active':stepNumber === 3}">
      <span class="steps-marker">3</span>
    </li>
    <li class="steps-segment" :class="{'is-active':stepNumber === 4}">
      <span class="steps-marker">4</span>
    </li>
  </ul>
</template>
<script>
export default {
  name: "steps",
  props: {
    stepNumber: Number
  }
}
</script>


```
以上
picoCTF2022 Torrent Analyze を勉強した記録

この問題解けたな。もったいない。

鮫のデフォルト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/9bc3814c-f791-1794-458c-2df9e2a0d747.png)

当時はなぜか，BitTorrentにチェックが入っていたので，このままでokと思ってしまった。
保存していたヒント読むと bt-dht にもチェックが必要と明記してあった。

bittorrent_dht_udpにもチェックを入れて進める


bt-dhtでフィルタ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/45c7f9bb-e2d6-396f-d026-4e37f59f520c.png)

会社でダウンロードしてたので２行目のローカルIP　192.168.73.132　でフィルタ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/65abb386-133e-d201-9ec5-67f084ba90a2.png)

hashで検索

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/1660070d-f4bd-55c4-0500-ee9e4e07b978.png)

peerで検索

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/d48e01df-b020-8aee-87a7-79157d99f0f1.png)

e2467cbf021192c241367b892230dc1e05c0580e Bittorrent　をググる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/921179ec-2c59-aef1-ec87-5922c5859ce2.png)

拡張子が iso のファイル発見。
Circleci 自動デプロイで起きたエラー

 # はじめに
今回は、circleciでEC2に自動デプロイを構築しようとした時の備忘録として残します。

# 参考URL
https://qiita.com/ashketcham/items/0518322e5eca2896c0f0

こちらを参考に作成しました。

# 秘密鍵が登録できない
Circleciに秘密鍵を登録しようとした所こちらのエラーが出ました。
![65008A02-5E7B-46C8-A794-251997D38369.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594478/a71217ef-139f-688d-8ced-8d1228bbdea5.png)
どうやら秘密鍵が違うみたいです。
色々と調べてみたら、秘密鍵に形式があるみたいで、Circleciではopenssh形式でなく、rsa形式でないと登録できないみたいです。
なので、とりあえずこちらでコマンドで新しく秘密鍵を上書きにして作成しました。
```
$ openssl rsa -text < server.key
```

これで、opensshのところが、rsaに変わって登録ができました。

# 後一歩のところで...
秘密鍵が登録できたので、いざ自動デプロイと思いましたが、こちらのエラーが出ました。
![510B2180-B0EB-4E33-B13B-06A1575AAC8D.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594478/02002bac-6f56-2f99-964e-fa65233c0e15.png)
bundleのコマンドが見つからないというエラーですが、なぜか分からない。
https://jpcodeqa.com/q/c24d8d58636e89fa9b586761a5d610b2
とりあえずこちらの記事を参考にさせて頂きました。
```deploy-me.sh
#!/bin/bash -l

cd /home/ec2-user/アプリ名/ && git pull && bundle install --path vendor/bundle --without test development && bundle exec rails assets:precompile RAILS_ENV=production
```
こちらを追加したら、自動デプロイが成功しました。

/bin/bashに-lオプションを付けることでログインシェルとして起動されたかのように bash を動作させてくれます。

# まとめ
こちらは、Circleciもそうですが、いろいろな事について勉強不足と痛感しました。
Amazon Route53 主なルーティングポリシー

# はじめに
Markdown記法でテーブルを作ってみた。

# 主なルーティングポリシー
| ルーティングポリシー | 説明 |
|:-:|:-:|
| レイテンシールーティング | 最もレイテンシーが低いリソースへルーティングする |
| 加重ルーティング | 複数のリソースに対して加重度を設定し、指定した比率に応じて処理を分散するようにルーティングする |
| 位置情報ルーティング | 接続クライアントの場所に基づいて、地理的に近い場所へルーティングする |
| フェイルオーバールーティング | ルーティング対象となるリソースのヘルスチェックを行い、利用できるリソースへルーティングする |
| シンプルルーティング | 設定されたレコードの情報に従って、ルーティングする |
| 地理的近接性ルーティング | ユーザーとリソースの地理的場所に基づいてトラフィックをルーティングする |
| 複数値回答ルーティング | 最大8つからランダムに選ばれた正常なレコードを使用し、Route53がDNSクエリに応答する |
vee-validate2のクロスフィールドのカスタムルール設定(例：開始日、終了日チェック)

# 対象
vee-validateのカスタムルールで別のフィールドの値と比較した
クロスフィールドのチェックをしたいのに
検索するとvee-validate v3系の記事ばかりでした。
現場ではv2系(2.2.15)を使っているため、そのままではうまくいかなかったので
v2系のクロスフィールドのカスタムルールの設定の仕方を紹介したいと思います。
公式のクロスフィールドに関する記事も、対象の値の取得の仕方までの記述がなく
参考にならず…。

# 環境
vue v2
vee-validate v2

# 概要
To(終了日)に、From(開始日)以降の日付が設定されているかチェックするサンプルです。

# サンプル
* 追加しているカスタムルールは、`afterDate`です。
`options: { hasTarget: true }`、`paramNames: ["targetValue"]`を設定することで
対象となる`From(開始日)`の値を取得できます。

```js:index.js
import Vue from "vue";
import VeeValidate, { Validator } from "vee-validate";
import ja from "vee-validate/dist/locale/ja";

Validator.localize('ja', ja);
Vue.use(VeeValidate, { local: ja });
Vue.component("ValidationProvider", VeeValidate.ValidationProvider);
Vue.component("ValidationObserer", VeeValidate.ValidationObserer);

Validator.extend('afterDate', {
  options: { hasTarget: true },
  paramNames: ["targetValue"],
  getMessage(field, targetName) {
    return `${field}は、${targetName}よりも後の日付を入力してください`;
  },
  validate(value, target) {
    const afterDate = value;
    const beforeDate = target.targetValue;
    if (!afterDate || !beforeDate) return true;
    // yyyyMMdd形式でデータ来る想定で単純比較してますが、
    // 適宜、日付比較関数を使ってください。
    return beforeDate <= afterDate;
  }
});
```

* vue側では、`vid`の設定が必要です。
(*vee-validate v3系だと@のみでOKみたいですが)

```index.vue
<template>
  <div>
    <validation-provider v-slot="{ errors }" name="開始日" vid="from" rules="required">
      <input type="date" v-model="dayFrom" />
      <p v-if="errors.length">{{ errors[0] }}</p>
    </validation-provider>
    <label>～</label>
    <validation-provider v-slot="{ errors }" name="終了日" vid="to" rules="required|afterDate:from">
      <input type="date" v-model="dayTo" />
      <p v-if="errors.length">{{ errors[0] }}</p>
    </validation-provider>
  </div>
</template>
<!--　省略 -->
```

# 最後に
* 単純に日付を比較するならdate_formatとafter(もしくはbefore)でいいのでは？　とも思い
試したのですがdate_formatがうまく機能しませんでした。
そのためカスタムルールで自作することに。
v2系か、v3系で大きく記述が異なるのでかなり苦労しましたが、
この記事がお役に立てればなによりです。
■実装を行うにあたって、踏まえておくべきポイント


●最初にテスト仕様書を作成する。
　実装漏れを防ぐ効果と、実装できていない箇所を数値化し明確な進捗を把握することができる。

●エラーが発生したら、エディタに
　・内容
　・取得した情報
　・試している解決案を書く
　➝同じ解決を繰り返さないために。

●モジュールごとの「IN」「OUT」をあらかじめ定義しておく。
　そのモジュールの役割の明確化できる。

●前日に明日の作業概要を練っておく。
廃止されたJavaアプレットをブラウザ外で動かしてみました

# はじめに
本投稿の内容は、ブラウザ上でJavaアプレットを動かすものではありません。

現状として私は何度か繰り返し使う可能性が高い方法です。なのに忘れそうです。
ここにメモしておきます。

# 環境および前提
Windows10.

この方法ではJavaアプレット本体のソースが不可欠です。
今回は、動かしたいJavaアプレットが載っているページの管理人様が、github上でアプレットの[本体であるソース](https://github.com/edpegg/CutTheKnot-Java)を公開していました。
(あまり公開されているものとは思いません。が、今回のケースに関しては公開することで、Javaアプレットの廃止に対応できないことを補う意図があったそうです。非公開だけどどうしても使いたいなら、管理人様にお願いすることになるのかもしれません。)

また、JavaがPCにインストールされていることが必要です。
今回の環境は下記。
```
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) Client VM (build 25.131-b11, mixed mode)
```

# 背景
JavaアプレットはJava11以降は廃止の技術です。

それでも、例えば[ここcut-the-knot.org様のコンテンツ](https://www.cut-the-knot.org/Curriculum/Arithmetic/S1089.shtml)のように、
Javaアプレットを用いたページがインターネット上にはまだ存在していて、それを動かしてみたいことがあります。

しかし、主要なブラウザでは既にサポートが廃止されています。
つまり最新バージョンのブラウザ上では実行できないはずです。
私が使っているブラウザ5つのどれもが実行できませんでした。

# 問題

ブラウザ外でどうすればJavaアプレットを動かせるか。
個人的に使った方法を共有します。
Java関連の知識が無いので正攻法ではないかもしれません。

# 解決策

Java SEをインストールすると附属してくるappletviewer.exeというツールを使うと、appletを動かすことができます。

## 定義
- Javaアプレットを使用しているページを仮に「applet.html」とします
- Javaアプレットの本体であるクラスが格納されたフォルダを「classes」とします
- applet.htmlとclassesを格納したフォルダを「c:\tmp\demo」とします

## 手順アウトライン

1. applet.htmlを入手します
2. classesを入手します
2. applet.htmlとclassesを、`c:\tmp\demo`に配置します
2. applet.htmlの内容を修正します
2. appletviewer.exeを使ってアプレットを動かします

## 手順詳細

アウトラインの1~3については、今回はファイルを単にダウンロードして、ディレクトリ作って配置するだけで済みました。
主に「applet.htmlの内容を修正」、および「appletviewer.exeを使ってアプレットを動かす」段階を忘れそうなので書いておきます。

### applet.htmlの内容を修正します

仮に、applet.htmlの中身の`<applet>`要素の中身が下記のようであったとします。
`<applet code="C" codebase="../../classes" archive="A.zip,B.zip,C.zip">`

codebaseを下記のように修正します。
`<applet code="C" codebase="classes" archive="A.zip,B.zip,C.zip">`

以上です。
要は、アプレットのコードが格納されたディレクトリを、自分の格納したディレクトリへと変更しています。

### appletviewer.exeを使ってアプレットを動かします
1. appletviewer.exeが格納されたフォルダを探します。
2. 見つかったフォルダでコマンドプロンプトを起動します。
3. コマンドプロンプト内で下記のコマンドを打ちます。

`appletviewer.exe "C:\tmp\demo\applet.html"`

これでアプレットを動かせました。

# 個人的な感想など

demoディレクトリの作成及び配置が終わってしまえば、同じアプレットを使うhtmlは、上記の通り一部修正するだけでアプレットを動かせるようになります。
なので、今後私は、同じドメインの他のページでJavaアプレットを使っているなら、同じディレクトリ(今回はdemo)にhtmlをまとめておくことにします。

廃止の技術なのでいつまでこの方法で動かせるかわかりません。
appletviewer.exeが使えなくなれば、この忘備録の価値もなくなります。
あるいは、仮想マシンなどに古いJavaをインストールしたりして環境を再現すれば動かせないこともないです。面倒ですが。

またこの忘備録の方法を他のシチュエーションで使いたくなったら、再利用性ありということです。
再利用性があるということであれば、Javaアプレットを調べなおして(廃止だからあまり時間かけたくない)、よりしっかりした方法を見つけようと思います。

# 参考リンク
- [本投稿で例示した数学関係コンテンツを公開してくださっているcut-the-knot.orgサイト管理人様の、アプレットについての説明](https://www.cut-the-knot.org/HelpWithJava.shtml)
- [Oracle公式ドキュメントのappletviewer.exeの使い方](https://docs.oracle.com/javase/jp/7/technotes/tools/windows/appletviewer.html)