Re: Math with sequences and single values
- Posted by jaygade Mar 13, 2011
- 2375 views
-- Now, a REAL invoice program would probably use EDS or an external database -- system and not even worry about sequences in this way exactly. include std/math.e -- Return a price or a list of prices changed by the amount in change. -- Note: a discount must be negative, a markup postive. If the discount or -- markup are on a per-item basis then price and change must be the same length. -- Change is expressed as a decimal indicating a percentage markup or markdown. function priceChange(object price, object change = 0) integer lpr, lch object total if sequence(price) and sequence(change) then lpr = length(price) lch = length(change) -- ensure sequences are the same size by padding with 0s. if lpr < lch then price &= repeat(0, lch - lpr) else change &= repeat(0, lpr - lch) end if end if total = price * (1 + change) return total end function -- This is the equivalent of Vinoba's original "invoice()" function function item_total(object sprice, object squantity) integer lsp, lsq object sitemcost if sequence(sprice) and sequence(squantity) then lsp = length(sprice) lsq = length(squantity) -- ensure sequences are the same size by padding with 0s. if lsp < lsq then sprice &= repeat(0, lsq - lsp) else squantity &= repeat(0, lsp - lsq) end if end if sitemcost = sprice * squantity return sitemcost end function -- Print out the subtotals for each item purchased. Could be re-written to -- return strings or sequences or html or whatever instead. procedure invoice(sequence sitems, object subtotals) integer lsi, lsu if atom (subtotals) then subtotals = {subtotals} -- promote subtotals to a sequence end if lsi = length(sitems) lsu = length(subtotals) if lsi < lsu then sitems &= repeat("", lsu - lsi) else subtotals &= repeat(0, lsi - lsu) end if -- Really, we should have "item, quantity, price, total" but we're not -- doing that complicated. If so then I would refactor this whole thing. for i = 1 to lsi do printf(1, "Item: %s Total: %.2f \n", {sitems[i], subtotals[i]}) end for puts(1, "\n") end procedure -- Main sequence spurchages = { "Screws", "Nails", "Rivets" } sequence spr = {7.34, 2.54, 6.72} object squan = 12 -- buy 12 of everything. sequence sdetails sdetails = item_total(spr, squan) ? sdetails -- the sum cost of each item ? sum(sdetails) -- the total purchase invoice(spurchages, sdetails) squan = { 12, 10, 20 } -- buy different quantities of each thing. sdetails = item_total(spr, squan) ? sdetails ? sum(sdetails) invoice(spurchages, sdetails) sequence disprices = priceChange(spr, -0.15) -- discount everything 15% sdetails = item_total(disprices, squan) ? sdetails ? sum(sdetails) invoice(spurchages, sdetails) disprices = priceChange(spr, {-0.10, 0, -0.20}) -- discount by different amounts sdetails = item_total(disprices, squan) ? sdetails ? sum(sdetails) invoice(spurchages, sdetails)
Not perfect, but it demonstrates what we've been talking about.
BTW, the example program you posted would fail, or at least the invoice() method would if the sequences sprice and squantity were different lengths anyway.
This program - while a simplification, but that's what we're working with here - shows operations on sequences and single values and operations on sequences and sequences. One caveat with regards to operations on two sequences is that they must have the same length and shape. The interpreter doesn't assume that you haven't made a mistake and silently pad your shorter sequences with zeroes or empty strings if they don't match. That's up to the programmer to do.