I am trying to make my own log that makes a string of changed data between object (my old object and my new object) However i keep getting back empty string,
My code:
def log_fields(old_obj, new_obj):
fields = new_obj.__class__._meta.fields
changed_fields = ""
old_data = ""
new_data = ""
# get all changed data
for field in fields:
old_field_data = old_obj.__getattribute__(field.name)
new_field_data = new_obj.__getattribute__(field.name)
if old_field_data != new_field_data:
count =+ 1
# convert changed data to strings
# number + space + data + 5 spaces for next string
changed_fields.join(str(count)).join(" ").join(str(field)).join(" ")
old_data.join(str(count)).join(" ").join(str(old_field_data)).join(" ")
new_data.join(str(count)).join(" ").join(str(new_field_data)).join(" ")
print changed_fields
print old_data
print new_data
I got a feeling something with the string .join combination something is going wrong, cause trying this manually in shell seems to work up to the comparison. Not sure tho hos i should change the string
changed_fields = changed_fields + str(count) + "." + str(field.name) + " "
old_data = old_data + str(count) + "." + str(old_field_data) + " "
new_data = new_data + str(count) + "." + str(new_field_data) + " "
Seems to do the job, so for now, ill keep it at this
Related
I want to enter the value of a variable into a MySql database, but it is giving me this error:
I use code like this:
ADOQuery1->SQL->Clear();
ADOQuery1->SQL->Add("insert into data_nasabah(nama_nasabah,tanggal,debit/kredit,saldo,no_rekening)values('"+ns[0].nama+"','"+Date()+"','"+ns[0].dk[0]+"','"+ns[0].saldo[0]+"','"+rekening[n]+"')");
ADOQuery1->ExecSQL();
Column names that have special characters in them need to be quoted with `, or " in ANSI_QUOTES mode. See 9.2 Schema Object Names in MySQL's documentation.
Try this:
ADOQuery1->SQL->Text = "insert into data_nasabah (nama_nasabah, tanggal, `debit/kredit`, saldo, no_rekening) values ('" + ns[0].nama + "','" + Date() + "','" + ns[0].dk[0] + "','" + ns[0].saldo[0] + "','" + rekening[n] + "')";
However, don't format SQL statement parameters manually like you are! This is subject to SQL Injection attacks. You can use Sysutils::QuotedStr() (or Sysutils::AnsiQuotedStr()) to avoid this, eg:
ADOQuery1->SQL->Text = "insert into data_nasabah (nama_nasabah, tanggal, `debit/kredit`, saldo, no_rekening) values (" + QuotedStr(ns[0].nama) + "," + QuotedStr(Date()) + "," + QuotedStr(ns[0].dk[0]) + "," + QuotedStr(ns[0].saldo[0]) + "," + QuotedStr(rekening[n]) + ")";
But, you really should be using a parameterized query instead, let the database engine handle the quoting for you, eg:
// make sure to set ADOQuery1->ParamCheck=true beforehand!
ADOQuery1->SQL->Text = "insert into data_nasabah (nama_nasabah, tanggal, `debit/kredit`, saldo, no_rekening) values (:PNamaNasabah, :PTanggal, :PDebitKredit, :PSaldo, :PNoRekening)";
ADOQuery1->Parameters->ParamByName("PNamaNasabah")->Value = ns[0].nama;
ADOQuery1->Parameters->ParamByName("PTanggal")->Value = Date();
ADOQuery1->Parameters->ParamByName("PDebitKredit")->Value = ns[0].dk[0];
ADOQuery1->Parameters->ParamByName("PSaldo")->Value = ns[0].saldo[0];
ADOQuery1->Parameters->ParamByName("PNoRekening")->Value = rekening[n];
ADOQuery1->ExecSQL();
i am new to Python and i cant get this.I have a List and i want to take the input from there and write those in files .
p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']
What i am trying :
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
i = 0
while i < len(p):
start = p[i].split('/')
if (start[0] == 'Eth101'):
i += 3
key = start[0]
i += 1
while i < len(p) and p[i].split('/')[0] == key:
i += 1
end = p[i-1].split('/')
fw2.write('confi ' + start[0] + '/' + start[1] + '-' + end[1] + '\n mode\n')
What i am looking for :
abc1.txt should have
int Eth1/1
mode
int Eth1/5
mode
int Eth2/1
mode
int Eth 2/4
mode
abc2.txt should have :
int Eth101/1/1-3
mode
int Eth102/1/1-3
mode
int Eth103/1/1-4
mode
int Eth104/1/1-4
mode
So any Eth having 1 digit before " / " ( e:g Eth1/1 or Eth2/2
)should be in one file that is abc1.txt .
Any Eth having 3 digit before " / " ( e:g Eth101/1/1 or Eth 102/1/1
) should be in another file that is abc2.txt and .As these are in
ranges , need to write it like Eth101/1/1-3, Eth102/1/1-3 etc
Any Idea ?
I don't think you need a regex here, at all. All your items begin with 'Eth' followed by one or more digits. So you can check the length of the items before first / occurs and then write it to a file.
p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
fw2.write('int ' + i + '\n mode\n')
I refactored your code a little to bring with-statement into play. This will handle correctly closing the file at the end. Also it is not necessary to iterate twice over the sequence, so it's all done in one iteration.
If the data is not as clean as provided, then you maybe want to use regexes. Independent of the regex itself, by writing if re.match(r'((Eth\d{1}\/\d{1,2})', "p" ) you proof if a match object can be created for given regex on the string "p", not the value of the variable p. This is because you used " around p.
So this should work for your example. If you really need a regex, this will turn your problem in finding a good regex to match your needs without any other issues.
As these are in ranges , need to write it like Eth101/1/1-3, Eth102/1/1-3 etc
This is something you can achieve by first computing the string and then write it in the file. But this is more like a separate question.
UPDATE
It's not that trivial to compute the right network ranges. Here I can present you one approach which doesn't change my code but adds some functionality. The trick here is to get groups of connected networks which aren't interrupted by their numbers. For that I've copied consecutive_groups. You can also do a pip install more-itertools of course to get that functionality. And also I transformed the list to a dict to prepare the magic and then retransformed dict to list again. There are definitely better ways of doing it, but this worked for your input data, at least.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from itertools import groupby
from operator import itemgetter
p = ['Eth1/1', 'Eth1/5', 'Eth2/1', 'Eth2/4', 'Eth101/1/1', 'Eth101/1/2',
'Eth101/1/3', 'Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3', 'Eth103/1/1',
'Eth103/1/2', 'Eth103/1/3', 'Eth103/1/4', 'Eth104/1/1', 'Eth104/1/2',
'Eth104/1/3', 'Eth104/1/4']
def get_network_ranges(networks):
network_ranges = {}
result = []
for network in networks:
parts = network.rpartition("/")
network_ranges.setdefault(parts[0], []).append(int(parts[2]))
for network, ranges in network_ranges.items():
ranges.sort()
for group in consecutive_groups(ranges):
group = list(group)
if len(group) == 1:
result.append(network + "/" + str(group[0]))
else:
result.append(network + "/" + str(group[0]) + "-" +
str(group[-1]))
result.sort() # to get ordered results
return result
def consecutive_groups(iterable, ordering=lambda x: x):
"""taken from more-itertools (latest)"""
for k, g in groupby(
enumerate(iterable), key=lambda x: x[0] - ordering(x[1])
):
yield map(itemgetter(1), g)
# only one line added to do the magic
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
p = get_network_ranges(p)
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
fw2.write('int ' + i + '\n mode\n')
I am working on a script that sorts people's names. I had this working using the csv module, but as this is going to be tied to a larger pandas project, I thought I would convert it.
I need to split a single name field into fields for first, middle and last. The original field has the first name first. ex: Richard Wayne Van Dyke.
I split the names but want "Van Dyke" to be the last name.
Here is my code for the csv module that works:
with open('inputfil.csv') as inf:
docs = csv.reader(inf)
next(ccaddocs, None)
for i in docs:
#print i
fullname = i[1]#it's the second column in the input file
namelist =fullname.split(' ')
firstname = namelist[0]
middlename = namelist[1]
if len(namelist) == 2:
lastname = namelist[1]
middlename = ''
elif len(namelist) == 3:
lastname = namelist[2]
elif len(namelist) == 4:
lastname = namelist[2] + " " + namelist[3] #gets Van Dyke in lastname
print "First: " + firstname + " middle: " + middlename + " last: " + lastname
Here is my pandas-based code that I'm struggling with:
df = pd.DataFrame({'Name':['Richard Wayne Van Dyke','Gary Del Barco','Dave Allen Smith']})
df = df.fillna('')
df =df.astype(unicode)
splits = df['Name'].str.split(' ', expand=True)
df['firstName'] = splits[0]
if splits[2].notnull and splits[3].isnull:#this works for Bret Allen Cardwell
df['lastName'] = splits[2]
df['middleName'] = splits[1]
print "Case 1: First: " + df['firstName'] + " middle: " +df['middleName'] + " last: " + df['lastName']
elif splits[2].all() == 'Del':#trying to get last name of "Del Barco"
print 'del'
df['middleName'] = ''
df['lastName'] = splits[2] + " " + splits[3]
print "Case 2: First: " + df['firstName'] + " middle: " +df['middleName'] + " last: " + df['lastName']
elif splits[3].notnull: #trying to get last name of "Van Dyke"
df['middleName'] = splits[1]
df['lastName'] = splits[2] + " " + splits[3]
print "Case 3: First: " + df['firstName'] + " middle: " +df['middleName'] + " last: " + df['lastName']
There is something basic that I'm missing.
if len(name) >= 3: # (assume that user only has one middle name)
firstname = splits[0]
middlename = splits[1]
lastnames = splits[2:] ( catch all last names into a list )
I am using a for loop for getting data from the user in command prompt using python 2.7. Then storing the data in a text file in certain format. I am looking for a method to get the data from the user and store it in a list and use it where required.
for Input_Number in range(Number_Of_Inputs):
Input_Number = Input_Number+1
GUI_Parameter = str(raw_input("Please enter input parameter " + str(Input_Number) + " :"))
GUI_Parameter_Name = str(raw_input("Enter the GUI name for the parameter " + str(Input_Number) + " :"))
Store_GUI_Parameter(Opened_File, GUI_Parameter, GUI_Parameter_Name)
I would like to use this data to store it in a specific location in a text file according to required syntax. The above code stores the data in the text file. But the problem is it doesn't store it at the required place.
def Store_GUI_Parameter(Opened_File, GUI_Parameter, GUI_Parameter_Name):
GUI_Description = "| " + '"'+ GUI_Parameter_Name + '"' + " |$" + GUI_Parameter.title() + " |"
Write_Data(Opened_File, GUI_Description)
print "GUI parameters written to NDF file"
return
The data storage is done using the above function...
I tried this, but unfortunately this also is not working
GUI_Parameter= []
GUI_Parameter_Name = []
for Input_Number in range(Number_Of_Inputs):
Input_Number = Input_Number+1
GUI_Parameter[Input_Number] = str(raw_input("Please enter input parameter " + str(Input_Number) + " :"))
GUI_Parameter_Name[Input_Number] = str(raw_input("Enter the GUI name for the parameter " + str(Input_Number) + " :"))
Using it outside the loop in the same function...
GUI_Description(Opened_File, GUI_Parameter_Name[Input_Number], GUI_Parameter[Input_Number])
The function implementation:
def GUI_Description(Opened_File, GUI_Parameter_Name[Input_Number], GUI_Parameter[Input_Number]):
Iteration = 0
while Iteration < Input_Number:
Iteration += 1
GUI_Description = "| " + '"'+ GUI_Parameter_Name[Input_Number] + '"' + " |$" + GUI_Parameter[Input_Number].title() + " |"
Write_Data(Opened_File, GUI_Description)
print "GUI parameters written to NDF file"
return
But it shows syntax error at the def GUI_Description
C:\Users\padmanab\Desktop>python CtoN.py File "CtoN.py", line 173
def GUI_Description(Opened_File, GUI_Parameter_Name[Input_Number], GUI_Parameter[Input_Number]):
^ SyntaxError: invalid syntax
The syntax error in the function GUI_Description is caused by your input arguments. 'GUI_Parameter_Name[Input_Number]' is not a valid input argument. Since your function requires both 'GUI_Parameter_Name' and 'Input_Number' they should be separate input arguments. The code snippet below would solve this syntax error:
def GUI_Description(Opened_File, Input_Number, GUI_Parameter_Name, GUI_Parameter):
...
The code below will give an 'index out of range' error since the lists 'GUI_Parameter' and 'GUI_Parameter_Name' have zero length.
GUI_Parameter= []
GUI_Parameter_Name = []
Number_Of_Inputs = 1
for Input_Number in range(Number_Of_Inputs):
Input_Number = Input_Number+1
GUI_Parameter[Input_Number] = str(raw_input("Please enter input parameter " + str(Input_Number) + " :"))
GUI_Parameter_Name[Input_Number] = str(raw_input("Enter the GUI name for the parameter " + str(Input_Number) + " :"))
If you want to add items to the arrays you should append them:
GUI_Parameter.append(raw_input())
I've been working on a small contact importer, and now I'm trying to implement a block that automatically selects the output file format based on the number of contacts to be imported.
However, every time it results in the error:
KeyError: 'q'
I can't figure out for the life of me why this is happening, and I would love any help offered.
My idea of scalability is that the dictionary personDict would be of the format personDict = {nameid:[name,email]}, but nothing works.
Any help is good help,
Thanks
def autoFormat():
while True:
name = input("Enter the person's name \n")
if name == "q":
break
email = input("Enter the person's email \n")
personDict[name] = [name, email]
if len(personDict) <= 10:
keyValue = personDict[name]
for keyValue in personDict:
for key, value in personDict.iteritems():
combined = "BEGIN:VCARD\nVERSION:4.0\n" + "FN:" + name + "\n" + "EMAIL:" + email + "\n" + "END:VCARD"
fileName = name + ".vcl"
people = open(fileName, 'a')
people.write(combined)
people.close()
print("Created file for " + name)
autoFormat()
The main problem is that when the user types "q" your code leaves the while loop
with name keeping "q" as value. So you should remove this useless line:
keyValue = person_dict[name]
Since there is no element with key "q" in your dictionary.
Also in the export part you write in file values different from those you loop with.
Your code becomes:
if len(personDict) <= 10:
for name, email in personDict.values():
combined = "BEGIN:VCARD\nVERSION:4.0\n" + "FN:" + name + "\n" + "EMAIL:" + email + "\n" + "END:VCARD"
fileName = name + ".vcl"
people = open(fileName, 'a')
people.write(combined)
people.close()
print("Created file for " + name)