OmniAICreator/Qiita-1.07M huggingface dataset:
【忘備録】Java : 文字列調査

# はじめに
今回は今まで逃げ続けてきたJavaの今までの復習と勉強ををしていきます。初めてプログラミングでJavaを触った結果、Javaに対して苦手意識が生まれたのですが、JavascriptやRubyを学んでから、学んだことがJava現場でも少しずつ活かされ始めて少しずつJavaも書けるようになり、Javaを今度こそ、しっかり学んでいきたいと思うようになりました。

今回はJavaにもともと、備わっているStringクラスのメソッドの復習をしていきます。使っている参考書は有名な[こちら](https://www.amazon.co.jp/dp/B00O0NIW30/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)です。

## String操作

### 1, equals
文字列比較の定番。
比較対象の文字列が等しいか見てくれる。小文字、大文字も見てくれる。

```sample.java
public class string {
    public static void main(String[] args){
        boolean result;
        int length;
        boolean empty;

        // 文字列の内容が正しいか調べる
        String s1 = "this is Java";
        String s2 = "This is Java";
        String s3 = "これはJavaです";

        result = s1.equals(s2);
        System.out.println("s1 : s2 => "+result);
        result = s1.equals(s3);
        System.out.println("s1 : s3 => "+result);
        result = s2.equals(s3);
        System.out.println("s2 : s3 => "+result);
        result = "this is Java".equals(s1);
        System.out.println("this is Java : s1 => "+result);
    }
}
```

```結果.java
s1 : s2 => false
s1 : s3 => false
s2 : s3 => false
this is Java : s1 => true
```

### 2, equalsIgnoreCase
大文字、小文字関係なく同等の文字列か判定してくれる。

```sample.java
result = s1.equalsIgnoreCase(s2);
System.out.println("s1 : s2 => "+result);
result = s1.equalsIgnoreCase(s3);
System.out.println("s1 : s3 => "+result);
result = s2.equalsIgnoreCase(s3);
System.out.println("s2 : s3 => "+result);
result = "this is Java".equalsIgnoreCase(s1);
System.out.println("this is Java : s1 => "+result);
```

```結果.java
s1 : s2 => true
s1 : s3 => false
s2 : s3 => false
this is Java : s1 => true
```

### 3, length
文字列長を見てくれる。スペースも一文字として見ることに注意。

```sample.java
length = s1.length();
System.out.println("\"this is Java\"の文字列長は"+length+"です。");
length = s2.length();
System.out.println("\"This is Java\"の文字列長は"+length+"です。");
length = s3.length();
System.out.println("\"これはJavaです\"の文字列長は"+length+"です。");
```

```結果.java
"this is Java"の文字列長は12です。
"This is Java"の文字列長は12です。
"これはJavaです"の文字列長は9です。
```

### 4, isEmpty
文字列が空か判定。isEmptyの場合、空白が入っていると空扱いにならない。
isBlankの場合、空白が含まれていても空扱いになってしまう。

```sample.java
empty = s1.isEmpty();
        System.out.println("s1.isEmpty : " + empty);
        empty = s2.isEmpty();
        System.out.println("s2.isEmpty : " + empty);
        empty = s3.isEmpty();
        System.out.println("s3.isEmpty : " + empty);
        empty = "".isEmpty();
        System.out.println("\"\".isEmpty : " + empty);
        empty = "  ".isEmpty();
        System.out.println("\"  \".isEmpty : " + empty);
        empty = "".isBlank();
        System.out.println("\"\".isBlank : " + empty);
        empty = "  ".isBlank();
        System.out.println("\"  \".isBlank : " + empty);
```

```結果.java
s1.isEmpty : false
s2.isEmpty : false
s3.isEmpty : false
"".isEmpty : true
"  ".isEmpty : false
"".isBlank : true
"  ".isBlank : true

```
初心者のためのVue.jsの環境構築方法

# 初心者のためのVue.jsの環境構築方法
初心者向けのVue.jsの環境構築方法をまとめました。
Vue.jsをローカルで少し動かしてみたい方は以下の記事を参考にしてみてください。

<a href="https://masa-enjoy.com/vuejs-download" target="_blank">今話題のJavaScriptフレームワーク「Vue.js」の簡単な始め方</a>
6ドルの激安LiDAR(Camsense X1)を使ってみる


##2000円のLidarって大丈夫？
Aliexpressで2千円のLidarが売っている事を知りましたが、怪しすぎて買うのを躊躇っていました。
そんなところ、買った方のコメントや、Qiita記事を見て自分も購入してみました。
###・camsense-X1
https://github.com/Vidicon/camsense-X1
###・激安LiDAR(Camsense X1)を使ってみる
https://qiita.com/junp007/items/819aced4d48efd97c79f
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/69fb8fe8-cfbc-2024-85f0-1c57b54360b8.png)
##届いたのは？
2個購入した所
左はNG品、右は正常品でした。
NGと書いてあったり、本体にCamsense X1のロゴが無いのはNG品です。
![比較するよｰ上](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/3e838133-4014-166a-8b6b-c0091a04fa9d.jpeg)
![比較するよｰ背面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/9d47c0c7-5033-e30b-87ae-bf6452bfe4a2.jpeg)
NG品は、修正が入っていますね。
##動作させる
今回は、USB-Serialアダプタを使って接続します。
![USB-Serial](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/25ccd990-48d6-3300-7308-0f1fd5b961d9.jpeg)
電源は5V、USB-Serialの接続先はRXです。
（TX⇒RX)
こういう時に使用するのは
スルホール用テストワイヤ　ＴＴ－２００　（１０本入）
http://akizukidenshi.com/catalog/g/gC-09831/
##TeraTermの受信内容
接続します。
ボーレート：115200
TeraTermの表示内容はこんな感じです。
これを見て壊れていると思ってしまいますよね・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/191082aa-cdeb-c690-91ab-ede4f59fafbe.png)
##使えるようにしてみよう
「激安LiDAR(Camsense X1)を使ってみる」に
https://qiita.com/junp007/items/819aced4d48efd97c79f
「距離と強度データが8ステップずつ入った36バイトのパケットになっていて」と記載されています。
つまり、このままではダメです。
記載されているとおり、Pythonで動かしてみましょう。
##Windowsで動かす・・・camsenseX1.py
必要なのはpython、pyserial、matplotlibです。
これらをインストールします。
私は、Windows標準のコマンドプロンプトを使用しており
まずは、pipをインストールし、Python、pyserial、matplotlibをインストールしていきます。
最後に、こちらのプログラムを起動します。
コマンドプロンプトの最後に、シリアルポートを選択します

```
C:\Users\user\Desktop\camsenseX1.py COM2
```
シリアルポートを指定しないと、こんなメッセージが出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/fe1b36b1-beda-f5dc-e57d-b6e701040941.png)
##無事起動
ちょっと、怪しい挙動がありますが、動きました。
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/c449e81c-629e-89a7-d13a-f6572cd5e682.png)
これで2000円なら満足ですね。
##配線するよ
それでは、キチンと使えるようにしましょう。
というのは、コネクタの品種がわからず、使えないからです。
本来はL型のピンヘッダが必要ですが無いので普通のを曲げました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/23bb63e7-8227-9a12-841b-0b9e75dfb972.jpeg" alt="" width="250" height="" border="0" />
買う人は、秋月電子のこちらなど
ピンヘッダ　（Ｌ型）　１×６　（６Ｐ）
http://akizukidenshi.com/catalog/g/gC-05336/
##はんだ付け
![はんだ付け](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/7fa3da69-e4c1-4e66-096a-ec409bc161ae.jpeg)
##脚をつけるよ
M2.5X20を選択しました。
![背面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5ce26ca9-c906-06e0-fd9f-c8fdff588281.jpeg)
![スペーサー取り付け後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5a0744fd-9eb7-d764-7681-83fff5d0edd1.jpeg)

##今や6ドル未満
今は6ドル未満で売っています。
送料がかかるので実際は1000円です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5cbf12ba-f64e-ae9e-9bb0-15bd22ef6a6f.png)
この価格は何でしょうか？
非常に困ってしまいますね・・・
##お勧めはしない
ここまで見ると動きそうだと思われますね
ですが、正直お勧めできません
ふつうの人であれば、動かない商品を買うのは嫌でしょう
私ですら嫌です。
なので、動かない可能性が高い本商品は、2個のうち1個動けばいいやと思えるかが重要です。

2000円の時に2個買った私は、6ドルならば６個買ってもほぼ一緒ですが・・・
動かない前提で試してみる気があるならば・・・
数字版のinclude? はないのか？

メモがてらのアウトプットです。

今回想定したのはよくあるお買い物ポイントを計算するプログラムを組みました。
下記コード

```ruby:qiita.rb
n = gets.to_i


d_1,p_1 = Array.new(n){gets.chomp.split(' ').map{|i| i.to_i}}.transpose
p = 0
c = 0

while n > 0 do
  if d_1[c].to_s.include?("3")
    p += (p_1[c] * 0.03).floor
  elsif d_1[c].to_s.include?("5")
    p += (p_1[c] * 0.05).floor
  else
    p += (p_1[c] * 0.01).floor
  end
  c = c + 1
  n = n - 1

end

puts p
```

困ったのは１点　include?の使い方です。
結果的にto_sで文字列に返して参照しましたが
数字を直接参照するメソッドはないのかな？と
思いました。

探した限り見つからなかったのですが何かあるんですかね。。。
g++によるopenCVのコンパイル

最近CNNを学習しつつ，C++で一からコーディング中です．
画像認識をさせたくてopenCVで画素データ取得しようと思ったのですが，コンパイル段階でかなり苦戦しました...
コードも画像読み込みと画素取得だけなのに，コンパイルが通らなくて大変でした．

色々調べて`pkg-config`を使ったコンパイル方法などもあったのですが，うまく行かず．(後で原因わかりましたが)
おそらくopenCVをIDEではなくエディタ環境で使ってる人の多くが躓きそうだなぁと...

そこで，openCVの基本中の基本，__画像読込み__ と __画素データ取得__ のコードをコンパイルできるようにする事が目的です．
openCVを使いこなすことが目的ではなく，画素データ取得できればいいんだよ！という方向けです．

## 実行環境
OS : __Arch Linux__
OpenCV : __4.4.0__
g++(GCC) : __10.1.0__

## 実装
同一ディレクトリ内にある`sample.jpg`というデータのRGB情報を取得，表示するだけのコードです．

```c++:hoge.cpp
#include <iostream>
#include <opencv2/opencv.hpp>

int main() {
  cv::Mat img, img_rgb;

  img = cv::imread("sample.jpg");
  // error handling
  if(img.data == NULL) {
    std::cerr << "Error: not found such file." << std::endl;
    exit(1);
  }
  // convert BGR to RGB
  cv::cvtColor(img, img_rgb, cv::COLOR_BGR2RGB);

  // print pixel data
  std::cout << img_rgb << std::endl;
}
```
`cv::imread()`で読み込んだ画素データはBGRの順番になっています．そこで`cv::cvtColor()`でBGRをRGBに並び替えてます．そのままでも良い方は`cv::cvtColor()`は不要です．

## コンパイル
上記コード用のMakefileです．

```makefile:Makefile
# Makefile

FILE = hoge.cpp
HDIR = -I /usr/include/opencv4
OPT  = -lopencv_core -lopencv_imgproc -lopencv_imgcodecs

a.out: $(FILE)
    $(CXX) -Wall $(FILE) $(HDIR) $(OPT)
```
ソースファイル名が`sample.cpp`なら，上記3行目を`FILE = sample.cpp`と書き換えるか，実行時に`make FILE=sample.cpp`としてください．

これで実行ファイルが作成されると思います．
もしコードにそのほかのopenCVの関数を使った場合は，適宜オプションを追加してください．

これでコンパイル時に悩まされないと思います．
`pkg-config`を使うとMakefileを使わずにできますが，個人的にMakefileが好きという事もありMakefileで記述しました．

## おまけ
連番になっている画像の画素データをファイルに書き出したかったので，そのコードも載せておきます．
ファイル名を`sample_0.jpg,...,sample_(n).jpg`の連番形式，画像サイズを28x28とします．

```c++:get_rgb.cpp
#include <iostream>
#include <fstream>    // for ofstream
#include <opencv2/opencv.hpp>

#define PIXEL 28   // image size
#define CHNEL 3    // number of channel [RGB = 3]

int main() {
  cv::Mat img, img_rgb;
  std::ofstream ofs("pixel_data.txt");
  int idx = 0;    // for file index

  while((img = cv::imread("sample_"+std::to_string(idx)+".jpg", 1)).data) {
    // convert BGR to RGB
    cv::cvtColor(img, img_rgb, cv::COLOR_BGR2RGB);

    // output pixel data to file
    for(int i = 0; i < CHNEL; i++) {
      for(int m = 0; m < PIXEL; m++) {
        for(int n = 0; n < PIXEL; n++) {
          ofs << static_cast<int>(img_rgb.at<cv::Vec3b>(cv::Point(n, m))[i]);
          if(n != PIXEL-1) ofs << " ";
        }
        ofs << "\n";
      }
    }
    idx++;
  }
  std::cout << "outputting pixel data to file completed." << std::endl;
}
```
簡単に説明します．
出力形式は空白区切り，データの並びは各ファイルごとにRGBの順に出力されます．
実際に画素データを取得，出力してるのは，21行目の

```c++
ofs << static_cast<int>(img_rgb.at<cv::Vec3b>(cv::Point(n, m))[i]);
```
です．
Matクラスのat関数を用いて，Channel[i]の(n, m)番値の画素データを取得，intにキャスとした値をファイルに出力，という事をしています．
`cv::Point(n, m)`が番地を指定しているのですが，(m, n)にするとMatクラスで取得した行列の転置行列になってしまうので，(n, m)にしています．

もし簡単なファイル出力方法などあれば，教えていただけると幸いです．
プログラムを書くときの注意点：その２

【概要】
----------------------------------------
<b>1.結論</b>
<b>2.オープン・クローズドの原則とは何か</b>
<b>3.オープン・クローズドの原則どう使うのか</b>
<b>4.なぜオープン・クローズドの原則が必要か</b>
<b>5.ここから学んだこと</b>
<br>

1.結論
----------------------------------------
<b>オープン・クローズドの原則にも従う！
<br>

2.オープン・クローズドの原則とは何か
----------------------------------------
●オープン・クローズドの原則とは、
<br>
 <b>拡張に対して開いていて、
修正に対して閉じていなければならない</b>
<br>
つまり、拡張する分にはOKだけど、
拡張した時の修正範囲は最小限に止めようね。
そうしないと破壊的変更(とてつもない修正)を
しないといけなくなるということです！


3.オープン・クローズドの原則はどう使うのか
----------------------------------------
言葉だけではイメージがしにくいと思うので
例を挙げてみます！

```Ruby:オープン・クローズドの原則
class A
  class Interface B 

class *** implements　C（interface名）B

class Interface B
  puts ******
```

```Ruby:オープン・クローズドの原則ではない
class A
 class B
  puts ******
```
ただあまりにも抽象化しすぎると、
本当に必要でないクラスができてしまいます。
（上記ではわかりやすくするために簡素化しているので
”オープン・クローズドの原則ではない”方がわかりやすいですし、
class A 
puts ****でいいまであります。）

上記は簡単に書いているのでまだ追えていますが、
階層が深くなるとどこにいるのか
わからない（可読性がなくなる）
部分がでてきます。

なので、変更箇所が今後ありそうな箇所を
予測した際に有効で、難しい原則です。

これは”プログラムを書くときの注意点：その４（次々回投稿）”
のインターフェース分離の原則でも関わってきます。

<br>

4.なぜオープン・クローズドの原則が必要か
----------------------------------------
結論としては、プログラミングを書く際の要は以下の
3つに集約されると思っています。

Ⅰ）保守性：修正（エラー発見のしやすさ）・管理のしやすさ
Ⅱ）拡張性：追加機能実装のしやすさ
Ⅲ）可読性：記述のわかりやすさ
が必要だと考えております。

上記3つのことは自分が他の4つの原則を説明する際に同じことを言うので、
５つの原則のうちどれかを読んでいただくと
結論はすべてこの３つに収まります。

つまり、上の3つを叶えるには
<b>オープン/クローズドの原則に”も（他の４つの原則もあるので）”従う！！</b>
 <br>

5.ここから学んだこと
----------------------------------------
i)implements,interfaceメソッドを知ることができました！

ii)implements,interfaceメソッドを駆使することで
可読性かつ保守性のあるプログラムをかけますが、あまり不本意に適用
したらいいわけでないと思いました。プロジェクトでお客さまに提案する際や、
今後拡張しそうな箇所を予測した上で使う原則であり、非常に奥深い原則だなと感じました。
<br>
Spring Security設定の解説メモ（OAuth 2）

# SecurityConfigパッケージ作成
自分は以下のパッケージに作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684074/85bbb927-578b-bd3a-9d18-c9056717488c.png)

# SecurityConfigコード

```java

package jojoidu.boot.springboot.config.auth;

import jojoidu.boot.springboot.domain.user.Role;
import lombok.RequiredArgsConstructor;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@RequiredArgsConstructor
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private final CustomOAuth2UserService customOAuth2UserService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .headers().frameOptions().disable()
                .and()
                    .authorizeRequests()
                    .antMatchers("/", "/css/**", "/images/**", "/js/**", "/h2-console/**", "/profile").permitAll()
                    .antMatchers("/api/v1/**").hasRole(Role.USER.name())
                    .anyRequest().authenticated()
                .and()
                    .logout()
                        .logoutSuccessUrl("/")
                .and()
                    .oauth2Login()
                        .userInfoEndpoint()
                            .userService(customOAuth2UserService);
    }
}

```
#### @EnableWebSecurity
- Spring Security設定を活性化するため使います。

#### csrf().disable().headers().frameOptions().disable()
- h2-console画面を使うために該当オプションをdisableします。
（プライベートプロジェクトH2データベースを使っているため。）

#### authorizeRequests()
- URLごとの権限管理の設定オプションは「authorizeRequests()」から始まります。
- authorizeRequestsを宣言してからantMatchers()を使うことができます。

#### antMatchers()
- 権限管理対象を指定するオプションです。
- URL、HTTPメソッドごとに管理が可能です。
- "/"など指定されたURLは「permitAll()」オプションを使って全体観覧権限を与えました。
- "/api/v1/**"のアドレスを持っているAPIはUSER権限を持っているユーザーのみ呼び出しができるように設定しました。

#### anyRequest()
- 設定された値以外のURLを示します。
- 今回は「authenticated()」を追加して残りURLに対しては**すべて認証ユーザーのみ**許可します。
- **認証ユーザー**はつまりログインされているユーザーのことです。

#### logout().logoutSuccessUrl("/")
- ログアウト機能に関して様々な設定をします。
- ログアウト成功時、「/」（TOP）に遷移させます。

#### oauth2Login()
- Oauth 2ログイン機能に関連設定を行います。（始まり）

#### userInfoEndpoint()
- Oauth 2ログイン成功後、ユーザー情報を持ってくるときの設定を行います。

#### userService(customOAuth2UserService)
- ソーシャルログイン成功後、実行するUserService Interfaceを継承しているクラスを登録します。

```java

@RequiredArgsConstructor
@Service
public class CustomOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> {
}
```

- リソースサーバー（ソーシャルサービス）からユーザー情報を持ってきた状態で追加処理の機能を記述できます。（UserService Interfaceを継承しているクラス内で）

# 終わり
今回はOAuth2のSpringboot2のsecurity設定を行いましたが、
整理しながらもう一度勉強になりました。
内容はメモって感じなので、詳しい情報などはDOCや他のブログを参考にしたほうが良いかと思います。
Operator '>' cannot be applied to types 'boolean' and 'number'.って言われた時

```html
 <div *ngIf="!hoge?.length > 0">
```

```
ERROR in hoge.html(123,456): Operator '>' cannot be applied to types 'boolean' and 'number'.
```

Oh...

#解決
```html
 <div *ngIf="!(hoge?.length > 0)">
```
#参考
https://stackoverflow.com/questions/45974764/operator-cannot-be-applied-to-types-boolean-and-number
パッケージというかnamespaceの依存関係を機械的にチェックしたい

作った。
https://github.com/nishphp/phpstan-namespace-dependency
https://github.com/nishimura/phpstan-namespace-dependency-sample

DDDでもMVCでも単純なレイヤー構造でもいいけど、各レイヤーごとの依存関係を静的にチェックしたかった。

コードを書き始めて、最初のうちは気を付けるしnewするときは割と意識しているんだけど、しばらく経った後とか急いでいるときとかにreturnやthrowでレイヤーを飛び越えて返却してしまうことがある。

最初はnamespaceを飛び越えてないかだけチェックしようと思ったけど、クラス名までチェックするようにしたらfriendやpackage private的なものも出来るようになってしまった。
コンストラクタやメソッドだけに制限をかけているわけではなくてクラス名単位で制限がかかるからちょっと違うけど。


実際のプロジェクトに適用するところまでいけてないので、使い勝手はまだ不明。
Railsでデータベースの中身を確認する

#プログラミングの勉強日記
2020年8月17日　Progate Lv.226
今まではSQLiteStudioで確認していた。
SQLiteStudioの方が見やすいが、見るのに手間がかかるので、コンソールで確認することができたのでまとめる。

#方法
　SQLiteはデータベースサーバを使用しないで、データベースごとに1つのファイルを使うことで管理する。

##1. SQLiteコマンドのツールのインストール
　[SQLiteの公式サイト](https://www.sqlite.org/index.html)にアクセスする。Downloadをクリック。
![0817.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/71a1fcd5-b6ff-4ce7-c084-6973cf568873.png)

　Windows10の環境を利用するので、recompiled Binaries for Windowsのsqlite-tools-win32-x86-3330000.zipをクリックして、ダウンロードする。
![0817-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/81a8e87f-8b7a-7282-c92c-c3d7488e5553.png)

　ダウンロードが完了したら、zipファイルを展開する。
　今回はRailsアプリの中のdbフォルダの下に展開した3つのファイルを置いた。

![0817-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/a5006b82-09b7-a699-aee6-063d765485fb.png)

##2. コンソールの立ち上げ
　dbフォルダの中に移動して、`.\sqlite3 .\development.sqlite3`とコマンドを入力するとコンソールが立ち上がる。
　`sqlite> `が出てくれば成功。

```
.\sqlite3 .\development.sqlite3
SQLite version 3.33.0 2020-08-14 13:23:32
Enter ".help" for usage hints.
```

#主なコマンド

##テーブルの一覧の表示
　`.tables`で作成したテーブルの一覧を表示する。

```
sqlite> .tables
ar_internal_metadata  posts                 schema_migrations   
goods                 reviews               users
```

##カラム名などのテーブルの構造を表示する
　`.schema テーブル名`で指定したテーブルの構造を表示する。

```
sqlite> .schema users     
CREATE TABLE IF NOT EXISTS "users" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar, "email" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL, "image_name" varchar, "password_digest" varchar);
```

##テーブルの中身を確認する
　`select * from テーブル名;`でテーブルの中身を確認できる。`*`ですべてのテーブルの中身を表示できる。<font color=blue>セミコロンを忘れないように。</font>

```
sqlite> select * from users;
1|aiueo|aiueo|2020-08-09 09:28:46.103511|2020-08-09 09:29:37.184446|1.jpg|$2a$12$eJlR9MsvgcnbXaEY2DpD3.hoQG3fy2vwdtE44buDy6DltamJQ/2Jm
```

##コンソールの終了
　`.quit`でコンソールを終了できる。

```
.quit
```

#参考文献
[SQLiteインストール](https://www.dbonline.jp/sqlite/install/)
[【Rails】データベースの中身を確認する方法【Cloud9】](https://shuheitakada.com/rails-database-check)
M5stackをROS(rosserial）につなげる方法

#経緯
rosserialをwifi経由で使ってみたく、色々探してみました。まず[@aNo研 nnn](https://qiita.com/nnn112358)さんの以下の記事が参考になったのですが、自分の環境ではすんなり行かなかったので、自分なりに挑戦した内容を記載してみます。

[ROSのrosserialを使って、M5stackとUSB通信してLチカする](https://qiita.com/nnn112358/items/47970f67103f7474e838)
#1. Windows10では何故か失敗
　Windows10では上記で参考にさせて頂いたスケッチをArduinoIDEでM5stackに書き込もうとすると、大量のエラーが吐き出され、コンパイルすることを断念しました。そこでUbuntuよりArduinoIDEを起動してコンパイルすることにしてみました。（結果成功！）そのためUbuntuで実施した内容を記載します。

#2. Ubuntu18.04LTSにROS Melodicをインストール
　いつも通りROSをインストールします。インストールは以下を参考にしております。もう既にROSをインストールしている場合は飛ばしてください。

[Ubuntu install of ROS Melodic](http://wiki.ros.org/melodic/Installation/Ubuntu)

#3. Ubuntu18.04LTSにArduinoIDEをインストール
ArduinoIDEのインストールは以下を参考にしました。ただしArduinoのバージョンが新しくなっているため、2020/8/27時点では"arduino-1.8.5"となっている個所を"arduino-1.8.13"にしております。

[Ubuntu 18.04にArduino IDEをインストールして、プログラムをArduinoに書き込む](https://symfoware.blog.fc2.com/blog-entry-2230.html)

#4. M5stackをArduinoIDEで書き込める環境を作る
M5stackにスケッチを書き込む環境を構築していきます。
##4.1. ボードマネージャの設定
以下を参考にしてM5stackへ書き込める環境を構築しました。
[LinuxでM5Stack向けArduinoIDE環境を構築する](https://raspberrypi.mongonta.com/howto-install-arduinoide-on-linux/)
##4.2. ライブラリの登録
ArduinoIDEを起動し、”スケッチ”→”ライブラリをインクルード”→””イブラリを管理”をクリックする

![メニュー_003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212663/210a41f3-f7af-b6dc-a182-51b116dddbe4.png)

そして"M5stack"と記入して、表示された”M5stack”をインストールする。
![範囲を選択_006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212663/b8b26ccd-ff6b-61f3-e2a2-00bbdc15133a.png)

##4.3. エラー< avr/pgmspace.h >が見つからない場合の対処
ArduinoIDEでスケッチを書き込もうとすると< avr/pgmspace.h >が見つからないと言うエラーが出てきました。そこでRosserial_Arduino_Libraryディレクトリにあるros.hを修正します。
私の場合ros.hは、”/Arduino/libraries/Rosserial_Arduino_Library/src”ディレクトリにありました。


ここで、ros.hの40行目に書かれている 

```
#include <avr/pgmspace.h>
```
 を

```
 #include <pgmspace.h> 
```

に変更しました。

##4.4. permissionの許可
M5stackに書き込む際permissionの許可を与える必要があります。そこで以下のコマンドを使いました。

```
  sudo chmod 666 /dev/ttyUSB0
```
##4.5. スケッチの記述
スケッチは参考として@aNo研さんのスケッチを使わさせていただきました。

[ROSのrosserialを使って、M5stackとUSB通信してLチカする](https://qiita.com/nnn112358/items/47970f67103f7474e838)

##4.6. M5scackへの書き込み
　以下の様に”ツール”→"ボード"→”ESP32Arduino”→”M5stack-Core-ESP32”と選択します。
![メニュー_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212663/e4b0291b-14d0-e3f3-51c8-8cbc78676ea8.png)

　そしてCtrl+Rで書き込みます。

#5.試してみる！
では実際にrosserialを動かしてみましょう！新しいターミナルを開きroscoreを起動します。

```
roscore
```
その後M5stackに電源を入れます。
更にその後、新しいターミナルを開きrosserialを起動します。

```
rosrun rosserial_python serial_node.py tcp
```

rosserialによってM5stackと通信できたら以下のようなメッセージが出てきます。
![範囲を選択_007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212663/49b89b13-ebd6-b029-8f0e-187798e86626.png)
もしうまく動いていないなら、電源ボタンを”トン、トン”とダブルクリックしてみてください。
これで動いたら、最後に新しいターミナルで以下のコマンドを打ってみて下さい。

```
rostopic pub toggle_led std_msgs/Empty --once
```

これで画面が光ったのではないでしょうか？

おしまい！

#最後に
@aNo研さん。とても参考になりましたありがとうございます！
【AWS】 CDKのデプロイで複数のAWSアカウントを使い分ける方法

## やりたいこと
- AWS CDKでデプロイする際に、何も設定しない場合、AWS CLIで指定されているアカウントでデプロイを行います
- ただし、お仕事とプライベートでAWS CLIのアカウントを分けたかったり、開発環境と本番環境で異なるアカウントを使用したいということがあるかと思います
- AWS CDKでデプロイする際に、使用するAWSアカウントを明示的に指定できるようにしてみましょう

## --profileオプション
- --profileオプションを使えば、AWS CDKを実行するアカウントを指定できます
- こちらの使い方を説明していきます

### configを設定する
- ローカルのawsフォルダ以下にコンフィグファイルを新規作成します
- VS Codeを使用する場合は以下コマンドで作成できます

```console
code ~/.aws/config
```

- 作成されたconfigファイルに以下を記述します
- 「profile XXXX」の「XXXX」に適当な分かりやすい名前をつけましょう

```
[profile personal]
aws_access_key_id = XXXXXXXXX
aws_secret_access_key = XXXXXXXX
region = ap-northeast-1

[profile work]
aws_access_key_id = XXXXXXXX
aws_secret_access_key = XXXXXXXX
region = ap-northeast-1
```

### AWS CDKを実行する
- AWS CDKコマンドに```--profile``` オプションを付けて実行すれば、指定したアカウントで実行するようになります

```
cdk diff --profile personal
cdk deploy --profile personal
cdk destroy --profile personal
```
NumPyの操作方法

https://www.udemy.com/course/ds_for_python/
をやってるなかで、コマンド忘れそうなので

```python:import
import numpy as np
```


#flatten()

```python:flatten
array1=np.array([[1,2,3],[4,5,6],[7,8,9]])
array1.flatten()
```
##結果
`array([1, 2, 3, 4, 5, 6, 7, 8, 9])`

#squeeze

```python:squeeze
array1=np.array([[1,2,3]])
array1.shape
```
`(1, 3)`

```python:squeeze
np.squeeze(array1)
```
`(3,)`

次元を減らす。

#expand_dims
```python:expand_dims
ndarray1=np.array([1,2,3])
ndarray1.shape
expand_axis=np.expand_dims(ndarray1, axis=-1)
expand_axis.shape
expand_axis
```

```
(3,)

(3, 1)

array([[1],
       [2],
       [3]])
```

逆に、次元を増やす。
`axis`の引数で増やす場所が変わる。
Kotlin Coroutineにおける実行スレッドの選択について

# Dispatchers

Kotlinでコルーチンを使用する際、`Dispatchers`によってどのスレッドで実行するかを選択することができます。

```kotlin

GlobalScope.launch(Dispatchers.Main) {
    // 何かしらの処理
}
```

`Dispatchers.Main`は、コルーチンの実行スレッドを表しています。
主な種別は以下の通りです。


| 種別 | 説明 |
|:-----------|:------------|
| Defalut | バックグラウンドスレッド。リストの並び替えやJSONのパースなどのCPUに負荷がかかる処理向け。 |
| IO | バックグラウンドスレッド。データベース処理やファイルの読み書きおよびネットワーク処理といった入出力処理向け。 |
| Main | メインスレッド。他の`Dispatchers`での処理終了後に結果をUIに反映したり、`delay`関数でnミリ秒後にUIを表示させるなどのUI処理用。|

# withContext

コルーチンの中で実行スレッドを切り替えるには、`withContext`を使用します。

```kotlin

class MainActivity : AppCompatActivity(), CoroutineScope {
...
// コルーチンを使用する際のデフォルトのDispatchersを設定する
override val coroutineContext: CoroutineContext
        get() = SupervisorJob() + Dispatchers.Main
...

launch {
    // ここではメインスレッドとして処理される
    withContext(Dispatchers.IO) {
        // withContextによってバックグラウンドスレッド（入出力処理）に切り替わる
    }
}
```
【Salesforce】InBoxMessage受信後、一定日数経過後にメッセージを削除する方法

SMC管理画面からではなくアプリ側からメッセージを削除したい場合がありました。
アプリ側からInBoxMessageを受信した際に一定日数経過後のメッセージを削除する方法を実装しました。

## 環境
```
'MarketingCloudSDK', '6.2.3'
```

## メッセージの削除

特定のメッセージの削除には以下のメソッドを使用します。

```swift
// メッセージを削除済みとしてマークします。
- (BOOL)sfmc_markMessageDeleted:(NSDictionary *_Nonnull)messageDictionary

// 戻り値
メッセージを削除済みに設定したことを示す値

```


## 実装
```swift
import Foundation
import MarketingCloudSDK

class ViewController: UIViewController {

    private let tableView = UITableView()
    private var inboxMessages = [[String: Any]]()

    override func viewDidLoad() {
        fetchInboxMessage(completion: { [weak self] in
            self?.tableView.reloadData()
        })
    }

    private func fetchInboxMessages(completion: (() -> Void)? = nil) {
        guard let messages = MarketingCloudSDK.sharedInstance().sfmc_getAllMessages() as? [[String: Any]] else { return }
        let filterMessages = messages.filter { message -> Bool in
            guard let sendDate = message["sendDateUtc"] as? Date,
                let elapsedDays = Calendar.current.dateComponents([.day], from: sendDate, to: Date()).day else { return false }
            // 受信日から30日後にメッセージを削除
            guard elapsedDays < 30 else {
                return !MarketingCloudSDK.sharedInstance().sfmc_markMessageDeleted(message)
            }
            return true
        }
        self.inboxMessages = filterMessages
        completion?()
    }
}
```

## InboxMessageの構造
送信日以外にも条件を追加できます。

```
{
     subject = inboxSubject; // inboxの件名
     statusDirty = 2;　
     url =  "https://hoge.com";
     id = 12345678910; // someID
     read = 0; // 未読・既読状態 
     startDateUtc = "2019-03-25 15:50:00 +0000"; // 開始日?
     sendDateUtc = "2019-03-25 15:51:00 +0000"; // 送信日時
     requestId = 12345678910; // someID
     sound = default;
     contentType = 2;
     name = some name; // 管理画面上で設定。
     alert = "Inbox Alert"; // 管理画面上で設定。
     endDateUtc = "2020-11-11 08:11:00 +0000";
     deleted = 0;
     messageHash = 12345678910; // someID
     messageDeleted = 0 // メッセージの削除状態
 }
```

### 補足
受信時に削除する場合、配列の範囲外エラーになる可能性があるので、メッセージを受信後にViewの更新をするのがポイントかもです。

少しでも参考になれば幸いです😌

## 参考
- [Todd_MobilePushDemo_SDK/InBoxViewController.swift at b7be92ed99e972d5afb93fb7b121db97f333fb42 · toddisaacs/Todd_MobilePushDemo_SDK](https://github.com/toddisaacs/Todd_MobilePushDemo_SDK/blob/b7be92ed99e972d5afb93fb7b121db97f333fb42/Todd_MobilePushDemo_SDK/InBoxViewController.swift)
- [MarketingCloudSDK Class Reference](https://salesforce-marketingcloud.github.io/MarketingCloudSDK-iOS/appledoc/Classes/MarketingCloudSDK.html#//api/name/sfmc_markMessageDeleted)
Flutter で右上の「DEBUG」ラベルを非表示にする方法

## 概要

Flutter でアプリ開発しエミュレータデバッグすると、右上に「DEBUG」ラベルが表示されます。

いくらデバッグ時でも邪魔になるときがあったので、この DEBUG ラベルの削除方法を調査し、共有します。

## 削除方法

`lib/main.dart` の一番上の `build()` 部分に以下の一文を追加するだけで削除できます。

```
debugShowCheckedModeBanner: false,
```

### 例

```lib/main.dart
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
    debugShowCheckedModeBanner: false, // ここに追加
      title: ...,
      theme: ...,
      home: ...,
    );
  }
}
...
...
```
【Java】ArrayListの最長文字列をstreamを使って簡単に取得する方法

ArrayList\<String>に格納されている文字列のうち、最大長であるものを簡単に取り出す方法です。
普通に考えたら、forで回してlenghtがMaxになるものを取得するというものですが、
ここでは<font color="red"><strong>streamを使って ~~1行で~~ 簡単に取得</strong></font>します。

追記）2020/08/19
1. ご指摘により、Listが空の場合（NoSuchElementException）に対応しました。
2. Nullが含まれていた場合、空文字として扱うように修正しました。

注）streamはJava8以降で利用可能です。

# ソースコード
maxString()が最大文字列長を取得するメソッドです。

``` StringList.java

package samples.stream.main;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class StringList {
    private List<String> _strList = new ArrayList<String>();

    public void add(String str) {
        _strList.add(str);
    }

    public String maxString() {
        if(_strList.isEmpty()) return null;
        return _strList.stream()
                .map(s -> s == null ? "" : s)
                .max(Comparator.comparing(String::length)).get();
    }
}
```

　
# 解説
- .map(s -> s == null ? "" : s)

_strListの要素がNULLの場合は空文字に置換し、そうでない場合はその文字列をそのまま返します。

- max(

指定されたComparator（全体順序付けを行う比較関数）の最大要素を返します。
これにより、Comparatorで比較した最大値が返ってきます。

- Comparator.comparing(String::length)

比較するためのキーとして、String型のlengthを指定します。
これにより、文字列の長さで比較します。

- .get()

値を返します。

よって、<font color="red"><strong>String型のlengthで比較して最大となる値を返す</strong></font>ことができます。
　
# テストコード(おまけ)
検証したテストコードです。
今後は、public static void main(String...strings) で例示するのではなく、
TDDの学習も兼ねて、テストコードで例示していきたいと思っています。

``` StreamMaxTest.java

package samples.stream.test;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import org.junit.jupiter.api.Test;

import samples.stream.main.StringList;

class StreamMaxTest {
    @Test
    void ArrayList_String_内で最大長となる文字列を返す() {
        StringList stringList = new StringList();
        stringList.add("");
        stringList.add(null);
        stringList.add("12345");
        stringList.add("1234567890");
        String str = stringList.maxString();
        assertThat("1234567890", is(str));
    }

    @Test
    void ArrayList_String_が空の場合はNULLを返す() {
        StringList stringList = new StringList();
        String str = stringList.maxString();
        assertThat(null, is(str));
    }

    @Test
    void ArrayList_String_がNULLの場合は空文字を返す() {
        StringList stringList = new StringList();
        stringList.add(null);
        String str = stringList.maxString();
        assertThat("", is(str));
    }
}
```
[初心者]Vagrantで構築した仮想環境にログインする手順

１、ターミナルを起動

まずは下記のように出てくる

```
ユーザー名$ 
```
　　
　

２、現在のディレクトリから移動する
　　今回はhome/MyVagrant/MyCentOS 内に"Vagrantfile"があるのでそこまで移動する。

```
~$ cd      //ホームディレクトリに戻る（場所の確認）
~$ cd MyVagrant
~$ cd MyCentOS　　　//MyCentOSまで移動

pc名：MyCentOS ユーザー名＄　　//←と出てくればOK
```
  
　　
　　
３、仮想環境を起動、ログインする

```
~$ vagrant up
~$ vagrant ssh
```
  
  
この２つを実行後下記のように表示されていればログイン完了！
   
  


```
[vagrant@localhost ~]$
```
Rails enum 都道府県をプルダウン方式で選択

# はじめに

個人開発アプリでGoogle APIと連携して地図情報を取得できる様にしたのですが、

住所を全て手入力するのは面倒なので都道府県をプルダウン方式で選択できるようにしようと思います。

```ruby:new.html.erb

<%= form_for @ride, method: :post do |f| %>
 <%= f.select :prefecture, ['北海道', '青森県', '秋田県', '岩手県' 以下略], { include_blank: '選択してください' } %>
<% end %>
```

コードの可読性を無視して実装するならこんな感じで入力していくだけなのですが、

このようにview側に47都道府県全てを入力すると**非常に見苦しい**と思ったのでスマートにできる方法を探してみました。


# enum
enumというものがあるようでこれによってviewではなくmodelに記述することができ、

view側のコードをかなりスッキリさせることができます！



```ruby:
class CreateRides < ActiveRecord::Migration[5.2]
  def change
    create_table :Rides do |t|
      t.integer :ride_area, null: false, default: 0
    end
end
```
まずはintegerでカラムを作成します。

```ruby:ride.rb
class Ride < ApplicationRecord
 enum ride_area:{
     "---":0,
     北海道:1,青森県:2,岩手県:3,宮城県:4,秋田県:5,山形県:6,福島県:7,
     茨城県:8,栃木県:9,群馬県:10,埼玉県:11,千葉県:12,東京都:13,神奈川県:14,
     新潟県:15,富山県:16,石川県:17,福井県:18,山梨県:19,長野県:20,
     岐阜県:21,静岡県:22,愛知県:23,三重県:24,
     滋賀県:25,京都府:26,大阪府:27,兵庫県:28,奈良県:29,和歌山県:30,
     鳥取県:31,島根県:32,岡山県:33,広島県:34,山口県:35,
     徳島県:36,香川県:37,愛媛県:38,高知県:39,
     福岡県:40,佐賀県:41,長崎県:42,熊本県:43,大分県:44,宮崎県:45,鹿児島県:46,
     沖縄県:47
   }
end
```

モデル側にはこんな感じで都道府県を書いておきます。

ハッシュのキーがセレクトボックスに表示されます。


```ruby:new.html.erb

<%= form_for @ride, method: :post do |f| %>
 <%= f.select :prefecture, Ride.ride_areas.keys, {} %>
<% end %>
```

冒頭で書いたコードをこのように書き換えてあげましょう。

`Ride.ride_areas.keys, {}` と書く事でモデルに書いている都道府県全てを順番に処理してくれるのでブラウザ上ではプルダウン方式で都道府県が選択できるようになっています！

以上です。
NoCodeのglideでスマホアプリを作ったお話＜その２＞

ノーコーダーの皆さん、グーテンターク！！！！（変化球）

#### 前回のあらすじ

今回は、弊社が運用している女性向けリッチテキストメールマガジンe-zinesのスマホクライアントをNoCodeの Google glide で作成したお話の＜その２＞です。

前回はこちら↓です。
[NoCodeのglideでスマホアプリを作ったお話＜その１＞](https://qiita.com/ericcho/items/47ad5d2106238dda0e4e)

***

glide自体は、簡単だったのですがデータベースからデータを取得することが出来ませんでした。

理由は、セキュリティ上の問題で「直接データベースにアクセスすることが出来ない」からです。

困ったのでそこらへんが詳しい社内の先輩に相談してみたところ以下ならデータ取得が出来るとのことだったのでお願いしてみました。

***

#### 手順

１．本番サーバで当日配信されたデータだけをバッチで抽出してTSV形式ファイルに出力する
２．cronで中間サーバにscpで上記２ファイルを転送する
３．windows10のバッチで上記２ファイルをGoogleドライブのフォルダに転送する
４．スプレッドシートのGASのスケジューラで上記２ファイルを取り込む


これを時間差で実行するとのことでした。メモしたのをそのまま書いてます。。。

うん、分からない！！さっぱり分からない！！中間サーバはミーティングで聞いたことがあるようなないような。。。。

早速、データ転送システム（私が名付けた）を作ってもらいテストをしたのですが、上手くいきません。

確認してもらうとWindows10のスケジューラでPCがスリープ状態のときは実行しない設定になってました。
これを修正してみると・・・・・・・・・・・・上手く更新出来ました！！

***

#### 結論

glideはとても簡単！しかし、それなりのことをしようとすると一人じゃ無理！笑
あとWindows10のスケジューラ設定が難しかったです。（かなりググりました）

でも楽しいのでいろいろ作ってみます！

***


現場からは以上です。
FuelPHP・SQL で where句 と or_where句 を同時に使うとき

#はじめに
selectするときに、whereとor_whereを同時に使うときは注意しないと思っているようなクエリが発行されません。これは、論理演算子に優先順位が設定されているためです。（orよりandの方が優先順位が高いため）
https://dev.mysql.com/doc/refman/5.6/ja/operator-precedence.html

どういったクエリが発行されるか見ていきたいと思います。
また、whereはand_whereと書くこともありますが、今回はwhere、or_whereで統一します。
#環境
PHP 5.3.29
FuelPHP 1.7.3
MySQL 5.5.61
#本題
まずはor_whereから。

```sample1.php
  public static function sample1()
  {
    $query = \DB::select()
    ->from('table_name')
    ->or_where('column1', '=', 0)//条件1
    ->or_where('column2', '=', 0)//条件2
    ->execute()
    return $query;
  }
```
この場合はおそらくイメージ通り`条件1または条件2`となります。
ではここにwhere句を入れるとどうなるか。

```sample2.php
  public static function sample2()
  {
    $query = \DB::select()
    ->from('table_name')
    ->or_where('column1', '=', 0)//条件1
    ->or_where('column2', '=', 0)//条件2
    ->where('column3', '=', 0)//条件3
    ->execute()
    return $query;
  }
```
こうすると発行されるクエリは、`条件1または(条件2かつ条件3)`となり、後半に書かれたwhere句の処理が優先されます。
`(条件1または条件2)かつ条件3`としたい場合は、

```sample3.php
  public static function sample3()
  {
    $query = \DB::select()
    ->from('table_name')
    ->where_open()
      ->or_where('column1', '=', 0)//条件1
      ->or_where('column2', '=', 0)//条件2
    ->where_close()
    ->where('column3', '=', 0)//条件3
    ->execute()
    return $query;
  }
```
という書き方をする必要があります。同様に、`または`のくくりを大きくしたい場合は`or_where_open(),close()`というものが使えます。
How to uninstall mmhmm

To uninstall mmhmm, simply drag the app from your Mac's 'Applications' folder into the trashcan.

**AND**

sudo rm -rf /Library/CoreMediaIO/Plug-Ins/DAL/mmhmmCamera.plugin

https://help.mmhmm.app/hc/en-us/articles/360052331813-How-do-I-uninstall-mmhmm-from-my-computer-
https://telestreamforum.forumbee.com/t/h4k9d0/uninstall-wirecast-virtual-camera
win10 仮想環境のcentos7 記録メモ

#win10でVMwareでローカルに仮想環境(CentOS)を立ち上げる

・CentOS7のダウンロード
https://www.centos.org/download/

から指定バージョンのminimal.iso
をダウンロード

・VMで空の仮想マシンを立ち上げる

・その際にダウンロードしたisoディスクの場所を指定

・立ち上げるとCentOS7がインストールされる

・GUIツール

```
 # sudo -E yum groups install "GNOME Desktop" -y
```

・CUI→GUI

```
# systemctl isolate graphical.target
```

・GUI→CUI

```
# systemctl isolate multi-user.target
```
参考URL：(https://qiita.com/U_ikki/items/4342905d42c34a620247)

## yumとはなんぞや
#### リポジトリ：インターネット上にあるパッケージを置いてある倉庫
#### rpm：rpm 形式のパッケージを管理するときに使います
#### yum：パッケージの統合管理システム
インストールするパッケージの依存関係の解決に必要なパッケージを一緒にインストールしてくれる。
内部的にはrpmを呼び出しているがいろいろと高性能。

## EPEL リポジトリとは
EPEL リポジトリとは、CentOS 標準のリポジトリでは提供されていないパッケージを、yum コマンドでインストールすることを可能にするリポジトリのことです。

・EPELリポジトリ追加

```
# yum -y install epel-release
```
## remiリポジトリとは
標準のLinux リポジトリでは提供していないパッケージを提供している、拡張パッケージリポジトリである。
様々なバージョンのphpのパッケージを配布しているレポジトリである。
※remiリポジトリを使用するためにはEPELリポジトリをインストールする必要がある

・remiリポジトリ

```
# yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

・リポジトリ確認

```
# yum repolist all
```

・php5.6 and appach インストール

```
# yum -y --enablerepo=remi,remi-php56 install httpd php php-common
```
参考：https://weblabo.oscasierra.net/centos7-php56-install/

##google chrome install

```
# vi /etc/yum.repos.d/google.chrome.repo
```

```
[google-chrome]
name=google-chrome
baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch
enabled=1
gpgcheck=1
gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub
```
```
# yum update
```

```
# yum install google-chrome-stable --nogpgcheck
```

## VMware Tools install

### open-vm-toolsをインストール
```
# sudo yum install open-vm-tools
```

### 再起動して反映
```
# sudo shutdown -r now
```

### [事後確認・作業]
```
# rpm -qa open-vm-tools
open-vm-tools-9.10.2-5.el7_2.x86_64
```
【エラー解決】HV000030: No validator could be found for constraint 〜〜

#####【環境】

- ProductName:	Mac OS X
- ProductVersion:	10.14.6
- BuildVersion:	18G2022


#####【遭遇したタイミング】

- spring-bootでアプリを開発中

---

###結論

- 使うべきアノテーションを間違えていた。

###原因

`@Pattern` では使えない方法でバリデーションを設定していた。

---

#####【エラー内容】

```
There was an unexpected error (type=Internal Server Error, status=500).
HV000030: No validator could be found for constraint 'javax.validation.constraints.Pattern' validating type 'java.math.BigDecimal'. Check configuration for 'price'
```


訳：

```
HV000030: 型 'java.math.BigDecimal' を検証する制約 
'javax.validation.constraints.Pattern' のバリデータが見つかりませんでした。price' の構成を確認してください。
```
---

誤

```java

// 必須入力、1000円以上、数値へ変換
@NotNull
@Min(1000)
@Pattern(regexp = "#,###") // 指定パターンの文字列を、数値に変換する
private BigDecimal price;
```

正

```java
// 必須入力、1000円以上、数値へ変換
@NotNull
@Min(1000)
@NumberFormat(pattern = "#,###") // 指定パターンの文字列を、数値に変換する
private BigDecimal price;
```
MySQL⑦　使用できる値を制限する


#使用できる値を制限する
##１つだけ選択できる　enum
### カラムを作成する　カラム名 enum(値①, 値②, 値③)
create table users (
  id int unsigned primary key auto_increment,
  name varchar(20),
  score float,
  rank enum('gold', 'silver', 'bronze')
);

####値を入力
insert into users (name, score, rank) values ('taguchi', 5.8, 'silver');
insert into users (name, score, rank) values ('fkoji', 8.2, 'gold');
insert into users (name, score, rank) values ('dotinstall', 6.1, 'red'); 　<-　これはrankの値は保存されない

###内部的に値に１番スタートの連番が振られている
enum(①, ②, ③)

select * from users where rank = 'silver';
select * from users where rank = 2;

上記は同じ意味になる


##複数選択できる　set

### カラムを作成する　カラム名 set(値①, 値②, 値③)
create table users (
  id int unsigned primary key auto_increment,
  name varchar(20),
  score float,
  rank set('gold', 'silver', 'bronze')
);

####値を入力
insert into users (name, score, rank) values ('taguchi', 5.8, 'silver, gold');
insert into users (name, score, rank) values ('fkoji', 8.2, 'gold, bronze');
insert into users (name, score, rank) values ('dotinstall', 6.1, 'red'); 　<-　これはrankの値は保存されない

###内部的に値に番号が振られている
enum(２の0条, ２の1条, ２の4条)

select * from users where rank = 'gold,silver';
select * from users where rank = 3; 　<-　これは、２の0条の１ と ２の1条の２ を足した数

上記は同じ意味になる
GitHubのリポジトリの公開と非公開の切り替え

# はじめに
GitHubで非公開設定にしていたリポジトリを公開設定に切り替えようと思ったので、記録がてら記事にしておきます。
記事のなかでの動作は公開設定から非公開への切り替えで対応していますが、ご自身の切り替えたい方に合わせて選択欄はクリックしてください。

## 切り替え方法
まずは公開・非公開の切り替えをしたいリポジトリを開きます。
Code Issueなどメニューがずらりと並ぶ中から、一番右端の**Settingをクリック**。


Settingページを開いたら一番下までスクロールすると、
下記表示が見られるかと思います。
![スクリーンショット 2020-08-17 18.01.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646665/533d2f1c-009f-d439-2c1b-9bfe7361213b.png)
今回は一番上の『**Change repository visibility※**』を調整していきます。
※訳：リポジトリの可視性を変更する

![スクリーンショット 2020-08-17 18.03.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646665/7d407da0-599d-02e5-34ea-9b6eb3129bc8.png)

今回は**公開設定から非公開**への切り替えになるので、初期値としてMake privateにマークがついています。逆の場合はMake publicにマークがついています。

切り替えたい設定をクリックし、表示枠内の空欄に
**Please type ○○○○ to confirm.**
○○○○の部分を入力すると、以下のように設定の変更ボタンがクリックできるようになります。
※○○○○はユーザー名/リポジトリ名になっているはずです。
![スクリーンショット 2020-08-17 18.09.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/646665/bbc462be-1a43-e316-b08b-51170fb716c7.png)
ボタンをクリックして設定変更の切り替えは完了です。
なお、切り替え時に表示されている注意書きは興味があればGoogle翻訳にかけて読んでみてください。

## まとめ
**①変更したいリポジトリを開きSettingページへいく
②Danger ZoneのChange visibilityをクリック
③切り替えたい方をクリックし、ユーザー名/リポジトリ名を入力し、変更ボタンをクリック**
sqlで直接DBを更新をしないといけない時はトランザクションをかける



mysqlの場合

```sql

BEGIN;

# 何かしらの更新処理
update users set password = "hogehoge" where id = xx;

COMMIT;
# or rollback
```

* 更新処理を流した時に更新された件数が意図した件数かを確認してから `COMMIT`する

```sql

Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0
```

* 処理を取りやめたい（戻したい時は）`rollback`で戻せる
An error occurred while installing libv8 (3.16.14.19), and Bundler cannot continue

bundle install しようとした時に libv8 でエラー
自分の環境では下記の手順で bundle install が通ったので、メモ。

- エラー

```shell

An error occurred while installing libv8 (3.16.14.19), and Bundler cannot continue.Make sure that `gem install libv8 -v ‘3.16.14.19’ —source
```


- rbenvにbundleをインストール

[「libv8とtherubyracerが入らない時の対処法」をやっても入らないとき - Qiita](https://qiita.com/shunsuke1980/items/b16f3f87b6df4e9de1c1)

> bundleがrbenv内のgemを使っていないとbundle installが通らないので、rbenvにbundleをインストール

- 下記のコマンドを実行

[macOS Mojaveで古いlibv8とtherubyracerが入らない時の対処法 - Qiita](https://qiita.com/shimx/items/32e85093f21e673c7127)

```shell
brew install v8-315
bundle config --local build.libv8 --with-system-v8
bundle config --local build.therubyracer --with-v8-dir=$(brew --prefix v8-315)
```

さらにエラーがでた

```shell
An error occurred while installing mysql2 (0.4.10), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.4.10' --source 'https://rubygems.org/'` succeeds before bundling.

```

LIBRARY_PATH の変更

```shell

export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/opt/openssl/lib/
```

一応これで bundle install が通った。
[VirtualBox]Macでの仮想環境の構築方法

#仮想環境とは
「仮想環境」は、1台のPC内に、あたかも別のPCが入っているような環境をバーチャルで（仮想的に）作ることです。

仮想環境を構築すると、現在のPCの設定に影響を与えずに、別のPCとして開発環境を試すことができます。仮想環境は、不要になったら削除も可能です。

#1.VirtualBoxをインストール
まず、VirtualBoxをインストールして、PC上に仮想環境を構築します。
下のリンクからOSに合わせてVirtualboxをダウンロードします。

OSがMojave・Catalina
https://download.virtualbox.org/virtualbox/6.0.14/VirtualBox-6.0.14-133895-OSX.dmg

それ以外
http://download.virtualbox.org/virtualbox/5.2.6/VirtualBox-5.2.6-120293-OSX.dmg

#2.Vagrantをインストール
Vagrantは、仮想マシンを管理するツールで、Windows、Mac OS X、Linuxで動作します。
Vagrant自体には仮想化する機能はないため、仮想ソフトの操作をVirtualBoxで代行させています。

下記、Mac用のvagrantダウンロードページからダウンロードします。
https://releases.hashicorp.com/vagrant/2.2.4/vagrant_2.2.4_x86_64.dmg

#3.Vagrantを起動する準備
###3-1.「vagrant-vbguest」プラグインをインストール
vagrant-vbguestプラグインは、仮想マシンでの面倒な操作を肩代わりしてくれるプラグインです。 Macはターミナルを起動し、以下を入力します。
エラーが起きなければ、成功です。

```
$ vagrant plugin install vagrant-vbguest
```

###3-2.Vagrantの初期設定を行う
初期設定を行うには、「Vagrantfile」を利用します。Vagrantfileは、Vagrantの初期設定が記述されたファイルです。

下記からファイルをダウンロードします。
https://wals.s3-ap-northeast-1.amazonaws.com/uploads/unit/vagrant/Vagrantfile

ダウンロードが完了したら、以下のコマンドを実行します。

```
$ cd Desktop
$ mkdir vagrant 
$ cd vagrant 
```

ディレクトリの作成を確認できたら、先ほどダウンロードした「Vagrantfile」を「vagrant」フォルダ内にコピーまたは移動します。

#4.Vagrantを起動
以下のコマンドでvagrantを起動します。
起動までは1時間以上かかる場合があります。

```
$ vagrant up
```

#5.仮想環境へSSH接続
vagrantを起動しただけでは、仮想環境へは接続できていませんので、SSH接続を行います。

SSH接続とは、自分のPCから他のPCへ安全に接続するために接続手法です。
以下の通り、接続します。

```
$ vagrant ssh
```

以下のようになれば、仮想環境への接続は成功です。

```
[vagrant@localhost ~]$
```
MySQL⑥　レコードの更新、文字列の扱い

#レコードの更新､削除
####全てのレコードのカラムを更新する　update テーブル名 set 更新するカラム名 = 更新する値; 
update users set score = 5.9;

####特定のレコードだけ更新する update テーブル名 set 更新するカラム名 = 更新する値 where 条件にするカラム名 = 条件にする値;
update users set score = 5.9 where id = 1;

####複数のカラムを更新する
update users set name = 'sasaki', score = 2.9 where name = 'tanaka';


####レコードの全件削除
delete from users;

####条件を指定して削除
delete from users where score < 5.0;



#数値の演算
\+ - * / %

####カラムの値を計算して更新する
id が偶数の人のスコアを 1.2倍する。
update users set score = score * 1.2 where id % 2 = 0;

####数値の丸め（四捨五入）
select round(5.355);　　-> 5

####小数点 1 桁目で丸める
select round(5.355, 1); 　-> 5.4

####小数点以下の切り捨て 
select floor(5.833); 　-> 5
####小数点以下の切り上げ 
select ceil(5.238); 　-> 6

####ランダムで抽出する
select rand();
＊rand() を使うと 0 以上 1 未満のランダムな数値を返す。

####rand()で抽選１名
select * from users order by rand() limit 1;



#文字列の演算

####文字数の表示
select length('Hello'); 　--> 5

####何文字目以降を表示
select substr('Hello', 2);　-->ello
select substr('Hello', 2, 3);　-->ell

####大文字にする
select upper('Hello');　--> HELLO
####小文字にする
select lower('HELLO');　-->hello

####連結する
select concat('hello', 'world');　--> helloworld

####文字数でならべかえる
elect length(name), name from users order by length(name);

####カラムに別名をつける　as
select length(name) as len, name from users order by len;
Pythonの特徴について

# Pythonで出来ること
自身がPythonを学ぶ上で出来ることをまとめてみました。

* AI
PythonはAI・機械学習の開発に使えるライブラリがたくさん揃っており、その開発が現在進行系で進んでいる。AIや機械学習は数学的処理の塊です。行列計算や統計処理など山のように用いられます。それらを逐一実装していると時間がいくらあっても足りません。ライブラリが整っているおかげで効率よく学習でき、Pythonであれば効率よく開発ができます。AIや機械学習のプログラミングをする際は、すべての計算を自分で書くわけではない。特に教育現場でのロボット制御が有名で、レゴのマインドストリーム EV3もPythonを使って制御することが可能です。
<br>予測モデルを作成し、価格予測を行ったり、株式や債券などのポートフォリオ最適によって、投資リスクを最小にしてリターンを最大にする銘柄の算出なども行えます。


* Webサイト作成
Pythonはシステム寄りの言語と思われがちですが、Webサイトを作成することが可能です。
素のHTML/CSSを使うよりもはるかに高機能かつ保守性の高いサイトを作れます。
DjangoやFlaskといったフレームワークを利用することで効率的に開発することが可能です。ただし、WebアプリケーションにおいてはHTML/CSS、
Javascriptなど他の技術と組み合わせて利用することが一般的です。

* Web上の情報収集ツールの作成
クローリング、スクレイピングという技術を使って、例えば自身が気になる情報を自動定期的に収集するなどの操作がPythonは可能です。
有名な技術としてSeeniumというライブラリがあり、これを用いることで情報収集やブラウザ操作やテキスト入力が可能になります。自分が定期的にチェックしているWebサイトのデータを取ることで、手動でアクセスする手間が省けます。Webサイトの更新を自動的にチェックしたり、定期的に価格情報を取得して保存するなどの行動も可能なので、競合サイトのチェック作業を短縮することができます。
[YouTube][Instagram]にもPythonが使用されています。

* データ処理・分析・解析
Pythonの強みとして、数値計算能力と連携可能なシステムの多さが挙げられます。
大量にあるデータベースのデータを内部計算して読みやすい行列表に計算したり、競馬や株価の予測プログラムや自動取引アルゴリズムが作成できたり、別アプリにコピーしたりする柔軟なデータ処理が可能です。
<br>Excelはデータの整理やグラフ化を行うためのツールですが、同じ処理を毎日のように行うのは大変な作業です。ExcelにはVBAと呼ばれるプログラミング言語が用意されていますが、活用範囲が限定的なことから他の言語学習に時間を割く方は多い、Pythonを使用すればExcel操作の自動化を実施できます、一度プログラムを作成すればデータの集計・削除・統合やグラフなどを自動化できるようになります。

* スマホアプリ制作
Pythonのみを用いて、iOS/Android両方に対応したスマホアプリを作ることができます。
Kivyなどのマルチプラットフォームを使うとPythonでiPhone用のアプリやAndroid用のアプリを開発することも可能です。
SwiftやJavaなどのネイティブ言語と違い使用できない機能の制限もありますが、複数のライブラリが存在しています。

* ゲーム制作
Pythonでゲームを実装すると言ったら、まず名前が挙がるのがこのPYgameです。
Pygameを活用すれば、Pythonだけでゲーム開発ができます。Pygameに慣れれば手軽にPythonの機械学習アプリのデモを作ることもできるようになります
Pythonを使うと、2Dのレトロゲームから3Dのゲーム開発まで可能となります。
ゲーム開発といえばUnityですが、ゲームエンジンを使うとPythonでも本格的なゲームを作成することができます。 ディズニー社でも使われた実績があります。
実用的なUnityなどのフレームワークに比べると導入している企業は少ないです。

# Pythonの特徴
文法はやさしく、初心者にも学びやすく、コードが読みやすいことから、学校などでのプログラミング教育用にも使われています。

シンプルな必要最低限のコードで多くの処理ができます。 
強力な標準ライブラリやフレームワークと充実した外部ライブラリ
Pythonでは多くのタスクをサポートするライブラリやフレームワークが豊富にあります。 また、AI分野を主とする外部ライブラリが充実しているため、これらをふんだんに活用することにより、生産性の高い開発が可能になります。

様々なハードウェアとOSに対応できる移植性の高さ
Windows、Mac、Linux、PlayStationなどに対応することができ、どの機種・OSにおいてもPythonで作ったプログラムは同じ動きをします。
配列のパターン計算、摘出のプログラム

練習でプログラムしてたのでアウトプットです。
今回は個人的にスッキリしたコードになりました。

```ruby:qiita.rb
number = gets.chomp.split(' ').map{|i| i .to_i}
total = []

number.permutation(4) do |n|
  total.push((n[0]*10+n[1]) + (n[2]*10 + n[3]))
end

puts total.max
```


・入力した４つの数字を２つに切り分けて、それぞれに１０の位、１の位を与える。
・できた２けたの数字を加算する。
・それを予め入力した４つの数字のならび全てに適用する
・その合計値が一番大きいものを出力しました。

わかりにいくいと思うので下記処理内容です。

```ruby:qiita.rb
＃入力した値
 1 2 3 4  

#パターン出力
46　←12+ 34
55　←34+ 21
37　以下全パターン
55
37
46
55
64
37
64
37
55
55
73
46
73
46
55
64
73
55
73
55
64

#最大値　73
```
※実際はパターン出力も省略してます。

これをやるにあたり、何となく処理の流れは思い浮かんだのですが
配列の並びのパターンをどう抽出するか、、、とひたすら調べまくってたら
permutation を見つけました。

参考記事　https://qiita.com/shshimamo/items/5a458ecc88e7c24d5112

もっと時間をかけずに出来るようになりたいですねえ、、
何かアドバイスがあれば是非コメントお待ちしております！
プログラミング言語を学ぶ時には、はじめにプログラミング言語の家系図を見ておくとよいよ、という話

# プログラミング言語の家系図ってなに

あるプログラミングがいつ、どのような言語に影響を受けて誕生したかを表す系譜のことです。

# プログラミング言語の家系図はここにある

プログラミング家系図を載せているサイトはいくつかあるのですが、今回はこちらのサイトを紹介します。

[diagram & history of programming languages](http://rigaux.org/language-study/diagram.html) (プログラミング言語の系譜)

|![program_diagram.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288329/c5cab079-38a7-1cba-f4d0-0681f128ccd9.png)|
|:--|

主要言語のみものと、150以上の言語を載せているバージョンの2種類が記載されています。
2020年8月時点で、2018年の分まで記載されています。

# いくつかの言語をピックアップ

主要言語の図から、いくつかの言語をピックアップしてみましょう。

## C言語(K&R)

- 誕生: 1978年
- 影響を受けた言語:　Algol 60
- 影響を与えた言語:　C++, Python (他、子孫多数)

注)
C言語の誕生は1972年であるが、リンク先の図では、『プログラミング言語C』(原題：The C Programming Language、通称 K&R）が出版された年を採用している。(参考: [C言語 - Wikipedia](https://ja.wikipedia.org/wiki/C%E8%A8%80%E8%AA%9E), [プログラミング言語C - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9EC))

## Python

- 誕生: 1991年
- 影響を受けた言語: C, C++, Pascal
- 影響を与えた言語: Ruby

## Ruby

- 誕生: 1995年
- 影響を受けた言語: Perl, Eiffel, Python
- 影響を与えた言語: Swift

## Java

- 誕生: 1995年
- 影響を受けた言語: C++
- 影響を与えた言語: JavaScript, C#, Kotlin

## JavaScript

- 誕生: 1995年
- 影響を受けた言語: Java
- 影響を与えた言語: Kotlin

# プログラミング言語(2言語目以降)を学ぶ時には、はじめにプログラミング言語の家系図を見ておくとよいよ

さて表題の件ですが、2言語目以降のプログラミング言語を学ぶときにはこの家系図を最初に確認することをおすすめします。

理由は

- 自分がすでに知っているプログラミング言語と、新しく学ぶ言語がどのくらい離れているかによって習得難易度を把握することができるから
- 自分がすでに知っているプログラミング言語より新しい場合、新しくて便利な構文があることを期待しながら学習を進められるから
- 自分がすでに知っているプログラミング言語より古い場合、便利な機能がないことを覚悟しながら学習を進めることができるから

です。

自分の場合は、Java歴5年、Perlはバッチ程度ならで少し書ける程度のときに、Rubyを習得しようとしました。
そのときに、RubyはPerlから影響を受けていることを知ったので構文の理解に役立ちました。
一方、関数型言語の知識はほぼ無かったのでその部分は苦労しましたが、そのことを事前に予測できたのはよかったと思います。

# あとがき

『[はじめてのRuby](https://www.amazon.co.jp/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AERuby-Yugui/dp/4873113679
)』(著: Yugui) にRubyに関係する部分のプログラミング言語家系図が記載されていました。この図はRubyの理解に大変役に立ちました。

ほかの言語の図も探していたところリンク先のものが見つかりました。

プログラミング言語はここ数十年で大幅に進化しているのだなあ。