Possibly more important than how an Interaction is visually displayed is what role that Interaction should play within your UI. That role depends in part on what children the Interaction contains. What the Interaction does with those children is determined by the
GenInteractionType
of that object. Interactions of different visibility may function in essentially the same manner, but Interactions of different types may differ greatly in their functionality.
For example, if an Interaction contains a GenItemGroup with three GenItem children, it will not affect the basic functionality if that Interaction is built as a dialog, popup, or sub-group. Each item will still perform its default function (such as sending a message). The GII _type of Interaction might affect that functionality, however, by forcing the Items to send out their messages as a group or individually (for example in a GIT_PROPERTIES Interaction).
You should pick the
GenInteractionType
based on what actions you wish to perform on the children you select for the Interaction. By default, an Interaction is of type GIT_ORGANIZATIONAL. In some cases, the functionality you need will reside entirely with the children; in those cases, a GIT_ORGANIZATIONAL will most likely suffice.
Certain
GenInteractionType
Interactions, if built as GIV_DIALOG, may create a reply bar with
standard
response
triggers
. A reply bar is a special area of a dialog Interaction to place commands for user responses. Standard response triggers perform additional actions for dialog Interactions, apart from any functionality your application provides. You do not need to add these triggers yourself; they are added by the Specific UI.
Standard response triggers perform one of several pre-defined
InteractionCommand
commands. Depending on the particular type of Interaction, each
command may perform different actions. An
InteractionCommand
is a special data type that the Specific UI recognizes. The Specific UI decides what action to take upon receiving this command; depending on the value of the
InteractionCommand
, the Specific UI may perform several different actions.
For example, the GIT_NOTIFICATION type, if built as a dialog box, may create an "OK" trigger automatically. The trigger will become one of the dialog box's children. This trigger sends out the
InteractionCommand
IC_OK when activated. The Specific UI will also decide how to implement that IC_OK message. (In OSF/Motif, for example, IC_OK will dismiss the dialog box as one of its actions.)
You can create your own response triggers within an Interaction. You can also replace any standard response trigger by supplying one of your own. For complete information on how
InteractionCommand
s and response triggers work, see Interaction Commands
.
An organizational interaction is the simplest type of interaction. It is also the default
GenInteractionType
. An organizational Interaction only functions to contain objects--without indicating any meaning to the makeup of those objects. Because of this, a GIT_ORGANIZATIONAL Interaction should not interpret any
InteractionCommand
types. See Interaction Commands
.
GIT_ORGANIZATIONAL
Interactions are only used, therefore, to group their children; there is never any implied meaning to the children they contain. The Interaction may have a certain visual form defined in its
GenInteractionVisibility
field, but presumably the Interaction should perform its activity under any visible arrangement.
You will most often need an organizational Interaction to arrange objects within another window, whether that "window" is a GenPrimary or a GIV_DIALOG GenInteraction. For example, you may need organizational Interactions solely to arrange a group of generic children in a horizontal or vertical row. There are several hints in
GenClass
that may affect the visual implementation of an organizational Interaction. See the Managing UI Geometry chapterfor full details.
Organizational Interactions may appear as sub-groups, menus, or dialog boxes; each of its items should already contain all the functionality needed. For example, an edit menu (GIV_POPUP Interaction) with three triggers (Cut, Copy, and Paste) could be organizational if each of those triggers is capable of performing its action purely through the sending of a message (a function of
GenTriggerClass
).
No standard response triggers are provided with a GIT_ORGANIZATIONAL Interaction, even if it is built as a dialog box, though you may supply your own. See Standard Response Triggers .
Code Display 7-7 Organizational Interactions
/* This properties dialog box will group a collection of GIT_ORGANIZATIONAL * Interactions. */
@object GenInteractionClass MyMasterInteraction = { GI_comp = FirstOrganizational, SecondOrganizational; GII_visibility = GIV_DIALOG; GII_type = GIT_PROPERTIES; }
@object GenInteractionClass FirstOrganizational = { /* GenInteractions are GIT_ORGANIZATIONAL by default. */ GI_comp = One, Two, Three; }
@object GenInteractionClass SecondOrganizational = { GI_comp = Four, Five, Six; }
@object GenTriggerClass One = { /* This trigger, after sending out MY_SPECIAL_MESSAGE to the process, will send a * MSG_GEN_GUP_INTERACTION_COMMAND with IC_INTERACTION_COMPLETE to the first * non-GIT_ORGANIZATIONAL Interaction it encounters up the tree * (MyMasterInteraction). This behavior is due to the GenAttribute * GA_SIGNAL_INTERACTION_COMPLETE. (See GenClass.) */
GTI_actionMsg = MY_SPECIAL_MESSAGE; GTI_destination = process; GI_attrs = GA_SIGNAL_INTERACTION_COMPLETE; }
GIT_PROPERTIES Interactions allow the Interaction to display and set attributes of a specific selected object (the "current selection"). In many cases, this current selection will be the target of the application. (See the Input chapter.) Users can change the UI gadgets in the properties group to change the attributes of the selected object. When the user selects a different object, the UI gadgetry changes to reflect the attributes of the new selection.
For example, a properties dialog may alter text properties within a text editor. If some text is selected, changing properties in the text dialog will change the appearance of the text.
Properties Interactions may appear as sub-groups, popups, or dialog boxes. If a properties Interaction takes the form of a dialog box, the Specific UI may create response triggers with the
InteractionCommand
types IC_APPLY, IC_RESET and IC_DISMISS. These triggers will either apply changes made in the properties group, reset those changes to their initial state, or close the dialog, respectively. In OSF/Motif these triggers are labeled "Apply" or "OK," "Reset," and "Close" or "Cancel."
Code Display 7-8 GenInteraction as Properties Dialog Box
@object GenInteractionClass MyInteraction = { GI_visMoniker = "Dialog Box"; GI_comp = PropertiesList; GII_visibility = GIV_DIALOG; GII_type = GIT_PROPERTIES; }
/* The GenItemGroup below is a list of three properties. */
@object GenItemGroupClass PropertiesList = { GI_visMoniker = "Properties List"; GI_comp = @PropOne, @PropTwo, @PropThree; GIGI_behaviorType = GIGBT_NON_EXCLUSIVE; }
@object GenItemClass PropOne = { GI_visMoniker = "A"; GII_identifier = 1; }
@object GenItemClass PropTwo = { GI_visMoniker = "B"; GII_identifier = 2; }
@object GenItemClass PropThree = { GI_visMoniker = "C"; GII_identifier = 3; }
There are two ways that an application can deal with UI gadgetry in a property dialog. Either the application can work completely off the state change notification messages sent by the UI gadgetry when the properties are changed, or the application may need to do some extra work after the properties are changed. This extra work can include checking for valid settings in the UI gadgetry, querying the UI gadgetry for their states, or dealing with the UI gadgetry as a group rather than individually (i.e. fetching each of their states and using them all at once to make a single change instead of making separate changes for each state).
Properties dialogs work in one of two modes: immediate and delayed. In immediate mode, the UI gadgetry within a properties box reflects the actual state of those objects. Changing selections within the properties Interaction changes the state of those objects immediately. For example, if a "Fonts" dialog box containing a list of font selections is in immediate mode, selecting each separate font will cause the selected text to immediately display itself in the selected font.
In delayed mode, the UI gadgetry within the properties box reflects a separate "user" state rather than the actual state. The user is free to change settings within the properties Interaction without causing such changes to be made on the object immediately. The UI does this by storing two states for the UI gadgetry: the actual state (which reflects the current state of the objects) and a user state (which reflects the state specified in the dialog box). The user can apply changes made within a delayed mode properties Interaction with use of an "Apply" mechanism. Usually, the Specific UI will provide an "Apply" trigger for such a case.
If either the Specific UI or hints determine that the properties dialog box should be run in delayed mode, an apply trigger will be supplied. In OSF/Motif, an "Apply" trigger will be placed in a reply bar along with a "Close" trigger that dismisses the property box.
The GIT_PROPERTIES type and GIV_DIALOG visibility indicate to the Specific UI to build a property dialog box. The Specific UI will also determine whether this box should run in immediate or delayed mode. Because the application works completely through its UI gadgets within the dialog, it will support either mode. However, there are good reasons for wanting the properties to work in one mode or another. You can supply additional hints for this purpose.
These hints only affect the behavior of properties dialog boxes (GIV_DIALOG). Therefore, if an Interaction is a GIV_POPUP or GIV_SUB_GROUP, these hints will have no effect. If the Interaction is a GIV_CONTROL_GROUP or GIV_NO_PREFERENCE, these hints may force the object to appear as a dialog box.
HINT_INTERACTION_COMPLEX_PROPERTIES
indicates that the properties dialog box contains complex properties and therefore a means to reset the properties to their initial state should be supplied if available. In OSF/Motif, for example, a "Reset" response trigger is supplied.
HINT_INTERACTION_SIMPLE_PROPERTIES
indicates that the properties dialog box contains simple properties and therefore a means to reset the properties to their initial state is probably unneeded.
HINT_INTERACTION_RELATED_PROPERTIES
indicates that the properties dialog contains properties that are closely related. Therefore, the specific UI should run the objects as a group in delayed mode and provide an "Apply" trigger. This might be useful if you set several graphics area properties (such as color, texture, and dithering) and only wish to send out the changes after the final selection has been made for all the properties.
HINT_INTERACTION_UNRELATED_PROPERTIES
indicates that the properties dialog contains unrelated properties that may be set individually. Therefore, the Interaction can be run in immediate mode and no "Apply" trigger is needed.
HINT_INTERACTION_SLOW_RESPONSE_PROPERTIES
indicates that the properties dialog contains properties that may take a long time to be reflected in the state of the object. The specific UI may create an "Apply" trigger operating in delayed mode so that the user can set these attributes all at once.
HINT_INTERACTION_FAST_RESPONSE_PROPERTIES
indicates that this properties dialog contains properties in which changes can be quickly reflected. The Interaction will be run in immediate mode without any "Apply" and "Reset" triggers.
HINT_INTERACTION_REQUIRES_VALIDATION
If an application needs to do additional work on a properties dialog box, such as validation of the attributes, you should define a "custom" properties dialog box. You can do this by replacing the default "Apply" and "Reset" triggers with ones of your own design.
HINT_INTERACTION_REQUIRES_VALIDATION
indicates that this properties dialog should prompt the user for verification before implementing changes to the properties group. The Interaction will thus be implemented in delayed mode while also allowing a custom "Apply" trigger. The trigger action should be handled in the normal fashion to add any additional functionality to validate before proceeding with the apply.
You can modify the standard IC_APPLY trigger by adding your own apply trigger with ATTR_GEN_TRIGGER_INTERACTION_COMMAND set to IC_APPLY. This trigger will replace the default IC_APPLY trigger that the Specific UI would have supplied otherwise.
HINT_SEEK_REPLY_BAR
places the trigger in the property dialog's reply bar. In the GenInteraction itself, you might want to include
HINT_INTERACTION_REQUIRES_VALIDATION
or another more appropriate hint to ensure that the properties dialog will be working in delayed mode.
An application-supplied trigger allows the application to define whatever action output and method it desires. When the user activates this trigger, the action message will be sent out to the action output (as usual for GenTriggers); the default IC_APPLY functionality will not be performed. In the handler for this custom message, the application can do whatever is necessary with the properties dialog (such as validation of the attributes).
When finished, the application can either manually fetch the state of the attributes or send
MSG_GEN_GUP_INTERACTION_COMMAND
with IC_APPLY to the GenInteraction. (This is the default behavior of an IC_APPLY
InteractionCommand
.) You may choose not to send out this message if you wish to replace instead of supplement the default behavior.
Finally, you can send
MSG_GEN_GUP_INTERACTION_COMMAND
with IC_INTERACTION_COMPLETE to notify the GenInteraction that the user has finished a single usage of the Interaction. (You may also mark such a trigger with GA_SIGNAL_INTERACTION_COMPLETE.) Upon this notification, the specific UI will decide if the GenInteraction should be dismissed. Instead, you may send IC_DISMISS to unconditionally dismiss the Interaction.
Code Display 7-9 Replacing the Default IC_APPLY Trigger
@object GenInteraction LineProperties = { GI_visMoniker = "Line Properties"; GI_comp = LineWidth, LineStyle, LinePropertiesApply; GII_type = GIT_PROPERTIES; GII_visibility = GIV_DIALOG; HINT_INTERACTION_REQUIRES_VALIDATION; /* Forces delayed mode. */ }
@object GenItemGroupClass LineWidth = { /* ... */ }
@object GenItemGroupClass LineStyle = { /* ... */ }
@object GenTriggerClass LinePropertiesApply = { GTI_destination = process; GTI_actionMsg = MSG_MY_PROCESS_PROPERTIES_APPLY; /* Setting GA_SIGNAL_INTERACTION_COMPLETE will dismiss the dialog * after applying the properties. */ GI_attrs = @default | GA_SIGNAL_INTERACTION_COMPLETE; /* Setting this attribute to IC_APPLY tells the specific UI to replace * the standard response trigger with this one. */
ATTR_GEN_TRIGGER_INTERACTION_COMMAND = { IC_APPLY }; HINT_SEEK_REPLY_BAR; }
The moniker for an application-supplied apply trigger may be set by the application or (preferably) left blank so that the Specific UI can provide an appropriate moniker. The Specific UI uses the IC_APPLY data in the
ATTR_GEN_TRIGGER_INTERACTION_COMMAND
vardata and any properties hints to determine what moniker to use. (In OSF/Motif this is either "Apply" or "OK.")
If the application wants to alter a moniker but does not need to do any other work, the trigger's output fields should be left blank. Because the trigger has
ATTR_GEN_TRIGGER_INTERACTION_COMMAND
, if the output fields are null, the trigger will send
MSG_GEN_GUP_INTERACTION_COMMAND
with the
ATTR_GEN_TRIGGER_INTERACTION_COMMAND
data to itself. This message will travel up to the appropriate properties GenInteraction where it will be handled, as usual. If doing this, you should make sure to mark any replacement triggers GA_SIGNAL_INTERACTION_COMPLETE so that the Specific UI can determine whether to dismiss the dialog or not when the trigger is activated. (See Replacing the Default IC_APPLY moniker
.)
Code Display 7-10 Replacing the Default IC_APPLY moniker
@object GenTriggerClass LinePropertiesApply = { GI_visMoniker = "Set Line Properties"; GI_attrs = @default | GA_SIGNAL_INTERACTION_COMPLETE; ATTR_GEN_TRIGGER_INTERACTION_COMMAND = { IC_APPLY }; HINT_SEEK_REPLY_BAR; }
An alternate way to supplement an apply trigger's default behavior is to subclass
GenInteractionClass
and intercept
MSG_GEN_GUP_INTERACTION_COMMAND
. If the
InteractionCommand
sent is IC_APPLY, the application's supplemental apply work may then be done. Then call the superclass to finish with the default apply behavior.
Note that this method cannot be used to override the default GA_SIGNAL_INTERACTION_COMPLETE behavior as that is done separately with
MSG_GEN_GUP_INTERACTION_COMMAND
and IC_INTERACTION_COMPLETE.
For either default or custom properties dialogs, if the properties dialog contains a large number of attributes, it may be useful to provide a means to reset the properties to their former state. This is often done with a hint such as
HINT_INTERACTION_COMPLEX_PROPERTIES
.
Just as you may use ATTR_GEN_TRIGGER_INTERACTION_COMMAND with IC_APPLY to provide a custom apply trigger, you may use ATTR_GEN_TRIGGER_INTERACTION_COMMAND with IC_RESET to provide a custom reset trigger. This is useful if the application needs to do some additional work when the user resets the attributes or if the application wishes to override the default reset moniker ("Reset" in OSF/Motif). You may still perform the default reset behavior (sending
MSG_GEN_RESET
to the UI objects) by sending
MSG_GEN_GUP_INTERACTION_COMMAND
with IC_RESET to the properties Interaction.
GIT_COMMAND Interactions allow the user to set up parameters for and issue commands. For example, a "rename file" command in a file manager application needs to request the new name for the file from the user. This can be done with a command dialog that shows the file's current name and has a text entry field for the file's new name. A reply bar with a "Rename" action trigger could be provided to initiate the rename action when the user has finished entering the new name.
Command Interactions can appear as menus, dialogs, or sub-groups within a larger window. If the Interaction is displayed as a dialog, the specific UI may provide a response trigger with the IC_DISMISS
InteractionCommand
that closes the dialog without executing any commands. In OSF/Motif, this trigger is labeled "Close" or "Cancel." You should supply your own additional command triggers yourself. You may also add custom response triggers with
ATTR_GEN_TRIGGER_INTERACTION_COMMAND
set to a custom
InteractionCommand
Command dialogs provide applications with a place to group related commands. They also provide a convenient place to locate UI gadgetry needed to set up parameters used by commands. A command dialog usually contains one or more command triggers in the dialog reply bar. The Specific UI will usually create a trigger to close the dialog box (with IC_DISMISS) but will not supply any command triggers; you must set up any command triggers or custom response triggers yourself.
Code Display 7-11 Using a Command Dialog Box
/* The Command Dialog created below contains one command trigger (RenameTrigger) * which sends MSG_MY_PROCESS_RENAME to the process object. */
@object GenInteractionClass RenameBox = { GI_visMoniker = "Rename"; GI_comp = @RenameSource, @RenameDest, @RenameTrigger; GII_type = GIT_COMMAND; GII_visibility = GIV_DIALOG; }
@object GenTextClass RenameSource = { /* Single-line text entry object */ }
@object GenTextClass RenameDest = { /* Single-line text entry object */ }
@object GenTriggerClass RenameTrigger = { GI_visMoniker = "Rename"; GTI_destination = process; GTI_actionMsg = MSG_MY_PROCESS_RENAME; GI_attrs = @default | GA_SIGNAL_INTERACTION_COMPLETE; HINT_SEEK_REPLY_BAR; }
The Rename trigger in the above example is marked
HINT_SEEK_REPLY_BAR
to place it in the reply bar of the Interaction, though this is not necessary. The GA_SIGNAL_INTERACTION_COMPLETE attribute on the command trigger indicates that when the user activates this trigger, their use of the dialog is complete and the Specific UI may dismiss the dialog, if it desires. By default, non-modal command dialogs in OSF/Motif are not dismissed. You may use hints to override this behavior.
You may wish to modify this closing behavior, however. For example, if the user chooses an invalid destination name, you might not want to close that dialog; instead, the dialog should remain up and the user should be alerted that he has chosen an incorrect destination. In this case, you should remove the GA_SIGNAL_INTERACTION_COMPLETE attribute from the trigger. You should then handle the closing behavior, after validating the destination, in the
MSG_MY_PROCESS_RENAME
handler. To dismiss the command dialog, send
MSG_GEN_GUP_INTERACTION_COMMAND
with IC_DISMISS to it. (You may also use IC_INTERACTION_COMPLETE if you wish to defer to the Specific UI whether to close the dialog box.)
The Specific UI will also create a standard response trigger to dismiss the command dialog box. If some action needs to take place when the user attempts to close this dialog box, you should replace the default Close trigger by adding your own trigger to replace the IC_DISMISS
InteractionCommand
. As with IC_APPLY and IC_RESET, use
ATTR_GEN_TRIGGER_INTERACTION_COMMAND
with IC_DISMISS to replace the default trigger. You should also mark this trigger
HINT_SEEK_REPLY_BAR
if you wish it to appear in the Interaction's reply bar.
Code Display 7-12 Replacing the Default Close Trigger
@object GenInteractionClass RenameBox = { GI_visMoniker = "Rename"; GI_comp = RenameSource, RenameDest, RenameTrigger, RenameClose; GII_type = GIT_COMMAND; GII_visibility = GIV_DIALOG; }
@object GenTextClass RenameSource = { /* Single-line text entry object */ }
@object GenTextClass RenameDest = { /* Single-line text entry object */ }
@object GenTriggerClass RenameTrigger = { GI_visMoniker = "Rename"; GTI_destination = process; GTI_actionMsg = MSG_MY_PROCESS_RENAME; GI_attrs = @default | GA_SIGNAL_INTERACTION_COMPLETE; HINT_SEEK_REPLY_BAR; }
@object GenTriggerClass RenameClose = { GTI_destination = process; GTI_actionMsg = MSG_MY_PROCESS_CLOSE_RENAME; ATTR_GEN_TRIGGER_INTERACTION_COMMAND = { IC_DISMISS }; HINT_SEEK_REPLY_BAR; }
GIT_PROGRESS Interactions report the progress of an operation. You will need progress dialogs most often to show the status of an ongoing operation. Progress Interactions may appear as either a dialog or as part of a larger window. (Typically progress reports should not appear within a popup, as popups will not remain on-screen.)
If a progress Interaction takes the form of a dialog box, the Specific UI may create a response trigger with the
InteractionCommand
IC_STOP. This trigger will halt the operation (and therefore the progress report) and may close the dialog box if the Specific UI or the application desires this. In OSF/Motif this trigger is labeled "Stop." The Specific UI will not supply a default way to close the dialog other than this IC_STOP trigger. In OSF/Motif this means that a system menu for a non-modal progress dialog will have its "Close" trigger disabled.
For example, you can use a progress dialog to report the progress of a disk format. Gadgets within the progress dialog might reflect the current state of the disk format (for example, a bar indicating the time-percentage of the operation completed). A "Stop" trigger in the reply bar allows the user to abort the disk format. Your application should intercept the
InteractionCommand
IC_STOP in this case so that you can perform any actions required in the halting operation.
A progress dialog may be either modal or non-modal, depending on the application and the operation in progress. The
GenInteractionType
GIT_PROGRESS is designed for cases where the application supports stopping an in-progress operation.
While the Specific UI will supply an IC_STOP trigger in the reply bar for halting the on-going operation, the trigger by itself does nothing. You must either replace this IC_STOP trigger with one that performs the required halting operation, or you must provide a subclass of GenInteraction to intercept
MSG_GEN_GUP_INTERACTION_COMMAND
with IC_STOP. Providing a replacement IC_STOP trigger is the easiest method.
Code Display 7-13 Replacing the Default IC_STOP Trigger
/* This Progress Dialog shows the progress of a data transfer. Its first child * shows the number of packets sent in the operation, and the second child is an * IC_STOP trigger to halt the transfer operation. */
@object GenInteractionClass FileTransferProgress = { GI_visMoniker = "File Transfer Status"; GI_comp = FileTransferPktCount, FileTransferStop; GII_visibility = GIV_DIALOG; GII_type = GIT_PROGRESS; }
/* The GenText object shows the title "Packets Sent" and updates the GTI_text field * with the current number of packets sent. */
@object GenTextClass FileTransferPktCount = { GI_visMoniker = "Packets sent:"; GTXI_text = "0"; }
/* When the user activates the "Abort File Transfer" trigger, the trigger sends out * MSG_MY_PROCESS_ABORT_FILE_TRANSFER to the process. This action should also * close the dialog box. Since this trigger may initiate a destructive action, * HINT_TRIGGER_DESTRUCTIVE_ACTION makes sure that the focus does not lie on the * dialog box (and therefore the trigger cannot be activated by a default * activation method such as hitting RETURN). */
@object GenTriggerClass FileTransferStop = { GI_visMoniker = "Abort File Transfer"; /* OSF/Motif will dismiss this dialog box if marked * GA_SIGNAL_INTERACTION_COMPLETE because it is GIT_PROGRESS. */ GI_attrs = @default | GA_SIGNAL_INTERACTION_COMPLETE; GTI_destination = process; /* The handler for MSG_MY_PROCESS_ABORT_FILE_TRANSFER must stop the * operation. You may also dismiss the dialog at that time. */ GTI_actionMsg = MSG_MY_PROCESS_ABORT_FILE_TRANSFER; ATTR_GEN_TRIGGER_INTERACTION_COMMAND = { IC_STOP }; HINT_SEEK_REPLY_BAR; HINT_TRIGGER_DESTRUCTIVE_ACTION; /* Don't place focus here. */ }
GIT_NOTIFICATION Interactions allow your application to send notices to the user. You should use a notification Interaction when you wish to notify the user of an event without needing to prompt the user for further information.
GIT_NOTIFICATION interactions normally appear as dialogs. If so, the Specific UI will create a response trigger with the
InteractionCommand
IC_OK. This command will close the dialog box in most Specific UIs. In OSF/Motif, this trigger is labeled "OK." The Specific UI will not supply a way to close the dialog without responding with this trigger. In OSF/Motif, this means that the system menu in a non-modal notification dialog will have its "Close" trigger disabled.
A notification Interaction may in theory be of any visibility, but it usually takes the form of a modal dialog box. Therefore, the user should only need to acknowledge the dialog box (usually by activating the "OK" trigger).
You will usually require a notification dialog when you need to let the user know that something has occurred that may or may not require his immediate attention. For example, a notification dialog would be appropriate to notify the user that new e-mail has arrived; a notification dialog would also be appropriate to notify the user that an error has occurred.
Notifications that require immediate attention should be marked GIA_MODAL or
HINT_INTERACTION_MODAL
, depending on the application's dependence on their modality. Interactions that do not require immediate attention may be marked
HINT_INTERACTION_NO_DISTURB
so that when brought up, they do not disturb the focus or target of the application. This is especially useful for cases such as e-mail notification, where switching the focus away from another application at each new notice might become irritating to the user.
Code Display 7-14 An E-mail Notification Dialog
/* The Notification dialog is marked HINT_INTERACTION_NO_DISTURB so that it * will not grab the focus and target. The notification itself has only one child: * the text to display to the user. The Specific UI will also create an IC_OK * trigger that is used to acknowledge and dismiss the notification. */
@object GenInteractionClass NewMailNotice = { GI_visMoniker = "Mailbox"; GI_comp = NewMailText; GII_type = GIT_NOTIFICATION; GII_visibility = GIV_DIALOG; HINT_INTERACTION_NO_DISTURB; }
@object GenGlyphClass NewMailText = { GI_visMoniker = "New mail has arrived"; }
By default the IC_OK trigger will just dismiss the dialog. If some other action might need to be taken when the user acknowledges the notification, you should provide a custom IC_OK trigger to replace the specific UI supplied one.
Code Display 7-15 Replacing the IC_OK Trigger
/* This Notification dialog now contains two explicit children: the text to * display to the user and a custom trigger to acknowledge the notification. */
@object GenInteractionClass NewMailNotice = { GI_visMoniker = "Mailbox"; GI_comp = NewMailText, NewMailAcknowledge; GII_type = GIT_NOTIFICATION; GII_visibility = GIV_DIALOG; HINT_INTERACTION_NO_DISTURB; }
@object GenGlyphClass NewMailText = { GI_visMoniker = "New mail has arrived"; }
/* When the user clicks on the Acknowledge Trigger, MSG_MY_PROCESS_NEW_MAIL_ACK is * sent to the process class. Marking the trigger as IC_OK replaces the default * trigger. Note that the Specific UI is still allowed to pick the visual moniker * for this trigger as its GI_visMoniker field is left blank. */
@object GenTriggerClass NewMailAcknowledge = { GTI_destination = process; GTI_actionMsg = MSG_MY_PROCESS_NEW_MAIL_ACK; GI_attrs = @default | GA_SIGNAL_INTERACTION_COMPLETE; ATTR_GEN_TRIGGER_INTERACTION_COMMAND = { IC_OK }; HINT_SEEK_REPLY_BAR; }
GIT_AFFIRMATION Interactions allow your application to provide the user with a choice of yes or no. GIT_AFFIRMATIONs normally appear as dialog boxes. If so, the Specific UI will create response triggers with the commands IC_YES and IC_NO. In OSF/Motif, the triggers are labeled "Yes" and "No." The Specific UI will not provide a default manner to close the dialog without responding to one of these. In OSF/Motif, this means that non-modal dialog boxes will have their "Close" triggers disabled.
For example, your application may need to prompt the user with a yes or no question (such as "Do you want to continue?"). Depending on the value returned in the
InteractionCommand
, the dialog box may continue or abort any impending operations. In most cases, you will want to use an affirmation interaction when you wish to force the user to make a choice.
An affirmation dialog allows the user to make a single yes or no choice, without an option to ignore the choice and close the dialog. In general, this type of dialog is normally modal or used with
UserDoDialog()
to block the calling thread until the user responds. When the user chooses, the caller will be unblocked and
UserDoDialog()
will return IC_YES or IC_NO. Alternatively, you can supply replacement IC_YES or IC_NO (or both) triggers which send out custom messages when activated.
Code Display 7-16 An Affirmation Dialog for Deleting a File
/* Rather than using UserDoDialog(), this dialog is simply marked GIA_MODAL. * This approach has the advantage of allowing any views that are run by the * process thread to be updated if they are exposed by the application. */
/* This dialog keeps the default IC_NO trigger to dismiss the dialog but * replaces the default IC_YES trigger. */
@object GenInteractionClass DeleteAffirmation = { GI_comp = DeleteAffirmationText, DeleteAffirmationYes; GII_type = GIT_AFFIRMATION; GII_visibility = GIV_DIALOG; GII_attrs = @default | GIA_MODAL; }
@object GenGlyphClass DeleteAffirmationText = { GI_visMoniker = "Are you sure you want to delete this file?"; }
/* This trigger replaces the default IC_YES trigger. */
@object GenTriggerClass DeleteAffirmationYes = { GI_attrs = @default | GA_SIGNAL_INTERACTION_COMPLETE; GTI_destination = process; GTI_actionMsg = MSG_MY_PROCESS_DELETE_FILE; ATTR_GEN_TRIGGER_INTERACTION_COMMAND = {IC_YES}; HINT_SEEK_REPLY_BAR; }
GIT_MULTIPLE_RESPONSE Interactions allow the UI to provide the user with a number of choices, one of which must be selected. GIT_MULTIPLE_RESPONSE Interactions normally appear as dialog boxes. The Specific UI itself supplies no standard response triggers; you must add your own response triggers. (See Standard Response Triggers .) There is no default provision to just close or cancel the dialog, ignoring the choice. In OSF/Motif, this means the system menu for a non-modal dialog will have its "Close" trigger disabled.
The GIT_MULTIPLE_RESPONSE type allows you to build a custom dialog box. By default, a multiple-response dialog provides no standard response triggers and no way to close the dialog. You must therefore provide any response triggers you might need (including an IC_DISMISS
InteractionCommand
). If not, the dialog will only be dismissable by the application, not by the user. In general, you should use a GIT_MULTIPLE_RESPONSE when you wish to prompt the user with several choices, one of which must be chosen.
Code Display 7-17 A Fragmentation Warning Dialog Box
@object GenInteractionClass DatabaseFragmentWarning = { GI_comp = DBFragmentText, DBFragmentCompact, DBFragmentContinue; GII_type = GIT_MULTIPLE_RESPONSE; GII_visibility = GIV_DIALOG; GII_attrs = @default | GIA_MODAL; }
@object GenGlyphClass DBFragmentText = { GI_visMoniker = "Database is getting fragmented." }
/* As none of the following triggers are standard trigger replacements, there is no * need to use ATTR_GEN_TRIGGER_INTERACTION_COMMAND. */
@object GenTriggerClass DBFragmentCompact = { GI_visMoniker = "Run Compaction utility."; GTI_destination = process; GTI_actionMsg = MSG_MY_PROCESS_DB_COMPACT; GI_attrs = @default | GA_SIGNAL_INTERACTION_COMPLETE; HINT_SEEK_REPLY_BAR; }
@object GenTriggerClass DBFragmentContinue = { GI_visMoniker = "Continue without Compacting."; GTI_destination = process; GTI_actionMsg = MSG_MY_PROCESS_DB_CONTINUE; GI_attrs = @default | GA_SIGNAL_INTERACTION_COMPLETE; HINT_SEEK_REPLY_BAR; }
Toolboxes are useful to display small icons for commonly used operations. Toolboxes are normally provided by controllers. (See the Generic UI Controllers chapter.) In many cases toolboxes are non-modal GIT_ORGANIZATIONAL dialog boxes. Any GenInteraction may be marked HINT_TOOLBOX
, however. (In some cases, you may wish a toolbox to be GIT_MULTIPLE_RESPONSE.) GeoDraw provides a toolbox to alter the properties of graphics objects. This toolbox appears at appropriate times in the GeoDraw application and will remain on-screen until the user explicitly closes it by selecting "Close" in its system menu.
Toolbox dialogs should never steal the focus or target of the application; this prevents the user from constantly having to reselect current objects. The hint
HINT_TOOLBOX
provides this functionality.
This hint prevents a toolbox Interaction from grabbing the focus whenever an object within the toolbox is activated.


Title
[Administration]
[Add]
service description
No items yet
Javascript Libraries
Javascript Libraries


In this article we look at some of the best books you can buy to aid you in learning web development
@Elliot_f
25th January, 2020


{% extends "layout.html" %} {% block body %} {# FORM TO UPDATE PROCESS DETAILS #} {% for process in process_table %} {#loop ends at end of template!#}


Domain Expertise
Our domain expertise include the following:
- Computational Mechanics
- Condensed Matter Systems
- Continuum Mechanics
- Crystal Plasticity
- Data Visualization
- Deformation Mechanisms
- Electrochemistry
- Electron Microscopy
- Fiber Composites
- Finite Element Methods
- Freeze casting
- Fuel Cells
- High performance computing
- Image Processing
- Material Knowledge System
- Mathematical Physics
- MATLAB
- Mechanics of Materials
- Microstructure Analytics
- Multi-scale mechanical testing
- Multi-scale modeling
- Nanoindentation
- Software Design
- Thermal Mechanical Processing
- Thin films
- Viscoelasticity


This is an overview page of various ways to test the Launchpaddy app during development.Choose one of the options below to launch the app in the WebIDE preview.


An error has occurred: = error ?>.
You may close this tab.
Signed in! You may close this tab.
Sign in failed. You may close this tab.


{% extends "home/basesite.html" %} {% block body %}
{{ response.0.total }} of {{ responsesCount }} who voted chose {{ response.1.avaliableAnswersText }}


ar65 is a replacement for the libr65 archiver that was part of the cc65 C compiler suite developed by John R. Dunning. libr65 had some problems and the copyright does not permit some things which I wanted to be possible, so I decided to write a completely new assembler/linker/archiver suite for the cc65 compiler. ar65 is part of this suite.
The archiver is called as follows:
Usage: ar65 <operation ...> lib file|module ...
Operations are some of:
r Add modules
d Delete modules
t List library table
v Increase verbosity (put before other operation)
x Extract modules
V Print the archiver version
You may add modules to a library using the `r' command (`a' is deprecated). If the library does not exist, it is created (and a warning message is printed which you may ignore if creation of the library was your intention). You may specify any number of modules on the command line following the library.
If a module with the same name exists in the library, it is replaced by the new one. The archiver prints a warning, if the module in the library has a newer timestamp than the one to add.
Here's an example:
ar65 r mysubs.lib sub1.o sub2.o
This will add two modules to the library `mysubs.lib' creating the library if necessary. If the library contains modules named sub1.o or sub2.o, they are replaced by the new ones.
Modules names in the library are stored without the path, so, using
ar65 v v r mysubs.lib ofiles/sub1.o ofiles/sub2.o
will verbose add two modules named `sub1.o' and `sub2.o' to the library.
Deleting modules from a library is done with the `d' command. You may not give a path when naming the modules.
Example:
ar65 d mysubs.lib sub1.o
This will delete the module named `sub1.o' from the library, printing an error if the library does not contain that module.
The `t' command prints a table of all modules in the library (`l' is deprecated). Any module names on the command line are ignored.
Example:
ar65 tv mysubs.lib
Using the `x' command, you may extract modules from the library. The modules named on the command line are extracted from the library and put into the current directory.
Note: Because of the indexing done by the archiver, the modules may have a changed binary layout, that is, a binary compare with the old module (before importing it into the library) may yield differences. The extracted modules are accepted by the linker and archiver, however, so this is not a problem.
Example for extracting a module from the library:
ar65 x mysubs.lib sub1.o
The `V' command prints the version number of the assembler. If you send any suggestions or bugfixes, please include your version number.
In addition to these operations, the archiver will check for, and warn about duplicate external symbols in the library, every time when an operation does update the library. This is only a warning, the linker will ignore one of the duplicate symbols (which one is unspecified).
ar65 (and all cc65 binutils) are (C) Copyright 1998-2000 Ullrich von Bassewitz. For usage of the binaries and/or sources the following conditions do apply:
This software is provided 'as-is', without any expressed or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:


Contact Us
- Want to talk to a person?
-
Qref prides ourselves on top-notch customer service. To prove it, we've set up a special phone line and email for you to talk to someone if you need help with this app and can't find your answer below.
(888) 660-QREF
We will get back to you within 24 hours.
Getting Started
- No checklist yet?
-
No problem. Qref checklists are but a tap away. Purchase and download the checklist you need directly from the app. Tap Download to view a list of available aircraft models. This list is being added to regularly, so check back if you don't see the checklist you need.
- I purchased a checklist, but don't see it in the dashboard.
-
Sometimes, if an in-app purchase doesn't go through for some reason, simply download the checklist again. Both we and Apple keep track of your purchases. If you weren't charged for it the first time, you will be prompted to buy it. If you were charged, you'll be able to download it again at no additional cost. This is also the case if you remove your checklist from the dashboard.
- Can I edit a checklist?
-
Absolutely! From the checklist, tap the pencil icon at the top of the page to turn on/off edit mode.
Qref Account
- Why do I need a Qref account?
-
Setting up a Qref account allows for automatic backup of your changes and allows syncing across devices.
Please note that your Qref Checklist app account is separate from any other account, including a qref.com account. At this time, you can only access your checklists from an app.
Editing
- How do I edit the aircraft tail number on the dashboard?
-
On the dashboard, tap the pencil icon at the top of the page to turn on edit mode. Tap on the desired aircraft and you will be prompted for the tail number.
The tail number will be synced with your account the next time you log in or select Manual Sync from the menu. This means you'll see the tail number (and any checklist edits) on any device you log in with using the Qref app.
- How do I remove a checklist from the Dashboard?
-
On the dashboard, tap the pencil icon at the top of the page to turn on edit mode. Swipe the checklist you'd like to remove, then tap "Delete". If you want to add this checklist back, you can by simply downloading it again. You will not be charged for it again. Promise! One thing to keep in mind, though... your edits will be gone if you remove the checklist from the dashboard.
- How do I reset a checklist to the original download?
-
If you have edited a checklist and want to revert back to the original version, simply remove the checklist from the Dashboard (see above), go to Downloads, and download the checklist again. Because we keep track of your purchases, you won't be charged for it again.
Syncing
- Syncing between two or more devices
-
Syncing your edited checklists between multiple devices is easy. Your Qref account links your app to a cloud server that maintains a backup of all of your checklists, including any edits.
Syncing can be done 2 ways.
- Immediately after editing: When you are done editing on the first device, tap the pencil icon at the top of the page to turn off edit mode. Tap "Sync Now" to send the changes you made to the Qref cloud server. There, they will be available for another device to sync to.
- Manually: At any time, you can manually sync your checklists and any edits made to the cloud server. To do this, tap the menu icon , then tap "Manual Sync" . If the checklist on your device is newer than on the server, it is sent to the server. Otherwise, if the checklist on the server is newer than your local version, the local version is replaced with server version.
Once the changes are sync'd, you can update any other devices by performing a manual sync as described above. The newer checklist on the server will replace the older checklist on your other devices.
Note: in order to sync across multiple devices, all devices must be signed in to the same account.
Multiple, Duplicate Checklists
- Can I dupliacte a checklist?
-
Yes, and easily so. If you would like two different versions of the same checklist, simply download the checklist again. Once you have purchased a checklist, you will not be charged for another download. Tap "Download" at the bottom of the Dashboard and find the model you've already purchased. Tap on it, and then tap "Install". This will install another version of the checklist which you can access from the Dashboard. A new, random tail number will be assigned so you can tell the two apart.
Note: The new, second checklist will contain the default checklist data and will not include any edits made to the first version.


|
||||||||||
| PREV NEXT | FRAMES NO FRAMES |
| Packages that use ConnectionPool | |
|---|---|
| org.apache.tomcat.jdbc.pool | |
| org.apache.tomcat.jdbc.pool.interceptor | |
| org.apache.tomcat.jdbc.pool.jmx |
| Uses of ConnectionPool in org.apache.tomcat.jdbc.pool |
|---|
| Fields in org.apache.tomcat.jdbc.pool declared as ConnectionPool | |
|---|---|
protected ConnectionPool |
PooledConnection.parent
The parent |
protected ConnectionPool |
DataSourceProxy.pool
|
protected ConnectionPool |
ProxyConnection.pool
|
| Fields in org.apache.tomcat.jdbc.pool with type parameters of type ConnectionPool | |
|---|---|
protected java.lang.ref.WeakReference<ConnectionPool> |
ConnectionPool.PoolCleaner.pool
|
| Methods in org.apache.tomcat.jdbc.pool that return ConnectionPool | |
|---|---|
ConnectionPool |
DataSourceProxy.createPool()
Sets up the connection pool, by creating a pooling driver. |
ConnectionPool |
ProxyConnection.getParentPool()
|
ConnectionPool |
DataSourceProxy.getPool()
|
ConnectionPool |
ProxyConnection.getPool()
|
private ConnectionPool |
DataSourceProxy.pCreatePool()
Sets up the connection pool, by creating a pooling driver. |
| Methods in org.apache.tomcat.jdbc.pool with parameters of type ConnectionPool | |
|---|---|
void |
JdbcInterceptor.disconnected(ConnectionPool parent,
PooledConnection con,
boolean finalizing)
Called when Connection.close() is called on the underlying connection. |
void |
JdbcInterceptor.poolClosed(ConnectionPool pool)
This method is invoked by a connection pool when the pool is closed. |
void |
JdbcInterceptor.poolStarted(ConnectionPool pool)
This method is invoked by a connection pool when the pool is first started up, usually when the first connection is requested. |
abstract void |
JdbcInterceptor.reset(ConnectionPool parent,
PooledConnection con)
Gets called each time the connection is borrowed from the pool This means that if an interceptor holds a reference to the connection the interceptor can be reused for another connection. |
void |
TrapException.reset(ConnectionPool parent,
PooledConnection con)
no-op for this interceptor. |
void |
DisposableConnectionFacade.reset(ConnectionPool parent,
PooledConnection con)
|
void |
ProxyConnection.reset(ConnectionPool parent,
PooledConnection con)
|
void |
ProxyConnection.setPool(ConnectionPool pool)
|
| Constructors in org.apache.tomcat.jdbc.pool with parameters of type ConnectionPool | |
|---|---|
ConnectionPool.PoolCleaner(ConnectionPool pool,
long sleepTime)
|
|
PooledConnection(PoolConfiguration prop,
ConnectionPool parent)
Constructor |
|
ProxyConnection(ConnectionPool parent,
PooledConnection con,
boolean useEquals)
|
| Uses of ConnectionPool in org.apache.tomcat.jdbc.pool.interceptor |
|---|
| Fields in org.apache.tomcat.jdbc.pool.interceptor declared as ConnectionPool | |
|---|---|
protected ConnectionPool |
SlowQueryReportJmx.pool
|
| Fields in org.apache.tomcat.jdbc.pool.interceptor with type parameters of type ConnectionPool | |
|---|---|
private static java.util.concurrent.ConcurrentHashMap<ConnectionPool,java.util.concurrent.atomic.AtomicInteger> |
StatementCache.cacheSizeMap
|
| Methods in org.apache.tomcat.jdbc.pool.interceptor with parameters of type ConnectionPool | |
|---|---|
void |
StatementCache.disconnected(ConnectionPool parent,
PooledConnection con,
boolean finalizing)
|
void |
ConnectionState.disconnected(ConnectionPool parent,
PooledConnection con,
boolean finalizing)
|
void |
StatementCache.poolClosed(ConnectionPool pool)
|
void |
SlowQueryReportJmx.poolClosed(ConnectionPool pool)
|
void |
SlowQueryReport.poolClosed(ConnectionPool pool)
|
void |
StatementCache.poolStarted(ConnectionPool pool)
|
void |
SlowQueryReportJmx.poolStarted(ConnectionPool pool)
|
void |
SlowQueryReport.poolStarted(ConnectionPool pool)
|
void |
StatementFinalizer.reset(ConnectionPool parent,
PooledConnection con)
|
void |
StatementCache.reset(ConnectionPool parent,
PooledConnection con)
|
void |
AbstractCreateStatementInterceptor.reset(ConnectionPool parent,
PooledConnection con)
no-op for this interceptor. |
void |
ConnectionState.reset(ConnectionPool parent,
PooledConnection con)
|
void |
SlowQueryReportJmx.reset(ConnectionPool parent,
PooledConnection con)
|
void |
SlowQueryReport.reset(ConnectionPool parent,
PooledConnection con)
|
| Uses of ConnectionPool in org.apache.tomcat.jdbc.pool.jmx |
|---|
| Fields in org.apache.tomcat.jdbc.pool.jmx declared as ConnectionPool | |
|---|---|
protected ConnectionPool |
ConnectionPool.pool
the connection pool |
| Methods in org.apache.tomcat.jdbc.pool.jmx that return ConnectionPool | |
|---|---|
ConnectionPool |
ConnectionPool.getPool()
|
| Constructors in org.apache.tomcat.jdbc.pool.jmx with parameters of type ConnectionPool | |
|---|---|
ConnectionPool(ConnectionPool pool)
|
|
||||||||||
| PREV NEXT | FRAMES NO FRAMES |


Sunny 16 Rule

In photography, the sunny 16 rule (also known as the sunny f/16 rule) is a method of estimating correct daylight exposures without a light meter. (For lunar photography there is a similar rule known as the looney 11 rule.) Apart from the obvious advantage of independence from a light meter, the sunny 16 rule can also aid in achieving correct exposure of difficult subjects. As the rule is based on incident light, rather than reflected light as with most camera light meters, very bright or very dark subjects are compensated for. The rule serves as a mnemonic for the camera settings obtained on a sunny day using the exposure value (EV) system.
An elaborated form of the sunny 16 rule is to set shutter speed nearest to the reciprocal of the ISO film speed / setting and f-number according to this table
| Lighting conditions | Aperture | ISO* | Shutter Speed* | Shadow detail |
|---|---|---|---|---|
| Snow/sand | f/22 | 100 | 1/125 | Dark with sharp edges |
| Sunny | f/16 | 100 | 1/125 | Distinct |
| Slight overcast | f/11 | 100 | 1/125 | Soft around edges |
| Overcast | f/8 | 100 | 1/125 | Barely visible |
| Heavy overcast | f/5.6 | 100 | 1/125 | No shadows |
| Open shade/sunset | f/4 | 100 | 1/125 | No shadows |
| Backlighting | Add one stop | 100 | 1/125 | n/a |
*You can set ISO, but you'll change Shutter Speed nearby 1/ISO too. Ex : ISO = 200, you'll set Shutter Speed = 1/250(nearby ISO). ISO = 400, you'll set Shutter Speed = 1/500(nearby ISO).


Earlier we gave several examples of pattern matching in defining functions---for example length and fringe. In this section we will look at the pattern-matching process in greater detail (§3.17). (Pattern matching in Haskell is different from that found in logic programming languages such as Prolog; in particular, it can be viewed as "one-way" matching, whereas Prolog allows "two-way" matching (via unification), along with implicit backtracking in its evaluation mechanism.)
Patterns are not "first-class;" there is only a fixed set of
different kinds of patterns. We have already seen several examples of
data constructor patterns; both length and fringe defined
earlier use such patterns, the former on the constructors of a
"built-in" type (lists), the latter on a user-defined type (Tree).
Indeed, matching is permitted using the constructors of any type,
user-defined or not. This includes tuples, strings, numbers,
characters, etc. For example, here's a contrived function that
matches against a tuple of "constants:"
contrived :: ([a], Char, (Int, Float), String, Bool) -> Bool
contrived ([], 'b', (1, 2.0), "hi", True) = False
This example also demonstrates that nesting of patterns is
permitted (to arbitrary depth).
Technically speaking, formal parameters (The Report calls these variables.) are also patterns---it's just that they never fail to match a value. As a "side effect" of the successful match, the formal parameter is bound to the value it is being matched against. For this reason patterns in any one equation are not allowed to have more than one occurrence of the same formal parameter (a property called linearity §3.17, §3.3, §4.4.3).
Patterns such as formal parameters that never fail to match are said to be irrefutable, in contrast to refutable patterns which may fail to match. The pattern used in the contrived example above is refutable. There are three other kinds of irrefutable patterns, two of which we will introduce now (the other we will delay until Section 4.4).
So far we have discussed how individual patterns are matched, how some are refutable, some are irrefutable, etc. But what drives the overall process? In what order are the matches attempted? What if none succeeds? This section addresses these questions.
Pattern matching can either fail, succeed or diverge. A successful match binds the formal parameters in the pattern. Divergence occurs when a value needed by the pattern contains an error (_|_). The matching process itself occurs "top-down, left-to-right." Failure of a pattern anywhere in one equation results in failure of the whole equation, and the next equation is then tried. If all equations fail, the value of the function application is _|_, and results in a run-time error.
For example, if [1,2] is matched against [0,bot], then 1 fails to match 0, so the result is a failed match. (Recall that bot, defined earlier, is a variable bound to _|_.) But if [1,2] is matched against [bot,0], then matching 1 against bot causes divergence (i.e. _|_).
The other twist to this set of rules is that top-level patterns
may also have a boolean guard, as in this definition of a
function that forms an abstract version of a number's sign:
sign x | x > 0 = 1
| x == 0 = 0
| x < 0 = -1
Note that a sequence of guards may be provided for the same pattern;
as with patterns, they are evaluated top-down, and the first that
evaluates to True results in a successful match.
The pattern-matching rules can have subtle effects on the meaning of
functions. For example, consider this definition of take:
take 0 _ = []
take _ [] = []
take n (x:xs) = x : take (n-1) xs
and this slightly different version (the first 2 equations have been
reversed):
take1 _ [] = []
take1 0 _ = []
take1 n (x:xs) = x : take1 (n-1) xs
Now note the following:
| take 0 bot | => | [] |
| take1 0 bot | => | _|_ |
| take bot [] | => | _|_ |
| take1 bot [] | => | [] |
We see that take is "more defined" with respect to its second argument, whereas take1 is more defined with respect to its first. It is difficult to say in this case which definition is better. Just remember that in certain applications, it may make a difference. (The Standard Prelude includes a definition corresponding to take.)
Pattern matching provides a way to "dispatch control" based on structural properties of a value. In many circumstances we don't wish to define a function every time we need to do this, but so far we have only shown how to do pattern matching in function definitions. Haskell's case expression provides a way to solve this problem. Indeed, the meaning of pattern matching in function definitions is specified in the Report in terms of case expressions, which are considered more primitive. In particular, a function definition of the form:
| f p11 ... p1k = e1 |
| ... |
| f pn1 ... pnk = en |
where each pij is a pattern, is semantically equivalent to:
f x1 x2 ... xk = case (x1, ..., xk) of
| (p11, ..., p1k) -> e1 |
| ... |
| (pn1, ..., pnk) -> en |
where the xi are new identifiers. (For a more general translation
that includes guards, see §4.4.3.) For example, the
definition of take given earlier is equivalent to:
take m ys = case (m,ys) of
(0,_) -> []
(_,[]) -> []
(n,x:xs) -> x : take (n-1) xs
A point not made earlier is that, for type correctness, the types of the right-hand sides of a case expression or set of equations comprising a function definition must all be the same; more precisely, they must all share a common principal type.
The pattern-matching rules for case expressions are the same as we have given for function definitions, so there is really nothing new to learn here, other than to note the convenience that case expressions offer. Indeed, there's one use of a case expression that is so common that it has special syntax: the conditional expression. In Haskell, conditional expressions have the familiar form:
if e1 then e2 else e3
which is really short-hand for:
| case e1 of | True -> e2 |
| False -> e3 |
From this expansion it should be clear that e1 must have type Bool, and e2 and e3 must have the same (but otherwise arbitrary) type. In other words, if-then-else when viewed as a function has type Bool->a->a->a.
There is one other kind of pattern allowed in Haskell. It is called a lazy pattern, and has the form ~pat. Lazy patterns are irrefutable: matching a value v against ~pat always succeeds, regardless of pat. Operationally speaking, if an identifier in pat is later "used" on the right-hand-side, it will be bound to that portion of the value that would result if v were to successfully match pat, and _|_ otherwise.
Lazy patterns are useful in contexts where infinite data structures are being defined recursively. For example, infinite lists are an excellent vehicle for writing simulation programs, and in this context the infinite lists are often called streams. Consider the simple case of simulating the interactions between a server process server and a client process client, where client sends a sequence of requests to server, and server replies to each request with some kind of response. This situation is shown pictorially in Figure 2. (Note that client also takes an initial message as argument.)
Let us further assume that the structure of the server and client look
something like this:
client init (resp:resps) = init : client (next resp) resps
server (req:reqs) = process req : server reqs
where we assume that next is a function that, given a response from
the server, determines the next request, and process is a function
that processes a request from the client, returning an appropriate
response.
Unfortunately, this program has a serious problem: it will not produce
any output! The problem is that client, as used in the recursive
setting of reqs and resps, attempts a match on the response list
before it has submitted its first request! In other words, the
pattern matching is being done "too early." One way to fix this is
to redefine client as follows:
client init resps = init : client (next (head resps)) (tail resps)
Although workable, this solution does not read as well as that given
earlier. A better solution is to use a lazy pattern:
client init ~(resp:resps) = init : client (next resp) resps
Because lazy patterns are irrefutable, the match will immediately
succeed, allowing the initial request to be "submitted", in turn
allowing the first response to be generated; the engine is now
"primed", and the recursion takes care of the rest.
As an example of this program in action, if we define:
init = 0
next resp = resp
process req = req+1
then we see that:
take 10 reqs => [0,1,2,3,4,5,6,7,8,9]
As another example of the use of lazy patterns, consider the
definition of Fibonacci given earlier:
fib = 1 : 1 : [ a+b | (a,b) <- zip fib (tail fib) ]
We might try rewriting this using an as-pattern:
fib@(1:tfib) = 1 : 1 : [ a+b | (a,b) <- zip fib tfib ]
This version of fib has the (small) advantage of not using tail on
the right-hand side, since it is available in "destructured" form on
the left-hand side as tfib.
[This kind of equation is called a pattern binding because it is a top-level equation in which the entire left-hand side is a pattern; i.e. both fib and tfib become bound within the scope of the declaration.]
Now, using the same reasoning as earlier, we should be led to believe that this program will not generate any output. Curiously, however, it does, and the reason is simple: in Haskell, pattern bindings are assumed to have an implicit ~ in front of them, reflecting the most common behavior expected of pattern bindings, and avoiding some anomalous situations which are beyond the scope of this tutorial. Thus we see that lazy patterns play an important role in Haskell, if only implicitly.
It is often desirable to create a nested scope within an expression, for the purpose of creating local bindings not seen elsewhere---i.e. some kind of "block-structuring" form. In Haskell there are two ways to achieve this:
These two forms of nested scope seem very similar, but remember that a let expression is an expression, whereas a where clause is not---it is part of the syntax of function declarations and case expressions.
The reader may have been wondering how it is that Haskell programs
avoid the use of semicolons, or some other kind of terminator, to
mark the end of equations, declarations, etc. For example, consider
this let expression from the last section:
let y = a*b
f x = (x+y)/y
in f c + f d
How does the parser know not to parse this as:
let y = a*b f
x = (x+y)/y
in f c + f d
?
The answer is that Haskell uses a two-dimensional syntax called layout that essentially relies on declarations being "lined up in columns." In the above example, note that y and f begin in the same column. The rules for layout are spelled out in detail in the Report (§2.7, §B.3), but in practice, use of layout is rather intuitive. Just remember two things:
First, the next character following any of the keywords where, let, or of is what determines the starting column for the declarations in the where, let, or case expression being written (the rule also applies to where used in the class and instance declarations to be introduced in Section 5). Thus we can begin the declarations on the same line as the keyword, the next line, etc. (The do keyword, to be discussed later, also uses layout).
Second, just be sure that the starting column is further to the right than the starting column associated with the immediately surrounding clause (otherwise it would be ambiguous). The "termination" of a declaration happens when something appears at or to the left of the starting column associated with that binding form. (Haskell observes the convention that tabs count as 8 blanks; thus care must be taken when using an editor which may observe some other convention.)
Layout is actually shorthand for an explicit grouping mechanism,
which deserves mention because it can be useful under certain
circumstances. The let example above is equivalent to:
let { y = a*b
; f x = (x+y)/y
}
in f c + f d
Note the explicit curly braces and semicolons. One way in which this
explicit notation is useful is when more than one declaration is
desired on a line; for example, this is a valid expression:
let y = a*b; z = a/b
f x = (x+y)/z
in f c + f d
For another example of the expansion of layout into explicit
delimiters, see §2.7.
The use of layout greatly reduces the syntactic clutter associated with declaration lists, thus enhancing readability. It is easy to learn, and its use is encouraged.


Zero to One
Zero to One - Notes on Startups, or How to Build the Future is a book based on the lectures of Peter Theil and the notes of Blake Masters. The original notes are legendarily meticulous, and the book is itself a curated and refactored collection of those notes.
Peter Theil
Peter Theil is a fascinating figure; a contrarian, “the bad boy of Silicon Valley”, “the philosopher VC”, Theil has quite the notoriety. From supporting Donald Trump to the lawsuit against Gawker media, Theil has earned the ire of most of left-leaning Silicon Valley. Despite all of this, Theil has remained something of a cult figure, especially among the more conservative minded. I wasn’t all too sympathetic towards Theil and his views but after reading this book I am approaching my attitudes towards him from an entirely different angle. While I still don’t agree with much of what he says, he clearly knows a thing or two about entrepreneurship and start-ups.
This book is not a step by step guide for creating a start-up when compared to titles such as “the Lean Startup” or “the Startup Owners Manual”, but it is a unique view into the minds of one of Silicon Valley’s most intriguing people. I’ll discuss the most insightful and in-depth chapters.
Party Like It’s 1999
Peter Theil along with Elon Musk and “the PayPal mafia” sold their company PayPal right before the 2001 dot-com bust. Going from maniac exuberance back to reality caused the companies of the time to learn a few lessons about business and technology. They were to:
- Make Incremental Advances
- Stay Lean and Flexible
- Improve on the competition
- Focus on product, not sales
Theil argues that all of these ideas are mistaken, and will just lead to mediocrity. I personally was on board with those suggestions until Theil made his argument for an alternative and contrarian version of the list which he contends will lead a company to much greater success. Theil claims:
- It is better to risk boldness than triviality
- A bad plan is better than no plan
- Competitive markets destroy profits
- Sales matters just as much as product
I was talking to a friend about this and he seemed to be skeptical of most of these points. Perhaps a really bad plan can be worse than no plan. Competition breeds improvement. If you don’t focus on your product you won’t get sales.
To these I’d probably say:
-
It’s rare to be able to plan so badly that no plan is superior. A plan would at the very least improve your business and move it in a particular direction whereas no plan would improve you nowhere in particular. It’s not the difference between a specialist and generalist, it’s more like the difference between having goals and messing around.
-
A competitive market is good for consumers in that you get the cheapest prices, but R&D cannot be done without profits. Improvements can’t be made without investment. Ultimately you want companies to spend a lot on R&D so that you can have better products over time, not just the cheapest products right now.
-
You need both sales and product but some people will buy a bad product if the sales strategy is great. If you have the greatest product in the world but nobody knows about it, it’s irrelevant.
I would say however that these two lists aren’t mutually exclusive, all of the points must be judged by the specific context in which they take place. Some companies really have a bad product and great sales, so they should actually focus on product. Some companies are too rigid and overly planned, not responding to consumer demand and market changes. Any list that claims to have the be all, end all truth is wrongheaded at best.
You have to find your place within these dichotomies:
Incrementalism vs. Boldness
Leanness vs. Planning
Competition vs. Monopolization
Product vs. Sales
You Are Not a Lottery Ticket
Theil starts the chapter criticizing the hyper-successful who ascribe their considerable wealth and success to pure luck or being in the right place at the right time. He notably brings up the fact that there are people who have created multiple billion - dollar companies which seems to fly in the face of the idea that every huge company is a lucky one hit wonder.
Most entrepreneurs seem to reject this framing. Almost every guest on podcasts such as “How I Built This” say that their success is mostly luck based and being in the right place at the right time. The book quotes Bill Gates, Jeff Bezos and the like talking about their abundant luck. Theil thinks that this is a sort of strategic modesty. I think it’s not only that, but also that people may not realize how weird they really are. Oftentimes when narrating their journey, great entrepreneurs seem to get into situations which a normal person wouldn’t, or take risks that a normal person wouldn’t.
In addition to that, they all seem to work inhumanly hard and are extremely intelligent. Michael Dell talked about making hundreds of thousands in sales out of a dorm room basically, but unlike a typical college student who would be incredibly satisfied with that, he continued pushing and trying to compete with bigger and bigger companies. Can you imagine many undergrads deciding to work harder after casually getting $600,000 in sales from their dorm room business?
Jim Koch of Samuel Adams quit his lucrative consulting job at BCG to start a company in a seemingly dead industry. American beer went from being a joke to probably the best in the world when it comes to craft beer. The founders of Airbnb created hugely successful presidential election cereal on a whim. These aren’t the actions or achievements of normal people. Obviously, the market conditions and lifestyles of all these entrepreneurs was perfect for what they wanted to do, but that’s discounting their own very real talent of being able to take advantage of those opportunities at all.
Moving past the discussion of luck, the book takes a philosophical turn into a discussion of free will and our loci of control. Theil argues that instead of thinking of yourself as a lottery ticket and just hoping that you are the one in a million who will create something transcendent, you actually have to believe it and go try to make it happen. Far too often people are fatalistic when it comes to their own success; they hear Bill Gates say that he was just lucky, and they hope they get lucky too.

The philosopher Daniel Dennett brought this up in one of his talks (5:30): which would you prefer to have as an army (assuming equal training and equipment); 1000 fundamentalists who are willing to die for this battle, or 1000 economists looking over their life insurance policies? Even if the economists have a more accurate worldview, they still wouldn’t be as successful as the fundamentalists. Dan goes on further to say that the fundamentalists pay the hidden cost of dishonesty, but we don’t have to in our case, we can accept our evidence backed (or not!) beliefs of reality while living life a different way. Effectively we can have our cake and eat it too. This hints at a more complicated problem, however; how do you know if you are the lone genius or the lone lunatic?
I think that ultimately you can’t know. A true lunatic will never know that they are a lunatic, and this is why it will always be safer not to go down the uncharted road. However, if nobody ever took such a risk where would we be? Even if you don’t ultimately believe it, living your life as if you have 100% control over everything that happens, and you’ll make a much bigger impact on your circumstances than you may think. Just think about it: being screwed over by a person who has power over you may be something that seemed completely out of your control, but if you live your life as if you could’ve prevented it, then in the future you’ll be able to identify the superiors who would do you harm, and find a way to lessen or neutralize their influence over you. Making an effort in that direction, where there was none before can have incredibly positive impacts that you never would’ve known had you just given up.
Optimism vs. Pessimism and Planning vs. Hope
In the same chapter, an interesting concept introduced by Theil was the idea of the 4 quadrants of definite optimism, indefinite optimism, definite pessimism, and indefinite pessimism. This was a very stars and stripesy section but it brought up some interesting ideas.
Indefinite Optimism
Theil writes that the USA is currently in an indefinite optimistic mindset: we believe the world will be better in the future, we just don’t know how. We aren’t going to make specific steps towards it either; we’ll just sit and watch. There’s a cycle of finance in this indefinitely optimistic country which goes like this:
Nothing is really happening. It’s just a self-sustaining cycle where nobody is brave enough to make an actual investment in anything or anyone. We just live with the assumption that someone else will do it. People hold onto government bonds and savings even while they have a lower or equal expected return than the inflation rate. People are allowing their money to slowly rot away rather than actually investing it in anything. This seems absurd.
Even the “innovative” companies like Google and Apple are just sitting on piles of cash in offshore accounts, and letting them rot. They’re too scared to put that money into an actual venture and are content with just losing it slowly. The United States at this moment seems to be a bunch of risk managers, nothing more.
Indefinite Pessimism
Europe, on the other hand, is pessimistic about the future; it’s in decline, but won’t take any definitive steps to stop it. Once again, they’ll just sit and watch.
Definite Pessimism
China, Theil argues, is a pessimistic society but with defined plans. They know they can copy the Western model to great success and will continuously copy until they catch up. Theil writes “Every other country is afraid that China is going to take over the world; China is the only country afraid that it won’t.”
What’s interesting is Japan’s place in this. Theil said that Japan used to occupy this position; they relentlessly copied the United States in every facet. Japan took denim, technology, manufacturing from the USA and the West. Now, however, Japan seems completely uninterested in the USA. Japanese denim is the best in the world. Japanese technology is very different than American, same with cars, programming, and television. Golf used to be hugely popular in the 80s in Japan, now the golf courses are being turned into solar farms. Theil thinks that this is a disturbing sign of the stagnation of the West. We used to think that it was OK for Japan to copy us because while they were busy copying, we’d be moving on to the next thing. Now, however, they’ve caught up, and they’ve found nothing more that we provide. The Western world is no longer far ahead.
Definite Optimism
Theil reminisces for the USA of the 50s and 60s. John F. Kennedy said that we would reach the moon in 10 years, and we did it. People made huge, ambitious, audacious plans and then went out and tried to complete them. Nowadays we’ll have experts saying that everything is impossible or infeasible. The thing is; the experts are right 99% of the time; that’s why they’re experts. This is the problem with our society though; if we only do the feasible we’ll never do anything truly great or amazing. Greatness comes from doing what’s unthinkable, not what we say “yeah we should do that next” to.
Theil wants us to forget finance and focus on engineering. Forget savings and focus on investment. The greatest companies are built by great engineers and sales people (more on this in the next section) not CFOs and accountants.
If You Build It, Will They Come?
Engineers have always seemed to have the upper hand in the “who is more useful” debate. After all, what’s a sales person with nothing to sell? This chapter really dives into the false security engineers have in “product” over everything.
The bottom line is; a product that sells itself is a fantasy.
This is definitely a lesson for a lot of professionals. The lawyer that gets paid the most in the firm isn’t the best lawyer in the courthouse; he’s the rainmaker out there getting clients for the firm. The richest businessmen aren’t the CTOs, they’re the CEOs. The most powerful political actors aren’t policy geniuses, they’re political geniuses. In order to do anything; the “engineering” is expected, the sales is where the greatness comes in. Nikola Tesla was probably a much better engineer and inventor than Thomas Edison, yet he’s not nearly as well known (before Elon Musk’s Tesla that is), and he wasn’t remembered like Edison was. This is the prototypical case of the pure engineer against the 1/2 engineer, 1/2 salesman.
Conclusion
There is much more to get into with this book, from the similarities between the Unabomber and hipsters to secrets and philosophy. Perhaps I’ll get into it in another blog post. What I’ve written above however are what I found to be the most seminal points. This wasn’t a start-up manual, it was a historical and philosophical look into the mind of one of Silicon Valley’s most interesting people. The breadth of topics covered was as wide as the perspectives unique. I suggest you give it a read.


Send a post request to url with data header containing following data as json list or list of lists:
url
data


Planting billions of trees across the world is one of the biggest and cheapest ways of taking CO2 out of the atmosphere to tackle the climate crisis, according to scientists, who have made the first calculation of how many more trees could be planted without encroaching on crop land or urban areas
Growing a garden is not only beneficial for us, but it is also good for the environment since it minimises the number of miles it takes to bring food from the farm to our kitchen table, lowering the carbon footprint of our food
Planting trees aids in the storage of carbon from the atmosphere in the soil.


And God said
\begin{align} \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\ \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\ \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\ \nabla \cdot \vec{\mathbf{B}} & = 0 \end{align}
and then there was light
Finally, while display equations look good for a page of samples, the ability to mix math and text in a paragraph is also important. This expression \(\sqrt{3x-1}+(1+x)^2\) is an example of an inline equation. As you see, MathJax equations can be used this way as well, without unduly disturbing the spacing between lines.


| 907 | (A) | and ȝalde Sathanas his saulle and hym-selfe quellide |
| 913 | (C) | He ȝalde sathanas his soule . for he hym-selfe kylled |
| 899 | (D) | And yold þe soul to Sathanas & hym-self quellid |
| 876 | (E) | & ȝald his sowle to sathanas . for he hym-self quellyd . |
| (Ex) | ---- no text ---- | |
| 931 | (L) | þan he ȝeldeþ sathanas þe soule & hym-self quelled |
| 849 | (P) | And ȝelde Sathanas þe saule & hym-self quelled |
| 885 | (U) | And yelde his soule to sathanas / and him self quelled |
| (V) | ---- no text ---- |


Buttons: borderless
a.button-icon (Borderless, 32px)
.button-clear Next .button-icon
button.button-icon (Borderless, 32px)
a.button-block.button-icon (Borderless, 32px)
button.button-block.button-icon (Borderless, 32px)


Search for a City
Temperature: ℉
Humidity: %
Wind Speed: MPH
UV Index:
5-Day Forcast:
Date
Temp:
Humidity:
Date
Temp:
Humidity:
Date
Temp:
Humidity:
Date
Temp:
Humidity:
Date
Temp:
Humidity:
Temperature: ℉
Humidity: %
Wind Speed: MPH
UV Index:
Temp:
Humidity:
Temp:
Humidity:
Temp:
Humidity:
Temp:
Humidity:
Temp:
Humidity:


Menu
Dinesh Bhavsar
Profile Completness - 50%
Home
Emails
Upload Photos
Settings
Deactivate Profile
Feedback/Contact
Logout


{% import 'partials/section.html' as section %} {% extends "layouts/_twocol.html" %} {% block page_title %}Server error (Error 500) - ONS Business Surveys{% endblock %} {% block main %}
Something has gone wrong with the website.
You may want to visit the homepage
If you still encounter problems please contact us. We apologise for any inconvenience this may have caused.


How To Run Ansible Playbooks Remotely
Ansible is a great automation platform that allows you to control and configure multiple instances from your local machine without having to login to them.
Pre-req
I have one Amazon Linux instance running that I will make changes to. You’ll need the following:
- Public IP to your instance
- PEM key
Install Ansible
Make sure that your running instance have Ansible installed already or run the following:
sudo amazon-linux-extras install ansible2
Hosts file
The hosts file allows us to categorize our hosts into groups so that we can run a playbook on all hosts belonging to a group. It varies where your hosts file is located depending how you installed Ansible. I’m going to create a new folder called Ansible
inside my projects folder and also create a new file called hosts.ini
inside that folder.
mkdir Ansible
touch hosts.ini
Open the newly created file with the vi editor and add the following:
vi Ansible/hosts.ini
Press i
to enter edit mode.
[NAME-OF-GROUP-GOES-HERE]
IP-ADDRESS ansible_ssh_private_key_file=PATH-TO-PEM-FILE
In my case:
[test]
<IP_ADDRESS> ansible_ssh_private_key_file=ansible-test.pem
Press esc
and then :
followed by x
in order to save the changes.
We can simply repeat the process if we want to add more hosts/groups to control. Like this:
[test]
<IP_ADDRESS> ansible_ssh_private_key_file=ansible-test.pem
<IP_ADDRESS> ansible_ssh_private_key_file=ansible-test.pem
Test Playbook
Next step is to create a simple Ansible playbook that creates a new folder so that we can see our changes. Create a new file called test.yml
and open it with the vi editor.
touch test.yml
vi test.yml
Add the following and save the file:
---
- hosts: test
become: true
tasks:
- name: Test
shell: |
mkdir /home/ec2-user/test
Ansible reads the hosts file and applies these changes to all IPs belonging to the group specified, the group test
in our case. It is now time to run our test.yml script to see if things are working properly. From your projects folder, run the following:
ansible-playbook test.yml -i ansible/hosts.ini --user=ec2-user
Your output should be similar to this.
<IP_ADDRESS> : ok=2 changed=1 unreachable=0 failed=0
Yay, you just made a new folder on your instance without even logging in!


Downloading
.
.
.
10 MB / 4.0 MB
Sit tight, we are downloading content for your home
Installing
.
.
.
Just a moment
Success!

Houston...
An unfortunate error has occurred:


is used to group together elements R1 rotates in cardoid fashion. Four more such group is added by using svg tag.


{{=[[ ]]=}}
Templates are written in Mustache. Templates can be used for HTML, CSS, JavaScript, RSS feeds - anything. They works by expanding tags using values provided in a object. For example, the template:
Welcome to {{name}}'s blog
Recent posts:
{{#posts}}
- {{title}}
{{/posts}}
When rendered with the following object:
{
"name": "Chris",
"posts": [
{ title: "Apple" },
{ title: "Orange" }
]
}
Will produce the following result:
Welcome to Chris's blog
Recent posts:
- Apple
- Orange
You can retrieve the object used to render your site's template if you append the query string ?debug=true to any page on your site.
We call it "logic-less" because there are no if statements, else clauses, or for loops. Instead there are only tags. Some tags are replaced with a value, some nothing, and others a series of values. This document explains the different types of Mustache tags.
Tags are indicated by the double mustaches. {{person}}
is a tag, as
is {{#person}}
. In both examples, we'd refer to person
as the key
or tag key. Let's talk about the different types of tags.
The most basic tag type is the variable. A {{name}}
tag in a basic
template will try to find the name
key in the current context. If
there is no name
key, the parent contexts will be checked recursively.
If the top context is reached and the name
key is still not found,
nothing will be rendered.
All variables are HTML escaped by default. If you want to return
unescaped HTML, use three curly braces rather than two: {{{name}}}
.
You can also use &
to unescape a variable: {{& name}}
. This may be
useful when changing delimiters (see "Set Delimiter" below).
A variable "miss" returns an empty string.
For example, the template:
* {{name}}
* {{age}}
* {{company}}
* {{{company}}}
When given the following object:
{
"name": "Chris",
"company": "GitHub"
}
Will produce:
* Chris
*
* GitHub
* GitHub
Sections render blocks of text one or more times, depending on the value of the key in the current context.
A section begins with a pound and ends with a slash. That is,
{{#person}}
begins a "person" section while {{/person}}
ends it.
The behavior of the section is determined by the value of the key.
False Values or Empty Lists
If the person
key exists and has a value of false or an empty
list, the HTML between the pound and slash will not be displayed.
Template:
Shown.
{{#person}}
Never shown!
{{/person}}
Hash:
{
"person": false
}
Output:
Shown.
Non-Empty Lists
If the person
key exists and has a non-false value, the HTML between
the pound and slash will be rendered and displayed one or more times.
When the value is a non-empty list, the text in the block will be displayed once for each item in the list. The context of the block will be set to the current item for each iteration. In this way we can loop over collections.
Template:
{{#repo}}
{{name}}
{{/repo}}
Hash:
{
"repo": [
{ "name": "resque" },
{ "name": "hub" },
{ "name": "rip" }
]
}
Output:
resque
hub
rip
Lambdas
When the value is a callable object, such as a function or lambda, the
object will be invoked and passed the block of text. The text passed
is the literal block, unrendered. {{tags}}
will not have been expanded
- the lambda should do that on its own. In this way you can implement
filters or caching.
Template:
{{#wrapped}}
{{name}} is awesome.
{{/wrapped}}
Hash:
{
"name": "Willy",
"wrapped": function() {
return function(text, render) {
return "" + render(text) + ""
}
}
}
Output:
Willy is awesome.
Non-False Values
When the value is non-false but not a list, it will be used as the context for a single rendering of the block.
Template:
{{#person?}}
Hi {{name}}!
{{/person?}}
Hash:
{
"person?": { "name": "Jon" }
}
Output:
Hi Jon!
An inverted section begins with a caret (hat) and ends with a
slash. That is {{^person}}
begins a "person" inverted section while
{{/person}}
ends it.
While sections can be used to render text one or more times based on the value of the key, inverted sections may render text once based on the inverse value of the key. That is, they will be rendered if the key doesn't exist, is false, or is an empty list.
Template:
{{#repo}}
{{name}}
{{/repo}}
{{^repo}}
No repos :(
{{/repo}}
Hash:
{
"repo": []
}
Output:
No repos :(
Comments begin with a bang and are ignored. The following template:

Today{{! ignore me }}.

Will render as follows:

Today.

Comments may contain newlines.
Partials begin with a greater than sign, like {{> box}}
.
 Just avoid infinite loops.
They also inherit the calling context. Whereas in an [ERB](http://en.wikipedia.org/wiki/ERuby) file you may have this:
<%= partial :next_more, :start => start, :size => size %>
Mustache requires only this:
{{> next_more}}
Why? Because the next_more.html
file will inherit the size
and
start
methods from the calling context.
In this way you may want to think of partials as includes, imports, template expansion, nested templates, or subtemplates, even though those aren't literally the case here.
For example, this template and partial:
base.html:

Names

{{#names}}
{{> user}}
{{/names}}
user.html:
{{name}}
Can be thought of as a single, expanded template:

Names

{{#names}}
{{name}}
{{/names}}
Set Delimiter tags start with an equal sign and change the tag
delimiters from {{
and }}
to custom strings.
Consider the following contrived example:
* {{default_tags}}
{{=<% %>=}}
* <% erb_style_tags %>
<%={{ }}=%>
* {{ default_tags_again }}
Here we have a list with three items. The first item uses the default tag style, the second uses erb style as defined by the Set Delimiter tag, and the third returns to the default style after yet another Set Delimiter declaration.
According to ctemplates, this "is useful for languages like TeX, where double-braces may occur in the text and are awkward to use for markup."
Custom delimiters may not contain whitespace or the equals sign.
[[={{ }}=]]


The participant was identified as a potential lung screening candidate by:
Eligible based on chart review?
Was a pre-enrollment discussion held?
A pre-enrollment discussion with the participant resulted in:
Additional information can be provided on the background form
Veteran of age and exposure to cigarette smoke as described above, and without a current diagnosis or obvious symptoms suggestive of lung cancer, has been educated today about the estimated risk for lung cancer, the possibility of a cure or life prolonging if an early lung cancer were to be found during screening, the possibility of imaging abnormalities not being lung cancer, the possibility of complications from additional diagnostic procedures, and the approximate amount of radiation exposure associated with each screening procedure. In addition, the veteran has been educated today about the importance of avoiding exposure to cigarette smoke, available tobacco cessation programs and available lung screening services at this VA facility. Education material was provided to the veteran.
2018-10-31 12:00 PM - {USERNAME}: {TEXT HERE}
2018-10-31 12:00 PM - {USERNAME} changed to {FIELD} to {VALUE}: {REASON} - {EXPLANATION}
Are you certain you want to delete this form?


So, just had my first voice call with Stella as we approach show time as a bit of a prep for the show. I’ve loved her writing for a while, but to really hear her first hand in thoughtful conversation I was blown away. What a class act! What a thoughtful lady! She’s awesomer than I even thought. So, I’m completely thrilled (even more so than before) to have her on The Minnow Mayor Town Hall show. It’s going on live tonight in 5 hrs (9pm New York Time).
If you’re wondering what we’re gonna talk about… here’s your hint: Tribes!
Contests
3 Contests will happen on the show.
- 1500 Delegated SP from a scavenger hunt I released earlier this week- https://steemit.com/mspwaves/@aggroed/stellabelle-to-star-on-the-minnow-mayor-town-hall-this-sunday-night-9-11-est-2-000-sp-delegation-contest-and-50-sbd-inside
- 500 SP from an in show contest where the audience will recruit other listeners and for every person you recruit you get an extra “raffle ticket”
- Dice Bitches- We’ll roll some bones and the winner will get 25SBD (we’ll do this twice on the second half of the show)
But you gotta be there if you want to win!!! So, check out mspwaves.com/listen to hear the show and go to the PALnet Discord channel home of the Minnow Support Channel- https://discord.gg/dpGVBcy!
Quick Side Note
The scavenger hunt for 1500 SP has a number of things you need to do for your shot at the 1500 SP. These are purposefully designed to help and encourage you to do some of the things that separate dolphins from minnows. So, the things on that list are things you already should know how to do, and if you don’t now’s the time to learn. It’s your Dolphin 101 homework with an MSP theme and a 1500 delegated SP potential as your reward.
Should be fun!
See you there!
This page is synchronized from the post: ‘5 Hrs it’’s time for @aggroed and @stellabelle to go live on air!!! (Don’’t miss your chance at 2,000 delegated SP and 50 SBD)’


--- layout: archive title: Zulip Chat Archive permalink: /stream/113488-general/topic/slogan.html ---
I am writing from an AFOSR meeting on dynamical systems and control theory in Washington, DC. This morning, one of the speakers, Arthur Krener, used the following slogan:
Think mathematically, act computationally.
It's a nice play on Buckminster Fuller's famous slogan, and it is widely applicable. It also fits well with this group, so I thought I would pass it along.
{% endraw %}Last updated: Apr 24 2020 at 19:02 UTC


Amazon pulls "racist" skin-lightening products
by APE-commerce giant Amazon.com has pulled more than a dozen skin-lightening products with dangerous mercury levels off its website after pushback from Minnesota health and environmental activists.
The Seattle-based company's change came after the BeautyWell Project and the Sierra Club's state branch delivered a petition on Wednesday with more than 23,000 signatures to Amazon's fulfillment center in Shakopee, Minnesota.
The two organizations also took out a full-page ad in a local newspaper that day demanding that Amazon stop selling toxic skin-lightening creams. The ad had three words in bold print—"Dangerous, racist, and illegal."
An Amazon spokesperson told Minnesota Public Radio News in an email Thursday that such products are "no longer available."
As of Thursday, all but one of the 15 products with high mercury levels appeared to be removed from Amazon's website.
It's the latest incidents where Amazon removed products from its site that some found offensive. Earlier this year, Amazon pulled doormats bath mats that features phrases from the Quran.
In June, a study found that face-recognition technology that Amazon was marketing for law enforcement purposes had a racial and gender bias.