I am trying to replicate the C# method to python, I got stuck near the query
var handler = from handler in _message
private JObject ProcessMessage(JObject json)
{
var type = GetProperty(json, TypeField).ToString();
message = GetProperty(json, MsgField).ToString();
var handlers = from handler in _message
where handler.Type == type && handler.Name == msg
select handler;
var selected = handlers.FirstOrDefault();
return selected.Process(json);
}
here is python code I have tried,
def process_message(self):
type=get_property(self,translator.TypeField)
message=get_property(self,translator.MsgField)
def get_property(self, TypeField):
type_token = self.get(TypeField)
return type_token
There are a few things wrong with your python code.
First of all, I'm assuming you want to pass a JSON object as a parameter to process_message. I'm also assuming your code is inside a class. In that case, you want to write process_message(self, json), not just process_message(self).
Secondly, get_property is redundant. You can replace it with just type = json.get(translator.TypeField) for example.
As for the query, you can use list comprehension:
handlers = [h for h in _message if h.type == type and h.name == message]
In the end, we get something like this:
def process_message(self, json):
type = json.get(translator.type_field)
message = json.get(translator.msg_field)
selected = [h for h in _message if h.type == type and h.name == message]
if len(selected) > 0:
return selected[0].process(json)
I replaced your naming with lowercase, since in python, it's convention to mark field names as such.
Related
I have been trying to write C# code to output the network tab contents of Developer tools as JSONArray, this is what I have so far:
*IWebDriver driver = new ChromeDriver(#"C:\Users\xxx\Downloads\chromedriver_win32");
driver.Navigate().GoToUrl("https://google.com");
String scriptToExecute = "var performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {}; var network = performance.getEntries() || {}; return network;";
String netData = ((IJavaScriptExecutor)driver).ExecuteScript(scriptToExecute).ToString();
Console.WriteLine(netData);*
And the other:
*IWebDriver driver = new ChromeDriver(#"C:\Users\xxx\Downloads\chromedriver_win32");
driver.Navigate().GoToUrl("https://google.com");
String ste = "Return window.performance.getEntries();";
String Timings = ((IJavaScriptExecutor)driver).ExecuteScript(ste).ToString();
Console.WriteLine(Timings);*
But my output is not giving the expected result. It looks like the String netData variable is returning as empty, thinking it is an issue with the Script.
Any suggestions on a workaround for this?
You have to be aware of the return type of ExecuteScript method. If case of JS script
return window.performance.getEntries()
it will be
IReadOnlyCollection<object>
getEntries() returns an array of objects - in case of c# code it will be IDictionary<string, object> - key is a JS object property name, value is its value (:))
You have to do something like that:
var ste = "return window.performance.getEntries();";
var scriptResult = (IReadOnlyCollection<object>)(IJavaScriptExecutor)driver).ExecuteScript(ste);
var perfEntries = scriptResult.Select(e => ((IDictionary<string, object>)e);
//(result will be an IEnumerable of IDictionary<string,object>), you can create a new, custom class to convert dictionaries to more verbose objects)
PS
Please, try to stick to c# convention -> e.g. use string instead of String; name variable using lower case etc.
I'm currently trying to find invocations of .ExecuteSqlCommand and examine the first value being passed to the sql param.
Here is an example of the differences I've found in our code base.
ExecuteSqlCommand("[sql statement here]");
vs.
var sql = "sql statement";
ExecuteSqlCommand(sql);
So far, I have this:
var invocations = root.DescendantNodes()
.OfType<InvocationExpressionSyntax>()
.Select(ie => ModelExtensions.GetSymbolInfo(model, ie).Symbol)
.Where(symbol => symbol != null && symbol.Name == "ExecuteSqlCommand");
foreach (var invocation in invocations)
{
var method = (IMethodSymbol)invocation;
foreach (var param in method.Parameters)
{
//I can't quite seem to get information from IParameterSymbol about whether the param is a string literal, or a reference to a string via a variable.
}
}
If the param is not a string, and instead, a var, then I'll need to get the value of the var (as much as it's defined at runtime).
I'm not too sure if this is a job for the SemanticModel or the SyntaxTree, but my GUESS is that the SemanticModel should have the richer information I need to let me discover what I'm looking for.
My overall goal is to interrogate the sql being passed to the ExecuteSqlCommand method.
Thanks!
SemanticModel.GetConstantValue is the API we have for handling this situation.
It can accept both a syntax node and an expression. You will still need to track the state of variables back to their declaration sites and determine if they were given a constant expression.
I would use SemanticModel.GetSymbolInfo.Symbol?.DeclaringSyntaxReferences.First() to find the declaration site of a variable and then check to see if its a constant expression.
The Syntax API could be used to extract the sql statement value but depends on whether the variable declaration (i.e. var sql = "sql statement";) is included as part of code submitted to the syntax tree.
For example, if it's part of the same method implementation as where ExcuteSqlCommand() is called then you can first get the name of variable (i.e. sql) passed to it and use that to find the matching variable declaration statement within that same method. Finally, the sql statement value (i.e. "sql statement") can be extracted from that.
The following code first checks if the sql value is passed as a string literal otherwise looks for the variable declaration. The assumption it's all within the same method:
// whatever c# *method* code contains the sql.
// otherwise the root of the tree would need to be changed to filter to a specific single `MethodDeclarationSyntax`.
string submittedCode = "public void SomeMethodContainingSql(){ ...//rest of code...";
var tree = CSharpSyntaxTree.ParseText(submittedCode);
var root = (CompilationUnitSyntax) tree.GetRoot();
var arguments = root
.DescendantNodes()
.OfType<InvocationExpressionSyntax>()
.First(node => node.DescendantNodes().OfType<IdentifierNameSyntax>()
.First()
.Identifier.Text == "ExecuteSqlCommand")
.ArgumentList.DescendantNodes().ToList();
string sqlStatementValue = "";
var literalExpression = arguments.OfType<LiteralExpressionSyntax>().FirstOrDefault();
if (literalExpression != null)
{
sqlStatementValue = literalExpression.GetText().ToString();
}
else
{
var variableName = arguments
.First()
.ToFullString();
var variableDeclaration = root
.DescendantNodes()
.OfType<VariableDeclarationSyntax>()
.Single(node => node.DescendantNodes().OfType<VariableDeclaratorSyntax>()
.First()
.Identifier.Text == variableName);
sqlStatementValue = variableDeclaration.DescendantNodes()
.OfType<LiteralExpressionSyntax>()
.First()
.DescendantTokens()
.First()
.Text;
}
Otherwise, may need to look for the variable declaration in other parts of the submitted code (ex. class fields, properties, other methods, etc.) which is a bit more cumbersome.
Unfortunately Roslyn cannot provide a variable's value in a common cases when values is defined at runtime, because Roslyn actually doesn't know all possible values which may pass from outside the program, it doesn't calculate them and so on so forth. But if you can limit the needed cases to a inlining strings or variables which was declared and initialized at strings, Roslyn may help you with this:
You need to keep InvocationExpressionSyntax (or directly their first arguments)
var invocations = root.DescendantNodes()
.OfType<InvocationExpressionSyntax>()
.Select(ie => (ModelExtensions.GetSymbolInfo(model, ie).Symbol, ie))
// Would be better to compare not method's name but it FQN
.Where((symbol, node)) => symbol != null && symbol.Name == "ExecuteSqlCommand" &&
symbol.Parameters.Length == 1 &&
symbol.Parameters[0].Type.SpecialType == SpecialType.System_String &&
node.ArgumentList.Arguments.Count == 1)
.Select((symbol, node) => node);
You need to check not method parameter, but method argument which was passed to it
foreach (var invocation in invocations)
{
var argument = invocation .ArgumentList.Arguments[0];
if (argument is LiteralExpressionSyntax literal && literal.IsKind(SyntaxKind.StringLiteralExpression))
{
// You find invocation of kind `ExecuteSqlCommand("sql")`
}
else
{
var argSymbol = ModelExtensions.GetSymbolInfo(model, argument).Symbol;
if (!(argSymbol is null) && (argSymbol.Kind == SymbolKind.Field || argSymbol.Kind == SymbolKind.Property || argSymbol.Kind == SymbolKind.Local))
{
if (argSymbol.DeclaringSyntaxReferences.Length == 1)
{
var declarationNode = argSymbol.DeclaringSyntaxReferences[0].GetSyntax();
// I'm actually don't remember what exactlly `GetSyntax` returns for fields or locals:
// VariableDeclaratorSyntax or one of it parent LocalDeclarationStatementSyntax and FieldDeclarationSyntax, but if it returns declarations you also can
// get from them VariableDeclaratorSyntax that you need, it's just be a more deep pattern matching
if (declarationNode is VariableDeclaratorSyntax declaratorSyntax &&
declaratorSyntax.EqualsValueClauseSyntax?.Value is LiteralExpressionSyntax literal2 && literal2.IsKind(SyntaxKind.StringLiteralExpression) )
{
// You find invocation of kind `ExecuteSqlCommand(variable)` where variable is local variable or field
}
else if (declarationNode is PropertyDeclarationSyntax property)
{
// You can do the same things for properties initializer or expression body that you was do for fields and locals to check your case,
// but it doesn't work for property with get/set accessors in a common cases
}
}
}
}
}
Hi im doing a test program that uses a wrapper dll to communicate .net projects on a c++ dll. I wanted to create a Form Based example but the documentation only shows samples in console. There is a particular part that bothers me the most.
var mgr = new Pump("localhost",1,"test");
var result = mgr.Connect();
mgr.OnStart = sender => { var sga = sender.GetAllInfo(); };
what does sender means and is there anyway to rewrite it?
Thanks...
What you see here is a lambda expression. In short terms the last line means something like:
Assign to mgr.OnStart a handler that takes one parameter sender and executes the given code. The code invokes the GetAllInfo() method on the sender object and assigns the result to the sga variable.
What don't you like about it and why do you want to rewrite it?
Based on your comment I assume that the code in your question is actually itself invoked inside an event handler (for example a button's OnClick evnet handler) that already takes a parameter named sender.
In that case, simply rename the parameter name in either location, for example like this:
mgr.OnStart = sndr => { var sga = sndr.GetAllInfo(); };
To add to the answers I thought it would be worthwhile showing the comparison of lambdas to normal methods...
Example 1 - Method with single parameter and no return value
Lambda
...
mgr.OnStart = sender => { var sga = sender.GetAllInfo(); };
...
Normal method
...
mgr.OnStart = this.Mgr_Start;
...
private void Mgr_Start(object sender)
{
var sga = sender.GetAllInfo();
}
Note that the parameter type of the above method is object. This will need to change depending on the signature of OnStart's delegate.
Example 2 - Method with no parameters, with a return value
Lambda
...
var getDateTime = () => DateTime.Now;
var dateTime = getDateTime();
...
Normal method
...
var dateTime = this.GetDateTime();
...
private DateTime GetDateTime()
{
return DateTime.Now;
}
I have built my own SQL Query builder that breaks apart an Expression, however, I'm having an issue trying to get the value of string defined in the same function as the lambda expression.
Here is what I am trying to do in console app:
private static void MyBuilderTest()
{
var sqlBuilder = new SqlBuilder();
// Doesn't work -- NEED GUIDANCE HERE
var testValue = "Test"; // Defined in the same function as the lambda below
sqlBuilder.Select<FooObject>(o => o.FooValue == testValue);
// Works
var someObject = new SomeObject { SomeValue = "classTest };
sqlBuilder.Select<FooObject>(o => o.FooValue == someObject.SomeValue);
}
In my builder it subclasses from ExpressionVisitor, and I override the VisitMember. I found that a string defined in at the base Console level will come back as:
Node.Expression.NodeType == ExpressionType.Constant
The Node.Expression passes back properties of:
CanReduce = false
DebugView = ".Constant<ConsoleApplication1.Program+<>c__DisplayClass1>(ConsoleApplication1.Program+<>c__DisplayClass1)"
NodeType = Constant
Type = System.Type {System.RunetimeType}
Value = {ConsoleApplication1.Program}
The Node.Expression.Value contains:
testValue = "Test" (Type: string)
How do I get this value? I've tried several things, like:
var memberType = node.Expression.Type.DeclaringType;
This passes back a ConsoleApplication1.Program type.
However, when I do:
memberType.GetProperty("testValue"); // Declaring Type from Expression
It passes back null.
The above methods work fine if I place the lambda "strings" in a class, but doesn't work if they string is defined in the console function.
Can anyone tell me how to get the string value if it's defined at the function level of the lambda?
EDITED: Added VisitMember
protected override Expression VisitMember(MemberExpression node)
{
if (node.NodeType == ExpressionType.Constant)
{
// Node.Expression is a ConstantExpression type.
// node.Expression contains properties above
// And Has Value of: {ConsoleApplication1.Program}
// Expanding Value in Watch window shows: testValue = "Test"
// How do I get this value, if the ConsoleApplication1.Program type doesn't
// even know about it? Looks like maybe a dynamic property?
}
}
EDITED
Added code to the console app example to show what works and what doesn't.
The lambda in your example has "closed over" the testValue variable, meaning the compiler has captured it as a field of the same name in an automatically generated class called ConsoleApplication1.Program+<>c__DisplayClass1>. You can use normal reflection to get the current value of that field by casting the right hand-side of the binary expression into a MemberExpression.
var testValue = "hello";
var expr = (Expression<Func<string, bool>>) (x => x == testValue);
var rhs = (MemberExpression) ((BinaryExpression) expr.Body).Right;
var obj = ((ConstantExpression) rhs.Expression).Value;
var field = (FieldInfo) rhs.Member;
var value = field.GetValue(obj);
Debug.Assert(Equals(value, "hello"));
testValue = "changed";
value = field.GetValue(obj);
Debug.Assert(Equals(value, "changed"));
Alternatively you can change your variable into a constant.
const string testValue = "hello";
var expr = (Expression<Func<string, bool>>) (x => x == testValue);
var value = ((ConstantExpression) ((BinaryExpression) expr.Body).Right).Value;
Debug.Assert(Equals(value, "hello"));
Instead of doing this by yourself, have a look at PartialEvaluator from Matt Warren. It replaces all references to constants with the constants themselves.
this link: http://www.codeproject.com/Articles/19911/Dynamically-Invoke-A-Method-Given-Strings-with-Met
explains clearly how to invoke a method when you have a method name + type as string variable.
I'm making a c# project with WatiN. All the WatiN methods I use are of the same form:
Examples: *(ById,.ByClass..; so should be connected, but then I could not set it bold :s )
browser.**TextField**(Find.By **Id**("name")).**TypeText**("my name");
browser.**Span**(Find.By **Class**("main_title")).**Click(**);
browser.**Link**(Find.By **Id**("mid_link")).**Click(**);
As you can see, this always consist of 3 methods which are variable. I created a class webElement consisted of the string properties: tag, type, search, action.
Where in example -> tag = "TextField"; type = "Id", search = "name"; action = "TypeText".
To get the web-elements dynamically, I created a WebHandler class where I try to dynamically call the right methods.
So a main class has a list of all the webElement objects and can give the right one at a given time to the WebHandler class. The Webhandler class should now invoke each element dynamically. I use the same invoke method as in given url, so my code to call it is:
class WebHandler:
private IE browser = new IE("google.com");
public void method(WebElement webElement)
{
//Get the findBy dynamically | this works
WatiN.Core.Constraints.Constraint findBy =
(WatiN.Core.Constraints.Constraint)InvokeMethod("WatiN.Core.Find, WatiN.Core", "By" + webElement.Type, webElement.Search); //where type = "Id" and search = "name"
//Get the tag (like textfield, link, span) dynamically | this does not work
Type aType = Type.GetType("WatiN.Core." + webElement.Tag, "WatiN.Core") //how can I set the element variable to this type? aType element -> Does not work
aType element = (WatiN.Core.TextField)InvokeMethod("this.browser", webElement.Tag, findBy); //tag = TextField
element.TypeText("a name"); //same problem as above | so should be invoked
}
QUESTIONS:
How do I invoke method (TextField) of instance class IE
(browser) dynamically using his string version "TextField" as variable? Another way of phrasing it would be: How do I get current variable (browser) by using it's string version "browser"?
How do I set type of variable element dynamically? So when webElement.Tag = Textfield then type should be WatiN.Core.TexField
element = .. (see code)
OWN CONSIDERATIONS:
Main problem I found is that you can only invoke a method from a type, so not from an instance of that type. Is there a way to do this anyway?
This line
Type aType = Type.GetType("WatiN.Core" + webElement.Tag)
does not have a dot after Core. It seems as if Core is a namespace and should thus be separated from the Tag name.
The gist of this is you get the Type you want, then use reflection to get the methods, then invoke the given method, passing the instance in.
So, something like this:
Type aType = Type.GetType(string.Format("WatiN.Core.{0}.WatiN.Core", webElement.Tag));
MethodInfo method = aType.GetMethod("TextField");
method.Invoke(this.browser, webElement.Tag, findBy);
The key bits here are:
Get the Type
Get the Method
Invoke the method with the instance you want
There are shortcuts, and I probably don't have the specifics right for your question, but that should get you close to what you want.
Here ya go, threw this together in LINQPad, but should be more-or-less portable:
void Main()
{
WatiN.Core.Browser theBrowser = new WatiN.Core.IE("google.com");
Foo(theBrowser, "Id", "gbqfq", "TextField", "TypeText", "Search for this");
}
public void Foo(WatiN.Core.Browser browser, string findTypeBy, string search, string tagName, string elementMethodName, params object[] argsForMethod)
{
var watinCoreAsm = Assembly.LoadWithPartialName("WatiN.Core");
if(watinCoreAsm == null) return;
var watinCoreTypes = watinCoreAsm.GetTypes();
if(watinCoreTypes == null) return;
var findType = watinCoreTypes.FirstOrDefault(type => type.Name == "Find");
if(findType == null) return;
var constraintInstance = findType.GetMethod("By" + findTypeBy, new Type[]{ typeof(string) }).Invoke(null, new[]{search});
if(constraintInstance == null) return;
var browserAccessor = browser.GetType().GetMethod(tagName, new Type[]{ constraintInstance.GetType() });
if(browserAccessor == null) return;
var resultElement = browserAccessor.Invoke(browser, new[]{ constraintInstance });
if(resultElement == null) return;
var elementMethod = resultElement.GetType().GetMethod(elementMethodName);
if(elementMethod == null) return;
elementMethod.Invoke(resultElement, argsForMethod);
}