怎么才能高效地将长话单拆分成按小时分解的多条短话单?

怎么才能高效地将长话单拆分成按小时分解的多条短话单?

原始话单是这样的:

USERID STARTTIME ENDTIME SERVICETYPE CHANNELCODE PROGRAMNAME
xxxxxxxxxxxxxxxxx1 2021-05-24 19:52:28 2021-05-24 23:56:27 1 精灵宝可梦

老板让分析每个用户各个时段都在看啥,所以我想吧话单拆分成这样:

USERID STARTTIME ENDTIME SERVICETYPE CHANNELCODE PROGRAMNAME PERIODTIME
xxxxxxxxxxxxxxxxx1 2021-05-24 19:52:28 2021-05-24 20:00:00 1 精灵宝可梦 2021-05-24 19:00:00
xxxxxxxxxxxxxxxxx1 2021-05-24 20:00:00 2021-05-24 21:00:00 1 精灵宝可梦 2021-05-24 20:00:00
xxxxxxxxxxxxxxxxx1 2021-05-24 21:00:00 2021-05-24 22:00:00 1 精灵宝可梦 2021-05-24 21:00:00
xxxxxxxxxxxxxxxxx1 2021-05-24 22:00:00 2021-05-24 23:00:00 1 精灵宝可梦 2021-05-24 22:00:00
xxxxxxxxxxxxxxxxx1 2021-05-24 23:00:00 2021-05-24 23:56:27 1 精灵宝可梦 2021-05-24 23:00:00

目前的方法是根据起止时间生成时间序列,然后 for 循环生成新的行,再拼接成一个新的 dataframe

# split_data
...
for i in range(0, len_date-1):
    df_y['Period'] = date_rng[i]
    df_y['EndTime'] = date_rng[i+1]
    df_y['StartHour'] = date_rng[i]
    df_y['EndHour'] = date_rng[i+1]
    df_x = df_x.append(df_y)
...

主函数还要写个 for 循环遍历整个话单

for i in range(len(df_tmp)):
    df_x = split_data(df_tmp.iloc[i])
    df_t = df_t.append(df_x)
df_t

这样能获得想要的结果,但话单太多了,跑起来没完没了……

有没有更好的方法能提高下效率?

pyecharts 诡异问题求解,同一个图表在不同模板中渲染出来数值相反?

pyecharts 诡异问题求解,同一个图表在不同模板中渲染出来数值相反?

我做了一个记账小工具,按月把支出情况以折线图表示,但同一个图表在不同模板中渲染出来数值相反,一时间给我整懵了,不知道问题出在哪,恳请大家帮看看

在 html 模板 A 中渲染结果是这样的
A
但在 html 模板 B 中渲染结果确是这样的…?!
B

折线图生成函数如下

def make_echart():
    line = Line(init_opts=opts.InitOpts(
        height="400px", width="100%"
    ))
    dates = list(set([
        x.ctime.strftime("%Y-%m")
        for x in Log.query.filter_by(type_name="支出").all()
        ]))
    dates.sort()
    outlay = []
    for d in dates:
        y,m = d.split("-")
        outlay.append(round(
            Log.query.with_entities(func.sum(Log.money)).filter(
                extract('year', Log.ctime) == y,
                extract('month', Log.ctime) == m,
                Log.type_name == '支出',
                Log.kind_name != '房贷'
            ).first()[0], 2)
        )
    line.add_xaxis(xaxis_data=dates)
    line.add_yaxis(
        series_name="支出",
        y_axis=outlay,
        markline_opts=opts.MarkLineOpts(
            data=[opts.MarkLineItem(type_="average", name="平均支出")]
        )
    )
    return line.render_embed()

折线图都是用同样的模板语法传进去的

<div class="echart">{{echart|safe}}</div>

我也在 flask shell 里面运行了图表生成函数,返回的代码里面数值是正值的,但不知道为什么到页面上就变成负值了

iOS网络编程————POST请求和GET请求

iOS网络编程内容很多,也很重要,小编慢慢总结,慢慢来讲。

iOS的网络编程主要涉及两者:客户端和服务器端,上传和下载数据都是客户端通过访问服务器端来实现的。

服务器端开发语言有Java,.Net,C/C++,PHP,Ruby,Python等,而手机客户端的开发语言有OC,Java等与后端开发语言不同,因此要实现服务器端与客户端的数据传输必然要有约定一种数据传输的格式和传输协议,否则二者不能进行交流。这个格式可以为JSON,XML等,传输协议我们熟知的有http(超文本传输协议),它是一个通信规则,注意:这个协议永远都是客户端发起请求,服务器端回送响应。

HTTP请求包:客户端发送一个HTTP请求,是向服务器提交了一个HTTP请求包。

请求包的结构:请求头和请求体。

请求体的数据格式:JSON、XML、符号拼接,客户端向服务器提交的数据都放在请求体中或者后面的URL中。

HTTP请求包包括GET请求和POST请求:

GET请求是客户端向服务器索取数据的一种请求方式,(只包含请求头)。

POST请求是客户端向服务器提交数据的方式,(包含请求头和请求体)。

HTTP响应包:服务器收到请求之后向客户端回应了一个HTTP响应包。

响应包结构:响应头和响应体。

服务器通过响应体将数据传给客户端,数据格式有JSON、XML。

同步请求:数据的请求过程在主线程执行的,网络数据传输的过程会导致主线程堵塞。

异步请求:数据的请求过程在多线程执行的,保持主线程的流畅性,UI界面的渲染与刷新在主线程中,主线程不流畅会导致UI界面卡顿。

下面来点干货

网络组件:NSURLSession可以实现上传,下载,处理认证等工具,能处理http协议中的所用事情。

NSURLSession由NSURLSessionConfiguration和可选代理(optional delegate)构成。再根据你的网络需求通过NSURLSessionTask来创建session。

GET请求:

<span style=”font-size:14px;”>#import “ViewController.h”

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextView *textView;

@end

@implementation ViewController

– (void)viewDidLoad {
[super viewDidLoad];

}

– (IBAction)GET:(id)sender {

/*
使用NSURLSession 进行网络请求的几个步骤
1.构造NSURL地址
2.构造请求对象 NSURLRequest
3.构造NSURLSessionConfiguration配置文件,可选
4.构造NSURLSession网络会话对象
5.创建网络任务
6.执行网络任务,发送网络请求
*/

//1
NSURL *url = [NSURL URLWithString:@”http://piao.163.com/m/cinema/list.html?app_id=1&mobileType=iPhone&ver=2.6&channel=appstore&deviceId=9E89CB6D-A62F-438C-8010-19278D46A8A6&apiVer=6&city=110000″];

//2 使用URL 创建一个可变的请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

//设置请求对象
//请求方式
request.HTTPMethod = @”GET”;

//超时时间
request.timeoutInterval = 60;

//设置请求头中的参数
// [request setValue:@”1533″ forHTTPHeaderField:@”cinema_id”];

//3 创建会话对象 默认的会话
NSURLSession *session = [NSURLSession sharedSession];

//4 创建网络任务
//NSURLSessionTask 抽象类 使用其子类 dataTask,uploadTask,downloadTask
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

//判断错误
if (error) {
NSLog(@”请求出错:%@”, error);

return;
}

NSError *jsonError = nil;

//Json解析
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError];
NSString *jsonText = [NSString stringWithFormat:@”%@”, dic];

//回到主线程 来刷新文字
[_textView performSelectorOnMainThread:@selector(setText:) withObject:jsonText waitUntilDone:NO];

}];

//5 开启任务
[dataTask resume];

}</span>

POST请求:
<span style=”font-size:14px;”>#import “ViewController.h”

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextView *textView;

@end

@implementation ViewController

– (void)viewDidLoad {
[super viewDidLoad];

}
– (IBAction)POST:(id)sender {

/*
使用NSURLSession 进行网络请求的几个步骤
1.构造NSURL地址
2.构造请求对象 NSURLRequest
3.构造NSURLSessionConfiguration配置文件,可选
4.构造NSURLSession网络会话对象
5.创建网络任务
6.执行网络任务,发送网络请求
*/

NSURL *url = [NSURL URLWithString:@”http://piao.163.com/m/cinema/schedule.html?app_id=1&mobileType=iPhone&ver=2.6&channel=appstore&deviceId=9E89CB6D-A62F-438C-8010-19278D46A8A6&apiVer=6&city=110000″];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

//设置POST请求
request.HTTPMethod = @”POST”;
request.timeoutInterval = 60;
//设置请求体
//cinema_id=1533
NSData *bodyData = [@”cinema_id=1533″ dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPBody = bodyData;

NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSString *jsonString = [NSString stringWithFormat:@”%@”, dic];

[_textView performSelectorOnMainThread:@selector(setText:) withObject:jsonString waitUntilDone:NO];

//获取响应包
//将response 转化为一个子类的HTTPURLResponse
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
//打印状态码
NSLog(@”状态码:%li”, httpResponse.statusCode);
//获取响应头
NSDictionary *responseHeader = httpResponse.allHeaderFields;
NSLog(@”响应头:%@”, responseHeader);

}];

//开始网络任务
[dataTask resume];

}</span>

NSURLSessionConfiguration配置网络会话
<span style=”font-size:14px;”>
@implementation ViewController

– (void)viewDidLoad {
[super viewDidLoad];

//使用NSURLSessionConfiguration 来配置网络会话
/*
1 构造URL地址
2 创建Request对象(可选)
3 构建 NSURLSessionConfiguration 对象
4 通过配置 来构建网络会话
5 创建网络任务
6 开启任务

*/

_data = [NSMutableData data];

//URL
NSURL *url = [NSURL URLWithString:@”http://piao.163.com/m/cinema/list.html?app_id=1&mobileType=iPhone&ver=2.6&channel=appstore&deviceId=9E89CB6D-A62F-438C-8010-19278D46A8A6&apiVer=6&city=110000″];
//NSURLSessionConfiguration
/*
defaultSessionConfiguration; 默认的网络会话类型,会进行自动的缓存
ephemeralSessionConfiguration; 临时会话,不会进行任何缓存
backgroundSessionConfigurationWithIdentifier:(NSString *)identifier 后台会话,可以在程序进入到后台之后,继续网络任务
*/
NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

//config的常用设置
//config.requestCachePolicy 设置缓存策略
//config.networkServiceType 网络服务类型
config.timeoutIntervalForRequest = 20; //网络超时时间
//config.HTTPAdditionalHeaders 请求头的设置
//config.discretionary 节能设置
config.allowsCellularAccess = YES; //是否使用蜂窝网络数据

//创建会话对象
//delegateQueue:用于指定代理方法所运行的队列
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];

//创建网络任务
NSURLSessionDataTask *task = [session dataTaskWithURL:url];

[task resume];

}

#pragma mark – NSURLSessionDataDelegate
//当一次网络请求开始,收到返回的响应头之后所调用的方法
– (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
NSLog(@”response: %@”,response);
//将NSURLResponse的对象,强转成子类NSHTTPURLResponse对象
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSLog(@”状态码:%li”, httpResponse.statusCode);

//completionHandler 完成后的回调
//通过执行此bolck 来设定接下来网络访问
/*
NSURLSessionResponseCancel = 0, 取消网络访问,不在读取响应体
NSURLSessionResponseAllow = 1, 允许本次网络访问,继续接受数据
NSURLSessionResponseBecomeDownload = 2, 转化为downLoadTask
NSURLSessionResponseBecomeStream
*/
completionHandler(NSURLSessionResponseAllow);

}

//响应体的接受
– (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
//接收到响应体中的数据时 调用的方法
NSLog(@”data.lenght = %li”, data.length);
//将每次接收到的数据,拼接到全局变量中
[_data appendData:data];

}

//响应完成
– (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {

if (error) {
NSLog(@”%@”, error);
_data = nil;
} else {

//读取无误,Json解析
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:_data options:NSJSONReadingMutableContainers error:nil];
NSLog(@”dic = %@”, dic);

}

}</span>

 

iOS开发————几种音频播放方式

这篇同样是编者对自己学习的小总结以及对iOS初级开发者的小福利,大神莫吐槽…

首先来谈谈AVFoundation框架:它是iOS中用于处理基于时间的媒体数据的高级框架,也是基于Core Audio,Core Media,Core Video等框架构建的,充分利用了多核硬件的优势并大量使用了Block和GCD机制。

所有的iOS App都具有默认的音频会话,它定义了以下行为:

可以播放音频,但是不能录制音频。

静音模式下App播放的所有音频都会静音。

设备锁定时音频处于静音状态。

App播放音频时所有后台播放的音频都会静音。

iOS系统中音频播放方式:AVAudioPlayer,AVPlayer,播放系统声音,音频队列(小编也不熟…)。

AVAudioPlayer:使用简单,功能强大,但只能播放本地音频。

AVPlayer:可以播放网络音频,本地音频和流媒体播放,但处理音频不够灵活。

播放系统声音:系统声音属于非压缩的存储类型,但是系统声音时长短,不超过30s,格式为 : caf / wav / aiff。

举例:AVAudioPlayer

#import “ViewController.h”
#import <AVFoundation/AVFoundation.h>

@interface ViewController () <AVAudioPlayerDelegate> {

AVAudioPlayer *_audioPlayer;
AVPlayer *_avPlayer;

}

@end

@implementation ViewController

– (void)viewDidLoad {
[super viewDidLoad];

//AVAudioPlayer
//查找本地音乐文件路径
NSString *filePath = [[NSBundle mainBundle] pathForResource:@”多远都要在一起” ofType:@”mp3″];

//构建URL
NSURL *url2 = [NSURL fileURLWithPath:filePath];

//创建音乐播放器
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url2 error:nil];

//根据URL地址来读取音乐文件(写在ViewDidLoad中会自动播放)
[_audioPlayer prepareToPlay];

_audioPlayer.delegate = self;

}
– (IBAction)play:(id)sender {

[_audioPlayer play];

}
– (IBAction)pause:(id)sender {

[_audioPlayer pause];

}

举例:AVPlayer
#import “ViewController.h”
#import <AVFoundation/AVFoundation.h>

@interface ViewController () <AVAudioPlayerDelegate> {

AVAudioPlayer *_audioPlayer;
AVPlayer *_avPlayer;

}

@end

@implementation ViewController

– (void)viewDidLoad {
[super viewDidLoad];
//在iOS9之后,苹果对http访问进行了限制,需要设置info.plist文件
//在info.plist文件中加入字段App Transport Secruity Settings
//在其中添加Allow Arbitrary Loads —— YES

//使用AVPlayer来播放在线音乐
//@”http://218.76.27.57:8080/chinaschool_rs02/135275/153903/160861/160867/1370744550357/mp3″
//创建URL
NSURL *url = [NSURL URLWithString:@”http://218.76.27.57:8080/chinaschool_rs02/135275/153903/160861/160867/1370744550357.mp3″];

//创建播放器
_avPlayer = [[AVPlayer alloc] initWithURL:url];

[_avPlayer play];
}

举例:播放系统声音
#import “ViewController.h”
#import <AVFoundation/AVFoundation.h>

@interface ViewController () <AVAudioPlayerDelegate> {

AVAudioPlayer *_audioPlayer;
AVPlayer *_avPlayer;
SystemSoundID soundID;

}

@end

@implementation ViewController

– (void)viewDidLoad {
[super viewDidLoad];
//播放系统声音
//查找声音文件(此声音文件是编者自己添加到程序包中去的)
NSString *filePath2 = [[NSBundle mainBundle] pathForResource:@”44th Street Medium” ofType:@”caf”];

//构建URL
NSURL *url3 = [NSURL fileURLWithPath:filePath2];

//创建系统声音ID
SystemSoundID soundID;

//注册声音文件,并且将ID保存
AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url3), &soundID);

//播放声音
AudioServicesPlaySystemSound(soundID);

}
//移除系统声音
– (void)dealloc {

//移除注册的系统声音
AudioServicesRemoveSystemSoundCompletion(soundID);
}

 

iOS开发————几种图片加载方式

作为编者自己的一个复习总结以及广大iOS开发初学者的小小福利,呕心沥血诞生出这篇图片加载方式的文章,如有不足请指正。

先谈谈iOS图像加载方式的分类吧。

本地加载:从程序包中加载,从沙盒加载以及从本地相册加载。

网络加载:根据网络地址来加载图片。

先总结网络加载:NSData提供了简单的网络数据加载,这个数据当然包括了图像数据啦,NSData和UIImage之间可以互相转换。

举例:加载网络图片到屏幕

注意前提:将info.plist文件中添加App Transport Security Settings,在其中添加Allow Arbitrary Loads并设置为YES。

– (void)viewDidLoad {
[super viewDidLoad];

//创建一个屏幕大小的imageView来显示图片
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];

//获取网络图片地址
NSURL *url = [NSURL URLWithString:@”http://www.gooii.com/wp-content/uploads/2013/02/apple_logo.png”];

//将网络地址的NSString类型转化为NSData类型
NSData *data = [NSData dataWithContentsOfURL:url];

//image与data的相互转换
UIImage *image = [UIImage imageWithData:data];

//配置图片到imageView上
imageView.image = image;

//将imageView添加到当前视图上去
[self.view addSubview:imageView];

}

再说本地加载:
从程序包中加载:程序包就是我们下载一个APP时它本身的包,比如一些图标,控件图片等都在程序包中,当然我们也可以在制作APP时将一些必要的图片放到程序包中,通过这些图片加载到界面的过程就是从程序包中加载。

举例:从程序包加载图片

– (void)viewDidLoad {
[super viewDidLoad];

//创建一个屏幕大小的imageView
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];

//获取程序包内图片根路径
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];<pre name=”code” class=”html”><span style=”font-family: Arial, Helvetica, sans-serif;”> </span>
//图像路径 NSString *path = [resourcePath stringByAppendingPathComponent:@”gem.jpeg”]; //创建图片 UIImage *image = [UIImage imageWithContentsOfFile:path]; //将图片添加到imageView imageView.image = image; [self.view addSubview:imageView]; }

从沙盒加载图片:
每个APP都有一个独立的沙盒,其中存放着App中的本地文件,比如音频,视频,图片,文字等。当前App无权访问其他App的沙盒。

沙盒目录中有如下子目录:

Document:存放长期使用的文件。其中在该App中下载或者保存的文件都在其中。

Library:存放系统文件。

tmp:存放临时文件,App重启时,该;目录下的文件清空。

举例:从沙盒中的文件加载图片

– (void)viewDidLoad {
[super viewDidLoad];

//创建屏幕大小的imageView
UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds];

//获取沙盒路径
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@”Documents/gem.jpeg”];

//打印沙盒路径
NSLog(@”%@”, NSHomeDirectory());

//获取路径对应的图片文件
UIImage *image = [UIImage imageWithContentsOfFile:path];

//给imageView添加视图文件
imageView.image = image;

//将imageView添加到屏幕
[self.view addSubview:imageView];
}

从相册加载图片文件:首先是获取到相册,在选择图片加载,相册资源访问通过UIImagePickerController类来读取,该类继承自UINavigationController,是个地理的导航控制器,一般使用模态窗口的方式弹出。

举例:从相册资源中加载图片

#import “ViewController.h”

@interface ViewController () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

//在storyboard中设置显示图片的imageView
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

@implementation ViewController

//在storyboard中设置选取图片的按钮
– (IBAction)getPhoto:(id)sender {

//用户的相册资源通过UIImagePickerController读取
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

//设置代理
imagePicker.delegate = self;

//常用属性
//选择的资源类型
// UIImagePickerControllerSourceTypePhotoLibrary,所有同步到iPhone的图像及用户拍摄的图片在内的相册照片
// UIImagePickerControllerSourceTypeCamera,通过相机拍摄
// UIImagePickerControllerSourceTypeSavedPhotosAlbum,仅含相册

// 判断当前设备是否有摄像头
// UIImagePickerControllerCameraDeviceRear,后置摄像头

BOOL isCamera = [UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceRear];

// sourceType属性可指定选取器要选取的资源类型
// 如果有摄像头则通过相机拍摄取照片
if (isCamera) {
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;

// 否则通过相册取照片
} else {
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

}

//通过模态视图打开
[self presentViewController:imagePicker animated:YES completion:nil];

}

– (IBAction)getVideo:(id)sender {

}

//读取完成后调用,info包含了许多数据,
– (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {

//打印info中的数据
NSLog(@”info = %@”, info);

//获取媒体类型
NSString *type = info[UIImagePickerControllerMediaType];

//判断是否是图片类型
if ([type isEqualToString:@”public.image”]) {

//将图片显示到视图中
_imageView.image = info[UIImagePickerControllerOriginalImage];

//模态视图自动退出相册
[picker dismissViewControllerAnimated:YES completion:nil];
}
}

//模态视图方式取消选择退回原界面
– (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {

NSLog(@”取消选择”);

[picker dismissViewControllerAnimated:YES completion:nil];
}

 

iOS开发常用术语————API,SDK,IDE和Xcode概念和关系

浅谈编者对iOS API,iOS SDK以及Xcode的区别和联系

对于iOS开发的初学者,我相信很多朋友也会像我一样对一些常会提到的名词并不是很了解,就比如iOS API,iOS SDK,Xcode。这三者到底有什么样的联系呢?

首先说API(Application Programming Interface)字面翻译是应用程序编程接口,应用程序通过调用操作系统的 API 而使操作系统去执行应用程序的命令(动作)。其实说白了就是一个给编程人员使用的接口,就是我们在编程时候用到的已经封装好了的类和方法。这些类和方法就像一块一块的各种各样的积木,我们使用这些积木可以搭建各种建筑物各种自己想要的东西。

另外补充一些,Cocoa Touch由苹果公司提供的软件开发api,也是苹果公司针对iPhone应用程序快速开发提供的一个类库。此库以一系列框架库的形式存在,支持开发人员使用用户界面元素构建图像化的事件驱动的应用程序。而Cocoa是苹果公司为Mac OS X所创建的原生面向对象的API,苹果的面向对象开发框架,用来生成 Mac OS X 的应用程序。

其次SDK(Software Development Kit)软件开发工具,Xcode、iPhone模拟器、Interface Builder、Instruments和API集合等一些开发相关的工具等都属于SDK,iOS SDK*开始是独立于Xcode发布的,但是后来和Xcode绑定一起发布了,即在近期版本的Xcode中已经集成了iOS SDK。

然后IDE(Integrated Development Environment)被集成好的开发环境,Xcode就是一个iOS的IDE,是一个集成了开发工具(SDK)的IDE。

*后Xcode,也是我们*为熟知的,它是运行在操作系统Mac OS X上的IDE,是一个开发环境,开发平台,是开发OS X APP 和 iOS APP的*快捷的方式。

总结来说:Xcode是一个集成开发环境(IDE),它里面有软件开发工具(SDK),软件开发工具(SDK)中包含应用程序编程接口(API)。

IOS开发笔记 代码篇

注:楼主开发多年,向来没有做笔记的习惯,遇到Bug或者遗忘的知识往往需要再查资料,非常痛苦,故*近开始写Blog,也因此有机会写出本文,权当作笔记和备忘,只为了以后复习方便,也希望对其他新人有所帮助。

本文只是在IOS开发中的一些比较好的资料的汇总,并不见得有系统,

一: Object-C

1.1

@property 和@synthesize

http://justcoding.iteye.com/blog/1444548

(也包括 strong weak unsafe copy assign retain 的属性值-关键字-所有权 关系)

@property 语法: @property(参数1, 参数2)类型 名字;

头文件 .h 中

@property int count;

等效于在头文件中声明2个方法

//创建新变量和变量初始化方法
-(int) count
-(void)setCount:(int)newCount

实现文件 .m 中
@synthesize count

等效于在实现文件 .m 中实现两个方法

-(int) count{
return count;
}

-(void)setCount:(int)newCount{
count = newCount;
}

1.1.1

@property属性对介绍。

http://blog.csdn.net/volcan1987/article/details/6721828 基本介绍

http://www.2cto.com/kf/201205/133943.html 进阶介绍
readwrite:默认,会自动为你生成存取器

assign:一般用来处理基础类型,比如int、float等等,如果你声明的属性是基础类型的话,assign是默认的,你可以不加这个属性

不更改reference count, 会引起内存管理对问题。

适用于:原生类型如 int, float等可以用assign。

copy:这个会自动生成你赋值对象的克隆,相当于在内存中新生成了该对象的副本,这样一来,改变赋值对象就不会改变你声明的这个成员变量了

相当于拷贝内容。不希望a/b用同一内存的时会用到

适用于:NSString

retain:会自动retain赋值对象

相当于拷贝一个指针,用reference count 方式解决了assign的管理问题

适用于:NSObject 和 其子类。

copy, retain拷贝之前都会释放旧对象。

atomic:默认是有该属性的,这个属性是为了保证程序在多线程情况,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题

readonly:只生成getter不会有setter方法

nonatomic:如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率

二: 杂记

2.1: 在Object-C 中的 NSArray,NSString…… NS到底是什么??

NSArray, NSString 等等NS前缀类、函数归属于属于cocoa Fundation基础类库,其”NS”的由来据说是这样的:乔布斯被苹果开除后,创立了NeSt公司,而cocoa Fundation基础类库就是出自于NeST公司,NeST中的”NS”被作为Fundation中所有成员的前缀。当时的情况就是这样的,回答完毕。

不用管他多,就是他自己封装的一层架构,数据类型一般是 NS 界面相关的一般是 UI

2.2:
Java有基本类型了,为什么还有基本类型的对象封装?

注:Object C 里面一样有类似的情况,比如把基本数据类型 int, float 封装成对象

//封装
NSNumber *monthNumber = [NSNumber numberWithInt: 03];
NSLog(@”monthNumber = %@”, monthNumber);
//还原
int month = [monthNumber intValue];
NSlog(@”%d”, month);
原因总结起来主要如下:

1: 基本类型无法和 类 放在一起:比如集合类(Collection 类),ArrayList 中没办法放基本类型,

2: 封装类中提供了很多基本类型没有的方法。

Python 数值中的下划线是怎么回事?

Python 数值中的下划线是怎么回事?
概要和原理
本 PEP 提议扩展 Python 的语法,使得在“字符串变成数”(number-from-string)构造器中,下划线可以作为视觉分隔符,对整数、浮点和复数字面量的数字进行分组。
(Python猫注:关于 Python 的数值类型,可以查看 PEP-3141)
这是其它现代语言的一个常见特性,有助于理解长的或者值应该被直观地分成几部分的字面量,如十六进制表示法中的字节或单词。
例子:
# grouping decimal numbers by thousands
amount = 10_000_000.0
# grouping hexadecimal addresses by words
addr = 0xCAFE_F00D
# grouping bits into nibbles in a binary literal
flags = 0b_0011_1111_0100_1110
# same, for string conversions
flags = int(‘0b_1111_0000’, 2)
规范
目前的提议是在数字之间和在数字字面量的基本标识符之后,允许有一个下划线。下划线没有语义上的意义,数字字面量会被解析得就像没有下划线一样。
字面量语法
因此,整型字面量的表示法看起来像这样:
integer: decinteger | bininteger | octinteger | hexinteger
decinteger: nonzerodigit ([“_”] digit)* | “0” ([“_”] “0”)*
bininteger: “0” (“b” | “B”) ([“_”] bindigit)+
octinteger: “0” (“o” | “O”) ([“_”] octdigit)+
hexinteger: “0” (“x” | “X”) ([“_”] hexdigit)+
nonzerodigit: “1”…”9″
digit: “0”…”9″
bindigit: “0” | “1”
octdigit: “0”…”7″
hexdigit: digit | “a”…”f” | “A”…”F”
浮点数和复数的字面量:
floatnumber: pointfloat | exponentfloat
pointfloat: [digitpart] fraction | digitpart “.”
exponentfloat: (digitpart | pointfloat) exponent
digitpart: digit ([“_”] digit)*
fraction: “.” digitpart
exponent: (“e” | “E”) [“+” | “-“] digitpart
imagnumber: (floatnumber | digitpart) (“j” | “J”)
构造函数
遵循相同的放置规则,下划线可以在以下构造函数中使用:
int()(任意进制)
float()
complex()
Decimal()
进一步的变更
新式的数字转字符串(number-to-string)格式化语法将被扩展,允许 _ 作为千位分隔符。这可以用更具可读性的字面量来轻松地生成代码。[11]
The syntax would be the same as for the comma, e.g. {:10_} for a width of 10 with _ separator.(这句没看懂…不译)
对于 b、x 和 o 格式符,_ 也将支持,并按 4 位数分组。
现有的技术
那些允许下划线分组的语言,实现了大量放置下划线的规则。在语言规范与实际行为相矛盾的情况下,以下会列出实际的行为。(“单个”或“多个”指的是允许多少连续的下划线。)
Ada:单个,仅在数字间 [8]
C# (7.0 版本的提案):多个,仅在数字间[6]
C++14:单个,在数字之间(选了其它分隔符)[1]
D:多个,任意位置,包括末尾 [2]
Java:多个,仅在数字间 [7]
Julia:单个,仅在数字间(但不含浮点指数部分) [9]
Perl 5:多个,基本是任意位置,尽管文档说数字间限制 1 个下划线 [3]
Ruby:单个,仅在数字间(尽管文档说“任意位置”)[10]
Rust:多个,任意位置,除了指数“e”与数字间[4]
Swift:多个,数字之间和末尾(尽管文档说仅在“数字之间”) [5]
被否决的语法
(Python猫注:每个 PEP 在初提出阶段,都可能引起很多关于语法设计的讨论,在正式采纳的 PEP 中,一般会保留一些有代表性的被否决的方案,例如下面的两项)
1、下划线的放置规则
减少下划线的使用限制,而不是上面声明的相对严格的规则。在其它语言中,常见的规则包括:
只允许一个连续的下划线,并且只能在数字之间。
允许多个连续的下划线,但只能在数字之间。
允许多个连续的下划线,在大多数位置,除了字面量的开头,或特殊的位置(例如小数点后)。
本 PEP 中的语法*终被选中,因为它涵盖了常见的用例,并且不会出现被 Python 风格指南所不鼓励使用的语法。
一个不太常见的规则是只允许每 N 位数字有下划线(其中 N 可能是 3 个十进制字面量,或 4 个十六进制字面量)。这是不必要的限制,特别是考虑到这些分隔符位置在不同的文化中是不同的。(Python猫注:例如,我们国家习惯将 4 个数字分为一组,即 10000 是 1 万,而不是英语文化中的 10 thousand)
2、其它的分隔符
还有一种建议是使用空格进行分组。虽然字符串是一种结合相邻字面量的先例,但这种行为可能会导致意外的效果,而下划线则不会。而且,除了那些基本会忽略任何空格的语言外,没有其它语言使用此规则。
c++ 14 引入了单引号来进行分组(因为下划线会与用户定义的字面量产生歧义),由于单引号已经被 Python 的字符串字面量使用了,所以没有考虑它。[1]
实现
实现上述规范的初步补丁已经发布到问题跟踪器。[12]
参考内容
[1] (1, 2) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3499.html
[2] https://dlang.org/spec/lex.html#integerliteral
[3] https://perldoc.perl.org/perldata#Scalar-value-constructors
[4] https://web.archive.org/web/20160304121349/http://doc.rust-lang.org/reference.html#integer-literals
[5] https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html
[6] https://github.com/dotnet/roslyn/issues/216
[7] https://docs.oracle.com/javase/7/docs/technotes/guides/language/underscores-literals.html
[8] http://archive.adaic.com/standards/83lrm/html/lrm-02-04.html#2.4
[9] https://web.archive.org/web/20160223175334/http://docs.julialang.org/en/release-0.4/manual/integers-and-floating-point-numbers/
[10] https://ruby-doc.org/core-2.3.0/doc/syntax/literals_rdoc.html#label-Numbers
[11] https://mail.python.org/pipermail/python-dev/2016-February/143283.html
[12] http://bugs.python.org/issue26331

Python 列表解析式竟然支持异步?

Python 列表解析式竟然支持异步?
PEP原文:https://www.python.org/dev/peps/pep-0530
PEP标题:PEP 530 — Asynchronous Comprehensions
PEP作者:Yury Selivanov
创建日期:2016-09-03
合入版本:3.6
译者:豌豆花下猫@Python猫
PEP翻译计划:https://github.com/chinesehuazhou/peps-cn
摘要
PEP-492 和 PEP-525 通过 async/await 语法,引入了对原生协程和异步生成器的支持。本 pep 提议给列表、集合、字典解析式和生成器表达式添加异步的版本。
基本原理和目标
Python 广泛地支持同步的推导式,允许使用简单而简洁的语法生成列表、字典和集合。我们提议为异步代码实现类似的语法结构。
为了说明可读性的改善,请考虑下面的例子:
result = []
async for i in aiter():
    if i % 2:
        result.append(i)
有了提议的异步解析式语法,上面的代码会变得非常简短:
result = [i async for i in aiter() if i % 2]
本 PEP 也使得在各种解析式中使用 await 表达式成为可能:
result = [await fun() for fun in funcs]
规范
异步的解析式
我们提议允许在列表、集合与字典解析式中使用 async。待 PEP-525 被批准之后,我们还可以创建异步的生成器表达式。
例子:
集合解析式:{i async for i in agen()}
列表解析式:[i async for i in agen()]
字典解析式:{i: i ** 2 async for i in agen()}
生成器表达式:(i ** 2 async for i in agen())
允许在异步解析式和生成器表达式中使用 async for 与 if 以及 for 子句:
dataset = {data for line in aiter()
                async for data in line
                if check(data)}
data = {data for line in aiter() async for data in line if check(data)}
异步解析式只允许在“async def”函数中使用。
原则上,异步生成器表达式允许用在任何上下文中。然而,在 Python 3.6 中,由于 async 和 await 只是“软关键字”(soft-keyword),异步生成器表达式只允许在 async def 函数中使用。一旦 async 和 await 在 Python 3.7 中成为保留关键字,这个限制将被移除。
解析式中的 await
我们提议允许在异步和同步解析式中使用 await 表达式:
result = [await fun() for fun in funcs]
result = {await fun() for fun in funcs}
result = {fun: await fun() for fun in funcs}
result = [await fun() for fun in funcs if await smth]
result = {await fun() for fun in funcs if await smth}
result = {fun: await fun() for fun in funcs if await smth}
result = [await fun() async for fun in funcs]
result = {await fun() async for fun in funcs}
result = {fun: await fun() async for fun in funcs}
result = [await fun() async for fun in funcs if await smth]
result = {await fun() async for fun in funcs if await smth}
result = {fun: await fun() async for fun in funcs if await smth}
这只在 async def 函数体中有效。
语法的更新
本提议需要在语法层面做一个修改:在 comp_for 中添加可选的“async”关键字:
comp_for: [ASYNC] ‘for’ exprlist ‘in’ or_test [comp_iter]
解析式的 AST 节点将有一个新的 is_async 参数。
向后兼容性
本提案是完全向后兼容的。
接受
在 2016 年 9 月 6 日[1],PEP-530 被 Guido 接受。
参考材料
1、https://mail.python.org/pipermail/python-ideas/2016-September/042141.html
2、https://github.com/1st1/cpython/tree/asyncomp
3、http://bugs.python.org/issue28008
致谢
感谢 Guido van Rossum、Victor Stinner 和 Elvis pranskevichuss 对于这个 pep 的反馈、代码检视和讨论。

总结Python的几点语言特性

总结Python的几点语言特性
总结Python的几点语言特性
Python语言简洁,优雅,扩展性强…… 这些特点常被Python程序员挂在嘴边,确实也都是Python的特点。
要讨论语言的特点或特性,可以得到很多不同的结论,有针对语言整体而言的特性,也有针对某一个应用领域的特性。本文只从语言设计方面(其他的不讨论),总结Python的几点语言特性。
一、解释型语言
高级语言不能直接被计算机理解(计算机只能理解机器语言,二进制代码),要先将高级语言翻译成机器语言,计算机才能执行高级语言编写的代码。根据翻译工具(解释器或编译器)的不同,高级语言分为解释型语言和编译型语言。
解释型语言:在代码运行时,解释器将代码逐行翻译成机器语言,代码可以按行运行。
编译型语言:先使用编译器对代码编译,生成可执行文件(如.exe文件),然后运行可执行文件。
Python是解释型语言,所以Python代码不需要编译,编写完就可以直接运行。
解释型语言相当于实时翻译,省去了编译这个步骤。每运行一次代码,解释器都要重新翻译代码,而解释器把代码翻译成机器语言是要花时间的,所以,解释型语言的运行效率比编译型语言低很多,速度慢,性能上处于劣势。
编译型语言相当于提前翻译,运行时直接运行可执行文件。编译只需要一次,后面不管运行多少次,都可以直接运行可执行文件,所以,编译型语言的运行效率比解释型语言高很多,速度快,性能上有优势。
因为性能上的劣势,解释型语言不适合开发操作系统、大型应用程序、数据库系统等对性能要求高的程序,这些程序基本都是使用编译型语言。当然,解释型语言可以通过对解释器进行优化来提高运行效率,同时,随着计算机硬件的性能提升,也可以弥补解释型语言在性能上的不足,使性能差距对生产的影响降低,甚至消除。
另一方面,因为在运行时才解释代码,解释型语言的跨平台性更好,代码移植到不同的操作系统中后可以直接运行。而因为不同操作系统识别的机器语言有差异,编译型语言移植到不同的操作系统后,需要重新编译后才能运行,跨平台性不如解释型语言。
说回Python,Python程序运行后也可以将运行的机器语言保存到以.pyc为扩展名的文件中,下次运行时,如果代码没有变化,解释器可以直接运行.pyc文件。这算是Python对运行效率的一种​优化,所以,也有人说Python是一种解释型和编译型相结合的语言。
二、动态类型语言
在不同的高级语言中,都有很多数据类型,这些数据类型的定义大同小异。在代码中,数据一般保存在变量之中(被变量引用),通常会先定义变量,然后将数据赋值给变量。根据定义变量前是否需要提前声明变量的数据类型,高级语言分为动态类型语言和静态类型语言。
动态类型语言:定义变量前,不需要声明变量的数据类型,执行代码的时候由解释器动态确认变量的数据类型。
静态类型语言:定义变量前,必须先声明变量的数据类型,给变量赋值时数据类型必须匹配。
Python是动态类型语言,所以Python代码中不需要提前声明变量的数据类型,运行代码的时候再动态确认数据类型。
var = 100
print(var, type(var))
var = ‘!@#$%’
print(var, type(var))
100 <class ‘int’>
!@#$% <class ‘str’>
看上面的例子,定义变量var的时候赋值为100,运行时的数据类型为int(整数),再将它赋值为字符!@#$%,运行时的数据类型为str(字符串)。不仅变量的数据类型不需要提前声明,在运行过程中,数据类型还会根据不同的引用而改变。
动态类型语言不需要提前声明变量的数据类型,使代码更加简洁,可以少写很多代码,同时,也给了程序员很大的自由度,写代码时多了很多自由发挥的空间。但是,太自由了也可能会有弊端,如果一些变量定义得不规范(如多处出现同名变量名),会使代码的可读性降低,增加定位问题的难度,甚至带来一些不易察觉的BUG。
静态类型语言的每个变量都先声明了数据类型,每个变量都必须先声明才能使用,一旦声明后数据类型不能修改,这充分保证了同一个变量名在上下文中的一致性,即使代码量很大的情况下也不会出现混乱。只是,会使代码量变多,实现相同的功能,代码量会增加很多。
三、强类型语言
在高级语言中,将不同类型的变量进行运算时,有些语言可以自动对数据类型进行转换,使不同数据类型的变量能兼容,能返回运算结果,程序不报错,另一些语言必须先将数据类型转换成一致,才能进行运算,否则程序会报错。所以高级语言可以分为强类型语言和弱类型语言。
强类型语言:不同类型的数据进行运算前,必须先将数据类型转换成一致。
弱类型语言:不同类型的数据进行运算,会自动进行数据类型转换。
Python是强类型语言,所以Python代码中不同类型的数据运算会报错。
强类型和弱类型是体现在数据运算时不同类型的数据能否兼容,而动态类型和静态类型是体现在定义变量时是否需要先声明数据类型,所以这是两个维度的概念,不能混淆了。
a = 100
print(a, type(a))
b = ‘100’
print(b, type(b))
print(a + b)
100 <class ‘int’>
100 <class ‘str’>
TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’
print(str(a) + b, type(str(a) + b))
print(a + int(b), type(a + int(b)))
100100 <class ‘str’>
200 <class ‘int’>
看上面的例子,变量a是int(整型),变量b是str(字符串),将两者相加时,会报错TypeError:不支持整型与字符串相加。当将a和b的数据类型转换成一致后,可以正常运算。
强类型语言不支持不同类型的数据直接进行运算,必须先对数据类型进行转换,这可以帮助程序员在变量运算前确认和厘清数据的类型,避免了不同数据类型进行运算的混乱。但是,不同类型的数据进行运算前,要先进行类型转化,多了一个步骤,也会降低运行效率。
弱类型语言支持不同类型的数据直接进行运算,在不同类型的数据进行运算时会自动进行转换,省了自动转换的步骤。但是,两个不同类型的数据直接运算,可能会使程序员错误判断结果的数据类型,甚至可能会带来BUG。
在动态类型和静态类型方面,Python给程序员留了足够的自由,但在强类型和弱类型方面,Python又对数据的运算进行了限制。可以猜想,Guido这么设计是经过深思熟虑的,在定义变量的时候给了足够自由,也提升了代码的简洁性,但在进行数据运算时进行了限制,加了一道保险,避免太过自由带来一些不必要的问题。
四、面向对象语言
在编程时,一个功能可以分成多个步骤来逐步实现,基本所有语言都支持按步骤实现功能和抽取可重用的函数,而面向对象语言还支持由数据和功能组合而成的对象来实现功能。所以,根据是否支持面向对象编程,高级语言可以分为面向对象语言和面向过程语言。
面向对象语言:以对象作为代码的基础结构,通过对象的属性和方法来实现业务功能。
面向过程语言:代码由过程代码和抽取的功能函数构成,函数可以重复使用。
Python是面向对象语言,Python中一切皆对象,可以将数据和功能封装到对象中,从对象的角度去处理问题和实现功能。当然,用Python也可以实现面向过程编程。
面向对象语言的设计聚焦于对象之上,将数据作为属性封装在对象内,将功能作为方法封装在对象内,不管是使用属性还是方法,都可以通过对象调用。面向对象语言具有封装、继承和多肽三大特性,可以使程序设计得更加清晰,由此也产生了很多设计模式。在复杂的业务中,不同的对象执行不同的功能,降低了代码的耦合度,有利于提高开发效率,降低重构代码的难度。
面向过程语言的代码按照业务逻辑自上而下,逐步实现功能,如果有可以重复使用的功能,可以抽取成函数。面向过程编程没有面向对象编程抽象,所以更容易理解,代码与业务逻辑环环相扣,一步一步地实现,这就使得代码的耦合度很高。即使将重复代码抽取成函数,还是很难避免代码的冗余,代码的设计模式也比较少,设计思路没有面向对象的清晰,重构代码也更难。
关于面向对象语言和面向过程语言的讨论内容很多,对于业务逻辑比较复杂的程序,比较统一的看法是面向对象优于面向过程,而对于业务逻辑简单的程序,面向对象和面向过程都可以。
上面总结了几点Python的语言特性,如果有一些编程经验,大家都会有自己的理解,每个人的理解可能会存在一些小差异,所以没必要在意是否权威,自己思考*重要。