Cheatsheet

scala-cli repl --dep io.github.quafadas::scautable::0.0.44 \
  --scalac-option -Xmax-inlines --scalac-option 2048 \
  --java-opt -Xss4m \
  --repl-init-script 'import io.github.quafadas.table.{*, given}'

Reading CSV Files

Csv Available As CSV Size Columns Hints
Inlined in code <1Kb < 100 inline val s= "aHeader\nr1c1\nr2c1"

CSV.fromString(s)
File - Compile Time < 20Mb <100 CSV.relativeToSource("a.csv")

CSV.projectRoot("data/a.csv")

CSV.resource("a.csv")

CSV.absolutePath("/abs/path/to/a.csv")
File - Compile Time > 20Mb & < 250 Mb Dont attempt to infer types at compile time.

val inferOpts = CsvOpts(TypeInferrer.FirstN(20000))

val knownOpts = CsvOpts(TypeInferrer.FromTuple[(Int, String, Double)])

CSV.relativeToSource("path/a.csv", inferOpts)

CSV.absolutePath("/path/a.csv", knownOpts)

CSV.resource("a.csv", knownOpts)
File - Run Time < 250Mb <100 val reader = CSV.fromTyped[("col1", "col2", "col3"), (String, Int, Double)]

val data = reader(os.pwd / "simple.csv")
File > 250 Mb or >100 columns Scautable is not the right thing to analyse this file. Consider a proper query optimised dataframe library such as Spark or Polars

Displaying Tables

Assuming you have an Iterator / Iterable of named tuples.

e.g. val data : Seq[(col1 : String, col2 : Int, col3 : Double)] = ???

Target Hints
repl print / markdown data.ptbln
String data.consoleFormatNt(fansi = false)
html HtmlRenderer.nt(data)
Almond Html(HtmlRenderer.nt(data))
browser window HtmlRenderer.desktopShowNt(data)
format one column data.formatColumn["col3", Decimals[2]].ptbln

Joining

Assuming two Iterator / Iterable of named tuples. The key goes after the right hand table.

Want Hints
inner join, same key name orders.join(customers)["custId"]
inner join, different key names orders.joinOn(people)["custId", "id"]
left join, right columns become Option orders.leftJoin(customers)["custId"]
left join, different key names orders.leftJoinOn(people)["custId", "id"]
right join swap the tables and use leftJoin
a name is on both sides compile error - renameColumn or dropColumn first
key column is Option None never matches, as in SQL / pandas
key column is Option, after join narrowed - Option[Int] becomes Int
key column is Option, after leftJoin left alone - the None rows are still there
really want None to match mapColumn["k", Int](_.getOrElse(-1)) first

The right hand table is read into memory; the left streams. Put the smaller table on the right.

Excel Operations (JVM only)

TBD

Type Inference

Inferrer Use Case
FromAllRows Most accurate type detection (default)
FirstRow Fast, but less accurate type detection
StringType Safe Mode
FromFirstNRows(n) Balance between accuracy and speed
FromTuple[T] You have control of type inference. Can decode complex types via implicit evidence