Getting this output, with generators/list comprehensions? - python

I'm having a bit of trouble with something, and I don't know how I could do it.
Well, I'm creating a dynamic form with buttons that adapts to how many files (in this case, movies) there are in a directory.
I have got this so far:
path="C:\\Users\\User\\Desktop\\test\\" # insert the path to the directory of interest
movies = []
dirList=os.listdir(path)
for fname in dirList: # loops through directory specified
print fname # prints file name
movies.append(fname) # adds the file name to list
my_form = form.Form([form.Button("btn", id="btn" + movies[i], value = i, html=movies[i], class_="btn" +movies[i]) for i in range(len(movies))])
However, I want the list comprehension/generator to make my_form look something like this:
my_form = form.Form(
form.Button("btn", id="btnA", value="A", html="Movie1", class_="btnA")
form.Button("btn", id="btnB", value="B", html="Movie2", class_="btnB")
)
As you can see instead of the movie name being the id, it is btnA or btnB.
So how could I generate that output?

I think you want to do something like:
from string import ascii_uppercase
buttons = [form.Button("btn", id="btn{0}".format(char), value=char,
html=movie, class_="btn{0}".format(char))
for char, movie in zip(ascii_uppercase, movies)]
my_form = form.Form(buttons)
This uses the letters in string.ascii_uppercase to label each item in movies.

If I understand correctly, you want the id to be btn + a letter according to the index of the movie?
you can use this code:
def letterForIndex(idx):
return chr(ord('A')+idx)
so you would do :
my_form = form.Form([form.Button("btn", id="btn" + letterForIndex(i),
value = letterForIndex(i), html=movies[i], class_="btn" +letterForIndex(i)) for i in range(len(movies))])

Related

how can i fill my key's json automatically

I have a json template that I would like to autofill.
currently i do it manually like this:
for i in range(len(self.dict_trie_csv_infos)):
self.template_json[i]['name'] = self.dict_trie_csv_infos[i]['name']
self.template_json[i]['title'] = self.dict_trie_csv_infos[i]['title']
self.template_json[i]['startDateTime'] = self.dict_trie_csv_infos[i]['startDateTime']
self.template_json[i]['endDateTime'] = self.dict_trie_csv_infos[i]['endDateTime']
self.template_json[i]['address'] = self.dict_trie_csv_infos[i]['address']
self.template_json[i]['locationName'] = self.dict_trie_csv_infos[i]['locationName']
self.template_json[i]['totalTicketsCount'] = self.dict_trie_csv_infos[i]
.....etc..
as you can see they have the same key's name,
i tried to do it with a loop but it didn't worked.
How can i fill it automatically (is it possible)?
Thanks for your answer
If you're matching names you could do something like:
for i in range(len(self.dict_trie_csv_infos)):
for key in list(self.dict_trie_csv_infos.keys()):
self.template_json[i][key] = self.dict_trie_csv_infos[i][key]

Passing the objects created in a class to the global workspace

I'm trying to figure out how to make the objects I create inside a definition appear on the same workspace as my "name == main" area, so I can call it in other definitions. I don't think I can use a simple "return" statement in my def, because my function is designed to create n-number of objects of a particular class.
def book_to_object(subfolders):
# converts my dictionary of book titles and volumes into individual book objects
for key, val in subfolders.items():
title = replace_spaces_with_underscores(key)
# check to see if book already exists in the registry
if title in [book.name for book in Book._registry]:
print("Book already exists")
else:
exec(title + " = Book(subfolders ,key, Fpath)")
The whole program below.
I'm calling this def from my if __name__ == '__main__': function
print("Done")
#converts my dictionary of book titles and volumes into individual book objects
book_to_object(subfolders)
Originally I had the code in my def in the name=main area of my code but I wanted to reduce the clutter and make it into a definition to give me more flexibility later.
The whole program below.
import os
#get date modified time of a file to determine which file is the newest
def get_date_modified(file):
return os.path.getmtime(file)
#replace spaces with underscores in a string
def replace_spaces_with_underscores(string):
aa = string.replace(" ", "_")
bb= aa.replace('-', '_')
cc= bb.replace("__", "_")
title = cc.replace("__", "_")
return title
# create a list of volumes that have not been exported
def get_unexported_volumes(self):
unexported_volumes = []
for volume in self.volumes:
if volume not in self.last_exported:
unexported_volumes.append(volume)
return unexported_volumes
def book_to_object(subfolders):
# converts my dictionary of book titles and volumes into individual book objects
for key, val in subfolders.items():
title = replace_spaces_with_underscores(key)
# check to see if book already exists in the registry
if title in [book.name for book in Book._registry]:
print("Book already exists")
else:
exec(title + " = Book(subfolders ,key, Fpath)")
class Book(object):
#__metaclass__ = IterBook
_registry = []
#constructor
def __init__(self, my_dict, key, Fpath):
self._registry.append(self)
self.name = key
self.volumes = my_dict[key]
self.Filepath = Fpath + "/" +self.name
#self.last_exported = self.volumes[0]
self.last_exported = ""
self.newest = self.volumes[-1]
self.last_downloaded = self.volumes[-1]
self.last_converted = self.volumes[-1]
self.last_exported_date = get_date_modified(self.Filepath + "/" + self.last_exported)
self.newest_date = get_date_modified(self.Filepath + "/" + self.newest)
self.last_downloaded_date = get_date_modified(self.Filepath + "/" + self.last_downloaded)
self.last_converted_date = get_date_modified(self.Filepath + "/" + self.last_converted)
self.last_exported_volume = self.last_exported
self.newest_volume = self.newest
self.last_downloaded_volume = self.last_downloaded
self.last_converted_volume = self.last_converted
self.last_exported_volume_date = self.last_exported_date
self.newest_volume_date = self.newest_date
self.last_downloaded_volume_date = self.last_downloaded_date
self.last_converted_volume_date = self.last_converted_date
self.last_exported_volume_name = self.last_exported
self.newest_volume_name = self.newest
self.unexported_volumes = get_unexported_volumes(self)
if __name__ == '__main__':
print("Starting")
# File Paths for Debugging purposes
Fpath = '~/'
F_Temp_path = '~/temp'
#parses directory for book based on folder names
subfolders = {'Encyclopedia': ['Vol.001', 'Vol.002', 'Vol.003', 'Vol.004', 'Vol.005'], 'Enginnering_Encyclopedia': ['Avionics', 'Civil', 'Electrical', 'Materials', 'Mechanical']}
print("Done")
#converts my dictionary of book titles and volumes into individual book objects
book_to_object(subfolders)
Notes:
In case anyone is wondering why I'm using objects instead of keeping everything in dictionaries, I need the flexibility that objects give.
Variables such as, file_paths and subfolders are dynamic and are based on what directory the user gives and what files are in that directory, for the purpose of asking the questions they have been hard coded so someone could copy and paste my code and reproduce the problem in question.

Python looping for label variables

I am trying to create a loop that will display each title of product for their individual labels (Tkinter module).
With the current loop i can get it to print my 10 "static_webpage_1_titles" in the list, but i am wanting to also increase the variable Label_1 by +1 increment each time.
For example, it should do somthing like this:
Label_1['text'] = static_webpage_1_titles[0]
Label_2['text'] = static_webpage_1_titles[1]
Label_3['text'] = static_webpage_1_titles[2]
Here is my current code:
def Generate_Product_Name_and_Price_1():
if Button_on:
Find_static_webpage_1()
for i in range(len(static_webpage_1_titles)):
Label_1['text'] = static_webpage_1_titles[i]
EDIT:
product_labels = [Label_1['text'], Label_2['text'], Label_3['text'],
Label_4['text'], Label_5['text'], Label_6['text'],
Label_7['text'], Label_8['text'], Label_9['text'],
Label_10['text']]
I have created a list above with each label widget and changed the last line of code in my loop to:
def Generate_Product_Name_and_Price_1():
if Button_on:
Find_static_webpage_1()
for i in range(len(static_webpage_1_titles)):
product_labels[i] = static_webpage_1_titles[i] +': $'+ static_webpage_1_price[i]
When i run this, i do not receive any IDLE error but my label widgets do not get populated with data.
You need to make a list of the Label instances, not the text attributes of Label instances. Like this:
product_labels = [Label_1, Label_2, Label_3,
Label_4, Label_5, Label_6,
Label_7, Label_8, Label_9,
Label_10]
Then you access the attribute like this:
for i in range(len(static_webpage_1_titles)):
product_labels[i]['text'] = static_webpage_1_titles[i] +': $'+ static_webpage_1_price[i]
You could also make this a little neater with zip():
for label, title, price in zip(product_labels, static_webpage_1_titles, static_webpage_1_price):
label['text'] = title +': $'+ price

How do I access a dictionary value for use with the urllib module in python?

Example - I have the following dictionary...
URLDict = {'OTX2':'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=OTX2&action=view_all',
'RAB3GAP':'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=RAB3GAP1&action=view_all',
'SOX2':'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=SOX2&action=view_all',
'STRA6':'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=STRA6&action=view_all',
'MLYCD':'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=MLYCD&action=view_all'}
I would like to use urllib to call each url in a for loop, how can this be done?
I have successfully done this with with the urls in a list format like this...
OTX2 = 'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=OTX2&action=view_all'
RAB3GAP = 'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=RAB3GAP1&action=view_all'
SOX2 = 'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=SOX2&action=view_all'
STRA6 = 'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=STRA6&action=view_all'
MLYCD = 'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=MLYCD&action=view_all'
URLList = [OTX2,RAB3GAP,SOX2,STRA6,PAX6,MLYCD]
for URL in URLList:
sourcepage = urllib.urlopen(URL)
sourcetext = sourcepage.read()
but I want to also be able to print the key later when returning data. Using a list format the key would be a variable and thus not able to access it for printing, I would lonly be able to print the value.
Thanks for any help.
Tom
Have you tried (as a simple example):
for key, value in URLDict.iteritems():
print key, value
Doesn't look like a dictionary is even necessary.
dbs = ['OTX2', 'RAB3GAP', 'SOX2', 'STRA6', 'PAX6', 'MLYCD']
urlbase = 'http://lsdb.hgu.mrc.ac.uk/variants.php?select_db=%s&action=view_all'
for db in dbs:
sourcepage = urllib.urlopen(urlbase % db)
sourcetext = sourcepage.read()
I would go about it like this:
for url_key in URLDict:
URL = URLDict[url_key]
sourcepage = urllib.urlopen(URL)
sourcetext = sourcepage.read()
The url is obviously URLDict[url_key] and you can retain the key value within the name url_key. For exemple:
print url_key
On the first iteration will printOTX2.

How to save and load QListWidjet contents to/from QSetting with PyQt4?

I've got a QListWidget in my PyQt4 app. It contains folders paths.
I want to save its contents to QSettings and load them later.
I used this code to do this:
def foldersSave(self):
folders = {} '''create dict to store data'''
foldersnum = self.configDialog.FolderLIST.count() '''get number of items'''
if foldersnum:
for i in range(foldersnum):
folders[i] = self.configDialog.FolderLIST.item(i).text() '''save items text to dict'''
return str(folders) '''return string of folders to store in QSettings'''
return None
But if I make so folders paths are stored in config file like:
musicfolders={0: PyQt4.QtCore.QString(u'/home/sam/Ubuntu One')}
So I have no idea how to load them then. I've tryed something like this in different variants:
def foldersLoad(self):
folders = eval(self.tunSettings.value('musicfolders').toString())
It returns error:
TypeError: eval() arg 1 must be a string or code object
It looks like I just need to save data some other way then I do now.
Gooled a lot, but have no clue. I'm sure the answer is trivial, but I'm stuck.
The solution is very simply. I were to use QStringList.
def foldersSave(self):
folders = QtCore.QStringList()
foldersnum = self.configDialog.FolderLIST.count()
if foldersnum:
for i in range(foldersnum):
print (i, " position is saved: ", self.configDialog.FolderLIST.item(i).text())
folders.append(self.configDialog.FolderLIST.item(i).text())
return folders
return None
and load
def foldersLoad(self):
folders = QtCore.QStringList()
folders = self.tunSettings.value('musicfolders', None).toStringList()
if folders.count():
foldersnum = folders.count()
for i in range(foldersnum):
self.configDialog.FolderLIST.addItem(folders.takeFirst())

Categories