| I l@ve RuBoard |
The STL provides several standard algorithms for the processing of elements of collections. These algorithms offer general fundamental services, such as searching, sorting, copying, reordering, modifying, and numeric processing.
Algorithms are not member functions of the container classes. Instead, they are global functions that operate with iterators. This has an important advantage: Instead of each algorithm being implemented for each container type, all are implemented only once for any container type. The algorithm might even operate on elements of different container types. You can also use the algorithms for user-defined container types. All in all, this concept reduces the amount of code and increases the power and the flexibility of the library.
Note that this is not an object-oriented programming paradigm; it is a generic functional programming paradigm. Instead of data and operations being unified, as in object-oriented programming, they are separated into distinct parts that can interact via a certain interface. However, this concept also has its price: First, the usage is not intuitive. Second, some combinations of data structures and algorithms might not work. Even worse, a combination of a container type and an algorithm might be possible but not useful (for example, it may lead to bad performance). Thus, it is important to learn the concepts and the pitfalls of the STL to benefit from it without abusing it. I provide examples and more details about this throughout the rest of this chapter.
Let's start with a simple example of the use of STL algorithms. Consider the following program, which shows some algorithms and their usage:
// stl/algo1.cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { vector<int> coll; vector<int>::iterator pos; //insert elements from 1 to 6 in arbitrary order coll.push_back(2); coll.push_back(5); coll.push_back(4); coll.push_back(1); coll.push_back(6); coll.push_back(3); //find and print minimum and maximum elements pos = min_element (coll.begin(), coll.end()); cout << "min: " << *pos << endl; pos = max_element (coll.begin(), coll.end()); cout << "max: " << *pos << endl; //sort all elements sort (coll.begin(), coll.end()); //find the first element with value 3 pos = find (coll.begin(), coll.end(), //range 3); //value //reverse the order of the found element with value 3 and all following elements reverse (pos, coll.end()); //print all elements for (pos=coll.begin(); pos!=coll.end(); ++pos) { cout << *pos << ' ' ; } cout << endl; }
To be able to call the algorithms, you must include the header file <algorithm>:
#include <algorithm>
The first two algorithms called are min_element() and max_element(). They are called with two parameters that define the range of the processed elements. To process all elements of a container you simply use begin() and end(). Both algorithms return an iterator for the minimum and maximum elements respectively. Thus, in the statement
pos = min_element (coll.begin(), coll.end());
the min_element() algorithm returns the position of the minimum element (if there is more than one, the algorithm returns the first). The next statement prints that element:
cout << "min: " << *pos << endl;
Of course, you could do both in one statement:
cout << *max_element(coll.begin(), coll.end()) << endl;
The next algorithm called is sort(). As the name indicates, it sorts the elements of the range defined by the two arguments. As usual, you could pass an optional sorting criterion. The default sorting criterion is operator <. Thus, in this example all elements of the container are sorted in ascending order:
sort (coll.begin(), coll.end());
So afterward, the vector contains the elements in this order:
1 2 3 4 5 6
The find() algorithm searches for a value inside the given range. In this example, it searches the first element that is equal to the value 3 in the whole container:
pos = find (coll.begin(), coll.end(), //range 3); //value
If the find() algorithm is successful, it returns the iterator position of the element found. If it fails, it returns the end of the range, the past-the-end iterator, which is passed as the second argument. In this example, the value 3 is found as the third element, so afterward pos refers to the third element of coll.
The last algorithm called in the example is reverse(), which reverses the elements of the passed range. Here the third element that was found by the find() algorithms and the past-the-end iterator are passed as arguments:
reverse (pos, coll.end());
This call reverses the order of the third element up to the last one. The output of the program is as follows:
min: 1 max: 6 1 2 6 5 4 3
All algorithms process one or more ranges of elements. Such a range might, but is not required to, embrace all elements of a container. Therefore, to be able to handle subsets of container elements, you pass the beginning and the end of the range as two separate arguments rather than the whole collection as one argument.
This interface is flexible but dangerous. The caller must ensure that the first and second arguments define a valid range. This is the case if the end of the range is reachable from the beginning by iterating through the elements. This means, it is up to the programmer to ensure that both iterators belong to the same container and that the beginning is not behind the end. If this is not the case, the behavior is undefined and endless loops or forbidden memory access may result. In this respect, iterators are just as unsafe as ordinary pointers. But note that undefined behavior also means that an implementation of the STL is free to find such kinds of errors and handle them accordingly. The following paragraphs show that ensuring that ranges are valid is not always as easy as it sounds. See Section 5.11, for more details about the pitfalls and safe versions of the STL.
Every algorithm processes half-open ranges. Thus, a range is defined so that it includes the position used as the beginning of the range but excludes the position used as the end. This concept is often described by using the traditional mathematical notations for half-open ranges:
[begin,end)
or
[begin,end[
I use the first alternative in this book.
The half-open range concept has the advantages that were described on page 84 (it is simple and avoids special handling for empty collections). However, it also has some disadvantages. Consider the following example:
// stl/find1.cpp #include <iostream> #include <list> #include <algorithm> using namespace std; int main() { list<int> coll; list<int>::iterator pos; //insert elements from 20 to 40 for (int i=20; i<=40; ++i) { coll.push_back(i); } /*find position of element with value 3 * - there is none, so pos gets coll.end() */ pos = find (coll .begin() , coll.end(), //range 3); //value /*reverse the order of elements between found element and the end * - because pos is coll.end() it reverses an empty range */ reverse (pos, coll.end()); //find positions of values 25 and 35 list<int>::iterator pos25, pos35; pos25 = find (coll.begin(), coll.end(), //range 25); //value pos35 = find (coll.begin(), coll.end(), //range 35); //value /*print the maximum of the corresponding range * - note: including pos25 but excluding pos35 */ cout << "max: " << *max_element (pos25, pos35) << endl; //process the elements including the last position cout << "max: " << *max_element (pos25, ++pos35) << endl; }
In this example, the collection is initialized with integral values from 20 to 40. When the search for an element with the value 3 fails, find() returns the end of the processed range (coll.end() in this example) and assigns it to pos. Using that return value as the beginning of the range in the following call of reverse() poses no problem because it results in the following call:
reverse (coll.end(), coll.end());
This is simply a call to reverse an empty range. Thus, it is an operation that has no effect (a so-called "no-op").
However, if find() is used to find the first and the last elements of a subset, you should consider that passing these iterator positions as a range will exclude the last element. So, the first call of max_element()
max_element (pos25, pos35)
finds 34 and not 35:
max: 34
To process the last element, you have to pass the position that is one past the last element:
max_element (pos25, ++pos35)
Doing this yields the correct result:
max: 35
Note that this example uses a list as the container. Thus, you must use operator ++ to get the position that is behind pos35. If you have random access iterators, as with vectors and deques, you also could use the expression pos35 + 1. This is because random access iterators allow "iterator arithmetic" (see Section 2, page 93, and Section 7.2.5, for details).
Of course, you could use pos25 and pos35 to find something in that subrange. Again, to search including pos35 you have to pass the position after pos35. For example:
//increment pos35 to search with its value included ++pos35; pos30 = find(pos25,pos35, //range 30); //value if (pos30 == pos35) { cout << "30 is in NOT the subrange" << endl; } else { cout << "30 is in the subrange" << endl; }
All the examples in this section work only because you know that pos25 is in front of pos35. Otherwise, [pos25,pos35) would not be a valid range. If you are not sure which element is in front, things are getting more complicated and undefined behavior may occur.
Suppose you don't know whether the element that has value 25 is in front of the element that has value 35. It might even be possible that one or both values are not present. By using random access iterators, you can call operator < to check this:
if (pos25 < pos35) { //only [pos25,pos35) is valid ... } else if (pos35 < pos25) { //only [pos35,pos25) is valid ... } else { //both are equal, so both must be end() ... }
However, without random access iterators you have no simple, fast way to find out which iterator is in front. You can only search for one iterator in the range of the beginning to the other iterator or in the range of the other iterator to the end. In this case, you should change your algorithm as follows: Instead of searching for both values in the whole source range, you should try to find out, while searching for them, which value comes first. For example:
pos25 = find (coll.begin(), coll.end(), //range 25); //value pos35 = find (coll.begin(), pos25, //range 35); //value if (pos35 != pos25) { /*pos35 is in front of pos25 *so, only [pos35,pos25) is valid */ ... } else { pos35 = find (pos25, coll.end(), //range 35); //value if (pos35 != pos25) { /*pos25 is in front of pos35 *so, only [pos25,pos35) is valid */ ... } else { // both are equal, so both must be end() ... } }
In contrast to the previous version, here you don't search for pos35 in the full range of all elements of coll. Instead, you first search for it from the beginning to pos25. Then, if it's not found, you search for it in the part that contains the remaining elements after pos25. As a result you know which iterator position comes first and which subrange is valid.
This implementation is not very efficient. A more efficient way to find the first element that either has value 25 or value 35 is to search exactly for that. You could do this by using some abilities of the STL that are not introduced yet as follows:
pos = find_if (coll.begin(), coll.end(), //range compose_f_gx_hx(logical_or<bool>(), //criterion bind2nd(equal_to<int>(), 25), bind2nd(equal_to<int>(), 35))); switch (*pos) { case 25: //element with value 25 comes first pos25 = pos; pos35 = find (++pos, coll.end(), //range 35); //value ... break; case 35: //element with value 35 comes first pos35 = pos; pos25 = find (++pos, coll.end(), //range 25); //value ... break; default: //no element with value 25 or 35 found ... break; }
Here, a special expression is used as a sorting criterion that allows a search of the first element that has either value 25 or value 35. The expression is a combination of several predefined function objects, which are introduced in Section 5.9.2, and Section 8.2, and a supplementary function object compose_f_gx_hx, which is introduced in Section 8.3.1.
Several algorithms process more than one range. In this case you usually must define both the beginning and the end only for the first range. For all other ranges you need to pass only their beginnings. The ends of the other ranges follow from the number of elements of the first range. For example, the following call of equal() compares all elements of the collection coll1 element-by-element with the elements of coll2 beginning with its first element:
if (equal (coll1.begin(), coll1.end(), coll2.begin())) { ... }
Thus, the number of elements of coll2 that are compared with the elements of coll1 is specified indirectly by the number of elements in coll1.
This leads to an important consequence: When you call algorithms for multiple ranges, make sure the second and additional ranges have at least as many elements as the first range. In particular, make sure that destination ranges are big enough for algorithms that write to collections!
Consider the following program:
// stl/copy1.cpp #include <iostream> #include <vector> #include <list> #include <algorithm> using namespace std; int main() { list<int> coll1; vector<int> coll2; //insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll1.push_back(i); } //RUNTIME ERROR: // - overwrites nonexisting elements in the destination copy (coll1 .begin(), coll1.end(), //source coll2.begin()); //destination ...... }
Here, the copy() algorithm is called. It simply copies all elements of the first range into the destination range. As usual, for the first range, the beginning and the end are defined, whereas for the second range, only the beginning is specified. However, the algorithm overwrites rather than inserts. So, the algorithm requires that the destination has enough elements to be overwritten. If there is not enough room, as in this case, the result is undefined behavior. In practice, this often means that you overwrite whatever comes after the coll2.end(). If you're in luck, you'll get a crash; at least then you'll know that you did something wrong. However, you can force your luck by using a safe version of the STL for which the undefined behavior is defined as leading to a certain error handling procedure (see Section 5.11.1).
To avoid these errors, you can (1) ensure that the destination has enough elements on entry, or (2) use insert iterators. Insert iterators are covered in Section 5.5.1. I'll first explain how to modify the destination so that it is big enough on entry.
To make the destination big enough, you must either create it with the correct size or change its size explicitly. Both alternatives apply only to sequence containers (vectors, deques, and lists). This is not really a problem because associative containers cannot be used as a destination for purposes for overwriting algorithms (Section 5.6.2, explains why). The following program shows how to increase the size of containers:
// stl/copy2.cpp #include <iostream> #include <vector> #include <list> #include <deque> #include <algorithm> using namespace std; int main() { list<int> coll1; vector<int> coll2; //insert elements from 1 to 9 for (int i=1; i<=9; ++i) { coll1.push_back(i); } //resize destination to have enough room for the overwriting algorithm coll2.resize (coll1. size()); /*copy elements from first into second collection *- overwrites existing elements in destination */ copy (coll1.begin(), coll1.end(), //source coll2.begin()); //destination /*create third collection with enough room *- initial size is passed as parameter */ deque<int> coll3(coll1 size()); //copy elements from first into third collection copy (coll1.begin(), coll1.end(), //source coll3.begin()); //destination }
Here, resize() is used to change the number of elements in the existing container coll2:
coll2.resize (coll1.size());
coll3 is initialized with a special initial size so that it has enough room for all elements of coll1:
deque<int> coll3(coll1.size());
Note that both resizing and initializing the size create new elements. These elements are initialized by their default constructor because no arguments are passed to them. You can pass an additional argument both for the constructor and for resize() to initialize the new elements.
| I l@ve RuBoard |


Variational optical flow refinement. More...
#include <opencv2/video/tracking.hpp>
Public Member Functions | |
| virtual void | calcUV (InputArray I0, InputArray I1, InputOutputArray flow_u, InputOutputArray flow_v)=0 |
| calc function overload to handle separate horizontal (u) and vertical (v) flow components (to avoid extra splits/merges) More... | |
| virtual float | getAlpha () const =0 |
| Weight of the smoothness term. More... | |
| virtual float | getDelta () const =0 |
| Weight of the color constancy term. More... | |
| virtual int | getFixedPointIterations () const =0 |
| Number of outer (fixed-point) iterations in the minimization procedure. More... | |
| virtual float | getGamma () const =0 |
| Weight of the gradient constancy term. More... | |
| virtual float | getOmega () const =0 |
| Relaxation factor in SOR. More... | |
| virtual int | getSorIterations () const =0 |
| Number of inner successive over-relaxation (SOR) iterations in the minimization procedure to solve the respective linear system. More... | |
| virtual void | setAlpha (float val)=0 |
| Weight of the smoothness term. More... | |
| virtual void | setDelta (float val)=0 |
| Weight of the color constancy term. More... | |
| virtual void | setFixedPointIterations (int val)=0 |
| Number of outer (fixed-point) iterations in the minimization procedure. More... | |
| virtual void | setGamma (float val)=0 |
| Weight of the gradient constancy term. More... | |
| virtual void | setOmega (float val)=0 |
| Relaxation factor in SOR. More... | |
| virtual void | setSorIterations (int val)=0 |
| Number of inner successive over-relaxation (SOR) iterations in the minimization procedure to solve the respective linear system. More... | |
| Public Member Functions inherited from cv::DenseOpticalFlow | |
| virtual void | calc (InputArray I0, InputArray I1, InputOutputArray flow)=0 |
| Calculates an optical flow. More... | |
| virtual void | collectGarbage ()=0 |
| Releases all inner buffers. More... | |
| Public Member Functions inherited from cv::Algorithm | |
| Algorithm () | |
| virtual | ~Algorithm () |
| virtual void | clear () |
| Clears the algorithm state. More... | |
| virtual bool | empty () const |
| Returns true if the Algorithm is empty (e.g. in the very beginning or after unsuccessful read. More... | |
| virtual String | getDefaultName () const |
| virtual void | read (const FileNode &fn) |
| Reads algorithm parameters from a file storage. More... | |
| virtual void | save (const String &filename) const |
| virtual void | write (FileStorage &fs) const |
| Stores algorithm parameters in a file storage. More... | |
| void | write (const Ptr< FileStorage > &fs, const String &name=String()) const |
| simplified API for language bindings This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts. More... | |
Static Public Member Functions | |
| static Ptr< VariationalRefinement > | create () |
| Creates an instance of VariationalRefinement. More... | |
| Static Public Member Functions inherited from cv::Algorithm | |
| template<typename _Tp > | |
| static Ptr< _Tp > | load (const String &filename, const String &objname=String()) |
| Loads algorithm from the file. More... | |
| template<typename _Tp > | |
| static Ptr< _Tp > | loadFromString (const String &strModel, const String &objname=String()) |
| Loads algorithm from a String. More... | |
| template<typename _Tp > | |
| static Ptr< _Tp > | read (const FileNode &fn) |
| Reads algorithm from the file node. More... | |
Additional Inherited Members | |
| Protected Member Functions inherited from cv::Algorithm | |
| void | writeFormat (FileStorage &fs) const |
Detailed Description
Variational optical flow refinement.
This class implements variational refinement of the input flow field, i.e. it uses input flow to initialize the minimization of the following functional: \(E(U) = \int_{\Omega} \delta \Psi(E_I) + \gamma \Psi(E_G) + \alpha \Psi(E_S) \), where \(E_I,E_G,E_S\) are color constancy, gradient constancy and smoothness terms respectively. \(\Psi(s^2)=\sqrt{s^2+\epsilon^2}\) is a robust penalizer to limit the influence of outliers. A complete formulation and a description of the minimization procedure can be found in [15]
Member Function Documentation
◆ calcUV()
|
pure virtual |
calc function overload to handle separate horizontal (u) and vertical (v) flow components (to avoid extra splits/merges)
◆ create()
|
static |
Creates an instance of VariationalRefinement.
◆ getAlpha()
|
pure virtual |
Weight of the smoothness term.
- See also
- setAlpha
◆ getDelta()
|
pure virtual |
Weight of the color constancy term.
- See also
- setDelta
◆ getFixedPointIterations()
|
pure virtual |
Number of outer (fixed-point) iterations in the minimization procedure.
- See also
- setFixedPointIterations
◆ getGamma()
|
pure virtual |
Weight of the gradient constancy term.
- See also
- setGamma
◆ getOmega()
|
pure virtual |
Relaxation factor in SOR.
- See also
- setOmega
◆ getSorIterations()
|
pure virtual |
Number of inner successive over-relaxation (SOR) iterations in the minimization procedure to solve the respective linear system.
- See also
- setSorIterations
◆ setAlpha()
|
pure virtual |
Weight of the smoothness term.
- See also
- getAlpha
◆ setDelta()
|
pure virtual |
Weight of the color constancy term.
- See also
- getDelta
◆ setFixedPointIterations()
|
pure virtual |
Number of outer (fixed-point) iterations in the minimization procedure.
- See also
- getFixedPointIterations
◆ setGamma()
|
pure virtual |
Weight of the gradient constancy term.
- See also
- getGamma
◆ setOmega()
|
pure virtual |
Relaxation factor in SOR.
- See also
- getOmega
◆ setSorIterations()
|
pure virtual |
Number of inner successive over-relaxation (SOR) iterations in the minimization procedure to solve the respective linear system.
- See also
- getSorIterations
The documentation for this class was generated from the following file:
- opencv2/video/tracking.hpp


Dungeon Full Dive:
The new way to play tabletop
DFD
aims to be the MOST immersive tabletop EVER. This means we will give players
features they never had before while playing tabletop, while at the same time
making it easier than ever to play tabletop:
Become one with your hero character by
making your own 3D-Character that you can control
Not only talk about your
worlds but actually dive inside them, walk around, explore and interact
with your friends inside them
Take your combat to the next
level by possessing your miniature: no more spectating, dive into the
battle!
Choose from a WIDE variety of
3D battlemaps, modify them or make your own!
Actually speak to all the
magical creatures of your adventures. Your gamemaster doesn't have to
pretend anymore. He can transform into any NPC he wants you to meet.
and
much more....
We created a Kickstarter project for DFD because we want the community to be part of the development. If you support us now, not only will you get Kickstarter EXCLUSIVE rewards (and heffty rebates!). But you will also become part of the development process of DFD. YOUR input will help us make the best version of DFD: the version YOU want to play. All Kickstarter supporters can exchange with us on our Discord and give input on features, assets or content, that we will add to DFD.
Yes, DFD supports traditional mouse and keyboard input AND VR-devices! This means, that you will be able to play with all of your friends with or without VR-headset!
You can play any tabletop RPG that you want! You can easily import any character sheets or notes into DFD and we make sure, that you can modify all the elements in DFD to fit your liking. Furthermore, DFD will include game mechanics and stat integration for DnD 5e on launch. That means that things like initiative tracking can be done with just a click of a button.
Yes! If you don't have time to write your own campaigns, you can pick one of our prebuilt campaigns. With our carefully written stories, NPCs and even encounters your Gamemaster can host a thrilling gamenight even without any preparation. You can also modify our campaigns to make your own, unique adventures! Or write your own campaigns of course!
We want to give players ALL the tools they need for their tabletop adventures. So that you can experience your own, unique adventures. If that means the community wants to have steampunk or sci-fi assets, we will 100% give that to them. DFD will never stop evolving and continuously add more free content for the players even after release. So while we currently only plan to support the fantasy settings at launch, additional settings are definitely on our radars for the after launch roadmap!
No. We wanted to emphasize that we are not using a subscription model, but we might have formulated it a bit confusingly. If you buy DFD now, you'll be able to play it forever. If you buy it later, you will be able to play it forever.
DFD can be played with any VR Headset! For now, if you want to use the Quest you can simply connect it via link to your laptop or PC. And even better: After the full release, native Quest support is one of the first things on our planned feature agenda, that we will look into!
For the launch of the game, we will start with a wide variety of base characters from all kind of races to choose from. Here all the humans will be customizable. For "fancy" races, we will add customization later down the road (depending on the amount of resources/backers we are able to get).
Yes! If you play 5e stats are integrated and you can use the ingame UI to create and track your character stats! But of course, we support all the rulesets. So if you have a character sheet lying around you can just import the picture file. It's that easy :)
This website uses cookies to ensure you get the best experience on the website.


WHAT'S THE WEATHER LIKE?
Location:
(???),(???).


1.3 Essentials of Business Quality Management
Businesses are driven by an active communication chain that drives the business process. The effectiveness of teamwork and management depends on effective communication. However, the communication chain can be interrupted by bottlenecks in the flow of data, inconsistent or misleading reporting, and other communication breakdowns. Quality standards help ensure that processes related to production and quality control are subject to timely, data-driven management. In essence the ability of a business to fix a problem depends on the quality of communications that provide access to the description of the true nature and extend of the problem and knowledge of possible remedies.
Meaningful communication requires a reciprocal interaction between the speaker and the listener. As shown in the following table, social norms and good ethicate depend on transmission of a message and an appropriate response. The communication chain is lost when messages in either direction are lost or misinterpreted. The growing use of social media with its emphasis on icons or one word responses has often been blamed for the reduction in quality of personal verbal and written skills. Interaction with customers and suppliers depends on clear and effective communication.
| Initiation message | Response message |
|---|---|
| Greeting | Acknowledgement |
| Question | Response |
| Proposal | Acceptance/Rejection |
| Command | Action |
| Accusation | Acceptance/Rebuttal |
1.3.1 ISO9000/ISO9001
ISO 9000 was first published in 1987 by the International Organization for Standardization (ISO). The derivative quality standards help organizations address the needs of customers and while meeting relevant statutory and regulatory requirements.(International Organization for Standardization 2019) The ISO9001 standards provide guidance and tools for companies and organizations who want to ensure that their processes regularly deliver products and services that meet customer’s requirements. It also defines the requirements for certification against these standards which are reviewed and revised every 5 years.(International Organization for Standardization 2015)
- Point 1: Clear customer understanding of the goods or services offered within a business contract.
- Point 2: Verification of intended results to ensure that the terms of the business contract were met.
- Point 3: Prevention of undesired effects that might cause delays or problems in the delivery of goods and services
- Point 4: Improve performance based on the information gathered
An example of an ISO9001 compliant transaction
Discuss what points of the ISO9001 standard is satisfied by the follow stages of a simple business transaction at a restuarant.
- The customer enters a restaurant and is given a menu with pictures of the food.
- The waiter takes the order and repeats the order back to the customer for confirmation.
- The waiter brings the food and doubles check that the order is complete.
- The waiter comes back to check if everything is okay.
- The cashier checks that all was well when the bill is paid.
- The whole transaction is recorded and the receipt gives a website for feedback.
- The customer’s feedback on the website is analyzed for patterns of service that could be improved.
Exercise: ISO9001 and MacDonalds
Worldwide MacDonald is a successful multinational enterprise run by staff most of which are under the age of 21 and yet it is a certified ISO9001 company. When a customer orders food at any MacDonald outlet in the world, the interaction between the customer and the counter staff is always the same.
- Create a swim lane workflow diagram to describe the information flow in the conversation between the customer, the counter staff, the kitchen staff, the accounting system, and the point-of-sale computer system.
- Identify how the basic principles of ISO9001 principles for quality management are a ddressed by this basic operating procedure..
References
International Organization for Standardization. 2015. “ISO 9001:2015(en) Quality Management Systems.” https://www.iso.org/obp/ui/#iso:std:iso:9001.
International Organization for Standardization. 2019. “The Iso 9000 Family - Quality Management.” https://www.iso.org/iso-9001-quality-management.html.


“So last night I was watching a movie. The storyline was conventional, ‘boy rescues the girl from grave dangers’. After the movie ended, I realized something. Throughout the movie, all my focus was on the girl. Her beauty captured all my attention and at that moment of admiration, I imagined myself as the hero character who can give up all his hopes and dreams to be her rescuer”, said the boy to the sage.
The boy was a little unsettled by such experiences he had encounter now and then. With a hope to get some clarity, he reached out to the sage who was passing by his town and had taken shelter under a nearby tree.
The sage kept on listening to the boy.
“This scares me because It’s not the first time I’ve felt that way. How can I give up my dreams with such an ease? Are my dreams so trivial? Or is it I don’t believe in them”.
Now the boy was eagerly waiting for some answer.
After a significant pause, the sage replied, “Everyone wants to possess the beauty that they desire the most. It’s not an imperfection in you and feeling either shallow or scared of such emotions is the worst thing we can do as a human. This emotion is the ultimate truth ingrained in human consciousness because beauty makes our soul happy.”
“I understand the point you’re making”, replied the boy in despair. “I was looking for a solution though”.
This brought a smile on the sage’s face. It was the same response that he had heard many times. All his life he had multiple encounters with thousands of people and everyone was looking for answers, but rarely someone wanted to understand the question itself.
“It’s not my place to give you a solution, but I can tell you about the beauty that one should desire and the beauty that one should admire, from a distance”, and the sage began explaining.
“The charm of a rose is quite captivating.  When you pluck it and keep it on your desk in an attempt to capture that feeling for eternity, you are destined to fail miserably. It might hold your attention for a few days or a week, but when the charm is all gone, there’s only one place where that rose ends up at.”
“Why does this happen? Because It cannot offer you something new, besides the fragrance, to which you ultimately get habituated, and it’s vivid color that gradually fades away.”
“The beauty that can present itself in different forms and shapes, should be treated as of higher significance. Think about the beauty of a night sky. Every night is an opportunity of finding something new and fascinating in a sky full of sparkling stars. It evolves every day and you can always find something that can leave you awestruck. If you can find something like night sky, that’s the beauty that one can desire to hold on to.”
“So you’re saying that the girl in the movie is like a rose?” Asked the boy.
“No, All I am saying is respect these emotions that arise in you but enhance your ability to evaluate whether those emotions lead to a plucked rose or a magnificent night sky.”
“Oh. That makes sense”, replied the boy. “So have you found your magnificent night sky?” Asked the boy with a mischievous grin.
“Well..!!”


TimerManager module
import paho.mqtt.client as mqtt import stmpy import logging from threading import Thread import json MQTT_BROKER = 'test.mosquitto.org' MQTT_PORT = 1883 MQTT_TOPIC_INPUT = 'ttm4115/command' MQTT_TOPIC_OUTPUT = 'ttm4115/answer' class TimerLogic: """ State Machine for a named timer. This is the support object for a state machine that models a single timer. """ def __init__(self, name, duration, component): self._logger = logging.getLogger(__name__) self.name = name self.duration = duration self.component = component def started(self): self.stm.start_timer('t', self.duration * 1000) self._logger.debug('New timer {} with duration {} started.' .format(self.name, self.duration)) def timer_completed(self): self._logger.debug('Timer {} expired.'.format(self.name)) self.stm.terminate() def report_status(self): self._logger.debug('Checking timer status.'.format(self.name)) time = int(self.stm.get_timer('t') / 1000) message = 'Timer {} has about {} seconds left'.format(self.name, time) self.component.mqtt_client.publish(MQTT_TOPIC_OUTPUT, message) def create_machine(timer_name, duration, component): """ Create a complete state machine instance for the timer object. Note that this method is static (no self argument), since it is a helper method to create this object. """ timer_logic = TimerLogic(name=timer_name, duration=duration, component=component) t0 = {'source': 'initial', 'target': 'active', 'effect': 'started'} t1 = { 'source': 'active', 'target': 'completed', 'trigger': 't', 'effect': 'timer_completed'} t2 = { 'source': 'active', 'trigger': 'report', 'target': 'active', 'effect': 'report_status'} timer_stm = stmpy.Machine(name=timer_name, transitions=[t0, t1, t2], obj=timer_logic) timer_logic.stm = timer_stm return timer_stm class TimerManagerComponent: """ The component to manage named timers in a voice assistant. This component connects to an MQTT broker and listens to commands. To interact with the component, do the following: * Connect to the same broker as the component. You find the broker address in the value of the variable `MQTT_BROKER`. * Subscribe to the topic in variable `MQTT_TOPIC_OUTPUT`. On this topic, the component sends its answers. * Send the messages listed below to the topic in variable `MQTT_TOPIC_INPUT`. {"command": "new_timer", "name": "spaghetti", "duration":50} {"command": "status_all_timers"} {"command": "status_single_timer", "name": "spaghetti"} """ def on_connect(self, client, userdata, flags, rc): self._logger.debug('MQTT connected to {}'.format(client)) def on_message(self, client, userdata, msg): """ Processes incoming MQTT messages. We assume the payload of all received MQTT messages is an UTF-8 encoded string, which is formatted as a JSON object. The JSON object contains a field called `command` which identifies what the message should achieve. As a reaction to a received message, we can for example do the following: * create a new state machine instance to handle the incoming messages, * route the message to an existing state machine session, * handle the message right here, * throw the message away. """ self._logger.debug('Incoming message to topic {}'.format(msg.topic)) # encdoding from bytes to string. This try: payload = json.loads(msg.payload.decode("utf-8")) except Exception as err: self._logger.error('Message sent to topic {} had no valid JSON. Message ignored. {}'.format(msg.topic, err)) return command = payload.get('command') self._logger.debug('Command in message is {}'.format(command)) if command == 'new_timer': try: print(type(self)) timer_name = payload.get('name') duration = int(payload.get('duration')) # create a new instance of the timer logic state machine timer_stm = TimerLogic.create_machine(timer_name, duration, self) # add the machine to the driver to start it self.stm_driver.add_machine(timer_stm) except Exception as err: self._logger.error('Invalid arguments to command. {}'.format(err)) elif command == 'status_all_timers': s = "List of all timers" # We loop over all state machines in the driver. All of them are a # timer that we should include in our list that we present to the # user. for name, stm in self.stm_driver._stms_by_id.items(): time = int(stm.get_timer('t')/1000) s = s + 'Timer {} has about {} seconds left. '.format(stm.id, time) self.mqtt_client.publish(MQTT_TOPIC_OUTPUT, s) elif command == 'status_single_timer': # report the status of a single timer try: print(type(self)) timer_name = payload.get('name') # send a signal to the corresponding timer state machine to # trigger reporting the status. self.stm_driver.send_signal('report', timer_name) except Exception as err: self._logger.error('Invalid arguments to command. {}'.format(err)) else: self._logger.error('Unknown command {}. Message ignored.'.format(command)) def __init__(self): """ Start the component. ## Start of MQTT We subscribe to the topic(s) the component listens to. The client is available as variable `self.client` so that subscriptions may also be changed over time if necessary. The MQTT client reconnects in case of failures. ## State Machine driver We create a single state machine driver for STMPY. This should fit for most components. The driver is available from the variable `self.driver`. You can use it to send signals into specific state machines, for instance. """ # get the logger object for the component self._logger = logging.getLogger(__name__) print('logging under name {}.'.format(__name__)) self._logger.info('Starting Component') # create a new MQTT client self._logger.debug('Connecting to MQTT broker {} at port {}'.format(MQTT_BROKER, MQTT_PORT)) self.mqtt_client = mqtt.Client() # callback methods self.mqtt_client.on_connect = self.on_connect self.mqtt_client.on_message = self.on_message # Connect to the broker self.mqtt_client.connect(MQTT_BROKER, MQTT_PORT) # subscribe to proper topic(s) of your choice self.mqtt_client.subscribe(MQTT_TOPIC_INPUT) # start the internal loop to process MQTT messages self.mqtt_client.loop_start() # we start the stmpy driver, without any state machines for now self.stm_driver = stmpy.Driver() self.stm_driver.start(keep_active=True) self._logger.debug('Component initialization finished') def stop(self): """ Stop the component. """ # stop the MQTT client self.mqtt_client.loop_stop() # stop the state machine Driver self.stm_driver.stop() # logging.DEBUG: Most fine-grained logging, printing everything # logging.INFO: Only the most important informational log items # logging.WARN: Show only warnings and errors. # logging.ERROR. Show only error messages. debug_level = logging.DEBUG logger = logging.getLogger('__main__') logger.setLevel(debug_level) # INFO: Print less than debugging. ch = logging.StreamHandler() ch.setLevel(debug_level) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') ch.setFormatter(formatter) logger.addHandler(ch) t = TimerManagerComponent()
Module variables
var MQTT_BROKER
var MQTT_PORT
var MQTT_TOPIC_INPUT
var MQTT_TOPIC_OUTPUT
var ch
var debug_level
var formatter
var logger
var t
Classes
class TimerLogic
State Machine for a named timer.
This is the support object for a state machine that models a single timer.
class TimerLogic: """ State Machine for a named timer. This is the support object for a state machine that models a single timer. """ def __init__(self, name, duration, component): self._logger = logging.getLogger(__name__) self.name = name self.duration = duration self.component = component def started(self): self.stm.start_timer('t', self.duration * 1000) self._logger.debug('New timer {} with duration {} started.' .format(self.name, self.duration)) def timer_completed(self): self._logger.debug('Timer {} expired.'.format(self.name)) self.stm.terminate() def report_status(self): self._logger.debug('Checking timer status.'.format(self.name)) time = int(self.stm.get_timer('t') / 1000) message = 'Timer {} has about {} seconds left'.format(self.name, time) self.component.mqtt_client.publish(MQTT_TOPIC_OUTPUT, message) def create_machine(timer_name, duration, component): """ Create a complete state machine instance for the timer object. Note that this method is static (no self argument), since it is a helper method to create this object. """ timer_logic = TimerLogic(name=timer_name, duration=duration, component=component) t0 = {'source': 'initial', 'target': 'active', 'effect': 'started'} t1 = { 'source': 'active', 'target': 'completed', 'trigger': 't', 'effect': 'timer_completed'} t2 = { 'source': 'active', 'trigger': 'report', 'target': 'active', 'effect': 'report_status'} timer_stm = stmpy.Machine(name=timer_name, transitions=[t0, t1, t2], obj=timer_logic) timer_logic.stm = timer_stm return timer_stm
Ancestors (in MRO)
- TimerLogic
- builtins.object
Static methods
def __init__(
self, name, duration, component)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, name, duration, component): self._logger = logging.getLogger(__name__) self.name = name self.duration = duration self.component = component
def create_machine(
timer_name, duration, component)
Create a complete state machine instance for the timer object. Note that this method is static (no self argument), since it is a helper method to create this object.
def create_machine(timer_name, duration, component): """ Create a complete state machine instance for the timer object. Note that this method is static (no self argument), since it is a helper method to create this object. """ timer_logic = TimerLogic(name=timer_name, duration=duration, component=component) t0 = {'source': 'initial', 'target': 'active', 'effect': 'started'} t1 = { 'source': 'active', 'target': 'completed', 'trigger': 't', 'effect': 'timer_completed'} t2 = { 'source': 'active', 'trigger': 'report', 'target': 'active', 'effect': 'report_status'} timer_stm = stmpy.Machine(name=timer_name, transitions=[t0, t1, t2], obj=timer_logic) timer_logic.stm = timer_stm return timer_stm
def report_status(
self)
def report_status(self): self._logger.debug('Checking timer status.'.format(self.name)) time = int(self.stm.get_timer('t') / 1000) message = 'Timer {} has about {} seconds left'.format(self.name, time) self.component.mqtt_client.publish(MQTT_TOPIC_OUTPUT, message)
def started(
self)
def started(self): self.stm.start_timer('t', self.duration * 1000) self._logger.debug('New timer {} with duration {} started.' .format(self.name, self.duration))
def timer_completed(
self)
def timer_completed(self): self._logger.debug('Timer {} expired.'.format(self.name)) self.stm.terminate()
Instance variables
var component
var duration
var name
class TimerManagerComponent
The component to manage named timers in a voice assistant.
This component connects to an MQTT broker and listens to commands. To interact with the component, do the following:
- Connect to the same broker as the component. You find the broker address
in the value of the variable
MQTT_BROKER
. - Subscribe to the topic in variable
MQTT_TOPIC_OUTPUT
. On this topic, the component sends its answers. -
Send the messages listed below to the topic in variable
MQTT_TOPIC_INPUT
.{"command": "new_timer", "name": "spaghetti", "duration":50}
{"command": "status_all_timers"}
{"command": "status_single_timer", "name": "spaghetti"}
class TimerManagerComponent: """ The component to manage named timers in a voice assistant. This component connects to an MQTT broker and listens to commands. To interact with the component, do the following: * Connect to the same broker as the component. You find the broker address in the value of the variable `MQTT_BROKER`. * Subscribe to the topic in variable `MQTT_TOPIC_OUTPUT`. On this topic, the component sends its answers. * Send the messages listed below to the topic in variable `MQTT_TOPIC_INPUT`. {"command": "new_timer", "name": "spaghetti", "duration":50} {"command": "status_all_timers"} {"command": "status_single_timer", "name": "spaghetti"} """ def on_connect(self, client, userdata, flags, rc): self._logger.debug('MQTT connected to {}'.format(client)) def on_message(self, client, userdata, msg): """ Processes incoming MQTT messages. We assume the payload of all received MQTT messages is an UTF-8 encoded string, which is formatted as a JSON object. The JSON object contains a field called `command` which identifies what the message should achieve. As a reaction to a received message, we can for example do the following: * create a new state machine instance to handle the incoming messages, * route the message to an existing state machine session, * handle the message right here, * throw the message away. """ self._logger.debug('Incoming message to topic {}'.format(msg.topic)) # encdoding from bytes to string. This try: payload = json.loads(msg.payload.decode("utf-8")) except Exception as err: self._logger.error('Message sent to topic {} had no valid JSON. Message ignored. {}'.format(msg.topic, err)) return command = payload.get('command') self._logger.debug('Command in message is {}'.format(command)) if command == 'new_timer': try: print(type(self)) timer_name = payload.get('name') duration = int(payload.get('duration')) # create a new instance of the timer logic state machine timer_stm = TimerLogic.create_machine(timer_name, duration, self) # add the machine to the driver to start it self.stm_driver.add_machine(timer_stm) except Exception as err: self._logger.error('Invalid arguments to command. {}'.format(err)) elif command == 'status_all_timers': s = "List of all timers" # We loop over all state machines in the driver. All of them are a # timer that we should include in our list that we present to the # user. for name, stm in self.stm_driver._stms_by_id.items(): time = int(stm.get_timer('t')/1000) s = s + 'Timer {} has about {} seconds left. '.format(stm.id, time) self.mqtt_client.publish(MQTT_TOPIC_OUTPUT, s) elif command == 'status_single_timer': # report the status of a single timer try: print(type(self)) timer_name = payload.get('name') # send a signal to the corresponding timer state machine to # trigger reporting the status. self.stm_driver.send_signal('report', timer_name) except Exception as err: self._logger.error('Invalid arguments to command. {}'.format(err)) else: self._logger.error('Unknown command {}. Message ignored.'.format(command)) def __init__(self): """ Start the component. ## Start of MQTT We subscribe to the topic(s) the component listens to. The client is available as variable `self.client` so that subscriptions may also be changed over time if necessary. The MQTT client reconnects in case of failures. ## State Machine driver We create a single state machine driver for STMPY. This should fit for most components. The driver is available from the variable `self.driver`. You can use it to send signals into specific state machines, for instance. """ # get the logger object for the component self._logger = logging.getLogger(__name__) print('logging under name {}.'.format(__name__)) self._logger.info('Starting Component') # create a new MQTT client self._logger.debug('Connecting to MQTT broker {} at port {}'.format(MQTT_BROKER, MQTT_PORT)) self.mqtt_client = mqtt.Client() # callback methods self.mqtt_client.on_connect = self.on_connect self.mqtt_client.on_message = self.on_message # Connect to the broker self.mqtt_client.connect(MQTT_BROKER, MQTT_PORT) # subscribe to proper topic(s) of your choice self.mqtt_client.subscribe(MQTT_TOPIC_INPUT) # start the internal loop to process MQTT messages self.mqtt_client.loop_start() # we start the stmpy driver, without any state machines for now self.stm_driver = stmpy.Driver() self.stm_driver.start(keep_active=True) self._logger.debug('Component initialization finished') def stop(self): """ Stop the component. """ # stop the MQTT client self.mqtt_client.loop_stop() # stop the state machine Driver self.stm_driver.stop()
Ancestors (in MRO)
- TimerManagerComponent
- builtins.object
Static methods
def __init__(
self)
Start the component.
Start of MQTT
We subscribe to the topic(s) the component listens to.
The client is available as variable self.client
so that subscriptions
may also be changed over time if necessary.
The MQTT client reconnects in case of failures.
State Machine driver
We create a single state machine driver for STMPY. This should fit
for most components. The driver is available from the variable
self.driver
. You can use it to send signals into specific state
machines, for instance.
def __init__(self): """ Start the component. ## Start of MQTT We subscribe to the topic(s) the component listens to. The client is available as variable `self.client` so that subscriptions may also be changed over time if necessary. The MQTT client reconnects in case of failures. ## State Machine driver We create a single state machine driver for STMPY. This should fit for most components. The driver is available from the variable `self.driver`. You can use it to send signals into specific state machines, for instance. """ # get the logger object for the component self._logger = logging.getLogger(__name__) print('logging under name {}.'.format(__name__)) self._logger.info('Starting Component') # create a new MQTT client self._logger.debug('Connecting to MQTT broker {} at port {}'.format(MQTT_BROKER, MQTT_PORT)) self.mqtt_client = mqtt.Client() # callback methods self.mqtt_client.on_connect = self.on_connect self.mqtt_client.on_message = self.on_message # Connect to the broker self.mqtt_client.connect(MQTT_BROKER, MQTT_PORT) # subscribe to proper topic(s) of your choice self.mqtt_client.subscribe(MQTT_TOPIC_INPUT) # start the internal loop to process MQTT messages self.mqtt_client.loop_start() # we start the stmpy driver, without any state machines for now self.stm_driver = stmpy.Driver() self.stm_driver.start(keep_active=True) self._logger.debug('Component initialization finished')
def on_connect(
self, client, userdata, flags, rc)
def on_connect(self, client, userdata, flags, rc): self._logger.debug('MQTT connected to {}'.format(client))
def on_message(
self, client, userdata, msg)
Processes incoming MQTT messages.
We assume the payload of all received MQTT messages is an UTF-8 encoded
string, which is formatted as a JSON object. The JSON object contains
a field called command
which identifies what the message should achieve.
As a reaction to a received message, we can for example do the following:
- create a new state machine instance to handle the incoming messages,
- route the message to an existing state machine session,
- handle the message right here,
- throw the message away.
def on_message(self, client, userdata, msg): """ Processes incoming MQTT messages. We assume the payload of all received MQTT messages is an UTF-8 encoded string, which is formatted as a JSON object. The JSON object contains a field called `command` which identifies what the message should achieve. As a reaction to a received message, we can for example do the following: * create a new state machine instance to handle the incoming messages, * route the message to an existing state machine session, * handle the message right here, * throw the message away. """ self._logger.debug('Incoming message to topic {}'.format(msg.topic)) # encdoding from bytes to string. This try: payload = json.loads(msg.payload.decode("utf-8")) except Exception as err: self._logger.error('Message sent to topic {} had no valid JSON. Message ignored. {}'.format(msg.topic, err)) return command = payload.get('command') self._logger.debug('Command in message is {}'.format(command)) if command == 'new_timer': try: print(type(self)) timer_name = payload.get('name') duration = int(payload.get('duration')) # create a new instance of the timer logic state machine timer_stm = TimerLogic.create_machine(timer_name, duration, self) # add the machine to the driver to start it self.stm_driver.add_machine(timer_stm) except Exception as err: self._logger.error('Invalid arguments to command. {}'.format(err)) elif command == 'status_all_timers': s = "List of all timers" # We loop over all state machines in the driver. All of them are a # timer that we should include in our list that we present to the # user. for name, stm in self.stm_driver._stms_by_id.items(): time = int(stm.get_timer('t')/1000) s = s + 'Timer {} has about {} seconds left. '.format(stm.id, time) self.mqtt_client.publish(MQTT_TOPIC_OUTPUT, s) elif command == 'status_single_timer': # report the status of a single timer try: print(type(self)) timer_name = payload.get('name') # send a signal to the corresponding timer state machine to # trigger reporting the status. self.stm_driver.send_signal('report', timer_name) except Exception as err: self._logger.error('Invalid arguments to command. {}'.format(err)) else: self._logger.error('Unknown command {}. Message ignored.'.format(command))
def stop(
self)
Stop the component.
def stop(self): """ Stop the component. """ # stop the MQTT client self.mqtt_client.loop_stop() # stop the state machine Driver self.stm_driver.stop()
Instance variables
var mqtt_client
var stm_driver


Contents
Short Descriptions
|
is a utility for reclustering tables in a PostgreSQL database. |
|
|
creates a new PostgreSQL database. |
|
|
defines a new PostgreSQL user account. |
|
|
removes a PostgreSQL database. |
|
|
removes a PostgreSQL user account. |
|
|
is the embedded SQL preprocessor. |
|
|
creates a new database cluster. |
|
|
resolves OIDs (Object IDs) and file nodes in a PostgreSQL data directory. |
|
|
cleans up PostgreSQL WAL (write-ahead log) archive files. |
|
|
takes base backups of a running PostgreSQL cluster. |
|
|
retrieves PostgreSQL version information. |
|
|
returns information initialized during initdb, such as the catalog version and server locale. |
|
|
controls stopping and starting the database server. |
|
|
dumps database data and metadata into scripts which are used to recreate the database. |
|
|
recursively calls pg_dump for each database in a cluster. |
|
|
checks the connection status of a PostgreSQL server. |
|
|
is used to stream write-ahead logs from a PostgreSQL server. |
|
|
controls PostgreSQL logical decoding streams. |
|
|
resets the write-ahead log and other control information of a PostgreSQL database cluster. |
|
|
creates databases from dump files created by pg_dump. |
|
|
synchronizes a PostgreSQL data directory with another data directory that was forked from the first one. |
|
|
supports the creation of a PostgreSQL warm standby server. |
|
|
determines fastest wal_sync method for PostgreSQL. |
|
|
measures timing overhead. |
|
|
upgrades a PostgreSQL server instance. |
|
|
displays a human-readable rendering of the write-ahead log of a PostgreSQL database cluster. |
|
|
runs a benchmark test on PostgreSQL. |
|
|
is a support script used to delete a module from a PL/Tcl table. The command requires the Pgtcl package to be installed also. |
|
|
is a support script used to list the modules in a PL/Tcl table. The command requires the Pgtcl package to be installed also. |
|
|
is a support script used to load a module into a PL/Tcl table. The command requires the Pgtcl package to be installed also. |
|
|
is the PostgreSQL database server. |
|
|
(deprecated, a symlink to postgres) is a multi-user database daemon. |
|
|
is a console based database shell. |
|
|
is a utility for rebuilding indexes in a database. |
|
|
compacts databases and generates statistics for the query analyzer. |
|
|
removes orphaned large objects from a PostgreSQL database. |
|
|
contains functions to support embedded SQL in C programs. |
|
|
is the ecpg compatibility library. |
|
|
is the port-specific subsystem of the Postgres backend. |
|
|
contains functions for dealing with Postgres data types. |
|
|
is the C programmer's API to Postgres. |


Motivation
Hi again! Since you are visiting this page means you are interested in knowing about my past experience with computing devices. My experience with computers started when I was a child. My dad owned a small internet cafe, therefore I grew up seeing different computing devices around me. While helping my dad and the staff there, my motivation towards computing gadgets increased. I was happy as I was learning more and more each day I spent at the internet cafe.
Experience
The first computers I saw in the internet cafe were the computers with the cathode ray monitors as shown below. After some years, dad changed all computers to flat screen monitors. The following is the trend of computer changing I experienced.


Interacting with the B.C. Data CatalogueFunctions to search, browse, list, and explore records and their resources (datasets) in the B.C. Data Catalogue |
|
|---|---|
Load the B.C. Data Catalogue URL into an HTML browser |
|
Search the B.C. Data Catalogue |
|
Get the valid values for a facet (that you can use in |
|
Return a full list of the names of B.C. Data Catalogue records |
|
Show a single B.C. Data Catalogue record |
|
Direct downloads of datasetsDirectly dowload (or preview) datasets (resources) from the B.C. Data Catalogue |
|
Download and read a resource from a B.C. Data Catalogue record |
|
Get map from the B.C. Web Service |
|
Formats supported and loading functions |
|
Querying data from a Web Service catalogue recordIssue queries using |
|
Query data from the B.C. Web Service |
|
Describe a Web Service feature |
|
Filter a query from Web Service call |
|
Select columns from Web Service call |
|
Force collection of Web Service request from B.C. Data Catalogue |
|
|
|
CQL Geometry Predicates |
CQL escaping |
|
Retrieve options used in bcdata, their value if set and the default value. |


{% extends "../htmlForms.html" %} {% block demoSectionClasses %}demo_html_forms_single{% endblock %} {% block meta_title %}Demos - HTML Forms - File upload{% endblock %} {% block meta_description %}File upload using Spincast{% endblock %} {% set demoId = "fileUpload" %} {% block demoBody %}
Select a file and submit it.
Only an image of less than 200KB will be accepted! Otherwise, you're going to see some validation messages.
{% if uploadFileBase64ImageSrc is not empty | default(false) %}Uploaded image :
{% endif %}
HTML
template (the frontend part) :
fileUpload.html
Uploading a file is very easy. On the client-side : {% verbatim %}
<form action="#form" method="post" accept-charset="UTF-8" enctype="multipart/form-data"> //... <input type="file" name="demoForm.fileToUpload" /> // ... {{validation['demoForm.fileToUpload'] | validationMessages()}} // ... <button id="subBtn" type="submit" class="btn btn-primary">Submit</button> </form>
Explanation :
enctype="multipart/form-data"
attribute.
file
input, with
a meaningful "name"
attribute.
Validation Messages
resulting
from the validation of the file.
On the server side, we get the uploaded file using its "name"
. Note that
multiple uploaded files can have the same name, but since we only have one here, we
use the getUploadedFileFirst(...)
method from our
Request Context :
File uploadedFile = context.request().getUploadedFileFirst("demoForm.fileToUpload");
We can then run validation on this file and process it. Here's for example how we validate that it is actually an image :
try { ImageIO.read(uploadedFile).toString(); } catch(Exception e) { form.addError("fileToUpload", "fileToUpload_notValidImage", "The file must be a valid image of type PNG, JPEG, GIF or BMP."); }
Explanation :
javax.imageio.ImageIO
class to try to read
the image. It's it's not a valid image, an exception is
thrown.
Validation Message
to our form to record the fact that the validation failed.
Make sure you also try the first demo of this section, Introduction - Single field which introduces forms and validation using Spincast.
Otherwise, you can learn everything about forms and validation in the dedicated Forms section of the documentation.
{% endblock %}


We’ve just pushed 2.0.0-alpha.34. A lot of changes have been going into the alpha versions to support more types of games and more complex usage.
The biggest change is the introduction of Mdx.timestepMode
which allows developers to change their game’s timestep to use normal deltas (time since last frame) or a physics-based timestep implementing the updatePhysics
method in their game. Previously, mini2Dx forced developers to use a physics-based approach but this is not ideal for all games. Now developers have the flexibility to choose their timestep based on their game.
Github Packages have started to enforce lowercase for all artifacts. As such, from 2.0.0-alpha.34, the artifact IDs in the your Gradle dependencies will need to be lowercase.
Your dependencies should look like:
compile "org.mini2Dx:mini2dx-core:$mini2DxVersion"
compile "org.mini2Dx:mini2dx-tiled:$mini2DxVersion"
We have an internal deadline of December for a project to provide the consoles runtime on. There’s a good few optimisations and bug fixes to be done but once everything is stable-ish, we’ll be releasing the mini2Dx 2.0 beta along with the new website!
In the meantime, make sure to join our community on Discord!
We’ve just released mini2Dx 2.0.0-alpha.22 which adds support for LibGDX’s LWJGL 3 runtime. This will provide improved support for many things including internationalized input handling, ARM architecture, multi-monitor setups and more!
Moving forward there will be two LibGDX desktop runtimes:
compile "org.mini2Dx:mini2Dx-libgdx-desktop-lwjgl2:2.0.0-alpha.22"
OR
compile "org.mini2Dx:mini2Dx-libgdx-desktop-lwjgl3:2.0.0-alpha.22"
DesktopMini2DxConfig has now been replaced with Lwjgl2Mini2DxConfig and Lwjgl3Mini2DxConfig.
If you haven’t upgraded to the 2.0.0 alpha yet, you can find more info here page to update your version. If you find any issues, please report them on the Issue Tracker.
We’re still working on supporting games consoles but have been delayed due to everyone being busy with work. However, progress is being made and we hope to have a beta version soom(TM)!
In the meantime, make sure to join our community on Discord!
We’ve just released mini2Dx 2.0.0-alpha.15 which contains a new XML format for UI thanks to Dan Dudley. Originally, we had planned on working on a new format in 2.1 but thanks to Dan’s massive contribution this will be part of 2.0.
The new format is much simpler and comes with an XML schema so that IDEs can auto-complete and validate your XML.
A sample of the new format can be found below. As always, follow the updating mini2Dx page to update your version.
<container xmlns="https://github.com/mini2Dx/mini2Dx">
<flex-row>

<select id="select1" style="default">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
<option value="4">Option 4</option>
</select>

<text-button id="button1" text="" style="default"/>
<image-button id="button2" style="default">
<normal-texture>button.png</normal-texture>
</image-button>

<text-box id="textBox1" style="default"/>

</flex-row>
</container>
We’re still working on minor fixes to support games consoles. Once we have a stable build running in January/February, we’ll transition 2.0 to beta. As mentioned before, the alpha version is considered stable for desktop and mobile platforms and the API is near-final.
We’re also working on a new website as part of 2.0 and hope to launch the new site during the beta. The new website will feature a whole new design with more documentation, tutorials and sample projects.
In the meantime, make sure to join our community on Discord!
We’ve just released mini2Dx 2.0.0-alpha.11 which contains the following changes:
As always, follow the updating mini2Dx page to update your version.
2.0.0-alpha.11 will be the last alpha build of 2.0.0. This version is considered the near-final API that will be used for the final 2.0.0 release.
Normally alpha/beta would be considered unstable, however, we have been using the alpha builds for Alchemic Cutie without issue. In fact, 2.0.0-alpha.11 performs better than the latest 1.9.x release! So if you’ll be upgrading to mini2Dx 2.0 in the future, we recommend using alpha.11 to test your code.
Up next will be 2.0.0-beta.1 which will be the first build supporting games consoles. There’s still a few issues left for us to fix but we’re really close to having a build of Alchemic Cutie running on Nintendo Switch. As mentioned before, the console runtime will require a license for a cross-compiler (more info on pricing/availability soon).
After 2.0 is released, we’ll be focusing on fixes and optimisations before moving on to 2.1. If there are features you’d like to see in 2.1, make sure to add them to the Issue Tracker!
We’ve just released mini2Dx 2.0.0-alpha.9 which contains the following changes:
As always, follow the updating mini2Dx page to update your version.
An easy to use API with powerful features and plugins to help you build your next game


--- title: Trove query parser keywords: fastai sidebar: home_sidebar summary: "Convert a query from the Trove web interface into a set of parameters that can be used with the Trove API." description: "Convert a query from the Trove web interface into a set of parameters that can be used with the Trove API." nb_path: "index.ipynb" ---
parse_query
function.from trove_query_parser.parser import parse_query
parse_query('https://trove.nla.gov.au/search/category/newspapers?keyword=wragge&l-artType=newspapers&l-state=Queensland&l-category=Article&l-illustrationType=Cartoon')
See the documentation for a more detailed example.
Created by Tim Sherratt (@wragge) for the GLAM Workbench.


SMTP is the main transport in Nodemailer for delivering messages. SMTP is also the protocol used between different email hosts, so its truly universal. Almost every email delivery provider supports SMTP based sending, even if they mainly push their API based sending. APIs might have more features but using these also means vendor lock-in while in case of SMTP you only need to change the configuration options to replace one provider with another and you’re good to go.
let transporter = nodemailer.createTransport(options[, defaults])
Where
Alternatively you could use a connection url instead of an object for the options. Use ‘smtp:' or ‘smtps:' as the protocol in the url.
let poolConfig = "smtps://username:password@smtp.example.com/?pool=true";
Hostnames for the host field are resolved using dns.resolve()
. If you are using a non-resolvable hostname (eg. something listed in /etc/hosts or you are using different resolver for you Node apps) then provide the IP address of the SMTP server as host and for the actual hostname user tls.servername parameter. This way not hostname resolving is attempted but TLS validation still works.
host
was set to an IP addressSetting secure to false does not mean that you would not use an encrypted connection. Most SMTP servers allow connection upgrade via STARTTLS command but to use this you have to connect using plaintext first
true
then logs to console. If value is not set or is false
then nothing is loggedThis example would connect to a SMTP server separately for every single message
nodemailer.createTransport({
host: "smtp.example.com",
port: 587,
secure: false, // upgrade later with STARTTLS
auth: {
user: "username",
pass: "password",
},
});
This example would set up pooled connections against a SMTP server on port 465
nodemailer.createTransport({
pool: true,
host: "smtp.example.com",
port: 465,
secure: true, // use TLS
auth: {
user: "username",
pass: "password",
},
});
This config would open a connection to TLS server with self-signed or invalid TLS certificate
nodemailer.createTransport({
host: "my.smtp.host",
port: 465,
secure: true, // use TLS
auth: {
user: "username",
pass: "pass",
},
tls: {
// do not fail on invalid certs
rejectUnauthorized: false,
},
});
If authentication data is not present, the connection is considered authenticated from the start. Otherwise you would need to provide the authentication options object.
auth is the authentication object
For authenticating using OAuth2 instead of normal auth, see OAuth2 options for the auth object here.
You can also define custom authentication handlers for protocols that are not natively supported by Nodemailer, see NTLM handler as an example of such custom handler.
You can verify your SMTP configuration with verify(callback) call (also works as a Promise). If it returns an error, then something is not correct, otherwise the server is ready to accept messages.
// verify connection configuration
transporter.verify(function (error, success) {
if (error) {
console.log(error);
} else {
console.log("Server is ready to take our messages");
}
});
Be aware though that this call only tests connection and authentication but it does not check if the service allows you to use a specific envelope From address or not.


abstract fun allowSelectMultiple(): Boolean
Supply the option of whether the ChildItems of this ParentItem can be multi-selected
Return Whether multi-selected ChildItems are allowed