Shared library for use by V-REP (from Coppelia Robotics). More...
Classes | |
| struct | State |
| Data structure that contains an object state. More... | |
| struct | Device |
| Data structure that contains a haptic device handle and related state information. More... | |
| class | Object |
| Data structure that contains an object of type ObjectType used to generate haptic feedback. More... | |
Macros | |
| #define | CONCAT(x, y, z) x y z |
| #define | strConCat(x, y, z) CONCAT(x,y,z) |
| #define | LUA_START_COMMAND "simExtCHAI3D_start" |
| #define | LUA_RESET_COMMAND "simExtCHAI3D_reset" |
| #define | LUA_ADD_SHAPE_COMMAND "simExtCHAI3D_addShape" |
| #define | LUA_ADD_CONSTRAINT_POINT_COMMAND "simExtCHAI3D_addConstraintPoint" |
| #define | LUA_ADD_CONSTRAINT_SEGMENT_COMMAND "simExtCHAI3D_addConstraintSegment" |
| #define | LUA_ADD_CONSTRAINT_PLANE_COMMAND "simExtCHAI3D_addConstraintPlane" |
| #define | LUA_UPDATE_SHAPE_COMMAND "simExtCHAI3D_updateShape" |
| #define | LUA_UPDATE_CONSTRAINT_COMMAND "simExtCHAI3D_updateConstraint" |
| #define | LUA_REMOVE_OBJECT_COMMAND "simExtCHAI3D_removeObject" |
| #define | LUA_READ_POSITION_COMMAND "simExtCHAI3D_readPosition" |
| #define | LUA_READ_FORCE_COMMAND "simExtCHAI3D_readForce" |
| #define | LUA_READ_BUTTONS_COMMAND "simExtCHAI3D_readButtons" |
Enumerations | |
| enum | ObjectType { SHAPE, CONSTRAINT_POINT, CONSTRAINT_SEGMENT, CONSTRAINT_PLANE } |
| Types of haptic objects. More... | |
Functions | |
| int | addObject (Object *object) |
| Add generic object to the scene. More... | |
| bool | updateShape (int objectID, float pos[3], float rot[3], float stiffnessFactor) |
| Update the parameters of a SHAPE haptic object. More... | |
| bool | updateConstraint (int objectID, float pos[3], float dir[3], float Kp, float Kv, float Fmax) |
| Update the parameters of a constraint haptic object. More... | |
| bool | removeObject (int objectID) |
| Safely remove an object from the object list. More... | |
| bool | removeObject (Object *object) |
| Safely remove an object from the object list. More... | |
| void | hapticLoop () |
| Main haptic loop. More... | |
| void | hapticStart () |
| Start the haptic loop. More... | |
| void | hapticStop () |
| Stop the haptic loop. More... | |
| bool | hapticConnect (int deviceIndex, float toolRadius, float workspaceRadius) |
| bool | hapticDisconnect (int index) |
| Disconnect from haptic device. More... | |
| void | hapticReset () |
| Clean up the scene. More... | |
| void | LUA_START_CALLBACK (SLuaCallBack *p) |
| Connect to a haptic device. More... | |
| void | LUA_RESET_CALLBACK (SLuaCallBack *p) |
| Disconnect from a haptic device and reset the scene. More... | |
| void | LUA_ADD_SHAPE_CALLBACK (SLuaCallBack *p) |
| Add a SHAPE object to the scene. More... | |
| void | LUA_ADD_CONSTRAINT_POINT_CALLBACK (SLuaCallBack *p) |
| Add a CONSTRAINT_POINT object to the scene. More... | |
| void | LUA_ADD_CONSTRAINT_SEGMENT_CALLBACK (SLuaCallBack *p) |
| Add a CONSTRAINT_SEGMENT object to the scene. More... | |
| void | LUA_ADD_CONSTRAINT_PLANE_CALLBACK (SLuaCallBack *p) |
| Add a CONSTRAINT_PLANE object to the scene. More... | |
| void | LUA_UPDATE_SHAPE_CALLBACK (SLuaCallBack *p) |
| Update the parameters of a SHAPE haptic object. More... | |
| void | LUA_UPDATE_CONSTRAINT_CALLBACK (SLuaCallBack *p) |
| Update the parameters of a constraint haptic object. More... | |
| void | LUA_REMOVE_OBJECT_CALLBACK (SLuaCallBack *p) |
| Safely remove an object from the object list. More... | |
| void | LUA_READ_POSITION_CALLBACK (SLuaCallBack *p) |
Retrieve the current position of a haptic device (identified by its deviceIndex ) in the scene. More... | |
| void | LUA_READ_FORCE_CALLBACK (SLuaCallBack *p) |
Retrieve the force currently displayed by a haptic device (identified by its deviceIndex ). More... | |
| void | LUA_READ_BUTTONS_CALLBACK (SLuaCallBack *p) |
Retrieve a haptic device (identified by its deviceIndex ) end-effector buttons status. More... | |
| VREP_DLLEXPORT unsigned char | v_repStart (void *reservedPointer, int reservedInt) |
| V-REP shared library initialization. More... | |
| VREP_DLLEXPORT void | v_repEnd () |
| V-REP shared library disconnect. More... | |
| VREP_DLLEXPORT void * | v_repMessage (int message, int *auxiliaryData, void *customData, int *replyData) |
| V-REP shared library message processing callback. More... | |
Please refer to the introduction for more information on how to use the CHAI3D plugin for V-REP.
| #define CONCAT | ( | x, | |
| y, | |||
| z | |||
| ) | x y z |
| #define strConCat | ( | x, | |
| y, | |||
| z | |||
| ) | CONCAT(x,y,z) |
| #define LUA_START_COMMAND "simExtCHAI3D_start" |
| #define LUA_RESET_COMMAND "simExtCHAI3D_reset" |
| #define LUA_ADD_SHAPE_COMMAND "simExtCHAI3D_addShape" |
| #define LUA_ADD_CONSTRAINT_POINT_COMMAND "simExtCHAI3D_addConstraintPoint" |
| #define LUA_ADD_CONSTRAINT_SEGMENT_COMMAND "simExtCHAI3D_addConstraintSegment" |
| #define LUA_ADD_CONSTRAINT_PLANE_COMMAND "simExtCHAI3D_addConstraintPlane" |
| #define LUA_UPDATE_SHAPE_COMMAND "simExtCHAI3D_updateShape" |
| #define LUA_UPDATE_CONSTRAINT_COMMAND "simExtCHAI3D_updateConstraint" |
| #define LUA_REMOVE_OBJECT_COMMAND "simExtCHAI3D_removeObject" |
| #define LUA_READ_POSITION_COMMAND "simExtCHAI3D_readPosition" |
| #define LUA_READ_FORCE_COMMAND "simExtCHAI3D_readForce" |
| #define LUA_READ_BUTTONS_COMMAND "simExtCHAI3D_readButtons" |
| enum ObjectType |
Each Object in the scene must be assigned one of the following types.
| Enumerator | |
|---|---|
| SHAPE |
Arbitrary 3D mesh object. |
| CONSTRAINT_POINT |
Constraint that holds the haptic device at a given point. The point is defined by State::Pos. |
| CONSTRAINT_SEGMENT |
Constraint that holds the haptic device on a given segment. The segment is defined by a point (State::Pos) and a vector (State::Dir). |
| CONSTRAINT_PLANE |
Constraint that holds the haptic device on a given plane. The plane is defined by a point (State::Pos) and a normal direction (State::Dir). |
| int addObject | ( | Object * | object | ) |
| bool updateShape | ( | int | objectID, |
| float | pos[3], | ||
| float | rot[3], | ||
| float | stiffnessFactor | ||
| ) |
| objectID | object identifier (returned by addObject). |
| pos | new target SHAPE target position, expressed in m. |
| rot | new target SHAPE orientation in the scene, expressed as ZYX extrinsic Euler angles. |
| stiffnessFactor | new target object stiffness factor (between 0.0 and 1.0). |
| bool updateConstraint | ( | int | objectID, |
| float | pos[3], | ||
| float | dir[3], | ||
| float | Kp, | ||
| float | Kv, | ||
| float | Fmax | ||
| ) |
| objectID | object identifier (returned by addObject). |
| pos | new constraint position in the scene, expressed in m. |
| dir | new constraint direction, as defined in ObjectType. |
| Kp | new constraint stiffness factor (between 0.0 and 1.0). |
| Kv | new constraint viscosity factor (between 0.0 and 1.0). |
| Fmax | new constraint max force for Kp, expressed in N. |
| bool removeObject | ( | int | objectID | ) |
| objectID | object identifier (returned by addObject). |
| bool removeObject | ( | Object * | object | ) |
| object | pointer to object to remove. |
| void hapticLoop | ( | ) |
The haptic loop runs in the background (with high priority) and renders all Objects haptically to all devices in the scene. Use hapticStart() to start the haptic loop, and hapticReset() to stop it.
| void hapticStart | ( | ) |
| void hapticStop | ( | ) |
| bool hapticConnect | ( | int | deviceIndex, |
| float | toolRadius, | ||
| float | workspaceRadius | ||
| ) |
\brief Connect to a haptic device and add it to the scene.
If successful, the device is added to the device list and will be controlled by the hapticLoop().
| deviceIndex | index of the device to open in the list of devices detected by the operating system. This is guaranteed to be the same between executions as long as no hardware changes occur. |
| toolRadius | radius of the haptic device proxy (tool) in the simulated scene, expressed in m. |
| workspaceRadius | radius of the simulated workspace that the physical device workspace must be scaled to, expressed in m. |
| bool hapticDisconnect | ( | int | index | ) |
This will remove all objects associated with this particular device, and will remove the device from the scene.
| index | index of the device to disconnect. This should be the same as the index given to hapticConnect(). |
| void hapticReset | ( | ) |
This function disconnects all devices and removes all objects from the scene.
| void LUA_START_CALLBACK | ( | SLuaCallBack * | p | ) |
This LUA callback is a wrapper for hapticConnect().
The arguments parsed from the p
buffer are passed on to hapticConnect(int deviceIndex, float toolRadius, float workspaceRadius).
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| void LUA_RESET_CALLBACK | ( | SLuaCallBack * | p | ) |
This LUA callback is a wrapper for hapticReset().
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| void LUA_ADD_SHAPE_CALLBACK | ( | SLuaCallBack * | p | ) |
This LUA callback is a wrapper for addObject() and Object::Object().
The arguments parsed from the p
buffer are passed on to Object::Object(float pos[3], float rot[3], vector<float>vertices, vector<int> indices, float stiffnessFactor).
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| void LUA_ADD_CONSTRAINT_POINT_CALLBACK | ( | SLuaCallBack * | p | ) |
This LUA callback is a wrapper for addObject() and Object::Object().
The arguments parsed from the p
buffer are passed on to Object::Object(ObjectType constraintType, int device, float pos[3], float dir[3], float Kp, float Kv, float Fmax).
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| void LUA_ADD_CONSTRAINT_SEGMENT_CALLBACK | ( | SLuaCallBack * | p | ) |
This LUA callback is a wrapper for addObject() and Object::Object().
The arguments parsed from the p
buffer are passed on to Object::Object(ObjectType constraintType, int device, float pos[3], float dir[3], float Kp, float Kv, float Fmax).
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| void LUA_ADD_CONSTRAINT_PLANE_CALLBACK | ( | SLuaCallBack * | p | ) |
This LUA callback is a wrapper for addObject() and Object::Object().
The arguments parsed from the p
buffer are passed on to Object::Object(ObjectType constraintType, int device, float pos[3], float dir[3], float Kp, float Kv, float Fmax).
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| void LUA_UPDATE_SHAPE_CALLBACK | ( | SLuaCallBack * | p | ) |
This LUA callback is a wrapper for updateShape().
The arguments parsed from the p
buffer are passed on to updateShape(int objectID, float pos[3], float rot[3], float stiffnessFactor).
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| void LUA_UPDATE_CONSTRAINT_CALLBACK | ( | SLuaCallBack * | p | ) |
This LUA callback is a wrapper for updateShape().
The arguments parsed from the p
buffer are passed on to updateConstraint(int objectID, float pos[3], float dir[3], float Kp, float Kv, float Fmax).
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| void LUA_REMOVE_OBJECT_CALLBACK | ( | SLuaCallBack * | p | ) |
This LUA callback is a wrapper for removeObject().
The arguments parsed from the p
buffer are passed on to removeObject(int objectID).
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| void LUA_READ_POSITION_CALLBACK | ( | SLuaCallBack * | p | ) |
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| void LUA_READ_FORCE_CALLBACK | ( | SLuaCallBack * | p | ) |
| void LUA_READ_BUTTONS_CALLBACK | ( | SLuaCallBack * | p | ) |
The buttons are returned in the form of an array of bit. A bit state of 1
indicates that the button at the given bit array index is pressed, 0
means it is not.
| p | SLuaCallBack I/O buffer. |
The corresponding LUA function is:
| VREP_DLLEXPORT unsigned char v_repStart | ( | void * | reservedPointer, |
| int | reservedInt | ||
| ) |
| VREP_DLLEXPORT void v_repEnd | ( | ) |
| VREP_DLLEXPORT void* v_repMessage | ( | int | message, |
| int * | auxiliaryData, | ||
| void * | customData, | ||
| int * | replyData | ||
| ) |
| bool SimulationRunning |
| cThread* HapticThread |
| cMutex* SimulationLock |
| cMutex* SceneLock |
| cMutex* ObjectLock |
| vector<Object*> Objects |
| cHapticDeviceHandler* DeviceHandler |
| cWorld* World |
| map<int,cGenericHapticDevicePtr> Devices |
| map<int,Device*> Cursors |
| cPrecisionClock Clock |
| double BiggestRadius = 0.0 |
| double LowestStiffness = -1.0 |
| LIBRARY vrepLib |
| const int inArgs_START[] |
| const int inArgs_RESET[] |
| const int inArgs_ADD_SHAPE[] |
| const int inArgs_ADD_CONSTRAINT_POINT[] |
| const int inArgs_ADD_CONSTRAINT_SEGMENT[] |
| const int inArgs_ADD_CONSTRAINT_PLANE[] |
| const int inArgs_UPDATE_SHAPE[] |
| const int inArgs_UPDATE_CONSTRAINT[] |
| const int inArgs_REMOVE_OBJECT[] |
| const int inArgs_READ_POSITION[] |
| const int inArgs_READ_FORCE[] |
| const int inArgs_READ_BUTTONS[] |


Create a HTML page like the image below. Make sure that the whole webpage doesn’t reload every time the user clicks on a link to change the image shown in the box. Use iframe tag.
Create two HTML pages like the image below (100% accuracy is not required). Use frames for the layout of the first one. Use semantic tags and CSS for the layout of the second one.
Create a web page like the image below (100% accuracy is preferable) and make its HTML Semantic. Use some kind of approach to support old (non-HTML5-compatible) Web browsers like IE6-IE8.


|
SAFETY ZONE - the 2x4 area in the
middle of the board (the marked cells in the diagram).
|
|
STACK - a stack may have stones
of either color. The owner of a stack is the owner of the upper stone.
|
|
TURN
- On each turn, each player
moves on of his stacks.
|
A stack can move diagonally forward
to an empty cell. |
|
A stack can also jump over a stack
landing on the immediate next empty cell.
|
Jumps can be made in any
direction except (diagonally or orthogonally) backwards.
|
|
After the jump, the player
places a friendly stone on top of the jumped stack if it
belongs to the opponent. |
|
Jumps are not mandatory. |
|
Jumps cannot be made over stacks
inside the safety zone or in the stack's first row. |
|
Stacks at the last row, can move
sideways or jump
sideways over friendly stacks if that's the only way to make
room for another stack. |
|
|
|
GOAL - A player wins by
either filling his last row with stacks (meaning that if
the adversary doesn't move all of his pieces out, he only has to fill
up the empty cells) or by moving all of his stacks into the last row
if the player does not control eight stacks. |
|


M.S. in Intelligent Robotics
Ph.D. Programs
The majority of robotics Ph.D. students are in the
Computer Science Department; here is the information about the CS Ph.D. Program.
Ph.D. students in other departments can also pursue robotics research by working with
RASC faculty.


ELF.JS is a simple and efficient JavaScript framework. It not only places a great emphasis on the user's experience, but also places great emphasis on the developer's experience.
Learn more »Easily create an interactive user interface. Automatically and accurately update and render the correct components.
The template engine with Source Map makes your view more intuitive and easier to debug.
Based on the design of component, the complex structure is simplified and the code reuse rate is improved.
The same HTML template and DOM event mechanism as the native, State management is more simple.
No need to compile and wait during development, Bring the acme development experience.
10kb min+gzip size. Super fast virtual DOM.


The best way to find a professional
-
We make sleek and modern designs for your business.
-
Our creations embrace
the simplicity to look extraordinary.
-
Platforms are built from a solid engine & best experiments.
-
Is not easy to be a Sparking professional
The best way to find a professional
-
We make sleek and modern designs for your business.
-
Our creations embrace
the simplicity to look extraordinary.
-
Platforms are built from a solid engine & best experiments.
-
Is not easy to be a Sparking professional


Dinah Jane Opens Up About Making Her Music Authentic
Dinah Jane goes old school glam for the beauty cover of In Love magazine’s new issue.
The 22-year-old singer opened up about her beauty secrets and rituals, and also opened up about how her solo music differs from Fifth Harmony‘s.
“My creative process is pretty smooth. I’ll come straight into the room as an open book, ready to bring a topic to life,” Dinah shares. “The difference is that the music and project revolve around only one girl now, so whatever I’m envisioning will be 100 percent about me; nobody else.”
She continues, “I’m taking you on a journey of being in my shoes – what’s it’s like to be with me and, or, be like me.”
Dinah also opened up about the shift in her music to be as authentic as possible.
“It’s important to surround yourself with people who know you better than anyone else – or better yet, know you better than you know yourself. I told myself, ‘The only music you’re going to be making from here on out is music that speaks to you and is honest.’”
Dinah adds, “‘These aren’t anyone else’s records but yours, so don’t waste time creating something that has no connection to you or something your heart isn’t in, because at that point you are doing a disservice to yourself as an artist.’”
You can read more of Dinah‘s interview at InLoveMag.com.


Who’s No. 1 in College Football Playoff has never mattered more
by Zach BrazillerThe race is on. It’s too early to tell who will earn this coveted spot. It is the major storyline of the remaining few weeks in the regular season.
This isn’t about the fourth slot in the College Football Playoff, which is still wide open. It is for No. 1, to be decided between LSU and Ohio State.
Who finishes atop the committee’s rankings has never mattered more. The winner receives a soft landing in the semifinals. The loser will almost certainly draw defending national champion Clemson.
The difference is massive.
At this point, there are a number of possibilities for the team that could be No. 4. Georgia is the front-runner, provided it can knock off LSU, an unlikely scenario. Then there is Alabama sans dynamic quarterback Tua Tagovailoa, Utah, Oklahoma and maybe even a second Big Ten team (more on that later). It’s like the old saying about quarterbacks, if you think you have two, you have none. There is a reason there isn’t a clear choice for the last spot. None belongs in the same conversation as the big three.
All those teams have significant deficiencies and hardly compare to the talent, championship pedigree and difficulty Clemson would present. Georgia has lost at home to four-loss South Carolina and was nearly upset by mediocre Texas A&M on Saturday. Utah has a loss to pedestrian USC and hasn’t defeated a ranked opponent. Alabama’s defense is shaky and quarterback Mac Jones is an unknown. Oklahoma nearly blew big leads to Iowa State and TCU in recent weeks, along with a setback to four-loss Kansas State.
Which is why it’s so important to see what happens with LSU and Ohio State. Both can afford a loss and still reach the playoff. Their résumés are that strong. But a defeat would also knock them out of the race for No. 1.
At the moment. LSU has the edge, courtesy of wins over Alabama (with Taglovailoa), Florida and Auburn. But Ohio State still has two big games left, Saturday at hard-charging Michigan followed by the Big Ten title game, against either Minnesota or Wisconsin, and owns wins over Penn State, Wisconsin and 10-1 Cincinnati. Two blowouts to close the year could elevate the Buckeyes.
It is so important, the difference between a likely blowout and facing an equal in Clemson. Who’s No. 1 has never mattered so much for the teams jockeying for top position in the playoff.
Can’t Mich’
Michigan is an upset away from giving the playoff committee a lot to think about. A two-loss team has never reached the final four, but the Wolverines would have a case. While upsetting Ohio State would be a stunner, and may not be likely, the Wolverines are getting better by the week, will be at home, are coming off four straight blowouts of Notre Dame, Maryland, Michigan State and Indiana and their 10th-ranked scoring defense could give Ohio State problems.
They would have wins over the second-ranked Buckeyes, No. 16 Notre Dame and No. 17 Iowa, based on the playoff committee’s poll. Their losses have both come on the road, to No. 8 Penn State and No. 12 Wisconsin. That’s a résumé nobody battling for the fourth spot can match aside from Georgia, again provided it knocks off LSU in the SEC title game.
Long road to go for ’horns
Few experts predicted Baylor would return to elite status faster than Texas, but that’s the case after the Bears overwhelmed the Longhorns, 24-10 on Saturday, clinching a spot in the Big 12 title game.
Texas is as close to the Big 12 basement as the penthouse. It has lost three of four games, two to in-state rivals TCU and the Bears. Tom Herman’s third season, with a 6-5 record, isn’t too different from Charlie Strong’s 5-7 mess in his third year that led to his ouster.
Herman better not lose Saturday to two-win Texas Tech. His high-level recruiting classes will keep him safe only so long.
Top 10
1. LSU (11-0) (Last week: 1)
LSU clinched its first SEC West title in eight years on Saturday. All that can keep the Tigers out of the playoff now is two losses in their last two games.
2. Ohio State (11-0) (2)
The Buckeyes responded to some rare game pressure like champions, after watching a 21-point lead cut to four late in the third quarter. They held Penn State to 49 yards the rest of the way, quickly erasing any upset thoughts.
3. Clemson (11-0) (3)
This will be an adjustment for Clemson. Facing a team that can actually challenge it. Ignore South Carolina’s 4-7 record; it upset Georgia and pushed Florida.
4. Georgia (10-1) (4)
Georgia keeps winning in unimpressive fashion, three of its last four victories by seven points or less. But unlike the other teams jockeying for the fourth spot in the playoff, the Bulldogs’ path is simple: Beat LSU in the SEC title game.
5. Alabama (10-1) (6)
The good news: Tua Tagovailoa replacement, Mac Jones, has completed 71.4 percent of his passes for 841 yards and seven touchdowns. The bad news: It’s hard to take much from those numbers mostly coming against Western Carolina and Arkansas.
6. Oklahoma (10-1) (7)
The Sooners aren’t just playing with fire, they’re taunting it, dancing dangerously close to the flames. Two of the last three weeks, they have nearly blown big leads, only to narrowly hang on. The playoff committee won’t be impressed.
7. Utah (10-1) (8)
Sure, the Utes don’t have a single win over a ranked opponent. Their non-conference schedule was weak. But performance matters and they are surging at the right time, with a margin of victory of 34.2 in their current seven-game winning streak.
8. Florida (9-2) (10)
Miami is 6-5 and has lost four times as a double-digit favorite. Florida State, mired in mediocrity, is looking for a new coach. It’s good to be a Gators fan these days.
9. Minnesota (10-1) (NR)
Minnesota’s goals — a Big Ten crown and the playoff — remain in play. But they can’t happen without a win over Wisconsin.
10. Michigan (9-2) (NR)
Ohio State won’t coast Saturday in Ann Arbor. Michigan, averaging 39.3 points over its last six games, will put a scare into the Buckeyes.
Dropped out: Penn State (9-2) and Oregon (9-2)
Heisman Watch (in predicted order)
QB Joe Burrow, LSU
It’s hard to believe quarterback Billy Cannon way back in 1959 is the lone LSU Heisman Trophy winner when you consider the kind of player the SEC school attracts. Burrow looks like the next one, continuing his dream season with three touchdown passes in a rout of Arkansas on Saturday.
QB Justin Fields, Ohio State
His performance against Penn State wasn’t poor — Fields threw for 188 yards and two touchdowns and ran for 68 more yards — but it wasn’t the brilliance needed to gain ground on Burrow. His two lost fumbles certainly didn’t help.
QB Jalen Hurts, Oklahoma
Turnovers are becoming a problem for Hurts, two more in Saturday’s ugly win over TCU. They won’t keep him from New York City next month, but they are lessening his already slim chances.
DE Chase Young, Ohio State
In the Buckeyes’ two biggest games, Young has been an absolute monster, combining for 15 tackles, seven sacks, four forced fumbles and nine tackles for loss in wins over Wisconsin and Penn State.
RB Jonathan Taylor
Three straight 200-yard rushing performances have the junior back in the mix. He can really make a statement by leading Wisconsin past Minnesota on Saturday for the Big Ten West crown.


DearJim is a revolutionary task manager designed to help you organise your tasks that is simple and easy to use. DearJim is a Java desktop application that has a GUI, and the main mode of input in DearJim is through keyboard commands.
This guide describes the design and implementation of DearJim. It will help you understand how DearJim works and how you can further contribute to its development. We have organised this guide in a top-down manner so that you can understand the big picture before moving on to the more detailed sections.
JDK 1.8.0_60
or later
Having any Java 8 version is not enough.
This app will not work with earlier versions of Java 8.
Buildship Gradle Integration plugin from the Eclipse Marketplace
File
> Import
Gradle
> Gradle Project
> Next
> Next
Browse
, then locate the project's directoryFinish
- If you are asked whether to 'keep' or 'overwrite' config files, choose to 'keep'.
- Depending on your connection speed and server load, it can even take up to 30 minutes for the set up to finish
(This is because Gradle downloads library files from servers during the project set up process)- If Eclipse auto-changed any settings files during the import process, you can discard those changes.
The Architecture Diagram of DearJim
The Architecture Diagram given above explains the high-level design of the App.
Given below is a quick overview of each component.
Main
has only one class called MainApp
. It is responsible for,
Commons
represents a collection of classes used by multiple other components.
Two of those classes play important roles at the architecture level.
EventsCentre
: This class (written using Google's Event Bus library)LogsCenter
: Used by many classes to write log messages to the App's log file.The rest of the App consists four components.
UI
: The UI of the App.Logic
: The command executor.Model
: Holds the data of the App in-memory.Storage
: Reads data from, and writes data to, the hard disk.Each of the four components
interface
with the same name as the Component.{Component Name}Manager
class.For example, the Logic
component (see the class diagram given below) defines its API in the Logic.java
interface and exposes its functionality using the LogicManager.java
class.
The class diagram for the Logic Component of DearJim
The Sequence Diagram below shows how the components interact for the scenario where the user issues the
command delete 1
.
The sequence diagram for the scenario
delete 1
Note how the
Model
simply raises aTaskManagerChangedEvent
when the Task Manager data are changed,
instead of asking theStorage
to save the updates to the hard disk.
The diagram below shows how the EventsCenter
reacts to that event, which eventually results in the updates
being saved to the hard disk and the status bar of the UI being updated to reflect the 'Last Updated' time.
The sequence diagram showing the
TaskManagerChangedEvent
and effects onStorage
andUI
Note how the event is propagated through the
EventsCenter
to theStorage
andUI
withoutModel
having
to be coupled to either of them. This is an example of how this Event Driven approach helps us reduce direct
coupling between components.
The sections below give more details of each component.
The class diagram for the UI component of DearJim
API : Ui.java
The UI consists of a MainWindow
that is made up of parts e.g.CommandBox
, ResultDisplay
, TaskListPanel
, TaskCard
, SwitchViewButtons
, StatusBarFooter
, etc. All these, including the MainWindow
, inherit from the abstract UiPart
class
and they can be loaded using the UiPartLoader
.
The UI
component uses JavaFx UI framework. The layouts of these UI parts are defined in matching .fxml
files
that are in the src/main/resources/view
folder.
For example, the layout of the MainWindow
is specified in
MainWindow.fxml
The UI
component,
Logic
component.Model
so that the UI can auto-update when data in the Model
change.UI
accordingly.The class diagram for the Logic component of DearJim
API : Logic.java
Logic
uses the CommandParser
class to parse the user command.Command
object which is executed by the LogicManager
.Model
(e.g. adding a task) and/or raise events.History
if command executed is an UndoableCommand
.CommandResult
object which is passed back to the UI
.Given below is the Sequence Diagram for interactions within the Logic
component for the execute("delete 1")
API call.
The sequence diagram for the interactions within the
Logic
component forexecute("delete 1")
The class diagram for the Model component of DearJim
API : Model.java
The Model
,
UnmodifiableObservableList<ReadOnlyTask>
that can be 'observed' e.g. the UI can be bound to this listThe class diagram for the Storage component of DearJim
API : Storage.java
The Storage
component,
UserPref
objects in json format and read it back.Classes used by multiple components are in the seedu.taskmanager.commons
package.
Examples of these classes include the StringUtil
class, which has the containsIgnoreCase(String, String)
method, and CollectionUtil
class, which has the isAnyNull(Object...)
method.
We are using java.util.logging
package for logging. The LogsCenter
class is used to manage the logging levels
and logging destinations.
logLevel
setting in the configuration fileLogger
for a class can be obtained using LogsCenter.getLogger(Class)
which will log messages according toConsole
and to a .log
file.Logging Levels
SEVERE
: Critical problem detected which may possibly cause the termination of the applicationWARNING
: Application can continue running, but minor errors may occurINFO
: Information showing the noteworthy actions by the AppFINE
: Details that is not usually noteworthy but may be useful in debuggingCertain properties of the application can be controlled (e.g App name, logging level) through the configuration file
(default: config.json
):
Tests can be found in the ./src/test/java
folder.
In Eclipse:
If you are not using a recent Eclipse version (i.e. Neon or later), enable assertions in JUnit tests
as described here.
src/test/java
folder and chooseRun as
> JUnit Test
Using Gradle:
We have two types of tests:
GUI Tests - These are System Tests that test the entire App by simulating user actions on the GUI.
These are in the guitests
package.
seedu.taskmanager.commons.UrlUtilTest
seedu.taskmanager.storage.StorageManagerTest
Hybrids of unit and integration tests. These tests are checking multiple code units as well as
how the are connected together.
e.g. seedu.taskmanager.logic.LogicManagerTest
Headless GUI Testing :
Thanks to the TestFX library we use,
our GUI tests can be run in the headless mode.
In the headless mode, GUI tests do not show up on the screen.
That means the developer can do other things on the Computer while the tests are running.
See UsingGradle.md to learn how to run tests in headless mode.
See UsingGradle.md to learn how to use Gradle for build automation.

See UsingTravis.md for more details.
Here are the steps to create a new release.
v0.1
A project often depends on third-party libraries. For example, DearJim depends on the
Jackson library for XML parsing. Managing these dependencies
can be automated using Gradle. For example, Gradle can download the dependencies automatically, which
is better than these alternatives.
a. Include those libraries in the repo (this bloats the repo size)
b. Require developers to download those libraries manually (this creates extra work for developers)
Priorities: High - * * *
Medium - * *
Low - *
| Priority | As a ... | I want to ... | So that I can... |
|---|---|---|---|
* * * |
new user | see instructions on how to use the app | refer to instructions when I forget how to use the App |
* * * |
user | add tasks to the todo list | be reminded of what to do |
* * * |
user | add tasks with deadline | remember by what time I have to complete a task |
* * * |
user | add tasks with timeframe | know what I have to attend an event |
* * * |
user | view upcoming tasks in chronological order | check what I need to do / have to do soon |
* * * |
user | search for details on a task or event | view what needs to be done |
* * * |
user | delete a task that has been completed | completely remove it from my task manager |
* * * |
user | mark a task as completed upon completion | keep an archive of tasks that I have completed |
* * * |
user | view tasks that I have completed | recall what I have completed |
* * * |
user | undo my actions | reverse any mistake that I have made |
* * * |
user | redo my undo | correct any accidental undo |
* * * |
user | edit tasks | keep them up to date |
* * * |
user | store my tasks in different locations | share the tasks with multiple devices |
* * |
user | sync my task with other computers | keep track of what to do anywhere |
* * |
user | enter synonyms for the commands | use natural language to accomplish what I want |
* |
user | tag tasks | classify them and search for them according to these tags |
* |
user | call up the todo list with a simple keystroke | start the application anytime during my workflow |
(For all use cases below, the System is the Task Manager
and the Actor is the user
, unless specified otherwise)
MSS
add
command, specifying details of the task to be addedadd
command, and adds the task to the current task listUse case ends
Extensions
1a. User enters a task name that needs to be escaped as it contains values that CommandParser is unable to parse correctly.
1a1. TaskManager's instant parsing feature reflects to the user that his / her input is being parsed into the wrong field
1a2. User uses the double inverted commas to escape the task name
Use case resumes at step 2
2a. User enters an input that does not follow the add
command format
2a1. TaskManager displays an error message on the GUI, informing the user of the correct format for the
add
command and an exampleadd
command
Use case resumes at step 1
2b. User is currently at done list view
2b1. TaskManger displays an error message on the GUI, informing the user that he / she is unable to perform the add command in done list view, and prompts the user to switch to undone list view instead to perform the add command
Use case resumes at step 1
3a. User identifies a mistake in the details of the task added
3a1. User edits the task details (UC03)
Use case ends
MSS
list
commandlist
commandUse case ends
Extensions
2a. User enters an input that does not follow the list
command format
2a1. TaskManager displays an error message on the GUI, informing the user of the correct format for the
list
command and an examplelist
command
Use case resumes at step 1
2b. The list is empty
Use case ends
MSS
edit
command, specifying the INDEX
of the task in the list to be edited, the fields to be edited and their new valuesedit
command and looks for the task in the listUse case ends
Extensions
2a. The list is empty
Use case ends
3a. Index is not given
3a1. TaskManager displays an error message on the GUI, informing the user of the correct format for the
edit
command and an exampleedit
command
Use case resumes at step 3
3b. User enters a task name that needs to be escaped as it contains values that CommandParser is unable to parse rightly.
3b1. TaskManager's instant parsing feature reflects to the user that his / her input is being parsed into the wrong field
3b2. User uses the double inverted commas to escape the task name
Use case resumes at step 3
4a. The given index is invalid
4a1. TaskManager displays an error message on the GUI, informing the user that the given index is invalid and thus cannot edit any task
Use case resumes at step 3
4b. User enters an end date that occurs before the start date.
4b1. TaskManager displays an error message on the GUI, informing the user that the end date must occur after the start date
Use case resumes at step 3
4c. User enters an input that does not follow the edit
command format
4c1. TaskManager displays an error message on the GUI, informing the user of the correct format for the
edit
command and an exampleedit
command
Use case resumes at step 3
MSS
delete
command, specifying the INDEX
of the task in the list to be deleteddelete
command and looks for the task in the listUse case ends
Extensions
2a. The list is empty
Use case ends
4a. The given index is invalid
4a1. TaskManager displays an error message on the GUI, informing the user that the given index is invalid and thus cannot delete any task
Use case resumes at step 3
4b. User enters an input that does not follow the delete
command format
4b1. TaskManager displays an error message on the GUI, informing the user of the correct format for the
delete
command and an exampledelete
command
Use case resumes at step 3
MSS
undo
commandundo
commandExtensions
1a. User enters an undo
command, followed by some arguments
1a1. TaskManager parses the
undo
command, ignoring the arguments that follow
Use case resumes at step 3
3a. There is no previous undoable command
3a1. TaskManager indicates that there is nothing to undo.
Use case ends.
4a. User wants to reverse the undo
command
4a1. User enters the
redo
command (UC06)
Use case ends.
MSS
undo
command successfully (UC05)redo
commandredo
commandundo
, redoing the effects of that commandExtensions
1a. User enters a non-undoable command
1a1. TaskManager handles the command
Use case resumes at step 2
1b. User enters an undoable command
1b1. TaskManager handles the command and clears the history of commands to
redo
1b2. User enters aredo
command
1b3. TaskManager parses theredo
command and indicates that there is nothing toredo
Use case ends.
2a. User enters a redo
command, followed by some arguments
1a1. TaskManager parses the
redo
command, ignoring the arguments that follow
Use case resumes at step 3
1.8.0_60
or higher installed.Windows, Linux, Unix, OS-X
Able to work well as number of tasks grows
Alternative names for a single command
Code that is readable and easy to contribute towards
| Product | Strength | Weaknesses |
|---|---|---|
| Wunderlist |
|
|
| Todo.txt |
|
|
| Google Calendar |
|
|
| Remember the milk |
|
|
Summary: We observed that these products have very good features, but we realised that none of these products have the specific combination of features that caters to our target audience. Therefore, we are incorporating some of the good features such as minimalistic interface and ability to sync with multiple computers while designing DearJim carefully to avoid the pitfalls found in these products, to make a targeted product for our intended audience.


Insert/Update a Movie!
Delete a Movie
Search Movie(s) with given actor
Print highest rated movies
Print lowest rated movies


Last updated: 2021-09-24
Checks: 7 0
Knit directory: myTidyTuesday/
This reproducible R Markdown analysis was created with workflowr (version 1.6.2). The Checks tab describes the reproducibility checks that were applied when the results were created. The Past versions tab lists the development history.
Great! Since the R Markdown file has been committed to the Git repository, you know the exact version of the code that produced these results.
Great job! The global environment was empty. Objects defined in the global environment can affect the analysis in your R Markdown file in unknown ways. For reproduciblity it’s best to always run the code in an empty environment.
The command set.seed(20210907)
was run prior to running the code in the R Markdown file. Setting a seed ensures that any results that rely on randomness, e.g. subsampling or permutations, are reproducible.
Great job! Recording the operating system, R version, and package versions is critical for reproducibility.
Nice! There were no cached chunks for this analysis, so you can be confident that you successfully produced the results during this run.
Great job! Using relative paths to the files within your workflowr project makes it easier to run your code on other machines.
Great! You are using Git for version control. Tracking code development and connecting the code version to the results is critical for reproducibility.
The results in this page were generated with repository version c7e3daf. See the Past versions tab to see a history of the changes made to the R Markdown and HTML files.
Note that you need to be careful to ensure that all relevant files for the analysis have been committed to Git prior to generating the results (you can use wflow_publish
or wflow_git_commit
). workflowr only checks the R Markdown file, but you know if there are other scripts or data files that it depends on. Below is the status of the Git repository when the results were generated:
Ignored files:
Ignored: .Rhistory
Ignored: .Rproj.user/
Ignored: catboost_info/
Ignored: data/2021-09-08/
Ignored: data/CNHI_Excel_Chart.xlsx
Ignored: data/CommunityTreemap.jpeg
Ignored: data/Community_Roles.jpeg
Ignored: data/YammerDigitalDataScienceMembership.xlsx
Ignored: data/acs_poverty.rds
Ignored: data/fmhpi.rds
Ignored: data/grainstocks.rds
Ignored: data/hike_data.rds
Ignored: data/us_states.rds
Ignored: data/us_states_hexgrid.geojson
Ignored: data/weatherstats_toronto_daily.csv
Untracked files:
Untracked: code/YammerReach.R
Untracked: code/work list batch targets.R
Note that any generated files, e.g. HTML, png, CSS, etc., are not included in this status report because it is ok for generated content to have uncommitted changes.
These are the previous versions of the repository in which changes were made to the R Markdown (analysis/AnimalCrossing.Rmd
) and HTML (docs/AnimalCrossing.html
) files. If you’ve configured a remote Git repository (see ?wflow_git_remote
), click on the hyperlinks in the table below to view the files as they were in that past version.
| File | Version | Author | Date | Message |
|---|---|---|---|---|
| Rmd | c7e3daf | opus1993 | 2021-09-24 | adopt direct labeling and viridis H palette |
suppressPackageStartupMessages({
library(tidyverse)
library(tidytext)
library(lubridate)
library(tidyr)
library(stm)
library(tidymodels)
library(textrecipes)
library(vip)
})
source(here::here("code","_common.R"),
verbose = FALSE,
local = knitr::knit_global())
ggplot2::theme_set(theme_jim(base_size = 12))
Our goal this week is to explore and predict ratings for Animal Crossing user reviews in this week’s #TidyTuesday dataset from the text in the review. This is what is typically called a sentiment analysis modeling, and it’s a common real-world problem.
user_reviews <- readr::read_tsv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-05-05/user_reviews.tsv")
user_reviews %>%
count(grade) %>%
ggplot(aes(factor(grade), n)) +
geom_col(aes(fill = factor(grade)),
show.legend = FALSE
) +
labs(
title = "Most Animal Crossing Reviews are at the Extremes",
subtitle = paste0(
"User Review Scores from ",
format(min(user_reviews$date), "%B %d, %Y"),
" to ",
format(max(user_reviews$date), "%B %d, %Y")
),
caption = "Jim Gruman | #TidyTuesday",
x = "Grade",
y = "Number of Reviews"
)
This phenomenon is common in surveys, where many people give the extreme scores of zero and 10. This does not look like a nice distribution for predicting a not-really-continuous quantity like grade, so we’ll convert these user scores to a label, good vs. bad user reviews, and build a classification model. A common theme for the negative reviews is frustration with the one-island-per-console setup, and more specifically the relative roles of player 1 vs. others on the same console.
There is definitely evidence of scraping problems when looking at the review text. Let’s remove at least the final “Expand” from the reviews, and create a new categorical rating variable.
reviews_parsed <- user_reviews %>%
mutate(text = str_remove(text, "Expand$")) %>%
mutate(rating = factor(case_when(
grade > 7 ~ "good",
TRUE ~ "bad"
)))
What is the distribution of the new, dependent, category variable rating?
There is a slight skew but we will soldier on and ignore it.
reviews_parsed %>%
ggplot(aes(rating, fill = rating)) +
geom_bar(show.legend = FALSE) +
labs(title = "With a cutoff at 8-10 as Good, how balanced is the dataset?")
What is the distribution of words per review?
The graph suggests that something is driving a bimodal distribution, with a gap at about 100 words. It should be investigated further.
reviews_parsed %>%
unnest_tokens(word, text) %>%
count(user_name, name = "total_words") %>%
ggplot(aes(total_words)) +
geom_histogram(fill = "#2AA198", bins = 30) +
scale_x_log10() +
labs(
title = "Count of Words in Animal Crossing Reviews",
subtitle = paste0(
"Reviews from ",
format(min(user_reviews$date), "%B %d, %Y"),
" to ",
format(max(user_reviews$date), "%B %d, %Y")
),
caption = "Jim Gruman | #TidyTuesday",
x = "Number of Words in Review",
y = "Number of Reviews"
) +
geom_vline(xintercept = 100, color = "firebrick") +
annotate(
"text",
x = 105,
y = 325,
hjust = 0,
color = "firebrick",
label = "Sharp cliff\nat 100 words"
)
After a cursory inspection of the text of the reviews, there are some where the author pasted the same phrase into the field verbatim several times. We will filter out the repeats above 3x in the modeling dataset.
Let’s take a look at how the reviews evolve over time:
by_week <- reviews_parsed %>%
group_by(week = floor_date(date, "week", week_start = 1)) %>%
summarize(
nb_reviews = n(),
avg_grade = mean(grade),
pct_zero = mean(grade == 0),
pct_ten = mean(grade == 10)
)
by_week %>%
ggplot(aes(week, avg_grade)) +
geom_line(color = "#2AA198") +
geom_point(aes(size = nb_reviews), color = "#2AA198") +
expand_limits(y = 0) +
scale_x_date(date_labels = "%b %d", date_breaks = "1 week") +
labs(
x = "Week", y = "Average Grade",
size = "# of Reviews",
title = "Animal Crossing User Review Grades",
subtitle = paste0("By Week"),
caption = "Jim Gruman | #TidyTuesday"
)
by_week %>%
gather(type, value, contains("pct")) %>%
mutate(type = ifelse(type == "pct_zero", "Rated 0", "Rated 10")) %>%
ggplot(aes(week, value, color = type)) +
geom_line(show.legend = FALSE) +
geom_point(aes(size = nb_reviews)) +
expand_limits(y = 0) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
scale_x_date(date_labels = "%b %d", date_breaks = "1 week") +
labs(
x = "Week", y = "Portion of Reviews",
size = "# of Reviews",
title = "Most Polarizing Animal Crossing Reviews",
subtitle = paste0("By Week"),
caption = "Jim Gruman | #TidyTuesday"
)
Let’s take a look at how the reviews evolve by day of the week:
by_dow <- reviews_parsed %>%
group_by(dow = wday(date, label = TRUE, week_start = 1)) %>%
summarize(
nb_reviews = n(),
avg_grade = mean(grade),
pct_zero = mean(grade == 0),
pct_ten = mean(grade == 10)
)
by_dow %>%
ggplot(aes(dow, avg_grade)) +
geom_point(aes(size = nb_reviews), color = "#2AA198") +
expand_limits(y = 0) +
# scale_x_date(date_labels = "%b %d", date_breaks = "1 week")+
labs(
x = "Day", y = "Average Grade",
size = "# of Reviews",
title = "Animal Crossing User Review Grades",
subtitle = paste0("By Day of Week"),
caption = "Jim Gruman | #TidyTuesday"
)
by_dow %>%
gather(type, value, contains("pct")) %>%
mutate(type = ifelse(type == "pct_zero", "Rated 0", "Rated 10")) %>%
ggplot(aes(dow, value, color = type)) +
geom_point(aes(size = nb_reviews),
shape = 21
) +
expand_limits(y = 0) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
labs(
x = "Day", y = "Portion of Reviews",
size = "# of Reviews",
title = "Most Polarizing Animal Crossing Reviews",
color = "Review Grade",
subtitle = paste0("By The Day of the Week"),
caption = "Jim Gruman | #TidyTuesday"
)
For further topic modeling, we will remove the stop words and excessive copy-pasting within each review document.
user_review_words <- reviews_parsed %>%
unnest_tokens(word, text) %>%
anti_join(stop_words, by = "word") %>%
group_by(user_name, word) %>%
mutate(id = row_number()) %>%
filter(id < 4) %>%
ungroup() %>%
count(user_name, date, grade, word)
What are the words that are positively or negatively associated with each user grade?
by_word <- user_review_words %>%
group_by(word) %>%
summarize(
avg_grade = mean(grade),
nb_reviews = n()
) %>%
filter(nb_reviews >= 25) %>%
arrange(desc(avg_grade))
by_word %>%
filter(nb_reviews >= 75) %>%
ggplot(aes(nb_reviews, avg_grade)) +
geom_point() +
geom_text(aes(label = word),
vjust = 1, hjust = 1,
check_overlap = TRUE
) +
scale_x_log10()
To make a nice chart, let’s zoom in on the 20 words associated with the lowest Review Grades:
by_word %>%
top_n(20, -avg_grade) %>%
ggplot(aes(nb_reviews, avg_grade)) +
geom_point() +
geom_text(aes(label = word),
vjust = 1, hjust = 1, check_overlap = TRUE
) +
scale_x_log10() +
labs(
x = "Number of Reviews", y = "Mean Review Grade",
title = "Words Associated with Lowest Animal Crossing Reviews",
subtitle = "20 most common words in unfavorable reviews; Appearing at least 25 times",
caption = "Jim Gruman | #TidyTuesday"
)
The stm
Structural Topic Model package offers unsupervised approaches to building clusters of topics, their relationships with documents, and their relationships with words.
We will arbitrarily choose to cluster here into 6 topics.
review_matrix <- user_review_words %>%
group_by(word) %>%
filter(n() >= 25) %>%
cast_sparse(user_name, word, n)
topic_model <- stm(review_matrix,
K = 6,
verbose = FALSE,
init.type = "Spectral"
)
We can plot the words most highly associated with each of 6 topics:
tidy(topic_model) %>%
group_by(topic) %>%
top_n(10, beta) %>%
ggplot(aes(beta, reorder_within(term, by = beta, within = topic), fill = factor(topic))) +
geom_col(show.legend = FALSE) +
tidytext::scale_y_reordered() +
facet_wrap(~topic, scales = "free_y") +
labs(
x = "beta",
y = "Word Tokens",
title = "Animal Crossing Review Topics",
caption = "@jim_gruman | #TidyTuesday"
) +
theme(
axis.text.x.bottom = element_text(size = 8),
plot.margin = unit(c(c(1, 1, 1, 0.5)), units = "cm")
)
Is there a correlation between the document gamma and the grade that the reviewer gave? We will use the Spearman Correlation, which is sensitive to the ranks of the items. And once again, we will examine how each topic is represented over time.
topic_model_gamma <- tidy(topic_model, matrix = "gamma") %>%
mutate(user_name = rownames(review_matrix)[document]) %>%
inner_join(user_reviews, by = "user_name")
topic_model_gamma %>%
group_by(topic) %>%
summarize(
spearman_correlation = cor(gamma, grade, method = "spearman"),
.groups = "drop"
) %>%
knitr::kable()
| topic | spearman_correlation |
|---|---|
| 1 | 0.4214898 |
| 2 | 0.5652946 |
| 3 | 0.2873774 |
| 4 | -0.5849657 |
| 5 | -0.6001275 |
| 6 | 0.1519181 |
topic_model_gamma %>%
group_by(
week = floor_date(date, "week", week_start = 1),
topic
) %>%
summarize(
avg_gamma = mean(gamma),
.groups = "drop"
) %>%
ggplot(aes(week, avg_gamma, color = factor(topic))) +
geom_line(size = 2, show.legend = FALSE) +
geom_text(
data = . %>% filter(week == as.Date("2020-04-27")),
aes(label = paste0("Topic ", topic)),
nudge_x = 2,
check_overlap = TRUE,
show.legend = FALSE
) +
expand_limits(y = 0) +
scale_y_continuous(labels = scales::percent_format(accuracy = 1)) +
scale_x_date(
date_labels = "%b %d",
date_breaks = "1 week",
limits = c(NA_Date_, as.Date("2020-04-30"))
) +
labs(
x = "Date", color = "Topic",
y = "Average gamma (document-topic association)",
title = "Animal Crossing Review Topic Evolution",
caption = "@jim_gruman | #TidyTuesday"
)
We start by loading the tidymodels metapackage, and splitting our data into training and testing sets.
review_split <- initial_split(reviews_parsed, strata = rating)
review_train <- training(review_split)
review_test <- testing(review_split)
Next, let’s preprocess the data to get it ready for modeling. We can use specialized steps from textrecipes, along with the general recipe steps.
review_rec <- recipe(rating ~ text + date, data = review_train) %>%
step_mutate(date = as.numeric(difftime(date, min(date), units = "days"))) %>%
step_mutate(dow = wday(date, label = TRUE, week_start = 1)) %>%
step_dummy(dow) %>%
step_tokenize(text) %>%
step_stopwords(text) %>%
step_tokenfilter(text, max_tokens = 500) %>%
step_tfidf(text) %>%
step_normalize(all_predictors())
review_prep <- prep(review_rec)
review_prep
Data Recipe
Inputs:
role #variables
outcome 1
predictor 2
Training data contained 2249 data points and no missing data.
Operations:
Variable mutation for date [trained]
Variable mutation for dow [trained]
Dummy variables from dow [trained]
Tokenization for text [trained]
Stop word removal for text [trained]
Text filtering for text [trained]
Term frequency-inverse document frequency with text [trained]
Centering and scaling for date, dow_1, dow_2, dow_3, dow_4, dow_5, ... [trained]
Let’s walk through the steps in this recipe, which are sensible defaults for a first attempt at training a text classification model such as a sentiment analysis model.
First, we must tell the recipe()
what our model is going to be (using a formula here) and what data we are using.
Next, we tokenize our text, with the default tokenization into single words.
Next, we remove stop words (again, just the default set).
It wouldn’t be practical to keep all the tokens from this whole dataset in our model, so we can filter down to only keep, in this case, the top 500 most-used tokens (after removing stop words). This is a pretty dramatic cut and keeping more tokens would be a good next step in improving this model.
We need to decide on some kind of weighting for these tokens next, either something like term frequency or, what we used here, tf-idf. `
Finally, we center and scale (i.e. normalize) all the newly created tf-idf values because the model we are going to use is sensitive to this.
Before using prep()
these steps have been defined but not actually run or implemented. The prep()
function is where everything gets evaluated.
Now it’s time to specify our model. Here we can set up the model specification for lasso regression with penalty = tune()
since we don’t yet know the best value for the regularization parameter and mixture = 1 for lasso. The lasso is often a good baseline for text modeling.
I am using a workflow()
in this example for convenience; these are objects that can help you manage modeling pipelines more easily, with pieces that fit together like Lego blocks. This workflow()
contains both the recipe and the model.
lasso_spec <- logistic_reg(
penalty = tune(),
mixture = 1
) %>%
set_engine("glmnet")
lasso_wf <- workflow() %>%
add_recipe(review_rec) %>%
add_model(lasso_spec)
lasso_wf
== Workflow ====================================================================
Preprocessor: Recipe
Model: logistic_reg()
-- Preprocessor ----------------------------------------------------------------
8 Recipe Steps
* step_mutate()
* step_mutate()
* step_dummy()
* step_tokenize()
* step_stopwords()
* step_tokenfilter()
* step_tfidf()
* step_normalize()
-- Model -----------------------------------------------------------------------
Logistic Regression Model Specification (classification)
Main Arguments:
penalty = tune()
mixture = 1
Computational engine: glmnet
Let’s get ready to tune
the lasso model! First, we need a set of possible regularization parameters to try.
lambda_grid <- grid_regular(penalty(), levels = 40)
Next, we need a set of resampled data to fit and evaluate all these models.
review_folds <- bootstraps(review_train, strata = rating)
Now we can put it all together and implement the tuning. We can set specific metrics to compute during tuning with metric_set()
. Let’s look at AUC, positive predictive value, and negative predictive value so we can understand if one class is harder to predict than another.
all_cores <- parallelly::availableCores(omit = 1)
all_cores
system
11
future::plan("multisession", workers = all_cores) # on Windows
lasso_grid <- tune::tune_grid(
lasso_wf,
resamples = review_folds,
grid = lambda_grid,
metrics = yardstick::metric_set(yardstick::roc_auc, yardstick::ppv, yardstick::npv)
)
Once we have our tuning results, we can examine them in detail. Visualization is often more helpful to understand model performance.
lasso_grid %>%
collect_metrics() %>%
ggplot(aes(penalty, mean, color = .metric)) +
geom_line(size = 1.5, show.legend = FALSE) +
facet_wrap(~.metric) +
scale_x_log10() +
labs(title = "Model Performance at various Penalty Values")
This shows us a lot. We see clearly that AUC and PPV have benefited from the regularization and we could identify the best value of penalty for each of those metrics. The same is not true for NPV. One class (the happy comments) is harder to predict than the other. It might be worth including more tokens in our model, based on this plot.
Let’s keep our model as is for now, and choose a final model based on AUC. We can use select_best()
to find the best AUC and then update our workflow lasso_wf with this value.
best_auc <- lasso_grid %>%
collect_metrics() %>%
filter(.metric == "roc_auc") %>%
top_n(1, wt = mean) %>%
select(penalty)
best_auc
# A tibble: 1 x 1
penalty
<dbl>
1 0.00889
final_lasso <- finalize_workflow(lasso_wf, best_auc)
This is our tuned, finalized workflow (but it is not fit yet). One of the things we can do when we start to fit this finalized workflow on the whole training set is to see what the most important variables are using the vip
package.
final_lasso %>%
fit(review_train) %>%
extract_fit_parsnip() %>%
vip::vi(lambda = best_auc$penalty) %>%
group_by(Sign) %>%
top_n(20, wt = abs(Importance)) %>%
ungroup() %>%
mutate(
Importance = abs(Importance),
Variable = str_remove(Variable, "tfidf_text_"),
Variable = fct_reorder(Variable, Importance)
) %>%
ggplot(aes(x = Importance, y = Variable, fill = Sign)) +
geom_col(show.legend = FALSE) +
facet_wrap(~Sign, scales = "free_y") +
labs(y = NULL) +
labs(
title = "Animal Crossing Review Word Importance",
caption = "@jim_gruman | #TidyTuesday"
)
People who are happy with Animal Crossing like to talk about how relaxing, fantastic, enjoyable, and great it is, and also talk in their reviews about the “review bombing” of the negative reviews. Notice that many of the words from the negative reviews are specifically used to talk about the multiplayer experience. These users want a fix and they declare Nintendo greedy for the one-island-per-console play.
final_lasso %>%
fit(review_train) %>%
pull_workflow_fit() %>%
vi(lambda = best_auc$penalty) %>%
group_by(Sign) %>%
ungroup() %>%
mutate(id = row_number()) %>%
filter(str_detect(Variable, "dow")) %>%
mutate(
Importance = abs(Importance),
Variable = str_remove(Variable, "dow_"),
Variable = fct_reorder(Variable, Importance),
) %>%
ggplot(aes(x = Importance, y = Variable, fill = Sign)) +
geom_col(show.legend = FALSE) +
geom_label(aes(label = id), x = 0.1, show.legend = FALSE) +
facet_wrap(~Sign, scales = "free_y") +
labs(y = NULL) +
labs(
title = "Animal Crossing Review Day of Week Importance",
caption = "@jim_gruman | #TidyTuesday"
)
The Day of Week feature does not appear in the Top 20. In this model, a Review written on a Wednesday (day 3) is 88th in importance, after 87 tokenized words. It has a positive influence. Thursday, day 4, is negative.
Finally, let’s return to our test data. The tune
package has a function last_fit()
which is nice for situations when you have tuned and finalized a model or workflow and want to fit it one last time on your training data and evaluate it on your testing data. You only have to pass this function your finalized model/workflow and your split.
review_final <- last_fit(final_lasso, review_split)
review_final %>%
collect_metrics() %>%
knitr::kable()
| .metric | .estimator | .estimate | .config |
|---|---|---|---|
| accuracy | binary | 0.8840000 | Preprocessor1_Model1 |
| roc_auc | binary | 0.9360624 | Preprocessor1_Model1 |
We did not overfit during our tuning process, and the overall accuracy is not bad. Let’s create a confusion matrix for the testing data.
review_final %>%
collect_predictions() %>%
conf_mat(rating, .pred_class)
Truth
Prediction bad good
bad 442 53
good 34 221
Though our overall accuracy isn’t great, we discover here that it is easier to detect the negative reviews than the positive ones.
sessionInfo()
R version 4.1.1 (2021-08-10)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19043)
Matrix products: default
locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] glmnet_4.1-2 Matrix_1.3-4 vctrs_0.3.8 rlang_0.4.11
[5] stopwords_2.2 vip_0.3.2 textrecipes_0.4.1 yardstick_0.0.8
[9] workflowsets_0.1.0 workflows_0.2.3 tune_0.1.6 rsample_0.1.0
[13] recipes_0.1.16 parsnip_<IP_ADDRESS>0 modeldata_0.1.1 infer_1.0.0
[17] dials_0.0.10 scales_1.1.1 broom_0.7.9 tidymodels_0.1.3
[21] stm_1.3.6 lubridate_1.7.10 tidytext_0.3.1 forcats_0.5.1
[25] stringr_1.4.0 dplyr_1.0.7 purrr_0.3.4 readr_2.0.1
[29] tidyr_1.1.3 tibble_3.1.4 ggplot2_3.3.5 tidyverse_1.3.1
[33] workflowr_1.6.2
loaded via a namespace (and not attached):
[1] readxl_1.3.1 backports_1.2.1 systemfonts_1.0.2
[4] plyr_1.8.6 splines_4.1.1 listenv_0.8.0
[7] SnowballC_0.7.0 digest_0.6.27 foreach_1.5.1
[10] htmltools_0.5.2 viridis_0.6.1 fansi_0.5.0
[13] magrittr_2.0.1 tzdb_0.1.2 globals_0.14.0
[16] modelr_0.1.8 gower_0.2.2 extrafont_0.17
[19] vroom_1.5.5 R.utils_2.10.1 extrafontdb_1.0
[22] hardhat_0.1.6 colorspace_2.0-2 rvest_1.0.1
[25] textshaping_0.3.5 haven_2.4.3 xfun_0.26
[28] crayon_1.4.1 jsonlite_1.7.2 survival_3.2-11
[31] iterators_1.0.13 glue_1.4.2 gtable_0.3.0
[34] ipred_0.9-12 R.cache_0.15.0 Rttf2pt1_1.3.9
[37] shape_1.4.6 future.apply_1.8.1 DBI_1.1.1
[40] Rcpp_1.0.7 viridisLite_0.4.0 bit_4.0.4
[43] GPfit_1.0-8 lava_1.6.10 prodlim_2019.11.13
[46] httr_1.4.2 ellipsis_0.3.2 farver_2.1.0
[49] R.methodsS3_1.8.1 pkgconfig_2.0.3 nnet_7.3-16
[52] sass_0.4.0 dbplyr_2.1.1 utf8_1.2.2
[55] here_1.0.1 reshape2_1.4.4 labeling_0.4.2
[58] tidyselect_1.1.1 DiceDesign_1.9 later_1.3.0
[61] munsell_0.5.0 cellranger_1.1.0 tools_4.1.1
[64] cachem_1.0.6 cli_3.0.1 generics_0.1.0
[67] evaluate_0.14 fastmap_1.1.0 yaml_2.2.1
[70] ragg_1.1.3 rematch2_2.1.2 bit64_4.0.5
[73] knitr_1.34 fs_1.5.0 future_1.22.1
[76] whisker_0.4 R.oo_1.24.0 xml2_1.3.2
[79] tokenizers_0.2.1 compiler_4.1.1 rstudioapi_0.13
[82] curl_4.3.2 reprex_2.0.1 lhs_1.1.3
[85] bslib_0.3.0 stringi_1.7.4 highr_0.9
[88] gdtools_0.2.3 hrbrthemes_0.8.0 lattice_0.20-44
[91] styler_1.6.1 conflicted_1.0.4 pillar_1.6.2
[94] lifecycle_1.0.1 furrr_0.2.3 jquerylib_0.1.4
[97] data.table_1.14.0 httpuv_1.6.3 R6_2.5.1
[100] promises_<IP_ADDRESS> gridExtra_2.3 janeaustenr_0.1.5
[103] parallelly_1.28.1 codetools_0.2-18 MASS_7.3-54
[106] assertthat_0.2.1 rprojroot_2.0.2 withr_2.4.2
[109] parallel_4.1.1 hms_1.1.0 grid_4.1.1
[112] rpart_4.1-15 timeDate_3043.102 class_7.3-19
[115] rmarkdown_2.11 git2r_0.28.0 pROC_1.18.0


Contents
Introduction
Create 2 is an affordable STEM resource for educators, students and developers. Use Create to grasp the fundamentals of robotics, computer science and engineering. Ready to get hacking?
Equipment
What you will need to use this extension:
- The iRobot Create 2 Programmable Robot
- The Communication Cable for The Create 2 (Comes with the Create 2 Robot)
Getting Started
Now that you have the hardware, follow these few steps and you'll be controlling a robot in no time!- Install the latest version of Adobe flash
- Install the 32 bit ESR version of Firefox. This is the only browser that works with the Scratch plugin
- Install the Scratch Extension Browser Plugin
- Connect the Communication Cable to the Create 2 robot and your computer.
- Note: It may take a minute for the drivers to install the first time you connect the cable.
- Make sure the robot is on (indicated by the Clean button LED). If it is not, press the button once to turn it on.
- Note: If the Clean button LED is red, the robot needs to be charged.
- Load the Create 2 extension on ScratchX
| When you see the indicator light in the More Blocks tab turn green you're ready to robot! | ||
The blue Dirt Detectlight should also be on to indicate the robot is ready as well. |
At this point you are ready to start programming with the Scratch Blocks below. Use these Example Projects and Sensor Diagrams to help you get started.
Scratch Blocks
Here is a short description of each of the blocks included in this extension:
|
| Runs when the selected robot sensor is triggered. The selectable sensors include wall and cliff detection. |
|
| |
Runs when the selected robot button or bumper is pressed. |
|
|
| |
Checks if the selected robot sensor is triggered. The selectable sensors include wall and cliff detection. |
|
|
| |
Checks if the selected robot button or bumper is pressed. |
|
|
| |
Sets the tempo in beats per minute that the robot will play notes sent by the Play Note Block at. |
|
|
| |
Plays the selected note for the selected beats through the robot speaker at the tempo selected in the Set Tempo block. If you click the down arrow next to the note number, it will drop a piano roll down to make note selection easier. |
|
|
| |
Sets the speed the robot will drive at. The valid range for the drive speed is between 0% (stopped) and 100% (full speed). The default speed is 100%. Note: The robot will not drive until one of the drive blocks below is sent. |
|
|
| |
Drives the robot at the most recently selected drive speed from the Set Drive Speed Block. |
|
|
| |
Drives the robot at the most recently selected drive speed from the Set Drive Speed Block for the given distance. The distance must be between -1500 and 1500 cm. Note: A negative distance will drive the robot backwards and a positive distance forward. |
|
|
| |
Turns the robot in place counter-clockwise the given number of degrees. The degrees must be between 0 and 360 (one full rotation). |
|
|
| |
Turns the robot in place clockwise the given number of degrees. The degrees must be between 0 and 360 (one full rotation). |
|
|
| |
Stops the robot from moving. This includes driving forward and turning. |
|
|
| |
Turns the selected robot LED on or off. |
|
|
| |
Displays the 4 digits on the robot display. Each digit must be a single character. |
|
|
| |
Set the brightness of the Clean button LED. The brightness must be between 0 (off) and 100% (full). |
|
|
| |
Set the color of the Clean button LED. |
|
|
| |
Start a robot docking mission. The 'leave' dock mission must be run to safely drive the robot off the dock. The 'go to' dock mission should only be run if the robot is near the charging dock. Please be aware that this may cause the robot to drive away from your computer and pull or damage the Communication Cable. |
|
|
|
Example Projects
- Tethered Driving
- Drive in a square
- Play a song
- Display Characters and Blink LEDs
- Zoom Clean Button LED
Sensors
Below are diagrams of where the sensors and LEDs included in the Create 2 Scratch Extension are located on the robot. Blue indicates buttons and LEDs. Green indicates other sensors, such as bumper presses and wall detection.
Troubleshooting
If you run into issues controlling the Create 2 robot using Scratch, here's a few items to check to make sure your setup is correct and the robot is ready:- Make sure you are using the 32 bit ESR version of Firefox. This is the only supported browser for Scratch. Note that the 64 bit ESR version does not work with the scratch plugin. See https://support.mozilla.org/en-US/kb/npapi-plugins
- Make sure the latest version of Adobe flash is installed. Older versions can be incompatible with Scratch.
- Make sure the robot is fully charged (indicated by a the Clean button LED being green).
- If it is not charged, the robot may experience communication issues which can result in the blocks not performing the desired functionality.
- Make sure the Communication Cable is fully connected.
- It's possible that the cable may come loose while driving the robot around. If this happens, then the robot will no longer be able to receive commands from Scratch
- Make sure the robot is turned on
- If the robot is turned off when you open the extension in Scratch, it will not be able to connect to the robot and the indicator light in Scratch will not turn green. To prevent this from happening, turn the robot on before opening Scratch. After the robot is on (indicated by the Clean button LED being green), you can then open the extension in Scratch
- Make sure your browser is not blocking the Scratch Browser Plugin
- If all else fails, reset the robot and browser and try again
- Sometimes the robot may get out of sync with Scratch. If none of the above steps worked, starting fresh may solve the problem. To reset the robot, hold the Spot and Dock buttons at the same time for 10 seconds or take the battery out and replace it. After the robot resets, turn it on and then open the extension in Scratch again.


--- ---
Department of Mathematics
Indian Institute of Science
Bangalore 560 012
SEMINAR
|
Speaker |
: |
Dr. Eli Lebow |
| Affiliation | : | NCBS, Bangalore. |
|
Subject Area |
: |
Mathematics
|
|
Venue |
: |
Lecture Hall - I, Dept of Mathematics
|
|
Time |
: |
4.00 pm
|
|
Date |
: |
April 4,2008 (Friday) |
|
Title |
: |
The Behavior of the Mordell-Weil Groups for an Elliptic Curve. |
| Abstract | : |
Embedded contact homology is an invariant of contact 3-manifolds. ECH is given by the homology of a chain complex generated by certain collections of embedded closed Reeb orbits in the 3-manifold Y, with a differential that counts certain embedded pseudoholomorphic curves in Y x R. The result presented in this talk gives the ECH of T^2 bundles over S^1 whose monodromy A in SL_2(Z) is a hyperbolic matrix (or $-1$), where these manifolds are equipped with certain standard contact forms. The form of the answer is nearly independent of A, essentially depending only on whether the eigenvalues are positive or negative. This work extends the
results and methods of Hutchings and Sullivan (``Rounding corners of
polygons and the embedded contact homology of {$T\sp 3$}'', Geometry and
Topology, 2006) on the case Y=T^3. |


The fourth OMNeT++ Community Summit will be held at the University of Bremen in Germany on Thursday and Friday, September 07 - 08, 2017.
OMNeT++ is a public-source, component-based, modular and open-architecture simulation environment with strong GUI support and an embeddable simulation kernel. It is designed to simulate discrete event systems, with the simulation of communication networks as one of its primary application areas.
In continuation of the history of the International Workshop on OMNeT++ and three very successful editions of its reincarnation, the OMNeT++ Community Summit, we continue on the path of holding a yearly, open meeting for all members of the OMNeT++ community with less costs and more interaction between the participants. The Community Summit provides a forum for tutorials, discussion sessions and presentations on recent developments and novel ideas in the area of simulation and modeling, with a focus on the OMNeT++ simulation environment.
The first three Summits in Hamburg, Zurich, and Brno were huge successes with lively discussions, keynotes, tutorials and panels, as well as presentations and demonstrations of ongoing and finalized research covering many aspects of OMNeT++-related research. The 2017 event continues to expand the idea of a yearly community summit by explicitly addressing the interaction through tutorials and panels with additional discussion slots while keeping the extended 2-day time frame of the last summits.
The OMNeT++ summit unites users, developers, and researchers to discuss applications, developments, and ideas on the topics of integrating simulation models, coupling different simulation tools and providing more accurate and more efficient modeling approaches and simulation models.
We invite researchers and users alike to submit one or more of the following three contribution types:
All submissions should be of interest to the OMNeT++ community. We welcome case studies that employ OMNeT++ in the evaluation of systems as well as contributions addressing general questions of OMNeT++-based simulations. For model-centric submissions we ask the author(s) to publicize source code at the time of submission on a platform of choice.
Submissions will be checked by the technical program committee and the organizers. Individual contributions will be invited as oral presentations, demos, tutorials or panels, depending on the submission type and the expected interest for the OMNeT++ community. We will provide poster presentation slots for all interested participants.
Topics of interest include, but are not limited to:
Authors are encouraged to submit their tutorial / demo / discussion proposals as well as research abstracts describing original, previously unpublished work, not currently under review by another conference or venue, addressing state-of-the-art research and topics as listed. If a submission extends work described in a previous publication of their own, we strongly encourage authors to include a citation to that publication.
Abstracts must be submitted electronically via EasyChair.
Full papers and short abstracts should be prepared with the IEEE conference proceedings template, available online. Please prepare your submission with an A4 page size and the conference mode enabled. You can indicate which type of submission you provide during the submission process (e.g., academic or industry).
Submissions that are accepted and presented at the community summit will appear in the proceedings. The proceedings will be published as a technical report on the OMNeT++ website. All presented full papers will also be submitted to arXiv for indexing. Copyrights will remain solely with the authors. This allows for a publication of revised versions at other venues.
The 4th OMNeT++ Community Summit will take place at the University of Bremen in Germany.
On-Site Location:
University of Bremen - Building "Cartesium (CART)"
Enrique-Schmidt-Straße 5, 28359 Bremen
All rooms are equipped with WLAN and satellite TV. There are business and economy rooms available. For business rooms, breakfast and some other services are included in the price. For economy rooms, breakfast can be booked separately. Please contact the hotel directly for pricing information and booking using the code "OMNeT".
Address:
Wiener Straße 4
28359 Bremen
Contact:
Telephone: +49 421 24670
E-Mail<EMAIL_ADDRESS>All rooms are equipped with WLAN and satellite TV. Breakfast can be booked separately. Please contact the hotel directly for pricing information and booking using the code "Omnet".
Address:
Universitätsallee 4
28359 Bremen
Contact:
Telephone: +49<PHONE_NUMBER>7
E-Mail<EMAIL_ADDRESS>For other hotels, please check for instance www.booking.com and search for Bremen.
In case you want to contact the organizers, feel free to write an e-mail to<EMAIL_ADDRESS>The OMNeT++ Community Summit 2017 is sponsored. No registration fees will apply.
We would like to thank the Communication Networks Working Group located at the Faculty of Physics and Electrical Engineering of the University of Bremen for their support in hosting the summit.


Deal number should start with 2 digits, followed by [P, S, R, M or T] and '-' then followed by 4 digits eg: 99S-1111
{{deal.filename}}


Ahlfeld Media Inc. has extensive experience in delivering clients successful ROI-based campaigns. With strong vendor relationships across all media, we are also able to negotiate media costs competitive with large agencies.
By ensuring the important metrics are in place prior to execution we are able to properly measure the success of the campaign. Regular reporting throughout the campaign allows us to optimize and adjust on the fly.
Understanding what your consumers are saying about your brand is integral in getting the proper message forward to them.


--- layout: muck title: Postfurry MUCK categories: muck, muck-main ---
Postfurry MUCK is a text-based server for roleplay, socializing, and kink. Previously known as 12Fold MUCK, the server has been running since 2005 and offers plenty of different spaces to explore and interact. The sights you can see include:
We welcome any new players who are interested in respectfully contributing to the vibe, whether you're new to this sort of RP or not. We're always happy to see new faces, and get folks up to speed with how MUCKs work, including extensive help documents on this site.


Join our Club!
The Team
Attendance
Calendar
Presentations
Hackathons
Home
VikingHacks
@ Lynbrook High School


|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
public interface Predicated
Interface for objects which can have one or more predicates.
| Method Summary | |
|---|---|
void |
addPredicate(Predicate predicate)
Add an additional predicate to this object. |
List |
getPredicates()
Returns a possibly empty list of predicates. |
PredicateSet |
getPredicateSet()
Returns a possibly empty set of predicates. |
| Method Detail |
|---|
void addPredicate(Predicate predicate)
predicate
- the predicate to addList getPredicates()
PredicateSet getPredicateSet()
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


This process will remove the ability to undo the redaction. Please be sure to save a copy of your document before finalizing.
Are you sure you want to continue?


This week I decided to take a look at another matrix decomposition method i.e. Cholesky Factorization, which is useful when working with symmetric positive definite matrices. It helps in splitting AN x N into LN x N, UN x N such that 👇
My interest is in implementing it targeting accelerators i.e. OpenCL enabled CPUs and GPGPUs. I'd like to start with how this factorization works and then move to its SIMT implementation technique. While explaining, I'll factorize 👇 symmetric positive definite matrix by hand.
After this factorization I'd like to produce one upper triangular matrix, so I've to iterate over all pivots of matrix A
in-order and process elements along row of current selected pivot. After N iterations, I must get desired result. I start with pivot
A0, 0, then after this iteration I should get row A0, _ in desired form --- that's how it should be
in final UN x N.
First step is updating pivot while performing some arithmetics with elements living in same column above pivot A0, 0.
As there's no element above selected pivot, I just move to second step. I can programmatically represent first step as 👇.
In second step, I've to update pivot with square root of it. This produces 👇 updated matrix, which is to be operated on during step three, due to computational dependency.
In final step of first iteration, I'd like to update remaining elements in first row, as pivot is already in shape. I programmatically show what needs to be done.
After step three, I obtain matrix with updated non-pivot columns of first row, which looks like 👇.
It's time to move to next pivot i.e. sitting at A1, 1. Applying step one of algorithm, I get following matrix with pivot cell updated to 👇. Blue marked cell, just above selected pivot, is what accessed during pivot updation.
Step two is easy, producing following matrix, while only updating selected pivot.
During last step, I update only single cell i.e. non-pivot column in second row with column index > k. Following snippet depicts what I do.
It produces updated matrix as below, with upper triangular portion of first two rows as supposed to be in factorized matrix.
In final iteration where I work on pivot A2, 2 just first two steps are what required. As no non-pivot column with column index > (k = 2) exists, I'm skipping last step. During first step, two cells above selected pivot, in same column, are accessed for computing updated pivot. Finally step two follows.
This way I get upper triangular matrix from factorization, transposing same gives me lower triangular one. Multiplication of them ensures Cholesky Factorization worked as expected !
Before I start with SIMT implementation of Cholesky Factorization, I'd like to mention about an algorithm for producing symmetric positive definite matrix, which is required here. Let me start with a random matrix.
Reviewing whole flow of factorization makes it easy to figure out how to parallelize portions of algorithm without introducing any data race. I put following data dependency diagram for making it more clear.
For a matrix of dimension N x N, I've to go through N steps of execution in-order, where during each iteration I schedule three kernels for computing above main diagonal cells along selected row ( i.e. pivot row ) of final upper triangular matrix. I implement parallel cholesky factorization in SYCL DPC++ & run it on multiple hardwares with a random matrix of dimension 1024 x 1024 and work group size of 32.
I see performance is not impressive and I've some ideas how it can be improved. In current implementation,
scope of parallelism is not well respected. In each iteration when a pivot is selected and cells on same row are computed, only
a subset of elements are accessed, not requiring me to make whole matrix available to compute unit. Currently usage of conditional
statements in kernel body produces divergent control flow, reducing achievable parallelism. In coming days, I'd like
to improve Cholesky Factorization implementation while keeping aforementioned points in mind.
I keep current implementation here for future reference.
Have a great time !


Photos: Hrithik Roshan goes on evening bicycle ride on the streets of Mumbai
by TIMESOFINDIA.COMHrithik Roshan is currently enjoying the success of his two back to back hits at the box office. Along with being a fantastic actor, Hrithik has also been a dance and fitness icon for a lot of people out there.
He often shares pictures and videos from his workout session on his social media accounts. And today, the actor was snapped by the paparazzi while enjoying a cycle ride in the city. For his night cycling session, the actor was in a black hoodie teamed with black and blue joggers and shoes. He was also sporting spectacles during the ride.
Check out the pictures here:
Meanwhile, on the work front, it is being reported that Hrithik will next star in Farah Khan's 'Satte Pe Satta' reportedly co-starring Anushka Sharma. Also, reports of him doing the role of yesteryear don Haji Mastan in Sanjay Leela Bhansali's 'Gangubai Kathiawadi'. However, there is no official announcement on the same.


Starting from an Excel workbook, risk data is imported and run through a simulation model to estimate the expected losses for each scenario. The results of these simulations are used to create a detailed analysis and a formal risk report. A starter analysis report, overview dashboard, and a sample Shiny application are all included in the toolkit.
Evaluator takes a domain-driven and framework-independent approach to strategic risk analysis. For information security analysis – where Evaluator originated – ISO, COBIT, HITRUST CSF, PCI-DSS or any similar model may be used. If you are able to describe the domains of your program and the controls and threat scenarios applicable to each domain, you will be able to use Evaluator!
While not required, a basic understanding of the OpenFAIR methodology and terminology is highly recommended.
Follow these steps to complete an analysis:
Evaluator needs to know the domains of your risk universe. These are the major buckets into which you divide your program. Examples of domains include Physical Security, Strategy, Policy, Business Continuity/Disaster Recovery, and Technical Security. Out of the box, Evaluator comes with a demonstration model based upon the HITRUST CSF.
To start a fresh analysis using the default starter files, run create_templates("~/evaulator")
. This creates an evaluator
directory in your home location with an inputs
subdirectory containing a survey tool (Excel), a comma-separated file defining the domains used in the survey tool, and a file defining the risk tolerance levels for your organization.
If you have a different domain structure (e.g. ISO2700x, NIST CSF, or COBIT), you will need to edit the inputs/domains.csv
file to include the domain names and the domain IDs, and a shorthand abbreviation for the domain (such as POL for the Policy domain).
Identifying the controls (or capabilities) and risk scenarios associated with each of your domains is critical to the final analysis. The elements are documented in the Excel workbook. The workbook includes one tab per domain, with each tab named after the domain IDs defined in the previous step. Each tab consists of a controls table and a threats table.
The key objectives of each domain are defined in the domain controls table. While the specific controls will be unique to each organization, the sample spreadsheet included in Evaluator may be used as a model. It is best to avoid copying every technical control from, for example, ISO 27001 or COBIT, since most control frameworks are too fine-grained to provide the high level overview that Evaluator delivers. In practice, 50 controls or less will usually be sufficient to describe most organizations. Each control must have a unique numeric ID and should be assigned a difficulty (DIFF) score that ranks the maturity (effectiveness) of the control on a CMM scale from Initial (lowest score) to Optimized (best of class).
The threats table consists of the potential loss scenarios described by each domain. Each scenario is made up of a descriptive field that describes who did what to whom, the threat community that executed the attack (e.g. external hacktivist, internal workforce member, third party vendor), how often the threat actor acts upon your assets (TEF), the strength with which they act against your assets (TCap), the losses incurred (LM) and a comma-separated list of the control IDs that prevent the scenario.
As an alternative to manually performing the subsequent steps steps in this document, a run_analysis.R
script placed in the ~/evaluator
directory by the create_templates()
function can be used to run all of these steps automatically. To use this bootstrap script, simply set a base_dir
variable to the ~/evaluator
directory and source
the script. The run_analysis
script will generate a lot of console output. Performing at least a read through of the rest of this document to familiarize yourself with the steps being executed is strongly recommended.
Using the quick start (run_analysis
) script:
To extract the spreadsheet into data files for further analysis, run import_spreadsheet()
. Evaluator will extract the data and save two comma separated files in the inputs
directory with the results.
domains <- readr::read_csv("~/evaluator/inputs/domains.csv")
import_spreadsheet("~/evaluator/inputs/survey.xlsx", domains, output_dir = "~/evaluator/inputs")
Afer importing, you are strongly encouraged to run validate_scenarios()
to verify there are no data integrity issues. If there are errors detected, the validation process will abort and a message summarizing the problem is displayed. Correct the errors displayed, reimport, and repeat the validation process until there are no errors reported.
qualitative_scenarios <- readr::read_csv("~/evaluator/inputs/qualitative_scenarios.csv")
mappings <- readr::read_csv("~/evaluator/inputs/qualitative_mappings.csv")
capabilities <- readr::read_csv("~/evaluator/inputs/capabilities.csv")
validate_scenarios(qualitative_scenarios, capabilities, domains, mappings)
Once the quantitative scenarios are ready for simulation, run run_simulations(quantitative_scenarios)
. By default, Evaluator puts each scenario through 10,000 individual simulated years, modeling how often the threat actors come into contact with your assets, the strength of the threat actors, the strength of your controls, and the losses involved in any situation where the threat strength exceeds your control strength. This simulation process is computationally intense and can take some time to run.
The raw simulation results typically require summarization for the default reporting functions. These summarized data files, performed at both the per scenario and per domain level are in addition to the previously generated full results. An analyst can always access the full simulation results if desired.
In the following code block, Evaluator produces scenario_summary.rds
and domain_summary.rds
files for the reporting in the final section.
Several analysis functions are provided, including a template for a technical risk report. The risk report can be generated via generate_report()
. This creates a pre-populated risk report that identifies key scenarios and generates initial plots for the analyst to prepare a final report.
Other included report tools include risk_dashboard()
, which produces a single-page static web dashboard view of all the scenarios and their results.
For interactive exploration, use explore_scenarios()
to launch a local copy of the Scenario Explorer application. The Scenario Explorer app may be used to view information about the individual scenarios and provides a sample overview of the entire program.
For more in depth analysis, the following data files may be useful to exploration and analysis from either within R or with a R-compatible external business intelligence program such as Tableau:
| Data File | Purpose |
|---|---|
| simulation_results.rds | Full details of each simulated scenario |
| scenario_summary.rds | Simulation results, summarized at the scenario level |
| domain_summary.rds | Simulation results, summarized at the domain level |
# Explorer
explore_scenarios(input_directory = "~/evaluator/inputs",
results_directory = "~/evaluator/results")
# Risk Dashboard
risk_dashboard(input_directory = "~/evaluator/inputs",
output_directory = "~/evaluator/results",
"~/evaluator/risk_dashboard.html")
# Sample Report
generate_report(input_directory = "~/evaluator/inputs",
results_directory = "~/evaluator/results",
"~/evaluator/risk_report.html") %>% rstudioapi::viewer()
To view that same report as a Word document for editing, use generate_report(input_directory = "~/evaluator/inputs", results_directory = "~/evaluator/results", "~/evaluator/risk_report.docx", format = "word")
.


EngCards
beta
{{ item.word }}
{{ item.note }}
No results found for search term '{{ search }}'
No words save,
tap here add one.
Delete all
add new word


{{creatorTitle}}
{{timeSinceCreated}}
{{creatorUsername}}
{{creatorValue}}
Reply
Views : {{countViews}}
ALREADY VOTED!
{{votesCount}}
Replies
{{reps.replyCreatorDate | dateFilter}}
{{reps.replyCreatorUsername}}
{{reps.replyCreatorValue}}


Create a random forest to selects the taxonomic groups/OTUs that can differentiate between the chosen categorical variable values. The weights of the taxonomic groups/OTUs the algorithm considers most important according to the Boruta feature selection algorithm or the Random Forest regressor will be displayed.
{% include 'notifications.html' %}
{% include 'download_container.html' %}


---
layout: post
title: ! 'JavaScript: Trapping the enter key event'
tags: []
status: publish
type: post
published: true
comments: true
meta: {}
---
Here is a refined script for trapping the user pressing the enter key. In certain cases under Netscape, where you have two text input fields, hitting the enter key will result in nothing happening. To this end I searched the web and found the following script:
[js]
[/js]
This script first looks up the version of the browser you are using and if the user uses NS whichCode is equal to the event e.which. Since IE handles it differently you need to the else if statement and we set which Code for IE equal to the event e.keyCode. In both cases this will return a value. Now hitting the enter key returns the value 13. So in the next step we check for that value and if this is the case then we submit the form.
This function is called by including the event handler onKeyPress next to your input fields. Hence you could call the code() function first to check whether return was hit or not, then maybe run a validation script and if successful submit the form. I would also like to point out that you will need to provide a action property to your form for Netscape to submit the form successfully. Not doing so will result in the page just sitting there. Short and sweet, but useful.


Resize window to change Clowns
This calls clown.svg as a background image, and fails to change the clown


mongo_database module¶
-
mongo_database.
add_new_user
(email)¶ This function initializes a user in the image database before any images are uploaded.
Parameters: email – Email argument input into the GUI
-
mongo_database.
check_if_user_registered
(email)¶
-
mongo_database.
download_normal_img
(email, photo_name)¶ This function returns img_data for a normal image
Parameters: - email (string) – user email for ID
- photo_name (string) – which photo to load processed options for
Returns: string of encoded photo data
Return type: photoString (str)
-
mongo_database.
download_processed_img
(email, photo_name, processType)¶ This function returns image data for a processed image given normal image name
Parameters: - email (string) – user email for ID
- photo_name (string) – which photo to load processed data for
- processType (string) – which process type to load
Returns: string of encoded photo data
Return type: photoString (str)
-
mongo_database.
get_latency
(email, photo_name, processType)¶ This function returns latency for a processed image
Parameters: - email (string) – user email for ID
- photo_name (string) – which photo to load latency for
- processType (string) – which process type to load
Returns: latency value
Return type: latency (float)
-
mongo_database.
get_one_user
(email)¶ This function will pull all the data for a given user and put it into a dictionary which can then be used in other modules.
Parameters: email – Email input from the GUI. Returns: returns the populated user_dictionary Return type: dict
-
mongo_database.
get_time
(email, photo_name)¶ This function returns timestamp of upload for a normal image
Parameters: - email (string) – user email for ID
- photo_name (string) – which photo to load processed options for
Returns: datetime object of upload time
Return type: timestamp (datetime.datetime)
-
mongo_database.
get_time_pro
(email, photo_name, processType)¶ This function returns timestamp for a processed image
Parameters: - email (string) – user email for ID
- photo_name (string) – which photo to load timestamp for
- processType (string) – which process type to load
Returns: timestamp of img
Return type: timestamp (datetime.datetime)
-
mongo_database.
global_init
()¶
-
mongo_database.
new_image_added
(email, upload_package)¶ This function will take in a dictionary which contains the image name, the image data, and, the processing action. It will then.
Parameters: image_dict – A dictionary from the post request that contains the image name, the image data, and the processing action to be performed.
Returns: status message Return type: string
-
mongo_database.
new_image_added_pro
(email, upload_package)¶ - This function will take in a dictionary which contains the
- processed image name, the processed image data, and, the processing action. It will then save the processed image data to the correct field in the MongoDB.
Parameters: - email – Email corresponding to the user.
- upload_package – A dictionary from the post request
- contains the processed image name, the processed image data, and (that) –
- processing action to be performed. (the) –
Returns: A status message
Return type: sttring
-
mongo_database.
normal_images
(email)¶ This function simply returns a list of normal images (unique) for a user
Parameters: email (string) – user email for ID Returns: all uploaded non-processed images for user Return type: imgList (list)
-
mongo_database.
print_users
()¶
-
mongo_database.
processed_images
(email, photo_name)¶ This function simply returns a list of processed images (unique) for a user
Parameters: - email (string) – user email for ID
- photo_name (string) – which photo to load processed options for
Returns: all uploaded processed images for user
Return type: imgList (list)
-
class
mongo_database.
users
(*args, **kwargs)¶ Bases:
pymodm.base.models.MongoModel
This is a class which initializes the data fields which will then be used to store all data in the MongoDB database. For original_images, he_images…, the inputs will be a tuple containing the image name as a string and the image data also as a longer base64 string.
-
exception
DoesNotExist
¶ Bases:
pymodm.errors.DoesNotExist
-
exception
MultipleObjectsReturned
¶ Bases:
pymodm.errors.MultipleObjectsReturned
-
cs_count
¶ A field that stores a Python int.
-
email
¶ A field that stores unicode strings.
-
he_count
¶ A field that stores a Python int.
-
lc_count
¶ A field that stores a Python int.
-
objects
¶ The default manager used for
MongoModel
instances.This implementation of
BaseManager
usesQuerySet
as its QuerySet class.This Manager class (accessed via the
objects
attribute on aMongoModel
) is used by default for all MongoModel classes, unless another Manager instance is supplied as an attribute within the MongoModel definition.Managers have two primary functions:
- Construct
QuerySet
instances for use when querying or working withMongoModel
instances in bulk. - Define collection-level functionality that can be reused across different MongoModel types.
If you created a custom QuerySet that makes certain queries easier, for example, you will need to create a custom Manager type that returns this queryset using the
from_queryset()
method:class UserQuerySet(QuerySet): def active(self): '''Return only active users.''' return self.raw({"active": True}) class User(MongoModel): active = fields.BooleanField() # Add our custom Manager. users = Manager.from_queryset(UserQuerySet)
In the above example, we added a users attribute on User so that we can use the active method on our new QuerySet type:
active_users = User.users.active()
If we wanted every method on the QuerySet to examine active users only, we can do that by customizing the Manager itself:
class UserManager(Manager): def get_queryset(self): # Override get_queryset, so that every QuerySet created will # have this filter applied. return super(UserManager, self).get_queryset().raw( {"active": True}) class User(MongoModel): active = fields.BooleanField() users = UserManager() active_users = User.users.all()
- Construct
-
original_images
¶ A field that stores a list.
-
processed_images
¶ A field that stores a list.
-
rv_count
¶ A field that stores a Python int.
-
exception