I'm grabbing my Amazon order history, page by page.
Every page gets appended to a text file.
I end up with a long text file which contains all of my orders.
Now I want to grab the order sum of each one of these orders, and add them up together.
They look like this:
I'll have hundreds of occurrences in the text file.
I can find them with this regex pattern:
(?m)SUMME\nEUR (\d*,\d*)
But what's the most elegant way to have KBM go through the file once, grab each occurrence, and add it to one variable (let's say AmazonSpending2017)?
I thought about running a loop: Grab the first match. Add it to my results variable. Then delete the occurrence. And run the same loop again and again, until the pattern cannot be found anymore.
Is there a more elegant way to do this?
The comma might need to be replaced by a period. I'm using Amazon in Germany, which also doesn't have the CSV reporting tool that the US version has - hence my need for a KBM solution. But it's a problem that interests me in general, because I come across it often - how to deal with multiple occurrences of a regex match.
I doubt this is the most elegant way, but here's the first thing that came to my mind upon seeing this problem; hopefully it will prove useful. Feel free to ask if you have any questions about how it works!
Gabe ⇢ My approach was almost exactly like yours, although I hadn’t bothered with the formatted output. Good job.Â
Okay, I’ll demonstrate once again why I like the Satimage.osax so much.
If you forget about the handlers there’s all of 4 lines of code.
(Remember — the script won’t work, unless the Satimage.osax has been installed!)
-Chris
------------------------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2017/11/19 07:25
# dMod: 2017/11/19 07:30
# Appl: AppleScript + Satimage.osax
# Task: Extract values from text and sum them
# Libs: None
# Osax: Satimage.osax (MUST BE INSTALLED OR THE SCRIPT WON'T WORK!)
# Tags: @Applescript, @Script, @SIO, @Satimage.osax, @Extract, @Values, @Text, @Sum, @Them, @ccstone
------------------------------------------------------------------------------
set sourceText to "
BESTELLUNG AUFGEGEBEN
3. Oktober 2017
SUMME
EUR 20,40
BESTELLUNG AUFGEGEBEN
3. Oktober 2017
SUMME
EUR 21,40
BESTELLUNG AUFGEGEBEN
3. Oktober 2017
SUMME
EUR 22,40
BESTELLUNG AUFGEGEBEN
3. Oktober 2017
SUMME
EUR 23,40
"
set euroList to fndUsing("^SUMME\\nEUR (\\d+,\\d+)", "\\1", sourceText, true, true) of me
set euroList to cng(",", ".", euroList) of me
set theSum to format (sum of (statlist euroList)) into "€0.00"
------------------------------------------------------------------------------
--» HANDLERS
------------------------------------------------------------------------------
on cng(_find, _replace, _data)
change _find into _replace in _data with regexp without case sensitive
end cng
------------------------------------------------------------------------------
on fndUsing(_find, _capture, _data, _all, strRslt)
try
set findResult to find text _find in _data using _capture all occurrences _all ¬
string result strRslt with regexp without case sensitive
on error
false
end try
end fndUsing
------------------------------------------------------------------------------
@gglick, using “For each” really seems like the most elegant way to do it with KBM’s building blocks.
And @ccstone, thanks for the pointer to Satimage.osax. I had never heard of it, nor am I experienced in AppleScript. But I’ll have a look at it. Doing such a task in four lines - that does sound elegant indeed.
Happy to help, @LeoB. “For each” is a fairly new addition to my KM repertoire, and one that I’ve found to have a bit of a learning curve even compared to other aspects of using KM, but it’s incredibly useful and well worth the time it takes to get up to speed with.
Sorry to disillusion you, but For Each came in in version 5.1, March 2012.
For Each is fairly simple once you get your head around the concept. Basically, any time you have or want a list of things, For Each is likely the tool to choose. It iterates through the list, setting a variable each time to one entry and performing the actions.
So as soon as you say "sum all all numbers" in your question title, the For Each action should be your starting point (unless your @ccstone and then AppleScript is your starting point ;- ). the same would be true if you were asking anything like:
Oh, I know that For Each has been around for a few versions now. I just meant that I wasn’t personally aware of it (I clearly didn’t read the 5.1 update notes very carefully, even though I was happily using KM since version 5.0) and didn’t even try using it until this year; hence why it’s a recent addition to my KM repertoire
and, of course, we don't need Satimage to use Regex matching in Applescript - the Foundation classes also give us that
( though of course it's always simpler in JavaScript : -)
And, Satimage comes with a host of other great features/functions/commands that all run very fast and make it an excellent choice for most who want to get the most out of AppleScript for the least amount of effort.
Coders can choose the method they find that works best for them.
------------------------------------------------------------------------------
# Auth: Christopher Stone
# dCre: 2017/11/19 07:25
# dMod: 2017/11/21 08:55
# Appl: AppleScript + Satimage.osax
# Task: Extract values from text and sum them
# Libs: None
# Osax: Satimage.osax (MUST BE INSTALLED OR THE SCRIPT WON'T WORK!)
# Tags: @Applescript, @Script, @SIO, @Satimage.osax, @Extract, @Values, @Text, @Sum, @Them, @ccstone
------------------------------------------------------------------------------
set sourceText to "
BESTELLUNG AUFGEGEBEN
3. Oktober 2017
SUMME
EUR 20,40
BESTELLUNG AUFGEGEBEN
3. Oktober 2017
SUMME
EUR 21,40
BESTELLUNG AUFGEGEBEN
3. Oktober 2017
SUMME
EUR 22,40
BESTELLUNG AUFGEGEBEN
3. Oktober 2017
SUMME
EUR 23,40
"
# Due to a BUG in the Discourse Forum software please manually remove 1 forward slash from "\\\1" below.
set euroList to find text "^SUMME\\nEUR (\\d+,\\d+)" in sourceText using "\\\1" with regexp, all occurrences and string result
set euroList to change "," into "." in euroList with regexp
set theSum to format (sum of (statlist euroList)) into "€0.00"
------------------------------------------------------------------------------