python的map函数的用法

作为python的常用内置函数之一,map函数在某些场景解决问题确实方便,今天就整理一下map函数的用法。

函数官方解释

def map(function, sequence, *sequence_1): # real signature unknown; restored from __doc__
“””
map(function, sequence[, sequence, …]) -> list

Return a list of the results of applying the function to the items of
the argument sequence(s). If more than one sequence is given, the
function is called with an argument list consisting of the corresponding
item of each sequence, substituting None for missing values when not all
sequences have the same length. If the function is None, return a list of
the items of the sequence (or a list of tuples if more than one sequence).
“””
return []

看上去还是挺好理解的,加上一些例子就没问题了。

参数

function:一个函数

Sequence:列表

*sequence_1:多个列表

返回值

一个列表list

作用

①传入一个函数,一个列表的情况

将函数作用于列表中的每一个元素,最终返回作用后的结果列表。

相当于[function(x) for x in sequence]

②传入一个函数,多个列表的情况

取不同列表相同位置的元素,传入函数中进行处理,最终返回作用后的结果列表。

例子

①传入一个函数,一个列表的情况

上代码:

list1 = [1, 2, 3, 4]
def incre(x):
    return x+1
result_list = map(incre,list1)
print result_list

输出结果为[2, 3, 4, 5]

②结合匿名函数lambda使用

以下代码的效果和例子①是一样的:

list1 = [1, 2, 3, 4]
result_list = map(lambda x:x+1,list1)
print result_list

lambda函数,这是python的匿名函数,这里先不多说了。

③传入一个函数,多个列表的情况

先上代码:

list1 = [1, 2, 3, 4]
list2 = [2, 3, 4, 5]
list3 = [3, 4, 5, 6]
def addition(x,y,z):
    return x+y+z
result_list = map(addition,list1,list2,list3)
print result_list

输出结果是[6, 9, 12, 15]

看数字,可以感觉得出来,6=1+2+3,9=2+3+4,12=3+4+5,15=4+5+6,这个时候再看看我在上面的解释:

取不同列表相同位置的元素,传入函数中进行处理,最终返回作用后的结果列表

就比较好理解了,这相当于并行处理。

这里要注意两点:

1.传入的列表(或元组)的数目,要和函数参数的数目一致,比如例子③里面函数addition就需要三个参数,这个时候得传三个列表进去。

2.不同列表的长度要一致,且对应元素的类型要相同。

④传入None

这种情况,直接传入None作为函数,看代码:

list1 = [1, 2, 3, 4]
list2 = [2, 3, 4, 5]
result_list = map(None, list1)
print result_list
#输出结果:[1, 2, 3, 4]
result_list = map(None, list1, list2)
print result_list
#输出结果:[(1, 2), (2, 3), (3, 4), (4, 5)]

如果只传一个列表进去,那就原封不动的返回,如果传多个列表,则效果和zip()函数是一样的,返回一个大列表,里面是多个列表相同位置元素组合出来的元组。

python的切片(slice)机制

在python编程中,我们经常要取list或者tuple里面的元素,或者对字符串进行处理,这恰恰也是python的一个闪光点,它的切片(slice)机制,使得我们处理这类问题变得简单灵活。

“切片”是针对列表(list)、元组(tuple)的,另外,字符串也可以当作特殊的list,通过切片,可以很轻易的实现截取字符串、反转字符串的操作。

所谓的切片,就是按照你的规则,将一个列表切成另外一个列表,先来直观感受一下。

list = ["lookfor404","lipengfei","hello","what"]
list1 =list[0:2:2]
print list1

你猜输出什么?输出了一个新的列表['lookfor404']

假如是这样呢?又会输出什么?

list = ["lookfor404","lipengfei","hello","what"]
list1 =list[0:2:1]
print list1

答案是['lookfor404', 'lipengfei']

现在就来解释一下。切片的使用就是这么简单,在一个list后面加个中括号,里面有两个冒号,插空有3个参数。

list[first_index:last_index:step]

这个表示,从这个list的first_index开始,到last_index结束(不包括last_index本身),以step步长来截取这个list

回到刚才的例子,由于list = ["lookfor404","lipengfei","hello","what"],这个list有4个元素,而list1 =list[0:2:2]表示的是,从list的第0个元素(lookfor404)开始,到第2个元素(hello)结束,以步长2来截取list,这里要注意的是,前两个参数0和2,在数学上是个半闭半开的区间:[0,2)。所以,很自然的,可以得到list1的结果就是['lookfor404']

当然,并不是一定要用两个冒号,如果只使用了一个冒号,就意味着步长默认为1。以上是常规用法,下面拓展一下,其实它很强大,所以python不需要一些字符串的截取函数了。

比如————
复制list,可以直接这样

list = ["lookfor404","lipengfei","hello","what"]
list1 =list[:]

list1就复制了list的内容过来了,因为冒号两边不填参数的话,就默认从0到最后一个元素(包括最后一个元素)。

再比如————
反转字符串,可以这样

str = "helloworld"
str1 =str[::-1]

此时输出str1就是'dlrowolleh'。原因在于步长参数,我们选择了负数,没错,负数就表示反着来,-1表示倒序,-2表示隔着步长2倒序,也就是说,如果str1 =str[::-2],那么输出str1为'drwle'

最后对边界进行一个总结,直接上代码:

s = ["a","b","c","d"]       # s的上界为0,下界为 4(事实上,最后一个元素的索引为3,但这里称4为下界)
s[-100:100]       #返回 [1,2,3,4] :-100超出了上界,100超出了下界:等价于 s[0:4]
s[-100:-200]      #返回 [] :-100,-200均超出了上界,自动取上界:等价于s[0:0]
s[100:200]        #返回 [] :100,200均超出了下界,自动取下界值:等价于s[4:4]
s[:100]           #返回 [1,2,3,4] :开始值省略表示从第0个开始,等价于s[0:4]
s[0:]             #返回 [1,2,3,4] :结束值为空表示到最后一个结束,等价于s[0:4]

运行ggplot出现问题:no display name and no $DISPLAY environment variable

最近在用django做一个项目,关于数据可视化的。作图方面,之前用过百度的echart,这个是在前端直接调用的,这次想尝试在后台直接生成图,然后存在服务器上,之后前端再把图片显示出来就好了。

用的ggplot。

在windows下,用runserver测试,没问题。但是在服务器上,就跑不了了,出现了这样的提示:

tkinter.TclError: no display name and no $DISPLAY environment variable

查看了一下debug信息,发现貌似和Matplotlib有关,继续顺藤摸瓜。

找到了问题所在:http://matplotlib.org/faq/howto_faq.html#howto-webapp

官网的英文解释:

Many users report initial problems trying to use maptlotlib in web application servers, because by default matplotlib ships configured to work with a graphical user interface which may require an X11 connection. Since many barebones application servers do not have X11 enabled, you may get errors if you don’t configure matplotlib for use in these environments. Most importantly, you need to decide what kinds of images you want to generate (PNG, PDF, SVG) and configure the appropriate default backend. For 99% of users, this will be the Agg backend, which uses the C++ antigrain rendering engine to make nice PNGs

不想读完也没关系,大概说下怎么回事。

不同的系统有不同的用户图形接口,默认的接口在windows下跑是没有问题的,问题是我们很多的webapp都不在windows上跑,一般在linux上面,所以要更改它的默认配置,把模式更改成Agg。

纯代码解决方案

这也是大部分人在网上诸如stackoverflow的问答平台得到的解决方案,在引入pyplot、pylab之前,要先更改matplotlib的后端模式为”Agg”。直接贴代码吧!

# do this before importing pylab or pyplot
Import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot asplt

更改配置文件方案

就我的情况而言,上面那种解决方案似乎不适用,因为我是在django中使用的ggplot,它调用matplotlib的时机,我并不是很清楚。所以试了几次,都没有能把matplotlib.use('Agg')这句代码放在正确的位置上,因而也解决不了错误。

所以我转向了另一种解决方案,也是从官网启发而来。

好了,这里告诉我们,什么是backend:

http://matplotlib.org/faq/usage_faq.html#what-is-a-backend

然后这里告诉我们,怎么改配置文件:

http://matplotlib.org/users/customizing.html#customizing-matplotlib

看到下面这个地方:

matplotlibrc文件

没错,它的配置文件就是matplotlibrc,在哪里呢?不同系统不一样,我的系统是ubuntu,运行了命令whereis matlotlibrc,找到了。

matplotlibrc文件位置

编辑一下:

sudo vim /etc/matplotlibrc

找到backend这里,然后将其改成Agg,如下!

# The default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
# CocoaAgg MacOSX Qt4Agg Qt5Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG
# Template.
# You can also deploy your own backend outside of matplotlib by
# referring to the module name (which must be in the PYTHONPATH) as
# ‘module://my_backend’.
backend : Agg

保存,运行,错误消失。

在linux服务器上部署django项目

不得不承认,django自带的runserver功能确实强大,使得我们在开发的过程中可以轻松的在本地调试、查看网站。但开发是开发,做的项目总归是要部署到服务器上面去的,最近把项目部署到linux上了,这里记录一下。

官方文档:https://docs.djangoproject.com/en/1.9/howto/deployment/

我是参照着文档部署的。下面是我的环境:

ubuntu14.04.3
python2.7.6
apache2.4.7
django1.9.7
mod_wsgi4.5.3

接下来进入配置环节。

安装python-dev

默认情况下,ubuntu系统是安装了python的,不过如果只用这个python,在后面的部署过程就会出问题,先查看你的python版本,不出意外的话是2.7.x,然后额外安装一个对应的dev版。

apt-get install python2.7-dev

安装django

这个很简单,直接pip安装就行,选择好你要的版本。

pip install Django==1.9.7

安装python的mysql驱动

如果你的数据库用的是mysql,还得安装这个。

sudo apt-get install python-mysqldb

安装Apache

在ubuntu系统上,Apache是预装了的,但是它不支持apxs的,对于之后要安装的wsgi组件来说,apxs是必须的。还得安装一个Apache的dev版。先确认你已经安装的Apache版本,我的是Apache2,所以直接运行以下命令继续安装dev版:

sudo apt-get install apache2-dev

安装编译mod_wsgi

有了上述的准备工作之后,安装mod_wsgi就不是什么问题了。

这个是官方文档:https://modwsgi.readthedocs.io/en/develop/user-guides/quick-installation-guide.html

我记录一下我安装编译的步骤。

先去下载源代码:https://github.com/GrahamDumpleton/mod_wsgi/releases

我下载的是mod_wsgi-4.5.3.tar.gz。

然后上传到服务器,解压:

tar xvfz mod_wsgi-X.Y.tar.gz

PS:X,Y为你实际的文件版本,跟文件名一致即可。

解压之后,cd到对应的目录。然后运行

./configure

./configure命令
然后继续运行:

make

最后运行(PS:这一步是需要管理员权限的):

sudo make install

安装成功:
mod_wsgi安装成功
注意图片的第一行,说的是mod_wsgi安装的路径;还有最后一行,要给mod_wsgi.so加上对应的权限。

sudo chmod 644 /usr/lib/apache2/modules/mod_wsgi.so

配置mod_wsgi到Apache上

安装成功之后,要更改一下Apache的配置文件。编辑(不同系统下Apache配置文件不一样,有的是httpd.conf)

sudo vim /etc/apache2/apache2.conf

在文件的最后一行,加上
LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so
其中第三个参数,是刚才安装完的mod_wsgi.so对应的路径。

部署django项目

django项目刚开始的时候,我们一般都是运行startproject命令来生成项目,这样做有一个好处,django会帮我们自动生成wsgi的配置文件。

首先把本地的django项目复制到服务器上,一般是/var/www/html下,以你Apache的配置为准。

然后我们继续编辑Apache的配置文件:

sudo vim /etc/apache2/apache2.conf

在最后,添加如下内容:

WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonPath /path/to/mysite.com

Require all granted< /Files>

要注意,/path/to/mysite.com/ 这个路径不要搞错,就是你项目的路径。

配置完毕,重启Apache。

sudo apachectl restart

访问网站
直接输入ip地址访问网站,发现访问不了,查看了一下Apache的error log:

from django.core.wsgi import get_wsgi_application
ImportError: No module named ‘django.core.wsgi’

后来发现,原来是权限问题,无法执行django里面的文件。心累。。

加个权限就行了。

cd /usr/local/lib/python2.7/dist-package
sudo chmod a+x django

ok,项目就这么部署完毕了,如果你是正式的项目,记得把django的debug模式关掉。

WinSCP上传文件出错解决方法

在用WinSCP上传本地文件到/var/www的时候,出现了一个错误:

Permission denied.
Error code: 3
Error message from server: Permission denied

很明显,权限错误。

也就是说,我登陆的这个账号,不能往这个文件夹里面写东西。解决方法也有很多种,无非就是更改权限,或者更改文件归属了。

最暴力的方法:

sudo chmod 777 -R /var/www

其中,-R代表www下的子文件的权限也被更改
或者可以更改文件夹的归属:

sudo chown -R username /var/www/

其中username更改为你登陆WinSCP的用户名即可。

问题是解决了,但是以上方法并不是最好的方法,最好的方法是要根据自己服务器的安全策略,然后给文件夹设定对应的权限,这就涉及到linux的跟权限有关的知识了,这里也整理一下。

文件权限

以以下这个文件为例:

drwxrwxr-x 2 ubuntu ubuntu 4.0K Jul 26 11:58 testdir

一个一个解释。

drwxrwxr-x:有10个字母,第一个字母代表文件的类型,-代表文件,d代表文件夹,l代表链接;剩下9个字母,三个字母分为一组,共有三组。第一组代表文件所有者的相应权限,第二组代表与文件所有者同一组的用户的相应权限,第三组代表其他用户的权限。r代表读权限,w代表写权限,x代表执行权限。

2:代表链接的文件数,有2个。

ubuntu:文件所有者

第二个ubuntu:文件所有者所在组

再后面就是时间和文件名了。

更改文件权限

更改文件权限的基本命令是chmod,这里抛出一个规定,那就是每种权限对应一个数字:r=4,w=2,x=1,所以rwx可以表示为7(4+2+1),rw-可以表示为6(4+2),就是简单的加法。有了这个规定,我们来看命令就很明白了。

chmod 751 abc:赋予abc权限rwxr-x–x

chmod u=rwx,g=rx,o=x abc:同上,u=用户权限,g=组权限,o=不同组其他用户权限

chmod u-x,g+w abc:给abc去除用户执行的权限,增加组写的权限,减号代表去除权限,加号代表增加权限

chmod a+r abc:a代表所有用户,这里是给所有用户添加读的权限

chmod a=rwx abc:这条命令等价于chmod 777 abc

在windows下用ppk后缀文件登陆远程服务器

最近要部署一个项目到服务器上,对方给我生成了一个以ppk为后缀名的密钥,让我直接登陆,这里记录一下过程。

用putty通过ssh登陆服务器

下载putty

貌似官网上不了。我是在这里下载的:

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

下载putty.exe,不用安装。

连接服务器

打开putty,在host name那里填写服务器地址,登录方式默认就行了。

putty登陆服务器

在左边栏打开选择SSH,找到AUTH,然后Browse你的ppk授权文件,点击open。

导入ppk授权文件

然后输入ppk授权文件对应的linux用户名,即可登陆成功,如下:

putty登陆成功

用WinScp登陆文件服务器

WinScp给了我们图形化的操作界面,允许我们从windows直接拖拽文件到服务器上,非常方便。这里记录下怎么用ppk文件来登陆。

下载、安装WinScp

下载地址:http://winscp.net/eng/download.php

安装过程可以选择语言,默认是中文,我选择的是英文。

使用ppk文件登录

打开软件,在Host name填写服务器地址,Port number默认22即可,User name填写用户名。然后点击下面的advanced选项。

打开winscp

然后选择ssh下的authentication,在private key file选择授权文件(即你的ppk后缀名文件)即可。

winscp选择授权文件

点击ok,然后回到第一个界面,login就行了。

登录成功,可以直接拖拽文件实现上传下载了。

winscp登陆成功

django中的Q()函数:应用于model数据查询的与(and)或(or)操作

问题背景

之前用django的时候,数据库这一块也没有涉及到比较复杂一点的查询,一般就是一个filter()或者一个get()就搞定了,前几天做一个可视化的项目时,遇到了多条件复合查询,看了下文档,django的orm还是挺好用的,Q()函数可以解决这个问题。

比如我要查询id为1或者id为2的一个数据,在filter里面,是不能够这么直接来的:filter(id=1,id=2),只能使用Q函数。为了更深入地理解Q函数,我参考官方文档,整理一下它的用法。

文档位置:https://docs.djangoproject.com/en/1.9/topics/db/queries/#complex-lookups-with-q-objects

django中Q()函数的介绍

如果你需要进行复杂的查询(比如or条件),你可以使用Q对象。

Q对象是用来封装查询参数的,比如,它可以仅仅用来封装单独一个like查询:

from django.db.models import Q
Q(question__startswith='What')

Q函数可以通过逻辑符号连接

Q对象可以和&|这两个符号一起来使用,即and和or。下面这个例子就用or将两个查询组合在了一起:

Q(question__startswith='Who') | Q(question__startswith='What')

相当于以下sql语句:

WHERE question LIKE 'Who%' OR question LIKE 'What%'

另外,还可以使用非符号~,比如:

Q(question__startswith='Who') | ~Q(pub_date__year=2005)

Q函数用于数据库查询

以上介绍了Q的组合方法,那么怎么把它应用到数据库的查询呢?一般而言,可以把它们放到filter(),get()或者exclude()里面,比如:

Poll.objects().filter(Q(question__startswith='Who') | ~Q(pub_date__year=2005))

Q函数和关键字参数混合使用

另外,Q对象还可以和关键字参数一起使用,不过Q一定要放在前面,以下是正确例子:

Poll.objects.get(
    Q(question__startswith='Who'),
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)

相当于sql查询语句如下:

SELECT * from polls WHERE question LIKE 'Who%'
    AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

关键字参数放在前面是错误的用法!!如下是错误的!

# 错误用法
Poll.objects.get(
    question__startswith='Who',
    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
)

我的实践

我喜欢这样来用Q对象。先在外面将条件组合好,然后再传入filter()get()或者exclude()里面,代码片段如下:

from django.db.models import Q
my_filter = Q()
my_filter = my_filter | Q(id=1)
my_filter = my_filter | Q(name="lipengfei")
result = People.objects.filter(my_filter)

java获取网页正文:WebCollector

WebCollector是一个无须配置、便于二次开发的JAVA爬虫框架(内核),它提供精简的的API,只需少量代码即可实现一个功能强大的爬虫。

Github上面更新到最新版本2.28,maven的中央仓库暂时只更新到2.09

2.09版本似乎没有把ContentExtractor集成进来,所以还是建议直接在github上先下载最新版本的jar,然后在buildpath里面引进来就行。

项目介绍:http://crawlscript.github.io/WebCollector/

项目github:https://github.com/CrawlScript/WebCollector

中文文档:https://github.com/CrawlScript/WebCollector/blob/master/README.zh-cn.md

来个简单的例子,对于中文url的支持,这个框架还是可以的。

import cn.edu.hfut.dmic.contentextractor.ContentExtractor;
import cn.edu.hfut.dmic.contentextractor.News;

public class WebExtraction {
    public static void main (String args[]) throws Exception{
        String url = "https://www.lookfor404.com/利用bootstrap的滚动监听+affix做一个侧导航landingpage/";
	String content = ContentExtractor.getContentByUrl(url);
	System.out.println("content:"+content);
	News news = ContentExtractor.getNewsByUrl(url);
	System.out.println("title:"+news.getTitle());
	System.out.println("content:"+news.getContent());
	}
}

输出结果如下:
webcollector例子输出结果

python获取网页正文:goose-extractor

做项目要用到提取网页的正文内容,于是在网上找找有什么好用的库。先测试一下,发现python就有现成的库,叫做goose-extractor。

事不宜迟,开始安装吧。

pip install goose-extractor

什么?出现问题了。

在安装依赖的lxml的时候,出现了以下的错误提示:

Microsoft\\Visual C++ for Python\\9.0\\VC\\Bin\\amd64\\cl.exe’ failedwith exitstatus 2

找不到好的解决方案,最后祭出大杀器。直接用编译好的。

先打开http://www.lfd.uci.edu/~gohlke/pythonlibs/

ctrl+F搜索lxml,然后下载它对应的whl文件,下载之后pip install xxx.whl即可安装!

安装完这个比较难缠的lxml之后,就方便了,重新pip install goose-extractor

等待安装成功。

使用非常简单,给出一个实例代码,抓取《https://www.lookfor404.com/简易python爬虫–爬取冷笑话/》的正文内容。

# -*- coding: utf-8 -*-
from goose import Goose
from goose.text import StopWordsChinese
url  = 'https://www.lookfor404.com/%e7%ae%80%e6%98%93python%e7%88%ac%e8%99%ab-%e7%88%ac%e5%8f%96%e5%86%b7%e7%ac%91%e8%af%9d/'
g = Goose({'stopwords_class': StopWordsChinese})
article = g.extract(url=url)
print article.cleaned_text

效果不错,截取一下控制台的输出:
goose-extractor提取网页正文结果

但是速度并不快,具体里面怎么实现的还没看,但是它要用到python的结巴分词,估计这个耗时久一点,另外还有一个问题,就是我<code>标签里面的内容,被过滤掉了,所以抓取技术文章,有点不合适,哈哈。

Mysql在linux下的使用以及用java编程

平时管理mysql喜欢用可视化的phpmyadmin,方便易用,简单的事情就不要复杂化。今天在做项目的过程中,发现需要远程连接mysql数据库,虽然说phpmyadmin是可以连接远程的数据库的,但是需要远程的数据库对我这边开启一定的访问权限。

鉴于安全考虑,打消了这个念头。

而想想,自己无非就是想去看看表的结构,select几个字段罢了,那就直接登录直接使用吧,遂把今天的一些操作记录一下吧。

linux下使用mysql

安装就不说了,直接进入主题。

先登录,命令如下:其中,-u后面直接输入用户名,-p后面直接输入密码

mysql -uusername -ppassword

无意外,登录成功。

在这里记录一个坑,那就是登录成功之后,进入mysql的命令行模式,此后输入命令都要以分号;结尾,就和我们日常编程一样,否则输入命令之后,会没有任何错误提示,并且也不会有任何反应。

首先看看有哪些数据库:

show databases;

选择一个数据库,比如我想对数据库名为test的数据库进行操作。

use test;

之后,就是输入各种select语句就行了。最后退出的时候输入命令exit就行。

Java下mysql的使用

首先下载mysql的jdbc驱动,去搜索mysql-connector-java,然后下载。

我搜索到的下载地址:http://dev.mysql.com/downloads/connector/j/

然后新建一个工程,把下载的jar包引进去就行。

随后开始编程,使用很简单,我写了一个简单的example记录一下,操作都大同小异,不过我这里用的不是存储过程,而是基本的sql语句操作。附上代码:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;




public class mysqlExample {
	public static void main(String args[]) {
		try {
			Class.forName("com.mysql.jdbc.Driver"); // 加载MYSQL JDBC驱动程序
			System.out.println("加载驱动成功!");
		} catch (Exception e) {
			System.out.print("加载驱动失败!");
			e.printStackTrace();
		}




		try {
			Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbName", "root", "");
			System.out.println("连接到数据库成功");
			String sql = "select * from `user`;";
			ResultSet rs = getResult(sql,connection);
			//遍历结果,rs是结果游标 
			while(rs.next()) { 
				 /*
				  * getString方法可以传int index,即第几列(1代表结果的第一列..)
				  * 也可以传String columnname,可以直接指定要哪个字段
				  */
				 System.out.println(rs.getString(1));
				 System.out.println(rs.getString("admin"));
				 } 
			 //关闭连接
			connection.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 获取sql查询结果
	 * @param sql sql语句
	 * @param connection 连接
	 * @return 结果集
	 * @throws SQLException
	 */
	public static ResultSet getResult(String sql,Connection connection) throws SQLException{
		Statement stmt = connection.createStatement();
		ResultSet rs = stmt.executeQuery(sql);
		return rs;
	}
}