Another learning exercise

I’m using some downtime this holiday week to hone my Tinderbox action code skills, but I’ve run into a snag and I’m spinning my wheels on the right way to process a list.

Test RepCount text.tbx (215.2 KB)

In the uploaded file, I’ve got a /Data folder with 2 Notes that have $Text populated from a workout tracker program.

I’m processing the lines in the $Text to look for a workout exercise title, create a new note, and then process the following lines to calculate the weight x reps as attributes and generate a volume number (=weight x reps).

I’m getting the exercise titles, but I’m not figuring out how to process the following lines of data up to the next blank line and then create a note with the exercise title and the volume as a number attribute.

Just posting this in case there’s an easy path to solution … or in case there’s an obvious step that I may be missing.

This should be fun.

The text we’re processing looks like this:

Leg Extensions
150x12
160x12
Matrix Chest Press
130x12
140x12
150x12
....

So, you’re making a list of the lines in this file, vExercises. You step through each line:

vExercises.each(aPart) {
    if(aPart.contains("^[a-zA-Z+].+"))  {
       vSet=aPart.extract("^[a-zA-Z+].+");
       create(vSet);
      }
   }

And you do, indeed, make a new note to represent that exercise!

The next steps I suggest are:

  1. create returns the path of the created note. Save that in a local variable theNote.
  2. When you meet a vExercise that does NOT begin with letters, it’s a weight and a repetition count. Append that to the text of the new note: $Text(theNote) += aPart;. This is just for testing; later, we’ll process the information.

That shouldn’t be too hard. Give it a go!


One minor refinement: it can help to encapsulate details in small functions. For example, you write:

if(aPart.contains("^[a-zA-Z+].+")) {....}

This is fine! But I think it’s a little bit cleaner to write

if(isExercise(aPart)) {....}

where you have a function

function isExercise(s:string) {
     return s.contains("^[a-zA-Z+].+")
}

This makes your intention a little clearer. If, someday, the test for checking whether the line is an exercise gets more complicated, you can hide that complication away inside the function.

4 Likes

Thanks! I updated the stamp with your suggestions, and made progress.

But-- the value of the path to the created Note appears not to be retained during the "each"cycle:

var theNote = create(vSet);

I’ve added \Logs to track the progress.

Test RepCount text.tbx (270.2 KB)

    if(isExercise(aPart))
      {
// Come here if we know this item is an exercise title
       Log("Cycling through vExercises:  "+aPart);
       vSet=aPart.extract("^[a-zA-Z+].+");
       var theNote = create(vSet);
       Log("Path to created note: "+theNote);
      }
       else
// Otherwise, add the exercises to the Text of the just-created note
       {
        Log("Cycling through weights & reps:  "+aPart+" with "+theNote);
//        $Text(theNote) += aPart;
       }
   }

Local variables are local: they don’t last forever. In this case, the var theNote lasts until its if clause ends. So it won’t be there in the next trip through the loop.

It’s easy enough to declare it outside the loop, so it lasts longer:

    var:string theNote;
    vExercises.each(aPart) {
        if(isExercise(aPart)) {
       Log("Cycling through vExercises:  "+aPart);
       vSet=aPart.extract("^[a-zA-Z+].+");
       theNote = create(vSet);
       Log("Path to created note: "+theNote);
      }
       else {
          Log("Cycling through weights & reps:  "+aPart+" with "+theNote);
       }
   }

Now, theNote is defined through the life of the stamp. Its value is set when we start a new exercise, and lasts until (a) the value is changed when we start a newer exercise, or (b) the stamp ends.

2 Likes