OmniAICreator/Qiita-1.07M huggingface dataset:
ASP.NET CoreでWeb開発～環境構築からHello World～

## はじめに
### なぜ今ASP.NET CoreでWeb開発なのか
これまでC#, ASPと言えばWindows OS(Azure)で動作させる製品のイメージでした。
しかし近年(2016~) .NETは、.NET Coreへ以降しつつあり、その際下記の大きな変化が見られました。

<dl>
  <dt>オープンソース化</dt>
  <dd>リリース当初からGithubで公開された</dd>
  <dt>クロスプラットフォーム</dt>
  <dd>Windows OSはもちろん、LinuxやMacOSもサポートされた</dd>
</dl>
これを機にC#でのWeb開発が広く普及していくと考えられます。

### 本記事のスコープ

* .NET Coreのインストール
* HelloWoldプロジェクト作成・実行

## .NET Coreのインストール
１．[MicroSoftのダウンロードページ](https://dotnet.microsoft.com/download)を開く
２．[Download .NET Core SDK]を選択し、インストーラをダウンロードする
３．インストーラを実行する
４．[インストール]を押下する(画像赤枠)
５．インストール完了まで待機
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463879/17f0a7aa-03ce-8ba7-dfe5-83eb76fdfb6f.png)


## HelloWoldプロジェクト作成・実行
### プロジェクト作成
※本記事ではVisual Studioのセットアップをスコープ対象外としております。
かなり多くの方が記事にしているので、セットアップされてない方は他記事を参考にしてください。

１．Visual Studioを開く
２．[新しいプロジェクトを作成]を選択する
![b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463879/ee1e088b-0fd6-2d3c-fa57-32f8691f6f49.png)
３．[ASP.NET Core Webアプリケーション]を選択する
※選択肢にない場合は、Visual Studioインストーラで[ASP.NETとWeb開発]をインストールしましょう。
![c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463879/c9809314-745d-bd04-05ed-1bfe84bedc93.png)
４．任意のプロジェクト名を設定し[作成]を選択する
![d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463879/6ffafd16-5d70-7dd9-9217-1bf2a6270fd3.png)
５．アプリの種別を選択する、今回はHello Worldなので[空]を選択する
![e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463879/15916f50-0db4-7f63-a083-8ba195644285.png)
６．Visual StudioのEditorが開かれれば、プロジェクトの作成完了

### Hellow World実行
１．Visual Studio上で[▶IIS Express]を選択する
![f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463879/693d2e3a-abec-15db-7a4d-5b4f9135b8db.png)
２．デフォルトのソースでSSLを使用するよう実装されているため、[はい]を選択して自動生成される自己証明書を信頼する
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463879/fdf33d6a-cb5c-e0c7-3c13-4c412d36f65b.png)
３．[はい]を選択し、自動生成されたオレオレ証明書のインストールを行う
※発行者がご自身で開発中のアプリである事をしっかりと確認の上、自己責任で実施して下さい。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463879/5259b042-89a1-952e-2361-54ac1630d7d8.png)
４．自動で開かれるブラウザ上でHello Worldが開かれたら成功
![j.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463879/6838dab7-960b-db5f-1b97-b44858a80d46.png)

## おわりに
今回は導入であるHello Worldでした。
次回から多くのフレームワークで採用されているMVCアプリケーションを作成したいと思います。
[rails]deviseでのログイン画面実装

#deviseでのログイン画面実装

1.Gemfileに「gem 'devise'」を追加

```
gem 'devise'
```

2.追加したdeviseを、アプリケーションに読み込ませる。
※gemを追加した時に忘れてはいけない

```
$ bundle install
```

3.deviseの初期設定

```
$ rails g devise:install
```

これでdeviseを使う準備は完了。

4.Userモデルとマイグレーションファイルを作成
rails g devise モデル名の記述は、devise独自のルールです。

```
$ rails g devise User
```

5.データベースへ反映
新しくUserテーブルをデータベースへ反映させます。

```
$ rails db:migrate
```

6.deivse用のログイン画面を作成

```
$ rails g devise:views
```

7.rails s -b 0.0.0.0でサーバー起動させ、画面確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/681053/e3c58ad2-8a8c-560d-4a08-db1845bc50d0.png)
bxsliderでリンクが効かなくなった時の対処法

jQueryプラグイン「bxslider」でリンクが効かなくなるという現象に遭遇したので対処法を探してみました。
すでにいくつか対応されている記事を拝見しましたが、スマートフォンとタブレットではスワイプ機能は使えるように調整をしてみました。

## 原因
Chromeの仕様変更により、スライダーのスワイプやドラッグ操作でスライドを切り替える機能が原因のようです。
（確認の際は運よくリンク先に遷移したので最初は気付きませんでした...）

## すぐできる対処法

bxsliderのオプションの中にある

```javascript:bxsliderオプション
touchEnabled: false
```

を追記すると解消できました。
この「**touchEnabled**」オプションは、スワイプ（フリック）時にスライドを移動させるためのオプションです。


## スマホとタブレットで見る時はtouchEnabledをtrueにする
先のtouchEnabledオプションをfalseのままだとスマホ・タブレットで見た時スワイプができなくなります。
スマートフォン・タブレットでスワイプできないと、ページャーやナビゲーションボタンをタップすることになります。
そうなると特にスマートフォンで見る時に、おそらく小さいボタンをタップすることになりますし、ユーザーにとってストレスになる可能性があります。
タッチデバイスではスワイプでスライドを移動できるように、[@mitsuhiro_Kさん](https://qiita.com/mitsuhiro_K)の対処法を元に少し変えて対処しました。
[bxSliderがクリック出来なくなった時の応急処置](https://qiita.com/mitsuhiro_K/items/66fb985ec9a6eb277dbb)

```javascript

$(function(){
  let bxSliderConfig = {
    //使用しているサイトにあったオプション,
    touchEnabled: false
  };

  let ua = navigator.userAgent;
  let sp = ua.indexOf('iPhone') > -1 || (ua.indexOf('Android') > -1 && ua.indexOf('Mobile') > -1); // スマートフォン
  let tab = ua.indexOf('iPad') > -1 ||(ua.indexOf('Macintosh') > -1 && 'ontouchend' in document) || ua.indexOf('Android') > -1; // タブレット

  // スマートフォンまたはタブレットの場合にtouchEnabledをtrueにする
  if (sp || tab) {
    bxSliderConfig.touchEnabled = true;
  }

  let slide = $('#slider ul').bxSlider(bxSliderConfig);
});

```

#### 他参考サイト
[bxSlider をつかったスライダーのリンクが機能しないときの対処方法](https://www.powercms.jp/blog/2019/07/bxslider.html)
[bxSliderのスライド内のリンクが効かなくなった際の対処方](https://kaminarimagazine.com/web/2019/03/29/bxslider%E3%81%AE%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E5%86%85%E3%81%AE%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%8C%E5%8A%B9%E3%81%8B%E3%81%AA%E3%81%8F%E3%81%AA%E3%81%A3%E3%81%9F%E9%9A%9B%E3%81%AE%E5%AF%BE/)
[]()

#### bxsliderオプション参考サイト
[オプションで自分好みにカスタマイズ！bxsliderの使い方](http://y-plan.jp/1058)
【Java】JDK 13のSwitch Expressions (Preview)を見てみましょう

# OpenJDK 13の5つの重要機能
> 
350:	Dynamic CDS Archives
351:	ZGC: Uncommit Unused Memory
353:	Reimplement the Legacy Socket API
354:	Switch Expressions (Preview)
355:	Text Blocks (Preview)

上記の中でも本日は「Switch Expressions (Preview)」を見ていきたいと思います。

# Switch Expressions (Preview)
- JDK 12でもPreviewでしたか13でもPreviewですね。
- Previewなので--enable-previewのオプションを与えないと使えないらしいです。

### ・Arrow labels

```java

static void howMany(int k) {
    switch (k) {
        case 1  -> System.out.println("one");
        case 2  -> System.out.println("two");
        default -> System.out.println("many");
    }
}
```
従来の「case L：」をよく使用していましたが、「case L->」のようにも使えるようになりました。
ただ、「case L->」のような書き方をするとfull throughがないためbreakを書かなくてもよいらしいです。

##### 呼び出すときは以下となります。
```java

howMany(1);
howMany(2);
howMany(3);
```
##### 結果
```java

one
two
many
```
### ・Switch expressions

switchがexpressionで使えるようになりました。

```java

static void howMany(int k) {
    System.out.println(
        switch (k) {
            case  1 -> "one"
            case  2 -> "two"
            default -> "many"
        }
    );
}
```

なので、switch文の結果を変数に代入することもできます。

```java

T result = switch (arg) {
    case L1 -> e1;
    case L2 -> e2;
    default -> e3;
};
```
### ・Yielding a value

「yield」キーワードが追加されました。

```java

int j = switch (day) {
    case MONDAY  -> 0;
    case TUESDAY -> 1;
    default      -> {
        int k = day.toString().length();
        int result = f(k);
        yield result; // switch文の戻り値を設定
    }
};
```

「yield」は"case L:"式のswitch文の中でも使用できます。 

```java

int result = switch (s) {
    case "Foo": 
        yield 1;
    case "Bar":
        yield 2;
    default:
        System.out.println("Neither Foo nor Bar, hmmm...");
        yield 0;
};
```


# 参考
- https://openjdk.java.net/projects/jdk/13/
- https://openjdk.java.net/jeps/354
- https://johngrib.github.io/wiki/jdk13/
[データベース]データ型種類

#データ型の種類
データベースにデータを保存する場合、データの形式を理解しておく必要があります。
このようなデータ形式のことを、「データ型」といいます。
代表的なデータ型には、以下のようなものがあります。

| データ型 | 種類 |
|:--|:--|
| integer | 数値（整数） |
| decimal | 数値（精度の高い小数） |
| float | 数値（浮動小数） |
| string | 文字（短い文字列） |
| text | 文字（長い文字列） |
| date | 日付 |
| datetime | 日時 |
| time | 時刻 |
| timestamp | タイムスタンプ |
| binary | バイナリ |
| boolean | 真偽 |

まだまだ、初心者なのでなんとも言えませんが、
「integer」「string」「text」を使うことが多いと思います。
Ubuntu20.04にdropboxをインストールして実行

※　この記事は個人で実行してみた際にうまく行った方法を記しただけで、検証・考察して得た方法ではありません。
※　ほとんど以下の公式サイトに書いてあるとおりです。
https://www.dropbox.com/install-linux


# 手順
## 1. インストール

以下のコマンドを実行してインストール

```
cd ~ && wget -O - "https://www.dropbox.com/download?plat=lnx.x86_64" | tar xzf -
```


## 2. ログイン、登録
以下のコマンドを実行してDropboxデーモンを起動

```
~/.dropbox-dist/dropboxd
```

*サーバーで初めて Dropbox を実行する場合、使用中のブラウザでリンクをコピーして貼り付けて新規アカウントを作成するか、既存のアカウントとサーバーを連携させるように指示が表示されます。その後、Dropbox フォルダがホーム ディレクトリに作成されます。（上記公式HPより）*

作成された~/Dropboxにファイルを入れると同期されるようになる。
上記プログラムを終了してしまうと、自動同期されないので以下のプログラムの実行などが必要


## 3. 同期させるためのプログラムの実行

公式サイト（以下URL）の下部から"Pythonスクリプト"をダウンロードする
https://www.dropbox.com/install-linux

ダウンロードしたpythonプログラムを実行

```
python3 dropbox.py start
```
これで自動で同期されるようになる。
**python2だとそのままでは実行できない点に注意。**
健康応援システムーDB知識－午後

応用情報技術者令和元年秋期 午後問6

１、E-R図のエンティティ間関連と属性名
注意点：
　①属性名の実線、破線が忘れないように。
　②矢印は、例え、上下の矢印だと、「↓、↑」　で表示、左右の矢印だと、「→、←」で表示

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/f96a0153-f6a9-9914-e4d0-179d4c2a1f21.png)

答え：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/6240dd11-63fd-62c4-fd0c-fb5e4136da53.png)

２、SQLに適切な字句
注意点：
　①変数の使用。例え、「：レポート年月」は集計する対象年月を格納する埋め込み変数ので、
　　Select　従業員番号,：レポート年月　From　従業員　は正
　　Select　従業員番号,TOYM（システム日付）　From　従業員　は　**誤**

　②総歩数は、SUM(歩数.歩数)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/05f24d38-0870-135e-4ca8-b703505aef53.png)


３、不具合

当該質問には、不具合は
①睡眠終了日時がNULL
②従業員番号＋測定日　が重複　※みにくいですね。

言い換えて、下記２つパターン：
①就寝中にリストバイドが外れてしまい睡眠終了日時が取得できない
②１日２件以上睡眠データを取得する


修正の方法は、
①は、月次レポート作成機能を修正
②は、睡眠テーブルの主キーを"従業員番号、睡眠開始日時"に変更


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/eb316dc2-9871-b6c1-de56-974c461056d6.png)
リストを作る時に使うタグ

###リストを作る時に使うタグ
今回は、リストを作る時に使うタグをまとめていく。

##liタグ

liタグを使うことによってその文字列をリスト化することができる。
親要素である、ulタグやolタグで囲むことによって様々な形にできる。

##ulタグ
ulタグでliタグを囲うことによって、中のliリストが全て同じ箇条書きで表示される。

##olタグ
olタグでliタグを囲うことによって、数字の優先順位がついたリストで表示される。

##dlタグ
dlタグは、その中が定義型リストであるということを示す。
主に、見出しと文章などがあるリストはこのタグを使う。

##dtタグ
dtタグは、dlタグの中の見出しを作る時に使うタグである。

##ddタグ
ddタグは、dtタグで記述したものに説明を加えたりする時に使うタグである。
dtタグの下に記述され、少しインデントがあく。
[rails]Strong Parametersとは？

#Strong Parametersとは
Strong ParametersはRails4系から追加されたセキュリティを向上させるための仕組みです。
指定した値以外は受け取らないようにして、攻撃者による意図しないコードの実行を防止するセキュリティ対策。

フォームからデータを送信するときは、「マスアサインメント脆弱性」というセキュリティ上の問題があります。
簡単に伝えると、データ送信時に不正なリクエストによって、予期しない値が変更されてしまう脆弱性です。
Railsでは、この脆弱性を防ぐ「Strong Parameters」の仕組みが用意されています。

こんな感じです。
Strong parametersは必ずprivateより下に記述します。

```app/controller/user_controller.rb
class UsersController < ApplicationController
  def create
    user = User.new(user_params)
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end
end
```

簡単に言うと、userに関する値（パラメーター）が送信されても「name」「email」しか許可しませんよということです。
Pyhonを使ったTwitterの簡単なbot作成

#はじめに
この記事では, pythonの実行コマンドがTwiiterに反映される方法を紹介します. 

いわば導入編なので, 良かったら見て行ってください. 

#TwitterのAPIを利用する
まずはTwitterのAPIを使えるように, アカウント登録が必要です. 
下記のURLクリックしてみてください. 
https://developer.twitter.com/en/apps

英語で答える箇所がありますが, そこはGoogle翻訳に任せてみても良いかと思います. 

#ライブラリのインストール
下記のコマンドを実行すると必要なライブラリがインストールされます. 

```
pip install requests requests-oauthlib
```

#ファイルの準備
下記のファイルを準備してください. 

```
file
├── config.py #認証情報を管理
├── xxx.py #各スクリプト
└── ...
```

config.pyは, 先ほど登録したTwitterのApplication Managementからトークンを生成してください. 

```
#config.py
CONSUMER_KEY = "**************"
CONSUMER_SECRET = "**************"
ACCESS_TOKEN = "**************"
ACCESS_TOKEN_SECRET = "**************"
```
#プログラムからツイートしてみよう！
ここまで, 登録できたら後はプログラムを実行するだけです. 

```
#tweet_form_python.py

import json, config #標準のjsonモジュールとconfig.pyの読み込み
from requests_oauthlib import OAuth1Session #OAuthのライブラリの読み込み

CK = config.CONSUMER_KEY
CS = config.CONSUMER_SECRET
AT = config.ACCESS_TOKEN
ATS = config.ACCESS_TOKEN_SECRET
twitter = OAuth1Session(CK, CS, AT, ATS) #認証処理

url = "https://api.twitter.com/1.1/statuses/update.json" #ツイートポストエンドポイント

print("内容を入力してください。")
tweet = input('>> ') #キーボード入力の取得
print('*******************************************')

params = {"status" : tweet}

res = twitter.post(url, params = params) #post送信

if res.status_code == 200: #正常投稿出来た場合
    print("Success.")
else: #正常投稿出来なかった場合
    print("Failed. : %d"% res.status_code)
```

上記のプログラムを実行すると下記の出力結果が得られます. 

```
内容を入力してください。
>> tweet from python
***************************************
success
```

以上です. 
プログラムは実行できましたかね！？

他のコマンドを試したい場合は, 下記のサイトをご参考ください. 
https://maxmaruone.com/2020/05/10/twitter%e3%81%aeapi%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6bot%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%81%bf%e3%81%9f%ef%bc%81%e3%80%80%e5%b0%8e%e5%85%a5%e7%b7%a8/
GMT5覚え書き

# 基本情報

ハワイ大学のホームページ。大抵のことは書いてある。

http://gmt.soest.hawaii.edu/projects/gmt/

こちらも便利なページ

https://sites.google.com/site/classaofd/Home/ex1/tebiki/02

# カラーパレット

標準カラーパレットのサンプル

http://www.hysk.sakura.ne.jp/Linux_tips/GMT_img_script/makecpt_20131206.png

#環境設定

コマンドラインで`gmtdefaults`と打つと設定項目がずらずら出てくる。変更したい場合は、

```bash:*.gmt
gmt gmtset TIME_EPOCH = 1970-01-01T00:00:00
```

などとすれば自由にカスタマイズできる。

特定のgmtコマンドのみに適用したい場合は、

```bash:*.gmt
gmt psxy --FONT_ANNOT_PRIMARY=12p
```

といったようにオプションをつければよい。
特定の軸だけ色やフォントを変えるのに便利！

# いらない空白領域の削除

`psconvert`で画像ファイル形式の変換と同時にできる

```bash:*.gmt
gmt psconvert [filename].eps -Tg -A -P
# -T: ファイル形式の指定 (gでpng)
# -A: いらない領域の削除
# -P: 画像の回転
 ```

# -Bオプションの情報

GMTで一番ややこしいオプション

以下のページが便利

日本語 : https://estuarine.jp/2017/11/gmt-5-map-frame-b/

英語 : http://gmt.soest.hawaii.edu/doc/5.4.4/psbasemap.html
composerでNetCommons3開発用インストール

NetCommons3はプラグインがそれぞれ別リポジトリに別れてるので、NetCommons3本体だけgit cloneしても動きません。

そこで、開発用に各プラグインもリリース版でなく最新ソースを取得した状態にしたいので、composerでNetCommons3をインストールしていきます。

（開発用でなくリリース版でOKなら [NetCommos3をcomposerでインストール · NetCommons3/NetCommons3 Wiki](https://github.com/NetCommons3/NetCommons3/wiki/NetCommos3%E3%82%92composer%E3%81%A7%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB) の手順に従えばOKです）

# NetCommons3をgit clone

```
$ git clone https://github.com/NetCommons3/NetCommons3.git
$ cd NetCommons3
```

# composer.json変更してcomposer install

composer.jsonに ``` "minimum-stability": "dev" ``` を追加します。

scripts のあとあたりに追記します。

```composer.json
{
 中略
 "scripts": {
        "post-install-cmd": ["app/Console/cake install.install install_bower"],
        "post-update-cmd": [
            "app/Console/cake install.install install_bower"
         ]
    },
    "minimum-stability": "dev"
}
```

composer.jsonの編集がおわったらnetcommons/*パッケージをupdateしてからinstall

```
$ comopser update "netcommons/*"
$ composer install
```

# MAMP用に direnv設定

```
$ touch .envrc
$ direnv edit .
```

最初にtouchしてるのはdirenvのエディタにcotエディタを指定してて、ファイルがないとエラーになってしまうので。


```.envrc
PATH_add /Applications/MAMP_PHP_BIN/php7.4
PATH_add /Users/ryuji/code/NetCommons3/app/Console
```

MAMPアップデートするとPHPのマイナーバージョンが変わってパスも変わってしまうので、シンボリックリンクつくってそっちにパス通すようにしてるので上記のようなPATH_addになってます。
MAMPアップデートしたら下記の様なコマンドでシンボリックリンクはってます。

```
$ ln -s /Applications/MAMP/bin/php/php7.4.2/bin/php php7.4/php
```


# NetCommons3 インストール

```
$ cd NetCommons3
$ cake install.install
```
TortoiseGit で GitLab に Merge Request する

**GitLab** にリモートリポジトリを作成し、**TortoiseGit** でローカル作業を行う時の操作方法をメモしておきます。

# TortoiseGit

## 環境

- Windows10
- TortoiseGit 2.10.0.2
- GitLab CE 12.8.6（Windows10で仮想サーバー起動）

## 初回のみ

### クローン

GitLab のリポジトリをクローンします。

![ss01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/d8f2ad18-35bd-5b8a-2c1c-5d048100569e.jpeg)

TortoiseGit の「Git クローン」を選択します。

![ss02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/cf2d657e-d1e1-ece1-5349-8fbccf90db91.jpeg)

リポジトリの URL とクローン先のディレクトリを指定します。

![ss03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/e706e336-66a3-cee9-333c-9976c013b33f.jpeg)

## ブランチ作成

GitLab の issueごとにブランチを作成して作業します。

### masterブランチをプルする

「TortoiseGit」→「プル」を選択します。
リモートに origin を指定します。
リモートブランチに master を指定します。

![ss04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/3ad5f3a2-b7f6-5f8a-f9ff-195744402478.jpeg)

### testブランチを作成する

「TortoiseGit」→「ブランチを作成」を選択します。
ブランチに test（ブランチ名） を指定します。
「新しいブランチに切り替える」にチェックを付けます。

![ss05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/d5da1f30-dfb7-fc12-1412-91f538ac657f.jpeg)

## 繰り返し作業

### testブランチをコミットする

「Git コミット -> "test"」を選択します。
メッセージを入力します。
**メッセージに issue番号（例：#4）を入れると GitLab でコミットと issue が紐づきます。**
「コミット」をクリックします。

![ss06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/5552fb55-2572-004a-7a58-2067b384705f.jpeg)

## プッシュ

### testブランチでorigin/masterをプルする

「TortoiseGit」→「プル」を選択します。
リモートに origin を指定します。
リモートブランチに master を指定します。
「フェッチ後にリベース」にチェックを付けます。
**フェッチ後のリベースで競合したら（頑張って）解決します。**

![ss07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/16029958-0b59-6be4-8503-dba2b6dc6228.jpeg)

### testブランチをプッシュする

「TortoiseGit」→「プッシュ」を選択します。
ローカルに test を指定します。

![ss08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/8848f7e5-adc1-b600-fb49-1ccf46d87c8a.jpeg)

# GitLab

## Merge Request

「マージリクエストを作成」をクリックします。

![ss09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/52f7df70-b057-6795-a6f5-ee8bfe8e2acf.jpeg)

タイトルなどを記入します。
「Submit マージリクエスト」をクリックします。

![ss10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30731/f5058e54-f806-8fde-7a85-468974853067.jpeg)
GrADS覚え書き

# コマンドライン上で実行

コマンドラインから、GrADSスクリプトを実行

```bash
grads -lbc sample.gs 
# -l: landscapeモード (横長) -p: portraitモード(縦長)
# -b: バックグラウンド実行
# -c: 最初に実行するコマンド
```

# 引数の設定
```bash
grads -lbc sample.gs a1 a2
```

ここで、`a1`と`a2`は引数。

sample.gs内では、以下のように設定すれば、`x1`に1番目の引数(`a1`)、`x2`に2番目の引数(`a2`)がそれぞれ読み込まれる。

```grads:*.gs
function main(args) # 1行目にかく
x1=subwrd(args,1)  
x2=subwrd(args,2)
```


# 時刻情報の扱い

タイムステップの情報を取り出す。

```grads:*.gs
'q time' #時刻を確認
word = subwrd(result,3) #空白で区切られた文字列を取り出す
time = substr(word,4,5) #文字列を取り出す 
```

時刻は、hh:mmZddmmmyyyyまたはddmmmyyyyの形式。

# 履歴保存

今まで打ったGrADSコマンドをGrADSスクリプトに保存したいときは、

```grads
his sample.gs 
```

# 未定義エラーの非表示

領域全体が未定義で"Entire grid Undefined"と出るのを消したいときは、

```grads:*.gs
'set datawarn off '
```

ただし、地図すらかいてくれないので、必要なときはdummy変数を用意してかかせるなどする。


# アスキーファイル出力

GrADSで計算した結果を描画するのではなく、アスキーファイルに出力。

```grads:*.gs
'set gxout print'
'set prnopts %7.2f 1 1' #書式 / 1行あたりに出力するデータ数 / データ間の空白
'd var'
rc=write(test.txt, result)
rc=close(test.txt) 
```

# 便利な組み込み関数

|関数|意味|
|--------------------------------| -------------|
|  `abs(a)`|絶対値           |
|  `mag(u, v)`|2乗和の平方根(ベクトルの長さなど)|
| `math_mod(n, m)`|余りの計算(nをmで割った余り)   |

# 領域平均

ave(undefを取り除く)とaave(undefを取り除かない)はundefのデータを含んでいなければ、同じ結果になる。

```grads:
ave(ave(var,x=1,x=10),y=1,y=20)
aave(var,x=1,x=10,y=1,y=20)
```

# ループ
脱出は`break`、続けるときは`continue`

```grads:
i=1
while(i<=3)
  'set t 'i
  'd u'
  i=i+1
endwhile
```
docker-composeで、MySQLの設定ファイル変更を適用させる

## 何をするのか
docker-composeでMySQLの設定ファイル(my.conf)の中身を更新したが、作り直したコンテナに反映されなかったため、これを反映させる。

## 環境
- Laravel
- MySQL8.0
- docker-compose version 1.26.2



## 解決方法
どうやら**データベース（volumes）がマウントされていると設定が変更されない**ようでした。

一度データベース(volumes)を削除すればOKなので、、、

```:terminal
docker volume prune
```

したところ、マイグレーションまで問題なくできました。

参考：
[Docker: where is docker volume located for this compose file](https://stackoverflow.com/questions/45271420/docker-where-is-docker-volume-located-for-this-compose-file)
jetson nano起動時にエラーが表示されたまま先に進まない（A start job is running for End-user configuration after initial OEM installation）

イメージ取得後、jetson nano初回起動後、以下のエラーが表示されたまま先に進まない

```
A start job is running for End-user configuration after initial OEM installation (10min 25s / no limit)
```

jetson nanoのイメージは以下から取得

[JetPack 4.4 JETSON NANO DEVELOPER KIT](https://developer.nvidia.com/embedded/jetpack)
　⇒　JETSON NANO DEVELOPER KIT を選択してダウンロード


色々調べたのち、ただ電源をOFF/ONするだけでエラーが解消して無事に起動しました。。

# 参考
[Jetpack 4.2.1 fails to boot on Nano](https://forums.developer.nvidia.com/t/jetpack-4-2-1-fails-to-boot-on-nano/78710)
[Jetson Nanoで使えるSDカードのイメージファイルまとめとイメージ書き込み方法](https://qiita.com/karaage0703/items/0583528f1f9c34911a31)
[JetPack Archive](https://developer.nvidia.com/embedded/jetpack-archive)
[JetPack 4.4 JETSON NANO DEVELOPER KIT](https://developer.nvidia.com/embedded/jetpack)
ジャックベラ検定

#1 この記事は

ジャックベラ検定をPythonで行う方法を説明します。

#2 内容

##2-1 ジャックベラ検定とは

ジャックベラ検定とは、標本が正規分布に従うかどうかを判定する手法です。

検定統計量JBは、下記式のとおりになります。[by Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B8%E3%83%A3%E3%83%83%E3%82%AF%E2%80%93%E3%83%99%E3%83%A9%E6%A4%9C%E5%AE%9A#:~:text=%E3%82%B8%E3%83%A3%E3%83%83%E3%82%AF%EF%BC%9D%E3%83%99%E3%83%A9%E6%A4%9C%E5%AE%9A%EF%BC%88%E3%82%B8%E3%83%A3%E3%83%83%E3%82%AF,%E9%81%A9%E5%90%88%E5%BA%A6%E6%A4%9C%E5%AE%9A%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82)

<img width="758" alt="94.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/0226eb55-96bf-2114-ef4d-2228af8d3a8d.jpeg">

検定統計量JBはχ二乗分布に従います。検定統計量JBで下記に記載された仮設の検定を行う。(有意水準 p%)

<b>
H0(帰無仮説) : 標本は正規分布に従う。
H1(対立仮設) : 標本は正規分布に従わない。 
</b>

Pythonでは、 stats.jarque_bera(x)で標本xの検定統計量JBを計算できます。stats.jarque_beraの返却値は、[JB計算値, p値]です。

有意水準p=0.05に設定した場合、stats.jarque_beraの返却値p値>0.05であれば、帰無仮説が採択されるため標本は正規分布に従うと判断できます。逆に算出されたp値<=0.05の場合は、標本は正規分布に従わないと判断されます。

##2-2 Pythonでのジャックベラ検定の実行例

###例1

平均0,分散1の正規分布に従う乱数を10000個発生させ、標本を作製します。その標本に対してジャックベラ検定を行い、標本が正規分布に従うかを検定します。


```python:sample.py
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

#正規分布に従う乱数を発生させる。
x = np.random.normal(0, 1, 10000) 

#標本のヒストグラムを描写する。
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.hist(x, bins=50)
ax.set_title('first histogram')
ax.set_xlabel('x')
ax.set_ylabel('freq')
fig.show()

#ジャックベラ検定を行う。
jarque_bera_test = stats.jarque_bera(x)
print('Jack Bera:', '\t', jarque_bera_test)　
```

(実行結果)ジャックベラ検定の結果、p-value>0.05と算出されているので標本は正規分布に従っているという帰無仮説を採択できます。

```console:test.txt
Jack Bera: 	 (JB=0.3352314362400006, p-value=0.8456787512712962)
```

<img width="342" alt="95.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/d86c9069-71c0-4d28-9206-1aab3855ba6d.jpeg">



###例2

自由度1のχ二乗分布に従う乱数を10000個発生させ、標本を作製します。その標本に対してジャックベラ検定を行い、標本が正規分布に従うかを検定します。


```python:sample.py
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

#正規分布に従う乱数を発生させる。
x = np.random.normal(0, 1, 10000) 
kai=x*x #kaiはχ二乗分布に従う

#標本のヒストグラムを描写する。
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.hist(kai, bins=50)
ax.set_title('first histogram')
ax.set_xlabel('kai')
ax.set_ylabel('freq')
fig.show()

#ジャックベラ検定を行う。
jarque_bera_test = stats.jarque_bera(kai)
print('Jack Bera:', '\t', jarque_bera_test)
```

(実行結果)ジャックベラ検定の結果、p-value<0.05と算出されているので、帰無仮説は棄却され標本は正規分布には従っていないという対立仮設が採用されます。

```console:test.txt
Jack Bera: 	 (JB=89946.17232671285, p-value=0.0)
```

<img width="344" alt="96.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150223/16a6104f-63e9-e12e-7522-bdaabec55a5b.jpeg">
Oracle Databaseのインストールがエラーで完了しました

<strong>・現象</strong>
oracle dbインストール時に下記画像のように表示され失敗する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/2028acca-7a56-0cc7-f563-21062c291d90.png)<br>
<strong>・解決策</strong>
インストール先を指定する際、パス名は下記画像のように半角英数字を基本にする。<br>(日本語は不可)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/1f61c161-9833-334e-0f88-cb003b95a7a9.png)
【Rails】テストに使うダミーデータを用意する【Faker】

## はじめに
RSpecなどでテストする際に、FactoryBotなどであらかじめデータを用意することがありますが、その際にランダムデータをいい感じに作ってくれるFakerの使い方について書いていきます。

## 準備
gemをインストールするだけです。

```rb:Gemfile
group :development, :test do
  # （略）
  gem 'faker'
end
```

```:ターミナル
$ bundle install
```

## 使い方
rbファイル内で`Faker::[ジャンル].[タイトルなど]`と入力すればOKです。
どんなものが用意されているかは[公式リファレンス](https://github.com/faker-ruby/faker)から確認してみてください。

READMEのとこにサンプルが並んでるので、使いたいものをクリックしてリンク先の表示どおりに使うだけです。
<img width="573" alt="278199070c4abe565b7f1ecb13ca831c.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/57581544-c0e2-99d1-0f71-fe748fbb996d.png">

使ってみないとわかりにくいので実際に使ってみます。
今回はMoviesを使ってみたいと思います。READMEのMoviesをクリックすると下のように同一ページのMovies欄に飛びます。
<img width="407" alt="25cbc0c934fbfedd13009afd6e7fb9ff.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/11acd202-9d8e-a206-996a-0b91b5928163.png">
今回は`Faker::movie`を使います。
`Faker::movie`をクリックして詳細ページに飛びます。
<img width="1281" alt="9c862c81313fa7018403ab0fb7212a8e.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/c0745504-de4c-0a46-21b8-fd91f8e3ff89.png">
このページに書かれているとおりに記述すれば、ランダムにデータを取得してくれます。
試しに`Faker::Movie.title`で映画のタイトルを取得してみましょう。

コンソールで確かめます。

```:ターミナル
$ rails c
```
<img width="263" alt="95008ab8d5f596fb880f99867f2cab20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/01d0ba07-038b-b599-e8b2-b34082f24bc4.png">

こんな感じで取得してくれます。

ポケモンやスターウォーズなんかのデータもあるので面白いです。
<img width="309" alt="3b3af87aaeeec64d399f9f9819055435.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/64dd22c0-f6d3-f2b2-e9f9-0aeb6c91a12b.png">
<img width="352" alt="b03d65bc4ae23c1a32f8c04b8bf6266e.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605568/c1e58105-233d-c247-a79a-6cb8222a544f.png">

## FacrotyBotでの使い方
FactoryBotを使う時は下のように書けばOKです。

```rb:book.rb
FactoryBot.define do

  factory :book do
    title     { Faker::Book.title }
    author    { Faker::Book.author }
    publisher { Faker::Book.publisher }
  end

end
```
同様にseedファイルなんかでも使えば初期データをランダムにいろいろ作成できたりします。
俺のDockerコマンドメモ

# Dockerコマンド

## コンテナ操作

### 起動中コンテナ確認
`docker ps`
`docker container ls`

#### 止まってるコンテナも確認
`docker ps -a`
`docker container ls -a`

### Dockerfileからイメージ生成
`docker build -t [image_name] [Dockerfile_dir]`

### イメージからコンテナ生成
`docker create [image_name]`

### イメージからコンテナを生成して起動
`docker run -it [image_name] [command]`

#### centosのイメージを起動してbashログイン
`docker run -it centos /bin/bash`

#### コンテナの80ポートをホスト8080ポートにポートフォワーディングしてhttpdを起動
`docker run -d -p 8080:80 httpd`
`docker run -d -p 8080:80 -p 8081:443 httpd`

#### ローカルのディレクトリをコンテナにマウント
`docker run -itd --privileged -p [host_port]:[container_port] -v [local_dir]:[container_dir] --name [container_name] [image_name]:[image_tag] /sbin/init`

### コンテナ起動
`docker container start [container_id]`

### コンテナ停止
`docker container stop [container_id]`

### コンテナ再起動
`docker container restart [container_id|container_name]`

### コンテナ削除
`docker rm [container_id]`

#### 動いてるコンテナを削除
`docker rm -f [container_id]`

### コンテナに入ってbashログイン
`docker exec -it [container_name] /bin/bash`

### 起動中コンテナでコマンド実行
`docker container exec [container_id|container_name] [command]`

### コンテナのログを確認
`docker logs [container_id]`

### コンテナの状態を確認
`docker stats [container_id]`

## Dockerイメージ操作

### Dockerイメージの取得
`docker pull [image_name]`

### Dockerイメージの検索
`docker search [image_name]`

### Dockerイメージの確認
`docker images`

### Dockerイメージのコミット
`docker commit [container_id] [image_name]:[image_tag]`

### Dockerイメージの削除
`docker rmi [image_id]`

### Dockerイメージをtar形式でエクスポート
`docker save [image_name]:[image_tag] -o image.tar`

### ファイルを読み込んでDockerイメージをインポート
`docker load -i image.tar`

# Docker Composeコマンド

### イメージをビルドしてコンテナをバックグラウンドで起動
`docker-compose up -d --build`

### コンテナを再起動
`docker-compose restart`

### イメージをビルド
`docker-compose build`

### コンテナを削除
`docker-compose down`

### コンテナに接続してシェル起動
`docker-compose exec [service_name] bash`
【Laravel】ルート定義を正規表現付きで設定するには

## 正規表現の制約設定
Laravelでは、ルートを定義するファイル`routes/web.php`に正規表現を利用してルート定義できます。ルートインスタンスの`where`メソッドを使用しましょう。
第１引数に制約設定をしたいパラメータ名、第２引数に正規表現を記入します。

```php:（例１）routes/web.php
Route::get('user/{name}', function ($name) {
    //　
})->where('name', '[A-Za-z]+');
```
・ `name`パラメータは、小文字a~z、大文字A~Zで1文字以上であること
　

```php:（例２）routes/web.php
Route::get('user/{id}', function ($id) {
    //
})->where('id', '[0-9]+');
```
・ `id`パラメータは、数字0~9で1文字以上であること
　

```php:（例３）routes/web.php
Route::get('user/{id}/{name}', function ($id, $name) {
    //
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
```
・`id`パラメータは、数字0~9で1文字以上であること
・`name`パラメータは、小文字a~zで1文字以上であること

例３では`where`メソッドに連想配列を入れて制約設定を行っています。
キーにパラメータ名、値に正規表現という感じです。

上記の各々の例を参考に、パラメータの制約が設定できます。「自分で定めた設定のパラメータを正規表現で設定したいんや～！」というときに、この`where`メソッドを活用しましょう。:grinning:


## グローバル制約
ルート定義ファイル`routes/web.php`に`where`メソッドを使用して、１個ずつルートの制約設定をするのも良いですが、指定した正規表現を、ルート定義した全部のルートパラメータに適応させたい場合は`app/Providers/RouteServiceProvider.php`の`boot`メソッド内で設定を行いましょう。

```php:app/Providers/RouteServiceProvider.php
    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        Route::pattern('id', '[0-9]+'); // 追加した部分
        parent::boot();
    }

```

`Route::pattern('id', '[0-9]+');`の部分を追加することで、`id`パラメータを使用している全ルートで、自動的に「0~9の数字で1文字以上」という制約がかかります。
nodenvでディレクトリごとにバージョンを指定する方法


今回はnodenvのセットアップ方法について簡単に紹介します。
先日、nodebrewのセットアップ方法について紹介したのですが、プロジェクト毎にnode.jsのバージョンを指定したかったのでnodenvに乗り換えました。
#はじめに
まず、node.jsのバージョン管理でnodebrewを使用していた場合にはnodebrewを削除する必要があります。
実際の手順を紹介します

##使用しているnode.jsのバージョンを控える
その前に現在使用しているnode.jsのバージョンを控えておきましょう。
以下のコマンドの実行結果を控えます。
`$ nodebrew list`

##nodebrewを削除
※この手順はnodebrewを使用していない場合はスキップしてください

`$ brew uninstall nodebrew`

##設定ファイルの記述を削除

最後に利用しているシェルの設定ファイルから以下を削除します。
`export PATH=$HOME/.nodebrew/current/bin:$PATH`

この際、MacOSのバージョンによって設定ファイルが異なりますので注意しましょう。
###Catalina以前の場合

`vi ~/.bash_profile  `

###Catalinaの場合
`vi ~/ .zprofile   `

こちらに関してはMacOS Cataliaからデフォルトログインシェルが「bash」から「zsh」に変更されたことが理由です。


#nodenvインストール
インストールは以下のコマンドで実行できます。
`$ brew install nodenv`

インストールが完了したら一応確認してみましょう。
`$ nodenv -v`

バージョンが表示されたらOKです。

##設定ファイルの記述
設定ファイルに以下を書き込みます。
`export PATH="$HOME/.ndenv/bin:$PATH"`
`eval "$(nodenv init -)"`

ここでも先ほどの注意点と同様に書き込み先を間違えないようにしましょう。

これでnodenvを使用する準備は整いました。

#nodenvの使い方

最後にnodenvでのnodeのインストール方法やバージョン指定の方法について簡単に紹介します。

##利用できるバージョンの確認
`$ nodenv install --list`

##バージョンを指定してインストール
`$ nodenv install <version>`

例 : v12.0.0をインストールするとき
`$ nodenv install 12.0.0`

##バージョンの指定
`$ nodenv global <version>`

##ディレクトリ毎にバージョン指定
`$ nodenv local <version>`
React-nativeでのDom編集(getElementByIdをreactでやる方法)

# 目的
- input項目の値を、submitしたらクリアする、という処理にとてもハマった
- reactでのdom操作の考え方の一端を学ぶことができた
- 今回の例はinputだけだが、異なるdom要素でも同様の考え方になると思うので、整理する

# やりたいこと
- react-nativeで、input項目を用意し、submitしたらinputフィールドのvalueをクリアしたい

# 問題の事象
- 普通のhtmlではないため、getElementById、などでinput要素を取ることができない

# 対策
## 考え方
- 要素にrefを定義しておいて、それを元にjs側で扱う、という操作をする
- document.getElementBy...の代わりに、refを使う
- Reactから`createRef()`で、`input`(名称は任意)というタグ名で変数を作り、
- dom要素のInputのref属性に設定する

```
const input = React.createRef();

<Input
  ref={input}
  ...
/>
```
- dom要素が扱えるものは、コンポーネントに何を使っているかによるが、
> 今回react-native-elementsを使っているので、ドキュメントに定義がある
> https://react-native-elements.github.io/react-native-
- inputが使えるメソッド

```
input.current.focus();
input.current.blur();
input.current.clear();
input.current.isFocused();
input.current.setNativeProps({ value: 'hello' });
input.current.shake();
```

## クラスで実際に使うときに
- 考え方としては上記だが、
- このままだと、onPressのスコープとrefをしているrenderのスコープがずれてしまう場合（例の通り）refが取れないので、
- クラスで変数を持ち、constructorでrefを設定しておく

> 参考    Ref と DOM
> https://ja.reactjs.org/docs/refs-and-the-dom.html


```javascript:サンプルのクラス
import React from 'react';
import { StyleSheet, Text, View, FlatList, Image,Dimensions, Alert,KeyboardAvoidingView } from 'react-native';
import { Button, Input } from 'react-native-elements';

export default function(props) {
  return <CommentList {...props} navigation={navigation} />;
}

class CommentList extends React.Component {
  state = {
    comment: ''
  }

  constructor(props) {
    super(props);

    // input項目のバインド
    this.onChangeComment = this.onChangeComment.bind(this);

    // domへアクセスするためのrefを全体に見えることろで定義
    this.ref = React.createRef();
  }

  submit = () => {
    console.log('Submit')

    // input項目を初期化 refで要素を取得する
    const node = this.ref.current;
    node.clear();　　　// Dom要素をここで操作している

  }

  render() {

    // input要素へのアクセスのためのrefを設定する
    const input = React.createRef();

    <Input ref={this.ref} label="コメント" style={styles.input} onChangeText={this.onChangeComment}/>
    <Button title="送信" onPress={this.submit}/>

  }
}
const styles = StyleSheet.create({省略})
```
競技プログラミング練習記 No.61【ABC102練習】

初回 -> [はじめに](https://qiita.com/easychoco/items/a9ae28aca97cfe47091f)

[ABC102](https://atcoder.jp/contests/abc102)を解きました。
3完です！

|問題|時間|アルゴリズム|実行時間
|:-:|:-:|:-:|:-:|
| A |  1min |-| 8ms|
| B |  1min |-| 6ms|
| C | 82min |二分探索| 37ms|

# まとめ
先にまとめを載せます。これ自体は最後に書いてます。


最小要素と最大要素は`std::min_element()`と`std::max_element()`を使えば求まります。
書くのが少し手間なので、計算量的に間に合う場合は`sort`で十分です。

C問題の実行速度が提出時に `C++ (GCC 9.2.1)` で解いた人の中で1番でした。嬉しい。

## A - Multiple of 2 and N
```c++
  int n;
  cin >> n;
  cout << (n % 2 == 0 ? n : n * 2);
```
「`2` と `N` のどちらでも割り切れる最小の正整数」は、`N`が偶数の時は`N`自身で、`N`が奇数の時は`2 * N` ですね。
制約の範囲が大きいのでオーバーフローに注意です。（今回は大丈夫です。）

## B - Maximum Difference
``` c++
  int n;
  cin >> n;
  vector<int> a(n);
  for(int i = 0; i < n; ++i)
  {
    cin >> a[i];
  }
  sort(a.begin(), a.end());
  cout << a.back() - a[0];
```
数列内の異なる2要素の差の絶対値を最大化する問題ですね。
数列内の最小要素と最大要素の差が答えになります。
最小要素と最大要素は`std::min_element()`と`std::max_element()`を使えば求まります。
今回は計算量的に間に合って書くのが手間だったので`sort`しました。

## C - 	Linear Approximation

``` c++
  ll n;
  cin >> n;
  vector<ll> a(n);
  for(int i = 0; i < n; ++i)
  {
    cin >> a[i];
    a[i] -= (i + 1);
  }

  auto f = [&](ll b)
  {
    ll ret = 0;
    for(int i = 0; i < n; ++i)
    {
      ret += abs(a[i] - b);
    }
    return ret; 
  };

  ll le = -1000200001LL, re = 1000200001LL;
  ll lv = f(le);
  ll rv = f(re);
  while(re - le > 1)
  {
    ll mid = (le + re) / 2LL;
    ll mv = f(mid);
    if (lv < rv)
    {
      re = mid;
      rv = mv;
    }
    else
    {
      le = mid;
      lv = mv;
    }
  }
  cout << min(rv, lv);
```
$A_i - i$を先に計算しておけば、 $b$ だけについて考えればいいですね。

$b$ についての二分探索で解きました。想定解法は中央値を使う方法です。
実行速度だけは速くて、提出時に `C++ (GCC 9.2.1)` で解いた人の中で1番でした。嬉しい。
二分探索の場合は範囲に注意で、$[-10^9 - 2 * 10^5\ ,\ \ \  10^9 + 2 * 10^5]$ になります。

以下、解いたときの思考回路です。
これは平均値が答えだ(ﾄﾞﾔｧ
からのWA安定でした。
これは中央値が答えになります。
考察中に中央値も思い浮かんだのですが、謎の理由で却下していました。猛省せねば。

理想なら中央値を思い浮かんだ時点で実装しているべきですが、中央値からどんどん離れていきます。

問題名が`Linear Approximation(線形近似)`なのでグラフの極値を求める問題かなと思いました。
ちょうど解空間が下に凸な二次関数の形をしています。
ニュートン法？再急降下法？と思いましたが微分がよくわからず、、、
そんな重い実装はないはず、という思考で二分探索を思いつきました。



以上です。ありがとうございました。
Let's Encryptによるワイルドカード証明書　～簡単なコマンドオプション解説を添えて～

# certbotコマンドを実行

```bash
certbot certonly \ # 1
--manual \ # 2
--server https://acme-v02.api.letsencrypt.org/directory \　# 3
--preferred-challenges dns \ # 4
-d *.example.com \ # 5
-d example.com \ # 5
-m fclef@example.jp \ # 6
--agree-tos \ # 7
--manual-public-ip-logging-ok # 8
```

## 1. certonly
`certbot`のサブコマンドです。

単に`$ certbot`で実行すると、デフォルトでサブコマンド`run`が実行されます。
`run`は稼働中のウェブサーバーに対し、証明書の取得・インストールを実行します。

それに対し、`certonly`では証明書の取得だけを実行します。
ウェブサーバーへのインストールは自分でやります。

Let's Encryptの解説記事を見るとよく`certonly`が使われてますが、何故だかはわかっていません。
勝手にウェブサーバーの設定を触られると変になるかもしれないからかな？
夏バテで試す気力もないので、親切な人がいたら教えて下さい。

## 2. --manual
ドメイン名の認証を手動で行います。
これなしで実行すると、ウェブサーバーの設定から自動でドメインを認識します。多分。
精度が不明なので`--manual`指定しかやったことないです。

## 3. --server
証明書のリソースURIを指定します。
デフォルトは`https://acme-v01.api.letsencrypt.org/directory`です。
今回はワイルドカードに対応している環境である`https://acme-v02.api.letsencrypt.org/directory`を指定します。

## 4. --preferred-challenges
ドメインを使用する権利があることを確認する認証の方式を選択できます。

デフォルトはhttpによる認証です。
ウェブサーバー上に配置した認証用ファイルをHTTP経由で確認できれば認証成功です。

ワイルドカード証明書を使用するには、DNSによる認証を選択する必要があります。
Let's Encryptが発行するトークンをDNSのTXT属性に設定する必要があり、その操作を持ってドメインの使用権があることを確認します。

## 5. -d
証明書を使用するドメインを指定します。
ワイルドカードの場合、サブドメインありとなしの両方を指定します。

## 6. -m
アカウント用のメールアドレスを指定します。
Let's Encrypt上で管理されるアカウントに紐づくメールアドレスで、
更新のお知らせなどが届きます。
証明書を使用するドメインのメールアドレスである必要はありません。
普段遣いのメールアドレスを使用して、お知らせを見逃さないようにするのがいいでしょう。

## 7. --agree-tos
利用規約に自動で同意します。

## 8. --manual-public-ip-logging-ok
グローバルIPアドレスを認証局でロギングすることを自動で承諾します。

# DNSの設定
コマンドを実行すると、以下のメッセージが表示されるので、この画面は一旦そのまま置いておきます。

```bash
Please deploy a DNS TXT record under the name
_acme-challenge.example.com with the following value:

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Before continuing, verify the record is deployed.
```

`xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`は実際は認証用のトークンなので、
それを`_acme-challenge.example.com`への問い合わせで確認できるようTXTレコードを登録します。

```
_acme-challenge TXT xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

DNSにTXTレコードを登録してもキャッシュなどの影響ですぐに反映はされないので、別のターミナルを開いて、何度か以下のコマンドを叩いて登録したトークンの応答があることを確認します。

```bash
$ nslookup -type=TXT _acme-challenge.example.com 8.8.8.8
Server:         8.8.8.8
Address:        8.8.8.8#53

Non-authoritative answer:
_acme-challenge.example.com        text = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # ←この応答があればOK

Authoritative answers can be found from:

```

DNSがトークンの応答を返すことを確認したら、Let's Encryptの画面に戻り、Enterを押します。

# 簡単に確認
失敗した場合は、何故失敗したのかがメッセージに表示されています。
ドメインが悪いのか、DNSの設定が悪いのか、原因は様々だと思いますが、各種トラブルシューティング記事を参照して解決してください。

上手くいくと、なんやかんやメッセージが表示されます。
証明書ファイルの場所が表示されているので、ウェブサーバーにインストールしましょう。

証明書をインストールしたあと、サブドメインで運用しているサービスへアクセスし、
証明書情報を見たときに、ワイルドカード表示がされていたら成功です。

# 参考
* [Let’s Encryptでワイルドカード証明書を取得する](https://ssilab.co.jp/blog/tech-blog/tech-blog-child/lets-encrypt_wildcard)
* [Let's Encrypt総合ポータル | Let's Encryptユーザーガイド](https://free-ssl.jp/docs/using.html)
* [Let's Encrypt総合ポータル | コマンド解説（コマンドリファレンス）](https://free-ssl.jp/command/)
EC2のデプロイに関わるエラーを確認するコマンド一覧

#この記事の使い方
EC2、RDS(MySQL)、Rails、nginx、pumaを使用してデプロイする際のお供に。

何を隠そうこれは筆者のためのメモでもあります。笑
Amazon linuxとAmazon linux2でコマンドが違っていたりして混乱するので。

#使用するAMI
 **Amazon linux2**


#Nginx関連
```
$ sudo systemctl start nginx.service   #起動
$ sudo systemctl status nginx.service  #ステータス確認
$ tail -f log/nginx.error.log          #エラーログ確認
$ sudo nginx -t                        #設定ファイル内の間違いを教えてくれる
```

#puma関連
```
$ bundle exec pumactl start            #起動
```

#MySQL関連
```
$ sudo systemctl start mysqld.service  #起動
$ sudo systemctl status mysqld.service #ステータス確認
```

###見てくださりありがとうございました。
この記事がデプロイの助けになれば幸いです。
Transform,Position,擬似要素達

最近マークアップを触っていなくて、全然思い出せなくて詰まりまくったのでメモ...
##Transform
transformは、2D変形、3D変形を行うことができるよ
関数を使用することで、移動、回転、遠近効果などを生み出せるよ
アニメーションをする際に結構使われるよ

**Transform関数**

|役割|関数名|
|:-----------------|------------------:|
|　移動　|　translate(x,y)　|
|　回転　|　rotate(deg)　|
|　縮尺　|　scale(x,y)　|
|　並行　|　skew(x,y)　|

半角スペースを入れると、関数を複数使うことができるよ

*transform-origin: x y;プロパティで変形の起点(支点、原点)を変えることができる*

第三引数にはeaseを設定することができ、デベロッパツールでグラフをいじって時間量、変化量の数値を生成し、反映することで変更できる

参考サイト：http://www.htmq.com/css3/transform.shtml

##Position
位置を調節するプロパティだよ
デフォルト値はstaticだよ

値は以下五つ

`static`：staticはpositionの初期値で、top,left,z-indexは適用されない

`relative`：指定してもstaticと位置は特に変わらないが、top,left,z-indexは適用されるようになるよ

`absolute`：一番近い順で、親要素がstatic以外の場合、親要素を基準に絶対位置を指定（親要素がない場合、左上からの絶対位置が指定される）
要素の高さはなくなり（親要素も子要素分の高さが引かれる）、下にある通常配置の要素が上に詰まって配置されるよ

`fixed`：absoluteと同じで高さがなくなるよ
ウィンドウ画面を基準に絶対位置を指定、スクロールしてもその場所に固定されてるよ

`sticky`：static,relativeと同じで高さがあるよ
親の要素の中でしか、指定した位置に絶対配置されない
つまりスクロールをするとfixedと同じでウインドウ全体を基準に指定した位置に指定されるよ
親要素が終わるとstickyの要素もそこまでしかスクロールの絶対配置効果が効かない

##擬似要素
擬似要素は、要素の前(::before)後(::after)に内容を挿入できるよ
挿入内容はcontentプロパティで指定(背景色を利用したいときは空文字を渡す)
2つ以上は同じ要素に指定できない
Linux bash使いのためのWindowsスクリプティング

# Linux bashではゴリゴリとスクリプト書いてるのに、Windowsになるといまいち書けないって人向けの記事。

**Linuxでbashならこう書くんだけどなぁ**、ってのをことあるごとに調べたくないので、そのためのまとめ。

## はじめに
### 前提 
- [WSL2](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)とかを使えば、WindowsでもネイティブなLinux bashは使えるけど、商用環境向けで気軽にミドルウェア追加できないとか、そのためだけに構成変更できない（したくない）という状況向け。
- Windows環境で最初から使える（主に）PowerShellやコマンドスクリプト（*.cmd）、VBSなどでの書き方がメイン。
- 純開発者向けよりは半インフラ担当者向けかも（もちろん開発者がLinux向けのスクリプトをWindows向けにバックポートする際にも活用はできるものかと）。
- PowerShellよりもコマンドスクリプトファースト（PowerShellは細かいバージョンの違いが面倒なため）←個人的な好みに近い
- Linuxは主にRHEL（CentOS）を使用してますが基本どのディストリビューションのbash使いでも同じはず。

別の機会に[WSL2](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10)の有効的な使い方、みたいなものも触れてみたい。

## 目次


- おまじない系
 - 実行スクリプト名の取得
 - 実行ディレクトリ名の取得
- プロセスID
- ウェイトをかける
- 関数の書き方
- 遅延展開のさせ方
- 制御文
 - IF分岐の書き方
 - 繰り返し処理の書き方

# おまじない系

## おまじない系／実行スクリプト名の取得

### ◇Bashの場合
```shell:basename.sh
#!/bin/bash
_LNAME=$(basename "$0")
echo "$_LNAME";
```
```shell:(実行結果)
basename.sh
```

### ◇Windows／コマンドスクリプトの場合
```:basename.cmd
@echo off
setlocal enabledelayedexpansion
set _LNAME=%~nx0 
echo.%_LNAME%
```

```:(実行結果)
basename.cmd
```

### ◇Windows／PowerShellの場合

```.ps1:basename.ps1
echo $MyInvocation.MyCommand.Name
```

```:(実行結果)
basename.ps1
```

## おまじない系／実行ディレクトリ名の取得

### ◇Bashの場合
```shell:current_dir.sh
#!/bin/bash
_LNAME=$(dirname "$0")
echo "$_LNAME";
```
```shell:(実行結果)
/usr/local/src
```

### ◇Windows／コマンドスクリプトの場合
```:current_dir.cmd
@echo off
setlocal enabledelayedexpansion
set _LNAME=%~dp0 
echo.%_LNAME%
```

```:(実行結果)
C:\Users\hoge\My Test\
```
**注意点はコマンドスクリプトの場合、末尾に\がつく点**
嫌なら以下のように末尾を１文字削る。

```:current_dir.cmd
@echo off
setlocal enabledelayedexpansion
set _LNAME=%~dp0
set _LNAME=%_LNAME:~0,-1%　　　←先頭から文字長-1きりとる、という意味
echo.%_LNAME%
```

```:(実行結果)
C:\Users\hoge\My Test
```

### ◇Windows／PowerShellの場合

```.ps1:current_dir.ps1
echo $(Split-Path $MyInvocation.MyCommand.Path -Parent)
```

```:(実行結果)
C:\Users\xxx\PowerShell
```

## プロセスIDの取得方法

### ◇Bashの場合

```:process_id.sh
echo $$
sleep 30
```

```:(実行結果)
121
```

### ◇Windows／コマンドスクリプトの場合

コマンドスクリプトの場合は、実行しているスクリプトファイルのプロセスIDは取得できない
（コマンドプロンプトのcmd.exeのプロセスIDまでしか取得できない）。

### ◇Windows／PowerShellの場合


## ウェイトをかける

### ◇Bashの場合

```shell:wait_cmd.sh
sleep 5
```

### ◇Windows／コマンドスクリプトの場合

```:wait_cmd.cmd
timeout 5 >NUL
```

### ◇Windows／PowerShellの場合

## 関数の書き方

### ◇Bashの場合

```shell:
function any_function () {
    echo "test $1";
}

any_function "test"
```

```:(実行結果)
test test
```

### ◇Windows／コマンドスクリプトの場合


```shell:
goto MAIN

:FUNCTIONS

:DO_MY_FUNC
    echo.%1
    exit /b

:MAIN
call :DO_MY_FUNC test
```

```:(実行結果)
test
```

### ◇Windows／PowerShellの場合

## 遅延展開のさせ方

### ◇Bashの場合

### ◇Windows／コマンドスクリプトの場合

### ◇Windows／PowerShellの場合

# 制御文

## 制御文／IF分岐の書き方
 
### ◇Bashの場合

```shell:
if [ -f "/var/log/messages" ]; then
    ls -lah /var/log/messages;
else
   :
fi
```

### ◇Windows／コマンドスクリプトの場合

```shell:
if exists xxx (
    echo.xxx
) else (
   echo.yyy
)
```
**注意点**
if ～ else ～ が全て1ステートメントとなっておりこの1ステートメントを評価した瞬間の環境変数が展開された状態で実行されるため、
ifやelseブロック内で、戻り値を受け取って環境変数として参照しようとしても参照できない。

## 制御文／繰り返し処理の書き方
自動ツールの機能と選び方法

#1.アプリケーション開発のアプローチ
 ![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634099/1b9df5da-00ed-d30b-710d-aa3e2841057f.png)
#2.ツールとApexの対応関係
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634099/ef5879ed-26f1-4bef-ebde-63a2fc7f889d.png)
#3.自動ツールの機能
![https___qiita-image-store.s3.amazonaws.com_0_332907_ad0efdf4-93e9-f7db-ae2d-1240f4891d8a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634099/a8e89518-f624-ca95-06ff-d2a246a6b4bf.png)
#4.ツールの選び方法
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634099/ac47bbf8-3e09-36cc-9b80-c95c51168488.png)
#5.参照資料
[・自動ツールの機能](https://help.salesforce.com/articleView?id=process_which_tool.htm&type=5)
[・適切な自動化ツールの選択](https://trailhead.salesforce.com/ja/content/learn/modules/business_process_automation/process_whichtool)
クラウドAI開発講座 Microsoftと高専キャリアがコラボ #4

# クラウドAI開発講座
[マイクロソフトと高専キャリア教育研究所が共催するAI開発プログラム](https://online.kosen-career.tech/ai)
**無料**で参加でき、困ったときにはメンターに相談ができるオンラインプログラム



## 進歩
レッスン[おーちょさん](https://qiita.com/miokawa/items/6f1a3e480580e1e29abc)（途中）のLINE botをMicrosoft Teams botで使用可能にする。

[Twitter developersアカウントに登録](https://developer.twitter.com/en)申請をしたのですが、まだ、申請が通らないため、とりあえずMicrosoft Teams botで実装してみます。

**「Twitterとの連携が取れた時にMicrosoft Teams botに実装できなかったら心が折れる」**というおーちょさんからのアドバイスです。





### bot がチームに追加されない問題と対処
[ちょまどさん](https://qiita.com/chomado/items/6bda10abde0551f25723)の記事を参考にして、Microsoft Teams bot に追加しました。
しかし、bot がチャットには反映されるが、チームに追加されていないという事件が発生！


次の手順で、無事にチームに追加されました。

カスタムアプリをインストール
![picture4_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668928/15184b53-bd02-e9f5-b1e2-cc879f420de4.png)

ファイルを選択
![picture4_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668928/c30fd32d-a65d-19e1-a5cb-42a83bc3a6ed.png)

**ここからが重要、追加の横のプルダウンメニュー**
![picture4_3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668928/58facc9a-3aa3-cdf6-38b3-c7db3c3cb5fc.png)

チームに追加
![picture4_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668928/031eb839-d5b4-9afe-333b-c9521f1db859.png)

チームを検索＝＞設定＝＞戻る
![picture4_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668928/9400fa49-5ba3-9f88-ceef-94cef3ddffc4.png)

チームで bot が使用可能になりました。
ポジティブな言葉をかけると塩対応してきます。
ネガティブな言葉をかけるとエラーメッセージが返ってきます。 
![picture4_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668928/d05f0f30-a719-8712-8988-78794a06900a.png)










とりあえず Microsoft Teams bot を作成しましたが、エラーメッセージがそのまま返信となっています


早くツイッターと連携させて、次に進みたい！

待ってる間、[Microsoft Learn for Students](https://docs.microsoft.com/ja-jp/learn/roles/student?WT.mc_id=BlendedCurriculum-MSLearn-nosuzuk)で学習を進めます。




## 高専キャリアONLINEの提供コンテンツ（高専キャリア教育研究所）
[高専キャリアONLINE](https://online.kosen-career.tech/)の提供コンテンツ（[高専キャリア教育研究所](https://kosen-career.tech/)）

- [Business Design Lab](https://online.kosen-career.tech/business-design-lab)
- [クラウドAI開発講座](https://online.kosen-career.tech/ai)（本記事）
- [【高専生/編入生限定】特許活用ビジネスプランコンテスト](https://online.kosen-career.tech/bizdev-weekend)
vim 操作方法

###vimインストール・起動・バージョン確認

```sh:
#バージョン確認
vim --version
#インストール
sudo apt install vim
#起動
vim ファイル名
```
vimは基本的にキーで操作する。
###カーソル移動
|移動キー|説明|
|:---|:---|
|k|上移動|
|j|下移動|
|l|右移動|
|h|左移動|

###コマンド
|キー|説明|
|:----|:----|
|a|挿入|
|a > Insert|置換|
|dd|1行削除|
|行の末尾へ|$|
|行の先頭へ|^|
|ファイルの先頭へ|gg|
|ファイルの末尾へ|Shift + g|
|Ctrl + Insert|コピー|
|Shift + Insert|貼り付け|
|:wq|保存、終了|
|:q!|保存せずに終了|
Adafruit SSD1306互換品、Adafruit GFXライブラリのincludeエラーで3時間ほど格闘した【備忘録】

**Arduino Nano互換品**を用いて、Adafruit社から出ている**SSD1306互換品の128 x 64ピクセルモノクロOLEDディスプレイ**と、**Adafruit GFX Libraryのエラー**で3時間ほど格闘したので、解決した際の方法を記します。

# SSD1306、Adafruit GFX Libraryとはなにか
SSD1306は、Adafruit製のモノクロミニディスプレイ向けディスプレイコントローラーです。これを搭載したミニディスプレイは、いくつかのバリエーションが展開されています。

Arduino然り、Adafruit社の製品にも中国製の互換マシンが多く出回っており、今回はSSD1306互換の128 x 64ピクセルモノクロOLEDディスプレイを使用しました。Arduino用のミニディスプレイとしてはおそらく一番広く使われているものだと思います。日本でも、秋月電子やAmazonなどで容易に入手することが可能です。
Arduino IDE用にAdafruitから専用のライブラリ**Adafruit_SSD1306**が配布されています。

標準ライブラリの``Wire.h``とともにSSD1306コントローラとの通信を行う**Adafruit_SSD1306ライブラリ**に加えて必要で、SSD1331などAdafruitの他のディスプレイ系製品でも使用される映像処理担当のライブラリが**Adafruit GFX Library**です(たぶん)。
# エラーの内容
Adafruit GFX Library内で呼び出されている、``adafruit_i2cdevice.h``のincludeに失敗しました。本来、各ライブラリで呼び出されるヘッダーファイルは同じライブラリに含まれているか、標準でインストールされているはずです。

```c:libraries>Adafruit_GFX_Library>Adafruit_MonoOLED.h
//29行目以降
#include <Adafruit_GFX.h>
#include <Adafruit_I2CDevice.h>//エラーが起きていた箇所
#include <Adafruit_SPIDevice.h>
#include <SPI.h>
#include <Wire.h>
```

```C:code.ino
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
```

自前のコード冒頭に以上のように記述すると、exit status 1が吐き出され、``adafruit_i2cdevice.h``がinclude出来なかったと表示されました。

Adafruit GFX Libraryの再インストール、バージョンの変更などを何度も試しましたたが、解決しませんでした。

# 解決方法
Adafruitのウェブサイトで公開されている、SSD1306のチュートリアルを読むと、以下のように書かれています。

>If using an earlier version of the Arduino IDE (prior to 1.8.10), also locate and install Adafruit_BusIO (newer versions will install this dependency automatically).

要は、バージョン1.8.10以前のArduino IDEを使用している場合は、Adafruit GFX Libraryともう一つのAdafruit BusIOの依存関係がデフォルトでインストールされないから、自分で探してインストールしなさいということです。

私の開発環境はVSCode+Arduino用拡張機能で、使用していたArduino IDEはバージョン1.8.12でしたが、ものは試しと**Adafruit BusIOをインストールしてみたところ、このエラーは解消されました**。
# 参考

* [ArduinoでOLEDディスプレイを試す]
(https://qiita.com/jakalada/items/8f83d07291d984a31633)
* [Monochrome OLED Breakouts - Adafruit](https://learn.adafruit.com/monochrome-oled-breakouts/arduino-library-and-examples)
【アルゴリズム】文字列の降順

# 問題説明
文字列sのパラメータを受け取り、降順でソートを行って新しい文字列を返却するメソッドsolutionを作成してください。
sは英文字の小文字、大文字のみで構成されていて、大文字は小文字より値が小さい値として扱う。

# 条件
- パラメータ：sの長さは1以上の文字列です。

# 入出力の例
| x       |    result    |
|:-----------------|------------------:|
| "Zbcdefg"|              "gfedcbZ"|

# 解説
※解説は私が作成したコードなので、もっといいアルゴリズム等々ありましたら、共有してください！

### 方法１
```java

class Solution {
    public String solution(String s) {
        return Stream.of(s.split("")) // 文字列を1文字ずつ分割
            .sorted(Comparator.reverseOrder()) // 降順にソート
            .collect(Collectors.joining()); // 分割した文字列を1つの文字列にする。
    }
}
```

### 方法２
```java

class Solution {
    public String solution(String s) {
        char[] sol = s.toCharArray(); // 文字列からchar配列を取得
        Arrays.sort(sol); // "Zbcdefg"

        // StringBuilderのreverseを利用して逆順にする。
        return new StringBuilder(new String(sol)).reverse().toString();
    }
}
```
※個人的には「方法１」のほうが簡略で読みやすくて好きですが、
速度のほうは「方法２」のほうが早いですね。