# 现代集成开发环境(IDE) 下面的`Python多行字符串`包含了根据搜索引擎IDE关键词频次建立的IDE排行榜数据,以下数据直接从网页https://pypl.github.io/IDE.html 右侧的表格拷贝下来: ```python top_ide_trend = ''' Rank Change IDE Share Trend 1 Visual Studio 29.24 % +3.5 % 2 Eclipse 13.91 % -2.9 % 3 Visual Studio Code 12.07 % +3.3 % 4 Android Studio 9.13 % -2.5 % 5 pyCharm 8.43 % +0.7 % 6 IntelliJ 6.7 % +0.8 % 7 NetBeans 4.82 % -0.3 % 8 Sublime Text 3.49 % -0.2 % 9 Xcode 3.37 % -1.2 % 10 Atom 3.25 % -0.5 % 11 Code::Blocks 2.16 % +0.2 % 12 Vim 0.79 % -0.1 % 13 Xamarin 0.48 % -0.1 % 14 PhpStorm 0.46 % -0.2 % 15 geany 0.39 % +0.2 % 16 Komodo 0.31 % -0.2 % 17 Qt Creator 0.26 % -0.0 % 18 Emacs 0.18 % -0.1 % 19 JDeveloper 0.13 % -0.0 % 20 RAD Studio 0.08 % -0.0 % 21 JCreator 0.07 % -0.0 % 22 Light Table 0.07 % -0.0 % 23 MonoDevelop 0.06 % -0.0 % 24 SharpDevelop 0.03 % -0.0 % 25 Eric Python 0.03 % -0.0 % 26 Aptana 0.02 % -0.0 % 27 RubyMine 0.02 % -0.0 % 28 Coda 2 0.02 % +0.0 % 29 Monkey Studio 0.01 % -0.0 % 30 DrJava 0.01 % -0.0 % ''' ``` 事实上其中有些是`编辑器`,例如`Vim`和`Sublime Text`,这些编辑器有丰富的辅助开发的插件体系,因此许多程序员也会用它们来作为集成开发环境。VIM编辑器源自 Bram Moolenaar 在 80 年代末购入他的 Amiga 计算机时,Amiga 上没有他最常用的编辑器vi。Bram 从一个开源的 vi 复制 Stevie 开始,开发了 Vim 的 1.0 版本。另一个著名的编辑器是 Emacs,VIM 和 Emacs 是编辑器的两大流派。 特别值得一提的是如果你装了VIM,在命令行里输入VIM,打开的VIM屏幕上会展示打开文本,其中文本`Help poor children in Uganda!`是一个线索,你可以通过搜索引擎了解这个细节。 此外不同的编辑器的学习陡峭程度不同,下图展示了这点: ![](./editor.jpg) 下面的`Python数组`包含了一组 Python 开发常用工具信息: ```python py_ide_infos = [ "IDEL(https://docs.python.org/3/library/idle.html), Python 内置的IDE,功能比较一般。", "VIM(http://www.vim.org/),如果你是个VIM爱好者,可以用VIM编写Python,但是Python的缩进处理会比较麻烦。当然,你在 Linux 服务器上的时候有时候就只能用VI/VIM了。", "Visual Studio Code(https://code.visualstudio.com/),VSCode 对Python的支持非常友好,配合几个插件后几乎是对 Python 开发最友好的IDE了。", "PyCharm(https://www.jetbrains.com/pycharm/),jetbrains 出品的 PyCharm 也是 Python 开发者常用的IDE。" ] ``` 请编写一个 Python 比对程序,支持功能: 1. 解析 Python 常用开发工具信息,获得结构化信息 2. 解析 Python 排行榜数据,获得结构化信息 3. 在 Python 排行榜结构化信息中查找 Python 常用开发工具的数据 4. 输出合并后的结构信息 基本的程序框架如下: ```python def parse_ide_trend(top_ide_trend): top_ides = [] top_ide_lines = top_ide_trend.split('\n')[1:] head = top_ide_lines[0] columns = head.split('\t') for row in top_ide_lines[1:]: row = row.strip() if row: cells = row.split('\t') top_ide = {} for i in range(0, len(columns)): column = columns[i] cell = cells[i] top_ide[column] = cell top_ides.append(top_ide) return top_ides def parse_py_ide(py_ide_infos): py_ides = [] for row in py_ide_infos: name_end = row.find('(') name = row[0:name_end] link_end = row.find(')') link = row[name_end+1:link_end] desc = row[link_end+2:] py_ides.append({'name': name, 'link': link, 'desc': desc}) return py_ides def dump_join_result(py_ide, top_ide): py_ide_name = py_ide['name'] print(f'Python IDE:{py_ide_name}') print('----------') print('* 基本信息') for key in py_ide: value = py_ide[key] print(f' * {key}: {value}') print('* 排行信息') if top_ide: for key in top_ide: if key != 'IDE' and key != 'Change': value = top_ide[key] print(f' * {key}: {value}') else: print(' * 无') print('') if __name__ == '__main__': top_ide_trend = ... py_ide_infos = ... top_ides = parse_ide_trend(top_ide_trend) py_ides = parse_py_ide(py_ide_infos) # TODO(You): 请在此编写比对程序 ``` 比对程序的输出格式如下: ```bash Python IDE:IDEL ---------- * 基本信息 * name: IDEL * link: https://docs.python.org/3/library/idle.html * desc: Python 内置的IDE,功能比较一般。 * 排行信息 * 无 Python IDE:VIM ---------- * 基本信息 * name: VIM * link: http://www.vim.org/ * desc: 如果你是个VIM爱好者,可以用VIM编写Python,但是Python的缩进处理会比较麻烦。当然,你在 Linux 服务器上的时候有时候就只能用VI/VIM了。 * 排行信息 * Rank: 12 * Share: 0.79 % * Trend: -0.1 % Python IDE:Visual Studio Code ---------- * 基本信息 * name: Visual Studio Code * link: https://code.visualstudio.com/ * desc: VSCode 对Python的支持非常友好,配合几个插件后几乎是对 Python 开发最友好的IDE了。 * 排行信息 * Rank: 3 * Share: 12.07 % * Trend: +3.3 % Python IDE:PyCharm ---------- * 基本信息 * name: PyCharm * link: https://www.jetbrains.com/pycharm/ * desc: jetbrains 出品的 PyCharm 也是 Python 开发者常用的IDE。 * 排行信息 * Rank: 5 * Share: 8.43 % * Trend: +0.7 % ``` 以下选项是对代码中`TODO`部分的多种实现,你能找出以下实现错误的选项吗? ## template ```python def parse_ide_trend(top_ide_trend): top_ides = [] top_ide_lines = top_ide_trend.split('\n')[1:] head = top_ide_lines[0] columns = head.split('\t') for row in top_ide_lines[1:]: row = row.strip() if row: cells = row.split('\t') top_ide = {} for i in range(0, len(columns)): column = columns[i] cell = cells[i] top_ide[column] = cell top_ides.append(top_ide) return top_ides def parse_py_ide(py_ide_infos): py_ides = [] for row in py_ide_infos: name_end = row.find('(') name = row[0:name_end] link_end = row.find(')') link = row[name_end+1:link_end] desc = row[link_end+2:] py_ides.append({'name': name, 'link': link, 'desc': desc}) return py_ides def dump_join_result(py_ide, top_ide): py_ide_name = py_ide['name'] print(f'Python IDE:{py_ide_name}') print('----------') print('* 基本信息') for key in py_ide: value = py_ide[key] print(f' * {key}: {value}') print('* 排行信息') if top_ide: for key in top_ide: if key != 'IDE' and key != 'Change': value = top_ide[key] print(f' * {key}: {value}') else: print(' * 无') print('') def compare_1(): for py_ide in py_ides: find_top_ide = None for top_ide in top_ides: if py_ide['name'].lower() == top_ide['IDE'].lower(): find_top_ide = top_ide dump_join_result(py_ide, find_top_ide) def compare_2(): top_ide_dict = {} for top_ide in top_ides: top_ide_dict[top_ide['IDE'].lower()] = top_ide for py_ide in py_ides: find_top_ide = top_ide_dict.get(py_ide['name'].lower()) dump_join_result(py_ide, find_top_ide) def compare_3(): find_records = {} for top_ide in top_ides: for py_ide in py_ides: py_ide_name = py_ide['name'] if not find_records.get(py_ide_name): if py_ide['name'].lower() == top_ide['IDE'].lower(): find_records[py_ide['name']] = True dump_join_result(py_ide, top_ide) def compare_4(): top_ide_dict = {} i = 0 while i < len(top_ides): top_ide_dict[top_ides[i]['IDE'].lower()] = i i += 1 j = 0 while j < len(py_ides): py_ide = py_ides[j] find_index = top_ide_dict.get(py_ide['name'].lower()) find_top_ide = None if find_index and find_index >= 0: find_top_ide = top_ides[find_index] dump_join_result(py_ide, find_top_ide) j += 1 if __name__ == '__main__': top_ide_trend = ''' Rank Change IDE Share Trend 1 Visual Studio 29.24 % +3.5 % 2 Eclipse 13.91 % -2.9 % 3 Visual Studio Code 12.07 % +3.3 % 4 Android Studio 9.13 % -2.5 % 5 pyCharm 8.43 % +0.7 % 6 IntelliJ 6.7 % +0.8 % 7 NetBeans 4.82 % -0.3 % 8 Sublime Text 3.49 % -0.2 % 9 Xcode 3.37 % -1.2 % 10 Atom 3.25 % -0.5 % 11 Code::Blocks 2.16 % +0.2 % 12 Vim 0.79 % -0.1 % 13 Xamarin 0.48 % -0.1 % 14 PhpStorm 0.46 % -0.2 % 15 geany 0.39 % +0.2 % 16 Komodo 0.31 % -0.2 % 17 Qt Creator 0.26 % -0.0 % 18 Emacs 0.18 % -0.1 % 19 JDeveloper 0.13 % -0.0 % 20 RAD Studio 0.08 % -0.0 % 21 JCreator 0.07 % -0.0 % 22 Light Table 0.07 % -0.0 % 23 MonoDevelop 0.06 % -0.0 % 24 SharpDevelop 0.03 % -0.0 % 25 Eric Python 0.03 % -0.0 % 26 Aptana 0.02 % -0.0 % 27 RubyMine 0.02 % -0.0 % 28 Coda 2 0.02 % +0.0 % 29 Monkey Studio 0.01 % -0.0 % 30 DrJava 0.01 % -0.0 % ''' py_ide_infos = [ "IDEL(https://docs.python.org/3/library/idle.html), Python 内置的IDE,功能比较一般。", "VIM(http://www.vim.org/),如果你是个VIM爱好者,可以用VIM编写Python,但是Python的缩进处理会比较麻烦。当然,你在 Linux 服务器上的时候有时候就只能用VI/VIM了。", "Visual Studio Code(https://code.visualstudio.com/),VSCode 对Python的支持非常友好,配合几个插件后几乎是对 Python 开发最友好的IDE了。", "PyCharm(https://www.jetbrains.com/pycharm/),jetbrains 出品的 PyCharm 也是 Python 开发者常用的IDE。" ] top_ides = parse_ide_trend(top_ide_trend) py_ides = parse_py_ide(py_ide_infos) compare_1() compare_2() compare_3() compare_4() ``` ## 答案 ```python find_records = {} for top_ide in top_ides: for py_ide in py_ides: py_ide_name = py_ide['name'] if not find_records.get(py_ide_name): if py_ide['name'].lower() == top_ide['IDE'].lower(): find_records[py_ide['name']] = True dump_join_result(py_ide, top_ide) ``` ## 选项 ### 两层循环 ```python for py_ide in py_ides: find_top_ide = None for top_ide in top_ides: if py_ide['name'].lower() == top_ide['IDE'].lower(): find_top_ide = top_ide dump_join_result(py_ide, find_top_ide) ``` ### 索引 ```python top_ide_dict = {} for top_ide in top_ides: top_ide_dict[top_ide['IDE'].lower()] = top_ide for py_ide in py_ides: find_top_ide = top_ide_dict.get(py_ide['name'].lower()) dump_join_result(py_ide, find_top_ide) ``` ### 使用整数索引 ```python top_ide_dict = {} i = 0 while i < len(top_ides): top_ide_dict[top_ides[i]['IDE'].lower()] = i i += 1 j = 0 while j < len(py_ides): py_ide = py_ides[j] find_index = top_ide_dict.get(py_ide['name'].lower()) find_top_ide = None if find_index and find_index >= 0: find_top_ide = top_ides[find_index] dump_join_result(py_ide, find_top_ide) j += 1 ```