OmniAICreator/Qiita-1.07M huggingface dataset:
B - Bingo, C - Takahashi's Information, C - 山崩し

##[B - Bingo](https://atcoder.jp/contests/abc157/tasks/abc157_b)

O(N)
実装問題です。

```python:python
import math
import heapq
import itertools
from functools import reduce
 
# main
def main():
    A = []
    Field = [[False] * 3, [False] * 3, [False] * 3]
 
    for i in range(0, 3):
        a = list(map(int, input().split()))
        A.append(a)
 
    N = int(input())
    B = [0] * N
    for i in range(0, N):
        B[i] = int(input())
 
    for b in B:
        for i in range(3):
            for j in range(3):
                if A[i][j] == b:
                    Field[i][j] = True
 
    bingo = False
    if Field[0][0] and Field[1][1] and Field[2][2]:
            bingo = True

    if Field[0][2] and Field[1][1] and Field[2][0]:
            bingo = True
    
    for i in range(3):
        if Field[i][0] and Field[i][1] and Field[i][2]:
            bingo = True
 
    for i in range(3):
        if Field[0][i] and Field[1][i] and Field[2][i]:
            bingo = True
    
    if bingo:
        print("Yes")
    else:
        print("No")
 
# エントリポイント
if __name__ == '__main__':
    main()
```

##[C - Takahashi's Information](https://atcoder.jp/contests/abc088/tasks/abc088_c)

O(1)
問題文から下記の要素が推測できる。
引き算をして各要素が等しいか判定。

```math

a_1 + b_1,  a_1 + b_2, a_1 + b_3 \\
a_2 + b_1,  a_2 + b_2, a_2 + b_3 \\
a_3 + b_1,  a_3 + b_2, a_3 + b_3 \\

```

```python:python
import math
import heapq
import itertools
from functools import reduce
 
# main
def main():
    C = []

    for _ in range(0, 3):
        row = list(map(int, input().split()))
        C.append(row)

    ok = True
    if C[0][0] - C[0][1] != C[1][0] - C[1][1] or C[1][0] - C[1][1] != C[2][0] - C[2][1]:
        ok = False
    if C[0][1] - C[0][2] != C[1][1] - C[1][2] or C[1][1] - C[1][2] != C[2][1] - C[2][2]:
        ok = False
    
    if ok:
        print("Yes")
    else:
        print("No")

# エントリポイント
if __name__ == '__main__':
    main()
```

##[C - 山崩し](https://atcoder.jp/contests/past202004-open/tasks/past202004_c)

O(N*(2N-1))
全探索の問題です。
実装問題。

```
5
....#....
...##X...
..#####..
.#X#####.
#########
```

配列の下から判定すると上手くいきますね。

```python:python
import math
import heapq
import itertools
from functools import reduce
 
# main
def main():
    N = int(input())
    field = []

    for _ in range(0, N):
        S = str(input())
        field.append(S)

    for i in range(N-1, 0, -1):
        for j in range(0, 2*N-1):
            if field[i][j] == 'X':
                if j-1>=0 and field[i-1][j-1] == '#':
                    field[i-1] = field[i-1][:j-1] + 'X' + field[i-1][j:]

                if field[i-1][j] == '#':
                    field[i-1] = field[i-1][:j] + 'X' + field[i-1][j+1:]

                if j+1<2*N-1 and field[i-1][j+1] == '#':
                    field[i-1] = field[i-1][:j+1] + 'X' + field[i-1][j+2:]
                    
    for i in range(0, N):
        print(field[i])

# エントリポイント
if __name__ == '__main__':
    main()
```
Lambdaのエラー率がしきい値を超えた時にslack通知する仕組みをCloudFormationで構築する

## はじめに
Lambdaが安定稼働しているかどうかをできるだけ労力をかけずにモニタリングしたい。
ということで、Lambdaのエラー発生率がしきい値を超えた時にslack通知する仕組みを構築してみた。

## 通知までの流れ
以下のような流れでSlackへの通知を行う

1. CloudWatchアラーム  
↓
2. SNS  
↓
3. AWS Chatbot  
↓
4. Slack  

## CloudFormation

```
Alarm:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmDescription: Alarm if Error occured more than expected.
      AlarmActions:
        - !Ref SlackNotificationTopic
      Metrics:
        - Expression: errors / invocations
          Id: errorrate
          ReturnData: true
        - Id: errors
          MetricStat:
            Metric: 
              Namespace: AWS/Lambda
              MetricName: Errors
              Dimensions:
              - Name: FunctionName
                Value: !ImportValue FunctionName
            Period: !Ref AlarmPeriod
            Stat: Sum
            Unit: Count
          ReturnData: false
        - Id: invocations
          MetricStat:
            Metric:
              Namespace: AWS/Lambda
              MetricName: Invocations
              Dimensions:
              - Name: FunctionName
                Value: !ImportValue FunctionName
            Period: !Ref AlarmPeriod
            Stat: Sum
            Unit: Count
          ReturnData: false
      ComparisonOperator: GreaterThanThreshold
      Threshold: !Ref AlarmThreShold
      EvaluationPeriods: !Ref AlarmEvaluationPeriods
      TreatMissingData: ignore

SlackNotificationTopic:
    Type: AWS::SNS::Topic
    Properties:
      TopicName: SlackNotificationTopic

ChannelSetting:
    Type: AWS::Chatbot::SlackChannelConfiguration
    Properties:
      ConfigurationName: ErrorNotification
      IamRoleArn: !GetAtt ChatbotIamRole.Arn
      LoggingLevel: ERROR
      SlackChannelId: !Ref SlackChannelId
      SlackWorkspaceId: !Ref SlackWorkspaceId
      SnsTopicArns: 
        - !Ref SlackNotificationTopic
  ChatbotIamRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: ErrorNotification-chatbot-role
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: chatbot.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: ErrorNotification-chatbot-policy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - cloudwatch:Describe*
                  - cloudwatch:Get*
                  - cloudwatch:List*
                Resource:
                  - "*"
```

## 軽く説明

### CloudWatch
エラーレートという指標はデフォルトで用意されていないので、こちら側で Error / Invocation のメトリクスを設定する必要がある。
`Metrics:`の項目の中で①一定期間内のinvocationの合計②一定期間内のerrorの合計 というメトリクスを生成し、② / ①の数式を実行した値をアラームの指標とする。`Period:`がデータポイントの詳細度であり、例えば「60」に設定すると60秒ごとにデータが評価されるようになる。
その他の項目については[公式ガイド](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-cw-alarm.html#cfn-cloudwatch-alarm-metrics)を見るのがわかりやすい。


### AWS Chatbot
※ AWS ChatbotでSlackのクライアント登録はコンソールで行う必要があるため注意。
チャネル設定の作成のみCloudFormationで行う。

## おわりに
もっと簡単な構成があれば教えてください〜〜〜〜
スクロールで動的に追加される要素をユーザスクリプトで加工する

```html
<div id="recommendations">
  <div><!-- ページ表示時のHTMLに静的に存在している要素 -->
    <a class="recommendation">...</a>
    <a class="recommendation">...</a>
    <a class="recommendation">...</a>
  </div>
  <div><!-- スクロール時に動的に追加された要素 -->
    <a class="recommendation">...</a>
    <a class="recommendation">...</a>
    <a class="recommendation">...</a>
  </div>
</div>
```

上記のようにスクロールに応じて、一定個数ずつ動的に読み込まれ表示されていくサイトの場合、ユーザスクリプトでページ表示時にHTMLの加工を実施すると、スクロールによって動的に追加される部分が処理されません。

不要なものを削除する系なら`setInterval`で定期実行しても十分ですが、DOMの追加に応じて丁寧に処理を挟みたい時には `MutationObserver`で要素の追加を監視します。


```js
(function() {
    'use strict';
    const observer = new MutationObserver((mutations) => {
        //console.log(mutations)
        let m = mutations.filter(m => m.target.id == 'recommendations');
        if (m[0]) process(m[0].addedNodes[0]);
    });
    observer.observe(document.querySelector('#recommendations'), {
        childList: true,
        attributes: false,
        characterData: false,
        subtree: true,
    });
    function process(wrapEl) {
        Array.from(wrapEl.querySelectorAll('.recommendation')).forEach(function(el){
            let a = document.createElement('a');
            a.href = '#';
            a.innerHTML = '何か便利なリンク';
            el.querySelector('.title').appendChild(a);
        });
    }
    process(document.querySelector('#recommendations > div'));

})();
```

注意が必要な点として、ユーザスクリプト自身で行った`appendChild()`の操作でも検知するため監視の条件によっては無限再起でハングアップします。
それを防ぐために変化の内容を確認してフィルタします。
監視の起点とする要素や監視の条件をうまく調整すれば省けるのですが、サイトによって作りが異なるのでそこまでは付き合わず、毎回フィルタするコードを書く方がやりやすいです。

応用例として、Qiitaでのタグから最新記事でのページネーションのようにJSで記事一覧を再構築している場合にも同じやり方が適用できます。

```js
// ==UserScript==
// @name         nabeatsu
// @match        https://qiita.com/tags/*
// ==/UserScript==

(function() {
    'use strict';
    const observer = new MutationObserver((mutations) => {
        //console.log(mutations)
        let m = mutations
            .filter(m => m.addedNodes[0])
            .filter(m => m.addedNodes[0].tagName == 'DIV')
            .filter(m => !/Dummy/.test(m.addedNodes[0].className));
        if (m[0]) process(m[0].addedNodes[0]);
    });
    observer.observe(document.querySelector('[id^="TagNewestItemList-"]'), {
        childList: true,
        attributes: false,
        characterData: false,
        subtree: true,
    });
    function process(wrapEl) {
        Array.from(wrapEl.querySelectorAll('article')).forEach(function(el){
            let lgtm = el.querySelector('svg').nextSibling.textContent;
            if (/3/.test(lgtm) || (lgtm > 0 && lgtm % 3 == 0)) {
                let a = el.querySelector('h2 a');
                a.textContent = a.textContent.replace(/[a-zA-Z0-9]/g, m => String.fromCharCode(m[0].charCodeAt(0) + 0xFEE0));
            }
        });
    }
})();
```

LGTMの数字が3の倍数か3が含まれる時にタイトルの英数が全角になります。

Qiitaの場合、HTMLを読み込んだ初期状態で記事一覧は存在しないことと、
ローディング表示のダミー要素が一度出るためそれを無視するようなケアを行いましたが、
サイトが異なってもほぼ同じやり方が流用できそうでした。
STM32F103C8とOLED、OLED096UNO-AでHello Worldを表示2(16x8)


x mbedが使える人が対象
x SSD1306_128x64_I2Cライブラリインストール済
x 注意　説明を大幅に省略

1.mbedでstm32f103c8をコンパイル出来るようにする。
2.新規プログラムを開く
3.下記のソースを書く。
4.oledのライブラリをインストールする。
Dai YokotaさんのSSD1306_128x64_I2Cライブラリを使用した。
https://os.mbed.com/users/jk1lot/code/SSD1306_128x64_I2C/file/46dcbaa430f4/SSD1306.h/

工夫点
8x8を16*8にした

忙しい人よう
https://os.mbed.com/users/caa45040/code/oled_helloworld_8x16_103_1/


```c++


//
// 128*64
// 303 oled 8*16
//

#include "mbed.h"
#include "SSD1306.h"
#include "font_8x8.h"

DigitalOut myled(LED1);

#define ADDR     (0x3c<<1) //  address
//#define ADDR     (0x3d<<1) //  address

//I2C i2c(I2C_SDA, I2C_SCL);
I2C i2c(PB_7, PB_6); // STM32F103C8

// Host PC Communication channels
//Serial pc(USBTX, USBRX); // tx, rx
Serial pc(PA_9, PA_10); // tx, rx 103

// Instantiate OLED
SSD1306 oled(i2c, ADDR);

char ddff[8*4];

void char11(int row,int com,int cha)
{

    int char_index1;

    char_index1 = cha-0x20;

    int ii;

for (ii = 0;ii<(8*2);ii++) {ddff[ii]=0;} // オールクリア
for (ii =0;ii<8;ii++){
ddff[ii+ 0] = ddff[ii+ 0] | ((font_8x8[char_index1][ii] >> 0) & 1)<<0; //1bit 1 
ddff[ii+ 0] = ddff[ii+ 0] | ((font_8x8[char_index1][ii] >> 0) & 1)<<1; //1bit 2
ddff[ii+ 0] = ddff[ii+ 0] | ((font_8x8[char_index1][ii] >> 1) & 1)<<2; //2bit 3
ddff[ii+ 0] = ddff[ii+ 0] | ((font_8x8[char_index1][ii] >> 1) & 1)<<3; //2bit 4
ddff[ii+ 0] = ddff[ii+ 0] | ((font_8x8[char_index1][ii] >> 2) & 1)<<4; //3bit 5
ddff[ii+ 0] = ddff[ii+ 0] | ((font_8x8[char_index1][ii] >> 2) & 1)<<5; //3bit 6
ddff[ii+ 0] = ddff[ii+ 0] | ((font_8x8[char_index1][ii] >> 3) & 1)<<6; //4bit 7
ddff[ii+ 0] = ddff[ii+ 0] | ((font_8x8[char_index1][ii] >> 3) & 1)<<7; //4bit 8
ddff[ii+ 8] = ddff[ii+ 8] | ((font_8x8[char_index1][ii] >> 4) & 1)<<0; //5bit 1
ddff[ii+ 8] = ddff[ii+ 8] | ((font_8x8[char_index1][ii] >> 4) & 1)<<1; //5bit 2
ddff[ii+ 8] = ddff[ii+ 8] | ((font_8x8[char_index1][ii] >> 5) & 1)<<2; //6bit 3
ddff[ii+ 8] = ddff[ii+ 8] | ((font_8x8[char_index1][ii] >> 5) & 1)<<3; //6bit 4
ddff[ii+ 8] = ddff[ii+ 8] | ((font_8x8[char_index1][ii] >> 6) & 1)<<4; //7bit 5
ddff[ii+ 8] = ddff[ii+ 8] | ((font_8x8[char_index1][ii] >> 6) & 1)<<5; //7bit 6
ddff[ii+ 8] = ddff[ii+ 8] | ((font_8x8[char_index1][ii] >> 7) & 1)<<6; //8bit 7
ddff[ii+ 8] = ddff[ii+ 8] | ((font_8x8[char_index1][ii] >> 7) & 1)<<7; //8bit 8
}//for

oled.writeBitmap((uint8_t*) ddff,
              row, (row + 2 - 1),   //y
              com, (com + 8 - 1));  //x

} //end chr11    

int main() {
    int ii;
    pc.baud(9600);

    char ss1[]="Hello World !";
    ii=0;
    while(ss1[ii]!=0){
        //     y  x    文字
        char11(0,ii*8,ss1[ii]);ii++;
    }
    pc.printf("Printed something\r");    
}



```

![103_mbed_oled_hloo16_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2f463a82-d369-5c95-da39-38bc48da756b.jpeg)
【Python】Listを文字列として出力する方法

# 概要
１：文字列を含むlistを文字列に変換
２：数値を含むlistを文字列に変換

## 検証環境
OS：18.04.5 LTS
Python：3.6.9

# 方法
## 文字列を含むlistを文字列に変換
```python
list = ['v','e','r','i','f','y']
print(''.join(list))

# 実行結果
verify
```

## 数値を含むリストを文字列に変換
### 
```python
list = [0,1,2,3,4,5]
print(''.join(map(str,list)))

# 実行結果
012345
```

```python

data = [0,1,2,3,4,5]
print(*data, sep='')

# 実行結果
012345
```
CareKitのコードから学ぶCore Dataの活用方法

# はじめに

CareKitはアップルが開発しているオープンソースのフレームワークです。iOSとMacで動作します。
また、内部の永続化、検索処理にCore Dataを活用しているという事で、昔CoreDataを使いまくっていた人間としては活用方法に非常に興味があります。ただ、Core Data自体を使う事は今はあまりお勧めしません。

# ソースコード

CareKitのソースコードは[ここ](https://github.com/carekit-apple/CareKit)から入手可能です。

# 理解する上で参考となる文献

CareKitで使っている各種設計パターンについてはマーチンファウラーの有名な文献が参考になります。

[エンタープライズアプリケーションアーキテクチャパターン]  (https://www.amazon.co.jp/dp/B01B5MX2O2)

# 基本的な設計思想

前述の通り、Core Dataを活用しています。ただし、利用者には隠蔽しています。理由はCore Dataを剥き出しにする設計にすると、利用者はCore Dataを学習する必要があるからです。これは他のフレームワーク、EventKit, ContactsKit, HealthKitも大体同じ考えです。

# OCKStore周りのクラス構成
![OCKStoreの構造.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39706/1fd1fee9-86d2-0913-940e-7764c7df857b.png)
OCKStoreクラスは所謂リポジトリクラスです。プロトコル指向で実装しており、図以外にもプロトコルを継承しています。この辺についてはこの記事では深堀しません。
OCKStoreクラスは内部にCoreDataフレームワークのインスタンスを内部に持っています。

# OCKCarePlan周りのクラス構成
![CarePlanクラスの構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39706/32f0e6a3-601f-d61f-e4f8-0d1dcbb0792a.png)
ごちゃごちゃしていますが、利用者に見せるOCKCarePlanクラスとCoreDataとのやりとりに使うOCKCDCarePlanクラスに分かれています。
OCKStoreから検索、保存等を行う際に相互に変換します。所謂データマッパーパターンです。NSManagedObjectから派生している方のクラスは所謂DTOとして使っています。どうやって変換しているかについては現段階では深堀しません。

# OCKCarePlanQuery周りのクラス構成
![OCKCareQueryクラスの構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39706/9114014a-9160-f446-6edc-6a51be81d3fa.png)
OCKCarePlanQueryクラスは所謂Queryオブジェクトです。検索する際に、OCKStoreがOCKCarePlanQueryのメソッドを使ってNSPredicateやSortDescriptorクラスに変換します。このクラスがあるおかげで利用者はNSPredicateの文法やクエリーの詳細を覚えなくてすみます。

# 検索処理の流れ
![フェッチのシーケンス図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39706/467ccda2-8ce5-e78c-c481-33ae53119b9d.png)
検索処理の流れです。わかりやすくするためにOCKCarePlanStoreとOCKStoreと分けて書いています。OCKStoreクラスが内部でCore Dataとのやりとりに必要なデータに変換、Core Dataに渡しています。Core Dataから帰ってきたデータを利用者に公開しているOCKCarePlanオブジェクトに変換しています。意外な事にNSManagedObjectContextを複数使って処理負荷を下げる事はしていませんでした。

# 追加、更新、削除処理の流れ
WIP

# まとめ
CareKitの永続化周りのコードを追うことによって、参考文献に載っている様々な設計パターンが活用されている事がわかりました。ここでは説明していませんが、これまでの説明以外の様々なパターンが活用されています。
なお、開発メンバー全員がCore Dataに精通している場合はこのような複雑な設計を採用する必要はないかもしれません。
UXやUIを重視したアプリQAについて


# プロダクトはUXやUIを重視したアプリ

ユーザーに**高品質**かつ**ストレスを与えないサービス**を利用していただくために
例えば、**アプリ**だと色合いの方が**重要視**（ターゲット層によっても異なる）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/66a0736a-5e08-0f9b-d1b5-5b765721d99b.png)

- UXやUIの観点
- 多端末側面（機種、利用OS・利用OSバージョン）

-  [アプリ動作](https://qiita.com/jun2014/items/34ad620159550f20372b)

品質を担保する仕組作りをしておりました。

# テスト

- 機能テスト：コアキングスペースでリラックスしながら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/836280ac-faab-2d21-2c18-55609e8b6715.png)

- バックエンドテスト：CharlesとFirebaseを利用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/a659f2ee-7684-e898-b63e-ce54728af206.png)

# QAでは下記の内容を重視

1.**リリーススピード**と**品質**、両方とも大事でありQAが社内にあることでアプリチームの負担が軽減

2.**過去起きた障害**を分析し、把握対処することに時間をかけることが可能

3.QAの情報をアプリチームにも提供できQAへの意識が高まる

4.不具合改修確認を勝手にデザイナー、アプリエンジニアがすることがなくQAに最終権限

# プロジェクトQA体制
1.iOSアプリエンジニア
2.Androidアプリエンジニア
3.QAエンジニア
4.QAテスター

の4名で進めてみる

# QAフェーズ
 
QAフェーズとして**3種類**になります

**Overall QA**

**Must QA**

**Production QA**

# QAフェーズ詳細
**Overall QA**

・既存機能と新規機能に関する機能や表示のテストを **「通常利用に問題がないか」** という観点で行うことで **「ユーザー」** に対して **「アプリの利用体験が適な状態」** を保証する

・このQA工程のみ、 **「アプリエンジニアやデザイナー」** も参加します。

・理由としては、QAだけではなくアプリエンジニアやデザイナーも参加することで開発部全体のQA底上げができる

・アプリエンジニアやデザイナーがQAを通じて現状の課題や今後の対応すべき内容をいち早くキャッチアップできる点がメリットである

・どういう不具合が多いのか、傾向を把握することにより、今後実装時に生かすことができる点。

・QA期間内は、毎朝朝会で昨日の不具合チケットや要望Issueチケットを確認し、**優先対応レベル判断**を用意しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/852efe1a-2d5d-f6a9-0292-64af1db56bf9.png)


**Must QA**

・ **「金銭の授受を含み契約に関連する機能」** に関する、同意した項目テストを網羅的に実装されているかという観点で行うことで社内のステークホルダーに対してクライアントに提供するものが不完全ではないことを保証する。
・FirebaseのDebugViewで対象ログが出力されているか。impやClickであったり。
・Charlesでリクエストやレスポンス確認

DebugViewでリアルタイムにログ確認
https://console.firebase.google.com/?hl=ja

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/f3381f0d-0ef6-efc2-c30f-214cc6992eee.png)

Charlesは、AndroidやiOSのスマホアプリテストでJSONファイルを書き換えで、リクエストやレスポンス確認にちょっと使っております。

https://www.charlesproxy.com


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/351624a5-a680-0e2c-5291-4c6cfb0ce1ce.png)




**Production QA**

・最終チェックであり、 **「起動できることマーケティング（スキーマ起動）できること、バージョンが正しいこと、PUSH通知が送れること、強制アップデートができること、ログが本番の分析環境に正しく出力していること」** を確認する


# 全体のまとめ
・リリースマネージャとともに、リリース計画からリリース予定日までリリース全体の把握とリリース品質を判断し、リリースの可否を決めます。このリリースマネージャが社内のリリース作業の効率化を行います。
QA実施は、開発エンジニアがコードフリーズ後に取り掛かります。

# 今後どうあるべきか
・まずはテスト自動化できる項目を洗い出し、[Appium](https://qiita.com/jun2014/items/10ac6065af513190e9ff)という**モバイルテストフレームワーク**を利用し。自動で確認できる仕組み。

・手動テストでもテスト設計レベルを、要件・因子でGithubのIssueテンププレート化し直交表に落とし込むことにより、禁則であったり網羅性の担保、全てのテストケースを作成する工数自体削減できる

# 取り組み
・**一定の品質を提供するテスト設計のテンプレート**を用意することにより、誰でも同じ粒度のテストケースが左作成でき、アプリリリース時にも同じ品質のアプリを常に提供できる

・第三者からのテストというレビューUXやUIについても。まずはQA時に1ユーザーとして気になる点や、使い勝手をチケットに記載。これは不具合というよりもユーザー視点でのレビュー

・独立性を保つため、アプリエンジニアとQA担当が分かれることによりお互い独立視点を維持できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55160/b39f53b5-8c37-6138-6db5-8a2e5947cbf2.png)
【学習記録】Railsチュートリアル　一章

Railsチュートリアルに記載された手順通りに作業したのにlocalhost:3000に接続できなかった時にやったこと

試したこと（）
・サーバの再度立ち上げ
・一度ログアウトして再度ログインし直す
・adBlockの無効化
・bundle installとupdate
・cloud9を作成し直す





結局qiitaで同じエラーの投稿を見つけ解決に至った。
Dockerコンテナのアタッチとデタッチについて

## はじめに
Dockerコンテナのアタッチとデタッチについての備忘録。

## コンテナのアタッチとデタッチ

### アタッチとは：
コンテナと接続している状態で、フォアグラウンドでコンテナが起動する。

### デタッチとは：
コンテナと切り離した状態で、バックグラウンドでコンテナが起動する。

### オプション：

|オプション|省略形|説明|補足|
|---|---|---|---|---|
|--interactive|-i|Keep STDIN open even if not attached|標準入出力をコンテナに対して結びつける。つまり、入力した文字はコンテナに渡され、コンテナからの出力が画面に表示されるようになる。|
|--tty|-t|Allocate a pseudo-TTY|pseudo tty (=pty: 疑似端末/仮想端末)を有効にする設定。(疑似端末は、カーソルキーやエスケープキー、［Ctrl］キーなどで操作するためのもの。)|
|--detach|-d|Run container in background and print container ID|コンテナと端末を切り離してバックグラウンドで実行するオプション。|

### 補足：
- 「i」「t」「d」の3つのオプションの組み合わせて、-itdでつかうことが多し。
- コンテナのアタッチとデタッチは切り替え可能。
  - ［Ctrl］＋［P］、［Ctrl］＋［Q］の順に押下で、コンテナをデタッチできる。
  - `$ docker attach CONTAINER ID` でコンテナにアタッチできる。
- コンテナにアタッチ状態で［Ctrl］＋［C］押下すると、コンテナをSTATUS: Exitedになる。

### 実例：

```bash:アタッチモードでコンテナを起動
$ docker run -it nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up

```
```bash:アタッチモードで起動したコンテナをデタッチする
［Ctrl］＋［P］、［Ctrl］＋［Q］を押下でデタッチし、コンテナが起動中であることを確認。

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
51687903bc7c   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   80/tcp    intelligent_lehmann
```
```bash:デタッチしたコンテナに再びアタッチする
$ docker attach 51687903bc7c
```
```bash:デタッチドモードでコンテナを起動
$ docker run -itd nginx
9c68f8ccd978d7071ddbb915f38a552995c069c28f97a25a97681451d3896a68
```

### 備考：

コンテナ内に入っている状態で、［Ctrl］＋［P］、［Ctrl］＋［Q］を押下すると、ホスト側に操作が切り替わる。（コンテナは起動状態。）

```bash
$ docker run -it nginx bash

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                      PORTS     NAMES
7fa53110f23f   nginx     "/docker-entrypoint.…"   22 seconds ago   Up 21 seconds               80/tcp    lucid_shirley
```
【HTML】エスケープ処理を行う方法

#プログラミング勉強日記
2021年3月6日

#エスケープとは
　エスケープは、HTMLのコードでは別の意味を持ったり環境に依存する文字(特殊文字)を別の文字列に置き換えること。
　例えば、`<`や`>`はHTMLのタグで使われているので、文章中に含めると不具合が生じる可能性がある。そこで、`&lt;`, `&gt;`に置き替えることで、安全にページを表示できる。

　実際にスペースの扱い方には気を付ける必要がある。

```html
<p>あ&nbsp;い&nbsp;う&nbsp;え&nbsp;&nbsp;&nbsp;お(エスケープ文字)</p>
<p>あ い う え   お（半角スペース）</p>
<p>あ　い　う　え　　　お（全角スペース）</p>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/9a42824b-a8e0-4671-34c0-4d2c20682ef4.png)


#特殊文字一覧

| 表示 | 記号 |
|:--:|:--:|
| < | `&lt;` |
| > | `&gt;` |
| & | `&amp;` |
| © | `&copy;` |
| " | `&quot;` |
| ' | `&#39;` |
| 空白文字 | `&nbsp;` |



#参考文献
[HTMLのエスケープとは？スペースを表示させる方法について解説！](https://www.sejuku.net/blog/85398)
[HTMLで特殊文字のエスケープ処理を行う方法【初心者向け】](https://techacademy.jp/magazine/12553)
[Flutter] Flutter 2.0 Migration方法

## Migration

- 方法

```
> dart migrate
```

- Process

```
C:/Users/itsme/Documents/GitHub/flutter_migration> dart migrate
Migrating C:/Users/itsme/Documents/GitHub/flutter_migration

See https://dart.dev/go/null-safety-migration for a migration guide.

Analyzing project...
[------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\]
No analysis issues found.

Generating migration suggestions...
[-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------]

Compiling instrumentation information...
[-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------]

View the migration suggestions by visiting:

  http://127.0.0.1:59295/C:/Users/itsme/Documents/GitHub/flutter_migration?authToken=SLX1RWDeq6Y%3D

Use this interactive web view to review, improve, or apply the results.
When finished with the preview, hit ctrl-c to terminate this process.

If you make edits outside of the web view (in your IDE), use the 'Rerun from
sources' action.

```

migrateをすると、Null　safety　Previewのリンクかでます。


## Proposed null safety changes
- リンクはプロジェクトによって、違います。

```
http://127.0.0.1:59295/C:/Users/itsme/Documents/GitHub/flutter_migration?authToken=SLX1RWDeq6Y%3D
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/3292ce0c-cb4e-6e08-1e40-9bc97e4364f9.png)


## Apply Migration
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/924f52c5-cff2-2ee2-cfd8-9bd88c262bd0.png)

- マイグレーションにすると、environmentの変えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137182/96305b86-2f39-3515-581e-e78b18a7cde2.png)
RailsでQRコードを生成

<h1>前提条件</h1>
・ruby 2.6.6
・rails 6.0.3.4
・macOS Catalina バージョン10.15.7

<h1>概要</h1>
　webアプリ内で一般的な会員システムに搭載されているmyQRコードを作成したいと思い、実装したので忘れないようここに残すことにした。
　難しいことは特になく、比較的簡単に実装が完了した。

<h1>gemの導入</h1>
　webアプリ内にQRコードを生成させるためには
・gem 'rqrcode'
・gem 'chunky_png'
　の２つを導入する必要がある。

```ruby:Gemfile
gem 'rqrcode'
gem 'chunky_png'
```

```ruby:ターミナル
bundle
```
これで前準備は完了。
次にコードを書いていく。

<h1>QRコードを生成させる</h1>
　今回は個人的な理由だが、各ユーザーのマイページに設置したいため、user_helper.rbにコードを記述する。

```ruby:app/helpers/users_helper.rb
module UsersHelper
#ここから
require 'chunky_png'

  def qrcode_tag(url, _options = {})
    qr = ::RQRCode::QRCode.new(url)
    ChunkyPNG::Image.from_datastream(qr.as_png.resize(250, 250).to_datastream).to_data_url
  end
#ここまで
end
```

　引数でurlを渡すことで、pngを生成する。
　また注意して欲しいのが、gemを導入しているときはターミナルでwebアプリを再起動してからじゃないと、エラーが起きてうまく作動しないので注意。（自分も忘れていて何でエラーが起きているかわからなかった。）

<h1>Viewに表示させる</h1>
　QRコード生成の準備ができたので、ViewでQRコードを表示させるコードを書いていく。自分の場合は何度もいうがマイページに設置したいので users/show.html.erb　に記述していく。

```ruby:users/show.html.erb

<%= image_tag qrcode_tag url %>
```

とは言っても表示させたい場所に上記のコードを記述するだけで完了。
urlの部分に、生成されるQRコードを読み取ったときに遷移させるページのURLを記述すれば、読み込んだときにそのページに遷移するQRコードが生成される。以上。

<h1>参考文献</h1>
・QRコードの生成・埋め込み
　https://qiita.com/koteko/items/d6d033997c544c47b718
・https://github.com/whomwah/rqrcode
・https://github.com/wvanbergen/chunky_png
react-routerでルーティングしているSPAをApacheに公開する

##はじめに
始めてReactを使ってSPAを作成し、Webサーバ（さくらVPS）で公開しようとした時に、ルーティングがうまくいかずてこずったので。備忘録も兼ねて書きます。

##状況
React Reduxを使用してSPAを作成していた。

・connected-react-router
・react-router
を使いルーティングを実現していた。

ローカル環境では問題なくルーティングは動いていた。

##問題点
「npm run build」してできたbuildフォルダ内のファイルを、Webサーバにアップロードしてアクセスしたら、ルーティングで読み込んでいたコンポーネントが表示されなかった。

「～/login」というパスをURLに打ち込むと「404:Not Found」が表示された。

##疑った事
build時の設定（package.json）の設定を変更してbuildをして、特別な形のファイル書き出しを行わないといけないのではないか。

##解決方法
結論を先に書くと

**publicフォルダに.htaccessを追加してbuildする。**

です。

```:.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html [QSA,L]
```

ここからは紆余曲折を書いていこうと思うので、急いでいる方はどうぞ読み飛ばしてください。
なかなかこの結論に達するまでに時間を費やしたので、変なテンションで書いていきたいと思います。

まずは、connected-react-routerやreact-routerを使用したルーティングのbuild方法やデプロイ方法を調べようと思い、「react connected-react-router build デプロイ」なんて感じで検索し、いろんな記事を漁りました。

なかなか解決になるような記事は見つからず、途方にくれ始めてこのQiitaアカウントを作成し、質問を投稿してみました。（※この事が今回の中で一番の収穫であろう）
まぁ、そんな早く返信もあるはずもなく、Qiita内で検索できる事を知り（どんだけ使った事ないんだという、、、） Reactやreact-router関連の過去記事を漁りました。

build・デプロイ関連の記事も沢山あるんですが、

いろんな記事を読んでいくうちに、自分の大きな勘違いに気づきました。

**SPAなんだから、buildされてできるのはindex.htmlだけ**

てっきりreact-routerを使うとそういうディレクトリ構成でbuildされると思っていたわけです。
なので、packege.jsonになにか設定を書くじゃないか、webpack.config.jsを修正するんじゃないかと違う方向ばかりに目が向いていました。

そして、行きついた先が、create-react-appの[公式ページ](https://create-react-app.dev/docs/deployment/ "create-react-app")でした。
**やはり、公式ページをちゃんと見るのが大事。**

こちらにちゃんと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1177606/1e37fee6-bc29-bd5b-de60-da0a9210e822.png)

と書かれていました。。。。

公式、大事。

という事で、無事.htaccessを追加してbuildを行いこれでOKとルンルン気分でアップロードしアクセスしたんですが。。。

##落とし穴がありました。
ならん。
Not Found変わらない。

なぜだ！！！

書き方が悪いのかと調べているとこちらの記事に辿りつきました。

https://tech-it.r-net.info/program/react/271/

この記事内の注釈に

**※mod_rewriteが利用できることが前提です。**

と書いてありました。

ん？

今までレンタルサーバしか利用した事なかったけど、.htaccessって標準で使えるものなの？
さくらVPSにApacheのインストールは自分でしたから.htaccessが使える設定じゃないんじゃないの？

と思い、バージョン、設定を確認したところ

Apacheのバージョン：2.4.6

設定で.htaccessが無効になっていたので、こちらの記事を参考に有効に変更しました。

https://www.sakura-vps.net/2014/06/11/htaccess-available/

これで、無事に遷移（ルーティング）ができました。
ぱちぱち

##終わりに
実はこの解決にいたるまで、3日ほど検索を行っていました。
なかなか、解決に辿り着けずもやもやした毎日を過ごしていました。

ですので、同じ事で悩んでいる人がもしいた時の為に今回初めて記事を投稿しました。
誰かの約に立てば嬉しいですね。

今後はもっとQiitaなどのサービスを活用して理解を深めていきたいと思います。

今回ひとつ解決したけど、また壁にぶつかりそう。。。。
その時はまた記事にしたいと思います！
Google places apiを使い倒す


今日やること
・[google places api](https://cloud.google.com/maps-platform/places/?hl=ja)の使い方を理解して、電話番号から店舗情報を取得する

#Google places api
まず事前準備がいくつかあります。

最初にGoogleアカウントが必要ですので、アカウントがない場合は作成しておきます。 また、 [Google Places API Web Service](https://developers.google.com/maps/documentation/places/web-service/search?hl=ja) の仕様を確認してみると、「APIキー」なるものが必要とありますのでこちらも取得します。 APIキーを取得する手順は以下の通りです。

####1.[Google API Console](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwjY6OH78ejNAhWHnpQKHeBuDaEQFggrMAA&url=https%3A%2F%2Fconsole.developers.google.com%2F%3Fhl%3DJA&usg=AFQjCNGj0x-PAc20W6CsV-wXWgvq6l3kgA) でログインする。

####2. Google APIの認証情報へいく
![スクリーンショット 2021-03-06 17.56.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965206/b054dc9d-d251-22ed-7ebe-bad5c2f7d1f2.png)


####3. 認証情報を作成をクリックしAPIを作成する
![スクリーンショット 2021-03-06 17.57.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/965206/ebea2793-3f59-ede5-3e9b-8e431d62e339.png)



####4. APIを保存する
無事にAPIが作成されたのでどこかに保存しておきましょう。


#google places search rest api
[google places search rest api](https://developers.google.com/maps/documentation/places/web-service/search?hl=ja)を読んで電話番号で位置情報を取得したい。

記事を確認したが現時点では日本語の記事が少なくドキュメントを理解する方が早そう、、、

今回使っていくのはFind placeという機能です。

これにより名称や電話番号を使ってピンポイントに施設を検索することができるようです。


##URLに情報を追加していく

先程のドキュメントからHTTPのフォームを取得することができるのでそこに情報を追加していく。

```
https://maps.googleapis.com/maps/api/place/findplacefromtext/output?parameters
```
今回はjson形式で情報を取得したいので`output`を`json`に変更。`Required parameters`を見ると`key`, `input`, `inputtype`をそれぞれ指定する必要があるので必要な情報を指定していく。

今回の場合はこのようになった。

```
https://maps.googleapis.com/maps/api/place/findplacefromtext/json?&key=mykeycode&input=%2B810426349723&inputtype=phonenumber&fields=name(etc.)
```

`input`の[%2B]とは[＋]のことだが[URLエンドコード](https://tech-unlimited.com/urlencode.html)で利用する場合このように変換しておかないとエラーになる。

より詳しい情報を取得したい場合は`Place Details`を利用する。

この場合必要になる情報は下記の通りだ。

・output / json or xml
・key / api key
・place_id / Place Searchで取得できるもの
オプションとして次のものを指定できる
・language /　[選択可](https://developers.google.com/maps/faq?hl=ja#languagesupport)
・fields /  [選択可](https://developers.google.com/maps/documentation/places/web-service/details?hl=ja#fields)

では先ほどと同様にURLに必要な情報を入力していこう

```
https://maps.googleapis.com/maps/api/place/details/json?&key=mykeycode&place_id=ChIJR0OkRtgdGWAR2rkr1KG8dqA&fields=formatted_phone_number
```
これでおそらく電話番号を取得できると思う。他にもいろいろな情報を取得できるので遊んでみよう！

今日はここまで。

#今日の課題

Postモデルに保存した写真をサーバー上でダウンロード

Gmapmapを使って地図上に緯度と軽度でpostを表示する
RailsにAjaxでデータ保存する時に困ったこと

## 記事の目的 ##
Railsでオリジナルアプリを作成中にAjaxでデータ保存出来ずに困ったこと、どのように解決したのかを忘れないために書いておきます。

## 開発環境 ##

- macOS Big Sur 11.1
- VScode
- Ruby 2.6.5
- Rails 6.0.3.4
- mysql 14.14
- JavaScript
- gem 3.0.3
- heroku 7.47.12

## オリジナル読書アプリ ##
読書アプリケーションを作りました。
https://github.com/hiro-mu/book_smart.git

## 困ったこと　##
実装したのは読書アプリによくあるようなドラッグした部分の背景色が変わる機能です。
この機能の実装は
1. 文字列がドラッグされた場合にイベントが発生し、その文字列をデータベースに保存
2. データベースに存在する文字列が表示されている場合、replaceメソッドでブラウザ上のHTMLに背景色を変えるCSSを追加
と言う流れで行っています。
難しかったところはこの部分です。

```javascript:highlight.js
XHR.open("GET", `/highlights/create?book_id=${bookId}&pagenum=${pageNum}&text=${selectedStr}`, true);
```
本来であればデータベースに変更を加えるリクエストなので、POSTを使うべきです。しかし、保守性の観点からRailsに外部からのデータベースを変更させるPOSTやPUTのリクエストは受け付けないという機能があるらしく、データベースに保存出来ませんでした。（厳密にはRailsはDELETE、PATCH、PUTのHTTPメソッドは全てPOSTとして扱うようです）
ようやく見つけた解決策は、HTTPメソッドはGETにしておいて、パラメータをURLに含めて送ってしまおうという手法でした・・・もっといい解決策があれば知りたいです。

## 学んだこと ##
CSRFなどの不正なリクエストのためにRailsに備わっているセキュリティ対策によって自身が苦しめられました。非常に勉強になりました。
React(material-ui)カスタマイズ

Reactでチャットボット作ろう！
今回は以下のとらゼミさんの動画を参考にチャットボットを作成中。です！
現在はお問い合わせ内容をSlackに送るところまで出来ました。
非常にわかりやすく解説してくれるので、理解が深まります！

https://www.youtube.com/watch?v=MzJkWO73S70&list=PLX8Rsrpnn3IVOk48awq_nKW0aFP0MGpnn

動画でもあるんですが、
今回は以下の内容を！

##**Material-ui**
Material-uiのカスタマイズ方法です！
Hook APIを使用してやります。

インストール

```
npm install --save @material-ui/styles
```

import 

```
import {createStyles, makeStyles} from '@material-ui/core/styles'¥¥¥¥¥
```

関数定義

```
const useStyles = makeStyles(() => (
  createStyles({
    "button": {
      borderColor: '#FFB549',
      color: '#FFB549',
      fontWeight: 600,
      marginBottom: '8px',
      "&:hover": {
        backgroundColor: '#FFB549',
        color: '#fff'
      }
    }
  })
));
```

ここまで出来たら、以下のように。
useStylesをclassesに入れて、このように⇨className={classes.button}

```
const Answer = (props) => {
  const classes = useStyles();

  return (
      <Button
       className={classes.button}
       variant="outlined" onClick= {() => props.select(props.content,props.nextId)} 
      >
        {props.content}
      </Button>
  )
}
```

##感想

まだ作成途中ですが、
コンポーネントの設計がしっかり出来ているから、とてもコードが理解しやすいのだろうと
思うところです。私も何か作るときは自分なりに考えて設計を組み立てていきます！


今回は以上、ありがとうございました。
【初心者】Swift UIを勉強する その② ーーーSymbolsとList

# はじめに

**今回のはシンボルとリストの作成方法を学習していきます。**

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/a154c2c7-cb57-fea4-319d-66a94ba136a5.gif" width=30%>

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [SF Symbols](#SF Symbols)
2. [リスト作成](#リスト作成)
3. [まとめ](#まとめ)
4. [参考文献](#参考文献)


<!-- 各チャプター -->
<a id="#SF Symbols"></a>
# SF Symbols
・appleさんはシンボルアプリを提供していますので、[SF Symbols](https://developer.apple.com/sf-symbols/)をダウンロードしましょう。

![截屏2021-02-23 15.19.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/09222303-a4d8-24ed-0dca-1336359b436b.png)
・Swift UIファイルを新規作成し、SF Symbolsを使ってみましょう。
　SF Symbolsアプリにてシンボルの名称をImageとして作成します。
　また、デフォルトのシンボルはかなり小さいので、`imageScale()`を使って大きさを決めましょう。
　だたし、こうやるとシンボルのみサイズが変わるために、シンボルとセットになっているパーツを揃ってデザインを変えるのがおすすめです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/4053a0f3-fc01-749c-70ad-47cdc94e2dfd.png" width=40%> 

```swift:CourseRow.swift
struct CourseRow: View {
    var body: some View {
        HStack(alignment: .top) {
            Image(systemName: "paperplane.circle.fill")
                .renderingMode(.template)
                .frame(width: 48.0, height: 48.0)
                .imageScale(.medium)
                .foregroundColor(.white)
            }
        }
    }
}
```

・シンボルのフレームを48x48に、背景色と`clipShape(Circle())`で円形に切り取りで完成です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/be5c4019-baa7-ddb4-327c-5c6507403b85.png" width=20%>

```swift:CourseRow.swift
struct CourseRow: View {
    var body: some View {
        HStack(alignment: .top) {
            Image(systemName: "paperplane.circle.fill")
                .renderingMode(.template)
                .frame(width: 48.0, height: 48.0)
                .imageScale(.medium)
                .background()
                .clipShape(Circle())
                .foregroundColor(.white)
            VStack(alignment: .leading, spacing: 4.0) {
                Text("SwiftUI")
                    .font(.subheadline)
                    .bold()
                Text("Description")
                    .font(.subheadline)
                    .bold()
            }
            Spacer()
        }
    }
```





<a id="#リスト作成"></a>
# リスト作成
・新規Swift UIファイルを作成し、先ほど作った`CourseRow()`を呼び出します。
・`List{}`に詰め込めば完成しました。(UIKitのようにscrollViewがなくでもスクロールできて感動しました)
![截屏2021-02-23 16.54.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/6d8970ab-0c71-d3a5-eee5-888793086e09.png)

・Listのスタイルは何かあるのかをみたい時に、`option`を押しながら`listStyle`のドキュメントからチェックできます。
![截屏2021-02-23 16.57.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/9ab56841-a544-f464-5fd0-ea009cc09edb.png)



<a id="#まとめ"></a>
# まとめ
・UIKitの半分のコードでlistを作れました。再びSwift UIの強さを感じました。


**ソースコードは[Github](https://github.com/wsimple1028/swiftUI_ios14)**

<a id="#reference"></a>
# 参考文献
- [Design Code --- SwiftUI for iOS 14](https://designcode.io/swiftui-ios14)
- https://www.anchorblogs.com/
gitコマンドメモ

#基本的な使い方

```
git init
```

リポジトリの作成をする
一番初めに必ず実行する

```
git add -A
もしくは
git add .
```

プロジェクトのすべてのファイルをリポジトリに追加する

```
git status
```

Gitにプロジェクトのファイルを追加すると、最初はステージング（Staging）という一種の待機用リポジトリに置かれ、コミットを待ちます。安全のため、いきなりコミットしないようになっているのです。ステージングの状態を知るにはstatusコマンドを使います。

```
git commit -m "Initialize repository"
Initialize repositoryは例なので、任意でコミット名を変える
```

ステージングエリアで控えている変更を本格的にリポジトリに反映（コミット）するには、commitコマンドを使います。
mフラグを使うと、コミットメッセージをコマンドラインで直接指定できます。-mフラグを使わない場合はシステムのデフォルトのエディタが開き、そこでコミットメッセージを入力します。

```
git log
```

logコマンドでコミットメッセージの履歴を参照できます。

#ブランチを使用する場合
##流れ
トピックブランチ作成
↓
ブランチ上で変更をコミット
↓
トピックブランチをmasterブランチにマージ
↓
（ブランチを削除）

```
git checkout -b (ブランチ名)
```

トピックブランチ（短期間だけ使う一時的なブランチ）はcheckoutと-bフラグを使って作成できます。

```
git branch
 master
* modify-README
```

git branchは、すべてのローカルブランチを一覧表示します。「*」はそのブランチが現在使用中であることを表します。

```
git commit -a -m "(コミット名：命令形かつ現在進行形)"
```

ブランチ上でコミット

```
git checkout master
git merge (マージしたいブランチ名)
```

コミット後、上記のコマンドでブランチをmasterブランチにマージ

```
git branch -d (ブランチ名)
```

変更をマージ後、上記のコマンドでトピックブランチを削除して終了。
トピックブランチの削除は必須ではありません。実際、トピックブランチを削除せずにそのままにしておくことはよく行われています。トピックブランチを削除せずに残しておけば、トピックブランチとmasterブランチを交互に行き来して、キリの良い所で変更をマージする事ができます。

```
git branch -D (ブランチ名)
```

トピックブランチ上の変更を破棄することができる
-dフラグと異なり、-Dフラグは変更をマージしていなくてもブランチを削除してくれます。

#GitHubへのプッシュ

```
git push (origin masterは省略可)
```
Ruby で解けず Java と Crystal で解く AtCoder ABC 189 C

# はじめに
*[AtCoder Problems](https://kenkoooo.com/atcoder/#/)* の Recommendation を利用して、過去の問題を解いています。
AtCoder さん、AtCoder Problems さん、ありがとうございます。

# 今回のお題
*[AtCoder Beginner Contest C - Mandarin Orange](https://atcoder.jp/contests/abc189/tasks/abc189_c)*
<font color="brown">Difficulty: 565</font>

今回のテーマ、トランスパイラ

コンテスト中にRubyのコンテスタントが7名しか解けなかった問題です。
実行時間制限: 1.5 sec と厳しいのですが、Difficultyは茶色でした。
# Java
```java.java
import java.util.*;

class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = Integer.parseInt(sc.next());
        int a[] = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = Integer.parseInt(sc.next());
        }
        sc.close();
        long ans = 0;
        long max = 0;
        for (int i = 0; i < n; i++) {
            long min = 1000000000;
            for (int j = i; j < n; j++) {
                if (min > a[j]) {
                    min = a[j];
                }
                if (max < min * (j - i + 1)) {
                    max = min * (j - i + 1);
                }
            }
            if (ans < max) {
                ans = max;
            }
        }
        System.out.println(ans);
    }
}
```
コンテスト中に`Ruby`から`Java`に切り替えて解答しました。
コードとして捻りも何もないのですが、短時間では脳が付いていかないです。
# Crystal
```Crystal.cr
n = gets.to_s.to_i
a = gets.to_s.split.map { |c| c.to_i }
cnt = 0
max = 0
n.times do |i|
  min = 10**9
  i.upto(n - 1) do |j|
    min = a[j] if min > a[j]
    max = min * (j - i + 1) if max < min * (j - i + 1)
  end
  cnt = max if cnt < max
end
puts cnt
```
このコードは`Ruby`でもそのまま動作します。
`Windows10`で`Crystal`が動作すれば代替してもいいのですが。

||Ruby|Java|Crystal|
|:--:|:--:|:--:|:--:|:--:|
|コード長 (Byte)|265|831|265|
|実行時間 (ms)|**TLE**|268|76|
|メモリ (KB)|14816|43072|3860|
# まとめ
+ ABC 189 C を解いた
+ Crystal に詳しくなった
カレントディレクトリのフォルダ直下のnode_modulesを削除

ほぼ自分用のメモですが...

## 確認のみ

```sh
find . -name "node_modules" -type d -maxdepth 2
```
## 削除も

```sh
find . -name "node_modules" -type d -maxdepth 2 | xargs rm -rf
```
Vuetifyとはなんぞ

今回はVue.jsで使用するフレームワークについて触れていきます！

#①Vuetifyとは
簡単に言うと、CSSを使わなくてもおしゃれなボタンとかができる画期的なulのフレームワークみたいです！
▶ul？　https://qiita.com/akari_0618/items/ac6eb7fae89f2329ed2c

これを使うことによって、CSSでたくさん書かなくても、言い訳ですね👌

使い方は、Vuetifyを使いたいフォルダの中に移動して、ターミナルで以下のように打ち込むと使えるみたいです👍

```
 % vue add vuetify
 % npm run server
```

で使えるようです！！

ちなみにこれはHTMLの中に埋め込まれています。
たとえばこんな感じですね。

```index.html
<v-alert
  color="red"
  dismissible
  icon="$mdiAccount"
  type="success"
>クリック</v-alert>
```
みたいな。
初めこの文字列をみたときはてな？ってなる駆け出しさんいると思いますが、落ち着いて行きましょう🥲
表示はこうなります。
![スクリーンショット 2021-03-06 18.18.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/9bb8fd9a-1729-9343-4015-6d5c5dbd7cdc.png)
CSSを入力しなくてもここまでできるのは助かりますね👌

いろいろあったので、公式さん貼っときます😊
https://vuetifyjs.com/ja/components/alerts/#section-4f7f304465b9
Webを支える技術　Web概論編３

# Webの誕生
# ハイパーメディアとしてのWeb
Webは当初**インターネットを使ったハイパーメディア**として設計された。

Web以前のハイパーメディアとの一番の違いは、**「インターネットを使う」**ということ。
これによって、**不特定多数の情報をリンクさせあう**ことができ、**システムを大規模化**しやすいという重要な利点がある。

その反面、**情報の集中的な管理は難しい（一つのサーバーで管理するのは難しい）**ために、リンク切れになりやすいという欠点もある。

また、Webが実現しているリンクは、**単方向リンク**であることも特徴だ。
元々は外部からリンクを指定するという複雑なリンク機構を取り込もうとしていたが、シンプルな単方向リンクが使われた。
# 分散システムとしてのWeb

RPCは閉じたネットワーク環境で、あらかじめ想定した数と種類のクライアントを相手にサービスを提供するシステムとしては優れている。

一方で、**オープンで不特定多数を相手にするシステム**がWebです。

Webでは、各ユーザのコンピュータ環境は特定のOSやハードウェアには統一されておらず、**さまざまなブラウザやデバイスから一つのWebサービスにアクセスできる**。

なぜなら、**クライアントとサーバの間のインターフェースをHTTPというシンプルなプロトコルで固定した**からだ。
[OutSystems]Local Storageのトランザクション

MobileアプリケーションにあるLocal Storageのトランザクションについて確認してみます。
Local StorageはiOS/Android端末内にデータが格納されるEntity。

配置先が端末内であるため、サーバーとはトランザクションの扱いに違いがある。

# ドキュメント
公式ドキュメントでは、Local Storageのトランザクションについてあまり記述がないのですが、以下のページがありました。
[Design a Lightweight Local Storage](https://success.outsystems.com/Documentation/Best_Practices/Architecture/Mobile_Data_Layer?origin=d#Design_a_Lightweight_Local_Storage)

> Local storage entity actions use individual transactions, so avoid writing multiple times in the local storage in the same request. If not possible, then design the model to endure the loss of transaction.

Local Entityでは、Entity Action (Entityを作ると自動作成されるCRUD用のAction群）呼び出しごとに独立のトランザクションになるとのこと。

以下では、このことを実地に確認してみます。

# Local Entityと確認画面を用意
Local Entity「LocalTransactionTest」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/5ba2559d-5b53-9b68-286e-bae506aa36c9.png)
DateTime：INSERT時に実行日時を設定
Number：同じタイミングで複数レコードをINSERTするときには連番を振って区別する

確認画面はこのLocal Entityからスキャフォールディングして作成します。

# INSERTを2回繰り返して実行　→　正常に2件登録される
Entity Action「CreateLocalTransactionTest」が、Local Entityの下に自動で用意されるので、これを利用してデータを登録します。

実装ロジック。CreateのEntity Actionを2回呼んだだけ。見て分かる通り、Commitを明示的に実行していません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/9e40ad12-ef21-2664-8701-7f1831ea79b1.png)

実行結果。当然ながら、2件データが登録されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/26c7d568-dec1-d8e1-2979-f189c134416c.png)

# INSERT後、例外を発生させる　→　正常に1件登録される（ロールバックされない）
ここがLocal Storageのトランザクション理解に重要な点ですね。
INSERTを1回実行後、明示的にExceptionをRaiseしてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/84b48bfe-65aa-b6fa-9877-cfd0281094a4.png)

結果。例外を発生させているのに、INSERTは無事に成功してしまっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/2c5f1418-19b3-05d6-a4e2-f7984d6ddc5b.png)

これが、Entity Actionが独立のトランザクションなるということの意味ですね。トランザクションは終わってしまっているので更新はコミット済み。だから、その後で例外が発生してもロールバックされない。

これが、ServerのEntityであれば、（Exception HandlerでAbort TransactionプロパティをNoにしない限り）例外が発生するとそれまでの更新はロールバックされるところです。

Client ActionのException HandlerにはそもそもAbort Transactionプロパティがありません。
左がClient Action、右がServer ActionのException Handlerのプロパティです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/4fa6e77c-dd9d-b146-673d-537077a06f3d.png)

# Client ActionにはCommit/Rollbackを発行するためのActionがない
Client ActionにはCommitやRolebackを発行するためのActionがありません。トランザクションがEntity Actionごとに完結してしまうので、あっても使いみちがないですが。

このように、Manage Dependenciesのダイアログでフィルタしてみると、Server ActionのCommitTransaction/AbortTransactionのみが見つかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/8f57e487-140d-2d67-cc1f-30d64ccf9b05.png)
コンポーネント

今回はコンポーネントについて学んでいきます！！
Vue.jsについては後で触っていきます。

#①コンポーネントとは
ソフトウェアやシステムを構成する要素のことを言います！
またこれらは、単体ではなく、他のプログラムに呼び出されたりしたときに使います！！
なんでこれを使うかというと、機能の追加・修正・削除などが発生した場合に、コンポーネント単位で対応することができるからです！👍

#②モジュールとは
コンポーネントと同じ意味をもつ部品にモジュールというものがあります！
モジュールとコンポーネントの違いは、単体で使えるか使えないかみたいです！😊

更にここからVueの中でコンポーネントが２つに別れます。
今回はVue.jsをまだ勉強してないのでとりあえずこんなもんなのね。ってことでさらっとだけみていきます。

##１）グローバルコンポーネント
全てのルート Vue インスタンス(new Vue)のテンプレート内で使用できることを意味します。
##２）ローカルコンポーネント
他のサブコンポーネント内では使用できないみたいです！

今回のはコードを読みたくて調べたメモなので参考にならないと思いますが(^_^;)
必要になったら引き続き戻って追記していきます👍
iOSで電話番号がリンクになった時の対処法

備忘録として残します。

iOSで確認したところ、aタグを使っていないのにも関わらず電話番号がリンクとして表示されていたので調べてみました。

####なぜリンクになるのか
iOSは、ユーザが電話番号をタップやクリックすると電話を掛けられるように
自動的にaタグを挿入する仕様になっているそう。

####対処法
以下のコードをheadタグ内に記述します。

```
<meta name="format-detection" content="telephone=no">
```

####CSSでは効かないのか？
以下の方法で試しましたが、やり方が悪いのか私の場合は効きませんでした。

```
a {
  text-decoration: none;
  color: #色;
}
```

参考：

https://qiita.com/megurock/items/edbd9db255eb167712c6
プログラミング超入門(３)〜GO言語〜

#文字列型
コンピューターで扱われる言葉が人間に理解できるように文字として並べたものを**「文字列」**と呼びます。GO言語における文字列の正式なデータ型は、**string型**です。string型の値(文字列値)を作成するには「””」ダブルクォーテーションで文字の並びを囲みます。**Println関数**や**Printf関数**により出力されているのがこの**文字列値**です。

```string.go
package main

import "fmt"

func main() {
    
    normalString := "はじめまして！"
    emptyString := ""
    emptyString += "宜しくお願い致します！" 
    
    fmt.Println(normalString)
    fmt.Println(emptyString)
}
```
###・実行結果

```
はじめまして！
宜しくお願い致します！
```
上記の場合、従来`var normalString string = "はじめまして！"`が省略されて記述されています。

--------------------
Println関数のように、fmtパッケージ関数には`文字列の中に埋め込め`て`表示形式を指定できる`機能を持った**Printf関数**があります。printf関数をしようして変数aの値が少数のとき、少数第２まで表示させてみます。

```
fmt.Printf("%.2f",a)
```

「””」ダブルクォーテーション内の`%.2f`は表示形式が指定されています。％から始まり、少数点「.」とその後の桁数「2」そしてそれを指定する「f」に分けられ「,」カンマで区切られ、表示したい内容「a」が`fmt.Printf`後の (　)カッコ内に記述されています。

```
fmt.Printf("aの値は%.2fです",a)
```
文字列の中に埋め込めるというのは「””」ダブルクォーテーションの中に他の文字を置くことができることを意味します。

```DecimalPoint.go
package main

import "fmt"

func main() {
    a := 4.2
    b := 6.4
    fmt.Printf("a+b=%.2f", a+b)
    fmt.Printf("a+b=%.2f", a-b)
    fmt.Printf("a+b=%.2f", a*b)
    fmt.Printf("a+b=%.4f", a/b)
}
```
###・実行結果

```
a+b=10.60a-b=-2.20a*b=26.88a/b=0.6562
```

上記の実行結果は除算を少数第４位まで表示させました。結果がくっついて見づらいため出力結果の文字列に改行の指示を行わせる「\n」を含めるとします。この「\」(円マークまたはバックスラッシュ)をエスケープ記号と呼び、非常に多くの種類があります。例えば、「\n」は改行、「\t」はタブ、「\s」はスペース、「\b」はバックスペース、「\0」は終端文字、を意味します。「\\」はエスケープ記号ではなく、文字列として「\」を出力します。「\'」はシングルクォーテーションと「\"」はダブルクォーテーションは文字列の始まりと終わりを示す記号でなく、文字列として「'」「"」を出力します。　では、改行を加えて書き換えてみます。

```DecimalPoint.go
package main

import "fmt"

func main() {
    a := 4.2
    b := 6.4
    fmt.Printf("a+b=%.2f\n", a+b)
    fmt.Printf("a+b=%.2f\n", a-b)
    fmt.Printf("a+b=%.2f\n", a*b)
    fmt.Printf("a+b=%.4f\n", a/b)
}
```
###・実行結果

```
a+b=10.60
a-b=-2.20
a*b=26.88
a/b=0.6562
```
[←前回の記事](https://qiita.com/ume-bar/items/95f7c5f61e44dddf9401)　[次の記事へ→](https://qiita.com/ume-bar/items/3f3daa402a2d4b7bcc88)
【Swift】UISearchBarを利用してTableViewの表示を絞る

UISearchBarでTableViewの表示を絞る方法

![スクリーンショット 2021-03-06 17.12.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840715/6f3288cc-ecf1-1ea4-7d24-72c1bfe9b501.png)

1.storyboardでUISearchBarを配置し、ViewControllerと接続します。

```
@IBOutlet weak var searchBar: UISearchBar!
```

2.ViewControllerにUISearchBarDelegateプロコトルを適用させます。

```
class ViewController: UIViewController, UISearchBarDelegate{
```

3.searchBarの処理をコードで実装します。
  
```
// searchButtonを押した時に実行されるメソッド
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
　　　　　// tableViewに表示するデータリストをsearchBarに入力されたテキストで絞り込む
        members = members?.filter("name CONTAINS[cd] %@", searchBar.text!).sorted(byKeyPath: "name", ascending: true)
        tableView.reloadData()
    }
    
    // searchBarの入力が無くなったら絞り込みを解除する
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchBar.text?.count == 0 {
            loadMembers()
            DispatchQueue.main.async {
                searchBar.resignFirstResponder()
            }
        }
    }
```
ESP32で加速度データを取得

ESP32で加速度データを取得してみました。

使った機材は以下となります。

- ESP32 WROOM 32 （1500円ほど）
- ADXL337 （1300円ほど）

## 前提

仮想ドライバーが必要になるかもしれません。
mac ユーザーなので以下からダウンロードしました。
https://jp.silabs.com/developers/usb-to-uart-bridge-vcp-drivers#mac

## 繋げ方

繋げ方は以下のようになります。とりあえずX軸のデータのみとってみました。

![Screen Shot 2021-03-06 at 17.23.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/8d1e8672-9c0a-be6e-9b05-7d14ba3fa89c.png)


## ソースコード

```
void setup() {
  Serial.begin(115200);
}

void loop() {
  int rawX = analogRead(34);
  Serial.println(rawX);
}
```

ピンの番号は以下の画像を参考にしました。左の上から5番目のピンが34だったので、上記のソースコードでも34番となっています。

![esp32_devkitc_pinout_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/d392bc75-d7b0-cb3d-7c20-9e481437cbe7.png)



## 可視化

Serial Plotterにて以下のように可視化できます。

![Screen Shot 2021-03-06 at 17.39.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396623/9e038a9c-9622-3884-0115-32f10932379a.png)


## 参考

> [ESP32-WROOM-32](https://ht-deko.com/arduino/esp-wroom-32.html)
EKSとECSの違い

## 勉強前イメージ

EKSはkubernetes、ECSはDockerのイメージ

## 調査

### EKSとは？

kubernetesのマネージドサービスで、AWS上で簡単に実行できるサービス
詳細は [こちら](https://qiita.com/miyuki_samitani/items/a9d7d67e8786ec8f4df2)

### ECSとは？

Elastic Container Service の略で、
Dockerコンテナを簡単に実行・停止出来る管理サービスです。
ECSを利用することによってDockerのインフラをまるっとAWSにおまかせできます。
詳細は [こちら](https://qiita.com/miyuki_samitani/items/69abb6289aea8ae40ffe)

### kubernetesとDockerの違い

Dockerは1台のサーバ上でコンテナを作成し、その管理をしています。
しかし、複数台のサーバで稼働するコンテナを横断的に管理することが出来ないので、
複数台のサーバにまたがったコンテナを増やさないといけない場合に対処出来ません。
それを解決するのがKubernetesで、複数台のサーバのコンテナ管理を1台の実行環境のように扱うことが出来ます。

- Kubernetes : 複数台のサーバにまたがったコンテナ管理ができる
- Docker : 1台のサーバ上でしかコンテナを管理できない

### EKSとECSの違い

- EKS : Kubernetesのマネージドサービス
- ECS : AWSが開発したコンテナ管理サービス

### ちなみに・・・

EKSとECSは コンテナを管理する役割として、 `コントロールプレーン` と呼ばれており、
コンテナが動く場所として、 `データプレーン` と呼ばれているのが Fargate, EC2 になります。
Fargateの詳細は [こちら](https://qiita.com/miyuki_samitani/items/b1f29abfbf89b27d7ff4)

いままで EKS+Fargate が使えなかったのですが、2019年に使えるようになりました。
下記のどの組み合わせでも使うことが出来ます。

- ECS+Fargate
- ECS+EC2
- EKS+Fargate
- EKS+EC2

## 勉強後イメージ

ECSはAWS独自のコンテナ管理サービスで、EKSはKubernetes(コンテナ管理サービス)のマネージドサービスってことか。
Fargateの雰囲気もなんとなくわかってきた気がする

## 参考

- [AWS コンテナサービス「Fargate」「ECS」「EKS」の違いを解説](https://xn--o9j8h1c9hb5756dt0ua226amc1a.com/?p=2025)
- [AWSでコンテナを支えるサービスについて ECS、EKS、Fargateの違いは？　第１回](https://www.sunnycloud.jp/column/20201215-01/)
お猿さんのためのReactまとめ： Vol.2　ライフサイクル編

##1...ライフサイクルとは？
* コンポーネントの中の「時間の流れ」。
* 人の一生に例えて、生まれて、成長して、死んでいく流れ（循環）。
* それぞれの段階で必要な処理を記述する。
* そのコンポーネントの外に影響を与える関数を記述するため。
 *  DOM変更
 *  API通信
 *  ログ出力
 *  setState() .....etc
* 副作用＝適切な場所に配置すべき処理。 

![React.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/b3d58a83-99ad-9742-4e46-f4400b69df5c.png)
##2...実際のコードと画面で確認する
![React (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/d12f9c9b-2ae1-9df7-0b24-e6c6cdd10187.png)
![React (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/be23d322-0fc2-c3dd-2167-a306cb92ee0d.png)

参考：[日本一わかりやすいReact入門【基礎編】](https://youtu.be/2jRkPz4-hSo)