ラベル IT の投稿を表示しています。 すべての投稿を表示
ラベル IT の投稿を表示しています。 すべての投稿を表示

2021年4月10日土曜日

最近仕事で扱っている技術

転職をして、なんだかんだもう時期2年が経過しようとしている。

SESの会社で働いているが、2つ目の現場で、わりとモダンな技術を使っている現場に当たったので、そういう意味では恵まれていると思う。

自分含めて周りもあんまりわかってないので、わからないことだらけなので、残業続きで大変ではあるけど。

自分にとっては多少背伸び気味の現場なので、そこで揉まれて成長できているとは思う。

当然のことながあんまり詳しいことは書けないけど、クラウド系の技術を使っていて、

docker、kubernete、OpenShift。

あとHelmchart、istioとかも。

正直理解が追いついてないので、キーワードを並べるだけになってしまうけど。

正直あんまりコードは書いていない。

でも、環境構築をして、仕組みがどうなってるのかをしれるから楽しい。

よくわかってないけど、多分DevOpsっていうのだろうか。

普段からわりと動作原理とか仕組みがわかって満足という気質はある。

環境構築して動くことが確認できれば満足、という感じ。

環境構築して動かせる環境さえ作ってしまえば、あとはコード書いていくだけだし、と思っている。(もちろんコードを書くのだってそんな簡単な話ではないことはわかっているが)

プライベートでも勉強がてらDockerなどを触ってみたりしている。

DockerやVirtualBoxなど、仮想化という便利な技術を知ったので、前は「環境構築失敗してもとに戻せなかったらどうしよう」と躊躇していたようなことも、「失敗したら戻せばいいや」と気軽に行えるので、いろいろ手をつけてみている。

GCPなんかも触ってみている。

DevOps系のスキルをもっと高めて、MLOps系の方向へ行きたいなと思っている。


2020年4月13日月曜日

python3.8 on CentOS8


  • Pythonのディレクトリ構造
  • VirturalBoxの使い方
  • CentOS8に触ってみる
といったことを勉強したかったので、CentOS8にPython3.8をインストールをしてみました。

その時の手順を参考になればと思い記事を書きました。

それなりの枚数の画像が挿入されて記事が長くなると思われるので、この記事の要点を先に述べておきたいと思います。

この記事で触れること

  • CentOS8のインストール手順
  • Python3.8のインストール手順(二通り)
  • Python3.8をそれぞれの方法でインストールしたとき、ディレクトリはどうなるか

この記事で触れないこと

  • VirturalBox自体のインストールには触れません。他の記事を引用するに留めます。

自分の環境

  • MacOS 10.15.3 Catalina (今回はVirtualBoxインストール済みのところから話を始めるのであまり関係はないですが。。。)
  • VirtualBox 6.0.18

Python3.8のディレクトリ構造

まず、Python3.8のディレクトリ構造がどうなるか、述べてしまいたいと思います。

コマンドでインストール

  • python3.8の実行ファイル(バイナリファイル)は絶対パスの/usr/binにきます。
  • ライブラリなどは絶対パスの/usr/local/lib/Python3.8/site-packagesにきます。

インストーラーでインストール

CentOSの場合にはインストーラーというものはないようです。

公式サイトへいってもダウンロードできるのはソースコードしかないので、結局はそれを自分でビルドしていくことになるので、上記のコマンドを使う方法と同じことになります。

VirtualBoxのインストール手順

これは調べればたくさん記事が出てくるので、割愛。インストールは済んでいるところから話を始めます。 例えば、
などなど。

CentOS8のイメージファイルのダウンロード

CentOSの公式ページから、まずはCentOS本体のデータをダウンロードします。 この中にあるものであれば、どれも同じなのでどれでもいいのでダウンロードします。






CentOS8のインストール

まずはVirtualBoxを起動します。

下記の画面では、自分が試しに作った別用途のCentOSが表示されてしまっていますが、今回は新規につくるので「新規」をクリックします。



名前の欄は、「あとから起動する時に区別するため」の名前を適当に決めます。ここでは、わかりやすく「CentOS8」としました。

それ以外の設定は特にいじらず、名前の欄を入力したら、「作成」ボタンを押して先へ進みます。



次に、ファイルの場所を決めます。

これは、今から作る仮想マシン自体も、この今作業しているパソコン上に存在することになるわけですが、その場所やそのファイルの名前をどうするのか、ということです。

これも特別な理由がないのであれば、いじらなくていいです。

ファイルサイズは、デフォルトでは8GBになっています。

あとあと、CentOSをインストールする際に、いくつかバリエーションが選べるのですが、「本当に最小限」のものだけをインストールするのであれば、8GBでもいいのですが、そうでない場合には8GBだと足りないので、うまくいくように11GBにします。

最小限、ただ起動するだけだとしても、そのために必要なファイルなどがあるわけです。それらのファイルにも存在できる場所は必要なので、その合計値よりも多くなければいけないということです。

それ以外は、下記画像と同じようになっているか確認し、「作成」ボタンを押します。


そうすると、まずはCentOS8をインストールするための場所が確保できました。


次に、実際にインストールをしていきます。

今作成したCentOS8のところを右クリックして、「起動」→「通常起動」をクリックします。




そうすると、次のような画面になります。


ここで、ダウンロードしてある、CentOS8のイメージファイルを選択します。

選択したら、「Start」を押します。


そうすると、CentOS8のインストール画面が立ち上がります。

いくつか選択肢が表示されていますが、「Install CentOS Linux 8」が選ばれているはずなので、そのまま「Enter」を押します。(まぁなにも押さなくてもカウントダウンが終わればそのまま自動で選択されます。)


言語の設定をします。

操作に少し注意が必要です。

仮想環境の中と外では、別操作になります。仮想環境の画面上をクリックすれば、操作が仮想環境の中に移りますが、そのままでは今度は仮想環境の外の操作ができないので、(仮想環境の中ではなく)普通のPCの操作をしたい場合には「左のCommand」を押します。

日本語を選んで、「続行」を押します。


「続行」を押すと、以下のような画面になります。

画面が途中で見切れてしまっています。これはあとで別途設定することで直すこともできますが、ここでは一旦このまま進めます。

この画面から、
  • 時刻と日付
  • ソフトウェアの選択
  • ネットワークとホスト名
を設定していきます。


日付と時刻を以下のように設定します。

設定したら、左上の「完了」を押します。



「完了」を押すと、元の画面に戻るので、今度は「ソフトウェアの選択」を選択し、以下のように設定。

ここで、「最小限のインストール」を選択してもいいのですが、そうすると本当に最小限しかインストールされずGUIとかもなくCUI上でコマンド操作しなくてはいけなくなります。

なので、慣れないうちはある程度その他のツールも込み込みの「ワークステーション」を選ぶとよいと思います。

勉強して詳しくなってきたら、「サーバー」とか「最小限のインストール」とかでチャレンジしてみるのもいいかもしれません。

冒頭のほうでファイルサイズを8GBに設定しました。

仮に「最小限のインストール」をインストールする場合には、それで足りるのですがその他のツールも含めてインストールしようとするとそれでは足りなくなるので、そのために冒頭では11GBに設定したのでした。

右側の「選択した環境用のその他のソフトウェア」の中も、適当にいくつか選びます。

自分の場合は、以下の画像のように選択しました。




選択したら、まだ左上の「完了」を押して元の画面に戻り、今度は「ネットワークとホスト名」を設定します。

右上のEthernet(enp0s3)のところをクリックしてONにします。そうしたら左上の「完了」を押します。


元の画面に戻りますので、右下の「インストールの開始」をクリックします。


そうすると、インストールが始まります。

それなりの時間がかかるので、その間にrootのパスワードとユーザーの作成をします。


「rootのパスワード」を選択し以下の画面を表示させます。

パスワードを二回入力し、左上の「完了」を押します。

同様に、ユーザーの作成も行います。

ユーザー名とパスワードを入力。

「このユーザーを管理者にする(M)」もチェックをつけておきます。

設定したら左上の「完了」ボタン。


あとはインストールが終わるまでしばらく待ちます。



完了すると以下のような画面になります。そうしたら右下の「再起動」をクリックします。



このまま、何も操作をせずに待っているともう一度インストール画面になってしまうので、一旦イメージファイルを外します。

まずは再起動される前に、以下の画面のような元々のVirtualbox起動時の画面で、今作成中のCentOS8を右クリックして、「閉じる」→「電源オフ」で仮想マシンの電源を落とします。

以下のような画面になっていることを確認。

この画面で「設定」を押します。



設定の画面が開いたら、下記画面のように選択。

そして「仮想ドライブからディスクを除去」を選択。



以下のようになることを確認し、右下の「OK」をクリックし設定画面を閉じます。



VirtualBox起動時の画面へ戻ったら、CentOS8をダブルクリックして起動します。

少し待つと以下のような画面が表示されます。

License informationをクリックします。




「ライセンス契約に同意します。(A)」にチェックを入れて、左上の「完了」を押します。


右下の「設定の完了」を押します。


そうするとユーザー選択画面が表示されます。

作成したユーザーでログインします。



該当ユーザーのパスワードを入力し「ログイン」をクリックします。



無事ログインできれば、以下のような画面が表示されるはずです。


このあと、Pythonをインストールをするにしても、ネットへ繋がってなければなにも始まらないので、ネットが繋がるかどうかも確認しておきます。

これもいろんな方法があるとは思いますが、そのうちの一つ。

Firefoxを起動します。



そして、なんでもいいですが、googleの検索画面が表示できるか確認しましょう。




実は、CentOS8のインストール自体はこれでできているのですが、「画面を最大化」したり、「ホストOSからゲストOSへコピペ」とかいったりということがまだできません。

一通り作業が終わったあとにやるつもりですが、行う順番はどちらが先でもいいので、先に設定したい方はこちらの記事を先に読んでください。

VirtualBoxで画面を最大化する方法、クリップボードを共有する方法


python3.8のインストール

dnfを使用してインストールする場合

CentOS8のトップ画面へ戻り、「端末」を起動します。 これ以降はこの中での作業になります。



以下のコマンドを打ちます。

仮想環境の外から仮想環境の中へコピペもする方法はありますが、今この段階ではできないので、頑張って手打ちします。

$ sudo dnf groupinstall 'development tools’ 
何度か、確認を求めれるので全て「y」を押して進みます。

処理が終わったら、続いて次のコマンドを実行します。
$sudo dnf install bzip2-devel expat-devel gdbm-devel ncurses-devel openssl-devel readline-devel sqlite-devel tk-devel xz-devel zlib-devel wget
$VERSION=3.8.2
$wget https://www.python.org/ftp/python/${VERSION}/Python-${VERSION}.tgz
ここまで完了すると、/home/name(←いまログインしているユーザーの名前)以下に、.tgzのファイルが入ります。
$tar -xf Python-${VERSION}.tgz   // .tgzファイルを解凍
$cd Python-${VERSION}            // 解凍したファイルへ移動
$./configure --enable-optimizations  
$nproc

//自分の場合の出力
1
$sudo make -j 1 (←nprocで出力された数字を入力)
$sudo make altinstall
インストール自体はこれで完了なので、きちんとインストールされているか確認します。これも方法はいくつかあると思いますが、以下のようになれば成功しています。
//一例
$python3.8 —-version
Python3.8.2
あるいは実際に起動してみてもいいでしょう。
$Python3.8
Python3.8.2 (default ,Apr 10 2020, 00:51:32)
[GCC 8.3.1 20190507 (Red Hat 8.3.1-4)] on linux
Type "help","copyright","credits" or "license" for more information.
>>

そして、たびたびくどいようであれですが、「画面の最大化の設定」や「ホストOSとゲストOSでクリップボードの共有」などを設定した場合はこのあとに行っても構いません。

VirtualBoxで画面を最大化する方法、クリップボードを共有する方法


補足(万が一ネットにつながらないという場合)

基本、この手順を最初からなぞっていけば、ネットにも繋がっているとは思いますが、万が一つながらない場合には、以下のコマンドを実行してみましょう。
$nmcli d    // 接続の状態を確認、
                 // enp0s3のところ接続されていない状態になっている可能性がある。
$nmcli  connection up enp0s3   // 接続を確立
$nmcli d //念のため、もう一度状態が変わったか確認

VirtualBoxで画面を最大化する方法、クリップボードを共有する方法

この記事では、
  • VirtualBoxの中の画面を最大化する方法
  • ホストOSとゲストOSでクリップボードを共有する方法について説明します。
画面の最大化については、初期の状態では仮想化のウィンドウ自体を最大化しても、中の画面は大きくなりません。

そのままサイズで、周囲が黒く囲まれ、表示されるべきはずの画面が一部見切れているような状態になります。

これを通常の画面と同じように、スクリーン全体で表示できるように設定します。

また、同様に初期状態では、ホストOSとゲストOSでクリップボードが共有されていません。

どういうことかというと、例えばホストOSでコピーをしてゲストOSへ貼り付けようとしても、クリップボードが共有されていないので、貼り付けできません。

ゲストOSからホストOSへのコピペもしかり。

以上のことに対処するため設定していきます。

環境

  • MacOS 10.15.3 catalina
  • VirtualBox 6.0.18
  • CentOS8

VBoxGuestAdditionsのダウンロード

まず始めに、ここへアクセスしVBoxGuestAdditions をダウンロードします。


VBoxGuestAdditionsのインストール

続いて、該当の仮想マシンを起動し、「端末」を起動します。 

そして以下のコマンドを順次実行します。
$sudo yum update

パスワードを求められるので、入力します。(表示はされませんが入力はされています) 

場合にもよると思いますが、結構数が多いのでそれなりに時間がかかると思われます。

また、しばらくすると確認を求められるのでyを押します。

同様に、次のコマンドを実行します。

$sudo yum groupinstall "Development Tools”

これも、パスワードを入力し、確認が求められたらyを押します。 最後に次のコマンドを実行します。

$sudo yum install kernel-devel elfutils-libelf-devel

ここは確認しか求められないのでyを押します。

 続いて、先ほどダウンロードしたVBoxGuestAdditionsをインストールします。

 「Insert GuestAdditions CD images...」を選択します。



そうすると、仮想マシン上に次のような画面が表示されます。これは「実行」を選択します。





 ログインしているユーザーのパスワードを入力します。 




 そうすると、自動で処理が始まり、最終的には以下のような画面になります。



 Returnを押します。

 画面を最大化するだけであればこれで完了ですが、クリップボードの共有にはもう少し作業をします。

 一旦仮想マシンを終了します。

クリップボードの共有の設定

VirtualBoxの起動画面で、「設定」をクリックします。



 「一般」→「高度」と表示し、「クリップボードの共有」と「ドラッグ&ドロップ」を「双方向」にしておきます。

 設定したら「OK」を押して画面を閉じます。



これで設定は以上になるので、あとは起動して実際に確認すればできるようになっているはずです。

2019年9月8日日曜日

Java/クラス継承

新しい会社でJavaを新たに学ぶことになり、JavaSilverを勉強中。

勉強の記録したことを、自分の記録としても残しておこうと思う。

可能な限りシンプルな例で、言語の仕様などを理解できるように書いていこうと思う。

前提

JVMはインストールされている前提とする。

開発する環境はいろいろあるとは思うが(実際自分のパソコンにもSTSが入っているが)、愚直にコマンドラインからコンパイルを行っていく。

クラスの継承

Jobsというクラスを継承して、EngineerやPolice、Firefighter、Doctorといった子クラスを作っていくことを考える。

(まずはEngineerをつくるので、Policeなどはまだつくらないかもしれないが)

まず、Jobsクラスをつくる。
//Jobs.javaというファイル名にする。
//クラス名とファイル名は同じにしなければいけない。
public class Jobs{
int salary;
}
同様に、Engineerクラスを作る。
//Engineer.javaというファイル名にする。
//クラス名とファイル名は同じにしなければいけない。
public class Engineer extends Jobs{
  Engineer(){
    salary = 50;
  }
}
この二つのファイルを作成し、同じディレクトリに置いておく。

コマンドでカレントディレクトリ(この二つのファイルが置いてあるディレクトリ)に移動したら、以下のようにコマンドを打つ。
$javac Engineer.java
そうすると、同じディレクトリに、Jobs.classというファイルと、Engineer.classというファイルが作成される。

今回の場合、何かを行うわけではないので(コンソールに表示したりとか)、「無事コンパイルできました」というところで話は一区切りとなる。
$javac Jobs.java Engineer.java
としてもよいが、Engineer.javaだけでも同じこと。

コンパイルが失敗する例

コンパイルできない例も書いておく。

Jobsクラスは以下のようにする。(フィールドは何も宣言しない。)
//Jobs.javaというファイル名にする。
//クラス名とファイル名は同じにしなければいけない。
public class Jobs{
}
Engineerクラスは同じ。(だけどもう一度書いておく。)
//Engineer.javaというファイル名にする。
//クラス名とファイル名は同じにしなければいけない。
public class Engineer extends Jobs{
  Engineer(){
    salary = 50;
  }
}
これで、同じく
$javac Engineer.java
と打つ。

そうすると、以下のようなエラーが吐かれる。
Engineer.java:5: エラー: シンボルを見つけられません
    salary = 50;
    ^
  シンボル:   変数 salary
  場所: クラス Engineer
エラー1個
salaryという変数は親クラスでも子クラスでも宣言されていないからだ。

余談

本題とは少し関係ないが、やらかした凡ミスも書いておく。

本当に初歩の初歩のミスだが、extendsのところをsを抜かしてextendにしてしまってコンパイルできなかったことがあった。
//Engineer.javaというファイル名にする。
//クラス名とファイル名は同じにしなければいけない。
public class Engineer extend Jobs{
  Engineer(){
    salary = 50;
  }
}
これでコンパイルをしようとすると以下のようなエラーが出される。
Engineer.java:1: エラー: '{'がありません
public class Engineer extend Jobs{
                     ^
エラー1個

2019年8月12日月曜日

C++のコンパイルいろいろ(基礎から応用まで) --- その1

最近、他の言語のことや、コンパイラ周りのことを勉強して、今更ながら分割コンパイルのことを理解してきたので、全く知識ゼロ向けの人に向けて、導入編を書いてみたいと思います。

自分が当時わからなかったこととか、あるいはこんな記事があればいいのにな、ということを想定して書いていますが、わかりにくかったり、間違ったことを書いていれば教えて頂けるとありがたいです。

前提

前提としてclang++が入っていることを想定しています。

ざっくり言えば、よくサンプルコードとして紹介されるHello worldが動く状態です。

ちなみに、以前紹介したwhichコマンドを使って調べると、自分のパソコンにはclang++が入っていました。
$ which -a clang++
#二つありますよ、という意味で2行出てくる。
/Users/hiroshi/.pyenv/shims/clang++       #単にclang++ で実行するとこちらのコンパイラが動く。
/usr/bin/clang++    #これがXcode付属のコンパイラ
バージョンを確認すると、
/usr/bin/clang++
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
となっているが、ここはよくわからないので、そんなもんかということで先へ進むことにする。最新バージョンはclang10のようだけど。。。?

参考 : Clang 10 documentation


基本

まずは、なんのひねりもない、一番基本から。

Hello worldを表示するプログラムをコンパイルします。

コンパイルするコードは以下のコード。
// ファイル名はhello.cppとする。
#include<iostream>

using namespace std;

int main(){

  cout << "Hello world \n" ;

  return 0;
}

hello.cppがあるフォルダと同じフォルダに移動し、以下のコマンドでコンパイルする。
$  /usr/bin/clang++ -std=c++17  hello.cpp
-std=c++17 の部分はコマンドのオプションです。

「-std=なになに」でc++のどのバージョンとしてコンパイルできるかを指定できます。

このあたりの話は今回は省略します。また機会があれば詳しく書くかもしれません。

同じフォルダにa.outという実行ファイルができているので、それを実行します。
$  ./a.out      # くどい説明かもしれないけど、「./」で「現在のディレクトリの中の」の意味。現在いるディレクトリの中のa.outというファイルを実行している。
Hello world


分割コンパイル(ダメな例)

複数のソースコードをまとめてコンパイルすることもできます。

で、成功するやりかたの前に、誰しも一度はやってしまうであろう(そんなことない?)ダメなパターンを紹介します。

まず、以下のような2つのソースコードを作ります。
// 先ほどのhello.cpp
#include<iostream>

using namespace std;

int main(){

  cout << "Hello world \n" ;

  return 0;
}
// 2つめのファイルはmorning.cppとしておく。
#include<iostream>

using namespace std;

int main(){

  cout << "Good morning! \n" ;

  return 0;
}
これを、
$/usr/bin/clang++ -std=c++17  hello.cpp morning.cpp
と実行すると、
duplicate symbol _main in:
    /var/folders/3j/6lblgwg16hsf8kqx9wl_5r440000gn/T/hello-eafe6a.o
    /var/folders/3j/6lblgwg16hsf8kqx9wl_5r440000gn/T/morning-cca263.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
というエラーが掃き出される。

いくつかのファイルをまとめてコンパイルする場合、その中にmain関数は一個にしなければならないが、hello.cppのほうも、morning.cppのほうもmain関数になってしまっているのでエラーになっている。


分割コンパイル(うごく方法)


  その1

ヘッダファイルを介してインクルードする。

同じディレクトリの中に、以下の3つのソースコードを用意する。

ディレクトリ構造も、書くまでもないが一応書いておく。
  • greeting.cpp
  • morning.cpp
  • morning.hpp
// 今度はgreeting.cppという名前にする。
#include<iostream>
#include "morning.hpp"
using namespace std;

int main(){

  Morning();

  return 0;
}

//これはmorning.cppという名前にする。
#include<iostream>

using namespace std;

void Morning(){

  cout << "Good morning! \n" ;

}
// これはmorning.hppとする。
void Morning();
これで、
$ /usr/bin/clang++ -std=c++17  greeting.cpp morning.cpp
と実行する。そして、./a.outを実行すると、Good morning! と表示される。

  その2

直接.cppのファイルをインクルードすることもできる。

今度は、以下2つのファイルを用意する。
  • greeting.cpp
  • morning.cpp
// このファイルはgreeting.cppとする。
#include<iostream>
#include "morning.cpp"
using namespace std;

int main(){

  Morning();

  return 0;
}
 //これはmorning.cppとする
#include<iostream>

using namespace std;

void Morning(){

  cout << "Good morning! \n" ;

}
そして、コンパイルする際には、以下のようにgreeting.cppだけをコンパイルする。
 $/usr/bin/clang++ -std=c++17  greeting.cpp
これでも、またa.outを実行すれば、Good morning! と表示されるはず。

  その3

2つ以上のファイルを一度にコンパイルもできる。

再びヘッダファイルからインクルードする。

今度は以下のようなファイルを用意し同じディレクトリに置く。

ディレクトリ構造を書けば、
  • greeting.cpp
  • morning.cpp
  • afternoon.cpp
  • evening.cpp
  • morning.hpp
  • afternoon.hpp
  • evening.hpp
 // これはgreeting.cppという名前にしておく。
#include<iostream>

#include "morning.hpp"
#include "afternoon.hpp"
#include "evening.hpp"
using namespace std;

int main(){

  Morning();
  Afternoon();
  Evening();

  return 0;
}
 // これはmorning.cppという名前にしておく。
#include<iostream>

using namespace std;

void Morning(){

  cout << "Good morning! \n" ;

}
 //これはafternoon.cppという名前にしておく。
#include<iostream>

using namespace std;

void Afternoon(){

  cout << "Good afternoon! \n" ;

}
 //これはevening.cppという名前にしておく。
#include<iostream>

using namespace std;

void Evening(){

  cout << "Good evening! \n" ;

}

 //これはmorning.hppという名前にしておく。
void Morning();
 //これはafternoon.hppという名前にしておく。
void Afternoon();
 //これはevening.hppという名前にしておく。
void Evening();
それで、以下のようにコマンドを実行する。
$  /usr/bin/clang++ -std=c++17 greeting.cpp morning.cpp afternoon.cpp evening.cpp
$ ./a.out
そうすると以下のようになるはずです。
Good morning! 
Good afternoon! 
Good evening! 

  その4

ヘッダファイルだけを一つのディレクトリにまとめてしまうこともできる。

先ほどの、greeting.cpp〜evening.hppをまた使うことにする。

ソースコードはさすがにくどいので省略。

ディレクトリ構造は以下のようになっているとする。
  • greeting.cpp
  • morning.cpp
  • afternoon.cpp
  • evening.cpp
  • my_include    →このディレクトリは新しくつくる。その中に以下の3つを入れる。
    • morning.hpp
    • afternoon.hpp
    • evening.hpp
$  /usr/bin/clang++ -std=c++17 greeting.cpp morning.cpp afternoon.cpp evening.cpp  -I ./my_include
$ ./a.out
そうすると、また同様に以下のように表示されるはずです。
Good morning! 
Good afternoon! 
Good evening!


長くなってきたので、今回はここまでにしておきます。

まだまだいろいろあるので、また次回以降にしようと思います。

2019年8月11日日曜日

未経験からエンジニアに転職するまで

さて、先日、転職をしたことを書いたが、やっと8月から現場が決まったので、巷で流行りの転職体験談を書いてみようと思う。

あらかじめ断っておくが、かなり長いと思う。


ことのはじまり

数学で大学院へ進学したはいいものの、数学で生きていくには厳しいと悟り、就職をしようとしていた。

しかし、就職活動がうまくいかないまま、大学院を修了した。

その後、紆余曲折を経て、某大手企業で契約社員としてテクニカルサポートで約4年働いていた。

いわゆるコールセンター。一般ユーザーからの問い合わせに対応していた。

数学ではないにしても、他の分野でアカデミックな道を目指したいと思っていたが、当時はお金もなく(むしろ奨学金などでマイナス)、実力もなかったので、とりあえずはエンジニアなどで正社員を目指していた。

良くも悪くも、当時いた職場が居心地がよく、気づいたら4年近く経っていた。

このままではまずい、と危機感を覚えはじめ、転職活動を始めた。

転職活動開始

2016年下旬に一度目、2018年初旬に二度目の転職活動をしていた。

2016年の転職活動のときは、転職エージェントをつかっておこなっていた。

このとき、転職活動を一旦止めてしまった理由は二つある。

一つは、何社ほど面接へいったのか覚えていないが、当時選考を進めていた企業が全滅してしまったからだ。

もう一つは、転職エージェントの担当者が提案してくるペースが速く、それについていけず疲れてしまったのだ。

そして、しばらく休んだのち、2018年初旬に再度転職する活動をしなければいけない危機感に苛まれ、活動を始めることにした。

このときは、学習し履歴書や職務経歴書も以前よりはうまく書けるようになっていた。(といっても今現在から比べればまだまだだったと思う。)

しかし、また全滅。

方針転換

当時、独学でも勉強していたが、いま一つアピールとしては弱かったような気がする。

本気度も伝わっていなかった気がする。

どうすれば、より本気度がアピールできるか考えた結果、プログラミングスクールに通うことを思いついた。

SNSなどでも広告をたまに見かけたりして存在は知っていたが、いざ本格的に調べてみると思ったよりもいろんなスクールがあることがわかった。

このときの資金状況としては、やはりあまり芳しくはなかったが、このままなにもアクションを起こさない状態では、悪い状況は変わらないし、アクションを起こして仮に失敗したとしても、「行動を起こした」という事実自体が、一つのアピールにしたいと考えたからだ。

ここでも、一旦転職活動そのものは休止し、まずはプログラミングスクールへ通うことに目標をシフトした。

説明会や事前選考などを受け、最終的に4つのスクールから入学許可を出た。そのうちのひとつに入学することになる。

スクールのカリキュラムの関係で、当時の職場で働き続けるのは困難だったため、契約更新を打診されるときに、更新しない旨(=退職すること)を伝えた。

有給がかなり残っていたので、2018年7月の1ヶ月は丸々有給をつかい、同時に7月からプログラミングスクールに通うことにした。

最近多い、転職サポート付きのスクールで、AI系のエンジニアを目指すコースへ通うことになった。

これが、2018年7月のことである。

プログラミングスクールへ通う

そのプログラミングスクールでは、同期が何人かいて、一部チーム開発的なこともやった。

メンターや同期と関わるなかで、そもそもの本題の内容はもちろんのこと、エンジニアとして常識的な考え方やスキル、あるいは(同期もエンジニア未経験ではあるけれど)同期の秀でたところや、逆に自分の秀でたところも発見できとても刺激的だった。

特に、今までコールセンターでしか働いてないので、大した実績もなく、転職活動の選考でも落ち続けている自分は、なにも優れたところがないと悲観的になっていたが、他の人が苦労していることが自分には自然にできていることなどがあって、自分にも秀でたところがあるんだと、自信が湧いてきた。

しかし、環境そのものはよかったが、資金面でやや見切り発車してしまったため、資金が尽き、泣く泣くプログラミングスクールを中途解約することになる。

ふりだしに戻る

転職活動云々の前に、目先の生活のためのお金がないので、まずはなんでもいいので働くことにした。

テクニカルサポートの経験が長く、ある程度勝手がわかることもあり、以前とは違う職場ではあるが、またテクニカルサポートで働くことになってしまう。

これがだいたい2018年の11月〜12月頃のことだ。

転機その1

ドタバタしすぎていて、転職活動そのものは休止にせざる得なかったが、このときは「タイミングをみてすぐにでも活動開始してやる」と気持ちを切らすことはなかった。

一方で、(ここでは書かないが)他にもいろいろなことが起こりすぎて、少し憔悴していた。




さて、再度働き始めたコールセンターでも、研修などが終わり軌道に乗り始めた頃。

転職サイトでつながりをもっていた、先ほど述べたプログラミングスクールの同期(正確には同期ではなくて一期入学が前の人だが交流があった)から、連絡があった。
(当時の記事 : 喫茶店ピース / 新宿西口)

その人は無事転職を成功させたようで、またその会社がデータサイエンティストを募集しているので、応募してみないかと言われた。
(当時の記事 : 「とりあえず動いてみる」の大切さ)

プログラミングスクールに通うことを決意したときもそうだが、このときはいいタイミングがきたら、あまり後先考えずとりあえずアクションを起こしてみる思考になっていたような気がする。

その知人からの紹介により、応募。

面接までいくが残念ながら不採用となってしまう。
(当時の記事 : 久しぶりに怒涛の一日)

しかしそのときは、一般応募ではなく、社員からの紹介ということだったので、面接を担当してくれた方も、率直な意見やアドバイスをくれた。

結果としては不採用ではあったが、そのときの自分の立ち位置やレベルが理解できたので、これはこれで前進したとは思った。

転機その2

再度働き始めたコールセンターでは、「どうせそんなに長くいるつもりはないから、人間関係もそんなに深く関わらないでいいや」という心持ちであまり周囲と関わらなかった。

もともとそんなに深く関わるのは得意ではないのだけれど、今まで以上に距離をおいている感じだったと思う。

とはいっても、同期入社が全体的に中がよく、向こうから絡んでくれたので仲良くなった。

ある日、同期メンバーでもんじゃを食べに行くことになった。

正直、ああいう自分で調理するようなやつはあまり得意ではなくて、参加するか迷ったけど、参加してみることにした。

お好み焼きを作るのも苦手なこともさることながら、もんじゃにいたってはそもそもどういう風につくるのかいまいち理解していなかった。

もんじゃの調理を任されたとき、引き受けるかどうか迷ったが、引き受けた。

そもそも作り方がよくわからないけど、失敗したところで命を取られるわけじゃないし、突撃してみようと思った。

そして、よくわからない自分は、お好み焼きよろしく、もんじゃの具を一気に鉄板の上に流し込んでしまった。

そうしたら、参加していた自分よりも一回りも若い子に笑われた。

でも、不思議と恥ずかしいとは思わなかった。

自分は結構常識的なことを知らないけど、今更それを悔いてもしょうがない。

いまこのことによって、今まで知らなかったことを一つ知れてよかったじゃないか、と思えるようになった。

「若い子に笑われた」と書いたが、その子が可愛かったので、「笑ってくれた」ではなく「笑われた」のだとは思うがそれでも、なにか反応してくれたのが嬉しかったのもある。

そして、それがきっかけで、「笑われる」=「自分は世間の常識ではないことをしている」=「単に物を知らない or オリジナルなことしている」という構図が頭の中に成立し、「笑われる」ことがある種快感になっていった。

それが、「笑ってくれている」のではなく、「笑われている」のだとしても。

そして、「失敗を楽しめ!」というモットーが自分の中に誕生した。

転職活動再開

先ほどのプログラミングスクールでの知人とまた食事をし、先日の結果などについてお伝えした。

またその話の流れで、キャリアプランの話とか、アルバイトであれば未経験でもエンジニアを募集しているところが意外にあるといった話にもなった。

それをきっかけに、先ほどの「失敗を楽しめ!」の精神で、転職サイトに登録しまくり、応募もしまくった。

転職サイトについては、たくさんあるので、一度に全てのプロフィールを完成させることはできないので、「毎日」少しずつプロフィールを埋めて、かつ改善させていった。

また応募に関しても、気になった企業には、「半ば機械的に」、「毎日数社ノルマを決めて」応募をしていった。

最終的に内定がでるまでには40〜50社応募はしていたと思う。

期待をくじかれる

その中で、最終面接一歩手前まで進んだ企業がある。

書類選考の段階で、比較的いい印象をもってもらえたようで、一次面接にいったその日に二次面接まで行ってもらえた。

しかし、残すは最終面接のみとなったとき、選考フローには書かれていなかった、コーディング課題が出されてしまった。

特に期限は指定されなかったが、一週間弱をめどに取り組むも終わらず、さらに一週間延長。結局完全な完成までは至らなかったが、これ以上延長するのもあれだったので、それで提出した。

しかし、そこで不採用になってしまう。

一次、二次をサクサク進み、残すは最終面接のみだったので期待したが、それも砕かれた。

しかし、著作権はこちらもちで構わない、もし必要であれば他社へ応募する際にポートフォリオとして使って構わないと言われたので、遠慮なく使わせてもらうことにした。

内定

引き続き、「毎日数社」とノルマを決めて応募をしていた。

書類で落ちることもあったが、面接までいける会社も結構あった。

そうすると、コールセンターで週5で働きながら、休みの日(平日)に面接にいく、みたいな生活を送っていた。

面接に一社いくと、往復の移動時間も含めると数時間は使ってしまうし、交通費もバカにならないので、この頃は書類が通過して面接に呼ばれても、「面接しても通る見込みが薄いようであれば、書類で落としてもらえると嬉しい」みたいなことで、可能性が低いところは、切っていた気がする。


そんな生活をしているうちに4月末ごろ、なんと内定がでたのだ!

そこで、新規の応募は中断。

今現在、面接待ちのところの結果をみて終わりにしようと決めた。

そして驚くことに、残していた残り一社の面接でも内定がでたのだ。

今となってはわからないが、「内定が一個でている」ということを伝えたのも効果的だったかもしれない。

「内定が出ています」カードはわりと強いのか。

給料としては一社目の方がよかったが、自分のキャリアプランや社員の雰囲気などからあとあとから内定が出たほうに入社することにした。

引き止め

うれしいことに、一社目の会社からは引き止められたりもした。

「会社の魅力を十分に伝えられなかったかも知れないので、もう一度話し合いの機会を設けさせてくれないか」といわれたので、「意思を変更することを前提としないのであれば」という条件で、もう一度面接をしに行ってきた。

今度は、選考面接ではないので、非常にざっくばらんに話をさせてもらった。

決して雰囲気は悪くはなかったが、話をするなかで、もう一社のほうが自分のキャリアプランに合っていそうな気を改めて強くしたので、改めて辞退をすることにした。

研修

どこの会社もだいたい同じかとは思うが、技術研修は課題が与えられてそれをどんどん進めていく形式だった。

研修はJavaの研修だった。

履歴書や職務経歴書、ポートフォリオなどをみて自分の実力を知っている人事や講師からは、「他の人の半分の期間で終わらせようか(笑)」と言われてたが、途中バグが取れなかったり、意外にボリューミーだったこともあり、なんだかんだ周りと同じになってしまった。

とはいっても周りよりは遥かに詳しかったので、同期の人とかに教えたりもしていた。

一方で、それなりにスキルがあるということで、会社としても退屈な現場に行かせたくないのか、現場を選んでくれているようで、なかなか現場が決まらなかった。

研修も終わりようやく現場着任となった。

現場着任

詳しいことは言えないが、Javaを使う現場で、SpringFrameworkを使う現場にまずは着任となった。

詳細設計から携わることになり、今まで独学でプログラミングをやってきて、変数名とか適当でやってたので、画面仕様書の作り方でExcelと格闘している、という状態。

以前、倉庫作業のアルバイトをするための送迎バス待ち合わせをした場所の近くで、そのとき、ビルの中へ吸い込まれていく人達をみて「いつかあっち側の世界に行きたいな」と思ったところだったので、いざそちら側へきてみると感慨深い。
(当時の記事 : 分断されている世界)

振り返って

振り返ってみると、未経験から転職するにはポートフォリオを充実させることは重要だと思った。

自分の場合は、先ほど述べた知人から紹介された会社へ応募する際に、その人が作った履歴書や職務経歴書を参考に見せてもらった。

そうするとかなり職務経歴書やポートフォリオが充実していたので、それを見習った。

自分が職務経歴書や転職サイトに載せたのは、
  • githubのURL(プログラミングスクールでつくった成果物を少し整理した)
  • 先ほど述べた選考の途中で課されたコーディング課題の成果物
  • このブログ
などである。

あと、職務経歴書の方も多少盛ってしまったが、少しでも触ったことがあるものはスキルとして書いたので結構なボリュームになった。

面接で言葉を並べるのもいいけれど(話すときに使うキーワードである程度スキルは見極められるだろうから)、実際にコードをみればより的確にスキルを見てもらえるので、是非載せるべきだと思う。



あと、やや繰り返しにはなるが、「失敗を楽しめ!」というモットーが自分の中に誕生したことは大きかったと思う。

「失敗を楽しめ!」という命令形なのか「失敗を楽しむ」なのかは、テンションにもよるけど、なにか躊躇することがあったときには、このフレーズを頭に唱えることで、随分性格が変わったと思う。

そもそもここに至ったのは、もんじゃの件がきっかけではあるけれど。

たかがもんじゃ。

何気ない日常の中に、思いもよらないきっかけは隠れているのかもしれない。

2019年6月29日土曜日

MNISTデータの読み込み

これまた、いまさら感が半端無いが、MNISTの読み込み方を書いておく。

市販されている本(例えば『ゼロからつくるDeeplearning』とか)にうまーくパッキングされたものが付録としてついてきている場合もあるが、そういうのに頼らず、自力でやる方法を紹介する。

なぜなら本を買うとお金がかかってしまう可能性があるから。

ChainerやTensorFlowであれば、標準搭載されていますが、できるだけ高度なライブラリは使わず、できるかぎり標準的な装備でやりたいというのもあるので。

条件

  • お金はかけない(市販されている本などは頼らない)
  • できるだけ低装備で行う

注意

sklearnにも、load_digitsというデータセットが入っているが、こちらはMNISTを加工して作られた8ピクセル×8ピクセルの画像データで、MNISTの簡略版なので、MNISTとは違うので注意しよう。
(参考:https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_digits.html)

オリジナルのMNISTは28ピクセル×28ピクセルの画像データだ。

MNISTデータをダウンロード

まずは、MNISTのデータ本体を以下のURLへアクセスしてダウンロードする。

http://yann.lecun.com/exdb/mnist/

そこで、以下の4つのファイルをダウンロードしてくる。
  • train-images-idx3-ubyte.gz
  • train-labels-idx1-ubyte.gz
  • t10k-images-idx3-ubyte.gz
  • t10k-labels-idx1-ubyte.gz
で解凍までする。

それで、新しくディレクトリをつくって、そこにこの4つのファイルを入れる。

新しいディレクトリの名前はなんでもいいのですが、ここではMNIST_dataという名前にすることにする。

python-mnistをインストール

MNISTを扱うようのライブラリがあるのでインストールする。 ターミナルを起動して、以下のようにコマンドを打つ。
pip install python-mnist
(参考: https://pypi.org/project/python-mnist/ )

python-mnistのインポートからファイル読み込みまで

今回MNISTを読み込むコードを書くファイルは、とりあえずmnistとしておく。

そして、mnistという名前のファイルと同じディレクトリに、先ほどのMNIST_dataというディレクトリも置く。

実際のインポートは以下のようにします。
from mnist import MNIST
mnist = MNIST('../MNIST_data')
x_train, y_train = mnist.load_training() 

import numpy as np
import matplotlib.pyplot as plt
x_train = np.asarray(x_train).astype(np.float32)

x_train.shape      # (60000, 784)が返ってくる。
x_train[0]           #  784要素の配列が返ってくる。

plt.imshow(x_train[0].reshape(28,28))     # 画像として表示される。
plt.show()
以上でMNISTのインストールが完了。

あとは、いろいろと好きなようにゴリゴリやっていくだけです。

2019年6月26日水曜日

Tomcatの起動の仕方

随分久しぶりの更新となってしまった。

転職先の研修でJavaをやっているので、その絡みで、これまでの流れ?と話は変わるがTomcatについて書こうと思う。


今回書くのは、まずはTomcatのターミナルからの起動方法。

Tomcat自体は、単体でもインストールできるが、Eclipse(エクリプスorイクリプスと読みます)をインストールすればその中に入っているので、とりあえずそれを使うことにする。(Spring tool suite、通称STSでも同様。)

Tomcat自体のインストールやEclipseのインストールは検索すればすぐ出てくるので省略する。

もう少し具体的にいえば、途中までの行き方はインストールの仕方によってそれぞれ違うと思うので、ここでは、Tomcatの中のbinというディレクトリのところまで辿りつけたところから話を始める。

ちなみにbinというのはどういうディレクトリかというと、中にはこんなファイルやディレクトリがあるところ。

  • bootstrap.jar
  • commons-daemon.jar
  • makebase.sh
  • tomcat-juli.jar
  • catalina-tasks.xml
  • configtest.bat
  • setclasspath.bat
  • tomcat-native.tar.gz
  • catalina.bat
  • configtest.sh
  • setclasspath.sh
  • tool-wrapper.bat
  • catalina.sh
  • daemon.sh
  • shutdown.bat
  • tool-wrapper.sh
  • ciphers.bat
  • digest.bat
  • shutdown.sh
  • version.bat
  • ciphers.sh
  • digest.sh
  • startup.bat
  • version.sh
  • commons-daemon-native.tar.gz
  • makebase.bat
  • startup.sh
参考までに、今回の記事のようにEclipseの中のTomcatを使う場合、その場所は、

/Applications/Eclipse_2019-03.app/Contents/tomcat/9/bin

にある。

さて、binの中のstartup.shのコマンドを打ちたいが、このままではパーミッションが有効ではないので、カレントディレクトリがbinの状態で以下のようなコマンドを打つ。
$ chmod 755 *.sh
特に何か起こったようには見えないが、気にしない。

そうすれば、startup.shが実行できるようになるので、以下のようにコマンドを打つ。
 #くどいようだけど、カレントディレクトリがbinフォルダであるという前提。
$ ./startup.sh
そうすると以下のようになれば成功。
Using CATALINA_BASE:   /Applications/Eclipse_2019-03.app/Contents/tomcat/9
Using CATALINA_HOME:   /Applications/Eclipse_2019-03.app/Contents/tomcat/9
Using CATALINA_TMPDIR: /Applications/Eclipse_2019-03.app/Contents/tomcat/9/temp
Using JRE_HOME:        /Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home
Using CLASSPATH:       /Applications/Eclipse_2019-03.app/Contents/tomcat/9/bin/bootstrap.jar:/Applications/Eclipse_2019-03.app/Contents/tomcat/9/bin/tomcat-juli.jar
Tomcat started.
適当なブラウザを開き、http://localhost:8080/というURLに移動すれば、Tomcatのページが表示される。

2019年3月24日日曜日

『闇ウェブ』




ダークウェブについて知っておきたいことが、バランスよくコンパクトにまとまっている印象だった。

技術的な部分については、ある程度厳密性を犠牲にしてるおかげで全体像が捕えやすかった。

結局、匿名であることがいろいろと事をややこしくしている印象。匿名だからこそ、命がけで正義を全うするのに一役買う側面がある一方で、匿名であることを悪用すると非常に厄介。


2019年3月6日水曜日

プログラミング言語

プログラミングの周辺の話題で、以前から興味があることがある。

というか、疑問。

「なんであんなにたくさん言語があるのか」




自然言語(英語とか日本語とか中国語とか普通に喋る用の言語)ならわかる。

歴史的要因や地理的要因、流行などその他諸々によって進化していくので、あれだけ数があることも、特別疑問に感じない。

でも、プログラミング言語の場合って、機械語やアセンブリ言語然り、Cなど低いレイヤーの言語があるじゃないですか。なんでそれ一本槍でいかないのかと。

というか、いい年をしてこんなことを疑問に思ってて、でも意外にみんな、そんな感じで素朴に質問されたら答えられないのではないかと思っている。



そこで、

「プログラミング言語はマシンを統制するための言語」

という視点にたち、

「最終的に機械語に置き換えられて実行されるんであれば、程度の差こそあれ『プログラミング言語』という一つのツールとしてみなせないのか」

と思って、いろんな言語同士をお互いに埋め込んだり、処理を受け渡したりする方法をちょこちょこ調べていたりする。

なんか我ながらマニアックなことをやっていると思う。

調べること中心で、あんまり実装はできていないけど、そういうものも含めて興味があることは、
  • pythonコードにC++を埋め込む
  • C++のコードにpythonを埋め込む
  • pythonのコードにJavaを埋め込む
  • Javaのコードにpythonを埋め込む(←あんまりやる意味ない?)
  • Javascriptの中にC++を埋め込む
などなど以下、他の言語同士でも同様。さらに、
  • C++のコードにアセンブリ言語を埋め込む
  • SVGの中にC++を埋め込む
  • C++からmatplotlibへ描画
  • C++からgnuplotへ描画
  • ProcessingにC++を埋め込む
などなど。あんまり理解していないので、そもそもやる意味ないやつとか、支離滅裂なことをいっている組み合わせもあるかも。




自然言語で話すときは、方言とか、違う言語通しチャンポンで話すことも結構あったりするのに、プログラミング言語でそれができないのは、なんかもどかしいなっていう感じ。

なんか発言がど素人的な発言だけど。

でもいいのさ。素人の目線でみて、専門家的に考え検討するの大事だと思うから気にしなーい!

2019年3月1日金曜日

C++11のコンパイルのための環境確認

今回、久々にC++を書いてみたくなり、改めて勉強してみた。

その際、そのときどうやらC++11のコードで書いてしまっていたようで、警告がでてしまった。

現在の環境確認の確認なども行なったのでそれのメモ。

今回コンパイルするコード

今回は以下のコードをコンパイルすることにする。ファイル名はstudy.cppとする。
## 以下のコードをテキストエディタやAtom、Vimなど適当なテキストエディタに書いて、ファイル名をstudy.cppにして保存。
#include<iostream>

using namespace std;

int main(){
  auto ch = "x";            #ここの部分がC++11のコード
  cout << "success \n";
  return 0;
}

環境の確認

最近になって、コンパイラが云々という細かい話が少しわかってきた。 とりあえず、ネットなどでよくみたりして自分が知っているコンパイラが、gcc、g++、c++ ,clang、clang++なので、それのバージョンなどを調べてみた。 といった矢先、まずそれぞれ実行コマンドがどこにあるのか調べてみることにした。

whichコマンド(その1)

whichコマンドで、実行コマンドがどこのディレクトリにあるのか確認できるらしい。 特に、オプションとして-aをつけて実行すると、環境変数PATHに登録されている中から全て検索するらしい。 whichを実行した結果がこれ。
  • gcc
  • $which -a gcc     #ターミナルを開いて、カレントディレクトリがどこでもいいので、左記を打って実行。
    /usr/bin/gcc      #実行結果
    
  • g++
  • $ which -a g++
    /usr/bin/g++
    
  • c++
  • $ which -a c++
    /usr/bin/c++       
    
  • clang
  • $ which -a clang
    #二つありますよ、という意味で2行出てくる。
    /Users/hiroshi/.pyenv/shims/clang
    /usr/bin/clang       #これがXcode付属のコンパイラ
    
  • clang
  • $ which -a clang++
    #二つありますよ、という意味で2行出てくる。
    /Users/hiroshi/.pyenv/shims/clang++
    /usr/bin/clang++    #これがXcode付属のコンパイラ
    
上記にもコメントをしているように、/usr/binにあるのがXcodeの付属のコンパイラらしい。

whichコマンド(その2)

上記のwhich -a コマンドで二つあるものがあったが、それでは実際にはどっちが実行されるのかというのはwhichでしらべる。
  • clang
  • $ which clang
    /Users/hiroshi/.pyenv/shims/clang
    
  • clang++
  • $ which clang++
    /Users/hiroshi/.pyenv/shims/clang++
これらは、環境変数PATH、つまり
$ echo $PATH
/Users/hiroshi/.pyenv/shims:/Users/hiroshi/.pyenv/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/opt/X11/bin
において、より左側に書かれているディレクトリから探索していって、より早く見つかる実行ファイルが実行されている。

バージョンの確認

上記で確認した、gcc、g++、c++、clang、clang++全てについてバージョンを確認しようと思ったが、clangとclang++以外はよくわからなかったのでその二つについて書く。 それ以外はわかり次第、追い追いかくかも。 なにも指定せず、以下のようにclang -vのように打った場合には、環境変数PATHに置いてより左側にある実行ファイルのバージョンが確認できる。
$clang -v
clang version 4.0.0 (tags/RELEASE_400/final)
Target: x86_64-apple-darwin18.2.0
Thread model: posix
InstalledDir: /Users/hiroshi/.pyenv/versions/anaconda3-4.3.0/bin
$ clang++ -v
clang version 4.0.0 (tags/RELEASE_400/final)
Target: x86_64-apple-darwin18.2.0
Thread model: posix
InstalledDir: /Users/hiroshi/.pyenv/versions/anaconda3-4.3.0/bin
環境変数とか関係なしに、特定の実行ファイルのバージョンを調べたい場合は、絶対パスで書いてしまう。
$ /usr/bin/clang -v
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin18.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
$ /usr/bin/clang++ -v
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
Target: x86_64-apple-darwin18.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Xcode付属のclang、clang++については、これだけでは明確にわからない気がしたが、どうやら少なくとも10以上の様子。
( cf:Xcode --wikipedeia )

オプションの指定

さて、Xcode付属のclangやclang++であれば、C++11に対応しているはずなので、以下のように実行してみるがエラーになってしまう。
$/usr/bin/clang++ study.cpp
study.cpp:6:3: warning: 'auto' type specifier is a C++11 extension [-Wc++11-extensions]
  auto ch = "x";
  ^
1 warning generated.

(もしくは)
$/usr/bin/clang study.cpp
→たくさんエラーが掃き出されるので省略。
調べてみたところ、自分の理解力では明確な理由はわからないが、以下のようにオプションをつけて実行すればコンパイルできるらしい。
$ /usr/bin/clang++ -std=c++11 study.cpp
hiroshi-no-MacBook-Air:3-C:C++ hiroshi$
生成された実行ファイルを実行するために、./a.outと打てば、以下のようになり成功したことがわかる。
./a.out
success
当然clangのほうではできない。理由については自信がない。

これらのコマンド群はシェルでつくってしまってもいいかもしれない。そのあたりのことはまた別の機会に。

2018年2月15日木曜日

Syntaxhighlighterのサンプル

//preタグで記述する場合
print("hello world!!")

これはSyntaxhighlighterのテスト用の投稿です。

2018年2月14日水曜日

google-code-prettifyのサンプル

print("hello world!!")
これはgoogle-code-prettifyのテスト用の投稿です。

2018年1月28日日曜日

dein.vimのインストール

ネットにも、もう十分に情報は転がっているが、忘備録的な意味も含めて書いておく。

まず新しいディレクトリを作成するため
$hiroshi-no-MacBook-Air:~ hiroshi$ mkdir ~/.cache/dein
と打ってreturnを押す。(見た目上はなにも起こらない)

で、そのあとディレクトリを移動する。
$hiroshi-no-MacBook-Air:~ hiroshi$ cd ~/.cache/dein
そこで、以下のようなコマンドを打つ。
$curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
そうすると、こんな処理が走る。
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2355  100  2355    0     0   6722      0 --:--:-- --:--:-- --:--:--  6747
続いて、こう打つ。
$ sh ./installer.sh ~/.cache/dein
そうすると、次のような処理が走って完了となる。
Install to "/Users/hiroshi/.cache/dein/repos/github.com/Shougo/dein.vim"...

git is /usr/bin/git

Begin fetching dein...
Cloning into '/Users/hiroshi/.cache/dein/repos/github.com/Shougo/dein.vim'...
remote: Counting objects: 4752, done.
remote: Compressing objects: 100% (78/78), done.
remote: Total 4752 (delta 51), reused 126 (delta 42), pack-reused 4607
Receiving objects: 100% (4752/4752), 934.74 KiB | 1.48 MiB/s, done.
Resolving deltas: 100% (2699/2699), done.
Done.

Please add the following settings for dein to the top of your vimrc (Vim) or init.vim (NeoVim) file:


"dein Scripts-----------------------------
if &compatible
  set nocompatible               " Be iMproved
endif

" Required:
set runtimepath+=/Users/hiroshi/.cache/dein/repos/github.com/Shougo/dein.vim

" Required:
if dein#load_state('/Users/hiroshi/.cache/dein')
  call dein#begin('/Users/hiroshi/.cache/dein')

  " Let dein manage dein
  " Required:
  call dein#add('/Users/hiroshi/.cache/dein/repos/github.com/Shougo/dein.vim')

  " Add or remove your plugins here:
  call dein#add('Shougo/neosnippet.vim')
  call dein#add('Shougo/neosnippet-snippets')

  " You can specify revision/branch/tag.
  call dein#add('Shougo/deol.nvim', { 'rev': 'a1b5108fd' })

  " Required:
  call dein#end()
  call dein#save_state()
endif

" Required:
filetype plugin indent on
syntax enable

" If you want to install not installed plugins on startup.
"if dein#check_install()
"  call dein#install()
"endif

"End dein Scripts-------------------------


Done.
Complete setup dein!

最後のコマンドを打ったあとに処理される上記の"dein Scripts-----------------------------のところから"End dein Scripts-------------------------をコピーする。
それをvimrcに貼り付けるので、以下のコマンドをうってvimrcを起動する。
$vim .vimrc
でそこにコピーした内容を貼り付け。

vimrcのほうは一度上書き保存して終了。

vimを起動したあと、ノーマルモードで

:call dein#install()
とすればインストールらしき処理が始まりcompleteという感じになる。。

で、試しに挿入モードで
div
とか打って、[control+y],と打つと
<div>
みたいに展開される。

[control+y]だけじゃなくて、そのあとに,必要!を打ち忘れてて、「展開されないなー」と少し悩んでしましまったので注意!

「control+y」を、例えば[contorol+e]とかに変更するには、.vimrcとかに
let g:user_emmet_leader_key = '< c-e >'< /c-e >
とか記述すれば、キーの対応が変わる。
参考にしたところ(主なものだけ)

2017年7月21日金曜日

Skleranを使ってみる3

前回の『Sklearnを使ってみる2』を引き続き読み進めていく。

本の方では、『Setosaとそれ以外という分類は簡単にできたが、ではSetosa以外をVirginicaとVirsicolorに分類するのはどうすればいいか、簡単にできそうにはない』と話が進んでいく。

ではどうするかというと、とりあえずの回答として『力技で総当たりで閾値を探す』という方法をとる。

で、まず手始めの準備として、Setosa以外だけから成る、特徴量とラベルを改めて抽出しなおしておく。
(不要なところは#でコメントアウトしてある。)
from matplotlib import pyplot as plt
from sklearn.datasets import load_iris
import numpy as np

data = load_iris()

features=data["data"]
feature_names=data["feature_names"]
target=data["target"]
target_names=data["target_names"]
labels=target_names[target]


#for t,marker,c in zip (range(3),'>ox','rgb'):
#    
#    plt.scatter(features[target == t,0],features[target == t,1],marker=marker,c=c)
#
#plt.show()


plength=features[:,2]
is_setosa=(labels=='setosa')

max_setosa=plength[is_setosa].max()
min_non_setosa=plength[~is_setosa].min()

#print('Maximum of setosa:{0}'.format(max_setosa))
#print('Minimum of others:{0}'.format(min_non_setosa))

features=features[~is_setosa]
labels=labels[~is_setosa]
virginica=(labels=="virginica")

最後の三行
features=features[~is_setosa]
labels=labels[~is_setosa]
virginica=(labels=="virginica")
が新たに加わった分。 最初の二行も前回やったブールインデックス参照。

is_setosaがsetosaのところがTrueでそれ以外がFalseの配列なので、それをTrueとFalseを反転させている。

なので~is_setosaは、setosa以外がTrueになっていて、setosaがFalseになっています。
で、ブールインデックス参照を使って、配列からsetosa以外に該当するものを抽出している。

三行目は二行目で抽出したsetosa以外のラベルから、特にvirginicaに一致するものだけをさらに抽出し、ブーリアン配列を生成する。

で、本題の閾値を探す部分のコードが以下。
#初期値の値は処理に影響がないように適当に決める。
とりあえず絶対に影響がないような値として負の値で設定しています。
best_acc=-1.0       #正解率の値の初期値
best_fi=-1.0          #閾値となる特徴量のラベルの値の初期値
best_t=-1.0           #具体的な閾値の数値の初期値


for fi in range(features.shape[1]):    #features.shapeの値はこのとき(100,4)となっている。
なのでfeatures.shape[1]は4。つまり特徴量の個数です。全ての特徴量を総当たりで試すという方針。

    thresh=features[:,fi].copy()       #特徴量を一つ固定してそれに対する数値を全部抽出
    thresh.sort()         #上の行で抽出した数値をソートする。

    for t in thresh:       #測定値一つ一つに対して、「それが閾値になりうるか」を総当たりで試す。

        pred=(features[:,fi]>t)      #測定値一つをとりあえず閾値として固定して、
その閾値以上となっている測定値に対して新しいブーリアン配列としている。

        if (labels[pred]=="virginica")!=():     #accがnanになることを排除。詳細は下記で。
        acc=(labels[pred]=="virginica".mean())      

#上の行でつくったブーリアン配列に対して、さらにラベルが"virginica"に一致しているものを抽出。
#つまり、結果としては、測定値が閾値以上でかつvirginicaであるものを抽出してその平均をとっている。
        if acc > best_acc:    #よりよい結果を出した「特徴量と閾値の組み合わせ」に更新する処理。
          best_acc=acc      #もし、よりいい正解率が出たのなら、よりその時点での最良正解率としてそれに更新
          best_fi=fi             #もし、よりいい正解率がでたのなら、そのときの特徴量を採用。
          best_t=t              #もし、よりいい正解率がでたのなら、そのときの閾値を採用。


本文とは違い、if(labels[pred]=="virginica")!=():  という行を追加していますが、これなしだと、accがnanになってしまうことがあるので追加している。

最後に以下を追加して一段落。
def apply_model(example):
   if example[best_fi] > best_t : print("virginica")
   else:print("versicolor")

2017年1月16日月曜日

Sklearnを使ってみる2

以前、といってもかなり前になってしまいますが、『Sklearnを使ってみる1』という投稿で、『実践 機械学習システム』という本を読み進めようとしていましたが、かなり間があいてしまいましたが、続きをやっていこうと思います。


前回、とりあえず以下のコードが動きました。
from matplotlib import pyplot as plt
from sklearn.datasets import load_iris
import numpy as np

data = load_iris()

features=data["data"]
feature_names=data["feature_names"]
target=data["target"]
target_names=data["target_names"]
labels=target_names[target]

for t,marker,c in zip (xrange(3),">ox","rgb"):

 plt.scatter(features[target == t,0],features[target == t,1],marker=marker,c=c)


とりあえず、この先
for t,marker,c in zip (xrange(3),">ox","rgb"):

 plt.scatter(features[target == t,0],features[target == t,1],marker=marker,c=c)


の部分は使わないので、コメントアウトするなり消すなりしておきます。
from matplotlib import pyplot as plt
from sklearn.datasets import load_iris
import numpy as np

data = load_iris()

features=data["data"]
feature_names=data["feature_names"]
target=data["target"]
target_names=data["target_names"]
labels=target_names[target]

#for t,marker,c in zip (xrange(3),">ox","rgb"):

 #plt.scatter(features[target == t,0],features[target == t,1],marker=marker,c=c)


で代わりにコードを継ぎ足して以下のようにします。
from matplotlib import pyplot as plt
from sklearn.datasets import load_iris
import numpy as np

data = load_iris()

features=data["data"]
feature_names=data["feature_names"]
target=data["target"]
target_names=data["target_names"]
labels=target_names[target]

#for t,marker,c in zip (xrange(3),">ox","rgb"):

 #plt.scatter(features[target == t,0],features[target == t,1],marker=marker,c=c)


###追加した部分
plength=features[:,2]
is_setosa=(labels=='setosa')

max_setosa=plength[is_setosa].max()
min_non_setosa=plength[~is_setosa].min()

print("Maximum of setosa:{0}".format(max_setosa))
print("Minimum of others:{0}".format(min_non_setosa))



一行一行説明していきます。

plengthの行

まず、plengthの行は、生データから花弁の長さ(plength)の値だけからなる新しい配列を作成しています。

前回、Irisデータセットは辞書型配列になっていて、その"data"要素には生データの一覧がarray型で格納されているということを確認しました。

それで、そのdata要素をfeaturesという変数に格納しました。(なので当然featuresにも生データが入っている。)

featuresの中は特徴量がarray型としてデータ別に入っているわけです。各要素の3番目の要素(インデックスとしては2番目)には花弁の長さの値が入っているので、インデックス2番目だけをすべて抽出して、plengthという変数に配列として格納しますよ、という意味。

厳密に言えば、plengthの型はarray型です。気になるようであれば、print(type(plength))として確認する。

plengthの部分だけ確認するのであれば、print(plength)を一番最後に追記しておけば、本当かどうか確かめられる。


from matplotlib import pyplot as plt
from sklearn.datasets import load_iris
import numpy as np

data = load_iris()

features=data["data"]
feature_names=data["feature_names"]
target=data["target"]
target_names=data["target_names"]
labels=target_names[target]

#for t,marker,c in zip (xrange(3),">ox","rgb"):

 #plt.scatter(features[target == t,0],features[target == t,1],marker=marker,c=c)


###追加した部分
plength=features[:,2]
is_setosa=(labels=='setosa')

max_setosa=plength[is_setosa].max()
min_non_setosa=plength[~is_setosa].min()

#print("Maximum of setosa:{0}".format(max_setosa))
#print("Minimum of others:{0}".format(min_non_setosa))

print(plength)
print(type(plength))



これを実行すれば、
[ 1.4  1.4  1.3  1.5  1.4  1.7  1.4  1.5  1.4  1.5  1.5  1.6  1.4  1.1  1.2
  1.5  1.3  1.4  1.7  1.5  1.7  1.5  1.   1.7  1.9  1.6  1.6  1.5  1.4  1.6
  1.6  1.5  1.5  1.4  1.5  1.2  1.3  1.5  1.3  1.5  1.3  1.3  1.3  1.6  1.9
  1.4  1.6  1.4  1.5  1.4  4.7  4.5  4.9  4.   4.6  4.5  4.7  3.3  4.6  3.9
  3.5  4.2  4.   4.7  3.6  4.4  4.5  4.1  4.5  3.9  4.8  4.   4.9  4.7  4.3
  4.4  4.8  5.   4.5  3.5  3.8  3.7  3.9  5.1  4.5  4.5  4.7  4.4  4.1  4.
  4.4  4.6  4.   3.3  4.2  4.2  4.2  4.3  3.   4.1  6.   5.1  5.9  5.6  5.8
  6.6  4.5  6.3  5.8  6.1  5.1  5.3  5.5  5.   5.1  5.3  5.5  6.7  6.9  5.
  5.7  4.9  6.7  4.9  5.7  6.   4.8  4.9  5.6  5.8  6.1  6.4  5.6  5.1  5.6
  6.1  5.6  5.5  4.8  5.4  5.6  5.1  5.1  5.9  5.7  5.2  5.   5.2  5.4  5.1]

こうなる。

is_setosaの行

次にis_setosaの行。
まさにリスト内包表記を使っている例。
前回でlabelという変数に、どのデータがどの花なのかという名前の対応リストを格納しました。

(label=='setosa')で、labelの中の名前の一覧と比較してsetosaに一致していればTrueを、そうでなければFalseを返してTrueかFalseから成る配列を生成しis_setosaに格納します。

もっとスマートにいえばブーリアン配列を生成するということです。

確認するには、例のごとくprint(is_setosa)を追記して実行すればいいです。面倒なのと、若干くどい気もするので、ここは省略。


max_setosaの行

次にmax_setosaの行へ行きます。

plength[is_setosa]の意味ですが、ブールインデックス参照という書き方です。

is_setosaがTrue or Falseからなる配列であることを上で書きました。そういうブーリアン配列をインデックスとして代入すると、plengthの要素の中からブーリアン配列のTrueに対応している要素だけを抽出して新しい配列を作成します。

Trueになっているのはsetosaのところでしたので、setosaに対応している花弁の長さだけが抽出できます。

plength[is_setosa]という名前の新しい配列なので、それにmax()メソッドを使っている。

つまり、setosaの花弁の長さの中で一番値が大きいものを、max_setosaに代入。

min_non_setosaの行

この行も、先ほど使ったブールインデックス参照が使われてます。

今度はsetosa以外のものの最小値を求めています。

setosa以外、ということはis_setosaにおいてはFalseにあたるものです。

Falseのままではブールインデックス参照ができないので、「~」演算子を使ってビット反転させis_setosaのTrueはFalseに、FalseはTrueにしてして代入しています。

printの行

最後は、処理というよりは、単純にpythonの文法ですが、一応自分なりに説明しておきます。

これは文字列に対するformatメソッドです。
調べてみると、formatメソッドにもいろいろ描き方のバリエーションがあるようですが、おそらく基本的な描き方は以下の形式かと思われます。

'文字列'.format(要素0,要素1,・・・)
ドットより前の文字列の中に、formatに引数として渡されている要素のインデックスの番号を代わりに代入して、最終的な出力文字列の体裁だけ整えるイメージです。

上記の"Maximum of setosa:{0}".format(max_setosa)とかであれば、この場合はformatメソッドに渡している要素が一つだけなので、それがインデックス0番目ということになりますが、それを「Maximum of setosa:{0}」という文字列の{0}をmax_setosaで置き換えたものが、結果としてできる文字列です。それをprintしている。
{数字}のところが、その番号に対応しているインデックスの要素で置きかわるという意味です。
詳しくは、下でまとめてあるリンクや本を参照。


で結局のところ、
from matplotlib import pyplot as plt
from sklearn.datasets import load_iris
import numpy as np

data = load_iris()

features=data["data"]
feature_names=data["feature_names"]
target=data["target"]
target_names=data["target_names"]
labels=target_names[target]


#for t,marker,c in zip (range(3),'>ox','rgb'):
#    
#    plt.scatter(features[target == t,0],features[target == t,1],marker=marker,c=c)
#
#plt.show()


plength=features[:,2]
is_setosa=(labels=='setosa')

max_setosa=plength[is_setosa].max()
min_non_setosa=plength[~is_setosa].min()

print('Maximum of setosa:{0}'.format(max_setosa))
print('Minimum of others:{0}'.format(min_non_setosa))

を実行すると、
hiroshi-no-MacBook-Air:Pro-tr hiroshi$ python3 others.py
Maximum of setosa:1.9
Minimum of others:3.0

という感じになります。
参考にしたページや文献・書籍
NumPy配列のブールインデックス参照 | hydroculのメモ
Python 3 の文字列フォーマット formatメソッド | TM Life
『実践 機械学習システム』(オライリー)

2016年7月22日金曜日

Graphviz/PyGraphvizのインストール

前々から使ってみたいとは思っていました。

調べてみたら以外にインストールのハードル自体は低そうなので、サクっと入れてみました。
brewとpip3を用いてインストールできるようです。
brewについてはbrew searchを実行してたくさん吐き出されるリストの中にgraphvizが確かにあることを自分で確認してみましょう。

環境は以下の通り。

  • El'Captan(10.11.5)
  • Homebrewはインストール済み

Graphvizのインストール

hiroshi-no-MacBook-Air:~ hiroshi$ sudo brew install graphvi

と実行するだけです。例のごとく自分のPCのパスワードを求められるので、パスワードを入力すれば、次のような処理がはしります。それほど長くない処理。
==> Downloading https://homebrew.bintray.com/bottles/graphviz-2.38.0.el_capitan.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring graphviz-2.38.0.el_capitan.bottle.1.tar.gz
🍺  /usr/local/Cellar/graphviz/2.38.0: 469 files, 67M

Graphvizのインストール自体はこれだけ。
PyGraphvizのインストール、と先へ進む前に、Graphvizのインストールがきちんとできているか確認します。

テキストファイルに次のように記述して、Sample.dotというように拡張子をdotにして保存します。

#####以下のように記述し、dotという拡張子で保存
graph g{
    "Hello World"
    }

でSample.dotという、今保存したファイルが保存してあるディレクトリへカレントディレクトリを移し、そこで次のようなコマンドを実行します。

######Sample.svgというファイルで出力する場合
hiroshi-no-MacBook-Air:Pro-tr hiroshi$ dot -Tsvg Sample.dot -o Sample.svg

そうするとSample.dotが保存されているディレクトリと同じディレクトリにSample.svgとファイルが生成されます。
それをブラウザで開けば、次のようなものが表示されます。

注意)紛らわしいけど、上に貼り付けてある画像はSVGファイルをブラウザで開いたものをスクリーンショットで撮影したpng画像です!BloggerだとSVGファイルは挿入できないらしい。



PyGraphvizのインストール

pip3を入れているので、以下のようにコマンドを打つだけで完了です。
hiroshi-no-MacBook-Air:Pro-tr hiroshi$ sudo pip3 install pygraphviz

例のごとく自分のPCのパスワードを入れると次のような処理が進み(すぐ終わります)、完了です。

The directory '/Users/hiroshi/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
You are using pip version 7.1.0, however version 8.1.2 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
The directory '/Users/hiroshi/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting pygraphviz
  Downloading pygraphviz-1.3.1.zip (123kB)
    100% |████████████████████████████████| 126kB 2.0MB/s 
Building wheels for collected packages: pygraphviz
  Running setup.py bdist_wheel for pygraphviz
  Stored in directory: /Users/hiroshi/Library/Caches/pip/wheels/81/03/ed/eb3b7ef51ee6527abfaf2701e222e74107b97344cfa2201881
Successfully built pygraphviz
Installing collected packages: pygraphviz
Successfully installed pygraphviz-1.3.1

確認作業は、

hiroshi-no-MacBook-Air:Pro-tr hiroshi$ python3    #python3と打ってrerurnを押す。
Python 3.4.3 (default, Aug 11 2015, 08:57:25) 
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pygraphviz       #import pygraphvizと打ってreturn
>>> 

としてエラーがでなければOK。

2016年7月10日日曜日

シグモイド関数の描画

gnuplotもインストールしたし、matplotlibも使える状態だしということで、なんだかんだ可視化やグラフ描画をするツールは割りと揃ってきた。。

それぞれ、ツールの使い方の勉強という意味含め、ニューラルネットなどででてくるのシグモイド関数の振る舞いをイメージしておきたいなども理由もあるので、シグモイド関数を描画してみようと思い描画してみた。。

gnuplotでの描画

gnuplotでもfor文が使えるらしいのでそれを使う。

ターミナルを起動して、gnuplotを起動する。
hiroshi-no-MacBook-Air:Pro-tr hiroshi$ gnuplot     #gnuplotと打ち込んでreturnを押す
起動したら次のように打ちます。
gnuplot> set yrange[0:1]       #見栄えを良くするための設定。y軸方向の描画範囲の指定。
gnuplot> plot for [i=0:10] 1/(1+exp(-i*x/10))
これを実行すると、次のような図が表示される。




gnuplotを起動したときに、毎回表示されるバージョンを確認しよう。
どうやら、plot forという書き方はバージョン4.4からの機能のようだ。
(参考:明日できること)

matplotlibでの描画

matplotlibでは次のように描画する。

matplotlibとscipyがインストールできていることは前提。 インストールできていない場合はまずこちらから。
Macでpython3の環境構築9---Scipyのインストール---
Macでpython3の環境構築4---Matplotlibのインストール1---
from matplotlib import pyplot as plt
import scipy as sp

x=sp.arange(-10,10,0.1)
for t in range(10):        #必要なグラフは先にすべて生成する。
  y=1/(1+sp.exp(-(2*t*x/10)))
  plt.plot(x,y)         


plt.show()   #最後にまとめて描画すると重ねて表示される。
matplotlibの使い方の説明にもなってしまうが、グラフを重ねて描画するときは、先にplt.plot()、plt.plot()という感じで必要なグラフをすべて生成して、最後にplt.show()をして最後に描画する。

上記を例えば、テキストファイルに書き、sigmoid.pyという名前で保存。sigmoid.pyがあるカレントディレクトリに移動して、
hiroshi-no-MacBook-Air:Pro-tr hiroshi$ python3 sigmoid.py
とコマンドを打って実行すると、次のような画面が出てくる。



for文のところで、あまり数を刻みすぎてしまうと、グラフが表示されたときよくわからない表示になってしまうので、適当に間引いて描画したほうがそれらしくみえる。

参考にしたページや文献・書籍
明日できること
シグモイド関数---wiki