I have the following script transformation component.
public class ScriptMain : UserComponent
{
Regex findCOMMAexp, findAmpersandExp, findANDExp;
public override void PreExecute()
{
base.PreExecute();
//extract and compress publishers.
findANDExp = new Regex(#"(\w+\s*)+(?=\band\b)",RegexOptions.Compiled);
findCOMMAexp = new Regex(#"(\w+\s*)+[,]\s*(\w+\s*)",RegexOptions.Compiled);
findAmpersandExp = new Regex(#"(\w+\s*)+[&]\s*(\w+\s*)",RegexOptions.Compiled);
}
public override void PostExecute()
{
base.PostExecute();
}
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
Row.CompressedPublisher = compressPublisher(Row.F018Publisher);
}
public String compressPublisher(String str)
{
Match match;
if (str.Contains("/"))
{
return str.Substring(0, str.IndexOf(('/')));
}
else if ((match = findANDExp.Match(str)).Success)
{
return match.ToString();
}
else if ((match = findCOMMAexp.Match(str)).Success)
{
return Regex.Replace(str, ",", "");
}
else
{
return str;
}
}
}
The 3 Regex objects are defined in the main class, initialized in the PreExecute(), and used in a method called by the ProcessInputRow. I have a database source that pulls in a single varchar(45) string, defined as F018Publisher. I stopped this task after 10 mins, while trying to parse 9k entries. What is going wrong?
Thanks.
I wrapped this into a C# commandline app and passed ABCDEFGHIJKLMOPQRSTUVWXYZ01234567890123456789 as a parameter to compressPublisher and it never returned from this check else if ((match = findANDExp.Match(str)).Success)
Same comment posted to twitter as well
Related
I'm trying to customize some of nUnits behaviour, however I'm constantly hitting a brick wall
because of nUnits heavy use of code reflection. Test methods (and also setup methods etc) are passed all the way down, deep into the framework, and are converted into a delegate at the latest step possible.
The classes I'm interested in are called TestCommands and only there the framework becomes functional.
For reference here is a snippet I found in nUnits source of the TestMethodCommand class which propably is the bread and butter test execution delegate.
public class TestMethodCommand : TestCommand
{
private readonly TestMethod testMethod;
private readonly object[] arguments;
public TestMethodCommand(TestMethod testMethod) : base(testMethod)
{
this.testMethod = testMethod;
this.arguments = testMethod.Arguments;
}
public override TestResult Execute(TestExecutionContext context)
{
object result = InvokeTestMethod(context); // missing a branch deciding about sync vs. async
// missing some code that checks object against "expected result"
return context.CurrentResult;
}
private object InvokeTestMethod(TestExecutionContext context)
{
return testMethod.Method.Invoke(context.TestObject, arguments);
}
}
I'm puzzled why nUnit couldn't wrap the test method into an Func<object> way way sooner and just pass the context along. As it stands for now if I don't have a MethodInfo nUnit can't run it.
In case you wonder, here is an example of a thing I want to do but I ran into the same problem in other instances as well.
[Scenario(When: "Device Registration reads out PCB Type",
Then: "Device Type might change")]
public void Identifier_Changes_Are_Recognized()
{
var changedType = reference.ChangeType(DeviceType.Terminal);
var changedID = reference.ChangeID(123456);
Assert.Multiple(() =>
{
AssertIsSameDevice(reference, changedType);
AssertIsDifferentDevice(reference, changedID);
});
}
This scenario attribute is supposed to print a small description like so.
public void RunBeforeTest()
{
var text = new MultiLineText
("Scenario:",
"\tGiven:\t" + When,
"\tThen:\t" + Then,
"-------------\n"
);
Console.WriteLine(text);
}
I reaaallly want to tell nUnit "Look, here is an action, please run it" but for the time beeing this seems very hard to achieve. Did anyone else here run in these kinds of problems?
Are there possibly ways to achieve what I'm trying to do? Maybe create my own TestCommand, but as I mentioned, these objects only get created very deep into the framework.
OP here (Writing from my home account)
I looked more into this and actually found a working solution:
public class ArbitraryCodeExecutionWrapper : DelegatingTestCommand
{
public ArbitraryCodeExecutionWrapper(TestCommand innerCommand) : base(innerCommand)
{
}
public Action<TestExecutionContext> BeforeTest { get; init; } = _ => { };
public Action<Test, TestResult> AfterTest { get; init; } = (_,_) => { };
public override TestResult Execute(TestExecutionContext context)
{
BeforeTest(context);
var result = innerCommand.Execute(context);
AfterTest(context.CurrentTest, result);
return result;
}
}
public class NUnitTestCommandWrapperAttribute : Attribute, IWrapTestMethod
{
protected virtual void BeforeTest(TestExecutionContext context)
{
}
protected virtual void AfterTest(Test test, TestResult result)
{
}
public TestCommand Wrap(TestCommand command)
=> new ArbitraryCodeExecutionWrapper(command)
{
BeforeTest = BeforeTest,
AfterTest = AfterTest
};
}
public class ScenarioAttribute : NUnitTestCommandWrapperAttribute
{
public string When { get; init; } = "";
public string Then { get; init; } = "";
protected override void BeforeTest(TestExecutionContext context)
{
var text = new MultiLineText
("Scenario:",
"\tGiven:\t" + When,
"\tThen:\t" + Then
);
Console.WriteLine(text);
}
protected override void AfterTest(Test test, TestResult result)
{
Console.WriteLine("After Test");
}
}
[TestFixture]
public class TestCodeExecution
{
[Test]
[Scenario(When = "nUnit Comes here",
Then = "Print Hello World")]
public void Try_Out_Code_Execution()
{
Console.WriteLine("Hello World");
}
}
public class MultiLineText
{
private List<string> items = new();
public static implicit operator string(MultiLineText text) => text.ToString();
public MultiLineText(params string[] lines)
{
items = lines.ToList();
}
public override string ToString() => string.Join("\n", items);
}
I'm creating a program which will execute a command after user input.
Some commands I want to implement are: creating, reading a file, getting current working directory etc.
I created a dictionary which will store user input and corresponding command:
public static Dictionary<string, Action<string[]>> Commands { get; set; } = new Dictionary<string, Action<string[]>>()
{
{"pwd", PrintWorkingDirectory },
{"create", CreateFile },
{"print", ReadFile },
};
Unfortunately I have issues with triggering the method:
public void Run()
{
Console.WriteLine("Welcome, type in command.");
string input = null;
do
{
Console.Write("> ");
input = Console.ReadLine();
Execute(input);
} while (input != "exit");
}
public int Execute(string input)
{
if(Commands.Keys.Contains(input))
{
var action = Commands.Values.FirstOrDefault(); //doesn't work, gives '{command} not found'
}
Console.WriteLine($"{input} not found");
return 1;
}
Also I noticed that this solution would not work with method which is not void, but returns something, as for example CreateFile.
public static string CreateFile(string path)
{
Console.WriteLine("Create a file");
string userInput = Console.ReadLine();
try
{
string[] file = userInput.Split(new char[] { ' ' }).Skip(1).ToArray();
string newPath = Path.GetFullPath(Path.Combine(file));
using (FileStream stream = new FileStream(newPath, FileMode.Create, FileAccess.ReadWrite))
{
stream.Close();
}
using (StreamWriter sw = new StreamWriter(newPath))
{
Console.WriteLine("Please type the content.Press Enter to save.");
sw.WriteLine(Console.ReadLine());
sw.Close();
Console.WriteLine("File {0} has been created", newPath);
}
}
catch (Exception)
{
throw;
}
return path;
}
public static void ReadFile(string[] args)
{
Console.WriteLine("Reading file");
string userInput = Console.ReadLine();
string[] file = userInput.Split(new char[] { ' ' }).Skip(1).ToArray();
string newPath = Path.GetFullPath(Path.Combine(file));
string[] lines = File.ReadAllLines(newPath);
foreach (string line in lines)
Console.WriteLine(line);
}
public static void PrintWorkingDirectory(string[] args)
{
var currentDirectory = Directory.GetCurrentDirectory();
Console.WriteLine(currentDirectory);
}
Could somebody advise me how to deal with these issues?
Is it that this dictionary I created does not make much sense at all?
First problem: You're always fetching the first element of the dictionary and are not using the index operator to retrieve the correct value. Therefore change:
if(Commands.Keys.Contains(input))
{
var action = Commands.Values.FirstOrDefault(); //doesn't work, gives '{command} not found'
}
to:
public int Execute(string input)
{
if (Commands.Keys.Contains(input))
{
var action = Commands[input]; //doesn't work, gives '{command} not found'
action?.Invoke(new string[] { });
}
else
{
Console.WriteLine($"{input} not found");
}
return 1;
}
Regarding to your second question about dictionary usage. I think it is ok to use a dictionary to map different commands based on a given key. The alternative would be switch or if constructs, which can be prevented in Object Oriented Programming.
Regarding to your question about string CreateFile(string path). Since C# is strongly typed language your dictionary can only contain objects of type Action<string[]>, so you can't use methods with another signature than that. One solution is to add another dictionary in the form of Dictionary<string,Func<string[], string>. As a result you'll get more and more dictionaries depending on your method signatures. From here on you should think to build to encapsulate your commands in an e.g. CommandInterpreter class, that could offer an API like that:
void Request(string cmdName, string[] cmdParameters);
string GetLastResult();
int GetLastCode();
Update:
Below code shows a possible object oriented solution (I've left out interfaces to make the code more compact):
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
public class Command<T>
{
public string Name { get; }
public T TheCommand { get; }
public Command(string name, T theCommand)
{
Name = name;
TheCommand = theCommand;
}
}
public interface ICommandResult
{
void Ok(Action<ICommandResult> yes, Action<ICommandResult> no);
int Code { get; }
string Description { get; }
}
public abstract class CommandResult : ICommandResult
{
public int Code { get; }
public string Description { get; }
protected CommandResult(int code, string description)
{
Code = code;
Description = description;
}
public abstract void Ok(Action<ICommandResult> yes, Action<ICommandResult> no);
}
public class NullCommandResult : CommandResult
{
public NullCommandResult() : base(-1, "null")
{
}
public override void Ok(Action<ICommandResult> yes, Action<ICommandResult> no) => no?.Invoke(this);
}
public class SuccessCommandResult : CommandResult
{
public SuccessCommandResult(string description) : base(0, description)
{
}
public override void Ok(Action<ICommandResult> yes, Action<ICommandResult> no) => yes?.Invoke(this);
}
public class CommandInterpreter
{
private Dictionary<string, Func<IEnumerable<string>, ICommandResult>> Commands = new Dictionary<string, Func<IEnumerable<string>, ICommandResult>>();
public void RegisterCommand(Command<Func<IEnumerable<string>, ICommandResult>> cmd)
=> Commands.Add(cmd.Name, cmd.TheCommand);
public ICommandResult RunCommand(string name, IEnumerable<string> parameters)
=> Commands.Where(kvp => kvp.Key.Equals(name))
.Select(kvp => kvp.Value)
.DefaultIfEmpty(strArr => new NullCommandResult())
.Single()
.Invoke(parameters);
}
class Program
{
private CommandInterpreter _cmdInterpreter;
private Program()
{
_cmdInterpreter = new CommandInterpreter();
_cmdInterpreter.RegisterCommand(new Command<Func<IEnumerable<string>, ICommandResult>>("pwd", PrintWorkingDirectory));
_cmdInterpreter.RegisterCommand(new Command<Func<IEnumerable<string>, ICommandResult>>("create", CreateFile));
_cmdInterpreter.RegisterCommand(new Command<Func<IEnumerable<string>, ICommandResult>>("print", ReadFile));
}
private static CommandResult ReadFile(IEnumerable<string> arg) => new SuccessCommandResult("File read");
private static CommandResult CreateFile(IEnumerable<string> arg) => new SuccessCommandResult("File xyz created");
private static CommandResult PrintWorkingDirectory(IEnumerable<string> arg) => new SuccessCommandResult("Printed something");
static void Main() => new Program().Run();
private void Run()
{
Console.WriteLine("Welcome, type in command.");
string input;
do
{
Console.Write("> ");
input = Console.ReadLine();
var cmdResult = _cmdInterpreter.RunCommand(input, Enumerable.Empty<string>());
cmdResult.Ok(
r => Console.WriteLine($"Success: {cmdResult.Code}, {cmdResult.Description}"),
r => Console.WriteLine($"FAILED: {cmdResult.Code}, {cmdResult.Description}"));
} while (input != "exit");
}
}
}
Output:
Welcome, type in command.
> pwd
Success: 0, Printed something
> create
Success: 0, File xyz created
> abc
FAILED: -1, null
>
You can just copy the code and play around with it.
This question is messed up
See bottom
In ResultsB how do I access List?
public class ResultsB : List<ResultB>
{
public string Methods
{
get
{
// what I want is
return string.Join(", ", this);
// and have this be List<ResultB>
// this fails
// it returns "PuzzleBinarySearchWeighted.Program+ResultB, PuzzleBinarySearchWeighted.Program+ResultB"
// I just get information about the object
// this fails also - same thing information about the object
//return string.Join(", ", this.GetEnumerator());
}
}
public void testEnum()
{
// this works
foreach (ResultB resultB in this)
{
Debug.WriteLine(resultB.MethodsString);
}
}
}
Externally I can do this -
ResultsB resultsB = new ResultsB();
resultsB.Add(new ResultB(1, "a:b"));
resultsB.Add(new ResultB(2, "c:b"));
I was just looking at this wrong
I needed an iEnumerable the from all List
I cannot delete as an answer has up votes
Sorry - I VTC and request you do the same
public string Methods
{
get
{
return string.Join(", ", this.MethodsAll);
}
}
public HashSet<string> MethodsAll
{
get
{
HashSet<string> hs = new HashSet<string>();
foreach (ResultB resultB in this)
{
foreach (string s in resultB.Methods)
{
hs.Add(s);
}
}
return hs;
}
}
Implicitly with this.
For example, calling Add as follows Add("hello world") which implicitly is this.Add("hello world"):
public class CustomListOfStrings : List<string>
{
// ...
private void DoStuff()
{
Add("Whatever");
}
}
#Paparazzi commented out:
I should have been more clear I need a foreach
this keyword to the rescue!
foreach(ResultB result in this)
{
}
OP wants to use string.Join directly
OP has edited the question and says that wants to use string.Join as follows:
string.Join(", ", this).
The string.Join overload that you can use is string.Join(string, IEnumerable<T>), and it'll call Object.ToString on each object found in the given sequence (i.e. IEnumerable<T>). So you need to provide an overridden Object.ToString method in your result class (you can check that on Reference Source for string.Join):
public class ResultB
{
public override string ToString()
{
// You need to provide what would be a string representation
// of ResultB
return "Who knows what you want to return here";
}
}
...and your code will work as you expect!
I was making a test case for some code on binary search tree my professor gave
public static void Main(string [] args)
{
//on my prof's code, public class BinSearchTree<T>
BinSearchTree<int> myTree = new BinSearchTree<int>();
myTree.Insert(10);
myTree.Insert(15);
myTree.Insert(5);
myTree.Insert(2);
myTree.Insert(1);
Console.WriteLine(myTree.ToString());
Console.ReadKey();
}
It compiles, but it displays
BinSearchTree`1[System.Int32]
Can somebody tell me why it displays that?
my prof's code:
public class BinSearchTree<T> where T : IComparable<T>
{
private class OurTreeNode<T>
{
public T Data { get; set; }
public OurTreeNode<T> Left;
public OurTreeNode<T> Right;
public OurTreeNode(T d = default(T), OurTreeNode<T> leftnode = null, OurTreeNode<T> rightnode = null)
{
Data = d;
Left = leftnode;
Right = rightnode;
}
public override string ToString()
{
return Data.ToString();
}
}
//...other methods
//prof's Insert method
public void Insert(T newItem)
{
mRoot = Insert(newItem, mRoot);
}
private OurTreeNode<T> Insert(T newItem, OurTreeNode<T> pTmp)
{
if (pTmp == null)
return new OurTreeNode<T>(newItem, null, null);
else if (newItem.CompareTo(pTmp.Data) < 0)
pTmp.Left = Insert(newItem, pTmp.Left);
else if (newItem.CompareTo(pTmp.Data) > 0)
pTmp.Right = Insert(newItem, pTmp.Right);
else
throw new ApplicationException("...");
return pTmp;
}
}
I tried adding a ToString() method after the Insert method but it gives me an error when I used foreach. Is there a way of displaying it without making too much extra methods?
The class is using the default (Object's) ToString() implementation. You have 2 options:
walk though the elements of the tree and print it yourself
ask the author to implement/override the ToString() method
Can somebody tell me why it displays that?
It displays that because ToString() prints the type definition.
Default implementations of the Object.ToString method return the fully qualified name of the object's type. (from the docs)
For instance, the following short program prints System.Collections.Generic.List`1[System.Int32], which is the type of List<int>.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main(string[] args)
{
List<int> myTree = new List<int>();
myTree.Add(10);
Console.WriteLine(myTree.ToString());
}
}
Here are the rudiments of how to override the ToString() method to produce some meaningful output.
using System;
using System.Collections.Generic;
public class Program
{
public static void Main(string[] args)
{
BinSearchTree<int> myTree = new BinSearchTree<int>();
myTree.Insert(10);
myTree.Insert(15);
Console.WriteLine(myTree.ToString());
}
}
public class BinSearchTree<T> where T : IComparable<T>
{
private List<T> values = new List<T>();
// rest of class omitted for clarity
public void Insert(T val) {
values.Add(val);
}
public override string ToString() {
var result = string.Empty;
foreach(var v in values)
{
result += v + ", ";
}
return result;
}
}
Output
10, 15,
As you have created the object of BinaryTree Class and have not overridden the ToString() method inside BinaryTree Class. You have not created object of OurTreeNode class and not calling ToString() method overriden inside it. Hence it is giving you the default ToString() method output of BinaryTree Class.
BinSearchTree<int> myTree = new BinSearchTree<int>();
You are calling
Console.WriteLine(myTree.ToString());
have a php code like this,going to convert it in to C#.
function isValid($n){
if (preg_match("/\d+/",$n) > 0 && $n<1000) {
return true;
}
return false;
}
Here is my try,BUT error shown Error is "expected class, delegate, enum, interface or struct error C#"
public string IsValidate(string Item)
{
string Result = Item;
try
{
Result = System.Text.RegularExpressions.Regex.Replace(InputTxt, #"(\\)([\000\010\011\012\015\032\042\047\134\140])", "$2");
}
catch(Exception ex)
{
console.WriteLine(ex.Message)
}
return Result;
}
What is the error,Is there any other way to implement this better than my try ?
i got this snippet from here code
You haven't define this method inside a class/struct that is why you are getting this error. You may define this method inside a class.
public class MyValidator
{
public string IsValidate(string Item)
{
//Your code here
}
}
Later you can use it like:
MyValidator validator = new MyValidator();
validator.IsValid("Your string");
Also you are missing semicolon at the end of the Console.Write statement, plus 'c' for Console should be in uppercase
Edit:
Since in your php code, it looks like you are trying to see if the string passed is an integer and it is less than 1000, you may use the int.TryParse like the following:
public class MyValidator
{
public bool IsValidate(string Item)
{
string Result = Item;
int val;
if (int.TryParse(Item, out val) && val > 0 && val < 1000)
{
return true;
}
else
{
return false;
}
}
}
In you main method you can do:
static void Main()
{
MyValidator validator = new MyValidator();
Console.WriteLine(validator.IsValidate("asdf123")); // This will print false
Console.WriteLine(validator.IsValidate("999")); //This will print true
Console.WriteLine(validator.IsValidate("1001")); //This will print false
}
In C# a method must be placed inside a class or struct:
public class Validator {
public string IsValidate(string item) {
...
}
}
In this case I would probably translate it like this:
public static class Validator {
public static bool IsValid(string item) {
int value;
return int.TryParse(item, out value)
&& value > 0 && value < 1000;
}
}
You could define your function inside a static class such that you dont have to create an instance of it before invoking the function. Like,
public static class Validator
{
public static string IsValidate(string item)
{
// ...
}
}
Then, you can call it using:
Validator.IsValidate("String to validate")
EDIT: You could then check that your function is returning what you expect by doing:
if(Validator.IsValidate("String to validate") == "Expected result")
{
/* Logic to be executed here */
}