Example 2: Dead Plant
July 13, 2017Imagine that you come home from vacation and you find that your favorite plant is dead, wilted up from lack of moisture.  But wait, you told your neighbor Mary to water it while you away, right? So who really is to blame? Let's use Etcetera Abduction to solve this problem.

These three facts are the observables in this abduction problem. We could represent these three facts as follows:
;; One possible way to represent the observables (tasked-to-water-while-away Me Mary Plant) (vacation Me) (dead Plant)
This is perfectly acceptable as first-order logic, but the first predicate "tasked-to-water-while-away" is pretty unwieldy. Conceptually, there are really two parts to the fact that we're trying to express. First, there is the real event of Me tasking Mary to do something. This really happened in the world of our problem. Second, there is the act of watering my Plant, which may or may not have happened in the world of our problem. The thing we're trying to represent as an observable is that the "something" that Mary was tasked to do was the watering of the plant.
Logicians, in the past, have invented all sorts of complicated ways to represent a "second-order" idea such as this, where the watering event is in some special modality defined by the speaking event. There's even a whole logic specially designed for obligations of this sort (deontic logic). Etcetera Abduction, however, is strictly limited to plain old first-order logic. It's actually super-restricted: it does not handle logical negation of literals, and all of the axioms must be written as definite clauses.
Fortunately, there is no need to resort to specialized logics to represent the watering task. Instead, we just need to figure out how we can make the "watering" event an actual "thing" in the world of our problem, so that we stick it can be an argument of some "tasking" literal. To do this, we're going to "reify" the watering event. This word "reify" comes from the Latin "res", meaning "thing", so instead we might say we're going to "thing-ify" the watering event.
Here's what a reified watering event might look like:
;; Reification of (water Mary Plant) (water' W Mary Plant)
In this example, we have created a new predicate water', that takes three arguments, where the first one is "W". This "W" is something we've made up to help us represent this problem in first-order logic. It's the "reificiation" of a watering event involving Mary and my Plant. We've created a new "thing" in our problem world, which is the eventuality of Mary watering my Plant. That is, "W" is a constant that is the name of a watering event that may or may not have actually happened.
Now that we have reified the event, we can stick this same "W" in as an argument of a tasking literal, as follows:
;; Another possible way to represent the observables (task Me Mary W) (water' W Mary Plant) (vacation Me) (dead Plant)
That's better. This business of "reifying" a literal turns out to be pretty useful, and has been explored thoroughly by Jerry Hobbs and Donald Davidson. Some like to call it "Davidsonian" notation, but we will use the term "eventuality notation," and adhere to a set of conventions. When representing an eventuality, we make sure that the predicate and arguments are all the same as the relation it is supposed to be reifying, with two exceptions. First, the predicate gets a new last character, an apostrophe, which distinguishes it from the predicate used in the un-refied version of the literal. Second, one more argument is added, always in the first position, which is meant to represent the reified eventuality of the event.
Eventuality notation turns out to be so useful in knowledge representation that we may want to use it in other places, as well. We may need to write axioms that rely on second-order relations between literals. For example, we may want to say that the eventuality of the death of the plant should have been a concern of Mary, or that the eventuality of me tasking her should have obligated her to actually do the task.
For this reason, we might as well represent all of the literals in our problem in eventuality notation, both the observables and in the knowledgebase. That is, every predicate will get the apostrophe at the end, and every first argument reifies an eventuality. Here's what that would look like:
;; The best way to represent the observables (task' E1 Me Mary E2) (water' E2 Mary Plant) (vacation' E3 Me) (dead' E4 Plant)
Here, each reified eventuality argument gets a unique name, composed from the capital letter "E" for the eventuality (a constant), and an integer. If there are 100 observables, we'd have "E100" as the last one. All of these observables are free to incorporate these eventualities among their own arguments, allowing for the representation of complex relational structures in plain-old first-order logic.
Next we need to provide some prior probabilities for each of these observables. In the following four prior-probability axioms, the eventuality arguments are all universally quantified variables, so that they can be matched to the constants in our observables.
;; The priors of the observables (if (etc0_task 0.1 e x y z) (task' e x y z)) (if (etc0_water 0.02 e x y) (water' e x y)) (if (etc0_vacation 0.01 e x) (vacation' e x)) (if (etc0_dead 0.01 e x) (dead' e x))
And with that, we can get our first solution to the dead plant problem by invoking the Etcetera Abduction reasoning engine:
$ python -m etcabductionpy -i dead-plant.lisp ((etc0_dead 0.01 E4 Plant) (etc0_task 0.1 E1 Me Mary E2) (etc0_vacation 0.01 E3 Me) (etc0_water 0.02 E2 Mary Plant)) 1 solutions.
Given only knowledge of prior probabilities, the best that we can come up with is that the cause of the death of the plant is simply random chance. Plants sometimes die. That was its fate. It was possible, and it happened. Bad luck. Or more accurately, the conditions of the universe were just right to cause this plant to be dead. This is what the prior probability is meant to encode.
Now let's add some knowledge that can help us come up with a better explanation. Basically, we need to encode the following commonsense intuitions:
- Plants are likely to die if nobody waters them.
- People don't do something when they can't do it.
- People sometimes forget to do the tasks they are given.
- People sometimes can't do things because they are on vacation.
- People often task other people to do something when they can't do it themselves.
There are a lot of different ways that we might encode this knowledge, at various levels of detail. For this problem, I've tried to be as consise as possible:
;; Why dead? Nobody watered (if (and (didnt' e1 y e2) (water' e2 y x) (etc1_dead 0.9 e e1 e2 x y)) (dead' e x)) ;; why didnt? couldnt (if (and (couldnt' e2 x e) (etc1_didnt 0.9 e e1 e2 x)) (didnt' e x e1)) ;; why didnt? forgot (if (and (forgot' e2 x e1) (task' e3 y x e1) (etc2_didnt 0.9 e e1 e2 e3 x y)) (didnt' e x e1)) ;; why couldnt? On vacation (if (and (vacation' e1 x) (etc1_couldnt 0.9 e e1 e2 x)) (couldnt' e x e2)) ;; why task? couldnt oneself (if (and (couldnt' e2 x e1) (etc1_task 0.9 e e1 e2 x y)) (task' e x y e1))
Lastly, we'll need to provide the prior probabilities of the three new literals that we've introduced in these axioms, namely for "didnt", "couldnt" and "forgot".
;; priors on assumptions (if (etc0_didnt 0.01 e1 y e2) (didnt' e1 y e2)) (if (etc0_couldnt 0.01 e1 y e2) (couldnt' e1 y e2)) (if (etc0_forgot 0.05 e x e1) (forgot' e x e1))
That should do it. Let's see what we get now when we run the Etcetera Abduction engine.
One million was a bit of an over-estimate: there are only 87 intepretations of the observables given our knowledge base. Let's take a look at the graph of the most probable interpretation:
Let's look at the chain of explanation leading to each of the four observed literals.
- My tasking of Mary is because I couldn't do E2, because I was on vacation, for some unknown reason.
- The eventuality of watering (E2) is for some unknown reason.
- My going on vacation is because of some unkonwn reason.
- The plant is dead because Mary didn't do E2, which is the watering of my plant. She didn't do it because she was tasked with doing it (see #1, above), but forgot. She forgot for some unkonwn reason.
In this interpretation, Mary is to blame. Her not watering the plant is the direct cause of its death. But if I hadn't tasked her with watering the plant, it would be a different story. We can see this alternative by commenting out the two observables having to do with the tasking of Mary.
;; The observables, but without the tasking of Mary ;(task' E1 Me Mary E2) ;(water' E2 Mary Plant) (vacation' E3 Me) (dead' E4 Plant)
When we graph the most probable interpretation now, a new person is to blame.
Now we have the following explanations for the observations:
- I went on vacation for some unknown reason.
- The plant is dead because I didn't water it, because I couldn't water it, because I was on vacation for some unknown reason.
In this example we can see that adding information to the situation can radically change its interpretation. In AI, this is called nonmonotonic reasoning, in that the pool of conclusions does not exclusively grow with each additional input. With abductive reasoning, the more you observe, the better your overall intepretation of the whole situation and the better your explanation for any of its component observations.
This example also highlights the importance of choosing appropriate representations for your observations and axioms. In particular, the reification of watering plants (using eventuality notation) was super-important in figuring out who was to blame for the death of the plant. When Mary is specifically asked to do so, her watering the plant can be connected to its explanation. Without this tasking, it's my not-doing-something (because of vacation) that is connected into the explantion. Both of these explanations beat the prior probabilities of the observables; its more likely that one of us is to blame, given the evidence, than attributing the death to bad luck or random chance.


UserCollectionViewCell
class UserCollectionViewCell : UICollectionViewCell, CellInterface
The purpose of ‘UserCollectionViewCell’ collectionview cell is to configure collection cell.
There’s matching scene in the UserCollectionViewCell.xib file. Go to Interface Builder for details.
The ‘UserCollectionViewCell’ class is a subclass of the ‘UICollectionViewCell’.
-
Undocumented
Declaration
Swift
@IBOutlet weak var avatarImageView: UIImageView!
-
Undocumented
Declaration
Swift
@IBOutlet weak var backgroundGradientView: UIView!
-
Undocumented
Declaration
Swift
@IBOutlet weak var nameListLabel: UILabel!
-
Undocumented
Declaration
Swift
@IBOutlet weak var nameGridLabel: UILabel!
-
Undocumented
Declaration
Swift
@IBOutlet weak var statisticLabel: UILabel!
-
Undocumented
Declaration
Swift
@IBOutlet weak var avatarImageViewWidthConstraint: NSLayoutConstraint!
-
Undocumented
Declaration
Swift
@IBOutlet weak var avatarImageViewHeightConstraint: NSLayoutConstraint!
-
Undocumented
Declaration
Swift
@IBOutlet var nameListLabelLeadingConstraint: NSLayoutConstraint! { get set }
-
Undocumented
Declaration
Swift
@IBOutlet weak var statisticLabelLeadingConstraint: NSLayoutConstraint!
-
Undocumented
Declaration
Swift
var avatarGridLayoutSize: CGFloat
-
Undocumented
Declaration
Swift
var initialLabelsLeadingConstraintValue: CGFloat
-
Undocumented
Declaration
Swift
var pictureData: [UserData]? { get set }
-
Undocumented
Declaration
Swift
var index: Int!
-
setData function is used to set data in collection view cell
Declaration
Swift
func setData()
Return Value
nil
-
Undocumented
Declaration
Swift
func setupGridLayoutConstraints(_ transitionProgress: CGFloat, cellWidth: CGFloat)
-
Undocumented
Declaration
Swift
func setupListLayoutConstraints(_ transitionProgress: CGFloat, cellWidth: CGFloat)
-
Undocumented
Declaration
Swift
override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes)


Version 0.8 (2014-06-25)#
Changelog#
Add Python3 support by Nick Ward, Alex Gramfort, Denis Engemann, and Eric Larson
Add
get_peak
method for evoked and stc objects by Denis EngemannAdd
iter_topography
function for radically simplified custom sensor topography plotting by Denis EngemannAdd field line interpolation by Eric Larson
Add full provenance tacking for epochs and improve
drop_log
by Tal Linzen, Alex Gramfort and Denis EngemannAdd systematic contains method to
Raw
,Epochs
andEvoked
for channel type membership testing by Denis EngemannAdd fiff unicode writing and reading support by Denis Engemann
Add 3D MEG/EEG field plotting function and evoked method by Denis Engemann and Alex Gramfort
Add consistent channel-dropping methods to
Raw
,Epochs
andEvoked
by Denis Engemann and Alex GramfortAdd
equalize_channnels
function to set common channels for a list ofRaw
,Epochs
, orEvoked
objects by Denis EngemannAdd
plot_events
function to visually display paradigm by Alex GramfortImproved connectivity circle plot by Martin Luessi
Add ability to anonymize measurement info by Eric Larson
Add callback to connectivity circle plot to isolate connections to clicked nodes Roan LaPlante
Add ability to add patch information to source spaces by Eric Larson
Add
split_label
function to divide labels into multiple parts by Christian BrodbeckAdd
color
attribute toLabel
objects by Christian BrodbeckAdd
max
mode forextract_label_time_course
by Mads JensenAdd
rename_channels
function to change channel names and types in info object by Dan Wakeman and Denis EngemannAdd
compute_ems
function to extract the time course of experimental effects by Denis Engemann, Sébastien Marti and Alex GramfortAdd option to expand Labels defined in a source space to the original surface (
Label.fill()
) by Christian BrodbeckGUIs can be invoked form the command line using
$ mne coreg
and$ mne kit2fiff
by Christian BrodbeckAdd
add_channels_epochs
function to combine different recordings at the Epochs level by Christian Brodbeck and Denis EngemannAdd support for EGI Netstation simple binary files by Denis Engemann
Add support for treating arbitrary data (numpy ndarray) as a Raw instance by Eric Larson
Support for parsing the EDF+ annotation channel by Martin Billinger
Add EpochsArray constructor for creating epochs from numpy arrays by Denis Engemann and Federico Raimondo
Add connector to FieldTrip realtime client by Mainak Jas
Add color and event_id with legend options in plot_events in viz.py by Cathy Nangini
Add
events_list
parameter tomne.concatenate_raws
to concatenate events corresponding to runs by Denis EngemannAdd
read_ch_connectivity
function to read FieldTrip neighbor template .mat files and obtain sensor adjacency matrices by Denis EngemannAdd display of head in helmet from -trans.fif file to check coregistration quality by Mainak Jas
Add
raw.add_events
to allow adding events to a raw file by Eric LarsonAdd
plot_image
method to Evoked object to display data as images by Jean-Remi King and Alex Gramfort and Denis EngemannAdd BCI demo with CSP on motor imagery by Martin Billinger
New ICA API with unified methods for processing
Raw
,Epochs
andEvoked
objects by Denis EngemannApply ICA at the evoked stage by Denis Engemann
New ICA methods for visualizing unmixing quality, artifact detection and rejection by Denis Engemann
Add
pick_channels
anddrop_channels
mixin class to pick and drop channels fromRaw
,Epochs
, andEvoked
objects by Andrew Dykstra and Denis EngemannAdd
EvokedArray
class to create an Evoked object from an array by Andrew DykstraAdd
plot_bem
method to visualize BEM contours on MRI anatomical images by Mainak Jas and Alex GramfortAdd automated ECG detection using cross-trial phase statistics by Denis Engemann and Juergen Dammers
Add Forward class to succinctly display gain matrix info by Andrew Dykstra
Add reading and writing of split raw files by Martin Luessi
Add OLS regression function by Tal Linzen, Teon Brooks and Denis Engemann
Add computation of point spread and cross-talk functions for MNE type solutions by Alex Gramfort and Olaf Hauk
Add mask parameter to
plot_evoked_topomap
andevoked.plot_topomap
by Denis Engemann and Alex GramfortAdd infomax and extended infomax ICA by Denis Engemann, Juergen Dammers and Lukas Breuer and Federico Raimondo
Aesthetically redesign interpolated topography plots by Denis Engemann and Alex Gramfort
Simplify sensor space time-frequency analysis API with
tfr_morlet
function by Alex Gramfort and Denis EngemannAdd new somatosensory MEG dataset with nice time-frequency content by Alex Gramfort
Add HDF5 write/read support for SourceEstimates by Eric Larson
Add InverseOperator class to display inverse operator info by Mainak Jas
Add
$ mne report
command to generate html reports of MEG/EEG data analysis pipelines by Mainak Jas, Alex Gramfort and Denis EngemannImprove ICA verbosity with regard to rank reduction by Denis Engemann
BUG#
Fix incorrect
times
attribute when stc was computed usingapply_inverse
after decimation at epochs stage for certain, arbitrary sample frequencies by Denis EngemannFix corner case error for step-down-in-jumps permutation test (when step-down threshold was high enough to include all clusters) by Eric Larson
Fix selection of total number of components via float when picking ICA sources by Denis Engemann and Qunxi Dong
Fix writing and reading transforms after modification in measurement info by Denis Engemann and Martin Luessi and Eric Larson
Fix pre-whitening / rescaling when estimating ICA on multiple channels without covariance by Denis Engemann
Fix ICA pre-whitening, avoid recomputation when applying ICA to new data by Denis Engemann
API#
The minimum numpy version has been increased to 1.6 from 1.4.
Epochs object now has a selection attribute to track provenance of selected Epochs. The length of the drop_log attribute is now the same as the length of the original events passed to Epochs. In earlier versions it had the length of the events filtered by event_id. Epochs has also now a plot_drop_log method.
Deprecate Epochs.drop_picks in favor of a new method called drop_channels
Deprecate
labels_from_parc
andparc_from_labels
in favor ofread_labels_from_annot
andwrite_labels_to_annot
The default of the new add_dist option of
setup_source_space
to add patch information will change from False to True in MNE-Python 0.9Deprecate
read_evoked
andwrite_evoked
in favor ofread_evokeds
andwrite_evokeds
. read_evokeds will return allEvoked
instances in a file by default.Deprecate
setno
in favor ofcondition
in the initialization of an Evoked instance. This affectsmne.fiff.Evoked
andread_evokeds
, but notread_evoked
.Deprecate
mne.fiff
module, usemne.io
instead e.g.mne.io.Raw
instead ofmne.fiff.Raw
.Pick functions (e.g.,
pick_types
) are now in the mne namespace (e.g. usemne.pick_types
).Deprecated ICA methods specific to one container type. Use ICA.fit, ICA.get_sources ICA.apply and
ICA.plot_*
for processing Raw, Epochs and Evoked objects.The default smoothing method for
mne.stc_to_label
will change in v0.9, and the old method is deprecated.As default, for ICA the maximum number of PCA components equals the number of channels passed. The number of PCA components used to reconstruct the sensor space signals now defaults to the maximum number of PCA components estimated.


Tests:
not multiselectable
1
2
not multiselectable 2
1
2
is multiselectable
1
2
is multiselectable
1
2


async |
Boolean
|
<optional>
|
false
|
Pixel change detection will be sent to a libuv worker thread. |
difference |
Number
|
<optional>
|
5
|
Pixel difference value 1 to 255 |
percent |
Number
|
<optional>
|
5
|
Percent of pixels that exceed difference value. |
regions |
Array
|
<optional>
|
|
Array of regions. |
regions[i].name |
String
|
|
|
Name of region. |
regions[i].difference |
Number
|
<optional>
|
options.difference
|
Difference value for region. |
regions[i].percent |
Number
|
<optional>
|
options.percent
|
Percent value for region. |
regions[i].polygon |
Array
|
|
|
Array of x y coordinates [{x:0,y:0},{x:0,y:360},{x:160,y:360},{x:160,y:0}] |
mask |
Boolean
|
<optional>
|
false
|
Indicate if regions should be used as masks of pixels to ignore. |


--- layout: conference sidemenu: conference title: "Music Encoding Conference 2019" subtitle: "" venue: "University of Vienna – Department of Musicology, Vienna, Austria" image: conference/2019/mec2019dates.jpg date-start: 2019-05-29 date-end: 2019-06-01 permalink: "/conference/2019/" tag: MEC2019 role: about id: about ---
The Music Encoding Conference is the annual focal point for the Music Encoding Initiative community.
Music encoding is a critical component of the emerging fields of digital musicology, digital editions, symbolic music information retrieval, and others. At the centre of these fields, the Music Encoding Conference has emerged as an important cross-disciplinary venue for theorists, musicologists, librarians, and technologists to meet and discuss new advances in their fields.
The conference is organised jointly by the Division of Musicology of the Austrian Academy of Sciences, the Mozart Institute of the Mozarteum Foundation Salzburg and the Department of Musicology of the University of Vienna.
The conference awarded travel grants in a total of 4000 EUR to students with appropriate expertise. The bursaries partially cover the costs of registration, travel and accommodation.


(Solution proposed by Laurent Théry, see also Section 13.4.1 of the Coq'Art)
Errata
Page 220, section 8.2.7, read :
"binary_word (n+p)" and "binary_word (p+n)"
Page 227, last paragraph. Erase the proposition "and to the fact ... auto"
Pagge 229, last paragraph. Read "(page 134)" instead of "(Sect. 134)"


Mobile Mummy
An Imperfect Prototype For The Perfect App
Remember all those times you'd be behind on, well basically, life?
But then you always had someone running after you with a slipper in hand, making sure you actually got stuff done? Yeah, my childhood was definitely better than yours. But adult life has become seemingly difficult. And that's why, I present to you
Mobile Mummy
The basic point of the app is for me to set timelines on the basic requirements for me to adult.
However, the reader needs to keep in mind that this is a prototype, and like all successful virtual products, the output will most likely be completely different from what is originally planned.


Share Canvas
Choose Color:
Choose Size:
Small
Normal
Large
Extra Large
Draw Cooldown:
READY!
Refresh Timer:
5s


Tempus
Time Tracking Without Effort
Stop wasting time. Subscribe for product updates and beta testing.


Created by Ryan McDermott / @ryansworks
Full stack web programmer.
Pythonista
JavaScript kiddie
Very timid C/C++ developer
Musician and music enthusiast.
I discovered new artists and artists' connections by clicking through related artists. Sounded like something that could be automated.
If you're not a fan of bacon, here's Hamm.
Golang seemed like a good solution.
It's also pretty hip and all over Hacker News, so that's pretty cool.
Spotifind is an app that connects artists by a chain of related artists using Spotify's API and Goroutines to "thread" requests.
Spotifind uses a worker/work queue concurrency pattern to distribute API requests to Spotify and speed up performance.
// Simple structure to hold a reference to an artist.
type WorkRequest struct {
Artist *Artist
Visited *VisitedArtists
}
// A buffered channel that we can send work requests on.
var WorkQueue = make(chan WorkRequest, 100)
var WorkerQueue chan chan WorkRequest
type Worker struct {
ID int
Work chan WorkRequest
WorkerQueue chan chan WorkRequest
}
func StartDispatcher(nworkers int) {
WorkerQueue = make(chan chan WorkRequest, nworkers)
for i := 0; i < nworkers; i++ {
fmt.Println("Starting worker", i+1)
worker := NewWorker(i+1, WorkerQueue)
worker.Start()
}
go func() {
for {
select {
case work := <-WorkQueue:
go func() {
worker := <-WorkerQueue
worker <- work
}()
}
}
}()
}
func NewWorker(id int, workerQueue chan chan WorkRequest) Worker {
worker := Worker{
ID: id,
Work: make(chan WorkRequest),
WorkerQueue: workerQueue,
}
return worker
}
var GlobalQuitChan = make(chan Artist)
func (w Worker) Start() {
go func() {
for {
w.WorkerQueue <- w.Work
select {
case work := <-w.Work:
fmt.Printf("worker %d: %s\n", w.ID, work.Artist.Name)
FindRelatedArtists(work.Artist, work.Visited)
case <-GlobalQuitChan:
fmt.Printf("worker %d stopping\n", w.ID)
return
}
}
}()
}
type Artist struct {
Name string
Id string
Parent *Artist
}
type Artists struct {
Href string
Items []Artist
}
type VisitedArtists struct {
Artists []Artist
}
Build a tree of related artists, back to the origin artist from the destination.
func WalkRelatedArtists(artist *Artist, tree []string) []string {
tree = append(tree, artist.Name)
if artist.Parent != nil {
tree = WalkRelatedArtists(artist.Parent, tree)
}
return tree
}
And yes, apparently Kevin Bacon is actually in Spotify!
We're tired of the bacon jokes, how did I feel about Golang?
Getting acquainted with Go required a bit of adjustment after having used C/C++. Declaring types to the right of variables names can be a bit mind altering at the beginning.
var jobs int
var hopes string
var cash [10]int
var treasuremap map[string]int
type StartupProcess struct {
startup bool
cashIn bool
sellOut bool
broDown bool
}
Almost as chaotic as learning to drive on the other side of the road, like Swedes had to start doing in 1967.
But the Swedes are happy now.
go get looks great from a semantic point of view, but just shoving everything into the GOPATH feels a little weird when you come from having the luxury of pip/virtualenv, npm, gem/rvm, etc.
It doesn't handle versioning problem well, but it does silo off dependencies to the package level
GOPATH := ${PWD}/vendor:${GOPATH}
export GOPATH
vendor_get: vendor_clean
GOPATH=${PWD}/vendor go get -d -u -v \
github.com/rapito/go-spotify/spotify \
github.com/codegangsta/cli
vendor_update: vendor_get
rm -rf `find ./vendor/src -type d -name .git` \
&& rm -rf `find ./vendor/src -type d -name .hg` \
&& rm -rf `find ./vendor/src -type d -name .bzr` \
&& rm -rf `find ./vendor/src -type d -name .svn`
I expected some similar functionality between slices and maps, but that's not the case.
Delete from map
delete(m, k) // remove element m[k] from map m
Delete from slice
a = append(a[:i], a[i+1:]...)
“By convention, packages are given lower case, single-word names; there should be no need for underscores or mixedCaps.”
But why?
Only cats like strange packages
if err != nil {
doSomething()
}
This kind of code is everywhere. Because of Golang's lack of exceptions it seems to crop up a lot. Defer, panic, and recover provide some ways around it but maybe Golang needs exceptions, then again I could be wrong!
Coming from GCC, you are used to -Wall, but probably not of completely having the compiler halt on unused variables!
All of this can come across as pedantic, if you're like me and spend all your days in a dynamic language.
Sometimes it's nice to play fast and loose, but in the end Go's strictness saves you from yourself.
Out of this strictness, does come a lot of goodness. One of those things that I love is a formatter being built in with the language: go fmt. No more of these kinds of interactions:
Object composition
Go is the future of systems software. Where bigger beasts roamed, Golang takes over by being nimble, powerful, and fun. The prior solutions were too big and massive, and now feel almost inappropriate in comparison to Go. Just look at a keyword comparison between C++ and Go →
C++
Go
Any questions?


Overview
pvaClientMultiChannel provides examples of using pvaClientMultiChannel.cpp
- shortestPutGetDouble
-
The least amount of code to get and put to a record with a scalar value field.
- longerPutGetDouble
-
Get and put to a scalar value field without an exceptions or caching.
- shortestPutGetDoubleArray
-
The least amount of code to get and put to a record with a scalar array value field.
- longerPutGetDoubleArray
-
Get and put to a scalar array value field without an exceptions or caching.
Running the example
Start the example database
In one window run:
mrk>pwd
/home/epicsv4/masterCPP/exampleCPP/database/iocBoot/exampleDatabase
../../bin/linux-x86_64/exampleDatabase st.cmd
Start Clients
Go to directory
/home/epics7/modules/exampleCPP
Then in separate window start the following:
bin/linux-x86_64/multiMonitorDouble
and
bin/linux-x86_64/multiPutDouble
and
bin/linux-x86_64/ntMultiMonitor
and
bin/linux-x86_64/ntMultiPut


Cats are clearly the best pets. They are furry and soft and loveable. You can play with them with low effort. They mostly take care of themselves all you have to do is feed them
Unlike dogs cats are a lot less work you don't have to take them out for walks, and they got to the bathroom on their own. A nother good thing about cats is that they are much quiter than dogs and won't wake you up with barking.
Dogs aren't just good for being loveable pets though, they can be trained for contests like obstacle courses. They can also be trained to help you hunt or can be a reliable guard dog to scare of intruders.


client module¶
-
client.
get_histogram
(ID, filename)¶ GET request to get histogram image from server/database :param ID: user name :type ID: str :param filename: filename :type filename: str
- Returns
array of histogram image
- Return type
i (nparray)
-
client.
get_image
(outfile)¶ Decode images to numpy arrary
- Parameters
outfile (dict) – Dictionary with keys File: filename Image: Image in b64 tiff format Process: processing algorithm applied
- Returns
Decoded image from server method (str): Method used to process this image
- Return type
img (nparray)
-
client.
get_image_file
(ID, filename)¶ Get image file :param ID: user name :type ID: str :param filename: file name :type filename: str
- Returns
- Dictionary with keys
File: filename Image: Image in b64 tiff format Process: processing algorithm applied
If user/image does not exist, an error message will be returned to the client.
- Return type
r6.json()(dict or str)
-
client.
get_image_list
(username)¶ Get list of processed image names
- Parameters
username (str) – user name
- Returns
List of processed image names or error message
- Return type
outfile (list or str)
-
client.
image_metrics
(ID, filename)¶ GET image metrics from server :param ID: user name :type ID: str
- Returns
- Dictionary containing the image metrics
- example: outdict = {
“timestamp”: …, “size”: [100, 100], “latency”: 1, “process”: ‘Reverse Video’}
- Return type
r7.json() (dict)
-
client.
post_new_user
(ID)¶ POST request to save new user name to MongoDB
- Parameters
ID (str) – user name
-
client.
process_image
(ID, filename, method)¶ POST request the user to process the image
- Parameters
ID (str) – user name
filename (str) – filename that should exist in database
method (str) – processing method
- Returns
Confirmation that image was processed or error message
- Return type
r6.json() (str)
-
client.
read_file_as_b64
(image_path)¶ Encode image file or image from zip archive to base64
- Parameters
image_path (bytes or str) – if from a zip archive, it is an image in bytes; if from local directory, it should be a string specifying the filepath
- Returns
encoded image file ready to be sent to server
- Return type
b64_string (str)
-
client.
save_b64_image
(base64_string)¶ Saves base64 string as bytes, then covert it back to an image array in tiff format
- Parameters
base64_string – image output string in base 64
- Returns
image array
- Return type
i (nparray)
-
client.
upload_file
(ID, filename, extension, filepathname)¶ Upload files to server/database
- Parameters
ID (str) – user name
filename (str) – filename with no path and extension
extension (str) – image type
filepathname (str) – full filename with path and extension
- Returns
message from server
- Return type
r4.text (str)
-
client.
user_metrics
(ID)¶ GET user metrics from server :param ID: user name :type ID: str
- Returns
- Dictionary containing the user metrics of
number of times used and latency for each method
- Return type
r7.json() (dict)


Our Problem
One of the major concerns of the ICBF is related to problems in early childhood nutrition, given that every year new cases of deaths related to malnutrition are detected. According to the World Bank, OMS, and UNICEF, at least 10% of child and infant mortality was caused by malnutrition issues in 2015. Particularly, in Colombia, according to the National Survey of Nutritional Situation in 2015, the prevalence of delays in the development was around 10.8% and of acute malnutrition of 1.6%, but these values could drastically increase in some specific regions of the country.
For these reasons, the ICBF was interested in finding some insights about socioeconomic and nutritional variables that could influence in a long term the early childhood (0 - 5 years old) malnutrition. Furthermore, the main goal of finding some correlation between these variables was to solve the following question: Could we use these socioeconomic and nutritional information to predict recurrent cases of malnutrition? Solving this question will give the Institute really important information so they could focus their efforts on the predicted cases and reduce their risk of malnutrition problems in the future.


This page shows MFA information for all users. The accuracy of this data depends on whether collection was done with a privileged account (Security/Global Reader/Admin) and whether the --mfa flag was specified during data gathering. MFA can be enforced per user or based on conditions via Conditional Access. Per-user MFA can be collected as any user, but uses artifacts that are created when this is assigned, so this may not be fully accurate. Whether a FIDO key is added to an account can also be collected using any user account.


LETTERS TO THE EDITOR: Trump not like Nixon, Clinton
by THE WASHINGTON TIMESANALYSIS/OPINION:
Democrats are trying to point out supposed double standards at play in the GOP by pointing out that the Republicans changed the rules during the Benghazi closed-door hearings — hence why the Democrats want closed-door impeachment hearings now. But you can’t compare the impeachment of a sitting president to the Benghazi closed-door hearings.
The impeachments of Richard Nixon and Bill Clinton had bipartisan support in the procedural votes. This time around, it’s partisan. Impeachment in the cases of Mr. Nixon and Mr. Clinton was never about a partisan effort; both Mr. Nixon and Mr. Clinton had criminal charges against them before the impeachment. With Mr. Trump, there is no criminal case. Quid pro quo isn’t criminal, and I see no high crimes.
TEDDYLEE GRAY
St. Ann, Jamaica
Sign up for Daily Opinion Newsletter
Copyright © 2019 The Washington Times, LLC. Click here for reprint permission.
Please read our comment policy before commenting.


WHAT'S NEW PUSSYCAT A film review by Andrew Hicks Copyright 1996 Andrew Hicks / Fatboy Productions
**
Officially, this is what started it all in the film career of Woody Allen. From this uneven, overlong mishmash of a movie, you'd never guess he'd go on to become one of the most talented filmmakers of the 20th century (as opposed to the amazing movie directors of the Renaissance). WHAT'S NEW PUSSYCAT goes from a semi-interesting sex farce to a stunningly long and inane conclusion that even includes a go-kart chase.
Peter "Pink Panther" Sellers plays a Don Juan who has women falling all over him. He gets plenty of sex out of it but is hounded by women wanting commitment. (Kind of a sex and race reversal version of SHE'S GOTTA HAVE IT.)  O'Toole throughout the movie tries to force himself upon woman after woman, in that light-hearted brand of sexual harassment humor bred only in the 60's.
Meanwhile, Allen himself has a minor role as Sellers' friend, who is in love with Romy Schneider, one of the women who wants Sellers to marry her. So Sellers, Allen and O'Toole all want Prentiss, although all three of them lust after scores of other beautiful women over the course of the movie. Allen ends up with Ursula Andress, "a close personal friend of James Bond," who sleeps with him after he buys a sports car.
For 1965, WHAT'S NEW PUSSYCAT has a surprising amount of sexual content. There wouldn't be a plot without the sex, even down to the characters' occupations. Sellers is a fashion magazine editor who has a regular parade of models in and out of his bed and Allen is the guy who dresses and undresses strippers at a nightclub for twenty francs a week. ("It's all I could afford," Woody remarks.) In his later films, Allen would reduce sex to a supporting role with his other favorite topics of death, God and food (in that order), but in WHAT'S NEW PUSSYCAT sex is the front-and-center theme.
Like the 1963 movie SEX AND THE SINGLE GIRL, the sexual tensions and desires from the first part of the movie manifest themselves in a wild, everything-but-the-kitchen-sink conclusion, but here the movie is severely hindered by the silly, convulted finale. In SEX, the conclusion was the best part of the movie, but with Woody Allen, a more laid-back verbal humor works best, not an overblown slapstick farce, particularly if he's only onscreen in a few scenes. When taking the starring role and directorial reigns in the early 70's classics BANANAS and SLEEPER, Woody would prove his talent for slapstick. But nothing is proven here, except that Sellers, Allen and Andress didn't learn their lesson the first time out. They would all three do much worse two years later with the 007 parody CASINO ROYALE.
--
Visit the Movie Critic at LARGE homepage at http://www.missouri.edu/~c667778/movies.html Serving America For Over 1/50th of a Century!
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Alembic For The Database Schema Migrations
Using just sql scripts for managing database schema migrations is alright. But in that case we have to explicitly create a system where we have to keep track of the sequences of the scripts (one of the reasons: foreign key dependencies). While in development environment, if we want to check whether existing function/method code compatible with earlier table schema, we have to manually write some commands in our favorite db client. That adds up extra effort.
There are many ways we can automate the process of upgrading/rollbacking the db changes by using tools like flyway/liquibase. But I find it quite tedious to use json/yaml and likewise for managing db migrations. Alembic does the same job with Python code (which is simple to read and maintain).
Let’s go through an example to understand how awesomely easy it is to manage database migrations in alembic.
Let’s create a directory my_db_migration
, and cd
into it
pranav@ubuntu:~$ mkdir my_db_migration
pranav@ubuntu:~$ cd my_db_migration
pranav@ubuntu:~/my_db_migration$
We can create a virtual environment for our project called env
.
pranav@ubuntu:~/my_db_migration$ virtualenv env
Using base prefix '/usr'
New python executable in /home/pranav/my_db_migration/env/bin/python3
Also creating executable in /home/pranav/my_db_migration/env/bin/python
Installing setuptools, pip, wheel...
done.
Now, let’s activate it,
pranav@ubuntu:~/my_db_migration$ source env/bin/activate
(env) pranav@ubuntu:~/my_db_migration$
We are ready to create our alembic project. For that we will install the alembic
library with pip.
(env) pranav@ubuntu:~/my_db_migration$ pip install alembic
Collecting alembic
Downloading https://files.pythonhosted.org/packages/70/3d/d5ed7a71fe84f9ed0a69e91232a40b0b148b151524dc5bb1c8e4211eb117/alembic-1.3.0.tar.gz (1.1MB)
|████████████████████████████████| 1.1MB 923kB/s
Collecting SQLAlchemy>=1.1.0
Downloading https://files.pythonhosted.org/packages/14/0e/487f7fc1e432cec50d2678f94e4133f2b9e9356e35bacc30d73e8cb831fc/SQLAlchemy-1.3.10.tar.gz (6.0MB)
|████████████████████████████████| 6.0MB 9.0MB/s
Collecting Mako
Downloading https://files.pythonhosted.org/packages/b0/3c/8dcd6883d009f7cae0f3157fb53e9afb05a0d3d33b3db1268ec2e6f4a56b/Mako-1.1.0.tar.gz (463kB)
|████████████████████████████████| 471kB 1.8MB/s
Collecting python-editor>=0.3
Downloading https://files.pythonhosted.org/packages/c6/d3/201fc3abe391bbae6606e6f1d598c15d367033332bd54352b12f35513717/python_editor-1.0.4-py3-none-any.whl
Collecting python-dateutil
Downloading https://files.pythonhosted.org/packages/d4/70/d60450c3dd48ef87586924207ae8907090de0b306af2bce5d134d78615cb/python_dateutil-2.8.1-py2.py3-none-any.whl (227kB)
|████████████████████████████████| 235kB 8.0MB/s
Collecting MarkupSafe>=0.9.2
Downloading https://files.pythonhosted.org/packages/b2/5f/23e0023be6bb885d00ffbefad2942bc51a620328ee910f64abe5a8d18dd1/MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl
Collecting six>=1.5
Downloading https://files.pythonhosted.org/packages/65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl
Building wheels for collected packages: alembic, SQLAlchemy, Mako
Building wheel for alembic (setup.py) ... done
Created wheel for alembic: filename=alembic-1.3.0-py2.py3-none-any.whl size=144427 sha256=ca5d1444658877ebb2d612420ae10b6807ff190199ec1746ee67d80e997a8999
Stored in directory: /home/pranav/.cache/pip/wheels/40/f8/22/ad0f408796a4c656fae5ee1fd8d8a139b19ca4af61059cea5b
Building wheel for SQLAlchemy (setup.py) ... done
Created wheel for SQLAlchemy: filename=SQLAlchemy-1.3.10-cp36-cp36m-linux_x86_64.whl size=1200400 sha256=b2b67ee0f089bfb5972b0cc2a19b439e89badb4da8094d405a2808c51286f287
Stored in directory: /home/pranav/.cache/pip/wheels/4b/b2/89/cd2231ee623987c605f049df55f40a3e4252ef6a15b94836c2
Building wheel for Mako (setup.py) ... done
Created wheel for Mako: filename=Mako-1.1.0-cp36-none-any.whl size=75363 sha256=3f73fac5d5e18ce52c37f5a87f8e2c46c9d71dde81c4938bf21603ec44be73ef
Stored in directory: /home/pranav/.cache/pip/wheels/98/32/7b/a291926643fc1d1e02593e0d9e247c5a866a366b8343b7aa27
Successfully built alembic SQLAlchemy Mako
Installing collected packages: SQLAlchemy, MarkupSafe, Mako, python-editor, six, python-dateutil, alembic
Successfully installed Mako-1.1.0 MarkupSafe-1.1.1 SQLAlchemy-1.3.10 alembic-1.3.0 python-dateutil-2.8.1 python-editor-1.0.4 six-1.13.0
We will create an alembic project with following command
(env) pranav@ubuntu:~/my_db_migration$ alembic init alembic
Creating directory /home/pranav/my_db_migration/alembic ... done
Creating directory /home/pranav/my_db_migration/alembic/versions ... done
Generating /home/pranav/my_db_migration/alembic.ini ... done
Generating /home/pranav/my_db_migration/alembic/env.py ... done
Generating /home/pranav/my_db_migration/alembic/script.py.mako ... done
Generating /home/pranav/my_db_migration/alembic/README ... done
Please edit configuration/connection/logging settings in '/home/pranav/my_db_migration/alembic.ini' before proceeding.
The above command creates a structure for alembic migrations. We have to edit the .ini
file
to make the connection with the database. For this example we are going to use
the postgres database.
Let’s connect to local postgres server on our dev machine using command
pranav@ubuntu:~$ psql
psql (10.10 (Ubuntu 10.10-0ubuntu<IP_ADDRESS>))
Type "help" for help.
pranav=>
Create a table called example_db
for the example
pranav=> create database example_db;
CREATE DATABASE
pranav=> \c example_db;
You are now connected to database "example_db" as user "pranav".
Now that we have created the database example_db
, let us edit the alembic.ini
file
created by alembic to add the database connection string. replace
sqlalchemy.url = driver://user:pass@localhost/dbname
with
sqlalchemy.url = postgres://username:password@localhost:5432/example_db
Now, let’s create a sqlalchemy model from which we are going to generate the database version. For that we first have to install sqlalchemy.
(env) pranav@ubuntu:~/my_db_migration$ pip install sqlalchemy
Requirement already satisfied: sqlalchemy in ./env/lib/python3.6/site-packages (1.3.10)
(env) pranav@ubuntu:~/my_db_migration$ pip freeze
alembic==1.3.0
Mako==1.1.0
MarkupSafe==1.1.1
python-dateutil==2.8.1
python-editor==1.0.4
six==1.13.0
SQLAlchemy==1.3.10
Seems like it is already installed as it is the dependency for the alembic
.
Create a models.py which contains the code,
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()
class Student(Base):
__tablename__ = 'students'
name = Column(String)
seq = Column(Integer, primary_key=True)
def __init__(self, name):
self.name = name
Now that we have added our model, let’s run some commands to autogenerate the migration.
(env) pranav@ubuntu:~/my_db_migration$ alembic revision --autogenerate -m "Added students table"
Traceback (most recent call last):
File "/home/pranav/my_db_migration/env/bin/alembic", line 8, in <module>
sys.exit(main())
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/config.py", line 575, in main
CommandLine(prog=prog).main(argv=argv)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/config.py", line 569, in main
self.run_cmd(cfg, options)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/config.py", line 549, in run_cmd
**dict((k, getattr(options, k, None)) for k in kwarg)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/command.py", line 214, in revision
script_directory.run_env()
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/script/base.py", line 489, in run_env
util.load_python_file(self.dir, "env.py")
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/util/pyfiles.py", line 98, in load_python_file
module = load_module_py(module_id, path)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/util/compat.py", line 173, in load_module_py
spec.loader.exec_module(module)
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "alembic/env.py", line 77, in <module>
run_migrations_online()
File "alembic/env.py", line 62, in run_migrations_online
poolclass=pool.NullPool,
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/sqlalchemy/engine/__init__.py", line 522, in engine_from_config
return create_engine(url, **options)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/sqlalchemy/engine/__init__.py", line 479, in create_engine
return strategy.create(*args, **kwargs)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/sqlalchemy/engine/strategies.py", line 87, in create
dbapi = dialect_cls.dbapi(**dbapi_args)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/sqlalchemy/dialects/postgresql/psycopg2.py", line 737, in dbapi
import psycopg2
ModuleNotFoundError: No module named 'psycopg2'
As we are trying to connect to postgresql, we need psycopg2
installed. Let’s install it.
(env) pranav@ubuntu:~/my_db_migration$ sudo apt-get install libpq-dev
[sudo] password for pranav:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
postgresql-doc-10
The following NEW packages will be installed:
libpq-dev
0 upgraded, 1 newly installed, 0 to remove and 29 not upgraded.
Need to get 218 kB of archives.
After this operation, 1,092 kB of additional disk space will be used.
Get:1 http://us.archive.ubuntu.com/ubuntu bionic-updates/main amd64 libpq-dev amd64 10.10-0ubuntu<IP_ADDRESS> [218 kB]
Fetched 218 kB in 1s (232 kB/s)
Selecting previously unselected package libpq-dev.
(Reading database ... 192301 files and directories currently installed.)
Preparing to unpack .../libpq-dev_10.10-0ubuntu<IP_ADDRESS>_amd64.deb ...
Unpacking libpq-dev (10.10-0ubuntu<IP_ADDRESS>) ...
Setting up libpq-dev (10.10-0ubuntu<IP_ADDRESS>) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
(env) pranav@ubuntu:~/my_db_migration$ pip install psycopg2
Collecting psycopg2
Using cached https://files.pythonhosted.org/packages/84/d7/6a93c99b5ba4d4d22daa3928b983cec66df4536ca50b22ce5dcac65e4e71/psycopg2-2.8.4.tar.gz
Building wheels for collected packages: psycopg2
Building wheel for psycopg2 (setup.py) ... done
Created wheel for psycopg2: filename=psycopg2-2.8.4-cp36-cp36m-linux_x86_64.whl size=419315 sha256=1de8e1dd0029846c82a21db758c76b774c71133aa3d124c1b40d950b9c6d9617
Stored in directory: /home/pranav/.cache/pip/wheels/7e/5b/53/30085c62689dcfce50c8f40759945a49eb856af082e9ebf751
Successfully built psycopg2
Installing collected packages: psycopg2
Successfully installed psycopg2-2.8.4
Now, we are gonna create table using autogenerate command
(env) pranav@ubuntu:~/my_db_migration$ alembic revision --autogenerate -m "Added students table"
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
ERROR [alembic.util.messaging] Can't proceed with --autogenerate option; environment script /home/pranav/my_db_migration/alembic/env.py does not provide a MetaData object or sequence of objects to the context.
FAILED: Can't proceed with --autogenerate option; environment script /home/pranav/my_db_migration/alembic/env.py does not provide a MetaData object or sequence of objects to the context.
But it fails. The reason is that alembic is not having any information about table metadata to generate
the script. So, we will add the base metadata in env.py
.
from logging.config import fileConfig
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from alembic import context
from models import Base
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = Base.metadata
...
Now, let’s run the autogenerate command again.
(env) pranav@ubuntu:~/my_db_migration$ alembic revision --autogenerate -m "Added students table"
Traceback (most recent call last):
File "/home/pranav/my_db_migration/env/bin/alembic", line 8, in <module>
sys.exit(main())
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/config.py", line 575, in main
CommandLine(prog=prog).main(argv=argv)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/config.py", line 569, in main
self.run_cmd(cfg, options)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/config.py", line 549, in run_cmd
**dict((k, getattr(options, k, None)) for k in kwarg)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/command.py", line 214, in revision
script_directory.run_env()
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/script/base.py", line 489, in run_env
util.load_python_file(self.dir, "env.py")
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/util/pyfiles.py", line 98, in load_python_file
module = load_module_py(module_id, path)
File "/home/pranav/my_db_migration/env/lib/python3.6/site-packages/alembic/util/compat.py", line 173, in load_module_py
spec.loader.exec_module(module)
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "alembic/env.py", line 8, in <module>
from models import Base
ModuleNotFoundError: No module named 'models'
It seems that current directory is not in PYTHONPATH. Add current directory to PYTHONPATH with command,
(env) pranav@ubuntu:~/my_db_migration$ export PYTHONPATH=.
(env) pranav@ubuntu:~/my_db_migration$ alembic revision --autogenerate -m "Added students table"
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'students'
Generating /home/pranav/my_db_migration/alembic/versions/6f1220842ecc_added_students_table.py ... done
It successfully creates the version.
pranav@ubuntu:~/my_db_migration$ ls
alembic alembic.ini env models.py __pycache__
pranav@ubuntu:~/my_db_migration$ cd alembic/
pranav@ubuntu:~/my_db_migration/alembic$ ls
env.py __pycache__ README script.py.mako versions
pranav@ubuntu:~/my_db_migration/alembic$ cd versions/
pranav@ubuntu:~/my_db_migration/alembic/versions$ ls
6f1220842ecc_added_students_table.py __pycache__
pranav@ubuntu:~/my_db_migration/alembic/versions$ cat 6f1220842ecc_added_students_table.py
"""Added students table
Revision ID: 6f1220842ecc
Revises:
Create Date: 2019-11-09 18:59:29.147570
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '6f1220842ecc'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('students',
sa.Column('name', sa.String(), nullable=True),
sa.Column('seq', sa.Integer(), nullable=False),
sa.PrimaryKeyConstraint('seq')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('students')
# ### end Alembic commands ###
Now, let’s apply the migration to our database,
(env) pranav@ubuntu:~/my_db_migration$ alembic upgrade head
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 6f1220842ecc, Added students table
We have successfully applied the migration. To see the table created, go to the postgres client and execute,
example_db=> \dt
List of relations
Schema | Name | Type | Owner
--------+-----------------+-------+--------
public | alembic_version | table | pranav
public | students | table | pranav
(2 rows)
example_db=> \d students
Table "public.students"
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------+----------+---------------------------------------
name | character varying | | |
seq | integer | | not null | nextval('students_seq_seq'::regclass)
Indexes:
"students_pkey" PRIMARY KEY, btree (seq)
You can check the current alembic version of your database,
example_db=> select * from alembic_version;
version_num
--------------
6f1220842ecc
(1 row)
Let’s add another non nullable column email to the table, and make name non nullable as well.
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
Base = declarative_base()
class Student(Base):
__tablename__ = 'students'
name = Column(String, nullable=False)
seq = Column(Integer, primary_key=True)
email = Column(String, nullable=False)
def __init__(self, name, email):
self.name = name
self.email = email
Let’s run the autogenerate command and apply the migration,
(env) pranav@ubuntu:~/my_db_migration$ alembic revision --autogenerate -m "Added column 'email' to students table, and made 'name' necessary"
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.ddl.postgresql] Detected sequence named 'students_seq_seq' as owned by integer column 'students(seq)', assuming SERIAL and omitting
INFO [alembic.autogenerate.compare] Detected added column 'students.email'
INFO [alembic.autogenerate.compare] Detected NOT NULL on column 'students.name'
Generating /home/pranav/my_db_migration/alembic/versions/64d7e64488b4_added_column_email_to_students_table_.py ... done
(env) pranav@ubuntu:~/my_db_migration$ alembic upgrade head
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running upgrade 6f1220842ecc -> 64d7e64488b4, Added column 'email' to students table, and made 'name' necessary
Now, if you see the students table structure again, ‘name’ is the mandatory field, and there is new mandatory field ‘email’. The alembic version is increased as well
example_db=> \d students
Table "public.students"
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------+----------+---------------------------------------
name | character varying | | not null |
seq | integer | | not null | nextval('students_seq_seq'::regclass)
email | character varying | | not null |
Indexes:
"students_pkey" PRIMARY KEY, btree (seq)
example_db=> select * from alembic_version;
version_num
--------------
64d7e64488b4
(1 row)
Want to rollback by one step? Just execute,
(env) pranav@ubuntu:~/my_db_migration$ alembic downgrade -1
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.runtime.migration] Running downgrade 64d7e64488b4 -> 6f1220842ecc, Added column 'email' to students table, and made 'name' necessary
And voila,
example_db=> \d students
Table "public.students"
Column | Type | Collation | Nullable | Default
--------+-------------------+-----------+----------+---------------------------------------
name | character varying | | |
seq | integer | | not null | nextval('students_seq_seq'::regclass)
Indexes:
"students_pkey" PRIMARY KEY, btree (seq)
example_db=> select * from alembic_version;
version_num
--------------
6f1220842ecc
(1 row)
As simple as that.


Welcome!
My name is Filipa Lacerda and I'm a Senior Frontend Engineer at Zapier, a speaker and a mentor.
I'm based in sunny Portugal and I'm passionate about the web & teaching.
Talks
- GitLab's journey With Vue - from jQuery to GraphQL @ Connect Fest Porto, Portugal • September 5th, 2019
- Workshop CI/CD como ferramenta de Devops @ DETI, Aveiro, Portugal • April 25, 2019
- Vuex Patterns: Why actions matter @ VueJS Amsterdam Amsterdam, Netherlands • February 14-15, 2019
- Beyond Agile - Conversational Development at GitLab @ GDG DevFest Lisboa, Portugal • December 8, 2018
- Vue and Vuex: The good, the bad and the ugly - GitLab's use case @ GDG DevFest Coimbra, Portugal • November 24, 2018
- Vue and Vuex: The good, the bad and the ugly @ Vue Conf TO Toronto, Canada • November 14-16, 2018
- An overvue a tale of speed and maintainability @ Commit Porto Porto, Portugal • June 30, 2018
- Vuejs made my life easier @ require('lx') - The JavaScript meetup in Lisbon Lisboa, Portugal • February 21, 2018
- One Tool for Software Development @ Semana da Engenharia Informática Braga, Portugal • February 3-11, 2018
- GitLab CI/CD - An overview @ DevOps Porto Porto, Portugal • June 21-23, 2017
- No time to refactor, how we made the Frontend awesome at GitLab with Vue.js @ Vue Conf WROCŁAW, Poland • June 21-23, 2017
Blog Posts
Podcasts
Experience
-
Senior Frontend EngineerDecember 2020 - CURRENT
-
Frontend EngineerDecember 2019 - 2020
-
Senior Frontend Engineer, Release and VerifySeptember 2017 - December 2019
Developing several Release and Verify features.
Worked 4 months as Release Manager
Wrote the documentation for Vuex Patterns.
Refactored several Rails features into VueJS+Vuex.
Maintainer.
-
Frontend EngineerSeptember 2016 - September 2017
Developed several CI/CD features.
Designed the Architecture for our Vue applications.
Wrote Documentation for Vue patterns and Flux state management & Internal Styleguide for Vue.
Maintainer.
-
MentorJuly 2018 - December 2018Frontend Mentorship - Coaching students
-
AuthorJanuary 2018 - March 2018Wrote technical blog posts about Vue.js
-
Frontend DeveloperJanuary 2015 - September 2016Built the Frontend for a fraud prevention product using React, Redux & Webpack. Built the Frontend for several clients, on-site.
-
Frontend DeveloperMarch 2013 - December 2014Developed the client side of some projects with ember.js, javascript, jQuery, HTML5, CSS3 and using REST APIs; Including the development of the user experience interface. Worked with Agile Methodologies.
-
User Experience DesignerNovember 2011 - February 2013Developed projects in JavaScript, HTML and CSS in the healthcare field
-
ResearcherNovember 2010 - June 2011Fundação Calouste Gulbenkian - Casa das Ciência
Education
-
MSc in Multimedia Communication - Interactive MultimediaUniversidade de Aveiro2010-2012
-
BSc in New Communication TechnologiesUniversidade de Aveiro2007-2010


{% include head.html %}
Toggle navigation
Bootply
Get Started
Edit
Visualize
Prototype
{% include sidebar-nav.html %}
{% capture md %}{% include landing-content.md %}{% endcapture %} {{ md|markdownify }}
{% include foot.html %}


"x" "1" "GREEN,JL, PAN,YHL AND REED,GA, MUTAGENICITY OF BENZO[A]PYRENEBAY-REGION SULFONATES, CARCINOGENESIS 12(7):1359-1362, 1991"


My name is Jose and I am a (UX) Designer based in madrid working with brands to bring their digital products to life
If you want to know a bit more about me.


|
Files | |
| file | DFLEX-driver.h |
ROBOTC Dexter Industries dFlex Sensor driver. | |
Defines | |
| #define | DFLEXDAT "DFLEX.dat" |
Functions | |
| int | DFLEXvalRaw (tSensors link) |
| int | DFLEXvalNorm (tSensors link) |
| void | DFLEXcalLow (tSensors link) |
| void | DFLEXcalLow (int lowval) |
| void | DFLEXcalHigh (tSensors link) |
| void | DFLEXcalHigh (int highval) |
| void | _DFLEXcheckSensor (tSensors link) |
| void | _DFLEXwriteCalVals (int lowval, int highval) |
| void | _DFLEXreadCalVals (int &lowval, int &highval) |
Variables | |
| int | dflexlow = 0 |
| int | dflexhigh = 1023 |
| bool | DFLEX_calibrated = false |
Dexter Industries dFlex Sensor driver
| #define DFLEXDAT "DFLEX.dat" |
Datafile for dFlex Sensor calibration info
Definition at line 41 of file DFLEX-driver.h.
| void _DFLEXcheckSensor | ( | tSensors | link ) |
Check if the sensor is set to raw and that it's been configured as a sensorAnalogInactive. If not, reconfigure the port.
Note: this is an internal function and should not be called directly
| link | the dFlex Sensor port number |
Definition at line 152 of file DFLEX-driver.h.
| void _DFLEXreadCalVals | ( | int & | lowval, |
| int & | highval | ||
| ) |
Read the low and high calibration values from a data file.
Note: this is an internal function and should not be called directly
| lowval | the low calibration value |
| highval | the high calibration value |
Definition at line 227 of file DFLEX-driver.h.
| void _DFLEXwriteCalVals | ( | int | lowval, |
| int | highval | ||
| ) |
Write the low and high calibration values to a data file.
Note: this is an internal function and should not be called directly
| lowval | the low calibration value |
| highval | the high calibration value |
Definition at line 167 of file DFLEX-driver.h.
| void DFLEXcalHigh | ( | int | highval ) |
Calibrate the dFlex Sensor's high calibration value with the supplied value.
| highval | the sensor's high calibration value |
Definition at line 139 of file DFLEX-driver.h.
| void DFLEXcalHigh | ( | tSensors | link ) |
Calibrate the dFlex Sensor's high calibration value with the current raw sensor reading.
| link | the dFlex Sensor port number |
Definition at line 127 of file DFLEX-driver.h.
| void DFLEXcalLow | ( | int | lowval ) |
Calibrate the dFlex Sensor's low calibration value with the supplied value.
| lowval | the sensor's low calibration value |
Definition at line 117 of file DFLEX-driver.h.
| void DFLEXcalLow | ( | tSensors | link ) |
Calibrate the dFlex Sensor's low calibration value with the current raw sensor reading.
| link | the dFlex Sensor port number |
Definition at line 105 of file DFLEX-driver.h.
| int DFLEXvalNorm | ( | tSensors | link ) |
Read the normalised value of the dFlex Sensor, based on the low and high values.
Note: this is not a linear value
| link | the dFlex Sensor port number |
Definition at line 81 of file DFLEX-driver.h.
| int DFLEXvalRaw | ( | tSensors | link ) |
Read the raw value of the dFlex Sensor.
| link | the dFlex Sensor port number |
Definition at line 67 of file DFLEX-driver.h.
| bool DFLEX_calibrated = false |
Has the sensor been calibrated yet
Definition at line 46 of file DFLEX-driver.h.
| int dflexhigh = 1023 |
| int dflexlow = 0 |


Wrapper for Graph.get_collection_ref()
using the default graph.
tf.compat.v1.get_collection_ref(key)
See tf.Graph.get_collection_ref
for more details.
key
: The key for the collection. For example, the GraphKeys
class contains
many standard names for collections.The list of values in the collection with the given name
, or an empty
list if no value has been added to that collection. Note that this returns
the collection list itself, which can be modified in place to change the
collection.
Collections are not supported when eager execution is enabled.


Haptic Model Predictive Controller class. More...
Public Member Functions | |
| def | __init__ |
| Constructor. | |
| def | initControlParametersFromServer |
| Read parameters from the ROS parameter server and store them. | |
| def | initRobot |
| Initialise the robot joint limits. | |
| def | getSkinData |
| getSkinData accessor function. | |
| def | getJointAngles |
| getJointAngles accessor function. | |
| def | getDesiredJointAngles |
| getDesiredJointAngles accessor function. | |
| def | getJointStiffness |
| getJointStiffness accessor function. | |
| def | getMPCData |
| getMPCData accessor function. | |
| def | initMPCData |
| Builds the MPC data structure from the individual parameters This is just a convenience data structure to amalgamate the data. | |
| def | updateWeightsCallback |
| Update the position/orientation weights used by the controller. | |
| def | goalCallback |
| Store the current trajectory goal. | |
| def | mpcMonitorCallback |
| Store the state information from the monitor node. | |
| def | robotStateCallback |
| Store the robot haptic state. | |
| def | goalOrientationInQuat |
| Interpolate a step towards the given goal orientation. | |
| def | goalMotionForHand |
| Interpolate a step towards the given goal position. | |
| def | deltaQpJepGen |
| Main control calculation. | |
| def | contactStiffnessMatrix |
| Computes the contact stiffness matrix, K_ci. | |
| def | contactForceTransformationMatrix |
| Calculates the force transformation matrix from a list of force normals. | |
| def | deltaForceBounds |
| Compute bounds for delta_f. | |
| def | publishDeltaControlValues |
| Publishes a list of Deltas for the desired joint positions. | |
| def | publishDesiredJointAngles |
| Publish a desired joint position list directly (rather than deltas) | |
| def | updateController |
| Main control function. | |
| def | initComms |
| Initialise the ROS communications - init node, subscribe to the robot state and goal pos, publish JEPs. | |
| def | enableHapticMPC |
| Enable Haptic MPC service handler (default is enabled). | |
| def | start |
| Start the control loop once the controller is initialised. | |
Public Attributes | |
| opt | |
| state_lock | |
| goal_lock | |
| Haptic state lock. | |
| monitor_lock | |
| Goal state lock. | |
| gain_lock | |
| Monitor state lock. | |
| mpc_data | |
| Controller gain state lock. | |
| msg | |
| MPCData data structure. | |
| last_msg_time | |
| Haptic state message. | |
| timeout | |
| waiting_to_resume | |
| waiting_for_no_errors | |
| mpc_state | |
| mpc_error | |
| Current MPC state. | |
| joint_names | |
| Current MPC errors. | |
| joint_angles | |
| desired_joint_angles | |
| joint_velocities | |
| joint_stiffness | |
| joint_damping | |
| end_effector_pos | |
| end_effector_orient_quat | |
| skin_data | |
| Jc | |
| Je | |
| time_step | |
| goal_pos | |
| goal_orient_quat | |
| orient_weight | |
| pos_weight | |
| deadzone_distance | |
| deadzone_angle | |
| currently_in_deadzone | |
| mpc_enabled | |
| ma_to_m | |
| allowable_contact_force | |
| max_delta_force_mag | |
| stopping_force | |
| goal_velocity_for_hand | |
| static_contact_stiffness_estimate | |
| estimate_contact_stiffness | |
| jerk_opt_weight | |
| frequency | |
| joint_limits_max | |
| joint_limits_min | |
| robot_state_sub | |
| goal_sub | |
| delta_q_des_pub | |
| q_des_pub | |
| mpc_monitor_sub | |
| mpc_weights_sub | |
| mpc_weights_pub | |
| enable_mpc_srv |
Haptic Model Predictive Controller class.
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.__init__ | ( | self, | |
| opt, | |||
node_name = "haptic_mpc" |
|||
| ) |
Constructor.
| opt | optparse options. Should be created using the helper utility script for reliability. |
| node_name | Name used for the ROS node. |
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.contactForceTransformationMatrix | ( | self, | |
| n_l | |||
| ) |
Calculates the force transformation matrix from a list of force normals.
| n_l | List of force normals |
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.contactStiffnessMatrix | ( | self, | |
| n_l, | |||
| k_default, | |||
k_est_min = 100.0 , |
|||
k_est_max = 100000.0 |
|||
| ) |
Computes the contact stiffness matrix, K_ci.
| n_l | List of normal forces #param k_default Default stiffness, N/m. Default is typically 200.0-1000.0 |
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.deltaForceBounds | ( | self, | |
| f_n, | |||
| max_pushing_force, | |||
| max_pulling_force, | |||
| max_pushing_force_increase, | |||
| max_pushing_force_decrease, | |||
| min_decrease_when_over_max_force, | |||
| max_decrease_when_over_max_force | |||
| ) |
Compute bounds for delta_f.
| delta_f_min | Minimum bound |
| delta_f_max | Maximum bound |
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.deltaQpJepGen | ( | self, | |
| mpc_dat | |||
| ) |
Main control calculation.
| mpc_dat | An MPCData class, populated with relevant control parameters and current data |
Enable Haptic MPC service handler (default is enabled).
getDesiredJointAngles accessor function.
getJointAngles accessor function.
getJointStiffness accessor function.
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.getMPCData | ( | self | ) |
getMPCData accessor function.
Returns a copy of the control data structure.
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.getSkinData | ( | self | ) |
getSkinData accessor function.
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.goalCallback | ( | self, | |
| msg | |||
| ) |
Store the current trajectory goal.
The controller will always attempt a linear path to this.
| msg | A PoseStamped message |
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.goalMotionForHand | ( | self, | |
| x_h, | |||
| x_g, | |||
| dist_g | |||
| ) |
Interpolate a step towards the given goal position.
| x_h | The current hand position as a numpy matrix: [x,y,z] |
| x_g | The current goal position as a numpy matrix: [x,y,z] |
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.goalOrientationInQuat | ( | self, | |
| q_h_orient, | |||
| q_g_orient, | |||
| max_ang_step | |||
| ) |
Interpolate a step towards the given goal orientation.
| q_h_orient | The current hand orientation as a quaternion in list form: [x,y,z,w] |
| q_g_orient | The current goal orientation as a quaternion in list form: [x,y,z,w] |
Read parameters from the ROS parameter server and store them.
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.initMPCData | ( | self | ) |
Builds the MPC data structure from the individual parameters This is just a convenience data structure to amalgamate the data.
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.initRobot | ( | self | ) |
Initialise the robot joint limits.
This relies on something (usually the haptic state node) pushing the appropriate joint limits to the param server before execution. NB: All joint limits are specified in degrees and converted to radians here (easier to understand)
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.mpcMonitorCallback | ( | self, | |
| msg | |||
| ) |
Store the state information from the monitor node.
Allows the control to be somewhat stateful. The state and error fields are lists of strings indicating some state.
| msg | HapticMpcState message object |
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.publishDeltaControlValues | ( | self, | |
| ctrl_data | |||
| ) |
Publishes a list of Deltas for the desired joint positions.
| ctrl_data | List of desired joint position deltas to be published |
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.publishDesiredJointAngles | ( | self, | |
| ctrl_data | |||
| ) |
Publish a desired joint position list directly (rather than deltas)
| ctrl_data | List of desired joint positions to be published (not deltas). |
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.robotStateCallback | ( | self, | |
| msg | |||
| ) |
Store the robot haptic state.
| msg | RobotHapticState message object |
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.start | ( | self | ) |
Start the control loop once the controller is initialised.
Main control function.
Builds the control data structure and passes it to the control calculation routine
| def hrl_haptic_mpc.haptic_mpc.HapticMPC.updateWeightsCallback | ( | self, | |
| msg | |||
| ) |
Update the position/orientation weights used by the controller.
| msg | HapticMpcWeights message object |
Current MPC errors.
Stored as a list of strings
Current MPC state.
Stored as a list of strings
MPCData data structure.