#!/ usr / bin / env Ġkotlin - script . sh Ċ @ file : Suppress (" Package Directory Mismatch ") Ċ package Ġscripts . histogram Ċ Ċ import Ġorg . ko hs uke . args 4 j . Option Ċ import Ġorg . ko hs uke . args 4 j . Cmd Line Parser Ċ import Ġorg . ko hs uke . args 4 j . Cmd Line Exception Ċ import Ġjava . io . BufferedReader Ċ import Ġjava . io . FileReader Ċ import Ġjava . io . InputStream Reader Ċ import Ġjava . math . BigDecimal Ċ import Ġjava . io . File Ċ import Ġorg . jfree . chart . J Free Chart Ċ import Ġorg . jfree . data . statistics . Histogram Dataset Ċ import Ġorg . jfree . data . statistics . Histogram Type Ċ import Ġorg . jfree . chart . Chart Factory Ċ import Ġorg . jfree . chart . plot . Plot Orientation Ċ import Ġorg . jfree . chart . Chart Utilities Ċ Ċ val Ġscript Ġ= ĠFile ( System . getProperty (" kotlin . script . file ") !! ) Ċ Ċ class ĠConfig Ġ{ ĊĠĠĠ Ġ@ Option ( name Ġ= Ġ"- output ", Ġrequired Ġ= Ġtrue , Ġmeta Var Ġ= Ġ"< output >", Ġusage Ġ= Ġ" Output Ġfile Ġfor Ġthe Ġgenerated Ġhistogram ") ĊĠĠĠ Ġval Ġoutput Ġ= Ġ"" ĊĊĠĠĠ Ġ@ Option ( name Ġ= Ġ"- input ", Ġmeta Var Ġ= Ġ"< input >", Ġusage Ġ= Ġ" Input Ġfile . ĠIf Ġnot Ġspecified Ġstdin Ġis Ġassumed . Ġ" ĊĠĠĠ Ġ+ Ġ" Input Ġis Ġexpected Ġto Ġbe Ġa Ġsequence Ġof Ġnumeric Ġvalues , Ġone Ġper Ġline .") ĊĠĠĠ Ġval Ġinput : ĠString ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Option ( name Ġ= Ġ"- title ", Ġmeta Var Ġ= Ġ"< title >", Ġusage Ġ= Ġ" Histogram Ġtitle ") ĊĠĠĠ Ġval Ġtitle : ĠString ? Ġ= Ġnull ĊĊĠĠĠ Ġ@ Option ( name Ġ= Ġ"- min ", Ġmeta Var Ġ= Ġ"< percentile >", Ġusage Ġ= Ġ" Min ium Ġpercent ile Ġto Ġinclude Ġin Ġthe Ġchart . ĠDefaults Ġto Ġ 5 ") ĊĠĠĠ Ġval Ġmin Percent ile Ġ= Ġ 5 ĊĊĠĠĠ Ġ@ Option ( name Ġ= Ġ"- max ", Ġmeta Var Ġ= Ġ"< percentile >", Ġusage Ġ= Ġ" Maximum Ġpercent ile Ġto Ġinclude Ġin Ġthe Ġchart . ĠDefaults Ġto Ġ 9 5 ") ĊĠĠĠ Ġval Ġmax Percent ile Ġ= Ġ 9 5 ĊĊĠĠĠ Ġ@ Option ( name Ġ= Ġ"- width ", Ġmeta Var Ġ= Ġ"< width >", Ġusage Ġ= Ġ" Width Ġof Ġthe Ġgenerated Ġhistogram . ĠDefaults Ġto Ġ 6 0 0 px ") ĊĠĠĠ Ġval Ġwidth Ġ= Ġ 6 0 0 ĊĊĠĠĠ Ġ@ Option ( name Ġ= Ġ"- height ", Ġmeta Var Ġ= Ġ"< height >", Ġusage Ġ= Ġ" Height Ġof Ġthe Ġgenerated Ġhistogram . ĠDefaults Ġto Ġ 4 0 0 px ") ĊĠĠĠ Ġval Ġheight Ġ= Ġ 4 0 0 ĊĊĠĠĠ Ġ@ Option ( name Ġ= Ġ"- bins ", Ġmeta Var Ġ= Ġ"< bins >", Ġusage Ġ= Ġ" Number Ġof Ġbins Ġin Ġthe Ġhistogram . ĠDefaults Ġto Ġ 5 0 .") ĊĠĠĠ Ġval Ġbins Ġ= Ġ 5 0 ĊĊĠĠĠ Ġ@ Option ( name Ġ= Ġ"- label ", Ġmeta Var Ġ= Ġ"< label >", Ġrequired Ġ= Ġtrue , Ġusage Ġ= Ġ" Label Ġfor Ġthe Ġdata .") ĊĠĠĠ Ġval Ġlabel Ġ= Ġ"" ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" config ( input =$ input , Ġoutput =$ output , Ġtitle =$ title , Ġmin Percent ile =$ min Percent ile , Ġ" Ġ+ ĊĠĠĠĠĠĠĠ Ġ" max Percent ile =$ max Percent ile , Ġwidth =$ width , Ġheight =$ height , Ġbins =$ bins , Ġlabel =$ label )" ĊĠĠĠ Ġ} Ċ } Ċ val Ġconfig Ġ= ĠConfig () Ċ Ċ fun Ġgenerate Histogram () Ġ{ ĊĠĠĠ Ġvalidate Config () ĊĠĠĠ Ġval Ġdata Ġ= Ġprepare Data () ĊĠĠĠ Ġval Ġchart Ġ= Ġgenerate Chart ( data ) ĊĠĠĠ ĠChart Utilities . save Chart As PNG ( File ( config . output ), Ġchart , Ġconfig . width , Ġconfig . height ) Ċ } Ċ Ċ fun Ġgenerate Chart ( data : ĠDouble Array ): ĠJ Free Chart Ġ{ ĊĠĠĠ Ġval Ġdataset Ġ= ĠHistogram Dataset () ĊĠĠĠ Ġdataset . type Ġ= ĠHistogram Type . REL ATIVE _ FREQ UENCY ĊĠĠĠ Ġdataset . add Series ( config . label , Ġdata , Ġconfig . bins ) ĊĊĠĠĠ Ġval Ġchart Ġ= ĠChart Factory . create Histogram ( config . title , Ġnull , Ġnull , Ġdataset , ĠPlot Orientation . VERTICAL , Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfalse , Ġfalse ) !! ĊĊĠĠĠ Ġchart . xy Plot ?. foreground Alpha Ġ= Ġ 0 . 7 5 f ĊĠĠĠ Ġreturn Ġchart Ċ } Ċ Ċ fun Ġprepare Data (): ĠDouble Array Ġ{ ĊĠĠĠ Ġval Ġreader Ġ= ĠBufferedReader ( if Ġ( config . input Ġ== Ġnull ) ĠInputStreamReader ( System .` in `) Ġelse ĠFileReader ( config . input )) ĊĠĠĠ Ġval Ġsorted Ġ= Ġreader . use Lines Ġ{ Ġit . map Ġ{ ĠBigDecimal ( it ). toDouble () Ġ}. toList (). sorted () Ġ} ĊĠĠĠ Ġval Ġstart Ġ= Ġsorted . size Ġ* Ġconfig . min Percent ile Ġ/ Ġ 1 0 0 ĊĠĠĠ Ġval Ġend Ġ= Ġsorted . size Ġ* Ġconfig . max Percent ile Ġ/ Ġ 1 0 0 ĊĠĠĠ Ġif Ġ( end Ġ<= Ġstart ) Ġreturn ĠDouble Array ( 0 ) Ġ// ĠData Ġset Ġmust Ġbe Ġtiny ĊĊĠĠĠ Ġ// ĠSome Ġmanual Ġfun Ġas ĠJ Free Chart Ġseems Ġto Ġrequire Ġan Ġarray Ġinstead Ġof Ġa ĠList ĊĠĠĠ Ġval Ġdata Ġ= ĠDouble Array ( end Ġ- Ġstart ) ĊĠĠĠ Ġvar Ġto Ġ= Ġ 0 ĊĠĠĠ Ġfor Ġ( from Ġin Ġstart .. end Ġ- Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdata [ to ++] Ġ= Ġsorted [ from ] ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġdata Ċ } Ċ Ċ fun Ġvalidate Config () Ġ{ ĊĠĠĠ Ġrequire ( config . input Ġ== Ġnull Ġ|| ĠFile ( config . input ). exists () Ġ&& ĠFile ( config . input ). can Read ()) Ġ{ Ġ" Input Ġfile Ġ'${ config . input } Ġdoes Ġnot Ġexist Ġor Ġcan 't Ġbe Ġread " Ġ} ĊĊĠĠĠ Ġrequire ( config . min Percent ile Ġin Ġ 0 .. 1 0 0 ) Ġ{ Ġ" Min Ġpercent ile Ġmust Ġbe Ġbetween Ġ 0 Ġand Ġ 1 0 0 Ġinclusive " Ġ} ĊĠĠĠ Ġrequire ( config . max Percent ile Ġin Ġ 0 .. 1 0 0 ) Ġ{ Ġ" Max Ġpercent ile Ġmust Ġbe Ġbetween Ġ 0 Ġand Ġ 1 0 0 Ġinclusive " Ġ} ĊĠĠĠ Ġrequire ( config . min Percent ile Ġ< Ġconfig . max Percent ile ) Ġ{ Ġ" Min Ġpercent ile Ġmust Ġbe Ġ< Ġmax Ġpercent ile " Ġ} Ċ } Ċ Ċ fun Ġerr ( message : ĠString ) Ġ= ĠSystem . err . println ( message ) Ċ Ċ fun Ġmain ( args : ĠArray < String >) Ġ{ ĊĠĠĠ Ġval Ġparser Ġ= ĠCmd Line Parser ( config ) ĊĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġparser . parse Argument ( args . toList ()) ĊĠĠĠĠĠĠĠ Ġgenerate Histogram () ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠCmd Line Exception ) Ġ{ ĊĠĠĠĠĠĠĠ Ġerr (" Error : Ġ${ e . message }\ n ") ĊĠĠĠĠĠĠĠ Ġerr ("${ script . name } Ġgenerates Ġa Ġhistogram Ġchart Ġfor Ġa Ġsequence Ġof Ġnumbers \ n ") ĊĠĠĠĠĠĠĠ Ġerr (" Usage : Ġ${ script . name } Ġ< options >") ĊĠĠĠĠĠĠĠ Ġparser . print Usage ( System . err ) ĊĠĠĠĠĠĠĠ Ġerr ("\ n Example : Ġ${ script . name } Ġ- input Ġdata . txt Ġ- output Ġresponses . png Ġ- label Ġ' Response Ġ( s )' Ġ- bins Ġ 1 0 0 ") ĊĠĠĠĠĠĠĠ ĠSystem . exit ( 1 ) ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġerr (" Error : Ġ${ e . message }\ n ") ĊĠĠĠĠĠĠĠ ĠSystem . exit ( 1 ) ĊĠĠĠ Ġ} Ċ }