Priting output in tkinter instead of console - python

I'm using graphlab to print out recommendations and have my tkinter GUI which currently prints out the recommendation results in the console and I'm lost on how to get it to print in the GUI.
Class "UserID" is where i have a button that calls the "printrec" function but only prints out the recommendations in the console.
from Tkinter import *
import sqlite3
class Welcome():
def __init__(self,master):
self.master=master
self.master.geometry('170x110+100+200')
self.master.title('Welcome!')
self.label1=Label(self.master,text='Music Recommender',fg='black', bg="red").grid(row=0,column=1)
self.button1=Button(self.master,text="Enter UserID",fg='black', bg="blue", command=self.gotoUserID).grid(row=1,column=1)
self.button2=Button(self.master,text="Comparing models",fg='black', bg="blue").grid(row=2,column=1)
#self.button3=Button(self.master,text="Click to print recs",fg='red',command=self.rec).grid(row=3,column=1)
self.button4=Button(self.master,text="Exit",fg='black' , bg="blue",command=self.exit).grid(row=4,column=1)
def exit(self):
#exit button#
self.master.destroy()
def gotoUserID(self):
#USERID GUI#
root2=Toplevel(self.master)
myGUI=UserID(root2)
class UserID():
#userID class prints song recs
def __init__(self,master):
self.userRec=int()
self.master=master
self.master.geometry('400x250+100+200')
self.master.title('ID recommender')
self.label2=Label(self.master,text='Welcome to the Music Recommender',fg='red').grid(row=0,column=0)
self.label2=Label(self.master,text='Please enter UserID: ',fg='black').grid(row=3,column=0)
self.ID=Entry(self.master,textvariable=self.userRec).grid(row=3,column=1)
self.button4=Button(self.master,text="Get recommendations",fg='red',command=self.printrec).grid(row=7,column=0)
self.button5=Button(self.master,text="Exit",fg='red',command=self.exit).grid(row=9,column=0)
def printrec(self):
#currently prints song recs in console
print song_recommendations
def main():
root=Tk()
root.configure(background='blue')
myGUIWelcome=Welcome(root)
root.mainloop()
if __name__ == '__main__':
main()
This is the model im using to recommend. It uses the graphlab package.
recs_model = gl.recommender.ranking_factorization_recommender.create(plays_df, user_id="userID", item_id="songID", target="plays")
recommendations = recs_model.recommend(users=["3a613180775197cd08c154abe4e3f67af238a632"])
song_recommendations = recommendations.join(songs_df, on="songID", how="inner").sort("rank")
This is the output I want to appear in my GUI but im not sure if its possible to print an sframe like this into tkinter.
+-------------------------------+--------------------+---------------+------+
| userID | songID | score | rank |
+-------------------------------+--------------------+---------------+------+
| 3a613180775197cd08c154abe4... | SOXTUWG12AB018A2E2 | 59.1517736392 | 1 |
| 3a613180775197cd08c154abe4... | SOYBLYP12A58A79D32 | 30.0328809695 | 2 |
| 3a613180775197cd08c154abe4... | SOFVLYV12A8C145D8F | 28.9258825259 | 3 |
| 3a613180775197cd08c154abe4... | SOVWBYM12A6D4F8A22 | 28.9166185336 | 4 |
| 3a613180775197cd08c154abe4... | SOAUWYT12A81C206F1 | 27.7749540286 | 5 |
| 3a613180775197cd08c154abe4... | SODCNEE12A6310E037 | 27.7024595218 | 6 |
| 3a613180775197cd08c154abe4... | SOAIWAB12A8C13710A | 24.2139894443 | 7 |
| 3a613180775197cd08c154abe4... | SOFFXAQ12A8AE45C2E | 23.7690011935 | 8 |
| 3a613180775197cd08c154abe4... | SONDKOF12A6D4F7D70 | 22.8345548587 | 9 |
| 3a613180775197cd08c154abe4... | SOJFQWU12A8C1448C7 | 22.2914831119 | 10 |
+-------------------------------+--------------------+---------------+------+
+--------------------------------+--------------------------------+
| title | release |
+--------------------------------+--------------------------------+
| Drop The Hammer (Album Ver... | A Search For Reason |
| Up And Up (Acoustic) | Must Have Done Something Right |
| Believe In Yourself | Questions |
| Video Killed The Radio Star | Friends Reunited: Music Of... |
| Undo | Vespertine Live |
| Sorrow (1997 Digital Remaster) | The Best Of David Bowie 19... |
| Blind Date | Anchors Aweigh |
| Death Chamber | Isolation |
| Recado Falado (Metrô Da Sa... | 2 Em 1 |
| Rain On Your Parade | Rain On Your Parade |
+--------------------------------+--------------------------------+
+------------------+------+
| artistName | year |
+------------------+------+
| Kilgore | 1998 |
| Relient K | 0 |
| Us3 | 2004 |
| The Buggles | 1979 |
| Björk | 2001 |
| David Bowie | 0 |
| Bouncing Souls | 2003 |
| Fear My Thoughts | 2008 |
| Alceu Valença | 0 |
| Duffy | 0 |
+------------------+------+
[10 rows x 8 columns]
Thanks!

you can make the gui:
from tkinter import *
root = Tk()
Console = Text(root)
Console.pack()
root.mainloop()
and then you can rewrite the print function:
def write(*message, end = "\n", sep = " "):
text = ""
for item in message:
text += "{}".format(item)
text += sep
text += end
Console.insert(INSERT, text)
and here you have the output in tkinter, you just have to call write() instead of print()

Related

Button Not Interacting (Custom Type) - Pywinauto

I am working on automating a process that uses our ancient HRIS system that unfortunately doesn't have API Access.
I am fairly new to Python, so I have been taking this task bit by bit. I've managed to connect to the app and input my username and password to sign in. However, I am stuck on selecting a menu item. I've tried everything that I know to do and have Googled until I've gone cross-eyed.
Dialog - 'City of Conway LIVE Springbrook V7' (L0, T0, R1032, B1039)
['Dialog', 'City of Conway LIVE Springbrook V7Dialog', 'City of Conway LIVE Springbrook V7', 'Dialog0', 'Dialog1']
child_window(title="City of Conway LIVE Springbrook V7", auto_id="MainMenu", control_type="Window")
|
| Pane - '' (L231, T87, R1024, B118)
| ['Pane', 'Pane0', 'Pane1']
| child_window(auto_id="_panelExWorkArea", control_type="Pane")
| |
| | Pane - 'Desktop' (L231, T90, R1021, B115)
| | ['DesktopPane', 'Desktop', 'Pane2']
| | child_window(title="Desktop", auto_id="_ssiGroupHeaderWorkArea", control_type="Pane")
|
| Pane - '' (L228, T87, R231, B1005)
| ['Pane3']
| child_window(auto_id="_ssiExpandableSplitter1", control_type="Pane")
|
| Pane - '' (L8, T87, R228, B1005)
| ['Pane4']
| child_window(auto_id="_panelTaskArea", control_type="Pane")
| |
| | Pane - '' (L11, T90, R228, B1002)
| | ['Pane5']
| | child_window(auto_id="328582", control_type="Pane")
| | |
| | | TreeView - '' (L11, T115, R228, B1002)
| | | ['TreeView', 'TreeView0', 'TreeView1']
| | | child_window(auto_id="1775914", control_type="Tree")
| | | |
| | | | Pane - '' (L28, T269, R194, B609)
| | | | ['Pane6']
| | | | child_window(auto_id="726924", control_type="Pane")
| | | | |
| | | | | Pane - '' (L28, T269, R194, B609)
| | | | | ['Pane7']
| | | | | child_window(auto_id="1317216", control_type="Pane")
| | | | | |
| | | | | | TreeView - '' (L28, T269, R194, B609)
| | | | | | ['TreeView2']
| | | | | | child_window(auto_id="2101028", control_type="Tree")
| | | | | | |
| | | | | | | Custom - 'Maintenance' (L0, T0, R0, B0)
| | | | | | | ['Custom', 'Maintenance', 'MaintenanceCustom', 'Custom0', 'Custom1', 'Maintenance0', 'Maintenance1', 'MaintenanceCustom0', 'MaintenanceCustom1']
| | | | | | | child_window(title="Maintenance", control_type="Custom")
I'm using a few tools to inspect the GUI, and this one specifically allows me to do the desired task by selecting "do it". It allows me to expand and collapse the section, so surely I've got to be missing something somewhere?
enter image description here
enter image description here
Here is my code:
from pywinauto import Application
app=Application(backend="uia").connect(path=r"C:\Users\skywalker\AppData\Local\Apps\2.0\C38DNYDP.PZ6\07BV1NGN.8G6\spri..ons1_b443b3e57637483a_0007.000f_52ec298e739bfebb", timeout = 30)
maintenance = app.CityofConwayLIVESpringbrookV7.WindowsForms10.Window.8.app.0.a0f91b_r8_ad1, 263022
maintenance.click()
I would also like to mention that I CAN get it to work with Click_Input, but I would like to avoid that if at all possible.

Unstack (pivot?) dataframe in Pandas

I have a dataframe somewhat like this:
ID | Relationship | First Name | Last Name | DOB | Address | Phone
0 | 2 | Self | Vegeta | Saiyan | 01/01/1949 | Saiyan Planet | 123-456-7891
1 | 2 | Spouse | Bulma | Saiyan | 04/20/1969 | Saiyan Planet | 123-456-7891
2 | 3 | Self | Krilin | Human | 08/21/1992 | Planet Earth | 789-456-4321
3 | 4 | Self | Goku | Kakarot | 05/04/1975 | Planet Earth | 321-654-9870
4 | 4 | Child | Gohan | Kakarot | 04/02/2001 | Planet Earth | 321-654-9870
5 | 5 | Self | Freezer | Fridge | 09/15/1955 | Deep Space | 456-788-9568
I'm looking to have the rows with same ID appended to the right of the first row with that ID.
Example:
ID | Relationship | First Name | Last Name | DOB | Address | Phone | Spouse_First Name | Spouse_Last Name | Spouse_DOB | Child_First Name | Child_Last Name | Child_DOB |
0 | 2 | Self | Vegeta | Saiyan | 01/01/1949 | Saiyan Planet | 123-456-7891 | Bulma | Saiyan | 04/20/1969 | | |
1 | 3 | Self | Krilin | Human | 08/21/1992 | Planet Earth | 789-456-4321 | | | | | |
2 | 4 | Self | Goku | Kakarot | 05/04/1975 | Planet Earth | 321-654-9870 | | | | Gohan | Kakarot | 04/02/2001 |
3 | 5 | Self | Freezer | Fridge | 09/15/1955 | Deep Space | 456-788-9568 | | | | | |
My real scenario dataframe has more columns, but they all have the same information when the two rows share the same ID, so no need to duplicate those in the other rows. I only need to add to the right the columns that I choose, which in this case would be First Name, Last Name, DOB with the identifier for the new column label depending on what's on the 'Relationship' column (I can rename them later if it's not possible to do in a straight way, just wanted to illustrate my point.
Now that I've said this, I want to add that I have tried different ways and seems like approaching with unstack or pivot is the way to go but I have not been successful in making it work.
Any help would be greatly appreciated.
This solution assumes that the DataFrame is indexed by the ID column.
not_self = (
df.query("Relationship != 'Self'")
.pivot(columns='Relationship')
.swaplevel(axis=1)
.reindex(
pd.MultiIndex.from_product(
(
set(df['Relationship'].unique()) - {'Self'},
df.columns.to_series().drop('Relationship')
)
),
axis=1
)
)
not_self.columns = [' '.join((a, b)) for a, b in not_self.columns]
result = df.query("Relationship == 'Self'").join(not_self)
Please let me know if this is not what was wanted.

Pandas - Sort order by Last Page Viewed

Can anyone help me sort the order of last page viewed?
I have a dataframe where I am attempting to sort it by the previous page viewed and I am having a really hard time coming up with an efficient method using Pandas.
For example from this:
+------------+------------------+----------+
| Customer | previousPagePath | pagePath |
+------------+------------------+----------+
| 1051471580 | A | D |
| 1051471580 | C | B |
| 1051471580 | A | exit |
| 1051471580 | B | A |
| 1051471580 | D | A |
| 1051471580 | entrance | C |
+------------+------------------+----------+
To this:
+------------+------------------+----------+
| Customer | previousPagePath | pagePath |
+------------+------------------+----------+
| 1051471580 | entrance | C |
| 1051471580 | C | B |
| 1051471580 | B | A |
| 1051471580 | A | D |
| 1051471580 | D | A |
| 1051471580 | A | exit |
+------------+------------------+----------+
However it could be millions of rows long for thousands of different customers so I really need to think how to make this efficient.
pd.DataFrame({
'Customer':'1051471580',
'previousPagePath': ['E','C','B','A','D','A'],
'pagePath': ['C','B','A','D','A','F']
})
Thanks!
What you're trying to do is topological sorting, which can be achieved with networkx. Note that I had to change some values in your dataframe in order to prevent it throwing a cycle error, so I hope that the data you work on contains unique values:
import networkx as nx
import pandas as pd
data = [ [1051471580, "Z", "D"], [1051471580,"C","B" ], [1051471580,"A","exit" ], [1051471580,"B","Z" ], [1051471580,"D","A" ], [1051471580,"entrance","C" ] ]
df = pd.DataFrame(data, columns=['Customer', 'previousPagePath', 'pagePath'])
edges = df[df.pagePath != df.previousPagePath].reset_index()
dg = nx.from_pandas_edgelist(edges, source='previousPagePath', target='pagePath', create_using=nx.DiGraph())
order = list(nx.lexicographical_topological_sort(dg))
result = df.set_index('previousPagePath').loc[order[:-1], :].dropna().reset_index()
result = result[['Customer', 'previousPagePath', 'pagePath']]
Output:
| | Customer | previousPagePath | pagePath |
|---:|-----------:|:-------------------|:-----------|
| 0 | 1051471580 | entrance | C |
| 1 | 1051471580 | C | B |
| 2 | 1051471580 | B | Z |
| 3 | 1051471580 | Z | D |
| 4 | 1051471580 | D | A |
| 5 | 1051471580 | A | exit |
you can sort your DataFrame by column like that.
df = pd.DataFrame({'Customer':'1051471580','previousPagePath':['E','C','B','A','D','A'], 'pagePath':['C','B','A','D','A','F']})
df.sort_values(by='previousPagePath')
and you can find the document here pandas.DataFrame.sort_values

Handling Custom ComboBox in pywinauto

I am writing a script to select a region in a ComboBox. I can use app.dialog['Region:ComboBox'].select(index), but not app.dialog['Region:ComboBox'].select('string'). I notice the ComboBox is custom and is generated real time. How can I select the proper option using a string? The string would be a region like US West, US East, etc.
| | GroupBox - 'Preferences' (L811, T456, R1108, B593)
| | ['PreferencesGroupBox', 'Preferences', 'GroupBox', 'GroupBox0', 'GroupBox1']
| | child_window(title="Preferences", control_type="Group")
| | |
| | | Static - 'PREFERENCES' (L817, T462, R1102, B476)
| | | ['PREFERENCES', 'PREFERENCESStatic', 'Static25']
| | | child_window(title="PREFERENCES", control_type="Text")
| | |
| | | Static - 'Region Text:' (L0, T0, R0, B0)
| | | ['Region Text:Static', 'Region Text:', 'Static26']
| | | child_window(title="Region Text:", control_type="Text")
| | |
| | | Static - '' (L0, T0, R0, B0)
| | | ['Static27']
| | |
| | | Static - 'Region:' (L822, T498, R937, B512)
| | | ['Region:Static', 'Region:', 'Static28']
| | | child_window(title="Region:", control_type="Text")
| | |
| | | Custom - '' (L947, T492, R1097, B518)
| | | ['Custom3', 'Region:Custom']
| | | |
| | | | ComboBox - '' (L947, T492, R1097, B518)
| | | | ['ComboBox', 'Region:ComboBox', 'ComboBoxESRI.ArcGIS.Azure.IaaS.Interfaces.RegionInfo']
| | | | |
| | | | | Edit - '' (L0, T0, R0, B0)
| | | | | ['Edit', 'Edit0', 'Edit1']
| | | | | child_window(auto_id="PART_EditableTextBox", control_type="Edit")
| | |
| | | Static - 'Remote Desktop Port:' (L822, T534, R937, B548)
| | | ['Remote Desktop Port:', 'Remote Desktop Port:Static', 'Static29']
| | | child_window(title="Remote Desktop Port:", control_type="Text")
| | |
| | | Edit - '3389' (L947, T528, R1097, B554)
| | | ['Edit2', 'Remote Desktop Port:Edit']
| | | child_window(title="3389", control_type="Edit")
| | | |
| | | | ScrollBar - '' (L0, T0, R0, B0)
| | | | ['ScrollBar', 'ScrollBar0', 'ScrollBar1']
| | | | child_window(auto_id="VerticalScrollBar", control_type="ScrollBar")
| | | |
| | | | ScrollBar - '' (L0, T0, R0, B0)
| | | | ['ScrollBar2']
| | | | child_window(auto_id="HorizontalScrollBar", control_type="ScrollBar")
| | | |
| | | | Button - 'r' (L0, T0, R0, B0)
| | | | ['r', 'Button8', 'rButton']
| | | | child_window(title="r", auto_id="PART_ClearText", control_type="Button")
| | |
| | | CheckBox - 'Track application usage anonymously' (L822, T564, R1097, B582)
| | | ['Track application usage anonymously', 'CheckBox', 'Track application usage anonymouslyCheckBox', 'Track application usage anonymously0', 'Track application usage anonymously1']
| | | child_window(title="Track application usage anonymously", control_type="CheckBox")
| | | |
| | | | Static - 'Track application usage anonymously' (L846, T565, R1043, B581)
| | | | ['Track application usage anonymously2', 'Track application usage anonymouslyStatic', 'Static30']
| | | | child_window(title="Track application usage anonymously", control_type="Text")
Here's how I implemented it. This function emulates the select() function more efficiently.
def comboselect(combo,sel):
combo.type_keys("{ENTER}") # Selects the combo box
texts = combo.texts() #gets all texts available in combo box
try:
index = texts.index(str(sel)) #find index of required selection
except ValueError:
return False
sel_index = combo.selected_index() # find current index of combo
if(index>sel_index):
combo.type_keys("{DOWN}"*abs(index-sel_index))
else:
combo.type_keys("{UP}"*abs(index-sel_index))
return True

Creating a chess board for the 8 Queens puzzle

s = [0,2,6,4,7,1,5,3]
def row_top():
print("|--|--|--|--|--|--|--|--|")
def cell_left():
print("| ", end = "")
def solution(s):
for i in range(8):
row(s[i])
def cell_data(isQ):
if isQ:
print("X", end = "")
return ()
else:
print(" ", end = "")
def row_data(c):
for i in range(9):
cell_left()
cell_data(i == c)
def row(c):
row_top()
row_data(c)
print("\n")
solution(s)
My output has a space every two lines, when there shouldn't be, I'm not sure where it's creating that extra line.
The output is suppose to look like this:
|--|--|--|--|--|--|--|--|
| | | | | | X| | |
|--|--|--|--|--|--|--|--|
| | | X| | | | | |
|--|--|--|--|--|--|--|--|
| | | | | X| | | |
|--|--|--|--|--|--|--|--|
| | | | | | | | X|
|--|--|--|--|--|--|--|--|
| X| | | | | | | |
|--|--|--|--|--|--|--|--|
| | | | X| | | | |
|--|--|--|--|--|--|--|--|
| | X| | | | | | |
|--|--|--|--|--|--|--|--|
| | | | | | | X| |
|--|--|--|--|--|--|--|--|
I know this chess board isn't very square but this is only a rough draft at the moment.
Here is an alternative implementation:
def make_row(rowdata, col, empty, full):
items = [col] * (2*len(rowdata) + 1)
items[1::2] = (full if d else empty for d in rowdata)
return ''.join(items)
def make_board(queens, col="|", row="---", empty=" ", full=" X "):
size = len(queens)
bar = make_row(queens, col, row, row)
board = [bar] * (2*size + 1)
board[1::2] = (make_row([i==q for i in range(size)], col, empty, full) for q in queens)
return '\n'.join(board)
queens = [0,2,6,4,7,1,5,3]
print(make_board(queens))
which results in
|---|---|---|---|---|---|---|---|
| X | | | | | | | |
|---|---|---|---|---|---|---|---|
| | | X | | | | | |
|---|---|---|---|---|---|---|---|
| | | | | | | X | |
|---|---|---|---|---|---|---|---|
| | | | | X | | | |
|---|---|---|---|---|---|---|---|
| | | | | | | | X |
|---|---|---|---|---|---|---|---|
| | X | | | | | | |
|---|---|---|---|---|---|---|---|
| | | | | | X | | |
|---|---|---|---|---|---|---|---|
| | | | X | | | | |
|---|---|---|---|---|---|---|---|
It is now very easy to change the width of the board by changing the strings passed to row, empty, full; I added an extra char to each, resulting in a (somewhat) squarer board.
You are still printing an extra newline:
def row(c):
row_top()
row_data(c)
print("\n")
Remove the explicit ''\n'` character:
def row(c):
row_top()
row_data(c)
print()
or better still, follow my previous answer more closely and print a closing | bar:
def row(c):
row_top()
row_data(c)
print('|')

Categories

Resources