jmoenig / Snap

a visual programming language inspired by Scratch
http://snap.berkeley.edu
GNU Affero General Public License v3.0
1.5k stars 744 forks source link

Input name choices from a pulldown list which varies #2565

Open jcaldw737 opened 4 years ago

jcaldw737 commented 4 years ago

Can we do the following?

After we have allowed users to fill in items in a list, then run another block where the choices in a pulldown for an input name come from that list?

jmoenig commented 4 years ago

Good question! Right now pulldowns are only static. Allowing for dynamic menus has long been on our list of features to add, and recently @bromagosa has pioneered a workable solution that we're planning to put into the next major release later this summer in time for (preparation for) the next school year.

Depending on how urgent you need it I could be talked into releasing that feature earlier. Mind you, it would be solution that requires the author of such a block to use the JavaScript function block, so it wouldn't be something we'd expect students to come with themselves. But teachers and creators of so-called microworlds could use it to make blocks for libraries.

Can you reveal a little more about your plan?

jcaldw737 commented 4 years ago

I work with elementary school students as a volunteer. And I have "moved" a subset of a few commands to the Motion tab to make things simpler for them. Also added some simplifying blocks.

Here's a link

https://tinyurl.com/ezSNAP2019

Now I am working on expanding to include variables for more experienced students. (Will probably put this on the Looks tab .)

Since I don't think I can create a variable via a custom block, I am planning to have, say, 5 blocks created already. The situation would look like

image

In the above example the student has used a custom block to name each of the first 3 variables, and another custom block to assign values to the first two blocks. Those blocks would look like

name(1:, height) set(height,200)

there would be another custom block to get the value of the variable. It would be a function and look like get(height) and would return 200

Each of those custom blocks needs a pulldown list. The name block could have a fixed list of 1:, 2:, 3:, 4:, 5:

But the others need to show whatever names the student has used, in this case height, weight, distance

I believe I can do this via lists, but I can't do the non-static pulldowns.

jmoenig commented 4 years ago

Hmm... I think you might be able to do all of this - including the "dynamic" menus if you try using variables instead of lists after all, but I'm not sure. Are you aware of the library that lets you create variables programmatically? This might address your issue, because once you've created a variable - using the custom blocks in the library - its name also appears in the drop-down menu of the setter block:

make a variable

Do you think this might help with your project?

jcaldw737 commented 4 years ago

Thanks so much! let me give that a try - will have to be tonight.

jcaldw737 commented 4 years ago

Thanks so very much for the block that creates variables. That will improve our system - especially by getting rid of having a fixed number of user variables.

We need to have our blocks on a small number of tabs, say Motion or Looks - one reason is to keep things simpler for our young users of varying skills - we work with pretty much the entire class. But we also want to keep users off the Variables page - so they will be less likely to mess with our system variable(s) and blocks like "global variables"

To "move" a block, like "set", I need to create a "front end" that has the same inputs as the "real" block. So I need to create non-static pulldowns. Btw, in the case of "set" I could also filter out any system variables so it will be less likely that the user will change them.

So that is my case for releasing dynamic menus sooner.

jguille2 commented 4 years ago

Hi @jcaldw737 ,

But you already can do it! You can't make all the dynamic drop-down menus that you want... but you can use some dynamic menus... and the "variables dropdown menu" is one of this. Then, doing...

variableDropDown

You can make it!

usingVariablesDropDown

Joan

jcaldw737 commented 4 years ago

Wow! Thanks so much!

Following your example, I can now get a pulldown with the variable names as choices.

But when I try to pass that to set I get this:

image

Naharie commented 4 years ago

@jcaldw737 You can make the set block use the value of var with the run block: untitled script pic

Using it you can put variables in for all the inputs that are normally drop downs, such as the first input to the set block.

jguille2 commented 4 years ago

Hi! Oh yes, I made a mistake :(

You don't need to drag and drop because that var is just inside your "set block" dropdown. But it is not the way, because "that bar" is then a new instance... not a pointer of the real global var. But we can do it!

settingVars

Joan

jguille2 commented 4 years ago

Thanks @KingDavid12 ,

I was typing the same solution. Great!

Joan

jcaldw737 commented 4 years ago

pls see screen capture below. menu test 1 works. menu test 2 gives an error:]:

a variable of name " does not exist in this context

image

Naharie commented 4 years ago

@jcaldw737 The run block doesn't just replace all the inputs, it fills in the empty ones. It only sees the dropdown as empty. In menu test 2 you need to delete the zero so the box is empty.

jcaldw737 commented 4 years ago

What can I say, except "THANKS TO ALL OF YOU - AGAIN!!!"

jcaldw737 commented 4 years ago

This item is closed, but perhaps just a question: if anyone knows of a block that deletes variables, that information would be greatly appreciated.

jguille2 commented 4 years ago

Hi @jcaldw737 , I've made a new block to delete variables, and edited the "variables creator" to be able to choose between global and sprite variables.

variablesLibPlus

Sharing this library...

varLibPlus.xml.zip

Joan

jmoenig commented 4 years ago

Wonderful, @jguille2! Hey, Joan, why don't you add another reporter block that lets you query the value of a variable by its name and then issue a pull-request to add those to our existing library? That would be perfect, if you get around to it. Thanks!

jcaldw737 commented 4 years ago

Thank you, Joan! And the reporting block which returns the value of a variable given its name is needed here very much.

brianharvey commented 4 years ago

Indeed, thank you, Joan. That's been on my to-do list forever...

jguille2 commented 4 years ago

Hi everybody! After your comments, a new proposal:

variablesLibPlus

Here with the reporter block. And also, I've added a check to the "delete block" and it does nothing (no error) if there is not any var with that name.

@jmoenig If you want to edit our official library, some questions...

Ok. Sharing last proposal...(please, test it)

variablesLibPlus.xml.zip

Joan

brianharvey commented 4 years ago

This is great. I wonder if it wouldn't be good to have a SET _ TO block with a text input for the first slot, even though it can be done with RUN, because that's an obscure feature not everyone knows about. This would sort of complete the algebra of variables. And it's a library, so we don't have to fight for palette slots. :)

jguille2 commented 4 years ago

Ok, then "Set" your decisions :smile: (@brianharvey and @jmoenig )

An extra set block could be

newSetVar

with the existing variables dropdown, but not readOnly, is this right?

If we add this block, I have only one question. What must it do when there is no variable with that name? Using directly "run - set" would make errors... I think it's better to do nothing i that case (no variable with that name). I wait your thoughts... Joan

brianharvey commented 4 years ago

Red halo if no such variable.

This will be great!

jguille2 commented 4 years ago

Hi @brianharvey and @jmoenig ,

Let's go... I don't want to be annoying with this... but it's important to fix clearly these behaviors (you know custom libraries are difficult to maintain, because old projects keep old definitions, and this is not transparent).

So, points to decide:

  1. variable reporter will show red halo for wrong names. For me, it is the right response, because it should not report any value (not even an empty string). And we have the variable predicate to check if it exists.
  2. But what about new "set var to ", for wrong var names? I want to avoid unnecessary errors. So for me, we have two options: 1- do nothing and 2- create global var and set that value.
  3. And a question about "create var" block. Current behavior (last proposal and also current lib) causes overwriting when we want to create a variable that already exists (it loses its value). I think this is not good. I propose to check this, and do nothing if that variable already exists.
  4. Validate block names at my proposal (especially if the shortform "var" is right for you)

and

  1. Remember to send me Portuguese (@MMSequeira ) and German block texts if you want those translations on my PR.

Extra Note. Depending your decisions, I would suggest an extra feature, that will make happy those who wanted to create and set variable values in one go. Yes, they can do it with all these new blocks, but maybe it can be beatiful doing...

createVar1

and also

createVar2

and, of course, keeping the basic use to create a variable without any value.

That's all!

Joan

jcaldw737 commented 4 years ago

Joan -

You didn't ask for my opinions, but here they are anyway :) and please forgive me if I make too bold a use of the word "we"

  1. variable reporter will show red halo for wrong names. yes

  2. But what about new "set var to ",- it seems to me that we need to be consistent in that if trying to report an nonexistent variable gives an error, then trying to set an nonexistent variable should also give an error

  3. And a question about "create var" block. I certainly agree that we shouldn't overwrite, but doesn't the user need some feedback if we don't do anything? - so I vote for an error

  4. Validate block names at my proposal no comment since I don't understand this point

creating and setting variables in one block certainly seems like an excellent feature.

jguille2 commented 4 years ago

Hi @jcaldw737 , Your opinions are welcomed and also appreciated. Thanks. But, of course, I need Brian and Jens validation to do the job :smile:

Joan

jcaldw737 commented 4 years ago

Thank you for the info. I am looking forward to using your blocks. They will lead to a great benefit to my students!

brianharvey commented 4 years ago

I'm always afraid of procedures that just do nothing. I can't tell whether that means I succeeded or failed! Personally I'd rather have an error message. (But of course it's not an error to make a sprite-local variable with the same name as an existing global.)

About SET: This is a case in which my goal of Snap! being a Logo and my goal of Snap! being a Scheme conflict. In Scheme it's an error to SET a variable that doesn't exist in the current scope. In Logo, there is a single command MAKE that creates a global variable, if there is no variable in the current scope, and then in either case sets its value. So I don't have strong feelings either way. :-) But I guess my inclination is to treat the no-such-variable case as an error, because I hate to encourage people to use global variables.

And that train of thought makes me wonder if we don't also need a SCRIPT VARIABLES block with variadic Text input slot in this library.

I'm okay with VAR instead of VARIABLE.

jeandrek commented 4 years ago

And that train of thought makes me wonder if we don't also need a SCRIPT VARIABLES block with variadic Text input slot in this library.

That would only be useful if VAR and SET VAR were to not follow lexical scoping (which can be done by using JavaScript, I think.) Also, this (aside from script variables) is a Panther feature, but I don't see how it's useful when one has associative lists.

brianharvey commented 4 years ago

Hi, Jonathan.

I agree that this entire discussion is somewhat superfluous because you can use an alist instead. But several people have been arguing for it. It's a library -- maybe we should include an alist-based implementation!

I don't understand your point about scoping. Once you make a variable from its name, it behaves like any other variable. It's true that we then can't compile out the variable lookups, so we lose one of the virtues of lexical scope. Is that what you mean?

MMSequeira commented 4 years ago

Hi Joan,

  • And finally, translations. I'll add Catalan and Spanish translations. This library has already Portuguese (@MMSequeira if you want to check this, write on new texts (only see pictures) and I'll also add them). If somebody wants to add others (German?)

Here goes the library with the blocks translated to Portuguese: variablesLibPlusPT.xml.zip.

The options in the new variable creation block are still in English. Is it possible to translate slot menu options? I did not find any way of doing it.

Manuel

jeandrek commented 4 years ago

Hello! Ok, that wasn't quite accurate. It wouldn't be useful for a script to make script variables with names which aren't known in advance unless they can be used, like with THING and MAKE in Logo (or if you were to add hybrid scoping perhaps you'd shadow a variable used in another procedure.)

brianharvey commented 4 years ago

Right, the idea is that SET and the new proposed VAR would take the name as input. It's no more or less true for script variables than for global variables that the feature of creating them doesn't do any good if you can't then read and write them.

Presumably people won't really literally type names into these blocks; the input would be computed, so you could, for example, make 26 variables named A through Z programmatically.

jeandrek commented 4 years ago

Yes, but since they are procedures, they wouldn't report or assign to a variable local to the caller unless they didn't follow lexical scoping.

jguille2 commented 4 years ago

Hi Manuel (@MMSequeira ,

Oops! I thought I had answered your post... but it was not been sended :(

First, thanks! I will pick up your translation for the "final" lib before PR it.

And I think there is no way to translate dropdown input options. It's not easy, because there is not only a visualization issue, it is just about the real content of a variable.

Continue, Joan

brianharvey commented 4 years ago

@Jonathan50 Oh, now I see what you mean! Right, if those were procedures written in Snap! they wouldn't have access to their caller's variables, so they have to be special forms with special evaluation rules. That's true already for the regular SET and variable reporters.

Since this is a library we're talking about, the JS code will be inside a Snap! wrapper, so yes, the JS has to back out one level of procedure calling. Thanks for reminding me -- I'm getting old.

jguille2 commented 4 years ago

Ok, I will include script vars behavior. The idea is to do the same primitives are doing now. So, the scope evaluation is from down to top (script -> sprite -> global). I we have variables with the same name at different scopes, blocks will consider the first encounter (the lower scope one).

Joan