#StackBounty: #c# #visual-studio #visual-studio-extensions #vsix #envdte VS Extension: TextPoint.GreaterThan / LessThan very slow for l…

Bounty: 50

I’m working on a VS Extension that needs to be aware of which class member the text-cursor is currently located in (methods, properties, etc). It also needs an awareness of the parents (e.g. class, nested classes, etc). It needs to know the type, name, and line number of the member or class. When I say “Type” I mean “method” or “property” not necessarily a “.NET Type”.

Currently I have it working with this code here:

public static class CodeElementHelper
{
    public static CodeElement[] GetCodeElementAtCursor(DTE2 dte)
    {
        try
        {
            var cursorTextPoint = GetCursorTextPoint(dte);

            if (cursorTextPoint != null)
            {
                var activeDocument = dte.ActiveDocument;
                var projectItem = activeDocument.ProjectItem;
                var codeElements = projectItem.FileCodeModel.CodeElements;
                return GetCodeElementAtTextPoint(codeElements, cursorTextPoint).ToArray();
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("[DBG][EXC] - " + ex.Message + " " + ex.StackTrace);
        }

        return null;
    }

    private static TextPoint GetCursorTextPoint(DTE2 dte)
    {
        var cursorTextPoint = default(TextPoint);

        try
        {
            var objTextDocument = (TextDocument)dte.ActiveDocument.Object();
            cursorTextPoint = objTextDocument.Selection.ActivePoint;
        }
        catch (Exception ex)
        {
            Debug.WriteLine("[DBG][EXC] - " + ex.Message + " " + ex.StackTrace);
        }

        return cursorTextPoint;
    }

    private static List<CodeElement> GetCodeElementAtTextPoint(CodeElements codeElements, TextPoint objTextPoint)
    {
        var returnValue = new List<CodeElement>();

        if (codeElements == null)
            return null;

        int count = 0;
        foreach (CodeElement element in codeElements)
        {
            if (element.StartPoint.GreaterThan(objTextPoint))
            {
                // The code element starts beyond the point
            }
            else if (element.EndPoint.LessThan(objTextPoint))
            {
                // The code element ends before the point
            }
            else
            {
                if (element.Kind == vsCMElement.vsCMElementClass ||
                    element.Kind == vsCMElement.vsCMElementProperty ||
                    element.Kind == vsCMElement.vsCMElementPropertySetStmt ||
                    element.Kind == vsCMElement.vsCMElementFunction)
                {
                    returnValue.Add(element);
                }

                var memberElements = GetCodeElementMembers(element);
                var objMemberCodeElement = GetCodeElementAtTextPoint(memberElements, objTextPoint);

                if (objMemberCodeElement != null)
                {
                    returnValue.AddRange(objMemberCodeElement);
                }

                break;
            }
        }

        return returnValue;
    }

    private static CodeElements GetCodeElementMembers(CodeElement codeElement)
    {
        CodeElements codeElements = null;

        if (codeElement is CodeNamespace)
        {
            codeElements = (codeElement as CodeNamespace).Members;
        }
        else if (codeElement is CodeType)
        {
            codeElements = (codeElement as CodeType).Members;
        }
        else if (codeElement is CodeFunction)
        {
            codeElements = (codeElement as CodeFunction).Parameters;
        }

        return codeElements;
    }
}

So that currently works, if I call GetCodeElementAtCursor I will get the member and it’s parents back. (This is kinda old code, but I believe I originally snagged it from Carlos’ blog and ported it from VB).

My problem is that when my extension is used on code that is very large, like auto-generated files with a couple thousand lines, for example, it brings VS to a crawl. Almost unusable. Running a profiler shows that the hot lines are

private static List<CodeElement> GetCodeElementAtTextPoint(CodeElements codeElements, TextPoint objTextPoint)
{
    foreach (CodeElement element in codeElements)
    {
        ...
/*-->*/ if (element.StartPoint.GreaterThan(objTextPoint)) // HERE <---
        {
            // The code element starts beyond the point
        }
/*-->*/ else if (element.EndPoint.LessThan(objTextPoint)) // HERE <----
        {
            // The code element ends before the point
        }
        else
        {
            ...
            var memberElements = GetCodeElementMembers(element);
/*-->*/     var objMemberCodeElement = GetCodeElementAtTextPoint(memberElements, objTextPoint); // AND, HERE <---

            ...
        }
    }

    return returnValue;
}

So the third one is obvious, it’s a recursive call to itself so whatever is affecting it will affect a call to itself. The first two, however, I’m not sure how to fix.

  • Is there an alternative method I could use to retrieve the type of member my cursor is on (class, method, prop, etc), the name, line #, and the parents?
  • Is there something that I could do to make the TextPoint.GreaterThan and TestPoint.LessThan methods perform better?
  • Or, am I S.O.L.?

Whatever the method is, it just needs to support VS2015 or newer.

Thank you!

UPDATE: To answer Sergey’s comment – it does indeed seem to be caused by .GreaterThan / .LessThan(). I’ve separated the code and the slow-down is definitely occurring on those method calls, NOT the property accessor for element.StartPoint and element.EndPoint.

enter image description here


Get this bounty!!!

#StackBounty: #c++ #osx #docker #virtual-memory #docker-build "virtual memory exhausted" when building Docker image

Bounty: 50

When building a Docker image, there’s some compilations of C++ scripts and I ended up with errors like:

src/amun/CMakeFiles/cpumode.dir/build.make:134: recipe for target 'src/amun/CMakeFiles/cpumode.dir/cpu/decoder/encoder_decoder_state.cpp.o' failed
virtual memory exhausted: Cannot allocate memory

But when building the same .cpp code on the host machine, it works fine.


After some checking, the error message seems to be similar to the one that people get on a Raspberry Pi, https://www.bitpi.co/2015/02/11/how-to-change-raspberry-pis-swapfile-size-on-rasbian/

And after some more googling, this post on the <a href="https://discussions.apple.com/thread/7417584?start=0&tstart=0“>Mac forum says that:

Swapfiles are dynamically created as needed, until either the disk is
full, or the kernel runs out of page table space. I do not think you
can change the page table space limits in the Mac OS X kernel. I have
not seen anything in all the years I’ve been using OS X.

Is there a way to increase the swap space for Docker build on Mac OS?

If not, how else can be done to overcome the “virtual memory exhausted” error when building a Docker image?


Get this bounty!!!

#StackBounty: #c# #mongodb #composite-primary-key MongoDB Composite Key: InvalidOperationException: {document}.Identity is not supported

Bounty: 250

I am having issues with hydrating a class which consists of a composite ID which in turn has a base class, I am getting an error saying InvalidOperationException: {document}.Identity is not supported.

The class i am trying to write to the database is below:

public class Product
{
    public readonly Sku Sku;
    public string Name { get; private set; }
    public string Description { get; private set; }
    public bool IsArchived { get; private set; }
    public Identity<Product> Identity => Sku;

    public Product(Sku sku, string name, bool isArchived)
    {
        Sku = sku;
        Name = name;
        IsArchived = isArchived;
    }
}

In turn has an ID Sku which is a class formed of the below composite values (VendorId and a local Value within Sku):

public class Sku : Identity<Product>
{
    public readonly VendorId VendorId;
    public readonly string Value;

    public Sku(VendorId vendorId, string value)
    {
        VendorId = vendorId;
        Value = value;
    }

    protected override IEnumerable<object> GetIdentityComponents()
    {
        return new object[] {VendorId, Value};
    }
}

public class VendorId : Identity<Vendor>
{
    public readonly string Value;

    public VendorId(string value)
    {
        Value = value;
    }

    protected override IEnumerable<object> GetIdentityComponents()
    {
        return new object[] {Value};
    }
}

I have a base class for my entities Identity which i use in my DDD libraries, essentially the ToString() output here could be used as the ID if this would simplify things:

public abstract class Identity<T> : IEquatable<Identity<T>>
{
    public override bool Equals(object obj) { /* snip */ }
    public bool Equals(Identity<T> other) { /* snip */ }
    public override int GetHashCode() { /* snip */ }

    public override string ToString()
    {
        var id = string.Empty;

        foreach (var component in GetIdentityComponents())
        {
            if (string.IsNullOrEmpty(id))
                id = component.ToString(); // first item, dont add a divider
            else
                id += "." + component;
        }

        return id;
    }

    protected abstract IEnumerable<object> GetIdentityComponents();
}

I register the mappings on app start:

// rehydrate readonly properties via matched constructor
// https://stackoverflow.com/questions/39604820/serialize-get-only-properties-on-mongodb
ConventionRegistry
    .Register(nameof(ImmutablePocoConvention), new ConventionPack { new ImmutablePocoConvention() }, _ => true);

BsonClassMap.RegisterClassMap<Product>(cm =>
{
    cm.AutoMap();
    cm.MapIdMember(c => c.Sku);
});

BsonClassMap.RegisterClassMap<Vendor>(cm =>
{
    cm.AutoMap();
    cm.MapIdMember(c => c.Id);
});

However when i go and write, i get `InvalidOperationException: {document}.Identity is not supported.`

var product = new Product(new Sku(new VendorId("dell"), "12434" ),"RAM", false );

this.Database
    .GetCollection<T>(product.GetType().FullName)()
    .ReplaceOneAsync(x=>x.Identity.Equals(entity.Identity), entity, new UpdateOptions() {IsUpsert = true})
    .Wait();

Quite stuck and not sure if this is now overly complicated by me persisting direct from my entities layer (or if i just use an automapper and simpler POCO)… or if I am missing some mapping directives.

Appreciate any help or pointers.


Get this bounty!!!

#StackBounty: #c# #oauth #exchangewebservices How to authenticate with OAuth to access EWS APIs

Bounty: 50

My web service is currently doing basic username/password authentication in order to subscribe the exchange user for receiving the events (like new mail event etc) like below:

var service = new ExchangeService(exchangeVersion)
                                  {
                                      KeepAlive = true,
                                      Url = new Uri("some autodiscovery url"),
                                      Credentials = new NetworkCredential(username, password)
                                  };

var subscription = service.SubscribeToPushNotifications(
                                    new[] { inboxFolderFoldeID },
                                    new Uri("some post back url"),
                                    15,
                                    null,
                                    EventType.NewMail,
                                    EventType.Created,
                                    EventType.Deleted,
                                    EventType.Modified,
                                    EventType.Moved,
                                    EventType.Copied);

Now, I am supposed to replace the authentication mechanism to use the modern OAuth protocol. I saw some examples but all of them seem to be talking about authenticating the client (https://msdn.microsoft.com/en-us/library/office/dn903761%28v=exchg.150%29.aspx?f=255&MSPPError=-2147217396) but nowhere I was able to find an example of how to authenticate an exchange user with OAuth protocol. Any code sample will help a lot. Thanks.


Get this bounty!!!

#StackBounty: #c# #sql-server #database #entity-framework #code-first why code first want to create index column?

Bounty: 50

I have two table like below:

[Table("MyFlashCard")]
public partial class MyFlashCard
{
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
    public MyFlashCard()
    {
        MyFlashCardPics = new HashSet<MyFlashCardPic>();
    }
    public int Id { get; set; }

    public int? FaslID { get; set; }

    public virtual FasleManJdl FasleManJdl { get; set; }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
    public virtual ICollection<MyFlashCardPic> MyFlashCardPics { get; set; }
}

[Table("MyFlashCardPic")]
public partial class MyFlashCardPic
{
    public int Id { get; set; }

    [ForeignKey("MyFlashCard")]
    public int MyFlashCardId { get; set; }

    public virtual MyFlashCard MyFlashCard { get; set; }
}

and

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
        modelBuilder.Entity<MyFlashCard>()
            .HasMany(e => e.MyFlashCardPics)
            .WithRequired(e => e.MyFlashCard)
            .HasForeignKey(e => e.MyFlashCardId)
            .WillCascadeOnDelete();
  }

and when i add migration it will create the below code

CreateTable(
            "dbo.MyFlashCardPic",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    MyFlashCardId = c.Int(nullable: false),
                    MyFlashCard_Id = c.Int(),
                    MyFlashCard_Id1 = c.Int(),
                })
            .PrimaryKey(t => t.Id)
            .ForeignKey("dbo.MyFlashCard", t => t.MyFlashCard_Id)
            .ForeignKey("dbo.MyFlashCard", t => t.MyFlashCard_Id1)
            .ForeignKey("dbo.MyFlashCard", t => t.MyFlashCardId, cascadeDelete: true)
            .Index(t => t.MyFlashCardId)
            .Index(t => t.MyFlashCard_Id)
            .Index(t => t.MyFlashCard_Id1);

i have just MyFlashCardId column in MyFlashCardPic table but it want to create another column like: MyFlashCard_Id,MyFlashCard_Id1

I want to know why this happens and how prevent it?

when i delete these columns from above migration,after creating database(with update-database command) it will throws below error when i want to use MyFlashCardPic entity

Invalid column name ‘MyFlashCard_Id1’ , Invalid column name ‘MyFlashCard_Id’

and when i don’t delete these columns from migration i have problem in editing flashcard that have pics like another question i have recently

How to find out context objects that one entity is attached to?

another point is that without

[ForeignKey("MyFlashCard")]

attribute it will create 3 index column and without

modelBuilder.Entity<MyFlashCard>()
            .HasMany(e => e.MyFlashCardPics)
            .WithRequired(e => e.MyFlashCard)
            .HasForeignKey(e => e.MyFlashCardId)
            .WillCascadeOnDelete();

in OnModeling it will create 4 index column


Get this bounty!!!

#StackBounty: #c++ #library #pathfinding #fluent-interface Pathfinding library in C++ with fluent API

Bounty: 50

Introduction

I have this C++ pathfinding library. My primary requirement is that a client programmer may couple his/her own graph representation and the library will work with that representation.

The only API a client graph node type is to implement is begin() and end() which should return a sequence of neighbors in case of undirected graphs, or a sequence of child nodes in case of directed graphs.

What comes to weight function, my library expects only that the weight type is default-constructible (which must represent the “zero-weight”) and a operator>. In my 2nd demo, the weights are $2 times 2$-matrices, for example.

Critique request

Please tell me anything that comes to mind. However, I am most interested in hearing the comments regarding

  • const (in)correctness,
  • efficiency,
  • adherence to C++ programming idioms.

Code

pathfinding.hpp

#ifndef NET_CODERODDE_PATHFINDING_HPP
#define NET_CODERODDE_PATHFINDING_HPP

#include "a_star.hpp"
#include "dijkstra.hpp"
#include "heuristic_function.hpp"
#include "weight_function.hpp"
#include "weighted_path.hpp"

namespace net {
namespace coderodde {
namespace pathfinding {

    template<typename Node, typename Weight>
    class heuristic_function_selector {
    public:
        heuristic_function_selector(
                                Node& source,
                                Node& target,
                                weight_function<Node, Weight>* weight_function)
        :
        m_source{source},
        m_target{target},
        m_weight_function{weight_function} {}

        weighted_path<Node, Weight> without_heuristic_function() {
            return search(m_source, m_target, *m_weight_function);
        }

        weighted_path<Node, Weight>
        with_heuristic_function(
                        heuristic_function<Node, Weight>* heuristic_function) {
            return search(m_source,
                          m_target,
                          *m_weight_function,
                          *heuristic_function);
        }

    private:
        Node m_source;
        Node m_target;
        weight_function<Node, Weight>* m_weight_function;
    };

    template<typename Node, typename Weight>
    class weight_function_selector {
    public:
        weight_function_selector(Node& source, Node& target) :
        m_source{source},
        m_target{target} {}

        heuristic_function_selector<Node, Weight>
        with_weights(weight_function<Node, Weight>* wf) {
            return heuristic_function_selector<Node, Weight>(m_source,
                                                             m_target,
                                                             wf);
        }

    private:
        Node m_source;
        Node m_target;
    };

    template<typename Node, typename Weight>
    class target_node_selector {
    public:
        target_node_selector(Node source) : m_source{source} {}
        weight_function_selector<Node, Weight> to(Node& target) {
            return weight_function_selector<Node, Weight>(m_source, target);
        }

    private:
        Node m_source;
    };

    template<typename Node, typename Weight>
    class source_node_selector {
    public:
        target_node_selector<Node, Weight> from(Node& source) {
            return target_node_selector<Node, Weight>{source};
        }
    };

    template<typename Node, typename Weight>
    source_node_selector<Node, Weight> find_shortest_path() {
        return source_node_selector<Node, Weight>{};
    }

} // End of namespace net::coderodde::pathfinding.
} // End of namespace net::coderodde.
} // End of namespace net.

#endif // NET_CODERODDE_PATHFINDING_HPP

a_star.hpp

#ifndef NET_CODERODDE_PATHFINDING_A_STAR_HPP
#define NET_CODERODDE_PATHFINDING_A_STAR_HPP

#include "child_node_iterator.hpp"
#include "heuristic_function.hpp"
#include "path_not_found_exception.hpp"
#include "weighted_path.hpp"
#include "weight_function.hpp"
#include <algorithm>
#include <iostream>
#include <queue>
#include <unordered_map>
#include <unordered_set>

namespace net {
namespace coderodde {
namespace pathfinding {

    template<typename Node, typename Weight>
    struct node_holder {
        Node* m_node;
        Weight m_f;

        node_holder(Node* node, Weight f) : m_node{node}, m_f{f} {}
    };

    template<typename Node, typename Weight, typename Cmp>
    void remove_and_delete_all_node_holders(
                std::priority_queue<node_holder<Node, Weight>*,
                                            std::vector<node_holder<Node, Weight>*>,
                                            Cmp>& open) {
        while (!open.empty()) {
            node_holder<Node, Weight>* current_node_holder = open.top();
            open.pop();
            delete current_node_holder;
        }
    }

    template<typename Node, typename Weight>
    weighted_path<Node, Weight>
    traceback_path(Node& target,
                   std::unordered_map<Node*, Node*>& parents,
                   weight_function<Node, Weight>& w) {
        std::vector<Node*> path;
        Node* current_node = &target;

        while (current_node) {
            path.push_back(current_node);
            current_node = parents[current_node];
        }

        std::reverse(path.begin(), path.end());

        Weight total_weight {};

        for (size_t i = 0; i < path.size() - 1; ++i) {
            total_weight += w(*path[i], *path[i + 1]);
        }

        return weighted_path<Node, Weight>(path, total_weight);
    }

    template<typename Node, typename Weight>
    weighted_path<Node, Weight> search(Node& source,
                                       Node& target,
                                       weight_function<Node, Weight>& w,
                                       heuristic_function<Node, Weight>& h) {

        auto cmp = [](node_holder<Node, Weight>* nh1,
                      node_holder<Node, Weight>* nh2) {
            return nh1->m_f > nh2->m_f;
        };

        std::priority_queue<node_holder<Node, Weight>*,
                            std::vector<node_holder<Node, Weight>*>,
                            decltype(cmp)> open(cmp);

        std::unordered_set<Node*> closed;
        std::unordered_map<Node*, Node*> parents;
        std::unordered_map<Node*, Weight> distances;

        open.push(new node_holder<Node, Weight>(&source, Weight{}));
        parents[&source] = nullptr;
        distances[&source] = Weight{};

        while (!open.empty()) {
            Node* current_node = open.top()->m_node;
            open.pop();

            if (*current_node == target) {
                remove_and_delete_all_node_holders(open);
                return traceback_path(*current_node, parents, w);
            }

            if (closed.find(current_node) != closed.end()) {
                continue;
            }

            closed.insert(current_node);

            for (Node& child_node : *current_node) {
                if (closed.find(&child_node) != closed.end()) {
                    continue;
                }

                Weight tentative_distance = distances[current_node] +
                w(*current_node, child_node);

                if (distances.find(&child_node) == distances.end()
                    || distances[&child_node] > tentative_distance) {
                    open.push(new node_holder<Node, Weight>(
                                        &child_node,
                                        tentative_distance + h(child_node)));
                    distances[&child_node] = tentative_distance;
                    parents[&child_node] = current_node;
                }
            }
        }

        remove_and_delete_all_node_holders(open);
        throw path_not_found_exception<Node>(source, target);
    }
} // End of namespace net::coderodde::pathfinding.
} // End of namespace net::coderodde.
} // End of namespace net.

#endif // NET_CODERODDE_PATHFINDING_A_STAR_HPP

dijkstra.hpp

#ifndef NET_CODERODDE_PATHFINDING_DIJKSTRA_HPP
#define NET_CODERODDE_PATHFINDING_DIJKSTRA_HPP

#include "a_star.hpp"
#include "heuristic_function.hpp"

namespace net {
namespace coderodde {
namespace pathfinding {

    template<typename Node, typename DistanceType>
    class zero_heuristic :
    public virtual heuristic_function<Node, DistanceType> {

    public:
        DistanceType operator()(const Node& target) const {
            DistanceType zero{};
            return zero;
        }
    };

    template<typename Node, typename Weight>
    weighted_path<Node, Weight> search(Node& source,
                                       Node& target,
                                       weight_function<Node, Weight>& w) {
        zero_heuristic<Node, Weight> h;
        return search(source, target, w, h);
    }

} // End of namespace net::coderodde::pathfinding.
} // End of namespace net::coderodde.
} // End of namespace net.

#endif // NET_CODERODDE_PATHFINDING_DIJKSTRA_HPP

child_node_iterator.hpp

#ifndef NET_CODERODDE_PATHFINDING_FORWARD_NODE_EXPANDER_HPP
#define NET_CODERODDE_PATHFINDING_FORWARD_NODE_EXPANDER_HPP

namespace net {
namespace coderodde {
namespace pathfinding {

    template<typename Node>
    class child_node_iterator {

    public:
        virtual child_node_iterator<Node>& operator++() = 0;
        virtual Node& operator*()                       = 0;
    };

} // End of namespace net::coderodde::pathfinding.
} // End of namespace net::coderodde.
} // End of namespace net.

#endif // End of NET_CODERODDE_PATHFINDING_FORWARD_NODE_EXPANDER_HPP.

heuristic_function.hpp

#ifndef NET_CODERODDE_PATHFINDING_HEURISTIC_FUNCTION_HPP
#define NET_CODERODDE_PATHFINDING_HEURISTIC_FUNCTION_HPP

namespace net {
namespace coderodde {
namespace pathfinding {

    template<typename Node, typename DistanceType>
    class heuristic_function {

    public:
        virtual DistanceType operator()(const Node& target) const = 0;
    };

} // End of namespace net::coderodde::pathfinding.
} // End of namespace net::coderodde.
} // End of namespace net.

#endif // End of NET_CODERODDE_PATHFINDING_HEURISTIC_FUNCTION_HPP.

path_not_found_exception.hpp

#ifndef NET_CODERODDE_PATHFINDING_PATH_NOT_FOUND_EXCEPTION_HPP
#define NET_CODERODDE_PATHFINDING_PATH_NOT_FOUND_EXCEPTION_HPP

#include <sstream>
#include <stdexcept>

namespace net {
namespace coderodde {
namespace pathfinding {

    template<typename Node>
    class path_not_found_exception : public virtual std::logic_error {
    public:
        path_not_found_exception(const Node& source,
                                 const Node& target)
        :
        std::logic_error{""},
        m_source{&source},
        m_target{&target}
        {}

        const char* what() {
            std::stringstream ss;
            ss << "A path from source {" << *m_source << "} to target {"
               << *m_target << "} not found.";
            return ss.str().c_str();
        }

    private:
        const Node* m_source;
        const Node* m_target;
    };

} // End of namespace net::coderodde::pathfinding.
} // End of namespace net::coderodde.
} // End of namespace net.

#endif // NET_CODERODDE_PATHFINDING_PATH_NOT_FOUND_EXCEPTION_HPP

weight_function.hpp

#ifndef NET_CODERODDE_PATHFINDING_WEIGHT_FUNCTION_HPP
#define NET_CODERODDE_PATHFINDING_WEIGHT_FUNCTION_HPP

namespace net {
namespace coderodde {
namespace pathfinding {

    template<typename Node, typename WeightType>
    class weight_function {

    public:
        virtual WeightType operator()(const Node& a, const Node& b) = 0;
    };

} // End of namespace net::coderodde::pathfinding.
} // End of namespace net::coderodde.
} // End of namespace net.

#endif // NET_CODERODDE_PATHFINDING_WEIGHT_FUNCTION_HPP

weighted_path.hpp

#ifndef NET_CODERODDE_PATHFINDING_WEIGHTED_PATH_HPP
#define NET_CODERODDE_PATHFINDING_WEIGHTED_PATH_HPP

#include <iostream>

namespace net {
namespace coderodde {
namespace pathfinding {

    template<typename Node, typename Weight>
    class weighted_path {
    public:
        weighted_path(std::vector<Node*> path_vector, Weight total_weight)
        :
        m_path_vector{path_vector},
        m_total_weight{total_weight}
        {}

        Node& node_at(size_t index) {
            return *m_path_vector->at(index);
        }

        Weight total_weight() const {
            return m_total_weight;
        }

    private:
        std::vector<Node*> m_path_vector;
        Weight             m_total_weight;

        friend std::ostream& operator<<(std::ostream& out, weighted_path& path) {
            std::string separator{};
            out << "[";

            for (Node* node : path.m_path_vector) {
                out << separator;
                separator = ", ";
                out << *node;
            }

            return out << "]";
        }
    };

} // End of namespace net::coderodde::pathfinding.
} // End of namespace net::coderodde.
} // End of namespace net.

#endif // NET_CODERODDE_PATHFINDING_WEIGHTED_PATH_HPP

main.cpp

#include "pathfinding.hpp"
#include "child_node_iterator.hpp"
#include "path_not_found_exception.hpp"

#include <cstdlib>
#include <functional>
#include <iostream>
#include <unordered_set>
#include <utility>
#include <vector>

using net::coderodde::pathfinding::child_node_iterator;
using net::coderodde::pathfinding::heuristic_function;
using net::coderodde::pathfinding::weight_function;
using net::coderodde::pathfinding::weighted_path;
using net::coderodde::pathfinding::find_shortest_path;
using net::coderodde::pathfinding::path_not_found_exception;

// This is just a sample graph node type. The only requirement for coupling it
// with the search algorithms is 'bool operator==(const grid_node& other) const'
// and 'begin()' + 'end()' for iterating over the child nodes.
class grid_node {
private:

    class grid_node_neighbor_iterator : public child_node_iterator<grid_node> {
    private:
        std::vector<grid_node*>* m_neighbor_vector;
        std::size_t m_index;

    public:
        grid_node_neighbor_iterator(std::vector<grid_node*>* neighbor_vector,
                                    std::size_t index)
        :
        m_neighbor_vector{neighbor_vector},
        m_index{index} {}

        ~grid_node_neighbor_iterator() {
            delete m_neighbor_vector;
        }

        grid_node_neighbor_iterator& operator++() {
            ++m_index;
            return *this;
        }

        bool operator==(grid_node_neighbor_iterator& other) const {
            return m_index == other.m_index;
        }

        bool operator!=(grid_node_neighbor_iterator& other) const {
            return m_index != other.m_index;
        }

        grid_node& operator*() {
            return *m_neighbor_vector->at(m_index);
        }
    };

public:

    grid_node(int x, int y, bool traversable);

    void set_top_neighbor    (grid_node& neighbor);
    void set_bottom_neighbor (grid_node& neighbor);
    void set_left_neighbor   (grid_node& neighbor);
    void set_right_neighbor  (grid_node& neighbor);

    bool operator==(const grid_node& other) {
        return m_x == other.m_x && m_y == other.m_y;
    }

    grid_node_neighbor_iterator begin() {
        std::vector<grid_node*>* neighbor_vector =
        new std::vector<grid_node*>;

        if (m_top_neighbor && m_top_neighbor->m_traversable) {
            neighbor_vector->push_back(m_top_neighbor);
        }

        if (m_bottom_neighbor && m_bottom_neighbor->m_traversable) {
            neighbor_vector->push_back(m_bottom_neighbor);
        }

        if (m_left_neighbor && m_left_neighbor->m_traversable) {
            neighbor_vector->push_back(m_left_neighbor);
        }

        if (m_right_neighbor && m_right_neighbor->m_traversable) {
            neighbor_vector->push_back(m_right_neighbor);
        }

        return grid_node_neighbor_iterator(neighbor_vector, 0);
    }

    grid_node_neighbor_iterator end() {
        std::size_t neighbor_count = 0;

        if (m_top_neighbor && m_top_neighbor->m_traversable) {
            neighbor_count++;
        }

        if (m_bottom_neighbor && m_bottom_neighbor->m_traversable) {
            neighbor_count++;
        }

        if (m_left_neighbor && m_left_neighbor->m_traversable) {
            neighbor_count++;
        }

        if (m_right_neighbor && m_right_neighbor->m_traversable) {
            neighbor_count++;
        }

        return grid_node_neighbor_iterator(nullptr, neighbor_count);
    }

    // Heuristic function must know the coordinates:
    friend class grid_node_heuristic_function;

    // For printing to, say, cout:
    friend std::ostream& operator<<(std::ostream& out, const grid_node& gn);

    // std::hash and std::equal_to so that the internal unordered_* data
    // structures may work with grid nodes via pointers:
    friend class std::hash<grid_node*>;
    friend class std::equal_to<grid_node*>;

private:

    int m_x;
    int m_y;

    bool   m_traversable;

    grid_node* m_top_neighbor;
    grid_node* m_bottom_neighbor;
    grid_node* m_left_neighbor;
    grid_node* m_right_neighbor;
};

grid_node::grid_node(int x, int y, bool traversable)
:
m_x{x},
m_y{y},
m_traversable{traversable}
{
    m_top_neighbor    = nullptr;
    m_bottom_neighbor = nullptr;
    m_left_neighbor   = nullptr;
    m_right_neighbor  = nullptr;
}

void grid_node::set_top_neighbor(grid_node& neighbor)
{
    m_top_neighbor = &neighbor;
}

void grid_node::set_bottom_neighbor(grid_node& neighbor)
{
    m_bottom_neighbor = &neighbor;
}

void grid_node::set_left_neighbor(grid_node& neighbor)
{
    m_left_neighbor = &neighbor;
}

void grid_node::set_right_neighbor(grid_node& neighbor)
{
    m_right_neighbor = &neighbor;
}

std::ostream& operator<<(std::ostream& out, const grid_node& gn)
{
    out << "{x=" << gn.m_x << ", y=" << gn.m_y << "}";
    return out;
}

// This class will be used as an EDGE WEIGHT:
class matrix {
public:
    matrix(int a1, int a2, int b1, int b2)
    :
    m_a1{a1},
    m_a2{a2},
    m_b1{b1},
    m_b2{b2}
    {}

    matrix() : matrix{0, 0, 0, 0} {}

    int determinant() const {
        return m_a1 * m_b2 - m_a2 * m_b1;
    }

    matrix operator+(const matrix& other) {
        return matrix{m_a1 + other.m_a1,
                      m_a2 + other.m_a2,
                      m_b1 + other.m_b1,
                      m_b2 + other.m_b2};
    }

    matrix& operator+=(const matrix& other) {
        m_a1 += other.m_a1;
        m_a2 += other.m_a2;
        m_b1 += other.m_b1;
        m_b2 += other.m_b2;
        return *this;
    }

    bool operator>(const matrix& other) {
        return abs(determinant()) > abs(other.determinant());
    }

    friend std::ostream& operator<<(std::ostream& out, const matrix& m) {
        return out << "{{" << m.m_a1 << ", " << m.m_a2 << "}, {"
                   << m.m_b1 << ", " << m.m_b2 << "}}";
    }

    friend class grid_node_heuristic_function;
    friend class std::hash<grid_node*>;
    friend class std::equal_to<grid_node*>;

private:
    int m_a1;
    int m_a2;
    int m_b1;
    int m_b2;
};

// A graph node type whose edge weights are matrix. This is just a demonstration
// of flexibility of the library.
class matrix_node {
private:

    class matrix_node_child_iterator :
    public child_node_iterator<matrix_node> {

    private:
        std::size_t m_index;
        std::vector<matrix_node*>* m_matrix_node_pointer_vector;

    public:
        matrix_node_child_iterator(
                        std::vector<matrix_node*>& matrix_node_pointer_vector,
                        std::size_t index)
        : m_matrix_node_pointer_vector{&matrix_node_pointer_vector},
          m_index{index} {}

        matrix_node_child_iterator& operator++() {
            m_index++;
            return *this;
        }

        bool operator!=(const matrix_node_child_iterator& other) {
            return m_index != other.m_index;
        }

        matrix_node& operator*() {
            return *m_matrix_node_pointer_vector->at(m_index);
        }
    };

public:

    matrix_node(size_t id) : m_id{id} {}

    bool operator==(const matrix_node& other) const {
        return m_id == other.m_id;
    }

    void add_neighbor(matrix_node& neighbor) {
        m_neighbors.push_back(&neighbor);
    }

    matrix_node_child_iterator begin() {
        return matrix_node_child_iterator(m_neighbors, 0);
    }

    matrix_node_child_iterator end() {
        return matrix_node_child_iterator(m_neighbors, m_neighbors.size());
    }

private:

    friend class std::hash<matrix_node>;
    friend class std::equal_to<matrix_node>;
    friend std::ostream& operator<<(std::ostream& out, const matrix_node& n);

    std::vector<matrix_node*> m_neighbors;
    size_t m_id;
};

std::ostream& operator<<(std::ostream& out, const matrix_node& node) {
    return out << "{id=" << node.m_id << "}";
}

namespace std {
    template<>
    struct hash<matrix_node> {
        std::size_t operator()(const matrix_node& node) const {
            return node.m_id;
        }
    };

    template<>
    struct equal_to<matrix_node> {
        bool operator()(const matrix_node& a, const matrix_node& b) const {
            return a.m_id == b.m_id;
        }
    };
}

class grid_node_weight_function :
public virtual weight_function<grid_node, int>
{
public:
    int operator()(const grid_node& a, const grid_node& b) {
        return 1;
    }
};

class grid_node_heuristic_function :
public virtual heuristic_function<grid_node, int>
{
public:
    grid_node_heuristic_function(const grid_node source)
    :
    m_source{source}
    {}

    int operator()(const grid_node& target) const {
        // Manhattan-distance:
        return abs(m_source.m_x - target.m_x) + abs(m_source.m_y - target.m_y);
    }

private:
    grid_node m_source;
};

class matrix_node_weight_function :
public virtual weight_function<matrix_node, matrix>
{
public:
    std::unordered_map<matrix_node, matrix>&
    operator[](const matrix_node& node) {
        return m_map[node];
    }

    matrix operator()(const matrix_node& tail, const matrix_node& head) override {
        return m_map[tail][head];
    }

private:
    std::unordered_map<matrix_node,
    std::unordered_map<matrix_node, matrix>> m_map;
};

namespace std {

    template<>
    struct hash<grid_node*> {
        std::size_t operator()(const grid_node* gn) const {
            return gn->m_x ^ gn->m_y;
        }
    };

    template<>
    struct equal_to<grid_node*> {
        bool operator()(const grid_node* a, const grid_node* b) const {
            return a->m_x == b->m_x && a->m_y == b->m_y;
        }
    };
}

int main(int argc, const char * argv[]) {
    std::vector<std::vector<int>> maze = {
        { 0, 0, 0, 1, 0, 0 },
        { 0, 1, 1, 1, 0, 0 },
        { 0, 0, 0, 1, 0, 0 },
        { 1, 1, 0, 1, 0, 0 },
        { 0, 0, 0, 1, 0, 0 },
        { 0, 1, 1, 1, 0, 0 },
        { 0, 0, 0, 0, 0, 0 },
    };

    std::vector<std::vector<grid_node>> grid_node_maze;

    for (size_t y = 0; y < maze.size(); ++y) {
        std::vector<grid_node> grid_node_maze_row;

        for (size_t x = 0; x < maze[y].size(); ++x) {
            grid_node_maze_row.push_back(grid_node(x, y, maze[y][x] != 1));
        }

        grid_node_maze.push_back(grid_node_maze_row);
    }

    for (size_t y = 0; y < grid_node_maze.size(); ++y) {
        for (int x = 0; x < grid_node_maze[0].size() - 1; ++x) {
            grid_node_maze[y][x].set_right_neighbor(grid_node_maze[y][x + 1]);
        }

        for (int x = 1; x < grid_node_maze[0].size(); ++x) {
            grid_node_maze[y][x].set_left_neighbor(grid_node_maze[y][x - 1]);
        }
    }

    for (size_t x = 0; x < grid_node_maze[0].size(); ++x) {
        for (int y = 0; y < grid_node_maze.size() - 1; ++y) {
            grid_node_maze[y][x].set_bottom_neighbor(grid_node_maze[y + 1][x]);
        }

        for (int y = 1; y < grid_node_maze.size(); ++y) {
            grid_node_maze[y][x].set_top_neighbor(grid_node_maze[y - 1][x]);
        }
    }

    grid_node_weight_function grid_node_wf;
    grid_node_heuristic_function grid_node_hf(grid_node_maze[6][5]);

    try {
        auto path = find_shortest_path<grid_node, int>()
                    .from(grid_node_maze[0][0])
                    .to(grid_node_maze[6][5])
                    .with_weights(&grid_node_wf)
                    .with_heuristic_function(&grid_node_hf);
        std::cout << path << "n";
        std::cout << "Final maze distance: " << path.total_weight() << "n";
    } catch (path_not_found_exception<grid_node>& ex) {
        std::cerr << ex.what() << "n";
    }

    ////////// MATRIX DEMO ///////////
    matrix_node a{1};
    matrix_node b{2};
    matrix_node c{3};
    matrix_node d{4};
    matrix_node e{5};

    matrix_node_weight_function matrix_wf;

    matrix mab{1,   2,  3, 4};
    matrix mac{1,  -2, -3, 4};
    matrix mbc{2,   2,  1, 3};
    matrix mcd{5,  10,  7, 8};
    matrix mce{4,   0,  1, 3};
    matrix mde{1, -10,  9, 2};

    matrix_wf[a][b] = mab; a.add_neighbor(b);
    matrix_wf[a][c] = mac; a.add_neighbor(c);
    matrix_wf[b][c] = mbc; b.add_neighbor(c);
    matrix_wf[c][d] = mcd; c.add_neighbor(d);
    matrix_wf[c][e] = mce; c.add_neighbor(e);
    matrix_wf[d][e] = mde; d.add_neighbor(e);

    try {
        weighted_path<matrix_node, matrix> path
        = find_shortest_path<matrix_node, matrix>()
            .from(a)
            .to(e)
            .with_weights(&matrix_wf)
            .without_heuristic_function();

        std::cout << path << "n";
        std::cout << "Final matrix length: " << path.total_weight() << "n";
    } catch (path_not_found_exception<matrix_node>& ex) {
        std::cerr << ex.what() << "n";
    }
}


Get this bounty!!!

#StackBounty: #c# #entity-framework #entity-framework-6 Why is Entity Framework so slow to add multiple items in one SaveChanges()?

Bounty: 200

This is a follow-up from a previous question, in which I was trying to figure out the main cause for my code running slowly. I think I’ve narrowed it down to a minimal example below. I have a basic database structure as follows:

public class Foo
{
    public int Id { get; set; }
    public string Bar { get; set; }
}

public class FooContext : DbContext
{
    public DbSet<Foo> Foos { get; set; }
}

Now, if I had a list of Foo objects, and wanted to add them to the database, the suggested way would be to use AddRange(). But I noticed it was taking a long time, and is affected poorly by the number of items in the collection, even with a small amount like 200. So I wrote it out manually, and viola, it runs faster!

class Program
{
    static void Main(string[] args)
    {
        var foos = Enumerable.Range(0, 200).Select(index => new Foo { Bar = index.ToString() });

        // Make sure the timing doesn't include the first connection
        using (var context = new FooContext())
        {
            context.Database.Connection.Open();
        }

        var s1 = Stopwatch.StartNew();
        using (var context = new FooContext())
        {
            context.Foos.AddRange(foos);
            context.SaveChanges();
        }
        s1.Stop();

        var s2 = Stopwatch.StartNew();
        using (var context = new FooContext())
        {
            // Ignore the lack of sanitization, this is for demonstration purposes
            var query = string.Join(";n", foos.Select(f => "INSERT INTO Foos ([Bar]) VALUES (" + f.Bar + ")"));
            context.Database.ExecuteSqlCommand(query);
        }
        s2.Stop();

        Console.WriteLine("Normal way: {0}", s1.Elapsed);
        Console.WriteLine("Hard way  : {0}", s2.Elapsed);
        Console.ReadKey();
    }
}

My initial thought was that Entity Framework might be using a separate transaction for each entry, but logging the SQL shows that’s not the case. So why is there such a difference in execution time?


Get this bounty!!!

#StackBounty: #c# #.net #watson #watson-conversation Recording WAV to IBM Watson Speech-To-Text

Bounty: 50

I’m trying to record audio and immediately send it to IBM Watson Speech-To-Text for transcription. I’ve tested Watson with a WAV file loaded from disk, and that worked. On the other end, I’ve also tested with recording from microphone and storing it to disk, works good too.

But when I try to record the audio with NAudio WaveIn, the result from Watson is empty, as if there’s no audio.

Anyone who can shine a light on this, or someone has some ideas?

private async void StartHere()
{
    var ws = new ClientWebSocket();
    ws.Options.Credentials = new NetworkCredential("*****", "*****");

    await ws.ConnectAsync(new Uri("wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize?model=en-US_NarrowbandModel"), CancellationToken.None);

    Task.WaitAll(ws.SendAsync(openingMessage, WebSocketMessageType.Text, true, CancellationToken.None), HandleResults(ws));

    Record();
}

public void Record()
{
    var waveIn = new WaveInEvent
    {
        BufferMilliseconds = 50,
        DeviceNumber       = 0,
        WaveFormat         = format
    };

    waveIn.DataAvailable    += new EventHandler(WaveIn_DataAvailable);
    waveIn.RecordingStopped += new EventHandler(WaveIn_RecordingStopped);
    waveIn.StartRecording();
}

public void Stop() 
{
    await ws.SendAsync(closingMessage, WebSocketMessageType.Text, true, CancellationToken.None);
}

public void Close()
{
    ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close", CancellationToken.None).Wait();
}

private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
{
    await ws.SendAsync(new ArraySegment(e.Buffer), WebSocketMessageType.Binary, true, CancellationToken.None);
}

private async Task HandleResults(ClientWebSocket ws)
{
    var buffer = new byte[1024];

    while (true)
    {
        var segment = new ArraySegment(buffer);
        var result = await ws.ReceiveAsync(segment, CancellationToken.None);

        if (result.MessageType == WebSocketMessageType.Close)
        {
            return;
        }

        int count = result.Count;
        while (!result.EndOfMessage)
        {
            if (count >= buffer.Length)
            {
                await ws.CloseAsync(WebSocketCloseStatus.InvalidPayloadData, "That's too long", CancellationToken.None);
                return;
            }

            segment = new ArraySegment(buffer, count, buffer.Length - count);
            result = await ws.ReceiveAsync(segment, CancellationToken.None);
            count += result.Count;
        }

        var message = Encoding.UTF8.GetString(buffer, 0, count);

        // you'll probably want to parse the JSON into a useful object here,
        // see ServiceState and IsDelimeter for a light-weight example of that.
        Console.WriteLine(message);

        if (IsDelimeter(message))
        {
            return;
        }
    }
}

private bool IsDelimeter(String json)
{
    MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ServiceState));
    ServiceState obj = (ServiceState) ser.ReadObject(stream);

    return obj.state == "listening";
}

[DataContract]
internal class ServiceState
{
    [DataMember]
    public string state = "";
}


Edit: I’ve also tried to send the WAV “header” prior to StartRecording, like this

    waveIn.DataAvailable    += new EventHandler(WaveIn_DataAvailable);
    waveIn.RecordingStopped += new EventHandler(WaveIn_RecordingStopped);

    /* Send WAV "header" first */
    using (var stream = new MemoryStream())
    {
        using (var writer = new BinaryWriter(stream, Encoding.UTF8))
        {
            writer.Write(Encoding.UTF8.GetBytes("RIFF"));
            writer.Write(0); // placeholder
            writer.Write(Encoding.UTF8.GetBytes("WAVE"));
            writer.Write(Encoding.UTF8.GetBytes("fmt "));

            format.Serialize(writer);

            if (format.Encoding != WaveFormatEncoding.Pcm && format.BitsPerSample != 0)
            {
                writer.Write(Encoding.UTF8.GetBytes("fact"));
                writer.Write(4);
                writer.Write(0);
            }

            writer.Write(Encoding.UTF8.GetBytes("data"));
            writer.Write(0);
            writer.Flush();
        }

        byte[] header = stream.ToArray();

        await ws.SendAsync(new ArraySegment(header), WebSocketMessageType.Binary, true, CancellationToken.None);
    }
    /* End WAV header */

    waveIn.StartRecording();


Get this bounty!!!

#StackBounty: #c# #.net #client Handling Server Responses

Bounty: 100

I’m not 100% sure this is the right place to post this. It is not about the specific code being written, but more about the design of the code. (Of course any constructive criticism is appreciated)

I have the following interfaces for dealing with talking to a server:

public interface IAction
{
    GatewayResponseHandlerResult Run();
}

public abstract class GatewayResponseHandler
{
    protected GatewayResponseHandlerResult Result = new GatewayResponseHandlerResult();

    private GatewayResponseHandlerResult Handle(GatewayResponse Response)
    {
        //specific handling code omitted
    }
}

The idea is each type of action (ex. Login, Logout) is its own class that implements the IAction interface. The action performs the call to the servers and passes the response to the GatewayResponseHandler.Handle() function which then passes back a GatewayResponseHandlerResult object. The specific IAction object then passes the GatewayResponseHandleResult object back to the caller.

This is the GatewayResponseHandlerResult class:

public class GatewayResponseHandlerResult
{
    public bool Succeeded;
    public bool Failed;
    public bool Errored;
    public object Result { get; set; }

    public void SetAsSuccess()
    {
        Succeeded = true;
        Failed = false;
        Errored = false;
    }

    public void SetAsFailure()
    {
        Succeeded = false;
        Failed = true;
        Errored = false;
    }

    public void SetAsError()
    {
        Succeeded = false;
        Failed = false;
        Errored = true;
    }
}

This is what an Action would look like:

public sealed class LoginAction : IAction
{
    private string Username;
    private string Password;

    public LoginAction(string Username, string Password)
    {
        this.Username = Username;
        this.Password = Password;
    }

    public GatewayResponseHandlerResult Run()
    {
        try
        {
            GatewayResponse LoginResponse = GatewayRequest.Login(Username, Password);
            return GatewayResponseHandler.Handle(LoginResponse);
        }
        catch (Exception ex)
        {
            throw ex.Log();
        }
    }
}

And the corresponding derived response handler:

sealed class LoginHandler : GatewayResponseHandler
{
    protected override bool CanHandle()
    {
        return Response.action == GatewayAction.LOGIN;
    }

    protected override GatewayResponseHandlerResult ProcessError(Exception ex = null)
    {
        Result.SetAsError();
        return Result;
    }

    protected override GatewayResponseHandlerResult ProcessFailure()
    {
        Result.SetAsFailure();
        return Result;
    }

    protected override GatewayResponseHandlerResult ProcessSuccess()
    {
        try
        {
            if (Response.result_code == (int)ResponseCodes.SuccessCode.MFA_REQUIRED)
            {
                //specific MFA handling omitted
            }
            else if (Response.result_code == (int)ResponseCodes.SuccessCode.PW_RESET_REQUIRED)
            {
                //specific password reset code omitted
            }

            MessageBox.Show("Login successful");
            Result.SetAsSuccess();
        }
        catch (Exception Ex)
        {
            ProcessError(Ex);
            Result.SetAsError();
        }
        return Result;
    }
}

As you can see the LoginResponseHandler can need to deal with several possible responses from a successful login since it can require an MFA code to be passed back to complete the login or a password reset might be required on login. This can mean running new Actions. Should the LoginResponseHandler be executing those directly or passing back something to let the caller of the action know they need to perform further Actions?

I’m also not sure if I should have the Actions be instantiated, or perhaps make the Run() method static and have some sort of abstract argument object with specific implementation for each action that actually need it.

For example:

public interface IActionArgs{}

public class LoginActionArgs : IActionArgs 
{
    public string Username;
    public string Password;
}

public abstract class Action
{
    public static GatewayResponseHandlerResult Run(IActionArgs ActionArgs)
    {
        throw new NotImplementedException();
    }
}

public sealed class LoginAction : IAction 
{
    public static new GatewayResponseHandlerResult Run(IActionArgs ActionArgs)
    {
        //code omitted
    }
}

While I like the idea of the methods being static, I don’t like the way the code looks, and the fact that you could call Run on the abstract class since interface can’t have static methods.

Any general advice on how to improve the architecture of the code is very much appreciated.


Get this bounty!!!

#StackBounty: #c# #asp.net coded ui test project, obtain value of asp label

Bounty: 250

Created a simple calculator app in webforms.
User enters a number in a text field MainContent_numberTb and clicks on results button.

Added a new ‘coded UI Test Project’ to my solution. Have tested the UI by adding ‘5’, This all works fine. Would now like to compare the actual result against the expected result.

BrowserWindow Browser = BrowserWindow.Launch("http://localhost:37426/Calculator");

UITestControl UiInputField = new UITestControl(Browser);
UiInputField.TechnologyName = "Web";
UiInputField.SearchProperties.Add("ControlType", "Edit");
UiInputField.SearchProperties.Add("Id", "MainContent_numberTb");

//Populate input field
Keyboard.SendKeys(UiInputField, "5");

//Results Button
UITestControl ResultsBtn = new UITestControl(Browser);
ResultsBtn.TechnologyName = "Web";
ResultsBtn.SearchProperties.Add("ControlType", "Button");
ResultsBtn.SearchProperties.Add("Id", "MainContent_calBtn");

Mouse.Click(ResultsBtn);

All above code works fine, problem occurs when trying to access the label

<asp:Label ID="AllNumLbl_Res" runat="server"></asp:Label>

What do I insert beside control type? It’s not edit as edit is the text field. Then also, what stores the actual result so I can compare AllNumsTB?

string expectedAllNums = "1, 2, 3, 4, 5";
UITestControl AllNumsTB = new UITestControl(Browser);
AllNumsTB.TechnologyName = "Web";
AllNumsTB.SearchProperties.Add("ControlType", "?????");
AllNumsTB.SearchProperties.Add("Id", "MainContent_AllNumLbl_Res");

if(expectedAllNums != AllNumsTB.??????)
{
    Assert.Fail("Wrong Answer");
}

UPDATE
OK so using the debugger console I was able to get the value of the label using ((Microsoft.VisualStudio.TestTools.UITesting.HtmlControls.HtmlSpan)new System.Collections.ArrayList.ArrayListDebugView(((System.Collections.CollectionBase)(AllNumsTB.FindMatchingControls()).List).InnerList).Items[0]).DisplayText

but when I use this in the code & ArrayListDebugView are inaccessible due to protection??


Get this bounty!!!