Python beginner has some problems with the spotipy search function - python-3.x

i am trying to set up a basic tool which is supposed to do following:
1. Search for Musicans in Spotify
2. Print results in a way i can use them for stuff (e.g. show output in a window or something like that)
Unfortunatly i cant wrap my head around following Problem:
import spotipy
import sys
from spotipy.oauth2 import SpotifyClientCredentials
client_credentials_manager = SpotifyClientCredentials(client_id='',
client_secret='')
spotify = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
result = spotify.search(q='Korn', limit=5)
for i, t in enumerate(result['tracks']['items']): # way i dont understand
print (' ', i, t['name'])
print(result) #way i would like to do it
The code can print a list in this enumerate fashion but isnt capable of printing it normally. The thing is I dont understand the way enumerate does this.
Can someone please give me some insights how the search function and enumerate work and maybe show me an elegant solution so i can print this list?

I don't know about the spotipy module so I'll have to assume a few things, based on what you said works or doesn't work.
So... your variable named 'result' seems to behave like a dictionary. You can index it with keys ('tracks', 'items'), (as shown there: result['tracks']['items']), and this seems to give you back stuff that behaves like a list containing stuff that behaves like a dictionary, that among other things contains the key 'name' (as shown there: t['name']).
To illustrate how enumerate works, here's an example:
>>> hello = ['h', 'e', 'l', 'l', 'o']
>>> print(list(enumerate(hello)))
[(0, 'h'), (1, 'e'), (2, 'l'), (3, 'l'), (4, 'o')]
It essentially gives you back tuples of each index in the list, and what is at that index.
Also note that Python has a principle called 'duck-typing'. It says that “If it looks like a duck and quacks like a duck, it must be a duck.”. That's why I don't worry to much about what type an object is, what I care about is what it behaves like.
Now, when you say something like:
for index, element in enumerate(elements):
You're using what's called unpacking. It lets you separate the tuples that enumerate gives you into two variables.
Then if we wanted to simply do print(result), the class that let you instantiate result would need to implement either the __repr__ or __str__ methods. In it, you would have all the logic that's contained in your for loop, grabbing the data at the appropriate keys in the dictionary-like object and returning a correctly formatted string. But it looks like this class comes from an external library, so I'm not sure it would be a good idea to implement these yourself (I don't have experience doing that yet).
Hope that my explanations were at least a little bit helpful.

Related

ADF Dynamic Expression - concat/if missing period

In what I would have thought was relatively simple code, I can't figure out what the issue is with adding another string to my list of concatenations
Below is the code that I currently have and I get expected output
#concat('start ', if(equals(coalesce(pipeline().parameters.p_source_object.TYPE,''),'x'), 'a', 'b'))
However, I want to add more strings to the concatenation but when I add a comma between the two end brackets like so
#concat('start ', if(equals(coalesce(pipeline().parameters.p_source_object.TYPE,''),'x'), 'a', 'b'), )
I get an "Invalid" error with "Missing period" message. If I put a period before the comma, the error goes away (but obviously invalid syntax)
What is it expecting here?
On a related note, is there a better way to concatenate while also doing some functions that output strings? It's the most unintuitive interface imaginable (Microsoft do seem to pride themselves in the ridiculous!)
Hoping someone can find my sanity for me!
In the end, I completely reworked it avoiding the layers... however, I have discovered a resolution
#{concat('start ', if(equals(coalesce(pipeline().parameters.p_source_object.TYPE,''),'x'), 'a', 'b'), 'dd')}
While it doesn't stand out as to how... there's a space at the start of the line, this stops it being considered "Dynamic content" but instead uses string interpolation

How to get substring keys on firebase?

I'm working with firebase on pyhon3. I wanted to know if there's a way I can check if a substring is present in the firebase keys. For e.g. if I have a string 'he', and I have keys in my firebase for 'hell' and 'hello'. I can perform a get for 'he', but how can I get the others as well. And i dont want to get the entire parent and search on python as it is a fairly large database.
How can I go about to get them? I know this is not how firebase is designed. But remodeling will take a lot of time. So can it be done, and if so how?
Try using in like this:
>>> x = 'hello'
>>> y = 'll'
>>> y in x
True
So if you have a value you can assign, and you know what you want to check against, this is the easiest way to go about this in Python.

Python3: Building dictionary from .fasta - "strange" printout for value

I am parsing a .fasta-File containing one big sequence into python by using:
for rec in SeqIO.parse(faFile, "fasta"):
identifier=(rec.id)
sequence=(rec.seq)
Then, I am building a dictionary:
d={identifier:sequence}
When printing sequence only, I get the following result:
CAGCCAGATGGGGGGAGGGGTGAGCGCTCTCCCGCTCAAAACCTCCAGCACTTT...CAT
Note: All letters are printed, I made dots to shorten this
When printing the dictionary, I get:
{'NC_003047.1': Seq('CAGCCAGATGGGGGGAGGGGTGAGCGCTCTCCCGCTCAAAACCTCCAGCACTTT...CAT', SingleLetterAlphabet())}
Where does the "Seq" and the SingleLetter alphabet come from?
Desired result would be:
{'NC_003047.1':'CAGCCAGATGGGGGGAGGGGTGAGCGCTCTCCCGCTCAAAACCTCCAGCACTTT...CAT'}
Update1:
following the link in the comments, I tried
input_file=open(faFile)
d=SeqIO.to_dict(SeqIO.parse(faFile,"fasta"))
resulting in:
{'NC_003047.1': SeqRecord(seq=Seq('CAGCCAGATGGGGGGAGGGGTGAGCGCTCTCCCGCTCAAAACCTCCAGCACTTT...CAT', SingleLetterAlphabet()), id='NC_003047.1', name='NC_003047.1', description='NC_003047.1 Sinorhizobium meliloti 1021 chromosome, complete genome', dbxrefs=[])}
So, sadly, this does not help :(
Thanks in advance for your time and effort :)
SeqIO doesn't return a string, it returns an object. When you print it, you print the object's string representation, which in this case is not just the data contained in (some attribute of) the object.
(Some objects are designed so that printing the object will print just the data inside it. This depends on how the library is put together and how the programmer designed its __str__() method. This is probably not useful for you at this point, but might help you understand other related resources you find if you pursue this further.)
I'm not familiar with SeqIO but quick googling suggests you probably want
d={identifier: sequence.seq}
to put just the SeqIO object's seq attribute as the value for this identifier.

Where can I find an overview of how the ec2.instancesCollection is built

In boto3 there's a function:
ec2.instances.filter()
The documentation:
http://boto3.readthedocs.org/en/latest/reference/services/ec2.html#instance
Say it returns a list(ec2.Instance) I wish...
when I try printing the return I get this:
ec2.instancesCollection(ec2.ServiceResource(), ec2.Instance)
I've tried searching for any mention of an ec2.instanceCollection, but the only thing I found was something similar for ruby.
I'd like to iterate through this instanceCollection so I can see how big it is, what machines are present and things like that.
Problem is I have no idea how it works, and when it's empty iteration doesn't work at all(It throws an error)
The filter method does not return a list, it returns an iterable. This is basically a Python generator that will produce the desired results on demand in an efficient way.
You can use this iterator in a loop like this:
for instance in ec2.instances.filter():
# do something with instance
or if you really want a list you can turn the iterator into a list with:
instances = list(ec2.instances.filter())
I'm adding this answer because 5 years later I had the same question and went round in circles trying to find the answer.
First off, the return type in the documentation is wrong (still). As you say, it states that the return type is: list(ec2.Instance)
where it should be:ec2.instancesCollection.
At the time of writing there's an open issue in github covering this - https://github.com/boto/boto3/issues/2000.
When you call the filter method a ResourceCollection is created for the particular type of resource against which you called the method. In this case the resource type is instance which gives an instancesCollection. You can see the code for the ResourceCollection superclass of instancesCollection here:
https://github.com/boto/boto3/blob/develop/boto3/resources/collection.py
The documentation here gives an overview of the collections: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/collections.html
To get to how to use it and actually answer your question, what I did was to turn the iterator into a list and iterate over the list if the size is > 0.
testList = list(ec2.instances.filter(Filters=filters))
if len(testList) > 0;
for item in testList;
.
.
.
This may well not be the best way of doing it but it worked for me.

Python 3/ PyGame: Surfaces Reference / Handling (former title: Strange behaviour of copied dictionaries)

Technical background: Python 3.4 + PyGame 1.9.2 on a Win XP system.
IMPORTANT
The original title was misleading as it turned out that is has NOTHING to do with how Python dictionaries work! It was just a coincidence it happened with a dictionary. I quickly explain the problem, hoping it will be useful to somebody in the future.
There are two dictionaries representing the two players' "boards" (it's kind of a battleship/sea battle as computer game) containing position-tuples (x, y) as keys and surfaces as keys' content. Some Pseudo-Code for clarification:
surface1 = pygame.Surface((w, h)).convert()
surface1.fill(WATER_COLOUR)
dict1 = {(x1, y1): surface1.copy(), (x2, y2): surface1.copy(), (x3, y3): surface1.copy()}
dict2 = dict1.copy()
In the course of the game the players would click on the display and if they'd hit a valid game field, that field would change its colour depending on whether a ship has been hit or not.
def clicked(mousepos, key):
if active_player == 1:
if mousepos_inside_enemy_ship_rectangle(mousepos):
dict1[position_of_mouse].fill((255, 0, 0)) # Make it red
else:
dict1[position_of_mouse].fill((0, 0, 0)) # Make it black
To my surprise ALL the square-surfaces would change their colour in both dictionaries! I first thought, it's a problem with the dictionary, until I found out, that it's a problem with how surfaces work in PyGame.
It seems that all surface1.copy() refer to one single copy of surface1. So to say: if I change one of the copies, all the others look the same, they do not really copy it, they just reference it!
Two solutions there are:
Create a surface for each state: one for "not clicked yet", one for "clicked but missed" and one for "clicked and hit". Then change the dictionaries key to the respective surface.
Create an individual surface for each key in the dictionary and then fill them with the respective colours individually. That also works.
Thanks to everybody who tried to resolve it and sorry for the trouble... It's a completely different problem. I updated the title and the keywords, hoping it helps somebody else in the future. I left the old question text for reference. And whoever added the link to that other dictionary question: Please remove it, it's not about dictionaries but surfaces, thanks!
Pat
OLD QUESTION TEXT Left for reference
My script has a function f() returning a dictionary:
def f(data):
d = {}
for n in range(len(data)):
d.update({n: data[n]})
return d
I need two dictionaries starting with the precisely same data, so I can modify these data in different ways.
dict1 = f(data)
dict2 = dict1.copy()
To my surprise, when I modify dict1 the same changes are also shown by dict2! I thought the copy would be independent from the original - have I misunderstood something?
It has definitely something to do with the .copy() method. When I change my code like this:
dict1 = f(data)
dict2 = f(data)
I receive precisely what I wanted and I can modify both dictionaries differently without interfering with each other.
Basically this solves my problem but it raises a number of questions... Have I misunderstood what .copy() does? Is this a general issue in this Python version?
//edit:
To clarify what I mean by "modify":
Some of the keys' data in dict1 is changed, if the keys meet a certain condition:
for key in dict1:
if key == meets_this_condition:
dict1[key] = new_data
In another method I constantly compare the contents of the two dictionaries and call certain functions depending on them either being the same or being different
for key in dict1:
if dict1[key] == dict2[key]:
do_something()
else:
do_something_else()
Thanks for any insights!
Pat
I would try use deepcopy function something like
dict2=copy.deepcopy(dict1);
import the copy library
as I remember .copy make a shallow copy so it only copy pointers. so if you modified one in some cases the copy also would be change.

Resources