You can handle the positive case using the following:
In [150]:
import re
df['fundleverage'] = '+' + df['name'].str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('X') + '00'
df
Out[150]:
name fundleverage
0 BULL AXP UN X3 VON +300
1 BULL ESTOX X12 S +1200
You can use np.where to handle both cases in a one liner:
In [151]:
df['fundleverage'] = np.where(df['name'].str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('X').str.isdigit(), '+' + df['name'].str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('X') + '00', '+100')
df
Out[151]:
name fundleverage
0 BULL AXP UN X3 VON +300
1 BULL ESTOX X12 S +1200
So the above uses the vectorised str methods strip, extract and isdigit to achieve what you want.
Update
After you changed your requirements (which you should not do for future reference) you can mask the df for the bull and bear cases:
In [189]:
import re
df = pd.DataFrame(["BULL AXP UN X3 VON", "BEAR ESTOX 12x S"], columns=["name"])
bull_mask_name = df.loc[df['name'].str.contains('bull', case=False), 'name']
bear_mask_name = df.loc[df['name'].str.contains('bear', case=False), 'name']
df.loc[df['name'].str.contains('bull', case=False), 'fundleverage'] = np.where(bull_mask_name.str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('X').str.isdigit(), '+' + bull_mask_name.str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('X') + '00', '+100')
df.loc[df['name'].str.contains('bear', case=False), 'fundleverage'] = np.where(bear_mask_name.str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('x').str.isdigit(), '-' + bear_mask_name.str.extract(r"(X\d+|\d+X)\s", flags=re.IGNORECASE).str.strip('x') + '00', '-100')
df
Out[189]:
name fundleverage
0 BULL AXP UN X3 VON +300
1 BEAR ESTOX 12x S -1200
Answer from EdChum on Stack Overflowpython - Attribute Error: 'str' object has no attribute 'str' - Stack Overflow
python - AttributeError: 'str' object has no attribute 'str' - Stack Overflow
python - AttributeError: 'str' object has no attribute 'xpath' - Stack Overflow
python - Apply function 'str' object has no attribute 'str' - Stack Overflow
Try this:
import scrapy
class CybexbotSpider(scrapy.Spider):
name = 'cybexbot'
allowed_domains = ['http://links.com']
start_urls = ['http://links.com']
def parse(self, response):
data=response.xpath('//tr[contains(@class,"GridView")]')
for d in data[1:]:
print(type(d))
temp=dict()
temp['Code']=d.xpath('tr//td[1]/a/text()').extract()
temp['Desc']=d.xpath('tr//td[2]/a/text()').extract()
yield temp
Once you extract it, it becomes a string so the library can no longer process it
I believe you need something like this (notice how I use relative XPath to get values):
for row in response.xpath('//tr[contains(@class,"GridView")][position() > 1]'):
temp=dict()
temp['Code'] = row.xpath('.//td[1]/a/text()').extract_first() # may be you need .extract() here
temp['Desc'] = row.xpath('.//td[2]/a/text()').extract_first() # may be you need .extract() here
yield temp
At this line:zipfile.ZipFile.extractall(zip, None, pwd=str.encode(pwd))
i allways get the error (in the title).
My zip path (as string zip) is like this:zipFile = r'/home/itsthooor/This That/Empty.zip'
Where's the problem?
I saw a stack overflow post about it, but it didn't me help at all.
Your code has multiple problems - not just the one that has been answered by @Tanishq
You entire approach is not ideal. It's much better to limit your Student class to storing data and handling its representation. Acquisition of the data should be dealt with separately.
Something like this:
Copyfrom typing import Any
class Student:
def __init__(self, name: str):
self._name: str = name
self._data: dict[str, float] = {}
def __add__(self, __value: Any) -> 'Student':
subject, score = __value
self._data[subject] = score
return self
def __str__(self):
r = [self._name]
for subject, score in self._data.items():
r.append(f'{subject} -> {score}')
return '\n'.join(r)
name = input('Student name: ')
student = Student(name)
n = int(input('Number of subjects: '))
for _ in range(n):
subject = input('Subject name: ')
score = float(input('Score: '))
student += (subject, score)
print(student)
Console example:
CopyStudent name: John
Number of subjects: 2
Subject name: English
Score: 65
Subject name: Geography
Score: 58
John
English -> 65.0
Geography -> 58.0
Note:
Numeric input validation omitted for brevity
Here is one way of doing what you want
Copyclass student(object):
def __init__(self, standard: int, name: str, age: int, address: str):
self.standard = standard
self.name = name
self.age = age
self.address = address
self.calc()
def calc(self):
self.subject = []
self.score = []
N = (int)(input('Please enter number of Subjects: '))
for i in range(N):
item = input('Enter Subject name: ').upper()
self.subject.append(item)
for i in range(len(self.subject)):
item = input(f'Please Enter the score for {self.subject[i]}: ')
self.score.append(item)
student1 = student(standard=10, name="foo", age=13, address="bar")
Your error:
- You are directly calling the
calcfunction of the class,student, without instantiating it. (You can checkout staticmethods in Python if you still want to do this.) - The
selfis then treated as a variable name, and since you pass''as the value of self, it is inferred to be a string. - This is why you get the error, that the
strhas no attributename- because theselfis a string and not the instance.
Some notes:
- You need to instantiate the class,
student, and pass in the required arguments (as shown in the last line of my solution). - You can merge the
printbefore theinputinto one, as shown. - You can merge the
calcfunction with__init__, as mentioned in the comments. - You are returning within the for loop, after you do
self.subject.append(...). This will not let to have more than 1 subject, and your scores will always be empty - since the functioncalcwill never reach the score handling section. - You might want to look at exception handling to handle the input of number of subjects, here.
