OmniAICreator/Qiita-1.07M huggingface dataset:
[メモ] Postman の OAuth 1.0a ヘルパーの encoding でまたハマる (pre-request script で回避)


少し前に Runscope でも同じ問題に遭遇し、同様に Pre-request Scripts で回避する記事を書きました。
https://qiita.com/jrsyo/items/0fc6cc85e1af49dfbe21

今回はその Postman client 版です。よって説明はだいぶ省略しています。

## Issue
概要は下記の issue の内容の通りです。
https://github.com/twitterdev/postman-twitter-ads-api/issues/2

Runscope と同様、POST の場合は代わりにリクエストボディを使うことで Postman でも回避できましたが、リクエストボディを使わない GET などの場合は Pre-request Script での対応が必要でした。

## Pre-request Script (Postman)

下記に置いてます。これを対象のリクエストの Pre-request Script にまるっと貼り付けて使います (+ 当該リクエストの `Authorization` TYPE を Inherit => `No Auth` に変更)。
https://github.com/twitterdev/postman-twitter-ads-api/blob/master/scripts/pre-request.js

Runscope よりもデフォルトで使えるライブラリが限られていたので少し冗長になってます。
参考: [Postman Sandbox | Commonly used libraries and utilities
](https://learning.getpostman.com/docs/postman/scripts/postman_sandbox/)

### その他 Postman pre-request script について

今回 Postman client の pre-request script を初めて利用しましたが、ドキュメントに記載がない独自の専用メソッドやそのオプションが多数あり、これらを使うことで面倒な処理を減らすことができました。
参考までに、下記の Postman Collection SDK のドキュメントが結構役に立ちました。
https://www.postmanlabs.com/postman-collection/index.html

上記のドキュメントは Node.js の SDK モジュールをベースに説明していますが、一部の Class は Postman client 単体からもアクセスが可能です。

意外だったのは、Postman では最近まで (prior to v7.0.9) pre-request を使った request header の改変が出来なかったようで、最新バージョンでは

```js
pm.request.headers.add()
pm.request.headers.upsert()
pm.request.headers.remove()
```

を使って自由に request header を変更出来るようになっています。
参考: [Cannot add headers with pm.request.headers.add #4631
](https://github.com/postmanlabs/postman-app-support/issues/4631)

今回は少なくとも `Authorization: ` header を追加する必要があったため、上記の修正なしでは成り立ちません。

#### 便利系

下記は現在定義されている Postman の Environment 変数一覧をオブジェクト形式で受け取る例です。
`excludeDisabled: true` を使うことで、disable になっている変数を除外することができます。
`pm.environment.get("variable_key")` で個別に値を取得することも可能ですが、毎回内部 API コールを行うよりは予めこのようにまとめて取得しておいた方がよいでしょう。

```js
const env_variables = pm.environment.toObject({
    excludeDisabled: true
});
```

下記は現在リクエストに定義されている `Query Params` 一覧を受け取る例です。
前述同様、`excludeDisabled: true` を使うことで、disable になっているパラメーターを除外することができます。通常リクエストの params には required/optional 両方のパラメーターが混在していることが多いため、このオプションはとても役に立ちます。

\* ただし受け取る値は単なる String なので、それぞれの parameter に何か処理を加えたい場合、SDK を読み込んで `QueryParam.parse()` を使うことで Array 形式で parameter を受け取れます (Array の各 index に paramter が `key: パラメータ名`, `value: パラメータ値` の object が入っている)。

```js
// 単純に query parameter を string で受け取る
const query_string = pm.request.url.getQueryString({
    ignoreDisabled: true
});

// query parameter を Array で受け取る
const sdk = require('postman-collection');
// https://www.postmanlabs.com/postman-collection/QueryParam.html#.parse
const query_string_array = sdk.QueryParam.parse(
    pm.request.url.getQueryString({
        ignoreDisabled: true
    })
);

```

その他にも、`pm.request.*` 系は頻繁に使われる定番系メソッドだと思います。リクエストの情報を取得(e.g., `pm.request.method`)するだけでなく、上書きも可能です (e.g., `pm.request.url`)。

## 宣伝
ということで、Twitter Ads API の Postman Collection を最近公開しました。下記からインポートできます。
https://github.com/twitterdev/postman-twitter-ads-api
DRFのGeneric viewの使い方

公式サイトを見るとGeneric viewのクラスがいくつもあって、
どれをどのように使うのか迷ったので整理しました。

参考：[公式サイト](https://www.django-rest-framework.org/api-guide/generic-views/)

##概要
いくつかクラスがあるのですが、

| クラス | 操作 | 
|:-----------------|:------------------|
| CreateAPIView | 登録（POST） |
| ListAPIView | 一覧取得（GET） |
| RetrieveAPIView | 取得（GET） |
| UpdateAPIView | 更新（PUT、PATCH） |
| DestroyAPIView | 削除（DELETE） |
を押されておけば大丈夫かと。

他のクラスは、上記クラスを組み合わせたクラスになります。
HTTPのリクエスト メソッドで役割を切り替えます。
**ListCreateAPIView** （POST、GET） = ListAPIView + CreateAPIView
**RetrieveUpdateAPIView**（GET、PUT、PATCH） = RetrieveAPIView + UpdateAPIView
**RetrieveDestroyAPIView**（GET、DELETE） = RetrieveAPIView + RetrieveDestroyAPIView
**RetrieveUpdateDestroyAPIView**（GET、PUT、PATCH） = RetrieveAPIView + UpdateAPIView + DestroyAPIView

##実装
ざっくり書くと、どのクラスを使う場合も、

```python:views.py
class [適当なクラス名](generics.[上記の使いたいクラス]):
    queryset = モデル.objects.all()
    serializer_class = モデルのSerializer
```
```python:urls.py
path('api/v1/books/<str:pk>/', views.[適当なクラス名].as_view(), name='detail'),
```
でいけます。
urls.pyの**`<str:pk>`**は、str型のプライマリーキーを、取得や更新の条件にするという意味で、
int型だったら**`<int:pk>`**になります。
プライマリーキー以外使う場合は、使いたいカラム名で、
`<int:カラム名>`とし、views.pyに
`lookup_field = 'カラム名'`
を追加します。

##サンプルプログラム
```python:views.py
from rest_framework import generics
from shop.models import Book
from .serializers import BookSerializer

class BookList(generics.ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

class BookRetrieve(generics.RetrieveAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
#    lookup_field = 'price'

class BookRetrieveUpdate(generics.RetrieveUpdateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
#    lookup_field = 'price'

class BookUpdate(generics.UpdateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    lookup_field = 'price'

class BookDestroy(generics.DestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
```

```python:urls.py
from django.urls import path, include
from rest_framework import routers
from apiv1.views.model_view import BookList

from . import views

urlpatterns = [
    path('api/v1/books/', views.model_view.BookList.as_view()),
    path('api/v1/books_retrieve/<str:pk>/', views.model_view.BookRetrieve.as_view(), name='detail'),
    path('api/v1/books_retrieve_update/<str:pk>/', views.model_view.BookRetrieveUpdate.as_view(), name='detail'),
    path('api/v1/books_update/<str:price>/', views.model_view.BookUpdate.as_view(), name='detail'),
    path('api/v1/books_destory/<str:pk>/', views.model_view.BookDestroy.as_view(), name='detail'),
]
```
プログラミング講習（仮）03

# プログラミング講習（仮）03
##目的
勉強したい人の支援

##内容
固定長配列
自作関数
プロトタイプ宣言
再帰関数

## パスカルの三角形関数
``` prex03a.c
#include <stdio.h>
#define NUM 8

void fx_pascal(int [NUM]);

void main()
{
	int arr [NUM] = {};

	fx_pascal(arr);
}

void fx_pascal(int inp[NUM])
{
	int i;
	int narr [NUM] = {};
	narr[0]++;

	for (i = 1; i < NUM; i++)
		narr[i] = inp[i] + inp[i - 1];

	for (i = 0; i < NUM; i++)
		printf("%2d ", narr[i]);
	printf("\n");
}
```
```
$./prex03a
 1  0  0  0  0  0  0  0 
```

## パスカルの三角形（再帰関数）
``` prex03b.c
#include <stdio.h>
#define NUM 8

void fx_repascal(int [NUM], int);

void main()
{
	int arr [NUM] = {};

	fx_repascal(arr, NUM - 1);
}

void fx_repascal(int inp[NUM], int cnt)
{
	int i;
	int narr [NUM] = {};
	narr[0]++;

	for (i = 1; i < NUM; i++)
		narr[i] = inp[i] + inp[i - 1];

	for (i = 0; i < NUM; i++)
		printf("%2d ", narr[i]);
	printf("\n");

	if (0 < cnt)
		fx_repascal(narr, cnt - 1);
}
```
```
$./prex03b               
 1  0  0  0  0  0  0  0 
 1  1  0  0  0  0  0  0 
 1  2  1  0  0  0  0  0 
 1  3  3  1  0  0  0  0 
 1  4  6  4  1  0  0  0 
 1  5 10 10  5  1  0  0 
 1  6 15 20 15  6  1  0 
 1  7 21 35 35 21  7  1 
```

## おまけ
```
$./prex03c               
                 1
               1   1
             1   2   1
           1   3   3   1
         1   4   6   4   1
       1   5  10  10   5   1
     1   6  15  20  15   6   1
   1   7  21  35  35  21   7   1
```
tmuxを使えるようにする

##tmuxのインストール
homebrewでインストールしました。

```:
$ brew install tmux
```

##.tmux.confの設定
tmuxは.tmux.confをいじることにより設定を変えることができます。
また、tmuxからコピーしたものをmacのクリップボードに移すために必要なreattach-to-user-namespaceをインストールします。

```:
$ brew install reattach-to-user-namespace
```

プラグインマネージャーであるtpmをインストールします。

```:
$ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
```


以下は現在自分が使っている```.tmux.conf```

```:.tmux.conf
# tmux起動時のシェルをzshにする
set-option -g default-shell /usr/local/bin/zsh

# tmuxを256色表示できるようにする
set-option -g default-terminal screen-256color
set -g terminal-overrides 'xterm:colors=256'

# prefixキーをC-qに変更
set -g prefix C-q

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

# ステータスバーをトップに配置する
set-option -g status-position top

# 左右のステータスバーの長さを決定する 
set-option -g status-left-length 90
set-option -g status-right-length 90

# #P => ペイン番号
# 最左に表示
set-option -g status-left '#H:[#P]'

# Wi-Fi、バッテリー残量、現在時刻
# 最右に表示
set -g status-right '#{battery_status_bg} Batt: #{battery_icon} #{battery_percentage} #{battery_remain} | %a %h-%d %H:%M '

# ステータスバーを1秒毎に描画し直す
set-option -g status-interval 1

# センタライズ（主にウィンドウ番号など）
set-option -g status-justify centre

# ステータスバーの色を設定する
set-option -g status-bg "colour238"

# status line の文字色を指定する。
set-option -g status-fg "colour255"

# vimのキーバインドでペインを移動する
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

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

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

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

# 番号基準値を変更
set-option -g base-index 1

# マウス操作を有効にする
set-option -g mouse on
bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e'"


set -g @tpm_plugins '              \
  tmux-plugins/tpm                 \
  tmux-plugins/tmux-yank           \
  tmux-plugins/tmux-open           \
  tmux-plugins/tmux-resurrect      \
  tmux-plugins/tmux-battery        \
  tmux-plugins/tmux-pain-control   \
'

run-shell '~/.tmux/plugins/tpm/tpm'
```
QUERY関数で「月ごと」に集計したい

(追記 2020/10/24)
[QUERY関数で「年月ごと」に集計したい](https://qiita.com/sakaimo/items/3ba584afee391c2ff7d1) の記事のほうがニーズに合うかもしれません。

----------

GoogleスプレッドシートのQUERY関数をつかって、「月ごと」に集計したいケースに出会ったのですが、ちと戸惑ったので自分メモ。わかってれば何でもないのだろうけれども。

# やりたいこと

こんな表があったとして
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/fcff9a17-4656-985b-5d7d-9125cfee748f.png)


↓ これを出したい
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/7d48219e-b76a-d619-a343-fec6c4ac7d6e.png)


# やったこと

```
=QUERY($A$1:$B,"
  select month(A)+1, sum(B) 
  where A is not null 
  group by month(A)+1
", true)
```
ってやると↓こうなる
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/347bb177-df9c-dcb3-e51b-4de7ff073cda.png)

※コメントいただいたように、`month(A)+1`する理由は、**Query関数のmonth関数はゼロベースでのカウント**(0が1月。1が2月)なので、`month(5)` は 4月を表します。


ラベルを付けたいのでこうする↓

```
=QUERY($A$1:$B,"
  select month(A)+1, sum(B) 
  where A is not null 
  group by month(A)+1 
  label month(A)+1 '月', sum(B) '合計'
", true)
```

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8612/69b798bb-661b-ac34-b19e-b06a2b491499.png)


うん。QUERY関数楽しい。(もっとスマートな書き方があったら教えて！)
まとめ　injection　とmodelまとめ


ページネーションを使いつつ
groupby を使うには
一度、SQL側でView を作らないといけない。

Elquentを使うには
modelを使わないと行けないということで、

手順としては
make:migraytion＜SQLテーブル名＞　　<-何故か最後にSをつけないといけない
viwのコードを書き
make:model ＜モデル名＞
コントローラーで
use app/hogehoge
を書いてから使う

これで集計したデータは取れるが、コード順になっているので
blade側ではそれ以外を撮ってくる

blade側は

```
@injection('metrics','App\Services\MetricsService')
⌇
{{$metrics-> productName($product->seq_variation_id)}}
```

コントローラー側では、

```
use Illuminate\Support\Facades\DB;
use App\products;
use Illuminate\Http\Request;

class MetricsService
{
    public function productName($id)
    {
        $list = products::where('id',$id)->get();
        foreach ($list as $items){
            $item = $items->productName;
        }
        return $item;
    }

}

```
puppeteerを使いChromeでルーターの管理画面にアクセスし、ルーターを再起動をする

最近ネットの速度が遅いことがあり、ルーターを再起動してIPアドレスが変わるとしばらくは状況が改善するような事があるので、せっかく自宅のPCを24時間起動しっぱなしにしてるので、寝てる間にでも定期的にルーターを再起動するようにしようという話です。

# 前提
- OS: Ubuntu 19.04
- Node.js: v10.16.0
- npm: 6.9.0
- ルーター: [NetGenesis GiagLink1000](https://www.mrl.co.jp/support/gl1000/index.html)
    - IPアドレス: 192.168.0.1
- WiFi: [Aterm WG1200HS](http://www.aterm.jp/support/wg1200hs/index.html)
    - IPアドレス: 192.168.0.211

WiFiの方は今回は触れません。

# 準備
## Node.jsのインストール
まずこれがないと話にならないのでインストールします。
「ubuntu node」なんかでググると[こちら](https://qiita.com/seibe/items/36cef7df85fe2cefa3ea)の記事が出てくるので、参考にします。
npmで-gオプションを付けなかったので、nのインストールおよびnを使用したnodeのインストールは以下のようになりました。

```
$ npm install n  
$ sudo ./node_modules/.bin/n stable
```
PATHを通すために.zshrcに以下を記載します。
(bashの人とかは適宜必要なファイルに記載する)

```
if [ -d ${HOME}/node_modules/.bin ]; then
    export PATH=${HOME}/node_modules/.bin:${PATH}
fi
```

## puppeteerのインストール
npmでインストールします。

```
npm install puppeteer
```

これで準備が整いました。

# 実装
さっそくソース全体行っちゃいます。

```javascript:router-reboot-chrome.js
const fs = require('fs').promises;
const puppeteer = require('puppeteer');

const url = 'http://192.168.0.1/';

(async() => {
    const browser = await puppeteer.launch({headless:true, slowMo: 10, executablePath:'/usr/bin/google-chrome'});
    const page = await browser.newPage();
    await page.setViewport({width:1280, height:800});

    try {
        const userName = 'LOGIN_NAME';
        const password = 'LOGIN_PASS';
        await page.authenticate({username:userName, password:password});
        await page.goto(url);

        const indexFrame = page.frames().find(frame => frame.name() === 'INDEX');
        await indexFrame.waitForSelector('body > div > table > tbody > tr:nth-child(1) > td > table > tbody > tr:nth-child(23) > td > a');
        indexFrame.click('body > div > table > tbody > tr:nth-child(1) > td > table > tbody > tr:nth-child(23) > td > a');

        const pagesFrame = page.frames().find(frame => frame.name() === 'PAGES');
        await pagesFrame.waitForSelector('body > center > form > nobr > input[type="SUBMIT"]');
        pagesFrame.click('body > center > form > nobr > input[type="SUBMIT"]');

        await page.waitFor(200);

    } catch(e) {
        console.log(e);
    }
    browser.close();
})();

```

注意点(？)
1. puppeteer.launchのオプションでheadlessをどうするか指定しておく
2. 操作を行う箇所をtry{}catch(){}する

デフォルトでも `puppeteer.launch` のオプションに `headless` を指定しなければ `headless:true` となるようですが、開発中はむしろブラウザの挙動が見えている方が良いので `headless:false` としておきます。

`try{}catch(){}` に関しましては、`waitFor` 等、で例外が投げられる場合にcatchできないとブラウザを閉じられないので、 `browser.close()` をその外側に書いて終了するようにします。

これであとは以下を実行し、無事にルーターが再起動されたらcronに登録して定期的に再起動するようにしてやります。

```
$ node const browser = router-reboot-chrome.js
```

# 参考ページ
- https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md
- https://helloworld-blog.tech/javascript/puppeteer%E3%81%A7basic%E8%AA%8D%E8%A8%BC%E3%82%92%E7%AA%81%E7%A0%B4%E3%81%99%E3%82%8B
Quest便利ツールやコマンド、Tips等

ほぼ自分用です。
便利なコマンドやツールのメモ。

「こんな便利なツールあるよ！」などあれば、ぜひコメントや編集リクエストを。

## Unityでのデバッグに便利

#### LogCatWindow.cs

Unity上でAndroidのLogCatを表示するやつ。


https://gist.github.com/kleusbalut/fe557073f5f97515b01a59387f5822ef

baba-sさんが追記されていた分をgistに上げました
※Unity 2018.2.21で動作確認済み。


参照元: http://baba-s.hatenablog.com/entry/2018/12/27/085000
元スクリプト: https://github.com/dzonatan/Unity3D-LogCat-extension

## adb関連

#### adb経由の画面プレビュー(Vysor代替)

**scrcpy**

無料でイケてる。無料。
遅延少ない。画面最大化時にVysorのような変な警告出ない。
apkインストール不要。
録画もできる。すごい。

https://github.com/Genymobile/scrcpy

解説: [Oculus Quest の映像をテレビに映したりキャプチャする方法 - 4. scrcpy を使う](https://qiita.com/Tomoyuki_Mikami/items/183be9b0698ee00f7fac#4-scrcpy-%E3%82%92%E4%BD%BF%E3%81%86)
解説: [【低遅延・高画質】scrcpy+adbでOculusQuestのプレイ画面をMacにミラーリングする方法](https://note.mu/masaki_ponpoko/n/nc759f6499c79)

#### Questでブラウザを開く

`adb shell am start {開きたいURL}`

参照元: https://twitter.com/antungame/status/1135377229146337285

## Tips

#### ビルド時に"Compiling shader variants"でめちゃくちゃ時間がかかる問題 

##### Oculus Integration起因

Oculus Goと同じで、`Assets/Oculus/Avatar` と `Assets/Oculus/SampleFramework` を削除すると軽くなる。
Oculus Avatar用のシェーダーのコンパイルにめちゃくちゃ時間がかかっている。

参照元: https://twitter.com/gunsturn_tw/status/1134700211673001984

##### その他のシェーダー(Standardなど)

Unity 2018.2.21を使用して発生している。
Unity 2019.3で修正とあるものの、2018.2.21を使いたいのでワークアラウンドするしかない。
既知の問題ぽい。世界中から悲鳴が聞こえる。
なぜか日本語で言及しているものがあまりヒットしない。

悲鳴1: [BUILDING PROJECT GETS STUCK ON "COMPILING SHADER VARIANTS" DIALOG WHEN LIGHTWEIGHT RENDER PIPELINE/LIT SHADER IS COMPILING](https://issuetracker.unity3d.com/issues/building-project-gets-stuck-on-compiling-shader-variants-dialog-when-lightweight-render-pipeline-slash-lit-shader-is-compiling)
悲鳴2: [Compiling Shader Variants Taking Ages](https://forum.unity.com/threads/compiling-shader-variants-taking-ages.527724/)

#### ゲーム/アプリのプレイ後に充電されない問題

前面パネルが熱くなっている状態、温度が43℃以上だと充電されない模様。
参照元: https://joytokey.net/ja/blog/vr/oculus-quest-does-not-charge/


#### PCとUSB接続してもQuestのファイルシステムが見えない

開発者モードがONになっていると、MTPモードでアクセスできない。
`adb pull`等のコマンドで取得するか、いったんOFFに。
完全に素人ですがプログラミングに興味があります🤣

自分で自分のやりたい事を実現出来る時代。
![person-731479_640.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430334/a07b163d-b037-f391-6a2a-5096141a5aec.jpeg)
昨日までなかった物がドンドン世に出てくる物は全てプログラミングで成り立ってるのではないか？
https://ryujin.site/ryukyuokinawa
API Connect のアセンブルでGatewayScript処理を共通化

# はじめに

API ConnectではAPI毎にパス等の設定や動作(アセンブル)を定義します。
アセンブルでは、ポリシーを1個以上配置し、APIの動作を定義しますが、
GatewayScriptポリシーというJavaScriptライクな言語で処理を実装可能なポリシーが存在します。

今回は、複数のGatewayScriptポリシーで、似たような処理を実装するんだけど、どうやって共通化するんだけっけ？　みたいなお悩みにお答えする記事になっています。

# 環境

IBM CloudのAPI Connectサービスで動作確認しています。

# アセンブル定義

今回、下図のアセンブルを定義しました。
このAPIでは、get/trimとget/trim2 の２パスの処理を定義しています。
赤枠のtrim body、trim body２が処理を共通化したいGatewayScriptポリシーです。
![assemble.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/15c5dc1c-5704-6cc8-d849-9ee6209ec46d.png)

# GatewayScript(共通化前)

今回のtrim bodyおよびtrim2 bodyには、例として、「APIレスポンスのトリム処理」を実装します。

```javascript

// get http body
var httpBody = apim.getvariable('message.body');

// trim 
Object.keys(httpBody).forEach(function(key) {
  var value = httpBody[key];
  if (typeof(value) == 'string') {
    httpBody[key] = value.replace(/ +$/g, '');
  }
});

// set http body
apim.setvariable('message.body', httpBody);
```

# プロパティー

さて、このトリム処理を共通化するためには、どうすればよいでしょうか？
答えの一つがプロパティーを利用する方法です。

プロパティーとは固定値をなど定義し、アセンブルから参照させる場合によく利用します。
ここでは、共通化したい処理を関数として定義してしまいます。
図、右下の値フィールドに、コードを記述します。
![property.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/5a8f5a7d-bc86-0d4d-24b7-f2d3e4484f92.png)

ただ、設計ビューでは、コーディングしづらいので、ソースビューを利用することをお勧めします。
今回は、「trimFunction」というプロパティー名で無名関数としてトリム処理を定義しています。
![source.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/6340cc91-710e-242a-2751-9940b0c24189.png)


# GatewayScript(共通化後)

プロパティーを利用したGatewayScriptポリシーのコーディングは、以下の通りです。
$(trimFunction)で、プロパティーから関数を取得しています。

```javascript

// get http body
var httpBody = apim.getvariable('message.body');

// trim
var trimFunction = $(trimFunction);
trimFunction(httpBody);

// set http body
apim.setvariable('message.body', httpBody);

```

# 最後に

今回は、プロパティーに共通化したい処理を関数として定義し、複数のGatewayScriptポリシーで利用する方法をご紹介しました。

GatewayScriptを利用するシーンとしては、アクセスログを出力するケースが挙げられます。
アクセスログは、開始時、終了時の２個所で出力しますが、それらの処理を共通化する場合に今回の方法が利用できます。
Railsのflashメッセージに改行を入れ左寄せする方法

レスポンシブなwebサービスを作成していると、長文メッセージをPC版だけでなく、mobile版の画面でも表示しなければならない場面が出てくる。特に、flash[:notice]を利用する際に対応が発生する方が多いのではないだろうか。

flash[:notice]に設定するdevise用ymlメッセージの改行設定を行う際、一瞬、deviseをoverrideしないといけないのではないか？と対応方法の検討に戸惑ったので、備忘的な意味も込めて対応方法を簡単にまとめてみた。

~~~Ruby:config/locales/other/devise.ja.yml(必要箇所のみ抜粋)
ja:
  devise:
    confirmations:
      send_instructions: '確認メールを、登録したメールアドレス宛に再送しました。<br>メールに記載されたリンクを開いてアカウントを有効にして下さい。'
~~~

~~~Ruby:view側の記述
<% flash.each do |type, msg| %>
  <div class="flash flash--<%= type %><%= ' flash-notice--long-sentence' if msg.include?('<br>') %>">
    <span class="flash__text"><%= msg.html_safe %></span>
  </div>
<% end %>
~~~

~~~Ruby:css(scss)の記述
.flash-notice--long-sentence {
  text-align: left;
}
~~~

表示メッセージに`.html_safe`を記述し、メッセージ内に改行タグ`<br>`が存在した時は、調整用のclassを表示するという方法である。

PC版と改行箇所が同じになってしまうというデメリットもあるが、上記のように対応すると、対応工数がほとんどかからず、シンプルな実装になる。

ymlファイルに記述した文言の改行をしたい場合など応用が効きそうな方法なので、同じような場面に遭遇したらテクニックの１つとして活用していきたいと思う。
エルボー法（k-meansの最適なクラスタ数の推定法）を実装してみた（scikit-learn使用）

代表的な非階層型クラスタリング手法としてk-meansが知られています。

k-meansは構築するクラスタ数`k`を入力として与える必要がありますが、最適な`k`の値は試行錯誤しながら探す必要があります。

この`k`を自動推定するための手法としてエルボー法という手法があります。

# k-means法とは
与えられたデータをk個のクラスタに分割する比階層的クラスタリング手法です。

k-meansの動作イメージは以下のページがものすごくわかりやすいです。
[K-means 法を D3.js でビジュアライズしてみた](http://tech.nitoyon.com/ja/blog/2013/11/07/k-means/)

k-meansのイメージは↑のような感じですが、数学的には以下の式を最小化する問題として定式化することができます。

```math
\sum_{i=1}^{k}\sum_{p\in C_{i}}(p-c_{i})^2
```
ここで、$k$はクラスタ数、$C_{i}$は$i$番目のクラスタに含まれるデータ点集合、$c_{i}$は$C_{i}$の重心です。

また、この値は[SSE(Sum of Squared errors of prediction)](https://ja.wikipedia.org/wiki/%E6%AE%8B%E5%B7%AE%E5%B9%B3%E6%96%B9%E5%92%8C)と呼ばれます。

# エルボー法とは
エルボー法では、クラスタ数を変えながら上記の[SSE](https://ja.wikipedia.org/wiki/%E6%AE%8B%E5%B7%AE%E5%B9%B3%E6%96%B9%E5%92%8C)を計算し、結果を図示することで最適（と思われる）クラスタ数を推定する手法です。

クラスタ数を変えながらSSEを計算し図示することで、例えば以下のようなグラフになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245628/b152fc47-f69a-81a0-2e3b-3b4a40e0701f.png)

横軸にクラスタ数、縦軸にSSEを図示すると、肘（エルボー）のようにポキっと曲がった場所があることがわかります。
上記の例ではクラスタ数=4の点でグラフがポキっと曲がっていますね。

エルボー法ではこのような点を見つけることで最適な（と思われる）クラスタ数を推定します。

# `sklearn.cluster.KMeans`
[scikit-learnのk-means用のクラス](https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html)を調べると、以下のような記述があります。

> Attributes:
> inertia_ : float
> Sum of squared distances of samples to their closest cluster center.

そうです。
この値を使えば一発でSSEにアクセスできます。

# ソースコード
全文は[ここ](https://github.com/takecx/MachineLearning/blob/master/Clustering/kMeans_Elbow.ipynb)に置いています(jupyter notebook)。
今回は私の理解のために、上記の`inertia_`を使って算出したSSEを別の方法でも算出して間違いがないか確認しました。
実際にエルボー法でSSEを計算しているのは以下の部分です。

```python
# エルボー法で最適なクラスタ数を探索する
sse = np.zeros((max_cluster_num,))     # Sum of Square Error（クラスタ内誤差平方和）
se = np.zeros((max_cluster_num,))      # Sum of Error（クラスタ内誤差和）
inertia = np.zeros((max_cluster_num,)) # scikit-learnにより自動計算するクラスタ内誤差平方和
for i in range(max_cluster_num):
    cluster_num = i + 1
    kmeans = KMeans(n_clusters=cluster_num)
    # 各データがどのクラスタに所属するか
    pred = kmeans.fit_predict(data_array)
    inertia[i] = kmeans.inertia_
    
    # 各データが自身の所属するクラスタ中心からどれだけ離れているか調べる
    transforms = kmeans.transform(data_array)    
    distances = np.zeros((data_array.shape[0]))
    for index in range(len(transforms)):
        distances[index] = transforms[index,pred[index]]
    
    se[i] = np.sum(distances)
    sse[i] = np.sum(distances**2)
```

# 結果
今回使用したデータは以下の２次元データです。
正規分布で適当なパラメータを指定して５クラスタになるようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245628/7374de6b-7e32-36ce-7b01-7c61f0fbb1ec.png)

SSEを計算して図示した結果がこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245628/7e265395-07fd-a487-2565-7e8f1d9904b9.png)

クラスタ４のあたりでポキっと折れてますね。
今回の場合は実際にはクラスタ数５が正解なのですが、分析するデータが２次元（もしくは３次元）で可視化可能なことは稀だと思います。
データがどういう形をしているのかわからないという前提で考えればクラスタ数４という推定はまぁまぁ良い結果では無いでしょうか。

最適だろうと推定したクラスタ数プラマイ１ずつ（３、４、５）の結果を図示してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245628/67d0a3b4-a67c-dba3-fc4d-dd5aafcbb681.png)

並べてみるとクラスタ数５が最適なことは明確ですが、クラスタ数３の結果とクラスタ数４の結果を比べるとなんとなく今回の結果になったことも納得できる気がします。

間違いなどあったらぜひご指摘ください。
ログイン時にtmuxを自動起動したい！

# 概要

sshでログインしたとき、いちいち`tmux -u2`って打つのが面倒だし、もしもセッションが残ってたら自動でそれに`tmux attach`して欲しい、面倒くさがりな欲張りさん向けです。

`.bash_profile`もしくは`.bashrc`に以下のコードを追記して下さい。

# code

```bash:.bashrc
alias tmux="tmux -u2"

# tmuxの自動起動
count=`ps aux | grep tmux | grep -v grep | wc -l`
if test $count -eq 0; then
    echo `tmux`
elif test $count -eq 1; then
    echo `tmux a`
fi
```

## やっていること

`$count`には、現在起動中のtmuxプロセス数が入ります。なので、以下の条件で各状態を判断出来るはずです。

- `$count = 0`なら`tmux`は起動していないはずなので、`tmux -u2`で`tmux`を起動します。
- `$count = 1`なら`tmux`のセッション自体は起動しているものの、ユーザは`tmux`へと`attach`していないはずです。
- `$count > 1`なら、ユーザはすでに`atattch`しているので、これ以上の処理はしません。新しい`pane`作るたびに`.bashrc`は読み込まれるので、無限に`atattch`してしまうのを防ぐためです。
自動販売機を作ってみよう part6 - DB設計 答え合わせ編1

前回の記事の最後に載せた、勘違いER図を元に、何がいけなかったか考えてみる![ss_er01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318674/345f4972-0a75-4cd7-8dbf-6d50b36def55.png)

まず、オブジェクト的な思考にはなっているのでそれはオッケーと師匠から言われた。
(ホッとしたものの、本人としては全然ダメな気がしている…)

### どう直すべきか

- パーツはページごとに持たなくていい。
- 同じ名前のデータは作らなくていい

実はデータベース上では 「購入した」履歴さえ残せればよい
メインとなるデータは以下の二つ

- 購入履歴
- 商品リスト

この二つさえあれば完成するのである。
#### データとして保持したいものはどれ？
#### カスタマイズしたい場所はどこ？
簡潔に、重複せずにに組める最強の方法を考えろ！


### 重要！種別の共通化をできるだけ行う。
決まり切った項目は一個のテーブルとしてマスターにできるのである！！
つまり、タイプ(温度、素材etc)は別テーブルにする。

### 忘れちゃいけない、各テーブルに入れたいもの
あと、フレームワークにもよるが、必ず入れるべき情報がある。

- update_at
- created_at
- deleted_at

この三つは必ず入れておく。
ただし、改ざんを防ぐために、もしもこの3つの情報を表示、参照などさせたい場合は別にデータをつくっておくこと。


以上を踏まえて、次回、実際にER図を書き換えてみますよ！
【VFXGraph】冷気っぽいエフェクトを作ってみた

# はじめに
冷気のようなエフェクトをUnity2019のVFXGraph(Visual Effect Graph)で作成してみました。
![mist.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/3a008070-f193-0451-c9af-f659cb460345.gif)

今回はこのエフェクトを紹介したいと思います。

# 環境
Unity2019.2.0a9
Windows 10

High Definition Render Pipeline - Version 6.7.1 (Preview)
Visual Effect Graph - Version 6.7.1 (preview)

# VFXGraph全体
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/b2a6b1ce-1ca8-d891-479c-6cca234b5755.png)

# VFXGraphの解説
VFXGraphは以下のような構成になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/27f519c6-f863-0ca5-54fd-c6176aa23dbb.png)

## Spawn(パーティクル生成部分)
Spawnノードには24を指定して、毎秒24個のパーティクルが生成されるようにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/0c252e45-c3a3-2e43-5e34-a208793f7051.png)

## Initialize(パーティクル初期化)部分
パーティクルの初期化部分では、パーティクルの初期位置・速度・回転速度・寿命の設定を行っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/5b688651-d34f-b7f9-ec80-02785d96896d.png)

## Update(毎フレーム更新)部分
毎フレーム更新部分には、経過時間(Life)に応じたサイズ変化を設定しました。
Set Scale over Lifeには0~1のサイズ変化を定義し、下流のMultiply Scaleで全体的な大きさをコントロールしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/a23f9e4d-0aad-e862-93ed-3c6b3ab7ff02.png)

## Output(描画)部分
Quad Outputノードでパーティクルの描画を行っています。、
Main Textureの部分には[霧テクスチャ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/9dd178ca-1eed-595f-1c58-1b49d6dab1bc.png)を設定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/ca361c3d-6657-553e-2d3b-552587fa6863.png)

# 補足 : 霧テクスチャの作り方
今回の[霧テクスチャ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/9dd178ca-1eed-595f-1c58-1b49d6dab1bc.png)はSubstance Designerで作成しました。
Clouds2ノイズとGaussianパターンをBlend(Multiply)で合成して作っています。
<img src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44288/37aad441-71db-2dd7-71aa-962999bcfb9e.png">
知識ゼロから学ぶ ソフトウェアテスト(2章 ソフトウェアテストの基本 -ホワイトボックステスト-)

知識整理のために投稿しています。
本は `知識ゼロから学ぶ ソフトウェアテスト[改訂版]`です。
テストってなかなか書けない。

## ホワイトボックステストの特徴

- プログラムの**論理構造**が正しいかテストする
- ソフトウェアの**仕様**が間違っていることによるバグは発見できない

## ホワイトボックステストの手法

### 制御パステスト法

  - プログラムの振る舞い、制御、実行の流れをテストする
  - カバレッジ率を取るために使われる


- ステートメントカバレッジ

  - コード内の命令文(ステートメント)を必ず1回は実行する
  - 分岐はテストしない
  - 非常に弱いテスト手法


- ブランチカバレッジ
  - 分岐に対するTRUE / FALSEの結果を必ず1回ずつ持つようにする
  - テストコードがかなり増える
  - **バグが起きやすい部分にだけ**絞って行うことが多い


### カバレッジ基準

- 一般の商用ソフトウェアなら`60~90%`
  - ソフトウェアの種類によって変わる(命に関わるものは当然高くなる)
- **製品によって妥当な目標を適切に設定すべき**

### カバレッジテストの限界

- エラー処理 / 使われていないコードはカバーできない
- 以下のバグは検出が困難
  - プログラムのループに関するバグ
  - 仕様自体が違っていたり機能が備わっていないバグ
  - データに関するバグ
  - タイミングに関するバグ
    - マルチタスク/ 割り込みなど

## TDDによるホワイトボックステストの復権

- 赤・緑・リファクター
- 単体テストができるように**フレームワークを選定する**必要がある
- 「単体テストをやっている暇はない」という言い訳を無くせる
- 確実な品質保証 <<< **スピード**を持った開発 & 変更に対する**耐性**
  - TDDではホワイトボックステストの一部しか実現できない
Windows 環境で Docker を使って LAMP (P は Perl)する

## 背景
* ありものを使ってお手軽に LAMP(erl)環境が作れないかを試した結果のまとめ

## Docker for Windows をセットアップする
* https://docs.docker.com/docker-for-windows/install/

## LAP(Linux/Apache/Perl) コンテナを作る
* https://github.com/pclinger/docker-apache-perl
  * c:/www フォルダはあらかじめ作成しておく
  * フォルダマウント時に Docker から許可/認証(ひっそりと窓が出るので注意)をする必要がある
    * 前回うまくいっているのにエラーが出る場合は、Docker for Windows の Settings で Reset credentials をする
  * Port 80が既に使われていると言われたらぐぐって何とかする
    * 私の場合は BrancheCache が Port 80 を使っていたので一時的に止めた
* 動作確認
  * C:/www に cgi を置いて確認する
    * http://localhost/hoge.cgi

``` hoge.cgi
#!/usr/bin/perl

print "Content-type: text/html\n\n";
print "Perl Programming";
exit;
```
## M(MySQL) コンテナを作る

``` 
$ docker pull mysql
$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=mysql -d -p 3306:3306 mysql

コンテナに接続して IP アドレスを確認する
$ docker ps 
$ docker exec -it コンテナID bash
# cat /etc/hosts
名前がコンテナ ID の IP アドレスを控えておく
```

## LAMP 全体の動作を確認する
* C:/www に cgi を置いて確認する
  * http://localhost/mysql.cgi

``` mysql.cgi
#!/usr/bin/perl

use DBI;

my $dsn = "dbi:mysql:database=information_schema;host=[MySQL コンテナの IP アドレス];port=3306";

my $user = "root";
my $pass = "mysql";

my $dbh = DBI->connect( $dsn, $user, $pass, {
    AutoCommit => 1,
    PrintError => 0,
    RaiseError => 1,
    ShowErrorStatement => 1,
    AutoInactiveDestroy => 1
})|| die $DBI::errstr;

print "Content-type: text/html\n\n";

my $sth = $dbh->prepare("SELECT * FROM engines");
$sth->execute();
while (my $ref = $sth->fetchrow_hashref()) {
    print "Found a row: engine = $ref->{'ENGINE'}, comment = $ref->{'COMMENT'}<br>";
}
$sth->finish();

$dbh->disconnect();

exit;
```

## 感想
* ありものを使うことにすると細かいところで手作業が発生する
  * Dockerfile や Docker Compose を自分で書いて複数のコンテナを管理するなどしたほうが、長い目で見ると幸せな感じがしました (当たり前)
Ansible検証用環境を構築する（Docker,VirtualBox）

Ansibleの検証のため、ローカルPCに仮想環境を構築した時のメモ

# 流行りのDockerで簡単に構築できるスクリプト作成しました！
厳密な検証にはならないですが、こちらのほうが簡単です。
手順はgithubのreadmeのほうに記載してますので参照していただければ :pray: 

https://github.com/naonex/test-ansible

# 以下はVirtualBox版手順
## VirtualBoxインストール
仮想化ソフトはVirtualBoxを使用する
インストールはGUIで簡単にできるので割愛...

### VirtualBox内に複数の仮想環境作成（CentOS6）
CentOSの公式サイトからインストール媒体をダウンロードし、それを使用してVirtualBox内に仮想環境を作成する
こちらもGUIで簡単にできるので省略させてもらいます...

以下からが本題です

## 作成した仮想環境にホストオンリーネットワークを設定する
対象ゲストOSが電源オフの状態でホストオンリーアダプタを割り当てる
![WS003500.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386520/4c1c527e-cfaa-1b53-f083-1df0ec7ec81c.jpeg)

※アダプター2に割り当てること。また、この際に自動で振られたMACアドレスは後で使用します

ゲストOSを起動し、ネットワークアダプタが追加されていることを確認

```
ip addr
```

※特にいじってなければeth1として追加されているはず

### CentOS6のネットワーク設定を行う
以下のパスへ移動し、下の画像のように設定ファイルを修正＆作成する
`/etc/sysconfig/network-scripts/`
![WS003501 (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386520/acadb0c3-5763-ffb0-a4fb-93f7fadda108.jpeg)

* 最初から存在するifcfg-eth0（NAT）は、ゲストOSで外部ネットワークに接続する時に使用（yum実行時など）  
  また、ONBOOT設定をyesにしておくことで、起動時に自動でネットワークが有効になる
* ifcfg-eth1のMACアドレスは前工程で確認したものを設定  
  IPアドレスは192.168.56.0 or 2~99までの値を設定（ホストオンリーネットワークがデフォルト設定の時）

設定を反映させるためネットワーク再起動

```
service network restart
```

上記の設定を2台以上行う
（またはクローンして設定変更で作成 https://qiita.com/naonex/items/42bb5ee98afd9bdcfdc1）

## Ansible検証編
Ansibleをインストールする

```bash
# epelリポジトリから取得する
yum install epel-release

yum install ansible
# ※最新版をインストールしたい時はepel-testingから
yum install ansible --enablerepo=epel-testing
```

仮想マシン同士で鍵設定を行った後、ansibleの疎通確認コマンドを実行してみる
（鍵設定について詳しく記載すると脱線するので割愛。鍵設定せずにパスワードで接続することもできます）

```bash
# ローカル仮想マシン１（192.168.56.11）から、ローカル仮想マシン２へ（192.168.56.12）
ansible all -i 192.168.56.12, -m ping
```

無事に接続できれば完了
仮想マシンなので壊れても作り直せばいいし、簡単に新品用意してテストとかできるので上手く使いこなそう
もくじ

### はじめに

Qiitaに記事を書いていくうえで、自分用のwikiっぽく使いたいという思いがあり、そういえば数年前に読んだ[パターン、Wiki、XP ―― 時を超えた創造の原則 WEB+DB PRESS plus](https://www.amazon.co.jp/dp/B07JJN5NBY/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1) に「ブログとwikiの違いは、そんなになくって使い方次第で、ブログもwikiとして使えるし、逆も然り」のような記述が書いてあったな..と思ったので、この記事を自分のrootとして、記事を書いていきたいと思います。

なお、最初は手元にあるメモを書き写したり、書きたいことを書いておいて、徐々に校正や記事追加をかけていくスタイルでいくつもりです。

### アイコンについて
📝: 下書き（Qiita的には限定公開という設定なので、一応見れます）
🗑: 削除予定

---

### 技術系
- 設計
    - ソフトウェア設計
        - 📝[オブジェクト指向設計カタログ in Ruby](https://qiita.com/shirofune9876/private/5241f46f3a332c62253d)
        - 📝オブジェクト指向設計の指針
        - デザインパターン
        - リファクタリング
        - Rails
            - Rubyのメトリクス系gem
            - サービスクラスを辞めて、ConcernとPOROを使って、インターフェースを改善する
    - 仕様設計
        - DesignDoc
        - 業務フロー図
        - ER図
- React
- Ruby
    - [RubyとRailsの情報収集をする](https://qiita.com/shirofune9876/items/de334b9c892dc5f61737)
    - 小技
        - [Rubyで2つの変数を入れ替える](https://qiita.com/shirofune9876/items/cf74bcebc456ef240c40)
        - [Rubyのメソッド定義位置や「こんなメソッドないかな？」を調べる方法](https://qiita.com/shirofune9876/items/211fc54f09f356c85afd)
    - Ruby Silver & Gold
    - RSpec
- DB
- Docker
- k8s
- Git
    - [Gitのコミットテンプレートとrebaseを使って、開発ログを見やすくしたい](https://qiita.com/shirofune9876/items/0093630b2f928e4601bf)
    - [先に実装が終わってしまったコードにGitを使ってテストコードを書く](https://qiita.com/shirofune9876/items/6d1e441fe2cb7dc4dc41)
    - .gitmodules
    - .gitignore
- OSX / Setting


### プロジェクト運営系 
- 見積りと実績が合わないときにするべきこと
- 残業を減らす方法
- チームのみんなで目標達成する方法
- チームビルディングの方法
- プロジェクトを２つ同時にマネジメントする
- プロジェクトを横断的に管理する

### その他
- [Web+DB vol.110 の感想](https://qiita.com/shirofune9876/private/e027b8ab46af6b9f043a) 
- [「下書き→限定公開→Qiitaに投稿」でURLがどう変わるかを見る
](https://qiita.com/shirofune9876/items/7485b68b20f6c2897821)
- [Macの便利なショートカット](https://qiita.com/shirofune9876/private/74d009bf4296ac06a91c)
JavaScriptでimageに、y=sinxの動きをさせるシューティングゲームを作成しました。

#はじめに
JavaScriptでシューティングゲームを作成しました。
目標(星の画像）にy=sinxの動きをさせる事が出来たので、投稿しました。
<img width="1507" alt="スクリーンショット 2019-06-04 16.43.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427892/83182dac-1af0-90d1-d200-ee79374b34ff.png">
[リンクはこちら](http://take619.xsrv.jp/shootingStarGame/index.html)
#苦労した点
imageにy=sinxの動きをさせるに少し手間取りました。

#改善したい点
setIntervalでモーションをつけているのですが、clearIntervalをしても（おそらくclearIntervalの挿入位置が悪い）、２回目以降は目標物が止まらなくなる点と、clearInterval出来ていないので２回目以降は衝突判定が効かない点。

#imageにy=sinxの動きをどうやってつけたか
```javascript
//imageOfStarにsinθの動きをさせる
  movingxStar = 1;
  positionxOfStar += movingxStar;
  movingyStar = Math.sin(positionxOfStar*Math.PI/180);
  positionyOfStar += movingyStar;
  document.getElementById("imageOfStar").style.left = positionxOfStar + "px";
  document.getElementById("imageOfStar").style.top = positionyOfStar + "px";
```
まず、動かしたいimageにidをセットしてsetInterval()で、上記のコードを繰り返し処理させます。
movingxStarは、setIntervalでの単位時間あたりのx軸方向での動かしたい移動量を書きます。上記ではmovingxStar = 1;となっていますが、movingxStar = 5と記述すると、単位時間あたりに5px動くようになります。私は、出来るだけ滑らかなモーションを実現したかった為、movingxStar = 1；としました。
positionxOfStarとpositionyOfStarは、移動量ではなく、その時におけるimageOfStar（画像）のx軸位置、y軸位置を表しています。
positionxOfStarをif文で判定することによって、画面上のどの位置まできたら、〜の処理をしたい、などを実装することが出来ます。
もし全てのコードを見たい、という方がいらっしゃった場合、上記のリンクからとんで頂けば見れると思います。
機械学習初心者の私に告ぐ「4つの忠告」

# 1.はじめに
業務で機械学習を使用することが決まり、約3ヶ月前から機械学習の勉強を始めました。
私自身理系大学出身であったため、数式も多少調べればわかるだろう程度に考えていました。
しかし、勉強すればするほど自分の考えが甘かったことに気づきました。

この記事では、当時私が実際にやってしまっていた思い込みへの忠告を書いていきます。
これから機械学習の勉強を始める方々の参考になれば幸いです。

# 2.4つの忠告
以下4つが機械学習初心者の頃の私へ送る忠告です。
・ディープラーニングだけじゃ機械学習は網羅できない
・学習モデルのことだけではなく、全体像を見る必要がある。
・データ前処理はすぐには終わらない。むしろ機械学習は前処理が8割。
・評価方法は正解率だけではない。

それぞれ詳細について書いていきます。

## 2-1.ディープラーニングだけじゃ機械学習は網羅できない
機械学習＝ディープラーニングというイメージは
機械学習の勉強を始めた人にありがちだと思います。

私が最初に手に取った書籍もオライリーの「[ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/dp/4873117585)」でした。

![pasted image 0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329544/8d35cd05-e28b-a986-77b8-65d4a11bffdd.jpeg)


この書籍を一通り勉強し、「これで機械学習いけるで！」と意気込んでいましたが、
蓋を開けてみると、機械学習はディープラーニングだけではありませんでした。
ディープラーニング以外にもSVMや決定木ベースのモデルなどなど複数の学習モデルが存在しています。
以下の記事を読んでいた際に気づきました。
https://qiita.com/tomomoto/items/b3fd1ec7f9b68ab6dfe2




## 2-2.学習モデルのことだけではなく、全体像を見る必要がある
ディープラーニング以外にも学習モデルが複数種類があることを知った私は、
どの学習モデルが最適なのかを知るために、各モデルについて調査し始めました。
しかし、調査を進めても機械学習全体像をうまくつかめていなかったため、
どのタイミングでなんの処理をする必要があるのか理解できませんでした。

機械学習の全体像は以下図の通りです。

![pasted image 0-2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329544/61bf5890-6608-dd5d-ec38-2d24e84ce9ef.jpeg)
  図.機械学習の全体像


## 2-3.データ前処理はすぐには終わらない。むしろ機械学習は前処理が8割
全体像を掴み、調査を進めていると「前処理が8割」という言葉をよく見かけるようになりました。
この言葉を見た瞬間は、正直半信半疑でした。

しかし、実務をやり始めるとこの言葉の通り、「欠損値をどう埋めるか」や
「他の特徴量を生成した方がいいのでは」、「どの特徴量を使うべきか」などなど
ほとんどの時間が前処理に費やす時間でした。

ちなみにデータの前処理では以下のようなことをやっています。
・欠損値処理
・カテゴリーデータ処理
・特徴量の変換
・ランダムフォレストを用いて特徴量にアクセスする
・次元削除

## 2-4.モデルの評価方法は正解率だけではない
データ前処理をしモデル学習をさせた後、モデルを評価する必要があります。
この評価方法も正解率だけではなく、適合率や再現率という評価方法がありました。
また汎化性能を測るためにクロスバリデーションという手法も頻繁に使用されています。

評価方法の式について以下簡易的にまとめておきます。
詳細を知りたい方は、以下サイトを参考にしてください。
https://qiita.com/tf-gane/items/31483cc4365eca287d24

|  |1 |0 |
|---|---|---|
|1|TP|FN|
|0|FP|TN|
(横軸：予測値、縦軸：実測値)


正解率：

```math
 \frac{(TP+TN)}{(TP+TN+FP+FN)}
```

適合率：

```math
 \frac{TP}{(TP+FP)}
```

再現率：

```math
 \frac{TP}{(TP+FN)}
```


# 3.まとめ
学習開始当時に私がしてきた機械学習の思い込みについての忠告をまとめました。
実際にまだまだ知らないことだらけで勉強不足だと痛感する日々です。
やっと全体がつかめてきたので、今後はKaggleにも積極的にチャレンジしていこうと思います。

不足点等あればご指摘いただけると幸いです。


参考文献
・[ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/dp/4873117585)
・[[第2版]Python 機械学習プログラミング 達人データサイエンティストによる理論と実践](https://www.amazon.co.jp/dp/4295003379)
・代表的な機械学習手法一覧
(https://qiita.com/tomomoto/items/b3fd1ec7f9b68ab6dfe2)
・機械学習の評価指標を簡単にまとめてみた
(https://qiita.com/tf-gane/items/31483cc4365eca287d24)
Gitのお作法～失敗談を添えて～

#ファイルやディレクトリ名を変更、移動、削除する
ローカルのファイルをエクスプローラーでリネームしたら、git で差分として認識されなかった。
**しかも、以後そのファイルをgitが追跡できなくなった。**

→ファイルのリネーム、削除はgitのコマンドで行う。

ファイルの削除
`$ git rm <file>`
ファイルの移動、リネーム
`$ git mv <oldfilename> <newfilename>`

#変更したファイルを元に戻す
Laravelで過去のマイグレーションファイルをいじるのはNGというルールを忘れ、いじってしまった。そのうえgitを導入しているにもかかわらず、またそのファイルを手で書き換えて元に戻した。結果、正確に元の状態に戻っていないことに。。。

→gitで過去のコミットを打ち消すことでファイルを元の状態に戻す。

**コミットの打ち消しとは？？**
特定コミットの処理を、うち消すコミットを作成する。コミットログとしては、誤ったコミットとそれを打ち消すためのコミットの2つが残る。過去の履歴を書き換えないので、安全に取り消しが行える。

`$ git revert <打ち消すコミットID>`

＜メモ＞
git revert をするとき、お尻から revert しないとコンフリクトが発生した。git revert --abortでrevert自体の取り消しをして、お尻からrevertをして解決。
Cloud Source RepositoriesをCloud SDK抜きのSSH認証で使う

https://cloud.google.com/source-repositories/docs/authentication

の通り。ベータ版らしい。Cloud Source Repositories特有の手順や問題は特にない。リポジトリを作ったら

```shell
ssh-keygen -t rsa -C "${USER_EMAIL}" -f ~/.ssh/id_rsa_google
```
みたいに鍵を生成して

https://source.cloud.google.com/user/ssh_keys
からid_rsa_google.pubの中身を登録して

```shell
Host source.developers.google.com
 HostName source.developers.google.com
 Port 2022
 IdentityFile ~/.ssh/id_rsa_google
```
みたいにssh config書いて


```shell
git remote add google ssh://${USER_EMAIL}@source.developers.google.com:2022/p/${PROJECT_ID}/r/${RESPOSITORY_NAME}
```
ローカルリポジトリにremoteとして追加して(空リポジトリの場合はコピペ用コマンドがリポジトリ管理画面に表示される)
![スクリーンショット 2019-06-04 16.39.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47823/e67e86b7-af3d-401d-b473-47b6351c7c42.png)
(唯一のremoteなら別に"google"じゃなく"origin"でもいいと思う)

```shell
git push --all google
```
すればok
プライオリティーキューで昇順ソートする方法

```cpp
  priority_queue<pair<cpp_int,cpp_int>,vector<pair<cpp_int,cpp_int>>,greater<pair<cpp_int,cpp_int>>>q;
```

第二引数には第一引数の型のvector、第三引数には第一引数の型のgreaterを指定します。
【PHP】内閣府の国民の祝日csvを3行で処理する

少し前、Twitter 等で[内閣府の国民の祝日csvが酷いという話が話題になりました](https://www.google.co.jp/search?q=%E5%86%85%E9%96%A3%E5%BA%9C+%E5%9B%BD%E6%B0%91%E3%81%AE%E7%A5%9D%E6%97%A5+csv+%E9%85%B7%E3%81%84&ie=UTF-8)が、今ではとてもプログラマに優しいフォーマットになってますので、PHP を使って 3 行で処理してみます。

--------------------------------------------------------------------------------

## コード

```php
//-- csvを取得
$csv = file_get_contents('https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv');

//-- UTF8へ変換
$csv = mb_convert_encoding($csv, 'UTF-8', 'SJIS-win');

//-- 正規表現で抜き出す
if (!preg_match_all('/(\d{4})\/(\d{1,2})\/(\d{1,2}),(.+)/u', $csv, $matchAllAry, PREG_SET_ORDER)) {
	die('Error');
}
```

コメントまで含めると 10 行になっちゃってますが、コード的には実質 3 行です。

--------------------------------------------------------------------------------

## この後どうするの？

`preg_match_all()` の第 4 引数に `PREG_SET_ORDER` を渡す事により、`$matchAllAry` は `foreach` で処理しやすい配列になっていますので…


### 配列にしてみるとか…

```php
$holidayAry = [];

foreach ($matchAllAry as $matchAry) {
	list( , $year, $month, $day, $name) = $matchAry;

	$tmpAry = [
		$year,
		sprintf('%02d', $month),
		sprintf('%02d', $day),
	];

	$holidayAry[$year][implode('/', $tmpAry)] = trim($name);

	//-- 場合によってはこんな配列にしてしまうとか
	// $holidayAry[(int) $year][(int) $month][(int) $day] = trim($name);
}

print_r($holidayAry);

//-- serialize()して保存すれば、簡単に配列として再利用する事もできます
file_put_contents('./holiday.array', serialize($holidayAry));
print_r(unserialize(file_get_contents('./holiday.array')));
```


### フォーマットを変換してみるとか…

```php
$tsv = '';

foreach ($matchAllAry as $matchAry) {
	list( , $year, $month, $day, $name) = $matchAry;

	$tmpAry = [
		$year,
		sprintf('%02d', $month),
		sprintf('%02d', $day),
		trim($name),
	];

	$tsv .= implode("\t", $tmpAry) . "\n";
}

echo $tsv;
```

初心者の方は、祝日に対応した万年カレンダー辺りを作ってみたら、色々と勉強になるのではないでしょうか。

--------------------------------------------------------------------------------

### 余談

1. 祝日のデータを○○の形式に変換したものが欲しい
1. なにか csv でも無いかな？とググる
1. PHP でコードを書いて実行

今回のような処理なら、↓のような環境を作っておけば、ほんの数分で欲しい結果が得られます。

- [PHP・Ruby・Perl等のスクリプト言語をサクっと書いてサクっと実行\(EmEditor編\) \- Qiita](https://qiita.com/fallout/items/0d4f221e176d6521091f)

こういう「手軽さ」も、スクリプト言語の良いところですので、IDE とは別に環境を用意しておくと、何かと便利ですよ。

なお、これまで「正規表現を使うのは最終手段した方が良いです」と何度か書いていますが、今回のように「その場で欲しい結果がサクっと得られさえすればそれで OK」というケースなら、正規表現でも別に良いと思います。

使い分けが大事ですね。
ROS2インストール・初期設定 for Dashing Diademata

[ROS2関係トップページへ](https://qiita.com/NeK/items/7ac0f4ec10d51dbca084)
Dashing Diademata用
Crystal Clemmys用は[こちら](https://qiita.com/NeK/items/819631b2178da12f49ca)


# Ubuntu 18.04
[install]:https://index.ros.org/doc/ros2/Installation/
[公式インストールガイド][install]のDebian Packagesに従ってインストール．

## 特記
### localeについて
説明ではen_US.UTF-8だが，ja_JP.UTF-8に置き換えてインストール．

### Install ROS2 packages
[公式インストールガイド][install]のDebian packagesにて[Install ROS2 packages](https://index.ros.org/doc/ros2/Installation/Dashing/Linux-Install-Debians/#install-ros-2-packages)でインストールするものを選択しないといけないが，以下のように選ぶ．

- Ubuntu Desktop 18.04
    - Desktop Install(Recommended)
- Ubuntu Server 18.04
    - ROS-Base Install(Bare Bones)

Ubuntu Server 18.04は，例えば[Raspberry Pi 3B+](https://qiita.com/NeK/items/849c6d1e05fb05314fc6)でロボットを制御する場合(GUIが不必要な場合)での使用が考えられる．

### 上記ガイド以外でインストールしたもの

```Bash:terminal
$ sudo apt install ros-dashing-rqt*
$ sudo apt install python3-colcon-common-extensions
$ sudo apt install python-catkin-pkg python-bloom
$ sudo apt install python-pip python3-pip
$ sudo -H pip install -U catkin_pkg
$ sudo -H pip install empy
$ sudo -H pip install lark-parser
$ sudo -H pip install numpy
$ sudo -H pip3 install -U catkin_pkg
$ sudo -H pip3 install empy
$ sudo -H pip3 install lark-parser
$ sudo -H pip3 install numpy
```

# 細かいメモ
pip install -U catkin_pkgやempyをしていないと，ROS2のビルド(colcon build)でImportErrorが出る場合がある．というか出た．

特にlarkをインストールしていないと独自メッセージ作成の時にImportErrorで"no module lark"と出た．rosidlでlark-parserを使用しているみたい
[参考](https://github.com/ros2/rosidl/issues/354)

pip install larkも必要かも？いらないとは思うが．

rosと共存していて管理者でインストールする時には，pip3でインストールした方がよいかも．
PL/SQL等をデバッグしようとしたら「デバッグ実行に必要なパッケージが見つかりません」というエラーが出る

表題の通り。
Oracle等のツール（ここではSI Object Browser）を使用してPL/SQLやPackageのデバッグ実行を行おうとしたら「デバッグ実行に必要なパッケージが見つかりません」というエラーが出たときの対処方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30304/1db9d71b-9304-1e49-bada-c5f2444dd41a.png)

## 原因
デバッグ実行をしようとしているユーザーに `debug connect session` 権限が足りない。

## 対処
SYSTEMユーザーで対象ユーザーに権限付与する
```
grant debug connect session to ユーザー名;
```
fastlaneでAppleIDの2段階認証に詰まったときにやったこと

# 概要
fastlaneコマンドを叩いたときにAppleIDの2段階認証につまづいて試行錯誤したメモ。

## 何が起こったのか
ちょっと放置していたiOSアプリのProvisioningProfile更新の時期がやってきた。
とりあえずAppleDeveloperにログインして状況を確認。
なにやら2段階認証が必要になったとのことで、設定をする。

さて、証明書はfastlaneで作り直せばいいから楽勝〜とか思っていたら、2019年3月頃？にAppleIDのログイン時に2段階認証が必要になっていて、 `fastlane match` を叩いたらこんなエラーが。。。
>[!] Apple provided the following error info:
    Two-factor authentication must be turned on for your Apple ID. After you turn it on, signing in to your developer account will require both your password and access to your trusted devices or trusted phone number.
>
>To learn more, see https://developer.apple.com/support/account/authentication/.

いろいろ調べて見た結果、衝撃の書き込みを発見。。。
>「2段階認証を無効にしたApple IDを別途作成して、必要な権限を与えて使ってください」とのことでした。説明見てるとできそうだけど、時間かけてもあまり意味もないと思うので今回は諦めました。以上です

え、これ無効にできないの？？
新しいID取得とかいろいろ影響ありすぎてやりたくないんだけど！！！！！

## やったこと
1. エラーログに表示されたURLにアクセスし概要を把握
2. fastlane を最新にアップデート
3. 下記を参考に`Appパスワード生成`
4. 環境変数 `FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD` に3で生成したAppパスワードを設定
5. `fastlane spaceauth -u user@email.com`　※メールアドレスはAppleIDで使用しているもの
6. 5で生成しためっちゃ長い文字列を環境変数 `FASTLANE_SESSION` に設定
7. 無事にコマンドが叩けるようになった！:tada:

参考記事
https://docs.fastlane.tools/best-practices/continuous-integration/#application-specific-passwords
1年がけで laravel と vue.js を勉強した結果・・・

urap.jp を作ってみた。

# 概要
診断メーカーがアクセス集めてるから、似たようなの作れば人くるでしょ。
というコンセプト。

# 技術
・laravel 5.7
・vue.js 2.6
・element ui
・twitterAPI
・conoha VPS
・gcp sql

cakephp3信者でしたので、全て1から勉強しました。

# 制作期間

2018年11月1日から2019年6月4日まで。
一旦公開するも、Adsenseの審査が通らず断念。

2019年6月10日に
https://urap.jp をリニューアルすると共に合体させることを決意。

結果全リニューアルが完了したのが、2019年10月25日。
結局すべてで、1年近くかかりましたね。

# laravel5.7 と cakephp3 の違い

## laravel の 良いところ

・ライブラリ系が最新。
・情報が豊富。
・ハマったらググりゃすぐに答えが出てくる。
まして、ライブラリが新しいのでサムネイル一つ作るにしても非常に楽。

## cakephp3 の良いところ

・慣れてる
・ルーティング自動なので楽

これから勉強するなら、 laravel 一択で良いでしょう。


# vue.js の良いところ

・一度読み込めばサクサク動く


# vue.js の泣きたいところ

・サーバーサイド と フロントエンド を分けて作成するので開発速度は遅くなる。
・いちいちビルドするのが面倒
・初期読み込みが重い

# vue.js アレコレ

・v-touchを使う場所を考えないと反応良すぎていろんなページに飛んでしまって逆に不便。
→ 使わなくてもいいんじゃないの？

・npm node.js の両方とも、最新版にしてからインストールすることを忘れずに。
→ npm run build で 意味不明なエラーでバグっちゃう。

・moment.js は使わず day.js を使う。
・element ui もけっこう重い。


# web アプリ系に Adsense の審査は通るか？

Adsenseにはフォーラムがある。
そこで、Adsense審査について質問をしてみた。

>前回もこのサイト見た気がしますが・・・
基本的にアドセンスは価値ある文字をビッシリ書くスタイルを想定していますので、文字数が極端に少ないwebサービスのようなサイトでは現在新規ではほとんど審査が通らないと思います。

と言われたので、リニューアルをしたのだが。
その後qiitaで聞いたら

https://qiita.com/kinmi/items/ce39b52ff712098431c4


>ブログなら投稿数少ない＝内容薄い、で分かるんですが
Webサービスで内容薄いとか判断できるのか・・・？と思って色々試しましたね。
noindex付けてる、sitemap無い、サーチコンソール登録してない→即日リジェクト
テスト投稿のみ→申請からちょっと期間置いてリジェクト
クローズドテストでそれっぽい投稿してもらう→申請からちょっと期間置いて合格


通るのかい！
ちゃんと通るのかい！
まぁ、僕の実力不足だったんですね。

アドセンスフォーラムは結局Google社員ではなく、Google好きな人がボランティアで答えているだけなので鵜呑みにしないようにしたほうが良さそうです。

# 結果アクセス数どうなの？

全然無いですね。。。
次を考えていかないと駄目みたい。
zipcloakコマンドは危険？zipコマンドを使おう！

# 目的
mac bookのフォルダをパスワード付きzipで圧縮する

# 動作環境
macOS Mojave 10.14.3
ZipCloak 3.0
Zip 3.0

# zipcloakコマンドを使ってパス付きzipを作成した
```
$ zipcloak aaa/
Enter password:
Verify password:
```
zipはできた。が、正しく展開できなかった。
mac bookデフォルトアプリのアーカイブユーティリティを使用して展開したところ、パスワードを何度も聞かれる自体に。正しいパスワード入れてるのに何回も聞き直してくる。（最初の確認では通ったように見え、解凍ステータスバーが進む。1/3くらいで再度聞かれ、以後繰り返し同じ個所で聞かれる。）
試しにwindowsからも7-zip使って展開試みたが、「パスワードが間違っていませんか？」のような曖昧な表示がされた。構成は展開できていたが、ファイルの中身は0KBだった。

# 解決策
タイトルの通り、zipコマンドを使う。

```
zip -e -r --password=xxx aaa.zip aaa/
```
できた。指定したパスワードを用いて正しく展開できることも確認。

# 最後に
zipcloak使ってzipファイルができたことに満足して展開確認せず圧縮対象をゴミ箱に入れていた。完全に消していたらと思うと、、、
確認は大事！！！

対処方法や原因などご存知の方いらっしゃいましたらご教示ください。
シェルスクリプトにおける特別な変数

シェルスクリプトを書き始めて間もない初心者の私のために記事を書きました。特別な変数をまとめて記述します。

他の初学の方で参考になればとおもいます。


＄0～9：位置パラメータ
＄#：引数の個数
＄@：引数全体の参照 ex. "＄@"="＄1" "＄2" "＄3"・・"＄n"
＄*：引数全体の参照 ex. "＄*"="＄1 ＄2 ＄3 ・・＄n"
＄?：直前に実行したコマンドの終了値
＄＄：シェルスクリプトのプロセスID
＄!：最後に実行したバックグラウンドプロセスID

＄{@:-.}：引数があれば＄@を使い、なければ.(カレントディレクトリー)を使う
ダウンキャストの話（備忘録）

#ダウンキャストとは
サブクラスのオブジェクトにスーパークラスのオブジェクトを格納すること。

##ダウンキャストの失敗
instance of を用いてインスタンスを代入できるか確認すればいいのですが、確認しなくてもわかればいいなと思い自分なりの解釈を備忘録として書くことにしました。


実際にコードにしてみると....
#####NGパターン（ダウンキャスト）

```
public class Human {
  public void speak (){
    System.out.println("アイウエオ");
  }
}
```

```
public class Men extends Human {
  public void speak (){
    System.out.println("かきくけこ");
  }
}
```

```
public class Main {
  public static void main void (String [] args){
    Human h = new Human();
    Men M = (Men) h;
  }
}
```

この場合はHumanはMenの内容を知らないのでダウンキャストができない。

しかし以下の場合だと（Mainクラスを編集）

```
public class Main {
  public static void main void (String [] args){
    Human h = new Men();
    Man m = (Man) h;
  }
}
```
MenはHumanの内容を知っているのでダウンキャストができる。
[Vue.js]vee-validateで連番で回ってる要素に対してバリデーションをつける

## やりたいこと

配列を回すごとに生成される<base-input>（input要素のコンポーネントだとお思いください）に対して、都度バリデーションを貼りたい


## やったこと

```html

<template v-for="(value, index) Ary">
              <base-input
                :key="index"
                v-model="Ary[index].name"
                v-validate="'required|email'"
                :name="'name' + index"
                :class="{ 'has-error': errors.has('name' + index) }"
                data-vv-as="タイトル"
              />
              <p v-if="errors.has('name' + index)" class="alert-danger">
                {{ errors.first('name' + index) }}
              </p>
</template>

```
プログラミング講習（仮）02

# プログラミング演習（仮）02
##目的
勉強したい人の支援

##内容
for
if 
while

## for文

```prex02a.c
#include <stdio.h>

void main() 
{
	int i;
	int sum = 0;

	for (i = 0; i < 10; i++)
	{
		printf("%d\n", i);
		sum += i;
	}

	printf("SUM : %d\n", sum);
}

```

```
$./prex02a
0
1
2
3
4
5
6
7
8
9
SUM : 45
```

## while文
```prex02b.c
#include <stdio.h>

void main() 
{
	int i;
	int sum = 0;

    i = 0;

	while (i < 10)
	{
		printf("%d\n", i);
		sum += i;
		i++;
	}

	printf("SUM : %d\n", sum);
}
```

## 素数表示
``` prex02c.c
#include <stdio.h>
#include <stdbool.h>

void main() 
{
	int i, j = 2;
	int lim = 10;
	int count = 0;
	bool flag;

	while (true)
	{
		flag = true;

		for (i = 2; i < j; i++)
		{
			if (j % i == 0)
			{
				flag = false;
				break;
			}
		}

		if (flag)
		{
			printf("%d\n", j);
			count ++;

			if (count == lim)
				break;
		}
	
		j++;
	}
}
```