Python Selenium: Alternative to string formatting for lists? - python

I am trying to take the value from the input and put it into the browser.find_elements_by_xpath("//div[#class='v1Nh3 kIKUG _bz0w']") function. However, the string formatting surely doesn't work, since it's the list, hence it throws the AttributeError.
Does anyone know any alternatives to use with lists (possibly without iterating over each file)?
xpath_to_links = input('Enter the xpath to links: ')
posts = browser.find_elements_by_xpath("//div[#class='{}']").format(devops)
AttributeError: 'list' object has no attribute 'format'

Looks like the reason of error is that you are placing the format function in the wrong place, so instead of operating on string "//div[#class='{}']" you call it for the list returned by find_elements_by_xpath. Could you please try to replace your code with one of the following lines ?
posts = browser.find_elements_by_xpath("//div[#class='{}']".format(devops))
posts = browser.find_elements_by_xpath(f"//div[#class='{devops}']")

Related

How can I check with a loop if a group of strings is empty or not?

I am trying to go through a loop of strings (alias names) in order to apply the unidecode, and to avoid the error of not having aliases words in some cases, I am using an if/else to check if there is a string or not, so I can apply the unidecode.
I tried by checking the length of the word by doing this code, but it keeps saying "list' object has no attribute 'element". I am not sure what should I do.
alias=record.findall("./person/names/aliases/alias")
alias_name=[element.text for element in alias]
if len(alias_name.element.text)!=0:
alias_names_str = ','.join(alias_name)
alias_names_str=unidecode.unidecode(alias_names_str)
else:
alias_name.element.text="NONE"
Not exactly sure what you are trying to accomplish, but it looks like an XML or HTML decoder.
# alias is an iterable of elements
alias=record.findall("./person/names/aliases/alias")
# alias_names is a list of strings, you have already dereferenced the text
alias_names=[element.text for element in alias]
if len(alias_names)>0:
alias_names_str = ','.join(alias_names)
alias_names_str = unidecode.unidecode(alias_names_str)
else:
alias_names_str = "NONE"
thank you! yes, I want to apply the unidecode to remove the diacritics of those strings. Your code helped, then I needed to change some details and it worked!
Thank you so much! :)

How to read and understand 'Unexpected type(s)' problem in Python?

I am trying to split a String based on the symbol: | and further split each String in it on a : and convert the result into a dictionary as below.
column_data = 'component_id:numeric(15,0)|name:character varying(30)|operation_num:numeric(15,0)|component_item:numeric(15,0)|item_number:character varying(800)|last_update_date:timestamp without time zone|last_updated_by:numeric(15,0)|creation_date:timestamp without time zone|created_by:numeric(15,0)|item_num:numeric|component_quantity:numeric|component_yield_factor:numeric|component_remarks:character varying(240)|effectivity_date:date|change_notice:character varying(10)'
column_names = dict(item.split(":") for item in gp_column_data.split("|"))
But I see a warning on the IDE that says:
Unexpected type(s): (Generator[List[str], Any, None]) Possible types: (Mapping) (Iterable[Tuple[Any, Any]])
The image can be seen below:
The same logic worked fine on Python shell but when I put the logic on IDE, the line highlights.
gp_column_data is a str that I am receiving as a method parameter.
def fix_source_columns(gp_column_data: str, precision_columns:str):
column_names = dict(item.split(":") for item in gp_column_data.split("|"))
I am new to Python and see these messages often on IDE.
Could anyone let me know if this is an error message ? If so how can I fix the problem ?
The IDE is smart enough to warn you that item.split(":") might output an iterable with a single element in case item does not contain : (or more than 2 if there are multiple :). In these cases, dict will fail because it expects an iterable in which all elements have exactly 2 elements (which is exactly what Iterable[Tuple[Any, Any]] in the warning means).

Python iteration 'Nonetype' using 'in' statement

Hi so I loaded a JSON file into a list using the following code:
import json
postal_mtl = ['H9W','H4W','H9P','H3B','H3A','H2Z','H3H','H3G','H3X','H9J','H1B','H1G','H1H','H4X','H2Y','H9R','H3Z','H3Y']
data = []
with open('business.json',encoding="utf8") as f:
for line in f:
data.append(json.loads(line))
Now I am trying to find the number of restaurants in montreal in this dataset (coming from Yelp). I tried the following code:
compteur3 = 0
for i in range(len(data)):
if data[i]['postal_code'][0:3] in postal_mtl and 'Restaurants' in data[i]['categories']:
compteur3 += 1
print(compteur3)
But I am getting an error saying "argument of type 'NoneType' is not iterable" I guess Python considers the date[i]['categories'] as a Nonetype ? Why is that ? If I enter the following I can see that it's clearly a string:
data[5]['categories']
'Shipping Centers, Couriers & Delivery Services, Local Services, Printing Services'
Now I just want to iterate over all the elements in my data list and find each line where we have the word 'Restaurants' (I got the Montreal stuff fixed)... Any idea ? Thanks !
Based on the code provided, it seems that the error is most likely coming from the if condition. Specifically, it is most likely coming from the statement 'Restaurants' in data[i]['categories']. Under the hood, Python is trying to iterate through data[i]['categories'] to see if 'Restaurants' is in it. If data[i]['categories'] is None, that would cause this error.
This may be caused by the JSON string not being formatted the way you expected. Perhaps, if no categories were listed in the 'Categories' field, a null was put instead of an empty list. To check for this in your code, you can try the following:
compteur3 = 0
for i in range(len(data)):
is_inmontreal = data[i]['postal_code'][0:3] in postal_mtl
is_restaurant = data[i]['categories'] and 'Restaurants' in data[i]['categories']
if is_inmontreal and is_restaurant:
compteur3 += 1
print(compteur3)
Above, I simply split the condition into two parts. Functionally, this would be the same as having the conditions in one line, it just makes it slightly clearer. However, I also added a check in is_restaurant to see if data[i]['categories'] has a positive truth value. In effect, this will check if the value is not None and it is not an empty list. If you really want to be explicit, you can also do
is_restaurant = data[i]['categories'] is not None and 'Restaurants' in data[i]['categories']
Depending on how dirty the data is, you may need to go a little further than this and use exception handling. However, the above is just speculation as I do not know what the data looks like.

Looping over a list - 'int' object is not subscriptable

I've uploaded a PDF using PyPDF2. Here's my code:
PageNo=list(range(0,pfr.numPages))
for i in PageNo:
pg = writer.addPage(i)
PageNo creates a list of all the page numbers and I'm trying to add each page from the list into a new PDF, but when I run this script, I'm getting 'int' object is not subscriptable. I know it's an error in my for loop, and I'm sure it's obvious, but any insight on my mistake above would be appreciated.
Thanks!
Edit - here's the solution:
for i in list(range(0,pfr.numPages))
pg = pfr.getPage(i)
writer.addPage(pg)
Without seeing more code, like what exactly is pfr.numPages? Where is it created? How is it used? the error is happening because PageNo is being evaluated as an int, so its less likely its an error in your for loop and more likely an error in your list. Assuming pfr.numPages is an array of some type, try this:
for i in range(0, len(pfr.numPages)):
pg = writer.addPage(prf.numPages[i])
However as mentioned before, if PageNo is being evaluated as an int, then pfr.numPages isn't an array or its an array with one element. Pay close attention to the trace if this errors, it will tell you which line, and if it says int is not subscriptable on the line with prf.numPages, then you know that your problem is deeper than this for loop.
I am assuming that writer is a PdfFileWriter object. In that case, you will have to pass a page retrieved from pfr to the writer.addPage method, instead of passing an integer.
for i in pfr.pages:
writer.addPage(i)

python list TypeError: 'int' object is not iterable

I made this code in python but it has much errors that i want you to check it for me as I'm new at python
for i in range(phones):
pho = int(raw_input( "Phone Number %d : " % (i+1)))
phNums.append(pho)
for name in range(phot):
name1 = '{0}/phone.txt'.format(pathname)
file = open(name1, 'w')
file.write = (pho)
file.close()
First issue that when i run the script i had this error
Traceback (most recent call last):
file.write = (pho)
AttributeError: 'file' object attribute 'write' is read-only
The script should do this scenario :
First the user give the number of Perfixes and the count of the progs
The script will count phot which it the progs / phones
then the user will give each phone number
the script will take the first number and write it in the text file "phone.txt" on the folders 1 2 3 until reach phot count of folders then move to the next number and continue writing to next count of folders ... etc
please check what is the issue with the code
phNums.append(pho) adds ints to your list phNums, you then try to iterate over phNums[i] which is each int in your list which you cannot do and why you get the error.
Just iterate over each element directly:
for i in phNums:
name = '{}phone.txt'.format(i) # i is an int so use str.format to concat
Or looking at your code, you may have meant to iterate over a list of names that is not provided in your code.
This is a simple error that has already been answered sufficiently, so rather than give you a direct answer, I want to direct you through my debugging process. Hopefully this will save time in the future.
First step is to check where the error occurred:
for name in phNums[i]:
Ok, now what was the error?
TypeError: 'int' object is not iterable
The "for" statement will iterate over a given iterable and is generally like this:
for _item_ in _iterable_
Now we know which part of the line to look at. What type is phNums[i] ?
phNums is defined earlier as a list, but with phNums[i], we want to find the type of the items in that list. It appears that the only time the script adds to the list is when appending pho, which is an int.
There's the issue, you're trying to iterate over an int item! The error makes sense now, but how should we fix it?
note: I tried going further, but your description is unclear. Do you want the folder structure to be:
1/phone.txt
2/phone.txt
3/phone.txt
where phone.txt contains the phone number in each?

Categories