|
GoodHabits
Encourage your good habbits!
|
Signals | |
| void | habitStored (var habit) |
| void | habitRemoved () |
| Signal emited as habit removed. | |
| void | recordRemoved () |
| Signal emited as record removed. | |
Public Member Functions | |
| string | getHabitTitleById (string uid) |
| var | getHabitById (string uid) |
| string | generateId () |
| string | getUniqueId (array) |
| void | saveAndUpdateHabits () |
| void | saveAndUpdateRecords () |
Properties | |
| alias | dispatcher |
| Property to configure target dispatcher / logic. More... | |
| alias | cache |
| Main cache component. | |
| alias | records |
| Loaded in-memory records. | |
| alias | habits |
| Loaded in-memory habits. More... | |
| alias | habitDetails |
| Component for ease of usage, loaded in-memory habit. More... | |
| alias | recordDetails |
| Component for ease of usage, loaded in-memory record. | |
Data access object. Component do read/write access to storage and holds in memory all data required for application.
WebStorage
. | string DataModel::generateId | ( | ) |
Function returns random id based on random and on time. Simple and light implementation UUID.
| var DataModel::getHabitById | ( | string | uid | ) |
Helper function that returns habit by given id.
| uid | identifier of habit |
| string DataModel::getHabitTitleById | ( | string | uid | ) |
Function that returns title of habit by given id.
| uid | identifier of habit |
| string DataModel::getUniqueId | ( | array | ) |
Function generate unique id using generateId
. Then iterate over given array
to ensure that generated id is unique. If so, returns it, otherwise generate new and repeat procedure until generated id will be unique.
| JSON-array | of elements with attribute id . |
array
) uid.
|
signal |
Signal emited as habit stored.
| var | habit JSON-onject of stored habit. |
| void DataModel::saveAndUpdateHabits | ( | ) |
Store habits permanently and notify views by sending respective signals.
| void DataModel::saveAndUpdateRecords | ( | ) |
Store records permanently and notify views by sending respective signals.
| alias DataModel::dispatcher |
Property to configure target dispatcher / logic.
Logic
| alias DataModel::habitDetails |
Component for ease of usage, loaded in-memory habit.
| alias DataModel::habits |
Loaded in-memory habits.


1
Prolog stands for PROgramming in LOGic. It was developed from a foundation of logical theorem proving and originally used for research in natural language processing. Although its popularity has sprung up mainly in the artificial intelligence (AI) community, where it has been used for applications such as expert systems, natural language, and intelligent databases, it is also useful for more conventional types of applications. It allows for more rapid development and prototyping than most languages because it is semantically close to the logical specification of a program. As such, it approaches the ideal of executable program specifications.
Programming in Prolog is significantly different from conventional procedural programming and requires a readjustment in the way one thinks about programming. Logical relationships are asserted, and Prolog is used to determine whether or not certain statements are true, and if true, what variable bindings make them true. This leads to a very declarative style of programming.
In fact, the term program does not accurately describe a Prolog collection of executable facts, rules and logical relationships, so you will often see term logicbase used in this book as well.
While Prolog is a fascinating language from a purely theoretical viewpoint, this book will stress Prolog as a practical tool for application development.
Much of the book will be built around the writing of a short adventure game. The adventure game is a good example since it contains mundane programming constructs, symbolic reasoning, natural language, data, and logic.

You should create a source file for the game, and enter the examples from the book as you go. You should also create source files for the other three programs covered in the exercises. Sample source code for each of the programs is included in the appendix.
The adventure game is called Nani Search. Your persona as the adventurer is that of a three year old girl. The lost treasure with magical powers is your nani (security blanket). The terrifying obstacle between you and success is a dark room. It is getting late and you're tired, but you can't go to sleep without your nani. Your mission is to find the nani.
Nani Search is composed of
You control the game by using simple English commands (at the angle bracket (>) prompt) expressing the action you wish to take. You can go to other rooms, look at your surroundings, look in things, take things, drop things, eat things, inventory the things you have, and turn things on and off.
Figure 1.1 shows a run of a completed version of Nani Search. As you develop your own version you can of course change the game to reflect your own ideas of adventure.
The game will be implemented from the bottom up, because that fits better with the order in which the topics will be introduced. Prolog is equally adept at supporting top-down or inside-out program development.
A Prolog logicbase exists in the listener's workspace as a collection of small modular units, called predicates. They are similar to subroutines in conventional languages, but on a smaller scale.
The predicates can be added and tested separately in a Prolog program, which makes it possible to incrementally develop the applications described in the book. Each chapter will call for the addition of more and more predicates to the game. Similarly, the exercises will ask you to add predicates to each of the other applications.
We will start with the Nani Search logicbase and quickly move into the commands that examine that logicbase. Then we will implement the commands that manipulate the logicbase.
Along the way there will be diversions where the same commands are rewritten using a different approach for comparison. Occasionally a topic will be covered that is critical to Prolog but has little application in Nani Search.
One of the final tasks will be putting together the top-level command processor. We will finish with the natural language interface.
You are in the kitchen. You can see: apple, table, broccoli You can go to: cellar, office, dining room > go to the cellar You can't go to the cellar because it's dark in the cellar, and you're afraid of the dark. > turn on the light You can't reach the switch and there's nothing to stand on. > go to the office You are in the office. You can see the following things: desk You can go to the following rooms: hall, kitchen > open desk The desk contains: flashlight crackers > take the flashlight You now have the flashlight > kitchen You are in the kitchen > turn on the light flashlight turned on. ... |
Figure 1.1. A sample run of Nani Search
The goal of this book is to make you feel comfortable with
As with any language, the best way to learn Prolog is to use it. This book is designed to be used with a Prolog listener, and will guide you through the building of four applications.
The adventure game will be covered in detail in the main body of the text, and the others you will build yourself based on the exercises at the end of each chapter.
There will be two types of example code throughout the book. One is code, meant to be entered in a source file, and the other is interactions with the listener. The listener interactions are distinguished by the presence of the question mark and dash (?-) listener prompt.
Here is a two-line program, meant to help you learn the mechanics of the editor and your listener.
mortal(X) :- person(X). person(socrates).
In the Amzi! Eclipse IDE, first create a project for your source files. Select File | New | Project on the main menu, then click on 'Prolog' and 'Project', and enter the name of your project, 'adventure'. Next, create a new source file. Select File | New | File, and enter the name of your file, 'mortal.pro'. Enter the pro-gram in the edit window, paying careful attention to upper and lowercase letters and punctuation. Then select File | Save from the menu.
Next, start the Prolog listener by selecting Run | Run As | Interpreted Project. Loading the source code in the Listener is called consulting. You should see a message indicating that your source file, 'mortal.pro', was consulted. This message is followed by the typical listener prompt.
?-
Entering the source code in the Listener is called consulting. Select Listener/Consult from the main menu, and select 'mortal.pro' from the file menu. You can also consult a Prolog source file directly from the listener prompt like this.
?- consult(mortal). yes
See the documentation and/or online help for details on the Amzi! listener and Eclipse IDE.
In all the listener examples in this book, you enter the text after the prompt (?), the rest is provided by Prolog. When working with Prolog, it is important to remember to include the final period and to press the 'return' key. If you forget the period (and you probably will), you can enter it on the next line with a 'return.'
Once you've loaded the program, try the following Prolog queries.
?- mortal(socrates). yes ?- mortal(X). X = socrates.
Now let's change the program. First type 'quit.' to end the listener. Go back to the edit window and add the line
person(plato).
after the person(socrates) line.
Select Run | Run As | Interpreted Project to start the listener again with your updated source file. And test it.
?- mortal(plato). yes
One more test. Enter this query in the listener.
?- write('Hello World'). Hello World yes
You are now ready to learn Prolog.
Let's look at the simple example in more detail. In classical logic we might say "All people are mortal," or, rephrased for Prolog, "For all X, X is mortal if X is a person."
mortal(X) :- person(X).
Similarly, we can assert the simple fact that Socrates is a person.
person(socrates).
From these two logical assertions, Prolog can now prove whether or not Socrates is mortal.
?- mortal(socrates).
The listener responds
yes
We could also ask "Who is mortal?" like this
?- mortal(X).
and receive the response
X = socrates
This declarative style of programming is one of Prolog's major strengths. It leads to code that is easier to write and easier to maintain. For the most part, the programmer is freed from having to worry about control structures and transfer of control mechanisms. This is done automatically by Prolog.
By itself, however, a logical theorem prover is not a practical programming tool. A programmer needs to do things that have nothing to do with logic, such as read and write terms. A programmer also needs to manipulate the built-in control structure of Prolog in order for the program to execute as desired.
The following example illustrates a Prolog program that prints a report of all the known mortals. It is a mixture of pure logic from before, extra-logical I/O, and forced control of the Prolog execution behavior. The example is illustrative only, and the concepts involved will be explained in later chapters.
First add some more philosophers to the 'mortal' source in order to make the report more interesting. Place them after 'person(plato).'
person(zeno). person(aristotle).
Next add the report-writing code, again being careful with punctuation and upper- and lowercase. Note that the format of this program is the same as that used for the logical assertions.
mortal_report:- write('Known mortals are:'),nl, mortal(X), write(X),nl, fail.
Figure 1.2 contains the full program, with some optional comments, indicated by the percent sign (%) at the beginning of a line. Load the program in the listener and try it. Note that the syntax of calling the report code is the same as the syntax used for posing the purely logical queries.
?- mortal_report. Known mortals are: socrates plato aristotle no
The final 'no' is from Prolog, and will be explained later.
% This is the syntax for comments. % MORTAL - The first illustrative Prolog program mortal(X) :- person(X). person(socrates). person(plato). person(aristotle). mortal_report:- write('Known mortals are:'),nl, mortal(X), write(X),nl, fail. |
Figure 1.2. Sample program
You should now be able to create and edit source files for Prolog, and be able to load and use them from a Prolog listener.
You have had your first glimpse of Prolog and should understand that it is fundamentally different from most languages, but can be used to accomplish the same goals and more.
With any field of knowledge, the critical concepts of the field are embedded in the definitions of its technical terms. Prolog is no exception. When you understand terms such as predicate, clause, backtracking, and unification you will have a good grasp of Prolog. This section defines the terms used to describe Prolog programs, such as predicate and clause. Execution-related terms, such as backtracking and unification will be introduced as needed throughout the rest of the text.
Prolog jargon is a mixture of programming terms, database terms, and logic terms. You have probably heard most of the terms before, but in Prolog they don't necessarily mean what you think they mean.
In Prolog the normally clear distinction between data and procedure becomes blurred. This is evident in the vocabulary of Prolog. Almost every concept in Prolog can be referred to by synonymous terms. One of the terms has a procedural flavor, and the other a data flavor.
We can illustrate this at the highest level. A Prolog program is a Prolog logicbase. As we introduce the vocabulary of Prolog, synonyms (from Prolog or other computer science areas) for a term will follow in parentheses. For example, at the highest level we have a Prolog program (logicbase).
The Prolog program is composed of predicates (procedures, record types, relations). Each is defined by its name and a number called arity. The arity is the fixed number of arguments (attributes, fields) the predicate has. Two predicates with the same name and different arity are considered to be different predicates.
In our sample program we saw three examples of predicates. They are: person/1, mortal_report/0, and mortal/1. Each of these three predicates has a distinctly different flavor.
Each predicate in a program is defined by the existence of one or more clauses in the logicbase. In the example program, the predicate person/1 has four clauses. The other predicates have only one clause.
A clause can be either a fact or a rule. The three clauses of the person/1 predicate are all facts. The single clauses of mortal_report/0 and mortal/1 are both rules.
Copyright ©1990,1996-97, 2004 Amzi! inc. All Rights Reserved


The lu-select
component is just a InputWithPicker
. Which means it is an input (it implements the control value accessor), and it has a picker (a popover that help picking a value).
The most important notion here is that the select components delegate the logic of displaying a list of options to its picker, while handling the 2-way data binding (as a control value accessor)
So even if in these examples we only use a lu-option-picker
, you can use whatever picker you want as long as it implements the interface IPickerPanel
. you can have a select with a date-picker, a color-picker, etc...
Another important notion is that the lu-select
has no idea how to properly display the current value, so you must pass him a InputDisplayer
In the same vein, you can pass the select any select-clearer
and it will display it in the right place and clear itself when the clearer calls onClear


{{ . | default "" | safeHTML }}
{{ . | markdownify }}
Nederburg Hugo Theme by Appernetic.
A port of Tracks by Compete Themes.


Honzi
/
Bookmarks
/
Software
/Thief
Thief 3 Difficulty
Hearing
Vision
Easy
100
0
Normal
1
1
Hard
100
100
Expert
0
0


Here is a very interesting issue in MySQL database.
SQL truncation occurs when you try to insert/update a field with a string which is longer than the maximum length defined in the table structure.
For instance if you defined a column name
as a varchar(8) and you provide abracadabra
wich is 11, MySQL will truncate the string to 8 and will insert abracada
instead.
No message, no warning, nothing at all. This flaw can lead to security issue in some case.
First I create this small table:
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`login` varchar(8) NOT NULL,
`passwd` varchar(64) NOT NULL,
PRIMARY KEY (`id`)
);
Then I insert some users:
My three users are ok and absolutly regular.
But now what’s happen if I try to insert another user who has a name longer that 8 (login
max length)?
See? It has been truncated to 8 without any additionnal message. So maybe I can try another one?
Looks like it worked.
Now I have a user “admin
” and a user “admin
“ with some trailing spaces.
Unfortunatly MySQL strings compare also suffers of another issue who ignores trailing spaces, that means those two strings are considered as equal in some case. POC:
Et voilà! MySQL clause group by
considers user 1
and user 4
as “equal”.
Tests with operator like
:
</div>
In this situation like
seems to be safer.
First of all, it should not be allowed to register two users with the same login/email in any system. Then, since MySQL will return 2 results in some case, you cannot really predict wich one will be used when comparing with the user entry so it can be dangerous in some function like “Forgot password”. A user could receive an email with credentials of another user…
According to MySQL documentation, a trick is to change sql_mode
to be more strict:
If a value could not be inserted as given into a transactional table, abort the statement.
As a matter of fact I’m not sure this is a good solution. Many developers don’t even test the result of their sql requests so if the server uses this parameter this can leads to many holes.
Another solution would be to use a unique index on the proper field, MySQL will trigger an error because it will (again) consider ”admin
” and “admin
“ as equal.
Finally, most of the orm check the good validity of the values before executing the queries and apply filters. This must be tested…


In The Toolbox Ė Whiteboards
They say a picture is worth a thousand words and in software development there are plenty of words to be said about a great many things from what weíre building to how weíre building it. The old adage ďa stitch in time saves nineĒ is a cornerstone of the agile methodology as we struggle to ensure that the team (customer, developers, testers, etc.) are all on the same page before we start laying down code.
In the modern world of software development where there is a bias towards ďworking software over comprehensive documentationĒ the written word is starting to give way to higher bandwidth conversations, most notably just talking to each other face-to-face when the need arises. But words alone are not enough as not everyone can understand a concept just through verbal communication, you canít just talk slower, and louder, and hope that the other people will just ďget itĒ. The moment a conversation begins to deteriorate is (if youíve not already done so) probably a great time to double the lines of communication and open a channel to the visual senses.
In an earlier instalment of this column [1] I touched briefly on drawing diagrams, but from the perspective of using my notebook as the canvas. Whilst it has some benefits, for example the permanency, Iíve found that I would much prefer the larger, more transitory nature of the whiteboard if it was on offer. What Iíve come to discover is that I was resorting to using my notebook due to the absence of a better tool (the whiteboard), and because it was a much better tool than the alternative (Visio & SharePoint) for the nature of the message I wanted to convey.
One of downsides of working in The Enterprise is that large organisations are obsessed with exploiting economies of scale and this is very noticeable when you look at the workspace allocated to teams. Open plan offices with banks of desks ensure the maximum density of people and can feel somewhat like a battery farming approach to software delivery. In a continued drive to replace anything physical with its virtual equivalent there is no longer any room for luxuries like whiteboards or Kanban boards. Presumably information persisted as ďelectronic bitsĒ are so much more versatile than physical media, so why would you want to accept anything less?
The rationale for digitising everything in the office is (I suspect) predicated on a false assumption that doing anything more than once is waste and must therefore be eliminated. The fact that you have not understood what it is that needs doing, and will therefore build the wrong thing, is secondary to the needs of appearing to make progress. By removing the physical tools we use to collaborate we remove the impetus to do so and the whiteboard is one of the largest and most accessible reminders we have available. I can think of no other tool that draws (no pun intended) us in quite like a whiteboard covered in ad-hoc sketches and notes.
Whilst the notion of hot-desking might be great in theory, in practice a team that is going to spend any considerable amount of time together needs a place to call home. This spot needs a certain amount of permanence, ideally closely located to its dependencies, with some surfaces on which the team can draw and attach its information radiators. If youíre unlucky enough to be sitting in one of the rat runs that develop when you have a naÔve desk layout then you can use the board as a barrier at one end to dissuade through traffic. If you have noisy neighbours you might be able to use it as a baffle too. Just be mindful that any physical barrier you put up radiates information outwards to ensure you donít appear sectioned off and hostile towards collaboration with outsiders.
Like most things these days even the humble whiteboard comes in every form from the simplest to the all-singing, all-dancing, Internet Enabled tm version. Your basic large board on wheels is probably the most common breed sighted in the wild as itís easily moveable, and therefore shareable and large enough to be usable, i.e. hold more than one scribble at a time. Some offices have re-discovered the benefits of such a medium and gone all out and turned every wall into a writeable surface. At one company I worked up you could never find anyone at their desk because they were always at a break-out room or huddled around some random patch of wall chatting and drawing pictures.
For those offices that prefer zero-clutter (which usually means a clean desk policy and nothing on the walls except art or a picture of the CEO) there is the temporary solution Ė drive-by whiteboards. These are rolls of white plastic film which are statically charged and can therefore be hung on most surfaces, e.g. painted walls and windows. They can stay up for a surprisingly long time and also easily be taken down and re-hung elsewhere. Rather than capture their content in another form they are so cheap that you could just keep the original sketches, at least until you know for sure itís worth transcribing them formally elsewhere. Apart from a few surprising surfaces where they donít work the main thing to watch out for is ensuring that you donít disturb some other teamís peace and tranquillity by pitching up on some free window space near them for an ad-hoc design meeting. Whilst you might enjoy attempting to subvert the organisation by getting stuff done, the complaints from the wrong neighbours may perversely strengthen the argument for virtual collaboration.
One of the earliest electronic whiteboards I got to use was essentially a whiteboard with a scanner and printer welded on the side.  Since then the humble board has gotten much smarter, so much so that itís no longer a physical canvas but a virtual one. Now you draw fake lines, boxes, circles and arrows with (coloured) fake pens and create your sketch in the alternate reality. As if that wasnít enough your scribble can be added to your SharePoint archive under the guise of a OneNote document where you can relive this masterpiece time and time again.
Only no one does. In the same way that JIRA brings your product development into the electronic age with a promise of taking away all the fuss and nonsense of shuffling around post-it notes, so the electronic whiteboard comes with similar dreams and aspirations. And yet there is still so much friction to working with computer-based tooling that itís easier to just do it the old fashioned way. Just as the daily stand-up becomes dominated by the time it takes to access the electronic task board on a shared screen, so a quick design meeting becomes bogged down in bizarre networking problems and pens that feel unresponsive.
Donít get me wrong they are very clever pieces of kit and they can do some pretty neat tricks around transcribing text and recognising shapes. For example where you might previously have had to rub out and redraw parts of a diagram on a physical board to make room you can just select an area and shrink or move it about. If you think your database should have been on the left, or drawn in red ink just change it. And if you think your sketch is destined for a greater part in the world then it has tools to clean it up and allow you to pretend that you drew it in Visio all along.
Of course in the meantime whilst some companies have been developing smarter boards, others have been developing smarter apps to help give your physical doodles some permanence. For some, just using the camera software on your phone will be more than enough, whilst others might want to clean it up slightly (e.g. fix the white balance) before emailing or uploading to their teamís Slack channel or wiki. As you might expect there are a number of free apps for modern phones that are optimised for taking photos of whiteboards which helps reduce the friction a little more, e.g. Office Lens. Just bear in mind that it might be quicker to draw it again when the need arises than shave the yak.
Itís easy to get hung up on notation, but donít. Back in the early Ď90s during The Notation Wars the three amigos (Booch, Jackobson & Rumbaugh) called a truce and worked together to product the one notation to rule them all Ė the Unified Modelling Language (UML). Whilst this caters for a whole slew of different diagram types each with its own sets of symbols, youíll rarely need this in practice to sketch out a concept; in fact most of the time you can get away with nothing more than some badly drawn squares and a few arrows.
Being a graphic artist is not a prerequisite for being able to communicate with simple sketches, yes you might have to redraw bits if they go really wonky, but thatís the beauty of a whiteboard Ė rub it off and try again. If youíre drawing some kind of rough architecture diagram and you want to be more adventurous you still only really need three symbols: a rectangle, a tall cylinder (for a database) and a rotated cylinder (for a message queue). You could even throw in a dotted line if you have a need to distinguish more than one relationship. The one thing I do think is important is that every arrow means the same thing Ė donít mix-and-match dependencies with data flows as itís confusing (the arrows usually just point in opposite directions).
A couple of different coloured pens will naturally allow you a little more freedom too, such as when you have namespaces and containers to group things, but as a rule if you find yourself needing lots of different colours (or trying to add hatching to a diagram) youíve probably gone over the top. The main thing to watch out for though is to keep your pens well segregated! When youíre working with both a whiteboard and post-it notes itís all too easy for a permanent marker to infiltrate the whiteboard pen drawer and then youíve got a problem. I think itís worth sticking with well-known brands, e.g. buy Sharpieís for your stickies and Staedtler pens for your whiteboard, as youíll instantly know if itís in the wrong pile. Also once whiteboards become popular again make sure you have a drawer with a seriously heavy-duty lock to keep them and your board rubber safe from those less well stocked in the stationary department.
As with any technical diagram you should really stick to the same level of abstraction throughout, e.g. donít try and mix classes into a high-level architecture sketch. Simon Brown [2] has a really nice concept that he calls C4 which stands for Context, Container, Component and Class. Iíve found this is a useful aide memoire when thinking about what it is I want to draw. The static structure of a system is fairly easy to draw using only rudimentary skills and basic shapes, but when it comes to something like a sequence diagramming the swim-lanes approach of UML is as good a notation as any. UML may be much derided for leading many down the rabbit hole of Big Design Up Front, but the U in UML (unified) does at least mean that should you choose to embrace a richer notation itís one most people should be likely to know.
Although Iíve focused heavily on the more pictorial uses for whiteboards we shouldnít forget that they are more useful than that Ė you can write words on them too. Okay so theyíre not necessarily the best thing for writing lengthy prose, not least due to the unsightly stain youíll probably acquire on the edge of your palm, but thereís nothing wrong with using the board to help you create lists of stuff. Or you could use the top corner to write up a point of focus (aka sprint goal) for the next few days to continuously remind the team about what over-arching business event or theme they should be collectively working towards.
Even though you might be decomposing your work into epics, stories and tasks, there is still a need to flesh out details at the point of implementation. For instance you may have defined some loose conditions of satisfaction [3] at an earlier planning stage, but now that youíre ready to work on the story in earnest it would be useful to lay down a more formal set of acceptance criteria, perhaps with the other 3 amigos (BA, developer and tester). Naturally the board is a good place to work out a list of happy and sad paths that need to be catered for. Or maybe you need to sketch out something around the UI, perhaps the developer and tester need to factor some kind of test API into the design, or someone from ops needs to see how this new feature affects the monitoring of the system. A story is just a placeholder for this conversation.
Whilst index cards are nice for arranging on a desk, they donít stick very well to walls, unlike Post-it notes. Iíve known places though where you arenít allowed to stick Post-it notes on windows and their walls are painted with some kind of anti-sticky-note paint, so the board may have to double up as both a task board and design tool. Personally Iíve always been fonder of arranging things on a vertical surface than horizontal, but Iím sure mileage varies greatly here.
The one thing I never use the board for is writing code. Apart from an interview where Iím being specifically asked to write code on a board, Iíd always do it at a terminal using a tool custom built for the job Ė the text editor.
The humble whiteboard is becoming an endangered species in the corporate world. Itís a sad moment seeing one sat in the corner of an office with an architecture diagram from years ago almost burnt into it because the pen ink has had so long to dry out. Almost every day for a board should be different as people come and go, stopping only briefly to chat, sketch, write, arrange, sip coffee and reflect before moving on. These bursts of activity will be interspersed with periods of serenity, before once again the slate is swiped clean and the hullabaloo of collaboration punctuates the air once again. Whiteboards are for living.
[1] C Vu 25-4, http://www.chrisoldwood.com/articles/in-the-toolbox-pen-and-paper.html
[2] http://www.codingthearchitecture.com/2014/08/24/c4_model_poster.html
[3] http://stackoverflow.com/questions/3697466/can-you-clarify-the-differences-between-conditions-of-satisfaction-cos-and-acc
Chris Oldwood
14 June 2016
Chris is a freelance programmer who started out as a bedroom coder in the 80ís writing assembler on 8-bit micros. These days it's enterprise grade technology in plush corporate offices. He also commentates on the Godmanchester duck race and can be easily distracted via<EMAIL_ADDRESS>or @chrisoldwood.


How to test 2 years of behavior
for 16 70 countries
in 4 minutes... 18 minutes
Giorgio Sironi
Since well-engineered things tend to acts as a center of gravity, the latest data I have on this test suite suggest that it has been greatly expanded from when I had this talk for the first time.
I'm a developer (writes code, design stuff)
Interested in
Automated testing and TDD
Object-oriented programming
Distributed systems
If you are looking at these slides on your pc, press S to see the notes
I built this test infrastructure with (the help of) the Onebip team, where I worked for the last 3 years. Now I work at eLife, a scientific journal that open sources everything they do in the spirit of open access in science.
Context
Onebip is a payment provider that takes money from your SIM card and uses it to pay for digital goods. There are hundreds of mobile phone operators to integrate with. Different people may work on each system. I'm ignoring reporting here and concentrate on the transactional part: what is needed to perform a payment.
What we wanted to do
daily deployment
refactor the hidden legacy code in the core system
deal with moving and complex requirements, always know what's live
Test suites support multiple goals, like safety (I deploy and don't break what was working before), but also change (refactoring with a safety net) and documentation (readability of steps and avoiding writing tens of thousands of lines of test code.
The standard solution
unit
end-to-end
fast
slower
isolated
all-encompassing, covering even legacy
1000s
100s
technical
customer-facing
"A return code of 709143 is FAILED"
"I am billed with the message 'Thank you for your purchase'"
Bicycle toolkit
Cycling
So I'm showing here how to write effective and fast end-to-end tests, but I'm saying at the same time that unit tests are just as important. Just easier to write, so here's some advice on the end-to-end ones.
Introducing simulators
"Just test with the real thing you mockist design-damager!"
A run of the suite when tested with real mobile phone operators (which have no preproduction systems) costs about 500 EUR
Substituting the real APIs of operators. Implementing the Fake pattern.
Simulator API
SimulatedUser::addBilling($phoneNumber, $amount) : boolean
new SimulatedUser($mongoCollection);
It's not as simple as mocking, as simulators need to be backed by an actual database as their code may run in many different processes and servers. Don't make the mistake of going for "as simple as possible" solutions like writing on files as they will get crazy with race conditions.
If you can't test results through the API (need to look into the database directly for results),
you're missing a way to monitor and drive the real system.
Surprise, not only unit test drive design forcing low coupling and cohesion of objects; also end-to-end tests drive the design of a self-sufficient, complete and concurrent API.
Tests are just another client of
Merchant notifications (SUBSCRIPTION_ACTIVATED)
Logs of calls between components
Domain Events raised
"Stop introducing APIs just for testing you mockist design-damager!"
A run of our suite if executed manually by someone would take several weeks to complete. You can test with real databases, but not with real time .
1st try: PHPUnit
1st try: PHPUnit
public function testAIusacellUserWithMoneyCanActivateASubscription($serviceId, ...)
{
$this->given(
$this->withServiceId($serviceId)
->withOperator('Iusacell')
)
->when(
$this->subscribing()
)
->then(
$this->userReceivesBillings($firstBillingMessage)
->forTimes(1)
->merchantIsNotifiedOf('SUBSCRIPTION_ACTIVATED')
->userReceivesBillings($renewalMessage)
->forTimes(3)
);
}
2nd try: Behat
Given I am a US user
When I subscribe to US_BROWSER_GAME
Then I am billed 3.00 USD
Separate automation from specification, which is one thing that Cucumber-style frameworks force you to do. Also you cannot write much data inside Gherkin as it's not a structured format, so you have to select the most relevant, provide sensible defaults and make the job of the users of your system easier by asking them to fill in only what is written here (no 10-page form).
2nd try: Behat
Ah, decoupling. Apparently it works with testing frameworks too.
(potentially you could ship the Client object as an SDK for PHP)
The renewals problem
Given I am a US user
And I have subscribed to US_BROWSER_GAME a week ago
Then I am renewed with a 3.00 USD billing?
Execution time: 168 hours
Time passing is a Command to the system
Given I am a US user
And I have subscribed to US_BROWSER_GAME
When a week has passed
Then I am renewed with a 3.00 USD billing
Business time API
$ curl -X POST 'http://example.com/subscription/42/clock' \
-H 'X-Some-Authentication: ...'
-d 'ticks=168'
{
now: "2014-05-16T09:30:00Z"
}
Needs to be aggregate-specific, in this case impacting a single subscription or a single user. That opens up the possibility of parallelizing later.
The race condition problem
They expose design problems that may become serious bugs in production under large traffic.
When automating a payment flow that lasts tens of seconds to a single scenario of 1 second
Concurrent accesses to the same rows, responses that come too early.
Which may not necessarily being the last commits, a problem can emerge because them produce a difference in timing patterns, or a change in the CI machine
A test suite where 1 test randomly fails is flaky and may not be trusted
Read high level logs to find out which interactions are
(another example of system TDD driving you towards better auditing)
Once found out the problem, reproduce them reliably by inserting sleep() that exacerbate the problem in the right place
Sometimes you need support from people from multiple projects to find out the culprit
The "integrated tests are slow" problem
$ time vendor/bin/behat features/
... much later
real 121m6.114s
If you run the tests serially, one after the other, you can grow a beard before you have a result.
Discovery: our applications support concurrency
The tests can be designed so that they are isolated from each other, following the boundaries of the Aggregates (Domain-Driven Design jargon) in the system. For example, use different randomly-generated phone numbers for each test, and only assert things that happen to that user such as their credit being affected by the payment and their subscription to a magazine being now active.
Also, any test should be able to run no matter what is the state of the database, so that large batches of setup and teardown operation are not necessary.
The code for parallelization
grep -nHR "Scenario:" features/ | sort -t: -k1,1 -k2,2n \
| cut -d ":" -f1,2 | parallel -P 200% --gnu --halt-on-error=0 \
--keep-order "php bin/behat {}"
by @badkill
Concurrency enables parallelism: if the tests are isolated from each other, you can run them in parallel. Specify a fixed process pool in order not to overload the system (here 2 processes per CPU.)
Final results
X countries with 2 years of simulated time, in X minutes
Configuring new countries, merchant and services with confidence
Stop regressions while daily integrating (and deploying) the work of multiple teams and microservices
Living documentation (at least for the developers)
Enabling cleanup of legacy code now covered
Simulating the feasibility of a scenario in minutes
Built a sandbox for integration of merchants where they do not spend real money
We did not concentrate on BDD or on business communication, but started solving our verification problems by selecting good practices coming from experts. They worked and had also positive spillovers such as offering a sandbox.
Interested?
These are good, bullshit-free practical books that teach how to write good test suites which which also have good side-effects on architecture.


| read_eurocordex_data | R Documentation |
search for EURO-CORDEX netCDF files, get the data from the netCDF files and put them into a data.frame
read_eurocordex_data(dir, variable, domain, driver, experiment, ensemble, institute, model, downscaling_realisation, time_frequency, time, stations)
dir |
string: file direcotory |
variable |
string: model variable, see EURO-CORDEX Doc |
domain |
string: model domain, see EURO-CORDEX Doc |
driver |
string: driving global model, see EURO-CORDEX Doc |
experiment |
string: experiment type (historical, rcp2.6, rcp4.5, rcp8.5), see EURO-CORDEX Doc |
ensemble |
string: ensemble (e.g. r12i1p1), see EURO-CORDEX Doc |
institute |
string: institution who did the model run, see EURO-CORDEX Doc |
model |
string: used RCM (regional climate model), see EURO-CORDEX Doc |
downscaling_realisation |
string: version of the downscaling realisation (most often 'v1'), see EURO-CORDEX Doc |
time_frequency |
string: time frequency of model output (e.g. 'day'), see EURO-CORDEX Doc |
stations |
data.frame of three columns station_name, lon, and lat |
time_lim |
string, numeric or integer: array of length 2 containing start and end time to read in format 'YYYYMMDD' (as character, numeric or integer) |
data.frame with first column "time" and last column "time_posix". further columns in between are denoted according to idxStations$station_name; each row contains data of one time step
# define directory that contains the model data dir <- '/my/data/directory/for/EUROCORDEX/data' # define EURO-CORDEX model run details variable <- 'sfcWind' domain <- 'EUR-11' driver <- 'ICHEC-EC-EARTH' experiment <- 'rcp85' ensemble <- 'r12i1p1' institute <- 'CLMcom' model <- 'CCLM4-8-17' downscaling_realisation <- 'v1' time_frequency <- 'day' time <- c('20110201', '20170301') # define stations stations <- data.frame(c('abc', 'def', 'ghi', 'jkl'), c(10.31, 11.12, 9.2, 9.31), c(55.19, 54.77, 55.02, 53.2), c(44, 1, 5, 107), stringsAsFactors = FALSE) names(stations) <- c('station_name', 'lon', 'lat', 'elev') # read in the data my_data <- read_eurocordex_data(dir, variable, domain, driver, experiment, ensemble, institute, model, downscaling_realisation, time_frequency, time, stations)


Http request settings
Url
Method
GET
PUT
POST
DELETE
Parameters
{{p.key}}
Response
Requesting
{{result.status}} - {{result.statusText}}
{{result.data | json}}


|
Standard Reference Data Program |
Data Gateway |
Chemistry WebBook |
|
Go To: Top, Constants of diatomic molecules, References, Notes / Error Report
Data compilation copyright by the U.S. Secretary of Commerce on behalf of the U.S.A. All rights reserved.
Data evaluated as indicated in comments:
HL - E.P. Hunter and S.G. Lias
Data compiled as indicated in comments:
B - J.E. Bartmess
LLK - S.G. Lias, R.D. Levin, and S.A. Kafafi
| Quantity | Value | Units | Method | Reference | Comment |
|---|---|---|---|---|---|
| Proton affinity (review) | 1021.7 | kJ/mol | N/A | Hunter and Lias, 1998 | HL |
| Quantity | Value | Units | Method | Reference | Comment |
| Gas basicity | 996.4 | kJ/mol | N/A | Hunter and Lias, 1998 | HL |
| EA (eV) | Method | Reference | Comment |
|---|---|---|---|
| 0.342 ± 0.012 | LPES | Sarkas, Hendricks, et al., 1994 | B |
| IE (eV) | Method | Reference | Comment |
|---|---|---|---|
| 7.9 ± 0.3 | EI | N/A | LLK |
| Quantity | Value | Units | Method | Reference | Comment |
|---|---|---|---|---|---|
| ΔrH° | 1489.5 ± 0.42 | kJ/mol | D-EA | Haeffler, Hanstorp, et al., 1996 | gas phase; Given: 0.618049(20) eV; B |
| Quantity | Value | Units | Method | Reference | Comment |
| ΔrG° | 1468.2 ± 1.3 | kJ/mol | H-TS | Haeffler, Hanstorp, et al., 1996 | gas phase; Given: 0.618049(20) eV; B |
Go To: Top, Gas phase ion energetics data, References, Notes / Error Report
Data compilation copyright by the U.S. Secretary of Commerce on behalf of the U.S.A. All rights reserved.
Data compiled by: K.P. Huber and G. Herzberg
| State | Te | ωe | ωexe | ωeye | Be | αe | γe | De | βe | re | Trans. | ν00 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| For ab initio calculations of X 1Σ, A 1Σ, B 1Π, a 3Σ, b 3Π (lowest stable triplet state at ~1700 cm-1 below B 1Π see Docken and Hinze, 1972. Excitation energies and oscillator strengths for higher-lying states have been computed by Stewart, Watson, et al., 1975. The most recent ground state studies are those of Meyer and Rosmus, 1975 and Yardley and Balint-Kurti, 1976, the latter including other low-lying 1Σ+ states. | ||||||||||||
| B 1Π | 34912 | [130.73] Z | 1 | 3.383 2 3 | 0.986 | -0.045 | [2.6E-3] 4 | 2.378 | B ← X R | 34312.26 Z | ||
| missing citation | ||||||||||||
| A 1Σ+ | 26516 | [280.96] 5 Z | [2.8536] 5 3 | [1.187E-3] 5 | 2.605 | A ↔ X 6 7 R | 25943.13 Z | |||||
| Crawford and Jorgensen, 1935 | ||||||||||||
| X 1Σ+ | 0 | 1405.65 Z | 23.20 | 0.163 | 7.5131 3 | 0.2132 8 | 0.00075 | 0.8617E-3 9 | -0.0160E-3 | 1.5957 10 | ||
| Klemperer, 1955; Norris and Klemperer, 1958; James, Norris, et al., 1960 | ||||||||||||
| Mol. beam electric 11 | ||||||||||||
| Wharton, Gold, et al., 1960; Rothstein, 1969; Freeman, Jacobson, et al., 1975 | ||||||||||||
| and magn. Reson. | ||||||||||||
| Lawrence, Anderson, et al., 1963 |
| 1 | ΔG(3/2) = 45.9. |
| 2 | Predissociation by rotation; breaking off above J'= 8,5,2 in v' = 0,1,2, respectively; see also Way and Stwalley, 1973. Dissociation limit at 34492.5 cm-1 above X 1Σ, v"=0, J"=0. |
| 3 | RKR potential curves Fallon, Vanderslice, et al., 1960; Singh and Jain, 1962[A state]; Way and Stwalley, 1973 [B state combination with long-range tail and exponential inner wall]. |
| 4 | D1 = 4.8E-3; H0 = -1.7E-5, H1 = -5.6E-5. |
| 5 | ΔG(v+1/2), Bv, Dv, Hv have been determined up to v=14. The ΔG and Bv curve have maxima for v=9 and 3, respectively; ωe ~ 235, ωexe ~ -28, ωeye ~ -4; Be ~ 2.819, αe ~ -0.078, γe ~ -0.026 and higher order constants. |
| 6 | Radiative lifetimes τ(v',J'): τ(2,3) = 29.4 ns, τ(5,3) = 30.5 ns, τ(7,12) ~ 36.9 ns Dagdigian, 1976; τ(5,5-15) = 31 ns Wine and Melton, 1976. |
| 7 | Intensity distribution in the v'-0 bands Fernandez-Florez and Velasco, 1969; RKR Franck-Condon factors Halmann and Laulicht, 1967. The A-X system of 6LiH was analyzed by Velasco and Rivero, 1974. |
| 8 | All rotational constants are from v = 0,1,2 only. |
| 9 | See 8. Hv = 11.4E-8 - ... |
| 10 | Rot.-vibr. sp. |
| 11 | μel(v=0,1,2) = 5.8820, 5.9905, 6.098 D Wharton, Gold, et al., 1960, Rothstein, 1969. Hyperfine structure constants Wharton, Gold, et al., 1960, Rothstein, 1969, Freeman, Jacobson, et al., 1975. Zeeman spectrum Freeman, Jacobson, et al., 1975, gJ(v=0,J=1) = -0.65842 Freeman, Jacobson, et al., 1975 in agreement with an earlier less precise value obtained by Lawrence, Anderson, et al., 1963, using the magnetic resonance method. For a combination of both theoretical Docken and Hinze, 1972, and experimental results see Docken and Freeman, 1974. |
| 12 | From the predissociation in B 1Π; the evaluation by Way and Stwalley, 1973 takes into account the long-range potential of this state. |
Go To: Top, Gas phase ion energetics data, Constants of diatomic molecules, Notes / Error Report
Data compilation copyright by the U.S. Secretary of Commerce on behalf of the U.S.A. All rights reserved.
Hunter and Lias, 1998
Hunter, E.P.; Lias, S.G.,
Evaluated Gas Phase Basicities and Proton Affinities of Molecules: An Update,
J. Phys. Chem. Ref. Data, 1998, 27, 3, 413-656. [doi:10.1063/1.556018]
[all data]
Sarkas, Hendricks, et al., 1994
Sarkas, H.W.; Hendricks, J.H.; Arnold, S.T.; Bowen, K.H.,
Photoelectron Spectroscopy of Lithium Hydride Anion,
J. Chem. Phys., 1994, 100, 1884. [all data]
Haeffler, Hanstorp, et al., 1996
Haeffler, G.; Hanstorp, G.; Kiyan, I.; Klinkm|ller, A.E.; Ljungblad, U.; Pegg, D.J.,
Electron affinity of Li: A state-selective measurement,
Phys. Rev. A, 1996, 53, 4127-4131. [all data]
Docken and Hinze, 1972
Docken, K.K.; Hinze, J.,
LiH potential curves and wavefunctions for X1Σ+, A1Σ+, B1Π, 3Σ+, and 3Π,
J. Chem. Phys., 1972, 57, 4928. [all data]
Stewart, Watson, et al., 1975
Stewart, R.F.; Watson, D.K.; Dalgarno, A.,
Variational time-dependent Hartree-Fock calculations. I. Applications to four-electron atomic and molecular systems,
J. Chem. Phys., 1975, 63, 3222. [all data]
Meyer and Rosmus, 1975
Meyer, W.; Rosmus, P.,
PNO-Cl and CEPA studies of electron correlation effects. III. Spectroscopic constants and dipole moment functions for the ground states of the first-row and second-row diatomic hydrides,
J. Chem. Phys., 1975, 63, 2356. [all data]
Yardley and Balint-Kurti, 1976
Yardley, R.N.; Balint-Kurti, G.G.,
Ab initio valence-bond calculations on HF, LiH, LiH+ and LiF,
Mol. Phys., 1976, 31, 921. [all data]
Crawford and Jorgensen, 1935
Crawford, F.H.; Jorgensen, T., Jr.,

The molecular Zeeman and hyperfine spectra of LiH and LiD by molecular beam high resolution electric resonance,
J. Chem. Phys., 1975, 63, 2597. [all data]
Lawrence, Anderson, et al., 1963
Lawrence, T.R.; Anderson, C.H.; Ramsey, N.F.,
Rotational magnetic moments of lithium hydride and deuteride,
Phys. Rev., 1963, 130, 1865. [all data]
Way and Stwalley, 1973
Way, K.R.; Stwalley, W.C.,
Accurate dissociation energies from rotational predissociation and long-range forces: B1Π LiH,
J. Chem. Phys., 1973, 59, 5298. [all data]
Fallon, Vanderslice, et al., 1960
Fallon, R.J.; Vanderslice, J.T.; Mason, E.A.,
Erratum: Potential curves for HF and LiH,
J. Chem. Phys., 1960, 33, 944. [all data]
Singh and Jain, 1962
Singh, N.L.; Jain, D.C.,
The Rydberg-Klein-Rees method of constructing the true potential energy curves of diatomic molecules,
Proc. Phys. Soc. London, 1962, 79, 274. [all data]
Dagdigian, 1976
Dagdigian, P.J.,
Detection of LiH and NaH molecular beams by laser fluorescence and measurement of radiative lifetimes of the A1Σ+ state,
J. Chem. Phys., 1976, 64, 2609. [all data]
Wine and Melton, 1976
Wine, P.H.; Melton, L.A.,
Radiative lifetime of LiH A1Σ+,
J. Chem. Phys., 1976, 64, 2692. [all data]
Fernandez-Florez and Velasco, 1969
Fernandez-Florez, I.; Velasco, R.,
Contribucion al estudio de la molecula LiH: distribucion de intensidades en el sistema A-X,
Opt. Pura Apl., 1969, 2, 123. [all data]
Halmann and Laulicht, 1967
Halmann, M.; Laulicht, I.,
Isotope effects on Franck-Condon factors. VII. Vibrational intensity distribution in the H2 Lyman, H2 Werner, O2 Schumann-Runge, N2 first positive, N2 Vegard-Kaplan, and LiH (A-X) systems based on PKR potentials,
J. Chem. Phys., 1967, 46, 2684. [all data]
Velasco and Rivero, 1974
Velasco, R.; Rivero, F.,
Espectro de absorcion de la molecula 6LiH,
Opt. Pura Apl., 1974, 7, 45. [all data]
Docken and Freeman, 1974
Docken, K.K.; Freeman, R.R.,
Some molecular properties of LiH and LiD,
J. Chem. Phys., 1974, 61, 4217. [all data]
Go To: Top, Gas phase ion energetics data, Constants of diatomic molecules, References
| EA | Electron affinity |
| ΔrG° | Free energy of reaction at standard conditions |
| ΔrH° | Enthalpy of reaction at standard conditions |
Copyright for NIST Standard Reference Data is governed by the Standard Reference Data Act.
|
Standard Reference Data Program |
Data Gateway |
Chemistry WebBook |
If you have comments or questions about this site, please contact us.


Business name:
Business Info:
City:
Why do you need this money:
How much money do you need?
$10
$100
$1000
$10000


A full fledged event designed on the lines of the United Nations, Veltech university, Avadi is hosting its first edition of it's Model United Nations. A complete day of active debating and public speaking, the event is aimed to be pinnacle of communication and social events ever held in this University. Students from all over the university, including foreign students, are going to participate as delegates. Starting from General Assembly meeting to individual committee meets, delegates will be allotted their countries, committees and topics. From hosting training workshops to the valedictory speech, the delegates would be adequately armed with the knowledge of the functioning of the United Nations. They will get equipped with the experience to participate in similar events outside the university.


Access History
This page shows the activities of using your personally identifiable information for web access. Note that it records the submission of your information by clicking 'submit' button or whatever. Other activities are not logged here.
| Time Stamp |
Site |
Used Information |
Type |
|


| Home | Trees | Indices | Help |
|
|---|
|
|
object --+ | named._Named --+ | named._NamedBase --+ | UtmUpsBase
(INTERNAL) Base class for Utm and Ups coordinates.
| Instance Methods | |||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
Inherited from Inherited from Inherited from |
| Properties | |
|
convergence DEPRECATED, use property gamma .
|
|
|
datum Class property with retrievable name.
|
|
|
easting Get the easting ( meter ).
|
|
|
eastingnorthing Get easting and northing (EasNor2Tuple (easting, northing) ).
|
|
|
falsed Get easting and northing falsed ( bool ).
|
|
|
falsed2 (INTERNAL) Must be overloaded, see function notOverloaded .
|
|
|
gamma Get the meridian convergence ( degrees ) or
None if not available.
|
|
|
hemisphere Get the hemisphere ( str , 'N'|'S').
|
|
|
northing Get the northing ( meter ).
|
|
|
scale Get the grid scale ( float ) or None .
|
|
|
scale0 Get the central scale factor ( float ).
|
|
|
Inherited from Inherited from |
| Method Details |
(INTERNAL) New UtmUpsBase.
|
Default
|
Default
|
Return easting and northing, falsed or unfalsed.
|
DEPRECATED, use method
|
Determine the EPSG (European Petroleum Survey Group) code. |
Convert this UTM/UPS coordinate to an MGRS grid reference.
See Also: Function pygeodesy.toMgrs in module mgrs for more details. Note:
If not specified, the latitudinal |
| Property Details |
convergenceDEPRECATED, use property
|
datumClass
|
eastingGet the easting (
|
eastingnorthingGet easting and northing (EasNor2Tuple
|
falsedGet easting and northing falsed (
|
falsed2(INTERNAL) Must be overloaded, see function
|
gammaGet the meridian convergence (
|
hemisphereGet the hemisphere (
|
northingGet the northing (
|
scaleGet the grid scale (
|
scale0Get the central scale factor (
|
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sun Aug 20 14:42:12 2023 | http://epydoc.sourceforge.net |


Press ESC to quit this game
Player One:
Press → to Move to the Right
Press ← to Move to the Left
Press ↑ to Move to the Up
Press ↓ to Move to the Down
Press 'ALT' to Drop a Bomb
Player Two:
Press 'D' to Move to the Right
Press 'A' to Move to the Left
Press 'W' to Move to the Up
Press 'S' to Move to the Down
Press 'CAPS' to Drop a Bomb


module Bytes:sig
..end
We enhanced OCaml standard Bytes
module with the expected set
of functions. Bytes
are not Regular
, as Regular
interface
itself refers to bytes. However it includes a pretty big subset
of regular (excluding Std.Data
module, but bytes indeed do not need
any specific support for the serialization).
typet =
Std.Bytes.t
include Container.S0
include Blit.S
include Identifiable.S
module To_string:Blit.S_distinct
with type src := t
with type dst := string
module From_string:Blit.S_distinct
with type src := string
with type dst := t
val create : int -> t
create n
returns a new byte sequence of length n
. The
sequence is uninitialized and contains arbitrary bytes.
Raise Invalid_argument
if n < 0
or n >
Sys.max_string_length
.val make : int -> char -> t
make n c
returns a new byte sequence of length n
, filled with
the byte c
.
Raise Invalid_argument
if n < 0
or n >
Sys.max_string_length
.val init : int -> f:(int -> char) -> t
init n ~f
returns a fresh byte sequence of length n
, with
character i
initialized to the result of f i
(in increasing
index order).
Raise Invalid_argument
if n < 0
or n >
Sys.max_string_length
.val empty : t
empty
a byte sequence of size 0.val length : t -> int
length t
returns the length (number of bytes) of t
.val get : t -> int -> char
get s n
returns the byte at index n
in s
.
Raise Invalid_argument
if n
not a valid index in s
.val set : t -> int -> char -> unit
set s n c
modifies s
in place, replacing the byte at index n
with c
.
Raise Invalid_argument
if n
is not a valid index in s
.val copy : t -> t
copy t
returns a new byte sequence that contains the same
bytes as t
.val of_string : string -> t
of_string s
returns a new byte sequence that contains the
same bytes as the given string.val to_string : t -> string
to_string t
returns a new string that contains the same
bytes as the given byte sequence.val extend : t -> int -> int -> t
extend s left right
returns a new byte sequence that contains
the bytes of s
, with left
uninitialized bytes prepended and
right
uninitialized bytes appended to it. If left
or right
is negative, then bytes are removed (instead of appended) from
the corresponding side of s
.
Raise Invalid_argument
if the result length is negative or
longer than Sys.max_string_length
bytes.val fill : t -> int -> int -> char -> unit
fill s start len c
modifies s
in place, replacing len
characters with c
, starting at start
.
Raise Invalid_argument
if start
and len
do not designate a
valid range of s
.val concat : t -> t list -> t
concat sep sl
concatenates the list of byte sequences sl
,
inserting the separator byte sequence sep
between each, and
returns the result as a new byte sequence.
Raise Invalid_argument
if the result is longer than
Sys.max_string_length
bytes.val cat : t -> t -> t
cat s1 s2
concatenates s1
and s2
and returns the result
as new byte sequence.
Raise Invalid_argument
if the result is longer than
Sys.max_string_length
bytes.val iteri : t -> f:(int -> char -> unit) -> unit
iteri t ~f
same as iter
, but the function is
applied to the index of the byte as first argument and the
byte itself as second argument.val map : t -> f:(char -> char) -> t
map s ~f
applies function f
in turn to all the bytes of s
(in increasing index order) and stores the resulting bytes in
a new sequence that is returned as the result.val mapi : t -> f:(int -> char -> char) -> t
mapi s ~f
calls f
with each character of s
and its
index (in increasing index order) and stores the resulting bytes
in a new sequence that is returned as the result.val trim : t -> t
trim t
returns a copy of t
, without leading and trailing
whitespace. The bytes regarded as whitespace are the ASCII
characters ' '
, '\012'
, '\n'
, '\r'
, and '\t'
.val escaped : t -> t
escaped t
returns a copy of t
, with special characters
represented by escape sequences, following the lexical
conventions of OCaml.
Raise Invalid_argument
if the result is longer than
Sys.max_string_length
bytes.val index : t -> char -> int
index s c
returns the index of the first occurrence of byte c
in s
.
Raise Not_found
if c
does not occur in s
.val rindex : t -> char -> int
rindex s c
returns the index of the last occurrence of byte c
in s
.
Raise Not_found
if c
does not occur in s
.val index_from : t -> int -> char -> int
index_from s i c
returns the index of the first occurrence of
byte c
in s
after position i
. index s c
is
equivalent to index_from s 0 c
.
Raise Invalid_argument
if i
is not a valid position in s
.
Raise Not_found
if c
does not occur in s
after position i
.val rindex_from : t -> int -> char -> int
rindex_from s i c
returns the index of the last occurrence of
byte c
in s
before position i+1
. rindex s c
is equivalent
to rindex_from s (length s - 1) c
.
Raise Invalid_argument
if i+1
is not a valid position in s
.
Raise Not_found
if c
does not occur in s
before position i+1
.val contains : t -> char -> bool
contains s c
tests if byte c
appears in s
.val contains_from : t -> int -> char -> bool
contains_from s start c
tests if byte c
appears in s
after
position start
. contains s c
is equivalent to contains_from
s 0 c
.
Raise Invalid_argument
if start
is not a valid position in s
.val rcontains_from : t -> int -> char -> bool
rcontains_from s stop c
tests if byte c
appears in s
before
position stop+1
.
Raise Invalid_argument
if stop < 0
or stop+1
is not a valid
position in s
.val uppercase : t -> t
uppercase t
returns a copy of t
, with all lowercase letters
translated to uppercase, including accented letters of the ISO
Latin-1 (8859-1) character set.val lowercase : t -> t
lowercase t
returns a copy of t
, with all uppercase letters
translated to lowercase, including accented letters of the ISO
Latin-1 (8859-1) character set.val capitalize : t -> t
capitalize t
returns a copy of t
, with the first byte set
to uppercase.val uncapitalize : t -> t
uncapitalize t
returns a copy of t
, with the first byte set
to lowercase.module Unsafe:sig
..end


[§634F-3] Relationship to other laws. Nothing in this chapter shall limit or preclude any rights the moving party may have under any other constitutional, statutory, case or common law, or rule provisions. [L 2002, c 187,pt of §2]


Discover
interesting
things
No matter where you go, Let us help you find exciting things you will love.
Sign up
Log in
Not ready to Sign Up? Explore the app.