TI-84 Python development sample

Preparation (optional)


Get sample code from GITHUB here

Open Pycharm (or another editor) and create a project from the GITHUB link
Tip: close all projects first

There are 2 files for the mastermind project: MASTR002.PY and test\MASTR002.py
The one in test\ is used for unit tests

Install the emulator software, see howto here

Deploying a .py file on the TI-emulator

Start the TI-Smartview emulator

Get the contents

Now you can copy the file MASTR002.PY to the emulator with drag and drop:

You’ll get the following dialog box:

Now the MASTR002.PY is listed and ready to run

Now you can run MASTR002 on the TI-emulator

To run the program, click on Y=

Now you can play the game as long as you want!

After ending the game you can click 2nd quit

and then GRAPH (red below)

TI-84 programming Python – Mastermind

In this project you’ll learn how to adapt source-code to TI-84.
I’ve used this code as a base: Mastermind

The game
If you want to play the game you have to know the rules of Mastermind.
There are 6 colors, each of them have a different number:
1 – RED, 2 – GREEN, 3 – YELLOW, 4 – BLUE, 5 – BLACK, 6 – ORANGE
Example: RED YELLOW ORANGE BLACK —> 1 3 6 5

After entering your code (for instance 1 1 2 2) you’ll get back feedback with two characters:
R – color and position is OK
W – only the color is OK

The source code

I’ve checked the sample program in in Github, file MASTR002.py. I’ve made several commits with comments to make it easier for you to follow the steps.

There were several challenges to solve.
The “random” functionality of the TI-84 lacks a function “shuffle”, so I had to rewrite the code like this:

Original code:
random.shuffle(colors)
passcode = colors[:4]
Changed code:
col1 = random.randrange(1, 6)
col2 = random.randrange(1, 6)
col3 = random.randrange(1, 6)
col4 = random.randrange(1, 6)
# passcode = colors[:4]
passcode = []
passcode.clear()
passcode.append(colors[col1])
passcode.append(colors[col2])
passcode.append(colors[col3])
passcode.append(colors[col4])

You see, quite a change! In the first part (col1..col4) the variables are filled with a random number between 1 and 6. In the second part, the table passcode is filled with the generated codes (col1..col4)

Then, there was this problem with the display: the display of the TI-84 is quite small.
So, I’ve defined a variable called dottedline and initialized it with a much smaller value.

BEFORE
print("-----------------------------------------")
print("\t      MASTERMIND")
print("-----------------------------------------")

AFTER
dottedline="------------------------"
print(dottedline)
print(" MASTERMIND")
print(dottedline)

TESTING and REFACTORING

While testing the mastermind.py script I discovered that the setting of the guess_flags was not always correct.
Steps to improve it:
Take the original code and make a function out of it:

# Function to set the guess_flags
def setGuessflags(guess_flags, turn, code, colors_map, passcode):
    dummy_passcode = [x for x in passcode]
    pos = 0
    for x in code:
        if colors_map[x] in dummy_passcode:
            if code.index(x) == passcode.index(colors_map[x]):
                guess_flags[turn][pos] = 'R'
            else:
                guess_flags[turn][pos] = 'W'
            pos += 1
            dummy_passcode.remove(colors_map[x])
    return guess_flags

Test the function “setGuessflags” to see if it works like before.
Afterward: implement a simpler version of setGuessflags

Build unit tests first, check Stackoverflow how to do that:

import unittest
from MASTR002 import setGuessflags
# https://stackoverflow.com/questions/52013612/python-unittest-does-not-run-tests

class Mastr002TestCase(unittest.TestCase):
    def test_setGuessflagsRed(self):
        chances = 8
        passcode = []
        passcode.append(1)
        passcode.append(6)
        passcode.append(2)
        passcode.append(5)
        turn=1
        guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
        guess_codes = [['1', '6', '2', '5'] for x in range(chances)]
        newguessflags = setGuessflags(guess_flags,turn,guess_codes,passcode)
        self.assertEqual(['R', 'R', 'R', 'R'], newguessflags[1])

    def test_setGuessflagsRedWhite(self):
        chances = 8
        passcode = []
        passcode.append(1)
        passcode.append(6)
        passcode.append(2)
        passcode.append(5)
        turn=1
        guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
        guess_codes = [['1', '6', '5', '2'] for x in range(chances)]
        newguessflags = setGuessflags(guess_flags,turn,guess_codes,passcode)
        self.assertEqual(['R', 'R', 'W', 'W'], newguessflags[1])

    def test_setGuessflagsNone(self):
        chances = 8
        passcode = []
        passcode.append(1)
        passcode.append(6)
        passcode.append(2)
        passcode.append(5)
        turn=1
        guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
        guess_codes = [['2', '2', '3', '3'] for x in range(chances)]
        newguessflags = setGuessflags(guess_flags,turn,guess_codes,passcode)
        self.assertEqual(['W', '-', '-', '-'], newguessflags[1])

    def test_setGuessflagsSimulation2262(self):
        chances = 8
        passcode = []
        passcode.append(2)
        passcode.append(2)
        passcode.append(6)
        passcode.append(2)
        turn=1
        guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
        guess_codes = [['1', '1', '2', '2'] for x in range(chances)]
        newguessflags = setGuessflags(guess_flags,turn,guess_codes,passcode)
        self.assertEqual(['-', '-', 'W', 'W'], newguessflags[1])

    def test_setGuessflagsSimulation4464(self):
        chances = 8
        passcode = []
        passcode.append(4)
        passcode.append(4)
        passcode.append(6)
        passcode.append(4)
        turn = 1
        guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
        guess_codes = [['4', '4', '4', '4'] for x in range(chances)]
        newguessflags = setGuessflags(guess_flags, turn, guess_codes, passcode)
        self.assertEqual(['R', 'R', 'W', '-'], newguessflags[1])


if __name__ == '__main__':
    unittest.main()

After successful unit tests the code looks like this:

# Function to set the guess_flags
def setGuessflags(guess_flags, turn, code, passcode):
    ii = 0
    passcodeItemChecked=[]
    for x in code:
        if (ii==turn):
           cc=0
           for codeitem in x:
               pp=0
               for passcodeitem in passcode:
                   # check if passworditem is already processed
                   toprocess = True
                   for pitem in passcodeItemChecked:
                       if pitem == pp:
                           toprocess = False
                   if toprocess == True:
                      if (str(codeitem)==str(passcodeitem)):
                         if cc==pp:
                            guess_flags[turn][cc] = 'R'
                         else:
                            guess_flags[turn][cc] = 'W'
                         passcodeItemChecked.append(pp)
                         break
                   pp +=1
               cc +=1
        ii +=1

    return guess_flags

Fine Tuning

After further testing I’ve discovered another smaller problem: I’ve forgotten to prioritize:
The most important are the RED colors (code and position).

So, I’ve added another Unittest (test first!):

    def test_setGuessflagsSimulation4464(self):
        chances = 8
        passcode = []
        passcode.append(4)
        passcode.append(4)
        passcode.append(6)
        passcode.append(4)
        turn = 1
        guess_flags = [['-', '-', '-', '-'] for x in range(chances)]
        guess_codes = [['4', '4', '4', '4'] for x in range(chances)]
        newguessflags = setGuessflags(guess_flags, turn, guess_codes, passcode)
        self.assertEqual(['R', 'R', '-', 'R'], newguessflags[1])



And changed (and tested) the method “setGuessflags”:

def setGuessflags(guess_flags, turn, code, passcode):
    ii = 0
    passcodeItemChecked=[]
    # check code and position
    for x in code:
        if (ii==turn):
           cc=0
           for codeitem in x:
               pp=0
               # check code and position
               for passcodeitem in passcode:
                   # check if passworditem is already processed
                   toprocess = True
                   for pitem in passcodeItemChecked:
                       if pitem == pp:
                           toprocess = False
                   if toprocess == True:
                      if (str(codeitem)==str(passcodeitem)):
                         if cc==pp:
                            guess_flags[turn][cc] = 'R'
                            passcodeItemChecked.append(pp)
                         break
                   pp +=1
               cc +=1
        ii += 1
    ii = 0
    # check code independent of position
    for x in code:
        if (ii == turn):
           cc = 0
           for codeitem in x:
               pp = 0
               # check code
               for passcodeitem in passcode:
                   # check if passworditem is already processed
                   toprocess = True
                   for pitem in passcodeItemChecked:
                       if pitem == pp:
                           toprocess = False
                   if toprocess == True:
                       if (str(codeitem) == str(passcodeitem)):
                           if cc == pp:
                               guess_flags[turn][cc] = 'R'
                           else:
                               guess_flags[turn][cc] = 'W'
                           passcodeItemChecked.append(pp)
                           break
                   pp += 1
               cc +=1
        ii +=1
    return guess_flags



Next challenges
Try to define more functions in the source code MASTR002 and test it with Unit-Tests


Try to implement Mastermind in another language like react.
You can see a sample here:
https://react.rocks/example/Mastermind

TI-84 Python programming – Introduction – simple Euro Calculator

TI-84 Python edition – hybrid programming

The Texas Instruments TI-84 Plus CE-T calculator has a special edition called “Python Edition”
It’s easy to develop Python programs for this system. 
I’m developing like this:
I develop the programs like normal python programs on a PC with an editor (in my case PyCharm and Notepad++).
To be able to test the program on a PC (multi-platform, hybrid) I’ve made the following design.

1. conditional support for imports from TI libraries, like this:
​try:
    from ti_system import *
except Exception as e:
     print (“no module ti_system”)

2. read and write data wrapped in functions with a hybrid implementation
For reading data TI uses recall_list
For writing data TI uses store_list
On a “normal” system without the ti_system library this will not work.
So, I made wrapper functions with exception handling, e.g.

def saveeuro(ieuro):
    xlist=[]
    xlist.append(ieuro)
  try:
      store_list(“1”,xlist)
  except NameError as e:
      saveEuroToFile(ieuro)
  return

See github for the sourcecode (or see EUROCHF.py below):
github.com/edleijnse/ti84python

EUROCHF.py
sample program to convert currencies (in sample from CHF TO EURO)
The EURO currency is stored and can be changed anytime.
On the TI-84 you can read (or set) the currency with STAT and L1

try:
  from ti_system import *
except Exception as e:
    print ("no module ti_system")
def euro2chf(initeuro):
  print("")
  try:
     neweuro = float(input("new euro value? (" + '{:.2f}'.format(initeuro) + "): "))
  except Exception as e:
     neweuro=initeuro

  euro= neweuro

  print("euro: " + '{:.2f}'.format(euro))
  print("")
  eurocount=float(input("amount euros "))
  print("amount euros: ", eurocount)
  chf=euro*eurocount
  print ("costs in CHF: " + '{:.2f}'.format(chf))
  return neweuro

def getEuroFromFile():
    try:
       file1 = open("eurostore.txt","r")
       storedeuro = file1.read()
       storedeuro = int(storedeuro)
       file1.close()
    except Exception as e:
       storedeuro = .95
    return storedeuro
def geteuro():
    try:
        xlist=recall_list("1")
        storedeuro = float(xlist[0])
    except NameError as e:
        storedeuro=getEuroFromFile()
    except Exception as e:
        storedeuro = .83
    saveeuro(storedeuro)
    return storedeuro
def saveEuroToFile(iEuro):
    file1 = open("eurostore.txt","w")
    file1.write(str(iEuro))
    file1.close()
def saveeuro(ieuro):
    xlist=[]
    xlist.append(ieuro)
    try:
       store_list("1",xlist)
    except NameError as e:
       saveEuroToFile(ieuro)
    return

initeuro=geteuro()
while True:
  try:
    stopnow = input("stop program (1=y)? ")
    if stopnow == "1":
       break
    initeuro = euro2chf(initeuro)
    saveeuro(initeuro)
  except Exception as e:
    print(e)

LINKS TI-PYTHON articles

https://www.tomshardware.com/news/circuitpython-powers-ti-84-calculator