C# Art

30 Янв
2012

Поздравляю всех с наступившим годом какого-то там дракона! Как бы там его астрологи не называли, но для меня дракон всегда черно-красный!

Для начала — картинка:


Не бойтесь, она единственная, дальше чуть-чуть текста и немного кода )



Картинка вверху — вполне работающий кусок кода, правда её надо разделить на блоки, поставить один за одним и тогда скомпилить, но оно работает…

А всё к чему? Просто когда я общался с папой, олдскульным прогером любящим фортран я всегда аргументировал нежелание учить этот язык отсутствием сводного позиционирования кода (он предлагал обмен опытом: он учит шарп, я -фортран))) ). Но только недавно я задумался над тем что по факту мне дает это самое свободное позиционирование… Ну да, можно расставить отступы, абзацы, пробелы, все красиво, понятно, но… скучно!

А вот как бы сделать код веселее и попутно скрыть его от случайных глаз? Скажем вы программируете за общественным ПК и храните свои творения там-же, забирая только удавшиеся проекты (чур меня от такого). А что если ваши исходники откроет знающий человек и «позаимствует» хорошую идею? Печально. А станет ли даже самы лучший спец без веского основания вчитываться в такой вот код:

                    using System; using System.Collections.Generic;
               using System.Text; using Math_Super.Consts; using System.IO;
           using Math_Super.Operators; using System.Reflection; using System.
          Globalization; namespace Math_Super { public class Math_Base { protected
         string tp = "Math_Base"; public bool can_cash = false; public bool is_cash 
        = false; public   double                                    cash = 0; public
       static    Dictionary   <                                       string,Type>Funcs
       =new Dictionary<string,                                         Type>();   public
      virtual  double  Eval()                                          {return double.NaN
     ; }  public static void                                            Init(string path)
    { string[ ] functions =
    Directory  .  GetFiles(
   path ,"Function_*.dll"
  ,         SearchOption.
  TopDirectoryOnly ); for
  ( int  i  =  0 ;  i  < 
 functions.Length; i++) {
 Assembly asm= Assembly.
 LoadFrom(functions[i]);                                                Type[]  tp  =  asm.
  GetTypes(); for(int j =                                               0; j < tp.Length;j++
   ) { Object  ob  = tp[j].                                            GetConstructor  (  new 
   Type[]{typeof(Math_Base)                                           }).Invoke(new Object[]
   { Math_Base.Parse("PI", "") });                                  Funcs.Add(((Math_Function
    )ob).Alias, tp[j]);} }} public static Math_Base Parse(string s, string pre) { return 
     Parse(s, pre, "",""); } public static Math_Base Parse(string s,string pre,string 
       int_pre,string int_var) { if (s == "") { return new Math_Const(0); } for (int 
          i = 0; i < s.Length; i++) { if (s[i] == '+') { string left = s.Substring(
             0, i);string right=s.Substring(i + 1);output.Add("Found '+' operator");
               return new Operator_Plus( Math_Base.Parse( left,   pre,   int_pre, 
                 int_var), Math_Base.Parse(right, pre, int_pre, int_var));

                          }if (s[i] == '-')                  { string left =
                         s.Substring(0,i);                  string right  = 
                        s.Substring(i+1);                  output.Add("Found"+
                       " '-' operator");                  return      new 
               Operator_Minus(Math_Base.Parse(left, pre, int_pre, int_var), Math_Base.
              Parse(right, pre, int_pre, int_var)); }if (s[i] == '('){output.Add("Found"+
             "'('. Ignoring"); i = ignore(s, i);if (i == -1)break;}} for (int i = 0; i <
            s.Length; i++){if (s[i] == '*'){output.Add("Found '*' operator");string left 
           =  s.Substring(0,  i); string  right  =  s.Substring( i  +  1) ;  return new 
          Operator_Multiply(Math_Base.Parse(left, pre,  int_pre,  int_var),  Math_Base.
         Parse(right, pre, int_pre, int_var));}if(s[i]== '/') {output.Add("Found '/'"+
               " operator");string                  left = s.Substring(
              0, i); string right                  = s.Substring(i + 1);
             return          new                  Operator_Devide    (
            Math_Base.Parse  (                   left,  pre,  int_pre, 
           int_var),Math_Base.                  Parse(  right,   pre, 
     int_pre, int_var));} if (s[i] == '('){output.Add("Found '('. Ignoring"); i = 
    ignore(s, i); if (i == -1)break;}}for (int i = 0; i < s.Length; i++) {if(s[i] 
   == '^') { output.Add("Found '^' operator"); string left = s.Substring(0, i);
  string right = s.Substring(i + 1);return new Operator_Power(Math_Base.Parse
 (left, pre, int_pre, int_var), Math_Base.Parse(right, pre, int_pre, int_var
 ));}if (s[i] == '('){output.Add("Found '('. Ignoring"); i = ignore(s, i);
if (i == -1)break;}}if (s[0]  ==  '(' && ignore(s, 0) == s.Length - 1) {
     output.Add("Found"+                    " '(' at start."  +
    " ReParsing without"+                  " breckets"   )   ;
   return   Math_Base.                    Parse(s.Substring
  (1, s.Length - 2),                     pre,     int_pre, 
  int_var);}bool ok                     = true; for (int 
             
                                 i = 0; i < s.Length; i++)
                               { if (!char.IsDigit(s[i]) &&
                              s[i] != ',' && s[i] != '.')  {
                            ok = false; }} if (ok) {  output.
                         Add("Found numeric constant."); return
                        new Math_Const(            double.Parse(
                       s, CultureInfo.            InvariantCulture));
                      }if (s == "E"){             output.Add("Found "+
                    "const E");return             new Const_E();} if (s
                    == "PI") {output.             Add("Found const PI");
                    return new Const_PI(); } if (char.IsLetter(s[0])||s[
                    0]=='!'){ bool br=false;for (int i = 1; i < s.Length; 
                   i++) {if (s[i] == '('){br=true; if (ignore(s, i) ==  s
                   .Length  -  1 ) {              output . Add ( "Found" +
                   " Function."  +                 " Inditificating."  );
                   return                            GetFunction        (
                  s.Substring(0, i                  ), s.Substring(i + 1 ,
                  s.Length - i - 2                  ),pre,int_pre,int_var);
                   
                   }else{break;}}} if (!br){if (s != int_var){
                   output . Add ( "Found Variable. Name: " + s + 
                   " Prefix: " + pre);                 return new 
                   Math_Variable ( pre                     + "_" + s);
                   }else{output.Add                        ("Found "+
                   "Variable. Name:"                       + s+" Pre"+
                   "fix: " + int_pre);                      return new
                   Math_Variable   (                         int_pre + 
                   "_" + int_var); }}}if(s.Length>8) if (s.Substring(0
                   , 8) == "Integral"){ if (s[8] ==  '(' ) {  int k =
                   ignore(s, 8); int k2 = ignore(s, k + 1); int k3 =
                   ignore(s, k2 + 1); string 
                   inte = s.        Substring
                   (9, k - 9);       string lft
                   = s.Substring      (k + 2, k2
                   -k-2); string        rt  =  s.
                   Substring(k2+         2,k3- k2-
                   2);  Random r         =new Random();
                   string var  =          s.Substring(k3

                    + 2, s.Length - k3 - 3); output.Add("Found Integral."+
                    " Base: " + inte + " Left: " + lft + " Right: " + rt + 
                    " Variable: " +var);return new Math_Integral(Math_Base.
                                        Parse(inte,pre),
                                        Math_Base.Parse
                                        ( lft ,  pre ) , 
                                        Math_Base.Parse
                                        (rt, pre),pre +
                                        "_"+var);} else
                                        {if(s.Substring
                                        (8,11)=="_Trape"
                                        +"cials"){int k 
                                        = ignore(s, 20);
                                        int k2 = ignore
                                        (s, k + 1); int 

k3=ignore(s,k2+1);string inte=s.Substring(20, k-20);string 
lft=s.Substring(k+2, k2-k-2);string rt=s.Substring(k2+2,k3
-k2-2);Random r=new Random(); string var=s.Substring(k3+2, 
s.Length-k3-3);output.Add("Found Trapecial Integral. Base: "
+inte+" Left: "+lft+" Right: "+rt+" Variable: "+var);return 
new Integral_Trapecials(Math_Base.Parse(inte,pre),Math_Base
.Parse(lft, pre), Math_Base.Parse(rt, pre),var);}}} output.
Add("Can't indefine sring: "+s+" Returning ZERO");   return 
new Math_Const(0);}private static int ignore(string s,int i)
{int c = 1;if (s.Length < 3)return -1;for (int j = i + 1; j 
< s.Length; j++){if (s[j] == '(')c++;if (s[j] == ')')  c--;
if (c ==0)return j;}return-1;}static Math_Base GetFunction(
string s,string val,string pre,string int_pre,string int_var
){s = s.ToLower();if (Funcs.ContainsKey(s)){  output.Add(s);
return(Math_Base)Funcs[s].GetConstructor(new Type[]{ typeof
(Math_Base) }).Invoke(new Object[] {Math_Base.Parse(val,pre)
});}else{output.Add("Udefined function: " + s); return new 
Math_Const(0);}} public static Dictionary<string, double> 
vars = new Dictionary<string, double>();public static List
<string> output = new List<string>();}}


Ну так станет, а?

Думаю нет. Да, знаю что скажете: в MVS надо просто убрать и поставить последнюю фигурную скобку и всё выровняется. Я тоже так думал пока не попробовал. БОльшая часть кода так и останется не отформатированной. «Так-то дружок» как сказал-бы ДоДо из сказки о Алисе.

А знаете к чему я это всё? Неа, не знаете 🙂 Просто решил поделится свой простенько прогой на шарпе, которая из любой строчки вида sin(Pi/2)*3^3 или такого вида Integral(ln(cosh(tan(x)))(0)(5)(x) /*интеграл выражения на интервале от 0 до 5 dx*/ в адекватный результат…
Вообщем сделал я парсер математических выражений на шарпе, сделал возможность добавлять новые распознаваемые функции в виде подключаемых библиотек и решил подарить вам всем, кому потребуется… Только с основным классом парсера прийдется повозится, что-бы к нормальному виду привести, ведь это именно он там вверху так изнасилован 🙂

Спасибо за внимание, проектик с парсером, пачкой функций, и простенькое приложение-калькулятор вот тут
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх