INTERACT FORUM

Please login or register.

Login with username, password and session length
Advanced search  
Pages: [1]   Go Down

Author Topic: Examples of the new LOAD and SAVE functions?  (Read 12152 times)

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Examples of the new LOAD and SAVE functions?
« on: April 25, 2012, 04:09:57 am »

Been trying for an hour or so and getting nowhere.

save() seems to work but I haven't figured out how to work with load() at all :/

Anybody provide any examples?
Logged

MrC

  • Citizen of the Universe
  • *****
  • Posts: 10462
  • Your life is short. Give me your money.
Re: Examples of the new LOAD and SAVE functions?
« Reply #1 on: April 25, 2012, 11:25:57 am »

I just used these last night.  Let's say you have a path you use a bunch of times, and want to tidy up your expression, with an audio path (we'll call it AP):


Save(\some\long\audio\path\goes\here, AP)/
IfElse(
  IsEqual([Media Type], Audio), Load(AP),
  IsEqual([Media Type], Video), d:\movies,
  1, NOT CONFIGURED YET
)
Logged
The opinions I express represent my own folly.

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #2 on: April 25, 2012, 11:35:59 am »

Thanks for the example.

So these variables only work inside ONE expression? MEH!

I was hoping these were the globals we have been discussing :'(
Logged

Matt

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 42445
  • Shoes gone again!
Re: Examples of the new LOAD and SAVE functions?
« Reply #3 on: April 25, 2012, 11:52:08 am »

I added Load(...) / Save(...) for a failed experiment with the expression compiler.  I thought these functions might be useful anyway, so left them.

Making the variables global wouldn't be hard, but I'm not clear why you'd do that or how you'd ensure you had set a variable when you expected.

And as a disclaimer, I don't want to open a big new front in expression land for a while.
Logged
Matt Ashland, JRiver Media Center

MrC

  • Citizen of the Universe
  • *****
  • Posts: 10462
  • Your life is short. Give me your money.
Re: Examples of the new LOAD and SAVE functions?
« Reply #4 on: April 25, 2012, 12:28:13 pm »

... but I'm not clear why you'd do that or how you'd ensure you had set a variable when you expected.
FYI: here is mark_h's thread.  I think the thread assumes an ordered execution, updating of smartlists, and variable assignment:

  1) run smartlist
  2) grab some field from single entry in that list
  3) assign it to a GV
  4) run another smartlist based upon this GV

There's probably a more direct route to solving this particular case.
Logged
The opinions I express represent my own folly.

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #5 on: April 25, 2012, 12:59:37 pm »

FYI: here is mark_h's thread.  I think the thread assumes an ordered execution, updating of smartlists, and variable assignment:

  1) run smartlist
  2) grab some field from single entry in that list
  3) assign it to a GV
  4) run another smartlist based upon this GV

There's probably a more direct route to solving this particular case.

Yes, that's exactly what I want to do.  There are loads of things I'd like to do but require such functionality.

It'd be great if the contents of the save() variable were available to ANY expression once save()'d

Logged

rick.ca

  • Citizen of the Universe
  • *****
  • Posts: 3729
Re: Examples of the new LOAD and SAVE functions?
« Reply #6 on: April 25, 2012, 01:34:13 pm »

Quote
It'd be great if the contents of the save() variable were available to ANY expression once save()'d

+1

Would there be in any harm in saving variables to the Library so they can be, in effect, permanent? I suppose there would have to be an accompanying tool (in Options?) for cleaning up messes: Clear saved variables. And maybe a List saved variables for troubleshooting. :-\
Logged

MrC

  • Citizen of the Universe
  • *****
  • Posts: 10462
  • Your life is short. Give me your money.
Re: Examples of the new LOAD and SAVE functions?
« Reply #7 on: April 25, 2012, 02:32:32 pm »

One can almost think about the various File Locations as being a specialized case of this.  And calculated Fields w/static values.  Maybe this could be extended and generalized.

I use an [fCoverArt] field for cover art base directory for inside expressions so I don't have to hard code paths.  But it feels wrong to be a per-record field, when really it is a global var like File Location settings.
Logged
The opinions I express represent my own folly.

Matt

  • Administrator
  • Citizen of the Universe
  • *****
  • Posts: 42445
  • Shoes gone again!
Re: Examples of the new LOAD and SAVE functions?
« Reply #8 on: April 25, 2012, 04:44:50 pm »

Next build:
Changed: Expression variables used with Load(...) and Save(...) are global, and valid for the run of the program.

However, I reserve the right to back-track on the first sign of trouble.

The change is trivial, but I don't love it for two reasons:
1) The expression compiler can't optimize variables like it can constants since they can change every run (and since they're global, there's some overhead for locking).
2) Sharing a global variable space is not a reliable thing to do in a highly threaded environment like Media Center (for example, someone browsing with Gizmo could clobber variables that you're using while browsing locally -- it won't crash, but the results will be undefined)


I use an [fCoverArt] field for cover art base directory for inside expressions so I don't have to hard code paths.  But it feels wrong to be a per-record field, when really it is a global var like File Location settings.

I agree it's weird, but it isn't storing anything per-record.  And it has the advantage that the expression compiler knows it's static.

I suppose a list of constants would be more elegant.
Logged
Matt Ashland, JRiver Media Center

rick.ca

  • Citizen of the Universe
  • *****
  • Posts: 3729
Re: Examples of the new LOAD and SAVE functions?
« Reply #9 on: April 25, 2012, 07:07:19 pm »

Obviously variables can be set by any expression that needs them, but I was thinking it might be more convenient if they could be set more like 'environment variables'—so certain constants are always available to any expression. I still haven't decided what I might use this for, but this is what I came up with...
Logged

glynor

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 19608
Re: Examples of the new LOAD and SAVE functions?
« Reply #10 on: April 25, 2012, 09:13:32 pm »

Next build:
Changed: Expression variables used with Load(...) and Save(...) are global, and valid for the run of the program.

However, I reserve the right to back-track on the first sign of trouble.

Yeah.... This made me nervous when I read it tonight.

It could certainly come in handy, and there really needs to be a way to pass variables from expression to expression easily (as in the examples given, which were certainly my first thoughts for using this).  I guess more for the second reason you gave than the first, but... Really more that...

Even with my limited programming experience I understand many of the reasons why it is a good rule-of-thumb to scope your variables (and whatnot) as narrowly as is practical.  And when not needed, with complicated expressions, I can also see it leading to trouble and difficult debugging.  So it concerns me on a basic level that these are all global.

It seems like asking for trouble.  But then, I'm having some trouble thinking of use cases for them in any case.  I know I've wished for them (not even that long ago, during my iDevice syncing adventure), but I'm fried I guess.

Wouldn't it be possible to have local variables that you can store in a custom Field when you need them to be global?

I don't know... Feel free to ignore me.
Logged
"Some cultures are defined by their relationship to cheese."

Visit me on the Interweb Thingie: http://glynor.com/

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #11 on: April 26, 2012, 03:51:32 am »

OK, so this is now sort of working...

I create a seed smartlist that pulls ONE entry from my database and has an expression column that save()'s a variable based on a piece of data.  WORKS.

I create a second smartlist that calls the seed smartlist, but I don't get refreshed values for the variable... just whatever was created when the seed smartlist was manually called...

This defeats my goal, which is to use the seed smartlist to AUTOMATICALLY refresh the variable every time it is used.

Can this be achieved?
Logged

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #12 on: April 26, 2012, 06:11:57 am »

So as an example, here is what I've achieved (ignoring the auto-refresh issue...)

VarChartEntry is the variable, generated by the seed smartlist and is a random week in pop charts history.

RegexpPosit... is a regular expression, using VarChartEntry, to find the chart position of all tracks I have that were in the charts that week as shown by the data in Chart History (singles).

Finally I sort on RegexpPosit to give the order for the charts in the VarChartEntry week.

The idea is that I can generate (at random if auto-refresh were available) a week of chart tracks sorted by their chart position.

Logged

rick.ca

  • Citizen of the Universe
  • *****
  • Posts: 3729
Re: Examples of the new LOAD and SAVE functions?
« Reply #13 on: April 26, 2012, 06:23:49 am »

So as an example, here is what I've achieved (ignoring the auto-refresh issue...)

Could you avoid the auto-refresh issue by determining the random week mathematically in the same smartlist, rather using the separate seed smartlist?
Logged

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #14 on: April 26, 2012, 06:52:02 am »

Could you avoid the auto-refresh issue by determining the random week mathematically in the same smartlist, rather using the separate seed smartlist?

Without variables, AFAIK, it's impossible to do because there is no concept of data perpetuating across records; same reason we cannot calculate album ratings etc.  Certainly I've tried, but always failed, hence my strong desire for variables and now for AUTO-REFRESHING when a smartlist is referenced within another (the data refreshes, so not sure why the variables don't - will leave that for Matt...)

Logged

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #15 on: April 26, 2012, 07:55:48 am »

Another example.  In a view with one album showing, this expression:

if(isequal([track #],load(vartracks[artist][album]),5),save([track #],vartracks[artist][album],),-1)

will count the number of tracks on the album and deposit the result in the variable: vartracks[artist][album]

I'm guessing this could be written to a field for all albums, but would generate a lot of variables...?

Update:

OK, so add a user field 'Album Tracks #' as a calculated field:

if(isequal([track #],load(vartracks[artist][album]),5),save([track #],vartracks[artist][album],1),load(vartracks[artist][album]))

And now you have the count of track numbers for all your albums available...

The (terrifying?!) power of variables... :D

Logged

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #16 on: April 26, 2012, 08:15:23 am »

Next challenge - calculate an album average rating...
Logged

vagskal

  • Citizen of the Universe
  • *****
  • Posts: 1227
Re: Examples of the new LOAD and SAVE functions?
« Reply #17 on: April 26, 2012, 11:58:14 am »

Clever mark_h!

This gave me the idea to create a field relational to another field (other than the already available artist, album and series stock fields). But this did not work:

Field A (for internal use)
Save([Original Artist],varOriginalArtist[Name],1)

Field B (for display making in effect [Original Artist] relational to [Name]
Load(varOriginalArtist[Name])

I might have misunderstood something...

EDIT because I got wiser: This seems to actually work:

Field A (for internal use)
if(IsEmpty([Original Artist]),,Save([Original Artist],varOriginalArtist[Name],1))

Field B (for display making in effect [Original Artist] relational to [Name]
Load(varOriginalArtist[Name])
Logged

rick.ca

  • Citizen of the Universe
  • *****
  • Posts: 3729
Re: Examples of the new LOAD and SAVE functions?
« Reply #18 on: April 26, 2012, 03:36:00 pm »

Without variables, AFAIK, it's impossible to do because there is no concept of data perpetuating across records...

I meant determine the random week mathematically and Save() the result.
Logged

vagskal

  • Citizen of the Universe
  • *****
  • Posts: 1227
Re: Examples of the new LOAD and SAVE functions?
« Reply #19 on: April 27, 2012, 01:18:04 am »

This seems to actually work:

Field A (for internal use)
if(IsEmpty([Original Artist]),,Save([Original Artist],varOriginalArtist[Name],1))

Field B (for display making in effect [Original Artist] relational to [Name]
Load(varOriginalArtist[Name])

Well it seems to work only when both [Field A] and [Field B] are set as columns in a view. It does not work if only [Field B] is set as a column. Is that the intended behaviour?
Logged

MrC

  • Citizen of the Universe
  • *****
  • Posts: 10462
  • Your life is short. Give me your money.
Re: Examples of the new LOAD and SAVE functions?
« Reply #20 on: April 27, 2012, 01:37:04 am »

Probably the field/GV is not evaluated until necessary.  You can test for it in the Set Rules for File Display.  That will cause an evaluation.

If it is a user field, just test that the field is not empty to include those files.  Or if it is not a field or to force evaluation, you can use something like:

   [=save(value,variable)1]=1

as a Custom Rule in Set Rules for File Display.  Note the forced 1 after the paren so that the Search returns TRUE always.
Logged
The opinions I express represent my own folly.

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #21 on: April 27, 2012, 01:39:45 am »

I meant determine the random week mathematically and Save() the result.

Again, AFAIK it cannot be done within ONE smartlist because that calculation will be carried out by ALL other tracks in the smartlist and will come up with a different answer OR the answer won't be available for further rules to consider in time.  I'll take a look today as I might have an idea that can be tried...
Logged

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #22 on: April 27, 2012, 01:48:09 am »

Probably the field/GV is not evaluated until necessary.

Yeah, there's definitely some rule here to understand.

While smartlists get evaluated each time you run them, variables only seem to be refreshed if they are part of the view.

Just tested the above and that's not true.

More experimenting today.
Logged

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #23 on: April 27, 2012, 01:56:51 am »

If it is a user field, just test that the field is not empty to include those files.  Or if it is not a field or to force evaluation, you can use something like:

   [=save(value,variable)1]=1

This has provided the key for refreshing!  BUT, it only works with another level of smartlists, so I now have:

seed list - this pulls ONE entry from which to take the chart week
intermediate list - calls the seed list and creates the variable based on the chart week
final list - calls the intermediate to recover the new variable and display results.

if the final list calls only the seed list the variable is not refreshed because there is no sorting to the database applied and so the first value is always selected, resulting in the same chart week every time.  Rick's suggestion of calculating a starting week may be able to remove the intermediate list.


Logged

mark_h

  • MC Beta Team
  • Citizen of the Universe
  • *****
  • Posts: 1855
Re: Examples of the new LOAD and SAVE functions?
« Reply #24 on: April 27, 2012, 03:41:12 am »

The problem with not being able to use one seed list is related to the way smartlists are processed:

Ideally I would use a scheme like:

[Media Type]=[Audio] ~sort=Random ~n=1 [=save([chart entry],VarChartEntry)1]=1

This would pick ONE random track from my audio collection and create a variable based on that tracks [chart entry].

But because of the way the smartlist parser works it reorganises the above to:

[Media Type]=[Audio] [=save([chart entry],VarChartEntry)1]=1 ~sort=Random ~n=1

Which has the effect of always selecting the same [chart entry] for the variable AND THEN restricts the results to one random entry, but the variable is already set...

I'm guessing there are plenty of situations where order is critical to the success of our smartlists and this enforced order creates situations that require workarounds.  It would be nice if we had full control over the order of the smartlist processing...

Logged

MrHaugen

  • Regular Member
  • Citizen of the Universe
  • *****
  • Posts: 3774
Re: Examples of the new LOAD and SAVE functions?
« Reply #25 on: April 27, 2012, 03:54:43 am »

Next challenge - calculate an album average rating...

Oh yea. I've been looking for that for a long time. Would save me a lot of trouble manually add album ratings. This is also connected to things like counters for episodes for series, and how many of them that is left who is not watched. This would be perfect to have in the Info pane for TV Shows. Then you would not have to relay so much on views. As I think I've understood, this cross media file counters is not possible today right?
Logged
- I may not always believe what I'm saying

vagskal

  • Citizen of the Universe
  • *****
  • Posts: 1227
Re: Examples of the new LOAD and SAVE functions?
« Reply #26 on: April 27, 2012, 07:18:49 am »

Probably the field/GV is not evaluated until necessary.  You can test for it in the Set Rules for File Display.  That will cause an evaluation.

Thanks! Just setting the rules for file display to this works (at least until Matt sees the opportunity to optimize the evaluation engine even further...):
([Field A]=[] or -[Field A]=[])

Logged

MrC

  • Citizen of the Universe
  • *****
  • Posts: 10462
  • Your life is short. Give me your money.
Re: Examples of the new LOAD and SAVE functions?
« Reply #27 on: April 27, 2012, 11:06:45 am »

Linking to mark_h's new thread on Calculating Album Average Rating using variables:

   http://yabb.jriver.com/interact/index.php?topic=71790.0
Logged
The opinions I express represent my own folly.

vagskal

  • Citizen of the Universe
  • *****
  • Posts: 1227
Re: Examples of the new LOAD and SAVE functions?
« Reply #28 on: April 27, 2012, 12:12:20 pm »

I just wanted to share this discovery of how clever the expression engine is.

The variable name can in fact include functions, since the expression engine recognizes them without any escapement. At first I messed with variable names like varComposerBorn[Composer]ListItem([Composer],0), but later discovered that the expression engine accepts/understands this varComposerBornListItem([Composer],0). And now I can also have fields relational to the "Primary" composer (or the "primary"/first item in any other list type field)!

Sorry if this was obvious to everyone else.
Logged

MrC

  • Citizen of the Universe
  • *****
  • Posts: 10462
  • Your life is short. Give me your money.
Re: Examples of the new LOAD and SAVE functions?
« Reply #29 on: April 27, 2012, 12:35:26 pm »

Now all we need is self-modifying code.

This is going to bite someone, somehow, someway...

Typically in a language, keywords are isolated and identified by various parsing tokens.  But in MC, the language is looser, and parsing uses the longest match to identify keywords, with function-identification keyed by parenthesis.  Once a pair of parens is identified, the parse tracks backwards to look for functions.  The parsing is context-aware.  So,

   varComposerBornListItem()

gets parsed into:

   varComposerBornListItem()

and the varComposerBorn is just text.  But if you or some user use something like:

  varAlbumReplaceListItem()

anticipating the current behavior, and JRiver adds a new function:

  ReplaceListItem()

guess what happens?

I believe the /# #/ escapements introduced when Regex() was added provide a means to prevent this (but I'm not certain of this, esp. with recent w/inlining changes), and makes the intent clearer:

   varComposerBorn/##/ListItem()
Logged
The opinions I express represent my own folly.

vagskal

  • Citizen of the Universe
  • *****
  • Posts: 1227
Re: Examples of the new LOAD and SAVE functions?
« Reply #30 on: April 27, 2012, 12:44:52 pm »

Yes, MrC. The cleverness (I hope that is an English word) of the expression engine surprised me as well. I would not mind escaping each function that is part of a variable name.

BTW Do you, or anyone else, know what this restriction actually means?
Next build:
Changed: Expression variables used with Load(...) and Save(...) are global, and valid for the run of the program.
Logged

MrC

  • Citizen of the Universe
  • *****
  • Posts: 10462
  • Your life is short. Give me your money.
Re: Examples of the new LOAD and SAVE functions?
« Reply #31 on: April 27, 2012, 12:52:04 pm »

BTW Do you, or anyone else, know what this restriction actually means?

I presumed it meant until the program closes, and the vars are not saved to disk in any way.  They don't exist when the program starts (unlike field data maintained in the on-disk DB).  They are re-calculated when first referenced.
Logged
The opinions I express represent my own folly.

vagskal

  • Citizen of the Universe
  • *****
  • Posts: 1227
Re: Examples of the new LOAD and SAVE functions?
« Reply #32 on: April 27, 2012, 12:56:04 pm »

Thanks!

They are re-calculated when first referenced.

Aha, and that is why you suggested a display rule for the relevant views that referenced those fields. I see. Clever!
Logged

vagskal

  • Citizen of the Universe
  • *****
  • Posts: 1227
Re: Examples of the new LOAD and SAVE functions?
« Reply #33 on: April 30, 2012, 01:50:51 pm »

These global variables are really useful!

I have since long searched for an easy way to tag my cover art files (folder, back, booklet, inside, inlay & CD) stored in the audio album folder with [Album], [Album Artist], [Date] fields etc. that correspond to fields for the audio files in that folder to use them in all media views (my file structure is not robust enough to do this from file paths, and I like to keep the paths intact).

This is now possible in an all media view by making expression columns with expressions like
if(IsEmpty([Album]),,Save([Album],varAlbum[Filename (path)],1))
and clearing in the cover art files all values in the referenced fields ([Album] in the example). Then it is easy to set the fields in the cover art files to the values in the corresponding audio files with expressions like this
=Load(varAlbum[Filename (path)])

Great! Global values enabled me to create not only, in effect, custom relational fields but also all media views where my cover art is grouped along with the associated audio files.

Thanks!
Logged
Pages: [1]   Go Up