I am New to python and going though few online training.I couldn't get any close related to below question.
I am using tkinter GUI
from Tkinter import *
root = Tk()
trainings = {"title":"Python Training Course for Beginners",
"location":"Frankfurt",
"ID": 111,"title":"Intermediate Python Training",
"location":"Berlin",
"ID": 133,"title":"Python Text Processing Course",
"location":"Mdsgtd",
"ID": 122}
for key in trainings.keys():
x = trainings.get(key)
print x
Label(root, text = x ).pack()
mainloop()
Getting output only:122
But I am expecting result should be display in GUI Label:
{'ID': 111, 'location': 'Frankfurt', 'title': 'Python Training Course for Beginners'}
{'ID': 122, 'location': 'Mdsgtd', 'title': 'Python Text Processing Course'}
{'ID': 133, 'location': 'Berlin', 'title': 'Intermediate Python Training'}
Can I used inside the function label as in below code: which is not working:
def OnButtonClick(self):
self.top= Toplevel()
self.top.title("Read Data Service Menu Item")
self.topdata = {'parakeet': ['fly', 'bird'], 'dog': 'animal', 'cat': 'feline'}
for key in self.topdata.keys():
x = self.topdata.get(key)
self.topL2 = Label(self.top, text = key).pack()
self.top.resizable(1,0)
self.top.transient(self)
self.B1.config(state = 'normal') #disable/normal
self.topButton = Button(self.top, text = 'Close', command = self.OnChildClose)
self.topButton.pack()
You have a few issues at present, as noted in the comments. Firstly, you should change your trainings dictionary to be a list of dictionaries to let you store the relevant information for each course in turn.
Assuming you want to show a different label for the information relating to each course, the following should work:
from Tkinter import *
courses = [{"title": "Python Training Course for Beginners",
"location": "Frankfurt",
"ID": 111},
{"title": "Intermediate Python Training",
"location": "Berlin",
"ID": 133},
{"title": "Python Text Processing Course",
"location": "Mdsgtd",
"ID": 122}]
root = Tk()
for course in courses:
temp_text = '{0} ({1}) - {2}'.format(course['title'], course['ID'], course['location'])
Label(root, text=temp_text).pack()
mainloop()
We use string formatting to create a nicely-written output, of the course name followed by its ID in brackets, then the location of the course after a dash.
What is critical here is that we want to create a Label widget for every course - hence, we add the new Label within our for loop to ensure this happens.
Related
I am new to personal projects and am working on a library book management system through the python terminal.
I'm running into an issue that has had been stuck for a while.
I'm trying to get my code to print out into the console
------ Main Menu ------
All Books
Check In
Check Out
Look Up
But instead it just gives me over and over again just "Choose Option". I'm not sure what I'm doing wrong as I've tried iterating a bunch of times over but I can't find the resolution.
Source Code:
Terminal Output:
In the future try pasting your code directly into your question rather than as an image.
Regardless, try moving the line starting with option i.e.:
option = input("Choose options: ")
into inside the mainMenu
function (main_menu in the attempted reconstruction of your attempt below):
#
#
# Print menu
# Menu will include a list if menu options
# Create a main menu function that will control the main menu
# Then call functions as they are requested by the user
# Will require a dictionary using id's as the key and book info as values
#
#
import pprint
import os
# Books in the System
books = [
{"ID": 100001, "title": "Meditations", "author": "Marcus Aurelius", "year": 180},
{"ID": 100002, "title": "To Kill a Mockingbird", "author": "Harper Lee", "year": 1960},
{"ID": 100003, "title": "The Great Gatsby", "author": "F. Scott Fitzgerald", "year": 1925},
{"ID": 100004, "title": "Don Quixote", "author": "Miguel de Cervantes", "year": 1615},
{"ID": 100005, "title": "The Little Prince", "author": "Antoine de Saint-Exupery", "year": 180}
]
menu = " ------ Main Menu ------ \n\n 1. All Books \n 2. Check In \n 3. Check Out \n 4. Look Up \n"
def menu1():
pprint.pprint(books)
option1 = input("Type 0 to go back: ")
if option1 == "0":
os.system("clear")
return main_menu()
def main_menu():
print(menu)
option = input("Choose option: ")
if option == "1":
os.system("clear")
return menu1()
if __name__ == '__main__':
main_menu()
Example Usage:
------ Main Menu ------
1. All Books
2. Check In
3. Check Out
4. Look Up
Choose option: 1
[{'ID': 100001,
'author': 'Marcus Aurelius',
'title': 'Meditations',
'year': 180},
{'ID': 100002,
'author': 'Harper Lee',
'title': 'To Kill a Mockingbird',
'year': 1960},
{'ID': 100003,
'author': 'F. Scott Fitzgerald',
'title': 'The Great Gatsby',
'year': 1925},
{'ID': 100004,
'author': 'Miguel de Cervantes',
'title': 'Don Quixote',
'year': 1615},
{'ID': 100005,
'author': 'Antoine de Saint-Exupery',
'title': 'The Little Prince',
'year': 180}]
I have this code for changing stoploss on opened order/orders in metatrader 5. When I run this code nothing happens even when my compiler print that, nothing is wrong. I have algotrading on so I'm not sure where is the problem.
Here is source code:
def sl_change(ticket, SL, TP, pair, p_open, volume, o_type):
order_request = {
'action': mt5.TRADE_ACTION_SLTP,
'ticket': ticket,
'type': o_type,
'price_open': p_open,
'volume': volume,
'sl': SL,
'tp': TP,
'symbol': pair,
'deviation': 20,
"magic": ea_magic_number,
"comment": "sent by python",
"type_time": mt5.ORDER_TIME_GTC, # good till cancelled
'type_filling': mt5.ORDER_FILLING_FOK,
"type_filling": mt5.ORDER_FILLING_RETURN,
}
result = mt5.order_check(order_request)
return result, order_request
pair = 'AUDUSD'
SL = 0.7101
positions = mt5.positions_get(symbol=pair)
ordernum = len(positions)
for i in range(0, ordernum):
position = positions[i]
ticket = position.ticket
TP = position.tp
volume = position.volume
o_type = position.type
p_open = position.price_open
print(positions)
time.sleep(5)
sl_change(ticket, SL, TP, pair, p_open, volume, o_type)
When I replace order_check with order_send still nothing happens.
This is what works for me now it's sample code if you don't understand input answer me I can give you more info
def changeslpl(ticket,pair,pos_type,SL,tp,ea_magic_number,volume,p_open):
request = {
"action": mt5.TRADE_ACTION_SLTP,
"symbol": pair,
"volume": volume,
"type": pos_type,
"position": ticket,
"price_open": p_open,
"sl": SL,
"tp": tp,
"deviation": 20,
"magic": ea_magic_number,
"comment": "python script open",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_FOK,
"ENUM_ORDER_STATE": mt5.ORDER_FILLING_RETURN,
}
#// perform the check and display the result 'as is'
result = mt5.order_send(request)
if result.retcode != mt5.TRADE_RETCODE_DONE:
print("4. order_send failed, retcode={}".format(result.retcode))
print(" result",result)
I found out why we were facing this problem.
When you execute a trade for the first time note that STOP_LOSS is always equal to for example 500 points difference from price but now you want to modify a stop loss.
So 500 points +/- current_price = e.g. 138.500 == OUR STOP_LOSS
The hack here is that you put price for a STOP_LOSS, NOT POINTS.
So the new request will be:
request = { 'action': mt5.TRADE_ACTION_SLTP, 'position': position.ticket, 'sl': 139.000, }
Now you will be finally on to something.
You should invert your order type. If it is a mt5.ORDER_TYPE_BUY, the SL/TP modification request should be a mt5.ORDER_TYPE_SELL
# This is what is important to you!
if(order_type == mt5.ORDER_TYPE_BUY):
order_type = mt5.ORDER_TYPE_SELL
price = mt5.symbol_info_tick(symbol).bid
else:
order_type = mt5.ORDER_TYPE_BUY
price = mt5.symbol_info_tick(symbol).ask
#importance ends here.
sltp_request = {
"action": mt5.TRADE_ACTION_SLTP,
"symbol": symbol,
"volume": float(volume),
"type": order_type,
"position": deal_id,
"sl": sl,
"price": price,
"magic": 234000,
"comment": "Change stop loss",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_IOC,
}
result = mt5.order_send(sltp_request)
I am getting command line output in below format
server
3 threads started
1.1.1.1 ONLINE at SUN
version: 1.2.3.4
en: net
1.1.1.2 ONLINE at SUN
version: 1.2.3.5
en: net
1.1.1.3 OFFLINE at SUN
version: 1.2.3.6
en: net
File: xys
high=600
low=70
name=lmn
I want parsed output like
l1 = [
{
"1.1.1.1": {
"status": "ONLINE",
"version": "1.2.3.4",
"en": "net"
},
"1.1.1.2": {
"status": "ONLINE",
"version": "1.2.3.5",
"en": "net"
},
"1.1.1.3": {
"status": "OFFLINE",
"version": "1.2.3.6",
"en": "net"
}
}
]
l2 = {
"File": "xys",
"high": 600,
"low": 70,
"name": "lmn"
}
I am getting all this in a string.
I Have split string by \n and created a list and then From "File" keyword created 2 lists of the main list. Then parsed both lists separately.
index = [i for i in range(len(output)) if "File" in output[i] ]
if index:
list1 = output[:index[0]]
list2 = output[index[0]:]
Is there any other more efficient way to parse this output.
What you did would work alright.
How much you should worry about this would depend on if this is just some quick setup being done for a few automated tests or if this code is for a service in an enterprise environment that has to stay running, but the one thing I would be worried about is what happens if File: ... is no longer the line that follows the IP addresses. If you want to make sure this does not throw of your code, you could go through the string line by line parsing it.
You would need your parser to check for all of the following cases:
The word server
The comments following the word server about how many threads where started
Any other comments after the word server
The IP address (regex is your friend)
The indented area that follows having found an IP addresses
key value pairs separated with a colon
key value pairs separated with an equals sign
But in all reality, I think what you did looks great. It's not that hard to change your code from searching for "File" to something else if that need ever arises. You will want to spend a little bit of time verifying that it appears that "File" does always proceed the IP addresses. If reliability is super important, then you will have some additional work to do in protecting yourself from running into problems later on if the order things come in is changes on you.
The solution provided below does not need to use the number of server threads running, as it can keep track of the thread number by removing all metadata preceding and following the threads' information:
with open("data.txt", "r") as inFile:
lines = [line for line in inFile]
lines = [line for line in lines[2:] if line != '\n']
threads = lines[:-4]
meta = lines[-4:]
l1 = []
l2 = {}
for i in range(0,len(threads),3):
status = threads[i]
version = threads[i+1]
en = threads[i+2]
status = status.split()
name = status[0]
status = status[1]
version = version.split()
version = version[1].strip()
en = en.split()
en = en[1].strip()
l1.append({name : {'status' : status, "version" : version, "en" : en}})
fileInfo = meta[0].strip().split(": ")
l2.update({fileInfo[0] : fileInfo[1]})
for elem in meta[1:]:
item = elem.strip().split("=")
l2.update({item[0] : item[1]})
The result will be:
For l1:
[{'1.1.1.1': {'status': 'ONLINE', 'version': '1.2.3.4', 'en': 'net'}}, {'1.1.1.2': {'status': 'ONLINE', 'version': '1.2.3.5', 'en': 'net'}}, {'1.1.1.3': {'status': 'OFFLINE', 'version': '1.2.3.6', 'en': 'net'}}]
For l2:
{'File': 'xys', 'high': '600', 'low': '70', 'name': 'lmn'}
I have a text file that is 26 Gb, The line format is as follow
/type/edition /books/OL10000135M 4 2010-04-24T17:54:01.503315 {"publishers": ["Bernan Press"], "physical_format": "Hardcover", "subtitle": "9th November - 3rd December, 1992", "key": "/books/OL10000135M", "title": "Parliamentary Debates, House of Lords, Bound Volumes, 1992-93", "identifiers": {"goodreads": ["6850240"]}, "isbn_13": ["9780107805401"], "languages": [{"key": "/languages/eng"}], "number_of_pages": 64, "isbn_10": ["0107805405"], "publish_date": "December 1993", "last_modified": {"type": "/type/datetime", "value": "2010-04-24T17:54:01.503315"}, "authors": [{"key": "/authors/OL2645777A"}], "latest_revision": 4, "works": [{"key": "/works/OL7925046W"}], "type": {"key": "/type/edition"}, "subjects": ["Government - Comparative", "Politics / Current Events"], "revision": 4}
I'm trying to get only the last columns which is a json and from that Json I'm only trying to save the "title", "isbn 13", "isbn 10"
I was able to save only the last column with this code
csv.field_size_limit(sys.maxsize)
# File names: to read in from and read out to
input_file = '../inputFile/ol_dump_editions_2019-10-31.txt'
output_file = '../outputFile/output.txt'
## ==================== ##
## Using module 'csv' ##
## ==================== ##
with open(input_file) as to_read:
with open(output_file, "w") as tmp_file:
reader = csv.reader(to_read, delimiter = "\t")
writer = csv.writer(tmp_file)
desired_column = [4] # text column
for row in reader: # read one row at a time
myColumn = list(row[i] for i in desired_column) # build the output row (process)
writer.writerow(myColumn) # write it
but this doesn't return a proper json object instead returns everything with a double quotations next to it. Also how would I extract certain values from the json as a new json
EDIT:
"{""publishers"": [""Bernan Press""], ""physical_format"": ""Hardcover"", ""subtitle"": ""9th November - 3rd December, 1992"", ""key"": ""/books/OL10000135M"", ""title"": ""Parliamentary Debates, House of Lords, Bound Volumes, 1992-93"", ""identifiers"": {""goodreads"": [""6850240""]}, ""isbn_13"": [""9780107805401""], ""languages"": [{""key"": ""/languages/eng""}], ""number_of_pages"": 64, ""isbn_10"": [""0107805405""], ""publish_date"": ""December 1993"", ""last_modified"": {""type"": ""/type/datetime"", ""value"": ""2010-04-24T17:54:01.503315""}, ""authors"": [{""key"": ""/authors/OL2645777A""}], ""latest_revision"": 4, ""works"": [{""key"": ""/works/OL7925046W""}], ""type"": {""key"": ""/type/edition""}, ""subjects"": [""Government - Comparative"", ""Politics / Current Events""], ""revision"": 4}"
EDIT 2:
so im trying to read this file which is a tab separated file with the following columns:
type - type of record (/type/edition, /type/work etc.)
key - unique key of the record. (/books/OL1M etc.)
revision - revision number of the record
last_modified - last modified timestamp
JSON - the complete record in JSON format
Im trying to read the JSON file and from that Json im only trying to get the "title", "isbn 13", "isbn 10" as a json and save it to the file as a row
so every row should look like the original but with only those key and values
Here's a straight-forward way of doing it. You would need to repeat this and extract the desired data from each line of the file as it's being read, line-by-line (the default way text file reading is handled in Python).
import json
line = '/type/edition /books/OL10000135M 4 2010-04-24T17:54:01.503315 {"publishers": ["Bernan Press"], "physical_format": "Hardcover", "subtitle": "9th November - 3rd December, 1992", "key": "/books/OL10000135M", "title": "Parliamentary Debates, House of Lords, Bound Volumes, 1992-93", "identifiers": {"goodreads": ["6850240"]}, "isbn_13": ["9780107805401"], "languages": [{"key": "/languages/eng"}], "number_of_pages": 64, "isbn_10": ["0107805405"], "publish_date": "December 1993", "last_modified": {"type": "/type/datetime", "value": "2010-04-24T17:54:01.503315"}, "authors": [{"key": "/authors/OL2645777A"}], "latest_revision": 4, "works": [{"key": "/works/OL7925046W"}], "type": {"key": "/type/edition"}, "subjects": ["Government - Comparative", "Politics / Current Events"], "revision": 4}'
csv_cols = line.split('\t')
json_data = json.loads(csv_cols[4])
#print(json.dumps(json_data, indent=4))
desired = {key: json_data[key] for key in ("title", "isbn_13", "isbn_10")}
result = json.dumps(desired, indent=4)
print(result)
Output from sample line:
{
"title": "Parliamentary Debates, House of Lords, Bound Volumes, 1992-93",
"isbn_13": [
"9780107805401"
],
"isbn_10": [
"0107805405"
]
}
So given that your current code returns the following:
result = '{""publishers"": [""Bernan Press""], ""physical_format"": ""Hardcover"", ""subtitle"": ""9th November - 3rd December, 1992"", ""key"": ""/books/OL10000135M"", ""title"": ""Parliamentary Debates, House of Lords, Bound Volumes, 1992-93"", ""identifiers"": {""goodreads"": [""6850240""]}, ""isbn_13"": [""9780107805401""], ""languages"": [{""key"": ""/languages/eng""}], ""number_of_pages"": 64, ""isbn_10"": [""0107805405""], ""publish_date"": ""December 1993"", ""last_modified"": {""type"": ""/type/datetime"", ""value"": ""2010-04-24T17:54:01.503315""}, ""authors"": [{""key"": ""/authors/OL2645777A""}], ""latest_revision"": 4, ""works"": [{""key"": ""/works/OL7925046W""}], ""type"": {""key"": ""/type/edition""}, ""subjects"": [""Government - Comparative"", ""Politics / Current Events""], ""revision"": 4}'
Looks like what you need to do is: First - Replace those double-double-quotes with regular double quotes, otherwise things are not parsible:
res = result.replace('""','"')
Now res is convertible to a JSON object:
import json
my_json = json.loads(res)
my_json now looks like this:
{'authors': [{'key': '/authors/OL2645777A'}],
'identifiers': {'goodreads': ['6850240']},
'isbn_10': ['0107805405'],
'isbn_13': ['9780107805401'],
'key': '/books/OL10000135M',
'languages': [{'key': '/languages/eng'}],
'last_modified': {'type': '/type/datetime',
'value': '2010-04-24T17:54:01.503315'},
'latest_revision': 4,
'number_of_pages': 64,
'physical_format': 'Hardcover',
'publish_date': 'December 1993',
'publishers': ['Bernan Press'],
'revision': 4,
'subjects': ['Government - Comparative', 'Politics / Current Events'],
'subtitle': '9th November - 3rd December, 1992',
'title': 'Parliamentary Debates, House of Lords, Bound Volumes, 1992-93',
'type': {'key': '/type/edition'},
'works': [{'key': '/works/OL7925046W'}]}
You can conveniently get any field you want from this object:
my_json['title']
# 'Parliamentary Debates, House of Lords, Bound Volumes, 1992-93'
my_json['isbn_10'][0]
# '0107805405'
Especially because your example is so large, I'd recommend using a specialized library such as pandas, which has a read_csv method, or even dask, which supports out-of-memory operations.
Both of these systems will automatically parse out the quotations for you, and dask will do so in "pieces" direct from disk so you never have to try to load 26GB into RAM.
In both libraries, you can then access the columns you want like this:
data = read_csv(PATH)
data["ColumnName"]
You can then parse these rows either using json.loads() (import json) or you can use the pandas/dask json implementations. If you can give some more details of what you're expecting, I can help you draft a more specific code example.
Good luck!
I saved your data to a file to see if i could read just the rows, let me know if this works:
lines = zzread.split('\n')
temp=[]
for to_read in lines:
if len(to_read) == 0:
break
new_to_read = '{' + to_read.split('{',1)[1]
temp.append(json.loads(new_to_read))
for row in temp:
print(row['isbn_13'])
If that works this should create a json for you:
lines = zzread.split('\n')
temp=[]
for to_read in lines:
if len(to_read) == 0:
break
new_to_read = '{' + to_read.split('{',1)[1]
temp.append(json.loads(new_to_read))
new_json=[]
for row in temp:
new_json.append({'title': row['title'], 'isbn_13': row['isbn_13'], 'isbn_10': row['isbn_10']})
I am getting stuck trying to figure out an efficient way to parse some plaintext that is structured with indents (from a word doc). Example (note: indentation below not rendering on mobile version of SO):
Attendance records 8 F 1921-2010 Box 2
1921-1927, 1932-1944
1937-1939,1948-1966,
1971-1979, 1989-1994, 2010
Number of meetings attended each year 1 F 1991-1994 Box 2
Papers re: Safaris 10 F 1951-2011 Box 2
Incomplete; Includes correspondence
about beginning “Safaris” may also
include announcements, invitations,
reports, attendance, and charges; some
photographs.
See also: Correspondence and Minutes
So the unindented text is the parent record data and each set of indented text below each parent data line are some notes for that data (which are also split into multiple lines themselves).
So far I have a crude script to parse out the unindented parent lines so that I get a list of dictionary items:
import re
f = open('example_text.txt', 'r')
lines = f.readlines()
records = []
for line in lines:
if line[0].isalpha():
processed = re.split('\s{2,}', line)
for i in processed:
title = processed[0]
rec_id = processed[1]
years = processed[2]
location = processed[3]
records.append({
"title": title,
"id": rec_id,
"years": years,
"location": location
})
elif not line[0].isalpha():
print "These are the notes, but attaching them to the above records is not clear"
print records`
and this produces:
[{'id': '8 F',
'location': 'Box 2',
'title': 'Attendance records',
'years': '1921-2010'},
{'id': '1 F',
'location': 'Box 2',
'title': 'Number of meetings attended each year',
'years': '1991-1994'},
{'id': '10 F',
'location': 'Box 2',
'title': 'Papers re: Safaris',
'years': '1951-2011'}]
But now I want to add to each record the notes to the effect of:
[{'id': '8 F',
'location': 'Box 2',
'title': 'Attendance records',
'years': '1921-2010',
'notes': '1921-1927, 1932-1944 1937-1939,1948-1966, 1971-1979, 1989-1994, 2010'
},
...]
What's confusing me is that I am assuming this procedural approach, line by line, and I'm not sure if there is a more Pythonic way to do this. I am more used to working with scraping webpages and with those at least you have selectors, here it's hard to double back going one by one down the line and I was hoping someone might be able to shake my thinking loose and provide a fresh view on a better way to attack this.
Update
Just adding the condition suggested by answer below over the indented lines worked fine:
import re
import repr as _repr
from pprint import pprint
f = open('example_text.txt', 'r')
lines = f.readlines()
records = []
for line in lines:
if line[0].isalpha():
processed = re.split('\s{2,}', line)
#print processed
for i in processed:
title = processed[0]
rec_id = processed[1]
years = processed[2]
location = processed[3]
if not line[0].isalpha():
record['notes'].append(line)
continue
record = { "title": title,
"id": rec_id,
"years": years,
"location": location,
"notes": []}
records.append(record)
pprint(records)
As you have already solved the parsing of the records, I will only focus on how to read the notes of each one:
records = []
with open('data.txt', 'r') as lines:
for line in lines:
if line.startswith ('\t'):
record ['notes'].append (line [1:])
continue
record = {'title': line, 'notes': [] }
records.append (record)
for record in records:
print ('Record is', record ['title'] )
print ('Notes are', record ['notes'] )
print ()