OmniAICreator/Qiita-1.07M huggingface dataset:
IntellijでSpringBootプロジェクトを作成してGithubにpushするまで

# 概要
SpringBootを使ったプロジェクトの環境構築の手順をまとめました。
手順をよく忘れるので自分用にGithubにpushするところまで書きます。


# 環境
Spring Boot 2.3.1 (Spring Framework 5.2.7)
Java11 (OpenJDK 11.0.2)
Intellij Community Edition 2019.1.3

Java11が入っていない方は以下の記事が参考になります。
[OpenJDK 11 を Homebrew で macOS にインストールする](https://qiita.com/niwasawa/items/fed67553845f8d1b72bc)

# プロジェクト作成
Intellij Ultimate Editionの方はSpring Initizalizrでも構いません。

「Spring Assistant」のプラグインをインストールします。
<img width="959" alt="スクリーンショット 2020-06-20 22.24.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440811/0a00725f-b8aa-6932-d9b6-6a463cf8abf4.png">
<img width="797" alt="スクリーンショット 2020-06-20 22.25.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440811/b2739f71-da6b-efb5-d5ba-3d99ed140621.png">

Intellijをリスタートしてプロジェクトを新規作成します。 
Spring Assistantを選ぶとSpring Initializrのように簡単にプロジェクトが作成できます。
設定値は
- Project SDK: 11.0.2
- Spring Initializr Server: Default

を選択します。

依存関係は後から追加できるので最低限のものだけ追加します。
私はSpring Webを入れました。

# GithubにPUSHする
先にGithubで新しいリポジトリを作成します。
<img width="1395" alt="スクリーンショット 2020-06-20 22.40.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440811/f15f32af-0a48-3997-feab-8e5cb2591def.png">
既存のリポジトリをpushする方を使います。
先ほど作成したローカルのリポジトリで以下コマンド実行します。

```
git init
git add .
git cm -m "initial commit"
git remote add origin git@github.com:pandarkness/sample.git
git push -u origin master
```

動作するSpringアプリケーションを簡単に作成できました。
【MySQL】Mysql2::Error::ConnectionError: Access denied for user ～への対処法【環境構築】

##はじめに
ポートフォリオ制作のためDockerにて新たに環境構築をしました。今回は新たにWEBサーバーにnginxを導入して構築しました。（Docker+Rails6+puma+nginx+mysql）
その際起きたデータベース接続エラーにかなり時間をとられてしまったので同じエラーで悩んでる方のためにも対応策を書き留めておこうと思います。

**環境**

- windows10 Pro
- Rails: 6.0.3.2
- ruby: 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
- Docker for windows
- MySQL 5.6
- nginx:1.15.8

##データベース接続エラー
[こちらの記事](https://qiita.com/kohki4115/items/c37ff8550b01bbc75df2)を参考に環境構築を進めていた時
```docker-compose exec app rails db:create``` をしたら以下のようなエラーが発生しました。

```
Mysql2::Error::ConnectionError: Access denied for user 'ユーザー名'@'%' to database 'webapp_development'
Couldn't create 'webapp_development' database. Please check your configuration.
```
どうやらデータベースにアクセスを拒否されてDBの作成に失敗したようです。DBのvolumeを削除してコンテナ再起動してみたりするも変わらず、、パスワードもちゃんと設定してあっているしタイポもしてないしいったいなぜ拒否されたんだろう？とだいぶ悩みました。volumeを削除してコンテナ再起動してみたりするも変わらず、、

##原因
結論から言いますと原因は**DBへアクセスするユーザーに権限がなかったから**です。（**ちなみにdbのvolumeも一旦削除する必要があります。**DBコンテナの仕組み上そうしなければならないようです（postgresqlとかも））
ここに気付くまでだいぶ時間がかかってしまいました。おそらく僕と同じように独学で勉強している方だと同じ場面でかなり悩むと思います。

##解決策
dbのvolumeを削除しコンテナを再起動後、DBへアクセスできるように**ユーザーに権限を付与**すればいいだけです。
まず、コンテナが停止していたら起動し、コンテナ内に入りルートユーザーでMySQLに接続します。

```
docker-compose up -d
docker-compose exec db bash
root@b8d3d3c0300f:/# mysql -u root -p
```

パスワードを設定している人は-pオプションを付けてパスワードを入力してください。
いつものmysqlの画面になります。

```
Welcome to the MySQL monitor.  Commands end with ; or \g.
．．．
（中略）
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

ここでユーザーについている権限を確認します。

```
mysql> SHOW GRANTS for 'hoge'@'%';
+----------------------------------+
| Grants for hoge@%                |
+----------------------------------+
| GRANT USAGE ON *.* TO 'hoge'@'%' |
+----------------------------------+
1 row in set (0.00 sec)
```

```SHOW GRANTS for　'ユーザー名'@'%';```でそのユーザーに付与されている権限を確認することができます。
上のUSAGEというのは何も権限がないことを意味しており、これがDB接続エラーの原因だったのです。
このユーザーにすべての権限を付与（スーパーユーザー）します。

```
mysql> GRANT ALL ON *.* TO 'kiyo'@'%';
```

権限を確認します。

```
mysql> SHOW GRANTS for 'kiyo'@'%';
+-------------------------------------------+
| Grants for kiyo@%                         |
+-------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'kiyo'@'%' |
+-------------------------------------------+
1 row in set (0.00 sec)
```

ALLはすべての権限を意味しますのでしっかりと権限付与できていることが確認できます。
これで完了です！
最初に権限を確認したとき、USAGEになっていた方はおそらくこれで接続できるようになると思います。

##最後まで読んでいただきありがとうございました。
この記事を読んで少しでも解決になれば幸いです！また何か解釈に誤りなどございましたらご指摘いただけると幸いです。
GitLabでSlack通知する仕組みを作った話

自分はSlack通知botをよくGASで作っているのですが、GASだと社内オンプレサービスに接続できない事が多いと思います。今回、社内オンプレにつながるGitLabを使ってSlack通知できたので、それをまとめたいと思います。

# GitLab のパイプラインスケジュールを活用

GitLab には[パイプラインスケジュール](https://docs.gitlab.com/ee/ci/pipelines/schedules.html)という機能があります。これを使って特定日時に社内サービス(RedmineとかJIRAとか)にアクセスして、そのレポートをSlackに通知します。

## 環境変数の設定

このパイプラインスケジュールにはスケジュールごとに環境変数を設定できます。例えばSlack のWebhookが設定されている場合だけSlackに通知するようにして、それ以外は標準出力に出力するようにしておけば、デバッグ時は標準出力で確認できて、スケジュール起動のときはSlackに通知するようにできます。

# 感想

GitLab 便利ですね。もっと色々活用したいです。
おじさん会社員の略歴

##はじめに
[AtCoderの軌跡](https://qiita.com/gtkr/items/228d16314576974e9b07)を書くにあたって、見ている人にどんなエンジニアが挑戦しようとしているのか知ってもらうのも意味があるかと思いました。

##どんなプログラミング人生
* 19歳(2006)：大学の電気電工学科に入学、プログラミングに触れ面白いと感じた。[「解きながら学ぶC言語」](https://www.yodobashi.com/product/100000009002517946/?gad1=&gad2=g&gad3=&gad4=56278881131&gad5=11146226555728688687&gad6=&gclid=CjwKCAjw57b3BRBlEiwA1ImytolLDr764uOjp1s59WJrjktj-B316pEgE1Ewzu3FNxoLRrRRVgSu0RoCBmIQAvD_BwE&xfr=pla)という本で問題形式で学習したおかげで、ポインタとかを正確に学べて挫折せずにすんだと思う。
* 20歳(2007)：アルゴリズムの授業に興味を持つ。[林晴比古さんのアルゴリズムの本](https://www.amazon.co.jp/C%E8%A8%80%E8%AA%9E%E3%81%AB%E3%82%88%E3%82%8B%E5%AE%9F%E7%94%A8%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E5%85%A5%E9%96%80-%E6%9E%97-%E6%99%B4%E6%AF%94%E5%8F%A4/dp/4797328290)に惚れる。だが、勉強したアルゴリズムの活用先は思いつかず...
* 23歳(2010)：暫くプログラミングはしておらず、1留して研究室に配属。研究室のゼミで数独を解くプログラムを作るという課題で、3年前に勉強したバックトラック法が活躍。卒業研究でHough変換やクラスタリング等の画像処理を学ぶ。
* 24歳(2011)：大学院に進学し路車間通信(V2I)の研究を行う。その過程で、車両挙動やパケット通信のシミュレーションをJavaで開発。
* 26歳(2013)：精密機械メーカーに就職。GUIから制御盤までC#でECU検査装置の全体を開発する。
* 27歳(2014)：ECU本体の開発で組み込みプログラミングと、FPGAのHDLを経験する。
* 28歳(2015)：FPGAによる車載カメラ画像処理や、[組込みOS入門](https://www.amazon.co.jp/12ステップで作る組込みOS自作入門-坂井-弘亮/dp/4877832394)のOSを別CPUに移植&拡張などの開発を行う。
* 29歳(2016)：心機一転、自動車会社に転職し、自動運転の行動計画・制御系エンジニアになる。転職の際は[この本](https://www.amazon.co.jp/IT%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E7%90%86%E8%AB%96%E5%85%A5%E9%96%80-%E4%B8%AD%E4%BA%95-%E6%82%A6%E5%8F%B8/dp/4774176982/ref=asc_df_4774176982/?tag=jpgo-22&linkCode=df0&hvadid=295719984664&hvpos=&hvnetw=g&hvrand=12788238610820555811&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009235&hvtargid=pla-524758677282&psc=1&th=1&psc=1)で勉強。流行りの深層学習ではなく、理論がしっかりとした機械学習の本で勉強したのは本当に良かった。
* 30歳(2017)：自動運転への強化学習の応用について研究する。入門書ではないが、[この本](https://www.amazon.co.jp/%E3%81%93%E3%82%8C%E3%81%8B%E3%82%89%E3%81%AE%E5%BC%B7%E5%8C%96%E5%AD%A6%E7%BF%92-%E7%89%A7%E9%87%8E-%E8%B2%B4%E6%A8%B9/dp/4627880316)はためになると思う。
* 31歳(2018)：自動運転の車両制御開発を行う。Simulinkを必死に習得。←慣れると制御系の開発は本当に便利。
* 30歳(2019)：ROSで開発を行うことになる。ROSは便利ですねー。
* 33歳(2020)：さて、これからどうするか！

##総括
そこそこ色々な経験はしてきたなー、と感じます。
業務上書けないこともありますが、自分が得てきた知見をできるだけ発信して、貢献&アピールができればいいな、と思っています。
AtCoderは20代の若い人たちが多いようです。30代のおじさんの経験が負けないように頑張ります！
【Laravel】ルーティングの書き方

# 概要
Laravelにおけるルーティング周辺について書いていくよ
初心者向けの内容だよ
# routing
ルーティングとは、クライアントからのアクセスに対応してどういう処理をするか決めること
例えば、「http://.../○○というアドレスにアクセスしたら、××コントローラの△△アクションを実行する」みたいな感じ
ルーティングが記述されたファイルは、routesフォルダのweb.phpだよ

※以下のソースコードで、デフォルトのnamespaceやuseは省略
## 基本
```php:routes/web.php
// (1)
Route::get('/', function() {
  return view('welcome');
});
// (2)
Route::get('/', 'HelloController@index');
```
書式は以下の通り

```php:
// (1)
Route::get('path', クロージャ); // クロージャの中にpathに対応する処理を書く
// (2)
Route::get('path', 'コントローラ名@アクション名');
```
HTTP動詞に対応して

- Route::get
- Route::post
- Route::put
- Route::patch
- Route::delete

などが同様に使える
(1)のクロージャの中の関数viewは引数にテンプレート名をしてすることでレンダリングされる
つまり、(1)は「'/'にアクセスされたらテンプレート'welcome'をブラウザに表示させる」ということ
(2)は「'/'にアクセスされたら、Helloコントローラのindexアクションを実行する」ということ
Helloコントローラは、例えば、以下のような感じ

```php:app/Http/Controllers/HelloController.php
class HelloController extends Controller
{
    public function index() {
        return view('welcome');
    }
}
```

(1)と(2)の使い分けは、ビューだけを表示させるなら(1)、処理が多いと(2)とかかな
本格的なアプリだとモデル使うので確実に(2)を使うし、ビューだけ表示させることが少ないなら(2)に統一したほうが見やすいよね

[Readouble](https://readouble.com/laravel/7.x/ja/routing.html)によると、ビューを返すだけならRoute::viewを使うといいらしいので(1)の出番はほぼないね(とは言っても一応説明はしておく)

```php:
Route::view('/', 'welcome', ['param'=>'Hello']);
Route::view('path', 'テンプレート名', パラメータ); // パラメータは任意
```

## 必須パラメータ
```php:routes/web.php
// (1)のタイプ
Route::get('index/{msg}', function($message) {
    return view('hello.index', ['msg'=>$message]);
});
```

上の例だと、「'/index/test'とアクセスされたら、'test'が\$messageに代入されて、helloフォルダのテンプレート'index'をブラウザに表示する」ということになる
この時、テンプレート'index'内の\$msgに\$message(つまり'test')が代入されるよ
見ればわかるけど、パラメータ名とクロージャの引数の名前は一致しなくてもいい
複数のパラメータがあると、順に代入される

```php:
Route::get('index/{id}/{name}', function($param1, $param2) {
    return view('hello.index', ['id'=>$param1, 'name'=>$param2]);
});
```
例えば、上の例だとidは\$param1、nameは\$param2に代入される
(2)のタイプも以下に示しておこう

```php:routes/web.php
// (2)のタイプ
Route::get('index/{msg}', 'HelloController@index');
```
```php:app/Http/Controllers/HelloController.php
class HelloController extends Controller
{
    public function index($message) {
        return view('hello.index', ['msg'=>$message]);
    }
}
```

## 任意パラメータ

パラメータの後ろに?をつけると、そのパラメータがなくてもルーティングが通る

```php:routes/web.php
// (1)のタイプ
Route::get('index/{msg?}', function($message='Hello') {
    return view('hello.index', ['msg'=>$message]);
});
```

上の例だと、'/index/test'というパスも'/index'というパスもエラーを出すことなく通る
ただし、代入先の変数はデフォルト値を与えておく必要がある（上の例では'Hello'をデフォルトにしている）
(2)のタイプも以下に示そう

```php:routes/web.php
// (2)のタイプ
Route::get('index/{msg?}', 'HelloController@index');
```
```php:app/Http/Controllers/HelloController.php
class HelloController extends Controller
{
    public function index($message='Hello') {
        return view('hello.index', ['msg'=>$message]);
    }
}
```

# おわり

ルーティングの基礎について書いてみました
簡単なアプリであれば、Route::getとRoute::postだけあればいける
私は今のところ(2)のタイプしか使わないね
OracleCloudをTerraformで構築する

# 背景
TerraformでOracleクラウドを構成しようとした。
ociコマンドを使って鍵を作る手順が一番簡単だったので紹介する。

## 事前準備
テナンシのOCIDとリージョン情報を準備する。

> テナンシのOCIDとユーザーのOCIDを取得する場所
> https://docs.cloud.oracle.com/ja-jp/iaas/Content/API/Concepts/apisigningkey.htm#five

## 手順

### プロファイルとPEMキーの作成

```
% oci setup config
```
してプロファイルを作る。
次へ次へで良い。パスフレーズは入力しないほうが後々楽。
画面の指示通り進めれば、この過程でPEMキーが作成される。


### PEMキーの登録
Web管理画面にてPEMキーの登録を行う。

<img width="1019" alt="ユーザー___Oracle_Cloud_Infrastructure_と_Default__zsh_.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576356/dc9efc20-b998-f7e1-9d5d-44819d229ec3.png">

1. 画面右上のユーザボタンをクリックして[ユーザ設定]を選択する。
2. ユーザ管理画面より左下の[APIキー]をクリックして表示される画面にて[APIキーの追加]をクリックする
キーの選択画面にて前の手順で作成したPEMキーを選択する。セットアップ通り作成していれば```/Users/ユーザ名/.oci/oci_api_key_public.pem```に保存されている

### Terraformへ反映
``` cat ~/.oci/config``` の結果を参考に、以下の通りTerraformに反映する。

```
variable "fingerprint" { default = "＜fingerprintの値を記載＞"}
variable "private_key_path" { default = "/Users/ユーザ名/.oci/oci_api_key.pem"}
variable "tenancy_ocid" { default = "＜tenancyの値＞"}
variable "region" { default = "＜regionの値＞"}
```

## サンプルTerraform
https://github.com/terraform-providers/terraform-provider-oci/tree/master/examples/always_free
上記スクリプトのままだとエラーが出るので、以下の通り書き換える。

```
ssh_authorized_keys = file(var.ssh_public_key)
```

### SSH接続方法

```
% terraform output                    
 app = http://xxx.xxx.xxx.xxx
```
appのIPアドレスに次のコマンドでSSHする。

```
$ ssh opc@xxx.xxx.xxx.xxx -i ~/.ssh/id_rsa
```

# トラブルシュート

```
Error: Service error:NotAuthorizedOrNotFound. shape VM.Standard.E2.1.Micro not found. http status code: 404
```
下記の番号を変える。

```
variable "ad_region_mapping" {
  type = map

  default = {
    us-phoenix-1 = 2
    us-ashburn-1 = 1
    us-seattle-1 = 2
  }
}
```
# 参考リンク

- https://github.com/oracle-quickstart/oci-quickstart
AtCoder 生活　81日目

[前回](https://qiita.com/flandrescarlet237/items/98a86050ae02f191039d)

#81日目
今回は茶色diffの問題を4問解きました。

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|ABC045|B|◯|20分20秒|
|ABC058|C|✕|81分21秒|
|ABC047|C|✕|30分46秒|
|ARC013|B|◯|56分11秒|



##[ABC045_B](https://atcoder.jp/contests/abc045/tasks/abc045_b)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    string a,b,c;
    cin >> a >> b >> c;
    char now = 'a';
    char ans;
    bool ok = true;
    while(ok){
        if(now == 'a'){
            if(a.size() == 0){
                ok = false;
                ans = 'A';
            }
            else{
                now = a[0];
                a = a.substr(1);
            }
        }
        if(now == 'b'){
            if(b.size() == 0){
                ok = false;
                ans = 'B';
            }
            else{
                now = b[0];
                b = b.substr(1);
            }
        }
        if(now == 'c'){
            if(c.size() == 0){
                ok = false;
                ans = 'C';
            }
            else{
                now = c[0];
                c = c.substr(1);
            }
        }
    }
    cout << ans << endl;
}

```

解くのにかかった時間：20分20秒


##[ABC058_C](https://atcoder.jp/contests/abc058/tasks/arc071_a)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int n;
    cin >> n;
    vector<map<char,int>> d(n);
    rep(i,n){
        string s;
        cin >> s;
        rep(j,s.size()){
            d[i][s[j]]++;
        }
    }
    map<char,int> m = d[0];
    for(auto x:m){
        char k = x.first;
        rep(i,n) m[k] = min(m[k],d[i][k]);
    }
    for(auto x:m){
        rep(i,x.second) cout << x.first;
    }
    cout << endl;
}

```

解くのにかかった時間：81分21秒
感想：なかなかこの問題を解けるように慣れない


##[ABC047_C](https://atcoder.jp/contests/abc047/tasks/arc063_a)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    string s;
    cin >> s;
    int cnt = 1;
    rep(i,s.size()-1){
        if(s[i] != s[i+1]) cnt++;
    }
    cout << cnt - 1 << endl;
}

```

解くのにかかった時間：30分46秒
感想：これは自力で気づくべきだった。


##[ARC013_C](https://atcoder.jp/contests/arc013/tasks/arc013_2)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int c;
    cin >> c;
    int x = 0,y = 0,z = 0;
    rep(i,c){
        vector<int> a(3);
        cin >> a[0] >> a[1] >> a[2];
        sort(a.begin(),a.end());
        x = max(x,a[0]);
        y = max(y,a[1]);
        z = max(z,a[2]);
    }
    cout << x*y*z << endl;
}

```

解くのにかかった時間：56分11秒


###最後に
速く解けるようにして早く茶色になりたい

難易度|かかった平均時間|解けた問題数|
|:-:|---|---|
|B|38分15秒|2問中2問|
製薬企業研究者がRDKitについてまとめてみた

# はじめに

ここでは、ケモインフォマティクスに不可欠なRDKitについて解説します。
Pythonを用いた基本的な方法についてまとめていきます。


# インストールとインポート

RDKitを利用するには、Anacondaをインストールして、`conda`でインストールするのが良いでしょう。

```bash
$ conda install -c rdkit rdkit
```

利用するときは、以下のようにインポートします。

```python
from rdkit import Chem
```


# 分子の読み込みと書き込み

例えば、SMILESで示された化合物の構造をpngファイルとして保存するには、以下のようにします。

```python
from rdkit import Chem


molecule = Chem.MolFromSmiles(化合物のSMILES)
Chem.Draw.MolToFile(molecule, 'ファイル名.png')
```

また、molファイルから作成することもできます。

```python
from rdkit import Chem


molecule = Chem.MolFromMolFile(化合物のmolファイル)
Chem.Draw.MolToFile(molecule, 'ファイル名.png')
```


# 化合物の記述子の計算

SMILESで読み込んだ化合物の記述子を計算するには、以下のようにします。

```python
from rdkit import Chem
from rdkit.ML.Descriptors import MoleculeDescriptors


smiles_list = [対象化合物のSMILESのリスト]
target_descriptors = []
for desc in Chem.Descriptors.descList:
    target_descriptors.append(desc[0]) # descは、記述子名と関連情報のタプルになっている。
print(len(target_descriptors))
print(target_descirptors)

descriptor_calculator = MoleculeDescriptors.MolecularDescriptorCalculator(target_descriptors)
descriptors = []
for smiles in smiles_list:
    molecule = Chem.MolFromSmiles(smiles)
    descriptors.append(descriptor_calculator.CalcDescriptors(molecule))
print(descriptors)
```


# まとめ

ここでは、PythonでRDKitを利用する方法について解説しました。
この内容が理解できれば、化合物の記述子計算が簡単にできるようになりますよ。


# 参考資料・リンク

[ケモインフォマティクスは製薬企業でどう役立つ？どんな知識が必要？](https://pharma-engineer.com/chemoinformatics/medicinal-chemistry-summary/)
Rubyでトリボナッチ数列の問題を解いてみた、再帰で。

「[Rubyでトリボナッチ数列の問題を解いてみた(制限時間10分)](https://qiita.com/keisuke_oyatu/items/43c0100f885c2050b956)」という記事を見て、再帰で書きたいな、と思ったのでカキコ... というのは嘘で、本当はトリボナッチっていうものを知らなかったので、焦って書きました。

# コード
```ruby
# Tribonacci
def tribonacci n
  if n == 1
    return 1
  elsif n == 2
    return 1
  elsif n == 3
    return 2
  else
    return tribonacci(n - 3) + tribonacci(n - 2) + tribonacci(n - 1)
  end
end

p (1..10).map{|n| tribonacci n } # => [1, 1, 2, 4, 7, 13, 24, 44, 81, 149]

# Unit Test
require 'test/unit'

class TC_Foo < Test::Unit::TestCase
  def test_one
    assert_equal tribonacci(1), 1
  end

  def test_two
    assert_equal tribonacci(2), 1
  end

  def test_three
    assert_equal tribonacci(3), 2
  end

  def test_ten
    assert_equal tribonacci(10), 149
  end
end
```

# おわりに
末尾呼出し最適化は？とか、メモ化は？とか、そもそも再帰でなくてループで書けよ！、せっかくの機会だから Haskell か Elm で書けよ！、イテレーターで書けば？とかそんな内なる声は無視する。なぜなら、自分は10分でそれらをやる自信がないからね！

#【PR】**[HP12c を讃えよ](http://melborne.github.io/)**
[Rubyのrepeat関数でフィボナッチ、トリボナッチ、テトラナッチ！](http://melborne.github.io/2011/07/01/Ruby-repeat/)
Windows版Wireguardで接続/切断をコマンドでやる

調べたのでメモ。トンネルを独立したサービスとして登録する方法で実現します。

# 準備
## Wireguardを入れる
公式のバイナリを普通にインストールします
https://www.wireguard.com/install/

## 接続用CONFを準備
トンネルを張るためのCONFファイルを準備します。
ここでは例として`"C:\Program Files\WireGuard\vpntest.conf"`とします

## 接続用サービスを作成
管理者権限で下記コマンドを実行します。
`"c:\Program Files\WireGuard\wireguard.exe" /installtunnelservice "C:\Program Files\WireGuard\vpntest.conf"`

管理ツールのサービスを開いて、 `WireGuard Tunnel: vpntest` という名でサービスが作成されていることを確認します。
![ss1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212876/cfa23e31-deda-bc0d-85bf-d9d690c26970.png)

## 起動時に自動接続しないようにする
そのままでは起動のたびに自動接続してしまうので、サービスのスタートアップを手動に設定します。
![ss2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212876/2fade61d-92ad-81aa-f2af-cb169058befc.png)


# 接続/切断のコマンド
いずれも管理者権限が必要です
## 接続
`net start "WireGuard Tunnel: vpntest"`
## 切断
`net stop "WireGuard Tunnel: vpntest"`

# 補足
- サービスが不要になった場合は下記コマンドで登録解除します<br>
`"c:\Program Files\WireGuard\wireguard.exe" /uninstalltunnelservice vpntest`
- タスクトレイのGUIからは接続状態は確認できませんので、`wg`コマンドで確認します。
- `WireGuard Manager`サービスも"手動"に変更するとタスクトレイのアイコンを隠すことができます。
Dronecode Devマニュアル抜粋&翻訳 - PWM_limit State Machine

#この記事は
前回の [Mixing and Actuators](https://qiita.com/sakaeda11/items/e6576de0a73f4a92af70) に引き続き、
Dronecode本家サイトの[PWM_limit State Machine](https://dev.px4.io/master/en/concept/pwm_limit.html)ページの抜粋・翻訳です。

※主に自分の理解用に書いています。

# PWM_limit State Machine
**PWM_limitステートマシン**は、pre-armed入力とarmed入力の関数としてPWM出力を制御します。 「"armed"のアサーション」と、「armedのアサーション時のスロットルのranmp-up」との間に遅延を提供します。

("armed"のアサーションというのが何を指すのかよくわからない。。。)

## Quick Summary

### Inputs
- armed: プロペラの回転など危険な動作を可能にさせるアサート
- pre-armed: コントロールサーフェスの移動などの良性動作を有効にするようなアサート
    - この入力は現状の状態を上書きします
    - pre-armedのアサートは、現在の状態に関係なく、ただちに状態ONの動作にします
    - pre-armedのアサート解除により、動作が現在の状態に戻ります

### States
- INIT and OFF
    - disarmed値に設定されたpwm出力
- RAMP
    - pwmは、disarm値から最小値にランプアップします。
- ON
    - 制御値に従って設定されたPWM出力

## State Transition Diagram
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124098/1b6d4ee7-6e4c-bfe9-b321-d90c67ba5e10.png" width=70%>

Note:
pre_armed入力は、アサートされている間、現在の状態をオーバーライドします。アサート解除されると、ステートマシンは正常に機能します。 pre_armedがアサートされている間は、スロットルコントロールをNaNに設定する必要があります。
位置情報を活用したIoT水耕栽培のアイデア

#初めに
本コンテンツはSORACOM Summer Challenge 2020向けに作成したものです。

筆者は親元を離れているので自炊が当たり前になる。そうなるとやはり困るのが食費である。なんとか安くできないかなと考えているので、そのアイデアをここに記そうと思う。

#概要
RasberryPi・GPSマルチユニットSORACOM Edition・ポンプなどを活用し、GPSを利用し位置情報を取得、アメダスAPIにアクセスし、状況に応じて水量などを変える自動水耕栽培器の作成

#設計図
以前、大学の助成金で作成を考えていた水耕栽培器の設計図があるので、それを載せておきます。
<img width="586" alt="設計図.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659464/29465e9e-34a1-1a93-d66b-bdef714adebd.png">
※設計はだいぶ前なので、SORACOM Summer Challengeにあわせて大幅に変えるとは思いますが...。

#実現したいこと
* 野菜の自動栽培（おそらく手間などを考えて葉物野菜）
* 天気・気温・湿度などのデータ取得とそれによる水やり調整（ベランダで栽培するつもりなので重要）
* Googleスプレッドシートから温度や画像などの管理・記録

#詳しくはこちら
[水耕栽培設計ノート 2020/07/06更新](
https://docs.google.com/presentation/d/e/2PACX-1vRM_niaZEL6oByfRLqFk98909f8_tOJrGbrFQiMs5IrmHvtFnb68F3-IRS77Fw_7w/pub?start=false&loop=false&delayms=3000&slide=id.p10)
気が向いたら更新します
OutSystemsのReactive Web AppにおけるRoleのチェック

Reactive Web Appはクライアントサイドでの動作がメインとなっているため、Roleの使い方にTraditional Webとの違いがあるのか確認してみました。

# Reactive Web AppでのRoleチェック方法のまとめ
ログインユーザーがRoleを持っているかどうかの判定は、基本的にはサーバーサイドで行う。
このとき、Roleに付属するCheck<Role名>を使用する。

JavaScript APIを使うことでクライアント側でも判定できるが、これは、恐らくログイン時に保存しておいた情報で判定している。
そのため、確実な判定が必要なとき（サーバーのマスタに更新かけるときとか）には使えない。
画面ごとのRoleチェックは、ScreenのRole名チェックボックスで設定する。

# 各Roleチェック方法の検討
## ScreenのRole許可
画面ごとにアクセスできるユーザーのRoleをScreenの設定で指定できます。Traditionalと同じですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/d3fe365c-837d-6848-fad2-f5a3b88f96c3.png)

ちなみに、指定のRoleがないユーザでアクセスすると、画面のOnInitializeイベントよりも前にSecurityExceptionが発生するようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/ebac9434-c8d7-72fd-553b-92942af19ee3.png)

## Roleに付属するCheck<Role名> Function
RoleをService Studioで定義したときに、Roleに付属して自動作成されるCheck<Role名> Function。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/87603393-882f-748b-b726-fdcf28ac6478.png)
特定のユーザーにそのRoleが与えられているかどうかを判定することができます。
パラメータは対象ユーザーのUserId。
（ログインしているときは、GetUserId()を呼ぶことでログイン中ユーザーのUserIdが取得可能）

Client Action Flow内にドロップできないため、Server ActionでRoleチェックを行うことになります。

[公式ドキュメント](https://success.outsystems.com/Documentation/ja-jp/11/Developing_an_Application/Secure_the_Application/User_Roles/Create_and_Use_Roles)には、この点の記術がありませんが……。

## CheckRole Function
Check<Role名>とにていますが、こちらは第一引数にRoleを指定する一般形。
[CheckRoleの公式ドキュメント](https://success.outsystems.com/Documentation/ja-jp/11/Reference/OutSystems_Language/Logic/Built-in_Functions/Roles#CheckRole)

OutSystems APIのドキュメントには、そのAPIがどこで使えるか、という記述があります。
上記ドキュメントには、以下の記述があります。この記述によると、やはりClient Actionでは使用できない。

> 利用可能箇所:

> サーバー側ロジック: Yes
> クライアント側ロジック: No

## JavaScript API
Reactive Web App上のJavaScriptフロー要素で使えるJavaScript APIが公式に提供されています。
JavaScript APIの各オブジェクトは、`$public`の下に定義されています。ただし、JavaScriptフロー要素内でしか使えないようで、例えばブラウザの開発者ツールのconsoleで`$public`と入力してもオブジェクトは参照できません。
[checkIfCurrentUserHasRole](https://success.outsystems.com/Documentation/11/Reference/OutSystems_APIs/JavaScript_API/Security)

この中にログイン中のユーザーに特定のロールがあるかを判断するAPIとしてSecurityオブジェクトのcheckIfCurrentUserHasRole関数が提供されており、以下のように使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/585b88de-8479-d745-38f3-9712eddfe3aa.png)

checkIfCurrentUserHasRole関数に渡すパラメータは、ログイン中のユーザーが保持しているかを判定するロール。
ロールは、`$roles.<Role名>`で指定してください。

重要なことは、このAPIを実際に呼んでみると、ネットワーク通信が発生しないこと。
つまり、恐らくログイン時に保存しておいたロール情報をもとに判定しているのでしょう。そうなると、重要な判定（DB更新とか個人情報表示とか）には使わないほうがいいですね。
一度ログインしたあと、Usersでログインユーザのロール情報を変更しても、ログアウトして再度ログインするまではこのAPIの判定には反映しないようです。
等値演算子のオーバーロードで null にハマった

C# で等値演算子をオーバーロードしたら null が引数に渡されたときハマってしまったので、その流れや解決策をメモ。

## 確認
まず、 C# では以下のようにして等値演算子（==）をオーバーロードすることができる。

```csharp
public static bool operator ==(Person a, Person b) {
  return a.Equals(b);
}
```

しかしこのサンプルコードでは、引数 a が null のとき `NullReferenceException` が発生する。

ここで正常な挙動を確認すると、以下のようになっている。

```csharp
// Random クラスを用いているのに特に意味はない.
Random r1 = null;
Random r2 = null;
Console.WriteLine(r1 == r2); // True
Console.WriteLine(r1.Equals(r2)); // NullReferenceException
```

このことから、サンプルコードのように愚直に `Equals` メソッドを呼び出すわけにはいかない。

## 試行

では以下のようにしてみるとどうだろう。

```csharp
public static bool operator ==(Person a, Person b) {
  if (a == null) {
    return b == null;
  } else {
    return a.Equals(b);
  }
}
```

このコードは、実行してみれば分かるが、引数 a、b の内容によらず `StackOverflowException` が発生する。
それは、a や b が null かどうかを判定する条件式で等値演算子を使うことによって、無限ループ（無限再帰）を作り出しているためである。

## 解決策

再帰呼び出しを回避しつつ、null 判定をすることができるのが、 `ReferenceEquals` メソッドである。
`ReferenceEquals` メソッドは **参照の**等価性を評価するため、null の変数は参照も null であるから、正しく判定をすることができる。

```csharp
Random r1 = null;
Random r2 = null;
Console.WriteLine(ReferenceEquals(r1, null)); // True
Console.WriteLine(ReferenceEquals(r2, null)); // True
Console.WriteLine(ReferenceEquals(r1, r2)); // True
```

以上のことから、等値演算子をオーバーロードする際には、以下のようにすると良い。

```csharp
public static bool operator ==(Person a, Person b) {
  if (ReferenceEquals(a, null)) {
    return ReferenceEquals(b, null);
  } else {
    return a.Equals(b);
  }
}
```

## 非等値演算子

サンプルコードでは省いていたが、等値演算子をオーバーロードするときには、非等値演算子も同時にオーバーロードする必要がある。
ここでは再帰にならないため、以下のように簡潔に実装することができる。

```csharp
public static bool operator !=(Person a, Person b) {
  return !(a == b);
}
```

## おまけ（Equals）

`Equals` メソッドをオーバーライドするときにも、同じ方法を使ったほうが良い。
等値演算子をオーバーロードしている状態で以下のように実装すると、引数 obj が null でないとき、何度か再帰呼び出しをすることになる。

```csharp
public override bool Equals(object obj) {
  Person person = obj as Person ;
  if (person == null) {
    return false;
  } else {
    return person.Id == this.Id;
  }
}
```

無限ループに陥ることはないので問題はないが、以下のようにして回避することができる。

```csharp
public override bool Equals(object obj) {
  Person person = obj as Person ;
  if (ReferenceEquals(person, null)) {
    return false;
  } else {
    return person.Id == this.Id;
  }
}
```

または、そもそも as 演算子ではなく is 演算子を使うことでも回避できる。
（記事を書いていて気づいた）

```csharp
public override bool Equals(object obj) {
  if (obj is Person person) {
    return person.Id == this.Id;
  } else {
    return false;
  }
}
```

## まとめ
`hoge == null` ではなく `ReferenceEquals(hoge, null)` を使おう。

## 参考
https://docs.microsoft.com/dotnet/api/system.object.referenceequals
https://docs.microsoft.com/dotnet/csharp/language-reference/operators/equality-operators
https://docs.microsoft.com/dotnet/csharp/programming-guide/statements-expressions-operators/how-to-define-value-equality-for-a-type
新・Railsポートフォリオ作成の備忘録①


#0.はじめに
以下記事の0.-01.をする。
https://qiita.com/Yuki0531/items/d948d2af298a50a0e9b5
（それ以降は見ないことw）

以下図面、設計書などを作成し、方向性を決めること
　1.ER図
　2.ガントチャート
　3.ワイヤーフレーム
　4.用件定義

#1.rails new

Mysqlを指定して、rails new アプリを作成した

```
$ rails new アプリ名 -d mysql
```

# 2.MYSQLのインストール
Mysqlをインストールした。
https://qiita.com/hkusu/items/cda3e8461e7a46ecf25d

# 3.データベースの環境設定

database.ymlのユーザーとパスワードを以下のように設定する。
（セキュリティの観点、共同作業を容易にする目的のため、環境関数を使用する）

```
username: <%= ENV['DATABASE_アプリ名(大文字)_DEV_USER'] %>
password: <%= ENV['DATABASE_アプリ名(大文字)_DEV_PASSWORD'] %>
```

この後、ターミナルでviコマンドを使用する。

```
vi ~/.bash_profile
```
以下追記すること

```
export DATABASE_"大文字のアプリ名"_DEV_USER='root'
export DATABASE_"大文字のアプリ名"_DEV_PASSWORD='mysqlのパスワードを記載'
```

viの基本操作は以下サイトがわかりやすい！
http://www.gi.ce.t.kyoto-u.ac.jp/user/susaki/command/vi.html

viから抜けたら、以下コマンドをターミナルで入力すること

```
$ sorce ~/.bash_profile
```

# 4. .gitignoreを書き換える

下記のサイトに基づいてrails用のgitignoreを作成する。
これをコピーし、アプリ直下にある.gitignoreを全て上書きする。
https://www.toptal.com/developers/gitignore

#5.Diviseによる複数ユーザーの会員登録機能の作成

当方が作成したポートフォリオ では、購入者と販売者のように複数のモデルを作成する必要があった。
以下、３つの記事を組み合わせて乗り越えた。

1. https://qiita.com/cigalecigales/items/f4274088f20832252374
この記事が、導入として素晴らしかった、しかし！！！

```
$ rails g devise:install 
```
上記コマンドが抜けていたので、後ほどrails db:migrateを入力しても上手くいかなかった。

2.困っていたところ、以下ページを見つけ、$ bundle install の直後に $ rails g devise:install が必要とわかる。
https://qiita.com/ryouzi/items/9c5324ba567109ab2a22

3.複数モデルを作成する為に、以下記事が素晴らしく参考になった。
https://qiita.com/Yama-to/items/54ab4ce08e126ef7dade
しかし、当方は最後の　rails d devise:viewsが上手くいかなかったので手動で不用なファイルを削除した。

＊diviseのマイグレーションをいじるとバグが起きやすい為、
　rails g migration add_column〜〜〜して、
　rails db:migrateをすること

＊Rails チュートリアル ６章のuserモデル作成のページでは
マイグレーションファイルに unique: true
has_secure_password
bcryptのgemfile
など言及されていたが、diviseでは認証に関するカラムは全て自動で生成されている為、作成する必要がなかった。
ユーザー名とか自己紹介分とかはないので追加しないといけない

*モデルのコードに全角空白があり、syntaxエラーが出た。
以下全角チェッカーで発見し、無事解決
https://ao-system.net/doublecharcheck/
オブジェクト指向言語でのメモリの仕組み

# 記事を書こうと思った理由
仕事でspring bootを使っており、その肝であるDI(Dependency Injection)では、
singletonデザインパターンが採用されており、デフォルトで1つしかインスタンスが生成されないという。
ネットで調べてもspring bootで状態を持つような実装をしてるとバグるみたいな記事がわんさか出てきた。
色々考えると、あれ？？？インスタンスは1個しか作られないけど、1つのAPIに対して同時リクエストとかされると、大丈夫か？どうなってんだ？？？と思ったりした。
たぶんメモリ配置がどこに？どの期間？というのが理解できていないためだと思ったので改めて整理した。
# メモリの仕組み（Javaベース）
まずは、メモリ領域
・静的領域
・ヒープ領域
・スタック領域

続いて、メモリへ展開するのも（だいたいなので、他にもありそうな）
1. コード情報（クラス本体）
2. グローバル変数
3. インスタンス
4. インスタンス変数(コンストラクタとかで指定)
5. ローカル変数
6. 各メソッドの引数
7. 戻り値

それぞれを表でまとめたのがこちら
![スクリーンショット 2020-06-20 21.57.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324175/b7e57227-d139-c03c-e175-12975110e34f.png)

ということで、改めて考えると、「状態を持ってはいけない」というのはインスタンス変数を持つような実装にすると、
バグるということで、５、６、７はリクエストのスレッド情報としてスタック領域に展開されるのでバグるとかの心配は無いですね。
# シングルトンを改めて考える
改めてシングルトンのデザインパターン眺めても、スッと頭に入ります。
グローバル変数として1つだけインスタンスを作製し、それはprivate変数になっているので再度作成されることもない。
getInstance()メソッドの呼び出すことで、先程、ヒープ領域に展開したインスタンスのアドレスをリターンしている。
spring bootのアノテーションで@Bean、@Controller、@Service、@Componentを各クラスに付与してあげると、内部ではこんな感じの動きになっていると思われる。

```singlton.java
public class Singlton{
private static Singlton singlton = new Singlton();
    private Singlton(){}
    public static Singlton getInstance(){
        return singlton;
    }
}
```

# おまけ　NARUTOの世界で考えてみた
●NARUTOで例えると・・
ナルト（本体）:コード情報
→色んな術（メソッド）を持っている。
ナルト（影分身体）：オブジェクト
→こなす仕事はそれぞれ異なる。
定期的に分身体を解除しないとナルト本体がチャクラ切れになる（発生するのはメモリリーク、定期的にオブジェクトを消すのはガベージコレクション）。
ナルト（影分身）の行動：ローカル変数など
→手裏剣投げるとか、術使うとかの行動。

###結論：NARUTOとは・・・object ninja!!!
型または名前空間の名前 'Android' が名前空間 'Xamarin.Forms.Platform' に存在しません



#結論
[パッケージを再インストールしましょうね～。](https://docs.microsoft.com/ja-jp/nuget/consume-packages/reinstalling-and-updating-packages
)

```
PM> Update-Package –reinstall
```
パッケージマネージャーコンソールからコマンドをぽちっとするだけ。

旧バージョンから新バージョンへとアップデートをした際に依存関係が崩壊する場合があるのでそれを修復するおまじない。


還暦を迎えた両親も最近喧嘩して依存関係が崩壊しかけたので、何かいいおまじないは無いでしょうか(´・ω・｀)ｼｮﾎﾞｰﾝ

###参照

https://oki2a24.com/2015/11/12/easily-update-nuget-package-with-command/
http://incomesoftdotnet.blogspot.com/2019/07/error-cs0234-android-2nd.html
vimを触ってみた　Vim日記Part.1

久しぶりにVimを触ってみました。
他の開発エディタがあるからvimなんていいじゃん。　と思っていたなんちゃってエンジニアです笑

触ってみると学ぶことがかなり多くてびっくりしたので、ここでvimの概念から触ったところまで共有させて頂きます。

結構内容もハードなのでvim日記のような形で定期的に掲載します！！


#Vimって何？


　vimとは、viから派生し発展した高性能なテキストエディタのことです。 イメージとしてはAtom,VisualStudioCode、IntelliJ IDEAの仲間ですね。

#特徴
特徴は上記のテキストエディタと比べるとCUI上でファイルの編集をすることに特化しているという点になります。


Vimの操作には、マウスの操作は必要にならないです。(これが個人的には楽ちんです笑)

必要な操作はコマンドを打ち込むことで実行できます。

マウスでほぼすべての操作が可能となるため、よりコーディングに専念しやすいことが特徴になると思います。
→この部分は個人差があると思いますが…


#CUIって何？
 先程の説明で CUIという単語が出てきました。

ではそもそもCUIって何？　って話になります笑

CUIとはcharacter user interfaceと呼ばれキーボード等からの文字列を入力できます。

文字列が表示されるウィンドウで印字される文字などを出力とする、ユーザインタフェースの様式となっています

良くGUIの対義語として使われます。

##長所
・処理の自動化が簡単

・すべてテキストなので容量が軽いです

・テキストデータなので、操作の記録を残しやすい

・テキストデータなのでコピペして複数人で共有しやすい

##短所
・初心者には操作が難しく、学習コストがかかってしまう

・直感的に分かりにくい 

#GUIって何？
 せっかくなので、GUIについての知識も共有しようと思います笑(余計なお世話なんて言わないでくださいね)

GUIとはGraphical User Interfaceの略であり、グラフィックベースの操作体系を持つUser Interfaceのことです。

情報の表示にグラフィックを多用しており、命令文を入力して実行する方式に比べ、かなり直感的に操作することが可能となります。

まぁ簡単にまとめると
「マウスや指で操作できる画面」

です！！

##長所
・グラフィカルでユーザに分かりやすい

・初心者やエンドユーザが操作しやすい

##短所
・プログラムの容量が多くなる

・動きが遅い

・バッチ処理には不向き



#簡単なコマンド一覧
話がそれてしまいました…　すいません

１．基礎操作
基礎操作はいかになります！！

| コマンド| (操作)|効果|
|:--|:--|:--|
| h|(左)|カーソルを左にずらす|
| j|(下)|カーソルを下にずらす|
| k|(上)|カーソルを上にずらす|
| l|()|カーソルを左にずらす|


2.入力と保存
次はVimの入力と保存です！！

| コマンド | 効果 |
|:--|:--|
| i | カーソルの場所からInsertModeに入る |
| x | カーソル直下の文字を消す |
| :w | ファイルの保存 |
| :q | 実行中のタブを閉じる |
| :wq | 上を組み合わせて保存して閉じること |
| :w! | 強制的に処理を終了 |

※ InsertMode：テキストを入力する際のモードの一つで、入力した文字を当該箇所に挿入していくモードのことです。
基本的にテキスト入力を行うソフトウェアのほとんどが標準的に採用しているモードとなっています。


３．Vimで使用するコマンド入力のモード
Vimは一切マウスを使わないことからコマンド入力モード・文字入力モード・選択モードとつのモードに分かれています。

| 名前 | 主な機能 | 起動の仕方 |
|:--|:--|:--|
| NormalMode：コマンド入力 | カーソルの移動 | Esc |
| InsertMode：文字入力 |テキストの入力、編集。 | a/i/A/I |
| VisualMode：文字選択 | テキストの選択。 | v |


#レッスン1!!
1.1 カーソルは矢印もしくはhjklを用いることでキーで移動することができます！！
　→基礎操作でコマンドは記入されているので省略させて頂きます。

1.2 Vim を起動するにはプロンプトから vim ファイル名 ENTER を押します

1.3 Vim を終了するには　ESC :q!　ENTERとタイプします
　　変更を保存する場合は ESC　:wq　ENTERとタイプします

1.4 カーソルの下の文字を削除するには、ノーマルモードで x とタイプします。

1.5. カーソルの位置に文字を挿入するには、ノーマルモードで i とタイプします。

| コマンド | (テキスト操作) | 効果 |
|:--|:--|:--|
| i | テキストのタイプ ESC | カーソル位置に追加 |
| A | テキストの追加　ESC | 行末に追加 |

※ ESCキーを押すとノーマルモードに移行します。その際、間違ったり入力途中のコマンドを取り消すことができます



#レッスン2!!
2.1 カーソル位置から単語の末尾までを削除するには dw とタイプします。

2.2  カーソル位置から行の末尾までを削除するには d$ とタイプします。

2.3 行全体を削除するには dd とタイプします。

2.4 モーションを繰り返すためには数値を付与：　2w

2.5 変更に用いるコマンドの形式は

```
オペレータ   [数値]   モーション
```
それぞれ：

```
オペレータ - 削除 d の類で何をするか。
数値     - そのコマンドを何回繰り返すか。
モーション - w (単語)や $ (行末)などの類で、テキストの何に対して働きかけるか。
```

2.6. 行の先頭に移動する時ゼロを使用します: 0

2.7 削除方法

```
前回の動作を取消す:       小文字の「u」 
行全体の変更を取消す:    　大文字の「U」
取消しの取消し:           「CTRL-R」
```

となります

#最後に
知っているようで、あんまり使用することがなかったので良い機会だったと思います。

せっかくなので今後はVimを使っていこうかな笑
それぐらいに使いやすいエディタだと思います！！

今度のPart２では更に深堀りをした内容を共有させて頂きます！！
おじさん会社員がAtCoderに挑戦する軌跡

##はじめに
COVID-19によって、世界が大きく変わらず負えない状況で、おじさんがエンジニアとして生き残っていく術を考えないといけないと感じています。
どうするのが最善かはわかりませんが、手をこまねいていても仕方がないので、スキルアップと自己アピールを兼ねて競技プログラミングに挑戦しようと思います。

そこで、この記事には毎回のAtCoderへの挑戦の記録を記していきます！

##おじさんの経歴
[ここに概要](https://qiita.com/gtkr/items/9a30340a9f0c61b0c448)をまとめました。どんなおじさんがチャレンジするのか知ってもらえると嬉しいです。

##次回
6/21 9:00
AtCoder Beginner Contest 171
に参加します！
【Python】【pandas】pd.DataFrame().Tはどうやって実装されているのか？

ipythonで`df.T??`を打ってヘルプを見てみる。

```
>>> df = pd.DataFrame()
>>> df.T??
Type:
property
String form: <property object at 0x7f1aa67d6540>
Source:
# df.T.fget
def transpose(self, *args, copy: bool = False) -> "DataFrame":
"""
Transpose index and columns.
(snip...)
```

`df.T`は`df.transpose()`と同じらしい。
`df.transpose??`しても同じヘルプしか見れなかったので、ソースコードをgrepして頑張って見つけた。
以下のように組込関数`property`を使って`self.transepose()`を`self.T`として呼べるように登録してあるらしい。

[Python Documentation 組み込み関数 property](https://docs.python.org/ja/3/library/functions.html#property)

```python:/opt/miniconda3/lib/python3.8/site-packages/pandas/core/base.py
from pandas.compat.numpy import function as nv
(snip...)
class IndexOpsMixin:
(snip...)
    def transpose(self, *args, **kwargs):
        """
        Return the transpose, which is by definition self.

        Returns
        -------
        %(klass)s
        """
        nv.validate_transpose(args, kwargs)
        return self

    T = property(
        transpose,
        doc="""
        Return the transpose, which is by definition self.
        """,
    )
(snip...)
```

propertyの第一引数は属性値を取得するための関数です。
...うん、イマイチ自分の言葉に落とし込めないのですが、やりたいことはできたので、いつか理解できたらいいなと思っておきます。
Minecraftをpythonで制御して自動で階段を作った話

MinecraftをPythonで制御できるみたいなので、簡単なことからやってみた。
#コード
```Python:Stairs.py
import mcpi.minecraft as minecraft
import math
import time

mc = minecraft.Minecraft()


while True:
    x,y,z = mc.player.getPos()
    distance = 1
    rad = math.radians(mc.player.getRotation())
    x1 = 0-math.sin(rad)*distance
    z1 = math.cos(rad)*distance

    if 0.0006462497831514223 > rad and -0.78485008484511 < rad:
        b=2
        mc.setBlock(x+x1,y,z+z1,53,b)
        time.sleep(0.001)


    if 0.7852897061620548 > rad and 0.0006462497831514223 < rad:
        b=2
        mc.setBlock(x+x1,y,z+z1,53,b)
        time.sleep(0.001)


    if 1.5711064519038362 > rad and 0.7852897061620548 < rad:
        b=1
        mc.setBlock(x+x1,y,z+z1,53,b)
        time.sleep(0.001)


    if 2.3567598792917686 > rad and 1.5711064519038362 < rad:
        b=1
        mc.setBlock(x+x1,y,z+z1,53,b)
        time.sleep(0.001)


    if 3.1414014386235256 > rad and 2.3567598792917686 < rad:
        b=3
        mc.setBlock(x+x1,y,z+z1,53,b)
        time.sleep(0.001)

    if -3.141350838562814 > rad and -2.3557998097187953 < rad:
        b=3
        mc.setBlock(x+x1,y,z+z1,53,b)
        time.sleep(0.001)


    if -1.5708293499924135 > rad and -2.3557998097187953 < rad:
        b=8
        mc.setBlock(x+x1,y,z+z1,53,b)
        time.sleep(0.001)

    if -0.78485008484511 > rad and -1.5708293499924135 < rad:
        b=8
        mc.setBlock(x+x1,y,z+z1,53,b)
        time.sleep(0.001)
```
#解説
```python
    x,y,z = mc.player.getPos()
    distance = 1
    rad = math.radians(mc.player.getRotation())
    x1 = 0-math.sin(rad)*distance
    z1 = math.cos(rad)*distance
```
ここで、プレイヤーの向きを調べて計算します。
引用：https://www.omotenashi-mind.com/index.php?title=Minecraft%EF%BC%9A%E4%B8%80%E6%AC%A1%E5%A4%89%E6%8F%9B%E3%82%92%E6%B4%BB%E7%94%A8%E3%81%97%E3%81%A6%E7%9B%AE%E3%81%AE%E5%89%8D%E3%81%AB%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%82%92%E5%87%BA%E7%8F%BE%E3%81%95%E3%81%9B%E3%82%8B

残りのifのところで階段の向きを指定して置いています。
それをwhile True:で繰り返しています。
#まとめ
実行すると、多少詰まってしまうことはあるけれど、うまく動きました。
環境作りができずに一時は断念したMinecraft制御、うまくいってよかったです。
![コメント 2020-06-20 212150.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644120/6132a58e-100c-fcf5-8eb2-d4a19eefdb63.png)
擬似的な陰関数のフィッティング

機械学習について色々勉強しだした後輩が最小二乗法を使って楕円のフィッティングをしようと頑張っていたのですが、多分こっちの方が簡単だよなぁと思って簡単にコードを書いたときのメモです。

陰関数$f(x,y)=0$のうちの$f(x,y)$を最小化するイメージです。

# イメージ

以下のように, $f(x,y)$をポテンシャルのようなものとして捉えます。

```python
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy import optimize

a = 2.0 #長軸
b = 1.5 #短軸
r = np.linspace(-1 * 3, 3, 1000) #計算範囲を決定
grid_X, grid_Y = np.meshgrid(r, r) #グリッドの作成

#楕円のポテンシャルを計算
def ellipse_potential(x, y, a, b):
    return np.abs(x**2/a**2 + y**2/b**2 -1)

data = ellipse_potential(grid_X, grid_Y, a, b) #各位置でのポテンシャルを計算

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(grid_X, grid_Y, data, cmap='bwr', linewidth=0)
fig.colorbar(surf)
ax.set_title("Surface Plot")
plt.show()
```
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516969/d70adc12-c5a6-0e85-fc2e-d1a8e629fb74.png)


# 実験
### データの作成
めちゃくちゃ適当に検証用データを作ります

```python
a = 2.0 #長軸
b = 1.5 #短軸
def ellipse(x, a, b):
    return b * np.sqrt(1 - (np.power(x, 2) / np.power(a, 2)))

X = np.linspace(-1 * a, a, 1000) 
Y = ellipse(X, a, b)

X = np.concatenate([X,X])
Y = np.concatenate([Y,-Y])

plt.scatter(X,Y)
plt.show()
```
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516969/1df1347c-e6cd-f872-a994-1c6f7906f92e.png)

```python
noiseX = (np.random.rand(200) -1)*0.2
noiseY = (np.random.rand(200) -1)*0.3

noised_X = X+noiseX
noised_Y = Y+noiseY

plt.scatter(noised_X,noised_Y)
plt.show()
```
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516969/6c7e8bd5-37e2-860d-134d-c16a2a9c890e.png)

### パラメータ推定
```python
#scipy向けに書き直し
def ellipse_potential_scipy(w, x, y):
    a = w[0]
    b = w[1]
    return np.sum(np.abs(x**2/a**2 + y**2/b**2 -1))

w = np.random.rand(2) #適当にパラメータを初期化
w_opt = optimize.fmin_bfgs(f=ellipse_potential_scipy, x0=w, args=(noised_X, noised_Y))
print(w_opt)
#array([ 1.98004494, -1.60650745])
```

以上でデータにフィットする陰関数のパラメータ推定ができました。
目標値は(2, 1.5)ですが、(1.98, -1.6)となかなかの数値が出ているのではないでしょうか。yのノイズを若干大きくしているので、真値とのズレもその影響が出ていますね。

特に精度を求めないのであればこれで十分ですね。
正負を特に考慮してないのが気持ち悪いですが、まぁ実用上問題無さそうです。
memo_website

# はじめに
- 親が簡単なものでいいから、website作りたいと言ってきたので作ることにします。
- 環境について
    - サーバー
        - lolipop
    - localPC
        - mac
    - html制作ソフト
        - python mkdocs

# 手順
![スクリーンショット 2020-06-20 21.02.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418485/bfd5c2dc-ef6b-a32e-eeae-380514830188.png)

ということで、本記事もstep1~step5までの解説になります。

## step1 会員登録（5分）

1. 会員登録：[https://lolipop.jp/order/form/]　よりエコノミーを選択すると、会員情報を入力をするページに遷移します。
    2. 必須情報（基本的な有料サイトに入れるような情報ですね。）
        3. ログインパスワード
        3. 氏名
        4. 住所
        5. クレジットカード

## step2 設定（5分）

1. ログインします。
    2. 説明省略

1. fileのupload画面の確認
画面真ん中左に"ホームページ作成をはじめる" > "自分で作ったサイトを公開する" > "データをアップロード"するというボタンがありますね。ここにhtmlファイルをuploadすればよさそう
    <img width="984" alt="スクリーンショット 2020-06-20 21.18.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418485/69e7c2d5-3118-1795-48ba-9488a79cf9ae.png">

    1.とりあえずgoogleのホームページをhtml保存したものをuploadしてみる
        1. uploadボタンの確認<img width="666" alt="スクリーンショット 2020-06-20 21.22.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418485/410d6483-953b-c37c-303e-2d64b4040aef.png">
        1. google.html -> index.htmlにファイルを書き換えてupload<img width="684" alt="スクリーンショット 2020-06-20 21.24.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418485/f2029053-0ee4-9c89-239f-bdf3e87132c9.png">
        1. webpageにアクセスして、サイトがgoogleになっていることを確認<img width="968" alt="スクリーンショット 2020-06-20 21.26.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/418485/9d9813a6-4d85-3de4-f167-3cd003da5f66.png">

google.comからdownloadしたhtmlファイルと一緒についてきた画像をuploadしていないため、googleのロゴがちゃんと表示されていないですが、よしとしましょう。　step3でちゃんとしたものを作りますので。

## step3 htmlファイル作成
## step4 htmlファイル送付
## step5 閲覧確認
Laravelで@csrf入れてるのに419エラーが消えないよ

くだらない話なんだけどね。

Laravelで、画面から項目を入れてテーブルに登録するって処理のテストをしていて、上手く動かなかった訳さ。phpのエラーが出たりしてね。

いくつか修正してphpのエラーは出なくなったんだけど、今度は419エラーの画面が出続けてしまう。
@csrfはあるし、特に変なところはない。なのに419のエラーが出ている。
ググっても答えが見つからずに途方に暮れていたとき、ある考えが閃いた。

**俺って、テストを「戻る」で続けてね？**

@csrfのトークンの有効期限はデフォルト120分だそうな。
120分過ぎたら、トークンの期限が切れるよね。戻るボタンで戻った画面ではトークン取り直さないもんね。リロードしていないし。

ブラウザ閉じて、改めてurlから入ったら、難なくエラーは消えました。

おいらみたいなぼけなすの助けになれば幸いです。
Webの基礎：動的ページの仕組み編

最近、個人的にＷｅｂ関連の基礎の振り返り的なものを行っているので、そのアウトプットに。
「こんなのググればすぐ出てくンじゃん！」的な内容も多々あると思うが、あくまで個人的なアウトプットでやっているだけなので、、、、~~文句があるやつはかかってきやがれ！~~

今回は動的ページの仕組みについての基礎振り返り！


#静的ページと動的ページについて
##静的
状況や人によって内容が変わらないページ
主にHTML、CSSによって構成されており、人が直接手を加えなければ表示内容の変化がない
就活性が死ぬほど見る企業のHPは大体、これだな。。。

##動的ページ
プログラムによって状況やアクセスする人によって表示内容が変わるページ
youtubeとかまさにこれ。
「あなたにおススメ」とか、まじで何でわかんねん・・・~~（かなり恐怖を感じた）~~

#動的ページの仕組み
以下のようなもので実装されている

##CGI
Common Gateway Interface
三文字でいうと「仕組み」
どんな仕組みかというとサーバ上で動的ページを作っているプログラムを起動させるための仕組み。
インタフェースと名がついている通り、サーバとプログラム間を取り持ってよしなにやってくれる
※なおプログラムそのものを指してCGIもしくはCGIプログラムと言う場合もある

ちなみにURLはCGIが置かれたファイルにアクセスしているので、YouTubeなんかもURLの先にはCGIが置いてあるってことかな。

##スクリプト言語
動的ページをつくってるプログラム、いわば本体やな。
大きく分けてサーバサイドスクリプト（サーバ側で動くスクリプト）と
クライアントサイドスクリプト（あんたが今このページ見ているsafariやChrome等々といったブラウザで動くスクリプト）の二つに分けられるぞ。

###サーバサイドスクリプト
CGIから呼び出されるプログラム。
基本的にはサーバ側で動的ページを作ってそれはホイってブラウザ側へ渡す。

・よく使われる言語
Perl、Ruby、Python、PHP、JavaScript
（ちなみに業界人の中にはJavaScriptをJSっていう人もいるぞ☆）

まぁこいつら↑はまとめて「スクリプト言語」って言われとるし、まんまやな。
興味ある人は「スクリプト言語　一覧」とかで調べたったらいい。

###クライアントサイドスクリプト
HTMLに埋め込まれて、ブラウザ側に渡って、ブラウザ側で実行される。
ちなみに、最初にも書いたように、動くのはスマホ or PCのSafariやChromeといったブラウザ上なので、ブラウザがそもそもそのプログラムに対応していなければ動かない。
まぁ今となってほぼ無いが・・・（古いバージョンのIEだと動かんかったりする）

・よく使われる言語
JavaScript
クライアント側ではこれが一番、メジャーやな。むしろこれ以外を使っている動的ページってほぼないんとちゃうかなぁ・・・

#終わり
終わりです、こんな感じで基礎的なこと（or たまに深いこと）をゆる～く投稿していこうと思います。
Apache2 で perl の CGI を使えるようにする

Ubuntu 20.04 で確認しました。
次の記事を参考にしました。
[https://pentan.info/server/apache_cgi.html](https://pentan.info/server/apache_cgi.html)

次のファイルを作成

```text:/etc/apache2/conf-available/cgi-enabled.conf
<Directory "/var/www/html/public_html">
    Options +ExecCGI
    AddHandler cgi-script .cgi .pl
</Directory>
```

次のコマンドで変更を反映

```bash
sudo a2enconf cgi-enabled
sudo a2enmod cgi
sudo systemctl restart apache2
```

任意の場所でスクリプトを動かす為には、次のようにする必要がある。

```text:/etc/apache2/conf-available/serve-cgi-bin.conf
<IfModule mod_alias.c>
	<IfModule mod_cgi.c>
		Define ENABLE_USR_LIB_CGI_BIN
	</IfModule>

	<IfModule mod_cgid.c>
		Define ENABLE_USR_LIB_CGI_BIN
	</IfModule>

#	<IfDefine ENABLE_USR_LIB_CGI_BIN>
#		ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
#		<Directory "/usr/lib/cgi-bin">
#			AllowOverride None
#			Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
#			Require all granted
#		</Directory>
#	</IfDefine>
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
```
putsでnilが返ってくる。これの意味は？

#putsでnilが返ってきているが、どう言うこと？
今まで無視してきましたが、考えてみればこれは一体どう言う意味なのか？

```
irb(main):001:0> a = "apple"
=> "apple"
irb(main):002:0> puts a
apple
=> nil
```

上記を見ると、putsでappleがあるのは分かるが、nilが返ってきている。

前提として**『出力』と『返り値（戻り値）』は別物**みたいです。

同じ意味ではないです。

・```出力```：表示するだけ
・```戻り値```：値を返して、メソッドを終了

じゃ結局のところ、putsは表示させるだけのものと言うことですね。

なぜ、そんなものが必要なのでしょう？
[参考](https://teratail.com/questions/10171)
↑
表示するだけで、プログラム自体には変化を与えていないと言うこと。
無駄をなくすためと言うことですね。

#参考

https://tsubasa0105.hatenablog.com/entry/2018/11/03/015243
webサーバとアプリケーションサーバって何が違うんだろう？

「webサーバとアプリケーションサーバって何が違うんだろう？」、ふと思ったのでまとめた。

#サーバとは
まずサーバって何？という話。サーバは英語でserver、つまり供給する・提供するってこと。[IT用語辞典](http://e-words.jp/w/%E3%82%B5%E3%83%BC%E3%83%90.html) によるとサーバとは、コンピュータネットワークにおいて、他のコンピュータに対し、自身の持っている機能やサービス、データなどを提供するコンピュータのこと。私たちがwebページを閲覧するとき、自分のPCから「このページ見たい！」とサーバにお願いする。すると、サーバが「はい、これ！」とページを返してくれる。これで、めでたくwebページが見れる。通常、個々のサーバ機やサーバソフトは、外部に提供する機能やサービス、対応しているデータ形式やプロトコル（通信規約）が決まっている。そして、「DBサーバ」「webサーバ」「アプリケーションサーバ」のように、提供する機能などの種類を冠して「○○サーバ」と呼ぶ。

#webサーバ
webサーバはブラウザからのコンテンツのリクエストを受け取り、ブラウザにレスポンスを返すのが役割。このときのリクエストが静的なwebコンテンツだった場合(HTML、CSS、画像ファイルのような更新しない限り同じ表示コンテンツを表示するコンテンツ)、webサーバが処理してレスポンスを返す。また、クライアントごとに表示内容を変化させる処理が必要な動的なwebコンテンツの場合、webサーバはアプリケーションサーバへとリクエストを送る。そして、アプリケーションサーバから返ってきた結果をレスポンスとして返します。webサーバとして有名なのは Nginx、Apache など。


#アプリケーションサーバ
アプリケーションサーバは私たちが作ったアプリケーションを動かしてくれるもの。webサーバから送られてきたリクエストをアプリケーションサーバからアプリケーションに伝え、アプリが処理した結果をwebサーバに返す。ローカル環境下での開発の場合はアプリケーションサーバのみを立てるが、本番環境ではwebサーバをアプリケーションの手前に置くことで、静的なコンテンツの処理を負担させることが多い。


##例えばRailsだったら
Railsのアプリケーションサーバとして代表的なのはUnicorn、Thin、Rainbows、Pumaなど。webサーバから送られてきたリクエストをアプリケーションサーバからRailsアプリケーションに伝え、Railsアプリが処理した結果をwebサーバに返す。ローカル環境下での開発の場合はPumaのようなRails用のアプリケーションサーバのみを立てる(普段development環境でやってるやつ)。一方、本番環境(production環境)ではwebサーバをRailsアプリケーションの手前に置き、静的なコンテンツの処理を負担させることが多い。こうすることで、Webサーバが複数のアプリケーション一度に処理したり、アセットを素早くレンダリングしたりして、リクエストごとに発生する多くの処理をさばいてくれる。


##Rack
ここでRackに触れておく。RackとはRuby製のフレームワークとアプリケーションサーバの間に入り、互いをつなぐ役割をしてくれる。サーバはRackを使用することで、送られてきたHTTPのリクエストがアプリにも理解できる形に変換される。逆にアプリからのレスポンスはRackを通じてHTTPに変換されてサーバに返る。Rackを使用することでサーバとフレームワークの組み合わせが自由になる。

#まとめ
ここまでの内容をまとめる。ブラウザから送られてきたリクエストをwebサーバが受け取り、静的なwebコンテンツだった場合レスポンスをブラウザに返す。しかし、リクエストが動的なwebコンテンツの場合、webサーバでは処理せず、アプリケーションサーバに送る。そして、アプリケーションサーバがミドルウェアを通してアプリに伝える。処理が終わったら、先ほどとは逆の順番で結果をブラウザに返す。

#参考
[webサーバーとアプリケーションサーバーの違い](https://qiita.com/sumin/items/86a0e2edc40566bcb666)
[IT用語辞典](http://e-words.jp/w/%E3%82%B5%E3%83%BC%E3%83%90.html)
[Rails開発におけるwebサーバーとアプリケーションサーバーの違い（翻訳）](https://qiita.com/jnchito/items/3884f9a2ccc057f8f3a3)
ゼロから始めるLeetCode Day62「83. Remove Duplicates from Sorted List」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

Python3で解いています。

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day61「7. Reverse Integer」](https://qiita.com/KueharX/items/c2fcff8d439c5259d91e)

今はTop 100 Liked QuestionsのMediumを優先的に解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。

**[技術ブログ](https://kueharx.blogspot.com/)始めました！！**
技術はLeetCode、Django、Nuxt、あたりについて書くと思います。**こちらの方が更新は早いので**、よければブクマよろしくお願いいたします！


# 問題
[83. Remove Duplicates from Sorted List](https://leetcode.com/problems/remove-duplicates-from-sorted-list/)

難易度はEasy。

解いた問題と記事を書いた問題の管理が上手くできていなくて、てっきり書いたものだと思っていました。

- [ゼロから始めるLeetCode Day48 「26. Remove Duplicates from Sorted Array」](https://qiita.com/KueharX/items/f234d8beab96328a171a)

こっちの方しか書いてませんでした。
名前が紛らわしくて思わず笑っちゃいました。

さて、今回の問題ですが、連結リストが与えられるので、全ての要素が一度しか登場しないようにDuplicates(複製)を取り除いてください、という問題です。

>Example 1:

>Input: 1->1->2
Output: 1->2
Example 2:

>Input: 1->1->2->3->3
Output: 1->2->3


# 解法

僕は以下のように書きました。
他言語特有のん？となるような要素も少ないですし、他の言語で書いていらっしゃる方も読めるのではないでしょうか。

```python
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        runner = head
        while runner:
            while runner.next and runner.next.val == runner.val:
                runner.next = runner.next.next
            runner = runner.next
        return head
# Runtime: 48 ms, faster than 31.67% of Python3 online submissions for Remove Duplicates from Sorted List.
# Memory Usage: 14 MB, less than 21.02% of Python3 online submissions for Remove Duplicates from Sorted List.
```

```python
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        origin = head
        pre = head
        head = None if head is None else head.next
        while head:
            if pre.val == head.val:
                pre.next = head.next
            else:
                pre = pre.next
            head = head.next
        return origin
# Runtime: 44 ms, faster than 58.51% of Python3 online submissions for Remove Duplicates from Sorted List.
# Memory Usage: 13.8 MB, less than 55.82% of Python3 online submissions for Remove Duplicates from Sorted List.        
```


一方で、二つ保持して書いた方がスピードは出ました。
強いていうなら最初の`head`への代入は内包表記で書いているので一瞬戸惑うかもしれませんね。
要は

```python

if head is None:
    head = None
else:
    head.next
```
というのを短く書いているだけです。
こうするとreturnとかするときに一個にまとめられるので個人的に好きです。短く楽して書けるの良いですよね。

originを見てたらオリジン弁当が食べたくなってきたので今回はここまで。お疲れ様でした。