OmniAICreator/Qiita-1.07M huggingface dataset:
競技プログラミングの練習会を毎日開催してみた

この記事は [Competitive Programming (1) Advent Calendar 2018](https://adventar.org/calendars/2931) 3日目の記事です。

こんにちは。最近退職で話題の会社のグループ会社に所属しています @ktateish です。
某社の一部界隈では、今年競技プログラミングが大流行しました。一部の競プロ関係者には、この流行のことが伝わっていたようです。

本記事では、その流行を支えた練習会の話を共有したいと思います。



## きっかけ

すべての始まりは、 @kumagi さんが競技プログラミングを始めたことだったと思います。
彼は今年の5月ごろから AtCoder や Codesignals, LeetCode などに参加して、Slack で競プロチャンネルをつくり、参加報告をつぶやくようになりました。

私も昔競技プログラミングに興味を持って各種サービスにアカウントを作ってあったんですが、過去問をいくつか解いた後 1〜2回ほど参加してそのあとは放置、という状況でした。 たまたま @kumagi さんが AGC024 に参加しまーすと言っているのを見て、「また再開してみようかなー」と思い、そのとき勢いで参加ボタンをポチりました。Slack で参加を宣言すると、他にも何名か後に続いてくれました。

## 練習会

そうこうしているうちに、AtCoder の過去問の練習に取り組む人が出てきました。どうせなら、都合のつく人で一緒に競争するか〜という話になり、 6/29 に @aajisaka さんが [AtCoder Virtual Contest](https://not-522.appspot.com) を見つけて、バーチャルコンテストのインスタンスを立ててくれました。このときの参加者は @kumagi さんと @aajisaka さん @ktateish の3名だけでした。

練習後は解法について Slack でワイガヤしつつあーだこーだ感想戦をしていると、競プロ経験者を始めとする興味を持った他の人も議論に参加してきてくれました。

## 練習会の継続

その翌日 6/30、たまたま暇だったので私が Virtual Contest を立て、2回目の練習会を実施しました。すると、前日の盛り上がりを見て参加したくなった人が参加してくれて、 参加者は一気に8名になりました。

これが、私達の中で競プロが大きなムーブメントになった瞬間でした。某Slackでは1日1回チャンネルごとの発言数ランキングが #general で発表されるのですが、練習後にあーでもないこーでもないと議論していると発言数はかなり伸びます。すると翌日のランキングではほぼ確実に1位になります。それを見た人たちが競プロチャンネルにJoinし、練習会に参加、さらに発言数が増える、という循環が回り始め、チャンネル参加者は一気に数十人レベルに膨れ上がりました(現在は100名を超えています)。その全員が練習会に参加するわけではありませんが、参加してくれる人が増えてくると、 Virtual コンテンストを開催するほうも、継続したくなります。（というか、簡単にはやめられなくなります）

急いで初心者向けに練習会参加用のマニュアルを整備し、過去の開催状況を一覧にしてチャンネルに共有したり、問題セットの選択方法を整理したりして、継続を楽にしつつ、新しい人達が参加しやすい環境を整えました。

## オンサイト・コンテストの開催

ここまで盛り上がってくると、オンサイト・コンテストを開催したくなります。
上司に相談して会社のイベントスペースを借り、普段競プロチャンネルで練習会に参加している人たちを対象にオンサイト・コンテストを開催しました。コンテンストに出す問題は、参加者が解いてなさそうな過去問から出題することにし（作成はしない）、一部有志のメンバーには問題選定＆解説をやってもらいました。

このオンサイト・コンテストには20名以上が参加し、大成功でした。

## 初心者向けセミナーの実施

今年の夏頃行われた某テックカンファレンスでは、競プロ経験者の @bakaming さんが一般の初心者向けの競プロセミナーを開催(私はサポート要員として参加)したのですが、 実は Slack のチャンネルには参加してるけど、いまいち練習会への参加のきっかけをつかめずにいたメンバーが何人か参加してくれて、そこから参加を継続してくれるメンバーも出てきました。

Slackで盛り上がっているとはいえ、ある程度メンバーが固定化されてくると、新しい人は入りづらい、という事象はどうしても発生してしまうので、こういった形できっかけを作ることはとても重要だなと思いました。

## ブームの終焉 → 定着

競プロチャンネルには経験者の比較的強いメンバーも結構はいってきてくれてはいたのですが、基本的に練習会は AtCoder ABC の問題セットを中心に開催しています。7月から始めた練習会でしたが、原則として本家 ABC/ARC/AGC や企業コンなどがない日には毎日開催しており、 10月ごろには ABC を1周しました。

この頃になると、練習会の参加者も減り始めて、現在は結構下火になってしまっています。
しかし、本家 ABC 等のコンテストになると結構な人数がコンスタントに参加しているので、少なくとも某 Slack 内では競プロが文化として定着したんじゃないかなと思います。

今は私自身、最近はあまり時間をとれないこともあって、問題セットの選び方などの見直しをできていないのですが、このあたりをうまく変えて、今後またムーブメントを大きくできたらいいなと思います。

## 成果

私個人で言うと、 7月ごろから AtCoder に本格的に参加し始めて、 9月末には水色になることができました。やったね。
某Slack全体を見ると、AtCoder に新規に参加しはじめた人が30人前後はいると思います。そのうち、ICPCなどの競プロ経験者も含みますが、ざっくり5人前後が水色以上、10人程度が緑色に到達しています。

また、気分転換的に、いつもの競プロチャンネルのメンバーで [picoCTF 2018](https://2018game.picoctf.com/) に2週間ほど参加したりもしました。この手のコンテストイベントに気軽に参加する文化ができたのも、この練習会の成果だと思っています。

## まとめ

動画にすると、つまり↓のような感じです。
[![How to Start a Movement](http://img.youtube.com/vi/lbaemWIljeQ/default.jpg)](https://www.youtube.com/watch?v=lbaemWIljeQ)



## 謝辞

[AtCoder](https://atcoder.jp/) の chokudai さんを始めとするみなさま、 [AtCoder Virtual Contest](https://not-522.appspot.com) の not_522 さま、いつも使わせていただいてありがとうございます。
ジャルジャルの「国名分けっこ」を実装してみた

##はじめに
こんにちは！[Life is Tech! Tokai Mentors Advent Calendar 2018](https://qiita.com/advent-calendar/2018/lit-tokai-mentors)の6日目の記事はわだどんが書かせていただきます。

突然ですがみなさん..._**漫才は好きですか？**_

諸々の導入はぶっ飛ばしますが、今回の記事で[ジャルジャルさん](https://twitter.com/jarujaru12th)を愛してやまない筆者が実装するのは**「国名分けっこ」**です。

## 「国名分けっこ」とは

「国名分けっこ」を知らない...？

**もしかして「分けっこ国名」って言ってました？**

※「国名分けっこ」を知らないそこのあなたは[**こちら**](https://www.youtube.com/watch?v=b1J39WQFvSs)のネタ動画を見てからこの記事を読み進めることをオススメします。

## ゲーム進行(ざっくり)
1. 福徳さんが国名を任意の位置までぶった切って言う
2. 後藤さんが残りの国名を返す

## 
実際はリズムに合わせてのやりとりが面白いんですが今回はその辺は実装しません。制限時間とかつけたらいい感じにできるはずです。知らんけど。

## 実装する処理の流れ
1. 国名を途中まで出力
2. プレイヤーが答えを入力
3. 正解なら「ええやん！」不正解なら「全然あかんやん！」と出力

## 実装
### 国名をランダムに取得する
```.py
class CountryModel:
    def __init__(self):
        self.countries = [('アルゼンチン',17),('インドネシア',17),('イタリア',5),('オーストラリア',4),('ニッポン',3),('チュウゴク',3),('ドイツ',2),('モンゴル',2),('エジプト',2),('カナダ',2),('ギリシャ',2),('ブラジル',2),('アメリカ',1),('イギリス',1),('カンコク',1)]

    def get_prob_sum(self):
        prob_sum = 0
        for c in self.countries:
            prob_sum += c[1]
        return prob_sum

    def get_country(self):
        rand = random.randint(0,self.get_prob_sum()-1)
        count = 0
        prob = 0
        while True:
            prob = self.countries[count][1]
            rand -= prob
            if rand<=0:
                break
            count+=1
        return self.countries[count][0]
```

コンストラクタでは`self.countries`に`('国名',重み)`となるタプルを格納しています。
重みはM-1の時のネタでの出現数を**手動で数えました**。

`get_prob_sum()`で出現率の合計を算出し、`get_country()`で重みとかを計算した後に国名を返します。

コードを見てもわかる通り**アルゼンチンとインドネシアが圧倒的に出やすい**です。

### 国名をぶった切ったり答えのチェックしたり
```.py
class TextModel:
    def chop_text(self,text):
        length = len(text)
        rand = random.randint(1,length-1)
        return text[0:rand]

    def check(self,question,answer,countries):
        answer = question+answer
        for c in countries:
            if c[0] == answer:
                print('ええやん！')
                return

        print('全然あかんやん！')
        return
```

本当は`split()`とかで任意の位置での切り分けができればよかったんですが、区切り文字が存在しなかったのでムリっぽいですね。

`chop_text()`はランダムな位置で文字列を2つにぶった切って先頭側の方を返してくれます。

`check()`はその名の通り答えがあっているかどうかのチェックをしています。

## 動作
<img width="265" alt="スクリーンショット 2018-12-04 2.49.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/163599/126c27bc-e068-4153-d9d3-e48b7f9fd364.png">

**ええやん！**

## ソースコード
ソースコードは[こちら](https://github.com/wada-don/Wakekko/blob/master/wakekko.py)

## 感想
国名の出現数を数えるところが1番きつかったです。

**頭おかしなるわこれ！！**
Unity開発するにあたって知っておきたいコンパイラのすゝめ(Part0.5～.NET Frameworkの概要編～)

#最初に

この記事はUnityで使用されているコンパイラについてまとめた記事のうちの、土台部分である**.NET Framework**について簡単にまとめた記事です。そのため、Part1ではなく、とっかかりという意味で0.5と記載させて頂きました。

- [Part0.7〜JITとAOT概要編〜](https://qiita.com/4_mio_11/items/f58fedbf2a7721c3df58)
- [Part1～Mono編～](https://qiita.com/4_mio_11/items/716d28add984405a80cc)
- [Part2～IL2CPP編～](https://qiita.com/4_mio_11/items/d5d7b4e879a8341595cd)
- [Part3～Burst編～](https://qiita.com/4_mio_11/items/cda0c8aa4c77a7748418)

## .NET と .NET Frameworkって違うの？

### .NET

.NETとはマイクロソフトが提供している各種のライブラリや基盤となるフレームワークそれらをすべて含めた統合開発環境のことを指します(IL言語については後述)。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/c1a6de7d-2e86-7a2e-32e1-a9d1d577af19.png)

.NETの中でも特に大きなライブラリが.NET Frameworkとなります。

そのため、.NET Framework のことを .NET と呼ぶ人も多いです。

### .NET Framework

.NET Frameworkは

- **「共通言語基盤(CLI:Common Language Infrastructure)」**という、「言語に依存しない開発環境および実行環境を提供すること」を目的にした、実行コードや実行環境の仕様を実装した代表的なものである**「共通言語ランタイム（CLR：Common Language Runtime）」**というプログラム実行エンジン(.NET FrameworkやMono)
- 基本クラス(Systemなど)、ライブラリやフレームワーク

で構成されています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/f80e104c-e127-3179-23fb-81edcacbdc10.png)

.NET Frameworkにおいて、CLI互換な実行環境をターゲットとしている言語(C#,VBなど)の場合は一旦、.NET の**中間言語（IL:Intermediate Language(別名:CIL,MSIL)）**にコンパイルされます。アプリやライブラリ等は、ILの状態で配布を行うようです。

ILはアセンブリ言語で定義されており、VESによってJITで実行されます。

## 処理の流れ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/36899/78d3d6b8-6de4-f57f-ff94-b61b31263503.png)

VESからマシン語に変換される際にはJITで行われますが、JITについては次の記事で解説しようと思います。

#最後に

いかがだったでしょうか。私自身は今までC#の言語機能ばかりを追い続けていて基盤部分には目を向けていなかったため、すごくあやふやな状態でした。今回この記事を書いて、自分自身の勉強にもなりました。この記事が僕のような初心者の方の役に立てれば幸いです。

#参考

- [IL の概要](https://ufcpp.net/study/il/summary/il_about/)
- [共通中間言語](https://ja.wikipedia.org/wiki/%E5%85%B1%E9%80%9A%E4%B8%AD%E9%96%93%E8%A8%80%E8%AA%9E)
- [.NETとは何か？](http://www.atmarkit.co.jp/ait/articles/1105/30/news129.html)
- [【初心者向け】C#.NETとは？C#との違いは？徹底解説](https://web-camp.io/magazine/archives/5182)
- [.NET Framework の概要](https://docs.microsoft.com/ja-jp/dotnet/framework/get-started/)
Railsでアプリケーションを作成する一通りの流れ（概要編）

## サクッとディレクトリやファイル紹介

とりあえず５つだけわかればいいです。上三つを合わせてMVCと呼びます。

| 名前  | だいたいやること |
|:-----------------|:------------------|
| Model            | だいたいDB | 
| View             | ブラウザから見えてる部分 |
| Controller       | DBとViewをつなぐもの|
| config/route.rb  |URLを操作できるとこ|
|DB|DBの中身の構造を決めるところ、マイグレーションファイルがいっぱい入っている|

図に表すとこんな感じで、ModelとViewをつなぐのがController

![alt](https://s3-ap-northeast-1.amazonaws.com/mash-jp/staging/uploads/6301/5e83d02af0b1e17ffb58fc48adc6ccdb3fd52220.6335.desktop.png)

※引用させていただきました
https://blog.codecamp.jp/what_is_rails

##Railsアプリケーションの手順をざっくり理解
- まず土台を作る

```
rails new　アプリケーション名
```
- gemのインストールをする

```
bundle install 
```
- コマンドでコントローラーとmigrationファイルを生成する
viewのフォルダが勝手に生成されるので、viewフォルダの中身は自分で追加して編集する

```
rails g　controller コントローラー名を複数形に(例えばHoges)
```

- コマンドでモデルを作成する
migrationファイルはコントローラーを作成すると勝手にできる

```
rails g model コントローラー名を単数形に(例えばHoge)
```
- マイグレーションファイルに型とカラム名を書いてDBを作る

```
rake db:migrate
```

- コントローラーにアクションを追加してアクションの中身を書く
- viewでコントローラーからわたしたインスタンス変数を表示させる（for文などを使用）
- 必要に応じてルーティングを修正する

- サーバーを起動する

```
rails s -p $PORT -b $IP
```

※modelはアソシエーションと言って、二つのテーブルを連携させたり、メソッドを作成したり、スコープを定義したりする際に必要になりますが、序盤では何も記載しなくても構いません。
Reactで複数のプロジェクトで共通のコンポーネントを扱う方法[create-react-app]

## TL;DR
- ReactでAtomicDesignなどを採用していて、コンポーネントを再利用性を加味しながら作成していて、複数のプロジェクトで共通のコンポーネントを使いたい場合がある。（e.g. `User用`と`Admin用`を別のプロジェクトとして作成し、共通のコンポーネントを扱う、等）
- [**create-react-app**](https://github.com/facebook/create-react-app)でプロジェクトを始めた場合はデフォルトの設定では難しいため、不可逆な操作である`yarn eject` (or `npm run eject`)を行い、手動で設定を行うことで実現した。
![movie.gif](https://qiita-image-store.s3.amazonaws.com/0/108880/1d77c432-0ef0-8101-feb0-a5443ebf3070.gif)

# Pros & Cons
## Pros
- create-react-appの恩恵を受けれる(簡単に構築できる)
- ホットリロードしてくれるので、共通コンポーネントの修正などが爆速でできる

## Cons
- monorepoな構成になるため、はじめてコードを見た人にとっては威圧的になる
- 複数プロジェクトを同一の`package.json`で管理するため、複数のプロジェクトで同一のパッケージを使う場合はバージョンを揃える必要がある
- `npm run eject`を行うため、create-react-appのバージョンアップに追従できない

# 方法

1. `yarn eject`
2. `config/paths.js`を編集
3. `src/`,`public/`のディレクトリ構成を修正
4. `package.json`を編集

### 前提
create-react-app ( ver1.3.1 )

[サンプル(Github)](https://github.com/coffeemk2/shared-component-using-cra-sample)
[commit](https://github.com/coffeemk2/shared-component-using-cra-sample/commit/22034311414076d7617a33dcb4b8aa9e664674e4)

### 1. `yarn eject`
```shell
$ yarn eject
```

　**注意**： *このコマンドを実行すると(git操作以外では)元に戻すことができなくなります*

### 2. `config/paths.js`を編集
```paths.js
 ~ 省略 ~ 
// デフォルトは'user'　
const ENTRY_NAME = process.env.ENTRY_NAME || 'user' //追加

module.exports = {
  dotenv: resolveApp('.env'),
  appPath: resolveApp('.'),
  appBuild: resolveApp('build/' + ENTRY_NAME),                      //
  appPublic: resolveApp('public/' + ENTRY_NAME),                    //
  appHtml: resolveApp(`public/${ENTRY_NAME}/index.html`),           //　 編集
  appIndexJs: resolveModule(resolveApp, `src/${ENTRY_NAME}/index`), //  
  appPackageJson: resolveApp('package.json'),
  appSrc: resolveApp('src'),
  appTsConfig: resolveApp('tsconfig.json'),
  yarnLockFile: resolveApp('yarn.lock'),
  testsSetup: resolveModule(resolveApp, 'src/setupTests'),
  proxySetup: resolveApp('src/setupProxy.js'),
  appNodeModules: resolveApp('node_modules'),
  publicUrl: getPublicUrl(resolveApp('package.json')),
  servedPath: getServedPath(resolveApp('package.json')),
};


```

### 3. `src/`, `public/`のディレクトリ構成を修正
```
config
scripts
public
  index.html
  favicon.ico
  manifest.json
src
  index.js
  index.css
package.json
```
↓

```
config
scripts
public
  admin
    index.html
    favicon.ico
    manifest.json
　　 user　　
    index.html
    favicon.ico
    manifest.json
src
  admin
    index.js
    index.css
  user
    index.js
    index.css
  shared
    MySharedComponent.jsx
package.json
```

### 4. `package.json`を編集

```package.json
  "scripts": {
    "start": "node scripts/start.js",
    "build": "node scripts/build.js",
    "test": "node scripts/test.js",
    "start:admin": "ENTRY_NAME='admin' node scripts/start.js",
    "build:admin": "ENTRY_NAME='admin' node scripts/build.js",
    "test:admin": "ENTRY_NAME='admin' node scripts/test.js"
  },
```
Azure Blockchain Workbench の Hello World

こちらの記事は、Qiita に掲載した [Microsoft Azure Tech Advent Calendar 2018](https://qiita.com/advent-calendar/2018/microsoft-azure-tech) の企画に基づき、執筆した 内容となります。(3 日目)

Azure に Blockchain プロジェクトを簡単に構築できる Azure Blockchain Workbench がプレビューで公開されてます。簡単に Hello World 的な最初のステップを試してみます。

#1 プロジェクトの作成
Azure Blockchain Workbench のテンプレートが用意されているのでポータルから作成します。仮想マシン、SQL Databases、Web Apps さらにはネットワーク設定も含めて展開をしてくれます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/826b9220-25d6-2a8e-7e5e-6091b9f45c83.png)

#2 Azure AD の構成
テンプレートで作成された Web Apps にアクセスすると以下のようなスクリプトが表示されます。こちらを Cloud Shell で実行して設定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/cfa9e12e-3f9f-c5af-a1ab-63b8cf690372.png)

実行すると、対象の Azure AD のテナント名も求められますので入力します。Success が出れば成功です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/bef8229a-ccfc-4468-a1af-6b84b9f58ee9.png)

次に Azure AD 側でアプリケーションを登録します。登録したアプリケーションのマニュフェストの設定から "appRoles": [] を以下のように編集します。GUID は、[guid]::NewGuid() の Shell などから作成します。

```
"appRoles": [
     {
       "allowedMemberTypes": [
         "User",
         "Application"
       ],
       "displayName": "Administrator",
       "id": "<A unique GUID>",
       "isEnabled": true,
       "description": "Blockchain Workbench administrator role allows creation of applications, user to role assignments, etc.",
       "value": "Administrator"
     }
   ],
```

OAuth2 も許可します。
```
"oauth2AllowImplicitFlow": true,
```

登録したアプリケーションで以下を設定します。
- 必要なアクセス許可に Microsoft Graph を追加して、Read all user's basic profile を許可します。
- 応答 URL に作成された Web Apps アプリケーションの URL を設定します。

#3 アプリケーションの作成
テンプレートから作成された Web Apps のサイトにいくと新規作成のページがあります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/51bde61d-7e8c-a3ee-e33c-dee9811984ea.png)

GitHub のサンプル [Hello Blockchain](https://github.com/Azure-Samples/blockchain/tree/master/blockchain-workbench/application-and-smart-contract-samples/hello-blockchain) からHelloBlockchain.json と HelloBlockchain.sol を取得します。

New から HelloBlockchain.json と HelloBlockchain.sol を登録するとアプリが登録されました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/6f7d99d2-376c-aa41-bc90-8509ac33b4bc.png)

こちらのサンプルは、ブロックチェーンを使用した台帳の Requestor と Responder が必要になります。なので、追加でメインアカウント以外のアカウントも Azure AD に追加しておき、アプリ側で、Requestor と Responder を少なくとも一名追加します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/c95bac3e-ccd6-88d5-f9b4-04e5350b7586.png)

Requestor では Take Action からリクエストを登録します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/aa41a6b8-60f3-c095-22e9-54339c8ecd36.png)

Responder では Take Action からリクエストに応答します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/7b9123d9-b58a-b23d-006e-2ab9bec27181.png)

特にユーザー側でブロックチェーンのハッシュなどに関して認識する必要はないですが、きちんと Block HASH で管理されていることが確認できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/3a807c3e-ccda-727b-1d6d-69a631a97baf.png)

ブロックチェーンがこんな簡単に使えるなんてすごいですね。是非お試し下さい。
cloud9でサクッとRailsを勉強する

## 趣旨
railsとgitを個人的に教えることになったので手順書を簡単に書きます。
あとで編集予定です。

## まず準備
- githubとcloud9のアカウントを開設する
初心者の方はパスワードやアカウント名は忘れないようにメモっておくといいです

- cloud9でworkspaceを作成する。
以下のようにworkspace名とblankを選択
![スクリーンショット 2018-12-04 午前1.56.25.png](https://qiita-image-store.s3.amazonaws.com/0/140595/b06fd91e-f5fb-1c97-7926-74f93bcaf857.png)


- githubのプロジェクトをクローン

githubのプロジェクトのフォルダ名がいっぱい書いてあるページの緑のボタンを押す
そこをコピーして以下コマンドの後ろに貼る
![スクリーンショット 2018-12-04 午前2.00.07.png](https://qiita-image-store.s3.amazonaws.com/0/140595/e9d26ad2-98bf-14d6-c67b-5759da290292.png)

```
git clone コピーしたもの
```

- クローンしたらそのディレクトリ（フォルダ）に移動する

```
cd　フォルダ名
```

※今回クローンしてきたレポジトリの場合、以下のようなエラーが出るので、rubyのバージョンを合わせる
ruby-2.4.1 is not installed.
To install do: 'rvm install ruby-2.4.1'

```
rvm install ruby-2.4.1
```

- この状態だとrailsアプリケーションは動かないのでおまじないをする

まずgemをインストール

```
gem install bundler
bundle install
```

そのあとマイグレーションしてデータベースが使えるようにする

```
rake db:migrate
```

- これでようやく見れるようになるのでサーバーを起動
※cloud9の場合、ポートとIPを指定しなきゃいけないので以下コマンド

```
rails s -p $PORT -b $IP
```
- ちゃんと起動されているはずなのに表示されず、、、以前のcloud9だとこのまま右に緑の吹き出しが出てきてそのurlをみればよかったが吹き出しが出てこない。

そこで以下urlを参考に、右上のshareタブからapplicationのurlにアクセスするとみれた。

https://teratail.com/questions/112174

## gitの準備

- エディタをVimに設定


コミットメッセージを編集するとき、デフォルトだとnanoに設定されてしまうのでこれをvimに修正しておく。

```
git config --global core.editor 'vim -c "set fenc=utf-8"'
```

- ユーザー情報を設定する

以下で自分の名前をgithubに登録してあるアドレスを登録しておく。
以下コマンドを編集して打つことで登録できる。

```
git config --global user.name "First-name Family-name"
git config --global user.email "username@example.com"
```

- 余力があればcloud9のssh　keyを設定しておくと楽

> cloud9にログインした状態で、https://c9.io/account/ssh に遷移する
cloud9のアカウント用の[Default SSH key]が表示されるのでクリップボードにコピーする
GitHubにログインした状態で、https://github.com/settings/ssh に遷移する
[New SSH Key]ボタンを押下し、先ほどコピーしたSSH Keyを貼り付ける ※titleは適当でOK

こちらより引用
https://qiita.com/hisashi629/items/006f3df072a816030c4c

- githubのCollaborators追加

レポジトリの管理者の方はSettingsのCollaboratorsからアカウント名を追加して、レポジトリにpushできるようにする

![スクリーンショット 2018-12-04 午前9.00.38.png](https://qiita-image-store.s3.amazonaws.com/0/140595/d8158166-b8ad-7979-493c-a10dc17a285c.png)
手作業を自動化する手順

かなりチラシの裏ですが・・・

日々定型業務と呼べないはずの作業が定型化することがあると思います。
次に作業するのが数か月後とかになるやつです。

そんな作業も順をコマンド1発の自動化する手順を持っているので、一応形にしておきたいと思います。
この手順の利点は、作業毎に少しずつ改善することでめったにしない作業を自動化したり、自動化をするのが遅かったりがないことです。また、自動化のための時間をわざわざ確保しなくても良いのが利点です。

# 前提条件
　コマンドラインで作業しましょうプログラマ用のツールであればコマンドラインもしくは、テキストファイルをコマンドラインから読み込ませる事ができるはずです。あらゆる作業をGUIを避けるようにしてください。

# 1.ログを残す
　どのような作業であれ、コマンドラインで実行し、そのログを記録します。名称などを工夫し後で見つけやすいようにしましょう。

# 2.テンプレート化
　前回のログファイルで実行したコマンドから、実行コマンドの部分だけを切り出してファイルにします。今回、変更が必要な部分をテキスト置換で実行できるように切り出し、テンプレートとます。途中でキーとなる値を検索し、その値をもと・・・にという場合は、テンプレートを分けます。

　利用方法は、テンプレートファイル一式をコピーして置換しながら実行します。何度か実行するうちに変更すべき点がどこなのかハッキリします。

# 3.変数化
　テンプレートの置換部分を引数指定で実行できるように変更します。これで部分的に自動化されます。

# 4.自動生成
　コマンドの実行結果から次の作業につながる場合は引数ではうまくいかない場合があります。その場合は、実行結果からスクリプトを自動生成します。多くの場合はそれをほど複雑なものにならないでコマンドラインのみで生成できると思います。

# 5.ツールとして周知
　このレベルまで持ってこれた作業はもはや定型作業といえると思います。システムに組み込んで保守対象としましょう。
　


　その他の注意として、実行結果のログはきちんと出力されるようにしましょう。場合によっては調査用と実行用に分けて変更の可否を判断してから実行するようにします。
Mysql2::Error: Duplicate entry for key.. エラーを撃退した話 [Rails]

# はじめに
Railsでの開発でレコードに一意性制約を設けるにあたって、マイグレーションファイルに記述してスキーマに登録しました。
ですので、重複するレコードデータは自動的に保存されるときに弾かれるものと思い込んでいたために、` Mysql2::Error: Duplicate entry for key..`というエラーに遭遇しました。
その解決策を備忘録として書き記します。

# **エラー公開**

```20181202104022_create_friends.rb
class CreateFriends < ActiveRecord::Migration[5.2]
  def change
    create_table :friends do |t|
      t.integer :from
      t.integer :to

      t.timestamps null: false
    end

    add_index :friends, :from
    add_index :friends, :to
    add_index :friends, [:from, :to], unique: true　 
  end
end
```

上記のように、`friends`テーブルに`from`カラムと`to`カラムの組み合わせが一意であるようにインデックスに登録しました。

### **問題発生**

これでマイグレーションファイルを実行し、データを保存しようとしたところ、　`Mysql2::Error: Duplicate entry for key..`エラーに遭遇しました。

```
$ rake db:migrate
```

```friends_controller.rb
  def add_friend
    @friend = Friend.new(from: ..., to: ...)
    @friend.save
    .
    .
    .
  end
  end
```

コードは端折っておりますが、上記のような感じです。一意性制約を設けたために、同じカラム値の組み合わせデータを`save`メソッドで保存しようとすると、エラーが発生しました。

### **解決**

下記コード一行を`friend`モデルに追記するとエラーは無くなりました。

```friend.rb
class Friend < ApplicationRecord
  validates :from, uniqueness: { scope: :to }
end
```

スキーマに記すとともに、バリデーションの記述をモデルにも書く必要があったのですね。

ちなみに上記のコードは複数のフィールド（カラム）で一意になるようにチェックしたい時の記述になります。

# **エラー記事まとめ**
＊2018/12/04時点で、まだ2記事しかございません。これからストックしていきます。
みなさんが同様のエラーに遭遇した時の一助になると幸いです。

[Mysql2::Error::ConnectionErrorの謎を解明！](https://qiita.com/takuyanin/items/d06168f63bdbffbce3f3)
[undefined local variable or method display_meta_tags for..](https://qiita.com/takuyanin/items/c37b9842926a78531ac2)


# **終わりに**
同じエラーに遭遇してこの記事が役にたったよー、って方はいいねしてくれると嬉しいです(^^)
Tclのlambda式

# apply
Tclでlambda式を使う手段として、Tcl 8.6でapplyコマンドが標準装備されました。

実は私はlambda式のメリットを理解できていません。このため、普段はapplyコマンドを使うことがありません。

だけどもしかしたら知ってしまえば使わずにはいられないくらい便利なものかも知れない・・・とも思うわけで、勉強がてらapplyコマンドを試してみました。

# 基本的な使い方
[applyコマンドのヘルプ](http://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=http%3A%2F%2Fdocs.activestate.com%2Factivetcl%2F8.6%2Ftcl%2FTclCmd%2Fapply.html&anno=2&sandbox=1)によれば書式は以下の通りです。

```tcl
apply func ? arg1 arg2 ... ?
```

で、最も簡単な例だと

```tcl
puts [apply {{a b} {expr $a + $b}} 1 2]
```

を評価すると「3」が表示される、と。

まぁ、機能は何となく分かります。しかし問題は「で？」という感想しか出せないところ。

# ヘルプで紹介されている便利な使い方
ヘルプでは「traceのコールバックが書きやすいよ」と紹介されています。

```tcl:applyのヘルプより
trace add variable vbl write {apply {{v1 v2 op} {
	upvar 1 $v1 v
	puts "updated variable to \"$v\""
}}}
```

逆にapplyを使わなかったらこうなるんでしょうね。

```tcl
trace add variable vbl write report

proc report {v1 v2 op} {
	upvar 1 $v1 v
	puts "updated variable to \"$v\""
}
```

まぁ、確かにapplyを使うことでtraceからしか呼び出さないコールバック関数にわざわざ「report」なんてな名前を付けずに済みます。

しかし「そもそもtraceはデバッグ用の機能で他の変数の監視もするから関数化しとくべき」とか「ゴチャゴチャして可読性さがる」という印象の方が強い。

# 頑張って無理にでも使ってみた
「[TclでHello, world! ～その2～](https://qiita.com/qoLop/items/f418e5e3a20626b2d544)」に書いたTCPのEchoサーバーを無理やりapplyで書いてみました。

```tcl:hello1.tcl
socket -server [list apply {{sock host port} {
    fconfigure $sock -buffering line -encoding utf-8 -translation crlf
    fileevent $sock readable [list apply {{sock} {
		set data [gets $sock]
		if {[eof $sock]} {
			close $sock
		} else {
			puts $sock $data
		}
	}} $sock]
}}] 9999
vwait forever
```

ちぇんと動作しました。が・・・う～ん、やっぱりゴチャゴチャして理解しにくい。
Firebase Performance Monitoring の導入方法と注意点

# FirebasePerformanceMonitoring is 何?
- ライブラリ導入するだけで、アプリ実行中のパフォーマンスがわかる
- ボトルネックになっている通信などをコンソール上で確認できる
- 導入は簡単だけど注意点あり(下記参照)

# 導入方法
## Firebaseプロジェクトの準備
- コンソール上でプロジェクト作成する

<img width="373" alt="スクリーンショット 2018-12-04 0.40.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/168872/c2c3da46-3e8b-cf0e-24a5-61f35b89cb13.png">


- プロジェクトの設定から構成ファイルをダウンロードする

<img width="662" alt="スクリーンショット 2018-12-04 0.39.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/168872/fc092bbd-69c5-616c-0fef-778e748a9dea.png">

- `google-services.json` をapp配下に置く

- プロジェクトのGradleファイル

```gradle

buildscript {
    dependencies {
        classpath 'com.google.gms:google-services:4.1.0'
    }
}

allprojects {
    repositories {
        google()
    }
}
```

- アプリのGradleファイル
  - `apply plugin: 'com.google.gms.google-services'`
はファイル一番下に書かないとちゃんと動かない(失敗あるある)

```gradle
apply plugin: 'com.android.application'

dependencies {
  implementation 'com.google.firebase:firebase-core:16.0.4'
}

// ファイルの一番下に記載する
apply plugin: 'com.google.gms.google-services'
```

## Performance Monitoringを追加

- プロジェクトのGradleファイル

```gradle
buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.google.firebase:firebase-plugins:1.1.5'
    }
}

```

- アプリのGradleファイル

```gradle
apply plugin: 'com.android.application' // ←の下に書く
apply plugin: 'com.google.firebase.firebase-perf'

dependencies {
    implementation 'com.google.firebase:firebase-perf:16.2.1'
}
```

ここまでやってビルドすると、Firebaseのコンソールから情報を確認できるようになります。楽勝ですね!



# で、本題(?)はここから
- ふと、妙にアプリのビルドが遅いことに気づく
- AndroidStudioのアップデートあたりが原因だろうと思っていたが、ボトルネックを調べたら原因が判明
  - コマンド : `./gradlew --profile --recompile-scripts --offline --rerun-tasks assembleDebug`
  - なんかめっちゃ時間かかってる・・・(画像はサンプルプロジェクトで、実際のプロダクトで測定したら1分近く長くなっていた)
  <img width="964" alt="スクリーンショット 2018-12-04 1.04.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/168872/00dd97f8-0301-680a-562b-b7f84081241f.png">
- 対処法がないか調べたところ、一件だけ見つけることができた
  - https://proandroiddev.com/how-to-mitigate-slow-build-times-while-using-firebase-performance-plugin-c40e9422cf7a?gi=75a75b39b9b4
- 僕の理解では、開発中にライブラリを除外して気にしないようにするような感じ
- 素のままで使っている場合は良いけど、[カスタムトレース](https://firebase.google.com/docs/perf-mon/get-started-android?hl=ja#--1-)などやってる場合はどうすればいいか不明

# まとめ
- FirebasePerformanceMonitoringを導入した
- 導入結果をコンソール上で確認し、ボトルネックとなる処理の情報を得ることができた
- 引き換えに、それなりのビルド時間を奪われた


**解決法ご存知の方コメントいただけると嬉しいです**


# 参考URL
- https://firebase.google.com/docs/android/setup
- https://firebase.google.com/docs/perf-mon/get-started-android?authuser=0
rails new & rails -v コマンドでactivesupportのコンフリクトが起こる

#背景
railsで新たに開発するため、rails newコマンドを使った時に起こったエラーです。

#開発環境
・rails 5.0.7
・ruby 2.3.1

#コマンドとエラー文
```text:ターミナル
$rails new app-git -d mysql
/Users/hasegawataichiro/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/specification.rb:2274:in `check_version_conflict': can't activate activesupport-5.1.1, already activated activesupport-5.0.7 (Gem::LoadError)
from /Users/hasegawataichiro/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/specification.rb:1403:in `activate'
from /Users/hasegawataichiro/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:89:in `block in require'
```

#原因
まずバージョンを確認してみる。

```text:ターミナル
$ gem list | grep activesupport
activesupport (5.1.1, 5.0.7, 5.0.1, 5.0.0.1, 4.2.6, 4.2.5)
```

```text:ターミナル
$ gem list | grep rails

・
・
rails (5.0.7, 5.0.1, 5.0.0.1, 4.2.6, 4.2.5)
・
・

```
activesupportには、バージョン5.1.1があるのに対し、railsには5.1.1が存在しない。
どうやらrails と activesupport のバージョンを一致させる必要があるみたいです。

#解決法
activesupport5.1.1のgemをアンインストール

```text:ターミナル
$ gem uninstall activesupport -v 5.1.1
```
再び rails new　するとできました。

activesupportのgemはrailsと同時にインストールされるみたいです。
文字列の前後の空欄を削除したい。

文字列の前後の空欄を削除したいときの手法です。

以下のcsvファイルを読み込んだ場合を例に説明します。
データフレームに用いたヘッダーの前後に空欄があり、扱いづらいときに用いた対処法です。
######　test2.csv
![test2.png](https://qiita-image-store.s3.amazonaws.com/0/319484/408c6910-002d-36e7-a298-4b11429be41c.png)



```test.py
import pandas as pd

#csvファイルを読み込む
test_info=pd.read_csv("test2.csv",sep=',',header=0,index_col=None)
#ヘッダー部を表示
test_info.columns
```

空欄があることがわかる。

```
Index(['   INDEX', '    SITE', '      TNUM', '    RUNS', '    FAILS',
       '         LLIM', '          HLIM', '           MIN', '          MEAN',
       '           MAX', '         RANGE', '           STD', '           CP',
       '            CPK', '      UNITS',
       '    TNAME                               '],
      dtype='object')
```
<b>str.strip()を用いて文字列前後の空欄を削除する。</b>

```test.py
#文字列前後の空欄を削除
test_info.columns=test_info.columns.str.strip()

#ヘッダー部を表示
test_info.columns
```

#####結果
ヘッダーの文字列前後の空欄が削除された。

```
Index(['INDEX', 'SITE', 'TNUM', 'RUNS', 'FAILS', 'LLIM', 'HLIM', 'MIN', 'MEAN',
       'MAX', 'RANGE', 'STD', 'CP', 'CPK', 'UNITS', 'TNAME'],
      dtype='object')
```
OpenMediaVaultのNFSサーバはrpc.statdが動いていない！？

# 経緯

KubernetesのPVC用にOpenMediaVaultをNFSサーバにして動的プロビジョンできるようにしたのですが、一部のアプリ、例えばGrafanaの起動がハングする事象が発生しました。

結論を言いますと、GrafanaはPVにSQLiteのDBをもちますが、そのときにロックの獲得に失敗していたため内部的にリトライが走り続けていたようです。

# 原因

OpenMediaVaultでrpc.statdが動いていませんでした。rpc.statdはNFSv2/v3のロック制御のためのプロセスです。これが動いていないために、NFSクライアント側でロックの獲得に失敗していたようです。

# 対応

OpenMediaVaultサーバにsshし、rpc-statdサービスを起動しました。rpc.ではなくrpc-であることに注意。

```
# systemctl enable rpc-statd
# systemctl start rpc-statd
```
webrick


サーバーのオブジェクトを作成してくれる

```ruby

require 'webrick'
srv = WEBrick::HTTPServer.new({ :DocumentRoot => './',
                                :BindAddress => '127.0.0.1',
                                :Port => 20080})
srv.mount('/view.cgi', WEBrick::HTTPServlet::CGIHandler, 'view.rb')
srv.mount('/foo.html', WEBrick::HTTPServlet::FileHandler, 'hoge.html')
trap("INT"){ srv.shutdown }
srv.start


同じディレクトリ配下に　hoge.htmlファイルを作成

<h1>yahooo</h1>
```
[RHEL]/etc/pam.d/system-authにおけるpam_pwquality.soのオプション

# はじめに
仕事でちょっとpwquality.soのオプションを調べる機会があり、その中でドツボにハマったので備忘がてら記載します。

# pam_pwquality.soとは
パスワードの強固さを検証するためのモジュール。
`/etc/pam.d/system-auth`や`/etc/pam.d/password-auth`の中でロードする。
（二つのファイルの違いは謎ですが、「system-auth＞password-auth」の優先度があるみたいです（詳しくは宿題））
オプションは`/etc/security/pwquality.conf`で指定することもできる。

（RHEL7マニュアル）
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/security_guide/chap-hardening_your_system_with_tools_and_services

デフォルトの記載はこんな感じ。

    password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=

特にハマったのが、「local_users_only」と「authtok_type」オプションの意味がなかなか見つからなかったことです。

# 調べ方と調べた内容
結論だけ言うと、`man pam_pwquality`で調べるのが一番早いし楽でした。

（参考ページ）
https://www.unix-power.net/networking/post-742

以下、オプションについて調べた結果。

|オプション|意味|
|:--|:--|
|local_users_only|/etc/passwdに記載されているユーザのみをパスワード検証の対象にする|
|authtok_type|パスワード変更時のプロンプトを指定（"New **UNIX** password: "や"Retype  **UNIX**  password:  "の"**UNIX**"の部分。指定が無ければ"UNIX"になる）|
コードレビューとプログラミングの表現力[雑感]

自分がコードレビューをするときの指針を考えていたので、文章化してみます。ここでのコードレビューとは、共同開発時のプルリクエストに対するコードレビューです。

私がコードレビューで悩んでいたケースのひとつが、このコードには別の書き方もあり、自分としては別の書き方のほうが「好み」だというときです。

プログラミングには、１つの目的を達成するために複数の方法をとれる場合があります。その事自体は悪いことではありません。どの書き方がいいか、好みかというのは個人によって差があります。経験や開発に対する思想によっても違いがでてきます。しかしコードレビューで変更を依頼するときには、明確な理由をつける必要があります。少なくとも私はそう心がけています。

別の表現に変更を依頼するのはコードレビューの目的から逸脱してるのではないだろうか…読みやすさやコーディングスタイルの統一性などを含めたコードの品質の視点から、明確な理由を言えないのに変更を依頼していないだろうか…ということで悩んでいました。

プログラミングには個性がでる。だから別の表現があってもいいのだ。というのが私の今のスタンスです。レビューのときに自分とは違う書き方をするコードを見ても、ああこんな表現もあるんだなとニュートラルな気持ちでいられます。違いをみとめたうえで、変更する合理的理由を考えて、なければそれでよし、という指針を採用しています。

というようなことを考えました。
EC2（Amazon Linux）にSQL::Translatorをインストール

## 概要

Amazon LinuにSQL::Translatorをyumでインストールするとバージョンが古く、
思わぬ不具合に遭遇したので別の方法でインストールする。

### 主にハマった問題

MySQLにおいてON UPDATEが解釈できずスカラーリファレンスに化けてしまう。
（この問題自体は `0.11019 2014-09-02` で解決済み）

```diff
+ DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
- datetime on update SCALAR(0x3333b68) NULL DEFAULT CURRENT_TIMESTAMP
```

#### 参考の修正履歴

- https://metacpan.org/changes/distribution/SQL-Translator#L77
- https://github.com/dbsrgits/sql-translator/commit/1fb4f40fa5d6b158b7241b01c41be3e2c1d8edad#diff-9738439aca40d63b897311c4de413a22

### yum で入れた場合のバージョン

```bash
$ sudo perl -MSQL::Translator -e 'print $SQL::Translator::VERSION'
0.11016
$ yum list | grep perl-SQL-Translator
perl-SQL-Translator.noarch           0.11016-1.2.amzn1             @amzn-main
```

## 環境

- Amazon Linux AMI 2018.03.0.20180811 x86_64 HVM GP2
- Amazon Linux AMI 2017.03.1.20170623 x86_64 HVM GP2

Amazon Linux 2 AMI 2.0.20181114 x86_64 HVM gp2だとyum listでperl-SQL-Translator上がってこない。

## 手順

### 開発関係のパッケージをインストール

```bash
$ sudo yum install gcc gcc-c++ perl perl-devel
```

`$ sudo yum groupinstall "Development tools"` でもいいかも？

### yumでインストールしてしまっている場合は削除する

```bash
$ sudo yum remove perl-SQL-Translator.noarch
```

### cpanmのインストール

```bash
$ curl -L https://cpanmin.us | perl - --sudo App::cpanminus
```

#### sudoでcpanmを使えるようにする

上記コマンドでインストールすると `/usr/local/bin/` にスクリプトが配置される。
このままだとsudoのPATHが通っていないのでsecure_pathをいじるか、secure_pathが通っている場所にシンボリックリンクを貼る必要がある。

今回はsecure_pathを変更する。

``` bash
$ sudo visudo
```

```diff
- Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
+ Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
```

### SQL::Translatorのインストール

```bash
$ sudo cpanm SQL::Translator -n
$ sudo perl -MSQL::Translator -e 'print $SQL::Translator::VERSION'
0.11024
```
欠損値を処理する方法

# はじめに
データ分析をしていると欠損のあるデータに出会います。欠損値を埋める方法はいくつかありますが、ここでは簡単なものを列挙します。

# 参考
- https://pandas-docs.github.io/pandas-docs-travis/generated/pandas.Series.interpolate.html

# 手順
下記の欠損があるデータを使用します。

```python
import numpy as np
from numpy import nan as NA
import pandas as pd

np.random.seed(0)
df = pd.DataFrame(np.random.rand(5,4), columns=['A','B','C','D'])

# わざと欠損にする
df.loc[1,'A'] = NA
df.loc[2:4:2,'B'] = NA
df.loc[1:2,'D'] = NA
```
<img width="283" alt="スクリーンショット 2020-02-26 22.54.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/661d7426-7fca-d29d-2c95-7bd1e2bfaf7c.png">


## リストワイズ削除
欠損を埋めるのではなく、欠損がある行は分析に使用しないという考えです。欠損のある行をすべて削除します。

```python
df.dropna()
```

<img width="283" alt="スクリーンショット 2020-02-26 22.55.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/6b1b7b15-8c85-18a4-b225-78960823f2b4.png">


## ペアワイズ法
欠損のある行をすべて削除してしまうとデータが少なすぎるので、欠損の少ない列を使用することにし、特定の行を取り出してから欠損を削除します。

```python
df[['A','C']].dropna()
```
<img width="155" alt="スクリーンショット 2020-02-26 22.55.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/0e386c6a-c6ff-d9d0-0f85-ba251d227929.png">


## 決められた値で一律に埋める
とりあえずの処理として一律で埋めることはありえます。値は平均値や中央値にすることが多いです。

```python
df.fillna(0)
```

<img width="280" alt="スクリーンショット 2020-02-26 22.56.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/e6da1546-fca8-4cfc-051a-3c5790d4c478.png">


## 前の行の値で埋める
時系列データでは、データの種類によっては計測間隔が異なることがあります。例えば気象データでは、観測地点によっては降水量は毎時、雲量は3時間ごと、などです。欠損している部分の真の値はわからないので、前回計測時点の値で補完するということは十分にあり得ます。

```python
df.fillna(method="ffill")
```

<img width="280" alt="スクリーンショット 2020-02-26 22.57.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/d93778da-26d6-c44b-2ba7-0a6f847ca170.png">


## 線形補間・スプライン補間
`method`で補間方法を、`limit_direction`と`limit_area`で補間する範囲を指定します。
`limit_area`は0.23以降の機能なので、google colabを使用している場合はバージョンに注意が必要です。

```python
df.interpolate(method='linear', limit_direction='forward', limit_area='inside')
```

<img width="280" alt="スクリーンショット 2020-02-26 22.58.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211712/87400c00-3929-dd0e-8498-6cfe1c9dc056.png">
ResponderとGrapheneで１０分くらいでGraphQLサーバ作る

きっかけは下記の記事です。

[人間のためのイケてるPython WebFramework「responder」、そして作者のKenneth Reitzについて](https://blog.ikedaosushi.com/entry/2018/12/01/195512)


# Responder のインストール

## 前提環境

python 3.6以上。でないと後でpipenvに怒られる。

## 使いやすくするためのpipenvをインストール

```sh

pip install --user pipenv
```

## pipenvで環境を用意する

```sh
mkdir responder
cd responder
pipenv install responder --pre
```

## pipenv shellでresponderの環境に入る

```
pipenv shell
```

## サーバアプリの実装

下記ファイルをコピーして、sample.pyを作成する。

注意！　ファイル名を `graphql.py`にすると、`graphql-core`と名前がかぶるらしく、途中で失敗するので、**ファイル名はgraphqlじゃないものを選ぶ** [参考. grapheneのissues](https://github.com/graphql-python/graphene/issues/441)

```sample.py
import responder
import graphene

api = responder.API()

class Query(graphene.ObjectType):
    hello = graphene.String(name=graphene.String(default_value="stranger"))

    def resolve_hello(self, info, name):
        return f"Hello {name}"

schema = graphene.Schema(query=Query)
view = responder.ext.GraphQLView(api=api, schema=schema)

api.add_route("/graph", view)

if __name__ == '__main__':
    api.run()
```

## ModuleNotFoundErrorの解消

このままサーバを起動すると2018/12/03現在`ModuleNotFoundError: No module named 'starlette.lifespan'`が出る。

https://github.com/kennethreitz/responder/issues/255

回避するには`starlette`の0.8を指定してインストールする。

```
(pipenv shell内で)
pip install starlette==0.8
```

## サーバ実行

```sh
python sample.py
```

## 実行画面

`localhost:5042/graph`にブラウザからアクセスすると下記のような画面が見える。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/96277/bfa42442-78e5-905f-9345-c1659a632d57.png)

`{hello}`とクエリを打てば、指定した結果が返ってくる。

以上。
VBAでOutlookの仕様『宛先へ付与される「’」』を表示名ごと削除する

# 退屈なことはVBAにやらせよう
OutlookでもExcelと同じようにVBAが使えます。便利なのに、Excelと比較するとあまり知られていないため、少しでも広まればと。
なお、本コードはOutlook2013、2010で動作を確認しています。

# Outlookの仕様『宛先への「’」シングルクォーテーション付与』について
Outlookは、宛先、CC、BCCをシングルクォーテーションで囲う仕様になっています。
個人的に、これがなんとなく受け入れ難いです。自分で入れたわけではない余計な文字ですし。
また、下記の事象も発生し、とことんOutlookの仕様に抵抗するしかないと思いました。

- 『'』だけでなく、『"』に囲まれることがある
- 『'表記名'<'xxx@xxx.com'>』となった場合、『'』もメールアドレスの一部として認識されメール送信できない
- 企業文化ですが、顧客に返信する際、表示名に『様』をつける

# 「'」と表示名を削除するコードとボタンの設定

下記を参考に、たとえばメール作成画面に『’』削除ボタンを配置します。
[ボタンにマクロを割り当てる](https://support.office.com/ja-jp/article/%E3%83%9C%E3%82%BF%E3%83%B3%E3%81%AB%E3%83%9E%E3%82%AF%E3%83%AD%E3%82%92%E5%89%B2%E3%82%8A%E5%BD%93%E3%81%A6%E3%82%8B-728c83ec-61d0-40bd-b6ba-927f84eb5d2c)

```VB
Private Type typeMailAddress
    enabled As Boolean
    addr As String
    mailtype As Integer
End Type

Const MSG_DELETE_SINGLEQUOTATION As String = "「’」を削除しました"

Public Sub DelSinglequotation()

    Dim orgMail As MailItem
    Set orgMail = ActiveInspector.CurrentItem
    
    ' To,CC,BCCに設定されているメールアドレスの数
    Dim cntAddress As Long
    cntAddress = orgMail.Recipients.Count  
    
    '「’」削除後のメールアドレスを一時的に格納する
    Dim wkMailAddress() As typeMailAddress
    ReDim wkMailAddress(cntAddress) As typeMailAddress
    
    Dim i As Long
    Dim orgRecipient As Recipient
    
    '最後尾のMailAddressから対象にすることにより、メールアドレスの並びを出来る限り保持
    For i = cntAddress To 1 Step -1
        Set orgRecipient = orgMail.Recipients.Item(i)
        
        If orgRecipient.AddressEntry.Type = "SMTP" Then 'Exchangeは対象外
            wkMailAddress(i).addr = Replace(orgRecipient.address, "'", "")
            wkMailAddress(i).mailtype = orgRecipient.Type
            
            orgMail.Recipients.Remove i
            wkMailAddress(i).enabled = True
        Else
            wkMailAddress(i).enabled = False
        End If
    Next
    
    Dim newRecipient As Recipient

    '先頭のMailAddressから対象にすることにより、メールアドレスの並びを出来る限り保持
    For i = 1 To cntAddress
        If wkMailAddress(i).enabled = True Then
            
            ' 退避させた[’]無しメールアドレスを追加する
            Set newRecipient = orgMail.Recipients.Add(wkMailAddress(i).addr)
            newRecipient.Type = wkMailAddress(i).mailtype
            newRecipient.Resolve
        End If
    Next
    
    orgMail.Display
    MsgBox MSG_DELETE_SINGLEQUOTATION
End Sub
```

# 備考
表示名がなければ『様』を書かなくても良いんじゃないかという発想ですが、むしろ自動で付けるのもありな気がしました。
今後もOutlookの仕訳ルールで出来ないことをVBA(+α)で実現していきたいと思います。
【Delphi】PostgreSQLのデータ表示エラー

# はじめに
これは[Delphi Advent Calendar 2018](https://qiita.com/advent-calendar/2018/delphi)の4日目の記事となります。

現在サーバーリプレイスの移行作業(Windows Server 2008R2 + Oracle 11g から Windows Server 2016 + PostgreSQL 9.6)を行っています。
Delphi 5 で作成されたアプリケーションが残っており、幾つかは Delphi から C# に移行したのですがコストや時間の関係から、Delphi 5 のままデータベースを Oracle から PostgreSQL に変更する対応をしています。

# SQLのVIEWが表示されない
実際に改修作業を行っている同僚から、DelphiのClientDataSetでグリッド表示する際にSQLのVIEWを表示しようとするとアプリケーションが落ちるという報告がありました。
だたし正常に表示されるVIEWもあるとのこと。ちなみに Oracle では問題なかった。
PostgreSQLは、psqlODBC(PostgreSQL ODBC driver) 32bit版のUnicodeをADOで接続しています。

同僚曰く、表示されるVIEWと表示されないVIEWの違いとして、表示されないVIEWには文字列連結のパイプ処理やMAXなどの関数を使用していることでした。ただ関数でも数値型だと表示される。

他の同僚も交えて調査してみたところ、PostgreSQLで関数を使用したVIEWを作成して保存すると自動的に「::text」が付くということです。
試しに型を「::text」から「::character varying(5)」に変更してみるとVIEWが正常に表示されるようになりました。

原因として「::text」だと桁数が定まらないので表示できなくなってしまうのではないでしょうか。
もっとも、Delphi 5 と古いので現在のDelphiでは当てはまらないかも知れません。

# 最後に
Delphiの代入演算子は「:=」でコロン(:)を忘れてコンパイルエラーになるなど面倒だなと思ったのですが、人工知能ブームで数学を意識するようになり数学に関する記事を書くようになって、代入演算子の見方を変えてもいいかなと思いました。

そんな記事を以前書きましたでの、良かったら読んでみてください。
[変数の代入演算子と等価演算子について](https://qiita.com/yaju/items/16d91d58ae65af1ecab9)
VaporをDocker化し、CentOS上で動かす

VaporはSwiftがサポートされているUbuntu上でしか動作しませんが、Dockerを使うことでUbuntu以外のOS上でも動かすことができます。本記事ではVaporをCentOS上で動かします。

まず、ubuntu:16.04をベースイメージとして、Vaporのイメージを作成します。下記のファイルは[GitHubGist](https://gist.github.com/O-Junpei/aa3e41db8c2cddb01c9bee07c3022bf5)に上げてあります。

```dockerfile:Dockerfile
FROM ubuntu:16.04

RUN apt-get update && apt-get install -y \
  nginx \
  git \
  vim \
  wget \
  curl
RUN /bin/bash -c "$(wget -qO- https://apt.vapor.sh)"
RUN apt-get install -y \
  swift \
  vapor

RUN rm /etc/nginx/nginx.conf
COPY vapor.conf /etc/nginx/conf.d
COPY nginx.conf /etc/nginx

RUN vapor new Hello --template=web
WORKDIR /Hello
RUN swift build
RUN vapor build

EXPOSE 80

COPY entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]
```


```bash:startup.sh

#!/bin/bash

nginx
vapor run
```

```conf:nginx.conf
user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
	worker_connections 768;
	# multi_accept on;
}

http {

	##
	# Basic Settings
	##

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	# server_tokens off;

	# server_names_hash_bucket_size 64;
	# server_name_in_redirect off;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;

	##
	# Logging Settings
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";

	# gzip_vary on;
	# gzip_proxied any;
	# gzip_comp_level 6;
	# gzip_buffers 16 8k;
	# gzip_http_version 1.1;
	# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

	##
	# Virtual Host Configs
	##

	include /etc/nginx/conf.d/*.conf;
}
```


```conf:vapor.conf
server {
        listen 80;
        listen [::]:80;
        server_name 0.0.0.0;

        location / {
                proxy_set_header Host $http_host;
                proxy_pass http://localhost:8080;
        }
}
```

Dockerfileの準備ができたらビルドを行います。
以下のコマンドを実行し、ビルドとランを行なってください。
localhost：80にブラウザからアクセスし、Vaporのロゴが表示されていることを確認してください。

```bash
$ docker build -t simple-vapor:latest .
$ docker run -d -p 80:80 simple-vapor:latest
```

Vaporのロゴが表示されていることを確認したらDockerHubにアップロードします。
ここでの kabigon　はDockerHubでの私のユーザー名なので、適宜変えてください。

```bash
$ docker build -t kabigon/simple-vapor .
$ docker push kabigon/simple-vapor
```

次にCentOS7のサーバーインスタンスをConohaで作成し、Dockerをインストールします。
CentOS7はyumで簡単にインストールすることができます。
Conohaちゃん可愛い。


```bash
ssh root@IP_ADDRESS
```

```bash
sudo yum -y install docker
docker --version
```


Dockerのインストールが終わったらDockerを起動します。

```bash
sudo systemctl start docker
sudo systemctl enable docker　　// 自動起動設定
```

先ほどDockerHubにアップロードしたイメージをダウンロードして起動します。

```bash
docker pull kabigon/simple-vapor
docker run -d -p 80:80 kabigon/simple-vapor
```

ブラウザからサーバーインスタンスのIPアドレスにアクセスするとVaporのロゴが表示されます。
FlutterでWebviewを表示する

[webview_flutter](https://pub.dartlang.org/packages/webview_flutter#-readme-tab-)がpublishされたのでwebviewを表示してみたいと思います。
versionは `v0.0.1`

# 導入
pubspec.yamlに下記を追加

```yaml
  webview_flutter: ^0.3.0
```

ios/Runner/Info.plistに下記を追加

```xml
	<key>io.flutter.embedded_views_preview</key>
	<true/>
```


# 実装例

```dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() => runApp(MaterialApp(home:WebViewExample()));

class WebViewExample extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  WebViewController _controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Webview Demo'),
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.refresh),
              onPressed: () {
                _controller.loadUrl('https://www.twitch.tv/');
              },
            ),
            IconButton(
              icon: Icon(Icons.add_comment),
              onPressed: () {
                showDialog(context: context, builder: (context) {
                  return AlertDialog(title: Text('webviewの上に表示'),);
                });
              },
            ),
          ],
        ),
        body: WebView(
          initialUrl: 'https://youtube.com',
          javascriptMode: JavascriptMode.unrestricted,
          onWebViewCreated: (WebViewController controller) {
            _controller = controller;
          },
        ),
    );
  }
}

```

### Webviewでページを表示する

initialUrlで設定したページを表示することができます。
また、JavaScriptを有効にする場合にはunrestrictedを設定します。
デフォルトだと無効になっているので注意。

```
initialUrl: 'https://youtube.com',
javaScriptMode: JavaScriptMode.unrestricted,
```

### 任意のページを読み込む

webviewを作成した際にwebviewを操作するControllerを受け取ることができます。

```dart
onWebViewCreated: (WebViewController controller) {
  _controller = controller;
},
```

このControllerを利用してボタンをタップした際にページを読み込むようにしてみます。

```dart
            IconButton(
              icon: Icon(Icons.refresh),
              onPressed: () {
                _controller.loadUrl('https://www.twitch.tv/');
              },
            ),
```

### Webviewの上にWidgetを表示する

おそらくflutterではメジャーなこちらの[flutter_webview_plugin](https://pub.dartlang.org/packages/flutter_webview_plugin)だとwebviewが最前面のレイヤーに表示されるため、
webviewの上にwidgetを表示することができませんでした。
[webview_flutter](https://pub.dartlang.org/packages/webview_flutter#-readme-tab-)を使えばダイアログもwebviewの上に表示することができます。


![flutter-webview.gif](https://qiita-image-store.s3.amazonaws.com/0/236405/2be99da5-260a-22da-155c-9f0988afa012.gif)


まだちょっと機能不足ではありますがwebviewを使う場合は選択肢に入れてもいいかなと思います。
社会人Androidエンジニアになって１年が経ち、もうすぐ２年が経とうとしている

この記事は[nana music Advent Calendar 2018](https://qiita.com/advent-calendar/2018/nana-music)の4日目の記事です。

自分はAndroidエンジニアとして今の会社に入社して、社会人となりました。
社会人1年目はわからないことだらけで、まともに出来たと思えた仕事は数えられるほど少なかったです。
そんな自分の1年間で得た知見や経験を社内勉強で発表したりもしました。

[入社して１年が経ったので振り返ってみた/Speakerdeck](https://speakerdeck.com/fujikinaga/shen-iimian-qiang-hui-vol-dot-3)

今回は１年目の振り返りと、２年目ではAndroidエンジニアとして必要なスキルや知識などがどう変わったか、などをお伝えできればと思います。

## 社会人１年目 : 好き勝手やっていた趣味エンジニアからの脱却
自分は社会人エンジニアになるまでは、1人でしか開発したことがなく、その頃はサードパーティーのライブラリは好きなものを選び使いたい放題、好きな(適当な)設計で書き放題、面倒なところはサボり放題、といった感じで良くも悪くも自由にやれていました。入社するとそんな環境が一変します。

- 作りたいものを期限を設けずに作れたが...
    - **スクラム開発**を採用してます
    - タスクはそれぞれイシューにして**カンバン**で管理します
    - このイシューは**1スプリント**で終わらせましょう

- 作業が終わったらmasterにプッシュ、ブランチはたまにしか切らなかったが...
    - **Git-flow**に従ってブランチワークしていきましょう
    - レビューするので**プルリク**出してください
    - 差分は少なめにプルリク出すようにお願いします。
    
- 淡々と1人で作業していたが...
    - 1スプリントごとに**KPT**やりましょう
    - 困ってることがあれば1on1で話しましょう
    - **お菓子でも食べながら**バグ出し会やりましょう
    - ホウ・レン・ソウはこまめに行い、情報共有していきましょう
    - 朝会は毎日やります
    - 朝会の後は**ラジオ体操**しましょう

という感じで、業務としての開発に慣れるまでには時間がかかりました。
中でも、個人では出来なかった、プルリクの相互レビューは大変ですがとても有意義だなと感じています。
コーディングに自信がない中で他人のコードをレビューする、という環境が常に緊張感を与えてくれていたし、書く時間よりも読む時間の方が増えたことで、より多くのコードに触れることができています。

1年目は、社会人としての働き方に慣れること、既存のアプリコードの理解、Androidの技術トレンドのキャッチアップに手一杯で、与えられた仕事をなんとかこなしていました。２年目になると少し視野も広がり、余裕も出てきました。

### １年目に覚えた技術などなど
`MVP/Retrofit/OkHttp/RxJava/RxAndroid/MediaSession/ExoPlayer/
MaterialDesign/Glide/IAB3/MPAndroidChart`

## 社会人2年目 : メンテのしやすいコード、保守性の高いコードを意識した開発への挑戦
普段の業務をこなしている時に、気持ち的な余裕が生まれてきて、勉強会で得た知見や新しい技術をとりあえず簡単に取り入れてみようとしてみたり、休日を利用して仕事で使えない技術を試してみる、という機会が増えたような気がします。結果的にプログラミングにかける時間は１年目よりも大幅に増加しています。

こうした流れからか、既存のコードをより良いものにしていこう、ユーザーにストレスなく使ってもらえるにはどうしたらいいか、ということを頻繁にチーム内でも議論したり、考えるようになってきました。
大きく以下の2つに分けれそうです。

- アプリの見た目や動きが微妙なもの（**ユーザーに影響がある部分**）
    - デザインチームやPOも巻き込んで改善していく
    - MaterialDesign、MaterialThemingを絡めたデザイン的な提案を意識
- 動いてはいるが、書き方が微妙、もしくは古いもの(**ユーザーに影響がない部分**)
    - チーム内で改善案を出し、解決する
    - 影響範囲の広い修正はQAチームにも確認してもらう
    - テスタブルな実装、QAで出る不具合が少なくなるような実装を意識

こういった問題解決への動きを率先して引っ張ったり、解決のためのMTGに出席することが増えてきたのは1年目の時にはできていなかったことです。
コードを書く以前に決めるべき要件整理や仕様の策定の場所に参加できているのは良い勉強になっているなと感じます。

さて、3年目に突入したら何を勉強していこうかなぁ

### 2年目に覚えた技術などなど
`Kotlin/MVVM/Dagger2/Jetpack/AAC/ConstraintLayout/
DataBinding/AdTech/Hyperion/Firebase`

## 社会人3年目 : 苦手な分野への挑戦
抽象的ですが、学習コストが高いもの、一見地味なもの(出来るとかっこいい)、すぐには結果が出ないもの、などを勉強していこうかなぁと思います。
例えば、

- テスト
- Thread処理
- カメラや動画などハード寄りな機能
- DDD
- CI/CD

などでしょうか！

## まとめ
今回は、Qiitaにほとんど記事をあげたこともなかったので、自分事で恐縮ですが書きやすいテーマで投稿させていただきました。

今後はこれを機に技術的な投稿もやっていければ良いなと思います！

弊社 nana musicのアドベントカレンダーはまだまだ続きます。
技術的な記事も2回目でどこかで投稿しようかなぁ:eyes:
明日は @yamanemur さんが華麗にお届けします！
12-4 portmidiとrtmidi

https://adventar.org/calendars/3353 の4日目エントリーです。

## クロスプラットフォームMIDI API

前回はオーディオAPIに標準といえるものが無くプラットフォーム固有のAPIになる、という話を書きましたが、MIDIについても同様にプラットフォーム固有のAPIになります。一方でアプリケーションで使用したいMIDIの機能は「デバイスに接続して、MIDIポートを開いて、MIDIメッセージを送受信する」程度の単純なものであることが多いです。

これを実現できる程度に単純化されたクロスプラットフォームのMIDIライブラリがいくつか開発されています。有名なのがportmidiとrtmidiでしょう。どちらもCのAPIを公開しているので、他言語からのバインディングが比較的容易に行なえます。rtmidiのAPIはもともとC++のみだったのですが、しばらく前にわたしがCのAPIを追加して、その後何人かのコントリビューターが改良を加えているようです。

## portmidiとporttime

一般的には、MIDIのデータ転送はオーディオのデータ転送ほど大規模ではなく、処理中のデータの加工も比較的手軽に行えます。一方で、リアルタイム性については（中で行われる処理が軽量であるとしても）オーディオに準ずる正確性が期待されます。また、オーディオのチャンネルは大概はステレオ構成でデータも単純なPCMデータですが、MIDIのトラックは多数になることがあり、それらを1回のMIDIメッセージ処理時間の間に全て処理することが求められます。現代的にはいわゆるMIDIデバイスとのやり取りで問題になることは少ないと思いますが、たとえばVSTなどを活用したソフトウェア・シンセサイザーのチャンネルであるとしたら、処理が重くなるかもしれません。

portmidiは、リアルタイム処理を意識したタイマーライブラリporttimeがそのサブセットとして含まれています。rtmidiについては、リアルタイム呼び出しはアプリケーション側の責務ということになります。

## メッセージを構造化するか否か

わたしはどちらかというとportmidiよりはrtmidiのほうが好みなのですが、その最大の理由はMIDIメッセージを無理に構造化しないことにあります。MIDIデータはタイムスタンプとMIDIイベントのペアを時系列順にやり取りするものであり、MIDIイベントはチャンネル、ステータスコード、1バイトまたは2バイトの引数またはシステムエクスクルーシブメッセージやメタデータについては可変長の引数、といった構造になっています。

これをMIDI仕様に合わせて構造化することもできるのですが、SMFからロードしてそのままMIDIプレイヤーやMIDIデバイスに転送したい場合、特にパフォーマンスを考慮して無駄なエンコード／デコード処理を施したくない場合には、メッセージの構造化は無駄な処理でしかありません。残念ながらportmidiはメッセージの送受信にバイト列ではなく構造化されたメッセージ（正確には、32bit intに変形した短いメッセージか、構造化したF[n]hメッセージ）を受け取るようになっているので、無駄な処理が避けられません。

http://portmedia.sourceforge.net/portmidi/doxygen/group__grp__io.html#g9257b8cddc72ae5a1e142dc0ab478ae6

## MIDI APIを各種言語で実装する場合のアプローチ

わたしはMono/.NET環境向けのクロスプラットフォームMIDIライブラリとしてmanaged-midiを公開しているのですが、MIDIデバイスアクセス部分には当初はportmidiとrtmidiのバインディングを中心とした構成となっていました。しかしportmidiは前述の問題で抵抗感があり、またrtmidiにもプラットフォームによって生じる問題があり、さらにいずれの場合もプラットフォームごとにビルド済バイナリを一緒に提供しなければならないのは面倒なので、結局自前でWinMM/CoreMIDI/ALSAのバインディングを作ってしまいました。

このアプローチだと、余計なネイティブライブラリ配布の手間が省けて楽ですが、プラットフォームごとのMIDIアクセスのAPIを学ばなければならなくなるので、深入りするのでなければ、あまりお勧めはできません。一方でクロスプラットフォームAPIが提供していない機能にも、比較的容易に対応できるでしょう。

同様のアプローチを採っているものとしては、Rust用のAPIであるmidirがあります: https://github.com/Boddlnagg/midir
【Ruby】インスタグラムのアカウント（ユーザ）名の正規表現

## 意外とスニペットが落ちていなかった

### 前提条件

- 許可
 - 英数字
 - .（ピリオド）
 - _（アンダースコア）
- 拒否
 - 先頭がピリオド
 - 末尾がピリオド

```:正規表現
\A(?!\.)[\w.]+(?<!\.)\z
```

### 解説
- `(?!\.)` ピリオドで開始する事を否定（否定先読み）
- `[\w.]+` アルファベット・数字・アンダースコア・ピリオドの1回以上連続
- `(?<!\.)` ピリオドで終了する事を否定（否定後読み）

### 参考
- [Rubular](http://rubular.com/)
- [正規表現：文字列を「含まない」否定の表現まとめ | WWWクリエイターズ](http://www-creators.com/archives/1827#i-6)