I'm trying to get my youtube statistics from Youtube Data API, and then put all the statistics on an image.
When I'm trying to pass the arguments to my image maker function,
# vid_stats and c_stats are dictionaries,
# but in them, there's no "video_title" key or anything
statimager.create_image(video_title="Video title", video_stats=vid_stats, channel_stats=c_stats)
it gives me this TypeError:
Traceback (most recent call last):
File "D:\_Prog\Python\ytstatupdater\ytstatupdater.py", line 118, in <module>
statimager.create_image(video_title="Video title", video_stats=vid_stats, channel_stats=c_stats)
TypeError: create_image() got multiple values for argument 'video_title'
And here's the definition of create_image() function:
def create_image(video_title, video_stats, channel_stats):
In this function, I only use these arguments to put the video_title, and the strings in video_stats and channel_stats to a string array.
I don't really understand why does the program wants to pass multiple values as video_title, as video_title is a single string object.
I'm working in Python 3.9.1.
So in the comments, #ted-klein-bergman mentioned that I forgot to put self in the definition as first parameter.
I've put that in the definition and it works now.
This is the code I have designed as of now.
import sys #so that later on I can exit easily
CoinCountData = open("CoinCountData.txt","r")
class Volunteer:
def __init__(self,name,coin_type,weight_of_bag,TrueCount):
self.name = (name)
self.coin_type = (coin_type) #a function allowing me to class the data
self.weight_of_bag = (weight_of_bag)
self.TrueCount = (TrueCount)
I also have a little test part of data which is an attempt to make the second row of my txt file into a class
volunteer1 = Volunteer(CoinCountData.readlines()[1])
however, I am prompted with the following message.
Traceback (most recent call last):
File "C:\Users\Owner\Desktop\CW\!Coincount\coincount.py", line 14, in <module>
volunteer1 = Volunteer(CoinCountData.readlines()[1])
TypeError: __init__() missing 3 required positional arguments: 'coin_type', 'weight_of_bag', and 'TrueCount'
I do not understand how to actually class this data. It seems that it thinks that the entire thing is a name, I figured out that that is what the problem is by changing the code for an experiment:
import sys #so that later on I can exit easily
CoinCountData = open("CoinCountData.txt","r")
class Volunteer:
def __init__(self,name):
self.name = (name)
volunteer1 = Volunteer(CoinCountData.readlines()[1])
print(volunteer1.name)
When I ran the program it printed the entire line (Malcolm,1p,3356.00,Y)
Just for context, this is for my project for making a coin counter, the data given to me for the coin counting is as follows:
Abena,5p,325.00,Y
Malcolm,1p,3356.00,Y
Jane,£2,120.00,Y
Andy,£1,166.25,N
Sandip,50p,160.00,Y
Liz,20p,250.00,Y
Andy,20p,250.00,Y
Andy,50p,160.00,Y
Jane,£1,183.75,N
Liz,£,179.0,N
Liz,50p,170.0,N
Jane,50p,160.0,Y
Sandip,£1,183.0,N
Jane,£2,132.0,N
Abena,1p,3356.0,N
Andy,2p,250.0,N
Abena,£1,175.0,Y
Malcolm,50p,160.0,Y
Malcolm,£2,175.0,N
Malcolm,£1,175.0,Y
Malcolm,1p,356.0,Y
Liz,20p,250.0,Y
Jane,£2,120.0,Y
Jane,50p,160.0,Y
Andy,£1,175.0,Y
Abena,1p,359.56,N
Andy,5p,328.5,N
Andy,£2,108.0,N
Malcolm,£2,12.0,N
The data is listed vertically so it shows Abena,5p,325.00,Y and then below is Malcolm,1p,3356.00,Y etc
I understand the issue that the commas within the text file do not work as actual legitimate commas within python, I am not allowed to change the actual text file either so please let me know how I can make a full class which inputs all variables.
You should be iterating over the open file and splitting each line to provide the required parameters:
class Volunteer:
def __init__(self,name,coin_type,weight_of_bag,TrueCount):
self.name = name
self.coin_type = coin_type #a function allowing me to class the data
self.weight_of_bag = weight_of_bag
self.TrueCount = TrueCount
with open("CoinCountData.txt","r") as CoinCountData:
volunteers = []
for line in CoinCountData
volunteers.append(Volunteer(*line.strip().split(',')))
The error message you get is pretty straightforward.
Traceback (most recent call last): File "C:\Users\Owner\Desktop\CW!Coincount\coincount.py", line 14, in volunteer1 = Volunteer(CoinCountData.readlines()[1]) TypeError: init() missing 3 required positional arguments: 'coin_type', 'weight_of_bag', and 'TrueCount
It basically tells you that 3 parameters are missing when you're instanciating your Volunteer object : coin_type, weight_of_bag and TrueCount (which by the way should be named true_count to be consistent with the rest of your parameters).
Now, if you take a closer look at your code :
class Volunteer:
def __init__(self,name,coin_type,weight_of_bag,TrueCount):
...
You see here that when instanciating your Volunteer object, you need to give it 4 parameters : name, coin_type, weight_of_bag and TrueCount (self does not count as a parameter you need to provide).
Now, when you're instanciating your object, you do as follow :
volunteer1 = Volunteer(CoinCountData.readlines()[1])
You only give one parameter (that is, name). You also need to provide values for coin_type, weight_of_bag and TrueCount parameters.
It should look like something like that:
volunteer1 = Volunteer(CoinCountData.readlines()[1], "some coin type", 42, 14)
where name has the value of CoinCountData.readlines()[1], coin_type has the value some coin type and so on.
Readlines
I think you'll go into some more issues afterward, as your usage of readlines() seems incorrect in your case.
The readlines() method returns a list containing each line in your file (https://docs.python.org/3/distutils/apiref.html?highlight=readlines#distutils.text_file.TextFile.readlines).
So you will need a loop somewhere to loop over each line if you want to do it the way you've started.
CSV
The data file you're working with is a CSV (comma separated values). It means each line is a data entry, with each value separated by a comma.
You should have a look on the Python doc on how to read an CSV file : https://docs.python.org/3.6/library/csv.html
readlines returns a list of strings, each of the strings representing a line from the file.
You need to split the lines into their components, which you could do using
CoinCountData.readlines()[1].split(',')
You could then use argument unpacking to create an instance of the Volunteer class:
Volunterr(*CoinCountData.readlines()[1].split(','))
Note the asterisk (*).
Python obviously does not allow the same keyword to appear multiple times in function arguments. Here are 2 code samples to show that point:
def foo(a=None, **kwargs):
pass
Calling this code to produce a SyntaxError:
>>> # Example 1
>>> foo(a=1, a=1)
File "<stdin>", line 1
SyntaxError: keyword argument repeated
Calling this code to produce a TypeError:
>>> # Example 2
>>> foo(1, a=123)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() got multiple values for argument 'a'
Intuitively, I would expect both examples to raise SyntaxErrors.
Why does the first method produce a SyntaxError while the second method produces a TypeError?
From here:
Syntax errors are the most basic type of error. They arise when the Python parser is unable to understand a line of code.
So foo(a=1, a=1) is an invalid python code, while foo(1, a=123) by itself without escope context is a valid python code, thus syntax error is not raised. However, after the code gets parsed, the interpretation of it given the current context fails because the signature of the foo function defined before confuses the interpreter since you have multiple definitions for a.
I can say that it's not a KeyError because you don't have an explicitly dictionary involved. You are passing key words arguments but a dictionary was never created and KeyError is Raised when a mapping (dictionary) key is not found in the set of existing keys. Additionally, from the documentation you linked in the comment, I would say that it's a TypeError because it involves the parsing of the arguments in a function call. But I'm not so sure. Nevertheless, the RuntimeError is a generic exception when no one of the other exceptions fit but the interpreter detected an error.
I'm just getting started with HarfBuzz, and have switched to using the GObject Introspection interface to explore its API. Everything has been easy so far, but I'm a bit confused with language_from_string, which has the following docstring:
language_from_string(str:list) -> HarfBuzz.language_t
i.e. in IPython, I do:
from gi.repository import HarfBuzz
?HarfBuzz.language_from_string
in vanilla Python, you can replace the last line with: print(HarfBuzz.language_from_string.__doc__) (or similar)
if I call this method with a string, e.g:
HarfBuzz.language_from_string('en')
I get
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Item 0: Must be number, not str
back, while if I convert to a list of code points first:
en = HarfBuzz.language_from_string(list(map(ord, 'en')))
the error goes away, and I get something useful back. e.g. I can do:
HarfBuzz.language_to_string(en)
and I get the expected en back, in a string.
HarfBuzz Issue #91 is about this method, but doesn't seem to be relevant.
You have to call it like HarfBuzz.language_from_string(b'en') (string but prefixed with b) in python3 as strings are not just sequence of bytes anymore in py3 unlike py2.
Do you know any gi API that gets an actual python representation of string in python3? If so let me know otherwise this is expected from HarfBuzz side.
Whenever a Python function is called with missing named arguments, it produces a runtime error that lists the number of missing arguments:
TypeError: getVolume() takes exactly 3 arguments (2 given)
However, this doesn't tell me which specific arguments are missing. This runtime error message would be much more informative if it actually printed the names of the missing arguments, instead of just printing the number of arguments that are missing. This is especially important when working with functions that accept a large number of arguments: it's not always easy to remember the name of every single argument that is missing.
In general, is it possible to modify Python functions so that they will print the names of the missing arguments whenever arguments are missing?
def getVolume(length, width, height):
return length*width*height;
print(getVolume(height=3, width=3));
This has changed in Python3.3 (at most), you get the missing argument names for free:
>>> def getVolume(length, width, height):
... return length*width*height;
...
>>> print(getVolume(height=3, width=3));
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: getVolume() missing 1 required positional argument: 'length'