Alina
Alina

Reputation: 31

chart.render_to_file('python_repos.svg')AttributeError: 'NoneType' object has no attribute 'decode'

I'm learning python with the book: "Python Crash Course: A Hands-On, Project-Based Introduction to Programming". In chapter 17 of the book "Working with APIs", I did as the book says, but an error is occurring. I don't know what the error means. Does that mean there is something wrong with the site-packages? How to fix it?

import requests
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS

# Make an API call, and store the response.
url = 'https://api.github.com/search/repositories?q=language:python&sort=stars'
r = requests.get(url)
print("Status code:", r.status_code)

# Store API response in a variable.
response_dict = r.json()
print("Total repositories:", response_dict['total_count'])

# Explore information about the repositories.
repo_dicts = response_dict['items']

names, plot_dicts = [], []
for repo_dict in repo_dicts:
    names.append(repo_dict['name'])

    plot_dict = {
        'value': repo_dict['stargazers_count'],
        'label': repo_dict['description'],
        }
    plot_dicts.append(plot_dict)

# Make visualization.
my_style = LS('#333366', base_style=LCS)

my_config = pygal.Config()
my_config.x_label_rotation = 45
my_config.show_legend = False
my_config.title_font_size = 24
my_config.label_font_size = 14
my_config.major_label_font_size = 18
my_config.truncate_label = 15
my_config.show_y_guides = False
my_config.width = 1000

chart = pygal.Bar(my_config, style=my_style)
chart.title = 'Most-Starred Python Projects on GitHub'
chart.x_labels = names

chart.add('', plot_dicts)
chart.render_to_file('python_repos.svg')

the error is below

Status code: 200
Total repositories: 2198954
Traceback (most recent call last):
  File "2018-07-13-1.py", line 45, in <module>
    chart.render_to_file('python_repos.svg')
  File "C:\Users\Administrator\AppData\Roaming\Python\Python35\site-packages\pygal\graph\public.py", line 114, in render_to_file
    f.write(self.render(is_unicode=True, **kwargs))
  File "C:\Users\Administrator\AppData\Roaming\Python\Python35\site-packages\pygal\graph\public.py", line 52, in render
    self.setup(**kwargs)
  File "C:\Users\Administrator\AppData\Roaming\Python\Python35\site-packages\pygal\graph\base.py", line 217, in setup
    self._draw()
  File "C:\Users\Administrator\AppData\Roaming\Python\Python35\site-packages\pygal\graph\graph.py", line 933, in _draw
    self._plot()
  File "C:\Users\Administrator\AppData\Roaming\Python\Python35\site-packages\pygal\graph\bar.py", line 146, in _plot
    self.bar(serie)
  File "C:\Users\Administrator\AppData\Roaming\Python\Python35\site-packages\pygal\graph\bar.py", line 116, in bar
    metadata)
  File "C:\Users\Administrator\AppData\Roaming\Python\Python35\site-packages\pygal\util.py", line 233, in decorate
    metadata['label'])
  File "C:\Users\Administrator\AppData\Roaming\Python\Python35\site-packages\pygal\_compat.py", line 61, in to_unicode
    return string.decode('utf-8')
AttributeError: 'NoneType' object has no attribute 'decode'

Upvotes: 3

Views: 1749

Answers (2)

Oussama Elourdi
Oussama Elourdi

Reputation: 1

H=''
names, plot_dicts = [],[]

for repo_dict in repo_dicts:
   names.append(repo_dict['name'])

   if repo_dict['description']is not None:
      H = repo_dict['description']

   plot_dict = {
        'value': repo_dict['stargazers_count'],
        'label':H,  
            }

   plot_dicts.append(plot_dict) 

Upvotes: 0

mostlyoxygen
mostlyoxygen

Reputation: 991

The error is caused by one of the labels you're setting on the chart being None, which is one of Python's special built-in constants. When pygal comes to render the chart it expects the label to be a string and calls the decode function. This function doesn't exist on a None object, so the error is raised.

Looking at the name and descriptions of the Github repositories (which you're setting as the x labels and data labels, respectively) we can see that the description for one of the repositories is None. I wouldn't say there is anything particularly wrong with the code from the book, it's just bad luck that one of the most starred Python repositories at this moment in time has no description.

We can work around this by checking for None values in the for loop:

for repo_dict in repo_dicts:

    if repo_dict['name'] is None:
        names.append('')  # Empty string.
    else:
        names.append(repo_dict['name'])

    plot_dict = {'value': repo_dict['stargazers_count']}
    if repo_dict['description'] is not None:
        plot_dict['label'] = repo_dict['description']

    plot_dicts.append(plot_dict)

In the first part we've added an empty string in place of any None values (because you'll need something there when you set the x labels).

In the second part we've created the dict with just the value, then added the description as a label only if the description is not None.

Upvotes: 1

Related Questions