D3.js 01信号の可視化

信号に関する授業を聴いていたらふと思い立ったのでやってみた。 コード index.html 個人的テンプレを書く。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>0-1 Signal</title> </head> <body> <h1>0-1 Signale</h1> <svg> </svg> <script src="https://d3js.org/d3.v5.min.js"></script> <script src="script.js"></script> </body> </html> script.js JavaScriptでflatMap使うのはこれが初めてかも。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 const format = (data, w) => { const pairs = d3.pairs(data); const deltas = pairs.flatMap(e => { let sig = e.toString() if (sig == '0,0') { return [[1,0]]; } else if (sig == '0,1') { return [[1,0],[0,-1]]; } else if (sig == '1,0') { return [[1,0],[0,1]]; } else if (sig == '1,1') { return [[1,0]]; } else { throw new Error('invalid element.'); } }); const points = deltas.reduce((acc, e) => { const back = acc[acc.length - 1].slice(); back[0] += w * e[0]; back[1] += w * e[1]; return acc.concat([back]) }, [[0,0]]); return points; }; const [svgWidth, svgHeight] = [800, 800]; const svg = d3.select('svg') .attr('width', svgWidth) .attr('height', svgHeight); const pad = 70; const render = (data) => { svg.selectAll('*').remove(); svg.append('path') .datum(data) .attr('transform', `translate(${pad}, ${pad})`) .attr('stroke', 'black') .attr('fill', 'none') .attr('d', d3.line() .x(d => d[0]) .y(d => d[1])); }; render(format([0,0,1,0,1,0,1,1,1,1,0,0], 50)); 実行結果 説明 format 01の情報を、path用の頂点データに変換する関数。 ...

2019-12-17 · (updated 2019-12-26) · 2 min · 231 words

iPhoneアプリ開発メモ - TableViewCellのスワイプ処理

目標 スワイプしたら削除されるテーブルを作る。 準備 TableViewに最低限の設定をしておく。 Main.storyboardを次のようにする。 ViewController.swiftの内容を以下のようにする。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! var items = ["Item1", "Item2", "Item3", "Item4", "Item5"] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. tableView.dataSource = self tableView.delegate = self } } extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "testCell")! cell.textLabel?.text = items[indexPath.row] return cell } } スワイプしたらボタンが出る処理 次のメソッドを実装する。 ...

2019-12-15 · (updated 2019-12-22) · 4 min · 799 words

iPhoneアプリ開発メモ - UIPageViewControllerの利用

目標 ウォークスルーっぽいものを作る。 メイン画面でボタンを押すとウォークスルー画面に飛ぶ。 ウォークスルー画面では、左右にスワイプすると画面が移動する。 画面下に、何ページかを教えてくれる白丸(Page Control)を配置する。 登場物 Main.storyboardとViewController.swift Walkthrough.storyboardとPageViewController.swift 準備 上に書いたものをとりあえず全て作る。ただし、PageViewControllerのサブクラスはUIPageViewControllerであることに注意。 Main.storyboard ボタンを一つ作っておく。 Walkthrough.storyboard 配置を次のようにする Page View Controllerのidentifierはwalkとする。また、classをPageViewControllerにする。 “Page1"と書かれたViewControllerのidentifierはpage1とする。 “Page2"と書かれたViewControllerのidentifierはpage2とする。 “Page3"と書かれたViewControllerのidentifierはpage3とする。 以下で、Transition Styleを"Scroll"とする。もし"Page Curl"とした場合は、ページをめくるようなアニメーションになる。その代わりにPage Controlが表示されない。 PageViewController.swift 次のように書く。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 class PageViewController: UIPageViewController { var controllers: [UIViewController] = [] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. view.backgroundColor = .black let stb = storyboard! let page1 = stb.instantiateViewController(withIdentifier: "page1") let page2 = stb.instantiateViewController(withIdentifier: "page2") let page3 = stb.instantiateViewController(withIdentifier: "page3") controllers = [page1, page2, page3] setViewControllers([controllers[0]], direction: .forward, animated: true, completion: nil) dataSource = self } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ } extension PageViewController: UIPageViewControllerDataSource { func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { if let index = controllers.firstIndex(of: viewController), index-1 >= 0 { return controllers[index-1] } else { return nil } } func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { if let index = controllers.firstIndex(of: viewController), index+1 < controllers.count { return controllers[index+1] } else { return nil } } func presentationCount(for pageViewController: UIPageViewController) -> Int { return controllers.count } func presentationIndex(for pageViewController: UIPageViewController) -> Int { return 0 } } 説明 UIPageViewControllerは次のように利用する。 ...

2019-12-14 · (updated 2019-12-22) · 2 min · 367 words

iPhoneアプリ開発メモ - addTarget/SegmentedControl

目標 降順、昇順の切り替えができるTableViewを作成する。 準備 Main.storyborad 部品を以下のように配置する。 Segmented Controlのラベルの設定は以下で行える。 TableViewCellのindentifierはtestCellとする。 ViewController.swift 後々の処理のため、TableViewに表示するデータをitems、その元データをitemsSourceと分けることにする。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class ViewController: UIViewController { let itemsSource = ["items1", "items2", "items3", "items4", "items5", "items6", "items7", "items8"] var items: [String] = [] @IBOutlet weak var segmentedControl: UISegmentedControl! @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. tableView.dataSource = self items = itemsSource } } extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return items.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "testCell")! cell.textLabel?.text = items[indexPath.row] return cell } } Segmented Controlのイベント設定 ViewController.swiftに追記する。 ...

2019-12-14 · (updated 2019-12-22) · 2 min · 268 words

iPhoneアプリ開発メモ - セミモーダルビューからの遷移

目標 セミモーダルビューを作成する セミモーダルビュー上のボタンを押すと、それを閉じた後に別ビューに遷移する。 登場物 Main.storyboardとViewController Menu.storyboardとMenuViewController Dest1.storyboard Dest2.storyboard 前提 今後Viewが増えていく状況を想定して、Storyboardを分割することを考える。Storyboard同士はStoryboard Referenceで結びつける。 セミモーダルビューの作成 検索して良く出てくるのはUIPresentationControllerを利用する方法。ただ今回はなるべくStoryboardで完結させたい。 そこで、以下のページを参考して作ることを考える。 ハンバーガーメニューを作成するには? - Swift Life ファイル作成 Menu.storyboard、MenuViewController、 Menu.storyboard、Dest1.storyboard、 Dest2.storyboardの5つをあらかじめ作成しておく。 Menu.storyboard classにはMenuViewControllerを指定する。部品配置は以下のようにする。 全体を包むViewを親View、その中に作ったViewを子Viewと呼ぶことにすると、 Constraintは適当に設定する。子Viewが画面下に配置されるようにする。 StackViewにはFill Equallyの設定を行っておく。 親Viewの背景色を、黒の半透明に設定する。設定手順は以下の通り。 BackgroundをBlackに設定 BackgroundをCustomに設定し直すと、カラーピッカーが現れる。そこで透明度を50%に設定する。 また、“Initial View Controller"にチェックをつける。 親Viewのtagを1に設定しておく。これはタッチイベントを捕捉する際に必要になる。 Dest1.storyboard、Dest2.storyboard Dest1.storyboardの部品配置は以下のようにする。 “Is initial View Controller"にチェックをつける。 Dest2.storyboardの部品配置は以下のようにする。 “Is initial View Controller"にチェックをつける。 Main.storyboard 部品配置は以下のようにする。 OpenButtonからStoryboard ReferenceへのSegueのActionは"Present Modally"を選択。Segueの設定は以下のようにする。 Storyboard Referenceにて、“Storyboard"をMenuに、“Referenced ID"を未記入にする。 “Referenced ID"が未記入の場合、Storyboard上のInitial View Controllerへの参照にしてくれる。もしInitial View ControllerでないViewControllerに遷移したいなら、ここに記入する。ただし、遷移先のView ControllerにてIdentifierを設定しておくことを忘れずに。 MenuViewController.swift Menu.storyboardの小ViewのOutletを作成する。名前はmenuViewとする。 その上で以下の文を追記する。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class MenuViewController: UIViewController { ... override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let menuPosY = menuView.layer.position.y menuView.layer.position.y += menuView.layer.frame.height UIView.animate( withDuration: 0.5, delay: 0, options: .curveEaseOut, animations: { self.menuView.layer.position.y = menuPosY }, completion: nil) } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { for touch in touches { if touch.view?.tag == 1 { UIView.animate( withDuration: 0.2, delay: 0, options: .curveEaseOut, animations: { self.menuView.layer.position.y += self.menuView.layer.frame.height }) { bool in self.dismiss(animated: bool, completion: nil) } } } } } dismissメソッドを使うと自身のビューを閉じることができる。 ...

2019-12-14 · (updated 2019-12-15) · 2 min · 399 words

Socket通信勉強(2) - Pythonでの書き方/HTTPサーバーもどき作成

PythonでのSocket通信 やってることはCでやったときと同じである。サーバーとクライアントの通信手順は同じだし、関数名も同じである。しかしCで書いた場合に比べてシンプルに書ける。エラーは例外として投げられるため、自分で書く必要がない。またsockaddr_inなどの構造体が登場することはなく、Pythonでのbind関数とconnect関数の引数に直接アドレス・ポートを指定する。 server.py 前回と同じく、以下の手順で通信を行う。 listen(待ち受け)用のソケット作成 - socket 「どこからの接続を待つのか」「どのポートにて待ち受けするのか」を決める - bind関数の引数 ソケットにその情報を紐つける - bind 実際に待ち受けする - listen 接続要求が来たら受け入れる - accept 4によって通信用のソケットが得られるので、それを用いてデータのやりとりをする- send/recv 1 2 3 4 5 6 7 8 9 10 import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("", 8000)) s.listen(5) (sock, addr) = s.accept() print("Connected by" + str(addr)) sock.send("Hello, World".encode('utf-8')) sock.close() s.close() 上のコードを見れば各関数がどんな形で引数をとって、どんな値を返すのかがわかると思う。いくつか補足しておく。 bind (受け入れアドレス, ポート)というタプルを引数にとる。受け入れアドレスを空文字列にしておけば、どんなアドレスからの接続も受け入れる。つまりCでやったINADDR_ANYと同じ。 1 s.bind(("", 8000)) encode Pythonのstring型をそのまま送ることはできないので、byte型に変換する。これはstring.encodeで行える。 1 sock.send("Hello, World".encode('utf-8')) client.py サーバーとの通信用のソケット作成 - socket サーバが待ち受けている宛先を設定 - connectの引数 2で設定した宛先に対して接続する - connect 1で作ったソケットを用いてデータのやりとりをする。 - send/recv 1 2 3 4 5 6 7 import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(("localhost", 8000)) data = sock.recv(64) print(data) sock.close() これも2点補足する。 ...

2019-12-08 · (updated 2021-03-03) · 3 min · 536 words

Androidアプリ開発勉強(4) - LiveData/TableLayout/電卓アプリ作成

どんなアプリを作るか 電卓を作る。 市販の電卓とは違い、括弧が使えるようにする。なので、軽い構文解析を書くことになる。しかし今回の記事ではデータの扱い方やViewの組み方に焦点を当てているため、電卓の計算処理についてはかなり軽めに説明する。 プロジェクト作成 プロジェクト名は"Calculator"とする。 DataBindingは有効にする Fragmentに分ける 今回は1画面のアプリなのでわざわざFragmentに分ける必要もないのだが、「もしかしたら他にもFragmentを追加するかもしれない」というケースを想定して、一応分けてみる。 CalcFragmentを作成する。xmlファイルはfragment_calc.xmlとする。 activity_main.xmlの内容を以下のようにする。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <fragment android:id="@+id/calcFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.example.calculator.CalcFragment" /> </merge> merge Android Kotlin Fundamentals 06.2で存在を初めて知った。こうするとactivity_main.xmlでLayoutを作って、fragmentの中でもまたLayoutを作るといった冗長性を排除できる。 CalcFragmentの設定 string.xml fragment_calc.xmlに設定するための文字列定数を定義する。string.xmlを以下のようにする。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <resources> <string name="app_name">Calculator</string> <string name="calc_0">0</string> <string name="calc_1">1</string> <string name="calc_2">2</string> <string name="calc_3">3</string> <string name="calc_4">4</string> <string name="calc_5">5</string> <string name="calc_6">6</string> <string name="calc_7">7</string> <string name="calc_8">8</string> <string name="calc_9">9</string> <string name="calc_plus">+</string> <string name="calc_minus">-</string> <string name="calc_mul">*</string> <string name="calc_div">/</string> <string name="calc_ac">AC</string> <string name="calc_eq">=</string> <string name="calc_lp">(</string> <string name="calc_rp">)</string> </resources> fmagment_calc.xml fragment_calc.xmlを以下のようにする。初めて触れた要素・属性があるので、これらは後で補足する。 ...

2019-11-28 · (updated 2019-12-08) · 7 min · 1365 words

gnuplotの使い方メモ

備忘録に。 インストール Macの場合はbrewでインストールできる。 1 $ brew install gnuplot gnuplotコマンドで起動。 ファイルをプロットする 例えばdata.txtが以下のようになっているとする。 1 2 3 4 5 #x #y1 #y2 0 1 2 1 2 1 2 0 2 3 1 1 これを描画する。 using X:Yで、X番目の列を横軸、Y番目の列を縦軸にする。 w lpとは"with linespoints"の略。つまり線と点を描画する。w lだと"with line"、w lp lt 3 lw 2だと"with linepoints linetype 3 linewidth 2"という意味。いろいろある。 1 2 3 $ set xlabel "X axis" $ set ylabel "Y axis" $ plot "data.txt" using 1:2 w pl 軸の範囲指定 例えばx軸を[0,3000]の範囲に制限して描画したいなら、次のコマンドを打つ。 ...

2019-11-26 · (updated 2019-11-27) · 1 min · 207 words

Socket通信の勉強(1) - ディスクリプタ/TCPによる通信

Socket通信を勉強する。 前提 プログラムはMac(Mojave)で動かす。 ネットワークに関する知識はほんの少しある。 使うプログラミング言語はC++だが、ここではbetter Cの意味でしか用いない。 (寄り道) ファイル入出力 Socket通信を学んでいると、ファイルディスクリプタが出てきたので、まずはそこから勉強する。 関数定義についてはJM Projectから引用したものを用いる。これはLinuxマニュアルと同じらしいので、恐らくmanコマンドで出力されるものと同じである(ただし英語であるが)。 ファイルディスクリプタとは ファイルディスクリプタとは、ファイルと結びつけられた単なる整数値である。データの読み書きを行う場合は、この整数値を指定してアクセスする。例えばファイルtest.txtのファイルディスクリプタが4だった場合、読み書きをする関数read/writeには引数4を指定する。 個人的には、ファイルとプロセスのやりとりはあるケーブルを介して行なっているイメージがある。例えば番号4の端子にはすでにtest.txtが繋がっているとしよう。このとき、プロセスがtext.txtにアクセスしたいなら、番号4の端子にアクセスすれば良い。 ファイルの読み込み ファイルディスクリプタを用いてファイルを読み込む例を以下に示す。以下は、test.txtを読み込んで、そのファイルディスクリプタとファイルの内容を出力するプログラムである。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <stdio.h> #include <unistd.h> #include <fcntl.h> int main() { int fd = open("test.txt", O_RDONLY); char buf[64]; read(fd, buf, sizeof(buf)); printf("fd: %d\n", fd); printf("%s\n", buf); close(fd); return 0; } test.txtの内容は以下のようにする。 1 Hello, World 実行すると、以下のように出力される。fdの値は実行環境によって異なる。 1 2 fd: 3 Hello, World 以下説明するopen/read/closeは関数ではなく、全てシステムコールである。 openでファイルを開く 開きたいファイルのパスと、読み書きの方法を引数に指定する。成功するとファイルディスクリプタを返す。 ...

2019-11-24 · (updated 2021-03-03) · 5 min · 1015 words

Androidアプリ開発勉強(3) - データの受け渡し

次の2つの事項について扱う。 DataBindingにおけるデータの受け渡し Navigationを用いた、異なるFragment間におけるデータの受け渡し さらに具体的に言うと、次の機能を持つアプリを作る MainFragmentにはEditTextが1つある。 EditTextが入力されると、TextViewが"String: [EditTextの文字列]“に変わる。 Buttonが押されると、ReverseFragmentに遷移する ReverseFragmentは、MainFragmentのテキストフィールドの文字列を受け取って、それを逆順にした文字列を表示する。 Android Kotlin Fundamentals Courseでの05辺りを勉強した記録なので、詳しいことはそちらに載っている。 プロジェクト初期設定 “Empty Project"として作成して、名前を"DataTest"とする。 build.gradle(module:App)について、dataBindingの設定をしておく。 次のようにMainFragmentとReverseFragmentを作成しておく。作成時、“Create layout XML?“にのみチェックをつけておく。 MainFragmentの設定 fragment_main.xmlを次のようにする。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=".main.MainFragment"> <data> <variable name="myMsg" type="com.example.datatest.main.MainFragment.MyMsg" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_gravity="center_vertical" > <EditText android:id="@+id/edit_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:hint="@string/hello_blank_fragment" android:layout_gravity="center_horizontal" android:textAlignment="center" /> <TextView android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@={myMsg.text}" android:layout_gravity="center_horizontal" android:textAlignment="center" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="@string/to_reverse_fragment" android:textAllCaps="false" /> </LinearLayout> </layout> 重要なのは以下の部分で、これはMainFragment.ktで定義されたMyMsgというクラスのインスタンスをこのファイルではmyMsgとして扱う、という意味。 ...

2019-11-22 · (updated 2019-12-08) · 5 min · 861 words