Need to print with spaces - python

I have to print name with spaces, can u help me please?
I got the code like this:
class Perfil:
def __init__(self,email,nome,cidade):
self.email=email
self.nome=nome
self.cidade=cidade
def __str__(self):
return "Perfil de "+self.nome+" ""("+self.email+")"" de "+self.cidade
def getCidade(self):
return self.cidade
def setCidade(self,novo):
self.cidade=novo
def getDominio(self):
t=self.email.rpartition("#")
return t[2]
def limpaNome(self):
new=""
if self.nome.isalpha()==True:
return self.nome
else:
for i in self.nome:
if i.isalpha()==True:
new +=i
return new
When i run the program:
>>> p=Perfil("lol#mail.pt","Ze Car231los", "Porto")
>>> p.limpaNome()
'ZeCarlos'
I need a print like 'Ze Carlos' (with space)
Basically i need to wrote a program using abstract data types (class Profile) to save information for each user. Each object got the following attributes:
email
name
city
The class should have the following methods to manipulate the objects above
Method
__init__(self, email, name, city) - constructor
__str__(self)
getCity(self) - return the value of atribute city
getCity(self.new) - return the atribute city with a new value
getDomain(self) - example: lol#mail.com sugestion: use the method partition (i have to return mail.com only)
cleanName(self) - change the atribute name, deleting characters WICH are not alphabetic or spaces sugestion: use method isalpha

If all you want to do is remove all occurrences of '0','1','2',...,'9' from the string, then you could use str.translate like this:
def limpaNome(self):
return self.nome.translate({ord(c):None for c in '0123456789'})
Note that there is no need for getters/setters like this in Python:
def getCidade(self):
return self.cidade
def setCidade(self,novo):
self.cidade=novo
Instead, just let the user access/set the attribute directly: self.cidade. If, at some point, you'd like to run a function whenever the attribute is accessed or assigned to, then you can make cidade a property without having to change the usage syntax.
You could even make getDominio and limpaNome properties too:
#property
def dominio(self):
t=self.email.rpartition("#")
return t[2]
#property
def limpaNome(self):
return self.nome.translate({ord(c):None for c in '0123456789'})
Notice you don't need paretheses when accessing or setting the property. The syntax looks the same as though lipaNome were a plain attribute:
>>> p=Perfil("lol#mail.pt","Ze Car231los", "Porto")
>>> p.limpaNome
Ze Carllos
>>> p.dominio
mail.pt

import string
# ... the rest of your code
# ...
def limpaNome(self):
whitelist = set(string.ascii_uppercase+string.ascii_lowercase+" ")
if self.nome.isalpha():
return self.nome
else:
return ''.join(ch for ch in self.nome if ch in whitelist)
Or with regex:
import re
# ...
# ...
def limpaNome(self):
return re.sub(r"[^a-zA-Z ]",'',self.nome)
Note that if I were you, I'd do:
class Perfil:
def __init__(self, email, nome, cidade):
self.email = email
self.cidade = cidade
self.nome = limpaNome(nome)

Related

Print class object content through python function

I am reading some threads but i don't understand how do proceed.
I have a function and class as follow. How can I print the class content through the function?
def get_address(address):
resource = 'address/{0}?format=json'.format(address)
response = util.call_api(resource)
json_response = json.loads(response)
return Address(json_response)
class Address:
def __init__(self, a):
self.hash160 = a['hash160']
self.address = a['address']
self.n_tx = a['n_tx']
self.total_received = a['total_received']
self.total_sent = a['total_sent']
self.final_balance = a['final_balance']
self.transactions = [Transaction(tx) for tx in a['txs']]
I tried to print(get_address('*******************')), but this return the object name. Then, adding the following code to the class but it return a tuple which is throw an error. How can I print all these element correctly?
def __str__(self):
return (self.hash160,
self.address,
self.n_tx,
self.total_received,
self.total_sent,
self.final_balance,
self.transactions)
You need to either convert the entire tuple to a string:
def __str__(self):
return str((self.hash160,
self.address,
self.n_tx,
self.total_received,
self.total_sent,
self.final_balance,
self.transactions))
or you can use an f-string (or just regular string concatenation) to build your own:
def __str__(self):
return f'hash: {self.hash160}, ' +
f'address: {self.address}, ' +
...
Note that you may want to also implement __repr__(self) by having it just return str(self). Depending on how you try to output the class, this might be necessary.
__str__ needs to return a string as it's the API that declares how your class instance would be represented as a string. You could throw everything in that tuple into a dictionary and wrap it in a json.dumps() to parse it to a json string.

How to create a list of instances of a given class

I'm facing problem with my code. In fact, I need to create a list of instances of my class( Patent). The name of the list is patent_ints. But when I'm trying to verify if any element in that list is a Patent one, I'm always getting a False response. And when iterating the first element is like "<__main__.Patent at 0x7f107820b710>".
Here is my code, I need help !
import json
import datetime
patent_data = json.loads(open('NASA_data.json', "r").read())
unique_center = []
for thing in patent_data["Patent_Information"]["Results"]:
for val in thing:
if(val == 'NASA Center'):
unique_center.append(thing[val])
total_num_centers = len(set(unique_center))
class Patent:
def __init__(self, abbreviated_organization_name, dict_data):
self.org_name = abbreviated_organization_name
self.title = dict_data["Title"]
# initialize instance variable called year. The value can be extracted from dict_data.
# This should be a four digit string.
self.year = str(datetime.datetime.strptime(dict_data['Date'], '%m/%d/%Y').year) #dict_data['Date'].split('/')[2]
# initialize an instance variable called month. The value can be extracted from dict_data.
# This should be a two digit string.
self.month = str(datetime.datetime.strptime(dict_data['Date'], '%m/%d/%Y').month) #dict_data['Date'].split('/')[0]
# initialize an instance variable called day. The value can be extracted from dict_data.
# This should be a two digit string.
self.day = str(datetime.datetime.strptime(dict_data['Date'], '%m/%d/%Y').day) #dict_data['Date'].split('/')[1]
self.id = dict_data['Case Number']
self.access_limit = dict_data['SRA Final']
patent_ints = [Patent(i, data) for i in unique_center for data in patent_data["Patent_Information"]["Results"]]
patent_ints[0]
Thank you in advance!
<__main__.Patent at 0x7f107820b710> is the default representation of the class when you try to print it. Add an __str__ or __repr__ method to the class and define some custom logic to return your desired details as a string:
class Patent:
def __init__(self, abbreviated_organization_name, dict_data):
...
def __repr__(self):
# return a dictionary of items in the class but you can return whatever you want
# you could do f'{self.title} {self.id} {self.year}-{self.month}-{self.day}' but str(self.__dict__) is quick to test
return str(self.__dict__)

Use of arguments with property.deleter

I'm trying to define a property deleter with a parameter for an attribute of Character class as follows:
class Character(object):
_status = None
#property
def status(self):
""" Return _status if it exists or False if not."""
return self._status
#status.setter
def status(self, status_value):
"""
Receive the status and the duration(continous or not) and add
it for the _status.
"""
if not self._status:
self._status = []
self._status.append(status_value)
#status.deleter
def status(self, status_value):
"""
Delete the specified object from the _status list.
"""
status = [value for value in self._status
if status_value in value.keys()]
if status:
self._status.remove(self._status.index(status[0]))
I'm trying to delete a specific object from the status.
>>>a = Character()
>>>a.status = 'Test'
Would return a list with 1 element:
>>>a.status
['Test']
If i set the status again, the old value persists and new one is added to the list:
>>>a.status = 'Dazed'
>>>a.status
['Test', 'Dazed']
As well I want to delete only a specific value from the list:
>>>del a.status('Dazed')
And the expected result should be:
>>> a.status
['Test']
The problem is that hen I try:
del a.status('Dazed')
The following error occurs:
SyntaxError: can't delete function call
Is there any way to use arguments with a property.deleter?
This is odd behaviour you are trying to create, and would likely trip up users of your class. I certainly wouldn't expect:
self.status = "happy"
to add the new string to an existing list.
As far as I'm aware there is no way to pass an argument to a #property.deleter.
A better approach might be to make the character.status a set (I am assuming that you meant this to be an instance attribute, but this all stands for class attributes too):
class Character(object):
def __init__(self, ..., status=None):
if status is None:
self.status = set()
else:
self.status = set(status)
...
conan = Character(..., status=("happy", "cold"))
conan.status.add("tired")
conan.status.remove("happy")
One advantage of a set is that it prevents duplicates. Also, it provides for very fast membership tests (e.g. if "warm" in conan.status:) and you can find out if two Character instances have any of the same status easily:
if conan.status.intersection(other_character.status):

How to intercept a specific tuple lookup in python

I'm wondering how could one create a program to detect the following cases in the code, when comparing a variable to hardcoded values, instead of using enumeration, dynamically?
class AccountType:
BBAN = '000'
IBAN = '001'
UBAN = '002'
LBAN = '003'
I would like the code to report (drop a warning into the log) in the following case:
payee_account_type = self.get_payee_account_type(rc) # '001' for ex.
if payee_account_type in ('001', '002'): # Report on unsafe lookup
print 'okay, but not sure about the codes, man'
To encourage people to use the following approach:
payee_account_type = self.get_payee_account_type(rc)
if payee_account_type in (AccountType.IBAN, AccountType.UBAN):
print 'do this for sure'
Which is much safer.
It's not a problem to verify the == and != checks like below:
if payee_account_type == '001':
print 'codes again'
By wrapping payee_account_type into a class, with the following __eq__ implemented:
class Variant:
def __init__(self, value):
self._value = value
def get_value(self):
return self._value
class AccountType:
BBAN = Variant('000')
IBAN = Variant('001')
UBAN = Variant('002')
LBAN = Variant('003')
class AccountTypeWrapper(object):
def __init__(self, account_type):
self._account_type = account_type
def __eq__(self, other):
if isinstance(other, Variant):
# Safe usage
return self._account_type == other.get_value()
# The value is hardcoded
log.warning('Unsafe comparison. Use proper enumeration object')
return self._account_type == other
But what to do with tuple lookups?
I know, I could create a convention method wrapping the lookup, where the check can be done:
if IbanUtils.account_type_in(account_type, AccountType.IBAN, AccountType.UBAN):
pass
class IbanUtils(object):
def account_type_in(self, account_type, *types_to_check):
for type in types_to_check:
if not isinstance(type, Variant):
log.warning('Unsafe usage')
return account_type in types_to_check
But it's not an option for me, because I have a lot of legacy code I cannot touch, but still need to report on.

how to select an object from a list of objects by its attribute in python

Apologies if this question has already been asked but I do not think I know the correct terminology to search for an appropriate solution through google.
I would like to select an object from a list of objects by the value of it's attribute, for example:
class Example():
def __init__(self):
self.pList = []
def addPerson(self,name,number):
self.pList.append(Person(self,name,number))
class Person():
def __init__(self,name,number):
self.nom = name
self.num = number
a = Example()
a.addPerson('dave',123)
a.addPerson('mike',345)
a.pList #.... somehow select dave by giving the value 123
in my case the number will always be unique
Thanks for the help
One option is to use the next() built-in:
dave = next(person for person in a.pList if person.num == 123)
This will throw StopIteration if nothing is found. You can use the two-argument form of next() to provide a default value for that case:
dave = next(
(person for person in a.pList if person.num == 123),
None,
)
A slightly more verbose alternative is a for loop:
for person in a.pList:
if person.num == 123:
break
else:
print "Not found."
person = None
dave = person
If those nom's are unique keys, and all you are ever going to do is access your persons using this unique key you should indeed rather use a dictionary.
However if you want to add more attributes over time and if you like to be able to retrieve one or more person by any of those attributes, you might want to go with a more complex solution:
class Example():
def __init__(self):
self.__pList = []
def addPerson(self,name,number):
self.__pList.append(Person(name,number))
def findPerson(self, **kwargs):
return next(self.__iterPerson(**kwargs))
def allPersons(self, **kwargs):
return list(self.__iterPerson(**kwargs))
def __iterPerson(self, **kwargs):
return (person for person in self.__pList if person.match(**kwargs))
class Person():
def __init__(self,name,number):
self.nom = name
self.num = number
def __repr__(self):
return "Person('%s', %d)" % (self.nom, self.num)
def match(self, **kwargs):
return all(getattr(self, key) == val for (key, val) in kwargs.items())
So let's assume we got one Mike and two Dave's
a = Example()
a.addPerson('dave',123)
a.addPerson('mike',345)
a.addPerson('dave',678)
Now you can find persons by number:
>>> a.findPerson(num=345)
Person('mike', 345)
Or by name:
>>> a.allPersons(nom='dave')
[Person('dave', 123), Person('dave', 678)]
Or both:
>>> a.findPerson(nom='dave', num=123)
Person('dave', 123)
The terminology you need is 'map' or 'dictionnary' : this will lead you to the right page in the python doc.
Extremely basic example:
>>> a = {123:'dave', 345:'mike'}
>>> a[123]
'dave'
The missing underscore makes plist a public property. I don't think that's what you want, since it does not encapsulate the functionality and you could call a.plist.append instead of a.addPerson.
class Example():
...
def filter(self, criteria):
for p in self.plist:
if criteria(p):
yield p
def getByNum(self, num):
return self.filter(lambda p: p.num == num)
dave = next(a.getByNum(123))
If the numbers are unique, you may also consider using a dictionary that maps from number to name or person instead of a list. But that's up to your implementation.

Categories

Resources