Tsearch2 - Introduction
[Online version] of this document is available.
The tsearch2 module is available to add as an extension to the PostgreSQL database to allow for Full Text Indexing. This document is an introduction to installing, configuring, using and maintaining the database with the tsearch2 module activated.
Please, note, tsearch2 module is fully incompatible with old tsearch, which is deprecated in 7.4 and will be obsoleted in 7.5.
USING TSEARCH2 AND POSTGRESQL FOR A WEB BASED SEARCH ENGINE
This documentation is provided as a short guide on how to quickly get up and running with tsearch2 and PostgreSQL, for those who want to implement a full text indexed based search engine. It is not meant to be a complete in-depth guide into the full ins and outs of the contrib/tsearch2 module, and is primarily aimed at beginners who want to speed up searching of large text fields, or those migrating from other database systems such as MS-SQL.
The README.tsearch2 file included in the contrib/tsearch2 directory contains a brief overview and history behind tsearch. This can also be found online [right here].
Further in depth documentation such as a full function reference, and user guide can be found online at the [tsearch documentation home].
ACKNOWLEDGEMENTS
Robert John Shepherd originally wrote this documentation for the previous version of tsearch module (v1) included with the postgres release. I took his documentation and updated it to comply with the tsearch2 modifications.
Robert's original acknowledgements:
"Thanks to Oleg Bartunov for taking the time to answer many of my questions regarding this module, and also to Teodor Sigaev for clearing up the process of making your own dictionaries. Plus of course a big thanks to the pair of them for writing this module in the first place!"
I would also like to extend my thanks to the developers, and Oleg Bartunov for all of his direction and help with the new features of tsearch2.
OVERVIEW
MS-SQL provides a full text indexing (FTI) system which enables the fast searching of text based fields, very useful for websites (and other applications) that require a results set based on key words. PostgreSQL ships with a contributed module called tsearch2, which implements a special type of index that can also be used for full text indexing. Further more, unlike MS' offering which requires regular incremental rebuilds of the text indexes themselves, tsearch2 indexes are always up-to-date and keeping them so induces very little overhead.
Before we get into the details, it is recommended that you have installed and tested PostgreSQL, are reasonably familiar with databases, the SQL query language and also understand the basics of connecting to PostgreSQL from the local shell. This document isn't intended for the complete PostgreSQL newbie, but anyone with a reasonable grasp of the basics should be able to follow it.
INSTALLATION
Starting with PostgreSQL version 7.4 tsearch2 is now included in the contrib directory with the PostgreSQL sources. contrib/tsearch2 is where you will find everything needed to install and use tsearch2. Please note that tsearch2 will also work with PostgreSQL version 7.3.x, but it is not the module included with the source distribution. You will have to download the module separately and install it in the same fashion.
I installed the tsearch2 module to a PostgreSQL 7.3 database from the contrib directory without squashing the original (old) tsearch module. What I did was move the modules tsearch src driectory into the contrib tree under the name tsearchV2.
Step one is to download the tsearch V2 module :
[http://www.sai.msu.su/~megera/postgres/gist/tsearch/V2/] (check Development History for latest stable version !)
tar -zxvf tsearch-v2.tar.gz mv tsearch2 PGSQL_SRC/contrib/ cd PGSQL_SRC/contrib/tsearch2
If you are installing from PostgreSQL version 7.4 or higher, you can skip those steps and just change to the contrib/tsearch2 directory in the source tree and continue from there.
Then continue with the regular building and installation process
gmake gmake install gmake installcheck
That is pretty much all you have to do, unless of course you get errors. However if you get those, you better go check with the mailing lists over at http://www.postgresql.org or http://openfts.sourceforge.net/ since its never failed for me.
The directory in the contib/ and the directory from the archive is called tsearch2. Tsearch2 is completely incompatible with the previous version of tsearch. This means that both versions can be installed into a single database, and migration the new version may be much easier.
NOTE: the previous version of tsearch found in the contrib/tsearch directory is depricated. ALthough it is still available and included within PostgreSQL version 7.4. It will be removed in version 7.5.
ADDING TSEARCH2 FUNCTIONALITY TO A DATABASE
We should create a database to use as an example for the remainder of this file. We can call the database "ftstest". You can create it from the command line like this:
#createdb ftstest
If you thought installation was easy, this next bit is even easier. Change to the PGSQL_SRC/contrib/tsearch2 directory and type:
psql ftstest < tsearch2.sql
The file "tsearch2.sql" holds all the wonderful little goodies you need to do full text indexing. It defines numerous functions and operators, and creates the needed tables in the database. There will be 4 new tables created after running the tsearch2.sql file : pg_ts_dict, pg_ts_parser, pg_ts_cfg, pg_ts_cfgmap are added.
You can check out the tables if you like:
#psql ftstest ftstest=# \d List of relations Schema | Name | Type | Owner --------+--------------+-------+---------- public | pg_ts_cfg | table | kopciuch public | pg_ts_cfgmap | table | kopciuch public | pg_ts_dict | table | kopciuch public | pg_ts_parser | table | kopciuch (4 rows)
You may need to grant permissions to use on pg_ts_dict, pg_ts_parser, pg_ts_cfg, pg_ts_cfgmap tables to let non-superuser works with tsearch2. GRANT SELECT should be enough for search-only access.
TYPES AND FUNCTIONS PROVIDED BY TSEARCH2
The first thing we can do is try out some of the types that are provided for us. Lets look at the tsvector type provided for us:
SELECT 'Our first string used today'::tsvector; tsvector --------------------------------------- 'Our' 'used' 'first' 'today' 'string' (1 row)
The results are the words used within our string. Notice they are not in any particular order. The tsvector type returns a string of space separated words.
SELECT 'Our first string used today first string'::tsvector; tsvector ----------------------------------------------- 'Our' 'used' 'again' 'first' 'today' 'string' (1 row)
Notice the results string has each unique word ('first' and 'string' only appear once in the tsvector value). Which of course makes sense if you are searching the full text ... you only need to know each unique word in the text.
Those examples were just casting a text field to that of type tsvector. Lets check out one of the new functions created by the tsearch2 module.
The function to_tsvector has 3 possible signatures:
to_tsvector(oid, text); to_tsvector(text, text); to_tsvector(text);
We will use the second method using two text fields. The overloaded methods provide us with a way to specifiy the way the searchable text is broken up into words (Stemming process). Right now we will specify the 'default' configuration. See the section on TSEARCH2 CONFIGURATION to learn more about this.
SELECT to_tsvector('default', 'Our first string used today first string'); to_tsvector -------------------------------------------- 'use':4 'first':2,6 'today':5 'string':3,7 (1 row)
The result returned from this function is of type tsvector. The results came about by this reasoning: All of the words in the text passed in are stemmed, or not used because they are stop words defined in our configuration. Each lower case morphed word is returned with all of the positons in the text.
In this case the word "Our" is a stop word in the default configuration. That means it will not be included in the result. The word "first" is found at positions 2 and 6 (although "Our" is a stop word, it's position is maintained). The word(s) positioning is maintained exactly as in the original string. The word "used" is morphed to the word "use" based on the default configuration for word stemming, and is found at position 4. The rest of the results follow the same logic. Just a reminder again ... the order of the 'word' position in the output is not in any kind of order. (ie 'use':4 appears first)
If you want to view the output of the tsvector fields without their positions, you can do so with the function "strip(tsvector)".
SELECT strip(to_tsvector('default', 'Our first string used today first string')); strip -------------------------------- 'use' 'first' 'today' 'string'
If you wish to know the number of unique words returned in the tsvector you can do so by using the function "length(tsvector)"
SELECT length(to_tsvector('default', 'Our first string used today first string')); length -------- 4 (1 row)
Lets take a look at the function to_tsquery. It also has 3 signatures which follow the same rational as the to_tsvector function:
to_tsquery(oid, text); to_tsquery(text, text); to_tsquery(text);
Lets try using the function with a single word :
SELECT to_tsquery('default', 'word'); to_tsquery ----------- 'word' (1 row)
I call the function the same way I would a to_tsvector function, specifying the 'default' configuration for morphing, and the result is the stemmed output 'word'.
Lets attempt to use the function with a string of multiple words:
SELECT to_tsquery('default', 'this is many words'); ERROR: Syntax error
The function can not accept a space separated string. The intention of the to_tsquery function is to return a type of "tsquery" used for searching a tsvector field. What we need to do is search for one to many words with some kind of logic (for now simple boolean).
SELECT to_tsquery('default', 'searching|sentence'); to_tsquery ---------------------- 'search' | 'sentenc' (1 row)
Notice that the words are separated by the boolean logic "OR", the text could contain boolean operators &,|,!,() with their usual meaning.
You can not use words defined as being a stop word in your configuration. The function will not fail ... you will just get no result, and a NOTICE like this:
SELECT to_tsquery('default', 'a|is¬|!the'); NOTICE: Query contains only stopword(s) or doesn't contain lexem(s), ignored to_tsquery ----------- (1 row)
That is a beginning to using the types, and functions defined in the tsearch2 module. There are numerous more functions that I have not touched on. You can read through the tsearch2.sql file built when compiling to get more familiar with what is included.
INDEXING FIELDS IN A TABLE
The next stage is to add a full text index to an existing table. In this example we already have a table defined as follows:
CREATE TABLE tblMessages ( intIndex int4, strTopic varchar(100), strMessage text );
We are assuming there are several rows with some kind of data in them. Any data will do, just do several inserts with test strings for a topic, and a message. here is some test data I inserted. (yes I know it's completely useless stuff ;-) but it will serve our purpose right now).
INSERT INTO tblMessages VALUES ('1', 'Testing Topic', 'Testing message data input'); INSERT INTO tblMessages VALUES ('2', 'Movie', 'Breakfast at Tiffany\'s'); INSERT INTO tblMessages VALUES ('3', 'Famous Author', 'Stephen King'); INSERT INTO tblMessages VALUES ('4', 'Political Topic', 'Nelson Mandella is released from prison'); INSERT INTO tblMessages VALUES ('5', 'Nursery rhyme phrase', 'Little jack horner sat in a corner'); INSERT INTO tblMessages VALUES ('6', 'Gettysburg address quotation', 'Four score and seven years ago' ' our fathers brought forth on this' ' continent a new nation, conceived in' ' liberty and dedicated to the proposition' ' that all men are created equal'); INSERT INTO tblMessages VALUES ('7', 'Classic Rock Bands', 'Led Zeppelin Grateful Dead and The Sex Pistols'); INSERT INTO tblMessages VALUES ('8', 'My birth address', '18 Sommervile road, Regina, Saskatchewan'); INSERT INTO tblMessages VALUES ('9', 'Joke', 'knock knock : who\'s there?' ' I will not finish this joke'); INSERT INTO tblMessages VALUES ('10', 'Computer information', 'My computer is a pentium III 400 mHz' ' with 192 megabytes of RAM');
The next stage is to create a special text index which we will use for FTI, so we can search our table of messages for words or a phrase. We do this using the SQL command:
ALTER TABLE tblMessages ADD COLUMN idxFTI tsvector;
Note that unlike traditional indexes, this is actually a new field in the same table, which is then used (through the magic of the tsearch2 operators and functions) by a special index we will create in a moment.
The general rule for the initial insertion of data will follow four steps:
1. update table 2. vacuum full analyze 3. create index 4. vacuum full analyze
The data can be updated into the table, the vacuum full analyze will reclaim unused space. The index can be created on the table after the data has been inserted. Having the index created prior to the update will slow down the process. It can be done in that manner, this way is just more efficient. After the index has been created on the table, vacuum full analyze is run again to update postgres's statistics (ie having the index take effect).
UPDATE tblMessages SET idxFTI=to_tsvector('default', strMessage); VACUUM FULL ANALYZE;
Note that this only inserts the field strMessage as a tsvector, so if you want to also add strTopic to the information stored, you should instead do the following, which effectively concatenates the two fields into one before being inserted into the table:
UPDATE tblMessages SET idxFTI=to_tsvector('default',coalesce(strTopic,'') ||' '|| coalesce(strMessage,'')); VACUUM FULL ANALYZE;
Using the coalesce function makes sure this concatenation also works with NULL fields.
We need to create the index on the column idxFTI. Keep in mind that the database will update the index when some action is taken. In this case we _need_ the index (The whole point of Full Text INDEXINGi ;-)), so don't worry about any indexing overhead. We will create an index based on the gist function. GiST is an index structure for Generalized Search Tree.
CREATE INDEX idxFTI_idx ON tblMessages USING gist(idxFTI); VACUUM FULL ANALYZE;
After you have converted all of your data and indexed the column, you can select some rows to see what actually happened. I will not display output here but you can play around yourselves and see what happened.
The last thing to do is set up a trigger so every time a row in this table is changed, the text index is automatically updated. This is easily done using:
CREATE TRIGGER tsvectorupdate BEFORE UPDATE OR INSERT ON tblMessages FOR EACH ROW EXECUTE PROCEDURE tsearch2(idxFTI, strMessage);
Or if you are indexing both strMessage and strTopic you should instead do:
CREATE TRIGGER tsvectorupdate BEFORE UPDATE OR INSERT ON tblMessages FOR EACH ROW EXECUTE PROCEDURE tsearch2(idxFTI, strTopic, strMessage);
Before you ask, the tsearch2 function accepts multiple fields as arguments so there is no need to concatenate the two into one like we did before.
If you want to do something specific with columns, you may write your very own trigger function using plpgsql or other procedural languages (but not SQL, unfortunately) and use it instead of tsearch2 trigger.
You could however call other stored procedures from within the tsearch2 function. Lets say we want to create a function to remove certain characters (like the @ symbol from all text).
CREATE FUNCTION dropatsymbol(text) RETURNS text AS 'select replace($1, \'@\', \' \');' LANGUAGE SQL;
Now we can use this function within the tsearch2 function on the trigger.
DROP TRIGGER tsvectorupdate ON tblmessages; CREATE TRIGGER tsvectorupdate BEFORE UPDATE OR INSERT ON tblMessages FOR EACH ROW EXECUTE PROCEDURE tsearch2(idxFTI, dropatsymbol, strMessage); INSERT INTO tblmessages VALUES (69, 'Attempt for dropatsymbol', 'Test@test.com');
If at this point you receive an error stating: ERROR: Can't find tsearch config by locale
Do not worry. You have done nothing wrong. And tsearch2 is not broken. All that has happened here is that the configuration is setup to use a configuration based on the locale of the server. All you have to do is change your default configuration, or add a new one for your specific locale. See the section on TSEARCH2 CONFIGURATION.
SELECT * FROM tblmessages WHERE intindex = 69; intindex | strtopic | strmessage | idxfti ----------+--------------------------+---------------+----------------------- 69 | Attempt for dropatsymbol |<EMAIL_ADDRESS>| 'test':1 'test.com':2 (1 row)Notice that the string content was passed throught the stored procedure dropatsymbol. The '@' character was replaced with a single space ... and the output from the procedure was then stored in the tsvector column.
This could be useful for removing other characters from indexed text, or any kind of preprocessing needed to be done on the text prior to insertion into the index.
QUERYING A TABLE
There are some examples in the README.tsearch2 file for querying a table. One major difference between tsearch and tsearch2 is the operator ## is no longer available. Only the operator @@ is defined, using the types tsvector on one side and tsquery on the other side.
Lets search the indexed data for the word "Test". I indexed based on the the concatenation of the strTopic, and the strMessage:
SELECT intindex, strtopic FROM tblmessages WHERE idxfti @@ 'test'::tsquery; intindex | strtopic ----------+--------------- 1 | Testing Topic (1 row)
The only result that matched was the row with a topic "Testing Topic". Notice that the word I search for was all lowercase. Let's see what happens when I query for uppercase "Test".
SELECT intindex, strtopic FROM tblmessages WHERE idxfti @@ 'Test'::tsquery; intindex | strtopic ----------+---------- (0 rows)
We get zero rows returned. The reason is because when the text was inserted, it was morphed to my default configuration (because of the call to to_tsvector in the UPDATE statement). If there was no morphing done, and the tsvector field(s) contained the word 'Text', a match would have been found.
Most likely the best way to query the field is to use the to_tsquery function on the right hand side of the @@ operator like this:
SELECT intindex, strtopic FROM tblmessages WHERE idxfti @@ to_tsquery('default', 'Test | Zeppelin'); intindex | strtopic ----------+-------------------- 1 | Testing Topic 7 | Classic Rock Bands (2 rows)
That query searched for all instances of "Test" OR "Zeppelin". It returned two rows: the "Testing Topic" row, and the "Classic Rock Bands" row. The to_tsquery function performed the correct morphology upon the parameters, and searched the tsvector field appropriately.
The last example here relates to searching for a phrase, for example "minority report". This poses a problem with regard to tsearch2, as it doesn't index phrases, only words. But there is a way around which doesn't appear to have a significant impact on query time, and that is to use a query such as the following:
SELECT intindex, strTopic FROM tblmessages WHERE idxfti @@ to_tsquery('default', 'gettysburg & address') AND strMessage ~* '.*men are created equal.*'; intindex | strtopic ----------+------------------------------ 6 | Gettysburg address quotation (1 row) SELECT intindex, strTopic FROM tblmessages WHERE idxfti @@ to_tsquery('default', 'gettysburg & address') AND strMessage ~* '.*something that does not exist.*'; intindex | strtopic ----------+---------- (0 rows)
Of course if your indexing both strTopic and strMessage, and want to search for this phrase on both, then you will have to get out the brackets and extend this query a little more.
TSEARCH2 CONFIGURATION
Some words such as "and", "the", and "who" are automatically not indexed, since they belong to a pre-existing dictionary of "Stop Words" which tsearch2 does not perform indexing on. If someone needs to search for "The Who" in your database, they are going to have a tough time coming up with any results, since both are ignored in the indexes. But there is a solution.
Lets say we want to add a word into the stop word list for english stemming. We could edit the file :'/usr/local/pgsql/share/english.stop' and add a word to the list. I edited mine to exclude my name from indexing:
- Edit /usr/local/pgsql/share/english.stop - Add 'andy' to the list - Save the file.
When you connect to the database, the dict_init procedure is run during initialization. And in my configuration it will read the stop words from the file I just edited. If you were connected to the DB while editing the stop words, you will need to end the current session and re-connect. When you re-connect to the database, 'andy' is no longer indexed:
SELECT to_tsvector('default', 'Andy'); to_tsvector ------------ (1 row)
Originally I would get the result :
SELECT to_tsvector('default', 'Andy'); to_tsvector ------------ 'andi':1 (1 row)
But since I added it as a stop word, it would be ingnored on the indexing. The stop word added was used in the dictionary "en_stem". If I were to use a different configuration such as 'simple', the results would be different. There are no stop words for the simple dictionary. It will just convert to lower case, and index every unique word.
SELECT to_tsvector('simple', 'Andy andy The the in out'); to_tsvector ------------------------------------- 'in':5 'out':6 'the':3,4 'andy':1,2 (1 row)
All this talk about which configuration to use is leading us into the actual configuration of tsearch2. In the examples in this document the configuration has always been specified when using the tsearch2 functions:
SELECT to_tsvector('default', 'Testing the default config'); SELECT to_tsvector('simple', 'Example of simple Config');
The pg_ts_cfg table holds each configuration you can use with the tsearch2 functions. As you can see the ts_name column contains both the 'default' configurations based on the 'C' locale. And the 'simple' configuration which is not based on any locale.
SELECT * from pg_ts_cfg; ts_name | prs_name | locale -----------------+----------+-------------- default | default | C default_russian | default | ru_RU.KOI8-R simple | default | (3 rows)
Each row in the pg_ts_cfg table contains the name of the tsearch2 configuration, the name of the parser to use, and the locale mapped to the configuration. There is only one parser to choose from the table pg_ts_parser called 'default'. More parsers could be written, but for our needs we will use the default.
There are 3 configurations installed by tsearch2 initially. If your locale is set to 'en_US' for example (like my laptop), then as you can see there is currently no dictionary configured to use with that locale. You can either set up a new configuration or just use one that already exists. If I do not specify which configuration to use in the to_tsvector function, I receive the following error.
SELECT to_tsvector('learning tsearch is like going to school'); ERROR: Can't find tsearch config by locale
We will create a new configuration for use with the server encoding 'en_US'. The first step is to add a new configuration into the pg_ts_cfg table. We will call the configuration 'default_english', with the default parser and use the locale 'en_US'.
INSERT INTO pg_ts_cfg (ts_name, prs_name, locale) VALUES ('default_english', 'default', 'en_US');
We have only declared that there is a configuration called 'default_english'. We need to set the configuration of how 'default_english' will work. The next step is creating a new dictionary to use. The configuration of the dictionary is completlely different in tsearch2. In the prior versions to make changes, you would have to re-compile your changes into the tsearch.so. All of the configuration has now been moved into the system tables created by executing the SQL code from tsearch2.sql
Lets take a first look at the pg_ts_dict table
ftstest=# \d pg_ts_dict Table "public.pg_ts_dict" Column | Type | Modifiers -----------------+---------+----------- dict_name | text | not null dict_init | oid | dict_initoption | text | dict_lexize | oid | not null dict_comment | text | Indexes: pg_ts_dict_idx unique btree (dict_name)
The dict_name column is the name of the dictionary, for example 'simple', 'en_stem' or 'ru_stem'. The dict_init column is an OID of a stored procedure to run for initialization of that dictionary, for example 'snb_en_init' or 'snb_ru_init'. The dict_init option is used for options passed to the init function for the stored procedure. In the cases of 'en_stem' or 'ru_stem' it is a path to a stopword file for that dictionary, for example '/usr/local/pgsql/share/english.stop'. This is however dictated by the dictionary. ISpell dictionaries may require different options. The dict_lemmatize column is another OID of a stored procedure to the function used to lemmitize, for example 'snb_lemmatize'. The dict_comment column is just a comment.
Next we will configure the use of a new dictionary based on ISpell. We will assume you have ISpell installed on you machine. (in /usr/local/lib)
There has been some confusion in the past as to which files are used from ISpell. ISpell operates using a hash file. This is a binary file created by the ISpell command line utility "buildhash". This utility accepts a file containing the words from the dictionary, and the affixes file and the output is the hash file. The default installation of ISPell installs the english hash file english.hash, which is the exact same file as american.hash. ISpell uses this as the fallback dictionary to use.
This hash file is not what tsearch2 requires as the ISpell interface. The file(s) needed are those used to create the hash. Tsearch uses the dictionary words for morphology, so the listing is needed not spellchecking. Regardless, these files are included in the ISpell sources, and you can use them to integrate into tsearch2. This is not complicated, but is not very obvious to begin with. The tsearch2 ISpell interface needs only the listing of dictionary words, it will parse and load those words, and use the ISpell dictionary for lexem processing.
I found the ISPell make system to be very finicky. Their documentation actually states this to be the case. So I just did things the command line way. In the ISpell source tree under langauges/english there are several files in this directory. For a complete description, please read the ISpell README. Basically for the english dictionary there is the option to create the small, medium, large and extra large dictionaries. The medium dictionary is recommended. If the make system is configured correctly, it would build and install the english.has file from the medium size dictionary. Since we are only concerned with the dictionary word listing ... it can be created from the /languages/english directory with the following command:
sort -u -t/ +0f -1 +0 -T /usr/tmp -o english.med english.0 english.1
This will create a file called english.med. You can copy this file to whever you like. I place mine in /usr/local/lib so it coincides with the ISpell hash files. You can now add the tsearch2 configuration entry for the ISpell english dictionary. We will also continue to use the english word stop file that was installed for the en_stem dictionary. You could use a different one if you like. The ISpell configuration is based on the "ispell_template" dictionary installed by default with tsearch2. We will use the OIDs to the stored procedures from the row where the dict_name = 'ispell_template'.
INSERT INTO pg_ts_dict (SELECT 'en_ispell', dict_init, 'DictFile="/usr/local/lib/english.med",' 'AffFile="/usr/local/lib/english.aff",' 'StopFile="/usr/local/pgsql/share/english.stop"', dict_lexize FROM pg_ts_dict WHERE dict_name = 'ispell_template');
Now that we have a dictionary we can specify it's use in a query to get a lexem. For this we will use the lexize function. The lexize function takes the name of the dictionary to use as an argument. Just as the other tsearch2 functions operate.
SELECT lexize('en_ispell', 'program'); lexize ----------- {program} (1 row)
If you wanted to always use the ISpell english dictionary you have installed, you can configure tsearch2 to always use a specific dictionary.
SELCECT set_curdict('en_ispell');
Lexize is meant to turn a word into a lexem. It is possible to receive more than one lexem returned for a single word.
SELECT lexize('en_ispell', 'conditionally'); lexize ----------------------------- {conditionally,conditional} (1 row)
The lexize function is not meant to take a full string as an argument to return lexems for. If you passed in an entire sentence, it attempts to find that entire sentence in the dictionary. SInce the dictionary contains only words, you will receive an empty result set back.
SELECT lexize('en_ispell', 'This is a senctece to lexize'); lexize -------- (1 row) If you parse a lexem from a word not in the dictionary, then you will receive an empty result. This makes sense because the word "tsearch" is not int the english dictionary. You can create your own additions to the dictionary if you like. This may be useful for scientific or technical glossaries that need to be indexed. SELECT lexize('en_ispell', 'tsearch'); lexize -------- (1 row)
This is not to say that tsearch will be ignored when adding text information to the the tsvector index column. This will be explained in greater detail with the table pg_ts_cfgmap.
Next we need to set up the configuration for mapping the dictionay use to the lexxem parsings. This will be done by altering the pg_ts_cfgmap table. We will insert several rows, specifying to using the new dictionary we installed and configured for use within tsearch2. There are several type of lexims we would be concerned with forcing the use of the ISpell dictionary.
INSERT INTO pg_ts_cfgmap (ts_name, tok_alias, dict_name) VALUES ('default_english', 'lhword', '{en_ispell,en_stem}'); INSERT INTO pg_ts_cfgmap (ts_name, tok_alias, dict_name) VALUES ('default_english', 'lpart_hword', '{en_ispell,en_stem}'); INSERT INTO pg_ts_cfgmap (ts_name, tok_alias, dict_name) VALUES ('default_english', 'lword', '{en_ispell,en_stem}');
We have just inserted 3 records to the configuration mapping, specifying that the lexem types for "lhword, lpart_hword and lword" are to be stemmed using the 'en_ispell' dictionary we added into pg_ts_dict, when using the configuration ' default_english' which we added to pg_ts_cfg.
There are several other lexem types used that we do not need to specify as using the ISpell dictionary. We can simply insert values using the 'simple' stemming process dictionary.
INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'url', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'host', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'sfloat', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'uri', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'int', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'float', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'email', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'word', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'hword', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'nlword', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'nlpart_hword', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'part_hword', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'nlhword', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'file', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'uint', '{simple}'); INSERT INTO pg_ts_cfgmap VALUES ('default_english', 'version', '{simple}');
Our addition of a configuration for 'default_english' is now complete. We have successfully created a new tsearch2 configuration. At the same time we have also set the new configuration to be our default for en_US locale.
SELECT to_tsvector('default_english', 'learning tsearch is like going to school'); to_tsvector -------------------------------------------------- 'go':5 'like':4 'learn':1 'school':7 'tsearch':2 SELECT to_tsvector('learning tsearch is like going to school'); to_tsvector -------------------------------------------------- 'go':5 'like':4 'learn':1 'school':7 'tsearch':2 (1 row)
Notice here that words like "tsearch" are still parsed and indexed in the tsvector column. There is a lexem returned for the word becuase in the configuration mapping table, we specify words to be used from the 'en_ispell' dictionary first, but as a fallback to use the 'en_stem' dictionary. Therefore a lexem is not returned from en_ispell, but is returned from en_stem, and added to the tsvector.
SELECT to_tsvector('learning tsearch is like going to computer school'); to_tsvector --------------------------------------------------------------------------- 'go':5 'like':4 'learn':1 'school':8 'compute':7 'tsearch':2 'computer':7 (1 row)
Notice in this last example I added the word "computer" to the text to be converted into a tsvector. Because we have setup our default configuration to use the ISpell english dictionary, the words are lexized, and computer returns 2 lexems at the same position. 'compute':7 and 'computer':7 are now both indexed for the word computer.
You can create additional dictionarynlists, or use the extra large dictionary from ISpell. You can read through the ISpell documents, and source tree to make modifications as you see fit.
In the case that you already have a configuration set for the locale, and you are changing it to your new dictionary configuration. You will have to set the old locale to NULL. If we are using the 'C' locale then we would do this:
UPDATE pg_ts_cfg SET locale=NULL WHERE locale = 'C';
That about wraps up the configuration of tsearch2. There is much more you can do with the tables provided. This was just an introduction to get things working rather quickly.
ADDING NEW DICTIONARIES TO TSEARCH2
To aid in the addition of new dictionaries to the tsearch2 module you can use another additional module in combination with tsearch2. The gendict module is included into tsearch2 distribution and is available from gendict/ subdirectory.
I will not go into detail about installation and instructions on how to use gendict to it's fullest extent right now. You can read the README.gendict ... it has all of the instructions and information you will need.
BACKING UP AND RESTORING DATABASES THAT FEATURE TSEARCH2
Believe it or not, this isn't as straight forward as it should be, and you will have problems trying to backup and restore any database which uses tsearch2 unless you take the steps shown below. And before you ask using pg_dumpall will result in failure every time. These took a lot of trial and error to get working, but the process as laid down below has been used a dozen times now in live production environments so it should work fine.
HOWEVER never rely on anyone elses instructions to backup and restore a database system, always develop and understand your own methodology, and test it numerous times before you need to do it for real.
To Backup a PostgreSQL database that uses the tsearch2 module:
1) Backup any global database objects such as users and groups (this step is usually only necessary when you will be restoring to a virgin system)
pg_dumpall -g > GLOBALobjects.sql
2) Backup the full database schema using pg_dump
pg_dump -s DATABASE > DATABASEschema.sql
3) Backup the full database using pg_dump
pg_dump -Fc DATABASE > DATABASEdata.tar
To Restore a PostgreSQL database that uses the tsearch2 module:
1) Create the blank database
createdb DATABASE
2) Restore any global database objects such as users and groups (this step is usually only necessary when you will be restoring to a virgin system)
psql DATABASE < GLOBALobjects.sql
3) Create the tsearch2 objects, functions and operators
psql DATABASE < tsearch2.sql
4) Edit the backed up database schema and delete all SQL commands which create tsearch2 related functions, operators and data types, BUT NOT fields in table definitions that specify tsvector types. If your not sure what these are, they are the ones listed in tsearch2.sql. Then restore the edited schema to the database
psql DATABASE < DATABASEschema.sql
5) Restore the data for the database
pg_restore -N -a -d DATABASE DATABASEdata.tar
If you get any errors in step 4, it will most likely be because you forgot to remove an object that was created in tsearch2.sql. Any errors in step 5 will mean the database schema was probably restored wrongly.


Like CR7! Check Out Rashford's 'Ronaldo Chop' Skill Move
by SL SocialAs a player who has been tipped to have a bright future, Manchester United star Marcus Rashford recently produced a bit of skill that Cristiano Ronaldo has often pulled off throughout his playing career. Check it out!
The English national team have been in high spirits under the tutelage of Gareth Southgate, and have grown from strength to strength since their 2018 World Cup semi-final appearance.
Download The Soccer Laduma Social Media App & Earn Airtime for Selfies!
In the most recent international break, Southgate's troops were at their free-scoring best, winning 7-0 and 4-0 in their latest two encounters, respectively.
Managing to get on the scoresheet in both games was United's Rashford, who has now contributed 11 goals in his past 10 matches for club and country.
In the Three Lions' recent 4-0 win over Kosovo, the United attacker produced a bit of skill that had fans on social media comparing it to a move often done by former Red Devils superstar Ronaldo.
Check out Rashford's Ronaldo chop:
Do you think Rashford has what it takes to become one of the best players in the world?


Home
About
Login
Post
Here
A Subredd
.
ı
t Pred
.
ı
ctor
Intelligently suggesting relevant subreddits, on demand.
Get Started


2009 Employee Sales by Department
food
auto
household
furniture
Mary
190
160
40
120
Tom
3
40
30
45
Brad
10
180
10
85
Kate
40
80
90
25


We're going to use a function and a map to covert English into Morse code.
There is a code sample in "snippets" to get you started
The snippet is a function. Within the function you define a map of inputs to outputs.
In our case, we want to map each letter to a corresponding Morse code.
Once your function is ready, you can use it! See the palette for an example of use


Before Change
hidden = torch.Tensor(1, n_hidden)
out, hidden = rnn(cat, dummy_input, hidden)
with SummaryWriter(comment="RNN") as w:
w.add_graph(rnn, (cat, dummy_input, hidden), verbose=False)
import pytest
print("expect error here:")
with pytest.raises(Exception) as e_info:
dummy_input = torch.rand(1, 1, 224, 224)
After Change
dummy_input = torch.rand(1, 3, 224, 224)
with SummaryWriter(comment="basicblock") as w:
model = BasicBlock(3, 3)
w.add_graph(model, (dummy_input, ), verbose=True)


influenza virus {border-style px;} #ffffff;} infection symptoms (HN) Centers Control women Disease px; {font-family font-size patients pregnant risk Case Health Prevention blood case collab: day days double; novel patient Influenza baby border-color border-width flu high signs solid; swab viral {font-style {font-weight Infectious Obstetrics Pregnant bold cold contact cough courier; diagnosed em; hygiene mask mother neonatal noted pandemic pregnancy pressure pt;} specimen transmission


--- layout: page title: Lean Prover Zulip Chat Archive permalink: archive/116395maths/39703quotienttopology.html ---
Do we have a lemma about closure (quotient.mk '' s)
somwhere?


Sonny Booth
Front-end Developer
More about me
I am cool
My skills
I enjoy going bare stuff
HTML
CSS
Javascript
Get onto me
Bell me on 077******,
Social media


Aloe vera is known as the ‘plant of immortality’ by the ancient Egyptians and has many benefits especially for skins and hair. It is so effective in treating a variety of skin conditions like flaky or dry skin, cosmetic ailments, and hair and scalp problems that is one of the staple ingredients used in many of the beauty and skin products. While many brands offer some form of aloe vera or the other, today we are going to see how to create our own DIY Aloe Vera Mist.
Take aloe vera , remove the skin and make it into a concentrate using a blender. Take a mist bottle and add ⅔ of aloe vera concentrate and the ⅓ rose water. You can add in a few drops of rose water concentrate to give a nice aroma and also Argan oil that is high in vitamin E and acts as a great moisturizer. Remember to shake it well before spraying.
Aloe vera is known to promote shine and moisturizes the hair while also preventing hair loss and dandruff.  Mixing it with rosewater dilutes it enough to make it sprayable and adding a few of the argan oil adds a bit more moisture to the entire mixture. This can also be used as face and body spray that will help you keep them moisturized and fresh during hot days especially when you travelling.


1. Which of the following is the pinyin of 苹果?
2. Which of the followng means "go to school"?
3. What does "兴高采烈" means?
4. What is the right word of the blank "手舞_蹈"
5. What is the following phrase after "举头望明月"?
6. Whihc of the following was born in Tang dynasty?


--- title: 'Blog' template: 'blog' url: "blog" sitemap: priority: 0.8 lastModified: '2016-10-10' changeFrequency: 'daily' ---
Foobar
Foobaz


You don't have any projects yet
Create a new project from your GitHub wiki project or create a new project from scrach.


Return to the main page
Learn more about us!
Buy MOAR things!
We have a vast assortment of ever-changing salmon cookie accessories!


Selected Issues:
{{openIssueList.length}} Open, {{exemptedIssueList.length}} Exempted
You are trying to add an exception for an already exempted issue.
This will overwrite the exemption period used previously.
Open issues can not be revoked.
{{openIssueList.length}}
selected open issues will remain unchanged.
maxIssues || (showRevokeExceptionmodal && exemptedIssueList.length === 0)" (click)='$event.stopPropagation(); proceedWithException()'>
NEXT
maxIssues'>Please select maximum {{maxIssues}} issues only.
Please select atleast 1 exempted issue to revoke exception.
Note: Maximum {{maxIssues}} issues can be exempted or revoked at a time.


<template is="dom-bind"> Demo [[myAttrib]]
You last clicked on {{lastClicked}}.
[[item]]
(By the way, I'm odd.)


If the element is enabled to be used in-game at all, use a value of 1. You can use a value of 0 to disable elements softly while still breaking every save in existence. In general, keep it as 1.


{% extends "global/Page.html" %} {% load otree %} {% block title %}Your Decision (Game 2) {% endblock %} {% block content %}
Congrats! You are Participant 1. That means you get to decide on the income split. Choice 1 is an even (50, 50) income split where you and your partner both get 50 points, and Choice 2 which is an uneven income split (75, 150) where you get 75 points and your partner gets 150 points.
{% formfield player.choice label="Please choose your preferred income split" %} {% next_button %} {% include Constants.instructions_template %} {% endblock %}


Open vSwitch supports tunneling in userspace. Tunneling is implemented in a platform-independent way.
Setup physical bridges for all physical interfaces. Create integration bridge. Add VXLAN port to int-bridge. Assign IP address to physical bridge where VXLAN traffic is expected.
Connect to VXLAN tunnel endpoint logical IP: <IP_ADDRESS> and <IP_ADDRESS>.
Configure OVS bridges as follows.
Let's assume <IP_ADDRESS>/24 network is reachable via eth1. Create physical bridge br-eth1. Assign IP address (<IP_ADDRESS>/24) to br-eth1. Add eth1 to br-eth1.
Check ovs cached routes using appctl command.
$ ovs-appctl ovs/route/show
Add tunnel route if not present in OVS route table.
$ ovs-appctl ovs/route/add <IP_ADDRESS>/24 br-eth1
Add integration bridge int-br and add tunnel port using standard syntax.
$ ovs-vsctl add-port int-br vxlan0 \ -- set interface vxlan0 type=vxlan options:remote_ip=<IP_ADDRESS>
Assign IP address to int-br.
The final topology should looks like so:
Diagram <IP_ADDRESS>/24 +--------------+ | int-br | <IP_ADDRESS>/24 +--------------+ +--------------+ | vxlan0 | | vxlan0 | +--------------+ +--------------+ | | | | | | <IP_ADDRESS>/24 | +--------------+ | | br-eth1 | <IP_ADDRESS>/24 +--------------+ +---------------+ | eth1 |----------------------------------| eth1 | +--------------+ +---------------+ Host A with OVS. Remote host.
With this setup, ping to VXLAN target device (<IP_ADDRESS>) should work.


http://info.cern.ch - home of the first website
From here you can:
Browse the first website
Browse the first website using the line-mode browser simulator
Learn about the birth of the web
Learn about CERN, the physics laboratory where the web was born


@* * Copyright 2021 HM Revenue & Customs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *@ @import play.api.i18n._ @import views.html.helper._ @import play.mvc.Call @import uk.gov.hmrc.agentoverseasfrontend.config.view.AnswerRow @this() @(answerRow: AnswerRow)(implicit messages: Messages)


{% extends "base.html" %} {% block content %}
403
SORRY YOU'RE NOT AUTHORIZED
We're sorry, you don't have privilege to access this page.
Home Page


Backwards Compatibility
For 1.0.x
Vagrant 1.1+ provides full backwards compatibility for valid Vagrant 1.0.x Vagrantfiles which don't use plugins. After installing Vagrant 1.1, your 1.0.x environments should continue working without modifications, and existing running machines will continue to be managed properly.
If you use any Vagrant 1.0.x plugins, you must remove references to these from your Vagrantfile prior to upgrading. Vagrant 1.1+ introduces a new plugin format that will protect against this sort of incompatibility from ever happening again.
If your Vagrantfile doesn't just work with 1.1 and doesn't use any plugins, please report a bug.
For 1.x
Backwards compatibility between 1.x is not promised, and Vagrantfile syntax stability isn't promised until 2.0 final. Any backwards incompatibilities within 1.x will be clearly documented.
This is similar to how Vagrant 0.x was handled. In practice, Vagrant 0.x only introduced a handful of backwards incompatibilities during the entire development cycle, but the possibility of backwards incompatibilities is made clear so people aren't surprised.
Vagrant 2.0 final will have a stable Vagrantfile format that will remain backwards compatible, just as 1.0 is considered stable.


Log Out
Instructor of the Day
Next
Bump
Post a Common Issue
Post
Cancel
Active Course
Unavailable
Unavailable


I was born and raised in Troy, NY but now work in Boston, MA. I am a graphic designer, artist, photographer, and lover of all things creative. Check out my portfolio above, contact me below, or look at my resume!
For six months I worked at Boston Globe Media Partners as a Brand Marketing Design Co-op. I worked with a small marketing team to create print, digital, and on-site promotional materials.
To advertise a virtual cocktail class hosted by Boston.com, I made an instagram ad, a facebook ad, and a video slide.
I made ads for GlobeDocs events that were printed in The Boston Globe's newspaper, as well as created weekly GlobeDocs subscriber emails using HTML.
To promote a virtual town hall for Boston students, I made a series of digital ads that appeared on The Boston Globe's website.
I designed a background screen for panelists to sit in front of at a Globe event.
The Boston Globe has a section on its site as well as two newsletters dedicated to cannabis related news stories. I designed a set of stickers promoting these newsletters that were distributed at the Northeast Cannabis Business Conference.
In 2019 my college roommate and I started a company called Rm 29 Designs. Named after the room where we met our freshman year, Rm 29 is a design studio that specializes in covering small business's graphic design and web development needs. I created all materials for Rm 29's brand, including our logo, style guide, business cards, and website illustrations. Much of the work displayed on this portfolio was done for Rm 29 clients.
Check out our website at rmtwentynine.com
Search Sustainable is a web application that helps users find everyday products from sustainable sources. I worked with three developers to create Search Sustainable during a weekend-long Hackathon. The goal of this project is to create a helpful tool that directs consumers to better purchasing options. My role as the designer and front end developer was to develop the UX design strategy, then impliment it using HTML and CSS.
Users can search for a product name and our app will query our database of carefully selected sustainable items. If we do not have enough results in our database our application will use a web socket to connect to our web crawling API. Our custom crawler will query the products of sustainable vendors and show them as results to the users. These items will also be added to our catalog. Our database will learn from the preferences of our users to improve itself.
If the users find a sustainable item from a source outside of our database they can request to add the product to our site by filing out a request form. Administrators are notified of these requests and can look them over and decide if the product should be added to our database. If so admins can use the dashboard tools to add the requested it.
If a user finds a product that is not sustainable or otherwise unworthy of being on our site they can report it by pressing the report button in the bottom corner of the product card. The user enters a brief reason for the report and our admins are notified of the possible flawed product. Using the admin tools, our team can choose to remove the product or resolve the report in a manner they see fit.
Our admin user authentication process is powered by Firebase. If an administrator forgets their password they can use the forgot password link. They will get an email with a reset link fitted with a verification token that will allow them to securely reset their password.
Click here for more details on how the web app works
I used Figma and Adobe Creative Suite to research and create the design strategy for our brand. Search Sustainable is a helpful tool for making environmentally-conscious decisions, and so I created a style guide and logo that is clean, modern, and user-friendly.
Aeris is an independent musician who released their debut single "Cottagecore" in March 2021. I illustrated and designed the cover for this single, as well as for their second single "No No No."
For the "No No No" cover, I took a photo of a casette tape, then used photoshop to add Aeris's handwriting and adjust the colors, creating the final cover below.
As a freelancer, I've created a variety of logos for clients, who are predominantly small business owners. This is a selection of some of those logos.
During the summer of 2021 I worked on a personal project with my great-aunt. Over the course of the past year she had been writing stories about her life and about various members of our family, including my great-grandparents. I took these stories and the many photos that she scanned from family photo albums and designed a book and cover.
Each page is 8 x 10 inches, with a large outer margin to allow space for photo captions. All photos were constrained to the same margins as the text, with the exception of photos beside the chapter titles.
Every chapter title comes with a full bleed photo beside it. The chapter titles, running heads, and captions are set in small caps Mr. Eaves, while the body text is set in 11 pt Corundum with a 14 pt leading.
For the front cover I used a photo of my great aunt and my grandfather as children. For the back cover I used a scan of a page of my great-grandmother's scrapbook, which includes three rough proof photos and a hand written caption.
In the fall of 2021 I was a Project Lead for Scout, Northeastern University's student-led design organization. I managed a team of three designers and one developer to create a new brand and website for The Circuit.
The Circuit (formerly known as Tech for the People) is a student-run editorial and media platform that highlights the multifaceted uses and effects of technology. They came to Scout looking to add relevance and credibility to the organization through a rebrand and website update. User testing of the existing platform revealed that students viewed the organization as a blog rather than a credible editorial or a citable source.
We began the project by conducting research to understand what Tech for the People is and determine what Tech for the People could be. We worked with the client on brand exercises, conducted user interviews on the existing site, and wrote an elevator pitch that summarized the organization.
Once we understood the goals of the rebrand, we started to explore visual identities with moodboarding. Based on client feedback from our moodboards we created a design strategy that outlined the new brand’s typography, color palette, UX components, and imagery to guide us through the remainder of the project.
As part of Tech for the People’s relaunch, the client requested a new name as well as a new logo.Our team and the client agreed that The Circuit was the name that represents the organization the best, referencing both themes of technology and connection.
With a design strategy and logo in place, it was time for us to build a website that represented The Circuit’s brand. We began by writing user stories to help us determine what features the new site needed. Once a list of features was finalized and approved by the client, we created a sitemap that guided us through the designing of lo-fi and eventually hi-fi wireframes.
While a new website was our most prioritized deliverable, the client was also planning for a relaunch of The Circuit’s instagram page and newsletter. We created a new email template using Mailchimp as well as custom Canva templates for instagram posts.
To guide the client through The Circuit’s relaunch, we created a brand book that outlined how to use the new color palette, typography, imagery, and components effectively. Our final deliverables included this brand book as well as a folder of logo files, social media and email templates, and a newly published website.


Toggle navigation
Daakiya
Orders
Fleet
Routes
Route Details
Please wait, Loading your route plan.
TRIP-
Total Distance -
- km
×
Order Status Changed


Darkan Calculator
Loading...
Prayer
Magic
Cooking
Woodcutting
Fletching
Fishing
Firemaking
Crafting
Smithing
Mining
Herblore
Agility
Thieving
Farming
Runecrafting
Hunter
Construction
Summoning
« Return to skill list
  |
Level | XP |
| Current | ||
| Target | ||
| Required XP: 83 | ||
| Multiplier | ||
| Modifier (%) |
| Category | |
| Subcategory |
| Number | Name | LVL | XP |
| 1 | Data | 1 | 1 |


Features
- get and set value and unmasked value easily
- no external dependencies
- supports overwrite mode
- supports all major browsers and *IE11+
- RegExp mask
- Function mask
- Number mask (integer and decimal support)
- Date mask (with various format support and autofix mode)
- Dynamic/on-the-fly mask
- Pattern mask
- show placeholder always or when needed
- unmasked value can contain fixed parts
- optional input parts (greedy)
- custom definitions
- reusable blocks
- Enum and Range masks


Good Newwz Trailer Launch: Akshay Kumar Arrives In A Pram, Sucks On A Pacifier As Kareena Kapoor Khan Poses For Cameras
18 Nov 2019, 07:45 by Saheli Maity
The trailer of Good Newwz has hit the internet. It features Akshay Kumar, Kiara Advani, Kareena Kapoor Khan and Diljeet Dosanjh and the foursome are at the launch party as we speak. Here are their latest pictures.
Akshay Kumar, Kiara Advani, Kareena Kapoor Khan and Diljeet Dosanjh arrive for the Good Newwz trailer lauch. (Image Source:- Viral Bhayani)
Trailer launches are always a delight to watch and well, Good Newwz’ trailer launch is no different (Image Source:- Viral Bhayani)
It is even more unusual because Akshay Kumar and Diljit Dosanjh arrived in a pram while sucking onto their pacifiers (Image Source:- Viral Bhayani)
Talking about Kareena Kapoor Khan and Kiara Advani, the two ladies are seen putting their most fashionable foot forward (Image Source:- Viral Bhayani)
Kareena Kapoor Khan wears a mellow-yellow cutout dress, keeping her beautiful messy tresses unpinned while Kiara Advani wears a pink dress, giving out candy vibes (Image Source:- Viral Bhayani)
Good Newwz is a Dharma Productions film and is directed by Raj Mehta (Image Source:- Viral Bhayani)


@(rule: Rule, suggestionTemplate: SuggestionTemplate)
@expressionTerms("Removing a suggestion template", "rules") {
Are you sure you want to remove this suggestion from @rule.name?
- Suggestion
- @suggestionTemplate.name
@helper.form(routes.RuleSuggestionTemplatesController.delete(rule.id.get, suggestionTemplate.id.get)) {
Cancel
}
}


Menu bar controls not working.
-
sweek
Hey there,
Well, the subject says it pretty much. After just using the computer for a while the menu bar controls stop working, and I have to restart Synergy to get it to work again... for a little while. I can still right click on the play/paus button tough to get that menu. I don't really know what this could possibly be. I'm using 10.3.8 with Synergy 1.72 and iTunes 4.71. The floater and hot keys are working nicely, no problems there. I really wouldn't know what else to tell you about this problem, but as you can guess it's pretty annoying.
-
Greg Hurrell
You should look at the bug database:
http://wincent.com/a/support/bugs/show_bug.cgi?id=39
http://wincent.com/a/support/bugs/show_bug.cgi?id=52
It might be one of those issues. You should also read this on how to file a good bug report:
http://wincent.com/a/knowledge-base/archives/2004/11/how_to_file_a_g.php
Reply
This topic is now closed.


Font size: 12 pixels Font is black, nyt-franklin, helvetica, arial, sans-serif
Anchor tags (a tags): - Hover: has an underline for its text decoration
Buttons: - background color: light blue - background color hover: blue - border has a radius of 3 pixels - font is bold, white, “arial, helvetica, sans-serif” - font size is 11 - padding: 7 pixels vertical / 9 pixels horizontal - margin: 4 pixels horizontal - text is white and transformed to uppercase - background color transitions on hover over a duration or .3 seconds
Header 1: - bottom margin of 10 pixels - bottom padding of 10 pixels - font size is 28 pixels, style is italic, and weight is bold
Paragraphs: - line height of 16 pixels
Overall content width: maximum 1400px


UBC urges exchange students in Hong Kong to return to B.C. due to violent protests
by Taran ParmarSummary
Exchange students in Hong Kong are being urged to come home by the University of British Columbia
32 students at four universities in Hong Kong have been contacted by UBC
UBC has reached out to partner schools to confirm measures are in place to ensure the safety of exchange students
VANCOUVER (NEWS 1130) – The University of British Columbia is urging 32 exchange students to leave Hong Kong, and return to B.C.
Joesphine Chiu-Duke is a professor with the Department of Asian Studies at UBC and says safety is top of mind for the university, as it recommends students return home immediately.
“The obvious reason is that we don’t feel that the students staying there are safe because the violence being escalated by the police and the students in Hong Kong, trying to resist and fight back,” she says.
“The campus in the Chinese University of Hong Kong has become a small battleground between protesters and police.”
The students overseas are attending four universities in Hong Kong and as of Friday, they were all urged to leave as violence between police and protesters continues.
UBC will be working with those who have decided to return home and will help make travel arrangements.


Solar energy is the future. To use solar energy people must first understand how it works and what it can do with it. To buy and install a solar system is an investment for the future. Solar systems today are available for everyone to buy, they are cheaper than ever and very efficient. A solar system can last up to 25 years before any service or repair is needed. It is a good investment for rural areas where power is not available or urban areas where in combination with the electricity grid can create a lot cheaper home to live in and also an eco-friendly solution for big cities that require a lot of power to maintain.


--- layout: post title: itertools date: 2011-11-07 23:02:03.000000000 +00:00 type: post parent_id: '0' published: true password: '' status: publish categories: - python tags: [] meta: _edit_last: '1' author: Noel permalink: "/itertools/" ---
Some quick reference notes made on the itertools library
import itertools ### chain ### Takes any number of iterables, back-to-backs them so you can iterate through all if the iterators in a single loop >>> [ i for i in itertools.chain( [1, 2, 3], [4, 5, 6], [7, 8, 9] ) ] [1, 2, 3, 4, 5, 6, 7, 8, 9] ### combinations ### Think of nCr and nPr. In the example below, it returns unique pairs (hence the second arg, 2) for the set of values in the first arg - the list >>> [ i for i in itertools.combinations( [1, 2, 3, 4], 2) ] [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] ### cycle ### For the iterable passed as an argument, cycle through each element, wrapping back to the start at the end it = itertools.cycle([1, 2, 3]) it.next() -> 1, 2, 3, 1, ... ### dropwhile ### Iterate through a sequence until the lambda test (predicate) is True. Return all of the seq as soon as the test is satisfied >>> [ i for i in itertools.dropwhile( lambda x: x < 3, [1, 2, 3, 4, 5, 1] ) ] [3, 4, 5, 1] ### groupby ### Bundles the elements of the first arg into iterators for each unique element (can also define a grouping fn) >>> [ i for i in itertools.groupby([1, 2, 3, 2]) ] [(1, <itertools._grouper>), (2, <itertools._grouper>), (3, <itertools._grouper>)] # 2's grouper has more data ### ifilter ### Just like filter. You pass either a lambda or None as the predicate >>> [ i for i in itertools.ifilter(None, [1, 0, 7, 8]) ] [1, 7, 8] ### ifilterfalse ### Opposite of ifilter. Would return [0] for the example of ifilter ### imap ### Same as map except you can also use it to zip elements together, pushing them in to the same lambda: >>> [ i for i in itertools.imap(lambda x, y: '%s%s' % (x, y), [1, 2, 3], [4, 5, 1]) ] ['14', '25', '31'] ### islice ### Like slicing for lists, this iterates over a sequence, returning every 2nd elem from 1st index until 1000th elem >>> [ i for i in itertools.islice(['MSFT', 26, 'AAPL', 660, 'FBOOK', 0.01], 1, 1000, 2) ] [26, 660, 0.01] ### izip ### Just like zip, returns nth elem of multiple sequences together >>> [ i for i in itertools.izip( ['a', 'b', 'c'], ['m', 'n'] ) ] [('a', 'm'), ('b', 'n')] # notice 'c' is missing ### izip_longest ### Just like izip but fills in blanks with Nones >>> [ i for i in itertools.izip_longest( ['a', 'b', 'c'], ['m', 'n'] ) ] [('a', 'm'), ('b', 'n'), ('c', None)] ### permutations ### See combinations - nPr rather than nCr >>> [ i for i in itertools.permutations( [1, 2, 3, 4], 2) ] [(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4, 1), (4, 2), (4, 3)] ### product ### Cartesian product of all elements from each of the sequences passed as args - join everything from table A to table B and repeat over for table C ... >>> [ i for i in itertools.product(['a', 'b'], ['c', 'd']) ] [('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd')] ### repeat ### Repeats to first arg 4 times in example below. Will repeat endlessly without the 2nd arg >>> [ i for i in itertools.repeat(10, 4) ] [10, 10, 10, 10] ### starmap ### Like a map inside a map function. (I think this fn is of less use) >>> [ i for i in itertools.starmap( pow, [ [2, 3], [7, 3] ] ) ] [8, 343] ### takewhile ### Opposite of dropwhile - failing as soon as the predicate returns True >>> [ i for i in itertools.takewhile( lambda x: x < 3, [1, 2, 3, 4, 5, 1] ) ] [1, 2] ### tee ### For a given sequence (1, 2), returns 3 copies of the same sequence to iterate over >>> i, j, k = itertools.tee([1, 2], 3) >>> i.next() 1 >>> i.next() 2 >>> i.next() StopIteration >>> j.next() 1 >>> j.next()


For more information on the weather, visit our weather page, look at weather on Wikipedia, or check out weather on Extreme Science.


hardy.arbitrage package¶
Submodules¶
hardy.arbitrage.arbitrage module¶
Created on Tue Apr 21 19:04:32 2020 @author: hurtd
WRAPPING PACKAGE to Combine “Hanlding” and “Transformations” to produce Data To Plot on Demand and deliver to the Image Processing f(n)s
This package will contain several ‘sections’:
- __Perform Transformation__: Wrapper function(s) to actually /do/ the
transformations. This MAY be smart-ish and perform only specified ones, perhaps from a CONFIG or LIST? (That List and Config is an idea we’ll talk about in __yNot__ probably!)
- __Association Functions:__ This is optional, but once you’ve done
the transformations (or before?) you can check how well the data CORRELATES/ASSOCIATES, both to itself and to a “Standard” dataset AKA starting with linear data and transforming it! This may give us “SCORES” for each transformation, which we can use to prioritize!
- __Timeline + Milestones__:
- 2020-04-21: List of the high-priority functions and
Simple-Transformations, with progress and timeline to get them all done soon.
- 2020-04-28: Passing Tests and can __HAND OFF__ to the classifier - a
DataFrame of “all” the transformed data columns. Recieve Handoff from handling, and begin to Integrate.
- 2020-05-12: Complex Transforms - consider what other things we may want,
and discuss feedback with group
- 2020-06-09: Make Decision on Association functions and __HAND OFF__
if so. Otherwise, simply focus on new group priorities
- 2020-06-23: IF yNot function is doing Configuration ideas, make
Stretch-Goal learning gameplan… TBD…
- __Current Status__:
(2020-04-14)
Just creating files and setup, no progress yet
Planning Functions, in compontent spec document (here!)
Considering how much to Frankenstien from prior work. Configuration?
__Module List__:
### SECTION: Perform Transformation #### get_xy():
- Uses handling.py to load a file, check that we have xy data,
and do a quick analysis on it!
INPUT: file name
- OUTPUT: each of 1D arrays X and Y, plus messages OR list of
“Approved” transformations??
- #### perform_transform():
- Wrapping function, to take some input data and return a
dataframe with every transform that we want to use:
- INPUT: 1D arrays X, Y, some sort of list or guiance for what
transforms to do
- OUTPUT: Pandas dataframe of X and Y with all of their transforms
as requested.
NOTE: There might be a better way to do this -
- #### generate_linear_transforms():
- Creates a “sample” linear 2D dataset, possibly following
range instructions, and performs all(?) transforms on the data
- INPUT: [ALL OPTIONAL? Default 0-1 and X=Y], [List of transforms to do??
default True to perform “ALL”]
- OUTPUT: pandas dataframe with all X-transformationa and all
Y-transformations - (Maybe in Standard names? Maybe Not?)
- NOTE: This could get messy - And maybe use the same wrapping function
above to perform the listed tranforms?
- ### SECTION: Association Functions
- NOTE: Not really planning these yet, that will be scoped or
descoped based on Team Update by __2020-04-28__
- #### setup_correlation_matrix():
Sets up the 2D matrix of “scores” to judge the correlations
- #### correlate_to_transforms():
- For a given transform, determine (?) how correlated the
data is to all other columns in the dataframe
- #### correlate_to_linear():
- Compares the given transform to the linear_transform()
function transforms. Any that correlate are probably good ideas?!?
- #### correlate_to_null():
- Maybe compares the given transform to a flat line of low but
nonzero values (all value = 0.1)?
Not sure what’s the best way to do this…
- What I’m TRYING to do is to identify/flag “BORING” data, which are
probably BAD transforms to use?
- #### grade_all_transforms():
- Wrapping function. Given a “fully” transformed dataset
(or generate it here?), run all correlations and use some fancy math or grading (we generate?) to give each column a “SCORE”
- The __SCORE__ should reflect how “Interesting” we think the data
is (which is a topic for discussion, but all zeros is not interesting)
- INPUT: dataframe ready to be “graded”, OR give an XY dataset and
we’ll call the transform functions on it
- OUTPUT: dictionary of Key,Values where each Key is a transform
(or column key), and each Value is a “grade” to estimate how interesting we think the data may be
- NOTE: This is SUPER arbitrary and is the ‘creative’ part of the
STRETCH-GOALS of the project.s!
- #### grade_all_files():
- Load all the files in a list, perform transformations, and grade.
Hopefully this is a fast function so you can do a large list of files.
- Then combine all the grades to get an average idea of what
transforms we consider “good”
INPUT: list of files
- OUTPUT: dictionary of key, values as before, where results
are averaged across dataset
- ACTIONS: Optionally, save results as a report csv (or append to
existing csv report??), to track grades over time
- #### load_transform_results():
- IF we’ve run this program before, we should have a file that has
previous “grades”, this time based on the model training
- If one transform shows up in a lot of the best-performing models,
we should bump it to the top of the Transform To-Do List!
- #### combine_grades_results():
- Somehow we should combine the ‘grades’ with the ‘prior results’
to get our new guess for what are the ‘best’ transformations to try
- this will allow our model to do the highest-profile transfomations
first and hopefully get good results in fewer attempts.
-
hardy.arbitrage.arbitrage.
apply_tform
(raw_df, tform_commands, rgb_col_number=6)¶ - Parameters
raw_df (pd.DataFrame of raw data from list_of_tuples) –
Un-Transformed data to apply transform to. This will be a call of list_of_tuples[#][1], because as
defined elsewhere, each raw data has one tuple in list, contains (Filename, DataFrame, classifier)
tform_commands (List of Tform Commands) –
This will be a call of tform_command_dict[tform_command_list[#]], Thus it will contain a list of tform commands:
(Index=0, transform, source), (Index=1, transform, source), (Index=2, transform, source), As explained elsewhere
- Returns
tform_df –
- Each column is placed in “Index”, and gets its name from “source”
(New name from SourceColumnName__tform__TformName)
- Each column’s data is ouput of the tform_1d1d function called
and the remainder are passed as zero (with # as col name?)
- Return type
pd.DataFrame
-
hardy.arbitrage.arbitrage.
import_tform_config
(tform_config_path='.\tform_config.yaml', raw_df=None)¶ - Parameters
tform_config_path (Str, optional) – Path of transform configuration file to DESCRIPTION. The default is ‘. form_config.yaml’.
CHECKS –
------ –
Index are in 0-5 (for RGBrgb-style plotting) (All) –
transform commands are in transform.list_1d1d (All) –
source # are below the length of the raw-data list (All) –
- Returns
tform_command_list (list of str) – Ordered list of transform commands to use. Differs from the dict.keys() because this is ordered! (May save Report with this string as the key, to be looked up?)
tform_command_dict (dict of List-of-Transform-tuples) – Each key will return a list of transforms to do on this data loop. Each “List of Transforms” as stated elsewhere contain:
(Index=0, transform, source), (Index=1, transform, source), (Index=2, transform, source), etc. where: “Index” is the output column destination, “transform” is command in transform.list_1d1d, and “source” is the raw data column to be used in the tform
-
hardy.arbitrage.arbitrage.
tform_tuples
(list_of_tuples, tform_commands, rgb_format='RGBrgb')¶ Wrapping function to apply a list of transform commands to each dataframe in the list_of_tuples, and replace it with a same-format list_of_tuples containing transformed data.
- Parameters
list_of_tuples (List of Tuples) – Described in depth elsewhere. Standardized list for each raw file, tuple in format (filename_str, DataFrame, label)
tform_commands (List of List(3)) – Described in depth elsewhere
rgb_format (str, optional) – String of how we will parse the output files. Input here to get the output dataframe size. The default is “RGBrgb”.
- Returns
transformed_tuples – Formatted the same as the input list, but each DataFrame is replaced with the Transformed DF.
- Return type
List of Tuples
hardy.arbitrage.transformations module¶
Created on Tue Apr 21 19:04:12 2020 @author: hurtd
- The first-level functions, which will take input data
(either 2D, 3D, or eventually nD…), and perform transformations to generate the full set of data-columns that we will test against!
THIS FILE IS FOR MATHEMATICAL TRANSFORMATIONS THEMSELVES. DATA WILL BE PROCESSED IN THE “ARBITRAGE.py” FILE
- This package will contain several ‘sections’:
- __Transformation Functions:__ This is the mathematical side,
and to start out we will be able to perform a variety of 1D or 2D transformations such as Log, Inverse, accumulate, Integrate, derrive, etc.
- __Complex Transforms__: Some data transformations are combinations of
the ones above (you can integrate AFTER you log-ify, for instance)
- __Timeline + Milestones__:
- 2020-04-21: List of the high-priority functions and
Simple-Transformations, with progress and timeline to get them all done soon.
- 2020-04-28: Passing Tests and can __HAND OFF__ to the classifier - a
DataFrame of “all” the transformed data columns. Recieve Handoff from handling, and begin to Integrate.
- 2020-05-12: Complex Transforms - consider what other things we may want,
and discuss feedback with group
- 2020-06-09: Make Decision on Association functions and __HAND OFF__
if so. Otherwise, simply focus on new group priorities
- 2020-06-23: IF yNot function is doing Configuration ideas, make
Stretch-Goal learning gameplan… TBD…
- __Current Status__:
(2020-04-14)
Just creating files and setup, no progress yet
Planning Functions, in compontent spec document (here!)
Considering how much to Frankenstien from prior work. Configuration?
__Module List__:
### SECTION: Basic 1D Transformations
- #### transform_log():
INPUT: 1D data array with NO NEGATIVE VALUES
OUTPUT: Logrythmic transform of that data
- Note: Consider shifting or abs() for negative data?
no? simply don’t call log transform for negative data?
- #### transform_reciprocal():
INPUT: 1D data array - Limits tbd?
OUTPUT: all values inverted (1/x)
Note: twice should return itself!
- #### transform_cumsum():
INPUT: 1D data array -
OUTPUT: cumulative sum of data (aka integrated with unit-steps)
Note: Not in high priority list?
- #### transform_1d_derrivative():
INPUT: 1D data array
OUTPUT: the step-by-step delta (Note: copy last delta to retain length?)
- Note: Also not in high-priority list? Should also be able to complete
the loop w/ cumsum.
- #### transform_exp():
INPUT: 1D data array - Limits?
OUTPUT: e^x of each datapoint.
- Note: may be redundant in general with log? should be able to
complete that loop!
- #### transform_0to1():
INPUT: 1D data array, data handling case instructions
- OUTPUT: that array shifted and scaled to the 0-to-1 basis
(by FIRST shifting to min=0, THEN scaling to max=1)
- Note: option to leave data alone if min is already 0-to-1,
or if max After Shift is already 0-to-1 (case: data begins 0.2-0.4, can either scale 0-1 or leave as is!)
- Note2: BETTER scaling is to devine 0 as -MAX(ABS(Data))
and 1 as +MAX(ABS(Data)). This maintains fidelity of absolute Y data
- #### transform_pm1():
INPUT: 1D data array, data handling case instructions
- OUTPUT: that array shifted and scaled to the 0-to-1 basis
[THIS TIME: 0=(-,MaxAbs(X)), and 1 =(+MaxAbs(X))]
### SECTION: Basic 2D Transformations
- #### transform_2D_int():
- INPUT: 2 equal size 1D arrays Y, X, to be integrated (Y)dx -
[Optional offset value? to use as the Plus-C]
OUTPUT: The integral of Y dx (BOX? Trapz?) - offset if instructed to.
- Note: Error handling? What if not Sorted/Linear in X?
Should we sort by X first? (Or, what if reciprocating data ie CV Sweeps?)
- #### transform_2D_der():
INPUT: 2 equal size 1D arrays Y, X - Sorted? in either?
- OUTPUT: the Single-point derivatives dY/dX, also the offset so
you /could/ integrate it back again!
- Note: could use some sort of average or smoothing to reduce noise?
However that would be LOSSY DATA PRACTICE!
- #### transform_prod():
- INPUT: 2 equal size 1D arrays X, Y , [Optional Power arguments?
or do those in the 1D cases and use as inputs?]
OUTPUT: Product of each x*y, maybe with power-math included (options)
- ### SECTION: More Complex Transformations
- #### transform_fourier_wavelets():
- Ok so this is the only High-Priority one that I’m genuinely
concerned with… while you “CAN” try to do a transform on a whole dataset, that gets noisy and lossy.
- What I want to investigate is “Wavelet Filtering” Fourier transform,
which we learned about at a Data Sci seminar last quarter? (Or otherwise, there’s a whole realm of Signal-transforming science, I can research that…)
- INPUT: 2 equal size 1D arrays X, Y - Sorted in X??
(Frequency range parameters? or is that the X-size?)
- OUTPUT: 2D? output matrix or Meshgrid - in X-Freq space
(for each wavelet size, return the match(-1 to 1?)*amplitude at each X?)
- NOTE: This will have to be a group discussion- we need TEST DATA
that should work in this space, and then we can report that back!
- #### multi_transform():
- Wrapping function, to perform multiple transformations all together…
Not sure which of these may be useful but I can see possible value in knowing the integral of a log function, for example.
- INPUT: X, [Y if 2D], Multiple transforms to perform…
Is this what classes are for??
OUTPUT: Data output from the final transform listed.
- NOTE: This is low-priority, and should only be done if we convince
ourselves that it’s useful… RELATED, if we get the “Smart” learning functionality, maybe we can combine things this way
- #### transform___():
INPUT:
OUTPUT:
-
hardy.arbitrage.transformations.
list_1d2d
= {'1d_cwt': <function transform_1d_cwt>}¶ # ========================================================================== # test zone (Note: Uncomment Matplotlib at top of file!
x_linear = np.linspace(0, 20, 1000) y_test = 10 * np.sin(2 * np.pi * 0.1 * x_linear) + 1 * np.sin(2 * np.pi * 5 * x_linear) test_df = pd.DataFrame(data={“Xlinear”: x_linear, “Ytest”: y_test}) # Valid Test: Pass Test_df and the Y-axis transform to get output df # of the Y-test data. fig, ax = plt.subplots(2, 1) result_1 = transform_1d_cwt(test_df, ‘y’) ax[0].imshow(result_1, cmap=’PRGn’) ax[1].plot(x_linear, y_test) fig, ax2 = plt.subplots(2, 1)
y_chirp = signal.chirp(x_linear, 2, 20, 0.001) result_2 = transform_1d_cwt(y_chirp) ax2[0].imshow(result_2, cmap=’PRGn’) ax2[1].plot(x_linear, y_chirp) # ==========================================================================
-
hardy.arbitrage.transformations.
transform_1d_cumsum
(raw_array)¶ The function return the cumulative sum of input array
raw_array: Input numpy array
- log_array: np.ndarray
cumulative sum of values in the input array
-
hardy.arbitrage.transformations.
transform_1d_cwt
(raw_df, xy=0)¶ Transform to execute a “Continuous Wavelet Transform” on a 1d data array pass it a raw XY data and tell it which column to use for the transform. See Documentaion on CWT transform:
https://docs.scipy.org/doc/scipy/reference/generated/ scipy.signal.cwt.html#scipy.signal.cwt
- Note: I need to do testing to understand the in/outputs here…
*Plan is to simply hard-code a certain type of Wavelet to use… and Output Data may not be able to be square… In that case, we will discuss how to integrate this result with the compression of the data.
- Parameters
raw_df (pandas.DataFrame or 1D array (Mx2 or Mx1)) – the raw data which is to be transformed.
xy (boolean, or string 'x', or 'y') – information on which dataframe column to transform. ignored if an 1D array is passed instead.
w_method (string or boolean?) – input instructions guiding how to choose wavelet sizes. default should be linear, with options for log- or exponential? (Will have to experiment with data to discover best option)
- Returns
cwt_matrix – Square M-by-M matrix of the wavelet transform data (Not yet compressed to plottable 0-1 data)
- Return type
np.ndarray (MxM)
-
hardy.arbitrage.transformations.
transform_1d_derivative
(raw_array, spacing=0)¶ Function that outputs the gradient of 1-D array using numpy.gradient function
raw_array: numpy array spacing: int representing the spacing between each datapoint
- derivative_array: np.ndarray
array representing gradient at each datapoint
-
hardy.arbitrage.transformations.
transform_1d_exp
(raw_array)¶
-
hardy.arbitrage.transformations.
transform_1d_log
(raw_array)¶ The function that outputs the natural log of input array
raw_array: Input numpy array
- log_array: np.ndarray
natural log values of each element in the input array
-
hardy.arbitrage.transformations.
transform_1d_none
(raw_array)¶
-
hardy.arbitrage.transformations.
transform_1d_reciprocal
(raw_array)¶ The function the outputs the reciprocal of input array
raw_array: Input numpy array
- log_array: np.ndarray
reciprocal values of each element in the input array
-
hardy.arbitrage.transformations.
transform_array_multiplication
(x, y=None)¶ Function that multiplies two arrays x & y, element by element. If y is None, it return x*x
- x: numpy.array
numpy array representing the one array to be multiplied
- y: numpy.array
numpy array representing the second array to be multiplied if None it the module will square the x array
- multi_array: numpy.array
numpy array representing the one to one multiplication of two arrays


CQ CQ CQ!
We're brewing something on this site! Meanwhile you can checkout our social media pages for updates!


Press n or j to go to the next uncovered block, b, p or k for the previous block.
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| crypto-app |
|
88.89% | 24/27 | 100% | 0/0 | 0% | 0/2 | 88.89% | 24/27 |
| crypto-app/config |
|
100% | 3/3 | 100% | 0/0 | 100% | 0/0 | 100% | 3/3 |
| crypto-app/models |
|
96.43% | 27/28 | 66.67% | 6/9 | 100% | 7/7 | 96.43% | 27/28 |
| crypto-app/routes |
|
73.61% | 53/72 | 0% | 0/6 | 42.86% | 3/7 | 73.61% | 53/72 |
| crypto-app/services |
|
87.5% | 28/32 | 100% | 0/0 | 100% | 7/7 | 87.5% | 28/32 |
| crypto-app/utils |
|
100% | 4/4 | 100% | 0/0 | 100% | 1/1 | 100% | 4/4 |
| crypto-app/utils/auth/strategies |
|
46.15% | 12/26 | 0% | 0/6 | 0% | 0/2 | 46.15% | 12/26 |
| crypto-app/utils/middlewares |
|
76.92% | 10/13 | 62.5% | 5/8 | 100% | 3/3 | 76.92% | 10/13 |


Connecting Volunteers with Charities
Our Hands And Feet (OHAF) helps find the right volunteer positions for you by matching people with opportunities to help our local charities. If you want to make a difference, want to add to the positive energy of the universe, or just need volunteer hours to satisfy your club requirements, OHAF can help!
About Our Hands And Feet
OHAF was started in the summer of 2016. It grew out of a desire to give back to the community and a need to find appropriate opportunities to give of time and talents. OHAF is still under development by a diverse team of dedicated programmers using cutting edge web technologies. Keep checking back to see what new features we have created! If you are interested in joining us in creating this awesome app, please contact us at<EMAIL_ADDRESS>; we are always on the lookout for talented individuals. If you have more money than time to give, we also accept monitary donations!
Frequently Asked Questions
Q: What does OHAF do?
A: OHAF provides a list of volunteer opportunities based on the criteria you select. It also shares the info you provided with our partner charities, who may contact you with offers.
Q: When will I be able to use OHAF to find my perfect volunteer position?
A: Soon, very soon! Please keep checking back!
Q: I would like to keep track of my volunteer hours. Can OHAF help me with this?
A: Great question! This is a feature that we may implement in the nearfuture.
Q: Do you do manicures and pedicures?
A: Not in the foreseeable future, sorry!
Q: How can I contribute?
 We do have expenses, however, and welcome donations! You can also contribute by helping us directly – please email Josh Sherman at<EMAIL_ADDRESS>to discuss the many opportunities available, or to donate. Please note, OHAF does not have official non-profit status yet, so monitary donations are not tax-deductible at this time.
Q: What is your favorite charity?
A: OHAF doesn’t play favorites!
Q: Do you support other body parts besides hands and feet?
A: Of course! We have opportunities of all kinds; please check out our list of charities for possibilities.
Connecting Volunteers with Charities
Our Hands And Feet (OHAF) helps find the right volunteer positions for you by matching people with opportunities to help our local charities. If you want to make a difference, want to add to the positive energy of the universe, or just need volunteer hours to satisfy your club requirements, OHAF can help!
About Our Hands And Feet
OHAF was started in the summer of 2016. It grew out of a desire to give back to the community and a need to find appropriate opportunities to give of time and talents. OHAF is still under development by a diverse team of dedicated programmers using cutting edge web technologies. Keep checking back to see what new features we have created! If you are interested in joining us in creating this awesome app, please contact us at<EMAIL_ADDRESS>We are always on the lookout for talented individuals. If you have more money than time to give, we also accept contributions!
Frequently Asked Questions
Q: What does OHAF do?
A: OHAF provides a list of volunteer opportunities based on the criteria you select. It also shares the info you provided with our partner charities, who may contact you with offers.
Q: When will I be able to use OHAF to find my perfect volunteer position?
A: Soon, very soon! Please keep checking back!
Q: I would like to keep track of my volunteer hours. Can OHAF help me with this?
A: Great question! This is a feature that we may implement in the near future.
Q: Do you do manicures and pedicures?
A: Not in the foreseeable future, sorry!
Q: How can I contribute?
 We do have expenses, however, and welcome donations! You can also contribute by helping us directly – please email Josh Sherman at<EMAIL_ADDRESS>to discuss the many opportunities available, or to donate. Please note, OHAF does not have official non-profit status yet, so contributions are not tax-deductible at this time.
Q: What is your favorite charity?
A: OHAF doesn’t play favorites!
Q: Do you support other body parts besides hands and feet?
A: Of course! We have opportunities of all kinds; please check out our list of charities for possibilities.


| lesson 14 A noble gangster |
| There was a time when the owners of shops and businesses in Chicago had to pay large sums of money to gangsters in return for 'protection'. |
| If the money was not paid promptly, the gangsters would quickly put a man out of business by destroying his shop. |
| Obtaining 'protection money' is not a modern crime. |
| As long ago as the fourteenth century, an Englishman, Sir John Hawkwood, made the remarkable discovery |
| that people would rather pay large sums of money than have their life work destroyed by gangsters. ^ |
| Six hundred years ago, Sir John Hawkwood arrived in Italy with a band of soldiers and settled near Florence. ^ 6 |
| He soon made a name for himself and came to be known to the Italians as Giovanni Acuto. |
| Whenever the Italian city-states were at war with each other, |
| Hawkwood used to hire his soldiers to princes who were willing to pay the high price he demanded. |
| In times of peace, when business was bad, Hawkwood and his men would march into a city-state and, |
| after burning down a few farms, would offer to go away if protection money was paid to them. |
| Hawkwood made large sums of money in this way. |
| In spite of this, the Italians regarded him as a sort of hero. |
| When he died at the age of eighty, the Florentines gave him a state funeral |
| and had a picture painted which was dedicated to the memory of 'the most valiant soldier and most notable leader, Signor Giovanni Haukodue'. |


val receiver: SourceReceiver?
Information related to the receiver flow. Present if the source is a receiver (flow is SourceFlow.RECEIVER).


You can zoom in on the image using your mouse scroll wheel or trackpad.
Describe your task briefly here and provide examples.


- upcoming meets
- gallery
-
locate a squad
or
- contact
- useful links
- records
- more
- sign in
0800 SWIMNOW | 0800 794 6669
Lorem Ipsum is simply dummy text of the printing and typesetting industry....Read more.
Lorem Ipsum is simply dummy text of the printing and typesetting industry....Read more.
Lorem Ipsum is simply dummy text of the printing and typesetting industry....Read more.
Squad training is available to all swimmers involved in aquatic sports, whether it is competitive swimming, triathlon, surf lifesaving or waterpolo.Our comprehensive programme allows the flexibility for all disciplines to work together and fit swimming training into busy schedules