课程全名:An Introduction to Interactive Programming in Python,来自 Rice University

授课教授:Joe Warren, Scott Rixner, John Greiner, Stephen Wong

工具:http://www.codeskulptor.org/, simplegui 模块

最后一个project,继续完善上一周的工程,做完就是一个既简单又棒棒的打陨石(飞机)游戏。

第八周:

关于Python的知识,set类型的用法

定义:set和C++中的STL中的set类似,用来维护一组不重复的无序元素。

# 定义一个空的set
set_empty = set() # or set([])
print set_empty
# set([]) # 定义set
set_a = set([1, 2, 3])
set_b = set((1, 2, 3))
set_c = set({1:1, 2:1, 3:1})
set_d = set("abcd")
set_e = set(["a", "b", "cd"])
print set_a, set_b, set_c
print set_d, set_e
# set([1, 2, 3]) set([1, 2, 3]) set([1, 2, 3])
# set(['a', 'b', 'c', 'd']) set(['a', 'b', 'cd']) # set的交、并、差运算、对称差集
# 这些操作返回一个新的集合,set_a,set_b不发生改变
set_a = set([1, 2, 3])
set_b = set([2, 3, 4])
print set_a.intersection(set_b)
# set([2, 3])
print set_a.union(set_b)
# set([1, 2, 3, 4])
print set_a.difference(set_b)
# set([1])
print set_a.symmetric_difference(set_b)
# set([1, 4]) # 这些对应操作没有返回值,并且直接改变set_a,set_b不变化
set_a.intersection_update(set_b)
set_a.update(set_b) # 添加多个元素,就是union含义
set_a.difference_update(set_b)
set_a.symmetric_difference_update(set_b) # set 其他的操作符
s = set([1, 2, 3, 4])
s.add(5) # 添加单个元素
s.add(4) # 重复元素没有效果
s.remove(4) # 移除集合中的元素,如果元素不存在会报错
s.discard(8) # 也是移除集合中的元素,但是对于不存在元素不影响
s.pop() # 弹出集合中的任意一个元素,如果集合为空执行该操作报错 set([2, 9, 7, 1].issubset(set([1, 7])) # 判断是否是子集,返回True或者False
set([2, 9, 7, 1]).issuperset(set([1, 7])) # 判断是否是父集,返回True或者False

set因为是无序集合,所以不支持index索引和slice([ ])切片的操作,可以用element in set来判断集合是否存在该元素。或者for 循环用iterable遍历。

set和list是可变类型,下面的a和b都是指向同一个空间位置。

a = set([1, 2, 3])
b = a
print a
# set([1, 2, 3])
b.add(4)
print a
# set([1, 2, 3, 4])

Python知识介绍完,上游戏图

回顾上周,完成了一个飞船,一个陨石,一个子弹。

基本的绘制、更新以及大部分的方法都已经实现,这一周主要是实现多个陨石以及子弹的连续发射,还有加上飞船三者之间碰撞的关系处理。

对于游戏来说,掌握关键的一帧,核心就在draw的绘制中:

· 更新时间,绘制背景元素

· 绘制和更新my_ship

· 如果游戏开始

· 绘制更新rock_group

· 绘制更新missile_group

· 绘制更新explosion_group

· 如果 rock_group和my_ship碰撞,lives –= 1

· 如果 lives<=0,init_game()

· score 加上发生rock_group与missile_group碰撞的数量(biu~~~~)

· 游戏没开始就换个splah提示

· 绘制lives text

· 绘制score text

# draw handler
def draw(canvas):
global time, lives, rock_group, missile_group, my_ship, score, started # animiate background
time += 1
wtime = (time / 4) % WIDTH
center = debris_info.get_center()
size = debris_info.get_size()
canvas.draw_image(nebula_image, nebula_info.get_center(), nebula_info.get_size(), [WIDTH / 2, HEIGHT / 2], [WIDTH, HEIGHT])
canvas.draw_image(debris_image, center, size, (wtime - WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT))
canvas.draw_image(debris_image, center, size, (wtime + WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT)) # draw and update ship
my_ship.draw(canvas)
my_ship.update() if started: # draw and update rock_group
process_sprite_group(rock_group, canvas) # draw and update missile_group
process_sprite_group(missile_group, canvas) # draw and update explosioin_group
process_sprite_group(explosion_group, canvas) # ship - rock_group collide and update the lives
if group_collide(rock_group, my_ship):
lives -= 1
# game over
if lives <= 0:
init_game()
message_label.set_text('Click to start!')
# update score
score += group_group_collide(rock_group, missile_group) * 10 else:
canvas.draw_image(splash_image, splash_info.get_center(), splash_info.get_size(), (WIDTH / 2, HEIGHT / 2), splash_info.get_size()) # draw lives
canvas.draw_text("Lives", [WIDTH / 12, HEIGHT / 12], 30, "White")
canvas.draw_text(str(lives), [WIDTH / 12, HEIGHT / 12 + 40], 30, "White") # draw score
canvas.draw_text("Score", [10 * WIDTH / 12, HEIGHT/12], 30, "White")
canvas.draw_text(str(score), [10 * WIDTH /12, HEIGHT/12 + 40], 30, "White")

my_ship的绘制更新上周已经完成,上周主要处理一个陨石和子弹的情形,这周完成多个,奥秘就在process_sprite_group()中。

def process_sprite_group(sprite_group, canvas):
remove_set = set([])
for sprite in sprite_group:
sprite.draw(canvas)
if sprite.update():
remove_set.add(sprite)
sprite_group.difference_update(remove_set)

process_sprite_group完成对group中每一个对象的绘制和更新,sprite.update()的if判断主要是针对子弹,子弹发生是存在距离,这个距离通过age时间来衡量,当sprite.lifespan超过了age,那么update就返回True,我们就要把这些过了保质期的子弹从他的group中移走,而默认rock陨石的lifespan保质期是inf,永不过期,除非被飞机打掉了。这样通过process_sprite_group就可以维护rock_group,missile_group,explosion_group.

那么接下来重要的问题来了?挖掘机….处理元素之间的碰撞关系。这里碰撞主要存在两种,飞机与陨石之间碰撞,陨石和子弹之间碰撞。

def group_collide(group, other_object):
is_collide = False
remove_set = set([])
for obj in group:
if obj.collide(other_object):
is_collide = True
remove_set.add(obj)
# create new explosion
pos = [other_object.pos[0], other_object.pos[1]]
new_explosion = Sprite(pos, [0, 0], other_object.angle, 0, explosion_image, explosion_info, explosion_sound)
explosion_group.add(new_explosion) group.difference_update(remove_set)
return is_collide def group_group_collide(group, other_group):
num_collide = 0
for obj in list(group):
if group_collide(other_group, obj):
group.discard(obj)
num_collide += 1
return num_collide

通过上面两个Help Function,第一个可以用来检测rock_group和my_ship,需要实现一个sprite的collide方法,用距离和半径和的关系判断是否碰撞,然后再group_collide函数中只要遍历rock_group,调用collide方法判断是否和my_ship相撞。相撞的元素从group中移走,为了实现explosion的效果,在这里向explosion_group添加以other_project坐标属性的新元素。

第二个,主要用来监测rock_group和missile_group的碰撞关系,遍历rock_group然后在调用group_collide方法,判断单个元素和group之间碰撞(复用大法好)。

碰撞检测后,记得更新score 和 lives的值。

游戏的核心也就差不多了。剩下的就没什么了。started变量控制一下游戏开始状态,基本的Tile的图像绘制,加个偏移就好。再有就是一些加速的参数需要自己手工调整,关乎你游戏的可玩性。忘记一点,随机生成rock的时候,加一个判断当坐标离自己飞船在一定范围之外,才能生成,不然莫宁奇妙的躺枪。

一个陨石10分,无聊的加了个button,500分换一条命。

下面就贴完整代码:

# program template for Spaceship
import simplegui
import math
import random # globals for user interface
WIDTH = 800
HEIGHT = 600
score = 0
lives = 3
time = 0.5 class ImageInfo:
def __init__(self, center, size, radius = 0, lifespan = None, animated = False):
self.center = center
self.size = size
self.radius = radius
if lifespan:
self.lifespan = lifespan
else:
self.lifespan = float('inf')
self.animated = animated def get_center(self):
return self.center def get_size(self):
return self.size def get_radius(self):
return self.radius def get_lifespan(self):
return self.lifespan def get_animated(self):
return self.animated # art assets created by Kim Lathrop, may be freely re-used in non-commercial projects, please credit Kim # debris images - debris1_brown.png, debris2_brown.png, debris3_brown.png, debris4_brown.png
# debris1_blue.png, debris2_blue.png, debris3_blue.png, debris4_blue.png, debris_blend.png
debris_info = ImageInfo([320, 240], [640, 480])
debris_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/debris2_blue.png") # nebula images - nebula_brown.png, nebula_blue.png
nebula_info = ImageInfo([400, 300], [800, 600])
nebula_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/nebula_blue.f2014.png") # splash image
splash_info = ImageInfo([200, 150], [400, 300])
splash_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/splash.png") # ship image
ship_info = ImageInfo([45, 45], [90, 90], 35)
ship_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png") # missile image - shot1.png, shot2.png, shot3.png
missile_info = ImageInfo([5,5], [10, 10], 3, 50)
missile_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot2.png") # asteroid images - asteroid_blue.png, asteroid_brown.png, asteroid_blend.png
asteroid_info = ImageInfo([45, 45], [90, 90], 40)
asteroid_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blue.png") # animated explosion - explosion_orange.png, explosion_blue.png, explosion_blue2.png, explosion_alpha.png
explosion_info = ImageInfo([64, 64], [128, 128], 17, 24, True)
explosion_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha.png") # sound assets purchased from sounddogs.com, please do not redistribute
soundtrack = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/soundtrack.mp3")
missile_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/missile.mp3")
missile_sound.set_volume(.5)
ship_thrust_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/thrust.mp3")
explosion_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.mp3") # helper functions to handle transformations
def angle_to_vector(ang):
return [math.cos(ang), math.sin(ang)] def dist(p,q):
return math.sqrt((p[0] - q[0]) ** 2+(p[1] - q[1]) ** 2) # Ship class
class Ship:
def __init__(self, pos, vel, angle, image, info):
self.pos = [pos[0],pos[1]]
self.vel = [vel[0],vel[1]]
self.thrust = False
self.angle = angle
self.angle_vel = 0
self.image = image
self.image_center = info.get_center()
self.image_size = info.get_size()
self.radius = info.get_radius() def draw(self,canvas):
if self.thrust:
center = (self.image_center[0]+self.image_size[0], self.image_center[1])
canvas.draw_image(self.image, center, self.image_size, self.pos, self.image_size, self.angle)
else:
canvas.draw_image(self.image, self.image_center, self.image_size, self.pos, self.image_size, self.angle) def update(self):
self.angle += self.angle_vel
self.pos[0] = (self.pos[0] + self.vel[0]) % WIDTH
self.pos[1] = (self.pos[1] + self.vel[1]) % HEIGHT
c = 0.05
self.vel[0] *= (1 - c)
self.vel[1] *= (1 - c)
forward = angle_to_vector(self.angle)
if self.thrust:
self.vel[0] += forward[0] * 0.8
self.vel[1] += forward[1] * 0.8 def change_angle_vel(self, ori, key_state):
if ((ori == "right" and key_state == "keyup") or
(ori == "left" and key_state == "keydown")):
self.angle_vel -= 0.1
elif ((ori == "right" and key_state == "keydown") or
(ori == "left" and key_state == "keyup")):
self.angle_vel += 0.1 def set_thruster(self, thruster_state):
self.thrust = thruster_state
if self.thrust:
ship_thrust_sound.rewind()
ship_thrust_sound.play()
else:
ship_thrust_sound.rewind() def shoot(self):
global missile_group
offset = self.image_size[0] / 2.0
forward = angle_to_vector(self.angle)
pos = [self.pos[0] + offset * forward[0], self.pos[1] + offset * forward[1]]
vel = [self.vel[0] + 6 * forward[0], self.vel[1] + 6 * forward[1]]
ang = 0
ang_vel = 0
missile_group.add(Sprite(pos, vel, ang, ang_vel, missile_image, missile_info, missile_sound)) def get_position(self):
return self.pos def get_radius(self):
return self.radius # Sprite class
class Sprite:
def __init__(self, pos, vel, ang, ang_vel, image, info, sound = None):
self.pos = [pos[0],pos[1]]
self.vel = [vel[0],vel[1]]
self.angle = ang
self.angle_vel = ang_vel
self.image = image
self.image_center = info.get_center()
self.image_size = info.get_size()
self.radius = info.get_radius()
self.lifespan = info.get_lifespan()
self.animated = info.get_animated()
self.age = 0
if sound:
sound.rewind()
sound.play() def draw(self, canvas):
if self.animated:
center = (self.image_center[0] + self.age * self.image_size[0], self.image_center[1])
canvas.draw_image(self.image, center, self.image_size, self.pos, self.image_size, self.angle)
else:
canvas.draw_image(self.image, self.image_center, self.image_size, self.pos, self.image_size, self.angle) def update(self):
if started:
self.angle += self.angle_vel
self.pos[0] = (self.pos[0] + self.vel[0]) % WIDTH
self.pos[1] = (self.pos[1] + self.vel[1]) % HEIGHT self.age += 1
if self.age >= self.lifespan:
return True
else:
return False def get_position(self):
return self.pos def get_radius(self):
return self.radius def collide(self, other_object):
dis = self.get_radius() + other_object.get_radius()
if dis > dist(self.get_position(), other_object.get_position()):
return True
else:
return False # Help Function to deal collision
def group_collide(group, other_object):
is_collide = False
remove_set = set([])
for obj in group:
if obj.collide(other_object):
is_collide = True
remove_set.add(obj)
# create new explosion
pos = [other_object.pos[0], other_object.pos[1]]
new_explosion = Sprite(pos, [0, 0], other_object.angle, 0, explosion_image, explosion_info, explosion_sound)
explosion_group.add(new_explosion) group.difference_update(remove_set)
return is_collide def group_group_collide(group, other_group):
num_collide = 0
for obj in list(group):
if group_collide(other_group, obj):
group.discard(obj)
num_collide += 1
return num_collide def process_sprite_group(sprite_group, canvas):
remove_set = set([])
for sprite in sprite_group:
sprite.draw(canvas)
if sprite.update():
remove_set.add(sprite)
sprite_group.difference_update(remove_set) # draw handler
def draw(canvas):
global time, lives, rock_group, missile_group, my_ship, score, started # animiate background
time += 1
wtime = (time / 4) % WIDTH
center = debris_info.get_center()
size = debris_info.get_size()
canvas.draw_image(nebula_image, nebula_info.get_center(), nebula_info.get_size(), [WIDTH / 2, HEIGHT / 2], [WIDTH, HEIGHT])
canvas.draw_image(debris_image, center, size, (wtime - WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT))
canvas.draw_image(debris_image, center, size, (wtime + WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT)) # draw and update ship
my_ship.draw(canvas)
my_ship.update() if started: # draw and update rock_group
process_sprite_group(rock_group, canvas) # draw and update missile_group
process_sprite_group(missile_group, canvas) # draw and update explosioin_group
process_sprite_group(explosion_group, canvas) # ship - rock_group collide and update the lives
if group_collide(rock_group, my_ship):
lives -= 1
# game over
if lives <= 0:
init_game()
message_label.set_text('Click to start!')
# update score
score += group_group_collide(rock_group, missile_group) * 10 else:
canvas.draw_image(splash_image, splash_info.get_center(), splash_info.get_size(), (WIDTH / 2, HEIGHT / 2), splash_info.get_size()) # draw lives
canvas.draw_text("Lives", [WIDTH / 12, HEIGHT / 12], 30, "White")
canvas.draw_text(str(lives), [WIDTH / 12, HEIGHT / 12 + 40], 30, "White") # draw score
canvas.draw_text("Score", [10 * WIDTH / 12, HEIGHT/12], 30, "White")
canvas.draw_text(str(score), [10 * WIDTH /12, HEIGHT/12 + 40], 30, "White") # timer handler that spawns a rock
def rock_spawner():
global rock_group
if started and len(rock_group) < 12:
pos = [random.randint(0, WIDTH-1), random.randint(0, HEIGHT-1)]
# dist great than 20 can spawn a new rock
if dist(pos, my_ship.get_position()) > 150:
vel = [random.randrange(1, 3, 1)*random.choice([1, -1]), random.randrange(1, 3, 1)*random.choice([1, -1])]
ang = 0
ang_vel = random.randrange(5, 10, 1) / 100.0 * random.choice([1, -1])
new_rock = Sprite(pos, vel, ang, ang_vel, asteroid_image, asteroid_info)
rock_group.add(new_rock) # key_up handler
def key_up(key):
if started:
if simplegui.KEY_MAP['left'] == key:
my_ship.change_angle_vel("left", "keyup")
elif simplegui.KEY_MAP['right'] == key:
my_ship.change_angle_vel("right", "keyup")
elif simplegui.KEY_MAP['up'] == key:
my_ship.set_thruster(False) # key_down handler
def key_down(key):
if started:
if simplegui.KEY_MAP['left'] == key:
my_ship.change_angle_vel("left", "keydown")
elif simplegui.KEY_MAP['right'] == key:
my_ship.change_angle_vel("right", "keydown")
elif simplegui.KEY_MAP['up'] == key:
my_ship.set_thruster(True)
elif simplegui.KEY_MAP['space'] == key:
my_ship.shoot() # mouse_click handler
def mouse_click(position):
global started
if position[0] < WIDTH and position[1] < HEIGHT and not started :
started = True
soundtrack.rewind()
soundtrack.play()
message_label.set_text('Welcome, enjoy!') # puchase button handler:
def purchase_button():
global score, lives, message_label
if started:
if score >= 500:
score -= 500
lives += 1
message_label.set_text("Purchase successfully.")
else:
message_label.set_text("Scores are not enough.")
else:
message_label.set_text("Game hasn't started yet.") # exit game button
def exit_button():
soundtrack.rewind()
ship_thrust_sound.rewind()
missile_sound.rewind()
explosion_sound.rewind()
frame.stop() # init the game state
def init_game():
global my_ship, rock_group, missile_group, explosion_group, started, score, lives
# initialize ship and two sprites
my_ship = Ship([WIDTH / 2, HEIGHT / 3], [0, 0], 1.5*math.pi, ship_image, ship_info)
rock_group = set([])
missile_group = set([])
explosion_group = set([])
score, lives = 0, 3
started = False
soundtrack.rewind()
ship_thrust_sound.rewind()
missile_sound.rewind()
explosion_sound.rewind() # initialize frame
frame = simplegui.create_frame("Asteroids", WIDTH, HEIGHT) # init the game
init_game() # register handlers
frame.set_draw_handler(draw)
frame.set_keydown_handler(key_down)
frame.set_keyup_handler(key_up)
frame.set_mouseclick_handler(mouse_click)
frame.add_button('500 Scores for a life', purchase_button, 200)
frame.add_button('Quit', exit_button, 200)
message_label = frame.add_label('Click to start!')
author_label = frame.add_label('Tiny656')
contact_label = frame.add_label('236798656@qq.com')
timer = simplegui.create_timer(1000.0, rock_spawner) # get things rolling
timer.start()
frame.start()

坐等最后的Peer Evaluation,这么课应该就结束了,感谢Rice大学这些兢兢业业对于教学富有激情和创意的老师,能让我有幸聆听到这么有意思的课程,收获满满,感谢Coursera这么棒棒的平台,拉近了每个人与知识的距离,对于充满好奇心的我,一比无价的财富。现在的环境是,永远不缺知识以及还有这么多优秀的知识分享者,缺少一颗渴望学习的心,不管做什么,耐心和毅力总能感觉到自己不断成长的步伐,学习的道路上,永远不应该放下脚步,引用Jobs的话,stay hungry, stay foolish, 求知若饥求知若愚。

接下来开始认真跟Princeton的算法II,妈蛋的,第二周都放出来了,第一周的视频还一点没看,得抓紧。还有老板的活要干,还有英语要复习,真是分神乏力。咬咬牙,坚持下来。12月开始刷题复习,明年找工作。

Mini projects #8–RiceRocks的更多相关文章

  1. Mini projects #7 ---- Spaceship

    课程全名:An Introduction to Interactive Programming in Python,来自 Rice University 授课教授:Joe Warren, Scott ...

  2. Mini projects #6 ---- Blackjack

    课程全名:An Introduction to Interactive Programming in Python,来自 Rice University 授课教授:Joe Warren, Scott ...

  3. Mini projects #3 ---- Stopwatch: The Game

    课程全名:An Introduction to Interactive Programming in Python,来自 Rice University 授课教授:Joe Warren, Scott ...

  4. Mini projects #5 ---- Memory

    课程全名:An Introduction to Interactive Programming in Python,来自 Rice University 授课教授:Joe Warren, Scott ...

  5. Mini projects #4 ---- Pong

    课程全名:An Introduction to Interactive Programming in Python,来自 Rice University 授课教授:Joe Warren, Scott ...

  6. A Complete List of .NET Open Source Developer Projects

    http://scottge.net/2015/07/08/a-complete-list-of-net-open-source-developer-projects/?utm_source=tuic ...

  7. Building Xcode iOS projects and creating *.ipa file from the command line

    For our development process of iOS applications, we are using Jenkins set up on the Mac Mini Server, ...

  8. All the Apache Streaming Projects: An Exploratory Guide

    The speed at which data is generated, consumed, processed, and analyzed is increasing at an unbeliev ...

  9. Golang优秀开源项目汇总, 10大流行Go语言开源项目, golang 开源项目全集(golang/go/wiki/Projects), GitHub上优秀的Go开源项目

    Golang优秀开源项目汇总(持续更新...)我把这个汇总放在github上了, 后面更新也会在github上更新. https://github.com/hackstoic/golang-open- ...

随机推荐

  1. 【python】函数之内置函数

    Python基础 内置函数 今天来介绍一下Python解释器包含的一系列的内置函数,下面表格按字母顺序列出了内置函数: 下面就一一介绍一下内置函数的用法: 1.abs() 返回一个数值的绝对值,可以是 ...

  2. tcp/ip http socket笔记

    1.TCP/IP协议是传输层协议,主要解决数据如何在网络中传输 HTTP是应用层协议,主要解决如何包装数据 2.TCP连接的三次握手 第一次握手:客户端发送syn包到服务器,并进入SYN_SEND状态 ...

  3. CSS3 结构伪类选择器 详解

    1 CSS3 结构伪类选择器 1.E:root 匹配E元素所在的根元素 即:html 2. E:nth-child(n) (1)匹配E元素的父元素中第n个子元素,(2)且该位置的子元素类型必须是E类型 ...

  4. Spring+quartz 实现定时任务job集群配置

    为什么要有集群定时任务? 因为如果多server都触发相同任务,又同时执行,那在99%的场景都是不适合的.比如银行每晚24:00都要汇总营业额.像下面3台server同时进行汇总,最终计算结果可能是真 ...

  5. C语言调用curl库抓取网页图片(转)

    思路是先用curl抓取网页源码,然后以关键字寻找出图片网址.  范例: #include <stdio.h> #include <stdlib.h> #include < ...

  6. iOS网络请求之multipart/form-data提交数据

    multipart/form-data表单数据 在http网络请求中,post没有请求长度的限制,因为post把数据放在了body中,而不是像Get一样放在了浏览器的地址栏中(可以这么理解), 所以相 ...

  7. Python SQLAlchemy --1

    本文為 Python SQLAlchemy ORM 一系列教學文: SQLAlchemy 大概是目前 Python 最完整的資料庫操作的套件了,不過最令人垢病的是它的文件真的很難閱讀,如果不搭配個實例 ...

  8. flash中htmlText样式

    赋值htmlText时,htmlText中指定了样式的按指定样式显示,没有指定的按该文本的默认样式显示. PS:flash软件拖出来的文本,在赋值htmlText的时候该文本原有样式会失效,而new出 ...

  9. Maven 命令速记

    1. 创建项目 1) 创建父目录 mvn archetype:generate -DgroupId=com.qunar.training -DartifactId=training -Dversion ...

  10. HibernateTemplate的一些常用方法总结

    1:get/load存取单条数据 public Teacher getTeacherById(Long id) { return (Teacher)this.hibernateTemplate.get ...