Friday, March 13, 2015

User Scenarios and Lean Solutions

After reading the book Lean Solutions a few years ago it was easy to see that agile methodolgies are "Lean Solutions" in comparison to traditional methodologies, but I wondered how we could apply that knowledge to design and build Lean Solutions for our clients (yes, you can still build bad systems with agile). User Scenarios are one tool that can help.

Well written user scenarios put all the features into a flow that is relevant to the users value stream. They can help us design a solution as a unified value stream rather than just a bunch of features put together. From Lean Solutions:
"Companies must provide the goods and services consumers actually want, when and where they are wanted, without burdening the consumer."
For more information and an example, check out Jeff Pattons stickyminds article.
Read more »

Thursday, March 12, 2015

Deprecating Script Gallery in the old version of Google Sheets

Recently we launched add-ons for Google Docs and Sheets. Now developers can easily package Apps Script applications as add-ons and distribute these scripts via the add-on store. The add-on store gives developers wider distribution, automatic updates, versioning and is vastly superior to the restrictive script gallery that it was designed to replace.

Starting today, we are deprecating the option for developers to publish to the script gallery. No new gallery submissions will be accepted or approved, but scripts already present in the gallery will remain accessible (via the old version of Sheets).

If you rely on distributing or consuming your script from the script gallery, then please convert your script into an add-on and follow the add-on publication instructions.

Read more »

FitNesse and todays date with net

I have an acceptance test that says I need to validate the age of majority in each of the different states and provinces.  Here is a simple example:

Given Mary who is born January 5, 1995 and lives in Manitoba
When she asks if she is the age of majority
Then return no

The test above is faily simple and I could write it like this in the wiki as a Column Fixture (using the fitSharp.dll to test C# code)

!|Check Age of Majority|
|Province State|Birth Date|Am I Underage?|
|MB            |5-Jan-1995|Yes           |

The problem of course is that this test will start failing on January 5, 2013 when Mary turns 18.  Also, it does not perform the boundary testing that I would like it to do in order to test someone who is 18 today vs. someone who will turn 18 tomorrow.  In order to improve this test, I investigated some other date functions in FitNesse and a plugin by James Carr that allowed you to add days to the current date.  These work ok for smaller calculations like "Given document ABC, When it is 30 days old, Then archive it".  However, this would be a little more cumbersome for birth dates when adding 18 years (esp. with leap year calculations) and the !today function in FitNesse does not work in ColumnFixture wiki tables.  So, I found a simple way to meet my requirement.

First, I wrote a class in C# that accepts two parameters to Add or Subtract Years and Days to the current date.  The class uses C#s simple DateTime addition to add or subtract the years/days from today and returns the result.  You could easily extend this to add months or add other functionality required in your tests:

namespace FitNesseTutorial.Tests
{
      public class GetDateBasedOnToday : ColumnFixture
      {
        public int AddYears;
        public int AddDays;

        public DateTime ResultingDate()
            {
            return DateTime.Today.AddYears(AddYears).AddDays(AddDays);
            }
      }
}

Then in FitNesse at the top of my script for this story I call GetDateBasedOnToday and store the resulting values in FitNesse variables.  Finally,  I use the variable names through my script to reference the underage and of age birth dates.  Here is an example:

The FitNesse script:

Get underage and of age dates for 18 and 19 year olds
!|Get Date Based On Today          |
|Add Years|Add Days|Resulting Date?|
|-18      |1       |>>UNDERAGE_18  |
|-19      |1       |>>UNDERAGE_19  |
|-18      |0       |>>OFAGE_18     |
|-19      |0       |>>OFAGE_19     |

!|Check Age of Majority|
|Province State|Birth Date   |Am I Underage?|
|MB            |<<OFAGE_18   |Yes           |
|MB            |<<UNDERAGE_18|No            |
|BC            |<<OFAGE_19   |Yes           |
|BC            |<<UNDERAGE_19|No            |

In FitNesse, the final result including the acceptance criteria above looks like this:


 (Note: The example above should probably be written as a unit test because it is fairly straightforward, but it simply illustrates how to use the date logic that Im using as part of larger acceptance tests.)
Read more »

Code updates required for Apps Script advanced services

The APIs for three of Apps Scripts advanced services — Analytics, BigQuery, and Prediction — will undergo breaking changes on Monday, November 18. If you dont update your code to the new syntax before then, youll receive error messages such as Required parameter is missing.

Advanced services allow you to easily connect to certain public Google APIs from Apps Script. Were working to expand and improve our advanced services, and as a side effect some methods and parameters that were incorrectly listed as optional are now required.

On November 18, these services will switch to use the new method signatures shown in the tables below. To learn how new arguments should be structured, refer to the documentation for the underlying API. For example, the documentation for the BigQuery services Jobs.query()method shows the valid properties for the resource object in the "Request body" section of the page.


OldNew
Analytics.Management.Uploads

.deleteUploadData(
accountId,
webPropertyId,
customDataSourceId,
optionalArgs)

.deleteUploadData(
resource,
accountId,
webPropertyId,
customDataSourceId)
BigQuery.Datasets

.insert(
resource,
optionalArgs)

.insert(
resource,
projectId)

.update(
resource,
optionalArgs)

.update(
resource,
projectId,
datasetId)
BigQuery.Jobs

.insert(
resource,
mediaData,
optionalArgs)

.insert(
resource,
projectId,
mediaData)

.query(
projectId,
query)

.query(
resource,
projectId)
BigQuery.Tabledata

.insertAll(
projectId,
datasetId,
tableId,
optionalArgs)

.insertAll(
resource,
projectId,
datasetId,
tableId)
BigQuery.Tables

.insert(
resource,
optionalArgs)

.insert(
resource,
projectId,
datasetId)

.update(
resource,
optionalArgs)

.update(
resource,
projectId,
datasetId,
tableId)
Prediction.Hostedmodels

.predict(
project,
hostedModelName,
optionalArgs)

.predict(
resource,
project,
hostedModelName)
Prediction.Trainedmodels

.insert(
project,
optionalArgs)

.insert(
resource,
project)

.predict(
project,
id,
optionalArgs)

.predict(
resource,
project,
id)

.update(
project,
id,
optionalArgs)

.update(
resource,
project,
id)

If you want to prepare your code ahead of time, you can add a try/catch around your existing code that retries with the new method signature if the old one fails. For example, the following sample applies this approach to the BigQuery services Jobs.query() method:


var result;
try {
result = BigQuery.Jobs.query(projectId, query, {
timeoutMs: 10000
});
} catch (e) {
// Refer to the BigQuery documentation for the structure of the
// resource object.
var resource = {
query: query,
timeoutMs: 1000
};
result = BigQuery.Jobs.query(resource, projectId);
}

We apologize for inconvenience and look forward to sharing exciting news about advanced services in the coming weeks.


Eric Koleda profile

Eric is a Developer Programs Engineer based in NYC on the Google Apps Script team. Hes previously worked with the AdWords API and enterprise content management software.

Read more »

Wednesday, March 11, 2015

Google Apps Script with UI Properties and New Sites

Weve just finished pushing one of our most feature-rich Google Apps Script releases ever! So much has been added and improved in this release that its hard to fit it all in one blog post. Ill run through the highlights, but please make sure to check out the Release Notes for a complete list of changes in this release.

The biggest news is that UiApp is now available to all users! UiApp allows you to build user interfaces, giving scripts the ability to show a friendly interface, which is a necessity for less technical users. We’re very happy to make this formerly Premier feature available to everyone. For more information, see the UiApp code samples and reference documentation.

Next, weve added ScriptProperties and UserProperties. These features allow scripts to store key:value data per user, or per script. ScriptProperties are a great place to store passwords and other script-specific information. UserProperties are useful for storing things like user preferences. For details on using these properties, check out the documentation.

Weve added some new functionality to Sites and cleaned up some inconsistencies and bugs. This has greatly simplified the API, while at the same time making it more powerful and flexible. Some of these improvements have required changes to the API, which is documented in the SitesApp reference guide.

Finally, weve updated the Apps Script editor with a bunch of convenient features. You can perform Find & Replace in the editor. Script revisions are now available, so that you can see a history of changes to your scripts. Lastly, we’ve added the ability to change the timezone of a script, something that we hope will make developers’ lives easier.

The remaining items in this release are listed in the Release Notes. Were look forward to hearing your feedback about all the new changes, and would love to see what you do with the new features. Some large improvements and features are in our pipeline, so stay tuned!

Want to weigh in on this topic? Discuss on Buzz

Read more »