使用Spotipy / Spotify API的“其他”序列问题

如何解决使用Spotipy / Spotify API的“其他”序列问题

我和我的团队(python的新手)编写了以下代码,以生成与特定城市和相关术语相关的Spotify歌曲。 如果用户输入的城市不在我们的CITY_KEY_WORDS列表中,则它告诉用户输入将被添加到请求文件中,然后将输入写入文件中。 代码如下:


from random import shuffle
from typing import Any,Dict,List
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
sp = spotipy.Spotify(
    auth_manager=SpotifyClientCredentials(client_id="",client_secret="")
)
CITY_KEY_WORDS = {
    'london': ['big ben','fuse'],'paris': ['eiffel tower','notre dame','louvre'],'manhattan': ['new york','new york city','nyc','empire state','wall street',],'rome': ['colosseum','roma','spanish steps','pantheon','sistine chapel','vatican'],'berlin': ['berghain','berlin wall'],}

def main(city: str,num_songs: int) -> List[Dict[str,Any]]:
    if city in CITY_KEY_WORDS:
        """Searches Spotify for songs that are about `city`. Returns at most `num_songs` tracks."""
        results = []
        # Search for songs that have `city` in the title
        results += sp.search(city,limit=50)['tracks']['items']  # 50 is the maximum Spotify's API allows
        # Search for songs that have key words associated with `city`
        if city.lower() in CITY_KEY_WORDS.keys():
            for related_term in CITY_KEY_WORDS[city.lower()]:
                results += sp.search(related_term,limit=50)['tracks']['items']
        # Shuffle the results so that they are not ordered by key word and return at most `num_songs`
        shuffle(results)
        return results[: num_songs]
    else:
        print("Unfortunately,this city is not yet in our system. We will add it to our requests file.")
        with open('requests.txt','r') as text_file:
            request = text_file.read()
        request = request + city + '\n'
        with open('requests.txt','w+') as text_file:
            text_file.write(request)

def display_tracks(tracks: List[Dict[str,Any]]) -> None:
    """Prints the name,artist and URL of each track in `tracks`"""
    for num,track in enumerate(tracks):
        # Print the relevant details
        print(f"{num + 1}. {track['name']} - {track['artists'][0]['name']} {track['external_urls']['spotify']}")
if __name__ == '__main__':
    city = input("Virtual holiday city? ")
    number_of_songs = input("How many songs would you like? ")
    tracks = main(city,int(number_of_songs))
    display_tracks(tracks)

对于“ if”语句,该代码运行良好(如果有人进入我们列出的城市)。 但是在运行else语句时,在执行完确定的操作后会出现2个错误(它将打印用户的输入并将其写入文件)。

出现的错误是:

Traceback (most recent call last):
  File "...",line 48,in <module>
    display_tracks(tracks)
  File "...",line 41,in display_tracks
    for num,track in enumerate(tracks):
TypeError: 'NoneType' object is not iterable

请原谅我缺乏知识,但是请有人可以帮助解决这个问题吗?

我们也想在最后创建歌曲的播放列表,但是在此方面一直面临困难。

解决方法

在执行if语句时,您将返回一个项目列表,并将其馈送到display_tracks()函数中。但是执行else语句后会发生什么?您可以将请求添加到文本文件中,但不返回任何内容(或NoneType项目)并将其输入display_tracks()中。 display_tracks然后对此NoneType项进行迭代,并引发异常。

您只想在实际有任何曲目要显示的情况下显示曲目。一种实现方法是将对display_tracks()的调用移到您的main函数中,但是如果未在搜索条件中找到任何曲目,则会引发相同的错误。另一个解决方案是首先检查您的tracks是否为空,或者使用类似的

捕获TypeError异常。
tracks = main(city,int(number_of_songs))
try:
    display_tracks(tracks)
except TypeError:
    pass
,

您的main函数在return子句中没有else语句,这导致tracksNone。导致错误的是在tracks上对None进行迭代。 您可以采取一些措施来改善代码:

  • 关注点分离:main函数正在做两种不同的事情,检查输入并获取轨道。
  • 一开始只做一次.lower(),所以您不必重复。
  • 遵循文档约定。
  • 在使用前检查响应
  • 一些代码清除

请参见下面我上面建议的更改:

def fetch_tracks(city: str,num_songs: int) -> List[Dict[str,Any]]:
    """Searches Spotify for songs that are about `city`.

    :param city: TODO: TBD
    :param num_songs:  TODO: TBD
    :return: at most `num_songs` tracks.
    """
    results = []
    for search_term in [city,*CITY_KEY_WORDS[city]]:
        response = sp.search(search_term,limit=50)
        if response and 'tracks' in response and 'items' in response['tracks']:
            results += response['tracks']['items']
    # Shuffle the results so that they are not ordered by key word and return
    # at most `num_songs`
    shuffle(results)
    return results[: num_songs]


def display_tracks(tracks: List[Dict[str,Any]]) -> None:
    """Prints the name,artist and URL of each track in `tracks`"""
    for num,track in enumerate(tracks):
        # Print the relevant details
        print(
            f"{num + 1}. {track['name']} - {track['artists'][0]['name']} "
            f"{track['external_urls']['spotify']}")


def main():
    city = input("Virtual holiday city? ")
    city = city.lower()
    # Check the input city and handle unsupported cities.
    if city not in CITY_KEY_WORDS:
        print("Unfortunately,this city is not yet in our system. "
              "We will add it to our requests file.")
        with open('requests.txt','a') as f:
            f.write(f"{city}\n")
        exit()

    number_of_songs = input("How many songs would you like? ")
    tracks = fetch_tracks(city,int(number_of_songs))
    display_tracks(tracks)


if __name__ == '__main__':
    main()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-