kivantium活動日記

プログラムを使っていろいろやります

Docker上で開発を行う

ライブラリの開発をするときに、現在のバージョンと開発中のバージョンの性能比較をすることがあります。同じ名前のライブラリが1つの環境に複数存在すると面倒なことになるのでDockerを使って環境を分けることにしました。そのときに使ったコマンドについて記録します。

Dockerの仕組みやインストール方法については触れません。

Ubuntu 16.04のコンテナのダウンロード

Ubuntu 16.04を使うには

docker pull ubuntu:16.04

とします。

Dockerイメージの実行

Dockerイメージを入手したら

docker run -it ubuntu:16.04 /bin/bash

を実行するとコンテナ上でシェルが実行されます。オプションの意味は以下の通りです。

  • -i: 標準入力を開いたままにする
  • -t: 擬似ttyに接続する。

コンテナの実行中にCtrl+PCtrl+Qを続けて押すとデタッチされます。

アタッチするには、

docker ps

で現在実行中のコンテナのCONTAINER IDを確認してから

docker attach <CONTAINER ID>

を実行します。

別の実行方法

上の方法でコンテナを実行するとCtrl+Dをうっかり押したときにコンテナが終了してしまいます。以下のようにすると回避できます。

まずバックグラウンド実行のオプションをつけた状態でコンテナを起動します。

docker run -it -d --name mycontainer ubuntu:16.04

シェルを開くときには

docker exec -it mycontainer /bin/bash

のようにコンテナ上でbashを実行します。

docker stop mycontainer

とすればコンテナが停止します。

参考 - Dockerコンテナ内で操作 attachとexecの違い

Dockerイメージの作成

ライブラリの開発に必要なパッケージをインストールしたDockerイメージを用意しておくと便利です。こういうときにはDockerfileというファイルを作ります。

OpenBabel 2.4.1をmakeしてインストールしてあるDockerイメージを作るときに使ったDockerfileの例を示します。

FROM ubuntu:16.04
RUN apt-get update && apt-get install -y \
  build-essential \
  cmake \
  libcairo2-dev \
  libeigen2-dev \
  wget \
  zlib1g-dev
RUN wget https://github.com/openbabel/openbabel/archive/openbabel-2-4-1.tar.gz && \
  tar xf openbabel-2-4-1.tar.gz && \
  cd openbabel-openbabel-2-4-1/ && \
  mkdir build && cd build/ && \
  cmake .. && make -j ${nproc} && make install

これをDockerfileという名前で保存し、

docker build -t openbabel2.4.1 .

を実行すると openbabel2.4.1 という名前のDockerイメージが作成されます。

ファイルのコピー

ファイルをコピーするにはホスト側で

docker cp hoge.txt <CONTAINER ID>:/huga

のようにすればいいです。

停止したコンテナの扱い

停止したものも含めたコンテナ一覧を見るには

docker ps -a

とします。

docker start <CONTAINER ID>

でコンテナを起動することができます。

docker rm <CONTAINER ID>

でコンテナを削除することができます。

docker ps -a -qでIDの一覧を出せるので、コンテナを一括で削除するには

docker rm `docker ps -a -q`

とすればよいです。(参考: Dockerイメージとコンテナの削除方法

イメージの削除

イメージ一覧は

docker images

で確認できます。

削除するには

docker rmi <イメージ名>

とすればよいです。

他に有用なコマンドを学んだら追記します。

2018年9月

8月号はなしです。

中国に行ったあと1週間ほど腹痛と下痢で寝込んでいたので大変でした。

英語の勉強

真面目に英語を勉強します。今度こそ本気です。
勉強に使っているサイトを紹介します。

CNNの学生向けの10分の番組で月〜金に更新されます。最初のニュースをディクテーションしています。ニュース以外は面白くないので飛ばしています。CNN.com - Transcriptsにtranscriptがあったりなかったりします。ディクテーションした後に今日はtranscriptがないことに気づくととてもつらい。

毎日ABCニュースの内容を取り上げて、同じ内容を字幕付き→日本語訳字幕→字幕なし→字幕付きと4回聞く番組。
途中で単語の解説も入っているのでよいです。

科学の内容を取り上げて60秒で解説する番組のはずだが、60秒に収まっていることはほとんどないです。
これもtranscript(実は放送されている内容と若干違う)があるのでディクテーションの練習に使えます。
元論文の主張とずれているタイトルをつける回が割とあって嫌になってきたので最近は聞いてません。

Annict

読書メーターのアニメ版みたいなやつ。サムネイル画像の使いかたが引用の範囲なのか怪しい気がする。
本の書影を図書館報に使う場合も解釈が分かれているっぽい→図書館報に本の表紙写真を掲載する場合の許諾について | レファレンス協同データベース

読んだ本


色塗りの仕方がとても詳しく書かれていて良い。この本の1つ目の作例の通りに描いたのが以下の絵。

入門確率過程

入門確率過程

多目的計画法の理論と応用

多目的計画法の理論と応用

目的関数が複数あるときにどう最適化するかという理論の本。
1つの目的関数をこれ以上良くしようとすると他の目的関数が悪くなってしまうような解をPareto最適解と呼び、Pareto最適解を求める方法や複数のPareto最適解の中からどれを選ぶかというような議論が載っていた。
線形関数・凸関数の議論が中心で非線形関数の議論が弱い、NSGA-IIのようなヒューリスティック手法の議論がない、古い本なので最近の議論が載ってない、などの点で満足できなかった。

みらいのふうふですけど?(1) (百合姫コミックス)

みらいのふうふですけど?(1) (百合姫コミックス)

とても良かった。このくらいのドキドキ感の百合がちょうどよくて好き。

パワハラ美少女カンパニー 1 (ヤングジャンプコミックス)

パワハラ美少女カンパニー 1 (ヤングジャンプコミックス)

おっさんが美少女に見えるメガネを掛けてパワハラ上司のいる職場を生き抜く話。発想が完全勝利しているので応援している。部長がかわいい。

君に好きっていわせたい (百合姫コミックス)

君に好きっていわせたい (百合姫コミックス)

ゆりゆり (百合姫コミックス)

ゆりゆり (百合姫コミックス)

七人のイヴ ? (新☆ハヤカワ・SF・シリーズ)

七人のイヴ ? (新☆ハヤカワ・SF・シリーズ)

中国旅行

9/10〜9/14にかけて北京に旅行に行ってきたので記録を書きます。

行った場所の地図は以下の通りです。

Twitterの関係するツイートは以下にまとめました。

時系列で何をしたかはtogetterを見ればいいのでここではトピックごとに書きます。

渡航前の準備

飛行機の予約

いかに安い飛行機を確保するかが旅行全体の値段を大きく左右するので念入りに探す必要があります。

飛行機を探すときに役に立ったのは

です。
Googleフライトでは日程ごとの最安値を表示することができるので、チケットが安く買える日という基準で日程を決めることができます。
SkyscannerはGoogleフライトよりも多くの予約サイトに対応している気がします。
今回の旅行では、Googleフライトで安い日程を決めた後、Skyscannerで同じ日程を調べて便を決定し、Skyscannerに表示された日本の予約サイト経由で予約しました。

ホテルの予約

ホテルのクオリティは旅行の満足度に大きな影響を与えます。
今回の旅行ではExpediaで調べて出てきた北京燕山大酒店にしました。
Expediaは予約の時点で支払いを済ますことができるので現地スタッフとの会話を減らすことができ便利です。

SIMカードの購入

中国国内はインターネットの規制が厳しく、Google, Twitter, Slackなどにはアクセスできません。
しかし、香港の通信会社のSIMカードを使うと中国当局の規制を受けずにインターネットを使うことができます。
僕はChina UnicomのSIMカードを購入しました。

SIMカードを購入するときはFrequencyCheckなどのサイトで自分の携帯がその会社のバンドに対応しているかを調べておくと良いです。

高徳地図

Googleマップよりも高徳地図のほうが中国国内の移動に関しては詳しいので事前にインストールしておくと良いです。

北京の公共交通機関

地下鉄

北京は地下鉄がかなり発展しています。
空港線は25元(旅行時の1元は17.8円)ですが、それ以外の路線は3〜5元で移動することができます。
空港で一卡通という中国版Suicaのようなものを買っておくと便利です。
f:id:kivantium:20180915170604j:plain:w480

地下鉄に乗る際には荷物検査があり、荷物のX線チェックと人間への金属探知機による確認があります。
空港線のチェックは厳しいですが、それ以外の路線のチェックは雑でした。
車内やホームにはたくさんの警備員が立っており、セキュリティ意識の高さを感じました。
f:id:kivantium:20180915170930j:plain:w480

ホームドアが全路線に設置されていました。
f:id:kivantium:20180915171222j:plain:w480

路線図のLED表示はかなり分かりやすかったです。
f:id:kivantium:20180915171059j:plain:w480
空港線のようにLED表示がない路線もあります。
路線ごとの細かな違いは作られた時期の違いによるだそうで、1号線には冷暖房すらないそうです。
f:id:kivantium:20180915171305j:plain:w480

驚いたのは車外広告で、電車の外にあるディスプレイが電車の動きに合わせて広告を流しているように見えました。


後でTwitterで教えてもらったのですが、日本にも昔あったそうで、スリットに入った複数の画像を見ているという仕組みのようです。

バス

バスの運賃は一卡通の場合は1元です。
荷物検査はありませんが、警備員が一台に4人立っていたのでやはりセキュリティには気をつかっているようです。
高徳地図を使って路線検索するのが便利です。

QRコード決済

中国ではQRコードを使った決済が普及していると聞いていましたが、想像以上に便利そうでした。

博物館などの観光スポットの前には必ず大きなQRコードがあり、そこからチケット購入サイトに飛ぶよう指示されます。
入場するときは携帯でQRコードを表示して機械に読み取らせることで入場券の代わりとします。
この写真は故宮博物館の例です。
f:id:kivantium:20180915174342j:plain:w480

テーブルにあるQRコードからアクセスできるサイトからメニューを選んで注文すると店員がテーブルに運んできてくれるという店もありました。
f:id:kivantium:20180915174714j:plain:w480

このように便利なQRコード決済ですが、観光客にとっては非常につらいものです。
中国国内で主に使われているのはWeChatPayとAlipayという決済サービスですが、どちらも中国の銀行に口座を持っていないと利用することができません。
(WeChatPayは1000元までならクレジットカードの登録のみでできるという情報もあった)
またクレジットカードもUnionPayしか使えないところがほとんどで、VISAやMastercardは役に立ちませんでした。
ただし、ほとんどの場所では現金も受け付けてくれるので現金を持っていけばどうにかなります。
例外として、空港の自動販売機に現金を受け付けてくれないものがありました。
また、故宮博物館はオンラインのチケット購入しか認められず、SMS認証が必要だったのでSMSが使えないSIMカードでは入れなさそうでした(同行していた人にチケットを買ってもらいました)。

中国語について

中国はかなり英語が通じない国でした。
日本人は中国人とあまり区別がつかないのか容赦なく中国語で話しかけてきます。
English, please.などと言って英語で話すよう要求しても英語が分からない人が多くて苦労しました。

Google翻訳アプリのカメラ入力機能を使うと読み方の分からない簡体字を翻訳することができるので便利でした。

また、中国語の特性なのか多くの人が怒っているような話し方をするので精神衛生上よくありませんでした。

北京の食事

北京での食事は厳しかったです。
まず、メニューを見ても何の料理か分からないものが多くて選ぶことができませんでした。
猪は豚だろうなどの漢字のイメージで選んでもその漢字の中国語読みが分からないので注文もできません。
ようやく注文しても匂いや味が日本では食べたことのない系統のことが多く、あまりおいしいと感じることができませんでした。
日本で食べる中華料理は日本人向けにローカライズされているとは聞いていましたが、かなり改変されていたようです。

お茶に甘い味をつけたものが中国では人気らしいのですが、僕は紅茶に砂糖を入れたものですら飲めないのでそういうお茶は飲む気になれませんでした。
ファミリーマートが中国に進出しているので、そこでは日本の緑茶を購入することができました。
コカコーラのコーラ・スプライト・水はいろんなところで入手できたので助かりました。
特にコカコーラの純悦にはお世話になりました。
f:id:kivantium:20180915200332j:plain:w480

箸は日本のものと違って先があまり細くなっていません。
このような高温消毒器に箸を入れて提供している店が多かったです。
f:id:kivantium:20180915200539j:plain

プロパガンダ

中国の国家的イベントで作られた施設の近くにはプロパガンダがたくさんありました。

オリンピック公園での例です。
社会主義核心価値観とされる「富強、民主、文明、和諧、自由、平等、公正、法治、愛国、敬業、誠信、友善」はあらゆるところで見かけます。
f:id:kivantium:20180915200918j:plain:w480
f:id:kivantium:20180915201055j:plain:w480
f:id:kivantium:20180915201110j:plain:w480

国家博物館の近代展示
f:id:kivantium:20180915201310j:plain:w480

石景山遊楽園の近くの道路にあった例
f:id:kivantium:20180915201206j:plain:w480

石景山遊楽園

最後に日本で数年前に偽ディズニーランドとして話題になった石景山遊楽園の現状を紹介します。

入り口近くのゲート
f:id:kivantium:20180915201421j:plain:w480

入場門
f:id:kivantium:20180915202218j:plain:w480

入ってすぐのビジターセンター。この写真からも分かるようにほとんど人がいませんでした。
f:id:kivantium:20180915201443j:plain:w480

最近はこのようなオリジナルキャラクターが多く、パクリはほとんど見かけませんでした。
f:id:kivantium:20180915201532j:plain:w480

最近できたというフライトシミュレータで遊べる施設。128元と高かったので入りませんでした。
f:id:kivantium:20180915201618j:plain:w480

動いていない遊具。
f:id:kivantium:20180915201718j:plain:w480

屋台は全て閉店していました。
f:id:kivantium:20180915201807j:plain:w480

エロゲメリーゴーラウンド。日本のエロゲの絵が特に脈絡なく貼られていました。
f:id:kivantium:20180915201828j:plain:w480

どことなくシンデレラ城に似ている建物。
f:id:kivantium:20180915201931j:plain:w480

と思ったら案内には思いっきりCINDERELLA CASTLEと書かれていまし。
f:id:kivantium:20180915202035j:plain:w480

ゲームセンターには許諾のなさそうな景品がいくつか。
f:id:kivantium:20180915202128j:plain:w480

遊園地の南と北をつなぐ階段。アンサイクロペディアの記事にある写真と比べるとその人気の衰えが分かります。
f:id:kivantium:20180915202308j:plain:w480

このようにパクリは残りつつも影をひそめ、そもそも観光客の来ない寂れた遊園地になっているという現状でした。

2018年7月

今月紹介したいもの

Kibela

WikiやBlogを団体内で共有するためのサービス。
Slackでは流れてしまう情報をまとめておくときなどに有用。特にOSSプロジェクト、技術コミュニティ、研究室などの非営利団体は無料であるところが嬉しい。研究室でも導入した。

メンヘラちゃんフリーアイコン

かわいい。他にもフリーアイコン素材 | ホームページ・イラスト・デザイン制作会社のジョイネットからいろいろダウンロードできる。LINEスタンプに入っていた文字はフリーアイコン版では削除されているようだ。

Chainerでimage captioning


クーポンコレクター問題

> 「全てのクーポンを集めると、何らかの特典が得られる」ような場合に、何回クーポンを引けば良いかという問題

中央値が絶対偏差を最小化すること



kitayutaは天才。

その他


今月読んだ本

日本軍のインテリジェンス なぜ情報が活かされないのか (講談社選書メチエ)

日本軍のインテリジェンス なぜ情報が活かされないのか (講談社選書メチエ)



日本兵捕虜は何をしゃべったか (文春新書)

日本兵捕虜は何をしゃべったか (文春新書)

今月観た映画

カメラを止めるな!

監督&俳優養成スクール・ENBUゼミナールが制作したゾンビ映画
映画の観客にはカメラで撮影された映像しか見えないことを活かすアイデアが素晴らしく、300万円という低予算のゾンビ映画で最大限客を楽しませるにはどうすればいいかという難題に見事に答えていた。
もともと都内の2つの映画館でしか上映していなかったのだが人気のため現在では100館以上で上映するようになっている。
見に行くときは公式サイトのPVやあらすじを読んでしまうと初見の衝撃が減ってしまうので上映館の情報だけ調べてから行くのが良い。

今月描いた絵





Vue.jsとFlaskの間でフォーム情報をやり取りする

Pythonで作ったプログラムにWebインターフェースをつけることができると便利です。
せっかくなのでフロントエンドも勉強しようと思って見た目簡単そうなVue.jsを試しました。

ソースコード

バックエンド (Python)

PythonのシンプルなウェブアプリケーションフレームワークであるFlaskを使いました。
/にアクセスするとindex.htmlが表示されます。
/apiにPOSTでデータを送りつけると、送られたフォームデータをsplit()したものをjsonで返します。

from flask import Flask, request, render_template, jsonify
app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route("/api", methods=['POST'])
def hello():
    result = {
        "results": request.json["text"].split()
    }
    return jsonify(result)

if __name__ == '__main__':
    app.run(debug=True)

フロントエンド (Vue.js)

フロントエンドにはVue.jsを使いました。
axiosを使って/apiにフォームの情報を投げています。
検索した範囲ではVue.jsではフォーム情報をこうやって取るのが正しい雰囲気があったのですが、本当にこれが正解なのかはよく分かりません。
結果が返ってきたら結果表示欄にリストで表示します。
FlaskのレンダーとdelimiterがかぶっているのでVue.js側のdelimiterを変更する必要がありました。

<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<form v-on:submit.prevent="submit">
<textarea v-model="formData.text"></textarea>
<input type="submit" value="submit">
</form>
<div v-if="seen">
<h2>Results</h2>
<ul>
<li v-for="result in results"> [[ result ]] </li>
</ul>
</div>
</div>
</body>
<script>
const vm = new Vue({
  el: '#app',
  delimiters: ['[[', ']]'], // Flaskのdelimiterとの重複を回避
  data: {
    seen: false,
    results: [],
    formData: {
      text: ''
    }
  },
  methods: {
    submit: function() {
      axios.post('/api', this.formData)
        .then(response => {
          this.results = response.data.results;
          this.seen = true;
        })
      .catch(error => {
        console.log(error);
      })
    }
  }
});
</script>
</html>

動作例

submitする前

f:id:kivantium:20180723173258p:plain

submitした後

f:id:kivantium:20180723173339p:plain


もっと良い書き方があったら教えてください

C/C++でのメモリリーク検出方法 〜AddressSanitizer, Valgrind, mtrace〜

C/C++でプログラムを書いているときに遭遇する厄介なバグの一つがメモリリークです。
今回はメモリリークを検出するのに使えるツールの使い方について書きます。

AddressSanitizer

コンパイルオプションをつけるだけで使えて出力も見やすいのでおすすめです。

AddressSanitizerはGCC 4.8以降かLLVM 3.1以降で使うことができます。
コンパイル時にオプションをつけるだけでメモリリークを検出してくれます。(若干実行時間が長くなります)

以下のメモリリークのあるプログラム leak.cpp を例に使い方を説明します。

int main() {
  int *a = new int[10];
}

newで作った動的配列をdeleteしていないのでメモリリークになります。

g++ -fsanitize=address -fno-omit-frame-pointer -g leak.cpp
./a.out

のようにオプションをつけてコンパイルして実行すると以下のような出力を得ます。(clangの場合もオプションは同じです)

=================================================================
==6027==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7f606cd7a6b2 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x996b2)
    #1 0x4006f7 in main /home/kivantium/leak.cpp:2
    #2 0x7f606c93782f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: 40 byte(s) leaked in 1 allocation(s).

leak.cppの2行目のメモリリークの存在が分かりました。

詳細はAddressSanitizer · google/sanitizers Wiki · GitHubが詳しいです。

Valgrind

仮想機械の上でプログラムを実行することでメモリリークの検出などを行うツールです。実行ファイルだけあれば使える点が便利ですが、実行はけっこう遅くなります。

インストールは基本的には

sudo apt install valgrind

でできるはずですが、僕の環境ではlinux-tools-4.13.0-45-genericのインストールも必要でした。

int main() {
  int *a = new int[10];
}

をValgrindでチェックするには、

g++ -g leak.cpp
valgrind --leak-check=full ./a.out

を実行します。結果は、

==6911== Memcheck, a memory error detector
==6911== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==6911== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==6911== Command: ./a.out
==6911== 
==6911== 
==6911== HEAP SUMMARY:
==6911==     in use at exit: 72,744 bytes in 2 blocks
==6911==   total heap usage: 2 allocs, 0 frees, 72,744 bytes allocated
==6911== 
==6911== 40 bytes in 1 blocks are definitely lost in loss record 1 of 2
==6911==    at 0x4C2E80F: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6911==    by 0x400607: main (leak.cpp:2)
==6911== 
==6911== LEAK SUMMARY:
==6911==    definitely lost: 40 bytes in 1 blocks
==6911==    indirectly lost: 0 bytes in 0 blocks
==6911==      possibly lost: 0 bytes in 0 blocks
==6911==    still reachable: 72,704 bytes in 1 blocks
==6911==         suppressed: 0 bytes in 0 blocks
==6911== Reachable blocks (those to which a pointer was found) are not shown.
==6911== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==6911== 
==6911== For counts of detected and suppressed errors, rerun with: -v
==6911== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

のようになり、2行目にメモリリークがあることが分かります。

他にも機能があるようなので機会があったら追記します。

mtrace

メモリリークの位置を絞って探すときに使えます。glibcに入っているので使える環境が多いですが出力が見にくいです。

mtraceを使うにはmcheck.hをインクルードして、調べる範囲にmtrace()muntrace()を書く必要があります。

例としては

#include <stdlib.h>
#include <mcheck.h>
 
int main() {
  mtrace();
  int *a = (int*) malloc(sizeof(int)*10);
  muntrace();
}

のようになります。

実行するには

gcc -g leak.c
export MALLOC_TRACE=./mtrace.log
./a.out
mtrace a.out mtrace.log

のようにログ出力先を環境変数に指定したあとにプログラムを実行し、バイナリとログファイルを引数に与えてmtraceを実行します。

出力は

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000001456450     0x28  at /home/kivantium/leak.cpp:6

のようになります。

C++

#include <mcheck.h>
 
int main() {
  mtrace();
  int *a = new int[10];
  muntrace();
}

のように書いた場合、出力は

Memory not freed:
-----------------
           Address     Size     Caller
0x00000000008b5060     0x28  at 0x7fe1589bbe78

のようになってしまい、どの行が問題だったのか分かりません。addr2lineを使って

addr2line -e a.out 0x7fe1589bbe78

とすればどの行か分かる場合もあるようですが、僕の環境では分かりませんでした。
C++ではかなり使いにくいようです……

2018年6月



読んだ本

The Three-Body Problem

The Three-Body Problem

非常に人気のある中国SF。原題は三体 (Wikipedia)。ヒューゴー賞などを受賞しているが、まだ日本語訳が出ていないため英語版で読んだ。

私の百合はお仕事です! 3 (百合姫コミックス)

私の百合はお仕事です! 3 (百合姫コミックス)

どんどん弱っていくくるみちゃんが見ていてつらい。
量子コンピュータと量子通信〈1〉量子力学とコンピュータ科学 (量子コンピュータと量子通信 1)

量子コンピュータと量子通信〈1〉量子力学とコンピュータ科学 (量子コンピュータと量子通信 1)

カドラプロのおすすめ。量子ゲートなどの具体例から入るので他の本よりも分かりやすかった。2巻から急に難しくなって全然読めていない。
工学のための関数解析 (工学のための数学)

工学のための関数解析 (工学のための数学)

前原さんのおすすめ。行間が狭いところは良いが、紹介された新しい概念の工学での使い所がいまいち分からなかった。
お兄ちゃんはおしまい! (IDコミックス)

お兄ちゃんはおしまい! (IDコミックス)

科学者の妹に女の子にされたお兄ちゃんの話。お兄ちゃんがかわいい。

特定商取引法に定められた事項は請求により遅滞なく提供する