# coding=utf-8
# !/usr/bin/env python
"""
:mod:"IKA_RV10" -- API for IKA RV10 remote controllable rotary evaporator
===================================
.. module:: IKA_RV10
:platform: Windows
:synopsis: Control IKA RV10 rotary evaporator.
.. moduleauthor:: Cronin Group 2017
(c) 2017 The Cronin Group, University of Glasgow
This provides a python class for the IKA RV 10 rotary evaporator
with IKA HB 10 heating bath.
The command implementation is not based on the manual since the
manual list different/wrong commands for the rotavap and no commands
for the bath at all. The correct commands were worked out in
correspondence with IKA and by trial and error.
For style guide used see http://xkcd.com/1513/
"""
# system imports
import re
import serial
import os
import inspect
import sys
from time import sleep, time
from threading import Event
HERE = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
sys.path.append(os.path.join(HERE, '..'))
# additional module imports
from SerialDevice.serial_labware import SerialDevice, command
[docs]class IKARV10(SerialDevice):
"""
This provides a python class for the IKA RV 10 rotary evaporator
with IKA HB 10 heating bath.
The command implementation is not based on the manual since the
manual list different/wrong commands for the rotavap and no commands
for the bath at all. The correct commands were worked out in
correspondence with IKA and by trial and error.
"""
def __init__(self, port=None, device_name=None, connect_on_instantiation=False, soft_fail_for_testing=False):
"""
Initializer of the IKARV10 class
:param str port: The port name/number of the rotavap (remember under Windows: COM15 -> port 14)
:param str device_name: A descriptive name for the device, used mainly in debug prints.
:param bool connect_on_instantiation: (optional) determines if the connection is established on instantiation of
the class. Default: Off
"""
super().__init__(port, device_name, soft_fail_for_testing)
# serial settings
self.baudrate = 9600
self.bytesize = serial.SEVENBITS
self.parity = serial.PARITY_EVEN
self.write_delay = 0.1
self.read_delay = 0.1
# answer patterns
self.stranswer = re.compile("([0-9A-Z_]+)\r\n")
self.intanswer = re.compile("(\d+) (\d)\r\n")
self.floatanswer = re.compile("(\d+\.\d+) (\d)\r\n")
# DOCUMENTED COMMANDS for easier maintenance
self.GET_ROTATION_PV = "IN_PV_4"
self.GET_ROTATION_SP = "IN_SP_4"
self.SET_ROTATION_SP = "OUT_SP_4" # 20-280 RPM
self.GET_TEMP_PV = "IN_PV_2"
self.GET_TEMP_SP = "IN_SP_2"
self.SET_TEMP_SP = "OUT_SP_2" # 0-180°C, max. T is safety temperature minus 10°C, T>90°C switches to oil mode
self.GET_SAFETY_TEMP_SP = "IN_SP_2"
self.SET_SAFETY_TEMP_SP = "OUT_SP_2"
self.START_TEMP = "START_2"
self.STOP_TEMP = "STOP_2"
self.START_ROTATION = "START_4"
self.STOP_ROTATION = "STOP_4"
self.RESET = "RESET"
self.GET_NAME = "IN_NAME"
self.SET_NAME = "OUT_NAME"
self.GET_SOFTWARE_VERSION = "IN_SOFTWARE"
self.SET_INTERVAL_SP = "OUT_SP_60" # 1-60s, "0" switches mode off
self.SET_TIMER_SP = "OUT_SP_61" # 1-199min, "0" switches mode off
self.LIFT_UP = "OUT_SP_62 1"
self.LIFT_DOWN = "OUT_SP_63 1"
self.MAX_RPM = 280
self.MAX_RETRIES = 10
self.heating_on = Event() # communicator for switching the keepalive on or off
self.launch_command_handler()
if connect_on_instantiation:
self.open_connection()
[docs] def keepalive(self):
"""
Queries heating bath temperature every 2 seconds if the heating is on to keep it alive. Overrides dummy
keepalive from parent method. This does not utilise the non_blocking_wait method because passing a property as
callback leads to unwanted behaviour (i.e. property gets read on every loop iteration, not just
every x seconds). self.last_time is initialised in the parent method.
"""
if time() >= (self.last_time + 2):
self.last_time = time()
if self.heating_on.is_set():
temp = self.temperature_pv
try:
floattemp = float(temp[0])
except Exception:
self.logger.exception("Oh noes! Something went wrong!")
else:
return None
[docs] @command
def initialise(self):
"""
Due to unspeakable firmware dumbfuckery both rotavap and heating bath only actually enter remote mode
after a start command has been sent. This method starts and stops both devices to force them into
remote mode.
:return: True if successful, False if not
"""
self.logger.debug("Initialising IKA RV10...")
try:
self.start_rotation()
self.stop_rotation()
self.start_heater()
self.stop_heater()
return True
except Exception as e:
self.logger.critical("Error while initialising rotavap: {0}".format(e))
return False
@property
@command
def rotation_speed_pv(self):
"""
Reads the process variable (i.e. the current) rpm
:return: call back to send_message with a request to return and check a value
"""
return self.send_message(self.GET_ROTATION_PV, True, self.intanswer)
@property
@command
def rotation_speed_sp(self):
"""
Reads the set point (target) for the rpm
:return: call back to send_message with a request to return and check a value
"""
return self.send_message(self.GET_ROTATION_SP, True, self.intanswer)
@rotation_speed_sp.setter
@command
def rotation_speed_sp(self, rpm=None):
"""
Sets the rotation speed and return the set point from the rotavap so the user can verify that it was successful
:param rpm: (integer) the target rotation speed of the rotavap
"""
try:
# type checking of the rotation speed that the user provided
rpm = int(rpm)
except ValueError:
raise(ValueError("Error setting rotation speed. Speed was not a valid integer: \"{0}\"".format(rpm)))
if rpm < 0 or rpm > self.MAX_RPM:
raise (ValueError("Error setting rotation speed. Speed was outside the limits: \"{0}\"".format(rpm)))
self.logger.debug("Setting rotation speed to {0} RPM...".format(rpm))
# actually sending the command
self.send_message("{0} {1}".format(self.SET_ROTATION_SP, rpm))
@property
@command
def temperature_pv(self):
# reading the process variable
return self.send_message(self.GET_TEMP_PV, True, self.floatanswer)
@property
@command
def temperature_sp(self):
return self.send_message(self.GET_TEMP_SP, True, self.floatanswer)
@temperature_sp.setter
@command
def temperature_sp(self, temperature=None):
"""
Sets the target temperature for the heating bath"
:param temperature: (float) the target temperature
"""
try:
temperature = int(temperature)
except ValueError:
raise(ValueError("Error setting temperature. Value was not a valid float \"{0}\"".format(temperature)))
self.logger.debug("Setting heating bath temperature to {0}°C...".format(temperature))
self.send_message("{0} {1}".format(self.SET_TEMP_SP, temperature))
[docs] @command
def set_interval_sp(self, interval=None):
"""
Sets the time for the interval operation. Here it rotates in one direction for a time, then reverts the
direction, and so forth.
Args:
interval (int): desired interval time in seconds. "0" deactivates interval mode.
"""
try:
interval = int(interval)
except ValueError:
raise (ValueError("Error setting interval. Value was not a valid float \"{0}\"".format(interval)))
self.logger.debug("Setting interval time to {0}°C...".format(interval))
self.send_message("{0} {1}".format(self.SET_INTERVAL_SP, interval))
[docs] @command
def start_heater(self):
self.logger.debug("Starting heater...")
self.heating_on.set()
return self.send_message(self.START_TEMP)
[docs] @command
def stop_heater(self):
self.logger.debug("Stopping heater...")
self.heating_on.clear()
return self.send_message(self.STOP_TEMP)
[docs] @command
def start_rotation(self):
self.logger.debug("Starting rotation...")
return self.send_message(self.START_ROTATION)
[docs] @command
def stop_rotation(self):
self.logger.debug("Stopping rotation...")
return self.send_message(self.STOP_ROTATION)
[docs] @command
def lift_up(self):
self.logger.debug("Lifting up...")
return self.send_message(self.LIFT_UP)
[docs] @command
def lift_down(self):
self.logger.debug("Lifting down...")
return self.send_message(self.LIFT_DOWN)
[docs] @command
def reset_rotavap(self):
self.logger.debug("Resetting rotavap...")
return self.send_message(self.RESET)
@property
@command
def name(self):
"""
Returns the name of the rotavap
:return: call back to send_message with a request to return the name
"""
return self.send_message(self.GET_NAME, True)
# setting a name doesn't seem to work
# @name.setter
# def name(self, name=None):
# """
# Sets the name of the rotavap to "name". Resets to default (self.IKA_default_name) if no name is passed.
# Warns that names longer than 6 characters get truncated upon restart of the rotavap.
# :param name: (string) the new name
# """
# if name is None:
# name = self.IKA_default_name
# if len(name) > 6:
# self.logger.debug("Warning name will be shortened to \"{}\" by the rotary evaporator after restart.".format(name[0:6]))
# self.send_message("{0} {1}".format(self.SET_NAME, name))
@property
@command
def software_version(self):
"""
Returns the software version of the firmware
!!!WARNING!!! Despite being documented this does not seem to work as intended, it just returns an empty string
:return: (supposed to...) software version of the firmware
"""
return self.send_message(self.GET_SOFTWARE_VERSION, True)
@property
@command
def safety_temp(self):
return self.send_message(self.GET_SAFETY_TEMP_SP, True, self.floatanswer)
@safety_temp.setter
@command
def safety_temp(self, temperature):
"""
Sets the safety temperature for the heating bath
:param temperature: (float) the safety temperature
"""
try:
temperature = float(temperature)
except ValueError:
raise(ValueError("Error setting heating bath temperature. Value was not a valid float \"{0}\"".format(temperature)))
self.send_message("{0} {1}".format(self.SET_SAFETY_TEMP_SP, temperature))
[docs] @command
def set_interval(self, interval):
"""
Sets the interval length in seconds for the interval mode. Setting this to 0 stops the function
:param interval: (int) the interval in seconds (1-60)
"""
try:
interval = float(interval)
except ValueError:
raise(ValueError("Error setting interval time. Value was not a valid integer \"{0}\"".format(interval)))
self.logger.debug("Setting interval time to {0}s...".format(interval))
self.send_message("{0} {1}".format(self.SET_INTERVAL_SP, interval))
[docs] @command
def set_timer(self, time_setpoint):
"""
Sets the time in minutes for the timer mode. Setting this to 0 stops the function
:param time_setpoint: (int) the time in minutes (1-199)
"""
try:
time_setpoint = float(time_setpoint)
except ValueError:
raise (ValueError("Error setting timer. Value was not a valid integer \"{0}\"".format(time_setpoint)))
self.send_message("{0} {1}".format(self.SET_TIMER_SP, time_setpoint))
if __name__ == '__main__':
rv = IKARV10(port="COM5", connect_on_instantiation=True)
sleep(1)
rv.initialise()
rv.temperature_sp = 30 # setting temperature to 30 °C
print("Temp {}".format(rv.temperature_pv))
rv.start_rotation() # starting the heater
# rv.stop_heater() # stopping heater
sleep(1)
print("Safety temp {}".format(rv.safety_temp))
print("Temp {}".format(rv.temperature_pv))
print("Speed {}".format(rv.rotation_speed_pv))
# print("Name {}".format(rv.name))
# print("Ver {}".format(rv.software_version))
while True:
pass


Hi all,
These days, smartphones are a little computers that have the possibility to put in the pocket.
Their performance increasing year by year.
I thought about which useful application may I run on it.
The idea of application to install I found in Jan C. Borchardt account, in nextcloud-scripts repository.
Today, I will describe how I ran Nextcloud on Samsung Galaxy S7 edge smartphone using Userland app.
When I have been started Userland app the first time I must choosed the Linux distro on which I want work and connection method.
I choosed Ubuntu in 18.04 version.
By default Userland app using default Android connections.
I tried check the IP address using ifconfig
command but net-tools
package has not been installed.
To be able to establish ssh connection from my MacBook I installed openssh
package.
To start ssh deamon I run sshd
command.
I checked current user using whoami
command.
On MacBook, I ran ssh <user>@<ipaddress>
command, but I was not be able to connect.
I must add a port to command to establish connection - a little help I found on GitHub portal in the following thread:
CyberpunkArmory thread
I ran the following command to prepare the environment for Nextcloud:
$ sudo apt update
$ sudo apt upgrade
I installed htop
to monitor the Galaxy S7 edge perfomance but I met an issue that I still do not solve.
$ sudo apt install htop
To be able to clone Nextcloud repository I need git
:
$ sudo apt install git
Editing files will be easier with powerful editor:
$ sudo apt install vim
The Nextcloud need php
and a few dependencies to start so I installed them:
$ sudo apt install php
$ sudo apt install php-fpm
$ sudo apt install sqlite
$ sudo apt install coreutils
$ sudo apt install openssl-tool
$ git clone https://github.com/nextcloud/server.git nextcloud
$ cd nextcloud/ && git submodule update --init
After the installation of this packages Nextcloud returned a message about incorrect php
version,
from the repository I installed 7.2
version, but the required is 7.3
version.
So I removed the packages which I installed,
and started again installing all packages in correct versions.
I edit sources.list
file and add the new repository:
deb http://ppa.launchpad.net/ondrej/php/ubuntu bionic main
deb-src http://ppa.launchpad.net/ondrej/php/ubuntu bionic main
In next step I tried update the repositories, but retrieved message with issue about Public GPG key.
The following command fix this issue:
$ apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4F4EA0AAE5267A6C
After successfully repositories update I installed the following packages:
$ sudo apt install php7.3-sqlite
$ sudo apt install php7.3-zip
$ sudo apt install php7.3-dom
$ sudo apt install php7.3-mbstring
$ sudo apt install php7.3-gd
$ sudo apt install php7.3-curl
After successfully packages installation, I start the Nextcloud using the following command:
$ php -S <IP_ADDRESS>:8080 -t /home/<user_created_during_userland_setup>/nextcloud/
The Nextcloud has been started successfully.
It is everything that I have for today.
Everyone is a blacksmith of own fate.
Mateusz.


Work Experience
Product Manager
Two Sigma
New York City, New York
Jan 2023 - Present
Sr. Product Manager
Kong
New York City, New York
Oct 2021 - Nov 2022
Product Manager
Datadog
New York City, New York
May 2020 - Sep 2021
• Led strategic planning for the Marketplace team, owning the product strategy, road map and shipping of
features, through creation of product specifications and agile development
• Grew the partner integration ecosystem by overseeing the on-boarding and development of 80+ technology
partner contributions from product specification phase to release, including the launch of go-to-market
activities
• Brought the Datadog Marketplace from ideation to go-to-market, launching an ecosystem of partner created
integrations and products that could be sold directly to customers
Product Management Intern
Datadog
New York City, New York
May 2019 - August 2019
• Led strategic planning for the containers integration team, focusing on the instrumentation and visibility
of the Datadog agent on platforms such as Kubernetes, GKE and EKS, growing adoption of the integrations by
21%
• Wrote a
specification and coordinated engineering and design work to improve the live containers page, releasing
with a go to market strategy including blog posts, dashboards, a PRFAQ and marketing material
• Conducted over 30 customer interviews, gathering insight and driving the product vision through the
creation of quarterly OKRs
Software Engineer Intern
Wave
Toronto, Canada
Jan 2019 - May 2019
A fintech startup based out of Toronto which offers financial services including accounting, invoicing,
payments and payroll.
Worked on the Developer Systems team, a team designed to improve developer efficiency, effectiveness and
education. Contributions
have inlcuded creating an internal Django web page caching package in Python3, with a built-in
metrics logging system connected to
Datadog. Have also worked extensively in optimizing Docker images on both local and production
environments to improve build times and performance.
Software Developer Intern
Zenreach
Waterloo, Canada
May 2018 - August 2018
A late stage startup which modernizes marketing for the offline world. Made the 2017
break out list, backed by venture capatalists
of the likes of Peter Thiel and Kevin Durant. Work includes
fulfilling product iniatives through creating front end features coded in
Javascript/HTML/CSS leveraging the
React framework and backend services in
Django.
Software Developer Intern
Freshbooks
Toronto, Canada
Sept 2017 - December 2017
A cloud accounting software as a service which makes accounting accessible and easy for small businesses.
Work includes implementing
product functionality and performing experiments via
A/B (split) testing. Engineered front end functionality using
Javascript/HTML/CSS in the
EmberJS framework and backend functions in
Python in the
Flask framework. Automatic tests were created using the
Cucumber mark down language and
Selenium.
Software Developer Intern
Tulip
Waterloo, Canada
May 2017 - August 2017
Tulip is an application which puts power into the sales associate's hand to assist brick and mortar stores.
Used
PHP to transform client data and write
SQL queries to insert them as defined objects to be used by the application. Also focused on the
creation
of dashboards to display key metrics and analytics on the application in vanilla
Javascript.
Software Developer Intern
VSETA
Toronto, Canada
April 2016 - August 2016
VSETA aimed at using IOT technologies, specifically iBeacons, to solve inefficiences in everyday life.
Created the mobile
app using the
Apache Cordova framework written in
Javascript/HTML/CSS. Provided an unique and end user focused experience through innovative mobile
design
patterns.
Work Term Report
Read a little more about my work experience here:
-
Datadog
-
Zenreach
-
Freshbooks
-
Tulip
School
Graduated the
Software Engineering (Co-op) program at the University of Guelph with a minor in
statistics.
Technical Skills
Languages
-
Excited about:
-
Javascript
-
Python
-
SQL
-
HTML5
-
CSS3
-
And experience with:
Frameworks
-
Have used:
- - Django
- - Flask
-
React/Redux
-
EmberJS
- - Apache Cordova
-
Node.js
-
Built on top of:
- - Kubernetes (GKE, EKS, AKS)
- - Docker
- - REST Api Design
- - MongoDB
- - MYSQL
- - iPython
Projects
Just A Bit -
Created for Hack the North 2016, at the University of Waterloo. The application detects nearby iBeacons and
gives the user
the option to donate a custom amount towards the street performer. Using
Coinbase's API, we were able to create a secure, private and effective POS system.
Veil -
Created for Guelph Hacks 2018, at the University of Guelph. Veil was a mobile application was made to solve
the problem of
providing health care information for inviduals or populations with poor or no internet access. This was
achieved did this by using the
Right Mesh API to allow P2P data transfer through a
mesh network.
Inbox Marketer Research Project -
Under the supervision of Dr. Daniel Gillis, I worked closely with a local e-mail marketing company to
investigate
their data set and generate actionable insights. Using
Tensorflow and
iPython I was able to
groom
the dataset, and train a machine learning model (Linear Regression & Recursive Neural Network) to predic the
best times to send an email during the day, per industry.
Awards
-
Just A Bit:
Winner of best use of Coinbase's API (1st)
- Hack the North 2016
-
Veil:
Winner of best use of Rightmesh's API (1st)
- Guelph Hacks 2018


command FROM SCRIPT: {{command}}
variable FROM SCRIPT: {{variable}}
colorbar FROM SCRIPT: {{colorbar}}


Before Change
def __init__(self, d_model, num_heads, pdrop, scale=True, layers=1, activation="relu", d_ff=None, name=None, **kwargs):
super(TransformerEncoderStack, self).__init__(name=name)
self.encoders = []
self.ln = LayerNorm(name="ln_out")
for i in range(layers):
self.encoders.append(TransformerEncoder(d_model, num_heads, pdrop, scale, activation, d_ff))
def call(self, inputs, mask=None):
After Change
def __init__(self, num_heads, d_model, pdrop, scale=True, layers=1, activation_type="relu", d_ff=None, name=None, **kwargs):
super().__init__(name=name)
self.encoders = []
self.ln = tf.keras.layers.LayerNormalization(epsilon=1e-6)
for i in range(layers):
self.encoders.append(TransformerEncoder(num_heads, d_model, pdrop, scale, activation_type, d_ff))
def call(self, inputs):


This documentation is intended for software developers to allow them to query the VeriSmart booking database within their own applications.
The VeriSmart Agent API (Referred to as just "API" hereafter) currently has two endpoints available.
The "Provisioning" API allows a developer to fetch and store the credentials needed in JSON format using the Agents username and password.
The "Booking" API allows you to use these credentials to fetch, and insert data in JSON format from our database.
All responses include a field of "response_status".
Response of 1 means the query is successful, and 0 means failure. If failed, the only other field will be "error", which contains the reason for failure.
All submitted data should be URL Encoded.
All responses will be JSON encoded.
All endpoints use SSL, and will not work over a normal http:// transport.
https://app.verismart.co.uk/dcal/api/v1/provisioning/
https://app.verismart.co.uk/dcal/api/v1/booking/
The Provisioning API allows you to fetch the apikey and secret.
Three fields are submitted, either via POST or GET
"devkey" - your developers key, supplied separately
"username" - Agents calendar username, usually an email address
"password" - Agents calendar password
All GET requests should be URL Encoded.
As all of our Agents currently login to the calendar and should know their login details, the recommended flow is to request their login details and use them to query the Provisioning API.
V2 of the Provisioning API will use the OAuth, or a similar system as yet to be decided.
JSON-encoded string with request_status, apikey and secret.
Line breaks added for clarity
{
"request_status":"1",
"apikey":"D15AD8F8015989F637EF53E8A1458YHR4C444B58",
"secret":"OTc2ZDg3ODFlMmU4MzRjNzBjODgwZWFmZGI4YjZFgrrtgGMyODc4MWE1NTk5Njg0NGY4ZjQxNzVjNWMxODJiZA%3D%3D"
}
You will need both the apikey and the secret to interact with the Booking API.
The booking API uses signed query strings to authenticate the request. The querystring will be signed using the secret, which is then appended to the URL before the GET request is made.
We will be signing just the query string, which contains the apikey and our requests and/or data.
An simple example query string, showing all bookings for today:
apikey=D15AD8F8015989F637EF53E8A1458YHR4C444B58&mode=show
Now we take that string, and and hash it with sha512 to produce our signature string.
In PHP:
$signature = hash_hmac("sha512", $query_string, $secret);
This signature can now be appended as "signature" to the url
In PHP:
$query_string = $query_string . '&signature=' . $signature;
And this URL can be used to query the API. The signature tells VeriSmart that this request is correctly authed, and SSL ensures the request data remains private.
A full PHP example:
$request_data = array(
'apikey' => $apikey,
'mode' => 'show'
);
$query_string = http_build_query($request_data);
$signature = hash_hmac("sha512", $query_string, $secret);
$query_string = $query_string . '&signature=' . $signature;
$result = file_get_contents($apiurl . '?' . $query_string);
The Booking API currently supports querying on specific bookings, bookings on a specific day, bookings in a specific month, and bookings on a specific property.
We will start with the most useful query type, specific property.
The mode is "property", and we are basically querying the VeriSmart database with a search.
The search fields available are
property_name - This is the building name, eg Heron Court
property_flatno - Can be numbers, letters or mixed
property_houseno - Can be numbers, letters or mixed
property_address1 - Address Line 1, traditionally the street address
property_address2 - Address Line 2, rarely used
property_town - The postal town
property_county - The postal county
property_postcode - REQUIRED
The property search will find a single property that matches the criteria, and return all of it's bookings for the authed customer. Most fields are optional, but using more data will ensure more accurate results.
Example url, linebreaks added for clarity:
?apikey=APIKEY&mode=property&property_flatno=98
&property_houseno=99&property_name=Bakewell%20Mansions
&property_address1=Bobby%20Tables%20Street&property_postcode=BH11XX&signature=SIGNATURE
All spaces in submitted postcodes are ignored, so feel free to submit with or without spaces.
To select all bookings from a specific day, the mode is "show" and you supply three fields.
The fields are:
day - numeric, 1..31
month - Month name, January...December
year - four digits, 2013
Example url:
?apikey=APIKEY&mode=show&month=April&year=2013&day=9&signature=SIGNATURE
To select all bookings from a specific month, the mode is "show" and you supply two fields.
The fields are:
month - Month name, January...December
year - four digits, 2013
Example url:
?apikey=APIKEY&mode=show&month=April&year=2013&signature=SIGNATURE
To select available slots, the mode is "slots" and you supply three fields.
The fields are
day - 1...31, day number without leading zeroes
month - Month name, January...December
year - four digits, eg 2013
Example url:
?apikey=APIKEY&mode=slots&day=8&month=April&year=2013&signature=SIGNATURE
Successful Return:
{
"request_status": "1",
"0": {
"teamid": "1506",
"team_name": "Deans Test Inventory Clerk",
"available": 1,
"status": "Available",
"available_slots": [
"Anytime",
"Morning",
"Afternoon",
"TBA",
"09:00",
"09:30",
"12:30",
"16:30",
"17:00"
]
}
}
Note that certain logins scope with more than one "team" within the VeriSmart booking system. As you can see from the json returned,this API call can return multiple teams availability.
The following fields are returned for each team record:
teamid: Unique ID for that team
team_name: Business name for that team
available: Boolean, if "0" then that team is not available that day
status: "Available" or an explanation of why the team is not available, eg "Day is full"
available_slots: an array of available slots. Slot names can be used as-is during API calls when creating bookings
The mode for creation is "create".
The following fields are accepted. Required fields are marked with an asterisk.
flat_no - Flat Number/Letter
house_no - House Number
property_name - Property Name
* address1 - First line of address, usually street name
address2 - Second line of address, generic
* town - Name of town
county - Name of County
* postcode - Postcode of property
* bedrooms - Number of bedrooms in property
* furnishings - UNFURNISHED, FURNISHED or PART-FURNISHED
garden - Yes, No, Unknown
outhouse - Yes, No, Unknown
garage - Yes, No, Unknown
* assignment - One of: INVENTORY, CHECK-IN, INTERIM, CHECK-OUT, UPDATE
* day - Day of the month, eg 1 or 16
* month - Textual month name, eg January, May
* year - Four-digit format, eg 2013, 2015
* service_time - Same as slots data, 24-format eg 09:00, 14:00
* key_location - Where are the keys, One of: Agent, Tenant, Landlord, Property, Other
contact - Contact name/number if meeting anyone
branch_id - Not used yet
comments - Free text field for any extra information
tenant_name - Required for Paperless
tenant_mobile - Required for Paperless
tenant_email - Required for Paperless
landlord_email - Optional for Paperless
ondelivery_hook_url - A full URL which the system will POST json data to, on report delivery, see below for details
Please note, VeriSmart Tenant Delivery is optional, but all three tenant_ fields are required if you do wish to have us deliver to the Tenant.
Example url:
https://app.verismart.co.uk/dcal/api/v1/booking/?apikey=APIKEY&mode=create&flat_no=9&house_no=23
&address1=bellington+gardens&town=bournemouth
&postcode=BH1+1XX&bedrooms=3&furnishings=UNFURNISHED&assignment=INVENTORY&
day=26&month=May&year=2013&service_time=Anytime&key_location=Tenant&contact=07854123456&
comments=Mind+the+dog&tenant_name=Dean+Owen&tenant_mobile=07854123456
&tenant_email=dean%40de4n.co.uk&landlord_email=noone%40surrounded.org.uk&signature=SIGNATURE
Status code, unique VeriSmart reference number
{"request_status":"1","taskid":79172}
When the supplier has uploaded the report (which sends the report as a link via email), the system will POST the following data, in json format -
taskid - Unique reference number
report_url - URL to download the report PDF
Please note your URL can include query string information, but this will be converted to JSON and included within the payload.
The POST will contain a single parameter, called "payload", which will contain the JSON data, plus a field called "custom_data" which will contain any query string data included in the hook url.
Please note, the report may be uploaded multiple times, therefore this event may fire multiple times.
{
"taskid": "123456",
"report_url": "http:\/\/ivcn.saveatree.co.uk\/333872_79564.pdf",
"custom_data": {
"mode": "new_upload",
"data": "myinternalref"
}
}


§1-12 Application of statutory construction provisions. All provisions of the Hawaii Revised Statutes relating to general statutory construction shall apply not merely to laws now in force but to all hereafter enacted, unless otherwise expressed or obviously intended. [L 1945, c 233, §4; RL 1955, §1-15; HRS §1-12]


| {{saturdayGroup.player1}} |
| {{saturdayGroup.player2}} |
| {{saturdayGroup.player3}} |
| {{saturdayGroup.player4}} |
| {{sundayGroup.player1}} |
| {{sundayGroup.player2}} |
| {{sundayGroup.player3}} |
| {{sundayGroup.player4}} |
| {{player.name}} | {{player.handicap}} |
| Rule | Description |
|---|---|
| Flights & Tournament Winner | Gross minus handicap equals net score (all ties decided by scorecard playoff starting with #1 handicap hole from day 2 scorecard) |
| Tees | White Tees |
| Improve lie | Fairway & Rough and on greens with club head only (see Below)
|
| Play ball down | Traps and hazards. |
| Clean ball | Fairway & rough and greens – replace (only applies when something foreign is visible on ball. mud etc otherwise use the Improve lie rule listed above) |
| Lost Ball | Fairway (no penalty and drop in fairway)Rough – one stroke penalty and drop in rough Traps and Hazards (one stroke penalty and drop in trap/hazard) |
| Out of Bounds |
|
| Putts | Putt out all putts. Even the ones that are “impossible to miss” |
| Scoring | Person that fills out the scorecard is responsible for reading scores off to scorer. Any discrepencies (addition errors etc.) can be addressed immediately. |


Haveibeenpwned.com pwned our helpdesk! GLPI 9.4.5 SQL Injection – fyr.io On GLPI 9.4.5, creating a call (via the standard interface or email, etc) that contains the basic SQL injection string ';-- " will be logged normally with no abnormal behaviour, however if a Technician assigns themselves to that call via the quick “Assign...
The Unattributable "Lead Hunter" Data Breach Pwned again. Damn. That's me who's pwned again because my personal data has just turned up in yet another incident from a source I can't attribute. Less than 3 weeks ago I wrote about The Unattributable "db8151dd" Data Breach which, after posting that blo...
Police are Attacking Journalists at Protests. We’re Suing. We are facing a full-scale assault on the First Amendment freedom of the press.
This German city wants to ditch Microsoft for Linux - AndroidRookies This German city wants to replace Microsoft with Linux and other open-source alternatives
Declining worker power versus rising monopoly power Since the early 1980s, the US has seen a falling labour share and slow wage growth for typical workers, while measures of corporate valuations and measured markups have increased. A number of papers have argued that increasing monopoly or monopsony power ...
Software Engineering Within SpaceX - Yasoob Khalid Hi everyone! 👋 I am sure quite a few of you must have seen the SpaceX launch this past Saturday. It was an amazing and historic event. Millions of people were watching it live on YouTube and elsewhere. With each passing day, we are getting closer to comm...
Mark Zuckerberg Believes Only in Mark Zuckerberg Why is he abetting Trump while civil rights leaders and his own employees rebuke him? It's about dominance.
Avoiding Unexpected Navigation For over twenty years, browsers broadly supported two features that were often convenient but sometimes accidentally invoked, leading to data loss. The first feature was that hitting backspace woul…
Lenovo Brings Linux® Certification to ThinkPad and ThinkStation Workstation Portfolio, Easing Deployment for Developers & Data Scientists | Lenovo StoryHub Lenovo is moving to certify the full workstation portfolio for top Linux distributions from Ubuntu® and Red Hat® – every model, every configuration.
Blazor Beyond the Browser w/ Ed Charbeneau & Daniel Roth Twitch is the world's leading video platform and community for gamers.
Building an All Terrain Vehicle for Twitch to pilot Twitch is the world's leading video platform and community for gamers.
The Rise and Fall of Commercial Smalltalk Relics Gilad Bracha recently posted an article “Bits of History, Words of Advice” that talks about the incredible influence of Smalltalk but bemoans the fact that: …today Smalltalk is relegated to a small niche of true believers. Whenever two or more Sma...
Add Black Lives Matter banner by benaadams · Pull Request #106 · dotnet-foundation/website Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
The Unattributable "Lead Hunter" Data Breach Pwned again. Damn. That's me who's pwned again because my personal data has just turned up in yet another incident from a source I can't attribute. Less than 3 weeks ago I wrote about The Unattributable "db8151dd" Data Breach which, after posting that blo...
Gleam v0.9 released! – by Otter Nonsense Version v0.9 of the Gleam programming language has been released! Let's take a look at what's new.
The Current State of OpenTelemetry in .NET In the past we’ve discussed why distributed tracing is becoming commonplace and the OpenTracing standard for instrumenting libraries and applications. In this post I want to touch on the emerging OpenTelemetry standard, which will become a common componen...
Using Currying to Pass Additional Data to React Event Handlers How to use currying to pass additional data to React event handlers
Visual Studio 2019 v16.7 Preview 2 Available Today! | Visual Studio Blog Today we are releasing 16.7 Preview 2 with new features in C++ Connection Manager, .NET Productivity, Git Productivity, and Local Process with Kubernetes.
Introducing Local Process with Kubernetes for Visual Studio 2019 | Visual Studio Blog Today, we’re proud to announce the Local Process with Kubernetes preview feature in Visual Studio 2019 16.7 Preview 2. Local Process with Kubernetes allows you to write, test and debug your .NET microservice code on your development workstation while ...
OAuth 2.0 with GitHub in ASP.NET Core - Simple Talk In this article, Diogo Souza explains how to use OAuth2 to authenticate users for GitHub in an ASP.NET Core application.
Papers with Code - The latest in machine learning Papers With Code highlights trending ML research and the code to implement it.
Running Awk in parallel to process 256M records TL;DR Awk crunches massive data; a High Performance Computing (HPC) script calls hundreds of Awk concurrently.
When police officers are told they’re in a war, they act like it "We are the action arm for a fucked-up national mindset": A CIA officer turned cop speaks out.
http://www.harbaum.org/till/nanovm/index.shtml The NanoVM is a java virtual machine for the Atmel AVR ATmega8 CPU, the member of the AVR CPU family used e.g. in the DLR Asuro robot, manufactured by AREXX engineering. With the NanoVM, the Asuro can be programmed in the popular Java language using the...
How to write a (toy) JVM Exploring JVM specification and trying to write a little code to interpret a Java class like a real JVM.
QuantumBox/blackgamedevs A list of Black game developers. Contribute to QuantumBox/blackgamedevs development by creating an account on GitHub.
Black Game Developers A list of black game developers, designers, artists, and more. Here they are. Hire them. Buy their stuff.
immuni-app/immuni-documentation Repo for Immuni's documentation. Contribute to immuni-app/immuni-documentation development by creating an account on GitHub.
TypeScript - JavaScript that scales. TypeScript brings you optional static type-checking along with the latest ECMAScript features.


Anthony Woodcroft
Home
(current)
About
Projects
Java Text Based Adventure Game
JavaScript Garage
JavaScript King Search
JavaScript FizzBuzz
JavaScript Iteration 4
JavaScript Strings 4
JavaScript DOM 1
JavaScript JSON 1
Contact
Old Home
Anthony Woodcroft
Programming Projects
JSON 1 - Super Heros
This task was to get data from a JSON file and output it to the web page.


W-projection settings.
More...
#include <types.h>
◆ W_ProjectionPars() [1/2]
| stp::W_ProjectionPars::W_ProjectionPars |
( |
| ) |
|
|
inline |
◆ W_ProjectionPars() [2/2]
| stp::W_ProjectionPars::W_ProjectionPars |
( |
int |
_num_wplanes, |
|
|
int |
_max_wpconv_support, |
|
|
int |
_undersampling_opt = 1 , |
|
|
double |
_kernel_trunc_perc = 0.0 , |
|
|
bool |
_hankel_opt = false , |
|
|
stp::InterpType |
_interp_type = stp::InterpType::LINEAR , |
|
|
bool |
_wplanes_median = false |
|
) |
| |
|
inline |
Constructor.
- Parameters
-
| [in] | _num_wplanes | (int): Number of planes for W-Projection. Set zero to disable W-projection. |
| [in] | _max_wpconv_support | (int): Defines the maximum 'radius' of the bounding box within which convolution takes place when W-Projection is used. Box width in pixels = 2*support+1. |
| [in] | _undersampling_opt | (int): Use W-kernel undersampling for faster kernel generation. Set 0 to disable undersampling and 1 to enable maximum undersampling. Reduce the level of undersampling by increasing the integer value. |
| [in] | _kernel_trunc_perc | (double): Kernel truncation percentage. |
| [in] | _hankel_opt | (bool): Use Hankel Transform (HT) optimization for quicker execution of W-Projection. Set 0 to disable HT and 1 or 2 to enable HT. The larger non-zero value increases HT accuracy, by using an extended W-kernel workarea size. |
| [in] | _interp_type | (InterpType): Select kernel interpolation type - required when using Hnakel transform approach. |
| [in] | _wplanes_median | (bool): Use median to compute w-planes, otherwise use mean. |
◆ isEnabled()
| bool stp::W_ProjectionPars::isEnabled |
( |
| ) |
const |
|
inline |
Indicates whether W-projection is enabled or not.
- Returns
- (bool): True if W-projection is enabled.
◆ hankel_opt
| bool stp::W_ProjectionPars::hankel_opt |
◆ interp_type
◆ kernel_trunc_perc
| double stp::W_ProjectionPars::kernel_trunc_perc |
◆ max_wpconv_support
| int stp::W_ProjectionPars::max_wpconv_support |
◆ num_wplanes
| int stp::W_ProjectionPars::num_wplanes |
◆ undersampling_opt
| int stp::W_ProjectionPars::undersampling_opt |
◆ wplanes_median
| bool stp::W_ProjectionPars::wplanes_median |
The documentation for this struct was generated from the following file:
- /home/lucas/skadev/FastImaging/src/stp/types.h


Version 4.0.4
Release Date: July 15, 2020
4.0.4 release of CodeIgniter4
BREAKING
Added
$arguments
parameter toafter()
andbefore()
inFilterInterface
. This is a breaking change, so all code implementing theFilterInterface
must be updated.
Enhancements
The location for the SQLite3 database has changed and by default will be now located in a
writable
folder instead of thepublic
folder.New CLI command:
cache:clear
that will destroy all data within the current cache engine.Thanks to samsonasik, we have several libraries brought up to 100% test coverage.
A few small performance increases. Every ounce matters!
getFieldData()
in the database results class now returns column type and length.Default .htaccess file updated to work better with extended characters.
New Testing Feature: Fabricator makes creating mock classes simple and repeatable in your tests.
Model class can now have the callbacks overridden at runtime. Useful for testing.
A number of improvements to Feature Tests in general.
New command() helper function to programatically run your CLI commands. Useful for testing and cron jobs.
New command,
make:seeder
to generate a Database Seed class skeleton file.Colors now available on the CLI within Windows, as well as other Windows-related CLI improvements.
New helper mb_url_title() that functions like
url_title()
but automatically escapes and extended URL characters.Image library now supports
webp
images.Added Unicode support for regular expressions in the Router.
Added support for removing hidden folders in the delete_files() helper.
fetchGlobal()
in the Request class now supports applying filters to arrays of data, not just the first item.file
validation now works with arrays of files.URI class now supports a
setSilent()
method that will disable the throwing of Exceptions.New argument to
URI::getSegment()
that allows us to change the default value returned if nothing exists.Implemented a
withResource()
in Image so that you can use method chaining instead of using the provided getResource() (used in tests). To just compress your image.Cookies and headers can be copied from the global Response object when doing a redirect using the new
withCookies()
andwithHeaders()
methods.Support for special prefix “hex2bin:” which can be used with
$key
parameter in Encryption class or in .env file.
Bugs Fixed
Fixed location for the SQLite3 database which by default will be now located in a
writable
folder instead of thepublic
folder.Fixed bug where
force_https()
could addhttps://
a second time.Fixed a bug with CurlRequest that could result in incorrect “100 Continue” headers.
Image::save() bug fixed when
$target
parameter wasnull
.fixes for
set_checkbox()
andset_radio()
when the $default parameter is set totrue
.fix for result object handling in Model class.
fixed escape character SQLite database.
fix for inserts on Postgres and Entities when the primary key was null.
CLI scripts can now correctly recognize dashes within arguments.
CURLRequest now properly sets content length with multipart data.
Misc. stability improvements for the ImageMagick handler.
setting validation errors within a config file should now work.
Unicode characters are not escaped when saving JSON from Entities.
redirecting with a custom HTTP code should work correctly now.
Time::setTimezone()
now working correctly.added full outer join support for Postgres.
some cast items in the Entity (like array, json) were not being set correctly during a
fill()
process.Fixed bug in Image GD handler that would try to compress images twice in certain cases.
Ensure get translation output logic work on selected locale, dashed locale, and fallback “en”.
Fix
is_unique
/is_not_unique
validation called on POST/PUT via API in PostgreSQL.Fixed a bug where filter arguments were not passed to
after()
.
See the repo’s CHANGELOG_4.0.md for a complete list of bugs fixed.


In my previous article, we concluded that:
To calculate estimated account value, we need to get items from these four parts:
1) The assets in wallet( And in SAVINGS)
2) The assets in internal market
3) The assets(SBD) in conversion processes
4) The assets(rewards) to be claimed
I will explain how to get them in this article.
The assets in wallet( And in SAVINGS)
The following assets need to be fetched.
- STEEM
- STEEM POWER
- STEEM DOLLARS
- STEEM in SAVINGS
- STEEM DOLLARS in SAVINGS
There is a API named get_accounts
will retrieve the account information which contained the above items.vector< extended_account > get_accounts( vector< string > names ) const;
To retrieve them we need to put the account name into list, and then call API with this list as arguments. We can read the item value from the result using the corresponding key.
| Item | Key |
|---|---|
| STEEM | balance |
| STEEM POWER | vesting_shares |
| STEEM DOLLARS | sbd_balance |
| STEEM in SAVINGS | savings_balance |
| STEEM DOLLARS in SAVINGS | savings_sbd_balance |
An additional note, STEEM POWER was expressed in the form of VESTS, we need to convert it to equivalent STEEM.
The assets in internal market
To simplify the problem, In order to simplify the problem, we define two type of operations: BUY and SELL.
- BUY: We pay SBD, and want to receive STEEM
- SELL: We pay STEEM, and want to receive SBD
So, We get the following correspondence
| Asset | How to calculate |
|---|---|
| STEEM in internal market | Remaining STEEM in all opening SELL order |
| STEEM DOLLARS in internal market | Remaining SBD in all opening BUY order |
There is a API named get_open_orders
, will return all open orders in internal market for specified account.vector<extended_limit_order> get_open_orders( string owner )const;
The example return information for my account.
We can draw the results from above information: we have 0.586 STEEM and 2 SBD in internal market.
The assets(SBD) in conversion processes
As I mentioned in previous article, if we try to convert some amount SBD to STEEM, it will disappear from the wallet. So to accurately calculate the estimated account value, we need to get this part of SBD.
Fortunately, there is a API called get_conversion_requests
.vector<convert_request_api_obj> get_conversion_requests( const string& account_name )const;
The result should like this one, We can work out the total amount of SBD easily.
The assets(rewards) to be claimed
And after HF18, users need to claim their rewards manually, so to accurately calculate the estimated account value, we need to add this part: Rewards to be claim.
The good news is we can retrieval them directly from user info, with same API get_accounts
and the same way.
| Item | Key |
|---|---|
| STEEM Reward to be claimed | reward_steem_balance |
| STEEM DOLLARS to be claimed | reward_sbd_balance |
| STEEM POWER to be claimed | reward_vesting_balance / reward_vesting_steem |
For STEEM POWER to be claimed, we can obtain it from reward_vesting_balance
or reward_vesting_steem
, but the previous one need to be converted, so the later one is better.
For detailed usage of APIs, Please refer to the steem source code on Github.
中文
上篇文章中我们得出结论，精确计算账户估值，我们需要读取：
- 钱包资产（包括存款账户）
- 内部市场资产
- 转换中的资产
- 待收取的资产
我们可以使用：get_accounts
读回钱包资产（包括存款账户）get_open_orders
读回并计算出内部市场资产get_conversion_requests
读回并计算出 转换中的资产get_accounts
读回待收取的资产
API的详细用法，请参考Github上的steem源码
This page is synchronized from the post: How to calculate estimated account value: Part Two / 如何计算账户估值：第二部分


Start Job
{{ _("Please select process to start") }}
{% for process in available_processes %}
{{ process }}
{% endfor %}


Solutions and grades for the summer assignment
The solutions of the exercises in the summer assigment are finally online (I had to wait until I was sure that no one would make a late submission for the last session of exams).
The grades are as follows: mat. 708980 is under 90 points, mat. 708980 133/150. Other submissions were previously discussed face à face.
September is very close!
The summer assignment is here to download. This assignment is for (a) all the people who have not submitted assignment number 1 and (b) all the people who desire to better the degrees they got for the 1st assignment.
Please tell me about any problem you have in understanding the text of the problems.
September is nearing
All the students that have not submitted the 1st home assignment shall submit a different home assignment, that will be posted here sometimes before friday 23th of July. Details of the submission will be given in the text of the assignment
Multiple support excitation
As a stop gap measure, i post a link to the notes of the lesson i gave in 2008-09. The material covered is the same as this year lesson, the format of the file is a bit unusual, so you need a specific plugin to read the notes
1st Home Assignment Results
I have mailed to all interested parties the file with your results. In case somebody finds a problem with the attachment, i post here the results.
Home assignment number two
The text of the second home assignment are available. You must submit your solutions when you substain your oral examination.
The corrections of the first assignment are almost finished, I'll post the results here tomorrow.
Home assignment solutions
The solutions of the first home
assignment are available [2010-06-15].
Corrections and graduations proceed slowly. I hope to
publish the results before the end of the month.
Red Alert
The first home assignment is out! The assignment is due on thursday 3rd of June and is now available here.
Introduction
The course deals with the dynamical response of mechanical systems, linear and non-linear, under the assumption of small displacements.
Focus is given to analytical and numerical methods for the integration of the equations of motion, both in time and in frequency domain, to the numerical methods for the eigen-analysis of multiple degrees of freedom systems and to earthquake engineering applications.
Classes include tutorials and computational exercises.
During the semester, you'll be given two home assignments, the first one approximately in mid may, the second at the end of the lessons. Your degree will be based on the home assignments and on a final oral exam.
The slides i use in classes will be made available on this page in a short time after the classes, but older versions of the slides are already available, as i taught the same course, more or less the same course, in the previous academic years, and if you want to peek at the material i posted during the previous year, 2008-2009, it is still on line.
Similar materials regarding the 2007-2008 course were put in the attic but are still available should you need it.
Recommended books
- Ray W,Clough, Joseph Penzien,
Dynamics of Structures.
Please note that the standard 2nd edition is out of press, but the link points to a software house that has bought the rights and issued a revised edition of the classic book by Clough and Penzien. - Anil K.Chopra,
Dynamics of Structures (Theory and Applications
to Earthquake Engineering), 3rd ed.
A number of copies of this book are available from the campus library in Lecco.
Should you find a hugely discounted used copy of the 2nd edition of prof. Chopra's book, don't worry and buy it, the 2nd ed. is good enough for our purposes.
90% of the material you'll see in the first part of the course is inspired from Clough and Penzien's book, 90% of the material of the second part of the course from Chopra's.
While it is very easy to follow the first part of the course using Chopra as your reference (the difference being in some notational convention and a more liberal use of examples in Chopra), following the second part of the course using the book from Clough and Penzien as a reference may be difficult.
In short, should you prefer to buy a single book, buy Chopra's.
Home assignments
In general, the home assignments that you're supposed to do require no more than paper, pencil and a hand-held calculatur (or a decent spreadsheet program, Excel or OpenOffice Calc the names that spring to mind...)
Of course, anything more sophisticated than Excel (think of Mathematica and Matlab, or of Matlab's free clone Octave) can be helpful.
When i work preparing and solving the assignments, my setup comprises:
- Calc, an advanced calculator and mathematical tool that runs as part of the GNU Emacs environment, that i use for its capabilities in symbolic manipulation of matrices and symbolic derivation and integration. It's not Mathematica, and it's very different from Mathematica, but it's useful and free.
- Emacs itself, the extensible, customizable, self-documenting real-time display editor.
- Scipy, a library of scientific tools for the programming language Python, i prefer using a set of libraries from inside a full blown programming language (Python) than an ad hoc one (Matlab, Octave). Of course, Matlab has different assets... (toolkits, i.e.)
- Python itself, an interpreted, interactive, object-oriented, extensible programming language.
- Gnuplot, a command-line driven interactive data and function plotting utility, for 2- and 3-D graphs, Gnuplot does also parametric plots, model fitting and something more.


EV-A enterovirus vaccine vaccines infection inactivated disease {border-style virus px;} #ffffff;} Infect human mouth protein neutralizing effective hand, infections study Asia-Pacific Dis Virol children clinical antibodies region capsid isolated mice potential China DNA attenuated caused development elicit foot px; recombinant strains subgenogroups {font-family However, associated control different font-size involvement prevention severe showed Clin Onee cause challenge circulating developed double; epidemic epidemics foot, identified lethal patients protective strain studies vaccination vaccines. Enterovirus Microbiol Res Table border-color border-width common efficacy epidemiology genetic genogroups herpangina immunization including infections. major manifestations neurological observed protect solid; {font-style {font-weight CNS Genogroup USA al.The antibody bold cases courier; em; evolutionary fatal genogroup high immune induced live-attenuated molecular outbreak outside pages particle particles previous pt;} pulmonary reported significant significantly symptoms titers transmission use vaccine. vaccines, viral virus-like


PartiQL Team
PartiQL provides an interactive shell, or Read Evaluate Print Loop (REPL), that allows users to write and evaluate PartiQL queries.
PartiQL requires the Java Runtime (JVM) to be installed on your machine. You can obtain the latest version of the Java Runtime from either
Follow the instructions on how to set JAVA_HOME
to the path where your Java Runtime is installed.
Each release of PartiQL comes with an archive that contains the PartiQL REPL as a zip file.
Assets
to see the zip and tgz archives. the latest partiql-cli
1 zip archive to your machine.├── partiql-cli
├── bin
│ ├── partiql
│ └── partiql.bat
├── lib
│ └── ...
├── README.md
└── Tutorial
├── code
│ └── ...
├── tutorial.html
└── tutorial.pdf
where ...
represents elided files/directories.
The root folder partiql-cli
contains a README.md
file and 3 subfolders
bin
contains startup scripts partiql
for macOS and Unix systems and partiql.bat
for Windows systems. Execute these files to start the REPL.lib
contains all the necessary Java libraries needed to run PartiQL.Tutorial
contains the tutorial in pdf
and html
form. The subfolder code
contains 3 types of files:
.env
. These files contains PartiQL data that we can query..sql
. These files contain the PartiQL queries used in the tutorial..output
. These files contain sample output from running the tutorial queries on the appropriate data.Run (double click on) partiql.bat
. This should open a command-line prompt and start the PartiQL REPL which displays:
Welcome to the PartiQL REPL!
PartiQL>
partiql-cli
2 folder../bin/partiql
and pressing ENTER, which displays:Welcome to the PartiQL REPL!
PartiQL>
Let’s write a simple query to verify that our PartiQL REPL is working. At the PartiQL>
prompt type:
PartiQL> SELECT * FROM [1,2,3]
and press ENTER
twice. The output should look similar to:
PartiQL> SELECT * FROM [1,2,3]
|
==='
<<
{
'_1': 1
},
{
'_1': 2
},
{
'_1': 3
}
>>
---
OK!
PartiQL>
Congratulations! You successfully installed and run the PartiQL REPL. The PartiQL REPL is now waiting for more input.
To exit the PartiQL REPL, press:
Control+D
in macOS or UnixControl+C
on Windowsor close the terminal/command prompt window.
An easy way to load the necessary data into the REPL is use the -e
switch when starting the REPL and provide the name of a file that contains your data.
./bin/partiql -e Tutorial/code/q1.env
You can then see what is loaded in the REPL’s global environment using the special REPL command !global_env
, i.e.,
Welcome to the PartiQL REPL!
PartiQL> !global_env
|
==='
{
'hr': {
'employees': <<
{
'id': 3,
'name': 'Bob Smith',
'title': NULL
},
{
'id': 4,
'name': 'Susan Smith',
'title': 'Dev Mgr'
},
{
'id': 6,
'name': 'Jane Smith',
'title': 'Software Eng 2'
}
>>
}
}
---
OK!
PartiQL provides SQL-compatible unified query access across multiple data stores containing structured, semi-structured and nested data. PartiQL separates the syntax and semantics of a query from the underlying data source and data format. It enables users to interact with data with3 or without regular schema.
This tutorial aims to teach SQL users the PartiQL extensions to SQL. The tutorial is primarily driven by “how to” examples.
For the reader who is interested in the full detail and formal specification of PartiQL, we recommend the 2-tiered PartiQL formal specification: The formal specification first describes the PartiQL core, which is a short and concise functional programming language. Then the specification layers SQL compatibility through syntactic sugar that shows how SQL features can be translated to semantically equivalent core PartiQL expressions. These translations presented as syntactic sugar enable SQL compatibility.
PartiQL is backwards compatible with SQL-924. We will see what compatibility means when it is used to query data found in data formats and data stores.
For starters, given the table hr.employees
| Id | name | title |
|---|---|---|
| 3 | Bob Smith | null |
| 4 | Susan Smith | Dev Mgr |
| 6 | Jane Smith | Software Eng 2 |
the following SQL query
SELECT e.id,
AS employeeName,
e.name AS title
e.title FROM hr.employees e
WHERE e.title = 'Dev Mgr'
is also a valid PartiQL query. As we know from SQL, when this query operates on the table hr.employees
it will return the result
| Id | employeeName | title |
|---|---|---|
| 4 | Susan Smith | Dev Mgr |
INFO
For convenience we have provided the file
tutorial-all-data.env
in the folderTutorial/code/
. You will also find separate.env
files in the same folder for each query in the tutorial.For example, running
./bin/partiql -e Tutorial/code/tutorial-all-data.env
will load all the data used in the tutorial in the REPL. This will allow you to copy-paste queries from the tutorial into the REPL and try them out.
PartiQL operate not just on SQL tables but also on data that may have nesting, union types, different attributes across different tuples, and many other features that we often find in today’s nested and/or semi-structured formats, like JSON, Ion, Parquet, etc.
To capture this generality, PartiQL is based on a logical type system: the PartiQL data model. Each PartiQL implementation maps data formats, like JSON, Parquet etc., into a PartiQL data set that follows the PartiQL data model. PartiQL queries work on the PartiQL data set abstraction.
For example, the table hr.employees
is denoted in the PartiQL data model as this dataset
{
'hr': {
'employees': <<
-- a tuple is denoted by { ... } in the PartiQL data model
{ 'id': 3, 'name': 'Bob Smith', 'title': null },
{ 'id': 4, 'name': 'Susan Smith', 'title': 'Dev Mgr' },
{ 'id': 6, 'name': 'Jane Smith', 'title': 'Software Eng 2'}
>>
}
}
Notice that the employees
is nested within hr
.
The delimiters <<
… >>
denote that the data is an unordered collection (also known as bag), as is the case with SQL tables. That is, there is no order between the three tuples. Single-line comments start with --
and end at the end of the line.
A very different kind of data source may lead to the same PartiQL dataset. For example, a set of JSON files that contain the following JSON objects
{
"hr" : {
"employees": [
{ "id": 3, "name": "Bob Smith", "title": null },
{ "id": 4, "name": "Susan Smith", "title": "Dev Mgr" },
{ "id": 6, "name": "Jane Smith", "title": "Software Eng 2"}
]
}
}
will likely5 be abstracted by a PartiQL-supporting implementation into the identical PartiQL abstraction with the hr.employees
table.
Remark: You will keep noticing the similarity of the PartiQL notation with the JSON notation. Notice also the subtle differences: In the interest of SQL compatibility, a PartiQL literal is single-quoted, while JSON literals are double-quoted.
Remark: You may conceptually think that a deserializer inputs JSON and outputs the PartiQL data set. But do not assume that the query processing of a PartiQL implementation will have to actually parse and abstract into PartiQL each and every bit of the underlying data storage.
Back to our query
SELECT e.id,
AS employeeName,
e.name AS title
e.title FROM hr.employees e
WHERE e.title = 'Dev Mgr'
Instead of a SQL result set, evaluating the query in PartiQL produces:
<<
{
'id': 4,
'employeeName': 'Susan Smith',
'title': 'Dev Mgr'
}
>>
---
OK!
the result remains the same, no matter whether hr.employees
is a SQL table or a JSON file. All that is needed is an association between the name hr.employees
and the PartiQL abstraction of the data.
In the same spirit, the same PartiQL abstraction may come from a CSV file or a Parquet file, a format that has gained big traction, thanks to the efficient way in which it stores data. Again, the same query makes perfect sense, regardless of what exactly was the storage format behind hr.employees
.
PartiQL data sets look very much like JSON.
What are the differences? Indeed, PartiQL adopts the tuple/object and array notation of JSON. However, the PartiQL string literals are denoted by single quotes. Importantly, the scalar types of PartiQL are those of SQL, not just strings, numbers and booleans, as in JSON.
Do implementations need to have a catalog?
If queries refer to names, a catalog logically validates whether the name exists or not. However, we will also see PartiQL queries that refer to no names.
SQL-92 only has tables that have tuples that contain scalar values. A key feature of many modern formats is nested data. That is, attributes whose values may themselves be tables (i.e., collections of tuples), or may be arrays of scalars, or arrays of arrays and many other combinations. Let’s take a closer look at PartiQL’s features (SQL extensions) that allow us to work with nested data.
We also include sections titled “Use Case”. Such “Use Case” sections do not introduce additional features. They merely show how to combine the few novel PartiQL features with standard SQL features in order to solve a large number of problems.
Let’s now add the nested attribute projects
into the data set.
{
'hr': {
'employeesNest': <<
{
'id': 3,
'name': 'Bob Smith',
'title': null,
'projects': [ { 'name': 'AWS Redshift Spectrum querying' },
{ 'name': 'AWS Redshift security' },
{ 'name': 'AWS Aurora security' }
]
},
{
'id': 4,
'name': 'Susan Smith',
'title': 'Dev Mgr',
'projects': []
},
{
'id': 6,
'name': 'Jane Smith',
'title': 'Software Eng 2',
'projects': [ { 'name': 'AWS Redshift security' } ]
}
>>
}
}
Notice that the value of 'projects'
is an array. Arrays are denoted by [ ... ]
with array elements separated by commas. In our example the array happens to be an array of tuples. We will see that arrays may be arrays of anything, not just arrays of tuples.
The following query finds the names of employees who work on projects that contain the string 'security'
and outputs them along with the name of the 'security'
project. Notice that the query has just one extension over standard SQL — the e.projects AS p
part.
SELECT e.name AS employeeName,
AS projectName
p.name FROM hr.employeesNest AS e,
AS p
e.projects WHERE p.name LIKE '%security%'
The output of our query is
<<
{
'employeeName': 'Bob Smith',
'projectName': 'AWS Redshift security'
},
{
'employeeName': 'Bob Smith',
'projectName': 'AWS Aurora security'
},
{
'employeeName': 'Jane Smith',
'projectName': 'AWS Redshift security'
}
>>
---
OK!
The extension over SQL is the FROM
clause item e.projects AS p
. Standard SQL would attempt to find a schema named e
with a table projects
and since in our example there isn’t an e.projects
table, the query would fail. In contrast, PartiQL recognizes e.projects
to refer to the projects
attribute of e
.
Once we allow this extension, the semantics are alike SQL’s. The alias (also called variable in PartiQL) e
gets bound to each employee, in turn. For each employee, the variable p
gets bound to each project of the employee, in turn. Thus the query’s meaning, like SQL, is
e
from hr.employeesNest
p
from e.projects
p.name LIKE '%security%'
e.name AS employeeName, p.name AS projectName
Notice that our query involved variables that were ranging over nested collections (p
in the example), along with variables that were ranging over tables (e
in the example), as standard SQL aliases do. All variables, no matter what they range over, can be used wherever in the FROM
, WHERE
, SELECT
clauses as we will see in the examples that follow.
Can I only unnest arrays of tuples?
No, anything can be unnested. For example, arrays of scalars, etc.
Does e.projects AS p
have to appear in the same FROM
clause that defines e
?
No. For example, see below the use cases that involve subqueries. There, the e
and p
are defined in separate FROM
clauses.
How could I force e.projects
to refer to the nested attribute projects
even if there were a schema named e
with a table projects
?
Use the syntax @e.projects
. Recall, in the absence of the @
, in the interest of SQL compatibility, PartiQL will first attempt to dereference the e.projects
against the catalog.
SQL allows me to avoid writing an explicit alias e
when I write, say, e.name
. Can I avoid writing the e
in PartiQL as well?
SQL allows us to avoid writing aliases (variables) when the schema of the tables allows correct dereferencing. PartiQL does the same. However, recall, a schema is not necessary for a PartiQL data set. Indeed, our example has not assumed a schema. In the absence of a schema, you cannot omit the aliases (variables). For example, if you write just name
and there is no schema, PartiQL cannot tell whether you mean employee name or project name. Thus you need to explicitly write the alias (variable).
There is one exception to this rule: If your query has a single item in its FROM
clause, you can omit the alias (variable). Eg, you can write
SELECT name FROM hr.employeesNest
In this case it is apparent that name
may only be an employee name and thus PartiQL allows you to not provide an alias (variable).
Nevertheless, for clarity we recommend that you always use aliases (variables) and this is what this tutorial does.
If there is a schema, can I avoid writing the alias p
?
No. The p
has to be written in order to denote the iteration over the projects.
JOIN
In this section, we simply present an alternate way to express and think about unnesting collections.
One may think that the FROM
clause of the example executes, in a sense, a JOIN
between employees and projects. If it helps you to think in terms of JOIN
, you may replace the comma with JOIN
. That is, the following two queries are equivalent.
|
|
Assume that we want to write a query that returns as a bag of tuples the entire employee and project information from hr.employeesNest
. The query result we want is this bag of tuples with attributes id
, employeeName
, title
and projectName
:
<<
{
'id': 3,
'employeeName': 'Bob Smith',
'title': NULL,
'projectName': 'AWS Redshift Spectrum querying'
},
{
'id': 3,
'employeeName': 'Bob Smith',
'title': NULL,
'projectName': 'AWS Redshift security'
},
{
'id': 3,
'employeeName': 'Bob Smith',
'title': NULL,
'projectName': 'AWS Aurora security'
},
{
'id': 4,
'employeeName': 'Susan Smith',
'title': 'Dev Mgr'
},
{
'id': 6,
'employeeName': 'Jane Smith',
'title': 'Software Eng 2',
'projectName': 'AWS Redshift security'
}
>>
---
OK!
Notice that there is a 'Susan Smith'
tuple in the result, despite the fact that Susan has no project. Susan’s projectName
is null
. We can obtain this result by combining employees and projects using the LEFT JOIN
operator, as follows:
SELECT e.id AS id,
AS employeeName,
e.name AS title,
e.title AS projectName
p.name FROM hr.employeesNest AS e LEFT JOIN e.projects AS p ON true
The semantics of this query can be thought of as
e
from hr.employeesNest
e.projects
is an empty collection then // this part is special about LEFT JOINse.id AS id
, e.name AS employeeName
, e.title AS title
null AS projectName
p
from e.projects
e.id AS id
, e.name AS employeeName
, e.title AS title
The following use cases employ the unnesting features, which we have already discussed, in new use cases. A lesson that emerges is that we can use variables (SQL aliases) that range over nested data as if they were standard SQL aliases. This realization gives us the power to solve a great number of use cases just by combining the unnesting features with features we already know from standard SQL.
In our first use case we want a query that returns the names of the employees that are involved in a project that contains the word 'security'
.
In the second use case we want a query that outputs the names of the employees that have more than one security project and we are aware of a key for employees (e.g., an attribute that is guaranteed to have a unique value for each employee). We can find the requested employees by utilizing a combination of GROUP BY
and HAVING
.6 In our example, let’s assume that the id
attribute is a primary key for the employees. Then we could find the employees with more than one security project with this query:
SELECT e.name AS employeeName
FROM hr.employeesNest e,
AS p
e.projects WHERE p.name LIKE '%security%'
GROUP BY e.id, e.name
HAVING COUNT(*) > 1
which returns
<<
{
'employeeName': 'Bob Smith'
}
>>
---
OK!
Next, let’s find how many querying projects (that is, projects whose name contains the word ‘querying’) each employee has.7
Making the same asssumption as before, that id
is a key for employees, we can solve the problem with the query
SELECT e.name AS employeeName,
COUNT(p.name) AS queryProjectsNum
FROM hr.employeesNest e LEFT JOIN e.projects AS p ON p.name LIKE '%querying%'
GROUP BY e.id, e.name
that returns
<<
{
'employeeName': 'Bob Smith',
'queryProjectsNum': 1
},
{
'employeeName': 'Susan Smith',
'queryProjectsNum': 0
},
{
'employeeName': 'Jane Smith',
'queryProjectsNum': 0
}
>>
---
OK!
Notice this query’s result includes Susan Smith and Jane Smith, who have no querying projects.
A value may also be a tuple – also called object and struct in many models and formats. For example, the project value in the following tuples is always a tuple with project name and project org.
{
'hr': {
'employeesWithTuples': <<
{
'id': 3,
'name': 'Bob Smith',
'title': null,
'project': {
'name': 'AWS Redshift Spectrum querying',
'org': 'AWS'
}
},
{
'id': 6,
'name': 'Jane Smith',
'title': 'Software Eng 2',
'project': {
'name': 'AWS Redshift security',
'org': 'AWS'
}
}
>>
}
}
PartiQL’s multistep paths enable navigating within tuples. For example, the following query finds AWS projects and outputs the project name and employee name.
SELECT e.name AS employeeName,
AS projectName
e.project.name FROM hr.employeesWithTuples e
WHERE e.project.org = 'AWS'
The result is
<<
{
'employeeName': 'Bob Smith',
'projectName': 'AWS Redshift Spectrum querying'
},
{
'employeeName': 'Jane Smith',
'projectName': 'AWS Redshift security'
}
>>
---
OK!
The previous examples have shown nested attributes that were arrays of tuples. It need not be the case that the nested attributes are collections of tuples. They may just as well be arrays of scalars, arrays of arrays, or any combination of data that one can create by composing scalars, tuples and arrays. You need not learn a different set of query language features for each case. The unnesting features, which we have already seen, are sufficient.
The list of projects associated with each employee in hr.employeesNest
could have been simply a list of project name strings. Replacing the nested tuples with plain strings gives us
{
'hr': {
'employeesNestScalars': <<
{
'id': 3,
'name': 'Bob Smith',
'title': null,
'projects': [
'AWS Redshift Spectrum querying',
'AWS Redshift security',
'AWS Aurora security'
]
},
{
'id': 4,
'name': 'Susan Smith',
'title': 'Dev Mgr',
'projects': []
},
{
'id': 6,
'name': 'Jane Smith',
'title': 'Software Eng 2',
'projects': [ 'AWS Redshift security' ]
}
>>
}
}
Let us repeat the previous use cases on the revised employee data.
The following query finds the names of employees who work on projects that contain the string 'security'
and outputs them along with the name of the ‘security’ project.

The variable p
ranges (again) over the content of e.projects
. In this case, since e.projects
has strings (as opposed to tuples), the variable p
binds each time to a project name string. Thus, this query can be thought of as executing the following snippet.
e
from hr.employeesNestScalars
p
from e.projects
p
matches '%security%'
e.name AS employeeName
and the string p AS projectName
Arrays may also contain arrays, directly, without intervening tuples, as in the matrices
data set.
{
'matrices': <<
{
'id': 3,
'matrix': [
[2, 4, 6],
[1, 3, 5, 7],
[9, 0]
]
},
{
'id': 4,
'matrix': [
[5, 8],
[ ]
]
}
>>
}
The following query finds every even number and outputs the even number and the id
of the tuple where it was found.
SELECT t.id AS id,
AS even
x FROM matrices AS t,
AS y,
t.matrix AS x
y WHERE x % 2 = 0
The preceding query returns
<<
{
'id': 3,
'even': 2
},
{
'id': 3,
'even': 4
},
{
'id': 3,
'even': 6
},
{
'id': 3,
'even': 0
},
{
'id': 4,
'even': 8
}
>>
---
OK!
Informally the query’s evaluation can be thought of as
t
from matrices
y
from t.matrix
x
from y
x
is even thent.id AS id
and x AS even
Literals of the PartiQL query language correspond to the types in the PartiQL data model:
scalars, including null
which follow the SQL syntax when applicable. For example:
5
'foo'
tuples, denoted by {...}
with tuple elements separated by ,
(also known as structs and/or objects in many formats and other data models)
{ 'id' : 3, 'arr': [1, 2] }
arrays, denoted by [...]
with array elements separated by ,
[ 1, 'foo' ]
bags, denoted by << ... >>
with bag elements separated by a ,
<< 1, 'foo'>>
Notice that in the spirit of the PartiQL data model, literals compose freely and any kind of literal may appear within any tuple, array and bag literal, eg.,
{
'id': 3,
'matrix': [
[2, 4, 6],
'NA'
]
}
Many formats do not require a schema that describes the data – that is schemaless data. In such cases it is possible to have various “heterogeneities” in the data:
One tuple may have an attribute x
while another tuple may not have this attribute
In one tuple of the collection an attribute x
may be of one type, e.g., string, while in another tuple of the same collection the same attribute x
may be of a different type – e.g, array.
The elements of a collection (be it a bag or array) can be heterogeneous (not have the same type). For example, the first element may be a string, the second one may be an integer and the third one an array.
Generally, any composition is possible as we can bundle heterogeneous elements in arrays and bags.
Heterogeneities are not particular to schemaless. Schemas may allow for heterogeneity in the types of the data. For example, one of the Hive data types is the union type,8 which allows a value to belong to any one of a list of types. Consider the following schema whose projects
attribute may be either a string or an array of strings
CREATE TABLE employeesMixed(
id: INT,
name: STRING,
title: STRING,<STRING, ARRAY<STRING>>
projects: UNIONTYPE );
A collection of PartiQL tuples that follows this schema could be
{
'hr': {
'employeesMixed1': <<
{
'id': 3,
'name': 'Bob Smith',
'title': null,
'projects': [
'AWS Redshift Spectrum querying',
'AWS Redshift security',
'AWS Aurora security'
]
},
{
'id': 4,
'name': 'Susan Smith',
'title': 'Dev Mgr',
'projects': []
},
{
'id': 6,
'name': 'Jane Smith',
'title': 'Software Eng 2',
'projects': 'AWS Redshift security'
}
>>
}
}
Thus we see that data may have heterogeneities — regardless of whether they are described by a schema or not. PartiQL tackles heterogeneous data in ways that we will see in the next use cases and feature presentations.
Let’s go back to the hr.employees
table (that is, bag of tuples). Bob Smith has no title and, as is typical in SQL, the lack of title is modeled with the null
value.
{
'hr': {
'employees': <<
{ 'id': 3, 'name': 'Bob Smith', 'title': null }
{ 'id': 4, 'name': 'Susan Smith', 'title': 'Dev Mgr' }
{ 'id': 6, 'name': 'Jane Smith', 'title': 'Software Eng 2'}
>>
}
}
Nowadays, many semi-structured formats allow users to represent “missing” information in two ways.
null
.That is, we can represent the fact that Bob Smith has no title by simply having no title
attribute in the 'Bob Smith'
tuple:
{
'hr': {
'employeesWithMissing': <<
{ 'id': 3, 'name': 'Bob Smith' }, -- no title in this tuple
{ 'id': 4, 'name': 'Susan Smith', 'title': 'Dev Mgr' },
{ 'id': 6, 'name': 'Jane Smith', 'title': 'Software Eng 2'}
>>
}
}
PartiQL does not argue about when to use null
s and when to use “missing”. Myriads of datasets already use one of the two or both. However, PartiQL enables queries to distinguish between null and missing values, and also enables query results that have nulls and missing values. Indeed, PartiQL makes it very easy to propagate source data nulls as query result nulls and source data missing attributes into result missing attributes.
Consider again this PartiQL query, which happens to also be an SQL query.
SELECT e.id,
AS employeeName,
e.name AS title
e.title FROM hr.employeesWithMissing AS e
WHERE e.title = 'Dev Mgr'
What will happen when the query goes over the Bob Smith tuple, which has no title
?
The first step to answering this question is understanding the result of the path e.title
when the alias (variable) e
binds to the tuple { 'id': 3, 'name': 'Bob Smith' }
. In more basic terms, what is the result of the expression { 'id': 3, 'name': 'Bob Smith' }.title
? PartiQL says that it is the special value MISSING
. MISSING
behaves very similar to null
.
If a function (including infix functions like =
) inputs a MISSING
the function’s result is NULL
. In the case of the example, this means that the WHERE
clause e.title='Dev Mgr'
will evaluate to NULL
when e
binds to { 'id': 3, 'name': 'Bob Smith' }
and, as usual in SQL, the WHERE
clause fails when it does not evaluate to true
. Thus the output will be
<<
{
'id': 4,
'employeeName': 'Susan Smith',
'title': 'Dev Mgr'
}
>>
---
OK!
What would happen if a missing attribute or, more generally, an expression returning MISSING
appears in the SELECT
?
SELECT e.id,
AS employeeName,
e.name AS outputTitle
e.title FROM hr.employeesWithMissing AS e
The query will output one tuple for each employee. When it outputs the Bob Smith tuple, the e.title
will evaluate to NULL
and then the output tuple will not have an outputTitle
attribute.
<<
{
'id': 3,
'employeeName': 'Bob Smith'
},
{
'id': 4,
'employeeName': 'Susan Smith',
'outputTitle': 'Dev Mgr'
},
{
'id': 6,
'employeeName': 'Jane Smith',
'outputTitle': 'Software Eng 2'
}
>>
---
OK!
The same treatment of MISSING
would happen if, say, we had this query that converts titles to capital letters:
SELECT e.id,
AS employeeName,
e.name UPPER(e.title) AS outputTitle
FROM hr.employeesWithMissing AS e
Again, the e.title
will evaluate to MISSING
for 'Bob Smith'
, the UPPER(e.title)
is then UPPER(MISSING)
and also evaluates to NULL
. Thus the result will be:
<<
{
'id': 3,
'employeeName': 'Bob Smith',
'outputTitle': NULL
},
{
'id': 4,
'employeeName': 'Susan Smith',
'outputTitle': 'DEV MGR'
},
{
'id': 6,
'employeeName': 'Jane Smith',
'outputTitle': 'SOFTWARE ENG 2'
}
>>
---
OK!
A PartiQL variable (called alias in SQL) can bind to data of different types during a query’s evaluation. This is unlike SQL where the variables always bind to tuples. It is even different from what happened in Use Case: Unnesting Arrays of Scalars and what happened in Use Case: Unnesting Arrays of Arrays.
In the first use case, the PartiQL variable p
happened to always bind to a string (given the particular sample data of the example). In the second use case, the PartiQL variable y
was always bound to an array (again, given the particular sample data of the example).
To make the case for variables that bind to different types, consider the following twist in the employeesNest
data set. Some of the elements of the projects
array are plain strings and some are tuples. Even the employee tuples do not always have the same attributes.
{
'hr': {
'employeesMixed2': <<
{
'id': 3,
'name': 'Bob Smith',
'title': null,
'projects': [
{ 'name': 'AWS Redshift Spectrum querying' },
'AWS Redshift security',
{ 'name': 'AWS Aurora security' }
]
},
{
'id': 4,
'name': 'Susan Smith',
'title': 'Dev Mgr',
'projects': []
},
{
'id': 6,
'name': 'Jane Smith',
'projects': [ 'AWS Redshift security']
}
>>
}
}
This query on hr.employeesMixed2
produces employee name – employee project pairs.
 The IS
operator can be used to check a value against its type at evaluation time. Notice also that the variable p
binds to different types.
In general, the FROM
clause of a query binds its variables (aliases) to data. The variables need not bind to data that have the same types. Each binding is fed to the SELECT
clause, which evaluates its expressions.
This table shows each variables’ binding produced by the FROM
clause and the corresponding tuple output by the SELECT
clause.
Variable e |
Variable p |
Result tuple |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
SQL allows us to order the output of a query using the ORDER BY
clause. However, the SQL data model does not recognize order in the input data. In contrast, many of the new data formats feature arrays; the arrays’ elements have an order. We may want to find an array element by its index or, we may want to find the positions of certain elements in their arrays.
<Array> [<number>]
Let’s consider again the dataset hr.employeesNest
.
{
'hr': {
'employeesNest': <<
{
'id': 3,
'name': 'Bob Smith',
'title': null,
'projects': [ { 'name': 'AWS Redshift Spectrum querying' },
{ 'name': 'AWS Redshift security' },
{ 'name': 'AWS Aurora security' }
]
},
{
'id': 4,
'name': 'Susan Smith',
'title': 'Dev Mgr',
'projects': []
},
{
'id': 6,
'name': 'Jane Smith',
'title': 'Software Eng 2',
'projects': [ { 'name': 'AWS Redshift security' } ]
}
>>
}
}
The projects
attribute is an array of tuples; that is, each tuple has an ordinal associated with it. The following query returns each employee name, along with the first project of the employee.
SELECT e.name AS employeeName,
0].name AS firstProjectName
e.projects[FROM hr.employeesNest AS e
The query returns
<<
{
'employeeName': 'Bob Smith',
'firstProjectName': 'AWS Redshift Spectrum querying'
},
{
'employeeName': 'Susan Smith'
},
{
'employeeName': 'Jane Smith',
'firstProjectName': 'AWS Redshift security'
}
>>
---
OK!
Technically, the structure [<number>]
is a kind of path step. For example, notice the 4-step path e.projects[0].name
. When e
is bound to the first tuple of hr.employeesNest
, then the path e.projects
results into the array
[
{ 'name': 'AWS Redshift Spectrum querying' },
{ 'name': 'AWS Redshift security' },
{ 'name': 'AWS Aurora security' }
]
Consequently applying the [0]
step on e.projects
(that is, evaluating e.projects[0]
) leads to {'name': 'AWS Redshift Spectrum querying'}
. Finally, evaluating the .name
step on e.projects[0]
(that is, evaluating e.projects[0].name
) leads to 'AWS Redshift Spectrum querying'
.
Let’s assume that each employees’ projects are sorted in priority order. The following query finds the names of each employee involved in a security project, the security project, and, its index in the projects
array.
SELECT e.name AS employeeName,
AS projectName,
p.name AS projectPriority
o FROM hr.employeesNest AS e,
AS p AT o
e.projects WHERE p.name LIKE '%security%'
Notice the new feature: AT o
. While p
ranges over the elements of the array e.projects
, the variable o
is assigned to the index of the element in the array. The query returns:
<<
{
'employeeName': 'Bob Smith',
'projectName': 'AWS Redshift security',
'projectPriority': 1
},
{
'employeeName': 'Bob Smith',
'projectName': 'AWS Aurora security',
'projectPriority': 2
},
{
'employeeName': 'Jane Smith',
'projectName': 'AWS Redshift security',
'projectPriority': 0
}
>>
---
OK!
Many queries need to range over and collect the attribute name/value pairs of tuples or the key/value pairs of maps.
Consider this dataset that provides the closing prices of multiple ticker symbols.
{
'closingPrices': <<
{ 'date': '4/1/2019', 'amzn': 1900, 'goog': 1120, 'fb': 180 },
{ 'date': '4/2/2019', 'amzn': 1902, 'goog': 1119, 'fb': 183 }
>>
}
The following query unpivots the stock ticker/price pairs.
SELECT c."date" AS "date",
AS "symbol",
sym AS price
price FROM closingPrices AS c,
AS price AT sym
UNPIVOT c WHERE NOT sym = 'date'
Notice the use of "
in this query. The double quotes allow us to disambiguate from date
the keyword and "date"
the identifier. Double quotes can also specify case sensitivity for attribute lookups.
The query returns
<<
{
'date': '4/1/2019',
'symbol': 'amzn',
'price': 1900
},
{
'date': '4/1/2019',
'symbol': 'goog',
'price': 1120
},
{
'date': '4/1/2019',
'symbol': 'fb',
'price': 180
},
{
'date': '4/2/2019',
'symbol': 'amzn',
'price': 1902
},
{
'date': '4/2/2019',
'symbol': 'goog',
'price': 1119
},
{
'date': '4/2/2019',
'symbol': 'fb',
'price': 183
}
>>
---
OK!
Unpivoting tuples enables the use of attribute names as if they were data. For example, it becomes easy to compute the average price for each symbol as
SELECT sym AS "symbol",
AVG(price) AS avgPrice
FROM closingPrices c,
AS price AT sym
UNPIVOT c WHERE NOT sym = 'date'
GROUP BY sym
which returns
<<
{
'symbol': 'amzn',
'avgPrice': 1901
},
{
'symbol': 'fb',
'avgPrice': 181.5
},
{
'symbol': 'goog',
'avgPrice': 1119.5
}
>>
---
OK!
Pivoting turns a collection into a tuple. For example, consider the collection
{
'todaysStockPrices': <<
{ 'symbol': 'amzn', 'price': 1900},
{ 'symbol': 'goog', 'price': 1120},
{ 'symbol': 'fb', 'price': 180 }
>>
}
Then the following PIVOT
query
AT sp."symbol"
PIVOT sp.price FROM todaysStockPrices sp
produces the tuple
{
'amzn': 1900,
'goog': 1120,
'fb': 180
}
---
OK!
Notice that the PIVOT
query looks like a SELECT-FROM-WHERE-...
query except that instead of a SELECT
clause it has a PIVOT <value expression> AT <attribute expression>
. Note also that the PIVOT
query does not return a collection of tuples: rather it literally returns a tuple value.
(This example also uses the grouping features of PartiQL, Creating Nested Results with GROUP BY
… GROUP AS
.)
Let us generalize the previous case of pivoting. We have a table of stock prices
{
'stockPrices':<<
{ 'date': '4/1/2019', 'symbol': 'amzn', 'price': 1900},
{ 'date': '4/1/2019', 'symbol': 'goog', 'price': 1120},
{ 'date': '4/1/2019', 'symbol': 'fb', 'price': 180 },
{ 'date': '4/2/2019', 'symbol': 'amzn', 'price': 1902},
{ 'date': '4/2/2019', 'symbol': 'goog', 'price': 1119},
{ 'date': '4/2/2019', 'symbol': 'fb', 'price': 183 }
>>
}
and we want to pivot it into a collection of tuples, where each tuple has all the symbol:price
pairs for a date, as follows
<<
{
'date': date(4/1/2019),
'prices': {'amzn': 1900, 'goog': 1120, 'fb': 180}
},
{
'date': date(4/2/2019),
'prices': {'amzn': 1902, 'goog': 1119, 'fb': 183}
}
>>
The following query first creates one group datesPrices for each date. Then the PIVOT
subquery pivots the group into the tuple prices.
SELECT sp."date" AS "date",
AT dp.sp."symbol"
(PIVOT dp.sp.price FROM datesPrices as dp ) AS prices
FROM StockPrices AS sp GROUP BY sp."date" GROUP AS datesPrices
For example, the datesPrices
collection, returned from GROUP AS
for sp.date = date(4/1/2019)
is
'datesPrices': <<
{
'sp': {
'date': '4/1/2019',
'symbol': 'amzn',
'price': 1900
}
},
{
'sp': {
'date': '4/1/2019',
'symbol': 'goog',
'price': 1120
}
},
{
'sp': {
'date': '4/1/2019',
'symbol': 'fb',
'price': 180
}
}
>>
PartiQL allows queries that create nested results as well as queries that create heterogeneous results.
SELECT VALUE
QueriesLet’s consider again the dataset hr.employeesNestScalars
:
{
'hr': {
'employeesNestScalars': <<
{
'id': 3,
'name': 'Bob Smith',
'title': null,
'projects': [
'AWS Redshift Spectrum querying',
'AWS Redshift security',
'AWS Aurora security'
]
},
{
'id': 4,
'name': 'Susan Smith',
'title': 'Dev Mgr',
'projects': []
},
{
'id': 6,
'name': 'Jane Smith',
'title': 'Software Eng 2',
'projects': [ 'AWS Redshift security' ]
}
>>
}
}
The following query outputs each tuple of hr.employeesNestScalars
, except that instead of all projects each tuple has only the security projects of the employee. The important new feature here is the SELECT VALUE <expression>
.
SELECT e.id AS id,
AS name,
e.name AS title,
e.title SELECT VALUE p
( FROM e.projects AS p
WHERE p LIKE '%security%'
AS securityProjects
) FROM hr.employeesNestScalars AS e
The result is
<<
{
'id': 3,
'name': 'Bob Smith',
'title': NULL,
'securityProjects': <<
'AWS Redshift security',
'AWS Aurora security'
>>
},
{
'id': 4,
'name': 'Susan Smith',
'title': 'Dev Mgr',
'securityProjects': <<>>
},
{
'id': 6,
'name': 'Jane Smith',
'title': 'Software Eng 2',
'securityProjects': <<
'AWS Redshift security'
>>
}
>>
---
OK!
A SELECT VALUE <expression>
query (or subquery, as in this example) returns a collection of whatever the <expression>
evaluates to.
Notice the difference from SQL’s SELECT
, which always produces tuples. If a SQL SELECT
appears as a subquery, then the context of the subquery designates whether the subquery’s result should be coerced into a scalar (e.g., when 5 = <subquery>
), coerced into a collection of scalars (e.g., when 5 IN <subquery>
), etc. None of this applies to SELECT VALUE
, which produces a collection and this collection is not coerced.
GROUP BY ... GROUP AS
Another pattern of creating nested results in PartiQL is via the GROUP AS
extension to SQL’s GROUP BY
. This pattern is more efficient and more intuitive than the use of nested SELECT VALUE
queries when the required nesting is not following the nesting of the input. (The example in Creating Nested Results with SELECT VALUE
Queries is one where the nesting in the output follows the nesting of the input and thus, an intuitive solution does not involve GROUP BY
.)
The following query outputs each security project found in hr.employeesNestScalars
along with the list of employee names that work on the project.

The GROUP AS
generalizes SQL’s GROUP BY
by making the formulated groups available in their entirety to the query’s SELECT
and HAVING
clauses. Contrast with SQL’s GROUP BY
, where the SELECT
and HAVING
clauses can have aggregate functions over grouped columns but they cannot get access to the individual values of the grouped columns.
To better understand the workings of GROUP BY ... GROUP AS
it is best to think of PartiQL queries as a pipeline of clauses, starting with the FROM
, continuing with the GROUP BY
and finishing with the SELECT
. Each clause is a function that inputs data and outputs data. In that sense, the GROUP BY ... GROUP AS
is a function that inputs the result of the FROM
and outputs its result to the SELECT
.
The following query (conceptually) produces the output of the FROM
clause.
 This is like SQL’s FROM
semantics.
Variable e |
Variable p |
|---|---|
|
|
|
|
|
|
Then the GROUP BY ... GROUP AS ...
can be thought of as outputting a table that has one column for each group-by expression (i.e., each security project p
) and a last column perProjectGroup
whose value (conceptually) is the collection of employee/project e
/p
tuples that correspond to the group-by expression p
. Thus the GROUP BY ... GROUP AS ...
output is the table
p |
perProjectGroup |
|---|---|
|
|
|
|
Finally the SELECT
clause inputs the above and outputs the query result.
The PartiQL website contains news, updates, documentation, and more information about PartiQL implementations.
We are always happy to receive your feedback as well as work with you on PartiQL.
The file will append PartiQL’s release version to the archive, i.e., partiql-cli-0.1.0.zip
.↩
The folder name will have the PartiQL version as a suffix, i.e., partiql-cli-0.1.0
.↩
The implementation currently only supports data without schema. Schema support is forthcoming.↩
The JSON value attached to employee
is an ordered list. PartiQL implementations may provide their own mappings from popular data formats, e.g., CSV, TSV, JSON, Ion etc., to the PartiQL data model and/or allow clients to implements their own mappings.↩
We could also have used the >
operator with the subquery’s result, but a current issue with the implementation currently prevents us from doing so.↩
We could also have used the >
operator with the subquery’s result, but a current issue with the implementation currently prevents us from doing so.↩


PSALMS 56
A psalm written by David for the choir director, concerning the time the Philistines seized David in Gath; to be sung using the tune "Dove on distant oaks."
1 God, act mercifully toward me because men have harassed me;
all day my enemies pursue me.
2 My enemies harass me all day long;
there are many of them who proudly attack me.
3 But whenever I am afraid,
I trust in you.
4 God, I praise you because you do what you have promised;
I trust in you, and then I am not afraid.
Ordinary humans certainly cannot harm me!
5 All day long my enemies claim that I said things that I did not say;
they are always thinking of ways to harm me.
6 In order to cause trouble for me, they hide
and watch everything that I do,
waiting for an opportunity to kill me.
7 So, God, punish them for the wicked things that they are doing;
show that you are angry by defeating those people!
8 You have counted all the times that I have been wandering alone;
it is as though you have put all my tears in a bottle
so that you can see how much I have cried.
You have counted my tears and written the number in your book.
9 When I call out to you, my God, my enemies will be defeated;
I know that will happen because you are fighting for me.
10 I praise you that you do what you have promised;
Yahweh, I will always praise you for that.
11 I trust in you, and as a result, I will not be afraid.
I know that humans cannot really harm me!
12 I will bring to you the offering that I promised;
I will bring an offering to you to thank you
13 because you have rescued me from being killed;
you have kept me from stumbling.
As a result, I will continue to live in your presence in the light that shines on those who are alive.


[gecode-users] How to get the next solution?
Mikael Zayenz Lagerkvist
zayenz at kth.se
Wed Mar 4 10:04:14 CET 2009
Hi,
A search in the mailing.list archives for getting all the solutions
gives the following:
http://search.gmane.org/search.php?group=gmane.comp.lib.gecode.user&query=getting+all+solutions
Cheers,
Mikael
2009/3/4 Jeffrey <jeffreym9 at yahoo.com.hk>:
> i would like to get all the solution for a problem.
> How to get them?
>
> Using gecode, does it mean I need to trigger the search, and then, get the
> solution, and then trigger search again, until no solution is returned?
> How to do it? Is there any example?
> ________________________________
> Yahoo!香港提供網上安全攻略，教你如何防範黑客!了解更多
> _______________________________________________
> Gecode users mailing list
> users at gecode.org
> https://www.gecode.org/mailman/listinfo/gecode-users
>
>
--
Mikael Zayenz Lagerkvist, http://www.ict.kth.se/~zayenz/
More information about the gecode-users
mailing list


|
Xerces-C++
3.1.4
|
This class represents the core information about a notation declaration that all validators must at least support. More...
Public Member Functions | |
| XMLSize_t | getId () const |
| const XMLCh * | getName () const |
| const XMLCh * | getPublicId () const |
| const XMLCh * | getSystemId () const |
| const XMLCh * | getBaseURI () const |
| unsigned int | getNameSpaceId () const |
| MemoryManager * | getMemoryManager () const |
| void | setId (const XMLSize_t newId) |
| void | setName (const XMLCh *const notName) |
| void | setPublicId (const XMLCh *const newId) |
| void | setSystemId (const XMLCh *const newId) |
| void | setBaseURI (const XMLCh *const newId) |
| void | setNameSpaceId (const unsigned int newId) |
| const XMLCh * | getKey () const |
Constructors | |
| XMLNotationDecl (MemoryManager *const manager=XMLPlatformUtils::fgMemoryManager) | |
| XMLNotationDecl (const XMLCh *const notName, const XMLCh *const pubId, const XMLCh *const sysId, const XMLCh *const baseURI=0, MemoryManager *const manager=XMLPlatformUtils::fgMemoryManager) | |
Destructor | |
| ~XMLNotationDecl () | |
| Public Member Functions inherited from XMemory | |
| void * | operator new (size_t size) |
| This method overrides operator new. More... | |
| void * | operator new (size_t size, MemoryManager *memMgr) |
| This method defines a custom operator new, that will use the provided memory manager to perform the allocation. More... | |
| void * | operator new (size_t size, void *ptr) |
| This method overrides placement operator new. More... | |
| void | operator delete (void *p) |
| This method overrides operator delete. More... | |
| void | operator delete (void *p, MemoryManager *memMgr) |
| This method provides a matching delete for the custom operator new. More... | |
| void | operator delete (void *p, void *ptr) |
| This method provides a matching delete for the placement new. More... | |
Additional Inherited Members | |
| Protected Member Functions inherited from XMemory | |
| XMemory () | |
| Protected default constructor. More... | |
This class represents the core information about a notation declaration that all validators must at least support.
Each validator will create a derivative of this class which adds any information it requires for its own extra needs.
At this common level, the information supported is the notation name and the public and sysetm ids indicated in the notation declaration.
| XMLNotationDecl::XMLNotationDecl | ( | MemoryManager *const | manager = XMLPlatformUtils::fgMemoryManager | ) |
| XMLNotationDecl::XMLNotationDecl | ( | const XMLCh *const | notName, |
| const XMLCh *const | pubId, | ||
| const XMLCh *const | sysId, | ||
| const XMLCh *const | baseURI = 0 , |
||
| MemoryManager *const | manager = XMLPlatformUtils::fgMemoryManager |
||
| ) |
| XMLNotationDecl::~XMLNotationDecl | ( | ) |
| const XMLCh * XMLNotationDecl::getBaseURI | ( | ) | const |
| XMLSize_t XMLNotationDecl::getId | ( | ) | const |
| const XMLCh * XMLNotationDecl::getKey | ( | ) | const |
| MemoryManager * XMLNotationDecl::getMemoryManager | ( | ) | const |
| const XMLCh * XMLNotationDecl::getName | ( | ) | const |
| unsigned int XMLNotationDecl::getNameSpaceId | ( | ) | const |
| const XMLCh * XMLNotationDecl::getPublicId | ( | ) | const |
| const XMLCh * XMLNotationDecl::getSystemId | ( | ) | const |
| void XMLNotationDecl::setBaseURI | ( | const XMLCh *const | newId | ) |
References MemoryManager::deallocate(), and XMLString::replicate().
| void XMLNotationDecl::setId | ( | const XMLSize_t | newId | ) |
| void XMLNotationDecl::setName | ( | const XMLCh *const | notName | ) |
| void XMLNotationDecl::setNameSpaceId | ( | const unsigned int | newId | ) |
| void XMLNotationDecl::setPublicId | ( | const XMLCh *const | newId | ) |
References MemoryManager::deallocate(), and XMLString::replicate().
| void XMLNotationDecl::setSystemId | ( | const XMLCh *const | newId | ) |
References MemoryManager::deallocate(), and XMLString::replicate().