Python Forum
Is there a better way to write this case scenario?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Is there a better way to write this case scenario?
#1
Relatively new programmer here, familiar with the 'basic' languages such as VB, but not so crash hot with Python. Is there a better way to write the script below? It may not look 100% correct for pure python scripting as it's actually a derivative named ArcPy. They are generally very close, so I could work out any suggestions, I'm sure.

The script essentially returns the page size based on the pageSize.height and pageSize.width functions. I intend to remove the print("page size") portions and replace with some variables once I know this step is working.

if mxd.pageSize.height == 1189:
	if mxd.pageSize.width == 841:
		print("Page size is A0 Portrait")
if mxd.pageSize.height == 841:
	if mxd.pageSize.width == 1189:
		print("Page size is A0 Landscape")
	elif mxd.pageSize.width == 594:
		print("Page size is A1 Portrait")
elif mxd.pageSize.height == 594:
	if mxd.pageSize.width == 841:
		print("Page size is A1 Landscape")
	elif mxd.pageSize.width == 420:
		print("Page size is A2 Portrait")
elif mxd.pageSize.height == 420:
	if mxd.pageSize.width == 594:
		print("Page size is A2 Landscape")
	elif mxd.pageSize.width == 297:
		print("Page size is A3 Portrait")
elif mxd.pageSize.height == 297:
	if mxd.pageSize.width == 420:
		print("Page size is A3 Landscape")
	elif mxd.pageSize.width == 210:
		print("Page size is A4 Portrait")
elif mxd.pageSize.height == 210:
	if mxd.pageSize.width == 297:
		print("Page size is A4 Landscape")
Reply
#2
in python we usually use dicts in such kind of case scenario
here are two implementations, the second being more modular by implementing function

page_sizes = {1189:'A0', 841:'A1', 594:'A2', 420:'A3', 297:'A4'}
page_orientations = {True:'Portrait', False:'Landscape'}

p_size = page_sizes[max(mxd.pageSize.height, mxd.pageSize.width)]
p_orientation = page_orientations[mxd.pageSize.height>mxd.pageSize.width]
print("Page size is {} {}".format(p_size, p_orientation))
def page_info(height, width):
    page_sizes = {1189:'A0', 841:'A1', 594:'A2', 420:'A3', 297:'A4'}
    page_orientations = {True:'Portrait', False:'Landscape'}
    p_size = page_sizes[max(height, width)]
    p_orientation = page_orientations[height>width]
    return {'size':p_size, 'orientation':p_orientation}

p_info = page_info(height=mxd.pageSize.height, width=mxd.pageSize.width)
print("Page size is {size} {orientation}".format(**p_info))

Eventually, to avoid KeyError when retrieve value from page_size (i.e. hieght is not present in the dict) you may use
p_size = page_sizes.get(max(height, width), 'Unknown') # may use None if you prefer
instead of
p_size = page_sizes[max(height, width)]
also note that if height=width, page_info will return "Landscape" for orientation. You may change the code if you prefer 'Portrait' in this particular case.
Reply
#3
I was thinking further and realised that the function (and your if/else construct to that matter) does not cover all possibilities. Here is more 'universal" one that takes into account when height and width is not a standard one, e.g. cases like height 297 (standard) and width=100, which is not a standard one.

def page_info(height, width):
    if height == width:
        p_size, p_orientation = 'Unknown', 'Square'
    else:
        p_dimensions = tuple(sorted([height, width], reverse=True))
        page_sizes = {(1189, 841):'A0', (841, 594):'A1', (594, 420):'A2',
                      (420, 297):'A3', (297, 210):'A4'}
        page_orientations = {True:'Portrait', False:'Landscape'}
        p_size = page_sizes.get(p_dimensions, 'Unknown')
        p_orientation = page_orientations[height>width]
    return {'size':p_size, 'orientation':p_orientation}

for height, width in ((1189, 841), (210, 297), (200, 100), (300, 300)):
    p_info = page_info(height, width)
    print("Page size is {size}, orientation is {orientation}".format(**p_info))
Output:
Page size is A0, orientation is Portrait Page size is A4, orientation is Landscape Page size is Unknown, orientation is Portrait Page size is Unknown, orientation is Square
Reply
#4
That is super helpful, thank you.

It looks like I have some reading to do on things like Tuple and dictionaries in order to come up to speed.

Once again, amazing work, thanks.
Reply
#5
The main takeaway is the use of the dict in such scenario (i.e. instead of case construct available in other languages). The use of the tuple as a key is something particular to the current task - we need to use both height and width as key and because tuple is hashable, it can be used as key in dictionary.
Reply
#6
I see that. It makes sense, really.

I'm now struggling through working the code into my project and having lots of fun dealing with numbers coming from other places and trying to match them to those in this snippet. Good learning experience right here.
Reply
#7
With the last example you've to pay attention about the order of the definition for page_sizes.

page_sizes = {(1189, 841):'A0', (841, 594):'A1', (594, 420):'A2',
                      (420, 297):'A3', (297, 210):'A4'}
The big numbers comes first, so this is the portrait orientation of this formats. If you accidentally exchange them (small number first, big number after), you'll never find the key.

You can calculate the sizes also with a function, here a small example:

from collections import OrderedDict


def format_sizes():
    formats_by_class = OrderedDict()
    formats_by_size = OrderedDict()
    w, h = 841, 1189 # definition of A0
    for i in range(11):
        formats_by_class['A{}'.format(i)] = (h, w)
        formats_by_size[(h, w)] = 'A{}'.format(i)
        w, h = round(h / 2), w
    return formats_by_class, formats_by_size
Instead of a normal dict, I use an OrderedDict, which keeps the order. So if you print the output, the order is preserved.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#8
In actual fact the issues have forced me to adopt a fairly creative approach and I'm probably going to reuse the concept of tuples for force some answers.

Thanks again for the above snippet.
Reply
#9
(Sep-25-2017, 09:44 AM)DeaD_EyE Wrote: If you accidentally exchange them (small number first, big number after), you'll never find the key.


actually that is not true. In my snippet, I sort the height and weight in descending order (post#3, line#5). You can see from the example it is dealing corretly with both Portrait and Landscape orientated pages
Reply
#10
Yes, you're sorting p_dimensions, but you're not sorting page_sizes. The current data is in the right order height > width. But what is the right definition of ISO Paper Size? I read this article: https://en.wikipedia.org/wiki/Paper_size...aper_sizes but I can't find anything about height and width which belongs to A0 - A10. I know it's a bit of nit picking...
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Switch case or match case? Frankduc 9 4,523 Jan-20-2022, 01:56 PM
Last Post: Frankduc
  Help: write 'case' with Python ICanIBB 2 1,880 Jan-27-2021, 09:39 PM
Last Post: Larz60+
  How to write switch case statement in Python pyhelp 9 9,251 Nov-11-2018, 08:53 PM
Last Post: woooee

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020