Get the index of the push button - python

I have the following problem, which doesn't seem particularly difficult, but I've been standing still for 1 day and can't find the right logic.
I have a list that searches for objects that end with the name "_ctrl". This list currently contains 4 items, but can contain any number of items. Depending on how many objects exist, it will add that many rows of buttons to the table.
My question is - how to get the index of the selected button to be printed in another function.
enter image description here
I hope you can understand me what I wanted to ask.
def refresh_table(self):
self.table_wdg.setRowCount(0)
controls = cmds.ls("*_ctrl")
for i in range(len(controls)):
self.table_wdg.insertRow(i)
controls[i] = QtWidgets.QPushButton("Button")
self.table_wdg.setCellWidget(i,0,controls[i])
controls[i].clicked.connect(self.printing)
def printing(self):
print()

Related

Tkinter - Return column number of selected treeview

How do I get the number of the column that is selected in a tkinter treeview?
Right now I'm using tree.focus() but it returns something like I001 or I00A and I have no idea how to convert that to a number.
I can't index the tree because there are multiple items with the same name in it, and I want to know the exact column the user clicks on.
What I expect is to click the first item and get the integer 0 back, etc.
Thanks, please ask questions if I was confusing...
Here are docs for Treeview.
You have used the term "column" repeatedly, but when you say "multiple items with the same name" and refer to "first item" it sounds a lot like you're talking about rows.
If you want the column, you'll need to capture the click event using treeview.bind("<Button-1>", callback) or a variant of that. You would then use treeview.identify_column to get the column index based on the event's x location (keep in mind, per the docs, that if your columns are rearranged you may need to do some extra work). Here are two links if you need information on events.
If you were actually talking about rows, you can use treeview.selection() to get a list of iids of selected items, and then feed them into treeview.index() to get the 0-index of the row that you were talking about.

Display text from a key/value pair in a nested dictionary

I'm a novice.
I am trying to print the elements from the Periodic Table to the screen arranged like the table itself. I'm using (' - ') to separate the symbols that I haven't written in the dictionary yet. I'm only using a nested dictionary with two entries total to minimize confusion.
Training Source last exercise.
I asked this question elsewhere and someone (correctly) suggested using str.join(list) but It wasn't part of the tutorial.
I'm trying to teach myself and I want to understand. No schooling, no work, no instructor.
The hints at the bottom of the linked tutorial says:
1."Use a for loop to loop through each element. Pick out the elements' row numbers and column numbers."
2."Use two nested for loops to print either an element's symbol or a series of spaces, depending on how full that row is."
I'd like to solve it this way. Thanks in advance.
Note* No, pre-intermediate, intermediate or advanced code please, the tutorial has only covered code related to variables, strings, numbers, lists, tuples, functions(beginners),if statements, while loops, basic terminal apps and dictionaries.
Lastly I'd like to have the table itself printed with the shape of the real Periodic Table. If you could throw in a bit of that code for a novice it'd really help thanks.
My attempt(wrong):
ptable = {'mercury':{'symbol':'hg','atomic number': '80','row': '6','column': '12','weight':'200.59',}, 'tungsten':{'symbol':'w','atomic number':'74','row':'6','column':'6','weight':'183.84'},}
for line in range(1,7):
for key in ptable:
row = int(ptable[key]['row'])
column = int(ptable[key]['column'])
if line != row:
print('-'*18)
else:
space = 18 - column
print('-'*(column-1)+ptable[key]['symbol']+'-'*space)
outputs:
------------------
------------------
------------------
------------------
------------------
------------------
------------------
------------------
------------------
------------------
-----------hg------
-----w------------
The output should have 7 lines as in the Periodic table. It is supposed to display the symbols of each element in the correct place as in the Periodic Table. Since I only have two elements in the library it should show Hg and W in their correct places
The experienced programmers' solution:
for line in range(1, 8): # line will count from 1 to 7
# display represents the line of elements we will print later
# hyphens show that the space is empty
# so we fill the list with hyphens at first
display = ['-'] * 18
for key in ptable:
if int(ptable[key]['row']) == line:
# if our element is on this line
# add that element to our list
display[int(ptable[key]['column']) - 1] = ptable[key]['symbol']
# str.join(list) will "join" the elements of your list into a new string
# the string you call it on will go in between all of your elements
print(''.join(display))
I honestly think this code isn't that hard to understand and I think trying to change it would only make it more complicated. I'm going to put you some links at the end for you to check it out and understand the ''join() method and the range() function which you seem not to understand either. You said you wanted to learn Python by yourself and that's a great thing! (I'm doing it too) But that doesn't mean you have to stick to a tutorial ;). You can go beyond it and also skip the parts you don't care about and come back later when you need them. If you need explanations about methods (like ''.join) or any other thing let me know. Sorry if that doesn't help you ;(.
Links:
The .join() method
The range() function

Appending to lists, with variables. Python

I have made a math quiz(simple.asks 10 maths question to the user). I made the user take the quiz 3 times using a for loop, because i needed 3 scores for each student.I decided to store the 3 scores in a list HOWEVER because the variable "score" changes every time the for loop runs and every time the user does the quiz..i find it very difficult to append each score in the same list one after another.
I have read some other response to a similar question and the answer was the use of indexes, but i am not quiet sure how i could use them for my problem as i don't have a specific location in the list to add my 3 different scores, i need to add them one after another.
Here is the part in my code that i need to work on:
hscore = []
hscore.append(score)
print("This is hscore: ",hscore)
score = 0
I am sorry, this is my first time using this webiste so..i don't know how to present my code properly. But as you can see..i have my empty list which i want to append to. score is the variable that changes 3 times, and the print was just for me to check if it was working which it wasn't. Also every time the for loops runs again i had to set the score to 0, so the scores wouldn't get add up together.
You should declare all variables out side your loop, cause it looks like you're resetting score to 0.
And as a recommendation, try using a dictionary to better handle this kind of information.
Like this:
scores={}
scores[Name]=[]
## Your code block here
## or for loop
scores[Name].append(score)
print scores[Name]
scores will be able to hold the scores of each student with a list of their score. Hope that helps! :)

Reading text and assigning a class to data in Python

I've been searching around, and had no luck finding anything answering my question.
Essentially I have a file with the following data:
Title - 19
Artist - Adele
Year released - 2008
1 - Daydreamer, 3:41, 1
2 - Best for Last, 4:19, 5
3 - Chasing Pavements, 3:31, 7
4 - Cold Shoulder, 3:12, 3
Title - El Camino
Artist - The Black Keys
Year released - 2011
1 - Lonely Boy, 3:13, 1
2 - Run Right Back, 3:17, 10
EOF
I know how to create classes, and how to assign an object to a class and values to that object, but I am just about ready to tear my hair out on how it is I'm supposed to process the text. From text, I need to create a title for the album, and assign the album's information to it. There's more else besides that needs to be done, and there are more lines to be read, and I just don't know where to start on this. I've found two "album.py" files via google, and I've been unable to make heads or tails of how to apply the solution to my case.
And yes, this is for a school assignment. I've done some digging around and found some things relevant, but I'm just not understanding it. I'm new to programming in general, and I've made progress but this seems too far over my head.
I know I could reduce this to lists using split (\n\n) and operating on a series of progressively smaller lists, but I am trying to avoid this method at all costs.
EDIT:
For the time being, it's best to assume I know nothing. Though, to answer below question: I can open the file and read it. If its a consistent CSV formatted file, I can write code to process the enclosed data, and create a class structure that uses that data. Right now I'm just having trouble with the first three lines, and the digits immediately below.
APRIL 4 2012:
Okay, I have some code, I've left the comments with respect to it underneath.
def getInput():
global albums
raw = open("album.txt","r")
infile = raw
raw.close
text=""
line = infile.readline()
while (line != "EOF\n" ):
text += line
line=infile.readline()
text=text.rstrip("\n\n")
albums=[str(n) for n in text.split("\n\n")]
return albums
class Album():
def __init__(self, title, artist, date):
self.title=title
self.artist=artist
self.date=date
self.track={}
def addSong(self, TrackID, title, time, ranking):
self.track+={self}
def getAlbumLength(self):
asdf=0
def getRanking(self):
asdf=0
def labels(x): #establishes labels per item to be used for Album Classifier
title=""
artist=""
date=""
for i in range(0,len(albums),1):
sublist=[str(n) for n in albums[i].split("\n")]
RANDUMB=len(albums[i])
title=sublist[0]
artist=sublist[1]
date=sublist[2]
for j in range(0,len(sublist),1):
song_info = [str(k) for k in sublist[3:].split("," and " - ")]
TrackID=song_info[0]
title=song_info[1]
time=song_info[2]
ranking=song_info[3]
getInput()
labels(albums)
Personal comments on code:
I was trying to avoid getting it into lists because I anticipated this problem. As the functions are concerned, I have to use every single bloody one, because it's in the assignment requirements... I am displeased because I could probably get around using them. The code is working sufficiently enough, except for the last part of it where I am trying to take the song information. I want to split the song information into lists, which are nested into the album information list. Something like:
[Album title, Artist, Date released,[01,Song,3:44,2],[02,Song,0:01,9]....]
The current code gives me index out of range error as of right now... I am using python3.
TLDR: The substance of my problem has thus changed from one of trying to solve how to go about starting the solution to how to take items in a list and convert them into nested lists.
If you end up editing your question to contain some more specific examples of what is giving you trouble, I will edit this answer. But to address your general question, there are some steps involved to achieving your goal.
Like you said, you need to write a class that reflects the structure you intend to have from this data.
You will need to parse this file, probably line by line. So you have to determine if this file format is consistant. If it is, then you need to determine:
What is the delimiter between each set of data, which will be conformed into a class instance?
What is the delimiter between each field of each line?
When you are looping over each line, you will know that you need to start a new album object whenever you encounter a blank line.
When you know you are starting a new album, you can assume that the first line will be a title, the second an artist, the third, the year, etc.
For each of these lines you will also have to have rules of how to split each one into the data you want. At a basic level it can be a simple set of splits. At a more advanced level you might define regular expressions for each type of line.

How to stop infinite recursion when Python objects trigger each other's updates?

I'm using PyGTK and the gtk.Assistant widget. On one page I have six comboboxes, which initially have the same contents (six numbers). When the users selects a number in one of those comboboxes, this number should no longer be available in the other five boxes (unless it's present as a duplicate in the original list). Hence I would like to always update the contents.
I have tried the following approach (just a few code snippets here), but (of course...) it just jumps into infinite recursion once the process has been triggered:
# 'combo_list' is a list containing the six comboboxes
def changed_single_score(self, source_combo, all_scores, combo_list, indx_in_combo_list):
scores = all_scores.split(', ')
for i in range(6):
selected = self.get_active_text(combo_list[i])
if selected in scores:
scores.remove(selected)
# 'scores' only contains the items that are still available
for indx in range(6):
# don't change the box which triggered the update
if not indx == indx_in_combo_list:
# the idea is to clear each list and then repopulate it with the
# remaining available items
combo_list[indx].get_model().clear()
for item in scores:
combo_list[indx].append_text(item)
# '0' is appended so that swapping values is still possible
combo_list[indx].append_text('0')
The above function is called when a change occurs in one of the comboboxes:
for indx in range(6):
for score in self.selected['scores'].split(', '):
combo_list[indx].append_text(score)
combo_list[indx].connect('changed', self.changed_single_score, self.selected['scores'], combo_list, indx)
Perhaps I ought to mention that I'm new to Python, OOP, and also rather new to GUI-programming. I'm probably being really stupid here, and/or overlooking the obvious solution, but I have so far been unable to figure out how to stop each box from triggering updating of all other boxes once it itself has been updated.
Thanks in advance for your replies - any help would be greatly appreciated.
The simplest fix for this sort of problem is generally to figure out if you're going to need to change the contents of the object (the combobox, in your case) and then only apply changes if you're actually changing something. This way you'll only propagate update events as far as they do something.
This should look something like:
# '0' is appended so that swapping values is still possible
items = [item for item in scores] + ['0']
for indx in range(6):
# don't change the box which triggered the update
if not indx == indx_in_combo_list:
# I'm not 100% sure that this next line is correct, but it should be close
existing_values = [model_item[0] for model_item in combolist[indx].get_model()]
if existing_values != items:
# the idea is to clear each list and then repopulate it with the
# remaining available items
combo_list[indx].get_model().clear()
for item in items:
combo_list[indx].append_text(item)
This is a pretty general approach (even some build systems use it). The main requirement is that things actually do settle. In your case it should settle immediately.

Categories

Resources