<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Scikit-oTree Tutorial
Welcome to the Scikit-oTree tutorial. This package aims to integrate
any experiment developed on-top of oTree, with the 
Python Scientific-Stack; alowing
the scientists to access a big collection of tools for analyse the
experimental data.
Step1:  Philosophy
1. The data must be processed only by the oTree deployment.
Scikit-oTree don't preprocess any data from the experiment. All the information
are preserved exactly as any traditional export from oTree; the project only
take this data and present it.
2. The environment for analysis must not be modified.
oTree uses some global configuration to make it run. Scikit-oTree don't store
any global configuration alowwing to load data from different experiments
without problems. All the oTree related processing always happen in an
external process.
3. Only one data type for the data.
The data are always presented as a 
Pandas DataFrame
Installation
To install Scikit-oTree you must has Python and PIP. You can found
a comprensive tutorial to install it here.
After that you only need to run
bash
pip install -U scikit-otree
Local - Loading the experiment
To load your experiment you need to provide 
the location of the oTree deployment. This is the 
same location where the setting.py lives.
Step2:  The previous code make a lot of things in background
Step3:  This is the traditional object that you
obtain in any oTree experiment if you
write 
python
from django.conf import settings
Now let's check some information about the experiment, for example
all the exiting oTree apps.
Step4:  or maybe you want to see all the sessiong configured
that uses all this apps
Step5:  Yikes! the app and the session has the same name. Let's check the full session configuration.
Step6:  Finally you can access <span class="text-info">any</span> content of the settings object ussing the attribute showed before. For example, maybe you want to see the "currency code"
Step7:  The Data
Lets check the oTree server data tab
As you can see 4 kind of data can be exported from any experiment. 
1. All app
This generates one DataFrame with one row per participant, and all rounds are stacjed horizontally. For Scikit-oTree this functionallity are exposed as all_data() method
Step8:  2. Per-App Data
These data-frame contain a row for each player in the given app. If there are multiple rounds, there will be multiple rows for the same participant. To access this information you need to provide the application name to the  method app_data()
Step9:  With the power of pandas.DataFrame you can easily filter the data
Step10:  Describe the data
Step11:  group by participant
Step12:  or check all the columns availables
Step13:  3. Per-App Documentation
The code 
python
    experiment.app_doc("matching_pennies") 
returns the full documentation about the data retrieved by app_data()
4. Time spent on each page
Time spent on each page
Step14:  <div class="alert alert-info lead">
    <h4>Note</h4>
    <hr>
    This only show a simple example in how to use <strong>pandas.DataFrame</strong> to understand more, please check 
    <br>
    <a href="https
Step15:  as you can see the only available app (as we see before) is the matching_pennies.
Lets extract the data
Step16:  also for convenience the sintax storage.matching_pennied are available
Step17:  If for some reason the experiment fails, this method returns an exception. for example if we provide a invalid number of participants
Step18:  Connect to a remote experiment
<div class="alert alert-success lead">
    New in version <strong>0.4</strong>
</div>
To connect to a remote oTree location instead of given the settings.py path, you need to
provide the URL where the experiment is running.
Step19:  Connect to a remote experiment With Authentication
<div class="alert alert-success lead">
    New in version <strong>0.5</strong>
</div>
If you are trying to connect to server in auth level mode DEMO or STUDY (More Information about modes) without credentials an error will be shown
Step20:  In this cases you need to provide the parameters username and password
Step21:  and now all works as before
Step22:  <div class="text-warning">
    <h3>Some methods not work in a remote experiment</h3>
</div>
session_config()
bot_data()
Raises an NotImplementedError when are called.
<ASSISTANT_TASK:>
Python Code:
import skotree
skotree.VERSION
Explanation: Scikit-oTree Tutorial
Welcome to the Scikit-oTree tutorial. This package aims to integrate
any experiment developed on-top of oTree, with the 
Python Scientific-Stack; alowing
the scientists to access a big collection of tools for analyse the
experimental data.
End of explanation
# this load the library
import skotree
# this load the experiment located
# in the directory tests and
experiment = skotree.oTree("./tests")
experiment
Explanation: Philosophy
1. The data must be processed only by the oTree deployment.
Scikit-oTree don't preprocess any data from the experiment. All the information
are preserved exactly as any traditional export from oTree; the project only
take this data and present it.
2. The environment for analysis must not be modified.
oTree uses some global configuration to make it run. Scikit-oTree don't store
any global configuration alowwing to load data from different experiments
without problems. All the oTree related processing always happen in an
external process.
3. Only one data type for the data.
The data are always presented as a 
Pandas DataFrame
Installation
To install Scikit-oTree you must has Python and PIP. You can found
a comprensive tutorial to install it here.
After that you only need to run
bash
pip install -U scikit-otree
Local - Loading the experiment
To load your experiment you need to provide 
the location of the oTree deployment. This is the 
same location where the setting.py lives.
End of explanation
experiment.settings
Explanation: The previous code make a lot of things in background:
First create an extra process deatached from the local one
   to extract all oTree related settings.
Wait until the process to end.
Check the result of the process and store the settings as
   atrribute for experiment object.
Let's check the result
End of explanation
experiment.lsapps()
Explanation: This is the traditional object that you
obtain in any oTree experiment if you
write 
python
from django.conf import settings
Now let's check some information about the experiment, for example
all the exiting oTree apps.
End of explanation
experiment.lssessions()
Explanation: or maybe you want to see all the sessiong configured
that uses all this apps
End of explanation
experiment.session_config("matching_pennies")
Explanation: Yikes! the app and the session has the same name. Let's check the full session configuration.
End of explanation
experiment.settings.REAL_WORLD_CURRENCY_CODE
Explanation: Finally you can access <span class="text-info">any</span> content of the settings object ussing the attribute showed before. For example, maybe you want to see the "currency code"
End of explanation
all_data = experiment.all_data()
all_data
Explanation: The Data
Lets check the oTree server data tab
As you can see 4 kind of data can be exported from any experiment. 
1. All app
This generates one DataFrame with one row per participant, and all rounds are stacjed horizontally. For Scikit-oTree this functionallity are exposed as all_data() method
End of explanation
data = experiment.app_data("matching_pennies")
data
Explanation: 2. Per-App Data
These data-frame contain a row for each player in the given app. If there are multiple rounds, there will be multiple rows for the same participant. To access this information you need to provide the application name to the  method app_data()
End of explanation
filtered = data[["participant.code", "player.penny_side", "player.payoff"]]
filtered
Explanation: With the power of pandas.DataFrame you can easily filter the data
End of explanation
filtered.describe()
Explanation: Describe the data
End of explanation
group = filtered.groupby("participant.code")
group.describe()
Explanation: group by participant
End of explanation
data.columns
Explanation: or check all the columns availables
End of explanation
tspent = experiment.time_spent()
tspent
# check the available columns
tspent.columns 
# filter only the most important columns
tspent = tspent[["participant__code", "page_index", "seconds_on_page"]]
tspent
# lets describe the time expent by page
tspent.groupby("page_index").describe()
# and lets make a plot but grouped by participant
%matplotlib inline 
tspent.groupby("participant__code")[["seconds_on_page"]].plot();
Explanation: 3. Per-App Documentation
The code 
python
    experiment.app_doc("matching_pennies") 
returns the full documentation about the data retrieved by app_data()
4. Time spent on each page
Time spent on each page
End of explanation
storage = experiment.bot_data("matching_pennies", 4)
storage
Explanation: <div class="alert alert-info lead">
    <h4>Note</h4>
    <hr>
    This only show a simple example in how to use <strong>pandas.DataFrame</strong> to understand more, please check 
    <br>
    <a href="https://pandas.pydata.org/pandas-docs/stable/tutorials.html">
    https://pandas.pydata.org/pandas-docs/stable/tutorials.html</a>
</div>
Simulate with bots
Scikit-oTree offers out of the box the posibility to run the oTree bot-based-tests and retrieve all the data generated by them. 
The method bot_data() consume two arguments:
The name of the session to simulate
The number of participant 
And the return a dict like object (called CSVStorage) whith the same attributes as application has the session in the app_sequence key.
End of explanation
storage["matching_pennies"]
Explanation: as you can see the only available app (as we see before) is the matching_pennies.
Lets extract the data
End of explanation
storage.matching_pennies
Explanation: also for convenience the sintax storage.matching_pennied are available
End of explanation
experiment.bot_data("matching_pennies", 1)
Explanation: If for some reason the experiment fails, this method returns an exception. for example if we provide a invalid number of participants
End of explanation
remote = skotree.oTree("http://localhost:8000")
remote
remote.lsapps()
remote.lssessions()
remote.app_data("matching_pennies")
Explanation: Connect to a remote experiment
<div class="alert alert-success lead">
    New in version <strong>0.4</strong>
</div>
To connect to a remote oTree location instead of given the settings.py path, you need to
provide the URL where the experiment is running.
End of explanation
skotree.oTree("http://localhost:9000")
Explanation: Connect to a remote experiment With Authentication
<div class="alert alert-success lead">
    New in version <strong>0.5</strong>
</div>
If you are trying to connect to server in auth level mode DEMO or STUDY (More Information about modes) without credentials an error will be shown:
End of explanation
# the credential are not stored internally
exp = skotree.oTree("http://localhost:9000", username="admin", password="skotree")
exp
Explanation: In this cases you need to provide the parameters username and password
End of explanation
exp.all_data()
Explanation: and now all works as before
End of explanation
remote.bot_data("matching_pennies", 1)
Explanation: <div class="text-warning">
    <h3>Some methods not work in a remote experiment</h3>
</div>
session_config()
bot_data()
Raises an NotImplementedError when are called.
End of explanation
<END_TASK>