需求:最近组里有这样一个需求,大概就是用代码生成代码(这里的代码指的是C代码,其中有一大部分是重复的格式)。实际工作当中,如果手动自行去复制-->粘贴-->修改-->调试,大概率会调试不通过,问题多半出现在'修改'这个一环节。比如有时候少粘贴个';' ,这样的小失误会徒增我们码农的麻烦(最重要的是不能早点下班~~哈哈),所以这个小程序就出来了。
- python基础
- xlwings,这个是关于excel表格数据的处理库
- mako,模板引擎,用来做模子的。
- thinker,可以做一个简单的界面,将程序打成.exe给你的C猿使用。
- 整体分为三步,打开冰箱,把大象放进去,关上。。。不好意思,跑题了。
- c猿朋友,给我一个excel(3),里面有一些像java里的entity的东西,我们不管它是什么
- 然后我要给他,长的像这样(4)的.h/.c文件
名称 变量代码 信号名称 信号值描述 变量代码类型 id var_code signal_name signal_comment var_type 0x387 TBOX_Satellite_Time_Hour 小时 0x0:0 int8_t 0x387 TBOX_SatelliteTime_Minute 分钟 0x17:23 0x0:0 0x3B:59 int8_t
#ifndef __X_APP_CAN_H #define __X_APP_CAN_H #include "typedef.h" #include "stdint.h" #include "stdbool.h" enum { CAN_TX_ENABLE_NOSEND = 0, CAN_TX_ENABLE_SEND, CAN_TX_DISABLE, }; enum { CAN_BUS_STAT_NORMAL = 0, CAN_BUS_STAT_BUSOFF_FAST, CAN_BUS_STAT_BUSOFF_SLOW, }; typedef struct { uint8_t rx_flag; int32_t time; int8_t TBOX_Satellite_Time_Hour; int8_t TBOX_SatelliteTime_Minute; }TCU_DATA_0x387_t; extern TCU_DATA_0x387_t TCU_DATA_0x387; typedef struct { uint8_t rx_flag; int32_t time; int8_t TBOX_SatelliteTime_Minute; }TCU_DATA_0x999_t; extern TCU_DATA_0x999_t TCU_DATA_0x999; void app_can_data_init(void); void app_can_proc(void); void can_send_proc(void); uint16_t app_speed_get_speed_cm();
到这里,比较长的朋友应该看出来,这个东西不就是java里的实体嘛,然后我们的需求就像mybatis-plus 里的generateCode功能一样,当然这个他的这个功能比较完善,entity,dao,service,controller,还有mapper这些一套东西都有,搞java的同学应该很熟悉这些。所以,现在我们要做的是用python做个一个简单的generateCode。
仔细看,应该能看到h文件里的实体,动态的的字段有一个或者多个。
int8_t TBOX_Satellite_Time_Hour;
int8_t TBOX_SatelliteTime_Minute;
还有实体的名字也是变量
typedef struct
{
uint8_t rx_flag;
int32_t time;
int8_t TBOX_Satellite_Time_Hour;
int8_t TBOX_SatelliteTime_Minute;
}TCU_DATA_0x387_t;
extern TCU_DATA_0x387_t TCU_DATA_0x387;
看到这里,我想个位小天才也有思路了。
[{'id': '0x387', 'var_code': 'TBOX_Satellite_Time_Hour'},
{'id': '0x387', 'var_code': 'TBOX_SatelliteTime_Minute'}] ;
- enum {
- CAN_BUS_STAT_NORMAL = 0,
- CAN_BUS_STAT_BUSOFF_FAST,
- CAN_BUS_STAT_BUSOFF_SLOW,
- };
-
- % for item in entitys:
- typedef struct
- {
- uint8_t rx_flag;
- int32_t time;
- % for record in item['records']:
- ${record['var_type']} ${record['var_code']};
- % endfor
- }TCU_DATA_${item['id']}_t;
- extern TCU_DATA_${item['id']}_t TCU_DATA_${item['id']};
-
- % endfor
-
代码我就直接贴出来了
- import xlwings as xw
- from mako.template import Template
- from win32com.client import DispatchEx
-
- ''' 1,读取excel中的sheet,返回多个sheet列表'''
- def read_excel(excel):
- xl = xw._xlwindows.COMRetryObjectWrapper(DispatchEx("Ket.Application"))
- impl = xw._xlwindows.App(visible=False, add_book=False, xl=xl)
-
- app = xw.App(visible=False, add_book=False, impl=impl)
- wb = app.books.open(excel)
- sht = wb.sheets[0]
- # wb.save()
- wb.close()
- # app.quit()
-
- app.kill()
- return sht
-
- ''' 2,解析sheet,提取 entity 数据信息封装成dic'''
- # [{'id': '0x387', 'var_code': 'TBOX_Satellite_Time_Hour'},{'id': '0x387', 'var_code': 'TBOX_SatelliteTime_Minute'}]
- def parse_excel(sheet):
- titles_comm = sheet.range('A1').options(expand='right').value
- titels = sheet.range('A2').options(expand='right').value
- entitys = []
- for row in sheet.range('A3').expand('table').value:
- entity = dict(zip(titels, row))
- entitys.append(entity)
- return entitys
-
- ''' 通过ID 和并一些数据 ,返回list'''
- def merge_data_by_id(l: list):
- t = {}
- for d in l:
- if d['id'] not in t:
- t[d['id']] = {k: d.get(k, []) for k in ('id', 'records')}
- t[d['id']]['records'].append({k: d[k] for k in ('var_code', 'var_type', 'signal_name')})
- return t.values()
-
- ''' 3.根据mako模板生成.h/.c文件'''
- def generate_code_h(entitys: list):
- datas = {'entitys': entitys}
- h_file = Template(filename='./mako_template/entity_h.mako', module_directory='./mako_template/tmp').render(
- **datas)
- with open('./generate_file/entity_h.h', 'wb+') as f:
- f.write(h_file.encode('utf-8'))
- print('h_file 文件生成,成功 @——@')
-
-
-
-
- if __name__ == '__main__':
- excel = 'C:\\Users\\15839680585\\Desktop\\template\\Desktop\\entity2.xlsx'
- sht = read_excel(excel)
-
- # 读取excel数据,然后封装为json
- l = parse_excel(sht)
- l_entity = merge_data_by_id(l)
- print(l_entity)
- generate_code_h(l_entity)
写在最后,水平有限,请大佬们指导~ 最重要的是希望能帮助到像我这样到处查资料的人~