Gå til innhold

C#: Er dette en god kode for en simpel kalkulator, som regner ut regnestykker fra 1 tekstboks?


Gjest Slettet-aNZFa3

Anbefalte innlegg

Gjest Slettet-aNZFa3

Klikk for å se/fjerne innholdet nedenfor
public void Compile(string Code)
	{
		try
		{
			string sCode = @"
				  using System;
				  using System.Windows.Forms;
				  class Calc 
				  {
					  public void Main()
					  {
						MessageBox.Show(Convert.ToString(" + Code + @"));
					  }
				  }";

			CSharpCodeProvider codeProvider = new CSharpCodeProvider();

			ICodeCompiler compiler = codeProvider.CreateCompiler();
			CompilerParameters parameters = new CompilerParameters();
			parameters.GenerateExecutable = false;
			parameters.GenerateInMemory = true;
			parameters.MainClass = "Calc.Main";
			parameters.IncludeDebugInformation = false;

			foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
			{
				parameters.ReferencedAssemblies.Add(asm.Location);
			}

			CompilerResults results = compiler.CompileAssemblyFromSource(parameters, sCode);

			object o = results.CompiledAssembly.CreateInstance("Calc");
			Type type = o.GetType();
			MethodInfo m = type.GetMethod("Main");
			m.Invoke(o, null);
		}
		catch
		{

		}
	}

 

Jeg har nesten samme koden i et annet programm, men der bruker jeg koden til dynamisk kode visning, egentlig bare for moro skyld.

 

Kort oppsummert av kalkulatoren:

Den henter ut teksten fra en tekstboks, når det blir trykket på en knapp, den teksten blir da "matet" inn i funksjonen som da viser svaret i en MessageBox.

 

Spørsmål: Hvor avansert er det å lage en bool funksjon som verifisere teksten som et regnestykket? Er det bare å prøve å kompilere den koden og returnere true hvis det gikk bra, og false hvis det er noen feilmeldinger?

 

EDIT: koden den funker den.

Endret av Slettet-aNZFa3
Lenke til kommentar
Videoannonse
Annonse

okei, wtf? Så la meg bare få dette helt rett: du har en tekstboks, som for eksempel inneholder teksten "2+4" eller "3*6", og den koden der bruker du for å få svaret til å poppe opp i en tekstboks? Jeg håper virkelig jeg har misforstått noe kraftig, for det der må være den dårligste, treigeste, mest håpløse løsningen på et slikt problem du kunne funnet på.

Lenke til kommentar

er det så enkelt at du bare har "a+b", "a-b", "a*b" eller "a/b" ville jeg kanskje gjort noe slikt:

class Program
{
	public delegate double MyDelegate(double a, double b);

	static void Main(string[] args)
	{
		string math = "2 - 3";
		Console.WriteLine(Parse(math));

		math = "12432*234234";
		Console.WriteLine(Parse(math));

		math = "1345	 /	   123542";
		Console.WriteLine(Parse(math));
		Console.Read();
	}

	static double Parse(string math)
	{
		string pattern = @"^\s*(?<a>\d+)\s*(?<operator>(\+|\-|\*|\/))\s*(?<b>\d+)\s*$";
		if (Regex.IsMatch(math, pattern, RegexOptions.IgnorePatternWhitespace))
		{
			Match match = Regex.Match(math, pattern, RegexOptions.IgnorePatternWhitespace);
			MyDelegate del = GetDelegate(match.Groups["operator"].Value);
			return del(double.Parse(match.Groups["a"].Value), double.Parse(match.Groups["b"].Value));
		}
		else
			throw new Exception("parameter doesn't seem valid");
	}
	static MyDelegate GetDelegate(string op)
	{
		switch (op)
		{
			case "+":
				return new MyDelegate(Add);
			case "-":
				return new MyDelegate(Subtract);
			case "*":
				return new MyDelegate(Multiply);
			case "/":
				return new MyDelegate(Divide);
			default:
				throw new Exception("Invalid operator");
		}
	}

	static double Add(double a, double b)
	{
		return a + b;
	}
	static double Subtract(double a, double b)
	{
		return a - b;
	}
	static double Multiply(double a, double b)
	{
		return a * b;
	}
	static double Divide(double a, double b)
	{
		if(b != 0)
			return (a / b); 
		throw new DivideByZeroException();
	}
}

dog, det er heller ingen god løsning hvis problemet ikke alltid er så statisk.

 

PS: jeg tok meg friheten å sammenlikne ytelsen, denne løsningen var ca 7000 ganger raskere på 100 parsinger.

 

og enda en PS: du skal ha credit for kreativitet, løsningen var om ikke annet svært original. og en ting til, du kjører vel en form for validering av tekstboksinnholdet? hvem som helst kan jo skrive C#-kode der som kan kjøres av programmet ditt, kanskje ikke det smarteste.

Endret av hockey500
Lenke til kommentar
Gjest Slettet-aNZFa3

Jeg har også med sin, cos, tan og log. Koden min så kan man regne ut lange regnestykker (men treigt).

Eks:

2+2*(Cos(3)/Tan(2))+5*10

, den funker den, men Texas Kalkulatoren min er mye raskere.

Men skal prøve koden din seinere idag, og modifisere den til mitt bruk. Jeg har mye igjen å lære, og jeg stopper vel heller ikke å lære.

 

Jeg har endel kode til (med tan, sin cos etc), men den er egentlig ikke så relevant for saken akkuratt nå.

Endret av Slettet-aNZFa3
Lenke til kommentar

Skal du kunne parse sånne uttrykk ville jeg ikke satset på verken min eller din løsning. da trenger du en helt annen tilnærming til problemet.

 

Tror faktisk det nylig ble diskutert her på forumet, det var en fyr som spurte om forslag til hva han kunne lage i IT2 på VGS, en kalkulator som parser slike uttrykk ble da foreslått. Du kan kanskje starte med å lese hva som ble sagt der. Eller du kan fortsette med din metode, som forsåvidt funker greit, så lenge du forsikrer deg om at det ikke skrives inn kode i input og du ikke bryr deg om ytelse.

Lenke til kommentar

Mitt forslag til utbedring er å hente ut den innerste parentesen, deretter lage en liste over instruksjoner som du sorterer etter operator, og utfører, og repeat.

Det er normal praksis at ( dytter akkumulatorverdien til stack, og ) henter den tilbake.Koden til hockey500 tar ikke hensyn til operator presedens eller parantes. Compileren er treg, som vel er eneste ulempen.

10 + 20 * 30 + ( 40 - 50 )

som kan sees slik

20 * 30 + 10 + ( 40 - 50 )

 

add 20

mul 30

add 10

push

add 40

sub 50

add pop

 

edit: og bytt fra double til decimal.

 

Når det gjelder C# compileren til kalkulator kan det være en god idé å alltid legge til return først, slik at koden alltid havner på maks én linje.

Sånn det er gjort nå, så kan hvem som helst gjøre hva som helst.

Endret av GeirGrusom
Lenke til kommentar
Gjest Slettet-aNZFa3

En løsning til er jo å opprette et .vbs skript, og så kjøre den.

Jeg leste i den andre tråden, og kom fram til at jeg kunne prøve å få til reversed polish notation.

Lenke til kommentar
Gjest Slettet-aNZFa3

Det med et .vbs skript fungere perfekt, rask var den også (raskere). Men jeg skal fortsatt ta en titt på reverse polish notation.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...