Wednesday, April 30, 2014

Java之OCR

Java的OCR有一个简单的lib是ocr4j.jar,他可以识别背景不复杂的文字

              OCR ocr = null;
              try {
                     ocr = new OCR();
              } catch (IOException e2) {
                     // TODO Auto-generated catch block
                     e2.printStackTrace();
              }
              File img = new File("C:\\Users\\KK\\Documents\\Coding\\Java\\IMG_2915.PNG");
              try {
                     String text = ocr.recognise(ImageIO.read(img));
                     System.out.print(text);
              } catch (IOException e1) {
                     // TODO Auto-generated catch block
                     e1.printStackTrace();

              }

图片如下:


References:
[1] http://ocr4j.sourceforge.net/









Saturday, April 26, 2014

KB: Java之反射

import java.lang.reflect.*;

1.得到类名:Class c = Class.forName(this.getClass().getName().toString()); this为instance,如果这句在基类,类,getClass会得到给子类。class name是包括包名的,比如com.vtasters.entity.Car Car是类名
2. 得到某类(this)的某属性:c.getField("location").get(this),如果该属性是static,就如下c.getField("location").get(null)
3. 设置某类(this)的某属性:c.getField("location").set(this, "Jersey city");
4. 获得某类某属性的类型:
Field fields[] = c.getDeclaredFields();
for(Field f : fields)
{
            f.getType()
5. 调用方法:
    Class cls=null;
    cls=Class.forName("com.vtasters.Dish");
    Object obj=cls.newInstance();
    Method method=cls.getMethod("Test",null);
    method.invoke(obj);
    这里调用一个没有参数叫Test的方法

     Class cls=null;
  cls = Class.forName("com.framework.Action");

  Object obj = cls.newInstance();

  Class[] cArg = new Class[2];
  cArg[0] = int.class;
  cArg[1] = String.class;
  Method method2 = cls.getMethod("bbb", cArg);
  Object returnType = method2.getReturnType();
  Object value = method2.invoke(obj,5,"6");
  System.out.println(returnType.toString()+":"+value.toString());

    这里调用一个带参数和返回值叫bbb的方法,定义如下
    int bbb(int a, String b){}

    注意,有时一些内部类带的属性或方法,不能在被调用的方法(e.g. bbb)中使用,要作为参数输入,否则会出现Reflection异常

如果参数个数是动态,就这样写:
       String[] mainArgs = new String[5];
      method.invoke(null, (Object)mainArgs);
getDeclaredMethod可以得到protected的方法,但getMethod只能得到公共方法

6. 返回值
Object value = method.invoke(this, x);
                d = (Double) value;

7. 调用构造函数
            cls = Class.forName("com.itg.generic.Events");
            Class[] constructorArg = new Class[1];
            constructorArg[0] = Operator.class;
            Object obj = cls.getDeclaredConstructor(constructorArg).newInstance(this);

8. 判断一个数据是否实例
    Num param instanceof Double

a=="mystr"不对,要用a.equals("mystr")

Wednesday, April 23, 2014

KB: c#之反射

有时为了使相似度较高的代码智能化,我们会使用到反射。
这是Reflexion的命名空间using System.Reflection;

前面的blog说到C#之Entity framework,提到这段代码:

using (ModelEntities context = new ModelEntities())
{
     context.stocks_EF.Add(new stocks_EF() { Symbol = "CAT", Price = 98.42, PricePct = 2.5, Volume = 29389, AvgVolume = 39392, MktCap = "56.5B", Yield = 2.2, PE = 10.2, TradeDate = Convert.ToDateTime("2013-06-17 00:00:00.000") });
     context.SaveChanges();
}


    public partial class ModelEntities : DbContext
    {
        public DbSet<stocks_EF> stocks_EF { get; set; }

    }

下面我说说怎么用反射写这段代码。
1.已知道类型的Type:Type contextType = typeof(ModelEntities);如果是某instance的type是    
  obj.GetType()
2. 创建某类型的Instance:object context = Activator.CreateInstance(contextType);
3. 获得某Instance的某属性的值:
  object dbSetInstance = contextType.GetProperty(propName).GetValue(context);
4. 获得某Instance的某属性的类型:
    Type dbSetType = contextType.GetProperty(propName).PropertyType;
5.获得某类型的某方法:MethodInfo objAddMethod = dbSetType.GetMethod("Add");
6.Call某方法: objAddMethod.Invoke(dbSetInstance, new object[]{obj});
(eg2)7.获得泛型的参数类型
                if (propType.IsGenericType)
                {
                    Type[] paraList = propType.GetGenericArguments();
                    propertyName = paraList[0].Name;

                }
8.设置某属性的值:t.GetProperty(name).SetValue(obj, "abd")


Type contextType = typeof(ModelEntities);
object context = Activator.CreateInstance(contextType);
Type objType = obj.GetType();

var propNames = from p in contextType.GetProperties() select p.Name;

foreach (var propName in propNames)
{
    if (objType.ToString() == contextType.Namespace+"."+propName)
    {
         object dbSetInstance = contextType.GetProperty(propName).GetValue(context);
         Type dbSetType = contextType.GetProperty(propName).PropertyType;

         MethodInfo objAddMethod = dbSetType.GetMethod("Add");
         objAddMethod.Invoke(dbSetInstance, new object[] { obj });

         MethodInfo objSaveMethod = contextType.GetMethod("SaveChanges");
         objSaveMethod.Invoke(context, null);
     }
}

再训练一个:
    public partial class stocks_EF
    {
        public int ID { get; set; }
        public string Symbol { get; set; }
        public Nullable<double> Price { get; set; }
        public Nullable<double> PricePct { get; set; }
        public Nullable<int> Volume { get; set; }
        public Nullable<int> AvgVolume { get; set; }
        public string MktCap { get; set; }
        public Nullable<double> Yield { get; set; }
        public Nullable<double> PE { get; set; }
        public Nullable<System.DateTime> TradeDate { get; set; }
        public Nullable<System.DateTime> InsertTime { get; set; }

    }


code如下:
public static void Fill(string[] words, object obj)
{
    Type t = obj.GetType();
    var propNames = from p in t.GetProperties() select p.Name;
    int i=0;
    foreach (var name in propNames)
    {
        Type propType = t.GetProperty(name).PropertyType;
        string propertyName = propType.Name;

        if (propType.IsGenericType)
        {
            Type[] paraList = propType.GetGenericArguments();
            propertyName = paraList[0].Name;
        }
        if (propertyName == "DateTime")
            t.GetProperty(name).SetValue(obj, Convert.ToDateTime(words[i]));
        else if (propertyName == "Int32")
            t.GetProperty(name).SetValue(obj, Convert.ToInt32(words[i]));
        else if (propertyName == "Double")
            t.GetProperty(name).SetValue(obj, Convert.ToDouble(words[i]));
        else t.GetProperty(name).SetValue(obj, words[i]);
        i++;
    }


}

main函数:
string[] words = { "1", "CAT", "98.43", "2.5", "29389", "39392", "56.5B", "2.2", "10.2", "2013-06-17 00:00:00.000", "2014-04-23 00:00:00.000" };
 stocks_EF s = new stocks_EF();
 Fill(words, s);


KB: Batch的简介

Batch其实就是CMD编程

1. 传入参数
假设我们有一个test.bat,代码如下:

test.exe "abc.txt"

我们希望在cmd中传入自定义文件名称,batch file的代码可以改成

test.exe %1

然后cmd中可以输入test.bat abc.txt或者test.bat me.data,即可作为参数传递给test.exe

2.Call
如果调用非exe,要加上call,比如call abc.bat,否则如果有如下命令:
abc.bat
dd.exe
没有call的话,dd.exe不会执行,所以 应该这样:
call abc.bat
dd.exe
[1] http://stackoverflow.com/questions/4825746/cmd-exe-when-to-use-call-to-run-external-programs

3.常用设置
@rem表示注释行还可以用::
@echo off表示不输出cmd自带结果,除非你显示调用echo函数
@setlocal enableextensions enabledelayedexpansion设置环境变量可见性
endlocal结束设置环境变量可见性

4. 局部变量
Set Filename="abc.txt"
set aaa = %Filename%
for 循环的变量可以用%%x详见7

5. 循环、if and goto以及动态赋值
for:
for /l %%x in (1,1,100) do (
    echo %%x
    copy %%x.txt z\whatever\tect
)
左括号要在第一行,不能在新行
in cmd use %x instead of %%x
不能用::作注释只能用@rem
set newest=%a%
echo !newest!由于for是循环,赋值大部分都是动态,所以用动态取值(execution time rather than at parse time)!newest!而不是%newest% 还例如findstr /m /c:"my" !newest!连%errorlevel%也要改成!errorlevel!
要打印%today%要加引号"%today%"而!newest!无需引号

if:
if %aa%==5 echo 6
if %aa%==5 (
     echo 6
)
没有else,要用多重if来实现

goto:
@echo off
setlocal enabledelayedexpansion
IF 5==5 IF 4==3 (
    GOTO END
)
echo 2
:END
ECHO DONE
这里goto相当于break或者return

6. 等效and/or操作符的代码
AND: 
if %age% geq 2 if %age% leq 12 set class=child
OR: 
set res=false
if %hour% leq 6 set res=true
if %hour% geq 22 set res=true
if "%res%"=="true" (
    set state=asleep
)
NOT: 
if not a==5 echo 6




9. 文件和路径
执行非当前路径的命令---执行后返回到之前目录
pushd D:\a
for /f "tokens=*" %%a in ('dir /b /od') do set newest=%%a
copy "%newest%" D:\b
popd
复制最新文件到D:\b然后回到原来目录

移动所有文件
move "*.txt" c:\

判断文件夹是否未空或者不含某类文件:
@echo off
for /F %%i in ('dir /b "c:\test directory\*.*"') do (
   echo Folder is NON empty
   goto :EOF
)
echo Folder is empty or does not exist


10. 字符串操作
可以参考
http://scripts.dragon-it.co.uk/scripts.nsf/docs/batch-search-replace-substitute!OpenDocument&ExpandSection=3&BaseTarget=East&AutoFramed
http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace

10.1 在文档中找给定的字符串
findstr /c:"Job finished" abc.txt
     if %errorlevel%==0 (
     echo Given string is found
)

10.2 是否含有给定字符串
@setlocal enableextensions enabledelayedexpansion
@echo off
set str1=%1
if not %str1:bcd=%==%str1% echo It contains bcd
endlocal
str1是否含有bcd,用的方法是replace给定字符串再比较原来的,%str1:bcd=%是在str1中用空字符替换bcd如果给定字符串是变量,参见10.3

10.3 替代变量字符串
@echo off
setlocal enabledelayedexpansion
set string=This is my string to work with.
set find=my string
set replace=your replacement
call set string=%%string:!find!=!replace!%%
echo %string%
这里用了延迟赋值来替换
所以10.2如果bcd是变量可以变成if not %string%==%str1%

11. 睡眠sleep 30秒,ctrl+c中断
timeout /t 30 /nobreak

12. taskkill
taskkill /im calc.exe 终止所有计算机(一个或多个)
taskkill /f /fi "Windowtitle eq 5554:test" /im *(终止某一个指定程序)

13. Forfiles
http://ss64.com/nt/forfiles.html


--get files whose last modified date is older than 90 days
forfiles -p "C:\Users\KK\Documents\Test" /d -90


--loop in a dir and echo file name ("cmd /c echo @file" is default cmd)
forfiles -p "C:\Users\KK\Documents\Test" /d -90 /c "cmd /c echo @file"


--loop in a dir and see if any file exists in it(if not, error occurs)
forfiles /s -p "D:\ETLSourceFiles\Carmax\DEAR"

--loop in a dir and delete each directory whose last modified date is older than 90 days
forfiles -p "C:\Users\KK\Documents\Test" /d -90 /c "cmd /c IF @isdir == TRUE rd /s /q @path & echo @path >> abc.txt"

Monday, April 21, 2014

C#之Entity framework

Entity Framework用于简历数据库与逻辑对象的映射

假设我们有表:
CREATE TABLE [dbo].[stocks_EF](
    [ID] int identity(1,1),
       [Symbol] [varchar](10) NOT NULL,
       [Price] [float] NULL,
       [PricePct] [float] NULL,
       [Volume] [int] NULL,
       [AvgVolume] [int] NULL,
       [MktCap] [varchar](20) NULL,
       [Yield] [float] NULL,
       [PE] [float] NULL,
       [TradeDate] [datetime] NULL,
       [InsertTime] [datetime] default(getdate())
)



Visual studio 2012的设置:
连接数据库:
add sql server connection


















选择数据库:

































到这里,我们已经把数据库内置到了visual studio 2012中了。


下面我们加入entity framework:


































加入.edm,这个可以数据库命名
























选择Generate from database,然后选择要创建model的database表:






























完成后,我们看到生成的代码结构如下:



















双击ModelDB.edmx,会看到一个图形化表,如果以txt打开它,会看到它的内在代码:分为三部分:StorageModels (db table), ConceptualModels (C# class),Mappings。

运行如下C#代码:
          static void Main(string[] args)
        {
            using (ModelEntities context = new ModelEntities())
            {
                context.stocks_EF.Add(new stocks_EF() { Symbol = "CAT", Price = 98.42, PricePct = 2.5, Volume = 29389, AvgVolume = 39392, MktCap = "56.5B", Yield = 2.2, PE = 10.2, TradeDate = Convert.ToDateTime("2013-06-17 00:00:00.000") });
                context.SaveChanges();
            }


        }

会得到如下错误:
Unable to update the EntitySet 'stocks_EF' because it has a DefiningQuery and no <InsertFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.

如果表有primary key,不用手动修改edmx文件,否则就要做改动:
这是因为该表没有primary key,有两个解决方案:
1. 写SP
2. 手动改.edmx的代码:
去掉store:Schema中的store,还去掉definingQuery部分即可

    <edmx:StorageModels>
      <Schema Namespace="modelModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
        <EntityContainer Name="modelModelStoreContainer">
          <EntitySet Name="stocks_EF" EntityType="modelModel.Store.stocks_EF" store:Type="Tables" store:Schema="dbo" store:Name="stocks_EF">
            <DefiningQuery>SELECT
      [stocks_EF].[ID] AS [ID],
      [stocks_EF].[Symbol] AS [Symbol],
      [stocks_EF].[Price] AS [Price],
      [stocks_EF].[PricePct] AS [PricePct],
      [stocks_EF].[Volume] AS [Volume],
      [stocks_EF].[AvgVolume] AS [AvgVolume],
      [stocks_EF].[MktCap] AS [MktCap],
      [stocks_EF].[Yield] AS [Yield],
      [stocks_EF].[PE] AS [PE],
      [stocks_EF].[TradeDate] AS [TradeDate],
      [stocks_EF].[InsertTime] AS [InsertTime]
      FROM [dbo].[stocks_EF] AS [stocks_EF]</DefiningQuery>
          </EntitySet>
        </EntityContainer>
        <!--Errors Found During Generation:
      warning 6002: The table/view 'model.dbo.stocks_EF' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.
      -->
        <EntityType Name="stocks_EF">
          <Key>
            <PropertyRef Name="ID" />
            <PropertyRef Name="Symbol" />
          </Key>
          <Property Name="ID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
          <Property Name="Symbol" Type="varchar" Nullable="false" MaxLength="10" />
          <Property Name="Price" Type="float" />
          <Property Name="PricePct" Type="float" />
          <Property Name="Volume" Type="int" />
          <Property Name="AvgVolume" Type="int" />
          <Property Name="MktCap" Type="varchar" MaxLength="20" />
          <Property Name="Yield" Type="float" />
          <Property Name="PE" Type="float" />
          <Property Name="TradeDate" Type="datetime" />
          <Property Name="InsertTime" Type="datetimeStoreGeneratedPattern="Computed"/>
        </EntityType>
      </Schema>

    </edmx:StorageModels>

运行代码后,发现insertTime没有输入,显然是DEFAULT contraint没有设置好:
只要加入黄色部分代码StoreGeneratedPattern即可.。

Refer to http://blogs.msdn.com/b/alexj/archive/2009/09/01/tip-34-how-to-work-with-updatable-views.aspx