Login / My DCL
Log In / Register
My Library Dashboard
My Borrowing
Checked Out
On Hold
Fees
My Collections
Shelves
Lists
My Profile
My Settings
Advanced Search
Toggle search
Toggle navigation
Advanced Search
Explore
Recent Activity
New Titles
Awards
Bestsellers
Staff Picks
Locations
All Locations
Castle Pines
Castle Rock
Highlands Ranch
Lone Tree
Louviers
Parker
Roxborough
Douglas County History
Using the Library
Digital Media
Reserve a Space
Library Events
Research
Kids & Teens
Newsletters
Become a DCL insider and be the first to access ticket sales for our events! You’ll also get the inside scoop on great reads and upcoming programs.
Sign Up Now
Email Address
*
First Name
Last Name
Preferred Branch
Highlands Ranch
Parker
Lone Tree
Castle Pines
Castle Rock
Roxborough
Louviers
Interested in...
Children's
Food & Drink
Arts
Travel
Business
Author Presentations
Lifelong Learning
Book Lovers Events & Book Clubs
Teen
Genealogy
Languages
Home & Garden
Age
0-12
13-18
19-30
31-45
46-55
56-64
65+
Email Format
html
text
Check out some of our past e-newsletters:
Use the Classic Catalog »
© Douglas County Libraries,
100 S. Wilcox Street, Castle Rock, CO
|
(303) 791-7323


One of the main projects in our corp. includes having a hands-on industrial expertise on providing rover and drone supervision in case of major events and public rallys.
one of our acheivement includes the use of deep learning module as a part of the space program. Our preset modules are being used in the Indian Mars Mission.
Statistical Calculations and stock market prediction including one of our leading Artificial Intelligence: Generation 343, to accurately measure the ups and downs of the market
In order to help children get a good introduction to Machine learning modules and python, we have developed a new branch to our existing modules to enlighten them with the basic knowledge of machine learning
Another one of our projects includes using Deep learning directives to create a chatbot to handle client side messaging
Good console for admin purposes
AI can revolutionize the gaming world, hence we at MyAI.com has taken an initiative to help the world get the best gaming experience.
Chemical industry is one amongst the most sought after industry, hence to give a helping hand MyAI.com has launched CARBON to provide AI assistance in the field.
Photography is a stream which is gianing popularity in the recent years so with the advancement in it MyAI.com has launched Horizon a photoGallery to boast off the use of AI in photography
Another aspect of the influenced world is money. AI can be used in making a better bet on the crypto-currency market
You can find us at
The site content is provided by © MyAI.com


...to the world of Tereborn!
Fight against the countless enemies the Killer Rabbit of Caerbannog has placed before you. Should you win, peace shall grace the countryside at last. But if you are not victorious, the Killer Rabbit of Caerbannog will have your head.
Rolls left: 3 |
Add Stats: 5 |
Click to Reveal your Enemy.
The attack button will appear so you can click to roll your die.
The roll value plus your highest stat will be added to determine your attack roll.
Whomever has the highest attack roll value will win the match and the difference between your attack rolls will be subtracted from your health. Good luck!
Level:
Str:
Int:
Dex:
Con:
Click to reveal your enemy...
Str:
Int:
Dex:
Con:
Congratulations. At last all is well in the land of Tereborn! Your victory will be remembered for generations to come.
You were defeated by your enemy. Now the Killer Rabbit of Caerbannog will revel in your demise.


CrimPapers
Articles published on 5 August 2019
On 5 August 2019, 10 new articles were published in 5 journals.
Book Review: Shadows of Doubt: Stereotypes, Crime, and the Pursuit of Justice by Ava T. Carcirieri
Body-Worn Cameras: Evidence-Base and Implications by Callum Christodoulou, Helen Paterson, Richard Kemp
Perceived Appropriateness of Training and Organizational Commitment Among Korean Police by Hyunin Baek
Perceptions of Safety Confronted By Experience: How Visitors to Istanbul Modified Their Perceptions of Risk and Fear in the Light of Personal Experience by Rob I Mawby, Mine Özaşçılar, Neylan Ziyalar
Changing the Culture? A Feminist Academic Activist Critique by Kym Atkinson, Kay E. Standing
Tackling Rape Culture in Québec Universities: A Network of Feminist Resistance by Sandrine Ricci, Manon Bergeron
Making Power Visible: “Slow Activism” to Address Staff Sexual Misconduct in Higher Education by Tiffany Page, Anna Bull, Emma Chapman
Faculty Confronting Gender-Based Violence on Campus: Opportunities and Challenges by Simona Sharoni, Brian Klocke
Guest Editors’ Introduction by Ruth Lewis, Susan B. Marine
“It Is Time to Make Our Way Home”: How Contingent Labor Practices Impact Transformative Possibilities of Teaching About Violence Against Women by Deborah J. Cohan


Material Design is a design language developed by Google. Expanding upon the "card" motifs that debuted in Google Now, Material Design makes more liberal use of grid-based layouts, responsive animations and transitions, padding, and depth effects such as lighting and shadows.
Material Design Lite is a light-weight implementation of Material Design, specifically crafted for the web. Material Design Lite lets you add a Material Design look and feel to your websites. It doesn’t rely on any JavaScript frameworks and aims to optimize for cross-device use, and offer an experience that is immediately accessible. For more detailed guidelines and specifications for other platforms please refer to the Material Design site.


I had recently been caught with marijuana again at my school, this being my second offense, at our school once you are caught twice with anything you have to begin a drug testing program and start a drug group class thing.  When I was high at school or had brought a stash in my car, I would hide my keys in the spare tire on the back of my Jeep. I drove my friend to school that day and she had taken my car during 5th period without asking with 3 others. After school when I approached where my car was supposed to be parked, I believed to be stolen, considering jeeps are the number one stolen car to be stripped etc. There is a cop at our school, I was telling him what had happened and given the description of my car, when behold it pulls to its spot, cop gets all happy about a possible bust and immediatley searches my car and it just went to shit.
The driver had morphine on him too which didnt help the situtation.
Anyways, even though I wasnt supposed to smoke, I did, quite a few times. Before this had happened I was a daily smoker of marijuana. Over spring break I popped various pills like valium, flexiral, morphine, and snorted MDMA powder. My first test was on April 16, a wedsday and I had smoked on saturday, the day before that, two days before that, and the first week I probably smoked 4 times.
So, to try and have clean urine, all I did was drink cranberry grape juice lite and A LOT of water. I also worked out, as in running a little over 3 miles, working out on the stationary bike, and some weights. Just a little bit of weights. Anything aerobic to work up a sweat. Iím also a surfer so I had gone surfing 4 times between the time I last smoked and I test. Vitamin C pills also help because they help regulate my metabolism. I smoked the day after my test because it was my favorite holiday, 4/20, and I plan on doing the same routine, surfing, water, and cranberry juice. Cranberry juice does help clean out my system. The test was positive for Marijuana but the THC level was not high enough to be considered me recently having smoked. Eating healthy also helps, a lot of vegitables and fiber to help promote metabolism.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


Weather Dashboard
Search a city to find the weather forcast!
Temperature:
Humidity:
Wind Speed:
UV Index:
5-Day Forcast:


Main class for the baxter tasker that creates the GUI and objects for the robot.
The main window for baxter tasker. It links the buttons on the robot and the GUI to their corresponding behaviors.
| Parameters: |
|
|---|
Appends text to the currently selected editor window in the GUI. Can be used by all behaviors to easily store robot data
| Parameters: |
|
|---|
Callback for the back (arrow) buttons on the elbows. Shows the previous menu on the robot display
| Parameters: | side (str) – The side that has been pushed |
|---|
Callback for a button push for the wheel buttons on the elbows. Calls the current menu entry on the robot display
| Parameters: | side (str) – The side that has been pushed |
|---|
Selects the next or previous entry in the menu on the display. Called by the wheel method when the wheel is turned.
| Parameters: |
|
|---|
Callback when the oval (grip) button on the hand cuff is pressed. Opens or closes the gripper
| Parameters: |
|
|---|
Callback for the home buttons on the elbows. Directly shows the root menu on the robot display
| Parameters: | side (str) – The side that has been pushed |
|---|
Loads the task file that corresponds to the path from the harddisk into the GUI


←
Add a CLI to Node Apps with Vantage
NewSprint, Spectacle
Small Modules: Tales from a Serial Module Author
The End
→


Challenge Hunt helps you keep upto date with all the online programming challenges on over 25 platforms
If you want to be reminded of an upcoming challenge, just click on the bell and we'll add the challenge in your google calendar.


Tutorial
This tutorial is still incomplete. Please contribute by clicking on the Edit this page on GitHub
link at the bottom of this page.
Table of Contents
Registers
All registers are in undefined state at startup. The “Reset” column in the datasheets is misleading (and only emulated by the original IDE which generates code to set all registers to 0). You have to initialize all registers yourself.
Clock Sources and Setup
TODO: This section is still missing and should explain the following terms:
_sdcc_external_startup, IHRC, ILRC, external crystal, SYSCLK, maximum possible clk frequency, factory calibrated values, easy pdk calibration, …
Code Options
Padauk µCs have several options that are called “code option” in the datasheet. There is usually an overview of all code options a µC supports in a chapter towards the end of the datasheet. The datasheet does not provide any detailed information on how to set the code options, because Padauk expects users to use their IDE which takes care of that for you. Some code options are set as fuses, whereas others are set in undocumented registers.
To figure out whether a code option is set as a fuse or in an undocumented register, you can consult the following table.
For µCs not listed in the table, you need to look into the PDK include files as described in the next two sections, or into the original .INC
files that come with the Padauk IDE.
Click on an individual table cell to get the code that controls the corresponding code option.
| µC | Fuse | Undocumented Register | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ROP | MISC2 | MISCLVR | ||||||||||||||
| Security | Pin Drive | Startup Speed | 3-bit LVR | INT0 Source | INT1 Source | TMX Bits | TMX CLK | PWM Type | PWM CLK | TM2 OUT | COMP INT Edge | 3-bit LVR | 4-bit LVR | Bandgap CLK | ||
| PFS154 | x | x | x | x | x | |||||||||||
| PFS1721 | x | x | x | x | x | x | x | x | x | x | x | |||||
| PFS173 | x | x | x | x | x | x | x | x | x | x | x | x | ||||
| PMS150C | x | x | x | x | ||||||||||||
| PMS15A | x | x | x | x | ||||||||||||
| PMS152 | x | x | x | x | x | x | x | x | x | x | x | |||||
| PMS154C2 | x | x | x | x | x | |||||||||||
| PMS171B3 | x | x | x | x | x | x | x | x | x | x | x | x |
Fuses
Some of the code options are configured by setting bits in a magic word towards the end of the ROM.
These can be set using the PDK_SET_FUSE(...)
macro.
The factory-default fuse settings differ depending on the µC model, which is why it is best to always set all supported fuses.
Be aware that your program must only contain a single call to PDK_SET_FUSE
.
// Example of setting fuses on a PFS173
// The available fuses vary depending on the µC model!
#define PFS173
#include <pdk/device.h>
unsigned char _sdcc_external_startup(void)
{
PDK_SET_FUSE(FUSE_SECURITY_ON | FUSE_PB4_PB5_NORMAL | FUSE_BOOTUP_SLOW);
}
void main(void)
{
// ...
}
Undocumented Registers
Other code options are configured in undocumented registers:
-
ROP
: Many µCs have aROP
register that configures PWM, timer, and external interrupt related code options. -
MISC2
: Some µCs have aMISC2
register that supports selecting the comparator edge(s) that trigger an interrupt. -
MISCLVR
: Some µCs configure the LVR and sometimes bandgap related code options in aMISCLVR
register.
It is unclear whether you are allowed to change these code options while the µC is running, or whether you are supposed to only set them once and leave them as they are.
// Example of using the ROP register on a PFS173
// The available settings and undocumented registers vary depending on the µC model!
#define PFS173
#include <pdk/device.h>
unsigned char _sdcc_external_startup(void)
{
// ...
}
void main(void)
{
// Use PA4 for INT1 instead of PB0
ROP = ROP_INT_SRC_PA4;
}
Digital I/O
Digital I/O is organized in ports of (at most) 8 pins. The ports are named A
, B
, and C
.
I/O pins are controlled by the following registers (replace x
by A
, B
, or C
):
-
PxC
Control Register: Controls whether the pin is used as an input (0
) or output (1
). -
Px
Data Register: Sets the output low (0
) or (high
). Has no effect on inputs. -
PxPH
Pull-up (“pull-high”) Register: Enables a pull-up resistor. The resistor is also active when the pin is used as an output and driven high (!) -
PxPL
Pull-down (“pull-low”) Register: Enables a pull-down resistor (only very few ports and pins have pull-down resistors). It is unknown whether the resistor is also active when the pin is used as an output and driven high (!) -
PxDIER
Digital Input Enable Register: For pins to work as digital inputs, this register needs to be set to1
. Otherwise the input signal is cut off from the digital circuitry (including the external interrupt hardware + wake up functionality). This is recommended when using the pin as an analog input to the ADC or comparator, and required when using the pin as input of an external crystal.
The following table provides an overview of how the registers work together to control an I/O pin (this example uses PB.0).
| PBC.0 | PB.0 | PBPH.0 | PBPL.0 | PBDIER.0 | Result |
|---|---|---|---|---|---|
| 0 | x | x | x | 0 | Digital I/O disabled (can only use pin for analog input and crystal) |
| 0 | x | 0 | 0 | 1 | Input without pull resistors |
| 0 | x | 1 | 0 | 1 | Input with pull-up resistor |
| 0 | x | 0 | 1 | 1 | Input with pull-down resistor |
| 0 | x | 1 | 1 | 1 | not explicitly mentioned in datasheet |
| 1 | 0 | x | x | x | Output low wihout pull resistors |
| 1 | 1 | 0 | 0 | x | Output high wihout pull resistors |
| 1 | 1 | 1 | 0 | x | Output high with pull-up resistor |
| 1 | 1 | 1 | 1 | x | not explicitly mentioned in datasheet |
| 1 | 1 | 0 | 1 | x | not explicitly mentioned in datasheet |
Maximum Current
The maximum current an I/O pin can drive and sink varies by pin and µC. Take a look at the interactive pinout diagram of an individual µC and enable “Maximum Sink/Drive Current” to learn more.
TODO: Many µCs can increase the maximum current on two of their pins.
- How do I enable that?
- Is there any downside to enabling that?
Interrupts
Padauk µCs provide up to 8 interrupt sources. Interrupts are configured with the following registers:
-
INTEGS
: Interrupt Edge Select Register -
INTRQ
: Interrupt Request Register -
INTEN
: Interrupt Enable Register
Whenever an interrupt occurs, the corresponding bit in the INTRQ
register is set to 1
by hardware.
The µC never sets the bit back to 0
. This has to be done by your program.
If you want to trigger an interrupt service routine (ISR) when an interrupt occurs,
then you have to individually enable it for each interrupt source by setting the corresponding bit to 1
in the INTEN
register.
In addition, you need to enable interrupts globally by calling __engint()
.
All interrupts share a single ISR, which is denoted by adding the __interrupt(0)
attribute to the function definition.
Inside the ISR, you have to check which interrupt(s) triggered it by checking the corresponding bits in the INTRQ
register.
It is possible for multiple interrupts to occur at the same time
If you handle multiple interrupts in your ISR and you disable an interrupt conditionally by setting its corresponding bit in INTEN
to 0
at some point in your program, you also have to check the INTEN
register when the ISR is called. This is because the bit in INTRQ
is still set even if the interrupt is disabled in INTEN
.
The alternative is to disable all interrupts whenever you want to disable a single interrupt by calling __disgint()
.
The following example shows how to use the two external interrupts on a PFS173:
#include <stdint.h>
#include <pdk/device.h>
volatile uint16_t counter;
void interrupt(void) __interrupt(0)
{
if (
INTEN & INTEN_PA0 // Is the interrupt enabled?
&&
INTRQ & INTRQ_PA0 // Did the interrupt occur?
) {
// Reset interrupt request bit
INTRQ &= ~INTRQ_PA0;
// Handle interrupt
counter++;
}
if (
INTEN & INTEN_PB0 // Is the interrupt enabled?
&&
INTRQ & INTRQ_PB0 // Did the interrupt occur?
) {
// Reset interrupt request bit
INTRQ &= ~INTRQ_PB0;
// Handle interrupt
// ...
}
}
void main(void)
{
INTEN = INTEN_PA0 | INTEN_PB0;
INTEGS = INTEGS_PA0_BOTH | INTEGS_PB0_BOTH;
// Further initialization code
// Enable interrupts.
INTRQ = 0;
__engint();
for(;;) {
// Make sure to temporarily disable the interrupt when
// reading the variable from the main program, since access
// to 16 bit variables is not atomic.
uint16_t i;
INTEN &= ~INTEN_PA0;
// The ISR is now no longer called when an interrupt at PA0 occurrs.
// However, the INTRQ_PA0 bit in INTRQ will still be set if an interrupt at PA0 occurrs.
// -> Let's say at this moment the signal at PA0 changes
// -> INTRQ & INTRQ_PA0 is set to 1 by hardware
// -> The ISR is _not_ called, because INTEN & INTEN_PA0 is not set.
i = counter;
// -> Let's say at this moment the signal at PB0 changes
// -> INTRQ & INTRQ_PB0 is set to 1 by hardware
// -> The ISR is called, because INTEN & INTEN_PB0 is set AND interrupts are globally enabled.
//
// Important: The INTRQ_PA0 bit is still set to 1!
// If we don't check INTEN & INTEN_PA0 in the ISR, the code for PA0 would be triggered even
// though we disabled the interrupt.
// Re-enable the PA0 interrupt now that we have read the counter variable.
INTEN |= INTEN_PA0;
// ...
}
}
unsigned char _sdcc_external_startup(void)
{
// ...
}
VDD/2 LCD Bias Voltage Generator
Some µCs have the ability to output VDD/2
on some of their pins.
This functionality is enabled in the MISC
register.
After enabling the LCD bias voltage generator, the corresponding pins can no longer be used as input pins, because configuring them as input enables the VDD/2
output.
You should disable pull-up, pull-down resistors and also disable the PxDIER
bit for the corresponding pins when using the LCD bias voltage generator.
The following table provides an overview of how the registers work together to control the LCD bias voltage generator (this example uses PB.0).
| PBC.0 | PB.0 | PBPH.0 | PBPL.0 | PBDIER.0 | Result |
|---|---|---|---|---|---|
| 0 | x | 0 | 0 | 0 | Output VDD/2 |
| 1 | 0 | 0 | 0 | x | Output GND |
| 1 | 1 | 0 | 0 | x | Output VDD |
Watchdog Timer
The watchdog timer continuously counts up and automatically resets the µC when it reaches its maximum value.
It can be enabled in the CLKMD
register (make sure to enable both the watchdog and ILRC
).
The timeout value is set in the MISC
register and can be either 8k
, 16k
, 64k
, or 256k
ILRC
ticks.
To avoid µC resets during normal operation, you should regularly call __wdreset();
to reset the watchdog timer.
The ILRC
frequency and therefore watchdog timeout period can “drift a lot due to variation of manufacturing, supply voltage and temperature”4.
You should also call __wdreset();
right after reset and wakeup, because “the watchdog period will also be shorter than expected after reset or wakeup events”4.
Low Voltage Reset (LVR)
LVR automatically resets and stops the µC while the supply voltage is below the configured LVR threshold.
LVR is enabled by default and can be disabled in the MISC
register. The threshold is configured as a code option; see the Code Options section for more information.
You should configure the LVR threshold to at least meet the minium voltage supported by your system clock setting. Consult the f_SYS
row in the “Device Characteristics” table of the datasheet for more information.
Simulation and Emulation
Several options exist to simulate/emulate a Padauk µC. However, the official in-circuit emulator from Padauk currently is the only option that supports peripherals and interrupts. Emulators emulate a µC in hardware. They are usually realized using FPGAs and run in realtime. Simulators simulate a µC in software and are usually slower than the real µC.
µCsim
µCsim is part of SDCC and supports simulation of Padauk µCs, including breakpoints.
The binary is called spdk
and currently supports the following instruction sets and µCs (spdk -H
):
| Instruction Set | Simulated µC |
|---|---|
| PDK13 | PMC153 |
| PDK14 | PMS132B |
| PDK15 | PMS134 |
Interrupts are not currently supported.
µCsim Usage Example
This example invocation shows some of the commands supported by the simulator.
spdk main.ihx -X 8000000 -tPMS134
dump ram 0 9999 # dump RAM contents from byte 0 to 9999
dump regs8 0 9999 # dump register contents from register 0 to 9999
dump rom 0 9999 # dump ROM contents from word 0 to 9999
step 2 # step program execution 2 times
state # print state of µC
break 0x26 # set breakpoint before the instruction at 0x26 is executed
run # run program forever or until breakpoint is hit
Watchout: ROM addresses used by the emulator are word-based, whereas ROM addresses printed in the main.rst
file are byte-based. To break at the following instruction defined in the main.rst
file:
000040 F4 51 122 sub a, #0xf4
you have to divide the byte-based address (0x000040) by 2 when setting the breakpoint for the simulator:
break 0x20
Free PDK Simulator
A work in progress simulator for the PDK14 instruction set is available at free-pdk/fppa-pdk-tools. It currently does not support interrupts or peripherals.
pacmancoder/vpadauk
@pacmancoder has created a simulator for PDK13 that supports the PMS150C. The simulator is written in Rust and has support for interrupts, the timer, and digital IO.
Free PDK Emulator
A work in progress VHDL-based emulator for the PDK14 instruction set and PFS152 µC is available at free-pdk/fppa-pdk-emulator-vhdl.
Padauk ICE (in-circuit emulator)
Padauk offers in-circuit emulators that can be controlled from the Padauk IDE. A list of available emulators is available here. The list of µCs each emulator supports can be found here. The Padauk ICE supports most features of the µCs, and features not supported by ICE are usually called out in the datasheets.
The Padauk ICE cannot be used to emulate programs created by the Free PDK toolchain.
-
Some additional options seem to exist which are not documented in the datasheet: https://github.com/free-pdk/pdk-includes/blob/f44fc2e7678b1ab72ed8bac6b9d408118f330ad8/device/pfs172.h#L153-L165 ↩
-
This µC has additional undocumented code options configured in
MISC2
: https://github.com/free-pdk/pdk-includes/blob/f44fc2e7678b1ab72ed8bac6b9d408118f330ad8/device/pms154c.h#L156-L158 ↩ -
Some additional options seem to exist which are not documented in the datasheet: https://github.com/free-pdk/pdk-includes/blob/f44fc2e7678b1ab72ed8bac6b9d408118f330ad8/device/pms171b.h#L145-L148 ↩
Checkout /doc-style for more information on some of the special Markdown formatting features we use.


You just discovered ...
Ag
AaBbCc
Righteous
by Brian J. Bonislawsky
You just discovered ...
Ag
AaBbCc
Trochut
by Andreu Balius
You just discovered ...
Ag
AaBbCc
Fascinate Inline
by Brian J. Bonislawsky
You just discovered ...
Ag
AaBbCc
Lobster
by Pablo Impallari
You just discovered ...
Ag
AaBbCc
Sniglet
by Haley Fiege
Palet
tab
Discover new
fonts and colors
with every
tab
Palletab is a browser extension which uses Google fonts and amazing ColourLovers palettes to inspire you with fresh and clean inspiration every time you hit that new tab button!
For Chrome
For Firefox
A PROJECT BY
TIM HOLMAN
&
CLAUDIO GUGLIERI
Follow @twholman
Follow @claudioguglieri
Tweet


MBListenerAction Class Reference
| Inherits from | MBEventHandler : MBDataModel |
|---|---|
| Declared in | MBEventListener.h |
Overview
Provides a low-level API for performing actions in response to events received by listeners.
Subclasses must implement the eventReceived:byListener:container:
method
to handle events.
Action implementations should usually subclass MBExecutableListenerAction
,
which provides a higher-level API for executing actions.
Configuring the action's behavior
– acceptsTextContent
Indicates whether the action accepts text content within its XML tags.
- (BOOL)acceptsTextContent
Return Value
YES
if text content is accepted; NO
otherwise.
Discussion
Default implementation returns NO
.
Declared In
MBEventListener.h
– acceptsArbitraryAttributes
Indicates whether the action accepts an arbitrary set of attributes. Default implementation returns NO. If YES, attribute validation will not occur and arbitrary events will be accepted without issuing console warnings.
- (BOOL)acceptsArbitraryAttributes
Return Value
YES
if the listener accepts arbitrary attributes; NO
otherwise.
Declared In
MBEventListener.h
– ignoresNonstandardAttributes
Indicates whether the action ignores nonstandard attributes (i.e., those other
than “if
”, “afterDelay
” and “warnOnOverwrite
”.)
- (BOOL)ignoresNonstandardAttributes
Return Value
YES
if the listener ignores nonstandard attributes; NO
otherwise.
Discussion
Default implementation returns NO
. If YES
, attribute validation will fail
if any attributes appear other than the standard action attributes listed
above.
Declared In
MBEventListener.h


STATION 4 of 5
The experience of natural analogs by virtue of manifestation in organic, non-living and indirect evocations of nature is the underlying concept of materiality. This includes objects, materials, colors, shapes, sequences, and patterns found in nature, replicated or mimicked within the built environment in various forms. SDE4’s use of raw concrete, timber fixtures and fitting and floor patterns create an esoteric yet comprehensible analog to nature and biophilia.


From the Vega Example Gallery
A choropleth map of 2009 U.S. unemployment rates by county. A quantize scale is used to divide the color range into 9 discrete, uniformly-spaced bins.
A Dorling cartogram is a thematic map that uses sized circles to represent a quantity of interest per geographic region. This example visualizes the ratio of obese adults (BMI >= 30) by U.S. state in 2008. A double encoding uses both circle area and fill color to convey the obesity rate. Vega’s force transform and geoCentroid expression function are used to compute the layout.
A configurable map of world countries. Explore the results of applying different map projections and parameter settings. This example loads TopoJSON data and applies the Vega geoshape and graticule transforms.
A globe visualization of earthquakes reported by the USGS for the week of February 6, 2018. The earthquakes are formatted as GeoJSON data, and the geoshape transform’s pointRadius parameter is used to visualize earthquake magnitude as a circular area. This example is based on Jeremy Ashkenas’ USGS World Earthquake Map.
A gallery of world maps using various cartographic projections. Each map clips the projected land masses and graticule to the sphere of the Earth to ensure no extraneous shapes are shown. This example uses projections from the d3-geo-projection library that are not included in the standard Vega release.
A world map that pans and zooms in response to mouse drag and scroll wheel input. This example applies an inverse map projection (using Vega’s invert expression function) to map changes in pixel space to updated projection parameters.
This example visualizes the difference in projected area of countries using two different map projections. Each country is abstracted to a circle, sized by the area of that country under a particular map projection. Country circles are positioned based on the centroid position of the country under a primary projection. A second set of circles are then overlaid, with projected areas based on a secondary projection. This example demonstrates Vega’s geoArea and geoCentroid expression language functions.
A colored contour plot of the Maungawhau volcano in New Zealand. This example demonstrates contour generation directly from a provided grid of data values, rather than performing kernel density estimation on a discrete point set.
A vector field visualization of simulated winds over northwestern Europe. This example uses the angle channel of the symbol mark to set the orientation of wedge or arrow shape types.
2016 annual global precipitation data from the NOAA Climate Forecast System (CFS) v2. The data are provided as a raster grid of longitude and latitude (1° per cell). Isocontours are computed against the grid and projected. Adapted from an example by @mattijn.


General notes, terminology and policies
Raleigh HOG uses the mailer to periodically send campaigns to our members. Generally the campaigns we send are; Newsletter announce - sent once a month when the newsletter is published Monthly meeting reminder - sent once a month on the Monday before the Thursday meeting LoH Monthly meeting reminder - sent once a month on the Monday before the Thursday meeting Weekly ride reminder, aka Upcoming events - sent each Wednesday for the upcoming weekend ride(s) and/or events
- Please note, although certain steps may be specific to the Raleigh NC Chapter website, the overall steps should be generic enough that other chapters using HOG[SCAN] can follow along with only slight modifications.
- This environment is different than the website. There is only one, shared, account that is used for logging in. Do NOT change the Email or the Password.
- For the purposes of this tutorial, a campaign is what was previously called an 'email blast'.
- In this tutorial the Navagational Bar is referred to as the navbar.
- Every website has a navbar. It normally appears at the top of the page or on the left side of the page. As a user clicks links in the navbar to go to different pages within the website, the navbar retains its position making it easy for the user to navigate to other pages within the website.
- The Monthly Chapter Meeting template contains sensitive information, the link to join the Zoom meeting as well as the Meeting ID and Passcode
- This information should never be posted in the event calendar where it can be accessed by anyone in the world. It is only shared with current chapter members through the campaign.
- There are currently four groups that Raleigh HOG sends a campaign to. They are;
- Current Members - all current members of Raleigh HOG. This group is used to send a campaign to all members. E.g., monthly meeting announcement, newsletter announcement, weekly upcoming events
- Note - The Current Members group contains the LoH, Road Captains and Chapter Officers groups. It is all encompassing.
- LoH - current members of Ladies of Harley. This group is used to send a campaign that is only meant for the Ladies of Harley. E.g., LoH monthly meeting announcement, LoH party or activity such as their Christmas party or Myrtle Beach weekend
- Road Captains - current Road Captains. This group is used to send a campaign that is meant only for Road Captains. E.g. A pre-ride that is on the Road Captain's calendar if we ever take advantage of it.
- Chapter Officers - the six (6) elected chapter officers. This group is used to send a campaign that is meant only for the elected officers.
- Current Members - all current members of Raleigh HOG. This group is used to send a campaign to all members. E.g., monthly meeting announcement, newsletter announcement, weekly upcoming events
- This tutorial covers updating an existing template and sending a campaign. You can click the respective link to jump to a specific section;


Oops, you need to build the package before running this example. It's easy: just run rake
in the project's directory.
This is a simple example of how easy it is to get up and running with WysiHat.
Event.observe(window, 'load', function() {
var editor = WysiHat.Editor.attach('content');
new WysiHat.Toolbar(editor, {buttonSet: WysiHat.Toolbar.ButtonSets.Basic});
});


| app/ |
|
100% |
(2 / 2) |
100% |
(0 / 0) |
100% |
(1 / 1) |
100% |
(2 / 2) |
| app/blocks/backand-dataservice/ |
|
91.3% |
(21 / 23) |
0% |
(0 / 8) |
66.67% |
(6 / 9) |
91.3% |
(21 / 23) |
| app/blocks/exception/ |
|
72.22% |
(26 / 36) |
16.67% |
(1 / 6) |
83.33% |
(10 / 12) |
72.22% |
(26 / 36) |
| app/blocks/firebase-dataservice/ |
|
86.36% |
(19 / 22) |
100% |
(2 / 2) |
66.67% |
(6 / 9) |
86.36% |
(19 / 22) |
| app/blocks/geoloc/ |
|
42.86% |
(9 / 21) |
0% |
(0 / 4) |
33.33% |
(2 / 6) |
42.86% |
(9 / 21) |
| app/blocks/logger/ |
|
80% |
(16 / 20) |
100% |
(0 / 0) |
71.43% |
(5 / 7) |
80% |
(16 / 20) |
| app/blocks/router/ |
|
79.59% |
(39 / 49) |
40% |
(10 / 25) |
84.62% |
(11 / 13) |
81.25% |
(39 / 48) |
| app/blocks/utils/ |
|
70% |
(7 / 10) |
0% |
(0 / 2) |
50% |
(2 / 4) |
70% |
(7 / 10) |
| app/components/intro/ |
|
77.78% |
(28 / 36) |
0% |
(0 / 4) |
75% |
(9 / 12) |
77.78% |
(28 / 36) |
| app/components/shefotest/ |
|
85.19% |
(23 / 27) |
0% |
(0 / 2) |
87.5% |
(7 / 8) |
85.19% |
(23 / 27) |
| app/components/signin/ |
|
69.05% |
(29 / 42) |
100% |
(0 / 0) |
53.85% |
(7 / 13) |
69.05% |
(29 / 42) |
| app/core/ |
|
91.11% |
(41 / 45) |
50% |
(1 / 2) |
73.33% |
(11 / 15) |
93.18% |
(41 / 44) |
| app/layout/ |
|
100% |
(18 / 18) |
100% |
(0 / 0) |
100% |
(6 / 6) |
100% |
(18 / 18) |
| app/widgets/ |
|
45.83% |
(11 / 24) |
0% |
(0 / 4) |
33.33% |
(3 / 9) |
45.83% |
(11 / 24) |


I have been a Technology and Media Consultant professionally for the past ten years. For the first half of my career, I was self-employed as a Technology Consultant.  For the second half, I was a Media Consultant. In that field, I was able to take my passion for science and sound to a career level. I have designed sound for a few major recording acts as well as received an award at Festival de Cannes 2013. Working in the media industry has given me some of the most interesting contacts and experiences. One of these contacts recognized my abstract methods for tackling some of the most challenging situations and offered to bring me in as an IT temp for his company. I was back to breaking down problems to their root and provide an effective solution. My native skills and previous career background have brought me to a point where development is more attainable for me now then it was before. The reason why I have chosen to pursue development is because it encompasses all that the other industries have been lacking and that is to create efficiency and contact. I am eager to see where this path takes me. I am confident that my attention to detail, eye for superior quality of product and respect for estimated completion times will showcase my more unique qualities.


Grid based system
A grid based system is a design system where the websites are divided into grids. Usually the sites are divided into 12 columns. The combination of different number of columns forms a space for the contents of the site to reside. For example there can be a content that can occupy 6 such grids and width of the space created by that grid can be calculated as 6/12 or 50%. Only 2 such spaces can exist for that particular row (50% * 2).
Hype about resonsive webpages
Gone are the days when websites were delivered to computer screens of the fixed viewport. Nowadays a site needs to render correctly in any medium it is accessed with. It could be a monitor, tv, laptop, mobile phones of varying display etc. Hence to design sites capable of adjusting itself to these changes is of great importance. This is primarily achieved by using percentage values of display dimensions like width and height instead of fixed pixels. Another feature that allows for responsive design is the @media function which enables to design outcomes specific to output conditions.
Semantic Structure
A semantic structure not only gives structural inputs to the browser to render a webpage but also allows users to understand the contents. For example, the header tag implies that it is where the header details like logos or navigation bar can be found. Another good example is an article tag. An article tag tells the reader and browser that the content of it is independent of the other contents of the site. This article tag could be subdivided using section tags where each section can contain related or unrelated info pertaining the article. Similarly, a footer tag can help user and browser to identify the contents such as links, copyrights, sitemaps etc. Search engines make use of the semantics to display relevant search results and hence for search engine optimisation it is important to have a semantic design of the webpage.


The Java SE 1.4 platform included the "Crimson" reference implementation for JAXP 1.1. The Java SE 5 platform includes a reference implementation for JAXP 1.3 based on the Apache "Xerces" library.
Because these implementations come from entirely different codebases, and because the JAXP standard has evolved from 1.1 to 1.3, there are some subtle differences between the impementations, even they both conform to the JAXP standard. These two factors combine to create the compatibility issues described in this guide.
However, while XML applications written for 1.4 do suffer some
incompatibilities, JAXP 1.3 in the
Java SE 5 platform provides some compelling advantages:
That's the good news. The bad news is that some compatibility issues have survived all attempts at eradication. The remainder of this document discusses those issues.
While the reference implementation in Java SE 1.4 supported the DOM Level 2 API, the implementation in Java SE 5 supports the DOM Level 3 family of APIs. This section covers the impact of those changes on programs that used the JAXP 1.1 reference implementation:
For more information, see the complete list of changes in the DOM Level 3 Changes appendix.
In DOM level 3, additional methods were defined in the following interfaces:
The added methods only affect applications that implement the interfaces directly, and only then when the application is recompiled. Applications that use the factory methods to obtain implementation classes for these interfaces will have no problems.
These changes affect an application that reads in XML data into a DOM, makes modifications, and then writes it out in a way that preserves the original formatting.
In JAXP 1.1, extraneous whitespace was automatically removed on input, and a single property (ignoringLexicalInfo) was set to false to preserve entity nodes and CDATA nodes, for example. Including the additional nodes made the DOM somewhat more complex to process, but because they were there, adding whitespace output (indentation and newlines) produced highly readable, formatted version of the XML data which closely approximated the input.
In JAXP 1.3, there are four APIs that the application uses to determine how much lexical (formatting) information is available to process, using the following DocumentBuilderFactory methods:
The default values for all of these properties is false, which preserves all the lexical information necessary to reconstruct the incoming document in its original form. Setting them all to true lets you construct the simplest possible DOM, so the application can focus on the data's semantic content, without having to worry about lexical syntax details.
Note:
When adding new nodes, the application must add any indentation and
newline formatting that is needed for readability, since it is not
provided automatically.
Following are the changes made between SAX 2.0.0 and SAX 2.0.2
that might affect compatibility.
DeclHandler.externalEntityDecl
now requires the
parser to return the absolute system identifier for consistency
with DTDHandler.unparsedEntityDecl
. This may
cause some incompatibilities.In SAX 2.0.1, an application can set ErrorHandler, EntityResolver, ContentHandler, or DTDHandler to null. This is a relaxation of the previous restriction in SAX 2.0, which generated a NullPointerException (NPE) in such circumstances.
So the following code is legal in JAXP 1.3:
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader reader = sp.getXMLReader();
reader.setErrorHandler(null);
reader.setContentHandler(null);
reader.setEntityResolver(null);
reader.setDTDHandler(null);
The vast majority of applications are unaffected by this change, because the DefaultHandler implementation class has been modified to declare the additional exception, and very few applications use the DefaultHandler in such a way that they will run into a problem.
The only way an application can be affected is if it overrides the resolveEntity() method and also invokes super.resolveEntity(). In that case, the application won't compile in Java SE 5 until the method is modified to handle the IOExceptions that super.resolveEntity() could throw.
and the following new property:
For a complete list of Xerces features and properties, see
http://xml.apache.org/xerces2-j/features.html
and http://xml.apache.org/xerces2-j/properties.html.
Note:
One point of compatibility is also worth mentioning. Namespace
recognition was turned off by default in Java SE 1.4 (JAXP 1.1). For
backward compatibility, that policy is continued in Java SE 5 (JAXP
1.3). However, namespace recognition is turned on by
default in the official SAX implementation at www.saxproject.org. While not
strictly a compatibility issue from the standpoint of JAXP, it is
an issue that sometimes comes as a surprise.
Code that uses the standard JAXP APIs to create and access an XSL transformer does not need to be changed. The output will be the same, but will in general be produced much faster, since the XSLTC compiling transformer will be used by default, instead of the interpreting Xalan transformer.
Note:
There is no significant difference between Xalan and XSLTC
performance for a single run on a small data set, as when you are
developing and testing an XSL stylesheet. But there is a major
performance benefit when using XSLTC on anything larger.
JAXP 1.3 provides the standard XPath API for evaluating XPath expressions. We encourage users to use this API. Xalan-interpretive is not included in the reference implementation. If an application explicitly uses the Xalan XPath API to evaluate a standalone XPath expression (one that is not part of an XSLT stylesheet), you'll need to download and install the Apache libraries for Xalan, put them on the classpath.
This change does not affect applications that confine themselves to using the standard JAXP APIs. But applications that access implementation-specific features of the XML processors defined in previous JAXP versions will have to be modified to take into account package names that changed in JAXP 1.3.
The change has several effects on previous applications:
In Java SE 1.4, the fact that JAXP was built into the Java platform was a mixed blessing. On the one hand, an application could rely on that fact that it was there. On the other, most applications needed features and bug fixes that were available in later versions.
But adding new libarires had no effect, because internal classes always take precedence over the classpath. The solution for that problem in 1.4 was to use the endorsed standards mechanism. However, that was a new mechanism, and one which frequently placed an additional burden on the end user, as well as the application developer.
The solution in the JAXP 1.3 reference name is to change the package names of the Apache libraries used in the implementation. That change lets you reference newer Apache libraries in the classpath, so application developers can use them in the same way that would use any other additions to the Java platform.
The new names given to the Apache packages in the JAXP 1.3 reference implementation are shown below:
| JAXP 1.1 | JAXP 1.3 | |
|---|---|---|
| JAXP | org.apache.crimson |
-/- com.sun.org.apache.xerces.internal |
| org.apache.xml | com.sun.org.apache.xml.internal | |
| XSLT | org.apache.xalan org.apache.xpath org.apache.xalan.xsltc |
com.sun.org.apache.xalan.internal com.sun.org.apache.xpath.internal com.sun.org.apache.xalan.internal.xsltc |
Applications that specifying system properties on the command line with -D, in the JRE's lib/jaxp.properties file, or by hard-coding them into the application, generally do so in order to access functionality that is not present in the standard APIs.
JAXP 1.3 contains many new additions. When upgrading such applications, it is advisable to look for standard APIs in the javax.xml.* packages that will do the same job, because that's the best way to keep from having to change the application in the future. If absolutely necessary (either because of functionality restrictions or lack of time to investigate the new APIs), the property values can be changed by converting old-format package names into the format:
org.apache.somePackage --> com.sun.org.apache.SomePackage.internal
Similarly, internal implementation classes all use the new package names. If your application is using implementaton classes (it shouldn't!) those package names will have to change, as well.
While XML does not allow recursive entity definitions, it does permit nested entity definitions, which produces the potential for Denial of Service attacks on a server which accepts XML data from external sources. For example, a SOAP document like the following that has very deeply nested entity definitions can consume 100% of CPU time and large amounts of memory in entity expansions:
<?xml version="1.0" encoding ="UTF-8"?> <!DOCTYPE foobar[
<!ENTITY x100 "foobar"> <!ENTITY x99 "&x100;&x100;"> <!ENTITY x98 "&x99;&x99;"> ... <!ENTITY x2 "&x3;&x3;"> <!ENTITY x1 "&x2;&x2;"> ]> <SOAP-ENV:Envelope xmlns:SOAP-ENV=...> <SOAP-ENV:Body> <ns1:aaa xmlns:ns1="urn:aaa" SOAP-ENV:encodingStyle="..."> <foobar xsi:type="xsd:string">&x1;</foobar> </ns1:aaa> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
A system that doesn't take in external XML data need not be concerned with the issue, but one that does can utilize one of the following safeguards to prevent the problem:
entityExpansionLimit
system
property.


Resources: Facilities, Buffers and Stores¶
Facility¶
Facility is a resource that is used by entities for a finite duration. There is a limit on the number of entities that can use the facility at a given time. As an example, consider a barbershop (the facility) with m barbers (capacity of facility). The customers arrive at shop and wish to ‘use’ the resource (barber); if all barbers are busy, the customers wait until one barber is available.
The timeline of interactions between entities and facility is as follows:
- An entity requests the simulator to use a facility for duration time (with
useFacility()
Extended Entity Prototype
API). - If the facility is busy, the entity is placed in facility’s queue.
- If the facility is free or when the entity is done waiting in the queue, the entity is given access to the facility. This is modeled as:
- The facility is marked as busy.
- The simulator starts a timer for duration interval.
- At the expiration of the timer, the entity is notified that it has just finished using the facility.
Note
The entity is notified only at the completion of the request (step 4 above).
It is not notified, for example, when it done waiting in the queue or when it is preempted (if supported by queuing discipline).
Note
The useFacility()
request can only be cancelled or reneged while the entity is waiting in queue.
If the entity has started using the facility (step 3 above), the entity cannot be removed from the queue. That is, Sim.Request.cancel()
, Sim.Request.waitUntil()
and Sim.Request.unlessEvent()
will have no effect after the entity has started using facility.
Scheduling Disciplines
Scheduling Discipline is the policy on how the entities wait in the queue and use the facility. Some disciplines are:
- First Come First Server (FCFS)
- This is the most common scheduling discipline. Entities queue up in priority of their arrival times. Only when an entity is done using the facility, the next earliest entity is scheduled.
- Last Come First Served (LCFS)
- The last entity arriving at facility will preempt any current entity. When this entity is finished, the earlier entities will resume.
- Processor Sharing (PS)
- There is no queue in the system. All entities simultaneously use the facility, however their usage duration increases proportionally to the number of active entities.
- Round Robin (RR) (not supported)
- All entities take turn to use the facility for some time quanta duration each.
In the version 0.25 only FCFS, LCFS and Processor Sharing scheduling disciplines are supported. The other disciplines are planned for future releases.
Entities access the buffers through their Entity Prototype
API:
useFacility(facility, duration)
. Request to use the facility for duration time. This returns a Request object.
API Reference¶
-
class
Sim.
Facility
(name[, discipline[, numServers]])¶ Creates a new facility.
name
(string) is used for identifying the statistics in a report.discipline
is the scheduling discipline; currently it can take one of these values:- Sim.Facility.FCFS (first come first served) [Default value]
- Sim.Facility.LCFS (last come first served)
- Sim.Facility.PS (processor sharing; resources are “shared”, see Example: Processor Sharing)
numServers
is the number of servers available in the facility. By default, only one server is available per facility. Currently, only Sim.Facility.FCFS uses this parameter.
-
Sim.Facility.
usage
()¶ Return the duration for which this facility has been in use.
-
Sim.Facility.
systemStats
()¶ Return Population statistics for the request in the system (queue + service time).
-
Sim.Facility.
queueStats
()¶ Return Population statistics for the request in the queue.
Example: M/M/c Queue¶
The M/M/c problem: There are c servers (e.g. bank tellers) whose services are requested by customers. There is only one queue in front of all servers, so a customer at the head of the queue will move if any one of the c servers is free. The customers arrival is Poisson process, and service time is exponentially distributed. Such kind of queuing systems and servers can be easily modeled with FCFS facilities.
We create a facility as:
var server = new Sim.Facility('Server', Sim.Facility.FCFS, nServers);
The customers arrive at intervals that is exponentially distributed with mean lambda, and they request service for exponentially distributed duration with mean mu. We model the customer as:
var rand = new Sim.Random(SEED);
class Customer extends Sim.Entity {
start() {
// the next customer will arrive at:
var nextCustomerInterval = rand.exponential(lamda);
// wait for nextCustomerInterval
this.setTimer(nextCustomerInterval).done(() => {
// customer has arrived.
var useDuration = rand.exponential(mu); // time to use the server
this.useFacility(server, useDuration);
// repeat for the next customer
this.start();
});
}
}
Finally we create the simulation and entity objects, and start the simulation.
var sim = new Sim.Sim("M/M/c"); // create simulator
sim.addEntity(Customer); // add entity
sim.simulate(SIMTIME); // start simulation
server.report(); // statistics
Example: Processor Sharing¶
In the processor sharing service disciplines, all requesting entities get immediate access to the resource, however, their service time increases proportionally to the number of other entities already in the system.
As an example, consider CPU modeled as facility with Processor Sharing discipline. A single request to use CPU for 1 second will complete in 1 second. Two simultaneous requests to use CPU for 1 second each will finish in 2 seconds each (since the CPU is “shared” between the two requests).
Another example would be network connection link (e.g. Ethernet) with a given data rate. Entities request to use the resource, which in this case means sending data. If multiple overlapping requests are made then the network link is “shared” between all requests. Say, request one is initiated at time 0 to send data for 10 seconds. A second request is also made at time 5 seconds to send data for 1 second. In this case, the first request will finish at 11 seconds (0 - 5 sec at full capacity, 5 - 7 seconds at half capacity, and 7 - 11 sec at full capacity again), while the second request will finish at 7 seconds . We validate this as follows:
// create the facility
var network = new Sim.Facility("Network Cable", Sim.Facility.PS);
class Entity extends Sim.Entity {
start() {
// make request at time 0, to use network for 10 sec
this.useFacility(network, 10).done(() => {
assert(this.time(), 11);
});
// make request at time 5, to use the network for 1 sec
this.setTimer(5).done(() => {
this.useFacility(network, 1).done(() => {
assert(this.time(), 7);
});
});
}
};
var sim = new Sim.Sim();
sim.addEntity(Entity);
sim.simulate(100);
Buffer¶
Buffer is a resource that can store a finite number of tokens. Any entity can store tokens in the buffer if there is free space, or retrieve existing tokens from the buffer if some are available. Queueing happens when:
- an entity wishes to store tokens, but the buffer does not have sufficient free space to store them. The entity will be queued until some other entity (or entities) remove tokens from the buffer to create enough free space.
- an entity wishes to retrieve tokens, but the buffer does not have sufficient number of available tokens. The entity will be queued until some other entity (or entities) put enough number of tokens into the buffer.
Note
Buffer vs. Store
Buffers are resources that store “homogeneous” quantities. The buffers do not actually store any object, rather they keep a counter for the current usage, which is increment by putBuffer operation and decremented after getBuffer operation. If you wish to store real objects, consider using Store.
Buffers support two basic operations: put()
to store tokens in the buffer, and get()
to retrieve tokens from the buffers. The Buffer object has two queues: putQueue where the entities wait if their put()
request cannot be immediately satisfied, and getQueue where the entities wait if their get()
request cannot be immediately satisfied.
Entities access the buffers through their Entity Prototype
API:
putBuffer(buffer, amount)
. Attempt to store amount number of the tokens in buffer. This returns a Request object.getBuffer(buffer, amount)
. Attempt to retrieve amount number of the tokens from buffer. This returns a Request object.
API Reference¶
-
class
Sim.
Buffer
(name, maxCapacity[, initialAmount])¶ Creates a new buffer.
name
(string) is used for identifying the statistics in a report. The buffer hasmaxCapacity
capacity and has initiallyinitialAmount
number of tokens. IfinitialAmount
is omitted, then the buffer will be created empty.
-
Sim.Buffer.
size
()¶ The maximum capacity of the buffer.
-
Sim.Buffer.
current
()¶ The number of available tokens in the buffer.
-
Sim.Buffer.putQueue.
stats
¶ Population Statistics for the put queue.
-
Sim.Buffer.getQueue.
stats
¶ Population Statistics for the get queue.
The Buffer
class does not directly provide any put() or get() API. Instead, entities must use their Entity Prototype
functions (putBuffer()
and getBuffer()
) to access buffers.
Example: Producers-Consumers¶
The Producer-Consumer Problem: There are nProducers number of producer entities that produce tokens at rate of productionRate and stores them in a common buffer of bufferSize capacity. The producers must successfully store their produced items in buffer before they can begin on production of the next item. There are also nConsumers number of consumer entities that retrieve tokens from the same buffer and process them at rate of consumerRate.
We would like to study what is the average wait times for the producers and the consumers, given different values of the various parameters (such as bufferSize, productionRate etc).
We create the common buffer as:
var buffer = new Sim.Buffer("buffer", bufferSize);
We model the producers as entities that generate one token every t seconds, where t is exponential random number will mean productionRate.
Random rand = new Random(SEED);
class Producer extends Sim.Entity {
start() {
var timeToProduce = rand.exponential(1.0 / productionRate);
// Set timer to self (models the time spend in production)
this.setTimer(timeToProduce).done(() => {
// Timer expires => item is ready to be stored in buffer.
// When the item is successfully stored in buffer, we repeat
// the process by recursively calling the same function.
this.putBuffer(buffer, 1).done(this.start);
});
}
}
We model the consumers as entities that retrieve tokens from the buffers, and process them for t seconds, where t is exponential random number will mean consumptionRate.
class Consumer extends Sim.Entity {
start() {
// Retrieve one token from buffer
this.getBuffer(buffer, 1).done(() => {
// After an item has been retrieved, wait for some time
// to model the consumption time.
// After the waiting period is over, we repeat by
// recursively calling this same function.
var timeToConsume = rand.exponential(1.0 / consumptionRate);
this.setTimer(timeToConsume).done(this.start);
});
}
}
Finally we create the simulation and entity objects, and start the simulation.
// Create simulator
var sim = new Sim.Sim();
// Create producer entities
for (var i = 0; i < nProducers; i++) sim.addEntity(Producer);
// Create consumer entities
for (var i = 0; i < nConsumers; i++) sim.addEntity(Consumer);
// Start simulation
sim.simulate(SIMTIME);
// statistics
buffer.report();
Store¶
Store is a resource that can store a finite number of JavaScript objects (actually any datatype: number, string, function, array, object etc). Any entity can store objects in the store if there is free space, or retrieve existing objects from the store if some are available. Queueing happens when:
- an entity wishes to store objects, but the store does not have sufficient free space to store them. The entity will be queued until some other entity (or entities) remove objects from the store to create enough free space.
- an entity wishes to retrieve objects, but the store does not have sufficient number of available object. The entity will be queued until some other entity (or entities) put enough number of objects into the buffer.
Note
Store vs. Buffer
Stores are resources that store distinct JavaScript objects. If you do not wish to store actual objects, consider using Buffer.
Stores support two basic operations: put()
to store objects in the store, and get()
to retrieve objects from the stores. The Store object has two queues: putQueue where the entities wait if their put()
request cannot be immediately satisfied, and getQueue where the entities wait if their get()
request cannot be immediately satisfied.
Entities can retrieve objects from stores in two ways:
- Retrieve objects from store in FIFO order.
- Supply a “filter” function and retrieve object that matches the filter.
Entities access the stores through their Entity Prototype
API:
putStore(store, object)
. Attempt to store object in store. This returns a Request object.getStore(store[, filter])
. Attempt to retrieve object from buffer. If the filter function is supplied then the first object (in FIFO order) that matches the filter is retrieved; otherwise the first object in FIFO order is retrieved. This returns a Request object.
The retrieved object can be accessed via the this.callbackMessage
attribute in the callback function (see example below).
API Reference¶
-
class
Sim.
Store
(name, maxCapacity)¶ Creates a new store.
name
(string) is used for identifying the statistics in a report. The store hasmaxCapacity
capacity. The store will be created empty.
-
Sim.Store.
size
()¶ The maximum capacity of the store.
-
Sim.Store.
current
()¶ The number of available objects in the store.
-
Sim.Store.putQueue.
stats
¶ Population Statistics for the put queue.
-
Sim.Store.getQueue.
stats
¶ Population Statistics for the get queue.
The Store
class does not directly provide any put() or get() API. Instead, entities must use their Entity Prototype
functions (putStore()
and getStore()
) to access stores.
Example¶
// Create a store
var store = new Sim.Store("Example Store", 10);
class Entity extends Sim.Entity {
start() {
// Put an object
this.putStore(store, {myfield: "myvalue"});
// Put another object
this.putStore(store, {myfield: "othervalue"});
// arrays, numbers, strings etc can also be stored
this.putStore(store, "stored string");
// Retrieve object from store.
// Note 1: If filter function is not supplied, objects are returned in FIFO order
// Note 2: The object can be accessed via this.callbackMessage
this.getStore(store).done(() => {
assert(this.callbackMessage.myfield === "myvalue");
});
// Retrieve object from store using filter function
this.getStore(store, (obj) => obj === 'stored string')
.done(() => assert(this.callbackMessage === "stored string"));
}
}


Crossbar.io HA Demo - AutobahnJS (direct/non-proxied) Client
Open JavaScript console to watch output.


--- title: core keywords: fastai sidebar: home_sidebar summary: "Core functions for SQL formatting" description: "Core functions for SQL formatting" nb_path: "nbs/00_core.ipynb" ---
Basic formatting for SQL queries. Let's use an example throughout the core module.
This is how an input could look like
example_sql = """
create or replace table mytable as -- Mytable example
/* multi line
comment */
seLecT a.asdf,
-- some line comment
b.qwer, -- some comment here
/* and here is a line comment inside select */
substr(c.asdf,1,2) as substr_asdf,
/* some commenT
there */
case when a.asdf= 1 then 'b' /* here a case comment */
when b.qwer =2 then 'c' else 'd' end as new_field, -- Some comment
/* and here some inline comment */
b.asdf2 frOm table1 as a leFt join
table2 as b -- and here a comment
on a.asdf = b.asdf /* joiN this way */
inner join table3 as c
on a.asdf=c.asdf and a.qwer= b.qwer
whEre a.asdf= 1 -- comment this
anD b.qwer =2 and a.asdf<=1 --comment that
or b.qwer>=5
groUp by a.asdf
"""
and this is how we would like to format it
expected_sql = """CREATE OR REPLACE TABLE mytable AS -- Mytable example
/* multi line
comment */
SELECT a.asdf,
-- some line comment
b.qwer, -- some comment here
/* and here is a line comment inside select */
substr(c.asdf, 1, 2) as substr_asdf,
/* some commenT
there */
case when a.asdf = 1 then 'b' /* here a case comment */
when b.qwer = 2 then 'c'
else 'd' end as new_field, -- Some comment
/* and here some inline comment */
b.asdf2
FROM table1 as a
LEFT JOIN table2 as b -- and here a comment
ON a.asdf = b.asdf /* joiN this way */
INNER JOIN table3 as c
ON a.asdf = c.asdf and
a.qwer = b.qwer
WHERE a.asdf = 1 -- comment this
and b.qwer = 2
and a.asdf <= 1 --comment that
or b.qwer >= 5
GROUP BY a.asdf"""
Let's start by defining the main statements. The main statements all require a new line and should be in upper case
Remark:For OVER and PARTITION BY we only capitalize without adding a newline
We need to remove newlines and multiple spaces because they may be arbitrary.
Before removing newlines we also need to mark the end of coments with the special token [C] because we would not know where they end
We also mark the begin of comments / / with the special token [CS] (comment start) if they start in a newline
assert_and_print(
clean_query(
"""
SELECT asdf, qwer,
qwer1, qwer2
FROM table1
"""
), "SELECT asdf, qwer, qwer1, qwer2 FROM table1"
)
With usual comments
assert_and_print(
clean_query("""
SELECT asdf, qwer, -- some comment
qwer1, qwer2
FROM table1
WHERE asdf=1
"""), "SELECT asdf, qwer, -- some comment[C]qwer1, qwer2 FROM table1 WHERE asdf=1"
)
With other comment form
assert_and_print(
clean_query("""
SELECT asdf, qwer, /* another comment */
qwer1, qwer2
FROM table1
WHERE asdf=1
"""), "SELECT asdf, qwer, /* another comment */[C]qwer1, qwer2 FROM table1 WHERE asdf=1"
)
assert_and_print(
clean_query(
"""
SELECT asdf, qwer, /* another comment */
qwer1,
/* inline comment */
qwer2
FROM table1
WHERE asdf=1
"""
),
"SELECT asdf, qwer, /* another comment */[C]qwer1,[CS]/* inline comment */[C]qwer2 FROM table1 WHERE asdf=1"
)
assert_and_print(
clean_query(
"""
SELECT asdf,
qwer1, -- comment 1
-- inline comment
qwer2
FROM table1
WHERE asdf=1
"""
),
"SELECT asdf, qwer1, -- comment 1[C][CS]-- inline comment[C]qwer2 FROM table1 WHERE asdf=1"
)
assert_and_print(
clean_query(
"""
create or replace my_table as
/* some comment
some new comment line */
select asdf,
qwer, qwer2
from table1
"""
),
"create or replace my_table as[CS]/* some comment[CI]some new comment line */[C]select asdf, qwer, qwer2 from table1"
)
assert_and_print(
clean_query(
"""
create or replace table my_table as
select substr( asdf, 1, 2 ) as qwer,
qwer over (
PARTITION BY asdf
)
from table1
"""
), "create or replace table my_table as select substr(asdf, 1, 2) as qwer, qwer over (PARTITION BY asdf) from table1"
)
print(clean_query(example_sql))
We would like to have each main statement (SELECT, FROM , ...) in a separate line and in uppercase, ignoring text in comments. This way we can then later format each query statement separately. Also for the special case with PARTITION BY in the SELECT statement we will not add a newline because the main statement in that case is SELECT and not PARTITION BY
assert_and_print(
preformat_statements("select asdf, qwer as new_var from table1 where asdf = 1"),
"SELECT asdf, qwer as new_var\nFROM table1\nWHERE asdf = 1"
)
assert_and_print(preformat_statements("""
seLect asdf,
/* some comment inside select */
qwer
From table1 where asdf = 1
"""),
"SELECT asdf,[CS]/* some comment inside select */[C]qwer\nFROM table1\nWHERE asdf = 1"
)
assert_and_print(
preformat_statements("""
seLect asdf, /* some comment inside select */
qwer
From table1 where asdf = 1
"""),
"SELECT asdf, /* some comment inside select */[C]qwer\nFROM table1\nWHERE asdf = 1"
)
assert_and_print(
preformat_statements("""
create or replace view my_view as
seLect asdf,
/* some comment inside select */
qwer
From table1 where asdf = 1
"""),
"CREATE OR REPLACE VIEW my_view AS\nSELECT asdf,[CS]/* some comment inside select */[C]qwer\nFROM table1\nWHERE asdf = 1"
)
assert_and_print(
preformat_statements("""
create or replace view my_view as
seLect asdf,
qwer_function,
qwer
From table1 where asdf = 1
"""),
"CREATE OR REPLACE VIEW my_view AS\nSELECT asdf, qwer_function, qwer\nFROM table1\nWHERE asdf = 1"
)
assert_and_print(
preformat_statements("""
create or replace view my_view as
seLect asdf, qwer_function,
lead(asdf) over (Partition By asdf order BY qwer),
qwer2
From table1 where asdf = 1 order by asdf
"""),
"""
CREATE OR REPLACE VIEW my_view AS
SELECT asdf, qwer_function, lead(asdf) OVER (PARTITION BY asdf ORDER BY qwer), qwer2
FROM table1
WHERE asdf = 1
ORDER BY asdf
""".strip()
)
assert_and_print(
preformat_statements(
"""
create or replace table mytable as -- Mytable example
seLecT a.asdf, b.qwer, -- some comment here
/* and here is a line comment inside select */
substr(c.asdf, 1, 2) as substr_asdf
"""
),
"""
CREATE OR REPLACE TABLE mytable AS -- Mytable example[C]
SELECT a.asdf, b.qwer, -- some comment here[C][CS]/* and here is a line comment inside select */[C]substr(c.asdf, 1, 2) as substr_asdf
""".strip()
)
assert_and_print(
preformat_statements(
"""
create table mytable as -- Mytable example
seLecT a.asdf, b.qwer, -- some comment here
/* and here is a line comment inside select */
substr(c.asdf, 1, 2) as substr_asdf
"""
),
"""
CREATE TABLE mytable AS -- Mytable example[C]
SELECT a.asdf, b.qwer, -- some comment here[C][CS]/* and here is a line comment inside select */[C]substr(c.asdf, 1, 2) as substr_asdf
""".strip()
)
assert_and_print(
preformat_statements(
"""
create or replace table my_table as -- mytable
select distinct asdf, qwer, -- some comment
from table1
"""
),
"""
CREATE OR REPLACE TABLE my_table AS -- mytable[C]
SELECT DISTINCT asdf, qwer, -- some comment[C]
FROM table1
""".strip()
)
With additional keyword COMMENT
assert_and_print(
preformat_statements(
"""
create or replace table my_table comment='blabla' as -- mytable
select distinct asdf, qwer, -- some comment
from table1
"""
),
"""
CREATE OR REPLACE TABLE my_table comment='blabla' AS -- mytable[C]
SELECT DISTINCT asdf, qwer, -- some comment[C]
FROM table1
""".strip()
)
assert_and_print(
preformat_statements(
"""
create or replace transient table my_table as -- mytable
select distinct asdf, qwer, -- some comment
from table1
"""
),
"""
CREATE OR REPLACE TRANSIENT TABLE my_table AS -- mytable[C]
SELECT DISTINCT asdf, qwer, -- some comment[C]
FROM table1
""".strip()
)
assert_and_print(
preformat_statements(
"""
Create view my_table as -- mytable
select distinct asdf, qwer, -- some comment
from table1
"""
),
"""
CREATE VIEW my_table AS -- mytable[C]
SELECT DISTINCT asdf, qwer, -- some comment[C]
FROM table1
""".strip()
)
print(preformat_statements(example_sql))
assert_and_print(
lowercase_query("""
--- My nice view 1 --
Create or Replace VieW view_1 as
seLect asdf, -- Some Comment
qwER,
qwerTy, -- Some other comment
FROM table1
"""),
"""
--- My nice view 1 --
create or replace view view_1 as
select asdf, -- Some Comment
qwer,
qwerty, -- Some other comment
from table1
"""
)
assert_and_print(
lowercase_query("""
-- Some comment --
Create Or rePlace tablE aS
sElEct asdf,
/* sOme CommEnt */
qwer
FroM table1
"""),
"""
-- Some comment --
create or replace table as
select asdf,
/* sOme CommEnt */
qwer
from table1
"""
)
assert_and_print(
lowercase_query("""
-- Some comment --
Create Or rePlace tablE aS
sElEct asdf, replace('J', 'N', Asdf2) as Asdf3
/* sOme CommEnt */
qwer
FroM table1
"""),
"""
-- Some comment --
create or replace table as
select asdf, replace('J', 'N', asdf2) as asdf3
/* sOme CommEnt */
qwer
from table1
"""
)
assert_and_print(
lowercase_query("""
-- Some comment --
Create Or rePlace tablE aS
sElEct asdf, replace('J', 'N', Asdf2) as Asdf3
/* sOme CommEnt */
qwer
FroM table1 -- Some comment
"""),
"""
-- Some comment --
create or replace table as
select asdf, replace('J', 'N', asdf2) as asdf3
/* sOme CommEnt */
qwer
from table1 -- Some comment
"""
)
assert_and_print(
add_whitespaces_query(
"""
create or replace table my_table as /* some comment 1=1, 1 =1 */
select asdf, case when asdf= 1 then '=' else 0 end as qwerty
from table1 as a
left join table2 as b on a.asdf= b.asdf
where asdf=1 and qwer =2
"""
),
"""
create or replace table my_table as /* some comment 1=1, 1 =1 */
select asdf, case when asdf = 1 then '=' else 0 end as qwerty
from table1 as a
left join table2 as b on a.asdf = b.asdf
where asdf = 1 and qwer = 2
"""
)
assert_and_print(
split_apply_concat("select asdf, qwer, ", remove_wrong_end_comma),
"select asdf, qwer"
)
assert_and_print(
split_apply_concat("select asdf, qwer, -- some comment", remove_wrong_end_comma),
"select asdf, qwer -- some comment"
)
assert_and_print(
split_apply_concat("select asdf, qwer, /* another comment */", remove_wrong_end_comma),
"select asdf, qwer /* another comment */"
)
assert_and_print(
split_apply_concat("select asdf, qwer,,,, /* more than 1 comma */", remove_wrong_end_comma),
"select asdf, qwer /* more than 1 comma */"
)
assert_and_print(
reformat_too_long_line(
"select concat(substr(concat(')0', substr(asdf, 1, 2)), -2, 2), substr(concat('(0', substr(asdf, 3, 2)), -2, 2)) as qwer"
),
"""
select concat(substr(concat(')0', substr(asdf, 1, 2)), -2, 2),
substr(concat('(0', substr(asdf, 3, 2)), -2, 2)) as qwer
""".strip()
)
assert_and_print(
reformat_too_long_line(
" concat(substr(concat(')0', substr(asdf, 1, 2)), -2, 2), substr(concat('(0', substr(asdf, 3, 2)), -2, 2)) as qwer"
),
""" concat(substr(concat(')0', substr(asdf, 1, 2)), -2, 2),
substr(concat('(0', substr(asdf, 3, 2)), -2, 2)) as qwer"""
)
assert_and_print(
reformat_too_long_line(
" when concat('asdf', 'qwer', 'qwerqwerqwerqwerqwerqwerqwr', substr(concat('asdf', 'qwer'), 1, 2)) then 2"
),
" when concat('asdf',\n"
" 'qwer',\n"
" 'qwerqwerqwerqwerqwerqwerqwr',\n"
" substr(concat('asdf', 'qwer'), 1, 2)) then 2"
)
assert_and_print(
reformat_too_long_line(
"select case when asdf in (1234, 2345, 1234, 2354, 2345, 2352345, 245623462, 124123412,<PHONE_NUMBER>34) then 1"
),
"""
select case when asdf in (1234, 2345, 1234, 2354, 2345, 2352345, 245623462, 124123412,
124312341234) then 1
""".strip()
)
assert_and_print(
reformat_too_long_line(
"select case when asdf in (1234, 2345, 1234, 2354, 2345, 2352345, 245623462, 124123412,<PHONE_NUMBER>34) then 1",
max_len=40
),
"""
select case when asdf in (1234, 2345, 1234,
2354, 2345, 2352345,
245623462, 124123412,
124312341234) then 1
""".strip()
)
assert_and_print(
reformat_too_long_line(
"select case when asdf in ('1234', '2345', '1234', '2354', '2345', '2352345', '245623462', '124123412', '124312341234') then 1",
max_len=40
),
"""
select case when asdf in ('1234', '2345',
'1234', '2354',
'2345', '2352345',
'245623462', '124123412',
'124312341234') then 1
""".strip()
)
assert_and_print(
reformat_too_long_line("select asdf"),
"select asdf"
)
assert_and_print(
reformat_too_long_line("select asdf + asdf1 + asdf2 + asdf3 + asdf4 + asdf5 + asdf6 + asdf7 + asdf8 + asdf9"),
"select asdf + asdf1 + asdf2 + asdf3 + asdf4 + asdf5 + asdf6 + asdf7 + asdf8 + asdf9"
)
Simple usage without comments
assert_and_print(
format_select("select aSdf, cast(qweR as numeric), Asdf,qwer1"),
"select aSdf,\n cast(qweR as numeric),\n Asdf,\n qwer1"
)
More advanced usage with comments in SELECT
assert_and_print(
format_select("select asdf, cast(qwer as numeric), -- some comment[C]ASDF, qwer1"),
"select asdf,\n cast(qwer as numeric), -- some comment\n ASDF,\n qwer1"
)
assert_and_print(
format_select("select asdf, -- Some comment[C]asdforqwer -- Another comment[C]"),
"""
select asdf, -- Some comment
asdforqwer -- Another comment
""".strip()
)
Correcting common mistake on the flow: comma at end of SELECT
assert_and_print(
format_select("select qwer1, asdf,"),
"select qwer1,\n asdf"
)
assert_and_print(
format_select("SELECT a.asdf, b.qwer, -- some comment here[C][CS]/* and here is a line comment inside select */[C]qwer2"),
"""
SELECT a.asdf,
b.qwer, -- some comment here
/* and here is a line comment inside select */
qwer2
""".strip()
)
assert_and_print(
format_select("SELECT a.asdf,[CS]/* and here is a line comment inside select */"),
"""
SELECT a.asdf
/* and here is a line comment inside select */
""".strip()
)
Line comment with --
assert_and_print(
format_select("SELECT a.asdf, b.qwer, -- some comment here[C][CS]-- and here is a line comment inside select[C]qwer2"),
"""
SELECT a.asdf,
b.qwer, -- some comment here
-- and here is a line comment inside select
qwer2
""".strip()
)
Correcting comma at end of SELECT but having a comment in the last field
assert_and_print(
format_select("select qwer1 as qwer2, asdf as asdf3, -- this field"),
"select qwer1 as qwer2,\n asdf as asdf3 -- this field"
)
assert_and_print(
format_select("select qwer1, asdf, /* this field */"),
"select qwer1,\n asdf /* this field */"
)
With case when
conditions
assert_and_print(
format_select("select qwer1, case when abc = 1 then 'a' when abc = 2 then 'b' else 'c' end as qwer2"),
"""
select qwer1,
case when abc = 1 then 'a'
when abc = 2 then 'b'
else 'c' end as qwer2
""".strip()
)
assert_and_print(
format_select("select qwer1, case when abc = 1 then 'a' -- first condition[C]" +
"when abc = 2 then 'b' -- second condition[C]" +
"else 'c' end as qwer2, /* else condition */[C]"
"asdf3"
),
"""
select qwer1,
case when abc = 1 then 'a' -- first condition
when abc = 2 then 'b' -- second condition
else 'c' end as qwer2, /* else condition */
asdf3
""".strip()
)
Bad formatted case when
condition
assert_and_print(
format_select("select qwer1, case when abc <= 1 then 'a' -- first condition[C]" +
"when abc = 2 then 'b' -- second condition[C]" +
"else 'c' end as qwer2, -- else condition[C]"
"asdf3"
),
"""
select qwer1,
case when abc <= 1 then 'a' -- first condition
when abc = 2 then 'b' -- second condition
else 'c' end as qwer2, -- else condition
asdf3
""".strip()
)
case when
and comment after condition
assert_and_print(
format_select("select qwer1, case when abc <= 1 and -- first condition[C]" +
"abc >= -1 then 'a' -- second condition[C]" +
"else 'c' end as qwer2, -- else condition[C]"
"asdf3"
),
"""
select qwer1,
case when abc <= 1 and -- first condition
abc >= -1 then 'a' -- second condition
else 'c' end as qwer2, -- else condition
asdf3
""".strip()
)
case when
in comments
assert_and_print(
format_select("select qwer1, case when abc <= 1 and -- first condition case when[C]" +
"abc >= -1 then 'a' -- second condition case when[C]" +
"else 'c' end as qwer2, -- else condition[C]"
"asdf3"
),
"""
select qwer1,
case when abc <= 1 and -- first condition case when
abc >= -1 then 'a' -- second condition case when
else 'c' end as qwer2, -- else condition
asdf3
""".strip()
)
assert_and_print(
format_select("select asdf, case when asdf >= 1 and asdf <= 10 and" +
" substr(qwer, 1, 2) = 'abc' and substr(qwer, 3, 2) = 'qwerty'" +
" then 1 else 0 end as case_field, asdf2"
),
"""
select asdf,
case when asdf >= 1 and
asdf <= 10 and
substr(qwer, 1, 2) = 'abc' and
substr(qwer, 3, 2) = 'qwerty' then 1
else 0 end as case_field,
asdf2
""".strip()
)
2 case when ... end
assert_and_print(
format_select(
"select asdf, cast(case when asdf = 1 then 0 else 1 end as int) as qwer, " +
"case when asdf = 0 then 1 else 0 end as qwer2"
),
"""
select asdf,
cast(case when asdf = 1 then 0
else 1 end as int) as qwer,
case when asdf = 0 then 1
else 0 end as qwer2
""".strip()
)
With functions in SELECT
assert_and_print(
format_select("select aSdf, substr(qweR, 2) as qwer, Asdf,qwer1"),
"select aSdf,\n substr(qweR, 2) as qwer,\n Asdf,\n qwer1"
)
assert_and_print(
format_select(
"""
select car_id,
avg(price) as avg_price,
"""
),
"""
select car_id,
avg(price) as avg_price
""".strip()
)
With function in SELECT and case when
assert_and_print(
format_select("select qwer1, cast(case when asdf = 'J' then 1 else 0 end) as qwer2, qwer3"),
"""
select qwer1,
cast(case when asdf = 'J' then 1
else 0 end) as qwer2,
qwer3
""".strip()
)
assert_and_print(
format_select("select qwer1, cast(substr(case when asdf = 'CASE WHEN' then 1 else 0 end, 2, 1)) as qwer2, qwer3"),
"""
select qwer1,
cast(substr(case when asdf = 'CASE WHEN' then 1
else 0 end, 2, 1)) as qwer2,
qwer3
""".strip()
)
assert_and_print(
format_select("select qwer1, substr(qwer, case when asdf = 'J' then 1 else 0 end, 4) as qwer2, qwer3"),
"""
select qwer1,
substr(qwer, case when asdf = 'J' then 1
else 0 end, 4) as qwer2,
qwer3
""".strip()
)
assert_and_print(
format_select("select qwer1, substr('blabla', case when asdf = 'J' then 1 else 0 end, 4) as qwer2, qwer3"),
"""
select qwer1,
substr('blabla', case when asdf = 'J' then 1
else 0 end, 4) as qwer2,
qwer3
""".strip()
)
With SELECT DISTINCT
assert_and_print(
format_select("select distinct asdf, qwer, qwer2,"),
"""
select distinct asdf,
qwer,
qwer2
""".strip()
)
assert_and_print(
format_select("select distinct asdf, case when asdf = 1 then 1 else 2 end as qwerty, qwer2,"),
"""
select distinct asdf,
case when asdf = 1 then 1
else 2 end as qwerty,
qwer2
""".strip()
)
With PARTITION BY
assert_and_print(
format_select("select asdf, lead(asdf) over (partition by qwer, asdf2 order by qwer2) as qwer3, qwerty,"),
"""
select asdf,
lead(asdf) over (partition by qwer,
asdf2
order by qwer2) as qwer3,
qwerty
""".strip()
)
assert_and_print(
format_select("select asdf, lead(asdf) over (partition by asdf, qwer order by qwer), cast(qwer as numeric), -- some comment[C]ASDF, "),
"""
select asdf,
lead(asdf) over (partition by asdf,
qwer
order by qwer),
cast(qwer as numeric), -- some comment
ASDF
""".strip()
)
assert_and_print(
format_select("select asdf, lead(asdf) over (partition by asdf, qwer order by qwer, qwer2), cast(qwer as numeric), -- some comment[C]ASDF, "),
"""
select asdf,
lead(asdf) over (partition by asdf,
qwer
order by qwer, qwer2),
cast(qwer as numeric), -- some comment
ASDF
""".strip()
)
assert_and_print(
format_select("select asdf, lead(asdf, 1, 2) OVER (PARTITION BY snr, qwer ORDER BY asdf, qwer)"),
"""
select asdf,
lead(asdf, 1, 2) OVER (PARTITION BY snr,
qwer
ORDER BY asdf, qwer)
""".strip()
)
assert_and_print(
format_select("select DISTINCT asdf, lead(asdf) over (partition by asdf, qwer order by qwer), cast(qwer as numeric), -- some comment[C]ASDF, "),
"""
select DISTINCT asdf,
lead(asdf) over (partition by asdf,
qwer
order by qwer),
cast(qwer as numeric), -- some comment
ASDF
""".strip()
)
With comments within PARTITION BY
assert_and_print(
format_select("select DISTINCT asdf, lead(asdf) over (partition by asdf, -- some comment[C]qwer order by qwer), cast(qwer as numeric), -- some comment[C]ASDF, "),
"""
select DISTINCT asdf,
lead(asdf) over (partition by asdf, -- some comment
qwer
order by qwer),
cast(qwer as numeric), -- some comment
ASDF
""".strip()
)
With too long lines
assert_and_print(
format_select(
"select asdf, concat(substr(concat(')0', substr(asdf, 1, 2)), -2, 2), substr(concat('(0', substr(asdf, 3, 2)), -2, 2)) as qwer"
),
"""
select asdf,
concat(substr(concat(')0', substr(asdf, 1, 2)), -2, 2),
substr(concat('(0', substr(asdf, 3, 2)), -2, 2)) as qwer
""".strip()
)
assert_and_print(
format_select(
"select asdf, case when asdf in (1231, 123123, 12312,<PHONE_NUMBER>4,<PHONE_NUMBER>3, 12341234, 12341234, 1234) then 1 else 0 end as qwer, asdf2"
),
"""
select asdf,
case when asdf in (1231, 123123, 12312,<PHONE_NUMBER>4,<PHONE_NUMBER>3, 12341234, 12341234,
1234) then 1
else 0 end as qwer,
asdf2
""".strip()
)
Long line with in (...)
and quotes
assert_and_print(
format_select(
"select asdf, case when asdf in ('1231', '123123', '12312', '21412431234', '12341234123', '12341234', '12341234', '1234') then 1 else 0 end as qwer, asdf2"
),
"""
select asdf,
case when asdf in ('1231', '123123', '12312', '21412431234', '12341234123', '12341234',
'12341234', '1234') then 1
else 0 end as qwer,
asdf2
""".strip()
)
assert_and_print(format_from("from table1"), "from table1")
assert_and_print(format_join("inner join table1"), " inner join table1")
assert_and_print(
format_on("on a.asdf = b.asdf /* some comment */[C]"),
"""
on a.asdf = b.asdf /* some comment */
""".strip("\n")
)
assert_and_print(
format_on("on a.asdf = b.asdf and a.qwer = b.qwer"),
"""
on a.asdf = b.asdf and
a.qwer = b.qwer
""".strip("\n")
)
assert_and_print(
format_on("on a.asdf = b.asdf and a.qwer = b.qwer or a.qwer2 = b.qwer2"),
"""
on a.asdf = b.asdf and
a.qwer = b.qwer or
a.qwer2 = b.qwer2
""".strip("\n")
)
With comments and bad formatted
assert_and_print(
format_on("on a.asdf = b.asdf -- some comment[C]and a.qwer = b.qwer or /* another comment */[C]a.qwer2 = b.qwer2"),
"""
on a.asdf = b.asdf and -- some comment
a.qwer = b.qwer or /* another comment */
a.qwer2 = b.qwer2
""".strip("\n")
)
assert_and_print(
format_where(
"WHERE asdf = 1 and qwer = 1 or blabla = 'asdf'"
), "WHERE asdf = 1\n and qwer = 1\n or blabla = 'asdf'"
)
assert_and_print(
format_where(
"WHERE asdf = 1 -- and some comment[C]and qwer = 1 or blabla = 'asdf'"
), "WHERE asdf = 1 -- and some comment\n and qwer = 1\n or blabla = 'asdf'"
)
assert_and_print(
format_where(
"WHERE asdf = 1 and -- and some comment[C]qwer = 1 or blabla = 'asdf'"
), "WHERE asdf = 1 -- and some comment\n and qwer = 1\n or blabla = 'asdf'"
)
assert_and_print(
format_statement_line("select asdf, qwer"),
"""
select asdf,
qwer
""".strip())
assert_and_print(
format_statement_line("left join table1 as abc"),
" left join table1 as abc"
)
assert_and_print(
format_statement_line("where asdf = 1 and qwer = 'things' and blabla = 0 or stuff = -1"),
"""
where asdf = 1
and qwer = 'things'
and blabla = 0
or stuff = -1
""".strip())
assert_and_print(
format_statements("select asdf, qwer\nfrom table1", max_len=82),
"""
select asdf,
qwer
from table1
""".strip()
)
assert_and_print(
add_semicolon("""
CREATE OR REPLACE TABLE my_table AS
SELECT asdf,
qwer
FROM table1 /* something */
""".strip()),
"""
CREATE OR REPLACE TABLE my_table AS
SELECT asdf,
qwer
FROM table1; /* something */
""".strip()
)
assert_and_print(
add_semicolon("""
CREATE OR REPLACE TABLE my_table AS
SELECT asdf,
qwer
FROM table1 -- some thing
""".strip()),
"""
CREATE OR REPLACE TABLE my_table AS
SELECT asdf,
qwer
FROM table1; -- some thing
""".strip()
)
assert_and_print(
add_semicolon("""
CREATE OR REPLACE TABLE my_table AS
SELECT asdf,
qwer
FROM table1
""".strip()),
"""
CREATE OR REPLACE TABLE my_table AS
SELECT asdf,
qwer
FROM table1;
""".strip()
)
assert_and_print(
format_simple_sql(example_sql),
expected_sql
)
assert_and_print(
format_simple_sql(
"""
create or replace table first_table as -- my first table
select car_id,
avg(price) as avg_price,
from first_view
group by car_id
"""
),
"""
CREATE OR REPLACE TABLE first_table AS -- my first table
SELECT car_id,
avg(price) as avg_price
FROM first_view
GROUP BY car_id
""".strip()
)
This is how we could (badly) write a query with subqueries
example_with_subqueries = """
select asdf, cast(qwer as numeric), -- some comment
substr(qwer1, 3, 2) as substr_qwer /* some field */
from
(select asdf, qwer, /* some nice field */ from table1 where asdf = 1) as a
left
join (select asdf, qwer2 from table2 where qwer2 = 1) as b
on a.asdf = b.asdf
where qwer1 >= 0
"""
and this is the way we would like to have it nicely formatted
expected_with_subqueries = """
SELECT asdf,
cast(qwer as numeric), -- some comment
substr(qwer1, 3, 2) as substr_qwer /* some field */
FROM (SELECT asdf,
qwer /* some nice field */
FROM table1
WHERE asdf = 1) as a
LEFT JOIN (SELECT asdf,
qwer2
FROM table2
WHERE qwer2 = 1) as b
ON a.asdf = b.asdf
WHERE qwer1 >= 0
""".strip()
assert_and_print(
format_sql(example_with_subqueries),
expected_with_subqueries
)
It even works with simple queries without subqueries, therefore generalizing the format_simple_sql()
function
assert_and_print(
format_sql(example_sql),
expected_sql
)
example_nested_subqueries = """
select asdf, qwer
from (select a.asdf, lead(a.substr_qwer) over (partition by a.asdf, asdf2 order by qwer) as lead_qwerty
from (select asdf, substr(qwer, 3, 2) as substr_qwer from table2) as a
inner join (select asdf, qwer from table3) as b
on a.qwer = b.qwer
)
"""
expected_nested = """SELECT asdf,
qwer
FROM (SELECT a.asdf,
lead(a.substr_qwer) OVER (PARTITION BY a.asdf,
asdf2
ORDER BY qwer) as lead_qwerty
FROM (SELECT asdf,
substr(qwer, 3, 2) as substr_qwer
FROM table2) as a
INNER JOIN (SELECT asdf,
qwer
FROM table3) as b
ON a.qwer = b.qwer)"""
assert_and_print(
format_sql(example_nested_subqueries),
expected_nested
)
assert_and_print(
format_sql(
"""
select asdf, qwer from (select distinct asdf, qwer from table1)
"""
),
"""
SELECT asdf,
qwer
FROM (SELECT DISTINCT asdf,
qwer
FROM table1)
""".strip()
)
example_convoluted = """
select asdf
from (
select asdf, qwer, /* some comment */
from (select a.asdf, b.qwer, --some comment
from (select asdf
from table1) as a
right join (select qwer
from table2) as b
on a.asdf = b.asdf)
)
"""
expected_convoluted = """SELECT asdf
FROM (SELECT asdf,
qwer /* some comment */
FROM (SELECT a.asdf,
b.qwer --some comment
FROM (SELECT asdf
FROM table1) as a
RIGHT JOIN (SELECT qwer
FROM table2) as b
ON a.asdf = b.asdf))"""
assert_and_print(
format_sql(example_convoluted),
expected_convoluted
)
assert_and_print(
format_sql(
"""
select asdf,
qwer
from table1 union select qwer,
asdf, asdf2 from table3
where asdf2 >=2
"""
),
"""
SELECT asdf,
qwer
FROM table1
UNION
SELECT qwer,
asdf,
asdf2
FROM table3
WHERE asdf2 >= 2
""".strip()
)
Partition By with newline
assert_and_print(
format_sql("""
create or replace table asdf as
select asdf, qwer over (
partition by asdf, qwer order by qwerty
)
from table1
"""),
"""
CREATE OR REPLACE TABLE asdf AS
SELECT asdf,
qwer OVER (PARTITION BY asdf,
qwer
ORDER BY qwerty)
FROM table1
""".strip()
)
Too long lines query
assert_and_print(
format_sql("""
create or replace table asdf as
select asdf,
case when asdf in<PHONE_NUMBER>34,<PHONE_NUMBER>3412,<PHONE_NUMBER>34,<PHONE_NUMBER>32, 123412341, 1234) then 1 else 0 end as qwerty,
qwer over (
partition by asdf, qwer order by qwerty
)
from table1
"""),
"""
CREATE OR REPLACE TABLE asdf AS
SELECT asdf,
case when asdf in<PHONE_NUMBER>34,<PHONE_NUMBER>3412,<PHONE_NUMBER>34,<PHONE_NUMBER>32, 123412341,
1234) then 1
else 0 end as qwerty,
qwer OVER (PARTITION BY asdf,
qwer
ORDER BY qwerty)
FROM table1
""".strip()
)


What Is Yeoman
I just realized I’d never talked about some tools like Yo, Grunt or Bower so today I will fix this and I will talk about Yeoman…
First I saw on many blogs, poeple who are a bit confusing about Yeoman, Yeoman is not a scaffolding tool, it is just an installer for 3 different tools:
- Yo: This one is the scaffolding tool
- Bower: A package manager for your front end
- Grunt: A task runner
Even if Yo and Yeoman starts with the same letter it’s not a reason to mix them together ;) I think this confusion come because the same team is working on Yo and on Yeoman and moreover Yo generate configuration for bower and grunt which is some tools of Yeoman workflow. Anyway, this is close but keep thinking Yeoman is not a scaffolding tool but just a kind of workflow including awesome tools.
This post will be in 3 post, one for each tools.
Yo:
Yo is the first tool of Yeoman, this tool is a scaffolding for your application.
Let’s say you need to create a new application, for example an angular application with an expressjs server, yo will help you to startup your project, organize all your files, configure everything and even install some tools to be more productive like SASS or Coffee.
To do that, first you need to install yo with npm install -g yo
and you’re lucky because this will also install Bower and Grunt for the next parts ;)
Ok after that you need to find the right generator here. And good there is one angular-fullstack (AngularJS with an Express server), exactly what we want.
To install it, you can just run npm install -g generator-angular-fullstack
.
Now your generator is installed so we just have to generate our new app.
With the yo
command you will be able to see all the generators already installed and when you select one this will run the generator, so select the one Angular-fullstack or type directly yo angular-fullstack
.
That’s it, now you just have to answer to the questions and your application will be generate.

Yo is really an awesome tool and the list of generator is really good. For now there is 468 generators for everything, you can have a chrome extension, a worpress, a firefox os app, threejs app… really impressive, just have a look.


I am currently doing a PhD in Computer Science in France at the Laboratoire d'analyse et d'architecture des systèmes (LAAS). My main work is on Network Function Virtualization (NFV). More specifically in the multi-domain orchestration of network services. I am interested in the coordination of multiple orchestrators that have partial knowledge to support the correct execution of network services. I have work experience as a Software engineer in research projects at Samsung Research Tijuana (SRT). I supervised a team of four in a research project. Most of my work dealt with machine learning and distributed systems. Also, I was involved in many internal projects to continue education within the team such as training, seminars. I also hold a Master's Degree in Computer Science from the Instituto Nacional de Astrofísica, Óptica y Electrónica (INAOE). My thesis on bio-inspired data foraging relates the abstract notion of indirect communication with the spatial and temporal causality of events in order to identify regions of interest in an unknown and dynamic environment. My interest are: Distributed systems, formal systems, software architecture and competitive programming.
INAOE


Various Vector Visualization Verifications
Tests of the vector field (VField) package.
- Field Line Gaussian Cylinder Config
- Field Line Charged Line Config
- Field Line Dipole API
- Field Line Charged Cylinder Config
- Field Line Gaussian Sphere Config
- Field Line Gaussian Sphere Enclosing a Charge Config
- Field Line Positive Plane Config
- Simple Point Charge API
- Simple Point Charge Config
- Enable Disable Multiple Surfaces
- Simple Three Charge API
- Simple Function Config


--- title: Getting Interactive keywords: fastai sidebar: home_sidebar summary: "Making things more... fun?" description: "Making things more... fun?" nb_path: "notebooks/06_Interaction_with_ipycanvas.ipynb" ---
from ipycanvas import Canvas
canvas = Canvas(width=200, height=150)
canvas.fill_rect(25, 25, 100, 100)
canvas.clear_rect(45, 45, 60, 60)
canvas.stroke_rect(50, 50, 50, 50)
canvas
Apparently it's fast... Let's play with some perlin noise from 05.
import days_of_code
from days_of_code.perlin import *
import numpy as np
n_particles = 5_000
steps = 50
delta = 1
x = np.array(np.random.rayleigh(250, n_particles))
y = np.array(np.random.rayleigh(250, n_particles))
size = np.random.randint(1, 3, n_particles)
canvas = Canvas(width=800, height=500, sync_image_data=True)
for i in range(steps):
# Draw
canvas.fill_style = 'green'
canvas.fill_rects(x, y, size)
# Compute new locations
angles = days_of_code.perlin.perlin(x/100, y/100) * 3
x += np.sin(angles)*delta
y += np.cos(angles)*delta
canvas
canvas.to_file('outputs/perlin_ipycanvas1.png') # Saving to file requires sync_image_data=True when making the canvas
Nice! But the real fun is in making things move
from time import sleep
from ipycanvas import Canvas, hold_canvas
canvas = Canvas(width=800, height=500)
display(canvas)
x = np.array(np.random.rayleigh(250, n_particles))
y = np.array(np.random.rayleigh(250, n_particles))
size = np.random.randint(1, 3, n_particles)
for i in range(100): # while(True) for infinite
with hold_canvas(canvas):
# Clear the old animation step
canvas.clear()
canvas.fill_style = 'green'
canvas.fill_rects(x, y, size)
# Compute new locations
angles = days_of_code.perlin.perlin(x/100, y/100) * 3
x += np.sin(angles)*delta
y += np.cos(angles)*delta
# Animation frequency ~50Hz = 1./50. seconds
sleep(0.02)
I tried to add some interaction during animation with both ipycanvas' mouse events and ipevents - neither worked.  To fix this we can use the threading library to handle running the animation loop in a separate thread.
from ipywidgets import Label, HTML
from copy import deepcopy
# Setting up the canvas and event handling
canvas = Canvas(width=800, height=500)
h = HTML('Event info')
x = np.array(np.random.rayleigh(250, n_particles))
y = np.array(np.random.rayleigh(250, n_particles))
size = np.random.randint(1, 3, n_particles)
def update_canvas():
with hold_canvas(canvas):
canvas.clear() # Clear the old animation step
canvas.fill_style = 'green'
canvas.fill_rects(x, y, size) # Draw the new frame
def handle_mouse_down(xpos, ypos):
global x, y
x_new = np.array(np.random.rayleigh(30, 100))+xpos-15
y_new = np.array(np.random.rayleigh(30, 100))+ypos-15
x = np.concatenate([x[-4000:], x_new])
y = np.concatenate([y[-4000:], y_new])
size = np.random.randint(1, 3, len(x))
update_canvas()
# x = np.array(np.random.rayleigh(250, n_particles))
# y = np.array(np.random.rayleigh(250, n_particles))
# size = np.random.randint(1, 3, n_particles)
h.value = str(xpos) + '_' + str(x.shape) + '_' + str(x.shape)
# x = np.array(np.random.rayleigh(250, n_particles))
# y = np.array(np.random.rayleigh(250, n_particles))
# size = np.random.randint(1, 3, n_particles)
canvas.on_mouse_down(handle_mouse_down)
display(canvas, h)
def update():
global x, y
update_canvas()
# Compute new locations
angles = days_of_code.perlin.perlin(x/100, y/100) * 3
x += np.sin(angles)*delta
y += np.cos(angles)*delta
interval = 0.02
rt = RepeatedTimer(interval, update) # it auto-starts, no need of rt.start()
rt.stop()


| as_sass {sass} | R Documentation |
Converts multiple types of inputs to a single Sass input string for
sass
.
as_sass(input)
input |
Either a
|
Note that the LibSass compiler expects .sass files to use the Sass Indented Syntax.
a single character value to be supplied to sass
Visit https://sass-lang.com/documentation/file.SASS_REFERENCE.html#import for more details.
# Example of regular Sass input as_sass("body { color: \"blue\"; }") # There is support for adding variables as_sass( list( list(color = "blue"), "body { color: $color; }" ) ) # Add a file name someFile <- tempfile("variables") # Overwrite color to red write("$color: \"red\";", someFile) input <- as_sass( list( list(color = "blue"), sass_file(someFile), "body { color: $color; }" ) ) input # The final body color is red sass(input)


MKBarGraphView Class Reference
| Inherits from | MKGraphView : UIView |
| Declared in | MKBarGraphView.h |
Overview
MKBarGraphView is a subclass of MKGraphView. The class handels the drawing when the MKGraphTypeBar is used.
| Inherits from | MKGraphView : UIView |
| Declared in | MKBarGraphView.h |
MKBarGraphView is a subclass of MKGraphView. The class handels the drawing when the MKGraphTypeBar is used.


Image
When starting a new HTML page, it should look a bit like this:
<!DOCTYPE html>
<>

<title>The Page Title</title>
<link rel="stylesheet" src="styles.css" />

Hello, world!

I'm hidden text

This is an image:

Image

Important text
Something important

Emphasized text
Something emphasized

Small text
Something small
<big>
Big text
Something big

A comment that isn't displayed, but might be helpful next time you're reading the source code