Qt Python Calendar: selected day direct access - python

I have calendar that is working fine.
Here is the function that display the full date:
def selectDate(self,date):
self.fullDate = str(date.day()) + " / " + str(date.month()) + " / " + str(date.year())
print "full date: %s" % self.fullDate
And here the code with the calendar:
def TabCalendar(self):
self.calendar = QtGui.QCalendarWidget(self.tab)
self.calendar.setGeometry(QtCore.QRect(self.x1, self.y1, self.x2, self.y2))
QtCore.QObject.connect(self.calendar, QtCore.SIGNAL("selectionChanged()"), self.selectDate)
QtCore.QObject.connect(self.calendar, QtCore.SIGNAL("clicked(QDate)"), self.selectDate)
To have direct access to selected day, I am calling the function selectDate based on connect event, and then using the 'date' to obtain the precise date.day and so on -- which is working fine.
The only awkward thing that is annoying me is that it gives the following warning..
TypeError: turbSchedule_selectDate() takes exactly 2 arguments (1 given)
Any suggestion to stop this TypeError warning?
All comments and suggestions are highly appreciated.

I guess that the slot called by the selectdate signal shouldn't have any argument. You can access the selectedDate by the corresponding calendar method.
See the c++ docs: http://doc.trolltech.com/4.3/widgets-calendarwidget.html
So your code should be something like:
def selectDate(self):
date = self.calendar.selectedDate()
self.fullDate = str(date.day()) + " / " + str(date.month()) + " / " + str(date.year())
print "full date: %s" % self.fullDate

Related

How to allow users to enter number as a parameter in an API url call

I just started learning python today, so please take it easy. I have created a method that allows someone to enter a number and it will deliver the park name and weather for that location from MLB and Weather.gov. I have them hard coded for a couple of test cases to make sure it works. I want for the user to be able to input the venue number in it so that I can display the information for the proper location. I have searched around quite a bit but I can't seem to find exactly what Im looking for. For example, in the following url: https://statsapi.mlb.com/api/v1/venues/**3289**?hydrate=location, I want the user to pick the number that goes right there. Once I am able to do this, I should be able to take the latitude and longitude from the API call and use that in the weather API call. I'm just stuck right now. I am using the command line so all I need is for someone to be able to input mlbweather(xxx) and hit return. I tried using params, but that just seems to append to the end of the url and adds a ? and equals, so that doesnt work.
def mlbweather(venueNum):
citi = 3289
wrigley = 17
if venueNum == citi:
mlb_api = requests.get('https://statsapi.mlb.com/api/v1/venues/3289?hydrate=location')
mlb_data = mlb_api.text
parse_json = json.loads(mlb_data)
venueWanted = parse_json['venues'][0]['name']
print("Venue:" + " " + venueWanted)
weather_api = requests.get('https://api.weather.gov/gridpoints/OKX/37,37/forecast')
weather_data = weather_api.text
parse_json = json.loads(weather_data)
weatherWanted = parse_json['properties']['periods'][0]['detailedForecast']
print("Current Weather: \n" + weatherWanted)
elif venueNum == wrigley:
mlb_api = requests.get('https://statsapi.mlb.com/api/v1/venues/17?hydrate=location')
mlb_data = mlb_api.text
parse_json = json.loads(mlb_data)
venueWanted = parse_json['venues'][0]['name']
print("Venue:" + " " + venueWanted)
weather_api = requests.get('https://api.weather.gov/gridpoints/LOT/74,75/forecast')
weather_data = weather_api.text
parse_json = json.loads(weather_data)
weatherWanted = parse_json['properties']['periods'][0]['detailedForecast']
print("Current Weather: \n" + weatherWanted)
else:
print("Either you typed an invalid venue number or we don't have that info")
You're looking for simple string concatenation:
def mlbweather(venueNum):
mlb_api = requests.get('https://statsapi.mlb.com/api/v1/venues/' + str(venueNum) + '?hydrate=location')
mlb_data = mlb_api.text
parse_json = json.loads(mlb_data)
venueWanted = parse_json['venues'][0]['name']
print("Venue:" + " " + venueWanted)
weather_api = requests.get('https://api.weather.gov/gridpoints/OKX/37,37/forecast')
weather_data = weather_api.text
parse_json = json.loads(weather_data)
weatherWanted = parse_json['properties']['periods'][0]['detailedForecast']
print("Current Weather: \n" + weatherWanted)
mlbweather(3289)
Venue: Citi Field
Current Weather:
Patchy fog after 4am. Partly cloudy, with a low around 72. South wind 2 to 7 mph.
Alternatively, you can use fstrings:
mlb_api = requests.get(f'https://statsapi.mlb.com/api/v1/venues/{venueNum}?hydrate=location')

Revit, Using Python, Can't get the Family "Type Names" for a Family, Just the ID

I've tried for hours to attempt to solve this myself so I can learn. I'm able to get the Family I want out of Revit (called familyToUpdate) and list the family (symbol) types, but I can't get the type name itself only their ID's. I want to compare the actual Type Name against a text parameter I called (typeToDelete) so that I can delete only the types I know are not being used. I've been through numerous examples but can never get them to work.
Here is my code to date:
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
app = doc.Application
familyToUpdate = "MyFamily"
typeToDelete = "MyFamilyType"
print "Family Name = " + familyToUpdate
print "Type To Delete = " + typeToDelete
#Delete Family Type
Elements = FilteredElementCollector(doc).OfClass(Family).ToElements()
for m in Elements:
try:
if m.Name.startswith((familyToUpdate)):
symbols = list(m.GetFamilySymbolIds())
for i in symbols:
print "Family Type Id = " + str(i)
famsymbol = doc.GetElement(i)
print "famsymbol = " + str(famsymbol)
#symbolName = famsymbol.Family.Name
#print symbolName
#if symbolName == typeToDelete:
# print "I found the type name"
except:
pass
Answered it myself. Work on it for hours, then FINALLY post a question. Take one more look at it, and there it is!!!
Here's the code for anyone else in the future fumbling through what I did:
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *
uidoc = __revit__.ActiveUIDocument
doc = __revit__.ActiveUIDocument.Document
app = doc.Application
familyToUpdate = "VA Titleblock Consultant Logo (PIN07)"
typeToDelete = "VA Titleblock Consultant Logo (PIN07) (Hagerman)"
print "Family Name = " + familyToUpdate
print "Type To Delete = " + typeToDelete + "\n\n"
#Delete Family Type
Elements = FilteredElementCollector(doc).OfClass(Family).ToElements()
for m in Elements:
try:
if m.Name.startswith((familyToUpdate)):
symbols = list(m.GetFamilySymbolIds())
for i in symbols:
#print "Family Type Id = " + str(i)
famsymbol = doc.GetElement(i)
#print "Symbol ID = " + str(famsymbol)
symbolName = famsymbol.get_Parameter(BuiltInParameter.SYMBOL_NAME_PARAM).AsString()
print "SymbolName = " + symbolName
except:
pass
Thank you for the solution. In it, you are retrieving the symbol name from the SYMBOL_NAME_PARAM built-in parameter. That is perfectly valid. An easier and more direct way to read the symbol name is to simply query the Element.Name property. Element is the parent class of all Revit database resident objects, including FamilySymbol.
Element.Name will not work because of multi-level inheritance. try the following instead:
name = Element.Name.GetValue(familysymbol)

Parsing JSON in Python

I have below query stored in a variable I got and I need to fetch value of 'resource_status'.
I need 'UPDATE_IN_PROGRESS'
As requested, putting the code here. The variable evntsdata is storing the events list.
try:
evntsdata = str(hc.events.list(stack_name)[0]).split(" ") # this is the variable that is getting the JSON response (or so)
#print(evntsdata[715:733])
#event_handle = evntsdata[715:733]
if event_handle == 'UPDATE_IN_PROGRESS':
loopcontinue = True
while loopcontinue:
evntsdata = str(hc.events.list(stack_name)[0]).split(" ")
#event_handle = evntsdata[715:733]
if (event_handle == 'UPDATE_COMPLETE'):
loopcontinue = False
print(str(timestamp()) + " " + "Stack Update is Completed!" + ' - ' + evntsdata[-3] + ' = ' + evntsdata[-1])
else:
print(str(timestamp()) + " " + "Stack Update in Progress!" + ' - ' + evntsdata[-3] + ' = ' + evntsdata[-1])
time.sleep(10)
else:
print("No updates to perform")
exit(0)
except AttributeError as e:
print(str(timestamp()) + " " + "ERROR: Stack Update Failure")
raise
print(evntsdata) has below result
['<Event', "{'resource_name':", "'Stackstack1',", "'event_time':", "'2017-05-26T12:10:43',", "'links':", "[{'href':", "'x',", "'rel':", "'self'},", "{'href':", "'x',", "'rel':", "'resource'},", "{'href':", "'x',", "'rel':", "'stack'}],", "'logical_resource_id':", "'Stackstack1',", "'resource_status':", "'UPDATE_IN_PROGRESS',", "'resource_status_reason':", "'Stack", 'UPDATE', "started',", "'physical_resource_id':", "'xxx',", "'id':", "'xxx'}>"]
Do not serialize and parse objects when the data is in front of you. This is inefficient and hard to understand and maintain. The solution is quite trivial:
data = hc.events.list(stack_name)[0].to_dict()
event_handle = data['resource_status']
It's not JSON, it's a class that you've printed
class Event(base.Resource):
def __repr__(self):
return "<Event %s>" % self._info
Try poking around the source code to get access to the dictionary self._info, then access your fields according
For example,
event_info = hc.events.list(stack_name)[0]._info
event_handle = event_info['resource_status']
Though, there may be another way like calling to_dict() instead, since the underscore indicates a private variable

How to write an exception in the following case in Python3?

I need to revise a python code (given by a programmer) which I would like to use for a genealogy project of mine. I am very new to python and start being able to read code. Yet, I do not know how to fix the following thing.
I get the following error message when executing the code:
self['gebort'] += ", Taufe: %s" % place.get_title()
KeyError: 'gebort'
The issue is that for one of the persons in my database only the date of baptism (here: Taufe) is known but not the date of birth. This is were the code fails.
This is the relevant snippet of the code basis:
birth_ref = person.get_birth_ref()
if birth_ref:
birth = database.get_event_from_handle(birth_ref.ref)
self['gjahr'] = birth.get_date_object().get_year()
if self['gjahr'] >= 1990:
self['mindj'] = True
self['gebdat'] = dd.display(birth.get_date_object())
self['plaingebdat'] = self['gebdat']
place_handle = birth.get_place_handle()
self['geborthandle'] = place_handle
place = database.get_place_from_handle(place_handle)
if place:
self['gebort'] = place.get_title()
self['plaingebort'] = self['gebort']
for eventref in person.get_event_ref_list():
event = database.get_event_from_handle(eventref.ref)
if event.get_type() in (gramps.gen.lib.EventType.CHRISTEN, gramps.gen.lib.EventType.BAPTISM):
self['gebdat'] += ", Taufe: %s" % dd.display(event.get_date_object())
place_handle = event.get_place_handle()
place = database.get_place_from_handle(place_handle)
if place:
self['gebort'] += ", Taufe: %s" % place.get_title()
Now, I do not know to add an exception handling when there is no birth date/place found so that the code would not give out any values of birth. Would somebody be able to point me to the right direction?
Instead of:
dict_name['gebort'] += ", Taufe: %s" % place.get_title()
you could write
dict_name['gebort'] = dict_name.get('gebort', '') + ", Taufe: %s" % place.get_title()
As already written, naming something self is not clever, or is the code above from a class derived from dict? Using .get you can define what is returned in case if there is no key of that name, in the exampe an empty string.

Python subprocess doesn't run until calling process finished

EDIT 1 - added more code
I'm not sure that proc.communicate was needed, it was one of the suggestions I found from some other stackoverflow code.(Sorry I was tired last night and didn't think too much before asking the question.)
I should add that I am not an experienced coder (mechanical engineer) as you can probably tell from my code
In my Gui I have a button to call a subprocess
The subprocess (screenshot-cmd.exe) creates a png of a cropped screen shot but it won't actually produce the file until there is an error or if the button click event is over.
This makes me think that the subprocess is not actually run until the event is finished
I want to call the process several times after a single button press and move the files that it produces after each one is produced
if I use proc.wait(), the process hangs indefinitely.
How do I stop this?
# function to take a single image called 'fileName' and place it in directory 'dir'
def takeImage(dir,fileName):
# calculate the view to capture to get the whole display window in.
clientRect = win32gui.GetClientRect(win32gui.GetForegroundWindow())
windowRect = win32gui.GetWindowRect(win32gui.GetForegroundWindow())
print(windowRect)
windowSize = [windowRect[2]-windowRect[0],windowRect[3]-windowRect[1]]
print(windowSize)
print(clientRect)
diffSize = [windowSize[0] -clientRect[2], windowSize[1] - clientRect[3]]
lrbBorder = diffSize[0]/2
topBorder = diffSize[1] - lrbBorder
print("sizeDiff = " + str(diffSize))
windowName = win32gui.GetWindowText(win32gui.GetForegroundWindow())
handleId = win32gui.GetForegroundWindow()
leftMar = designLabel.GetPosition()[0] + lrbBorder
topMar = designLabel.GetPosition()[1] + topBorder + designLabel.GetSize()[1]
rightMar = leftMar + scene.width
bottMar = topMar+scene.height
margins = [leftMar,topMar,rightMar,bottMar]
print(margins)
# now print the view.
#command_line = r"screenshot-cmd -wt '" + windowName + "' -rc " + str(margins[0]) + " " + str(margins[1]) + " " + str(margins[2]) + " " + str(margins[3]) + " -o " + fileName
command_line = r"screenshot-cmd -wt '" + windowName + "' -rc " + str(margins[0]) + " " + str(margins[1]) + " " + str(margins[2]) + " " + str(margins[3]) + " -o " + fileName
print(command_line)
args = shlex.split(command_line)
proc = subprocess.Popen(args)
proc.wait()
wx.Yield()
if not os.path.isdir(dir):
os.makedirs(dir)
newPath = os.path.join(dir,fileName)
if os.path.exists(newPath):
os.remove(newPath)
oldPath = os.path.join(os.getcwd(), fileName)
print("Old Path: " + oldPath)
print("Exists: " + str(os.path.exists(oldPath)))
shutil.move(oldPath,newPath)
return
#event called upon clicking 'takeTenImag' button
def takeTenImgE(evt):
global designNo
global workingDirectory
global numDesigns
fileNameRoot = "test_"
fileExtention = ".png"
# check there are at least 10 designs
if numDesigns > 9 and os.path.exists(workingDirectory):
# find directory path to put images in
dir = os.path.join(workingDirectory, "images")
# for each design
for x in range(10):
print("design =" + str(designNo))
fileName = fileNameRoot + str(designNo) + fileExtention
print("------------------")
print("for x = " + str(x) + " " + fileName)
# create image and save
print(dir)
takeImage(dir,fileName)
#move to next design
wx.PostEvent(forwardDesign, wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, forwardDesign.GetId()) )
wx.Yield()
print("design =" + str(designNo))
return
takeTenImg = wx.Button(p, label='Take Ten Images', pos=(rb + visScaleText.GetSize()[0]+10,takeImg.GetPosition()[1]+5 +takeImg.GetSize()[1]), size = (100,30))
takeTenImg.Bind(wx.EVT_BUTTON, takeTenImgE)
https://code.google.com/p/screenshot-cmd/
Barnaby, you may be over-complicating your subprocess use. Popen is typically used for when you need to communicate with the process during the time it is running. From the sound of it, you don't need to do that, so might want to use a higher level function. See the docs on subprocess' various invocations, and perhaps try using the call method. You'll need shell=True, as detailed in SO questions such as this one.
I've found that the error is in my calling of subprocess.
I was using:
command_line = r"screenshot-cmd -wt '" + windowName + ...."
args = shlex.split(command_line)
subprocess.call(args,shell=True)
changing this to:
command_line = r"screenshot-cmd -wt '" + windowName + ...."
subprocess.call(command_line,shell=True)
solves the hang.
What is peculiar is that both options work when not inside a wx button click event(i.e. a python script launched from the command line), but only the second works when inside the wx button click event.
If anyone could enlighten me why that would be most appreciated.
EDIT:
upon further investigation, the hang is caused by trying to specify the active window in screenshot-cmd.
To solve this I find the position of the window using
windowRect = win32gui.GetWindowRect(win32gui.GetForegroundWindow())
and then use screenshot-cmd without specifying a window.
This solves all issues although it is unclear why this causes problems

Categories

Resources