| fct_shift {forcats} | R Documentation |
This is useful when the levels of an ordered factor are actually cyclical, with different conventions on the starting point.
fct_shift(f, n = 1L)
f |
A factor. |
n |
Positive values shift to the left; negative values shift to the right. |
x <- factor( c("Mon", "Tue", "Wed"), levels = c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"), ordered = TRUE ) x fct_shift(x) fct_shift(x, 2) fct_shift(x, -1)


Primary pyral classes and functions¶
For the most part, you’ll only be utilizing two main entry points to the pyral package.
The first is the rallySettings convenience function that you’ll use to obtain target and credential values. If you are using 1.1.x or beyond, you may want to alternatively use the rallyWorkset convenience function to obtain target and credential values if you intend to use a Rally API Key for credentials. The second is the Rally class, from which you’ll obtain an instance and then treat that as a direct link to the Rally SaaS. An instance of the Rally class has the basic four CRUD operations as well as several convenience methods to obtain information about workspaces, projects, users and Rally type/value metadata.
You’ll also be using the results of queries issued to Rally that are returned as instances of the RallyRESTResponse class. Instances of this class allow easy dot (‘.’) notation access to attributes of the representation of the Rally entity, whether the attribute is a simple value or a reference to another Rally entity.
rallyWorkset¶
New in 1.1.0.
This function takes into account your environment and arguments provided to this function to arrive at and return information necessary to establish a useful connection to the Rally server. This convenience function differs from rallySettings by also including the Rally API Key in the set of values considered and returned.
The process consists of a priority chain where some reasonable default information is established first and then overridden with subsequent steps in the chain (if they exist). After following the priority chain, values for server, user, password, apikey, workspace, project are returned to the caller.
- The priority chain consists of these steps:
establish baseline values from values defined in the module containing the rallyWorkset
- override with any environment variables present from this list:
- RALLY_SERVER
- RALLY_USER
- RALLY_PASSWORD
- APIKEY
- RALLY_WORKSPACE
- RALLY_PROJECT
- RALLY_PING
if present, use information from a rally-<version>.cfg file in the current directory, where <version> matches the Rally WSAPI version defined in the pyral.config module. Currently, that version is defined as v2.0.
if present, use the contents of a file named in the RALLY_CONFIG environment variable.
if present, use the contents of a config named on the command line via the –config-<filename> option
if present, use the values of individual credential/target settings provided as command line options via the –<option>=<value>.
The specific syntax available for these levels is detailed below.
Files
- The general syntax is:
- CAP_NAME = value
- Valid entries are:
- SERVER = <RallyServer>
- USER = <validUserName>
- PASSWORD = <validPassword>
- APIKEY = <validAPIKey>
- WORKSPACE = <validWorkspaceName>
- PROJECT = <validProjectName>
- RALLY_PING = True | False
Command line options
–rallyConfig=<configFileName>or –config=<configFileName>
or –conf=<configFileName>
or –cfg=<configFileName>
—rallyServer=<serverName>
–rallyUser=<validRallyUserName>
—rallyPassword=<validRallyPassword>
–apikey=<validRallyAPIKeyValue>
—workspace=<validWorkspaceName>
–project=<validProjectName>
—ping=True|False|true|false|yes|no|1|0
This mechanism provides the ability to centrally locate a configuration file that can be used by many members of a team where server, workspace, project are common to all members and each individual can have their own appropriately secured config file with their credentials. Using this mechanism can save tedious and error-prone entry of target information and credentials on the command line or having credential information in clear text in unsecured files.
The use of a Rally API Key value for identification/authentication is new in pyral 1.1.x. If used, you do not need to provide a username / password combination. In order to use this, you must first obtain a valid API Key value from the Rally Application Manager (API Keys) that you can access from https://rally1.rallydev.com/login. Once obtained, you should treat the key with the same level of protection as you would any user/password information; once presented to Rally via the Rally Web Services API, a connection has all the rights associated with the user whose key was presented. Consult the Rally help documentation for further information.
Example use:
% export RALLY_SERVER="rally1.rallydev.com"
% export<EMAIL_ADDRESS>% ls -l current.cfg
-rw------- 1 wiley eng 173 Jul 14 07:02 current.cfg
% cat current.cfg
USER =<EMAIL_ADDRESS>WORKSPACE = General Products Umbrella
PROJECT = Dairy Farm Automation
% cat basic.py
import sys
from rally import rallyWorkset
options = [opt for opt in sys.argv[1:] if opt.startswith('--')]
server, user, password, apikey, workspace, project = rallyWorkset(options)
print " ".join(['|%|' % opt for opt in [server, user, password, apikey, workspace, project]]
% python basic.py --config=current --rallyProject="Livestock Mgmt" --ping=yes
|rally1.rallydev.com|<EMAIL_ADDRESS>|*****| |*****| |General Products Umbrella| |Livestock Mgmt|
Note that for convenience purposes a configuration file name may be fully specified or you may elect to not specify the ‘.cfg’ suffix.
Returns a tuple of (server, username, password, apikey, workspace, project)
rallySettings¶
This is deprecated as of v1.2.0. The preferred function is rallyWorkset which will have ongoing support. The rallySettings function will be removed in v2.0.0.
This function takes into account your environment and arguments provided to this function to arrive at and return information necessary to establish a useful connection to the Rally server.
The process consists of a priority chain where some reasonable default information is established first and then overridden with subsequent steps in the chain (if they exist). After following the priority chain, values for server, user, password, workspace, project are returned to the caller.
- The priority chain consists of these steps:
establish baseline values from values defined in the module containing the rallySettings
- override with any environment variables present from this list:
- RALLY_SERVER
- RALLY_USER
- RALLY_PASSWORD
- RALLY_WORKSPACE
- RALLY_PROJECT
if present, use information from a rally-<version>.cfg file in the current directory, where <version> matches the Rally WSAPI version defined in the pyral.config module. Currently, that version is defined as v2.0.
if present, use the contents of a file named in the RALLY_CONFIG environment variable.
if present, use the contents of a config named on the command line via the –config-<filename> option
if present, use the values of individual credential/target settings provided as command line options via the –<option>=<value>.
The specific syntax available for these levels is detailed below.
Files
- The general syntax is:
- CAP_NAME = value
- Valid entries are:
- SERVER = <RallyServer>
- USER = <validUserName>
- PASSWORD = <validPassword>
- APIKEY = <validAPIKey>
- WORKSPACE = <validWorkspaceName>
- PROJECT = <validProjectName>
Command line options
–rallyConfig=<configFileName>or –config=<configFileName>
or –conf=<configFileName>
or –cfg=<configFileName>
—rallyServer=<serverName>
–rallyUser=<validRallyUserName>
—rallyPassword=<validRallyPassword>
–apikey=<validRallyAPIKeyValue>
—workspace=<validWorkspaceName>
–project=<validProjectName>
This mechanism provides the ability to centrally locate a configuration file that can be used by many members of a team where server, workspace, project are common to all members and each individual can have their own appropriately secured config file with their credentials. Using this mechanism can save tedious and error-prone entry of target information and credentials on the command line or having credential information in clear text in unsecured files.
The use of a Rally API Key value for identification/authentication is new in pyral 1.1.x. If used, you do not need to provide a username / password combination. In order to use this, you must first obtain a valid API Key value from the Rally Application Manager (API Keys) that you can access from https://rally1.rallydev.com/login. Once obtained, you should treat the key with the same level of protection as you would any user/password information; once presented to Rally via the Rally Web Services API, a connection has all the rights associated with the user whose key was presented. Consult the Rally help documentation for further information.
Example use:
% export RALLY_SERVER="rally1.rallydev.com"
% export<EMAIL_ADDRESS>% ls -l current.cfg
-rw------- 1 wiley eng 173 Jul 14 07:02 current.cfg
% cat current.cfg
USER =<EMAIL_ADDRESS>WORKSPACE = General Products Umbrella
PROJECT = Dairy Farm Automation
% cat basic.py
import sys
from rally import rallyWorkset
options = [opt for opt in sys.argv[1:] if opt.startswith('--')]
server, user, password, apikey, workspace, project = rallyWorkset(options)
print " ".join(['|%|' % opt for opt in [server, user, password, apikey, workspace, project]]
% python basic.py --config=current --rallyProject="Livestock Mgmt"
|rally1.rallydev.com|<EMAIL_ADDRESS>|*****| |*****| |General Products Umbrella| |Livestock Mgmt|
Note that for convenience purposes a configuration file name may be fully specified or you may elect to not specify the ‘.cfg’ suffix.
Returns a tuple of (server, username, password, apikey, workspace, project)
Rally¶
The Rally class is the central focus of the pyral package. Instantiation of this class with appropriate and valid target/credential information then provides a means of interacting with the Rally server.
- To instantiate a Rally object, you’ll need to provide these arguments:
- server usually rally1.rallydev.com unless you are using an OnPrem version
- user AgileCentral UserName
- password AgileCentral password for the given user
either in this specific order or as keyword arguments.
You must either have default workspace and project values set up for your account
OR
you must provide workspace and project values that are valid and accessible for your account.
- You can optionally specify the following as keyword arguments:
apikey (alternate credential specification)
workspace (name of the AgileCentral workspace)
project (name of the AgileCentral project)
verify_ssl_cert (True or False, default is True)
- warn (True or False, default is True)
Controls whether a warning is issued if no project is specified and the default project for the user is not in the workspace specified. Under those conditions, the project is changed to the first project (alphabetic ordering) in the list of projects for the specified workspace.
- server_ping (True or False, default in v1.3.0 + is False)
Specifies whether a ping attempt will be made to confirm network connectivity to the Rally server prior to making a Rally WSAPI REST request. Organizations may have disabled the ability to make ICMP requests so the ping attempt may fail even though there is network connectivity to the Rally server. For this reason, the use of the ping=True option is discouraged going forward. The ping operation itself will be dropped in the next major release (2.0.0).
- isolated_workspace (True or False, default in v1.2.0 + is False)
Specifies that the Rally instance will only be used for interacting with a single workspace (either the user’s default workspace or the named workspace). Using isolated_workspace=True provides performance benefits for a subscription with many workspaces, but it also means you cannot change the workspace you are working within a single instance of a Rally class, nor can you provide a workspace keyword argument to the get, create, update or delete methods that differs from the workspace identified at instantiation time. For subscriptions with a small to moderate number of workspaces (up to a few dozen), the performance savings will be relatively minor when using isolated_workspace=True vs. isolated_workspace=False. However, for subscriptions with a large number of workspaces, using isolated_workspace=False results in a request to AgileCentral for each workspace, which can result in a noticeable lag before the instantiation statement returns a ready-for-use Rally instance.
headers dict with entries for name, vendor, version of software/integration using this package.
If you use an apikey value, any user name and password you provide is not considered, the connection attempt will only use the apikey. Consult the Rally Help documentation for Rally Application Manager for information on how to generate an API Key and how to reset or delete an API Key.
Note
If your Subscription administrator has set up your Rally Subscription as “SSO only”, then to use pyral, you must have your account added to the whitelist in Rally so that you can use either BasicAuth (username and password) or the API Key to authenticate to Rally.
Note
As of the 1.2.2 release, pyral offers a means of precisely identifying a Project whose name appears in multiple locations within the forest of Projects with a Workspace. For example, your organization may have several “base” level Projects with sub-trees of Projects. In this scenario, you might have multiple Projects named ‘AgileTeam-X’ or ‘SalesPrep’. By using a Project path component separator of ‘ // ‘ (<space><slash><slash><space>) you can specify the unambiguous and unique path to the specific Project of interest. Example: Omnibus // Metallic // Conductive // Copper // Wire . You only have to use this syntax to specify a particular Project if you have multiple instances of that Project that have the same name. There is no provision for supporting the scenario where a Project of the same name exists in the same structural location.
-
class
Rally
(server, user=None, password=None, apikey=None, workspace=None, project=None, warn=True, server_ping=False)¶
Examples:
rally = Rally('rally1.rallydev.com'<EMAIL_ADDRESS>'bAbYF@cerZ', server_ping=True)
rally = Rally(server='rally1.rallydev.com', user='mchunko', password='mySEk^et')
rally = Rally(server, user, password, workspace='Division #1 Products', project='ABC')
rally = Rally(server, user, password, workspace='Brontoville', verify_ssl_cert=False, warn=False)
rally = Rally(server, apikey="_some-more-numbers", workspace='RockLobster', project='Fence Posts')
rally = Rally('rally1.rallydev.com'<EMAIL_ADDRESS>'bAbYF@cerZ', headers={'name': 'Fungibles Goods Burn Up/Down', 'vendor': 'Archimedes', 'version': '1.2.3'})
Core REST methods and CRUD aliases¶
-
put
(entityName, itemData, workspace=None, project=None)¶ This method allows for the creation of a single Rally entity for the given entityName. The data is supplied in a dict and must include settings for all required fields. An attempt to create an entity record for which the operational credentials do not include the privileges to create Rally entity entries will result in a RallyRESTException being generated.
Returns a representation of the item as an instance of a class named for the entity.
-
create
()¶ alias for put
-
get
(entityName, fetch=False | True | comma_separated_list_of_fields, query=None, order=None, **kwargs)¶ This method allows for the retrieval of records for the given entityName. A fetch value of False results in a “shell” record returned with only basic ref attributes having values. If the fetch value is True, a fully hydrated record for each qualifying entity is returned. If the fetch value is a string with a list of comma separated attribute names, those name attributes will be members of each returned entity record.
- keyword arguments:
- fetch = True/False or “List,Of,Attributes,We,Are,Interested,In”
- query = ‘FieldName = “some value”’ or [‘EstimatedHours = 10’, ‘MiddleName != “Shamu”’, ‘Name contains “foogelhorn pop-tarts”’, etc.]
- instance = True/False (defaults to False)
- pagesize = n (defaults to 500)
- start = n (defaults to 1)
- limit = n (defaults to no limit)
- workspace = workspace_name (defaults to current workspace selected)
- project = project_name (defaults to current project selected)
- projectScopeUp = True/False (defaults to False)
- projectScopeDown True/False (defaults to False)
- threads = n (value of 1 insures single-threading, any other value is advisory)
Returns a RallyRESTResponse object that has errors and warnings attributes that should be checked before any further operations on the object are attempted. The Response object supports the iteration protocol so that the results of the
get
can be iterated over via eitherfor rec in response:
orresponse.next()
.If the instance keyword value is True, then an instance of a Rally entity will be returned instead of a RallyRESTResponse. This can be useful when retrieving an item you know exists and is uniquely identified by your query argument.
The query keyword argument can consist of a String, a List of Strings as <name> <relation> <value> conditions or as a Dictionary where the key-value pairs have an implicit equality relationship and all the resulting conditions are AND’ed together.
Note
If you use a simple query, eg., ‘SomeField = “Abc”’ then _you_ don’t need to use parens (although the Rally REST API does...). If you specify the conditions as in the list variation (see the second example in the query keyword explanation above), then the conditions are AND’ed together in a form suitable for consumption by the Rally REST API.
Caution: If there are any paren characters in a query string, then the toolkit takes a hands-off policy and lets you take the responsibility for specifying the query in a form suitable for the Rally REST WSAPI. (See the Help page for for the Rally REST WSAPI in the Rally web-based product).
If you need to have any OR’ing of conditions, you’ll have to construct the entire query yourself in the form of a single String with paren characters in the correct locations to make the query syntactically conformant with the Rally REST WSAPI. Example: query=((Name contains “ABC”) OR ((Priority = “1-Critical”) AND (Severity != “3-Minor”))) Yes, it’s kind of a pain in the ...
Using the characters of ‘~‘ or ‘&‘ or ‘|‘ or a backslash ‘\‘ within a query expression (eg. ‘Name contains “|”’) are problematic with the use of this toolkit. A REST request will be issued, but even if there are actual qualifying items that you could observe by using the Rally web GUI, the Rally WSAPI response will not have the correct count or content of the qualifying items. Other workarounds are recommended to deal with this; one way is to post-process the results of a less restrictive criteria to filter or qualify the results to your specific criteria.
Use the instance keyword with caution, as an exception will be generated if the query produces no qualifying results. If the query produces more than one qualifying result, you’ll only get get the first result with no means to obtain any further qualifying items.
-
find
()¶ alias for get
-
post
(entityName, itemData, workspace=None, project=None)¶ This method allows for updating a single Rally entity record with the data contained in the itemData dict. The itemData dict must include a key-value pair for either the ObjectID or when applicable, the FormattedID, that will uniquely identify the entity to be updated. The itemData dict may not attempt to change the ObjectID value of the entity as the value for the ObjectID is used to identify the Rally entity to update. An attempt to update an entity record for which the operational credentials do not include the privileges to update will result in a RallyRESTException being generated.
Returns a representation of the updated item as an instance of a class named for the entity.
-
update
()¶ alias for post
-
delete
(entityName, itemIdent, workspace=None, project=None)¶ This method allows for deleting a single Rally entity record whose ObjectID (or FormattedID) must be present in the itemIdent parameter. An attempt to delete an entity record for which the operational credentials do not include the privileges to delete will result in the generation of a RallyRESTException.
Returns a boolean indication of the disposition of the attempt to delete the item.
-
search
(keywords, **kwargs)¶ Given a list of keywords or a string with space separated words, issue the relevant Rally WSAPI search request to find artifacts within the search scope that have any of the keywords in any of the artifact’s text fields.
NOTE: The search functionality must be turned on for your subscription to use this method.
- keyword arguments:
- projectScopeUp = true/false (defaults to false)
- projectScopeDown = true/false (defaults to false)
- pagesize = n (defaults to 500)
- start = n (defaults to 1)
- limit = n (defaults to no limit)
pyral.Rally instance convenience methods¶
-
enableLogging
(dest=sys.stdout, attrget=False, append=False)¶ Use this to enable logging. dest can set to the name of a file or an open file/stream (writable). If attrget is set to True, all Rally REST requests that are executed to obtain attribute information will also be logged. Be careful with that as the volume can get quite large. The append parameter controls whether any existing file will be appended to or overwritten.
-
disableLogging
()¶ Disables logging to whatever destination has been previously set up.
-
subscriptionName
()¶ Returns the name of the subscription for the credentials used to establish the connection with Rally.
-
setWorkspace
(workspaceName)¶ Given a workspaceName, set that as the current workspace and use the ref for that workspace in subsequent interactions with Rally.
-
getWorkspace
()¶ Returns an instance of a Workspace entity with information about the workspace in the currently active context.
-
getWorkspaces
()¶ Return a list of Workspace instances that are available for the credentials used to establish the connection with Rally.
-
setProject
(projectName)¶ Given a projectName, set that as the current project and use the ref for that project in subsequent interractions with Rally.
-
getProject
(name=None)¶ Returns a minimally hydrated Project entity instance with the Name and ref of the project in the currently active context if the name keyword arg is not supplied or the Name and ref of the project identified by the value of the name parameter as long as the name identifies a valid project in the currently selected workspace. Returns None if a name parameter is supplied that does not identify a valid project in the currently selected workspace.
-
getProjects
(workspace=None)¶ Return a list of Project instances that are available for the workspace context identified by the workspace keyword argument. If no workspace keyword argument is supplied (or is supplied as None), then the workspace context is that of the currently selected workspace.
-
getUserInfo
(oid=None, username=None, name=None)¶ A convenience method to collect the information associated with a specific user.
Caller must provide at least one keyword arg and non-None / non-empty value to identify the user target on which to obtain information. The name keyword arg is associated with the User.DisplayName attribute. The username keyword arg is associated with the User.UserName attribute. If provided, the oid keyword argument is used, even if other keyword args are provided. Similarly, if the username keyword arg is provided it is used even if the name keyword argument is provided.
Returns either a single instance of a User entity when the oid keyword argument matches a User in the system, or a list of User entity items when the username or name keywords are given and are matched by at least one User in the system. Returns None if there is no match in the Rally subscription/workspace for the keyword argument used to identify the user target.
-
getAllUsers
(workspace=None)¶ This method offers a convenient one-stop means of obtaining usable information about all users in the named workspace. If no workspace is specified, then the current context’s workspace is used. NOTE: Unless you are using credentials associated with a SubscriptionAdministrator or WorkspaceAdministrator, you will not be able to access a user’s UserProfile other than yourself.
Return a list of User instances (fully hydrated for scalar attributes) whose ref and collection attributes will be lazy eval’ed upon access.
-
typedef
(entityName)¶ This method returns a TypeDefinition instance for the given entityName. The is handy for occasions where you need identify a specific entity for something like ‘Feature’ or ‘Theme’ when creating or updating a PortfolioItem subclass. Intended usage is to use the return .ref attribute. For example, within an info dict, “PortfolioItemType” : rally.typedef(‘Feature’).ref .
-
getCollection
(collection_url)¶ Given a collection_url of the form:
http(s)://<server>(:<port>)/slm/webservice/v2.0/<entity>/OID/<attribute>issue a request for the url and return back a list of hydrated instances for each item in the collection.
-
getState
(entityName, stateName)¶ As of Rally WSAPI 1.37 (Sep 2012), the State attribute is no longer a String value for many entities, it is itself an entity (aka Rally Type). To be able to create (or update) an Artifact’s State attribute, you must provide a reference (_ref or ref) in the information dictionary used to populate the Artifact’s attributes. This method provides an easy means of obtaining the appropriate entity for the particular entity and state Name you want. Typically the usage would be along the lines of this example:
info = { ...., "State" : rally.getState('Feature', 'Discovering').ref, ... })
Warning
This method only works with PortfolioItem subclasses at this time. (Theme, Strategy, Initiative, Feature)
-
getStates
(entityName)¶ Given an entityName, returns a list of State instances populated with information about each state value permitted for the entityName.
-
getAllowedValues
(entityName, attributeName[, workspace=None])¶ Given an entityName and and attributeName (which must be valid for the entityName) issue a request to obtain a list of allowed values for the attribute. For standard attributes in the set of (‘Artifacts’, ‘Attachments’, ‘Changesets’, ‘Children’, ‘Collaborators’, ‘Defects’, ‘DefectSuites’, ‘Discussion’, ‘Duplicates’, ‘Milestones’, ‘Iteration’, ‘Release’, ‘Project’, ‘Owner’, ‘SubmittedBy’, ‘Predecessors’, ‘Successors’, ‘Tasks’, ‘TestCases’, ‘TestSets’, ‘Results’, ‘Steps’, ‘Tags’) this method will return a [True] value if the entity identified by entityName actually has the attributeName specified. To get the values associated with the attributes in the aforementioned list you should use the get() method with the entityName as the first argument and the singular form of the attribute name as the target of the fetch keyword argument. Of course, this only works with an entity that exists (such as ‘Attachment’ or ‘Milestone’ or ‘Tag’) but not entities named above like ‘Discussion’, or ‘SubmittedBy’ or ‘Result’. For custom fields though there is no such “disqualification”, that is the return value will be either a single value or a list of values regardless of whether the values are relevant to every such entity type or the values are a list that can vary per specific instance of the entity type.
-
addAttachment
(artifact, filename, mime_type='text/plain')¶ Given an artifact (actual or FormattedID for an artifact), validate that it exists and then attempt to add an Attachment with the name and contents of filename into Rally and associate that Attachment with the Artifact. Returns the Attachment item.
-
addAttachments
(artifact, attachments)¶ Given an artifact (either actual or FormattedID) and a list of dicts with each dict having keys and values for name (or Name), mime_type (or MimeType) and content_type (or ContentType), add an Attachment corresponding to each dict in the attachments list and associate it with the referenced Artifact.
-
getAttachment
(artifact, filename)¶ Given a real artifact instance or the FormattedID of an existing artifact, obtain the attachment named by filename. If there is such an attachment, return an Attachment instance with hydration for Name, Size, ContentType, Content, CreationDate and the User that supplied the attachment. If no such attachment is present, return None
-
getAttachmentNames
(artifact)¶ Given a real artifact instance that is hydrated for at least the Attachments attribute, return the names (filenames) of the Attachments associated with the artifact.
-
getAttachments
(artifact)¶ Given a real artifact instance, return a list of Attachment records. Each Attachment record will look like a Rally WSAPI Attachment with the additional Content attribute that will contain the decoded AttachmentContent.
-
rankAbove
(reference_artifact, target_artifact)¶ Rank the target_artifact above the reference_artifact.
-
rankBelow
(reference_artifact, target_artifact)¶ Rank the target_artifact below the reference_artifact.
-
rankTop
(target_artifact)¶ Rank the target_artifact at the top of the list of ranked Artifacts that the target_artifact exists in.
-
rankBottom
(target_artifact)¶ Rank the target_artifact at the bottom of the list of ranked Artifacts that the target_artifact exists in.
pyral.Rally experimental convenience methods¶
-
addCollectionItems
(target_item, collection_items)¶ Given a target_item and a homogenous list of items whose type appears as a One to Many relationship in the target item, add the collection_items to the corresponding attribute in the target_item.
...
milestones = [milestone_1, milestone_2, milestone_3]
story = rally.get('story', 'US123')
rally.addCollectionItems(story, milestones)
Warning
This method only works when the collection attribute on the target_item is Modifiable. Consult the AgileCentral WSAPI documentation for the target_item attributes to see whether the attribute of interest has a notation of ‘Collection Modifiable yes’. If there is no ‘Colletion Modifiable’ notation or the value for that is ‘no’, then use of this method should not be attempted. At this time, the AgileCentral WSAPI schema endpoint does not include information about ‘Collection Modifiable’ for any of the attributes, you’ll have to consult the documentation.
-
dropCollectionItems
(target_item, collection_items)¶ Given a target_item and a homogenous list of items whose type appears as a One to Many relationship in the target item, delete the collection_items to the corresponding attribute in the target_item from the current collection contents for the target_item.
Warning
See note above for the ‘addCollectionItems’ method. The restrictions there are also applicable to this method.
RallyRESTResponse¶
A RallyRESTResponse instance is returned from a call to get
(find) and several of the
convenience methods. A instance has the following useful state attributes:
- resource = partial URL identifying the resource for the HTTP Request
- status_code = numeric code for the HTTP Response
- headers = HTTP headers returned
- content = a dict produced by JSON’ifying the HTTP response body
- errors = a list of strings with any Error information
- warnings = a list of strings with any Warning information
- startIndex = natural number index (ie., 1 to _X_)
- pageSize = chunk size returned
- resultCount = total number of items in the set meeting the selection criteria
In addition and usually more importantly, a RallyRESTResponse instance can be used as an iterator over the results.
There are two common means of exercising the iterative nature of the reponse. Use a for loop to obtain each item (you can use this in a list comprehension also) or use the next method to obtain the next item in the qualifying result set.
Examples:
# regular for loop
response = rally.get('Defect', query=..., ...)
for item in response: print item
# in a list comprehension
response = rally.get('UserStory', query=..., ...)
story_titles = [story.Name for story in response]
# using the next method
response = rally.get('Task', query=..., ...)
task1 = response.next()
-
class
RallyRESTResponse
¶
-
next
()¶ Returns the next item from the set of qualifying items. This method handles any further requests to the server if the next qualifying item is not in the current page of results returned from Rally. If all qualifying items have been returned via this method, this method generates a StopIteration exception.
Item Attributes¶
Item instances returned from iterating on a RallyRESTResponse object are representations of Rally items. The attributes of each item are accessible via the standard dot (.) notation. The names are identical to those documented in the Rally WS API.
Generally, every concrete instance in the Rally system will have a Name attribute. You can use the attributes() method on an instance to obtain the names of all of the attributes available on your specific instance.
So, to obtain the name of a TestCase if you have a TestCase instance, you use testcase.Name, to obtain the formatted ID of a story, use story.FormattedID.
There are two special attributes, oid and ref that are convenient meta-attributes provided with every instance. The oid attribute is an alias for ObjectID and the ref attribute is the portion of the _ref attribute containing the entity name and ObjectID value. The ref attribute is suitable for use whenever you want/need to specify the value of a reference field.
Attributes that are classified as references (as opposed to a simple string or integer value) can be accessed and attributes on the referenced item can be obtained. A UserStory (alias for HierarchicalRequirement) can have a parent story. To obtain the parent’s FormattedID attribute value, you’d specify thusly: story.Parent.FormattedID.
An attribute can also be a collection. For example, Tasks associated with a UserStory. To access these tasks, you’d iterate over them as in:
response = rally.get('UserStory', fetch=True, query='State != "Closed"')
if not response.errors:
for story in response:
for task in story.Tasks:
print task.oid, task.Name, task.ActualHours
-
details
()¶ This convenience method is available on all WorkspaceDomain subclass instances and provides an organized and easy to read multiline string with the content of the instance.
Example:
response = rally.get('UserStory', fetch=True, query='FormattedID = S321')
story1 = response.next()
print story1.details()
HierarchicalRequirement
oid : 12345678
ref : hierarchicalrequirement/12345678
ObjectID : 12345678
_ref : https://rallydev.rallydev.com/slm/webservice/v2.0/hierarchicalrequirement/412345678
_CreatedAt : today at 3:14 am
_hydrated : True
Name : Filbert nuts should be added to all energy bars
Subscription : Subscription.ref (OID 400060 Name: Company 1)
Workspace : Workspace.ref (OID 722746 Name: Prime Cuts Workspace)
FormattedID : S321
AcceptedDate : None
AccountingProjec : None
AccountingTask : None
AffectedCustomer :
Attachments : []
Blocked : False
Blocker : None
Capitalizable : None
Changesets : []
Children : []
CreationDate : 2016-07-12T09:14:35.852Z
DefectStatus : NONE
Defects : []
Description : As a health conscious PO, I want better nutritional content in all bars
Discussion : []
IdeaURL : <pyral.entity.CustomField object at 0x101931290>
IdeaVotes : None
InProgressDate : 2016-07-12T09:14:36.098Z
Iteration : Iteration.ref (OID 1242381 Name Iteration 5 (Summer))
KanbanState : Accepted
LastUpdateDate : 2016-07-12T09:14:36.237Z
...


|
Package mail_cram Package to allow to authenticate to a CRAM SMTP server DisclaimerBased on a blog by Sean Stuber: http://www.experts-exchange.com/Database/Oracle/A_5915-Extending-Oracle%27s-Email-functionality-with-PL-SQL-Authentication.html |
| Program units |
| authenticate | Method to authenticate with a CRAM SMTP server like Exchange |
| Constants |
| c_hash_md5 | |
| c_hash_sha1 |
c_hash_md5
c_hash_md5 constant varchar2(20) := 'CRAM-MD5';
c_hash_sha1
c_hash_sha1 constant varchar2(20) := 'CRAM-SHA1';
authenticate
Procedure authenticate(p_conn in out nocopy utl_SMTP.connection, p_hash_method in varchar2, p_user_name in varchar2, p_password in varchar2)
Method to authenticate with a CRAM SMTP server like Exchange
| Usage |
|
Procedure will authenticate p_conn with the credentials provided and return the connection |
| Parameters |
| p_conn |
Parameter for the actual SMTP-connection | |
| p_hash_method |
One of the package constants to identify the authentication method | |
| p_user_name |
Name of the user to authenticate | |
| p_password |
Authentication users password |


Hi, I am Shantanu Thakar, working as a Research assistant in the Aerospace Department at the Indian institute of Science, Bangalore. I have completed my Bachelor and master degree in Mechanical Engineering from the Indian Institute of Technology Bombay, India. I have a keen interest in the fields of Robotics, motion planning and navigation.


The back to top button is useful on long pages to go quickly go back to the top of the page. It will only appear after a predetermined offset value has been met. Scroll to the bottom of this page to see an example.
Oh I know its not the right time tonight
But I won’t move until this stops
We go back to the top
Oh oh
Back to the top!
You will never belong to me
Now I can see the light – that you are
Never good at controlling me
Now I can see the light shine oh
And I know
And I know
It was blinding you
Say life can be long
Wanna know
Wanna know
Wanna know
Wanna know
It's truev
When you say
You gotta make me believe you
Oh I know its not the right time tonight
But I won’t move until this stops
We go back to the top
Oh oh
Back to the top!
I’m not scared if you run to me
Lost like when you were mine
And you can take what you want from me
Just offer me your time
Stay, life can be long
Wanna know
Wanna know
Wanna know
Wanna know
It’s true
When you say
I want you around
You gotta make me believe you
Oh I know it’s not the right time tonight
But I won’t move until this stops
We go back to the top
Oh oh
Back to the top!
Oh I know it’s not the right time tonight
But I won’t move until this stops
We go back to the top
Oh oh
Back to the top!
Oh I know it’s not the right time tonight
But I won’t move until this stops
We go back to the top
Oh oh
Back to the top!
| Attr | Type | Default | Details |
|---|---|---|---|
| data-offset | Number |
300 |
The height in pixels, measured from the top, when the button will be visible. |


A loader for `glTF 2.0` resources.
[link:https://www.khronos.org/gltf glTF] (GL Transmission Format) is an
[link:https://github.com/KhronosGroup/glTF/tree/master/specification/2.0 open format specification]
for efficient delivery and loading of 3D content. Assets may be provided either in JSON (.gltf)
or binary (.glb) format. External files store textures (.jpg, .png) and additional binary
data (.bin). A glTF asset may deliver one or more scenes, including meshes, materials,
textures, skins, skeletons, morph targets, animations, lights, and/or cameras.
[name] uses [page:ImageBitmapLoader] whenever possible. Be advised that image bitmaps are not automatically GC-collected when they are no longer referenced, and they require special handling during the disposal process. More information in the [link:https://threejs.org/docs/#manual/en/introduction/How-to-dispose-of-objects How to dispose of objects] guide.
[name] is an add-on, and must be imported explicitly. See [link:#manual/introduction/Installation Installation / Addons].
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
GLTFLoader supports the following [link:https://github.com/KhronosGroup/glTF/tree/master/extensions/ glTF 2.0 extensions]:
The following glTF 2.0 extension is supported by an external user plugin
2You can also manually process the extension after loading in your application. See [link:https://threejs.org/examples/#webgl_loader_gltf_variants Three.js glTF materials variants example].
// Instantiate a loader
const loader = new GLTFLoader();
// Optional: Provide a DRACOLoader instance to decode compressed mesh data
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( '/examples/jsm/libs/draco/' );
loader.setDRACOLoader( dracoLoader );
// Load a glTF resource
loader.load(
// resource URL
'models/gltf/duck/duck.gltf',
// called when the resource is loaded
function ( gltf ) {
scene.add( gltf.scene );
gltf.animations; // Array<THREE.AnimationClip>
gltf.scene; // THREE.Group
gltf.scenes; // Array<THREE.Group>
gltf.cameras; // Array<THREE.Camera>
gltf.asset; // Object
},
// called while loading is progressing
function ( xhr ) {
console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
},
// called when loading has errors
function ( error ) {
console.log( 'An error happened' );
}
);
[example:webgl_loader_gltf]
Textures containing color information (.map, .emissiveMap, and .specularMap) always use sRGB colorspace in glTF, while vertex colors and material properties (.color, .emissive, .specular) use linear colorspace. In a typical rendering workflow, textures are converted to linear colorspace by the renderer, lighting calculations are made, then final output is converted back to sRGB and displayed on screen. Unless you need post-processing in linear colorspace, always configure [page:WebGLRenderer] as follows when using glTF:
renderer.outputColorSpace = THREE.SRGBColorSpace;
GLTFLoader will automatically configure textures referenced from a .gltf or .glb file correctly, with the assumption that the renderer is set up as shown above. When loading textures externally (e.g., using [page:TextureLoader]) and applying them to a glTF model, colorspace and orientation must be given:
// If texture is used for color information, set colorspace.
texture.colorSpace = THREE.SRGBColorSpace;
// UVs use the convention that (0, 0) corresponds to the upper left corner of a texture.
texture.flipY = false;
Metadata from unknown extensions is preserved as “.userData.gltfExtensions” on Object3D, Scene, and Material instances, or attached to the response “gltf” object. Example:
loader.load('foo.gltf', function ( gltf ) {
const scene = gltf.scene;
const mesh = scene.children[ 3 ];
const fooExtension = mesh.userData.gltfExtensions.EXT_foo;
gltf.parser.getDependency( 'bufferView', fooExtension.bufferView )
.then( function ( fooBuffer ) { ... } );
} );
[page:LoadingManager manager] — The [page:LoadingManager loadingManager] for the loader to use. Default is [page:LoadingManager THREE.DefaultLoadingManager].
Creates a new [name].
See the base [page:Loader] class for common properties.
See the base [page:Loader] class for common methods.
[page:String url] — A string containing the path/URL of the `.gltf` or `.glb` file.
[page:Function onLoad] — A function to be called after the loading is successfully completed. The function receives the loaded JSON response returned from [page:Function parse].
[page:Function onProgress] — (optional) A function to be called while the loading is in progress. The argument will be the XMLHttpRequest instance, that contains .[page:Integer total] and .[page:Integer loaded] bytes. If the server does not set the Content-Length header; .[page:Integer total] will be 0.
[page:Function onError] — (optional) A function to be called if an error occurs during loading. The function receives error as an argument.
Begin loading from url and call the callback function with the parsed response content.
[page:DRACOLoader dracoLoader] — Instance of THREE.DRACOLoader, to be used for decoding assets compressed with the KHR_draco_mesh_compression extension.
Refer to this [link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/libs/draco#readme readme] for the details of Draco and its decoder.
[page:KTX2Loader ktx2Loader] — Instance of THREE.KTX2Loader, to be used for loading KTX2 compressed textures.
[page:ArrayBuffer data] — glTF asset to parse, as an `ArrayBuffer`, `JSON` string or object.
[page:String path] — The base path from which to find subsequent glTF resources such as textures and .bin data files.
[page:Function onLoad] — A function to be called when parse completes.
[page:Function onError] — (optional) A function to be called if an error occurs during parsing. The function receives error as an argument.
Parse a glTF-based `ArrayBuffer`, `JSON` string or object and fire [page:Function onLoad] callback when complete. The argument to [page:Function onLoad] will be an [page:Object] that contains loaded parts: .[page:Group scene], .[page:Array scenes], .[page:Array cameras], .[page:Array animations], and .[page:Object asset].
[link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/GLTFLoader.js examples/jsm/loaders/GLTFLoader.js]


--- layout: post title: Bru date: '2015-05-12T19:30:30+02:00' categories: - Storyboards picture_url: https://film-Storyboards.tumblr.com/post/118822029546 ---


--- layout: page title: Lean Prover Zulip Chat Archive permalink: archive/198800BigProof2019/07259lunch.html ---
Are there people around Pollocks hall of residence who want to have lunch before going to ICMS ?
I'm working right now in the lounge area of the hotel near the reception desk. Happy to go for a light lunch before things start up.
{% endraw %}


You do not have 'monkey_team.middleware.MonkeyTeamMiddleware' in setting's MIDDLEWARE_CLASSES !
{% endif %}
Install the userscript from here.
Dependencies
- Firefox: Install greasemonkey.
- Google Chrome: Download the userscript and then drag and drop it in the extensions tab. Walkthrough here.
{% if warn_debug %}


Please sign in
Sign in URL
Email address
Password
Remember me
Sign in
×
Holy guacamole!
You should check in on some of those fields below.


This is an
example
And this is the second paragraph
Numero de clicks en esta pagina
0
Change First Paragraph
Change all paragraphs
Change with HTML
Change with text


Notional Amount
Escrow Amount
Maturity Date
Rate Type
Select
Fixed to Variable
Variable to Fixed
Submit


My Team
Abdulhakeem Manager
Manager
ID: 1
Email:
<EMAIL_ADDRESS>Office number:<PHONE_NUMBER>
Abdulhakeem Engineer
Engineer
ID: 2
Email:
<EMAIL_ADDRESS>GitHub:
<EMAIL_ADDRESS>Engineer 2
Engineer
ID: 4
Email:
<EMAIL_ADDRESS>GitHub:
<EMAIL_ADDRESS>Abdulhakeem Intern
Intern
ID: 3
Email:
<EMAIL_ADDRESS>School: UW Bootcamp


Hello world ES5
Welcome to Javascript !
For full functionality of this site it is necessary to enable JavaScript. Here are the
instructions how to enable JavaScript in your web browser
.


Source code for gameanalysis.fixedpoint
"""Module for finding fixed points of functions on a simplex"""
import numpy as np
from gameanalysis import utils
[docs]def fixed_point(func, init, **kwargs):
"""Compute an approximate fixed point of a function
Parameters
----------
func : ndarray -> ndarray
A continuous function mapping from the d-simplex to itself.
init : ndarray
An initial guess for the fixed point. Since many may exist, the choice
of starting point will affect the solution.
kwargs : options
Additional options to pass on to labeled_subsimplex. See other options
for details.
"""
def fixed_func(mix):
"""Labeling function for a fixed point"""
return np.argmin((mix == 0) - mix + func(mix))
return labeled_subsimplex(fixed_func, init, **kwargs)
[docs]def labeled_subsimplex(
label_func, init, disc
): # pylint: disable=too-many-locals,too-many-statements
"""Find approximate center of a fully labeled subsimplex
This runs once at the discretization provided. It is recommended that this
be run several times with successively finer discretization and warm
started with the past result.
Parameters
----------
label_func : ndarray -> int
A proper lableing function. A labeling function takes an element of the
d-simplex and returns a label in [0, d). It is proper if the label
always coresponds to a dimension in support.
init : ndarray
An initial guess for where the fully labeled element might be. This
will be projected onto the simplex if it is not already.
disc : int
The discretization to use. Fixed points will be approximated by the
reciprocal this much.
Returns
-------
ret : ndarray
A discretized simplex with 1 coarser resolution (i.e. ret.sum() + 1 ==
init.sum()) that is fully labeled.
Notes
-----
This is an implementation of the sandwhich method from [5]_ and [6]_
.. [5] Kuhn and Mackinnon 1975. Sandwich Method for Finding Fixed Points.
.. [6] Kuhn 1968. Simplicial Approximation Of Fixed Points.
"""
init = np.asarray(init, float)
dim = init.size
# Base vertex of the subsimplex currently being used
dinit = _discretize_mixture(init, disc)
base = np.append(dinit, 0)
base[0] += 1
# permutation array of [1,dim] where v0 = base,
# v{i+1} = [..., vi_{perms[i] - 1} - 1, vi_{perms[i]} + 1, ...]
perms = np.arange(1, dim + 1)
# Array of labels for each vertex
labels = np.arange(dim + 1)
labels[dim] = label_func(dinit / disc)
# Vertex used to label initial vertices (vertex[-1] == 0)
label_vertex = base[:-1].copy()
# Last index moved
index = dim
# Most recent created index, should be set to
new_vertex = None
while labels[index] < dim:
# Find duplicate index. this is O(dim) but not a bottleneck
(dup_labels,) = np.nonzero(labels == labels[index])
(index,) = dup_labels[dup_labels != index]
# Flip simplex over at index
if index == 0:
base[perms[0]] += 1
base[perms[0] - 1] -= 1
perms = np.roll(perms, -1)
labels = np.roll(labels, -1)
index = dim
elif index == dim:
base[perms[-1] - 1] += 1
base[perms[-1]] -= 1
perms = np.roll(perms, 1)
labels = np.roll(labels, 1)
index = 0
else: # 0 < index < dim
perms[index - 1], perms[index] = perms[index], perms[index - 1]
# Compute actual value of flipped vertex
new_vertex = base.copy()
new_vertex[perms[:index]] += 1
new_vertex[perms[:index] - 1] -= 1
utils.check(
np.all(new_vertex >= 0) and new_vertex.sum() == disc + 1,
"vertex rotation failed, check labeling function",
)
# Update label of new vertex
if new_vertex[-1] == 2:
labels[index] = dim
elif new_vertex[-1] == 0:
labels[index] = np.argmax(new_vertex[:-1] - label_vertex)
else: # == 1
labels[index] = label_func(new_vertex[:-1] / disc)
utils.check(
0 <= labels[index] < dim and new_vertex[labels[index]],
"labeling function was not proper (see help)",
)
# Average out all vertices in simplex we care about
current = base
if index == 0: # pragma: no cover
count = 0
mean = np.zeros(dim)
else: # pragma: no cover
count = 1
mean = current.astype(float)
for i, j in enumerate(perms, 1):
current[j] += 1
current[j - 1] -= 1
if i != index:
count += 1
mean += (current - mean) / count
return mean[:-1] / disc
def _discretize_mixture(mix, k):
"""Discretize a mixture
The returned value will have all integer components that sum to k, with the
minimum error. Thus, discretizing the mixture.
"""
disc = np.floor(mix * k).astype(int)
inds = np.argsort(disc - mix * k)[: k - disc.sum()]
disc[inds] += 1
return disc


Simple Dice Roller Game
Simple About Me Page
First Version of Map Mania Game
Final Version of Map Mania Game
First Version of Mustang Lite
Second Version of Mustang Lite
Final Version of Mustang Lite
Final Project Web App to view Overwatch Esports scores, mathces, players, and discussion posts.


Gluipertje 2B2T queue proxy
Place in queue:
None
ETA:
None
Time started queueing:
-
Start queuing
Restart the queue if you're not connected at the end of it? (Recommended: ON)


Home
(current)
About
Contact
GitFind...
Perfect Place To Fetch Github Profile Data
Search User Profile
Search Github Users


Workshops
I have (co-)organized the following non-academic workshops in the adaptive media transport and streaming domain. These workshops brought engineers, researchers and service/content/OTT providers together. Follow the links for workshop agendas/presentations.
- ACM Mile High Video, 2023 (link)
- ACM Mile High Video, 2022 (link)
- Mile High Video, 2020 (link)
- Mile High Video, 2019 (link)
- Mile High Video, 2018 (link)
- 5th Workshop on Adaptive Media Transport, 2015 (agenda)
- 4th Workshop on Adaptive Media Transport, 2014 (agenda)
- 3rd Workshop on Adaptive Media Transport, 2012 (agenda)
- 2nd Workshop on Adaptive Video Streaming over IP Networks, 2010
- 1st Workshop on Video Distribution over IP Networks, 2008


A curious observer of the world. I'm always on the hunt to learn more about people, places, and things.
Find Out MoreA fast-paced multidisciplinary engineer seeking out opportunities in the intersection of engineering, design, and information sciences to make meaningful impacts on the world.
I've worked in a variety of industries ranging from Biotech to Hightech. I love the creative challenges of commercializing new technologies and realizing product-market fit. I also love to build and make things.
Currently I'm working on using Design Thinking and human centered design to improve Human Machine Interaction for advanced assisted driving. I enjoy outdoor hikes and also teach a class on beer brewing and tasting at Stanford.
Get Started!Figuring out how technology can improve lives
Understanding how people interact with computers
Hacking, Making, and Building things
Spreading Knowledge to the world
This project was part of half day dive into Bootstrap and LESS. I've setup quite a few wordpress sites for hire in the the past but it's been a while since I've played around with other web development frameworks. It's forked from one of the startbootstrap.com templates, so check them out! They're pretty cool.


Introduction
Copper is a set of small Go packages that help you build APIs quickly. All of the packages are designed to work well together but are optional to use. You can start with a single package and add others as you need them.
Copper's goal is to make it easy and fast to build APIs with idiomatic Go. Copper makes full use of the already powerful Go standard library and exposes the primitives in a way where you have to write less boilerplate.
Installation
To get started, create your project directory, initialize it as a new Go module, and "go get" the Copper package.
In the project directory, create a main.go
file and start the Copper HTTP app, as shown in the example.
That's it! You are now running an HTTP server on the port 7450
. It comes with a default health endpoint on /_health
.
mkdir my-project
cd my-project
go mod init github.com/my-user/my-project
go get github.com/tusharsoni/copper
package main
import (
"github.com/tusharsoni/copper"
"github.com/tusharsoni/copper/clogger"
)
func main() {
params := copper.HTTPAppParams{
Logger: clogger.NewStdLogger(),
}
copper.RunHTTPApp(params)
}
curl -i :7450/_health
>>HTTP/1.1 200 OK
>>Date: Wed, 26 Aug 2020 23:01:09 GMT
>>Content-Length: 2
>>Content-Type: text/plain; charset=utf-8
>>
>>OK
Directory Structure
Copper has no requirement on the directory structure - you are free to organize your project however you like. This guide provides a recommendation that works best for this type of project.
At the top level, split your project into cmd
and pkg
. The cmd
directory contains the main files under different commands. For instance, for the API, put your main.go
file at cmd/api/main.go
.
Most of your code is put under the pkg
directory split into different modules. Think of these modules as different sections of your application logically separated. For instance, in a blogging app, you may have the posts
and comments
directories in pkg
. Avoid creating global packages for models
, handlers
, and components
.
my-project/
├── Makefile
├── cmd/api/
│ └── main.go
└── pkg/
├── module1/
│ ├── migrations.go
│ ├── models.go
│ ├── repo.go
│ ├── router.go
│ └── svc.go
└── module2/
├── migrations.go
├── models.go
├── repo.go
├── router.go
└── svc.go
Routing
Basics
The copper.HTTPAppParams
struct accepts an array of chttp.Route
. Each chttp.Route
defines its path, HTTP method, middlewares, and the handler.
The example shows how you can create a route and register it to the server. If you were to create all of your routes here, the main function will get very large very quickly. Instead, follow the examples below to create distinct routers to split your routes.
package main
import "..."
func main() {
params := copper.HTTPAppParams{
Logger: clogger.NewStdLogger(),
// This is an illustration of how routes are created.
// Refer to future examples on how best to organize these routes instead of creating them all here.
Routes: []chttp.Route{
{
Path: "/",
Methods: []string{http.MethodGet},
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World"))
}),
},
},
}
copper.RunHTTPApp(params)
}
Routers
Instead of creating all your routes in the main function, you can create routers that group these routes. You should create multiple routers for your app - one for each significant part of your app. In a blogging application, you may have a separate router for posts and comments.
A single router has multiple routes. It has a Routes()
method that returns all of the routes. For each route, a handler of type http.HandlerFunc
is created on the router. By convention, the handler method is named in the format HandleX
.
As your routers grow in complexity, the Router
struct can hold its dependencies that can be accessed from all handlers.
package main
import "..."
func main() {
// Initialize the router and pass dependencies (if any).
routerA := NewRouterA()
params := copper.HTTPAppParams{
Logger: clogger.NewStdLogger(),
// By convention, the router should have a Routes() method.
// Call it here to pass all of the routes to Copper.
Routes: routerA.Routes(),
// If you have multiple routers, you can register all of
// their routes:
// Routes: append(
// routerA.Routes(),
// routerB.Routes()...,
// ),
}
copper.RunHTTPApp(params)
}
package main
import "..."
type RouterA struct{}
func NewRouterA() *RouterA {
return &RouterA{}
}
func (ro *RouterA) Routes() []chttp.Route {
return []chttp.Route{
{
Path: "/foo",
Methods: []string{http.MethodGet},
Handler: http.HandlerFunc(ro.HandleFoo),
},
{
Path: "/bar",
Methods: []string{http.MethodGet},
Handler: http.HandlerFunc(ro.HandleBar),
},
}
}
func (ro *RouterA) HandleFoo(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, Foo"))
}
func (ro *RouterA) HandleBar(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, Bar"))
}
Path Variables & Query Parameters
You can embed variables in the URL using the {variable}
pattern that can be later accessed in your handler using mux.Vars(r)["variable"]
. These variables act as pattern matchers such that your handler will only be called if the variable exists. Additionally, you can limit the scope of this variable using regex: {id:[0-9]+}
.
For query parameters, you can use the existing methods on the request object. For instance, to fetch the "limit" parameter from the url /posts?limit=10
, you can use r.URL.Query().Get("limit")
.
package main
import "..."
type RouterA struct{}
func NewRouterA() *RouterA {
return &RouterA{}
}
func (ro *RouterA) Routes() []chttp.Route {
return []chttp.Route{
{
// Use path variables to embed resource identifiers
Path: "/api/posts/{id}",
Methods: []string{http.MethodGet},
Handler: http.HandlerFunc(ro.HandleGetPost),
},
{
Path: "/api/posts",
Methods: []string{http.MethodGet},
Handler: http.HandlerFunc(ro.HandleGetAllPosts),
},
}
}
func (ro *RouterA) HandleGetPost(w http.ResponseWriter, r *http.Request) {
// Use the mux package to get the path variable
postID := mux.Vars(r)["id"]
...
}
func (ro *RouterA) HandleGetAllPosts(w http.ResponseWriter, r *http.Request) {
// The request has the ability to parse query parameters
var (
limit = r.URL.Query().Get("limit")
offset = r.URL.Query().Get("offset")
)
...
}
Reading & Writing JSON
Copper provides utilities to easily read and respond JSON objects with less boilerplate. This is especially useful when building backend APIs. The chttp
package has a ReaderWriter
interface with a JSON implementation.
Use the JSON implementation for chttp.ReaderWriter
in your routers by adding a dependency in the router struct. The chttp.ReaderWriter
provides methods to respond as well as consume and validate JSON.
package main
import "..."
type RouterA struct {
// Add the ReaderWriter dependency to the router so
// all handlers can access it.
rw chttp.ReaderWriter
}
// The constructor for the router takes in an implementation for
// chttp.ReaderWriter such as the one provided by
// chttp.NewJSONReaderWriter()
func NewRouterA(rw chttp.ReaderWriter) *RouterA {
return &RouterA{
rw: rw,
}
}
package main
import "..."
func main() {
logger := clogger.NewStdLogger()
// Initialize the router and pass the JSON Reader Writer to it
routerA := NewRouterA(chttp.NewJSONReaderWriter(logger))
params := copper.HTTPAppParams{
Logger: logger,
Routes: routerA.Routes(),
}
copper.RunHTTPApp(params)
}
Reading JSON
The chttp.ReaderWriter
has several write methods, one for each HTTP status code. It reduces boilerplate by setting the correct status code, headers, and more. Some of the methods such as OK
or Created
take an empty interface parameter. These objects are marshaled into JSON. If they implement the json.Marshaler
interface, that will be used.
func (ro *RouterA) HandleHelloWorld(w http.ResponseWriter, r *http.Request) {
// Define the body struct with JSON tags.
// Optionally, add validation tags from github.com/asaskevich/govalidator
var body struct {
Name string `json:"name" valid:"required"`
Email string `json:"email" valid:"required,email"`
}
// rw.Read unmarshals the request body into the body struct.
// If there are any validation errors, it responds with a 400
// status code and logs the error.
if !ro.rw.Read(w, r, &body) {
return
}
...
}
Writing JSON
The chttp.ReaderWriter
has several write methods, one for each HTTP status code. It reduces boilerplate by setting the correct status code, headers, and more. Some of the methods such as OK
or Created
take an empty interface parameter. These objects are marshaled into JSON. If they implement the json.Marshaler
interface, that will be used.
type User struct {
Name string `json:"name"`
Email string `json:"email"`
}
func (ro *RouterA) HandleHelloWorld(w http.ResponseWriter, r *http.Request) {
user := ...
// The OK method will respond with a 200 status code, set the proper
// content-type header and marshal the object as JSON
ro.rw.OK(w, &user)
}
Middleware
Copper supports route-level and global middleware. A middleware is a function that takes in http.Handler
and returns another http.Handler
. This is defined as chttp.MiddlewareFunc
in the chttp
package.
The example shows how to create a middleware that logs the incoming request's path and HTTP method. This is a perfect fit for a global middleware. Copper provides a variation of this middleware in the chttp
package and registers it for you when you run the app using copper.RunHTTPApp()
.
// NewIncomingRequestLogger returns a middleware that logs each
// request using the given logger.
func NewIncomingRequestLogger(logger clogger.Logger) MiddlewareFunc {
// The given http.Handler is the "next" in chain.
// We can call the ServerHTTP method on it when ready.
return func(next http.Handler) http.Handler {
// This handler logs the incoming request's method and path.
// Then, it calls the next handler.
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
logger.WithTags(map[string]interface{}{
"method": r.Method,
"path": r.URL.Path,
}).Info("New incoming request..")
next.ServeHTTP(w, r)
})
}
}
Global Middleware
The copper.HTTPAppParams
struct accepts an array of chttp.MiddlewareFunc
. Copper registers this list globally and applies them to all routes. The example shows how you can register a middleware globally.
func main() {
...
params := copper.HTTPAppParams{
...
// Register all of the global middlewares here
GlobalMiddlewares: []chttp.MiddlewareFunc{
NewIncomingRequestLogger(logger),
},
}
...
}
Route-Level Middleware
You can register middleware on a per-route basis as well. This is done when creating a new chttp.Route
object that accepts a list of middlewares in its MiddlewareFuncs
field.
Situations such as protecting a route with authentication works better at the route-level whereas logging each request works best at the global level.
func (ro *RouterA) Routes() []chttp.Route {
return []chttp.Route{
chttp.Route{
Path: "/hello-world",
Methods: []string{http.MethodGet},
MiddlewareFuncs: []chttp.MiddlewareFunc{
// This middleware will only be applied to this route
NewIncomingRequestLogger(),
},
Handler: http.HandlerFunc(ro.HandleHelloWorld),
},
}
}
Database / SQL
Copper provides some utility wrappers around GORM to reduce boilerplate. Ultimately, it returns the *gorm.DB
object for you to use throughout your app. Refer to the GORM docs on how to use that.
For now, Copper assumes Postgres as your default database driver.
func main() {
...
// Set up the database connection. If the connection
// fails, log the error and exit.
// Re-use this connection throughout your app.
db, err := csql.NewGormDB(csql.GormDBParams{
Config: csql.Config{
...
},
Logger: logger,
})
if err != nil {
logger.Error("Failed to connect to the database", err)
return
}
postsRouter := NewPostsRouter(PostsRouterParams{
Svc: NewPostsSvc(
// Pass the database connection to your repositories
NewPostsRepo(db),
),
})
...
}
Transaction Middleware
It is often useful to wrap every HTTP request in a single database transaction. If the request succeeds, the transaction is committed, else it is rolled back. The csql
package provides DBTxnMiddleware
that does exactly this.
The example shows how to register this as a global middleware so it is applied to all of your routes.
The middleware creates a transaction and sets it in the request's context. You can use the csql.GetConn
method to fetch the active transaction in your repository layer.
params := copper.HTTPAppParams{
...
GlobalMiddlewares: []chttp.MiddlewareFunc{
csql.NewDBTxnMiddleware(db, logger),
},
}
type PostsRepo struct {
db *gorm.DB
}
func NewPostsRepo(db *gorm.DB) *PostsRepo {
return &PostsRepo{
db: db,
}
}
func (r *PostsRepo) GetPostByID(ctx context.Context, id string) (*Post, error) {
// Use the csql.GetConn method to get an active transaction from the context object (if any).
db := csql.GetConn(ctx, r.db)
...
}
Authentication
The cauth
package provides a core set of entities and business logic to manage users and sessions. In addition, it provides several extensions that provide everything you need for authentication:
-
cauth/email
-
cauth/emailotp
All of the data is backed by Postgres and works best when using the csql
package.
Session Middleware
The cauth
module provides a middleware that can be used to protect your routes. The middleware verifies that a user has a valid session. If it fails, it returns a 401 status code.
The middleware uses HTTP Basic Authentication where the username is the User UUID and the password is the session token that is returned by login endpoints.
Once the session token is verified, the user uuid is set in the request's context and your handler is called. You can retrieve the user uuid using cauth.GetCurrentUserUUID(r.Context())
.
type Router struct {
// Add the auth middleware as a dependency on the router
authMW cauth.Middleware
}
func NewRouter(authMW cauth.Middleware) *Router {
return &Router{
authMW: authMW,
}
}
func (ro *Router) Routes() []chttp.Route {
return []chttp.Route{
{
Path: "/api/protected",
Methods: []string{http.MethodGet},
Handler: http.HandlerFunc(ro.HandleProtected),
// Register the VerifySessionToken middleware on the route
MiddlewareFuncs: []chttp.MiddlewareFunc{ro.authMW.VerifySessionToken},
},
}
}
func (ro *Router) HandleProtected(w http.ResponseWriter, r *http.Request) {
// Get the current user uuid from the request context
userUUID := cauth.GetCurrentUserUUID(r.Context())
}
Email & Password
The cauth/email
package allows users to register using an email and password. The email is verified by sending a verification code to their email.
This is the list of HTTP routes made available by this package:
curl -X POST -d '{
"email"<EMAIL_ADDRESS>"password": "my-password"
}' :7450/api/auth/email/signup
curl -X POST -d '{
"email"<EMAIL_ADDRESS>"password": "my-password"
}' :7450/api/auth/email/login
curl -u user_uuid:session_token -X POST -d '{
"verification_code": "abc-123"
}' :7450/api/auth/email/verify
curl -u user_uuid:session_token \
-X POST :7450/api/auth/email/resend-verification-code
curl -X POST -d '{
"email"<EMAIL_ADDRESS>"old_password": "old-password",
"new_password": "new-password"
}' :7450/api/auth/email/change-password
curl -X POST -d '{
"email"<EMAIL_ADDRESS>}' :7450/api/auth/email/reset-password
curl -u user_uuid:session_token -X POST -d '{
"new_email"<EMAIL_ADDRESS>}' :7450/api/auth/email/change-email
import (
cauthemail "github.com/tusharsoni/copper/cauth/email"
...
)
func main() {
...
// Run database migrations for cauth & its email extension
err = cauth.RunMigrations(db)
err = cauthemail.RunMigrations(db)
// Create the core auth module
auth := cauth.NewModule(db, logger)
// Set up the email extension module
authEmail := cauthemail.NewModule(cauthemail.NewModuleParams{
Auth: auth.Svc,
Mailer: cmailer.NewLogMailer(logger),
Config: cauthemail.GetDefaultConfig(),
Logger: logger,
DB: db,
})
params := copper.HTTPAppParams{
// Register the routes for auth email
Routes: authEmail.Routes,
...
}
copper.RunHTTPApp(params)
}
Email & One-time Password
The cauth/emailotp
package allows users to register using an email and a one-time password. The one-time password is sent to the user's email on every login. Since it is fully password-less, this method is far simpler to implement and may provide better user experience in some applications.
This package provides the login and signup endpoints:
curl -X POST -d '{
"email"<EMAIL_ADDRESS>}' :7450/api/auth/email-otp/signup
curl -X POST -d '{
"email"<EMAIL_ADDRESS>"verification_code": "abc123"
}' :7450/api/auth/email-otp/login
import (
cauthemailotp "github.com/tusharsoni/copper/cauth/emailotp"
...
)
func main() {
...
// Run database migrations for cauth & its emailotp extension
err = cauth.RunMigrations(db)
err = cauthemailotp.RunMigrations(db)
// Set up the core auth module
auth := cauth.NewModule(db, logger)
// Set up the email extension module
authEmailOTP, err := cauthemailotp.NewModule(cauthemailotp.NewModuleParams{
Auth: auth.Svc,
Mailer: cmailer.NewLogMailer(logger),
Logger: logger,
Config: cauthemailotp.GetDefaultConfig(),
DB: db,
})
params := copper.HTTPAppParams{
// Register the routes for auth email otp
Routes: authEmailOTP.Routes,
...
}
copper.RunHTTPApp(params)
}
Emails
Copper provides the cmailer.Mailer
interface and a few implementations to send emails. Other packages within Copper may depend on this interface to send an email.
The example shows how to set up a mailer that simply logs each email send. This is super convenient during development, especially when you don't have your actual provider's configuration handy.
func main() {
// Create a standard logger that logs to the console
logger := clogger.NewStdLogger()
// Create a log mailer using the logger that logs each
// email send to the console. Useful during development.
mailer := cmailer.NewLogMailer(logger)
// The mailer can be used anywhere the cmailer.Mailer
// interface is required
svc := NewSvc(mailer)
}
type Svc struct {
mailer cmailer.Mailer
}
func NewSvc(mailer cmailer.Mailer) *Svc {
return &Svc{
mailer: mailer,
}
}
func (s *Svc) DoSomething(ctx context.Context) {
...
body := "This is a test email!"
err := s.mailer.Send(ctx, cmailer.SendParams{
From<EMAIL_ADDRESS>To<EMAIL_ADDRESS>Subject: "Hello There!",
PlainBody: &body,
})
}
AWS SES
Copper provides an AWS implementation for the cmailer.Mailer
interface. Use this to send emails using AWS SES.
mailer, err := cmailer.NewAWSMailer(cmailer.AWSConfig{
Region: "",
AccessKeyId: "",
SecretAccessKey: "",
})
Logger
The clogger.Logger
interface provides a way to log messages in a structured manner. It provides the ability to tag messages with additional data and a level.
The example shows how to set up a logger that logs to the console and how to log an error with a few tags of various types. The logger returned by clogger.NewStdLogger()
works well with wrapped errors such as the ones used in the cerrors
package.
// Initialize a logger that outputs to the console
logger := clogger.NewStdLogger()
p := struct{ Foo string }{
Foo: "Bar",
}
// Log an error with structured tags
logger.WithTags(map[string]interface{}{
"param1": "foo",
"param2": 100,
"param3": p,
}).Error("Failed to complete task", errors.New("test error"))
>>2020/09/01 10:51:41 [ERROR] Failed to complete task where param1=foo,param2=100,param3={Foo:Bar} because
>>> test error
Errors
The cerror
package provides an implementation of the error
interface that includes structured tags and a cause error. This allows errors to be wrapped and keep the entire stack as they are propagated through the application stack.
The example shows how an error wrapped with other errors is handled in the main
function and logged properly. The logger provided by Copper unwraps and provides the full trace for the error.
func main() {
logger := clogger.NewStdLogger()
err := DoB()
if err != nil {
// Here, we want to handle the error by logging it.
// The StdLogger will unwrap the error stack properly.
logger.WithTags(map[string]interface{}{
"param": "b",
}).Error("Failed to do B", err)
}
}
func DoB() error {
err := DoA()
if err != nil {
// Wrap the error returned by DoA().
// Add contextual message and tags.
return cerror.New(err, "failed to do A", map[string]interface{}{
"param": "a",
})
}
return nil
}
func DoA() error {
// External code returns a normal error
return errors.New("failed to connect")
}
>>2020/09/01 20:01:57 [ERROR] Failed to do B where param=b because
>>> failed to do A where param=a because
>>> failed to connect


The namespace element defines a namespace used within the bound XML documents. Each namespace used within the documents must be defined using one of these elements. When marshalling to XML, the namespace definitions included in the binding are automatically added to the appropriate XML elements.
This works differently depending upon whether the namespace definition is in the binding element context, or that of a mapping element. If the namespace is the child of a mapping element it will be defined on the element associated with that mapping when it is marshalled. Only mapping elements that define an element name are allowed to have namespace child elements for this reason. If the namespace is a child of the binding element, it applies to all the top-level mappings defined within that binding. The effect is the same as if the namespace were instead present as a child element of every top-level mapping element.
Besides defining a namespace for the XML documents, the namespace element can also make that namespace the default for elements and/or attributes within the context of the definition. This is only a shortcut - a namespace URI can always be defined directly for each element or attribute, and a direct definition will always override the default defined by a namespace element. However, using a default namespace definition allows easy handling of common XML document structures. A default namespace for element names applies to the containing mapping element name as well as child element names.
The namespace element uses three unique attributes, but none of the common attribute groups.
| uri | This required attribute is the namespace URI being defined. |
| default | Optionally gives the default usage of this namespace, which must be "none" (only used where specified, the default if this attribute is not given), "elements" (default for elements only), "attributes" (default for attributes only), or "all" (both elements and attributes use this namespace by default). |
| prefix | This is the prefix to map to the namespace when marshalling. It is ignored when unmarshalling, since the namespace URI is used directly to identify elements and attributes. This attribute is required for namespaces in an output binding unless default="elements" is specified. |
namespace elements are subject to the restrictions that namespaces with the same prefix cannot be defined in the same context, and no two namespaces can be defined with conflicting defaults within the same context (i.e., two namespaces each having either default="elements" or default="all", or two namespaces each having default="attributes" or default="all").


|
ovs all
|
Public Member Functions | |
| def | __init__ (self, socket, name, status) |
| def | close (self) |
| def | connect (self) |
| def | recv (self, n) |
| def | send (self, buf) |
| def | run (self) |
| def | run_wait (self, poller) |
| def | wait (self, poller, wait) |
| def | connect_wait (self, poller) |
| def | recv_wait (self, poller) |
| def | send_wait (self, poller) |
| def | __del__ (self) |
Static Public Member Functions | |
| def | register_method (method, cls) |
| def | is_valid_name (name) |
| def | open |
| def | open_block (error, stream) |
Data Fields | |
| socket | |
| name | |
| state | |
| error | |
Static Public Attributes | |
| int | W_CONNECT = 0 |
| int | W_RECV = 1 |
| int | W_SEND = 2 |
| int | IPTOS_PREC_INTERNETCONTROL = 0xc0 |
| int | DSCP_DEFAULT = IPTOS_PREC_INTERNETCONTROL>>2 |
Bidirectional byte stream. Currently only Unix domain sockets are implemented.
| def ovs.stream.Stream.__init__ | ( | self, | |
| socket, | |||
| name, | |||
| status | |||
| ) |
| def ovs.stream.Stream.__del__ | ( | self | ) |
| def ovs.stream.Stream.connect | ( | self | ) |
Tries to complete the connection on this stream. If the connection is complete, returns 0 if the connection was successful or a positive errno value if it failed. If the connection is still in progress, returns errno.EAGAIN.
| def ovs.stream.Stream.connect_wait | ( | self, | |
| poller | |||
| ) |
|
static |
Returns True if 'name' is a stream name in the form "TYPE:ARGS" and TYPE is a supported stream type (currently only "unix:" and "tcp:"), otherwise False.
|
static |
Attempts to connect a stream to a remote peer. 'name' is a connection name in the form "TYPE:ARGS", where TYPE is an active stream class's name and ARGS are stream class-specific. Currently the only supported TYPEs are "unix" and "tcp". Returns (error, stream): on success 'error' is 0 and 'stream' is the new Stream, on failure 'error' is a positive errno value and 'stream' is None. Never returns errno.EAGAIN or errno.EINPROGRESS. Instead, returns 0 and a new Stream. The connect() method can be used to check for successful connection completion.
|
static |
Blocks until a Stream completes its connection attempt, either succeeding or failing. (error, stream) should be the tuple returned by Stream.open(). Returns a tuple of the same form. Typical usage: error, stream = Stream.open_block(Stream.open("unix:/tmp/socket"))
| def ovs.stream.Stream.recv | ( | self, | |
| n | |||
| ) |
Tries to receive up to 'n' bytes from this stream. Returns a (error, string) tuple: - If successful, 'error' is zero and 'string' contains between 1 and 'n' bytes of data. - On error, 'error' is a positive errno value. - If the connection has been closed in the normal fashion or if 'n' is 0, the tuple is (0, ""). The recv function will not block waiting for data to arrive. If no data have been received, it returns (errno.EAGAIN, "") immediately.
| def ovs.stream.Stream.recv_wait | ( | self, | |
| poller | |||
| ) |
|
static |
| def ovs.stream.Stream.run | ( | self | ) |
| def ovs.stream.Stream.send | ( | self, | |
| buf | |||
| ) |
Tries to send 'buf' on this stream. If successful, returns the number of bytes sent, between 1 and len(buf). 0 is only a valid return value if len(buf) is 0. On error, returns a negative errno value. Will not block. If no bytes can be immediately accepted for transmission, returns -errno.EAGAIN immediately.
| def ovs.stream.Stream.send_wait | ( | self, | |
| poller | |||
| ) |
| def ovs.stream.Stream.wait | ( | self, | |
| poller, | |||
| wait | |||
| ) |
|
static |
| ovs.stream.Stream.error |
|
static |
| ovs.stream.Stream.name |
| ovs.stream.Stream.socket |
| ovs.stream.Stream.state |
|
static |
|
static |
|
static |


my recent work
Application: jChat
A simple chat application with SignIn & SignOut Feature.

In the Lab


#include "recipe-box-card.html"
#include "camper-leaderboard-card.html"
#include "markdown-previewer-card.html"
#include "simon-card.html"
#include "bar-chart-card.html"
#include "twitch-card.html"
#include "wikipedia-card.html"
#include "weather-card.html"
#include "tic-tac-toe-card.html"
#include "pomodoro-card.html"
#include "calculator-card.html"
#include "random-quote-card.html"
#include "portfolio-card.html"
#include "tribute-card.html"


Checking the situation of city bike stations in the Helsinki metropolitan area is always one quick wrist gesture away!


| DOSE: |
1.25 leaves |
oral |
Datura |
(tea) |
So I thought I'd try out some Datura on the weekend. I don't really know how to describe it other then being intense, and up there with mushies and lsd in terms of how powerful the mindfuck/hallucinations were. From this point, the person taking the datura will be referred to as 'smashcrab' and this will be written from the point of view of his sitter 'sexyhottie'.
Saturday, June 24 2006
Smashcrab has been trying to get his hands on some Datura for ages now. And out of the blue he got offered enough from a friend. We did a bit of research. He decided to take it through tea form. Boiled for 30 mins and mixed it with coffee, milk, sugar. Boiled and drank some disgusting green tea at 3:00pm.
+1:00 Started feeling 'spaced out'. Had really dry mouth and not talking. Not able to open eyes. Thought a crow was staring at him in the eyes. Keeps twitching and shivering. Says he sounds like he has a lisp.
+2:30 Had to go to the shops for ciggies, locked up the house and locked him in my bedroom while I went out for a few minutes. When I left he was laying on his
back with his eyes open, was still in the same position when I got back but he insists he'd had an adventure on his own that felt like it lasted for hours. I was only gone for about 10mins tops.
+2:40 Has been tripping for a while now - wanting to go to the toilet often but not really going, getting up walking into the toilet but not going. Says he has already been. While standing in the toilet with the door half closed, not even going to the toilet just standing there, he was having a conversation with no one. Wanted to take a shower, then said that he already had one and that I was handing him the towel (I wasn't). Has gotten up 3 times to go to the toilet and not going.   Random words, rapid fire with a look of confidence on his face like he understands what he's talking about.
Gets angry when I say WHAT!!!!. Just said that the picture box is empty????? Asked is this certificate is ok for the dole tomorrow???? Was showing me the certificate, that didn't exist, and he didn't need. He is thinking I am saying things when I am not. Tried opening the toilet door by pressing 'buttons' (there are no buttons just a normal handle). Said he wants to take some pills but not for ages. Said my Nirvana poster lookes like they went to his high school, and has been feeling more and more paranoid that the bassist Kris had been staring at him and grinning evily as well as moving around the room and hiding.
+3:50 Tried to bite my nose. Just bit it softly. Has the pasteys bad. Keeps looking around the room with a scared look, but insists he's not scared of anything, just
confused. Says he has some 'Cerals' down there and have to wait till morning or until someone comes here. Said a guy was standing in the hall way with an evil grin on his face. The door was shut, he couldn't even see the hall way. I opened the door to show him that no one was there and he said that he has gone to the other side of the fence. Grabbed the filters off the ground and tried to hide them in his pocket saying that we have to hide the weed??? (there is no weed).
Keeps looking on the ground trying to find something. Was saying that there was a stain on the carpet and that we had to get it off or it will be there forever. Kept having conversations with me while I was out of the room. Said that when I walked back into the room and I sat on myself??
+4:17 Grabbed my big harvey norman bag and got a box out of it and threw it next to my TV. Is telling me to re install windows and it will fix everything. There is nothing wrong with my computer. Said that he had a dream that he wished for this guy to become a vegetable, then he said 'But I don't want him to be one'. Said something about arseholes chop up there family and put it in buckets and chuck it at people.????  On the verge of flipping out and attacking the rude, uninvited visitors because they've just stood there and stared at him for hours.
+6:27 Keeps picking at my blanket saying there is news articles about hemp on it and that there is alot of 'hemp heads' out here. (sunnybank hills, qld australia). Says he is feeling sweet. Keeps saying that he wants to go for a walk to Macdonalds, I said ok and then about 10 mins he still hasnt moved. Tries to find his jumper, I put it around his neck and then 5 seconds later he takes it off. Keeps picking up the blanket, trying to put it on like a jumper and trips out saying it's become like liquid and flashes in and out of existance.
First time he's pointed out that he dropped his ciggie in the bed and can't find it, never actually had any ciggies but convinced himself he had burnt the mattress with them. So convinced about the ciggies that his hands are held like he was actually carrying the ciggie and couldn't make his fingers close around where the ciggie was in his hand. Was a huge mission to 'crush the ciggie' that wasn't in his hand so he could get his head around the fact that it never existed. Gets scared that he'd bled all over the blanket, and kept pointing out 'huge blood stains' that just arent there, rubbing it onto his fingers and tries to show me and take photos of them for later 'proof'.
+7:00 Went for a walk (Finally) to macdonalds. Tripped on the road curb rolled ankle badly, skinning knees and popped thong plug out. Tried to fix the shoe he broke while sitting on the gutter pretty much on the road. While walking to macdonalds, kept saying that he needs his thongs and grabbed my feet thinking they were his shoes. Went to the gutter and said that he had forgotten to grab the weed, put his hand in the wet gutter looking for it (?). Finally got to Macdonalds, ordered him a burger sat down with it and went to have a bite and ran to the toilet to throw up but never actually did (But says that he did threw up a heap).
We left after that and walked home, there was a drain and you could see that you shouldn't walk on it cause it was broken and a 'sober' person would have seen that you could fall down it and I told him not to walk on it but he put his full weight on the drain cover, dropped in and somehow jumped off a falling cover back onto solid ground with ninja speed (out of nowhere). Is quite impressed at his reflexes kicking in in time, and that he could jump off something that was already falling and had nothing to support a jump (He should have just pushed the drain lid down faster and not gained any height from the jump). Says he feels like hes floating around and that his legs are back at home in the cupboard.
+10:00 Still halluciating but able to keep a conversation going without rambling and mumbling. Had something to eat here (as he didn't eat his burger at Macdonalds
and threw my meal out). He was able to eat without 'feeling' like he was throwing up.
+12:30 Still awake getting tired. Hasn't noticed any halluciations at the moment, has been having phantom ciggies all night. Has only had about 4 puffs of ciggies since 3:00pm.
+14:00 Finally fell asleep, and had extremely powerful/strange dreams and nightmares that felt real. Remembers seeing my face go grey and morph into wierd impossibly distorted positions that freaked him out hard.
+24:00 Pupils are still heavily dilated, keeps checking with me about whats real and what isn't but feels heaps better overall. Eyes are extremely blurry at close distances and better then usual at long distances (Smashcrab is shortsighted normally). Glasses give him a headache, seems like his vision has been reversed completely. The whole night all we did was sit in my room and walk to Macdonalds (About 1 block away), had one person come into my room (My brother), but he reckons we had about 14 visitors and that we sat in the lounge room for ages with 2 visitors. While my brother was in the room (5 mins) we just laughed at him as he mumbled something about the poster.  He has met my brother numerious times and knows him quite well.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


Select Account
Loading...
Deploy new contract
Name:
Email:
Deploy Contract
Deployed Contracts:
N/A
Allow Access
Smart contract Address:
New Address:
Allow Access
Get Email Address
Smart contract Address:
Get Email Address
Update Email Address
New Email:
Update


Dash is the cryptocurrency, which was created in 2014 to ensure the anonymity and safety of users. It takes a place in Top 15 cryptocurrencies in the world and its daily volume is about $ 200 MLN. Today Dash market capitalization is about $ 700 MLN and DASH current price is about 80 USD.
In 2017, the Dash coin price increased by 8000%, which attracted the investor's attention. At the launch time, the DASH price was just 0.2 USD. Within a few months, the Dash price began to rise fast – Dash was trading at $ 12 in August 2016. In 2017, there was a big jump in the Dash price: $ 109 was given for 1 DASH.
At the end of 2017, there was the largest price of the Dash coin, 1 DASH was sell for 1584 USD. During 2018, the Dash price decreased from $1300 to $80 and its market capitalization decreased from $ 12 BLN to $ 600 MLN. Despite this, the Dash community gradually developing and still reaching large volumes.
Dash architecture consists of two separately parts: miners and the master node that confirm the transaction. This mechanism is called "PrivateSend", because the principle of a two-level architecture provide completely anonymous transactions. The system doesn't store data about who send and receive the transactions and it's impossible to identify them during network operation. Users can set a number of mixes for they transaction from 2 to 8. As soon as the mixing is completed, the owner of the tokens receives them to new addresses in 2-3 minutes only. These facts are attract a lot of users and it explains the DASH price.
At the end of 2018, in the media appeared news that DASH coins began to be accepted as a means of payment by the fast-food chain Church’s Chicken restaurants in Venezuela – this is one of the signals that cryptocurrencies getting a mass adoption which necessarily affects its value. The Dash advantages are not only in the possibilities of anonymous transactions but also in the technology of mining, nonetheless, as for the perspectives of DASH price for 2019, it depends on what will happen with Bitcoin.
On December 2019, the cost of one DASH coin was $ 58. This price is the lowest in the last 2 years, because having overcome this mark in March 2017, the Dash price was no longer approaching it. Based on the fact that the crypto market conditions have changed a lot, and private investors have rethought their approach to buying cryptocurrencies, Dash has chances for success.
#1 Smartereum DASH Price Prediction
Very positive forecast for DASH price in 5 years, the coin may cost up to $5000.
#2 WalletInvestor DASH Price Prediction
Wallet Investor predicts bad long-term invesment index for DASH coin. DASH price may probably decrease to $6.5.
#3 CoinPredictor.io DASH Price Prediction
By December DASH price will may decrease to $30 per coin.
Despite strong competition from Monero (XMR) and Bytecoin (BCN), the Dash coin will find its place in the market. And if this year we'll see an influx of large investors in the cryptocurrency market, then DASH price has every chance to reach the price of 500-600 USD.
You can exchange DASH on the exchange services, but you shouldn’t store all your funds there, because these services are centralized. They stored your Private keys on their bases and theoretically it may be hacked.
You can trade the part of your DASH on the exchange and store all your DASH in the wallet. Or you can do it in one place. In Atomic Wallet you can manage 300+ cryptocurrency assets and instant exchange over 60 trading pairs in one secure interface.
To make a good choice of the cryptocurrency wallet you need to know the difference between them. There are 3 types of the cryptocurrency wallets:
Cold wallets download the full node. Custodial wallets store your Private keys in their bases and it theoretically may be hacked. Decentralized wallets store your Private keys in an encrypted manner on your device, so while you own your 12 words you can be sure that your money is under your control.
Manage and exchange DASH in one secure interface of Atomic Wallet with built-in exchange service. Atomic supports over 60 trading pairs for instant exchange with the market rates.
The arcticle has an informative purpose. The Atomic Wallet team is not trying to persuade or endorse you, neither are we making warranties for the accuracy of the content. All decisions are made at your own risk.


Jason Lengstorf wrote
Jason Lengstorf wrote
Jason Lengstorf wrote
Jason Lengstorf wrote
Jason Lengstorf wrote
Author
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis, expedita libero sequi optio in magnam totam?
Author
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis, expedita libero sequi optio in magnam totam?
Author
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis, expedita libero sequi optio in magnam totam?
ADVERT
A friendly community that keeps this website alive. With books, webinars, discounts and networking — for just 1 coffee a month. Join the family. Explore features
Explore features →author
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis, expedita libero sequi optio in magnam totam?
author
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis, expedita libero sequi optio in magnam totam?
author
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis, expedita libero sequi optio in magnam totam?
author
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis, expedita libero sequi optio in magnam totam?
A channel where seasoned developers show how they design, build, work and play. Coming up next: Form Design Patterns With Adam Silver with Adam Silver (Jan 15)
Explore features →Our new practical book on building accessible and robust interfaces. From accordions and buttons to modals and tables. With bulletproof code samples. Written by Heydon Pickering.
learn more about the book ->Rick Viscomi (@rick_viscomi) is a Senior Web Developer Programs Engineer at Google. Passionate about web transparency, he maintains the Chrome User Experience Report and the open-source HTTP Archive project. To bring meaning to the raw stats and trends that the HTTP Archive has been collecting, Rick published the first issue of the Web Almanac this year, a yearly report on the state of the web, backed up by real data and trusted web experts. Rick is also the co-author of Using WebPage Test and host of the video series The State of the Web. Thank you for everything you do for the web community, dear Rick!
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nobis, mollitia debitis. Impedit inventore perspiciatis dolor sunt autem quod. Quod laboriosam dolorum repudiandae perferendis
A channel where seasoned developers show how they design, build, work and play. Coming up next: Form Design Patterns With Adam Silver with Adam Silver (Jan 15)
Table of Contents →Imagine you wrote a beautiful song and nobody discovered it. That would make any cat sad. Don't let that happen.
Useful tips for web designers. Sent 2× a month.
You can unsubscribe any time — obviously.


RT @vektrasays: It is with much excitement we announce the availability of Vektra Alpha 1! http://discuss.vektra.com/t/welcome-alpha-warriors
10/2/2014, 5:34:01 PM
Favs: 0
Retweets: 0
link--- layout: tweet ---
RT @vektrasays: It is with much excitement we announce the availability of Vektra Alpha 1! http://discuss.vektra.com/t/welcome-alpha-warriors
10/2/2014, 5:34:01 PM
Favs: 0
Retweets: 0
link


Summary
Our goal was to generate parametrized code to determine the angle of defelction of control surfaces on a four finned rocket given a few basic parameters. Of course, there are many ways to fully define a rocket, but we took a few specific variables as inputs. These variables were
- rocket diameter
- desired cal/stability ratio
- rocket mass
- rocket velocity
- sensor data on pitch and yaw degrees of freedom
- length of the rocket
- the density of air a the desired altitude
- coefficient of drag for the vehicle in question
- desired time step for simulation, for fidelity level in simulation
- benchmarked proportional, integrative, and derivative gains experienced by the rocket--for both pitch and yaw degrees of freedom
From these values, we calculated the desired change in angle between the rocket's pointing vector and the tangent to the desired trajectory at that point.
Needless to say, this is hard, and we weren't able to progress past the "P" part of a "PID controller" for our simulation, and the number of assumptions we had to make to be able to make any headway on this project may have thrown off our numbers by a lot. The list of assumptions is under the "Assumptions" tab.