OmniAICreator/Qiita-1.07M huggingface dataset:
LINE bot を作ってみた

何番煎じかわからんけど、興味が湧いたの作ってみました

# 環境
- Google Spread Sheet
- Google Apps Script
- LINE Developers

# 経緯
- とりあえず LINE Developers に登録したけど、サーバーを一から作るのはめんどくさい
- GAS でできないか？と思い立って調べてみたら、多くの先人が同じ道を通っていた
- じゃあ少し前に流行ったズンドコキヨシを作ってみよう

# 手順（概要）
1. LINE Developers 登録
2. LINE Developers 設定
3. GAS 構築
4. Google Spread Sheet 公開
5. LINE Developers に Webhook URL を登録
6. 動作確認

# 手順（詳細）
## 1. LINE Developers 登録
- 酔っ払いながら登録したので、特に調べずにできるはず
- [ここから](https://developers.line.biz/ja/)登録

## 2. LINE Developers 設定
- https://developers.line.biz/console/channel/{id}/ でトークンを発行する
    - [MessagingAPI設定] > [チャネルアクセストークン] の「発行」を押下
- https://manager.line.biz/account/{account_id} ページでメッセージに関する設定する
    - [応答メッセージ] にあるデフォルトメッセージを disable
    - [トークルーム管理] > [あいさつメッセージ] を編集
    - 以下のようなリッチメッセージを作成
        ![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167986/473e1f8e-7a76-37ae-59da-0597b613486e.png)

## 3. GAS 構築
- 以下にソースを置きました
    - https://github.com/soso555BoBs/linebot_with_gas

## 4. Google Spread Sheet 公開
- エディタ右上 [デプロイ] > [新しいデプロイ]
    ![screenshot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167986/57d6eacd-2283-0eef-c05c-907dcddc24c0.png)
- 注意点
    - Google アカウントでのログインを求められた場合、ログイン後の画面で「詳細」リンクを押して承認する必要がある
    ![screenshot3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167986/2fe28b09-656a-8ca2-a093-9ad6c8141ec3.png)

## 5. LINE Developers に Webhook URL を登録
- Google Spread Sheet を公開した際に URL が発行される
- 発行された URL を LINE Developers Console の [MessagingAPI設定] > [Webhook URL] に入力
- [Webhook の利用] を有効化

## 6. 動作確認
- 動いた！

![capcha.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167986/d7dafc64-42c7-5e59-7944-ea06d8089a59.jpeg)


# 感想＆注意点
- GAS のデバッグ実行時に、関数への引数を注入する方法がわからなかった…
    - ので、デバッグする時には引数にデフォルト値を設定して実行してました
    - もっと良い方法は無いのだろうか
- GAS 修正後に WEB アプリケーションに反映させたい場合は以下手順が必要になる
    1. エディタ右上の [デプロイ] > [デプロイを管理]
    2. 鉛筆マークを押して編集画面を開く
    3. [バージョン] で「新しいバージョン」を選択
    4. [デプロイ] ボタンを押す
- 実行時エラーのログを見る方法がわからない…
    - グワーっと実装して動作確認しながら微調整していたので、エラーが発生しても原因がわからず結構口数がかかってしまった
- LINE Developers への登録含めて、おそらく 4 時間くらいかかった
    - とりあえず動かすことが目的なので、コピーコードも多くて恥ずかしい
NAS初期設定(その3) コンパネ＞権限設定

# コンパネ＞権限設定

## ユーザ (設定変更なし)
とりあえずadminだけで運用する予定。必要になったら追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407847/ce764470-0138-2798-2a97-75869a1afc58.png)


## ユーザグループ (設定変更なし)
とりあえずadminだけで運用するため変更なし。必要になったら追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407847/9267f74c-72e5-d100-b545-c700e6f12ac9.png)


## 共有フォルダー (設定変更なし)
ストレージの設定後に設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407847/4bb116ae-26d2-4892-ab8b-fa4b3a03623d.png)


## クォータ (設定変更なし)
とりあえずadminだけで運用するため変更なし。必要になったら追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407847/86294348-6743-025b-bd65-006ba4a1560e.png)


## ドメインセキュリティ
### Windows AD/LDAP (設定変更なし)
ActiveDirectoryもLDAPも使用しないので設定なし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407847/7aed29ec-b785-58ac-039e-76e5f892c4b0.png)

### SSO (設定変更なし)
Azure SSO は使用しないので設定なし。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407847/b5b025cb-8754-0a32-87ba-5543c31a96fc.png)


## ドメインコントローラ (設定変更なし)
ボリュームを作成してから設定する。けど多分使わない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407847/18fe70e6-aa84-3aa3-6ca9-d60ca4f9f450.png)


権限設定は以上。
Perl: ファイルのアップロード (cgi)

こちらと同じことを Perl で実装しました。
[Python3: ファイルのアップロード (cgi)](https://qiita.com/ekzemplaro/items/214394d653e4ee8bd8b8)
複数のファイルを同時にアップロードできます。
![upload_perl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c94daf03-9a7f-44d1-660e-90254106b60f.png)


```html:upload_perl.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>upload perl (Apr/11/2021)</title>
</head>
<body>
<h2>HTML5</h2>
<form method="post" action="upload_perl.pl" enctype="multipart/form-data">
<input type="file" name="files"  multiple>
<p><input type="submit" value="送信する"></p>
</form>
<p>Files will be uploaded to /tmp.</p>
<hr />
<p>Apr/11/2021 AM 08:25</p>
</body>
</html>
```

```pl:upload_perl.pl
#! /usr/bin/perl

use	strict;
use	utf8;
use	warnings;
use	CGI;
use	File::Copy;

# --------------------------------------------------------------------
my $SAVE_DIR = '/tmp';

my $q = CGI->new;
my @files = $q->param ('files');
print "Content-type: text/html\n\n";
for my $filename (@files)
{
	copy($q->tmpFileName($filename), "$SAVE_DIR/$filename") or die $!;
	print $filename . "<br />";
}

print	"Data is saved<br />";
#
exit;

# --------------------------------------------------------------------
```
Vue.jsでtopへ戻る機能を実装

Vue.jsで実装した機能を備忘録として記録する。
※Vue-CLIを使用しています。
<br>


```html:template
<div class="footer">
   <i class="icon-up-open-big scrollToTop" @click="scrollTop"></i>
</div>
```

<br>

```javascript:js
export default {

  data() {
      return {
          scrollY: 0
      }
  },

  mounted() {
    window.addEventListener('scroll', this.handleScroll);
  },

  methods: {
    handleScroll() {
        this.scrollY = window.scrollY;
        let scrollToTop = document.getElementsByClassName("scrollToTop")[0];

        if(scrollY > 100) {
            scrollToTop.style.display = "inline";
        } else {
            scrollToTop.style.display = "none";
        }
    },

    scrollTop() {
      window.scrollTo({
        top: 0,
        behavior: "smooth"
    });
  }
  }
}

```
CML2を使いこなす。（その２：ライセンスの登録）

# はじめに
前回はデプロイまで行ったので、今回はライセンス登録を行って`CML2`を使用できるようにしたいと思います。

- 【前】[CML2を使いこなす。（その１：ダウンロードとデプロイ）](https://qiita.com/sakai00kou/items/e91e747cac7fe07bb6aa)
- 【次】[CML2を使いこなす。（その３：ラボの作成）](https://qiita.com/sakai00kou/items/d8f24018a7fd89d54ae6)

# ライセンスの取得
前回`CML2`のイメージファイルをダウンロードした画面に「**2.x License**」ボタンがあるので、ボタンをクリックしてライセンスを表示させます。

ライセンスは後ほど使用するため、控えておきます。

![capture_12032021_080941.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/37747120-3136-8106-ab0e-103a370c0cea.jpeg)

# CML2管理画面へのログイン
コンソール画面に表示されているURLにアクセスします。

![capture_18032021_072901.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/7c699d30-722f-ec19-1a4f-e5983f0199a6.jpeg)

以下のログイン画面が表示されるため、デプロイ時に入力したadminパスワードを入力します。

![capture_20032021_173755.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/4eeecb79-ab30-83d2-f7c3-e0178498c59e.jpeg)

`CML2`の管理画面にログインすると以下のような画面が表示されます。

ライセンス登録がされていない場合、右下の`System Health Issue`が赤く表示されます。

![capture_20032021_174250.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/2c295f38-28d6-5305-b274-54b0317d86b7.jpeg)

# ライセンスの登録
画面右上の`TOOLS`から`Licensing`を選択すると以下画面が表示されます。

ライセンスを登録するには、インターネット接続する必要があるので、インターネット接続していない場合は接続できるようにして実施します。

![capture_20032021_175106.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/21f5f0d8-6e6d-75b0-473b-06d06bf23769.jpeg)

画面の`REGISTER`ボタンを押すと、以下のToken入力画面が表示されるので、先ほど控えたライセンス情報を入力します。

![capture_20032021_175738.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/21f5101e-b0d5-ce87-9c82-f29df04f30db.jpeg)

以下の様にステータスが`Authorized`になれば終了です。

![capture_20032021_180145.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/066f8dc5-3111-6a77-d596-c046c81b7652.jpeg)

# おわりに
ライセンス登録を行うことでようやくラボを作成できる状態となりました。

ライセンス登録後はデプロイしている仮想マシンとライセンスが紐付けられるため、誤って仮想マシンを削除してしまうと、同じライセンスを入力しても認証されないので注意してください。

もし、誤ってライセンスの紐付けを解除する前に仮想マシンを削除してしまった場合は以下の方法でクリアしましょう。

- [Cisco Modeling Labs v2.0 (CML2) のライセンスクリア方法](https://qiita.com/sakai00kou/items/2393904243925d4f1dcc)

次回はラボの作成とラボマシンへのコンソール接続を行おうと思います。
【メモ】intervention/imageを使って画像のリサイズとストレージへの保存

## バージョン

- PHP7.3
- Laravel7.30

## ライブラリのインストール

```bash:
$ composer require intervention/image
```

## 実装

### プロバイダ登録

```php:config/app.php

'providers' => [
  // 中略
  App\Providers\RouteServiceProvider::class,
  Illuminate\View\ViewServiceProvider::class,  // 追加
],

'aliases' => [
  'InterventionImage' => Intervention\Image\Facades\Image::class,
]
```

```bash:/var/www/laravel
$ php artisan config:cache
```

### 保存

横幅 500px で保存してみる

```php:

public function store(Request $request)
{
  if (Storage::missing('public/resized')) {
    Storage::makeDirectory('public/resized');
  }

  $file = $request->file('test_image');
  $response = $this->putResizedFile($file, storage_path('app/public/resized/test_image.' . $file->extension()), 500);

  return response($response, 200);
}

/**
  * @param $fileData = リソース
  * @param string $tempPath = 保存先
  * @param int $width サムネイルのサイズ
  * @return \Intervention\Image\Image
  */
protected function putResizedFile($fileData, $tempPath, int $width)
{
  return \InterventionImage::make($fileData)->resize($width, null, function ($constraint) {
    $constraint->aspectRatio();
  })->save($tempPath);
}
```

### 削除

Storage ファサードを使う

```php:
Storage::delete('public/resized/test_image.png');
```

### 注意点

`storage/app/public`直下に`resized`ディレクトリがない場合、勝手にディレクトリを作るようなことはなくエラーが出るため**`Storage::missing()`**でチェックしている。<br>

```log:storage/laravel.log
"Can't write image data to path (/var/www/laravel/storage/app/public/resized/test_image.png)"
```

この点、`Storage::put('public/resized/test_image.png')`の場合は勝手に作ってくれることと比較。
GoogleAppsScript トリガー設置、発動後トリガー削除

実行した２分後にトリガー設置
トリガー発動後、セットしたトリガーを削除

メインの関数にsetTrigger()入れとく。


```

// コピーして値のみ貼り付け（E~K列）
function pasteOnlyValue() {
  SHEET.getRange('E:K').activate();
  SHEET.getRange('E:K').copyTo(SHEET.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);

  delTrigger();
 }

// 三分後にpasteOnlyValue()のトリガー設置
function setTrigger(){
  const time = new Date();
  let hour = time.getHours()
  let minutes = time.getMinutes()
  time.setHours(hour);
  time.setMinutes(minutes + 2);
  ScriptApp.newTrigger('pasteOnlyValue').timeBased().at(time).create();
}

// トリガー削除
function delTrigger() {
  const triggers = ScriptApp.getProjectTriggers();
  for(const trigger of triggers){
    if(trigger.getHandlerFunction() == "pasteOnlyValue"){
      ScriptApp.deleteTrigger(trigger);
    }
  }
}
```
VBAを使ってスクレイピングの結果をメール送信する（さくらのレンタルサーバー使用)

スクレイピングの結果を即知りたいというのはよくある話。
Apiを使って結果を登録するのがいいのですが・・
「今日中に」とかいきなり言われると、社内ツールのアカウント手続きとか間に合わなくて。

そんな場合は自分のメールアドレスを使い結果を送信します。

自分の会社はさくらのレンタルサーバーをつかっているのですが、メールの設定がさくらのレンタルサーバーになっている記事が少なかったのでこちらにメモします。

VBAを使ってメールを送信するには以下のサイトが詳しくてわかりやすいです。
ほぼ下記のサイトそのままなのですがさくらのレンタルサーバー用にアレンジしました。
[VBAでメール送信する(CDO:Microsoft Collaboration Data Objects）](https://excel-ubara.com/excelvba4/EXCEL233.html)
※上のサイトでMicrosoft CDO for Windows 2000 Libraryの参照設定をしたら下の関数が使えるはずです。
※smtpサーバーなどメールの設定がわからないという場合はoutlookなどメーラの設定を参考にするとできます。

```:vba

'*******************************************************************************
'メールを送信する さくらのレンタルサーバー使用
'-------------------------------------------------------------------------------
'   引渡値 = ①メール件名
'　　　　　　②メール本文
'            ③送信先メールアドレス
'   戻り値=エラーなし　true　エラー false　　プログラム的にエラーがあるかないかだけで実際に届くかどうかは別
'   参考＝　https://help.sakura.ad.jp/206206021/
'　　　　　　http://mofuken.blogspot.com/2014/07/windows-cdomessage.html
'           http://hiroses.seesaa.net/article/365310670.html
'*******************************************************************************

Function SendSakuraMail(kenmei As String, mozi As String, address As String) As Boolean

    Dim objCDO As New CDO.Message    

    On Error GoTo Errlabel    'エラー処理

    With objCDO
    
        With .Configuration.Fields 
            .Item(cdoSMTPServer) = "ここにSMTPサーバー名を記入" 
            .Item(cdoSendUsingMethod) = cdoSendUsingPort
            .Item(cdoSMTPServerPort) = 587 　　　　　　　　　　　　'送信サーバーのポート番号
            .Item(cdoSMTPConnectionTimeout) = 15 　　　　　　　　　'タイムアウト
            .Item(cdoSMTPAuthenticate) = cdoBasic 　　　　　　　　　'SMTP認証
            .Item(cdoSMTPUseSSL) = False 　　　　　　　　　　　　　　'SSL
            .Item(cdoSendUserName) = "ここに送信元ユーザーのメールアドレスを記入" 
            .Item(cdoSendPassword) = "ここに送信元ユーザーのパスワードを記入" 
            .Item(cdoLanguageCode) = CdoCharset.cdoShift_JIS 　　　　　　　　　'文字セット指定
            .Update '設定を更新
        End With
        With .Fields
            '重要度、通常は以下のどちらかで良いでしょう
            .Item("urn:schemas:mailheader:X-Priority") = 1
            .Item("urn:schemas:mailheader:X-MsMail-Priority") = "High"
            .Update '設定を更新
        End With
        .MDNRequested = False '開封確認
        .MimeFormatted = True 'MIMEを使って書式設定
        .From = "送信元ユーザーのメールアドレス"
        .To = address                        '関数の引数で受け取った送信先
        .CC = "CCに付け加えたいメールアドレス"
        .subject = kenmei                    '関数の引数で受け取った件名
        .TextBody = mozi                    '関数の引数で受け取ったメール本文
        .Send                                  '送信
    
    End With
    
    Set objCDO = Nothing
    
    SendSakuraMail = True
    
    Exit Function
    
    
    
Errlabel:
    
    
    SendSakuraMail = False　　　'何かしらのエラーの場合はfasleをreturanする
    
    
End Function

```

SSLの部分をfalseにしてみたり、ポート番号をいろりろ調整し、やっと送信できました。
このままできなかったら間に合わないと焦っていたのでできてよかったです。
Rubyの環境構築の備忘録(アプリケーション導入編)

# VSCode(Visual Studio Code)のインストール
[VSCodeダウンロードページ](https://code.visualstudio.com/)からエディタをダウンロード
↓
エディタをアプリケーションフォルダに移動
↓
Dockに配置
↓
エディタを起動
↓
[システム環境設定]を開き、[セキュリティとプライバシー]をクリック
↓
[一般]タブを開き、画面下部の「ダウンロードしたアプリケーションの実行許可」にある[このまま開く]をクリック
# テキストエディタの拡張機能導入
日本語設定
起動したウィンドウ画面左側の、アイコンメニュー内にある四角のアイコンをクリック
↓
左上の「Search Extensions in Marketplace」に「Japanese Language Pack for Visual Studio Code」と入力
Japanese Language Pack for Visual Studio Codeを選択し、install（またはインストール）をクリックする
右下のRestart Nowをクリックして再起動すると、日本語設定になっている

# HTMLとCSSの自動補完機能の追加
起動したウィンドウ画面左側の、アイコンメニュー内にある四角のアイコンをクリック
↓
左上の「Marketplaceで拡張機能を検索する」に「HTML Snippets」と入力
↓
HTML Snippetsを選択し、install（またはインストール）をクリックする
↓
インストールが完了して、アンインストールの表示がされれば完了
# Rubyの構文チェック機能を追加
起動したウィンドウ画面左側の、アイコンメニュー内にある四角のアイコンをクリック
↓
左上の検索欄に「Ruby」と入力
↓
Rubyを選択し、install（またはインストール）をクリックする
↓
インストールが完了して、アンインストールの表示がされれば完了
# 全角スペースのチェック機能の追加
起動したウィンドウ画面左側の、アイコンメニュー内にある四角のアイコンをクリック
↓
左上の検索欄に「zenkaku」と入力
↓
zenkakuを選択し、install（またはインストール）をクリックする
↓
インストールが完了して、アンインストールの表示がされればインストール完了
↓
command + shift + pの3つのキーを同時入力し、コマンドパレットという設定ファイルの検索画面を開く
「> Enable zenkaku」と入力して選択する
↓
command + Qの2つのキーを同時入力し、VSCodeを終了する。
# zenkakuの機能を常時ONにするための設定
finderでホームディレクトリを開く
↓
command + shift + .で隠しディレクトリを表示する
↓
.vscode > extensions > mosapride.zenkaku-0.0.3 > と移動する
↓
extension.jsを2本指タップしてメニューを表示する
↓
「このアプリケーションを開く」から「テキストエディット」を選択する
↓
5行目の「var enabled = false;」を「var enabled = true;」に変更してcommand + Sで保存する
# コードのスペルチェック機能の追加
起動したウィンドウ画面左側の、アイコンメニュー内にある四角のアイコンをクリック
↓
左上の「Marketplaceで拡張機能を検索する」に「Code Spell Checker」と入力
↓
Code Spell Checkerを選択し、install（またはインストール）をクリックする
↓
インストールが完了して、アンインストールの表示がされれば完了
# tabキーで入力される半角スペースの数を設定
VSCodeのサイドバーより、「管理（下部の歯車マーク）」→ 「設定」の順に選択
Editor: Tab Sizeを２に設定
Editor: Render Whitespaceで「all」を選択
# オートセーブ設定
VSCodeのサイドバーより、「管理（下部の歯車マーク）」→ 「設定」の順に選択
オートセーブの設定で「onFocusChange」を選択

これで半分終わり
C言語+MPIのtips（MPIでのファイル出力（愚直編））

【目的】
並列計算で各プロセスでの計算結果を一つのファイル（data.datと名付ける）にまとめる。
MPI-IOは使用しない。

【使用するもの】
open-mpi

【環境】 
$ mpicc —version
 Apple clang version 11.0.3 (clang-1103.0.32.29)
Target: x86_64-apple-darwin20.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

【方法】

```c:Mpi_file.c 
#include<stdio.h>
#include"mpi.h"

int main(int argc, char *argv[]){
  int i;
  int num;
  int nprocs,myrank;
  char filename[20];
  FILE *fp;

  MPI_Init(&argc,&argv);
  MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
  MPI_Comm_rank(MPI_COMM_WORLD,&myrank);

  num=nprocs*(myrank+1);
  sprintf(filename,"data_%02d.dat",myrank);
  fp=fopen(filename,"w");

     fprintf(fp,"data_0%d.dat is open",myrank);
     for(i=0;i<num;i++) fprintf(fp,"!");
     fprintf(fp,"\n");
     fprintf(fp,"ID: %d, num= %d\n",myrank,num);
     fprintf(fp,"data_0%d.dat is closed",myrank);
     for(i=0;i<num;i++) fprintf(fp,"!");
     fprintf(fp,"\n");

  fclose(fp);
  MPI_Finalize();
  return 0;
}
```

【結果】
mpicc コマンドでコンパイル、mpirun コマンドでプロセス数を２にして実行。  

```
$ mpicc Mpi_file.c           
$ mpirun -np 2 ./a.out                                                                            
```

ターミナルで ls コマンドを実行すると、data_00.dat、data_01.dat が作成されている。

```
$ ls
Mpi_file.c    a.out      data_00.dat      data_01.dat
```

さらにcatコマンドでファイルの中身を見てみる。

```
$ cat data_00.dat            
data_00.dat is open!!
ID: 0, num= 2
data_00.dat is closed!!
```

```
$ cat data_01.dat  
data_01.dat is open!!!!
ID: 1, num= 4
data_01.dat is closed!!!!
```

【考察（何が起きたのか）】
まずプロセス０と１でnumが計算される。
at プロセス０　num=2*(0+1)=2
at プロセス１　num=2*(1+1)=4
次にdata_00.dat と data_01.datが作成される。
data_00.datではプロセス０の計算結果が出力される。
data_00.dat is open!!
ID: 0, num= 2
data_00.dat is closed!!

data_01.datではプロセス１の計算結果が出力される。
data_01.dat is open!!!!
ID: 1, num= 4
data_01.dat is closed!!!!

それぞれのファイルが閉じて終了。
これらを一つにまとめるにはcat コマンドの出力結果をdata.datにリダイレクトすれば良い。

```
$ cat data_00.dat data_01.dat > data.dat
```

ワイルドカードを使うと楽できる。ここでは?でも*でも良い。

```
$ cat data_0?.dat > data.dat
```

```
$ cat data_0*.dat > data.dat
```

ls コマンドでdata.dat ができていることを確認。さらにcat コマンドで data_00.dat、data_01.dat の順番に結果がまとめられていることを確認。

```
$ ls
Mpi_file.c    a.out      data.dat     data_00.dat      data_01.dat
```

```
$ cat data.dat
data_00.dat is open!!
ID: 0, num= 2
data_00.dat is closed!!
data_01.dat is open!!!!
ID: 1, num= 4
data_01.dat is closed!!!!
```                      
　
【参考】
MPIのファイル出力については「mpi i/o」「mpi io」などと検索するとさらに情報が得られると思います。
オブジェクト指向プログラミング(OOP)の恩恵を歴史的な経緯から読み解く

「オブジェクト指向は難しい」と色々な人がぼやくが私すんなり理解したと思っていたので
自分の理解が甘いのかプログラミングの変遷を直接体験してないから素直に受け入れられたのか…

いずれにせよはっきりさせるために改めてオブジェクト指向プログラミング(OOPk)とその恩恵を<strong>プログラミングの歴史を踏まえ</strong>調べまとめた。

# なぜオブジェクト指向プログラミングが必要なのか？
### ソフトウェア危機
2000年にはソフトウェア開発需要にプログラマの供給が足りなくなるという話し。
その為により保守性の高いプログラミングができるようにしなければならなかった。

しかしそれまでは書いたコードをいつまでも使いまわすなど考えていなかったため
保守性という観点が少なかった。
それまでは

+ 生産性  :簡単な表現
+ 品質    :複雑さを避ける

という観点からプログラム・言語そのものの開発が行われていた。

その認識にメスをいれるため新たに下記の指針が生まれた。

+ 保守性  :分かりやすいプログラム
+ 再利用性:重複ロジック削除、部品化による再利用促進

この時点で<strong>貧弱な再利用性、保守性（後述の「グローバル変数問題」)</strong>が課題となっており
これを解決するため、オブジェクト指向という考え方が生まれた。

##### 貧弱な再利用性
OOP以前はプログラムの再利用と言えばサブルーチン(関数)の共通化があった。
しかし一つの共通サブルーチンを変更するとその影響範囲が大きく迂闊に手出しできなかった。

<strong>新たな共通化手法が必要 => ポリモーフィズム</strong>

##### 保守性 (＝グローバル変数問題)
グローバル変数はプログラム内ならどこからでも呼び出せるため、影響範囲が広く一度修正するとその波紋がどこまで及ぶか想定することが難しかった。
ローカル変数では影響範囲は狭いものの関数が終わったら破棄されるという短命さ故、
複数のメソッドで共通する変数はグローバル変数を使わざるを得ないという問題があり保守性を大きく下げていた。

<strong>変数のスコープを限定する手法が必要　=> 「クラス」という単位</strong>

# OOPの三大要素

### 1. クラス
仕組み：「まとめて、隠して、たくさん作る」  
恩恵：
・後述のポリモーフィズム、継承によりコード量を減らせる。
・「インスタンス変数」「グローバル変数の長命さ」「ローカル変数の影響範囲の狭さ」を手に入れた。
これによって<strong>グローバル変数問題</strong>を解決。

+ 「まとめて」命名が短くなる。
サブルーチンと変数をまとめる
openFile, closeFile, readFileをFileクラスにまとめることでopen, close, readとできる。

+ 「隠して」変数の変更影響範囲を制限できる。(『グローバル変数問題』の解決)
クラス内部だけで使う変数(グローバル変数)やサブルーチンをかくす。
アクセサ修飾子を用いることで影響範囲をコントロールできる。

+ 「たくさん作る」
１つのクラスからインスタンスをたくさん作る。



##### インスタンスとは
実体を表現する方法ではなく、クラスで定義したインスタンス変数のメモリを確保する方法。()
これによりいくつでもメモリ領域を確保できる。

OOPで良く見る下記表現は複製したインスタンスのうち、どれを使うか指定するための書き方。

```
//TextFileReaderクラスから二つのインスタンス生成
TextFileReader reader1 = new TextFileReader();
TextFileReader reader2 = new TextFileReader();

//一つ目のインスタンスを指定し、メソッドを実行している。
reader1.open("C:\\aaa.txt");
```
##### ローカル変数、グローバル変数、インスタンス変数
原初の変数はグローバル変数である。
・プログラムどこからも呼び出せる
・アプリ開始～終了までいる(メモリを確保)
・複製できない。

OOP以前にグローバル変数問題を解決するため現れたのがローカル変数である。
・1つのサブルーチンからしかアクセスできない。
・サブルーチン呼び出し時に作られ、終了時に破棄。
・複製できない。

OOPのクラスの「たくさん作る」能力を使うために作られたのがインスタンス変数
ローカル変数と混同していたが、クラス直下の変数をインスタンス変数と言う。
・アクセス範囲は自由に指定できる。
・ンスタンスが作られてから不要になるまで。
・複製可能。このために存在する。

### 2. ポリモーフィズム
仕組み：「共通メインルーチン」を作ることで、サブルーチンを呼び出す側のロジックを一本化する。
恩恵：
・コンストラクタで引数を設定することで、処理のみの記述にできる。
「猫が鳴く」ではなく「鳴く」という処理にできる。引数に「猫」や「犬」を入れる。
これによって<strong>貧弱な再利用性問題</strong>を解決。


### 3. 継承
仕組み：クラス定義の共通部分を別クラスにまとめ、重複を排除する。
恩恵：
以前は共通サブルーチンという形で命令群をまとめていた。


# まとめ
なんとなくで話していたポリモーフィズムの意味を理解できた。
歴史的経緯を知ると当たり前のようにやっていることにありがたみが湧いてくる。

多分、これからプログラミングをする人はOOPでつまずくことはないと思った。

# 参照
[オブジェクト指向でなぜつくるのか 第2版](https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%A7%E3%81%AA%E3%81%9C%E3%81%A4%E3%81%8F%E3%82%8B%E3%81%AE%E3%81%8B-%E7%AC%AC2%E7%89%88-%E5%B9%B3%E6%BE%A4-%E7%AB%A0/dp/4822284654)
React Native + Expo CLI 環境構築 Windows編

# Expo さわってみる
React Native + Expoは使ったことがなく、既存案件のネイティブアプリはXamarinを使用している。
それに対し、WebサイトはReact + javascriptやReact + typescriptで構築している。
これまでは様々な事情があり上記の構成で運用してきたが、Reactで使用している業務ロジックをネイティブアプリでも使用していくことで効率化を図りたい。
よってReact Native + Expoを開発環境作成から進めてみる。

百聞は一見に如かずではないが、聞くでも見るでもなく、とにかく一度動かしてみよう！

## インストール
expo-cliのインストール(npmやnodeが入っている前提)

```
npm i -g expo-cli
```

## プロジェクト作成とコンパイル
プロジェクトを作成のディレクトリまで移動

```
expo init myFirstApp
```
今回はTypeScriptを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/fc36dbf4-4766-a339-f119-25894a5588fb.png)

プロジェクト作成完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/03727a13-21c5-ad27-ccee-cf7400494d13.png)

expo実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/09b4f6d9-760c-1906-e173-05dde9704254.png)

エラーですね。package.jsonがないと言っている。焦ってはいけません。
プロジェクト作成後に作成したディレクトリに移動してからexpoの実行
実行できると規定のブラウザ(http://localhost:19002/)が起動します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/19ce92d6-d26c-5658-cfbf-7553b1b7680c.png)


##　実行
App.tsxが作成されていることを確認して、コンポーネントの一部を変更して実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/39c9900a-0a8b-9c0b-b508-6a9022a73ae8.png)

スマホアプリでQRコードを読み取りアクセスすると画面が表示される
![62043.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/f2c2055c-6c59-5773-aee4-1285f1201f01.jpeg)


## ここまでのまとめ
React Native + Expo CLI 環境構築 と実効までの時間はnpmやNode.jsなどインストール10分程度。非常に簡単に開発環境を構築できることはメリットである。
fargateコンテナに入りたい時はECSexecを使おう

#1. 初めに
初投稿です！未経験からエンジニアに就職を目指しているshotaと申します。
ポートフォリオ作りでインフラの勉強の為、fargateを利用したデプロイをしていたのですが、データのやりとりが中々上手くいきませんでした。
ローカルでは問題ないのに...
こういった場合、コンテナの中に入ってローカルとの差分を見るのは一つの選択肢にあるのかなと思います。
ecs（ec2)ならec2インスタンスにSSH or SSMでログインしてdockerコマンドで直接ログインする方法があると思います。
ですが,ecs(fargate)の場合は今までに公式的なログイン方法はありませんでした。
そこで、どうにか方法が無いか調べていると、awsからセッションマネージャーを利用して、SSMエージェント経由でクライアントからコンテナへのアクセスができるという素敵なコンテンツが提供されているのを知りました。
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html
クラスメソッドさんもとても分かりやすく紹介していました。
https://dev.classmethod.jp/articles/ecs-exec/
使用できる条件があるので公式を見てくれたらと思います。
ECSexecは現在マネジメントコンソールの使用はサポートされていません。(4月11日現在）
aws-cliも対応しているバージョンを上の記事から対応するものをインストールしていただければと思います。
以降、公式の通りにはなるかと思いますが、簡単な順序を書いていきたいと思います。

この記事はハンズオン形式ではありませんので適宜解釈をしていただければと思います。

#2. 方法

初めにiamの権限の付与をします

```
{
   "Version": "2012-10-17",
   "Statement": [
       {
       "Effect": "Allow",
       "Action": [
            "ssmmessages:CreateControlChannel",
            "ssmmessages:CreateDataChannel",
            "ssmmessages:OpenControlChannel",
            "ssmmessages:OpenDataChannel"
       ],
      "Resource": "*"
      }
   ]
}
```

このiamポリシーをタスクロールにアタッチするのですが、既存のタスクロールがある方はそこに追記する形で問題ないかと思います。（名前は適宜変更した方が分かりやすいと思います）

次に、入りたいコンテナのtaskに先ほどのタスクロールを設定します。

あとは、コマンドライン上で--enable-execute-commandを使えるようにするために足りていないものがあれば公式を参考にダウンロードしてください。

私は既にサービスを立ち上げていたのでupdate-serviceコマンドを使用し、再デプロイしました。

```
$ aws ecs update-service \
    --cluster クラスターの名前 \
    --service サービスの名前 \
    --enable-execute-command
```

成功していれば、ターミナル上に

```
"enableExecuteCommand": true,
```

の表示が出ているかと思いますので,grepなりsedなりで探しましょう。

これで、お目当てのコンテナに入ることができます！

```
$ aws ecs execute-command \
    --cluster あなたのクラスター \
    --task あなたのtaskid \
    --container コンテナの名前 \
    --interactive \
    --command "/bin/sh"
```

コンテナにインストールされているシェルしか使えないので注意しましょう。

#3. おわりに
これでfargateでもコンテナにログインを簡単にすることができますね！
私でも簡単にできたので、もっとecsexecが広まって欲しいなと思い、この記事を書きました。
Cloudflare WorkersをDockerで（ホストにWranglerをインストールせずに）開発する

Cloudflare Workersで開発するには、通常は[公式ドキュメントにあるとおり](https://developers.cloudflare.com/workers/)`$ npm install -g @cloudflare/wrangler`でCLIツール「wrangler」をPCにインストールして行います。本稿ではwranglerを直接PCにはインストールせずDockerのみで開発してみました。

## 環境
- debian_version 10.9 (ChromeOS Linux)
- Docker version 19.03.13, build 4484c46d9d
- docker-compose version 1.27.4, build 40524192
- wrangler 1.15.0

## 設定
下記のようにファイルを設定していきます。

```docker-compose.yml 
version: '3'
services:
  app:
    build: .
    volumes:
      - .:/app
    ports:
      - 8080:80
```

```Dockerfile:Dockerfile
FROM nginx:1.19-alpine
WORKDIR /app

# nginx
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf

# wrangler
RUN apk add nodejs npm
COPY ./package.json ./
COPY ./package-lock.json ./
RUN npm install --also=dev

CMD nginx && npx @cloudflare/wrangler dev
```

```package.json
{
  // 中略
  "devDependencies": {
    "@cloudflare/wrangler": "^1.15.0"
  }
}
```

```nginx:nginx/default.conf 
server {
  listen 80;
  proxy_set_header Host $host:8080;

  location / {
    proxy_pass http://localhost:8787;
  }
}
```

`nginx:alpine`のDockerイメージにwranglerをインストールして両方同時に立ち上げています。こうすることでコンテナ外（ホスト）からwrangler devの実行結果を覗けるようになります。あまりきれいな方法ではないのですが、今回は開発環境のみということで...
「ホスト:8080→nginx:80→wrangler:8787」の順番でポートをつないでいきます。もちろん数字は整合していれば何でも構いません。

`$ docker-compose up`で立ち上げたら http://localhost:8080 にアクセスすると`$ wrangler dev`の開発サーバの結果を確認することができます。

デプロイは少々面倒ですが、`$ docker-compose exec app sh`でコンテナの中に入った後

```
# npx @cloudflare/wrangler login
# npx @cloudflare/wrangler publish
```

...することで対応しています。認証情報ファイルをホストに配置してからコピーすることで`$ wrangler login`せずに実行できるようにしても良いかも知れません。本格的に開発するようであればCI/CD等のデプロイ環境を組むと思うのであまり気にしなくていいと思います。

この方法で開発したものが以下です。

https://github.com/s2terminal/cloudflare-workers-kireaji
【Flutter環境構築】を終わらせたい。 ~zshでPATHを通すまで~

初めまして。プログラミング歴はまだまだ浅く、説明が下手な点もあるかと思います。
その際はご指摘等いただければ、めちゃくちゃ有難いですので気軽にコメントください。
<br>

- [x] PATHが通らない,,
- [x] さっさと環境構築終わらせたい,,

同じ苦しみを味わっている方の、役に立てばと思い書きました。
<br>
<details>
<summary><strong>〜目次〜</strong></summary>
 [1. Flutterのインストール](#1-flutterのインストール)
　 [1-1. ダウンロードから解凍](#1-1-ダウンロードから解凍)
　 [1-2. 管理場所の指定](#1-2-管理場所の指定)
[2. PATHを通す](#2-pathを通す)
　 [2-1. [zshrc]を開く](#2-1-zshrcを開く)
　 [2-2. [zshrc]への記載](#2-2-zshrcへの記載)
　 [2-3. PATHの確認](#2-3-pathの確認)
[3. 終わりに](#3-終わりに)
</details>

#1. Flutterのインストール
####1-1. ダウンロードから解凍
[Flutter公式ページ](https://flutter.dev/docs/get-started/install)からOSに対応するファイルを選択
そうするとZIPファイルがダウンロードされますので、解凍してインストールを開始して下さい。

|![スクリーンショット_2021-04-10_11_49_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/1cd734f7-db0b-e12e-2b00-2de549ef9c91.png)|
|:-:|

<br>

####1-2. 管理場所の指定
```
# ディレクトリの変更
cd ~/development

# そこにZIPファイルを解凍 
unzip ~/Downloads/flutter_macos_2.0.4-stable.zip
```
上記コードをターミナルで実行する前に、developmentというフォルダをファインダーに用意しておいて下さい。
そこにflutterが入ります。

|![スクリーンショット_2021-04-10_12_02_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/975aa04b-b7a7-3260-3442-390a26b9adbe.png)|
|:-:|

<br>

#2. PATHを通す
####2-1. [zshrc]を開く
zsh(Zシェル)の方は、Update your pathのリンクに移動して下さい。

|![スクリーンショット_2021-04-10_19_46_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/4cdb8d8b-a1d6-51d2-1cd4-f6c6a9740c9c.png)|
|:-:|
<br>


移動したページには「zシェルの方はzshrcに、コードを記載して下さい」という説明があります。

|![スクリーンショット_2021-04-11_10_01_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/4994e627-c887-b1d4-092b-41ce8bced683.png)|
|:-:|


zshrcは以下のコードで開くことができます。

```
vim .zshrc
```
zshrcが開いたらキーボードの[ i ]を押してinsert modeにして、書込みできる状態にします。

|![スクリーンショット_2021-04-11_15_09_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/64901dc0-dd62-d7aa-c1d6-af54791d9233.png)|
|:-:|

<br>
####2-2. [zshrc]への記載
下記コードをコピーしてペーストします。

|![スクリーンショット_2021-04-10_20_06_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/27b808ed-14be-c459-d9bd-82e191fd6e94.png)|
|:-:|
editにペーストしたら [PATH_OF_FLUTTER_GIT_DIRECTORY] の部分を削除しておきましょう。
次にファインダーから、パスをコピーします。

|![スクリーンショット_2021-04-11_15_25_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/912206/f8f8518a-6285-50c3-b26b-bde0f3617e8a.png)|
|:-:|
先ほど削除した[PATH_OF_FLUTTER_GIT_DIRECTORY]の箇所に、FlutterのPATHを差込む。
ここまできたら[ esc ]を押して[ :wp! ]と入力し[ enter ] を押せば抜けることができます。
<br>

####2-3. PATHの確認
確認の為に、ターミナルを再起動して、下記コードを打ち込みます。
読み込みが開始されれば、PATHが通せている状態です。

```
flutter doctor
```
>`出力結果`
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.0.4, on macOS 11.2.3 20D91 darwin-arm, localeja-JP)
[ ! ] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    ✗ Android licenses not accepted.  To resolve this, run: flutter doctor
      --android-licenses
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] VS Code (version 1.55.1)
[✓] Connected device (1 available)



#3. 終わりに
最後まで読んで頂きありがとうございました。
まだまだ初学者ですので、もっと良い記述の方法があればご指摘お願い致します！
その他なんでもコメントお待ちしております。
export defaultとは何か

備忘録です


<a id="#Chapter1"></a>
# export defaultとは？
他のコンポーネントが外部から参照できるようにするもので、単一コンポーネント方式でよく使う。以下のようにscriptタグ内にコードを記述して使う

```
<script>
export default {
	//コード記述
}
</script>
```

<a id="#Chapter2"></a>
# 何故export defaultを使うのか
VueCLIを使用する時点で、コンポーネント思想の考え方で作成することになる。コンポーネント思想は部品を組み合わせて一つのVueを作成するという考え方なので、作成したコンポーネントは他のコンポーネントも参照できなくてはいけない。
参照することで、参照したコンポーネントと自身で作成したコンポーネントを組み合わせることができる。
なので、VueCLIを使用するときは全ての<script>〜</script>の中にexport defaultは入れなくてはならない。


#まとめ
VueCLIを使用する以上、export default内でコードを書く必要がある
VSCodeでローカルのコマンドを実行する

## 準備しておくもの

* Visual Studio Code (VSCode)
* Node.js (npm)
* VSCode で `npm install` を実行した作業フォルダ (WorkFolder)


## 発生したこと

npm でローカルにインストールしたコマンドを VSCode のターミナルから実行しようとしたら、以下のエラーが出た。

```powershell:ターミナル[powershell]
PS C:\XXX\WorkFolder> yarn dev
yarn : 用語 'yarn' は、コマンドレット、関数、スクリプト ファイル、または操作可能な
プログラムの名前として認識されません。名前が正しく記述されていることを確認し、パスが
含まれている場合はそのパスが正しいことを確認してから、再試行してください。
...
```

エラー解決のためネットで調べてみても、欲しい内容が点在していて解決に時間がかかった。

なので、解消までの手順をまとめてみた。



## 解消までの手順

### 1. ローカルに設定ファイルを配置

<details><summary>2021/05/07 VSCode のバージョンアップで設定ができなくなった可能性あり (2021/05/08追記)</summary><div>

最初に行き着いたのは [環境変数の `PATH` にパスを通す必要がある][1] ということ。
これをするにはまず、WorkFolder に設定ファイル (settings.json) を配置する必要がある。

```
WorkFolder
  |- .vscode             <-- 無ければフォルダ作成
  |    |- settings.json  <-- 無ければファイル作成
  …
```

（VSCode 全体の settings.json もあるようだが、当然こちらは汚さない）

</div></details>

英語ペラペラな方は以下を確認してね

https://code.visualstudio.com/updates/v1_55#_terminal-profiles



### 2. 環境変数を設定する

<details><summary>2021/05/07 VSCode のバージョンアップで手順変更 (2021/05/08追記)</summary><div>

用意した settings.json に以下の内容を記載する。
（既に配置されていれば追記する）

```json:.vscode/settings.json
{
    "terminal.integrated.env.windows": {
        "PATH": "${workspaceFolder}\\node_modules\\.bin;${env:PATH}"
    }
}
```

</div></details>

![terminal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/765818/ccb92a7d-32ac-aef4-683f-41e75c2dc86a.png)

ターミナル画面右のリストから「ターミナル設定の構成」を選択。
開いた設定画面の `Terminal > Integrated > Profiles > Windows` を開いて、下記の修正をする。

```diff:settings.json
    "terminal.integrated.profiles.windows": {
        "PowerShell": {
            "source": "PowerShell",
-           "icon": "terminal-powershell"
+           "icon": "terminal-powershell",
+           "env": {
+               "PATH": "${workspaceFolder}\\node_modules\\.bin;${env:PATH}"
+           }
        },
```

`${workspaceFolder}` は [VSCode で開いているフォルダのパスが入る][2] ので、これを利用して`node_models/.bin` までの(フル)パスを追加する。

追加できているかどうかは、ターミナルで以下のコマンドを実行する。
（既に開いているターミナルには反映されないので開き直す）

```powershell:ターミナル[powershell]
PS C:\XXX\WorkFolder> $env:path
C:\xxx\node_modules\.bin;...
```

追加したパスが表示されていれば成功。
（ターミナルを開き直すと、VSCode からポップアップが出ることもある）




### 3. PowerShell の実行ポリシー変更

これで解決！と思いきや、まだあるのね。

```powershell:ターミナル[powershell]
PS C:\XXX\WorkFolder> yarn dev
yarn : このシステムではスクリプトの実行が無効になっているため、ファイル
C:\XXX\WorkFolder\node_modules\.bin\yarn.ps1 を読み込むことができません。
...
```

これは [PowerShell の実行ポリシーを変更する][3] 必要がある。
ターミナルからは変更できないので、コマンドプロンプトを管理者として実行する。

```batch:コマンドプロンプト
C:\XXX> PowerShell Set-ExecutionPolicy RemoteSigned
```

これで、晴れてローカルのコマンドが実行できるようになった！

```powershell:ターミナル[powershell]
PS C:\XXX\WorkFolder> yarn dev
yarn run v1.xx.xx
...
```

[1]:https://qiita.com/mysticatea/items/063b1a5ce5f49eb12cd2
[2]:https://qiita.com/ShortArrow/items/dc0c8cacd696154510f1
[3]:https://qiita.com/Targityen/items/3d2e0b5b0b7b04963750
Google Fonts を使って TextMeshPro で日本語を表示する

Unity の TextMeshPro で Google Fonts のフォント利用しつつ、日本語を表示する方法をまとめました。

# [Google Fonts](https://fonts.google.com/) とは
Google が提供してくれているフォントサービスです。基本的に無料で利用でき、日本語にも対応しているフォントがたくさんあります。もちろん非対応のフォントのほうが多いですが・・・。好きな書体があればすぐに使えるのがメリットだと思います。下の画像のようなフォントがたくさんあるので、まずは上のリンクからさっと見てみるとモチベーションが上がると思います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/1b05ec71-c36a-b15b-b936-4209a48d63d4.png" width=640 />


# 手順
1. まずは普通にブラウザで Google Fonts から日本語が使えるフォントをダウンロードします。（例えば [NotoSansJP](https://fonts.google.com/specimen/Noto+Sans+JP?preview.text_type=custom) を開き、`Download Family`を押します。zip ファイルの中に otf が入っているはずなので、後でそれを使用します。）
2. ここからはUnityです。TextMeshPro をインストールします。Window -> PackageManager を開き、検索ボックスに TextMeshPro をいれて探すのが楽かもしれません。  
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/c97a4c5d-7a3c-896b-b3a8-c6b0850a7b6f.png" width=512 />
3. インストールするとウィンドウが開くので、`Import TMP Essentials` を押して閉じます。  
![2021-03-15_16h50_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/ab2708da-0a73-adc6-2436-1c4fce95367d.png)
4. Window -> TextMeshPro -> Font Asset Creator を起動します。
5. 以下の値を設定して Generate Font Atlas を押します。登録する文字（※1）は Custom Characters を選択すると入力できる Custom Charcter List に貼り付けます。  
![2021-03-25_22h07_45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/ba40e861-9cc6-7963-fc07-6a627402f0b0.png)
6. 出力までに時間がかかるので待ちます。（手軽にやるなら Packing Method を Fast にするとここの待ち時間が短くなります。）
7. Save を押して Font Asset を保存します。
8. 上で保存したファイルを TextMesh Pro の Font Asset に設定します。

## ※1
* 漢字など第二水準までは [UnityのText Mesh Proでほぼ全ての日本語を表示させる](https://qiita.com/kgsi/items/08a1c78b3bee71136156) の記事がまとめてくれています。
* 第二水準まで全部入れようとすると、Atlas Resolution が 8192x8192 でないと入らないかもしれません。一度試しにやってみたところ 131MB というアホみたいなファイルサイズになりました。ちょっと無謀だと思うので、何かを削ることを考えないといけないかと思います。
* 上記リストの `哩` までが第一水準と信じて、それ以降を削除しつつ、Atlas Resolution を 4096 x 2048 にしたところ 18MB ぐらいまで減りました。この辺が妥協点なのではと思い、上記設定値はそうしてあります。
Javaバッファタイプとネイティブ配列：どちらが速いですか？

Cでプログラミングする場合、メモリを手動で割り当てたり、割り当てを解除したりする必要があります。これはエラーが発生しやすいプロセスです。対照的に、Java のような新しい言語は、多くの場合、メモリを自動的に管理します。Javaはガベージコレクションに依存しています。事実上、メモリはプログラマが必要に応じて割り当てられ、Javaはデータの一部が不要になったと判断し、対応するメモリを取得します。ガベージコレクションプロセスは高速で安全ですが、無料ではありません。何十年にもわたる最適化にもかかわらず、開発者にとって大きな頭痛の種となる可能性があります。

Javaにはネイティブ配列（たとえば、int []型）があります。これらの配列は通常、「Javaヒープ」に割り当てられます。つまり、それらはJavaによって動的データとして割り当てられ、管理され、ガベージコレクションの対象となります。

Javaには、IntBufferなどのバッファタイプもあります。これらは、ネイティブJava配列だけでなく、Javaヒープの外部にあるデータを含む他のデータソースによってもサポートできる高レベルの抽象化です。したがって、バッファタイプを使用して、Javaヒープにあまり依存しないようにすることができます。

しかし、私の経験では、ネイティブアレイと比較してパフォーマンスが低下します。バッファが遅いとは言えません。実際、バッファとストリーム（DataInputStream）のどちらかを選択する場合は、バッファタイプを強く優先する必要があります。ただし、私の経験では、ネイティブアレイほど高速ではありません。

「`new int [50000]`」または「`IntBuffer.allocate（50000）`」のいずれかを使用して、50,000個の整数の配列を作成できます。後者は基本的に（Javaヒープ上に）配列を作成する必要がありますが、IntBuffer「インターフェース」でラップします。

考えられる直感は、高レベルのインターフェイスで配列をラップすることは自由であるべきだということです。高レベルの抽象化にはパフォーマンスの低下（場合によってはパフォーマンスの向上）がないことは事実ですが、そうするかどうかは経験的な問題です。抽象化が無料で行われると思い込んではいけません。

私は経験的な声明を出しているので、想像できる最も簡単なテストでそれを経験的にテストしてみましょう。array / IntBufferのすべての要素に1を加算します。

```java
for(int k = 0; k  < s.array.length; k++) { 
    s.array[k] += 1;
}
```
```java
for(int k = 0; k  < s.buffer.limit(); k++) { 
    s.buffer.put(k, s.buffer.get(k) + 1);
}
```

デスクトップ（OpenJDK 14、4.2 GHz Intelプロセッサ）で次の結果が得られます。

|　　　　　　　タイプ　　　　　　　|　　　　　　　タイム　　　　　　　|
|::|::|
|int []|2.5 mus|
|IntBuffer|12 mus|

つまり、このテストでは、配列はIntBuffersよりも4倍以上高速です。  
必要に応じて、ベンチマークを自分で実行できます。
https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/tree/master/2020/11/30

私の期待は、Javaが配列に適用する多くの最適化がバッファー型に適用されないことです。

もちろん、これは、Javaヒープの外部から値をマップするためにバッファーが使用されたときに何が起こるかについてはほとんど教えてくれません。私の経験では、事態はさらに悪化する可能性があることが示唆されています。

少なくともパフォーマンスに関する限り、バッファタイプによってネイティブ配列が廃止されることはありません。

英語原稿: https://lemire.me/blog/2020/11/30/java-buffer-types-versus-native-arrays-which-is-faster/
Visual SudioでEdgeがDebugできない

自分用の備忘録です。
Visual StudioでDebug実行しようとしたときに、なぜかEdgeだけ動かない（Chromeでは問題ない）場合の解決法です。

Debug実行ボタン（IIS Express(Microsoft Edge))の右にある下矢印をクリックし、
スクリプトデバッグが有効の場合は、無効に変更してください。

スクリプトデバッグが問題だった場合は、これで解決します。
Google Colab のコード内で R・HTML・Markdown・YouTube埋め込みを利用する（＋α）

## はじめに
記事の内容は、表題の通りです。

ふと、「Colab の 1つのノートブック内で Python と R を両方実行できたりするかな」と思って調べたり試したりしたのがきっかけで、その後に「別のプログラミング言語やその他のものも使えたりするだろうか？」と思って、追加で「HTML・Markdown の利用」を試してみた時のメモです。

R・HTML・Markdown の件について、それぞれ以下を参照しました。

- R
   - [Google ColabでRを使う](https://oku.edu.mie-u.ac.jp/~okumura/stat/colab.html)
- HTML
   - [Jupyterで好きなHTMLを埋め込む - Qiita](https://qiita.com/xeno14/items/65b7da476d6f89d06388)
- Markdown
   - [python - What is the purpose of the IPython.display.display_markdown() function? - Stack Overflow](https://stackoverflow.com/questions/43133462/what-is-the-purpose-of-the-ipython-display-display-markdown-function)
- YouTube埋め込み
   - [jupyter notebookで画像や動画を表示させる簡単な方法 | self-methods](https://self-methods.com/jupyternotebook-ipython-display/?utm_source=rss&utm_medium=rss&utm_campaign=jupyternotebook-ipython-display#toc6)

## R の利用（Rpy2 を使う）
話は単純で Rpy2 を使えば良いようです。

Colab のノートブックで、まずは以下を実行します。

```bash
%load_ext rpy2.ipython
```

あとは、R を利用したい部分で、最初の行に「`%%R`」を入れれば良いようです。
以下、冒頭で書いた参考ページの中の内容を、実際に Colab上で試した際の画面キャプチャです。
![Rを実行.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9f9430a8-1b66-6cf8-ab9f-0131404da467.jpeg)

コードの部分はこんな感じです。

```R
%%R
curve(sin(x), -pi, pi)
```

## HTML の利用（IPython.display を使う）
HTML については `IPython.display` を使います。

以下、実行結果の画面キャプチャと、コードの部分です。
![HTML.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/35354547-e70b-2f33-98f0-4c75b7f8b38c.jpeg)

```python
from IPython.display import HTML
HTML("<h1>Hello world!</h1>")
```

## Markdown の利用（IPython.display を使う）
Markdown も HTML と同様に `IPython.display` を使います。

以下、実行結果の画面キャプチャと、コードの部分です。
![Markdown.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/81ef785c-6116-45c9-4a35-20f78fb2a652.jpeg)

```python
from IPython.display import Markdown
Markdown('# This is a Title')
```

## YouTube埋め込み（IPython.display を使う）
YouTube埋め込み も `IPython.display` を使います。

以下、実行結果の画面キャプチャと、コードの部分です。
![YouTube埋め込み.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/878d6b08-d6a7-d29a-5913-eda1d2b860b9.jpeg)

```python
from IPython.display import YouTubeVideo
YouTubeVideo('inN8seMm7UI', width=400, height=300)
```

埋め込んだ動画は以下になります。
　●Get started with Google Colaboratory (Coding TensorFlow) - YouTube
　　https://www.youtube.com/watch?v=inN8seMm7UI

## おわりに
今回使った IPython.display は、以下を見てみると他にもできることがいろいろありそうなので、試してみられればと思います。

●Module: display — IPython 7.22.0 documentation
　https://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html#

## 追記： その後に調べた内容
この記事を書いた後に、調べた内容をとりあえずメモしてみます。

●Google Colab で GIF動画をインライン表示させる - Qiita
　https://qiita.com/jun40vn/items/2efdaa3e599f8e7e8604

●Jupyter で音声データを埋め込む - Qiita
　https://qiita.com/mzmttks/items/13b5a67cf281215a69da

●KaggleのNotebookでコミットせずにファイルをダウンロードする方法 (Python) - Qiita
　https://qiita.com/sakabe/items/a9c3ac138b25a3f261af
GitHubのプロフィールREADMEをオシャレにするサービスを作ってみた

# プロフィールREADME
GitHubには、アイコンやbioなどの基本情報とは別にプロフィール機能があります。
自分のユーザー名と同じリポジトリを作成してREADMEを作るだけで、あとは自由にMarkdown形式で記述すればOK。
[公式：プロフィールの README を管理する](https://docs.github.com/ja/github/setting-up-and-managing-your-github-profile/managing-your-profile-readme)

# オシャレにするサービスたち
「GitHub Profile」と検索すると、設定の方法や便利なサービスなど色々と出てきます。

* [GitHub Readme Stats](https://github.com/anuraghazra/github-readme-stats)
* [Github Profile Trophy](https://github.com/ryo-ma/github-profile-trophy)
* [GitHub Profile Summary Cards](https://github.com/vn7n24fzkq/github-profile-summary-cards)

↑この辺りは常連ですね。
GitHub Readme StatsとGithub Profile Trophyは私も利用させていただいております🙇‍♂️

# 作ってみた
で、それらに便乗して自分も作ってみました。
[リポジトリ](https://github.com/rokumura7/github-chart)

[![github-chart](https://github-chart.vercel.app/api?user=rokumura7)](https://github.com/rokumura7/github-chart)

GitHub Profile Summary Cardsのチャートを前年と比較できる形にしつつ、GitHubActionsなどを利用せずにURL形式で手軽に利用できる形を目指しました。

使い方は下記の`user=***`部分にご自身のGitHubユーザー名を指定するだけです。

```md
[![github-chart](https://github-chart.vercel.app/api?user=rokumura7)](https://github.com/rokumura7/github-chart)
```

# 技術的なお話
TypeScriptのnpmプロジェクトでGitHubのGraphQL APIを利用しVercelにデプロイをしています。

## TypeScript良き
最近、実務でもTypeScriptを少しずつ使うようになってきた段階で、まだまだ経験は浅く調べながらでしたが、型安全と補完はやはり非常に強力で捗りました。
Javaから入ってる身としては「これだよ、これ」と言う感覚が強かったです😌

## GraphQL
今回は利用するだけでしたが、RESTに慣れきっていたので考え方自体とても面白さを感じました。
[公式：GitHubのGraphQL API](https://docs.github.com/ja/graphql)

GraphQLの理解に関しては下記の記事がとても参考になりました🙇‍♂️
[GraphQLの全体像とWebApp開発のこれから](https://qiita.com/saboyutaka/items/171f7382cdf75b67d076)
[アプリ開発の流れを変える「GraphQL」はRESTとどう違うのか比較してみた](https://www.webprofessional.jp/rest-2-0-graphql/)

## Vercelにハマった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241408/67a80fa9-54dc-ab26-9892-62cd943aa350.png)

Vercelのデプロイ自体は多くの人が述べているように、「え？こんだけ？」と言う感じで終わったのですが、開発を進める中で上記のエラーが突然発生するようになりました。

> Serverless Functions Created per Deployment

VercelのHobbyプラン（=無料プラン）ではサーバレスファンクションをデプロイ毎に12個までと言う制限があります。
[公式：Limits](https://vercel.com/docs/platform/limits?query=limits#plan-limits)
Vercelのデフォルトの設定だと`api/`配下に置かれたファイルでexportされたものがサーバレスファンクションとしてカウントされるようです。
リファクタリングをして処理を小分けにしていたらいつの間にやら超えてしまっていました😇
結局、`api/`にはindex.tsのみを残して他のファイル群は`lib/`などに切り出すことで解決しました。

# さいごに
是非利用してみてください！
IssueでもPull Requestでも何かしらフィードバックもらえるととても嬉しいです。
（特にデザイン周りはボロボロなので誰か助けて欲しい。。w）

開発に際して、GitHub Readme StatsとGithub Profile Trophyを大いに参考にさせていただきました🙇‍♂️🙇‍♂️🙇‍♂️
【メモ】JSON 応用「@JsonProperty」を使用してI/Fの名称揺れを吸収する。

## 使用したライブラリ
import com.fasterxml.jackson.annotation.JsonProperty;

## 使用したシチュエーション
複数の外部I/Fがあり新規のもののはずだが、A側は項目名がスネークケース、B側は項目名がキャメルケース、C側はどちらにも当てはまらないず単語単位で大文字になっているなどいろいろあり、外部設計は終わったことになっているが、あとから項目名が変わりそうな雰囲気を出していた。

項目名が変わってとgetterとsetterの呼び出し口が変更差分で出てくると、たまに変更ソースの一覧だけ見て影響範囲を心配しだす人がいたりするので、項目を定義してるオブジェクトのみの修正で済ませたかった。
あとJavaだと基本的にはキャメルケースで記述するので、項目のオブジェクトだけを見ると通常から外れているように見えるので、うっかりスネークケースをキャメルケースに修正する可能性が考えられるので防ぎたかった。

## 使用例

```
/**
 * JSONマッピング用のオブジェクト。
 *
 * @author start
 */
public class JsonSampleBean {

	/** ID */
	@Getter
	@Setter
	@JsonProperty("ID") // 名称が変わる場合はアノテーションの引数部分だけ修正する。
	private String id;

	/** 名称 */
	@Getter
	@Setter
	@JsonProperty("name_kana") // 名称が変わる場合はアノテーションの引数部分だけ修正する。
	private String name;

}
```
アジャイル未経験者が「アジャイルサムライ」で学んだことメモ

最近、PoCばかりをしているのですが、アジャイルの手法から取り入れられることがないことがたくさんあるだろうと[「アジャイルサムライ――達人開発者への道」](https://amzn.to/3fXtCg8)を読みました。その中で使えそうだと思ったことをメモしておきます。細かく読んでいませんが、初心者が概要を把握するのに非常に良い本だったと思います。
メモ程度なので本当に個人的備忘録の記事です。

<a href="https://www.amazon.co.jp/dp/B00J1XKB6K?_encoding=UTF8&btkr=1&linkCode=li2&tag=yoheifukuha06-22&linkId=d249ff07afe4f77ff092c063a4bf772c&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B00J1XKB6K&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=yoheifukuha06-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=yoheifukuha06-22&language=ja_JP&l=li2&o=9&a=B00J1XKB6K" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />


# メモした内容
メモしていない章は飛ばしています。

## 第2章 アジャイルチームのご紹介
### 2.2 チームをアジャイルにするためのこつ
**同じ仕事場で働く**。最近はコロナでリモートワークばかりなので、忘れがちでした。

### 2.3 よくある役割分担 
#### プロジェクト開始時のメンバーへの質問
以下の質問は使えるかと思いました。

1. 自分は何が得意なのか？
1. 自分はどうやって貢献するつもりか？
1. 自分が大切に思う価値は何か？
1. チーム弁バーは自分にどんな成果を期待してると思うか？

#### スクラムマスター
スクラムマスターとは、ということが以前から気になっていたため、メモ。

> スクラムマスターはアジャイルコーチとプロジェクトマネージャーを合わせた感じ。アジャイルコーチはアジャイル開発の原則や考え方をチームに説明し、受け入れていくことを後押しする。最後までやり遂げられるチームにするのがアジャイルコーチの仕事だ。そのために、チームが悪い習慣へ逆戻りしないように注意を払う。
練度の高いチームなら、専任のコーチはいなくても構わない

## 第3章 みんなをバスに乗せる
### 3.2 手強い質問をする
自分のチームや顧客にも答えにくい質問をするのは有効かと思いました。下がその例です。

> 1. どのくらい経験を積んでいるチームですか？
1. では、あなた自信はこの手の仕事の経験はありますか？
1. ご予算はどれぐらいですか？
1. このプロジェクトを統括するのはどなたですか？
1. ロールXXが2人の体制でも問題ないのでしょうか？
1. 過去のプロジェクトで、XX経験がほとんどない新人ばかりのチームを率いてXXの開発を成功させた事例はありますか？

### 3.3 インセプションデッキのご紹介
以下の一覧を明確にします。

1. 我々はなぜここにいるのか(プロジェクトの大きな目的)
1. エレベーターピッチを作る(簡潔なアピールポイント)
1. パッケージデザインを作る(キャッチーな広告)
1. やらないことリストを作る
1. 「ご近所さん」を探せ(プロジェクト関係者の明確化)
1. 解決案を描く(チーム全員の意思統一)
1. 夜も眠れなくなるような問題は何だろう(リスクをあげる)
1. 期間を見極める
1. 何を諦めるのかをはっきりさせる(期間、スコープ、予算、品質など譲れる要素)
1. 何がどれだけ必要か

## 第4章 全体像を捉える
### 4.2 エレベーターピッチを作る
こんな風に作ります。

|内容|具体例|
|:--|:--|
|[潜在的なニーズを満たしたり抱えている課題を解決したり]したい|[建設現場の作業を把握]したい|
|[対象顧客]向けの、|[現場責任者]向けの|
|[プロダクト名]というプロダクトは|[CSWP]というプロダクトは|
|[プロダクトのカテゴリー]です。|[危険作業許可発行システム]である|
|これは[重要な利点、対価に見合う説得力のある理由]ができ、|これは[作業許可証を申請・追跡・監査する]ことができ、|
|[代替手段の最右翼]とは違って、|[現行の紙ベースのシステム]とは違って、|
|[差別化の決定的な特徴]が備わっている|[ウェブ経由で、いつでもどこからでも利用できる機能]が備わっている|

以下の効能あり。

1. プロダクトを明確化
1. チームの意識を顧客に向けさせる
1. 革新を捉える

### 4.3 パッケージデザインを作る
キャッチーな言葉でわかりやすいOne Pager。
以下の例で、絵を交えた例あり。機能ではなく、効能にフォーカスする。

例) 

|内容|例|
|:--|:--|
|プロダクト名|建設安全作業許可証発行システム|
|最高のキャッチコピー|鉱山にうってつけ！|
|アピール1|素早く格好！|
|アピール2|より安全に！|
|アピール3|作業監視のお手間も取らせません。|

### 4.4 やらないことリストを作る
**やること**、**やらないこと**、**あとで決める**リストを作成

### 4.5 「ご近所さん」を探せ
あとで、不要な折衝やレビューをしないためにも関係者を洗い出しておく

## 第10章 アジャイルな意思疎通の作戦
### 10.5 ミニふりかえり
以下の2点を振り返る。魔女狩りではなくポジティブな振り返り。

1. うまくやれたこと
2. どうすればもっとうまくやれるか

### 10.6 デイリースタンドアップ
デイリーに5分から10分で以下を話す

1. 昨日やったこと
1. 今日やること
1. 課題
【GitHub】IssueをPull requestで閉じる方法

### はじめに
Issueをプルリクで閉じる方法があって便利なので紹介します！
### 手順
Issueを作成します
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927983/c68c87fe-3211-b794-7f4e-c0d4eac6a415.png" width="600px">
今回は、レイアウトが崩れています！とゆうタイトルで作成しました。**Issue番号は1**ですね 

このIssueをPull requestで閉じます

![スクリーンショット 2021-04-11 14.52.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927983/4d6de8ff-6ee9-9870-e742-5888c5fd3435.png)
プルリクの説明の欄に`close #[Issue番号]`を記入することで閉じる事ができます
**close以外にも`fix`や`resolve`など閉じるコマンドがあります、詳しくは[参考](https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue)を読んでみてください！**

Mergeさせると...
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927983/a36fd3b4-130f-84cb-b790-120465859e37.png" width="600px" />
**Issueが閉じました！**以上です

### 参考
https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue
【Minecraftサーバー】初心者が作った半自動ワールド切り替え

#シェルによるワールド切り替え
サーバーでワールドの切り替えを手動でするのが面倒なので作ろうと思いました。
いろいろ引用して作ってるのと、最近勉強し始めたばかりなのでスマートじゃないところがありますが、ご了承ください。

Minecraftのゲーム内の切り替えではなくOS上でできるものです。

##Minecraftサーバー環境
Ubuntu server 20.04 LTS
Minecraft全バージョン

#事前準備
・シェルなどを動かす際、便利なので`screen`でサーバーを動かします。
screenのインストール

```sh:screen
$ sudo apt-get install screen
```
・ファイルの作成
ワールドを止める際に一応バックアップをとるのでそのためのファイルを作成します。
※これは必須ではありません。推奨です。

```sh:mkdir
$ mkdir BU
```

#シェルスプリクト
今回のメインのプログラムです。
まずは自分の好きな場所にシェルを作ってください。

```sh
vi change.sh
```

```sh:change.sh
#!/bin/bash
#
#起動ワールドの切り替えスプリクト

########## ワールド内の通知 ###########
 #worldname,gameversion変更可能
 worldname=skyblock
 gameversion=1.16.5
 #起動中のワールド内のアナウンス
 screen -S minecraft -X stuff 'say '$time1'秒後に再起動し、'$worldname'に切り替えます。'`echo -ne '\015'`
 screen -S minecraft -X stuff 'say 次の'$worldname'のバージョンは'$gameversion''`echo -ne '\015'`
 sleep '$time1'
 screen -S minecraft -X stuff 'say 停止します。'`echo -ne '\015'`
 sleep 5
 screen -S minecraft -X stuff 'stop'`echo -ne '\015'`

########## minecarftが完全に終了するまで待機 ##########
 #javaのプロセス数を数えてるため
 #ほかにjavaを動かしていたら調整してください
 count1=`ps -ef | grep java | grep -v grep | wc -l`
 while :
 do
     if [ $count1 = 0 ] ; then
         break
     else
         sleep 0.5
         count1=`ps -ef | grep java | grep -v grep | wc -l`
     fi
 done

########## バックアップ開始 ##########
  #Temporaryの作成
  #仮のファイルです
  mkdir ~/バックアップファイルの場所/Temporary
  #world,world_nethr,world_the_end,logsのみコピー
  cp -rf ~/マイクラサーバのパス/world ~/バックアップファイルの場所/Temporary
  cp -rf ~/マイクラサーバのパス/world_nether ~/バックアップファイルの場所/Temporary
  cp -rf ~/マイクラサーバのパス/world_the_end ~/バックアップファイルの場所/Temporary
  cp -rf ~/マイクラサーバのパス/logs ~/バックアップファイルの場所/Temporary
  #時間をつけてzip
  zip -r ~/BU/`date "+%Y%m%d_%H%M"`.zip ~/BU/Temporary
##########切り替え##########
 screen -S minecraft -X stuff 'cd ~/二個目のマイクラサーバのパス/'$worldname''`echo -ne '\015'`
 sleep 5s
 ##########java起動#########
screen -S  java -Xmx4G -Xms4G -jar server.jar '\015'`
```
もう一つのワールドの`.jar`ファイルが入っているディレクトリ名と`worldname`を共通にすることで変更することができます。自分の環境に合わせていじってください。

シェルに権限を渡します。

```sh:権限
$ chmod 777 change.sh
```

#Minecraftの起動方法
`screen`で起動しますが、`screen`の名前が`minecraft`じゃないとダメですので`minecraft`で`screen`を起動してください。

```sh:名前付きscreen
screen -S minecraft
```
アタッチの場合は

```sh:アタッチ
screen -r minecraft
```

`screen`上で一つ目のワールドを起動しておきます。

```sh:起動
$ cd マイクラサーバのパス
$ java -Xmx4G -Xms4G -jar server.jar
```

#実際に動かしてみる。
一つ目のワールドが起動しているときに、実際にシェルを動かしてみる。

```sh:
$ ./backup.sh
```
すると、ワールド内に通知が飛びますので、それを確認してください。
![スクリーンショット (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530378/b1c1cc7e-7d50-32c2-dcad-0e0e1dad5b8b.png)

ついでにバックアップも圧縮して作成されています。下記の写真は解凍後の写真です。
![スクリーンショット 2021-04-11 155527.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530378/fcd461f4-7882-97ea-0cdb-6b81c33552aa.png)
![スクリーンショット 2021-04-11 155452.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530378/c2bad7dc-749a-7a72-ad3a-e637be6ab9c1.png)

一応これで以上になります。

めちゃわかりやすくて下記を参考にしました。

https://qiita.com/T1kus0n/items/7dcc6b28d84ff3365e6c