Understanding why this python code works randomly - python

I'm coding a little script that gets metadata from a sound file and creates a string with the desired values. I know I'm doing something wrong but I ain't sure why, but it's probably the way I am iterating the if's. When I run the code :
import os, mutagen
XPATH= "/home/xavier/Code/autotube/tree/def"
DPATH="/home/xavier/Code/autotube/tree/down"
def get_meta():
for dirpath, directories,files in os.walk(XPATH):
for sound_file in files :
if sound_file.endswith('.flac'):
from mutagen.flac import FLAC
metadata = mutagen.flac.Open(os.path.join(dirpath,sound_file))
for (key, value) in metadata.items():
#print (key,value)
if key.startswith('date'):
date = value
print(date[0])
if key.startswith('artist'):
artist = value
#print(artist[0])
if key.startswith('album'):
album = value
#print(album[0])
if key.startswith('title'):
title = value
#print(title[0])
build_name(artist,album,title) # UnboundLocalError gets raised here
def build_name(artist,album,title):
print(artist[0],album[0],title[0])
I get the desired result or an error, randomly :
RESULT :
1967 Ravi Shankar & Yehudi Menuhin West Meets East Raga: Puriya Kalyan
ERROR :
Traceback (most recent call last):
File "<stdin>", line 39, in <module>
File "<stdin>", line 31, in get_meta
build_name(artist,album,title)
UnboundLocalError: local variable 'album' referenced before assignment

If "title" comes before "album" in the meta data then album will never be initialised. "album" may not exist at all.
As you don't blank out the value of album for each track, if a track has previously had "album" defined then the next track which doesn't define "album" will use the previous track's value.
Give it a blank value for each track (if that's reasonable to you).
Looking at build_name the values are lists of strings, so the default should be ['']:
for sound_file in files:
artist = album = title = ['']
However, you will still not get values before calling build_name if the metadata is out of order.
You need to move build_name(artist, album, title) out of the loop:
for (key, value) in metadata.items():
... # searching metadata
build_name(artist, album, title)

Related

How to fill a column of type 'multi-select' in notion-py(Notion API)?

I am trying to create a telegram-bot that will create notes in notion, for this I use:
notion-py
pyTelegramBotAPI
then I connected my notion by adding token_v2, and then receiving data about the note that I want to save in notion, at the end I save a note on notion like this:
def make_notion_row():
collection_view = client.get_collection_view(list_url[temporary_category]) #take collection
print(temporary_category)
print(temporary_name)
print(temporary_link)
print(temporary_subcategory)
print(temporary_tag)
row = collection_view.collection.add_row() #make row
row.ssylka = temporary_link #this is link
row.nazvanie_zametki = temporary_name #this is name
if temporary_category == 0: #this is category, where do I want to save the note
row.stil = temporary_subcategory #this is subcategory
tags = temporary_tag.split(',') #temporary_tags is text that has many tags separated by commas. I want to get these tags as an array
for tag_one in tags:
**add_new_multi_select_value("Теги", tag_one): #"Теги" is "Tag column" in russian. in this situation, tag_one takes on the following values: ['my_hero_academia','midoria']**
else:
row.kategoria = temporary_subcategory
this script works, but the problem is filling in the Tags column which is of type multi-select.
Since in the readme 'notion-py', nothing was said about filling in the 'multi-select', therefore
I used the bkiac function:https://github.com/jamalex/notion-py/issues/51
here is the slightly modified by me ​function:
art_tags = ['ryuko_matoi', 'kill_la_kill']
def add_new_multi_select_value(prop, value, style=None):
​global temporary_prop_schema
​if style is None:
​style = choice(art_tags)
​collection_schema = collection_view.collection.get(["schema"])
​prop_schema = next(
​(v for k, v in collection_schema.items() if v["name"] == prop), None
​)
​if not prop_schema:
​raise ValueError(
​f'"{prop}" property does not exist on the collection!'
​)
​if prop_schema["type"] != "multi_select":
​raise ValueError(f'"{prop}" is not a multi select property!')
​dupe = next(
​(o for o in prop_schema["options"] if o["value"] == value), None
​)
​if dupe:
​raise ValueError(f'"{value}" already exists in the schema!')
​temporary_prop_schema = prop_schema
​prop_schema["options"].append(
​{"id": str(uuid1()), "value": value, "style": style}
​)
​collection.set("schema", collection_schema)`
But it turned out that this function does not work, and gives the following error:
add_new_multi_select_value("Теги","my_hero_academia)
Traceback (most recent call last):
​File "<pyshell#4>", line 1, in <module>
​add_new_multi_select_value("Теги","my_hero_academia)
​File "C:\Users\laere\OneDrive\Documents\Programming\Other\notion-bot\program\notionbot\test.py", line 53, in add_new_multi_select_value
​collection.set("schema", collection_schema)
​File "C:\Users\laere\AppData\Local\Programs\Python\Python39-32\lib\site-packages\notion\records.py", line 115, in set
​self._client.submit_transaction(
​File "C:\Users\laere\AppData\Local\Programs\Python\Python39-32\lib\site-packages\notion\client.py", line 290, in submit_transaction
​self.post("submitTransaction", data)
​File "C:\Users\laere\AppData\Local\Programs\Python\Python39-32\lib\site-packages\notion\client.py", line 260, in post
​raise HTTPError(
requests.exceptions.HTTPError: Unsaved transactions: Not allowed to edit column: schema
this is my table image: link
this is my telegram chatting to bot: link
Honestly, I don’t know how to solve this problem, the question is how to fill a column of type 'multi-select'?
I solved this problem using this command
row.set_property("Категория", temporary_subcategory)
and do not be afraid if there is an error "options ..." this can be solved by adding settings for the 'multi-select' field.

Pandoc Filter via Panflute not Working as Expected

Problem
For a Markdown document I want to filter out all sections whose header titles are not in the list to_keep. A section consists of a header and the body until the next section or the end of the document. For simplicity lets assume that the document only has level 1 headers.
When I make a simple case distinction on whether the current element has been preceeded by a header in to_keep and do either return None or return [] I get an error. That is, for pandoc --filter filter.py -o output.pdf input.md I get TypeError: panflute.dump needs input of type "panflute.Doc" but received one of type "list" (code, example file and complete error message at the end).
I use Python 3.7.4 and panflute 1.12.5 and pandoc 2.2.3.2.
Question
If make a more fine grained distinction on when to do return [], it works (function action_working). My question is, why is this more fine grained distinction neccesary? My solution seems to work, but it might well be accidental... How can I get this to work properly?
Files
error
Traceback (most recent call last):
File "filter.py", line 42, in <module>
main()
File "filter.py", line 39, in main
return run_filter(action_not_working, doc=doc)
File "C:\Users\ody_he\AppData\Local\Continuum\anaconda3\lib\site-packages\panflute\io.py", line 266, in run_filter
return run_filters([action], *args, **kwargs)
File "C:\Users\ody_he\AppData\Local\Continuum\anaconda3\lib\site-packages\panflute\io.py", line 253, in run_filters
dump(doc, output_stream=output_stream)
File "C:\Users\ody_he\AppData\Local\Continuum\anaconda3\lib\site-packages\panflute\io.py", line 132, in dump
raise TypeError(msg)
TypeError: panflute.dump needs input of type "panflute.Doc" but received one of type "list"
Error running filter filter.py:
Filter returned error status 1
input.md
# English
Some cool english text this is!
# Deutsch
Dies ist die deutsche Übersetzung!
# Sources
Some source.
# Priority
**Medium** *[Low | Medium | High]*
# Status
**Open for Discussion** *\[Draft | Open for Discussion | Final\]*
# Interested Persons (mailing list)
- Franz, Heinz, Karl
fiter.py
from panflute import *
to_keep = ['Deutsch', 'Status']
keep_current = False
def action_not_working(elem, doc):
'''For every element we check if it occurs in a section we wish to keep.
If it is, we keep it and return None (indicating to keep the element unchanged).
Otherwise we remove the element (return []).'''
global to_keep, keep_current
update_keep(elem)
if keep_current:
return None
else:
return []
def action_working(elem, doc):
global to_keep, keep_current
update_keep(elem)
if keep_current:
return None
else:
if isinstance(elem, Header):
return []
elif isinstance(elem, Para):
return []
elif isinstance(elem, BulletList):
return []
def update_keep(elem):
'''if the element is a header we update to_keep.'''
global to_keep, keep_current
if isinstance(elem, Header):
# Keep if the title of a section is in too keep
keep_current = stringify(elem) in to_keep
def main(doc=None):
return run_filter(action_not_working, doc=doc)
if __name__ == '__main__':
main()
I think what happens is that panflute call the action on all elements, including the Doc root element. If keep_current is False when walking the Doc element, it will be replaced by a list. This leads to the error message you are seeing, as panflute expectes the root node to always be there.
The updated filter only acts on Header, Para, and BulletList elements, so the Doc root node will be left untouched. You'll probably want to use something more generic like isinstance(elem, Block) instead.
An alternative approach could be to use panflute's load and dump elements directly: load the document into a Doc element, manually iterate over all blocks in args and remove all that are unwanted, then dump the resulting doc back into the output stream.
from panflute import *
to_keep = ['Deutsch', 'Status']
keep_current = False
doc = load()
for top_level_block in doc.args:
# do things, remove unwanted blocks
dump(doc)

Don't understand this tkinter.TclError

I can't seem to set (update) the column which I previously created to a value from a function which is called when I click a button, it says Item not found.
curItem = tree.focus()
contents =(tree.item(curItem))
selecteditem = contents['values']
tree.get_children(curItem)
Database()
cursor.execute("SELECT SUM(PRODUCT_QTY) FROM `product` WHERE `product_id` = %d" % selecteditem[0])
fetch = cursor.fetchall()
for data in fetch:
# d = tree.item(data)
tree.set(selecteditem, 3, data)
a = data
conn.commit()
cursor.close()
conn.close()
The Error and traceback:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\.\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py",
line 1705, in __call__ return self.func(*args)
File "c:\Users\.\Desktop\Simple_Inventory PYTHON\Simple Inventory System\index.py",
line 268, in calculate tree.set(selecteditem, 2, data)
File "C:\Users\.\AppData\Local\Programs\Python\Python37-32\lib\tkinter\ttk.py",
line 1482, in set res = self.tk.call(self._w, "set", item, column, value)
_tkinter.TclError: Item 8 e 3 4 not found
NOTE: 8 is the ID of the item, e the name,3 and 4 the price and quantity (dummy values)
For those who may struggle with the same problem, simply putting the curItem instead of selectedItem[0] in the tree.set() parameters fixes it. Just put in the focused tree variable there.
You are setting selecteditem to some values. The argument to tree.set must be an identifier. Like the error says, there is nothing in the tree with an id of 8 e 3 4.
The identifier will be whatever is returned when you called tree.insert. It will either be an indentifier computed for you of the form "IXXX" (eg: I001), or whatever you specified when you called tree.insert.
Since you didn't show how you created the items in the tree it's hard to say what the value should be. It might be enough to use curItem, but from the tiny bit of code you provided it's hard to say for certain.

spss: rename a variable label

I have a list of variable labels I would like to capitalize them
(i.e.) Variable label.
L0K3V "PROBLÈME AVEC VOS ENFANTS"
PK34 "QUEL ÂGE AVIEZ-VOUS?"
ML9KL "RÉPONDANT A-T'IL DÉJA ÉTÉ LÉGALEMENT MARIÉ(E)"
...
program
BEGIN PROGRAM PYTHON.
import spss
spss.StartDataStep()
#current dataset
datasetObj = spss.Dataset()
varcount=spss.GetVariableCount()
#populate a list or all the Variable Label
varNameList= [spss.GetVariableLabel(i) for i in xrange(varcount) ]
labellist=[]
for i in xrange(varcount):
myLabel = spss.GetVariableLabel(i)
newLabel = myLabel.capitalize()
spss.Submit(r""" rename labels (%s = %s) . """ %(myLabel, newLabel))
spss.EndDataStep()
END PROGRAM.
Traceback (most recent call last):
File "<string>", line 22, in <module>
File "C:\PROGRA~1\IBM\SPSS\STATIS~1\22\Python\Lib\site-packages\spss\spss.py", line 1527, in Submit
raise SpssError,error
spss.errMsg.SpssError: [errLevel 98] Submit cannot be used from within a Datastep.
1) You have an error suggesting Submit cannot be used from within a Dataset.
2) VARIABLE LABEL is the correct command to relabel a variable.
Here is a simplified way of achieving the same:
get file="C:\Program Files\IBM\SPSS\Statistics\23\Samples\English\Employee data.sav".
begin program.
import spss, spssaux, spssdata
spss.Submit("set mprint on.")
vd=spssaux.VariableDict()
spss.Submit("VARIABLE LABEL %s." % ("\n".join(["%s '%s' " % (str(v), v.VariableLabel.capitalize()) for v in vd])))
spss.Submit("set mprint off.")
end program.
You can also set the variable label property (v.VariableLabel = "...") rather than generating a VARIABLE LABEL command. If what you want is Title Case, you could just do v.VariableLabel = v.VariableLabel.title()

Not iterating through whole dictionary

So basically, I have an api from which i have several dictionaries/arrays. (http://dev.c0l.in:5984/income_statements/_all_docs)
When getting the financial information for each company from the api (e.g. sector = technology and statement = income) python is supposed to return 614 technology companies, however i get this error:
Traceback (most recent call last):
File "C:\Users\samuel\Desktop\Python Project\Mastercopy.py", line 83, in <module>
user_input1()
File "C:\Users\samuel\Desktop\Python Project\Mastercopy.py", line 75, in user_input1
income_statement_fn()
File "C:\Users\samuel\Desktop\Python Project\Mastercopy.py", line 51, in income_statement_fn
if is_response ['sector'] == user_input3:
KeyError: 'sector'
on a random company (usually on one of the 550-600th ones)
Here is the function for income statements
def income_statement_fn():
user_input3 = raw_input("Which sector would you like to iterate through in Income Statement?: ")
print 'Starting...'
for item in income_response['rows']:
is_url = "http://dev.c0l.in:5984/income_statements/" + item['id']
is_request = urllib2.urlopen(is_url).read()
is_response = json.loads(is_request)
if is_response ['sector'] == user_input3:
csv.writerow([
is_response['company']['name'],
is_response['company']['sales'],
is_response['company']['opening_stock'],
is_response['company']['purchases'],
is_response['company']['closing_stock'],
is_response['company']['expenses'],
is_response['company']['interest_payable'],
is_response['company']['interest_receivable']])
print 'loading...'
print 'done!'
print end - start
Any idea what could be causing this error?
(I don't believe that it is the api itself)
Cheers
Well, on testing the url you pass in the urlopen call, with a random number, I got this:
{"error":"not_found","reason":"missing"}
In that case, your function will return exactly the error you get. If you want your program to handle the error nicely and add a "missing" line instead of actual data, you could do that for instance:
def income_statement_fn():
user_input3 = raw_input("Which sector would you like to iterate through in Income Statement?: ")
print 'Starting...'
for item in income_response['rows']:
is_url = "http://dev.c0l.in:5984/income_statements/" + item['id']
is_request = urllib2.urlopen(is_url).read()
is_response = json.loads(is_request)
if is_response.get('sector', False) == user_input3:
csv.writerow([
is_response['company']['name'],
is_response['company']['sales'],
is_response['company']['opening_stock'],
is_response['company']['purchases'],
is_response['company']['closing_stock'],
is_response['company']['expenses'],
is_response['company']['interest_payable'],
is_response['company']['interest_receivable']])
print 'loading...'
else:
csv.writerow(['missing data'])
print 'done!'
print end - start
The problem seems to be with the final row of your income_response data
{"id":"_design/auth","key":"_design/auth","value":{"rev":"1-3d8f282ec7c26779194caf1d62114dc7"}}
This does not have a sector value. You need to alter your code to handle this line, for example by ignoring any line where the sector key is not present.
You could easily have debugged this with a few print statements - for example insert
print item['id'], is_response.get('sector', None)
into your code before the part that outputs the CSV.
A KeyError means that the key you tried to use does not exist in the dictionary. When checking for a key, it is much safer to use .get(). So you would replace this line:
if is_response['sector'] == user_input3:
With this:
if is_response.get('sector') == user_input3:

Categories

Resources