-
Robert_Tompkins
Traceback (most recent call last): File "/private/var/mobile/Containers/Shared/AppGroup/4696D4C5-8877-4DAB-9679-C1C82C4A5C18/Pythonista3/Documents/CompletedPrograms/ImageMatching.py", line 412, in <module> matchImage() File "/private/var/mobile/Containers/Shared/AppGroup/4696D4C5-8877-4DAB-9679-C1C82C4A5C18/Pythonista3/Documents/CompletedPrograms/ImageMatching.py", line 278, in matchImage ImageChops.screen(image1, outlinedDiff).show() File "/var/containers/Bundle/Application/24BCA42A-E70C-42BD-BD39-68CECBB90922/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/PIL/ImageChops.py", line 138, in screen return image1._new(image1.im.chop_screen(image2.im)) ValueError: images do not match
Oops, one more conversion I guess š
-
Robert_Tompkins
Possibly from here-ish?
https://forum.omz-software.com/topic/1935/how-can-i-convert-a-pil-image-to-a-ui-image/10Iām going to try this out, I know very little about images/image-data. All Iām trying to do is compare two images, change pixel color for differences and draw a circle (Path.oval) around the bounds with some offset. Apparently I canāt open an image and draw on it via ImageContext.. so.. conversion, conversion, conversion, undo all conversions, .show(). Since paste() appears to be broken as well.
-
Robert_Tompkins
@ccc ... Seriously? Lol. I open every file Iām curious about via Notepad++ just to see whatās goin on..but thatās at work/on a PC.
Without Notepad++ the thought never crossed my mind that maybe the .pyui file contains easily extractable/readable data. Itās even in dict/json format -.-
Well, thanks for the info. Iāll mess around with it and see if I can modify the function to serialize/deserialize the json and generate the copy/paste-able code still. This opens a world of options. Thanks! -
Robert_Tompkins
Hey guys, Iām just posting this here so other people can use it if they made the same mistake I did.
I wrote many programs and later built UI files in Pythonista to complement them. However, when I wrote a math program with UI for my daughter, every change I made required me to share BOTH the .py and .pyui files in order for her to use the updated version.So I wrote this function/method (that is still a work in progress) to simplify this process.
It essentially takes a UI.View() object and generates copy/paste-able code that can be pasted into your .py file to setup and configure the view so you donāt have to load a .pyui file.Small example of code produced from simple .pyui below. Below that is the function.
3 ui.TextField()
3 ui.Label()
2 ui.Button()#_______________________________________________ acInputField = ui.TextField() calculateDistanceButton = ui.Button() label2 = ui.Label() dcInputField = ui.TextField() label1 = ui.Label() arcDistanceOutputField = ui.TextField() label3 = ui.Label() resetFieldsButton = ui.Button() acInputField.name = 'acInputField' acInputField.x = 175.0 acInputField.y = 250.0 acInputField.width = 150.0 acInputField.height = 32.0 acInputField.background_color = (0.250545, 0.250545, 0.250545, 1.0) acInputField.border_width = 0.0 acInputField.tint_color = (0.431645, 0.431645, 0.431645, 1.0) acInputField.font = ('.SFUI-Regular', 17.0) acInputField.text = '' acInputField.autoresizing = 'LRTB' acInputField.alignment = 0 acInputField.flex = 'LRTB' acInputField.corner_radius = 0.0 acInputField.content_mode = 0 calculateDistanceButton.name = 'calculateDistanceButton' calculateDistanceButton.action = calculateDistanceTapped calculateDistanceButton.x = 75.0 calculateDistanceButton.y = 350.0 calculateDistanceButton.width = 250.0 calculateDistanceButton.height = 75.0 calculateDistanceButton.background_color = (0.401961, 0.401961, 0.401961, 1.0) calculateDistanceButton.border_width = 0.0 calculateDistanceButton.tint_color = (0.25, 1.0, 0.25, 1.0) calculateDistanceButton.title = 'Calculate' calculateDistanceButton.font = ('.SFUI-Semibold', 20.0) calculateDistanceButton.autoresizing = 'TB' calculateDistanceButton.flex = 'TB' calculateDistanceButton.corner_radius = 15.0 calculateDistanceButton.content_mode = 0 label2.name = 'label2' label2.x = 25.0 label2.y = 250.0 label2.width = 125.0 label2.height = 32.0 label2.background_color = (0.251634, 0.251634, 0.251634, 1.0) label2.border_width = 0.0 label2.tint_color = (0.25, 0.6084999999999998, 1.0, 1.0) label2.font = ('.SFUI-Regular', 18.0) label2.text = 'VAC' label2.autoresizing = 'LRTB' label2.alignment = 1 label2.flex = 'LRTB' label2.corner_radius = 0.0 label2.line_break_mode = 4 label2.content_mode = 7 label2.number_of_lines = 0 dcInputField.name = 'dcInputField' dcInputField.x = 175.0 dcInputField.y = 210.0 dcInputField.width = 150.0 dcInputField.height = 32.0 dcInputField.background_color = (0.250545, 0.250545, 0.250545, 1.0) dcInputField.border_width = 0.0 dcInputField.tint_color = (0.431645, 0.431645, 0.431645, 1.0) dcInputField.font = ('.SFUI-Regular', 17.0) dcInputField.text = '' dcInputField.autoresizing = 'LRTB' dcInputField.alignment = 0 dcInputField.flex = 'LRTB' dcInputField.corner_radius = 0.0 dcInputField.content_mode = 0 label1.name = 'label1' label1.x = 25.0 label1.y = 210.0 label1.width = 125.0 label1.height = 32.0 label1.background_color = (0.251634, 0.251634, 0.251634, 1.0) label1.border_width = 0.0 label1.tint_color = (0.25, 0.6084999999999998, 1.0, 1.0) label1.font = ('.SFUI-Regular', 18.0) label1.text = 'VDC' label1.autoresizing = 'LRTB' label1.alignment = 1 label1.flex = 'LRTB' label1.corner_radius = 0.0 label1.line_break_mode = 4 label1.content_mode = 7 label1.number_of_lines = 0 arcDistanceOutputField.name = 'arcDistanceOutputField' arcDistanceOutputField.x = 175.0 arcDistanceOutputField.y = 290.0 arcDistanceOutputField.width = 150.0 arcDistanceOutputField.height = 32.0 arcDistanceOutputField.background_color = (0.248366, 0.248366, 0.248366, 1.0) arcDistanceOutputField.border_width = 0.0 arcDistanceOutputField.tint_color = (0.32543625, 0.32543625, 0.32543625, 1.0) arcDistanceOutputField.font = ('.SFUI-Regular', 17.0) arcDistanceOutputField.text = '' arcDistanceOutputField.autoresizing = 'LRTB' arcDistanceOutputField.alignment = 0 arcDistanceOutputField.flex = 'LRTB' arcDistanceOutputField.corner_radius = 0.0 arcDistanceOutputField.content_mode = 0 label3.name = 'label3' label3.x = 25.0 label3.y = 290.0 label3.width = 125.0 label3.height = 32.0 label3.background_color = (0.248366, 0.248366, 0.248366, 1.0) label3.border_width = 0.0 label3.tint_color = (0.25, 0.6084999999999998, 1.0, 1.0) label3.font = ('.SFUI-Regular', 18.0) label3.text = 'Arc Distance' label3.autoresizing = 'LRTB' label3.alignment = 1 label3.flex = 'LRTB' label3.corner_radius = 0.0 label3.line_break_mode = 4 label3.content_mode = 7 label3.number_of_lines = 0 resetFieldsButton.name = 'resetFieldsButton' resetFieldsButton.action = resetFieldsTapped resetFieldsButton.x = 75.0 resetFieldsButton.y = 433.0 resetFieldsButton.width = 250.0 resetFieldsButton.height = 75.0 resetFieldsButton.background_color = (0.401961, 0.401961, 0.401961, 1.0) resetFieldsButton.border_width = 0.0 resetFieldsButton.tint_color = (0.25, 1.0, 0.25, 1.0) resetFieldsButton.title = 'Reset Fields' resetFieldsButton.font = ('.SFUI-Semibold', 20.0) resetFieldsButton.autoresizing = 'TB' resetFieldsButton.flex = 'TB' resetFieldsButton.corner_radius = 15.0 resetFieldsButton.content_mode = 0 fullView.add_subview(acInputField) fullView.add_subview(calculateDistanceButton) fullView.add_subview(label2) fullView.add_subview(dcInputField) fullView.add_subview(label1) fullView.add_subview(arcDistanceOutputField) fullView.add_subview(label3) fullView.add_subview(resetFieldsButton) #_______________________________________________
def generateUserInterfaceCode(viewObject): fullView = viewObject listOfTypes = [] listOfChildren = [] dictOfObjects = {} debugDict = {} listOfObjectTypes = [] for object in fullView.subviews: objectType = object._pyui['class'] text = None action = None autoresizing = None alignment = None flex = None corner_radius = None border_color = None border_width = None background_color = None tint_color = None title = None font = None continuous = None content_mode = None line_break_mode = None number_of_lines = None name = object.name x = object.x y = object.y width = object.width height = object.height try: tint_color = object.tint_color except AttributeError: None try: border_color = object.border_color except AttributeError: None try: border_width = object.border_width except AttributeError: None try: title = f"'{object.title}'" except AttributeError: None try: text = f"'{object.text}'" except AttributeError: None try: font = object.font except AttributeError: None try: autoresizing = f"'{object.autoresizing}'" except AttributeError: None try: flex = f"'{object.flex}'" except AttributeError: None try: alignment = object.alignment except AttributeError: None try: corner_radius = object.corner_radius except AttributeError: None try: background_color = object.background_color except AttributeError: None try: continuous = object.continuous except AttributeError: None try: if object.action != None: action = object.action action = str(action) #action = action.lstrip('<function ') actionList = action.split(' ') action = actionList[1] if object.name == "difficultySlider": action = f"difficultyChanged" else: action = f"{action}Tapped" except AttributeError: None try: line_break_mode = object.line_break_mode except AttributeError: None try: content_mode = object.content_mode except AttributeError: None try: number_of_lines = object.number_of_lines except AttributeError: None dictOfObjects[name] = { 'type' : objectType, 'action' : action, 'x' : x, 'y' : y, 'width' : width, 'height' : height, 'background_color' : background_color, 'border_color' : border_color, 'border_width' : border_width, 'tint_color' : tint_color, 'title' : title, 'font' : font, 'text' : text, 'autoresizing' : autoresizing, 'alignment' : alignment, 'flex' : flex, 'corner_radius' : corner_radius, 'continuous' : continuous, 'line_break_mode' : line_break_mode, 'content_mode' : content_mode, 'number_of_lines' : number_of_lines} continuous = None title = None text = None listOfChildren.append(object) print(f"#{'_' * 47}\n") for k, v in dictOfObjects.items(): print(f"{k} = ui.{v['type']}()") for k, v in dictOfObjects.items(): print(f"{k}.name = '{k}'") for key, value in v.items(): if value != None and key != 'type': print(f"{k}.{key} = {value}") for k, v in dictOfObjects.items(): if k != 'type': print(f"fullView.add_subview({k})") print(f"#{'_' * 47}\n") ```
-
Robert_Tompkins
@ccc
Thanks! Yea... I just recently started using that lol. This is why I try writing programs for a wide range of things. Otherwise I donāt learn about these things!Not trying to hijack.. but how can I simplify this? Goal of this was to just strip anything that is not always used in my use-case. Like punctuation. Iām detecting text on-screen via OCR and extract it and attempt to find a match. But I want to be lenient lol.
textString = textString.replace('[', '') textString = textString.replace(']', '') textString = textString.replace(' ', ' ') textString = textString.replace("'", '') textString = textString.strip() textString = textString.lower()
-
Robert_Tompkins
So I went through like 20 of my programs for a good, simple example..
But I realized that I donāt convert any user input in-line. I prefer to do it after storing the input to a variable.
This allows me to do my own tests on it before falling through to a default error message.For example, in my game, prompting for a name to be used for profile loading/saving..
def loadProfile(self, passedPlayerName=None, resetProfile=None): global profileLoaded listOfDebugNames = ["admin", "ADMIN", "Admin", "sudo", "SUDO", "Sudo"] if passedPlayerName != None: self.playerName = passedPlayerName else: self.playerName = console.input_alert( f'Please enter your Profile Name', 'Case Sensitive, probably', hide_cancel_button=True) if self.playerName == "": self.playerName = "NOOB" if self.playerName in listOfDebugNames: # Debug handling is done here
So with string being default, you can first check if it is equal to a debug string you specify.
Or, you can check the type of it first and handle it case by case / type by type.
Hereās a random example of me handling two cases where the item passed to a function can be a string, or can be a list of strings.def getPriceEsoItem(item): global dictOfItemFields global dictOfSearches device = zxtouch("127.0.0.1") dictOfSearches = {} argumentType = type(item) if argumentType == list: for string in item: length = len(string) dictOfSearches[string] = length else: length = len(item) dictOfSearches[item] = length
Maybe thereās a downside that I am missing.. But to me, it seems to always be better to store user input first. Then do your own handling for various input types depending on your use-case.
-
Robert_Tompkins
@talns100 said:
Hey, when I execute a script and enters a number as input it automatically behaves as a string.
How to fix that? I canāt add inputs cuase of it.
Will casting fix the problem?
Why does it happen in the first place?Yes, user input is treated as a string by default but casting does fix the problem.
Since user input can be of any type, handling it as a string is the safest way to store the value.You can easily cast it in-line
userInput = int(input(āEnter an integer:\nā))
Or later
userInput = input(āEnter stuff:\nā) integerInput = int(userInput) floatInput = float(userInput)
Thatās my two cents!
-
Robert_Tompkins
Unless somebody knows how to correct this.
Let me know if you can/cannot replicate this on your device.Problem: Debugger window font color is black, background color is automatically set to match āEditor > Editor Backgroundā color. So text is unreadable if you use a dark editor background while using Light iPhone theme.
Solution: Add debugger window attributes to the Custom Theme configuration options.
This would allow us to specify the color of the text and background separately from wherever they are currently pulling their attributes from.
Debugger Background
Debugger TextAnyone else have this issue? Or found a workaround?
-
Robert_Tompkins
Actually what you have right there is perfect!
@JonB, I donāt need the little things! However, I will probably create a new version of this code and turn it into that for practice! I could definitely use it.
Edit: On second thought, that sounds real complicated. I might quit Python attempting that at this point :)@cvp Again, those changes are exactly what I needed, thanks!
(https://imgur.com/a/TiCqTRz)^^ Dunno how to do inline images haha. I ran out of ideas, so thatās a link to what I have with your changes.
-
Robert_Tompkins
Ooo awesome. Thanks! I have been playing around with it trying to figure out a way to oāoffwetā the starting point so that the center of the slice on each vertical and horizontal axes line up. (Like on a dartboard).
Let me see if I can throw an image here to show you what I mean.