Skip to content

Commit

Permalink
Merge pull request #342 from yumaikas/fix/add-column-ref-instead-of-copy
Browse files Browse the repository at this point in the history
Pass in a reference to a spreadsheet instead of a copy of the spreadsheet
  • Loading branch information
refaktor committed Sep 12, 2024
2 parents d1b12a8 + 1bd3a28 commit d652ebc
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 7 deletions.
8 changes: 8 additions & 0 deletions evaldo/builtins_bson.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ func ValueToBSON(arg0 env.Object, topLevel bool) any {
}
}
val = vals
case *env.Spreadsheet:
rows := make([]any, len(obj.Rows))
for i, valu := range obj.Rows {
rows[i] = ValueToBSON(valu, false)
}
val = rows
typ = "spr"
met = obj.Cols
case env.Spreadsheet:
// spr["val"] = obj.Rows
//data := make([]interface{}, len(obj.Rows))
Expand Down
19 changes: 18 additions & 1 deletion evaldo/builtins_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,12 @@ func RyeToJSON(res any) string {
return strconv.Itoa(int(v.Value))
case env.List:
return ListToJSON(v)
case env.Vector:
return VectorToJSON(v)
case env.Dict:
return DictToJSON(v)
case *env.Spreadsheet:
return SpreadsheetToJSON(*v)
case env.Spreadsheet:
return SpreadsheetToJSON(v)
case env.SpreadsheetRow:
Expand All @@ -89,7 +93,7 @@ func RyeToJSON(res any) string {
case env.RyeCtx:
return "{ 'state': 'todo' }"
default:
return "\"not handeled\""
return fmt.Sprintf("\"type %T not handeled\"", v)
// TODO-FIXME
}
}
Expand Down Expand Up @@ -131,6 +135,19 @@ func EscapeJson(val string) string {
return res
}

func VectorToJSON(vector env.Vector) string {
var bu strings.Builder
bu.WriteString("[")
for i, val := range vector.Value {
if i > 0 {
bu.WriteString(", ")
}
bu.WriteString(RyeToJSON(val))
}
bu.WriteString("]")
return bu.String()
}

// Inspect returns a string representation of the Integer.
func ListToJSON(list env.List) string {
var bu strings.Builder
Expand Down
86 changes: 84 additions & 2 deletions evaldo/builtins_spreadsheet.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
},
},

// TODO 2 -- this could move to a go functio so it could be called by general load that uses extension to define the loader
// TODO 2 -- this could move to a go function so it could be called by general load that uses extension to define the loader
"load\\csv": {
Argsn: 1,
Doc: "Loads a .csv file to a spreadsheet datatype.",
Expand Down Expand Up @@ -603,6 +603,24 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
}
},
},
"drop-column": {
Argsn: 2,
Doc: "Remove a column from a spreadsheet. Returns new spreadsheet",
Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object {
switch spr := arg0.(type) {
case env.Spreadsheet:
switch rmCol := arg1.(type) {
case env.String:
return DropColumn(ps, spr, rmCol)
case env.Block:
return DropColumnBlock(ps, spr, rmCol)
default:
return MakeArgError(ps, 2, []env.Type{env.WordType, env.BlockType}, "drop-column")
}
}
return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "drop-column")
},
},
"add-column!": {
Argsn: 4,
Doc: "Adds a new column to spreadsheet. Changes in-place and returns the new spreadsheet.",
Expand Down Expand Up @@ -831,6 +849,69 @@ var Builtins_spreadsheet = map[string]*env.Builtin{
},
}

func DropColumnBlock(ps *env.ProgramState, s env.Spreadsheet, names env.Block) env.Object {
toDrop := make([]env.String, 0)
for _, obj := range names.Series.S {
switch word := obj.(type) {
case env.Word:
toDrop = append(toDrop, *env.NewString(ps.Idx.GetWord(word.Index)))
default:
return MakeError(ps, "Cannot use a non-word to specify a column to drop")
}
}
return DropColumns(ps, s, toDrop)
}

func DropColumn(ps *env.ProgramState, s env.Spreadsheet, name env.String) env.Object {
return DropColumns(ps, s, []env.String{name})
}

// Drop one or more columns from a spreadsheet, returning a new spreadsheet
func DropColumns(ps *env.ProgramState, s env.Spreadsheet, names []env.String) env.Object {
var columnsToCopy []int = make([]int, len(s.Cols)-len(names))
var keepColIdx int = 0

for colIdx, col := range s.Cols {
keep := true
for _, name := range names {
nameStr := name.Value
if col == nameStr {
keep = false
break
}
}
if keep {
columnsToCopy[keepColIdx] = colIdx
keepColIdx++
}
}

newCols := make([]string, len(columnsToCopy))

for toIdx, fromIdx := range columnsToCopy {
newCols[toIdx] = s.Cols[fromIdx]
}

newSheet := env.NewSpreadsheet(newCols)
newSheet.Rows = make([]env.SpreadsheetRow, len(s.Rows))

for rowIdx, row := range s.Rows {
newValues := make([]any, len(columnsToCopy))
for toIdx, fromIdx := range columnsToCopy {
newValues[toIdx] = row.Values[fromIdx]
}
newSheet.Rows[rowIdx] = *env.NewSpreadsheetRow(newValues, newSheet)
}
newSheet.Indexes = make(map[string]map[any][]int)

for _, colName := range newCols {
newSheet.Indexes[colName] = s.Indexes[colName]
}
newSheet.Kind = s.Kind

return newSheet
}

func GenerateColumn(ps *env.ProgramState, s env.Spreadsheet, name env.Word, extractCols env.Block, code env.Block) env.Object {
// add name to columns
s.Cols = append(s.Cols, ps.Idx.GetWord(name.Index))
Expand All @@ -848,7 +929,7 @@ func GenerateColumn(ps *env.ProgramState, s env.Spreadsheet, name env.Word, extr
}
// fmt.Println(val)
if er != nil {
return MakeBuiltinError(ps, er.Error(), "add-col!")
return MakeBuiltinError(ps, er.Error(), "add-column!")
}
if firstVal == nil {
var ok bool
Expand All @@ -875,6 +956,7 @@ func GenerateColumn(ps *env.ProgramState, s env.Spreadsheet, name env.Word, extr
// set the result of code block as the new column value in this row
// TODO -- make
row.Values = append(row.Values, ps.Res)
row.Uplink = &s
s.Rows[ix] = row
}
return s
Expand Down
18 changes: 14 additions & 4 deletions examples/spreadsheet/gamers.rye
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,21 @@ gamers: spreadsheet { "name" "gender" "scores" }

; add a row

gamers .add-rows [ "Bob" "M" vector { 86 110 } ]
withScores: gamers .add-rows [ "Bob" "M" vector { 86 110 } ]

; generate column with average scores
|add-column! 'avg-score { scores } { .avg }

|add-col! 'avg-score { scores } { .avg }
|to-bson
|write* %gamers.bson
print withScores
withScores .to-json |write* %gamers.json
withScores .to-bson |write* %gamers.bson

withoutScores: drop-column withScores { scores avg-score }
print withoutScores
withoutScores .to-json |write* %gamers-no-scores.json
withoutScores .to-bson |write* %gamers-no-scores.bson

withoutAvgScore: drop-column withScores "avg-score"
print withoutAvgScore
withoutAvgScore .to-json |write* %gamers-no-avg-score.json
withoutAvgScore .to-bson |write* %gamers-no-avg-score.bson

0 comments on commit d652ebc

Please sign in to comment.