OmniAICreator/Qiita-1.07M huggingface dataset:
cronの設定

# cronの設定

二番煎じですが忘れることが多いのでQiitaに投稿

## ステータス確認
```
$ /etc/init.d/cron status
● cron.service - Regular background program processing daemon
   Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2021-03-30 21:54:08 JST; 4 days ago
     Docs: man:cron(8)
 Main PID: 560 (cron)
    Tasks: 1 (limit: 2373)
   Memory: 7.7M
   CGroup: /system.slice/cron.service
           └─560 /usr/sbin/cron -f
```

## ユーザージョブ設定
```
$ crontab -u [user] -e
```

## ジョブ登録

crontabの書き方は以下を参考

https://gist.github.com/koudaiii/4f3a2c78db0274c91f55

*例：毎分ファイルを作成*

```
* * * * * touch /tmp/hoge_`date +\%Y\%m\%d\%H\%M\%S`
```

## 確認

```
# cat /var/spool/cron/crontabs/bitnami

* * * * * touch /tmp/hoge_`date +\%Y\%m\%d\%H\%M\%S`

$ ls /tmp/hoge_*

/tmp/hoge_20210404085001  /tmp/hoge_20210404085201  /tmp/hoge_20210404085401  
```

## shで自動登録

以下のようなshを作成することでコードで管理することができる。

*crontab.sh*

```
#!/bin/sh

USERNAME=$(whoami)

echo "* * * * * touch /tmp/hoge_`date +\%Y\%m\%d\%H\%M\%S`" >> /tmp/crontab.temp

if crontab -u ${USERNAME} /tmp/crontab.temp
then
    echo "crontab install is done successfully."
else
    echo "crontab install is failed."
fi
rm /tmp/crontab.temp
```

---

いいね！と思ったら LGTM お願いします :clap::clap::clap:

【PR】プログラミング新聞リリースしました！ → https://pronichi.com
【PR】週末ハッカソンというイベントやってます！ → https://weekend-hackathon.toyscreation.jp/about/
グラフと三角形面積求めてみた

Python学習の一環で棒グラフを作り、その面積を求める簡単なプログラム作ってみました。

**環境：**
Google Colaboratory

**フロー：**
①数字を入れる。
②数字を入れた数だけ棒グラフができる。
③形状が正三角形になるので、その面積を求める。

先ずは数字入力項目作り、変数nを設定

```python
n = int(input('数>'))
```


次にrange関数で数字出力範囲を決めます。出力の際に使用されるprint関数の引数endを記載。
endは、第一引数で渡した出力したい文字列の末尾にendで指定した文字列を出力します。
今回endを定義していますが、特に内容を指定していないので、出力はされていません。
これをfor文で回します。(for1)

```python
for j in range(1,n+1):
    print(str(j)+':', end=' ')
```


更に上記変数jの数の範囲で、第一引数■を、文字列の末尾に入れる為、endを使用し, for文で回します。(for2)

```python
    for i in range(0,j) :
        print('●',end='')
```

次にprint()をどこに入れるかが焦点になります。
for1, for2の処理がされての出力を行いたいので、for1に対してのprint出力になります。

```python
print()
```

最後に、数字入力が棒グラフの高さ、幅になり, 正三角形の形状になります。入力した数字から三角形面積を出力するコードを書いて終了です。

```python
print(f'面積:{j*j/2}')
```

**まとめコード**

```python
n = int(input('数> '))
for j in range(1,n+1) :
    print(str(j)+':',end='') 
    for i in range(0,j) :
        print('●',end='')
    print() 
print(f'面積:{j*j/2}')
```


**出力結果**
数> 5
1:●
2:●●
3:●●●
4:●●●●
5:●●●●●
面積:12.5

以上のように数字毎に●の数が表示されています。また、全体的な面積も出力されています。for文を二つ使う部分について、それぞれの目的として考えなければならないという点とendがはじめなかなか理解しづらかったです。
ファイルの圧縮、解凍とは

今回は、ファイルの圧縮、解凍について解説したいと思います。
ファイル圧縮とファイル解凍、これらは特に仕事でパソコンを利用されている方々に
とって日常的な操作だと思います。
なので、分からない場合聞きずらいことだと思います。。。
受け取ったファイルが圧縮されたもので、解凍しないとファイルの中身を見ることや
使用することができないのに、その方法が分からない。
その逆にファイルを圧縮して送りたい場合には、圧縮の方法を知らなければ相手の要望
通りに送ることができない。
そんなことを避けるためにも、ここで改めて確認・予習していきましょう！
#ファイルの圧縮、解凍とは
##圧縮

ファイル圧縮とは、データ量を節約するために開発された仕組みです。
例えば、「aaaaaaaaaa」といったような「a」が１０回並んだデータがある場合、
それを「a10」と表記すれば,
「aaaaaaaaaa」（１０文字）　－　「a１０」（３文）　＝　７文字
上記のように7文字分のデータを節約できます。
今では、通信手段が発達した為意識することはないとは思いますが、一昔前は記録す
る容量が小さなものが多く、データ通信も発達していないため、送るファイルはできる
だけ小さくする必要がありました。
そんな歴史がありファイルの圧縮は生まれました。
「じゃあ、なんで今でも使うの！？」とここまで読んで頂いた方は思われるかもしれませ
んが、実はメリットがいくつかあります。
<dl>
  <dt>ファイル圧縮のメリット</dt>
  <dd> ファイルサイズを小さくできる </dd>
  <dd>複数のファイルを1つにまとめられる</dd>
  <dd> パスワードを設定してファイルを保護できる </dd>
</dl>
一つ目の「ファイルサイズを小さくできる」ですが、これは今でもデータを小さくできると
いうのはメリットです。
例えば、取引先の相手にファイルを送る場合、ファイルサイズが大きすぎるとかなり送るの
が重たすぎる、受け取った側も重たすぎるファイルを受け取りたくはあまりありません。
なので、いまも多くのユーザーから重宝されています。


二つ目の「複数のファイルを１つにまとめられる」は、相手の複数のファイルを送りたい！っと
なた場合、フォルダごと送ればいいと思われるかもしれませんが、フォルダを丸ごとメールや
メッセージアプリに添付することができません。
１ファイルごと添付すればいいかもしれませんが、それは受け取った側からしたらかなり煩わしいです。。。
そこでファイル圧縮を利用すると、たくさんあるファイルを階層構造ごと1つのファイルにまとめてしま
うことができます。

三つ目の「パスワードを設定してファイルを保護できる」は、ファイルを圧縮する際にパスワードを設定
しておくと、圧縮されたファイルを受け取った人が正しいパスワードを入力しないと開けれなくすること
ができます。
これで、気密性の高いファイルを送る場合も、送る過程で盗み見されるリスクを防ぐことができます。

このようにファイルの圧縮は今の環境でも必要な機能ということが分かります。

##解凍
ファイルの解凍は、一度圧縮されたファイルを元の状態に復元することです。ここは重要な部分で、
ファイル圧縮には復元できる形式とそうでないものがあります。

例えば画像の圧縮形式であるJPEG、動画の圧縮形式であるMP4は画像、動画のデータ量を節約する
ことができる圧縮技術ですが、一度JPEG、MP4で圧縮したものを圧縮前の画質に戻すことはできません。
それに対してZIPやLZHといったファイル圧縮技術は、元のデータに復元することができます（この復元
作業を解凍といいます）。
今回の内容で解説するのは、このように復元できる技術を用いたファイル圧縮と、ファイル解凍です。

解凍のメリットは、上記のように圧縮したファイルに必要なので、メリットは圧縮での内容と同じになると思われます。
Nginx 　sudo systemctl start nginx　できない

EC2上でNginxを読み込むため、

```ruby
sudo systemctl start nginx　
```

を実行すると

```ruby
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
```

とエラーが返ってきました。

以下解決方法を記します。

### /etc/nginx/conf.d/rails.conf　の確認

ターミナル上で以下のコマンドを時効すると、/etc/nginx/conf.d/rails.confの記述内容が正しいかを検証できます。

```ruby
$ sudo nginx -t
```

結果、/etc/nginx/conf.d/rails.conf　に以下の誤りがあることがわかりました。

```ruby
error_page 500 502 503 504 /500.html;
{  <=中括弧の向きが逆
```

こちらを修正すると、

```ruby
=> nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

のように表示されます。

### それでもうまくいかない場合

私の場合はkillコマンドでプロセスをkillし、再度実行したらうまくいきました。

```ruby
$ ps aux | grep unicorn #EC2のアプリケーションのリポジトリ内で
```

```ruby
$ kill プロセス番号 #EC2のアプリケーションのリポジトリ内で
```

皆様のご参考になればと思います。
【Pandas】DatetimeIndexとは？　no.29

![見出しを追加 (67).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/c7ad0091-335d-9782-2962-a4f46400d4e5.png)
こんにちは、まゆみです。

Pandasについての記事をシリーズで書いています。

今回は第29回目の記事になります。

[前回の記事](https://qiita.com/Mayumi_Pythonista/items/4a323e507646e3e9c98c)から、Pandasの時間に関するモジュールについて書いています。

今回の記事では、『DatetimeIndex』について特化して書いていきます。

ではさっそく始めていきますね。

#DatetimeIndex
![見出しを追加 (68).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/13dd8f0a-b692-9e29-14d0-c7f05771d082.png)

DatetimeIndexとは文字通り、<font color="Red">『時間のデータ』 でインデックスを作る</font>ことができます。

前回の記事で紹介した、Pandasの『TimeStamp』はある1点の時間に関するデータでしたが、<font color="Red">DatetimeIndex はTimeStampが複数集まったもの</font>になります。

なので、リストに入れ、引数として渡しDatetimeIndexを作ります。

下記のスクショのように、予め、リストに入れたTimeStampを変数に代入してその変数を引数として渡しても良いですし、

![スクリーンショット 2021-04-04 073336.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/f171056d-040e-c891-78a6-5cc6f532a17a.jpeg)

リスト型データを変数に代入せず、リスト型データ自体をそのまま引数として渡しても大丈夫です。


![スクリーンショット 2021-04-04 073502.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/6d595fdf-5eb2-c2c2-4b2e-cde1e04eddb0.jpeg)

また、引数として渡すリストの中のアイテムは

>2020/03/06

>2020/June/12

>2020,03, 12

<font color="Red">ハイフンでも、スラッシュでも英語で表記しても</font>、ちゃんと認識されることは前回の記事でも書かせていただいた通りです。

また、Pythonにビルトインされているtype関数でデータ型を調べてみても、ちゃんとDatetimeIndexと表示されます

![スクリーンショット 2021-04-04 074829.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/3d3464e1-181a-2f64-b92f-b43642496ef6.jpeg)


![スクリーンショット 2021-04-04 073609.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/8143e46e-94c0-5914-a535-9032bf255f56.jpeg)
引用元：[Pandasドキュメント](https://pandas.pydata.org/docs/reference/api/pandas.DatetimeIndex.html)

ドキュメントにも書かれている通り、1-dimensional(1次元の)データを　data というパラメーターに引数として渡せばDatetimeIndexを作ることができます。(1-dimensional データって何？という方は[こちら](https://qiita.com/Mayumi_Pythonista/items/e900c09ca3c8f799e32b#one-dimensional%E3%81%A8%E3%81%AF)を参考にどうぞ)

#DatetimeIndexを使って、Seriesを作ってみる

せっかくDatetimeIndex を作ったので、それをSeriesのインデックスにしてみましょう

![スクリーンショット 2021-04-04 075714.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/8c693f92-9ccd-a60a-d718-718e30d0565e.jpeg)

#まとめ

今回の記事は、これくらいで終わりにします。

次回は、『.to_datetime()』メソッドについて記事にしていきますね。
python3で文字の切り取りの方法

python3での文字の切り取り方法です。
例として、12:34を標準入力から入力して、時と分を1行ずつ改行して標準出力するサンプルコードです。


```python3
input_line = input()
str1 = input_line[0:2]
str2 = input_line[3:5]
num1 = int(str1)
num2 = int(str2)
print(num1)
print(num2)
```


少し冗長に書いていますが2行目と3行目が指定された部分の文字列を切り取っています。
是非参考にしてください。
S3に画像アップロードして特定IPだけアクセス可能にする

1. Bucket作成
1. アクセ師制御ページを開く; 対象バケット > アクセス許可
1. ブロックパブリックアクセス > `任意のパブリックバケットポリシーまたは〜` をオフにする
1. バケットポリシーを編集

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AddPerm",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::${バケット名}/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "${対象のIPアドレス}"
                }
            }
        }
    ]
}
```
EC2起動コマンド


cdでホームディレクトに移動します。

```:ターミナル
cd ~
```
sshディレクトに移動します。

```:ターミナル
cd .ssh/
```
ダウロードした鍵の検索をします。

```:ターミナル
ls
```
EC2にログインします。

```:ターミナル
 ssh -i ダウンロードした鍵の名前.pem ec2-user@作成したEC2インスタンスと紐付けたElastic IP
```
クローンしたディレクトリに移動します。

```:ターミナル
cd  /var/www/開発中のアプリケーション
```
JavaScript Substringの使い方

## 概要
文字列を任意の箇所で切り取ることができます。

i番目から次の文字からj番目までを切り取ります。

```js
substring(i,j) //ｊは省略可能
```

```js
let hello = "hello";
//指定した番号から切り取ります
console.log(hello.substring(1)); //ello
console.log(hello.substring(4)); //o

console.log(hello.substring(0, 1)); //h
console.log(hello.substring(1, 3)); //hel
//lengthを使用
console.log(hello.substring(0, hello.length)); //hello
console.log(hello.substring(0, hello.length -1)); //hell
console.log(hello.substring(2, hello.length -1)); //ll
```

###参考
[MDN substring](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/substring)
ABAPレポートプログラムにchatbot(SAP Conversational AI)を実装する

#ゴール
ABAPで作成したアドオンプログラムに、SAP Conversational AIで作成したchatbotを実装する。
![ABAPからCAI.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22526/5fd8bb34-ff85-6c71-0c66-f159c749dad1.gif)

#ステップ
1. SAP Conversational AIでchatbot作成
2. ABAPプログラムにchatbot実装(こちらが本題)

#SAP Conversational AIでchatbot作成
こちらは、以下を参照(ステップ2)
[SAPUI5アプリケーションにchatbot(SAP Conversational AI)を実装する](https://qiita.com/mahko2/items/052ed10fbcb541701234)

#ABAPプログラムにchatbot実装
キッカケは以下のSAP Community Blogでした。
[How to Integrate a SAP Conversational AI Chatbot with SAP GUI](https://blogs.sap.com/2021/02/28/how-to-integrate-a-sap-conversational-ai-chatbot-with-sap-gui/)

cl_demo_outputを使用してchatbotを呼び出すだけなので、入力された値をABAP内で使用して、、とかはないです。
ソースコードはこんな感じ(ABAPのハイライトはうまく表示されないみたい)

```abap
REPORT y_test_cai.

* Webchat scriptの値
CONSTANTS src       TYPE string VALUE '<srcの値>'.
CONSTANTS channelid TYPE string VALUE '<channelidの値>'.
CONSTANTS token     TYPE string VALUE '<tokenの値>'.
CONSTANTS id        TYPE string VALUE '<idの値>'.

* 画面にボタン表示
SELECTION-SCREEN PUSHBUTTON 1(12) TEXT-b01 USER-COMMAND cai.

* 選択画面イベント
AT SELECTION-SCREEN.

  CASE sy-ucomm.
*   ボタン押下時
    WHEN 'CAI'.
      DATA(html) = |<script src="{ src }" channelId="{ channelid }" token="{ token }" id="{ id }"></script>'|.
      cl_demo_output=>display_html( html ).
    WHEN OTHERS.
  ENDCASE.
```
※src、channelid、token、idの値は、CAIのWebchat scriptを設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22526/d8c347e3-2368-2805-4ab4-6b37fb247906.png)

※channelidとかは、TVARVCなどで管理がよいのかも
※cl_demo_outputなのでお遊び的な使い方です
英単語発音のカナ表記の調べ方

# 英単語発音のカナ表記の調べ方
英単語発音のカナ表記の調べ方を示す。（特に[US]米英語の発音が気になった場合。）
<font color="blue">**【1】か【2】が、お薦め。**</font>
<font color="green">結局【1】ですかね。特別、具体的に【1】が良いというより、辞書として発音のカナ表現が提供されているものが、情報にはずれがない気がします。</font>

# 【1】英辞郎 :star2::star2:
https://eow.alc.co.jp/

図引用：https://eow.alc.co.jp/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/3d717370-748d-e799-6309-7945ae795d83.png)

結果表示例。
図引用：https://eow.alc.co.jp/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/aa28aa61-7759-f371-d008-be676053edbf.png)

## サンプル(combination, often)
[US]カムバネイション、[UK]コムビネイション
[US]オファン、アファン、[UK]オフン、オフトゥン


# 【2】toPhonetics :star2:
https://tophonetics.com/ja/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/5b181802-938e-07b2-ed63-19788c0c6951.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/2461e69a-0d66-4ba2-2c34-63f297b818f6.png)

## サンプル(combination, often)
[US]カムバˈネイシャン
[UK]コムビˈネイシャン

[US]オファン
[UK]オファン

# 【3】英語→カタカナ変換機
https://www.sljfaq.org/cgi/e2k_ja.cgi

図引用：https://www.sljfaq.org/cgi/e2k_ja.cgi
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/c840d53c-48ec-0a48-4731-1274e4ca86c8.png)

## サンプル(combination, often)
※[US]/[UK]どちらか明示されていないが、内容からすると[UK]
コンビネーション(コンビネーシュン)
オッフン


# 【4】freeenglish.jp
https://freeenglish.jp/pronunciation.html

図引用：https://freeenglish.jp/pronunciation.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/631f5619-6028-d5d6-47f8-2c904ffbb509.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/7a9f7969-b340-cd77-ad60-9758b8cf0a82.png)

## サンプル(combination, often)
※[US]/[UK]どちらか明示されていないが、内容からすると[US]
カムバネイしゃン
オーふぁン

## 補足

* かなの表記方法は、不明です。カタカナ、ひらがなの区別あり。また、太文字とかあり。
* このサイト自体は、最近の更新はないよう。

#まとめ
特にありません。
コメントなどあれば、お願いします。:candy:

#関連本人記事（余興）

[深層学習。自分を過学習させてみて、様子を観察する[英語リスニング編]。（いま、800回ループ中。まだ、過学習未達成。）](https://qiita.com/enoughspacefor/items/9042ebbbb198c0e42922)

[英単語発音。まずは、カナ表記レベルで誤りを認識する。](https://qiita.com/enoughspacefor/items/ae3e80f3bf2fe778ccd9)
Rails Validation failed: [Model] must exist

## 原因

* Railsでhas_manyのassociationが存在する場合に起こる
* 例 UserがPostというテーブルがあり、Users has_many Postsの関係性だとする。
* Postsを単体で作成しようとすると`Rails Validation failed: [Model] must exist` というエラーが起こる

## 解決方法

* `models/post.rb`のbelongs_toにoptional設定を入れる

```user.rb
belongs_to :users, optional :true
```

## optional trueとは？

optional trueは、belongs_toの外部キーのnilを許可するというもの。

## 参考

https://blog.ryskit.com/entry/2018/01/27/195442
Scikit-learn Boston Housing Datasetを使ってみる

Scikit-learnから使えるものに、Boston Housing Datasetというのがある。

Boston Housing Dataset
https://scikit-learn.org/stable/datasets/toy_dataset.html

まずは、データをロードしてみる。。。

<pre>
from sklearn import preprocessing
import pandas as pd
import numpy as np # we'll need it later
#Load the Boston dataset.

from sklearn.datasets import load_boston

boston = load_boston()
X,y = boston.data, boston.target
</pre>

データは、
boston.data
boston.target
に分かれる。

まずは、プロットしてみる。。。

<pre>
import matplotlib.pyplot as plt

plt.figure()
plt.subplot(211)
plt.plot(X)
plt.subplot(212)
plt.plot(y)
</pre>

![ダウンロード (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163445/d590acd1-40b2-9391-e3b4-6c80a2b6ac5b.png)

target(教師データ）の粒度を下げる方法がある。

np.digitizeという手法を使う。

<pre>
bins = 20*np.arange(20)
binned_y = np.digitize(y, bins)

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,stratify=binned_y)
</pre>

プロットしてみる。。。

![ダウンロード (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163445/243133ad-0d90-c287-61c2-56cd51c71e31.png)

https://github.com/RuoAndo/time-series-analysis-with-Python/blob/master/boston/dataload-boston-housing.ipynb
Braveブラウザで効率よくBATを稼ぐためにやってはいけないこと

#はじめに
最近話題のBraveブラウザ、使っていく中でBAT(BATポイント)を稼ぐためには注意しなくてはいけない点が存在することに気付いたので記事に残しておきます。
今後仕様が変わり効率よくBATを稼ぐための設定は変わっていくことも考えられますが自分がこのブラウザを使い続けている間は情報を更新していこうと考えています。

#Braveブラウザとは
Braveブラウザは強力な広告ブロック機能とプライバシー保護機能、そしてスピードを備えた新しいブラウザです。これだけで他のブラウザから乗り換える価値があると思います。しかし、このブラウザの最も特徴的な部分は広告表示をコントロールし、Braveから承認された広告を表示することによってユーザーが報酬を貰うことができる仕組みがあることです。

https://brave.com/ja/

詳しい仕組みは省きますがユーザーは広告を1時間に何回受け取るか、などを設定することによって受け取った広告数に応じてBasic Attention Tokenを報酬として得ることができます。現在できる設定では最高で1時間に5回広告を受け取ることができますが、残念なことに日本向けにはまだまだ広告数が少なく、1時間に最大5回に設定したとしても何時間も広告が来ないという現象が起きてしまいます。しかし、拡張機能や設定を工夫することによって毎回最大数の広告を受け取ることができるようになります。

#新しいタブをデフォルト以外のものにしてしまう拡張機能を入れると広告が激減する
FirefoxやChromeなどのブラウザからBraveに乗り換えた場合、恐らく多くのユーザーは新しいタブを開いたときに表示されるトップページが少ない、と感じるのでないでしょうか。Operaで言うとスピードダイヤルと呼ばれる機能でよく行くページがいくつかピックアップされ表示されるあの機能です。
Braveブラウザでは現状、6つまでしかトップページが表示されずFirefoxから乗り換えた身としてはあまりにも少なく感じました、これを解決するためにスピードダイヤル的なブラウザ拡張をインストールして表示数を増やしていたわけですが、これが広告数を激減させてしまうことに繋がってしまいます。

Braveの新しいタブは設定から背景画像にスポンサー画像を表示させることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214955/45b9fcfb-4a62-188e-63bc-a3411e42034b.png)
画像は新しいタブの設定画面ですが、画像と同じように設定すると何度かに一回、ちょうど後ろに表示されているようなスポンサー画像が表示されることがあります。実はこれが表示されることでも報酬を得ることができます。
新しいタブの背景画像は更新すれば他のものに切り替わるので1時間ごとに数回更新してしまえば最大数広告を得ることができてしまうわけです。

設定のこの部分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214955/135071a9-473a-e5b8-6c90-d5a328520b16.png)
をダッシュボードに設定し、ダッシュボード右下のカスタマイズをクリックして”スポンサー画像を表示する”をON、そしてスピードダイヤルなどの新しいタブを制御するような拡張機能は入れない、これが現在Braveブラウザで最も効率よくBATを稼ぐ方法だと思われます。

現在この他にも広告に関する設定を検証中ですのでよりよい方法があれば更新していこうと思います。
【javascript】配列のシャッフル

#コード
`Math.random() - 0.5`と大差ないっぽい

```javascript:
const shuffleArray = arr => arr.sort(() => Math.random() - Math.random());

console.log( shuffleArray([...Array(5).keys()]) );
```


#参考にした記事

[JavaScript] 配列の要素をシャッフルする実装方法
https://qiita.com/k_kazukiiiiii/items/7da39df4fe28d2fb3898
この記事を書くきっかけになった記事です。

javascriptでワンライナーでArray shuffle (2016年版)
https://qiita.com/terrierscript/items/94bf137c12bcda9e5dab
sortでいけるって教えてくれた記事。

Array#sort実装のshuffleは偏る
https://qiita.com/minodisk/items/94b6287468d0e165f6d9
sort微妙って教えてくれた記事。

入力配列をシャッフルした配列を返す関数
https://qiita.com/fushikky/items/9ba4ed092133d47b8822
コメントの@iMasanariさんのコードが良さそうなので単純化しました。


#感想
Fisher-Yatesが最適解なんだろうけど、このコード量は魅力的。
Boston Housing Datasetを使ってバギング回帰をする

Boston Housing Dataset
https://scikit-learn.org/stable/datasets/toy_dataset.html

データをロードする。
<pre>
import numpy as np
import pandas as pd

from sklearn.datasets import load_diabetes

diabetes = load_diabetes()

X = diabetes.data
y = diabetes.target

X_feature_names = ['age', 'gender', 'body mass index', 'average blood pressure','bl_0','bl_1','bl_2','bl_3','bl_4','bl_5']
</pre>

教師データをサンプリング（ヒストグラム）することで粒度を下げる。

<pre>
#bin target variable for better sampling
bins = 50*np.arange(8)
binned_y = np.digitize(y, bins)

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,stratify=binned_y)
</pre>

プロットしてみる。。

<pre>
import matplotlib.pyplot as plt
plt.figure()
plt.subplot(311)
plt.plot(X)
plt.subplot(312)
plt.plot(y)
plt.subplot(313)
plt.plot(binned_y)
</pre>

![ダウンロード (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163445/fe15fb4f-d560-7fa2-435f-9968f3232e11.png)

KNNを使ってバギング回帰をする。

<pre>
from sklearn.ensemble import BaggingRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import RandomizedSearchCV

single_estimator = KNeighborsRegressor()
ensemble_estimator = BaggingRegressor(base_estimator = single_estimator)

param_dist = {
 'max_samples': [0.5,1.0],
 'max_features' : [0.5,1.0],
 'oob_score' : [True, False],
 'base_estimator__n_neighbors': [3,5],
 'n_estimators': [100]
 }

pre_gs_inst_bag = RandomizedSearchCV(ensemble_estimator,
 param_distributions = param_dist,
 cv=3,
 n_iter = 5,
 n_jobs=-1)

pre_gs_inst_bag.fit(X_train, y_train)
</pre>

ベストなパラメータを見つける
<pre>
pre_gs_inst_bag.best_params_
</pre>

結果を張り付ける
<pre>
rs_bag = BaggingRegressor(**{'max_features': 0.5,
 'max_samples': 1.0,
 'n_estimators': 100,
 'oob_score': True,
 'base_estimator': KNeighborsRegressor(n_neighbors=5)})
</pre>

学習
<pre>
rs_bag.fit(X_train, y_train)
</pre>

予測してみる。。

<pre>
y_pred = rs_bag.predict(X_test)

from sklearn.metrics import r2_score, mean_absolute_error

print("R-squared",r2_score(y_test, y_pred))
print("MAE : ",mean_absolute_error(y_test, y_pred))
print("MAPE : ",(np.abs(y_test - y_pred)/y_test).mean())
</pre>

プロットしてみる。。
<pre>
plt.figure()
plt.subplot(211)
plt.plot(y_pred)
plt.subplot(212)
plt.plot(y_test)
</pre>

![ダウンロード (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163445/94e3d53e-cf9b-080a-5806-e16ab7b86577.png)


https://github.com/RuoAndo/time-series-analysis-with-Python/blob/master/qiita/boston-bagging.ipynb
【AWS】CognitoでSignUpしたユーザの情報をDynamoDBに追加する方法

現在iOSアプリを開発しており、Cognitoを使ったログイン機能は実装できたのですが、登録したユーザ名などの情報をアプリ上でも使いたかったのでその方法をまとめておきます。

ざっくりと以下のような流れになります。

**0. Cognitoでユーザプールを作成する
1. DynamoDBにデータを追加するテーブルを作成する
2. Lambda関数を作成する
3. Cognitoで確認後トリガーにLambda関数を設定する**

# 0. Cognitoでユーザプールを作成する
すでにユーザプールが作成されていることを想定しているため、省略します。
（ユーザプール名は```sample-userpool```としました。）
Lambda関数を作成後、トリガーの設定をするために戻ってきます。

# 1. DynamoDBにデータを追加するテーブルを作成する
下記のように、テーブル名を```sample-table```、プライマリーキーを```username```とし、テーブルを作成します。
今回はusernameだけを使いたいので、そのほかの属性は省略します。

# 2. Lambda関数を作成する
下記のように、関数名を```sample-lambda```、ランタイムを```Python3.8```とします。
![スクリーンショット 2021-04-04 3.01.51.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805717/531e9898-d0a5-3ca9-58ab-8444f57e9e64.jpeg)

アクセス権限のロールは、```AWSポリシーテンプレートから新しいロールを作成```にして、```シンプルなマイクロサービスのアクセス権限```と```テストハーネスのアクセス権限```を選びます。
![スクリーンショット 2021-04-04 3.59.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/805717/3794d562-8b02-5796-c692-7a37af812fd6.png)

次に、LambdaではPythonの外部モジュールをzipで読み込む必要があるため、zipファイルを作ります。
今回は```boto3```というAWSが提供しているライブラリを使用するため、下記コマンドでインストールします。

```
$ pip install boto3 -t ./sample-modules
```

すると、```sample-modules```が作成され、その中にいくつかのディレクトリとファイルが追加されていると思います。
できていたら、今作成した```sample-modules```内に、```lambda_function.py```を作成します。

```
$ cd sample-modules
$ vi lambda_function.py
```

Cognitoからユーザ情報（username）を受け取り、DynamoDBに追加するためのPythonのプログラムをlambda_function.pyに書き、保存します。

```Python:lambda_function.py
import boto3

def lambda_handler(event, context):

    dynamoDB = boto3.resource("dynamodb")
    # DynamoDBのテーブル名
    table = dynamoDB.Table("sample-table")

    # DynamoDBへデータを追加する
    table.put_item(
      Item = {
        "username": event['userName']
      }
    )

    return event
```

そして、sample-modules配下のファイルのパーミッションを755にします。

```
$ chmod -R 755 ./sample-modules/
```

最後に、現在のsample-modulesを圧縮し、upload.zipにします。

```
$ zip -r upload.zip *
```

これができたら、先ほど作成したLambda関数にzipファイルをアップロードしましょう。

念のため、テストタブで下記の```SignUpEvent```を実行して見てください。
DynamoDBのsample-tableに```testName```が追加されていたら成功です！

```
{
  "triggerSource": "testTrigger",
  "userPoolId": "testPool",
  "userName": "testName",
  "callerContext": {
      "clientId": "12345"
  },
  "response": {}
}
```

# 3. CognitoのトリガーにLambda関数を設定する
最後に、ユーザがSignUpを完了したタイミングで作成したLambda関数を呼び出すために、Cognitoのトリガーを設定します。
Cognitoでユーザプールを開き、左のメニューの```トリガー```を選択します。
すると、サインアップ前や認証前などが出てくると思うので、```確認後のトリガー```で```sample-lambda```を選んでください。

これで全工程が完了です！！いかがでしたでしょうか。
私は今回Lambdaを初めて使ったのでかなり時間がかかりました・・なので備忘録としてここに残しておきます。

# 参考にしたサイト
* https://zenn.dev/tatsurom/articles/cognito-data-to-dynamodb
* https://blog.denet.co.jp/lambda-python-zip/
* https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/user-pool-lambda-post-authentication.html
【Ruby】入力した文字列をハイパーリンク化する機能の実装【rails_autolink】

## はじめに
質問投稿アプリケーションを制作する上で投稿したURLから直接飛べるようにしたいと思い、いくつか方法を試した中でうまくいったものをまとめます。

##開発環境
Mac OS BIG Sur 11.1
ruby 2.6.5
Gem 3.0.3

##使用Gem
rails_autolink
https://github.com/tenderlove/rails_autolink
参考記事
https://d4192.hatenablog.com/entry/2019/04/10/141200

##Gemの導入
 ```:Gemfile
# Gemfileの一番下に記述
gem 'rails_autolink'
```
Gemfileに追記した後にbundle installを実行

##auto_linkメソッドを使う
```:sample.html.erb
<%= auto_link(sample.comment, html: { target: '_blank' }) %> 
```
auto_linkメソッドを使って自動挿入する文章をauto_link()を使って囲う。さらに、:htmlに属性を渡すことで、aタグに属性を挿入してくれる。

## auto_linkメソッドについて
auto_linkメソッドは、Ruby on Rails 3.0まで使用可能だったメソッドでのちのRuby on Rails 3.1でセキュリティの問題から使用できなくなっていた。今回使用したGemでは危険なタグを削除する機能がデフォルトでついているのでセキュリティ面は問題ないと思われる。

## 最後に
初投稿ですので間違った内容が含まれる場合がございます。
間違いや追記するべき内容があった場合はコメントをお願いします。
Visual Studioの「ビルドイベント」でビルド後のオプションを設定する

Visual Studioの「ビルドイベント」という機能で
ビルド後のオプションが設定できると聞いたのですが


どこに有るか全然分からねえ！

となって探し回ったので、誰かの役に立てば幸いです。

#設定方法#
［プロジェクト(P)］＞［（プロジェエクト名）のプロパティ(p)］
からプロジェクトの設定を開きます。
![プロパティの開き方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100934/ff8eed44-272b-de2b-7498-98e2e8921c05.png)

そして、ここから2パターンあって
後者だと見つけにくいと思います。

##パターン1##
左のメニューに「ビルドイベント」があれば、こんな画面が出るので
ここビルド前後に実行したいコマンドを設定できます
![プロジェクト プロパティ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100934/918afa12-5130-86c1-4900-2bcd1548de29.png)

##パターン2##
左のメニューに「ビルド」がなくて、「コンパイル」があるパターン
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100934/40296ee4-259c-70cb-abda-b44b5d5862ae.png)

右下にさりげなく「ビルドイベント」という項目があるのですが


**いや、分かりづらいわ！！！**

私は全く気づかなくて、他のところを探し回ってましたw

クリックすればちゃんと「ビルドイベント」が出てきます

![プロジェクト プロパティ2_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100934/191f2d01-d27b-d75f-fc4f-acafc0c19710.png)

#感想#
無事見つけられて良かったです(´∇｀)

イベントに.batを登録して、ビルド後にdllとかをコピーしてくれるようにしました
Mapped Types のキーの列挙

## ことの発端

```Mapped Types``` はとても便利で、個人的には ```typeorm``` の Entity と ```Generics``` の組み合わせは最高過ぎて失神するレベルです。
そんな ```Mapped Type``` ですが、たま～に、こいつのキーを列挙したいなんて事があります。

```ts
class A {};
class B {};
class C {};

type ABC = {
  A: A,
  B: B,
  C: C
};

console.log(Object.keys(ABC));
```

で、こんな結果になって欲しいと。

```js
["A", "B", "C"]
```

まぁ、 ```ABC``` は値じゃなくて型なので、 ```Object``` じゃない。
そして、 ```Object``` じゃないのに ```Object.key()``` なんて呼び出せる訳もない。
で、こんなエラーになります。

```
'ABC' only refers to a type, but is being used as a value here.
```

で、人によって色々な対応方法があると思うのですが、私の妥協案を記事にしようかと。
う～ん、大した話じゃなくて申し訳ないです。


## 妥協案

「型じゃだめなら値にする」という至極当然な妥協案です。


```ts
class A {};
class B {};
class C {};

type ABC = {
  A: A,
  B: B,
  C: C
};

const ABC_MAP: {[T in keyof ABC]: T} = {
  A: "A",
  B: "B",
  C: "C"
};

console.log(Object.keys(ABC_MAP));
```

型 ```ABC``` の定義と、値 ```ABC_MAP``` の定義が酷似しているので、何とかならんか試行錯誤するが、非力な私にはどうにもならないのでした。
まぁ、こいつを定義しておくと、後に ```ABC``` に新しい型を追加したら ```ABC_MAP``` がエラーするので、定義し忘れ的なのは無いので、今のところ不便はない。（けど、何とかならんかなぁ）

```ts
type ABC = {
  A: A,
  B: B,
  C: C,
  D: D /* <-- 追加 */
};

const ABC_MAP: {[T in keyof ABC]: T} = {
  A: "A",
  B: "B",
  C: "C"
  /* D: "D" を定義しないとエラー */
};
```

ちなみに、 ```ABC_MAP``` を使って ```ABC``` から型を取りだす際は ```typeof``` を忘れずに。

```ts
const hoge: ABC["A"] = {};
const hogehoge: ABC[typeof ABC_MAP.A] = {};
```

あ、どうでも良いですが、 ```keyof ABC``` が大量に登場するのもアレなので、こんな定義もよく書いたりします。

```ts
type ABC_NAME = keyof ABC;
/* ABC_NAME = "A" | "B" | "C" */
```
【VR空間サービス Spatial.io】 #6 Spatial3.0新機能

#サマリ
2021/4/1、Spatial3.0がリリースされました。
Spatial2.0がリリースされてから約１か月でのメジャーバージョンアップ。
勢いが感じられていいですね！

本家のリリースページはコチラ
→[Spatial3.0](https://support.spatial.io/hc/en-us/articles/360058972971-Spatial-3-0-Custom-Environments-Live-Translation-Spatial-Cast-More-)
![Spatial3.0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933978/d94b7bb3-cb3d-9a0b-409f-69b1abcea3cd.png)

##目次
1. Custom environments
1. Live translation
1. Spatial Cast
1. Guest mode
1. private rooms
1. Avatar customization
1. Share Selfie Pictures

##1. Custom environments
自分でアップロードした3Dオブジェクトを部屋として設定できるようになりました。
今まではデフォルトで用意されている部屋を使うか、何もない空間に3Dオブジェクトを置いて部屋を作るかしかできませんでしたが、自分のカスタマイズした部屋を作れるようになりました。
背景も360度画像を使って変えられるようになったので用途に応じた環境を作れるようになりましたね。
セミナーなんかもやりやすくなったのではないでしょうか。
アップロードできるファイルサイズには制限があるのでその点は要注意です。
→[Custom environments](https://support.spatial.io/hc/en-us/articles/360058728892)

##2. Live translation
翻訳機能が実装されました。70以上の言語に対応しているとのこと。
もちろん日本語も対応していますよ。
話した言葉が翻訳されて頭の上に表示されます。
Pro版のライセンスが必要ですが母国語が違う人とのミーティングにも使えますね！
→[Live translation](https://support.spatial.io/hc/en-us/articles/360059202851-Live-Translation)

##3. Spatial Cast
PC用の画面共有アプリが提供されました。現在はMac版だけですが、Win版も開発中とのこと。
今までもブラウザからログインして画面共有はできましたが、専用アプリになったことで以下の点が良くなっているようです。
　・PCで発生している音を共有できる
　・VR空間から画面共有したPCを操作できる(クリックのみ)
→[Spatial Cast](https://support.spatial.io/hc/en-us/articles/360058708732)

##4. Guest mode
アカウントがない状態からブラウザでSpatialルームに参加できるようになりました。
ちらっとブラウザから見たいという人をルームに誘うときに、事前にアカウント作ってもらうのって微妙にハードルなんですよね。
ブラウザからならノーアカウントで参加できるということでウェビナー的な使い方もやりやすくなりましたね。
→[Guest mode](https://support.spatial.io/hc/en-us/articles/360042150712)

##5. Private rooms
招待した人のみアクセスできるルームを作れるようになりました。
今までも部屋のURLを教えなければアクセスできなかったと思うのですが、URLは公開するけどアクセスできる人は限定したいというような場合でしょうか。
あまり使い道ないかな。。。
→[Private rooms](https://support.spatial.io/hc/en-us/articles/360058875692)

##6. Avatar customization
ついにアバターのカスタマイズが出来るようになった！
と喜んだのですが、Tシャツと肌の色を変えられるだけ。。。
Tシャツのテクスチャを指定できるとか、服装を選べるとかだったらよかったんだけど。。。
→[Avatar customization](https://support.spatial.io/hc/en-us/articles/360042244612)

##7. Share Selfie Pictures
自撮り棒で撮影した画像を自分またはルームにいる人に対してメール送信できるようになりました。
今までは自撮り棒で記念撮影しても画面キャプチャしないと画像を持ち出せなかったんですよね。
これは地味にうれしいです。
→[Share Selfie Pictures](https://support.spatial.io/hc/en-us/articles/360036072512)

#　
チームハイエナ <img width="120" alt="hyaeninae_tomei.png"  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933978/99b448d3-7ff0-58f3-302b-8528cf339b8d.png">
R言語でマクドナルドの業績をウォーターフォール可視化・library("waterfalls")

##waterfallsライブラリを使います

先日、9年ぶりに最高益を記録した[マクドナルドの損益計算書（PL）のウォーターフォール図を、**「ggplot2」と「geom_rect」**などを使い、作りました](https://qiita.com/text_owleyes_0214/items/86c2a72b5961b6456d54)。
矩形を描画して作る、という応用的な手段でした。

今回、専用の関数を使い、描画しました。
**waterfall関数**です。
[こちら](https://cran.r-project.org/web/packages/waterfalls/index.html)から仕様が入手できます。

```r
 install.packages("waterfalls")
```
インストールしました。
これで少ステップでウォーターフォール図を作成できます。

##可視化します

業績のデータフレーム 用意し、**waterfalls関数**に適用します。
前回とは違い、**"利益"**の値は指定しなくても描画可能です。
**calc_total=TRUE**と指定することで、収入と原価のプラスマイナスの結果は自動で計算・可視化してくれます。

```r
library("waterfalls")
pl_data2 <- data.frame(
    items = c("売上高", "売上原価", "販売費及び一般管理費", "営業外収益", "営業外費用", "特別利益", "特別損失", "法人税住民税及び事業税", "法人税等調整額"),
    amount = c(288332, -230075, -26966, 1421, -1286, 0, -870, -10140, -226),
    stringsAsFactors=F
)

options(scipen=100) #Y軸が指数表示になるのでそれを回避
theme_set( theme_bw(base_family = "HiraKakuProN-W3"))
waterfall(
    pl_data2, 
    calc_total=TRUE,  #「TRUE」で最終的な収支の差分を描画する
    total_axis_text = "当期純利益", #上記描画部分に配置する文字列
    total_rect_text_color="black", #同線の色
    total_rect_color="goldenrod1"  #同塗りつぶしの色
) 
```

<img width="700" alt="ウォーターフォール2_1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1143963/79146f10-f859-ec2f-d3d7-e83807a2f0a0.png">

前回と当期純利益の数字が微妙に異なります。
小数点を丸めた数字などが含まれているせいかもしれません。
x軸の文字のサイズを小さくしたかったのですが、その方法はわかりませんでした。
**ggplot2**の方が細かく設定できそうな感触はしました。

**了**
偏差値の計算をJavaScriptとPHPで書いてみた

## きっかけ

ゲームアプリ作ってるときに

「スコアの他に順位や偏差値とか表示したら嬉しくね？」

と思ったので実装しようとした😸

(追記)
JavaScriptの記事を書いたけど
サーバー側で処理したくてPHPで書き直したのでそのコードも載せておく(メソッド分割してない)😿

### 偏差値を求める

下記のスコアに対する偏差値を表示してみる

```js
// スコア一覧
[10, 30, 50, 70, 80, 100]
```

### プログラム(JavaScript)

```js
// 平均
const average = scores => scores.reduce((acc, current) => acc + current, 0) / scores.length

// 分散
const variance = (scores, avg) => scores.reduce((acc, current) => acc + Math.pow(current - avg, 2), 0) / scores.length

// 標準偏差
const standardDeviation = (scores, avg) => Math.sqrt(variance(scores, avg))

// 偏差値
const standardScore = (score, avg, sd) => (((score - avg) * 10) / sd) + 50

// スコア一覧
const scores = [10, 30, 50, 70, 80, 100]

// 偏差値の表示
const avg = average(scores)
const sd = standardDeviation(scores, avg)

scores.forEach((score, i) => console.log((i + 1) + "番目の偏差値: " + standardScore(score, avg, sd)))

```

### プログラム(PHP)

```php
$scores =  [10, 30, 50, 70, 80, 100];
$length = count($scores);
$average = array_sum($scores) / $length;

$sum = 0;
foreach ($scores as $score) {
    $sum += pow(abs($score - $average), 2);
}

foreach ($scores as $i => $score) {
    $standardScore = ($score - $average) / sqrt($sum / $length) * 10 + 50;
    echo ($i + 1) . "番目の偏差値: " . $standardScore . "\n";
}
```

### 結果

```:JavaScript
1番目の偏差値: 34.63300360144335
2番目の偏差値: 41.218859200824774
3番目の偏差値: 47.80471480020619
4番目の偏差値: 54.39057039958762
5番目の偏差値: 57.683498199278326
6番目の偏差値: 64.26935379865975
```

```:PHP
1番目の偏差値: 34.633003601443
2番目の偏差値: 41.218859200825
3番目の偏差値: 47.804714800206
4番目の偏差値: 54.390570399588
5番目の偏差値: 57.683498199278
6番目の偏差値: 64.26935379866
```

### 実際に使ってみた

https://emoshare.net/games/tap

![87FBFF9B-962B-44B3-A01A-08992DCC6219.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122701/15931e65-2416-647d-21b3-39964b5d944b.png)

正しく計算されてるっぽく見える❗️😸

### おわりに

ES6のナウい書き方にしてみた

アロー関数の省略記法で長くなったらどこで折り返しするんだろう...😹
(そもそも折り返したいような場合は省略せずに複数行書くべきなのかも)

あとゼロ除算の考慮とかしてないのでコピって使う場合は気を付けてね😽
kubernetesマニフェストを含むYeoman generatorを作るときのメモ

構成を考えるのを諦めた、ただのメモです。

generatorのひな型の作成方法
-----------------------

1. Node.js をインストールする。
1. yeoman をインストールする。

   ```text
   npm install -g yo
   ```
1. yeoman の generator-generator をインストールする。

   ```text
   npm install -g generator-generator
   ```

1. yeoman の generator-generator を使って、generator のひな型を作成する。

   ```text
   yo generator
   ```

   generator の名前を聞かれるので、適当に `generator-test-123456` などと答える。

開発中のテスト方法
----------------

generator のディレクトリで、 `npm link` と実行すると、
`yo test-123456` (入力した generator の名前) で実行できるようになる。

YAMLのテンプレート
------------

テンプレートの例

```yaml:test-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: test
  <%_ if (ownerLabelEnabled) { -%>
  labels:
    owner: <%= ownerLabel %>
  <%_ } -%>
```

- `<%_` : 前の空白を消す。これがないと、変な空白行ができる。
- `-%>` : 改行を消す。これがないと、変な空白行ができる。

テンプレートを書き込む例

```js:generators/app/index.js
  writing() {
    this.fs.copyTpl(
      this.templatePath('test'),
      this.destinationPath('test'),
      this.props
    );
  }
```

テンプレートパスはディレクトリを指定可能。
ただし、オプションによってファイル自体含めたくない場合は、
下記のようにファイル1個1個を指定していかないといけなそう。

```js:generators/app/index.js
  writing() {
    this.fs.copyTpl(
      this.templatePath('test/test-ns.yaml'),
      this.destinationPath('test/test-ns.yaml'),
      this.props
    );
    if (this.props.generateDefaultServiceAccount) {
      this.fs.copyTpl(
        this.templatePath('test/test-default-sa.yaml'),
        this.destinationPath('test/test-default-sa.yaml'),
        this.props
      );
    }
  }
```
C言語：構造体の渡し方(代入や引数への)


```c
struct person{
   int age;
   char *name;
} man;
```

構造体は、ポインタではない。
printfに構造体を渡すと、構造体の一番最初に定義されたメンバの値が出力される。(上記ではageの値)
なので、構造体へのポインタ型に構造体のポインタを渡すときは,下記のように普通の変数と同じようにアンパサンドをつける。


```c
struct person *i;

i = &man;
```

配列として構造体を宣言した場合は、配列が先頭のポインタを指すように、配列構造体も先頭のポインタを指すので、配列を渡すようにそのまま渡すことができる。
SynologyのDSMじゃなくてSRMでrsyncする

# Synologyのルーター
Synologyには[SRM](https://www.synology.com/ja-jp/srm)というルーターOSがある。
USBでストレージをつなげばNASにもなり、[DSM](https://www.synology.com/ja-jp/dsm)と同じようにSynologyのバックアップソフトも使える。
さらにsshも使える。これならrsyncでもバックアップできるのでは…(フラグ)

# 今回の環境
- クライアント
    - MacBook Air (M1)
    - macOS 11.2
- サーバー
    - MR2200ac
    - SRM 1.2

# DSMのrsync
[こちら](https://www.synology.com/ja-jp/knowledgebase/DSM/tutorial/Backup/How_to_back_up_Linux_computer_to_Synology_NAS)によると、DSMには`Enable rsync service`というメニューがあるとのこと。
SRMにはそもそも`rsync`というタブが無い。
がーん。

# SRMでsshを有効化
気を取り直し、`コントロールパネル->サービス->System Services->SSHサービスを有効化する`チェックボックスで、sshを有効化する。
`i`アイコンにマウスオーバーすると、ユーザーadminでしか使えなさそうなことが書かれている。
そこで、adminでログインし、rsyncを実行してみる。

```shell-session
ssh admin@srm.example.com
(中略)
srm> rsync --version
rsync  version 3.0.9  protocol version 30
```

使えそう。

# 外からrsyncしてみる
```shell-session
rsync -a hoge admin@srm.example.com:
(中略)
Permission denied, please try again.
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
```
だめ。`Permission denied`。

# 外からsshでrsyncを実行してみる
```shell-session
ssh admin@srm.example.com rsync
Permission denied, please try again.
```
同じ理由で実行できない。

```shell-session
ssh admin@srm.example.com ls
```
`ls`は`Permission denied`にならずに実行できる。
busyboxは実行できるということか。

# rsyncのパスを指定して外からrsyncしてみる
[こちら](https://qiita.com/tkykmw/items/7f1216088b789d0538fb)で`--rsync-path`というオプションの存在を知る。

まずはrsyncのパスを確認。

```shell-session
ssh admin@srm.example.com which rsync
/usr/syno/bin/rsync
```

rsyncのパスを指定。

```shell-session
rsync -a --rsync-path='/usr/syno/bin/rsync' hoge admin@srm.example.com:
Segmentation fault
rsync: connection unexpectedly closed (8 bytes received so far) [sender]
```
えっSEGV。でも`Permission denied`は出なくなった。
きっとこのオプションは必要ということだろう。

# 同期先をフルパス指定
まずは同期先を確認。

```shell-session
ssh admin@srm.example.com which pwd
/volumeUSB1/usbshare/@sharebin/homes/admin
```

同期先をフルパス指定。

```shell-session
rsync -a --rsync-path='/usr/syno/bin/rsync' hoge admin@srm.example.com:/volumeUSB1/usbshare/@sharebin/homes/admin
```

転送できたっぽい。
めでたしめでたし。

# 要因
未調査。

# TODO
- 公開鍵設定
Scikit-learn Diabetesデータセットを使ってみる

scikit-learnに、糖尿病患者のデータベースというのがある。

https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_diabetes.html

重回帰用のデータである。
ロードしてみる。。。

データはdataとtargetに分かれる。

diabetes.data
diabetes.target

<pre>
import numpy as np
import pandas as pd

from sklearn.datasets import load_diabetes

#X_feature_names = ['age', 'gender', 'body mass index', 'average blood pressure','bl_0','bl_1','bl_2','bl_3','bl_4','bl_5']

df = pd.DataFrame(diabetes.data, columns=("age", "gender", "boby mass index", "average blood pressure", "tc", "ldl", "hdl", "tch", "ltg", "glu"))
df['target'] = diabetes.target

df.head()
</pre>

data.targetだが、おそらくこれは血圧だと思われる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163445/15574252-26cc-d6d2-7a94-68d573c18b60.png)

サンプリングして表示してみる。。

<pre>
import matplotlib.pyplot as plt
plt.figure()
plt.subplot(211)
plt.plot(X)
plt.subplot(212)
</pre>

![ダウンロード (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163445/76420313-0eec-488f-a087-8acd0b94c1e8.png)

サンプリング（ヒストグラム）して表示してみる。。

<pre>
bins = 50*np.arange(8)
binned_y = np.digitize(y, bins)

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,stratify=binned_y)
</pre>


![ダウンロード (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163445/b5c242b9-8182-2435-09d7-1d35704b31a0.png)

https://github.com/RuoAndo/time-series-analysis-with-Python/blob/master/qiita/diabetes.ipynb
EPUBの濁点や半濁点について

　「あ゙」というのはライトノベルでよく使われる。ただ、これをEPUBで使おうとするとフォントが対応していないなどで表示されないことがある。

　そこでどのように表示するかについて考えてみよう。市販のEPUB作成機能がついたソフトウェアでどのように処理をされているのかを調べてみた。だが、そもそも対応している市販のソフトがあるのかよくわからなかった。

　あるところで調べると、画像を埋め込むなどが書かれていた。画像で埋め込むと白黒反転したときにその文字だけが画像だというのがバレる。背景が白で文字が黒であったならばばれないが。背景を黒にした途端、画像の部分だけ背景が白の文字が表示される。

- 縦中横を使って文字を並べて表示してはどうか。
- フォントを埋め込めがいいのだろうか。

などと考えて言えると、「フォントってライセンスどうなん？」というのも気になってくる。

改造版AozoraEpub3
https://github.com/kyukyunyorituryo/AozoraEpub3

改造版AozoraEpub3の表示テストの設定から[スタイル]-[濁点/半濁点文字]-[フォント]を選んだ状態の表示のテスト。

そのまま
```html
<p>あ゛あ゛あ゛あ゛</p>
<p>い゛い゛い゛い゛</p>
<p><span class="color-orangered">い゛</span></p>
<p><span class="color-orangered">●</span></p>
<p><br/></p>
```

ブックウォーカー
縦書きで表示すると濁点が下に表示されているのがわかる。結合文字の「あ゙」にしても分解されて表示される。
![2021-04-04_00h35_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186721/cff99929-c5a4-c24d-4e4e-5c82c9e31e10.png)


キンドルプレビュワー
ブックウォーカーと同様の表示
![2021-04-04_00h42_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186721/94da84a5-5891-04e3-7590-aa0a250c3512.png)

重ねる
「重ねる」というのは同じ位置に濁点と元の文字を重ねて表示するという意味なんだけど、重ねる位置がビュワーごとに異なるために同じ表示にすることが難しい。
```html
<p><span class="dakuten">あ<span>゛</span></span><span class="dakuten">あ<span>゛</span></span><span class="dakuten">あ<span>゛</span></span><span class="dakuten">あ<span>゛</span></span></p>
<p><span class="dakuten">い<span>゛</span></span><span class="dakuten">い<span>゛</span></span><span class="dakuten">い<span>゛</span></span><span class="dakuten">い<span>゛</span></span></p>
<p><span class="color-orangered"><span class="dakuten">い<span>゛</span></span></span></p>
```

ブックウォーカー
![2021-04-04_00h36_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186721/8cf45a4e-2640-1841-8104-25b0666d4574.png)
超縦書
![2021-04-04_00h46_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186721/ee9c6173-8a39-ead6-4375-56dee34a54ee.png)

フォント
　濁点のフォントを用意して、代わりに表示したら。一番思ったとおりに表示されました。
```html
<p><span class="glyph u3042-u3099">あ</span><span class="glyph u3042-u3099">あ</span><span class="glyph u3042-u3099">あ</span><span class="glyph u3042-u3099">あ</span></p>
<p><span class="glyph u3044-u3099">い</span><span class="glyph u3044-u3099">い</span><span class="glyph u3044-u3099">い</span><span class="glyph u3044-u3099">い</span></p>
<p><span class="color-orangered"><span class="glyph u3044-u3099">い</span></span></p>
```
ブックウォーカー
![2021-04-04_00h37_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186721/69c422d8-7bce-3e61-b90e-8e10eb4e357d.png)
for文


## 構文
```php
for (初期化式; 条件式; 増分式) {
    実行する文;
}
```

1.初期化式で変数宣言
2.条件式の評価結果がtrueなら次のステップへ、falseなら終了
3.実行する文を実行
4.増分式で変数を更新
5.(2)に戻る

```php
for(var i = 0; i <= 10; i++){
    console.log(i); //0~10を順番に出力
}
```
# 例文(配列)
```php
const arr = ["りんご","バナナ","みかん"];
console.log("配列の長さ: " + arr.length); //コンソール画面上に配列の長さを出力する
for(var i = 0; i < arr.length; i++) {　//arr.lengthで配列の長さの分だけループを実施する
    console.log(arr[i]); //コンソール画面上にarrのデータを出力する
}
```

# break
- ループ処理中に途中で抜け出したいとき

```php
const arr = [1,2,3,4,5,6,7,8,9,10];
for (var i = 0; i < arr.length; i++){
    if(arr[i] > 5){
        break;//for文から処理を抜ける。
    }
console.log(arr[i]);//1~5出力
}
```
Flutterのフォーム入力にはFlutter FormBuilderがオススメ

# 初めに

https://qiita.com/urbsny/items/3667167a800883033407

に関するTipsです。

# 本題
Flutter初心者として、Flutterでフォーム入力を実装する際に困りました。
公式のドキュメントはこのようになっていますが、

https://flutter.dev/docs/cookbook/forms/validation

今更emailバリデーションなど自分で実装したく無いしと感じ、
Submitエラーなど非同期のエラーをどのように反映するかも分かりませんでした。

Reactでいうredux-formやformikのような物が無いか色々なライブラリを検証した所、
「Flutter FormBuilder」が最高でした。日本語の記事を見かけなかったので紹介します。

https://pub.dev/packages/flutter_form_builder

公式のドキュメントにもある通り、通常のバリデーションは

```dart
             validator: FormBuilderValidators.compose([
                FormBuilderValidators.required(context),
                FormBuilderValidators.numeric(context),
                FormBuilderValidators.max(context, 70),
              ]),
```

をフィールドにセットするだけです。
必要なバリデーションが用意されているので嬉しいですね。

ただ、非同期のエラーを簡単に扱うのには少しコツがいるようです。

## Submitエラーの扱い方
サンプルの実装はこちらをご覧ください。

#### 共通コンポーネント
https://github.com/PaykeDeveloper/payke-hinagata-native/tree/main/lib/ui/widgets/atoms

- validate_form_state.dart
- validate_text_field.dart

※「atomicデザイン採用したいようだけど、間違っていない？」と思った方、勉強中ですのでご了承ください。

#### 各画面の実装
https://github.com/PaykeDeveloper/payke-hinagata-native/blob/main/lib/ui/screens/sample/projects/widgets/form.dart

### ポイント

非同期エラーの反映は公式では、このようになっています。

https://pub.dev/packages/flutter_form_builder#programmatically-inducing-an-error

が、私が実装したかった仕様にはマッチしませんでした。

1. フォームを再度入力した際に入力した項目の非同期エラーをリセットする。
1. 登録ボタンが押された際に、全ての非同期エラーを一旦リセットする。

を実現したかったのですが、
「登録ボタンが押された際に、全ての非同期エラーを一旦リセットする」という部分について、
公式の実装方法ではうまく行きませんでした。

バリデーション処理でerrorTextが設定されている場合、バリエーションが通らないように
ライブラリ側で制御されています。

https://github.com/danvick/flutter_form_builder/blob/207cf0711513e20f86a1aa9dd22a764b0432ad87/lib/src/form_builder_field.dart#L176

登録ボタン押下時にエラーをリセットし、バリデーションを再度実行するのですが、
widget内のerrorTextのリセットが同期されない（する方法が分からない）為、errorTextが残った状態になり、
１回目の登録ボタン押下ではバリデーションがエラー判定になってしまいました。（２回目は問題無い。）

そこで、errorTextを使わずに独自バリデーション処理を追加することでこの問題を解決しています。
以下、具体的な実装箇所になります。

https://github.com/PaykeDeveloper/payke-hinagata-native/blob/7076c1d230da21a4ea086ea7993e68821f50f8ea/lib/ui/widgets/atoms/validate_text_field.dart#L31


アプリの挙動は、こんな感じになります。

![Apr-04-2021 00-59-36.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621435/ce01ce58-0b79-0db9-3c72-a107c4183139.gif)


以上、よろしくお願い致します。
【Rails】error: failed to write new configuration file /home/ubuntu/.gitconfig.lock対処法

<h2></h2>
ターミナル起動時に下記エラーメッセージが表示されてしまいました。
環境はcloud9です。

```
error: failed to write new configuration file /home/ubuntu/.gitconfig.lock
┌──────────────────────────────────────────────────────────┐
│                 npm update check failed                  │
│           Try running with sudo or get access            │
│           to the local update config store via           │
│ sudo chown -R $USER:$(id -gn $USER) /home/ubuntu/.config │
```

翻訳すると
「エラー：新しい構成ファイル/home/ubuntu/.gitconfig.lockの書き込みに失敗しました」
「npm更新チェックに失敗しました。sudoで実行するか、経由でローカルアップデート設定ストアに│sudochown-R$ USER：$（id -gn $ USER）/home/ubuntu/.configアクセスしてみてください」

ファイルをopenしても該当のファイルが見つかりませんでした。

下記を入力しても、一時的に使えませんと表示されてしましました。

```
sudo chown -R $USER:$(id -gn $USER) /home/ubuntu/.config
sudo: unable to resolve host ip-172-31-36-46: Resource temporarily unavailable
```

エラーメッセージを検索すると、<a href="https://teratail.com/questions/286668">同様の事象</a>にぶち当たっているのを発見。回答を見ると、「cloud9 No space left on devicedで検索せよ」とのこと。
おそらく、本事象は容量がないから更新できないため、npm更新チェックに失敗するなどが発生していると推測。

<h2>解決方法</h2>
容量不足を解決する手立てが立たず、環境を立て直しました。。。
すると、上記エラーも表示されなくなったため、憶測通り容量不足が解消されれば本エラーも解消されるみたいです。


<h2>参考</h2>
AWSで起動時にエラーが発生しました。
https://teratail.com/questions/286668
【Android】apkのversionCodeだけ更新する方法

apkは作成済みで、あとはPlay Consoleにアップするだけなのに、versionCodeの更新を忘れていて再度apkを作り直さなきゃ…みたいな状況でversionCodeだけを更新する方法をご紹介。
（素直にapkを作り直すのが絶対にいいと思いますが、諸事情でソースコードがなく作り直せない、みたいなときに役立つかもしれません。）

# 0. Apktoolをインストールする
[Apktool](https://ibotpeaches.github.io/Apktool/install/)というのが必要になるので、事前準備としてインストールします。
Macの場合はHomebrewで入れるのが簡単だと思います。

```
$ brew install apktool
```

# 1. apkをデコードする
変更を加えたいapkをデコードします。

```
$ apktool d sample.apk -o tmp
```

↑では `-o tmp` で `tmp` フォルダにapkの中身が出力されるように指定しています。

実行してみると下記のように色々と出力されます。
![スクリーンショット 2021-04-03 23.34.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/30d2b1e8-fbd0-f8f6-3e6d-a3de95eb4341.png)

# 2. versionCodeを書き換える
本題のversionCodeの更新部分です。
先ほど出力された `tmp` フォルダに `apktool.yml` というファイルがあるので、それをエディタで開きます。
するとその中に、下記のように `versionCode` の記述があると思うので、それを書き換えます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/7d30dc99-5c23-308c-a38b-521b0c865b72.png" width=250 />

# 3. `tmp` をビルドしapkを生成する
書き換えが終わったら、再度apktoolを利用して、apkを生成します。

```
$ apktool b tmp
```
実行すると `tmp` フォルダに `dist` フォルダが生成され、中にapkが生成されます。（ `sample.apk` ）
![スクリーンショット 2021-04-03 23.44.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/c8f7f5dd-6f86-24c6-5f33-084c66615fe8.png)

# 4. apkに署名する
新しく生成されたapk（`tmp/dist/sample.apk`）に署名をします。

```
jarsigner -keystore sample.keystore -storepass SamplePass -keypass SampleKeyPass tmp/dist/sample.apk SampleKeyAliasName
```

# 5. zipalignを実行する

zipalignを実行しておきます。
（参考：https://developer.android.com/studio/command-line/zipalign?hl=ja ）

```
$ zipalign -v 4 tmp/dist/sample.apk sample-release.apk
```
実行すると `sample-release.apk` が生成されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/995/ca75f821-6f4f-e9fb-f3f3-b5819a44e02e.png" width=300 />

---

以上で作業は終わりで、versionCodeを更新したapkを生成することができました。

# 参考
- https://gist.github.com/benvium/5923d50c30ab7c7df0f3
Udemy メモ「【はむ式】React Hooks 入門 - HooksとReduxを組み合わせて最新のフロントエンド状態管理手法を習得」

Typescript でやってみた

https://www.udemy.com/course/react-hooks-101/


### セクション３終了
状態管理を useContext 使用
https://github.com/masayuki-0319/ham-react-hooks-101/tree/study/study_useContext_for_state_management

### セクション4終了
諦めたorz
S3を静的WEBサイトにしてバケットポリシーで限定公開にする

## バケット作成
マネージメントコンソールからS3を選択し、**バケットの作成**を押下する。
※一意のバケット名にする必要がある
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032344/3f5b5e17-530d-38f9-e998-3c7f9d417176.png)



## 静的ウェブホスティングに設定
作成したバケットを選択し、**プロパティ**タブから一番下の「静的ウェブホスティング」を編集する。
「有効にする」「静的ウェブサイトをホストする」を選択し、変更を保存する。
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032344/1cacaec6-1f83-605f-5812-922996f61641.png)
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032344/96c0de54-818a-1232-f53b-a9b08aab5e6d.png)


## アクセス許可設定
**アクセス許可**タブを押下し、「パブリックアクセスをすべてブロック」の☑を外し、「現在の設定により、このバケットとバケット内のオブジェクトが公開される可能性があることを承認します」に☑を入れる。
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032344/ba9fc0fe-58e4-4503-5ebf-11601d9ba9bc.png)

バケットポリシーの欄にJSON形式で記述する。
今回の例ではSourceIPが27.142.108.157以外からは、バケット名「test-20210403」に対してS3に関するアクションを全て拒否するという内容。

```
{
    "Version": "2012-10-17",
    "Id": "SourceIP",
    "Statement": [
        {
            "Sid": "SourceIP",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::test-20210403",
                "arn:aws:s3:::test-20210403/*"
            ],
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": "27.142.108.157/32"
                }
            }
        }
    ]
}
```
OSとは

OSは、Operating System（オペレーティングシステム）を省略した言葉です。
和訳すると「操作するためのシステム」 となります。
OSの仕事は端末全体を管理、そして、制御することです。
上記の内容は「OSとは」など検索した場合によく見る内容だと思います。
私は正直言って上記の内容だけではOSを理解できませんでした。。。
現状、少しは理解できたと思うので私なりに噛み砕いて共有していきたいと思います。

#OSとは
上記の様に、OSとは「操作するためのシステム」です。
今使われているパソコン、スマホなどはこのOSが無いと動くことが出来ません。
OSが入っていない場合は
・電源ボタンを押しても電源が入らない
・キーボード、マウスを操作しても何も起こらない
上記の様に何も出来ない状態になってしまいます。
OSはハードとソフトの全てを管理して私たちが分かりやすく使いやすい様にしてくれています。
なので、OSが無いパソコンはただの箱になってしまいます。

#OSの種類
OSには種類があり、多くの方はOSと聞いたら、Windows,Macを思い浮かべるかも知れません。
みなさんが使われているパソコンのほとんどが上記のOSが入っていると思われます。
でも実際にはもっと多くのOSの種類がありパソコンだけではなくスマホにも入っているOSもあります。
代表的なOSを挙げさせて頂きます。
##Windows
Microsoft社が開発したOSです。
市販されているパソコンを購入すると大概はインストールされています。
そのためOSはWindowsしか知らないという方も多いと思われます。
##macOS
Apple社が開発したOSです。
Apple社はパソコンも作っていて、Appleが作っているパソコンにはmacOSが入っています。
グラフィックが優れているのでデザイン系の仕事方はmacOSを使っている方が多いと思われます。
##ios
こちらもApple社が開発したOSです。
macOSがパソコンといったコンピュータ用なのに対し、iOSはその他のAppleの機器用に使用されています。
例えば、iPodやiPhoneやiPadなどです。
Apple製品でしか使えません。
##Android
Google社が開発したOSです。
Apple社のiOSと違い、他の企業の端末でも使用できることからスマホでのシェアが爆発的に広がりました。
スマホだけではなく、カーナビや車そのものや、メガネなどにも搭載されてきています。
##Linux
誰でも無料で使えるOSです。