KrySA¶

Statistical analysis for rats.
A common translation of the word “krysa” is “a rat”, mostly considered a lower creature, but in fact a really cute and intelligent little rodent.
The idea behind KrySA is to make statistical software available even for the “rats” - people who can’t or don’t want to buy a commercial tool for statistics for whatever reason. KrySA is a free, open-source tool that anyone can afford!
- KrySA is released under GNU GPL v3.0 License. Please read the LICENSE.txt file.
Contents¶
Getting started¶
Warning
KrySA is still in pre-alpha, most of the features are buggy or not yet supported. Read Contributing section if you want to help speed up the process.
KrySA runs on Kivy framework, therefore it is possible to run it on any of available platforms for Kivy, mainly Windows, Linux and Mac with all required packages correctly compiled:
There’s no executable for KrySA yet, you’ll need to install it from source and run with Python until there is a release available.
Minimum system requirements¶
RAM | At least 256 MB |
Disk space | At least 400 MB free(*) |
Resolution | Minimum of 800 x 600 |
CPU | ? ? ? |
GPU | Anything with OpenGL 2.0 support should be enough |
Internet | Necessary for downloading requirements and updating |
*if installing from scratch
Installation¶
First of all you’ll need Python. To simplify the process use KivyInstaller on Windows, which will install Python together with Kivy. On other platforms use Kivy Installation page as reference.
Note
KrySA requires the latest version of Kivy. It’s available either as
daily-builds on ppa
or as the .whl
files uploaded on Google Drive.
If none of those are good, compile Kivy from source.
Then it gets a little bit harder with SciPy and NumPy because those need to be
compiled and it sometimes doesn’t work with Windows. For this case we will use
already compiled packages in .whl
files. You can find them either on pypi
or here. Choose packages for Python 2.7 (cp27). On Linux they should work
without issues with pip install <package>
.
pip install <path to package>.whl
Then install MatPlotLib. This is easy even on Windows:
pip install matplotlib
Getting KrySA¶
There are many ways how to get it, but basically you need to download it from the official repository.
Pip
KrySA is available on PyPi, simply type:
pip install krysa
and then run it with:
python -m krysa
Git
Clone the whole repository and be able to update KrySA when a new version arrives with a simple
git pull
.git clone https://github.com/KeyWeeUsr/KrySA
Zip
Click on the
Clone or download
button, download the zip file and unpack its contents.
When the repo clone(git/zip) of KrySA is ready, simply navigate into it and run:
python main.py
About docs¶
The documentation includes source with notes how most of the things work for example which widgets are connected, what’s needed to call to make a custom Task and other related stuff.
Each documented class or function/method will have a little source link on the right side. This will send you to its place in the code. In the code there are similar docs links (they’ll return you back) at the same place as it was for the source in modules’ documentation.
Project¶
As it’s obvious from the title, the main part of the application is a
Project which is a folder with a .krysa
file and some folders e.g.
for Data and Results. You are forced to create a Project
even with not being able to import data alone. It keeps your work at one place
and makes it simplier to Open and Save it.
Select File -> New -> Project
, navigate to a folder you want to save it to
and KrySA will create a <Project name>
folder there. Project’s name
can have only lowercase & uppercase ASCII and numbers.
Warning
Please do not manually edit any of the files, it may result in unexpected behavior and KrySA may crash
Open and Save¶
Open¶
To open already existing Project select File -> Open Project
and
then navigate to a folder with .krysa
file. Select the file with a click or
tap and press Open
.
Save¶
Each new Project is automatically saved in the beginning with an empty Data file and already created folders. Please do not remove any of them even if it’s nothing there.
To save changes made in a new Project select File -> Save Project
,
it will already know there’s an active project and save it in the same folder
without selecting where to save it.
Note
If there’s no active project, saving does nothing.
Data file¶
KrySA creates a single .sqlite
file which handles all the Data you
create. Although SQLite doesn’t limit its columns by default, KrySA uses this
option to prevent crashing caused by a user’s mistake of running a Task
expecting only numbers with a value of type TEXT.
Data¶
In the beginning there’s an empty Data file, which means we need to populate it.
Select File -> New -> Data
and name it. Data’s name can have only lowercase & uppercase ASCII and numbers. Then
create columns (same rules for the names) and input new values to them.
Remember, for each column you have to select a type of its values:
Type | Description |
REAL | Only numbers with a single . symbol (1.1 ) |
INTEGER | Only numbers without any special symbols |
TEXT | Non-limited value converting input directly to unicode |
Note
When an input box for the first value is added, the type of the column automatically locks to prevent values of different type in the single column e.g. REAL and TEXT.
Warning
Each column must have a unique name!
After the column is finished, you can Check & Lock
the values. It’ll check
if the values are the same as the column type and tell you if not. You can
always unlock the values later for example if the application tells you about
wrong values. When you’re finished, type Run
, it’ll run Check & Lock
for each available column. If all the columns pass the test, a new tab after
the Process Flow tab is created and then the application export every present
data to the Data file.
Each column in finished Data has an address you can access it later with in a Task.
Editing¶
Each cell in Data is clickable and editable in the limits of the column
type. Press <enter>
(<return>
) to confirm the edit, otherwise it won’t
change the value and only unfocus the cell.
Note
Edited cells aren’t automatically saved to Data file, how to save read in Open and Save.
Importing¶
Whenever you want to combine data from two or more Project s or just add additional tables from premade Data file, this is the way.
Select File -> Import Data
, navigate to .sqlite
file, select it with
a click or tap and press Import
. It will add another tab(s) containing the
data at the end of the panel.
Warning
Before importing check if the column names don’t collide, otherwise it may result in unexpected behavior and KrySA may crash.
Exporting¶
This will export all data you can see on the panel to a Data file which can be then accessed either with different editor or saved for later use in KrySA e.g. for combining data.
Select File -> Export Data
, navigate to a folder you want to put the
Data file to, select it with a click or tap and press Export
.
Results¶
Results are by default .png files in a resolution of 72DPI A4 page (595px x 842px) put in the results folder in the Project folder.
Note
Making a single file with all results is still under construction.
Process Flow¶
Nothing yet.
Task¶
This is the most important part of KrySA, it is the way of manipulating
Data values and reporting the result. Tasks are categorized by its
purpose and/or complexity into different groups e.g. Basic
.
Using a Task¶
Each Task needs values which it can use, otherwise it won’t run. When
the values are present, each column has an address starting with A
for the
first column. To select more than a single value, use :
character (e.g.
B1:AB2
):
. | A | B | C | ... | AA | AB | AC | ... | ZZ... |
1 | x | x | x | x | x | ||||
2 | x | x | x | x | x |
After the values are selected, pres Run
. Depending on the Task, it
can create new Data or a page in the Results panel.
Create a Task¶
Note
It’s good to peek in tasks.Task
.
KrySA uses Python for Task s. Each task according to its category(file) begins with a function named like this:
def <category>_<task>(*args):
This function sets the layout that is put into the Task popup, sets a
function that is called when user selects some options in the popup and opens
it. The Task s layout contains an option to select which Data
will be used in the following task, but you have to handle user’s input of the
address(A1:B2
).
def <category>_<task>(*args):
widget = SomeLayout()
task = Task(title='Title', wdg=widget,
call=['Title', <category>_<task>])
task.run = partial(<called function>,
task,
<widget containing address>)
It’s necessary to put into Task()
the layout and a link to itself. Layout
then can be accessed in the called function directly from arguments and the
link is used to append the used Task to list of Recent Tasks.
Then it’s necessary to write the <called function>
and handle its inputs.
Each Task must have some kind of output - new Data, modified
Data or a page in the Results:
def <called_function>(task, address, *args):
Each <called function>
takes at least two arguments task
and
address
, where task
is an instance of the main popup (so that you can
access the chosen Data) and address
is the widget with some kind of
string property.
To get the values from user’s input use the function task.from_address(), which is basically Body.from_address() accessed from within Task. The function takes two arguments - index of Data (returned in task.tablenum property) and string of address.
values = task.from_address(task.tablenum, address.text)
Values are returned as a simple list of everything selected no matter what the type it is. Example:
values = [0, 1.0, u'hi']
max(values)
>>> u'hi'
When you are finished, output the values e.g. into Results with task.set_page:
task.set_page('Count', str(len(values)), 'text')
Final functions would look like this:
def basic_count(*args):
widget = CountLayout()
task = Task(title='Count', wdg=widget,
call=['Count', basic_count])
task.run = partial(_basic_count,
task,
task.ids.container.children[0].ids.name)
task.open()
def _basic_count(task, address, *args):
values = task.from_address(task.tablenum, address.text)
task.set_page('Count', str(len(values)), 'text')
Contributing¶
There are three parts of the project you can contribute to, but only two of them require at least some programming skills (mainly in Python). Each part, however, requires a fully functional KrySA application.
Documentation¶
As the project is still in the beginning, there’s a lot of things to document
and to make screenshots of. If you have KrySA already installed, there’s a
docs
folder that contains the documentation.
The documentation is written in reStructuredText which you can test either in some online
editor (referencing files won’t work, obviously) or localy if you have already
installed Python. KrySA uses Sphinx for converting
reStructuredText to a html website. First install requirements from the .txt
file.
pip install -r docs-requirements.txt
To build the documentation use these commands in the docs
folder:
make clean && make html
Note
Extend the command with another &&
to e.g. automatically open a
browser with fresh index.html
file.
Please don’t break the formatting (max 79 characters in a single line) and fix the errors if any jumps out in Sphinx build.
Statistics¶
Hypotesis testing, factor analysis, averages, whatever part of statistics you think a user could find useful you can do two things:
Feature request
Open an issue in the GitHub repository describing the feature and its use case.
Pull request
Read the code, find out how it works and make a pull request to the GitHub repository with code that doesn’t break the Test Suite together with an example of how the new feature works.
Application¶
If you think the application might find your feature useful or that some behavior needs a fix, you are welcome to make a pull request. Before each pull make sure it is written in Python’s PEP8 style and that it doesn’t break the Test Suite. KivyUnitTest makes running the tests easier.
License¶
The Software¶
KrySA is released under the GNU General Public License (GPL, or “free software”).
This license grants people a number of freedoms:
- You are free to use KrySA, for any purpose
- You are free to distribute KrySA
- You can study how KrySA works and change it
- You can distribute changed versions of KrySA
The GPL strictly aims at protecting these freedoms, requiring everyone to share their modifications when they also share the software in public. That aspect is commonly referred to as Copyleft.
License details¶
The developed KrySA source code is by default licensed as GNU GPL Version 3.
KrySA also uses some modules/libraries from other projects. For example Python uses the Python License, Kivy uses the MIT License, SciPy and NumPy use the 3-clause BSD License, and MatPlotLib uses a license based on Python License.
All the components that together make KrySA are compatible under the GNU GPL Version 3. That is also the license to use for any distribution of KrySA binaries.
Your output¶
What you create with KrySA (e.g. Data file or Results) is your sole
property. All your other output, meaning images/graphs, tables, etc. including
the .krysa
files and other data files Krysa can write, is free for you to
use as you like.
That means the application can be used commercially by anyone to work on commercial projects, research, or for educational purposes.
KrySA’s GNU GPL license guarantees you this freedom. Nobody is ever permitted to take it away, in contrast to trial or “educational” versions of commercial software that will forbid your work in commercial situations.
Modules¶
KrySA¶
-
class
main.
Body
(**kw)[source]¶ The main layout for the application. It handles menu values, their appropriate functions, filtering of user’s input and functions for accessing Data file in
main.Table
.New in version 0.1.0.
-
_export_data
(selection, fname, *args)[source]¶ Exports all available Data (visible as tabs) as Data file into path selected in
Dialog
.New in version 0.1.1.
-
static
_extract_rows
(data)[source]¶ Extract values from
main.Table
‘s dictionary into a flat list.Example:
Data1 Data2 Data3 1 2.0 3 [u’Data1’, u’Data2’, u’Data3’, u‘1’, 2.0, 3, ...]
New in version 0.1.0.
-
_import_data
(selection, *args)[source]¶ Imports Data file from path selected in
Dialog
and puts it tomain.Table
.New in version 0.1.0.
-
_new_data
(*args)[source]¶ Opens a wizard for creating a new Data if a Project is available or shows a warning if it doesn’t exist.
New in version 0.1.3.
-
_new_project
(*args)[source]¶ Closes already opened Project if available and opens a dialog for creating a new one.
New in version 0.1.2.
-
_open_project
(selection, *args)[source]¶ Opens a Project from path selected in
Dialog
and imports Data file.New in version 0.1.7.
-
_save_data
(wizard, *args)[source]¶ Gets data from the wizard, puts them into
main.Table
and exports them into Data file.New in version 0.1.4.
-
_save_project
(selection=None, fname=None, *args)[source]¶ Saves a Project to path selected in
Dialog
and exports Data file.New in version 0.1.2.
-
static
about
(*args)[source]¶ Displays about page of the app and includes other credits.
New in version 0.1.0.
-
close_project
(*args)[source]¶ Clears all important variables, removes all Data available in
main.Table
and switches tomain.ProcessFlow
.New in version 0.1.0.
-
from_address
(table, address, extended=False, *args)[source]¶ Gets value(s) from
main.Table
according to the address such asA1
orA1:B2
. Values are fetched in the way that the final list contains even empty (u''
) values. It is not expected of user to use Task for strings and most of them won’t even run. To get non-empty values for a Task use for example Python’sfilter()
:values = filter(lambda x: len(str(x)), values)
This filter, however, will remain values such as
None
untouched.New in version 0.1.0.
Changed in version 0.3.5: Added extended options and a possibility to get
:all
values from data.
-
set_page
(task, result, result_type='text', footer='time')[source]¶ Creates a
main.PageBox
for a result. The header consists of the Task‘s name, the footer is by default the time when the result was created and the content depends on result_type which can be - text, image(path to image) or widget. If result_type == ‘widget’, result has to be an instance of a widget (obviously containing the output), e.g.:b = Button(text='my output') set_page('MyTask', b, result_type='widget')
Note
When exporting pages, everything is converted into images (pngs), therefore making fancy behaving widgets is irrelevant.
New in version 0.2.0.
Changed in version 0.3.2: Added tables as a result type.
-
-
class
main.
CreateWizard
(**kw)[source]¶ A popup handling the behavior for creating a new Data, i.e a wizard.
New in version 0.1.3.
-
class
main.
Dialog
(**kw)[source]¶ A dialog handling the behavior for creating or opening files e.g. Project or Data.
New in version 0.1.0.
-
class
main.
ErrorPop
(**kw)[source]¶ An error popup to let user know something is missing or typed wrong when console is disabled.
New in version 0.1.2.
-
class
main.
ImgButton
(**kwargs)[source]¶ A button with an image of square shape in the middle.
New in version 0.2.0.
-
class
main.
KrySA
(**kwargs)[source]¶ The main class of the application through which is handled the communication of other classes with getting an instance of the app via
App.get_running_app()
.Other than that, it holds important variables of Project, sql blacklist for Data file creating and updating or the application properties themselves.
-
class
main.
MenuDrop
(**kw)[source]¶ A list of
main.SizedButton
s displayed as a menu, where each button may create another menu depending on the function bound to it. The main menu is handled through a single instance ofmain.MenuDrop
which is instantiated beforemain.Krysa.build
function.Each click/tap on the menu button then assigns a value to it from
App.menu
dictionary according to its name in kv file.New in version 0.1.0.
-
class
main.
NewDataColumn
(**kw)[source]¶ A layout handling the behavior of type, values(
NewDataValue
) and some buttons for each new column in Data.New in version 0.1.4.
-
checklock
(disable, coltype, check, *args)[source]¶ Disables all cells in the column, then check them against a list of strings that could be used to corrupt Data file . If the check is done without an error, another check is made to protect against using an empty string
''
as a value, which if used inappropriately results in a crash.New in version 0.1.4.
-
static
free
(items)[source]¶ Frees all locked cells in the column except a column type. If a wrong type is used, removing the whole column is necessary. (protection against corrupting Data file)
New in version 0.1.4.
-
paste
(values, sep)[source]¶ Paste a value(s) from a user’s clipboard as a column values. A user can choose what kind of separator was used on the values, for example:
1 2 3 4 5 # (space) 1\t2\t3\t4\t # (tab) 1\n2\n3\n4\n # Unix-like new line character (<enter>/<return>)
If in doubt and your values were copied from a column (e.g. spreadsheet), use OS default, which will choose between
\n
(Unix-like) or\r\n
(Windows) new line separators.New in version 0.3.4.
-
-
class
main.
NewDataLayout
(**kw)[source]¶ A layout handling the behavior of
NewDataColumn
and some inputs for each new value in Data.New in version 0.1.3.
-
class
main.
NewDataValue
(**kw)[source]¶ A layout handling the behavior of inputs and button for each new value in Data.
New in version 0.1.4.
-
class
main.
PageBox
(**kwargs)[source]¶ A layout that includes Page widget together with transparent separator. It’s used for adding new results from Tasks.
New in version 0.2.0.
-
class
main.
PaperLabel
(**kwargs)[source]¶ A label with visual properties as a paper sheet.
New in version 0.2.0.
-
class
main.
ProcessFlow
(**kw)[source]¶ A canvas on which will be displayed actions for each Data related to them, such as used tasks connected with result of the tasks.
New in version 0.1.0.
(Not implemented yet)
-
class
main.
ResultGrid
(**kwargs)[source]¶ A black gridlayout, together with
main.Wrap
makes a table container for results that need a table.New in version 0.3.2.
-
class
main.
SideItem
(**kwargs)[source]¶ Supposed to be a part of settings, most likely will be removed/replaced.
New in version 0.1.0.
-
class
main.
SizedButton
(**kwargs)[source]¶ A button with width automatically customized according to text length of its siblings, which makes every sibling the same size as the one with the longest text string.
New in version 0.1.0.
-
class
main.
Table
(**kw)[source]¶ A view handling the behavior of the inputs from Data file. Separates the values from Data file according to its Data‘s column types into three Python categories - int, float or unicode and assigns an alphabetic order for each column together with row number to each value.
New in version 0.1.0.
-
clean
(*args)[source]¶ Removes all data from
main.Table
New in version 0.1.0.
-
-
class
main.
TableItem
(**kwargs)[source]¶ An item handling the behavior or each separate value in the
main.Table
such as updating/editing values in Data.New in version 0.1.0.
-
on_focus
(widget, focused)[source]¶ Makes sure the unconfirmed value is discarded e.g. when clicked outside of the widget.
-
update_value
(txt, *args)[source]¶ On
<enter>
(return
) key updates the valuesmain.TableItem.text
andmain.TableItem.old_text
inmain.Table
.New in version 0.1.0.
-
KrySA » Tasks¶
KrySA » Tasks » Basic¶
-
class
tasks.basic.
Basic
[source]¶ All Task s categorized as basic under one roof.
New in version 0.1.0.
-
static
_basic_count
(task, address, *args)[source]¶ Gets the values from address and returns the count.
New in version 0.1.0.
-
static
_basic_freq
(task, address, bins, limits, freq_type, intervals, *args)[source]¶ Gets the values from address and depending on the type of values dumps them either into bins of size 1 (integers) or into bins that consist of intervals (real numbers). Then according to the size of bins and limits of the frequency creates a table for chosen types of frequency.
May return a warning if intervals option isn’t checked for values containing real numbers:
IndexError: index max(<values>) + 1> is out of bounds for axis 1 with size max(<values>) + 1>
New in version 0.3.2.
-
static
_basic_large
(task, address, k, *args)[source]¶ Gets the values from address and returns the k-th value from the descending list of sorted values.
New in version 0.1.0.
-
static
_basic_max
(task, address, *args)[source]¶ Gets the values from address and returns a maximum.
New in version 0.1.0.
-
static
_basic_min
(task, address, *args)[source]¶ Gets the values from address and returns a minimum.
New in version 0.1.0.
-
static
_basic_small
(task, address, k, *args)[source]¶ Gets the values from address and returns the k-th value from the ascending list of sorted values.
New in version 0.1.0.
-
basic_count
(*args)[source]¶ Opens a
tasks.Task
with atasks.AddressLayout
that gets from user Data address.New in version 0.1.0.
-
basic_freq
(*args)[source]¶ (Not fully tested yet) Opens a
tasks.Task
with atasks.FreqLayout
that gets from user:- Data address
- type of values (interval for real numbers)
- type of frequency (absolute, relative or cumulative
- number of bins (optional)
- upper and lower limit (optional)
New in version 0.3.2.
-
basic_large
(*args)[source]¶ Opens a
tasks.Task
with atasks.SmallLargeLayout
that gets from user Data address and k variable representing the k-th value from the Task s output.New in version 0.1.0.
-
basic_max
(*args)[source]¶ Opens a
tasks.Task
with atasks.AddressLayout
that gets from user Data address.New in version 0.1.0.
-
basic_min
(*args)[source]¶ Opens a
tasks.Task
with atasks.AddressLayout
that gets from user Data address.New in version 0.1.0.
-
basic_small
(*args)[source]¶ Opens a
tasks.Task
with atasks.SmallLargeLayout
that gets from user Data address and k variable representing the k-th value from the Task s output.New in version 0.1.0.
-
static
KrySA » Tasks » Avgs¶
-
class
tasks.avgs.
Avgs
[source]¶ All Task s categorized as averages under one roof.
New in version 0.2.4.
-
static
_avgs_gen
(task, address, p, *args)[source]¶ Gets the values from address and depending on p (power) value returns either exceptional case for p == 0 (geometric mean), or value from the generalized mean’s formula.
New in version 0.2.4.
-
static
KrySA » Tasks » Manipulate¶
-
class
tasks.manipulate.
Manipulate
[source]¶ All Task s categorized as being able to manipulate data. A result after manipulation is a new data.
New in version 0.3.5.
-
static
_manip_append
(task, append_type, amount, overwrite, *args)[source]¶ Gets the amount of empty rows / cols to append from user and either returns a new, altered
main.Table
of selected one, or appends directly to the selected Table.New in version 0.3.6.
Changed in version 0.3.7: Added overwriting of selected
main.Table
-
static
_manip_sort
(task, sort_type, *args)[source]¶ Gets the values from address, sorts each column either ascending or descending and returns a new
main.Table
New in version 0.3.5.
-
manip_append
(*args)[source]¶ Opens a
tasks.Task
with atasks.AppendLayout
that gets from usermain.Table
, type of append and an amount of empty rows / cols to append.Note
Appending new columns don’t work for now. When such an action is possible, this note will be removed.
New in version 0.3.6.
-
manip_sort
(*args)[source]¶ Opens a
tasks.Task
with atasks.SortLayout
that gets from user the table which will be sorted and the type of sorting (Ascending or Descending).New in version 0.3.5.
-
static
-
class
tasks.
AddressLayout
(**kwargs)[source]¶ Simple layout that consists of single restricted input widget fetching only
[a-zA-Z0-9:]
values i.e. address.
-
class
tasks.
AppendLayout
(**kwargs)[source]¶ A layout that consists of a spinner with two values:
- Rows
- Columns
and a restricted input that allows only integers.
New in version 0.3.6.
-
class
tasks.
AvgsLayout
(**kwargs)[source]¶ A layout that consists of multiple restricted input widgets for address and p (power) value for the formula of generalized mean.
New in version 0.2.4.
-
class
tasks.
FreqLayout
(**kwargs)[source]¶ A layout that consists of multiple checkboxes and restricted input widgets for address, type of values, type of output frequency and limits of the input values.
New in version 0.3.2.
-
class
tasks.
SmallLargeLayout
(**kwargs)[source]¶ A layout that consists of multiple restricted input widgets for address and k value.
New in version 0.1.0.
-
class
tasks.
SortLayout
(**kwargs)[source]¶ A layout that consists only of a spinner with two values:
- Ascending
- Descending
The Task with this layout is using
tasks.manipulate.Manipulate._manip_sort
.New in version 0.3.5.
-
class
tasks.
Task
(**kw)[source]¶ A popup handling the basic choosing of Data from available Data file in the application.
New in version 0.1.0.
Changed in version 0.2.3: Placed into a separated module.
-
static
get_table_pos
(text, values, *args)[source]¶ Returns an index of selected
main.Table
from all available in the list.New in version 0.1.0.
-
recalc_height
(body, content)[source]¶ Recalculates the height of
tasks.Task
after a layout is added, so that the children are clearly visible without any stretching.New in version 0.3.2.
-
try_run
(*args)[source]¶ Tries to run a Task from the input a user specified and closes the popup. If no such an action is possible, it’ll show a popup with an error and leave
tasks.Task
opened.New in version 0.2.0.
-
static
KrySA » Tests¶
Tests run independently on each other, but not in a single python interpreter. After each test a fresh python is required (it won’t run as casual suite), so either run them like this one by one:
python test_<something>.py
or use KivyUnitTest to do it instead of you and better.