3.3 A Worksheet

Module: sage.server.notebook.worksheet

A Worksheet.

A worksheet is embedded in a webpage that is served by the Sage server. It is a linearly-ordered collections of numbered cells, where a cell is a single input/output block.

The worksheet module is responsible for running calculations in a worksheet, spawning Sage processes that do all of the actual work and are controlled via pexpect, and reporting on results of calculations. The state of the cells in a worksheet is stored on the filesystem (not in the notebook pickle sobj).

Author: William Stein

Module-level Functions

after_first_word( s)

Return everything after the first whitespace in the string s. Returns the empty string if there is nothing after the first whitespace.

Input:

s
- string
Output: a string

convert_seconds_to_meaningful_time_span( t)

convert_time_to_string( t)

dictify( s)

Input:

s
- a string like 'in=5, out=7'
Output:
dict
- such as 'in':5, 'out':7

extract_first_compute_cell( text)

Input: a block of wiki-like marked up text Output:

meta
- meta information about the cell (as a dictionary)
input
- string, the input text
output
- string, the output text
end
- integer, first position after "}}}" in text.

extract_name( text)

extract_system( text)

extract_text_before_first_compute_cell( text)

Output: Everything in text up to the first {{{.

first_word( s)

format_completions_as_html( cell_id, completions)

ignore_prompts_and_output( aString)

Given a string s that defines an input block of code, if the first line begins in "sage:" (or "»>"), strip out all lines that don't begin in either "sage:" (or "»>") or "...", and remove all "sage:" (or "»>") and "..." from the beginning of the remaining lines.

TESTS:

sage: test1 = sage.server.notebook.worksheet.__internal_test1
sage: test1 == sage.server.notebook.worksheet.ignore_prompts_and_output(test1)
True

sage: test2 = sage.server.notebook.worksheet.__internal_test2
sage: sage.server.notebook.worksheet.ignore_prompts_and_output(test2)
'2 + 2\n'

init_sage_prestart( server, ulimit)

Set the module-scope variable _a_sage to an initialized sage server.

Input:

server, ulimit
- strings that are passed to the Sage pexpect interface constructor

The _a_sage variable is initially set to None:

sage: sage.server.notebook.worksheet._a_sage

We call init_sage_prestart and now _a_sage is a Sage instance:

sage: sage.server.notebook.worksheet.init_sage_prestart(None,None)
sage: sage.server.notebook.worksheet._a_sage
Sage

initialized_sage( server, ulimit)

Return one copy of a Sage compute process that has initialization code run.

Input:

server
- if sessions will be run via ssh on a remote account then this string specifies that account (passed on to the Sage pexpect interface).
ulimit
- string; passed to the ulimit command before running the subprocess

Output: a pexpect interface to a local or remote copy of Sage

sage: S = sage.server.notebook.worksheet.initialized_sage(None,None)
sage: S
Sage

next_available_id( v)

Return smallest nonnegative integer not in v.

one_prestarted_sage( server, ulimit)

Return a Sage interface that has been initialized.

Input:

server, ulimit
- strings that are passed to the Sage pexpect interface constructor
Output:
- an interface to a running copy of Sage

If the global variable multisession is true, each call to one_prestarted_sage returns a new Sage compute instance. Otherwise it always returns the same instance.

sage: sage.server.notebook.worksheet.one_prestarted_sage(None,None)
Sage
sage: sage.server.notebook.worksheet.multisession=False
sage: sage.server.notebook.worksheet.one_prestarted_sage(None,None) is sage.server.notebook.worksheet._a_sage
True
sage: sage.server.notebook.worksheet.multisession=True

split_search_string_into_keywords( s)

The point of this function is to allow for searches like this:

          "ws 7" foo bar  Modular  '"the" end'

i.e., where search terms can be in quotes and the different quote types can be mixed.

Input:

s
- a string

Output:
list
- a list of strings

worksheet_filename( name, owner)

Return the relative directory name of this worksheet with given name and owner.

Input:

name
- string, which may have spaces and funny characters, which are replaced by underscores.
owner
- string, with no spaces or funny characters

Output: string

sage: sage.server.notebook.worksheet.worksheet_filename('Example worksheet 3', 'sage10')
'sage10/Example_worksheet_3'
sage: sage.server.notebook.worksheet.worksheet_filename('Example#%\&! work\sheet 3', 'sage10')
'sage10/Example_____work_sheet_3'

Class: Worksheet

class Worksheet
Worksheet( self, name, dirname, notebook_worksheet_directory, system, owner, [docbrowser=False], [pretty_print=False], [auto_publish=False])

Create and initialize a new worksheet.

Input:

name
- string; the name of this worksheet
dirname
- string; name of the directory in which the worksheet's data is stored
notebook_worksheet_directory
- string; the directory in which the notebook object that contains this worksheet stores worksheets, i.e., nb.worksheet_directory().
system
- string; 'sage', 'gp', 'singular', etc. - the math software system in which all code is evaluated by default
owner
- string; username of the owner of this worksheet
docbrowser
- bool (default: False); whether this is a docbrowser worksheet
pretty_print
- bool (default: False); whether all output is pretty printed by default.

We test the constructor via an indirect doctest:

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Test', 'admin')
sage: W
[Cell 0; in=, out=]

Functions: add_collaborator,$ \,$ add_viewer,$ \,$ append,$ \,$ append_new_cell,$ \,$ attach,$ \,$ attached_data_files,$ \,$ attached_files,$ \,$ attached_html,$ \,$ autosave,$ \,$ best_completion,$ \,$ cell_id_list,$ \,$ cell_list,$ \,$ cells_directory,$ \,$ check_cell,$ \,$ check_comp,$ \,$ check_for_system_switching,$ \,$ clear,$ \,$ clear_queue,$ \,$ collaborators,$ \,$ completions_html,$ \,$ compute_cell_id_list,$ \,$ compute_process_has_been_started,$ \,$ computing,$ \,$ conf,$ \,$ cython_import,$ \,$ data_directory,$ \,$ date_edited,$ \,$ delete_all_output,$ \,$ delete_cell_input_files,$ \,$ delete_cell_with_id,$ \,$ delete_cells_directory,$ \,$ delete_notebook_specific_data,$ \,$ delete_user,$ \,$ detach,$ \,$ DIR,$ \,$ directory,$ \,$ do_sage_extensions_preparsing,$ \,$ docbrowser,$ \,$ edit_save,$ \,$ edit_text,$ \,$ enqueue,$ \,$ eval_asap_no_output,$ \,$ everyone_has_deleted_this_worksheet,$ \,$ filename,$ \,$ filename_without_owner,$ \,$ get_cell_with_id,$ \,$ get_snapshot_text_filename,$ \,$ has_published_version,$ \,$ hide_all,$ \,$ html,$ \,$ html_data_options_list,$ \,$ html_file_menu,$ \,$ html_menu,$ \,$ html_ratings_info,$ \,$ html_save_discard_buttons,$ \,$ html_share_publish_buttons,$ \,$ html_time_last_edited,$ \,$ html_time_since_last_edited,$ \,$ html_title,$ \,$ html_worksheet_body,$ \,$ hunt_file,$ \,$ initialize_sage,$ \,$ input_text,$ \,$ interrupt,$ \,$ is_active,$ \,$ is_archived,$ \,$ is_auto_publish,$ \,$ is_doc_worksheet,$ \,$ is_last_id_and_previous_is_nonempty,$ \,$ is_owner,$ \,$ is_published,$ \,$ is_publisher,$ \,$ is_rater,$ \,$ is_trashed,$ \,$ javascript_confirm_before_leave,$ \,$ javascript_for_being_active_worksheet,$ \,$ javascript_for_jsmath_rendering,$ \,$ last_compute_walltime,$ \,$ last_edited,$ \,$ last_to_edit,$ \,$ load_any_changed_attached_files,$ \,$ load_path,$ \,$ move_out_of_trash,$ \,$ move_to_archive,$ \,$ move_to_trash,$ \,$ name,$ \,$ new_cell_after,$ \,$ new_cell_before,$ \,$ next_block_id,$ \,$ next_hidden_id,$ \,$ notebook,$ \,$ owner,$ \,$ ping,$ \,$ plain_text,$ \,$ postprocess_output,$ \,$ preparse,$ \,$ preparse_input,$ \,$ preparse_introspection_input,$ \,$ preparse_nonswitched_input,$ \,$ pretty_print,$ \,$ published_version,$ \,$ publisher,$ \,$ queue,$ \,$ queue_id_list,$ \,$ quit,$ \,$ quit_if_idle,$ \,$ rate,$ \,$ rating,$ \,$ ratings,$ \,$ record_edit,$ \,$ reset_interact_state,$ \,$ restart_sage,$ \,$ revert_to_last_saved_state,$ \,$ revert_to_snapshot,$ \,$ sage,$ \,$ satisfies_search,$ \,$ save,$ \,$ save_snapshot,$ \,$ set_active,$ \,$ set_auto_publish,$ \,$ set_cell_counter,$ \,$ set_collaborators,$ \,$ set_filename,$ \,$ set_filename_without_owner,$ \,$ set_is_doc_worksheet,$ \,$ set_name,$ \,$ set_not_computing,$ \,$ set_owner,$ \,$ set_pretty_print,$ \,$ set_published_version,$ \,$ set_system,$ \,$ set_user_view,$ \,$ set_worksheet_that_was_published,$ \,$ show_all,$ \,$ snapshot_data,$ \,$ snapshot_directory,$ \,$ start_next_comp,$ \,$ synchro,$ \,$ synchronize,$ \,$ system,$ \,$ time_idle,$ \,$ time_since_last_edited,$ \,$ truncated_name,$ \,$ uncache_snapshot_data,$ \,$ user_autosave_interval,$ \,$ user_can_edit,$ \,$ user_is_collaborator,$ \,$ user_is_only_viewer,$ \,$ user_is_viewer,$ \,$ user_view,$ \,$ user_view_is,$ \,$ viewers,$ \,$ warn_about_other_person_editing,$ \,$ worksheet_command,$ \,$ worksheet_that_was_published

add_collaborator( self, user)

Add the given user as a collaborator on this worksheet.

Input:

user
- a string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: nb.add_user('diophantus','sage','sage@sagemath.org',force=True)
sage: W = nb.create_new_worksheet('Collaborator test', 'admin')
sage: W.collaborators()
[]
sage: W.add_collaborator('diophantus')
sage: W.collaborators()
['diophantus']

add_viewer( self, user)

Add the given user as an allowed viewer of this worksheet.

Input:

user
- string (username)

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: nb.add_user('diophantus','sage','sage@sagemath.org',force=True)
sage: W = nb.create_new_worksheet('Viewer test', 'admin')
sage: W.add_viewer('diophantus')
sage: W.viewers()
['diophantus']

append_new_cell( self)

Create and append a new cell to the list of cells.

Output: a new empty cell

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Test Edit Save', 'admin')
sage: W
[Cell 0; in=, out=]
sage: W.append_new_cell()
Cell 1; in=, out=
sage: W
[Cell 0; in=, out=, Cell 1; in=, out=]

attached_data_files( self)

Return a list of the filenames of files in the worksheet data directory.

Output: list of strings

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.attached_data_files()
[]
sage: open('%s/foo.data'%W.data_directory(),'w').close()
sage: W.attached_data_files()
['foo.data']

cell_id_list( self)

Return a new list of the id's of cells in this worksheet.

Output: a new list

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Test Edit Save', 'admin')

Now we set the worksheet to have two cells with the default id of 0 and another with id 10.

            sage: W.edit_save('Sage
{{{
2+3
///
5
}}}
{{{id=10|
2+8
///
10
}}}')
            sage: W.cell_id_list()
            [0, 10]

cell_list( self)

Return a reference to the list of the all the cells in this worksheet.

Output:

list
- a list of cells

NOTE: This function loads the cell list from disk (the file worksheet.txt) if it isn't available in memory.

            sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
            sage: W = nb.create_new_worksheet('Test Edit Save', 'admin')
            sage: W.edit_save('Sage
{{{
2+3
///
5
}}}
{{{
2+8
///
10
}}}')
            sage: v = W.cell_list(); v
            [Cell 0; in=2+3, out=5, Cell 1; in=2+8, out=10]
            sage: v[0]
            Cell 0; in=2+3, out=5

cells_directory( self)

Return the directory in which the cells of this worksheet are evaluated.

Output: string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.cells_directory()
'.../worksheets/admin/0/cells/'

check_cell( self, id)

Check the status on computation of the cell with given id.

Input:

id
- an integer

Output:
status
- a string, either 'd' (done) or 'w' (working)
cell
- the cell with given id

check_comp( self, [wait=0.2])

Check on currently computing cells in the queue.

Input:

wait
- float (default: 0.2); how long to wait for output.

            sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
            sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)
            sage: W = nb.create_new_worksheet('Test', 'sage')
            sage: W.edit_save('Sage
{{{
3^20
}}}')
            sage: W.cell_list()[0].evaluate()
            sage: W.check_comp()     # random output -- depends on computer speed
            ('d', Cell 0; in=3^20, out=
            3486784401
            )
            sage: nb.delete()

check_for_system_switching( self, s, C)

Check for input cells that start with %foo, where foo is an object with an eval method.

collaborators( self)

Return a (reference to the) list of the collaborators who can also view and modify this worksheet.

Output: list

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('test1', 'admin')
sage: C = W.collaborators(); C
[]
sage: C.append('sage')
sage: W.collaborators()
['sage']

compute_process_has_been_started( self)

Return True precisely if the compute process has been started, irregardless of whether or not it is currently churning away on a computation.

computing( self)

Return whether or not a cell is currently being run in the worksheet Sage process.

conf( self)

Return the configuration object for this worksheet, which is stored in an sobj in the worksheet directory.

Output: worksheet configuration object.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('test1', 'admin')
sage: W.conf()
Configuration: {}

data_directory( self)

Return path to directory where worksheet data is stored.

Output: string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.data_directory()
'.../worksheets/admin/0/data/'

date_edited( self)

Returns the date the worksheet was last edited if already recorded otherwise the current local time is recorded and returned.

delete_all_output( self, username)

Delete all the output in all the worksheet cells.

Input:

username
- name of the user requesting the deletion.

We create a new notebook, user, and a worksheet with one cell.

            sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
            sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)
            sage: W = nb.create_new_worksheet('Test', 'sage')
            sage: W.edit_save('Sage
system:sage
{{{
2+3
///
5
}}}')

Notice that there is 1 cell with 5 in its output.

sage: W.cell_list()
[Cell 0; in=2+3, out=5]

We now delete the output, observe that it is gone.

sage: W.delete_all_output('sage')
sage: W.cell_list()
[Cell 0; in=2+3, out=]

If an invalid user tries to delete all, a ValueError is raised.

sage: W.delete_all_output('hacker')
Traceback (most recent call last):
...
ValueError: user 'hacker' not allowed to edit this worksheet

Clean up.

sage: nb.delete()

delete_cell_input_files( self)

Delete all the files code_%s.py and code_%s.spyx that are created when evaluating cells. We do this when we first start the notebook to get rid of clutter.

delete_cell_with_id( self, id)

Remove the cell with given id and return the cell before it.

delete_cells_directory( self)

Delete the directory in which all the cell computations occur.

            sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
            sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)
            sage: W = nb.create_new_worksheet('Test', 'sage')
            sage: W.edit_save('Sage
{{{
3^20
}}}')
            sage: sorted(os.listdir(W.directory()))
            ['snapshots', 'worksheet.txt']
            sage: W.cell_list()[0].evaluate()
            sage: sorted(os.listdir(W.directory()))
            ['cells', 'code', 'data', 'snapshots', 'worksheet.txt']
            sage: W.delete_cells_directory()
            sage: sorted(os.listdir(W.directory()))
            ['code', 'data', 'snapshots', 'worksheet.txt']

delete_notebook_specific_data( self)

Delete data from this worksheet this is specific to a certain notebook. This means deleting the attached files, collaborators, and viewers.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: nb.add_user('hilbert','sage','sage@sagemath.org',force=True)
sage: W = nb.create_new_worksheet('test1', 'admin')
sage: W.add_viewer('hilbert')
sage: W.delete_notebook_specific_data()
sage: W.viewers()
[]
sage: W.add_collaborator('hilbert')
sage: W.collaborators()
['admin', 'hilbert']
sage: W.delete_notebook_specific_data()
sage: W.collaborators()
['admin']

delete_user( self, user)

Delete a user from having any view or ownership of this worksheet.

Input:

user
- string; the name of a user

We create a notebook with 2 users and 1 worksheet that both view.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: nb.add_user('wstein','sage','wstein@sagemath.org',force=True)
sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)
sage: W = nb.new_worksheet_with_title_from_text('Sage', owner='sage')
sage: W.add_viewer('wstein')
sage: W.owner()
'sage'
sage: W.viewers()
['wstein']

We delete the sage user from the worksheet W. This makes wstein the new owner.

sage: W.delete_user('sage')
sage: W.viewers()
['wstein']
sage: W.owner()
'wstein'

Then we delete wstein from W, which makes the owner None:

sage: W.delete_user('wstein')
sage: W.owner() is None
True
sage: W.viewers()
[]

Finally, we clean up.

sage: nb.delete()

DIR( self)

Return the absolute path to the directory that contains the Sage Notebook directory for the notebook that contains this worksheet.

Output: string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.DIR()   # random output
'/Users/was/.sage/temp/teragon_2.local/19129'

directory( self)

Return the full path to the directory where this worksheet is stored.

Output: string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.directory()
'.../worksheets/admin/0'

docbrowser( self)

Return True if this is a docbrowser worksheet.

Output: bool

We first create a standard worksheet for which docbrowser is of course False:

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('test1', 'admin')
sage: W.docbrowser()
False

We create a worksheet for which docbrowser is True:

sage: W = nb.create_new_worksheet('docs', 'admin', docbrowser=True)
sage: W.docbrowser()
True

edit_save( self, text, [ignore_ids=False])

Set the contents of this worksheet to the worksheet defined by the plain text string text, which should be a sequence of html and 's code blocks.

Input:

text
- a string
ignore_ids
- bool (default: False); if True ignore all the id's in the code block.

We create a new test notebook and a worksheet.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)
sage: W = nb.create_new_worksheet('Test Edit Save', 'sage')

We set the contents of the worksheet using the edit_save command.

            sage: W.edit_save('Sage
{{{
2+3
///
5
}}}
{{{
2+8
///
10
}}}')
            sage: W
            [Cell 0; in=2+3, out=5, Cell 1; in=2+8, out=10]
            sage: W.name()
            'Sage'

edit_text( self)

Returns a plain-text version of the worksheet with {{{}}} wiki-formatting, suitable for hand editing.

enqueue( self, C, [username=None], [next=False])

Queue up the cell C for evaluation in this worksheet.

Input:

C
- a Cell
username
- the name of the user that is evaluating this cell (mainly used for loging)

NOTE: If C.is_asap() is True, then we put C as close to the beginning of the queue as possible, but after all asap cells. Otherwise, C goes at the end of the queue.

everyone_has_deleted_this_worksheet( self)

Return True if all users have deleted this worksheet, so we know we can safely purge it from disk.

Output: bool

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: W.everyone_has_deleted_this_worksheet()
False
sage: W.move_to_trash('admin')
sage: W.everyone_has_deleted_this_worksheet()
True

filename( self)

Return the filename (really directory) where the files associated to this worksheet are stored.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.filename()
'admin/0'
sage: sorted(os.listdir(nb.directory() + '/worksheets/' + W.filename()))
['snapshots', 'worksheet.txt']

filename_without_owner( self)

Return the part of the worksheet filename after the last /, i.e., without any information about the owner of this worksheet.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.filename_without_owner()
'0'
sage: W.filename()
'admin/0'

has_published_version( self)

Return True if there is a published version of this worksheet.

Output: bool

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: P = nb.publish_worksheet(W, 'admin')
sage: P.has_published_version()
False
sage: W.has_published_version()
True

html_ratings_info( self)

Return html that renders to give a summary of how this worksheet has been rated.

Output:

string
- a string of HTML as a bunch of table rows.

            sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
            sage: W = nb.create_new_worksheet('Publish Test', 'admin')
            sage: W.rate(0, 'this lacks content', 'riemann')
            sage: W.rate(3, 'this is great', 'hilbert')
            sage: W.html_ratings_info()
            '<tr><td>hilbert</td><td align=center>3</td><td>this is
great</td></tr>
<tr><td>riemann</td><td align=center>0</td><td>this lacks
content</td></tr>'

input_text( self)

Return text version of the input to the worksheet.

interrupt( self)

Interrupt all currently queued up calculations.

Output:

bool
- return True if no problems interrupting calculation return False if the Sage interpreter had to be restarted.

We create a worksheet and start a large factorization going:

            sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
            sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)
            sage: W = nb.create_new_worksheet('Test', 'sage')
            sage: W.edit_save('Sage
{{{
factor(2^997-1)
}}}')
            sage: W.cell_list()[0].evaluate()

It's running still

sage: W.check_comp()
('w', Cell 0; in=factor(2^997-1), out=...)

We interrupt it successfully.

sage: W.interrupt()         # random -- could fail on heavily loaded machine
True

Now we check and nothing is computing.

sage: W.check_comp()        # random -- could fail on heavily loaded machine  
('e', None)

Clean up.

sage: nb.delete()

is_active( self, user)

Return True if this worksheet is active for the given user.

Input:

user
- string
Output: bool

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Active Test', 'admin')
sage: W.is_active('admin')
True
sage: W.move_to_archive('admin')
sage: W.is_active('admin')
False

is_archived( self, user)

Return True if this worksheet is archived for the given user.

Input:

user
- string
Output: bool

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Archived Test', 'admin')
sage: W.is_archived('admin')
False
sage: W.move_to_archive('admin')
sage: W.is_archived('admin')
True

is_auto_publish( self)

Returns boolean of "Is this worksheet set to be published automatically when saved?" if private variable "autopublish" is set otherwise False is returned and the variable is set to False.

is_published( self)

Return True if this worksheet is a published worksheet.

Output:

bool
- whether or not owner is 'pub'

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: W.is_published()
False
sage: W.set_owner('pub')
sage: W.is_published()
True

is_publisher( self, username)

Return True if username is the username of the publisher of this worksheet, assuming this worksheet was published.

Input:

username
- string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: P = nb.publish_worksheet(W, 'admin')
sage: P.is_publisher('hearst')
False
sage: P.is_publisher('admin')
True

is_rater( self, username)

Return True is the user with given username has rated this worksheet.

Input:

username
- string

Output: bool

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: W.rate(0, 'this lacks content', 'riemann')
sage: W.is_rater('admin')
False
sage: W.is_rater('riemann')
True

is_trashed( self, user)

Return True if this worksheet is in the trash for the given user.

Input:

user
- string
Output: bool

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Trash Test', 'admin')
sage: W.is_trashed('admin')
False
sage: W.move_to_trash('admin')
sage: W.is_trashed('admin')
True

load_any_changed_attached_files( self, s)

Modify s by prepending any necessary load commands corresponding to attached files that have changed.

move_out_of_trash( self, user)

Exactly the same as set_active(user).

Input:

user
- string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Active Test', 'admin')
sage: W.move_to_trash('admin')
sage: W.is_active('admin')
False
sage: W.move_out_of_trash('admin')
sage: W.is_active('admin')
True

move_to_archive( self, user)

Move this worksheet to be archived for the given user.

Input:

user
- string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Archive Test', 'admin')
sage: W.move_to_archive('admin')
sage: W.is_archived('admin')
True

move_to_trash( self, user)

Move this worksheet to the trash for the given user.

Input:

user
- string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Trash Test', 'admin')
sage: W.move_to_trash('admin')
sage: W.is_trashed('admin')
True

name( self)

Return the name of this worksheet.

Output: string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.name()
'A Test Worksheet'

new_cell_after( self, id, [input=])

Insert a new cell into the cell list after the cell with the given integer id.

Input:

id
- integer
input
- string

Output: new cell with the given input text (empty by default).

new_cell_before( self, id, [input=])

Insert a new cell into the cell list before the cell with the given integer id. If the id is not the id of any cell, inserts a new cell at the end of the cell list.

Input:

id
- integer
input
- string

Output: new cell with the given input text (empty by default).

notebook( self)

Return the notebook that contains this worksheet.

Output: a Notebook object.

This really returns the Notebook object that is set as a global variable of the twist module.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.notebook()
<class 'sage.server.notebook.notebook.Notebook'>
sage: W.notebook() is sage.server.notebook.twist.notebook
True

plain_text( self, [prompts=False], [banner=True])

Return a plain-text version of the worksheet.

Input:

prompts
- if True format for inclusion in docstrings.

pretty_print( self)

Return True if output shold be pretty printed by default.

Output:

bool
- True of False

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.pretty_print()
False
sage: W.set_pretty_print('true')
sage: W.pretty_print()
True

published_version( self)

If this worksheet was published, return the published version of this worksheet. Otherwise, raise a ValueError.

Output: a worksheet (or raise a ValueError)

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: P = nb.publish_worksheet(W, 'admin')
sage: W.published_version() is P
True

publisher( self)

Return username of user that published this worksheet.

Output: string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: S = nb.publish_worksheet(W, 'admin')
sage: S.publisher()
'admin'

quit_if_idle( self, timeout)

Quit the worksheet process if it has been ``idle'' for more than timeout seconds, where idle is by definition that the worksheet has not reported back that it is actually computing. I.e., an ignored worksheet process (since the user closed their browser) is also considered idle, even if code is running.

rate( self, x, comment, username)

Set the rating on this worksheet by the given user to x and also set the given comment.

Input:

x
- integer
comment
- string
usename
- string

We create a worksheet and rate it, then look at the ratings.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: W.rate(3, 'this is great', 'hilbert')
sage: W.ratings()
[('hilbert', 3, 'this is great')]

Note that only the last rating by a user counts:

sage: W.rate(1, 'this lacks content', 'riemann')
sage: W.rate(0, 'this lacks content', 'riemann')
sage: W.ratings()
[('hilbert', 3, 'this is great'), ('riemann', 0, 'this lacks content')]

rating( self)

Return overall aerage rating of self.

Output: float or the int -1 to mean "not rated"

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: W.rating()
-1
sage: W.rate(0, 'this lacks content', 'riemann')
sage: W.rate(3, 'this is great', 'hilbert')
sage: W.rating()
1.5

ratings( self)

Return all the ratings of this worksheet.

Output:

list
- a reference to the list of ratings.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: W.ratings()
[]
sage: W.rate(0, 'this lacks content', 'riemann')
sage: W.rate(3, 'this is great', 'hilbert')
sage: W.ratings()
[('riemann', 0, 'this lacks content'), ('hilbert', 3, 'this is great')]

reset_interact_state( self)

Reset the interact state of this worksheet.

restart_sage( self)

Restart Sage kernel.

sage( self)

Return a started up copy of Sage initialized for computations.

If this is a published worksheet, just return None, since published worksheets must not have any compute functionality.

Output: a Sage interface

satisfies_search( self, search)

Input: search is a string that describes a search query, i.e., a space-separated collections of words.

Output: True if the search is satisfied by self, i.e., all the words appear in the text version of self.

set_active( self, user)

Set his worksheet to be active for the given user.

Input:

user
- string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Active Test', 'admin')
sage: W.move_to_archive('admin')
sage: W.is_active('admin')
False
sage: W.set_active('admin')
sage: W.is_active('admin')
True

set_auto_publish( self)

Sets the worksheet to be published automatically when the worksheet is saved if the worksheet isn't already set to this otherwise it is set not to.

set_collaborators( self, v)

Set the list of collaborators to those listed in the list v of strings.

Input:

v
- a list of strings

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)
sage: nb.add_user('hilbert','sage','sage@sagemath.org',force=True)
sage: W = nb.create_new_worksheet('test1', 'admin')
sage: W.set_collaborators(['sage', 'admin', 'hilbert', 'sage'])

Note that repeats are not added multiple times and admin - the owner - isn't added:

sage: W.collaborators()
['hilbert', 'sage']

set_filename( self, filename)

Set the worksheet filename (actually directory).

Input:

filename
- string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.filename()
'admin/0'
sage: W.set_filename('admin/10')
sage: W.filename()
'admin/10'

set_filename_without_owner( self, nm)

Set this worksheet filename (actually directory) by getting the owner from the pre-stored owner via self.owner().

Input:

nm
- string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.filename()
'admin/0'
sage: W.set_filename_without_owner('5')
sage: W.filename()
'admin/5'

set_name( self, name)

Set the name of this worksheet.

Input:

name
- string

We create a worksheet and change the name:

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.set_name('A renamed worksheet')
sage: W.name()
'A renamed worksheet'

set_pretty_print( self, [check=false])

Set whether or not output should be pretty printed by default.

Input:

check
- string (default: 'false'); either 'true' or 'false'.

NOTE: The reason the input is a string and lower case instead of a Python bool is because this gets called indirectory from javascript. (And, Jason Grout wrote this and didn't realize how unpythonic this design is - it should be redone to use True/False.)

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.set_pretty_print('false')
sage: W.pretty_print()
False
sage: W.set_pretty_print('true')
sage: W.pretty_print()
True

set_published_version( self, filename)

Set the published version of this worksheet to be the worksheet with given filename.

Input:

filename
- string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: P = nb.publish_worksheet(W, 'admin')  # indirect test
sage: W._Worksheet__published_version
'pub/0'
sage: W.set_published_version('pub/0')

set_system( self, [system=sage])

Set the math software system in which input is evaluated by default.

Input:

sysem
- string (default: 'sage')

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.set_system('magma')
sage: W.system()
'magma'

set_user_view( self, user, x)

Set the view on this worksheet for the given user.

Input:

user
- a string
x
- int, one of the variables ACTIVE, ARCHIVED, TRASH in worksheet.py

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: W.set_user_view('admin', sage.server.notebook.worksheet.ARCHIVED)
sage: W.user_view('admin') == sage.server.notebook.worksheet.ARCHIVED
True

set_worksheet_that_was_published( self, W)

Set the worksheet that was published to get self to W.

Input:

W
- a Worksheet

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: P = nb.publish_worksheet(W, 'admin')
sage: P.worksheet_that_was_published() is W
True

We fake things and make it look like P published itself:

sage: P.set_worksheet_that_was_published(P)
sage: P.worksheet_that_was_published() is P
True

system( self)

Return the math software system in which by default all input to the notebook is evaluated.

Output: string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('A Test Worksheet', 'admin')
sage: W.system()
'sage'
sage: W.set_system('mathematica')
sage: W.system()
'mathematica'

user_can_edit( self, user)

Return True if the user with given name is allowed to edit this worksheet.

Input:

user
- string
Output: bool

We create a notebook with one worksheet and two users.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)
sage: nb.add_user('william', 'william', 'wstein@sagemath.org', force=True)
sage: W = nb.create_new_worksheet('Test', 'sage')
sage: W.user_can_edit('sage')
True

At first the user 'william' can't edit this worksheet:

sage: W.user_can_edit('william')
False

After adding 'william' as a collaborator he can edit the worksheet.

sage: W.add_collaborator('william')
sage: W.user_can_edit('william')
True

Clean up:

sage: nb.delete()

user_view( self, user)

Return the view that the given user has of this worksheet. If the user currently doesn't have a view set it to ACTIVE and return ACTIVE.

Input:

user
- a string

Output:
Python int
- one of ACTIVE, ARCHIVED, TRASH, which are defined in worksheet.py

We create a new worksheet and get the view, which is ACTIVE:

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: W.user_view('admin')
1
sage: sage.server.notebook.worksheet.ACTIVE
1

Now for the admin user we move W to the archive:

sage: W.move_to_archive('admin')

The view is now archive.

sage: W.user_view('admin')
0
sage: sage.server.notebook.worksheet.ARCHIVED
0

For any other random viewer the view is set by default to ACTIVE.

sage: W.user_view('foo')
1

user_view_is( self, user, x)

Return True if the user view of user is x.

Input:

user
- a string
x
- int, one of the variables ACTIVE, ARCHIVED, TRASH in worksheet.py

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: W.user_view_is('admin', sage.server.notebook.worksheet.ARCHIVED)
False
sage: W.user_view_is('admin', sage.server.notebook.worksheet.ACTIVE)
True

viewers( self)

Return list of viewers of this worksheet.

Output:

list
- of string

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: nb.add_user('sage','sage','sage@sagemath.org',force=True)
sage: nb.add_user('hilbert','sage','sage@sagemath.org',force=True)
sage: W = nb.create_new_worksheet('test1', 'admin')
sage: W.add_viewer('hilbert')
sage: W.viewers()
['hilbert']
sage: W.add_viewer('sage')
sage: W.viewers()
['hilbert', 'sage']

warn_about_other_person_editing( self, username, threshold)

Check to see if another user besides username was the last to edit this worksheet during the last threshold seconds. If so, return True and that user name. If not, return False.

Input:

username
- user who would like to edit this file.
threshold
- number of seconds, so if there was no activity on this worksheet for this many seconds, then editing is considered safe.

worksheet_that_was_published( self)

Return the worksheet that was published to get this worksheet, if this worksheet was published. Otherwise just return this worksheet.

Output: Worksheet

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Publish Test', 'admin')
sage: W.worksheet_that_was_published() is W
True

sage: S = nb.publish_worksheet(W, 'admin')
sage: S.worksheet_that_was_published() is S
False
sage: S.worksheet_that_was_published() is W
True

Special Functions: __cmp__,$ \,$ __getitem__,$ \,$ __getstate__,$ \,$ __init__,$ \,$ __len__,$ \,$ __repr__,$ \,$ __setstate__,$ \,$ _enqueue_auto,$ \,$ _enqueue_auto_cells,$ \,$ _eval_cmd,$ \,$ _get_last_identifier,$ \,$ _load_file,$ \,$ _new_cell,$ \,$ _new_text_cell,$ \,$ _normalized_filenames,$ \,$ _process_output,$ \,$ _record_that_we_are_computing,$ \,$ _save_objects,$ \,$ _saved_by_info,$ \,$ _strip_synchro_from_start_of_output

__cmp__( self, other)

We compare two worksheets.

Input:

self, other
- worksheets
Output:
-1,0,1
- comparison is on the underlying filenames.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W2 = nb.create_new_worksheet('test2', 'admin')
sage: W1 = nb.create_new_worksheet('test1', 'admin')
sage: cmp(W1, W2)
1
sage: cmp(W2, W1)
-1

__getstate__( self)

The getstate method makes sure that the self.__cells dictionary is not saved in the pickle since it could be huge.

Output: a dictionary; same as self.__dict__ but with some fields deleted.

sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
sage: W = nb.create_new_worksheet('Test Edit Save', 'admin')
sage: v = W.__getstate__().keys(); v.sort(); v
['_Worksheet__autopublish', '_Worksheet__collaborators',
'_Worksheet__comp_is_running', '_Worksheet__dir', '_Worksheet__docbrowser',
'_Worksheet__filename', '_Worksheet__name', '_Worksheet__next_id',
'_Worksheet__owner', '_Worksheet__pretty_print', '_Worksheet__queue',
'_Worksheet__saved_by_info', '_Worksheet__system', '_Worksheet__viewers']

__len__( self)

Return the number of cells in this worksheet.

Output: int

            sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
            sage: W = nb.create_new_worksheet('test1', 'admin')
            sage: len(W)
            1
            sage: W.edit_save('Sage
{{{
2+3
///
5
}}}
{{{id=10|
2+8
///
10
}}}')
            sage: len(W)
            2

__repr__( self)

Return string representation of this worksheet, which is simply the string representation of the underlying list of cells.

Output: string

            sage: nb = sage.server.notebook.notebook.Notebook(tmp_dir())
            sage: W = nb.create_new_worksheet('test1', 'admin')
            sage: W.__repr__()
            '[Cell 0; in=, out=]'
            sage: W.edit_save('Sage
{{{
2+3
///
5
}}}
{{{id=10|
2+8
///
10
}}}')
            sage: W.__repr__()
            '[Cell 0; in=2+3, out=5, Cell 10; in=2+8, out=10]'

See About this document... for information on suggesting changes.