Discuss Scratch

MathlyCat
Scratcher
1000+ posts

Ultimate List of Workarounds And More

thanks alxephan


You may have noticed that I have decided to re-do this entire sticky. Please be aware, the Workarounds still exist.


What Is A Workaround?


You might come here and think to yourself: “What in the world is a workaround!” Well I'll explain it to you!

To put it simply, a workaround on Scratch is a way of making a script that does the function of a made-up block.

Workaround = A script that does a function = Made-up block

If you still aren't sure, here's an example:

I have a made-up block that I call:

(() + () + 1) :: operators

A workaround looks like this:

(() + (() + (1)))

See how the top one is made-up, but the bottom one isn't? Though the bottom one works just like the top one!

Here in the suggestions forum many people make suggestions for new blocks. The purpose of this thread is to keep up with blocks which have workarounds to!

—-

Notable Posts/Workarounds from other Suggestions:

A new operators block, similar to (letter () of ) by dvargasews

TheMonsterOfTheDeep wrote:

So, for anybody who's curious, here is the full workaround, that is the absolute best approximation to the block suggested in the OP, which stores its output in ‘result’:
define letters (a) to (b) of (str) => result
if <<<(a) < [1]> or <(b) < [1]>> or <<(a) > (length of (str))> or <(b) > (length of (str))>>> then
set [result v] to []
stop [this script v]
end
delete (all v) of [chars v]
set [i v] to (a)
if <(a) < (b)> then
repeat (((b) - (a)) + (1))
add (letter (i) of (str)) to [chars v]
change [i v] by (1)
end
else
repeat (((a) - (b)) + (1))
add (letter (i) of (str)) to [chars v]
change [i v] by (-1)
end
end
set [result v] to (chars)
“But that's too long!” I hear you say. Note that this is the absolute complete workaround, that does everything mentioned in the OP (reverse output on backwards indices) and then some (return the same thing as letter (0) of (str) if indices are out of bounds).

For the majority of cases, something much simpler will work, such as:
define letters (a) to (b) of (str) => result
set [i v] to (a)
set [result v] to []
repeat (((b) - (a)) + (1))
set [result v] to (join (result) (letter (i) of (str)))
Note that the only things this block does not support are a) reverse strings, b) bounds checking, and c) strings above the join block limit, which is barely even a problem, as most string manipulation will involve the join block anyways.

Also note that this block will still return a valid value for invalid bounds, simply due to how Scratch bound checks the letter of () block.

If the i variable is bothering you, it gets even better:
define next letter (i) (b) (str)
set [result v] to (join (result) (letter (i) of (str)))
if <(i) < (b)> then
next letter ((i) + (1)) (b) (str)
end

define letters (a) to (b) of (str) => result
set [result v] to []
next letter (a) (b) (str)
And if we had custom reporters, this block would need no variables at all.

To compare, the speed of all three blocks is pretty good for small strings, and the second one should work for almost anything that you would actually need to do in Scratch. It's likely that whatever block the Scratch Team implemented would also be slow on ridiculously large strings, simply because creating substrings, unless they are interned, is by nature an O(n) operation.

My point with this post is that OP's argument that the workaround is laggy / slow is basically moot; although this custom block only works in a single thread, if you are doing multi-threaded string manipulation you are already probably doing something wrong.

I'm honestly not sure where I stand in terms of better string manipulation features in Scratch - certainly they are useful, but figuring out how to implement them myself was honestly one of the best critical thinking exercises I ever received from Scratch. It's important to be able to know how these sorts of operations work on the inside, as it allows you to see how slow they really are - I think people learning to implement them manually is a good experience, and I think that it is not at all bad that Scratch provides it.

I especially think that if we do ever get custom reporters, we should not implement blocks like these - if there were custom reporters (and maybe local variables) than implementing these blocks by hand would have very little negative effect, while it would have a huge educational effect.

Maybe not though. I am using anecdotal evidence here, but I don't think my point is entirely invalid.

Concerning the Bounce block

TheMonsterOfTheDeep wrote:

Because they seem to be cropping up, let me make an offtopic post to clear up some misconceptions about the bounce block…

It's very difficult to make a general “bounce” block, because what it does is reflect the sprite by mirroring its velocity across the line normal to the surface it hits. (Sorry, it's kind of hard to be exactly clear about what it does, so I'm trying to be specific).

However, it's very likely that this block would work imperfectly, at least for bitmap sprites, because the normal line calculated would be more of an “average” normal line than the actual line.

That's not the only problem, of course - the other problem is the question of what to do when the sprite is intersecting (not merely touching the edge of) the other sprite, and what to do when it's touching or intersecting multiple sprites.

The ‘if on edge, bounce’ block is comparatively simple - it merely means that if the sprite is touching or intersecting an edge, reflect across the line perpendicular to that edge in the middle of the sprite, which is really easy to do.

(The reason intersection works for the edge and not for sprites is because the edge is a single line - it's easy to define where the reflection line is, which is straight in the middle of the sprite. However, if it is intersecting a generally shaped object, you also have to calculate the normal line - and where to calculate that is based on where it is touching, which is ambiguous.)

P.S. If you would like to discuss the bounce block more, please make a new topic or find an old one (I'm pretty sure there is at least one old one you can use).

Last edited by MathlyCat (Feb. 14, 2017 13:46:00)


Go make up your bed and work!

Life can be process of trial and error. Yours seems to be error and error.
MathlyCat
Scratcher
1000+ posts

Ultimate List of Workarounds And More

Workarounds
Note: If you have trouble finding one already in the list then make a post asking about a workaround to a certain block. I'll reply with the workaround if there is one!


NOTICE: I honestly don't want to overkill these posts with workarounds so I'm working on separate projects for workarounds for each category!


Motion:
None!

Looks:

previous costume ::looks

switch costume to ((costume #) - (1))
____________________
(showing? :: looks)

define hide
hide
set [showing v] to [false ]

define show
show
set [showing v] to [true]

if <(showing)=[true]> then
say [ you can see me!]
else
say [you can't see me!]
____________________
color :: reporter looks //works for any effect, just change the dropdowns/var names

change [color v] effect by (25)
change [color v] by (25)
____________________
____________________
____________________
Sound:
None!

Pen:

set pen color to hexadecimal input [] :: pen // Applies to all set pen color hex variants

set pen color to ((((R) * (65536)) + ((G) * (256))) + (B))
____________________
____________________

Events:

([  v] recieved? ::events)


when green flag clicked
set [var v] to [0]
forever

if <(var) = [1]> then

set [var v] to [0]
...
end

end


when I receive [message v]
set [var v] to [1]
wait (0.25) secs
set [var v] to [0]
____________________
when <> ::events hat
...


when [timer v] > (0.1)
forever

if <> then
...
end

end
____________________
when costume switches to [costume1 v] ::events hat

when gf clicked
forever
wait until <([costume name v] of [sprite v]) = [costume name here]>
...
end
____________________
The workaround for a for/while loop:
set [i v] to [0 
repeat until <(i) = (45)>
...
change [i v] by (1)
end
____________________
____________________
____________________
____________________

Control:

if <> then {
} else if <> {
} :: control

if <> then

else
if <> then

end

end
____________________
forever if <> {
} :: control cap

forever

if <> then

end

end
____________________
repeat () secs {
} :: control

reset timer //this will only work if you're not using the timer elsewhere in your project
repeat until <(timer) = (number)>
...
end

set [old timer v] to (timer)
repeat until (((timer) - (old timer)) > (seconds ::grey) ) //use this if you are using the timer elsewhere in your project
...
end
____________________
repeat (1) secs {
} :: control
The best workaround:
set [mode v] to (0)
broadcast [repeat secs v] and wait
when I receive [repeat secs v]
if <(mode)=[0]> then
set [t v] to (((days since 2000)*(86400))+(seconds::grey))
wait until <((days since 2000)*(86400))>(t)>
set [mode v] to [1]
broadcast [repeat secs v]
end
when I receive [repeat secs v]
if <(mode)=[0]> then
forever
...
end
end
Because sometimes the script inside the loop will run longer than it is supposed to, like in this situation:
repeat (1) secs {
wait (2) secs
} :: control
____________________
(CloneID::control)

set [clone id v] to [0 ]
repeat (...)

create clone of [sprite v]
change [clone id v] by (1)
end


when I start as a clone
if <(clone id) = [1 ]> then
...:: grey
end
____________________
spawn {
...
} :: control

broadcast [spawn v]
when I receive [spawn v]
...
____________________
for each((var) : (list :: list):: reporter control) {
...
} :: control
//Workaround:

set [var v] to [] // leave this blank
set [i v] to [1] //since scratch's array index starts in 1
repeat (length of [array v])
set [var v] to (item (i v) of [array v])
... //do your stuffs here
change [i v] by (1)
end
____________________
____________________

Sensing:

(clone? ::sensing)

when I start as a clone
set [clone? v] to [true] //variable for this sprite only
____________________
(ask in progress? ::sensing)

set [ask v] to [1]
ask [...] and wait
set [ask v] to [0]
____________________
(sprite clicked? ::sensing)


when this sprite clicked
set [clicked v] to [1]
wait until <not <<mouse down?> and <touching [mouse-pointer v] ?> >>
set [clicked v] to [0]
____________________
day of year :: sensing reporter 

((days since 2000) - ((365) * ((current [year v]) - (2000))))
____________________
____________________
____________________
____________________

Operators:
Project

____________________
Variables/Lists:
Project
____________________

Last edited by MathlyCat (Aug. 2, 2016 18:18:20)


Go make up your bed and work!

Life can be process of trial and error. Yours seems to be error and error.
MathlyCat
Scratcher
1000+ posts

Ultimate List of Workarounds And More

bump?

Go make up your bed and work!

Life can be process of trial and error. Yours seems to be error and error.
Sheep_tester
Scratcher
500+ posts

Ultimate List of Workarounds And More

What's the suggestion here?

Last edited by Sheep_tester (Feb. 28, 2016 17:36:52)


The above post was most likely written by a sheep. Advertisements:
Scratcher1002
Scratcher
1000+ posts

Ultimate List of Workarounds And More

Sheep_tester wrote:

What's the suggestion here?
It's an updated version of the sticky.
DaSpudLord
Scratcher
1000+ posts

Ultimate List of Workarounds And More

I'll report this to be stickied.


U^ェ^U::motion//This is Blocky. He lives in my signature. He is a trained attack block. He protects my siggy from kumquats.
Paddle2See
Scratch Team
1000+ posts

Ultimate List of Workarounds And More

DaSpudLord wrote:

I'll report this to be stickied.
I'm waiting for a response from the original topic owner to see if they are willing to give up the responsibility. If I don't hear back in a few days, we'll assume that they have moved on.

Scratch Team Member, kayak enthusiast, and servant to multiple cats.

;
Ninkancho
Scratcher
500+ posts

Ultimate List of Workarounds And More

Workaround for when stop sign clicked. Use sparingly!

when green flag clicked
forever
set [timer.1 v] to ((timer) + (0.1))
end

when [timer v] > (timer.1)
...

Ninkancho STUDIO☁️ Cloud Clicker DEMO
Let's Play TogetherAnother Rather Unremarkable PlatformerSinewarper
public class Scrape{public static void main(String[] args){Scrape myScrape=new Scrape();myScrape.eternally{myScrape.picture();myScrape.write();myScrape.tell();}}}
Windows NT 10.0, Chrome 51.0.2704.79, Flash 23.0 (release 0)), Flash 23.0 (release 0)
kajquats;
monstermash3
Scratcher
1000+ posts

Ultimate List of Workarounds And More

(letters () to () of []::operators)
has this workaround:
(letters (number::grey) to (other number::grey) of (string::grey)::operators)
is the same as
(solution)
at the end of the following script:
set [index v] to (number::grey)
set [solution v] to []
repeat until <(index) > (other number::grey)>
set [solution v] to (join (solution) (letter (index) of (string::grey)))
change [index v] by (1)
end

(Swallowed by an evil kumquat who was just taking a walk in the neighborhood of evil kumquats when they saw a garage sale where they bought a plate which they used to eat but they discovered that it leaked and they went to get their money back but the sale was over so they went in the house but the door was locked so they got their key but it didn't fit so they went home to use the key on the right door which was their own door and then they decided to swallow a signature for no reason.)
Scratcher1002
Scratcher
1000+ posts

Ultimate List of Workarounds And More

I have quite a few workarounds in the studio in my signature, so you can use those, if you want.
MathlyCat
Scratcher
1000+ posts

Ultimate List of Workarounds And More

Scratcher1002 wrote:

I have quite a few workarounds in the studio in my signature, so you can use those, if you want.
I prefer it if you post each one in Scratchblocks that way I don't get clogged up with workarounds to post!

Go make up your bed and work!

Life can be process of trial and error. Yours seems to be error and error.
bjskistad
Scratcher
1000+ posts

Ultimate List of Workarounds And More

Thanks for reposting this!

Kumquat was Here
PythonKitten
Scratcher
31 posts

Ultimate List of Workarounds And More

Could someone give me a workaround to if some variable contains another? EG:
set [ variable1] to [HELLO!!!!!! ]
set [variable2] to [HELLO]
if (variable2) contains (variable1) then
set [variable1] to (pick random (1) to (10))
end
Ninkancho
Scratcher
500+ posts

Ultimate List of Workarounds And More

http://wiki.scratch.mit.edu/wiki/Checking_if_a_String_Contains_a_String

Ninkancho STUDIO☁️ Cloud Clicker DEMO
Let's Play TogetherAnother Rather Unremarkable PlatformerSinewarper
public class Scrape{public static void main(String[] args){Scrape myScrape=new Scrape();myScrape.eternally{myScrape.picture();myScrape.write();myScrape.tell();}}}
Windows NT 10.0, Chrome 51.0.2704.79, Flash 23.0 (release 0)), Flash 23.0 (release 0)
kajquats;
PythonKitten
Scratcher
31 posts

Ultimate List of Workarounds And More

Thanks!
DrKat123
Scratcher
1000+ posts

Ultimate List of Workarounds And More

The workaround for a for/while oop:
set [i v] to [0 
repeat until <(i) = (45)>
...
change [i v] by (1)
end

Last edited by DrKat123 (March 2, 2016 10:45:28)


Moving from Scratch? Don't learn C or Java, try Snap!
it haz OOP
DrKat McKatFace
First of all I'm 100% human and humans does not have a cat face
and second, the Boaty McBoatFace/Parsey McParseFace madness has just begun

λ
Sharp, my new Scratch mod
Is my post/siggy worthy for an internet?
PythonKitten
Scratcher
31 posts

Ultimate List of Workarounds And More

Nice!
MathlyCat
Scratcher
1000+ posts

Ultimate List of Workarounds And More

PythonKitten wrote:

Could someone give me a workaround to if some variable contains another? EG:
set [ variable1] to [HELLO!!!!!! ]
set [variable2] to [HELLO]
if (variable2) contains (variable1) then
set [variable1] to (pick random (1) to (10))
end
Maybe I wasn't clear, I don't know. But if you have questions about scripts please go to the Help With Scripts forum.
Please read question 7 next time! Thanks

DrKat123 wrote:

The workaround for a for/while oop:
set [i v] to [0 
repeat until <(i) = (45)>
...
change [i v] by (1)
end
Thanks!

Go make up your bed and work!

Life can be process of trial and error. Yours seems to be error and error.
DrKat123
Scratcher
1000+ posts

Ultimate List of Workarounds And More

I got some more workarounds!

color :: reporter looks

change [color v] effect by (25)
change [color v] by (25)

for each((var) : (list :: list):: reporter control) ::cstart control 
...
end
//Workaround:

set [var v] to [] // leave this blank
set [i v] to [1] //since scratch's array index starts in 1
repeat (length of [array v])
set [var v] to (item (i v) of [array v])
... //do your stuffs here
change [i v] by (1)
end

Moving from Scratch? Don't learn C or Java, try Snap!
it haz OOP
DrKat McKatFace
First of all I'm 100% human and humans does not have a cat face
and second, the Boaty McBoatFace/Parsey McParseFace madness has just begun

λ
Sharp, my new Scratch mod
Is my post/siggy worthy for an internet?
PythonKitten
Scratcher
31 posts

Ultimate List of Workarounds And More

Oh. Sorry about that!

Powered by DjangoBB

Standard | Mobile