Calling C# static method from F# - c#

I have this class in C#:
using System.Collections.Generic;
namespace StrassGlassLib
{
public class Mesh
{
private List<Model.Node> _ns;
private List<Model.Plate> _ps;
public Mesh()
{
_ns = new List<Model.Node>();
_ps = new List<Model.Plate>();
}
public List<Model.Node> Nodes => _ns;
public List<Model.Plate> Plates => _ps;
public void AddNode(Model.Node n)
{
_ns.Add(n);
}
public void AddPlate(Model.Plate p)
{
_ps.Add(p);
}
// CREATION METHOD
public static Mesh CreatePlanarMesh()
{
// create new mesh
Mesh m = new Mesh();
// add node
for (int y = 0; y < 2; y += 1)
{
for (int x = 0; x < 4; x += 1)
{
m.AddNode(new Model.Node(0, x, y, 0.0));
}
}
return m;
}
}
}
I'm trying to call from F# to learn how to make test with this language, but:
namespace StraussGlassTest
open System
module MeshTesting =
open StrassGlassLib
let m = Mesh.CreatePlanarMesh()
The problems are:
I've got error FS0039: The namespace or module 'Mesh' is not defined.
No error on the console, the code looks good
if I try to access to Nodes property I've got error FS0039: The field, constructor or member 'Nodes' is not defined
I imagine i miss more than something on how F# works, Do you have some hints?

ok
the problem was the interactive part
#if INTERACTIVE
#r #"C:\Users\p.cappelletto\Documents\Visual Studio 2015\Projects\StraussGlass\StraussGlassLib\bin\Debug\StraussGlassLib.dll"
#r #"C:\Users\p.cappelletto\Documents\Visual Studio 2015\Projects\StraussGlass\StraussGlassLib\bin\Debug\StrausLib.dll"
#endif
namespace StraussGlassTest
open System
module MeshTesting =
open StraussGlassLib
open StrausLib
let m = Mesh.CreatePlanarMesh()
printfn "%A" m.Nodes.Count
Now it works, see it also this

Related

How to parse a multi-lined lambda statement string into DynamicExpression.ParseLambda?

I want to pass a multi-statement lambda string (a little program in fact) into DynamicExpression.ParseLambda but I fear I may have reached its limitations. I have written code to feed small lambda expressions but I think it will choke on a full program.
Here is MCVE so far. It shows the original algorithm BuildSieve() and also it shows the beginning of lambda equivalent but it fails on first line with exception Unknown identifier 'long'
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using diag=System.Diagnostics;
using myAlias = System.Linq.Dynamic; //install package 'System.Linq.Dynamic' v.1.0.7 with NuGet
namespace LambdaStatement
{
class Program
{
static void Main(string[] args)
{
BuildSieveLambda();
Console.ReadKey();
}
static void BuildSieveLambda()
{
try
{
var pList = new List<ParameterExpression>();
pList.Add(Expression.Parameter(typeof(int), "x"));
LambdaExpression e = myAlias.DynamicExpression.ParseLambda(pList.ToArray(), null, "long n = 2000000;");
}
catch (Exception ex)
{
string msg = GetExMessage(ex);
diag.Debug.WriteLine("DEBUGME: " + msg);
throw new Exception(msg);
}
}
public static string GetExMessage(Exception ex)
{
string ret = ex.Message;
if (ex.InnerException!=null)
{
ret= ret+ ": " + GetExMessage(ex.InnerException);
}
return ret;
}
static void BuildSieve()
{
//https://gist.github.com/gideondsouza/1978926 Sieve of Eratosthenes C# implementation by code Gideon Israel Dsouza
long n = 2000000;
bool[] e = new bool[n];//by default they're all false
for (int i = 2; i < n; i++)
{
e[i] = true;//set all numbers to true
}
//weed out the non primes by finding mutiples
for (int j = 2; j < n; j++)
{
if (e[j])//is true
{
for (long p = 2; (p * j) < n; p++)
{
e[p * j] = false;
}
}
}
}
You may think this is impossible but I've seen some really complicated lambda expressions in C# code, full method implementations in fact. So if the C# compiler or Visual Studio can do this then is there access to that API to programmers?
You need to add n the same way you added x:
pList.Add(Expression.Parameter(typeof(long), "n"));
LamdaExpression e = myAlias.DynamicExpression.ParseLamda(pList.ToArray(), null, "n = 200000");
Although, I admit, I have no idea what this program does, but this is why you get that error. It is reading long in the string as an identifier, instead of a type.

C# Ambiguous reference between self built Node<T> \ List<T> Class to system's Node and List

I have built my own Node\List Classes in c#, and I have tried to use them in a new project, but vs seems to give me countless errors which I can't figure out how to solve out.
Code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Students;
using Nodes;
namespace schoolNodes
{
class Program
{
public static Student Best(List<Student> x)
{
Node<Student> p = x.GetFirst();
Student tal, talmax = null;
float mem, max = 0;
while (p != null)
{
tal = p.GetValue();
mem = tal.Avg();
if (mem > max)
{
max = mem;
talmax = tal;
}
p = p.GetNext();
}
return talmax;
}
public static int NumTeacherOfClass(string s, List<Teacher> l)
{
Node<Teacher> p = l.GetFirst();
int n = 0;
while (p != null)
{
if (p.GetValue().CheckClass(s))
n++;
p = p.GetNext();
}
return n;
}
Wherever there is List<...> it gives me an error.
The names space where I put my Node\List classes in is called "Nodes".
Any suggestions? Thank you!
You are using System.Collections.Generic together with your Nodes, which contains List definition. This leads to compiler error. Try to using full name with namespace, like Nodes.List<Student> instead of List<Student>.

C# Variable is assigned but never used [duplicate]

This question already has answers here:
Variable is assigned but its value is never used (C#)
(4 answers)
Closed 6 years ago.
I am getting an error with my code.. I am new to C# and I am trying to make a two player turn based game. Doing this using visual studio
The error is "Warning 2 The variable 'gs' is assigned but its value is never used"
The code is below;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System;
namespace GridWorld
{
public class newAI : BasePlayer
{
PlayerWorldState myWorldState;
private double maxSpeed = 5f;
//public int MaxNumTurn = 15;
private int Steps;
private object count;
public newAI ()
: base()
{
this.Name = "AI FOR GAMES THE A TEAM";
// this.MaxNumTurn = 15;
var gs = new GridSquare.ContentType(); // the variable gs is now a new GridSquare content type
}
void Pathfind()
{
PlayerWorldState startingPoint = BasePlayer(GridSquare.ContentType.Snail);
int myX = 0;
int myY = 0;
if (myX == -1 || myY == -1) // if myX & myY are equal to minus 1 then increment the steps
Steps++;
{
return;
}
gs [myX, myY].Steps = 0; // outside whileloop
while (true)
{
bool madeProgress = false;
foreach (startingPoint mainPoint in gs)
{
int x = mainPoint.X;
int y = mainPoint.Y;
if (SquareOpen(x, y))
{
int passHere = GridSquare[x, y].Steps;
foreach (startingPoint movePoint in ValidMoves(x, y))
{
int myX = movePoint.X;
int myY = movePoint.Y;
int newPass = passHere + 1;
if (GridSquare[myX, myY].Steps > newPass)
{
GridSquare[myX, myY].Steps = newPass;
madeProgress = true;
}
It is not really an error. As it says, its just a warning stating that the variable 'gs' is assigned somewhere but never used anywhere. This should not cause your application to stop working.
You're declaring and defining gs in your constructor newAI and attempting to use it in Pathfind. Pathfind can't see it, because it's local to your class constructor i.e. a local scoped variable. Move it into your class like your maxSpeed, Steps and count variables.
It is only a warning, but your code is going to have undefined behaviour at the very least.

Vector folding using Divide et Impera in c#

I'm in trouble on a College project.The project needs to be done using c# as a programming language and made in Windows Form like.
The program executes. I know it has flaws but at least i want to know how to get of this error: http://postimg.org/image/gwuzmyc73/ .
For the problem i need to fold a vector using the Divide et Impera.
I need to insert a number from the keyboard n, the generated vector would be like a=(1,2,3,4,5,6,7) and the final elements are 1,3,5,7.
The problem sounds like:
A vector of n elements.We define its folding by overlaping the 2 halfs,if n is odd.The 2 halfs are folded again until de subvector reaches 1 element.Utilize Divide et Impera.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Plierea_Vectorilor
{
public partial class Form1 : Form
{
public int n;
public int i;
public int[] efinal = new int[50];
public string m = new string(new char[50]);
public int Ls, Ld;
public char[] aux = new char[50];
public Form1()
{
InitializeComponent();
}
public void Pliaza(int p,int q)
{
if (p == q)
{
efinal[p] = 1;
}
else
{
if ((q - p + 1) % 2 != 0)
{
Ls = (p + q) / 2 - 1;
}
else
{
Ls = (p + q) / 2;
}
Ld = (p + q) / 2 + 1;
}
Pliaza(p, Ls);
Pliaza(Ld, q);
/*
string ss = Ls.ToString();
string sd = Ld.ToString();
for (i = p; i <= Ls; i++)
{
aux[0] = 'S';
string.Concat(aux, ss);
string.Concat(aux, " ");
string m = aux.ToString();
string.Concat(aux, m[i]);
}
for ( i = Ld; i <= q; i++)
{
aux[0] = 'D';
string.Concat(aux,Ld);
string.Concat(aux, " ");
string m = aux.ToString();
string.Concat(aux, m[i]);
}
*/
}
private void button1_Click(object sender, EventArgs e)
{
Pliaza(1, n);
for (i = 1; i <= n; i++)
{
if (efinal[i]!=0)
{
label2.Text = Convert.ToString(i);
}
}
}
private void label2_Click(object sender, EventArgs e)
{
}
}
}
You're ALWAYS executing the Pliaza function FROM Pliaza. Aren't you missing a finish condition?
The recursive loop must be finished sometime in someway, else you will get that stack overflow.
A StackOverflowException usually means you have uncontrolled recursion going on. Reviewing your code, I see that Pliaza calls itself twice, using different variables ... but there is no path for Pliaza to exit without calling itself. You need some path to let the recursion bottom out. Very likely this would be to add a return; statement after the efinal[p] = 1; line.

c# create program using function to generate multiplication table using [Class Library] and test the function with different scenarios [NUnit]

Hi I need a little help creating a simple program that will Generate multiplication table (using for-loop) by using Class Library from VS C#.
I have here below the incomplete code for the for-loop but I got lost coz it's a bit different than application form and console application. If you're using class library you cannot use debug, you can run or check the codes by using Test Explorer/ Test.
(Edited Update 1) For this 2 things are needed.
Class Library (Main program)
Same solution but another class name, now it comes with NUnit that is referenced to the Main Program.
(Edited Update 2)
I'll be back to check for some info
Update 3. Here's the new code
namespace FunctionTest
{
[TestFixture]
public class Class1
{
[Test]
public void Multiplication()
{
int i;
int n = 0;
n = Convert.ToInt32(Console.ReadLine());
for (i = 1; i < 13; i++)
{
Console.WriteLine(i + "x" + n + " = " + i * n);
}
}
}
Here's the idea or what it should be look like. (Below is the program)
using System;
namespace ExerciseFunction
{
public class Equations
{
public int addition(int x, int y)
{
int z = x + y;
return z;
}
public int subtraction(int x, int y)
{
int z = x - y;
return z;
}
public int multiplication(int x, int y)
{
int z = x * y;
return z;
}
public int division(int x, int y)
{
int z = x / y;
return z;
}
static void Main(string[] args)
{
}
}
}
Now this one is the NUnit to check if the input or answer is correct or not of the Program.
using NUnit.Framework;
using ExerciseFunction;
namespace ExerciseNunit
{
[TestFixture]
public class Operations
{
[Test]
public static void addition()
{
Equations result = new Equations ();
float r = result.addition(4, 5);
Assert.AreEqual(9, r);
Assert.AreNotEqual(13, r);
}
[Test]
public static void subraction()
{
Equations result = new Equations();
int t = result.subtraction(5, 3);
Assert.AreEqual(2, t);
Assert.AreNotEqual(5, t);
}
[Test]
public static void multiplication()
{
Equations result = new Equations();
int y = result.multiplication(6, 3);
Assert.AreEqual(18, y);
Assert.AreNotEqual(15, y);
}
[Test]
public static void division()
{
Equations result = new Equations();
int u = result.division(4, 2);
Assert.AreEqual(2, u);
}
}
}
Thanks and looking forwards hearing your response. Your help is appreciated!
If you want to write a program, you probably want to execute it too. So you need and executable, not a library.
So first create a new project "Console Application" or "Windows Forms Application", or maybe a "WPF application" but not a Class Library. Also writing some unit test is useful, but I don't thing that in this case.
Secondly: do not declare loop variable i before the cycle. Do it in the cycle like this
for (int i = 0; i < 15; ++i) //or i++ there is a difference but not relevant right now.
Then... You probably want to get some input from a user to get your n.
In console application you can do that like this
int n;
string input = Console.ReadLine();
if (int.TryParse(input, out n))
{
//do your math here.
}
else
{
Console.WriteLine("That was not a number.");
}
Your for-cycle would work but the formatting of the output will be poor and most importantly, you are not printing or giving the output anywhere. So let's fix it like this (put that to place "//do your math here."):
for (int i = 1; i < 15; ++i)
{
Console.WriteLine(string.Format("{0} x {1} = {2}", i, n, i * n));
}
In the end you might want the application not to exit immediately. If you add Console.ReadLine(); in the end. It will wait for pressing any key before it exits.
If you so much want to have the algebra part in another project (which doesn't really make sense, but OK), you can create another project (Class Library) with this class in it (or put just the class in the existing project):
public static class Algebra
{
public static int Multiply(int a, int b)
{
return a * b;
}
//.... other methods
}
and then call it in the for loop like this:
int product = Algebra.Multiply(i, n);
Console.WriteLine(string.Format("{0} x {1} = {2}", i, n, product));
And of course you can then unit-test the Multiply method as much as you want.

Categories

Resources