Class: Aws::DynamoDB::Types::UpdateItemInput
| Inherits: |
Struct
|
| Defined in: |
(unknown) |
Overview
Represents the input of an UpdateItem operation.
Note: When passing UpdateItemInput
as input to a Client method, you can use a vanilla Hash
:
{
table_name: "TableName", # required
key: { # required
"AttributeName" => "value", # value <Hash,Array,String,Numeric,Boolean,IO,Set,nil>
},
attribute_updates: {
"AttributeName" => {
value: "value", # value <Hash,Array,String,Numeric,Boolean,IO,Set,nil>
action: "ADD", # accepts ADD, PUT, DELETE
},
},
expected: {
"AttributeName" => {
value: "value", # value <Hash,Array,String,Numeric,Boolean,IO,Set,nil>
exists: false,
comparison_operator: "EQ", # accepts EQ, NE, IN, LE, LT, GE, GT, BETWEEN, NOT_NULL, NULL, CONTAINS, NOT_CONTAINS, BEGINS_WITH
attribute_value_list: ["value"], # value <Hash,Array,String,Numeric,Boolean,IO,Set,nil>
},
},
conditional_operator: "AND", # accepts AND, OR
return_values: "NONE", # accepts NONE, ALL_OLD, UPDATED_OLD, ALL_NEW, UPDATED_NEW
return_consumed_capacity: "INDEXES", # accepts INDEXES, TOTAL, NONE
return_item_collection_metrics: "SIZE", # accepts SIZE, NONE
update_expression: "UpdateExpression",
condition_expression: "ConditionExpression",
expression_attribute_names: {
"ExpressionAttributeNameVariable" => "AttributeName",
},
expression_attribute_values: {
"ExpressionAttributeValueVariable" => "value", # value <Hash,Array,String,Numeric,Boolean,IO,Set,nil>
},
}
Instance Attribute Summary collapse
-
#attribute_updates ⇒ Hash<String,Types::AttributeValueUpdate>
This is a legacy parameter, for backward compatibility. -
#condition_expression ⇒ String
A condition that must be satisfied in order for a conditional update to succeed.
-
#conditional_operator ⇒ String
This is a legacy parameter, for backward compatibility. -
#expected ⇒ Hash<String,Types::ExpectedAttributeValue>
This is a legacy parameter, for backward compatibility. -
#expression_attribute_names ⇒ Hash<String,String>
One or more substitution tokens for attribute names in an expression.
-
#expression_attribute_values ⇒ Hash<String,Types::AttributeValue>
One or more values that can be substituted in an expression.
-
#key ⇒ Hash<String,Types::AttributeValue>
The primary key of the item to be updated.
-
#return_consumed_capacity ⇒ String
Determines the level of detail about provisioned throughput consumption that is returned in the response:
-
#return_item_collection_metrics ⇒ String
Determines whether item collection metrics are returned.
-
#return_values ⇒ String
Use ReturnValues if you want to get the item attributes as they appeared either before or after they were updated.
-
#table_name ⇒ String
The name of the table containing the item to update.
-
#update_expression ⇒ String
An expression that defines one or more attributes to be updated, the action to be performed on them, and new value(s) for them.
Instance Attribute Details
#attribute_updates ⇒ Hash<String,Types::AttributeValueUpdate>
This parameter can be used for modifying top-level attributes; however, it does not support individual list or map elements.
The names of attributes to be modified, the action to perform on each, and the new value for each. If you are updating an attribute that is an index key attribute for any indexes on that table, the attribute type must match the index key type defined in the AttributesDefinition of the table description. You can use UpdateItem to update any non-key attributes.
Attribute values cannot be null. String and Binary type attributes must have lengths greater than zero. Set type attributes must not be empty. Requests with empty values will be rejected with a ValidationException exception.
Each AttributeUpdates element consists of an attribute name to modify, along with the following:
Value - The new value, if applicable, for this attribute.
Action - A value that specifies how to perform the update. This action is only valid for an existing attribute whose data type is Number or is a set; do not use
ADD
for other data types.If an item with the specified primary key is found in the table, the following values perform the following actions:
PUT
- Adds the specified attribute to the item. If the attribute already exists, it is replaced by the new value.DELETE
- Removes the attribute and its value, if no value is specified forDELETE
. The data type of the specified value must match the existing value\'s data type.If a set of values is specified, then those values are subtracted from the old set. For example, if the attribute value was the set
[a,b,c]
and theDELETE
action specifies[a,c]
, then the final attribute value is[b]
. Specifying an empty set is an error.ADD
- Adds the specified value to the item, if the attribute does not already exist. If the attribute does exist, then the behavior ofADD
depends on the data type of the attribute:If the existing attribute is a number, and if Value is also a number, then Value is mathematically added to the existing attribute. If Value is a negative number, then it is subtracted from the existing attribute.
If you use ADD
to increment or decrement a number value for an item that doesn\'t exist before the update, DynamoDB uses 0 as the initial value.Similarly, if you use
ADD
for an existing item to increment or decrement an attribute value that doesn\'t exist before the update, DynamoDB uses0
as the initial value. For example, suppose that the item you want to update doesn\'t have an attribute named itemcount, but you decide toADD
the number3
to this attribute anyway. DynamoDB will create the itemcount attribute, set its initial value to0
, and finally add3
to it. The result will be a new itemcount attribute, with a value of3
.If the existing data type is a set, and if Value is also a set, then Value is appended to the existing set. For example, if the attribute value is the set
[1,2]
, and theADD
action specified[3]
, then the final attribute value is[1,2,3]
. An error occurs if anADD
action is specified for a set attribute and the attribute type specified does not match the existing set type.Both sets must have the same primitive data type. For example, if the existing data type is a set of strings, Value must also be a set of strings.
If no item with the specified key is found in the table, the following values perform the following actions:
PUT
- Causes DynamoDB to create a new item with the specified primary key, and then adds the attribute.DELETE
- Nothing happens, because attributes cannot be deleted from a nonexistent item. The operation succeeds, but DynamoDB does not create a new item.ADD
- Causes DynamoDB to create an item with the supplied primary key and number (or set of numbers) for the attribute value. The only data types allowed are Number and Number Set.
If you provide any attributes that are part of an index key, then the data types for those attributes must match those of the schema in the table\'s attribute definition.
#condition_expression ⇒ String
A condition that must be satisfied in order for a conditional update to succeed.
An expression can contain any of the following:
Functions:
attribute_exists | attribute_not_exists | attribute_type | contains | begins_with | size
These function names are case-sensitive.
Comparison operators:
= | <> | < | > | <= | >= | BETWEEN | IN
Logical operators:
AND | OR | NOT
For more information on condition expressions, see Specifying Conditions in the Amazon DynamoDB Developer Guide.
#conditional_operator ⇒ String
A logical operator to apply to the conditions in the Expected map:
AND
- If all of the conditions evaluate to true, then the entire map evaluates to true.OR
- If at least one of the conditions evaluate to true, then the entire map evaluates to true.
If you omit ConditionalOperator, then AND
is the default.
The operation will succeed only if the entire map evaluates to true.
Possible values:
- AND
- OR
#expected ⇒ Hash<String,Types::ExpectedAttributeValue>
A map of attribute/condition pairs. Expected provides a conditional block for the UpdateItem operation.
Each element of Expected consists of an attribute name, a comparison operator, and one or more values. DynamoDB compares the attribute with the value(s) you supplied, using the comparison operator. For each Expected element, the result of the evaluation is either true or false.
If you specify more than one element in the Expected map, then by default all of the conditions must evaluate to true. In other words, the conditions are ANDed together. (You can use the ConditionalOperator parameter to OR the conditions instead. If you do this, then at least one of the conditions must evaluate to true, rather than all of them.)
If the Expected map evaluates to true, then the conditional operation succeeds; otherwise, it fails.
Expected contains the following:
AttributeValueList - One or more values to evaluate against the supplied attribute. The number of values in the list depends on the ComparisonOperator being used.
For type Number, value comparisons are numeric.
String value comparisons for greater than, equals, or less than are based on ASCII character code values. For example,
a
is greater thanA
, anda
is greater thanB
. For a list of code values, see http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters.For type Binary, DynamoDB treats each byte of the binary data as unsigned when it compares binary values.
ComparisonOperator - A comparator for evaluating attributes in the AttributeValueList. When performing the comparison, DynamoDB uses strongly consistent reads.
The following comparison operators are available:
EQ | NE | LE | LT | GE | GT | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS | BEGINS_WITH | IN | BETWEEN
The following are descriptions of each comparison operator.
EQ
: Equal.EQ
is supported for all datatypes, including lists and maps.AttributeValueList can contain only one AttributeValue element of type String, Number, Binary, String Set, Number Set, or Binary Set. If an item contains an AttributeValue element of a different type than the one provided in the request, the value does not match. For example,
`{"S":"6"}`
does not equal`{"N":"6"}`
. Also,`{"N":"6"}`
does not equal{"NS":["6", "2", "1"]}
.NE
: Not equal.NE
is supported for all datatypes, including lists and maps.AttributeValueList can contain only one AttributeValue of type String, Number, Binary, String Set, Number Set, or Binary Set. If an item contains an AttributeValue of a different type than the one provided in the request, the value does not match. For example,
`{"S":"6"}`
does not equal`{"N":"6"}`
. Also,`{"N":"6"}`
does not equal{"NS":["6", "2", "1"]}
.LE
: Less than or equal.AttributeValueList can contain only one AttributeValue element of type String, Number, or Binary (not a set type). If an item contains an AttributeValue element of a different type than the one provided in the request, the value does not match. For example,
`{"S":"6"}`
does not equal`{"N":"6"}`
. Also,`{"N":"6"}`
does not compare to{"NS":["6", "2", "1"]}
.LT
: Less than.AttributeValueList can contain only one AttributeValue of type String, Number, or Binary (not a set type). If an item contains an AttributeValue element of a different type than the one provided in the request, the value does not match. For example,
`{"S":"6"}`
does not equal`{"N":"6"}`
. Also,`{"N":"6"}`
does not compare to{"NS":["6", "2", "1"]}
.GE
: Greater than or equal.AttributeValueList can contain only one AttributeValue element of type String, Number, or Binary (not a set type). If an item contains an AttributeValue element of a different type than the one provided in the request, the value does not match. For example,
`{"S":"6"}`
does not equal`{"N":"6"}`
. Also,`{"N":"6"}`
does not compare to{"NS":["6", "2", "1"]}
.GT
: Greater than.AttributeValueList can contain only one AttributeValue element of type String, Number, or Binary (not a set type). If an item contains an AttributeValue element of a different type than the one provided in the request, the value does not match. For example,
`{"S":"6"}`
does not equal`{"N":"6"}`
. Also,`{"N":"6"}`
does not compare to{"NS":["6", "2", "1"]}
.NOT_NULL
: The attribute exists.NOT_NULL
is supported for all datatypes, including lists and maps.This operator tests for the existence of an attribute, not its data type. If the data type of attribute \" a
\" is null, and you evaluate it usingNOT_NULL
, the result is a Boolean true. This result is because the attribute \"a
\" exists; its data type is not relevant to theNOT_NULL
comparison operator.NULL
: The attribute does not exist.NULL
is supported for all datatypes, including lists and maps.This operator tests for the nonexistence of an attribute, not its data type. If the data type of attribute \" a
\" is null, and you evaluate it usingNULL
, the result is a Boolean false. This is because the attribute \"a
\" exists; its data type is not relevant to theNULL
comparison operator.CONTAINS
: Checks for a subsequence, or value in a set.AttributeValueList can contain only one AttributeValue element of type String, Number, or Binary (not a set type). If the target attribute of the comparison is of type String, then the operator checks for a substring match. If the target attribute of the comparison is of type Binary, then the operator looks for a subsequence of the target that matches the input. If the target attribute of the comparison is a set (\"
SS
\", \"NS
\", or \"BS
\"), then the operator evaluates to true if it finds an exact match with any member of the set.CONTAINS is supported for lists: When evaluating \"
a CONTAINS b
\", \"a
\" can be a list; however, \"b
\" cannot be a set, a map, or a list.NOT_CONTAINS
: Checks for absence of a subsequence, or absence of a value in a set.AttributeValueList can contain only one AttributeValue element of type String, Number, or Binary (not a set type). If the target attribute of the comparison is a String, then the operator checks for the absence of a substring match. If the target attribute of the comparison is Binary, then the operator checks for the absence of a subsequence of the target that matches the input. If the target attribute of the comparison is a set (\"
SS
\", \"NS
\", or \"BS
\"), then the operator evaluates to true if it does not find an exact match with any member of the set.NOT_CONTAINS is supported for lists: When evaluating \"
a NOT CONTAINS b
\", \"a
\" can be a list; however, \"b
\" cannot be a set, a map, or a list.BEGINS_WITH
: Checks for a prefix.AttributeValueList can contain only one AttributeValue of type String or Binary (not a Number or a set type). The target attribute of the comparison must be of type String or Binary (not a Number or a set type).
IN
: Checks for matching elements within two sets.AttributeValueList can contain one or more AttributeValue elements of type String, Number, or Binary (not a set type). These attributes are compared against an existing set type attribute of an item. If any elements of the input set are present in the item attribute, the expression evaluates to true.
BETWEEN
: Greater than or equal to the first value, and less than or equal to the second value.AttributeValueList must contain two AttributeValue elements of the same type, either String, Number, or Binary (not a set type). A target attribute matches if the target value is greater than, or equal to, the first element and less than, or equal to, the second element. If an item contains an AttributeValue element of a different type than the one provided in the request, the value does not match. For example,
`{"S":"6"}`
does not compare to`{"N":"6"}`
. Also,`{"N":"6"}`
does not compare to{"NS":["6", "2", "1"]}
For usage examples of AttributeValueList and ComparisonOperator, see Legacy Conditional Parameters in the Amazon DynamoDB Developer Guide.
For backward compatibility with previous DynamoDB releases, the following parameters can be used instead of AttributeValueList and ComparisonOperator:
Value - A value for DynamoDB to compare with an attribute.
Exists - A Boolean value that causes DynamoDB to evaluate the value before attempting the conditional operation:
If Exists is
true
, DynamoDB will check to see if that attribute value already exists in the table. If it is found, then the condition evaluates to true; otherwise the condition evaluate to false.If Exists is
false
, DynamoDB assumes that the attribute value does not exist in the table. If in fact the value does not exist, then the assumption is valid and the condition evaluates to true. If the value is found, despite the assumption that it does not exist, the condition evaluates to false.
Note that the default value for Exists is
true
.
The Value and Exists parameters are incompatible with AttributeValueList and ComparisonOperator. Note that if you use both sets of parameters at once, DynamoDB will return a ValidationException exception.
#expression_attribute_names ⇒ Hash<String,String>
One or more substitution tokens for attribute names in an expression. The following are some use cases for using ExpressionAttributeNames:
To access an attribute whose name conflicts with a DynamoDB reserved word.
To create a placeholder for repeating occurrences of an attribute name in an expression.
To prevent special characters in an attribute name from being misinterpreted in an expression.
Use the # character in an expression to dereference an attribute name. For example, consider the following attribute name:
Percentile
^
The name of this attribute conflicts with a reserved word, so it cannot be used directly in an expression. (For the complete list of reserved words, see Reserved Words in the Amazon DynamoDB Developer Guide). To work around this, you could specify the following for ExpressionAttributeNames:
`{"#P":"Percentile"}`
^
You could then use this substitution in an expression, as in this example:
#P = :val
^
For more information on expression attribute names, see Accessing Item Attributes in the Amazon DynamoDB Developer Guide.
#expression_attribute_values ⇒ Hash<String,Types::AttributeValue>
One or more values that can be substituted in an expression.
Use the : (colon) character in an expression to dereference an attribute value. For example, suppose that you wanted to check whether the value of the ProductStatus attribute was one of the following:
Available | Backordered | Discontinued
You would first need to specify ExpressionAttributeValues as follows:
{ ":avail":`{"S":"Available"}`, ":back":`{"S":"Backordered"}`,
":disc":`{"S":"Discontinued"}` }
You could then use these values in an expression, such as this:
ProductStatus IN (:avail, :back, :disc)
For more information on expression attribute values, see Specifying Conditions in the Amazon DynamoDB Developer Guide.
#key ⇒ Hash<String,Types::AttributeValue>
The primary key of the item to be updated. Each element consists of an attribute name and a value for that attribute.
For the primary key, you must provide all of the attributes. For example, with a simple primary key, you only need to provide a value for the partition key. For a composite primary key, you must provide values for both the partition key and the sort key.
#return_consumed_capacity ⇒ String
Determines the level of detail about provisioned throughput consumption that is returned in the response:
-
INDEXES - The response includes the aggregate ConsumedCapacity for the operation, together with ConsumedCapacity for each table and secondary index that was accessed.
Note that some operations, such as GetItem and BatchGetItem, do not access any indexes at all. In these cases, specifying INDEXES will only return ConsumedCapacity information for table(s).
-
TOTAL - The response includes only the aggregate ConsumedCapacity for the operation.
-
NONE - No ConsumedCapacity details are included in the response.
Possible values:
- INDEXES
- TOTAL
- NONE
#return_item_collection_metrics ⇒ String
Determines whether item collection metrics are returned. If set to
SIZE
, the response includes statistics about item collections, if any,
that were modified during the operation are returned in the response. If
set to NONE
(the default), no statistics are returned.
Possible values:
- SIZE
- NONE
#return_values ⇒ String
Use ReturnValues if you want to get the item attributes as they appeared either before or after they were updated. For UpdateItem, the valid values are:
NONE
- If ReturnValues is not specified, or if its value isNONE
, then nothing is returned. (This setting is the default for ReturnValues.)ALL_OLD
- If UpdateItem overwrote an attribute name-value pair, then the content of the old item is returned.UPDATED_OLD
- The old versions of only the updated attributes are returned.ALL_NEW
- All of the attributes of the new version of the item are returned.UPDATED_NEW
- The new versions of only the updated attributes are returned.
There is no additional cost associated with requesting a return value aside from the small network and processing overhead of receiving a larger response. No Read Capacity Units are consumed.
Values returned are strongly consistent
Possible values:
- NONE
- ALL_OLD
- UPDATED_OLD
- ALL_NEW
- UPDATED_NEW
#table_name ⇒ String
The name of the table containing the item to update.
#update_expression ⇒ String
An expression that defines one or more attributes to be updated, the action to be performed on them, and new value(s) for them.
The following action values are available for UpdateExpression.
SET
- Adds one or more attributes and values to an item. If any of these attribute already exist, they are replaced by the new values. You can also useSET
to add or subtract from an attribute that is of type Number. For example:SET myNum = myNum + :val
SET
supports the following functions:if_not_exists (path, operand)
- if the item does not contain an attribute at the specified path, thenif_not_exists
evaluates to operand; otherwise, it evaluates to path. You can use this function to avoid overwriting an attribute that may already be present in the item.list_append (operand, operand)
- evaluates to a list with a new element added to it. You can append the new element to the start or the end of the list by reversing the order of the operands.
These function names are case-sensitive.
REMOVE
- Removes one or more attributes from an item.ADD
- Adds the specified value to the item, if the attribute does not already exist. If the attribute does exist, then the behavior ofADD
depends on the data type of the attribute:If the existing attribute is a number, and if Value is also a number, then Value is mathematically added to the existing attribute. If Value is a negative number, then it is subtracted from the existing attribute.
If you use ADD
to increment or decrement a number value for an item that doesn\'t exist before the update, DynamoDB uses0
as the initial value.Similarly, if you use
ADD
for an existing item to increment or decrement an attribute value that doesn\'t exist before the update, DynamoDB uses0
as the initial value. For example, suppose that the item you want to update doesn\'t have an attribute named itemcount, but you decide toADD
the number3
to this attribute anyway. DynamoDB will create the itemcount attribute, set its initial value to0
, and finally add3
to it. The result will be a new itemcount attribute in the item, with a value of3
.If the existing data type is a set and if Value is also a set, then Value is added to the existing set. For example, if the attribute value is the set
[1,2]
, and theADD
action specified[3]
, then the final attribute value is[1,2,3]
. An error occurs if anADD
action is specified for a set attribute and the attribute type specified does not match the existing set type.Both sets must have the same primitive data type. For example, if the existing data type is a set of strings, the Value must also be a set of strings.
The ADD
action only supports Number and set data types. In addition,ADD
can only be used on top-level attributes, not nested attributes.DELETE
- Deletes an element from a set.If a set of values is specified, then those values are subtracted from the old set. For example, if the attribute value was the set
[a,b,c]
and theDELETE
action specifies[a,c]
, then the final attribute value is[b]
. Specifying an empty set is an error.The DELETE
action only supports set data types. In addition,DELETE
can only be used on top-level attributes, not nested attributes.
You can have many actions in a single expression, such as the following:
SET a=:value1, b=:value2 DELETE :value3, :value4, :value5
For more information on update expressions, see Modifying Items and Attributes in the Amazon DynamoDB Developer Guide.


A 2D Physics-Based Game Engine in Python with OpenGL
The Mindjail Engine, my hand-crafted 2D game engine!
Performance Art: Skilled Manipulation of Inertia Props
I spin Poi and Staff in my spare time
DDR Clone in Javascript and SVG
Shoof Shoof Revolution?
This is a really impressive project!
And here's another
And here's another
And here's another
And here's another
And here's another
And here's another
And here's another
And here's another


|
x,y,width,height - Initial shape of the panel
group - Group the panel belongs to style - optional style flags |
|
CreatePanel creates a panel gadget and returns a handle to it.
A panel gadget is a simple grouping gadget that is usually used to contain or 'clip' child gadgets. The optional style flag controls how the panel looks 0 - No border to the panel 1 - Sunken border to the panel By default, a borderless panel is created. See also: SetPanelImage, SetPanelColor. |


Our team is working to maintain the project runnning.
You can easily deploy an instance and update it.
We propose Software as a Service: focus on workflow, not application.
A product that evolves with your needs! Ask new features!


Client-Central provides the user with access to cardholder information relating to one or more client institutions, which are named FIIDs for Debit clients and OrgIDs for Full Service Credit clients. This page allows you to grant or remove user access to specific FIIDs and/or OrgIDs.
When the user has the Base24 System checked on the User Details page, the FIIDs section displays. When the Full Service Credit System is checked, the OrgIDs section displays.
Note: Every institution has one designated primary security administrator. Maximum privileges applicable to the institution are defined on this user's security record. Other administrators and other users can be given the same or lesser privileges. When adding or maintaining a user record, you are not able to give more access than you have. Please refer to the Security manual for further details.
Click the following links for more information:
Key Information
Auto-filled with client and user identification values.
| First Name | First name of the selected user. |
| Last Name | Last name of the selected user. |
| Institution ID | 6-digit identifier assigned by Card Services for the selected institution. |
| User ID | Client-Central user ID of the selected user. |
FIIDs for LNET
Allows you to control user FIID access.
| Available FIIDs |
Financial institution IDs available for access. You can highlight FIIDs from this list and move them to the Selected FIIDs list.
Note: This list is limited to the FIIDs specified on your own user record. |
| Selected FIIDs |
The user is granted access to all the FIIDs within the Selected FIIDs list. To remove access from the user record, highlight FIIDs in this list and move them back to the Available FIIDs list. |
OrgIDs
Allows you to control user OrgID access.
| Available OrgIDs |
OrgIDs available for access. You can highlight OrgIDs from this list and move them to the Selected OrgIDs list.
Note: This list is limited to the OrgIDs specified on your own user record. |
| Selected OrgIDs |
The user is granted access to all the OrgIDs within the Selected OrgIDs list. To remove access, highlight OrgIDs in this list and move them back to the Available OrgIDs list. |
| >> | Moves the highlighted items from the Available list to the Selected list. |
| All >> | Moves all items in the section from the Available list to the Selected list. |
| << | Moves the highlighted items from the Selected list back to the Available list. |
| All << | Moves all items in the section from the Selected list back to the Available list. |
| OK |
Temporarily stores the information entered and takes you to the User Record page. You can then choose to save your changes by selecting Update or you can make additional changes on any of the other tabs available. All changes are held until you select Update. |
| Cancel | Discards your changes and returns you to the User Record page. |


R
R
- To download R, choose a CRAN mirror closest to your geographic location.
- In order to build R packages, you should also download the latest recommended version of Rtools. Currently, the latest recommended version is
Rtoools35.exe
.
- During installation, there should be an option to add Rtools to system path. You should check this option.
- Afterwards, input the following code into R. If the output is TRUE, then Rtools was installed properly.
install.packages("devtools")
library(devtools)
find_rtools()
R Studio
- R Studio is an integrated development environment (IDE) for R. After downloading R Studio, you should be able to type the following command at the console to download some common R packages for data analysis and visualization.
install.packages(c("dplyr", "tidyr", "ggplot2", "esquisse", "stats", "xtable"))
Cleaning and Reshaping Data
library(reshape2)
library(tidyr)
library(xtable)
library(stringr)
library(knitr)
options(kableExtra.latex.load_packages = FALSE)
library(kableExtra)
library(pander)
#original data is organized by id/trial (two locations per entry)
game <- data.frame(id = c(rep("X",3), rep("Y",3), rep("Z",3)),
trial = rep(c(1,2,3), 3),
location_A = round(rnorm(9, mean = 0, sd = 1), 1),
location_B = round(rnorm(9, mean = 0, sd = 1), 1))
# reshape data from wide to long (each entry is unique by id/trial/location)
game_long <- melt(game, id = c("id","trial"), value.name = "score")
game_long$variable <- str_sub(game_long$variable,-1,-1)
colnames(game_long)[3] <- "location"
# reshape data back to wide (same as original data)
game_wide <- dcast(game_long, id + trial ~ location, value.var = "score")
# reshape data into even wider form (one entry per id with 6 value columns: 2 locations X 3 trials)
game_wider <- dcast(game_long, id ~ location + trial, value.var = "score")
# using tidyr and dplyr to reshape data
game_long2 <- game %>% gather(label, score, location_A, location_B) %>%
separate(label, c("label_p1","location"), sep = "_") %>%
dplyr::select(-label_p1)
game_wide2 <- game_long2 %>% spread(location, value = score)
#unite() function creates the location X trial combinations first in long format # then apply the spread() function to reshape into wide format
#just like in game_wide, each entry in game_wide2 is unique by id
game_wider2 <- game_long2 %>% unite(location_trial, location, trial) %>%
spread(location_trial, value = score)
#xtable method
#print(xtable(game, caption = "Wide Data Listed by Person/Trial (Scores by Location)"), type="html")
#kable method
#kable(game, caption = "Wide Data Listed by Person/Trial (Scores by Location)", booktabs = TRUE) %>%
# kable_styling(latex_options = c("hold_position"))
#pander method (most flexible)
pandoc.table(game, caption = "(\\#tab:wide) Wide Data Listed by Person/Trial (Scores by Location)")
Table 11.1: Wide Data Listed by Person/Trial (Scores by Location)
| X |
1 |
1 |
0.1 |
| X |
2 |
-0.8 |
-0.4 |
| X |
3 |
0.6 |
0 |
| Y |
1 |
-0.4 |
-2.3 |
| Y |
2 |
-0.2 |
-0.4 |
| Y |
3 |
-0.8 |
-0.5 |
| Z |
1 |
0.6 |
-1.2 |
| Z |
2 |
-0.4 |
2.4 |
| Z |
3 |
-0.4 |
-1.5 |
pandoc.table(game_wider, caption = "(\\#tab:wider) Wider Data Listed by ID (Scores by Location/Trial)")
Table 11.2: Wider Data Listed by ID (Scores by Location/Trial)
| X |
1 |
-0.8 |
0.6 |
0.1 |
-0.4 |
0 |
| Y |
-0.4 |
-0.2 |
-0.8 |
-2.3 |
-0.4 |
-0.5 |
| Z |
0.6 |
-0.4 |
-0.4 |
-1.2 |
2.4 |
-1.5 |
pandoc.table(game_long, caption = "(\\#tab:long) Long Data")
Table 11.3: Long Data
| X |
1 |
A |
1 |
| X |
2 |
A |
-0.8 |
| X |
3 |
A |
0.6 |
| Y |
1 |
A |
-0.4 |
| Y |
2 |
A |
-0.2 |
| Y |
3 |
A |
-0.8 |
| Z |
1 |
A |
0.6 |
| Z |
2 |
A |
-0.4 |
| Z |
3 |
A |
-0.4 |
| X |
1 |
B |
0.1 |
| X |
2 |
B |
-0.4 |
| X |
3 |
B |
0 |
| Y |
1 |
B |
-2.3 |
| Y |
2 |
B |
-0.4 |
| Y |
3 |
B |
-0.5 |
| Z |
1 |
B |
-1.2 |
| Z |
2 |
B |
2.4 |
| Z |
3 |
B |
-1.5 |


tl;dr: The web development environment has too many flaws for us as developers to ignore at this point. The web is broken technology and its about time someone fixed it.
The web is one of the largest platforms in the tech industry. It can in many ways be considered the core of many products and services that consumers all over the world use in a daily basis. It is a powerful tool that allows access to anyone with a computer and an internet connection. The point of this post is to highlight its strengths and weaknesses from a development point of view.
The good thing about webdev is the open world that it lives in. Webdev has many ports of entry. Anyone from can learn webdev in a matter of minutes and launch their own website in a matter of hours. It does not matter what language you know or if you know any at all. It is common for beginners in the field of computer science to approach webdev because of all the resources available.
Almost every language has a web framework that harnesses its powers. This allows experienced programmers with no knowledge of webdev to create something with it. An example is the one that I am currently using, Django powered by python. Django is a fast way to create dynamic web applications using an MVC architecture and I would highly recommend it to anyone looking for something new to learn. Others include Rails(Ruby), Nodejs(JavaScript), J2EE(Java), etc. With a little about of knowledge about the syntax and basic html we can create dynamic websites instantly.
The web also has dark parts that people don’t realize until they are deep into it. Eventually every web developer realizes that they have to worry about cross browser compatibility. This means that their technology needs to be working equally among all browsers and not just their most commonly used one. This means testing each page in Chrome, Firefox, Safari, and IE. As an experienced slave of this task I can say that never will you achieve full compatibility without some kind of sorcery. There are many resources out there that try to provide developers with this power but none are perfect.
Compatibility extends to more than just browsers. Recently we have entered a market where websites needs to be compatible with screens of every size possible and needs to be dynamically created as such. We as developers need to think about viewing and interacting with the website from phones, tablets, and computers. All of this compatibility is absolutely necessary if we want to deliver the full experience to our users. Compatibility can be a nightmare but it is just a shadow to a darker truth.
The truly dark side of web development is disguised in its static state surrounding its lack of growth. The web has very little and very old standards. The lack of evolution of HTML, JavaScript(JS), and CSS as a productive and effective language are the main causes. I think that it is unacceptable that we have to rely on things such as LESS, Compass, etc. to write our CSS for us so it can be processed by our browsers. I feel the same way about JS and how it has no intuitive form of OOP. It is a powerful free form language and I respect that however webdev often follows specific architecture that would beneficial from both the flexibility and a strongly typed version of JS. Lastly HTML, there is no greater evil than it. Have you ever counted how many classes a tag has and realized that sure you are doing something wrong. The unfortunate part is that it is most likely not you but the technology itself.
Developers we are working in a broken system. We need to work with technology that is up to par so we can do more. If we can do this we will not have to worry about compatibility as much as we will have the luxury to test everything in a more thorough manner.


--- layout: post title: "Coalescing DTOs" description: "Refactoring to a universal abstraction." date: 2022-09-12 7:35 UTC tags: [Software Design, Code] --- {% include JB/setup %}
{{ page.description }}
Despite my best efforts, no code base I write is perfect. This is also true for the code base that accompanies Code That Fits in Your Head.
One (among several) warts that has annoyed me for long is this:
[HttpPost("restaurants/{restaurantId}/reservations")] public async Task<ActionResult> Post( int restaurantId, ReservationDto dto) { if (dto is null) throw new ArgumentNullException(nameof(dto)); var id = dto.ParseId() ?? Guid.NewGuid(); Reservation? reservation = dto.Validate(id); if (reservation is null) return new BadRequestResult(); // More code follows...
Passing id
to Validate
annoys me. Why does Validate
need an id
?
When you see it in context, it may makes some sort of sense, but in isolation, it seems arbitrary:
internal Reservation? Validate(Guid id)
Why does the method need an id
? Doesn't ReservationDto
have an Id
?
Yes, indeed, ReservationDto
has an Id
property:
public string? Id { get; set; }
Then why do callers have to pass an id
argument? Doesn't Validate
use the Id
property? It's almost as though the Validate
method begs you to read the implementing code:
internal Reservation? Validate(Guid id) { if (!DateTime.TryParse(At, out var d)) return null; if (Email is null) return null; if (Quantity < 1) return null; return new Reservation( id, d, new Email(Email), new Name(Name ?? ""), Quantity); }
Indeed, the method doesn't use the Id
property. Reading the code may not be of much help, but at least we learn that id
is passed to the Reservation
constructor. It's still not clear why the method isn't trying to parse the Id
property, like it's doing with with At
.
I'll return to the motivation in a moment, but first I'd like to dwell on the problems of this design.
It's a typical example of ad-hoc design. I had a set of behaviours I needed to implement, and in order to avoid code duplication, I come up with a method that seemed to solve the problem.
And indeed, the Validate
method does solve the problem of code duplication. It also passes all tests. It could be worse.
It could also be better.
The problem with an ad-hoc design like this is that the motivation is unclear. As a reader, you feel that you're missing the full picture. Perhaps you feel compelled to read the implementation code to gain a better understanding. Perhaps you look for other call sites. Perhaps you search the Git history to find a helpful comment. Perhaps you ask a colleague.
It slows you down. Worst of all, it may leave you apprehensive of refactoring. If you feel that there's something you don't fully understand, you may decide to leave the API alone, instead of improving it.
It's one of the many ways that code slowly rots.
What's missing here is a proper abstraction.
I recently hit upon a design that I like better. Before I describe it, however, you need to understand the problem I was trying to solve.
The code base for the book is a restaurant reservation REST API, and I was evolving the code as I wrote it. I wanted the code base (and its Git history) to be as realistic as possible. In a real-world situation, you don't always know all requirements up front, or even if you do, they may change.
At one point I decided that a REST client could supply a GUID when making a new reservation. On the other hand, I had lots of existing tests (and a deployed system) that accepted reservations without IDs. In order to not break compatibility, I decided to use the ID if it was supplied with the DTO, and otherwise create one. (I later explored an API without explicit IDs, but that's a different story.)
The id
is a JSON property, however, so there's no guarantee that it's properly formatted. Thus, the need to first parse it:
var id = dto.ParseId() ?? Guid.NewGuid();
To make matters even more complicated, when you PUT
a reservation, the ID is actually part of the resource address, which means that even if it's present in the JSON document, that value should be ignored:
[HttpPut("restaurants/{restaurantId}/reservations/{id}")] public async Task<ActionResult> Put( int restaurantId, string id, ReservationDto dto) { if (dto is null) throw new ArgumentNullException(nameof(dto)); if (!Guid.TryParse(id, out var rid)) return new NotFoundResult(); Reservation? reservation = dto.Validate(rid); if (reservation is null) return new BadRequestResult(); // More code follows...
Notice that this Put
implementation exclusively considers the resource address id
parameter. Recall that the Validate
method ignores the dto
's Id
property.
This is knowledge about implementation details that leaks through to the calling code. As a client developer, you need to know and keep this knowledge in your head while you write your own code. That's not really code that fits in your head.
As I usually put it: If you have to read the code, it implies that encapsulation is broken.
At the time, however, I couldn't think of a better alternative, and since the problem is still fairly small and localised, I decided to move on. After all, perfect is the enemy of good.
Is there a better way? Perhaps you think that you've spotted an obvious improvement. Why don't I just try to parse dto.Id
and then create a Guid.NewGuid()
if parsing fails? Like this:
internal Reservation? Validate() { if (!Guid.TryParse(Id, out var id)) id = Guid.NewGuid(); if (!DateTime.TryParse(At, out var d)) return null; if (Email is null) return null; if (Quantity < 1) return null; return new Reservation( id, d, new Email(Email), new Name(Name ?? ""), Quantity); }
The short answer is: Because it doesn't work.
It may work for Get
, but then Put
doesn't have a way to tell the Validate
method which ID to use.
Or rather: That's not entirely true, because this is possible:
dto.Id = id;
Reservation? reservation = dto.Validate();
This does suggest an even better way. Before we go there, however, there's another reason I don't like this particular variation: It makes Validate
impure.
Why care? you may ask.
I always end up regretting making an otherwise potentially pure function non-deterministic. Sooner or later, it turns out to have been a bad decision, regardless of how alluring it initially looked. I recently gave an example of that.
When weighing the advantages and disadvantages, I preferred passing id
explicitly rather than relying on Guid.NewGuid()
inside Validate
.
One of the reasons I find universal abstractions beneficial is that you only have to learn them once. As Felienne Hermans writes in The Programmer's Brain our working memory juggles a combination of ephemeral data and knowledge from our long-term memory. The better you can leverage existing knowledge, the easier it is to read code.
Which universal abstraction enables you to choose from a prioritised list of candidates? The First monoid!
In C# with nullable reference types the null-coalescing operator ??
already implements the desired functionality. (If you're using another language or an older version of C#, you can instead use Maybe.)
Once I got that idea I was able to simplify the API.
Instead of that odd Validate
method which isn't quite a validator and not quite a parser, this insight suggests to parse, don't validate:
internal Reservation? TryParse() { if (!Guid.TryParse(Id, out var id)) return null; if (!DateTime.TryParse(At, out var d)) return null; if (Email is null) return null; if (Quantity < 1) return null; return new Reservation( id, d, new Email(Email), new Name(Name ?? ""), Quantity); }
This function only returns a parsed Reservation
object when the Id
is present and well-formed. What about the cases where the Id
is absent?
The calling ReservationsController
can deal with that:
Reservation? candidate1 = dto.TryParse(); dto.Id = Guid.NewGuid().ToString("N"); Reservation? candidate2 = dto.TryParse(); Reservation? reservation = candidate1 ?? candidate2; if (reservation is null) return new BadRequestResult();
First try to parse the dto
, then explicitly overwrite its Id
property with a new Guid
, and then try to parse it again. Finally, pick the first of these that aren't null, using the null-coalescing ??
operator.
This API also works consistently in the Put
method:
dto.Id = id; Reservation? reservation = dto.TryParse(); if (reservation is null) return new BadRequestResult();
Why is this better? I consider it better because the TryParse
function should be a familiar abstraction. Once you've seen a couple of those, you know that a well-behaved parser either returns a valid object, or nothing. You don't have to go and read the implementation of TryParse
to (correctly) guess that. Thus, encapsulation is maintained.
The ReservationsController
mutates the dto
and relies on the impure Guid.NewGuid()
method. Why is that okay when it wasn't okay to do this inside of Validate
?
This is because the code base follows the functional core, imperative shell architecture. Specifically, Controllers make up the imperative shell, so I consider it appropriate to put impure actions there. After all, they have to go somewhere.
This means that the TryParse
function remains pure.
Sometimes a good API design can elude you for a long time. When that happens, I move on with the best solution I can think of in the moment. As it often happens, though, ad-hoc abstractions leave me unsatisfied, so I'm always happy to improve such code later, if possible.
In this article, you saw an example of an ad-hoc API design that represented the best I could produce at the time. Later, it dawned on me that an implementation based on a universal abstraction would be possible. In this case, the universal abstraction was null coalescing (which is a specialisation of the monoid abstraction).
I like universal abstractions because, once you know them, you can trust that they work in well-understood ways. You don't have to waste time reading implementation code in order to learn whether it's safe to call a method in a particular way.
This saves time when you have to work with the code, because, after all, we spend more time reading code than writing it.
Comments
After the refactor in this article, is the entirety of your Post method (including the part you didn't show in this article) an impureim sandwich?
Not yet. There's a lot of (preliminary) interleaving of impure actions and pure functions remaining in the controller, even after this refactoring.
A future article will tackle that question. One of the reasons I even started writing about monads, functor relationships, etcetera was to establish the foundations for what this requires. If it can be done without monads and traversals I don't know how.
Even though the
Post
method isn't an impureim sandwich, I still consider the architecture functional core, imperative shell, since I've kept all impure actions in the controllers.The reason I didn't go all the way to impureim sandwiches with the book's code is didactic. For complex logic, you'll need traversals, monads, sum types, and so on, and none of those things were in scope for the book.


Visualize building construction docs and sheets online by scanning a QR Code.
This project was developed September 2015 at the AEC Technology Symposium + Hackathon in New York City.
by quickly scanning a QR code and viewing the wider building context in your browser
Example Projects| Name | Organization | Project |
|---|---|---|
| Charlie Portelli | KPF Architects | Revit |
| Matt Mason | IMAGINiT Technologies | Revit |
| Maximilian Thumtart | Thorton Tomasetti | Revit |
| Josh Wentz | Lucid | Web Viewer |
| Jonatan Schumacher | Thornton Tomasetti | Web Viewer |
| Nick Mattise | University of Maryland | Web Viewer |
| Irmak Turan | MIT | Logo |
Built at AEC Hackathon 2015 | AEC Technology Symposium 2015
Open Source MIT License | Special thanks to the open source software that made DOCQR possible: Three.js | GitHub | Bootstrap | jQuery


ReFigure was envisioned by Girija Goyal and James Akin to address an unmet need in scientific communication and early career scientists-making every experiment and every figure an actionable, creditable finding without losing the context that comes with the traditional story-telling of full length publications.


Select field type you want to add to the form below and click on 'Add Field' button. Don't forget to set field properties. After you finish creating the form, you can preview the form by clicking Preview Form button.
No fields added yet.


Guard Babenco:
I just received a report that a large army of savage Maille Lizardmen is gathering in the western section of the Town of Gludio. They're not satisfied staying on the plains.
Captain Bathis is recruiting militiamen in Gludio, and we need all the help we can get.
You seem worthy. Would you join us?
"I'll help!"


HomePage
Sign Up
Sign In
Sign Out
My Profile
Videos
FAQs
Contact Us
About us
Business Requests
{{g.organizationName}}
Approve
Delete
Announcements
{{ann.body}}
Delete
Add Announcement


|
Table 1
|
Chemical composition, concentrations (%) and calculated rete ... |
|
Table 2
|
Anthelmintic activity of T. bovei essential oil |
|
Table 3
|
Percentage inhibition of DPPH activity by T. bovei extract a ... |
|
Table 4
|
Antimicrobial activities of T. bovei essential oil |


Welcome to One Night Car, your number one source for all things Car Sharing. We're dedicated to giving you the very best of Car Sharing. Founded in 2019 by OneNightCar Team, One Night Car has come a long way from its beginnings in Erfurt. When OneNightCar first started out, its passion to provide the Best service so that One Night Car can offer you the world's most comfortable Car Sharing System. We now serve customers in Erfurt, Weimar and Jena, and are thrilled that we're able to turn our passion into our own website. we hope you enjoy our Services as much as we enjoy offering them to you. If you have any questions or comments, please don't hesitate to contact us at<EMAIL_ADDRESS>Sincerely, Your One Night Car Team


I am a troubleshooter. I am a big believer in team work, meeting goals, and reaching one’s potential. I have a solid work ethic and computer skills.
Education
Job Experience
Why take up programming?
I decided to take up programming because problem solving is my passion. Throughout my professional career, it is the one constant between all of my jobs. I love to wrap my mind around a puzzle and understand why it does or does not do what is intended. I view programming the same way. You are able to systematically go through a program and alter a simple code. That change thus allows you to enhance the intended function or solve an error that is causing the program to not perform the whay it was intended.
Here at Epicodus, I am able to create programs where I can explore the wonderful world of coding
My Projects


N-dim array¶
N-dim array module for SymPy.
Four classes are provided to handle N-dim arrays, given by the combinations dense/sparse (i.e. whether to store all elements or only the non-zero ones in memory) and mutable/immutable (immutable classes are SymPy objects, but cannot change after they have been created).
Examples¶
The following examples show the usage of Array
. This is an abbreviation for
ImmutableDenseNDimArray
, that is an immutable and dense N-dim array, the
other classes are analogous. For mutable classes it is also possible to change
element values after the object has been constructed.
Array construction can detect the shape of nested lists and tuples:
>>> from sympy.tensor.array import Array
>>> a1 = Array([[1, 2], [3, 4], [5, 6]])
>>> a1
[[1, 2], [3, 4], [5, 6]]
>>> a1.shape
(3, 2)
>>> a1.rank()
2
>>> from sympy.abc import x, y, z
>>> a2 = Array([[[x, y], [z, x*z]], [[1, x*y], [1/x, x/y]]])
>>> a2
[[[x, y], [z, x*z]], [[1, x*y], [1/x, x/y]]]
>>> a2.shape
(2, 2, 2)
>>> a2.rank()
3
Otherwise one could pass a 1-dim array followed by a shape tuple:
>>> m1 = Array(range(12), (3, 4))
>>> m1
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
>>> m2 = Array(range(12), (3, 2, 2))
>>> m2
[[[0, 1], [2, 3]], [[4, 5], [6, 7]], [[8, 9], [10, 11]]]
>>> m2[1,1,1]
7
>>> m2.reshape(4, 3)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]
Slice support:
>>> m2[:, 1, 1]
[3, 7, 11]
Elementwise derivative:
>>> from sympy.abc import x, y, z
>>> m3 = Array([x**3, x*y, z])
>>> m3.diff(x)
[3*x**2, y, 0]
>>> m3.diff(z)
[0, 0, 1]
Multiplication with other SymPy expressions is applied elementwisely:
>>> (1+x)*m3
[x**3*(x + 1), x*y*(x + 1), z*(x + 1)]
To apply a function to each element of the N-dim array, use applyfunc
:
>>> m3.applyfunc(lambda x: x/2)
[x**3/2, x*y/2, z/2]
N-dim arrays can be converted to nested lists by the tolist()
method:
>>> m2.tolist()
[[[0, 1], [2, 3]], [[4, 5], [6, 7]], [[8, 9], [10, 11]]]
>>> isinstance(m2.tolist(), list)
True
If the rank is 2, it is possible to convert them to matrices with tomatrix()
:
>>> m1.tomatrix()
Matrix([
[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9, 10, 11]])
Products and contractions¶
Tensor product between arrays \(A_{i_1,\ldots,i_n}\) and \(B_{j_1,\ldots,j_m}\) creates the combined array \(P = A \otimes B\) defined as
\(P_{i_1,\ldots,i_n,j_1,\ldots,j_m} := A_{i_1,\ldots,i_n}\cdot B_{j_1,\ldots,j_m}.\)
It is available through tensorproduct(...)
:
>>> from sympy.tensor.array import Array, tensorproduct
>>> from sympy.abc import x,y,z,t
>>> A = Array([x, y, z, t])
>>> B = Array([1, 2, 3, 4])
>>> tensorproduct(A, B)
[[x, 2*x, 3*x, 4*x], [y, 2*y, 3*y, 4*y], [z, 2*z, 3*z, 4*z], [t, 2*t, 3*t, 4*t]]
Tensor product between a rank-1 array and a matrix creates a rank-3 array:
>>> from sympy import eye
>>> p1 = tensorproduct(A, eye(4))
>>> p1
[[[x, 0, 0, 0], [0, x, 0, 0], [0, 0, x, 0], [0, 0, 0, x]], [[y, 0, 0, 0], [0, y, 0, 0], [0, 0, y, 0], [0, 0, 0, y]], [[z, 0, 0, 0], [0, z, 0, 0], [0, 0, z, 0], [0, 0, 0, z]], [[t, 0, 0, 0], [0, t, 0, 0], [0, 0, t, 0], [0, 0, 0, t]]]
Now, to get back \(A_0 \otimes \mathbf{1}\) one can access \(p_{0,m,n}\) by slicing:
>>> p1[0,:,:]
[[x, 0, 0, 0], [0, x, 0, 0], [0, 0, x, 0], [0, 0, 0, x]]
Tensor contraction sums over the specified axes, for example contracting positions \(a\) and \(b\) means
\(A_{i_1,\ldots,i_a,\ldots,i_b,\ldots,i_n} \implies \sum_k A_{i_1,\ldots,k,\ldots,k,\ldots,i_n}\)
Remember that Python indexing is zero starting, to contract the a-th and b-th axes it is therefore necessary to specify \(a-1\) and \(b-1\)
>>> from sympy.tensor.array import tensorcontraction
>>> C = Array([[x, y], [z, t]])
The matrix trace is equivalent to the contraction of a rank-2 array:
\(A_{m,n} \implies \sum_k A_{k,k}\)
>>> tensorcontraction(C, (0, 1))
t + x
Matrix product is equivalent to a tensor product of two rank-2 arrays, followed by a contraction of the 2nd and 3rd axes (in Python indexing axes number 1, 2).
\(A_{m,n}\cdot B_{i,j} \implies \sum_k A_{m, k}\cdot B_{k, j}\)
>>> D = Array([[2, 1], [0, -1]])
>>> tensorcontraction(tensorproduct(C, D), (1, 2))
[[2*x, x - y], [2*z, -t + z]]
One may verify that the matrix product is equivalent:
>>> from sympy import Matrix
>>> Matrix([[x, y], [z, t]])*Matrix([[2, 1], [0, -1]])
Matrix([
[2*x, x - y],
[2*z, -t + z]])
or equivalently
>>> C.tomatrix()*D.tomatrix()
Matrix([
[2*x, x - y],
[2*z, -t + z]])
Derivatives by array¶
The usual derivative operation may be extended to support derivation with respect to arrays, provided that all elements in the that array are symbols or expressions suitable for derivations.
The definition of a derivative by an array is as follows: given the array \(A_{i_1, \ldots, i_N}\) and the array \(X_{j_1, \ldots, j_M}\) the derivative of arrays will return a new array \(B\) defined by
\(B_{j_1,\ldots,j_M,i_1,\ldots,i_N} := \frac{\partial A_{i_1,\ldots,i_N}}{\partial X_{j_1,\ldots,j_M}}\)
The function derive_by_array
performs such an operation:
>>> from sympy.tensor.array import Array, tensorcontraction, derive_by_array
>>> from sympy.abc import x, y, z, t
>>> from sympy import sin, exp, symbols, Function
With scalars, it behaves exactly as the ordinary derivative:
>>> derive_by_array(sin(x*y), x)
y*cos(x*y)
Scalar derived by an array basis:
>>> derive_by_array(sin(x*y), [x, y, z])
[y*cos(x*y), x*cos(x*y), 0]
Deriving array by an array basis: \(B^{nm} := \frac{\partial A^m}{\partial x^n}\)
>>> basis = [x, y, z]
>>> ax = derive_by_array([exp(x), sin(y*z), t], basis)
>>> ax
[[exp(x), 0, 0], [0, z*cos(y*z), 0], [0, y*cos(y*z), 0]]
Contraction of the resulting array: \(\sum_m \frac{\partial A^m}{\partial x^m}\)
>>> tensorcontraction(ax, (0, 1))
z*cos(y*z) + exp(x)


The
Performance Style controls how your score is played back.
- Simple Roll
- Scrolls the score like roll of parchment at an even pace.
- Roll by Measure
- Let's you playback scores that have a complex flow. Choose this style if your score contains Repeats, Dal Sengo, Coda or similar sections.
- Manual
- Manual style.
Check out the help section of each style for more information.


Looks familiar.
You may have notice that HTML tags can be nested. For example, in the following the pre-formatted text is nested inside the blockquote:
<blockquote> <pre> Indented, preformatted, text </pre> </blockquote>
| correct | wrong |
|---|---|
( [ ] ) |
( [ ) ] |
<blockquote> <pre> </pre> </blockquote> |
<blockquote> <pre> </blockquote> </pre> |
This is correct syntax, and does what you expect. The <blockquote> "turns on" the blockquote, then the <pre> "turns on" pre-formatting, so both apply.
To follow correct syntax, you should "turn off" features in the backward order of how they were turned on. So if pre-formatting was last to be turn on, it should be first to be turned off (as is done in the above). Another way to think of this is that tags nest like parentheses and brackets in math (or programs).
Most browsers do not enforce this rule, but the official latest version of HTML (XHTML) requires this.