ぶろぐめんどくさい

技術系の記事と漫画レビューが入り混じった混沌

bash on ubuntu on windows (buw) でpython3のためのmysql.connectorを導入するよ

次のコマンドを実行するだけ。

sudo apt-get install python3-mysql.connector

導入されていることを確認するには?

$ python3
Python 3.4.3 (default, Nov 17 2016, 01:08:31)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import mysql.connector
>>>

bash on ubuntu on windows (buw) でapache導入からドキュメントルートの設定まで

だいたいubuntuの場合と同じ。

apache2の導入

sudo apt-get install apache2

apacheをインストールapacheはインストールした直後から起動しているらしい。

ドキュメントルートの変更について

UbuntuでApache2のドキュメントルートをユーザーディレクトリに変更する。 in Koonzの毎日作りかけブログ

を参考に

要は/etc/apache2の中のapache2.confを編集、000-default.confの代わりを用意してコマンドによりシンボリックリンクを変更。 最後に

sudo service apache2 restart

で終わり。

ポート変更

ポートが競合してサービスを再起動できない? ならばポートを変更しましょう。

madroom project: UbuntuでApacheのポートを変更するメモ

を参考に

ports.confと000.default.confのポート番号を変更。

nodejsでwebページを表示するまで

nodejsを使いたいならば、webページ表示させるまで簡単に解説しましょう。

https://nodejs.org/ja/ からnode.jsをインストール

コマンドプロンプト、ターミナルを開いて node -vを入力。

NodejsをインストールしたWindowsには(Macでも?) npmというパッケージマネージャが入ります。

早速パッケージをインストールします。 npm install express express-generator を入力しましょう。

expressはnode.jsを扱いやすくするためのパッケージ。 express-generatorはexpressを使ったサンプルを吐くパッケージ。

とりあえず、適当なディレクトリに移動して express sample-appと入力しましょう。

するとsample-appというディレクトリが作成されます。 フォルダ構造はこんな感じです。 (Macだと/fいらないかもです)

tree sample-app /f
sample-app
│  app.js
│  package.json
│
├─bin
│      www
│
├─public
│  ├─images
│  ├─javascripts
│  └─stylesheets
│          style.css
│
├─routes
│      index.js
│      users.js
│
└─views
        error.jade
        index.jade
        layout.jade

cd sample-appしてnpm installする。 (いろんなパッケージがインストールされる) んでnpm startでサーバスタート。

express-generatorが吐くサンプルでは3000ポートを開けて待っているので、 ブラウザを開いてhttp://localhost:3000へアクセス。

するとこんな画面が表示されます。

f:id:be116:20170106115517p:plain

とりあえずこれでnodejsを使うことができました。

やったね。

自己分析の例文の現実感の薄さについて

就活の時期ですね。 スーツを着て歩き回るあの。 正月が明け、就活に向けて自己分析をしています。

自己分析。 過去の自分を振り返り自分について掘り下げる課題。 就活生の90割がやっています。

これがなかなか難題。 指が動かない。 なにせなにをしたらいいのかわかんない。

だから俺、しらべた。 いろいろしらべたよ。 で、みつけた。こんな記事。

careerpark.jp

読んだ。まー? ためになったよ。ためにね。 でもさ、でもさ、ちょっとさ、言っちゃなんだけど、言いたくないんだけどさ。 就活生の例文おかしくない?

引用するよ。

『 【中学・高校時代】 ・得意科目: 国語、社会、英語 ・不得意科目: 数学 ・習い事: 珠算(中学まで)、塾 ・取得した資格:珠算4段、英検準2級 ・熱中していた物:ソフトテニス(中学のみ、高校時代は辞める) ・印象に残っている事柄:弁論大会優勝(中学)、部活動(中学)、文化祭(高校) ・努力していたこと:部活動(中学)、生徒会活動(中学)、勉学(高校)、委員長(高校) ・将来の夢:アナウンサー、国際公務員 ・アルバイト:なし ・その他:中学から英語が話すようになりたく、留学するという夢を持つ。

【大学時代】 ・得意科目:財務管理学、経営学、国際経営学 ・不得意科目:文学系 ・習い事:なし ・取得した資格:アーチェリー指導員資格、TOFEL iBT 101 ・熱中していた物:映画鑑賞、文化交流 ・印象に残っている事柄:留学、奨学金獲得、1学期全学科でA獲得、旅行、寮生活 ・将来の夢:英語を生かせる仕事に就く、国際人を育てたい(教育) ・アルバイト:カフェ店員・副寮長・チューター ・その他:異文化・宗教理解、英語習得 』

弁論大会優勝ってすごいね。すごい人を例に出したんだね。 優勝って文字だけで凄さがわかるよ。 アーチェリー指導員資格? すごい! 弦を引くだけじゃなくて弦を引かせることもできるんだね!

まあいいよ。これくらいは。 まあそういう人を例に出したんだなって。

でも、もっとひどいと思ったよ。思ったことがあるよ。それがこれ。

『 【小学校】 小学校1年生の時、野球教室に入った。2年生の5月に初めて試合に出場、7月に初ヒットを打った。3年生の夏休み、夏の甲子園野球を見に行った。小学校4年の時、英語教室に入会。○○先生にマンツーマンで発音を教えてもらい、英語が好きになった。6年生になった頃にはメジャーリーグの実況を英語で聞き取れるようになり、他のスポーツの解説も英語で聞くのが楽しくなった。

【中高】 中学入学のタイミングで中国地方から関東に引っ越し、毎週のようにプロ野球を見に行くようになった。高校入学のタイミングで学業に専念するため野球をしなくなるが、観戦は続いた。現役・OB問わず、知っている選手が増えたため、前よりも見るのが楽しくなった。野球の話をすると、友達も興味ありげに聞いてくれた。スポーツについて詳しいというキャラクターが定着して、自分でももっとスポーツ全般を知りたいと思うようになった。

【大学】 大学はスポーツ心理学を専攻し、ラクロス部のマネージャーをしながら野球サークルも立ち上げた。マネージャーは楽しく取り組めた。練習メニューのきつさが分からなかったので、主将にお願いして、月1でフィジカルトレーニングに参加。2年生時は、メニュー考案と部員へのフィードバックを対応した。 』

小中高充実した学生生活エンジョイしてたのはいいよ。 そういう人が大部分だろうよ認めるよ。

でもさ、でもさ。小6で英語が聞き取れるって? サークルを立ち上げたって? 主将ってのは王将でだべってたの間違いじゃないの?

みんなこうなの? みんな生徒会に入ってたの? みんな部活で全国大会に行ったの? みんなサークル立ち上げるの?

俺の価値観が間違ってなければさ、 みんなこうだとしたらさ、みんな嘘つきなんじゃないかな。

年納め

おはようございます。

それでは早速、今年度の総決算。

数学ガールの著者様にリツイートをもらう。 パリヤさんの記事が意外とヒット。 そこそこアクセス増えて満足です。

でも、急にバズるとビビりますよね。 不幸にもそれほどの肝っ玉は持ち合わせていませんので、 そこそこ見てもらえるくらいで十分だなと思っております。

ですので、来年度もひっそりやっていくつもりでございます。 どうぞ宜しくお願いします。

それでは良いお年を。

線形探索を高速化する単純なアイデア

線形探索というアルゴリズムがあります。 これは、プログラムを勉強する上では避けて通れない基本的なアルゴリズムです。

線形探索とはなにかというと、 ある配列があったとき、その中身を先頭から最後尾にかけて順番に走査していこうという考え方のことです。 線形探索はこのように単純でわかりやすいので実装が簡単ですが、配列の要素数が大きくなるとそれだけ時間がかかるようになってしまいます。 これを解消するようなアルゴリズムとして2分探索がありますがその話はまた後日しますん。

今回はこの線形探索をどうしたら高速化できるかを思いついたので、実装して検証してみましょうという企画です。

さっそく本題に入りましょう。 今回、思いついたアイデアというのは線形探索のスレッド化です。

説明のために図を用意しました。(褒めて)

f:id:be116:20161213191652p:plain:w500

通常の線形探索では図のようにそれぞれの配列を一つずつ探索していきます。 それと比較して、スレッドを使用した線形探索では複数の要素を複数のスレッドにより一気に探索することができます。

線形探索はメモリ効率が最適です。 メモリ効率とは次に探索する要素がどれだけ近くにあるかを示す指標です。 メモリ効率がいい、すなわち、次に探索する要素が近くにあれば、探索の時間は短縮されます。 もし、次に探索する要素が遠くにあった場合には、それだけ探索に時間がかかるようになります。 線形探索では、常に隣の要素を探索するためメモリ効率は最適と言っても過言では無いでしょう。(間違ってたら助けて) スレッドを使用した線形探索においても、常に近いところを探索し続けるため、メモリ効率は良いといえます。

次に実装の話に移りましょう。

スレッドは共有メモリを使用しています。 説明がめんどくさいので適当ですが、1つのプログラムで走っているよ、だからどのすれっどからも1つのメモリ空間にアクセスできるよみたいなものです。

線形探索にスレッドを適用する場合、この共有メモリの概念が重要になります。 スレッドには関数のように返り値を返すといった仕様がありません。 そこでグローバル変数を使用して、返り値の代わりをしてもらいます。

というところで飽きてきたのでプログラムはこうなります。

逐次処理

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SIZE 8192

int flg = 0;
int* array;

int main()
{
  int i;
  clock_t start, end;

  array = (int*)calloc(sizeof(int),SIZE);

  array[SIZE-1] = 1;

  start = clock();

  for (i=0; i<SIZE; i++) {
    if (array[i]) {
      flg = 1;
      break;
    }
  }

  end = clock();

  if (flg)
    printf("みつけたぞ\n");
  else
    printf("なんぞこれ\n");

  printf("%lf秒もかかったぞ\n", (double)(end - start) / CLOCKS_PER_SEC);

  free(array);

  return 0;
}

スレッドを使用

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <thread>
#include <vector>

#define SIZE 8192
#define THREAD_NUM 32

int flg = 0;
int* array;

void func(int i)
{
  if (array[i]) {
    flg = 1;
    return;
  }
  return;
}

int main()
{
  int i, j;
  clock_t start, end;

  array = (int*)calloc(sizeof(int),SIZE);

  array[SIZE-1] = 1;

  std::vector<std::thread> th_group;

  start = clock();

  for (i=0; i<SIZE; i+=THREAD_NUM) {
    for (j=0; j<THREAD_NUM; j++) {
      th_group.push_back(std::thread(func, i+j));
    }
    for (auto itr=th_group.begin(); itr!=th_group.end(); ++itr) {
      itr->join();
    }
    th_group.resize(0);
    if (flg) {
      break;
    }
  }

  end = clock();

  if (flg)
    printf("みつけたぞ\n");
  else
    printf("なんぞこれ\n");

  printf("%lf秒もかかったぞ\n", (double)(end - start) / CLOCKS_PER_SEC);

  free(array);

  return 0;
}

素数8192で比較。

逐次処理

みつけたぞ
0.000000秒もかかったぞ

スレッドを使用した場合

みつけたぞ
0.859375秒もかかったぞ

あれれー、おかしいぞー? スレッド化のメリットよりもスレッド生成のコストが上回ったっていうことなのかー? そーなのかー。

といった話でした。

まとめ。

なんでもかんでもスレッド使えばいいってもんじゃないね。 はぁ…。

c++のスレッドで返り値が欲しいのならば

返り値に代わる変数を渡せばいいじゃない。

#include <thread>
#include <stdio.h>

int th(int* ret)
{
  printf("1");
  ret = 1;

  return 1;
}

int main()
{
  int ret;

  std::thread th(th, &ret);
  th.join();

  return 0;
}

ね、簡単でしょ。