OSとファイル…
前期の後半はファイルについての説明を細かく行う。 まずは、ファイルとOSは切っても切れない関係ということで、 簡単にOSの歴史を説明。
OSの歴史と役割
簡単にOSの意味を説明するために、簡単に歴史を紹介。 最初のコンピュータが出てきた時代は、すべてが機械語で、 ハードディスクにデータを記録するためにも、面倒なプログラムを自分で書いていた。 しかし、ハードの複雑化と共に、ファイルにデータを記録するといった一般的な処理は 基本となる共通の処理をあらかじめ書いておくことで、 プログラムを共通化できるようになった。
OS,CPUの歴史をパソコンに限定して説明する。 最初のパソコンのOSはBASICだった。しかし機能が不足して16bit化される時に、 新しいOSが必要となりMS-DOSが作られ、異なるハードウェアでも 共通の機能で使えるようになった。
一方、8bit時代にAppleⅡを開発していたApple社は、 Lisaなどを経てGraphical User Interface(GUI)で操作しやすいMacintoshを開発する。 この操作性の影響を受け、Microsoft社は Windows などを開発していく。
これ以前のOSは、シングルタスク・シングルユーザが普通であった。 しかしWindows などのGUI環境では、ウィンドウ毎に別プログラムを動かすことから、 マルチタスク機能が重要となってきた。そしてこれらの機能を安定して動かすために、 i80286,i80386のような32bitコンピュータの開発時に、 プログラム保護機能が実装された。これにより、 不当な動きのプログラムを強制的に止めたりすることができるようになり、 マルチユーザ・マルチタスク機能が普及する。
ファイルとPATH
unixやMS-DOSでは、木構造ファイルが採用され、ディレクトリを使って ファイルを分類して保存ができるようになった。この中でファイルの場所を 指定するために、ディレクトリの名前を根幹から書き連ねる絶対PATHが 使われる。一方で、巨大なファイルであれば、PATH表現は長くて不便となる。 このため注目している場所を起点としてファイルの場所を表現する相対PATHも 使われる。
振る舞い図と相互作用図
http://www.itsenka.com/contents/development/uml/communication.html 振る舞い図と相互作用図について説明を行う。
相互作用図
- アクティビティ図
フローチャートを起源とする図で、状態変化と制御の流れ・データの流れを表現する。
rarestyleの記事の図を引用
- ユースケース図
Think ITの記事の図を引用
- ステートチャート図(状態遷移図)
慶応・藤原氏の記事の図を引用
相互作用図
- シーケンス図
IT専科の記事より図を引用
- コミュニケーション図
IT専科の記事より図を引用
DebianにMaharaをインストール
eポートフォリオのMaharaを使ったネタをやりませんかとのお誘いで、 自分の環境にひとまずMaharaを入れてみることからやってみよう。
# aptitude install mahara 色々と競合とかでてきたので、競合相手も追加してinstallをかける... # dpkg-reconfigure -plow mahara データベースの種類: mysql5 データベースのホスト名: なし データベースのポート番号: なし データベース名: mahara データベースのユーザ名: mahara データベースのパスワード: パスワード SMTPホスト名: なし ## /usr/share/doc/mahara/README.Debian に書いてある通り # mysql -u root -p Enter password: MYSQLの管理者パスワード > CREATE DATABASE mahara CHARACTER SET utf8; Query OK, 1 row affected (0.00 sec) > GRANT ALL ON mahara.* to mahara IDENTIFIED BY 'パスワード'; Query OK, 0 rows affected (0.00 sec) > FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) > exit (( /etc/mahara/apache.conf )) # http://ホスト名/mahara/ で使えるように、先頭の以下のコメントをはずす。 Alias /mahara /usr/share/mahara
このあと、http://ホスト名/mahara/にアクセス。いろいろチェックがかかって インストール作業がおこわなわれて、最後に Admin User のパスワードとメールアドレスを登録して終了。
参考サイトの情報を元に、https://wiki.mahara.org/index.php/Language_Packs より、 ja-1.3_STABLE_tar.gz をダウンロードし….
# cd /usr/share/mahara/lang # tar zxvf ...PATH.../ja-1.3_STABLE.tar.gz
あ、日本語化の途中で何か壊しちゃった….site settings が表示できなくなった…
UML構造図
先週のUMLの全体像の話に続いて、UMLの中の構造図を中心に説明を行う。
- クラス図
- オブジェクト図
- コンポーネント図
- パッケージ図
- 配置図
いかのサイトが、必要最小限かつ細かい表現方法が記載されていて便利。 (具体例は他のサイトを参照したほうがいい…)
クラス図とオブジェクト図
四角の枠の中に、クラス名、属性、メソッドを記載。 属性・メソッドの前には、可視性の+:public,-:private,#:protectedの記号を書く。 クラス間に何らかのつながりがあれば、関連ということで直線で結ぶ。 線上には、役割や多重度(例:1..*)を記載。
関連で、包含関係にあるものは集約(あるいは単に包含)と呼ばれ、 ◇ーの矢印で接続する。集約の中で特にライフサイクル依存が強いものは、 コンポジションと呼ばれ、一般的に"has-a"関係となる。 この場合は、[本体] ◆ー [パーツ]の矢印で接続する。 C++あたりであれば、大抵の場合は、集約ならポインタで実装され、コンポジションなら実体で実装されるだろう。
class Tire { | class Engine { : | : } ; | } ; -----------------+---------+------------------- class Car { // Composition | class Car { private: | private: Tire wheel[ 4 ] ; | Tire* wheel[ 4 ] ; Engine engine ; | Engine* engine ; } ; | } ;
汎化や派生(継承)といった関係の例えば、"Person is-a Animal" といった関係は、 派生クラスから親クラスへの△矢印で接続を行う。
オブジェクト図は、クラス図を具体的な実例で書く。クラス名には下線を書く。
コンポーネント図、パッケージ図
コンポーネント図は、物理的な構成要素からシステム構造を記述する。 大きなプロジェクトの全体像を広い視点で見渡すような場合に有効。 他のコンポーネントとのインタフェースを、ロリポップで表現。
[コンポーネント]—(◯—[コンポーネント]—(◯—[…]
パッケージ図は、パッケージ同士の依存関係を論理的なグルーピングで表現。 1つのパッケージは、フォルダの図で表現し、そのパッケージ間の依存関係を、 破線の矢印で結ぶ。
配置図
具体的なデバイスや実行環境を、立方体の絵で表現。 各デバイス間の関係を直線で接続して表す。
まともな過去問を使えよ…
4EIのテスト問題の採点中。 プログラムと効率の理解を確認するために、途中へのデータ挿入の 効率理解ということで、リストであればO(1)であるところを、 配列の途中へのデータ挿入がO(N)かかることの実践ということで、 配列へのデータ挿入を出題している。
しかし、過去の試験問題で似た出題があって、どうも過去問をみて勉強しているようで、 過去の回答者の効率の悪いコードを真似ている人が多い。 さらに、模範解答で説明したネタと一緒になって記憶しているだけの人がいて、 2つのコードを混ぜた回答していて、ハチャメチャ。
# 頭の中で自分のコードをシミュレートしろよ…
途中挿入だから、移動領域の重なったmoveだし、後ろ側からコピーする典型。 データ検索部を抜いて、後ろにシフトする部分のコードは、
// 普通の後方シフト int idx ; // 挿入場所 int data ; for( int i = size - 1 ; i >= idx ; i-- ) array[ i + 1 ] = array[ i ] ; array[ idx ] = data ; // 効率の悪い後方シフト for( int i = idx ; i < size ; i++ ) { int temp = array[ i ] ; array[ i ] = data ; data = array[ i ] ; } array[ i ] = data ;
確認として、配列サイズ10000件で同一処理を10000回ループで時間を計測。 通常後方シフト=0.281秒、効率の悪いシフト=0.534秒で、1.9倍遅い。 まあ、速度比較の結果としてはそんなもんだろう…
試したいけど、Android …(06/10)
- 06/10 試したいけど、Android 3.1な端末が必要なのか… "Android Open AccessoryとArduinoベースの開発キット" http://arms22.blog91.fc2.com/blog-entry-… #fnct
- 06/10 Arduinoで動いてるんだってさ。"自動追尾台車「カルガモちゃん」" http://arms22.blog91.fc2.com/blog-entry-… #fnct
この記事は、 の @TohruSaitohに掲載した #fnct タグ付き記事を、まとめたものです。
UMLの歴史と意味
プログラミングでの演習もほぼ終わり、オブジェクト指向での設計の話へ。 オブジェクト指向でUMLの書き方は、統一した図法という意味で重要であることを 示しながら、全体の説明を行う。
最初に、UML以前の説明として、フローチャート図やPADの説明を行う。 処理の流れを記載するものとして、使われてきているがデータ構造の設計も重要。
UMLは、ランボーによるOMT(Object Modeling Technique どちらかというとOOA中心?)と、 ヤコブソンによるオブジェクト指向ソフトウェア工学(OOSE)を元に1990年頃に 発生し、ブーチのBooch法(どちらかというとOOD中心?)の考えをまとめて、 UML(Unified Modeling Language)としてでてきた。
OMTでは、OOA(Object Oriented Analyze:分析中心)として(1)問題記述、(2)オブジェクトモデルの記述、(3)状態遷移図の作成、(4)データフロー図の作成といったプロセスが行われる。 これに、OOD(Object Oriented Design:実装目的)でOOA段階の図法に加え、 ユースケース図、シーケンス図などを加えながら設計を行う。 この2つをOOADとまとめる場合も多い。
UMLでよく使われる図を列記すると、以下の物が挙げられる。
- 構造図
- クラス図
- コンポーネント図
- 配置図
- オブジェクト図
- パッケージ図
- 振る舞い図
- アクティビティ図
- ユースケース図
- ステートチャート図(状態遷移図)
- 相互作用図
- シーケンス図
- コミュニケーション図(コラボレーション図)
リストの考え方の導入
テストを明日からに控え、新しい所に入りたくはないけど、 配列の利点や欠点を理解するためにも、ランダムアクセスやシーケンシャルアクセスの 話を取り混ぜながら、導入説明を行う。
配列の添字でリスト
struct List { int data ; int next ; } ; int top = 2 ; struct List table[] = { { 56 , 1 } , // 0 { 78 , -1 } , // 1 { 12 , 3 } , // 2 { 34 , 0 } , // 3 } for( int p = top ; p >= 0 ; p = table[ p ].next ) { printf( "%d" , table[ p ].data ) ; }
次のアドレスでリスト
struct List { int data ; struct List* next ; } ; struct List* top ; top = (struct List*)malloc( sizeof( struct List ) ) ; top->data = 12 ; top->next = (struct List*)malloc( sizeof( struct List ) ) ; top->next->data = 34 ; top->next->next = (struct List*)malloc( sizeof( struct List ) ) ; top->next->next->data = 56 ; top->next->next->next = NULL ; struct List* p ; for( p = top ; p != NULL ; p = p->next ) printf( "%d" , p->data ) ;
ポインタで配列をスキャン&bit演算
例年のテスト問題の範囲を確認して、bit演算の話をしたけど、 先週の授業でのポインタのネタが不完全だったので、 その続きを後半で説明をした。
ポインタで配列をスキャン
ポインタの説明ということで、今週はアドレス渡しによるプログラムを説明。 分かりやすい例ということで、swap()を説明し、動作イメージを解説。
void swap( int* a , int* b ) { int temp = *a ; *a = *b ; *b = temp ; } void main() { int x = 11 , y = 22 , z = 33 ; swap( &x , &y ) ; swap( &y , &z ) ; }
次に、配列をポインタでスキャンするような処理で、 ポインタのインクリメントの説明。
分かりやすい事例として、配列末尾に終了目印(0)がついている内容の加算を考える。
int a[] = { 11 , 22 , 33 , 0 } ; int sum( int a[] ) { // 配列で書いてみる int s = 0 ; for( int i = 0 ; a[i] != 0 ; i++ ) s += a[i] ; return s ; } int sum( int* p ) { // ポインタで書いてみる int s = 0 ; for( ; *p != 0 ; p++ ) s += *p ; return s ; } int sum( int* p ) { // もっと短く int s = 0 ; while( *p != 0 ) s += *p++ ; return s ; }
ビット演算
2進数の理屈が分かっていれば、コンピュータ内部の電子回路的に行われている 掛算もプログラムで記述できる。この時、2進数の数値の処理ということで、 ビット演算が重要。
int mul( int x , int y ) { int s = 0 ; while( y != 0 ) { if ( y & 1 != 0 ) s += x ; x <<= 1 ; y >>= 1 ; } return s ; }
ArduinoでGPSデータ取れ…(06/03)
- 06/03 ArduinoでGPSデータ取れちゃうのね。"Arduinoで遊ぼう-GPSで現在位置を取得する" http://arms22.blog91.fc2.com/blog-entry-… #fnct
この記事は、 の @TohruSaitohに掲載した #fnct タグ付き記事を、まとめたものです。