Package: tivars
tivars_lib_pytivars_lib_pyis a Python package for interacting with TI-(e)z80 (82/83/84 series) calculator files, i.e. lists, programs, matrices, appvars, etc.Much of the functionality of this package has been ported over fromtivars_lib_cpp. However, a number of changes have made to the API to better suit Python's strengths and capabilities as a language (e.g. scripting).InstallationThe current release version isv0.8.2. All versions require Python 3.10+ to run.As a PackageInstall thetivarspackage from PyPI usingpip:pip install tivarsAlternatively, you can clone this repository ordownload a releaseand extract thetivarsdirectory to include it in your next project. Once downloaded, you can also usepipto install it locally.As a SubmoduleInclude this repository in your next project as a submodule usinggit submoduleor manually cloning and writing the following in.gitmodules:[submodule "tivars_lib_py"]
	path = path/to/tivars_lib_py
	url = https://github.com/TI-Toolkit/tivars_lib_py.gitThen, add the following to any file which importstivars:importsyssys.path.insert(1,'tivars_lib_py/')Check outthis toolfor an example.Unit TestingYou can run the test suite via__main__.py, or run individual tests found intests/withunittest. Tests for optional package extensions (e.g. PIL) will be skipped if the package cannot be found.Note that the PyPI distribution doesnotinclude the test suite.How to UseCreating varsEvery var file has two parts: aheaderand a number ofentries, where an entry contains the data for a single variable. Usually, var files contain just one entry; in these cases, there's not much distinction between a var and an entry for the purposes of messing with its data.To create an empty entry, instantiate its corresponding type fromtivars.types. You can specify additional parameters as you like:fromtivars.modelsimport*fromtivars.typesimport*my_program=TIProgram(name="HELLO")If you're not sure of an entry's type, instantiate a baseTIEntry:my_entry=TIEntry()If you want to create an entire var or just a header, useTIVarorTIHeaderinstead:fromtivars.varimport*my_var=TIVar()my_var_for84pce=TIVar(model=TI_84PCE)my_header=TIHeader()my_header_with_a_cool_comment=TIHeader(comment="Wow! I'm a comment!")Reading and writingVars can be loaded from files or raw bytes:my_var=TIVar.open("HELLO.8xp")# Note binary mode!withopen("HELLO.8xp",'rb')asfile:my_var.load_var_file(file)file.seek(0)my_var.load_bytes(file.read())Entries can be loaded from files or raw bytes. When loading from a file, you may specify which entry to load if there are multiple:# Raises an error if the var has multiple entries; use load_from_file insteadmy_program=TIProgram.open("HELLO.8xp")withopen("HELLO.8xp",'rb')asfile:# Offset counts the number of entries to skip; defaults to zeromy_program.load_from_file(file,offset=1)file.seek(0)my_program.load_bytes(file.read())Most entry types also support loading from other natural data types. Any data can be passed to the constructor directly and be delegated to the correct loader:my_program=TIProgram("Disp\"HELLO WORLD!\"")my_program.load_string("Disp\"HELLO WORLD!\"")my_real=TIReal(1.23)my_real.load_float(1.23)BaseTIEntryobjects, as well other parent types likeTIGDB, will be automatically coerced to the correct type:# Coerces to a TIProgrammy_entry=TIEntry.open("HELLO.8xp")Export a var as bytes or straight to a file:my_var.save("HELLO.8xp")# Infer the filename and extensionmy_var.save()withopen("HELLO.8xp",'wb+')asfile:file.write(my_var.bytes())Entries can be passed an explicit header to attach or model to target when exporting:my_program.save("HELLO.8xp")my_program.save()withopen("HELLO.8xp",'wb+')asfile:file.write(my_program.export(header=my_header).bytes())Any input data type can also be exported to:assertmy_program.string()=="Disp\"HELLO WORLD!\""assertmy_real.float()==1.23Data types corresponding to built-in Python types can be obtained from the built-in constructors:assertstr(my_program)=="Disp\"HELLO WORLD!\""assertfloat(my_real)==1.23Data SectionsVars are comprised of individualsectionswhich represent different forms of data, split across the header and entries. The var itself also contains the total entry length and checksum sections, but these are read-only to prevent file corruption.You can read and write to individual sections of an entry or header as their "canonical" type:my_header.comment="This is my (even cooler) comment!"my_program.archived=Trueassertmy_program.type_id==0x05Data sections can also be other entry types:my_gdb=TIGDB()my_gdb.Xmin=TIReal(0)assertmy_gdb.Xmax==TIReal(10)Each section is annotated with the expected type.ModelsAll TI-82/83/84 series calcs are represented asTIModelobjects stored intivars.models. Each model contains its name, metadata, and features; usehason aTIFeatureto check that a model has a given a feature. Models are also used to determine var file extensions and token sheets.For these reasons, it isnotrecommended to instantiate your own models.Other FunctionalitiesPILThetivars.PILpackage can be used to interface with PIL, the Python Imaging Library. Simply import the package to register codecs for each of the TI image types. You can then open such images directly into a PILImage:fromPILimportImagefromtivars.PILimport*img=Image.open("Pic1.8ci")img.show()TokenizationFunctions to decode and encode strings into tokens can be found intivars.tokenizer. Support currently exists for all models in the 82/83/84 series as well as the TI-73; PR's concerning the sheets themselves should be directed upstream toTI-Toolkit/tokens.DocumentationLibrary documentation can be found onGitHub Pages.The var file format(s) and data sections can be found in a readable format on therepository wiki. Much of the information is copied from theTI-83 Link Guide, though has been updated to account for color models.ExamplesYou can find more sample code inexamplesthat details common operations on each of the entry types. There are also examples for interfacing with popular external libraries (e.g. NumPy, PIL). Contributions welcome!