| 573 | |
| 574 | |
| 575 | class InputGrid(InteractControl): |
| 576 | def __init__(self, var, rows, columns, default_value=None, label=None, to_value=lambda x: x, width=4): |
| 577 | """ |
| 578 | A grid interact control. |
| 579 | |
| 580 | INPUT |
| 581 | var -- the variable |
| 582 | rows -- the number of rows |
| 583 | columns -- the number of columns |
| 584 | default_value -- if this is a scalar, it is put in every |
| 585 | cell; if it is a list, it is filled into the cells row by |
| 586 | row; if it is a nested list, then it is filled into the |
| 587 | cells according to the nesting structure. |
| 588 | label -- the label for the control |
| 589 | to_value -- a function which is applied to the nested list |
| 590 | from user input when assigning the variable |
| 591 | width -- the width of the input boxes |
| 592 | |
| 593 | EXAMPLES: |
| 594 | sage: sage.server.notebook.interact.InputGrid('M', 2,2, default_value = 0, label='M') |
| 595 | A 2 x 2 InputGrid interactive control with M=[[0, 0], [0, 0]] and label 'M' |
| 596 | sage: sage.server.notebook.interact.InputGrid('M', 2,2, default_value = [[1,2],[3,4]], label='M') |
| 597 | A 2 x 2 InputGrid interactive control with M=[[1, 2], [3, 4]] and label 'M' |
| 598 | sage: sage.server.notebook.interact.InputGrid('M', 2,2, default_value = [[1,2],[3,4]], label='M', to_value=MatrixSpace(ZZ,2,2)) |
| 599 | A 2 x 2 InputGrid interactive control with M=[1 2] |
| 600 | [3 4] and label 'M' |
| 601 | sage: sage.server.notebook.interact.InputGrid('M', 1, 3, default_value=[1,2,3], to_value=lambda x: vector(flatten(x))) |
| 602 | A 1 x 3 InputGrid interactive control with M=(1, 2, 3) and label 'M' |
| 603 | """ |
| 604 | |
| 605 | self.__rows = rows |
| 606 | self.__columns = columns |
| 607 | self.__to_value = to_value |
| 608 | self.__width = width |
| 609 | |
| 610 | if type(default_value) != list: |
| 611 | default_value = [[default_value for _ in range(columns)] for _ in range(rows)] |
| 612 | elif not all(type(elt)==list for elt in default_value): |
| 613 | default_value = [[default_value[i*columns+j] for j in xrange(columns)] for i in xrange(rows)] |
| 614 | |
| 615 | self.__default_value_grid = default_value |
| 616 | |
| 617 | InteractControl.__init__(self, var, self.__to_value(default_value), label) |
| 618 | |
| 619 | def __repr__(self): |
| 620 | """ |
| 621 | String representation of an InputGrid interactive control. |
| 622 | |
| 623 | EXAMPLES: |
| 624 | sage: sage.server.notebook.interact.InputGrid('M', 2,2).__repr__() |
| 625 | "A 2 x 2 InputGrid interactive control with M=[[None, None], [None, None]] and label 'M'" |
| 626 | """ |
| 627 | |
| 628 | return 'A %r x %r InputGrid interactive control with %s=%r and label %r'%( self.__rows, |
| 629 | self.__columns, self.var(), self.default_value(), self.label()) |
| 630 | |
| 632 | def _adaptor(self, value, globs): |
| 633 | """ |
| 634 | Adapt a user input, which is the text they enter, to be an |
| 635 | element selected by this control. |
| 636 | |
| 637 | INPUT: |
| 638 | value -- text entered by user |
| 639 | globs -- the globals interpreter variables (not used here). |
| 640 | |
| 641 | OUTPUT: |
| 642 | object |
| 643 | |
| 644 | EXAMPLES: |
| 645 | sage: sage.server.notebook.interact.InputGrid('M', 1,3, default_value=[[1,2,3]], to_value=lambda x: vector(flatten(x)))._adaptor("[[4,5,6]]", globals()) |
| 646 | (4, 5, 6) |
| 647 | """ |
| 648 | |
| 649 | return self.__to_value(sage_eval(value, globs)) |
| 650 | |
| 651 | def value_js(self): |
| 652 | """ |
| 653 | Return javascript string that will give the value of this |
| 654 | control element. |
| 655 | |
| 656 | OUTPUT: |
| 657 | string -- javascript |
| 658 | |
| 659 | EXAMPLES: |
| 660 | sage: sage.server.notebook.interact.InputGrid('M', 2,2).value_js() |
| 661 | ' "[["+jQuery(this).parents("table").eq(0).find("tr").map(function(){return jQuery(this).find("input").map(function() {return jQuery(this).val();}).get().join(",");}).get().join("],[")+"]]" ' |
| 662 | """ |
| 663 | # Basically, given an input element in a table, it constructs |
| 664 | # a python string representation of a list of lists from the |
| 665 | # rows in the table. |
| 666 | |
| 667 | return """ "[["+jQuery(this).parents("table").eq(0).find("tr").map(function(){return jQuery(this).find("input").map(function() {return jQuery(this).val();}).get().join(",");}).get().join("],[")+"]]" """ |
| 668 | |
| 669 | def render(self): |
| 670 | """ |
| 671 | Render this control as a string. |
| 672 | |
| 673 | OUTPUT: |
| 674 | string -- html format |
| 675 | |
| 676 | EXAMPLES: |
| 677 | sage: sage.server.notebook.interact.InputGrid('M', 1,2).render() |
| 678 | '<table><tr><td><input type=\'text\' value=\'None\' ... |
| 679 | |
| 680 | """ |
| 681 | table = "<table>" |
| 682 | for i in range(self.__rows): |
| 683 | table += "<tr>" |
| 684 | for j in range(self.__columns): |
| 685 | table += "<td><input type='text' value='%s' size='%s' onchange='%s'></input></td>"%(self.__default_value_grid[i][j], self.__width, self.interact()) |
| 686 | table += "</tr>" |
| 687 | table += "</table>" |
| 688 | |
| 689 | return table |
| 690 | |
| 1547 | |
| 1548 | |
| 1549 | class input_grid(control): |
| 1550 | def __init__(self, rows, columns, default=None, label=None, to_value=lambda x: x, width=4): |
| 1551 | r""" |
| 1552 | An input grid interactive control. Use this in conjunction |
| 1553 | with the interact command. |
| 1554 | |
| 1555 | INPUT: |
| 1556 | default -- object; the default put in this input box |
| 1557 | label -- the label rendered to the left of the box. |
| 1558 | to_value -- the grid output (list of rows) is sent through |
| 1559 | this function. This may reformat the data or coerce the |
| 1560 | type. |
| 1561 | width -- size of each input box in characters |
| 1562 | |
| 1563 | NOTEBOOK EXAMPLE: |
| 1564 | @interact |
| 1565 | def _(m = input_grid(2,2, default = [[1,7],[3,4]], |
| 1566 | label='M=', to_value=matrix), |
| 1567 | v = input_grid(2,1, default=[1,2], |
| 1568 | label='v=', to_value=matrix)): |
| 1569 | try: |
| 1570 | x = m\v |
| 1571 | html('$$%s %s = %s$$'%(latex(m), latex(x), latex(v))) |
| 1572 | except: |
| 1573 | html('There is no solution to $$%s x=%s$$'%(latex(m), latex(v))) |
| 1574 | |
| 1575 | |
| 1576 | EXAMPLES: |
| 1577 | sage: input_grid(2,2, default = 0, label='M') |
| 1578 | Interact 2 x 2 input grid control labeled M with default value 0 |
| 1579 | sage: input_grid(2,2, default = [[1,2],[3,4]], label='M') |
| 1580 | Interact 2 x 2 input grid control labeled M with default value [[1, 2], [3, 4]] |
| 1581 | sage: input_grid(2,2, default = [[1,2],[3,4]], label='M', to_value=MatrixSpace(ZZ,2,2)) |
| 1582 | Interact 2 x 2 input grid control labeled M with default value [[1, 2], [3, 4]] |
| 1583 | sage: input_grid(1, 3, default=[[1,2,3]], to_value=lambda x: vector(flatten(x))) |
| 1584 | Interact 1 x 3 input grid control labeled None with default value [[1, 2, 3]] |
| 1585 | |
| 1586 | """ |
| 1587 | self.__default = default |
| 1588 | self.__rows = rows |
| 1589 | self.__columns = columns |
| 1590 | self.__to_value = to_value |
| 1591 | self.__width = width |
| 1592 | control.__init__(self, label) |
| 1593 | |
| 1594 | def __repr__(self): |
| 1595 | """ |
| 1596 | Return print representation of this input box. |
| 1597 | |
| 1598 | EXAMPLES: |
| 1599 | sage: input_grid(2,2, label='M').__repr__() |
| 1600 | 'Interact 2 x 2 input grid control labeled M with default value None' |
| 1601 | |
| 1602 | """ |
| 1603 | |
| 1604 | return 'Interact %r x %r input grid control labeled %s with default value %s'%( self.__rows, |
| 1605 | self.__columns, self.label(), self.default()) |
| 1606 | |
| 1607 | |
| 1608 | def default(self): |
| 1609 | """ |
| 1610 | Return the default value of this input grid. |
| 1611 | |
| 1612 | EXAMPLES: |
| 1613 | sage: input_grid(2,2, default=1).default() |
| 1614 | 1 |
| 1615 | """ |
| 1616 | return self.__default |
| 1617 | |
| 1618 | |
| 1619 | def render(self, var): |
| 1620 | r""" |
| 1621 | Return rendering of this input grid as an InputGrid to be used |
| 1622 | for an interact canvas. Basically this specializes this |
| 1623 | input to be used for a specific function and variable. |
| 1624 | |
| 1625 | INPUT: |
| 1626 | var -- a string (variable; one of the variable names input to f) |
| 1627 | |
| 1628 | OUTPUT: |
| 1629 | InputGrid -- an InputGrid object. |
| 1630 | |
| 1631 | EXAMPLES: |
| 1632 | sage: input_grid(2,2).render('x') |
| 1633 | A 2 x 2 InputGrid interactive control with x=[[None, None], [None, None]] and label 'x' |
| 1634 | |
| 1635 | """ |
| 1636 | return InputGrid(var, rows=self.__rows, columns=self.__columns, default_value=self.__default, label=self.label(), to_value=self.__to_value, width=self.__width) |
| 1637 | |
| 1638 | |