Im using objects.create to create object o my model. Using the following logic. But payment_quantity (somehow) is setting to NoneType. And not setting to the value i passed into objects.create
class PrizesExchangeModeResourceBMR(resources.ModelResource):
#transaction.atomic
def create_exchange_mode(self, code, points, price):
cuotas = [1,3,6,12] # array de cuotas
prize = Prize.objects.filter(code = code) # busca el premio
if len(prize) != 0: # si existe el premio
PrizesExchangeMode.objects.create( #crea puntos al 100%, 0 cuotas
prize = prize[0],
payment_amount = 0,
points_value = points,
payment_quantity=0,
price_value = 0
)
puntos = round(points/2)
for cuota in cuotas: # crea con puntos al 50% y [1,3,6,12] cuotas
valor = round(price/cuota)
PrizesExchangeMode.objects.create(
prize = prize[0],
payment_amount = valor,
points_value = puntos,
payment_quantity = 0.0,
price_value = 0.0)
else:
print("Premio no encontrado") # no existe el premio
def get_instance(self,instance_loader, row):
self.get_queryset().get(prize__code=row.get('prize'))
def save_instance(self, instance, using_transactions, dry_run):
code = instance.prize.code #guarda el codigo
points = instance.points_value # guarda puntos
price = instance.payment_amount # guarda precio
self.create_exchange_mode(code, points, price) # se lo pasa a la funcion anterior
class Meta:
model = PrizesExchangeMode
fields = ("prize", "points_value", "payment_amount") # Campos que queremos importar
First project newbie here - In this model I am trying to create a field that combines first and last names of two people depending if the last names are the same or not. If the last name is the same, I want it to display as "first_name1 & first_name2 last_name1". It works except that when last_name1 is empty, which will be the case a lot of the time, it displays something like "John & Jane None". I had to specify last_name1 as a string or else I got an error: must be str, not NoneType. How do I do this properly? Also what do I call this type of function in a model...is it a manager? I wasn't sure how to title this post.
class Contact(models.Model):
first_name1 = models.CharField(max_length=100, verbose_name='First Name', null=True)
last_name1 = models.CharField(max_length=100, verbose_name='Last Name', null=True, blank=True)
first_name2 = models.CharField(max_length=100, verbose_name='First Name (Second Person)', null=True, blank=True)
last_name2 = models.CharField(max_length=100, verbose_name='Last Name (Second Person)', null=True, blank=True)
def get_full_name(self):
combined_name = ''
if self.last_name1 == self.last_name2:
combined_name = self.first_name1 + ' & ' + self.first_name2 + ' ' + str(self.last_name1)
return '%s' % (combined_name)
full_name = property(get_full_name)
The reason on why you're getting an error that last_name1 must be a String, not a NoneType is due to the fact you've set null to True in your field declaration for the said field.
So what's wrong with doing that? When you are defining null=True for fields like CharField or TextField you'll end up having None. The Django convention is to use EMPTY STRING.
Here's a link that talks about how you would use blank or null on field declarations.
You can check if those values are "Truth-y" before doing the comparison check. However, you'll need to decide how to handle the other cases.
#property
def get_full_name(self):
combined_name = ''
if self.last_name1 and self.last_name2:
if self.last_name1 == self.last_name2:
combined_name = self.first_name1 + ' & ' + self.first_name2 + ' ' + str(self.last_name1)
elif self.last_name1: # Only last_name1 is set
pass
elif self.last_name2: # Only last_name2 is set
pass
else: # Both last_name1 and last_name2 are None or ''
pass
return combined_name
The way you've defined the names, any and all of them can be None, if you change them to the empty string you'll have similar problems. To illustrate, lets start by writing a unit test (substitute the empty string for None if you want):
def test_contact_full_name():
# correct.
assert Contact('Jane', None, 'John', None).full_name == "Jane & John"
assert Contact('Bart', 'Simpson', 'Lisa', 'Simpson').full_name == "Bart & Lisa Simpson"
assert Contact('Bart', 'Simpson', 'Frodo', 'Baggins').full_name == "Bart Simpson & Frodo Baggins"
assert Contact('Bart', None, None, None).full_name == "Bart"
assert Contact('Bart', 'Simpson', None, None).full_name == "Bart Simpson"
assert Contact(None, 'Simpson', None, None).full_name == "Simpson"
assert Contact(None, None, None, None).full_name == ""
# correct?
assert Contact('Bart', 'Simpson', 'Lisa', None).full_name == "Bart Simpson & Lisa"
# correct??
assert Contact('Bart', None, 'Lisa', 'Simpson').full_name == "Bart & Lisa Simpson"
Then it's just a question of dividing the problem into smaller pieces, I've put everything into a regular class just to make it easier to test. First some helper methods:
class Contact(object):
def __init__(self, a, b, c, d):
self.first_name1 = a
self.last_name1 = b
self.first_name2 = c
self.last_name2 = d
def combined_last_name(self, a, b):
"Return ``a`` if ``a`` and ``b`` are equal, otherwise returns None."
return a if a and b and a == b else None
def normalize_name(self, n):
"Returns the name or the empty string if ``n`` is None."
return n if n else ""
def get_name(self, f, l):
"""Returns a string containing firstname lastname and omits any of them
if they're None.
"""
if f and l:
return "%s %s" % (f, l)
if f:
return f
elif l:
return l
return ""
def has_second_name(self):
"Returns true if there is a second name."
return self.first_name2 or self.last_name2
then we can define the full_name property:
#property
def full_name(self):
"""Returns a string that combines first and last names of two people
depending if the last names are the same or not. If the last name
is the same, it displays as::
first_name1 & first_name2 last_name1
"""
cln = self.combined_last_name(self.last_name1, self.last_name2)
if cln: # have a common last name..
return "%s & %s %s" % (
self.first_name1,
self.first_name2,
cln
)
elif self.has_second_name():
return "%s & %s" % (
self.get_name(self.first_name1, self.last_name1),
self.get_name(self.first_name2, self.last_name2)
)
else:
return self.get_name(self.first_name1, self.last_name1)
if we put everything in a file named fullname.py we can use the pytest tool (pip install pytest) to run the tests:
c:\srv\tmp> pytest --verbose fullname.py
============================= test session starts =============================
platform win32 -- Python 2.7.16, pytest-3.3.1, py-1.5.2, pluggy-0.6.0 -- c:\srv\venv\finautfaktura\scripts\python.exe
cachedir: .cache
rootdir: c:\srv\tmp, inifile:
plugins: xdist-1.20.1, forked-0.2, django-3.1.2, cov-2.5.1
collected 1 item
fullname.py::test_contact_full_name PASSED [100%]
========================== 1 passed in 0.20 seconds ===========================
All is well... or is it?
Let's write another test:
def test_only_second_name():
assert Contact(None, None, None, "Simpson").full_name == "Simpson"
assert Contact(None, None, "Lisa", "Simpson").full_name == "Lisa Simpson"
assert Contact(None, None, "Lisa", None).full_name == "Lisa"
running pytest again reveals the (first) error:
c:\srv\tmp> pytest --verbose fullname.py
============================= test session starts =============================
platform win32 -- Python 2.7.16, pytest-3.3.1, py-1.5.2, pluggy-0.6.0 -- c:\srv\venv\finautfaktura\scripts\python.exe
cachedir: .cache
rootdir: c:\srv\tmp, inifile:
plugins: xdist-1.20.1, forked-0.2, django-3.1.2, cov-2.5.1
collected 2 items
fullname.py::test_contact_full_name PASSED [ 50%]
fullname.py::test_only_second_name FAILED [100%]
================================== FAILURES ===================================
____________________________ test_only_second_name ____________________________
def test_only_second_name():
> assert Contact(None, None, None, "Simpson").full_name == "Simpson"
E AssertionError: assert ' & Simpson' == 'Simpson'
E - & Simpson
E ? ---
E + Simpson
fullname.py:83: AssertionError
===================== 1 failed, 1 passed in 0.37 seconds ======================
i.e. the property returned " & Simpson" instead of the expected "Simpson" for the first assert.
To fix this we can make the full_name property handle this added complexity as well, or.., we can solve the problem somewhere else, e.g. in the __init__:
class Contact(object):
def __init__(self, a, b, c, d):
self.first_name1 = a
self.last_name1 = b
self.first_name2 = c
self.last_name2 = d
if not a and not b:
# if no name1, then put name2 into name1 and set name2 to None
self.first_name1 = self.first_name2
self.last_name1 = self.last_name2
self.first_name2 = self.last_name2 = None
running pytest again shows that this fixed the second test.
You can of course not provide your own __init__ in a Django model to solve this problem, but you can do something similar in if you override the save(..) method:
def save(self, *args, **kwargs):
if not self.first_name1 and not self.last_name1:
self.first_name1 = self.first_name2
self.last_name1 = self.last_name2
self.first_name2 = self.last_name2 = None
super(Contact, self).save(*args, **kwargs)
It's a guessing game and at the end of the code I want to ask if they would like to play the game again. If they do say yes then it start back from the top and if they say no the program ends. This is what i currently have not sure what i did wrong, ive had some help and this is what i have so far
import random
name = input('Entrez votre nom: ')
Kilo = input (name + ' Veux-tu jouer un jeu ')
def play(name):
randomNumber = random.randrange(0,100)
guessed = False
want_to_play = True
while want_to_play:
print("Un nombre aléatoire a été généré 1 a 100 ")
while guessed==False:
userInput = int(input("Entrez votre estimation: "))
if userInput==randomNumber:
guessed = True
print("Bien joué!")
elif userInput>100:
print("Notre fourchette est entre 0 et 100, essayez un peu plus bas")
elif userInput<0:
print("Notre fourchette est comprise entre 0 et 100, essayez un peu plus haut ")
elif userInput>randomNumber:
print("Essayez une fois de plus, un peu plus bas")
elif userInput < randomNumber:
print("Essayer une fois de plus, un peu plus haut")
You could encapsulate your game into a function. Then, use a loop around the function call:
name = input('Entrez votre nom: ')
def play(name):
randomNumber = random.randrange(0,100)
guesses = False
# etc...
want_to_play = True
while want_to_play:
play(name) # This start your game
want_to_play = input('Veux tu encore jouer? (O/N)')
if want_to_play.lower() == 'o':
want_to_play = True
elif want_to_play.lower() == 'n':
want_to_play = False # EDIT: oups, thanks Primusa
else:
print('invalid input!')
want_to_play = False
So I'm struggling. I've seen quite a few posts on this topic, but after a couple hours struggling with the problem, I can't figure this out. Here are a few snippets of code I have. I'd like to be able to change one instance of the class without the other being changed as well, and I'm coming up short
class voter:
def __init__(self, iPositon, jPosition, affiliation):
self.affiliation = affiliation
self.iPositon = iPositon
self.jPosition = jPosition
class district:
def __init__(self, *listOfVotersPassed):
# super(district, self).__init__()
self.listOfVoters = []
for x in listOfVotersPassed:
self.listOfVoters.append(x)
class city:
def __init__(self, *listOfDistrictsPassed):
self.listOfDistricts = []
for x in listOfDistrictsPassed:
self.listOfDistricts.append(x)
def main():
# I have a list of class district that I pass to city()
startCity = city(*startCityList)
solutionCity = city(*solutionCityList)
print solutionCity.listOfDistricts[0].listOfVoters[0].affiliation # Democrat
print startCity.listOfDistricts[0].listOfVoters[0].affiliation # Democrat
solutionCity.listOfDistricts[0].listOfVoters[0].affiliation = "Republican"
print solutionCity.listOfDistricts[0].listOfVoters[0].affiliation # Republican
print startCity.listOfDistricts[0].listOfVoters[0].affiliation # Republican
if __name__ == "__main__":
main()
edit.
So I was asked about how I created the instance(s) of city. I have a file I'm reading in, each has either R or D in each line.
file = open(fileName)
# import contents
startVoterList = []
solutionVoterList = []
for line in file:
for house in line:
if " " in house:
pass
elif "\n" in house:
pass
else:
startVoterList.append(house)
solutionVoterList.append(house)
I also updated the classes, now each is in the following format. No changes besides the "(object)" after each class className.
class voter(object):
def __init__(self, iPositon, jPosition, affiliation):
self.affiliation = affiliation
self.iPositon = iPositon
self.jPosition = jPosition
Hi guys I have a syntax error that I really don't understand... Anyone can help?
I get this message on the console:
File "./data_4.0.1.py", line 170
elif:
^
SyntaxError: invalid syntax
The error is raised on this elif:
#controllo ultimo timestamp
elif:
with open(nomen, 'rb') as f:
last_timestamp = f.readlines()[-1].split(",")[0]
Here is my code:
def funzione_aggiornamento_prezzi(titolo,timeframe,lookback):
#parametri per scaricare lo storico dei prezzi
if timeframe =='TBT':
lookback = 0
elif timeframe =='1M':
lookback = 7
elif timeframe =='5M':
lookback = 60
elif timeframe =='60M':
lookback = 180
elif timeframe =='1D':
lookback = 1800
params = {'item': titolo,
'frequency': timeframe,
'dataDa':x_giorni_fa(lookback)}
try:
r = requests.get(myurl, params=params)
except:
pprint("Si e' verificato un errore")
else:
pprint(r.status_code)
pprint(r.url)
new_list = crea_lista(r)
#codice per scrivere su di un csv da una lista
nomen = "%s.%s.csv" % (titolo,timeframe)
csvfile = open(nomen, 'a')
reportwriter = csv.writer(csvfile, quoting=csv.QUOTE_MINIMAL)
#codice per scrivere su di un csv
#controllo del numero di rows nel file
with open(nomen,"r") as f:
reader = csv.reader(f,delimiter = ",")
data = list(reader)
row_count = len(data)
if row_count == 0:
for i in new_list:
da_appendere = i
reportwriter.writerow(da_appendere)
csvfile.close()
#controllo ultimo timestamp
elif:
with open(nomen, 'rb') as f:
last_timestamp = f.readlines()[-1].split(",")[0]
#codice per appendere solo i nuovi dati
found_it = 0
for i in range((len(new_list))-1):
if new_list[i] == last_timestamp:
found_it = 1
if found_it == 1:
this_elem = new_list[i]
next_elem = new_list[(i+1)]
#print(this_elem)
#print(next_elem)
da_appendere1 = next_elem
reportwriter.writerow(da_appendere1)
csvfile.close()
for i in lista_indici:
for j in lista_timeframe:
funzione_aggiornamento_prezzi(i,j,lookback)
you end the if block in the previous line when put a instruction at the same level indentation that the if statement
if condition:
stuff
something # doing this close the if block
and a elif can only happen in a if block
and you do that in
if row_count == 0:
for i in new_list:
da_appendere = i
reportwriter.writerow(da_appendere)
csvfile.close() #<-- here you close the if block
#controllo ultimo timestamp
elif: #<-- you forgot the condition, and is outside of a 'if' block
with open(nomen, 'rb') as f:
last_timestamp = f.readlines()[-1].split(",")[0]
futhermore you forget to put a condition in the elif, if you don't need one use else instead
If you do not have another if statement, you should use else instead of elif.
See the documentation regarding control-flow.