001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 /* 019 * $Id: DTM.java<PHONE_NUMBER>-10-28 07:07:05Z minchau $ 020 */ 021 package org.apache.xml.dtm; 022 023 import javax.xml.transform.SourceLocator; 024 025 import org.apache.xml.utils.XMLString; 026 027 /** 028 * DTM is an XML document model expressed as a table 029 * rather than an object tree. It attempts to provide an interface to 030 * a parse tree that has very little object creation. (DTM 031 * implementations may also support incremental construction of the 032 * model, but that's hidden from the DTM API.) 033 * 034 *
Nodes in the DTM are identified by integer "handles". A handle must 035 * be unique within a process, and carries both node identification and 036 * document identification. It must be possible to compare two handles 037 * (and thus their nodes) for identity with "==".
 038 * 039 *
Namespace URLs, local-names, and expanded-names can all be 040 * represented by and tested as integer ID values. An expanded name 041 * represents (and may or may not directly contain) a combination of 042 * the URL ID, and the local-name ID. Note that the namespace URL id 043 * can be 0, which should have the meaning that the namespace is null. 044 * For consistancy, zero should not be used for a local-name index.
 045 * 046 *
Text content of a node is represented by an index and length, 047 * permitting efficient storage such as a shared FastStringBuffer.
 048 * 049 *
The model of the tree, as well as the general navigation model, 050 * is that of XPath 1.0, for the moment. The model will eventually be 051 * adapted to match the XPath 2.0 data model, XML Schema, and 052 * InfoSet.
 053 * 054 *
DTM does _not_ directly support the W3C's Document Object 055 * Model. However, it attempts to come close enough that an 056 * implementation of DTM can be created that wraps a DOM and vice 057 * versa.
 058 * 059 *
Please Note: The DTM API is still 060 * Subject To Change. This wouldn't affect most 061 * users, but might require updating some extensions.
 062 * 063 *
 The largest change being contemplated is a reconsideration of 064 * the Node Handle representation. We are still not entirely sure 065 * that an integer packed with two numeric subfields is really the 066 * best solution. It has been suggested that we move up to a Long, to 067 * permit more nodes per document without having to reduce the number 068 * of slots in the DTMManager. There's even been a proposal that we 069 * replace these integers with "cursor" objects containing the 070 * internal node id and a pointer to the actual DTM object; this might 071 * reduce the need to continuously consult the DTMManager to retrieve 072 * the latter, and might provide a useful "hook" back into normal Java 073 * heap management. But changing this datatype would have huge impact 074 * on Xalan's internals -- especially given Java's lack of C-style 075 * typedefs -- so we won't cut over unless we're convinced the new 076 * solution really would be an improvement!
 077 * */ 078 public interface DTM 079 { 080 081 /** 082 * Null node handles are represented by this value. 083 */ 084 public static final int NULL = -1; 085 086 // These nodeType mnemonics and values are deliberately the same as those 087 // used by the DOM, for convenient mapping 088 // 089 // %REVIEW% Should we actually define these as initialized to, 090 // eg. org.w3c.dom.Document.ELEMENT_NODE? 091 092 /** 093 * The node is a Root. 094 */ 095 public static final short ROOT_NODE = 0; 096 097 /** 098 * The node is an Element. 099 */ 100 public static final short ELEMENT_NODE = 1; 101 102 /** 103 * The node is an Attr. 104 */ 105 public static final short ATTRIBUTE_NODE = 2; 106 107 /** 108 * The node is a Text node. 109 */ 110 public static final short TEXT_NODE = 3; 111 112 /** 113 * The node is a CDATASection. 114 */ 115 public static final short CDATA_SECTION_NODE = 4; 116 117 /** 118 * The node is an EntityReference. 119 */ 120 public static final short ENTITY_REFERENCE_NODE = 5; 121 122 /** 123 * The node is an Entity. 124 */ 125 public static final short ENTITY_NODE = 6; 126 127 /** 128 * The node is a ProcessingInstruction. 129 */ 130 public static final short PROCESSING_INSTRUCTION_NODE = 7; 131 132 /** 133 * The node is a Comment. 134 */ 135 public static final short COMMENT_NODE = 8; 136 137 /** 138 * The node is a Document. 139 */ 140 public static final short DOCUMENT_NODE = 9; 141 142 /** 143 * The node is a DocumentType. 144 */ 145 public static final short DOCUMENT_TYPE_NODE = 10; 146 147 /** 148 * The node is a DocumentFragment. 149 */ 150 public static final short DOCUMENT_FRAGMENT_NODE = 11; 151 152 /** 153 * The node is a Notation. 154 */ 155 public static final short NOTATION_NODE = 12; 156 157 /** 158 * The node is a namespace node. Note that this is not 159 * currently a node type defined by the DOM API. 160 */ 161 public static final short NAMESPACE_NODE = 13; 162 163 /** 164 * The number of valid nodetypes. 165 */ 166 public static final short NTYPES = 14; 167 168 // ========= DTM Implementation Control Functions. ============== 169 // %TBD% RETIRED -- do via setFeature if needed. Remove from impls. 170 // public void setParseBlockSize(int blockSizeSuggestion); 171 172 /** 173 * Set an implementation dependent feature. 174 *
 175 * %REVIEW% Do we really expect to set features on DTMs? 176 * 177 * @param featureId A feature URL. 178 * @param state true if this feature should be on, false otherwise. 179 */ 180 public void setFeature(String featureId, boolean state); 181 182 /** 183 * Set a run time property for this DTM instance. 184 * 185 * @param property a String value 186 * @param value an Object value 187 */ 188 public void setProperty(String property, Object value); 189 190 // ========= Document Navigation Functions ========= 191 192 /** 193 * This returns a stateless "traverser", that can navigate over an 194 * XPath axis, though not in document order. 195 * 196 * @param axis One of Axes.ANCESTORORSELF, etc. 197 * 198 * @return A DTMAxisIterator, or null if the givin axis isn't supported. 199 */ 200 public DTMAxisTraverser getAxisTraverser(final int axis); 201 202 /** 203 * This is a shortcut to the iterators that implement 204 * XPath axes. 205 * Returns a bare-bones iterator that must be initialized 206 * with a start node (using iterator.setStartNode()). 207 * 208 * @param axis One of Axes.ANCESTORORSELF, etc. 209 * 210 * @return A DTMAxisIterator, or null if the givin axis isn't supported. 211 */ 212 public DTMAxisIterator getAxisIterator(final int axis); 213 214 /** 215 * Get an iterator that can navigate over an XPath Axis, predicated by 216 * the extended type ID. 217 * 218 * @param axis 219 * @param type An extended type ID. 220 * 221 * @return A DTMAxisIterator, or null if the givin axis isn't supported. 222 */ 223 public DTMAxisIterator getTypedAxisIterator(final int axis, final int type); 224 225 /** 226 * Given a node handle, test if it has child nodes. 227 *
 %REVIEW% This is obviously useful at the DOM layer, where it 228 * would permit testing this without having to create a proxy 229 * node. It's less useful in the DTM API, where 230 * (dtm.getFirstChild(nodeHandle)!=DTM.NULL) is just as fast and 231 * almost as self-evident. But it's a convenience, and eases porting 232 * of DOM code to DTM.
 233 * 234 * @param nodeHandle int Handle of the node. 235 * @return int true if the given node has child nodes. 236 */ 237 public boolean hasChildNodes(int nodeHandle); 238 239 /** 240 * Given a node handle, get the handle of the node's first child. 241 * 242 * @param nodeHandle int Handle of the node. 243 * @return int DTM node-number of first child, 244 * or DTM.NULL to indicate none exists. 245 */ 246 public int getFirstChild(int nodeHandle); 247 248 /** 249 * Given a node handle, get the handle of the node's last child. 250 * 251 * @param nodeHandle int Handle of the node. 252 * @return int Node-number of last child, 253 * or DTM.NULL to indicate none exists. 254 */ 255 public int getLastChild(int nodeHandle); 256 257 /** 258 * Retrieves an attribute node by local name and namespace URI 259 * 260 * %TBD% Note that we currently have no way to support 261 * the DOM's old getAttribute() call, which accesses only the qname. 262 * 263 * @param elementHandle Handle of the node upon which to look up this attribute. 264 * @param namespaceURI The namespace URI of the attribute to 265 * retrieve, or null. 266 * @param name The local name of the attribute to 267 * retrieve. 268 * @return The attribute node handle with the specified name ( 269 * nodeName) or DTM.NULL if there is no such 270 * attribute. 271 */ 272 public int getAttributeNode(int elementHandle, String namespaceURI, 273 String name); 274 275 /** 276 * Given a node handle, get the index of the node's first attribute. 277 * 278 * @param nodeHandle int Handle of the node. 279 * @return Handle of first attribute, or DTM.NULL to indicate none exists. 280 */ 281 public int getFirstAttribute(int nodeHandle); 282 283 /** 284 * Given a node handle, get the index of the node's first namespace node. 285 * 286 * @param nodeHandle handle to node, which should probably be an element 287 * node, but need not be. 288 * 289 * @param inScope true if all namespaces in scope should be 290 * returned, false if only the node's own 291 * namespace declarations should be returned. 292 * @return handle of first namespace, 293 * or DTM.NULL to indicate none exists. 294 */ 295 public int getFirstNamespaceNode(int nodeHandle, boolean inScope); 296 297 /** 298 * Given a node handle, advance to its next sibling. 299 * @param nodeHandle int Handle of the node. 300 * @return int Node-number of next sibling, 301 * or DTM.NULL to indicate none exists. 302 */ 303 public int getNextSibling(int nodeHandle); 304 305 /** 306 * Given a node handle, find its preceeding sibling. 307 * WARNING: DTM implementations may be asymmetric; in some, 308 * this operation has been resolved by search, and is relatively expensive. 309 * 310 * @param nodeHandle the id of the node. 311 * @return int Node-number of the previous sib, 312 * or DTM.NULL to indicate none exists. 313 */ 314 public int getPreviousSibling(int nodeHandle); 315 316 /** 317 * Given a node handle, advance to the next attribute. If an 318 * element, we advance to its first attribute; if an attr, we advance to 319 * the next attr of the same element. 320 * 321 * @param nodeHandle int Handle of the node. 322 * @return int DTM node-number of the resolved attr, 323 * or DTM.NULL to indicate none exists. 324 */ 325 public int getNextAttribute(int nodeHandle); 326 327 /** 328 * Given a namespace handle, advance to the next namespace in the same scope 329 * (local or local-plus-inherited, as selected by getFirstNamespaceNode) 330 * 331 * @param baseHandle handle to original node from where the first child 332 * was relative to (needed to return nodes in document order). 333 * @param namespaceHandle handle to node which must be of type 334 * NAMESPACE_NODE. 335 * NEEDSDOC @param inScope 336 * @return handle of next namespace, 337 * or DTM.NULL to indicate none exists. 338 */ 339 public int getNextNamespaceNode(int baseHandle, int namespaceHandle, 340 boolean inScope); 341 342 /** 343 * Given a node handle, find its parent node. 344 * 345 * @param nodeHandle the id of the node. 346 * @return int Node handle of parent, 347 * or DTM.NULL to indicate none exists. 348 */ 349 public int getParent(int nodeHandle); 350 351 /** 352 * Given a DTM which contains only a single document, 353 * find the Node Handle of the Document node. Note 354 * that if the DTM is configured so it can contain multiple 355 * documents, this call will return the Document currently 356 * under construction -- but may return null if it's between 357 * documents. Generally, you should use getOwnerDocument(nodeHandle) 358 * or getDocumentRoot(nodeHandle) instead. 359 * 360 * @return int Node handle of document, or DTM.NULL if a shared DTM 361 * can not tell us which Document is currently active. 362 */ 363 public int getDocument(); 364 365 /** 366 * Given a node handle, find the owning document node. This version mimics 367 * the behavior of the DOM call by the same name. 368 * 369 * @param nodeHandle the id of the node. 370 * @return int Node handle of owning document, or DTM.NULL if the node was 371 * a Document. 372 * @see #getDocumentRoot(int nodeHandle) 373 */ 374 public int getOwnerDocument(int nodeHandle); 375 376 /** 377 * Given a node handle, find the owning document node. 378 * 379 * @param nodeHandle the id of the node. 380 * @return int Node handle of owning document, or the node itself if it was 381 * a Document. (Note difference from DOM, where getOwnerDocument returns 382 * null for the Document node.) 383 * @see #getOwnerDocument(int nodeHandle) 384 */ 385 public int getDocumentRoot(int nodeHandle); 386 387 /** 388 * Get the string-value of a node as a String object 389 * (see http://www.w3.org/TR/xpath#data-model 390 * for the definition of a node's string-value). 391 * 392 * @param nodeHandle The node ID. 393 * 394 * @return A string object that represents the string-value of the given node. 395 */ 396 public XMLString getStringValue(int nodeHandle); 397 398 /** 399 * Get number of character array chunks in 400 * the string-value of a node. 401 * (see http://www.w3.org/TR/xpath#data-model 402 * for the definition of a node's string-value). 403 * Note that a single text node may have multiple text chunks. 404 * 405 * @param nodeHandle The node ID. 406 * 407 * @return number of character array chunks in 408 * the string-value of a node. 409 */ 410 public int getStringValueChunkCount(int nodeHandle); 411 412 /** 413 * Get a character array chunk in the string-value of a node. 414 * (see http://www.w3.org/TR/xpath#data-model 415 * for the definition of a node's string-value). 416 * Note that a single text node may have multiple text chunks. 417 * 418 * @param nodeHandle The node ID. 419 * @param chunkIndex Which chunk to get. 420 * @param startAndLen A two-integer array which, upon return, WILL 421 * BE FILLED with values representing the chunk's start position 422 * within the returned character buffer and the length of the chunk. 423 * @return The character array buffer within which the chunk occurs, 424 * setting startAndLen's contents as a side-effect. 425 */ 426 public char[] getStringValueChunk(int nodeHandle, int chunkIndex, 427 int[] startAndLen); 428 429 /** 430 * Given a node handle, return an ID that represents the node's expanded name. 431 * 432 * @param nodeHandle The handle to the node in question. 433 * 434 * @return the expanded-name id of the node. 435 */ 436 public int getExpandedTypeID(int nodeHandle); 437 438 /** 439 * Given an expanded name, return an ID. If the expanded-name does not 440 * exist in the internal tables, the entry will be created, and the ID will 441 * be returned. Any additional nodes that are created that have this 442 * expanded name will use this ID. 443 * 444 * NEEDSDOC @param namespace 445 * NEEDSDOC @param localName 446 * NEEDSDOC @param type 447 * 448 * @return the expanded-name id of the node. 449 */ 450 public int getExpandedTypeID(String namespace, String localName, int type); 451 452 /** 453 * Given an expanded-name ID, return the local name part. 454 * 455 * @param ExpandedNameID an ID that represents an expanded-name. 456 * @return String Local name of this node. 457 */ 458 public String getLocalNameFromExpandedNameID(int ExpandedNameID); 459 460 /** 461 * Given an expanded-name ID, return the namespace URI part. 462 * 463 * @param ExpandedNameID an ID that represents an expanded-name. 464 * @return String URI value of this node's namespace, or null if no 465 * namespace was resolved. 466 */ 467 public String getNamespaceFromExpandedNameID(int ExpandedNameID); 468 469 /** 470 * Given a node handle, return its DOM-style node name. This will 471 * include names such as #text or #document. 472 * 473 * @param nodeHandle the id of the node. 474 * @return String Name of this node, which may be an empty string. 475 * %REVIEW% Document when empty string is possible... 476 */ 477 public String getNodeName(int nodeHandle); 478 479 /** 480 * Given a node handle, return the XPath node name. This should be 481 * the name as described by the XPath data model, NOT the DOM-style 482 * name. 483 * 484 * @param nodeHandle the id of the node. 485 * @return String Name of this node. 486 */ 487 public String getNodeNameX(int nodeHandle); 488 489 /** 490 * Given a node handle, return its DOM-style localname. 491 * (As defined in Namespaces, this is the portion of the name after the 492 * prefix, if present, or the whole node name if no prefix exists) 493 * 494 * @param nodeHandle the id of the node. 495 * @return String Local name of this node. 496 */ 497 public String getLocalName(int nodeHandle); 498 499 /** 500 * Given a namespace handle, return the prefix that the namespace decl is 501 * mapping. 502 * Given a node handle, return the prefix used to map to the namespace. 503 * (As defined in Namespaces, this is the portion of the name before any 504 * colon character). 505 * 506 *
 %REVIEW% Are you sure you want "" for no prefix?
 507 * 508 * @param nodeHandle the id of the node. 509 * @return String prefix of this node's name, or "" if no explicit 510 * namespace prefix was given. 511 */ 512 public String getPrefix(int nodeHandle); 513 514 /** 515 * Given a node handle, return its DOM-style namespace URI 516 * (As defined in Namespaces, this is the declared URI which this node's 517 * prefix -- or default in lieu thereof -- was mapped to.) 518 * @param nodeHandle the id of the node. 519 * @return String URI value of this node's namespace, or null if no 520 * namespace was resolved. 521 */ 522 public String getNamespaceURI(int nodeHandle); 523 524 /** 525 * Given a node handle, return its node value. This is mostly 526 * as defined by the DOM, but may ignore some conveniences. 527 *
 528 * @param nodeHandle The node id. 529 * @return String Value of this node, or null if not 530 * meaningful for this node type. 531 */ 532 public String getNodeValue(int nodeHandle); 533 534 /** 535 * Given a node handle, return its DOM-style node type. 536 * 537 *
%REVIEW% Generally, returning short is false economy. Return int?
 538 * 539 * @param nodeHandle The node id. 540 * @return int Node type, as per the DOM's Node._NODE constants. 541 */ 542 public short getNodeType(int nodeHandle); 543 544 /** 545 * Get the depth level of this node in the tree (equals 1 for 546 * a parentless node). 547 * 548 * @param nodeHandle The node id. 549 * @return the number of ancestors, plus one 550 * @xsl.usage internal 551 */ 552 public short getLevel(int nodeHandle); 553 554 // ============== Document query functions ============== 555 556 /** 557 * Tests whether DTM DOM implementation implements a specific feature and 558 * that feature is supported by this node. 559 * @param feature The name of the feature to test. 560 * @param version This is the version number of the feature to test. 561 * If the version is not 562 * specified, supporting any version of the feature will cause the 563 * method to return true. 564 * @return Returns true if the specified feature is 565 * supported on this node, false otherwise. 566 */ 567 public boolean isSupported(String feature, String version); 568 569 /** 570 * Return the base URI of the document entity. If it is not known 571 * (because the document was parsed from a socket connection or from 572 * standard input, for example), the value of this property is unknown. 573 * 574 * @return the document base URI String object or null if unknown. 575 */ 576 public String getDocumentBaseURI(); 577 578 /** 579 * Set the base URI of the document entity. 580 * 581 * @param baseURI the document base URI String object or null if unknown. 582 */ 583 public void setDocumentBaseURI(String baseURI); 584 585 /** 586 * Return the system identifier of the document entity. If 587 * it is not known, the value of this property is null. 588 * 589 * @param nodeHandle The node id, which can be any valid node handle. 590 * @return the system identifier String object or null if unknown. 591 */ 592 public String getDocumentSystemIdentifier(int nodeHandle); 593 594 /** 595 * Return the name of the character encoding scheme 596 * in which the document entity is expressed. 597 * 598 * @param nodeHandle The node id, which can be any valid node handle. 599 * @return the document encoding String object. 600 */ 601 public String getDocumentEncoding(int nodeHandle); 602 603 /** 604 * Return an indication of the standalone status of the document, 605 * either "yes" or "no". This property is derived from the optional 606 * standalone document declaration in the XML declaration at the 607 * beginning of the document entity, and has no value if there is no 608 * standalone document declaration. 609 * 610 * @param nodeHandle The node id, which can be any valid node handle. 611 * @return the document standalone String object, either "yes", "no", or null. 612 */ 613 public String getDocumentStandalone(int nodeHandle); 614 615 /** 616 * Return a string representing the XML version of the document. This 617 * property is derived from the XML declaration optionally present at the 618 * beginning of the document entity, and has no value if there is no XML 619 * declaration. 620 * 621 * @param documentHandle the document handle 622 * @return the document version String object 623 */ 624 public String getDocumentVersion(int documentHandle); 625 626 /** 627 * Return an indication of 628 * whether the processor has read the complete DTD. Its value is a 629 * boolean. If it is false, then certain properties (indicated in their 630 * descriptions below) may be unknown. If it is true, those properties 631 * are never unknown. 632 * 633 * @return true if all declarations were processed; 634 * false otherwise. 635 */ 636 public boolean getDocumentAllDeclarationsProcessed(); 637 638 /** 639 * A document type declaration information item has the following properties: 640 * 641 * 1. [system identifier] The system identifier of the external subset, if 642 * it exists. Otherwise this property has no value. 643 * 644 * @return the system identifier String object, or null if there is none. 645 */ 646 public String getDocumentTypeDeclarationSystemIdentifier(); 647 648 /** 649 * Return the public identifier of the external subset, 650 * normalized as described in 4.2.2 External Entities [XML]. If there is 651 * no external subset or if it has no public identifier, this property 652 * has no value. 653 * 654 * @return the public identifier String object, or null if there is none. 655 */ 656 public String getDocumentTypeDeclarationPublicIdentifier(); 657 658 /** 659 * Returns the Element whose ID is given by 660 * elementId. If no such element exists, returns 661 * DTM.NULL. Behavior is not defined if more than one element 662 * has this ID. Attributes (including those 663 * with the name "ID") are not of type ID unless so defined by DTD/Schema 664 * information available to the DTM implementation. 665 * Implementations that do not know whether attributes are of type ID or 666 * not are expected to return DTM.NULL. 667 * 668 *
%REVIEW% Presumably IDs are still scoped to a single document, 669 * and this operation searches only within a single document, right? 670 * Wouldn't want collisions between DTMs in the same process.
 671 * 672 * @param elementId The unique id value for an element. 673 * @return The handle of the matching element. 674 */ 675 public int getElementById(String elementId); 676 677 /** 678 * The getUnparsedEntityURI function returns the URI of the unparsed 679 * entity with the specified name in the same document as the context 680 * node (see [3.3 Unparsed Entities]). It returns the empty string if 681 * there is no such entity. 682 *
 683 * XML processors may choose to use the System Identifier (if one 684 * is provided) to resolve the entity, rather than the URI in the 685 * Public Identifier. The details are dependent on the processor, and 686 * we would have to support some form of plug-in resolver to handle 687 * this properly. Currently, we simply return the System Identifier if 688 * present, and hope that it a usable URI or that our caller can 689 * map it to one. 690 * %REVIEW% Resolve Public Identifiers... or consider changing function name. 691 *
 692 * If we find a relative URI 693 * reference, XML expects it to be resolved in terms of the base URI 694 * of the document. The DOM doesn't do that for us, and it isn't 695 * entirely clear whether that should be done here; currently that's 696 * pushed up to a higher level of our application. (Note that DOM Level 697 * 1 didn't store the document's base URI.) 698 * %REVIEW% Consider resolving Relative URIs. 699 *
 700 * (The DOM's statement that "An XML processor may choose to 701 * completely expand entities before the structure model is passed 702 * to the DOM" refers only to parsed entities, not unparsed, and hence 703 * doesn't affect this function.) 704 * 705 * @param name A string containing the Entity Name of the unparsed 706 * entity. 707 * 708 * @return String containing the URI of the Unparsed Entity, or an 709 * empty string if no such entity exists. 710 */ 711 public String getUnparsedEntityURI(String name); 712 713 // ============== Boolean methods ================ 714 715 /** 716 * Return true if the xsl:strip-space or xsl:preserve-space was processed 717 * during construction of the document contained in this DTM. 718 * 719 * NEEDSDOC ($objectName$) @return 720 */ 721 public boolean supportsPreStripping(); 722 723 /** 724 * Figure out whether nodeHandle2 should be considered as being later 725 * in the document than nodeHandle1, in Document Order as defined 726 * by the XPath model. This may not agree with the ordering defined 727 * by other XML applications. 728 *
 729 * There are some cases where ordering isn't defined, and neither are 730 * the results of this function -- though we'll generally return true. 731 *
 732 * %REVIEW% Make sure this does the right thing with attribute nodes!!! 733 *
 734 * %REVIEW% Consider renaming for clarity. Perhaps isDocumentOrder(a,b)? 735 * 736 * @param firstNodeHandle DOM Node to perform position comparison on. 737 * @param secondNodeHandle DOM Node to perform position comparison on. 738 * 739 * @return false if secondNode comes before firstNode, otherwise return true. 740 * You can think of this as 741 * (firstNode.documentOrderPosition <= secondNode.documentOrderPosition). 742 */ 743 public boolean isNodeAfter(int firstNodeHandle, int secondNodeHandle); 744 745 /** 746 * 2. [element content whitespace] A boolean indicating whether a 747 * text node represents white space appearing within element content 748 * (see [XML], 2.10 "White Space Handling"). Note that validating 749 * XML processors are required by XML 1.0 to provide this 750 * information... but that DOM Level 2 did not support it, since it 751 * depends on knowledge of the DTD which DOM2 could not guarantee 752 * would be available. 753 *
 754 * If there is no declaration for the containing element, an XML 755 * processor must assume that the whitespace could be meaningful and 756 * return false. If no declaration has been read, but the [all 757 * declarations processed] property of the document information item 758 * is false (so there may be an unread declaration), then the value 759 * of this property is indeterminate for white space characters and 760 * should probably be reported as false. It is always false for text 761 * nodes that contain anything other than (or in addition to) white 762 * space. 763 *
 764 * Note too that it always returns false for non-Text nodes. 765 *
 766 * %REVIEW% Joe wants to rename this isWhitespaceInElementContent() for clarity 767 * 768 * @param nodeHandle the node ID. 769 * @return true if the node definitely represents whitespace in 770 * element content; false otherwise. 771 */ 772 public boolean isCharacterElementContentWhitespace(int nodeHandle); 773 774 /** 775 * 10. [all declarations processed] This property is not strictly speaking 776 * part of the infoset of the document. Rather it is an indication of 777 * whether the processor has read the complete DTD. Its value is a 778 * boolean. If it is false, then certain properties (indicated in their 779 * descriptions below) may be unknown. If it is true, those properties 780 * are never unknown. 781 * 782 * @param documentHandle A node handle that must identify a document. 783 * @return true if all declarations were processed; 784 * false otherwise. 785 */ 786 public boolean isDocumentAllDeclarationsProcessed(int documentHandle); 787 788 /** 789 * 5. [specified] A flag indicating whether this attribute was actually 790 * specified in the start-tag of its element, or was defaulted from the 791 * DTD (or schema). 792 * 793 * @param attributeHandle The attribute handle 794 * @return true if the attribute was specified; 795 * false if it was defaulted or the handle doesn't 796 * refer to an attribute node. 797 */ 798 public boolean isAttributeSpecified(int attributeHandle); 799 800 // ========== Direct SAX Dispatch, for optimization purposes ======== 801 802 /** 803 * Directly call the 804 * characters method on the passed ContentHandler for the 805 * string-value of the given node (see http://www.w3.org/TR/xpath#data-model 806 * for the definition of a node's string-value). Multiple calls to the 807 * ContentHandler's characters methods may well occur for a single call to 808 * this method. 809 * 810 * @param nodeHandle The node ID. 811 * @param ch A non-null reference to a ContentHandler. 812 * @param normalize true if the content should be normalized according to 813 * the rules for the XPath 814 * normalize-space 815 * function. 816 * 817 * @throws org.xml.sax.SAXException 818 */ 819 public void dispatchCharactersEvents( 820 int nodeHandle, org.xml.sax.ContentHandler ch, boolean normalize) 821 throws org.xml.sax.SAXException; 822 823 /** 824 * Directly create SAX parser events representing the XML content of 825 * a DTM subtree. This is a "serialize" operation. 826 * 827 * @param nodeHandle The node ID. 828 * @param ch A non-null reference to a ContentHandler. 829 * 830 * @throws org.xml.sax.SAXException 831 */ 832 public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch) 833 throws org.xml.sax.SAXException; 834 835 /** 836 * Return an DOM node for the given node. 837 * 838 * @param nodeHandle The node ID. 839 * 840 * @return A node representation of the DTM node. 841 */ 842 public org.w3c.dom.Node getNode(int nodeHandle); 843 844 // ==== Construction methods (may not be supported by some implementations!) ===== 845 // %REVIEW% What response occurs if not supported? 846 847 /** 848 * @return true iff we're building this model incrementally (eg 849 * we're partnered with a CoroutineParser) and thus require that the 850 * transformation and the parse run simultaneously. Guidance to the 851 * DTMManager. 852 */ 853 public boolean needsTwoThreads(); 854 855 // %REVIEW% Do these appends make any sense, should we support a 856 // wider set of methods (like the "append" methods in the 857 // current DTMDocumentImpl draft), or should we just support SAX 858 // listener interfaces? Should it be a separate interface to 859 // make that distinction explicit? 860 861 /** 862 * Return this DTM's content handler, if it has one. 863 * 864 * @return null if this model doesn't respond to SAX events. 865 */ 866 public org.xml.sax.ContentHandler getContentHandler(); 867 868 /** 869 * Return this DTM's lexical handler, if it has one. 870 * 871 * %REVIEW% Should this return null if constrution already done/begun? 872 * 873 * @return null if this model doesn't respond to lexical SAX events. 874 */ 875 public org.xml.sax.ext.LexicalHandler getLexicalHandler(); 876 877 /** 878 * Return this DTM's EntityResolver, if it has one. 879 * 880 * @return null if this model doesn't respond to SAX entity ref events. 881 */ 882 public org.xml.sax.EntityResolver getEntityResolver(); 883 884 /** 885 * Return this DTM's DTDHandler, if it has one. 886 * 887 * @return null if this model doesn't respond to SAX dtd events. 888 */ 889 public org.xml.sax.DTDHandler getDTDHandler(); 890 891 /** 892 * Return this DTM's ErrorHandler, if it has one. 893 * 894 * @return null if this model doesn't respond to SAX error events. 895 */ 896 public org.xml.sax.ErrorHandler getErrorHandler(); 897 898 /** 899 * Return this DTM's DeclHandler, if it has one. 900 * 901 * @return null if this model doesn't respond to SAX Decl events. 902 */ 903 public org.xml.sax.ext.DeclHandler getDeclHandler(); 904 905 /** 906 * Append a child to "the end of the document". Please note that 907 * the node is always cloned in a base DTM, since our basic behavior 908 * is immutable so nodes can't be removed from their previous 909 * location. 910 * 911 *
 %REVIEW% DTM maintains an insertion cursor which 912 * performs a depth-first tree walk as nodes come in, and this operation 913 * is really equivalent to: 914 * insertionCursor.appendChild(document.importNode(newChild))) 915 * where the insert point is the last element that was appended (or 916 * the last one popped back to by an end-element operation).
 917 * 918 * @param newChild Must be a valid new node handle. 919 * @param clone true if the child should be cloned into the document. 920 * @param cloneDepth if the clone argument is true, specifies that the 921 * clone should include all it's children. 922 */ 923 public void appendChild(int newChild, boolean clone, boolean cloneDepth); 924 925 /** 926 * Append a text node child that will be constructed from a string, 927 * to the end of the document. Behavior is otherwise like appendChild(). 928 * 929 * @param str Non-null reference to a string. 930 */ 931 public void appendTextChild(String str); 932 933 /** 934 * Get the location of a node in the source document. 935 * 936 * @param node an int value 937 * @return a SourceLocator value or null if no location 938 * is available 939 */ 940 public SourceLocator getSourceLocatorFor(int node); 941 942 /** 943 * As the DTM is registered with the DTMManager, this method 944 * will be called. This will give the DTM implementation a 945 * chance to initialize any subsystems that are required to 946 * build the DTM 947 */ 948 public void documentRegistration(); 949 950 /** 951 * As documents are released from the DTMManager, the DTM implementation 952 * will be notified of the event. This will allow the DTM implementation 953 * to shutdown any subsystem activity that may of been assoiated with 954 * the active DTM Implementation. 955 */ 956 957 public void documentRelease(); 958 959 /** 960 * Migrate a DTM built with an old DTMManager to a new DTMManager. 961 * After the migration, the new DTMManager will treat the DTM as 962 * one that is built by itself. 963 * This is used to support DTM sharing between multiple transformations. 964 * @param manager the DTMManager 965 */ 966 public void migrateTo(DTMManager manager); 967 }


Picture Credit: Adil Baaj
Chart.js is a JavaScript library that allows you to draw basic types of charts by using the HTML5 canvas element.
<canvas id="myChart" width="400" height="400">Sample text here...</canvas>
// Any of the following formats may be used
var ctx = document.getElementById("myChart"); // HTML Document Object Model (DOM)
var ctx = document.getElementById("myChart").getContext("2d"); // HTML Document Object Model (DOM)
var ctx = $("#myChart"); // jQuery Selector
var ctx = "myChart"; // Why?
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
</script>
The graphs below represent the amount of downloads per month of npm packages for Plotly.js, Highcharts, and Chart.js. The chart was generated via npm-stat.
Chart.js is open source and is under the MIT license. Simply put, it can be used for free and you can choose to contribute to the project itself on Github. If you would like support using Chart.js, you can post questions with the chartjs tag on Stack Overflow.
Picture Credit: Adil Baaj
| Bar Charts | Line Charts | Area Charts | Other Charts |
|---|---|---|---|
| Vertical | Basic | Boundaries (line) | Scatter |
| Horizontal | Multi Axis | Datasets (line) | Scatter - Multi Axis |
| Multi Axis | Stepped | Stacked (line) | Doughnut |
| Stacked | Interpolation | Radar | Pie |
| Stacked Groups | Line Styles | - | Polar Area |
| - | Point Styles | - | Radar |
| - | Point Sizes | - | Combo Bar / Line |
| Linear Scale | Logarithmic Scale | Time Scale | Scale Options |
|---|---|---|---|
| Step Size | Line | Line | Grid Lines Display |
| Min & Max | Scatter | Line (Point Data) | Grid Lines Style |
| Min & Max (Suggested) | - | Time Series | Multiline Labels |
| - | - | Combo | Filtering Labels |
| - | - | - | Non Numeric Y-Axis |
| - | - | - | Toggle Scale Type |
| Legend | Tooltip | Scriptable | Advanced |
|---|---|---|---|
| Positioning | Positioning | Bubble Chart | Progress Bar |
| Point Style | Interactions | - | Data Labelling (Plugin) |
| - | Callbacks | - | - |
| - | Border | - | - |
| - | HTML tooltips (line) | - | - |
| - | HTML tooltips (pie) | - | - |
| - | HTML tooltips (points) | - | - |
Demo Credit: chart.js


Orejime is an easy to use
consent manager that focuses on accessibility.
This is a demo page showing a glimpse of how Orejime works.
You can view the source code of this page or the documentation
for more details.
Privacy policy example
This is a sample section that acts as the privacy policy
page in this example.
Here you could, for example, let users open the consent
modal anytime with a simple button, or even reset their
consent preferences.


@import controllers.AssessmentController.FinishExamFormData @import domain.Assessment.Platform @import domain.Sitting @import org.apache.tika.mime.MediaType @import tags._ @import warwick.core.helpers.JavaTime @import domain.Announcement @import domain.BaseSitting.ProgressState @import warwick.fileuploads.UploadedFileControllerHelper.UploadedFileConfiguration @import services.TimingInfoService @( sitting: Sitting, finishExamForm: Form[FinishExamFormData], announcements: Seq[Announcement], uploadedFileConfig: UploadedFileConfiguration, timingInfo: TimingInfoService, )(implicit request: RequestHeader, messagesProvider: MessagesProvider, context: RequestContext) @uploadForm = { @b3.vertical.formCSRF( action = controllers.routes.AssessmentController.uploadFiles(sitting.assessment.id), Symbol("enctype") -> "multipart/form-data", Symbol("class") -> "upload-progress quash-beforeunload assessment-upload-form", Symbol("data-student-assessment-id") -> sitting.studentAssessment.id.toString ) { implicit vfc => @b3.free(Symbol("_label") -> "Attach files") { @* See OE-413 for why we don't include an accept attribute here. *@ }
@b3.free(Symbol("_class") -> "spaced-buttons") { } } } @lateFileUploadWarning() = {View your assessment in Moodle
} case Platform.QuestionmarkPerception => {Take your assessment in Perception
} case Platform.TabulaAssignment => { } case Platform.MyWBS => { } case Platform.OnlineExams => { @* Do nothing here, handled below *@ } }If you have concerns with specific parts of the assessment, you can use this form to bring it to the attention of an invigilator. Invigilators cannot assist you with understanding the assessment, but can look into potential errors and alert the entire cohort if necessary.
We accept all common file formats: PDF, Word/Excel/PowerPoint files (doc, docx, ppt, pptx, xls, xlsx, odt etc.), images (png, jpeg, svg, tiff), audio (mp3, m4a, webm, ogg, wav, flac) and video (mp4, mov, webm, avi).
@if(sitting.studentAssessment.uploadedFiles.nonEmpty) { @lateFileUploadWarning @uploadForm@helpers.humanReadableSize(file.contentLength) @localisedDatetime(file.created)
@b3.inline.formCSRF(controllers.routes.AssessmentController.deleteFile(sitting.assessment.id, file.id), Symbol("class") -> "quash-beforeunload") { implicit ifc => }Once you've answered the assessment questions and you're ready to submit, you can upload your files below.
@lateFileUploadWarning @uploadFormOnce you're ready, you can finish the assessment below. We'll record the time at which you do this.
Have you completed all of the following tasks?
@helpers.humanReadableSize(file.contentLength) @localisedDatetime(file.created)
Download


2 Kings 15:7
So Azariah slept with his fathers; and they buried him with his fathers in the city of David: and Jotham his son reigned in his stead.


About
Tracker is a concise and small application intended to help you get started with Hoodie. It's a basic tracker of all sorts. The mechanics let you keep track of anything you want plus its amount.
Tracker is a concise and small application intended to help you get started with Hoodie. It's a basic tracker of all sorts. The mechanics let you keep track of anything you want plus its amount.


Last updated: 2021-09-09
Checks: 7 0
Knit directory: myTidyTuesday/
This reproducible R Markdown analysis was created with workflowr (version 1.6.2). The Checks tab describes the reproducibility checks that were applied when the results were created. The Past versions tab lists the development history.
Great! Since the R Markdown file has been committed to the Git repository, you know the exact version of the code that produced these results.
Great job! The global environment was empty. Objects defined in the global environment can affect the analysis in your R Markdown file in unknown ways. For reproduciblity it’s best to always run the code in an empty environment.
The command set.seed(20210907)
was run prior to running the code in the R Markdown file. Setting a seed ensures that any results that rely on randomness, e.g. subsampling or permutations, are reproducible.
Great job! Recording the operating system, R version, and package versions is critical for reproducibility.
Nice! There were no cached chunks for this analysis, so you can be confident that you successfully produced the results during this run.
Great job! Using relative paths to the files within your workflowr project makes it easier to run your code on other machines.
Great! You are using Git for version control. Tracking code development and connecting the code version to the results is critical for reproducibility.
The results in this page were generated with repository version 03bfdad. See the Past versions tab to see a history of the changes made to the R Markdown and HTML files.
Note that you need to be careful to ensure that all relevant files for the analysis have been committed to Git prior to generating the results (you can use wflow_publish
or wflow_git_commit
). workflowr only checks the R Markdown file, but you know if there are other scripts or data files that it depends on. Below is the status of the Git repository when the results were generated:
Ignored files:
Ignored: .Rhistory
Ignored: .Rproj.user/
Ignored: catboost_info/
Ignored: data/2021-09-08/
Ignored: data/acs_poverty.rds
Ignored: data/grainstocks.rds
Ignored: data/hike_data.rds
Ignored: data/us_states.rds
Ignored: data/weatherstats_toronto_daily.csv
Unstaged changes:
Modified: code/_common.R
Note that any generated files, e.g. HTML, png, CSS, etc., are not included in this status report because it is ok for generated content to have uncommitted changes.
These are the previous versions of the repository in which changes were made to the R Markdown (analysis/LastAirbender.Rmd
) and HTML (docs/LastAirbender.html
) files. If you’ve configured a remote Git repository (see ?wflow_git_remote
), click on the hyperlinks in the table below to view the files as they were in that past version.
| File | Version | Author | Date | Message |
|---|---|---|---|---|
| Rmd | 03bfdad | opus1993 | 2021-09-09 | remove dependency on pdf in graphics |
Lately Julia Silge has been publishing screencasts demonstrating how to use the tidymodels framework, from first steps in modeling to how to evaluate complex models. Today’s example admittedly does not result in the best performing model you’ll ever see, but it is really fun and uses this week’s #TidyTuesday
dataset on Avatar: The Last Airbender. 🔥, 🌏, 🌊, 💨
This week’s #TidyTuesday dataset is from episodes of Avatar: The Last Airbender. Our modeling goal is to predict the speaker of each line of dialogue.
avatar <- tidytuesdayR::tt_load("2020-08-11")
Downloading file 1 of 2: `avatar.csv`
Downloading file 2 of 2: `scene_description.csv`
avatar_raw <- avatar$avatar
avatar_raw %>%
count(character, sort = TRUE) %>%
head() %>%
knitr::kable(caption = "The 6 characters with the most lines")
| character | n |
|---|---|
| Scene Description | 3393 |
| Aang | 1796 |
| Sokka | 1639 |
| Katara | 1437 |
| Zuko | 776 |
| Toph | 507 |
Rows with Scene Description
are not dialogue; the main character Aang speaks the most lines overall. How does this change through the three “books” of the show?
avatar_raw %>%
filter(!is.na(character_words)) %>%
mutate(
book = fct_inorder(book),
character = fct_lump_n(character, 10)
) %>%
count(book, character) %>%
mutate(character = reorder_within(character, n, book)) %>%
ggplot(aes(n, character, fill = book)) +
geom_col(show.legend = FALSE) +
facet_wrap(~book, scales = "free") +
scale_y_reordered() +
scale_fill_manual(values = c(
avatar_pal("WaterTribe")(1),
avatar_pal("EarthKingdom")(1),
avatar_pal("FireNation")(1)
)) +
labs(
y = NULL, x = NULL,
title = "Last Airbender words spoken by book"
)
Let’s create a dataset for our modeling question, and look at a few example lines.
avatar <- avatar_raw %>%
filter(!is.na(character_words)) %>%
mutate(aang = if_else(character == "Aang", "Aang", "Other")) %>%
dplyr::select(aang, book, text = character_words)
avatar %>%
filter(aang == "Aang") %>%
sample_n(10) %>%
pull(text) %>%
knitr::kable()
| x |
|---|
| You really think so? |
| Hey, I just found out this morning! |
| Good to see you here. |
| Well, if I’m going to the Eastern Air Temple, Appa and I can drop you off at Chameleon Bay to see your dad. |
| I never thought I’d miss grass this much! |
| I’ll do whatever it takes. |
| You’re just a curly tailed blue nose. |
| Uh … no one told us we had to have passports. |
| No self-control … |
| Just some dance movements. |
This… may be a challenge.
What are the highest log odds words from Aang and other speakers?
avatar_lo <- avatar %>%
unnest_tokens(word, text) %>%
count(aang, word) %>%
bind_log_odds(aang, word, n) %>%
arrange(-log_odds_weighted)
avatar_lo %>%
group_by(aang) %>%
top_n(n = 15, wt = log_odds_weighted) %>%
ungroup() %>%
mutate(word = reorder(word, log_odds_weighted)) %>%
ggplot(aes(log_odds_weighted, word, fill = aang)) +
geom_col(alpha = 0.8, show.legend = FALSE) +
facet_wrap(~aang, scales = "free") +
scale_fill_avatar(palette = "AirNomads") +
labs(
y = NULL, x = "log odds weights",
title = "Last Airbender Importance of Words"
)
These words make sense, but the counts are probably too low to build a good model with. Instead, let’s try using text features like the number of punctuation characters, number of pronons, and so forth.
tf <- textfeatures(
avatar,
sentiment = FALSE, word_dims = 0,
normalize = FALSE, verbose = FALSE
)
tf %>%
bind_cols(avatar) %>%
group_by(aang) %>%
summarise(across(starts_with("n_"), mean)) %>%
pivot_longer(starts_with("n_"), names_to = "text_feature") %>%
filter(value > 0.01) %>%
mutate(text_feature = fct_reorder(text_feature, -value)) %>%
ggplot(aes(aang, value, fill = aang)) +
geom_col(position = "dodge", alpha = 0.8, show.legend = FALSE) +
facet_wrap(~text_feature, scales = "free", ncol = 6) +
scale_fill_avatar("AirNomads") +
labs(x = NULL, y = "Mean text features per spoken line")
You can read the definitions of these counts here. The differences in these features are what we want to build a model to use in prediction.
We can start by loading the tidymodels metapackage, and splitting our data into training and testing sets.
set.seed(123)
avatar_split <- initial_split(avatar, strata = aang)
avatar_train <- training(avatar_split)
avatar_test <- testing(avatar_split)
Next, let’s create cross-validation resamples of the training data, to evaluate our models.
set.seed(234)
avatar_folds <- vfold_cv(avatar_train, strata = aang)
Next, let’s preprocess our data to get it ready for modeling.
avatar_rec <- recipe(aang ~ text, data = avatar_train) %>%
step_downsample(aang) %>%
step_textfeature(text) %>%
step_zv(all_predictors()) %>%
step_normalize(all_predictors())
avatar_prep <- prep(avatar_rec)
avatar_prep
Data Recipe
Inputs:
role #variables
outcome 1
predictor 1
Training data contained 7494 data points and no missing data.
Operations:
Down-sampling based on aang [trained]
Text feature extraction for text [trained]
Zero variance filter removed 15 items [trained]
Centering and scaling for 12 items [trained]
Let’s walk through the steps in this recipe.
recipe()
what our model is going to be (using a formula here) and what data we are using.We’re mostly going to use this recipe in a workflow()
so we don’t need to stress too much about whether to prep()
or not. Since we are going to compute variable importance, we will need to come back to juice(avatar_prep)
.
Let’s compare two different models, a random forest model and a support vector machine model. We start by creating the model specifications.
rf_spec <- rand_forest(trees = 1000) %>%
set_engine("ranger") %>%
set_mode("classification")
svm_spec <- svm_rbf(cost = 0.5) %>%
set_engine("kernlab") %>%
set_mode("classification")
Next let’s start putting together a tidymodels workflow()
, a helper object to help manage modeling pipelines with pieces that fit together like Lego blocks. Notice that there is no model yet: Model: None
.
avatar_wf <- workflow() %>%
add_recipe(avatar_rec)
Now we can add a model, and the fit to each of the resamples. First, we can fit the random forest model.
all_cores <- parallelly::availableCores(omit = 1)
all_cores
system
11
future::plan("multisession", workers = all_cores) # on Windows
set.seed(1234)
rf_rs <- avatar_wf %>%
add_model(rf_spec) %>%
fit_resamples(
resamples = avatar_folds,
metrics = metric_set(roc_auc, accuracy, sens, spec),
control = control_grid(save_pred = TRUE)
)
Second, we can fit the support vector machine model.
set.seed(2345)
svm_rs <- avatar_wf %>%
add_model(svm_spec) %>%
fit_resamples(
resamples = avatar_folds,
metrics = metric_set(roc_auc, accuracy, sens, spec),
control = control_grid(save_pred = TRUE)
)
We have fit each of our candidate models to our resampled training set.
Let have a look at how we did.
collect_metrics(rf_rs) %>% knitr::kable()
| .metric | .estimator | mean | n | std_err | .config |
|---|---|---|---|---|---|
| accuracy | binary | 0.5393722 | 10 | 0.0064483 | Preprocessor1_Model1 |
| roc_auc | binary | 0.5501353 | 10 | 0.0062918 | Preprocessor1_Model1 |
| sens | binary | 0.5307905 | 10 | 0.0085026 | Preprocessor1_Model1 |
| spec | binary | 0.5412460 | 10 | 0.0080031 | Preprocessor1_Model1 |
conf_mat_resampled(rf_rs) %>% knitr::kable()
| Prediction | Truth | Freq |
|---|---|---|
| Aang | Aang | 71.5 |
| Aang | Other | 282.0 |
| Other | Aang | 63.2 |
| Other | Other | 332.7 |
Well, that is underwhelming!
collect_metrics(svm_rs) %>% knitr::kable()
| .metric | .estimator | mean | n | std_err | .config |
|---|---|---|---|---|---|
| accuracy | binary | 0.5270838 | 10 | 0.0083769 | Preprocessor1_Model1 |
| roc_auc | binary | 0.5683824 | 10 | 0.0079888 | Preprocessor1_Model1 |
| sens | binary | 0.5790768 | 10 | 0.0192877 | Preprocessor1_Model1 |
| spec | binary | 0.5156948 | 10 | 0.0122867 | Preprocessor1_Model1 |
conf_mat_resampled(svm_rs) %>% knitr::kable()
| Prediction | Truth | Freq |
|---|---|---|
| Aang | Aang | 78.0 |
| Aang | Other | 297.7 |
| Other | Aang | 56.7 |
| Other | Other | 317.0 |
Different, but not really better! The SVM model is better able to identify the positive cases but at the expense of the negative cases. Overall, we definitely see that this is a hard problem that we barely are able to have any predictive ability for.
Let’s say we are more interested in detecting Aang’s lines, even at the expense of the false positives.
svm_rs %>%
collect_predictions() %>%
group_by(id) %>%
roc_curve(aang, .pred_Aang) %>%
ggplot(aes(1 - specificity, sensitivity, color = id)) +
geom_abline(lty = 2, color = "gray80", size = 1.5) +
geom_path(show.legend = FALSE, alpha = 0.6, size = 1.2) +
scale_color_avatar(palette = "EarthKingdom") +
coord_equal() +
labs(title = "ROC curve of SVM Models\nby cross validation fold")
This plot highlights how this model is barely doing better than guessing.
Keeping in mind the realities of our model performance, let’s talk about how to compute variable importance for a model like an SVM, which does not have information within it about variable importance like a linear model or a tree-based model. In this case, we can use a method like permutation of the variables.
set.seed(345)
avatar_imp <- avatar_wf %>%
add_model(svm_spec) %>%
fit(avatar_train) %>%
extract_fit_parsnip() %>%
vi(
method = "permute", nsim = 10,
target = "aang", metric = "auc", reference_class = "Other",
pred_wrapper = kernlab::predict, train = juice(avatar_prep)
)
avatar_imp %>%
slice_max(Importance, n = 8) %>%
mutate(
Variable = str_remove(Variable, "textfeature_text_n_"),
Variable = fct_reorder(Variable, Importance)
) %>%
ggplot(aes(Importance, Variable, color = Variable)) +
geom_errorbar(aes(xmin = Importance - StDev, xmax = Importance + StDev),
alpha = 0.5, size = 1.3, show.legend = FALSE
) +
geom_point(size = 3) +
scale_color_avatar(palette = "FireNation") +
labs(
y = NULL,
title = "Variable Importance"
)
These are the text features that are most important globally for whether a line was spoken by Aang or not.
Finally, we can return to the testing data to confirm that our (admittedly lackluster) performance is about the same.
avatar_final <- avatar_wf %>%
add_model(svm_spec) %>%
last_fit(avatar_split)
avatar_final %>%
collect_metrics() %>%
knitr::kable()
| .metric | .estimator | .estimate | .config |
|---|---|---|---|
| accuracy | binary | 0.5484388 | Preprocessor1_Model1 |
| roc_auc | binary | 0.5564722 | Preprocessor1_Model1 |
avatar_final %>%
collect_predictions() %>%
conf_mat(aang, .pred_class)
Truth
Prediction Aang Other
Aang 238 917
Other 211 1132
sessionInfo()
R version 4.1.1 (2021-08-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19043)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods
[7] base
other attached packages:
[1] kernlab_0.9-29 ranger_0.13.1 vctrs_0.3.8
[4] rlang_0.4.11 vip_0.3.2 themis_0.1.4
[7] textrecipes_0.4.1 yardstick_0.0.8 workflowsets_0.1.0
[10] workflows_0.2.3 tune_0.1.6 rsample_0.1.0
[13] recipes_0.1.16 parsnip_<IP_ADDRESS>0 modeldata_0.1.1
[16] infer_1.0.0 dials_<IP_ADDRESS>00 broom_0.7.9
[19] tidymodels_0.1.3 showtext_0.9-4 showtextdb_3.0
[22] sysfonts_0.8.5 tidylo_0.1.0 textfeatures_0.3.3
[25] tidytext_0.3.1 tvthemes_1.1.1 forcats_0.5.1
[28] stringr_1.4.0 dplyr_1.0.7 purrr_0.3.4
[31] readr_2.0.1 tidyr_1.1.3 tibble_3.1.4
[34] ggplot2_3.3.5 tidyverse_1.3.1 scales_1.1.1
[37] workflowr_1.6.2
loaded via a namespace (and not attached):
[1] utf8_1.2.2 proto_1.0.0 R.utils_2.10.1
[4] tidyselect_1.1.1 grid_4.1.1 pROC_1.18.0
[7] munsell_0.5.0 codetools_0.2-18 ragg_1.1.3
[10] future_1.22.1 withr_2.4.2 colorspace_2.0-2
[13] highr_0.9 knitr_1.34 rstudioapi_0.13
[16] Rttf2pt1_1.3.9 listenv_0.8.0 labeling_0.4.2
[19] git2r_0.28.0 farver_2.1.0 bit64_4.0.5
[22] DiceDesign_1.9 rprojroot_2.0.2 mlr_2.19.0
[25] parallelly_1.28.1 generics_0.1.0 ipred_0.9-11
[28] xfun_0.25 R6_2.5.1 doParallel_1.0.16
[31] tfse_0.5.0 lhs_1.1.3 cachem_1.0.6
[34] assertthat_0.2.1 promises_<IP_ADDRESS> vroom_1.5.4
[37] nnet_7.3-16 emojifont_0.5.5 gtable_0.3.0
[40] globals_0.14.0 timeDate_3043.102 BBmisc_1.11
[43] systemfonts_1.0.2 splines_4.1.1 extrafontdb_1.0
[46] selectr_0.4-2 checkmate_2.0.0 yaml_2.2.1
[49] modelr_0.1.8 backports_1.2.1 httpuv_1.6.2
[52] tokenizers_0.2.1 extrafont_0.17 tools_4.1.1
[55] lava_1.6.10 usethis_2.0.1 ellipsis_0.3.2
[58] jquerylib_0.1.4 Rcpp_1.0.7 plyr_1.8.6
[61] parallelMap_1.5.1 rpart_4.1-15 ParamHelpers_1.14
[64] viridis_0.6.1 haven_2.4.3 hrbrthemes_0.8.0
[67] fs_1.5.0 here_1.0.1 furrr_0.2.3
[70] unbalanced_2.0 magrittr_2.0.1 data.table_1.14.0
[73] magick_2.7.3 reprex_2.0.1 RANN_2.6.1
[76] GPfit_1.0-8 SnowballC_0.7.0 whisker_0.4
[79] ROSE_0.0-4 R.cache_0.15.0 hms_1.1.0
[82] evaluate_0.14 readxl_1.3.1 gridExtra_2.3
[85] compiler_4.1.1 crayon_1.4.1 R.oo_1.24.0
[88] htmltools_0.5.2 later_1.3.0 tzdb_0.1.2
[91] lubridate_1.7.10 DBI_1.1.1 dbplyr_2.1.1
[94] MASS_7.3-54 Matrix_1.3-4 cli_3.0.1
[97] R.methodsS3_1.8.1 parallel_4.1.1 gower_0.2.2
[100] pkgconfig_2.0.3 xml2_1.3.2 foreach_1.5.1
[103] bslib_0.3.0 hardhat_0.1.6 tidytuesdayR_1.0.1
[106] prodlim_2019.11.13 rvest_1.0.1 janeaustenr_0.1.5
[109] digest_0.6.27 rmarkdown_2.10 cellranger_1.1.0
[112] fastmatch_1.1-3 gdtools_0.2.3 curl_4.3.2
[115] lifecycle_1.0.0 jsonlite_1.7.2 viridisLite_0.4.0
[118] fansi_0.5.0 pillar_1.6.2 lattice_0.20-44
[121] fastmap_1.1.0 httr_1.4.2 survival_3.2-11
[124] glue_1.4.2 conflicted_1.0.4 FNN_1.1.3
[127] iterators_1.0.13 bit_4.0.4 class_7.3-19
[130] stringi_1.7.4 sass_0.4.0 rematch2_2.1.2
[133] textshaping_0.3.5 styler_1.5.1 future.apply_1.8.1


Movie Ark Search
Search for local cinema:
Your Nearest Cinema:
Distance Away (Miles):
ID Number:
Other Cinemas We Found:
Name
Distance Away (Miles):
ID Number:
Name
Distance Away (Miles):
ID Number:
Name
Distance Away (Miles):
ID Number:
(c)2017 All Rights Reserved


to as Simon Peter, a nod to his old and new nature mixed together in one. Becoming Peter didn’t mean that Simon was lost.
If we’re honest, most of us are also a mix of the old and the new, a work in progress with Jesus gradually helping us subtract the negative and add the positive. If we learn anything from Peter, it’s that it certainly takes some time to work out our spiritual kinks.
If the disciples had been students of Jesus, learning from Him for three years, the last few days they spent with Him were definitely an accelerated course. The day before the crucifixion was like a final exam for all the disciples, but especially for Peter. He crammed more learning and life change into his last few days with Jesus than many of us can imagine absorbing in a lifetime! The story of this day is told in several of the Gospel accounts. The following Scriptures piece together some of the events.
Read each Scripture. Then select a plus or minus beside it to indicate whether you think it was a positive or negative moment for Peter.
Luke 22:14-20
Luke 22:24
Luke 22:33
Luke 22:34
John 13:8
John 13:9
Mark 14:32-41
John 18:10
Matthew 26:69-75
Talk about a rough night! You can see why Peter’s learning curve was so steep here at the end of his time with Jesus. And you can see God’s love for numbers begin to unfold.
What number appears again and again in Peter’s story?


To find typographic design patterns that are common in modern Web design and to resolve some common typographic issues, we conducted extensive research on 50 popular websites on which typography matters more than usual (or at least should matter more than usual). We've chosen popular newspapers, magazines and blogs as well as various typography-related websites.
We've carefully analyzed their typography and style sheets and searched for similarities and differences. We have also put together a spreadsheet of the study that displays the websites' various values (for example, the ratio between the line height and line length).
Ultimately, we identified 7 general typographic problems and issues related to typographic design and tried to find answers to them through our research:
We ended up with solid data, which we evaluated and prepared for this article. Based on the statistics, we have identified several "rules of thumb" for working with type. Please note that these rules can often, but not always, be considered best practice.
Whether designers should use serif or sans-serif fonts for body copy is one of the most discussed and unresolved questions about typesetting on the Web. Some designers prefer to give their headlines serifs (which are short, decorative lines at the end of letter strokes) to give them more appeal. The main reason to choose a serif font for your headlines is that, at a large size, serif fonts are easy to read and look great. The contrast between a serif font for headlines and a sans-serif font for body copy can be interesting, too.
Some designers prefer serif fonts for body copy because they believe the lines at the end of letter strokes help guide readers from one letter to the next, making scanning and reading more comfortable.
According to our study, sans-serif fonts are still more popular than serif fonts for headlines, although they seem to have dropped in popularity in recent years.
Two thirds of the websites we surveyed used sans-serif fonts for body copy. The main reason is probably because, despite the growing popularity of advanced font replacement techniques, such as Cufón, most designers stick to the core Web fonts, which essentially give them only two viable options: Georgia and Times New Roman. And because of the stigma attached to Times New Roman (that it often makes a modern website look outdated), they're left with only Georgia. Sans-serif fonts offer a wider variety of options for the Web.
Surprisingly, despite the growing popularity of font replacement techniques and growing availability of new pre-installed fonts (e.g. Windows Vista and Mac fonts), designs in our study mainly used the traditional, core Web fonts, the only exceptions being Lucida Grande (which comes installed only on Macs), Helvetica and Baskerville.
As one would expect, Arial, Georgia and Verdana are used for the majority of body copy today. In our study, around 80% of websites used one of these three fonts. For the remaining 20%, designers' favorite Helvetica is a popular choice, as is Lucida Grande.
With options such as Verdana and Arial available as fall-backs, a designer really has no reason not to specify other non-standard fonts to achieve the best effect. You can learn more about advanced CSS font stacks in Nathan Ford's article Better CSS Font Stacks and CodeStyle's Build Better CSS Font Stacks.
Jon Tan uses serif typeface Baskerville for headlines and serif typeface Georgia for body copy.
Verdana is used minimally for headlines. Only 10 websites use it for body copy to begin with, and only four use it for headlines. The main reason is that Verdana puts a lot of spacing between letters, which makes it not as tidy to read at a large size. If you are going to use it for headlines, you may want to take advantage of the CSS letter-spacing
property. Georgia and Arial are most popular fonts for headings.
Finally, we note that "alternative" fonts are used much more for headlines than for body copy. Designers seem more willing to experiment with their headings than with the main body. If you want to bring some typographic variation into your next design, headings may be the easiest place to start.
We were curious to learn the extent to which designers were willing to experiment with dark background colors. We looked out for any typography-oriented websites that had a dark color scheme and were surprised to find not a single one.
The New Yorker has a light color scheme, with Times New Roman used for headlines and body copy.
Pure white background for body copy won by a landslide. However, many of the designs avoid the high contrast of pure white on pure black; text color is often made a bit lighter than pure black. Designers clearly focus on legibility and avoid experimenting with background colors. The contrast of black on white is easy to read and is, at least among these websites, the status quo.
Of course, the choice of headline font size depends on the font used in the design. In any case, in our study by far the most popular font sizes ranged from 18 to 29 pixels, with 18 to 20 pixels and 24 to 26 pixels being the most popular choices.
Our study didn't yield any clear winners. The average font size for headings is 25.6 pixels. But note that any size between 18 and 29 pixels could be effective; it depends, after all, on how your headings fit the overall design of your website. Still, you could try experimenting with larger sizes, because displays are always getting larger, as are display resolutions.
An obvious outlier is Wilson Miner (screenshot below), who uses a massive font size of 48 pixels for his headlines. His website is a special case, though, because all of his posts have extremely short titles, only a few words.
Do you remember about seven years ago when Web designs had tiny, barely readable elements, and body copy was set to 8 pixels in Tahoma? Small font sizes are out, and more and more modern designers are turning to large font sizes. From our sample size, we saw a clear tendency towards sizes between 12 and 14 pixels. The most popular font size (38%) is 13 pixels, with 14 pixels slightly more popular than 12 pixels. Overall, the average font size for body copy is 13 pixels.
We noted (as one would expect) more and more attention being paid to the smallest typographic details. Dashes, quotes, footnotes, author names, introductory text and paragraphs have been carefully set, with optimal legibility in mind. Type setting is usually very consistent, with a lot of white space, leading and padding.
Typographica uses a large font size for the introductory paragraphs of its articles, and then reverts to a normal size for the rest of text.
To better understand the relationship between heading and body font size, we divided each website's heading font size by its body font size. We took the average of these ratios and derived a rule of thumb for you to work with:
Heading font size ÷ Body copy font size = 1.96
The overall value, then, is 1.96. This means that when you have chosen a font size for your body copy, you may want to multiply it by 2 to get your heading font size. This, of course, depends on your style; the rule of thumb won't necessarily give you the optimal size for your particular design. Another option is to use a traditional scale (6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 21, 24, 36, 48, 60, 72) or the Fibonacci sequence (e.g. 16 - 24 - 40 - 64 - 104) to get natural typographic results.
Leading (or line height) will always depend on your chosen font size and measure (or line length). In general, the longer the measure, the longer the leading should be. Therefore, presenting a chart of the most popular choices for leading in pixels wouldn't make sense here. More appropriate would be for you to use a relative unit, such as an em or percentage value, that determines the relation between leading and measure and between leading and font size.
According to our study:
AIGA is a perfect example of optimal leading. Its font size is 13.21 pixels (converted from ems) and its line height is 19.833 pixels (conversion from ems). In fact, 19.8333 ÷ 13.2167 = 1.5011.
So, once you have decided on your body copy font size, multiplying this value by 1.5 will give you the optimal line height. Once you've got that, you can multiply this new value by 27.8 to get your optimal line length. Note that the layout will also need gutters, margins and padding to let the body copy breathe.
The New Scientist has 20 pixels of spacing between paragraphs.
According to a classic rule of Web typography, 55 to 75 is an optimal number of characters per line. Surprisingly, our study shows that most websites have a higher number. We counted how many characters could fit on one line using the design's default font size. The result, which is an average of 88.74 characters per line (maximum), is extremely high. Of course, this maximal number is different from the average number of characters per line, which in general ranges between 75 and 85 characters per line. Still, the range is way above the conventional range - quite peculiar.
Between 73 and 90 characters per line is a popular choice among designers, yet we also found outliers: Monocle (47 characters per line) and Boxes and Arrows (125 characters per line). To get a more exact reading for each website, you would need to take an average character count from multiple lines.
The study shows a clear set of common practices and guidelines for setting type in Web design. Note, though, that these findings are not scientific and should serve only as rough guidelines:
Of course these "rules" aren't set in stone. Rather, they are a set of rough guidelines that you can use as a basis for setting typography. Every website is unique, and you may want to modify your choices at each stage of your design to suit your layout. You can also take a look at the spreadsheet of the study and export its data for further analysis.


Browsers support the storing and sending back of small text files called "Cookies". These cookie files can be used (amongst other things) to help track the usage of a website. See the Mozilla description of cookies for more details.
Compiler Explorer uses Google Analytics, which in turn uses cookies. Google Analytics allows us to see how many individual users of Compiler Explorer there are, how often users visit us, the average amount of time spent on the site, the frequency and distribution of compilers selected, and so on. It is invaluable in helping us make decisions in prioritising work on the site. It's important to note that these cookies are anonymous: we don't know who each individual user is. Our Google Analytics settings prevent data being retained for more than 14 months. The cookie stored is a first party cookie: you will find it in your browser under "godbolt.org" cookies.
Your privacy is important to us and you may opt out of this tracking at any time using the buttons on this dialog, with no loss of access or functionality of Compiler Explorer.
To store your preferred options between sessions, such as your input code and user interface layout, we make use of your browser's local storage, where we place:
Note that the usage of local storage is necessary for the proper functioning of the site, and it won't be disabled if you choose to not grant cookie usage consent. This information is not used to track any user identifying information. The data stored locally is only that required by the site to function.
You can change your cookie consent decision on Compiler Explorer by pressing one of the following buttons:


The odsResultEnumerator widget enumerates the search results (records for a Dataset Context, datasets for a Catalog Context). It repeats the template (the content of the directive element) for each of them.
If used with a Catalog Context, for each result, the following AngularJS variables are available:
item.datasetid
: Dataset identifier of the dataset
item.metas
: An object holding the key/values of metadata for this dataset
If used with a Dataset Context, for each result, the following AngularJS variables are available:
item.datasetid
: Dataset identifier of the dataset this record belongs to
item.fields
: an object hold all the key/values for the record
item.geometry
: if the record contains geometrical information, this object is present and holds its GeoJSON representation


QAM in Montreal
I spent a bit of time goofing around with the system in order to determine whether ther's anything worth picking up on QAM in Montreal. That's the digital encoding system used by cable operators to send digital TV. Anywho, basically in Montreal, from a quick scan you can get: Radio and VOD advertisement channels. Disappointing, as even if some of the local non-HD channels were available it would be an improvement in recording quality by skipping an ADA conversion.
The good news tho is that I can probably attach a splitter and get dual OTA HD recepetion. Which is kinda cool, but also means that I'd need more hard disk space!
Besides, the real concern right now is getting a consistent signal for the shows Joan really cares about. She gets quite emotional when they don't come in. (Although a little searching on Torrent could solve the problem. But, then one wonders why you pay for Cable at all, then?)
About this entry
You"re currently reading "QAM in Montreal," an entry on a crick in the net
- Published:
- 01.31.07 / 1pm
- Category:
- MythTV
Ummm... because of the transfer rate? Waiting several hours for something that you could watch in real time in a half hour or an hour is kind of annoying, and at least here, chews up bandwidth which we could be using doing other useful things. That and the whole, 'I really want that, but no one is seeding...' I've been using torrent to keep up with some Japanese shows (actually, to get subtitles for shows I watched raw on JapanTV).
I suppose if you're timeshifting, that time argument doesn't matter too much.
We pay Rogers the bucks mainly for JapanTV. The other channels don't get much action, but buying JapanTV on its own ends up costing nearly as much as the massive 'get just about everything' package that we're subscribed to... That's a whole other story...
(Side comment... I'm using way too many ellipses again... See what I mean?...)
Yes... Yes I do...
ISTR reading an I, Cringely where he was examining the case of a micro-broadcaster (in toronto, methinks) and the marginal cost of each channel. At the prices you're talking, maybe it would be worth looking into it?


Thanks for voting!
ARTIST
VOTES
{% for artist in artistvotes %}
{{ artist.artistname }}
{{ artist.votecount }}
{% endfor %}
HOME


Samsung Galaxy S7 Edge review: this is the smartphone to beat
6/11/2018-Ho Chi Minh cityLatest high-end Android phone raises bar for screen, camera and speed, while bringing back such fan favourites as waterproofing, expandable storage and decent battery life
Curved screen, metal, glass and waterproof
Last year saw a dramatic shift in design for Samsung. Out went derided plastic and in came premium materials: glass and metal. The Galaxy S6 came in a regular flat version and one called “Edge” with a screen with curved on the left and right edges.
It is this version that the Galaxy S7 Edge (find here) takes its design from. Side-by-side they look barely any different apart from a bigger screen – 5.5in to the older 5.1in – and the back now has rounded edges.
S7 Edge is waterproof to IP68 standards meaning 1.5m for 30 minutes in fresh water. This time, however, all the ports are open and do not require fiddly plugs.
Two processors
The S7 Edge will be available with two different processors, depending on the country. In the UK and Europe, the phone will come with Samsung’s own Exynos 8890 octa-core processor.
In the US and other regions, the S7 Edge will come with Qualcomm’s most powerful chip, the Snapdragon 820. Benchmarking indicates the Snapdragon 820 is more powerful than the Exynos 8890, particularly its graphics power.
It will likely handle anything you can throw at it. The Snapdragon 820 should perform similarly. Both have 4GB of RAM, which helps with multitasking.
Camera
Samsung’s cameras have been very good over the years, but the one fitted to the Galaxy S7 Edge is a cut above. The 12-megapixel sensor produces detailed, rich images and focuses so fast you think it’s broken. But it is the low-light performance that sets it apart from the rest, producing some of the best blur-free images in poor light of any smartphone.
The 5-megapixel selfie camera is slightly disappointing. It produces very soft images that lack fine detail, even without the various beauty modes on. Some might find the images flattering, smoothing over blemishes, but blown up to full size they’re far too soft for my tastes.


Exercises Day 4
Problem 1: Template classes
Take the Vector
class you created in the previous exercise
and make it into a template class so that you can store other objects in it.
Problem 2: Memory management objects
As manual memory management is tricky and dangerous we want to create classes that does this for
us. The trick is to put the delete
statement inside of the
destructor of the class. This will ensure that the resource is always deleted when all the pointers
to it doesn't exist any more.
-
Create a class
UniquePointer
that is a template class of the pointer type and contains a single pointer to an object of that type - Create suitable constructor and destructors for that class
- Overload the dereference and dereference+access (
->
) operators - Disable any form for copying of the object, but implement the move constructor so that you can move a resource from one pointer to another
-
Create a class
SharedPointer
that is similar toUniquePointer
. The difference is thatSharedPointer
can be copied, and when it is copied it keeps a count of how many instances of the class "owns" the same resource. Write the destructor so that it only frees the resource when all the pointers have gone out of scope - Create a
.useCount()
function so that you can test if the class works as expecte
Problem 3: Design patterns - composite
The composite pattern is used for when you want to create tree structures where any branch can of course continue to branch as many times as it wants to. The fundamental class diagram for the composite pattern is:
We will use this pattern to create a TextObject
that can either
be text or a bullet list (or whatever we want to expand it to). The bullet list itself can of
course contain more bullet lists.
-
Create a virtual class
TextObject
that has a pure virtual.print(std::ostream&)
function. Overload the stream operator to call this function -
Create the leaf class first, e.g. a simple
StringObject
that contains a string, and prints this when theprint()
function is called -
Now create the composite
BulletList
object. For storage you can either use theLinkedList
class you defined orstd::list
. To have polymorphism work, you need to store pointers toTextObject
s in it. YourUniquePointer
would be perfect for this, but it is still missing some of the functionality to have polymorphism work. You can usestd::unique_ptr
from the memory header header instead, for which polymorphism work as expected. Make the list print a bullet point for every element as well as call the elements own print function -
Optional: also implement an
Enumerate
class that print numbered lists
Problem 4: Design patterns - decorator
The second pattern we will deal with is the decorator pattern, also known as a wrapper. The decorator pattern is for when you want to add functionality to an object dynamically at runtime, and offer similar advantages to subclassing. The fundamental class diagram for the decorator pattern is:
In this exercise we will use this pattern to implement text decoration of strings, such as adding delimiters and colours.
-
Once more create a
TextObject
class that this time has a pure virtual.str()
function that returns a string. Also create aStringObject
class that inherit fromTextObject
and stores its own string -
Create the baseline for the decorator pattern by declaring a
TextDecorator
class that owns a pointer to aTextObject
instance. Once more you may make use of thestd::unique_ptr
class to do this -
Create a
DelimiterDecorator
class that inherits fromTextDecorator
and adds its own delimiters to the string from its parent. E.g."Hello"
to"{Hello}"
-
Optional: Create a
ColourDecorator
that makes use of the ANSI escape codes to colour text - Play around with the classes and see how the order of execution changes the output


I Click Solutions My Name is P.S.B Dassanayake My Id no 120083A My role is Project Manager My main focus is to manage work and divide the workload amoung memebers.


FANS NICKED
Rangers in Rotterdam: 42 football fans arrested following Feyenoord clash
by Connor BoylanDUTCH police have confirmed 42 football fans have been arrested following Rangers’ clash with Feyenoord in Rotterdam.
Cops nicked several supporters near to the De Kuip stadium after the alleged disturbances broke out, local media reports.
The offences include setting off fireworks, rowdy behaviour, insulting police officers and “selling things illegally”.
The nationality of those detained is largely unknown but it has been reported that one Scottish fan was arrested for public intoxication.
Police said that before, during and immediately after the 2-2 Europa League draw that it was a "manageable evening".
A police spokesman said: "I can confirm a total of 42 arrests. Overall at was a manageable evening."
Steven Gerrard's side earned a point thanks to a stunning double from Alfredo Morelos.
But his side will have to wait another two weeks to seal their place in the knockout stages after Porto's late win over Young Boys.
The Light Blues need just a point from their final game to secure European football after Christmas.
Boss Gerrard hailed deadly Morelos after the match and defended his £50million valuation of the Colombian striker.
We told how around 10,000 Gers fans were set to make the trip over to Holland despite only 3,000 having match tickets.
Travelling supporters gathered in Dam Square, Amsterdam, before making the trip to the stadium – around an hour away.
One video emerged last night of a violent clash which spilled onto the street from a bar in the area.


ÁVision Build Log
Project:
C:\Keil\Labware\Lab13_DAC\Lab13.uvproj Project File Date: 02/07/2020Output:
Rebuild target 'Lab13' assembling startup.s... compiling Lab13.c... compiling Sound.c... compiling DAC.c... compiling Piano.c... linking... Program Size: Code=6484 RO-data=9420 RW-data=80 ZI-data=1816 ".\Lab13.axf" - 0 Error(s), 0 Warning(s). Load "C:\\Keil\\Labware\\Lab13_DAC\\Lab13.axf" Connecting: Mode=JTAG, Speed=1000000Hz Erase Done. Programming Done. Verify OK. ash Download failed - Target DLL has been cancelled Load "C:\\Keil\\Labware\\Lab13_DAC\\Lab13.axf" Connecting: Mode=JTAG, Speed=1000000Hz Connection failed!, error code=&d Error: Flash Download failed - Target DLL has been cancelled s, 4 errors compiling Sound.c... compiling DAC.c... compiling Piano.c... ".\Lab13.axf" - 4 Error(s), 2 Warning(s). Target not created