《Python极客项目编程 》——1.4 完整代码

简介:

本节书摘来自异步社区《Python极客项目编程 》一书中的第1章,第1.4节,作者 [美] Mahesh Venkitachalam,王海鹏 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.4 完整代码

下面是完整的程序。在https://github.com/electronut/pp/tree/master/playlist/ ,你也可以找到本项目的代码和一些测试数据。

import re, argparse
import sys
from matplotlib import pyplot
import plistlib
import numpy as np

def findCommonTracks(fileNames):
    """
    Find common tracks in given playlist files,
    and save them to common.txt.
    """
    # a list of sets of track names
    trackNameSets = []
    for fileName in fileNames:
        # create a new set
        trackNames = set()
        # read in playlist
        plist = plistlib.readPlist(fileName)
        # get the tracks
        tracks = plist['Tracks']
        # iterate through the tracks
        for trackId, track in tracks.items():
            try:
                # add the track name to a set
                trackNames.add(track['Name'])
            except:
                # ignore
                pass
        # add to list
        trackNameSets.append(trackNames)
        # get the set of common tracks
        commonTracks = set.intersection(*trackNameSets)
        # write to file
        if len(commonTracks) > 0:
            f = open("common.txt", 'w')
            for val in commonTracks:
                s = "%s\n" % val
                f.write(s.encode("UTF-8"))
            f.close()
            print("%d common tracks found. "
                  "Track names written to common.txt." % len(commonTracks))
        else:
            print("No common tracks!")

    def plotStats(fileName):
        """
        Plot some statistics by reading track information from playlist.
        """
        # read in a playlist
        plist = plistlib.readPlist(fileName)
        # get the tracks from the playlist
        tracks = plist['Tracks']
        # create lists of song ratings and track durations
        ratings = []
        durations = []
        # iterate through the tracks
        for trackId, track in tracks.items():
            try:
                ratings.append(track['Album Rating'])
                durations.append(track['Total Time'])
            except:
                # ignore
                pass
        # ensure that valid data was collected
        if ratings == [] or durations == []:
            print("No valid Album Rating/Total Time data in %s." % fileName)
            return

        # scatter plot
        x= np.array(durations, np.int32)
        # convert to minutes
        x = x/60000.0
        y = np.array(ratings, np.int32)
        pyplot.subplot(2, 1, 1)
        pyplot.plot(x, y, 'o')
        pyplot.axis([0, 1.05*np.max(x), -1, 110])
        pyplot.xlabel('Track duration')
        pyplot.ylabel('Track rating')

        # plot histogram
        pyplot.subplot(2, 1, 2)
        pyplot.hist(x, bins=20)
        pyplot.xlabel('Track duration')
        pyplot.ylabel('Count')
        # show plot
        pyplot.show()

    def findDuplicates(fileName):
        """
        Find duplicate tracks in given playlist.
        """
        print('Finding duplicate tracks in %s...' % fileName)
        # read in playlist
        plist = plistlib.readPlist(fileName)
        # get the tracks from the Tracks dictionary
        tracks = plist['Tracks']
        # create a track name dictionary
        trackNames = {}
        # iterate through tracks
        for trackId, track in tracks.items():
            try:
                name = track['Name']
                duration = track['Total Time']
                # look for existing entries
                if name in trackNames:
                    # if a name and duration match, increment the count
                    # round the track length to the nearest second
                    if duration//1000 == trackNames[name][0]//1000:
                        count = trackNames[name][1]
                        trackNames[name] = (duration, count+1)
                else:
                    # add dictionary entry as tuple (duration, count)
                    trackNames[name] = (duration, 1)
            except:
                # ignore
                pass
        # store duplicates as (name, count) tuples
        dups = []
        for k, v in trackNames.items():
            if v[1] > 1:
                dups.append((v[1], k))
        # save duplicates to a file
        if len(dups) > 0:
            print("Found %d duplicates. Track names saved to dup.txt" % len(dups))
        else:
            print("No duplicate tracks found!")
        f = open("dups.txt", 'w')
        for val in dups:
            f.write("[%d] %s\n" % (val[0], val[1]))
        f.close()

    # gather our code in a main() function
    def main():
        # create parser
        descStr = """
        This program analyzes playlist files (.xml) exported from iTunes.
        """
        parser = argparse.ArgumentParser(description=descStr)
        # add a mutually exclusive group of arguments
        group = parser.add_mutually_exclusive_group()

        # add expected arguments
        group.add_argument('--common', nargs='*', dest='plFiles', required=False)
        group.add_argument('--stats', dest='plFile', required=False)
        group.add_argument('--dup', dest='plFileD', required=False)

        # parse args
        args = parser.parse_args()

        if args.plFiles:
            # find common tracks
            findCommonTracks(args.plFiles)
        elif args.plFile:
            # plot stats
            plotStats(args.plFile)
    elif args.plFileD:
        # find duplicate tracks
        findDuplicates(args.plFileD)
    else:
        print("These are not the tracks you are looking for.")

# main method
if __name__ == '__main__':
    main()
相关文章
|
7天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
7天前
|
程序员 开发者 Python
Python网络编程基础(Socket编程) 错误处理和异常处理的最佳实践
【4月更文挑战第11天】在网络编程中,错误处理和异常管理不仅是为了程序的健壮性,也是为了提供清晰的用户反馈以及优雅的故障恢复。在前面的章节中,我们讨论了如何使用`try-except`语句来处理网络错误。现在,我们将深入探讨错误处理和异常处理的最佳实践。
|
8天前
|
监控 Python
Python中的装饰器:提升代码灵活性与可读性
在Python编程中,装饰器是一种强大的工具,能够提升代码的灵活性和可读性。本文将介绍装饰器的基本概念、使用方法以及实际应用场景,帮助读者更好地理解和利用这一功能。
|
9天前
|
缓存 监控 算法
优化Python代码性能的10个技巧
提高Python代码性能是每个开发者都需要关注的重要问题。本文将介绍10个实用的技巧,帮助你优化Python代码,提升程序的运行效率和性能表现。无论是避免内存泄漏、减少函数调用次数,还是使用适当的数据结构,都能在不同场景下发挥作用,使你的Python应用更加高效稳定。
|
23小时前
|
API Python
Python模块化编程:面试题深度解析
【4月更文挑战第14天】了解Python模块化编程对于构建大型项目至关重要,它涉及代码组织、复用和维护。本文深入探讨了模块、包、导入机制、命名空间和作用域等基础概念,并列举了面试中常见的模块导入混乱、不适当星号导入等问题,强调了避免循环依赖、合理使用`__init__.py`以及理解模块作用域的重要性。掌握这些知识将有助于在面试中自信应对模块化编程的相关挑战。
6 0
|
1天前
|
数据安全/隐私保护 Python
Python中的装饰器:提升代码可读性与灵活性
Python中的装饰器是一种强大的工具,可以在不改变函数原有逻辑的情况下,为函数添加额外的功能。本文将介绍装饰器的基本概念和用法,并通过实例演示如何利用装饰器提升代码的可读性和灵活性,使代码更加简洁、易于维护。
|
1天前
|
BI 开发者 数据格式
Python代码填充数据到word模板中
【4月更文挑战第16天】
|
2天前
|
Python
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上)
python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上)
22 0
|
3天前
|
缓存 算法 Python
优化Python代码的十大技巧
本文介绍了十种优化Python代码的技巧,涵盖了从代码结构到性能调优的方方面面。通过学习和应用这些技巧,你可以提高Python程序的执行效率,提升代码质量,以及更好地应对复杂的编程任务。
|
3天前
|
程序员 Python
Python中的装饰器:提升代码可读性与灵活性
在Python编程中,装饰器是一种强大的工具,可以在不修改原始代码的情况下,动态地添加功能。本文将深入探讨Python中装饰器的原理、用法和实际应用,以及如何利用装饰器提升代码的可读性和灵活性。

热门文章

最新文章