---
title: TraCI/Interfacing TraCI from Python
permalink: /TraCI/Interfacing_TraCI_from_Python/
---

The [TraCI](../TraCI.md#traci_commands) commands are split into the
13 domains gui, lane, poi, simulation, trafficlight, vehicletype, edge,
inductionloop, junction, multientryexit, polygon, route, person and
vehicle, which correspond to individual modules. For a detailed list of
available functions see the [pydoc generated documentation](https://sumo.dlr.de/pydoc/traci.html). The source code
can be found at
[\[1\]](https://github.com/eclipse/sumo/tree/master/tools/traci)

## importing **traci** in a script

To use the library, the {{SUMO}}/tools directory must be on the python load
path. This is typically done with a stanza like this:

```
 import os, sys
 if 'SUMO_HOME' in os.environ:
     tools = os.path.join(os.environ['SUMO_HOME'], 'tools')
     sys.path.append(tools)
 else:
     sys.exit("please declare environment variable 'SUMO_HOME'")
```

This assumes that the [environment variable
**SUMO_HOME**](../Basics/Basic_Computer_Skills.md#additional_environment_variables)
is set before running the script. Alternatively, you can declare the
path to *sumo/tools* directly as in the line

```
sys.path.append(os.path.join('c:', os.sep, 'whatever', 'path', 'to', 'sumo', 'tools'))
```

## First Steps

In general it is very easy to interface with SUMO from Python (the
following example is a modification of
[tutorial/traci_tls](../Tutorials/TraCI4Traffic_Lights.md)):

First you compose the command line to start either
[sumo](../sumo.md) or [sumo-gui](../sumo-gui.md) (leaving out
the option  which was needed before 0.28.0):

```
sumoBinary = "/path/to/sumo-gui"
sumoCmd = [sumoBinary, "-c", "yourConfiguration.sumocfg"]
```

Then you start the simulation and connect to it with your script:

```
import traci
traci.start(sumoCmd)
step = 0
while step < 1000:
   traci.simulationStep()
   if traci.inductionloop.getLastStepVehicleNumber("0") > 0:
       traci.trafficlight.setRedYellowGreenState("0", "GrGr")
   step += 1

traci.close()
```

After connecting to the simulation, you can emit various commands and
execute simulation steps until you want to finish by closing the
connection. by default the close command will wait until the sumo
process really finishes. You can disable this by calling

```
traci.close(False)
```

## Subscriptions

Subscriptions can be thought of as a batch mode for retrieving
variables. Instead of asking for the same variables over and over again,
you can retrieve the values of interest automatically after each time
step. TraCI subscriptions are handled on a per module basis. That is you
can ask the module for the result of all current subscriptions after
each time step. In order to subscribe for variables you need to know
their variable ids which can be looked up in the traci/constants.py
file.

```
import traci
import traci.constants as tc

traci.start(["sumo", "-c", "my.sumocfg"])
traci.vehicle.subscribe(vehID, (tc.VAR_ROAD_ID, tc.VAR_LANEPOSITION))
print(traci.vehicle.getSubscriptionResults(vehID))
for step in range(3):
   print("step", step)
   traci.simulationStep()
   print(traci.vehicle.getSubscriptionResults(vehID))
traci.close()
```

The values retrieved are always the ones from the last time step, it is
not possible to retrieve older values.

## Context Subscriptions

Context subscriptions work like subscriptions in that they retrieve a
list of variables automatically for every simulation stop. However, the
do so by setting a reference object and a range and then retrieving
variables for all objects of a given type within range of the reference
object.

TraCI context subscriptions are handled on a per module basis. That is
you can ask the module for the result of all current subscriptions after
each time step. In order to subscribe for variables you need to the
domain id of the objects that shall be retrieved and the variable ids
which can be looked up in the traci/constants.py file. The domain id
always has the form CMD_GET_<DOMAIN\>_VARIABLE. The following code
retrieves all vehicle speeds and waiting times within range (42m) of a
junction (the vehicle ids are retrieved implicitly).

```
import traci
import traci.constants as tc

traci.start(["sumo", "-c", "my.sumocfg"])
traci.junction.subscribeContext(junctionID, tc.CMD_GET_VEHICLE_VARIABLE, 42, [tc.VAR_SPEED, tc.VAR_WAITING_TIME])
print(traci.junction.getContextSubscriptionResults(junctionID))
for step in range(3):
   print("step", step)
   traci.simulationStep()
   print(traci.junction.getContextSubscriptionResults(junctionID))
traci.close()
```

The values retrieved are always the ones from the last time step, it is
not possible to retrieve older values.

## Context Subscription Filters

For vehicle-to-vehicle context subscriptions (i.e., context
subscriptions, whose reference object is a vehicle and whose requested
context objects are vehicles as well) it is possible to request
additional filters to be applied already on the server side. The general
procedure is to equip a requested context subscription with the filter
directly after the call to `subscribeContext()` by a successive call to
`addSubscriptionFilter<FILTER_ID>()` as for instance in the following
snippet:

```
traci.vehicle.subscribeContext("ego", tc.CMD_GET_VEHICLE_VARIABLE, 0.0, [tc.VAR_SPEED])
traci.vehicle.addSubscriptionFilterLanes(lanes, noOpposite=True, downstreamDist=100, upstreamDist=50)
```

The first line requests a context subscription for the speed of vehicles
in the neighborhood of the reference vehicle with the ID `"ego"`. The
range of the context subscription (which refers to the radial context
region of the usual subscription mechanism) can be set equal to `0.0`,
since it is be overridden by the selective values of `downstreamDist`
and `upstreamDist`, respectively, given to the call of
`addSubscriptionFilterLanes()` in the second line. The call to
`addSubscriptionFilter<FILTER_NAME>()` automatically takes effect on
the last issued context subscription, which has to be of the
vehicle-to-vehicle form for a successful application.

The following filter types are available:

- Lanes: Return surrounding vehicles on lanes specified relatively to
  the reference vehicle
- CFManeuver: Return leader and follower on the reference vehicle's
  lane
- LCManeuver: Return leader and follower on the reference vehicle's
  lane and neighboring lane(s)
- Turn: Return conflicting vehicles on upcoming junctions along the
  vehicle's route
- VType: Only return vehicles of the specified vTypes
- VClass: Only return vehicles of the specified vClasses

See the [pydoc
documentation](http://sumo.dlr.de/daily/pydoc/traci._vehicle.html#VehicleDomain-addSubscriptionFilterCFManeuver)
for detailed specifications.

## Adding a StepListener

Often a function needs to be called each time when
traci.simulationStep() is called, to let this happen automatically
(always *after* each call to simulationStep()) it is possible to add a
StepListener object 'listener' (more precisely an instance of a subclass
of traci.StepListener) i.e.

```
 class ExampleListener(traci.StepListener):
    def step(self, t):
        # do something after every call to simulationStep
        print("ExampleListener called with parameter %s." % t)
        # indicate that the step listener should stay active in the next step
        return True

 listener = ExampleListener()
 traci.addStepListener(listener)
```
Please note that the listener is not activated for every simulation step
but for every call to simulationStep (which may perform multiple steps up to the given time *t*).
Furthermore the parameter *t* is not the current simulation time but exactly
the (optional) parameter passed to the simulationStep call (which is 0 by default).

!!! caution
    A TraCI StepListener cannot be used in the case that one TraCI client controls several SUMO-instances.

## Controlling parallel simulations from the same TraCI script

The TraCI python library can be used to control multiple simulations at
the same time with a single script. The function *traci.start()* has an
optional label argument which allows you to call it multiple times with
different simulation instances and labels. The function *traci.switch()*
can then be used to switch to any of the initialized labels:

```
 traci.start(["sumo", "-c", "sim1.sumocfg"], label="sim1")
 traci.start(["sumo", "-c", "sim2.sumocfg"], label="sim2")
 traci.switch("sim1")
 traci.simulationStep() # run 1 step for sim1
 traci.switch("sim2")
 traci.simulationStep() # run 1 step for sim2
```

If you prefer a more object oriented approach you can also use
connection objects to communicate with the simulation. They have the
same interface as the static *traci.* calls but you will still need to
start the simulation manually for them:

```
 traci.start(["sumo", "-c", "sim1.sumocfg"], label="sim1")
 traci.start(["sumo", "-c", "sim2.sumocfg"], label="sim2")
 conn1 = traci.getConnection("sim1")
 conn2 = traci.getConnection("sim2")
 conn1.simulationStep() # run 1 step for sim1
 conn2.simulationStep() # run 1 step for sim2
```

## Controlling the same simulation from multiple clients

To connect with multiple clients, the number of clients must be known in
advance and specified with sumo option **--num-clients** {{DT_INT}}. Also, the connection port must
be known to all clients. After deciding on a port it can be made
available to the clients via arguments or configuration files. A free
port can be obtained by

```
from sumolib.miscutils import getFreeSocketPort
port = sumolib.miscutils.getFreeSocketPort()
```

One client may use method *traci.start()* to start the simulation and
connect to it at the same time while the other client only needs to
connect. After establishing client order, each client must continuously
call *simulationStep* to allow the simulation to advance:

```
#client1
# PORT = int(sys.argv[1]) # example
traci.start(["sumo", "-c", "sim.sumocfg", "--num-clients", "2"], port=PORT)
traci.setOrder(1) # number can be anything
while traci.simulation.getMinExpectedNumber() > 0:
   traci.simulationStep()
   # more traci commands
traci.close(
```

```
# client2
# PORT = int(sys.argv[1]) # example
traci.init(PORT)
traci.setOrder(2) # number can be anything as long as each client gets its own number
while traci.simulation.getMinExpectedNumber() > 0:
   traci.simulationStep()
   # more traci commands
traci.close()
```

## Embedded Python

This feature has been removed Please use [libsumo](../Libsumo.md) instead.

## Additional Functions

When using TraCI there are some common tasks which are not covered by
the traci library such as

- Analyzing the road network
- Parsing simulation outputs

For this functionality it is recommended to use
[Tools/Sumolib](../Tools/Sumolib.md)

## Pitfalls and Solutions

- Note that strings, if exchanged, have to be ASCII-encoded.
- If you start sumo from within your python script using
  subprocess.Popen, be sure to call wait() on the resulting process
  object before quitting your script. You might loose output
  otherwise.

### Determine the traci library being loaded
When working with different sumo versions it may happen that the call `import traci` loads the wrong library.
The easiest way to debug this is to add the following lines after the import
```
import traci
print("LOADPATH:", '\n'.join(sys.path))
print("TRACIPATH:", traci.__file__)
sys.exit()
```
Make sure that the TRACIPATH corresponds to the sumo version that you wish to use.
If it does not, then the order of directories in LOADPATH (sys.path) must be changed or the SUMO installation must be removed from any directories that come before the wanted directory.

### Debugging a TraCI session on Linux

Sometimes SUMO may crash while running a simulation with TraCI. The
below steps make it simple to run sumo with traci in a debugger:

1\) Add the option *--save-configuration* to your traci script:

```
traci.start([sumoBinary, '-c', 'run.sumocfg', '--save-configuration', 'debug.sumocfg'])
```

2\) Run your traci script. Instead of starting sumo it will just write
the configuration with the chosen port but it will still try to connect
repeatedly.

3\) Run

```
gdb --args sumoD -c debug.sumocfg
```

(where sumoD is sumo [compiled in debug
mode](../Installing/Linux_Build.md#building_the_sumo_binaries_with_cmake_recommended))

## Usage Examples

### Run a simulation until all vehicles have arrived

```
  while traci.simulation.getMinExpectedNumber() > 0:
      traci.simulationStep()
```

### Add trips (incomplete routes) dynamically

Define a route that consists of the start and destination edge:

```
   traci.route.add("trip", ["startEdge", "endEdge"])
```

Then add the vehicle with that route

```
   traci.vehicle.add("newVeh", "trip", typeID="reroutingType")
```

This will cause the vehicle to compute a new route from startEdge to
endEdge according to the estimated travel times in the network at the
time of departure. For details of this mechanism see
[Demand/Automatic_Routing](../Demand/Automatic_Routing.md).

### coordinate transformations

```
 x, y = traci.vehicle.getPosition(vehID)
 lon, lat = traci.simulation.convertGeo(x, y)
 x2, y2 = traci.simulation.convertGeo(lon, lat, fromGeo=True)
```

```
 edgeID, lanePosition, laneIndex = traci.simulation.convertRoad(x3, y3)
 edgeID, lanePosition, laneIndex = traci.simulation.convertRoad(lon2, lat2, True)
```

### Retrieve the timeLoss for all vehicles currently in the network

import traci import traci.constants as tc junctionID = '...'

1.  subscribe around an aribtrary junction with a sufficiently large
    radius to retrieve the speeds of all vehicles in every step

traci.junction.subscribeContext(junctionID,
tc.CMD_GET_VEHICLE_VARIABLE, 1000000, \[tc.VAR_SPEED,
tc.VAR_ALLOWED_SPEED\]) stepLength = traci.simulation.getDeltaT()
while traci.simulation.getMinExpectedNumber() \> 0:

```
   traci.simulationStep()
   scResults = traci.junction.getContextSubscriptionResults(junctionID)
   halting = 0
   if scResults:
       relSpeeds = [d[tc.VAR_SPEED] / d[tc.VAR_ALLOWED_SPEED] for d in scResults.values()]
       # compute values corresponding to summary-output
       running = len(relSpeeds)
       halting = len([1 for d in scResults.values() if d[tc.VAR_SPEED] < 0.1])
       meanSpeedRelative = sum(relSpeeds) / running
       timeLoss = (1 - meanSpeedRelative) * running * stepLength
   print(traci.simulation.getTime(), timeLoss, halting)
```

traci.close()

## Further Resources

- The module [Simpla](../Simpla.md) provides a library for
  platooning functions that can be integrated with user client
  scripts.

{'repo_name': 'eclipse/sumo', 'stars': '728', 'repo_language': 'C++', 'file_name': 'testsuite.neteditcheckoutput', 'mime_type': 'text/plain', 'hash': 3838728933896588564, 'source_dataset': 'data'}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Materia.MathHelpers;

namespace Materia.Nodes.MathNodes
{
    public class LengthNode : MathNode
    {
        NodeInput input;
        NodeOutput output;

        public LengthNode(int w, int h, GraphPixelType p = GraphPixelType.RGBA) : base()
        {
            //we ignore w,h,p

            CanPreview = false;

            Name = "Length";
            Id = Guid.NewGuid().ToString();
            shaderId = "S" + Id.Split('-')[0];

            input = new NodeInput(NodeType.Float2 | NodeType.Float3 | NodeType.Float4, this, "Any Vector Type");
            output = new NodeOutput(NodeType.Float, this);

            Inputs.Add(input);
            Outputs.Add(output);
        }

        public override string GetShaderPart(string currentFrag)
        {
            if (!input.HasInput) return "";
            var s = shaderId + "1";
            var n1id = (input.Reference.Node as MathNode).ShaderId;

            var index = input.Reference.Node.Outputs.IndexOf(input.Reference);

            n1id += index;

            return "float " + s + " = length(" + n1id + ");\r\n";
        }

        public override void TryAndProcess()
        {
            if (!input.IsValid) return;
            try
            {
                MVector v = (MVector)input.Data;
                output.Data = v.Length;

                result = output.Data?.ToString();
            }
            catch (Exception e)
            {

            }
        }
    }
}

{'repo_name': 'Metric/Materia', 'stars': '185', 'repo_language': 'C#', 'file_name': 'Triangle.cs', 'mime_type': 'text/plain', 'hash': 2839098670615283314, 'source_dataset': 'data'}


/*
 * Copyright 2013, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.jf.dexlib2.writer.util;

import com.google.common.collect.Lists;
import org.jf.dexlib2.base.BaseTryBlock;
import org.jf.dexlib2.iface.ExceptionHandler;
import org.jf.dexlib2.iface.TryBlock;
import org.jf.util.ExceptionWithContext;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

public class TryListBuilder<EH extends ExceptionHandler>
{
    // Linked list sentinels that don't represent an actual try block
    // Their values are never modified, only their links
    private final MutableTryBlock<EH> listStart;
    private final MutableTryBlock<EH> listEnd;

    public TryListBuilder() {
        listStart = new MutableTryBlock<EH>(0, 0);
        listEnd = new MutableTryBlock<EH>(0, 0);
        listStart.next = listEnd;
        listEnd.prev = listStart;
    }

    public static <EH extends ExceptionHandler> List<TryBlock<EH>> massageTryBlocks(
            List<? extends TryBlock<? extends EH>> tryBlocks) {
        TryListBuilder<EH> tlb = new TryListBuilder<EH>();

        for (TryBlock<? extends EH> tryBlock: tryBlocks) {
            int startAddress = tryBlock.getStartCodeAddress();
            int endAddress = startAddress + tryBlock.getCodeUnitCount();

            for (EH exceptionHandler: tryBlock.getExceptionHandlers()) {
                tlb.addHandler(startAddress, endAddress, exceptionHandler);
            }
        }
        return tlb.getTryBlocks();
    }

    private static class TryBounds<EH extends ExceptionHandler> {
        @Nonnull public final MutableTryBlock<EH> start;
        @Nonnull public final MutableTryBlock<EH> end;

        public TryBounds(@Nonnull MutableTryBlock<EH> start, @Nonnull MutableTryBlock<EH> end) {
            this.start = start;
            this.end = end;
        }
    }

    public static class InvalidTryException extends ExceptionWithContext {
        public InvalidTryException(Throwable cause) {
            super(cause);
        }

        public InvalidTryException(Throwable cause, String message, Object... formatArgs) {
            super(cause, message, formatArgs);
        }

        public InvalidTryException(String message, Object... formatArgs) {
            super(message, formatArgs);
        }
    }

    private static class MutableTryBlock<EH extends ExceptionHandler> extends BaseTryBlock<EH> {
        public MutableTryBlock<EH> prev = null;
        public MutableTryBlock<EH> next = null;

        public int startCodeAddress;
        public int endCodeAddress;
        @Nonnull public List<EH> exceptionHandlers = Lists.newArrayList();

        public MutableTryBlock(int startCodeAddress, int endCodeAddress) {
            this.startCodeAddress = startCodeAddress;
            this.endCodeAddress = endCodeAddress;
        }

        public MutableTryBlock(int startCodeAddress, int endCodeAddress,
                               @Nonnull List<EH> exceptionHandlers) {
            this.startCodeAddress = startCodeAddress;
            this.endCodeAddress = endCodeAddress;
            this.exceptionHandlers = Lists.newArrayList(exceptionHandlers);
        }

        @Override public int getStartCodeAddress() {
            return startCodeAddress;
        }

        @Override public int getCodeUnitCount() {
            return endCodeAddress - startCodeAddress;
        }

        @Nonnull @Override public List<EH> getExceptionHandlers() {
            return exceptionHandlers;
        }

        @Nonnull
        public MutableTryBlock<EH> split(int splitAddress) {
            MutableTryBlock<EH> newTryBlock = new MutableTryBlock<EH>(splitAddress, endCodeAddress, exceptionHandlers);
            endCodeAddress = splitAddress;
            append(newTryBlock);
            return newTryBlock;
        }

        public void delete() {
            next.prev = prev;
            prev.next = next;
        }

        public void mergeNext() {
            //assert next.startCodeAddress == this.endCodeAddress;
            this.endCodeAddress = next.endCodeAddress;
            next.delete();
        }

        public void append(@Nonnull MutableTryBlock<EH> tryBlock) {
            next.prev = tryBlock;
            tryBlock.next = next;
            tryBlock.prev = this;
            next = tryBlock;
        }

        public void prepend(@Nonnull MutableTryBlock<EH> tryBlock) {
            prev.next = tryBlock;
            tryBlock.prev = prev;
            tryBlock.next = this;
            prev = tryBlock;
        }

        public void addHandler(@Nonnull EH handler) {
            for (ExceptionHandler existingHandler: exceptionHandlers) {
                String existingType = existingHandler.getExceptionType();
                String newType = handler.getExceptionType();

                if (existingType == null) {
                    if (newType == null) {
                        if (existingHandler.getHandlerCodeAddress() != handler.getHandlerCodeAddress()) {
                            throw new InvalidTryException(
                                    "Multiple overlapping catch all handlers with different handlers");
                        }
                        return;
                    }
                } else if (existingType.equals(newType)) {
                    // dalvik doesn't reject cases when there are multiple catches with the same exception
                    // but different handlers. In practice, the first handler "wins". Since the later
                    // handler will never be used, we don't add it.
                    return;
                }
            }

            exceptionHandlers.add(handler);
        }
    }

    private TryBounds<EH> getBoundingRanges(int startAddress, int endAddress) {
        MutableTryBlock<EH> startBlock = null;

        MutableTryBlock<EH> tryBlock = listStart.next;
        while (tryBlock != listEnd) {
            int currentStartAddress = tryBlock.startCodeAddress;
            int currentEndAddress = tryBlock.endCodeAddress;

            if (startAddress == currentStartAddress) {
                //|-----|
                //^------
                /*Bam. We hit the start of the range right on the head*/
                startBlock = tryBlock;
                break;
            } else if (startAddress > currentStartAddress && startAddress < currentEndAddress) {
                //|-----|
                //  ^----
                /*Almost. The start of the range being added is in the middle
                of an existing try range. We need to split the existing range
                at the start address of the range being added*/
                startBlock = tryBlock.split(startAddress);
                break;
            }else if (startAddress < currentStartAddress) {
                if (endAddress <= currentStartAddress) {
                    //      |-----|
                    //^--^
                    /*Oops, totally too far! The new range doesn't overlap any existing
                    ones, so we just add it and return*/
                    startBlock = new MutableTryBlock<EH>(startAddress, endAddress);
                    tryBlock.prepend(startBlock);
                    return new TryBounds<EH>(startBlock, startBlock);
                } else {
                    //   |-----|
                    //^---------
                    /*Oops, too far! We've passed the start of the range being added, but
                     the new range does overlap this one. We need to add a new range just
                     before this one*/
                    startBlock = new MutableTryBlock<EH>(startAddress, currentStartAddress);
                    tryBlock.prepend(startBlock);
                    break;
                }
            }

            tryBlock = tryBlock.next;
        }

        //|-----|
        //        ^-----
        /*Either the list of tries is blank, or all the tries in the list
        end before the range being added starts. In either case, we just need
        to add a new range at the end of the list*/
        if (startBlock == null) {
            startBlock = new MutableTryBlock<EH>(startAddress, endAddress);
            listEnd.prepend(startBlock);
            return new TryBounds<EH>(startBlock, startBlock);
        }

        tryBlock = startBlock;
        while (tryBlock != listEnd) {
            int currentStartAddress = tryBlock.startCodeAddress;
            int currentEndAddress = tryBlock.endCodeAddress;

            if (endAddress == currentEndAddress) {
                //|-----|
                //------^
                /*Bam! We hit the end right on the head... err, tail.*/
                return new TryBounds<EH>(startBlock, tryBlock);
            } else if (endAddress > currentStartAddress && endAddress < currentEndAddress) {
                //|-----|
                //--^
                /*Almost. The range being added ends in the middle of an
                existing range. We need to split the existing range
                at the end of the range being added.*/
                tryBlock.split(endAddress);
                return new TryBounds<EH>(startBlock, tryBlock);
            } else if (endAddress <= currentStartAddress) {
                //|-----|       |-----|
                //-----------^
                /*Oops, too far! The current range starts after the range being added
                ends. We need to create a new range that starts at the end of the
                previous range, and ends at the end of the range being added*/
                MutableTryBlock<EH> endBlock = new MutableTryBlock<EH>(tryBlock.prev.endCodeAddress, endAddress);
                tryBlock.prepend(endBlock);
                return new TryBounds<EH>(startBlock, endBlock);
            }
            tryBlock = tryBlock.next;
        }

        //|-----|
        //--------^
        /*The last range in the list ended before the end of the range being added.
        We need to add a new range that starts at the end of the last range in the
        list, and ends at the end of the range being added.*/
        MutableTryBlock<EH> endBlock = new MutableTryBlock<EH>(listEnd.prev.endCodeAddress, endAddress);
        listEnd.prepend(endBlock);
        return new TryBounds<EH>(startBlock, endBlock);
    }

    public void addHandler(int startAddress, int endAddress, EH handler) {
        TryBounds<EH> bounds = getBoundingRanges(startAddress, endAddress);

        MutableTryBlock<EH> startBlock = bounds.start;
        MutableTryBlock<EH> endBlock = bounds.end;

        int previousEnd = startAddress;
        MutableTryBlock<EH> tryBlock = startBlock;

        /*Now we have the start and end ranges that exactly match the start and end
        of the range being added. We need to iterate over all the ranges from the start
        to end range inclusively, and append the handler to the end of each range's handler
        list. We also need to create a new range for any "holes" in the existing ranges*/
        do
        {
            //is there a hole? If so, add a new range to fill the hole
            if (tryBlock.startCodeAddress > previousEnd) {
                MutableTryBlock<EH> newBlock = new MutableTryBlock<EH>(previousEnd, tryBlock.startCodeAddress);
                tryBlock.prepend(newBlock);
                tryBlock = newBlock;
            }

            tryBlock.addHandler(handler);
            previousEnd = tryBlock.endCodeAddress;
            tryBlock = tryBlock.next;
        } while (tryBlock.prev != endBlock);
    }

    public List<TryBlock<EH>> getTryBlocks() {
        return Lists.newArrayList(new Iterator<TryBlock<EH>>() {
            // The next TryBlock to return. This has already been merged, if needed.
            @Nullable private MutableTryBlock<EH> next;

            {
                next = listStart;
                next = readNextItem();
            }

            /**
             * Read the item that comes after the current value of the next field.
             * @return The next item, or null if there is no next item
             */
            @Nullable protected MutableTryBlock<EH> readNextItem() {
                // We can assume that next is not null, due to the way iteration happens
                MutableTryBlock<EH> ret = next.next;

                if (ret == listEnd) {
                    return null;
                }

                while (ret.next != listEnd) {
                    if (ret.endCodeAddress == ret.next.startCodeAddress &&
                            ret.getExceptionHandlers().equals(ret.next.getExceptionHandlers())) {
                        ret.mergeNext();
                    } else {
                        break;
                    }
                }
                return ret;
            }

            @Override public boolean hasNext() {
                return next != null;
            }

            @Override @Nonnull public TryBlock<EH> next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                TryBlock<EH> ret = next;
                next = readNextItem();
                // ret can't be null (ret=next and hasNext returned true)
                return ret;
            }

            @Override public void remove() {
                throw new UnsupportedOperationException();
            }
        });
    }
}

{'repo_name': 'F8LEFT/FUPK3', 'stars': '718', 'repo_language': 'C++', 'file_name': 'ExampleUnitTest.java', 'mime_type': 'text/html', 'hash': -3234674120523008592, 'source_dataset': 'data'}


(function () {
function handleExternalScript() {
  var container = Docsify.dom.getNode('#main');
  var scripts = Docsify.dom.findAll(container, 'script');

  for (var i = scripts.length; i--;) {
    var script = scripts[i];

    if (script && script.src) {
      var newScript = document.createElement('script');

      Array.prototype.slice.call(script.attributes).forEach(function (attribute) {
        newScript[attribute.name] = attribute.value;
      });

      script.parentNode.insertBefore(newScript, script);
      script.parentNode.removeChild(script);
    }
  }
}

var install = function (hook) {
  hook.doneEach(handleExternalScript);
};

window.$docsify.plugins = [].concat(install, window.$docsify.plugins);

}());

{'repo_name': 'ontio/documentation', 'stars': '121', 'repo_language': 'JavaScript', 'file_name': 'README.md', 'mime_type': 'text/plain', 'hash': 3805388197156589741, 'source_dataset': 'data'}


/*
 *  Copyright (c) 2014, Oculus VR, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

/// \file
/// \brief This will write all incoming and outgoing network messages to a file
///

#include "NativeFeatureIncludes.h"
#if _RAKNET_SUPPORT_PacketLogger==1

#ifndef __PACKET_OUTPUT_WINDOW_LOGGER_H_
#define __PACKET_OUTPUT_WINDOW_LOGGER_H_

#include "PacketLogger.h"

namespace RakNet
{

/// \ingroup PACKETLOGGER_GROUP
/// \brief Packetlogger that outputs to the output window in the debugger. Windows only.
class RAK_DLL_EXPORT  PacketOutputWindowLogger : public PacketLogger
{
public:
	PacketOutputWindowLogger();
	virtual ~PacketOutputWindowLogger();
	virtual void WriteLog(const char *str);
protected:
};

} // namespace RakNet

#endif

#endif // _RAKNET_SUPPORT_*

{'repo_name': 'DataRealms/CCOSS', 'stars': '306', 'repo_language': 'C++', 'file_name': 'Resources.Designer.cs', 'mime_type': 'text/plain', 'hash': 4922127576479855281, 'source_dataset': 'data'}


using GW2PAO.Data;
using GW2PAO.Modules.Commerce.Models;
using GW2PAO.PresentationCore;
using Microsoft.Practices.Prism.Mvvm;
using NLog;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GW2PAO.Modules.Commerce.ViewModels
{
    public class EctoSalvageHelperViewModel : BindableBase
    {
        /// <summary>
        /// Default logger
        /// </summary>
        private static readonly Logger logger = LogManager.GetCurrentClassLogger();

        public const int EctoplasmItemID = 19721;
        public const double EctoplasmChanceCoeff = 0.875; // see wiki
        public const double SalvageCost = 10.496; // 26s24c for 250 uses

        /// <summary>
        /// The Commerce User Data
        /// </summary>
        private CommerceUserData userData;

        /// <summary>
        /// Price of the highest buy order for Ectoplasm
        /// </summary>
        public Price EctoplasmBuyOrder { get; private set; }

        /// <summary>
        /// Price of the lowest sell listing for Ectoplasm
        /// </summary>
        public Price EctoplasmSellListing { get; private set; }

        /// <summary>
        /// Cost of Tax
        /// </summary>
        public Price Tax { get; private set; }

        /// <summary>
        /// The final calculated salvage threshold
        /// </summary>
        public Price SalvageThreshold { get; private set; }

        /// <summary>
        /// True if the Buy Order price should be used for ectoplasm prices
        /// </summary>
        public bool UseBuyOrder
        {
            get { return !this.userData.EctoplasmThresholdUsesSellListing; }
            set
            {
                if (this.userData.EctoplasmThresholdUsesSellListing != !value)
                {
                    this.userData.EctoplasmThresholdUsesSellListing = !value;

                    this.OnPropertyChanged(() => this.UseBuyOrder);
                    this.OnPropertyChanged(() => this.UseSellListing);
                    this.CalculateSalvageThreshold();
                }
            }
        }

        /// <summary>
        /// /// True if the Sell Listing price should be used for ectoplasm prices
        /// </summary>
        public bool UseSellListing
        {
            get { return this.userData.EctoplasmThresholdUsesSellListing; }
            set
            {
                if (this.userData.EctoplasmThresholdUsesSellListing != value)
                {
                    this.userData.EctoplasmThresholdUsesSellListing = value;

                    this.OnPropertyChanged(() => this.UseBuyOrder);
                    this.OnPropertyChanged(() => this.UseSellListing);
                    this.CalculateSalvageThreshold();
                }
            }
        }

        /// <summary>
        /// Default constructor
        /// </summary>
        public EctoSalvageHelperViewModel(CommerceUserData userData)
        {
            this.EctoplasmBuyOrder = new Price();
            this.EctoplasmSellListing = new Price();
            this.Tax = new Price();
            this.SalvageThreshold = new Price();
            this.userData = userData;

            this.EctoplasmBuyOrder.PropertyChanged += (o, e) => this.CalculateSalvageThreshold();
            this.EctoplasmSellListing.PropertyChanged += (o, e) => this.CalculateSalvageThreshold();
        }

        private void CalculateSalvageThreshold()
        {
            if (this.userData.EctoplasmThresholdUsesSellListing)
            {
                this.Tax.Value = this.EctoplasmSellListing.Value * 0.85;
                this.SalvageThreshold.Value = (this.EctoplasmSellListing.Value * 0.85 * EctoplasmChanceCoeff - SalvageCost) / 0.85;
            }
            else
            {
                this.Tax.Value = this.EctoplasmBuyOrder.Value * 0.85;
                this.SalvageThreshold.Value = (this.EctoplasmBuyOrder.Value * 0.85 * EctoplasmChanceCoeff - SalvageCost) / 0.85;
            }
        }
    }
}

{'repo_name': 'SamHurne/gw2pao', 'stars': '118', 'repo_language': 'C#', 'file_name': 'setup.iss', 'mime_type': 'text/plain', 'hash': -6400796212957836383, 'source_dataset': 'data'}


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.10"/>
<title>0.9.9 API documenation: GLM_GTC_ulp</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>

<link href="search/search.css" rel="stylesheet" type="text/css"/>

<link href="doxygen.css" rel="stylesheet" type="text/css" />

0.9.9 API documenation

Main Page

Modules

Files

          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)"
               onblur="searchBox.OnSearchFieldFocus(false)"
               onkeyup="searchBox.OnSearchFieldChange(event)"/>

Functions

GLM_GTC_ulp
Stable extensions

Include <glm/gtc/ulp.hpp> to use the features of this extension.
More...

Functions

template<typename T >

GLM_FUNC_DECL uint 	float_distance (T const &x, T const &y)

 	Return the distance in the number of ULP between 2 scalars.  More...

template<typename T , qualifier Q>

GLM_FUNC_DECL vec< 2, uint, Q > 	float_distance (vec< 2, T, Q > const &x, vec< 2, T, Q > const &y)

 	Return the distance in the number of ULP between 2 vectors.  More...

template<typename genType >

GLM_FUNC_DECL genType 	next_float (genType const &x)

 	Return the next ULP value(s) after the input value(s).  More...

template<typename genType >

GLM_FUNC_DECL genType 	next_float (genType const &x, uint const &Distance)

 	Return the value(s) ULP distance after the input value(s).  More...

template<typename genType >

GLM_FUNC_DECL genType 	prev_float (genType const &x)

 	Return the previous ULP value(s) before the input value(s).  More...

template<typename genType >

GLM_FUNC_DECL genType 	prev_float (genType const &x, uint const &Distance)

 	Return the value(s) ULP distance before the input value(s).  More...

Detailed Description

Include <glm/gtc/ulp.hpp> to use the features of this extension.

Allow the measurement of the accuracy of a function against a reference implementation. This extension works on floating-point data and provide results in ULP.

Function Documentation

          GLM_FUNC_DECL uint glm::float_distance
          (
          T const &
          x,

          T const &
          y

          )

Return the distance in the number of ULP between 2 scalars.

See also

<a class="el" href="a00167.html" title="Include <glm/gtc/ulp.hpp> to use the features of this extension. ">GLM_GTC_ulp

          GLM_FUNC_DECL vec<2, uint, Q> glm::float_distance
          (
          vec< 2, T, Q > const &
          x,

          vec< 2, T, Q > const &
          y

          )

Return the distance in the number of ULP between 2 vectors.

See also

<a class="el" href="a00167.html" title="Include <glm/gtc/ulp.hpp> to use the features of this extension. ">GLM_GTC_ulp

          GLM_FUNC_DECL genType glm::next_float
          (
          genType const &
          x	)

Return the next ULP value(s) after the input value(s).

See also

<a class="el" href="a00167.html" title="Include <glm/gtc/ulp.hpp> to use the features of this extension. ">GLM_GTC_ulp

          GLM_FUNC_DECL genType glm::next_float
          (
          genType const &
          x,

          uint const &
          Distance

          )

Return the value(s) ULP distance after the input value(s).

See also

<a class="el" href="a00167.html" title="Include <glm/gtc/ulp.hpp> to use the features of this extension. ">GLM_GTC_ulp

          GLM_FUNC_DECL genType glm::prev_float
          (
          genType const &
          x	)

Return the previous ULP value(s) before the input value(s).

See also

<a class="el" href="a00167.html" title="Include <glm/gtc/ulp.hpp> to use the features of this extension. ">GLM_GTC_ulp

          GLM_FUNC_DECL genType glm::prev_float
          (
          genType const &
          x,

          uint const &
          Distance

          )

Return the value(s) ULP distance before the input value(s).

See also

<a class="el" href="a00167.html" title="Include <glm/gtc/ulp.hpp> to use the features of this extension. ">GLM_GTC_ulp

<address class="footer">
Generated by

 1.8.10
</address>

{'repo_name': 'fossephate/JoyCon-Driver', 'stars': '702', 'repo_language': 'C++', 'file_name': 'toolbar.h', 'mime_type': 'text/x-c++', 'hash': -4091378772751787489, 'source_dataset': 'data'}


## Lab 200 - Analyzing Sales - Basic Introduction to Core Features

This section walks you through the analysis of a single data set.

Key takeaways from this lab:
- Creating projects with data sets and visualizations
- Understanding the visualization capabilities of DV
- Telling a story with annotated visualizations

### a) Creating a Project with a Data Source and Visualizations

**Scenario**

You are the Chief Marketing Officer (CMO) of KoolKart.

KoolKart is an e-Commerce company that sells 4 categories of products and is looking for innovative ways to increase revenues. As part of that initiative, you and your team have launched several social media campaigns within the past 6 months.

Given the level of investment your company has made, you are looking to ensure that resources are being effectively utilized. Hence, you are investigating the effectiveness of those campaigns.

After reaching out to the sales team, you have been provided with a spreadsheet with thousands of rows of information and are struggling to make heads or tails of what you are evaluating. Let’s see how DV can help you!

1. Review the spreadsheet containing the sales figures used in this lab.

     Download and open the **KoolKart Sales Data.xlsx** file.

    ![](images/200/img_2a_1_1.png " ")

    >You should see that there are several thousand records of sales figures (e.g. **Revenue** and **Number of Orders**) broken down by **Date**, **Category**, **Age Group**, and **Gender**.

    You can close the spreadsheet.

2. Create a project to evaluate the sales data and upload the Excel file.

    Select **Create Project** from the Home screen.

    ![](images/200/img_2a_2_1.png " ")

    Every project requires a data source, so you will be prompted to add one.

    Select **Create Data Set** to load in the Excel file.

    ![](images/200/img_2a_2_2.png " ")

    >If you had created connections to external systems (e.g. an Oracle Database), you would see those as options here. For the purpose of this lab, we will just upload a file.

    ![](images/200/img_2a_2_3.png " ")

    Navigate to the **KoolKart Sales Data.xlsx** file and select it.

3. Validate the uploaded data.

    >Following the upload of the file, which will be available for other projects as a **Data Source**, you have the ability to make changes to the data so it can be easily used within analyses.

    ![](images/200/img_2a_3_1.png " ")

    ![](images/200/img_2a_3_2.png " ")

    The system will determine, if the columns are **Attributes** or **Measures**.

    >![](images/200/img_2a_3_3.png " ") **Attributes**: Indicated by **A**, attributes are generally non-numeric fields.

    >![](images/200/img_2a_3_4.png " ") **Measures**: Indicated by **#**, measures are generally numeric fields.

    >If a field is determined to be a **Measure**, the system will also determine the default aggregation method for when it is used in an analysis (e.g. average, sum, count). If desired, you can change an **Attribute** to a **Measure** and vice-versa. For **Measures**, you can also change the default aggregation rule.

    >![](images/200/img_2a_3_5.png " ") **Clock**: Fields may also be indicated by a **Clock** icon. These will be your date and time based fields, which can be handled differently in certain visualizations. However, they still need to be defined as **Attributes** or **Measures**. If the **Clock** icon appears, the date is being treated as an **Attribute** otherwise it will have a **#** icon.

    No changes are needed for this data.

4. Add data to your project.

    Click **Add** to begin creating visualizations.

    ![](images/200/img_2a_4_1.png " ")

5. Use **Recommendations** to enrich your data set for analysis.

    On creating the data set, you will be guided to the **Prepare** screen, where you can modify your data set. OAC uses its intelligence to recommend changes that can enrich the data set.

    ![](images/200/img_2a_4_2.png " ")

    Selecting a column will filter the recommendations to show only those related to that column.

    Select **Customer Country** to see the recommendations for the column..

    ![](images/200/img_2a_4_3.png " ")

    >Although, we won't be using the recommendations now, it is a very powerful feature and we will see that in the last lab.

6. Create an analysis of monthly revenues.

    Select the **Visualize** tab (top right of the screen).

    ![](images/200/img_2a_5_1.png " ")

    Select the **Data Elements** icon and select **Month**. Press and hold the **Control(Windows)** or **Command(Mac)** key and click on **Revenue** Then, right click and select **Create Best Visualization**.

    ![](images/200/img_2a_5_2.png " ")

    >As an intelligent analytics platform, the system is able to provide recommendations for how best to visualize information. The system has determined that a horizontal bar chart is a good way to display the information that you are evaluating.

    ![](images/200/img_2a_5_3.png " ")

    Before we continue, let’s take a step back and better understand the interface of the Visualize tab and its capabilities.

### b) Understanding the Visualize Interface

1. Review the **Visualize** interface and menus.

    >We have previously established that a **Project** comprises of data sources and visualizations related to those data sources. We have already walked through the process of adding a data source in the previous section. Now, we will learn some more about visualizations.

    >Visualizations are displayed on a canvas. A **Canvas** can contain multiple visualizations and a **Project** can include multiple Canvases.

    >When you open the **Visualize** interface, you should see the **Canvas** in addition to a few other menus. The **Project Components Menu** will be on the left hand side. The **Project Tabs** will appear at the center top of the screen and the **Project Menu** will be in the top right.

    ![](images/200/img_2b_1_1.png " ")

    Let’s start by reviewing the **Project Tabs**, which allow you to switch between editing data sources, creating visualizations, and putting together a story about the visualizations.

    ![](images/200/img_2b_1_2.png " ")

    You can switch between the tabs as needed and each has a specific purpose:

    >**Prepare** – Validate and make changes to the data you wish to use in your visualizations.

    >**Visualize** – Create your visualizations.

    >**Narrate** – A nice feature where you can view, compile, and manage meaningful “stories” from your visualizations by picking certain ones to highlight and adding commentary.

    Next to the **Project Tabs**, you will find the **Project Menu** which allows you to manage various facets of your project.

    ![](images/200/img_2b_1_3.png " ")

    From left to right, the items are:

    >**Undo Last Edit** – Remove the last user change.

    >**Redo Last Edit** – Reapply the last user change rolled back by the above (greyed out, if there is nothing to redo).

    >**Share Project** – Bring up additional options for sharing the project.

    >**Canvas Settings** – Provides ability to manage canvas and project level properties.

    On the left hand side of the screen, the **Project Components Menu** displays the available Data Sources, **Data Elements**, **Analytics**, or **Visualizations** within the project (depending upon which one has been selected). If you are on the **Prepare** tab, then it will display **Preparation Script** or **Data Elements**.

    ![](images/200/img_2b_1_4.png " ")

    The icons on the left filter the items listed. From top to bottom they are:

    >**Data Elements** – Displays the actual data available for analysis (e.g. the columns from your data sources).

    >**Analytics** – Provides access to advanced analytics that can be added to visualizations such as trend lines, clusters, and outliers.

    >**Visualizations** – Visual elements available for use in the Canvas.

    Based on which icon is selected, you will see different results. The example below shows the **Data Elements** in our current project.

    ![](images/200/img_2b_1_5.png " ")

    The **Search** box allows you to search through the data sets. For example, you can search for **Data Elements** that are related to the customers by typing in customer.

    ![](images/200/img_2b_1_6.png " ")

    ![](images/200/img_2b_1_7.png " ") Click the **X** to remove any filters (please do so, now).

    Now that you have been exposed to the core features of the interface, let’s dive into some further analyses.

### c) Analyzing Sales Figures by Product and Customer Segments

>Thus far, you have brought data into DV and generated a basic analysis of revenues over the past six months. However, this is a fairly basic analysis and, as CMO, you really need and want to dig in to the data further. Specifically, you are interested in seeing how different product categories are performing and how different marketing segments (e.g. gender) have an impact on those figures.

1. Create a breakdown of revenue by product category.

    Drag and drop **Category** into the **Color** property of the previously created bar chart.

    ![](images/200/img_2c_1_1.png " ")

    You can now see monthly revenue broken out by product category.

    ![](images/200/img_2c_1_2.png " ")

    >Built-in intelligence can even attempt to determine the best way to add **Category** to your visualization by simply double clicking on it.

    >You can also interact with the results further by hovering over various categories. For example, if you move your mouse over the yellow portion of **2015-11** (which represents **Electronics & Computers**), you will see all other categories dimmed for easier viewing. You will also be able to see more detailed information on the actual data (e.g. the actual number of orders).

    ![](images/200/img_2c_1_3.png " ")

    ![](images/200/img_2c_1_4.png " ")

    >After looking at each product category, you can now see that Electronics & Computers and Clothing & Shoes categories are consistently the major contributors to sales in the past 6 months.

    >That helps in better understanding which categories drive the most revenues, but you still need to better understand your customer demographics.

2. Create a new type of visualization to evaluate revenues by age group.

    Select the **Data Elements** item and select **Customer Age Group**. Press and hold the **Control(Windows)** or **Command(Mac)** key and click on **Revenue**. Now, right click and select **Pick Visualization**.

    ![](images/200/img_2c_2_1.png " ")

    **Select Donut**.

    ![](images/200/img_2c_2_2.png " ")

    >As you can see, there is already a great variety of visualizations available and more are released in every new version of the tool. We won't be covering each and every one, but we have made an attempt to provide a few examples during the course of this workshop. Please feel free to try out the different types!

    ![](images/200/img_2c_2_3.png " ")

    You should see the new visualization, automatically placed next to the bar chart.

    >It looks like our customers in the 25-31 and 32-39 age range are the largest contributors to our revenues in the past 6 months. Let’s take a look at revenues over time to see if there is a noticeable increase over time (which we’d hope based upon our investments in the social media campaigns).

3. Create a new type of visualization to evaluate revenues by date (e.g. to view a trend over time as opposed to just monthly totals).

    Select the **Data Elements** item and select **Date**. Press and hold **Control(Windows)** or **Command(Mac)**. Select **Revenue**. Now, right click and select **Create Best Visualization**.

    ![](images/200/img_2c_3_1.png " ")

    You should now see a canvas that looks like the following:

    ![](images/200/img_2c_3_2.png " ")

    >It looks like we have seen some increased revenues, though we will likely need to drill in even further to identify the impact of the social media campaigns. However, before we do that, let’s “clean-up” the canvas so it’s easier to digest, in case we need to share the results.

### d) Formatting Visualizations and the Canvas

1. Rearrange the visualizations to make them easier to view.

    Click on the **Revenue by Date** timeline visualization. A blue border will indicate that the image has been selected. Hover your cursor near the top border until you see a 4-way arrow icon.

    ![](images/200/img_2d_1_1.png " ")

    Left click and drag the visualization into the top right of the canvas above the **Revenue by Customer Age Group** visualization until you see a thick blue line.

    ![](images/200/img_2d_1_2.png " ")

    Make sure that the thick blue line does not extend above Revenue by Month, Category otherwise the visualization you are moving will appear above both the bar chart and donut.

    ![](images/200/img_2d_1_3.png " ")

    ![](images/200/img_2d_1_4.png " ")

    Now, click on the **Customer Age Group** visualization. Just like the previous time, the image will have a blue border when selected. Hover your cursor until you see a 4-way arrow icon.

    ![](images/200/img_2d_1_5.png " ")

    Left click and drag the visualization into the bottom left of the canvas under the **Revenue by Month, Category** visualization until you see a thick blue line.

    ![](images/200/img_2d_1_6.png " ")

    Your canvas should look like the following:

    ![](images/200/img_2d_1_7.png " ")

2. Expand one of the visualizations.

    Now, click on the **Revenue by Date** visualization. Hover your cursor over the left border until you see an arrow icon.

    ![](images/200/img_2d_2_1.png " ")

    Left click and drag the edge of the visualization to the left to increase the size. Your canvas should now look like the following:

    ![](images/200/img_2d_2_2.png " ")

3. Adjust the project colors used in the visualizations.

    Select the **Canvas Settings** option in the **Project Menu** in the top right of the screen and select **Project Properties**.

    ![](images/200/img_2d_3_1.png " ")

    Click on **Default** in the **Color Series** option.

    ![](images/200/img_2d_3_2.png " ")

    Scroll down and select **Tokyo**. Then select OK.

    ![](images/200/img_2d_3_3.png " ")

    ![](images/200/img_2d_3_4.png " ")

    All of the visualizations will now reflect the new color scheme, across all canvases!

    ![](images/200/img_2d_3_5.png " ")

    >You may have noticed that in addition to a wide variety of options and configurations, there is also the ability to create custom palettes, which enables users to display results however they wish. For the purpose of this example, we made changes at the project level for a quick and easy change but colors and display options are also available at the visualization level to allow for full flexibility.

4. Reset the color palette.

    To avoid confusion with coloring in prior exercises, let’s go ahead and reset the color palette.

    Select the **Canvas Settings** option in the **Project Menu** in the top right of the screen and select **Reset Colors**.

    ![](images/200/img_2d_4_1.png " ")

5. Rename the Canvas.

    Since **Projects** can have multiple **Canvases**, it usually makes sense to name them for the ease of reviewing down the line.

    Select the **arrow icon** in the **canvas tab** on the bottom left of the screen.

    ![](images/200/img_2d_5_1.png " ")

    Give the **Canvas** a meaningful name such as **Revenue Analysis** by clicking in the box and typing it in. Select **OK** to confirm your changes.

    ![](images/200/img_2d_5_2.png " ")

### e) Analyzing Visualizations with Trend Lines and Trellis Rows

>As mentioned earlier, as the KoolKart CMO, you have now started to evaluate your revenue data. However, you want to make sure that it has some relation to the social media campaigns that you launched during November, January, February, and April. At first glance, it does look like revenues are increasing following those campaigns but you want to make sure things are also trending upwards, overall.

Luckily, DV can help. So, let’s take a closer look at our numbers!

1. Add a trend line to your Revenue by Date visualization.

    **Right click** anywhere in the **Revenue by Date** visualization and select **Add Statistics** followed by **Trend Line.

    ![](images/200/img_2e_1_1.png " ")

    You should now see a trend line within the **Revenue by Date** visualization.

    Click anywhere in the visualization to remove the trend line properties menu.

    >Upon adding the trend line, hopefully you also notice the ability to add other types of analyses such as: reference lines, clusters, forecasts, as well as the ability to fine tune those analyses. The platform is highly intelligent and robust, and allows for the deepest levels of analysis, some of which we will cover in later labs.

    >It looks like revenues are trending upwards and have been healthy for the past 6 months! But let’s see if that holds true for all product categories or if our campaigns have had more success in certain areas than others.

2. Further analyze your **Revenue by Date** visualization by breaking it out, according to product category.

    >Trellis Rows and Trellis Columns are mechanisms by which we can breakdown an analysis by creating multiple versions of that analysis for distinct entities. In the example being used, there is an initial line chart looking at revenues over time. Adding a Trellis Row for product category creates a line chart of revenues for each product category. See below for a screenshot.

    ![](images/200/img_2e_2_1.png " ")

    Make sure the **Revenue by Date** visualization is selected by clicking on it. Now, select **Category** from the **Project Components Menu** on the left (make sure to select the **Data Elements**, if you do not see **Category** listed). Drag and drop it into the **Trellis Rows** property of the visualization.

    ![](images/200/img_2e_2_2.png " ")

    Your line chart should now be comprised of 4 rows, each of which is its own line chart for a specific product category.

     ![](images/200/img_2e_2_3.png " ")

    >Now, this is interesting!

    >We knew overall revenues were trending upward and that certainly seems true for the Books & Audible and Movies & Music categories. However, Clothing & Shoes seems to have remained flat and Electronics & Computers is actually trending down! Electronics & Computers makes up a good portion of our overall revenues too, so we should really take a closer look at all of this.

    >We should talk with our team, but what is the best way to share this information?

### f) Narrating a Story with Visualizations and Insights

1. Add an Insight to your project.

    Click on **Narrate** in the **Project Tabs** in the top right of the screen.

     ![](images/200/img_2f_1_1.png " ")

     You will see the following screen:

     ![](images/200/img_2f_1_2.png " ")

2. Create a narration for your Insight.

    Click on the hamburger icon and select **Add To Story**.

    ![](images/200/img_2f_2_1.png " ")

    You should see the ability to add information into a text box at the top of the screen. Click into the **Description** text box and type in **Clothing & Electronics are not following the overall sales trend**. Click anywhere outside the box.

    ![](images/200/img_2f_2_2.png " ")

    Let’s also give the **Insight** tab a meaningful name. Double-click the Title Box (currently labeled "Canvas 1") and type **Clothing & Electronics**.

    ![](images/200/img_2f_2_3.png " ")

    The **Insight** is now ready to be shared, which we will cover later on. Let’s make sure to save our work at this point.

3. Save your project.

    Select the **Save** button from the **Project Menu** in the top right of the screen. Select **Save As** in the pop-up menu.

    ![](images/200/img_2f_3_1.png " ")

    Type in KoolKart Sales as the Name and click **Save**.

    ![](images/200/img_2f_3_2.png " ")

Congratulations! You have now successfully created compelling visualizations with DV. Proceed onto the next labs to learn about and try out even more robust features!

### g) Modifying Properties in the Data Panel

Now, let's go over the data panel in the bottom left of the UI for accessing properties. You will find yourself using them in the upcoming labs, so now is a good time to visit them.

![](images/200/img_2g_1.png " ")

This section will cover the functions of each of these options.

![](images/200/img_2g_2.png " ")

![](images/200/img_2g_3.png " ")

>![](images/200/img_2g_4.png " ") **General**: Allows you to edit the title, visualization type, and line type.

>![](images/200/img_2g_5.png " ") **Edge Labels**: Allows you to edit labels within your visualizations such as Trellis Rows or Trellis Columns.

>![](images/200/img_2g_6.png " ") **Axis**: Allows you to adjust the labels for different axes on your visualization. This includes the labels axis, values axis, and secondary values axis.

>![](images/200/img_2g_7.png " ") **Values**: Allows you to adjust the measures you have included in your data set. This includes the aggregation method, number format, and Y2 axis (if it applies).

>![](images/200/img_2g_8.png " ") **Date/Time Format**: Allows you to adjust how date/time column data is shown in your visualizations.

>![](images/200/img_2g_9.png " ") **Analytics**: Allows you to add different analytics options to your visualization. This includes Clusters, Outliers, Reference Lines, and Forecasts.

{'repo_name': 'oracle/learning-library', 'stars': '430', 'repo_language': 'PLSQL', 'file_name': 'dp_to_adb_intro.md', 'mime_type': 'text/html', 'hash': 979627357181862560, 'source_dataset': 'data'}


Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements.  See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

The following files are provided under the Apache License, Version 2.0:

  src/main/resources/examples/jamaica.txt
  src/main/resources/examples/default.txt
  src/main/resources/examples/LIST.txt

{'repo_name': 'apache/stanbol', 'stars': '115', 'repo_language': 'Java', 'file_name': 'stanbol_network.owl', 'mime_type': 'text/xml', 'hash': -372925748094438101, 'source_dataset': 'data'}