人生苦短,我用Python
Python很高级,能用最短的时间解决最需要解决的问题
比如,完成同一个任务,C语言要写1000行代码,Java只需要写100行,而Python可能只要20行。 代码少的代价是运行速度慢,C程序运行1秒钟,Java程序可能需要2秒,而Python程序可能就需要10秒。 所以,python适用于对性能不敏感,需要通过自动化来解放劳动力或需要快速开发的场合。 比如自动化日常任务,可以做网站,很多著名的网站包括YouTube,豆瓣等就是Python写的; 甚至很多在线游戏的后台都是Python开发的。总之,应用广泛。
跨平台,无需手动编译,解释型
可访问系统Api及其它语言编写的模块。 系统命令行能做的事情,几乎都可以用python自动化执行。 可以用C++等编写对性能要求高的模块,在python中调用
强大的库
Python标准库很强大,能够帮助你完成许多工作,包括正则表达式、文档生成、单元测试、线程、数据库、网页浏览器、 CGI(公共网关接口)、FTP(文件传输协议)、电子邮件、XML(可扩展标记语言)、XML-RPC(远程方法调用)、 HTML(超文本标记语言)、WAV(音频格式)文件、加密、GUI(图形用户界面)以及其它系统相关的代码。 记住,只要安装了Python,所有这些都能做到。这叫做Python的“遥控器”哲学。 除了标准库,还有丰富的,高质量的第三方库,可以在Python包索引找到它们。
简单专注
基于以上几点,再加上python本身语法简约(像伪代码一样),让我更专注于解决问题本身, 其哲学就是:“优雅”、“明确”、“简单” Python是一门简单而文字简约的语言。阅读好的Python程序感觉就像阅读英语,尽管是非常严格的英语。 在我看来是最适合非职业程序员学习的编程语言。
总之,python的优点就是两句话,简单灵活,要啥有啥。
参考资源:
案例1: 批量修改Excel文件
主要用到的python库:
Turn (almost) any Python command line program into a full GUI application with one line.
from gooey import Gooey @Gooey(program_name='GUI工具') def main(): parse = ArgumentParser(description='GUI工具') parse.add_argument('--verbose', action='store_true', help='...')
参考资源:
A simple, powerful python logging library.
logger = logging.getLogger('Logger Tag') logger.setLevel(logging.DEBUG) # file handler fh = logging.FileHandler('/path/to/logFile') fh.setLevel(logging.WARNING) fh.setFormatter(logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s')) logger.addHandler(fh) # console handler ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) ch.setFormatter(logging.Formatter('%(message)s')) logger.addHandler(ch) # then use: logger.info('info..') # logger.debug('...') balabala
基于xlrd和xlwt的一系列excel操作工具。
关键代码:
# formatting_info=True 用于加载格式信息 workBook = xlrd.open_workbook(filePath, formatting_info=True) # 获取工作表数组 sheet = workBook.sheets()[i] sheet.name # 工作表名称 sheet.ncols # 列数 sheet.nrows # 行数 cell = sheet.cell(row, col) # 获取一个单元格 cell.ctype # 单元格值类型 cell.value # 单元格值 cell.xf_index # 单元格样式索引 # 改变单元格的值 sheet.put_cell(row, col, ctype, value, xf_index) # 保存修改后的表格,xlrd只负责读,所以需要通过xlutils来保存 xlutils.save(workBook, filePath)
参考资源:
手游优化其实是一个找最佳平衡点的问题。要平衡:开发维护工作量、优化深度、性能、画面表现等之间的关系。
主要评估几个方面:
主流优化方法:
案例2: 批量优化压缩PNG文件
PNG:便携式网络图形(Portable Network
Graphics,PNG)是一种无损压缩的位图图形格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。
WikiPedia,说的非常详细。
通过PhotoShop的导出Web图片功能可以非常清晰的理解索引格式的原理。
索引压缩主要涉及的技术:
批量工具主要技术:
def getIHDRInfo(data): ''' get information of png file which is contained in the IHDR chunk data: IHDR chunk Chunk Data return value: information ''' result = struct.unpack('!iiBBBBB', data) # struct # { # int32 width; # int32 height; # uint8 bit_depth; # uint8 color_type; # uint8 compression_method; # uint8 filter_method; # uint8 interlace_method; # } info = {} prop = ['width', 'height', 'bitDepth', 'colorType', 'compressionMethod', 'filterMethod', 'interlaceMethod'] for idx, item in enumerate(prop): info[item] = result[idx] return info def getPNGInfo(filePath): f = open(filePath, 'rb') f.seek(8) f.seek(4 + 4, 1) data = f.read(13) f.close() return getIHDRInfo(data) def isPNGIndexMode(filePath): colorTypeList = [] colorTypeList.append('灰度') colorTypeList.append(' ') colorTypeList.append('真彩') colorTypeList.append('索引') colorTypeList.append('α灰度') colorTypeList.append(' ') colorTypeList.append('α真彩') info = getPNGInfo(filePath) return colorTypeList[info['colorType']] == '索引'
def runShellCommand(command): p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = p.communicate() return (p.returncode, output, error)
if sys.platform == 'darwin': (ramDiskStatus, output, error) = runShellCommand( 'diskutil erasevolume HFS+ TempRAMDisk `hdiutil attach -nomount ram://' + str(2 * 1024 * 64) + '`') # 64M else: (ramDiskStatus, output, error) = (-1, '', '')
优点:占用空间小,能达到20%~30%的高压缩比。
不足:主要是颜色数量不足导致的,如渐变及半透明的过渡问题(比如光效等)
常用优化工具:
想法的来源嘛,主要为了解决换肤类型的问题。
动态合图能解决的问题:
主要技术点:
二维装箱问题目前仍没有最优解解决方案,而且对最优解的趋近和速度成反比。目前MaxRects应该是最好的算法了。
UnityWiki上面有Unity官方的代码。
关于MaxRects算法,TexturePacker的官方说明是:
* Best-known algorithm for packing textures * Is fast and has a high packing ratio * Enable rotation and trimming for best results (depending on your target framework)
GUI/CMD value | Description |
---|---|
Best |
Tests all available placements and uses the result with the least used space |
ShortSideFit |
Short Side Fit |
LongSideFit |
Long Side Fit |
AreaFit |
Area Fit |
BottomLeft |
Bottom Left |
ContactPoint |
Contact Point |
Texture2D::updateWithData(const void *data,int offsetX,int offsetY,int width,int height)
但有一点麻烦的地方,此方法使用的glTexSubImage2D
要求图像宽度必须是2的倍数。
static SpriteFrame* createWithTexture(Texture2D* pobTexture, const Rect& rect, bool rotated, const Vec2& offset, const Size& originalSize); SpriteFrameCache::getInstance()->removeSpriteFrameByName(imageName); SpriteFrameCache::getInstance()->addSpriteFrame(spriteFrame, imageName);
需求来源:曾经有个项目,画风独特,使用了漂亮的字体,还需要支持14国语言。经过漫长的选择最终确定用Google思源字体作为游戏基本字库(字符全并且无版权问题)。但字体体积非常大,超过10M。游戏里面集成一个这样的字体就够大了,更何况还想多集成几个好看的字体。于是想到对字体进行精简,去掉游戏里面没有用到的字符。由于这个游戏所用到的字符相对固定(也就是说没有用户可以随便输入文字的地方),所以精简下来的字体文件应该非常小。
网上找到的工具和解决方案:
参考阅读:
通过SSH连接,通过SFTP传输文件,不需要额外的配置,简单实用,效率高。安全性能很好。速度快,比samba强,无需配置,映射任何目录
文件系统基于FUSE,mac需要先安装osxfuse
FUSE:用户空间文件系统(Filesystem in Userspace,簡稱FUSE)是一个面向类Unix计算机操作系统的软件接口,它使无特权的用户能够无需编辑内核代码而创建自己的文件系统。目前Linux通过内核模块对此进行支持。
sshfs [user@]host:[dir] mountpoint [options]
然后就可以像操作本地文件一样操作远程目录啦!
参考阅读:
利用SSH反向隧道穿透NAT,实现内网穿透。核心技术是端口转发,它能够将其他TCP端口的网络数据通过SSH链接来转发,并且自动提供了相应的加密及解密服务。这一过程有时也被叫做“隧道”(tunneling)。总的来说SSH端口转发能够提供两大功能:
机器代号 | 机器位置 | 地址 | 账户 | ssh/sshd 端口 | 是否需要运行sshd |
---|---|---|---|---|---|
A | 位于公网 | xx.xx.xx.xx | usera | 22 | 是 |
B | 位于NAT之后 | 127.0.0.1 | userb | 22 | 是 |
C | 位于NAT之后 | 127.0.0.1 | userc | 22 | 否 |
目标:在C上通过SSH连接B
在B机器上执行:
ssh -p <B ssh port> -qngfNTR <A port for B>:127.0.0.1:<B ssh port> <A user>@<A IP>
连接自己的SSH端口,转发到远程端口并绑定。
在A机器上执行:
ssh -p <A port for B> <B user>@127.0.0.1
如果要用C机器连接B,需要先在A机器上将/etc/ssh/sshd_config文件中的GatewayPorts设置为yes,然后到C机器执行:
ssh -p <A port for B> <B user>@<A IP>
参考阅读: