Splitting sentences in C# using Stanford.NLP

So I need to break some sentences up. I have a pretty cool regex that does this, however, I want to try out Stanford.NLP for this. Let’s check it out.

  1. Create a Visual Studio C# project.
    I chose a New Console Project and named it SentenceSplitter.
  2. Right-click on the project and choose “Manage NuGet Packages.
  3. Add the Stanford.NLP.CoreNLP nuget package.
  4. Add the following code to Program.cs (This is a variation of the code provide here: http://sergey-tihon.github.io/Stanford.NLP.NET/StanfordCoreNLP.html
    using edu.stanford.nlp.ling;
    using edu.stanford.nlp.pipeline;
    using java.util;
    using System;
    using System.IO;
    using Console = System.Console;
    
    namespace SentenceSplitter
    {
        class Program
        {
            static void Main(string[] args)
            {
                // Path to the folder with models extracted from `stanford-corenlp-3.4-models.jar`
                var jarRoot = @"stanford-corenlp-3.4-models\";
    
                const string text = "I went or a run. Then I went to work. I had a good lunch meeting with a friend name John Jr. The commute home was pretty good.";
    
                // Annotation pipeline configuration
                var props = new Properties();
                props.setProperty("annotators", "tokenize, ssplit, pos, lemma, ner, parse, dcoref");
                props.setProperty("sutime.binders", "0");
    
                // We should change current directory, so StanfordCoreNLP could find all the model files automatically 
                var curDir = Environment.CurrentDirectory;
                Directory.SetCurrentDirectory(jarRoot);
                var pipeline = new StanfordCoreNLP(props);
                Directory.SetCurrentDirectory(curDir);
    
                // Annotation
                var annotation = new Annotation(text);
                pipeline.annotate(annotation);
    
                // these are all the sentences in this document
                // a CoreMap is essentially a Map that uses class objects as keys and has values with custom types
                var sentences = annotation.get(typeof(CoreAnnotations.SentencesAnnotation));
                if (sentences == null)
                {
                    return;
                }
                foreach (Annotation sentence in sentences as ArrayList)
                {
                    Console.WriteLine(sentence);
                }
            }
        }
    }
    

    Warning! If you try to run here, you will get the following exception: Unrecoverable error while loading a tagger model

    java.lang.RuntimeException was unhandled
      HResult=-2146233088
      Message=edu.stanford.nlp.io.RuntimeIOException: Unrecoverable error while loading a tagger model
      Source=stanford-corenlp-3.4
      StackTrace:
           at edu.stanford.nlp.pipeline.StanfordCoreNLP.4.create()
           at edu.stanford.nlp.pipeline.AnnotatorPool.get(String name)
           at edu.stanford.nlp.pipeline.StanfordCoreNLP.construct(Properties A_1, Boolean A_2)
           at edu.stanford.nlp.pipeline.StanfordCoreNLP..ctor(Properties props, Boolean enforceRequirements)
           at edu.stanford.nlp.pipeline.StanfordCoreNLP..ctor(Properties props)
           at SentenceSplitter.Program.Main(String[] args) in c:\Users\jbarneck\Documents\Projects\NLP\SentenceSplitter\SentenceSplitter\Program.cs:line 20
           at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
      InnerException: edu.stanford.nlp.io.RuntimeIOException
           HResult=-2146233088
           Message=Unrecoverable error while loading a tagger model
           Source=stanford-corenlp-3.4
           StackTrace:
                at edu.stanford.nlp.tagger.maxent.MaxentTagger.readModelAndInit(Properties config, String modelFileOrUrl, Boolean printLoading)
                at edu.stanford.nlp.tagger.maxent.MaxentTagger..ctor(String modelFile, Properties config, Boolean printLoading)
                at edu.stanford.nlp.tagger.maxent.MaxentTagger..ctor(String modelFile)
                at edu.stanford.nlp.pipeline.POSTaggerAnnotator.loadModel(String A_0, Boolean A_1)
                at edu.stanford.nlp.pipeline.POSTaggerAnnotator..ctor(String annotatorName, Properties props)
                at edu.stanford.nlp.pipeline.StanfordCoreNLP.4.create()
           InnerException: java.io.IOException
                HResult=-2146233088
                Message=Unable to resolve "edu/stanford/nlp/models/pos-tagger/english-left3words/english-left3words-distsim.tagger" as either class path, filename or URL
                Source=stanford-corenlp-3.4
                StackTrace:
                     at edu.stanford.nlp.io.IOUtils.getInputStreamFromURLOrClasspathOrFileSystem(String textFileOrUrl)
                     at edu.stanford.nlp.tagger.maxent.MaxentTagger.readModelAndInit(Properties config, String modelFileOrUrl, Boolean printLoading)
                InnerException: 
    
    
  5. Download the stanford-corenlp-full-3.4.x.zip file from here: http://nlp.stanford.edu/software/corenlp.shtml#Download
  6. Extract the stanford-corenlp-full-2014-6-16.x.zip.
    Note: Over time, as new versions come out, make sure the version you download matches the version of your NuGet package.
  7. Extract the stanford-corenlp-3.4-models.jar file to stanford-corenlp-3.4-models.
    I used 7zip to extract the jar file.
  8. Copy the stanford-corenlp-3.4-models folder to your Visual Studio project files.
    Note: This is one way to include the jar file in your project. Other ways might be a copy action or another good way would be to use an app.config appSetting. I chose this way because it makes all my files part of the project for this demo. I would probably use the app.config method in production.
  9. In Visual Studio, use ctrl + left click to  highlight the stanford-corenlp-3.4-models folder and all subfolders.
  10. Open Properties (Press F4), and change the namespace provider setting to false.
  11. In Visual Studio, use ctrl + left click to  highlight the files under the stanford-corenlp-3.4-models folder and all files in all subfolders.
  12. Open Properties (Press F4), and change the Build Action to Content and the Copy to Output Directory setting to Copy if newer.
  13. Run the code.

 

Note: At first I tried to just load the model file. That doesn’t work. I got an exception. I had to set the @jarpath as shown above. I needed to copy all the contents of the jar file.

Results

Notice that I through it curve ball by ending a sentence with Jr. It still figured it out.

I went or a run. Then I went to work. I had a good lunch meeting with a friend name John Jr. The commute home was pretty good.

However, I just tried this paragraph and it did NOT detect the break after the first sentence.

Exit Room A. Turn right. Go down the hall to the first door. Enter Room B.

I am pretty sure this second failure is due to the similarity in string with a legitimate first name, middle initial, last name.

Jared A. Barneck
Room A. Turn

Now the question is, how do I train it to not make such mistakes?


Aspx CheckBoxList Alternative that allows for the OnCheckedChanged event

My team had to edit an older apsx website and add a list of CheckBoxes, which are actually html <input type="checkbox"/> tags.  We assumed that CheckBoxList would be perfect for our task. We assumed wrong.

I wrote desktop apps for years and now that I am writing web apps, I am using MVC and Razor, so I missed the aspx days. However, having to work on legacy aspx applications is catching me up.

My use case for list of CheckBoxes

Really, my use case is simple. There are icons that should show up for some products. We wanted to store a map between products and the icons in the database. On the product page, we want a list of the icons with a checkbox by each list item. This would allow the person who creates new products to select which icons to show on a product download page.

  1. Get a list of option from a database and display that list as html checkboxes.
  2. Checking a checkbox should add a row to a database table.
  3. Unchecking a checkbox should remove that row from a database table.

CheckBoxList Fails

So what I needed was an OnClick event which is actually called OnCheckedChanged in an asp:Checkbox. Well, it turns out that the CheckBoxList control doesn’t support the OnCheckedChanged event per CheckBox. The CheckBoxList doesn’t have any type of OnClick method. Instead, there is an OnSelectedIndexChanged event. But OnSelectedIndexChanged doesn’t even tell you which CheckBox was clicked. If a CheckBox is checked, then in the OnSelectedIndexChanged event, the SelectedItem equals the clicked item, however, if the CheckBox is unchecked, the SelectedItem was a completely different CheckBox that is checked.

So to me, this made the CheckBoxList control not usable. So I set out to replicate a CheckBoxList in a way that supports OnCheckedChanged.

Repeater with CheckBox for ItemTemplate

I ended up using the Repeater control with an ItemTemplate containing a CheckBox. Using this method worked pretty much flawlessly. It leaves me to wonder, why was CheckBoxList created in the first place if a Repeater with a CheckBox in the template works perfectly well.

Here is my code:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CheckBoxListExample._Default" %>

<%@ Import Namespace="CheckBoxListExample" %>
<%@ Import Namespace="CheckBoxListExample.Models" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
    <div>
        <asp:Repeater ID="Repeater1" runat="server">
            <ItemTemplate>
                <asp:CheckBox ID="cb1" runat="server" AutoPostBack="true" OnCheckedChanged="RepeaterCheckBoxChanged"
                    Text="<%# ((CheckBoxViewModel)Container.DataItem).Name %>"
                    Checked="<%# ((CheckBoxViewModel)Container.DataItem).IsChecked %>" />
            </ItemTemplate>
        </asp:Repeater>
    </div>
</asp:Content>
using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
using CheckBoxListExample.Models;

namespace CheckBoxListExample
{
    public partial class _Default : Page
    {
        private List<CheckBoxViewModel> _ViewModels;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                var _ViewModels = new List<CheckBoxViewModel>
                {
                    new CheckBoxViewModel {Name = "Test1", IsChecked = true},
                    new CheckBoxViewModel {Name = "Test2"},
                    new CheckBoxViewModel {Name = "Test3"}
                };
                Repeater1.DataSource = _ViewModels;
                Repeater1.DataBind();
            }
        }

        protected void RepeaterCheckBoxChanged(object sender, EventArgs e)
        {
            var cb = sender as CheckBox;
            if (cb == null) return;
            if (cb.Checked)
            {
                // Insert
            }
            else
            {
                // Delete
            }
        }
    }
}
namespace CheckBoxListExample.Models
{
    public class CheckBoxViewModel
    {
        public string Name { get; set; }
        public bool IsChecked { get; set; }
    }
}

Fiction.js (or making fun of javascript library names)

JavaScript libraries have some pretty awesome names. Unless you want to know what that library actually does that is. But hey, these names are great for inspiring fiction. As many of you know, I write fiction on the side. So here comes some fiction.js your way:

He straightened his backbone.js and tightened his angular.js jaw. Then he ate a banana.js while wearing a Bazinga.js shirt. He rubbed the handlbars.js of his mustache.js. His shotgun.js was ready.js. He looked at to the badass.js woman at his right.js. Jasmine.js had long.js auburn hair and a glow.js to her face. Her figure.js was a sight to behold.js–definitely a knockout.js. She sipped a cappucino.js. Kinetic.js magic.js was her forte.js. That and fire.js. She lifted her free hand.js and an ember.js of light.js illuminated.js her palm.

Evil.js was coming. Raphaël.js and Jasmine.js were ready.js!


Why to use string.format() over concatenation (Real world experience)

So today I was working on reverse engineering some old code. I will strip this down and remove proprietary info but still let you see the bug. This is a post for newbies but experienced coders might get a laugh out of this as well.

Here is the error code:

var contract = CustomerId + ProductGroupId + EndDate.ToString("yy-MM");

Now, imagine these values:

CustomerId = 12345
ProductId = 4
Date = 8/7/2014

A new developer would assume that this would return the following:

12345415-08

They would be wrong. See, CustomerId and ProductGroupId are integers. So they don’t concatenate as strings, they add as integers. The real value is this:

1234915-08

12345 + 4 = 12349. This is math, not string concatenation.

How would a developer resolve this bug? There are two solutions:

  • Use ToString() and concatenation (DO NOT USE!)
  • Use string.Concat() (USE FOR SIMPLE CONCATENATION OR PERFORMANCE!)
  • Use string.Format() (USE FOR CONCATENATION WITH FORMATTING!)

Here is the another interesting fact. I know exactly when this bug was introduced into the system. This code was written by the developer using the first solution. The developer had originally added .ToString() to the end of these objects. The developer didn’t write buggy code. He wrote code that worked.

The code used to look like this:

var contract = CustomerId.ToString() + ProductGroupId.ToString() + EndDate.ToString("yy-MM");

So what happened? If a developer didn’t break this code, who did?

I’ll tell you what happened and who did it. Resharper.

Today, developers aren’t the only ones messing with our code. We use tools that are pretty awesome to do masses of code automation for us. One of these tools is Resharper. Well, Resharper detected the ToString() methods as “Redundant Code.” Oh, in this case, it wasn’t redundant code.

The only reason I found this bug is because I was rewriting this piece of code and had to reconstruct a ContractId and I began reverse engineering this code. I noticed that the first part of the ContractId was the CustomerId up until a few months ago. After that, it seemed to be slightly off. I was able to check source from back then and see the difference and see why this bug started. Sure enough, when resharper cleaned up my redundant code, it removed the ToString() methods.

However, while this is a Resharper bug, let’s not jump so fast to blaming Resharper. I’ll submit a bug to them, but are they really at fault? I say not completely. Why? Because the developer chose to use ToString() and concatenation instead of string.Format(). This was the wrong choice. Always use string.format(). This has been preached by many, but just as many don’t listen.

What would have happened if the developer had followed the best practice to use string.Format() or string.Concat?

var contract = string.Concat(CustomerId, ProductGroupId, EndDate.ToString("yy-MM"));

or

var contract = string.Format("{0}{1}{2}", CustomerId, ProductGroupId, EndDate.ToString("yy-MM");

The bug would never had occurred. With either string.Concat() or string.Format(). In those uses, the ToString() methods really would be redundant. With or without them, the code acts the same.

But surely avoiding a Resharper bug isn’t the only reason to use string.Concat or string.Format()? Of course there are more reasons. This error was due to the ambiguous + operator. Using string.Format() or string.Concat() eliminates such ambiguities. Also, with string.Format(), the developer’s intentions are much more clear. The format decided upon is explicitly included. When I type “{0}{1}{2}”, there is no question about what the intended format is. This is why I chose string.Format() for this piece of code. It is self-documenting and unambiguous.

Conclusion

Best practices are best  practices for a reason. Use them. Using string.Format() is always preferable to string concatenation.

P.S. This old project also could have alerted us to this error if anyone would have bothered to write a Unit Test. But this code was buried deep in a method that itself was hundreds of lines long. Following the 100/10 rule and testing would have alerted us when Resharper introduced this error.


Add sql constraint on null, empty, or whitespace (C# string.IsNullOrWhiteSpace() equivelant)

Here is a User table. We wanted to make the UserName column not be null, empty, or whitespace.

So the constraint I made is this

ALTER TABLE [dbo].[User]  WITH CHECK ADD  CONSTRAINT [UserNameNotEmpty] CHECK  (([UserName]<>'' AND rtrim(ltrim(replace(replace(replace([UserName],char((9)),''),char((13)),''),char((10)),'')))<>''))
[UserName]<>''
Empty is checked first and not allowed.
replace([UserName],char((9)),'')
Replaces any instance a Tab character with an empty string.
replace([UserName],char((10)),'')
Replaces any instance a Carriage Return character with an empty string.
replace([UserName],char((13)),'')
Replaces any instance a Line Feed character with an empty string.
ltrim([UserName])
Left trim. It trims spaces from the left side of the string.
rtrim([UserName])
Right trim. It trims spaces from the right side of the string.

Note: You should know that char(9) is tab, char(10) is line feed, char(13) is carriage return.

Here is a complete User table. (This is a legacy system I inherited and I am fixing inadequacies.)

CREATE TABLE [dbo].[User](
	[UserId] [int] IDENTITY(1,1) NOT NULL,
	[UserName] [varchar](255) NOT NULL,
	[Password] [varchar](255) NOT NULL,
	[Salt] [varchar](255) NOT NULL,
	[FirstName] [varchar](255) NULL,
	[LastName] [varchar](255) NULL,
	[Email] [varchar](255) NULL,
	[Active] [bit] NOT NULL
 CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED 
(
	[UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED 
(
	[UserName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
SET ANSI_PADDING OFF
ALTER TABLE [dbo].[User] ADD  CONSTRAINT [DF_User_Active]  DEFAULT ((1)) FOR [Active]
ALTER TABLE [dbo].[User]  WITH CHECK ADD  CONSTRAINT [UserNameNotEmpty] CHECK  (([UserName]<>'' AND rtrim(ltrim(replace(replace(replace([UserName],char((9)),''),char((13)),''),char((10)),'')))<>''))
ALTER TABLE [dbo].[User] CHECK CONSTRAINT [UserNameNotEmpty]

Notice, I don’t check null on the constraint, as NOT NULL is part of the UserName column design.


How to add a progress bar to your blog

Some authors want to add progress bars to their blog. However, most authors are not web designers or developers. So they don’t know how to do this. Well, there is a secret in the html development world. The secret is that “Everything is easy once you know how to do it.” Yes, it is actually pretty easy to add a progress bar. I just added a progress bar to my blog.

Creating a Progress Bar on your Blog

Step 1. Create an HTML Widget for your side bar.

Using your blogging engine (WordPress or Blogger or whatever) create an html widget. In WordPress you would use a Text widget.

Step 2. Paste in the following html code

1st draft of Book 2
<div id="progressbar" style="background-color:black;border-radius:6px;padding:3px;">
    <div style="background-color:#dd6013;width:30%;height:10px;border-radius:4px;"></div>
</div>

It will look like this:

1st draft of Book 2

[Read More . . .]


I broke 2000 points on Stack Overflow

Check out my StackOverflow profile. http://stackoverflow.com/users/375727/rhyous?tab=badges

I broke 2000 points.


Select Option Web Control with Knockout.js and MVVM

<!-- Step 1 - Create the HTML File or the View -->
<!DOCTYPE html>
<html>
<head>
    <!-- Step 2 - Include jquery and knockout -->
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    <script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
     
    <!-- Step 3 - Add script to run when page loads -->
    <script type="text/javascript" >
        $(document).ready(function(){
 
 
            <!-- Step 4 - Create a data model -->
            var SelectableListDataModel = function () {
                // Private
                var _self = this;

                // Public
                _self.labels = new Array(); // Should have same count as values
                _self.values = new Array(); // Should have same count as Labels
                _self.defaultValue = 0;
                _self.canSelectMethod = function () { return true; },
                _self.push = function (label, value) {
                    _self.labels.push(label);
                    _self.values.push(value);
                };
            };
 
            <!-- Step 5 - Add an OptionViewModel -->
            var OptionViewModel = function(parent, label, value, canSelectMethod) {
                // private
                var _self = this;
                var _parent = parent;

                // public
                _self.id = ko.observable();
                _self.class = ko.observable();
                _self.label = label ? ko.observable(label) : ko.observable();
                _self.value = value ? ko.observable(value) : ko.observable();
                _self.isSelected = ko.computed(function () {
                    return (_parent && _parent.selectedValue) ? _parent.selectedValue() == _self.value() : false;
                }, _self);
                _self.canSelect = canSelectMethod ? ko.computed(canSelectMethod) : ko.computed(function () { return true; });
            };

            <!-- Step 6 - Add an SelectViewModel -->
            var SelectViewModel = function (selectableListDataModel) {
                // private
                var _self = this;
                var _defaultDataModel = new SelectableListDataModel();
                var _dataModel = selectableListDataModel ? selectableListDataModel : _defaultDataModel;

                // Public
                _self.canSelect = (_dataModel.canSelectMethod)? ko.computed(_dataModel.canSelectMethod) : ko.computed(_defaultDataModel.canSelectMethod);
                _self.list = ko.observableArray();
                _self.selectedValue = _dataModel.defaultValue ? ko.observable(_dataModel.defaultValue) : ko.observable();
                
                if (_dataModel.labels && _dataModel.values) {
                    for (var i = 0; i < _dataModel.labels.length; i++) {
                        _self.list.push(new OptionViewModel(_self, _dataModel.labels[i], _dataModel.values[i], _self.canSelect));
                    }
                }
                
                _self.selectedIndex = ko.computed(function () {
                    var index = 0;
                    var foundIndex = -1;
                    ko.utils.arrayForEach(_self.list(), function (item) {
                        if (_self.selectedValue() == item.value()) {
                            foundIndex = index;
                        }
                        index++;
                    });
                    return foundIndex;
                }, _self);

                _self.selectedText = ko.computed(function () {
               _self.selectedText = ko.computed(function () {
                    var index = _self.selectedIndex();
                    return (_self.list()[index]) ? _self.list()[index].label() : "";
                }, _self);
                }, _self);
                
                _self.clear = function (value) {
                    _self.selectedValue(value ? value : "");
                };
            }
 
            <!-- Step 7 - Create ViewModel for whatever you need -->
            function SurveyAnswerViewModel() {
                var self = this;
                 
                <!-- Step 8 - Create an observable list instance -->
                self.dataModel = new SelectableListDataModel();
                self.dataModel.labels = new Array("Good", "Average", "Poor");
                self.dataModel.values = new Array(10,5,1);
                self.dataModel.selectedValue = 10;
                
                <!-- Step 9 - Create a SelectViewModel instance -->
                self.selectGroup1 = new SelectViewModel(self.dataModel);                       
                 
                <!-- Step 10 - Create a computed value to require a selection before submitting -->
                self.canClick = ko.computed( function() {
                    return self.selectGroup1.selectedValue() != "";
                }, self);
                
                <!-- Step 11 - Make some button methods for this example -->
                self.submitClick = function(){
                    // Do something here
                }
                
                self.resetClick = function(){
                    self.selectGroup1.clear();
                }
            }
            
            <!-- Step 12 - Create a computed value to require a selection before submitting -->   
            ko.applyBindings(new SurveyAnswerViewModel());
        });
    </script>
</head>
<body>
    <!-- Step 13 - Create a drop down select item -->
    <select data-bind="options: selectGroup1.list, optionsText: 'label', optionsValue: 'value', value: selectGroup1.selectedValue"></select>
    <br />
    
    <!-- Step 14 - Add html elements to see other properties -->
    <p data-bind="text: 'Index: ' +  selectGroup1.selectedIndex()"></p>
    <p data-bind="text: 'Value: ' +  selectGroup1.selectedValue()"></p>
    <p data-bind="text: 'Text: ' +  selectGroup1.selectedText()"></p>
     
    <!-- Step 15 - Add a button and bind its to methods -->
    <button type="submit" id="btnSubmit" data-bind="enable: canClick, click: submitClick">Submit</button>
    <button type="reset" id="btnReset" data-bind="enable: canClick, click: resetClick">Reset</button>
 
</body>
</html>

RadioButton web control with Knockout.js and MVVM

Here is an example of a RadioButton control using Knockout and MVVM. Hope this helps anyone looking.

<!-- Step 1 - Create the HTML File or the View -->
<!DOCTYPE html>
<html>
<head>
    <!-- Step 2 - Include jquery and knockout -->
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    <script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
     
    <!-- Step 3 - Add script to run when page loads -->
    <script type="text/javascript" >
        $(document).ready(function(){
 
            <!-- Step 4 - Add a RadioButtonModel -->
            var RadioButtonModel = function(parent, inText, inValue, inGroupName, canClickMethod) {
                    // Private
                    var _self = this;
                    var _canClickMethod = (canClickMethod) ? canClickMethod : function() { return true; };
                    var _parent = parent;

                    // Public
                    this.text = ko.observable(inText);
                    this.value = ko.observable(inValue);
                    this.group = ko.observable(inGroupName);
                    this.class = ko.observable();
                    this.isSelected = ko.computed(function() {
                        return (_parent && _parent.selectedValue) ? _parent.selectedValue() == _self.value() : false;
                    }, _self);
                    _self.canClick = ko.computed(function() { return _canClickMethod(); });
                };
                
                
            <!-- Step 5 - Add a RadioButtonViewModel -->
            var RadioButtonViewModel = function (rbLabels, rbValues, group, defaultValue) {
                // Private
                var _self = this;
                var _rbLables = rbLabels;
                var _rbValues = rbValues;
                var _group = group;
                var _defaultValue = defaultValue;                

                // Public
                _self.selectedValue = ko.observable(_defaultValue);
                
                _self.list = ko.observableArray();
                for (var i = 0; i < _rbLables.length; i++) {
                    _self.list.push(new RadioButtonModel(_self, _rbLables[i], _rbValues[i], _group));
                }

                _self.selectedIndex = ko.computed(function () {
                    var i = 0;
                    var foundIndex = -1;
                    ko.utils.arrayForEach(_self.list(), function (item) {
                        if (_self.selectedValue() == item.value()) {
                            foundIndex = i;
                        }
                        i++;
                    });
                    return foundIndex;
                }, _self);

                _self.selectedText = ko.computed(function () {
                    return (_self.list()[_self.selectedIndex()]) ? _self.list()[_self.selectedIndex()].text() : "";
                }, _self);
                
                _self.clear = function(value){
                    _self.selectedValue(value ? value : "");
                }
                
            }
 
            <!-- Step 6 - Create ViewModel for whatever you need -->
            function SurveyAnswerViewModel() {
                var self = this;
                 
                <!-- Step 7 - Create an observable list instance -->
                self.rbGroup1 = new RadioButtonViewModel(new Array("Good", "Average", "Poor"), new Array(10,5,1), "Group1", 10);                           
                 
                <!-- Step 8 - Create a computed value to require a selection before submitting -->
                self.canClick = ko.computed( function() {
                    return self.rbGroup1.selectedValue() != "";
                }, self);
                
                <!-- Step 9 - Make some button methods for this example -->
                self.submitClick = function(){
                    // Do something here
                }
                
                self.resetClick = function(){
                    self.rbGroup1.clear();
                }                 
            }
            
            <!-- Step 10 - Create a computed value to require a selection before submitting -->   
            ko.applyBindings(new SurveyAnswerViewModel());
        });
    </script>
</head>
<body>
    <!-- Step 11 - Create a div containing the html for one radio button and bind to foreach: list -->
    <div data-bind="foreach: rbGroup1.list">
        <div>
            <input type="radio" data-bind="attr: {name: group}, value: value, checked: $root.rbGroup1.selectedValue, checkedValue: value" />
            <span data-bind="text: $index() + '. ' + text()"></span>
            <span data-bind="text: 'Is selected: ' + isSelected()"></span>
        </div>
    </div>
    <br />
    
    <!-- Step 12 - Add html elements to see other properties -->
    <p data-bind="text: rbGroup1.selectedValue"></p>
    <p data-bind="text: rbGroup1.selectedText"></p>
     
    <!-- Step 13 - Add a button and bind its to methods -->
    <button type="submit" id="btnSubmit" data-bind="enable: canClick, click: submitClick">Submit</button>
    <button type="reset" id="btnReset" data-bind="enable: canClick, click: resetClick">Reset</button>
 
</body>
</html>

Using slideToggle with Knockout’s MVVM

I recommend you use the third option: Option 3 – Boolean binding using a custom binding handler called slideToggle

<!-- Step 1a - Create the HTML File or the View -->
<!DOCTYPE html>
<html>
<head>
    <!-- Step 2 - Include jquery and knockout -->
    <script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
    <script type="text/javascript" src="http://knockoutjs.com/downloads/knockout-3.0.0.js"></script>
     
    <!-- Step 3 - Add script to run when page loads -->
    <script type="text/javascript">
        $(document).ready(function(){
         
            <!-- Step 4 - Create a ViewModel -->           
            function viewModel() {
                _self = this;
                _self.showHideChild = function(viewModel, event) {
                    $(event.currentTarget).children('div').slideToggle()
                };
                _self.showHideNextSibling = function(viewModel, event) {
                    var siblings = $(event.currentTarget).siblings('div');
                    for (var i=0;i<siblings.length;i++) {
                        if (siblings[i].previousElementSibling == event.currentTarget ) {
                            $(siblings[i]).slideToggle();
                        }
                    }                 
                };
                _self.isVisible = ko.observable(false);
                _self.showHide = function() {
                    _self.isVisible(!_self.isVisible());
                }
            };
           
            ko.bindingHandlers.slideToggle = {
                init: function (element, valueAccessor) {
                    var value = valueAccessor();
                    $(element).toggle(ko.utils.unwrapObservable(value));
                },
                update: function (element, valueAccessor) {
                    var value = valueAccessor();
                    var isVisible = element.offsetWidth > 0 && element.offsetHeight > 0;
                    if (ko.utils.unwrapObservable(value) != isVisible) {
                        $(element).slideToggle();
                    }
                }
            };
           
            <!-- Step 5 -  Activates knockout.js bindings -->
          ko.applyBindings(new viewModel());
        });
    </script>
</head>
<!-- Step 4 - Create a HTML Elements with bindings -->
<body style="">
    <div>
        Option 1 - Child div
        <div id="child1" data-bind="click: showHideChild" style="border:2px solid;">
        Click me
            <div id="child2" style="display: none;">
              Now you see me!
            </div>
        </div>
        
        Option 2 - Siblings div
        <div id="sib1" style="border:2px solid;">
            <div id="sib2" data-bind="click: showHideNextSibling" >
            Click me
            </div>
            <div id="sib3" style="display: none;">
            Now you see me!
            </div>
            <div id="sib4">
            You should always see me.
            </div>
        </div>
        Option 3 - Boolean binding using a custom binding handler called slideToggle 
        <div id="bool1" style="border:2px solid;">
            <div id="bool2" data-bind="click: showHide" >
            Click me
            </div>
            <div id="bool3" data-bind="slideToggle: isVisible">
            Now you see me!
            </div>
        </div>
    </div>
</body>
</html>