Scania Sans
The typeface that we use in our internal och external communication is called Scania Sans. The typeface comes in a few cuts; Regular, Bold, Italic, Headline, Headline Bold as well as Condensed, Condensed Bold and a Condensed Italic version. The typeface is an important part of how we communicate the Scania brand.
| Scania Sans Regular | |
| Scania Sans Bold | |
| Scania Sans Italic | |
| Scania Sans Headline | |
| Scania Sans Headline Bold | |
| Scania Sans Condensed | |
| Scania Sans Condensed Bold | |
| Scania Sans Condensed Italic |
Public Headers
Public headers are used on sites where we communicate with users outside of the Scania Network, for example fleet owners, potential new customers and journalists. Basically, the public headers are stronger and bolder than what we use for internal applications. They are most often written in uppercase and the headers should be short, yet still descriptive. Most headers for external use are center aligned.
Header 1 |
Your text |
Header 2 |
Your text |
Header 3 |
Your text |
Header 4 |
Your text |
Header 5 |
Your text |
Header 6 |
Your text |
Article Headers
Headers within the HTML article element should be used for traditionall documents like reports and news articles. The headers are smaller than our other headers to balance better with a smaller bread text. Basically, they are styled for high readability and to work good in print.
Header 1 |
Your text |
Header 2 |
Your text |
Header 3 |
Your text |
Header 4 |
Your text |
Header 5 |
Your text |
Header 6 |
Your text |
Application Headers
We use the headers slightly differently when it comes to external and internal communication. Below you'll find basic styles and corresponding HTML tags to be used to achive the correct header.
Header 1 |
Your text |
Header 2 |
Your text |
Header 3 |
Your text |
Header 4 |
Your text |
Header 5 |
Your text |
Header 6 |
Your text |
Stylesheets
The Scania Sans stylesheet should be linked into your application using the tag above. This ensures us that every user of the font has the latest version of it.
Cyrillic Fonts
All Scania Sans fonts are available in cyrillic versions. They are included in the Corporate UI setup. If needed for applications on a stand alone basis, then include the CSS mentioned above and the cyrillic fonts will be loaded when needed.
| Scania Sans Regular | Лорем ипсум долор сит амет |
| Scania Sans Bold | еу ерат дефиниебас про |
| Scania Sans Italic | еу ерат дефиниебас про |
| Scania Sans Headline | Яуи иусто омниум но |
| Scania Sans Headline Bold | ин денияуе репримияуе пер |
| Scania Sans Condensed | ид ест сонет малорум легимус |
| Scania Sans Condensed Bold | Ат мутат епицури перципитур дуо |
| Scania Sans Condensed Italic | ан сеа епицури пертинациа |


public class TextMenu
extends Activity
| Modifier and Type | Field and Description |
|---|---|
private java.lang.String |
cardId
The UUID of the audio card which is serving as the source for this textviewer activity.
|
private int |
cardPos
The position of the card within the cardscroll view from which the user
launched this audioplayer activity.
|
static boolean |
DEFAULT_NARR
The Constant DEFAULT_NARR.
|
private static int |
DEFAULT_POS
The Constant DEFAULT_POS.
|
static int |
DEFAULT_TEXT_POS
The Constant DEFAULT_TEXT_POS.
|
static java.lang.String |
EXTRA_LAST_TEXT_POS
The Constant EXTRA_LAST_TEXT_POS.
|
static java.lang.String |
EXTRA_NARRATION_REQUESTED
The Constant EXTRA_REQUESTED_NARRATION.
|
static java.lang.String |
EXTRA_SELECTED_ID
The Constant EXTRA_SELECTED_ID.
|
static java.lang.String |
EXTRA_SELECTED_POS
The Constant EXTRA_SELECTED_POS.
|
private boolean |
isNarrating
Boolean flag to indicate if the user has selected a narration at the options menu.
|
private int |
lastPos
The last pos selected before the user launched a menu.
|
private AudioManager |
mAudioManager
The audio manager used to provide audio feedback to the user in response
to user actions.
|
static java.lang.String |
TAG
The Constant TAG.
|
| Constructor and Description |
|---|
TextMenu() |
| Modifier and Type | Method and Description |
|---|---|
static void |
closeTextViewer(Context context)
Broadcasts an intent to close the textviewer activity quickly so that the user may return directly to the selectcardactivty directly from the menu activity
|
void |
onAttachedToWindow() |
boolean |
onCreateOptionsMenu(Menu menu) |
boolean |
onOptionsItemSelected(MenuItem item) |
void |
onOptionsMenuClosed(Menu menu) |
public static final java.lang.String TAG
public static final java.lang.String EXTRA_SELECTED_POS
SelectCardActivity
so that when the user returns to it, the card
they just tapped on is in focus.public static final java.lang.String EXTRA_SELECTED_ID
public static final java.lang.String EXTRA_LAST_TEXT_POS
public static final java.lang.String EXTRA_NARRATION_REQUESTED
public static final int DEFAULT_TEXT_POS
private static final int DEFAULT_POS
SelectCardActivity
cannot be obtained from the intent.public static final boolean DEFAULT_NARR
private int lastPos
private int cardPos
private java.lang.String cardId
private boolean isNarrating
private AudioManager mAudioManager
public void onAttachedToWindow()
public boolean onCreateOptionsMenu(Menu menu)
public boolean onOptionsItemSelected(MenuItem item)
public static void closeTextViewer(Context context)
context
- The activty's context, used to send a broadcast.public void onOptionsMenuClosed(Menu menu)


--- layout: post title: Character Design samples date: '2018-01-10T11:30:33+01:00' categories: - Character - Illustration picture_url: https://film-Storyboards.tumblr.com/post/169546942266/character-design-samples ---
Character design samples


--- permalink: nhl-hometowns ---
While hockey is stereotypically thought of as a sport played by Canadians, in reality players in the NHL come from all over the northern hemisphere. This visualization will let you explore the birth cities of NHL players individually, by team, or by city. It includes every NHL player to have played in at least one game of the 2017-18 season, as of 2018-05-26.
This map is meant to be used as a companion to my blog post about this data, found *here*.
The icons to the left allow you to search and filter the map by player, team, or city, respectively. More instructions can be found in each individual tab, with credits and more info in the tab at the very bottom of the sidebar.
Birth city data was taken from the excellent Hockey Reference site, and the city name was geocoded against the Geonames API to get the city's coordinates. I performed a little cleanup on the data by hand, as there were a few weird outliers that were very obviously wrong. The Geonames API has a tendency to choose a municipal airport for some cities / towns which led to some other weirdness; for example, Sidney Crosby's birth town of Cole Harbor was geocoded to the local airport. I didn't make as much of an effort to clean these up, as by and large they're rather close to where they should be. You'll surely find some other things if you explore the data closely enough. You can find the code I used to perform the data processing on Github.
Click on a player's name to zoom to their city of birth, or start typing a player's name or a team in the search bar to filter the list.
Click on a team to show only its players, or start typing a team name to filter the list.
Click on a city name to zoom to that city and see all players from the selected city. Or, use the search to filter by city name or country ISO-3 code.
First and foremost, thanks to Leaflet for creating an amazing free & open source mapping library.
This page uses Leaflet-sidebar-v2 for the slick sidebar you're reading this in, and list.js for the easily searchable player, team and city lists. Many thanks to the creators of those libraries, doing a bunch of work that I didn't have to.
I had never heard of or used the Geonames API before this project, and without their free city geocoding API, this project would have been over before it started. I highly recommend using & contributing to their service.
Finally, thanks to Hockey-Reference for maintaining one of the most comprehensive NHL stats sites on the web, and making that data freely available to all.


Pre 0.5.0 Release History¶
0.5.0¶
Main Changes and Additions * Add patsy dependency
Compatibility and Deprecation
cleanup of import paths (lowess)
Bug Fixes
input shapes of tools.isestimable
Enhancements and Additions
formula integration based on patsy (new dependency)
Time series analysis - ARIMA modeling - enhanced forecasting based on pandas datetime handling
expanded margins for discrete models
OLS outlier test
empirical likelihood - Google Summer of Code 2012 project - inference for descriptive statistics - inference for regression models - accelerated failure time models
expanded probability plots
improved graphics - plotcorr - acf and pacf
new datasets
new and improved tools - numdiff numerical differentiation
0.4.3¶
The only change compared to 0.4.2 is for compatibility with python 3.2.3 (changed behavior of 2to3)
0.4.2¶
This is a bug-fix release, that affects mainly Big-Endian machines.
Bug Fixes
discrete_model.MNLogit fix summary method
tsa.filters.hp_filter do not use umfpack on Big-Endian machine (scipy bug)
the remaining fixes are in the test suite, either precision problems on some machines or incorrect testing on Big-Endian machines.
0.4.1¶
This is a backwards compatible (according to our test suite) release with bug fixes and code cleanup.
Bug Fixes
build and distribution fixes
lowess correct distance calculation
genmod correction CDFlink derivative
adfuller _autolag correct calculation of optimal lag
het_arch, het_lm : fix autolag and store options
GLSAR: incorrect whitening for lag>1
Other Changes
add lowess and other functions to api and documentation
rename lowess module (old import path will be removed at next release)
new robust sandwich covariance estimators, moved out of sandbox
compatibility with pandas 0.8
new plots in statsmodels.graphics - ABLine plot - interaction plot
0.4.0¶
Main Changes and Additions
Added pandas dependency.
Cython source is built automatically if cython and compiler are present
Support use of dates in timeseries models
Improved plots - Violin plots - Bean Plots - QQ Plots
Added lowess function
Support for pandas Series and DataFrame objects. Results instances return pandas objects if the models are fit using pandas objects.
Full Python 3 compatibility
Fix bugs in genfromdta. Convert Stata .dta format to structured array preserving all types. Conversion is much faster now.
Improved documentation
Models and results are pickleable via save/load, optionally saving the model data.
Kernel Density Estimation now uses Cython and is considerably faster.
Diagnostics for outlier and influence statistics in OLS
Added El Nino Sea Surface Temperatures dataset
Numerous bug fixes
Internal code refactoring
Improved documentation including examples as part of HTML
Changes that break backwards compatibility
Deprecated scikits namespace. The recommended import is now:
import statsmodels.api as sm
model.predict methods signature is now (params, exog, …) where before it assumed that the model had been fit and omitted the params argument.
For consistency with other multi-equation models, the parameters of MNLogit are now transposed.
tools.tools.ECDF -> distributions.ECDF
tools.tools.monotone_fn_inverter -> distributions.monotone_fn_inverter
tools.tools.StepFunction -> distributions.StepFunction
0.3.1¶
Removed academic-only WFS dataset.
Fix easy_install issue on Windows.
0.3.0¶
Changes that break backwards compatibility
Added api.py for importing. So the new convention for importing is:
import statsmodels.api as sm
Importing from modules directly now avoids unnecessary imports and increases the import speed if a library or user only needs specific functions.
sandbox/output.py -> iolib/table.py
lib/io.py -> iolib/foreign.py (Now contains Stata .dta format reader)
family -> families
families.links.inverse -> families.links.inverse_power
Datasets’ Load class is now load function.
regression.py -> regression/linear_model.py
discretemod.py -> discrete/discrete_model.py
rlm.py -> robust/robust_linear_model.py
glm.py -> genmod/generalized_linear_model.py
model.py -> base/model.py
t() method -> tvalues attribute (t() still exists but raises a warning)
Main changes and additions
Numerous bugfixes.
Time Series Analysis model (tsa)
Vector Autoregression Models VAR (tsa.VAR)
Autoregressive Models AR (tsa.AR)
Autoregressive Moving Average Models ARMA (tsa.ARMA) optionally uses Cython for Kalman Filtering use setup.py install with option –with-cython
Baxter-King band-pass filter (tsa.filters.bkfilter)
Hodrick-Prescott filter (tsa.filters.hpfilter)
Christiano-Fitzgerald filter (tsa.filters.cffilter)
Improved maximum likelihood framework uses all available scipy.optimize solvers
Refactor of the datasets sub-package.
Added more datasets for examples.
Removed RPy dependency for running the test suite.
Refactored the test suite.
Refactored codebase/directory structure.
Support for offset and exposure in GLM.
Removed data_weights argument to GLM.fit for Binomial models.
New statistical tests, especially diagnostic and specification tests
Multiple test correction
General Method of Moment framework in sandbox
Improved documentation
and other additions
0.2.0¶
Main changes
renames for more consistency RLM.fitted_values -> RLM.fittedvalues GLMResults.resid_dev -> GLMResults.resid_deviance
GLMResults, RegressionResults: lazy calculations, convert attributes to properties with _cache
fix tests to run without rpy
expanded examples in examples directory
add PyDTA to lib.io – functions for reading Stata .dta binary files and converting them to numpy arrays
made tools.categorical much more robust
add_constant now takes a prepend argument
fix GLS to work with only a one column design
New
add four new datasets
A dataset from the American National Election Studies (1996)
Grunfeld (1950) investment data
Spector and Mazzeo (1980) program effectiveness data
A US macroeconomic dataset
add four new Maximum Likelihood Estimators for models with a discrete dependent variables with examples
Logit
Probit
MNLogit (multinomial logit)
Poisson
Sandbox
add qqplot in sandbox.graphics
add sandbox.tsa (time series analysis) and sandbox.regression (anova)
add principal component analysis in sandbox.tools
add Seemingly Unrelated Regression (SUR) and Two-Stage Least Squares for systems of equations in sandbox.sysreg.Sem2SLS
add restricted least squares (RLS)
0.1.0b1¶
initial release


Team members
Jakub Zmarzly, Brandon Peck, Ethan Maynes, Colin Mcay
Project Overview
I would like to make a website about my cousins restaurant similar to other websites providing a menu and other categories
Technology Overview
Im probably gonna be using W3 to help me inhance my website or guide me to better it. I probably might use other websites that give me information on how to do certain things I want for the website.
The Proposal last updated was tuesday the secound of November
Features list
Well I want to make the website interactive like being able to see different categories under the menu bar just by hovering over it.
I want to put some imagies of the food in the background of the webpage or have some imagies of their food.
Im gonna give a breif summary on the front of the page about the restaurant and in the bottom I wanna include the socials of the restaurant and maybe video from youtube about their food
I kinda just want to make it look like any regulor restaurant website like villa rosa for example
Future Feature list
I probably would like to add some animated features to make it look more interesting
Basic Techinical Features
Heading
writing paragraph
uploading imagies to website
Advanced Technical Feature
The one advanced feature would be being able to click on menu and seeing the different options to view and clicking on the one you want sending you to different categories


This chapter describes interactions with the Socket library, used for managing communications between threads -- threads on different machines or two GEOS threads on the same machine (via the "loopback" communication domain). It provides an API which is mostly independent of the medium used for inter-machine communication.
It is common to spawn a separate thread to poll a socket for incoming data; See the Multithreading chapter to learn about managing threads. Sample applications are located in APPL\SDK_C\MultThrd. Some socket operations require knowledge of the communications network used.
1 Introduction
2 Simple Example
3 Addresses
3.1 Letting the User Choose an Address
3.2 Managing Addresses
3.3 Hardware Ports
4 Making a Connection
5 Accepting a Connection
6 Loading on Connection
7 Sending and Receiving Data
7.1 Urgent Data
7.2 SocketSend() and SocketRecv()
7.3 Options
8 Closing the Connection
9 Checking the Connection
10 Domain-Specific Information
10.1 TCP/IP--GEOS Specific
10.2 TCP/IP--Standard
10.3 Loopback
The Socket library manages communications both between machines and between threads on the same machine. It provides a level of abstraction above individual communication protocols ( e.g. , IrLMP, TCP/IP). Programs using the Socket library can send and receive information packets without knowing much about the communications protocol by which those packets are being transmitted. Also, programs using the Socket library need not know about the hardware communication ports used -- whether communication is being carried out over an IR serial port, a modem, or a network connection -- the API is the same.
The Socket library supports different "delivery types"-- different levels of reliability in transmitting data. There is a trade-off: the more reliable delivery types require more set-up work by the programs using them. The following delivery types are available:
Each side of the connection is represented by an address. An address is made up of several parts:
The amount of overhead associated with sending and receiving data depends upon the devices involved, the domain, and the delivery type. When testing, experiment with different domains (if available), delivery types, and packet sizes to find a good balance of reliability and rapidity.
For any domain, there may be more than one address format. For instance, the TCP/IP address "geoworks.com" is conveniently human-readable, but cannot be used at the socket level to actually make a connection. Instead, you must resolve "geoworks.com" to a 32-bit address number. All socket operations require "primitive" addresses -- addresses resolved to their simplest form. To resolve an address, call
SocketResolve()
. We will discuss the details of working with addresses in more detail below.
Many of the Socket library routines return error values. Sometimes these error values are return values of routines; if you call a routine that can return an error value, be sure to check the return value and react appropriately to errors. Some routines don't return an error value directly, instead returning a flag to indicate that something has gone wrong. To find out exactly what went wrong, call
ThreadGetError()
.
Those Socket library routines that return error values do not set the thread error value. Calling
ThreadGetError()
after calling such a routine would not detect any error encountered by that routine.
ThreadGetError()
returns a word-sized value. The low byte of this word is a
SocketError
value; the high byte is a
SpecSocketDrError
value. If the returned word is zero, that means that there was no error.
In general, a
SpecSocketDrError
value indicates a low-level error, and a
SocketError
value indicates a high-level error. In many cases, there will be a
SocketError
in the low byte, but the high byte will be clear -- there was no problem with the low-level communication medium, but a protocol exception may have occurred.
In general, only the low byte (the
SocketError
value) is useful in determining how to handle the exception. The high byte might affect what error message is displayed to the user. For example, it probably doesn't matter to your program whether the high byte was SSDE_LINE_BUSY or SSDE_NO_DIALTONE. In either case, it just means that communication could not be established. However, users might want to know the nature of the problem so that they can figure out how fix it.
Some of the more common
SocketError
values are listed below. In addition, certain routines may make use of other
SocketError
values, which will be discussed with those routines.
SocketCheckMediumConnection()
to see if the port is being used for a socket connection.
SocketBind()
.
SocketListen()
.
SocketConnect()
.
SocketClose()
.
SocketCloseDomainMedium()
or the Socket's owning thread exiting.
ManufacturerID
of your port number.
SocketInterrupt()
.The sample application Appl/SDK_C/Talk provides an example of a simple application using the Socket library.
To understand how the program works, you should, of course, look at its source code. The following is a high-level overview of what the Talk example illustrates: a simple client-server connection in which the server awaits connections, the client connects, and then the two exchange data. Note: this application assumes that the host device (the client) has already connected to the server. Remote connections are usually made through PPP or Point-to-Point Protocol. See
SocketOpenDomainMedium()
discussed in Hardware Ports
.
The example performs the following steps:
SocketSetIntSocketOption()
to change its owning thread.)char recvBuf[16];
AccessPointControl
object prompts the user to choose an ISP, and a call to
SocketOpenDomainMedium()
opens a PPP connection to that ISP.
SocketGetAddressController()
returns the controller class' pointer;
ObjInstantiate()
creates an object of the class.ctrlClass = SocketGetAddressController(theAddress.SA_domain));
ctrlOb = ObjInstantiate( HandleOf(GeodeGetOptrNS(@AddressDialog)), ctrlClass);
@call ctrlOb::MSG_SOCKET_ADDRESS_CONTROL_SET_ACTION( ConstructOptr(0,TO_PROCESS), MSG_CTP_VALID);
@call GeodeGetOptrNS(@AddressDialog)::MSG_GEN_ADD_CHILD( ctrlOb, CCO_FIRST);
@call ctrlOb::MSG_GEN_SET_USABLE(VUM_NOW);
When the user enters an address, the following code is called. It gets the selected address from the address controller and packages it up into a form the Socket library can use.
MSG_SOCKET_ADDRESS_CONTROL_GET_ADDRESSES
returns a chunk with raw address data based on the address entered by the user.
SocketResolve()
reduces this raw address data to a primitive form that can be used for making connections.
adArray = @call ctrlOb::MSG_SOCKET_ADDRESS_CONTROL_GET_ADDRESSES();
address1 = ChunkArrayElementToPtrHandles( HandleOf(ctrlOb), adArray, 0,0);
theAddress.SA_addressSize = SocketResolve( theAddress.SA_domain, (byte *)&address1[1], address1->SACA_opaqueSize, addressBuffer, MAX_ADDRESS_SIZE);
LMemFreeHandles(HandleOf(ctrlOb), adArray);
dataSocket = SocketCreate(SDT_STREAM);
SocketConnect( dataSocket, (SocketAddress *) &theAddress, SOCKET_NO_TIMEOUT);
There are two "sockets" created on this, the server side of the connection. The first socket is bound to a particular port, and "listens" for incoming connections. It is possible to accept more than one connection over the listening socket--each accepted connection is represented by another socket to represent this side of the new particular connection.
listenSocket = SocketCreate(SDT_STREAM);
SocketBind(listenSocket, theAddress.SA_port, 0);
SocketListen(listenSocket, 5);
dataSocket = SocketAccept( listenSocket, SOCKET_NO_TIMEOUT);
textBlock = @call GeodeGetOptrNS(@InText):: MSG_VIS_TEXT_GET_ALL_BLOCK(NullHandle);
textPtr = MemLock(textBlock);
textSize = LocalStringSize(textPtr);
SocketSend( dataSocket, textPtr, textSize, 0, (SocketAddress *)0);
MemFree(textBlock);
while (( datasize = SocketRecv( dataSocket, recvBuf, sizeof recvBuf, SOCKET_NO_TIMEOUT, 0, (SocketAddress *)0)) != 0)
{ @call GeodeGetOptrNS(@OutText)::MSG_VIS_TEXT_APPEND_PTR( recvBuf, datasize); }
SocketCloseSend()
routine partially shuts down the socket so that it can receive data, but cannot send it; also, the routine sends a signal to the other side that the connection is closing.if (listenSocket) { SocketClose(listenSocket); listenSocket = 0; }
SocketCloseSend(dataSocket);
SocketRecv()
detects an error, it sets the thread error value, which may be retrieved via
ThreadGetError()
.) If the connection has closed, then Talk closes the sockets on this side of the connection.if (ThreadGetError() == SE_CONNECTION_CLOSED) { if (listenSocket) { SocketClose(listenSocket); listenSocket = 0; } SocketClose(dataSocket); }
In the example above, the application queried the user for a connection address. This is a fairly common case. However, some programs need to use hard-wired addresses. Perhaps you want to allow connections over all available domains. Thus, a few words about addresses may be in order.
Addresses are usually represented via the
SocketAddress
structure:
typedef struct { SocketPort SA_port; word SA_domainSize; char * SA_domain; word SA_addressSize; } SocketAddress; /* domain-specific address data here */
SocketPort
structure, made up of a 16-bit
ManufacturerID
and 16-bit arbitrarily-chosen token number. If the domain uses 16-bit socket numbers, then use MANUFACTURER_ID_SOCKET_16BIT_PORT
as the
ManufacturerID
. If the domain allows 32-bit socket numbers, then you may use MANUFACTURER_ID_SOCKET_16BIT_PORT or some other
ManufacturerID
, probably your own ID or that of some standard service provider. This numbering scheme helps to avoid overlapping port numbers.
SocketAddress
structure,
SA_domain
is a pointer to the null-terminated domain name string and
SA_domainSize
is the size of the buffer containing the domain name string.
SocketGetDomain().
(See Letting the User Choose an Address
.)
SA_addressSize
field of the
SocketAddress
structure contains the size of the address data. The buffer containing the address data should fall immediately after the
SocketAddress
structure. Read the documentation for a given domain to find out the format for its addresses.
SocketAddress
, that has the fields of
SocketAddress
, but also has a buffer to hold the resolved address data. More likely than not, you won't need to declare or define such a structure -- you're more likely to use
SocketCreateResolvedAddress()
or bypass the creation of this structure altogether.
Before using an address, make sure that it is in its primitive form. For instance, an IP address like "geoworks.com" is not in its primitive form -- the IP address must be translated into a four-byte number before it can be used. Use
SocketResolve()
(described below) to transform an address into its primitive form. Note that the address passed to
SocketResolve()
is not in a
SocketAddress
structure.
Letting the User Choose an Address
SocketAddressControllerClass, SocketGetDomains(), SocketGetAddressController(), SocketCreateResolvedAddress(), SocketResolve(), SocketInterruptResolve()
Given a domain, you can request the Socket library to provide UI gadgetry so that the user can choose an address within that domain. Many programs only support socket connections over one domain. However, if you need a list of all domains supported in the user's environment, call
SocketGetDomains()
.
The
SocketGetDomains()
routine takes the optr of a chunk array and fills in that array with elements. Each element contains a (non-null-terminated) string which is the name of a supported domain. This chunk array has a standard
ChunkArrayHeader
header and variable-sized elements.
If you want the routine to allocate the chunk array for you, pass an optr that contains a NullChunk ( i.e. , a null ChunkHandle):
MemHandle myHandle;
Optr myOptr;
myHandle = OptrToHandle(myHandle);
myOptr = ConstructOptr(myHandle, NULL);
For more information about working with chunk arrays, see the Local Memory chapter. In short, to manage the chunk array of domain names:
MemLock()
.
LMemDerefHandles()
to get a pointer to the chunk array.
ChunkArrayGetCount()
.
ChunkArrayElementToPtr()
or
ChunkArrayElementToPtrHandles()
.
MemUnlock()
on the local memory heap.
Given a domain name, you can create some UI gadgetry for choosing addresses within that domain. As shown in the Appl/SDK_C/Talk example, call
SocketGetAddressController()
to get the class of an appropriate controller. This class is guaranteed to support the messages shown in SocketAddressControllerClass
.
Code Display 23-1 SocketAddressControllerClass
/* Domain-specific subclasses of SocketAddressControllerClass all support * the following messages. MSG_SOCKET_ADDRESS_CONTROL_GET_ADDRESSES is probably * the most commonly used message. */
/* * Build the block of data that holds the addresses selected by the user * to pass to the transport driver. If OK, returns ChunkArray of SACAddress * structures in same block as controller. Else, returns 0.
* As of this writing, all address controllers return at most one address * in the list of addresses.
* The returned address(es) are not in its primitive form; use * SocketResolve() to transform the address into something usable. */ @message word MSG_SOCKET_ADDRESS_CONTROL_GET_ADDRESSES();
typedef struct { word SACA_opaqueSize; /* label byte SACA_opaque; Pass this to SocketResolve */ /* after the opaque address, there is a null-terminated * human-readable form of the address. */ } SACAddress;
/* * Inform the subclass of the type of medium selected by the user * so it can customize its appearance appropriately, should the controller * handle media that have different ways of addressing. */ @message void MSG_SOCKET_ADDRESS_CONTROL_SET_MEDIUM ( MediumType mediumType);
/* * Set the current user-editable address to the passed address. */ @message void MSG_SOCKET_ADDRESS_CONTROL_SET_ADDRESSES(optr addr);
/* * Inform the controller of the message and destination object it should use to * notify the invoker that a valid address exists. */ @message void MSG_SOCKET_ADDRESS_CONTROL_SET_ACTION ( optr dest, word actionMsg);
/* * Let the containing dialog know whether the address we've got is a * valid one, so it can decide whether to allow the user to send the * message. */ @message void MSG_SOCKET_ADDRESS_CONTROL_SET_VALID_STATE(Boolean valid);
You cannot use an address with Socket library routines unless that address is in its primitive form. This primitive form is created by taking a higher-level form of the address and passing it to the
SocketCreateResolvedAddress()
routine or the
SocketResolve()
routine. Exactly how the Socket library resolves the address depends upon the domain.
Recall that addresses returned by the address controller are not in their primitive form. The primitive form of an address can be volatile: feel free to re-use them if making several connections over a short period of time, but re-resolve the address if it's been a long time since it was last resolved. Note that there can be a large overhead when it comes to resolving addresses. Also note that IRLAP numeric addresses are especially volatile, changing every time the protocol connection starts, i.e., every time the IRLAP driver is loaded, either for the first time or after more than a minute of inactivity.
The
SocketCreateResolvedAddress()
routine takes a pointer to a domain name and raw address data and returns a buffer with a
SocketAddress
structure and the address data. Depending on what you're going to use the address for, you may need to fill in the structure's
SA_port
field.
SocketResolve()
is the same as
SocketCreateResolvedAddress()
except that
SocketResolve()
takes a buffer to hold the resolved address data. If the buffer isn't big enough,
SocketResolve()
returns SE_BUFFER_TOO_SMALL. Depending on the domain, calling
SocketResolve()
on an address already in its primitive form may have undesired results.
The resolution process may or may not require network access, depending on the domain and the input format. Depending on the domain, the addressing system may be volatile. Under these conditions, put off resolving the address as long as possible, until just before using the address; there will be less time for the address to go bad. If the network goes down, the Socket library might not be able to resolve addresses. In this case,
SocketCreateResolvedAddress()
or
SocketResolve()
returns SE_TEMPORARY_ERROR.
If you wish to interrupt the resolution process (perhaps you allow the user to cancel the operation), use the
SocketInterruptResolve()
function. This function attempts to halt the resolution process. It is, however, unreliable. It may not succeed in interrupting the resolution process; it may also interrupt other resolves happening at the same time.
SocketGetAddressSize(), SocketGetSocketName(), SocketGetPeerName()
Most programs blindly use addresses supplied by the user or use only hard-wired addresses. Only a few programs need to access and manipulate addresses. The Socket library provides a few utility routines for this purpose.
To find out the maximum address data size for a given domain, call
SocketGetAddressSize()
. This can be helpful when allocating memory to handle a full address, such as that returned by the
SocketGetSocketName()
and
SocketGetPeerName()
functions.
If a socket is connected, call
SocketGetPeerName()
to get the address of the socket at the other end of the connection. To find out the address used to represent the socket's own side of the connection, call
SocketGetSocketName()
.
SocketGetDomainMedia(), SocketGetAddressMedium(), SocketCheckMediumConnection(), SocketGetMediumAddress(), SocketOpenDomainMedium(), SocketCloseDomainMedium()
Most socket connections involve the use of some hardware "port" -- some physical connection to the outside world. To determine which sort of hardware ports the user's machine uses to connect to a given domain, call
SocketGetDomainMedia()
. This returns a chunk array of
MediumType
structures. Given a choice of domains to make a given connection, consider which medium would be used to make the connection.
To find out which port the Socket library would use to connect to a given address, call
SocketGetAddressMedium()
. Depending on the medium, you might try to connect to the other site via some other domain or decide not to make the connection at all.
To check a given hardware port is being used for an active connection, call
SocketCheckMediumConnection()
. If a point-to-point connection exists, this routine returns the address of the remote site. If there is a connection, but not a specific address, then the routine returns a null address. If there is no connection through the hardware port, the routine returns a
SocketError
value.
To find out the address of the local machine on a connection over a particular medium, use the
SocketGetMediumAddress()
routine. This is the address another machine would use to connect to this machine via that medium.
The
SocketOpenDomainMedium()
routine opens a "raw" connection using the specified medium. Exactly what is meant by a "raw" connection depends upon the domain involved. In the case of TCP, this routine will dial the modem and create a PPP connection to the PPP server but will not send any TCP packets.
It is possible to "hang up" a hardware port. Call
SocketCloseDomainMedium()
to force a domain to close a medium. You may request that the medium only be closed if it is not being used (
i.e.
, there are no active connections using the medium). If any socket connections are using the port, they will receive the error SE_CONNECTION_RESET. Later, we will discuss orderly ways to close a connection, being careful to send proper notification to the other side of the connection.
SocketCreate(), SocketConnect(), SocketInterrupt()
To make a connection, a program creates a socket and specifies an address to which to connect that socket.
To create a new socket, call
SocketCreate()
. You must specify the socket's delivery type: datagram, sequential packet, or stream.
Before sending or receiving data over a sequential packet or stream socket, you must "connect" it to the place it will be sending the data to or receiving it from.
Depending on the medium and device, you may need to make sure that the device is connected to a network. For example, for a Nokia 9000i Communicator to make a TCP/IP connection, it must first have made a PPP connection. Use the
SocketOpenDomainMedium()
routine to make the "raw" network connection.
To make a connection, call
SocketConnect()
. Pass the socket created via
SocketCreate()
, the address to connect to, and a time-out value. If it returns SE_NORMAL, then the connection was established successfully. If it returns SE_CONNECTION_REFUSED, the remote site wasn't prepared to accept the connection. If it returns SE_CONNECTION_ERROR, the connection didn't go through for some miscellaneous reason. If it returns SE_NON_UNIQUE_CONNECTION, then the attempted connection would have been identical to another connection: same source address, source port, destination address, destination port, and delivery type. There would be no way to tell these connections apart. If you try to open the same connection from both sides simultaneously, they may both fail with SE_NON_UNIQUE_CONNECTION.
To cancel the connection operation, call
SocketInterrupt()
.
Datagram sockets cannot form a true connection -- they are unreliable. Sockets must be able to send and receive datagram packets without relying on a permanent connection. However, using
SocketConnect()
with a datagram socket specifies a default destination address to use when sending packets.
SocketBind(), SocketBindInDomain(), SocketListen(), SocketAccept()
There's a bit of work involved in setting up a program to receive connections from other sockets. The program must create a socket and associate it with a port. If there is to be a sequenced-packet or stream delivery connection, then the program needs to do some more work to listen for and accept these connections.
If a program creates a socket that accepts connections, the program should probably spawn a separate thread for each accepted connection. If this is not practical, then see
SocketCheckReady()
for a way to monitor several sockets with a single thread.
Call
SocketCreate()
to create a socket for this side of the connection. If the socket is to receive datagram packets, then it must be of type datagram. If the other socket in the connection will be a sequenced packet or stream delivery type, then the socket accepting the connection must be either sequenced packet or stream delivery type; however, the two sockets need not be of the same type.
(If you follow the multi-threaded approach, be aware that when the Socket's owning thread exits, it frees the Socket. To allow a Socket to survive the exit of its thread, use
SocketSetIntSocketOption()
to change its owning thread.)
The other side of the connection attempts to hook up to a port number on this side of the connection. If a socket is to intercept connections to a certain port, it must somehow associate itself with that port. Use the
SocketBind()
or
SocketBindInDomain()
routines to associate a socket with a port number.
SocketBind()
associates the socket with a port number.
SocketBindInDomain()
associates the socket with a port number but only within a specific domain.
For any given domain, normally only one socket on the machine may be bound to any port number. Thus, if you call
SocketBindInDomain()
to bind socket A to port 3 in the TCP/IP domain, then:
SocketBindInDomain()
to bind socket B to port 3 in the IRLAP domain, but
SocketBindInDomain()
to bind socket C to port 3 in the TCP/IP domain, and
SocketBind()
to bind socket D to port 3.There are some ways around this restriction:
SocketBind()
or
SocketBindInDomain()
to re-use some port that another socket has bound, then pass the SBF_REUSE_PORT flag. Otherwise, be prepared to receive SE_PORT_IN_USE or SE_BIND_CONFLICT. Even the SBF_REUSE_PORT flag won't allow you to use both
SocketBind()
and
SocketBindInDomain()
on a single port. E.g., in the example above, you could use
SocketBindInDomain()
with SBF_REUSE_PORT to bind socket C to port 3 in the TCP/IP domain, but you could not use
SocketBind()
with SBF_REUSE_PORT to bind socket D to port 3. You may not use SBF_REUSE_PORT with datagram-based sockets.Always check for bind conflicts. Bind conflicts may occur even though a program is well-behaved: other programs may have bound ports to a socket. For reasons described in Loading on Connection , sometimes the Socket library itself may monitor a port.
When setting up a sequenced packet or stream delivery connection, a bit more set-up work is necessary. These delivery types require a "connection."
To listen for incoming sequenced packet or stream connections, call
SocketListen()
. The socket must be bound to a port before it can listen. To allow more than one connection through the port, specify the maximum number of connections as an argument to
SocketListen()
. The
SocketListen()
routine causes a socket to listen for incoming connections. If another socket is listening at the port,
SocketListen()
returns SE_PORT_ALREADY_LISTENING.
To make a socket wait for and accept a connection, call
SocketAccept()
. The socket must be listening for connections (processed by
SocketListen()
). Because the thread blocks until a connection is made or
SocketAccept()
times out, programs normally don't call this routine in their main execution thread. As in the Appl/SDK_C/Talk sample application, a separate thread handles accepting a connection and receiving data from the connection.
If a connection is made,
SocketAccept()
returns a
Socket
used to represent the connection. Do not confuse this connected socket with the listening socket. You might be able to accept more connections from the listening socket.
If
SocketAccept()
returns SE_LISTEN_QUEUE_EMPTY, then there were no connections waiting to be accepted.
SocketAddLoadOnMsg(), SocketAddLoadOnMsgInDomain(), SocketRemoveLoadOnMsg(), SocketRemoveLoadOnMsgInDomain()
It's all very well that you can tell a running program to accept packets and connections over sockets. However, it seems unreasonable to ask the user to run these programs by hand any time there might be a pending connection.
You can tell the Socket library to load a particular geode when it receives data on a particular port, or on a particular port via a particular domain. For an example, see the Appl/SDK_C/Talk sample application: if you run Talk and press the Autoload button, the Socket library knows to start up the Talk program because it senses that it is receiving an incoming Talk connection.
When the program starts up, it should probably create a socket, bind it to the appropriate port, and make that socket listen. If the listening socket is then destroyed, then any unaccepted connections are canceled.
The Socket library writes out an entry to the GEOS.INI file in the [socket] category and with key "LoadOnMsg". The Socket library consults these GEOS.INI file entries when it starts up and will act accordingly when it receives packets.
To make the Socket library load a program when receiving packets on a particular port, call
SocketAddLoadOnMsg()
. Specify the program by means of its path. To load a program when receiving packets on a particular port on a particular domain, call
SocketAddLoadOnMsgInDomain()
.
To remove the entries from the GEOS.INI file and tell the Socket library not to try to load the program when receiving packets, call either
SocketRemoveLoadOnMsg()
or
SocketRemoveLoadOnMsgInDomain()
.
To listen for incoming data in this manner, the Socket library effectively binds a socket to monitor the port. Thus
SocketAddLoadOnMsg()
and
SocketAddLoadOnMsgInDomain()
can run into bind conflicts just as
SocketBind()
and
SocketBindInDomain()
do.
SocketAddLoadOnMsg()
interferes with
SocketAddLoadOnMsgInDomain()
and
SocketBindInDomain()
on the same port.
SocketAddLoadOnMsgInDomain()
interferes with
SocketAddLoadOnMsg()
and
SocketBind()
on the same port.SocketSend(), SocketRecv(), SocketSetIntSocketOption(), SocketGetIntSocketOption(), SocketSetSocketOption(), SocketGetSocketOption()
Once both sides of a socket communication are set up, they're ready to send data back and forth. The
SocketSend()
and
SocketRecv()
routines, described below, allow a socket to transmit and receive data, respectively.
The amount of overhead associated with sending and receiving data depends on the devices involved, the domain, and the delivery type. Be certain that if just one byte of data is sent at a time, time performance will suffer.
Whenever possible, the sender should gather up small pieces of data and send them in one large packet. The optimal size of a packet depends on the device, domain, and delivery type. When designing a communications protocol, it would be worthwhile to figure out which sorts of data may be combined into larger blocks. Note that in some domains, the driver will try to do this gathering of small blocks into large packets for you.
The Socket library supports the notion of urgent data.  To send a packet marked urgent, pass the SSF_URGENT flag to
SocketSend()
.
In some domains, only one byte of data in a packet can be marked urgent. In such a domain, passing SSF_URGENT with a 32-byte packet to
SocketSend()
results in two packets being sent: a 1-byte urgent packet and a 31-byte non-urgent packet. The data of the 1-byte urgent packet is the last byte of the original 32-byte packet. Check your domain documentation for size limits on urgent packets.
Urgent data may be delivered out of order. It may arrive out of sync with non-urgent packets; it may arrive out of order with other urgent packets. There is no queue for urgent data. Each urgent data packet received causes the previous urgent data to be discarded.
The
SocketRecv()
routine, in charge of receiving incoming packets, may be instructed to receive only urgent data or only non-urgent data. If there is pending urgent data and
SocketRecv()
is told to poll for normal data, it will return an error value, SE_URGENT, signalling that the program should call
SocketRecv()
again, this time to receive urgent data. (If, instead, you call
SocketRecv()
telling it to receive normal data again, it will return any pending normal data; it will not generate the SE_URGENT exception for the pending piece of urgent data -- unless
another
piece of urgent data has arrived in the meantime.)
Datagram connections do not support urgent data;
SocketRecv()
generates an SE_URGENT error on a datagram connection, it's really generating a SE_EXCEPTION value. If you receive such an error, it is a sign that the network is having troubles and packets
may
not be getting through.
You may force incoming urgent data to be treated in the same manner as normal data by setting the socket's "in-line" option. See SO_INLINE: In-line urgent data To force urgent data to be treated the same as normal data. This allows you to poll for both urgent and normal data with a single SocketRecv() command. Of course, setting this option means that you will not receive for information about socket options.
The
SocketSend()
routine sends data over a socket. It takes several arguments:
SocketConnect()
routine to specify a default destination address. If they have no default address, you must specify the destination address for the packet. If there is a default destination address and you pass this optional address, then the optional address overrides the default for this send.Note that in some domains, the driver may delay before sending small packets of data because it is waiting for more packets to combine into one large packet. In many cases, this leads to more efficient communication. You may turn off this behavior by setting the "no delay" option. See SO_NODELAY: No Delay for small packets To force a driver to send small packets without waiting for other packets to bundle together. Drivers often delay sending small packets, waiting for other packets to bundle together in one larger packet. Th for information about setting socket options.
The
SocketRecv()
routine receives data from the socket. After filling the passed buffer with data, the socket discards its copy of the received data to make room for the next piece of incoming data.
Sequenced packet or datagram delivery sockets can only receive whole packets. If you grab data from the socket but don't grab all the data in the packet, the remaining data is lost. Thus, it's a good idea to establish a maximum packet size for sockets using these delivery types. If you're not sure how much room you'll need to receive a packet, call
SocketRecv()
with the SRF_PEEK flag. This allows you to "peek" at the incoming data without causing the socket to discard its copy.
The
SocketRecv()
routine takes the following arguments:
SocketAddress
buffer. (The buffer's
SA_domain
,
SA_domainSize
, and
SA_addressSize
fields must be initialized.) Make sure the buffer has room for the address data after the
SocketAddress
structure. Note that if either the domain name buffer or the address buffer isn't long enough to hold its string, the resulting truncated string isn't null-terminated.
The
SocketRecv()
routine returns the size of the received buffer. If this size is zero, there may be an error in the connection. Use
ThreadGetError()
to check for an error. If
ThreadGetError()
returns SE_NORMAL, then there was no error and you received a zero-length packet. For a datagram connection, an SE_EXCEPTION error indicates that the network is having problems and some datagrams
may
not be getting through.
To customize a socket's sending and receiving behavior, use
SocketSetIntSocketOption()
(or
SocketSetSocketOption()
if you are using Assembly language). The following options are available:
S
O_RECV_BUF
:
Receive Buffer
Size
To change the size of the buffer used to hold incoming data.
SocketRecv()
command. Of course, setting this option means that you will not receive urgent data as soon as possible.
You may find out the current options for a socket by calling
SocketGetIntSocketOption()
(
SocketGetSocketOption()
if you're using Assembly language).
SocketInterrupt(), SocketClose(), SocketCloseSend(), SocketReset(), SocketCloseDomainMedium()
To halt either an accept or receive operation in progress, call
SocketInterrupt()
. If no such operation is in progress but the socket is listening or connected, the next such operation will be interrupted. Look out for the error SE_SOCKET_NOT_INTERRUPTIBLE; this signals that a non-interruptible operation is taking place on the socket.
When it comes time to close the connection and/or free a socket, call
SocketClose()
or
SocketCloseSend()
.
SocketCloseSend()
works only with connected sockets. It partially shuts down the socket so that it can no longer send data; it can, however, still receive data. (Passing a partially closed socket to
SocketSend()
results in an SE_SOCKET_CLOSED error.)
SocketCloseSend()
sends an SE_CONNECTION_CLOSED exception packet to the other side of the connection to let it know that it's starting to shut itself down. Upon receipt of this exception packet, the other side of the connection will probably want to begin closing itself down as well.
Not all domains support closing the "send" part of a socket. In this case, the routine will return SE_CLOSE_SEND_NOT_SUPPORTED and you must use
SocketClose()
instead to close the connection and free the socket.
SocketClose()
closes the socket (shutting down both incoming and outgoing data) and frees it. This routine may be used on a socket in any state. You must use
SocketClose()
to close (and free) a datagram socket.
To close a connection with extreme prejudice, call
SocketReset()
. Use this routine with caution as it bypasses all normal protocol-level handshaking and unilaterally kills the connection. When using this routine, you should still call
SocketClose()
to free the socket data structures and flush any unread data.
The
SocketCloseDomainMedium()
routine can close all connections over a given medium without sending any notifications. It effectively hangs up the connection. You pass a flag to specify whether the routine should only hang up if there are no active connections through the medium, or hang regardless. For more information about socket media and this routine, see Hardware Ports
.
SocketCheckListen(), SocketCheckReady()
The Socket library provides utility routines that query the status of a connection. This can be helpful when figuring out why a connection may not be working or confirming that a connection is working.
Use
SocketCheckListen()
on a port to find out the domain and medium for the first connection request on the port; that is, the first connection request which has not yet been accepted. Think of this as a limited form of "caller ID" -- a chance to find out about the incoming connection before accepting it. If
SocketCheckListen()
returns SE_PORT_NOT_LISTENING, it means there is no socket that is bound to the port and listening.
To "peek" at the next packet of incoming data, call
SocketRecv()
and pass the SRF_PEEK flag. This allows you to get the size of the next packet of incoming data and to look at its contents without destroying it.
To check one or more sockets to see if they have received data, received connection requests, or are ready to write, call
SocketCheckReady()
. It can check connections for incoming data or just incoming urgent data.
For programs which need to poll many sockets,
SocketCheckReady()
provides a tidy means to do this without spawning a thread for each socket.
The
SocketCheckReady()
routine takes an array of
SocketCheckRequest
structures. Each one of these structures contains a socket and a condition.
SocketCheckReady()
looks at each
SocketCheckRequest
structure in the array and returns the index of the first structure whose socket meets the condition.
Thus, to determine if a given socket is properly set up so that you can send data through it, pass
SocketCheckReady()
a one-element array (represented in pseudo-code):
{ mySocket, SC_WRITE, 0 }
To check several sockets to see whether any of them had received any connection requests, pass to
SocketCheckReady()
an array of the form (represented in pseudo-code):
{ socket1, SC_ACCEPT, 0 }, { socket2, SC_ACCEPT, 0 }, { socket3, SC_ACCEPT, 0 }
For any socket, you may check for one or more of the following conditions, as represented by
SocketCondition
values:
If you query a socket about a condition that does not apply to its current state (
e.g.
, ask a non-listening socket if it is ready to accept connections), then
SocketCheckReady()
returns SE_IMPROPER_CONDITION.
Some portions of the Socket library API are domain specific; depending on which domain you're using, the domain name, address formats, port numbering schemes, etc. may differ.The following sections describe information specific to particular domains. Not all domains are available on any given device.
The TCP/IP domain is a popular standard used for internet communications. The GEOS-specific version supports 32-bit port numbers. GEOS TCP/IP data may be transmitted via a regular TCP/IP network, though both the sending and receiving machines must support GEOS TCP/IP.
TcpAccPntExtendedAddress
,a
TcpOnlyExtendedAddress
, or a
TcpNonAccPntExtendedAddress
.
SocketOpenDomainMedium()
with the TCP medium creates a PPP connection. The modem will dial, and the machine will connect to the PPP server, but no TCP level packets will be sent. If the PPP connection is already made, this routine will return SE_NORMAL, just as if the connection had been just now made. If the modem is already in use, an SE_MEDIUM_BUSY error will be returned. Use the
SocketCloseDomaninMedium()
to hang up the phone when done.
MSG_GEN_GUP_INTERACTION_COMMAND
, which queries the AccessPointControl for the selected ISP and extracts the useful information about that ISP; finally, the MSG_CTP_CONNECT handler dials the phone to make the PPP connection.)Code Display 23-2 Making the Raw TCP/IP Connection
Here we see three snippets of code from the Talk sample application
The AccessPointControl allows the user to choose an ISP:
@chunk char accpntMkr[] = "Access List";
@object AccessPointControlClass AccpntControl = { GI_states = GS_USABLE|GS_ENABLED; HINT_ACCESS_POINT_CONTROL_MINIMIZE_SIZE; ATTR_ACCESS_POINT_CONTROL_LIST_MONIKER = @accpntMkr; }
In @method TalkAddressClass, MSG_GEN_GUP_INTERACTION_COMMAND, we get information we'll need about the ISP
point = @call \ GeodeGetOptrNS(@AccpntControl)::MSG_ACCESS_POINT_CONTROL_GET_SELECTION();
/* store link info into address buffer */ rawAddress.UTA_link.TAPEA_linkSize = 3; rawAddress.UTA_link.TAPEA_linkType = LT_ID; rawAddress.UTA_link.TAPEA_accPntID = point;
/* the text of the address follows the link info */ alen = @call GeodeGetOptrNS(@IPText)::MSG_VIS_TEXT_GET_ALL_PTR( (char *)&(rawAddress.UTA_ip[0]));
if (alen > MAX_IP_ADDR_STRING_LENGTH) FatalError(0); /* too much text */
/* resolve the raw address into a SocketAddress */ theAddress.SA_addressSize = SocketResolve(theAddress.SA_domain, (byte *)(&rawAddress), sizeof(TcpAccPntExtendedAddress)+alen, (byte *)(&addressBuffer), MAX_ADDRESS_SIZE);
In MSG_CTP_CONNECT's handler, we make the PPP connection:
rval = SocketOpenDomainMedium((SocketAddress *) &theAddress, SOCKET_NO_TIMEOUT);
If you set the SSF_URGENT flag to
SocketSend()
when sending a multi-byte packet, the last byte of the packet will be marked urgent.
Recall that you can set the in-line option to specify that urgent data should be treated as normal data. In this case, urgent data will be treated as a normal 1-byte packet.
#define ECHO 7 /* TCP/UDP */ #define DISCARD 9 /* TCP/UDP */ #define FTP_DATA 20 /* TCP */ #define FTP 21 /* TCP */ #define TELNET_SERVER 23 /* TCP */ #define NAME_SERVER 42 /* UDP */ #define WHOIS 43 /* TCP */ #define DOMAIN_SERVER 53 /* TCP/UDP */ #define FINGER 79 /* TCP */
SocketAddress
structure takes the following form for the TCP domain:typedef struct { word TOEA_linkSize; /* 0 */ byte TOEA_ipAddr[4]; /* IP address */ } TcpOnlyResolvedAddress;
A variation on this structure is used for storing the address information for a TCP access point address. Along with the address information, there are three bytes of information about the nature of the link: the first of these bytes should have value LT_ID, so that the driver will know that the next two bytes represent a link ID; the other two bytes should be the access point's ID.
typedef struct { word TAPRA_linkSize; /* 3 */ byte TAPRA_linkType; /* LinkType (LT_ID) */ word TAPRA_accPntID; byte TAPRA_ipAddr[4]; /* IP address */ } TcpAccPntResolvedAddress;
This is the standard TCP/IP domain, popular protocol for internet communications.
TcpAccPntExtendedAddress
,a
TcpOnlyExtendedAddress
, or a
TcpNonAccPntExtendedAddress
.The loopback domain can only be used for communications between sockets on the same machine.


This report summarizes the analysis and modeling results of a study to infer the effects of per-channel marketing expenditures on unit sales, with and without the condition of gender targeting. The channels used in the analysis are Adsense display ads, Pinterest promoted pins, and Facebook news feed ads.
Analysis: Methods of analysis include multiple linear regression, t-tests, F-tests, confidence intervals, and cross-correlation. Primary results and figures are in the Results section, and all figures, tables and calculations can be found in the appendix.
Results and Conclusions: In the context of this study, results show that the best performing channel (without considering gender) is Adsense, and the weakest performer is Pinterest. Men are most responsive to Adsense, and are generally unresponsive to promoted pins. Women respond well to both Facebook and Pinterest, and less to Adsense. Cross-correlation shows that the expected time to conversion is one week.
This study concludes that the marketing budget can be allocated more effectively, especially for Adsense and Pinterest campaigns.
Recommendations:
Limitations: There are many lurking variables in this study that can affect conversion rates for advertisements. A major subset of these fall under conversion tracking: there is no attribution, contextual data, or information about ad content for various campaigns.
This report summarizes the primary analysis and statistical modeling results of a study involving 104 weeks of online marketing campaigns. The primary goal of this analysis is to use multiple regression to infer the effects of marketing expenditures on unit sales across three marketing channels, both with and without the condition of gender targeting. The secondary goal is to estimate the expected time to conversion using cross-correlation.
Two related datasets are used: The first contains week number, weekly spending for three different marketing channels, and the gender targeted in each campaign. The second contains week number and weekly unit sales (the response variable).
The questions that motivated this study are:
The dataset for this project is comprised of two tables (dset1 and dset2) in CSV format, both from a 104 week sample. The first (dset1) has five columns:
The second table (dset2) has two columns: week and units_sold (number of units sold that week), and 104 rows — one for each week of unit sales. There are no dates specified, only week number.
Before modeling, the data needed to be in a merged form that allows creation of gender-specific and gender-neutral models. To combine the sets, the spending and gender columns needed to be merged with unit sales according to week number. This merge was done with a simple inner join using the week number as the key, resulting in a single array with 208 rows and six columns (see table 1). This array was name dset and served as a master set for creating the ones to be used in the actual modeling process.
| week | ads | pin | fb | gender | units_sold | |
|---|---|---|---|---|---|---|
| 0 | 1.0 | 11.89 | 70.77 | 259.24 | 0.0 | 119.0 |
| 1 | 1.0 | 128.72 | 243.59 | 19.99 | 1.0 | 119.0 |
| 2 | 2.0 | 137.10 | 170.12 | 48.96 | 0.0 | 112.0 |
| 3 | 2.0 | 17.52 | 136.84 | 379.36 | 1.0 | 112.0 |
| 4 | 3.0 | 260.47 | 143.52 | 276.07 | 0.0 | 133.0 |
The second step was to create a gender-neutral data frame (dfn) with rows of the same week number summed for weekly total spending. This was achieved by grouping the data by week and using summation as the aggregate function, then dropping the gender column. This left the unit sales for every week doubled — a problem that was corrected by dividing all unit_sales values by two.
Before creating the gender-specific sets, cross-correlation was performed on dfn, which is described in the next section, where construction of gendered sets is described.
Because least squares regression requires statistical independence between predictors, this condition was verified by computing the Pearson correlation coefficient on all predictors (see figure 1). Cross-correlation was performed on unit sales against each of the channels in dfn using using the signal correlation function available in the Python SciPy package. The results showed that correlation was highest for all channels at the -1 lag, which indicates a one week time to conversion. The plotted results of the cross-correlations are below.
Because the cross-correlations show a lag of one week, dfn units_sold were shifted one week to account for the offset. The first step in creating the male and female sets (dfm and dff, respectively) was to create a copy of dset with units_sold shifted up by two weeks (there are two entries per week number). The second step was to filter this set by gender, setting dfm and dff equal to their respective filtered results, and dropping the gender column. The indices on dfm and dff were reset to generic row numbers.
The following scatter plots were produced to gain some visual insight into the relationship between unit sales and each channel, for gender-neutral and gender-specific:
A total of 12 models were fitted to the data — four for each of dfm, dff, and dfn: three bivariate models (one for each channel) and one multivariate model using all channels. These were fitted using an ordinary least squares regression algorithm I wrote (found here).
The models output descriptive statistics (see Evaluation) and the estimated parameters bi. The model parameters are the values of interest for answering the first question posed in this study. The estimates for the multivariate models are below.
| Neutral | Male | Female | |
|---|---|---|---|
| b0 | -2.862018 | 91.366817 | 78.718772 |
| b1 | 0.143175 | 0.172782 | 0.041876 |
| b2 | 0.115655 | 0.045164 | 0.188009 |
| b3 | 0.168091 | 0.134592 | 0.128299 |
The b0 value indicates the expected baseline sales with no money spent on advertising, and the values b1-b3 indicate the expected number of unit sales for every dollar spent on a specific channel. As an example, b1 = 0.17 means that a spend of $100 on Adsense in the gender-neutral model is expected to generate sales of 17 units, independent of other channels.
To evaluate the the multivariate models, ANOVA with unconstrained and incremental F-tests were used, and the bivariate models were evaluated using t-tests. The fits of all models were measured using R2 and adjusted R2. The results of the unconstrained F-tests are in the tables below.
| SS | DF | MS | F | p-value | R2 | R2adj | |
|---|---|---|---|---|---|---|---|
| Regression | 53677.99 | 3.0 | 17892.66 | 141.90 | 2.22e-16 | 0.81 | 0.81 |
| Error | 12483.47 | 99.0 | 126.10 | - | - | - | - |
| Total | 66161.46 | 102.0 | 648.64 | - | - | - | - |
| SS | DF | MS | F | p-value | R2 | R2adj | |
|---|---|---|---|---|---|---|---|
| Regression | 25979.75 | 3.0 | 8659.92 | 24.62 | 1.75e-11 | 0.45 | 0.43 |
| Error | 32356.49 | 92.0 | 351.70 | - | - | - | - |
| Total | 58336.24 | 95.0 | 614.07 | - | - | - | - |
| SS | DF | MS | F | p-value | R2 | R2adj | |
|---|---|---|---|---|---|---|---|
| Regresion | 20147.50 | 3.0 | 6715.83 | 14.40 | 1.94e-07 | 0.32 | 0.30 |
| Error | 41983.90 | 90.0 | 466.49 | - | - | - | - |
| Total | 62131.40 | 93.0 | 668.08 | - | - | - | - |
The F-tests were two-sided hypothesis tests of the form:
H0: β1 = β2 = β3 = 0
HA: At least one βi ≠ 0
Where βi are the true parameters. In other words, test the null hypothesis (H0) that there is no relationship between the amounts spent on any of the marketing channels and unit sales. The alternative hypothesis (HA) is that there is a relationship between the amount spent on at least one of the marketing channels and unit sales.
The incremental F-tests were similar, but they tested multivariate models excluding each of the channels, one at a time. This served to estimate the impact of each channel on the complete multivariate models, and determine if any were unimportant. The outcome of the incremental tests are discussed in the results section. Each incremental model kept two of the channels, and tests with only one channel were done in the bivariate models using t-tests. The pairs tested were therefore {(ads, pin), (ads, fb), (pin, fb)}. Using ANOVA results, 95% confidence intervals were constructed for the three multivariate models (see Results).
The estimated parameters for the multivariate models give the following equations for the three models, rounded to three decimal places:
ŷn = -2.862 + 0.143 xads + 0.116 xpin + 0.168 xfb
ŷm = 91.367 + 0.173 xads + 0.045 xpin + 0.135 xfb
ŷf = 78.719 + 0.042 xads + 0.188 xpin + 0.128 xfb
The ŷ values are the estimated number of units sold in response to spending on the three channels, xads, xpin, and xfb in each model. These equations produce hyperplanes that cannot be graphed, but the lines of best fit from the bivariate models are graphed over the scatter plots from figure 3, and their equations are displayed in the legends:
As was seen in tables 3-5, all models have p-values very nearly or precisely zero, which is strong evidence against the null hypothesis. For the multivariate models, this means there is strong evidence to suggest that at least one of the marketing channels has a linear relationship with unit sales for all three data sets. This says nothing about which, or if all of them have such a relationship. The results of the incremental models, however, give strong evidence (p < 0.001) that there is a linear relationship between all of the marketing channels and unit sales for all three sets, except for a slightly higher p-value (p = 0.0055) for the (ads, fb) model using the female set.
The 95% confidence intervals were constructed using the standard errors of the parameter estimates for each unconstrained model, and are shown as error bars with the estimated values in the following figure:
The interpretation of these intervals is that there is a 95% probability that each of these intervals contains the value of the true parameter βi. As an example, there is a 95% chance that the actual number of units that can be expected to sell for every dollar spent on Adsense is between 11.9 and 16.8 for the gender-neutral model.There is strong evidence to suggest that there are linear relationships between the number of dollars spent on each marketing channel and unit sales. Results suggest that the expected number of unit sales per dollar spent can be ranked (best to worst) as follows:
Neutral: (Facebook, Adsense, Pinterest)
Male: (Adsense, Facebook, Pinterest)
Female: (Pinterest, Facebook, Adsense)
Men are generally unresponsive to promoted pins, and most responsive to Adsense. Women are very responsive to promoted pins, and mostly unresponsive to Adsense. The results of cross-correlation show that the expected time to conversion is one week for all channels.
The confidence intervals are small enough for the gender-neutral model to have some confidence about the expected response without factoring in gender, while the intervals are large for the gender-specific sets. Because of the large gender-specific intervals, results should be used with some caution. This is unsurprising with no attribution of sales to specific campaigns, which would give more insight into gender response differences. An analysis of a dataset that accounts for more variables (see Recommendations) — or at least a wider range of spending — could help produce estimates with narrower intervals.
The first two recommendations are suggestions that should increase ROI for future ad campaigns, and the last is a suggestion that will lead to stronger, more useful analyses in the future.
There are many lurking variables in this study that can affect conversion rates for advertisements, and that are unaccounted for in the models presented here. A major subset of these variables fall under conversion tracking: there is no attribution, contextual data, or information about ad content for various campaigns. If this data were available, it could help produce superior models.


XZError
public enum XZError: Error
Represents an error, which happened during unarchiving XZ archive. It may indicate that either archive is damaged or it might not be XZ archive at all.
-
Either ‘magic’ number in header or footer isn’t equal to a predefined value.
Declaration
Swift
case wrongMagic
-
One of the fields in archive has an incorrect value.
Declaration
Swift
case wrongFieldValue
-
One of the reserved fields in archive has an unexpected value, which can also mean (apart from damaged archive), that archive uses a newer version of XZ format.
Declaration
Swift
case fieldReservedValue
-
Checksum of one of the fields of archive doesn’t match the value stored in archive.
Declaration
Swift
case wrongInfoCRC
-
Filter used in archvie is unsupported.
Declaration
Swift
case wrongFilterID
-
Archive uses SHA-256 checksum which is unsupported.
Declaration
Swift
case checkTypeSHA256
-
Either size of decompressed data isn’t equal to the one specified in archive or amount of compressed data read is different from the one stored in archive.
Declaration
Swift
case wrongDataSize
-
Computed checksum of uncompressed data doesn’t match the value stored in the archive. Associated value of the error contains already decompressed data.
Declaration
Swift
case wrongCheck(Data)
-
Padding (null-bytes appended to an archive’s structure) is incorrect.
Declaration
Swift
case wrongPadding
-
Either null byte encountered or exceeded maximum amount bytes during reading multi byte number.
Declaration
Swift
case multiByteIntegerError


Before Change
if _is_running_py3():
filename, start_line = frame.filename, frame.lineno
else:
filename, start_line = frame[:2]
yield
frame = _traceback.extract_stack()[-3]
if _is_running_py3():
end_line = frame.lineno
After Change
initial_spaces = match.end() if match else 0
for line in source_lines[end_line:]:
match = _SPACES_RE.match(line)
indentation = match.end() if match else 0
// The != 1 is because we want to allow "\n" between sections.
if indentation != 1 and indentation < initial_spaces:
break


I'm a User Experience Researcher and Interaction Designer based in La Jolla, CA. I'm currently studying Cognitive Science with a specialization in Human-Computer Interaction at the University of California, San Diego. My projected graduation date is June of 2015.
I have a huge interest in immersive storytelling and gaming, and also enjoy topics like UbiComp and augmented reality. I have an affinity for public works and charitable causes.


Witch Kalis:
Haven't you already passed my test? Why do you return to my humble abode?


---
layout: post
title: A Kernel of Truth at the Heart of a Story
date: '2012-03-02T14:10:00.000-06:00'
author: Jabell
tags:
- Story
- Writing
- Fiction
modified_time: '2012-03-02T14:10:48.278-06:00'
blogger_id: tag:blogger.com,1999:blog-19739956.post-6859867943601045426
blogger_orig_url: http://theabellsix.blogspot.com/2012/03/kernel-of-truth-at-heart-of-story.html
---
“My job as a writer is to whittle my story down to the bare truth at its heart and then build around it the best illusions I can muster, illusions that support and even illuminate without distracting. The failure to understand this is precisely why so many films fall flat—the storyteller is enraptured by his own illusion and forgets to paint the truth. If there’s not a kernel of truth at the heart of the story, then all the action sequences, precise prose, and emotionally manipulative music on earth can’t save it.”
—Pete Peterson, The Rabbit Room, Truth in the Guise of Illusion


About Us
We are a local Seattle company here to give you a new experience!
Locations
All stores open at 6am and close at 8pm everyday!
- 1st and Pike
- SeaTac Airport
- Seattle Center
- Capitol Hill
- Alki
Contact us!
Phone Number: 911
We are a local Seattle company here to give you a new experience!
All stores open at 6am and close at 8pm everyday!
Contact us!
Phone Number: 911


What do you get when you cross a bunch of passionate, self-directed engineers with an agile, iterative approach to both software and personal development? Predictably, you get continuous delivery of customer value and solutions to really hard problems. Additionally, as a nifty bonus, you get a new kind of discussion forum that brings all the best qualities of agile software development to individual improvement: the Personal Retrospective.
Before your imagination goes too far, let me assure you this does not require hugging, silly hats, or revealing favorite brands of underwear. Nor is there screaming into a mirror or "Fight Club" activities of any sort. The Personal Retrospective is an undertaking at Relevance that forms a cornerstone of our company culture and a critical ingredient to our goal of continuous improvement at all levels.
Great Feedback in 60 minutes or Less
The key ingredients for a Personal Retrospective at Relevance are five or so team members who have first hand experience with the subject's recent performance and another Relevance employee who serves as a neutral facilitator for the discussion. During the meeting, the individual is provided with an hour of open and honest feedback which validates and appreciates areas where they are providing their best value to their team and clients, and calls out ways they may not be meeting the mark or have the greatest room to grow.
An agenda is set ahead of time by the subject (with the help of the facilitator) to focus the feedback on areas and goals most important to them. The experience can be extremely positive, giving deeper insight into the impact your actions have had on those around you, as well as deeply emotional as you hear the negative effects even your best intentioned actions have had on the team.
Sometimes there are surprises, though often the subject has at least some notion of where things are not going great, and a critical component of a successful Personal Retrospective is a list of clear action items and mechanisms to encourage and monitor improvement once the meeting concludes.
I Never Thought it Would Happen to Me...
Recently I had the opportunity to participate in my own Personal Retrospective to evaluate current performance as an Agile Project Manager and Coach. Although I had requested the meeting and chose the attendees, it was still quite intimidating to hear several people who I respect greatly talk about me both positively and critically (and often in the third person as guided by the facilitator to ensure the messages are clear and actionable). In the end though, it worked wonders to quiet the distracting internal voice of insecurity by hearing where my efforts are helping the team. Additionally, it helped me understand where I have been dropping the ball, along with recommendations on how to get on the right track.
The guesswork has been largely eliminated in the form of a group of trusted peers stating "This set of things you do, they are really good; keep doing them. This other set of things, you're doing okay, and here are some tweaks to make them better. And this set of things, these actions are having a negative effect on us and the project; here are examples of them and some clear ways to change these behaviors.""
Bringing the Love Home
This isn't a review. No money, position, or responsibility changes are made as a direct result of what is said. It is a safe forum for enabling feedback to help folks at Relevance along in their journey. Such a personal and sometimes difficult meeting may not be for everyone nor for every organization, but it is an option you and your team should consider when looking for additional ways to get to the next level of individual and group performance. If you'd like more specifics on how the process works, give us a shout and we'll be happy to help. If it doesn't work, you can always go with the silly hats and underwear stories.
Originally posted at thinkrelevance.com


2750 BC - Some egyptians started to step on an electric eels
1750 BC - 1000 years later nothing changed - Greek, Roman and Arabic step on an electric eels too
600 BC - Thales found static electricity, probably by handshaking with a fellow businessman during a period of a good olive harvest
1600 AD - William Gilbert distinguished the lodestone effect from static electricity produced by rubbing amber. Seems we waited only ~2200 years for this to happen ...
~1745 AD - Dutch scientist Leyden and german clerik Kleist independently invented the capacitor
~1750 AD - Benjamin Franklin found the two types of electric charges, then proved the lightning is an electricity by using a kite and a house key
1791 AD - A guy named Luigi Galvani successfully managed to move the legs of a couple of dead frogs using electricity and stated that "electricity was the medium by which neurons passed signals to the muscles" , ...
1800 AD - ... but Alessandro Volta proved that Galvani is wrong, ie the medium was the metal wire used by Galvani in his experiments. Later Volta also created and one of the first electrochemical cells, or the battery. Great day for our bicycle flashlights, and not so great for Galvani, which probably hated Volta a lot
1800-1820 AD - Two French scientists, Ampère and Coulomb, and Danish Ørsted, experimented a lot in the field of electromagnetism, which was enough their names to be used in physics textbooks to this day
1821 AD - Michael Faraday invented the electric motor, so we can use them in radio-controlled models
1827 AD - Georg Ohm mathematically analysed the electrical circuit which established his famous law, but it's very annoying why we still cannot calculate properly the resistor values for our LED contraptions
1861-1862 AD - James Maxwell mathematically found the waveform nature of electric and magnetic fields, and concluded that the light is some form of electro-magnetic wave (whoa!), ...
1879 AD - ... later Heinrich Hertz confirmed Maxwell's equations through experiments with radio waves (another whoa!). In his honor we use his name for unit of frequency (Hz - hertz). In 1887 AD he found also that electrodes illuminated with ultraviolet light create electric sparks more easily ...
1905 AD - which led Albert Einstein to publish his work on the photoelectric effect, so today we can use solar panels


I am completely interested in tech. I started off building my first computer when I was 14, and have built several other computers for some friends since then. The top computer I have ever built is on display here. I was on my school's FRC robotics team for 2 years, one of which was being the executive leader of the programming team. I helped to program what would eventually be the code used to get our team to 14th in the province, while placing 4th at our regional tournament.
 This was where we would make repairs on our robot after a match, discuss strategy, and coordinate with other teams. There were around 40 people form our team at this event, from the ~60 total people on the team.


Let's get stemming!
Please enter a URL below to a list of words
Stem WordList
Lookup Word
{{errorText}}