2
\$\begingroup\$

I'm fairly new to programming and this is the 2nd thing I've done in python.

This code creates a /Tiles directory in the folder where the script is ran, then it makes an X (8) number of folders inside of /Tiles.

Inside of those 8 folders it makes a Y number of subfolders and downloads Z number of images per Y folder.

Y and Z are the same number but change depending on the X folder.

X folder 0 contains 2^0 Y folders and 2^0 Z images per Y folder.

Next X folder 2^1, etc until 8 folders or 2^7.

Any general or python specific advice for a newbie?

Also, any design advice?

I was thinking of having a loading bar of some sorts because it's ~20k images and was looking into this https://stackoverflow.com/questions/3173320/text-progress-bar-in-the-console

But in the end decided I just want to finish this up since I was done with the main functionality.

[..] means the code is on the same line but I made a new one for the purposes of reading here without scrolling.

Thanks.

import os
import urllib.request
import ctypes
print ("This script will download map tiles from [Redacted link]")
print ("The further it gets the more time it will take to fill the current folder.")
print ("Because the number of images increases exponentially.")
print ("You can check the progress by going into the latest folder.")
print ("When it is done the taskbar icon will flash and prompt you to close the window.")
# stores current directory
path = os.getcwd()
print ("The current working directory is {}.".format(path) + "\n")
# adds the names of the new directory to be created
path += "/Tiles/"
# defines the access rights
access_rights = 0o755
# creates the tiles directory
try:
 os.mkdir(path, access_rights)
except OSError:
 print ("Creation of the tiles directory {} failed.".format(path))
else:
 print ("All files will be downloaded to {}.".format(path))
 # for testing:
 # print ("Successfully created the tiles directory {}".format(path))
# number of x subfolders
x_folders = 8
# number of y subfolders and z images - different folders have a
[..] # different number of subfolders amd images
yz_array = [2**0, 2**1, 2**2, 2**3, 2**4, 2**5, 2**6, 2**7]
# main loop 
# creates the x directories
for x in range(x_folders):
 try:
 os.mkdir("{}/{}".format(path,x), access_rights)
 except OSError:
 print ("Failed to create the X directory - {}.".format(x))
 break
 except:
 print("Something went wrong creating X folders.")
 break
 else:
 print("Downloading images to {}{}.".format(path,x))
 # creates the y directories
 for y in range(yz_array[x]):
 try:
 os.mkdir("{}/{}/{}".format(path,x,y), access_rights)
 except OSError:
 print ("Failed to create the Y directory - {}.".format(y))
 break
 except:
 print("Something went wrong creating Y folders.")
 break
 else:
 pass
 # downloads z images
 for z in range(yz_array[x]):
 try:
 urllib.request.urlretrieve("[Redacted link]
[..]/{}/{}/{}.png" \
 .format(x,y,z), "{}/{}/{}/{}.png".format(path,x,y,z))
 except: 
 print("Something went wrong downloading Z images.")
 break
 else:
 pass
 print("Successfully filled folder {}{}.".format(path,x) + "\n")
print("Finished running.")
ctypes.windll.user32.FlashWindow(ctypes.windll.kernel32.
[..]GetConsoleWindow(),True) # flashes the taskbar icon
print("Press Enter to close")
input("\n")
asked Feb 22, 2020 at 6:09
\$\endgroup\$
0

1 Answer 1

4
\$\begingroup\$

Cool python exercise! And a nice job.
I'm going to assume you are using python3. There are some points of improvement:

  • Multiline strings: In python you can create a string with more than one line using """ so you an put all of the printing in the beginning of your program in one print statement.
  • Pathlib: There is a library called pathlib which allows you to create multi platform path objects. Try to use it instead of concatenating strings yourself.
  • Constants in capitals: Is access_rights a constant? Write it in capital letters if so (It's a normal naming convention).
  • String formatting: You can use fstrings instead of format, it looks much nicer and more readable (to me). So "Downloading images to {}{}.".format(path,x) can now be f"Downloading images to {path}{x}.".
  • List comprehension: you can create the yz_array using list comprehension, it is a bit complicated but it will look like: [2 ** x for x in range(8)] - will get the same result!
  • Meaningful variable names: instead of x even use x_index.
  • Meaningful exceptions: Using Exception as e you can print the system error, giving the user more information.
  • Logical error: Notice that even if there was an error in the file creation process you will still print "Successfully filled folder" which is not true. Add a boolean variable to prevent that.
  • Multi Platform compatibility: You are probably using windows, but on other os your code will crush, by adding another try - catch you can prevent that. You can also try and find the os and create a matching case for windows.

Maybe:

  • Functions: You can use functions to avoid the indentations.
  • Spaces: According to PEP8 you should add a space after a , and you should not add space after a print statement.
  • Use type annotation: (Last but this one is my personal favourite) When your code gets complicated and you start to use function - Do not forget to read about type annotations.

Overall - greate code, nicely written.
Good luck and Have fun!

answered Feb 23, 2020 at 21:11
\$\endgroup\$
1
  • \$\begingroup\$ Appreciate the response! I'll look into all the suggestions and make adjustments. Thanks a lot. \$\endgroup\$ Commented Feb 24, 2020 at 22:28

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.