import { isNone } from '@ember/utils';
import EmberError from '@ember/error';
import EmberObject, { computed, get } from '@ember/object';
import { DEBUG } from '@glimmer/env';
import { assert, warn, deprecate } from '@ember/debug';
import Ember from 'ember';
import { RECORD_DATA_ERRORS, RECORD_DATA_STATE, REQUEST_SERVICE } from '@ember-data/canary-features';
import {
coerceId,
DeprecatedEvented,
errorsArrayToHash,
InternalModel,
PromiseObject,
recordDataFor,
recordIdentifierFor,
relationshipsByNameDescriptor,
relationshipsObjectDescriptor,
relatedTypesDescriptor,
relationshipsDescriptor,
RootState,
} from '@ember-data/store/-private';
import Errors from './errors';
const { changeProperties } = Ember;
function isInvalidError(error) {
return error && error.isAdapterError === true && error.code === 'InvalidError';
}
function findPossibleInverses(type, inverseType, name, relationshipsSoFar) {
let possibleRelationships = relationshipsSoFar || [];
let relationshipMap = get(inverseType, 'relationships');
if (!relationshipMap) {
return possibleRelationships;
}
let relationshipsForType = relationshipMap.get(type.modelName);
let relationships = Array.isArray(relationshipsForType)
? relationshipsForType.filter(relationship => {
let optionsForRelationship = inverseType.metaForProperty(relationship.name).options;
if (!optionsForRelationship.inverse && optionsForRelationship.inverse !== null) {
return true;
}
return name === optionsForRelationship.inverse;
})
: null;
if (relationships) {
possibleRelationships.push.apply(possibleRelationships, relationships);
}
//Recurse to support polymorphism
if (type.superclass) {
findPossibleInverses(type.superclass, inverseType, name, possibleRelationships);
}
return possibleRelationships;
}
const retrieveFromCurrentState = computed('currentState', function(key) {
return get(this._internalModel.currentState, key);
}).readOnly();
const isValidRecordData = computed('errors.length', function(key) {
return !(this.get('errors.length') > 0);
}).readOnly();
const isValid = RECORD_DATA_ERRORS ? isValidRecordData : retrieveFromCurrentState;
let isDeletedCP;
if (RECORD_DATA_STATE) {
isDeletedCP = computed('currentState', function() {
let rd = recordDataFor(this);
if (rd.isDeleted) {
return rd.isDeleted();
} else {
return get(this._internalModel.currentState, 'isDeleted');
}
}).readOnly();
} else {
isDeletedCP = retrieveFromCurrentState;
}
let isNewCP;
if (RECORD_DATA_STATE) {
isNewCP = computed('currentState', function() {
let rd = recordDataFor(this);
if (rd.isNew) {
return rd.isNew();
} else {
return get(this._internalModel.currentState, 'isNew');
}
}).readOnly();
} else {
isNewCP = retrieveFromCurrentState;
}
let adapterError;
if (REQUEST_SERVICE) {
adapterError = computed(function() {
let request = this._lastError;
if (!request) {
return null;
}
return request.state === 'rejected' && request.response.data;
});
} else {
adapterError = null;
}
let isError;
if (REQUEST_SERVICE) {
isError = computed(function() {
let errorReq = this._errorRequests[this._errorRequests.length - 1];
if (!errorReq) {
return false;
} else {
return true;
}
});
} else {
isError = false;
}
let isReloading;
if (REQUEST_SERVICE) {
isReloading = computed(function() {
let requests = this.store.getRequestStateService().getPendingRequestsForRecord(recordIdentifierFor(this));
return !!requests.find(req => req.request.data[0].options.isReloading);
});
} else {
isReloading = false;
}
/**
@class Model
@module @ember-data/model
@extends EmberObject
@uses EmberData.DeprecatedEvented
*/
const Model = EmberObject.extend(DeprecatedEvented, {
init() {
this._super(...arguments);
if (DEBUG) {
if (!this._internalModel) {
throw new EmberError(
'You should not call `create` on a model. Instead, call `store.createRecord` with the attributes you would like to set.'
);
}
}
if (RECORD_DATA_ERRORS) {
this._invalidRequests = [];
}
if (REQUEST_SERVICE) {
this.store.getRequestStateService().subscribeForRecord(this._internalModel.identifier, request => {
if (request.state === 'rejected') {
// TODO filter out queries
this._lastError = request;
if (!(request.response && isInvalidError(request.response.data))) {
this._errorRequests.push(request);
} else {
this._invalidRequests.push(request);
}
} else if (request.state === 'fulfilled') {
this._invalidRequests = [];
this._errorRequests = [];
this._lastError = null;
}
this._notifyNetworkChanges();
});
this._errorRequests = [];
this._lastError = null;
}
},
_notifyNetworkChanges: function() {
if (REQUEST_SERVICE) {
['isSaving', 'isValid', 'isError', 'adapterError', 'isReloading'].forEach(key => this.notifyPropertyChange(key));
} else {
['isValid'].forEach(key => this.notifyPropertyChange(key));
}
},
/**
If this property is `true` the record is in the `empty`
state. Empty is the first state all records enter after they have
been created. Most records created by the store will quickly
transition to the `loading` state if data needs to be fetched from
the server or the `created` state if the record is created on the
client. A record can also enter the empty state if the adapter is
unable to locate the record.
@property isEmpty
@type {Boolean}
@readOnly
*/
isEmpty: retrieveFromCurrentState,
/**
If this property is `true` the record is in the `loading` state. A
record enters this state when the store asks the adapter for its
data. It remains in this state until the adapter provides the
requested data.
@property isLoading
@type {Boolean}
@readOnly
*/
isLoading: retrieveFromCurrentState,
/**
If this property is `true` the record is in the `loaded` state. A
record enters this state when its data is populated. Most of a
record's lifecycle is spent inside substates of the `loaded`
state.
Example
```javascript
let record = store.createRecord('model');
record.get('isLoaded'); // true
store.findRecord('model', 1).then(function(model) {
model.get('isLoaded'); // true
});
```
@property isLoaded
@type {Boolean}
@readOnly
*/
isLoaded: retrieveFromCurrentState,
/**
If this property is `true` the record is in the `dirty` state. The
record has local changes that have not yet been saved by the
adapter. This includes records that have been created (but not yet
saved) or deleted.
Example
```javascript
let record = store.createRecord('model');
record.get('hasDirtyAttributes'); // true
store.findRecord('model', 1).then(function(model) {
model.get('hasDirtyAttributes'); // false
model.set('foo', 'some value');
model.get('hasDirtyAttributes'); // true
});
```
@since 1.13.0
@property hasDirtyAttributes
@type {Boolean}
@readOnly
*/
hasDirtyAttributes: computed('currentState.isDirty', function() {
return this.get('currentState.isDirty');
}),
/**
If this property is `true` the record is in the `saving` state. A
record enters the saving state when `save` is called, but the
adapter has not yet acknowledged that the changes have been
persisted to the backend.
Example
```javascript
let record = store.createRecord('model');
record.get('isSaving'); // false
let promise = record.save();
record.get('isSaving'); // true
promise.then(function() {
record.get('isSaving'); // false
});
```
@property isSaving
@type {Boolean}
@readOnly
*/
isSaving: retrieveFromCurrentState,
/**
If this property is `true` the record is in the `deleted` state
and has been marked for deletion. When `isDeleted` is true and
`hasDirtyAttributes` is true, the record is deleted locally but the deletion
was not yet persisted. When `isSaving` is true, the change is
in-flight. When both `hasDirtyAttributes` and `isSaving` are false, the
change has persisted.
Example
```javascript
let record = store.createRecord('model');
record.get('isDeleted'); // false
record.deleteRecord();
// Locally deleted
record.get('isDeleted'); // true
record.get('hasDirtyAttributes'); // true
record.get('isSaving'); // false
// Persisting the deletion
let promise = record.save();
record.get('isDeleted'); // true
record.get('isSaving'); // true
// Deletion Persisted
promise.then(function() {
record.get('isDeleted'); // true
record.get('isSaving'); // false
record.get('hasDirtyAttributes'); // false
});
```
@property isDeleted
@type {Boolean}
@readOnly
*/
isDeleted: isDeletedCP,
/**
If this property is `true` the record is in the `new` state. A
record will be in the `new` state when it has been created on the
client and the adapter has not yet report that it was successfully
saved.
Example
```javascript
let record = store.createRecord('model');
record.get('isNew'); // true
record.save().then(function(model) {
model.get('isNew'); // false
});
```
@property isNew
@type {Boolean}
@readOnly
*/
isNew: isNewCP,
/**
If this property is `true` the record is in the `valid` state.
A record will be in the `valid` state when the adapter did not report any
server-side validation failures.
@property isValid
@type {Boolean}
@readOnly
*/
isValid: isValid,
_markInvalidRequestAsClean() {
if (RECORD_DATA_ERRORS) {
this._invalidRequests = [];
this._notifyNetworkChanges();
}
},
/**
If the record is in the dirty state this property will report what
kind of change has caused it to move into the dirty
state. Possible values are:
- `created` The record has been created by the client and not yet saved to the adapter.
- `updated` The record has been updated by the client and not yet saved to the adapter.
- `deleted` The record has been deleted by the client and not yet saved to the adapter.
Example
```javascript
let record = store.createRecord('model');
record.get('dirtyType'); // 'created'
```
@property dirtyType
@type {String}
@readOnly
*/
dirtyType: retrieveFromCurrentState,
/**
If `true` the adapter reported that it was unable to save local
changes to the backend for any reason other than a server-side
validation error.
Example
```javascript
record.get('isError'); // false
record.set('foo', 'valid value');
record.save().then(null, function() {
record.get('isError'); // true
});
```
@property isError
@type {Boolean}
@readOnly
*/
isError: isError,
_markErrorRequestAsClean() {
this._errorRequests = [];
this._lastError = null;
this._notifyNetworkChanges();
},
/**
If `true` the store is attempting to reload the record from the adapter.
Example
```javascript
record.get('isReloading'); // false
record.reload();
record.get('isReloading'); // true
```
@property isReloading
@type {Boolean}
@readOnly
*/
isReloading: isReloading,
/**
All ember models have an id property. This is an identifier
managed by an external source. These are always coerced to be
strings before being used internally. Note when declaring the
attributes for a model it is an error to declare an id
attribute.
```javascript
let record = store.createRecord('model');
record.get('id'); // null
store.findRecord('model', 1).then(function(model) {
model.get('id'); // '1'
});
```
@property id
@type {String}
*/
/**
@property currentState
@private
@type {Object}
*/
currentState: RootState.empty, // defined here to avoid triggering setUnknownProperty
/**
@property _internalModel
@private
@type {Object}
*/
_internalModel: null, // defined here to avoid triggering setUnknownProperty
/**
@property recordData
@private
@type undefined (reserved)
*/
// will be defined here to avoid triggering setUnknownProperty
/**
@property store
*/
store: null, // defined here to avoid triggering setUnknownProperty
/**
When the record is in the `invalid` state this object will contain
any errors returned by the adapter. When present the errors hash
contains keys corresponding to the invalid property names
and values which are arrays of Javascript objects with two keys:
- `message` A string containing the error message from the backend
- `attribute` The name of the property associated with this error message
```javascript
record.get('errors.length'); // 0
record.set('foo', 'invalid value');
record.save().catch(function() {
record.get('errors').get('foo');
// [{message: 'foo should be a number.', attribute: 'foo'}]
});
```
The `errors` property us useful for displaying error messages to
the user.
```handlebars
<label>Username: {{input value=username}} </label>
{{#each model.errors.username as |error|}}
<div class="error">
{{error.message}}
</div>
{{/each}}
<label>Email: {{input value=email}} </label>
{{#each model.errors.email as |error|}}
<div class="error">
{{error.message}}
</div>
{{/each}}
```
You can also access the special `messages` property on the error
object to get an array of all the error strings.
```handlebars
{{#each model.errors.messages as |message|}}
<div class="error">
{{message}}
</div>
{{/each}}
```
@property errors
@type {Errors}
*/
errors: computed(function() {
let errors = Errors.create();
errors._registerHandlers(
() => {
this.send('becameInvalid');
},
() => {
this.send('becameValid');
}
);
if (RECORD_DATA_ERRORS) {
let recordData = recordDataFor(this);
let jsonApiErrors;
if (recordData.getErrors) {
jsonApiErrors = recordData.getErrors();
if (jsonApiErrors) {
let errorsHash = errorsArrayToHash(jsonApiErrors);
let errorKeys = Object.keys(errorsHash);
for (let i = 0; i < errorKeys.length; i++) {
errors._add(errorKeys[i], errorsHash[errorKeys[i]]);
}
}
}
}
return errors;
}).readOnly(),
invalidErrorsChanged(jsonApiErrors) {
if (RECORD_DATA_ERRORS) {
this._clearErrorMessages();
let errors = errorsArrayToHash(jsonApiErrors);
let errorKeys = Object.keys(errors);
for (let i = 0; i < errorKeys.length; i++) {
this._addErrorMessageToAttribute(errorKeys[i], errors[errorKeys[i]]);
}
}
},
_addErrorMessageToAttribute(attribute, message) {
this.get('errors')._add(attribute, message);
},
_clearErrorMessages() {
this.get('errors')._clear();
},
/**
This property holds the `AdapterError` object with which
last adapter operation was rejected.
@property adapterError
@type {AdapterError}
*/
adapterError: adapterError,
/**
Create a JSON representation of the record, using the serialization
strategy of the store's adapter.
`serialize` takes an optional hash as a parameter, currently
supported options are:
- `includeId`: `true` if the record's ID should be included in the
JSON representation.
@method serialize
@param {Object} options
@return {Object} an object whose values are primitive JSON values only
*/
serialize(options) {
return this._internalModel.createSnapshot().serialize(options);
},
/**
Use [JSONSerializer](JSONSerializer.html) to
get the JSON representation of a record.
`toJSON` takes an optional hash as a parameter, currently
supported options are:
- `includeId`: `true` if the record's ID should be included in the
JSON representation.
@method toJSON
@param {Object} options
@return {Object} A JSON representation of the object.
*/
toJSON(options) {
// container is for lazy transform lookups
deprecate(
`Called the built-in \`toJSON\` on the record "${this.constructor.modelName}:${this.id}". The built-in \`toJSON\` method on instances of classes extending \`Model\` is deprecated. For more information see the link below.`,
false,
{
id: 'ember-data:model.toJSON',
until: '4.0',
url: 'https://deprecations.emberjs.com/ember-data/v3.x#toc_record-toJSON',
}
);
let serializer = this._internalModel.store.serializerFor('-default');
let snapshot = this._internalModel.createSnapshot();
return serializer.serialize(snapshot, options);
},
/**
Fired when the record is ready to be interacted with,
that is either loaded from the server or created locally.
@event ready
*/
ready: null,
/**
Fired when the record is loaded from the server.
@event didLoad
*/
didLoad: null,
/**
Fired when the record is updated.
@event didUpdate
*/
didUpdate: null,
/**
Fired when a new record is commited to the server.
@event didCreate
*/
didCreate: null,
/**
Fired when the record is deleted.
@event didDelete
*/
didDelete: null,
/**
Fired when the record becomes invalid.
@event becameInvalid
*/
becameInvalid: null,
/**
Fired when the record enters the error state.
@event becameError
*/
becameError: null,
/**
Fired when the record is rolled back.
@event rolledBack
*/
rolledBack: null,
//TODO Do we want to deprecate these?
/**
@method send
@private
@param {String} name
@param {Object} context
*/
send(name, context) {
return this._internalModel.send(name, context);
},
/**
@method transitionTo
@private
@param {String} name
*/
transitionTo(name) {
return this._internalModel.transitionTo(name);
},
/**
Marks the record as deleted but does not save it. You must call
`save` afterwards if you want to persist it. You might use this
method if you want to allow the user to still `rollbackAttributes()`
after a delete was made.
Example
```app/routes/model/delete.js
import Route from '@ember/routing/route';
export default Route.extend({
actions: {
softDelete() {
this.get('controller.model').deleteRecord();
},
confirm() {
this.get('controller.model').save();
},
undo() {
this.get('controller.model').rollbackAttributes();
}
}
});
```
@method deleteRecord
*/
deleteRecord() {
this._internalModel.deleteRecord();
},
/**
Same as `deleteRecord`, but saves the record immediately.
Example
```app/routes/model/delete.js
import Route from '@ember/routing/route';
export default Route.extend({
actions: {
delete() {
this.get('controller.model').destroyRecord().then(function() {
controller.transitionToRoute('model.index');
});
}
}
});
```
If you pass an object on the `adapterOptions` property of the options
argument it will be passed to your adapter via the snapshot
```js
record.destroyRecord({ adapterOptions: { subscribe: false } });
```
```app/adapters/post.js
import MyCustomAdapter from './custom-adapter';
export default MyCustomAdapter.extend({
deleteRecord(store, type, snapshot) {
if (snapshot.adapterOptions.subscribe) {
// ...
}
// ...
}
});
```
@method destroyRecord
@param {Object} options
@return {Promise} a promise that will be resolved when the adapter returns
successfully or rejected if the adapter returns with an error.
*/
destroyRecord(options) {
this.deleteRecord();
return this.save(options);
},
/**
Unloads the record from the store. This will not send a delete request
to your server, it just unloads the record from memory.
@method unloadRecord
*/
unloadRecord() {
if (this.isDestroyed) {
return;
}
this._internalModel.unloadRecord();
},
/**
@method _notifyProperties
@private
*/
_notifyProperties(keys) {
// changeProperties defers notifications until after the delegate
// and protects with a try...finally block
// previously used begin...endPropertyChanges but this is private API
changeProperties(() => {
let key;
for (let i = 0, length = keys.length; i < length; i++) {
key = keys[i];
this.notifyPropertyChange(key);
}
});
},
/**
Returns an object, whose keys are changed properties, and value is
an [oldProp, newProp] array.
The array represents the diff of the canonical state with the local state
of the model. Note: if the model is created locally, the canonical state is
empty since the adapter hasn't acknowledged the attributes yet:
Example
```app/models/mascot.js
import Model, { attr } from '@ember-data/model';
export default Model.extend({
name: attr('string'),
isAdmin: attr('boolean', {
defaultValue: false
})
});
```
```javascript
let mascot = store.createRecord('mascot');
mascot.changedAttributes(); // {}
mascot.set('name', 'Tomster');
mascot.changedAttributes(); // { name: [undefined, 'Tomster'] }
mascot.set('isAdmin', true);
mascot.changedAttributes(); // { isAdmin: [undefined, true], name: [undefined, 'Tomster'] }
mascot.save().then(function() {
mascot.changedAttributes(); // {}
mascot.set('isAdmin', false);
mascot.changedAttributes(); // { isAdmin: [true, false] }
});
```
@method changedAttributes
@return {Object} an object, whose keys are changed properties,
and value is an [oldProp, newProp] array.
*/
changedAttributes() {
return this._internalModel.changedAttributes();
},
/**
If the model `hasDirtyAttributes` this function will discard any unsaved
changes. If the model `isNew` it will be removed from the store.
Example
```javascript
record.get('name'); // 'Untitled Document'
record.set('name', 'Doc 1');
record.get('name'); // 'Doc 1'
record.rollbackAttributes();
record.get('name'); // 'Untitled Document'
```
@since 1.13.0
@method rollbackAttributes
*/
rollbackAttributes() {
this._internalModel.rollbackAttributes();
if (RECORD_DATA_ERRORS) {
this._markInvalidRequestAsClean();
}
if (REQUEST_SERVICE) {
this._markErrorRequestAsClean();
}
},
/*
@method _createSnapshot
@private
*/
_createSnapshot() {
return this._internalModel.createSnapshot();
},
toStringExtension() {
// the _internalModel guard exists, because some dev-only deprecation code
// (addListener via validatePropertyInjections) invokes toString before the
// object is real.
return this._internalModel && this._internalModel.id;
},
/**
Save the record and persist any changes to the record to an
external source via the adapter.
Example
```javascript
record.set('name', 'Tomster');
record.save().then(function() {
// Success callback
}, function() {
// Error callback
});
```
If you pass an object using the `adapterOptions` property of the options
argument it will be passed to your adapter via the snapshot.
```js
record.save({ adapterOptions: { subscribe: false } });
```
```app/adapters/post.js
import MyCustomAdapter from './custom-adapter';
export default MyCustomAdapter.extend({
updateRecord(store, type, snapshot) {
if (snapshot.adapterOptions.subscribe) {
// ...
}
// ...
}
});
```
@method save
@param {Object} options
@return {Promise} a promise that will be resolved when the adapter returns
successfully or rejected if the adapter returns with an error.
*/
save(options) {
return PromiseObject.create({
promise: this._internalModel.save(options).then(() => this),
});
},
/**
Reload the record from the adapter.
This will only work if the record has already finished loading.
Example
```app/routes/model/view.js
import Route from '@ember/routing/route';
export default Route.extend({
actions: {
reload() {
this.controller.get('model').reload().then(function(model) {
// do something with the reloaded model
});
}
}
});
```
@method reload
@param {Object} options optional, may include `adapterOptions` hash which will be passed to adapter request
@return {Promise} a promise that will be resolved with the record when the
adapter returns successfully or rejected if the adapter returns
with an error.
*/
reload(options) {
let wrappedAdapterOptions;
if (typeof options === 'object' && options !== null && options.adapterOptions) {
wrappedAdapterOptions = {
adapterOptions: options.adapterOptions,
};
}
return PromiseObject.create({
promise: this._internalModel.reload(wrappedAdapterOptions).then(() => this),
});
},
/**
Override the default event firing from Ember.Evented to
also call methods with the given name.
@method trigger
@private
@param {String} name
*/
trigger(name) {
let fn = this[name];
if (typeof fn === 'function') {
let length = arguments.length;
let args = new Array(length - 1);
for (let i = 1; i < length; i++) {
args[i - 1] = arguments[i];
}
fn.apply(this, args);
}
const _hasEvent = DEBUG ? this._has(name) : this.has(name);
if (_hasEvent) {
this._super(...arguments);
}
},
attr() {
assert(
'The `attr` method is not available on Model, a Snapshot was probably expected. Are you passing a Model instead of a Snapshot to your serializer?',
false
);
},
/**
Get the reference for the specified belongsTo relationship.
Example
```app/models/blog.js
import Model, { belongsTo } from '@ember-data/model';
export default Model.extend({
user: belongsTo({ async: true })
});
```
```javascript
let blog = store.push({
data: {
type: 'blog',
id: 1,
relationships: {
user: {
data: { type: 'user', id: 1 }
}
}
}
});
let userRef = blog.belongsTo('user');
// check if the user relationship is loaded
let isLoaded = userRef.value() !== null;
// get the record of the reference (null if not yet available)
let user = userRef.value();
// get the identifier of the reference
if (userRef.remoteType() === "id") {
let id = userRef.id();
} else if (userRef.remoteType() === "link") {
let link = userRef.link();
}
// load user (via store.findRecord or store.findBelongsTo)
userRef.load().then(...)
// or trigger a reload
userRef.reload().then(...)
// provide data for reference
userRef.push({
type: 'user',
id: 1,
attributes: {
username: "@user"
}
}).then(function(user) {
userRef.value() === user;
});
```
@method belongsTo
@param {String} name of the relationship
@since 2.5.0
@return {BelongsToReference} reference for this relationship
*/
belongsTo(name) {
return this._internalModel.referenceFor('belongsTo', name);
},
/**
Get the reference for the specified hasMany relationship.
Example
```app/models/blog.js
import Model, { hasMany } from '@ember-data/model';
export default Model.extend({
comments: hasMany({ async: true })
});
let blog = store.push({
data: {
type: 'blog',
id: 1,
relationships: {
comments: {
data: [
{ type: 'comment', id: 1 },
{ type: 'comment', id: 2 }
]
}
}
}
});
let commentsRef = blog.hasMany('comments');
// check if the comments are loaded already
let isLoaded = commentsRef.value() !== null;
// get the records of the reference (null if not yet available)
let comments = commentsRef.value();
// get the identifier of the reference
if (commentsRef.remoteType() === "ids") {
let ids = commentsRef.ids();
} else if (commentsRef.remoteType() === "link") {
let link = commentsRef.link();
}
// load comments (via store.findMany or store.findHasMany)
commentsRef.load().then(...)
// or trigger a reload
commentsRef.reload().then(...)
// provide data for reference
commentsRef.push([{ type: 'comment', id: 1 }, { type: 'comment', id: 2 }]).then(function(comments) {
commentsRef.value() === comments;
});
```
@method hasMany
@param {String} name of the relationship
@since 2.5.0
@return {HasManyReference} reference for this relationship
*/
hasMany(name) {
return this._internalModel.referenceFor('hasMany', name);
},
/**
Provides info about the model for debugging purposes
by grouping the properties into more semantic groups.
Meant to be used by debugging tools such as the Chrome Ember Extension.
- Groups all attributes in "Attributes" group.
- Groups all belongsTo relationships in "Belongs To" group.
- Groups all hasMany relationships in "Has Many" group.
- Groups all flags in "Flags" group.
- Flags relationship CPs as expensive properties.
@method _debugInfo
@for Model
@private
*/
_debugInfo() {
let attributes = ['id'];
let relationships = {};
let expensiveProperties = [];
this.eachAttribute((name, meta) => attributes.push(name));
let groups = [
{
name: 'Attributes',
properties: attributes,
expand: true,
},
];
this.eachRelationship((name, relationship) => {
let properties = relationships[relationship.kind];
if (properties === undefined) {
properties = relationships[relationship.kind] = [];
groups.push({
name: relationship.kind,
properties,
expand: true,
});
}
properties.push(name);
expensiveProperties.push(name);
});
groups.push({
name: 'Flags',
properties: ['isLoaded', 'hasDirtyAttributes', 'isSaving', 'isDeleted', 'isError', 'isNew', 'isValid'],
});
return {
propertyInfo: {
// include all other mixins / properties (not just the grouped ones)
includeOtherProperties: true,
groups: groups,
// don't pre-calculate unless cached
expensiveProperties: expensiveProperties,
},
};
},
notifyBelongsToChange(key) {
this.notifyPropertyChange(key);
},
/**
Given a callback, iterates over each of the relationships in the model,
invoking the callback with the name of each relationship and its relationship
descriptor.
The callback method you provide should have the following signature (all
parameters are optional):
```javascript
function(name, descriptor);
```
- `name` the name of the current property in the iteration
- `descriptor` the meta object that describes this relationship
The relationship descriptor argument is an object with the following properties.
- **key** <span class="type">String</span> the name of this relationship on the Model
- **kind** <span class="type">String</span> "hasMany" or "belongsTo"
- **options** <span class="type">Object</span> the original options hash passed when the relationship was declared
- **parentType** <span class="type">Model</span> the type of the Model that owns this relationship
- **type** <span class="type">String</span> the type name of the related Model
Note that in addition to a callback, you can also pass an optional target
object that will be set as `this` on the context.
Example
```app/serializers/application.js
import JSONSerializer from '@ember-data/serializer/json';
export default JSONSerializer.extend({
serialize: function(record, options) {
let json = {};
record.eachRelationship(function(name, descriptor) {
if (descriptor.kind === 'hasMany') {
let serializedHasManyName = name.toUpperCase() + '_IDS';
json[serializedHasManyName] = record.get(name).mapBy('id');
}
});
return json;
}
});
```
@method eachRelationship
@param {Function} callback the callback to invoke
@param {any} binding the value to which the callback's `this` should be bound
*/
eachRelationship(callback, binding) {
this.constructor.eachRelationship(callback, binding);
},
relationshipFor(name) {
return get(this.constructor, 'relationshipsByName').get(name);
},
inverseFor(key) {
return this.constructor.inverseFor(key, this._internalModel.store);
},
notifyHasManyAdded(key) {
//We need to notifyPropertyChange in the adding case because we need to make sure
//we fetch the newly added record in case it is unloaded
//TODO(Igor): Consider whether we could do this only if the record state is unloaded
this.notifyPropertyChange(key);
},
eachAttribute(callback, binding) {
this.constructor.eachAttribute(callback, binding);
},
});
/**
@property data
@private
@deprecated
@type {Object}
*/
Object.defineProperty(Model.prototype, 'data', {
configurable: false,
get() {
deprecate(
`Model.data was private and it's use has been deprecated. For public access, use the RecordData API or iterate attributes`,
false,
{
id: 'ember-data:Model.data',
until: '3.9',
}
);
return recordDataFor(this)._data;
},
});
const ID_DESCRIPTOR = {
configurable: false,
set(id) {
const normalizedId = coerceId(id);
if (normalizedId !== null) {
this._internalModel.setId(normalizedId);
}
},
get() {
// the _internalModel guard exists, because some dev-only deprecation code
// (addListener via validatePropertyInjections) invokes toString before the
// object is real.
return this._internalModel && this._internalModel.id;
},
};
Object.defineProperty(Model.prototype, 'id', ID_DESCRIPTOR);
if (DEBUG) {
let lookupDescriptor = function lookupDescriptor(obj, keyName) {
let current = obj;
do {
let descriptor = Object.getOwnPropertyDescriptor(current, keyName);
if (descriptor !== undefined) {
return descriptor;
}
current = Object.getPrototypeOf(current);
} while (current !== null);
return null;
};
let isBasicDesc = function isBasicDesc(desc) {
return (
!desc ||
(!desc.get && !desc.set && desc.enumerable === true && desc.writable === true && desc.configurable === true)
);
};
let isDefaultEmptyDescriptor = function isDefaultEmptyDescriptor(obj, keyName) {
let instanceDesc = lookupDescriptor(obj, keyName);
return isBasicDesc(instanceDesc) && lookupDescriptor(obj.constructor, keyName) === null;
};
const INSTANCE_DEPRECATIONS = new WeakMap();
const DEPRECATED_LIFECYCLE_EVENT_METHODS = [
'becameError',
'becameInvalid',
'didCreate',
'didDelete',
'didLoad',
'didUpdate',
'ready',
'rolledBack',
];
let lookupDeprecations = function lookupInstanceDeprecations(instance) {
let deprecations = INSTANCE_DEPRECATIONS.get(instance);
if (!deprecations) {
deprecations = new Set();
INSTANCE_DEPRECATIONS.set(instance, deprecations);
}
return deprecations;
};
Model.reopen({
init() {
this._super(...arguments);
this._getDeprecatedEventedInfo = () => `${this._internalModel.modelName}#${this.id}`;
if (!isDefaultEmptyDescriptor(this, '_internalModel') || !(this._internalModel instanceof InternalModel)) {
throw new Error(
`'_internalModel' is a reserved property name on instances of classes extending Model. Please choose a different property name for ${this.constructor.toString()}`
);
}
if (
!isDefaultEmptyDescriptor(this, 'currentState') ||
this.get('currentState') !== this._internalModel.currentState
) {
throw new Error(
`'currentState' is a reserved property name on instances of classes extending Model. Please choose a different property name for ${this.constructor.toString()}`
);
}
let idDesc = lookupDescriptor(this, 'id');
if (idDesc.get !== ID_DESCRIPTOR.get) {
throw new EmberError(
`You may not set 'id' as an attribute on your model. Please remove any lines that look like: \`id: attr('<type>')\` from ${this.constructor.toString()}`
);
}
let lifecycleDeprecations = lookupDeprecations(this.constructor);
DEPRECATED_LIFECYCLE_EVENT_METHODS.forEach(methodName => {
if (typeof this[methodName] === 'function' && !lifecycleDeprecations.has(methodName)) {
deprecate(
`You defined a \`${methodName}\` method for ${this.constructor.toString()} but lifecycle events for models have been deprecated.`,
false,
{
id: 'ember-data:record-lifecycle-event-methods',
until: '4.0',
url: 'https://deprecations.emberjs.com/ember-data/v3.x#toc_record-lifecycle-event-methods',
}
);
lifecycleDeprecations.add(methodName);
}
});
},
});
}
Model.reopenClass({
isModel: true,
/**
Create should only ever be called by the store. To create an instance of a
`Model` in a dirty state use `store.createRecord`.
To create instances of `Model` in a clean state, use `store.push`
@method create
@private
@static
*/
/**
Represents the model's class name as a string. This can be used to look up the model's class name through
`Store`'s modelFor method.
`modelName` is generated for you by Ember Data. It will be a lowercased, dasherized string.
For example:
```javascript
store.modelFor('post').modelName; // 'post'
store.modelFor('blog-post').modelName; // 'blog-post'
```
The most common place you'll want to access `modelName` is in your serializer's `payloadKeyFromModelName` method. For example, to change payload
keys to underscore (instead of dasherized), you might use the following code:
```javascript
import RESTSerializer from '@ember-data/serializer/rest';
import { underscore } from '@ember/string';
export default const PostSerializer = RESTSerializer.extend({
payloadKeyFromModelName(modelName) {
return underscore(modelName);
}
});
```
@property modelName
@type String
@readonly
@static
*/
modelName: null,
/*
These class methods below provide relationship
introspection abilities about relationships.
A note about the computed properties contained here:
**These properties are effectively sealed once called for the first time.**
To avoid repeatedly doing expensive iteration over a model's fields, these
values are computed once and then cached for the remainder of the runtime of
your application.
If your application needs to modify a class after its initial definition
(for example, using `reopen()` to add additional attributes), make sure you
do it before using your model with the store, which uses these properties
extensively.
*/
/**
For a given relationship name, returns the model type of the relationship.
For example, if you define a model like this:
```app/models/post.js
import Model, { hasMany } from '@ember-data/model';
export default Model.extend({
comments: hasMany('comment')
});
```
Calling `store.modelFor('post').typeForRelationship('comments', store)` will return `Comment`.
@method typeForRelationship
@static
@param {String} name the name of the relationship
@param {store} store an instance of Store
@return {Model} the type of the relationship, or undefined
*/
typeForRelationship(name, store) {
let relationship = get(this, 'relationshipsByName').get(name);
return relationship && store.modelFor(relationship.type);
},
inverseMap: computed(function() {
return Object.create(null);
}),
/**
Find the relationship which is the inverse of the one asked for.
For example, if you define models like this:
```app/models/post.js
import Model, { hasMany } from '@ember-data/model';
export default Model.extend({
comments: hasMany('message')
});
```
```app/models/message.js
import Model, { belongsTo } from '@ember-data/model';
export default Model.extend({
owner: belongsTo('post')
});
```
``` js
store.modelFor('post').inverseFor('comments', store) // { type: App.Message, name: 'owner', kind: 'belongsTo' }
store.modelFor('message').inverseFor('owner', store) // { type: App.Post, name: 'comments', kind: 'hasMany' }
```
@method inverseFor
@static
@param {String} name the name of the relationship
@param {Store} store
@return {Object} the inverse relationship, or null
*/
inverseFor(name, store) {
let inverseMap = get(this, 'inverseMap');
if (inverseMap[name]) {
return inverseMap[name];
} else {
let inverse = this._findInverseFor(name, store);
inverseMap[name] = inverse;
return inverse;
}
},
//Calculate the inverse, ignoring the cache
_findInverseFor(name, store) {
let inverseType = this.typeForRelationship(name, store);
if (!inverseType) {
return null;
}
let propertyMeta = this.metaForProperty(name);
//If inverse is manually specified to be null, like `comments: hasMany('message', { inverse: null })`
let options = propertyMeta.options;
if (options.inverse === null) {
return null;
}
let inverseName, inverseKind, inverse, inverseOptions;
//If inverse is specified manually, return the inverse
if (options.inverse) {
inverseName = options.inverse;
inverse = get(inverseType, 'relationshipsByName').get(inverseName);
assert(
"We found no inverse relationships by the name of '" +
inverseName +
"' on the '" +
inverseType.modelName +
"' model. This is most likely due to a missing attribute on your model definition.",
!isNone(inverse)
);
// TODO probably just return the whole inverse here
inverseKind = inverse.kind;
inverseOptions = inverse.options;
} else {
//No inverse was specified manually, we need to use a heuristic to guess one
if (propertyMeta.type === propertyMeta.parentModelName) {
warn(
`Detected a reflexive relationship by the name of '${name}' without an inverse option. Look at https://guides.emberjs.com/current/models/relationships/#toc_reflexive-relations for how to explicitly specify inverses.`,
false,
{
id: 'ds.model.reflexive-relationship-without-inverse',
}
);
}
let possibleRelationships = findPossibleInverses(this, inverseType, name);
if (possibleRelationships.length === 0) {
return null;
}
let filteredRelationships = possibleRelationships.filter(possibleRelationship => {
let optionsForRelationship = inverseType.metaForProperty(possibleRelationship.name).options;
return name === optionsForRelationship.inverse;
});
assert(
"You defined the '" +
name +
"' relationship on " +
this +
', but you defined the inverse relationships of type ' +
inverseType.toString() +
' multiple times. Look at https://guides.emberjs.com/current/models/relationships/#toc_explicit-inverses for how to explicitly specify inverses',
filteredRelationships.length < 2
);
if (filteredRelationships.length === 1) {
possibleRelationships = filteredRelationships;
}
assert(
"You defined the '" +
name +
"' relationship on " +
this +
', but multiple possible inverse relationships of type ' +
this +
' were found on ' +
inverseType +
'. Look at https://guides.emberjs.com/current/models/relationships/#toc_explicit-inverses for how to explicitly specify inverses',
possibleRelationships.length === 1
);
inverseName = possibleRelationships[0].name;
inverseKind = possibleRelationships[0].kind;
inverseOptions = possibleRelationships[0].options;
}
assert(
`The ${inverseType.modelName}:${inverseName} relationship declares 'inverse: null', but it was resolved as the inverse for ${this.modelName}:${name}.`,
!inverseOptions || inverseOptions.inverse !== null
);
return {
type: inverseType,
name: inverseName,
kind: inverseKind,
options: inverseOptions,
};
},
/**
The model's relationships as a map, keyed on the type of the
relationship. The value of each entry is an array containing a descriptor
for each relationship with that type, describing the name of the relationship
as well as the type.
For example, given the following model definition:
```app/models/blog.js
import Model, { belongsTo, hasMany } from '@ember-data/model';
export default Model.extend({
users: hasMany('user'),
owner: belongsTo('user'),
posts: hasMany('post')
});
```
This computed property would return a map describing these
relationships, like this:
```javascript
import Ember from 'ember';
import Blog from 'app/models/blog';
import User from 'app/models/user';
import Post from 'app/models/post';
let relationships = Ember.get(Blog, 'relationships');
relationships.get('user');
//=> [ { name: 'users', kind: 'hasMany' },
// { name: 'owner', kind: 'belongsTo' } ]
relationships.get('post');
//=> [ { name: 'posts', kind: 'hasMany' } ]
```
@property relationships
@static
@type Map
@readOnly
*/
relationships: relationshipsDescriptor,
/**
A hash containing lists of the model's relationships, grouped
by the relationship kind. For example, given a model with this
definition:
```app/models/blog.js
import Model, { belongsTo, hasMany } from '@ember-data/model';
export default Model.extend({
users: hasMany('user'),
owner: belongsTo('user'),
posts: hasMany('post')
});
```
This property would contain the following:
```javascript
import Ember from 'ember';
import Blog from 'app/models/blog';
let relationshipNames = Ember.get(Blog, 'relationshipNames');
relationshipNames.hasMany;
//=> ['users', 'posts']
relationshipNames.belongsTo;
//=> ['owner']
```
@property relationshipNames
@static
@type Object
@readOnly
*/
relationshipNames: computed(function() {
let names = {
hasMany: [],
belongsTo: [],
};
this.eachComputedProperty((name, meta) => {
if (meta.isRelationship) {
names[meta.kind].push(name);
}
});
return names;
}),
/**
An array of types directly related to a model. Each type will be
included once, regardless of the number of relationships it has with
the model.
For example, given a model with this definition:
```app/models/blog.js
import Model, { belongsTo, hasMany } from '@ember-data/model';
export default Model.extend({
users: hasMany('user'),
owner: belongsTo('user'),
posts: hasMany('post')
});
```
This property would contain the following:
```javascript
import Ember from 'ember';
import Blog from 'app/models/blog';
let relatedTypes = Ember.get(Blog, 'relatedTypes');
//=> [ User, Post ]
```
@property relatedTypes
@static
@type Ember.Array
@readOnly
*/
relatedTypes: relatedTypesDescriptor,
/**
A map whose keys are the relationships of a model and whose values are
relationship descriptors.
For example, given a model with this
definition:
```app/models/blog.js
import Model, { belongsTo, hasMany } from '@ember-data/model';
export default Model.extend({
users: hasMany('user'),
owner: belongsTo('user'),
posts: hasMany('post')
});
```
This property would contain the following:
```javascript
import Ember from 'ember';
import Blog from 'app/models/blog';
let relationshipsByName = Ember.get(Blog, 'relationshipsByName');
relationshipsByName.get('users');
//=> { key: 'users', kind: 'hasMany', type: 'user', options: Object, isRelationship: true }
relationshipsByName.get('owner');
//=> { key: 'owner', kind: 'belongsTo', type: 'user', options: Object, isRelationship: true }
```
@property relationshipsByName
@static
@type Map
@readOnly
*/
relationshipsByName: relationshipsByNameDescriptor,
relationshipsObject: relationshipsObjectDescriptor,
/**
A map whose keys are the fields of the model and whose values are strings
describing the kind of the field. A model's fields are the union of all of its
attributes and relationships.
For example:
```app/models/blog.js
import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
export default Model.extend({
users: hasMany('user'),
owner: belongsTo('user'),
posts: hasMany('post'),
title: attr('string')
});
```
```js
import Ember from 'ember';
import Blog from 'app/models/blog';
let fields = Ember.get(Blog, 'fields');
fields.forEach(function(kind, field) {
console.log(field, kind);
});
// prints:
// users, hasMany
// owner, belongsTo
// posts, hasMany
// title, attribute
```
@property fields
@static
@type Map
@readOnly
*/
fields: computed(function() {
let map = new Map();
this.eachComputedProperty((name, meta) => {
if (meta.isRelationship) {
map.set(name, meta.kind);
} else if (meta.isAttribute) {
map.set(name, 'attribute');
}
});
return map;
}).readOnly(),
/**
Given a callback, iterates over each of the relationships in the model,
invoking the callback with the name of each relationship and its relationship
descriptor.
@method eachRelationship
@static
@param {Function} callback the callback to invoke
@param {any} binding the value to which the callback's `this` should be bound
*/
eachRelationship(callback, binding) {
get(this, 'relationshipsByName').forEach((relationship, name) => {
callback.call(binding, name, relationship);
});
},
/**
Given a callback, iterates over each of the types related to a model,
invoking the callback with the related type's class. Each type will be
returned just once, regardless of how many different relationships it has
with a model.
@method eachRelatedType
@static
@param {Function} callback the callback to invoke
@param {any} binding the value to which the callback's `this` should be bound
*/
eachRelatedType(callback, binding) {
let relationshipTypes = get(this, 'relatedTypes');
for (let i = 0; i < relationshipTypes.length; i++) {
let type = relationshipTypes[i];
callback.call(binding, type);
}
},
determineRelationshipType(knownSide, store) {
let knownKey = knownSide.key;
let knownKind = knownSide.kind;
let inverse = this.inverseFor(knownKey, store);
// let key;
let otherKind;
if (!inverse) {
return knownKind === 'belongsTo' ? 'oneToNone' : 'manyToNone';
}
// key = inverse.name;
otherKind = inverse.kind;
if (otherKind === 'belongsTo') {
return knownKind === 'belongsTo' ? 'oneToOne' : 'manyToOne';
} else {
return knownKind === 'belongsTo' ? 'oneToMany' : 'manyToMany';
}
},
/**
A map whose keys are the attributes of the model (properties
described by attr) and whose values are the meta object for the
property.
Example
```app/models/person.js
import Model, { attr } from '@ember-data/model';
export default Model.extend({
firstName: attr('string'),
lastName: attr('string'),
birthday: attr('date')
});
```
```javascript
import Ember from 'ember';
import Person from 'app/models/person';
let attributes = Ember.get(Person, 'attributes')
attributes.forEach(function(meta, name) {
console.log(name, meta);
});
// prints:
// firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
// lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
// birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
```
@property attributes
@static
@type {Map}
@readOnly
*/
attributes: computed(function() {
let map = new Map();
this.eachComputedProperty((name, meta) => {
if (meta.isAttribute) {
assert(
"You may not set `id` as an attribute on your model. Please remove any lines that look like: `id: attr('<type>')` from " +
this.toString(),
name !== 'id'
);
meta.name = name;
map.set(name, meta);
}
});
return map;
}).readOnly(),
/**
A map whose keys are the attributes of the model (properties
described by attr) and whose values are type of transformation
applied to each attribute. This map does not include any
attributes that do not have an transformation type.
Example
```app/models/person.js
import Model, { attr } from '@ember-data/model';
export default Model.extend({
firstName: attr(),
lastName: attr('string'),
birthday: attr('date')
});
```
```javascript
import Ember from 'ember';
import Person from 'app/models/person';
let transformedAttributes = Ember.get(Person, 'transformedAttributes')
transformedAttributes.forEach(function(field, type) {
console.log(field, type);
});
// prints:
// lastName string
// birthday date
```
@property transformedAttributes
@static
@type {Map}
@readOnly
*/
transformedAttributes: computed(function() {
let map = new Map();
this.eachAttribute((key, meta) => {
if (meta.type) {
map.set(key, meta.type);
}
});
return map;
}).readOnly(),
/**
Iterates through the attributes of the model, calling the passed function on each
attribute.
The callback method you provide should have the following signature (all
parameters are optional):
```javascript
function(name, meta);
```
- `name` the name of the current property in the iteration
- `meta` the meta object for the attribute property in the iteration
Note that in addition to a callback, you can also pass an optional target
object that will be set as `this` on the context.
Example
```javascript
import Model, { attr } from '@ember-data/model';
let Person = Model.extend({
firstName: attr('string'),
lastName: attr('string'),
birthday: attr('date')
});
Person.eachAttribute(function(name, meta) {
console.log(name, meta);
});
// prints:
// firstName {type: "string", isAttribute: true, options: Object, parentType: function, name: "firstName"}
// lastName {type: "string", isAttribute: true, options: Object, parentType: function, name: "lastName"}
// birthday {type: "date", isAttribute: true, options: Object, parentType: function, name: "birthday"}
```
@method eachAttribute
@param {Function} callback The callback to execute
@param {Object} [binding] the value to which the callback's `this` should be bound
@static
*/
eachAttribute(callback, binding) {
get(this, 'attributes').forEach((meta, name) => {
callback.call(binding, name, meta);
});
},
/**
Iterates through the transformedAttributes of the model, calling
the passed function on each attribute. Note the callback will not be
called for any attributes that do not have an transformation type.
The callback method you provide should have the following signature (all
parameters are optional):
```javascript
function(name, type);
```
- `name` the name of the current property in the iteration
- `type` a string containing the name of the type of transformed
applied to the attribute
Note that in addition to a callback, you can also pass an optional target
object that will be set as `this` on the context.
Example
```javascript
import Model, { attr } from '@ember-data/model';
let Person = Model.extend({
firstName: attr(),
lastName: attr('string'),
birthday: attr('date')
});
Person.eachTransformedAttribute(function(name, type) {
console.log(name, type);
});
// prints:
// lastName string
// birthday date
```
@method eachTransformedAttribute
@param {Function} callback The callback to execute
@param {Object} [binding] the value to which the callback's `this` should be bound
@static
*/
eachTransformedAttribute(callback, binding) {
get(this, 'transformedAttributes').forEach((type, name) => {
callback.call(binding, name, type);
});
},
/**
Returns the name of the model class.
@method toString
@static
*/
toString() {
return `model:${get(this, 'modelName')}`;
},
});
export default Model;


|
EECS 448 Project
3
Spotify Recommendation System
|
Assemble Profile script. More...
Functions | |
| def | Assemble_Profile.dumpSongVectors (vectors) |
| dumpSongVectors More... | |
| def | Assemble_Profile.getSongFeatures (sp, ids) |
| getSongFeatures More... | |
| def | Assemble_Profile.getTracksUserAccount (sp, limit=20, index=0) |
| getTracksUserAccount More... | |
| def | Assemble_Profile.getUserSongVectors (user) |
| getUserSongVectors More... | |
| def | Assemble_Profile.getVectorFromTrack (sp, features, artists) |
| getVectorFromTrack More... | |
Variables | |
| list | Assemble_Profile.labels = ['artists', 'genres', 'popularity', 'acousticness', 'danceability', 'energy', 'instrumentalness', 'key', 'liveness', 'valence'] |
| A human-friendly list of the features in a user/song profile vector. | |
| string | Assemble_Profile.scope = 'user-library-read' |
| Assemble_Profile.user = sys.argv[1] | |
| Assemble_Profile.songs = getUserSongVectors(user) | |
Assemble Profile script.
Prepares a database of song features from track objects on the user's Spotify account. First step in setting up our recommendation system.
This script accesses the user's account and assembles up to the first 1000 songs in their library. From each song, the features we care about are extracted and packed into an easily parsed format in "SongVectors.txt".
Run this script after setting up a Spotify developer account, exporting your credentials to the system path, and setting up Spotipy in a virtual Python environment.
| def Assemble_Profile.dumpSongVectors | ( | vectors | ) |
dumpSongVectors
Write a list of song vectors to file for processing
| vectors | A list of song vectors in the format produced by getVectorFromTrack() |
Steps through the list of song vectors and writes each to SongVectors.txt on its own line. This file represents the "database" of known liked songs for a user, against which we can prepare a user profile and make decisions about new songs. Entries are separated by '###'. Since artists and genres are lists, they are recorded within '{{' '}}' and delimited by ',,'. For example, the list [1,2,3] would be encoded as {{1,,2,,3}}
| def Assemble_Profile.getSongFeatures | ( | sp, | |
| ids | |||
| ) |
getSongFeatures
Get the track data object for each song from a list of song ids
| sp | The handle to the Spotipy wrapper associated with the current user |
| ids | A list of Spotify song ids |
Fetches the full length track object for each of the songs associated with the list of ids passed in.
| def Assemble_Profile.getTracksUserAccount | ( | sp, | |
limit = 20 , |
|||
index = 0 |
|||
| ) |
getTracksUserAccount
Get the user's songs from their library
| sp | The handle to the Spotipy wrapper associated with the current user |
| limit | Optional integer representing the number of tracks to fetch |
| index | Optional integer representing the index into the user's library to begin with |
Fetches up to limit songs from the user's saved songs library, beginning at the index indicated.
| def Assemble_Profile.getUserSongVectors | ( | user | ) |
getUserSongVectors
Assembles a list of song vectors for a user
| user | The spotify username of the user to fetch songs from |
Steps through the first 100 songs of the user passed in, preparing a song vector for each and aggregating the results into a list. If the user does not have enough songs, or if some other errors are preventing the API calls from completing, the method will abandon its task after 3 failures
| def Assemble_Profile.getVectorFromTrack | ( | sp, | |
| features, | |||
| artists | |||
| ) |
getVectorFromTrack
Assembles a vector of feature values for a track
| sp | The handle to the Spotipy wrapper associated with the current user |
| features | A Spotify feature object associated with the track in question |
| artists | A list of Spotify artist objects that are associated with the track in question |
A vector of features that our app cares about is assembled from the multitude of information in the Spotify objects. The features passed in include a number of qualities curated by Spotify to classify a song with. The artist(s) that are associated with the song in question each provide contributions to a list of artist names, a list of genres, and an integer representing overall popularity rating. This popularity is averaged (to account for weird collaborations).


Tutorial¶
sed_eval
– Evaluation toolbox for Sound Event Detection¶
The structure of the sed_eval
toolbox is as follows:
- For evaluating the sound event detection system (SED system later), there are two types of metrics available: segment-based and event-based. For both types, there is a metric class
SegmentBasedMetrics
andEventBasedMetrics
. A member functionevaluate()
is used to go through system output (estimated event list) and ground truth (reference event list) pairs. Theresults()
function is used to get the metric values in dictionary. There are also functions to return results as a formatted string for convenience (e.g.result_report_overall()
), or one can just print class instance. - For evaluating the acoustic scene classification system, there is similar evaluation class,
SceneClassificationMetrics
, as for SED system evaluation.
sed_eval
also includes the following additional submodules:
io
which contains convenience functions for loading annotationsutil
which includes miscellaneous functions to handle event lists (list of event items), event roll (event activity indicator matrix used in evaluation), and scene list.
Quickstart: Using the evaluators¶
The easiest way to evaluate systems with sed_eval
is to use provided evaluators.
Evaluators are Python scripts which can be run from the command prompt and utilize sed_eval
to compute metrics
according to reference and estimated annotations you provide.
To use the evaluators, you must first install sed_eval
and its dependencies (see Getting started).
The evaluator scripts can be found in the sed_eval
repository in the evaluators
folder:
https://github.com/TUT-ARG/sed_eval/tree/master/evaluators
Currently there are two evaluators available, one for evaluating the sound event detection systems and one for evaluating acoustic scene classification systems.
Sound event detection¶
To get usage help:
./sound_event_eval.py --help
Evaluator takes as argument a csv-formatted file-list. The list contains pairs of filenames, one pair per row: first the filename of the reference event list
file and the second the estimated event list file. Format is [reference_file][delimiter][estimated_file], and supported delimiters are ,
, ;
, tab
.
Example of file-list:
office_snr0_high_v2.txt office_snr0_high_v2_detected.txt
office_snr0_med_v2.txt office_snr0_med_v2_detected.txt
Event list is csv-formatted text-file. Supported formats for the file are:
- [event onset (float >= 0)][delimiter][event offset (float >= 0)]
- [event onset (float >= 0)][delimiter][event offset (float >= 0)][delimiter][label]
- [filename][delimiter][scene_label][delimiter][event onset (float >= 0)][delimiter][event offset (float >= 0)][delimiter][event label]
Supported delimiters: ,
, ;
, tab
Example of event list file:
21.64715 23.00552 alert
36.91184 38.27021 alert
69.72575 71.09029 alert
63.53990 64.89827 alert
84.25553 84.83920 alert
20.92974 21.82661 clearthroat
28.39992 29.29679 clearthroat
80.47837 81.95937 clearthroat
44.48363 45.96463 clearthroat
78.13073 79.05953 clearthroat
15.17031 16.27235 cough
20.54931 21.65135 cough
27.79964 28.90168 cough
75.45959 76.32490 cough
70.81708 71.91912 cough
21.23203 22.55902 doorslam
7.546220 9.014880 doorslam
34.11303 35.04183 doorslam
45.86001 47.32867 doorslam
To get segment-based and event-based metrics report printed, run:
./sound_event_eval.py file_list.txt
To get segment-based and event-based metrics saved in YAML-format, run:
./sound_event_eval.py file_list.txt -o results.yaml
Acoustic scene classification¶
./scene_eval.py --help
Evaluator takes as argument a csv-formatted file-list. The list contains pairs of filenames, one pair per row: first the filename of the reference scene list
file and the second the estimated scene list file. Format is [reference_file][delimiter][estimated_file], and supported delimiters are ,
, ;
, tab
.
Example of file-list:
fold1_reference.txt fold1_estimated.txt
fold2_reference.txt fold2_estimated.txt
fold3_reference.txt fold3_estimated.txt
fold4_reference.txt fold4_estimated.txt
fold5_reference.txt fold5_estimated.txt
Scene list is csv-formatted text-file. Supported formats for the file are:
- [filename][delimiter][scene label]
- [filename][delimiter][segment start (float >= 0)][delimiter][segment stop (float >= 0)][delimiter][scene label]
Supported delimiters: ,
, ;
, tab
Example of scene list file:
scenes_stereo/supermarket09.wav supermarket
scenes_stereo/tubestation10.wav tubestation
scenes_stereo/quietstreet08.wav quietstreet
scenes_stereo/restaurant05.wav restaurant
scenes_stereo/busystreet05.wav busystreet
scenes_stereo/openairmarket04.wav openairmarket
scenes_stereo/quietstreet01.wav quietstreet
scenes_stereo/supermarket05.wav supermarket
scenes_stereo/openairmarket01.wav openairmarket
To get metrics printed, run:
./scene_eval.py file_list.txt
To get metrics saved in YAML-format, run:
./scene_eval.py file_list.txt -o results.yaml
Quickstart: Using sed_eval
in Python code¶
After sed_eval
is installed (see Getting started), it can be imported to your Python code as follows:
import sed_eval
Sound event detection¶
Usage example to evaluate files:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | import sed_eval
file_list = [
{
'reference_file': 'office_snr0_high_v2.txt',
'estimated_file': 'office_snr0_high_out.txt'
},
{
'reference_file': 'office_snr0_low_v2.txt',
'estimated_file': 'office_snr0_low_out.txt'
},
{
'reference_file': 'office_snr0_med_v2.txt',
'estimated_file': 'office_snr0_med_out.txt'
},
{
'reference_file': 'office_snr-6_high_v2.txt',
'estimated_file': 'office_snr-6_high_out.txt'
}
]
data = []
# Get used event labels
all_data = sed_eval.util.event_list.EventList()
for file_pair in file_list:
reference_event_list = sed_eval.io.load_event_list(file_pair['reference_file'])
estimated_event_list = sed_eval.io.load_event_list(file_pair['estimated_file'])
data.append({'reference_event_list': reference_event_list,
'estimated_event_list': estimated_event_list})
all_data += reference_event_list
event_labels = all_data.unique_event_labels
# Start evaluating
# Create metrics classes, define parameters
segment_based_metrics = sed_eval.sound_event.SegmentBasedMetrics(event_label_list=event_labels,
time_resolution=1)
event_based_metrics = sed_eval.sound_event.EventBasedMetrics(event_label_list=event_labels,
t_collar=0.250)
# Go through files
for file_pair in data:
segment_based_metrics.evaluate(file_pair['reference_event_list'],
file_pair['estimated_event_list'])
event_based_metrics.evaluate(file_pair['reference_event_list'],
file_pair['estimated_event_list'])
# Get only certain metrics
overall_segment_based_metrics = segment_based_metrics.results_overall_metrics()
print "Accuracy:", overall_segment_based_metrics['accuracy']['accuracy']
# Or print all metrics as reports
print segment_based_metrics
print event_based_metrics
|
Acoustic scene classification¶
Usage example to evaluate files:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | import sed_eval
file_list = [
{'reference_file': 'fold1_reference.txt', 'estimated_file': 'fold1_estimated.txt'},
{'reference_file': 'fold2_reference.txt', 'estimated_file': 'fold2_estimated.txt'},
{'reference_file': 'fold3_reference.txt', 'estimated_file': 'fold3_estimated.txt'},
{'reference_file': 'fold4_reference.txt', 'estimated_file': 'fold4_estimated.txt'},
{'reference_file': 'fold5_reference.txt', 'estimated_file': 'fold5_estimated.txt'},
]
data = []
# Get used scene labels
all_data = []
for file_pair in file_list:
reference_scene_list = sed_eval.io.load_scene_list(file_pair['reference_file'])
estimated_scene_list = sed_eval.io.load_scene_list(file_pair['estimated_file'])
data.append({'reference_scene_list': reference_scene_list,
'estimated_scene_list': estimated_scene_list})
all_data += reference_scene_list
scene_labels = sed_eval.sound_event.util.unique_scene_labels(all_data)
# Create metrics class
scene_metrics = sed_eval.scene.SceneClassificationMetrics(scene_labels)
for file_pair in data:
scene_metrics.evaluate(file_pair['reference_scene_list'],
file_pair['estimated_scene_list'])
# Get only certain metrics
overall_metrics_results = scene_metrics.results_overall_metrics()
print "Accuracy:", overall_metrics_results['accuracy']
# Or print all metrics as reports
print scene_metrics
|


24 hour Competition
As well as films from world-class talent, we will be putting on a competition for filmmakers in Lewes. This is a great opportunity to hone your creativity and show the world what you can do. Further details below:
- Brighton Film School will offer a £100 prize to the winning team of this challenge
- Registration of two person crews and payment of £10 entrance fee (£5 for students) should be done in advance. Please register before the 5th of October online at the bottom of this page. It is possible to register on the day at The Depot as well, but please arrive promptly and ensure you the entrance fee.
- Production meeting at 8pm on Friday the 6th of October in Lewes, with the competition commencing immediately after the meeting. The venue is the Studio in The Depot. The production meeting will include briefing of the project and we will issue an information pack.
- At the end of the competition, films should be uploaded via We Transfer to the festival email link by 8pm on Saturday the 7th of October
- The selected films will be screened on Sunday the 15th October with two free tickets for each selected crew
- Crews are suggested to use the Straight 8 app, as well as any camera of choice and edited using whatever editing software available to the filmmaker.
- The film may be either a drama, a documentary or experimental
- The competition will be judged by Brighton Film School
Do's and Don'ts
- No use of profanities (swearing), use of imitation weapons, copyright music, photos, or film/TV clips
- Running length not to exceed 3 minutes/180 seconds including titles and credits
- Crews are responsible for their own safety and that of the public
- The film must be delivered in H264 format
- Sound may be recorded in camera or by using an external mic; alternatively it can be added in post-production.
Competition Judges
Dylan Howitt
Director of the recent feature documentary 'Out of Thin Air' for BBC Storyville
Michele D'Acosta
Producer of 'Biggie & Tupac', 'Kurt & Courtney' and Blur's 'Nowhere Left to Run'
Artist, Storyteller and Producer


Help Us Transform Lives...
These are stressful times for families facing challenges, former foster children who no longer have a place to call home, and anyone overcoming susbtance abuse and mental health issues.
Thankfully, our Case Managers help clients navigate the challenges of launching into "independence". Not only do we help people get on track and surmount incredible odds, we also make sure they have resources to turn to in the future. One key to success is the ongoing trusting relationships that continue long after people have "completed" a program.
Your donation today helps make the difference between offering a temporary safety net and transforming a life.
Please join us by clicking the "donate" button to make a secure donation through PayPal, or mail a check to StarVista, 610 Elm Street, Suite 212, San Carlos, CA 94070. Thank you!


Gecode::IntVarArgs Class Reference
[Argument arrays]
Passing integer variables. More...
#include <int.hh>
Constructors and initialization | |
|
| |
| IntVarArgs (void) | |
| Allocate empty array. | |
| IntVarArgs (int n) | |
| Allocate array with n elements. | |
| IntVarArgs (const IntVarArgs &a) | |
| Initialize from variable argument array a (copy elements). | |
| IntVarArgs (const VarArray< IntVar > &a) | |
| Initialize from variable array a (copy elements). | |
| IntVarArgs (const std::vector< IntVar > &a) | |
| Initialize from vector a. | |
| template<class InputIterator > | |
| IntVarArgs (InputIterator first, InputIterator last) | |
| Initialize from InputIterator first and last. | |
| IntVarArgs (Space &home, int n, int min, int max) | |
| Initialize array with n new variables. | |
| IntVarArgs (Space &home, int n, const IntSet &s) | |
| Initialize array with n new variables. |
Detailed Description
Passing integer variables.
Definition at line 636 of file int.hh.
Constructor & Destructor Documentation
| Gecode::IntVarArgs::IntVarArgs | ( | void | ) | [inline] |
| Gecode::IntVarArgs::IntVarArgs | ( | int | n | ) | [inline, explicit] |
| Gecode::IntVarArgs::IntVarArgs | ( | const IntVarArgs & | a | ) | [inline] |
| Gecode::IntVarArgs::IntVarArgs | ( | const std::vector< IntVar > & | a | ) | [inline] |
template<class InputIterator >
| Gecode::IntVarArgs::IntVarArgs | ( | InputIterator | first, | |
| InputIterator | last | |||
| ) | [inline] |
| Gecode::IntVarArgs::IntVarArgs | ( | Space & | home, | |
| int | n, | |||
| int | min, | |||
| int | max | |||
| ) |
Initialize array with n new variables.
The variables are created with a domain ranging from min to max. The following execptions might be thrown:
- If min is greater than max, an exception of type Gecode::Int::VariableEmptyDomain is thrown.
- If min or max exceed the limits for integers as defined in Gecode::Int::Limits, an exception of type Gecode::Int::OutOfLimits is thrown.
Initialize array with n new variables.
The variables are created with a domain described by s. The following execptions might be thrown:
- If s is empty, an exception of type Gecode::Int::VariableEmptyDomain is thrown.
- If s contains values that exceed the limits for integers as defined in Gecode::Int::Limits, an exception of type Gecode::Int::OutOfLimits is thrown.
The documentation for this class was generated from the following files:
- gecode/int.hh (Revision: 14362)
- gecode/int/array.cpp (Revision: 11440)


{% extends "blogengine/includes/base.html" %} {% load custom_markdown %} {% block headercontent %}
Hello my name is Eric Shi and I'm currently serving as the 'A' society director for the Waterloo Engineering Endowment Foundation (WEEF). My term will last 16 months starting September 2015. I am working on improving the infrastructure WEEF has and if you are an undergraduate engineering student at the University of Waterloo and would like to help, please send me an email.
• Backend PHP and SQL work
• Front end and user interface design
• Implementation of feedback and proposal system changes
• Following up on funded proposals and getting up to date media for WEEF
• Generate up to date WEEF info-graphics to be shown online and in posters in CPH
• Engage engineering departments about labs and courses that would most benefit from new equipment or educational resources
• Collect feedback from students about which labs could use new equipment
• Engage lab instructors about where funding could benefit an undergraduate course
Please send me a email if you have any questions, suggestions, concerns. I'd like to hear from you.


EuroSciPy: past talks
Multicore, cluster, parallel computing
- PyFR: Heterogeneous Computing on Mixed Unstructured Grids [F. Witherden, M. Klemm, P. Vincent, 2015]
- Massively parallel pseudo-spectral DNS code for turbulent flows [M. Mortensen, 2015]
- Tricks for efficient multicore computing [O. Grisel, 2017]
Range of scientific disciplines
- Space mission design with Python [H. Eichhorn, 2015]
- Want drugs? Use Python [M. Nowotka, 2015]
- A global approach to muscle modeling with Python [J. Laforet, 2016]
- Real-time Crowd-sourced Detection of Earthquakes [R. Steed, 2017]
EuroSciPy: past talks
Data science and machine learning
- Data cleaning on text to prepare for analysis and machine learning [I. Osvald, 2015]
- FluRS - A Library for Streaming Recommendation Algorithms [T. Kitazawa, 2017]
- Deep Learning for Fraud Detection [V. Maggio, 2017]
Visualisation
- Veusz: a scientific plotting package [J. Sanders, 2016]
- Interactive 3D Visualization in Jupyter Notebooks [V. T. Fauske, 2017]
Memory, wrappers and compilers
- klepto: unified persistent storage to memory, disk, or database [M. McKerns, 2015]
- AutoWIG: Wrapping very large C++ libraries in Python automatically [P. Fernique, 2017]
- Introduction into the ppci project [W. Bouwen, 2017]
Jupyter Notebook tools
- Nbdime - Notebook diffing and merging [V. T. Fauske, 2016]
- nbval - Testing your notebooks [T. Kluyver, 2017]


Shadow is released from prison only to find out his wife had been cheating on him and was killed in a car accident. On his way to the funeral, Shadow meets Mr. Wednesday and takes a job as his bodyguard. This leads Shadow into the other side of America, where the old gods are real and are making their last stand against the gods of today.
Just a few of the gods to make appearances in the book are the Egyptian goddess Bast, Loki, Anansi from African folklore, and Czernbobg the Slavic god of darkness. In the world of American Gods if people believe in a god they become real. Basically, the gods are inside us. There are many incarnations of each god across the world, Anansi came to America from Africa with the slaves, and the Norse gods were “carried” in the minds of the Vikings and came to America when they first discover the continent. Because of this new gods are being born, Media, the Internet, and Money are all being created by modern people’s desires.
The conflict of the book comes from the new gods wanting supremacy and to destroy the old gods. As the old gods lose followers they become more marginal and less powerful. Most of the gods encountered by Shadow seem like your eccentric neighbor, they live in apartment complexes and work day jobs. Thoth, the Ancient Egyptian god of knowledge runs a funeral parlor in Cairo, Illinois. Though Shadows travels with Mr. Wednesday, we see how gods live and become attached to them, they are more like our crazy aunt than all powerful deities. We want the old gods to win, they are the underdogs and have more personality than the gods of today.
Overall, I love American Gods it is the first book I read by Neil Gaiman who has become my favorite author. I think the book brings up interesting ideas of what gods are and what is important in our lives today. It is fun to look up the characters and find out about new religions and beliefs from around the world.
Cyberpunk is within the realm of science fiction and is primarily about living in a world with advanced technology but low living standards. Hiro Protagonist the hero and protagonist of the book is one of the creators of the Metaverse, a wildly popular virtual reality world, but even will his success he lives in a storage unit. Hiro discovers a pseudo-narcotic while in the Metaverse named “Snow Crash” that can affect users in the real world. This leads Hiro on a trail that takes him through ancient Sumerian culture, linguistics, and computer viruses that make the user sick.
The language of Snow Crash is a mix of steam of consciousness and hacker speak. I have laughed out loud while reading this book and the first chapter sets the tone for the rest of the book. An interesting aspect of the book is that America has fallen to corporations and individual entrepreneurs. A Chinese food mogul and the Mafia own sovereign land which operates under its own laws. There is no unifying government anymore, each area is owned and operated differently from the next and requires proper documentation to move between the enclaves. It felt like reading a post-apocalyptic novel how everything was so broken and lawless. Our hero, Hiro, encounters citizens of a white supremacist enclave who legally try to murder him for being half Korean and half Black.
The main focus of Snow Crash is how our brain stem is like a computers BIOS. We are programmed by language to act and think certain ways. The Snow Crash virus is a program that uses ancient Sumerian language to reprogram the human brain. The whole second half of the book breaks down Sumerian history and religion. A main idea brought up is that religion is a virus, it is an idea that clings to a person’s brain and is replicated throughout a population. Computers become a metaphor for human lives.
This is another book I read about once a year, it’s a fun adventure that makes me think about culture, computers, and religion.
This novel takes place in a world similar but vastly different to our own, where humans exist alongside insect-like people, bird people, even humanoid cacti, and science and magic bleed together. Isaac (our hero) is asked by a bird creature to help regain his ability for flight after his wings were violently cut off. While trying to help Yagharek (the bird man) a giant dream eating moth attacks the city leaving those affected braindead vegetables. Isaac becomes interwoven into the intrigue of where the moth came from and takes it upon himself to eradicate it after his girlfriend is kidnapped by the man who released it into the world.
Overall, this was a great read with lots of science, magic, adventure, and mystery. China has an unusual writing style that takes some getting used to, but after the first chapter you hardly notice. I liked reading about all the different types of characters and wondering how they all evolved and came to be mostly bipedal humanoids that understand English. Could a world really exist in which sentient cacti coexist with a multi-dimensional giant spider being?
One example of a race in Perdido Street Station are the Khepri.  They cannot speak and instead use sign language and pheromones to communicate. The male Khepri are like traditional insects; they have no human level intelligence and are mainly used to reproduce. How is it possible for two completely different species to evolve and look identical with one exception? There is never any mention throughout the book as to where the different races come from, be it space or greatly isolated land masses.
China Mieville has written two other books that fit into a loose series with Perdido Street Station each highlighting other races and exploring different regions. All of China’s books are very well written, descriptive, and look into the underworld of wherever the characters live. I would definitely give any of his books a chance.


The time.Time.Format and
time.Parse functions expect a layout as first parameter.
This layout doesn't consist in initials (Y, M, D...). It is actually the desired formatted string of the reference time
Mon Jan 2 15:04:05 -0700 MST 2006
(equals to Unix time<PHONE_NUMBER>
),
and it is not the value of the input date.
Although useful, this convention is a difficulty for beginners.


CREATE NEW INCIDENT
Search for the Incident you want to EDIT using the parameters
provided.
You can only edit the DESCRIPTION or LOCATION!
Enter the parameters of the incident you want to DELETE.
CAUTION! THIS ACTION CANNOT BE UNDONE!


Basic concepts¶
Common terms¶
repository: where the source code is
remote (cloud) and local (machine)
clone: create a local copy of a remote repository
fetch: identify existing changes in the remote repository
merge: combine changes from different versions
pull: identify the changes and combine (fetch + merge)
add: add your local changes to a pile of changes
commit: create a timestamp for the changes in the pile
push: send the commits from local to remote repository
branch: a copy from your code that has an independent timeline
stash: group of changes detached from the branch
pull request: request to incorporate a specific branch to the main repository


These hilarious memes show off Pokémon Sword and Shield's creative fan base
Source: iMore
From the moment Pokémon Sword and Shield were announced, the games had an interesting presence on the internet. Pokémon's divided fan base was quick to create some of the most hilarious memes and GIFs to mark Pokémon reveals, leaks, disappointments, and anticipation. Whether you love the games or hate them, here are some of the best Pokémon Sword and Shield memes that are sure to make you laugh. Many of these will be more enjoyable with sound on.
Those who tried to resist
With the reveal of Dexit, many people claimed they'd be boycotting Pokémon Sword and Shield. However, the lure of a core Pokémon game on console was too hard for many ro resist. Heck, I know several people who bought a Switch solely for Sword and Shield.
Pokemon Sword and Shield from pokemon
A sentiment most Pokémon fans can agree with
I got freaking excited when I first saw Yamper.
When the new Pokémon leaked
I know many people who claimed they didn't want to know anything about the new Pokémon games before they released. That all seemed to change when several of the new Pokémon designs leaked a week early.
Creepy Pokémon
Since Red and Blue, there have always been creepy Pokémon in the franchise. Hatterne is yet another one of these creatures that we'd never want to see in the real world.
Getting pumped up for a gym battle like
You've searched hard, trained hard, and made your way to the gym. Now you get to prove your stuff!
Pokémon with character
Pokémon Camp has provided a new way to interact with your favorite Pokémon. The fun thing is you never quite know how your specific Pokémon will react.
Bad Pokémon!
Yet another example of the strange and fun things you can find in the Pokémon Camp. Poor Togepi.
Getting a little heavy
This is funny in a macabre sort of way. Even Pokémon is weighing in on the decline of nature.
Demonic Pikachu
Nothing sounds more terrifying or more comical than a Gigantamax Pikachu. I'm not sure if it wants to eat my soul or if it needs to use the bathroom.
The true jungle king
The role of resident Nintendo monkey percussionist has already been taken. I can't believe someone took the time to make this. 🤣
Trading a Pokémon's soul
When you trade a Pokémon away it can be an emotional experience. Although, this particular trainer must really regret their decision.
A little too similar . . .
Those curly, light-colored locks and that sassy attitude kinda seem a little too similar. Once seen, you can't unsee it.
Running for dear life
Seeing Pokémon in the Wild Area can be a frightening experience, especially if that Pokémon is several levels higher than you. Your only option is to run for the hills!
Gotta see 'em all!
Due to the creativity of the internet we're sure there are hundreds of additional funny memes out there. If you see any that we should have added to our list tell us about it in the comments. At any rate, I hope these gave you a chuckle or two. If you're currently playing the games, good luck on your Pokémon quest!
Canine protector
Pokémon Sword
More Pokémon to catch
Trainers travel the Galar region capturing new Pokémon, defeating new gyms, and proving that they are the best Pokémon trainers of them all.
Wolf guard
Pokémon Shield
A new adventure awaits
You'll explore a new U.K.-inspired land filled with new experiences, new Pokémon, and new gyms to defeat. See how many Pokémon you can catch.
Pokémon Sword and Shield
Main
- How to catch and evolve Eevee
- How to catch shiny Pokémon
- Differences between Sword and Shield
- All version exclusive Pokémon
- Can you use Pokémon Bank with Sword and Shield?
- How to evolve Toxel
- How to catch Noibat
- How to catch Galarian Ponyta
- How to evolve Milcery into Alcremie
We may earn a commission for purchases using our links. Learn more.


---
layout: post
title: Bloom | Pogo
date: '2014-02-07T08:51:32-08:00'
tags:
- pogo
- music
- disney
- fromtheinternet
tumblr_url: http://beekley.xyz/post/75906675115/bloom-pogo
---
Bloom | Pogo
This is the video for my track ‘Bloom’, a patchwork of vocals and musical chords from various Disney films. I recorded the harp sample from 'Sleeping Beauty’…


Why join us?
Semple! because we represent the most important university of our time!
Our teachers
Our teachers boast extraordinary curriculum !
Our certifications
Anyone who gets certifications in our university becomes demanded all over the world!
+500 Audio lessons
You can follow our lessons , even from miles away !
+1.200 Video lessons
You can also follow video lessons , this alows anyone to have better explanation!


@* * Copyright 2019 HM Revenue & Customs * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *@ @import uk.gov.hmrc.tariffclassificationfrontend.controllers.routes.{CaseController, CompleteCaseController} @import uk.gov.hmrc.tariffclassificationfrontend.config.AppConfig @import uk.gov.hmrc.tariffclassificationfrontend.models.{BTIApplication, Case} @import uk.gov.hmrc.tariffclassificationfrontend.views.html.includes.main @import uk.gov.hmrc.tariffclassificationfrontend.views.html.partials.case_heading @import views.html.helper.{CSRF, form} @(c: Case)(implicit request: Request[_], messages: Messages, appConfig: AppConfig) @main(bodyClasses = None, customTitle = Some(messages("page.title.complete.case"))) { @defining(c.application.asBTI) { btiApp: BTIApplication => @case_heading(c)
Completing this case will generate a BTI certificate, valid for @{appConfig.decisionLifetimeYears} years from today.
This certificate will be available to the applicant on their listed rulings page.
The ruling will also be published on the public rulings website.
An email will be automatically sent to the applicant, notifying them of the publication of the ruling.
@form(action = CompleteCaseController.postCompleteCase(c.reference), 'class -> "form") { @CSRF.formField Cancel }


mitochondrial protein transcripts codon soluble membrane Codon position strand Figure pos. proteins ribosomal NC_] genes pyrimidine genome {border-style human pyrimidine-purine species px;} walks #ffffff;} DNA signal RNA walk Table mtDNA purine purine-rich shown transcript genomes positions pyrimidine-rich abundance transcripts. rRNA Mitochondrial amino encode encoded proteins, sequences (see Arabidopsis Rule content file gene hydrophobic light px; {font-family Biol Chondrus Dictyostelium Mol acids additional algae driven font-size mitochondrial-encoded nucleotides origin protein-coding proteins. purine-rich. richness slightly analysis correlation crispus does double; encodes entire eukaryotic hydrophobicity large nucleotide oxidative rules selective similar small transcripts, (Figure However, Marchantia Porphyra base border-color border-width composition contain follow genes. likely low mRNA mtDNA-encoded mtDNA. pattern phosphorylation pressure purines replication second solid; species. strand. structure tRNAs versus {font-style {font-weight (-) (C) Biophys Chlamydomonas Evol Figures GRAVY Gene Pyrimidine-purine Soluble bold code conserved courier; data different diverse em; evolution genes, humans hydrophilic loop mainly mammalian mammals mitochondria nuclear overall percent percentage pressures pt;} purine-richness regions relative residues section seen species, strong tRNA thaliana walks.


Cheese Hamburger
Cheese Hambuerger with meat, tomatoes and a lot of delicious cheese.
3.99 USD$
★★★★☆ | 47 reviews
Cheese Hamburger
Cheese Hambuerger with meat, tomatoes and a lot of delicious cheese.
3.99 USD$
★★★★☆ | 47 reviews
Name
Email
Comments


Dropshadows. Yikes. What was I thinking. I had actually just read a design blog article about dropshadows and wanted to test them out, so there we go. It's not pretty, that's for sure. I was curious to explore having the bottom row of content as the longest, as I wanted to see if it detracts from the hierarchy of the design, and I do think it does. The way I've centered my div items on my portfolio page works much better I think. But the delineation between layers of content (boxes for each item, lines to indicate the next row, and of course those wonderful dropshadows to let you know that this is a 3D object) work well to offer different layers of content.


Manage Pokémon© TCG or VGC tournaments right now.
INCOMING!
Load ← currently does nothing.
Fields with a * are mandatory.
Load a players.xml file to get more players from your existing TOM, or Save the actual list.
| Player id | First name | Last name | Birth date | Age division | To edit or remove a player, select the player's line, then click on Edit or Remove. |
|---|
| Player id | First name | Last name | Birth date | Age division | There are currently 0 players: 0 Juniors, 0 Seniors and 0 Masters. |
|---|


--- layout: page ---
I am an educator looking to innovate new ways of integrating education with Human-Computer Interactions. I have earned a B.Sc in Mechanical Engineering from California State University Northridge in 2015. I have also earned a M.Sc in Physics from CSU Northridge in 2019. I am presently aiming for a PhD within a related field that will help integrate and promote educational research and development through technology. I think this is achievable through the integration of visualization and Human-Computer Interaction. I also have interests in neural networks, quantum computing, philosophy, biology, chemistry, astronomy, and everything from the invisibly small to the unfathomably large.


Match Play. DMP. How should Red play 53?
pips Red=93 White=140
(CorrectAnswer= 0/0, ErrorScore= 0)
When playing against a back game the key is to clear points and not try to maintain a block.
6/1, 4/1 and 9/1 would both be bad mistakes. The correct play is 7/4, 7/2 getting rid of the bar-point. Now all Red needs to do is clear his 9-pt. He can’t play sixes except 61 and 62 and he has plenty of spare fours and fives.
After 7/4, 7/2 Red will the game 70% of the time.
6/1, 4/1 and 9/1 would both be bad mistakes. The correct play is 7/4, 7/2 getting rid of the bar-point. Now all Red needs to do is clear his 9-pt. He can’t play sixes except 61 and 62 and he has plenty of spare fours and fives.
After 7/4, 7/2 Red will the game 70% of the time.
1. Cubeful 2-ply 7/4 7/2 Eq.: +0.414 0.707 0.113 0.002 - 0.293 0.022 0.000 2. Cubeful 2-ply 9/1 Eq.: +0.383 (-0.031) 0.692 0.112 0.002 - 0.308 0.034 0.000 3. Cubeful 2-ply 6/1 4/1 Eq.: +0.373 (-0.042) 0.686 0.109 0.001 - 0.314 0.032 0.000 4. Cubeful 0-ply 7/2 4/1 Eq.: -0.035 (-0.450) 0.482 0.115 0.003 - 0.518 0.127 0.004 5. Cubeful 0-ply 7/4 6/1 Eq.: -0.043 (-0.458) 0.478 0.110 0.003 - 0.522 0.122 0.003


1
{{ .Task.ProjectOptions.LabelType }}
{{ .Task.ProjectOptions.ItemType }}
? Toggle Keyboard Usage display
Esc Deselect label
Backspace / delete Delete selected label
+ Zoom in
- Zoom out
← Previous item
→ Next item
↑ Bring a selected label forward
f Bring a selected label to front
↓ Bring a selected label backward
b Bring a selected label to back
u Unlink selected label
c When hovering over midpoint, change the edge to bezier curve
s Toggle on/off quick draw mode
Alt Toggle path options along a polygon during quick draw mode


{% extends "frontend/base.html" %} {% block content %}
You need to add some devices or slideshow/streams first!


DBC-Cultural Blog:
Date: 07.26.15
Entry #: 2
Commentary:
Today's blog post I wanted to focus in on the Gregorc's Thinking Style; mine particularly said I was a Concrete Sequential style of thinker. What that means essentially is I like order and facts and dislike situations where discussion revolve around no particular point -I am systematic, if you will. With that said, I realize my experience at DBC will be extremely difficult unless I learn to accept that not everything will be in order, there will be times that things cannot be predictable and rather than to panic, I'd better start preparing myself for such said situations. How? you may ask? Well I plan on peer-pairing more often so I can get used to things not working in the way *I* intend on always -exposing myself to others' ideas more rather than single-handidly relying on mine alone.Growth vs. Fixed Mindset: The best way I can put it is do you have the personality/mindset which will put up a guard/ego and avoid foreign situations? Or do you have the mindset where you're up for challenges with a positive outlook determined to accomplish a set goal? I've always looked at myself as a very positive person -despite some very negative situations I've faced in my life. Being open, honest, accetping of constructive criticism, and seeking help when help is needed are all qualities that allow for intelligence to expand.
Reflection: So tomorrow marks my 4th week in Phase 0 at Dev BootCamp -wow, has it really been that long?!? Time really flew and the amount of information that has entered my brain and hasn't ooozed out of my ears is plentiful, almost unbelieveable given the short-time frame in which it was shoved in. I've learned a lot about shortcuts (not only for the command line/Sublime) but also for methods and how to go about solving the same problem with much fewer lines of code. A problem that I faced was regarding the aforementioned information leak from my brain; there were instances where I completely blanked on simple code as I thought far too deep about it and made it more complicated than it needed to be. It was then when I had realized that repetition is really the only way all of this information will stick -and even then, using resources was going to become a regular task.


Make sure all flexboxes have the same number of children. If you don't, content of flexbox will bleed to the next.
A better alternative if every box needs a different number of children.


Vegemite Launches Personalised Care Packages To Gift Yr Overseas Mates This Chrissy
by By PEDESTRIAN.TVVegemite has announced their new ‘Mitey Aussie Care Packages’ which can be personalised and gifted to your overseas mates this Christmas. This is surely the greatest way to earn some brownie points with your fellow expats.
“We know that our VEGE-Mates living overseas are missing the taste of Australia, especially around Christmas time, and we’re delighted to now ship Vegemite internationally,” Senior Vegemite Marketing Manager Matt Gray said in a press release.
The ‘Mitey Aussie Care Package’ – pictured below – includes a personalised 380g Vegemite Jar, socks, a mug, 220g Vegemite Jar and Arnott’s Shapes Vegemite & Cheese.
The package itself is AU $49.95, plus between $15-30 for postage if you’re shipping to a pal over New Zealand, Canada, US, UK.
The ‘Mitey Aussie Care Package’ is available for purchase via their online store. You can grab your own package for a mate now until midnight on Friday 13 December (ominous day but, whatever, don’t mind my superstitions) or until stocks last.
‘Straya.


"Erin Brockovich"
reviewed by Eric Grossman
Copyright Eric Grossman 2000
Despite being based on true events (key word there is based), "Erin Brockovich" isn't about a story, it's a star vehicle. Ostensibly, the film is about people having their water polluted by an evil corporation. A well-endowed, twice-divorced mom named Erin Brockovich (Julia Roberts), comes to their rescue by digging up the dirt on this corporation and then she gives her eunuch of a boss, a lawyer named Ed Masry (Albert Finney), the cajones to go after them. As David Spade might say, I liked this movie more when it was called, "A Civil Action," or "Silkwood" for that matter.
The film, which was directed by Steven Soderbergh, the man who helped put independent film on the radar, is so irritating that I wanted to throw something at the screen. Unfortunately, the three people behind me who were jabbering throughout the entire showing were too heavy. Just as an aside, I 've must say that going to the movies has become oh so pleasant nowadays. People put their feet on your armrest, kick your chair, talk through the movie, answer their cell-phones and all of this comes complete for the low, low price of nine bucks.
Julia Roberts is considered America's sweetheart, but I guess here is where I admit to being out of touch. In movie after movie, she treats other characters terribly. In "My Best Friends Wedding," she is awful as she connives and plots against Dermot Mulroney and Cameron Diaz. She is reprehensible in how she treats Hugh Grant's character in "Notting Hill," teeing off on him for no good reason and the worst part is, he takes it. Wasn't the whole point of that film the idea that he was different and unlike everyone else, not tolerant of spoiled-brat, movie star behavior. In "Runaway Bride," she keeps dumping men at the altar when she gets the jitters. Gee, let's make a charming little film about a guy who bails on his brides to be and see how charming audiences find that.  When she loses, she demands her lawyer give her a job because he "owes" her and then she continues to talk back to him whenever it suits her.  And when Ed, her boss, tells her that perhaps she ought to wear something other than the micro-miniskirts and revealing tops with her gazungas hanging out, her reply is, "as long as I have one ass instead of two, I'll wear what I like;" Wow, what a role model.
Instead of feeling bad for the people who were poisoned, I just began to get more and more disgusted by Roberts' character since in this film, the victims, like everyone else, are really just incidental to her. Unlike any other good legal drama, there is no compelling conflict created in regards to the tragedy. Soderbergh and his writer Susan Grant are more interested in making Roberts look good by having everyone else look like a schmuck. Finney comes across as a dolt as do all the other lawyers in the film.  The love interest, George (Aaron Eckhart) seems like a decent guy but like Hugh Grant in "Notting Hill," he takes so much trash from her that we can't care about him either.  I feel terrible for what happened to them and I think that Universal, Roberts, and the rest of the above-the-line talent should donate their entire earnings from this film to make up for exploiting their plight.
The biggest disappointment is that Soderbergh, after doing two good movies ("Out of Sight," "The Limey"), has so completely gone south here. Maybe he did it just so he could get a pet-project made or something lofty like that. However, I think the reality is that all independent filmmakers, with a few exceptions such as John Sayles, just want to sell out and make movies about Julia Roberts' breasts. That's fine, breasts are great, but let's cut the pretense and the "I'm an artist" routine.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Scale the browser down to a medium size to see the difference.
On a medium screen, I have a gutters!
On a large screen, I have no gutters!