Event Location:
Speed School of EngineeringUniversity of Louisville
132 Eastern Parkway
Louisville, Kentucky
Abstract:
In 2007 the media was buzzing with reports that hackers stole 45.7 million credit card numbers from a major retailer's databases. Experts agree the damage could have been mitigated with database encryption. In this presentation attendees will learn how to secure their corporate data in SQL Server 2008. Attendees will explore cell-level encryption, cryptographic hash functions, transparent database encryption (TDE), extensible key management (EKM), and even SQL CLR. By attending this presentation you will learn techniques that will ensure that your company doesn't appear in the headlines in the headlines for all the wrong reasons. Don't become another statistic; data security is a topic that no database professional can afford to ignore.
Speaker(s): Michael Coles,
Abstract:
Sure you've read the SSIS books. And sure you've seen a lot of SSIS presentations. But how do you put it all together to create a solid ETL framework for loading your data warehouse environment? In this (updated for 2010) session, we'll look at the ins and outs of a real-world ETL environment built using SSIS. We'll discuss the ETL design patterns used to handle a multi-tiered data warehouse environment with multiple data sources, different loading schedules, and different data transformation requirements. We'll also discuss how the development team responsible for the ETL environment at the Department of Veterans Affairs handles package auditing and logging, team development, package testing, and automated deployments.
Speaker(s): Dave Fackler,
Abstract:
An often-overlooked aspect to data optimization is what is happens under the covers – how does SQL Server store and access data? There are plenty of common rules covering tuning, but this session looks at data access from the physical layer, detailing how table access and indexes work, showing why some designs perform poorly, and why adding more indexes may not help. This will not be a discussion of normal forms or design rules. Instead, it will be a technical session providing the foundation for you to choose which concepts to apply to your designs. The session starts with the notion that SQL Server is not a magic box – most of what happens is well-documented and must be taken into consideration when designing or tuning databases.
Speaker(s): Eddie Wuerch,
Abstract:
In this session I will give an overview of how to design a database, including the common normal forms and why they should matter to you if you are creating or modifying SQL Server databases. Data should be easy to work with in SQL Server if the database has been organized as close as possible to the standards of normalization that have proven for many years. Many common T-SQL programming "difficulties" are the result of struggling against the way data should be structured and can be avoided by applying the basic normalization techniques and are obvious things that you find yourself struggling with time and again (i.e. using the SUBSTRING function in a WHERE clause meaning you can't use an index efficiently).
Speaker(s): Louis Davidson,
Abstract:
This is a vendor session.
Speaker(s): Steve Jones,
Abstract:
Are you seeking practical, in-depth technical advice for building a BI solution using SSAS? Analysis Services changed tremendously with the advent of SQL Server 2005. It introduced a new way of building dimensions and cubes that required a new way of modeling the solution. This session examines the best practices for properly designing cubes for performance and usability. It discusses some high-level topics but also looks at advanced topics such as alternative approaches to many-to-many dimensions, SCOPE statements, aggregation design, scalability issues, processing techniques, server properties, and more.
Speaker(s): Craig Utley,
Abstract:
Attribute discretization is an oft-overlooked feature in Analysis Services that allows us to automatically create a manageable number of groups of attribute values that are clearly separated by boundaries. Discretization can help us to make it easier for information consumers to work with large numbers of possible attribute member values. In this session, we will discuss the varied options, the design (and other) considerations involved, and best practices surrounding the use of this capability.
Speaker(s): William E Pearson III,
Abstract:
Most modern enterprise database environments require some measure of auditing their data. Previously, the DBA would need to put together a complicated web of triggers and history tables in order to properly track data changes. Now in SQL Server 2008, Change Data Capture allows the DBA to readily enact a very straight-forward method for tracking the changes and understanding easily how they took place. In this session, we will examine how to set-up, configure, use, and administer the Change Data Capture process in your environment
Speaker(s): Arie Jones,
Abstract:
SQL Azure allows you to host your data in SQL Server in the cloud. That provides some big benefits in scalability and management. However, it leaves open the question, “How do you get your data into / out of the cloud?” At some point, you are going to need to move data to or from an on-premise store to SQL Azure. In this session, we’ll discuss the available options for this, including SSIS, the Sync Framework, and BCP. We’ll cover the pros and cons for each. We’ll drill into one of the options, SSIS, in detail, and review performance options and potential issues that you may encounter when doing this.
Speaker(s): John Welch,
Abstract:
SQL Server 2008 R2 provides many compelling reasons to upgrade especially in the area of Reporting Services. In this session, we will walk through all of the new data visualizations that are available in the latest release from Microsoft. You will learn how to use Sparklines, Indicators, Data Bars, as well as the integrated Bing Maps control in order for you to create more captivating data visualizations for your BI projects. Along the way we'll also delve into other important new features such as shared datasets, new data sources, and the Report Part Gallery. You'll leave this session with the knowledge you need to take your next BI project to the next level.
Speaker(s): Arie Jones,
Abstract:
SQL Server provides a rich set of security features that allow customers to satisfy their security goals. Everything from encrypting sensitive data to recording all activity within a particular database is easily attainable with the features introduced in 2008. While SQL Server does not provide a packaged solution to facilitate Separation of Duties, it does provide functionality that allows Separation of Duties to be achieved. Come to this session to understand how to leverage the functionality available in SQL Server implemented through free community tools and achieve all of your compliance goals.
Speaker(s): Kathi Kellenberger,
Abstract:
Demonstrate what my dear Aunt Sally has to do with your T-SQL code as we explore order of operations and a select statement's execution order in general.
Speaker(s): Kevin Cross,
Abstract:
In today's enterprise environments, it is becoming increasingly necessary to integrate data from a variety of sources. As SQL Server continues its march into the enterprise, the days of focusing 100% on one platform are over. At a bare minimum, we need to be able to communicate with DBA's for other platforms. Terminology as simple as Instance and Database mean very different things in Oracle than they do in SQL Server. In this session, we will compare and contrast the two platforms in terms of features and terminology. We will also discuss some of the best practices and pitfalls when integrating the two.
Speaker(s): Randy Knight,
Abstract:
If you are always looking for better ways to deliver value to the business as part of a BI project, make sure you examine the capabilities of PowerPivot. Using existing data and tools, users now have the ability to analyze vast quantities of data without first designing dimensions and measure groups. Users can explore the data and optionally share their analysis with others. See how Gemini opens the power of Analysis Services to non-technical users while still allowing the IT organization to administer and secure the data.
Speaker(s): Craig Utley,
Abstract:
Start with a simple proposition: a process is either working or waiting. You can tune the working part, but are you seeing the whole picture? There are many different resources on which your process could be waiting – a lock, memory, disk, CPU, and much more. When a process must wait, SQL Server will log it. There are hundreds of different wait types, and they are a gold mine of data for finding and solving performance problems – and proving the changes worked. After attending this session, you will be able to gather wait stats and use them to zero in on performance issues affecting your databases. Stop guessing, start knowing!
Speaker(s): Eddie Wuerch,
Abstract:
A panel discussion headed by Kathi Kellenberger of Microsoft. Details to be updated soon.
Speaker(s): Mala Mahadevan,
Abstract:
Performance tuning is hard, everyone knows that. Attend this session and learn how to define, measure, and analyze performance issues as well as implementing changes and also how to make sure those changes continue to have the desired effects. In short, I break down performance tuning into pieces that anyone can understand. Leave this session knowing what actions to take when you get back to work on Monday.
Speaker(s): Thomas LaRock,
Abstract:
SQL Server 2008 once again improves on the classic built-in SQL Server full-text search (FTS) functionality by making FTS more efficient and transparent. In this course attendees will learn both the basics of the new Integrated FTS (iFTS) and how to build user-friendly Google-style search interfaces on top of SQL Server for the benefit of their end users.
Speaker(s): Michael Coles,
Abstract:
Maintaining a solid set of information about our servers and their performance is critical when issues arise, and often help us see a problem before it occurs. Buiding a baseline of performance metrics allows us to know when something is wrong and help us to track it down and fix the problem. This session will walk you through a series of PowerShell scripts you can schedule which will capture the most important data and a set of reports to show you how to use that data to keep your server running smoothly.
Speaker(s): Allen White,
Abstract:
Ever wonder if there is an easy way to gather performance metrics? Look no further...there is! In this session, we'll look at how to use free SQL Server diagnostic tools. We'll cover capturing performance counters, DMV data along with SQL trace data and correlate the information. A must have for quickly and easily finding system bottlenecks.
Speaker(s): Tim Chapman,
Abstract:
Performance-driven SSIS ETL solutions require a mix of both SQL and SSIS developer optimizations. In this session attendees will learn SQL code and SSIS data flow optimizations, tips and best practices that are specifically geared to obtain the best performance from your enterprise ETL solution. This session is specific to Datamart ETL, but much of the information presented can be applied to any SSIS solution.
Speaker(s): Michael Coles,
Abstract:
Managing DDL scripts has always been one of the biggest challenges facing Database Developers. How do you keep your Development, Test, Stage, and Production Environments in sync? Why aren't databases tightly integrated into source control systems like application code is? Visual Studio 2010 Database projects solve all these problems and more. In this session, we will learn how to use Visual Studio to treat database objects as the first-class citizens they have always been.
Speaker(s): Randy Knight,
Abstract:
The Policy-Based Management feature in SQL Server 2008 provides a great way to ensure your systems are configured consistently and correctly, but it can be tedious to implement on each server in your environment. PowerShell scripts allow you to automate the implementation of your policies so you can focus on more important problems. This session will walk you through how PBM works, how to define your policies in PowerShell, and how to set up Agent jobs to evaluate those policies regularly to let you know when you need to take action.
Speaker(s): Allen White,
Abstract:
Poor database performance is Achilles' heel of any system. Better and faster hardware can improve systems to a certain point. However, for truly great performing systems, there is no substitute for properly written queries and designed indexes. In this session we'll take a look at some common query performance killers, along with some no so obvious things that we can do to our queries to make them as fast as possible.
Speaker(s): Tim Chapman,
This is a list of speakers from the XML Guidebook records. The details and URLs were valid at the time of the event.
LinkedIn: http://www.linkedin.com/in/johncwelch/
Contact: http://agilebi.com/jwelch
John Welch joined SentryOne in spring 2018 as VP of Engineering with the acquisition by SentryOne of the software division of Pragmatic Works. John leads the development of a suite of products that make developing, managing, and documenting data solutions easier. John has been successfully delivering IT solutions to business problems since 1994, and has been focused on business intelligence and data warehousing technologies since 2001. He is a Microsoft Most Valued Professional (MVP), and a frequent presenter on SQL Server and data topics. He also contributes to several open source projects and community initiatives targeted toward making data professionals work more productive.
LinkedIn: http://www.linkedin.com/in/eddiewuerch
Contact: http://www.indydba.com
Eddie Wuerch has 20 years of experience as a SQL Server specialist in a much-longer IT career. A Microsoft Certified Master, Eddie spends his days in the Salesforce Marketing Cloud, focusing on performance, scale, and uptime for the massive SQL Server backend. These SQL Servers churn billions of transactions daily against trillions of rows of data in a 24x7 continuously-available online system accessed by millions worldwide every day.
Contact: http://www.programmersedge.com
Arie Jones 'AJ' is the Principal Technology Manager for Perpetual Technologies, Inc. in Indianapolis, IN. Arie leads PTI’s team of expert consultants in planning, design, development, deployment, and management of database environments and applications to achieve the best combination of tools and services for each client. Additionally, AJ is a community speaker, has written several books such as “Learn SQL in 24 Hours”, and blogs extensively at http://www.programmersedge.com
LinkedIn: http://www.linkedin.com/in/way0utwest
Contact: http://www.voiceofthedba.com/
Steve Jones is a Microsoft SQL Server MVP and has been working with SQL Server since version 4.2 on OS/2. After working as a DBA and developer for a variety of companies, Steve co-founded the community website SQLServerCentral.com in 2001. Since 2004, Steve has been the full-time editor of the site, ensuring it continues to be a great resource for SQL Server professionals. Over the last decade, Steve has written hundreds of articles about SQL Server for SQLServerCentral.com, SQL Server Standard magazine, SQL Server Magazine, and Database Journal.
LinkedIn: https://www.linkedin.com/in/mamahadevan/
Contact: http://curiousaboutdata.com
Mala Mahadevan is a senior database professional with over 20 years of experience working with data, primarily in SQL Server and related technologies. She has been volunteering with SQL Server community for the past 22 years, Regional Mentor over the KY/TN states, on the board of Raleigh PASS user group and recipient of the PASSion award for being an outstanding volunteer. She is also an Apress book author and blogger on sqlservercentral.com.
LinkedIn: http://www.linkedin.com/pub/allen-white-sql-server-mvp/5/784/b08/
Contact: http://dataperfpro.com/blog/
Allen White is a Data Platform consultant. He has been both a developer and an administrator, so he understands both perspectives towards database technology. He loves sharing his experiences and helping people learn how to use SQL Server. Allen has spent over 40 years in IT, using SQL Server since 1992, and has been awarded Microsoft’s MVP Award for the last 13 years. Allen was a PASS Director from 2016 - 2018.
LinkedIn: https://www.linkedin.com/e/fpf/252170891
Contact: https://mvp.support.microsoft.com/profile=02C5CD07-7511-4151-A678-3A4A3451F85E
Bill Pearson created Island Technologies Inc. in 1997, and has developed a large and diverse customer base since. Bill#39;s background as a CPA, Internal Auditor, Management Accountant, and SQL Server MVP (BI) enables him to provide value to clients as a liaison between Accounting / Finance and Information Services. Bill has implemented enterprise business intelligence systems over the years for many Fortune 500 companies and focuses his practice upon the integrated Microsoft Business Intelligence
LinkedIn: http://www.linkedin.com/in/sqlrockstar/
Contact: http://thomaslarock.com
Thomas LaRock is a Head Geek at SolarWinds and a Microsoft Certified Master, Data Platform MVP, VMware vExpert, and a Microsoft Certified Trainer. He has over 15 years’ experience in the IT industry in roles including programmer, developer, analyst, and database administrator.
LinkedIn: http://www.linkedin.com/pub/allen-white-sql-server-mvp/5/784/b08/
Contact: http://dataperfpro.com/blog/
Allen White is a Data Platform consultant. He has been both a developer and an administrator, so he understands both perspectives towards database technology. He loves sharing his experiences and helping people learn how to use SQL Server. Allen has spent over 40 years in IT, using SQL Server since 1992, and has been awarded Microsoft’s MVP Award for the last 13 years. Allen was a PASS Director from 2016 - 2018.
Contact: http://www.learnmicrosoftbi.com
Craig Utley is a Senior Architect with CTS and a former Program Manager with the SQL Server Customer Advisory Team (SQLCAT), where he focused on business intelligence. Craig has been involved in the Microsoft BI space since the betas of SQL Server 7.0 and has consulted on over 50 BI implementations worldwide, including the largest Microsoft data warehouse in the world. He is a former MVP in both SQL Server and C# and has written three books and more than 35 articles.
Tim Chapman is a Microsoft Certified Master (MCM) and works as a dedicated field engineer (PFE) at Microsoft specializing in performance tuning and high availability. Tim is from Louisville, KY and has over 12 years of database architecture, programming, and administration experience.
Contact: http://daytabase.org
I have been in IT since 1999 as an administrator, an analyst, an architect, a developer and, most recently, a manager for Elliott Tool Technologies LTD in Dayton OH. I have been managing and developing in SQL since Microsoft SQL Server 6.5 and have also handled applications running on Oracle, MySQL and IBM Universe. I guess you can call me a SQL addict. Fortunately, Elliott uses an ERP and other systems driven by MS SQL, and so my obsession for SQL can be quenched daily.
Michael Coles is a prolific writer on SQL Server topics. He has authored or coauthored several SQL Server developer titles including Expert SQL Server 2008 Encryption, Pro T-SQL 2008 Programmer's Guide and Pro Full-Text Search in SQL Server 2008. He has also written dozens of technical articles that have been published online and in print magazines. Michael is a Microsoft MVP (SQL) and holds MCST:SQL Server 2008 (database development), MCDBA and MCP+I certifications, with a Bachelors degree in Information Technology. Michael has over 15 years SQL Server experience and he is currently Chief ETL Architect for a BI consulting firm in New York.
LinkedIn: http://www.linkedin.com/in/randyknight
Contact: http://www.sqlsolutionsgroup.com/blog
Randy Knight is a data professional who has worked with Microsoft technology for over 25 years, focusing on SQL Server since 1997. He has worked in a variety of settings, including 6 years as a database architect for match.com. In 2010, he founded SQL Server Solutions Group LLC, a boutique SQL Server consultancy. A Microsoft Certified Master (MCM) in SQL Server, he speaks often at events all over the country including the PASS Summit, SQLIntersections, and numerous SQLSaturday and User Groups.
LinkedIn: http://www.linkedin.com/in/randyknight
Contact: http://www.sqlsolutionsgroup.com/blog
Randy Knight is a data professional who has worked with Microsoft technology for over 25 years, focusing on SQL Server since 1997. He has worked in a variety of settings, including 6 years as a database architect for match.com. In 2010, he founded SQL Server Solutions Group LLC, a boutique SQL Server consultancy. A Microsoft Certified Master (MCM) in SQL Server, he speaks often at events all over the country including the PASS Summit, SQLIntersections, and numerous SQLSaturday and User Groups.
LinkedIn: http://www.linkedin.com/in/louisdavidson
Contact: https://www.red-gate.com/simple-talk/author/louis-davidson/
Louis Davidson has worked in the IT industry for over 25 years as a corporate database developer and architect. He has been a Microsoft SQL Server MVP for 15 years and has written five books on database design, and contributed to many other SQL Server books as an author and tech editor. He has a bachelor's degree in Computer Science from the University of Tennessee at Chattanooga. You can read more about Louis at http://drsql.org.
Michael Coles is a prolific writer on SQL Server topics. He has authored or coauthored several SQL Server developer titles including Expert SQL Server 2008 Encryption, Pro T-SQL 2008 Programmer's Guide and Pro Full-Text Search in SQL Server 2008. He has also written dozens of technical articles that have been published online and in print magazines. Michael is a Microsoft MVP (SQL) and holds MCST:SQL Server 2008 (database development), MCDBA and MCP+I certifications, with a Bachelors degree in Information Technology. Michael has over 15 years SQL Server experience and he is currently Chief ETL Architect for a BI consulting firm in New York.
Contact: http://www.sqlservercentral.com/blogs/kathi_kellenberger/default.aspx
Kathi Kellenberger is a Data Technology Specialist with Microsoft in St. Louis, MO. Before joining Microsoft in 2010, she was a DBA and a SQL Server MVP. Kathi is author of "Beginning T-SQL 2008" and co-author of "Professional SQL Server 2005 Integration Services" and "SQL Server MVP Deep Dives." In her spare time, Kathi enjoys singing (she is the original #sqlkaroke), cycling, playing with her 5 year old grandson, and climbing the stairs in very tall buildings.
LinkedIn: http://www.linkedin.com/in/eddiewuerch
Contact: http://www.indydba.com
Eddie Wuerch has 20 years of experience as a SQL Server specialist in a much-longer IT career. A Microsoft Certified Master, Eddie spends his days in the Salesforce Marketing Cloud, focusing on performance, scale, and uptime for the massive SQL Server backend. These SQL Servers churn billions of transactions daily against trillions of rows of data in a 24x7 continuously-available online system accessed by millions worldwide every day.
Michael Coles is a prolific writer on SQL Server topics. He has authored or coauthored several SQL Server developer titles including Expert SQL Server 2008 Encryption, Pro T-SQL 2008 Programmer's Guide and Pro Full-Text Search in SQL Server 2008. He has also written dozens of technical articles that have been published online and in print magazines. Michael is a Microsoft MVP (SQL) and holds MCST:SQL Server 2008 (database development), MCDBA and MCP+I certifications, with a Bachelors degree in Information Technology. Michael has over 15 years SQL Server experience and he is currently Chief ETL Architect for a BI consulting firm in New York.
LinkedIn: https://www.linkedin.com/in/davefackler
Contact: http://davefackler.blogspot.com/
Dave Fackler is a business intelligence architect, focusing on enterprise data warehouse and business intelligence solutions using Microsoft technologies. Dave has helped organizations design and implement large-scale data warehouses, exploiting SQL Server enterprise database features using dimensional modeling design principles and best practices. He has also architected and developed several enterprise ETL processes using SSIS and its robust set of high-performance tasks and transformations. Dave has delivered various end-user reporting solutions using SSAS and SSRS, often coupled with SharePoint and Office components. Dave speaks about business intelligence at numerous technical conferences, user groups and professional groups each year.
Contact: http://www.programmersedge.com
Arie Jones 'AJ' is the Principal Technology Manager for Perpetual Technologies, Inc. in Indianapolis, IN. Arie leads PTI’s team of expert consultants in planning, design, development, deployment, and management of database environments and applications to achieve the best combination of tools and services for each client. Additionally, AJ is a community speaker, has written several books such as “Learn SQL in 24 Hours”, and blogs extensively at http://www.programmersedge.com
Contact: http://www.learnmicrosoftbi.com
Craig Utley is a Senior Architect with CTS and a former Program Manager with the SQL Server Customer Advisory Team (SQLCAT), where he focused on business intelligence. Craig has been involved in the Microsoft BI space since the betas of SQL Server 7.0 and has consulted on over 50 BI implementations worldwide, including the largest Microsoft data warehouse in the world. He is a former MVP in both SQL Server and C# and has written three books and more than 35 articles.
Tim Chapman is a Microsoft Certified Master (MCM) and works as a dedicated field engineer (PFE) at Microsoft specializing in performance tuning and high availability. Tim is from Louisville, KY and has over 12 years of database architecture, programming, and administration experience.
The following is a list of sponsors that helped fund the event.


Moody’s: German banking outlook changes to negative from stable as profitability weakens
by Dhwani MehtaThe US-based global rating agency, Moody’s Investors Service, revised down their outlook on the German banking system, with the key highlights found below.
"The creditworthiness of German banks is set to decline."
"Deposits are proving to be costly for German banks."
"German banks' profitability to weaken in a low-interest rate environment."
EUR/USD continues to trade around a flat line near 1.1075, as the shared currency shrugs-off the above report and awaits the ECB minutes amid looming trade uncertainty.


WebMidi Class
The WebMidi
object makes it easier to work with the Web MIDI API. Basically, it
simplifies two things: sending and receiving MIDI messages.
To send MIDI messages, you simply need to call the desired method (playNote()
,
sendPitchBend()
, stopNote()
, etc.) with the appropriate parameters and all the
native MIDI communication will be handled for you. The only additional thing that
needs to be done is enable WebMidi
. Here is an example:
WebMidi.enable(function() {
WebMidi.playNote(2, "C3");
});
The code above, calls the WebMidi.enable()
method. Upon success, this method
executes the callback function specified as a parameter. In this case, the callback
calls the playnote()
function to play a 3rd octave C (note number 60) on channel 2.
Receiving messages is just as easy. You simply have to set a callback function to be triggered when a specific MIDI message is received. For example, to listen for pitch bend events on any input MIDI channels:
WebMidi.addEventListener('pitchbend', function(e) {
console.log("Pitch value: " + e.value);
});
As you can see, this library makes it much easier to use the Web MIDI API. No need to manually craft or decode binary MIDI messages anymore!
Item Index
Methods
- addEventListener static
- enable static
- hasEventListener static
- noteNameToNumber static
- playNote static
- removeEventListener static
- send static
- sendChannelAftertouch static
- sendChannelMode static
- sendControlChange static
- sendKeyAftertouch static
- sendPitchBend static
- sendProgramChange static
- sendSystemMessage static
- sendSystemMessage static
- stopNote static
Methods
addEventListener
-
type
-
listener
-
[channel=all]
Adds an event listener that will trigger a function callback when the specified event happens. By default, the listener is system-wide (it will listen on all MIDI channels) but this can be changed by passing one or more specific channel(s) as the 3rd parameter.
Here is a list of events that are dispatched by the WebMidi
object and that can be
listened to.
Channel-specific MIDI events:
- noteoff
- noteon
- keyaftertouch
- controlchange
- channelmode
- programchange
- channelaftertouch
- pitchbend
System-wide MIDI events:
- sysex
- timecode
- songposition
- songselect
- tuningrequest
- clock
- start
- continue
- stop
- activesensing
- reset
- unknownsystemmessage
Interface event:
- statechange
For system-wide events, the specified channel (if any) will be silently ignored. The value "all" will be used instead.
Parameters:
Returns:
Returns the WebMidi
object so methods can
be chained.
Throws:
The specified event type is not supported.
enable
-
successHandler
-
[errorHandler]
-
[sysex=false]
Checks if the Web MIDI API is available and then tries to connect to the host's MIDI
subsystem. If the operation succeeds, the successHandler
callback is executed.
If not, the errorHandler
callback is executed and passed a string describing the
error.
Depending on the host environment, calling this method may prompt the user for authorization.
hasEventListener
-
type
-
listener
-
[channel=all]
Checks if the specified event type is already defined to trigger the listener
function on the specified channel. If the special value "all" is used for the
channel, the function will return true
only if all channels have the listener
defined.
For system-wide events (onstatechange
, sysex
, start
, etc.), the channel
parameter is silently ignored.
Parameters:
Returns:
Boolean value indicating whether or not the channel(s) already have this listener defined.
Throws:
WebMidi must be enabled before checking event listeners.
noteNameToNumber
-
name
Returns a MIDI note number matching the note name passed in the form of a string parameter. The note name must include the octave number which should be between -2 and 8: C5, G4, D#-1, F0, etc.
Parameters:
-
name
StringThe name of the note in the form of a letter, followed by an optional # symbol, followed by the octave number (between -2 and 8).
Returns:
The MIDI note number.
playNote
-
channel
-
[note=60]
-
[velocity=0.5]
-
[duration=undefined]
-
[delay=0]
Requests the playback of a single note or multiple notes on the specified channel.
You can delay the execution of the note on
command by using the delay
parameter
(milliseconds).
If no duration is specified, the note will play until a matching note off
is sent.
If a duration is specified, a note off
will be automatically executed after said
duration.
Please note that if you do use a duration, the release velocity will always be 64. If
you want to tailor the release velocity, you need to use separate playNote()
and
stopNote()
calls.
Parameters:
-
channel
UintThe MIDI channel number (between 0 and 15). You can view available channels in the
WebMidi.outputs
array. -
[note=60]
Array | Uint | String optionalThe note to play or an array of notes to play. The notes can be specified in one of two ways. The first way is by using the MIDI note number (an integer between 0 and 127). The second way is by using the note name followed by the octave (C3, G#4, F-1). The octave range should be between -3 and 5.
-
[velocity=0.5]
Number optionalThe velocity at which to play the note (between 0 and 1).
-
[duration=undefined]
Int optionalThe number of milliseconds to wait before sending a matching note off event. If left undefined, only a note on is sent.
-
[delay=0]
Int optionalThe number of milliseconds to wait before actually sending the
note on
command (using a negative number or 0 will send the command immediately).
Returns:
Returns the WebMidi
object so methods can be
chained.
Throws:
The velocity must be a decimal number between 0 and 1.
removeEventListener
-
type
-
listener
-
[channel=all]
Removes the specified listener from the requested channel(s). If the special value "all" is used for the channel parameter, the function will remove the listener from all channels.
For system-wide events (onstatechange
, sysex
, start
, etc.), the channel
parameter is silently ignored.
Parameters:
Throws:
WebMidi must be enabled before removing event listeners.
send
-
channel
-
command
-
[data=[]]
-
[timestamp=0]
Sends a MIDI message to one or all channels at the specified timestamp. Unless, you
are familiar with the details of the MIDI message format, you should not use this
method directly. Instead, use one of the helper methods: playNote()
, stopNote()
,
sendControlChange()
, sendSystemMessage()
, etc.
Parameters:
-
channel
"all" | UintThe MIDI channel number (between 0 and 15) or the string "all". You can view the available channels in
WebMidi.outputs
. -
command
UintThe command number. Check out the constants in the WebMidi object for a list of available commands (0-255).
-
[data=[]]
Array optionalArray of data bytes. The number of data bytes varies depending on the command.
-
[timestamp=0]
DOMHighResTimeStamp optionalThe timestamp at which to schedule the event. You can use
WebMidi.time
to retrieve the current timestamp.
Returns:
Returns the WebMidi
object so methods can be
chained.
Throws:
The command must be an integer between 0 and 255.
sendChannelAftertouch
-
channel
-
[pressure=0]
-
[delay=0]
Sends a MIDI channel aftertouch
message to the specified channel. For key-specific
aftertouch, instead use sendKeyAftertouch()
.
Parameters:
-
channel
UintThe MIDI channel number (between 0 and 15). You can view available channels in the
WebMidi.outputs
array. -
[pressure=0]
Number optionalThe pressure level (between 0 and 1)
-
[delay=0]
Int optionalThe number of milliseconds to wait before actually sending the
key aftertouch
command (using a negative number or 0 will send the command immediately).
Returns:
Returns the WebMidi
object so methods can be chained.
Throws:
WebMidi must be enabled before sending messages.
sendChannelMode
-
channel
-
command
-
value
-
[delay=0]
Sends a MIDI channel mode
message to the specified channel.
Parameters:
-
channel
UintThe MIDI channel number (between 0 and 15). You can view available channels in the
WebMidi.outputs
array. -
command
UintThe MIDI channel mode command (120-127)
-
value
UintThe value to send (0-127)
-
[delay=0]
Int optionalThe number of milliseconds to wait before actually sending the
key aftertouch
command (using a negative number or 0 will send the command immediately).
Returns:
Returns the WebMidi
object so methods can be chained.
Throws:
Value must be between 0 and 127.
sendControlChange
-
channel
-
controller
-
value
-
[delay=0]
Sends a MIDI control change
message to the specified channel.
Parameters:
-
channel
UintThe MIDI channel number (between 0 and 15). You can view available channels in the
WebMidi.outputs
array. -
controller
UintThe MIDI controller number (0-119)
-
value
UintThe value to send (0-127).
-
[delay=0]
Int optionalThe number of milliseconds to wait before actually sending the
key aftertouch
command (using a negative number or 0 will send the command immediately).
Returns:
Returns the WebMidi
object so methods can be chained.
Throws:
Value must be between 0 and 127.
sendKeyAftertouch
-
channel
-
note
-
[pressure=0]
-
[delay=0]
Sends a MIDI key aftertouch
message to the specified channel. This is a
key-specific aftertouch. For a channel-wide aftertouch message, use
sendChannelAftertouch()
.
Parameters:
-
channel
UintThe MIDI channel number (between 0 and 15). You can view available channels in the
WebMidi.outputs
array. -
note
UintThe MIDI number of the note whose pressure data is being sent (0-127).
-
[pressure=0]
Number optionalThe pressure level to send (between 0 and 1)
-
[delay=0]
Int optionalThe number of milliseconds to wait before actually sending the
key aftertouch
command (using a negative number or 0 will send the command immediately).
Returns:
Returns the WebMidi
object so methods can be chained.
Throws:
The note number must be between 0 and 127.
sendPitchBend
-
channel
-
[level=-1]
-
[delay=0]
Sends a MIDI pitch bend
message to the specified channel.
Parameters:
-
channel
UintThe MIDI channel number (between 0 and 15). You can view available channels in the
WebMidi.outputs
array. -
[level=-1]
Number optionalThe intensity level of the bend (between -1 and 1)
-
[delay=0]
Int optionalThe number of milliseconds to wait before actually sending the
key aftertouch
command (using a negative number or 0 will send the command immediately).
Returns:
Returns the WebMidi
object so methods can be chained.
Throws:
Pitch bend value must be between -1 and 1.
sendProgramChange
-
channel
-
program
-
[delay=0]
Sends a MIDI program change
message to the specified channel.
Parameters:
-
channel
UintThe MIDI channel number (between 0 and 15). You can view available channels in the
WebMidi.outputs
array. -
program
UintThe MIDI patch (program) number (0-127)
-
[delay=0]
Int optionalThe number of milliseconds to wait before actually sending the
key aftertouch
command (using a negative number or 0 will send the command immediately).
Returns:
Returns the WebMidi
object so methods can be chained.
Throws:
Program numbers must be between 0 and 127.
sendSystemMessage
-
manufacturer
-
[data=[]]
-
[delay=0]
Sends a system exclusive message to all connected devices. The message will automatically be properly terminated. It is generally suggested to keep system exclusive messages to 64Kb or less.
Parameters:
-
manufacturer
Uint | ArrayA uint or an array of three uints between 0 and 127 that identifies the targeted manufacturer.
-
[data=[]]
Array optionalAn array of uints between 0 and 127. This is the data you wish to transfer.
-
[delay=0]
Uint optionalThe number of milliseconds to wait before actually sending the command (using 0 will send the command immediately).
Returns:
Returns the WebMidi
object so methods can be
chained.
Throws:
WebMidi must be enabled sending messages.
sendSystemMessage
-
command
-
[data=[]]
-
[delay=0]
Sends a MIDI real-time or common system message to all available outputs. The available messages are as follows:
System common messages:
sysex timecode songposition songselect tuningrequest sysexend
System real-time messages:
clock start continue stop activesensing reset
Parameters:
-
command
StringA string representing the command to send. The available system commands are: sysex, timecode, songposition, songselect, tuningrequest, sysexend, clock, start, continue, stop, activesensing and reset.
-
[data=[]]
Array optionalAn array of data bytes to insert in the message. The number of data bytes varies depending on the command.
-
[delay=0]
Uint optionalThe number of milliseconds to wait before actually sending the command (using 0 will send the command immediately).
Returns:
Returns the WebMidi
object so methods can be chained.
Throws:
The requested system command is not supported.
stopNote
-
channel
-
[note=60]
-
[velocity=0.5]
-
[delay=0]
Sends a MIDI note off
message to the specified channel for a single note or
multiple notes. You can delay the execution of the note off
command by using the
delay
parameter (milliseconds).
Parameters:
-
channel
UintThe MIDI channel number (between 0 and 15). You can view available channels in the
WebMidi.outputs
array. -
[note=60]
Array | Uint | String optionalThe note or an array of notes to stop. The notes can be specified in one of two ways. The first way is by using the MIDI note number (an integer between 0 and 127). The second way is by using the note name followed by the octave (C3, G#4, F-1). The octave range should be between -3 and 5.
-
[velocity=0.5]
Number optionalThe velocity at which to release the note (between 0 and 1).
-
[delay=0]
Int optionalThe number of milliseconds to wait before actually sending the
note off
message (using a negative number or 0 will stop the note immediately).
Returns:
Returns the WebMidi
object so methods can be
chained.
Throws:
The release velocity must be a decimal number between 0 and 1.
Properties
connected
Boolean
static
[read-only] Indicates whether the interface to the host's MIDI subsystem is still active.
inputs
MIDIOutput
static
[read-only] An array of all currently available MIDI outputs.
supported
Boolean
static
[read-only] Indicates whether the browser supports the Web MIDI API or not.
time
DOMHighResTimeStamp
static
[read-only] Current MIDI performance time in milliseconds. This can be used to queue events in the future.
Events
activesensing
Event emitted when a system active sensing MIDI message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
channelaftertouch
Event emitted when a channel-wide aftertouch MIDI message has been received on a specific channel.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
channel
UintThe channel where the event occurred (between 0 and 15).
-
type
StringThe type of event that occurred.
-
value
NumberThe aftertouch value received (between 0 and 1).
-
channelmode
Event emitted when a channel mode MIDI message has been received on a specific channel.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
channel
UintThe channel where the event occurred (between 0 and 15).
-
type
StringThe type of event that occurred.
-
controller
Object-
number
UintThe number of the controller. -
name
StringThe number of the controller.
-
-
value
UintThe value received (between 0 and 127).
-
clock
Event emitted when a system timing clock MIDI message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
continue
Event emitted when a system continue MIDI message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
controlchange
Event emitted when a control change MIDI message has been received on a specific channel.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
channel
UintThe channel where the event occurred (between 0 and 15).
-
type
StringThe type of event that occurred.
-
controller
Object-
number
UintThe number of the controller. -
name
StringThe number of the controller.
-
-
value
UintThe value received (between 0 and 127).
-
keyaftertouch
Event emitted when a key-specific aftertouch MIDI message has been received on a specific channel.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
channel
UintThe channel where the event occurred (between 0 and 15).
-
type
StringThe type of event that occurred.
-
note
Object-
number
UintThe MIDI note number. -
name
StringThe usual note name (C, C#, D, D#, etc.). -
octave
UintThe octave (between -3 and 5).
-
-
value
NumberThe aftertouch amount (between 0 and 1).
-
noteoff
Event emitted when a note off MIDI message has been received on a specific channel.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
channel
UintThe channel where the event occurred (between 0 and 15).
-
type
StringThe type of event that occurred.
-
note
Object-
number
UintThe MIDI note number. -
name
StringThe usual note name (C, C#, D, D#, etc.). -
octave
UintThe octave (between -3 and 5).
-
-
velocity
NumberThe release velocity (between 0 and 1).
-
noteon
Event emitted when a note on MIDI message has been received on a specific channel.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
channel
UintThe channel where the event occurred (between 0 and 15).
-
type
StringThe type of event that occurred.
-
note
Object-
number
UintThe MIDI note number. -
name
StringThe usual note name (C, C#, D, D#, etc.). -
octave
UintThe octave (between -3 and 5).
-
-
velocity
NumberThe attack velocity (between 0 and 1).
-
pitchbend
Event emitted when a pitch bend MIDI message has been received on a specific channel.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
channel
UintThe channel where the event occurred (between 0 and 15).
-
type
StringThe type of event that occurred.
-
value
NumberThe pitch bend value received (between -1 and 1).
-
programchange
Event emitted when a program change MIDI message has been received on a specific channel.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
channel
UintThe channel where the event occurred (between 0 and 15).
-
type
StringThe type of event that occurred.
-
value
UintThe value received (between 0 and 127).
-
reset
Event emitted when a system reset MIDI message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
songposition
Event emitted when a system song position pointer MIDI message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
songselect
Event emitted when a system song select MIDI message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
song
StringSong (or sequence) number to select.
-
start
Event emitted when a system start MIDI message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
statechange
Event emitted when the interface's state changes. Typically, this happens when a MIDI device is being plugged or unplugged. This event cannot be listened on a specific MIDI channel, it is intended to be interface-wide. If a channel is specified, it will be silently ignored.
stop
Event emitted when a system stop MIDI message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
sysex
Event emitted when a system exclusive MIDI message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
timecode
Event emitted when a system MIDI time code quarter frame message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
tuningrequest
Event emitted when a system tune request MIDI message has been received.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-
unknownsystemmessage
Event emitted when an unknown system MIDI message has been received. It could be, for example, one of the undefined/reserved messages.
Event Payload:
-
event
Object-
target
MIDIInputThe target MIDI input where the event occurred.
-
data
Uint8ArrayThe raw MIDI message as an array of 8 bit values.
-
receivedTime
NumberThe time when the event occurred (in milliseconds since start).
-
timeStamp
UintThe timestamp when the event occurred (in milliseconds since the epoch).
-
type
StringThe type of event that occurred.
-


| Tips |
Preserve
extra grass seed by keeping it dry. Tape boxes and bags
closed, or seal them into plastic bags. Be sure to remove
extra air from the bags. Store all seed in a cool, dry area
such as a garage or basement. |
|
|
| Specials |
|
Bonsai Tree
$30.00 each
|
Red Delicious Strawberries
$3.50 (50 seeds)
|
Tulips
$17.00 (10 bulbs)
|
|


Squinty, the Comical Pig
by Richard Barnum
Chapter 3: “Squinty is Lost”
Additional Information
- Year Published: 1915
- Language: English
- Country of Origin: United States of America
- Source: Barnum, R. (1915). Squinty, the comical pig. New York: Barse and Hopkins.
-
Readability:
- Flesch–Kincaid Level: 3.5
- Word Count: 2,224
- Genre: Fantasy
- Keywords: children's stories
- ✎ Cite This
Downloads
This was the second time Squinty had run out of the pen and into the farmer’s garden. The first time he had been caught and brought back by Don, the dog. This time Squinty did not intend to get caught, if he could help it.
So, after crawling out through the hole under the pen, the little pig came to a stop, and looked carefully on all sides of him. His one little squinty eye was opened as wide as it would open, and the other eye was opened still wider. Squinty wanted to see all there was to be seen.
He cocked one ear up in front of him, to listen to any sounds that might come from that direction, and the other ear he drooped over toward his back, to hear any noises that might come from behind him.
What Squinty was especially listening for was the barking of Don, the dog.
 It will be time enough to go back to the pen when it is dark. Yes, that will be time enough,” for of course Squinty did not think of staying out after the sun had gone down. Or, at least, he did not imagine he would.
But you just wait and see what happens.
Squinty looked carefully about him. Even if one eye did droop a little, he could still see out of it very well, and he saw no signs of Don, the big dog. Nor could Squinty hear him.
Don must be far away, the little pig thought, far away, perhaps taking a swim in the brook, where the dog often went to cool off in hot weather.
“I think I’ll go and have a swim myself,” thought Squinty. He knew there was a brook somewhere on the farm, for he could hear the tinkle and fall of the water even in the pig pen. But where the brook was he did not know exactly.
“But it will be an adventure to hunt for it,” Squinty thought. “I guess I can easily find it. Here I go!” and with that he started to walk between the rows of potatoes.
Squinty made up his little mind that he was going to be very careful. Now that he was safely out of the pen again he did not want to be caught the second time. He did not want Don, or the farmer, to see him, so he crawled along, keeping as much out of sight as he could.
“I wish my brothers, Wuff-Wuff or Squealer were with me,” said Squinty softly to himself, in pig language. “But if I had awakened them, and asked them to run away with me, mamma or papa might have heard, and stopped us.”
Squinty did not feel at all sorry about running away and leaving his father and mother, and brothers and sisters. You see he thought he would be back with them again in a few hours, for he did not intend to stay away from the pen longer than that. But many things can happen in a few hours, as you shall see.
 “To pull up any of it, and eat it now, would make it wiggle. Then Don or the farmer might see it wiggling, and run over to find out what it was all about. Then I’d be caught. I’ll wait a bit.”
So, though he was very hungry, he would not eat a bit of the pig weed that grew near the pen. And he never so much as dreamed of taking any of the farmer’s potatoes. He did not yet know the taste of them. But, let me tell you, pigs who have eaten potatoes, even the little ones the farmer cannot sell, are very fond of them. But, so far, Squinty had never eaten even a little potato.
On and on went the little pig, looking back now and then toward the pen to see if any of the other pigs were coming after him. But none were.
And there was no sign of Don, the barking dog, nor the farmer, either. There was nothing to stop Squinty from running away. Soon he was some distance from the pen, and then he thought it would be safe to nibble at a bit of pig weed. He took a large mouthful from a tall, green plant.
“Oh, how good that tastes!” thought Squinty. “It is much better and fresher than the kind the farmer throws into the pen to us.”
Perhaps this was true, but I imagine the reason the pig weed tasted so much better was because Squinty was running away.
Perhaps you know how it is yourself.  If you ever did, you probably thought that bread and jam was much nicer than the kind you could get at home, though really there isn’t any better bread and jam than mother makes. But, somehow or other, the kind you get away from home tastes differently, doesn’t it?
It was that way with Squinty, the comical pig. He ate and ate the pig weed, until he had eaten about as much as was good for him. And then, as he saw one little potato on the ground, where it had rolled out of the hill in which it grew with the others, Squinty ate that. He did not think the farmer would care.
“Oh, how good it is!” he thought. “I wish I had not eaten so much pig weed, then I could eat more of those funny, round things the farmer calls potatoes. Now I will have to wait until I am hungry again.”
Squinty knew that would not be very long, for pigs get hungry many times a day.  But eating often is not good for boys and girls.
Squinty had now come some distance away from the pen, where he lived with his mother, father, sisters and brothers. He wondered if they had awakened yet, or had seen the hole out of which he had crawled, and if they were puzzled as to where he had gone.
“But they can’t find me!” said Squinty, with something that sounded like a laugh. I suppose pigs can laugh—in their own way, at any rate.
“No, they can’t find me,” thought Squinty, looking all around. All he saw were the rows of potato vines, and, farther off, a field of tall, green corn.
“Well, I have the whole day to myself!” thought Squinty. “I can do as I please, and not go back until night. Let me see, what shall I do first? I guess I will go to sleep in the shade.”
So he stretched out in the shade of a big potato vine, and, curling up in a little pink ball, he closed his eyes, the squinty one as well as the good one. But first Squinty looked all around to make sure Don, the dog, was not in sight. He saw nothing of him.
When Squinty awakened he felt hungry, as he always did after a sleep.
“Now for some more of those nice potatoes!” he said to himself. He liked them, right after his first taste. He did not look around for the little ones that might have fallen out of the hills themselves. No, instead, Squinty began rooting them out of the earth with his strong, rubbery nose, made just for digging.
I am not saying Squinty did right in this. In fact he did wrong, but then he was a little pig, and he knew no better. In fact it was the first time he had really run away so far, and he was quite hungry.
Squinty ate as many potatoes as he wanted, and then he said to himself, in a way pigs have:
“Well, I guess I’ll go on to the brook, and cool off in the water. That will do me good. After that I’ll look around and see what will happen next.”
Squinty had a good nose for smelling, as most animals have, and, tilting it up in the air, Squinty sniffed and snuffed. He wanted to smell the water, so as to take the shortest path to the brook.
“Ha! It’s right over there!” exclaimed Squinty to himself. “I can easily find the water to take a bath.”
Across the potato field he went, taking care to keep well down between the rows of green vines, for he did not want to be seen by the dog, or the farmer.
Once, as Squinty was walking along, he saw what he thought was another potato on the ground in front of him. He put his nose out toward it, intending to eat it, but the thing gave a big jump, and hopped out of the way.
“Ha! That must be one of the hop toads I heard my mother tell about,” thought Squinty. “I must not hurt them, for they are good to catch the flies that tickle me when I try to sleep. Hop on,” he said to the toad. “I won’t bother you.”
The toad did not stop to say anything. She just hopped on, and hid under a big stone. Maybe she was afraid of Squinty, but he would not have hurt her.
Soon the little pig came to the brook of cool water, and after looking about, to see that there was no danger near, Squinty waded in, and took a long drink. Then he rolled over and over again in it, washing off all the mud and dirt, and coming out as clean and as pink as a little baby. Squinty was a real nice pig, even if he had run away.
“Let me see,” he said to himself, after his bath. “What shall I do now? Which way shall I go?”
Well, he happened to be hungry after his swim. In fact Squinty was very often hungry, so he thought he would see if he could find anything more to eat.
“I have had potatoes and pig weed,” he thought, “and now I would like some apples. I wonder if there are any apple trees around here?”
He looked and, across the field of corn, he thought he saw an apple tree. He made up his mind to go there.
And that is where Squinty made another mistake. He made one when he ran away from the pen, and another one when he started to go through the corn field.
Corn, you know, grows quite high, and pigs, even the largest of them, are not very tall. At least not until they stand on their hind legs. That was a trick Squinty had not yet learned. So he had to go along on four legs, and this made him low down.
Now he had been able to look over the tops of the potato vines, as they were not very high, but Squinty could not look over the top of the corn stalks. No sooner had he gotten into the field, and started to walk along the corn rows, than he could not see where he was going. He could not even see the apple tree in the middle of the field.
“Well, this is queer,” thought Squinty. “I guess I had better go back. No, I will keep on. I may come to the apple tree soon.”
He hurried on between the corn rows. But, though he went a long distance, he did not come to the apple tree.
“I guess I will go back to the brook, where I had my bath, and start over again from there,” thought Squinty. “I will not try to get any apples to-day.  Yes, I will go back.”
But that was not so easy to do as he had thought. Squinty went this way and that, through the rows of corn, but he could not find the brook. He could not find his way back, nor could he find the apple tree. On all sides of him was the tall corn. That was all poor Squinty could see.
 I guess I am lost!”


Dear Bonkers Maisie, thou art so fair.

The day was windy, cold, and wet.

Oh Bonkers Maisie, my countryside belle!
They locked you up in the potting shed.
Poisoned by lead, poisoned by lead.


{0}
Date: {1,date,full}
Customer: {2}
Report Number: {3}
{4}
Selected Data
{5}
Signature:
Date: {1,date,full}


{% extends "base.html" %} {% block content %} Forgot to add something to your cart? Look around and come back when you're ready! Come Back to Us {% endblock %}


Time Remaining: 15 seconds
Instructions: This is a trivia game meant to test your knowledge of Denver, CO. After clicking on the start button, you will have 20 seconds to answer each multiple-choice question, a total of 10 questions. At the end of the game, you can see how well you know the Mile High City.


Downloads
Choose a version to download:
Mac
Windows
Thanks to Install4J:
Install4J multi-platform installer builder


User research, UX, Information Design, Wireframes, Interaction Design, High Fidelity Prototyping. Revamped the UX and UI completely for the mobile app. Lead the redesign initiative.
We were maintaining a log of pain points (across the app) internally, noting down the pain points we need to address. Even before the redesign effort commenced, we had a good sense of our users’ pain points:
We didn’t just want to address the major pain points, we wanted to refresh the identity of the app and build a simple, frictionless experience for our users.
Our users found the old UI confusing and overwhelming. They spent more 7 seconds understanding the form and over 400 seconds to complete the process. We had users reporting not finding particular fields / calls-to-action, when in fact they were present. Often they had to return to the form, since they missed certain details.
We realised our users were scanning instead of reading. The first thing users did when they saw the form was, estimate how long it would take to complete it. Perception was crucial. When they saw too many fields, they were quick to abandon the process.
The old design presented all the fields stacked one below the other. The lack of hierarchy and structure and an increasing number of fields, made the form difficult to comprehend. The mental and physical load on the user were too high.
Our users were hesitant to fill out forms. So, our goal was to make the process of filling out a form as easy as possible. We looked to avoid clutter and build on existing mental models of our users. We used a simple layout to make it look familiar and reduce the amount of learning.
In the old app a lot of information was buried, making it difficult to view the critical observations. Managers told us what information was valuable to them and when it is most useful to see them. They wanted to see Observation Title, Status, Due Date, Priority and Assigneé. On-site engineers wanted to see ID and type as well.
We wanted to provide all these data points in one place, to help users decide which observation to dive into. After a lot of chopping and changing, we eventually landed on a consolidated card structure with all these data points.
In the old design, the details page lacked any structure and hierarchy. The elements were ill-ordered and frustrated users. Important data points lacked emphasis and related data points weren’t grouped. (For example, the status field followed the location field and was buried in the form).
Our goal was simple. We wanted to craft a details page with a simple structure, that provided the right amount of information (too much data can overwhelm while too little can cause confusion). We wanted users to quickly understand what they see and find what they want in a glance. We wanted the page to resemble a conversation.
The old app was confusing and not functional, as a result of which it was hardly used. In the redesign, we were careful to track every nuance and detail. One thing we did was, considered the context of use. We knew that a lot of our users will be using the app outdoors. Here are some insights,
We iterated a lot to decide what information to present, which actions to highlight. We ensured that the text was comfortably legible at an arm’s distance.
This meant that the common practice of placing low-priority and dangerous actions at the top left corner of the screen wouldn’t work. To tackle this, when we warranted (such as when a user is closing an observation), we used modal boxes for confirmation to protect the user.
We maintained a healthy contrast ratio of fields so that the content is easier to perceive. We tested our designs with an online color contrast calculator. We restructured information, so that the important information was always front and center. We designed prominent calls-to-action and ample touch targets, so that they are easier to identify and tap.
I learnt that data visualisation is very interdisciplinary. I learnt that each visualisation always started with the data.
While working on this redesign, I tried to have a dialog with the data; Poking at it, looking at it from different perspectives. We tried a number of ways to visualise the data, until we stumbled upon one way that made sense and was most useful to the user. Here are some questions we kept asking ourselves,
Here’s a quote that I stumbled upon, “The more you know your user the better the design will be.”


--- title: "Appointment to Burnet Institute" author: "Mark Ziemann" date: 2023-08-04 categories: ["Careers"] tags: ["Deakin","Burnet"] ---
After five years at Deakin University I’m excited to announce that I will take on a new position at Burnet Institue as Head of Bioinformatics.
Deakin has been very good to me and has supported me throughout this time. At Deakin I was a Lecturer and Senior Lecturer in Biotechnology and Bioinformatics. In that role I was teaching primarily into the Masters of Biotechnology and Bioinformatics course, with some additional undergraduate units. I completed a Graduate Certificate in Higher Education, which helped me to become a better teacher. I also maintained a research group which became increasingly focused on bioinformatics. There was a restructure, and I became Course Director of Master of Biotechnology and Bioinformatics. At about the same time the course enrolments were paused for an overhaul of the curriculum and course design which I was deeply involved in. Over time, my time was taken up mostly by teaching and administration, and time for research had a low priority which did not agree with me.
The new role at Burnet is a dream job for me because I feel that my strengths in teaching, training and supervision can be applied for maximum benefit to build bioinformatics capacity at this world-leading institute. There are organisations that are seeing that data analysis capabilities are going to be essential to maintaining competitiveness, and those that invest in this area are going to be at the forefront of what they do, whether that is in business or research.


Biomorph - 1
Biological forms
generated from
Mathematical Feedback Loops
.
z = x + yi
z
n+1
= z
n
3
+ 0.5
x, y
range
n
Coordinates on complex plane
[-3.3 - 2.5i] to [3.3 + 2.5i]
Iteration with limit 1000


{{ receiver }}, {{ answerer }} {% trans "has answered your question" %} {% source_display answer "email" "#010101"%}{% trans ":" %}
{% endblock %}
{% block body_answer %}
{% include "items/feed_display/_answer.html" with display="email_html" content=answer %}
{% endblock %}
{% block extra_body %}
{% trans "Click here to see the answer on NewCo." %}
{% endblock %}


I'm A Celebrity host Dec blames James Haskell for failing 'impossible' trial
I'm A Celebrity host Dec Donnelly said James Haskell chose the wrong box to start with in the live trial
by Irishmirror.ieI'm A Celebrity host Dec Donnelly stood by his claim that the "impossible" live Bushtucker Trial was doable, as he appeared to blame contestant James Haskell for messing up.
James and campmate Roman Kemp had to retrieve three stars screwed down in three boxes, all containing different creatures.
Unable to complete the challenge in the set amount of time, it meant Ian Wright, Cliff Parisi and Andy Whyment did not get a roast dinner.
Viewers hit out at the show, with Ant and Dec also receiving a backlash from fans who claimed the task and result was unfair.
They believed the challenge was "impossible", something the hosts denied given the stand-ins managed to complete it during the rehearsals.
Ant and Dec even mocked the backlash in a sketch during the latest episode.
Speaking on spin-off series Extra Camp though, Dec repeated that the trial was possible, before suggesting it was the campmates' fault for not being successfull.
Ant joked it was down to James' "sausage fingers" for not finishing the task, while Dec implied his technique was to blame.
Dec said: "As I said on social media it was done in the block through, and rehearsal. The stand-ins did it.
"It was able to be completed."
He then quipped: "Why he started with the crab which is the hardest box and the furthest one away, I don't know."
Ant then joked: "It's cos he's got sausage fingers."
Viewers were still convinced that the challenge was "unfair", and that it wasn't James or Roman's fault they didn't complete their challenge.
Fans called for Ian, Cliff and Andy to still get their roast dinners, as others said the trial was a "fix".
Caitlyn ended up smuggling some food into camp for Ian, with Ant hinting the pair would be punished.
I'm A Celebrity airs nightly at 9pm on ITV.


In order to develop a MIDI sequence with a Music Programming Language using Midica, you must write the source code into a plain text file
with the file extension .midica
, .mpl
, .alda
or .abc
, depending on the language you want to use.
It doesn't matter which editor you use. Just use your favorite text editor.
If you choose MidicaPL for programming, than the actual language syntax and note naming depends on
the chosen configuration. In this tutorial the configuration settings shown in the
Configuration table are assumed.
This is the default configuration. But it can be changed in the Configuration
area in the main window (upper left corner).
For ALDA or ABC, the configuration doesn't matter.
During the development process you will switch from your editor to the Midica player very often.
You will change the file and save it in the editor, then switch to the player and hit the Reparse
button or press F5
.
Then the file will be parsed again. When hitting the Play
button or pressing p
or the space bar,
the resulting MIDI sequence will be played.
First of all you have to create the file. Just create an empty file and call it tutorial.midica
or something else with the file extension .midica
or .mpl
.
(Or test.alda
or something.abc
if you prefer to write in ALDA or ABC.)
Then start Midica, if not yet done. In the main window, press the upper right button. It's the select file
button in the import area. Switch to the right tab, if not yet done (e.g. MidicaPL
if you use MidicaPL).
Then choose the empty file that you have just created.
Now you can open the player with the button Start Player
.
You cannot play anything yet because the file is still empty and so the MIDI sequence is empty as well.
But now you can start your development cycle.
Begin with chapter 1 of the MidicaPL tutorial. (Or a different tutorial for ALDA or ABC.)
Follow the instructions and change the source file
according to the examples. Then switch to the player and press Reparse
or F5
, then play the sequence.
Then change the file again. Try out your own variations of the examples and so on...
Developing with Midica is a bit like developing a website. But the HTML editor is any text editor. And the browser is the player.
But F5 works similarly.


I think Twitter is very good as an information gathering tool. Especially technical information is fastest and easy to grab via Twitter.
I wanna use Twitter but feel a little bad about browsing it lordly during working time.
So I created a simple and quiet twitter client.
This is a text based tool and doesn't have images on the timeline.
Worc is published on GitHub.
Mac or Windows users can download from the top link of this page.
After downloading it, you need to open it from right click because this application is unsigned.
If you find some bugs or proposals, please register them to the GitHub.


react-aria-menubotton demo
Some interactions you should try
-
Click the trigger to toggle the menu.
-
With focus on the trigger, press Enter or Space to toggle the menu.
-
With focus on the trigger and the menu closed, press ArrowDown to open the menu and move focus to the first menu item.
-
With the menu opened, press ArrowDown or ArrowUp to cycle focus through the menu items.
-
With the menu opened, press a letter key to move focus to the next menu item whose label begins with that letter.
-
With the menu opened, click a menu item to fire the handler.
-
With the menu opened, use the keyboard to move focus to a menu item and press Enter or Space to fire the handler.
-
With the menu opened (which means focus is either on the trigger or a menu item), move focus outside of the menu — by clicking outside of it or pressing Tab — to close the menu.
-
With focus inside the menu, press Escape to close the menu and return focus to the trigger.
Keyboard interactions follow the
WAI-ARIA Design Pattern for
Menu Button.
Possibilities for Fanciness
You can include opening/closing animation (via ReactTransitionGroup) and use components as the content of menu items. Whichs means nothing can stop you.
Icons from Ballicons by PixelBuddha.
Please take note of a few things:
-
There is snazzy open/close animation.
-
You can use a React element as content for the menu button or any menu item.
-
You can still type a letter on the keyboard to navigate to the relevant item (because of metadata fed to these items).
-
Unlike the menu above, this one closes as soon as you make a selection (that's an option).
Great, now what do I do?
Go back to the repo


{{- define "main" -}}
Hi! I'm Stefano.
Enterprising Computer Scientist with a passion for AI and software development.
I'm a {{ .definition }}
{{ .description }}


This tests the SOS.App default application from the SOS.Ui.js module. The SOS.App pulls together the various UI components, such as SOS.Map, SOS.Plot etc. into an application to enable browsing, visualisation, and access, of SOS data.
Select a station from the map. Select an offering, then an observed property. The observed property's data will then be plotted and tabulated. By default, a rolling month's worth of data is shown, but specific dates can be selected via the Date Range controls under the Controls menu item. To overplot further data, check the Add To Existing control before selecting an additional observed property.


Toll Registration Information
VehicleNumber
Source
Destination
TollName
OneWay
TwoWay
Payment
{% for row in rows %}
{{row}}
{% endfor %}
Go back to home page


Nuvi Johnson
About
Portfolio
Contact
Portfolio
Hangman
RPG Game
Trivia Game
Rutgers Info Widget
Rock Paper Scissors


Request: More floater display prefs
-
Krypton
I know this is probably on your to-do list, but I thought I'd mention it all the same. I'd quite like to see prefs for:
Fade in/Don't fade in Fade out/Don't fade out Continuous sizes between smallest and medium size
-
Krypton
Also:
Ability to turn off floater shadow - noticed this doesn't cause all the redraw problems with other apps.
-
anonymous
I'd like to see an option to display the floater at the end of the song in addition to the beginning.
-
sebster
Quote: I'd like to see an option to display the floater at the end of the song in addition to the beginning.
Yes, this would be extremely cool - I would use it as a reminder to rate the song before it's over...is it possible to implement this in a future version?
-
anonymous
Personally, I'd love to see the ability to keep the floater (on the desktop, or somewhere unobtrusive) all the time. I've got about 5 itunes helper apps, it would be great if I could ditch at least one of 'em!
-
zerock
which other itunes appz u use, Gene?
-
anonymous
I use iScrobbler, Sofa (sometimes) and Now Playing (http://www.big.or.jp/~crane/soft/nowPlaying/index.html).  Can't wait for Dashboard...
-
Greg Hurrell
Thanks for posting the suggestions, everybody. Keep them coming! I've got all these things planned, and many more...
-
anonymous
It would be great to be able to see a substantially larger version of the album art in the floater, such as you can with Sofa.
I'm a long-time registered user, but just started using Synergy again. Thanks for all your work, it's great.
-
Diomedes
I'd like to see Synergy use the artwork that is attached with the music file, instead of taking the artwork and caching it in "Album Covers". I, for example, have different artwork for different tracks from the same album (e.g., artwork from CD singles). So if I have 5 tracks from an album, each with different artwork, Synergy will only use the artwork from the first instance of the album. Is there a reason Synergy can't use the artwork associated with the music file, native to iTunes?
-
Greg Hurrell
Synergy caches the art for historically reasons. It came out before iTunes ever had cover art support, and so needed its own cover store.
When iTunes 4 was released, I added the ability to pull art across from iTunes when present, but Synergy continued to keep a copy in the cache, as you've noted.
Again, due to historical reasons, Synergy has no way of knowing that the album art in the other tracks is different, which is why it pulls only the art from the first track over.
Synergy Advance is a completely new product, written from scratch, so it won't have any of these limitations.
Reply
This topic is now closed.


ExampleFile.md
138 words
Save
MARKDOWN
PREVIEW
Paragraphs are separated by a blank line.
Second paragraph. Italic, bold, and monospace. Itemized lists look like:
Block quotes are written like so.
They can span multiple paragraphs, if you like.


{% translate "You're not supposed to see this! Safe Exam Browser should have closed itself when you clicked the Quit link." %}
{% translate "Go back" %}{% extends "numbas_lti/base.html" %} {% load i18n %} {% block content %}
{% translate "You're not supposed to see this! Safe Exam Browser should have closed itself when you clicked the Quit link." %}
{% translate "Go back" %}


R language chatsheet
April 16, 2016
cheat-sheet
General commands
<- #assignment (also =)
<<- #assignment in another environment
# #comments
?help #also help(func) ; ?`:`for operators
example(func)
arguments(fun) #lsit the arguments of the function
identical() #compare two objects
save(list=c(objA, objB), file="filename.Rda")
load("filename.Rda")
Basic functions
#Object information
class()
str(x) #compactly display internal structure of a R object, including functions
#Shape
length() #vectors have length, not dim
dim(m) #number of rows&columns in matrix or df
#Names, attributes
names(x) #assign names to R objects
attributes() #attributes of an object
attr(object, "att_name") <- "m/s" #set an attribute
#Retetition, spliting and joining
rep(NA, 100) # repeat 100 times
unique() #remove duplicates
split #useful in conjunction with lapply or sapply
paste() #join elements from a vector; if two sequences given, is pariwise
Filesystem navigation
getwd()
setwd(abspath) #in Windows ""C:\\etc"
setwd("./data") #
setwd("../") #move one dir up
list.files(path) #also dir()
file.exists("dirName")
file.create()
file.copy()
file.path()
dir.create("dirName")
dir.exists()
unlink() #delete directory; note the recursive flag for nested directories
Workspace
ls() #list of variables in the workspace; rm(list=ls()) to clear
Packages
install.packages('ggplot2')
update.packages(checkBuilt=TRUE, ask=FALSE)
libary(ggplo2) #load package for use (no quotes!)
R.version.string
Is functions
is.na(x)
is.nan(x)
x[!is.na(x)] #removes NA values
complete.cases(x,y) #which cases are complete
Coercion
as.numeric(x)
as.logical(x)
as.character(x)
Tools
gl(n,k) #factor vector, n levels and k repetitions each
Atomic data types
Everythin is an object in R.
character
"string"
numeric
Inf
NaN #Undefined value - not a number. NaN is NA (but not the reverse)
integer
5L
complex
logical
T, F
TRUE, FALSE
missing values
NA #NA has a type as well (NA character, etc)
Date-times
as.Date("1970-01-01")
as.Date(x, "%d%b%Y"
Sys.time() #uses the POSIXct class, ie, seconds since 1970-01-01
as.POSIXlt(x) #list with sec, min, hour, mday, mon, year, wkday, yday, isdst
strptime("January 10, 2014", "%B %d %Y")
weekdays()
months()
julian() #days since origin, 1970-01-01
date() #returns current date/time as string
Sys.Date() #returns date (only) as Date class
library(lubridate)
ymd("20140108")
mdy()
dmy()
ymd_hms()
Data Structures
Vectors
- Only accepts elements of the same type
- Mixing types will coherce to the lowest denominator of types
- Can have named elements
vector() #empty vector
vector("numeric", length=10) #initializes to default value, 0
c(0,1,2,3,4) #'combine'
1:4 #also 15:1 or pi:10
seq(1,10,by=0.5) #generalizes the : operator
seq(5, 10, length=30)
seq_along(my_seq) #also seq(along.with = my_seq), or 1:length(my_seq)
rep(pi,10)
c(foo = 1, bar = 2) #named elements
Matrices
- All the data has to be same type (numeric, integer, logical, character).
- Special type of vector, with a dimension attribute being a vector of length 2
- a matrix is simply an atomic vector with a dimension attribute
- Matrix multiplication with
a%*%b
matrix(1:6, nrow = 2, ncol = 3)
matrix(1:10, ncol=2)
#can also be created by adding a dimension attr to a vector
dim(1:6) <- c(2,3) ; dim(v) = c(2,3)
#also by combining vectors
x <- 1:3; y=10:12 ; cbind(x,y) ; rbind(x,y)
data.frame
df <- data.frame(colA = c(1,2,3), colB = c('y','n','y'))
df$colA
df[,1] #first col
def[1,] #first row
#Attributes
names(df) #column names
colnames()
row.names #row names
#New elements
`X$var4 <- rnorm(5)` #new column var4
cbind(X,rnorm(5)) #like above
lists
- stores other objects
- can contain different types
- indexed with double brackets [[]] ```r list(1, “string”, 3.2) list(foo=1:4, bar=0.6)
unlist #flatten ```
factors
Factors are variables in R which take on a limited number of different values; such variables are often refered to as categorical variables. There are two types: ordered and unordered.
x <- factor(c("y","n","y"))
x <- factor(c("y","n","y"), levels=c("y","n")) #ordered
data.table
library(data.table)
tables() #all the datatables in memory
dt[c(2,3] #careful: when subsetting wtih single index, subsets rows!
df[,list(mean(x), sum(z))] #applies expressions to the table (x,y are colNames)
dt[,w:=z^2] #creates new column (without copying, as dataframe)
dt[,a:=x>0] #new column of T/F-s
Subsetting and sorting
[ ]
- Single square bracket always returns objects of the same class as the original
- To get multiple elements of a list, use [ ]
- Drop argument in the [ ] operator reduces dimensions of the returned object by default: so subsetting a matrix and taking one element gives back a 1 dim vector.
- Index vectors can be logical, integers (pos or neg) and character (if named elements exist)
x[1]
x["bar"]
x[1:4] #numeric index
x[c(1,3)] #List with elements 1 and 3 of the list
x[c(-2, -10)] #all elements except 2 and 10th. Also x[-c(2, 10)]
Rows and columns
r
x[,1] #first col in a matrix/df
x[,"colname"]
x[1,] #first row
x[1:2,"var2"]
Logical index
x[x>2]
x[!is.na(x)]
`X[(X$var1 <3 | X$var2>10), ]`
`X[which(X$var2>8), ]` #skips the NA by itself
[[ ]]
- Double bracket operator used to extract a single element of a list and dataframe.
- For example, with
x <- list(foo=1:4, bar=0.6)
, x[[1]] gives an integer vector, while x[1] gives a list (which is the same class as the original object). - Accepts computed arguments
- Recursive access:
x[[1]][[3]]
equivalent to x[[c(1,3)]], gives third element of the first element. Nota that this is not the same as x[c(1,3)]!
$
- Dollar sign used with lists or dataframes to get the element by name
- Needs to be a literal symbol.
- Accepts partial matching: ` x$a or x[[“a”, exact=FALSE]] ` retrieves
x$asdf
in the console)r x$bar equivalent to x[["bar"]]
existance or pertainance
a %in% v
any()
all()
sort
sort
`X[order(X$var1)]` #order the df according to var1
Set operations
intersect(X,Y)
Summarizing & transforming data
Summarize
r
head(df,n)
tail(df,n)
str(df)
summary(df)
table(df$col, useNA="ifany")
table(v1,v2)
table(x) #gives the count of number of items
quantile(df)
sum(is.na(col))
xtabs(Freq ~Gender + Admit, data=DF) #pivot table: values=Freq, rows=Gender, cols=Adm
ftable(xt) #hierarchical summary of xtabs
Create variables
r
col %in% c('A','B') #subset indication
ifelse(col<0,TRUE,FALSE) #binary variables
cut(col, breaks=quantiles(col)) #factor variable breaking up the variable in groups
factor(col)
as.numeric(col)
mutate(df, newcol=...) #adds new columns???
Reshape data
r
library(reshape)
melt #function to reshape (one row for each measure vars)
dcast(df, cyl~variable, mean)
Merge data
r
merge(x,y, by.x, by.y, all) #by default all the columns overlapping; else, use by.x etc)
plyr/dplyr packages
plyr
arrange(X,var1) #order
arrange(X,desc(var1)) #order desc
join #plyr package; only joins by common names
join_all(list(df1,df2,df3)) #
dplyr
Format: - first arg: df - subsequent args ; note that column names can be referred without the $.
select(df, col1:col3 #selects columns
select(df, -(col1:col3)) #excludes columns
filter(df, col2>10 & col1<100) #selectes rows
arrange(df, date) #sort
arrange(df, desc(date)) #sort descending
rename(df, newname=oldname)
mutate(df, detrend=var-mean(var)) #create new variable
summarize(group_by(df, var), colA=mean(colA))
%>% #pipeline operator
String manipulation
tolower() , toupper()
strsplit(names, "\\.") #. is a reserverd character.
sub("_","",names) #replace first
gsub("_","",names) #replace allç
grep("text", data) #returns element numbers where "test"apperas
grep("text", data, value=T) #returns elements where "test"apperas
grepl("text", data) #boolean vector where "text" appers
libarary(stringr)
substr("str", 0,2) #substring
paste("a","b") #paste together, default separation is space
str_trim("text ") #remove end spcaes
Regular expressions
```r
^str #beggining of line
str$ #end of line
[Bb][Uu][Ss][Hh] #matches bush, Bush, busH etc
[0-9][a-zA-Z] #range of characters
[^str] #matches any character NOT in the indicated class
. #any single character
str|str #combines alternatives with OR
() #group
()? #the expression is optional
+ #repeat any muber of times but at least one
* #repeat any number of times (including 0). It’s greedy (max chars it can)
*? #not greedy: min number of chars possible that match
{} #qualifiers; specify min and max number of times the expression matches
\1 \2 #to refer to the matched text before
## Reading /Writing data
```r
read.table() #parameters: file, header, sep, row.names, nrows
read.csv()
read.csv2()
readLines #lines of a text file
source #read R code files
dget #read R code files
unserialize #read R objects in binary form
write.table(df, file="outputfile.csv", sep=',')
xls files:
xlsx package, but alto xlsx2, XLConnect
r
library ( xlsx )
read.xlsx ("datafile.xlsx", sheetIndex=1,header=TRUE)
write.xlsx()
#xls files:
library ( gdata )
data <- read.xls ( "datafile.xls" )
XML
Componentes: Markup and Content.
Examples:
- elements <Greeting> Hello! </Greeting>
- empty tags <line-break/>
- attributes <step number=3> Connect A </step>
r
library(XML)
doc <- xmlTreeParse(fileUrl, useInternal=T)
rootNode <- xmlRoot(doc)
xmlName(rootNode)
rootNode[[1]] etc
Json
library(jsonlite)
jsonData <- fromJSON("...")
names(jsonData)
names(jsonData$field)
tojson(df, pretty=T)
mySQL
install.packages("RMySQL")
conn <- dbConnect(MySQL(), user="...", host="...")
dbGetQuery(conn, "show databases"") #shows all databases in the server
dbDisconnect(conn)
conn2 <- dbConnect(MySQL(), user="...", db="...", host="...")
dbListTables(conn2)
dbListFields(conn2, "tablename")
dbReadTable(conn2, "tablename")
dbGetQuery(conn2, "sql_sentence")
q <- dbSendQuery(conn2, "sql_sentence")
fetch(q, n=10) #10 rows of table
dbClearResult(query) #clear query from server
HDF5
Contains groups (with zero or more sets and their metadata):
- A group has a header, with group name and list of attributes
- Also a symbol table, with list of objects in the group.
Contains datasets (data and metadata)
- Header (name, dtype, dataspace, storage layout)
- Array with the data
r
source("http://bioconductor.org/biocLite.R")
biocLite("rhdf5")
library(rhdf5)
h5createFile("a.h5")
h5createGroup("a.h5", "foo") #create group
h5ls("a.h5") #see the groups
h5write(df, "a.h5", "foo") #foo is a group; or can be "df" to put at upper level
h5read("a.h5", "foo/A", index=list(1:3,1)) #read elements 1:3 of columns 1
Web
Webscraping ```r conn = url(“url”) htmlCode = readLines(conn) close (conn)
library(XML) html <- htmlTreeParse(url, useInternalNodes=T) xpathSApply(html, “//title”, xmlValue) ```
Alternative way to parese the data is httr, which allows authentication.
r
library(httr)
html2 = GET(url)
content2 = content(html2, as="text")
parsedHtml = htmlParse(content2, asText=T)
xpathSApply(...)
Using handles to not need to authenticate time and again ```r g = handle(“http://…”) pg1 = GET(handle=g, path=”/”)
#### API
```r
library(httr)
myapp = oauth_app("twitter", key="..", secret="..")
sig = sign_oauth1.0(myapp, token="..", token_secret="..")
homeTL = GET("https://...json", sig)
j = content(homeTL)
j2 = jsonlite::fromJSON(toJSON(j)
Etc
Rough memory requirement calculation: 8bytes/numeric. But R need about 2 times this amount
Other textual formats that preserve the metadata:
- dput / dget
: writes R code which can reconstruct the R object
- dump
: as dput can be used on multiple objects
Interfaces to files/sites
- file() ; close()
: opens a conection to a file
- url()
: connection to a webpage
Get data from the internet:
download.file()
#use flag method=”curl” if https
Control structures
IF statemen
if(i==1){
...
}
else{
...
}
#shortcut : ifelse(i==1, ..., ...)
#also : y <- if(...){1}else{0}
FOR loops
for(i in 1:5){...}
for(i in seq_along(x)) {x[i]}
WHILE loops
while(z>3 && z<10){...}
REPEAT loops
repeat {...}
Control structures
- To exit loops:
return
?? (stops the function) - To continue to next iteration:
next
logical operators
! x
x & y
x && y #only evaluates the first member of a vector, & does elementwise
x | y
x || y #only evaluates the first member of a vector, | does elementwise
xor(x, y)
isTRUE()
which() #returns indices of the TRUE *indices* of a vector
any()
all()
Loop functions (‘apply’ functions)
Like lookuping through elements, but more compact. These functions make use of anonomous functions. Split-apply-combine strategy
lapply / sapply / vapply
- lapply: loops over list and applyes func to each of them, returning list
- sapply: (variant of lapply) tries to put elements as vector or matrix when possible
- similar to sapply, but you can specify the output format requested; else it will error out
lapply(list, fun, ...) #applies fun to each element in list; returns *list^
#the ... arguments go to fun
lapply(df, range)
lapply(df, unique)
sapply(df, class) #vector
sapply(df, sum) #vector
#With Annonimous function
lapply(list, function(x) x[,2]) #takes the second col of each element
#vapply
vapply(df, class, character(1))
apply
Works over the margins of the array (rows or columns of matrix for ex)
r
apply(mymatrix, 2, sum) #sumes the columns; margin=2 means keep the second dimension (cols) and collaps the other dim
Note that specifically for row/col sums and means, there are specialized and optimized functions:
r
rowSums = apply(x, 1, sum) #colSumns
rowMean = apply(x, 1, mean) #colMeans
tapply
Apply function over subsets of a vector
r
tapply(x, index, fun) #index should be a factor that groups the observations of x
mapply
Can take multiple list arguments; applies in parallel to various objects; there should be as many lists as arguments nneded by mapply. A way to vectorize a function.
r
mapply(rep,1:4, 3:7) #repeat number 1 three-times, number 2 four-times etc
split
Similar to tapply but without the summary funcion.
replicate
replicate(100, rpois(5, 10)) #returns a matrix
Creating functions
myfunc <- function(x,y){
...
}
- R functions return the last expression in the function
- Default values to arguments like in python (n=10, m=NULL)
- Partial matching of argument names allowed
- R uses lazy evaluation: ie,
f(a,b){}
can be called withf(2)
if b not used in f. - Variable number of arguments with … (ie, **kwargs):
f(a,b,...)
. Any argument after … must be named explicitly (an din full, ie, no partial matching) - The function can end with invisible(x) so not to autoprint object to console
Scoping rules:
- First R looks for the symbol in the ‘global’ environment (ie, our defined symbols)
- If not found, R will look in the namespaces of each of the packages on the searchlist. The last included library goes in the top of the list.
- There are separate namespaces for functions and non-functions
- R uses ‘Lexical scoping’, ie, the values of free-variables (ie, not defined within a function) are searched for in the environment in which the function was defined, up to the top. Other languages use ‘dynamic scoping’ (ie, values are assigned looking at the environment where the function was called from).
- An environment is a collection of symbolvalue pairs. A function plus an environment is a function closure.
Debugging & Profiling
Debug
Indication levels: - message - warning : execution continues; warning appears at the end of execution - error : execution stopped - condtion : meaning exception, can be user defined
Debugging tools:
- traceback() : prints function call stack; does nothing if there is no error
- debug : flags a function and allows execution one line at a time; n
next line
- browser : supends execution of a funct at that particular point
- trace : insert debugging code at specific places
- recover : change default behaviour (during R session) of getting the console back, and instead will freez the execution of the failed function and look around with the browser
Profiling
Timing - user time: cpu - elapsed time: experienced by we (the users)
Rprof() - by.total : note that top level function takes always 100%. - by.self : most interesting format; substracts all other functions
system.time() #evaluates an expression
Rprof()
summaryRprof()
Random number generation
Functions ```r rnorm #generate random normal variates rpois #generate random Poisson variates rbinom #binomial, discrete values …
dnorm #evalueate the normal probability density at a point pnorm #evaluate the cumulative distr func fo a Normal distr qnorml #evaluate the quantile function … ```
Sample from aribrary vectors
r
sample(1:10, 4) #take 4 randomly; default replace=FALSE
sample(1:10) #permutation; default replace=FALSE
Seed
r
set.seed(1)
Plots
plot(x,y,...) #arguments: xlab, ylab, main (title), col (color), xlim
plot(dist ~ speed, cars) #'formula' interface
boxplot(formula = mpg ~ cyl, data = mtcars)
#Paramenters:
colors: red=2,
Snippets
x <- matrix (rnorm(200), 20, 10)
References
- Base contents are from the Coursera course on R programming (Johns Hopkins) https://github.com/rdpeng/courses/tree/master/02_RProgramming , and also from the genreal ‘Data Science’ specialization (Johns Hopkins)
- Introduction to R Programming Part 1 (youtube video)
- https://cran.r-project.org/doc/contrib/Torfs+Brauer-Short-R-Intro.pdf
- https://www.rstudio.com/resources/cheatsheets/