OmniAICreator/Qiita-1.07M huggingface dataset:
【クソアプリ】猫がいるリバーシアプリつくってみた

# 前置き

この記事は クソアプリ Advent Calendar 2020 の9日目の投稿です。
筆者は猫を飼いたいあまりおかしくなってしまいました。


# 猫との暮らし

猫と暮していると何をするにも猫がついてきます。

PC作業中に__キーボードに座られて仕事できない。。。__ってなるんだと思います。

そんな生活をぜひ皆さんに味わってほしくてこのアプリをつくりました。

表示が遅いのはきっと猫のせい。

[猫とリバーシ](https://trusting-visvesvaraya-3756e0.netlify.app/)


オンライン対戦できるようにしましたが、相手がいないと出来ないので

動きを確認したい人は下のオフライン対戦でお願いします。



# 猫がしてくれること

猫はひっくり返すのが大好き。

__きっと並べられている石を好き勝手にうらがえしてしまうでしょう。__

自分が4回打った時に裏返しに来ます。__かわいいですね。__


# 使用技術

angular 
scss
firebase


# 詰まったところ
盤面をfriebaseのCloud Firestoreで共有しているのですが

多重配列に対応していなかったので、文字列化してあげる必要がある

```ts:play.component.ts

// 初期ボードの値

   board = [
      [0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 1, 2, 0, 0, 0],
      [0, 0, 0, 2, 1, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0, 0],
    ];

// ボード情報を更新
  async setBoard(boardName: string) {
    const boardStr= JSON.stringify(this.board); //文字列化する
    await this.database
      .collection(boardName)
      .doc('board')
      .set({ board: boardStr});
  }

```



```ts:play.component.ts

// ボード情報を取得
  async getBoard(boardName: string) {
    await this.database
      .collection(boardName)
      .doc('board')
      .valueChanges() 
      .subscribe((res: Board) => {
        this.board = JSON.parse(res.board);
      });
   }
```

# プレイ画面

![play1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390321/ba1dcfe2-761a-35d1-8aa9-ba643f13fc7c.gif)
rails deivise 複数のモデルストロングパラメーター

```ruby:app/parameters/user/parameter_sanitizer.rb
class Corporation::ParameterSanitizer < Devise::ParameterSanitizer	  
	def initialize(*)
		super
        # 新規登録時のパラメーター
		permit(:sign_up, keys: [
			:email,
			:password, 
			:password_confirmation,
		    :name,
		   	:locate,
		    :start_year
		])   

        # ユーザー情報アップデート時のパラメーター
        permit(:account_update, keys: [
        	:email,
			:password, 
			:password_confirmation,
		    :name,
		   	:locate,
		    :start_year
		]) 
	end
end
```
こんな感じにストロングパラメーターを指定したいモデルにつき
app下にparametersフォルダを作り、その中に```モデル名```のフォルダを作り、parameter_sanitizer.rbファイルを作る。

全てのモデルに対して行う
![スクリーンショット 2020-12-08 23.57.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239663/e01e6911-4488-4e1a-4917-c02fc3e83baa.png)

こんな感じ

```ruby:config/application.rb
...
# 上記のものを読み込ませる
config.autoload_paths += Dir[Rails.root.join('app', 'parameters', '**', '*')]
...
```

```ruby:application_controller.rb
class ApplicationController < ActionController::Base
	  	def devise_parameter_sanitizer
	  		if resource_class == Student
	  			Student::ParameterSanitizer.new(Student, :student, params) 
	  		elsif resource_class == Corporation
		  		Corporation::ParameterSanitizer.new(Corporation, :corporation, params) 
		  	elsif resource_class == StudentGroup
		  		StudentGroup::ParameterSanitizer.new(StudentGroup, :student_group, params)
		  	elsif resource_class == NonProfitOrganization
		  		NonProfitOrganization::ParameterSanitizer.new(NonProfitOrganization, :non_profit_organization, params)
		  	else
		  		super # Use the default one
		    end
	  	end
end
```
用語メモ（バージョン管理関連など）

#用語メモ

<b>.gitignore</b>
gitでのバージョン管理において無視するファイルまたはディレクトリを指定

<b>composer.json</b>
パッケージと条件が書かれているJSONファイル

<b>composer.lock</b>
composer.jsonからインストールされた情報が記述されている
lockを利用して同じ環境を作ることが可能

#今日の名言

What do you want meaning for? Life is desire, not meaning.
（なぜ意味なんか求めるんだ？人生は願望だ、意味ではない）
 
-チャーリー・チャップリン
Git/GitHubの初期操作に触れてみた(@Python/Django)

#はじめに
今回は、Python/DjangoにてWebアプリを作成する過程で扱う
Git/GitHubの初歩的な初期操作について簡潔に確認していきます。

【前工程】
・djangoプロジェクト作成は[こちら](https://qiita.com/kosments/items/663baa3e7955f54438b9)
・Git初期設定は[こちら](https://qiita.com/kosments/items/d2b87f45a58e24c127d0)

#GitHubの初期操作
基本的には以下のように、公式のsetupに推奨される手順通り、コマンドを実行していきます。これらを実行することで、ローカルのプロジェクトを保存することから、Web上のGitHubへUPするところまで行います。

※事前にGitHubにサインインし、「+」マークから「New repository」を選択し、任意のリポジトリ名を付けて「Create」しておきます。

①リポジトリの作成とリモートリポジトリの紐付け

```
$ git init
$ git remote add origin https://github.com/aaaaa/bbbbb.git
```
originのあとは、作成したリポジトリのURLをコピー&ペースト

```
＄ git status
```
ローカルリポジトリのステータス確認

②コミット対象を指定
　今回の場合、"."とすることで、カレントディレクトリ以下の全てのファイルを対象としています。

```
$ git add .
```

```
＄ git status
```
ローカルリポジトリのステータス確認

③ローカルに保存する
　"first commit"という名前でローカルに保存します。

```
$ git commit -m "first commit"
```

④ローカルのブランチ名を変更する

```
$ git branch -M main
```

⑤事前に作成しておいたGitHubのリポジトリを使用してリモートリポジトリを追加する

```
$ git remote add origin https://github.com/指定のリポジトリ名/
```

誤って追加した場合の削除は以下の通りです。

```
$ git remote rm origin
```

⑥GitHub上にプッシュする(Web上にUPする)

```
$ git push -u origin main
```

ここでうまく実行されない場合は、
[初期設定](https://qiita.com/kosments/items/d2b87f45a58e24c127d0)がうまくいってない可能性があるため、
再確認し再度実行してみます。

GitHub上で"Success"と表示され完了しました。

#まとめ
今回は、Webアプリを作成する際、事前のプロジェクト作成後のGit/GitHub初期操作を確認しました。

Python/djangoによるWebアプリ作成の過程で、さらにGit/GitHubについて掘り下げていきたいと思います。

ありがとうございました。
PowerShellでオセロ

## はじめに

PowerShellだったら、途中経過をファイルに保存することなくオセロを実装できますね。

というわけで作ってみました。

## 使い方

※`.ps1`ファイルなので、管理者権限でPowerShellを起動して、`Set-ExecutionPolicy`でファイルの実行を許可しておいてください。

```powershell
Set-ExecutionPolicy RemoteSigned
```

```
> # 開始
> $board = .\Othello.ps1;
> 
> # 盤面表示
> $board.Show()

A  B  C  D  E  F  G  H  Index
-  -  -  -  -  -  -  -  -----
　 　 　 　 　 　 　 　     0
　 　 　 　 　 　 　 　     1
　 　 　 　 　 　 　 　     2
　 　 　 〇 ●  　 　 　     3
　 　 　 ●  〇 　 　 　     4
　 　 　 　 　 　 　 　     5
　 　 　 　 　 　 　 　     6
　 　 　 　 　 　 　 　     7
>
> # 手番
> # やっつけなので英数の順で小文字不可。
> $board.Set('F4')
●を置きました。次は〇

A  B  C  D  E  F  G  H  Index
-  -  -  -  -  -  -  -  -----
　 　 　 　 　 　 　 　     0
　 　 　 　 　 　 　 　     1
　 　 　 　 　 　 　 　     2
　 　 　 〇 ●  　 　 　     3
　 　 　 ●  ●  ●  　 　     4
　 　 　 　 　 　 　 　     5
　 　 　 　 　 　 　 　     6
　 　 　 　 　 　 　 　     7

>
```

## 自動再生

PowerShellなので次のようにパイプラインで配列を渡せばプレーを自動再生できます。

```
> $board = .\Othello.ps1; $board.Show()

A  B  C  D  E  F  G  H  Index
-  -  -  -  -  -  -  -  -----
　 　 　 　 　 　 　 　     0
　 　 　 　 　 　 　 　     1
　 　 　 　 　 　 　 　     2
　 　 　 〇 ●  　 　 　     3
　 　 　 ●  〇 　 　 　     4
　 　 　 　 　 　 　 　     5
　 　 　 　 　 　 　 　     6
　 　 　 　 　 　 　 　     7

> 'F4','D5','C4','F3','E2','F5','G4','E5','E6' | %{$board.Set($_)}
●を置きました。次は〇

A  B  C  D  E  F  G  H  Index
-  -  -  -  -  -  -  -  -----
　 　 　 　 　 　 　 　     0
　 　 　 　 　 　 　 　     1
　 　 　 　 　 　 　 　     2
　 　 　 〇 ●  　 　 　     3
　 　 　 ●  ●  ●  　 　     4
　 　 　 　 　 　 　 　     5
　 　 　 　 　 　 　 　     6
　 　 　 　 　 　 　 　     7


# 中略

終了 ●13 〇0

A  B  C  D  E  F  G  H  Index
-  -  -  -  -  -  -  -  -----
　 　 　 　 　 　 　 　     0
　 　 　 　 　 　 　 　     1
　 　 　 　 ●  　 　 　     2
　 　 　 ●  ●  ●  　 　     3
　 　 ●  ●  ●  ●  ●  　     4
　 　 　 ●  ●  ●  　 　     5
　 　 　 　 ●  　 　 　     6
　 　 　 　 　 　 　 　     7

>
```

## ソースコード

[Othello.ps1](https://github.com/kakei-akihiko/pso/blob/master/Othello.ps1)
川柳の作り方【Python】


```make_meiku.py
import random

def kana():
   return chr(random.randint(ord('あ'),ord('ん')))

text = ""
for i in range(5):
      text += kana()
text += " "
for i in range(7):
      text += kana()
text += " "
for i in range(5):
      text += kana()

print(text)
```

## わぞぃへお ほぜはぱちえで うょむめが
チャンプルーDocker環境(Rails+Laravel+MySQL)

# はじめに
書くネタがなかったのでニッチかもしれませんが、タイトルの通りRails+Laravel+MySQLのDocker環境を構築してみました。突貫で構築したので所々至らぬ点や改善点があるかと思いますのでお手柔らかにアドバイス頂けると助かります:bow_tone1:
ちなみにチャンプルーとは沖縄の方言で『ごちゃまぜ』という意味です:cooking:

# 環境
macOS Catalina 10.15.7
Docker 19.03.13
Compose 1.27.4
Rails 6.0.3(Ruby 2.7.0)
Laravel 7.30.0(PHP 7.2.34)

# フォルダ構成
```
.
├── laravel_app
│   ├── laravel
│   │   ├── app
│   │   ...
│   └── Dockerfile
├── rails_app
│   ├── app
│   ├── bin
│   ...
│   └── Dockerfile
└── docker-compose.yml

```

# Rails+MySQL環境
以前書いた記事を参考に構築しました:pencil2:
[RubyをインストールせずにDockerでRails環境を構築する](https://qiita.com/fukushi_yoshikazu/items/c9beba97914d89ab4022)

※変更点としてはフォルダパス(rails_app)が変わっているのとサービス名を*Rails*と*Laravel*でわかりやすいように変えています。あとはほとんど記事と同じ手順でRails+MySQL環境は構築出来ました:tada:

```
version: '3'
services:
  rails6:
    build: ./rails_app/
    environment:
      RAILS_ENV: development
      TZ: Asia/Tokyo
    ports:
      - '3000:3000'
    volumes:
      - ./rails_app/:/usr/src/app
    depends_on:
      - database
```

# Laravel環境
まず、Laravel用のDockerfileを用意します。

```Dockerfile:laravel_app/Dockerfile
FROM php:7.2-fpm
# install composer
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim
RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql
WORKDIR /var/www/html
```

次に、docker-compose.ymlに**php**の部分を追記します。

```docker-compose.yml
version: '3'
services:
  php:
    build: ./laravel_app/
    volumes:
      - ./laravel_app/:/var/www/html
    ports:
      - '8000:8000'
    depends_on:
      - database
  rails6:
...
```

ここで一度buildを行い、ComposerでLaravelプロジェクトを作成します。

```
$ docker-compose up -d --build
$ docker-compose exec php composer create-project --prefer-dist laravel/laravel ./laravel
```

これでlaravel_appフォルダ内に*laravel*プロジェクトが作成されますのでMySQL接続情報を設定します。

```env:laravel_app/laravel/.env
DB_CONNECTION=mysql
DB_HOST=database
DB_PORT=3306
DB_DATABASE=app_development
DB_USERNAME=root
DB_PASSWORD=password
```

最後にLaravelのビルトインサーバを起動するコマンド(php artisan serve)をDockerfileに定義して完成です。

```Dockerfile:laravel_app/Dockerfile
FROM php:7.2-fpm
# install composer
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim
RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql
WORKDIR /var/www/html/laravel
EXPOSE 8000
CMD ["php","artisan","serve","--host","0.0.0.0"]
```

それぞれhttp:localhost:3000とhttp:localhost:8000でアクセスして確認出来ます:santa:
![Rails_Laravel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61433/38c0370c-cb33-5cd9-de71-cf91d98a6162.png)
VSCodeのターミナルでカーソルの単語移動をする

自分用メモ

itermでのカーソルの単語移動は設定からできるし、VSCodeのエディタでの単語移動も簡単に設定できる。記事もそこそこ見つかる。VSCodeのターミナルでも単語移動自体は`Option+矢印キー`でできるがいちいちそこに指を持っていくのは辛いし、VSCodeなら任意のコマンドを割り当てたい。そのやり方がわからなかったのでメモする。

VSCodeでは`"command": "workbench.action.terminal.sendSequence"`を使ってエスケープシーケンスを送れる。単語移動に該当するエスケープシーケンスを送ればよいのだがそれが全然わからなかった。
結果は以下を追加すればよかった。keyは任意で。

```json
{
    "key": "cmd+b",
    "command": "workbench.action.terminal.sendSequence",
    "args": { "text": "\u001bb" },
    "when": "terminalFocus"
},
{
    "key": "cmd+f",
    "command": "workbench.action.terminal.sendSequence",
    "args": { "text": "\u001bf" },
    "when": "terminalFocus"
}
```
これでVSCodeでのターミナルで単語移動を任意コマンドに割り当てられるようになりとても捗る。
注意）MacOXでのみ確認。Windowsは不明。
Laravel Duskエラー　「Facebook\WebDriver\Exception\UnknownErrorException: unknown error: net::ERR_CONNECTION_REFUSED」

## 発生したタイミング
　テストコード作成後、下記コマンド実行時にタイトル記載のエラーが表示

```
php artisan dusk
```

## 原因
　調べるとどうやら.envに記載したAPP_URLパラメータの値が間違っている模様

##原因解決
　.envのAPP_URLパラメータの値をブラウザからアクセスするアプリケーションで使用するURLと一致させる。
　現在デプロイをしておらずローカル環境だった為下記のように変更する。

```
APP_URL=http://localhost:8000/
```

## 修正後コマンド実行
これで解決したと思い再度php artisan duskを実行すると......。
同じエラーが。
.......原因はサーバーを立ち上げていなかったから。
下記コマンドでサーバーを立ち上げ。。。。

```
php artisan serve
```
新規タブで

```
php artisan dusk
```

これで無事テストが実行されました！！！
以上
Notionでバックリンクを使う

アルプ株式会社でエンジニアをしています、集約のエンティティ@pictinyです。
これは[Notion Advent Calendar 2020](https://qiita.com/advent-calendar/2020/notion) 8日目のエントリです。
7日目は[Notionでページにメンションをする](https://qiita.com/pictiny/items/b4194b8e9e0a7ba04044)でした。

# ページリンク
Notionは[リンクブロック](https://qiita.com/pictiny/items/32a868130432d7b405e1#%E3%83%AA%E3%83%B3%E3%82%AF%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF)や[メンション](https://qiita.com/pictiny/items/b4194b8e9e0a7ba04044)でページのリンクを作ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/df30c902-7ec7-2716-72f9-67afdb0ccd62.png)

# バックリンク
リンクされたページには、リンクが設置されたページへのバックリンクが見れるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/4cf189ec-abde-4aec-363f-99a8e99b32e2.png)

バックリンクは、ページコメントの下に表示されます。

# まとめ
バックリンクがあると関連するページ間の移動が楽になりますね！

公式ドキュメントは[Create links & backlinks](https://www.notion.so/Create-links-backlinks-cb3c406403c940b68af52de121e05474)にありますので、そちらもご覧ください。
AWS CLIがMINGW64でc:\program: bad interpreter: No such file or directoryエラーになる場合の回避方法

## はじめに

GitBashで入れたMINGW64をシェル実行環境として利用している人がそれなりに遭遇してそうですが、意外と記事がなかったので、記録として残しておきます。
エラーのキーワードで検索するとbrewとか、pipの話が出てきますが、全く関係ありませんでした。

### 追記

この方法ではコマンドプロンプトでの事項ができなくなるので、結局はスペースがないフォルダに再インストールしました。
シンボリックリンクなども試してみましたが、ダメでした。

## 前提条件

- Windows
- MINGW64 ※Cgwinでの動作は未確認ですが、同様の事が起きると思います
- AWS CLI

## 現象

上記の環境にてAWS CLIを利用した際に以下のようなエラーになる。

``` 
$ aws
bash: /c/Program Files/Python38/Scripts/aws: c:\program: bad interpreter: No such file or directory
```
## 回避方法

環境変数のpathで指定しているScriptsを「'（シングルコーテーション）」で囲む。

これを

```
C:\Program Files\Python38\Scripts\
```

こうする

```
'C:\Program Files\Python38\Scripts\'
```

## 補足

ちなみに、「"（ダブルコーテーション）」だと設定できないとエラーになります。
ダメもとでPYTHON_HOMEとかで別で設定もしてみましたが、やはりダメでした。

## 最後に

エラーの内容をよく見れば当たり前の回避方法ですが、MINGW64環境固有の問題かと勝手に思い込んで15分位無駄に時間を使ってしまったので、供養として書き残しました。誰かの役に立てば幸いです。
Qt6がリリースされました

カレンダーが空いていたので投稿します。

本日Qt6が正式リリースされたようです。
![Qt6Released.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69678/739151fe-cba3-fe06-bb42-ec01cfd3f8d5.png)
https://www.qt.io/blog/qt-6.0-released

MaintenanceToolを実行すると、いろいろUpdateされていますね。
![MaintainQt6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69678/f8eecfa9-1f48-7fb4-6708-463f8be2e417.png)
更新対象の中に、「Documentation for Qt 6.0.0 〇〇」という項目がたくさんあるので、Qt6関連のドキュメントも入っているようです。
ダウンロードにかなり時間が掛かりそうなので、今晩放置して明日以降中身を確認します。楽しみですね。

Twitterに流れていたQt6のトップページ？はこちら。
https://www.qt.io/product/qt6?utm_campaign=Qt%206&utm_content=148435350&utm_medium=social&utm_source=twitter&hss_channel=tw-64366556

Qt6のドキュメントの場所です。
https://doc.qt.io/qt-6/index.html

Qt5のドキュメントはこちら。
今のところそのまま残っているようです。
https://doc.qt.io/qt-5/index.html
cronから仮想環境venvのスクリプトを実行する

https://github.com/kazuho/kaztools/blob/master/cronlog
[cron で > /dev/null して椅子を投げられないための3つの方法 \- 酒日記 はてな支店](https://sfujiwara.hatenablog.com/entry/20120613/1339547638)

```
$ cd tmp
$ python3 -m venv venv
$ pip install requests
$ cat p.py
import requests
$ cat /etc/cron.d/test
*/1 * * * * k8uwall cd /home/k8uwall/tmp; /usr/local/bin/cronlog --timestamp -- venv/bin/python p.py

# tail -f /var/log/cron
Dec  8 21:53:01 k8uwallsv CROND[6402]: (k8uwall) CMD (cd /home/k8uwall/tmp/c/; /
usr/local/bin/cronlog --timestamp -- venv/bin/python p.py)
```
Apple信者による、プログラミングの学習効率を爆上げするテクニック

##ツール

- iPad
- Apple pencil
- iCloud
- [GoodNotes5（アプリ）](https://apps.apple.com/jp/app/goodnotes-5/id1444383602)

##GoodNotes5（アプリ）とは
　言わずと知れた、有料のノートアプリです。¥980ですが、断言します。安い買い物です。買い切りなので、一度買ってしまえば、以後料金はかかりません。
　ノートアプリは無限にノートやページを増やすことができます。アナログではできない、デジタルの使い方をマスターすれば、学習効率爆上がり間違いなしです。
　細かい使い方については、割愛します。

##プログラミングの学習においての活用方法
　プログラミングの学習についてググると、よく「覚える必要はない。カンニングOK」という言葉を目にします。私も学習を始めて間も無いですが、大いに賛同できます。ググればおおよそ必要な情報にありつけます。しかし、正直全く覚えないとなると、同じ問題で何度も調べることになってしまい、時間の無駄に感じてしまうことがこれまでに多々ありました。そこでおすすめしたいのが、ノートアプリを使った学習です。特に真価を発揮するのは、スキルチェック系のプログラミング言語の問題の復習です。問題もスクショで撮ったり、自分の回答や模範解答をスクショしてノートに貼り付けると、いつでも学習の復習をすることができます。

##手順
1. Macでスクリーンショットを撮る
2. iPadでGoodNotesを起動し、ノートを開く
2. iPadのスライドオーバーを使って、画像をドラッグ&ドロップ
3. 画像をトリミングする
4. 手書きでコメントを書く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741816/ff886a3a-5365-5e93-13d0-b7658878d6ac.png)

##ちょっとしたテクニック
- Macでスクショを撮ったものを保存する先をiCloudにしておく。iPadのスライドオーバーをそのiCloudのファイルにしておく。大体10秒くらいで同期されます。
- iPhoneにも同期しておくと、移動時間にもチェックができます。
　

##課題
　画像なので、コードをそのままコピーして再利用することができません。今は、Notionをいうメモアプリで、コードを保存できないか模索中です。
Laravel Duskの導入

## 導入背景
　現在Laravelで作成したポートフォリオのテストをデフォルトで搭載されているテストディレクトリを使用して実行していたが、利用が簡単なブラウザの自動操作／テストAPIであるDuckの存在を知ったので使用してみた

## 導入方法
プロジェクトに移動し、パッケージを取得

```
cd (プロジェクト名)
composer require --dev laravel/dusk
php artisan dusk:install
```
上記後、プロジェクトのtestディレクトリ内にBrowserディレクトリが作成される


## .envの変更
.envファイル内のAPP_URL環境変数を変更する。
値はブラウザからアクセスするアプリケーションで使用するURLと一致させます。
※ローカル環境の場合

```
//デフォルト）
APP_URL=http://localhost
↓
//変更後）
APP_URL=http://localhost:8000
```

##参考文献
https://readouble.com/laravel/7.x/ja/dusk.html
【Android】root判定によるチート対策

[PONOS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/ponos) 9日目の記事です。

昨日は[@nissy_gp](https://qiita.com/nissy_gp)さんの[Node.js+Sequelizeで楽観的ロックを使って動作を確認する](https://qiita.com/nissy_gp/items/3c879d0469e7a89f86bf)でした。

##はじめに:eyeglasses:

前回の記事で「[Android開発者向けオプションを使ったチート対策](https://qiita.com/kerimeka/items/66337261453c3e2bb154)」を紹介しました。
今回は、「root判定によるチート対策」を紹介します。

##この記事の対象者:eyeglasses:
・アプリ開発者
・Android開発者

##root化された端末の判定
メモリハックによる値書き換えなどのチート行為は
root化された端末を使用して行われるケースが多いです。

今回はアプリ側から`su`コマンドを実行して
`IOException`の有無で判定してみましょう。
・`IOException`発生の場合はroot権限なし　ー＞　通常端末
・`IOException`発生しない場合はroot権限あり　ー＞　root端末

[java.lang.Runtime](https://docs.oracle.com/javase/jp/6/api/java/lang/Runtime.html#exec(java.lang.String))クラスの
[exec(String command)](https://docs.oracle.com/javase/jp/6/api/java/lang/Runtime.html#exec(java.lang.String))メソッドを使用します。

```
boolean isRoot = false;

try {
    Process process = Runtime.getRuntime().exec("su");
    process.destroy();
    isRoot = true;
    Log.d(TAG, "Root!!");
} catch (IOException e) {
    Log.d(TAG, "NotRoot!!");
} catch (Exception e){
    e.printStackTrace();
}

if(isRoot){
    //root権限ありの時の処理
    //例：情報をサーバーに送信し、root化解除を促すポップアップ表示
}

```
**メリット**
アプリのセキュリティーレベルを上げることができる。
実装コストが軽い

**デメリット**
マニアックな海外製端末で初期出荷状態から
root権限が付与されているケースなどがあり、健全ユーザーがチート扱いされてしまう場合もある。
※経験則になってしまいますが、このパターンはかなりレアケースでした。

**注意点**
リバースエンジニアリングによるコード改竄で今回のコードを無効化されてしまう恐れもあります。
root対策と同時にリパッケージされた不正アプリ対策を実装するのがお勧めです。
**不正アプリ対策**
・メモリシャッフル
・難読化
・SafetyNet導入
などがあり、SafetyNet の Attestation APIを使用してリパッケージされていないか判定することができます。

##SafetyNetの紹介

**SafetyNetでできること**
[SafetyNet Attestation API](https://developer.android.com/training/safetynet/attestation.html)：
   正規の Android デバイスで、正規のアプリかどうか判定できる

[SafetyNet Safe Browsing API](https://developer.android.com/training/safetynet/safebrowsing)：
    URL が Google によって既知の脅威としてマークされているかどうかを判定できる

[SafetyNet reCAPTCHA API](https://developer.android.com/training/safetynet/recaptcha)：
 悪意のあるトラフィックを検知することができる

[SafetyNet Verify Apps API](https://developer.android.com/training/safetynet/verify-apps)：
   有害なアプリから端末を保護することができる

####SafetyNet Attestation API
実装方法は[公式](https://developer.android.com/training/safetynet/attestation#java)に記載されているので省略しますが
以下の手順で正規アプリかどうか判定することができます。
1.SafetyNet 構成証明をリクエスト

2.SafetyNet 構成認証レスポンスを各種検証

3.apkPackageName: 呼び出し元のアプリのパッケージ名のチェック

4.APK証明書のSHA-256ハッシュ：署名に使用したAPK証明書を検証

5.APKのSHA-256ハッシュ：APKがリリースしたものから改ざんされていないことを確認するために、APKのSHA-256ハッシュが同一か検証

6.BasicIntegrityがtrueであることを確認

**※検証処理はサーバー側で行うこと**


##まとめ
今回紹介したroot判定は自前で実装する手法でしたが
SafetyNet Attestation API
を使用してでも判定することができます。
構成認証レスポンスのBasicIntegrityがfalseの場合はroot端末です


他にもSafetyNetを使用したチート対策があるので
公式ドキュメントを読んでおくことをお勧めします。


明日は[@block](https://qiita.com/block)の記事です。
お楽しみに！！
Slack絵文字多すぎ問題

こんにちは。オープンロジ アドベントカレンダー8日目担当の小池です。
本日はSlackに関する小ネタを共有したいと思います。

現在オープンロジでは社内コミュニケーションツールとしてSlackを利用しております。Slackは言わずもがな便利なコミュニケーションツールですが、その特徴のひとつとして他人の書き込みに対してカジュアルにリアクションできる **絵文字機能** が挙げられます。

元から多くの絵文字が用意されていますが、オリジナルの絵文字を追加できるので、たまに外部のワークスペースを覗く機会があるとどんな絵文字が用意されているのか気になりますよね（笑）。ちなみに12/8現在、オープンロジのオリジナル絵文字は **3411** 個あります。

ただこれには問題もあって（無理やり）、絵文字がありすぎるとどれを使うべきか迷いが生じます。例えば了承を意味する絵文字だけでも、OK、了解、拝承、わかった、わかりました、と言ったように多少のニュアンスの違いはあれど、基本的には同じ意味合いの絵文字が複数存在するのです。Slackは下記のスクショのように「よく使う絵文字」としてピックアップしてくれてはいるものの、目で選んで選択する or サジェストで絞り込んで選択するというアクションは、それ単体ではたいしたコストにはならないかもしれませんが、それが1万回、1億回と積み重なったらどうでしょう？
![Screenshot from 2020-12-08 13-45-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240373/d14c7dc9-4867-a329-6e05-21b321379ca9.png)

そこで最近見つけたSlackの面白い機能をご紹介したいと思います。

## Slackのリアクションを神速で行う方法
Slackには「ワンクリック絵文字リアクション」という機能が存在するのをご存知でしたか？
設定方法は、画面右上のアイコン＞環境設定＞メッセージ＆メディア
![Screenshot from 2020-12-08 18-39-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240373/c742b3d9-f4dd-a128-a0b6-a924e84ef704.png)

この機能を有効にして書き込みにカーソルを合わせると、表示されるメニューに絵文字が追加されます。後はこれをポチッとするだけでリアクションできるのです！

ただし設定できる絵文字は **3つ** だけ。賛否だけでも2枠使うので結構悩ましいですね・・・。
![kanai.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240373/948823d6-53c5-3295-0465-24992f068f23.jpeg)

絵文字の選択に悩んだあの日々、あの時間を、「ワンクリック絵文字リアクション」によって取り戻していただけたら幸いです。
gitでプッシュする前に確認すべきこと

## この記事を書こうと思ったきっかけ
最近gitを使ったチーム開発し始めたが、あまりにも凡ミス、初歩的なミスをしまくり先輩エンジニアにこってり叱られたので、自分でpushする前のチェック項目を作成すればミスる可能性が減ると思って書きました

# 対象読者
gitを最近触り始まて、怯えながらgit pushしているエンジニアに向けてます

## チェック項目
### 大前提
- コードのコメントアウトの内容が適切であるか
- 変数名、関数名、クラス名はネーミング定義にそっているか。特になければ'言語　ネーミングルール`などでググっていい感じのルールを探す。Pythonなら[pep8](https://pep8-ja.readthedocs.io/ja/latest/)などを参考にする。
- Pythonに限るがドックストリングの内容は簡潔に記載されているか。書き方など特に指定なければ[こちら](https://qiita.com/simonritchie/items/49e0813508cad4876b5a)の記事を参考に記載する。
- 不要なコードはないか。例えば確認用に記載したprintやTODOのコメントなど
- 修正内容がきちんと修正されているか。（プルリクで却下された内容に対応した修正となっているかなど）

## git addする前

- `git status`で追加したいファイルが赤文字になっているか確認する。
- 余計なファイルがないか確認する。ある場合は追加したい対象のファイルのみをaddする

## git add後
- `git status`で追加したファイルが緑文字になっているか確認する。
- 余計なファイルがないか確認する。ある場合はgit addの取り消しを行う。取り消し方法は[こちら](https://www-creators.com/archives/1282)参照

問題がなければコミットを行う。

```
git commit -m '修正内容'
```

## git commit後
- `git status`で追加したファイルが表示されていないことを確認する。
- `git log`で的外れなコメントをしていないか確認する
- 問題がなければ__'git pull origin master'__を行う。

#### 問題がなければ__'git pull origin master'__を行う。（超重要！！）

## git push後
- BacklogやGitBabやGitHub等で自分の追加・修正箇所が反映されていることを確認する。

# その他
この項目も確認した方がよいなどあればコメントいただけると助かります！
Power AutomateでGmailを分割してGoogle スプレッドシートに保存してみた

みなさま　はじめまして

ニジボックスでプロデュースグループという部署で営業活動を行っているものです。
本日は会社メンバーより「アドカレというものに参加してみないか？」とお声がけ頂きまして、
一筆、かけることをかきたいと思ってます。


# テーマ
Power AutomateでGmailを分割してGoogle スプレッドシートに保存してみた


## Power Automate とは？
Power Automateは、Microsoft社が提供する自動化したワークフローを作成し、
あらゆる連携が出来るサービスです。


## 本記事はどんな人向け？
メールの内容を順番どおりSpreadsheetに保存したい人むけです。

例えば、お問い合わせフォームから送られたメールについて、
整形されている内容を抜き出したい場合を想定しています。

例）

```
氏名：ニジ 太郎
メールアドレス：nijiniji@example.com
お問い合わせ内容：商品について詳しく教えてください
```

**今回は上記メールが届いたことを前提に解説します。**


## 作業手順

### 1.フローを作成
![スクリーンショット 2020-12-19 0.35.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908755/dfbce306-9a1e-ec08-612b-7c8023141e88.png)
まず、Power Automateで新しいフローを作成します。
今回はメールを想定しているので、新しいメールが届いたときを選択します。


### 2.ラベルを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908755/e4146266-00c1-e946-33c7-18ccb521077e.png)
メールが届いたときの条件を設定します。
ほぼ、Gmailの使い方と同じだと思うので困らないと思いますが、
Gmail側でフィルタとラベルを設定しておいたほうが、運用が楽だと思います。
※メールボックスも一緒に整理出来るため


### 3.変数を初期化しよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908755/51219b11-e7e3-0cc7-e51d-92904157de07.png)
アクションの選択で、「変数を初期化する」を選びましょう。
種類：変数の種類を選択します。今回は上記例を想定して対応したいので、配列を選択します。
値：配列に格納する情報を指定します。↓

改行で分割を指定

```
split(triggerBody()?['Body'], decodeBase64('Cg=='))
```


### 4.Google スプレッドシートへ行を挿入しよう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908755/9d3bfa17-d0ec-9762-acec-8d239caeab64.png)
格納したいGoogle スプレッドシートを指定しましょう。


指定する式は、取りたい配列を指定します。
replaceを使うことで、配列内の文章から余計な部分を切り出します。


```
replace(variables('array')?[0],'氏名：','')
```


### 5.完成
しっかりテストを行って試してください〜！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908755/8df92085-c85e-d048-d19e-ba26e102ac33.png)
[Rails] WindowsのWSL2(Ubuntu、VSCode)にRailsをローカルインストールしてgitコマンドでgithub(master)にpushする

## 背景
WindowsのWSL2をVSCodeで操作し、Rails6.1をインストールし、ブラウザでwelcomeページが表示できることを確認し、コンソールからgitコマンドでgithubのmasterブランチにコードをpushするまでの手順です。

WSLを使った理由は、MACでの環境構築方法と近いからです。
また、gitでのブランチの切り分けとプルリク方法、Railsのフォルダ構成を最後に載せています。

## WSL 2（Windows Subsystem for Linux 2）をVSCodeから使えるようにする
① コントロールパネルから「プログラム」>「プログラムと機能」>「Windows の機能の有効化または無効化」を選択する。
表示されたチェックボックスにて「Linux 用 Windows サブシステム」「仮想マシンプラットフォーム」の二つにチェックを付ける。その後再起動を要求されるので再起動する。

② Windows storeからubuntuをインストールする。  

③ 下記コマンドでWSLのバージョンを確認する。

```
$ wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Running         1
```
バージョンが1なので下記コマンドでバージョン2にする。

```
$ wsl --set-version Ubuntu 2
```

`wsl --set-version Ubuntu 2`で「カーネルコンポーネントの更新が必要」という旨のエラーが出た場合、
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10
上記リンクから`wsl_update_x64.msi`をダウンロードし `C:\Windows\System32\lxss\tools` に移動してから実行する。
`wsl_update_x64.msi`の実行後に再度`wsl --set-version Ubuntu 2`を実行する。

※`wsl_update_x64.msi`は `C:\Windows\System32\lxss\tools` に移動しないと実行時にエラーが出る。
※`wsl_update_x64.msi`は上記リンクの`x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ`からダウンロードできるが、ダウンロードがChromeにブロックされて進まない場合がある。その際は`リンクを名前を付けて保存`し左下のダウンロード警告に対し`継続`を選択すればダウンロードできる。

④ VSCodeにRemote Development拡張機能をインストール > 左下緑色の`><`アイコンをクリック > Remote-WSL: New Windowを選択して新しいWindowの左下緑色のアイコンが`WSL`になっていればVSCodeでWSLを操作できる。

## RubyとRailsの環境構築（Railsはローカルインストール）
環境構築するにあたって知っておいたほうがいい事前知識は下記の記事にまとめました。
[[Rails] 初心者のための事前知識(rbenv、RVM、gem、RSpec、Rubocop、bundler、ローカルインストール、env、フロントエンド関連)](https://qiita.com/Taka5689/items/ae8028fb0a687451961f)

環境構築は下記2つの記事を参考にさせていただきました。
① [WSLで作るRuby on Rails環境構築 〜VSCode Remoteを添えて〜](https://qiita.com/Developer_KanZG/items/f329dd3dd197b2005390)
② [Rails開発環境の構築（rbenvでRuby導入からBundler、Rails導入まで）（Macport編）](https://qiita.com/emadurandal/items/a60886152a4c99ce1017)
↑①の「4.Rubyのインストール」から「6. Railsのインストール」の手前まで実施し、その後は②の「SSL証明書のインポート」以降を実施します。

※②の最終盤で`bundle exec rails server`して「webpackerが必要」という旨のエラーが出た場合、webpackerをインストールする必要があります。
webpackerのインストールには最新のyarnが必要ですが、aptでyarnを入れても最新版でないためwebpackerを入れる際にエラーが出ます。なので下記の順番でwebpackerをインストールする必要があります。

①下記を参考にyarnをインストールする。
[yarnインストールの際にエラーがでた](https://honmushi.com/2020/01/15/yarn-install/)

②webpackerをインストールする。

```
$ bundle exec rails webpacker:install 
```

再びコマンドを実行し、Railsが動いていることをブラウザから確認できました。

```
$ bundle exec rails server 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/347198/7aa4f8c0-b06d-55ae-50ea-473a5aade6b7.png)


## コンソールからgitコマンドでgithubのmasterブランチにpushする

①gitに自分のemailとユーザー名を設定する。
※しないとコミット時にエラーが出ます。

```
$ git config --global user.email メールアドレス
$ git config --global user.name ユーザー名
```

②下記の記事通り実施する。
[【Rails入門】 Githubを導入する方法](https://www.sejuku.net/blog/34829)

以上となります。

## 蛇足
下記の記事はGithubでプルリクする方法です。
[初心者向けGithubへのPullRequest方法](https://qiita.com/samurai_runner/items/7442521bce2d6ac9330b)

下記の記事はRailsのフォルダ構成です。
[デフォルトのRailsフォルダ構造](https://qiita.com/RMEL/items/d2fc650396be67e52ef1)

最後に、参考にさせていただいた記事の投稿者の皆様、ありがとうございます。
私の記事に不備などありましたらご指摘いただけると幸いです。
「パブリック仮想インターフェイス」と「プライベート仮想インターフェイス」の違い

# 初めに
皆さんは「パブリック仮想インターフェイス」と「プライベート仮想インターフェイス」の違い理解していますか？

# 「パブリック仮想インターフェイス」と「プライベート仮想インターフェイス」
### パブリック仮想インターフェイス(Public virtual interface)
パブリックリソース (非 VPC サービス) に接続するために使用する。
　**※パブリックリソース・・・AmazonS3, AmazonGlacier等**

### プライベート仮想インターフェイス(Private virtual interface)
VPC に接続するために使用する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/690270d5-0d2c-418f-f55c-4d4f4058f8d3.png)

# 終わりに
なるべくシンプルに理解したいと思い、公式ドキュメントを読み漁ったところ、とてもシンプルな説明が書いてありました。
読んでくださった皆さんの理解の一助となれば幸いです。

# 公式ドキュメント
[AWS公式 仮想インターフェイスの作成](https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/create-vif.html)
[AWS公式 Direct Connectとは](https://docs.aws.amazon.com/ja_jp/directconnect/latest/UserGuide/Welcome.html)
Alibaba Cloudの.NETの情報まとめ

# Alibaba Cloudの.NETの情報まとめ
Alibaba Cloudの多くのサービスやSDKは、C#に対応しています。
Alibaba CloudでC#を使う際のTipsを簡単にまとめました。

## 対応言語を確認する
基本的なことですが、使うサービスがC#に対応していることを確認しましょう。
ドキュメントの「Programming languages」というページなどで確認できます。
Function Computeなどはこのように[ドキュメント](https://www.alibabacloud.com/help/doc-detail/74712.htm?spm=a2c63.l28256.b99.27.b5b53c94Q3MUjO)が準備されています。

## .NET Framework or .NET Core
.NET Frameworkまたは.NET Coreのどちらに対応しているかを確認しましょう。
ただし、.NET Frameworkは今後アップデートされる予定が無いので利用される際は計画的に。

.NET Coreを利用する際はバージョンを確認しましょう。
.NET Core自体は現在、.NET Core 2.1 LTS /.NET Core 3.1 LTS があり、2020年11月に.NET 5が発表されました。
Alibaba CloudではSDK含めて.NET Core 2.1 LTS対応のものをよく見かけるので、ローカル環境との差分が出ない様に注意が必要です。

.NET Standardと.NET Core、.NET Frameworkの対応表は[こちら](https://docs.microsoft.com/ja-jp/dotnet/standard/net-standard)
.csprojに記載されている<TargetFramework>の一覧は[こちら](https://docs.microsoft.com/ja-jp/dotnet/standard/frameworks)

## SDK
Alibaba CloudはGitHubに各種SDKが準備されています。
Alibaba Cloudの[Organization](https://github.com/aliyun)

2020/12/8時点ではC#で開発されているリポジトリは25件、


中国語のページでは、このような各言語毎のSDKがリストとしてまとめられています。
[SDK一覧(中国語)-.NET SDK](https://develop.aliyun.com/tools/sdk?spm=a2c63.p38356.879954.5.3d5d7aecuoXA9X#/dotnet)

## まとめ
Alibaba Cloudは.NET Coreに対応しているサービスが多く、SDKも準備されているので利用するハードルは低く感じます。
しかし、バージョンのアップデートの対応がなかなか進んでいないようなのでこちらも早い対応が待たれます。
【digdag】shellでのネストされた変数の扱われ方

# 概要
` _export `で入れ子の変数を定義した場合の扱われ方。
入れ子の変数を定義すると環境変数としてjsonのような文字列（例: ` {"b1":"foo","b2":"var"} `）
として格納されてしまい、大変扱いにくくなってしまう。

# 対策案
- shellオペレータでなくpythonオペレータで処理を行う
- そもそも入れ子の変数を避ける

これくらいしか思い浮かばなかったので、うまく例の`foo`や`var`を取り出す方法があればコメントで教えて下さい。

# digファイル
``` digdag
+step:
  _export:
    a: hoge
    b:
      b1: foo
      b2: var
  sh> env
```

# 出力
ワークフローを実行すると以下の出力を得る。

``` sh
a="hoge"
b={"b1":"foo","b2":"var"}
```

# 追記
@hiroysato さんに対策案をコメントいただきました！
ありがとうございます！

入れ子の変数が少ない場合は下記のやりかたでいい感じに取り出せそうです。

## 案1
実行時に`${foo.bar}`に値を埋め込む方法。

``` digdag
_export:
  foo:
    bar: 1234

+echo:
  sh>: "env FOO=${foo.bar} env"
```

## 案2
`_env`で環境変数に`${foo.var}`を埋め込む方法。

``` digdag
_export:
  foo:
    bar: 1234

+echo:
  sh>: "env"
  _env:
    FOO: ${foo.bar}
```

## 案3(shellで取り出す)
jqでjsonから要素を取り出す。

``` sh
FOO=$( echo '{"b1":"foo","b2":"var"}' | jq -r .b1 ) ; echo $FOO
foo
```
GASとClaspとTypeScriptについて・・・書けませんでした

GASで動かしているプログラムって、

- Githubで管理できない
- 本番環境(Webエディタ上)でしか実行できない
- ECMAScriptだから型とか不安がある

という欠点がありますよね。
そこで、Google先生が提供している [clasp](https://github.com/google/clasp) というライブラリを利用すると、ローカルでGAS開発ができるので、ソースコードのGithub管理が不要らしいんです！
さらにTypeScriptにも対応したらしいんです！
らしいというのは、まだ手元で動かせてないんです (ToT)

そのうち手元で動かしてこの文章アップデートします！！


参考文献
https://qiita.com/HeRo/items/4e65dcc82783b2766c03
https://qiita.com/HeRo/items/f2ce057c6b1456e896ad
Visual Studio Installer Projectsで自作プログラムを配布するインストーラを作成しよう

#はじめに
Visual Studio Instaler Projects を使うと、Visual Studio で作成したアプリケーションだけでなく、別のツールで作成した自作のプログラムを配布することも比較的簡単にできる。今回それをやってみたい。

#Visual Studio Installer Projectsのインストール手順
参考のURLを参照のこと

#今回配布したいアプリ
別ツールのアプリを配布したかったが簡単に作れなかったので、以下のコテコテのWindows フォームアプリとする。

アプリ名：「Hello World」
実行ファイル名：Hello.exe
実行イメージ：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/0acbf77f-34b9-18e5-0239-f80f1528fd22.png)

#インストーラ作成してみよう
まずVisual Studioを開き、プロジェクトの種類として「Setup Project」でプロジェクトを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/03db44c8-1261-306a-273d-3df5fdd0ffd0.png)


すると以下の画面が表示されるため、「Hello.exe」を左側の「Application Folder」にドラッグする。
ドラッグするとApplication Folderの下に「Hello.exe」が追加される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/54a1cb85-6d29-7ea3-daa9-a61ef8ff4897.png)

次に「User's Programs Menu」をクリックし、右側のペインで右クリックし、「新しいショートカットの作成」をクリックする。
すると下のダイアログが表示されるため、「Application Folder」の「Hello.exe」を選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/a30df1e2-b674-9299-4f3d-85ce2af05bad.png)

するとショートカットが作成されるので、右クリックで「名前の変更」で「My Application」等と好きな名前に変更する。

ソリューションエクスプローラでプロジェクトを右クリックしてビルドをすると、"setup.exe"というインストーラができる。

#インストール
setup.exeをダブルクリックして、指示に従って進めていくとアプリをインストールすることができる。

インストールが完了すると、作成したショートカットでメニューが追加されておりダブルクリックすると、アプリケーションが実行されるはずだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329816/d0dd7f43-3cf2-fea9-4e56-82e80b9750f9.png)


#おわりに
NSIS等のように面倒なスクリプトを作成する必要がないため、複雑な処理がなくファイルをコピーする程度のインストーラであれば、これでも十分使える。

#参考
- [なつかしの Visual Studio Installer（の後継）を現役のVisual Studioで使用する](https://qiita.com/otagaisama-1/items/39bf6852f0e99c761786)
bit DPをやってみる

#はじめに
DPを練習している中で、ナップサック問題とかそういうのはできたもののbitDPとか桁DPは敬遠しちゃってました。さすがにいつかは通らないといけない道なのでbitDPから練習することにします！

#bitDPとは
bit操作を使って集合を扱うところが特徴的な動的計画法(DP)の一つです。

以下のような漸化式を使って更新していきます。
集合$\\{0,1,\dots,n\\}$の部分集合Sにおいて 

```math
dp[S] = min_{u \in S}{dp[S/\{u\}] + cost[S/\{u\},u]}
```

集合Sはビット列で扱います。例えば集合$\\{0,1,\dots,7\\}$においてその部分集合$S=00101001$で表されるときSに含まれるのは$0,3,5$となります。
#実際に問題を解いてみる

<a href="http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_2_A&lang=ja">Traveling Salesman Problem</a>を解いてみました。

重み付きグラフ$G(V,E)$が与えられた時にある頂点から出発し、全ての頂点をちょうど一度づつ通ってから下の頂点に戻るような閉路を求める問題です。

####入力:
```math
|V|\ \ |E|\\
s_0\ t_0\ d_0\\
s_1\ t_1\ d_1\\
:\\
s_{|E|−1}\ t_{|E|−1}\ d_{|E|−1}
```

####出力:
最短経路の距離を1行に出力する。条件を満たす経路がない場合は -1 と出力する。

####制約:
$2 ≤ |V| ≤ 15$
$0 ≤ d_i ≤ 1,000$
$G$ に多重辺はない

どの頂点から出発しても得られる解は等しいのでここでは頂点0から出発して頂点0に再び戻ってくる場合を考えることにします。

dp[S][v]を頂点0から出発して集合Sに含まれる頂点を一度づつ通り、最終的に頂点$v$へ行くまでの距離の最小値とします。そうすると、全ての頂点を含む集合 $S_{all}$ とした時、dp[ $S_{all}$ ][0]が問の答えになるとわかります。

メモ化再帰を使ったコードは下のようになります。

```C++:bitdp.cpp 
#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < (n); ++i)
const int INF = 1000000000;
int V,E;
int dist[16][16];
int dp[(1<<16)+1][16];
int bitdp(int S,int v){
	if(S==0){
		if(v==0)return 0;
		else return INF;
	}
	if(dp[S][v]!=0)return dp[S][v];
	int mn = INF;
	rep(u,V){
		if(u==v)continue;
		if(!(S & (1<<u)))continue;
		mn = min(mn,bitdp(S & ~(1<<u),u)+dist[u][v]);
	}
	return dp[S][v] = mn;
}
int main() {
	cin>>V>>E;
    rep(i,16)rep(j,16)dist[i][j]= INF;
    rep(i,E){
        int s,t,d;cin>>s>>t>>d;
        dist[s][t] = d;
    }
    int ans = bitdp((1<<V)-1,0);
	if(ans!=INF)cout<<ans<<endl;
	else cout<<-1<<endl;
	return 0;
}
```

上で使っているビット操作は集合Sに頂点uが含まれているか調べる時と集合Sから集合$S/ \{u\} (u \in S)$を求める時です。

```
!(S & (1<<u))== true
```

のときuはSに含まれていません。&は二つのビット列でANDをとります。また、1<<uは1をuだけ左にシフトしています。例えばu = 3のとき1<<uは00001000となります。

```
S & ~(1<<u)
```
では集合Sから頂点uを取り除いた集合$S/\{u\}(u \in S)$を求めています。~はNOT操作でビット列の0,1を反転させます。
MyBatis内のSQL <![CDATA[ 比較演算子 ]]> 

Mapper.xmlファイル内のSQLで引っかかったので個人的メモ。

```MySQL:Mapper.xml
'select  A.cutromer_id
        ,A.number
        ,case
           when B.customer is not null and B.customer <![CDATA[<>]]> ''
           else ''
         end AS C
 from A
 left join B
   on A.cutromer_id = B.cutromer_id'
```

MySQLに読み替える際、<![CDATA[　]]>を除いて書き換える必要がありました。
＊比較演算子はちゃんと書く。

```MySQL:MySQL.
'select  A.cutromer_id
        ,A.number
        ,case
           when B.customer is not null and B.customer <> ''
           else ''
         end AS C
 from A
 left join B
   on A.cutromer_id = B.cutromer_id'
```

MyBatisはXMLファイルにSQL文を定義して使用する。
XMLなので比較演算子が直接、使えないのがわかっていたつもりでした💦
CakePHPでテキストを切り詰めてサフィックスを付ける

#はじめに
テキストを特定の文字数で切り詰めて末尾に```...```などを付けたいときありますよね。
PHPでの組み込み関数を使えば簡単に実現できるのですが、CakePHPでは更に簡単に使えるものがありました。
最新のCakePHP4のものを紹介します。（2.x、3.xでもありました）

https://book.cakephp.org/4/ja/core-libraries/text.html#Cake\Utility\Text::truncate

#使い方
Cookbookに載っている通りになるのですが、
```Cake\Utility\Text::truncate(string $text, int $length = 100, array $options)```メソッドを利用します。

```$text```が```$length```より長い場合、このメソッドはそれを```$length```の長さに切り詰め、 ```'ellipsis'```が定義されているなら末尾にその文字列を追加します。

ちなみに```ellipsis```は日本語で```省略記号```という意味です。（```truncate```は```切り捨てる```）

```php

use Cake\Utility\Text;

$text = 'テキストを切り詰めます'

echo Text::truncate(
    $text,
    5,
    [
        'ellipsis' => '...',
    ]
);
```

出力:

```
テキストを...
```

※$textがnullの場合でもサフィックスだけ表示されちゃうみたいなことは起きません。

#おわりに
FWを利用する場合、汎用的なメソッドであれば便利な形で用意されてることもあるので、一度FW標準のものがないか確認した上で、なければ組み込み関数を使うといった手順を踏んだ方がよい、と本日先輩に教わりましたので備忘録として書き記しました。
演算子について【Swift】

# はじめに
初歩的な演算子についての備忘録になります。

# 比較演算子
|      | 　例 |
| ---- | ----- |
| 等しい | a == b |
| 等しくない | a != b |
| 大なり | a > b |
| 小なり | a < b |
| より以上 | a >= b |
| より以下 | a <= b |

# 論理演算子
|      | 　例 |
| ---- | ----- |
| 論理否定 | 　!a |
| 論理積 | a && b |
| 論理和 | a ll b |

# 複合代入演算子
#### 変数の値を更新したいときに使う（整数のみ）

|      | 　例 | 　内容 |
| ---- | ----- |------|
| += | a += b | a = a + b |
| -= | a -= b | a = a - b |
| *= | a *= b | a = a * b |
| /= | a /= b | a = a / b |
| %= | a %= b | a = a % b |

#### 自然数列の和を求める例
```Swift
var sum = 0
for i in 1...100 {
    sum += i
}
print(sum) // 5050
```

# 三項演算子
#### 簡単な場合分けによる値代入
#### 書式
```
条件 ? trueの値 ： falseの値
```

#### 簡単な場合分けの例
```Swift
let a = 30
let b = 60
var winner = "勝者は"
// if文での条件分岐
if a > b {
    winner += "Aさん"
} else {
    winner += "Bさん"
}
print(winner) // 勝者はBさん
```

```Swift
let a = 30
let b = 60
var winner = "勝者は"
// 三項演算子
winner += a > b ? "Aさん" : "Bさん"
print(winner) // 勝者はBさん
```

* 5行が1行にまとまりスッキリとなりました。
* 三項演算子の気をつける点としまして、半角スペースを置かずに「?」をつけると「オプショナル型の宣言」と解釈されエラーになりますのでご注意下さい。
Stealthwatch Cloud で検知した自宅のネットワーク異常をLINE Notify で通知

CiscoのStealthwatch Cloudを用いて自宅のネットワーク環境を監視しました。
https://www.cisco.com/c/ja_jp/products/security/stealthwatch-cloud/index.html

Stealthwatch Cloudの60日間の無料トライアルは下記URLから申し込めます。
日本語版のページより、下記URLの方が無難です。
https://www.cisco.com/c/en/us/products/security/stealthwatch/stealthwatch-cloud-free-offer.html

Stealthwatch Cloud Sensor が出力するフロー数が0の状態が続くとLINE Notifyで通知します。

![stealthwatch_cloud-line.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102457/dce74186-6ea9-5f0a-8535-5c5579965935.png)

詳細は下記URLをご参照ください。
https://github.com/t-umeno/stealthwatch-cloud-aws-lambda/blob/master/README.ja.md
BitVisorのSQLite機能を試してみる(storage_io編)

以下の記事でBitVisorに組み込まれたSQLiteを有効にしてビルドして動かす方法が紹介されていました:
https://qiita.com/mmi/items/613bef0fdc6f41d3cb6b

ここではmemoryではなくてstorage_ioのほうを使ってみることにします。QEMUとLinux KVMを使って試します。

# defconfig

ここではconfig.vmm.driver.pciを以下のように設定しておきます:

```
.pci = "driver=ata",
```

# ビルド

これでbitvisor.elfの他、loadvmm.efiとdbgsh*.efiをビルドしておきます。

```
$ make
$ make -C boot/uefi-loader
$ make -C tools/dbgsh-uefi
```

# 準備

適当なディレクトリ(ここでは/tmp)にいくつかファイルを準備しておきます:

```
$ mkdir /tmp/hoge
$ cp bitvisor.elf boot/uefi-loader/loadvmm.efi tools/dbgsh-uefi/*.efi /tmp/hoge
$ dd if=/dev/zero of=/tmp/db count=8192
```

# 実行

```
$ qemu-system-x86_64 -enable-kvm -cpu host -m 1024 -bios OVMF.fd -net none -drive file=fat:/tmp/hoge,snapshot=on -drive file=/tmp/db,format=raw
```

これで、ATAのprimary masterに/tmp/hogeをFATパーティション化したものが見え、primary slaveにraw imageの/tmp/dbが見える形になります。

EFI Shellが起動したらまずloadvmmを実行します:

![20201208-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103733/bef0072e-5626-5ae9-8b9d-56fcfd161862.png)

次にdbgsh-a(for AMD)またはdbgsh-i(for Intel)を実行し、sqliteexampleを実行してデータベースに何か書き込んでみます:

![20201208-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103733/f6a16ef0-fc1a-6462-22cc-cf8b1e284265.png)

Device numberはprimary masterが0, primary slaveが1となりますので、1を指定しています。また、8192セクターのディスク全体を使用することにしたので、Start LBAを0, End LBAを8191としています。Storage sizeは正しく検出されていませんが、気にせず進めます。

そして簡単なSQLにより1から100までの数字が入った簡単なテーブルを作成します。

次に、一度QEMUを終了し、もう一度起動して、中身が残っているかを確認してみます:

![20201208-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103733/6cdf2a90-7c72-0fbe-95de-0e7c8121e48c.png)

大丈夫そうです。QEMUを終了して、disk imageを直接見てみると、以下のようにSQLiteのデータベースらしきものが入っていることがわかります:

![20201208-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103733/ceb164c0-324c-c941-83d0-c4ed1d9f3e87.png)
cordova-inappbrowserでwindow.open()が効かなくなった

## 起こったこと
- cordovaを使ったハイブリッドアプリを実装中のできごと。他SNSでのシェアを、`window.open(url, "_system")`でやっていたが、突然動かなくなる。
- 「あれ？ビルドミスった？」とあわてる。
- いろいろ調べて、[答えらしきもの](https://github.com/apache/cordova-ios/issues/898)にたどり着く

## なんだったのか
- `The window.open clobber was removed in the InAppBrowser v4 release`
- inappbrowserのv4以降では、window.openが使えなくなってるよ、とのこと
- そして`window.cordova.InAppBrowser.open()`をつかってね、とのことでした
- いろいろ調べてみたら[日本語の記事](https://qiita.com/ookishin2018/items/abe20983358f463b4cbc)もばっちりありました〜〜
Windowsでも$ touchがしたい！ ～PowerShellとCMD（コマンドプロンプト）で0byteファイルを作る～

# はじめに

最近、`$ touch`というLinuxコマンドの魅力に取り憑かれているのですが、
同じことをWindows環境でもできないか？と考え、調べてみました。

# この記事でわかること

Windows環境のコンソール（PowerShell, コマンドプロンプト）で、ファイル(0byteファイル)を作成する方法

# 実行環境
Linux：Ubuntu 20.04
Windows：Windows 10

## `$ touch`とは

ファイルの作成、あるいはタイムスタンプの更新を行うLinuxコマンドです。

例えば、`$ touch hoge`というコマンドの実行で、
そのディレクトリにhogeというファイルがなければhogeファイルを生成し、
hogeというファイルが存在していれば、タイムスタンプ（最終更新日時）を更新します。

ここでは前者の『そのディレクトリにhogeというファイルがなければhogeファイルを生成』というところに焦点を絞ります。


# Windows環境でtouchコマンドに相当するものを使うには？

Windowsで使う標準のターミナルは大きく分けてPowerShell, コマンドプロンプトの2種類がありますが、
Linuxにおける`$ touch`（からっぽのファイルを作る）と同じことをしようと思うと、
それぞれコマンドが異なります。


### PowerShellで`$ touch`する

New-Itemコマンドを使います。
例：`New-Item foo.java`

### コマンドプロンプト（CMD）で`$ touch`する

`copy nul`, あるいは`type nul >`を使います。

例
`copy nul foo.txt`
`type nul > foo.txt`

補足
`copy nul`コマンドは読んで字のごとく、本来ファイルのコピーを行うコマンドです。
`type nul`コマンドは指定したファイルを空にするか、存在しなければその名前のファイルを作成するものです。


# 参考

- [Linux標準教科書](https://linuc.org/textbooks/linux/)
- [コマンドプロンプトでファイルを空にするメモ](https://japanrock-pg.hatenablog.com/entry/20080819/1219126642)
- [ファイルをコピーする](https://www.k-tanaka.net/cmd/copy.php)
CSSで色を限りなくゴールドやシルバーに近づける

# どうも7noteです。単色では再現が難しいゴールド。

単色でゴールドをやろうとしても・・・

![e2d06e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/49763a69-aae1-1f31-918e-dd7894bebe7a.png)

単色でゴールドは結構難しいです。というか無理。

## グラデーションでゴールドにする

```css
div {
  background: linear-gradient(45deg, #B67B03 0%, #DAAF08 45%, #FEE9A0 70%, #DAAF08 85%, #B67B03 90% 100%);
}
```

![gold.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/588b30bd-803d-6ef3-57a7-66ef1f19d88e.png)

## シルバーなら・・・

```css
div {
  background: linear-gradient(45deg, #757575 0%, #9E9E9E 45%, #E8E8E8 70%, #9E9E9E 85%, #757575 90% 100%);
}
```

![silver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/dd6752a7-ee9e-ccf3-09df-49fdcfeaeda9.png)


## まとめ

ホームページの製作依頼を受けるときに、たまにゴールドを使いたいという要望が出たりするので、作り方は覚えておくといいかも。


**参考**
https://1-notes.com/css-text-metal-design/
https://encycolorpedia.jp/ffd700
ローカルにデータを保存する３つの方法（Android）

# はじめに

Androidアプリでローカルにデータを（永続的に）保存する３つの方法を本記事にまとめる。
備忘録程度
以下が３つの方法である。
1. Preference
2. ローカルファイル
3. SQLite

[サンプルコード](https://github.com/seaka829/SaveLocally_Android)

## 1. Preference
Preferenceは、データを**キー**と**値**で保存する
boolean、int、float、long、Stringの5つの型で値を保存できる
↓ String型の値を保存する場合のサンプルコード

```Preference.java
    // PreferenceでString型のデータを保存する
    private void save(String key, String value) {
        SharedPreferences pref = getContext().getSharedPreferences("pref", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = pref.edit();
        //putXXXメソッドを使用して値を保存する(XXXには型が入る)
        editor.putString(key, value);
        editor.commit();
    }

    // Preferenceで保存したデータを取得する
    private String load(String key) {
        SharedPreferences pref = getContext().getSharedPreferences("pref", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = pref.edit();
        //getXXXメソッドを使用して保存した値を取得する(XXXに型が入る)
        return pref.getString(key, null);
    }
```

↓ Preferenceでのデータ保存の画面イメージ
![preference.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/af121463-4512-ce4d-d777-ccec7cccac4c.png)


## 2. ローカルファイル
javaの**OutputStream**、**InputStream**を利用してデータをローカルファイルに保存する
↓ テキストファイルでデータを保存する場合のサンプルコード

```Localfile.java
    // ローカルファイルにデータを保存する
    private void save(String text) {
        try {
            OutputStream out = getContext().openFileOutput("test.txt", Context.MODE_PRIVATE);
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
            writer.append(text);
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // ローカルファイルのデータを取得する
    private String load() {
        String text = "";
        try {
            InputStream in = getContext().openFileInput("test.txt");
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
            String buf;
            while((buf = reader.readLine()) != null){
                text += buf + "\n";
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return text;
    }
```

↓ ローカルフォルダを利用したデータ保存の画面イメージ
![localfile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108396/e71f1ff4-5455-cbe2-f2ba-003815a55f71.png)

## 3. SQLite
アプリ内に軽量なDBを作り、そこでデータを保管する方法。
長くなるので、別途記事にまとめる。
【notepad++/jN plugin】Dialog.jsちょっと修正(styleエラー対応)

Jacop です、お久しぶりです。

今回は、notepad++ jN plugin の Tests>Show Dialog でエラーが出るので、その対策を。

前提条件として、jN plugin インストール済みであること。
notepad++ は portableapp版v7.8.5 で確認したよ。
jN plugin は ver2.2.185.6 で確認したよ。

## 修正箇所
\Notepad++\plugins\jN\jN\includes\Dialog.js 20行目を以下のように変更。

```javascript
styles.styleSheet.cssText = this.cfg.css || '\nbody {overflow: auto;}\n';
↓
styles.style.cssText = this.cfg.css || '\nbody {overflow: auto;}\n';
```

## 原因
styleSheet.cssText はIE10以前でしか動かないのでエラーとなる。


以上。
DroidScriptを(windows10)NoxPlayerでインストールして、自作javascriptを実行してみた。

インストールして大丈夫でしょうか？
(参考)NoxPlayerに危険性はある？利用時に考えられる3つの可能性
https://mayonez.jp/topic/1088522


###環境:
windows10
NoxPlayer バージョン7.0.0.7　2020/11/27
DroidScript バージョン1.80(Android 要件4.1 以上) 更新日2020年1月20日

###自作javascript:
DroidScriptで、3行3列のボタンのレイアウトをループや配列を使って、短くなりますか?
https://ja.stackoverflow.com/questions/72486/droidscript%e3%81%a7-3%e8%a1%8c3%e5%88%97%e3%81%ae%e3%83%9c%e3%82%bf%e3%83%b3%e3%81%ae%e3%83%ac%e3%82%a4%e3%82%a2%e3%82%a6%e3%83%88%e3%82%92%e3%83%ab%e3%83%bc%e3%83%97%e3%82%84%e9%85%8d%e5%88%97%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6-%e7%9f%ad%e3%81%8f%e3%81%aa%e3%82%8a%e3%81%be%e3%81%99%e3%81%8b?noredirect=1&lq=1
[Rails] モデルの作成方法

役割
---
モデルの役割はデータベース・テーブルを使って**「データを操作・管理する」**ことです。


作成方法
---

```ターミナル
rails　g　model　モデル名
```

モデルや、それに付随するファイルを一度に作成できるコマンドです。

モデルの命名規則は**単数形を使用する**です。
なので、商品の情報を管理する場合は「product」のように命名しましょう。
GA基礎の用語解説

# 概要
GoogleAnaliticsに関する用語の基礎を解説する。

# ユーザ
ユニークな同一アクセスのことであり、Cookieによって判別されている。
Cookieで判断しているため、1人が異なるブラウザやデバイスで2回サイトをアクセスした場合、ユーザ数は2となる。

## 新規ユーザとリピータ
### 新規ユーザ
過去2年以内にサイトを法申したことが無いユーザ
### リピータ
過去2年以内にサイトを訪問したことがあるユーザ
### 注意点
とある新規ユーザが10時にサイトアクセス➡同日の14時にまたサイトアクセス
という動作があった場合、新規ユーザ１、リピータ１とカウントされる。
新規ユーザ数＋リピータ数 ≠総ユーザ数　となるので注意。

# セッション
ユーザがサイトに対して行った一連の動作のこと。

1. サイトにアクセス
1. 色々と遷移
1. 商品購入
1. 商品閲覧

という一連の流れが総じて1セッションとなる。

セッションの「終わり」には複数のパターンがある。
## セッション終わりパターン
### 1.30分間新規行動が見られなかった場合
12:00にサイト訪問⇒12:10に行動完了⇒12:40まで同一ユーザの操作が見られなかった場合、1セッションとなる。
この際のセッション時間は
**12:00～12:10**
の10分間となる。

### 2．日をまたいだ場合
23:55にサイト訪問⇒24:05に別ページに遷移⇒24:10に操作終了した場合、2セッションとなる。
この際のセッション時間は
**23:55~23:59**
**24:05~24:10**
の2つとなる。

### 3．異なる参照元、メディア、キャンペーンで再アクセスした場合
異なる参照元、メディア、キャンペーンで再アクセスした場合、一度セッションが途切れる。
12:00にメルマガ経由でサイトにアクセス⇒12:10にTwitterから再度サイトにアクセス⇒12:20に操作終了した場合、
この際のセッション時間は
**12:00~12:09**
**12:10~12:20**
の2つとなる。

### 注意点
夜間アクセスが多いサイトは「2.日をまたいだ場合」の影響を大きく受ける。24時付近は「セッション時間が小さな値になる、セッション量が他時間より増える。」などがありうるので考慮する事。夜間のアクセス解析には、GAを使わずサーバのアクセスログを見るなどの工夫も必要。

# ページビュー
サイト内のページの表示された数のこと。
異なるページへの遷移はもちろん、戻るボタンのクリック、リロードでもカウントされる。
また、トラッキングコードを仕込めば、ページ遷移が無くともページビューとしてカウント可能。
逆に言えば、トラッキングコードを多重発火できるように仕込んでしまうと、ページビューとして多重カウントされるので注意が必要。

# セッション時間
1セッション毎の「セッションの開始」から「セッション終わり」までの時間のこと。

例えば

- サイトトップアクセス：　12:00
- 商品ページへ遷移　　：　12:05
- 商品ページを1時間熟読し、離脱

としたユーザがいた場合のセッション時間は「5分」となる。
最終ページの滞在時間は含まれない。
そのため、直帰セッションのセッション時間は0秒となる。

## 平均セッション時間
セッション時間/セッション数で算出される値。

- 10分間のセッション時間を持つセッション
- 20分間のセッション時間を持つセッション
- 30分間のセッション時間を持つセッション


の平均セッション時間は20分だが

- 10分間のセッション時間を持つセッション
- 20分間のセッション時間を持つセッション
- 30分間のセッション時間を持つセッション
- 直帰セッション

の平均セッション時間は15分となり、大幅に数字が低下する。

せり上がり広告流入ユーザなど、サイトに対する関心が低いユーザセグメントを含めると平均セッション時間はおのずと低下するので、セッション時間を評価する時はセグメントに注意が必要。

## 平均ページ滞在時間
ページ毎のセッション時間であり、全ユーザのページページ滞在時間/PV数で算出される値。

- サイトトップアクセス：　12:00
- 商品ページへ遷移　　：　12:05
- 商品ページを2時間熟読し、離脱

の場合、
サイトトップの滞在時間は5分
商品ページの滞在時間は0秒

となる。


この例で言うと、商品ページは滞在時間が短いのでエンドユーザは「商品ページを見ていない」
　→「商品ページのコンテンツを増やしてみよう。」というのは間違いの可能性が高い。

## 離脱率

任意のページに対する離脱数をそのページのPV数で割った値
ユーザは絶対にいつかはサイトから離脱するので、全セッションに対する全ページの離脱率合計は100%となる

ページがたくさんあると相対的に離脱率の値が小さくなるので、「新規ページを増やしたら〇〇というページの離脱率が下がった。導入効果があった！ 」は偽の可能性あり。分母が増えて数字が減っただけかも。

# コンバージョン率
コンバージョン数/総セッション数で算出される値。
また、コンバージョン数の定義自体が「コンバージョンに至ったセッション」というセッション目線の話なので
「1セッションで2回目標を達成してもコンバージョン数が1」と算出される点に注意。

例
コンバージョン＝とあるページ到達（資料請求ページなど）とした場合、「1セッションで3回、該当ページ到達」をするようなユーザがいた場合、コンバージョン数１だが、とあるページ自体のPV数は3となる。
マンガでわかる蛇足(ボートアンカー)ミニアンチパターン

![CA5D633C-74F3-4C32-937F-202E1C14E202.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/9b6690d8-f9ab-2253-327f-76b86788e819.png)
http://wiki.c2.com/?BoatAnchor

あったらむしろ台無しで使い物にならないものを導入してしまうケースを表すパターンです。

よくわからないうちから、宣伝文句に踊らされて技術製品を採用してしまうと、結局使い物にならずにモノだけが残ってしまいます。そうならないためには、まず、自分が開発しようとしているものをしっかり理解し、理性的に判断することが大切です。
エンジニア社長の元に未経験エンジニアが就職して感じたこと

AdventCalendar8日目です〜。
今年も終わりが近づいてきましたね。
ささっとゆる〜く書いていきますのでブレークタイムに流し読んでって下さい。

# 概要
エンジニア社長の元に弟子入りして感じたメリットデメリット、どんな人が向いてそうかなんてことを書きます。
中小企業(その中でも小規模企業者)とかスタートアップみたいに規模小さめの会社に就職しようと考えてる人へ少しでもイメージを持ってもらえればいいかな〜。

# お前誰や、どんな会社や
プログラミングスクールRUNTEQの卒業生です。
卒業後フリーランス社長の元に弟子採用みたいな形で就職。
社長と私の二人で稼働している受託会社です。
就職して4ヶ月が経過しました。

# メリット
### 社長の仕事や考え方を間近で見聞きできる
エンジニア出身社長ならではの、圧倒的エンジニアリング力をバックボーンにした営業は圧巻です。
会社の意思決定を持った人同士の商談になるので非常に勉強になります。
どういったことを考えて話しているのか聞けるのは距離が近く小さい会社ならではのメリットかなと感じています。

### 上流工程から下流工程まで経験できる
「この問題解消しといて！」って感じでタスクを振られることがよくあります。
クライアントが求めているシステムの内容を咀嚼し、要件に落とし込みチケットを作成し実装し...みたいなことを早い段階で経験できます。
規模は小さいですが、上下流工程を一貫してやらせてもらうことで要件定義だけしたら他のエンジニアに開発お願いするみたいなこともできるようになりPM業務的なことを早くから経験できます。

# デメリット

### コードレビューはないものと思った方が良い
そのまんまです。
小さな会社は一人一人が忙しいので他の人をみる余裕はないです。

### 稼働時間長くなりがち
うちもそうですが裁量労働制をとっている所が多いようです。
新人のうちは実装に時間がかかりますので必然的に稼働時間長くなります。
1年くらいはプライベート捨てる覚悟決めちゃった方が逆に気が楽かも。(私はプライベート捨てました)

# 向いてる人
PMとか後々上流工程の業務を目指している人は向いている気がします。

# 向いてない人
開発業務をずっとしていたい人とかプライベートの時間を大切にしたい人は向いていない気がします。

# 最後に
自分のキャリアをどうしたいのかによって選ぶ企業変わると思いますので就活前に固めておくことをオススメしておきます。
駆け足になってしまいましたがこれで終わります。
もっと詳しく聞きたいって方いればRUNTEQのイベントなんかで話しましょう！