OmniAICreator/Qiita-1.07M huggingface dataset:
GitHub Actionsでgit-pr-releaseを実行する

```yaml:/.github/workflows/git-pr-release.yml
name: git-pr-release

on:
  push:
    branches:
      - release

jobs:
  git-pr-release:
    name: git-pr-release
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
      with:
        fetch-depth: 0
    - uses: ruby/setup-ruby@v1
      with:
        ruby-version: 3.0
    - run: gem install -N git-pr-release
    - run: git-pr-release
      env:
        GIT_PR_RELEASE_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
GitHub プルリクエスト

#【GitHub プルリクエスト】

##コードレビューをする文化は根付いていますか？

自分のこれまでの実務では、コードレビューする文化はなかったです。
SIerとWeb系の違いのでしょうか。自分にはわかりません。

新人の自分が書いたコードを先輩方が確認する工数は無く、いつも納期に追われていました。。
コードレビュー無しで、push（自分はSVNを使用していたので、コミット）した結果、開発中のプロジェクトでエラーを出して、ご迷惑をお掛けしてしまうことがありました。

**これを改善していくためには、プルリクエストを当たり前にした開発を行なっていく必要があるようです。**

##プルリクエストとは。

GitHubが最初に提供した機能であり、開発者のローカルリポジトリでの変更を他の開発者に通知するもの。
この機能のおかげで、多くの開発者がOSS開発に参加しやすくなり、結果として品質の高いコードを作ることが可能になった。

###主に以下の機能がある。

・機能追加や改修など、作業内容をレビュー・マージ担当者やその他関係者に通知
・ソースコードの変更箇所をわかりやすく表示
・ソースコードに関するコミュニケーションの場を提供

##プルリクエストのメリット

**レビュー・マージ作業をタスク化して、やりとりを記録できる。**
　→　作成されたプルリクエストを一覧で見ることができる。
　→　完了・未完了が視覚的にすぐわかるので、漏れを防ぐことができる。
　→　プルリクエスト上でコメントのやり取りをして、品質向上に繋げられる。

**レビューを促進できる。**
　→　ソースコードの変更部分を明確に表示することができる。
　→　プルリクエストの作成者が、ソースコードの意図や補足事項をコメントとして伝えることができる。
　→　レビュー担当者の負担を減らすことができる。

##参考

[サル先生のGit入門 プルリクエスト](https://backlog.com/ja/git-tutorial/pull-request/02/)　　

参考にさせていただきました。
ありがとうございました。
Pythonのforループでインデックス番号を取得する

enumerate関数はカウントと値をタプルで返却する。
https://docs.python.org/ja/3/library/functions.html#enumerate

```sample.py
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
print(list(enumerate(seasons)))
>> [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
```

enumerate関数を利用してforループでインデックス番号を取得できる。

```sample.py
for i, v in enumerate(seasons):
    print(i, v)
>> 0 Spring
>> 1 Summer
>> 2 Fall
>> 3 Winter
```
4足歩行ロボットPettoi Bittleのキャリブレーション

# はじめに

今回は，Petoi Bittleのサンプルコードを使って，4足歩行ロボットの制御を行う．
本記事ではキャリブレーションを解説していく．

前回記事はこちら

[4足歩行ロボットPetoi Bittleのセットアップ](https://qiita.com/Naotaka_Kawata/items/344b01a34723f6084ebe)

# キャリブレーション
まず，"OpenCat/WriteInstinct/OpenCat.h"の"#define NyBoard_V*_*"が，使用しているNyBoardのバージョンと一致しているか確認し，違うならばバージョンを合わせる．

次に，"OpenCat/WriteInstinct/WriteInstinct.ino"を書き込み，サーボやIMUのキャリブレーションを行う．この時，Petoi Bittleを水平な床においてキャリブレーションを行う．

この姿勢で置くと安定すると思います．

![zero.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531981/1f03e7cb-cf41-edb6-6e98-2da59349f658.png)

書き込みが終わったら，シリアルモニタを開いて3つの質問に対し，「Y」を送信します．
3つの質問は以下の通りです．筆者は最後の質問が表示されていないので，もしかすると何か見落としがあるのかもしれません．

- Reset all joint calibration? (Y/n)
- Do you need to update Instincts? (Y/n)
- Calibrate MPU? (Y/n)

# 微調整
次に，"OpenCat/OpenCat.ino"を書き込み，サーボの微調整を行う．

1. シリアルモニタを開き，"c"と送信することでキャリブレーションモードに移行
2. シリアルモニタで以下の形式でコマンドを送信し，サーボの微調整をする．

```
c[パーツ番号] [角度]
例: c8 0
```

Pettoi Bittleのサーボの対応は以下のとおりである．コツとして，角度は-9~9を指定すると公式では書かれている．
しかし必ずしもこの範囲を守る必要はない．実際筆者のPettoi Bittleの左前足がかなり上向きだったため，-9~9の範囲を超えて30を指定している．

![Index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531981/fdf58bbb-ca47-0cfd-e51f-168bcd5c8323.png)


目標の姿勢は以下のとおりである．サーボの微調整には付属のジョイントチューナを用いる．

![calib1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531981/6c2a6f2e-b921-b271-0580-2813cfb440f8.png)

![assets_bittle_-MSGw-I0q_j0kHosz8nz_-MSGx1sAobtzY1ucuddF_53.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531981/5ee5d06c-a1a5-ae9a-099b-79896c40fd09.jpeg)

 
# 起動
 
すべてのサーボの角度が正しく調整出来たら，お腹のバッテリーを起動する．
2秒間電源ボタンを押し続けると起動する．電源を切りたい場合にも2秒間電源ボタンを押し続ける．
その後，IRリモコンのキャリブレーションボタンを押し，目標の姿勢になっているかを確認する．

なお，バッテリーは2秒間押し続けることで起動する．バッテリーのライトの色で状態を把握することができる．
電源を消す際も2秒間押し続ける．
- 青：満充電
- 赤：充電が必要

IRリモコンのボタン分布を以下に示す．

![remote_en.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531981/d6c7c1d3-728c-6bfa-9c73-815b3c3ceaa7.png)

日本語にするとこう

|   |           |  |
| :--- | :-----------: | -------: |
| ふせ（CH-）    | 前進（CH） |      ジャイロON/OFF（CH+） |
| 左折（│◃◃）   | 直立（▷▷│） |      右折 （▷││）|
| サーボ停止（-）    | 後退（+） |     キャリブレーション（EQ） |
| 足踏み（0）    | 這う（100+） |   歩く（200+） |
| 小走り（1）    | 走る（2） |     バウンド（3） |
| あいさつ （4）   | 腕立て（5） |   おしっこ（6） |
|  ストレッチ （7）  | お座り（8） | サーボの脱力（9） |

# 動作確認
IRリモコンの任意のボタンを押し，歩行ができるか確認する．ジャイロOFFにすることで，ゆっくりな動作の安定性が向上します．かわりに早い動作を行うときはジャイロONが推奨されています．

https://twitter.com/dancing_nanachi/status/1401107469745623044

# おわりに
サンプルを動かすだけでも，前進やおすわりなどが実現できていることが分かった．

しかし，右折や左折，ジャンプなどは歩くスピードや他センサを利用しないと安定しないとも感じている．

今後はラズパイなどとの連携を行い，センサを用いたフィードバック制御を行う．

# 参考文献
- [公式ドキュメント](https://bittle.petoi.com/6-calibration)
- [Petoi Bittle入門](https://note.com/npaka/n/n9969f23c3840)
VSCodeのGitでpushする時の「The current branch 'master' has no upstream branch...」メッセージの解決策

# はじめに
プログラミング初学者の[@kat_log](https://twitter.com/kat__log "Twitter")と申します。

自分と同じ初学者の状況の方がいるか分かりませんが、
ターミナルでのgit練習後→VSCodeのgit機能も使ってみよう！と思い
VSCodeの機能で`master`ブランチに`push`しようとした時に

>The current branch 'master' has no upstream branch...

というメッセージが出て戸惑ったのですが、解決したため共有です。

# 結論
gitにて**「上流ブランチ」**（英語でupstream branch）の設定が必要でした。

# 設定
次回`push`時に`-u`オプションを付けると設定できます。

```
git push -u origin master
```

これでpushと同時にpush先の`master`ブランチを上流ブランチとしても設定することができるので、VSCodeからpushがうまくいくようになります。

ちなみに、
>[git push は、特に初めてブランチをPushするときに「-u」オプションをつけることを推奨されます。](https://www-creators.com/archives/5204 "git push -u オプションで”上流ブランチ”を設定")

とのことなので、
>[ブランチ作成後の最初のgit pushには-uをつける](https://dev.classmethod.jp/articles/git_first_push_notes/ "[git][初心者向け]ブランチ作成直後のpushの注意事項")

と覚え「ブランチ作成と上流ブランチの設定」はセットで行うようにすると良いみたいですね。

（補足：2021/07/10追記）
本記事ではブランチ名を`master`で記載していますが、最近は[`main`に置き換える動きがある](https://www.publickey1.jp/blog/20/githubmainmastermain.html "GitHub、これから作成するリポジトリのデフォルトブランチ名が「main」に。「master」から「main」へ変更")みたいですね😉
（補足：2021/07/13追記）
上記ブランチ名の変更は「GitHub」の話しで、[「Git」側の設定もしておくといい](https://qiita.com/fk_chang/items/a4839a595fef9a2c3724 "Gitのデフォルトブランチをmasterからmainに変更する方法")みたいです！

# おわりに
お読みいただきありがとうございました。
自分と同じく初学者の参考になれば嬉しいです。
↓に載せております参考ページがすごく分かりやすくて勉強になりました！
一緒に頑張っていきましょう〜😄

# 参考
 - [Git用語:上流ブランチとは?](https://www-creators.com/archives/4931 "Git用語:上流ブランチとは?")
 - [git push -u オプションで”上流ブランチ”を設定](https://www-creators.com/archives/5204 "git push -u オプションで”上流ブランチ”を設定")
 - [[git][初心者向け]ブランチ作成直後のpushの注意事項](https://dev.classmethod.jp/articles/git_first_push_notes/ "[git][初心者向け]ブランチ作成直後のpushの注意事項")
 - [GitHub、これから作成するリポジトリのデフォルトブランチ名が「main」に。「master」から「main」へ変更](https://www.publickey1.jp/blog/20/githubmainmastermain.html "GitHub、これから作成するリポジトリのデフォルトブランチ名が「main」に。「master」から「main」へ変更")
 - [Gitのデフォルトブランチをmasterからmainに変更する方法](https://qiita.com/fk_chang/items/a4839a595fef9a2c3724 "Gitのデフォルトブランチをmasterからmainに変更する方法")
開発メモ（Pixelbook×Flutter）


# 0. Chromebook で Linux（ベータ版）をセットアップする
Chromebookの公式手順に沿ってセットアップ。
https://support.google.com/chromebook/answer/9145439

# 1. Install（Flutter）
Flutterno公式手順に沿ってインストール。
https://flutter.dev/docs/get-started/install/chromeos

## 1.1 Android setup
1章の手順内に「Android Setup」がある。
AndroidStudioの公式に飛ぶので、公式手順に沿ってインストール。
https://developer.android.com/studio/install#chrome-os

インストールしたら、Androidライセンスの許可。


#2. Set up an editor
1.1節でAndroidStudioをインストールしたので、AndroidStudioに「Flutter」と「Dart」をインストール。
https://flutter.dev/docs/get-started/editor


# 3. Test drive
AndroidStudioを起動し、「Create New Flutter Project.」を選択。
1章でtar展開したディレクトリを指定して、適当なプロジェクト名を入れて、セットアップ。（プロジェクト名はロワーケース）
https://flutter.dev/docs/get-started/test-drive

プロジェクトができたら、とりあえず何もせずにメニューバーのRunで実行。
勝手にエミュレータが立ち上がってくれる。


# 4. 開発開始
過去にうｐした記事を参考に実装。
https://qiita.com/tyaunuakkia/items/957173ff0dc85aa17d91


#9. 余談
ChomeOSがどんなもんかと思ってPixcelbookを買って約３ヶ月。
「PixelbookはGoogleだし、FlutterもGoogleだし、開発しやすいやろ」と思ってたけど意外と面倒くさい。

特にインストール先とかもろもろがLinux環境なのが億劫。
ソースコメントを書くために日本語入力したいけど、AndroidStudio上だとできないので、一回ローカルに移らないといけなかったりする。

あと、AndroidStudioで編集してる時、たまにフリーズするけど、一体なんなんだろう・・・。

安くない買い物だったのでうまく活用していきたいけど、今のところまでWindowsやMacが使いやすいな、、、慣れたい、、、、、
win32comでWordの変更履歴の承諾

Python3のwin32com.clientを使ってword文章を自動化を扱っているので、メモ。今回は、変更履歴関係を扱う。

環境：
・ windows 10
・ Python 3.8.1 64bit


```py
# 変更履歴の記録を有効化
doc.TrackRevisions = True

# 変更履歴/コメントなし に設定 (文字列置換で、変更前の文字列に変換が複数回かからないようする対応)
doc.ShowRevisions = False

```

```py
# すべての変更を承諾
doc.Revisions.AcceptAll()
```

```py
# 特定のTableのみ変更をリジェクト(元に戻す)
# 例として、一番最初のTable(Tables[0])内にすべての変更をリジェクト
for revision in doc.Tables[0].Range.Revisions:
    revision.Reject()
```

```py    
# 修正箇所が"XXX", "YYY" であれば、変更をリジェクト(元に戻す)
for revision in doc.Revisions:
    if revision.Range.Text in [ "XXX" ,"YYY"]:
        revision.Reject()
```
【Ruby】4乗ガウス問題

4乗的ガウス問題をRubyにて解いてみました。

【問題】
1から50までの整数の4乗の和を求めなさい。

【回答】

```ruby:Ruby
i = 0
while i <= 49
  i += 1
  num = num.to_i + (i ** 4)
  puts num
end

答え　65666665
```

もっとシンプルに計算できるような気もします…。
今の私に思いつく式は上記しかなかったので、他に分かりやすいコードがあれば教えていただければ幸いです。
laravel 8.xでのページネーションでbootstrapを使う

### laravelのpagination
bladeファイルで`$model->links()`で設定できるが
laravel 8.xからスタイルのデフォルトがTailwindになっているため
bootstrapスタイルにするには修正が必要

```php:App\Providers\AppServiceProvider.php
use Illuminate\Pagination\Paginator;

public function boot()
{
    Paginator::useBootstrap();
}

```
[laravel 8.x](https://readouble.com/laravel/8.x/ja/pagination.html)
propsと$emitによるデータのやりとり

#はじめに
Vue.jsは１つのコンポーネントで実装するよりも、粒度に応じて複数のコンポーネントに分解して実装する方がよいとされている。そのようが、ソースコードの可読性やメンテナンス性、コンポーネントの再利用性も活かすことができて便利なためだ。だが、複数のコンポーネント間でデータのやり取りも必要不可欠になり、そこがVue.jsの扱いで最も難しいとされる箇所の１つなのではないかと思う。
そこで今回は自分が忘れてしまってからも当記事を確認するだけですぐに思い出せるように、簡単に実装例も交えつつ、「props」「emit」について取り上げます。

#emit, propsとは
コンポーネント間には親と子という概念がある。片方のコンポーネントがもう片方のコンポーネントを取り込み（import）するとき、importする側を「親」,importされる側を「子」と呼ぶ。そして、親から子へデータを伝達する手段を「props」。子から親へデータを伝達する手段を「emit」としている。


#propsの使い方（親から子へデータを送る）
V-bind(:)を経由して親から子へデータを送信して、子でpropsを使ってプロパティという形で親からのデータを受け取って利用できる。



親からv-bindでデータを子へ送る

```csharp:Parents.vue
<template>
  //親で扱ってるデータをバインドしてそのプロパティとして子へデータ送る
  <Child
   :param0=“item”
   :param1=“value”
  />
<template>
<script>
  import Child from './components/Child.vue'
  components: {
    Child
  },
</script>
```

子でprops内のプロパティをという形で親が飛ばしたデータを受け取ってdataのように利用できる

```csharp:Child.vue
//親から送られてきたデータを受け取りdataのように使う
props: [“item”,  “value”]
```

#emitの使い方（子から親へデータ送る）
emitを使ったカスタムイベントで子から親へデータが渡される。
カスタムイベントとは、子コンポーネント内「@click」のイベントがクリックされると同時に発火する$emitを使用したイベントのこと。子コンポーネント内で親に送りたいデータを引数にした「$emit」が発火すると、親でそのイベントが違う名前のmethodsに渡されて、そのmethodsが発動する。つまり、子で発火してその引数がデータとして親に渡されて親のmethods内で関数として使われる。 
子から親へデータを渡すには、@clickや@changeなどのなにかしらのイベントが必要になってくる。

```csharp:Child.vue
<template>
  <div>
    <p>child_num: {{ child_num }}</p>
　　　　　　　　//@clickイベントでmethodsのsendが発動
    <button @click='send'>親に値を渡す</button>
  </div>
</template>

<script>
export default {
  data: function() {
    return {
      child_num: 0
    };
  },
  methods: {
　　　　　　　　//関数内のカスタムメソッド$emitが発火し、引数として親に送りたいデータを渡すことができる
    send() {
      this.$emit("my-click", this.child_num);
    }
  }
};
</script>
</script>
```
```csharp:Parents.vue
<template>
  <div>
    <p>parent_num: {{ parent_num }}</p>
　　　　　　　　//子のカスタムメソッドを親の関数として使う
    <Child @my-click='reflectNum'/>
  </div>
</template>

<script>
import Child from './components/Child.vue'
export default {
  data: function() {
    return {
      parent_num: 100
    }
  },
  components: {
    Child
  },
  methods: {
　　　　　　　　//子のカスタムイベントで引数にしたデータはこちらで受け取る(子から親へデータ渡す)
    reflectNum(value) {
      this.parent_num = value
    }
  }
}
</script>
```
Laravel5.8で404エラー時の処理を実装する

Laravel5.8で404の例外処理を実装したので忘備録としてまとめます。
<h2>404エラー時に表示したい画面を作成</h2>

今回はviews/errors/404.blade.phpとします。

```resources/views/errors/404.blade.php
<h1>404 Not Found.<br>このページは存在しません。</h1>
<p>あなたがアクセスしようとしたページは削除されたかURLが変更されています。</p>
```

※本来はユーザーの離脱率を下げるため、TOPページへのリンクや、サイト内検索フォームを設置する等の工夫があるのが理想です。その辺の話はこちらの記事を参考に。

https://www.asobou.co.jp/blog/web/not-found

<h2>Handler.phpの編集</h2>

例外処理はHandler.phpを編集することでカスタマイズ出来ます。

基本的には[こちらの記事](https://labo.nozomi.bike/article/13)を参考に実装していきましたが、エラーが出てしまって色々試行錯誤した結果、以下のように記述して解決しました。


```app/Exceptions/Handler.php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Request;
use Response;
use Illuminate\Auth\AuthenticationException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;  //①追加

//途中略

    public function render($request, Exception $exception)
    {
        //②ここから
        if ($exception instanceof NotFoundHttpException) { 
            return response()->view('errors.404');
        }
        //②ここまで追加
        return parent::render($request, $exception);
    }
```


[参考記事](https://labo.nozomi.bike/article/13)から修正した点としては、

・①でクラスを指定する必要がある。（他に`NotFoundHttpException`クラスが存在しているのか？原因はわかりませんが、これを記述しないとエラーが発生してしまいました。）

・②の`response()->view('errors.404')`の部分。
参考記事では`return view('errors.404')`となっていましたが、[Laravel5.8 公式ドキュメント](https://readouble.com/laravel/5.8/ja/errors.html)を確認すると`response()->view()`で書けよ！と言う事だったので、公式に従って修正したら上手くいきました。


今回は404エラーの例外処理のみの解説となりましたが、他の例外処理についても調べて実装できるようになりたいと思います。
【Python】for文の"_"(アンダースコア)の処理速度

# 概要
普通のfor文と"_"を使ったfor文の処理速度を比較します。



# 処理速度の比較
それぞれ10億回ループ処理をします。

```Python:処理速度の比較
import time

n = int(1e+9)
normal = 0
under_score = 0

# 普通のfor文
start_normal = time.time()
for i in range(n):
	normal += 1
print('normal:{:.5f} sec'.format(time.time() - start_normal))

# "_"を使ったfor文
start_under_score = time.time()
for _ in range(n):
	under_score += 1
print('under_score:{:.5f} sec'.format(time.time() - start_under_score))
```
```:出力結果
normal:79.93061 sec
under_score:79.05743 sec
```

# 結論
"_"を使った方が約1%速い結果になりました。いや待てよ？1回だけでなんか胡散臭い！と思われる方がいると思います。私もその1人です。

10,000,000回を1セットとして100回計測して箱ひげ図で比較します。
箱ひげ図は、[プログラマーのための統計学】箱ひげ図](https://qiita.com/Esfahan/items/14811149a047c44956b6)を参考にしました。

```Python:箱ひげ図による比較
import time
import matplotlib.pyplot as plt

number_of_set = 100
normal_list = []
under_score_list = []
n = int(1e+7)
# 普通のforと"_"の計測
for _ in range(number_of_set):
	# 普通のfor文
	normal = 0
	start_normal = time.time()
	for i in range(n):
	    normal += 1
	normal_list.append(time.time() - start_normal)

	# "_"を使ったfor文
	under_score = 0
	start_under_score = time.time()
	for _ in range(n):
	    under_score += 1
	under_score_list.append(time.time() - start_under_score)

# 箱ひげ図
time = (normal_list, under_score_list)# タプル化
fig, ax = plt.subplots()
bp = ax.boxplot(time)
ax.set_xticklabels(['normal', 'under score'])
plt.title('100 times with 10,000,000 loops as one set')
plt.xlabel('type')
plt.ylabel('time')
plt.grid()
# 描画
plt.show()
```
![スクリーンショット 2021-06-07 12.01.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/4f787a1a-afe8-35fb-3b97-c7e39b149263.png)
"_"の方が平均値では、速い結果となりました。縦軸の単位は秒です。




# おまけ
~~使っているところを見たことはないが、"_"は変数として機能しているようです。~~
[@shiracamus](https://qiita.com/shiracamus)さんコメントありがとうございます。アンダースコア1つは、**変数の値を使わずに捨てることを明示するための暗黙のルール**になってるとのことです。以下のコードは変数として機能することの確認ですが、実際に使うのは避けましょう。
ちなみに変数名のルールは以下のようになっています。
>
・使用できる文字は a ～ z 、 A ～ Z 、 0 ～ 9 、アンダーバー(_)、漢字など
・一文字目に数値(0～9)は使用できない
・一文字目にアンダーバーは使用できるが特別な用途で使用されているケースが多いので通常は使用しない方がいい
・大文字と小文字は区別される
・予約語は使用できない
(引用:<https://www.javadrive.jp/python/var/index1.html#section1>)

```Python
# 普通のfor文
print('---普通のfor文---')
for i in range(3):
	print('値:{}, 型:{}'.format(i, type(i)))

# "_"を使ったfor文
print('---"_"を使ったfor文---')
for _ in range(3):
	print('値:{}, 型:{}'.format(_, type(_)))
```

```:出力結果
---普通のfor文---
値:0, 型:<class 'int'>
値:1, 型:<class 'int'>
値:2, 型:<class 'int'>
---"_"を使ったfor文---
値:0, 型:<class 'int'>
値:1, 型:<class 'int'>
値:2, 型:<class 'int'>
```

# 編集履歴
(2021/06/07) 内容:箱ひげ図の追加、まとめの"_"のルールについて修正
MinecraftでJournyMap(MOD)をインストールする

# これは

子供用にMinecraftを設定した時のメモです（笑

# インストール手順

## 1.Modを使うためにMinecraft Forgeをインストールします。

https://files.minecraftforge.net/net/minecraftforge/forge/

* ダウンロードした.jarファイルをダブルクリックして実行します。

## ※Javaファイルをクリックして動作しない場合

macOSは最近はJavaが入っていないので、Javaをインストールする必要があります。その他のOSで特に何もなければスキップしてください。

下記から Downloadでアーキテクチャーを選択します。
https://www.azul.com/downloads/?os=macos&architecture=arm-64-bit&package=jdk#download-openjdk

私の場合(M1 Macbook Air)の場合はmacos,ARM64bit,.dmgを選択しました。

![スクリーンショット 2021-06-05 17.15.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/b955389e-479a-1f49-19da-be8405b7fee6.png)

ARM版があるのでAzulですが、他のJavaでも問題ありません。

インストール後に再度Forgeのインストールを実行してください。

## 2. JournyMap(Mod)のダウンロード

ファイルをダウンロードします。
https://www.curseforge.com/minecraft/mc-mods/journeymap

ダウンロード(1.16.5-5.7.1)
https://www.curseforge.com/minecraft/mc-mods/journeymap/download/3222876

## 3. MinecraftにModを設定する

* 起動構成でforgeを選んで起動します
* 起動後の最初の画面で「MOD」を選択します。
* 次の画面で「MODフォルダーを開く」を選択してその中に.jarファイルをインストールします。

# 使い方

* [J]でマップ
* [B]でWaypoint(マーカー)
* [CTRL+B]でWaypointの編集（削除など）

# ごにょごにょ

セットアップはお手の物なんですが...この世界観がよくわかりません（笑。
シェルでバブルソートを作った話

## 経緯
実は先日、Linuxの講習会を頼まれました．
一体何を教えればいいのかを考えた結果、講習会に参加する多くの生徒がすでに学習しているソートのうち、最もシンプルな**バブルソート**をシェルで組んでみようと思ったのがきっかけです．

## バブルソートの概要
配列の端から順に隣の配列と自身の値を比較し，大きい方を隣に移動させていく．すると片方の端に最も大きな数字が出てきます．
すると次に探索範囲を一つ狭めて引き続き同様の処理を行う．すると最終的に大きいものが順に配列に配置されるため，泡(大きな数字)が移動することからバブルソートという名前のソートになったそうです．

## 作成したコード
以下に作成したコードを示します．

```sh
#!/bin/sh

# バブルソートをシェルでやってみた

arr=(5 54 2 6 7 121 75) # ソートする対象の配列

len=${#arr[@]}                              # 配列の大きさ
for i in `seq 0 $(( ${len} - 1 ))`          # 第一ループ
do
    for j in `seq $(( ${len} - 1 )) 0`      # 第二ループ
    do
        if [ $j -le $i ]; then
            break                           # i > jを満たさなくなったら次のループへ
        fi
        if [ ${arr[$j]} -lt ${arr[( $j - 1 )]} ]; then
            temp=${arr[$j]}                 # swap
            arr[$j]=${arr[$(( $j - 1 ))]}   # swap
            arr[$(( $j - 1 ))]=$temp        # swap
        fi
    done
done
echo ${arr[@]}                              # ソート終了時に結果出力
```

## まとめ
今回はシェルスクリプトの勉強の一環としてソートアルゴリズムを実際のシェル処理に落とし込むという試みをした。
時間があればもっと別の処理を組んでみたい．(クイックソートとか)
PreparedStatementでin述語を使いたい場合の解決策(雑ですみません)

（in述語って言葉を初めて知ったが、、、）

daoクラスを書いているときに、

```sql

select fizz, buzz from HOGE where fizz in (?,?,,,)

```

のようなSQLを投げたいと思った。

しかし、SQLInjectionの観点から、

```java
String sql ="select fizz, buzz from HOGE where fizz in ({1})";

StringBuilder sb = new StringBuilder();

for(String fizz : fizzList ){
    sb.append(fizz+",");
}

String tmpBindParam = sb.toString();

String bindParam  tmpBindParam.sbString(0,tmpBindParam.length()-1)

sql = sql.replace("{1}",bindParam);

PreparedStatement ps = conn.prepareStatement(sql);

rs = ps.executeQuery();
...

```
のようなことは危険である。

間違っているので実際には書いてないが、
要するにPreparedStatement#setStringなどでバインド変数を使わない手法。

そこで、Bestかわかからないがこうやったらできるだろうと思った。

```java

StringBuilder sb = new StringBuilder();

for(String fizz : fizzList ){
    sb.append("?,");
}
String placeHolder = sb.deleteCharAt( sb.length() -1 ).toString();

String sql ="select fizz, buzz from HOGE where fizz in (" +placeHolder+ ")";

PreparedStatement ps = conn.prepareStatement(sql);

int i = 1;
for(String fizz : fizzList ){
    ps.setString(i++, fizz);
}

rs = ps.executeQuery();

```

こんな感じでやったら、一応バインド変数を用いて、
同じ数の **?** に動的に値を渡すことが可能である。

ただ本当にこれがベストなのかわからない。
もしもっと効率的な書き方があれば教えてほしい。

Java8で書けるもっといい方法があれば。。とくに。。。知りたい。
（あんま調べても出てこなかったのよね）。。


ちなみにin述語って言葉はSQLアンチパターンで本にありました。↓↓


<a href="https://www.amazon.co.jp/SQL%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Bill-Karwin/dp/4873115892?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=SQL%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3&qid=1622881146&sr=8-1&linkCode=li3&tag=soepy-22&linkId=a57a6c6aed8bb63462559316787d2113&language=ja_JP&ref_=as_li_ss_il" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4873115892&Format=_SL250_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=soepy-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=soepy-22&language=ja_JP&l=li3&o=9&a=4873115892" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

<a href="https://hb.afl.rakuten.co.jp/ichiba/1e84bfc8.365b74cc.1e84bfc9.0ee2bcb5/?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Fbooxstore%2Fbk-4873115892%2F&link_type=text&ut=eyJwYWdlIjoiaXRlbSIsInR5cGUiOiJ0ZXh0Iiwic2l6ZSI6IjI0MHgyNDAiLCJuYW0iOjEsIm5hbXAiOiJyaWdodCIsImNvbSI6MSwiY29tcCI6ImRvd24iLCJwcmljZSI6MSwiYm9yIjoxLCJjb2wiOjEsImJidG4iOjEsInByb2QiOjAsImFtcCI6ZmFsc2V9" target="_blank" rel="nofollow sponsored noopener" style="word-wrap:break-word;"  >SQLアンチパターン／BillKarwin／和田卓人／和田省二【3000円以上送料無料】</a>


//追記
先輩がこのサイト教えてくれました。

https://loglog.xyz/programming/jdbctemplate_in
NGUI要素と普通のColliderが被った場合マウスイベントはどっちで発火するか

# 超概要
普通のcolliderとNGUIで作ったボタン要素が被った場合、
マウスイベントはどっちで発火するか調べた

結果：普通のcolliderとNGUIの両方で発火する

# 環境
Unity 2018.4.31f1
NGUI: Next-Gen UI 2018.3.0f

# 経緯
## やりたいこと
既存プロジェクトのマウスイベントをマウスもタッチパネルも使えない環境に対応することになった
プログラムでマウスイベントを呼びたいがNGUIとUnityのマウスイベントがわからなかったので調べた

hierarchyに普通のカメラと普通のコライダーも混ざった場合、
クリック判定はどうなるのか？

## 実験
↓↓サンプルScene↓↓
![NGUI_タップ処理テスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/4c0cb9d0-61e4-db33-cb65-f0d62ab804d2.png)

## 結果
どっちも当たる
上の画像ならbuttonの判定と後ろのCubeの判定の両方が来る
※OnMouseイベントでテスト

NGUIはUnityのクリック判定を無視して独自に処理するらしい

なので
NGUIのUICameraを書き換えてプログラムからマウスイベントを呼べるように修正し、
UICamera以外のカメラからもRaycastしてマウスイベントを無理やりコールすることで解決

# 追記(2021/06/05)
uGUIでも同様の結果になりました

![uGUI_タップ処理テスト.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/7e85fea1-c534-c427-5071-e8e965bf5ef3.png)

全部重なったところを押すと
・uGUIで一番上の要素
・uGUI以外で一番上の要素
のマウスイベントが呼ばれるのでなんじゃこれ感ありますね
[初心者向け]OSの仕組み（概要を知る）

#はじめに
この記事はOSの仕組みについての概要になります。
ひとつひとつ詳細に説明すると膨大な量になりますので、深堀したい内容がありましたらそこからさらに調べていただけると幸いです（もし詳細記事を作成すればリンクを加筆します）。

#OSの定義

> オペレーティングシステム（英: Operating System、略称:OS、オーエス）とは、コンピュータのオペレーション（操作・運用・運転）を司るシステムソフトウェアである。

[出典: フリー百科事典『ウィキペディア（Wikipedia）](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%9A%E3%83%AC%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0) 

#OSの概要
皆さんが普段使用しているパソコンやスマートフォンには、OSがインストールされています。
OSが何をしてくれているのか、ですが例えば当たり前にやっている以下のような操作とかがOSのおかげでできてたりします。

●キーボードから文字を入力すると画面に表示される
●マウスを動かせばカーソルが動く
●複数のアプリケーションを同時に利用する

OSを人間に例えると「脳」の役割で、パソコン（スマートフォン）が「体」なんて表現される記載を目にします。
それくらいOSは様々な指令を出す役割を担っています。
また、OSはコンピュータの基本的な機能を提供してくれるソフトウェアであり、**基本ソフトウェア**とも呼ばれます（OSを広い意味で解釈すればですが）。




#OSの主な機能

●メモリ管理
●プロセス管理
●ファイル管理
●ネットワーク管理
●ハードウェアの管理
●ユーザーインターフェース

##メモリ管理

プログラムを実行するには、メモリ上にプログラムがロードされている必要があります。プログラムが同時に複数実行されることになれば、メモリ領域をそれぞれ割り当て、実行が終われば削除してメモリを解放します。
自身の環境でメモリをどれだけ使用しているかなどは、windowsだと「**タスクマネージャー**」で確認できます。
以下のような画面で表示されるので、自身の環境でもぜひ確認してみてください。

![image.png](https://assets.st-note.com/production/uploads/images/52354693/picture_pc_8138e0ae34e90008a4a11c54480ae00e.png)

##プロセス管理

###プロセスとは

まずプロセスとはですが、「**実行中のプログラム**」と置き換えてもらっても構いません。
例えば、Google Chromeを起動するとそれがプロセスとなります。プロセスにはメモリ領域が必要になります。Google ChromeだけでなくExcelやWordなども起動すると、その分のプロセスにメモリ領域が必要になりますが、その場合並列して処理が行われます。このことを**マルチプロセス（マルチタスク）**といいます。



###スレッドとは

プロセス内に作られる並列処理の実行単位です。プロセスは複数のスレッドからなります。
スレッドにはシングルスレッドとマルチスレッドがあります。
・**シングルスレッド**: スレッドを一つずつ順番に処理
・**マルチスレッド**: スレッドを複数並列に処理

![image.png](https://assets.st-note.com/production/uploads/images/53791175/picture_pc_d150ca04024969fa04b8715ccb203565.png)

プロセス管理についてざっくり説明しましたが、上記より深く踏み込んだ内容を別記事で作成しました。

[プロセスとスレッドについて](https://qiita.com/n-yama/items/98d63bf15b122cd2632e)


##ファイル管理

ファイル管理とは、パソコンに保存されている文書や写真、動画などのデータを管理する機能になります。
普段ファイルに名前を付けて作成していたりしますが、OSのおかげだったりします。

ちなみに特定のユーザーに操作を許可したり、パスワードを設定するような暗号化機能もファイル管理によるものです。


##ネットワーク管理
異なるコンピュータ間のやりとりや、プリンタやハードディスクなどに接続して情報を共有したりできます。
社内のPCをwindowsに統一して、社内ネットワーク内での連携や操作が可能になったりします。個人だとそこはあまり恩恵を感じませんが会社だと非常に助かると思います。

##ハードウェアの管理

ハードウェアの管理、ですがその前にハードウェアとは何を指しているのか。
パソコンでいえば、ハードウェアは以下のようなものですね。
●マウス
●キーボード
●スピーカー
●ディスプレイ


「OSの概要」部分でも少しお話ししましたが、キーボードで文字を入力してディスプレイに表示される、ということもOS（とデバイスドライバ）のおかげだったりします。
(デバイスドライバについては[出典: デバイスドライバとは？初心者の方向け](https://pc-kaizen.com/what-is-a-device-driver#3)の目次3から参考になります)

また、マウスやキーボードなどは色々な種類がありますが、細かな設定をせず使い始められます。
OSの役割である「**ハードウェアの抽象化**」のおかげで、製品ごとの微妙な仕様の違いなどを意識せずよしなにやってくれているみたいです。

##ユーザーインターフェース

OSは、ユーザーとコンピュータの架け橋的な役割を担っています。
GUI・CUIとかが当てはまりますね。

**GUI（ジーユーアイ）**：グラフィカル ユーザー インターフェース
→マウスでクリックしたり、ドラッグ＆ドロップしたり視覚的・感覚的に操作が可能な機能。コンピュータに詳しくなくても操作できる。

![image.png](https://1.bp.blogspot.com/-uc_ylx1Sfn8/VxTa5y0CHdI/AAAAAAAA5-8/_XAyKD93apgTdO2Mp6eelg19vC7GfMnPwCLcB/s450/desinger_free_sozai.png)



**CUI（シーユーアイ）**：キャラクタ ユーザー インターフェース
→キーボードによる文字入力操作なので、知識がないと中々難しい。(GUIが搭載される以前はCUIでの操作なので、パソコンは一部の人しか扱えなかったらしい)

![image.png](https://2.bp.blogspot.com/-Lm75_V4O7JY/V3x2OZbmIFI/AAAAAAAA8II/fzLckySfqnk0k7P-_YkSF8aDEBuUBodpQCLcB/s400/job_programmer.png)


#終わりに

OSといっても深く勉強しようと思えば結構範囲がありますので、ご自身でも調べて知識を深めていただければと思います。
「基本情報技術者」関連の参考書などに体系的に載っていることもあるので、ググるだけでなく本で勉強するのもおすすめかと思います。
IBM Cloud SSL-VPN接続 大阪エンドポイント


## IBM Cloud SSL-VPN 東京エンドポイントは繋がりにくい
日本の接続エンドポイントは東京VPN一箇所しかないのですが、そのせいか めちゃめちゃ繋がりにくいです。
日中だと 30回リトライしてもつながらなかったり………


### エンドポイント一覧
日本は「__vpn.tok02.softlayer.com__」しかありません
https://cloud.ibm.com/docs/iaas-vpn?topic=iaas-vpn-available-vpn-endpoints&locale=ja


## Workaround
サポート元に問い合わせたところ、まだエンドポイント一覧には載っていないが、以下の3つのエンドポイントを使えるので、こちらも試すように言われました。
試したところ、問題なく接続できるようです。

- vpn.osa21.softlayer.com 
- vpn.osa22.softlayer.com 
- vpn.osa23.softlayer.com

お困りの方はこちらもお試し下さい。
Symbol-ETL Part.2 TransferTransaction編

まずは基本のTransferTransaction

#Transaction
```json
{
	"transaction": {
		"type": 16724,
		"network": 152,
		"version": 38913,
		"maxFee": "17600",
		"deadline": "27643226853",
		"signature": "1C704CCC8E7F729EB5C2AE4C4A53510472CFA512FEC9F2726CE229FBECFAAAE8EBB34B145FFB482CCB7A0CC53E5E995A071158C954F3180D8AD710BE01973002",
		"signerPublicKey": "EAF79D749E51E4B3C1CD6A663EF9F1388CDD4A39F87544EEC91DD4312127ED89",
		"recipientAddress": {
			"address": "TDWGESLOQZRBLDC5OXIBJEBTSIGM4I4XIGKGCFQ",
			"networkType": 152
		},
		"mosaics": [
			{
				"amount": "10000000000",
				"id": "5B66E76BECAD0860"
			}
		]
	},
	"signer": {
		"publicKey": "EAF79D749E51E4B3C1CD6A663EF9F1388CDD4A39F87544EEC91DD4312127ED89",
		"address": "982B15CB943D0819D42C1DD6B86CE02ABC335FABD91BA8F6"
	},
	"transactionInfo": {
		"height": "375",
		"index": 1,
		"id": "5FC286F4A094C43139213EB1",
		"hash": "DE61702EB9EC9A00277BC97E196B87D287EDA3929AA9939CFEC5F6B931585F7E",
		"merkleComponentHash": "DE61702EB9EC9A00277BC97E196B87D287EDA3929AA9939CFEC5F6B931585F7E"
	}
}
```

##項目の説明
| field | description |
|:-:|:-:|:-:|
| type  | 16724は0x4154になるのでTransferTransaction |
| network | |
| version | |
| maxFee | このトランザクションに出せる最大手数料。実際に消費額はこの値以下になるのでこの値をそのまま使わないように注意。|
| deadline | このトランザクションの有効期間。| 
| signature | | 
| signerPUblicKey | 署名者の公開鍵。|
| signer | |
| transactionInfo | heightやindexの情報はブロック取り込み後に付加される？ETL作成的には非常にありがたい項目。 |

#Recipient
このTransactionによる副次的な資産変動等は発生しないため、Recipientもなし。
…Transactionのstatusは別APIを使わないといけないのか。面倒。
functools.wrapsについて調べてみた

Pythonの勉強をするためにとあるOSSを眺めてたところ、functools.wrapsを見つけた。
デコレータ関数につけるものらしいが、「つけないのと何が違うのか」、「使用シーン」が分からなかったため、少し調べてみた。
結論から言うと「デコレータを呼び出す関数の名前とdocを把握するために必要なデコレータ」と理解した。

## 調査方法
公式ドキュメントを参考に以下のコードを書いて実行した。

* コード

```python
from functools import wraps

def my_decorator(f):
  @wraps(f)
  def wrapper(*args, **kwds):
    """doc: wrapper関数"""
    print('wrapper関数処理中')
    return f(*args, **kwds)
  return wrapper

@my_decorator
def example():
  """doc: example関数"""
  print('example関数処理中')

if __name__=="__main__":
  example()
  print("example関数名",example.__name__)
  print("example関数doc",example.__doc__
```

* 結果

```
wrapper関数処理中
example関数処理中
example関数名 example
example関数doc doc: example関数
```
example関数で実行してる時、プログラムからはeaxmple関数として認識されている。


一方、@wrapsを削除すると、プログラムからはwrapper関数として認識されている。

* @wrapsを削除して実行した結果

```
wrapper関数処理中
example関数処理中
example関数名 wrapper
example関数doc doc: wrapper関数
```

恐らく@wrapsを使用しないと処理的には問題はないがデバッグやログ出力などで、「どのデコレータを呼び出す関数が何をしてるか正確に把握出来ない」といったことが起こりそうなので、今後実装する機会があったら活用しようと思う。

「そこ認識違うよ」などの意見がありましたら是非コメントにください。
LPC1114と内蔵ADCで電圧をソフトウェアシリアルに出力 3.300Vまで (ハードはichigojam)


目的
adcの練習用
工夫点は、書き込み用シリアルとデータ出力用シリアルを
分ける事によつて開発の効率を上げた。
データ出力用シリアルの出力先は、dp9
標準シリアルに出力を出したい場合は、dp16に変えればよい
速度は9600bps


```c++

#include "mbed.h"
 
//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)
 
//Serial pc(USBTX, USBRX); // tx, rx
//Serial pc(SERIAL_TX, SERIAL_RX); //767
//Serial pc(PA_2, PA_3); //010
//Serial pc(PA_9, PA_10); //010
//Serial pc(dp16, dp15); // tx, rx 1114

#define UART_DELAY (96) //  1/9600

//仮想シリアルの出力ポート
//DigitalOut TX(PA_9); //010
//DigitalOut TX(PA_2); //010
//DigitalOut TX(dp16); //1114  標準シリアルポートTX
DigitalOut TX(dp9); //1114

//DigitalOut myled(D13);    //767
//DigitalOut myled(PA_4);   //010
//DigitalOut myled(dp14); //1114

//アナログ入力の設定
//AnalogIn adc_vbat(A3); //PA_4
//AnalogIn adc_vbat(A0); //767
AnalogIn adc_vbat(dp4); //1114

char ch_hex_a_b[5];
char *ch_hex_a(int l_num)
{
    int a,b,c;

    b=DVI10(l_num);
    c=l_num-(b*10);
    a=DVI10(b);
    b=b-(a*10);

    ch_hex_a_b[0] = '0' + a;
    ch_hex_a_b[1] = '0' + b;
    ch_hex_a_b[2] = '0' + c;
    ch_hex_a_b[3] = 0;

    return(ch_hex_a_b);
} //ch_hex_a

//タイマーの定義
Timer t;

int q_st; //スタートタイム debug
int q_et; //エンドタイム   debug

//仮想シリアルへの一文字出力 9600bps
int pc_putc(char ch) {

    TX=1;
    
    q_st = t.read_us(); //debug
    
    TX=0;//START
    wait_us(UART_DELAY);
    
    for(int ii=0;ii<8;ii++){
        TX=(ch>>ii)&1;
        wait_us(UART_DELAY);
    }; //for

    TX=1;//Stop
    wait_us(UART_DELAY);

    q_et = t.read_us(); //debug 引いた数が0で1041ufなら正解
         
    return(0);
    
} //pc_putc

//文字列の表示
int pc_printf(char *str1) {

    //文字の中身がゼロか
    while(*str1){
            
        //一文字出力
        pc_putc(*str1 ++);
                        
    } //while

    //戻り値
    return(0);
}//pc_printf

char buffer[30];


int main() {

    //初期化
    TX=1;wait_ms(2);    //文字分のウエート
    pc_printf("\r\n");  //ゴミの吐き出し
            
    //タイマーの開始
    t.start();

    //最初のウエート
    wait_ms(1000);

    //無限ループ
    while(1) { 

        //adcの読み込み 0から4096 (精度は10bitのはず)
        int s = (adc_vbat.read_u16()>>4);

//d sprintf(buffer,"%d",s);     //debug
//d pc_printf( buffer );        //debug
//d pc_printf( "\r\n" );        //debug

        //電圧に変換 ex 3.300 -> 3300 mVを出力
        s=(s*6600)>>13;

//d sprintf(buffer,"%d",s);     //debug
//d pc_printf( buffer );        //debug
//d pc_printf( "\r\n" );        //debug

//小数点以上と小数点以下を分ける iiは1の桁 sは小数点以上の桁
int ii = s;
if     ( ii >= 3000 ) { ii = (ii - 3000); s = 3;}
else if( ii >= 2000 ) { ii = (ii - 2000); s = 2;}
else if( ii >= 1000 ) { ii = (ii - 1000); s = 1;}
else                  {                 ; s = 0;}

        //電圧の小数点以上の表示
        ch_hex_a( s*10 );
        ch_hex_a_b[0] = '+';
      //ch_hex_a_b[1] = '0' + s;
        ch_hex_a_b[2] = '.';      
        pc_printf(  ch_hex_a_b  );

        //電圧の小数点以下の表示
        pc_printf(  ch_hex_a(ii)  );

        //リターン
        pc_printf(  "\r\n"  );

        //約1秒を待つ
        wait_ms(1000);
    } //while

} //main

////容量削減
//void error(const char* format, ...){}


```

![serial_adc_1114_1_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/00c84b47-175b-5b47-14f9-b28e586ce27b.jpeg)
無料の SSL 証明書を取得する

# はじめに

当投稿は LSWS と組み合わせて使用することを前提にしています。

https://qiita.com/dxa/items/01d78bda1ca5df73bab6

# DNSを設定する

![dns.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21236/5a125d6d-e011-bc02-b178-461fec47d91f.png)

レジストラまたはDNSサーバーによって画面が異なるのでそちらに従ってください。
上図の例ではvsoと、それ以下のワイルドカード*.vsoをAレコードに登録してます。


# Certbot をインストールする

```bash
[root@vm opc]# dnf install certbot
```

見つからないと言われてしまう場合はEPELリポジトリを有効化してください。

# SSL 証明書を発行する

certbotコマンドは次の通りです。
certbot certonly --standalone -d <ドメイン> -m <メールアドレス> --agree-tos


```bash:LSWSを一旦止める
[root@vm opc]# systemctl stop lsws
```

```bash:Certbotで証明書取得
[root@vm opc]# certbot certonly --standalone -d test.vso.mydomain.com -m webmaster@mydomain.com --agree-tos

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Requesting a certificate for test.vso.mydomain.com
Performing the following challenges:
http-01 challenge for test.vso.mydomain.com
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/test.vso.mydomain.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/test.vso.mydomain.com/privkey.pem
   Your certificate will expire on 2021-08-28. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again. To non-interactively renew *all* of your
   certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le
```

```bash:LSWSをもう一度起動する
[root@vm opc]# systemctl start lsws
```
# SSL証明書の自動更新

SSL証明書の自動更新は次の通り。

```bash:実際のコマンド
[root@vm opc]# certbot renew 
	--standalone #certbotが単独で80番ポートを使って認証する
	--pre-hook "systemctl stop lsws" #更新前に実行するコマンド（例ではLSWS停止）
	--post-hook "systemctl start lsws" #更新後に実行するコマンド（例ではLSWS開始）
```

これを cron.d に登録する。

```bash:cron.dに登録
[root@vm opc]# vi /etc/cron.d/certbot
```

```vim:/etc/cron.d/certbot
00 04 02,17 * * root certbot renew --standalone --pre-hook "systemctl stop lsws" --post-hook "systemctl start lsws"
```

これで自動更新されます。

# PHPファイルを作る

```bash
[root@vm opc]# mkdir -m 755 -p /usr/local/lsws/virtual/test.vso.mydomain.com/html
[root@vm opc]# chown -R nobody:nobody /usr/local/lsws/virtual/
```

```bash
[root@vm opc]# vi /usr/local/lsws/virtual/test.vso.mydomain.com/html/index.php
```
```bash:/usr/local/lsws/virtual/test.vso.mydomain.com/html/index.php
<?php
echo 'Hello World';
```


<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vTYnWQ5xUZ7LdpSAgp_p7sJv1QpwspiG0T8y6NetmG9edRijcSpltTVJ5IFXdYl5VXPvFfeu4ClbVKc/embed?start=false&loop=false&delayms=3000" frameborder="0" width="500" height="570" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>


# ドメインにアクセスする https://～

![cap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21236/e9b2f473-b723-cf00-e950-61b4c14500f9.png)

警告が出なければ成功。


# Next

https://qiita.com/dxa/items/d973be04b0032813b416
最近のビデオチャット事情



最近コロナ禍でリモートワークになったり、休日の家時間で友人や家族と電話等をすることが増えたかと思います。
今回はそんな中で業務のビデオチャット事情を自分なりにまとめてみようと思います。
また今回はビデオチャットツールはいろんな方々がまとめられているので各ツール細かい説明はしません。

## ビデオチャットとは

ビデオチャットとは、インターネットを介してお互いの映像をリアルタイムで見ながら行うチャットのことである。

[ビデオチャットとは？ (weblio)](https://www.weblio.jp/content/%E3%83%93%E3%83%87%E3%82%AA%E3%83%81%E3%83%A3%E3%83%83%E3%83%88?dictCode=BINIT)

## ビデオチャットの用途

大きなくくりとしては「プライベート」「業務」があることでしょう。
プライベートでは「コミュニケーションの取りやすさ」や「ストレスない会話」「空間の共有しやすさ」
業務では企業によっては「セキュリティ」も重要なキーワードだと思います。

## 業務でのビデオチャット

業務でよく使用されるツールとしては下記がよく上がるのではないでしょうか。

- [teams](https://www.microsoft.com/ja-jp/microsoft-teams/group-chat-software)
- [skype](https://www.skype.com/ja/)
- [Zoom](https://zoom.us/jp-jp/meetings.html)
- [Slack](https://slack.com/intl/ja-jp/)
- [chatwork](https://go.chatwork.com/ja/)
- [Google meet](https://apps.google.com/intl/ja/meet/)

teamsやskypeはコロナ禍になる以前からよく使用されていたビジネス向けビデオチャットツールですね（teamsは管理ビデオチャットツールとは呼ばないか）
zoomはリモート推奨になってからはよく使われるビデオチャットツールですね。
またSlackやChatworkなんかはチャットコミュニケーションとして主に使われていますがビデオチャットとしても使用できます。（3人以上の場合別途有償プラン必須ですが）

- [discord](https://discord.com/brand-new)

discordはゲームなどをやる方々はよく耳にするんじゃないでしょうか。最近では音質やサーバ状況が良好ということもありビジネスで利用するケースも増えているみたいです。

- [o-vice](https://ovice.in/ja/)
- [spetialChat](https://spatial.chat/)
- [Remotty](https://ja.remotty.net/)
- [Sococo](https://www.telework-management.co.jp/services/tool/sococo/)
- [Remo](https://remo.co/)
- [roundz](https://roundz.jp/)

こちらはビデオチャット機能があるバーチャルオフィスサービスに属するものです。
remoなんかはバーチャルカンファレンスツールとしてカンファレンス会場として使用されるみたいです。
roundz/remotty以外は実際のアバターの距離が声の届く距離になっていて、実際にオフィスにいるような会話がで切るみたいです。
roundzはビデオがなく声のみのバーチャルオフィスを提供してるみたいです。（ちょっと話すなどのコミュニケーションを重要視しているみたい）

## まとめ

ビデオチャット多すぎ・・・。
git 基本<リモートでの作業用>

#Gitを使用したリモート（チーム開発）を進める時に使用するコマンドなど

1.git fetch <リモート名>
→リモートリポジトリからローカルリポジトリに内容を反映させる
→あくまでもローカルリポジトリ内
→ローカルのワークツリーには反映させない

2.git merge
→フェッチしてきたファイルなどを、ローカルのワークツリーに反映させる

3.git pull 
→フェッチしてから、マージまでを行うコマンド

##マージとブランチを使いこなそう
1.新たにブランチを作成してみる

git branch <ファイル名>
→新たにbranchを作成する

git branch
→現在あるブランチを表示する

2.作成したブランチに移動してみる

git checkout <ブランチ名>
→HEADを切り替える（ブランチを変更する）
→ブランチを変更することで、作業を並行して行える

3.マージをしてみる

git merge <ブランチ名>
→ブランチないに新たに変更分を取り込んでくれる
PHP XML、チェックボックス、半角全角、剰余算


#simplexml_load_file 読み込むurlを指定
```
simplexml_load_file('ここに読み込みたいhttpsのURLを記述');

----------------------------------------------------------
例
$xml = simplexml_load_file('https://_____________');

foreach($xml->channel->item as $item):
?>
<a href="<?php print($item->link); ?>"><?php print($item->title); ?></a>
<?php
endforeach;
?>

----------------------------------------------------------
<a href=""></a>   リンク先を記述
print($item->link)、print($item->title)　これで中身の要素を指定して出力する

$xmlや＄itemで何を持ってこれているのか、中身の確認をしたい場合
【var_dump】を使用することで確認ができる！！！
var_dump($xml);
```

#チェックボックス
```
チェックボックスを使用する場合、[]を使用し配列として持っていく!
[]がないと、配列の中身は空の状態になる！
name="reserve[]" ←OK
name="reserve"　←NG

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
例
<form action="submit.php" method="post">
  <p>希望日</p>
  <p>
    <input type="checkbox" name="reserve[]" value="6/5">6月5日<br>
    <input type="checkbox" name="reserve[]" value="6/6">6月6日<br>
    <input type="checkbox" name="reserve[]" value="6/7">6月7日<br>
  </p>
  <input type="submit" value="送信する">
</form>
```


#mb_convert_kana　半角全角
```
<?php
  $a = '１０'; ここに全角数字を入れた場合

  $a = mb_convert_kana($a, 'n', 'UTF-8');　←半角に変換
  if (is_numeric($a)){
    print($a.'歳');
  }else{
    print('年齢が数字ではありません');
  }
?>

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
通常は、全角数字では、if文のfalseになるが、
mb_convert_kanaを使用することで、全角数字を【半角】に変換してくれる！
文字の場合は、そのままで扱うえるので便利！！！
```


#ページの遷移 Location
```
<?php
  header('Location: https://_____________');
  exit();

// ページの遷移が可能
```

#剰余算　繰り返しを行う
```
剰余算を使用することで、動きを一定に稼働するよう利用する！
％で出たあまりの数字でを使用する！

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
例
<?php 
  $week = array('日','月','火','水','木','金','土');
  for($i=0; $i<31; $i++) {
    print($week[$i%7]. "\n"); ←割り切れると0になり、再度'日'に戻る！
  }
?>
```
SSL/TLSについて

# はじめに
開発環境構築する上で、XAMPPのSSLを有効化する機会がありました。
参考：[XAMPP for WindowsでSSLを有効にする](https://qiita.com/sutara79/items/21a068494bc3a08a4803)

その際、SSLってなんだっけ？となったので復習を兼ねて自分用にまとめます。
***注意：間違えている可能性があります。***

# ネットワーク通信に潜む危険
ネットワークの通信経路上に潜む危険として、代表的なものが以下の3つである。

### 盗聴
データのやり取り途中で、内容を第三者に盗み読まれる危険性

### 改ざん
データのやり取りは正常に行えているように見えるが、途中で第三者によって内容を書き換えられてしまっている危険性

### なりすまし
第三者がなりすまし、データを送受信できてしまう危険性



とはいえ、通信経路を見られないようにすることは難しい。
そこで、通信経路を見られるのはしょうがないから、見られても大丈夫なように暗号化することが重要である。


参考
キタミ式イラストIT塾 基本情報技術者 平成31年/01年 



# SSL/TLSとは？
SSLは***「Secure Sockets Layer」***の略で、送受信しているデータを暗号化する通信手順。
WebサイトのURLアドレスが、httpsから始まっている（URLに鍵マークがついている）ものはSSL化されている。

TLSは「Transport Layer Security」の略。SSLの脆弱性が発見され、それに対処するために設計されたのがTLS（そのため、厳密にはSSLとTLSは同じものではない）。現在SSLは実はTLSである場合がほとんどだが、なじみ深いSSLという言葉が使用されている。

SSL/TLSは、***共通鍵暗号方式と公開鍵暗号方式を用いて、通信を暗号化する仕組み***。

SSL通信を行うことで、ネットワーク通信に潜む「盗聴」「改ざん」「なりすまし」の防止をしている。

- ***盗聴防止***
  通信を暗号化することで、第三者の盗聴を防ぐ。

- ***改ざん防止***
  通信途中でデータが改ざんされた場合、改ざんされていることがわかる。かつ、信用できないデータを破棄し、再度データを送るよう依頼することができる。

- ***なりすまし防止***
  サイトをコピーしたとしても、SSL通信の際に用いる秘密鍵のコピーはできない。秘密鍵がない状態でSSL通信を行うことはできないため、なりすましであることに気づくことが出来る。


## SSL/TLSの流れ
1. クライアント側からサーバー側に、SSL通信のリクエストを送る
2. サーバー側から***「公開鍵」付きのSSLサーバ証明書***が送付される
3. ルート証明書を用いて、SSLサーバ証明書の署名検証を行う
4. クライアント側で生成した***「共通鍵」***を***「公開鍵」で暗号化***してサーバー側に送付
5. サーバー側は、ペアとなる***「秘密鍵」で複合***し、「共通鍵」を取得
6. ***共通鍵を使って、SSL/TLS暗号化通信を行う***


### SSLサーバ証明書とは？
SSLサーバ証明書とは、ウェブサイトの実在性を確認し、通信データの暗号化を行うための電子証明書。***SSLサーバ証明書には、ウェブサイトの所有者の情報や、暗号化通信に必要な鍵（公開鍵）、発行者の署名データが含まれている。***


### ルート証明書とは？
公開鍵を用いたやり取りを行うにあたり、そもそも公開鍵を作ったものがなりすましを行っていたら、なりすましを防ぐことが出来ない。そこで、信用できる第三者が「この公開鍵は本物である」と証明する機構（認証局）が考えられた。

ただ、***「信用できる第三者の信頼性」はどのように保証されているのか？***
→ルート認証局に関しては、PC出荷時に組み込まれているため信頼性が保証されている。
※Windows Update等で更新される

***ルート証明書とは、つまり最上位にある認証局を保証するものという認識かなと（多分）***


## SSL通信を行う上で共通鍵って必要？？
SSL通信をするうえで、公開鍵暗号方式でデータの暗号化を行えばいいのではないのか？とふと思った。ここで共通鍵暗号方式と公開鍵暗号方式のおさらいをする。

### 共通鍵暗号方式
送り手（暗号化する側）と受け手側（復号する側）が同じ鍵を用いる暗号方式。
この鍵が第三者に知られてはいけない。そのため、共通鍵を安全に受け渡しする必要がある。

強み：暗号化・復号化速度が速い　弱み：安全に鍵を渡す必要がある

### 公開鍵暗号方式
公開鍵暗号方式は、受信側が公開鍵と秘密鍵を用意する。
そして、公開鍵を配布する。データ送信者は、この配布された公開鍵を用いて暗号化する。
公開鍵で暗号化されたデータは、セットとなる秘密鍵でしか復号することができない。
そのため、公開鍵をばらまいても問題ない。

強み：安全性が高い　弱み：暗号化・復号化速度が遅い

### ２つの暗号方式を組み合わせる
上記の強み・弱みを踏まえて、***公開鍵暗号方式で共通鍵を安全に受け渡し、その共通鍵を用いて通信を行うことで安全性・処理速度面においての問題点を解消している。***
こういった背景から、SSL通信を行う際は２つの暗号方式を用いている！



## 参考
[【図解】SSL/TLSとは何か？その違いや仕組み・導入方法についてわかりやすく解説します](https://www.kagoya.jp/howto/rentalserver/ssl/)
[SSLって何？意味や仕組みをわかりやすく解説！](https://ssl.sakura.ad.jp/column/ssl/)
[SSLサーバ証明書とは](https://jp.globalsign.com/ssl-pki-info/ssl_beginner/sslcerts.html)
キタミ式イラストIT塾 基本情報技術者 平成31年/01年 
[いまさら聞けない、SSLサーバ証明書とルート証明書の関係](https://www.digicert.co.jp/welcome/pdf/wp_sslandroot-certificate.pdf)
[SSLサーバ証明書の仕組みに関すること](https://manual.iij.jp/ct/help/2261120.html)
[エンジニアなら知っておきたい、絵で見てわかるセキュア通信の基本](https://qiita.com/t_nakayama0714/items/83ac0b12ced9e7083927)
[サーバー証明書／中間CA証明書／ルート証明書の違いとは？](https://ssl.sakura.ad.jp/column/difference-in-ssl/)
[Python][OpenCV]グレースケール画像を単色濃淡画像に変換する

# はじめに

目標：Pythonを用いて，グレースケール（またはカラー画像をグレースケール化したもの）を単色の濃淡で表したい．例えばこういう感じ (https://www.qam-web.com/?p=13378)

検索してもサンプルコードに行き当たらなかったので，実装した．

## 方法

画像をHSV色調で考えて，彩度に画素値を入れることで擬似的に表現した．
色相参考：https://www.peko-step.com/html/hsv.html

## 実行環境

Python 3.8.8
anaconda 4.10.1
opencv 4.0.1

OpenCV導入: https://qiita.com/SatoshiGachiFujimoto/items/94da93f88578b87f6a89
(上記のanacondaではデフォルトでインストール済みだった）

# 元画像

Lena (https://en.wikipedia.org/wiki/File:Lenna_(test_image).png) を使用．
コードと同じディレクトリに入れておく．

# コード

```python
import numpy as np
import cv2

def main():
    img = cv2.imread('Lenna_(test_image).png', cv2.IMREAD_GRAYSCALE)
    img_color = gray2SingleColor(img, 0) # 第2因数をHSV色調のHで指定，0は赤
    cv2.imshow("image", img_color)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    return

def gray2SingleColor(img, h_hsv): # 黒の部分を指定色に置き換え
    height, width = img.shape[:2]
    hsv = np.zeros((height, width, 3))
    hsv[:, :, 0] = h_hsv/2  # 0-179 for opencv
    hsv[:, :, 1] = (255-img)
    hsv[:, :, 2] = 255
    im = cv2.cvtColor(np.array(hsv, np.uint8), cv2.COLOR_HSV2BGR)
    return im

def gray2SingleColor_rev(img, h_hsv): # 画像強度が大きいところを指定色の濃さに置き換え
    height, width = img.shape[:2]
    hsv = np.zeros((height, width, 3))
    hsv[:, :, 0] = h_hsv/2  # 0-179 for opencv
    hsv[:, :, 1] = img
    hsv[:, :, 2] = 255
    im = cv2.cvtColor(np.array(hsv, np.uint8), cv2.COLOR_HSV2BGR)
    return im

if __name__ == '__main__':
    main()

```

# 結果

### グレースケール読み取り（変換前）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613158/8c8943d3-ed1f-1b84-0ee9-f38d37b59ca7.png)

### 黒の部分を指定色に置き換え

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613158/79232506-7e56-8c5c-08f7-c734d045b1cc.png)

### 画像強度が大きいところを指定色の濃さに置き換え

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613158/cfb98f43-abfd-0284-39d6-8898eefb2153.png)
廃れそうな言語を調べてみた

# (個人的に)今後廃れそうな言語

## Objective-C
iOS開発に必須の言語でしたが、
Swiftの登場によって活躍する機会が減ってきました。
Swiftとの相互互換の機能があるため、
まだ一部の実装で使用しているプロジェクトも散見される印象ですが、
今後はどんどん見る機会が減っていくのではないかと思います。

## R
主に統計分析などで使用されている言語ですが、
Pythonの登場によって使われなくなっている印象です。

# （個人的に）なんだかんだ残りそうな言語

## Ruby
Ruby on Railsが有名になりすぎた印象がありRails自体が最近見かけなくなっていますが、
Ruby自体の言語仕様が優秀なので、今後も使われていくと思います。 

## Java
Kotlinが登場したことによって置き換えるケースがある印象ですが、
既存プロジェクトの総数が多いのと大規模開発で使用される印象があるため今後も使用されると思います。


# まとめ
既存の言語より優れた言語が次々と出てきており、置き換わっていく流れが多い印象がありました。
逆に残りそうな言語はその言語自体が優秀で使うメリットがあるため残っていくのではないでしょうか？
DynamoDBのデータ型とPythonのデータ型の対応

DynamoDBのデータ型は以下があります。Pythonのboto3でDynamoDBからデータを取得したときに、Pythonではどういうオブジェクトになるのかを確認しました。

- String
- Binary
- Number
- Boolean
- Null
- List
- Map
- Set of String
- Set of Binary
- Set of Number

# DynamoDBとPythonのデータ型の対応

boto3のclientを使う場合とresourceを使う場合とで、扱いが異なります。

 `session.client("dynamodb").get_item` は値とともにデータ型の情報が付随してきます。
 `session.resource("dynamodb").Table(table_name).get_item` は直接Pythonのオブジェクトに変換されて取得できます。

| DynamoDBでの型 | client | resource |
| ---- | ---- | ---- |
| String | `{'S': 'abc'}` | `'abc'` |
| Binary | `{'B': b'Hello,\nWorld!\n'}` | `Binary(b'Hello,\nWorld!\n')` |
| Number | `{'N': '1234'}` | `Decimal('1234')` |
| Boolean | `{'BOOL': True}` | `True` |
| Null | `{'NULL': True}` | `None` |
| List | `{'L': [{'S': 'abc'}, {'N': '123'}]}` |  `['abc', Decimal('123')]` |
| Map | `{'M': {'entry1': {'S': 'abc'}, 'entry2': {'S': 'def'}}}` | `{'entry1': 'abc', 'entry2': 'def'}` |
| Set of String | `{'SS': ['abc', 'def']}` | `{'abc', 'def'}` |
| Set of Binary | `{'BS': [b'Hello,\n', b'World!\n']}` | `{Binary(b'World!\n'), Binary(b'Hello,\n')}` |
| Set of Number | `{'NS': ['123', '456']}` | `{Decimal('456'), Decimal('123')}` |

2列目は `session.client("dynamodb").get_item`  で取得した結果です。
3列目は `session.resource("dynamodb").Table(table_name).get_item` で取得した結果です。

いずれもPythonの pprint での出力です。

# Pythonコード

確認に使ったPythonのソースコードです。

```python
from pprint import pformat

import boto3

profile = "default"
table_name = "sample"
record_id = "test1234"

session = boto3.session.Session(profile_name = profile)
dynamodb_client = session.client("dynamodb")

res = dynamodb_client.get_item(
    TableName = table_name,
    Key = {
        "Id": {
            "S": record_id,
        },
    },
)
for col, value in res["Item"].items():
    print(f"{col}: {pformat(value)}")

print()

dynamodb_resource = session.resource("dynamodb")
table = dynamodb_resource.Table(table_name)

res = table.get_item(
    Key = {
        "Id": record_id,
    },
)

for col, value in res["Item"].items():
    print(f"{col}: {pformat(value)}")
```
Markdown記法 サンプル集

### [Markdown記法 サンプル集](https://qiita.com/tbpgr/items/989c6badefff69377da7)

> お世話になります。xxxです。
> 
> ご連絡いただいた、バグの件ですが、仕様です。

インストールコマンドは `gem install hoge` です

~~~powershell
$Disk = $args[1]
$ftpUploadPath = $args[2]

if(!(Test-path -LiteralPath $Disk$ftpUploadPath)){
	mkdir -p $Disk$ftpUploadPath
}
~~~


java

~~~java
package main;

import java.util.Date;

public class Tool {
	
	public static String getDatePoor(Date startDate, Date endDate) {
		
	    StringBuffer result = new StringBuffer();
		 
	    long nd = 1000 * 24 * 60 * 60;
	    long nh = 1000 * 60 * 60;
	    long nm = 1000 * 60;
	    long ns = 1000;
	    // 获得两个时间的毫秒时间差异
	    long diff = endDate.getTime() - startDate.getTime();
	    // 计算差多少天
	    long day = diff / nd;
	    // 计算差多少小时
	    long hour = diff % nd / nh;
	    // 计算差多少分钟
	    long min = diff % nd % nh / nm;
	    // 计算差多少秒//输出结果
	    long sec = diff % nd % nh % nm / ns;
	    
	    if(day != 0) {
	    	result.append(day + "天");
	    }
	    if(hour != 0) {
	    	result.append(hour + "小时");
	    }
	    if(min != 0) {
	    	result.append(min + "分钟");
	    }
	    if(sec != 0) {
	    	result.append(sec + "秒");
	    }
	    
	    if(result.toString().equals("")) {
	    	result.append("0秒");
	    }
	    
	    return result.toString();
	}
	
}

~~~