YUI Compression VB vs C# - c#

I am converting a minification function from visual basic:
example = Yahoo.Yui.Compressor.JavaScriptCompressor.Compress(someString, False, True, True, True, -1, UTF8Encoding.UTF8, Globalization.CultureInfo.InvariantCulture)
to c#. However, the compress method in c# only takes a string argument and has no overload methods. Is the below code in c# equivalent to the original VB code above?
var compressor = new Yahoo.Yui.Compressor.JavaScriptCompressor();
example = compressor.Compress(someString);

The equivalent in C#, as far as I can tell from the source, would require you to set the respective properties in the JavaScriptCompressor instance yourself instead of passing them to the (seemingly non-existent) static Compress method. For example:
var compressor = new Yahoo.Yui.Compressor.JavaScriptCompressor
{
Encoding = UTF8Encoding.UTF8,
DisableOptimizations = false,
ObfuscateJavascript = true,
PreserveAllSemicolons = true,
IgnoreEval = true,
ThreadCulture = Globalization.CultureInfo.InvariantCulture
};
var example = compressor.Compress(someString);
The Boolean properties may not be in the same order as they were previously, so I just guessed. There's a JavaScriptCompressorConfig class in the library with these properties but I couldn't find how it would get passed to the compressor.

You are calling the static Yahoo.Yui.Compressor.JavaScriptCompressor.Compress method in VB.NET and instanciating a Yahoo.Yui.Compressor.JavaScriptCompressor class in C#.
You can call Yahoo.Yui.Compressor.JavaScriptCompressor.Compress in C# to reproduce the same behavior.

Related

How to serialize tensor input required by dnnclassifier (serving_input_reciever)

I want to be able to use the dnnclassifier (estimator) on top of IIS using tensorflowsharp. The model has previously been trained in python. I got so far that I can now generate PB files, know the correct input/outputs, however I am stuck in tensorflowsharp using string inputs.
I can create a valid .pb file of the iris dataset. It uses the following feate_spec:
{'SepalLength': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None), 'SepalWidth': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None), 'PetalLength': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None), 'PetalWidth': FixedLenFeature(shape=(1,), dtype=tf.float32, default_value=None)}
I have created a simple c# console to try and spin it up. The input should be an "input_example_tensor" and the output is located in "dnn/head/predictions/probabilities". This I discoved after alex_zu provided help using the saved_model_cli command here.
As far as I am aware all tensorflow estimator API's work like this.
Here comes the problem: the input_example_tensor should be of a string format which will be parsed internally by the ParseExample function. Now i am stuck. I have found TFTensor.CreateString, but this doesn't solve the problem.
using System;
using TensorFlow;
namespace repository
{
class Program
{
static void Main(string[] args)
{
using (TFGraph tfGraph = new TFGraph()){
using (var tmpSess = new TFSession(tfGraph)){
using (var tfSessionOptions = new TFSessionOptions()){
using (var metaGraphUnused = new TFBuffer()){
//generating a new session based on the pb folder location with the tag serve
TFSession tfSession = tmpSess.FromSavedModel(
tfSessionOptions,
null,
#"path/to/model/pb",
new[] { "serve" },
tfGraph,
metaGraphUnused
);
//generating a new runner, which will fetch the tensorflow results later
var runner = tfSession.GetRunner();
//this is in the actual tensorflow documentation, how to implement this???
string fromTensorflowPythonExample = "{'SepalLength': [5.1, 5.9, 6.9],'SepalWidth': [3.3, 3.0, 3.1],'PetalLength': [1.7, 4.2, 5.4],'PetalWidth': [0.5, 1.5, 2.1],}";
//this is the problem, it's not working...
TFTensor rawInput = new TFTensor(new float[4]{5.1f,3.3f,1.7f,0.5f});
byte[] serializedTensor = System.Text.Encoding.ASCII.GetBytes(rawInput.ToString());
TFTensor inputTensor = TensorFlow.TFTensor.CreateString (serializedTensor);
runner.AddInput(tfGraph["input_example_tensor"][0], inputTensor);
runner.Fetch("dnn/head/predictions/probabilities", 0);
//start the run and get the results of the iris example
var output = runner.Run();
TFTensor result = output[0];
//printing response to the client
Console.WriteLine(result.ToString());
Console.ReadLine();
}
}
}
}
}
}
}
This example will give the following error:
An unhandled exception of type 'TensorFlow.TFException' occurred in TensorFlowSharp.dll: 'Expected serialized to be a vector, got shape: []
[[Node: ParseExample/ParseExample = ParseExample[Ndense=4, Nsparse=0, Tdense=[DT_FLOAT, DT_FLOAT, DT_FLOAT, DT_FLOAT], dense_shapes=[[1], [1], [1], [1]], sparse_types=[], _device="/job:localhost/replica:0/task:0/device:CPU:0"](_arg_input_example_tensor_0_0, ParseExample/ParseExample/names, ParseExample/ParseExample/dense_keys_0, ParseExample/ParseExample/dense_keys_1, ParseExample/ParseExample/dense_keys_2, ParseExample/ParseExample/dense_keys_3, ParseExample/Const, ParseExample/Const, ParseExample/Const, ParseExample/Const)]]'
How can I serialize tensors in such a way that I can use the pb file correctly?
I also posted the issue on github, here you can find the iris example python file, pb file and the console applications. In my opinion solving this creates a
neat solution for all tensorflow users having ancient production environments (like me).
The Expected serialized to be a vector, got shape: [] error can be fixed by using an overload of the TFTensor.CreateString function: Instead of directly taking a string, the model apparently expects a vector containing a single string:
TFTensor inputTensor = TFTensor.CreateString(new byte[][] { bytes }, new TFShape(1));
The input_example_tensor in your case now expects a serialized Example protobuf message (see also the docs and the example.proto file).
Using the protobuf compiler, I've generated a C# file containing the Example class. You can download it from here: https://pastebin.com/iLT8MUdR. Specifically, I used this online tool with CSharpProtoc and replaced the import "tensorflow/core/example/feature.proto"; line by the messages defined in that file.
Once you've added the file to your project, you'll need a package reference to Google.Protobuf. Then, you can pass serialized examples to the model like this:
Func<float, Tensorflow.Feature> makeFeature = (float x) => {
var floatList = new Tensorflow.FloatList();
floatList.Value.Add(x);
return new Tensorflow.Feature { FloatList = floatList };
};
var example = new Tensorflow.Example { Features = new Tensorflow.Features() };
example.Features.Feature.Add("SepalLength", makeFeature(5.1f));
example.Features.Feature.Add("SepalWidth", makeFeature(3.3f));
example.Features.Feature.Add("PetalLength", makeFeature(1.7f));
example.Features.Feature.Add("PetalWidth", makeFeature(0.5f));
TFTensor inputTensor = TFTensor.CreateString(
new [] { example.ToByteArray() }, new TFShape(1));
runner.AddInput(tfGraph["input_example_tensor"][0], inputTensor);
runner.Fetch("dnn/head/predictions/probabilities", 0);
//start the run and get the results of the iris example
var output = runner.Run();
TFTensor result = output[0];

How do I grab what is written to console with CSharpCodeProvider

I use following to compile C# in runtime:
CompilerParameters parameters = new CompilerParameters
{
GenerateInMemory = true,
GenerateExecutable = true,
IncludeDebugInformation = true
};
// True - memory generation, false - external file generation
// True - exe file generation, false - dll file generation
var res = pro.CompileAssemblyFromSource(parameters,
code);
Assembly assembly = res.CompiledAssembly;
Type program = assembly.GetType("First.Program");
MethodInfo main = program.GetMethod("Main");
var invoke = main?.Invoke(null, null);
res.Output is an empty list, and If the code has Console.WriteLine(), It gets written to main application's console, however; I wanna grab what is written.
You also should check res.Errors. If there are errors, then they will be there instead. If both Errors and Output are empty, then you may have had a successful compilation without any output. Check: cr.NativeCompilerReturnValue.ToString()

Add class to compiled assembly (in memory)

Since CompileAssemblyFromSource add custom functions in a smart way was ignored im going to ask this question differently so people will bother to read it.
cutting at the chase,i am making a language by "translating" the new syntax into c# and compiling it in memory in this fashion.
using (Microsoft.CSharp.CSharpCodeProvider CodeProv =
new Microsoft.CSharp.CSharpCodeProvider())
{
CompilerResults results = CodeProv.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters()
{
GenerateInMemory = true
},
code);
var type = results.CompiledAssembly.GetType("MainClass");
var obj = Activator.CreateInstance(type);
var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
Console.WriteLine(output);
}
basically i am executing a "main" function written inside the code variable.
and i am using some functions in the code variable i would like to include without adding it as a string at the bottom like this:
code += #"public void Write(string path, object thevar)
{
if (thevar.GetType() == typeof(string))
{
System.IO.File.WriteAllText(path,(string)thevar);
}
if (thevar.GetType() == typeof(string[]))
{
System.IO.File.WriteAllLines(path,(string[])thevar);
}
}";
Can i somehow add a class from my Actual main project in VS and let the compiled in memory code access it? without adding it as a string.
You can embed your source code file(s) as resources. With this technique you can edit the file in Visual Studio and access the contents of the files as if it was a string during run-time.
This link shows how to do it:
https://stackoverflow.com/a/433182/540832

c# CommandLine.Parser - Use constructor that accepts Action<ParserSettings>

I was using this code, but I am getting a compiler warning that this method of creation is deprecated. As I want to remove the warning, and move to the newer version, I want to correct the code, but I can not get the CommandLineParser 1.9.7 library to work.
CommandLine.Parser OptionParser = new CommandLine.Parser(new CommandLine.ParserSettings
{
CaseSensitive = UseCaseSensitive,
IgnoreUnknownArguments = IgnoreUnknownOptions,
MutuallyExclusive = EnableMutuallyExclusive
}
);
bool Result = OptionParser.ParseArguments(Args, this);
This code works and Result would be True/False based on the parameters of the command line and options passed. However, the following warning is posted.
Warning 1 'CommandLine.Parser.Parser(CommandLine.ParserSettings)' is obsolete: 'Use constructor that accepts Action<ParserSettings>.'
The Online help shows this as an example for using the function.
new CommandLine.Parser(configuration: () => new CommandLine.ParserSettings(Console.Error))
I tried changing the code, but I am not getting the Lambda right, and am not sure how to get this to work. While the code executes, I only get the default functions, I can not seem to change the Case Sensitive, Mutually Exclusive, etc... options.
Line using the Constructor (from the inline IDE help)
bool Result = new CommandLine.Parser(configuration: (Settings) => new CommandLine.ParserSettings(UseCaseSensitive, EnableMutuallyExclusive, IgnoreUnknownOptions, null)).ParseArguments(Args, this);
Trying again with the virtual settings:
bool Result = new CommandLine.Parser(configuration: (Settings) => new CommandLine.ParserSettings
{
CaseSensitive = UseCaseSensitive,
IgnoreUnknownArguments = IgnoreUnknownOptions,
MutuallyExclusive = EnableMutuallyExclusive
}
).ParseArguments(Args, this);
The online help has not kept up with the tool, and I could use any pointers someone might have. Thanks in advance...
Looking at the source code the constructor runs that Action passed on new settings that it creates:
public Parser(Action<ParserSettings> configuration)
{
if (configuration == null) throw new ArgumentNullException("configuration");
this.settings = new ParserSettings();
configuration(this.settings);
this.settings.Consumed = true;
}
So in the Action<ParserSettings> you should set the values you want on the parameter, not create new settings (remember that an Action<T> is a prototype for a function that takes a T and does not return a value):
var parser = new CommandLine.Parser( s =>
{
s.CaseSensitive = UseCaseSensitive;
} );
NOTE: The source code I linked to does not appear to be the same version as you are using since Parser( ParserSettings ) is marked internal in the source I found, which means you wouldn't even be able to call it, and some of the ParserSettings properties do not appear in the version I found. However, I believe this answer applies to the version you have as well.

A failing minimal example of executing JS in Win 8.1 Chakra with C#

I'm attempting to execute a tiny piece of JS via the following code (utilising the Native class from the Chakra Host example from MSDN):
var runtime = default(JavaScriptRuntime);
Native.ThrowIfError(Native.JsCreateRuntime(JavaScriptRuntimeAttributes.None, JavaScriptRuntimeVersion.VersionEdge, null, out runtime));
var context = default(JavaScriptContext);
Native.ThrowIfError(Native.JsCreateContext(runtime, (Native.IDebugApplication64)null, out context));
Native.ThrowIfError(Native.JsSetCurrentContext(context));
var script = #"var bob = 1;";
var result = default(JavaScriptValue);
var contextCookie = default(JavaScriptSourceContext);
Native.ThrowIfError(Native.JsRunScript(script, contextCookie, "source", out result));
The problem is that it returns a "ScriptCompile" error with no additional details that I'm able to spot.
Is anyone able to reveal what I've missed / done dumb / gotten confused over?
I doubt you're still wrestling with this... but I just did and figured out the answer.
If you look in jsrt.h you'll see that all the native functions use a wchar_t when using string parameters, however the DllImport attribute doesn't specify the charset, so it defaults to ANSI.
I did a find/replace in the Native.cs file and changed all the DllImport attributes to read...
[DllImport("jscript9.dll", CharSet = CharSet.Unicode)]
... and now my code works fine. I've sent a pull request to the sample owner on GitHub to get this fixed up. The update is currently in my fork at https://github.com/billti/chakra-host
Try adding this to your AssemblyInfo.cs file:
[module: DefaultCharSet(CharSet.Unicode)]
I modified my implementation of Native.ThrowIfError to, in the case of a ScriptCompile error, get some values out of the errorObject. Like so:
var message = errorObject
.GetProperty("message")
.ToString();
var source = errorObject
.GetProperty("source")
.ToString();
var line = (int)errorObject
.GetProperty("line")
.ToDouble();
var column = (int)errorObject
.GetProperty("column")
.ToDouble();
var length = (int)errorObject
.GetProperty("length")
.ToDouble();
throw new JavaScriptParseException(error, message, source, line, column, length);
This should get you more information at least.

Categories

Resources