OmniAICreator/Qiita-1.07M huggingface dataset:
Reduxを学ぶメリット


Reduxつらい問題ってありますよね。
ちょっとした実装がしたいだけなのに、Reduxだとやたら量を書かないといけなかったりする。
「action? dispatch? reducer? 色々と学ぶことが多くて大変そう」と思う方もいらっしゃるでしょう。
今回はそんなReduxに尻込みしている初学者の方に送るReduxのメリットについての話です。

#メリット① redux-devtools-extention便利すぎ
Reactを書くときにいろんなところにconsole.logをしかけて、いちいち挙動を確認しているとしたら、redux-devtools-extentionはそんなあなたの手間を劇的に削減することでしょう。
redux-devtools-extentionを使うためにReduxを書いているといっても過言ではありません。
いやさすがにそれは言い過ぎました。（どっちやねん！）
何はともあれ、redux-devtoolsは非常に便利ですのでReduxを使ってみましょう
下記の記事をご参照ください。
https://qiita.com/elzup/items/fc24588b2c6bae0834a6

#メリット② 大きめのプロジェクトを管理しやすい
あなたはこう言うでしょう。
「簡単なことがしたいだけなのに！10行で書けることがReduxだと30行にも40行にもなるよ！」
その気持ち、ぐぅわかるよ。。。
Reduxのメリットは、大きめのプロジェクトでReduxを使ったことがある人にしかわからないものです。

そうReduxは大きくなればなるほどその力を発揮するものであって、
個人で開発するWebアプリにとってはほぼ例外なくオーバーキルです。
しかし、いざ大規模の開発となるとReduxは輝きます。
そのときに向けて個人開発で予行演習しておくことを強く推します。


#メリット③ 綺麗なコードについて考えるようになる
②とも共通することですが、Reduxで書くとそうでないときより読みやすくなることが多いです。
なぜなら、Reduxというのは単に状態管理のライブラリではなく、コードを体系的に書くための１個の考え方でもあるからです。（あくまで個人的な意見ですが。）
Reduxを勉強する過程で、綺麗なコードを書くための先人たちの知恵や思想に数多く出会うことでしょう。
それはducksかもしれないし、re-ducksかもしれないし、presentational-componentsとcontainer-componentsを分離させることかもしれません。
それが何であれ、その考え方自体は、いつかReduxが別のライブラリにとって代わられたとしても、一個の思想として残り続ける価値のあるものだと思います。

もし「immutableってどういうことだ？」「ディレクトリ構成ってどうやったらいんだ？」などと考えたことがあるなら、それはReduxを学ぶための最良のチャンスですよ！


#余談：HooksもいいけどReduxもいいよ
最後に余談。
Reduxに代わるものとしてReact界隈だと昨今はHooksに注目が集まっています。
「useContextなら関数も渡せるしReduxみたいな面倒なこともない」という意見もあります。
それでもReduxを推してみたい私です。
Reduxは必ずしもスマートではないかもしれませんが、やはり数の暴力といいますか、ちゃんとした情報がいろいろ落ちていたり、Reduxを強力にサポートするツールやライブラリが盛りだくさんだからです。
筆者は個人的にreact-redux-firebaseというreduxとfirebaseを良い感じに併用可能にしてくれるツールが好きで愛用しています。

「大変だけどHooksもReduxも両方学ぶのがベストだよ！」というのを今回の結論とさせてください！


#Let's get Started!!
幸いにしてQiitaにはReduxのを学ぶための良記事があるので、まずはそれから始めてはいかがでしょう。
下記にリンクを貼っておきます。
https://qiita.com/mpyw/items/a816c6380219b1d5a3bf
SharePointer が幸せになれるツール紹介

本投稿では、SharePoint 開発者や SharePoint をデータストアとして活用する Power Platform 開発者の方々が幸せになれるツールを２つ紹介します。

# SharePoint Online Client Browser
[bramdejager/spcb](https://github.com/bramdejager/spcb/releases)

SharePointer の方はインストールして損はない必須級（と筆者が勝手に思ってる）ツールです。
非表示コンテンツを含む、（ほぼ）すべての SharePoint コンテンツを視覚的に、そして簡潔に閲覧することができます。
普段目にしない非表示プロパティを眺めてるだけで、色々な発見があるのでとても楽しくなります。

筆者の最近の使用用途は…

- Microsoft Graph で SharePoint にアクセスする際に必要なサイトコレクションIDとサイトIDを確認するとき
- ビューに設定したフィルター条件、グループ条件などが含まれた CAML が欲しいとき（ViewQuery）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89309/c200d740-a44b-cefb-f760-9d96bb302f3c.png)

# SharePoint Search Query Tool
[SharePoint/PnP-Tools](https://github.com/SharePoint/PnP-Tools/releases)

SharePoint 検索 API を簡単に検証・実行できるツールです。
検索条件をチェックボックスでぽちぽち選んでいくと、勝手に検索 URL が生成されるのでとても助かります。
もちろん開発テナントに接続して実行して結果を確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89309/a734802f-725f-9a9c-4f1d-cc62669278d9.png)

# 最後に
他にオススメなツールがあれば教えていただけると筆者が泣いて喜びます
✌('ω'✌ )三✌('ω')✌三( ✌'ω')✌
Linuxサーバからリモートリポジトリにpush & リモートリポジトリからローカルPCにclone

######目標
 - linuxサーバ上で運用されているrailsアプリのソースコードをGitlab.comのリモートリポジトリにプッシュする。
 - リモートリポジトリからローカルPCのローカルリポジトリにクローンする。

######環境
- linux(GCE, Debian)
- Gitlab.com
- Mac(OSX 10.15.2)


######準備：git install (linuxサーバ、ローカルPCにGitをインストール）
下記サイトなどを参考にしてください。
https://git-scm.com/book/ja/v2/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-Git%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

######1. linuxの操作

######git config(USER_NAMEとEMAILは環境による)
```Bash:ターミナル
git config --list
git config --global user.name "USER_NAME"
git config --global user.email "EMAIL"
```
######ファイル権限(USERNAMEとUSERGROUPは環境による)
権限を間違えるとgit push時に権限エラーになります。

```Bash:ターミナル
sudo chown -R USERNAME:USERGROUP ./
sudo find ./ -type d -exec chmod 755 {} +
sudo find ./ -type f -exec chmod 644 {} +
```
######SSH鍵(gitlab_rsaは好きな名前をつける)
- 秘密鍵は~/.ssh/に置いてください。
- .pubの内容をGitlab.comのユーザーのssh鍵に貼り付けてください。

```Bash:ターミナル
ssh-keygen -t rsa -f gitlab_rsa

mv ./gitlab_rsa ~/.ssh/
mv ./gitlab_rsa.pub ~/.ssh/
cat gitlab_rsa.pub 
=>.pubの内容をGitlab.comに貼り付け

eval $(ssh-agent -s)

ssh-add ~/.ssh/gitlab_rsa

ssh -T git@gitlab.com
```

######git init ~ git pushまで(:repoは環境による)
gitコマンドの詳細の説明は省略します。
サーバのローカルリポジトリを初期化+初期コミットして、リモートリポジトリにプッシュしています。

```Bash:ターミナル
git init

vi .gitignore 
=>rails用のテンプレートから持ってくるとラク

git add .

git commit .

git remote add origin git@gitlab.com:repo

git push origin master
```

######2. ローカルPC操作

######プロジェクト用ディレクトリ作成(好きな名前のディレクトリを作成する)
```Bash:ターミナル
mkdir Gitlab
```
######SSH鍵(gitlab_rsa_userは好きな名前をつける)
- 秘密鍵は~/.ssh/に置いてください。
- .pubの内容をGitlab.comのユーザーのssh鍵に貼り付けてください。

```Bash:ターミナル
ssh-keygen -t rsa -f gitlab_rsa_user

mv gitlab_rsa_user ~/.ssh/

mv gitlab_rsa_user.pub  ~/.ssh/

cat gitlab_rsa_user.pub
=>Gitlabに貼り付け

eval $(ssh-agent -s)

ssh-add ~/.ssh/gitlab_rsa_user

ssh -T git@gitlab.com
```
######git config(USERNAMEとEMAILは環境による)
リモートリポジトリからローカルPCのローカルリポジトリにクローンしています。

```Bash:ターミナル
git config --global user.name "USERNAME"
git config --global user.email EMAIL
```

######git clone(/repo.gitは環境による)
```Bash:ターミナル
git clone https://gitlab.com/repo.git
```
######bundle ~ rails sまで

ローカルPCにクローンしてきたディレクトリでbundleとrails sが実行可能か確認する。
サーバ環境と同じrubyバージョン、railsバージョンで実行すると環境依存のエラーを回避できる。
rbenvを使用するとプロジェクトディレクトリ毎にrubyバージョンを指定できるのでラク。
windowsでrbenvを使用する場合は、wslを有効化してubuntuターミナル上で作業する。
参考：
https://qiita.com/chimame/items/8130aa2c07a152a865b1

エラーが出たらエラーメッセージを読んで不足するファイルをサーバから直接持ってくる。
(.gitignoreで指定したファイルはgit管理から外れるため。)


```Bash:ターミナル
bundle

rails s
```
俺的Kotlinリファレンス綿

javaと比べながら書きます。
#変数宣言

java

```java
//例 int型
int num = 1;
final int num = 1;
```
kotlin

```kotlin
//例 int型
var num = 1
val num = 1
//明示的に型を制限する場合
var num:Int = 1
TerraformでECSにEFSマウント

以下をベースに

>チュートリアル: Amazon ECS での Amazon EFS ファイルシステムの使用 - Amazon Elastic Container Service
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/using_efs.html

## 1. クラスタ構築

### 1-1. EFSつくる

```tf
resource "aws_efs_file_system" "app" {
  tags = {
    Name = "app"
  }
}

resource "aws_efs_mount_target" "app" {
  count = length(module.vpc.public_subnets)
  file_system_id  = "${aws_efs_file_system.app.id}"
  subnet_id       = element(module.vpc.public_subnets, count.index)
  security_groups = ["${aws_security_group.default.id}"]
}
```

例。変数は適宜設定。

### 1-2. ECSクラスタつくる

```tf
resource "aws_ecs_cluster" "app" {
  name = "myapp"
}
```

### 1-2. ユーザーデータ

```bash:cloudinit-ecs.tpl
#!/bin/bash
# Set any ECS agent configuration options
echo "ECS_CLUSTER=${ecs_cluster_name}" >> /etc/ecs/ecs.config
```

↑クラスタ名設定用テンプレート

```bash:cloudinit-ecs-efs.tpl
# Install amazon-efs-utils
cloud-init-per once yum_update yum update -y
cloud-init-per once install_amazon-efs-utils yum install -y amazon-efs-utils

# Create /efs folder
cloud-init-per once mkdir_efs mkdir /efs

# Mount /efs
cloud-init-per once mount_efs echo -e '${efs_id}:/ /efs efs defaults,_netdev 0 0' >> /etc/fstab
mount -a

```

↑EFSマウント用テンプレート

```tf
data "template_file" "container_instance_base_cloud_config" {
  template = "${file("cloudinit-ecs.tpl")}"

  vars = {
    ecs_cluster_name = "${aws_ecs_cluster.app.name}"
  }
}

data "template_file" "container_instance_efs" {
  template = "${file("cloudinit-ecs-efs.tpl")}"

  vars = {
    efs_id = "${aws_efs_file_system.app.id}"
  }
}

data "template_cloudinit_config" "container_instance_cloud_config" {
  gzip          = true
  base64_encode = true

  part {
    content_type = "text/x-shellscript"
    content      = "${data.template_file.container_instance_base_cloud_config.rendered}"
  }

  part {
    content_type = "text/cloud-boothook"
    content      = "${data.template_file.container_instance_efs.rendered}"
  }
}
```

上記によりmultipartで設定される。

### 1-3. Launch templateにユーザーデータ設定

```tf
resource "aws_launch_template" "container_instance" {
  # ...
  user_data = "${data.template_cloudinit_config.container_instance_cloud_config.rendered}"
}
```

### 1-4. AutoScalingでEC2たてる

省略

## 2. ECSのTask Definitionでvolumeマウント

チュートリアルのまま。
以下チュートリアル内の例。

```json
{
  "containerDefinitions": [
    {
      "memory": 128,
      "portMappings": [
        {
          "hostPort": 80,
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      "mountPoints": [
        {
          "containerPath": "/usr/share/nginx/html",
          "sourceVolume": "efs-html"
        }
      ],
      "name": "nginx",
      "image": "nginx"
    }
  ],
  "volumes": [
    {
      "host": {
        "sourcePath": "/efs/html"
      },
      "name": "efs-html"
    }
  ],
  "family": "nginx-efs"
}
```
EmbulkでConfig読み込み時にエラー(Can not deserialize instance of java.lang.String out of START_OBJECT token)

# 環境
embulk 0.9.17

# 現象

EmbulkでConfig読み込み時にエラー

```
org.embulk.exec.PartialExecutionException: org.embulk.config.ConfigException: java.lang.IllegalArgumentException: Can not deserialize instance of java.lang.String out of START_OBJECT token
```

# 原因

liquidのinclude構文を使っていたが、template側のsyntaxが間違っていた。

読み込んでいた親ファイル

```foo_parents.yml.liquid
{% include 'foo_input', file_path: '/path/to/' %}

filters:
（以下略）
```

子ファイル

```_foo_input.yml.liquid
in:
    type: file
    path_prefix: { file_path }
    last_path: foobar.csv
（以下略）
```

`_foo_input.yml.liquid` の変数部分 `{ file_path }` が間違っていて、 `{{ file_path }}` (2重カッコ)が正しい。
関数のキーワード引数とデフォルト引数

```py
def player(job='戦士', weapon='鋼の剣', money='2600'):
    print('職業は' + job + 'です。')
    print('武器は' + weapon + 'です。')
    print('所持金は' + money + 'ゼニーです。')
    print()
    
player()
player(weapon='木の杖', money='2500', job='魔法使い')
player(job='勇者', money='14500')
```

```:実行結果
職業は戦士です。
武器は鋼の剣です。
所持金は2600ゼニーです。

職業は魔法使いです。
武器は木の杖です。
所持金は2500ゼニーです。

職業は勇者です。
武器は鋼の剣です。
所持金は14500ゼニーです。
```

player()ではデフォルト引数
job='戦士', weapon='鋼の剣', money='2600'が入る。

player(weapon='木の杖', money='2500', job='魔法使い')では
キーワードにそって引数が入る。

player(job='勇者', money='14500')では、
job='勇者', money='14500'となり
指定のないweaponはデフォルト引数'鋼の剣'となる。
Riot.js で純粋なコンポーネント(riot.pure)を使用する

## riot.pure

Riot v4.8.0で`riot.pure`が追加されたので使ってみます。

コンポーネントのレンダリングを自分で制御したい場合に、`riot.pure` を使うことで Riot.js の内部ロジックをスキップすることができるようです。
内部ロジックがスキップされる為、HTMLとCSSは使えません。

## 基本動作

riot.pureを使って`mount`、`update`、`unmount`のメソッドを含んだオブジェクトを返すモジュールを登録します。

```html:pure.riot
<my-pure>
  <script>
  import { pure } from 'riot'

  export default pure(({ slots, attributes, props }) => {
    console.log(slots, attributes, props);
    return {
      el: null,
      mount(el, context) {
        this.el = el;
        console.log("mount", el, context);
        this.el.innerHTML = 'Hello There';
      },
      update(context) {
        console.log("update", context);
      },
      unmount(preserveRoot) {
        console.log("unmount", preserveRoot);
        this.el.parentNode.removeChild(this.el);
      }
    };
  });
  </script>
</my-pure>
```

`pure`で受け取れる内容は以下の３つ
1. `slots` - コンポーネント内で見つかった slot リスト
2. `attributes` - コンテキストからコンポーネントプロパティを推測するために評価可能なコンポーネントの属性式
3. `props` - riot.component 呼び出しによってのみ設定できる初期コンポーネントユーザープロパティ

pureの対象となるエレメントはマウント時にしかもらえないため、`this.el`に保持しています。

pureコンポーネントの使用はこんな感じで。

```html:app.riot
<my-app>
  <p>{ props.message }</p>
  <my-pure></my-pure>
  <input type="button" value="update" onclick="{ pre_update }">
  <input type="button" value="unmount" onclick="{ pre_unmount }">

  <script>
    import { unmount } from 'riot'

    export default {
      pre_update(e) {
        this.update();
      },

      pre_unmount(e) {
        unmount('my-pure');
      }
    }
  </script>
</my-app>
```
```javascript:index.js
import { component,register } from 'riot'
import App from './app.riot'
import Pure from './pure.riot'

register('my-pure', Pure);

component(App)(document.getElementById('root'), {
  message: 'Hello World'
});
```

## 試してみる…がunmount時に反応しない？ -> <追記あり v4.8.7で修正済み>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27443/fcfc1066-5465-4c35-588f-0697adc903f2.png)

どうやら、unmountの動きとしてriot-componentを持っていないとunmountを呼び出してくれないようです。

・動作確認用
https://plnkr.co/edit/sPjH1JE9zeLPErMBysx8?p=preview

というわけで、初めてのプルリクとやらをしてみました。1発ミスったのは内緒。
https://github.com/riot/riot/pull/2801

修正内容はいたって簡単で、持っていないなら持たせればいいじゃない、の精神。

```javascript:riot/src/core/component.js 
  return createCoreAPIMethods(method => (...args) => {
    component[method](...args)
    args[0][IS_PURE_SYMBOL] = component // ここ追加
    return component
  })
```
```javascript:riot/src/riot.js
export function unmount(selector, keepRootElement) {
  return $(selector).map(element => {
    if (element[DOM_COMPONENT_INSTANCE_PROPERTY]) {
      element[DOM_COMPONENT_INSTANCE_PROPERTY].unmount(keepRootElement)
    // ↓ ここ追加
    } else if (element[IS_PURE_SYMBOL]) {
      element[IS_PURE_SYMBOL].unmount(keepRootElement)
    }
    return element
  })
}
```

**1/20 追記**
プルリクは却下されてしまいました(さすがに修正内容が安直すぎた)が、Issueで修正してもらえました！
https://github.com/riot/riot/issues/2806

v4.8.7でunmountもRiot.jsから呼んでもらえるようになっています。

## まとめ
これを使えば複数のコンポーネントで使いまわせる共通の処理とか書けそう。
AtCoder AGC 041 C - Domino Quality　の全探索でハマった

# 概要

- N=7,Quality=3の時のドミノの置き方の探索にかなり時間がかかった
- $2^{49}\fallingdotseq 10^{15} $の探索を実装するときは、うまく枝を刈る必要がある
- PythonはC++よりも条件によっては20倍以上遅い

# pythonでN=7,Quality=3の場合の置き方の探索をした時

(0,0)からドミノを置いて試していく。試す順番は
1.縦向き
2.横向き
3.置かない

これで適した配置１つを見つけるのに **約740[s]** かかった。

```findPattern.py
import sys
import numpy as np
import datetime

sys.setrecursionlimit(10 ** 7)


def cntQuality(N, grids, num, axis):
    q = 0

    if axis == 0:
        g = grids[num, :]
    else:
        g = grids[:, num]

    last = -1

    for i in range(N):
        d = g[i]

        if last == d or d == 0:
            continue

        q += 1
        last = d

    return q


def dfs(N, grids, pos, num, q):
    x = pos // N
    y = pos % N


    if y == 0 and x != 0:
        qx = cntQuality(N, grids, x-1, 0)
        if qx != q:
            return False

    # end grids
    if x == N and y == 0:
        # valid
        for i in range(N):
            qy = cntQuality(N, grids, i, 1)
            if qy != q:
                return False
        return grids

    # not yet
    pos += 1

    # put vertical
    if y < N-1 and grids[x][y] == 0 and grids[x][y+1] == 0:
        v_num = num + 1
        # v_grids = copy.copy(grids)
        grids[x][y] = v_num
        grids[x][y+1] = v_num
        g = dfs(N, grids, pos, v_num, q)
        if g is not False:
            return g
        grids[x][y] = 0
        grids[x][y+1] = 0

    # put horizontal
    if x < N-1 and grids[x][y] == 0 and grids[x+1][y] == 0:
        h_num = num + 1
        # h_grids = copy.copy(grids)
        grids[x][y] = h_num
        grids[x+1][y] = h_num
        g = dfs(N, grids, pos, h_num, q)
        if g is not False:
            return g
        grids[x][y] = 0
        grids[x+1][y] = 0

    # dont put domino
    g = dfs(N, grids, pos, num, q)
    if g is not False:
        return g

    return False


start = datetime.datetime.now()
print("start", start)


N = 7
q = 3
grids = np.zeros((N, N))
g = dfs(N, grids, 0, 0, q)
end = datetime.datetime.now()
print("end", end)

print(g)
```

```実行結果.txt
start 2020-01-07 18:13:18.477510
end 2020-01-07 18:22:35.768316
[[  1.   1.   2.   2.   3.   3.   0.]
 [  4.   4.   5.   5.   6.   0.   0.]
 [  7.   7.   0.   0.   6.   8.   8.]
 [  0.   0.   9.  10.   0.   0.  11.]
 [  0.   0.   9.  10.   0.   0.  11.]
 [  0.   0.   0.   0.  12.  13.  14.]
 [  0.   0.   0.   0.  12.  13.  14.]]
```


# なんで740[s]もかかったのか？

探索する順番が悪かった模様。

1.横向き
2.縦向き
3.置かない

で探索した場合、1[s]以内で配置が見つかった。
おそらくこの探索順の場合、合致する枝が近くにあるのだろう。

# PythonとC++でいくつかパターンを試してみた

※手元で一度しか試してないので、ブレがあると思います

|探索順|Python|C++|
|---|---|---|
|横->縦->なし|100[ms]|5[ms]|
|縦->横->なし|740[s]|17[s]|
|なし->横->縦|430[ms]|10[ms]|


# 結論

- うまく枝刈りできないと、探索順によってはかなり時間の差が生まれる
- このくらいのオーダーだとPythonよりC++を使った方が良さそう
基本情報技術者　テクノロジ系　第2章 コンピュータ構成要素とハードウェア

[基本情報技術者試験](https://qiita.com/savaniased/items/d3f94da4f087e178cb69)
こちらより

続いて2章をざっくりと

# ハードウェア
入力装置
記憶装置
出力装置この3点が基本で

演算装置と制御装置でサポートしながら動かす形です。

# CPUの動作

1,命令フェッチ:メモリから命令取得
2,デコード：命令解読回路指定
3,オペランドフェッチ:メモリから対象データ取得
4,実行
5,結果書込み

※メモリからデータ取得

# CPUの構成要素

レジスタ: データの保持

ALU: 四則演算、論理演算
アキュムレータ: 計算結果保持

# CPU構造

CISC: 多機能,マイクロプログラム
RISC: 基本的な命令のみ,ワイヤードロジック制御

# パイプライン

CPU動作で休むことなく、命令を順次実行していくこと

## ハザード
要はエラー

# マルチコアプロセッサ

一つのCPUに複数のCPUが入ってるのをいいます。

2つでデュアル
4つでクアッド

#　オペランド

記憶やレジスタのアドレス

## アドレッシングモード

アドレスの指定方法のこと

# 割込み
CPU処理の割込み対応について

## 内部割込み
システム的な割込み
エラーやOSなど

## 外部割込み
ハードウェアや指定時間の超過

# メモリ


## ROM
永続記憶

## RAM
早いけど消える

## DRAM
主記憶に使用
リフレッシュ必要
低速・大容量

コンデンサを集積して作成

## SRAM
フリップフロップ(トランジスタ回路)のためリフレッシュ不要
キャッシュメモリに使用

## パリティ
1ビットの誤りを検出

## ハミング
1ビットの誤りを検出して修正
2ビットの誤りを検出

## 実行メモリアクセス時間

ヒット率x(キャッシュメモリのアクセス時間)　+ (1-ヒット率)x(主記憶のアクセス時間)

```
ヒット率:
必要とするデータがキャッシュメモリに存在する確率のこと
```

## データ書込み

ライトスルー: キャッシュメモリと主記憶の両方に書き込む
ライトバック: キャッシュメモリにだけ書きこみ、追い出されれる時に主記憶に書きこむ

## メモリインタリーブ
主記憶をバンク(区画)に分けて処理する方式

# ハードディスク

シリンダ: これが複数枚でハードディスクが構成
トラック: シリンダの輪
セクタ: トラックの1部分

## アクセス時間

アクセス時間= 

平均シーク時間(位置決め)+
平均回転待ち時間(1/2回転する時間)+
データ転送時間[(読込データサイズ/1トラックのサイズ)x1回転する時間]

で構成されます。

## RAID

複数台のハードディスクを束ねる方法

RAID-0: ストライピング　分割
RAID-1: ミラーリング　　コピー
RAID-5: ストライピングとパリティ(分散バックアップ)
application_helperを使う

長くてみにくかったviewの記述を`application_helper.rb`に移動させて`content_tag`と言うものを使ってhtmlタグを生成する

`content_tag`について
参考: https://qiita.com/yusaku_/items/d6e98b77124131e628fb



```rails/app/helpers/try_helper.rb
  def discount_text(service, provider)
    discount_price = provider.key == "noe-jx-group" ? service['discount'].to_f : service['discount'].to_i
    discount_from_energy = if SetPlan.is_discount_from_energy?(service)
      "/kWh"
    elsif SetPlan.yearly?(service)
      "/年"
    elsif SetPlan.monthly?(service)
      "/月"
    end
    content_tag(:div, class: "e__saving") do
      content_tag(:span, "割引額", class: "e__tag") + content_tag(:span, discount_price, class: "e__number e__deals" ) + "円" + discount_from_energy
    end
  end
```



```rails/app/views/try/_set_discount.html.erb
 // 修正前
<div class="e__saving"><span class="e__tag">割引額</span><span class="e__number e__deals"><%= service['discount'].to_i %></span>円<% if SetPlan.is_discount_from_energy?(service) %>/kWh<% elsif SetPlan.monthly?(service) %>/月<% elsif SetPlan.yearly?(service) %>/年<% end %></div>

// 修正後(とっても短くなった!)
<%= discount_text(service, @provider) %>
```
Datadogでホスト課金されずにログのみを送信する方法

検索しても出てこずググラビリティが低いということで、忘れないようにメモしておきます。

## やりたいこと

[なぜPrometheusを辞めてDatadogを採用したのか](https://tech-blog.abeja.asia/entry/why-datadog) にも書きましたが、DatadogのLogsは素晴らしいです。

「でも Datadog ってホスト課金になるので、ホスト課金＋ログ課金で高くつくんじゃない？」

と思いのあなた。
ホスト課金をされないようにして、ログだけを送信する設定がありました。

しかも安心してください。これ[公式](https://docs.datadoghq.com/ja/logs/faq/how-to-set-up-only-logs/?tab=host)に載ってる方法なので裏ワザ使ってるわけじゃないです。

## 設定内容
他の方法は[公式](https://docs.datadoghq.com/ja/logs/faq/how-to-set-up-only-logs/?tab=host)の方を見てください。
Kubernetesの場合は以下の通り、envに `Send logs only` 以下の設定を入れるだけ。


```
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: datadog-agent
  namespace: default
spec:
  selector:
    matchLabels:
      app: datadog-agent
  template:
    metadata:
      labels:
        app: datadog-agent
      name: datadog-agent
    spec:
      serviceAccountName: datadog-agent
      containers:
      - image: datadog/agent:latest
        ## (...)
        env:
          ## Set the Datadog API Key related to your Organization
          ## If you use the Kubernetes Secret use the following env variable:
          ## {name: DD_API_KEY, valueFrom:{ secretKeyRef:{ name: datadog-secret, key: api-key }}
          - {name: DD_API_KEY, value: "<YOUR_API_KEY>"}

          ## Set DD_SITE to "datadoghq.eu" to send your Agent data to the Datadog EU site
          - {name: DD_SITE, value: "datadoghq.com"}

          ## Send logs only
          - {name: DD_ENABLE_PAYLOADS_EVENTS, value: "false"}
          - {name: DD_ENABLE_PAYLOADS_SERIES, value: "false"}
          - {name: DD_ENABLE_PAYLOADS_SERVICE_CHECKS, value: "false"}
          - {name: DD_ENABLE_PAYLOADS_SKETCHES, value: "false"}

          ## (...)
```

## 注意点
注意点として「メタデータやタグが欠落するのでDatadogとしては推奨はしてないよ」とのことでした。
でも、DatadogのLogsは優秀なので、ホストは他で監視してるけどー。という方はぜひこの方法でLogsを試してみてください。
CoordinatorLayoutをやってみた

# はじめに
今回はCoordinatorLayoutを使用し、下記のようなスクロールでツールバー等を見え隠れさせるアプリを作成してみました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472891/bb96bba5-afc0-f0e9-55f7-761ef6678cb0.gif" width=30%>

## 実際に実装してみた
上記のアプリの実際のコードはこちらになります。

```MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Adapterの設定
        val sampleList = mutableListOf<String>()
        for (i in 0..20) {
            sampleList.add(i.toString())
        }
        val adapter = RecyclerAdapter(sampleList)
        recycler_view.adapter = adapter

        // 区切り線の表示
        recycler_view.addItemDecoration(DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
    }
}
```

```activity_main.xml
<RelativeLayout
    ...
    >

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <androidx.appcompat.widget.Toolbar
                ...
                app:layout_scrollFlags="scroll|enterAlwaysCollapsed" />

        </com.google.android.material.appbar.AppBarLayout>

        <androidx.recyclerview.widget.RecyclerView
            ...
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

</RelativeLayout>
```

## 実装する際のポイント
上記のようなアプリを実装するためには、いくつかのポイントがあります。
1.`CoordinatorLayout`でスクロール時に隠すためには、スクロールする部分が`NestedScrollView`か`RecyclerView`でないといけません。
2.隠したい部分は`AppBarLayout`の中に配置し、`app:layout_scrollFlags`を使用することで、隠れてくれます。
　`app:layout_scrollFlags`には色々な種類がありますが、ここでは割愛します。
上記のアプリを図で表して見ると、こんな感じになります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472891/dc783911-57d5-6671-83c6-b22bfae833b6.png" width=50%>

3.`RecyclerView`に`layout_behavior`がないと、`AppBarLayout`に`RecyclerView`が重なって表示されてしまいます。

4.下記の画像の場合、隠したくないものは`AppBarLayout`より上位の階位に書く必要があります。
　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472891/8c388419-c7f7-6947-6f95-76fab955b629.png" width=50%>

# おわりに
今回はCoordinatorLayoutを使用し、スクロールでツールバー等を見え隠れさせるアプリを作成してみました。
実装する中で、私が迷ったことや必要なポイントをまとめてみました。
皆さんのお役に立てれば幸いです。
CSSのcontentプロパティがUNICODEっぽく文字化けして困るとき

after要素で「必須」って表示させたいのにCMSの影響なのかしらんけどUNICODEっぽく文字化けして困るとき～


content要素をUNICODEで書いて解決。
なお↓はよく使う‘必須’の文字。
```content: "\5FC5 \9808"```

Content要素でUNICODE使いたいときはバックスラッシュを使おう。

UNICODE一覧はこちら
http://www.asahi-net.or.jp/~ax2s-kmtn/ref/unicode/cjku_klist.html
PHP 関数の作り方

# 目的

- PHPでの関数の作り方をまとめる
- ちなみに、関数内で定義した変数のスコープは当該関数内だけ

# 書き方の例

- 下記に関数の定義方法を記載する。

```php
//関数の定義(引数の有無に関わらず括弧をつけて変数を定義する)
function 関数名(第一引数を格納する変数A, 第二引数を格納する変数B){
  関数内で実行する処理;
}

//関数の呼び出し(定義時に引数が格納される変数の定義の有無に関わらず括弧をつけて呼び出す)
関数名(第一引数, 第二引数);
```

- 関数内での結果を変数に格納したい

```php
//関数の定義
function 関数名(第一引数を格納する変数A, 第二引数を格納する変数B){
  return 任意の処理;
}

$foo = 関数名(第一引数, 第二引数);
```

# より具体的な書き方の例

- hiと出力する関数`sayHi`を定義して実行する。

```php
//関数の定義
function sayHi() {
    echo "hi"
}

 //関数の実行
sayHi();
```

- 前述の関数`sayHi`にて「hi 関数の引数」と出力する場合の処理を記載する。

```php
function sayHi($name) {
    echo "hi $name";
}

//関数の実行時に引数を与えて実行する。
sayHi("miriwo");
```

- 前述の関数`sayHi`関数の引数に初期値を設定する。初期値を設定しておくと、関数呼び出し時に引数が指定されなかった時に自動で初期値が入り実行される。

```php
function sayHi($name = "people") {
    echo "hi $name";
}

sayHi();
```
Laravel 日付関連の処理を施す

`Carbon`はphpに標準で存在するDateTimeクラスを拡張して、日付操作をより簡単にしてくれます。

まず、composerにCarbonをインストールしましょう。

```
composer self-update

//composer --versionでバージョンの確認ができます。
```

そしたら、composerにCarbonをインストールしましょう。

```
composer require nesbot/carbon
```

現在地点からの日時取得


```php:hogehogeController.php

use Carbon\Carbon;

        // 現在日時
        $carbon_now = Carbon::now();
        // 昨日
        Carbon::yesterday();        
        // 今日
        Carbon::today();         
        // 明日
        Carbon::tomorrow();
        // 2年進める
        $carbon_now->addYears(2);
        // 2年戻る
        $carbon_now->subYears(2);
        // 2ヶ月進む
        $carbon_now->addMonth(2);
        // 2日進む
        $carbon_now->addDays(2);
        // 2時間戻る
        $carbon_now->subHours(2);
        // 平日で2日進む
        $carbon_now->addWeekdays(2);
        // 2週間進む
        $carbon_now->addWeeks(2);
 
```


こんな感じで簡単に色々できます。
>参考にさせて頂いたサイト

https://leben.mobi/blog/php_date_carbon/php/

上記サイトにほとんど書いてあるので、参考にしてみましょう！
Cloud Composer(Airflow version1.10系)で Gantt を開こうとすると AttributeError: 'NoneType' object has no attribute 'timetuple'

# 背景
- Airflowで DAG指定 -> Ganttを開こうとすると以下のような画面になる
- エラー内容は `AttributeError: 'NoneType' object has no attribute 'timetuple'`
![スクリーンショット 2019-11-07 13.19.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/189239ea-d330-3437-6c8d-345b526a2d0f.png)


# 原因
- Airflowの task_fail テーブルの start_dateカラムに Nullのものがあるのが原因

# 対応
- `UPDATE task_fail SET start_date='2019-11-01 00:00:00.000000' WHERE duration IS NULL` をしてあげればいい
  - start_dateは好きな時間入れる
- Cloud Composerを使っているので、手順としては、worker container とかに入って、mysqlに繋いでコマンドを実行する
  - ログイン手順は [この辺り](https://qiita.com/munaita_/items/f1a0b8a33c59d1c59437#%E6%89%8B%E9%A0%86)
  - Airflowを独自で立てている場合は、直接DBに対してコマンドを実行すればいい
pyenv で python のインストールが zlib not available で失敗する

# はじめに

pyenvでPythonバージョンを新しくインストールしようとしたら`zlib not available`エラーが出るようになりました。
色々探して解決策を試して見ても上手くいかずようやくインストール出来たのでそのメモです。

## 環境

```
ProductName:	Mac OS X
ProductVersion:	10.14.6
BuildVersion:	18G87
```

```
pyenv 1.2.16
```

## 再現

```bash
$ pyenv install 3.6.8
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.6.8.tar.xz...
-> https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tar.xz
Installing Python-3.6.8...
python-build: use readline from homebrew

BUILD FAILED (OS X 10.14.6 using python-build 20180424)

Inspect or clean up the working tree at /var/folders/qr/fspx_mhd2t3b04xf6s1jjh680000gn/T/python-build.20200107115925.41170
Results logged to /var/folders/qr/fspx_mhd2t3b04xf6s1jjh680000gn/T/python-build.20200107115925.41170.log

Last 10 log lines:
  File "/private/var/folders/qr/fspx_mhd2t3b04xf6s1jjh680000gn/T/python-build.20200107115925.41170/Python-3.6.8/Lib/ensurepip/__main__.py", line 5, in <module>
    sys.exit(ensurepip._main())
  File "/private/var/folders/qr/fspx_mhd2t3b04xf6s1jjh680000gn/T/python-build.20200107115925.41170/Python-3.6.8/Lib/ensurepip/__init__.py", line 204, in _main
    default_pip=args.default_pip,
  File "/private/var/folders/qr/fspx_mhd2t3b04xf6s1jjh680000gn/T/python-build.20200107115925.41170/Python-3.6.8/Lib/ensurepip/__init__.py", line 117, in _bootstrap
    return _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
  File "/private/var/folders/qr/fspx_mhd2t3b04xf6s1jjh680000gn/T/python-build.20200107115925.41170/Python-3.6.8/Lib/ensurepip/__init__.py", line 27, in _run_pip
    import pip._internal
zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1
```

以下の記事を参考に解決策を試したんですが、なぜか上手くいかず。。。
https://qiita.com/zreactor/items/c3fd04417e0d61af0afe

たぶん既にインストールしてるからか互換性がないから駄目だよってことなんだとは思いますが。。。

```bash
$ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
installer: Package name is macOS_SDK_headers_for_macOS_10.14
installer: Certificate used to sign package is not trusted. Use -allowUntrusted to override.
```

```bash
$ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target / -allowUntrusted
installer: Package name is macOS_SDK_headers_for_macOS_10.14
installer: Installing at base path /
installer: The install failed (The Installer encountered an error that caused the installation to fail. Contact the software manufacturer for assistance.)
```

## 解決策

最終的に以下で対応しました。
同じ悩みを抱える方が救われますように(；人；)

```bash
# コマンドラインツールを削除
sudo rm -rf /Library/Developer/CommandLineTools
# コマンドラインツールを再インストール
xcode-select --install
# パッケージインストール
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
```
KubernetesでボリュームをマウントしているのにNo such file or directoryになるやつ

定期的に遭遇するけどなんで発生してるか忘れるので備忘録

このYAMLをデプロイするとPodのデプロイに失敗する。なぜだろうか。

```yaml:hoge.yaml
apiVersion: v1
kind: Pod
metadata:
  name: init-demo
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html
  initContainers:
  - name: install
    image: busybox
    command:
    - "wget -O /work-dir/index.html http://kubernetes.io"
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  volumes:
  - name: workdir
    emptyDir: {}
  dnsPolicy: Default
```

以下のようにすると動くようになる

```yaml:fuga.yaml

apiVersion: v1
kind: Pod
metadata:
  name: init-demo
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html
  initContainers:
  - name: install
    image: busybox
    command:
    - wget
    - "-O"
    - "/work-dir/index.html"
    - http://kubernetes.io
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  volumes:
  - name: workdir
    emptyDir: {}
  dnsPolicy: Default
```

diffをとってみるとこうだ。

```diff
- 				"wget",
+ 				"wget -O /work-dir/index.html http://kubernetes.io",
- 				"-O",
- 				"/work-dir/index.html",
- 				"http://kubernetes.io",
```

Linuxのコマンドを実行する際に引数をどう渡すかによって結果が変わるという話だった。詳しくはだいぶ前に調べたんだが忘れてしまったので思い出したら書く。
【学習まとめ】 Railsアプリケーションのテスト

## なぜテストですか。

ソフトウェア開発の仕事は、機能しているコードを書くことと思います。

問題は、正確さをどうやって確保できるのか

一つの方法は、コードを書いた後で、実行してみます。この方法は、小さいプロジェクトに対して効果がありますが、ある時点で機能が多すぎて追跡できません。新しいコード（フィーチャー）を追加すると、他のコードが予期せず壊れてしまいます。これは、`regression`（リグレックション）と呼ばれています。

より良い方法があり、自動テストです。コードで作成したコードを自動的にテストしてもらいます。自動テストは、私たちのプログラムが機能していること、そして今後も機能して続いていることを確認します。

#### お金や時間の節約

自動テストは、バグをより早く発現し、本番に不正な状態を展開されるのを防ぎます。

#### コードに自信がある

良いテストがあると、

何か壊すことを恐れことなく、コードに大きな変更を加えることができます。
金曜日の午後でも、リリースする自信があります。

#### より良いドキュメント

ドキュメントは、コードを更新するとフルいくなります。テストは、いつもコードによって更新しなければならないものである。

## TDD（テスト駆動開発）

TDDは、テストを利用してアプリケーションの設計や開発の推進するプロセスである。
Red, Green, Refactorと呼ばれているサイクルから始めます。

![tdd-cycle.png](https://github.com/thoughtbot/testing-rails/raw/master/release/images/tdd-cycle.png)

#### Red

最初に、適用する予定のメソッドやロジックのテストを先に書きます。この時点でコードはどのように見えるかを知る必要がありません、それが何をするかを知るだけで十分です。

テストを実行すると、失敗するはずです。（テストがRed色になります）

#### Green

失敗するテストから、エラーメッセじを読んで、コードを書きます。この時点、テストを合格するのに十分なコードを書くだけです。コードの品質に焦点を合わせなくていいです。

#### Refactor

コードをクリーンニングし、複数なコードを削除する。アプリケーションのコードではなくテストコードもします。

コードに何か変更しても壊れない自信があるまでします。

## TDDアプローチ

#### Outside-In Development

アウトサイド ・イン開発は、最初は最高レベルアブストラクション（抽象化）から始めます。というのは、ユーザがブラウザ（UI）を操作し、ページ上の要素と対話する観点である。これは、受け入れテストと呼ばれています。

受け入れテストが緑色になったら、よりコードを記述する必要はありません。

#### Inside-Out Development

時々、最終のソリューションがどのように見えるかわからない場合、インサイド・アウト開発はお勧めします。コンポーネントごとを構築します。

## テスト駆動とテストファースト

最初にテストを書くだけで、テスト駆動と呼ばれているのは違います。

赤、緑、リファクタリングのサイクルに沿って、失敗テストに対して必要なコードのみを記述することは重要です。これにより、ソリューションのスコープ外の設計、テストされていない機能を実装しなくなります。

また、リファクタリングのスッテプをスキップしないことも重要です。これは、TDDの最も重要な部分の一つであります、コードを保守しやすく、将来変更しやすいくようにします。

## TDDの利点

+ Confidence（自信）
+ Time Savings（時間節約）
+ Flow（フロー）
+ Improved Design（設計の改善）

## TDDしない時（実用的）

+ アプリケーションが小さい、変更が少ない（ほとんどない）
+ 短い時間で利用するつもりであるプログラム
+ アプリケーションの重要性が低い、壊れても影響がない

## 効果的なテストスイートの特性

+ 速度 (speed)
+ 完成度 (complete)
+ 信頼性ある (reliable)
+ 孤立 (isolated)
+ 保守可能 (maintainable)

## テストタイプ

> テストパイラミッド
![](https://github.com/thoughtbot/testing-rails/raw/master/release/images/rails-test-types.png)


## Refs

[testing-rails/testing-rails.md at master · thoughtbot/testing-rails · GitHub](https://github.com/thoughtbot/testing-rails/blob/master/release/testing-rails.md)
vagrantの起動ができない！（VirtualBoxとのバージョンが合わない）


普段あまりvagrantを使わないのですが、
vagrantを久しぶりに起動したら、うまく起動しない...
VirtualBoxを別件でアップデートしたのが原因みたいです。

```
Vagrant has detected that you have a version of VirtualBox installed
that is not supported by this version of Vagrant. Please install one of
the supported versions listed below to use Vagrant:

4.0, 4.1, 4.2, 4.3, 5.0, 5.1, 5.2, 6.0

A Vagrant update may also be available that adds support for the version
you specified. Please check www.vagrantup.com/downloads.html to download
```
↑真っ赤なエラーメッセージ。

使えるvirtualBoxのバージョンは4.0, 4.1, 4.2, 4.3, 5.0, 5.1, 5.2, 6.0みたいで、
virtualBoxのバージョンは6.1でした。惜しい。

vagrantを公式からアップデートしてみるも、同じエラー文が出るようです。
まだ対応が追いついてないということみたいですね。

## issueに同じ不満を発見
https://github.com/hashicorp/vagrant/issues/11249
こちらドンピシャなissue。

ざっとしか読んでいませんが、
パッチを当てたりとか、ワイルドカード使って6.x読めるようにしようよ！とか
色々書かれているようですが、何かあったら怖い（アップデートしたものと整合性が取れなくなった場合）ので
VirtualBoxを6.0にダウングレードする方向でいこうと思います。

## VirtualBoxを6.1 -> 6.0にダウングレード

https://www.virtualbox.org/wiki/Download_Old_Builds
こちらから昔のバージョンのVirtualBoxをダウンロードできます。
（ダウンロードの際は、VitualBoxで起動しているものがあるとダウンロードできないので、電源オフにしておくことを忘れずに！）

無事ダウンロードして、`vagrant up`　したら問題なく起動しました！
ubuntu16.04LTSでSwiftの環境構築！

##はじめに
私はiOSアプリ開発によく使われるSwiftを勉強しようとSwiftのツール「Xcode」をやってみようとしましたが、
私のパソコンはWindowsなのでXcodeは使えないと知りました。
**「MacのパソコンじゃないとXcodeは動かない(´;ω;｀)」**
と嘆く私でしたが、WindowsでもSwiftを扱いたい！と思ったため、今回私がwindowsでSwiftの環境構築を
行った手順を紹介しようと思います。

windowsといっても **ubuntu16.04LTS** を使っていますが(笑)

##手順
Ubuntu16.04LTSを開いて以下のコマンドを入力していきます。
###パッケージのアップデート
```
$ sudo apt-get update
$ sudo apt-get upgrade
```
###clang libicu-devのインストール
swiftを使用するうえで必要なパッケージをインストールします。

```
$ sudo apt-get install clang libicu-dev
```
###Swiftを入れるディレクトリを作成
```
$ mkdir /mnt/c/Swift
```
###Swiftのダウンロード
```
$ cd /mnt/c/Swift
$ wget https://swift.org/builds/swift-5.1.3-release/ubuntu1604/swift-5.1.3-RELEASE/swift-5.1.3-RELEASE-ubuntu16.04.tar.gz
```
Swiftの最新バージョンは以下で確認できます。（バージョン5.1.3は2020/01/07現在最新）
https://swift.org/download/ 
###ダウンロードしたファイルを解凍
```
$ tar xzf swift-5.1.3-RELEASE-ubuntu16.04.tar.gz
```
###パスを通す
```
$ vi ~/.bashrc
```
最終行に以下を追加
`PATH="/mnt/c/Swift/swift-3.0.2-RELEASE-ubuntu14.04/usr/bin:$PATH"`

```
$ source ~/.bashrc
```
###Swift確認
以下のコマンドでSwiftのバージョンが確認できれば構築完了です。
おつかれさまでした！

```
$ swift -version
```
##Swiftのコンパイル＆実行
任意の場所にhelloWorld.swiftを置く。（中身は print("hello world!") ）

```
$ swiftc helloWorld.swift   ←コンパイル
$ ./helloWorld              ←実行
```
##プロジェクト作成
###プロジェクトディレクトリを作成
```
$ mkdir swiftProject
$ cd swiftProject
```
###プロジェクト作成
```
$ swift package init --type executable
```
###プロジェクトのビルド
```
$ swift build
```
###プロジェクトの実行
```
$ ./.build//x86_64-unknown-linux/debug/(プロジェクト名)
```
画面部品の配置

初学者ですが、個人的な勉強の為まとめました

##画面部品の配置

Androidアプリの画面は、Android SDKで用意された画面部品を配置することで作成する。これが、.xmlファイルに画面部品タグを記述することである
画面部品については、大きく**ビューグループ**と**ビュー**の2つがある


###ビューグループ

・**ビューグループ**は、各画面の配置を決めるもので、**レイアウト部品**とも呼ばれる。以下は、主なレイアウト部品である
　①**＜LinearLayout＞**･･･一番扱いやすいレイアウトで、画面部品を縦/横方向に並べて配置
　②**＜TableLayout＞**･･･表形式で画面部品配置
　③**＜GridLayout＞**･･･グリッド形式で画面部品を配置
　④**＜FrameLayout＞**･･･画面部品を重ねて配置
　⑤**＜RelativeLayout＞**･･･画面部品を相対的に配置
　⑥**＜ConstraintLauout＞**･･･RelativeLayout同様に、画面部品を相対的に配置

　※RelativeLayoutは、Android2.2まで、プロジェクトを作成した際に生成されるレイアウトXMLの最初に記述されていたものだが、2.3以降はより扱いやすくしたレイアウト部品として**ConstraintLayout**が導入され、これが基本レイアウトとなった

###ビュー

・**ビュー**は、画面部品そのもので、**ウィジェット**とも呼ぶ
・以下は、代表的なビュー
　①**＜TextView＞**･･･文字列の表示
　②**＜EditText＞**･･･テキストボックス
　③**＜Button＞**･･･ボタン
　④**＜RadioButton＞**･･･ラジオボタン
　⑤**＜CheckBox＞**･･･チェックボックス
　⑥**＜Spinner＞**･･･ドロップダウンリスト
　⑦**＜ListView＞**･･･リスト表示
　⑧**＜SeekBar＞**･･･スライダー
　⑨**＜RatingBar＞**･･･☆でレート値を表現
　⑩**＜Switch＞**･･･ON/OFFが表現できるスイッチ

###タグの組み合わせ

・Android画面では、レイアウト部品とビュー部品を階層的に組み合わせて使う
・レイアウト部品は、画面部品の配置を決めるものなので、その配下に画面部品を含んで使う
　例）

```activity_view_sample.xml
     <LinearLayout>
         <TextView/>
     </LinearLayout>
```

・レイアウト部品のような子要素を持つタグは開始タグと終了タグで囲み、ビュー部品は子要素を持たないものが多いので、終了タグを書かず、タグの右カッコの前にスラッシュを入れる、属性のみのタグが基本

###よく使われる属性

####①android:id

・画面部品のidの設定
・アクティビティ（Javaプログラム）内でこの部品を扱う場合にはIDを記述
・**＠+id/･･･**のように記述し、「･･･」の名前で部品にアクセスできる
　例）

```activity_view_sample.xml
<TextView
       android:id="@+id/tvLabelInput"
```

####②android:text

・画面部品が表示されるときの文字列を設定
・表示文字列は直接記述せずにstring.xmlに記述するので、string.xmlに記述された文字列と画面部品とを紐付ける方法が**＠string/･･･**である
　例）

```activity_view_sample.xml
<TextView
        android:text="@string/tv_msg"/>
```

```string.xml
<string name="tv_msg">お名前を入力してください。</string>
```

####③android:layout-width/height

・widthが部品の幅、heightが高さを表す
・すべての画面部品に記述する必要がある
・～dpのような数値、もしくは**wrap_content**や**match_content**などを使う
・wrap_contentは、必要なサイズに自動調整する
・match_contentは、親部品のサイズいっぱいまで拡張する

####④android:margin/padding

・margin/paddingともに余白を表す
・marginは画面外側の余白、paddingは部品の内側の余白
Androidビュー

初学者ですが、個人的な勉強の為まとめました

##Androidビュー

**Projectツールウィンドウ**の見え方は変更でき、デフォルトでは**Androidビュー**である
Androidビューでは、開発に必要なファイルのみ表示するようになっており、必要に応じては**Projectビュー**など他のビューに切り替える
※Projectビューは、より実際のファイルなどに近い構成になっている

###Androidビューのファイル構成

・大きく、**manifests**、**java**、**res**の3フォルダに分かれる

####①manifests

・**AndroidManifest.xml**ファイルが格納されている
・AndroidManifest.xmlファイルは、**アプリの実行に必要な設定**が記述されている

####②java

・名前の通り、javaファイルが格納されている
・パッケージ右側に（androidTest）,（test）と記述されているのは、Androidアプリをテストするための.Javaファイルの格納先


####③res

・.xmlファイルや、アプリで使われる画像ファイルなどを格納する
・resフォルダには、以下のサブフォルダがある
　①**drawable**･･･画像を格納
　②**layout**･･･画面構成に関わる.xmlファイルを格納
　③**mipmap**･･･アプリのアイコンを格納
　④**values**･･･アプリで格納する固定文字列（String.xml）、画面のスタイル（styles.xml）、色構成（colors.xml）を表す.xmlファイルなどを格納
初心者による ES6 class構文

#ES6によるclass構文の概要
javascriptにおけるclass構文は、主に「クラスの拡張」に重きを置いたものであるため、構文自体は他の言語を模倣した形となっている。つまり、「インスタンス」という概念はあるものの、いわゆる「クラス」がなく、「プロトタイプという概念」だけが存在するということである。ES6でのclassキーワードでのクラスは、関数として呼び出しは出来ないが、内部的には関数である。

```javascript:sample.js
class User {
 static age = 100
 constructor(name = '') {
  this.name = name
 }
 get() {
  /*コード内容*/
 }
 set() {
  /*コード内容*/
 }
}

//インスタンスの作成
const sample_user = new User('Tanaka')
```
特徴的なのは、constructor（Cではコンストラクタ）である。constructorはインスタンスが作成されたときに呼び出されるため、constructor内のthisはそのインスタンスを指している。constructorメソッドはオプションであり、クラスのインスタンスに対して、初期設定を行う。

またインスタンスの作成方法は、newキーワードを使う。
newキーワードで生成したインスタンスに関して後からインスタンスを追加することもでき、このことから他言語のクラスとは違うことがわかる。

#classにおけるthisとbind
thisキーワードは、コンストラクターによって生成されるインスタンスを表すものである。thisキーワードはどこからでも参照できる特別な変数であるがよえに、呼び出す場所、呼び出しの方法によって中身が変わってきてしまう。
そして、class内のメソッドは、自動的にバインドがされない。バインドされないとは、あるメソッドを呼び出したときにそれがどこのclassで定義されているメソッドなのかがわからないという仕様である。例えば、

```javascript:sample.js
class app {
 get() {
  const nameList = /*urlからnameのリストをダウンロードする*/
  return nameList.map(function(name) {
    return this.set(name)
  })
 }
 set(name) {
  this.name = name + '様'
 }
}
```
一見よさそうに見えるが、getメソッドが呼び出したsetメソッド内のthisはもうそのインスタンスを指していないため、nameは正しく保存されない。
このことを解決する手段は何種類かある。
一つ目は、constructorでバインドしてしまうことだ。

```javascript:sample.js
class app {
 constructor(name = '') {
  this.name = name
  this.set = this.set.bind(this)
 }
 get() {
  const nameList = /*urlからnameのリストをダウンロードする*/
  return nameList.map(function(name) {
    return this.set(name)
  })
 }
 set(name) {
  this.name = name + '様'
 }
}
```
constructorでbind(this)を用いることで、setを呼び出したインスタンスとset内で用いられているthisを同じインスタンスにしている。C言語でいうところのポインタを同じにするということだ。
二つ目はthatをかませることだ。

```javascript:sample.js
class app {
 constructor(name = ''){
  this.name = name
 }
 get() {
  const that = this
  const nameList = /*urlからnameのリストをダウンロードする*/
  return nameList.map(function(name) {
    return that.set(name)
  })
 }
 set(name) {
  this.name = name + '様'
 }
}
```
もしくは

```javascript:sample.js
 get() {
  const nameList = /*urlからnameのリストをダウンロードする*/
  return nameList.map(function(name) {
    return this.set(name)
  }, this)
 }
```
thatをいちいち作るとかっこ悪いのでmapの二つ目の変数にオプションとして付け加えるという方法もある。

しかし、一番使われているのはアロー関数を用いる解決策ではないだろうか。
アロー関数のthisはアロー関数が定義されたthisにバインドされる。

```javascript:sample.js
 get() {
  const nameList = /*urlからnameのリストをダウンロードする*/
  return nameList.map((name) => this.set(name))
 }
```
このthisはそれぞれのnameに対して適切に行われる。

#classの拡張
javascriptでclassを継承するときに覚えておくべきことは、やはりclassは親のプロパティを継承することである

```javascript:sample.js
class Student extends Person {
 constructor(name, age, score) {
  super(name, age)
  this.score = score
 }
}
```
javascriptではentendsキーワードを用いて、継承を行う。superキーワードを使うことで、いちいち親のコンストラクタをもう一度呼び出さなくてもよい。また、superキーワードは親のメソッドを呼び出したいときにも使われる。

#参考資料
山田祥寛様　「javascript本格入門」
JD Isaacks様　「入門javaScriptプログラミング」
UWPアプリケーションにおける設定ファイルの読み書き

# 動機
長らくWindowsアプリケーションを書いていなかったため、大昔のiniファイルを書いたりパースさせたりというのばかりに慣れてしまっており、最近のUWP(Universal Windows Platform)における設定ファイルの読み書きをどうすればよいのか分からなかったのでメモしておきます。ちょっと調べれば分かる話ですけど。

# さすがにもうiniファイルではない
そりゃそうですね。20数年前の知識で止まりすぎです。UWPではWindows.Storage.ApplicationDataContainerクラスもしくはWindows.Storage.ApplicationDataCompositeValueクラス（構造体のように複数の値で1つの属性を表す場合）で表現すればよいみたいです。

|設定種類|クラス名|
|:-----:|:-----:|
|デバイス特有の設定（ローミングさせないやつ）| Windows.Storage.ApplicationData.Current.LocalSettings |
|デバイス間をまたがって設定するもの| Windows.Storage.ApplicationData.Current.RoamingSettings |

# 設定の書き込み
Windows.Storage.ApplicationDataContainerクラスがキーバリューストアになっているため、単純に次のように書けばキーe-mailに対応する設定は"hogehoge@xyz.com"ですよ、という内容の設定ファイルとして残してくれます。設定用ページでセーブボタンを押したときに発動させればいいです。

```C#
ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
localSettings.Values["e-mail"] = "hogehoge@xyz.com";
```
#設定の読み込み
理屈は同じで、ApplicationDataContainerクラスを取ってきて、それをキーバリューストアで読み込めば良いだけです。ページロード時に読み込んで更新しておけばOKです。

```C#
ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
var email = localSettings.Values["e-mail"] as String;
```
というような感じ。
jQuery UI Sortable で位置を取る

jQuery UI Sortable で、ドラックしたアイテムが何番目になったのか取得する。
update のタイミングで親まで遡って自分が何番目か index() で取得する。

```javascript
$('#mylist').sortable({
  update: function( e, ui ) {
    let index = ui.item.closest('ul').find('li').index(ui.item[0]);
  }
});
```
LaTeXの論文の目次に「第~章」だけでなく「第~節」まで入れる方法

# pdfLateXでは目次には第~節が印字されない

pdfLateXで生成される目次では、第~章は印字されるが、第~節が印字されない。

```thesis.texの一部

\tableofcontents

\chapter{序論}

\section{背景}\label{sec:intro_background}
これこれこういう背景がある．

\section{目的}\label{sec:intro_purpose}
本研究は，これこれこういうことを目的とする．

\section{目標}\label{sec:intro_goal}
本研究の目標は，これこれこういうことである．

\section{構成}\label{sec:intro_contents}
本文書の構成を以下に示す．
```

これをpdfLaTeXでコンパイルする。

```terminal
platex thesis.tex
dvipdfmx thesis.dvi
```

これで出力される`thesis.toc`と`thesis.pdf`の目次は以下の通り。

```thesis.toc
\contentsline {chapter}{\numberline {第1章}序論}{1}

\contentsline {section}{\numberline {1}背景}{1}

\contentsline {section}{\numberline {2}目的}{2}

\contentsline {section}{\numberline {3}目標}{3}

\contentsline {section}{\numberline {4}構成}{3}
```

tesis.pdfの目次
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189802/511fadbb-db8a-7bfe-d502-c27bf44c9259.png)

`\chapter`は第~章となっているが、`\section`は第~節とはなっていない。

# 解決方法
`\section`に第~節を入れたい場合は、
`sed`コマンドで`thesis.toc`を書き換える。

```listofcontents.sh
#!/bin/sh
file=`date|sed 's/[\ :]/_/g'`
sed 's/\(\\contentsline\ {section}{\\numberline\ {\)\([0-9]\)}/\1第\2節}　/' ${1}.toc > $file
rm $file
```

platexでコンパイルしたあと、このスクリプトの第一引数に`thesis`を入れて実行してから、もう一度コンパイルする。

```terminal
platex thesis.tex
sh listofcontents.sh thesis
platex thesis.tex
dvipdfmx thesis.dvi
```

これで第~節も印字された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189802/695d3f62-21bc-f1a7-2f25-6051fd21a37f.png)
Ubuntuのapt-get updateで「File has unexpected size」エラー解消

以下のようなエラーが発生する場合の解決方法

```
E: Failed to fetch https://packages.microsoft.com/repos/azure-cli/dists/bionic/main/binary-amd64/Packages.bz2  File has unexpected size (7745 != 7578). Mirror sync in progress? [IP: 40.76.35.62 443]
   Hashes of expected file:
    - Filesize:7578 [weak]
    - SHA512:30aedbe5e049c2ca01e21eefa4f08305e1ff194e8d1e169cbf9b0f80cf53dff7737be1db73e86a4bae4f1e5b8d09de91a6fafe47ac70970f0064068b8a8966af
    - SHA256:1a3e7c4fef701ae1ed6eeeba7335bd46b00ab1bc8ab7237fab1995fcf6d227ce
    - SHA1:cba9edf2f8322ddef2e6254c41bb3c34bd91b8f7 [weak]
    - MD5Sum:04194afaa70a355bd05b7617f0eb8d97 [weak]
   Release file created at: Wed, 18 Dec 2019 06:16:18 +0000
E: Some index files failed to download. They have been ignored, or old ones used instead.
##[error]Process completed with exit code 100.
```

# 原因
`apt-get update`コマンド実行時に、Ubuntuにデフォルトで入っているパッケージリストの更新に失敗するため
※ 上記の場合は「/etc/apt/sources.list.d/azure-cli.list」の更新でコケている

# 対応
エラーが出ているパッケージが不要であれば、該当のパッケージリストを削除することで解決する

```bash
sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list /etc/apt/sources.list.d/azure-cli.list
sudo apt-get update
```

# 参考
- [Solved: ubuntu-latest Apt repository list issues? - Page 2 - GitHub Community Forum](https://github.community/t5/GitHub-Actions/ubuntu-latest-Apt-repository-list-issues/td-p/41122/page/2)
raspberry piでpythonを用いてグーグルスプレッドシートにアクセスする（自分用）

#目的
raspberry piでpythonを用いてグーグルスプレッドシートにアクセスするまでの覚え書きを記します

#準備
・↓google spread sheet に書き込み・読み取りをする準備まで
https://qiita.com/akabei/items/0eac37cb852ad476c6b9


raspberry piで準備するコード

呼ばれる側

``` python:test.py
import sys
sys.path.append('/usr/lib/python3/dist-packages')
import gspread
from oauth2client.service_account import ServiceAccountCredentials

def main():
        scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
        credentials = ServiceAccountCredentials.from_json_keyfile_name('/home/pi/Downloads/xxxxxxxxxxx.json', scope)
        gc = gspread.authorize(credentials)
        wks = gc.open('gspreadサンプル').sheet1
        wks.update_acell('A1', 'Hello World!')
        print(wks.acell('A1'))

if __name__ == "__main__":
        main()
```

呼ぶ側

```python:yobu.py

import test
test.main()
```

#問題
LANの異なる環境（自宅のLANと研究室のLAN）で以下のような問題が現れた．

```
raise HttpAccessTokenRefreshError(error_msg, status=resp.status)
oauth2client.client.HttpAccessTokenRefreshError: invalid_grant: Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values and use a clock with skew to account for clock differences between systems.
```

これはOSの内部時刻が現在時刻と同期されてないことに起因する問題だった．

```
sudo date --set='2020/01/07 16:54'
```

このように手動で時刻を合わせることで解決した

#追記
こんなエラーがでた

```
Requirement already satisfied: requests in /usr/lib/python3/dist-packages (2.21.0)
Could not fetch URL https://www.piwheels.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='www.piwheels.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')])"))) - skipping
```





#参考文献
・https://qiita.com/AAkira/items/22719cbbd41b26dbd0d1
・https://hombre-nuevo.com/microcomputer/raspberrypi/raspberrypi0044/
・https://www.xn--tckk6a9dufrb.com/raspberry-piraspbian%E3%81%AEntp%E3%82%B5%E3%83%BC%E3%83%90%E8%A8%AD%E5%AE%9A/
OMC Log Analytics ログ手動アップロード

Oracle Management Cloudに手動でログをアップロードする手順を紹介します

ここからアップロードに必要なサンプルログファイル(Oracle Databaseの監査XMLログ)をダウンロードしておきます
https://github.com/western24/omcdemo/blob/master/ora012_ora_39101_20200107163038268433930558.xml

- ログ管理のアップロードをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/69a58007-4964-942e-4312-df1a72a01766.png)

- 新規アップロードをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/b7ec22dd-28d3-18ef-7e4b-6e11f5fd8909.png)

- 任意のアップロード名を入力し、ファイル選択をクリック。ダウンロードしておいたログファイルを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/2def5e56-e8fd-8589-3cf7-c4b728d4cb20.png)

- ログソースの関連付けをクリックし、Database Audit XML Logsを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/4dd898de-5ccb-7f77-4587-6273e15fe3ea.png)

- 真ん中のアイコンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/adb04425-53a1-89b6-1705-ed23c3cd8723.png)

- タイムゾーンをasia/tokyoに指定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/551043f6-5168-3117-cfb1-62a1db5f2f1f.png)

- 上部の矢印>をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/b8013a17-8dc0-5dfa-5ef2-86d50e6e59c0.png)


- アップロードをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/1d8043ce-0431-a362-b7fd-2b5ebe87d71c.png)

- 1分以内にアップロードは完了。完了後に右のメニューからログ・エクスプローラで表示をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/bb818af0-df79-5012-61ef-884f5732c5fa.png)

- これでDatabaseのXML監査ログがアップロード完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/fee74eae-008f-555e-5513-d0ac3906e590.png)

OMCのGUIを使用した手動ログアップロード方式を紹介しました。これはCloud Agentをいちいちインストールする必要はないので、手持ちのログをさくっと分析したいときに便利です。また、ファイルは圧縮ファイルでもOKです。

ちまちまGUIじゃなくてまとめてログファイルをアップロードしたいんだよという方は、[ODUクライアント](https://docs.oracle.com/cd/E83857_01/paas/management-cloud/logcs/upload-log-files-using-odu-client.html)を使ってバッチやアップロードの自動化などに活用することができます。


Oracle Management Cloud関連の情報は[こちら](https://qiita.com/western24/items/1e44bfcaa77f3251a263)