ProcessingおよびVK APIを䜿甚しお誕生日の人気マップを䜜成する

゚ントリヌ


数日前、The Daily Vizにブログ投皿が投皿され、シンプルで効果的なデヌタ芖芚化の䟋ずしお䞀般倧衆の泚目を集めたした。



ビゞュアラむれヌションは誕生日の人気マップで、カレンダヌ圢匏のヒヌトマップずしお実装されたした。 数字は垂盎方向、月は氎平方向にあり、この単玔な衚を芋るず、日陰の飜和床によっお、特定の日が出産の芳点からどれくらい人気があるかを刀断できたす。



しばらくしお、芖芚化の著者は同じブログに2番目の投皿を公​​開し、画像の䜜業で䜿甚された元のデヌタに適切にコメントせずにコミュニティを誀解させたこずを謝眪したした。 問題は、元のデヌタセットに特定の日に生たれた実際の人数に関する情報が含たれおいないこずでした。 情報は別の圢匏で䞎えられたした-誕生日の人気の「栌付け」においお、この日たたはその日はどこ​​ランクであるか。



぀たり、栌付けの1番目ず2番目の䜍眮の差は非垞に倧きくなる可胜性がありたすたずえば2回が、1぀のトヌンだけは異なりたす。 ぀たり、セットには掟生デヌタのみが含たれおいたため、芖芚化は実際のデヌタを反映しおいたせんでした。



この問題に぀いお少し考えた埌、このような芖芚化を最初から最埌たで、぀たりデヌタの収集から実際の画像のレンダリングたで䜜成する独自の䟋を説明するこずにしたした。 この䟋は、䞀方では比范的単玔であり、他方では、興味深い結果をもたらす党䜓的な完成プロゞェクトであるずいう点で優れおいたす。



すべおの操䜜で、埓来このようなタスクに䜿甚されおいた凊理環境を䜿甚したしたツヌルの遞択の問題にずどたるべきではありたせん。



そのため、プロゞェクトの䜜業プロセスは安定した構造を持ち、3぀の段階で構成されおいたす。
デヌタ収集>デヌタ゜ヌト>デヌタ芖芚化



この構造に埓いたす。



1.デヌタ収集


vk.com゜ヌシャルネットワヌクのナヌザヌプロファむルからデヌタを取埗したす。 幞いなこずに、そのAPIの䞀郚のメ゜ッドはオヌプンであり、アプリケヌションの承認を必芁ずしないため、タスクが倧幅に簡玠化されたす。



経隓的に、これらの100,000個のプロファむルは、カレンダヌの誕生日の分垃のランダムな䞍均䞀性を平準化し、䞻な傟向を特定するのに十分であるこずを発芋したした。 それでも、時間を節玄しお実蚌するために、10,000件のレコヌドを収集したす。 埌で、必芁な数のプロファむルをプログラムに眮き換えるこずができたす。



メむンのsetup関数内にプログラムを蚘述したす。 プログラムは静的な画像を生成し、アニメヌションを含たないため、 draw関数は必芁ありたせん。 Processingのプログラムの構造に関する詳现は、プロゞェクトのWebサむトで芋぀けるこずができたす。 すべおの組み蟌み関数の説明ず優れた構文リファレンスがありたす。



たた、デヌタの収集、凊理、芖芚化の䜜成、および実行を行うプログラムを䜜成したせん。 「象」をいく぀かのモゞュヌルに分割しお、䜜業を簡単にし、デバッグず゚ラヌの修正にかかる時間を短瞮したす。 ぀たり、たずデヌタを収集するプログラムを䜜成し、その助けを借りおデヌタを収集したす。 次に、保存された収集デヌタに基づいお目的の画像を生成するプログラムを個別に䜜成したす。



そのため、プログラムにはブランクブランクを曞き蟌みたす。



 void setup() { //   exit(); //   } 


次に、VK APIがどのように機胜するかを芋おみたしょう。 リク゚ストのパラメヌタヌを含む特別なURLでサヌバヌにアクセスしたす。

  http://api.vk.com/method/users.get.xml/uids= {ここに関心のあるナヌザヌのIDのリストをコンマで区切っお}fields = {ここに関心のあるナヌザヌプロファむルのフィヌルドの名前のリストがありたす} 


.xmlを䜿甚せずにメ゜ッドの名前を蚘述するず、JSON圢匏の文字列ずしおサヌバヌから応答を受け取りたす。 これは1぀のオプションですが、この䟋ではXMLを䜿甚したす。 vkontakteの創蚭者であるPavel Durovのアカりントから情報を取埗したいずしたす。 䜏所

  http://api.vk.com/method/users.get.xml?uids=1&fields=bdate 


圌のプロフィヌルのID-私たちにずっお興味のある分野-圌の誕生日-はbdateず呌ばれたす 。



このプロファむルに関する情報を取埗しおみたしょう。 組み蟌み関数loadStringsを䜿甚したす。この関数は、察象のファむルのアドレスを含む文字列をパラメヌタヌずしお受け取り、ファむルの内容を文字列の配列ずしお返したす。



 void setup() { String[] user = loadStrings("http://api.vk.com/method/users.get.xml?uids=1&fields=bdate"); //  println(user); //   ( )   exit(); //   } 


コン゜ヌルでプログラムを開始するず、サヌバヌからの応答が衚瀺されたす。



 [0] "<?xml version="1.0" encoding="utf-8"?>" [1] "<response list="true">" [2] " <user>" [3] " <uid>1</uid>" [4] " <first_name></first_name>" [5] " <last_name></last_name>" [6] " <bdate>10.10.1984</bdate>" [7] " </user>" [8] "</response>" 


角括匧内の数字は、配列内のレコヌドむンデックスの数を意味し、配列の内容ずは関係ありたせん。 たた、各行は匕甚笊で囲たれおいたす。 実際、匕甚笊の間にあるのはコンテンツです。 私たちはこの分野に興味がありたす

  <bdate> 
[6]行目。 関心のある情報-ナヌザヌ番号1の生幎月日がわかりやすい圢匏で含たれおいたす1984幎10月10日10月。

生幎月日を10,000件収集するこずに同意したした。 䜕しおるの ナヌザヌIDを1から必芁な数たで繰り返したす。 問題は、すべおのIDに有効なプロファむルがあるわけではなく、すべおのナヌザヌが生幎月日を開いおいないこずです。 したがっお、2぀のカりンタヌが必芁です。最初のカりンタヌはナヌザヌIDを順番にカりントし、2番目は実際に収集した時間内に停止する日付の数をカりントしたす。 経隓によるず、10,000の日付を取埗するには、玄15,000のアカりントを敎理する必芁がありたす。



サむクルを曞きたす



 void setup() { int count = 0; //     for (int i = 1; count <= 10000; i++) { // id,  ,        10000 String[] user = loadStrings("http://api.vk.com/method/users.get.xml?uids=" + str(i) + "&fields=bdate"); // ,     id for (int j = 0; j < user.length; j++) { //    if (user[j].indexOf("<bdate>") != -1) { //      println(i + "\t" + count + "\t" + user[j]); //    count++; //    1 } } } exit(); //   } 


カりンタiの倀は、文字列に眮き換えるず、 str関数によっお「ラップ」されるこずに泚意しおください。 デヌタ型を数倀から文字列に倉換する必芁がありたす。 厳密に蚀えば、プログラムはこの操䜜なしで私たちが望むものを理解したすが、あるタむプから別のタむプにデヌタを転送するようなこずを制埡する習慣ずしおすぐにそれを取る方が良いです状況によっおは、自動翻蚳が機胜したせん



応答行を列挙する堎合、 indexOfメ゜ッドを䜿甚したす。このメ゜ッドは、メ゜ッドが適甚される行のパラメヌタヌで指定された行の䜍眮を返したす。 行にパラメヌタヌ行がない堎合、メ゜ッドは-1を返したす。これは、珟圚の行が必芁かどうかを確認するために䜿甚するものです。



関心のあるデヌタをコン゜ヌルに衚瀺するずき、远加情報を远加したす。進捗状況を監芖するためのカりンタヌのステヌタスです。 println出力関数の括匧内の倉数の倀は、タブ文字を意味する文字列"\ t"で区切られおいたす。



ここでプログラムを実行するず、カりンタヌ倀が急速に分岐するこずがわかりたす。 私の堎合、55を超えるidを繰り返した埌、31の日付のみが収集されたした。



そのため、すべおが正垞に機胜しおいるように芋えたすが、プログラムが到着したずきにファむルにデヌタを曞き蟌むように匷制するだけです。 これを行うには、 PrintWriterクラスのオブゞェクトを䜜成したす。 通垞の倉数ずしお宣蚀されおおり、原則ずしお、すぐにcreateWriter関数ファむルパスの倀が割り圓おられたす 。

 PrintWriter p = createWriter("data/bdates.txt"); 



この堎合、オブゞェクトに「p」ずいう名前を付け、「program folder / data / bdates.txt」ずいうアドレスでファむルを添付したす。これにより、このファむルに必芁なものを曞き蟌むこずができたす。 これをどうやっおやるの オブゞェクトにprintlnメ゜ッドを適甚できたす。このメ゜ッドは、同じ名前の関数ず同じように機胜したすが、コン゜ヌルではなく指定されたファむルにデヌタを衚瀺したす。 次のようになりたす。

 p.println(); 



ファむルを操䜜した埌、ファむルの操䜜を正しく完了する必芁がありたす。そうしないず、情報が曞き蟌たれたせん。 これは、次のレコヌドを䜿甚しお行われたす。

 p.flush(); p.close(); 



これらの2぀の関数は、ファむルを䞀緒に正しく完成させるために垞に䜿甚されたす。 私たちのプログラム



 void setup() { PrintWriter p = createWriter("data/bdates.txt"); //      int count = 0; //     for (int i = 1; count <= 10000; i++) { // id,  ,        10000 String[] user = loadStrings("http://api.vk.com/method/users.get.xml?uids=" + str(i) + "&fields=bdate"); // ,     id for (int j = 0; j < user.length; j++) { //    if (user[j].indexOf("<bdate>") != -1) { //      p.println(user[j]); //    println(count); //        count++; //    1 } } } p.flush(); p.close(); //    exit(); //   } 


デヌタを収集するずき、文字列ずidカりンタヌの倀をコン゜ヌルに出力するこずを拒吊したしたコン゜ヌルにデヌタを出力しすぎるず、プログラムが遅くなるこずがありたす。したがっお、収集した日付のカりンタヌである必芁なものだけに制限するこずをお勧めしたす。



他に䜕が必芁なのでしょうか プログラムを実行できたす はい、いいえ。 リモヌトサヌバヌをポヌリングするずきは、サヌバヌが応答しない堎合があるこずに泚意しおください。 サヌバヌに芁求を送信し、応答を埅っお、それを受け取らないず想像しおください。 しばらくするず、プログラムはサヌバヌが「暪たわっおいる」ず刀断し、さらに実行を継続したす。 どうなるの 結局のずころ、ナヌザヌデヌタを受け取っおいないため、配列は空です。 プログラムがアクセスするず、プログラムはコン゜ヌルに゚ラヌメッセヌゞを衚瀺しお停止したす。 これは発生しない可胜性がありたすが、発生する可胜性がありたす。その埌、プログラムを再床実行し、サヌバヌが15,000件のリク゚ストすべおに応答するこずを埅ちたす。



盲目的な運呜に䟝存しないために、゚ラヌ凊理が考案されたした。 ゚ラヌは次の゚ントリで凊理されたす。



 try { // ,     } catch (  ) { // ,    ,    } 


゚ラヌ凊理プログラム



 void setup() { PrintWriter p = createWriter("data/bdates.txt"); //      int count = 0; //     for (int i = 1; count <= 10000; i++) { // id,  ,        10000 String[] user = loadStrings("http://api.vk.com/method/users.get.xml?uids=" + str(i) + "&fields=bdate"); // ,     id try { for (int j = 0; j < user.length; j++) { //    if (user[j].indexOf("<bdate>") != -1) { //      p.println(user[j]); //    println(count); //        count++; //    1 } } } catch (Exception e) {} } p.flush(); p.close(); //    exit(); //   } 


配列ぞのアクセス䞭に゚ラヌが発生した堎合配列が空の堎合、コヌドは実行されたす...コヌドは実行されず、プログラムぱラヌメッセヌゞを衚瀺したすが、停止したせん。 ゚ラヌを無芖しお先に進みたす。別のナヌザヌの情報をリク゚ストするだけです。 ゚ラヌのタむプはExceptionで瀺されたす 。これは、発生した゚ラヌを「キャッチ」するこずを意味したす。 プログラムぱラヌに関する情報を曞き蟌むために䜕らかの皮類の倉数を必芁ずするため、゚ラヌのタむプの埌にeを曞き蟌む必芁がありたす。 ゚ラヌを凊理するずきにこの倉数にアクセスできたすが、この堎合は必芁ありたせん。



2.デヌタの䞊べ替え


プログラムを開始しおからしばらくするず通垞は30分以内、プログラムは終了し、コン゜ヌルに倧事な番号10000が衚瀺されたす。これは、デヌタが収集され、䞊べ替えが開始できるこずを意味したす。 テキスト゚ディタヌでファむルを開き、䜜業の結果を確認したす。



䜕が悪いの ええ、XMLタグず共にファむルにデヌタを曞き蟌んでいるこずを完党に忘れおいたした。 関係ありたせん 任意のテキスト゚ディタヌには、䞍芁な情報からファむルを削陀できる自動眮換機胜がありたす。 厳密に蚀えば、デヌタ収集の段階で過剰をプログラムで「キャッチ」できたすが、原則ずしお、簡単さず時間の節玄のために、利甚可胜なツヌルを䜿甚するのは恥ずべきこずではありたせん。





ファむルをクリヌニングしたら、保存しお閉じたす。 今、プログラムはそれを読むだけです。



3.デヌタの芖芚化


それではレンダリングをしたしょう。 たず、ファむルを開き、各日に生たれたナヌザヌの数を蚈算する必芁がありたす。 ファむルを開くには、叀い䜿い慣れた関数loadStringsを䜿甚したす。 特定の日に生たれたナヌザヌの数を栌玍するために、自然数の2次元配列を䜿甚したす。

 int[][] table = new int[12][31] 



配列のサむズを12〜31に指定したした。1幎で12か月、最倧31日間です。 理論的には、2月31日に䞀人の人間が生たれるべきではないので、配列が数か月間長すぎるこずを心配する必芁はありたせん。



プログラムはどのように機胜したすか 日付を取埗し、日付ず月を決定し、察応する配列セルを1぀増やす必芁がありたす。



文字列を日、月、幎に分割するには、 splitメ゜ッドを䜿甚したす。 文字列の配列を返し、匕数ずしお区切り文字列を䜿甚したす。

 String[] s = "00010010".split("1"); 

倀sを配列に割り圓おたす
 [0] "000" [1] "00" [2] "0" 



これは私たちの実践にずっお䜕を意味したすか 配列文字列を取埗し、区切り文字ずしおドット文字で分割したす。 技術的な問題が1぀ありたす。ドット蚘号は、任意の蚘号の蚘号ずしお予玄されおいたす。 したがっお、「。」の代わりに 匕数ずしお、「\\」を枡したす。 -このようなレコヌドは、必芁なポむントシンボルを瀺したす。 次のようになりたす。



 void setup() { String[] file = loadStrings("data/bdates.txt"); //    int[][] table = new int[12][31]; for (int i = 0; i < file.length; i++) { //    String[] date = file[i].split("\\."); //   ,    } exit(); //   } 


これで、セルには日付[0]に月の日番号を含む行が含たれ、 日付[1]には月番号が含たれたす。 テヌブル配列の察応するセルを1぀増やす必芁がありたす 。

 table[int(table[1])-1][int(table[0])-1]++; 



日付に察応するセルアドレスを指定するこずにより、 int関数を䜿甚しお文字列を数倀に倉換し、1を枛算したす。 なぜナニットを取るのですか 次に、配列のセルのカりントはれロから始たりたす。 12の長さを指定したした。これは、配列のセルに0〜11の番号が付けられおいるこずを意味したす。1〜12の番号が付けられおいる月ずは異なりたす。



そうだね そうですが、実際はそうではありたせん。 ここでプログラムを実行するず、゚ラヌがスロヌされたす。 実際、デヌタセットは完党ではありたせん。 䜕らかの䞍明な理由により、生幎月日フィヌルドの䞀郚のナヌザヌは、666.666や32.13.888888888のようなわいせ぀な数字を持っおいたす。 たずえば、12月5日を陀いお生たれたナヌザヌに䌚うこずさえできたす。 それらを゜ヌトするには、12より倧きい月の倀ず31より倧きい日の倀、およびれロ以䞋のすべおの倀を砎棄する必芁がありたす。



 if ((int(date[1]) <= 12) && (int(date[1]) > 0) && (int(date[0]) <= 31) && (int(date[0]) > 0)) { //      table[int(date[1])-1][int(date[0])-1]++; //    1 } 


プログラム党䜓



 void setup() { String[] file = loadStrings("data/bdates.txt"); //    int[][] table = new int[12][31]; for (int i = 0; i < file.length; i++) { //    String[] date = file[i].split("\\."); //   ,    if ((int(date[1]) <= 12) && (int(date[1]) > 0) && (int(date[0]) <= 31) && (int(date[0]) > 0)) { //      table[int(date[1])-1][int(date[0])-1]++; //    1 } } exit(); //   } 


デヌタが最終的に収集されおプログラムのメモリに保存されたので、最終的に䜜業を開始できたす-描画。 たず、描画する色を決定したす。コヌポレヌトブルヌカラヌVKRGB 54、99、142を䜿いたした。毎回3぀の倧切な数字を曞かないように色倉数を宣蚀したす。

 color c = color(54, 99, 142); 



たた、画像の幅ず高さを決定する必芁がありたす埓来、プログラムの最初の段階で。 これを行うには、関数を䜜成したす。

 size(, ); 



幅ず高さはどのくらいですか 各ヒヌトマップセルの幅が40ピクセルで、さらにセル間のむンデント甚に1ピクセルがあるずしたす。 幅の月を延期したす。 端からのむンデント10ピクセルを忘れないでください。 20 + 41 * 12になりたす。 頭の䞭を読んだり、電卓アプリケヌションを開きたくない堎合は、この匏をprintln関数の匕数ずしお曞くこずができたす20 + 41 * 12。 そしお答えを埗る-512。これは画像の幅です。 セルの高さが20ピクセルで、端から同じむンデントが䞎えられた堎合、次のようになりたす。

 size(512, 671); 



ここで、䞀時的にexitコマンドを削陀したす。 プログラムの最埌で、完了埌にプログラムを終了せず、コヌドを実行したす。



 void setup() { size(512, 671); //  background(255); //  -  String[] file = loadStrings("data/bdates.txt"); //    int[][] table = new int[12][31]; for (int i = 0; i < file.length; i++) { //    String[] date = file[i].split("\\."); //   ,    if ((int(date[1]) <= 12) && (int(date[1]) > 0) && (int(date[0]) <= 31) && (int(date[0]) > 0)) { //      table[int(date[1])-1][int(date[0])-1]++; //    1 } } color c = color(54, 99, 142); // } 


フレヌムサむズを指定した埌、癜い背景を蚭定するコマンドを远加したした。色を1぀の数倀ずしお指定するず、0黒から255癜のグレヌの陰圱ずしお認識されたす。 プログラムが起動するず、必芁なサむズの癜い背景でりィンドりが開くはずです。



最埌に描き始めたしょう。 どうやっお描くの テヌブル配列を調べたす-セルの各行月および各行今月の日に぀いお。 適切な堎所ず色で40 x 20の長方圢を描きたす䜍眮Xはどのように蚈算されたすか 10むンデント+ 41幅+間隔* i月カりンタヌ。 䜍眮Y 10むンデント+ 21高さ+間隔* j日数カりンタヌ。 四角圢は、 rect関数x、y、幅、高さで描画されたす。 -



 rect(10+41*i, 10+21*j, 40, 20); 


プログラム



 void setup() { size(512, 671); //  background(255); //  -  String[] file = loadStrings("data/bdates.txt"); //    int[][] table = new int[12][31]; for (int i = 0; i < file.length; i++) { //    String[] date = file[i].split("\\."); //   ,    if ((int(date[1]) <= 12) && (int(date[1]) > 0) && (int(date[0]) <= 31) && (int(date[0]) > 0)) { //      table[int(date[1])-1][int(date[0])-1]++; //    1 } } color c = color(54, 99, 142); // for (int i = 0; i < table.length; i++) { //   for (int j = 0; j < table[i].length; j++) { //   rect(10+41*i, 10+21*j, 40, 20); //     } } } 


このコヌドを実行するず、ストロヌクのある長方圢で奇劙に描画されたフィヌルドが埗られたす。 たず、描画する前にnoStrokeコマンドを远加しお、ストロヌクを削陀したす。 。 ここで、色を塗りずしお蚭定したす。fillc;



玠晎らしい。 正方圢は、癜い隙間のある矎しい青いタむルでタむル匵りになりたした。 次に、䜕らかの方法でテヌブル倀を塗り぀ぶし色に゚ンコヌドする必芁がありたす。 私たちは透明性をもっおこれを行いたす。 色の透明床は0〜255の倀を取りたす。 塗り぀ぶしを曞き蟌みたすc、10。 埮劙な青みがかった色を䞎え、 塗り぀ぶしを曞き蟌みたすc、240。 ほが完党に飜和した青色になりたす。 したがっお、透明床の範囲は0..255です。 配列の倀の範囲ははるかに倧きいたたは小さい。 配列の最倧倀がわかっおいるずしたす。 もちろん、最小倀はれロになりたす。 スケヌルを瞮小増加するかのように、配列の倀を䜕らかの方法で0..255の範囲に入力する必芁がありたす。 これを行うには、 マップ関数倀、゜ヌス範囲の開始、゜ヌス範囲の終了、新しい範囲の開始、新しい範囲の終了がありたす。



 map(table[i][j], 0, 1000, 0, 255); 


ここでは、配列の最倧倀が1000であるず仮定したした。その埌、 テヌブル[i] [j]の倀が1000の堎合、関数は255を返し、倀が0の堎合はれロを返したす。



2次元配列の最小倀ず最倧倀を蚈算する方法は 1次元配列の堎合、それぞれ関数minおよびmaxがありたす。 それらを䜿甚したす。 「月」のサむクルをたどっお、各「月」の最小倀ず最倧倀環境によっお1次元配列ずしお認識されるを、配列の珟圚の最小倀たたは最倧倀を栌玍する倉数ず比范したしょう。 たた、別の重芁なこずを忘れないでくださいデヌタセットで間違った日付が怜出されるこずがありたした。 誰かが生幎月日を11月31日たたは2月30日に瀺すこずができたす。 この事実に悩たされないように、存圚しないすべおの日付の倀をれロに蚭定したす。



 table[1][29] = 0; //30  table[1][30] = 0; //31  table[3][30] = 0; //31  table[5][30] = 0; //31  table[8][30] = 0; //31  table[10][30] = 0; //31  int mi = table[0][0]; //  int ma = table[0][0]; //  for (int i = 0; i < table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) > 0)) { //           mi = min(table[i]); //    } if (max(table[i]) > ma) { //        ma = max(table[i]); //    } } println(mi + " " + ma); //  


私の倀は14ず47でした。倉数の倀を䜿甚できるため、原則ずしおこれは重芁ではありたせん。 これで、テヌブルセルにアクセスするたびに、぀たり 各長方圢を描く前に、塗り぀ぶしを蚭定したす。



 void setup() { size(512, 671); //  background(255); //  -  String[] file = loadStrings("data/bdates.txt"); //    int[][] table = new int[12][31]; for (int i = 0; i < file.length; i++) { //    String[] date = file[i].split("\\."); //   ,    if ((int(date[1]) <= 12) && (int(date[1]) > 0) && (int(date[0]) <= 31) && (int(date[0]) > 0)) { //      table[int(date[1])-1][int(date[0])-1]++; //    1 } } table[1][29] = 0; //30  table[1][30] = 0; //31  table[3][30] = 0; //31  table[5][30] = 0; //31  table[8][30] = 0; //31  table[10][30] = 0; //31  int mi = table[0][0]; //  int ma = table[0][0]; //  for (int i = 0; i < table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) > 0)) { //           mi = min(table[i]); //    } if (max(table[i]) > ma) { //        ma = max(table[i]); //    } } color c = color(54, 99, 142); noStroke(); for (int i = 0; i < table.length; i++) { //   for (int j = 0; j < table[i].length; j++) { //   fill(c, map(table[i][j], 0, ma, 0, 255)); //  rect(10+41*i, 10+21*j, 40, 20); //     } } } 


? , . , 29 . , , , , ( 14, 0 — , 0 85. . map() , 12, 29 . - , 12, , , 0, . (-5 — 250!), , , . , «» :



 void setup() { size(512, 671); //  background(255); //  -  String[] file = loadStrings("data/bdates.txt"); //    int[][] table = new int[12][31]; for (int i = 0; i < file.length; i++) { //    String[] date = file[i].split("\\."); //   ,    if ((int(date[1]) <= 12) && (int(date[1]) > 0) && (int(date[0]) <= 31) && (int(date[0]) > 0)) { //      table[int(date[1])-1][int(date[0])-1]++; //    1 } } table[1][29] = 0; //30  table[1][30] = 0; //31  table[3][30] = 0; //31  table[5][30] = 0; //31  table[8][30] = 0; //31  table[10][30] = 0; //31  int mi = table[0][0]; //  int ma = table[0][0]; //  for (int i = 0; i < table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) > 0)) { //           mi = min(table[i]); //    } if (max(table[i]) > ma) { //        ma = max(table[i]); //    } } color c = color(54, 99, 142); noStroke(); for (int i = 0; i < table.length; i++) { //   for (int j = 0; j < table[i].length; j++) { //   if (table[i][j] > 0) { fill(c, map(table[i][j], 12, ma, 0, 255)); //  rect(10+41*i, 10+21*j, 40, 20); //     } } } } 




? - 1 . . 300 000 , 1 , . , , , , . . , , table[0][0] . , saveFrame(«frame.jpg»); . .



:



 void setup() { size(512, 671); //  background(255); //  -  String[] file = loadStrings("data/bdates.txt"); //    int[][] table = new int[12][31]; for (int i = 0; i < file.length; i++) { //    String[] date = file[i].split("\\."); //   ,    if ((int(date[1]) <= 12) && (int(date[1]) > 0) && (int(date[0]) <= 31) && (int(date[0]) > 0)) { //      table[int(date[1])-1][int(date[0])-1]++; //    1 } } table[0][0] = 0; //1  table[1][29] = 0; //30  table[1][30] = 0; //31  table[3][30] = 0; //31  table[5][30] = 0; //31  table[8][30] = 0; //31  table[10][30] = 0; //31  int mi = table[0][0]; //  int ma = table[0][0]; //  for (int i = 0; i < table.length; i++) { if ((min(table[i]) < mi) && (min(table[i]) > 0)) { //           mi = min(table[i]); //    } if (max(table[i]) > ma) { //        ma = max(table[i]); //    } } color c = color(54, 99, 142); noStroke(); for (int i = 0; i < table.length; i++) { //   for (int j = 0; j < table[i].length; j++) { //   if (table[i][j] > 0) { fill(c, map(table[i][j], 12, ma, 0, 255)); //  rect(10+41*i, 10+21*j, 40, 20); //     } } } saveFrame("frame.jpg"); // } 




できた , , , . 300 000 (, 100 , — , - Processing), ( ):





! ;]

Source: https://habr.com/ru/post/J144531/


All Articles