Binary vs Text

by Fraser Gordon on June 2, 2014 8 comments

One aspect of LiveCode 7.0 that I keep bringing up in my blog posts is the distinction between textual data and binary data. Although LiveCode does not implement data types for scripts, it does use them internally. Being aware of how the engine treats these types is important for getting the maximum speed out of your scripts.

The four basic types that the engine operates on are Text, BinaryData, Numbers and Arrays – there are a number of sub-types for each of these but the majority of them are not important here. Arrays are very different to the other three (for example, you can’t treat a number as an array or vice-versa) so I’ll ignore them in this blog post.

Bird, Plane or Binary?

First thing first: what exactly are each of the types?

  1. Number: integer or floating-point (decimal) value
  2. Binary: a sequence of bytes
  3. Text: human-readable text

The distinction between Binary and Text doesn’t seem all that clear; after all, isn’t text ultimately just a sequence of bytes stored somewhere?

The important difference is how you, the script writer, intend to use the data: if you think terms like "char" or "word" are meaningful for your data, it is probably Text. On the other hand, Binary is just a bunch of bytes to which the engine assigns no particular meaning. Another useful rule-of-thumb is that anything a human will interact with is text while anything a computer will use is binary (notable exceptions to this are HTML and XML, which are text-based formats).

Promotions

LiveCode will happily hide issues of binary vs text vs number from you. It is, however, very useful to know how exactly it does this because getting it wrong can result in unexpected results.

The types used by the engine can be thought of as a hierarchy, with the least meaningful types at the bottom and most meaningful at the top. This order, from top-to-bottom is:

  1. Number
  2. Text
  3. Binary

Inside the engine, types get moved up and down this hierarchy as necessary. A type can always be moved downwards to a less-specific type but cannot always be moved upwards. For example, the string "hello" isn’t exactly meaningful as a number.

One potentially surprising consequence of this is the code "put byte 1 of 42" will return ‘4’ rather than the byte with value 42. This happens because the conversion from Number to Binary passes through Text, where the number is converted to the string "42", of which the first byte is "4".

Types in a Typeless Language

Long-time LiveCoders amongst you will no doubt now be thinking that LiveCode is a typeless language and wondering how this information can be used. The key to it is simply being consistent in how you use any piece of data.

Implicit type-conversion within the engine can be slow, especially for large chunks of data, so you don’t want to do things like this:

answer byte  "1" to -1 of "¡Hola señor!"

That short line of code contains a number of un-necessary type conversions. The obvious one is specifying the byte using a string instead of a number. It also contains a conversion of Text to Binary – the "byte" chunk expression indicates you want to treat the input as binary data instead of text. Finally, the "answer" command expects Text, so it converts it back again.

Although the example is contrived, you do need to be careful with chunk expressions. Using "byte" means that you want the data to be Binary while any other chunk type is used for Text.

Text is Slow

It isn’t just type conversions that are slow; treating data as the wrong type can also be slow. In particular, comparison operations are slower for Text than for Binary or Number. To compare text, the caseSensitive and formSensitive properties have to be taken into consideration; case conversion and text normalisation operations mean that the Text operations are slower than the equivalent for Binary.

On the other hand, Text is far more flexible that Binary. Operations on Binary are limited to the following (anything outside this will result in conversion to Text):

  1. "is" and "is not" (must be Binary on both sides of the operation)
  2. "byte" chunk expressions
  3. "byteOffset" function
  4. concatenation ("put after", "put before" and "&" but not "&&")
  5. I/O from/to files and sockets opened as binary
  6. "binfile:" URLs
  7. functions explicitly dealing with binary data (e.g. compress, base64encode)
  8. properties marked as being binary data

Text Encodings and Strict-Mode

Those of you who have been paying attention to my previous blog posts (if you exist!) will have heard me mention that to convert between Text and Binary you need to use textEncode and textDecode. With these functions, you specify an encoding. But when the engine does it automatically, what encoding does it use?

The answer is the "native" encoding of the OS on which LiveCode is running. This means "CP1252" on Windows, "MacRoman" on OSX and iOS and "ISO-8859-1" on Linux and Android. All of these platforms fully support Unicode these days but these were the traditional encodings on these platforms before the Unicode standard came about. LiveCode keeps these encodings for backwards-compatibility.

The reason LiveCode continues to automatically convert between these encodings is because the engine previously did not treat Text and Binary any differently (one impact of this is having to set caseSensitive to true before doing comparisons with binary data). In some situations, you might want to turn this legacy behaviour off.

To aid this, we are planning to (at some point in the future) implement a "strict mode" feature similar to the existing Variable Checking option – in this mode, there will be no auto-conversion between Binary and Text and any attempt to do so will throw an error (similar to using a non-numeric string where a number is expected). Like variable checking, it will be optional but using it should help find bugs and potential speed improvements.

read more
Fraser GordonBinary vs Text

Introducing the new LiveCode stack file formats…JPEG & PNG?

by Neil Roger on May 30, 2014 15 comments

You might be wondering “What is this guy talking about??” or “Image formats for LiveCode stacks, eh?”. Well don’t worry, we’re not changing anything. Read on and all should become clear.

This does bring me onto a rather interesting point and one of the things that can make working in technical support quite a challenge at times….receiving a screenshot of a script and being asked “Why is it not working?”

“Urghh….”

Let me start of by saying that we are always happy to help when it comes to Tech Support. For basic issues, we are generally able to push, point or shove you (but gently) in the right direction. When we receive more advanced queries such as, full hard crashes of the IDE or very specific bugs we require a “recipe” which we can follow in order to reproduce and effectively troubleshoot the issue.

I am very glad to say that the majority of our users are happy to supply a stack file and an easy to follow recipe when reporting these issues, but there have been times when we receive…wait for it…a screenshot of the script.  Now you might be thinking, “What’s wrong with that?”…Well let me tell you 🙂

A screenshot, even though it may contain the troublesome script, requires a substantial amount of time to re-type, as you cannot select the text contained within. This especially becomes very difficult to manage when there are 100’s of lines of script across multiple screenshots.

We then have the added problem of effectively reproducing the issue as, even though we have copied the script correctly, there could be an underlying stack issue causing the problem.

It’s not just direct support that experience this Screenshot phenomenon, I have seen specific LiveCode forum posts of scriptshots which are either questions being asked, or replies to questions :(. This can  really frustrate both beginners and advanced users alike.

With that being said, we at RunRev are not perfect and I have ,  in the past, come across some tutorials on our lesson portal where the scripts have been in images (although I cannot locate these anymore… *phew*).

There is reason behind my rant. I would like to let everyone know of an awesome piece of kit that has made receiving screenshots scripts less daunting than it used to be.

For users of the Google Chrome browser, there is an extension called “Project Naptha”

http://projectnaptha.com/

Project Naptha, as their website states, “applies state-of-the-art computer vision algorithms on every image you see while browsing the web. The result is a seamless and intuitive experience, where you can highlight as well as copy and paste and even edit and translate the text formerly trapped within an image.”

What this essentially means is, that you have the ability to copy text from an image as if it was a text document….(what witchcraft is this I hear you scream!)

When I first saw this advertised, I was very sceptical and thought it was just going to be another attempt at some OCR that would soon vanish into the ether…how wrong was I!

Let me give you a brief demo to show how amazing this is-

You start by adding it to Google chrome via the “Add to Chrome” button on the Project Naptha home page. This is shown below-

Screen Shot 2014-05-21 at 15.44.47.png

After this has been added, I would recommend restarting your Chrome Browser although it should automatically start working on any new tabs you create.

Now, here comes the magic….Navigate to an image on any webpage that contains some form of legible text. As an example I uploaded the following image to the techsupport on-rev account.

http://techsupport.on-rev.com/napthaTest.png

naptha.png

Now, you should notice that if you however over the image, it changes from an arrow to a text selection icon.

You will then be able to copy & paste the text to your hearts content. Simple.

Screen Shot 2014-05-21 at 16.10.22.png

(mind = blown!)

Not only is this a great extension for extracting LiveCode scripts, but if you are interested in design work (e.g.Photoshop) and you want to replicate an image that contains text, open the source image in Chrome and you will be able to copy the required text directly.

Screen Shot 2014-05-21 at 16.08.34.png

selecting text in any image is easy

Another neat feature, that I discovered when writing this post, is that you have the ability to automatically remove text from images!!!! Simply select the text you wish to remove, right click —> Translate—>Erase Text….. Wow!

cool.gif

:O

I do have to admit, that although this has completely revolutionized working with text heavy images for me, it does have a few quirks (e.g. wrong character returned, characters not recognised) but even with these quirks I will not be removing it any time soon. I’m sure things will only get better.

Hopefully you will find this Chrome extension useful and, if you do decide to use it, please let me know in the comments below. I would also love to hear from you if there is anything specific that makes you go “urggh…..” when either communicating with the users of an app you’ve created or generally trying to find answers to any scripting issues you have.

read more
Neil RogerIntroducing the new LiveCode stack file formats…JPEG & PNG?

Eating Our Own Haggis

by Mark Waddingham on May 29, 2014 15 comments

My turn to blog has come around again and I thought today that I’d spend some time talking about a project I’ve been working on (quietly, in the background) for a while now.

As it stands LiveCode is a slightly different beast from most other programming languages and environments in that the LiveCode Language is tightly coupled to what you might call the LiveCode Framework. This LiveCode Framework is the functionality and object model you have access to when coding in the LiveCode Language – things such as stacks, controls, the message path and such. This integration is very tight (monolithic, one might say) and is quite different from more traditional environments such as Java and C.

The Java (and C) model is more along the lines of – you have a compiler, something capable of running the output of the compiler (virtual machine or the processor itself) and a very simple / low-level collection of functionality (control structures and basic types) which constitutes the language. In this model everything else is implemented in the same language (for the most part anyway) and provided to application programmers through packages (or libraries). The neat thing about this model is that you don’t have to leave the language to ‘extend’ the language, or indeed implement the majority of functionality that you expect from the environments. Perhaps crucially, if you can code in that language, then you can (essentially) extend the language (albeit through the generic function call / object style syntax we all know but perhaps are not great fans of – there must be a reason you like LiveCode, right?).

Indeed the state of affairs with LiveCode (as it stands) very much creates a rift – there is the engine implemented in C++ where the majority of the functionality we depend on is, and there is then the LiveCode Language which sits on top. If you can program in C++ then great, you can write externals or even submit patches to the engine itself; but if you do not program in C++ (or, indeed, do not have the time nor inclination to learn to program in C++) you are, to a certain extent, limited to what the engine gives you.

Wouldn’t it be great if you could for all intents and purposes extend the engine without ever leaving the LiveCode language?

I certainly think so and thus we come to the project I want to talk about. The ultimate goal of this project is nothing less than to reduce the C++ footprint of the engine to a core script compiler, virtual machine and basic type system with everything else being implemented in LiveCode itself (and who knows, perhaps it might even be reduced further over time – LiveCode implemented completely in LiveCode itself?). Of course, it is going to take quite a while to reach this goal, but the seeds are there and have been growing for a while – thus far principally through the refactoring work our team has been undertaking as part of LiveCode 7.

So, what does this actually mean for LiveCode developers as a whole?

Well, there will be a new dialect of LiveCode in which you will be able to write things called extensions. An extension will (in the first instance) either be a library or a widget.

Libraries are collections of commands and functions that integrate into the engine in exactly the same way as engine commands and functions do (the only caveat being initially is that you will be restricted to generic function / command call syntax to access them – full and proper syntax bindings will have to wait until Open Language is born).

Widgets are collections of commands, functions and event handlers – these will be used by a new control type widget and allow you to create you own controls which look, feel and act as if they were in fact part of the engine itself. Indeed, widgets will be very familiar to anyone who has ever written a control in Visual Basic, Delphi, or derived a new control from the base control class in any of the multiplicity of C++ GUI frameworks. This idea of controls is different from the aggregate style of custom control we currently see in LiveCode – rather than using a container in which you put other controls you instead get a ‘paint’ event and all the basic interaction events you need to craft your control entirely the way you want. To help you do this, you’ll also have access to an array of functionality crafted for the task – most importantly, you’ll be able to use a collection of syntax that provides 2d vector drawing capabilities along the lines of the HTML5 Canvas, or CoreGraphics library to draw your widgets.

I mentioned above that this will be based upon a ‘new dialect’ of LiveCode (I’m currently calling it LiveCodeish) but this shouldn’t cause alarm bells (hopefully, at least). Essentially the dialect will be a distilled form of the current LiveCode core syntax and semantics – this syntax will be cleaned up and its functionality will be much better defined (for example, getting rid of auto-conversion of arrays to empty strings and ‘fixing’ the non-standard ‘for x to y’ loop we have). The main aim of this clean up is to ensure we have a solid, predictable, reliable and completely defined base to work from without having to worry about any hangovers from the (very much organically evolved) past.

[ I think it is important for me to mention is that we do not intend there to be two LiveCode languages – the language you use for extensions (what I’m calling LiveCodeish) and the language you use in object scripts. It is our intention that there will be one, and only one, LiveCode – the object script language will also move to LiveCodeish, once we’re happy we’ve got LiveCodeish right (and don’t worry, when LiveCodeish does arrive at the LiveCode script level your existing scripts will all continue to run as they do now and you’ll be able to translate them automatically over time as needed with the script translation tool we are planning as part of the syntax cleanup project that will be enabled by Open Language). ]

There are perhaps three aspects of this proposed new LiveCodeish language which deserve mention.

The first is that this new dialect will provide the ability to directly hook into native code through binding to functions in native code (whether that be Java, Objective-C or C/C++) thus, hopefully, eliminating the need to write ‘glue-code’ externals and, again, making extending LiveCode much more accessible to anyone that can code in LiveCode rather than those few who can, or have the time to delve into these lower-level environments.

The next is that it will (eventually) be typed in a very natural way. You will be able to declare variables and handler parameters as having a given type (by default their type will be any). Whenever you try to assign a value to the variable the engine will attempt to convert it to the appropriate type and only throw an error if this is not possible. For example a variable with an integer type can have an integer put into it directly, a real number can be put into it after its been automatically rounded, and even a string can – as long as the string can be converted to an integer. This simple ability will mean that it will be easier to write ‘correct’ code – you’ll be able to much more easily debug things where it could be type-mismatches that are causing errors. It also means that (in the future) suitably typed code will run more efficiently – for example if you have an integer variable then that can be much more efficiently represented internally than a variable which can hold any type.

The third thing about LiveCodeish which is quite different from normal LiveCode scripts is that there is no message path – well, the message path is there, it’s just that command and functions in extensions do not sit in it. This is exactly the same situation as current engine commands and functions – they are bound at compile time. This not sitting in the message path does not mean that extensions have no access to it, quite the reverse as they will have access in the same way as engine syntax does – you will be able to send messages to objects through the message path just as the engine can. This slight change in perspective brings LiveCodeish much closer to more ‘traditional’ languages – and means that over time a much larger range of optimization potential becomes available (as things are more static in this world – dynamicity is great, except when you want to optimize at compile time!). Indeed, I can see no reason that LiveCodeish should not be eventually compilable to native code with performance at a level where the decision to code something in C or LiveCodeish due to that metric is a non-issue – LiveCodeish will be amply able.

So, there’s been a lot of words here so far about what will be but not many examples. We’re not quite at a point yet where we have something to show along these lines (although it is my principal project right now), but what I can do is give you a theoretical example of what a piece of (useful!) (untyped) LiveCodeish might look like. Here follows a potential future example LiveCodeish script for adding support for the ‘aspell’ library (note that this code might never actually run, it is still somewhat thought-experiment syntax!):

 library com.runrev.aspell
external function new_aspell_config() is pointer from “aspell”
external command aspell_config_replace(pointer, cstring, cstring) from “aspell”
external function new_aspell_speller(pointer) is pointer from “aspell”
external command delete_aspell_config(pointer) from “aspell”
external function aspell_error(pointer) is integer from “aspell”
external function aspell_error_message(pointer) is cstring from “aspell”
external function aspell_speller_error_message(pointer) is cstring from “aspell”
external command delete_aspell_can_have_error(pointer) from “aspell”
external comamnd delete_aspell_speller(pointer) from “aspell”
external function to_aspell_speller(pointer) is pointer from “aspell”
external function aspell_config_retrieve(pointer, cstring) is cstring from “aspell”
external function aspell_speller_check(pointer, cstring, integer) is integer from “aspell”
external function aspell_speller_suggests(pointer, cstring, integer) is integer from “aspell”
external function aspell_word_list_elements(pointer) is pointer from “aspell”
external function aspell_string_enumeration_next(pointer) is pointer from “aspell”
local sSpeller command spell_set_dictionary_language pLanguage local tConfig put new_spell_config() into tConfig aspell_config_replace tConfig, “lang”, pLanguage aspell_config_replace tConfig, “encoding”, “utf-8” local tNewSpellerOrErr put new_aspell_speller(tConfig) into tNewSpellerOrErr delete_aspell_config tConfig if aspell_error(tNewSpellerOrErr) is not 0 then local tErrorMsg put aspell_error_message(tNewSpellerOrErr) into tErrorMsg delete_aspell_can_have_error tNewSpellerOrErr throw tErrorMsg end if if sSpeller is not 0 then delete_aspell_speller sSpeller end if put to_aspell_speller(tNewSpellerOrErr) into sSpeller end spell_set_dictionary_language function spell_get_dictionary_language return aspell_config_retrieve(aspell_speller_config(sSpeller), “lang”) end spell_get_dictionary_language function spell_check_word pWord local tResult put aspell_speller_check(sSpeller, pWord, the number of characters in pWord) into tResult if tResult is -1 then throw aspell_speller_error_message(sSpeller) end if return tResult is 1 end spell_check_word function spell_check_not_word pWord return not spell_check_not_word(pWord) end spell_check_not_word function spell_suggest_spellings pWord local tResult local tSuggestions put aspell_speller_suggests(sSpeller, pWord, the number of characters in pWord) into tSuggestions if tSuggestions is 0 then throw aspell_speller_error_message(sSpeller) end if local tElements put aspell_word_list_elements(tSuggestions) into tElements try repeat forever local tSuggestedWord put aspell_string_enumeration_next(tElements) into tSuggestedWord if tSuggestedWord is empty then exit repeat end if if tResult is empty then put return after tResult end if put tSuggestedWord after tResult end repeat finally delete_aspell_string_enumeration tElements end try return tResult end spell_suggest_spellings

Here you see a collection of functions and commands which in the current world would have to be implemented in C and loaded in an external but in the new world you won’t need to touch C at all.

Now, the above aspell library is just commands and functions so from LiveCode (object) scripts you’d call them with expressions such as spell_suggest_spellings() – this isn’t very LiveCode-like and isn’t really what we want. However, this is where the Open Language project comes in and I’ll talk about how that project impacts LiveCodeish in another post.

There’s one final thought I’d like to finish with. If you look at the above example script it is clear that it is pretty much the same as the current object scripts we write everyday except for the ‘external’ handler declarations at the top; thus a valid question would be to ask ‘Why not just develop LiveCodeish as an updated form of object scripts and we can just put this stuff in the library stack or backscript?’. This is certainly a fair question if you are thinking within the current LiveCode Framework but that’s missing the point of LiveCodeish. LiveCodeish is aiming to be something much more general than a language which can be used in a LiveCode object script (which requires the notion of a LiveCode object to exist to begin with!), it is a distilled form of current LiveCode syntax and semantics which have no dependence on any framework nor any structures imposed upon it apart from those necessary to be a (minimal) programming language. If all goes well then it will be something that can be used to write the LiveCode Framework itself from the ground-up – we will get to eat our own haggis in totality.

read more
Mark WaddinghamEating Our Own Haggis

Extending the refactored engine – Properties

by Ali Lloyd on May 28, 2014 7 comments

One of the main goals of the refactoring project was to increase the clarity and extensibility of the LiveCode engine, by cleaning up and modularising the script execution code. The project has made it easier than ever to contribute to the development of LiveCode.

One of the areas of syntax in which this is particularly visible is that of properties. The setting and getting of properties is now largely table-driven. Say you want to add ‘myProperty’ as a global boolean property. Here is how it would be done

1) Add your property to the property enum type

The file ‘parsedef.h’ contains all the enum types associated with livecode syntax. For internal reference, ‘myProperty’ needs a numerical value, so you would just add P_MY_PROPERTY to the Properies enum.

2) Add ‘myProperty’ to the table of syntax tokens.

The file ‘lextable.cpp’ contains all the strings of LiveCode’s reserved words in various contexts. The factor table is where all the tokens for properties are defined. In this case, we would add the line

{"myProperty", TT_PROPERTY, P_MY_PROPERTY},

This associates the token with its type (property) and the enum value added in step 1. Make sure it is in alphabetical order! Script parsing uses the alphabetical ordering to speed lookup, so any mistakes will cause unexpected errors.

3) Add to the property info table

The property info table, kMCPropertyInfoTable, is located at the top of the file ‘property.cpp’. We would add

DEFINE_RW_PROPERTY(P_MY_PROPERTY, Bool, <Module>, MyProperty)

where <Module> is the name of the module in which the property should reside. This adds all the relevant information for the engine to be able to execute the relevant property setters and getters.

4) Implement the functions

The final piece of the puzzle is to implement the following two functions:

MC<Module>GetMyProperty(MCExecContext& ctxt, bool& r_value)
MC<Module>SetMyProperty(MCExecContext& ctxt, bool p_value)

All being well, this is enough to get the line ‘set the myProperty to true’ in LiveCode to execute the C++ code in the body of MC<Module>SetMyProperty(MCExecContext& ctxt, bool p_value), with p_value equal to true.

In the enhancement requests section of the LiveCode forums, Dar Scott recently suggested having properties of “opened things” (i.e. sockets, processes and files). This proved to be relatively simple to add to the engine, and can be seen on GitHub at https://github.com/runrevali/livecode/tree/feature_pseudo-object_props.

I have implemented the following examples:

the rect of screen 
the openmode of file|process 
the name of socket 

Notice that the last example is merely an example and not actually useful at all (it just returns the name you put in, or throws an error if the socket is not found). The first example, although equivalent to ‘line of the screenrects’, is an example of the kind of syntax that will be available with Open Language. However it is not a waste of time to implement pseudo-object properties now – it will save some effort later on when Open Language is implemented. Getting the openmode (read/write/update/append etc) of a process or file is, I believe, not currently possible, at least not directly.

The idea is just to have as a separate type of chunk expression, the pseudo-object, which behaves similarly to object chunks. There are no compound pseudo-objects (yet); the only way they parse correctly is in the form ‘the
of [screen|socket|file|process] ‘.

The framework has been set up so that more pseudo-objects can be added if necessary. Every pseudo-object needs:

– A property table, and function MC<Module>GetPropertyTable() that returns it,

– A ‘get object’ function, MC<Module>GetObject, that returns the relevant pseudo-object from the expression (eg the socket from the socket name, the screen from the screen index)

– A template function which calls the appropriate getters and setters

The implementations of these should be fairly easy to copy, see for example the file exec-network-socket.cpp for the implementations of the first two, and for the third exec.h, (search for MCSocketPropertyThunk) which contains the macros and templates – the complex systems of levers and pulleys that makes it work.

If the infrastructure of your pseudo-object is already there, you can add properties to it in much the same way as for the global properties described above, but adding the appropriate incantation to the pseudo-object’s property table. See MCScreenGetRect for a simple example, or MCProcessGetOpenMode for an example using an enumerated string type.

If you’re thinking of contributing to the engine, go to the Engine Contributors LiveCode forum at forums.runrev.com to discuss your ideas with us and other contributors.

read more
Ali LloydExtending the refactored engine – Properties

LiveCode for Tiger Moms

by Hanson Schmidt-Cornelius on May 23, 2014 3 comments

Over the last few years, more information has been emerging in the media, contrasting differences in education practices between Asian and Western parents and guardians, with books being published and reports appearing in prestigious journals. I do not intend to poke around in a bees nest here and will leave judgement on child education to the respective parents and guardians. 

What I do offer is an insight into how LiveCode can assist would be Tiger Mothers, parents and guardians who would like to raise their children’s mental maths ability and self-esteem.

In most societies, mathematics is part of an educational curriculum and there are a number of tested and proven approaches to teach this and encourage sprogs to enjoy their learning. However, especially when it comes to learning the basics of manipulating numbers and using mathematical operators, you may come across a degree of resistance.

Maybe this is because a certain games console is being neglected or there is a lack in agreement on the importance of being able to add a couple of numbers together. On the other hand you may find yourself with a child who is just purely bored with the level of mathematics offered at school and requires more challenging content. And no, the latter kind of children are not just fabled beings, they do actually exist and can be a challenge to work with.

There are of course applications that teach maths, and there are text books that have problems upon problems your kids are encouraged to indulge in. These tools are limited by what the application designers consider appropriate or by the number of equations one can squeeze on the page of a textbook. As most parents/guardians will know, children develop at different speeds, and motivation can be a balancing act between joy and tantrums.

This is where LiveCode comes in. Properly applied, LiveCode can help you emerge victorious from any battle and empower you to generate an endless numbers of equations that are at the right level for your child.

And of course the answers are also provided, allowing you to keep your street cred. Children have a miraculous tendency to remember events where you display any sign of weakness, and they utilize this knowledge to maximize their advantage in the next round of homework activities.

The code in this blog is a mathematical problem generator that can be placed in the script of a button control and modified at will. There is no woolliness in the code, only functionality that serves the purpose of generating equations for endless fun at learning.

You can of course modify the code to create your own stack that populates the configuration information with the appropriate variables and outputs the problems in a more interactive fashion. If you are really adventurous, why not ask your child to update the code for you, teaching them to build their own learning aids. 

I have added comments after the lines of code that are intended to be updated. These lines set variable values that control how the problems are generated:

1. tOperators stores a list of operators that should be used in the equations.

2. tInputRange1 defines the range of the first number in the equations.

3. tInputRange2 defines the range of the second number in the equations.

4. tOutputRange specifies the range of valid result values.

5. tAllowReal is a flag that determines whether or not the output can be a floating point number.

6. tProblemCount defines the maximum number of equations that are to be generated.

on mouseUp
   local tOperators, tInputRange1, tInputRange2, tOutputRange, tProblemCount, tAllowReal
   local tProblems, tProblemIndex, tEquation, tOperator, tVariable1, tVariable2, tResult
   // Parameters to be updated.
   put "+,-,*,/" into tOperators // The operators that are used in the equations.
   put "-50,50" into tInputRange1 // The range of the first number in the equations.
   put "1,100" into tInputRange2 // The range of the second number in the equations.
   put "-500,500" into tOutputRange // The permissible result range.
   put false into tAllowReal // Are the results allowed to have floating point values (true/false).
   put "20" into tProblemCount // The number of problems to generate.
   put empty into tProblems
   repeat with tProblemIndex = 1 to tProblemCount
     put item random (number of items in tOperators) of tOperators into tOperator
     repeat with tTestValidity = 1 to 100
         put random (item 2 of tInputRange1 - item 1 of tInputRange1 + 1) + item 1 of tInputRange1 -1 into tVariable1
         put random (item 2 of tInputRange2 - item 1 of tInputRange2 + 1) + item 1 of tInputRange2 -1 into tVariable2
         // Do a bit of testing to ensure we do not violate some fundamental rules.
         if tOperator is "/" and tVariable is 2 then next repeat
         do "do" && quote & "put" && tVariable1 && tOperator && tVariable2 && "into tResult" & quote
         // Test if the answer is allowed to contain floating point results.
         if tAllowReal is false and tResult is not an integer then next repeat
         // Test if the answer is within the specified range.
         if tResult  item 2 of tOutputRange then next repeat
         put tVariable1 & tab & tOperator & tab & tVariable2 & tab & "=" & tab & tab & tab & tResult into tEquation
         // Check that we do not already have the new equation we generated.
         if tEquation is among the lines of tProblems then next repeat
         put tEquation & return after tProblems
         exit repeat
     end repeat
   end repeat
   put tProblems into msg
end mouseUp

The default settings, as shown in this code, were used to generate the output shown in the attached image. The output is written directly into the message box. This output can be copied and pasted into other applications for printing or other manipulation. I left a larger gap between the problems and the results. This allows the results to be covered up when the problems are being solved and revealed when the answers are being checked.

example-output

read more
Hanson Schmidt-CorneliusLiveCode for Tiger Moms

How to Create an App with no coding experience?

by Steven Crighton on May 21, 2014 7 comments

A little over a year ago, and before I had discovered LiveCode, I asked my best friend Google this very question …How to create an app?

I found myself having lots of ideas both good and bad, and a serious desire to launch my own app, but how on earth could I achieve it?

I have a background in web development, design, online brand management and digital marketing, I am certainly not an app developer.

read more
Steven CrightonHow to Create an App with no coding experience?

LiveCode Global Jam: May 23 and 24

by Richard Gaskin on May 16, 2014 3 comments

Many open source projects have “global jam” events to rally their community around specific initiatives, and in the LiveCode world we have a big task ahead of us: testing LiveCode 7.0.

This first LiveCode Global Jam will take place May 23 and 24, with the goal of bringing as many interested LiveCode fans together to make a difference with one of the most ambitious LiveCode versions ever.

Version 7.0 includes a wide range of new features, including not only Unicode, but also folding in the OS X Cocoa support and more. With so much going into it, it can become a solid reference version for all of our work with LiveCode going forward – provided we take the time to test it thoroughly before release.

The theme of this first LiveCode Global Jam is “7th Heaven”, sharing a vision with the community for a new version that’s the most capable and stable version ever. To make this happen we’ll need as many people testing it as we can get – and that’s where you come in.

If you can set aside even just an hour during the Global Jam to help test with your projects, it’ll help us all a lot.

Prior to the Global Jam we’ll be providing testing guidelines so you can test copies of your stack files safely, and if you find any errors we’ll include tips for delivering the type of report the dev team can act on quickly. Additionally, we’re putting together a team of volunteers to provide live support for testers, so if you have trouble pinning down a reproducible recipe for your bug report you’ll have people you can contact to help. While we’re submitting bug reports, the team at RunRev is committed to focusing on fixing any issues you find as they come in, in as close to real-time as possible.

But it wouldn’t be much fun if it was all work, so we also have two live Q&A video chats scheduled as well: LiveCode CEO Kevin Miller from Edinburgh and yours truly as LiveCode Community Manager from Los Angeles. The video chats will be held via Google Hangouts so you can submit questions there, and they’ll be recorded so you can watch any you miss later on YouTube.

For access to the event schedule, testing support contacts, and more, you needn’t look any further than your installed copy of LiveCode: the LiveCode Global Jam is being managed via RevNet, accessed through the GoRevNet plugin included in the Development->Plugins menu.

We have a preliminary version of the Global Jam edition of RevNet in place now, and as we get close to the event you’ll find RevNet updated to include the latest info.

If you’d like to volunteer to help provide support for testers, host a video chat of your own, or have any suggestions for other activities for the LiveCode Global Jam, please send me an email and let’s make it happen. Many thanks to all of you who’ve been testing LiveCode 7, and for those of you who can spare some time to test during the Global Jam.

Together we can make this new version of LiveCode one we can be especially proud to share with the world.

Richard Gaskin

LiveCode Community Manager

richard@livecode.org

read more
Richard GaskinLiveCode Global Jam: May 23 and 24

Multimedia on MacOS

by Panagiotis Merakos on May 15, 2014 23 comments

The current project I am working on is about multimedia on MacOS. It includes replacing all  multimedia functionality (in the player object, revVideoGrabber external etc)  in LiveCode to use the latest Mac APIs (AVFoundation, introduced in OSX 10.7). All these multimedia capabilities rely on the QuickTime/QTKit APIs. But Apple recently deprecated QuickTime APIs. This means that apps that use QuickTime will be rejected in the AppStore submission.

 So, after transitioning the existing Quicktime/QTKit code to AVFoundation, users should be able to submit a multimedia based app to the AppStore for their OS 10.7 customers and above.

 The problem is that the new APIs do not provide the same functionality as the original QuickTime API, so we must ensure that we will provide our users with the same feature set they are currently used to. For example, the player control bar. QTKit’s controller is broken in OSX 10.7+ and AVFoundation does not have a controller until OSX 10.9. This means that we need to write our own custom controller.  

 I have almost finished implementing the custom controller, at least as far as the functionality is concerned. It probably needs a bit more work to look prettier! 

Below are both the QTKit controller and our custom controller, as implemented so far. Note that the selection handles are broken in QTKit controller on OSX 10.7+

QTKit controller for multimedia playback
QTKit controller for multimedia playback

 

custom controller
Custom controller for multimedia playback

The next stage is to update the LiveCode player object and all other multimedia functionality in the engine to use the newest AVFoundation APIs, as well as to implement a QTKit/AVFoundation version of the revVideoGrabber, since it too relies on the deprecated QuickTime API.

read more
Panagiotis MerakosMultimedia on MacOS