SQL Server Unit (aka SQL-Unit or SS-Unit*) is a unit testing framework for SQL
Server (i.e. T-SQL). It comprises of a set of stored procedures that allow you
to write unit tests for your SQL objects and code in T-SQL itself using the
familiar xUnit model. By this I mean that the concepts of Fixtures, the SetUp
& TearDown helper functions and use of AssertXxx
functions to verify
expectations are all present. Naturally there are limitations to T-SQL that make
these concepts less accessible than in a language like C# but they should be
pretty easy to grasp.
For a little more rationale around why you might choose to unit test your SQL code this way rather than through, say, your back-end services see my blog posts You Write Your SQL Unit Tests in SQL? & The Public Interface of a Database.
* The unfortunate choice of the original "SS-Unit" abbreviation only came to light a couple of years later when I started using the test framework in my Test-Driven SQL presentation. I have since tried to replace it with "SQL-Unit" where possible with only a few key places remaining - the schema names and some URLs.
The easiest way to see how SQL-Unit works is to look at the examples which are
contained in the Examples
folder. The *.dbo.sql
files are intended to represent the production code and the *.test.sql
scripts are the unit tests. You can run the examples either in batch mode (just
as your build server would) this way:-
C:\SQL-Unit\Examples> BuildDatabase .\SQLEXPRESS C:\SQL-Unit\Examples> RunTests .\SQLEXPRESS
or you can build the example database (with SQL-Unit applied) and run the unit test scripts interactively through a GUI tool such as SQL Server Management Studio (SSMS):-
C:\SQL-Unit\Examples> BuildDatabase .\SQLEXPRESS C:\SQL-Unit\Examples> SSMS
These batch files take the name of the SQL Server instance and assume a database name of "SQL_Unit_Examples". The command line above shows how to access a local instance of SQL Server Express which is freely available and makes an excellent tool for developing SQL code via TDD as its limitations are beyond the scope of what unit testing requires.
NB: These batch files invoke SQLCMD
to run the various .sql scripts and so
you need to have SQLCMD
on your PATH
.
Most unit test frameworks come with some sort of binaries, but because this is
SQL based it effectively comes as source code. It is intended that you apply
it to your baseline database schema and then run your set of test scripts.
There is a batch file in the Framework folder called Install.cmd
that you can use to load the test framework into any database, e.g.
C:\SQL-Unit\Framework> Install .\SQLEXPRESS SQL_Unit_Examples
That batch file uses SQLCMD
to run the SQL scripts which is not
exactly speedy and so there is an alternative that uses PowerShell instead, e.g.
C:\SQL-Unit\Framework> Install-ps .\SQLEXPRESS SQL_Unit_Examples
Note: Make sure you have used PowerShell Set-ExecutionPolicy
to
allow PowerShell scripts to run on your machine.
Most likely you will already have your code in some form of Version Control System and also have some tool (or batch files) to create your baseline database. Because this library comes in source form you can just add it to your 3rd party area and then either use the supplied batch file or manually integrate it into your own build system.
The framework uses its own schema 'ssunit' and so there should be no conflicts between the objects in the framework and your production codebase.
It's assumed that you're already familiar with the xUnit testing framework - probably NUnit - but if not, then as long as you have used one of the more popular ones SQL-Unit should make sense. As mentioned in the Introduction some artistic license was required to map the mechanisms a language like C# has at its disposal for metadata and reflection onto the much simpler T-SQL world.
So, let's start with the canonical unit test equivalent of the "Hello World" program beloved by programmers everywhere:-
create procedure test._@Test@_Assert_Hello_World as declare @expected varchar(max); set @expected = 'hello world'; exec ssunit.AssertStringEqualTo @expected, 'hello world'; go exec ssunit.RunTests;
If you run this piece of code in SSMS (using, say, the SQL_Unit_Examples database) you should see the following output:-
Alternatively you can save the query into a text file and run it with SQLCMD:-
The first result set shows you that you ran 1 test; it passed and was called "Assert_Hello_World". Below that is a second result set showing you a summary of the test outcomes for that run.
To make things a little more interesting, change either the expectation or the actual value to something different and run the test again. I changed the actual value to "Hello SQL-Unit" and got this:-
exec ssunit.AssertStringEqualTo @expected, 'Hello SQL-Unit';
Grrr, our first failed test! This time the outcome has changed to "FAILED" and the "Failure Reason" column is populated with a simple message that shows you why the comparison failed.
As one more final simple exercise, comment out the assert. This time the test is deemed "inconclusive" and so the outcome changes to "Unknown":-
--exec ssunit.AssertStringEqualTo @expected, 'Hello SQL-Unit';
It is expected that all code paths should assert at least one condition to distinguish from the scenario where an assert has just been forgotten.
It should be pretty obvious that tests are written as stored procedures - one
procedure per test. It should also be apparent that the end of the SQL script
must contain a call to invoke the unit test runner (exec ssunit.RunTests
)
at least when using a GUI tool like SSMS to run the tests.
What is probably less obvious is why there is
no drop procedure
statement and why there are funny _@
characters in the name...
If you've used NUnit you'll be accustomed to annotating your unit tests with a
[Test]
attribute. This is how NUnit finds your tests without you
having to register them. Sadly T-SQL doesn't support attributes and so we have
to find another way to achieve the same effect. So, it uses an adornment on the
test name instead: _@Test@_
. Hopefully the use of the '@' symbol will
make you think attribute. So these two (NUnit and SQL-Unit) test
definitions are intended to be equivalent:-
[Test] public void Thing_ShouldDoThat_WhenItDoesThis() { . . . } create procedure _@Test@_Thing_ShouldDoThat_WhenItDoesThis as . . . go
The position of any "attributes" is not important and so you can put them on the end if it makes the test name easier to read:-
create procedure Thing_ShouldDoThat_WhenItDoesThis_@Test@_ as . . . go
As for why you don't need to write the usual if object_id()/drop procedure
prologue, that's because the test framework drops the procedure for you. Why?
Because unit test names should be verbose and nothing kills your flow
more than having to fix your script because you forgot to drop the proc first or
you misspelled it. This then means that you can alternate between the production
code and writing/running the tests very rapidly.
A slightly more subtle point you may have noticed is that all the SQL-Unit
objects live in a separate schema called ssunit
. This gives it all
the benefits of namespaces to avoid name clashes with your test or production
code. The test runner assumes that all tests live in a schema called test
but that can be overridden as explained later.
NB: The schema ssunit_impl
is used for the implementation of
SQL-Unit and so there should be no need to access its objects from tests.
Due to the limitations of T-SQL not supporting overloading based on type the assert names have to encode the type instead. The set of assert procedures have been written only for the main types - integer (int), string (varchar), datetime, date and real. Given that SQL Server will do most type conversions automatically you should still be able to achieve most of your testing with just this subset.
| Assert Procedure | Description |
|---|---|
| AssertPass | Denotes the test as having conclusively passed |
| AssertFail @reason | Denotes the test as having conclusively failed |
| AssertNotImplemented | Fails the test with a reason of "Not implemented" |
| AssertTrue @actual | Compares the resultant value to 1 (i.e. true) |
| AssertFalse @actual | Compares the resultant value to 0 (i.e. false) |
| AssertThrew @error, @procedure | Executes a helper procedure which performs the test and should result in an error being thrown |
| AssertThrewAnyError @procedure | Shorthand for AssertThrew '%' |
| AssertXxxEqualTo @expected, @actual [, @tolerance] | Compares the resultant Xxx value to another for equivalence (with optional tolerance) |
| AssertXxxNotEqualTo @expected, @actual | Compares the resultant Xxx value to another for a difference |
| AssertXxxLessThan @expected, @actual | Performs a < comparison with the resultant Xxx value |
| AssertXxxLessThanOrEqualTo @expected, @actual | Performs a <= comparison with the resultant Xxx value |
| AssertXxxGreaterThan @expected, @actual | Performs a > comparison with the resultant Xxx value |
| AssertXxxGreaterThanOrEqualTo @expected, @actual | Performs a >= comparison with the resultant Xxx value |
| AssertXxxIsNull @actual | Compares the resultant Xxx value to NULL |
| AssertXxxIsNotNull @actual | Compares the resultant Xxx value to NULL |
| AssertIntegerBetween @lower, @upper, @actual | Compares an integer to a range (lower and upper bounds are inclusive) |
| AssertStringLike @regex, @actual | Compares two strings using the LIKE operator for a match |
| AssertStringNotLike @regex, @actual | Compares two strings using the LIKE operator for a difference |
| AssertTableRowCountEqualTo @expected, @table | Compares the number of rows in the table with a constant |
| AssertTableIsEmpty @table | Shorthand for AssertTableRowCountEqualTo 0 |
| AssertTableEqualTo @expected, @actual | Compares the contents of two tables for equivalence |
NB: AssertPass and AssertFail provide the underpinnings of the framework - all others are implemented in terms of these two.
You will notice that each 'set' of asserts has an explicit overload for comparing with NULL. It would have been quite easy to make the AssertXxxEqualTo procedures support a comparison with NULL, but I felt that goes against how NULL's are handled in real SQL. You learn early on that NULL can be synonymous for 'unknown' and so you never write "x = null", but "x is null". Consequently in SQL-Unit you don't say "AssertXxxEqualTo null, @x", but "AssertXxxIsNull @x".
SQL Server provides a Try/Catch mechanism that allows you to use an exception
style of programming to deal with errors via the RAISERROR
keyword. However,
writing a unit test to verify that an action throws can be very verbose; so to
avoid the boilerplate code obscuring the salient part of the test the
AssertThrew
procedure takes an extra argument that is the name of
a helper procedure to invoke as part of the test, e.g.
create procedure test._@Helper@_My_Procedure_That_Throws as -- simulate a constraint violation raiserror('my error', 16, 1); go create procedure test._@Test@_ShouldThrow as exec ssunit.AssertThrew 'my error', 'test._@Helper@_My_Procedure_That_Throws'; go
There are also two failure modes of an AssertThrew
style test as
opposed to the usual one. First the helper procedure may not cause an error to
be thrown, and secondly the error that is thrown may not the one expected - hence
the @error
argument. For example, when testing constraints, it's too
easy to write a test that causes a primary key or different foreign key
violation by accident instead of the desired failure and so you need the extra
comparison.
The problem with scraping error messages to verify a test is that they are
subject to change, at least for application specific errors. And so the message
comparison is done using the LIKE
operator so that you can perform
a fuzzy match. One benefit to explicitly naming your constraints is that you can
then use them as the @error
message instead of something vaguer, e.g.
-- Matches any FK violation exec ssunit.AssertThrew '%FOREIGN KEY%constraint%', 'test._@Helper@_My_Procedure_That_Throws'; -- Matches specific constraint violation through constraint name exec ssunit.AssertThrew '%MyTable_FK_MyColumn%', 'test._@Helper@_My_Procedure_That_Throws';
The _@Helper@_
attribute is used to indicate a helper procedure
that should also be deleted once the tests have run. If the attribute is not
applied then it must be handled either with the TestSchema_Clear
utility procedure or manually with a traditional drop procedure
call.
One technique for reducing noise and improving performance within the arrangement phase of a test is to factor out code into a helper function. The xUnit framework generally provides two mechanisms for two separate pairs of helper methods - one pair run per-test and the other pair run per-fixture. Within each pair the "SetUp" method is run before the test(s) and the "TearDown" method after.
In NUnit the first pair of methods are annotated with the [TestSetUp]
and [TestTearDown]
attributes, which in SQL-Unit is mapped to the
name adornments _@TestSetUp@_
and _@TestTearDown@_
.
Naturally it follows that the fixture-level pair in SQL-Unit are similarly named
_@FixtureSetUp@_
and _@FixtureTearDown@_
. In both
cases the rest of the procedure name is irrelevant and can be left off if so
desired. Each of the four helper procedures is optional too, so you can leave
out any that you don't need.
This just leaves the question of how you define a fixture. In NUnit it is the
name of the class that contains the test methods, but there are no classes in
T-SQL and so once again we must look to adorn the test name. This time we
use the format _$FixtureName$_
to define the name of the fixture.
All procedures that include the same _$XXX$_
in their name are
assumed to be part of the same fixture. Tests that belong to the same fixture
are run consecutively so that the fixture-level SetUp and TearDown helpers, if
defined, only have to be run once.
So, putting this all together we have the following example of how to write a test that has both fixture-level and test-level SetUp & TearDown helpers:-
create procedure test._@FixtureSetUp@_$CounterTests$_ as -- A good place to define static data and test tables. create table test.TestCounter ( Value int ); insert into test.TestCounter(Value) values(1); go create procedure test._@FixtureTearDown@_$CounterTests$_ as drop table test.TestCounter; go create procedure test._@TestSetUp@_$CounterTests$_ as update test.TestCounter set Value = Value + 10; go create procedure test._@TestTearDown@_$CounterTests$_ as update test.TestCounter set Value = 1; go create procedure test._@Test@_$CounterTests$_CounterShouldEqualElevenAfterSetUp as declare @value int; select @value = Value from test.TestCounter; exec ssunit.AssertIntegerEqualTo 11, @value; go exec ssunit.RunTests;
There is no restriction on the number of fixtures and tests that you can define
in a single script. If you prefer you can run all the test creation scripts in
one phase and then execute ssunit.RunTests
right at the end in one
go. That said, it is anticipated that you will partition your tests and
so the fixture name does not appear in the results output to conserve valuable
space.
The SetUp and TearDown helper procedures are specific instances of procedures
that are used to keep the test code readable by factoring out common code that
is invoked before and/or after the tests are run. Sometimes you have code that
is only common to a subset of the tests but you still want to factor it out, or
as explained earlier, you are writing the helper used to test that an error is
correctly raised. In these instances you can adorn the procedure with the
_@Helper@_
attribute:-
create procedure test._@Helper@_Do_common_action as -- Do something common such as inserting a piece of data go create procedure test._@Test@_Something_ShouldHappen_WhenAnotherThingOccurs as -- Use helper in the arangement phase exec test._@Helper@_Do_common_action; -- Act -- Assert go
Test procedures are dropped right after execution whereas helper procedures are only dropped at the end of the test run so they can be used multiple times.
Originally the only way to compare the contents of tables, views, stored
procedures, etc. was by capturing the output and executing a SELECT
that looked for the exact data with a complex WHERE
clause. Now
you can build a replica table with the expected data and assert the two tables
have the same contents, e.g.
create procedure test._@FixtureSetUp@_$MyFixture$_ as create table test.Actual ( FirstColumn int not null, SecondColumn varchar(100) null, ); create table test.Expected ( FirstColumn int not null, SecondColumn varchar(100) null, ); go create procedure test._@FixtureTearDown@_$MyFixture$_ as drop table test.Expected; drop table test.Actual; go create procedure test._@Test@_$MyFixture$_TablesShouldMatch as insert into test.Actual exec pub.MyProcThatReturnsResults; insert into test.Expected(FirstColumn, SecondColumn) select 41, 'forty-one' union all select 42, 'forty-two' union all select 43, 'forty-three' exec ssunit.AssertTableEqualTo 'test.Expected', 'test.Actual'; go
Here we use the SetUp and TearDown helper procedures to define the schema for
the tables we're going to use to capture the results (Actual
) and
define the expectation (Expected
). Using the
"INSERT INTO/UNION ALL SELECT
" idiom we can build the table with
our expected data in a nice readable fashion and then invoke the comparison.
Under the covers AssertTableEqualTo
just performs a
UNION ALL
and GROUP BY
using dynamic SQL and so the
two table schemas must be identical. Unlike the other AssertXxx
procedures, a table comparison is more complicated and so will report
additional information about comparison failures using extra result sets. For
instance if the table schemas don't match the column lists will be dumped,
whereas if the table contents don't match the rows of the two tables will be
returned.
The procedure you invoke to run the test suite (ssunit.RunTests
)
supports a number of parameters to control various aspects of test execution
and reporting:-
| Parameter | Description |
|---|---|
| @schemaName | Specify this if you want to run tests in a schema other than 'test' |
| @displayWidth | When running in 'batch mode' the console width is assumed to be 80 chars wide, use this parameter to widen or truncate the output |
| @reportResults | An enumeration value used to control the output of the per-test results (see blow) |
| @reportSummary | An enumeration value used to control the output of the results summary (see blow) |
| @isInteractive | Override the SQL client type by setting this to 0 for batch mode and 1 for interactive |
| @testNameFilter | The full or partial name of a single test or tests to run (uses LIKE to match test names) |
| @tearDownFirst | Flag to run the test & fixture tear down procedures before running the fixture set up |
The following example shows how to use a different schema and widen the output when running in batch mode:-
exec ssunit.RunTests @schemaName = 'unit_test', @displayWidth = 180;
The @reportResults
and @reportSummary
parameters are
enumeration values of the pseudo-type ssunit.ReportCondition
.
Essentially this is a tinyint
value with UDFs taking the place of
the enumeration symbols (so you don't hard-code a literal value):-
| Value | Symbol | Description |
|---|---|---|
| Never | ReportCondition_Never | Never generate the report |
| Always | ReportCondition_Always | Always generate the report |
| On Failure | ReportCondition_OnFailure | Only generate the report when at least one test has failed |
The following example shows how to configure the runner to only generate the per-test results when a test has failed:-
declare @onFailure ssunit.ReportCondition = ssunit.ReportCondition_OnFailure(); exec ssunit.RunTests @reportResults = @onFailure;
For more details about using UDFs to encapsulate constants and enumerations see my blog post Implementing Constants & Enumerations in a Database.
The @testNameFilter
allows you to focus on a single test, or group
of similarly named tests. This is useful when your test fixture is quite large
and you want to minimise the noise in the output, say, in SSMS. To run a single
test just specify the entire test name:-
exec ssunit.RunTests @testNameFilter = 'test._@Test@_SystemUser_ShouldThrow_WhenDuplicateLoginNameAdded';
The filter is applied to the test names using the LIKE
operator
which means you can match more than one test by using the wildcard characters:-
exec ssunit.RunTests @testNameFilter = '%_SystemUser_%';
To reduce the noise within each test script and ease the burden of constantly
setting the test runner parameters there is a global collection of these
that only need to be set once. You still have the option to override these
defaults on a per-script basis by passing different values when invoking
ssunit.RunTests
. The table below lists the parameters and the
API procedure used to set its default:-
| Parameter | API Procedure |
|---|---|
| @schemaName | ssunit.Configuration_SetSchemaNameDefault |
| @displayWidth | ssunit.Configuration_SetDisplayWidthDefault |
| @reportResults | ssunit.Configuration_SetReportResultsDefault |
| @reportSummary | ssunit.Configuration_SetReportSummaryDefault |
| @tearDownFirst | ssunit.Configuration_SetTearDownFirstDefault |
NB: The @isInteractive parameter was added to aid in testing SQL-Unit and as a
workaround for when the UDF ssunit.IsInteractive()
doesn't correctly
categorise the client so there is no way to override the default.
The framework has the notion of whether the tests are being run interactively,
such as via SSMS, or in batch mode via a command line tool like SQLCMD. This
discovery is done by the UDF ssunit.IsInteractive()
which just
queries the built-in app_name()
function and matches it to known
SQL clients.
The @displayWidth
parameter is only used in batch mode and allows
the runner to size the "Test Name" and "Failure Reason" columns to avoid ugly
text wrapping in a console window. When running as part of an automated build you are probably
redirecting the output and so effectively want to configure an "infinitely wide"
console instead.
As of v1.0 the SQL-Unit framework test script (RunTests.cmd
) uses
the global parameters feature to set the display
width once by invoking the relevant procedure:-
set displayWidth=120 . . . sqlcmd -E -S %server% -d %database% -Q "exec ssunit.Configuration_SetDisplayWidthDefault %displayWidth%"
Prior to v1.0 the test script used the variables feature of SQLCMD to inject the display width into the test script at run time:-
set displayWidth=120 . . . sqlcmd -E -S %server% -d %database% -i "%%f" -v DisplayWidth=%displayWidth%
Then in the SQL test script you need to parse that into an int so it can be
supplied to RunTests
. You also need to remember that the same script
run under SSMS will not substitute the variable and so you need to guard
against it causing an error:-
declare @displayWidth int = case when (isnumeric('$(DisplayWidth)') = 0) then 80 else convert(int, '$(DisplayWidth)') end; exec ssunit.RunTests @displayWidth = @displayWidth;
One of the problems with database unit testing is the stateful nature of the
database. In an ideal world you could build the database before each test
is run to minimise the problems of one test interfering with another, such as
when you forget to clean-up a temporary results table or adorn a helper procedure
with _@Helper@_
.
Sadly performance problems make this idea unworkable in all but the most trivial cases and so it is preferable to build the database once and try and avoid them by remembering to clean-up correctly in the TearDown procedures. Given the distinct lack of data when unit testing it is feasible to write a permanent helper procedure that just deletes from every table as part of the fixture TearDown; you could also call it as part of the fixture SetUp for a belt-and-braces approach.
To aid with the schema side of the problem SQL-Unit provides a procedure that
you can use to "wipe the schema clean" before running any new tests -
ssunit.TestSchema_Clear
. This procedure will drop all objects in
the specified schema (or 'test' by default) so that you won't have any errors
caused by attempting to create duplicate objects.
 You could also call them as the first step in your FixtureSetUp to
ensure that you're always starting the tests with no data. The @tearDownFirst
parameter was designed to automate this all for you. The only thing you need to
remember is to add a guard when dropping objects as they may not exist the
first time round.
create procedure test._@FixtureSetUp@_$MyFixture$_ as create table test.Result( . . . ); go create procedure test._@FixtureTearDown@_$MyFixture$_ as if (object_id('test.Result') is not null) drop table test.Result; delete from MyData; go
Once you get more familiar with the kinds of SQL error messages you see whilst
writing unit tests with SQL-Unit you may decide to forgo the pessimistic prologue
and just stick to the actual tests and invoking ssunit.RunTests
.
NB: The reason the test runner doesn't use nested transactions to avoid the data problem is to ensure that the production code runs as much as possible as it would in the real world.
Some database deployment techniques rely on applying "deltas" or "patches" to take the database from one release to the next. This may mean that your 3rd Party components (i.e. SQL-Unit) are also on different versions and so there is a UDF that tells you what version is installed, e.g.
declare @version ssunit.Version = ssunit.Version(); if (@version >= 150) begin -- SQL-Unit version is 1.5+ end
The version number is an integral value so that 1.0.0 = 100, 1.5.0 = 150, etc.
This library is freeware - you get what you pay for, nothing more, nothing less.
Please check the web site for updates.
Email<EMAIL_ADDRESS>Web: www.chrisoldwood.com
Chris Oldwood
12th July 2014


Delete
Are you sure?
Cancel
Delete
Admin Login
IP Cameras
Lecturesight
LS Overview
Clock
Audio monitoring
Opencast Stats
Opencast Failures
RPis
Venue Timetable
Fallback recorder
Live
recordings
CA checks
Completed
Title
Location
Start time
Progress
Title
Location
Start time
Title
Location
Recording date
Action
Title
Location
Start time
Progress


Regular Expression & Treemaps to Visualize Emergency Department Visits
Original post date: May 25 2017
I had the opportunity to attend the Open Data Science Conference (ODSC) East held in Boston, MA. Over a two day period I had the opportunity to listen to a number of leaders in various industries and fields. It was inspiring to learn about the wide variety of data science applications ranging from finance and marketing to genomics and even the refugee crisis.
One of the workshops at ODSC was text analytics, which includes basic text processing, dendrograms, natural language processing and sentiment analysis. This gave me the thought of applying some text analytics to visualize some data I was working on last summer. In this post I’m going to walk through how I used regular expression to label classification codes in a large dataset ( NHAMCS ) representing emergency department visits in the United States and eventually visualize the data.
The NHAMCS and ICD-9 Codes
Without going into too much detail, the National Health Ambulatory Medical Care Survey (NHAMCS) is large sample survey used to provide an estimate of visits to outpatient and emergency departments in general/short-stay hospital at a national scale for the United States. Those who are well versed in complex probability-sample survey designs (or interested in it), you can read about how it’s set up here . For this post I only using the emergency department data, not outpatient. The main thing to keep in mind moving forward is that the survey’s basic unit of measurement are visits or encounters made in the United States to emergency departments.
Diagnostic information on each visit is collected and coded in the NHAMCS by using the International Classification of Diseases (ICD) codes maintained by the World Health Organization. Specifically the NHAMCS public data files (1992-2014) use the ICD, 9th revision , clinical modification (ICD-9-CM). The 10th revision being currently used throughout the world since 2015 and the 11th revision is in-process, most likely it will be disseminated in 2018. You can check out this package I recently came across that validates and searches co-morbidities of ICD-9 and ICD-10 codes in R.
The Data Game Plan
In this post, the code is only for the 2005 emergency department (ED) NHAMCS dataset. If you interested in getting the original data you can go to this page . There is extensive documentation on the NHAMCS website that helps you download the data for use in SAS, Stata and SPSS. From my current knowledge (hours searching the vast interweb) there is no method in R to download these files. If someone wants to take the challenge of developing a method of pulling down the data using R, go for it! For this post, the data I’m using were Stata files and I used an R package to read-in those files. I’ve included subsetted data for ED NHAMCS from 2005 to 2009 in my GitHub repository if anyone is interested in using those files with my code.
To achieve our goal of visualizing diagnoses in ED visits we need to obtain, clean, and then appropriately setup our data. First we’re going to parse the text in official ICD-9-CM documentation using regular expression to create our own ICD dictionary/lookup table. Next, we’ll take the 2005 ED NHAMCS data, apply the survey design to get the correct estimates per ED visit. Then we’ll use our ICD dictionary to define each code, set it all up using the data.table
package
to create a
Treemap
visualization. I’ll be explaining a fair amount on data cleaning and regular expression, if you want to see the treemap you can scroll down to the end of the post.
Using Regex on ICD-9 Codes
Regular expression or regex is not unique just to R but is used across other types of programming languages (Java, Python, Perl). Simply put, regex is used to extract patterns of characters in a string. There is a good tutorial video here on regex and another video here on using regex in R. Disclaimer: I am not an expert on regex! I am still learning and this post is based on my current knowledge I’ve gathered so far. A good and helpful source I’ve been using is Rexegg . Regardless, let’s march forward towards our goal!
I’m going to take the 3-digit grouping ICD-9-CM documentation from the CDC’s Health Statistics [website]ftp://ftp.cdc.gov/pub/Health_Statistics/NCHS/Publications/ICD9-CM/2010), where I downloaded the DINDEX11.zip
file. Because of the annoying nature of the rich-text files (RTF), I just copied the entire document into a basic UTF-8 text file called Dc_3d10.txt
. My entire code is in my GitHub, but I’ll be referring to particular sections in this post. So moving forward, I’ll read this into R using the readLines
function and this output…
icd9.3 <- readLines("Dc_3d10.txt") > head(icd9.3,15)
# [1] "Appendix E\u2028List of Three-Digit Categories"
# [2] "1.\tINFECTIOUS AND PARASITIC DISEASES"
# [3] "Intestinal infectious diseases (001-009)"
# [4] "001\tCholera"
# [5] "002\tTyphoid and paratyphoid fevers"
# [6] "003\tOther salmonella infections"
# [7] "004\tShigellosis"
# [8] "005\tOther food poisoning (bacterial)"
# [9] "006\tAmebiasis"
# [10] "007\tOther protozoal intestinal diseases"
# [11] "008\tIntestinal infections due to other organisms"
# [12] "009\tIll-defined intestinal infections"
# [13] "Tuberculosis (010-018)"
# [14] "010\tPrimary tuberculous infection"
# [15] "011\tPulmonary tuberculosis"
It looks like there is a header/title at [1], numeric grouping at [2] “1.\tINFECTIOUS AND PARASITIC DISEASES”, subgrouping by ICD-9 code ranges, at [3] “Intestinal infectious diseases (001-009)” and then 3-digit ICD-9 codes followed by a specific diagnosis, at [10] “007\tOther protozoal intestinal diseases”. At the end we want to produce three separate data frames that we’ll categorize as:
- Groups: the title which contains the general diagnosis grouping
- Subgroups: the range of ICD-9 codes that contain a certain diagnosis subgroup
- Classification: the specific 3-digit ICD-9 code that corresponds with a diagnosis
First we’ll use a simple operation to remove the first line:
icd9.3 <- icd9.3[-1]
Next we’ll use regex to extract the Groups using this…
icd9.3[grep("^[0-9]+\\.",icd9.3)]
The grep()
function is used to extract patterns based on regex. To explain the regex, I am selecting lines that start with a digit of any length which is immediately followed by a period. The carat ^
initiates the pattern matching from the start of the string (going left to right). The [0-9]
represents any digit from 0 through 9 and the plus sign +
denotes at least one repeat of any digit. The two backslashes \\
is required because periods in regex are special meta-characters that represent any character (number, letter, symbol). To summarize, this identifies strings that start with 1.
, 2.
, 3.
, …, 17.
, and beyond.
Next I use the gsub()
function, which replaces or substitutes based on regex to replace all the \t
in the group names and replace it with two underscore __
which we’ll use later as an identifier to split the string in half to make the data frame (if this isn’t clear right now, hopefully it will be when we do the splitting).
icd9.3g <- gsub("\\.\t","__",icd9.3g) > icd9.3g[1:3]
# [1] "1__INFECTIOUS AND PARASITIC DISEASES"
# [2] "2__NEOPLASMS"
# [3] "3__ENDOCRINE, NUTRITIONAL AND METABOLIC DISEASES, AND IMMUNITY DISORDERS"
This regex removes all \t
specifically when it follows a period. Here we use the \\
again to identify a period.
Now we’ll split the string into separate columns within a data frame using the str_split_fixed
function in the stringr
package
. I set stringsAsFactors = FALSE
so that we maintain the data type of character with the strings. You can read about how this code has caused headaches for many users
here
. Here I assign Group.n
for the number
diag.g <- as.data.frame(stringr::str_split_fixed(icd9.3g,"__",2),stringsAsFactors = F)
names(diag.g) <- c("Group.n","Group")
diag.g <- diag.g[c("Group","Group.n")] #swap order of columns > head(diag.g)
# Group Group.n
# 1 INFECTIOUS AND PARASITIC DISEASES 1
# 2 NEOPLASMS 2
# 3 ENDOCRINE, NUTRITIONAL AND METABOLIC DISEASES, AND IMMUNITY DISORDERS 3
# 4 DISEASES OF BLOOD AND BLOOD-FORMING ORGANS 4
# 5 MENTAL DISORDERS 5
# 6 DISEASES OF THE NERVOUS SYSTEM AND SENSE ORGANS 6
Now we have a two-column data frame that contains the group number and name of that group so we can refer to for the future. However, later on (I realized when I got there) I needed to create additional columns to account for the range of 3-digit values that correspond to each Group. To do this I used the grep()
function to first get the names of each Group and the index of the Group titles in the text file by changing the value argument in grep()
.
groupn <- grep("\\.\t",icd9.3,value=T) #names
groupi <- grep("\\.\t",icd9.3,value=F) #index
Afterwards I find the lower and upper limit of each Group range by using the index and simple vector arithmetic in combination of gsub()
to extract only numbers. For the upper limit and added the maximum value of 999 (only 3-digits remember!) so that the lengths match, since I didn’t extract it from the code above. Then create the final dictionary for the Groups.
low.g <- gsub("[^0-9]","",icd9.3[groupi+2]) #lower limit of range
up.g <- c(gsub("[^0-9]","",icd9.3[groupi-1]),"999") #upper limit of range
diag.g <-data.frame(diag.g,low.g,up.g, stringsAsFactors = F)
names(diag.g) <- c("Group","Group.n","Start","End")
We move on to the Subgroups which we will extract based on the fact that all the corresponding lines have a parentheses contain a pattern of… 3 digits, a dash then another 3 digits. Ie. “Fracture of skull (800-804)” The appropriate regex is as follows…
icd9.3sg <- icd9.3[grep("\\([0-9]{3}-[0-9]{3}\\)",icd9.3)]
The double backslashes are used for parentheses (just like for periods) and I specify the pattern of any 3 digits using the {}
curly brackets. Next we remove any lingering \t
that might exist and replace with a space " "
. After that we’ll insert the __
split identifier we used above. This is specified by using regex to match the pattern of 3-digit parentheses that follows directly after a space, which is denoted as \\s
.
icd9.3sg <- gsub("\t"," ",icd9.3sg)
icd9.3sg <- gsub("\\s\\(([0-9]{3}-[0-9]{3})\\)","__\\1",icd9.3sg)
Like we did for the Group above, we’ll split the based on the __
split identifier.
diag.sg <- as.data.frame(
stringr::str_split_fixed(icd9.3sg,"__",2),
stringsAsFactors = F)
After that, we even want to split the ranges by the dash -
so we can get the ‘start’ and ‘end’ of the ICD-9 code range for each Subgroup. Then we’ll assign the names of the columns in the newly created data frame.
diag.sg <- as.data.frame(
cbind(
diag.sg,
stringr::str_split_fixed(diag.sg[,2],"-",2),
stringsAsFactors = F))
names(diag.sg) <- c("Subgroup","Range","Start","End") > head(diag.sg,4)
# Subgroup Range Start End
# 1 Intestinal infectious diseases 001-009 001 009
# 2 Tuberculosis 010-018 010 018
# 3 Zoonotic bacterial diseases 020-027 020 027
# 4 Other bacterial diseases 030-041 030 041
Now we’ll extract the Classifications. We want to generate a regex that captures a pattern of:
- A 3-digit sequence followed by a
\t
We can use the “|” or the OR operator in regex to capture these 3 patterns. Using similar regex from the Groups and Subgroups we generate this…
icd9.3c <- icd9.3[grep("(^[0-9]{3}\t)|(^V[0-9]{2}\t)|(E[0-9]{3}\t)",icd9.3)]
And then we can do the same method as the Group to remove any lingering “\t” and split the string to get an output of a data frame. Also
icd9.3c <- gsub("\t","__",icd9.3c)
diag.c <- as.data.frame(stringr::str_split_fixed(icd9.3c,"__",2),stringsAsFactors = F)
names(diag.c) <- c("Code","Classification")
diag.c <- diag.c[c("Classification","Code")] > head(diag.c)
# Classification Code
# 1 Cholera 001
# 2 Typhoid and paratyphoid fevers 002
# 3 Other salmonella infections 003
# 4 Shigellosis 004
# 5 Other food poisoning (bacterial) 005
# 6 Amebiasis 006
We started with some messy text but now after all that regex we have successfully extracted 3 separate data frames for the ICD-9 Group, Subgroup and Classification that can used as a reference moving forward!
Applying Survey Design
Since this post is focusing on regex, I will not go into detail about applying survey design to NHAMCS data files using R. In short, I used the survey
package
to apply the appropriate weighting based on the
4-stage probability sample survey
implemented by the NHAMCS. I’ve annotated my code for those who are interested about it but for the sake of this post I will not talk about it any further. All the details are based in the documentation files, that you can find by year in this
link
.
Why do we have to apply the weighting? By doing this, we can actually obtain accurate national estimates of ED visits in the United States. If we started running descriptive statistics on our data without this step, we’ll only be analyzing unweighted counts, which might not be an accurate representation of the sampling population. For those interested can read this post on about weighted surveys in R here .
Matching Codes to Descriptions
For the sake of this analysis we’ll only look at the first column of ICD-9 codes in the 2005 ED NHAMCS dataset, denoted as DIAG1
.
# > ed05$DIAG1[1:8]
# [1] "8472-" "78099" "V997-" "V997-" "7931-" "8489-" "920--" "8920-"
At first glance we notice two main things…
First, that each set of strings are five characters long. This is because the ICD-9 code system allows for more specificity with diagnoses beyond 3-digits. Take a quick look at the ICD-9 Wiki page for hypertensive disease. You can see that secondary hypertension can be further classified to malignant vs. benign and again whether it is renovascular or not. These classifications use up 5 digits (if you ignore the periods).
Secondly, that there are dashes when there are less than five characters. If we were only working with uniform patterns the match
function would have been a simple solution (link to a short explanatory
post
), but this is not the case. It looks like we’ll have to use regex again to look at the first 3 characters in each element of the DIAG1
vector.
I created a loop to match the 3-digit Classification code to the DIAG1
column. I created a new column and filled it with the appropriate code using regex matching. The last two lines are included to help us finalize our dictionary using data.table
package.
ed05.df$Code <- "-"
for (k in paste0("^",diag.c[,2])){ #codes
gindex <- grep(k,ed05.df[,1]) #matches code with DIAG1 column
ed05.df$Code[gindex] <- diag.c$Code[grep(k,diag.c[,2])]
ed05.df$Code.n <- as.numeric(ed05.df$Code) #some values are coered to NA
ed05.df$Code.n[which(is.na(ed05.df$Code.n))] <- 1000 #treat all NA's wih value 1000
}
Then we use the join()
function from the plyr
package to match the Classifications with the codes in our new data frame.
ed05.df <- join(ed05.df,diag.c,by="Code")
Overlap Joins using data.table
I’m not going to get into much detail here because this was something I had to learn when I discovered that joins and merges based on character types (ie. “001” or “057”) were tedious and very annoying. Thankfully this StackOverflow
post
was extremely useful to understand how the foverlaps()
function
works. In short to address this issue, I created numeric equivalents of the ICD-9 codes (ie. “019” became 19) because foverlaps() only works with numeric and integer values. After that I assigned the appropriate categories of Group and Subgroup to the Classification codes, cleaned it up a bit to remove unnecessary columns, and convert it back into a data.frame
class. My code is annotated if you would want to look at it and I would refer to the post I mentioned above.
Visualizing the Data
Since we have somewhat hierarchical data we can visualize this using a treemap. Now we make sure the treemap
package
is loaded and then use the lovely
IWantHue
website to get a nice color palette. I’ve annotated the code to explain what each argument does and after running this we get…
tree.n <- treemap(df.ed05,
index = c("Group", "Subgroup", "Classification"), #grouping for each
vSize = "Freq", #area of rectangles by NHAMCS estimates
type = "index", #see documentation
title = "NHAMCS Emergency Department Visits in 2005",
overlap.labels = 0.5, ##see documentation
palette = pal1, #custom palette from IWantHue
border.col = c("#101010", "#292929", "#333333"), #set border colors
fontsize.title = 40, #set font size
fontsize.labels = c(30, 24, 16), #set size for each grouping
lowerbound.cex.labels = .4, ##see documentation
fontcolor.labels = c("#000000", "#292929", "#333333"), #set color
fontface.labels = c(2, 4, 1), # bold, bold-italic, normal
fontfamily.labels = c("sans"), #sans font
inflate.labels = F, #see documentation
align.labels = c("center", "center"), #align all labels in center
bg.labels = 230 # 0 and 255 that determines the transparency
)
{width=95%}
From this we see that most ED visits had a diagnosis related to injury, poisoning, symptoms and respiratory system issues. This makes sense because usually you go to the hospital when you have an injury or some acute medical emergency. Below I’ve also created the treemaps for the other years leading up to 2009 with the colors corresponding with each group.
{width=20%} {width=20%} {width=20%} {width=20%} {width=20%}
Some comments on the data and visualization:
- It does not include ICD-9 codes for Supplementary Classifications (codes that start with V’s and E’s). I ignored these due to tedious nature of matching the Groups with characters and maybe in the future I can write something that includes them to the visualization.
- This data is for all visits regardless of demographic information. I suspect the treemaps between age, gender, race, and region would look very different.
- These are national estimates and the true value is contained within a confidence interval dependent on the survey design. Other visualizations may be appropriate to show the probability ranges of this data.
- There were missing or blank ICD-9 codes (the coders at the hospitals either didn’t fill them or there were no diagnoses?) accounted for 2.78% of all estimates.
- Originally I wanted to create a radial or sunburst tree of the data, but I had difficulty setting up the data in an appropriate form (ie. classes Node to phylo). I would appreciate any knowledge on how to get around this and maybe make that my next mini-project.
- This data is from ~10 years ago, it would be interesting to see what the most recent NHAMCS data says about emergency department visits.
Final Thoughts
From ODSC a speaker said that for data visualization, 80% of your work is cleaning setting up the data for the visualization and 20% is actually making the visualization… very true for this case. I did not expect the regex and data.table to take as long as it did. Regardless, I got the chance to learn more about the data.table package, practice my regular expression knowledge, and explore different tree visualizations! Any feedback, comments, and questions on the code or visualization are always welcome!
{width=20%}


HOME
AVAILABILITY
GLA UNIVERSITY
Academic Block 1
Ground floor
First floor
Second floor
Third floor
Faculty:


We require your residential address to post your gift pack.
Due to the prevailing situation in the country, Google IO Extended Sri Lanka 2019 team has made the decision
to
cancel the event.
We are pleased to announce that you have been selected to receive a limited edition Google I/O Extended Sri
Lanka 2019 gift pack.
Thank you for being part of Google I/O Extended Sri
Lanka 2019. Your gift pack will be posted to you sooner


Zend Framework
LICENSE
This source file is subject to the new BSD license that is bundled with this package in the file LICENSE.txt. It is also available through the world-wide-web at this URL: http://framework.zend.com/license/new-bsd If you did not receive a copy of the license and are unable to obtain it through the world-wide-web, please send an email to<EMAIL_ADDRESS>so we can send you a copy immediately.
Abstract Finite State Machine
Take a look on Wikipedia state machine description: http://en.wikipedia.org/wiki/Finite_state_machine
Any type of Transducers (Moore machine or Mealy machine) also may be implemented by using this abstract FSM. process() methods invokes a specified actions which may construct FSM output. Actions may be also used to signal, that we have reached Accept State
integer
$_defaultOperator= 'self'
Default boolean queries operator
self
Details\Zend_Search_Lucene_Search_QueryToken
$_lastToken= 'null'
Last token
It can be processed within FSM states, but this addirional state simplifies FSM
null
Details
boolean
$_suppressQueryParsingExceptions= 'true'
Defines query parsing mode.
If this option is turned on, then query parser suppress query parser exceptions and constructs multi-term query using all words from a query.
That helps to avoid exceptions caused by queries, which don't conform to query language, but limits possibilities to check, that query entered by user has some inconsistencies.
Default is true.
Use {@link Zend_Search_Lucene::suppressQueryParsingExceptions()}, {@link Zend_Search_Lucene::dontSuppressQueryParsingExceptions()} and {@link Zend_Search_Lucene::checkQueryParsingExceptionsSuppressMode()} to operate with this setting.
true
Details__construct(
)
:
void
Parser constructor
$states is an array of integers or strings with a list of possible machine states constructor treats fist list element as a sturt state (assignes it to $_current state). It may be reassigned by setState() call. States list may be empty and can be extended later by addState() or addStates() calls.
$inputAphabet is the same as $states, but represents input alphabet it also may be extended later by addInputSymbols() or addInputSymbol() calls.
$rules parameter describes FSM transitions and has a structure: array( array(sourseState, input, targetState[, inputAction]), array(sourseState, input, targetState[, inputAction]), array(sourseState, input, targetState[, inputAction]), ... ) Rules also can be added later by addRules() and addRule() calls.
FSM actions are very flexible and may be defined by addEntryAction(), addExitAction(), addInputAction() and addTransitionAction() calls.
_getInstance(
)
:
\Zend_Search_Lucene_Search_QueryParser
Get query parser instance
| Type | Description |
|---|---|
| \Zend_Search_Lucene_Search_QueryParser |
addEntryAction(
integer|string $state, \Zend_Search_Lucene_FSMAction $action
)
:
void
Add state entry action.
Inherited from: \Zend_Search_Lucene_FSM::addEntryAction()Several entry actions are allowed. Action execution order is defined by addEntryAction() calls
| Name | Type | Description |
|---|---|---|
| $state | integer|string | |
| $action | \Zend_Search_Lucene_FSMAction |
addExitAction(
integer|string $state, \Zend_Search_Lucene_FSMAction $action
)
:
void
Add state exit action.
Inherited from: \Zend_Search_Lucene_FSM::addExitAction()Several exit actions are allowed. Action execution order is defined by addEntryAction() calls
| Name | Type | Description |
|---|---|---|
| $state | integer|string | |
| $action | \Zend_Search_Lucene_FSMAction |
addInputAction(
integer|string $state, $inputSymbol, \Zend_Search_Lucene_FSMAction $action
)
:
void
Add input action (defined by {state, input} pair).
Inherited from: \Zend_Search_Lucene_FSM::addInputAction()Several input actions are allowed. Action execution order is defined by addInputAction() calls
| Name | Type | Description |
|---|---|---|
| $state | integer|string | |
| $inputSymbol | ||
| $action | \Zend_Search_Lucene_FSMAction |
addInputSymbol(
integer|string $inputSymbol
)
:
void
Add symbol to the input alphabet
Inherited from: \Zend_Search_Lucene_FSM::addInputSymbol()| Name | Type | Description |
|---|---|---|
| $inputSymbol | integer|string |
addInputSymbols(
array $inputAphabet
)
:
void
Add symbols to the input alphabet
Inherited from: \Zend_Search_Lucene_FSM::addInputSymbols()| Name | Type | Description |
|---|---|---|
| $inputAphabet | array |
addRule(
integer|string $sourceState, integer|string $input, integer|string $targetState, \Zend_Search_Lucene_FSMAction|null $inputAction
=
null
)
:
void
Add symbol to the input alphabet
Inherited from: \Zend_Search_Lucene_FSM::addRule()| Name | Type | Description |
|---|---|---|
| $sourceState | integer|string | |
| $input | integer|string | |
| $targetState | integer|string | |
| $inputAction | \Zend_Search_Lucene_FSMAction|null |
| Exception | Description |
|---|---|
| \Zend_Search_Exception |
addRules(
array $rules
)
:
void
Add transition rules
Inherited from: \Zend_Search_Lucene_FSM::addRules()array structure: array( array(sourseState, input, targetState[, inputAction]), array(sourseState, input, targetState[, inputAction]), array(sourseState, input, targetState[, inputAction]), ... )
| Name | Type | Description |
|---|---|---|
| $rules | array |
addState(
integer|string $state
)
:
void
Add state to the state machine
Inherited from: \Zend_Search_Lucene_FSM::addState()| Name | Type | Description |
|---|---|---|
| $state | integer|string |
addStates(
array $states
)
:
void
Add states to the state machine
Inherited from: \Zend_Search_Lucene_FSM::addStates()| Name | Type | Description |
|---|---|---|
| $states | array |
addTransitionAction(
integer|string $sourceState, integer|string $targetState, \Zend_Search_Lucene_FSMAction $action
)
:
void
Add transition action (defined by {state, input} pair).
Inherited from: \Zend_Search_Lucene_FSM::addTransitionAction()Several transition actions are allowed. Action execution order is defined by addTransitionAction() calls
| Name | Type | Description |
|---|---|---|
| $sourceState | integer|string | |
| $targetState | integer|string | |
| $action | \Zend_Search_Lucene_FSMAction |
closedRQLastTerm(
)
:
void
Process last range query term (closed interval)
| Exception | Description |
|---|---|
| \Zend_Search_Lucene_Search_QueryParserException |
dontSuppressQueryParsingExceptions(
)
:
void
Turn off 'suppress query parser exceptions' mode.
escape(
string $keyword
)
:
string
Escape keyword to force it to be parsed as one term
| Name | Type | Description |
|---|---|---|
| $keyword | string |
| Type | Description |
|---|---|
| string |
getDefaultEncoding(
)
:
string
Get query string default encoding
| Type | Description |
|---|---|
| string |
getState(
)
:
integer|string
Get FSM state.
Inherited from: \Zend_Search_Lucene_FSM::getState()| Type | Description |
|---|---|
| integerstring | $state|null |
openedRQLastTerm(
)
:
void
Process last range query term (opened interval)
| Exception | Description |
|---|---|
| \Zend_Search_Lucene_Search_QueryParserException |
parse(
string $strQuery, string $encoding
=
null
)
:
\Zend_Search_Lucene_Search_Query
Parses a query string
| Name | Type | Description |
|---|---|---|
| $strQuery | string | |
| $encoding | string |
| Type | Description |
|---|---|
| \Zend_Search_Lucene_Search_Query |
| Exception | Description |
|---|---|
| \Zend_Search_Lucene_Search_QueryParserException |
processModifierParameter(
)
:
void
Process modifier parameter
| Exception | Description |
|---|---|
| \Zend_Search_Lucene_Exception |
queryParsingExceptionsSuppressed(
)
:
boolean
Check 'suppress query parser exceptions' mode.
| Type | Description |
|---|---|
| boolean |
setDefaultEncoding(
string $encoding
)
:
void
Set query string default encoding
| Name | Type | Description |
|---|---|---|
| $encoding | string |
setDefaultOperator(
integer $operator
)
:
void
Set default boolean operator
| Name | Type | Description |
|---|---|---|
| $operator | integer |
setState(
integer|string $state
)
:
void
Set FSM state.
Inherited from: \Zend_Search_Lucene_FSM::setState()No any action is invoked
| Name | Type | Description |
|---|---|---|
| $state | integer|string |
| Exception | Description |
|---|---|
| \Zend_Search_Exception |


Version 1
The Extreme-scale Scientific Software Stack (E4S) and its related Software Development Kits (SDKs) are light-weight organizational elements intended to enhance collaboration and coordination across independently-developed products to provide an enhanced high-performance software stack.
E4S Community Policies are membership criteria for a product to become an E4S member package. This version of the policies was arrived at by the ECP SDK team, including representation from Programming Models and Runtimes, Development Tools, Math Libraries, Data and Vis, and Software Ecosystem and Delivery, and after considering multiple rounds of feedback from across ECP ST. The starting point for the majority of the policies was taken from the existing xSDK Community Policies.
E4S Membership Criteria
The policies below are criteria for E4S membership. To qualify for E4S membership, a package must demonstrate compatibility with each of these policies. Under special circumstances, a package may be granted an exception to a policy.
P1 Spack-based Build and Installation Each E4S member package supports a scriptable Spack build and production-quality installation in a way that is compatible with other E4S member packages in the same environment. When E4S build, test, or installation issues arise, there is an expectation that teams will collaboratively resolve those issues.
P2 Minimal Validation Testing Each E4S member package has at least one test that is executable through the E4S validation test suite (https://github.com/E4S-Project/testsuite). This will be a post-installation test that validates the usability of the package. The E4S validation test suite provides basic confidence that a user can compile, install and run every E4S member package. The E4S team can actively participate in the addition of new packages to the suite upon request.
P3 Sustainability All E4S compatibility changes will be sustainable in that the changes go into the regular development and release versions of the package and should not be in a private release/branch that is provided only for E4S releases.
P4 Documentation Each E4S member package should have sufficient documentation to support installation and use.
P5 Product Metadata Each E4S member package team will provide key product information via metadata that is organized in the E4S DocPortal format. Depending on the filenames where the metadata is located, this may require minimal setup.
P6 Public Repository Each E4S member package will have a public repository, for example at GitHub or Bitbucket, where the development version of the package is available and pull requests can be submitted.
P7 Imported Software If an E4S member package imports software that is externally developed and maintained, then it must allow installing, building, and linking against a functionally equivalent outside copy of that software. Acceptable ways to accomplish this include (1) forsaking the internal copied version and using an externally-provided implementation or (2) changing the file names and namespaces of all global symbols to allow the internal copy and the external copy to coexist in the same downstream libraries and programs. This pertains primarily to third party support libraries and does not apply to key components of the package that may be independent packages but are also integral components to the package itself.
P8 Error Handling Each E4S member package will adopt and document a consistent system for signifying error conditions as appropriate for the language and application. For e.g., returning an error condition or throwing an exception. In the case of a command line tool, it should return a sensible exit status on success/failure, so the package can be safely run from within a script.
P9 Test Suite Each E4S member package will provide a test suite that does not require special system privileges or the purchase of commercial software. This test suite should grow in its comprehensiveness over time. That is, new and modified features should be included in the suite.
Future Revision E4S Community Policies
The policies below are being considered for future revisions of the E4S Community Policies. These policies require further refinement or planning prior to adoption. The topics that these policies address provide information about likely subject areas for E4S policies going forward.
Note: FP stands for “future policy”
FP1 Portability Each E4S member package team will make a best effort at portability to common platforms. Depending on the function of the member package, considerations may include operating systems, compiler toolchains, architectures and accelerators. Lack of support for configurations should be denoted in appropriate Spack packages when possible.
FP2 Flexible Test Selection Support Each E4S member package will support the ability to specify that specific tests will be run for a given system allocation limit on execution time and node configuration resources. Particular use cases include the ability to a) run a subset of the test suite to complete within a few hours on standard workstation-level hardware b) be runnable in batch-only environments, that is, systems that require the use of PBS or other submission scripts.
FP3 Dependency Version Tracking Each E4S member package will document the versions of packages with which it can work or upon which it depends, in Spack. Similarly, incompatible versions of packages should also be appropriately tracked in Spack. The developers of E4S member packages will coordinate the needed versions of various packages for each E4S release.
FP4 Memory Testing Each E4S member package makes it possible to run their test suite under Valgrind in order to test for memory corruption issues. NOTE: The SDK team is planning to refine this policy so as to not specifically single out Valgrind.
FP5 Comprehensive Test Suite Each E4S member package will provide a comprehensive test suite that can be run by users and does not require special system privileges or the purchase of commercial software.
FP6 Documentation Each E4S member package should have sufficient documentation to support installation, use, and further development, as assessed periodically by its community of peers.
Library Policies: Apply to linkable libraries and similar products
Note: FLP stands for “future library policy”
FLP1 User-managed Exception Handling Each E4S member library package will have no hardwired calls to abort, exit, or MPI_Abort(). Also, no package should have hardwired print statements for error conditions. Each package should document which error codes/exceptions are recoverable, which may result in lost resources (for example, unfreed memory), and which indicate that the process may be in an undefined or totally broken state (for example, after a segmentation violation). It is the responsibility of the calling routine not to simply continue the computation when a “hard” error is returned; the calling routine will likely, by default, call an abort, but again that should be possible to override.
FLP2 User-managed I/O Control No package should have hardwired print or I/O statements that cannot be turned off through a programmatic interface; output should never be hard-wired to stdout or stderr. It is recommended that packages provide a way for users to turn on output and allow them to direct where it goes. Also, packages may print to stdout by default but only on one process (i.e., root rank “0”). But packages may also be completely silent by default (and require that users turn on outputting in the appropriate way).
FLP3 Symbols and Namespacing Each E4S member package will use a limited and well-defined symbol, macro, library, and include file name space. For example, there should be no publicly visible include files such as utils.h, or packages named libutil.a or macros named YES or TRUE. Namespacing of include files can be handled either by prepending each include file with a package name, for example <XXXmat.h>, or by placing and referencing all include files in a subdirectory with a package name, for example <XXX/mat.h>. Note that using a -I/XXX/ and referencing via <mat.h> would not be acceptable namespacing.
FLP4 Memory Leaks Each E4S member package will free all system resources it has acquired as soon as they are no longer needed, including closing open files, freeing memory, freeing MPI communicators, and freeing MPI data types created by the package. In particular, it is important that E4S compatible code not have any growing memory leaks (such as leaking memory during every timestep). Any resources created by the package that should be freed by the user, rather than by the package, must be fully documented. Note: Exceptions are permitted for situations where other software quality considerations are more important.


At Better Barter, we're dedicated to creating a more friendly community everywhere and everywhere by facilitating the old art of bartering! Here, you can offer old items or your work with others in your area, allowing you to exchange goods without any money involved!
A little archaic, a little unconventional, but wholly better for bringing people together.
...


Basics
Just the basics of Github and installation.
Read More
Commands
Commands we learned in class.
Read More
History
A summary of the history of GIT and Github.
Read More
Serives
An overview of some of the services that allow you to use graphically programs to interact with GIT.
Read More
Versioning
What is versioning and why is it important.
Read More


Its the time of the year again where all the teachers and staff wear there best suits and dresses, wear a good amount of makeup, have a clean shave. Its that time again! Staff Photos....
"Bullying is the use of force, threat, or coercion to abuse, intimidate, or aggressively dominate others. The behavior is often repeated and habitual. One essential prerequisite is the perception, by the bully or by others, of an imbalance of social or physical power ......
One touch of nature makes the whole world kin-That all with one consent praise new-born gauds, Though they are made and moulded of things past, And give to dust that is a little gilt More laud than gold o'er-dusted.....


Communal Cooking
Find
Near
Search
Forum
Account
Login/Signup
Profile
Joe C.
San Diego, CA
Message Me!
My Tools
meat thermometer
food processor
cast iron
13-inch frying pan
toaster
salad spinner
My Ingredients
white rice
pancake mix
garlic
cinnamon
thyme
eggs


_Erin_Brockovich_ (R) *** 1/2
On paper, _Erin_Brockovich_ bears more than a passing resemblance to 1998's _A_Civil_Action_. Both are vehicles for major Hollywood stars (respectively, Julia Roberts and John Travolta); both are based on true stories; and both stories are about a legal crusader helping the residents of a small town battle a large corporation that has been contaminating the local water supply. Despite these striking similarities, there remains one key difference: while treating its serious subject matter with the gravity it deserves, _Erin_Brockovich_ also manages to be a lot of fun.
That fact owes a lot to the film's vibrant title character, one that I imagine even Hollywood would have difficulty creating if reality hadn't. Erin (Roberts) is a vivacious, twice-divorced mother of three who, as we meet her, is not doing a very good job selling herself at a job interview. The scene is short, but its few minutes vividly depict the delicate balance that Roberts and director Steven Soderbergh achieves throughout the film's entire two-hour-plus running time. The scene is undeniably funny, its humor heightened by Erin's trashy mode of dress and the increasing desperation of her words. But one laughs at the situation and not her; in Roberts' eyes one can catch the underlying sadness and seriousness of the situation, plus the gradual awareness that she's fighting a losing battle. For the most part, _Erin_Brockovich_ plays in a similar way; one is consistently engaged on a purely--for lack of a better term--"entertainment" level, but providing an underlying foundation is something that lends the proceedings a bit more dramatic weight.
The major "something" in _Erin_Brockovich_ is the aforementioned case involving the residents of Hinkley, California, whose water supply has long been contaminated by the large PG&E corporation. Through some not-terribly-convincing plot machinations, Erin gets a job as an aide to attorney Ed Masry (Albert Finney), and it is through her work there that she gets personally involved with the plight of the Hinkley citizens, many of whom are suffering grave illness due to prolonged exposure to the poisoned water.
Erin is brassy, smartmouthed, and, most important of all, not a lawyer, and the bulk of the film's enjoyment derives from the ballsy, carefree way she conducts her research and life in general.  Roberts also has never been so ideally cast since that film; the kookiness of her character gives her ample opportunity to flash that trademark smile of hers (not to mention a few other assets) while giving her a chance to stretch comfortably as an actress. Not only are there plenty of the light moments for the fans, there are just as many heavier dramatic scenes for her to display her serious acting chops. That these two sides seamlessly gel into a full-bodied character is as much a compliment to her as it is to Soderbergh.
Soderbergh's sure direction keeps the action moving briskly enough, the actors believable enough, and the audience's emotions and interest engaged enough to forgive the overall familiarity of the story. Erin is, above anything else, an average woman, and this is a traditional tale of how she bucked the odds and scored a big triumph for herself and her fellow common folk. What aren't so easily forgiven, however, are other formulaic wrinkles in the script, which is credited to Susannah Grant. Chiefly problematic among these is her relationship with the next-door neighbor, a kind motorcyclist named George (Aaron Eckhart). Their relationship begins prickly, warms to a friendship, then heats up into a romance. Roberts and a barely unrecognizable Eckhart are well-matched, but their skill and rapport are shoved into some pedestrian plotting. As Erin gets more involved in her case, George and her kids feel neglected, leading to the usual resentment. It is here where Soderbergh comes up with the one moment that rings completely, ridiculously false: tending to Erin's kids at a barbecue, George longs for his more freewheeling days after watching a gang of Harley-riding bikers roar by.
The entirety of _Erin_Brockovich_ achieves its desired--and highly commercial--effect so well, though, that most viewers, including myself, won't ultimately care about such awkward moments. Soderbergh loyalists may be a bit dismayed that this film is not as risky and experimental as his other works, but only a filmmaker with his fresh savvy could take a well-worn formula and make such a satisfying entertainment.
Michael Dequina<EMAIL_ADDRESS>|<EMAIL_ADDRESS>|<EMAIL_ADDRESS>|<EMAIL_ADDRESS>Mr. Brown's Movie Site: http://welcome.to/mrbrown CinemaReview Magazine: http://www.CinemaReview.com on ICQ: #25289934 | on AOL Instant Messenger: MrBrown23
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


List of Graduates
No.
Id
Full name
Gender
E-mail
Graduation Year From Bachelor
Graduation Year From ORK Specialist
Graduation Year From Master
Photo
Operations
User info
Edit
Remove
Pagination summary:
info
«
1
(current)
Page size selector (javascript):
Show
entries


Maritime Bulletin Daily Nov 04 – 05
by Mikhail VoytenkoAccidents
• Tanker aground, Indonesia
• Cargo ship and tanker collided in Jeju Strait
• General cargo ship under tow
• Aframax tanker attacked in Gulf of Guinea UPDATE attack confirmed, 4 kidnapped
• Oil spill in Bremen
• Aground and Not Under Command vessels Worldwide Alerts (2 ships)
Details only for subscribers.
Annual subscription $750. For annual subscription, contact<EMAIL_ADDRESS>Subscribe if you want to receive accidents news ASAP and in full.


{% import "macros_2022.html" as macros %} {% extends "base.html" %} {% block content %}
All times are in Central European Time


i have been testing out my old stuff with the player 8 beta. i thought i’d dig around for some poorly coded fractal trials i was heavily into back in the winter when i was addicted to paul bourke’s work.
these were swfs i made that mostly give me that alert of how my movie is running slow and whether or not i would like to stop running it.
eventually i cleaned them up enough so that it hangs roughly right before i get that alert, but still i would have to wait @ 10 seconds before anything happened.
i was very pleased when i pushed them through 8 and cut my time in more than half… until i got to my mandelbrot swf- it wouldn’t even start iterating.
so i poked around, set intervals, tried to fill in textboxes with the current iteration- still nothing.
then i went down to the line that started it all…
onLoad = startMandelbrot;
//where startManelbrot is a function that does the iteration
don’t ask me why i used an onLoad for the timeline, i think i picked it from somewhere.
with this using player 7, what it did was allow the swf to appear in the browser before it did any work. taking this out and replacing it with just startMandelbrot(); would leave the browser comletely empty until it ran through the iteration.
with player 8, however, onLoad was never triggered.
now, it could be the case that i never should have done that in the first place ( i certainly haven’t done something like that in a while ), but i wonder why it worked using player 7 and not using player 8.


 They are described in the following sections.
The size of the pages used in the underlying database can be specified by calling the DB->set_pagesize() method. The minimum page size is 512 bytes and the maximum page size is 64K bytes, and must be a power of two. If no page size is specified by the application, a page size is selected based on the underlying filesystem I/O block size. (A page size selected in this way has a lower limit of 512 bytes and an upper limit of 16K bytes.)
There are several issues to consider when selecting a pagesize: overflow record sizes, locking, I/O efficiency, and recoverability.
First, the page size implicitly sets the size of an overflow record. Overflow records are key or data items that are too large to fit on a normal database page because of their size, and are therefore stored in overflow pages. Overflow pages are pages that exist outside of the normal database structure. For this reason, there is often a significant performance penalty associated with retrieving or modifying overflow records. Selecting a page size that is too small, and which forces the creation of large numbers of overflow pages, can seriously impact the performance of an application.
Second, in the Btree, Hash and Recno access methods, the finest-grained lock that Berkeley DB acquires is for a page. (The Queue access method generally acquires record-level locks rather than page-level locks.) Selecting a page size that is too large, and which causes threads or processes to wait because other threads of control are accessing or modifying records on the same page, can impact the performance of your application.
Third, the page size specifies the granularity of I/O from the database to the operating system. Berkeley DB will give a page-sized unit of bytes to the operating system to be scheduled for reading/writing from/to the disk. For many operating systems, there is an internal block size which is used as the granularity of I/O from the operating system to the disk. Generally, it will be more efficient for Berkeley DB to write filesystem-sized blocks to the operating system and for the operating system to write those same blocks to the disk.
Selecting a database page size smaller than the filesystem block size may cause the operating system to coalesce or otherwise manipulate Berkeley DB pages and can impact the performance of your application. When the page size is smaller than the filesystem block size and a page written by Berkeley DB is not found in the operating system's cache, the operating system may be forced to read a block from the disk, copy the page into the block it read, and then write out the block to disk, rather than simply writing the page to disk. Additionally, as the operating system is reading more data into its buffer cache than is strictly necessary to satisfy each Berkeley DB request for a page, the operating system buffer cache may be wasting memory.
Alternatively, selecting a page size larger than the filesystem block size may cause the operating system to read more data than necessary. On some systems, reading filesystem blocks sequentially may cause the operating system to begin performing read-ahead. If requesting a single database page implies reading enough filesystem blocks to satisfy the operating system's criteria for read-ahead, the operating system may do more I/O than is required.
Fourth, when using the Berkeley DB Transactional Data Store product, the page size may affect the errors from which your database can recover See Berkeley DB recoverability for more information.
The db_tuner utility suggests a page size for btree databases that optimizes cache efficiency and storage space requirements. This utility works only when given a pre-populated database. So, it is useful when tuning an existing application and not when first implementing an application.
The size of the cache used for the underlying database can be specified by calling the DB->set_cachesize() method. Choosing a cache size is, unfortunately, an art. Your cache must be at least large enough for your working set plus some overlap for unexpected situations.
When using the Btree access method, you must have a cache big enough for the minimum working set for a single access. This will include a root page, one or more internal pages (depending on the depth of your tree), and a leaf page. If your cache is any smaller than that, each new page will force out the least-recently-used page, and Berkeley DB will re-read the root page of the tree anew on each database request.
If your keys are of moderate size (a few tens of bytes) and your pages are on the order of 4KB to 8KB, most Btree applications will be only three levels. For example, using 20 byte keys with 20 bytes of data associated with each key, a 8KB page can hold roughly 400 keys (or 200 key/data pairs), so a fully populated three-level Btree will hold 32 million key/data pairs, and a tree with only a 50% page-fill factor will still hold 16 million key/data pairs. We rarely expect trees to exceed five levels, although Berkeley DB will support trees up to 255 levels.
The rule-of-thumb is that cache is good, and more cache is better. Generally, applications benefit from increasing the cache size up to a point, at which the performance will stop improving as the cache size increases. When this point is reached, one of two things have happened: either the cache is large enough that the application is almost never having to retrieve information from disk, or, your application is doing truly random accesses, and therefore increasing size of the cache doesn't significantly increase the odds of finding the next requested information in the cache. The latter is fairly rare -- almost all applications show some form of locality of reference.
That said, it is important not to increase your cache size beyond the capabilities of your system, as that will result in reduced performance. Under many operating systems, tying down enough virtual memory will cause your memory and potentially your program to be swapped. This is especially likely on systems without unified OS buffer caches and virtual memory spaces, as the buffer cache was allocated at boot time and so cannot be adjusted based on application requests for large amounts of virtual memory.
 In the steady state, this requires at most one I/O per operation to retrieve the appropriate leaf page.
You can use the db_stat utility to monitor the effectiveness of your cache. The following output is excerpted from the output of that utility's -m option:
prompt: db_stat -m 131072 Cache size (128K). 4273 Requested pages found in the cache (97%). 134 Requested pages not found in the cache. 18 Pages created in the cache. 116 Pages read into the cache. 93 Pages written from the cache to the backing file. 5 Clean pages forced from the cache. 13 Dirty pages forced from the cache. 0 Dirty buffers written by trickle-sync thread. 130 Current clean buffer count. 4 Current dirty buffer count.
The statistics for this cache say that there have been 4,273 requests of the cache, and only 116 of those requests required an I/O from disk. This means that the cache is working well, yielding a 97% cache hit rate. The db_stat utility will present these statistics both for the cache as a whole and for each file within the cache separately.
Database files created by Berkeley DB can be created in either little- or big-endian formats. The byte order used for the underlying database is specified by calling the DB->set_lorder() method. If no order is selected, the native format of the machine on which the database is created will be used.
Berkeley DB databases are architecture independent, and any format database can be used on a machine with a different native format. In this case, as each page that is read into or written from the cache must be converted to or from the host format, and databases with non-native formats will incur a performance penalty for the run-time conversion.
It is important to note that the Berkeley DB access methods do no data conversion for application specified data. Key/data pairs written on a little-endian format architecture will be returned to the application exactly as they were written when retrieved on a big-endian format architecture.
The Btree and Hash access methods support the creation of multiple data items for a single key item. By default, multiple data items are not permitted, and each database store operation will overwrite any previous data item for that key. To configure Berkeley DB for duplicate data items, call the DB->set_flags() method with the DB_DUP flag. Only one copy of the key will be stored for each set of duplicate data items. If the Btree access method comparison routine returns that two keys compare equally, it is undefined which of the two keys will be stored and returned from future database operations.
By default, Berkeley DB stores duplicates in the order in which they were added, that is, each new duplicate data item will be stored after any already existing data items. This default behavior can be overridden by using the DBC->put() method and one of the DB_AFTER, DB_BEFORE, DB_KEYFIRST or DB_KEYLAST flags. Alternatively, Berkeley DB may be configured to sort duplicate data items.
When stepping through the database sequentially, duplicate data items will be returned individually, as a key/data pair, where the key item only changes after the last duplicate data item has been returned. For this reason, duplicate data items cannot be accessed using the DB->get() method, as it always returns the first of the duplicate data items. Duplicate data items should be retrieved using a Berkeley DB cursor interface such as the DBC->get() method.
There is a flag that permits applications to request the following data item only if it is a duplicate data item of the current entry, see DB_NEXT_DUP for more information. There is a flag that permits applications to request the following data item only if it is not a duplicate data item of the current entry, see DB_NEXT_NODUP and DB_PREV_NODUP for more information.
It is also possible to maintain duplicate records in sorted order. Sorting duplicates will significantly increase performance when searching them and performing equality joins — both of which are common operations when using secondary indices. To configure Berkeley DB to sort duplicate data items, the application must call the DB->set_flags() method with the DB_DUPSORT flag. Note that DB_DUPSORT automatically turns on the DB_DUP flag for you, so you do not have to also set that flag; however, it is not an error to also set DB_DUP when configuring for sorted duplicate records.
When configuring sorted duplicate records, you can also specify a custom comparison function using the DB->set_dup_compare() method. If the DB_DUPSORT flag is given, but no comparison routine is specified, then Berkeley DB defaults to the same lexicographical sorting used for Btree keys, with shorter items collating before longer items.
If the duplicate data items are unsorted, applications may store identical duplicate data items, or, for those that just like the way it sounds, duplicate duplicates.
It is an error to attempt to store
identical duplicate data items when duplicates are being
stored in a sorted order. Any such attempt
results in the error message "Duplicate data items are not
supported with sorted data" with a
DB_KEYEXIST
return code.
Note that you can suppress the error message "Duplicate
data items are not supported with sorted data" by using the
DB_NODUPDATA flag. Use of this flag does not change the
database's basic behavior; storing duplicate data items in a
database configured for sorted duplicates is still an error
and so you will continue to receive the
DB_KEYEXIST
return code if you try to
do that.
For further information on how searching and insertion behaves in the presence of duplicates (sorted or not), see the DB->get() DB->put(), DBC->get() and DBC->put() documentation.
Berkeley DB allocates memory for returning key/data pairs and statistical information which becomes the responsibility of the application. There are also interfaces where an application will allocate memory which becomes the responsibility of Berkeley DB.
On systems in which there may be multiple library versions of the standard allocation routines (notably Windows NT), transferring memory between the library and the application will fail because the Berkeley DB library allocates memory from a different heap than the application uses to free it, or vice versa. To avoid this problem, the DB_ENV->set_alloc() and DB->set_alloc() methods can be used to give Berkeley DB references to the application's allocation routines.


Functional vs. Objection Oriented Programming
July 27, 2015
Trying to understand the difference between functional vs. object oriented programming has been quite a challenge. I have read articles on functional programming; I've read articles on objection oriented programming; I then read articles comparing the two. One major pattern I have noticed is that people are very passionate about this topic! It feels very politically incorrect to say that one is "better" than the other or that they are mutually exclusive. No, they are both useful and valuable when one knows how to use them and they can both be used together in the same program with good effect.
So what is the difference between functional and OOP? One concept I have learned is that functional programming has a strict philosophy on the behavior of functions and state. Specfically, state is immutable. Therefore, a function cannot be influenced by any external state that my change from function call to function call. Therefore, the behavior of a given function for a given set of inputs always produces the same output. This advantage of this consistent behavior of functions is that one can create very complex programs were many separate function can run concurrently without influencing one another. This consistency is not a requirement of OOP.
One side effect of this immutable-state property is that there is effectively no assignment operator. Since you can't change state, why bother having an assignment operator? Now you can change state in functional programming, but it must be a highly disciplined thought-out decision regarding the consequences. A functional programming language therefore typically makes the programmer jump through hoops in order to change the state of a variable.
When to use one or the other? This thread explains that you would use functional programming when you have a fixed set of things but the behavior may change, whereas you would use OOP when you have set of "operations on things" and you may primarily be adding more objects as your code evolves.


#include <tlm_core/tlm_2/tlm_generic_payload/tlm_phase.h>
|
| | tlm_phase (const std::type_info &type, const char *name) |
| |
Definition at line 42 of file tlm_phase.h.
◆ tlm_phase() [1/4]
| tlm::tlm_phase::tlm_phase |
( |
| ) |
|
|
inline |
◆ tlm_phase() [2/4]
| tlm::tlm_phase::tlm_phase |
( |
unsigned int |
id | ) |
|
◆ tlm_phase() [3/4]
| tlm::tlm_phase::tlm_phase |
( |
tlm_phase_enum |
standard | ) |
|
|
inline |
◆ tlm_phase() [4/4]
| tlm::tlm_phase::tlm_phase |
( |
const std::type_info & |
type, |
|
|
const char * |
name |
|
) |
| |
|
protected |
◆ get_name()
| const char* tlm::tlm_phase::get_name |
( |
| ) |
const |
◆ operator unsigned int()
| tlm::tlm_phase::operator unsigned int |
( |
| ) |
const |
|
inline |
◆ operator=()
| tlm_phase & tlm::tlm_phase::operator= |
( |
tlm_phase_enum |
standard | ) |
|
|
inline |
The documentation for this class was generated from the following file:


Could Westlife score their first number one album in more than a decade?
Celine Dion and Take That are behind them in the race to the top of the charts this week.
Westlife are expected to land their first UK number one album in more than a decade.
The Irish band’s new album Spectrum, their first release in nine years, is on course to top the charts on Friday, the Official Charts Company said.
At the halfway stage of the week, the album has shifted more than 50,000 in combined sales and is outselling the rest of the top 10 combined, including new releases from Celine Dion and Take That.
If the album continues its trajectory, it will be the eighth number one for Westlife.
The group, comprised of Kian Egan, Nicky Byrne, Shane Filan and Mark Feehily, last had a chart-topper with Back Home in 2007.
Spectrum is the band’s 11th studio album, and their first since 2010 record Gravity, which peaked at number three in the UK charts.
Dion’s new album Courage is set to debut in the charts at number two this week, ahead of Take That’s new live album Odyssey: Greatest Hits Live at number three.
Michael Ball and Alfie Boe are due to slip down to number four from number two with their latest release Back Together, while children’s album Kidz Bop 2020 is on course to enter the charts at number five.
Elsewhere in the top 10, retired footballer and pundit Chris Kamara is set to make his chart debut at number eight with his first ever album Here’s To Christmas, and The Police’s career anthology Every Move You Make: Studio Recordings is in the running to end the week at number nine.


This module describes the fragmentation model that partitions a flow into pages, columns, or regions.
It builds on the Page model module and introduces and defines the fragmentation model.
It adds functionality for pagination, breaking variable fragment size and orientation, widows and orphans.
CSS is a language for describing the rendering of structured documents
(such as HTML and XML)
on screen, on paper, etc.
Status of this document
This is a public copy of the editors’ draft.
It is provided for discussion only and may change at any moment.
Its publication here does not imply endorsement of its contents by W3C.
Don’t cite this document other than as work in progress.
GitHub Issues are preferred for discussion of this specification.
When filing an issue, please put the text “css-break” in the title,
preferably like this:
“[css-break] …summary of comment…”.
All issues and comments are archived,
and there is also a historical archive.
This document was produced by a group operating under
the W3C Patent Policy.
W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group;
that page also includes instructions for disclosing a patent.
An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
“At-risk” is a W3C Process term-of-art, and does not necessarily imply that the feature is in danger of being dropped or delayed. It means that the WG believes the feature may have difficulty being interoperably implemented in a timely manner, and marking it as such allows the WG to drop the feature if necessary when transitioning to the Proposed Rec stage, without having to publish a new Candidate Rec without the feature first.
1. Introduction
This section is not normative.
In paged media
(e.g., paper, transparencies, photo album pages,
pages displayed on computer screens as printed output simulations),
as opposed to continuous media,
the content of the document is split into
one or more discrete display surfaces.
In order to avoid awkward breaks
(such as halfway through a line of text),
the layout engine must be able to shift around content
that would fall across the page break.
This process is called pagination.
This is currently a diff spec.
See CSS Fragmentation Level 3 for the rest of the specification.
(That text will eventually be folded into this document.)
1.1. Adjoining Margins at Breaks: the margin-break property
When an unforced break occurs before or after the box,
any margins adjoining the break truncate to
the remaining fragmentainer extent before the break,
and are truncated to zero after the break.
When a forced break occurs there,
adjoining margins before the break are truncated,
but margins after the break are preserved. Cloned margins are always truncated to zero.
Note: When margins collapse
(see CSS2§8.3.1),
the margins of multiple boxes can be adjoining the break.
Antenna House also allows a second keep keyword,
which preserves the margin after the break;
it is otherwise discarded.
Do we want to include this feature?
Also, if only one keep is specified, does it apply only to the before margin or both sides?
See discussion.

Here we can compare the effects of margin-break,
before and after forced and unforced breaks.

This paragraph starts after an unforced break.

This heading is given a forced break before.

Here are illustrations of how it might render
with each margin-break value:
The editors would like to thank
Murakami Shinyu
specifically for his contributions to CSS Fragmentation Level 4,
and to all the contributors to Level 3,
which constitutes the bulk of this specification.
Conformance
Document conventions
Conformance requirements are expressed with a combination of
descriptive assertions and RFC 2119 terminology. The key words “MUST”,
“MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”,
“RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this
document are to be interpreted as described in RFC 2119.
However, for readability, these words do not appear in all uppercase
letters in this specification.
All of the text of this specification is normative except sections
explicitly marked as non-normative, examples, and notes. [RFC2119]
Examples in this specification are introduced with the words “for example”
or are set apart from the normative text with class="example",
like this:
This is an example of an informative example.
Informative notes begin with the word “Note” and are set apart from the
normative text with class="note", like this:
Note, this is an informative note.
Advisements are normative sections styled to evoke special attention and are
set apart from other normative text with , like
this: UAs MUST provide an accessible alternative.
Conformance classes
Conformance to this specification
is defined for three conformance classes:
A style sheet is conformant to this specification
if all of its statements that use syntax defined in this module are valid
according to the generic CSS grammar and the individual grammars of each
feature defined in this module.
A renderer is conformant to this specification
if, in addition to interpreting the style sheet as defined by the
appropriate specifications, it supports all the features defined
by this specification by parsing them correctly
and rendering the document accordingly. However, the inability of a
UA to correctly render a document due to limitations of the device
does not make the UA non-conformant. (For example, a UA is not
required to render color on a monochrome monitor.)
An authoring tool is conformant to this specification
if it writes style sheets that are syntactically correct according to the
generic CSS grammar and the individual grammars of each feature in
this module, and meet all other conformance requirements of style sheets
as described in this module.
Requirements for Responsible Implementation of CSS
The following sections define several conformance requirements
for implementing CSS responsibly,
in a way that promotes interoperability in the present and future.
Partial Implementations
So that authors can exploit the forward-compatible parsing rules to assign fallback values, CSS renderers must treat as invalid
(and ignore as appropriate)
any at-rules, properties, property values, keywords, and other syntactic constructs
for which they have no usable level of support.
In particular, user agents must not selectively ignore
unsupported property values and honor supported values in a single multi-value property declaration:
if any value is considered invalid (as unsupported values must be),
CSS requires that the entire declaration be ignored.
Implementations of Unstable and Proprietary Features
Once a specification reaches the Candidate Recommendation stage,
implementers should release an unprefixed implementation
of any CR-level feature they can demonstrate
to be correctly implemented according to spec,
and should avoid exposing a prefixed variant of that feature.
To establish and maintain the interoperability of CSS across
implementations, the CSS Working Group requests that non-experimental
CSS renderers submit an implementation report (and, if necessary, the
testcases used for that implementation report) to the W3C before
releasing an unprefixed implementation of any CSS features. Testcases
submitted to W3C are subject to review and correction by the CSS
Working Group.
This is currently a diff spec.
See CSS Fragmentation Level 3 for the rest of the specification.
(That text will eventually be folded into this document.) ↵
Antenna House also allows a second keep keyword,
which preserves the margin after the break;
it is otherwise discarded.
Do we want to include this feature?
Also, if only one keep is specified, does it apply only to the before margin or both sides?
See discussion. ↵


I could lavish my life, With a bed of silken fallacies But underneath are rotten springs I'm starting to see Facades that we fabricate Slowly crumbling away No guarantee that I'll be strong And I guarantee my pride is singing this song And I'm scared to show my little black box But it's all for you (2nd time "And" instead of "But") This little light will go away if I won't be real This little light will run away if I don't tell you how I feel Little light please stay don't stray Help me to tolerate myself, myself, myself, 'Cause I feel so vain I am bright as the sun, With a crimson heat so blackening And at the core the cool's shut in The sun knows it's time to set And to draw a close My memory just won't comply No guarantee that I'll be strong And I guarantee my pride is singing this song And I'm scared to show my little black box And it's all for you This little light will go away if I won't be real This little light will run away if I don't tell you how I feel Little light please stay don't stray Help me to tolerate myself, myself, myself, 'Cause I feel so vain This little light will go away if I won't be real This little light will run away if I don't tell you how I feel Little light please stay don't stray Help me to tolerate myself, myself, myself, 'Cause I feel so vain