OmniAICreator/Qiita-1.07M huggingface dataset:
セル内の文字を抽出する_４（中間の文字）

文字の中間の文字を抽出する
============
文章の中間部分を抜き出したい時の関数等を紹介します。

見本として電話番号に見立てて、A1に「090-1234-5678」とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879772/d6a9546e-8d5d-9915-973d-9d0b5632c36f.png)




Excel関数
------
関数で抽出する場合の書き方

```ecl
=MID(対象セル,特定の文字の1つ後の数字,抜き出す文字数)

入力例
=MID(A1,FIND("-",A1)+1,4)
```

"特定の文字の1つ後の数字"
に今回もFINDの関数を使いました。
4文字目と決まっている場合などは良いのですが、
メールアドレスで"@"を起点に考える場合などは
"抜き出す文字数"も考慮しなければいけません。

```ecl
=MID(対象セル,@の一つ後の数字,@から後ろの文字数)

@から後ろを抜き出したい場合
=MID(A1,FIND("@",A1)+1,LEN(A1)-FIND("@",A1))
```
ココで初めてLENが出てきました。
LENは対象の文字数を調べてくれる関数です。
関数が複雑になってきたので補足すると
"@の一つ後の数字"は
LENでA1の文字数を取得（見本では17文字）
FINDで@の文字数を取得（見本では5文字目）
それぞれの関数で取得した数値で
全体－@までを計算します。
数値化すると、17－5になるので、
"@の一つ後の数字"は12になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879772/ae448bbe-667b-60c0-a35b-a00c7d290b57.png)

関数の厄介なところは一行で色々な事を書くとすごく分かりづらくなってしまいます。
FINDを2回使って同じ計算処理もしています。

そんな時は隣のセル等にLENやFINDで計算しておく事で同じ計算処理を省く事が出来るので、うまく組み合わせて使ってください。


ExcelVBA
------
VBAで抽出する場合の書き方

```vb

結果 = Mid(対象セル,特定の文字の1つ後の数字[,抜き出す文字数])

```

なぜかExcelVBAでは抜き出す文字数は任意となっており、
値を入れない場合は最終文字まで取得してくれます。


```vb

Sub 文字の中間から抽出()
    
    'セルA1の左から半角スペースの一文字前までをセルB1に出力
    Cells(1, 2) = Mid(Cells(1, 1), WorksheetFunction.Find("-", Cells(1, 1)) + 1, 4)
    
    '確認用のメッセージボックス
    MsgBox Cells(1, 2)
    
End Sub

```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879772/64942879-30d0-6cec-8947-841c2582f1d6.png)

動作としては問題ありませんが、
取得する"取得する文字数"が4文字固定とは限りません。
一つ目と二つ目の-（ハイフン）の場所を変数に記憶させて
中間数の文字数を計算するように修正します。

```vb

Sub 文字の右から抽出()
    
    '変数名"x"、"y"、"z"をVariant方式で指定します
    Dim x, y, z As Variant
    
    '一つ目のハイフン
    x = WorksheetFunction.Find("-", Cells(1, 1))
    
    '二つ目のハイフン
    y = WorksheetFunction.Find("-", Cells(1, 1), x + 1)
    
    '一つ目と二つ目のハイフンの間の文字数を計算
    z = y - x - 1
    
    'セルA1の左から半角スペースの一文字前までをセルB1に出力
    Cells(1, 2) = Mid(Cells(1, 1), x + 1, z)
    
    '確認用のメッセージボックス
    MsgBox Cells(1, 2)
    
End Sub

```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879772/d5a9305d-62cd-f0e1-dd36-edf73c224cd8.png)



使用例としてはやはり電話番号でしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879772/fc2351cf-e6b2-7481-24d6-4c86b4109ae2.png)
ハイフンの一つ目、二つ目を隣のセルに先に取得しておくことで
どこからどこまで文字を取得するかを楽に入力できます。

今まで紹介した関数を使って携帯電話の番号を分割して取得しています。

次回は特定文字をカウントするCOUNTIF関数を紹介したいと思います。
セル内の文字を抽出する_３（左から指定の文字まで）

文字の左から指定の文字まで抽出する
============
前回の左から指定数の文字を抽出する場合、
全て同じ文字数を抽出すれば解決するのであれば良いのですが、
苗字と名前
都道府県と市区町村
数字と文字
など一緒の文字列になっているものを分けたい場合などをご紹介します。

見本としてA1に「宮本 武蔵」、A2に「佐々木 小次郎」としました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879772/e19fcdcb-7072-b783-ee10-98a6891c0514.png)


Excel関数
------
関数で抽出する場合の書き方

```rb
=LEFT(対象セル,特定の文字の1つ前の数字)

入力例
=LEFT(A1,FIND(" ",A1)-1)
```

"特定の文字の1つ前の数字"
にFINDの関数を使っています。
FINDは特定の文字が何文字目にあるかを返してくれる関数です。

```rb
=FIND(検索文字,対象セル,[開始位置])

入力例
=FIND(" ",A1)
```
開始位置は任意です。
開始位置をうまく使うと電話番号の-(ハイフン)等、
同じ検索文字の一つ目、二つ目を探して文字を抽出したりできます。
ココは別の記事で分けて書こうと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879772/d4715558-0e7c-47fb-3f6c-04b11461f05d.png)


ExcelVBA
------
VBAで抽出する場合の書き方

```rb

結果 = Left(対象セル,特定の文字の1つ前の数字)

```

としたいのですが、今までのRightやLeftのようにFindだけでは使えません。
別途計算をするか、"WorksheetFunction.Find"として書きます。
関数と同じ処理をしたいけど、そのままだと動かない場合に"WorksheetFunction"を使う事で
Excel関数と同じ処理をする事ができます。


```rb

Sub 文字の右から抽出()
    
    'セルA1の左から半角スペースの一文字前までをセルB1に出力
    Cells(1, 2) = Left(Cells(1, 1), WorksheetFunction.Find(" ", Cells(1, 1)) - 1)
    
    '確認用のメッセージボックス
    MsgBox Cells(1, 2)
    
End Sub

```
実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879772/ddb378ac-eb9e-fed6-dae9-74d538d1aeb1.png)

使用例としては市区町村を分けるときなどに使えると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879772/1849666b-7be6-39bf-2f2f-71a5c61d104c.png)

次回は文字の中間を抜き出す方法を紹介したいと思います。
API に Request した Body の JSON 文字列を Parse する処理を綺麗に書いてみる


Controllerの中でごちゃごちゃやりがちだったので備忘録として残しておく。

## InputModelクラスを定義

modelクラスを👇のように定義。

```C#
using System.Text.Json;
using System.Text.Json.Serialization;
namespace TestHogeHoge.Models
{
 public class InputModel
    {
        [JsonPropertyName("id")]
        public string Id { get; set; }
        [JsonPropertyName("name")]
        public string Name { get; set; }
        [JsonPropertyName("address")]
        public string Address { get; set; }

        public static InputModel Parse(string json)
        {
            return JsonSerializer.Deserialize<InputModel>(json);
        }
    }
}
```

各プロパティにはJson時のプロパティとParse先を定義してあげます。  
System.Text.JsonのJsonSerializerを使ってデシリアライズしてあげるようにParse()を定義します。  

リクエストするときのBodyは定義したModelに合わせてリクエストします。  
👇例

```JSON
{
    "id": "111",
    "name": "hogehoge",
    "address": "hoge address"
}
```

## 実際に定義したクラスを使って書いてみると

RequestBody を取得したら StreamReader で読み込んで、  
そのままInputModelクラスで定義したParseを実行させます。

```C#
var input = await new StreamReader({リクエストしたBody}, Encoding.UTF8).ReadToEndAsync();
var inputData = InputModel.Parse(input);
```
負荷試験 vegeta 使い方例

* [人気の負荷試験（負荷テスト）ツールを調べてみる（Locust, Vegeta, wrk） - もた日記](https://wonderwall.hatenablog.com/entry/load-testing-tools#%E8%B2%A0%E8%8D%B7%E8%A9%A6%E9%A8%93%E8%B2%A0%E8%8D%B7%E3%83%86%E3%82%B9%E3%83%88%E3%83%84%E3%83%BC%E3%83%AB%E4%B8%80%E8%A6%A7) によると2位の様子。
* https://github.com/tsenart/vegeta

## GET

```go
echo "GET http://localhost/" | vegeta attack -duration=5s | tee results.bin | vegeta report

vegeta report -type=json results.bin > metrics.json
cat results.bin | vegeta plot > plot.html
cat results.bin | vegeta report -type="hist[0,100ms,200ms,300ms]"
```

## POST

* request_url.txt : URLを記述
* parameter.txt   : POST値を記述

サンプル

```go:request_url.txt
POST http://localhost:8000/sample.php
Content-Type: application/x-www-form-urlencoded
@parameter.txt
```

```go:parameter.txt
type=test&hoge=fuga
```

```sh:run.sh
RATE=100
DURATION=5s

./vegeta attack \
 -duration=$DURATION \
 -rate=$RATE \
 -targets="request_url.txt" \
 > result.bin


cat result.bin | ./vegeta report
```

## report

* 複数を重ね合わせることが出来る

```go
vegeta plot results.100qps.bin > plot.html
```

### グラフ

```go
cat result/10.bin \
 | ./vegeta report -type='hist[100ms,200ms,300ms,400ms,500ms,1000ms]'
```

```go:サンプル
Bucket           #   %       Histogram
[0s,     100ms]  0   0.00%
[100ms,  200ms]  34  68.00%  ###################################################
[200ms,  300ms]  16  32.00%  ########################
[300ms,  400ms]  0   0.00%
[400ms,  500ms]  0   0.00%
[500ms,  1s]     0   0.00%
[1s,     +Inf]   0   0.00%
```

```go:サンプル2
Bucket           #   %       Histogram
[0s,     100ms]  26  30.59%  ######################
[100ms,  200ms]  4   4.71%   ###
[200ms,  300ms]  4   4.71%   ###
[300ms,  400ms]  2   2.35%   #
[400ms,  500ms]  6   7.06%   #####
[500ms,  1s]     8   9.41%   #######
[1s,     +Inf]   35  41.18%  #############################
```
【javascript】フロントでUTCの時間をJSTに変換するぞ【React】

<h2>UTCの時間をJSTに変換したい</h2>
DBに登録しておいたものをフロント側に持ってきたとき、なんだか9時間程度時間がずれて表示される事象がありました。

```terminal:UTC
//本来は2021-08-11 22:38:05に登録したものが下記になっていました
2021-08-11T13:38:05.813Z
```

原因としては、DB登録時にJST(日本時間)ではなく、UCT(協定世界時)で登録されていることが分かりました。

手っ取り早く実装を進めたかったので、根本の原因を追究するよりも暫定的にフロント側でUTCからJSTに変換しようと考えました。

<h2>実装してみる</h2>
以下で実装しました。
フロント側でファンクションを作成し、UTCをJSTに変換したのちに、「yyyy/MM/dd (w)hh:mm」にフォーマットするようなものにしました。

```react:changeJSTDate
export function changeJSTDate(date) {
  const newDate = new Date(date)
  const year = newDate.getFullYear()
  const month = newDate.getMonth() + 1
  const day = newDate.getDate()
  const dayOfWeek = '日月火水木金土'.charAt(newDate.getDay());

  const hour = (`0` + (newDate.getHours())).slice(-2)
  const minute = (`0` + (newDate.getMinutes())).slice(-2)
  return `${year}/${month}/${day} (${dayOfWeek}) ${hour}:${minute}`;
}
```

ちょっと見にくいですが、解説追加してみました。

ちなみに、@sgm94さんのご指摘で時刻のゼロサプレス対策がされていなかったので、「時」と「分」それぞれの先頭に0を足して、文字の後ろから2文字分までを渡すようになっています。

また、日にちを受けとるnewDateをnewDayと間違えてるとご指摘をいただいたので、そちらも修正しました。ご指摘ありがとうございます！

```react:
//dataの中身は「2021-08-11T13:38:05.813Z」です
export function changeJSTDate(date) {
  const newDate = new Date(date)//中身は「Wed Aug 11 2021 22:38:05 GMT+0900 (GMT+09:00)
  const year = newDate.getFullYear()//「2021」が代入される
  const month = newDate.getMonth() + 1 //「8」が代入される(getMonthだと1月分少なくなって返ってくるので+1する)
  const day = newDate.newDate()//「11」が代入される

  const dayOfWeek = '日月火水木金土'.charAt(newDate.getDay());//「水」が代入される

  const hour = (`0` + (newDate.getHours())).slice(-2)//「22」が代入される
  const minute = (`0` + (newDate.getMinutes())).slice(-2)//「38」が代入される
  return `${year}/${month}/${day} (${dayOfWeek}) ${hour}:${minute}`;//ここで文字列にフォーマットしてreturn
```

<h2>参考</h2>

https://iwb.jp/javascript-new-date-gettime/

https://qiita.com/study-toto/items/3174820b1c8b8c5ba4f7

https://ja.wikipedia.org/wiki/ISO_8601
シェルスクリプト作成の基礎 Part1(変数、配列)

【スクリプトの作成】
cat /etc/shells→サポートしているシェルを一覧表示

ファイル作成
viコマンドでファイル名末尾に.shを付ける
ファイルの中身→#!/bin/bash 1行目でシェルの場所を指定する
コメント文は#を文頭に記載
exit 0→処理終了(0が正常終了、それ以外は異常終了)

実行
chmod 755 ファイル名→パーミッション変更
./test.sh→シェルスクリプトの実行

【変数の使い方】
var1='変数1'→変数の宣言
var2=`command`→コマンドの実行結果を変数に格納
var3=$(command)→コマンドの実行結果を変数に格納

echo $var1→変数の中身を取り出す場合には、$を付ける

$BASH,$BASH_VERSION,$HOME,$PWD→システム変数の表示

【配列の作成】
echo ${fruits[@]}→配列の中の値を全て表示
echo ${fruits[0]}→インデックス0の要素を表示
echo ${!fruits[@]}→インデックスを表示
echo ${#fruits[@]}→配列の要素の数を表示

fruits[3]='lemon'→配列のインデックス3(4番目)にlemonを追加
unset fruits[2]→配列のインデックス2(3番目)を削除
【個人開発】データベースサーバ上のデータを用いたダッシュボードを作りたい。

## 目的
自分のアプリの利用状況を簡単に確認するために、業務で使っている**redashみたいなやつで個人で利用できるもの**が欲しい！！！

ちなみにアプリはこちら：

https://apps.apple.com/jp/app/twi%E3%82%B9%E3%82%B1/id1491291009


現状：
さくらのレンタルサーバにアクセスし、そこからデータベースサーバにアクセスし、GUIでテーブルを選択してデータ一覧をテーブル形式で見る。

理想：

- グラフ等で一週間の利用傾向を確認したい。
- 複数のテーブルにまたがるデータを結合してまとめて確認したい。
- できれば表示までのクリック数を減らしたい。

## 調査
そういったツールはたくさんあるらしい。

調べてみると、OSSバージョンは無料だけどクラウドバージョンは有償、というアプリが多かった。
その中で、macで簡単に利用できるものとして「MetaBase」をチョイス。

https://qiita.com/acro5piano/items/0920550d297651b04387

## 利用方法
以下からダウンロードして、指示の通りに設定していく。

https://www.metabase.com/docs/latest/operations-guide/running-the-metabase-mac-app.html

さくらのmySQLサーバは、さくらレンタルサーバ上からしかアクセスできないので、sshトンネル機能を利用する。
パスワードor公開鍵認証方式、自分が使っている方を選択。

## ダッシュボードの作成
使い方は使えばわかる。
まさに求めていたもの、という感じです！
![Metabase.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/46f46512-1e3c-91c8-22b6-da1f934655d2.jpeg)



## その他
使い勝手が悪いかなぁと感じている部分。

- 最初の方はよく落ちる
インストールしたての頃は、よく落ちた。
落ちて、再度開こうとすると、エラーが無限に出続ける。
そんな時は、アクティビティモニタからjavaを選択して強制終了。
原因は不明。
ログイン機能作成 ② php

#■⑦ログインフォーム

``` login.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ログイン登録画面</title>
</head>
<body>
    <h2>ログインフォーム</h2>
     <form action="top.php" method="POST">
         <p>
         <label for="email">メールアドレス：</label> 
         </p>
         <p>
         <label for="username">パスワード：</label>
         </p>
         <p>
         <input type="submit" value="ログイン">    
         </p>
     </form>
     <a href="signup_form.php">新規登録はこちら</a>
    
</body>
</html>
```

#■⑧バリデーション

``` top.php
<?php
require_once('../classes/UserLogic.php');
//エラ〜メッセージ
$err = [];

if(!$email = filter_input(INPUT_POST,'email')) {
    $err['email'] = 'メールアドレスを記入してください。';
}

if(!$pass = filter_input(INPUT_POST,'password')) {
    $err['password'] = 'パスワードを記入してください。';
}


if(count($err) === 0) {
   echo 'ログインしました。';
}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ユーザー登録完了画面</title>
</head>
<body>
    <?php if(count($err) > 0):?>
    <?php foreach($err as $e): ?>
    <p><?php echo $e?></p>
    <?php endforeach?>
    <?php else:?>         
    <p>ユーザー登録が完了しました。</p>
    <?php endif?> 
    <a href="./login.php">戻る</a>
</body>
</html>
```

#■⑨top.phpでsessionを使う。

``` top.php
//下記を追加
<?php
//セッションするのに必要
session_start();

if(count($err) > 0) {
    //エラーがあった場合はエラーを&_SESSIONに入れたままlogin.phpに戻る。
    $_SESSION = $err;
    //login.phpに戻る。
    header('Location: login.php');
    return;
}
?>
```

#■⑩login.phpにもsessionを使う。
例えば名前やパスワードを記入せず
ログインボタンを押した場合ページを変えずlogin.phpでエラーメッセージを出す事ができる。

``` login.php
<?php
//セッションするのに必要
session_start();

//セッションで　エラーメッセージを受け取る。
$err = $_SESSION;

//再度更新した時にセッションを消す。
$_SESSION = array();
session_destroy();
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ログイン登録画面</title>
</head>
<body>
    <h2>ログインフォーム</h2>
     <form action="top.php" method="POST">
         <p>
         <label for="email">メールアドレス：</label>
         <input type="email" name="email">
         //エラーメッセージがあれば記載  
         <?php if(isset($err['email'])):?>
         <p><?php echo $err['email'];?></p>
         <?php endif?>  
         </p>
         <p>
         <label for="username">パスワード：</label>
         <input type="password" name="password">
　　　　　　　　　　　　　　　　　　/エラーメッセージがあれば記載 
         <?php if(isset($err['password'])):?>
         <p><?php echo $err['password'];?></p>
         <?php endif?>       
         </p>
         <p>
         <input type="submit" value="ログイン">    
         </p>
     </form>
     <a href="signup_form.php">新規登録はこちら</a>
    
</body>
</html>
```
[Ruby] AtCoder 過去問 B - Digit Sums

##はじめに
AtCoderのB問題 Digit SumsをRubyで解いてみました。

問題の確認は下記からお願いします。
他のやり方などご教授いただけると幸いです。
それではよろしくお願いします。

https://atcoder.jp/contests/abc101/tasks/abc101_b

##B - Digit Sums

まずは入力の受け取りです。
今回は数値を一つだけ受け取ればいいので下記のように記述するだけで十分です。

```Ruby
n = gets.to_i
```

この数字を桁ごとに分解して、それらを足し算する必要があります。
このとき私は、まず文字列に変換して、charsメソッドで一文字ずつに分けて、再度数値に戻して。。。と考えていましたが、とても便利なメソッド、digitsメソッドを見つけましたのでこちらを活用したいと思います。


使い方は下記の記事にまとめておきました。

https://qiita.com/minhee/items/5a01438f20e274f58ed8


簡単にいうと数値を桁ごとに分けて配列で返してくれます。
さらにその配列の要素をsumメソッドで足して、変数に入れておきます。

```ruby
n = gets.to_i
 
n_sum = n.digits.sum
```

上記の記述で問題の↓の部分はクリアです。

> 整数 nに対して，nを十進法で表したときの各桁の和を S(n)で表すことにします． たとえばS(101) = 1 + 0 + 1 = 2です。
 

あとはこのn_sumでnが割り切れるかどうかをif文の条件式で分岐させて、trueならYes、falseならNoを出力させます。

```Ruby
n = gets.to_i
 
n_sum = n.digits.sum
 
if n % n_sum == 0
  puts "Yes"
else
  puts "No"
end
```

##終わりに
digitsメソッドの収穫は大きかったです。
他にも便利なメソッドや解法があれば教えていただければ幸いです。
「Android Gradle plugin requires Java 11 to run.」エラーの対処法

アプリを実行すると以下のエラーが発生しました。

```
An exception occurred applying plugin request [id: 'com.android.application']
> Failed to apply plugin 'com.android.internal.application'.
   > Android Gradle plugin requires Java 11 to run. You are currently using Java 1.8.
     You can try some of the following options:
       - changing the IDE settings.
       - changing the JAVA_HOME environment variable.
       - changing `org.gradle.java.home` in `gradle.properties`.
```

# 対処法

`Java 11`を選択することで解決します

## `Android Studio`の`Preferences`を開く

`command + ,`でも開けます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365643/ee759d03-8560-1dd9-d516-357e762e0062.png" width=250 />


## `Build, Execution, Deployment > Build Tools > Gradle`を開く

`Gradle JDK`から`11 version 11.0.10`を選択します。

![スクリーンショット 2021-08-18 19.04.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365643/9d90a7dc-a348-3029-b55d-e0925ba15d8a.png)

___

これでアプリが実行出来ると思います！
Androidブラウザ（実機 or エミュレータ）からローカルサーバ（localhost）にアクセスする

# はじめに

MacのPCにローカルサーバでnode.jsのアプリをnode appで実行している場合に、実機の端末からアクセスする方法です。
node.jsの場合はポートが3000がデフォルトです。

# 端末からアクセス

実機もPCももちろん同じネットワークに接続します。

```
http://localhost:3000/
```

このようにしてPCからであればアクセスできますが、実機やエミュレータでは、何もしないとエラーとなります。

```
http://127.0.0.1:3000/
```

これも同じくエラーです。

エミュレータと実機でアクセス方法が違います。

## エミュレータの場合

```
http://10.0.2,2:3000/
```

これでアクセスできます

## 実機の場合

まずPCでchromeブラウザを立ち上げて下記のアドレスにアクセスします。

```
chrome://inspect/#devices
```

![スクリーンショット 2021-08-18 19.02.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109862/6aabe278-5c01-33c6-f490-29a71457bcd1.png)


そして、port forwardingというボタンを押します

![スクリーンショット 2021-08-18 19.03.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109862/39c79ba7-ef9c-ca2e-9a04-642d8bc6c669.png)

そして下記のように登録して、Enable port forwardingにチェックを入れます
ipaddress and port : localhost:3000
port : 3000

この状態にすると

```
http://localhost:3000/
```

これでアクセスできます
Laravel Voyager BREADの入力制限設定

Laravel Voyagerの画面ポチポチで画面が作れるBREAD機能
入力制限やVaridationチェックはドキュメント
https://voyager-docs.devdojo.com/v/1.1/core-concepts/bread-builder#validation
にかかれていますが、具体的には以下のような感じでいけそうです。


作成したBREADのEditを行うと下の方にはフィールドが並んでいますよね
![スクリーンショット 2021-08-18 18.57.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19107/0732863d-4f42-00ca-a187-22aecb023dab.png)

その右側に「Optional Details」というのが有って、
ここにJSONで設定をします。

例えば・・

####必須で最大12文字の場合

```JSON
{
    "validation": {
        "rule": "required|max:12",
        "messages": {
            "required": ":attributeは必須項目です",
            "max": ":attributeは最大で :max 文字です"
        }
    }
}
```

####必須で数値の場合

```JSON
{
    "validation": {
        "rule": "required|numeric",
        "messages": {
            "required": ":attributeは必須項目です",
            "numeric": "数値で入力してください",
        }
    }
}
```

ruleに使えるVaridationは
https://laravel.com/docs/8.x/validation#available-validation-rules
を参考にすればいいようですが、若干使えないようなものもあるようですので、
試しながら・・でしょうかね。






###ちなみに
業務システムやサイト作成などお仕事お待ちしております。
お問い合わせはコメント欄にお願いします！
簡単airflow立ち上げ方法 #memo

＃メモ記事です。

これだけで実行可能。
passwardの部分だけは書き換えてね。
ローカル環境以外で立ち上げる人は、セキュリティ設定に気を付けましょう。

環境：ubuntu

```
export AIRFLOW_HOME=~/airflow
pip3 install apache-airflow
pip3 install typing_extensions
# initialize the database
airflow db init

airflow users create --username Admin --firstname FIRST_NAME --lastname LAST_NAME -p ぱすわーーーーーど --role Admin --email admin@example.org

# start the web server, default port is 8080
airflow webserver -p 8080
# start the scheduler. I recommend opening up a separate terminal #window for this step
airflow scheduler
# visit localhost:8080 in the browser and enable the example dag in the home page
```

# ref
立ち上げ：https://medium.com/@jacksonbull1987/how-to-install-apache-airflow-6b8a2ae60050
サンプル：https://dev.classmethod.jp/articles/airflow-gs-arch-learn/
AWS（VPC/EC2/RDS/Routes53）デプロイ時のエラー

## はじめに

AWS（VPC/EC2/RDS/Routes53）を使用してポートフォリオアプリをデプロイしました。参考にしたQiita記事を貼り付けておきます。

- https://qiita.com/take18k_tech/items/5710ad9d00ea4c13ce36

この記事では、上記記事を参考にデプロイした際のエラーについて解決方法を記載します。

## 開発環境

- Ruby 2.7.2
- Rails 6.1.4
- Docker
- MySQL
- CircleCI(RSpec、Rubocop)


## デプロイしたアプリのインフラ構成図

![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1536072/1d10108f-62b8-9da2-3bda-9eded75b95ea.png)

- 参考（デプロイしたポートフォリオのアプリ）↓

- http://target-01.work/

## エラー内容
### yumがアップデートできない
- NginXの設定

`sudo yum -y update`を実行したところ、下記エラーコード

- エラーコード

```rb

Loaded plugins: priorities, update-motd, upgrade-helper
Could not retrieve mirrorlist http://repo.ap-northeast-1.amazonaws.com/latest/main/mirror.list error was
12: Timeout on http://repo.ap-northeast-1.amazonaws.com/latest/main/mirror.list: (28, 'Connection timed out after 5001 milliseconds')


 One of the configured repositories failed (Unknown),
 and yum doesn't have enough cached data to continue. At this point the only
 safe thing yum can do is fail. There are a few ways to work "fix" this:

     1. Contact the upstream for the repository and get them to fix the problem.

     2. Reconfigure the baseurl/etc. for the repository, to point to a working
        upstream. This is most often useful if you are using a newer
        distribution release than is supported by the repository (and the
        packages for the previous distribution release still work).

     3. Disable the repository, so yum won't use it by default. Yum will then
        just ignore the repository until you permanently enable it again or use
        --enablerepo for temporary usage:

            yum-config-manager --disable <repoid>

     4. Configure the failing repository to be skipped, if it is unavailable.
        Note that yum will try to contact the repo. when it runs most commands,
        so will have to try and fail each time (and thus. yum will be be much
        slower). If it is a very temporary problem though, this is often a nice
        compromise:

            yum-config-manager --save --setopt=<repoid>.skip_if_unavailable=true

Cannot find a valid baseurl for repo: amzn-main/latest

```

#### 原因

- セキュリティグループのアウトバウンドルールが正しく設定されていなかった。

#### 解決策

- 下記サイトを参考にして、アウトバウンドルールを設定したところ、解決した。

https://www.dragonarrow.work/articles/151


### 画像が表示されない

#### 原因

- デプロイ時の画像ファイルの位置は`assets/images`配下になっていた。

- 調べたところ、AWSでは、`assets/images`配下の画像を読み込まない。**読み込まれるのは、`public/images`配下の画像**である、とのこと。

#### 解決策

- `mv assets/images public/images`を実施し、manifest.jsの中身を修正したところ、解決した。

```manifest.js

//= link_tree ../../../public/images
//= link_directory ../../javascript/stylesheets .scss

```
※もし参考にする場合、階層は各自のpublic配置場所に合わせてください。


## まとめ

**最低限の知識があれば、Qiita記事を参考に何とかAWSでデプロイできる**

これからも勉強を続けたいと思います。

## 参考

https://qiita.com/take18k_tech/items/5710ad9d00ea4c13ce36
Databricksにてローカル環境での開発を考慮した自作モジュールを取り込む方法

## 概要
Databricksにてローカル環境での開発を考慮した自作モジュールを取り込む方法を共有します。
あまりよい方法ではないので、よりよい方法をご存知の方はご教授ください。

Databricksでは自作モジュールを取り込む際に、%runを利用する必要があり、importを利用するとエラーとなるという課題があります。
また、ローカル開発時には、Jupyter等のノートブック型の開発ツールを利用しない場合には、%runがエラーになります。

上記の解決策となる下記の方法を紹介します。
エクスポートする手順を紹介してますが、Databricks Repos機能を用いることでGitでPythonコードを取得することも可能です。

- tryによりDatabricks上で開発時にエラーとしない
- databricksからエクスポートすることで%runの箇所をコメントアウト


詳細は下記のGithub pagesのページをご確認ください。

https://manabian-.github.io/databricks_tecks_for_qiita/#import_libarary_local_and_db/runner.html

コードを実行したい方は、下記のdbcファイルを取り込んでください。

```URL
https://github.com/manabian-/databricks_tecks_for_qiita/blob/main/tecks/import_libarary_local_and_db/dbc/import_libarary_local_and_db.dbc
```

## 手順
### 1. Databricks上での開発
#### 1-1. モジュールを作成

```python
class TestClass:

    @staticmethod
    def print_msg():
        print('Hello World')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/8cce422f-870d-b0e1-7fdb-35bf7f41f8bc.png)

#### 1-2. モジュール（クラスのメソッド）を利用

```python
try:
    from includes.module import *
except ImportError:
    pass
```

```python
%run ./includes/module
```

```python
TestClass.print_msg()
Hello World
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/cbf75465-0b3f-e8fb-abea-66b8d0544cc7.png)

### 2. ローカル上で開発
#### 2-1. Databricksからノートブックをエクスポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/cc51faab-9ebb-2791-94a8-c71dcb2ce6e3.png)


#### 2-2. ローカル上で実行できることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/a50b3560-211f-a87b-1eae-9d387f85ac8f.png)
UranusDet

#回転付きの物体検出

良いベンチマークがあったので共有します。

https://github.com/yangxue0827/RotationDetection

baiduに登録するのはハードルが高いと思うのでgoogleドライブに置いてみました。
[GWD](https://drive.google.com/drive/folders/1nDQ65SS-8MmlEb5AAfzb_wXndhVFCdZU?usp=sharing)
AWS：Rekognitionとpythonで顔の分析を行ってみる

#AWSのサービスを色々使って、理解を深める。
AWSの勉強をしていたら予想以上に色々できることに驚いた。
AWSを自由自在に使えたら便利なのでは？と思い付き、やってみた。
###参考
①_Qiita記事（コードの内容）
https://qiita.com/banquet_kuma/items/560787299b83fb924ff7
②_AWS_Rekognition公式入門ガイド
https://aws.amazon.com/jp/rekognition/resources/
③_AWS_Rekognition　detect_facesオペレーション
https://docs.aws.amazon.com/ja_jp/rekognition/latest/dg/faces-detect-images.html

###内容
1.　IAMユーザーの作成

2.　AWS CLI と AWS SDK をインストールして設定
　　※基本は参考③を見ながら実行しました。
　　※アクセスキーのデータは参考①のpythonのライブラリ「configparser」を使用
 
３. コードの記述及び実行
前半は参考①を、後半は参考③を参照し、つなぎ合わせたイメージ。

```python:コード全体
import boto3
import configparser
from PIL import Image

#参考①を参照して記述
ini = configparser.ConfigParser()
ini.read("Rekognition/config.ini","utf-8")

filename = "読み取りたい画像"
img = Image.open(filename)
img_width = img.size[0]
img_height = img.size[1]

bucket = "AWS S3のバケット名"
region = "AWS のregion名"

#iniデータからaws_access_key_idとaws_secret_keyを参照
access_key = ini["AWS_KEY"]["aws_access_key_id"]
secret_key = ini["AWS_KEY"]["aws_secret_key"]
session = boto3.Session(aws_access_key_id=access_key,aws_secret_access_key=secret_key,region_name=region)

s3 = session.client("s3")
rekognition = session.client("rekognition")

with open(filename, "rb") as f:
    # 読み込んだファイルをS3サービスにアップロード
    s3.put_object(Bucket=bucket, Key=filename, Body=f)

#参考③を参照して記述
response = rekognition.detect_faces(Image={"S3Object":{"Bucket":bucket,"Name":filename}},Attributes=["ALL"])


print('Detected faces for ' + filename)    
for faceDetail in response['FaceDetails']:
    print('The detected face is between ' + str(faceDetail['AgeRange']['Low']) 
            + ' and ' + str(faceDetail['AgeRange']['High']) + ' years old')


    #print('Here are the other attributes:')
    #print(json.dumps(faceDetail, indent=4, sort_keys=True))
    # Access predictions for individual face details and print them
    print("Gender: " + str(faceDetail['Gender']))
    print("Smile: " + str(faceDetail['Smile']))
    print("Eyeglasses: " + str(faceDetail['Eyeglasses']))
    print("Emotions: " + str(faceDetail['Emotions'][0]))
```
###実行結果
下の画像で実行。
漫画絵でも判別してくれる。
![nigaoe_edogawa_ranpo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698556/6e32f2fc-0421-b2a7-c7b0-b0dbbc4b5a79.png)
![screen 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698556/4525d721-b849-6a31-c323-a169aa16b5cb.png)
年齢：28〜44歳
笑っているか：不明
メガネ：あり
感情：落ち着いている

使用画像：いらすとや
https://www.irasutoya.com/

###所感
詳細は理解していませんが、まずは動かせました、ヨシ！！
真剣に学びつつ、遊びつつ、AWSの理解を深めていこうと思います。
AWSに感動中。
S3へクロスアカウントでファイルアップロードしたときの権限エラーについて

#はじめに
S3へクロスアカウントアクセスの設定をした際に、
アップロードしたファイルがダウンロードできない(Access Denied)になってしまったので
そのときの対応について書いておこうと思います。

#原因
EC2など(アカウントA)→S3(アカウントB)とクロスアカウントでアップロードした際に
アップロードしたオブジェクトの所有者がアカウントA側になってしまっていることが原因。

S3のコンソールからアップロードしたファイルのアクセス許可を確認すると
このような画面になっているはず。
![スクリーンショット 2021-08-18 17.51.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/15e6ec1a-096e-723d-bc97-b2a0fc001e36.png)

#解決方法
アップロード時のコマンドに「--acl bucket-owner-full-control」を追加する。

やってみた↓

```
aws s3api put-object --bucket 20210814cross-account-test --key storage-class/foo   --body test3 --acl bucket-owner-full-control
```


ダウンロードもできるように！
アクセス許可の画面も表示されるようになりました。
![スクリーンショット 2021-08-18 18.00.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/d7cd2265-9173-58e7-34c4-f3c98d30f8b6.png)


#注意事項
前提条件として、
S3のバケットポリシーの設定で「s3:PutObjectAcl」が許可されている必要がある。
（ここの権限がないと--aclオプションがつけられない）
![スクリーンショット 2021-08-18 18.08.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/9ec23583-0a13-6c90-11c0-53312ccb5dc4.png)


STSでIAMロールをAsuumeRoleしてあげるやり方もあるみたいなので
次はそれを試してみたいと思います。

#引用
https://aws.amazon.com/jp/premiumsupport/knowledge-center/s3-bucket-owner-access/

https://dev.classmethod.jp/articles/s3-cross-permission/
assertMatchesRegularExpression()で文字列にスラッシュが入ってる場合の対処

# はじめに

・`PHPUNITテスト`で文字列確認のテストを行う
・その文字列に`/`が含まれていて正常に動作しない状況である

# 対策

まず該当文字列がふくまれているかの確認は

`assertMatchesRegularExpression()`を使用する。

書き方は以下。

```php
$this->assertMatchesRegularExpression('/該当文字列を正規表現で表示/', $result);
```

該当文字列はデリミタに`スラッシュ`を使用する。

ここで問題はその該当文字列に`スラッシュ`やほかの記号が入る場合は,
エスケープさせるために`preg_quote()`を使用する。

```php
$this->assertMatchesRegularExpression('/' . preg_quote('23行目の列数(CSV:2列/正:3列)が正しくありません', '/') . '/', $result);
```

これで正常に確認が可能となる。
Macでウェブサーバーを構築する方法

Macでウェブサーバーを構築したい人向けに書きます。
やり方はとても簡単です。Linuxと対して設定方法が変わらないので結構楽にできます。
それではやっていきましょう。
※前提としてHomebrewがインストールされていることと、HomebrewパッケージのNGINX,CERTBOTがインストールされている必要があります。

# **ドメインを取得しよう**

まず最初にドメインを取得しなければ話になりません。ドメインはGMOのドメインレジスターを使うと
分かりやすく、やりやすいです。おすすめは、お名前.comです。このドメインレジストラーが一番お得に
ドメインを入手させてくれます。
https://onamae.com/
.xyz,.com,.netがおすすめです。私は.workを使っています。.workでもよいでしょう。.workはドメイン登録料が一円、更新費用が千円を切っているので私はこのドメインを使用しています。ドメインを取得出来たら、DNSを設定します。

# **DNSを設定しよう**

ドメインを取得し終わったら、ネームサーバーをお名前.comに変更します。そして、ネームサーバーの欄がお名前.comになっていればOKです。![スクリーンショット (34).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1807755/f55d6f4f-7fd8-f08c-afe8-07b84b2afc8c.png)

次にDNSを設定していきます。固定回線を契約していて、グローバルIPがある人はすぐに、設定できますが、固定回線がない人は少々面倒くさいやり方で、やる必要があります。ネームサーバーの設定の中のドメインのDNS設定を選びます。自分が取得した自宅ウェブサーバー用のドメインを選びます。「次へ」を押して、「DNSレコード設定を利用する」を選択します。
レコードタイプはA,TTLはデフォルトで十分、状態は有効にします。ホスト名は空にして、Valueのところに、自分のグローバルIPアドレスを入力します。
入力出来たら、一番右端の追加を押します。そして、一番下の「DNSレコード設定用ネームサーバー変更確認」のところにあるチェックボックスにチェックを入れてままにして、「確認画面に進む」クリックします。そして、「設定する」を押して、DNSを設定します。
そして、大抵は30分くらいで設定が完了します。設定が完了した通知がメールに来たことを確認したら、次にMacのターミナルを開きます。


# **ターミナルからドメインの設定をしよう**

ターミナルのコンソール画面を開き、 *sudo -s* を実行します。次にhostsを設定します。/etc/hostsを開いて、一番下の欄に、以下のように付け足してください。
/etc/hosts か /private/etc/hostsです。 hostsにドメインを登録することでこのMacでこのドメインを使用することができます。

```
##
# Host Database
#
# localhost is used to configure the loopback interface
# When the system is booting. Do not change this entry.
##
127.0.0.1        localhost
255.255.255.255  broadcasthost
::1              localhost

#ハッシュタグを使用するとコメントアウトができます。この下の欄に以下のものを追加します。

127.0.0.1   example.com
グローバルIPアドレス  example.com
```

example.comは自分の取得したドメイン名を使用してください。グローバルIPアドレスと書いた場所は自分のグローバルIPアドレスを入力してください。グローバルIPアドレスが不明な場合はこのサイトで調べてください。
https://www.cman.jp/network/support/go_access.cgi
次に、nginx.confを設定していきます。

# **nginxの設定をしよう**

ターミナルは開いたままで、nginx.confは */usr/local/etc/nginx/nginx.conf* にあります。
これに、書き込みを行います。
nginx.confのhttpsの最後の方に include servers/*となっているのでserversフォルダにリバースプロキシの設定などのファイルを書き込むことができます。

```
http {
 

  {省略}
  
  server {
           listen 80;
           server_name      localhost;
           #localhostの部分を取得したドメイン名に置き換えます。
           #Linuxと違って、わかりやすいと思います。下の方にはリバースプロキシの設定があったり、ドキュメントルートが書いてあったりします。
    {以下省略}
      }

{省略}
}
```

sudo nginxでnginxを起動します。 「nginxにネットワークの通信を許可しますか？」と聞かれるので許可を選択します。
ウェルノウンポートを使用するプログラムを実行するにはrootとして実行する必要があるので、sudo nginxでnginxをrootとして実行しています。
nginx -hで使い方が表示されるので、オプションはそれで参照してください。
うまくいけばこれでポート開放の確認を行うと、80/tcpが開いているはずです。

折角、ここまでやったのでSSLも設定したいですよね？SSLの設定方法を教えます。
参考させてもらったページ: https://neos21.net/blog/2019/03/11-01.html
とても分かりやすいです。
sudo certbotでcertbotを起動させます。メールアドレスを入力します。そのあとに同意するかどうか聞かれるので同意をします。agreeを選択してください。
そして、次にメールアドレスを公開するかどうかを聞かれているので、noを選択します。
次に、nginxを選びます。そして、そのあとは書いてある通りに進めてください。そうすると、SSL化ができます。
SSL succsessfulみたいに表示されたら、成功です。
nginxをリロードします。
sudo nginx -s reload
このオプションでリロードします。-sのsはsignalの略です。
これでSSLができたと思います。SSLができたか確認したい場合はポート開放確認ができるサイトを使用しましょう。sslのポートは443です。
http2を有効にしておくとよいです。nginx.confのhttpsのところに listen 443 ssl;になっているので、sslの後にhttp2をつけて、nginxをリロードするとhttp2が有効になります。
SSLの説明が分かりずらかったら、参考にさせてもらったページを見てください。

## **最後に**
ちゃんと、nginx,certbot,opensslやMacOS等はアップデートがあればアップデートをして最新版を使いましょう。
マイグレーションファイルは親テーブルから実行しないとエラーになる

##はじめに　　
ポートフォリオを作成するなかで、エラーになった箇所と解決方法を簡単にまとめました。
基本的な部分ですが、自分用のメモとして残しておきます。

##エラーの内容
```
PG::UndefinedTable: ERROR:  relation "モデル名" does not exist
```

rails db:migrateを実行したときに上記のようなエラーとなりました。

##結論
マイグレーションを実行した時に、親テーブル（外部キーを参照される側）から実行しなければならない。
今回の場合は、子テーブル（外部キーを参照する側）から実行してしまったで上記のエラーになってしまいました。

##解決法
###マイグレーションファイルを確認する

```
 Status   Migration ID    Migration Name
--------------------------------------------------
  down    2021xxxxxxxxxx  Create comments 【子テーブル】
  down    2021yyyyyyyyyy  Create documents
  down    2021zzzzzzzzzz  Create users 【親テーブル】
```

この場合、親テーブルである`users`テーブルと`documents`テーブルを先に実行する必要がある。

###マイグレーションファイルを一つずつ実行する
下記の通り、親テーブルを指定して実行する。

```
rails db:migrate:up VERSION=2021zzzzzzzzzz
```
親テーブルを実行出来たら、あとは`rails db:migrate`を実行すれば大丈夫です。

##おわりに
基礎的な内容でしたが、逐一エラーになって躓いた部分や理解したことはまとめていきたいと思います。
Eclipse 2021-06(4.20.0)でlombok 1.18.20適用時のエラー

# 環境
* java version "16" 2021-03-16

# 現象と対処方法
以下のエラーが発生してjavaのエディタが開けなくなる。

```java
java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @2b8bb184
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:357)
	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
```

とりあえずの対処方法は```eclipse.ini```に以下を追加する。

```java
--illegal-access=warn
--add-opens java.base/java.lang=ALL-UNNAMED
```

参考 https://github.com/projectlombok/lombok/issues/2882
react-hook-formでバリデーションする

#初めに
react-hook-formでユーザー登録のページを作ろうと思った時に、
SQLインジェクションなどのセキリュティの面でバリデーションを設けたいと思い、
react-hook-formに出会い、簡単に実装ができたので学習のためにoutputします。
#実装例

```react:sighup
<Input
  {...register("Name", {
    required: true,
    minLength: {
      value: 0,
      message: '名前を入力してください'
    },
    maxLength: {
      value: 15,
      message: '15文字以内で入力してください'
    },
    pattern: {
      value: /^[^^＾"”`‘'’<>＜＞_＿%$#＆％＄|￥]+$/,
      message: '特殊文字を使用しないでください'
    }
  })}
/>
{ errors.Name && errors.Name.message }
```

これは例なのですが、名前を入力するときに３つのバリデーションを設けました。
１名前を入力していないと「名前を入力して下さい」が出力される。
２名前が16文字以上だと「15文字以内で入力してください」が出力される。
３[^＾"”`‘'’<>＜＞_＿%$#＆％＄|￥]のいずれかが入力されていると「特殊文字を使用しないでください」が出力される。

それぞれminLengthやmaxLengthのvalueに違反すると、下の

```react:sighup
{ errors.Name && errors.Name.message }
```

の部分にエラーメッセージが出力される。
#おわりに
正規表現やコードが間違っている、などがありましたらお気軽にコメント等でお知らせ頂けると幸いです！
【12章】Javaを学ぼう

今回の記事では、クラスについて詳しく書いていきたいと思います。私自身のアウトプットの場になりますので、よろしくお願いいたします！

#クラスについて
クラスは、メソッドという小さな部品をまとめる、より大きな部品というようなイメージです。
下図では、MainクラスとPersonクラスの2つのクラスがあり、MainクラスのmainメソッドでPerson.hello()としています。このようにクラス名.メソッド名()とすることで、他のクラスのメソッドを呼び出すことができます。

```java:Main.java
class Main {
 public static void main(String[] args) {  
  Person.hello();
 //クラス名 メソッド名
 }
}
```

Personクラスのhelloメソッドを呼び出す↓

```java:Person.java
class Person {
 public static void hello() {  
  System.out.println("Hello");
 }
}
```

##クラスの定義について
```java:クラス名.java
class クラス名 {
 //ここにメソッドの定義
}
```

```java:Person.java
class Person {
 //ここにメソッドの定義
}
```


クラス名の**最初の文字は大文字**にすることに注意し、ファイル名は**「クラス名.java」**としなければなりません。

##Personクラスのメソッドを呼び出す
Mainクラスのmainメソッドから、Personクラスのメソッドを呼び出してみます。

```java:Main.java
class Main {
 public static void main(String[] args) {  
  String name = Person.fullName("John", "Connor"); //PersonクラスのfullNameメソッドを呼び出し
  System.out.println(name);
 }
}
```

PersonクラスのfullNameメソッドを呼び出す↓

```java:Person.java
class Person {
   .
   .
   .
 public static String fullName(String firstName, String lastName) {
  return firstName + " " + lastName;
 }
   .
   .
   .
}
```

出力結果↓

```java:コンソール
John Connor
```

以上がクラスを中心とした説明になります。次章では他人が作ったクラスを利用する外部ライブラリの利用について詳しく書いていきたいと思います。
よろしければご覧になってください！
最後までご覧いただきまして、ありがとうございました！
dockerでMySQLを複数起動する方法（Xプロトコル・ポート重複注意）

dockerコンテナで複数のMySQLを起動しようとすると、
何かと重複するので考慮してみた。

**Xプロトコルの存在を知った。**

# 重複が気になった部分

* image（イメージ名）
  * イメージができた時点で同じ名前になってしまう
  * 異なるプロジェクトで使うDBだと設定が異なるので別イメージにする必要あり
  * docker-composeを入れているディレクトリ名が同じだと同じイメージ名になってしまうので設定でイメージ名を指定する
* ports（ポート番号）
  * 通常使うポート番号3306以外にもXプロトコルのポート番号33060も重複する
* hostname（ホスト名）
  * ホスト名はもちろん重複すると困るので分ける

# docker-composeの例

```yml:1つ目
version: '3.1'
services:
  db:
    build: .
    image: mysql-kuma
    container_name: mysql-kuma
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: kumadb
      MYSQL_USER: develop
      MYSQL_PASSWORD: develop
      TZ: Asia/Tokyo
    ports:
      - 13306:3306
      - 13060:33060
    hostname: kuma
```

```yml:2つ目
version: '3.1'
services:
  db:
    build: .
    image: mysql-panda
    container_name: mysql-panda
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: pandadb
      MYSQL_USER: develop
      MYSQL_PASSWORD: develop
      TZ: Asia/Tokyo
    ports:
      - 23306:3306
      - 23060:33060
    hostname: kuma
```

# 参考

https://dev.mysql.com/doc/mysql-port-reference/en/mysql-ports-reference-tables.html
【11章】Javaを学ぼう

今回の記事では、戻り値を中心に書いていきたいと思います。私自身のアウトプットの場になりますので、よろしくお願いいたします！

#戻り値
メソッドの処理結果を、**メソッドの呼び出し元**で使いたい場合があります。このようなときは、メソッドが戻り値を返すようにします。

##メソッドの戻り値
メソッドの中で**return**を使うと、returnの値をメソッドの呼び出し元に返すことができます。また、戻り値があるメソッドは、戻り値の**データ型を指定**します。「public static void」のvoidの部分で指定します。

```java:Main.java
public static 戻り値のデータ型 メソッド名(引数) {                 
  return 戻り値;    //呼び出し元にデータを返す
}
```

```java:Main.java
public static int add(int x, int y) {                 
  return x + y;    //x + yが戻り値
}
```

上図のaddメソッドは、戻り値が整数なので「public static int ...」となります。
それではもう少し具体例に触れていきたいと思います。

```java:Main.java
class Main {
 public static void main(String[] args) {       
  int total = add(8, 4);   //add(8, 4)は12
  System.out.println(total);                                      
 }
 public static int add(int x, int y) {     
  return x + y;     //8+4の結果が戻り値になる
 }
}
```

出力結果↓

```java:コンソール
12
```

補足ですが、voidは戻り値がない、という意味になります。戻り値のない（returnがない）メソッドには、voidを指定します。

また、下図のように**同名のメソッド**は原則として定義できません。同じメソッドが複数存在すると、メソッドを呼び出したときにどのメソッドを用いればいいのか、コンピュータがわからなくなってしまうためです。

```java:Main.java
class Main {
 public static void main(String[] args) {       
  hello();   //エラーになる                                      
 }
 public static void hello() {     
  System.out.println("こんにちは");
 }                                 //同名のメソッド(hello())
 public static void hello() {     
  System.out.println("Hello");
 }
}
```

ただし、**引数の型や個数が違う場合は同名のメソッドを定義できます。**同名のメソッドがあっても、引数が違えばどれを呼べばいいのかコンピュータが判断できるためです。
同名のメソッドを定義することを**オーバーロード**と言います。

```java:Main.java
class Main {
 public static void main(String[] args) {       
  hello();        //引数がないhelloメソッド
  hello("Mia");   //String型の引数を持つhelloメソッド                                  
 }
 public static void hello() {     
  System.out.println("こんにちは");
 }                               
 public static void hello(String name) {     
  System.out.println("こんにちは" + name + "さん");
 }
}
```

出力結果↓

```java:コンソール
こんにちは
こんにちはMiaさん
```

#メソッドを組み合わせる
メソッドは、mainメソッド以外のメソッドから呼び出すことも可能です。
メソッドから他のメソッドを呼び出してみます。

```java:Main.java
class Main {
 public static void main(String[] args) {       
  System.out.println(average(3, 8));                                      
 }
 public static double average(int x, int y) { 
  int total = add(x, y);
  return(double)total / 2;
 }
 public static int add(int x, int y) {
  return x + y;   
 }
}
```

averageメソッドは平均を求めるメソッドです。aとbの平均は「(a + b) / 2」で求められますが、足し算の部分はaddメソッドを利用しています。

##真偽値の戻り値
真偽値のデータ型はbooleanなので、メソッド定義は下図のようになります。

```java:Main.java
public static boolean isEven(int x) {                 
  return x % 2 == 0;  //偶数であればtrue
}
```
isEvenメソッドは引数の値が偶数かどうかを調べ、偶数であればtrue、奇数であればfalseを返します。
isEvenメソッドをもう少し具体的に利用してみます。

```java:Main.java
class Main {
 public static void main(String[] args) {  
  int number = 7;
  if(isEven(number)) {    
   System.out.println(number + "は偶数です");                                      
  } else {
   System.out.println(number + "は奇数です");
  }
 }
 public static boolean isEven(int x) { 
  return x % 2 == 0;
 }
}
```

出力結果↓

```java:コンソール
7は奇数です
```

以上が戻り値を中心とした説明になります。次章ではクラスについて詳しく書いていきたいと思います。
よろしければご覧になってください！
最後までご覧いただきまして、ありがとうございました！
SpringBootアプリケーション(Jar)をCentOS7にデプロイ

# はじめに
SpringBootは実行可能ファイルとして jar 形式と war 形式の2種類のファイルを作成できます。
jar 形式はTomcatが組み込まれており、単体で実行可能です。
war 形式はTomcatがインストールされた環境にデプロイし、実行する必要があります。
今回はjarファイルをCentOS7にデプロイする手順を記載します。

# 前提

### 開発環境
IDE：eclipse(4.15.0)
Java：11
ビルドツール：Maven

### サーバー環境
OS：CentOS7（仮想マシン）
Java：11
Apache：2.4.6

# Jarファイル作成
プロジェクト上で右クリック > [実行] > [Maven install] を選択します。
完了後、[プロジェクトフォルダ] > [target]に「XXX.jar」ファイルが作成されます。
※ここではプロジェクト名「demo」のjarファイル作成
![jar作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798422/8cd53681-ab69-1e73-a6f9-4218e9ec37fe.png)

# Apache設定
ここでは2つの設定を行います。
1. プロキシ有効化
2. リバースプロキシ設定

### プロキシ有効化
Apacheのプロキシを有効にするには mod_proxy モジュールが有効になっている必要があります。
以下の手順で確認します。
まず、サーバー側の「/etc/httpd/conf/httpd.conf」を開きます。
Tera Termなどでコマンドを実行し、以下を確認してください。

```:httpd.conf
$ cat /etc/httpd/conf/httpd.conf
(中略)
Include conf.modules.d/*.conf
(中略)
```
「conf.modules.d」以下の「.conf」ファイルを読み込みしています。
次に、「/etc/httpd/conf.modules.d/00-proxy.conf」を開きます。

```:httpd.conf
$ cat /etc/httpd/conf.modules.d/00-proxy.conf
(中略)
LoadModule proxy_module modules/mod_proxy.so
(中略)
```

「mod_proxy」がロードされていることが確認できればオッケーです。

### リバースプロキシ設定
「/etc/httpd/conf.d」以下に任意の名前の設定ファイルを追加します。
ここでは「httpd-proxy.conf」とします。
以下のように記載してください。

```:httpd-proxy.conf
ProxyPreserveHost On
ProxyRequests Off
<Proxy *>
 Require all granted
</Proxy>
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
```

Apacheの再起動をします。

```:再起動
# service httpd restart
```

# デプロイ
jarファイルをサーバーにアップロードします。
任意のディレクトリにファイルをアップロードしてください。
※ここでは「/opt/bin」にアップロードすることとします。

```:アップロード
// ホストマシン側でコマンドを実行する
$ scp [jarファイルパス][ユーザー名]@[アップロード先IPアドレス]:[アップロード先パス]

（例）
$ scp C:\eclipse\workspace\demo\target\demo-0.0.1-SNAPSHOT.jar root@192.168.34.11:/opt/bin
```

# 起動
以下のコマンドでjarを起動します。

```:起動
// サーバー側でコマンド実行する
java -jar [jarファイルパス]

（例）
java -jar /opt/bin/demo-0.0.1-SNAPSHOT.jar
```

起動したら、ホストマシンのブラウザから以下のURLにアクセスしてください。
URL：http://localhost:8080/
【3STEP】最も簡単なWindows上のLinux開発環境(WSL2+VSCode)構築手順

# 説明
Ubuntu上で動いているVisual Studio Code(以下、VSCode)のように開発が行えるようになります。
そのため、開発中、パーミッションや文字コード、改行コードなどにより悩まされることがなくなります。
最も綺麗に少ない手数で環境構築できることを目指して書きました。

# 構築手順
## STEP1
[VSCode](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)に、「[Remote-WSL](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl)」という拡張機能をインストールしてVSCodeを閉じましょう。

## STEP2

PowerShellから下記コマンドで、Ubuntuをインストールしましょう。

```
wsl --install -d Ubuntu
```

## STEP3

Ubuntuが開くので、そこから以下のコマンドでVSCodeを開きましょう。

```
code .
```
これにより、VSCodeとUbuntuが接続され、次回以降はWindows上から開いてもUbuntuに接続されています。

接続中はVSCodeの左下に下の画像のような表示が出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153437/e47260d7-e0d7-6763-e96f-d5ba05c894ba.png)


あとは好きにしましょう。

# おまけ

以下はおまけです。

## 追加でやっておくとよいこと
### Ubuntuアップデート
Ubuntuをアップデートしましょう。

```
sudo apt update
sudo apt upgrade
```

### Docker導入
Dockerを導入しましょう。

:::note warn
WSL統合機能を使うことによりWindows上にインストールしたDockerをUbuntu上から利用できるため、UbuntuにDockerを入れる必要はありません。
:::

[Docker Desktop](https://www.docker.com/products/docker-desktop)をダウンロードしてインストールし、起動後、設定からResources > WSL Integrationを選び、Ubuntuを有効にしましょう。
このままだとDockerコマンドがUbuntuから使えないので、コマンドプロンプトかPowerShellから以下のコマンドでUbuntuを再起動しましょう。

```
wsl -t Ubuntu
```

以下のVSCode拡張機能を導入しておけば、コンテナに対する操作や確認などがVSCode上で簡単にできるようになります。

[Docker extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker)

## 開発上気を付けた方がよいこと
### 開発コードを置く場所
Windowsと共有している領域にファイルを置くとアクセスが遅いので置かないほうがいいです。
🙅 /mnt/c配下

以下のようなパスにcloneなどしましょう。
🙆 /home配下など

### Node.js 14系(LTS)を導入
Ubuntuにデフォルトで入る10系はサポートが終了しているため、node.jsを入れる場合は14系を入れましょう。

```
sudo curl -sL https://deb.nodesource.com/setup_14.x | sudo bash -
sudo apt install nodejs
```
​
## 予備知識
### WindowsからUbuntu上のファイルへアクセスしたい
​
エクスプローラから下記のパスを開くことでアクセスできます。

```
¥¥wsl$¥Ubuntu
```

が、ファイルへのアクセスは極力VSCode上から行った方が余計なトラブルが少ないと思います。

### WSLがメモリを思いっきり消費して困る

デフォルトでは、8GBか、搭載メモリの50%の少ない方のメモリ使用量が適用されます。

メモリ使用量に制限を設けたい場合は、下記のファイルを作成しましょう。

```
%USERPROFILE%¥.wsconfig
```

下記の通り、記述しましょう。
例：4GBに制限したい場合

```
[wsl2]
memory=4GB
```

設定を有効にするためにWSLを再起動します。

```
wsl --shutdown
```


### localhostForwardingが効かない

本来、localhostFowardingはデフォルトで有効になっており、ディストロ上でlistenしたポートはlocalhostでアクセスできますが、PCを再起動したタイミングなどでこの機能が効かなくなることがあります。
おそらくバグだと思うのですが、WSLを再起動することで直るのでそういう時は再起動を試みてください。

```
wsl --shutdown
```

また、この問題はWindowsの高速スタートアップを無効化することによって恒久的に解決できます。
Homebrewでインストールした git svn で Can't locate SVN/Core.pm となるのをサクッと解決する

### 1. シェル変数を設定する

```
$ PERL_VERSION=`ls /usr/local/lib/perl5/site_perl`
$ GIT_VERSION=`ls /usr/local/Cellar/git`
```

### 2. SVN/Core.pmなどのperlモジュールの場所を設定する

```
ln -sf \
/usr/local/lib/perl5/site_perl/${PERL_VERSION}darwin-thread-multi-2level/SVN \
/usr/local/Cellar/git/${GIT_VERSION}share/perl5
```
```
ln -sf \
/usr/local/lib/perl5/site_perl/${PERL_VERSION}darwin-thread-multi-2level/auto \
/usr/local/Cellar/git/${GIT_VERSION}share/perl5
```

### 完了

```
$ git svn --version
git-svn version 2.33.0 (svn 1.14.1)
```
【MotionBoard】日付グループ項目の基礎

MotionBoardの日付グループ項目の基本的な使い方の解説です。


#日付グループ項目とは
日付グループ項目とは、日付データを持つ対象項目を年度別、半期別、週別などにグループ化する項目です。
Salesforceのレポートとの違いを言うと（私はMotionBoardのClooud for Salesforceを使用しているので）、
Salesforceレポートは日付項目自体を年度や年月の形式に変換している感じですが、
MotionBoardの日付グループ項目は、対象の日付項目を『どういう形式でグルーピングするか』という設定を"新しく"作成する感じです。
なので、ひとつの日付項目に対して、年度単位のグルーピングも年月単位のグルーピングもいくらでも作れちゃいます。
Salesforceレポートと比べれば、便利。


#基本的な使い方
データソースエディタの「追加項目作成」から「日付グループ項目」を選択します。
「対象項目」で、グルーピングしたい日付項目を選択します。

もしグルーピングしたい項目が日付のデータ型ではなくても、読込フォーマットで指定すれば日付の形に変換してくれます。

「表示フォーマット」に、グルーピングしたい形式を入力します。
はい、ここは完全に手動入力です。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/ec70a8f2-c639-15bc-6c2c-8b75ce10f749.png)

初心は一回ここで挫折するね！（by 挫折した人）
表示フォーマットの「？」マークから入力パターンが確認できます。
上の「テンプレート」で入れることもできますが、年度以外はあんまり使わないかな。。

私が良く使う表示フォーマットはこんな感じ。
年度　：　yyyy年度　（これはテンプレートの年度と同じ）
年月　：　yyyy/MM
月　　：　MM月
半期　：　NNN期　（NNNはこの後説明します）

#注意その１．
表示フォーマットの下に「年初日」があります。
これが「月：1」だと「年の初月＝１月」という設定になります。
表示フォーマットで年度の設定をする場合、4月が年度の始まりの場合は「月」を4にする必要があります。
企業によって年度の始まり月は異なるかと思うので、1月の場合は1のままで良いですし、9月の場合は9にする必要があります。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/15388f13-f695-5fdb-4610-6694e6138266.png)



#注意その２．
「上期」「下期」みたいな分け方をしたいときは、置換文字列であるNNNを使用します。
設定方法はこんな感じ。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658354/b960327c-6071-4a9e-dbf0-7819b0051be3.png)



グルーピング内容が設定できたら、画面左の「項目名」を設定します。
このグルーピング項目の名前です。

これを入れればあとは「OK」で設定完了です。

ここで、注意２のように置換文字列を設定していない場合は、「置換文字列が未設定です！」と注意文が流れます。
びびる。最初びびった。

勇気を振り絞って「OK」を押しましょう。

これで日付グループ項目の完成です！
お疲れさまでした。
基本情報技術者　ネットワーク編③

#初めに
[前回](https://qiita.com/reo0612/items/d60891b9a84b04892054)の続きです。

#ネットワークを構成する装置
最もシンプルなネットワークは、コンピュータ同士をケーブルで直結しているものです。
ですがこれでは、計2台のネットワークしか構築できません。

もっと沢山のコンピュータに繋げたい場合は`ハブ`という機器を使わないといけませんし
インターネットに繋げたい場合は`ルータ`という機器が必要になります。

このように様々な機器を用いることでネットワークを構成することができます。

#OSI基本参照モデルとの関係
先ほど出てきたハブやルータなどの機器は
OSI基本参照モデルの各階層に振り分けることが出来ます。
![OSI基本参照モデル.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/2bb0aecd-efd3-0e7f-0e1b-b29ea1a4b4ea.jpeg)
※[第10回　OSI基本参照モデル――7階層による道案内で，データを迷わせない](https://xtech.nikkei.com/it/article/COLUMN/20070914/281963/) 参照

###◯第1層 物理層
####・LANケーブル
LANを構築するためのケーブルで、ハブやルータに接続するために用いられます。

####・NIC(Network Interface Card)
コンピュータをネットワークに接続するための拡張カードで`LANボード`とも呼ばれます。

最近では基本パーツの中にNICの機能が含まれており
LANケーブルを接続すればOKというものが多くなってきています。

役割としては、データを電気信号に変換してケーブル上に流したり、それを受け取ったりします。
つまり、`コンピュータがネットワークでやり取りするためには必要不可欠`です。

NICをはじめとするネットワーク機器には
製造段階で`MACアドレス`という番号が割り振られています。

これはIEEE(米国電気電子技術者協会)によって管理される製造メーカー番号と、自社製品に割り振る製造番号の組み合わせで出来ており、`世界中で重複しない番号として保証されています`。

イーサネットでは、このMACアドレスを使って各機器を識別しています。

####・リピータ
一方のケーブルから流れてきた電気信号を単純にもう一方のケーブルに送り出すという機器で
流れている`電気信号を増幅`し、LANの総延長距離を伸ばします。

LANの規格では、10BASE5や10BASE-Tなどの方式ごとに総延長距離が定められており
それ以上の距離で通信すると信号が歪んでしまってまともに通信できません。

ですが、リピータを間に挟むことによって、この信号を整形して送ってくれます。
結果、信号の歪みを解消することができる訳です。

しかし、パケットの中身を確認せず、ただ電気信号を増幅するだけなので宛先関係なく送信してしまいます。

現在では単体の製品はなく、ハブに置き換わりました。

####・ハブ
差込口(ポート)を複数持つコンピュータやプリンタなどのケーブルを集線する機器です。

LANの接続形態(トポロジー)のスター型で使われ、複数の端末のケーブルを一ヶ所に集約することが出来ます。

コンセントが沢山付いている延長コードみたいな感じですね。

内部にリピータを複数束ねている`リピータハブ`と
後述するブリッジという機器を複数束ねた`スイッチングハブ`の2種類があります。

リピータハブは、パケットが流れてくると`無条件に全ての差込口(ポート)`に流しますが
対して、スイッチングハブは`宛先のMACアドレスに該当する差込口(ポート)`にだけ流します。

###◯第2層 データリンク層
###・ブリッジ
リピータと同様に２つの差込口(ポート)があり、`MACアドレスを学習します`。

そして、宛先のMACアドレスを持つ機器がどの差込口(ポート)にあるかを判断し、データをその機器に送ることができます。

###◯第3層 ネットワーク層
####・ルータ
異なるネットワーク(LAN)同士の中継役として、流れてきたパケットのIPアドレス(コンピュータの住所)情報を確認した後、最適な経路へと送ります。

ブリッジと似ていますが、ブリッジはあくまで`MACアドレスが確認できる範囲内`で異なるLAN宛にデータは送れません。

ですがルータはパケットに付与されているIPアドレスを確認し、ルータ自身が持つ`経路表(ルーティングテーブル)`と照らし合わせて最適な転送先を選びます。

このことを`経路選択(ルーティング)`と呼びます。

ですがインターネットのように、接続されているネットワークが膨大な数となる場合には
直接、相手のネットワークに転送するのはまず不可能です。

なので、ルータ同士が`バケツリレーのようにパケットの転送を繰り返し、目的地へと運びます`。

現実世界で例えると、郵便みたいな感じですね。

郵便ポストに手紙を入れたら、市の集配所に届けられます。
そこから県の配送センターで仕分けされ、宛先に先ほどの逆の手順で目的地へと送られます。

ルータの役割は、それぞれの地域(LAN)を担当する郵便局みたいなものです。

###◯第4層以上
####・ゲートウェイ
携帯のメールとインターネットの電子メールは互いにやり取り出来ません。

それは`プロトコル(ネットワークを通じてコンピュータ同士がやり取りするための約束事)が違うから`です。

ですが、私も含めてみんな当たり前にやり取り出来ていますよね。
それはゲートウェイが`異なるプロトコル間に位置して変換しているから`です。

翻訳家みたいな役割を担っています。

基本的には、第4層(トランスポート層)以上の変換をしていますが
必要であれば全階層を変換することもあります。

#おわりに
今日はここまでです。

間違っている部分や気になるところがあればコメントして下さい。