While loop doesn't work inside my for loop - python-3.x

mi_path = "F:\\releases\\"
validate = False
for dirs, paths, files in os.walk(mi_path):
while not validate:
if str(release_buscar) in str(dirs):
print("Release encontrada", dirs)
break
else:
print("Release no encontrada")
release_buscar = input("Introduce el nombre otra vez:")
validate = False
print("Final del bucle")
I want to list all dirs from a route how I am doing and then find a string in that route. I need to do if string in dirs then make something if that string isn't in, then ask again for a valid string
I get the dirs with os.walk function and it return a string with dirs from the route. Then I want to find a string in a string(dirs).
The problem if what never find the folder, always jump to the else:.

for that you can use os.path.exists("my_dir") and your code gonna be something like
import os
def get_existing_dir():
my_dir = input("Please enter a directory name : ")
while True:
if os.path.exists(my_dir):
return my_dir
my_dir = input("Please enter an existing directory name : ")

Related

skip function if folder is empty

I want to read folder name(A/B/C/D) and call the convenable function for each file in Files folder and then process the next file (pass automatically to the next file and function).
Now i want to skip the function if the folder is empty how can i add this condition to my code please
Here is my code :
base_path = 'Files/'
for name in os.listdir(base_path):
path = os.path.join(base_path, name)
if os.path.isdir(path):
files = [os.path.join(path, f) for f in os.listdir(path)]
if name_to_func[path].__code__.co_argcount == len(files):
name_to_func[path](*files)
else:
name_to_func[path](files)
else:
name_to_func[path](path)
You can check like this if a directory is empty:
if len(os.listdir(path)) == 0:
# Directory is empty
else:
# Directory is not empty

cant get my while loops working the way i want it to

i am trying to get this code to work properly where if you input a number it will revert you back to the name=input prompt and once you enter alphabetical characters and not numerical characters it will allow you to move on to the next set of code but it keeps returning you to the name = input and doesnt let you through the rest of the code
def setup():
global name
global HP
global SP
global MP
while True:
try:
name = input('can you please tell me your name? ')
name2=int(name)
if not name.isalpha==True and not name2.isdigit==False:
break
except Exception:
print('please input your name')
continue
HP = randint(17,20)
SP = randint(17,20)
MP = randint(17,20)
print('welcome ['+name+':]: to the moon landing expedition')
There is a problem at name2=int(name) This causes an exception unless you type all numbers. In turn, this triggers the Exception and loops it forever. Your while loop seems fine.
What i think you should do:
while True:
name = input('What is your name')
isnum = False
for i in name:
if i.isnumeric():
isnum = True
break
if isnum:
print('Please type your name.')
continue
break

Determine if a path is valid in a class constructor

Without violating the guideline that a constructor should do work, I need to determine if the provided string (destination_directory) is a valid path before assigning it in the constructor.
It doesn't have to exist, but the provide string must be a valid one, i.e. no invalid symbols, or illegal characters. My project will run on Windows only, not Linux.
I looked at this page, but the answers seem to try and open the directory to test if the provided string is valid.
I also tried os.path.isabs(path)but it doesn't provide the results I require. For example, it says that T:\\\\Pictures is a absolute path, while that may be true, the \\\\ should mean the path is invalid.
Is there a clean, perhaps one line way of achieving what I want?
def __init__(self, destination_directory: str)
self._validate_path(path=destination_directory)
self.destination_directory = destination_directory
def _validate_path(self, path)
# code to validate path should go here.
We now a few things about a path, it contains at least a drive letter and subdirectories.
We also have rules about what symbols are not allowed in directories. We also know that a drive letter contains a single character.
Instead of allowing users of our class to pass in a full path, we break it down and only allow valid strings for directories names and one letter for the drive. When everything is validated, we can use the os module to build our path.
Here is how I would structure my Folder class:
class Folder:
def __init__(self, *subdirectories, root_drive):
self._validate_drive_letter(letter = root_drive)
self._validate_path(path=subdirectories)
self._root_drive = root_drive
self._subdirectories = subdirectories
def _validate_drive_letter(self, letter):
if not letter or len(letter) > 2 or not letter.isalpha():
raise ValueError("Drive letter is invalid")
def _validate_path(self, path):
self._forbidden_characters = ["<", ">", ":", "/", '"', "|", "?", "*", '\\']
for character in path:
for item in character:
if item in self._forbidden_characters:
raise ValueError("Directory cannot contain invalid characters")
def construct_full_path(self) -> str:
# use the os module and constructor parameters to build a valid path
def __str__(self) -> str:
return f"Drive Letter: {self._root_drive} Subdirectories: {self._subdirectories}"
Main:
def main():
try:
portable_drive = Folder("Pictures", "Landscape", root_drive="R") # Valid
# Using the construct_full_path() function, the returned string would be:
# R:\Pictures\Landscape
# Notice the user doesn't provide the : or the \, the class will do it.
vacation_pictures = Folder("Vac??tion", root_drive="T") # Will raise ValueError
# If we fix the error and call construct_full_path() we will get T:\Vacation
except ValueError as error:
print(error)
else:
print(portable_drive)
print(vacation_pictures)
if __name__ == "__main__":
main()
It may not be the best approach, but it works. I know a nested for loop is bad, but I don't see any other way to validate the individual characters of a string.
A regex solution:
import re
windows_path_regex = re.compile(r"""
\A
(?:(?:[a-z]:|\\\\[a-z0-9_.$\●-]+\\[a-z0-9_.$\●-]+)\\| # Drive
\\?[^\\/:*?"<>|\r\n]+\\?) # Relative path
(?:[^\\/:*?"<>|\r\n]+\\)* # Folder
[^\\/:*?"<>|\r\n]* # File
\Z
""", re.VERBOSE|re.I)
d = windows_path_regex .match(r"\test\txt.txt")
print(bool(d))
Note that\ is a valid path but / is not.
I used 8.18. Validate Windows Paths as a reference.

Python: Checking file names in a directory one by one

I am asking for user input of a name, and I want to search in the directory of the file with the code whether a file exists that is called the same thing as the inputted name, if yes, then the program asks for a new name, if not, then it will create a file with that name. I am struggling because the code I have written only checks the first file in the directory and doesn't continue with the rest.
The code that I am having the problem with looks something like this:
import os
Name = input("Please enter name for new file")
if Name in os.listdir():
print("Sorry this name already exists, please choose another one")
break
else:
NewFile = open("Name" + ".txt", "w+")
break
You can use glob:
import glob
existing = glob.glob('*.txt')
name = '{}.txt'.format(input("Please enter name for new file"))
if name in existing:
print("Sorry this name already exists, please choose another one")
else:
newfile = open(name, "w+")

File won't open when being passed from a function

How come it's not opening the file I put into the function? It opens when I plug the file name directly into the main program, but not when I try to pass it through the function. It gives me a FileNotFoundError.
def get_valid_filename(prompt):
'''Use prompt (a string) to ask the user to type the name of a file. If
the file does not exist, keep asking until they give a valid filename.
Return the name of that file.'''
filename = input(prompt)
if os.path.isfile(filename) == False:
print ("That file does not exist.")
filename = input(prompt)
return filename
if __name__ == '__main__':
prompt = 'enter the name of the file with unknown author:'
mystery_filename = get_valid_filename(prompt)
# readlines gives us the file as a list of strings each ending in '\n'
text = open(mystery_filename, 'r').read()
print (text)
get_valid_filename should look like this:
def get_valid_filename(prompt):
while True:
filename = input(prompt):
if os.path.exists(filename):
return filename
print('that file does not exist')

Resources