Conflict
Conflict is an essential part of any story. The world would be dull without it.
Challenge Levels
The following table should give The Adversary some guidance on assigning challenge levels.
| Task Difficulty | Challenge Level |
|---|---|
| Trivial | 3 |
| Mild | 6 |
| Fair | 9 |
| Moderate | 12 |
| Great | 15 |
| Incredible | 18 |
| Inconceivable | 21 |
The numbers above assume that the character has the necessary tools for the job in question - i.e., if a thief is trying to pick a lock, then he is using a standard lockpick. If the thief was trying to pick a lock with something nonstandard, like a dagger, then The Adversary should make the challenge level higher. If the character has an exceptional set of tools at his disposal, The Adversary should lower the challenge level a notch or two.
The numbers also assume that the character is taking a normal amount of time to perform the task. What this amount is depends upon the task - perhaps six seconds for picking a lock or six days for smithing a weapon.
Characters can obtain bonuses for extra time taken or penalties for rushed work.
| Extra time | Bonus |
|---|---|
| x2 | 3 |
| x3 | 5 |
| x4 | 6 |
| x5 | 7 |
| x6 | 8 |
| x8 | 9 |
| x10 | 10 |
Frex, one can get +3 to the trait check for taking twice as long as usual or +6 for taking four times as long. If the character tries to rush, The Adversary should increase the challenge level by 3 for for each halving of the required time.
Perception
Perception is used whenever The Adversary wants to see whether a character notices something, such as images, sounds, or smells that are hard to detect because they are small, faint, or far away. It is used to determine whether a character will notice subtle sensory input, like someone sneaking up behind him.
Various factors can affect a perception check. Bright light or pitch darkness can hamper vision. Loud noise can hamper hearing. The challenge level for any situation is up to The Adversary.
Unconscious characters get no perception checks - they are senseless. Being asleep is not the same as being knocked out, however; sleeping characters get normal hearing checks when unusual noises occur in their presense. If successful, they awaken. If the noises are very soft, such as someone sneaking toward the sleeper, the perception rolls are more difficult.
Perception is also used when The Adversary wants to see whether a character notices something subtle that is right in front of them, such as an enemy wearing a disguise or someone following them through a crowd. Anything that distracts the character from paying careful attention to detail could cause a penalty (a higher challenge roll).
Intuition
Intuition functions as supernatural perception.
This is a catchall for supernatural abilities used to learn the unknown. A mystic may hear the whispers of spirits, read the future in the stars, or simply know things without reason. It allows one to sense the presence of nearby disembodied spirits and to communicate with them on a primal level. One does not receive coherent thoughts from ghosts, only urges, feelings, and desires.
Intuition can be used by The Adversary as a plot device. He can allow a character to sense danger, receive visions of the future, or anything else that adds to the game.
Combat Values
Adventurers have a number of combat values based on their traits, skills, gifts, and equipment.
- Movement is equal to 10 + Athlete. The character's encumbrance and armor penalties are subtracted from this.
- Offense is based on the type of attack.
- Missile weapons use Archer.
- Hand-to-hand attacks and thrown weapons use Warrior.
- Mage spells use Intellect.
- Sorcerer spells use Presence.
- Dodge is equal to 7 + Athlete - encumbrance and armor penalties.
- Parry is equal to 7 + Warrior + weapon defense bonuses.
- Defiance is equal to 7 + Intellect or Intuition, whichever is greater.
- Protection is equal to Fortitude + armor.
Initiative
At the beginning of each battle, characters roll Perception to determine who acts first. This roll is the character's initiative. High initiatives act before low ones. The order will remain for the battle unless someone chooses to Haste. The Adversary should add 7 to each enemy's Perception rather than roll.
Environmental factors (such as surprise) or minor actions (such as darting a single space or drawing a weapon) may give bonuses or penalties to initiative.
Any trait bonuses or penalties that result from a character's actions last until the next round.
Action
The next step is the action phase. Characters take their turns in order of initiative, highest to lowest. A character disabled before his turn gets no actions.
Some actions, such as drawing a weapon, shouting to a comrade, or moving a single space, take little time and require no trait roll. if such actions must be done before more important ones, the character might have a penalty to Initiative.
Other actions do require a trait roll or take significant time. A character may take two such actions per round of conflict. For example, a character can move and attack, attack and move, move twice, attack twice, open a door and run down the hallway, jump off a ledge and tackle someone, etc.
Some actions may require more time to complete. Casting a spell takes a full round.
Round Zero
Round zero marks the beginning of any conflict. Whoever acts first automatically gets the initiative. This usually applies to a single individual, but can apply to a group in cases of ambush. After the initial round zero activity, conflict progresses to round 1 and participants roll initiative.
If the initiating individual or group has taken their opponents completely by surprise, then the opponents may take no actions at all on round zero - not even defensive ones. This simulates situations such as ambushes or knives thrown by hidden assassins.
Surprised characters get no trait added to their defense. The challenge level to hit an unaware character is a flat 4 plus any range modifiers. Sneak attacks can be deadly - the only defense is not to be caught unaware.
Movement
A character may move a single space per round without using an action. He may move a number of spaces equal to his Movement by expending an action.
Other moves - standing from a prone position, mounting an animal, making a leap, etc - take one action.
A character who is sitting or lying down is prone - he gets +3 defense against ranged attacks, but can move only 1 space per round.  Falling prone is a free action.
A mounted character uses the mount's movement in place of his own. Horses and such generally have twice the movement of a humanoid, or even more.
If the ground is not level, The Adversary may give a character bonuses or penalties to his movement. If the terrain is treacherous, The Adversary may require an Athlete roll (on foot - a rider may need to roll Ranger to control his mount).
Individuals may sometimes need to jump over things. The Adversary should require an Athlete roll with a challenge level of 4 * the number of spaces.
Charging characters may add their momentum to the damage of an attack. This works both ways, however - a charging character will take the same additional damage from any enemy melee weapon that hits him on that round. Momentum gives (and takes) +1 damage for every 3 spaces of movement. Whether to charge in with momentum or slow down and stop before attacking is up to the player.
A brave knight charges a line of soldiers atop his mount. His lance does 13 damage (9 for the lance + 4 for Brawn). The knight has moved 28 spaces on horseback, however, so adds 9 for a total of 22.
Unfortunately, the knight is hit by one of the braced spearmen, whose weapon gives him a damage of 10 (1 for Brawn, 9 for the pike). Adding the knight's momentum to this gives a total of 19. Good thing the knight is wearing his shining armor.
Combat movement is automatic. When finer detail is required - for races or chases - participants should roll Athlete. Each level of mox gains the victor one space of distance.
Range
The further away a target is, the harder it is to hit. Ranged abilities have challenge numbers based on distance (zero at point-blank range). These numbers are added to the defense of the target.
Ranged abilities are either Short or Long. Short-range abilities suffer a +1 to the challenge level for every space between the adventurer and the target. Long-range abilities suffer a +1 for every five spaces.
| type | range |
|---|---|
| thrown weapon | short |
| missile weapon | long |
| spell | long |
Senses are also limited in range. Olfaction is Short. Hearing, vision, and intuition are Long.
Abort
A character with actions remaining who is attacked may sacrifice actions for bonuses in response to the attack, even if it happens before the target's initiative. This intent must be declared before the dice are rolled.
Wait
A character is not required to act on his initiative. He can wait to see what others with lower initiatives will do.
A waiting character may take its action at any time, even within the action of another character.
Juk the Barbarian sees Mace the Ugly on a hilltop across the battlefield. Juk wins initiative, but waits to see what Mace will do.
Mace charges. Juk won the initiative, however, so he may choose to attack first after Mace has covered the distance between them - he was only waiting for his enemy to get close enough to strike. If Mace survives the attack, he may then take the rest of his action.
A waiting character may also hold action until the next round, in which case that character gets +10 to initiative for that round. He gets no extra actions, however.
The Waiting Game
This rule simulates scenes in books and movies in which two opponents stop and stare one another down, taking no actions, in the middle of a fight.
If two characters both decide to wait for the other to act and there are no other characters with actions left, then the action passes to the next round. This can even involve more than two characters. All characters involved in the waiting game get the initiative bonus over characters who acted in the previous round.


Changing inductive definitions
In chap11.v , the predicates
min and maj are defined with the help
of the predicate occ.
Give another definition, whithout using occ, and compare
the ease of
development in the two approaches. You should be able to redo the all
development with the new definitions.
Solution
This file contains some lemmas
which establish the relationship between both definitions. You should be
able to build a development similar to using
these lemmas.


Lori Harvey Returns To Instagram For The First Time Since Her Hit-And-Run Accident
November 17, 2019
Lori Harvey Returns To Instagram For The First Time Since Her Hit-And-Run Accident
Lori Harvey recently shared a video on Instagram three weeks after she was involved in a hit-and-run accident.
The model and stepdaughter of Steve Harvey returned to the photo-sharing app to promote a campaign that she is involved in. In the video, which was shared on November 15, Lori is in a winter wonderland while she is promoting a holiday gift set from Viktor & Rolf.
She is wearing a white dress as she smiles and spins around for the camera. Behind her is a bright pink backdrop, as snowflakes fly through the air and past Harvey’s face. Harvey is seen holding the gift set, and said that she is “obsessed” with it in the video.
She has a soft makeup look in the video, only adding foundation, eyeshadow, faux eyelashes, and lip gloss. She also styled her hair in a center part, as her dark hair is straight in the photo. Based off the model’s geotag on her post, the advertisement was shot in Paris, France.
At the time of this writing, Harvey’s post has received more than 35,000 views from the model’s 1.3 million Instagram followers. The video also received more than 80 comments from Harvey’s fans, many of whom were happy to see her reappear on social media.
“Great come back!” one fan exclaimed.
“Beautiful girl you are amazing,” another fan chimed in.
“Oh how I’ve missed you my love,” another fan said.
“You look stunning! Proud of you,” another fan wrote.
Harvey hasn’t been on Instagram or any of her other social media platforms since she was involved in her car accident back in October. The model was reportedly arrested and charged with a misdemeanor citation for crashing her Mercedes SUV into another vehicle, flipping her car on the scene.
Loading...
The cause of the accident was reportedly due to her texting and driving at the time. The other driver reportedly pulled Harvey out of her car before she attempted to flee the scene. Neither Harvey nor the second driver sustained any injuries after being found by Beverly Hills police.
Before her accident, Harvey was making headlines for a completely different reason. The model was romantically linked to Diddy back in March, and the two began sparking romantic rumors through the summer.
While both Diddy and Harvey denied that they were together at the time, they were seen out together on many occasions. Diddy also joined Harvey with her stepfather and mother, Marjorie Harvey, on a trip back in July.


Struggling Celta Vigo appoint Oscar Garcia as manager
La Liga strugglers Celta Vigo appointed Oscar Garcia as coach on Monday to replace Fran Escriba, who was sacked on Sunday.
REUTERS: La Liga strugglers Celta Vigo appointed Oscar Garcia as coach on Monday to replace Fran Escriba, who was sacked on Sunday.
Former Barcelona player Oscar, 46, has managed several teams including Brighton & Hove Albion, Watford and Red Bull Salzburg, most recently working with Olympiakos Piraeus in 2018.
Sunday's 1-0 defeat by visitors Getafe was Celta's fourth in a row and left them in 18th place on nine points from 12 games, two behind Real Mallorca and the safety zone.
"Oscar will be accompanied by three assistants and this Tuesday he is expected to lead his first training session," Celta said in a statement.
(Reporting by Rik Sharma; editing by Ken Ferris)


| Dec | Hex | Binary | Char |
|---|---|---|---|
| 0 | 0x00 | 00 00000 | NUL |
| 1 | 0x01 | 00 00001 | SOH |
| 2 | 0x02 | 00 00010 | STX |
| 3 | 0x03 | 00 00011 | ETX |
| 4 | 0x04 | 00 00100 | EOT |
| 5 | 0x05 | 00 00101 | ENQ |
| 6 | 0x06 | 00 00110 | ACK |
| 7 | 0x07 | 00 00111 | BEL |
| 8 | 0x08 | 00 01000 | BS |
| 9 | 0x09 | 00 01001 | HT |
| 10 | 0x0a | 00 01010 | LF |
| 11 | 0x0b | 00 01011 | VT |
| 12 | 0x0c | 00 01100 | FF |
| 13 | 0x0d | 00 01101 | CR |
| 14 | 0x0e | 00 01110 | SO |
| 15 | 0x0f | 00 01111 | SI |
| 16 | 0x10 | 00 10000 | DLE |
| 17 | 0x11 | 00 10001 | DC1 |
| 18 | 0x12 | 00 10010 | DC2 |
| 19 | 0x13 | 00 10011 | DC3 |
| 20 | 0x14 | 00 10100 | DC4 |
| 21 | 0x15 | 00 10101 | NAK |
| 22 | 0x16 | 00 10110 | SYN |
| 23 | 0x17 | 00 10111 | ETB |
| 24 | 0x18 | 00 11000 | CAN |
| 25 | 0x19 | 00 11001 | EM |
| 26 | 0x1a | 00 11010 | SUB |
| 27 | 0x1b | 00 11011 | ESC |
| 28 | 0x1c | 00 11100 | FS |
| 29 | 0x1d | 00 11101 | GS |
| 30 | 0x1e | 00 11110 | RS |
| 31 | 0x1f | 00 11111 | US |
| Dec | Hex | Binary | Char |
| 32 | 0x20 | 01 00000 | SPACE |
| 33 | 0x21 | 01 00001 | ! |
| 34 | 0x22 | 01 00010 | " |
| 35 | 0x23 | 01 00011 | # |
| 36 | 0x24 | 01 00100 | $ |
| 37 | 0x25 | 01 00101 | % |
| 38 | 0x26 | 01 00110 | & |
| 39 | 0x27 | 01 00111 | ' |
| 40 | 0x28 | 01 01000 | ( |
| 41 | 0x29 | 01 01001 | ) |
| 42 | 0x2a | 01 01010 | * |
| 43 | 0x2b | 01 01011 | + |
| 44 | 0x2c | 01 01100 | , |
| 45 | 0x2d | 01 01101 | - |
| 46 | 0x2e | 01 01110 | . |
| 47 | 0x2f | 01 01111 | / |
| 48 | 0x30 | 01 10000 | 0 |
| 49 | 0x31 | 01 10001 | 1 |
| 50 | 0x32 | 01 10010 | 2 |
| 51 | 0x33 | 01 10011 | 3 |
| 52 | 0x34 | 01 10100 | 4 |
| 53 | 0x35 | 01 10101 | 5 |
| 54 | 0x36 | 01 10110 | 6 |
| 55 | 0x37 | 01 10111 | 7 |
| 56 | 0x38 | 01 11000 | 8 |
| 57 | 0x39 | 01 11001 | 9 |
| 58 | 0x3a | 01 11010 | : |
| 59 | 0x3b | 01 11011 | ; |
| 60 | 0x3c | 01 11100 | < |
| 61 | 0x3d | 01 11101 | = |
| 62 | 0x3e | 01 11110 | > |
| 63 | 0x3f | 01 11111 | ? |
| Dec | Hex | Binary | Char |
| 64 | 0x40 | 10 00000 | @ |
| 65 | 0x41 | 10 00001 | A |
| 66 | 0x42 | 10 00010 | B |
| 67 | 0x43 | 10 00011 | C |
| 68 | 0x44 | 10 00100 | D |
| 69 | 0x45 | 10 00101 | E |
| 70 | 0x46 | 10 00110 | F |
| 71 | 0x47 | 10 00111 | G |
| 72 | 0x48 | 10 01000 | H |
| 73 | 0x49 | 10 01001 | I |
| 74 | 0x4a | 10 01010 | J |
| 75 | 0x4b | 10 01011 | K |
| 76 | 0x4c | 10 01100 | L |
| 77 | 0x4d | 10 01101 | M |
| 78 | 0x4e | 10 01110 | N |
| 79 | 0x4f | 10 01111 | O |
| 80 | 0x50 | 10 10000 | P |
| 81 | 0x51 | 10 10001 | Q |
| 82 | 0x52 | 10 10010 | R |
| 83 | 0x53 | 10 10011 | S |
| 84 | 0x54 | 10 10100 | T |
| 85 | 0x55 | 10 10101 | U |
| 86 | 0x56 | 10 10110 | V |
| 87 | 0x57 | 10 10111 | W |
| 88 | 0x58 | 10 11000 | X |
| 89 | 0x59 | 10 11001 | Y |
| 90 | 0x5a | 10 11010 | Z |
| 91 | 0x5b | 10 11011 | [ |
| 92 | 0x5c | 10 11100 | \ |
| 93 | 0x5d | 10 11101 | ] |
| 94 | 0x5e | 10 11110 | ^ |
| 95 | 0x5f | 10 11111 | _ |
| Dec | Hex | Binary | Char |
| 96 | 0x60 | 11 00000 | ` |
| 97 | 0x61 | 11 00001 | a |
| 98 | 0x62 | 11 00010 | b |
| 99 | 0x63 | 11 00011 | c |
| 100 | 0x64 | 11 00100 | d |
| 101 | 0x65 | 11 00101 | e |
| 102 | 0x66 | 11 00110 | f |
| 103 | 0x67 | 11 00111 | g |
| 104 | 0x68 | 11 01000 | h |
| 105 | 0x69 | 11 01001 | i |
| 106 | 0x6a | 11 01010 | j |
| 107 | 0x6b | 11 01011 | k |
| 108 | 0x6c | 11 01100 | l |
| 109 | 0x6d | 11 01101 | m |
| 110 | 0x6e | 11 01110 | n |
| 111 | 0x6f | 11 01111 | o |
| 112 | 0x70 | 11 10000 | p |
| 113 | 0x71 | 11 10001 | q |
| 114 | 0x72 | 11 10010 | r |
| 115 | 0x73 | 11 10011 | s |
| 116 | 0x74 | 11 10100 | t |
| 117 | 0x75 | 11 10101 | u |
| 118 | 0x76 | 11 10110 | v |
| 119 | 0x77 | 11 10111 | w |
| 120 | 0x78 | 11 11000 | x |
| 121 | 0x79 | 11 11001 | y |
| 122 | 0x7a | 11 11010 | z |
| 123 | 0x7b | 11 11011 | { |
| 124 | 0x7c | 11 11100 | | |
| 125 | 0x7d | 11 11101 | } |
| 126 | 0x7e | 11 11110 | ~ |
| 127 | 0x7f | 11 11111 | DEL |
The binary representation has the most significant bit first
(“big endian”).
ASCII is 7-bit; because many have called encodings such as
CP437,
ISO-8859-1,
CP-1252,
and others “extended ASCII” some are under the misapprehension that
ASCII is 8-bit (1 byte).
To understand why Control+i inserts a Tab in your terminal you need to understand ASCII, and to understand ASCII you need know a bit about its history and the world it was developed in. Please bear with me.
Teleprinters evolved from the telegraph. Connect a printer and keyboard to a telegraph and you’ve got a teleprinter. Early versions were called “printing telegraphs”.
Most teleprinters communicated using the ITA2 protocol. For the most part this would just encode the alphabet, but there are a few control codes: WRU (“Who R U”) would cause the receiving teleprinter to send back its identification, BEL would ring a bell, and it had the familiar CR (Carriage Return) and LF (Line Feed).
This is all early 20th century stuff. There are no electronic computers; it’s all mechanical working with punched tape. ITA2 (and codes like it) were mechanically efficient; common letters such as “e” and “t” required only a single hole to be punched.
These 5-bit codes could only encode 32 characters, which is not even enough for just English. The solution was to add the FIGS and LTRS codes, which would switch between “figures” and “letters” mode. “FIGS R W” would produce “42”. This worked, but typo’ing a FIGS or LTRS (or losing one in line noise) would result in gibberish. Not ideal.
In the 1950s teleprinters started to get connected to computers, rather than other teleprinters. ITA2 was designed for mechanical machines and was awkward to use. ASCII was designed specifically for computer use and published in 1962. Teleprinters used with computers were called terminals (as in “end of a connection”, like “train terminal”). Teleprinters were also called “TeleTYpewriter”, or TTY for short, and you can still find names like /dev/tty or /bin/stty on modern systems.
People really programmed computers using teleprinters. Here’s a video of a teleprinter in action, and here’s a somewhat cheesy (but interesting and cute) video which explains how they were used to program a PDP 11/10.
A terminal would connect to a computer with a serial port (RS-232), which simply transfers bytes back and forth. A terminal is more akin to a monitor with a keyboard, rather than a computer on its own.
If you’re wondering what a “shell” is: a shell is a program to interact with your computer. It provides a commandline, runs programs, and displays the result. The terminal just displays characters. It’s the difference between a TV and a DVD player.
Teleprinters needed some way to communicate events such as “stop sending me data” or “end of transmission”. This is what control characters are for. The exact meaning of control characters has varied greatly over the years (which is why extensive termcap databases are required). ASCII is more than just a character set; it’s a way to communicate between a terminal and a computer.
An additional method to communicate are
escape sequences.
This is a list of characters starting with the ESC control character (0x1b). For example
F1 is <Esc>OP
and the left arrow is <Esc>[OD
.
Computers can give instructions to terminals, too: <Esc>[2C
is move
the cursor 2 positions forward and <Esc>[4m
underlines all subsequent
text. This is also how the Alt key works: Alt+a is <Esc>a
.
All of this matters because modern terminals operate on the same principles as those of the 1960s. If you’re opening three xterm or iTerm2 windows then you’re emulating three terminals connecting to a “mainframe”.
If you look at the ASCII table above then there are some interesting properties: in the 1st column you can see how the left two bits are always set to zero, and that the other 5 bits count to 31 (32 characters in total; it starts at 0). The 2nd column repeats this pattern but with the 6th bit set to 1 (remember, read binary numbers from right-to-left, so that’s 6th counting from the right). The 3rd column repeats this pattern again with the 7th bit set, and the final column has both bits set.
The interesting part here is that the letters A-Z and some punctuation map directly to the control characters in the 1st column. All that’s needed is removing one bit, and that’s exactly what the Control key did: clear the 7th bit. Lowercase and uppercase letters align in the 3rd and 4th columns, and this is what the Shift key did: clear the 6th bit.
Pressing Control+i (lowercase) would mean sending “)”, which is not very useful. So most terminals interpret this as Control+I (uppercase), which sends HT. DEL is last is so all bits are set to 1. This is how you “deleted” a character in punch tapes: punch all the holes!
This is kind of neat and well designed, but for us it means:
The world has not completely stood still and there have been improvements since the 1960s, but terminals are still fundamentally ASCII-based text interfaces, and programs running inside a terminal – like a shell or Vim – still have very limited facilities for modern key events. Non-terminal programs don’t have these problems as they’re not restricted to a 1960s text interface.
Note: for brevity’s sake many aspects have been omitted in the above: ITA2 was derived from Murray code, the 1967 ASCII spec changed many aspects (1962 ASCII only had uppercase), there were other encodings (e.g. EBCDIC), graphical terminals such as the Tektronix 4014 (which xterm can emulate), ioctls, etc. References and further reading: An annotated history of some character codes, 7-bit character sets, Control characters in ASCII and Unicode, The TTY demystified


ML (MetaLanguage), is a general purpose functional programming language with popular derivatives including F# and OCaml.
Wrong Presentation!
You will need:
We will also download these libraries later:
Basically, it is what everyone uses.
It is an incredibly powerful interpreted language with many useful machine learning and visualisation libraries that can interact well with each other.
Furthermore, python is incredibly widely used for other applications, allowing Python+ML to enhance those massively. (eg. Houdini+scikit-learn)
Machine Learning (ML) is a form of computation where a program is designed to solve specific tasks using models and inference, as opposed to relying on explicit hard-coded instructions.
There are three broad categories of machine learning
When a machine learning algorithm attempts to infer a function from labeled training data.
When a machine learning algorithm attempts to infer some kind underlying structure to unlabelled data.
When a machine learning algorithm seeks to take actions in order to maximize some kind of reward.
We have..
The goal of a neural network (in this case!) is to model some function $f(\mathbf{x})$.
Where $\mathbf{x}$ is a multi-dimensional vector, eg. $784$ values representing the pixels of a $28 \cdot 28$ image.
The output could be a number the image represents.
So in this example, we want our neural network to take an image of the number $5$ and turn it into the number $5$.
$\rightarrow$ $5$
A simple network, the multilayer perceptron:
$\sigma$ is the activation function, processing all the inputs into a neuron. We will use the sigmoid function:
$$ \sigma (x) = \frac{1}{1 + e^{-x}} $$
The output of the sigmoid function looks like this:
DRAWING TIME!!!! :D
| $x$ | $y$ |
|---|---|
| -2.0 | 4.4 |
| 3.7 | 0.5 |
| 4.7 | -0.3 |
| 1.0 | 1.4 |
| 3.4 | 0.4 |
| 1.9 | 1.4 |
| 0.5 | 2.0 |
| 3.7 | 0.5 |
| -3.7 | 5.6 |
| -1.4 | 3.5 |
| $x$ | $y$ |
|---|---|
| -2.0 | 4.4 |
| 3.7 | 0.5 |
| 4.7 | -0.3 |
| 1.0 | 1.4 |
| 3.4 | 0.4 |
| 1.9 | 1.4 |
| 0.5 | 2.0 |
| 3.7 | 0.5 |
| -3.7 | 5.6 |
| -1.4 | 3.5 |
We can simplify the maths down to (1 layer, 1 neuron, no activation function $\sigma$): $$ a(x)=b + w x $$ This closely matches our desired output function: $$ y = c + m x $$
We need to train the neural network so that it finds $b$ and $w$ to best fit the data.
$$ a(x)=b + w x $$
We can do this with a cost function.
$$ C=\sum_{i=0}^{N-1} (a(x_i) - y_i)^2 $$
Where $(x_i, y_i)$ represents each sample from our training data.
Now we have a cost, we can calculate a new weight and bias which minimizes the cost:
$$ w'=w-\mu\frac{\partial C}{\partial w} $$
$$ b'=b-\mu\frac{\partial C}{\partial b} $$
Here, $\mu$ is what we call the learning rate.
$$ \frac{\partial C}{\partial w} = \sum_{i=0}^{N-1} 2 x_i ((b + wx_i) - y_i) $$
$$ \frac{\partial C}{\partial b} = \sum_{i=0}^{N-1} 2 ((b + wx_i) - y_i) $$
$m$ = 0.68, $c$ = 2.75
$m$ = 0.68, $c$ = 2.75
$m$ = 0.68, $c$ = 2.75
We have worked through the maths of a single-neuron network.
What glaring flaw do you potentially see with our values for $w$ and $b$?
What about the model overall?
Given $a^L_j=\sigma(b^L_j + \sum_{k=1}^{n_{L-1}} w^L_{jk} a^{L-1}_k)$.
We can use the same cost function and similarly calculate its derivative w.r.t. all weights and biases.
This makes extensive use of the chain rule to backpropagate the cost through the network.
Links at the end the presentation show the full maths behind this.
Create folder and add a text file called "process_digits.py".
Then, ensuring you have Python installed, run:
pip install scikit-learn
pip install numpy
The dataset can be found at http://yann.lecun.com/exdb/mnist/.
However, we will be using MNIST-for-Numpy to download and then load the data into a "process_digits.py".
By the end of the session, who can come-up with the best accuracy on the testing data?
Go back to playground, cover RELU and the like.


Flight Ticket Agent
Login
From
To
Departure date
Return date
Adult (15+ yrs):
×
Success!
Your price agent has started.


Note the due date for this assignment
In this assignment you will deliver your multi-user web application. The objectives are:
Each logged in user has a feed which is the collection of their articles and their follower's articles.
When the user requests GET /articles
we therefore need to return this joined set. A poor
algorithm would be the following
const userObj = getUser(req.user) const articles = [userObj.username, ...userObj.following].reduce((o, user) => o.concat(getArticlesByAuthor(user)), [])
This is bad because it adds all articles for all time to the result set (articles) and additionally makes multiple requests to the database. Instead we want one query to the database that retrieves articles for all users and only those articles that are recent. I.e., we would prefer something like
const userObj = getUser(req.user) const usersToQuery = [ userObj.username, ...userObj.following ] const articles = getArticlesByAuthors({ authors: usersToQuery, limit: 10 })
where the query will preferentially grab the 10 most recent articles by all of the users in the array. In this way the client will make one request to get the user's feed and it will be relatively small in size. To retrieve the next set of articles after the initial 10, we would implement pagination on the query. You'll want to look at the MongoDB/mongoose documentation, and write only one query to the database, and return only the desired data. The sorting of articles (most recent first) can be done either by MongoDB (better) or by the server (not terrible).
When a user logs in we register with them a session identifier. This session id is stored in a cookie for the user, and in a map from session id to user on our server. This way all subsequent requests from the user will be identifiable as them without requiring them to log in again.
Following an inclass exercise, move the in-memory sessionId-to-user map to a Redis caching store. In this way if we have multiple backend servers, they will share the memory of the session id lookup and not require users to login multiple times.
Run these commands to add Redis (i.e., following the inclass exercise)
heroku addons:create heroku-redis:hobby-dev heroku plugins:install heroku-redis npm install redis --save heroku config
From the last line you can find your Redis URL. Here is some code to get you started using Redis:
if (!process.env.REDIS_URL) { process.env.REDIS_URL = 'redis:// put your redis url here' } const redis = require('redis').createClient(process.env.REDIS_URL) // This sets the key-value pair (sid, userObj) redis.hmset(sid, userObj) // This gets the value corresponding to the key sid -- it is an async call redis.hgetall(sid, function(err, userObj) { console.log(sid + ' is mapped to ' + userObj) }) // these commands might be outdated -- check the redis documentation! // userObj must be an object, not a string or an array.
To log into your Redis server and flush the cache (i.e., delete all entires) to the following:
heroku redis:cli --confirm <APPNAME> redis> keys * redis> flushall
Here is the full list of commands for Redis.
When we upload a picture to the server it will be stored on disk. This we can potentially consume a lot of disk space if we're not careful about limiting user uploads etc. Additionally, local storage on Heroku is not persistent to dyno reboots, i.e., after you repush your code, your Heroku dyno will reboot and any locally uploaded files will not be available on the new dyno. Therefore local storage of images is not ideal.
MongoDB has a document limit size of 16 MB. This means for most uploads we could probably store them as documents in MongoDB. However, for images this is inconvenient because our backend server much first pull the document from MongoDB and then serve the image to the frontend. It would be much better if images were readily available to the frontend and the frontend could pull the images directly from a datastore.
In a lecture I showed how we can use Amazon's S3 to store blobs of data, such as images. S3 is a great service, and in fact S3 is used by Heroku for storage. But outside of a free trial period, S3 is not free. Instead, we will use Cloudinary, which has a free tier, to persist uploaded pictures.
We need a few modules:
Multer is a node.js middleware for handling multipart/form-data
, which is exactly what we have for uploading files.
npm install cloudinary multer --save heroku addons:create cloudinary:starter heroku config
The addon for Cloudinary requires billing information for Heroku -- again you will not be charged if you stay in the free tier. If you can not get Cloudinary to work through the Heroku plugin you can go to their site and register directly. We need the Cloudinary url, which is what the last line above provides.
Follow the in class exercise to demo the functionality. Then implement the PUT /avatar
endpoint
and validate it works using your frontend.
You also need to implement adding articles with text and images.
You will use the same middleware uploadImage
for both uploads.
Following an inclass exercise, add an option for third party authentication. It is your pick as to which third party you partner with. It can be Twitter, Facebook, Google, etc, any OAuth or OAuth2 provider should work. You should use either Request (OAuth) or PassportJS (OAuth or OAuth2) as middleware for authentication.
On your landing page next to the register and login buttons have an additional button to login with the third party. When a user logs in this way you do not know what user account they are linked to in our system. Perhaps you can try looking up the user by their email address. Nevertheless we will need some way to distinguish third part authenticated users from normal password users. Therefore add an additional field to your User model to capture this. When a user logs using third party authentication, if you do not already have a user record for them (i.e., by email or by looking up username+third party) then create a new record in the document store with no salt, no password, but with a username and with an identifier for the third party. E.g., I might have username="sep1" and auth="rice" to signify this is the Rice OAuth service for the netid sep1. Notice that we may now have username conflicts between "sep1" registered with a password and "sep1" with OAuth. Perhaps we would link these accounts together? But doing that without user confirmation can be problematic (what if the user owning sep1@rice does not own sep1 on our site?). Therefore we might instead choose to uniquly identify the username, e.g., "sep1@rice" to prevent username conflicts with an already registered sep1 on our site. This way a user can always log in with third party auth and still use our site as if they were a regular user.
But perhaps the accounts do belong to the same user?
Add to your profile page a way for a user to link their accounts together.
For example, on the profile page there would be a "Link Account" button
which if they are logged in using the third party, they would be able to login with a username
and password for our site. If they are logged into our site, then it would direct them
to login with the third party. After the user has logged in the second time,
we merge the two accounts together.
This means we need to search to see if there was already the second User record
and delete it if it exists. I.e., if I logged in as sep1 and then as sep1@rice
but then wanted to link the accounts together, then you would delete the sep1@rice record,
and merge the followed users together.
For the sep1 record you would add the additional auth information,
perhaps the field would be auth = [ rice: sep1, google: skotep, facebook: scott ]
so that I can
link multiple third party accounts. Later when a user logs in using the third party,
we need a MongoDB query that searches this new auth field to find the account in addition
to searching by username.
If we can link accounts then we should also allow users to unlink accounts, which should be straightforward.
In this case we would only delete the OAuth account, we would not generate a new User record for it, i.e.,
if I unlink my @rice then auth becomes: [ google: skotep, facebook: scott ]
but
no sep1@rice User record will be generated separately.
Tip!
Complete all other parts of the assignment before you work on linking accounts.
 This is your final submission everything should work "out of the box". An automated robot will grade sections of your assignment.
Your submission directory will look similar to that of the previous assignments.


| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| home-call-to-action.component.js | 95% | 19/20 | 79.31% | 23/29 | 100% | 4/4 | 100% | 16/16 | |
| home-hero.component.js | 77.78% | 28/36 | 80.65% | 25/31 | 50% | 4/8 | 78.13% | 25/32 | |
| home-highlights.component.js | 96% | 24/25 | 80.65% | 25/31 | 100% | 5/5 | 100% | 21/21 | |
| home-vendor-marquee.component.js | 95.24% | 20/21 | 79.31% | 23/29 | 100% | 4/4 | 100% | 17/17 |


{% extends "solution.html" %}
{% load static %}
{% block puzzle-author %}
Galactic Trendsetters
{% endblock %}
{% block solution-body %}
Draw the paths on a Cartesian plane. The two lines next to the checkmark are PARALLEL, but the two lines next to the X are not, so the answer is PARALLEL.
![]({% static 'puzzle_resources/geometry/geometry.svg' %})
{% endblock %}


{% load staticfiles %}
{% csrf_token %}
Search:
Submit
Clear
Loading...
Graph Exploration Parameters:
- Year Span:
- Maximum Number of Nodes:
- Maximum Hops From Nodes:
- Centrality Algorithm Parameter:
Sorted-Path-Centrality
Greedy-Path-Centrality
Betwennness
Degree
Page-Rank
Katz
Seed Selection:
Return Central Nodes
Graph Viewer:
Enable Tooltips
Weighted Node Size
Algorithm Outputs:
Clear Central Nodes
Output Size Limit:
Citation Browser:
Clear Browser
Selected Paper:
Citations:


--- title: OK, this is silly, but I was playing around with the GoPro yesterday to see if it would float, and the sunfish were just absolutely fascinated with it. The captions came to me on my bike ride this morning. I know, a mind is a terrible thing to waste. date: 2012-07-11 comments: true layout: post categories: - photography ref_url: ---
OK, this is silly, but I was playing around with the GoPro yesterday to see if it would float, and the sunfish were just absolutely fascinated with it. The captions came to me on my bike ride this morning. I know, a mind is a terrible thing to waste.


"YARN" Found only in 1 Kings 10:28, 2 Chronicles 1:16. The Hebrews word mikveh, i.e., “a stringing together,” so rendered, rather signifies a host, or company, or a string of horses. The Authorized Version has:“And Solomon had horses brought out of Egypt, and linen yarn: the king’s merchants received the linen yarn at a price;” but the Revised Version correctly renders: “And the horses which Solomon had were brought out of Egypt; the king’s merchants received them in droves, each drove at a price.”
"YARN" Found only in 1 Kings 10:28, 2 Chronicles 1:16. The Hebrews word mikveh, i.e., “a stringing together,” so rendered, rather signifies a host, or company, or a string of horses. The Authorized Version has:“And Solomon had horses brought out of Egypt, and linen yarn: the king’s merchants received the linen yarn at a price;” but the Revised Version correctly renders: “And the horses which Solomon had were brought out of Egypt; the king’s merchants received them in droves, each drove at a price.”


There have been no stock market periods that have brought so many incognitas like this.
On the one hand we have the presidency of Trump that so many headaches has brought most of the political and economic analysts.
On the other hand, a fragile Europe with challenges such as the Brexit or the elections in France that in case of having fallen in Lepen would have triggered in a hecatomb hard to imagine.
In addition, the tensions with North Korea in the seas of Japan and the tensions by the power in the war of Syria, with Russia, the United States and Turkey like protagonists.
Everyone expected that the year would end with a strong dollar reaching equal to the euro and the opposite would happen.
In it he emphasized the idea of closing his country and having a minimal foreign policy, prioritizing the internal problems of his country. I charge harshly against the pharmaceutical sector and against Europe, saying that America always had to go behind Europe.
He also started talking about a change in his trade policy with the rest of the countries, including the tariff idea and the idea of a weaker dollar to increase his exports.
This was a real time bomb, in which the fall of the dollar despite the rise in rates and the economic bonanza of the United States with almost full employment would be evident.
This instability and uncertainty in his words made the mining fever sick, in which the ounce of gold shot to maximum levels in 3 years.
At the same time as gold rose and the euro rose due to the decline of the dollar, the European indexes stagnated. From January to mid-February there was no increase in the indexes. And I was beginning to sound the leftover of the Frexit .
And in France there were elections in which nothing less than the integrity of the European Union was played. With the booms of populism in England, Holland and Austria a new axis had emerged with Le Pen and the French extreme right.
In February it would be the French elections in the first round but something surprising. The new party of the independent Macron with his party On Marche, beat the socialist party Frances and the party of right of Fillon the UMP.
And he would fight with Le Pen in the presidential elections. This change already assured that Macron would win due to the sympathy for liberal economic policies in France, close to the UMP and his smile to the ideals of French social socialism.
This effect would take off all European stock markets to record levels not seen since 2015. Reaching the IBEX the 11000 points or the 12500 in the German DAX, record levels since 2008.
This level was reached just a week before the French elections, which suggested that the electoral results in favor of Macron were discounted.
From there for the IBEX and nothing would be as before not reaching this level to reach throughout the year, closing around the 10300 points that is what he predicted at the end of the previous year.
In the summer of this year nothing memorable would happen on the map of indices, for the well-known summer relax. However, volatility in the currency and raw materials were assured.
And is that since early July to early September gold would vary from about 1200 points due to the clearance of a France outside the EU to 1350 points, maximum since 2008 due to doubts between an attack by the United States to the People's Republic of North Korea for its constant launch of missiles and its atomic tests.
These attacks would reappear the following year although the hope came when announcing that North Korea would accede to meetings about its atomic program at the start of the winter games of 2018 in neighboring South Korea.
The year 2017 will be remembered no doubt by the missile launch record, in which nearly 25 missiles were fired, perfecting the technique over time.
The launch of July 29 would mark a before and after due to the range of reach and may already reach the West Coast of America. In addition, it was no less unusual to fly over Japan, which could have a casus bellis to start any operation.
On September 3, Korea would conduct a nuclear test, which also affirmed that it had managed to miniaturize the bomb. The pump of Korea with hydrogen technology would have a destruction power of 70 kilotons, 4 times higher than those that the USA launched against Japan in the Second World War. It could also be coupled to a ballistic missile like the one launched on July 29. North Korea also claimed to be able to produce warheads from this chain model.
With all this, the reaction of the markets did not wait at all, producing generalized decreases in the indexes and a resurgence of appreciation of the precious metals before any intervention by the United States. However shortly after this trial and before the march of time, this rebound of gold was softening to levels somewhat normal for this year, the 1250 would climb again to the verbal threat of the North Korean leader.
In the following graph you can see how these events triggered a fear in the world economy that had not been seen since the Brexit. It is quite paradoxical that when the world economy is at a better level with the United States and interest rates are rising steadily, gold will suffer these increases.
At the beginning of the year, one of the biggest turbulence in Catalan values in the history of the Spanish stock market began. This was due to the attempt of the Catalan institutions to hold a referendum in a clandestine manner in which only a part of Catalan society would vote. This would strain the price of Catalan companies and values, due to the future punishment of their clients.
The consequences would take time to arrive but as messages were being sent by certain actors belonging to the independence world, the capitalization of companies based in Catalonia would begin to notice a serious setback.
The most affected in this case have been the Catalan banks of the IBEX35, such as Sabadell and Caixabank, but because we live in a globalized world, although some do not want to recognize it, as are those who try to separate themselves from the rest as if the rest were not with them. all the other Spanish banks also fell and therefore other IBEX35 values away from the problems of Catalonia. So much is the globalized economy that the Eurostox also had its fall but if we compare as it was a year ago the German DAX30 we will see how it has been maintained and the IBEX35 has seriously retreated as a 10% more, being paradoxical that Spain presents some bigger growth data than those of Germany.
The following graph shows the impeccable rise of Caixabank until the winds of independence and its correlation with the IBEX begin to blow.
Trump had already been warning since the beginning of the year about his new economic policy on shielding the American self-consumption and protect their companies and no one is surprised by the new tariff policies.
The first to fall would be Mexico, which China would follow. To Mexico the tariffs would come after the break of the free trade agreement, FTA, of North America signed by Canada, the United States and Mexico.
The environment would begin to warm up in summer and the rates to the minimum excuse would correct. Then it would begin to take the fears of the investors to a commercial war and relegate to a second position the fear of a military war with North Korea.
At the end after a series of accusations by both sides the thing would not materialize until November of this year. Trump enotnces would order aránceles to the alumínimo and all its derivatives. Where you would really notice the impact would be on the role of alumínimo. Without doubt it would be the first commercial attack that will follow more next year.
As a finishing touch and the most remarkable event of the year is the rise of cryptocurrencies. The year 2016 left a profitability difficult to improve and went at a good pace until the summer. What nobody imagined is what was about to happen since most of them expected a severe correction, having reached Bitcoin the level of $ 3000 in just 4 months from $ 1000.
This year will undoubtedly be remembered for the record of cryptocurrency levels, led by the Bitcoin in which they would reach end the year $ 20,000 for BTC .
Many criptodivisas would be born in 2017 and would beat record of returns. If the Bitcoin passed from the $ 300 to the $ 1,000 in 2016 reaching a profitability of 300% , 2017 would be no less going from 1000 to 20,000, ending the year with a profitability 2000% .
In other words, someone who had the idea of investing $ 6000 in bitcoins in early 2016, earning 20 bitcoins and having the idea of keeping them for two years would have stored the figure of $ 400,000. Assuming an increase of ... almost 7000% .
This profitability of 300% was difficult to assume for an experienced investor. Although it is already known that most investors are far from this speculative capital, especially if it is operated in the long term. The indicators are difficult to measure and follow other parameters than the stock market values.
If 300% was hardly assumable, it would continue to rise at the same rate, no longer at a linear pace, but at a logarithic rhythm, beating the RSI level of 80 (large overbought) to 6 months constantly. In November it would already be close to $ 10,000 and the year would end at $ 20,000.
And your little sister the Ethereum would not stay far away, if in 2016 it was not worth more than $ 10 and at the beginning of 2017 it was worth $ 40 at the end of the year it would reach 1200 $ per unit, having an even more meteoric rise than Bitcoin this year, 3000%! .
© 2016 - All Rights Reserved - Diseñada por Sergio López Martínez
El sitio se mantiene gracias a la publicidad, por favor Desactiva Adblock para seguir navegando
He desactivado Adblock


Interface Player.Listener
-
- All Known Subinterfaces:
AnalyticsCollector
- All Known Implementing Classes:
DefaultAnalyticsCollector
,ExoPlayerTestRunner
- Enclosing interface:
- Player
public static interface Player.Listener
Listener for changes in aPlayer
.All methods have no-op default implementations to allow selective overrides.
If the return value of a
Player
getter changes due to a change in command availability, the corresponding listener method(s) will be invoked. If the return value of aPlayer
getter does not change because the corresponding command is not available, the corresponding listener method will not be invoked.
-
-
Method Summary
All Methods Instance Methods Default Methods Deprecated Methods Modifier and Type Method Description default void
onAudioAttributesChanged(AudioAttributes audioAttributes)
Called when the value ofPlayer.getAudioAttributes()
changes.default void
onAudioSessionIdChanged(int audioSessionId)
Called when the audio session ID changes.default void
onAvailableCommandsChanged(Player.Commands availableCommands)
Called when the value returned fromPlayer.isCommandAvailable(int)
changes for at least onePlayer.Command
.default void
onCues(CueGroup cueGroup)
Called when the value ofPlayer.getCurrentCues()
changes.default void
onCues(List<Cue> cues)
Deprecated.UseonCues(CueGroup)
instead.default void
onDeviceInfoChanged(DeviceInfo deviceInfo)
Called when the device information changesdefault void
onDeviceVolumeChanged(int volume, boolean muted)
Called when the value ofPlayer.getDeviceVolume()
orPlayer.isDeviceMuted()
changes.default void
onEvents(Player player, Player.Events events)
Called when one or more player states changed.default void
onIsLoadingChanged(boolean isLoading)
Called when the player starts or stops loading the source.default void
onIsPlayingChanged(boolean isPlaying)
Called when the value ofPlayer.isPlaying()
changes.default void
onLoadingChanged(boolean isLoading)
Deprecated.UseonIsLoadingChanged(boolean)
instead.default void
onMaxSeekToPreviousPositionChanged(long maxSeekToPreviousPositionMs)
Called when the value ofPlayer.getMaxSeekToPreviousPosition()
changes.default void
onMediaItemTransition(MediaItem mediaItem, @com.google.android.exoplayer2.Player.MediaItemTransitionReason int reason)
Called when playback transitions to a media item or starts repeating a media item according to the currentrepeat mode
.default void
onMediaMetadataChanged(MediaMetadata mediaMetadata)
Called when the value ofPlayer.getMediaMetadata()
changes.default void
onMetadata(Metadata metadata)
Called when there is metadata associated with the current playback time.default void
onPlaybackParametersChanged(PlaybackParameters playbackParameters)
Called when the value ofPlayer.getPlaybackParameters()
changes.default void
<EMAIL_ADDRESS>int playbackState)
Called when the value returned fromPlayer.getPlaybackState()
changes.default void
<EMAIL_ADDRESS>int playbackSuppressionReason)
Called when the value returned fromPlayer.getPlaybackSuppressionReason()
changes.default void
onPlayerError(PlaybackException error)
Called when an error occurs.default void
onPlayerErrorChanged(PlaybackException error)
Called when thePlaybackException
returned byPlayer.getPlayerError()
changes.default void
onPlayerStateChanged(boolean playWhenReady, @com.google.android.exoplayer2.Player.State int playbackState)
Deprecated.UseonPlaybackStateChanged(int)
andonPlayWhenReadyChanged(boolean, int)
instead.default void
onPlaylistMetadataChanged(MediaMetadata mediaMetadata)
Called when the value ofPlayer.getPlaylistMetadata()
changes.default void
onPlayWhenReadyChanged(boolean playWhenReady, @com.google.android.exoplayer2.Player.PlayWhenReadyChangeReason int reason)
Called when the value returned fromPlayer.getPlayWhenReady()
changes.default void
<EMAIL_ADDRESS>int reason)
Deprecated.default void
onPositionDiscontinuity(Player.PositionInfo oldPosition, Player.PositionInfo newPosition, @com.google.android.exoplayer2.Player.DiscontinuityReason int reason)
Called when a position discontinuity occurs.default void
onRenderedFirstFrame()
Called when a frame is rendered for the first time since setting the surface, or since the renderer was reset, or since the stream being rendered was changed.default void
<EMAIL_ADDRESS>int repeatMode)
Called when the value ofPlayer.getRepeatMode()
changes.default void
onSeekBackIncrementChanged(long seekBackIncrementMs)
Called when the value ofPlayer.getSeekBackIncrement()
changes.default void
onSeekForwardIncrementChanged(long seekForwardIncrementMs)
Called when the value ofPlayer.getSeekForwardIncrement()
changes.default void
onShuffleModeEnabledChanged(boolean shuffleModeEnabled)
Called when the value ofPlayer.getShuffleModeEnabled()
changes.default void
onSkipSilenceEnabledChanged(boolean skipSilenceEnabled)
Called when skipping silences is enabled or disabled in the audio stream.default void
onSurfaceSizeChanged(int width, int height)
Called each time there's a change in the size of the surface onto which the video is being rendered.default void
onTimelineChanged(Timeline timeline, @com.google.android.exoplayer2.Player.TimelineChangeReason int reason)
Called when the value ofPlayer.getCurrentTimeline()
changes.default void
onTracksChanged(Tracks tracks)
Called when the value ofPlayer.getCurrentTracks()
changes.default void
onTrackSelectionParametersChanged(TrackSelectionParameters parameters)
Called when the value returned fromPlayer.getTrackSelectionParameters()
changes.default void
onVideoSizeChanged(VideoSize videoSize)
Called each time whenPlayer.getVideoSize()
changes.default void
onVolumeChanged(float volume)
Called when the value ofPlayer.getVolume()
changes.
-
-
-
Method Detail
-
onEvents
default void onEvents(Player player, Player.Events events)
Called when one or more player states changed.State changes and events that happen within one
Looper
message queue iteration are reported together and only after all individual callbacks were triggered.Listeners should prefer this method over individual callbacks in the following cases:
- They intend to trigger the same logic for multiple events (e.g. when updating a UI for
both
onPlaybackStateChanged(int)
andonPlayWhenReadyChanged(boolean, int)
). - They need access to the
Player
object to trigger further events (e.g. to callPlayer.seekTo(long)
after aonMediaItemTransition(MediaItem, int)
). - They intend to use multiple state values together or in combination with
Player
getter methods. For example usingPlayer.getCurrentMediaItemIndex()
with thetimeline
provided inonTimelineChanged(Timeline, int)
is only safe from within this method. - They are interested in events that logically happened together (e.g
onPlaybackStateChanged(int)
toPlayer.STATE_BUFFERING
because ofonMediaItemTransition(MediaItem, int)
).
- Parameters:
player
- ThePlayer
whose state changed. Use the getters to obtain the latest states.events
- ThePlayer.Events
that happened in this iteration, indicating which player states changed.
- They intend to trigger the same logic for multiple events (e.g. when updating a UI for
both
-
onTimelineChanged
default void onTimelineChanged(Timeline timeline, @TimelineChangeReason @com.google.android.exoplayer2.Player.TimelineChangeReason int reason)
Called when the value ofPlayer.getCurrentTimeline()
changes.Note that the current
MediaItem
or playback position may change as a result of a timeline change. If playback can't continue smoothly because of this timeline change, a separateonPositionDiscontinuity(PositionInfo, PositionInfo, int)
callback will be triggered.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
timeline
- The latest timeline. Never null, but may be empty.reason
- ThePlayer.TimelineChangeReason
responsible for this timeline change.
-
onMediaItemTransition
default void onMediaItemTransition(@Nullable MediaItem mediaItem, @MediaItemTransitionReason @com.google.android.exoplayer2.Player.MediaItemTransitionReason int reason)
Called when playback transitions to a media item or starts repeating a media item according to the currentrepeat mode
.Note that this callback is also called when the value of
Player.getCurrentTimeline()
becomes non-empty or empty.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
mediaItem
- TheMediaItem
. May be null if the playlist becomes empty.reason
- The reason for the transition.
-
onTracksChanged
default void onTracksChanged(Tracks tracks)
Called when the value ofPlayer.getCurrentTracks()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
tracks
- The available tracks information. Never null, but may be of length zero.
-
onMediaMetadataChanged
default void onMediaMetadataChanged(MediaMetadata mediaMetadata)
Called when the value ofPlayer.getMediaMetadata()
changes.This method may be called multiple times in quick succession.
onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
mediaMetadata
- The combinedMediaMetadata
.
-
onPlaylistMetadataChanged
default void onPlaylistMetadataChanged(MediaMetadata mediaMetadata)
Called when the value ofPlayer.getPlaylistMetadata()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.
-
onIsLoadingChanged
default void onIsLoadingChanged(boolean isLoading)
Called when the player starts or stops loading the source.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
isLoading
- Whether the source is currently being loaded.
-
onLoadingChanged
@Deprecated default void onLoadingChanged(boolean isLoading)
Deprecated.UseonIsLoadingChanged(boolean)
instead.
-
onAvailableCommandsChanged
default void onAvailableCommandsChanged(Player.Commands availableCommands)
Called when the value returned fromPlayer.isCommandAvailable(int)
changes for at least onePlayer.Command
.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
availableCommands
- The availablePlayer.Commands
.
-
onTrackSelectionParametersChanged
default void onTrackSelectionParametersChanged(TrackSelectionParameters parameters)
Called when the value returned fromPlayer.getTrackSelectionParameters()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
parameters
- The newTrackSelectionParameters
.
-
onPlayerStateChanged
@Deprecated default void onPlayerStateChanged(boolean playWhenReady, @State @com.google.android.exoplayer2.Player.State int playbackState)
Deprecated.UseonPlaybackStateChanged(int)
andonPlayWhenReadyChanged(boolean, int)
instead.
-
onPlaybackStateChanged
default void onPlaybackStateChanged(@State @com.google.android.exoplayer2.Player.State int playbackState)
Called when the value returned fromPlayer.getPlaybackState()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
playbackState
- The new playbackPlayer.State
.
-
onPlayWhenReadyChanged
default void onPlayWhenReadyChanged(boolean playWhenReady, @PlayWhenReadyChangeReason @com.google.android.exoplayer2.Player.PlayWhenReadyChangeReason int reason)
Called when the value returned fromPlayer.getPlayWhenReady()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
playWhenReady
- Whether playback will proceed when ready.reason
- ThePlayer.PlayWhenReadyChangeReason
for the change.
-
onPlaybackSuppressionReasonChanged
default void onPlaybackSuppressionReasonChanged(@PlaybackSuppressionReason @com.google.android.exoplayer2.Player.PlaybackSuppressionReason int playbackSuppressionReason)
Called when the value returned fromPlayer.getPlaybackSuppressionReason()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
playbackSuppressionReason
- The currentPlayer.PlaybackSuppressionReason
.
-
onIsPlayingChanged
default void onIsPlayingChanged(boolean isPlaying)
Called when the value ofPlayer.isPlaying()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
isPlaying
- Whether the player is playing.
-
onRepeatModeChanged
default void onRepeatModeChanged(@RepeatMode @com.google.android.exoplayer2.Player.RepeatMode int repeatMode)
Called when the value ofPlayer.getRepeatMode()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
repeatMode
- ThePlayer.RepeatMode
used for playback.
-
onShuffleModeEnabledChanged
default void onShuffleModeEnabledChanged(boolean shuffleModeEnabled)
Called when the value ofPlayer.getShuffleModeEnabled()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
shuffleModeEnabled
- Whether shuffling of media items is enabled.
-
onPlayerError
default void onPlayerError(PlaybackException error)
Called when an error occurs. The playback state will transition toPlayer.STATE_IDLE
immediately after this method is called. The player instance can still be used, andPlayer.release()
must still be called on the player should it no longer be required.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.Implementations of Player may pass an instance of a subclass of
PlaybackException
to this method in order to include more information about the error.- Parameters:
error
- The error.
-
onPlayerErrorChanged
default void onPlayerErrorChanged(@Nullable PlaybackException error)
Called when thePlaybackException
returned byPlayer.getPlayerError()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.Implementations of Player may pass an instance of a subclass of
PlaybackException
to this method in order to include more information about the error.- Parameters:
error
- The new error, or null if the error is being cleared.
-
onPositionDiscontinuity
@Deprecated default void onPositionDiscontinuity(@DiscontinuityReason @com.google.android.exoplayer2.Player.DiscontinuityReason int reason)
Deprecated.
-
onPositionDiscontinuity
default void onPositionDiscontinuity(Player.PositionInfo oldPosition, Player.PositionInfo newPosition, @DiscontinuityReason @com.google.android.exoplayer2.Player.DiscontinuityReason int reason)
Called when a position discontinuity occurs.A position discontinuity occurs when the playing period changes, the playback position jumps within the period currently being played, or when the playing period has been skipped or removed.
onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
oldPosition
- The position before the discontinuity.newPosition
- The position after the discontinuity.reason
- ThePlayer.DiscontinuityReason
responsible for the discontinuity.
-
onPlaybackParametersChanged
default void onPlaybackParametersChanged(PlaybackParameters playbackParameters)
Called when the value ofPlayer.getPlaybackParameters()
changes. The playback parameters may change due to a call toPlayer.setPlaybackParameters(PlaybackParameters)
, or the player itself may change them (for example, if audio playback switches to passthrough or offload mode, where speed adjustment is no longer possible).onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
playbackParameters
- The playback parameters.
-
onSeekBackIncrementChanged
default void onSeekBackIncrementChanged(long seekBackIncrementMs)
Called when the value ofPlayer.getSeekBackIncrement()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
seekBackIncrementMs
- ThePlayer.seekBack()
increment, in milliseconds.
-
onSeekForwardIncrementChanged
default void onSeekForwardIncrementChanged(long seekForwardIncrementMs)
Called when the value ofPlayer.getSeekForwardIncrement()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
seekForwardIncrementMs
- ThePlayer.seekForward()
increment, in milliseconds.
-
onMaxSeekToPreviousPositionChanged
default void onMaxSeekToPreviousPositionChanged(long maxSeekToPreviousPositionMs)
Called when the value ofPlayer.getMaxSeekToPreviousPosition()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
maxSeekToPreviousPositionMs
- The maximum position for whichPlayer.seekToPrevious()
seeks to the previous position, in milliseconds.
-
onAudioSessionIdChanged
default void onAudioSessionIdChanged(int audioSessionId)
Called when the audio session ID changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
audioSessionId
- The audio session ID.
-
onAudioAttributesChanged
default void onAudioAttributesChanged(AudioAttributes audioAttributes)
Called when the value ofPlayer.getAudioAttributes()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
audioAttributes
- The audio attributes.
-
onVolumeChanged
default void onVolumeChanged(float volume)
Called when the value ofPlayer.getVolume()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
volume
- The new volume, with 0 being silence and 1 being unity gain.
-
onSkipSilenceEnabledChanged
default void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled)
Called when skipping silences is enabled or disabled in the audio stream.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
skipSilenceEnabled
- Whether skipping silences in the audio stream is enabled.
-
onDeviceInfoChanged
default void onDeviceInfoChanged(DeviceInfo deviceInfo)
Called when the device information changesonEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
deviceInfo
- The newDeviceInfo
.
-
onDeviceVolumeChanged
default void onDeviceVolumeChanged(int volume, boolean muted)
Called when the value ofPlayer.getDeviceVolume()
orPlayer.isDeviceMuted()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
volume
- The new device volume, with 0 being silence and 1 being unity gain.muted
- Whether the device is muted.
-
onVideoSizeChanged
default void onVideoSizeChanged(VideoSize videoSize)
Called each time whenPlayer.getVideoSize()
changes.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
videoSize
- The new size of the video.
-
onSurfaceSizeChanged
default void onSurfaceSizeChanged(int width, int height)
Called each time there's a change in the size of the surface onto which the video is being rendered.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
width
- The surface width in pixels. May beC.LENGTH_UNSET
if unknown, or 0 if the video is not rendered onto a surface.height
- The surface height in pixels. May beC.LENGTH_UNSET
if unknown, or 0 if the video is not rendered onto a surface.
-
onRenderedFirstFrame
default void onRenderedFirstFrame()
Called when a frame is rendered for the first time since setting the surface, or since the renderer was reset, or since the stream being rendered was changed.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.
-
onCues
@Deprecated default void onCues(List<Cue> cues)
Deprecated.UseonCues(CueGroup)
instead.Called when the value ofPlayer.getCurrentCues()
changes.Both this method and
onCues(CueGroup)
are called when there is a change in the cues. You should only implement one or the other.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.
-
onCues
default void onCues(CueGroup cueGroup)
Called when the value ofPlayer.getCurrentCues()
changes.Both this method and
onCues(List)
are called when there is a change in the cues. You should only implement one or the other.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.
-
onMetadata
default void onMetadata(Metadata metadata)
Called when there is metadata associated with the current playback time.onEvents(Player, Events)
will also be called to report this event along with other events that happen in the sameLooper
message queue iteration.- Parameters:
metadata
- The metadata.
-
-


I was recently posed the question, “Can you use Mathematical Planning to optimize the Cutting Stock problem?” For those who are not familiar with this problem, you can find the Wikipedia article here. In summary, you have a stock size of paper material from which you need to produce smaller sizes. In the example provided on Wikipedia, the stock size is 5600mm. You are asked to produce a variety of sizes between 1380mm and 2200mm. The ideal plan is one which minimizes the amount of waste. This is a classic planning problem that can actually be reduced to the knapsack problem.
Note: Full code for this post can be found here
These are the cut lengths and quantities you need to produce in the example problem.
| Width [mm] | Number of Items |
|---|---|
| 1380 | 22 |
| 1520 | 25 |
| 1560 | 12 |
| 1710 | 14 |
| 1820 | 18 |
| 1880 | 18 |
| 1930 | 20 |
| 2000 | 10 |
| 2050 | 12 |
| 2100 | 14 |
| 2140 | 16 |
| 2150 | 18 |
| 2200 | 20 |
There are a variety of different ways you can cut the stock size into the smaller sizes. For example, you could produce 3 x 1820mm cuts from a 5600mm stock roll. You could also do 2200mm, 1820mm, and 1560mm. In total there are 308 possible combinations of cuts, not including the empty combination which has zero cuts. The most important thing to realize when approaching this problem is that the order you make the cuts does not matter. A more technical term would be that the order of cuts is commutative.
Generating the Possible Cuts
The most difficult part of this problem turned out to be the generating of the possible cuts.  A Plan
is a set of cuts. We want an algorithm which will generate the possible Plan
s for a set of Cut
s for our stock roll. To make our lives easier, I am going to go ahead and write some functions which allow us to work with these types more easily.
module Cut =
/// Take a Cut and return the length as a float
let length (Cut length) =
length
module Plan =
/// Give me a Plan with no cuts
let empty : Plan =
Plan Map.empty
/// Give me the total length of cuts in the plan
let length (Plan plan) =
plan
|> Seq.sumBy (fun (KeyValue(Cut cut, count)) -> cut * float count)
/// Add a Cut to a Plan and return a new Plan
let addCut (cut: Cut) (Plan plan) =
match Map.tryFind cut plan with
| Some count -> Plan (Map.add cut (count + 1) plan)
| None -> Plan (Map.add cut 1 plan)
/// Give me the count of each distinct cut in a given Plan
let cutCounts (Plan plan) =
plan
|> Seq.map (fun (KeyValue(cut, count)) -> cut, count)
We now have our domain for working in this space. Let’s talk about the function which will generate the possible Plan
s given a set of Cut
s and a Stock Length. We want something like this:
let generatePlans (stockLength: float) (cuts: Cut list) : Plan list =
// Do some magic here??
Now, I’m going to show you the answer that I came up with. What you are not seeing though is the couple of hours I spent with my notebook sketching out how this would work. It was not intuitive to me, so I don’t want you to think that this stuff just materializes out of thin air. I had to struggle. It was not intuitive but by the time I was done, I felt immense satisfaction.
The first thing I am going to do is sort cuts
from the shortest length to the longest and ensure that I only have distinct cuts.
let sortedCuts =
cuts
|> List.distinct
|> List.sortBy (fun (Cut length) -> length)
This algorithm is going to take advantage of the fact that the cuts are sorted from shortest to longest so that it can terminate early. Now I want to write a recursive function which is going to take an initially empty Plan
and try adding cuts to it. It will keep adding cuts until it exceeds the Stock Length. You can think of this as a sort of Constructive Heuristic. I’m going to show you the full function but then we will unpack it.
let rec generate (candidates: (Plan * Cut list) list) (approved: Plan list) =
match candidates with
| [] -> approved
| testCandidate::remainingCandidates ->
let plan, cuts = testCandidate
match cuts with
| [] ->
let newApproved = plan::approved
generate remainingCandidates newApproved
| nextCut::remainingCuts ->
if Plan.length plan + Cut.length nextCut <= stockLength then
let newPlan = Plan.addCut nextCut plan
let newCandidates = (newPlan, cuts)::(plan, remainingCuts)::remainingCandidates
generate newCandidates approved
else
let newApproved = plan::approved
generate remainingCandidates newApproved
We have a list of plans and possible cuts which we are exploring called candidates
. As candidates are approved, they are added to the approved
list of plans. Keep in mind, this function will be initially called with an empty Plan
and the full list of Cut
s available. Let’s go through the cases step by step.
match candidates with
| [] -> approved
This is the terminal case. We have evaluated all the Plan
s that were generated, and we return the Plan
s in the approved
list. Now for the case where we still have remaining candidates.
| testCandidate::remainingCandidates ->
let plan, cuts = testCandidate
In this case, there is at least one remaining candidate to evaluate, testCandidate
. We create plan
and cuts
values using structural unpacking of testCandidate
. plan
is the Plan
we are testing. cuts
is the list of possible cuts we can add to plan
. You will see that this list will shrink as our algorithm continues.
Now let’s match against the list of Cut
s to see what we should do.
match cuts with
| [] ->
let newApproved = plan::approved
generate remainingCandidates newApproved
If the list of cuts is empty, as indicated by the []
case, then we create newApproved
by adding plan
to approved
and calling generate
again. Now let’s look at the case where there are Cut
s remaining.
| nextCut::remainingCuts ->
if Plan.length plan + Cut.length nextCut <= stockLength then
let newPlan = Plan.addCut nextCut plan
let newCandidates = (newPlan, cuts)::(plan, remainingCuts)::remainingCandidates
generate newCandidates approved
else
let newApproved = plan::approved
generate remainingCandidates newApproved
We now look at nextCut
which we know is the shortest of the Cut
s in the list due to our sorting. We check that if we add this Cut
to plan
whether we will exceed the stockLength
limit. If we do not exceed the limit, we create a new plan newPlan
. We will add newPlan
to the list of candidates
with cuts
as the list of possible Cut
s to explore. We also add the current Plan
we are testing, plan
, to the list of candidates
but now with remainingCuts
as the possible Cut
s to add. Take your time with that. That puzzle took me awhile to figure out.
In the case that the length of nextCut
is too long, we add plan
to approved
and then continue to search the remaining candidates
.
We call our recursive function with an empty Plan
to start and the full list of Cut
s to get all the possible Plan
s we would want to consider.
let initialCandidate = Plan.empty, sortedCuts
generate [initialCandidate] []
The Optimization Problem
The optimization model for this is rather simple. We will create the list of possible Plan
s using the function we just described. We will associate an integer Decision
with each Plan
which is to indicate how many of each of those plans we will schedule. Let’s setup the data for our model so that we can build it.  We’ll open the namespaces we need and create our set of Decision
s associated with each Plan
in plans
. We are using SliceMaps to simplify formulation.
open Flips
open Flips.Types
open Flips.SliceMap
let planDecs =
DecisionBuilder "PlanCount" {
for plan in plans ->
Integer (0.0, infinity)
} |> SMap
We then need to calculate the number of each Cut
that is associated with each Plan
. This will be important for us to formulate the constraints around meeting the minimum cut requirements. We will store this information in a 2-D SliceMap
where the first index is the Plan
and the second index is the Cut
. The value in the SliceMap
is the number of a given Cut
in the Plan
.
let planCutCounts =
plans
|> Seq.collect (fun plan -> Plan.cutCounts plan
|> Seq.map (fun (cut, count) -> (plan, cut), float count)
) |> SMap2
It’s now actually simple to create our constraints. We will create a constraint for each Cut
in our data stating that the solution must meet the minimum quantity of each Cut
.
let cutRequirementConstraints =
ConstraintBuilder "CutRequirements" {
for cut in cuts ->
sum (planDecs .* planCutCounts.[All, cut]) >== cutRequirements.[cut]
}
Our objective is to minimize the total number of stock rolls required to meet the demand for each Cut
.
let objective = Objective.create "MinRolls" Minimize (sum planDecs)
We combine these into our model and solve.
let model =
Model.create objective
|> Model.addConstraints cutRequirementConstraints
let result = Solver.solve Settings.basic model
Let’s go ahead and provide some nice printing of the results to the console.
match result with
| Optimal solution ->
let values =
Solution.getValues solution planDecs
|> Map.filter (fun _ quantity -> quantity > 0.0)
let totalNumberOfRolls =
values
|> Seq.sumBy (fun (KeyValue(_, count)) -> count)
printfn "Quantity | Plan"
for KeyValue(plan, quantity) in values do
printfn $"%8.0f{quantity} | {plan}"
printfn "=========================================="
printfn $"Total Number of Rolls: {totalNumberOfRolls}"
printfn "=========================================="
| _ -> failwith "Unable to solve"
When you run the full script, you will see the following printed out.
Quantity | Plan
8 | Plan (map [(Cut 1380.0, 1); (Cut 2000.0, 1); (Cut 2200.0, 1)])
7 | Plan (map [(Cut 1380.0, 1); (Cut 2050.0, 1); (Cut 2150.0, 1)])
7 | Plan (map [(Cut 1380.0, 1); (Cut 2100.0, 2)])
10 | Plan (map [(Cut 1520.0, 1); (Cut 1880.0, 1); (Cut 2200.0, 1)])
10 | Plan (map [(Cut 1520.0, 1); (Cut 1930.0, 1); (Cut 2140.0, 1)])
3 | Plan (map [(Cut 1520.0, 1); (Cut 1930.0, 1); (Cut 2150.0, 1)])
2 | Plan (map [(Cut 1520.0, 1); (Cut 2000.0, 1); (Cut 2050.0, 1)])
2 | Plan (map [(Cut 1560.0, 1); (Cut 1820.0, 1); (Cut 2200.0, 1)])
8 | Plan (map [(Cut 1560.0, 1); (Cut 1880.0, 1); (Cut 2150.0, 1)])
1 | Plan (map [(Cut 1560.0, 2); (Cut 2050.0, 1)])
2 | Plan (map [(Cut 1710.0, 1); (Cut 1820.0, 1); (Cut 2050.0, 1)])
6 | Plan (map [(Cut 1710.0, 2); (Cut 2140.0, 1)])
7 | Plan (map [(Cut 1820.0, 2); (Cut 1930.0, 1)])
==========================================
Total Number of Cuts: 73
==========================================
If you check the Wikipedia article, you will see that the best possible answer is 73. There are multiple, equally good solutions. This is called Degeneracy. Problems with high levels of Degeneracy can be difficult to solve but fortunately this one was not. You may run this code on your machine and get a different set of plans, but you’ll still have a total of 73 stock rolls required.
Next Steps
This was a fun challenge and was a bit of a brain teaser. These types of problems are everywhere in manufacturing planning and scheduling. Minimizing the amount of raw resources required is incredibly important but can be brutally difficult. It’s often done by domain experts spending hours with Excel finding a plan that meets all the requirements. These are some of my favorite problems to turn into Mathematical Planning models. Thank you for your time and I look forward to chatting next week!
Please send me an email at<EMAIL_ADDRESS>if you have any questions and subscribe so you can stay on top new posts and products I am offering.


Features
Toolbar¶
For those people who prefer their commands front-and-center, available all the time with a single click, this extension adds a new Extensibility Logs toolbar. You'll need to enable the toolbar before you'll see it.
Menu¶
For those people who don't want to add yet another toolbar, this extension also adds a new Extensibility Logs menu to the View menu.
Logs¶
Each of the logs can be individually disabled, or all logs disabled together.
Activity Log¶
Opens Visual Studio's Activity Log in a tab in Visual Studio, without having to first remember where the file is stored, and then open it in your editor of choice.
- Folder: %APPDATA%\Microsoft\VisualStudio\instance_id\
- File: ActivityLog.xml
Diagnostic Failure Log¶
Opens MSBuild's latest Diagnostic Failure Log in a tab in Visual Studio, without knowing how to find it first, and then open it in your editor of choice.
- Folder: %TEMP%
- Files: MSBuild_*.failure.log
MEF Error Log¶
Opens Visual Studio's MEF Error Log in a tab in Visual Studio, without having to search for it, and then open it in your editor of choice.
- Folder: %LOCALAPPDATA%\Microsoft\VisualStudio\instance_id\ComponentModelCache
- File: Microsoft.VisualStudio.Default.err
Service Hub Log¶
Opens the latest Service Hub Log in a tab in Visual Studio, without first knowing how to it first, and then open it in your editor of choice.
- Folder: %TEMP%\servicehub\logs
- Files: VsixServiceDiscovery-*.log
Visual Studio Setup Log¶
Opens the latest Visual Studio Setup Log in a tab in Visual Studio, without scrambling to find it, and then open it in your editor of choice.
- Folder: %TEMP%
- Files: dd_setup_*.log
VSIX Installer Log¶
Opens the latest VSIX Installer Log in a tab in Visual Studio, without knowing what the file's called and how to find it, and then open it in your editor of choice.
- Folder: %TEMP%
- Files: dd_VSIXInstaller_*.log
Other¶
Environment Variables¶
Displays the environment variables for the current process in a tab in Visual Studio, without having to open a command prompt and issue a SET command.
Path Variables¶
Displays Windows' current search paths for executable files in a tab in Visual Studio, without having to open a command prompt and issue a PATH command.
Visual Studio Folder¶
Opens the current Visual Studio instance's folder in a File Explorer window, without having to first remember the location of the folder, and then open it in an external File Explorer window.
- Folder: %LOCALAPPDATA%\Microsoft\VisualStudio\instance_id\
Options¶
Any commands that have been disabled will still appear on the toolbar, but will be inactive, but they won't appear in the menu. The toolbar buttons can be hidden by removing them from the Extensibility Logs toolbar.
General Options¶
Enable Extensibility Logs¶
This setting allows the whole set of Extensibility Logs features to be turned off together.
Version Number¶
Displays then version number of Extensibility Logs that's currently installed.
Logs Options¶
Enable Logs Features¶
This setting allows the whole set of Logs features to be turned off together.
Enable Activity Log¶
The Activity Log feature can be disabled by setting Tools | Options | Extensibility Logs | Enable Activity Log
to false
.
Enable Diagnostic Failure Log¶
The Diagnostic Failure Log feature can be disabled by setting Tools | Options | Extensibility Logs | Enable Diagnostic Log
to false
.
Enable MEF Error Log¶
The MEF Error Log feature can be disabled by setting Tools | Options | Extensibility Logs | Enable MEF Error Log
to false
.
Enable Service Hub Log¶
The MEF Error Log feature can be disabled by setting Tools | Options | Extensibility Logs | Enable Service Hub Log
to false
.
Enable Visual Studio Setup Log¶
The Visual Studio Setup Log feature can be disabled by setting Tools | Options | Extensibility Logs | Enable Visual Studio Setup Log
to false
.
Enable VSIX Installer Log¶
The VSIX Installer Log feature can be disabled by setting Tools | Options | Extensibility Logs | Enable VSIX Installer Log
to false
.
Other Options¶
Enable Other Features¶
This setting allows the whole set of Other features to be turned off together.
Enable Environment Variables¶
The Environment Variables feature can be disabled by setting Tools | Options | Extensibility Logs | Enable Environment Variables
to false
.
Enable Path Variables¶
The Path Variables feature can be disabled by setting Tools | Options | Extensibility Logs | Enable Path Variables
to false
.
Enable Visual Studio Folder¶
The Visual Studio Folder feature can be disabled by setting Tools | Options | Extensibility Logs | Enable Open Visual Studio Folder
to false
.


I recieved 28 grams of Pharmaceutical grade Kanna in the mail from a well known vendor. Seeing the less-than-enthusiastic reports I read on kanna, I figured this needed submission
About me: Chronic user of cannabis, plus experiences with too many things to bother naming. Fairly good health.
Mood and Mindset: With Girlfriend and her brother, happy and excited (for getting to try a whole new array of legal products).
I busted out my trusty coffee grinder and scale, and began powdering .5 grams of the milled and chunky mixture of shredded brown and yellow bits. Realising the harder bits would never powder, I simply scraped what powder crusted/clumped/collected in the corners (much in the same way a cannabis addict does when out of pot). I I repeated grinding and scraping untill no more brown clumpy powder would build up. I got about .3g of material.
We split this into 9 small lines. I sure was surprised at how potent it was. The first line didnt burn or hurt very much, a little discomfort, but for snorting plant matter, not bad. Wasn't sure if effect was placebo, so I tried another one. We all experienced the same effect, and almost instantaneous (10 seconds to a minute) 'rush' or 'wave' of euphoria go over the body. followed quickly by sweaty palms, and then strong relaxation, slight sedation.
After a third line (over 45 minutes or so) I didnt really feel like I needed anymore, it was almost like just parts of being stoned.  Very relaxing, great stuff. Smoked a pipebowl of marijuana, synergised well, kind of overpowered kanna a little, but it was major couchlock from pot that didn't really give you couchlock. Kanna is a keeper.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


07. Constructing Links
Hyperlinks
The power of the web is that pages can lead to other pages. When you click on a link on a web page, it takes you to another page. This link is called a hyperlink.
Hyperlinks are created with anchor elements, which generally look like:
Udacity
and render on the page like this: Udacity.
Inside the opening a
tag there is href
, which stands for "reference." This is called an attribute. Attributes like href
describe the properties of HTML elements. In this case, the href
attribute is the target URL that the link will open. The content inside the anchor element is the text that users see displayed on the page.
This is the format that you must use when you make hyperlinks! Note:
- There is a space between
a
andhref
. - There are no spaces around the
=
. - The website has two
"
around it. - There are no spaces between the
href
attribute and the>
of the opening tag.
How to Complete this Quiz
For this quiz, I want you to make your first hyperlink! On the next quiz, I'll give you a URL and the text that needs to be displayed. It will be your job to write the link!
Constructing Links
SOLUTION:
NOTE: The solutions are expressed in RegEx pattern. Udacity uses these patterns to check the given answer


 Popularly known as Sakhi, the scheme is being implemented since 1st April 2015. These Centres are being established across the country to provide integrated support and assistance under one roof to women affected by violence, both in private and public spaces in phased manner.
Objectives
The objectives of the Scheme are
To provide integrated support and assistance to women affected by violence, both in private and public spaces under one roof.
To facilitate immediate, emergency and non - emergency access to a range of services including medical, legal, psychological and counselling support under one roof to fight against any forms of violence against women.
Services Provided
Emergency Response and Rescue Services
Medical assistance
Assistance to women in lodging FIR /NCR/DIR
Psycho - social support/ counselling
Legal aid and counselling
Food, Clothing and Shelter
Video Conferencing Facility
Helping in reaching out the family of victims
Ensuring safety and security of the victims
Fighting for women rights


Wexford is an important retail centre for the south eastern corner of Ireland. The town lies on the south side of the harbour, in the estuary of the River Slaney.
This harbour is best entered 2 hours each side of HW. In strong on-shore winds the seas can break over the bar.
Take care to follow the marked channel. It is advisable to check the latest plan
Yachts berth on the long pontoon just below the bridge. There is a sheltered anchorage in 2.3m off the town quays, but the tidal streams can be strong.


Here's some slightly longer sample text
That may vary in height between browsers.
Nicholson can you help deal with this kind of shenanigans easily.
Don't you think that's fantastic?


Ghent, Belgium
Antwerp, Belgium
Paris, France
New York, US
San Francisco, US
Amsterdam, NL
French Alps
Mt. Ventoux, France
Bergen, Norway
Tokyo, Japan
Capetown, South Africa
Kinshasa, Congo
Click 2 times anywhere on the map


This Cinema 4D student version has not yet been activated.To request your Activation Code please click on the link below and login to your MAXON Student License account.
After you have received your Activation Code by email (subject: 'Your Cinema 4D Student Activation Code'), click on the 'Enter Activation Code' button below and copy & paste your Activation Code from the email. Please note that the Activation Code will only work on the computer on which you started the activation process. |


| 1 | /* | |
| 2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
| 3 | * contributor license agreements. See the NOTICE file distributed with | |
| 4 | * this work for additional information regarding copyright ownership. | |
| 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
| 6 | * (the "License"); you may not use this file except in compliance with | |
| 7 | * the License. You may obtain a copy of the License at | |
| 8 | * | |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 | * | |
| 11 | * Unless required by applicable law or agreed to in writing, software | |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 | * See the License for the specific language governing permissions and | |
| 15 | * limitations under the License. | |
| 16 | */ | |
| 17 | package org.apache.commons.collections4; | |
| 18 | ||
| 19 | import org.apache.commons.collections4.trie.UnmodifiableTrie; | |
| 20 | ||
| 21 | /** | |
| 22 | * A collection of {@link Trie} utilities. | |
| 23 | * | |
| 24 | * @since 4.0 | |
| 25 | * @version $Id: TrieUtils.java 1686855 2015-06-22 13:00:27Z tn $ | |
| 26 | */ | |
| 27 | public class TrieUtils { | |
| 28 | ||
| 29 | /** | |
| 30 | * {@link TrieUtils} should not normally be instantiated. | |
| 31 | */ | |
| 32 | private TrieUtils() {} | |
| 33 | ||
| 34 | /** | |
| 35 | * Returns an unmodifiable instance of a {@link Trie} | |
| 36 | * | |
| 37 | * @param <K> the key type | |
| 38 | * @param <V> the value type | |
| 39 | * @param trie the trie to make unmodifiable, must not be null | |
| 40 | * @return an unmodifiable trie backed by the given trie | |
| 41 | * @throws NullPointerException if trie is null | |
| 42 | * | |
| 43 | * @see java.util.Collections#unmodifiableMap(java.util.Map) | |
| 44 | */ | |
| 45 | public static <K, V> Trie<K, V> unmodifiableTrie(final Trie<K, ? extends V> trie) { | |
| 46 |
1
1. unmodifiableTrie : mutated return of Object value for org/apache/commons/collections4/TrieUtils::unmodifiableTrie to ( if (x != null) null else throw new RuntimeException ) → KILLED |
return UnmodifiableTrie.unmodifiableTrie(trie); |
| 47 | } | |
| 48 | ||
| 49 | } | |
Mutations | ||
| 46 |
1.1 |


carousel-inner
Item elementThe item element will need to be set up with the following child elements:
...
all bootstrap formating will work here to include image responsiveness.
Sample text here...
carousel-control
elementThis item has no change to it. only the styling is changed to not overlap the item elements at trigger hover events for item hover events
.carousel-inner
element.carousel-control{
cursor:pointer;
}
.carousel-inner .active.left{
left: -25%;
}
.carousel-inner .next{
left:25%;
}
.carousel-inner .prev{
left:-25%;
}
.carousel-control{
width:4%;
}
.carousel-control.left{
margin-left:0;
background-image:none;
}
.carousel-control.right{
margin-right:0;
background-image:none;
}
Sample text here...
nav-carousel
AKA: carousel-indicator
this replaces the carousel-indicator
with a Bootstrap Navbar styling for responsiveness in any viewport width
List Element.nav-justified
, and one new custom styled element called .nav-carousel
list-item element
- One
- Two
- Three
- Four
- Five
As you see you still target the carousel with the carousel id. in this case I named the carousel id="thumbCarousel"
or #thumbCarousel
if you want to target that specific carousel.data-slide-to
Elementdata-slide-to="NUM"
to target each individual slide item.
#thumbCarousel
jQuery Scriptthis replaces the carousel-indicator
with a Bootstrap Navbar styling for responsiveness in any viewport width


JavaScript Task Manager App
made with jQuery and JSON!
Add Task
Task List:
Delete All Tasks
Show/Hide contact form
Name
Email
Message
Leave feedback here
Submit


[
prev
] [
prev-tail
] [
tail
] [
up
]
6.4
Discrete Cosine transform
to be written
[
prev
] [
prev-tail
] [
front
] [
up
]


|
Petri Net Plans
|
Exploration policy that exploits with an hysteresis. More...
#include <ExploitWithHysteresis.h>
Public Member Functions | |
| ExploitWithHysteresis (const std::string &planName, double hysteresis, bool remember=true) | |
| Ctor. | |
| virtual | ~ExploitWithHysteresis () |
| MemoryType * | getPolicy () |
Static Public Member Functions | |
| static void | clearMemory () |
| Deletes the previous policies of all plans. | |
| static void | forget (const std::string &planName) |
| Deletes the previous policy of a specific plan. |
Exploration policy that exploits with an hysteresis.
This class remembers the policy of the last episode. In each choice point, it switches to the new best policy only if it is hysteresis
times better. If hysteresis == 0 it is equivalent to Exploit.
With hysteresis = std::numeric_limits<double>::max() it may be used to execute the last policy exactly as it was (no switch can take place).
It maintains the last policy in memory, so it is not robust to restarts (as opposed to Learner that stores the value function in a file). Such a memory is indicized by the plan name, therefore it must be provided to the constructor.
| learnpnp::ExploitWithHysteresis::ExploitWithHysteresis | ( | const std::string & | planName, |
| double | hysteresis, | ||
| bool | remember = true |
||
| ) |
Ctor.
| planName | the name of the plan, used to retrieve the last policy for that plan |
| hysteresis | the number of time the new value must be better than the old one for a switch. 0 is neutral. |
| remember | whether or not it must remember the choice during the same episode (rather than making a new choice every time a choice point is encountered). Defaults to true. |
| virtual learnpnp::ExploitWithHysteresis::~ExploitWithHysteresis | ( | ) | [virtual] |
| static void learnpnp::ExploitWithHysteresis::clearMemory | ( | ) | [static] |
Deletes the previous policies of all plans.
ATTENTION: the current implementation invalidates all instances of this class that would hold a pointer to the deleted memory.
| static void learnpnp::ExploitWithHysteresis::forget | ( | const std::string & | planName | ) | [static] |
Deletes the previous policy of a specific plan.


/**
* A GameAction that handles Mouse events
* @name MouseAction
* @class MouseAction
* @extends {GameAction}
*/
define([
'dcl',
'dcl/bases/Mixer',
'./GameAction'
], function(dcl, Mixer, GameAction){
'use strict';
return dcl([Mixer, GameAction], {
startPosition: null,
endPosition: null,
position: null
});
});