Tag Archives: TI

Graphical chemical reaction analysis (Nspire Lua)

(By the way, don’t think that I’m talking about me at the third-person : this is a translation I’ve done of the original TI-Planet article 😉 )

Another exclusive TI-Planet program today!

Our dear member Adriweb, after releasing the Chemical Reaction analysis program for TI-83 + / 84 + ( http://tiplanet.org/forum/archives_voir.php?id=1308 ) , has now programmed its Nspire version ! This is a first on this calculator, especially as it profits from the main new feature offered by the OS 3 : Lua Scripting, like the program TabVar 3, presented yesterday.

This .tns document actually consists of two parts:

-> You run the program (TI-Basic) avancement() and follow the steps to provide information on the chemical reaction to be studied.

-> Go to the next tab and watch the table drawn in detail and in color (Nspire CX only) !

A screenshot?

1320062663avancementnspire.jpg

This program is open source and licensed under the Creative Commons BY-SA 2.0.

Source code : https://github.com/adriweb/Tableau-d-Avancement-LUA/blob/master/TableauAvancement.lua

Link the topic of TIPlanet (more info + download ….): http://tiplanet.org/forum/viewtopic.php?f=43&t=8385

Download link directly : http://tiplanet.org/index.php?mod=archives&ac=voir&id=3754

(Click on the “Telecharger” button)

TI-Planet.org : the website that creates smart programs !

By the way, Happy Halloween;-)

Save a high score (or anything) without cheating possibility !

In this tutorial we’re going to take a look at a pretty interesting feature of the TI-Nspire framework in Lua : save and restore any kind of data directly in Lua, that lets us playing around with a high score for a game or any other configuration data for a more complex program.

Example : You just released a wonderful game. You’d like to share it with your friends, that way they can challenge you thanks to your high-scores system. But how is that working?

The first way you could think of is to use the var API. Therefore, we save the high score in the document as a global variable (math variable).

Your high score system is done ! Hum … wait a second, one of your friend managed to score 10 000 000 points to your game ! What the heck ? He simply modified the global variable you’re using as an high score, since it’s freely accessible via a Calculator application. Here, it is not hard to cheat !

A second way is to protect the first one by using math.eval() which lets us launch any TI-Basic instruction, as the Lock one for example. Then, if we do like so :

math.eval("Unlock highscore")
var.store("highscore", highscore)
math.eval("Lock highscore")

our high score variable will be write protected. But, since Lock is a TI-Basic command, it can be launch outside the Lua program. Things aren’t going to be better.

What about looking for a specific Lua command ? Actually, there is var.monitor() that probes a specified variable and checks if this variable will be changed. If so, on.varChange() event is called. This lets us to control any variable changes.

Here is an example :

function on.create()
  if not var.recall("highscore") then
    highscore = 0
    var.store("highscore", highscore)
  end
  var.monitor("highscore")
end
 
function on.varChange(list)
  for k, v in pairs(list) do
    if k == "highscore" then
      if var.recall(k) ~= highscore then
        return 1 -- it is an external change, block modifications
      else
        return 0 -- it is an internal change, allow modifications
      end
    end
  end
  return 0 -- allow modifications of other monitored variables if any
end

This code will disallow any external modification of the highscore variable, with the following error message :

Cannot accept change : Invalid input

Obviously, if you have to do this for multiple variable, for example configuration data, don’t do this since it is a heavy and repetitive method …
It is at this moment that we take a look to the documentation. We can see two trivial events : on.save() & on.restore().
In fact, this event couple does exactly what we expected to do from the beginning !

Actually, when the widget get closed (when we close the document, or copy/cut the widget) the on.save() event is called. You have to define on.save() to make it return any kind of value (boolean, number, string, table etc …). The next time the widget will open (when we open the document, or paste the widget), the on.restore() event will be called, with the data returned by on.save() as the parameter !

Here we are, easy-going :

function on.save()
  return highscore
end
 
function on.restore(data)
  if type(data) == "number" then
    highscore = data
  end
end
 
function on.create()
  if not highscore then
    highscore = 0 -- first time we initialize highscore
  end
end

Concepts and Basics

This part will explain you how the Lua actually works inside the OS and help you to figure out what you’re doing when you write a script for the TI-Nspire. It is recommended to have some basics on Lua programming or some knowledge of event-driven languages, but keep in mind that it is not required.

The Lua is an interpreted script language which means that it isn’t as fast as ASM/C programs, but is still better than the TI-BASIC. One good thing is that this language is in a complete harmony with the OS with basic events and a powerful graphic context.

Lua is normally a sequential script language. For example, when we use the print() command to display a value, we can easily guess when the command will be run in the script. Here’s an example :

a = 1
print(a)
a = a + 1
print(a)

Output :

1
2

Nothing special. However, on the TI-Nspire, Lua has a completely different approach. We meet this approach with high-level programming or with object-oriented languages (like C++, C#, …). In those languages, we don’t have the ability to control the flow/execution of any function. Yes, it can be quite strange to hear that, but it’s the way it is. Are we going to learn a language that doesn’t do what we tell it to do ? Well, in a way, yes.

But don’t worry ! We’re here to learn how to cross this quite unstable bridge ! A wonderful world is on the other side.

First of all, you have to “change team”. As in before, you were the boss, this means you used to tell the machine to compute 1 + 1 and it would proudly output “2”. Now, you are a worker. A task authorization is given to you, thus, you explain to the machine how to do this work. Actually, those “authorizations” are called events. When the event is called, you can do what ever you want. Here is a pseudo-code explaining what to do when the “Cook” event is called :

function Cook()
	organize_the_bench()
	cut_ingredients()
	assemble()
	heat_up()
	serve()
end

You can easily understand that you won’t cook when you get the job. You’ll wait for your boss’ order ! Well, it is exactly the same thing between the TI-Nspire and you. But this time, the TI-Nspire framework is the boss. Everything is event-based.

In a nutshell, our functions have to be called by the TI-Nspire. But how to be sure that they will be executed ? It is the moment to look at the Events list. When an event is fired, the TI-Nspire gives zero, one or multiple parameters (“arguments”) that we can use in our function. This lets us know, for example, which key has been pressed, because when the TI-Nspire executes the charIn(ch) event, it gives also a string as an argument corresponding to the key. However, when the enterKey() event is fired, no argument is given.

Before, in a non-event-based language (like BASIC, C, PHP …) we used to program like this :

-- Init Constants here
...
k = 0
while k == 0 do
	k = getKey()
end
if k == 72 then
	-- do something
end

Now, it looks like that :

-- Init Constants here
...
function on.charIn(ch)
	if ch == "7" then
		-- do something
	end
end

We hope you understood that very important part…

 

Let’s go to Part 2 now !