WITNESS LIST Public Education Committee April 24, 2001-2:00P HB 704 For: Lara, Rene (Texas Federation of Teachers) HB 814 For: Hill, Michael (American Cancer Society) Against: Gerstenschlager, Merry Lynn (Texas Eagle Forum) HB 1568 For: Backus, David (Texas Association of School Administrators) Jackson, Diane (Spring Branch Independent School District) McAfee, Archie (Texas Association of Secondary School Principals) On: Lara, Rene (Texas Federation of Teachers) HB 3463 For: Douglass, Cathy (Texas Association of School Boards) SB 19 For: Berlanga, Hugo (Christus Children's Hospital) Blaydes, Jean (Action Based Learning) Everett, Diana (Texas Association for Health, Physical Education, Recreation, and Dance) Fullar, Missi (Self) SB 104 For: Lara, Rene (Texas Federation of Teachers) Molter, Michele (Association of Texas Professional Educators) SB 158 For: Lara, Rene (Texas Federation of Teachers) SB 218 For: Fickel, Ann (Texas Classroom Teachers Association) Lara, Rene (Texas Federation of Teachers) SB 385 For: Lara, Rene (Texas Federation of Teachers) Scheberle, Drew (Texas Business and Education Coalition) White, Michael (The Greater Houston Partnership) Against: Allamon, Dana (Self and Family and Consumer Sciences Teachers Association of Texas) Molter, Michele (Association of Texas Professional Educators) On: Euresti, Susan (Self) Flack, Teri (Texas Higher Education Coordinating Board) Frankenberger, Bud (UT Pan American) Smisko, Ann (Texas Education Agency) SB 388 For: Backus, David (Texas Association of School Administrators) Lara, Rene (Texas Federation of Teachers) McAfee, Archie (Texas Association of Secondary School Principals) SB 580 Against: Gerstenschlager, Merry Lynn (Texas Eagle Forum) SB 826 For: O'Hanlon, Kevin (Santa Gertrudis Independent School District) SB 975 For: Lara, Rene (Texas Federation of Teachers) School Finance On: Casey, Daniel (Self)


Try Otoroshi in 5 minutes
what you will need :
- JDK 11
- curl
- jq
- 5 minutes of free time
The elevator pitch
Otoroshi is an awesome reverse proxy built with Scala that handles all the calls to and between your microservices without service locator and lets you change configuration dynamically at runtime.
Download otoroshi
curl -L -o otoroshi.jar 'https://github.com/MAIF/otoroshi/releases/download/v1.5.0-dev/otoroshi.jar'
If you don’t/can’t have these tools on your machine, you can start a sandboxed environment using here with the following command
docker run -p "8080:8080" maif/otoroshi
Start otoroshi
to start otoroshi, just run the following command
java -jar otoroshi.jar
this will start an in-memory otoroshi instance with a generated password that will be printed in the logs. You can set the password with the following flags
java<EMAIL_ADDRESS>-Dapp.adminPassword=password -jar otoroshi.jar
if you want to have otoroshi content persisted between launch without having to setup a datastore, just usse the following flag
java -Dapp.storage=file -jar otoroshi.jar
as the result, you will see something like
$ java -jar otoroshi.jar
[info] otoroshi-env - Otoroshi version 1.5.0-dev
[info] otoroshi-env - Admin API exposed on http://otoroshi-api.oto.tools:8080
[info] otoroshi-env - Admin UI exposed on http://otoroshi.oto.tools:8080
[warn] otoroshi-env - Scripting is enabled on this Otoroshi instance !
[info] otoroshi-in-memory-datastores - Now using InMemory DataStores
[info] otoroshi-env - The main datastore seems to be empty, registering some basic services
[info] otoroshi-env - You can log into the Otoroshi admin console with the following credentials<EMAIL_ADDRESS>/ xol1Kwjzqe9OXjqDxxPPbPb9p0BPjhCO
[info] play.api.Play - Application started (Prod)
[info] otoroshi-script-manager - Compiling and starting scripts ...
[info] otoroshi-script-manager - Finding and starting plugins ...
[info] otoroshi-script-manager - Compiling and starting scripts done in 18 ms.
[info] p.c.s.AkkaHttpServer - Listening for HTTP on /0:0:0:0:0:0:0:0:8080
[info] p.c.s.AkkaHttpServer - Listening for HTTPS on /0:0:0:0:0:0:0:0:8443
[info] otoroshi-script-manager - Finding and starting plugins done in 4681 ms.
[info] otoroshi-env - Generating CA certificate for Otoroshi self signed certificates ...
[info] otoroshi-env - Generating a self signed SSL certificate for https://*.oto.tools ...
Log into the admin UI
just go to http://otoroshi.oto.tools:8080 and log in with the credentials printed in the logs
Create you first service
to create your first service you can either do it using the admin UI or using the admin API. Let’s use the admin API.
By default, otoroshi registers an admin apikey with admin-api-apikey-id:admin-api-apikey-secret
value (those values can be tuned at first startup). Of course you can create your own with
curl -X POST -H 'Content-Type: application/json' \
http://otoroshi-api.oto.tools:8080/api/apikeys/_template \
-u admin-api-apikey-id:admin-api-apikey-secret \
-d '{
"clientId": "quickstart",
"clientSecret": "secret",
"clientName": "quickstart-apikey",
"authorizedEntities": ["group_admin-api-group"]
}' | jq
now let create a new service to proxy https://maif.gitub.io
on domain maif.oto.tools
. This service will be public and will not require an apikey to pass
curl -X POST -H 'Content-Type: application/json' \
http://otoroshi-api.oto.tools:8080/api/services/_template \
-u quickstart:secret \
-d '{
"name": "quickstart-service",
"hosts": ["maif.oto.tools"],
"targets": [{ "host": "maif.github.io", "scheme": "https" }],
"publicPatterns": ["/.*"]
}' | jq
now just go to http://maif.oto.tools:8080
to check if it works
Create a service to proxy an api
now will we proxy the api at https://aws.random.cat/meow
that returns random cat pictures and make it use apikeys.
$ curl https://aws.random.cat/meow | jq
{
"file": "https://purr.objects-us-east-1.dream.io/i/20161003_163413.jpg"
}
First let’s create the service
curl -X POST -H 'Content-Type: application/json' \
http://otoroshi-api.oto.tools:8080/api/services/_template \
-u quickstart:secret \
-d '{
"id": "cats-api",
"name": "cats-api",
"hosts": ["cats.oto.tools"],
"targets": [{ "host": "aws.random.cat", "scheme": "https" }],
"root": "/meow"
}' | jq
but if you try to use it, you will have something like :
$ curl http://cats.oto.tools:8080 | jq
{
"Otoroshi-Error": "No ApiKey provided"
}
that’s because the api is not public and needs apikeys to access it.  First, we need to know what is the current state of the apikey quotas by enabling otoroshi headers about consumptions
curl -X PATCH -H 'Content-Type: application/json' \
http://otoroshi-api.oto.tools:8080/api/services/cats-api \
-u quickstart:secret \
-d '[
{ "op": "replace", "path": "/sendOtoroshiHeadersBack", "value": true }
]' | jq
and retry the call with
$ curl http://cats.oto.tools:8080 -u apikey1:secret --include
HTTP/1.1 200 OK
Date: Tue, 10 Mar 2020 12:56:08 GMT
Server: Apache
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-cache, must-revalidate
Otoroshi-Request-Id:<PHONE_NUMBER>529729796
Otoroshi-Proxy-Latency: 79
Otoroshi-Upstream-Latency: 416
Otoroshi-Request-Timestamp: 2020-03-10T13:55:11.195+01:00
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Otoroshi-Daily-Calls-Remaining: 9999998
Otoroshi-Monthly-Calls-Remaining: 9999998
Content-Type: application/json
Content-Length: 71
{"file":"https:\/\/purr.objects-us-east-1.dream.io\/i\/beerandcat.jpg"}
now let’s try to allow only 10 request per day on the apikey
curl -X PATCH -H 'Content-Type: application/json' \
http://otoroshi-api.oto.tools:8080/api/services/cats-api/apikeys/apikey1 \
-u quickstart:secret \
-d '[
{ "op": "replace", "path": "/dailyQuota", "value": 10 }
]' | jq
then try to call you api again
$ curl http://cats.oto.tools:8080 -u apikey1:secret --include
HTTP/1.1 200 OK
Date: Tue, 10 Mar 2020 13:00:01 GMT
Server: Apache
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-cache, must-revalidate
Otoroshi-Request-Id:<PHONE_NUMBER>930829633
Otoroshi-Proxy-Latency: 71
Otoroshi-Upstream-Latency: 92
Otoroshi-Request-Timestamp: 2020-03-10T13:59:04.456+01:00
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Otoroshi-Daily-Calls-Remaining: 7
Otoroshi-Monthly-Calls-Remaining: 9999997
Content-Type: application/json
Content-Length: 66
{"file":"https:\/\/purr.objects-us-east-1.dream.io\/i\/C1XNK.jpg"}
eventually you will get something like
$ curl http://cats.oto.tools:8080 -u apikey1:secret --include
HTTP/1.1 429 Too Many Requests
Otoroshi-Error: true
Otoroshi-Error-Msg: You performed too much requests
Otoroshi-State-Resp: --
Date: Tue, 10 Mar 2020 12:59:11 GMT
Content-Type: application/json
Content-Length: 52
{"Otoroshi-Error":"You performed too much requests"}


{% extends "base.html" %} {% block title %}
Medieval catalogues > NEW FRIARS > Lincoln-Austin > Lincolnshire list, 1528
{% endif %}4 identified entries found.
All data was derived from the List of Identifications by Professor Richard Sharpe.
{% if not printing %}
A key to codes used in the List is available (opens in new tab).{% endif %}


HTML Images is a link to a page on this website.
W3C is a link to a website on the World Wide Web.
This chapter explains ba bla bla
This chapter explains ba bla bla
This chapter explains ba bla bla
This chapter explains ba bla bla
This chapter explains ba bla bla
This chapter explains ba bla bla
This chapter explains ba bla bla
This chapter explains ba bla bla
This example uses a full URL to link to a web page:
This example uses a full URL to link to a web page:
The alt attribute provides an alternate text for an image, if the user for some reason cannot view it (because of slow connection, an error in the src attribute, or if the user uses a screen reader).
The GIF standard allows moving images.
Click on the ear or eyes to go to a new page and read more about the topic:
You can specify background images
for any visible HTML element.
In this example, the background image
is specified for this paragraph.
By default, the background-image
will repeat itself in the direction(s)
where it is smaller than the element
where it is specified. (Try resizing the
browser window to see how the
background image behave.
| Firstname | Lastname | Age |
|---|---|---|
| Jill | Smith | 50 |
| Eve | Jackson | 94 |
| John | Doe | 80 |
To make a cell span more than one column, use the colspan attribute.
| Name | Telephone | |
|---|---|---|
| sujata | 55577854 | 55577855 |
| Dinkar | 985577854 | 875577855 |
To make a cell span more than one row, use the rowspan attribute.
| address: | shinkoiwa |
|---|---|
| living person: | sujata |
| Dinkar |


Vaping illness cases rise again, to 2,172, CDC says
(NBC NEWS) – The number of vaping-related illnesses across the country increased again this week, though the jump in cases was smaller than in previous weeks.
On Thursday, the Centers for Disease Control and Prevention reported 2,172 lung injury cases linked to e-cigarette or vape products.
That’s an increase of 121 cases from last week. The only state left untouched by the epidemic is Alaska. Health officials in Puerto Rico and the U.S. Virgin Islands are also reporting cases of what’s now called EVALI, short for “e-cigarette, or vaping, product use associated lung injury.”
The illness has proven deadly for 42 people so far in 24 states and Washington, D.C.
California and Illinois are the states that have reported the largest number of EVALI deaths so far, with four each.
Last week, the CDC said it had found evidence of a synthetic form of vitamin E oil in lung fluid samples from patients. Of 29 samples tested, all 29 had extremely high levels of the oil.
While it’s a solid clue in the investigation into what is making people sick, it’s not likely to be the only cause.
The age range of patients is from 13 to people in their 70s — but most are men in their 20s and 30s, and most reported vaping products they bought off the street or got from friends that contained THC, marijuana’s psychoactive ingredient.
Patients generally have arrived at the hospital gasping for air and coughing, with a high fever, extreme fatigue and gastrointestinal problems. Many have been left with irreversible lung damage. And one patient — a 17-year-old boy in Michigan — needed a double lung transplant to survive.
In September, federal health officials announced they were planning to ban e-cigarette flavors, including mint and menthol. The Trump administration was expected to take some kind of action on vaping this week, but has not yet done so.
More International News Stories
-
Britain’s ‘first gay dads’ split after one starts dating daughter’s ex November 19, 2019
-
NYPD cop in fatal crash got at least 10 traffic citations this year November 19, 2019
-
At least three dead after Oklahoma Walmart shooting November 19, 2019
-
Vegan parents accused of starving 18-month-old son to death on raw food diet November 19, 2019
-
‘Invisibility cloak’ straight out of Harry Potter is now a thing November 19, 2019
-
Doctors warn that eyelash extensions are helping lice spread November 19, 2019
-
Dad marries daughter, has sex with her after allegedly killing man together: cops November 19, 2019
-
Criminal charges expected this week against Epstein guards November 19, 2019
-
Vegans sue Burger King over ‘contaminated’ fake meat in Impossible Burger November 19, 2019


Blinker provides fast & simple object-to-object and broadcast signaling for Python objects.
The core of Blinker is quite small but provides powerful features:
- a global registry of named signals
- anonymous signals
- custom name registries
- permanently or temporarily connected receivers
- automatically disconnected receivers via weak referencing
- sending arbitrary data payloads
- collecting return values from signal receivers
- thread safety
Blinker was written by Jason Kirtand and is provided under the MIT License. The library supports Python 2.4 or later; Python 3.0 or later; or Jython 2.5 or later; or PyPy 1.6 or later.
Named signals are created with signal():
>>> from blinker import signal
>>> initialized = signal('initialized')
>>> initialized is signal('initialized')
True
Every call to signal('name') returns the same signal object, allowing unconnected parts of code (different modules, plugins, anything) to all use the same signal without requiring any code sharing or special imports.
Signal.connect() registers a function to be invoked each time the signal is emitted. Connected functions are always passed the object that caused the signal to be emitted.
>>> def subscriber(sender):
... print("Got a signal sent by %r" % sender)
...
>>> ready = signal('ready')
>>> ready.connect(subscriber)
<function subscriber at 0x...>
Code producing events of interest can Signal.send() notifications to all connected receivers.
Below, a simple Processor class emits a ready signal when it’s about to process something, and complete when it is done. It passes self to the send() method, signifying that that particular instance was responsible for emitting the signal.
>>> class Processor:
... def __init__(self, name):
... self.name = name
...
... def go(self):
... ready = signal('ready')
... ready.send(self)
... print("Processing.")
... complete = signal('complete')
... complete.send(self)
...
... def __repr__(self):
... return '<Processor %s>' % self.name
...
>>> processor_a = Processor('a')
>>> processor_a.go()
Got a signal sent by <Processor a>
Processing.
Notice the complete signal in go()? No receivers have connected to complete yet, and that’s a-ok. Calling send() on a signal with no receivers will result in no notifications being sent, and these no-op sends are optimized to be as inexpensive as possible.
The default connection to a signal invokes the receiver function when any sender emits it. The Signal.connect() function accepts an optional argument to restrict the subscription to one specific sending object:
>>> def b_subscriber(sender):
... print("Caught signal from processor_b.")
... assert sender.name == 'b'
...
>>> processor_b = Processor('b')
>>> ready.connect(b_subscriber, sender=processor_b)
<function b_subscriber at 0x...>
This function has been subscribed to ready but only when sent by processor_b:
>>> processor_a.go()
Got a signal sent by <Processor a>
Processing.
>>> processor_b.go()
Got a signal sent by <Processor b>
Caught signal from processor_b.
Processing.
Additional keyword arguments can be passed to send(). These will in turn be passed to the connected functions:
>>> send_data = signal('send-data')
>>> @send_data.connect
... def receive_data(sender, **kw):
... print("Caught signal from %r, data %r" % (sender, kw))
... return 'received!'
...
>>> result = send_data.send('anonymous', abc=123)
Caught signal from 'anonymous', data {'abc': 123}
The return value of send() collects the return values of each connected function as a list of (receiver function, return value) pairs:
>>> result
[(<function receive_data at 0x...>, 'received!')]
Signals need not be named. The Signal constructor creates a unique signal each time it is invoked. For example, an alternative implementation of the Processor from above might provide the processing signals as class attributes:
>>> from blinker import Signal
>>> class AltProcessor:
... on_ready = Signal()
... on_complete = Signal()
...
... def __init__(self, name):
... self.name = name
...
... def go(self):
... self.on_ready.send(self)
... print("Alternate processing.")
... self.on_complete.send(self)
...
... def __repr__(self):
... return '<AltProcessor %s>' % self.name
...
You may have noticed the return value of connect() in the console output in the sections above. This allows connect to be used as a decorator on functions:
>>> apc = AltProcessor('c')
>>> @apc.on_complete.connect
... def completed(sender):
... print "AltProcessor %s completed!" % sender.name
...
>>> apc.go()
Alternate processing.
AltProcessor c completed!
While convenient, this form unfortunately does not allow the sender or weak arguments to be customized for the connected function. For this, connect_via() can be used:
>>> dice_roll = signal('dice_roll')
>>> @dice_roll.connect_via(1)
... @dice_roll.connect_via(3)
... @dice_roll.connect_via(5)
... def odd_subscriber(sender):
... print("Observed dice roll %r." % sender)
...
>>> result = dice_roll.send(3)
Observed dice roll 3.
Signals are optimized to send very quickly, whether receivers are connected or not. If the keyword data to be sent with a signal is expensive to compute, it can be more efficient to check to see if any receivers are connected first by testing the receivers property:
>>> bool(signal('ready').receivers)
True
>>> bool(signal('complete').receivers)
False
>>> bool(AltProcessor.on_complete.receivers)
True
Checking for a receiver listening for a particular sender is also possible:
>>> signal('ready').has_receivers_for(processor_a)
True
Both named and anonymous signals can be passed a doc argument at construction to set the pydoc help text for the signal. This documentation will be picked up by most documentation generators (such as sphinx) and is nice for documenting any additional data parameters that will be sent down with the signal.
See the documentation of the receiver_connected built-in signal for an example.
All public API members can (and should) be imported from blinker:
from blinker import ANY, signal
Token for “any sender”.
Sent by a Signal after a receiver connects.
| Argument : | the Signal that was connected to |
|---|---|
| Parameters: |
|
Deprecated since version 1.2.
As of 1.2, individual signals have their own private receiver_connected and receiver_disconnected signals with a slightly simplified call signature. This global signal is planned to be removed in 1.6.
A notification emitter.
| Parameters: | doc – optional. If provided, will be assigned to the signal’s __doc__ attribute. |
|---|
Emitted after each connect().
The signal sender is the signal instance, and the connect() arguments are passed through: receiver, sender, and weak.
New in version 1.2.
Emitted after disconnect().
The sender is the signal instance, and the disconnect() arguments are passed through: receiver and sender.
Note, this signal is emitted only when disconnect() is called explicitly.
The disconnect signal can not be emitted by an automatic disconnect (due to a weakly referenced receiver or sender going out of scope), as the receiver and/or sender instances are no longer available for use at the time this signal would be emitted.
An alternative approach is available by subscribing to receiver_connected and setting up a custom weakref cleanup callback on weak receivers and senders.
New in version 1.2.
A mapping of connected receivers.
The values of this mapping are not meaningful outside of the internal Signal implementation, however the boolean value of the mapping is useful as an extremely efficient check to see if any receivers are connected to the signal.
Connect receiver to signal events sent by sender.
| Parameters: |
|
|---|
Connect the decorated function as a receiver for sender.
| Parameters: |
|
|---|
New in version 1.1.
Execute a block with the signal temporarily connected to receiver.
| Parameters: |
|
|---|
This is a context manager for use in the with statement. It can be useful in unit tests. receiver is connected to the signal for the duration of the with block, and will be disconnected automatically when exiting the block:
with on_ready.connected_to(receiver):
# do stuff
on_ready.send(123)
New in version 1.1.
Disconnect receiver from this signal’s events.
| Parameters: |
|---|
True if there is probably a receiver for sender.
Performs an optimistic check only. Does not guarantee that all weakly referenced receivers are still alive. See receivers_for() for a stronger search.
Iterate all live receivers listening for sender.
Emit this signal on behalf of sender, passing on **kwargs.
Returns a list of 2-tuples, pairing receivers with their return value. The ordering of receiver notification is undefined.
| Parameters: |
|
|---|
An alias for connected_to().
| Parameters: |
|
|---|
New in version 0.9.
Changed in version 1.1: Renamed to connected_to(). temporarily_connected_to was deprecated in 1.2 and will be removed in a subsequent version.
Return the NamedSignal name, creating it if required.
Repeated calls to this function will return the same signal object. Signals are created in a global Namespace.
Bases: blinker.base.Signal
A named generic notification emitter.
The name of this signal.
Bases: dict
A mapping of signal names to signals.
Return the NamedSignal name, creating it if required.
Repeated calls to this function will return the same signal object.
Bases: weakref.WeakValueDictionary
A weak mapping of signal names to signals.
Automatically cleans up unused Signals when the last reference goes out of scope. This namespace implementation exists for a measure of legacy compatibility with Blinker <= 1.2, and may be dropped in the future.
New in version 1.3.
Return the NamedSignal name, creating it if required.
Repeated calls to this function will return the same signal object.
Released July 23, 2015
Released July 3, 2013
Released October 26, 2011
Released July 21, 2010
Released February 26, 2010
Released February 14, 2010


Please select one of the operations
Cash
Withdrawl
Cash
Deposit
Cheque
Deposit
Foreign
Currency
Other
Info


{% call appSummaryList({ heading: { text: "Attachments" }, actions: [ { href: actions.attachments, text: "Change", visuallyHiddenText: "attachments", classes: "app-c-summary-list__edit-section-link" }, { href: actions.reorder_attachments, text: "Reorder", visuallyHiddenText: "attachments", classes: "app-c-summary-list__edit-section-link" } if attachments | length > 1 ] if document.document_status != 'published' }) %} {%- if attachments | length %}
{% if attachment.isbn | length or attachment.urn | length or (attachment.cpn | length and attachment.cpn != "unnumbered") or (attachment.hcpn and attachment.hcpn != "unnumbered") %} Ref: {% endif %} {% if attachment.isbn | length %} ISBN {{ attachment.isbn }} {%- endif -%} {%- if attachment.urn | length %} {%- if attachment.isbn | length %},{% endif %} {{ attachment.urn }} {%- endif -%} {%- if attachment.cpn | length or attachment.official_document == 'yes_unnumbered_command_paper' %} {%- if attachment.isbn | length or attachment.urn | length %},{% endif %} {{ "Unnumbered command paper" if attachment.official_document == 'yes_unnumbered_command_paper' else attachment.cpn }} {%- endif -%} {%- if attachment.hcpn | length or attachment.official_document == 'yes_unnumbered_act_paper' %} {%- if attachment.isbn | length or attachment.urn | length or attachment.cpn | length %},{% endif %} HC {{ "Unnumbered act paper" if attachment.official_document == 'yes_unnumbered_act_paper' else attachment.hcpn }} {{ attachment.parliamentary_session }} {% endif %}
{%- if attachment.cpn == "unnumbered" or attachment.hcpn == "unnumbered" %}{{- 'Unnumbered command paper' if attachment.cpn == "unnumbered" else ('Unnumbered act paper' if attachment.hcpn == "unnumbered") -}}
{% endif -%} {%- if attachment.url | length %} {% elif attachment.type in ['html','file'] %} {% endif -%}No attachments added to this document.
{% endif -%} {% endcall %}


This is an example application that converts WordPress Backup XML (WXR) to JSON. The converter is written in Go, and uses this WXR library.
Upload your own XML file by dropping it below. You can also try the functionality, by clicking the button below to convert an example.xml.
{{wxrJson}}


Vegan
Vegetarian
Egg
Keto
Paleo
Allergies
What's your daily calorie goal?
How many meals do you eat a day?


Tidy Tuesday - African American History
If you’re not familiar with Tidy Tuesday, it is a weekly project hosted online by the R for data science community. Every Tuesday a new dataset is released and people are encouraged to explore, analyse, and visualize it in interesting ways. This is my first week exploring tidy tuesday data. Information about the project and datasets is at the tidytuesday github. Before working with this data I watched Julia Silge’s excellent screencast and picked up some great ways to find missing values and recode data.
A Little History
I learned a lot just by looking at the data provided. I was not previously aware of the history captured in the african_names dataset - which lists the names of enslaved people that were freed as they were being illegally smuggled to the Americas. The most names were recorded at the port of Freetown in Sierra Leone before making the trans-atlantic journey. Here’s the description of the dataset excepted on the tidytuesday github page:
During the last 60 years of the trans-Atlantic slave trade, courts around the Atlantic basins condemned over two thousand vessels for engaging in the traffic and recorded the details of captives found on board including their African names. The African Names Database was created from these records, now located in the Registers of Liberated Africans at the Sierra Leone National Archives, Freetown, as well as Series FO84, FO313, CO247 and CO267 held at the British National Archives in London. Links are provided to the ships in the Voyages Database from which the liberated Africans were rescued, as well as to the African Origins site where users can hear the names pronounced and help us identify the languages in which they think the names are used.
| Name | african_names |
| Number of rows | 91490 |
| Number of columns | 11 |
| _______________________ | |
| Column type frequency: | |
| character | 6 |
| numeric | 5 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| name | 0 | 1.00 | 2 | 24 | 0 | 62330 | 0 |
| gender | 12878 | 0.86 | 3 | 5 | 0 | 4 | 0 |
| ship_name | 1 | 1.00 | 2 | 59 | 0 | 443 | 0 |
| port_disembark | 0 | 1.00 | 6 | 19 | 0 | 5 | 0 |
| port_embark | 1126 | 0.99 | 4 | 31 | 0 | 59 | 0 |
| country_origin | 79404 | 0.13 | 3 | 31 | 0 | 563 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| id | 0 | 1.00 | 62122.02 | 51305.07 | 1.0 | 22935.25 | 45822.5 | 101263.8 | 199932 | ▇▆▃▁▂ |
| voyage_id | 0 | 1.00 | 17698.25 | 82016.88 | 557.0 | 2443.00 | 2871.0 | 3601.0 | 500082 | ▇▁▁▁▁ |
| age | 1126 | 0.99 | 18.89 | 8.60 | 0.5 | 11.00 | 20.0 | 26.0 | 77 | ▆▇▁▁▁ |
| height | 4820 | 0.95 | 58.61 | 6.84 | 0.0 | 54.00 | 60.0 | 64.0 | 85 | ▁▁▂▇▁ |
| year_arrival | 0 | 1.00 | 1831.40 | 9.52 | 1808.0 | 1826.00 | 1832.0 | 1837.0 | 1862 | ▂▆▇▃▁ |
## # A tibble: 5 x 2
## # Groups: port_disembark [5]
## port_disembark n
## <chr> <int>
## 1 Freetown 81009
## 2 Havana 10058
## 3 Bahamas unspecified 183
## 4 Kingston, Jamaica 144
## 5 St. Helena 96
From this output we can see that country_origin
has the most missing data by far. There’s a clue about this in the description of the data above, which mentions the African Origins site, where users can hear the names pronounced and help identify the languages in which they think the names are used.
So the people who were liberated were from such different cultures that the original documentarians could not speak the same language or determine where they originally came from. We can see that about 81,000 people were freed in Freetown (This now makes sense - again learning lots here). About 10,000 people were freed in Havana, Cuba, and many less in other locations in the caribbean.
The age
variable includes entries from a 6-month old child to a 77 year old person. The gender
variable has 12,878 missing values and 4 options. I’ll use some of the same techniques as Julia Silge to clean up this data.
african_names %>%
group_by(port_disembark, year_arrival) %>%
count() %>%
arrange(desc(year_arrival)) %>%
ggplot(aes(x = year_arrival, y = n, color = port_disembark)) + geom_line(alpha = 0.6, size = 2) + geom_point(alpha = 0.6)
We can see that the majority of liberations occured in Freetown. I wonder if the ships had stopped going to Freetown by 1849, or if there was less enforcement, or if they stopped being recorded. Similary, I wonder what the policies were in each of the other ports that made them free enslaved Africans for the time periods reflected in this data.


cice_to_obs - read binary files from the national snow and ice data center and convert percentages into sea ice concentration observation sequence files.
nsc 28 june 2016 based on conversion programs from Yongfei Zhang, now at University of Washington working with Cecelia Bitz.
right now no code uses netcdf or nc_check, so it's commented out.
@todo FIXME - originally i thought we needed to read the netcdf file
which contained the model land mask. but creating observations from
the binary files is unrelated to the model grid so this code is
currently commented out and probably should be removed. BUT: it could
be useful to create an obs_seq.in (synthetic obs) for
a perfect_model_obs experiment, so i've left it for now.
(all related code marked with LANDMASK tag for easier cleanup.)
nsc 30jun2016
see comment in cice_lat_file section
FIXME tell user we are ignoring existing file and why @todo make sure start_time = end_time if you aren't generating the filenames by pattern. @todo FIXME open the new output file? @todo make sure start_time = end_time if you aren't generating the filenames by pattern. see comment in cice_lat_file section
FIXME: here if we're looping over the output, write the obs_seq file and open a new one
| Type | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|
| character(len=*), | parameter | :: | routine | = | 'cice_to_obs' | |
| character(len=*), | parameter | :: | source | = | "$URL$" | |
| character(len=*), | parameter | :: | revision | = | "$Revision$" | |
| character(len=*), | parameter | :: | revdate | = | "$Date$" | |
| character(len=256) | :: | next_file | ||||
| character(len=512) | :: | msgstring | ||||
| character(len=512) | :: | msgstring1 | ||||
| integer | :: | oday | ||||
| integer | :: | osec | ||||
| integer | :: | iunit | ||||
| integer | :: | io | ||||
| integer | :: | rc | ||||
| integer | :: | year | ||||
| integer | :: | month | ||||
| integer | :: | day | ||||
| integer | :: | hour | ||||
| integer | :: | minute | ||||
| integer | :: | second | ||||
| integer | :: | num_copies | ||||
| integer | :: | num_qc | ||||
| integer | :: | max_obs | ||||
| integer | :: | ilon | ||||
| integer | :: | ilat | ||||
| integer | :: | start_index | ||||
| logical | :: | file_exist | ||||
| logical | :: | first_obs | ||||
| real(kind=r8), | allocatable | :: | lat(:,:) | |||
| real(kind=r8), | allocatable | :: | lon(:,:) | |||
| real(kind=r8), | allocatable | :: | percent(:,:) | |||
| real(kind=r8) | :: | perr | ||||
| real(kind=r8) | :: | qc | ||||
| integer(kind=i2), | allocatable | :: | rawdata_i2(:) | |||
| integer(kind=i4), | allocatable | :: | rawdata_i4(:) | |||
| type(obs_sequence_type) | :: | obs_seq | ||||
| type(obs_type) | :: | obs | ||||
| type(obs_type) | :: | prev_obs | ||||
| type(time_type) | :: | time_obs | ||||
| type(time_type) | :: | prev_time | ||||
| type(time_type) | :: | curr_time | ||||
| type(time_type) | :: | end_time | ||||
| type(time_type) | :: | one_day | ||||
| character(len=256) | :: | cice_lat_file | = | 'psn25lats_v3.dat' | ||
| character(len=256) | :: | cice_lon_file | = | 'psn25lons_v3.dat' | ||
| integer | :: | num_latitudes | = | 448 | ||
| integer | :: | num_longitudes | = | 304 | ||
| real(kind=r8) | :: | grid_scale_factor | = | 100000.0 | ||
| real(kind=r8) | :: | data_scale_factor | = | 10.0 | ||
| integer | :: | land_missing_value | = | -800 | ||
| integer | :: | pole_missing_value | = | -100 | ||
| real(kind=r8) | :: | error_factor | = | 0.10 | the observation error will be set by multiplying the obs value by this factor. we can also change this to be a fixed value, or ?? but for now the obs error will be 10% of the observed value. (or whatever you specify in the namelist) |
|
| logical | :: | ignore_zero_obs | = | .false. | science question - like radar obs with no reflectivity, there are many obs with 0 ice. this is information and these obs could be assimilated to remove ice where it isn't observed. but it greatly increases the number of obs created. it should be tested to see if these obs are worth using. |
|
| logical | :: | use_data_filename_pattern | = | .true. | these are alternatives for specifying the input file(s). if pattern is .true. the YYYY, MM, and DD will be replaced by the actual year, month, day and the program will loop from the start year/month/day to the end date. if pattern is false, it will ignore the start/end values below and simply open the single cice_data_file. |
|
| character(len=256) | :: | data_filename_pattern | = | 'bt_YYYYMMDD_n07_v02_n.bin' | ||
| character(len=256) | :: | cice_data_file | = | 'bt_19800101_n07_v02_n.bin' | ||
| logical | :: | use_obsseq_filename_pattern | = | .true. | these are alternatives for specifying the output file(s). if pattern is .true. the YYYY, MM, and DD will be replaced by the actual year, month, day and the program will create a different output file for each day. if pattern is false, all the obs will be added to a single output obs_seq file with the name given below. |
|
| character(len=256) | :: | obsseq_filename_pattern | = | 'obs_seq.YYYYMMDD' | ||
| character(len=256) | :: | obsseq_out_file | = | 'obs_seq.out' | ||
| integer | :: | start_year | = | 1980 | if using an input filename pattern, this program can loop
over multiple days. this section controls how many days to do. |
|
| integer | :: | start_month | = | 1 | ||
| integer | :: | start_day | = | 1 | ||
| integer | :: | end_year | = | 1980 | ||
| integer | :: | end_month | = | 1 | ||
| integer | :: | end_day | = | 1 | ||
| logical | :: | append_to_existing_file | = | .false. | probably not as useful here as might be in other converters. if looping outside this program (from a script), you can set this to true to append more obs to an existing obs_seq file. since this program loops already, you normally want to leave this as .false. |
|
| logical | :: | debug | = | .false. | set to true to print out more info. |
take a character string which must contain YYYY, MM, and DD and substitute the year, month and day. it is an error to have a pattern without all 3 items.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | inpattern | |||
| character(len=*), | intent(out) | :: | outstring | |||
| integer, | intent(in) | :: | year | |||
| integer, | intent(in) | :: | month | |||
| integer, | intent(in) | :: | day |


This slide is all text. This is in the header.
"These images are just placeholders"
While this slide is in the middle of the list, it's a "sponsor" slide, which means it will show up every few slides.
This slide...
...shows paragraphs...
...one at a time.
And this slide splits a paragraph up by characters and shows them one by one.
You have the power of Animate.CSS, so you can use different types of transitions!
This is another "sponsor" slide.
You can have it be anything you want.
Text, graphics, or combination of both.
I thought you would want to know.
So the majority of layout that I have implemented so far is on a grid system.
This is the final slide. Now we go back to the beginning.


The result of multiplying generators in a Green functor.
More...
#include <Green.hpp>
|
| | Green () |
| | Sets to zero. More...
|
| |
| | Green (const Chains< rank_t, diff_t > &, const Chains< rank_t, diff_t > &, int, int, int) |
| | Computes the product of generators given chains, degrees and level. More...
|
| |
| template<typename T , typename S > |
| auto | getNormalBasis (const T &, const S &) const |
| | Returns the (normalized) product of the given two elements (not necessarily generators) More...
|
| |
| template<typename T = int, typename S > |
| auto | getNormalBasis (int i, const S &b) const |
| | Returns the (normalized) product of the selected generator with another element. More...
|
| |
| template<typename T , typename S = int> |
| auto | getNormalBasis (const T &a, int j) const |
| | Returns the (normalized) product of the given element with the selected generator. More...
|
| |
| template<typename T = int, typename S = int> |
| auto | getNormalBasis (int i, int j) const |
| | Returns the (normalized) product of the selected generators. More...
|
| |
| bool | operator== (const Green< group_t > &) const |
| |
template<typename group_t>
class Mackey::Green< group_t >
The result of multiplying generators in a Green functor.
◆ Green() [1/2]
◆ Green() [2/2]
| Green |
( |
const Chains< rank_t, diff_t > & |
, |
|
|
const Chains< rank_t, diff_t > & |
, |
|
|
int |
, |
|
|
int |
, |
|
|
int |
|
|
) |
| |
Computes the product of generators given chains, degrees and level.
◆ getNormalBasis() [1/4]
| auto getNormalBasis |
( |
const T & |
, |
|
|
const S & |
|
|
) |
| const |
Returns the (normalized) product of the given two elements (not necessarily generators)
◆ getNormalBasis() [2/4]
| auto getNormalBasis |
( |
int |
i, |
|
|
const S & |
b |
|
) |
| const |
Returns the (normalized) product of the selected generator with another element.
◆ getNormalBasis() [3/4]
| auto getNormalBasis |
( |
const T & |
a, |
|
|
int |
j |
|
) |
| const |
Returns the (normalized) product of the given element with the selected generator.
◆ getNormalBasis() [4/4]
| auto getNormalBasis |
( |
int |
i, |
|
|
int |
j |
|
) |
| const |
Returns the (normalized) product of the selected generators.
◆ operator==()
| bool operator== |
( |
const Green< group_t > & |
| ) |
const |
◆ internal::GreenCompute
◆ serialize
| void serialize |
( |
Archive & |
, |
|
|
Green< T > & |
|
|
) |
| |
|
friend |
◆ Groups
The homology group the product lives in.
◆ isZero
1 if the homology group the product lives in is 0.
◆ boxID
Identifies the generators of the homology group the product lives in.
The documentation for this class was generated from the following file:


Bootstrap 3 PIE Header CSS
Here is an example PIE Header built in Bootstrap 3.
icon-th-ebay
icon-question-sign-ebay
icon-envelope-ebay
If you have any questions, contact Ted Pedersen<EMAIL_ADDRESS>Here is an example PIE Header built in Bootstrap 3.
icon-th-ebay
icon-question-sign-ebay
icon-envelope-ebay
If you have any questions, contact Ted Pedersen tepedersen@ebay.com


Software Engineer at Google
12/2018 - Present. Canada
Being part of "Engineering Productivity" group, my focus is on providing various development teams at Google with tools to reliably and efficiently test, profile and diagnose software products and systems to ultimately help maintain highest level of quality.
Principal Engineer at Scotiabank
2/2017 - 12/2018. Canada
In this role, I'm helping accelerating Scotiabank's transformation into a true technology company. I have spent my first few months working on Cloud Development Platform - a set of effective, reliable and easy to use tools for building, deploying and managing highly-available, enterprise-grade applications that serve internal and external customers. These days I am responsible for adoption of new technology in Scotiabank's South American locations (working with engineering teams in Mexico, Peru, Chile and Colombia).
7/2013 - 2/2017. Poland, Canada, USA
As a consultant / team lead, I work on various projects for different clients. Each and every project is unique in terms of architectural design, technologies and tools involved as well as the development workflow. It's also a great opportunity to learn new tools and practices and master existing skills. Not to mention that I'm constantly surrounded by exceptionally smart people - my colleagues.
Founder and TCO at Sprites
9/2014 - 8/2016. Poland, Canada
Sprites is a web-based tool for creating beautiful infographics and online presentations. I was behind the original concept, prototype, first version and was in charge of product development, marketing, sales and public relations.
System Developer and Architect at Dynamicweb
2/2006 - 7/2013. Denmark
My daily work consisted of designing and implementing core components for one of the finest content management systems in Denmark: Dynamicweb CMS. I was also spending a lot of time maintaining (and helping others maintain) the product as well as hosting and participating in webinars, training courses and conferences aimed at improving the level of knowledge of the system by the customers.
7/2012 - 1/2013. Denmark
PriceFlurry is a place to share and discover the cost of different goods and services. I was the author of the original idea, I have designed and implemented the entire platform (frontend, backend, public/private APIs, WP7 app). I've also implemented the entire UI. Although, I was very satisfied with the quality of the product and the technology behind it, I had to shut PriceFlurry down for a number of reasons (more details can be found on the blog).


Erin Becker
studied microbial genomics at UC Davis where she also did a postdoc in Biology Education Research.
She has experience developing and implementing practice-based instructional training programs as well as
building community for supporting instructional innovation. Erin tweets at
@ErinSBecker.
Email: ebecker@datacarpentry.org


Type: Served
Name: Dorian Popescu
Background
- Date of Birth:
- Gender: Male
- Location: Iasi, Romania
- Work place: Restaurant Blue Aqua, Waiter
- School: High School no 3
- Technology Level: Intermediate
Main Points
Dorian Popescu is a 44-year-old man. He has secondary education and a waiter specialization. In his free time he likes to use social networks, watch tv, hang out with friends and play on the phone.
- Experience with certain products;
He has recently learned to use a smartwatch and is always trying to keep up with the latest tech.
He likes to use devices such as tablet, phone. - Dislikes about certain aspects;
It is hard for him to decide what is the truth when there are so many information sources - Disabilities relevant to our research;
He is likely to be undecided or unwilling to test the application because it may seem too difficult - Working environment;
In his workplace he has contact with many culinary preparations, which makes him curious about the origin of the food and his availability in his town. - Social connections;
Daily uses Facebook to talk with family and friends and post his latest blog posts. - The user's goals.
He wants to have easy access to information, to be on the trend with his friends and to have lower living costs whilst not sacrificing health.
Goals
Goals are the reasons users perform tasks, not the tasks.
- Practical Goals:
Get the best food recommendation but also take into consideration price. - Personal Goals:
Because his revenues is rather small, he want to use such an application to reduce his cost of living. - Business Goals:
Because he has been working in the industry for such a long time, he is also searching for an app that could help him on multiple plans: provide data for starting a small bio restaurant, marketing of his business locally and finding fresh supplies for his business.
Frustrations and Pain Points
Some of the difficulties the user has with the product.
- UI, Interaction, User Experience;
It's hard to get familiar with unknown apps. He does not like applications that are too colorful. - Dislikes relevant to the research; Slow apps, apps that have a high learning curve, intrusive and annoying apps that waste his time.
- Disabilities;
It might be difficult to recognize certain suggestions of the application and may encounter difficulties in understanding the context of the application - Unreliability of the product;
Until he becomes accustomed to the application he may not feel comfortable in using it. - Difficulties in completing tasks;
Since English is used to provide the necessary information about the application, it may have difficulty in correctly understanding the recommendations proposed by the application and how it could be used. - Problems with the product:
There is the possibility of hardly adapting to the application, making it difficult to use because it has recommendations and suggestions that you would not know how to use them.
Detailed Description
Dorian has a solid career for over 10 years. He has worked for several types of restaurants in the country and abroad. He believes that the diversity of flavors he puts in food offers a special taste. Dorian has a personal blog posting his preparations.
- Personal Goals like:
He wants to reduce his personal financial costs and be as familiar with product marketing applications as possible. He thinks these apps can help him make quality content on his blog because he has the opportunity to buy various products. - Business Goals like:
Wants to have access to good prices for the food he is looking for in order to prepare his culinary products
- Experience with certain applications, products;
In his spare time he uses socializing applications such as Whatsapp, Facebook or Instagram. He likes to be in trend with his group of friends and participate in various events announced. Participant in online groups. - Frequency of use.
Frequently use the internet to find discounts, listen to music and socialize.
References
- Fluid Personas;
- An introduction to personas and how to create them;
- The Persona Lifecycle, Keeping People in Mind Throughout Product Design, John Pruitt & Tamara Adlin;
- This version of Personas Template includes microdata markup using schema.org Schemas.
Scenarios
1. At home, he uses the phone to put groceries needed, at shopping the smartwatch will tell what he needs and also show other suggestions and again with the phone it can scan different products to get information.
2. When the shopping list is made, it will suggest the best prices and where to buy from local producers to stimulate local economy and avoid crowded supermarkets
3. Be in trend with social life as he would get recommendations of products that her friends buy.


|
.NET Framework | |||||||||
| PREV TYPE NEXT TYPE | FRAMES NO FRAMES | |||||||||
| SUMMARY: INNER | FIELD | CONST | PROP | METHOD | OP | EVENT | DETAIL: FIELD | CONST | PROP | METHOD | OP | EVENT |
| Constructor Summary | |
|---|---|
|
FieldMethodizer() Allow object to be initialized without any data. You would use addObject() to add data later. |
|
|
FieldMethodizer(string s) Constructor that takes as it's arg the name of the class to methodize. |
|
|
FieldMethodizer(object o) Constructor that takes as it's arg a living object to methodize. Note that it will still only methodized the public static fields of the class. |
| Method Summary | |
|---|---|
| void |
addObject(object o) Add an Object to methodize |
| void |
addObject(string s) Add the Name of the class to methodize |
| object |
Get(string fieldName) Accessor method to get the fields by name. |
| Methods inherited from class System.Object |
|---|
| Equals, Finalize, GetHashCode, GetType, MemberwiseClone, ToString |
| Constructor Detail |
|---|
public FieldMethodizer()
Allow object to be initialized without any data. You would use addObject() to add data later.
public FieldMethodizer(string s)
Constructor that takes as it's arg the name of the class to methodize.
Parameters:
s
- Name of class to methodize.public FieldMethodizer(object o)
Constructor that takes as it's arg a living object to methodize. Note that it will still only methodized the public static fields of the class.
Parameters:
o
- object to methodize.| Method Detail |
|---|
public void addObject(object o)
Add an Object to methodize
public void addObject(string s)
Add the Name of the class to methodize
public object Get(string fieldName)
Accessor method to get the fields by name.
Parameters:
fieldName
- Name of static field to retrieve
|
.NET Framework | |||||||||
| PREV TYPE NEXT TYPE | FRAMES NO FRAMES | |||||||||
| SUMMARY: INNER | FIELD | CONST | PROP | METHOD | OP | EVENT | DETAIL: FIELD | CONST | PROP | METHOD | OP | EVENT |


Helvetia:
Look, I already told you! I can't give it to you for free. If you change your mind, come back and see me.


About trivial-main-thread
Sometimes it is absolutely necessary to run certain tasks in the main thread of the implementation. This is particularly the case with GUI applications on OS X, where only thread 0 is allowed to issue drawing calls. This library aims to help with that.
Why a Wrapper
Why not just call bt:interrupt-thread
and be done with it? Well, an implementation is not required to provide the user with the main thread, and may instead choose to use it for its own purposes. For example, CCL uses the thread for housekeeping and signal handling. As such, some implementations require workarounds to make this go by smoothly. That's why this library exists.
Basic Usage
Load trivial-main-thread through ASDF or Quicklisp.
(ql:quickload :trivial-main-thread)
Now you can simply issue calls to be sent to the main thread by using call-in-main-thread
or with-body-in-main-thread
.
(call-in-main-thread (lambda () (+ 1 1)))
(with-body-in-main-thread (:blocking T)
(+ 1 1))
Upon first usage of either of these two functions, trivial-main-thread will start a new thread to resume the main thread's functionality in if necessary, and interrupt the main thread with a task runner loop. From then on, call requests can be sent to the thread. For more information on the tasks and runners system, see simple-tasks.
For example, if you wanted to start a Qt application, you could do the following:
(call-in-main-thread #'qt:make-qapplication)
(with-body-in-main-thread ()
(qt:with-main-window (window (make-instance 'my-window))))
And the application will safely run in the main thread.
In the case where the main thread /is/ the evaluating thread, no additional threads are started, and the runner used will simply directly run tasks.
Also See
- Simple-tasks For remote task running.


{% extends "base.html" %} {% load url from future %} {% block head %} {% endblock %} {% block content %}
It seems you don't have any open annotations. You can just continue with the next one.


README¶
Python Guide for Practicing Wizards¶
Documentation¶
https://shawnjburke.github.io/py_guide/ https://py-guide.readthedocs.io/en/latest/
The docs are hosted with gitHub Pages, with html in the docs/ folder, powered by reStructured text markup in the data-source folder. You can get to the root at py_quide. They are also mirrored on Read the Docs.
Purpose of this Project¶
This project implements a Python Project generator. It’s aim is to create a standard framework for Python projects that includes best practices. The results should be code that is documented, has an installation and versioning paradigm in place, and makes it easier for a programmer to do things that are often tedious.
Best practice steps are organized as follows:
Installation¶
At this time you can’t install this module. At a later version the installation will provide an interface to create the recommended project structure, documented here.
c:\Python37>scripts\pip install sjb.pyguide
Successfully installed Menu-3.1.0 configparser2-4.0.0 sjb.pyguide-0.2.5
c:\Python37>scripts\py_guide --show_menu
Version History¶
- 0.2.5 - Fix missing installation requirements in setup.py such as missing package_data items. Console invoked generator appears functional.
- 0.2.4 - Fix issues with generated project, wheel installation file, not working. Add several files missing from generated project.
- 0.2.3 - Beta version of project generator. Creates a Python 3.x project with best practices, including initialized virtual environment.
- 0.2.2 - Adding in incomplete changes for project generator on way to v0.3.0. Will create directory structure and 1/2 dozen files for the project. Not complete yet.
- 0.2.1 - Remove revealjs theme which is no longer supported and didn’t work right anyway.
- 0.2.0 - Updated a number of package requirements such as sphinx themes to meet compatibility requirements.
- 0.1.0 - First version with semantic versioning schema. Most of documentation is strong. Console script to create a project is in an development state.


Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quaello.
Other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble.
+8801760-00000
<EMAIL_ADDRESS>10/2 Street View, New York, USA


Reserve a Room at The Hamilton Conference Center
To reserve a room, please contact Yancy Inwe at extension 388 or by e-mail at<EMAIL_ADDRESS>Reservations should be made at least 48 hours in advance. Cancellations require 24 hour notice. Room deposits will not be returned for cancellations within 24 hours of the scheduled event.


Table of Contents
Slack is an American cloud-based set of proprietary team collaboration software tools and online services, developed by Slack Technologies. Slack is a workspace where teams can communicate and collaborate.
Teamwork in Slack happens in channels — a single place for messaging, tools and files — helping everyone save time and collaborate.
One of the awesome features of Slack is Slack Apps, integrations and Slack Bots.
A Slack bot is a type of Slack App designed to interact with users via conversation. Your bot can send DMs, it can be mentioned by users, it can post messages or upload files, and it can be invited to channels. Cool right?
If you use Slack already, you should be familiar with some creative Slack bots like Standupbot, Birthdaybot and more.
In this article, I’ll walk you through building your first Slack bot from start to finish with Node.js and SlackBots.js
SlackBot Description
We’re going to build a simple Slackbot that displays random inspiring techie quotes and jokes for developers/designers.
I built a chrome extension before now that displays random inspiring techie quotes for developers/designers on your new tab (you can download it here), we’ll be using the quotes JSON from this extension as our quotes API and Chuck Norris Jokes API for the jokes.
When a user mentions our bot and adds inspire me, the bot returns a random quote from inspireNuggets, when the user types random joke, it returns a random joke from Chuck Norris API and when the user types help, it returns the instruction guide.
@inspirenuggets inspire me
@inspirenuggets random joke
@inspirenuggets help
This article is not really about what we’ll be building, it’s just to show you the concept behind Slack bots and how to build yours, after now, you can think about something else and build a different bot, there’re several possibilities.
You can clone or fork the final project here
Pretty interesting right? Let’s get started
Prerequisite
This bot will be built with Node.js and SlackBots.js. You don’t need to know how to write Node.js, I’ll walk you through it, but knowing it is an advantage.
- Basic JavaScript knowledge
- ES6 JavaScript
- Slack workspace
- Some experience with Slack
- Some version control skills
Setup environment
Let’s set up and install Node.js and Npm first.
- Download node here, If you have it installed already, skip this step. If you prefer to use a package manager to install, read this for all operating systems.
- Check if you have Node installed
node -v
- Node.js comes with Npm, you don’t have to install that again.
npm -v
Now that we have Node.js setup, let’s initialize our project
- Create your project directory (I called mine Slackbot)
- Initialize git
git init
- create an
index.js
file
touch index.js
- Initialize Npm
npm init
Simply answer all questions that come afterwards, if you’re having issues, here’s my own package.json
{
"name": "slackbot",
"version": "1.0.0",
"description": "A simple Slackbot that displays random inspiring techie quotes for developers/designers.",
"main": "index.js",
"scripts": {
"start": "index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/BolajiAyodeji/slackbot.git"
},
"author": "Bolaji Ayodeji",
"license": "MIT",
"bugs": {
"url": "https://github.com/BolajiAyodeji/slackbot/issues"
},
"homepage": "https://github.com/BolajiAyodeji/slackbot#readme"
}
Install Dependencies
Now let’s install and setup all libraries we need.
SlackBots.js
SlackBots.js is Node.js library for easy operation with Slack API.
npm install slackbots
In index.js
const SlackBot = require('slackbots');
Axios
Axios is a promise based HTTP client for the browser and node.js. If you know Fetch or AJAX, this is just a library that does same with far way cooler features. You can see them here
npm install axios
In index.js
const axios = require('axios')
Nodemon
To run a script in Node.js, you have to run node index.js
. Whenever you make changes to this file, you have to rerun node index.js
, this sucks right when you’re making so many changes like we’ll be doing. That’s why we need nodemon, nodemon is a tool that helps develop node.js based applications by automatically restarting the node application when file changes in the directory are detected.
npm install -g nodemon
In package.json
, locate the scripts section and add a new start script
"scripts": {
"start": "node index.js"
}
If you run npm start
, the file will run but won’t restart on change. To fix this use the nodemon we installed instead of node like so:
"scripts": {
"start": "nodemon index.js"
}
Dotenv
I won’t explain this in-depth, in a few days, I’ll publish an article around environmental variables, for now just know that we use this to hide secret keys and tokens like the Slack Access Token we would be using.  There are several ways to do this, but I prefer using dotenv, Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.
npm install dotenv
In index.js
const dotenv = require('dotenv')
dotenv.config()
After all installation, your package.json
should look like this:
{
"name": "inspireNuggetsSlackBot",
"version": "1.0.0",
"description": "A simple Slackbot that displays random inspiring techie quotes and jokes for developers/designers.",
"main": "index.js",
"scripts": {
"start": "nodemon index.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/BolajiAyodeji/inspireNuggetsSlackBot.git"
},
"author": "Bolaji Ayodeji",
"license": "MIT",
"bugs": {
"url": "https://github.com/BolajiAyodeji/inspireNuggetsSlackBot/issues"
},
"homepage": "https://github.com/BolajiAyodeji/inspireNuggetsSlackBot#readme",
"devDependencies": {
"dotenv": "^8.0.0"
},
"dependencies": {
"axios": "^0.19.0",
"slackbots": "^1.2.0"
}
}
Create your Slack workspace
Now that we have all set up, we need a Slack workspace to run our bot in development. Creating a workspace is pretty easy, read this.
Register your Slack Bot
Now that you have a workspace, you should have a Slack URL with your workspace name, mine is mekafindteam.slack.com
.
- Now you’ll need to create a Slack App. Create one here
Enter your App name and ensure you’re in the workspace you created if you’re in multiple workspaces.
- Now you’ll see the settings > Basic Information page. Click the first tab
Add features and functionality
Since we’re building a bot, select the Bots field.
- Now you’ll see the Bot user page
Click the Add a Bot User
button
- Your display name will automatically be filled in from your already chosen App name, you can update but I’ll advise you use the same name everywhere with the same alphabet case to avoid errors.
Now, toggle the Always Show My Bot as Online
switch to always show your bot as Online, remember this bot is just like a user in your workspace. Afterwards, click the Add Bot User
button
- Save all changes now
- Return to the
Basic Information
page and select theInstall your app to your workspace
tab.
Click the Install App to Workspace
Click allow and wait to be redirected back to the Basic Information
page.
Note the
Manage distribution
tab, this section is needed when you want to make your Bot available for installation by others, for now we’re just building in development and I won’t be covering distribution in this article, in my next article, I’ll show you how to deploy your Slack bot and make it available as an App to other workspaces.
- If you check your Slack workspace now, you should see the App installed in the Apps section
For now, it’s offline, once we start building the bot, we’ll turn this on.
Customize your Slack bot
Now we’ve created our bot, let’s do some customization
- Still, on the
Basic Information
page, scroll down to theDisplay Information
section
This is basic stuff, just upload a logo, change your background color and add a short description
Your icon should be
512x512px
or bigger and your background color should be in HEX. Read more on the App guidelines here
Here’s what mine looks like after customization:
Slack bot OAuth Tokens
Now we have our Slack bot setup, let’s grab out token keys.
- In the navigation bar, locate the Features section and click the
OAuth & Permission
tab
You’ll see two Access Tokens
- OAuth Access Token
- Bot User OAuth Access Token
Copy the Bot User OAuth Access Token
This would change every time you Reinstall this app or when you install it in another workspace. The token should start with
xoxb-
Keeping credentials secure is important whether you’re developing open source libraries and tools, internal integrations for your workspace, or Slack apps for distribution to workspaces across the world. - Slack
This is why we have installed Dotenv and we’ll set that up in the next section.
Building the bot
Now let’s build our bot :).
First, let’s keep our Access Token somewhere.
create a .env
file and add this:
BOT_TOKEN=YOUR_SLACK_ACCESS_TOKEN_HERE
- Now let’s start our SlackBot.js
const bot = new SlackBot({
token: `${process.env.BOT_TOKEN}`,
name: 'inspirenuggets'
})
We’ve just created a bot variable that initializes a new SlackBot instance which has two values, our token and app name.
I used the ES6 template string syntax to bring in our token key from our
.env
file, dotenv got this covered for us.Ensure to use the same name you used while creating your Slack app else you’ll have authentication errors.
- Now start the app
npm start
nodemon should be running now and our Slack app should be online too.
Start handler
Our Bot does nothing now even though it’s running, let’s return a message.
bot.on('start', () => {
const params = {
icon_emoji: ':robot_face:'
}
bot.postMessageToChannel(
'random',
'Get inspired while working with @inspirenuggets',
params
);
})
The
bot.on
handler sends the welcome message. We passed two parameters, the'start'
and a function which holds a params variable which also holds the slack emoji. Slack emoji have codes, you can find them here. I used:robot_face:
, you can change this to your preferred emoji.We also initialized the
bot.postMessageToChannel
function which is a SlackBot.js method to post a message to a channel In this function, we pass the channel name we want to post to, the message in a string and the params variable we declared earlier for the emoji. I used the #random channel and sentGet inspired while working with @inspirenuggets
to it. Your app should restart automatically and your bot should do this:
Cool right? You can also post messages to users and groups.
// define existing username instead of 'user_name'
bot.postMessageToUser('user_name', 'Hello world!', params);
// define private group instead of 'private_group', where bot exist
bot.postMessageToGroup('private_group', 'Hello world!', params);
Error Handler
Let’s also write a function to check for errors and return them:
bot.on('error', (err) => {
console.log(err);
})
Message Handler
Now let’s build the main bot functionality.
Like I said earlier, we’ll be using the quotes JSON from the extension I built as our quotes API. The JSON can be found with this URL: https://raw.githubusercontent.com/BolajiAyodeji/inspireNuggets/master/src/quotes.json
When a user mentions our bot and adds inspire me, the bot returns a random quote from inspireNuggets, when the user types random joke, it returns a random joke from Chuck Norris API and when the user types help, it returns the instruction guide.
First, let’s check for our command words from the user message (inspire me, random joke and help)
function handleMessage(message) {
if(message.includes(' inspire me')) {
inspireMe()
} else if(message.includes(' random joke')) {
randomJoke()
} else if(message.includes(' help')) {
runHelp()
}
}
Now let’s create the three function we need
- inspireMe()
Our demo JSON is not really an API, it’s just some JSON I used in the Chrome Extension, we’re only accessing it from GitHub raw contents, you can use any API you prefer, you’ll just have to iterate differently to get your data depending if your API returns an array or object, whichever it returns, it’s not a big deal.
Check out my previous articles on:
- Manipulating Arrays in JavaScript and
- Iterating through JavaScript Objects - 5 Techniques and Performance Tests.
function inspireMe() {
axios.get('https://raw.githubusercontent.com/BolajiAyodeji/inspireNuggets/master/src/quotes.json')
.then(res => {
const quotes = res.data;
const random = Math.floor(Math.random() * quotes.length);
const quote = quotes[random].quote
const author = quotes[random].author
const params = {
icon_emoji: ':male-technologist:'
}
bot.postMessageToChannel(
'random',
`:zap: ${quote} - *${author}*`,
params
);
})
}
We just used Axios to get the JSON file which returns some data:
[
{
"number": "1",
"author": "Von R. Glitschka",
"quote": "The client may be king, but he's not the art director."
},
{
"number": "2",
"author": "Frank Capra",
"quote": "A hunch is creativity trying to tell you something."
},
.
.
.
.
]
This JSON currently contains 210 quotes and I update them frequently. So we want to get a random quote plus the author name every time the user request for it. From our Axios response, we just do this:
const quotes = res.data;
const random = Math.floor(Math.random() * quotes.length);
const quote = quotes[random].quote
const author = quotes[random].author
And just like we did with the welcome message, we just return the quote and author instead of a string message:
`:zap: ${quote} - *${author}*`
Let’s test this
Type
@inspirenuggets inspire me
Yayyy! It worked!
PS: You can always change the emoji type for every request, if you noticed I changed the inspireMe() to
:male-technologist:
- randomJoke()
We’re getting the jokes from Chuck Norris API from this endpoint
https://api.chucknorris.io/jokes/random
.
{
"categories": [],
"created_at": "2016-05-01 10:51:41.584544",
"icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
"id": "6vUvusBeSVqdsU9C5-ZJZw",
"updated_at": "2016-05-01 10:51:41.584544",
"url": "https://api.chucknorris.io/jokes/6vUvusBeSVqdsU9C5-ZJZw",
"value": "Chuck Norris once choked a wildcat to death with his sphincter muscle."
}
This is a real API that returns a random joke on every request, so we don’t have to do Math.floor()
again.
function randomJoke() {
axios.get('https://api.chucknorris.io/jokes/random')
.then(res => {
const joke = res.data.value;
const params = {
icon_emoji: ':smile:'
}
bot.postMessageToChannel(
'random',
`:zap: ${joke}`,
params
);
})
}
By now, you should understand how this works already, make a post with the channel name, message and params.
- runHelp()
This is similar to our welcome message, we just want to return a custom text when the user adds help to the request.
function runHelp() {
const params = {
icon_emoji: ':question:'
}
bot.postMessageToChannel(
'random',
`Type *@inspirenuggets* with *inspire me* to get an inspiring techie quote, *random joke* to get a Chuck Norris random joke and *help* to get this instruction again`,
params
);
}
Now let’s test all three commands:
Everything works fine now, congratulations!!!! you just built your SlackBot.
There is an endless number of possibilities of Bots you can build with this to automate your own work or teamwork.
You can build a bot that: fetches your tasks from somewhere and reminds you when you type hey what next
, welcomes every user to your workspace (I built this during one of the HNG Internship’s), gives you football matches updates while you’re working, tell your team when you hit a milestone in number of registered users and many more…
It’s just about having somewhere to get the data from, and some basic iteration skills and the bot.postMessageToChannel()
method.
Automation is one thing we should learn as developers, we have a lot to do, we should automate the simpler one so we have time for the more tasking ones. I hope with this you can automate your tasks and I look forward to the creative ideas you’ll bring to life.
Final Code
Here’s our final index.js
What Next?
Our bot only runs in development now, to use it we always have to npm start
.
This isn’t cool, right? We’ll want to host it somewhere it can run every time. In my next article, I’ll show you how to host this on either Heroku, Zeit or Netlify and publish it to the Slack Apps store so anyone around the world can use it. Also, don’t forget to add this in your .gitignore
before pushing to GitHub
/.env
/node_modules
Subscribe to my newsletter to get updated.


Welcome to PizzaPopolis!
Where the pizza's hot, and the drinks are bottomless!
(Dine-in only)
Dine-in currently unavailable. Pick-up only. Masks and social distancing required.
Thank you for your cooperation and thinking of PizzaPopolis for your pizza needs!
$ due at pick up.
Choose your options and click the button above to add another pizza to your
order.


qualia2.rl.envs package¶
Submodules¶
qualia2.rl.envs.atari module¶
-
class
qualia2.rl.envs.atari.
BreakOut
(width=84, height=84)[source]¶ Bases:
qualia2.rl.envs.atari.AtariBase
Maximize your score in the Atari 2600 game Breakout.
Observation: Gym Default:
Type: Box(210, 160, 3) RGB image
- Transformed:
(1, 84, 84) BW image
- Actions:
Discrete(4) Num Action 0 no operation 1 fire 2 move right 3 move left
-
class
qualia2.rl.envs.atari.
BreakOutRAM
[source]¶ Bases:
qualia2.rl.envs.atari.AtariBase
Maximize your score in the Atari 2600 game Breakout.
- Observation:
Box(128,) the RAM of the Atari machine
- Actions:
Discrete(4) Num Action 0 no operation 1 fire 2 move right 3 move left
-
class
qualia2.rl.envs.atari.
Pong
(width=84, height=84)[source]¶ Bases:
qualia2.rl.envs.atari.AtariBase
Maximize your score in the Atari 2600 game Pong.
Observation: Gym Default:
Type: Box(210, 160, 3) RGB image
- Transformed:
(1, 84, 84) BW image
- Actions:
Discrete(6) Num Action 0 no operation 1 fire 2 move right 3 move left 4 RIGHTFIRE 5 RIGHTFIRE
-
class
qualia2.rl.envs.atari.
PongRAM
[source]¶ Bases:
qualia2.rl.envs.atari.AtariBase
Pong
Maximize your score in the Atari 2600 game Pong.
- Observation:
Box(128,) the RAM of the Atari machine
- Actions:
Discrete(6) Num Action 0 no operation 1 fire 2 move right 3 move left 4 RIGHTFIRE 5 RIGHTFIRE
qualia2.rl.envs.box2d module¶
-
class
qualia2.rl.envs.box2d.
BipedalWalker
[source]¶ Bases:
qualia2.rl.core.Env
Get a 2D biped walker to walk through rough terrain. Observation:
Type: Box(24) Num Observation Min Max Mean 0 hull_angle 0 2*pi 0.5 1 hull_angularVelocity -inf +inf - 2 vel_x -1 +1 - 3 vel_y -1 +1 - 4 hip_joint_1_angle -inf +inf - 5 hip_joint_1_speed -inf +inf - 6 knee_joint_1_angle -inf +inf - 7 knee_joint_1_speed -inf +inf - 8 leg_1_ground_contact_flag 0 1 - 9 hip_joint_2_angle -inf +inf - 10 hip_joint_2_speed -inf +inf - 11 knee_joint_2_angle -inf +inf - 12 knee_joint_2_speed -inf +inf - 13 leg_2_ground_contact_flag 0 1 - 14-23 10 lidar readings -inf +inf -
- Actions:
Type: Box(4) - Torque control(default) Num Name Min Max 0 Hip_1 (Torque / Velocity) -1 +1 1 Knee_1 (Torque / Velocity) -1 +1 2 Hip_2 (Torque / Velocity) -1 +1 3 Knee_2 (Torque / Velocity) -1 +1
- Rewards:
Reward is given for moving forward, total 300+ points up to the far end. If the robot falls, it gets -100. Applying motor torque costs a small amount of points, more optimal agent will get better score.
- Reference:
-
class
qualia2.rl.envs.box2d.
BipedalWalkerHardcore
[source]¶ Bases:
qualia2.rl.core.Env
BipedalWalker
Get a 2D biped walker to walk through rough terrain. Observation:
Type: Box(24) Num Observation Min Max Mean 0 hull_angle 0 2*pi 0.5 1 hull_angularVelocity -inf +inf - 2 vel_x -1 +1 - 3 vel_y -1 +1 - 4 hip_joint_1_angle -inf +inf - 5 hip_joint_1_speed -inf +inf - 6 knee_joint_1_angle -inf +inf - 7 knee_joint_1_speed -inf +inf - 8 leg_1_ground_contact_flag 0 1 - 9 hip_joint_2_angle -inf +inf - 10 hip_joint_2_speed -inf +inf - 11 knee_joint_2_angle -inf +inf - 12 knee_joint_2_speed -inf +inf - 13 leg_2_ground_contact_flag 0 1 - 14-23 10 lidar readings -inf +inf -
- Actions:
Type: Box(4) - Torque control(default) Num Name Min Max 0 Hip_1 (Torque / Velocity) -1 +1 1 Knee_1 (Torque / Velocity) -1 +1 2 Hip_2 (Torque / Velocity) -1 +1 3 Knee_2 (Torque / Velocity) -1 +1
- Rewards:
Reward is given for moving forward, total 300+ points up to the far end. If the robot falls, it gets -100. Applying motor torque costs a small amount of points, more optimal agent will get better score.
- Reference:
-
class
qualia2.rl.envs.box2d.
CarRacing
[source]¶ Bases:
qualia2.rl.core.Env
- Observation:
Type: Box(96,96,3)
qualia2.rl.envs.classic_control module¶
-
class
qualia2.rl.envs.classic_control.
Acrobot
[source]¶ Bases:
qualia2.rl.core.Env
The acrobot system includes two joints and two links, where the joint between the two links is actuated.
-
class
qualia2.rl.envs.classic_control.
CartPole
[source]¶ Bases:
qualia2.rl.core.Env
A pole is attached by an un-actuated joint to a cart, which moves along a frictionless track. The pendulum starts upright, and the goal is to prevent it from falling over by increasing and reducing the cart’s velocity.
- Observation:
Type: Box(4) Num Observation Min Max 0 Cart Position -4.8 4.8 1 Cart Velocity -Inf Inf 2 Pole Angle -24 deg 24 deg 3 Pole Velocity At Tip -Inf Inf
- Actions:
Type: Discrete(2) Num Action 0 Push cart to the left 1 Push cart to the right
- Reward:
0 for each step -1 if terminate condition meet before max_steps-5 1 if terminate condition meet after max_steps-5 (Note: original reward with the gym environment is not used)
- Reference:
-
class
qualia2.rl.envs.classic_control.
MountainCar
[source]¶ Bases:
qualia2.rl.core.Env
Get an under powered car to the top of a hill (top = 0.5 position)
- Observation:
Type: Box(2) Num Observation Min Max 0 position -1.2 0.6 1 velocity -0.07 0.07
- Actions:
Type: Discrete(3) Num Action 0 push left 1 no push 2 push right
- Reward:
-1 for each step
- Reference:
-
class
qualia2.rl.envs.classic_control.
MountainCarContinuous
[source]¶ Bases:
qualia2.rl.core.Env
MountainCar
Get an under powered car to the top of a hill (top = 0.5 position)
- Observation:
Type: Box(2) Num Observation Min Max 0 position -1.2 0.6 1 velocity -0.07 0.07
- Actions:
Type: Box(1) Num Action 0 Push car to the left (negative value) or to the right (positive value)
- Reward:
Reward is 100 for reaching the target of the hill on the right hand side, minus the squared sum of actions from start to goal.
- Reference:
-
class
qualia2.rl.envs.classic_control.
Pendulum
[source]¶ Bases:
qualia2.rl.core.Env
Try to keep a frictionless pendulum standing up.
- Observation:
Type: Box(3) Num Observation Min Max 0 cos(theta) -1.0 1.0 1 sin(theta) -1.0 1.0 2 theta dot -8.0 8.0
- Actions:
Type: Box(1) Num Action Min Max 0 Joint effort -2.0 2.0
- Reward:
The precise equation for reward: -(theta^2 + 0.1*theta_dt^2 + 0.001*action^2) Theta is normalized between -pi and pi. Therefore, the lowest cost is -(pi^2 + 0.1*8^2 + 0.001*2^2) = -16.2736044, and the highest cost is 0. In essence, the goal is to remain at zero angle (vertical), with the least rotational velocity, and the least effort.
- Starting State:
Random angle from -pi to pi, and random velocity between -1 and 1
qualia2.rl.envs.roboschool module¶
-
class
qualia2.rl.envs.roboschool.
RoboschoolAnt
[source]¶ Bases:
qualia2.rl.envs.roboschool.RoboSchoolBase
- Observation:
Type: Box(28,)
- Actions:
Type: Box(8,)
-
class
qualia2.rl.envs.roboschool.
RoboschoolHalfCheetah
[source]¶ Bases:
qualia2.rl.envs.roboschool.RoboSchoolBase
- Observation:
Type: Box(26,)
- Actions:
Type: Box(6,)
-
class
qualia2.rl.envs.roboschool.
RoboschoolHopper
[source]¶ Bases:
qualia2.rl.envs.roboschool.RoboSchoolBase
RoboschoolHumanoid
- Observation:
Type: Box(15,)
- Actions:
Type: Box(3,)
-
class
qualia2.rl.envs.roboschool.
RoboschoolHumanoid
[source]¶ Bases:
qualia2.rl.envs.roboschool.RoboSchoolBase
- Observation:
Type: Box(44,)
- Actions:
Type: Box(17,)
-
class
qualia2.rl.envs.roboschool.
RoboschoolWalker2d
[source]¶ Bases:
qualia2.rl.envs.roboschool.RoboSchoolBase
RoboschoolHumanoid
- Observation:
Type: Box(22,)
- Actions:
Type: Box(6,)
qualia2.rl.envs.toy_text module¶
-
class
qualia2.rl.envs.toy_text.
FrozenLake
[source]¶ Bases:
qualia2.rl.core.Env
The agent controls the movement of a character in a grid world. Some tiles of the grid are walkable, and others lead to the agent falling into the water. Additionally, the movement direction of the agent is uncertain and only partially depends on the chosen direction. The agent is rewarded for finding a walkable path to a goal tile.
SFFF (S: starting point, safe) FHFH (F: frozen surface, safe) FFFH (H: hole, fall to your doom) HFFG (G: goal, where the frisbee is located)
-
class
qualia2.rl.envs.toy_text.
FrozenLake8x8
[source]¶ Bases:
qualia2.rl.core.Env
The agent controls the movement of a character in a grid world. Some tiles of the grid are walkable, and others lead to the agent falling into the water. Additionally, the movement direction of the agent is uncertain and only partially depends on the chosen direction. The agent is rewarded for finding a walkable path to a goal tile.
SFFF (S: starting point, safe) FHFH (F: frozen surface, safe) FFFH (H: hole, fall to your doom) HFFG (G: goal, where the frisbee is located)


STEP 1. Select the type of activity you require.
Break Down Regular Expression to FSA
Convert NFA To Regular Expression
Convert NFA To DFA
Create Automaton


§664-5 No patent on award until boundaries settled. The department of land and natural resources is forbidden to issue any patent in confirmation of an award by name, made by the commissioners to quiet land titles, without the boundaries being defined in such patent, according to the decision of a commissioner of boundaries, or the intermediate appellate court, or the supreme court on appeal. [L 1894-5, c 14, §7; RL 1925, §556; RL 1935, §3664; RL 1945, §10205; RL 1955, §234-5; am L Sp 1959 2d, c 1, §21; am L 1961, c 132, §1; HRS §664-5; am L 2004, c 202, §73; am L 2006, c 94, §1; am L 2010, c 109, §1]
Cross References
See Appendix to Revised Laws of Hawaii 1925, pp 2120-2152.
Case Notes
Awards by metes and bounds. 30 H. 666 (1928).
Decree. 31 H. 118 (1929).
Cited: 49 H. 456, 486-7, 421 P.2d 550 (1966).


Elections seen as vote on pro-democracy protests underway in Hong Kong
A strong showing by the opposition would show that the public still supports the pro-democracy movement, even as the protests have become increasingly violent
by AP | PTIVoting was underway Sunday in Hong Kong elections that have become a barometer of public support for anti-government protests now in their sixth month.
Long lines formed outside polling stations for 452 seats in the city's 18 district councils. The councils are largely advisory and have little power. But the election has taken on symbolic importance in the semi-autonomous Chinese territory.
A strong showing by the opposition would show that the public still supports the pro-democracy movement, even as the protests have become increasingly violent.
The ruling camp in Hong Kong and the national government in Beijing hope that the unrest and disruption to daily life will turn voters against the movement.
Voters queue at a polling station during district council local elections in Hong Kong, China November 24, 2019. REUTERS/Adnan Abidi
There has been a rare break in the violence in recent days as protesters, anxious to validate their cause through the ballot box, hit the pause button to ensure the polls won't be postponed.
We need to show the world that our cause is legitimate. I don't believe that Beijing will not respond to the Hong Kong people's voice, a black-clad and masked student Alex Wong said during a peaceful march Saturday.
Hong Kong Chief Secretary Matthew Cheung said that the vote is a real democratic exercise, and that a strong police presence at polling stations will ensure that it proceeds smoothly.
Online messages from protest support groups have advised people not to wear black or face masks during voting in case they are targeted by police.


网络
{foreach $link as $key => $value}
{/foreach}
颜色
{foreach $color as $key=>$value}
{/foreach}
配置
{foreach $configure as $key => $value}
{/foreach}
容量
{foreach $size as $key=> $value}
{/foreach}


Background
The world of IT is vast and varied, and there are many possible career paths in it. Which one of these is right for you? That can be a very difficult question to answer. This assignment is intended to be a first step in the process for you.
A natural starting place is to ask why you have chosen to study this course at RMIT. There must be some reason why you are interested in IT, or you wouldn't have made it this far! What makes IT interesting for you? What lead you to study at RMIT? What do you hope to do after graduation? This assignment will require you to think about questions like these, and answer them as best you can. This information will be used in later assignments to assist you to form a group, and to plan an IT project with your group.
In order to help you develop a practical skill, you are to present your Assignment 1 information on a website, which you will set up via GitHub Pages or Amazon Web Services (AWS). You will be shown how to do this in the tutorial class in Week 3.
Overview
● This assignment is worth 10% of your overall mark.
● This is an individual assignment.
● You can seek feedback on your assignment from your tutor at any point during tutorials. You are strongly encouraged to work on this assignment regularly each week, therefore you should be writing relevant parts of your report each week.
● The Turnitin tool will be used on all submissions.
● Your information is to be presented on a website. You will be shown how to set up an appropriate website in one of the tutorials.
● This assignment should be submitted via Canvas. You should submit a short PDF document containing the link to your website.
Requirements
Your website should contain 5 sections, with the titles below.
1. Personal Information
2. Interest in IT
3. Ideal Job
4. Personal Profile
5. Project ideas
More details on each of these are given below.
Personal Information
Include your name, student number, email address, and some basic background information (nationality and culture, education to date, languages spoken etc). Include at least one fact about yourself that others may find interesting, such as a hobby, a pet or your favourite sport or other pastime.
Interest in IT
You should answer the questions below as best you can. Each answer should be one paragraph in length.
● What is your interest in IT? When did your interest in IT start? Was there a particular event or person that sparked your interest? Outline your IT experience (if any).
● Why did you choose to come to RMIT?
● What do you expect to learn during your studies?
Ideal Job
Find an advertisement showing what you believe to be your ideal job. This may require several years of experience, and hence be something that you have to work towards, rather than something that you are ready for now, or will be able to fill as soon as you graduate. There are various ways to search for IT jobs, including websites like \url{seek.com.au}. You should include the following information.
● The job advertisement itself. Include a link, and a snapshot of it (in case the link expires before the assignment deadline).
● A description (in your own words) of the position, and particularly what makes this position appealing to you.
● A description (in your own words) of the skills, qualifications and experience required for the position.
● A description (in your own words) of the skills, qualifications and experience you currently have.
● A plan describing how you will obtain the skills, qualifications and experience required for the position, building on those you have now. This need not be greatly detailed, (and will probably change significantly over time anyway), but try to be as specific as you can.
Personal Profile
There are a number of online tests that are commonly used by employers to get specific information about potential employees. One of the best-known of these is the Myers-Briggs Type Indicator (MBTI) test, which was developed by the mother-and-daughter team of Isabel Myers and Katharine Briggs. Another popular one (and very relevant to students) is about learning styles. There are various other tests available online as well, and while there is no guarantee that any specific test will be necessarily one that you will encounter in your career, it seems highly likely that you will have to do some kind of test like this as part of a recruitment process. Accordingly, you are required to present the following information
● The results of an online Myers-Briggs test.
● The results of an online learning style test.
● The results of one further online test of your choosing.
The third test should be distinct from both the Myers-Briggs test and the learning styles test. This could be a Big Five Personality test, a creativity test, or a psychometric test. You should be able to find something free, and please ensure that it is something that a potential employer may find relevant (so please avoid things like a Nerdy Personality Attribute assessment or a Generic Conspiracist Beliefs test!).
In addition to the results themselves, you should answer each of the questions below with one paragraph.
● What do the results of these tests mean for you?
● How do you think these results may influence your behaviour in a team?
● How should you take this into account when forming a team?
Project ideas
You are to write a report of around 1000 words describing your project idea. You should describe the project itself, as well as why you think it is important or interesting, and any potential drawbacks or obstacles you anticipate. What are you passionate about? What kind of IT innovation would you like to see? What project will help you develop the skills, experience and knowledge required to make you qualified for your ideal job?
You need not have full answers to any of these questions, but you are required to have some ideas about an IT project that you think will address at least one of these questions. It may not be possible to find one that answers all three, but it is quite likely that something you would find interesting or useful will have a similar effect on others. There are a number of possible types of projects that you may consider. Some potential ideas are below; others will be discussed in class.
● Developing a game using tools such as Unity, Construct2 or Cocos2d.
● Developing a smartphone app, using whatever programming language in which you have expertise, or by using tools such as MIT App Inventor.
● Finding an innovative application for new hardware developments, such as Raspberry Pis, Arduinos, Makey Makeys, small robots or related technologies.
● Creating a FAQ and implementing it as a chatterbot, possibly involving speech-to-text and text-to-speech software.
● Building an electronic artefact such as a model for Minecraft or similar games, along the lines of the United Nations Block by Block project.
For this assignment, you need to write approximately 1,000 words about your project idea. This should not only describe what the project would be, but also why you think it is important or interesting, and what potential drawbacks or obstacles you anticipate. Your description should include the following sections. The word counts below are recommendations only.
Overview (100 words) This should be a summary of what the project will be.
Motivation (100) words) This should be a description of why the project will be interesting or useful. This may include statistics or other evidence, such as ``There are 1.5 billion cat owners in Australia, and so there is a huge market for an automated cat feeder. Using Raspberry Pi technology is a cheap and easily assembled solution to this problem.''
Description (500 words) Detailed description of the features of the product or service.
Tools and Technologies (100) words) Describe the software, hardware and/or other
equipment needed. Include any relevant open source tools as appropriate.Skills Required (100 words) List the skills are required for your project, including software that needs to be written, and special hardware (if any). How feasible will it be to find the skills, software and hardware required?
Outcome (100 words) If the project is successful, what will be the outcome? How will the original problem be solved? What impact will this development have?


Playing Audio
Before playing audio you must first load a track. You do this by clicking on an entry in the track list. Once loaded the track will have a darker background in the track list and the track name will also be in the description box as shown here:
Once a track is loaded all the information is placed in the interface. This may take a short while depending on the size of the track.
A track will always play from its cue position. This position is specified by the lower arrow on the Track Controller. Hovering over the arrow changes the pointer to a slider symbol and the cue position can be altered by clicking and dragging:
The Cue Position will reset to the beginning when a track is loaded for the first time. Once set, the cue position is remembered until the track is removed from the list or the list is reloaded.
To mark where the lyrics of a track start, or any other place of interest you can use the upper arrow on the Track Controller to set a position at which the introduction of a track ends:
After setting introduction positions they are stored until you delete the track from your track list. Introduction positions for (L)ibrary tracks are stored to the Music Library and will be set when you or anyone else next loads the Music Library track.
The black arrow is a marker for the current position in the loaded track. You can click and drag it at any point whether the audio is playing or not. There may be a small delay between moving the slider and the audio responding but it is not anticipated that the slider will need to be moved often.
Along the central black line are visual cues as to how long the track is the larger of the markers being 1 minute markers and the smaller being 10 second markers
Here is the Track Controller with all its elements described:
You can control playback via the mouse or via the keyboard. The 'F' keys control playback from the keyboard as indicated on the interface. The 'F' keys will control baps regardless of which baps window is in focus. However, if no baps window has focus the 'F' keys will NOT work. The buttons change colour to indicate what is currently happening:
Playing a track when a track is playing is not possible
Pausing a track when a track is playing will stop the audio playing and keep its position where it is
Stopping a track when a track is playing will stop the audio playing and return the position to the Cue Position
Playing a track when a track is paused will restart the track from the Cue Position
(Un)Pausing a track when a track is paused will start the audio playing from its current position
Stopping a track when a track is paused will return the position to the Cue Position
Playing a track when a track is stopped will start the track from the Cue Position
Pausing a track when a track is stopped will set the state to paused and keep the position where it is
Stopping a track when a track is stopped will return the position to the Cue Position
Right clicking on a Track List will open the option menu for the channel:
When active an option has a tick next to it.
When active automatic advance will cause the channel to automatically move on to the next playable entry in the track list and load it as soon as a track finishes playing.
When active play on load causes tracks to immediately play when they are selected. If both automatic advance and play on load are active it has the effect of automatically playing all tracks in a track list (from the one you select to load) until the end of the list is reached.
Setting repeat to anything other than repeat none will override the above options.
When repeat one is active this will cause a track to repeat forever once you have started it playing
When repeat all is active this will cause all tracks in the list to be played over and over once you start any track playing
Selecting audiowall for a particular channel will open a window full of buttons. Each button refers to an item in the tracklist you opened the audiowall from. The buttons are ordered from left to right, top to bottom and show the first 20 entries in the list. Clicking once on a button will immediately load and play the audio from its cue position. The track list entry which is currently loaded will be highlighted in red.


Scale 0.5 to 1
Scale 2 and Scroll
Scale 2 to 1 and Scroll
Scale 0.5 and Scroll
Scale 0.5 and Console result


GA4GH reference server {{ info.version }}
Operations available
Method
Path
{% for rule in info.urls %}
{{ rule[1] }}
{{ rule[0] }}
{% endfor %}
Uptime
Running since {{ info.uptime.natural }} ({{ info.uptime.datetime }})


|
| |
| #define | spi_master_type0 SPI_MASTER_NATIVE_TYPE |
| spi_master derived type connections | |
|
| |
| #define | spi_device_type0 SPI_DEVICE_NATIVE_TYPE |
| spi_device derived type connections |
| #define spi_device_type0 SPI_DEVICE_NATIVE_TYPE |
spi_device derived type connections
| #define spi_master_type0 SPI_MASTER_NATIVE_TYPE |
spi_master derived type connections


Current
Professional
Experience
source: http://tjvantoll.com/2014/12/29/so-you-want-to-write-a-tech-book/Minneapolis, MN
Used by many major companies including:
https://grails.org/download.html
sdk install grails 3.0.17
| javascript | - Dynamic behavior in the browser |
| servlets | - HTML page generation |
| controllers | - Application Form Controllers + Tests |
| command | - Display objects + Tests |
| validation | - Validation and constraints + Tests |
| services | - Service Layer + Tests |
| queries | - Data access + Tests |
| domain | - Domain Model + Tests |
| DDL | - Database Schema |
grails create-app questionApp
cd questionApp
grails create-domain-class com.example.Question
package com.example
class Question {
String question
String answer
String userName
static constraints = {
}
}
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(Question)
class QuestionSpec extends Specification {
def setup() {
}
def cleanup() {
}
void "test something"() {
expect:"fix me"
true == false
}
}
grails clean
grails run-app
grails test-app
grails help
grails help 'target-name'
grails
grails generate-all com.example.Question
grails-app/controllers/com/example/QuestionController.groovy
grails-app/views/question
src/test/groovy/com/example/QuestionControllerSpec.groovy
| index | -Displays list of objects, default for / |
| show | - Shows one object for a given index |
| create | - Displays form to create new object |
| save | - Saves new object |
| edit | - Shows edit form |
| update | - Updates existing object |
| delete | - Deletes one object |
grails run-app
| Running Grails application
| Server running. Browse to http://localhost:8080
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond Question.list(params), model:[questionCount: Question.count()]
}
Add to the QuestionController
def hello() {
render "I am here!"
}
http://localhost:8080/question/hello
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
}
"/showQuestions" (controller: "question", action: "index")
http://localhost:8080/showQuestions
Better in recent versions, but still needs to happen occassionally
grails run-app
Go to /question/searchByUsername
def searchByUsername() {
def questionInstanceList = Question.findAllByUsername('doug')
respond questionInstanceList, model: [questionInstanceCount: Question.count()]
}
| In List | - in the list of given values |
| LessThan | - less than a given value |
| LessThanEquals | - less than or equal a give value |
| GreaterThan | - greater than a given value |
| GreaterThanEquals | - greater than or equal a given value |
| Like | - equivalent to a SQL like expression |
| Ilike | - case insensitive version of like |
| NotEqual | - negates equality |
| InRange | - between the values of a Groovy Range |
| Rlike | - performs a Regexp LIKE in MySQL or Oracle otherwise falls back to Like |
| Between | - between two values (requires two arguments) |
| IsNotNull | - not a null value (no arguments) |
| IsNull | - is a null value (no arguments) |
grails> console
import com.example.Question
Question q1 = new Question()
Question q2 = new Question(
question: 'What?',
answer: 'Me worry.',
userName: 'doug'
)
q1.save()
q2.save()
Question.findAll()
jenn@gr8ladies.org