I have this function I have built and it seems like I am missing something very minor here. This loop will not call for some reason. Indentation looks good and I am not getting any errors in my output, but the data is not being updated which you can see by the debug print statement I made not showing in the terminal.
Below is the function I am speaking of:
def updatefield(layer, prev_data):
print("DEUBG:: UPDATE FIELD")
fname, ftype, fdict = field_attr(prev_data)[0], field_attr(prev_data)[1], field_attr(prev_data)[2]
arcpy.AddField_management(
in_table=layer,
field_name=fname,
field_type=ftype,
field_is_nullable="NULLABLE"
)
# Use UpdateCursor to expedite the copy of the data to the new field.
with arcpy.da.UpdateCursor(layer, [prev_data, fname, "OID#"]) as uc:
print("DEUBG:: UPDATE CURSOR: {}".format(layer))
for record in uc:
print("\tDEBUG:: record: {}".format(record)) # THIS NEVER GETS CALLED
if record[0] in fdict.keys():
record[1] = fdict[record[0]]
else:
if layer == fms_conduit:
record[1] = None
# Can't recall if you can have empty keys...These also pretty much only apply to fiber.
elif prev_data == "CATEGORY" and record[0] == "":
record[1] = "OTH"
elif prev_data == "CABLECAPACITY" and (record[0] in ('', ' ', None)):
record[1] = 0
elif prev_data == "CABLECAPACITY":
record[1] = int(record[0])
else:
record[1] = ""
print("\nDEBUG:: OID: {}\tPrevField: {}\t NewFieldName: {}\tNewFieldValue: {}".format(
record[2], prev_data, fname, record[1])
)
uc.updateRow(record)
And here is the output:
The final few debug print statements are from another function but I should be getting that record printed. Again, probably something silly but I can't seem to get it.
Thank you for your time.
Turns out the data that was delivered to me was truncated at some point. The update cursor was empty and therefore nothing was being translated.
Related
I'm making an API route that returns a random number in Flask. When sending a post request to the end-point, I want it to return an error(s) if a certain field(s) is not in the post request (for example, if there is no "name" in the request, it should return an error).
I've tried doing this with a dictionary, try, and catch. If a field is missing, I add a key: value to the dictionary and if the dictionary isn't empty, to return that. First problem is if there is more than one field missing, it only adds one of them to the error dictionary. Second problem is, I'm also trying to make sure some fields also have a certain value (for example, color needs to be red or blue). If I check for one thing, it works - if I do
if color != "red" or color != "blue":
it will always show an error. Even if I split it up into multiple if statements, it will still be an error. I've searched Google, rephrasing my question at least 30 different times, and most answers I've gotten are about SalesForce (which I'm assuming is some company/software etc).
So...is there a way to make a certain field(s) required? Or am I on the right track with try and catch? If it is through try and catch, how do I make it show more than one error/have a variable a certain thing?
#app.route('/api/get-num', methods=["POST"])
def num():
errors = {}
try:
name = request.json['name']
except:
errors["errors"] = {"name" : "This field is required."}
try:
color = request.json['color']
if color != "red" or color != "blue":
errors["errors"] = {"color" : "Invalid value, must be red or blue."}
except:
errors["errors"] = {"color" : "Invalid value, must be red or blue."}
if len(errors) != 0:
return errors
create_dict = {
'name' : request.json['name'],
'email ': request.json['email'],
'year': request.json['year'],
'color' : request.json['color']
}
return jsonify(create_dict)
Examples:
If name is missing and color is wrong, it should show:
{
"errors": {
"color": [
"Invalid value, must be red or blue."
],
"name": [
"This field is required."
]
}
}
With name missing and color being "red", it's currently showing:
{
"errors": {
"color": "Invalid value, must be red or blue."
}
}
Create a dict with expected errors, in this case it would be all the required fields
errorsDict = {"errors":{"color":[],"name":[]}}
In your try except block append to the nested as items as necessary, example:
errorsDict = {"errors":{"color":[],"name":[]}}
try:
name = request.json['name']
except:
errorsDict["errors"]["name"].append("This field is required.")
try:
color = request.json['color']
except:
errorsDict["errors"]["color"].append( "COLORS MISSING!")
I have this function that uses PrettyTables to gather information about the Virtual Machines owned by a user. Right now, it only shows information and it works well. I have a new idea where I want to add a button to a new column which allows the user to reboot the virutal machine. I already know how to restart the virtual machines but what I'm struggling to figure out is the best way to create a dataset which i can iterate through and then create a HTML table. I've done similar stuff with PHP/SQL in the past and it was straight forward. I don't think I can iterate through PrettyTables so I'm wondering what is my best option? Pretty tables does a very good job of making it simple to create the table (as you can see below). I'm hoping to use another method, but also keep it very simple. Basically, making it relational and easy to iterate through. Any other suggestions are welcome. Thanks!
Here is my current code:
x = PrettyTable()
x.field_names = ["VM Name", "OS", "IP", "Power State"]
for uuid in virtual_machines:
vm = search_index.FindByUuid(None, uuid, True, False)
if vm.summary.guest.ipAddress == None:
ip = "Unavailable"
else:
ip = vm.summary.guest.ipAddress
if vm.summary.runtime.powerState == "poweredOff":
power_state = "OFF"
else:
power_state = "ON"
if vm.summary.guest.guestFullName == None:
os = "Unavailable"
else:
os = vm.summary.guest.guestFullName
x.add_row([vm.summary.config.name, os, ip, power_state])
table = x.get_html_string(attributes = {"class":"table table-striped"})
return table
Here is a sample of what it looks like and also what I plan to do with the button. http://prntscr.com/nki3ci
Figured out how to query the prettytable. It was a minor addition without having to redo it all.
html = '<table class="table"><tr><th>VM Name</th><th>OS</th><th>IP</th><th>Power
State</th></tr>'
htmlend = '</tr></table>'
body = ''
for vmm in x:
vmm.border = False
vmm.header = False
vm_name = (vmm.get_string(fields=["VM Name"]))
operating_system = (vmm.get_string(fields=["OS"]))
ip_addr = ((vmm.get_string(fields=["IP"])))
body += '<tr><td>'+ vm_name + '</td><td>' + operating_system + '</td> <td>'+ ip_addr +'</td> <td>ON</td></tr>'
html += body
html += htmlend
print(html)
i have two reports cout_materiel_facture_detail_report.xml (detailed report) and cout_materiel_facture_report.xml (simple report) and have a wizard where the user inputs some data and chooses whether he/she wants to print the simple report or the detailed one. Here is the wizard's class:
class CoutMaterielFactureWizard(models.TransientModel):
_name = 'gc.cout_materiel_facture_wizard'
directeur_parc_id = fields.Many2one('hr.employee', string='Directeur Parc')
procedure = fields.Char(string='Procedure')
version = fields.Char(string='Verion')
date_realisation = fields.Date(string='Date realisation')
# is_landscape = fields.Boolean(string='Mode paysage?')
is_detail = fields.Boolean(string='Version simplifiee?')
#api.multi
def do_toggle_print(self):
cout_materiel = self.env['gc.cout_materiel'].browse(self._context.get('active_id', False))
cout_materiel.write({
'directeur_parc_id': self.directeur_parc_id.id
})
# Print the simple report
if not self.is_detail:
return {
'type': 'ir.actions.report.xml',
'name': 'gestion_cout.cout_materiel_facture_report_template',
'report_name': 'gestion_cout.cout_materiel_facture_report_template',
}
# Print the detailed report
else:
sql = "SELECT SUM(h_sup)+SUM(h_exp),SUM(h_im),count(*),SUM(total), famille FROM gc_cout_materiel_line where " \
"cout_materiel_id =%s group by famille "
self.env.cr.execute(sql, (cout_materiel.id,))
results = self.env.cr.fetchall()
if len(results) > 0:
line_ids = []
for nbht, nbhim, qte, prix_total, famille in results:
line_ids.append((0, 0, {
'famille': famille,
'type': 'VA',
'qte': qte,
'nbr_heures': nbht,
'nbr_heures_im': nbhim,
'nbr_jours': 28,
'prix_unitaire': 'VA',
'prix_total': prix_total,
}))
self.env['gc.cout_materiel_facture_temp'].create({
'chantier_name': cout_materiel.chantier_id.name,
'mois_name': cout_materiel.mois_id.name,
'num_annexe': cout_materiel.num_annexe,
'expediteur': cout_materiel.expediteur,
'destinateur': cout_materiel.destinateur,
'application_date': cout_materiel.application_date,
'date_realisation': self.date_realisation,
'directeur_parc_name': self.directeur_parc_id.name,
'procedure': self.procedure,
'version': self.version,
'prix_total_global': cout_materiel.total_global,
'line_ids': line_ids,
})
return {
'type': 'ir.actions.report.xml',
'name': 'gestion_cout.gc_cout_materiel_facture_detail_report_template',
'report_name': 'gestion_cout.gc_cout_materiel_facture_detail_report_template',
}
But i get this error after i hit the print button
I checked out the database and found both reports are present there.
Any help? please!!
Finally i managed to solve my problem!!
Here is what i did:
I created a method in the wizard model which returns a list of objects that i whant to print and linked the wizard to the qweb report.
Then i called the method from the qweb report using object.my_mehtod() in a t-foreach loop, where object represents the wizard.
With this way i am able to create complex reports and print them easily. One can use this method to get data from several tables and organize the data and retur them as a list.
I hope that it will help someone.
Best regards!!
I'm having trouble removing a widgets with a label once it's added
Here's the relevant piece of code:
logi= True
if data == []:
logn =Label(text= "Incorrect Username",color=(190,0,0,1),
pos_hint={"right":1.035,"top":1.14})
self.add_widget(logn)
logu =Label(text= "Incorrect Password",color=(190,0,0,1),
pos_hint={"right":1.035,"top":1.04})
self.add_widget(logu)
logi= False
if logi == True:
textinput.text=''
textinput2.text=''
if 'logn' in locals() and 'logu' in locals() :
self.remove_widget(logn)
self.remove_widget(logu)
once the widgets have been added I can't seem to remove them, if i remove the if 'logn' in locals() and 'logu' in locals() :statement I get an error "Local variable referenced before assignment " every time I test this without the above mentioned if statment I make sure the widgets have been added
I assume you are entering this method twice (1st data==[] 2nd time data=[...]). So You should keep your variables at hand (put them on the instance - self)
logi= True
if data == []:
self.logn =Label(text= "Incorrect Username",color=(190,0,0,1),
pos_hint={"right":1.035,"top":1.14})
self.add_widget(self.logn)
self.logu =Label(text= "Incorrect Password",color=(190,0,0,1),
pos_hint={"right":1.035,"top":1.04})
self.add_widget(self.logu)
logi= False
if logi == True:
textinput.text=''
textinput2.text=''
if hasattr(self, 'logn'): #check that we put something here before...
self.remove_widget(self.logn)
self.remove_widget(self.logu)
Note all the places I've added self ...
I am trying to code a simple hangman game in python with a gui using tkinter. I have the gui frame set up with a user entry. The problem is when I enter a letter then run the code by pressing the play button it runs the letter through the code until the code runs out of lives (10 times). How can i improve my code so a letter is only run through once then a new letter can be input to guess again?
thank you
from numpy import*
from Tkinter import*
#set up gui frame
win=Tk() #create window assigned to variable win
welc=Label(win,text="Welcome to Hangman!").grid(row=0)
inst=Message(win,text="instructions: To play start by guessing a letter in the secret word. if the letter is in the word it will fill in a blank if not you lose a life. Continue guessing untill you have guessed the secret word.").grid(row=1)
guess_text=Label(win,text="Enter a letter or Word").grid(row=2)
blank_text=Label(win,text="Secret Word").grid(row=3)
lives_text=Label(win,text="Lives Remaining").grid(row=4)
e=Entry(win)
e.grid(row=2,column=1)
#library of secret words
lib=['hanakah','christmas','holly','thanksgiving','reigndeer','family','presents','santa','kwanza', 'chocolate', 'cheesecake']
n=len(lib)
#randomly pick secret word
inx=random.randint(1,n)
secret=lib[inx]
#set up game
lives_remaining=10
guessed_letters=''
#define function to play game
def play():
word=secret
while True:
guess=get_guess(word)
print guess
print type(guess)
if process_guess(guess,word):
Label(win,text="You Win!").grid(row=6)
break
if lives_remaining==0:
Label(win,text="You Lose!").grid(row=6)
Label(win,text="The secret word was: "+word).grid(row=7)
break
Button(win,text=("Play"),command=play).grid(row=5,column=0)
def get_guess(word):
blanks(word)
guess=e.get()
return guess
#diplay guessed letter in postion of word
def blanks(word):
Label(win,text=lives_remaining).grid(row=4,column=1)
display_word=''
for letter in word:
if guessed_letters.find(letter)> -1:
#LETTER found
display_word=display_word+letter
else:
#letter not found
display_word=display_word+'-'
Label(win,text=display_word).grid(row=3,column=1)
def process_guess(guess,word):
if len(guess)>1 and len(guess)==len(word):
return whole_word_guess(guess, word)
else:
return single_letter_guess(guess, word)
def whole_word_guess(guess, word):
if guess.lower() == word.lower():
return True
else:
lives_remaining=lives_remaining+(-1)
return False
def single_letter_guess(guess, word):
global guessed_letters
global lives_remaining
if word.find(guess) == -1:
# letter guess was incorrect
lives_remaining = lives_remaining+(-1)
guessed_letters = guessed_letters + guess.lower()
if all_letters_guessed(word):
return True
return False
def all_letters_guessed(word):
for letter in word:
if guessed_letters.find(letter.lower()) == -1:
return False
return True
mainloop()
I think I understand now.
The get_guess function is always pulling whatever info is in the e Entry, it's not waiting for the value of e to change.
A simple fix without creating listeners would be to create a new global variable called last_guess which can be initialized to '' and then passsed to get_guess as a 2nd arg to check if the guess has changed:
def get_guess(word, last_guess):
blanks(word)
guess=e.get()
#If the guess has not changed ret false
if guess == last_guess:
return False
#If the guess has changed update the last_guess
else:
last_guess = guess
return guess
And then in the main While loop:
while True:
guess=get_guess(word)
print guess
print type(guess)
if not guess: #<-- If the get_guess returned False
continue #<-- Just go on to on to the next iteration of the loop w/out updating lives etc
if process_guess(guess,word):
Label(win,text="You Win!").grid(row=6)
break
if lives_remaining==0:
Label(win,text="You Lose!").grid(row=6)
Label(win,text="The secret word was: "+word).grid(row=7)
break
I haven't run this code so it might have errors, but I think the general idea will work